From: Cédric Aguerre Date: Tue, 13 Oct 2015 15:47:17 +0000 (+0200) Subject: Initiating medtool X-Git-Tag: V8_0_0a1~5^2~24 X-Git-Url: http://git.salome-platform.org/gitweb/?a=commitdiff_plain;h=1a4fa437b4f33832bc467feacb4a08e4eb09dc31;p=modules%2Fmed.git Initiating medtool --- diff --git a/resources/LargeUnitTetra.med b/resources/LargeUnitTetra.med deleted file mode 100644 index 99ad8003b..000000000 Binary files a/resources/LargeUnitTetra.med and /dev/null differ diff --git a/resources/Pol1.fig b/resources/Pol1.fig deleted file mode 100644 index cee7eb792..000000000 --- a/resources/Pol1.fig +++ /dev/null @@ -1,15 +0,0 @@ -#FIG 3.2 Produced by xfig version 3.2.5-alpha5 -Landscape -Center -Metric -Letter -100.00 -Single --2 -1200 2 -5 1 0 1 0 7 50 -1 -1 0.000 0 1 0 0 2700.000 4800.000 3600 6000 4200 4800 3600 3600 -5 1 0 1 0 7 50 -1 -1 0.000 0 1 0 0 5400.000 1200.000 3600 3600 5400 4200 7200 3600 -5 1 0 1 0 7 50 -1 -1 0.000 0 0 0 0 5100.000 6300.000 7200 3600 7800 4200 8400 5400 -5 1 0 1 0 7 50 -1 -1 0.000 0 1 0 0 8400.000 6000.000 8400 5400 7800 6000 8400 6600 -5 1 0 1 0 7 50 -1 -1 0.000 0 1 0 0 9128.571 9642.857 8400 6600 6600 7800 6000 9600 -5 1 0 1 0 7 50 -1 -1 0.000 0 1 0 0 2820.000 9120.000 6000 9600 5400 7200 3600 6000 diff --git a/resources/Pol2.fig b/resources/Pol2.fig deleted file mode 100644 index 4778e6735..000000000 --- a/resources/Pol2.fig +++ /dev/null @@ -1,13 +0,0 @@ -#FIG 3.2 Produced by xfig version 3.2.5-alpha5 -Landscape -Center -Inches -Letter -100.00 -Single --2 -1200 2 -5 1 0 1 0 7 50 -1 -1 0.000 0 0 0 0 13000.000 7200.000 6600 9000 6600 5400 8400 2400 -5 1 0 1 0 7 50 -1 -1 0.000 0 1 0 0 10500.000 -900.000 8400 2400 10800 3000 12600 2400 -5 1 0 1 0 7 50 -1 -1 0.000 0 1 0 0 16242.857 6471.429 12600 2400 10800 6000 11400 9000 -5 1 0 1 0 7 50 -1 -1 0.000 0 0 0 0 9000.000 13500.000 6600 9000 9000 8400 11400 9000 diff --git a/resources/Pol3.fig b/resources/Pol3.fig deleted file mode 100644 index 4bad14493..000000000 --- a/resources/Pol3.fig +++ /dev/null @@ -1,11 +0,0 @@ -#FIG 3.2 Produced by xfig version 3.2.5-alpha5 -Landscape -Center -Inches -Letter -100.00 -Single --2 -1200 2 -2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 2 -3000 7200 6600 3600 diff --git a/resources/Pol4.fig b/resources/Pol4.fig deleted file mode 100644 index 1c6cd7924..000000000 --- a/resources/Pol4.fig +++ /dev/null @@ -1,10 +0,0 @@ -#FIG 3.2 Produced by xfig version 3.2.5-alpha5 -Landscape -Center -Inches -Letter -100.00 -Single --2 -1200 2 -5 1 0 1 0 7 50 -1 -1 0.000 0 0 0 0 4800.000 4837.500 4200 7200 4800 2400 5400 7200 diff --git a/resources/Test2D.med b/resources/Test2D.med deleted file mode 100644 index 8f651af39..000000000 Binary files a/resources/Test2D.med and /dev/null differ diff --git a/resources/Test2Dpoly.med b/resources/Test2Dpoly.med deleted file mode 100644 index 7d56fed90..000000000 Binary files a/resources/Test2Dpoly.med and /dev/null differ diff --git a/resources/Test3D.med b/resources/Test3D.med deleted file mode 100644 index 48eccd7a6..000000000 Binary files a/resources/Test3D.med and /dev/null differ diff --git a/resources/Test3Dpoly.med b/resources/Test3Dpoly.med deleted file mode 100644 index 621709411..000000000 Binary files a/resources/Test3Dpoly.med and /dev/null differ diff --git a/resources/agitateur.med b/resources/agitateur.med deleted file mode 100644 index 73c62e127..000000000 Binary files a/resources/agitateur.med and /dev/null differ diff --git a/resources/pointe.med b/resources/pointe.med deleted file mode 100644 index 73844dfa6..000000000 Binary files a/resources/pointe.med and /dev/null differ diff --git a/resources/square1.med b/resources/square1.med deleted file mode 100644 index 3fd7c4111..000000000 Binary files a/resources/square1.med and /dev/null differ diff --git a/resources/square2.med b/resources/square2.med deleted file mode 100644 index 9b9d0a40e..000000000 Binary files a/resources/square2.med and /dev/null differ diff --git a/src/CTestTestfileInstall.cmake b/src/CTestTestfileInstall.cmake deleted file mode 100644 index e9b04a1f6..000000000 --- a/src/CTestTestfileInstall.cmake +++ /dev/null @@ -1,20 +0,0 @@ -# Copyright (C) 2015 CEA/DEN, EDF 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, 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 -# 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 -# - -SUBDIRS(MEDCoupling) diff --git a/src/CTestTestfileInstallMEDCoupling.cmake b/src/CTestTestfileInstallMEDCoupling.cmake deleted file mode 100644 index 498ec4ba1..000000000 --- a/src/CTestTestfileInstallMEDCoupling.cmake +++ /dev/null @@ -1,35 +0,0 @@ -# Copyright (C) 2015 CEA/DEN, EDF 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, 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 -# 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(COMPONENT_NAME MEDCOUPLING) - -SUBDIRS(INTERP_KERNELTest) -SUBDIRS(MEDCalculator) -SUBDIRS(MEDCoupling) -#SUBDIRS(MEDCouplingCorba) -#SUBDIRS(MEDCouplingCorba_Swig) -SUBDIRS(MEDCoupling_Swig) -SUBDIRS(MEDLoader) -SUBDIRS(MEDLoader/Swig) -#SUBDIRS(MEDCalc) -SUBDIRS(MEDPartitioner) -#SUBDIRS(ParaMEDMEM_Swig) -#SUBDIRS(ParaMEDMEMTest) -SUBDIRS(MEDPartitioner_Swig) -SUBDIRS(RENUMBER_Swig) diff --git a/src/INTERP_KERNEL/BBTree.txx b/src/INTERP_KERNEL/BBTree.txx deleted file mode 100644 index 5694fa4bc..000000000 --- a/src/INTERP_KERNEL/BBTree.txx +++ /dev/null @@ -1,281 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 -// 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 __BBTREE_TXX__ -#define __BBTREE_TXX__ - -#include -#include - -#include -#include -#include - -template -class BBTree -{ - -private: - BBTree* _left; - BBTree* _right; - int _level; - double _max_left; - double _min_right; - const double *_bb; - 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 bbs pointer to the [xmin1 xmax1 ymin1 ymax1 xmin2 xmax2 ...] array containing the bounding boxes that are to be indexed. - \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. 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 - int nbelems=... - double* bbs= new double[2*2*nbelems]; - // filling bbs ... - ... - BBTree<2> tree = new BBTree<2>(elems,0,0,nbelems,1e-12); - \endcode - */ - - 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) - { - _terminal=true; - - } - 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:: cout << *median < 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+std::abs(_epsilon); - _min_right=min_right-std::abs(_epsilon); - ConnType *tmp; - tmp=0; - if(!new_elems_left.empty()) - tmp=&(new_elems_left[0]); - _left=new BBTree(bbs, tmp, level+1, (int)new_elems_left.size(),_epsilon); - tmp=0; - if(!new_elems_right.empty()) - tmp=&(new_elems_right[0]); - _right=new BBTree(bbs, tmp, level+1, (int)new_elems_right.size(),_epsilon); - - } - - - - ~BBTree() - { - if (_left!=0) delete _left; - if (_right!=0) delete _right; - - } - - - /*! returns in \a elems the list of elements potentially intersecting the bounding box pointed to by \a bb - - \param bb pointer to query bounding box - \param elems list of elements (given in 0-indexing that is to say in \b C \b mode) intersecting the bounding box - */ - - void getIntersectingElems(const double* bb, std::vector& elems) const - { - // terminal node : return list of elements intersecting bb - if (_terminal) - { - for (int i=0; i<_nbelems; i++) - { - const double* const bb_ptr=_bb+_elems[i]*2*dim; - bool intersects = true; - for (int idim=0; idim-_epsilon|| bb_ptr[idim*2+1]-bb[idim*2]<_epsilon) - intersects=false; - } - if (intersects) - { - elems.push_back(_elems[i]); - } - } - return; - } - - //non terminal node - double min = bb[(_level%dim)*2]; - double max = bb[(_level%dim)*2+1]; - if (max < _min_right) - { - _left->getIntersectingElems(bb, elems); - return; - } - if (min> _max_left) - { - _right->getIntersectingElems(bb,elems); - return; - } - _left->getIntersectingElems(bb,elems); - _right->getIntersectingElems(bb,elems); - } - - /*! - * This method is very close to getIntersectingElems except that it returns number of elems instead of elems themselves. - */ - int getNbOfIntersectingElems(const double* bb) - { - // terminal node : return list of elements intersecting bb - int ret(0); - if (_terminal) - { - for (int i=0; i<_nbelems; i++) - { - const double* const bb_ptr=_bb+_elems[i]*2*dim; - bool intersects = true; - for (int idim=0; idim-_epsilon|| bb_ptr[idim*2+1]-bb[idim*2]<_epsilon) - intersects=false; - } - if (intersects) - ret++; - } - return ret; - } - //non terminal node - double min = bb[(_level%dim)*2]; - double max = bb[(_level%dim)*2+1]; - if (max < _min_right) - return _left->getNbOfIntersectingElems(bb); - if (min> _max_left) - return _right->getNbOfIntersectingElems(bb); - return _left->getNbOfIntersectingElems(bb)+_right->getNbOfIntersectingElems(bb); - } - - - /*! returns in \a elems the list of elements potentially containing the point pointed to by \a xx - \param xx pointer to query point coords - \param elems list of elements (given in 0-indexing) intersecting the bounding box - */ - - void getElementsAroundPoint(const double* xx, std::vector& elems) const - { - // terminal node : return list of elements intersecting bb - if (_terminal) - { - for (ConnType i=0; i<_nbelems; i++) - { - const double* const bb_ptr=_bb+_elems[i]*2*dim; - bool intersects = true; - for (int idim=0; idim_epsilon|| bb_ptr[idim*2+1]-xx[idim]<-_epsilon) - intersects=false; - } - if (intersects) - { - elems.push_back(_elems[i]); - } - } - return; - } - - //non terminal node - if (xx[_level%dim] < _min_right) - { - _left->getElementsAroundPoint(xx, elems); - return; - } - if (xx[_level%dim]> _max_left) - { - _right->getElementsAroundPoint(xx,elems); - return; - } - _left->getElementsAroundPoint(xx,elems); - _right->getElementsAroundPoint(xx,elems); - } - - - - int size() - { - if (_terminal) return _nbelems; - return _left->size()+_right->size(); - } -}; -#endif diff --git a/src/INTERP_KERNEL/BBTreeDst.txx b/src/INTERP_KERNEL/BBTreeDst.txx deleted file mode 100644 index a5cbfb43d..000000000 --- a/src/INTERP_KERNEL/BBTreeDst.txx +++ /dev/null @@ -1,217 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 -// 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 deleted file mode 100644 index 6c4378a79..000000000 --- a/src/INTERP_KERNEL/BBTreePts.txx +++ /dev/null @@ -1,222 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 -// 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/Barycentric3DIntersectorP1P1.hxx b/src/INTERP_KERNEL/Barycentric3DIntersectorP1P1.hxx deleted file mode 100644 index 33746d4c4..000000000 --- a/src/INTERP_KERNEL/Barycentric3DIntersectorP1P1.hxx +++ /dev/null @@ -1,46 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 -// 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 __BARYCENTRIC3DINTERSECTORP1P1_HXX__ -#define __BARYCENTRIC3DINTERSECTORP1P1_HXX__ - -#include "Intersector3DP1P1.hxx" -#include "NormalizedUnstructuredMesh.hxx" - -namespace INTERP_KERNEL -{ - template - class Barycentric3DIntersectorP1P1 : public Intersector3DP1P1 - { - public: - static const int SPACEDIM=MyMeshType::MY_SPACEDIM; - static const int MESHDIM=MyMeshType::MY_MESHDIM; - typedef typename MyMeshType::MyConnType ConnType; - static const NumberingPolicy numPol=MyMeshType::My_numPol; - public: - Barycentric3DIntersectorP1P1(const MyMeshType& targetMesh, const MyMeshType& srcMesh, double precision); - ~Barycentric3DIntersectorP1P1(); - void intersectCells(ConnType targetCell, const std::vector& srcCells, MyMatrix& res); - protected: - double _precision; - }; -} - -#endif diff --git a/src/INTERP_KERNEL/Barycentric3DIntersectorP1P1.txx b/src/INTERP_KERNEL/Barycentric3DIntersectorP1P1.txx deleted file mode 100644 index 7009c7c36..000000000 --- a/src/INTERP_KERNEL/Barycentric3DIntersectorP1P1.txx +++ /dev/null @@ -1,98 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 -// 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 __BARYCENTRIC3DINTERSECTORP1P1_TXX__ -#define __BARYCENTRIC3DINTERSECTORP1P1_TXX__ - -#include "Barycentric3DIntersectorP1P1.hxx" -#include "Intersector3DP1P1.txx" -#include "MeshUtils.hxx" - -namespace INTERP_KERNEL -{ - - /** - * Constructor creating object from target cell global number - * - * @param targetMesh mesh containing the target elements - * @param srcMesh mesh containing the source elements - * @param policy splitting policy to be used - */ - template - Barycentric3DIntersectorP1P1::Barycentric3DIntersectorP1P1(const MyMeshType& targetMesh, const MyMeshType& srcMesh, double precision): - Intersector3DP1P1(targetMesh,srcMesh),_precision(precision) - { - } - - template - Barycentric3DIntersectorP1P1::~Barycentric3DIntersectorP1P1() - { - } - - /** - * @param targetCell in C mode. - * @param srcCells in C mode. - */ - template - void Barycentric3DIntersectorP1P1::intersectCells(ConnType targetCell, const std::vector& srcCells, MyMatrix& res) - { - std::vector CoordsT; - const ConnType *startOfCellNodeConnT=Intersector3DP1P1::getStartConnOfTargetCell(targetCell); - Intersector3DP1P1::getRealTargetCoordinates(OTT::indFC(targetCell),CoordsT); - int nbOfNodesT=CoordsT.size()/SPACEDIM; - const double *coordsS=Intersector3DP1P1::_src_mesh.getCoordinatesPtr(); - for(int nodeIdT=0;nodeIdT::ind2C(startOfCellNodeConnT[nodeIdT])]; - if(!resRow.empty()) - continue; - for(typename std::vector::const_iterator iterCellS=srcCells.begin();iterCellS!=srcCells.end();iterCellS++) - { - NormalizedCellType tS=Intersector3DP1P1::_src_mesh.getTypeOfElement(OTT::indFC(*iterCellS)); - if(tS!=NORM_TETRA4) - throw INTERP_KERNEL::Exception("Invalid source cell detected for meshdim==3. Only TETRA4 supported !"); - const CellModel& cmTypeS=CellModel::GetCellModel(tS); - // - std::vector connOfCurCellS; - Intersector3DP1P1::getConnOfSourceCell(OTT::indFC(*iterCellS),connOfCurCellS); - if( PointLocatorAlgos::isElementContainsPointAlg3D(&CoordsT[nodeIdT*SPACEDIM],&connOfCurCellS[0],connOfCurCellS.size(),coordsS,cmTypeS,_precision) ) - { - double resLoc[4]; - std::vector localCoordsS; - Intersector3DP1P1::getRealSourceCoordinates(OTT::indFC(*iterCellS),localCoordsS); - std::vector eap(4); - eap[0]=&localCoordsS[0]; eap[1]=&localCoordsS[3]; eap[2]=&localCoordsS[6]; eap[3]=&localCoordsS[9]; - barycentric_coords(eap,&CoordsT[nodeIdT*SPACEDIM],resLoc); - const ConnType *startOfCellNodeConnS=Intersector3DP1P1::getStartConnOfSourceCell(*iterCellS); - for(int nodeIdS=0;nodeIdS<4;nodeIdS++) - { - if(fabs(resLoc[nodeIdS])>_precision) - { - ConnType curNodeSInCmode=OTT::coo2C(startOfCellNodeConnS[nodeIdS]); - resRow.insert(std::make_pair(OTT::indFC(curNodeSInCmode),resLoc[nodeIdS])); - } - } - } - } - } - } -} - -#endif diff --git a/src/INTERP_KERNEL/Bases/InterpKernelAutoPtr.hxx b/src/INTERP_KERNEL/Bases/InterpKernelAutoPtr.hxx deleted file mode 100644 index 1e28d1e61..000000000 --- a/src/INTERP_KERNEL/Bases/InterpKernelAutoPtr.hxx +++ /dev/null @@ -1,84 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 -// 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 __INTERPKERNELAUTOPTR_HXX__ -#define __INTERPKERNELAUTOPTR_HXX__ - -namespace INTERP_KERNEL -{ - template - class AutoPtr - { - public: - AutoPtr(T *ptr=0):_ptr(ptr) { } - ~AutoPtr() { destroyPtr(); } - AutoPtr &operator=(T *ptr) { if(_ptr!=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() { delete [] _ptr; } - private: - T *_ptr; - }; - - template - class AutoCppPtr - { - public: - AutoCppPtr(T *ptr=0):_ptr(ptr) { } - ~AutoCppPtr() { destroyPtr(); } - AutoCppPtr &operator=(T *ptr) { if(_ptr!=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() { delete _ptr; } - private: - T *_ptr; - }; - - template - class AutoCPtr - { - public: - AutoCPtr(T *ptr=0):_ptr(ptr) { } - ~AutoCPtr() { destroyPtr(); } - AutoCPtr &operator=(T *ptr) { if(_ptr!=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 deleted file mode 100644 index dae549346..000000000 --- a/src/INTERP_KERNEL/Bases/InterpKernelException.cxx +++ /dev/null @@ -1,38 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 -// 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 "InterpKernelException.hxx" - -INTERP_KERNEL::Exception::Exception(const char *reason):_reason(reason) -{ -} - -INTERP_KERNEL::Exception::Exception(const char *reason, const char *file, int line):_reason(reason) -{ -} - -INTERP_KERNEL::Exception::~Exception() throw () -{ -} - -const char *INTERP_KERNEL::Exception::what() const throw() -{ - return _reason.c_str(); -} diff --git a/src/INTERP_KERNEL/Bases/InterpKernelException.hxx b/src/INTERP_KERNEL/Bases/InterpKernelException.hxx deleted file mode 100644 index 86fe0cc96..000000000 --- a/src/INTERP_KERNEL/Bases/InterpKernelException.hxx +++ /dev/null @@ -1,43 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 -// 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 __INTERPKERNELEXCEPTION_HXX__ -#define __INTERPKERNELEXCEPTION_HXX__ - -#include "INTERPKERNELDefines.hxx" - -#include -#include - -namespace INTERP_KERNEL -{ - class Exception : public std::exception - { - public: - INTERPKERNEL_EXPORT Exception(const char *reason); - INTERPKERNEL_EXPORT Exception(const char *reason, const char *file, int line); - INTERPKERNEL_EXPORT ~Exception() throw (); - INTERPKERNEL_EXPORT const char *what() const throw(); - protected: - std::string _reason; - }; -} - -#endif diff --git a/src/INTERP_KERNEL/Bases/InterpKernelHashFun.hxx b/src/INTERP_KERNEL/Bases/InterpKernelHashFun.hxx deleted file mode 100644 index 3fcc84ee6..000000000 --- a/src/INTERP_KERNEL/Bases/InterpKernelHashFun.hxx +++ /dev/null @@ -1,146 +0,0 @@ -// Copyright (C) 2001-2015 CEA/DEN, EDF 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, 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 -// 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 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 General Public License for more details. - -// Under Section 7 of GPL version 3, you are granted additional -// permissions described in the GCC Runtime Library Exception, version -// 3.1, as published by the Free Software Foundation. - -// You should have received a copy of the GNU General Public License and -// a copy of the GCC Runtime Library Exception along with this program; -// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see -// . - -/* - * Copyright (c) 1996-1998 - * Silicon Graphics Computer Systems, Inc. - * - * Permission to use, copy, modify, distribute and sell this software - * and its documentation for any purpose is hereby granted without fee, - * provided that the above copyright notice appear in all copies and - * that both that copyright notice and this permission notice appear - * in supporting documentation. Silicon Graphics makes no - * representations about the suitability of this software for any - * purpose. It is provided "as is" without express or implied warranty. - * - * - * Copyright (c) 1994 - * Hewlett-Packard Company - * - * Permission to use, copy, modify, distribute and sell this software - * and its documentation for any purpose is hereby granted without fee, - * provided that the above copyright notice appear in all copies and - * that both that copyright notice and this permission notice appear - * in supporting documentation. Hewlett-Packard Company makes no - * representations about the suitability of this software for any - * purpose. It is provided "as is" without express or implied warranty. - * - */ -#ifndef __INTERPKERNELHASHFUN_HXX__ -#define __INTERPKERNELHASHFUN_HXX__ - -#include - -namespace INTERP_KERNEL -{ - template - struct hash { }; - - inline std::size_t __stl_hash_string(const char* __s) - { - unsigned long __h = 0; - for ( ; *__s; ++__s) - __h = 5 * __h + *__s; - return std::size_t(__h); - } - - template<> - struct hash - { - std::size_t operator()(const char* __s) const - { return __stl_hash_string(__s); } - }; - - template<> - struct hash - { - std::size_t operator()(const char* __s) const - { return __stl_hash_string(__s); } - }; - - template<> - struct hash - { - std::size_t operator()(char __x) const { return __x; } - }; - - template<> - struct hash - { - std::size_t operator()(unsigned char __x) const { return __x; } - }; - - template<> - struct hash - { - std::size_t operator()(unsigned char __x) const { return __x; } - }; - - template<> - struct hash - { - std::size_t operator()(short __x) const { return __x; } - }; - - template<> - struct hash - { - std::size_t operator()(unsigned short __x) const { return __x; } - }; - - template<> - struct hash - { - std::size_t operator()(int __x) const { return __x; } - }; - - template<> - struct hash - { - std::size_t operator()(unsigned int __x) const { return __x; } - }; - - template<> - struct hash - { - std::size_t operator()(long __x) const { return __x; } - }; - - template<> - struct hash - { - std::size_t operator()(unsigned long __x) const { return __x; } - }; -} - -#endif diff --git a/src/INTERP_KERNEL/Bases/InterpKernelHashMap.hxx b/src/INTERP_KERNEL/Bases/InterpKernelHashMap.hxx deleted file mode 100644 index f4ff608b0..000000000 --- a/src/INTERP_KERNEL/Bases/InterpKernelHashMap.hxx +++ /dev/null @@ -1,414 +0,0 @@ -// Copyright (C) 2001-2015 CEA/DEN, EDF 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, 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 -// 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 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 General Public License for more details. - -// Under Section 7 of GPL version 3, you are granted additional -// permissions described in the GCC Runtime Library Exception, version -// 3.1, as published by the Free Software Foundation. - -// You should have received a copy of the GNU General Public License and -// a copy of the GCC Runtime Library Exception along with this program; -// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see -// . - -/* - * Copyright (c) 1996 - * Silicon Graphics Computer Systems, Inc. - * - * Permission to use, copy, modify, distribute and sell this software - * and its documentation for any purpose is hereby granted without fee, - * provided that the above copyright notice appear in all copies and - * that both that copyright notice and this permission notice appear - * in supporting documentation. Silicon Graphics makes no - * representations about the suitability of this software for any - * purpose. It is provided "as is" without express or implied warranty. - * - * - * Copyright (c) 1994 - * Hewlett-Packard Company - * - * Permission to use, copy, modify, distribute and sell this software - * and its documentation for any purpose is hereby granted without fee, - * provided that the above copyright notice appear in all copies and - * that both that copyright notice and this permission notice appear - * in supporting documentation. Hewlett-Packard Company makes no - * representations about the suitability of this software for any - * purpose. It is provided "as is" without express or implied warranty. - * - */ -#ifndef __INTERPKERNELHASHMAP__ -#define __INTERPKERNELHASHMAP__ - -#include "InterpKernelStlExt.hxx" -#include "InterpKernelHashTable.hxx" - -namespace INTERP_KERNEL -{ - template, - class _EqualKey = std::equal_to<_Key>, class _Alloc = std::allocator<_Tp> > - class HashMap - { - private: - typedef hashtable,_Key, _HashFn, - STLEXT::Select1st >, - _EqualKey, _Alloc> _Ht; - - _Ht _M_ht; - - public: - typedef typename _Ht::key_type key_type; - typedef _Tp data_type; - typedef _Tp mapped_type; - typedef typename _Ht::value_type value_type; - typedef typename _Ht::hasher hasher; - typedef typename _Ht::key_equal key_equal; - - typedef typename _Ht::size_type size_type; - typedef typename _Ht::difference_type difference_type; - typedef typename _Ht::pointer pointer; - typedef typename _Ht::const_pointer const_pointer; - typedef typename _Ht::reference reference; - typedef typename _Ht::const_reference const_reference; - - typedef typename _Ht::iterator iterator; - typedef typename _Ht::const_iterator const_iterator; - - typedef typename _Ht::allocator_type allocator_type; - - hasher hash_funct() const { return _M_ht.hash_funct(); } - - key_equal key_eq() const { return _M_ht.key_eq(); } - - allocator_type get_allocator() const { return _M_ht.get_allocator(); } - - HashMap() : _M_ht(100, hasher(), key_equal(), allocator_type()) {} - - explicit HashMap(size_type __n) : _M_ht(__n, hasher(), key_equal(), allocator_type()) {} - - HashMap(size_type __n, const hasher& __hf) : _M_ht(__n, __hf, key_equal(), allocator_type()) {} - - HashMap(size_type __n, const hasher& __hf, const key_equal& __eql, - const allocator_type& __a = allocator_type()) : _M_ht(__n, __hf, __eql, __a) {} - - template - HashMap(_InputIterator __f, _InputIterator __l) : _M_ht(100, hasher(), key_equal(), allocator_type()) - { _M_ht.insert_unique(__f, __l); } - - template - HashMap(_InputIterator __f, _InputIterator __l, size_type __n) : _M_ht(__n, hasher(), key_equal(), allocator_type()) - { _M_ht.insert_unique(__f, __l); } - - template - HashMap(_InputIterator __f, _InputIterator __l, size_type __n, const hasher& __hf) - : _M_ht(__n, __hf, key_equal(), allocator_type()) - { _M_ht.insert_unique(__f, __l); } - - template - HashMap(_InputIterator __f, _InputIterator __l, size_type __n, - const hasher& __hf, const key_equal& __eql, - const allocator_type& __a = allocator_type()) : _M_ht(__n, __hf, __eql, __a) - { _M_ht.insert_unique(__f, __l); } - - size_type size() const { return _M_ht.size(); } - - size_type max_size() const { return _M_ht.max_size(); } - - bool empty() const { return _M_ht.empty(); } - - void swap(HashMap& __hs) { _M_ht.swap(__hs._M_ht); } - - template - friend bool operator== (const HashMap<_K1, _T1, _HF, _EqK, _Al>&, - const HashMap<_K1, _T1, _HF, _EqK, _Al>&); - - iterator begin() { return _M_ht.begin(); } - - iterator end() { return _M_ht.end(); } - - const_iterator begin() const { return _M_ht.begin(); } - - const_iterator end() const { return _M_ht.end(); } - - std::pair insert(const value_type& __obj) { return _M_ht.insert_unique(__obj); } - - template - void insert(_InputIterator __f, _InputIterator __l) { _M_ht.insert_unique(__f, __l); } - - std::pair - insert_noresize(const value_type& __obj) { return _M_ht.insert_unique_noresize(__obj); } - - iterator find(const key_type& __key) { return _M_ht.find(__key); } - - const_iterator find(const key_type& __key) const { return _M_ht.find(__key); } - - _Tp& operator[](const key_type& __key) { return _M_ht.find_or_insert(value_type(__key, _Tp())).second; } - - size_type count(const key_type& __key) const { return _M_ht.count(__key); } - - std::pair equal_range(const key_type& __key) { return _M_ht.equal_range(__key); } - - std::pair equal_range(const key_type& __key) const { return _M_ht.equal_range(__key); } - - size_type erase(const key_type& __key) { return _M_ht.erase(__key); } - - void erase(iterator __it) { _M_ht.erase(__it); } - - void erase(iterator __f, iterator __l) { _M_ht.erase(__f, __l); } - - void clear() { _M_ht.clear(); } - - void resize(size_type __hint) { _M_ht.resize(__hint); } - - size_type bucket_count() const { return _M_ht.bucket_count(); } - - size_type max_bucket_count() const { return _M_ht.max_bucket_count(); } - - size_type elems_in_bucket(size_type __n) const { return _M_ht.elems_in_bucket(__n); } - }; - - template - inline bool operator==(const HashMap<_Key, _Tp, _HashFn, _EqlKey, _Alloc>& __hm1, - const HashMap<_Key, _Tp, _HashFn, _EqlKey, _Alloc>& __hm2) - { return __hm1._M_ht == __hm2._M_ht; } - - template - inline bool operator!=(const HashMap<_Key, _Tp, _HashFn, _EqlKey, _Alloc>& __hm1, - const HashMap<_Key, _Tp, _HashFn, _EqlKey, _Alloc>& __hm2) - { return !(__hm1 == __hm2); } - - template - inline void swap(HashMap<_Key, _Tp, _HashFn, _EqlKey, _Alloc>& __hm1, - HashMap<_Key, _Tp, _HashFn, _EqlKey, _Alloc>& __hm2) - { __hm1.swap(__hm2); } - - template, - class _EqualKey = std::equal_to<_Key>, - class _Alloc = std::allocator<_Tp> > - class HashMultiMap - { - private: - typedef hashtable, _Key, _HashFn, - STLEXT::Select1st >, _EqualKey, _Alloc> - _Ht; - _Ht _M_ht; - public: - typedef typename _Ht::key_type key_type; - typedef _Tp data_type; - typedef _Tp mapped_type; - typedef typename _Ht::value_type value_type; - typedef typename _Ht::hasher hasher; - typedef typename _Ht::key_equal key_equal; - - typedef typename _Ht::size_type size_type; - typedef typename _Ht::difference_type difference_type; - typedef typename _Ht::pointer pointer; - typedef typename _Ht::const_pointer const_pointer; - typedef typename _Ht::reference reference; - typedef typename _Ht::const_reference const_reference; - - typedef typename _Ht::iterator iterator; - typedef typename _Ht::const_iterator const_iterator; - - typedef typename _Ht::allocator_type allocator_type; - - hasher hash_funct() const { return _M_ht.hash_funct(); } - - key_equal key_eq() const { return _M_ht.key_eq(); } - - allocator_type get_allocator() const { return _M_ht.get_allocator(); } - - HashMultiMap() : _M_ht(100, hasher(), key_equal(), allocator_type()) { } - - explicit HashMultiMap(size_type __n) : _M_ht(__n, hasher(), key_equal(), allocator_type()) {} - - HashMultiMap(size_type __n, const hasher& __hf) : _M_ht(__n, __hf, key_equal(), allocator_type()) {} - - HashMultiMap(size_type __n, const hasher& __hf, const key_equal& __eql, - const allocator_type& __a = allocator_type()) : _M_ht(__n, __hf, __eql, __a) {} - - template - HashMultiMap(_InputIterator __f, _InputIterator __l) : _M_ht(100, hasher(), key_equal(), allocator_type()) - { _M_ht.insert_equal(__f, __l); } - - template - HashMultiMap(_InputIterator __f, _InputIterator __l, size_type __n) : _M_ht(__n, hasher(), key_equal(), allocator_type()) - { _M_ht.insert_equal(__f, __l); } - - template - HashMultiMap(_InputIterator __f, _InputIterator __l, size_type __n, const hasher& __hf) - : _M_ht(__n, __hf, key_equal(), allocator_type()) - { _M_ht.insert_equal(__f, __l); } - - template - HashMultiMap(_InputIterator __f, _InputIterator __l, size_type __n, - const hasher& __hf, const key_equal& __eql, - const allocator_type& __a = allocator_type()) - : _M_ht(__n, __hf, __eql, __a) - { _M_ht.insert_equal(__f, __l); } - - size_type size() const { return _M_ht.size(); } - - size_type max_size() const { return _M_ht.max_size(); } - - bool empty() const { return _M_ht.empty(); } - - void swap(HashMultiMap& __hs) { _M_ht.swap(__hs._M_ht); } - - template - friend bool operator==(const HashMultiMap<_K1, _T1, _HF, _EqK, _Al>&, - const HashMultiMap<_K1, _T1, _HF, _EqK, _Al>&); - - iterator begin() { return _M_ht.begin(); } - - iterator end() { return _M_ht.end(); } - - const_iterator begin() const { return _M_ht.begin(); } - - const_iterator end() const { return _M_ht.end(); } - - iterator insert(const value_type& __obj) { return _M_ht.insert_equal(__obj); } - - template - void insert(_InputIterator __f, _InputIterator __l) { _M_ht.insert_equal(__f,__l); } - - iterator insert_noresize(const value_type& __obj) { return _M_ht.insert_equal_noresize(__obj); } - - iterator find(const key_type& __key) { return _M_ht.find(__key); } - - const_iterator find(const key_type& __key) const { return _M_ht.find(__key); } - - size_type count(const key_type& __key) const { return _M_ht.count(__key); } - - std::pair equal_range(const key_type& __key) { return _M_ht.equal_range(__key); } - - std::pair equal_range(const key_type& __key) const { return _M_ht.equal_range(__key); } - - size_type erase(const key_type& __key) { return _M_ht.erase(__key); } - - void erase(iterator __it) { _M_ht.erase(__it); } - - void erase(iterator __f, iterator __l) { _M_ht.erase(__f, __l); } - - void clear() { _M_ht.clear(); } - - void resize(size_type __hint) { _M_ht.resize(__hint); } - - size_type bucket_count() const { return _M_ht.bucket_count(); } - - size_type max_bucket_count() const { return _M_ht.max_bucket_count(); } - - size_type elems_in_bucket(size_type __n) const { return _M_ht.elems_in_bucket(__n); } - }; - - template - inline bool operator==(const HashMultiMap<_Key, _Tp, _HF, _EqKey, _Alloc>& __hm1, - const HashMultiMap<_Key, _Tp, _HF, _EqKey, _Alloc>& __hm2) - { return __hm1._M_ht == __hm2._M_ht; } - - template - inline bool operator!=(const HashMultiMap<_Key, _Tp, _HF, _EqKey, _Alloc>& __hm1, - const HashMultiMap<_Key, _Tp, _HF, _EqKey, _Alloc>& __hm2) - { return !(__hm1 == __hm2); } - - template - inline void swap(HashMultiMap<_Key, _Tp, _HashFn, _EqlKey, _Alloc>& __hm1, - HashMultiMap<_Key, _Tp, _HashFn, _EqlKey, _Alloc>& __hm2) - { __hm1.swap(__hm2); } - -} - -namespace std -{ - // Specialization of insert_iterator so that it will work for HashMap - // and HashMultiMap. - template - class insert_iterator > - { - protected: - typedef INTERP_KERNEL::HashMap<_Key, _Tp, _HashFn, _EqKey, _Alloc> - _Container; - _Container* container; - public: - typedef _Container container_type; - typedef output_iterator_tag iterator_category; - typedef void value_type; - typedef void difference_type; - typedef void pointer; - typedef void reference; - - insert_iterator(_Container& __x) : container(&__x) {} - - insert_iterator(_Container& __x, typename _Container::iterator) : container(&__x) {} - - insert_iterator<_Container>& operator=(const typename _Container::value_type& __value__) - { - container->insert(__value__); - return *this; - } - - insert_iterator<_Container>& operator*() { return *this; } - - insert_iterator<_Container>& operator++() { return *this; } - - insert_iterator<_Container>& operator++(int) { return *this; } - }; - - template - class insert_iterator > - { - protected: - typedef INTERP_KERNEL::HashMultiMap<_Key, _Tp, _HashFn, _EqKey, _Alloc> - _Container; - _Container* container; - typename _Container::iterator iter; - - public: - typedef _Container container_type; - typedef output_iterator_tag iterator_category; - typedef void value_type; - typedef void difference_type; - typedef void pointer; - typedef void reference; - - insert_iterator(_Container& __x) : container(&__x) {} - - insert_iterator(_Container& __x, typename _Container::iterator) : container(&__x) {} - - insert_iterator<_Container>& operator=(const typename _Container::value_type& __value__) - { - container->insert(__value__); - return *this; - } - - insert_iterator<_Container>& operator*() { return *this; } - - insert_iterator<_Container>& operator++() { return *this; } - - insert_iterator<_Container>& operator++(int) { return *this; } - }; -} - -#endif diff --git a/src/INTERP_KERNEL/Bases/InterpKernelHashTable.hxx b/src/INTERP_KERNEL/Bases/InterpKernelHashTable.hxx deleted file mode 100644 index 6caa116b9..000000000 --- a/src/INTERP_KERNEL/Bases/InterpKernelHashTable.hxx +++ /dev/null @@ -1,1005 +0,0 @@ -// Copyright (C) 2001-2015 CEA/DEN, EDF 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, 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 -// 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 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 General Public License for more details. - -// Under Section 7 of GPL version 3, you are granted additional -// permissions described in the GCC Runtime Library Exception, version -// 3.1, as published by the Free Software Foundation. - -// You should have received a copy of the GNU General Public License and -// a copy of the GCC Runtime Library Exception along with this program; -// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see -// . - -/* - * Copyright (c) 1996,1997 - * Silicon Graphics Computer Systems, Inc. - * - * Permission to use, copy, modify, distribute and sell this software - * and its documentation for any purpose is hereby granted without fee, - * provided that the above copyright notice appear in all copies and - * that both that copyright notice and this permission notice appear - * in supporting documentation. Silicon Graphics makes no - * representations about the suitability of this software for any - * purpose. It is provided "as is" without express or implied warranty. - * - * - * Copyright (c) 1994 - * Hewlett-Packard Company - * - * Permission to use, copy, modify, distribute and sell this software - * and its documentation for any purpose is hereby granted without fee, - * provided that the above copyright notice appear in all copies and - * that both that copyright notice and this permission notice appear - * in supporting documentation. Hewlett-Packard Company makes no - * representations about the suitability of this software for any - * purpose. It is provided "as is" without express or implied warranty. - * - */ -#ifndef __INTERPKERNELHASHTABLE_HXX__ -#define __INTERPKERNELHASHTABLE_HXX__ - -#include "InterpKernelStlExt.hxx" -#include "InterpKernelHashFun.hxx" - -#include -#include -#include -#include - -namespace INTERP_KERNEL -{ - template - struct _Hashtable_node - { - _Hashtable_node* _M_next; - _Val _M_val; - }; - - template > - class hashtable; - - template - struct _Hashtable_iterator; - - template - struct _Hashtable_const_iterator; - - template - struct _Hashtable_iterator - { - typedef hashtable<_Val, _Key, _HashFcn, _ExtractKey, _EqualKey, _Alloc> - _Hashtable; - typedef _Hashtable_iterator<_Val, _Key, _HashFcn, - _ExtractKey, _EqualKey, _Alloc> - iterator; - typedef _Hashtable_const_iterator<_Val, _Key, _HashFcn, - _ExtractKey, _EqualKey, _Alloc> - const_iterator; - typedef _Hashtable_node<_Val> _Node; - typedef std::forward_iterator_tag iterator_category; - typedef _Val value_type; - typedef std::ptrdiff_t difference_type; - typedef std::size_t size_type; - typedef _Val& reference; - typedef _Val* pointer; - - _Node* _M_cur; - _Hashtable* _M_ht; - - _Hashtable_iterator(_Node* __n, _Hashtable* __tab) - : _M_cur(__n), _M_ht(__tab) { } - - _Hashtable_iterator() { } - - reference - operator*() const - { return _M_cur->_M_val; } - - pointer - operator->() const - { return &(operator*()); } - - iterator& - operator++(); - - iterator - operator++(int); - - bool - operator==(const iterator& __it) const - { return _M_cur == __it._M_cur; } - - bool - operator!=(const iterator& __it) const - { return _M_cur != __it._M_cur; } - }; - - template - struct _Hashtable_const_iterator - { - typedef hashtable<_Val, _Key, _HashFcn, _ExtractKey, _EqualKey, _Alloc> - _Hashtable; - typedef _Hashtable_iterator<_Val,_Key,_HashFcn, - _ExtractKey,_EqualKey,_Alloc> - iterator; - typedef _Hashtable_const_iterator<_Val, _Key, _HashFcn, - _ExtractKey, _EqualKey, _Alloc> - const_iterator; - typedef _Hashtable_node<_Val> _Node; - - typedef std::forward_iterator_tag iterator_category; - typedef _Val value_type; - typedef std::ptrdiff_t difference_type; - typedef std::size_t size_type; - typedef const _Val& reference; - typedef const _Val* pointer; - - const _Node* _M_cur; - const _Hashtable* _M_ht; - - _Hashtable_const_iterator(const _Node* __n, const _Hashtable* __tab) - : _M_cur(__n), _M_ht(__tab) { } - - _Hashtable_const_iterator() { } - - _Hashtable_const_iterator(const iterator& __it) - : _M_cur(__it._M_cur), _M_ht(__it._M_ht) { } - - reference operator*() const { return _M_cur->_M_val; } - - pointer operator->() const { return &(operator*()); } - - const_iterator& operator++(); - - const_iterator operator++(int); - - bool operator==(const const_iterator& __it) const { return _M_cur == __it._M_cur; } - - bool operator!=(const const_iterator& __it) const { return _M_cur != __it._M_cur; } - }; - - // Note: assumes long is at least 32 bits. - enum { _S_num_primes = 28 }; - - static const unsigned long __stl_prime_list[_S_num_primes] = - { - 53ul, 97ul, 193ul, 389ul, 769ul, - 1543ul, 3079ul, 6151ul, 12289ul, 24593ul, - 49157ul, 98317ul, 196613ul, 393241ul, 786433ul, - 1572869ul, 3145739ul, 6291469ul, 12582917ul, 25165843ul, - 50331653ul, 100663319ul, 201326611ul, 402653189ul, 805306457ul, - 1610612741ul, 3221225473ul, 4294967291ul - }; - - inline unsigned long - __stl_next_prime(unsigned long __n) - { - const unsigned long* __first = __stl_prime_list; - const unsigned long* __last = __stl_prime_list + (int)_S_num_primes; - const unsigned long* pos = std::lower_bound(__first, __last, __n); - return pos == __last ? *(__last - 1) : *pos; - } - - // Forward declaration of operator==. - template - class hashtable; - - template - bool operator==(const hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>& __ht1, - const hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>& __ht2); - - // Hashtables handle allocators a bit differently than other - // containers do. If we're using standard-conforming allocators, then - // a hashtable unconditionally has a member variable to hold its - // allocator, even if it so happens that all instances of the - // allocator type are identical. This is because, for hashtables, - // this extra storage is negligible. Additionally, a base class - // wouldn't serve any other purposes; it wouldn't, for example, - // simplify the exception-handling code. - template - class hashtable - { - public: - typedef _Key key_type; - typedef _Val value_type; - typedef _HashFcn hasher; - typedef _EqualKey key_equal; - - typedef std::size_t size_type; - typedef std::ptrdiff_t difference_type; - typedef value_type* pointer; - typedef const value_type* const_pointer; - typedef value_type& reference; - typedef const value_type& const_reference; - - hasher hash_funct() const { return _M_hash; } - - key_equal key_eq() const { return _M_equals; } - - private: - typedef _Hashtable_node<_Val> _Node; - - public: - typedef typename _Alloc::template rebind::other allocator_type; - allocator_type get_allocator() const { return _M_node_allocator; } - - private: - typedef typename _Alloc::template rebind<_Node>::other _Node_Alloc; - typedef typename _Alloc::template rebind<_Node*>::other _Nodeptr_Alloc; - typedef std::vector<_Node*, _Nodeptr_Alloc> _Vector_type; - - _Node_Alloc _M_node_allocator; - - _Node *_M_get_node() { return _M_node_allocator.allocate(1); } - - void _M_put_node(_Node* __p) { _M_node_allocator.deallocate(__p, 1); } - - private: - hasher _M_hash; - key_equal _M_equals; - _ExtractKey _M_get_key; - _Vector_type _M_buckets; - size_type _M_num_elements; - - public: - typedef _Hashtable_iterator<_Val, _Key, _HashFcn, _ExtractKey, - _EqualKey, _Alloc> - iterator; - typedef _Hashtable_const_iterator<_Val, _Key, _HashFcn, _ExtractKey, - _EqualKey, _Alloc> - const_iterator; - - friend struct - _Hashtable_iterator<_Val, _Key, _HashFcn, _ExtractKey, _EqualKey, _Alloc>; - - friend struct - _Hashtable_const_iterator<_Val, _Key, _HashFcn, _ExtractKey, - _EqualKey, _Alloc>; - - public: - hashtable(size_type __n, const _HashFcn& __hf, - const _EqualKey& __eql, const _ExtractKey& __ext, - const allocator_type& __a = allocator_type()) - : _M_node_allocator(__a), _M_hash(__hf), _M_equals(__eql), - _M_get_key(__ext), _M_buckets(__a), _M_num_elements(0) - { _M_initialize_buckets(__n); } - - hashtable(size_type __n, const _HashFcn& __hf, - const _EqualKey& __eql, - const allocator_type& __a = allocator_type()) - : _M_node_allocator(__a), _M_hash(__hf), _M_equals(__eql), - _M_get_key(_ExtractKey()), _M_buckets(__a), _M_num_elements(0) - { _M_initialize_buckets(__n); } - - hashtable(const hashtable& __ht) - : _M_node_allocator(__ht.get_allocator()), _M_hash(__ht._M_hash), - _M_equals(__ht._M_equals), _M_get_key(__ht._M_get_key), - _M_buckets(__ht.get_allocator()), _M_num_elements(0) - { _M_copy_from(__ht); } - - hashtable& operator= (const hashtable& __ht) - { - if (&__ht != this) - { - clear(); - _M_hash = __ht._M_hash; - _M_equals = __ht._M_equals; - _M_get_key = __ht._M_get_key; - _M_copy_from(__ht); - } - return *this; - } - - ~hashtable() - { clear(); } - - size_type size() const { return _M_num_elements; } - - size_type max_size() const { return size_type(-1); } - - bool empty() const { return size() == 0; } - - void swap(hashtable& __ht) - { - std::swap(_M_hash, __ht._M_hash); - std::swap(_M_equals, __ht._M_equals); - std::swap(_M_get_key, __ht._M_get_key); - _M_buckets.swap(__ht._M_buckets); - std::swap(_M_num_elements, __ht._M_num_elements); - } - - iterator begin() - { - for (size_type __n = 0; __n < _M_buckets.size(); ++__n) - if (_M_buckets[__n]) - return iterator(_M_buckets[__n], this); - return end(); - } - - iterator end() { return iterator(0, this); } - - const_iterator begin() const - { - for (size_type __n = 0; __n < _M_buckets.size(); ++__n) - if (_M_buckets[__n]) - return const_iterator(_M_buckets[__n], this); - return end(); - } - - const_iterator end() const { return const_iterator(0, this); } - - template - friend bool operator==(const hashtable<_Vl, _Ky, _HF, _Ex, _Eq, _Al>&, - const hashtable<_Vl, _Ky, _HF, _Ex, _Eq, _Al>&); - - public: - size_type bucket_count() const { return _M_buckets.size(); } - - size_type max_bucket_count() const { return __stl_prime_list[(int)_S_num_primes - 1]; } - - size_type elems_in_bucket(size_type __bucket) const - { - size_type __result = 0; - for (_Node* __n = _M_buckets[__bucket]; __n; __n = __n->_M_next) - __result += 1; - return __result; - } - - std::pair insert_unique(const value_type& __obj) - { - resize(_M_num_elements + 1); - return insert_unique_noresize(__obj); - } - - iterator insert_equal(const value_type& __obj) - { - resize(_M_num_elements + 1); - return insert_equal_noresize(__obj); - } - - std::pair insert_unique_noresize(const value_type& __obj); - - iterator insert_equal_noresize(const value_type& __obj); - - template - void insert_unique(_InputIterator __f, _InputIterator __l) - { insert_unique(__f, __l, __iterator_category(__f)); } - - template - void insert_equal(_InputIterator __f, _InputIterator __l) - { insert_equal(__f, __l, __iterator_category(__f)); } - - template - void insert_unique(_InputIterator __f, _InputIterator __l, - std::input_iterator_tag) - { - for ( ; __f != __l; ++__f) - insert_unique(*__f); - } - - template - void insert_equal(_InputIterator __f, _InputIterator __l, - std::input_iterator_tag) - { - for ( ; __f != __l; ++__f) - insert_equal(*__f); - } - - template - void insert_unique(_ForwardIterator __f, _ForwardIterator __l, - std::forward_iterator_tag) - { - size_type __n = std::distance(__f, __l); - resize(_M_num_elements + __n); - for ( ; __n > 0; --__n, ++__f) - insert_unique_noresize(*__f); - } - - template - void - insert_equal(_ForwardIterator __f, _ForwardIterator __l, - std::forward_iterator_tag) - { - size_type __n = std::distance(__f, __l); - resize(_M_num_elements + __n); - for ( ; __n > 0; --__n, ++__f) - insert_equal_noresize(*__f); - } - - reference find_or_insert(const value_type& __obj); - - iterator find(const key_type& __key) - { - size_type __n = _M_bkt_num_key(__key); - _Node* __first; - for (__first = _M_buckets[__n]; - __first && !_M_equals(_M_get_key(__first->_M_val), __key); - __first = __first->_M_next) - { } - return iterator(__first, this); - } - - const_iterator find(const key_type& __key) const - { - size_type __n = _M_bkt_num_key(__key); - const _Node* __first; - for (__first = _M_buckets[__n]; - __first && !_M_equals(_M_get_key(__first->_M_val), __key); - __first = __first->_M_next) - { } - return const_iterator(__first, this); - } - - size_type count(const key_type& __key) const - { - const size_type __n = _M_bkt_num_key(__key); - size_type __result = 0; - for (const _Node* __cur = _M_buckets[__n]; __cur; - __cur = __cur->_M_next) - if (_M_equals(_M_get_key(__cur->_M_val), __key)) - ++__result; - return __result; - } - - std::pair equal_range(const key_type& __key); - - std::pair equal_range(const key_type& __key) const; - - size_type erase(const key_type& __key); - - void erase(const iterator& __it); - - void erase(iterator __first, iterator __last); - - void erase(const const_iterator& __it); - - void erase(const_iterator __first, const_iterator __last); - - void resize(size_type __num_elements_hint); - - void clear(); - - private: - size_type _M_next_size(size_type __n) const { return __stl_next_prime(__n); } - - void _M_initialize_buckets(size_type __n) - { - const size_type __n_buckets = _M_next_size(__n); - _M_buckets.reserve(__n_buckets); - _M_buckets.insert(_M_buckets.end(), __n_buckets, (_Node*) 0); - _M_num_elements = 0; - } - - size_type _M_bkt_num_key(const key_type& __key) const - { return _M_bkt_num_key(__key, _M_buckets.size()); } - - size_type _M_bkt_num(const value_type& __obj) const - { return _M_bkt_num_key(_M_get_key(__obj)); } - - size_type _M_bkt_num_key(const key_type& __key, std::size_t __n) const - { return _M_hash(__key) % __n; } - - size_type _M_bkt_num(const value_type& __obj, std::size_t __n) const - { return _M_bkt_num_key(_M_get_key(__obj), __n); } - - _Node* _M_new_node(const value_type& __obj) - { - _Node* __n = _M_get_node(); - __n->_M_next = 0; - try - { - this->get_allocator().construct(&__n->_M_val, __obj); - return __n; - } - catch(...) - { - _M_put_node(__n); - throw; - } - } - - void _M_delete_node(_Node* __n) - { - this->get_allocator().destroy(&__n->_M_val); - _M_put_node(__n); - } - - void _M_erase_bucket(const size_type __n, _Node* __first, _Node* __last); - - void _M_erase_bucket(const size_type __n, _Node* __last); - - void _M_copy_from(const hashtable& __ht); - }; - - template - _Hashtable_iterator<_Val, _Key, _HF, _ExK, _EqK, _All>& - _Hashtable_iterator<_Val, _Key, _HF, _ExK, _EqK, _All>:: - operator++() - { - const _Node* __old = _M_cur; - _M_cur = _M_cur->_M_next; - if (!_M_cur) - { - size_type __bucket = _M_ht->_M_bkt_num(__old->_M_val); - while (!_M_cur && ++__bucket < _M_ht->_M_buckets.size()) - _M_cur = _M_ht->_M_buckets[__bucket]; - } - return *this; - } - - template - inline _Hashtable_iterator<_Val, _Key, _HF, _ExK, _EqK, _All> - _Hashtable_iterator<_Val, _Key, _HF, _ExK, _EqK, _All>:: - operator++(int) - { - iterator __tmp = *this; - ++*this; - return __tmp; - } - - template - _Hashtable_const_iterator<_Val, _Key, _HF, _ExK, _EqK, _All>& - _Hashtable_const_iterator<_Val, _Key, _HF, _ExK, _EqK, _All>:: - operator++() - { - const _Node* __old = _M_cur; - _M_cur = _M_cur->_M_next; - if (!_M_cur) - { - size_type __bucket = _M_ht->_M_bkt_num(__old->_M_val); - while (!_M_cur && ++__bucket < _M_ht->_M_buckets.size()) - _M_cur = _M_ht->_M_buckets[__bucket]; - } - return *this; - } - - template - inline _Hashtable_const_iterator<_Val, _Key, _HF, _ExK, _EqK, _All> - _Hashtable_const_iterator<_Val, _Key, _HF, _ExK, _EqK, _All>:: - operator++(int) - { - const_iterator __tmp = *this; - ++*this; - return __tmp; - } - - template - bool operator==(const hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>& __ht1, - const hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>& __ht2) - { - typedef typename hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>::_Node _Node; - - if (__ht1._M_buckets.size() != __ht2._M_buckets.size()) - return false; - - for (std::size_t __n = 0; __n < __ht1._M_buckets.size(); ++__n) - { - _Node* __cur1 = __ht1._M_buckets[__n]; - _Node* __cur2 = __ht2._M_buckets[__n]; - // Check same length of lists - for (; __cur1 && __cur2; - __cur1 = __cur1->_M_next, __cur2 = __cur2->_M_next) - { } - if (__cur1 || __cur2) - return false; - // Now check one's elements are in the other - for (__cur1 = __ht1._M_buckets[__n] ; __cur1; - __cur1 = __cur1->_M_next) - { - bool _found__cur1 = false; - for (__cur2 = __ht2._M_buckets[__n]; - __cur2; __cur2 = __cur2->_M_next) - { - if (__cur1->_M_val == __cur2->_M_val) - { - _found__cur1 = true; - break; - } - } - if (!_found__cur1) - return false; - } - } - return true; - } - - template - inline bool operator!=(const hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>& __ht1, - const hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>& __ht2) - { return !(__ht1 == __ht2); } - - template - inline void swap(hashtable<_Val, _Key, _HF, _Extract, _EqKey, _All>& __ht1, - hashtable<_Val, _Key, _HF, _Extract, _EqKey, _All>& __ht2) - { __ht1.swap(__ht2); } - - template - std::pair::iterator, bool> - hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>:: - insert_unique_noresize(const value_type& __obj) - { - const size_type __n = _M_bkt_num(__obj); - _Node* __first = _M_buckets[__n]; - - for (_Node* __cur = __first; __cur; __cur = __cur->_M_next) - if (_M_equals(_M_get_key(__cur->_M_val), _M_get_key(__obj))) - return std::pair(iterator(__cur, this), false); - - _Node* __tmp = _M_new_node(__obj); - __tmp->_M_next = __first; - _M_buckets[__n] = __tmp; - ++_M_num_elements; - return std::pair(iterator(__tmp, this), true); - } - - template - typename hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>::iterator - hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>:: - insert_equal_noresize(const value_type& __obj) - { - const size_type __n = _M_bkt_num(__obj); - _Node* __first = _M_buckets[__n]; - - for (_Node* __cur = __first; __cur; __cur = __cur->_M_next) - if (_M_equals(_M_get_key(__cur->_M_val), _M_get_key(__obj))) - { - _Node* __tmp = _M_new_node(__obj); - __tmp->_M_next = __cur->_M_next; - __cur->_M_next = __tmp; - ++_M_num_elements; - return iterator(__tmp, this); - } - - _Node* __tmp = _M_new_node(__obj); - __tmp->_M_next = __first; - _M_buckets[__n] = __tmp; - ++_M_num_elements; - return iterator(__tmp, this); - } - - template - typename hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>::reference - hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>:: - find_or_insert(const value_type& __obj) - { - resize(_M_num_elements + 1); - - size_type __n = _M_bkt_num(__obj); - _Node* __first = _M_buckets[__n]; - - for (_Node* __cur = __first; __cur; __cur = __cur->_M_next) - if (_M_equals(_M_get_key(__cur->_M_val), _M_get_key(__obj))) - return __cur->_M_val; - - _Node* __tmp = _M_new_node(__obj); - __tmp->_M_next = __first; - _M_buckets[__n] = __tmp; - ++_M_num_elements; - return __tmp->_M_val; - } - - template - std::pair::iterator, - typename hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>::iterator> - hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>::equal_range(const key_type& __key) - { - typedef std::pair _Pii; - const size_type __n = _M_bkt_num_key(__key); - - for (_Node* __first = _M_buckets[__n]; __first; - __first = __first->_M_next) - if (_M_equals(_M_get_key(__first->_M_val), __key)) - { - for (_Node* __cur = __first->_M_next; __cur; - __cur = __cur->_M_next) - if (!_M_equals(_M_get_key(__cur->_M_val), __key)) - return _Pii(iterator(__first, this), iterator(__cur, this)); - for (size_type __m = __n + 1; __m < _M_buckets.size(); ++__m) - if (_M_buckets[__m]) - return _Pii(iterator(__first, this), - iterator(_M_buckets[__m], this)); - return _Pii(iterator(__first, this), end()); - } - return _Pii(end(), end()); - } - - template - std::pair::const_iterator, - typename hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>::const_iterator> - hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>::equal_range(const key_type& __key) const - { - typedef std::pair _Pii; - const size_type __n = _M_bkt_num_key(__key); - - for (const _Node* __first = _M_buckets[__n]; __first; - __first = __first->_M_next) - { - if (_M_equals(_M_get_key(__first->_M_val), __key)) - { - for (const _Node* __cur = __first->_M_next; __cur; - __cur = __cur->_M_next) - if (!_M_equals(_M_get_key(__cur->_M_val), __key)) - return _Pii(const_iterator(__first, this), - const_iterator(__cur, this)); - for (size_type __m = __n + 1; __m < _M_buckets.size(); ++__m) - if (_M_buckets[__m]) - return _Pii(const_iterator(__first, this), - const_iterator(_M_buckets[__m], this)); - return _Pii(const_iterator(__first, this), end()); - } - } - return _Pii(end(), end()); - } - - template - typename hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>::size_type - hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>::erase(const key_type& __key) - { - const size_type __n = _M_bkt_num_key(__key); - _Node* __first = _M_buckets[__n]; - size_type __erased = 0; - - if (__first) - { - _Node* __cur = __first; - _Node* __next = __cur->_M_next; - while (__next) - { - if (_M_equals(_M_get_key(__next->_M_val), __key)) - { - __cur->_M_next = __next->_M_next; - _M_delete_node(__next); - __next = __cur->_M_next; - ++__erased; - --_M_num_elements; - } - else - { - __cur = __next; - __next = __cur->_M_next; - } - } - if (_M_equals(_M_get_key(__first->_M_val), __key)) - { - _M_buckets[__n] = __first->_M_next; - _M_delete_node(__first); - ++__erased; - --_M_num_elements; - } - } - return __erased; - } - - template - void hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>::erase(const iterator& __it) - { - _Node* __p = __it._M_cur; - if (__p) - { - const size_type __n = _M_bkt_num(__p->_M_val); - _Node* __cur = _M_buckets[__n]; - if (__cur == __p) - { - _M_buckets[__n] = __cur->_M_next; - _M_delete_node(__cur); - --_M_num_elements; - } - else - { - _Node* __next = __cur->_M_next; - while (__next) - { - if (__next == __p) - { - __cur->_M_next = __next->_M_next; - _M_delete_node(__next); - --_M_num_elements; - break; - } - else - { - __cur = __next; - __next = __cur->_M_next; - } - } - } - } - } - - template - void hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>::erase(iterator __first, iterator __last) - { - size_type __f_bucket = __first._M_cur ? _M_bkt_num(__first._M_cur->_M_val) : _M_buckets.size(); - - size_type __l_bucket = __last._M_cur ? _M_bkt_num(__last._M_cur->_M_val) : _M_buckets.size(); - - if (__first._M_cur == __last._M_cur) - return; - else if (__f_bucket == __l_bucket) - _M_erase_bucket(__f_bucket, __first._M_cur, __last._M_cur); - else - { - _M_erase_bucket(__f_bucket, __first._M_cur, 0); - for (size_type __n = __f_bucket + 1; __n < __l_bucket; ++__n) - _M_erase_bucket(__n, 0); - if (__l_bucket != _M_buckets.size()) - _M_erase_bucket(__l_bucket, __last._M_cur); - } - } - - template - inline void - hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>:: - erase(const_iterator __first, const_iterator __last) - { - erase(iterator(const_cast<_Node*>(__first._M_cur), - const_cast(__first._M_ht)), - iterator(const_cast<_Node*>(__last._M_cur), - const_cast(__last._M_ht))); - } - - template - inline void hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>::erase(const const_iterator& __it) - { erase(iterator(const_cast<_Node*>(__it._M_cur), const_cast(__it._M_ht))); } - - template - void hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>::resize(size_type __num_elements_hint) - { - const size_type __old_n = _M_buckets.size(); - if (__num_elements_hint > __old_n) - { - const size_type __n = _M_next_size(__num_elements_hint); - if (__n > __old_n) - { - _Vector_type __tmp(__n, (_Node*)(0), _M_buckets.get_allocator()); - try - { - for (size_type __bucket = 0; __bucket < __old_n; ++__bucket) - { - _Node* __first = _M_buckets[__bucket]; - while (__first) - { - size_type __new_bucket = _M_bkt_num(__first->_M_val,__n); - _M_buckets[__bucket] = __first->_M_next; - __first->_M_next = __tmp[__new_bucket]; - __tmp[__new_bucket] = __first; - __first = _M_buckets[__bucket]; - } - } - _M_buckets.swap(__tmp); - } - catch(...) - { - for (size_type __bucket = 0; __bucket < __tmp.size();++__bucket) - { - while (__tmp[__bucket]) - { - _Node* __next = __tmp[__bucket]->_M_next; - _M_delete_node(__tmp[__bucket]); - __tmp[__bucket] = __next; - } - } - throw; - } - } - } - } - - template - void hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>::_M_erase_bucket(const size_type __n, _Node* __first, _Node* __last) - { - _Node* __cur = _M_buckets[__n]; - if (__cur == __first) - _M_erase_bucket(__n, __last); - else - { - _Node* __next; - for (__next = __cur->_M_next; - __next != __first; - __cur = __next, __next = __cur->_M_next) - ; - while (__next != __last) - { - __cur->_M_next = __next->_M_next; - _M_delete_node(__next); - __next = __cur->_M_next; - --_M_num_elements; - } - } - } - - template - void hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>::_M_erase_bucket(const size_type __n, _Node* __last) - { - _Node* __cur = _M_buckets[__n]; - while (__cur != __last) - { - _Node* __next = __cur->_M_next; - _M_delete_node(__cur); - __cur = __next; - _M_buckets[__n] = __cur; - --_M_num_elements; - } - } - - template - void hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>::clear() - { - for (size_type __i = 0; __i < _M_buckets.size(); ++__i) - { - _Node* __cur = _M_buckets[__i]; - while (__cur != 0) - { - _Node* __next = __cur->_M_next; - _M_delete_node(__cur); - __cur = __next; - } - _M_buckets[__i] = 0; - } - _M_num_elements = 0; - } - - template - void hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>::_M_copy_from(const hashtable& __ht) - { - _M_buckets.clear(); - _M_buckets.reserve(__ht._M_buckets.size()); - _M_buckets.insert(_M_buckets.end(), __ht._M_buckets.size(), (_Node*) 0); - try - { - for (size_type __i = 0; __i < __ht._M_buckets.size(); ++__i) { - const _Node* __cur = __ht._M_buckets[__i]; - if (__cur) - { - _Node* __local_copy = _M_new_node(__cur->_M_val); - _M_buckets[__i] = __local_copy; - for (_Node* __next = __cur->_M_next; - __next; - __cur = __next, __next = __cur->_M_next) - { - __local_copy->_M_next = _M_new_node(__next->_M_val); - __local_copy = __local_copy->_M_next; - } - } - } - _M_num_elements = __ht._M_num_elements; - } - catch(...) - { - clear(); - throw; - } - } -} - -#endif diff --git a/src/INTERP_KERNEL/Bases/InterpKernelStlExt.hxx b/src/INTERP_KERNEL/Bases/InterpKernelStlExt.hxx deleted file mode 100644 index 162cc7871..000000000 --- a/src/INTERP_KERNEL/Bases/InterpKernelStlExt.hxx +++ /dev/null @@ -1,43 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 -// 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 __INTERPKERNELSTLEXT_HXX__ -#define __INTERPKERNELSTLEXT_HXX__ - -#include - -namespace INTERP_KERNEL -{ - namespace STLEXT - { - template - struct Select1st : public std::unary_function<_Pair, typename _Pair::first_type> - { - typename _Pair::first_type& operator()(_Pair& __x) const { return __x.first; } - const typename _Pair::first_type&operator()(const _Pair& __x) const { return __x.first; } - }; - - template - inline void Construct(_T1* __p, const _T2& __value__) { ::new(static_cast(__p)) _T1(__value__); } - - template inline void Destroy(_Tp* __pointer) { __pointer->~_Tp(); } - } -} - -#endif diff --git a/src/INTERP_KERNEL/Bases/NormalizedGeometricTypes b/src/INTERP_KERNEL/Bases/NormalizedGeometricTypes deleted file mode 100644 index b02d2cb72..000000000 --- a/src/INTERP_KERNEL/Bases/NormalizedGeometricTypes +++ /dev/null @@ -1,70 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 -// 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 __NORMALIZEDGEOMETRICTYPES__ -#define __NORMALIZEDGEOMETRICTYPES__ - -namespace INTERP_KERNEL -{ - typedef enum - { - NORM_POINT1 = 0, - NORM_SEG2 = 1, - NORM_SEG3 = 2, - NORM_SEG4 = 10, - NORM_POLYL = 33, - NORM_TRI3 = 3, - NORM_QUAD4 = 4, - NORM_POLYGON = 5, - NORM_TRI6 = 6, - NORM_TRI7 = 7, - NORM_QUAD8 = 8, - NORM_QUAD9 = 9, - NORM_QPOLYG = 32, - // - NORM_TETRA4 = 14, - NORM_PYRA5 = 15, - NORM_PENTA6 = 16, - NORM_HEXA8 = 18, - NORM_TETRA10 = 20, - NORM_HEXGP12 = 22, - NORM_PYRA13 = 23, - NORM_PENTA15 = 25, - NORM_HEXA20 = 30, - NORM_HEXA27 = 27, - NORM_POLYHED = 31, - NORM_ERROR = 40, - 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. - * - * The images below illustrates the policies in their respective order. - * - * \image html tetra_simplexize_5_6.jpg - * \image html tetra_simplexize_24_48.jpg - */ - typedef enum { PLANAR_FACE_5 = 5, PLANAR_FACE_6 = 6, GENERAL_24 = 24, GENERAL_48 = 48 } SplittingPolicy; -} - -#endif diff --git a/src/INTERP_KERNEL/Bases/NormalizedUnstructuredMesh.hxx b/src/INTERP_KERNEL/Bases/NormalizedUnstructuredMesh.hxx deleted file mode 100644 index 26732f94b..000000000 --- a/src/INTERP_KERNEL/Bases/NormalizedUnstructuredMesh.hxx +++ /dev/null @@ -1,35 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 -// 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 __NORMALIZEDUNSTRUCTUREDMESH_HXX__ -#define __NORMALIZEDUNSTRUCTUREDMESH_HXX__ - -#include "NormalizedGeometricTypes" - -namespace INTERP_KERNEL -{ - typedef enum - { - ALL_C_MODE , - ALL_FORTRAN_MODE - } NumberingPolicy; -} - -#endif diff --git a/src/INTERP_KERNEL/BoundingBox.cxx b/src/INTERP_KERNEL/BoundingBox.cxx deleted file mode 100644 index de2748b7a..000000000 --- a/src/INTERP_KERNEL/BoundingBox.cxx +++ /dev/null @@ -1,165 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// - -#include "BoundingBox.hxx" - -#include -#include -#include - -namespace INTERP_KERNEL -{ - - /** - * Constructor creating box from an array of the points corresponding - * to the vertices of the element. - * Each point is represented by an array of three doubles. - * - * @param pts array of points - * @param numPts number of vertices - * - */ - BoundingBox::BoundingBox(const double** pts, const unsigned numPts) - :_coords(new double[6]) - { - assert(numPts > 1); - - // initialize with first two points - const double* pt1 = pts[0]; - const double* pt2 = pts[1]; - - for(BoxCoord c = XMIN ; c <= ZMIN ; c = BoxCoord(c + 1)) - { - _coords[c] = std::min(pt1[c], pt2[c]); - _coords[c + 3] = std::max(pt1[c], pt2[c]); - } - - for(unsigned i = 2 ; i < numPts ; ++i) - { - updateWithPoint(pts[i]); - } - - assert(isValid()); - } - - /** - * Constructor creating box from union of two boxes, resulting in a box that encloses both of them - * - * @param box1 the first box - * @param box2 the second box - */ - BoundingBox::BoundingBox(const BoundingBox& box1, const BoundingBox& box2) - : _coords(new double[6]) - { - assert(_coords != 0); - - for(BoxCoord c = XMIN ; c <= ZMIN ; c = BoxCoord(c + 1)) - { - _coords[c] = std::min(box1._coords[c], box2._coords[c]); - _coords[c + 3] = std::max(box1._coords[c + 3], box2._coords[c + 3]); - } - - assert(isValid()); - } - - /** - * Destructor - * - */ - BoundingBox::~BoundingBox() - { - delete[] _coords; - } - - /** - * Determines if the intersection with a given box is empty - * - * @param box BoundingBox with which intersection is tested - * @return true if intersection between boxes is empty, false if not - */ - bool BoundingBox::isDisjointWith(const BoundingBox& box) const - { - for(BoxCoord c = XMIN ; c <= ZMIN ; c = BoxCoord(c + 1)) - { - const double otherMinCoord = box.getCoordinate(c); - const double otherMaxCoord = box.getCoordinate(BoxCoord(c + 3)); - - // boxes are disjoint if there exists a direction in which the - // minimum coordinate of one is greater than the maximum coordinate of the other - - // more stable version ? - // const double tol = 1.0e-2*_coords[c]; - // if(_coords[c] > otherMaxCoord + tol - // || _coords[c + 3] < otherMinCoord - tol) - - - if(_coords[c] > otherMaxCoord - || _coords[c + 3] < otherMinCoord) - - { - return true; - } - - } - return false; - } - - - - /** - * Updates the bounding box to include a given point - * - * @param pt point to be included - * - */ - void BoundingBox::updateWithPoint(const double* pt) - { - for(BoxCoord c = XMIN ; c <= ZMIN ; c = BoxCoord(c + 1)) - { - const double ptVal = pt[c]; - - // update min and max coordinates - _coords[c] = std::min(_coords[c], ptVal); - _coords[c + 3] = std::max(_coords[c + 3], ptVal); - - } - } - - /** - * Checks if the box is valid, which it is if its minimum coordinates are - * smaller than its maximum coordinates in all directions. - * - * @return true if the box is valid, false if not - */ - bool BoundingBox::isValid() const - { - bool valid = true; - for(BoxCoord c = XMIN ; c < ZMIN ; c = BoxCoord(c + 1)) - { - if(_coords[c] > _coords[c + 3]) - { - std::cout << "+++ Error in BoundingBox |: coordinate " << c << " is invalid : " - <<_coords[c] << " > " << _coords[c+3] << std::endl; - valid = false; - } - } - return valid; - } - -} diff --git a/src/INTERP_KERNEL/BoundingBox.hxx b/src/INTERP_KERNEL/BoundingBox.hxx deleted file mode 100644 index 02c2ce9a1..000000000 --- a/src/INTERP_KERNEL/BoundingBox.hxx +++ /dev/null @@ -1,110 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 -// 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 __BOUNDINGBOX_HXX__ -#define __BOUNDINGBOX_HXX__ - -#include "INTERPKERNELDefines.hxx" -#include - -namespace INTERP_KERNEL -{ - - /** - * \brief Class representing the bounding box of a number of points. - * - */ - class INTERPKERNEL_EXPORT BoundingBox - { - public: - - /// Enumeration representing the six coordinates that define the bounding box - enum BoxCoord { XMIN = 0, YMIN = 1, ZMIN = 2, XMAX = 3, YMAX = 4, ZMAX = 5 }; - - BoundingBox(const double** pts, const unsigned numPts); - - BoundingBox(const BoundingBox& box1, const BoundingBox& box2); - - ~BoundingBox(); - - bool isDisjointWith(const BoundingBox& box) const; - - inline void setCoordinate(const BoxCoord coord, double value); - - inline double getCoordinate(const BoxCoord coord) const; - - void updateWithPoint(const double* pt); - - inline void dumpCoords() const; - - private: - - bool isValid() const; - - /// disallow copying - BoundingBox(const BoundingBox& box); - - /// disallow assignment - BoundingBox& operator=(const BoundingBox& box); - - /// Vector containing the coordinates of the box - /// interlaced in the order XMIN, YMIN, ZMIN, XMAX, YMAX, ZMAX - double* _coords; - - }; - - /** - * Sets a coordinate of the box to a given value. - * - * @param coord coordinate to set - * @param value new value for coordinate - * - */ - inline void BoundingBox::setCoordinate(const BoxCoord coord, double value) - { - _coords[coord] = value; - } - - /** - * Gets a coordinate of the box - * - * @param coord coordinate to get - * @return value of coordinate - * - */ - inline double BoundingBox::getCoordinate(const BoxCoord coord) const - { - return _coords[coord]; - } - - /** - * Prints the coordinates of the box to std::cout - * - */ - inline void BoundingBox::dumpCoords() const - { - std::cout << "[xmin, xmax] = [" << _coords[XMIN] << ", " << _coords[XMAX] << "]" << " | "; - std::cout << "[ymin, ymax] = [" << _coords[YMIN] << ", " << _coords[YMAX] << "]" << " | "; - std::cout << "[zmin, zmax] = [" << _coords[ZMIN] << ", " << _coords[ZMAX] << "]"; - std::cout << std::endl; - } - -} - -#endif diff --git a/src/INTERP_KERNEL/BoxSplittingOptions.cxx b/src/INTERP_KERNEL/BoxSplittingOptions.cxx deleted file mode 100644 index a23a6b7e3..000000000 --- a/src/INTERP_KERNEL/BoxSplittingOptions.cxx +++ /dev/null @@ -1,47 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 -// 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 - -#include "BoxSplittingOptions.hxx" - -#include - -const double INTERP_KERNEL::BoxSplittingOptions::DFT_EFFICIENCY_GOAL=0.5; - -const double INTERP_KERNEL::BoxSplittingOptions::DFT_EFFICIENCY_THRESHOLD=0.7; - -void INTERP_KERNEL::BoxSplittingOptions::init() -{ - _efficiency_goal=DFT_EFFICIENCY_GOAL; - _efficiency_threshold=DFT_EFFICIENCY_THRESHOLD; - _min_patch_length=DFT_MIN_PATCH_LENGTH; - _max_patch_length=DFT_MAX_PATCH_LENGTH; - _max_nb_cells_in_patch=DFT_MAX_PATCH_MEASURE; -} - -std::string INTERP_KERNEL::BoxSplittingOptions::printOptions() const -{ - std::ostringstream oss; - oss << "Efficiency goal: " << 100*_efficiency_goal << "%" << std::endl; - oss << "Efficiency threshold: " << 100*_efficiency_threshold << "%" << std::endl; - oss << "Min. patch side length: " << _min_patch_length << std::endl; - oss << "Max. patch side length: " << _max_patch_length << std::endl; - oss << "Max. patch measure: " << _max_nb_cells_in_patch << std::endl; - return oss.str(); -} diff --git a/src/INTERP_KERNEL/BoxSplittingOptions.hxx b/src/INTERP_KERNEL/BoxSplittingOptions.hxx deleted file mode 100644 index 0834430ef..000000000 --- a/src/INTERP_KERNEL/BoxSplittingOptions.hxx +++ /dev/null @@ -1,68 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 -// 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 - -#ifndef __BOXSPLITTINGOPTIONS_HXX__ -#define __BOXSPLITTINGOPTIONS_HXX__ - -#include "INTERPKERNELDefines.hxx" - -#include - -namespace INTERP_KERNEL -{ - /*! - * \class BoxSplittingOptions - * Class defining the options for box splitting used for AMR algorithm like creation of patches following a criterion. - */ - class INTERPKERNEL_EXPORT BoxSplittingOptions - { - private: - double _efficiency_goal; - double _efficiency_threshold; - int _min_patch_length; - int _max_patch_length; - int _max_nb_cells_in_patch; - public: - BoxSplittingOptions() { init(); } - void init(); - double getEfficiencyGoal() const { return _efficiency_goal; } - void setEfficiencyGoal(double efficiency) { _efficiency_goal=efficiency; } - double getEfficiencyThreshold() const { return _efficiency_threshold; } - void setEfficiencyThreshold(double efficiencyThreshold) { _efficiency_threshold=efficiencyThreshold; } - int getMinimumPatchLength() const { return _min_patch_length; } - void setMinimumPatchLength(int minPatchLength) { _min_patch_length=minPatchLength; } - int getMaximumPatchLength() const { return _max_patch_length; } - void setMaximumPatchLength(int maxNbCellPatch) { _max_patch_length=maxNbCellPatch; } - int getMaximumNbOfCellsInPatch() const { return _max_nb_cells_in_patch; } - void setMaximumNbOfCellsInPatch(int maxNbCellsInPatch) { _max_nb_cells_in_patch=maxNbCellsInPatch; } - void copyOptions(const BoxSplittingOptions & other) { *this=other; } - std::string printOptions() const; - private: - static const int DFT_MIN_PATCH_LENGTH=1; - static const int DFT_MAX_PATCH_LENGTH=2147483647; - static const int DFT_MAX_PATCH_MEASURE=2147483647; - static const double DFT_EFFICIENCY_GOAL; - static const double DFT_EFFICIENCY_THRESHOLD; - public: - static const char PRECISION_STR[]; - }; -} - -#endif diff --git a/src/INTERP_KERNEL/CMakeLists.txt b/src/INTERP_KERNEL/CMakeLists.txt deleted file mode 100644 index 1fe07853b..000000000 --- a/src/INTERP_KERNEL/CMakeLists.txt +++ /dev/null @@ -1,88 +0,0 @@ -# Copyright (C) 2012-2015 CEA/DEN, EDF 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, 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 -# 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) - -SET(interpkernel_SOURCES - TransformedTriangle.cxx - TransformedTriangleIntersect.cxx - TransformedTriangleMath.cxx - BoundingBox.cxx - TranslationRotationMatrix.cxx - TetraAffineTransform.cxx - CellModel.cxx - DiameterCalculator.cxx - UnitTetraIntersectionBary.cxx - InterpolationOptions.cxx - BoxSplittingOptions.cxx - DirectedBoundingBox.cxx - Interpolation2DCurve.cxx - Interpolation3DSurf.cxx - Interpolation3D.cxx - Interpolation3D2D.cxx - MeshElement.cxx - InterpKernelMeshQuality.cxx - InterpKernelCellSimplify.cxx - InterpKernelMatrixTools.cxx - VolSurfUser.cxx - SplitterTetra.cxx - Bases/InterpKernelException.cxx - Geometric2D/InterpKernelGeo2DAbstractEdge.cxx - Geometric2D/InterpKernelGeo2DBounds.cxx - Geometric2D/InterpKernelGeo2DPrecision.cxx - Geometric2D/InterpKernelGeo2DComposedEdge.cxx - Geometric2D/InterpKernelGeo2DEdgeArcCircle.cxx - Geometric2D/InterpKernelGeo2DEdge.cxx - Geometric2D/InterpKernelGeo2DEdgeInfLin.cxx - Geometric2D/InterpKernelGeo2DEdgeLin.cxx - Geometric2D/InterpKernelGeo2DElementaryEdge.cxx - Geometric2D/InterpKernelGeo2DNode.cxx - Geometric2D/InterpKernelGeo2DQuadraticPolygon.cxx - ExprEval/InterpKernelExprParser.cxx - ExprEval/InterpKernelFunction.cxx - ExprEval/InterpKernelUnit.cxx - ExprEval/InterpKernelValue.cxx - ExprEval/InterpKernelAsmX86.cxx - GaussPoints/InterpKernelGaussCoords.cxx - ) - -INCLUDE_DIRECTORIES( - ${CMAKE_CURRENT_SOURCE_DIR} - ${CMAKE_CURRENT_SOURCE_DIR}/Bases - ${CMAKE_CURRENT_SOURCE_DIR}/Geometric2D - ${CMAKE_CURRENT_SOURCE_DIR}/ExprEval - ${CMAKE_CURRENT_SOURCE_DIR}/GaussPoints - ) - -SET(PLATFORM_MMAP) -IF(NOT WIN32) - SET(PLATFORM_MMAP "-D_POSIX_MAPPED_FILES") -ENDIF(NOT WIN32) - -ADD_LIBRARY(interpkernel SHARED ${interpkernel_SOURCES}) -SET_TARGET_PROPERTIES(interpkernel PROPERTIES COMPILE_FLAGS "${PLATFORM_MMAP}") -TARGET_LINK_LIBRARIES(interpkernel ${PLATFORM_LIBS}) -INSTALL(TARGETS interpkernel EXPORT ${PROJECT_NAME}TargetGroup DESTINATION ${SALOME_INSTALL_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} Bases/NormalizedGeometricTypes DESTINATION ${SALOME_INSTALL_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 deleted file mode 100644 index d3e364196..000000000 --- a/src/INTERP_KERNEL/CellModel.cxx +++ /dev/null @@ -1,889 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 -// 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 "CellModel.hxx" - -#include "InterpKernelException.hxx" -#include "DiameterCalculator.hxx" - -#include -#include -#include -#include - -namespace INTERP_KERNEL -{ - const char *CellModel::CELL_TYPES_REPR[]={"NORM_POINT1", "NORM_SEG2", "NORM_SEG3", "NORM_TRI3", "NORM_QUAD4",// 0->4 - "NORM_POLYGON", "NORM_TRI6", "NORM_TRI7" , "NORM_QUAD8", "NORM_QUAD9",//5->9 - "NORM_SEG4", "", "", "", "NORM_TETRA4",//10->14 - "NORM_PYRA5", "NORM_PENTA6", "", "NORM_HEXA8", "",//15->19 - "NORM_TETRA10", "", "NORM_HEXGP12", "NORM_PYRA13", "",//20->24 - "NORM_PENTA15", "", "NORM_HEXA27", "", "",//25->29 - "NORM_HEXA20", "NORM_POLYHED", "NORM_QPOLYG", "NORM_POLYL", "",//30->34 - "", "", "", "", "",//35->39 - "NORM_ERROR"}; - - std::map CellModel::_map_of_unique_instance; - - const CellModel& CellModel::GetCellModel(NormalizedCellType type) - { - if(_map_of_unique_instance.empty()) - buildUniqueInstance(); - const std::map::iterator iter=_map_of_unique_instance.find(type); - if(iter==_map_of_unique_instance.end()) - { - std::ostringstream stream; stream << "no cellmodel for normalized type " << type; - throw Exception(stream.str().c_str()); - } - return (*iter).second; - } - - const char *CellModel::getRepr() const - { - return CELL_TYPES_REPR[(int)_type]; - } - - /*! - * This method is compatible with all types including dynamic one. - */ - bool CellModel::isCompatibleWith(NormalizedCellType type) const - { - if(_type==type) - return true; - const CellModel& other=GetCellModel(type); - if(_dim!=other.getDimension()) - return false; - bool b1=isQuadratic(); - bool b2=other.isQuadratic(); - if((b1 && !b2) || (!b1 && b2)) - return false; - b1=isDynamic(); - b2=other.isDynamic(); - return b1 || b2; - } - - void CellModel::buildUniqueInstance() - { - _map_of_unique_instance.insert(std::make_pair(NORM_POINT1,CellModel(NORM_POINT1))); - _map_of_unique_instance.insert(std::make_pair(NORM_SEG2,CellModel(NORM_SEG2))); - _map_of_unique_instance.insert(std::make_pair(NORM_SEG3,CellModel(NORM_SEG3))); - _map_of_unique_instance.insert(std::make_pair(NORM_SEG4,CellModel(NORM_SEG4))); - _map_of_unique_instance.insert(std::make_pair(NORM_TRI3,CellModel(NORM_TRI3))); - _map_of_unique_instance.insert(std::make_pair(NORM_QUAD4,CellModel(NORM_QUAD4))); - _map_of_unique_instance.insert(std::make_pair(NORM_TRI6,CellModel(NORM_TRI6))); - _map_of_unique_instance.insert(std::make_pair(NORM_TRI7,CellModel(NORM_TRI7))); - _map_of_unique_instance.insert(std::make_pair(NORM_QUAD8,CellModel(NORM_QUAD8))); - _map_of_unique_instance.insert(std::make_pair(NORM_QUAD9,CellModel(NORM_QUAD9))); - _map_of_unique_instance.insert(std::make_pair(NORM_TETRA4,CellModel(NORM_TETRA4))); - _map_of_unique_instance.insert(std::make_pair(NORM_HEXA8,CellModel(NORM_HEXA8))); - _map_of_unique_instance.insert(std::make_pair(NORM_PYRA5,CellModel(NORM_PYRA5))); - _map_of_unique_instance.insert(std::make_pair(NORM_PENTA6,CellModel(NORM_PENTA6))); - _map_of_unique_instance.insert(std::make_pair(NORM_TETRA10,CellModel(NORM_TETRA10))); - _map_of_unique_instance.insert(std::make_pair(NORM_HEXGP12,CellModel(NORM_HEXGP12))); - _map_of_unique_instance.insert(std::make_pair(NORM_PYRA13,CellModel(NORM_PYRA13))); - _map_of_unique_instance.insert(std::make_pair(NORM_PENTA15,CellModel(NORM_PENTA15))); - _map_of_unique_instance.insert(std::make_pair(NORM_HEXA20,CellModel(NORM_HEXA20))); - _map_of_unique_instance.insert(std::make_pair(NORM_HEXA27,CellModel(NORM_HEXA27))); - _map_of_unique_instance.insert(std::make_pair(NORM_POLYGON,CellModel(NORM_POLYGON))); - _map_of_unique_instance.insert(std::make_pair(NORM_POLYHED,CellModel(NORM_POLYHED))); - _map_of_unique_instance.insert(std::make_pair(NORM_QPOLYG,CellModel(NORM_QPOLYG))); - _map_of_unique_instance.insert(std::make_pair(NORM_POLYL,CellModel(NORM_POLYL))); - _map_of_unique_instance.insert(std::make_pair(NORM_ERROR,CellModel(NORM_ERROR))); - } - - CellModel::CellModel(NormalizedCellType type):_type(type) - { - _is_extruded=false; - _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: - { - _nb_of_pts=1; _nb_of_sons=0; _dim=0; _extruded_type=NORM_SEG2; _is_simplex=true; - } - break; - case NORM_SEG2: - { - _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; - } - break; - case NORM_SEG3: - { - _nb_of_pts=3; _nb_of_sons=3; _dim=1; _extruded_type=NORM_QUAD8; _linear_type=NORM_SEG2; _quadratic=true; _is_simplex=false; - _sons_type[0]=NORM_POINT1; _sons_type[1]=NORM_POINT1; _sons_type[2]=NORM_POINT1; - _sons_con[0][0]=0; _nb_of_sons_con[0]=1; - _sons_con[1][0]=1; _nb_of_sons_con[1]=1; - _sons_con[2][0]=2; _nb_of_sons_con[2]=1; - } - break; - case NORM_SEG4: - { - _nb_of_pts=4; _nb_of_sons=4; _dim=1; _linear_type=NORM_SEG2; _quadratic=true; _is_simplex=false; // no _extruded_type because no cubic 2D cell - _sons_type[0]=NORM_POINT1; _sons_type[1]=NORM_POINT1; _sons_type[2]=NORM_POINT1; _sons_type[3]=NORM_POINT1; - _sons_con[0][0]=0; _nb_of_sons_con[0]=1; - _sons_con[1][0]=1; _nb_of_sons_con[1]=1; - _sons_con[2][0]=2; _nb_of_sons_con[2]=1; - _sons_con[3][0]=3; _nb_of_sons_con[3]=1; - } - break; - case NORM_TETRA4: - { - _nb_of_pts=4; _nb_of_sons=4; _dim=3; _quadratic_type=NORM_TETRA10; _is_simplex=true; - _sons_type[0]=NORM_TRI3; _sons_type[1]=NORM_TRI3; _sons_type[2]=NORM_TRI3; _sons_type[3]=NORM_TRI3; - _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]=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; _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; - _sons_con[2][0]=0; _sons_con[2][1]=4; _sons_con[2][2]=5; _sons_con[2][3]=1; _nb_of_sons_con[2]=4; - _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; _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; - _sons_con[2][0]=2; _sons_con[2][1]=3; _nb_of_sons_con[2]=2; - _sons_con[3][0]=3; _sons_con[3][1]=0; _nb_of_sons_con[3]=2; _extruded_type=NORM_HEXA8; - } - break; - case NORM_TRI3: - { - _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; - _sons_con[2][0]=2; _sons_con[2][1]=0; _nb_of_sons_con[2]=2; _extruded_type=NORM_PENTA6; - } - break; - case NORM_TRI6: - { - _nb_of_pts=6; _nb_of_sons=3; _dim=2; _linear_type=NORM_TRI3; _is_simplex=false; - _sons_type[0]=NORM_SEG3; _sons_type[1]=NORM_SEG3; _sons_type[2]=NORM_SEG3; - _sons_con[0][0]=0; _sons_con[0][1]=1; _sons_con[0][2]=3; _nb_of_sons_con[0]=3; - _sons_con[1][0]=1; _sons_con[1][1]=2; _sons_con[1][2]=4; _nb_of_sons_con[1]=3; - _sons_con[2][0]=2; _sons_con[2][1]=0; _sons_con[2][2]=5; _nb_of_sons_con[2]=3; _quadratic=true; _extruded_type=NORM_PENTA15; - } - break; - case NORM_TRI7: - { - _nb_of_pts=7; _nb_of_sons=3; _dim=2; _linear_type=NORM_TRI3; _is_simplex=false; - _sons_type[0]=NORM_SEG3; _sons_type[1]=NORM_SEG3; _sons_type[2]=NORM_SEG3; - _sons_con[0][0]=0; _sons_con[0][1]=1; _sons_con[0][2]=3; _nb_of_sons_con[0]=3; - _sons_con[1][0]=1; _sons_con[1][1]=2; _sons_con[1][2]=4; _nb_of_sons_con[1]=3; - _sons_con[2][0]=2; _sons_con[2][1]=0; _sons_con[2][2]=5; _nb_of_sons_con[2]=3; _quadratic=true; //no extruded type because no penta20 - } - break; - case NORM_QUAD8: - { - _nb_of_pts=8; _nb_of_sons=4; _dim=2; _linear_type=NORM_QUAD4; _is_simplex=false; - _sons_type[0]=NORM_SEG3; _sons_type[1]=NORM_SEG3; _sons_type[2]=NORM_SEG3; _sons_type[3]=NORM_SEG3; - _sons_con[0][0]=0; _sons_con[0][1]=1; _sons_con[0][2]=4; _nb_of_sons_con[0]=3; - _sons_con[1][0]=1; _sons_con[1][1]=2; _sons_con[1][2]=5; _nb_of_sons_con[1]=3; - _sons_con[2][0]=2; _sons_con[2][1]=3; _sons_con[2][2]=6; _nb_of_sons_con[2]=3; - _sons_con[3][0]=3; _sons_con[3][1]=0; _sons_con[3][2]=7; _nb_of_sons_con[3]=3; _quadratic=true; _extruded_type=NORM_HEXA20; - } - break; - case NORM_QUAD9: - { - _nb_of_pts=9; _nb_of_sons=4; _dim=2; _linear_type=NORM_QUAD4; _is_simplex=false; - _sons_type[0]=NORM_SEG3; _sons_type[1]=NORM_SEG3; _sons_type[2]=NORM_SEG3; _sons_type[3]=NORM_SEG3; - _sons_con[0][0]=0; _sons_con[0][1]=1; _sons_con[0][2]=4; _nb_of_sons_con[0]=3; - _sons_con[1][0]=1; _sons_con[1][1]=2; _sons_con[1][2]=5; _nb_of_sons_con[1]=3; - _sons_con[2][0]=2; _sons_con[2][1]=3; _sons_con[2][2]=6; _nb_of_sons_con[2]=3; - _sons_con[3][0]=3; _sons_con[3][1]=0; _sons_con[3][2]=7; _nb_of_sons_con[3]=3; _quadratic=true; _extruded_type=NORM_HEXA27; - } - break; - case NORM_PYRA5: - { - _nb_of_pts=5; _nb_of_sons=5; _dim=3; _quadratic_type=NORM_PYRA13; _is_simplex=false; - _sons_type[0]=NORM_QUAD4; _sons_type[1]=NORM_TRI3; _sons_type[2]=NORM_TRI3; _sons_type[3]=NORM_TRI3; _sons_type[4]=NORM_TRI3; - _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]=0; _sons_con[1][1]=4; _sons_con[1][2]=1; _nb_of_sons_con[1]=3; - _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; _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: - { - _nb_of_pts=10; _nb_of_sons=4; _dim=3; _linear_type=NORM_TETRA4; _is_simplex=false; - _sons_type[0]=NORM_TRI6; _sons_type[1]=NORM_TRI6; _sons_type[2]=NORM_TRI6; _sons_type[3]=NORM_TRI6; - _sons_con[0][0]=0; _sons_con[0][1]=1; _sons_con[0][2]=2; _sons_con[0][3]=4; _sons_con[0][4]=5; _sons_con[0][5]=6; _nb_of_sons_con[0]=6; - _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: - { - _nb_of_pts=12; _nb_of_sons=8; _dim=3; _is_simplex=false; _is_extruded=true; - _sons_type[0]=NORM_POLYGON; _sons_type[1]=NORM_POLYGON; _sons_type[2]=NORM_QUAD4; _sons_type[3]=NORM_QUAD4; _sons_type[4]=NORM_QUAD4; _sons_type[5]=NORM_QUAD4; - _sons_type[6]=NORM_QUAD4; _sons_type[7]=NORM_QUAD4; - _sons_con[0][0]=0; _sons_con[0][1]=1; _sons_con[0][2]=2; _sons_con[0][3]=3; _sons_con[0][4]=4; _sons_con[0][5]=5; _nb_of_sons_con[0]=6; - _sons_con[1][0]=6; _sons_con[1][1]=11; _sons_con[1][2]=10; _sons_con[1][3]=9; _sons_con[1][4]=8; _sons_con[1][5]=7; _nb_of_sons_con[1]=6; - _sons_con[2][0]=0; _sons_con[2][1]=6; _sons_con[2][2]=7; _sons_con[2][3]=1; _nb_of_sons_con[2]=4; - _sons_con[3][0]=1; _sons_con[3][1]=7; _sons_con[3][2]=8; _sons_con[3][3]=2; _nb_of_sons_con[3]=4; - _sons_con[4][0]=2; _sons_con[4][1]=8; _sons_con[4][2]=9; _sons_con[4][3]=3; _nb_of_sons_con[4]=4; - _sons_con[5][0]=3; _sons_con[5][1]=9; _sons_con[5][2]=10; _sons_con[5][3]=4; _nb_of_sons_con[5]=4; - _sons_con[6][0]=4; _sons_con[6][1]=10; _sons_con[6][2]=11; _sons_con[6][3]=5; _nb_of_sons_con[6]=4; - _sons_con[7][0]=5; _sons_con[7][1]=11; _sons_con[7][2]=6; _sons_con[7][3]=0; _nb_of_sons_con[7]=4; - } - break; - case NORM_PYRA13: - { - _nb_of_pts=13; _nb_of_sons=5; _dim=3; _linear_type=NORM_PYRA5; _is_simplex=false; - _sons_type[0]=NORM_QUAD8; _sons_type[1]=NORM_TRI6; _sons_type[2]=NORM_TRI6; _sons_type[3]=NORM_TRI6; _sons_type[4]=NORM_TRI6; - _sons_con[0][0]=0; _sons_con[0][1]=1; _sons_con[0][2]=2; _sons_con[0][3]=3; _sons_con[0][4]=5; _sons_con[0][5]=6; _sons_con[0][6]=7; _sons_con[0][7]=8; _nb_of_sons_con[0]=8; - _sons_con[1][0]=0; _sons_con[1][1]=4; _sons_con[1][2]=1; _sons_con[1][3]=9; _sons_con[1][4]=10; _sons_con[1][5]=5; _nb_of_sons_con[1]=6; - _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: - { - _nb_of_pts=15; _nb_of_sons=5; _dim=3; _linear_type=NORM_PENTA6; _is_simplex=false; - _sons_type[0]=NORM_TRI6; _sons_type[1]=NORM_TRI6; _sons_type[2]=NORM_QUAD8; _sons_type[3]=NORM_QUAD8; _sons_type[4]=NORM_QUAD8; - _sons_con[0][0]=0; _sons_con[0][1]=1; _sons_con[0][2]=2; _sons_con[0][3]=6; _sons_con[0][4]=7; _sons_con[0][5]=8; _nb_of_sons_con[0]=6; - _sons_con[1][0]=3; _sons_con[1][1]=5; _sons_con[1][2]=4; _sons_con[1][3]=11; _sons_con[1][4]=10; _sons_con[1][5]=9; _nb_of_sons_con[1]=6; - _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: - { - _nb_of_pts=20; _nb_of_sons=6; _dim=3; _linear_type=NORM_HEXA8; _is_simplex=false; - _sons_type[0]=NORM_QUAD8; _sons_type[1]=NORM_QUAD8; _sons_type[2]=NORM_QUAD8; _sons_type[3]=NORM_QUAD8; _sons_type[4]=NORM_QUAD8; _sons_type[5]=NORM_QUAD8; - _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][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: - { - _nb_of_pts=27; _nb_of_sons=6; _dim=3; _linear_type=NORM_HEXA8; _is_simplex=false; - _sons_type[0]=NORM_QUAD9; _sons_type[1]=NORM_QUAD9; _sons_type[2]=NORM_QUAD9; _sons_type[3]=NORM_QUAD9; _sons_type[4]=NORM_QUAD9; _sons_type[5]=NORM_QUAD9; - _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][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; _quadratic_type=NORM_QPOLYG; - } - break; - case NORM_POLYHED: - { - _nb_of_pts=0; _nb_of_sons=0; _dim=3; _dyn=true; _is_simplex=false; - } - break; - case NORM_QPOLYG: - { - _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: - { - _nb_of_pts=0; _nb_of_sons=0; _dim=1; _dyn=true; _extruded_type=NORM_POLYGON; _is_simplex=false; - } - break; - case NORM_ERROR: - { - _nb_of_pts=std::numeric_limits::max(); _nb_of_sons=std::numeric_limits::max(); _dim=std::numeric_limits::max(); - } - break; - } - } - - /*! - * Equivalent to getNumberOfSons except that this method deals with dynamic type. - */ - unsigned CellModel::getNumberOfSons2(const int *conn, int lgth) const - { - if(!isDynamic()) - return getNumberOfSons(); - if(_dim==2) - { - if(_type==NORM_POLYGON) - return lgth; - else - return lgth/2; - } - else if(_dim==1) - return lgth;//NORM_POLYL - else - 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. - */ - NormalizedCellType CellModel::getSonType2(unsigned sonId) const - { - if(!isDynamic()) - return getSonType(sonId); - if(_dim==2) - { - if(_type==NORM_POLYGON) - return NORM_SEG2; - else - return NORM_SEG3; - } - else if(_dim==1) - return NORM_ERROR;//NORM_POLYL - //polyedron - return NORM_POLYGON; - } - - /*! - * \b WARNING this method do not manage correctly types that return true at the call of isDynamic. Use fillSonCellNodalConnectivity2 instead. - */ - unsigned CellModel::fillSonCellNodalConnectivity(int sonId, const int *nodalConn, int *sonNodalConn) const - { - unsigned nbOfTurnLoop=_nb_of_sons_con[sonId]; - const unsigned *sonConn=_sons_con[sonId]; - for(unsigned i=0;iHEXA27 - */ - 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 !"); - } - - void CellModel::changeOrientationOf2D(int *nodalConn, unsigned int sz) const - { - if(sz<1) - return ; - if(!isQuadratic()) - { - std::vector tmp(sz-1); - std::copy(nodalConn+1,nodalConn+sz,tmp.rbegin()); - std::copy(tmp.begin(),tmp.end(),nodalConn+1); - } - else - { - unsigned int sz2(sz/2); - std::vector tmp0(sz2-1),tmp1(sz2); - std::copy(nodalConn+1,nodalConn+sz2,tmp0.rbegin()); - std::copy(nodalConn+sz2,nodalConn+sz,tmp1.rbegin()); - std::copy(tmp0.begin(),tmp0.end(),nodalConn+1); - std::copy(tmp1.begin(),tmp1.end(),nodalConn+sz2); - } - } - - void CellModel::changeOrientationOf1D(int *nodalConn, unsigned int sz) const - { - if(!isDynamic()) - { - if(sz==2 || sz==3) - { - std::swap(nodalConn[0],nodalConn[1]); - return ; - } - else if(sz==4) - { - std::swap(nodalConn[0],nodalConn[1]); - std::swap(nodalConn[2],nodalConn[3]); - } - else - throw Exception("CellModel::changeOrientationOf1D : unrecognized 1D cell type !"); - } - else - { - std::vector tmp(sz-1); - std::copy(nodalConn+1,nodalConn+sz,tmp.rbegin()); - std::copy(tmp.begin(),tmp.end(),nodalConn+1); - } - } - - //================================================================================ - /*! - * \brief Return number of nodes in sonId-th son of a Dynamic() cell - */ - //================================================================================ - - unsigned CellModel::getNumberOfNodesConstituentTheSon2(unsigned sonId, const int *nodalConn, int lgth) const - { - if(!isDynamic()) - return getNumberOfNodesConstituentTheSon(sonId); - - if(_dim==2)//polygon - { - if(_type==NORM_POLYGON) - return 2; - else - return 3; - } - else if(_dim==3) - {//polyedron - const int *where=nodalConn; - for(unsigned int i=0;i tmp(2*lgth); - std::vector::iterator it=std::copy(conn1,conn1+lgth,tmp.begin()); - std::copy(conn1,conn1+lgth,it); - it=std::search(tmp.begin(),tmp.end(),conn2,conn2+lgth); - if(it==tmp.begin()) - return true; - if(it!=tmp.end()) - return _dim!=1; - std::vector::reverse_iterator it2=std::search(tmp.rbegin(),tmp.rend(),conn2,conn2+lgth); - if(it2!=tmp.rend()) - return false; - throw INTERP_KERNEL::Exception("CellModel::getOrientationStatus : Request of orientation status of non equal connectively cells !"); - } - else - { - if(_dim!=1) - { - std::vector tmp(lgth); - std::vector::iterator it=std::copy(conn1,conn1+lgth/2,tmp.begin()); - std::copy(conn1,conn1+lgth/2,it); - it=std::search(tmp.begin(),tmp.end(),conn2,conn2+lgth/2); - int d=std::distance(tmp.begin(),it); - if(it==tmp.end()) - return false; - it=std::copy(conn1+lgth/2,conn1+lgth,tmp.begin()); - std::copy(conn1+lgth/2,conn1+lgth,it); - it=std::search(tmp.begin(),tmp.end(),conn2,conn2+lgth); - if(it==tmp.end()) - return false; - int d2=std::distance(tmp.begin(),it); - return d==d2; - } - else - { - int p=(lgth+1)/2; - std::vector tmp(2*p); - std::vector::iterator it=std::copy(conn1,conn1+p,tmp.begin()); - std::copy(conn1,conn1+p,it); - it=std::search(tmp.begin(),tmp.end(),conn2,conn2+p); - int d=std::distance(tmp.begin(),it); - if(it==tmp.end()) - return false; - tmp.resize(2*p-2); - it=std::copy(conn1+p,conn1+lgth,tmp.begin()); - std::copy(conn1+p,conn1+lgth,it); - it=std::search(tmp.begin(),tmp.end(),conn2+p,conn2+lgth); - if(it==tmp.end()) - return false; - int d2=std::distance(tmp.begin(),it); - return d==d2; - } - } - } - - DiameterCalculator *CellModel::buildInstanceOfDiameterCalulator(int spaceDim) const - { - switch(_type) - { - case NORM_TRI3: - { - switch(spaceDim) - { - case 2: - return new DiameterCalulatorTRI3S2; - case 3: - return new DiameterCalulatorTRI3S3; - default: - throw Exception("CellModel::buildInstanceOfDiameterCalulator : For TRI3 only space dimension 2 and 3 implemented !"); - } - break; - } - case NORM_QUAD4: - { - switch(spaceDim) - { - case 2: - return new DiameterCalulatorQUAD4S2; - case 3: - return new DiameterCalulatorQUAD4S3; - default: - throw Exception("CellModel::buildInstanceOfDiameterCalulator : For QUAD4 only space dimension 2 and 3 implemented !"); - } - break; - } - case NORM_TRI6: - { - switch(spaceDim) - { - case 2: - return new DiameterCalulatorTRI6S2; - case 3: - return new DiameterCalulatorTRI6S3; - default: - throw Exception("CellModel::buildInstanceOfDiameterCalulator : For TRI6 only space dimension 2 and 3 implemented !"); - } - break; - } - case NORM_TRI7: - { - switch(spaceDim) - { - case 2: - return new DiameterCalulatorTRI7S2; - case 3: - return new DiameterCalulatorTRI7S3; - default: - throw Exception("CellModel::buildInstanceOfDiameterCalulator : For TRI7 only space dimension 2 and 3 implemented !"); - } - break; - } - case NORM_QUAD8: - { - switch(spaceDim) - { - case 2: - return new DiameterCalulatorQUAD8S2; - case 3: - return new DiameterCalulatorQUAD8S3; - default: - throw Exception("CellModel::buildInstanceOfDiameterCalulator : For QUAD8 only space dimension 2 and 3 implemented !"); - } - break; - } - case NORM_QUAD9: - { - switch(spaceDim) - { - case 2: - return new DiameterCalulatorQUAD9S2; - case 3: - return new DiameterCalulatorQUAD9S3; - default: - throw Exception("CellModel::buildInstanceOfDiameterCalulator : For QUAD9 only space dimension 2 and 3 implemented !"); - } - break; - } - case NORM_TETRA4: - { - if(spaceDim==3) - return new DiameterCalulatorTETRA4; - else - throw Exception("CellModel::buildInstanceOfDiameterCalulator : For TETRA4 space dimension 3 expected !"); - } - case NORM_TETRA10: - { - if(spaceDim==3) - return new DiameterCalulatorTETRA10; - else - throw Exception("CellModel::buildInstanceOfDiameterCalulator : For TETRA10 space dimension 3 expected !"); - } - case NORM_HEXA8: - { - if(spaceDim==3) - return new DiameterCalulatorHEXA8; - else - throw Exception("CellModel::buildInstanceOfDiameterCalulator : For HEXA8 space dimension 3 expected !"); - } - case NORM_HEXA20: - { - if(spaceDim==3) - return new DiameterCalulatorHEXA20; - else - throw Exception("CellModel::buildInstanceOfDiameterCalulator : For HEXA20 space dimension 3 expected !"); - } - case NORM_HEXA27: - { - if(spaceDim==3) - return new DiameterCalulatorHEXA27; - else - throw Exception("CellModel::buildInstanceOfDiameterCalulator : For HEXA27 space dimension 3 expected !"); - } - case NORM_PENTA6: - { - if(spaceDim==3) - return new DiameterCalulatorPENTA6; - else - throw Exception("CellModel::buildInstanceOfDiameterCalulator : For PENTA6 space dimension 3 expected !"); - } - case NORM_PENTA15: - { - if(spaceDim==3) - return new DiameterCalulatorPENTA15; - else - throw Exception("CellModel::buildInstanceOfDiameterCalulator : For PENTA15 space dimension 3 expected !"); - } - case NORM_PYRA5: - { - if(spaceDim==3) - return new DiameterCalulatorPYRA5; - else - throw Exception("CellModel::buildInstanceOfDiameterCalulator : For PYRA5 space dimension 3 expected !"); - } - case NORM_PYRA13: - { - if(spaceDim==3) - return new DiameterCalulatorPYRA13; - else - throw Exception("CellModel::buildInstanceOfDiameterCalulator : For PYRA13 space dimension 3 expected !"); - } - default: - throw Exception("CellModel::buildInstanceOfDiameterCalulator : implemented only for TRI3, QUAD4, TETRA4, HEXA8, PENTA6, PYRA5 !"); - } - } -} diff --git a/src/INTERP_KERNEL/CellModel.hxx b/src/INTERP_KERNEL/CellModel.hxx deleted file mode 100644 index d1b5e1d95..000000000 --- a/src/INTERP_KERNEL/CellModel.hxx +++ /dev/null @@ -1,104 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 -// 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 __CELLMODEL_INTERP_KERNEL_HXX__ -#define __CELLMODEL_INTERP_KERNEL_HXX__ - -#include "INTERPKERNELDefines.hxx" - -#include "NormalizedUnstructuredMesh.hxx" - -#include - -namespace INTERP_KERNEL -{ - class DiameterCalculator; - - /*! - * This class descibes all static elements (different from polygons and polyhedron) 3D, 2D and 1D. - */ - class CellModel - { - 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(); - public: - INTERPKERNEL_EXPORT static const CellModel& GetCellModel(NormalizedCellType type); - INTERPKERNEL_EXPORT NormalizedCellType getEnum() const { return _type; } - INTERPKERNEL_EXPORT const char *getRepr() const; - INTERPKERNEL_EXPORT bool isExtruded() const { return _is_extruded; } - INTERPKERNEL_EXPORT bool isDynamic() const { return _dyn; } - INTERPKERNEL_EXPORT bool isQuadratic() const { return _quadratic; } - INTERPKERNEL_EXPORT unsigned getDimension() const { return _dim; } - INTERPKERNEL_EXPORT bool isCompatibleWith(NormalizedCellType type) const; - INTERPKERNEL_EXPORT bool isSimplex() const { return _is_simplex; } - //! sonId is in C format. - INTERPKERNEL_EXPORT const unsigned *getNodesConstituentTheSon(unsigned sonId) const { return _sons_con[sonId]; } - INTERPKERNEL_EXPORT bool getOrientationStatus(unsigned lgth, const int *conn1, const int *conn2) const; - 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; - INTERPKERNEL_EXPORT void changeOrientationOf2D(int *nodalConn, unsigned int sz) const; - INTERPKERNEL_EXPORT void changeOrientationOf1D(int *nodalConn, unsigned int sz) const; - INTERPKERNEL_EXPORT DiameterCalculator *buildInstanceOfDiameterCalulator(int spaceDim) const; - private: - bool _dyn; - bool _quadratic; - bool _is_simplex; - bool _is_extruded; - 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; - static const char *CELL_TYPES_REPR[]; - }; -} - -#endif diff --git a/src/INTERP_KERNEL/ConvexIntersector.hxx b/src/INTERP_KERNEL/ConvexIntersector.hxx deleted file mode 100644 index 53966f530..000000000 --- a/src/INTERP_KERNEL/ConvexIntersector.hxx +++ /dev/null @@ -1,54 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 -// 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 __CONVEXINTERSECTOR_HXX__ -#define __CONVEXINTERSECTOR_HXX__ - -#include "PlanarIntersectorP0P0.hxx" -#include "PlanarIntersectorP0P1.hxx" -#include "PlanarIntersectorP1P0.hxx" -#include "PlanarIntersectorP1P1.hxx" -#include "PlanarIntersectorP1P0Bary.hxx" -#include "PlanarIntersectorP0P1Bary.hxx" - -namespace INTERP_KERNEL -{ - template class InterpType > - class ConvexIntersector : public InterpType > - { - public: - static const int SPACEDIM=MyMeshType::MY_SPACEDIM; - static const int MESHDIM=MyMeshType::MY_MESHDIM; - typedef typename MyMeshType::MyConnType ConnType; - static const NumberingPolicy numPol=MyMeshType::My_numPol; - public: - ConvexIntersector(const MyMeshType& meshT, const MyMeshType& meshS, - double dimCaracteristic, double precision, double md3DSurf, double minDot3DSurf, double medianPlane, - bool doRotate, int orientation, int printLevel); - double intersectGeometry(ConnType icellT, ConnType icellS, ConnType nbNodesT, ConnType nbNodesS); - double intersectGeometryWithQuadrangle(const double *quadrangle, const std::vector& sourceCoords, bool isSourceQuad); - double intersectGeometryGeneral(const std::vector& targetCoords, const std::vector& sourceCoords); - double intersectGeoBary(const std::vector& targetCell, bool targetCellQuadratic, const double *sourceCell, std::vector& res); - private : - double _epsilon; - }; -} - -#endif diff --git a/src/INTERP_KERNEL/ConvexIntersector.txx b/src/INTERP_KERNEL/ConvexIntersector.txx deleted file mode 100644 index 9ab59b197..000000000 --- a/src/INTERP_KERNEL/ConvexIntersector.txx +++ /dev/null @@ -1,195 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 -// 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 __CONVEXINTERSECTOR_TXX__ -#define __CONVEXINTERSECTOR_TXX__ - -#include "ConvexIntersector.hxx" -#include "PlanarIntersectorP0P0.txx" -#include "PlanarIntersectorP0P1.txx" -#include "PlanarIntersectorP1P0.txx" -#include "PlanarIntersectorP1P1.txx" -#include "PlanarIntersectorP1P0Bary.txx" -#include "PlanarIntersectorP0P1Bary.txx" - -#include "PolygonAlgorithms.txx" - -#include - -#define CONVINTERSECTOR_TEMPLATE template class InterpType> -#define CONVEX_INTERSECTOR_ ConvexIntersector - -namespace INTERP_KERNEL -{ - CONVINTERSECTOR_TEMPLATE - CONVEX_INTERSECTOR_::ConvexIntersector(const MyMeshType& meshT, const MyMeshType& meshS, - double dimCaracteristic, double precision, double md3DSurf, double minDot3DSurf, - double medianPlane, bool doRotate , int oriantation, int printLevel) - :InterpType(meshT,meshS,dimCaracteristic, precision, md3DSurf, minDot3DSurf, medianPlane, doRotate, oriantation, printLevel), - _epsilon(precision*dimCaracteristic) - { - if(PlanarIntersector::_print_level >= 1) - { - std::cout << " - intersection type = convex " << std::endl; - if(SPACEDIM==3){ - if(PlanarIntersector::_do_rotate) std::cout << " _do_rotate = true" << std::endl; - else std::cout << " _do_rotate = false" << std::endl; - } - } - } - - CONVINTERSECTOR_TEMPLATE - double CONVEX_INTERSECTOR_::intersectGeometry(ConnType icellT, ConnType icellS, - ConnType nbNodesT, ConnType nbNodesS) - { - double result = 0; - int orientation = 1; - - /*** Obtain the coordinates of T and S ***/ - std::vector CoordsT; - std::vector CoordsS; - PlanarIntersector::getRealCoordinates(icellT,icellS,nbNodesT,nbNodesS,CoordsT,CoordsS,orientation); - /*** Compute the intersection area ***/ - INTERP_KERNEL::PolygonAlgorithms P(_epsilon, PlanarIntersector::_precision); - std::deque inter = P.intersectConvexPolygons(&CoordsT[0], &CoordsS[0], - CoordsT.size()/SPACEDIM, CoordsS.size()/SPACEDIM); - double area[SPACEDIM]; - int nb_inter =((int)inter.size())/SPACEDIM; - for(int i = 1; i(&inter[0],&inter[SPACEDIM*i],&inter[SPACEDIM*(i+1)],area); - result +=0.5*norm(area); - } - - //DEBUG prints - if(PlanarIntersector::_print_level >= 3) - { - std::cout << std::endl << "Number of nodes of the intersection = "<< nb_inter << std::endl; - for(int i=0; i< nb_inter; i++) - {for (int idim=0; idim - class CurveIntersector : public TargetIntersector - { - public: - static const int SPACEDIM=MyMeshType::MY_SPACEDIM; - static const int MESHDIM=MyMeshType::MY_MESHDIM; - typedef typename MyMeshType::MyConnType ConnType; - static const NumberingPolicy numPol=MyMeshType::My_numPol; - public: - CurveIntersector(const MyMeshType& meshT, const MyMeshType& meshS, - double precision, double adjustmentEpsAbs, double medianLine, int printLevel); - virtual ~CurveIntersector(); - void createBoundingBoxes(const MyMeshType& mesh, std::vector& bbox); - void adjustBoundingBoxes(std::vector& bbox, double adjustmentEpsAbs); - static void getElemBB(double* bb, const MyMeshType& mesh, ConnType iP, ConnType nb_nodes); - static bool ComputeBaryCoordsOf(double startOfSeg, double endOfSeg, double pt, double& startPos, double& endPos); - protected : - bool projectionThis(const double *coordsT, const double *coordsS, double& xs0, double& xs1, double& xt0, double& xt1) const; - bool getRealTargetCoordinates(ConnType icellT, std::vector& coordsT) const; - typename MyMeshType::MyConnType getNodeIdOfTargetCellAt(ConnType icellT, ConnType nodeIdInCellT) const; - bool getRealSourceCoordinates(ConnType icellS, std::vector& coordsS) const; - typename MyMeshType::MyConnType getNodeIdOfSourceCellAt(ConnType icellT, ConnType nodeIdInCellT) const; - double intersectSegments(const double *coordsT, const double *coordsS) const; - double intersectSegmentsInternal(const double *coordsT, const double *coordsS, double& xs0, double& xs1, double& xt0, double& xt1) const; - - struct TDualSegment - { - std::vector _coords; - int _nodeId; // in mesh mode - }; - static void getDualSegments(ConnType icell, - const MyMeshType& mesh, - std::vector& segments); - - protected: - const ConnType *_connectT; - const ConnType *_connectS; - const double *_coordsT; - const double *_coordsS; - const ConnType *_connIndexT; - const ConnType *_connIndexS; - const MyMeshType& _meshT; - const MyMeshType& _meshS; - double _tolerance; - double _precision; - double _median_line; - int _print_level; - }; -} - -#endif diff --git a/src/INTERP_KERNEL/CurveIntersector.txx b/src/INTERP_KERNEL/CurveIntersector.txx deleted file mode 100644 index c311605f7..000000000 --- a/src/INTERP_KERNEL/CurveIntersector.txx +++ /dev/null @@ -1,430 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 -// 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 __CURVEINTERSECTOR_TXX__ -#define __CURVEINTERSECTOR_TXX__ - -#include "CurveIntersector.hxx" -#include "InterpolationUtils.hxx" - -#include - -namespace INTERP_KERNEL -{ - template - CurveIntersector - ::CurveIntersector(const MyMeshType& meshT, const MyMeshType& meshS, - double precision, double tolerance, double medianLine, int printLevel): - _meshT(meshT), - _meshS(meshS), - _tolerance(tolerance), - _precision(precision), - _median_line(medianLine), - _print_level(printLevel) - { - if ( SPACEDIM != 1 && SPACEDIM != 2 ) - throw Exception("CurveIntersector(): space dimension of mesh must be 1 or 2"); - if ( MESHDIM != 1 ) - throw Exception("CurveIntersector(): mesh dimension must be 1"); - - _connectT = meshT.getConnectivityPtr(); - _connectS = meshS.getConnectivityPtr(); - _connIndexT = meshT.getConnectivityIndexPtr(); - _connIndexS = meshS.getConnectivityIndexPtr(); - _coordsT = meshT.getCoordinatesPtr(); - _coordsS = meshS.getCoordinatesPtr(); - } - - template - CurveIntersector::~CurveIntersector() - { - } - - //================================================================================ - /*! - \brief creates the bounding boxes for all the cells of mesh \a mesh - - \param mesh structure pointing to the mesh - \param bbox vector containing the bounding boxes - */ - //================================================================================ - - template - void CurveIntersector::createBoundingBoxes (const MyMeshType& mesh, - std::vector& bbox) - { - long nbelems = mesh.getNumberOfElements(); - bbox.resize(2*SPACEDIM* nbelems); - const double* coords = mesh.getCoordinatesPtr(); - const ConnType* conn = mesh.getConnectivityPtr(); - const ConnType* conn_index = mesh.getConnectivityIndexPtr(); - int ibox=0; - for(long icell=0; icell::max(); - bbox[2*SPACEDIM*ibox+2*idim+1] = -std::numeric_limits::max(); - } - //updating the bounding box with each node of the element - for (int j=0; j - ::coo2C(conn[OTT::conn2C(conn_index[icell]+j)]); - for(int idim=0; idim x ) ? bbox[ibox*2*SPACEDIM + 2*idim+1] : x; - } - } - ibox++; - } - } - - /*! - Computes the bouding box of a given element. iP in numPol mode. - */ - template - void CurveIntersector::getElemBB (double* bb, - const MyMeshType& mesh, - ConnType iP, - ConnType nb_nodes) - { - const double* coords = mesh.getCoordinatesPtr(); - const ConnType* conn_index = mesh.getConnectivityIndexPtr(); - const ConnType* conn = mesh.getConnectivityPtr(); - //initializing bounding box limits - for(int idim=0; idim::max(); - bb[2*idim+1] = -std::numeric_limits::max(); - } - - for (ConnType i=0; i::coo2C(conn[OTT::conn2C(conn_index[OTT::ind2C(iP)]+i)])); - for(int idim=0; idimbb[2*idim+1]) ? x : bb[2*idim+1]; - } - } - } - - /*! - * \param [in] startOfSeg - input coming from intersectSegments or intersectSegmentsInternal - * \param [in] endOfSeg - input coming from intersectSegments or intersectSegmentsInternal. Assume that endOfSeg>startOfSeg. - * \param [in] pt - position of point that the method computes the bary coords for. - */ - template - bool CurveIntersector::ComputeBaryCoordsOf(double startOfSeg, double endOfSeg, double pt, double& startPos, double& endPos) - { - double deno(endOfSeg-startOfSeg); - startPos=(endOfSeg-pt)/deno; - endPos=1.-startPos; - return startPos>=0. && endPos>=0.; - } - - /*! Readjusts a set of bounding boxes so that they are extended - in all dimensions for avoiding missing interesting intersections - - \param bbox vector containing the bounding boxes - */ - template - void CurveIntersector::adjustBoundingBoxes (std::vector& bbox, - double adjustmentEpsAbs) - { - long size = bbox.size()/(2*SPACEDIM); - for (int i=0; i - bool CurveIntersector::getRealTargetCoordinates(ConnType icellT, std::vector& coordsT) const - { - int nbNodesT(_connIndexT[OTT::ind2C(icellT)+1] - _connIndexT[OTT::ind2C(icellT)]); - coordsT.resize(SPACEDIM*nbNodesT); - for (ConnType iT=0; iT::coo2C(_connectT[OTT::conn2C(_connIndexT[OTT::ind2C(icellT)]+iT)])+idim]; - } - } - if ( nbNodesT > 2 ) - { - for(int idim=0; idim - typename MyMeshType::MyConnType CurveIntersector::getNodeIdOfTargetCellAt(ConnType icellT, ConnType nodeIdInCellT) const - { - int nbNodesT(_connIndexT[OTT::ind2C(icellT)+1] - _connIndexT[OTT::ind2C(icellT)]); - if(nodeIdInCellT>=0 && nodeIdInCellT::coo2C(_connectT[OTT::conn2C(_connIndexT[OTT::ind2C(icellT)]+nodeIdInCellT)]); - else - throw Exception("getNodeIdOfTargetCellAt : error in nodeId in cell"); - } - - /*! - * @param icellS id in source mesh in format of MyMeshType. - * @param coordsS output val that stores coordinates of the source cell automatically resized to the right length. - * @return true if segment is quadratic and in this case coordinates of medium node - * are placed in the middle of coordsS - */ - template - bool CurveIntersector::getRealSourceCoordinates(ConnType icellS, std::vector& coordsS) const - { - int nbNodesS = _connIndexS[OTT::ind2C(icellS)+1] - _connIndexS[OTT::ind2C(icellS)]; - coordsS.resize(SPACEDIM*nbNodesS); - for(ConnType iS=0; iS::coo2C(_connectS[OTT::conn2C(_connIndexS[OTT::ind2C(icellS)]+iS)])+idim]; - } - } - if ( nbNodesS > 2 ) - { - for(int idim=0; idim - typename MyMeshType::MyConnType CurveIntersector::getNodeIdOfSourceCellAt(ConnType icellS, ConnType nodeIdInCellS) const - { - int nbNodesS(_connIndexS[OTT::ind2C(icellS)+1] - _connIndexS[OTT::ind2C(icellS)]); - if(nodeIdInCellS>=0 && nodeIdInCellS::coo2C(_connectS[OTT::conn2C(_connIndexS[OTT::ind2C(icellS)]+nodeIdInCellS)]); - else - throw Exception("getNodeIdOfSourceCellAt : error in nodeId in cell"); - } - - /*! - * \brief Return dual segments of given segment - * \param icell - given segment in C mode - * \param mesh - mesh - * \param segments - dual segments - */ - template - void CurveIntersector::getDualSegments(ConnType icell, - const MyMeshType& mesh, - std::vector& segments) - { - // get coordinates of cell nodes - int nbNodes; - std::vector ncoords; - std::vector nodeIds; - { - const ConnType *connect = mesh.getConnectivityPtr(); - const ConnType *connIndex = mesh.getConnectivityIndexPtr(); - const double *coords = mesh.getCoordinatesPtr(); - - nbNodes = connIndex[icell+1] - connIndex[icell]; - - ncoords.resize(SPACEDIM*nbNodes); - nodeIds.resize(nbNodes); - - for(int i=0; i::conn2C(connIndex[OTT::ind2C(icell)]+i)]; - ncoords[SPACEDIM*i+idim] = coords[SPACEDIM*OTT::coo2C(nodeIds[i])+idim]; - } - if ( nbNodes > 2 ) // quadratic segment, put medium node in the middle - { - for(int idim=0; idim - bool CurveIntersector::projectionThis(const double *coordsT, const double *coordsS, - double& xs0, double& xs1, double& xt0, double& xt1) const - { - xt0 = coordsT[0]; xt1 = coordsT[1]; - xs0 = coordsS[0]; xs1 = coordsS[1]; - if ( SPACEDIM == 2 ) - { - // Pass 2D->1D - - enum { X=0, Y }; - - // check if two segments overlap in 2D within tolerance - - const double* t0 = coordsT; - const double* t1 = coordsT + 2; - double t01[2] = { t1[X]-t0[X], t1[Y]-t0[Y] }; // tgt segment direction - double tSize = sqrt( t01[X]*t01[X] + t01[Y]*t01[Y] ); // tgt segment size - if ( tSize < _precision ) - return false; // degenerated segment - t01[X] /= tSize, t01[Y] /= tSize; // normalize t01 - - const double* s0 = coordsS; - const double* s1 = coordsS + 2; - double t0s0[2] = { s0[X]-t0[X], s0[Y]-t0[Y] }; - double t0s1[2] = { s1[X]-t0[X], s1[Y]-t0[Y] }; - double nt01_x_t0s0 = t0s0[X] * t01[Y] - t0s0[Y] * t01[X]; // t0s0 dot norm of t01 - double nt01_x_t0s1 = t0s1[X] * t01[Y] - t0s1[Y] * t01[X]; // t0s1 dot norm of t01 - double dist_ts0 = fabs( nt01_x_t0s0 ); // dist from tgt seg to s0 - double dist_ts1 = fabs( nt01_x_t0s1 ); // dist from tgt seg to s1 - bool s0_out_of_tol = ( dist_ts0 > _tolerance ); - bool s1_out_of_tol = ( dist_ts1 > _tolerance ); - if ( nt01_x_t0s0 * nt01_x_t0s1 > 0 && ( s0_out_of_tol || s1_out_of_tol )) - return false; // tgt segment is to far from src segment - - double S0[2] = { s0[X], s0[Y] }; - double S1[2] = { s1[X], s1[Y] }; - if ( s0_out_of_tol ) // put s0 within tolerance - { - double t = _tolerance * nt01_x_t0s0 / dist_ts0; // signed tolerance - double r = ( nt01_x_t0s0 - t ) / ( nt01_x_t0s0 - nt01_x_t0s1 ); - S0[X] = s0[X] * ( 1.-r ) + s1[X] * r; - S0[Y] = s0[Y] * ( 1.-r ) + s1[Y] * r; - } - if ( s1_out_of_tol ) // put s1 within tolerance - { - double t = _tolerance * nt01_x_t0s1 / dist_ts1; // signed tolerance - double r = ( nt01_x_t0s1 - t ) / ( nt01_x_t0s1 - nt01_x_t0s0 ); - S1[X] = s1[X] * ( 1.-r ) + s0[X] * r; - S1[Y] = s1[Y] * ( 1.-r ) + s0[Y] * r; - } - - // project tgt and src segments to median line - - double s01[2] = { S1[X]-S0[X], S1[Y]-S0[Y] }; // src segment direction - double sSize = sqrt( s01[X]*s01[X] + s01[Y]*s01[Y] ); // src segment size - if ( sSize < _precision ) - return false; // degenerated segment - s01[X] /= sSize, s01[Y] /= sSize; // normalize s01 - - // make t01 and s01 codirected - double t01_x_s01 = t01[X] * s01[X] + t01[Y] * s01[Y]; // t01 dot s01 - if ( t01_x_s01 < 0 ) - s01[X] = -s01[X], s01[Y] = -s01[Y]; - - double medianDir[2] = { - t01[X] * ( 1.-_median_line) + s01[X] * _median_line, - t01[Y] * ( 1.-_median_line) + s01[Y] * _median_line - }; - double medianSize = sqrt( medianDir[X]*medianDir[X] + medianDir[Y]*medianDir[Y] ); - if ( medianSize < std::numeric_limits::min() ) - return false; // strange... - medianDir[X] /= medianSize, medianDir[Y] /= medianSize; - - xt0 = t0[X] * medianDir[X] + t0[Y] * medianDir[Y]; - xt1 = t1[X] * medianDir[X] + t1[Y] * medianDir[Y]; - xs0 = S0[X] * medianDir[X] + S0[Y] * medianDir[Y]; - xs1 = S1[X] * medianDir[X] + S1[Y] * medianDir[Y]; - - } // if ( SPACEDIM == 2 ) - return true; - } - - /*! - * \brief Return length of intersection of two segments - */ - template - double CurveIntersector::intersectSegmentsInternal(const double *coordsT, const double *coordsS, double& xs0, double& xs1, double& xt0, double& xt1) const - { - if(!projectionThis(coordsT,coordsS,xs0,xs1,xt0,xt1)) - return 0.; - - if ( xt0 > xt1 ) std::swap( xt0, xt1 ); - if ( xs0 > xs1 ) std::swap( xs0, xs1 ); - - double x0 = std::max( xt0, xs0 ); - double x1 = std::min( xt1, xs1 ); - return ( x0 < x1 ) ? ( x1 - x0 ) : 0.; - } - - /*! - * \brief Return length of intersection of two segments - */ - template - double CurveIntersector::intersectSegments(const double *coordsT, const double *coordsS) const - { - double xs0,xs1,xt0,xt1; - return intersectSegmentsInternal(coordsT,coordsS,xs0,xs1,xt0,xt1); - } - -} - -#endif diff --git a/src/INTERP_KERNEL/CurveIntersectorP0P0.hxx b/src/INTERP_KERNEL/CurveIntersectorP0P0.hxx deleted file mode 100644 index eabf428f6..000000000 --- a/src/INTERP_KERNEL/CurveIntersectorP0P0.hxx +++ /dev/null @@ -1,48 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 -// 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 __CURVEINTERSECTORP0P0_HXX__ -#define __CURVEINTERSECTORP0P0_HXX__ - -#include "CurveIntersector.hxx" - -namespace INTERP_KERNEL -{ - template - class CurveIntersectorP0P0 : public CurveIntersector - { - public: - static const int SPACEDIM=MyMeshType::MY_SPACEDIM; - static const int MESHDIM=MyMeshType::MY_MESHDIM; - typedef typename MyMeshType::MyConnType ConnType; - static const NumberingPolicy numPol=MyMeshType::My_numPol; - - CurveIntersectorP0P0(const MyMeshType& meshT, const MyMeshType& meshS, - double precision, double tolerance, - double medianLine, int printLevel); - public: - int getNumberOfRowsOfResMatrix() const; - int getNumberOfColsOfResMatrix() const; - void intersectCells(ConnType icellT, - const std::vector& icellsS, MyMatrix& res); - }; -} - -#endif diff --git a/src/INTERP_KERNEL/CurveIntersectorP0P0.txx b/src/INTERP_KERNEL/CurveIntersectorP0P0.txx deleted file mode 100644 index 61c7fd60b..000000000 --- a/src/INTERP_KERNEL/CurveIntersectorP0P0.txx +++ /dev/null @@ -1,79 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 -// 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 __CURVEINTERSECTORP0P0_TXX__ -#define __CURVEINTERSECTORP0P0_TXX__ - -#include "CurveIntersectorP0P0.hxx" -#include "CurveIntersector.txx" - -#define BASE_INTERSECTOR CurveIntersector - -namespace INTERP_KERNEL -{ - template - CurveIntersectorP0P0 - ::CurveIntersectorP0P0(const MyMeshType& meshT, const MyMeshType& meshS, - double precision, double tolerance, - double medianLine, int printLevel): - BASE_INTERSECTOR(meshT, meshS, precision, tolerance, medianLine, printLevel) - { - } - - template - int CurveIntersectorP0P0 - ::getNumberOfRowsOfResMatrix() const - { - return BASE_INTERSECTOR::_meshT.getNumberOfElements(); - } - - template - int CurveIntersectorP0P0 - ::getNumberOfColsOfResMatrix() const - { - return BASE_INTERSECTOR::_meshS.getNumberOfElements(); - } - - template - void CurveIntersectorP0P0 - ::intersectCells(ConnType icellT, const std::vector& icellsS, MyMatrix& res) - { - typename MyMatrix::value_type& resRow = res[icellT]; - std::vector coordsT; - int t, nbSegT = 1 + BASE_INTERSECTOR::getRealTargetCoordinates(icellT,coordsT); - for ( t = 0; t < nbSegT; ++t ) - for(typename std::vector::const_iterator - iter=icellsS.begin(); iter!=icellsS.end(); iter++) - { - int iS = *iter; - std::vector coordsS; - int s, nbSegS = 1 + BASE_INTERSECTOR::getRealSourceCoordinates(iS,coordsS); - for ( s = 0; s < nbSegS; ++s ) - { - double surf = BASE_INTERSECTOR::intersectSegments(&coordsT[0] + t*SPACEDIM, - &coordsS[0] + s*SPACEDIM); - if(surf!=0.) - resRow.insert(std::make_pair(OTT::indFC(iS),surf)); - } - } - } -} -#undef BASE_INTERSECTOR - -#endif diff --git a/src/INTERP_KERNEL/CurveIntersectorP0P1.hxx b/src/INTERP_KERNEL/CurveIntersectorP0P1.hxx deleted file mode 100644 index e8469d0f1..000000000 --- a/src/INTERP_KERNEL/CurveIntersectorP0P1.hxx +++ /dev/null @@ -1,48 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 -// 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 __CURVEINTERSECTORP0P1_HXX__ -#define __CURVEINTERSECTORP0P1_HXX__ - -#include "CurveIntersector.hxx" - -namespace INTERP_KERNEL -{ - template - class CurveIntersectorP0P1 : public CurveIntersector - { - public: - static const int SPACEDIM=MyMeshType::MY_SPACEDIM; - static const int MESHDIM=MyMeshType::MY_MESHDIM; - typedef typename MyMeshType::MyConnType ConnType; - static const NumberingPolicy numPol=MyMeshType::My_numPol; - - CurveIntersectorP0P1(const MyMeshType& meshT, const MyMeshType& meshS, - double precision, double tolerance, - double medianLine, int printLevel); - public: - void intersectCells(ConnType icellT, - const std::vector& icellsS, MyMatrix& res); - int getNumberOfRowsOfResMatrix() const; - int getNumberOfColsOfResMatrix() const; - }; -} - -#endif diff --git a/src/INTERP_KERNEL/CurveIntersectorP0P1.txx b/src/INTERP_KERNEL/CurveIntersectorP0P1.txx deleted file mode 100644 index a12e41142..000000000 --- a/src/INTERP_KERNEL/CurveIntersectorP0P1.txx +++ /dev/null @@ -1,97 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 -// 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 __CurveIntersectorP0P1_TXX__ -#define __CurveIntersectorP0P1_TXX__ - -#include "CurveIntersectorP0P1.hxx" -#include "CurveIntersector.txx" - -#define BASE_INTERSECTOR CurveIntersector - -namespace INTERP_KERNEL -{ - template - CurveIntersectorP0P1 - ::CurveIntersectorP0P1(const MyMeshType& meshT, const MyMeshType& meshS, - double precision, double tolerance, - double medianLine, int printLevel): - BASE_INTERSECTOR(meshT, meshS, precision, tolerance, medianLine, printLevel) - { - } - - template - int CurveIntersectorP0P1 - ::getNumberOfRowsOfResMatrix() const - { - return BASE_INTERSECTOR::_meshT.getNumberOfNodes(); - } - - template - int CurveIntersectorP0P1 - ::getNumberOfColsOfResMatrix() const - { - return BASE_INTERSECTOR::_meshS.getNumberOfElements(); - } - - //================================================================================ - /*! - * \brief Project from segments to nodes - */ - //================================================================================ - - template - void CurveIntersectorP0P1 - ::intersectCells(ConnType icellT, const std::vector& icellsS, MyMatrix& res) - { - std::vector segmentsT; - BASE_INTERSECTOR::getDualSegments( icellT, BASE_INTERSECTOR::_meshT, segmentsT); - for ( int t = 0; t < (int)segmentsT.size(); ++t ) - { - typename MyMatrix::value_type& resRow = res[ OTT::ind2C( segmentsT[t]._nodeId )]; - for(typename std::vector::const_iterator - iter=icellsS.begin(); iter!=icellsS.end(); iter++) - { - int iS = *iter; - std::vector coordsS; - int s, nbSegS = 1 + BASE_INTERSECTOR::getRealSourceCoordinates(iS,coordsS); - for ( s = 0; s < nbSegS; ++s ) - { - double surf = BASE_INTERSECTOR::intersectSegments(&segmentsT[t]._coords[0], - &coordsS[0] + s*SPACEDIM); - if(surf!=0.) - { - typename MyMatrix::value_type::const_iterator iterRes=resRow.find(OTT::indFC(iS)); - if(iterRes==resRow.end()) - resRow.insert(std::make_pair(OTT::indFC(iS),surf)); - else - { - surf+=(*iterRes).second; - resRow.erase(OTT::indFC(iS)); - resRow.insert(std::make_pair(OTT::indFC(iS),surf)); - } - } - } - } - } - } -} -#undef BASE_INTERSECTOR - -#endif diff --git a/src/INTERP_KERNEL/CurveIntersectorP1P0.hxx b/src/INTERP_KERNEL/CurveIntersectorP1P0.hxx deleted file mode 100644 index f2d78c200..000000000 --- a/src/INTERP_KERNEL/CurveIntersectorP1P0.hxx +++ /dev/null @@ -1,46 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 -// 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 __CURVEINTERSECTORP1P0_HXX__ -#define __CURVEINTERSECTORP1P0_HXX__ - -#include "CurveIntersector.hxx" - -namespace INTERP_KERNEL -{ - template - class CurveIntersectorP1P0 : public CurveIntersector - { - public: - static const int SPACEDIM=MyMeshType::MY_SPACEDIM; - static const int MESHDIM=MyMeshType::MY_MESHDIM; - typedef typename MyMeshType::MyConnType ConnType; - static const NumberingPolicy numPol=MyMeshType::My_numPol; - - CurveIntersectorP1P0(const MyMeshType& meshT, const MyMeshType& meshS, - double precision, double tolerance, double medianLine, int printLevel); - public: - void intersectCells(ConnType icellT, const std::vector& icellsS, MyMatrix& res); - int getNumberOfRowsOfResMatrix() const; - int getNumberOfColsOfResMatrix() const; - }; -} - -#endif diff --git a/src/INTERP_KERNEL/CurveIntersectorP1P0.txx b/src/INTERP_KERNEL/CurveIntersectorP1P0.txx deleted file mode 100644 index 7125fc8b3..000000000 --- a/src/INTERP_KERNEL/CurveIntersectorP1P0.txx +++ /dev/null @@ -1,97 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 -// 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 __CurveIntersectorP1P0_TXX__ -#define __CurveIntersectorP1P0_TXX__ - -#include "CurveIntersectorP1P0.hxx" -#include "CurveIntersector.txx" - -#define BASE_INTERSECTOR CurveIntersector - -namespace INTERP_KERNEL -{ - template - CurveIntersectorP1P0 - ::CurveIntersectorP1P0(const MyMeshType& meshT, const MyMeshType& meshS, - double precision, double tolerance, - double medianLine, int printLevel): - BASE_INTERSECTOR (meshT, meshS, precision, tolerance, medianLine, printLevel) - { - } - - template - int CurveIntersectorP1P0 - ::getNumberOfRowsOfResMatrix() const - { - return BASE_INTERSECTOR::_meshT.getNumberOfElements(); - } - - template - int CurveIntersectorP1P0 - ::getNumberOfColsOfResMatrix() const - { - return BASE_INTERSECTOR::_meshS.getNumberOfNodes(); - } - - //================================================================================ - /*! - * \brief Project from source nodes to target segments - */ - //================================================================================ - - template - void CurveIntersectorP1P0 - ::intersectCells(ConnType icellT, const std::vector& icellsS, MyMatrix& res) - { - typename MyMatrix::value_type& resRow = res[ icellT ]; - std::vector segmentsS; - std::vector coordsT; - int t, nbSegT = 1 + BASE_INTERSECTOR::getRealTargetCoordinates(icellT,coordsT); - for ( t = 0; t < nbSegT; ++t ) - for(typename std::vector::const_iterator - iter=icellsS.begin(); iter!=icellsS.end(); iter++) - { - int iS = *iter; - BASE_INTERSECTOR::getDualSegments( OTT::ind2C(iS), - BASE_INTERSECTOR::_meshS, segmentsS); - for ( int s = 0; s < (int)segmentsS.size(); ++s ) - { - double surf = BASE_INTERSECTOR::intersectSegments(&segmentsS[s]._coords[0], - &coordsT[0] + t*SPACEDIM); - if(surf!=0.) - { - int nS = segmentsS[s]._nodeId; - typename MyMatrix::value_type::const_iterator iterRes=resRow.find(nS); - if(iterRes==resRow.end()) - resRow.insert(std::make_pair(nS,surf)); - else - { - surf+=(*iterRes).second; - resRow.erase(nS); - resRow.insert(std::make_pair(nS,surf)); - } - } - } - } - } -} -#undef BASE_INTERSECTOR - -#endif diff --git a/src/INTERP_KERNEL/CurveIntersectorP1P1.hxx b/src/INTERP_KERNEL/CurveIntersectorP1P1.hxx deleted file mode 100644 index 34678e712..000000000 --- a/src/INTERP_KERNEL/CurveIntersectorP1P1.hxx +++ /dev/null @@ -1,48 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 -// 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 __CURVEINTERSECTORP1P1_HXX__ -#define __CURVEINTERSECTORP1P1_HXX__ - -#include "CurveIntersector.hxx" - -namespace INTERP_KERNEL -{ - template - class CurveIntersectorP1P1 : public CurveIntersector - { - public: - static const int SPACEDIM=MyMeshType::MY_SPACEDIM; - static const int MESHDIM=MyMeshType::MY_MESHDIM; - typedef typename MyMeshType::MyConnType ConnType; - static const NumberingPolicy numPol=MyMeshType::My_numPol; - - CurveIntersectorP1P1(const MyMeshType& meshT, const MyMeshType& meshS, - double precision, double tolerance, - double medianLine, int printLevel); - public: - void intersectCells(ConnType icellT, - const std::vector& icellsS, MyMatrix& res); - int getNumberOfRowsOfResMatrix() const; - int getNumberOfColsOfResMatrix() const; - }; -} - -#endif diff --git a/src/INTERP_KERNEL/CurveIntersectorP1P1.txx b/src/INTERP_KERNEL/CurveIntersectorP1P1.txx deleted file mode 100644 index 266c87083..000000000 --- a/src/INTERP_KERNEL/CurveIntersectorP1P1.txx +++ /dev/null @@ -1,92 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 -// 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 __CurveIntersectorP1P1_TXX__ -#define __CurveIntersectorP1P1_TXX__ - -#include "CurveIntersectorP1P1.hxx" -#include "CurveIntersector.txx" - -#define BASE_INTERSECTOR CurveIntersector - -namespace INTERP_KERNEL -{ - template - CurveIntersectorP1P1 - ::CurveIntersectorP1P1(const MyMeshType& meshT, const MyMeshType& meshS, - double precision, double tolerance, - double medianLine, int printLevel): - BASE_INTERSECTOR (meshT, meshS, precision, tolerance, medianLine, printLevel) - { - } - - template - int CurveIntersectorP1P1 - ::getNumberOfRowsOfResMatrix() const - { - return BASE_INTERSECTOR::_meshT.getNumberOfNodes(); - } - - template - int CurveIntersectorP1P1 - ::getNumberOfColsOfResMatrix() const - { - return BASE_INTERSECTOR::_meshS.getNumberOfNodes(); - } - - template - void CurveIntersectorP1P1 - ::intersectCells(ConnType icellT, const std::vector& icellsS, MyMatrix& res) - { - std::vector segmentsT, segmentsS; - BASE_INTERSECTOR::getDualSegments( icellT, BASE_INTERSECTOR::_meshT, segmentsT); - for ( int t = 0; t < (int)segmentsT.size(); ++t ) - { - typename MyMatrix::value_type& resRow = res[ OTT::ind2C( segmentsT[t]._nodeId )]; - for(typename std::vector::const_iterator - iter=icellsS.begin(); iter!=icellsS.end(); iter++) - { - int iS = *iter; - BASE_INTERSECTOR::getDualSegments( OTT::ind2C(iS), - BASE_INTERSECTOR::_meshS, segmentsS); - for ( int s = 0; s < (int)segmentsS.size(); ++s ) - { - double surf = BASE_INTERSECTOR::intersectSegments(&segmentsT[t]._coords[0], - &segmentsS[s]._coords[0]); - if(surf!=0.) - { - int nS = segmentsS[s]._nodeId; - typename MyMatrix::value_type::const_iterator iterRes=resRow.find(nS); - if(iterRes==resRow.end()) - resRow.insert(std::make_pair(nS,surf)); - else - { - surf+=(*iterRes).second; - resRow.erase(nS); - resRow.insert(std::make_pair(nS,surf)); - } - } - } - } - } - } -} -#undef BASE_INTERSECTOR - -#endif diff --git a/src/INTERP_KERNEL/CurveIntersectorP1P1PL.hxx b/src/INTERP_KERNEL/CurveIntersectorP1P1PL.hxx deleted file mode 100644 index d9bab059b..000000000 --- a/src/INTERP_KERNEL/CurveIntersectorP1P1PL.hxx +++ /dev/null @@ -1,50 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 -// 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 (EDF R&D) - -#ifndef __CURVEINTERSECTORP1P1PL_HXX__ -#define __CURVEINTERSECTORP1P1PL_HXX__ - -#include "CurveIntersector.hxx" - -namespace INTERP_KERNEL -{ - template - class CurveIntersectorP1P1PL : public CurveIntersector - { - public: - static const int SPACEDIM=MyMeshType::MY_SPACEDIM; - static const int MESHDIM=MyMeshType::MY_MESHDIM; - typedef typename MyMeshType::MyConnType ConnType; - static const NumberingPolicy numPol=MyMeshType::My_numPol; - - CurveIntersectorP1P1PL(const MyMeshType& meshT, const MyMeshType& meshS, - double precision, double tolerance, - double medianLine, int printLevel); - public: - void intersectCells(ConnType icellT, const std::vector& icellsS, MyMatrix& res); - int getNumberOfRowsOfResMatrix() const; - int getNumberOfColsOfResMatrix() const; - private: - static void AppendValueInMatrix(MyMatrix& res, ConnType nodeIdT, ConnType nodeIdS0, double val0, ConnType nodeIdS1, double val1); - static void AppendValueInMatrix2(typename MyMatrix::value_type& resRow, ConnType nodeIdS0, double val0); - }; -} - -#endif diff --git a/src/INTERP_KERNEL/CurveIntersectorP1P1PL.txx b/src/INTERP_KERNEL/CurveIntersectorP1P1PL.txx deleted file mode 100644 index 02b09eb91..000000000 --- a/src/INTERP_KERNEL/CurveIntersectorP1P1PL.txx +++ /dev/null @@ -1,112 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 -// 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 (EDF R&D) - -#ifndef __CURVEINTERSECTORP1P1PL_TXX__ -#define __CURVEINTERSECTORP1P1PL_TXX__ - -#include "CurveIntersectorP1P1PL.hxx" -#include "CurveIntersector.txx" - -#include - -namespace INTERP_KERNEL -{ - template - CurveIntersectorP1P1PL::CurveIntersectorP1P1PL(const MyMeshType& meshT, const MyMeshType& meshS, double precision, double tolerance, double medianLine, int printLevel):CurveIntersector(meshT, meshS, precision, tolerance, medianLine, printLevel) - { - } - - template - int CurveIntersectorP1P1PL::getNumberOfRowsOfResMatrix() const - { - return CurveIntersector::_meshT.getNumberOfNodes(); - } - - template - int CurveIntersectorP1P1PL::getNumberOfColsOfResMatrix() const - { - return CurveIntersector::_meshS.getNumberOfNodes(); - } - - template - void CurveIntersectorP1P1PL::AppendValueInMatrix2(typename MyMatrix::value_type& resRow, ConnType nodeIdS0, double val0) - { - typename MyMatrix::value_type::const_iterator iterRes(resRow.find(OTT::indFC(nodeIdS0))); - if(iterRes==resRow.end()) - { - resRow.insert(std::make_pair(OTT::indFC(nodeIdS0),val0)); - } - else - { - double val((*iterRes).second+val0); - resRow.erase(OTT::indFC(nodeIdS0)); - resRow.insert(std::make_pair(OTT::indFC(nodeIdS0),val)); - } - } - - template - void CurveIntersectorP1P1PL::AppendValueInMatrix(MyMatrix& res, ConnType nodeIdT, ConnType nodeIdS0, double val0, ConnType nodeIdS1, double val1) - { - typename MyMatrix::value_type& resRow(res[nodeIdT]); - AppendValueInMatrix2(resRow,nodeIdS0,val0); - AppendValueInMatrix2(resRow,nodeIdS1,val1); - } - - template - void CurveIntersectorP1P1PL::intersectCells(ConnType icellT, const std::vector& icellsS, MyMatrix& res) - { - std::vector coordsT; - if(CurveIntersector::getRealTargetCoordinates(icellT,coordsT)) - throw INTERP_KERNEL::Exception("Invalid target cell detected for meshdim==1. Only SEG2 supported !"); - assert(coordsT.size()/SPACEDIM==2); - for(typename std::vector::const_iterator iter=icellsS.begin();iter!=icellsS.end();iter++) - { - std::vector coordsS; - if(CurveIntersector::getRealSourceCoordinates(*iter,coordsS)) - throw INTERP_KERNEL::Exception("Invalid source cell detected for meshdim==1. Only SEG2 supported !"); - assert(coordsS.size()/SPACEDIM==2); - double xs0,xs1,xt0,xt1; - double lgth(CurveIntersector::intersectSegmentsInternal(&coordsT[0],&coordsS[0],xs0,xs1,xt0,xt1)); - ConnType nodeIdS0(CurveIntersector::getNodeIdOfSourceCellAt(*iter,0)); - ConnType nodeIdS1(CurveIntersector::getNodeIdOfSourceCellAt(*iter,1)); - if(lgth>0.) - { - double a,b; - // for first - ConnType nodeIdT0(CurveIntersector::getNodeIdOfTargetCellAt(icellT,0)); - if(CurveIntersector::ComputeBaryCoordsOf(xs0,xs1,xt0,a,b)) - { - a*=lgth; b*=lgth; - AppendValueInMatrix(res,nodeIdT0,nodeIdS0,a,nodeIdS1,b); - } - // - ConnType nodeIdT1(CurveIntersector::getNodeIdOfTargetCellAt(icellT,1)); - typename MyMatrix::value_type& resRow1=res[nodeIdT1]; - if(CurveIntersector::ComputeBaryCoordsOf(xs0,xs1,xt1,a,b)) - { - a*=lgth; b*=lgth; - AppendValueInMatrix(res,nodeIdT1,nodeIdS0,a,nodeIdS1,b); - } - } - } - } -} - -#endif diff --git a/src/INTERP_KERNEL/DiameterCalculator.cxx b/src/INTERP_KERNEL/DiameterCalculator.cxx deleted file mode 100644 index b89d66383..000000000 --- a/src/INTERP_KERNEL/DiameterCalculator.cxx +++ /dev/null @@ -1,745 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 -// 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 (EDF R&D) - -#include "DiameterCalculator.hxx" -#include "InterpKernelException.hxx" -#include "CellModel.hxx" - -#include -#include -#include - -using namespace INTERP_KERNEL; - -NormalizedCellType DiameterCalulatorTRI3S2::TYPE=NORM_TRI3; - -NormalizedCellType DiameterCalulatorTRI3S3::TYPE=NORM_TRI3; - -NormalizedCellType DiameterCalulatorTRI6S2::TYPE=NORM_TRI6; - -NormalizedCellType DiameterCalulatorTRI6S3::TYPE=NORM_TRI6; - -NormalizedCellType DiameterCalulatorTRI7S2::TYPE=NORM_TRI7; - -NormalizedCellType DiameterCalulatorTRI7S3::TYPE=NORM_TRI7; - -NormalizedCellType DiameterCalulatorQUAD4S2::TYPE=NORM_QUAD4; - -NormalizedCellType DiameterCalulatorQUAD4S3::TYPE=NORM_QUAD4; - -NormalizedCellType DiameterCalulatorQUAD8S2::TYPE=NORM_QUAD8; - -NormalizedCellType DiameterCalulatorQUAD8S3::TYPE=NORM_QUAD8; - -NormalizedCellType DiameterCalulatorQUAD9S2::TYPE=NORM_QUAD9; - -NormalizedCellType DiameterCalulatorQUAD9S3::TYPE=NORM_QUAD9; - -NormalizedCellType DiameterCalulatorTETRA4::TYPE=NORM_TETRA4; - -NormalizedCellType DiameterCalulatorTETRA10::TYPE=NORM_TETRA10; - -NormalizedCellType DiameterCalulatorHEXA8::TYPE=NORM_HEXA8; - -NormalizedCellType DiameterCalulatorHEXA20::TYPE=NORM_HEXA20; - -NormalizedCellType DiameterCalulatorHEXA27::TYPE=NORM_HEXA27; - -NormalizedCellType DiameterCalulatorPENTA6::TYPE=NORM_PENTA6; - -NormalizedCellType DiameterCalulatorPENTA15::TYPE=NORM_PENTA15; - -NormalizedCellType DiameterCalulatorPYRA5::TYPE=NORM_PYRA5; - -NormalizedCellType DiameterCalulatorPYRA13::TYPE=NORM_PYRA13; - -inline double SqNormV2(const double tab[2]) -{ - return tab[0]*tab[0]+tab[1]*tab[1]; -} - -inline void DiffV2(const double a[2], const double b[2], double c[2]) -{ - c[0]=a[0]-b[0]; - c[1]=a[1]-b[1]; -} - -inline double SqNormV3(const double tab[3]) -{ - return tab[0]*tab[0]+tab[1]*tab[1]+tab[2]*tab[2]; -} - -inline void DiffV3(const double a[3], const double b[3], double c[3]) -{ - c[0]=a[0]-b[0]; - c[1]=a[1]-b[1]; - c[2]=a[2]-b[2]; -} - -template -void ComputeForListOfCellIdsUMeshFrmt(const int *bgIds, const int *endIds, const int *indPtr, const int *connPtr, const double *coordsPtr, double *resPtr) -{ - Evaluator evtor; - NormalizedCellType ct(Evaluator::TYPE); - int cti((int) ct); - for(const int *it=bgIds;it!=endIds;it++) - { - int offset(indPtr[*it]); - if(connPtr[offset]==cti) - resPtr[*it]=evtor.ComputeForOneCellInternal(connPtr+offset+1,connPtr+indPtr[(*it)+1],coordsPtr); - else - { - std::ostringstream oss; oss << "DiameterCalculator::computeForListOfCellIdsUMeshFrmt : invalid nodal connectivity format at cell # " << *it << " !"; - throw Exception(oss.str().c_str()); - } - } -} - -template -void ComputeForRangeOfCellIdsUMeshFrmt(int bgId, int endId, const int *indPtr, const int *connPtr, const double *coordsPtr, double *resPtr) -{ - Evaluator evtor; - NormalizedCellType ct(Evaluator::TYPE); - int cti((int) ct); - for(int it=bgId;it -void ComputeFor1SGTUMeshFrmt(int nbOfCells, const int *connPtr, const double *coordsPtr, double *resPtr) -{ - Evaluator evtor; - NormalizedCellType ct(Evaluator::TYPE); - const CellModel& cm(CellModel::GetCellModel(ct)); - unsigned nbNodes(cm.getNumberOfNodes()); - const int *ptr(connPtr); - for(int i=0;i(bgIds,endIds,indPtr,connPtr,coordsPtr,resPtr); -} - -void DiameterCalulatorTRI3S2::computeForRangeOfCellIdsUMeshFrmt(int bgId, int endId, const int *indPtr, const int *connPtr, const double *coordsPtr, double *resPtr) const -{ - ComputeForRangeOfCellIdsUMeshFrmt(bgId,endId,indPtr,connPtr,coordsPtr,resPtr); -} - -void DiameterCalulatorTRI3S2::computeFor1SGTUMeshFrmt(int nbOfCells, const int *connPtr, const double *coordsPtr, double *resPtr) const -{ - ComputeFor1SGTUMeshFrmt(nbOfCells,connPtr,coordsPtr,resPtr); -} - -//================================================================= - -double DiameterCalulatorTRI3S3::ComputeForOneCellInternal(const int *bg, const int *endd, const double *coordsPtr) -{ - if(std::distance(bg,endd)==3) - { - const double *a(coordsPtr+3*bg[0]),*b(coordsPtr+3*bg[1]),*c(coordsPtr+3*bg[2]); - double l0[3],l1[3],l2[3]; - DiffV3(a,b,l0); - DiffV3(a,c,l1); - DiffV3(b,c,l2); - double res(std::max(SqNormV3(l0),SqNormV3(l1))); - res=std::max(res,SqNormV3(l2)); - return std::sqrt(res); - } - else - throw Exception("DiameterCalulatorTRI3S2::ComputeForOneCellInternal : input connectivity must be of size 3 !"); -} - -void DiameterCalulatorTRI3S3::computeForListOfCellIdsUMeshFrmt(const int *bgIds, const int *endIds, const int *indPtr, const int *connPtr, const double *coordsPtr, double *resPtr) const -{ - ComputeForListOfCellIdsUMeshFrmt(bgIds,endIds,indPtr,connPtr,coordsPtr,resPtr); -} - -void DiameterCalulatorTRI3S3::computeForRangeOfCellIdsUMeshFrmt(int bgId, int endId, const int *indPtr, const int *connPtr, const double *coordsPtr, double *resPtr) const -{ - ComputeForRangeOfCellIdsUMeshFrmt(bgId,endId,indPtr,connPtr,coordsPtr,resPtr); -} - -void DiameterCalulatorTRI3S3::computeFor1SGTUMeshFrmt(int nbOfCells, const int *connPtr, const double *coordsPtr, double *resPtr) const -{ - ComputeFor1SGTUMeshFrmt(nbOfCells,connPtr,coordsPtr,resPtr); -} - -//================================================================= - -double DiameterCalulatorTRI6S2::ComputeForOneCellInternal(const int *bg, const int *endd, const double *coordsPtr) -{ - if(std::distance(bg,endd)==6) - return DiameterCalulatorTRI3S2::ComputeForOneCellInternal(bg,bg+3,coordsPtr); - else - throw Exception("DiameterCalulatorTRI6S2::ComputeForOneCellInternal : input connectivity must be of size 6 !"); -} - -void DiameterCalulatorTRI6S2::computeForListOfCellIdsUMeshFrmt(const int *bgIds, const int *endIds, const int *indPtr, const int *connPtr, const double *coordsPtr, double *resPtr) const -{ - ComputeForListOfCellIdsUMeshFrmt(bgIds,endIds,indPtr,connPtr,coordsPtr,resPtr); -} - -void DiameterCalulatorTRI6S2::computeForRangeOfCellIdsUMeshFrmt(int bgId, int endId, const int *indPtr, const int *connPtr, const double *coordsPtr, double *resPtr) const -{ - ComputeForRangeOfCellIdsUMeshFrmt(bgId,endId,indPtr,connPtr,coordsPtr,resPtr); -} - -void DiameterCalulatorTRI6S2::computeFor1SGTUMeshFrmt(int nbOfCells, const int *connPtr, const double *coordsPtr, double *resPtr) const -{ - ComputeFor1SGTUMeshFrmt(nbOfCells,connPtr,coordsPtr,resPtr); -} - -//================================================================= - -double DiameterCalulatorTRI6S3::ComputeForOneCellInternal(const int *bg, const int *endd, const double *coordsPtr) -{ - if(std::distance(bg,endd)==6) - return DiameterCalulatorTRI3S3::ComputeForOneCellInternal(bg,bg+3,coordsPtr); - else - throw Exception("DiameterCalulatorTRI6S3::ComputeForOneCellInternal : input connectivity must be of size 6 !"); -} - -void DiameterCalulatorTRI6S3::computeForListOfCellIdsUMeshFrmt(const int *bgIds, const int *endIds, const int *indPtr, const int *connPtr, const double *coordsPtr, double *resPtr) const -{ - ComputeForListOfCellIdsUMeshFrmt(bgIds,endIds,indPtr,connPtr,coordsPtr,resPtr); -} - -void DiameterCalulatorTRI6S3::computeForRangeOfCellIdsUMeshFrmt(int bgId, int endId, const int *indPtr, const int *connPtr, const double *coordsPtr, double *resPtr) const -{ - ComputeForRangeOfCellIdsUMeshFrmt(bgId,endId,indPtr,connPtr,coordsPtr,resPtr); -} - -void DiameterCalulatorTRI6S3::computeFor1SGTUMeshFrmt(int nbOfCells, const int *connPtr, const double *coordsPtr, double *resPtr) const -{ - ComputeFor1SGTUMeshFrmt(nbOfCells,connPtr,coordsPtr,resPtr); -} - -//================================================================= - -double DiameterCalulatorTRI7S2::ComputeForOneCellInternal(const int *bg, const int *endd, const double *coordsPtr) -{ - if(std::distance(bg,endd)==7) - return DiameterCalulatorTRI3S2::ComputeForOneCellInternal(bg,bg+3,coordsPtr); - else - throw Exception("DiameterCalulatorTRI7S2::ComputeForOneCellInternal : input connectivity must be of size 7 !"); -} - -void DiameterCalulatorTRI7S2::computeForListOfCellIdsUMeshFrmt(const int *bgIds, const int *endIds, const int *indPtr, const int *connPtr, const double *coordsPtr, double *resPtr) const -{ - ComputeForListOfCellIdsUMeshFrmt(bgIds,endIds,indPtr,connPtr,coordsPtr,resPtr); -} - -void DiameterCalulatorTRI7S2::computeForRangeOfCellIdsUMeshFrmt(int bgId, int endId, const int *indPtr, const int *connPtr, const double *coordsPtr, double *resPtr) const -{ - ComputeForRangeOfCellIdsUMeshFrmt(bgId,endId,indPtr,connPtr,coordsPtr,resPtr); -} - -void DiameterCalulatorTRI7S2::computeFor1SGTUMeshFrmt(int nbOfCells, const int *connPtr, const double *coordsPtr, double *resPtr) const -{ - ComputeFor1SGTUMeshFrmt(nbOfCells,connPtr,coordsPtr,resPtr); -} - -//================================================================= - -double DiameterCalulatorTRI7S3::ComputeForOneCellInternal(const int *bg, const int *endd, const double *coordsPtr) -{ - if(std::distance(bg,endd)==7) - return DiameterCalulatorTRI3S3::ComputeForOneCellInternal(bg,bg+3,coordsPtr); - else - throw Exception("DiameterCalulatorTRI7S3::ComputeForOneCellInternal : input connectivity must be of size 7 !"); -} - -void DiameterCalulatorTRI7S3::computeForListOfCellIdsUMeshFrmt(const int *bgIds, const int *endIds, const int *indPtr, const int *connPtr, const double *coordsPtr, double *resPtr) const -{ - ComputeForListOfCellIdsUMeshFrmt(bgIds,endIds,indPtr,connPtr,coordsPtr,resPtr); -} - -void DiameterCalulatorTRI7S3::computeForRangeOfCellIdsUMeshFrmt(int bgId, int endId, const int *indPtr, const int *connPtr, const double *coordsPtr, double *resPtr) const -{ - ComputeForRangeOfCellIdsUMeshFrmt(bgId,endId,indPtr,connPtr,coordsPtr,resPtr); -} - -void DiameterCalulatorTRI7S3::computeFor1SGTUMeshFrmt(int nbOfCells, const int *connPtr, const double *coordsPtr, double *resPtr) const -{ - ComputeFor1SGTUMeshFrmt(nbOfCells,connPtr,coordsPtr,resPtr); -} - -//================================================================= - -double DiameterCalulatorQUAD4S2::ComputeForOneCellInternal(const int *bg, const int *endd, const double *coordsPtr) -{ - if(std::distance(bg,endd)==4) - { - const double *a(coordsPtr+2*bg[0]),*b(coordsPtr+2*bg[1]),*c(coordsPtr+2*bg[2]),*d(coordsPtr+2*bg[3]); - double l0[2],l1[2]; - DiffV2(a,c,l0); - DiffV2(b,d,l1); - return std::sqrt(std::max(SqNormV2(l0),SqNormV2(l1))); - } - else - throw Exception("DiameterCalulatorQUAD4S2::ComputeForOneCellInternal : input connectivity must be of size 4 !"); -} - -void DiameterCalulatorQUAD4S2::computeForListOfCellIdsUMeshFrmt(const int *bgIds, const int *endIds, const int *indPtr, const int *connPtr, const double *coordsPtr, double *resPtr) const -{ - ComputeForListOfCellIdsUMeshFrmt(bgIds,endIds,indPtr,connPtr,coordsPtr,resPtr); -} - -void DiameterCalulatorQUAD4S2::computeForRangeOfCellIdsUMeshFrmt(int bgId, int endId, const int *indPtr, const int *connPtr, const double *coordsPtr, double *resPtr) const -{ - ComputeForRangeOfCellIdsUMeshFrmt(bgId,endId,indPtr,connPtr,coordsPtr,resPtr); -} - -void DiameterCalulatorQUAD4S2::computeFor1SGTUMeshFrmt(int nbOfCells, const int *connPtr, const double *coordsPtr, double *resPtr) const -{ - ComputeFor1SGTUMeshFrmt(nbOfCells,connPtr,coordsPtr,resPtr); -} - -//================================================================= - -double DiameterCalulatorQUAD4S3::ComputeForOneCellInternal(const int *bg, const int *endd, const double *coordsPtr) -{ - if(std::distance(bg,endd)==4) - { - const double *a(coordsPtr+3*bg[0]),*b(coordsPtr+3*bg[1]),*c(coordsPtr+3*bg[2]),*d(coordsPtr+3*bg[3]); - double l0[3],l1[3]; - DiffV3(a,c,l0); - DiffV3(b,d,l1); - return std::sqrt(std::max(SqNormV3(l0),SqNormV3(l1))); - } - else - throw Exception("DiameterCalulatorQUAD4S3::ComputeForOneCellInternal : input connectivity must be of size 4 !"); -} - -void DiameterCalulatorQUAD4S3::computeForListOfCellIdsUMeshFrmt(const int *bgIds, const int *endIds, const int *indPtr, const int *connPtr, const double *coordsPtr, double *resPtr) const -{ - ComputeForListOfCellIdsUMeshFrmt(bgIds,endIds,indPtr,connPtr,coordsPtr,resPtr); -} - -void DiameterCalulatorQUAD4S3::computeForRangeOfCellIdsUMeshFrmt(int bgId, int endId, const int *indPtr, const int *connPtr, const double *coordsPtr, double *resPtr) const -{ - ComputeForRangeOfCellIdsUMeshFrmt(bgId,endId,indPtr,connPtr,coordsPtr,resPtr); -} - -void DiameterCalulatorQUAD4S3::computeFor1SGTUMeshFrmt(int nbOfCells, const int *connPtr, const double *coordsPtr, double *resPtr) const -{ - ComputeFor1SGTUMeshFrmt(nbOfCells,connPtr,coordsPtr,resPtr); -} - -//================================================================= - -double DiameterCalulatorQUAD8S2::ComputeForOneCellInternal(const int *bg, const int *endd, const double *coordsPtr) -{ - if(std::distance(bg,endd)==8) - return DiameterCalulatorQUAD4S2::ComputeForOneCellInternal(bg,bg+4,coordsPtr); - else - throw Exception("DiameterCalulatorQUAD8S2::ComputeForOneCellInternal : input connectivity must be of size 8 !"); -} - -void DiameterCalulatorQUAD8S2::computeForListOfCellIdsUMeshFrmt(const int *bgIds, const int *endIds, const int *indPtr, const int *connPtr, const double *coordsPtr, double *resPtr) const -{ - ComputeForListOfCellIdsUMeshFrmt(bgIds,endIds,indPtr,connPtr,coordsPtr,resPtr); -} - -void DiameterCalulatorQUAD8S2::computeForRangeOfCellIdsUMeshFrmt(int bgId, int endId, const int *indPtr, const int *connPtr, const double *coordsPtr, double *resPtr) const -{ - ComputeForRangeOfCellIdsUMeshFrmt(bgId,endId,indPtr,connPtr,coordsPtr,resPtr); -} - -void DiameterCalulatorQUAD8S2::computeFor1SGTUMeshFrmt(int nbOfCells, const int *connPtr, const double *coordsPtr, double *resPtr) const -{ - ComputeFor1SGTUMeshFrmt(nbOfCells,connPtr,coordsPtr,resPtr); -} - -//================================================================= - -double DiameterCalulatorQUAD8S3::ComputeForOneCellInternal(const int *bg, const int *endd, const double *coordsPtr) -{ - if(std::distance(bg,endd)==8) - return DiameterCalulatorQUAD4S3::ComputeForOneCellInternal(bg,bg+4,coordsPtr); - else - throw Exception("DiameterCalulatorQUAD8S3::ComputeForOneCellInternal : input connectivity must be of size 8 !"); -} - -void DiameterCalulatorQUAD8S3::computeForListOfCellIdsUMeshFrmt(const int *bgIds, const int *endIds, const int *indPtr, const int *connPtr, const double *coordsPtr, double *resPtr) const -{ - ComputeForListOfCellIdsUMeshFrmt(bgIds,endIds,indPtr,connPtr,coordsPtr,resPtr); -} - -void DiameterCalulatorQUAD8S3::computeForRangeOfCellIdsUMeshFrmt(int bgId, int endId, const int *indPtr, const int *connPtr, const double *coordsPtr, double *resPtr) const -{ - ComputeForRangeOfCellIdsUMeshFrmt(bgId,endId,indPtr,connPtr,coordsPtr,resPtr); -} - -void DiameterCalulatorQUAD8S3::computeFor1SGTUMeshFrmt(int nbOfCells, const int *connPtr, const double *coordsPtr, double *resPtr) const -{ - ComputeFor1SGTUMeshFrmt(nbOfCells,connPtr,coordsPtr,resPtr); -} - -//================================================================= - -double DiameterCalulatorQUAD9S2::ComputeForOneCellInternal(const int *bg, const int *endd, const double *coordsPtr) -{ - if(std::distance(bg,endd)==9) - return DiameterCalulatorQUAD4S2::ComputeForOneCellInternal(bg,bg+4,coordsPtr); - else - throw Exception("DiameterCalulatorQUAD9S2::ComputeForOneCellInternal : input connectivity must be of size 9 !"); -} - -void DiameterCalulatorQUAD9S2::computeForListOfCellIdsUMeshFrmt(const int *bgIds, const int *endIds, const int *indPtr, const int *connPtr, const double *coordsPtr, double *resPtr) const -{ - ComputeForListOfCellIdsUMeshFrmt(bgIds,endIds,indPtr,connPtr,coordsPtr,resPtr); -} - -void DiameterCalulatorQUAD9S2::computeForRangeOfCellIdsUMeshFrmt(int bgId, int endId, const int *indPtr, const int *connPtr, const double *coordsPtr, double *resPtr) const -{ - ComputeForRangeOfCellIdsUMeshFrmt(bgId,endId,indPtr,connPtr,coordsPtr,resPtr); -} - -void DiameterCalulatorQUAD9S2::computeFor1SGTUMeshFrmt(int nbOfCells, const int *connPtr, const double *coordsPtr, double *resPtr) const -{ - ComputeFor1SGTUMeshFrmt(nbOfCells,connPtr,coordsPtr,resPtr); -} - -//================================================================= - -double DiameterCalulatorQUAD9S3::ComputeForOneCellInternal(const int *bg, const int *endd, const double *coordsPtr) -{ - if(std::distance(bg,endd)==9) - return DiameterCalulatorQUAD4S3::ComputeForOneCellInternal(bg,bg+4,coordsPtr); - else - throw Exception("DiameterCalulatorQUAD8S3::ComputeForOneCellInternal : input connectivity must be of size 9 !"); -} - -void DiameterCalulatorQUAD9S3::computeForListOfCellIdsUMeshFrmt(const int *bgIds, const int *endIds, const int *indPtr, const int *connPtr, const double *coordsPtr, double *resPtr) const -{ - ComputeForListOfCellIdsUMeshFrmt(bgIds,endIds,indPtr,connPtr,coordsPtr,resPtr); -} - -void DiameterCalulatorQUAD9S3::computeForRangeOfCellIdsUMeshFrmt(int bgId, int endId, const int *indPtr, const int *connPtr, const double *coordsPtr, double *resPtr) const -{ - ComputeForRangeOfCellIdsUMeshFrmt(bgId,endId,indPtr,connPtr,coordsPtr,resPtr); -} - -void DiameterCalulatorQUAD9S3::computeFor1SGTUMeshFrmt(int nbOfCells, const int *connPtr, const double *coordsPtr, double *resPtr) const -{ - ComputeFor1SGTUMeshFrmt(nbOfCells,connPtr,coordsPtr,resPtr); -} - -//================================================================= - -double DiameterCalulatorTETRA4::ComputeForOneCellInternal(const int *bg, const int *endd, const double *coordsPtr) -{ - if(std::distance(bg,endd)==4) - { - const double *a(coordsPtr+3*bg[0]),*b(coordsPtr+3*bg[1]),*c(coordsPtr+3*bg[2]),*d(coordsPtr+3*bg[3]); - double l0[3],l1[3],l2[3],l3[3],l4[3],l5[3]; - DiffV3(a,b,l0); - DiffV3(a,c,l1); - DiffV3(b,c,l2); - DiffV3(a,d,l3); - DiffV3(b,d,l4); - DiffV3(c,d,l5); - double tmp[6]; - tmp[0]=SqNormV3(l0); tmp[1]=SqNormV3(l1); tmp[2]=SqNormV3(l2); tmp[3]=SqNormV3(l3); tmp[4]=SqNormV3(l4); tmp[5]=SqNormV3(l5); - return std::sqrt(*std::max_element(tmp,tmp+6)); - } - else - throw Exception("DiameterCalulatorTETRA4::ComputeForOneCellInternal : input connectivity must be of size 4 !"); -} - -void DiameterCalulatorTETRA4::computeForListOfCellIdsUMeshFrmt(const int *bgIds, const int *endIds, const int *indPtr, const int *connPtr, const double *coordsPtr, double *resPtr) const -{ - ComputeForListOfCellIdsUMeshFrmt(bgIds,endIds,indPtr,connPtr,coordsPtr,resPtr); -} - -void DiameterCalulatorTETRA4::computeForRangeOfCellIdsUMeshFrmt(int bgId, int endId, const int *indPtr, const int *connPtr, const double *coordsPtr, double *resPtr) const -{ - ComputeForRangeOfCellIdsUMeshFrmt(bgId,endId,indPtr,connPtr,coordsPtr,resPtr); -} - -void DiameterCalulatorTETRA4::computeFor1SGTUMeshFrmt(int nbOfCells, const int *connPtr, const double *coordsPtr, double *resPtr) const -{ - ComputeFor1SGTUMeshFrmt(nbOfCells,connPtr,coordsPtr,resPtr); -} - -//================================================================= - -double DiameterCalulatorTETRA10::ComputeForOneCellInternal(const int *bg, const int *endd, const double *coordsPtr) -{ - if(std::distance(bg,endd)==10) - return DiameterCalulatorTETRA4::ComputeForOneCellInternal(bg,bg+4,coordsPtr); - else - throw Exception("DiameterCalulatorTETRA10::ComputeForOneCellInternal : input connectivity must be of size 10 !"); -} - -void DiameterCalulatorTETRA10::computeForListOfCellIdsUMeshFrmt(const int *bgIds, const int *endIds, const int *indPtr, const int *connPtr, const double *coordsPtr, double *resPtr) const -{ - ComputeForListOfCellIdsUMeshFrmt(bgIds,endIds,indPtr,connPtr,coordsPtr,resPtr); -} - -void DiameterCalulatorTETRA10::computeForRangeOfCellIdsUMeshFrmt(int bgId, int endId, const int *indPtr, const int *connPtr, const double *coordsPtr, double *resPtr) const -{ - ComputeForRangeOfCellIdsUMeshFrmt(bgId,endId,indPtr,connPtr,coordsPtr,resPtr); -} - -void DiameterCalulatorTETRA10::computeFor1SGTUMeshFrmt(int nbOfCells, const int *connPtr, const double *coordsPtr, double *resPtr) const -{ - ComputeFor1SGTUMeshFrmt(nbOfCells,connPtr,coordsPtr,resPtr); -} - -//================================================================= - -double DiameterCalulatorHEXA8::ComputeForOneCellInternal(const int *bg, const int *endd, const double *coordsPtr) -{ - if(std::distance(bg,endd)==8) - { - const double *p0(coordsPtr+3*bg[0]),*p1(coordsPtr+3*bg[1]),*p2(coordsPtr+3*bg[2]),*p3(coordsPtr+3*bg[3]),*p4(coordsPtr+3*bg[4]),*p5(coordsPtr+3*bg[5]),*p6(coordsPtr+3*bg[6]),*p7(coordsPtr+3*bg[7]); - double l0[3],l1[3],l2[3],l3[3]; - DiffV3(p0,p6,l0); - DiffV3(p1,p7,l1); - DiffV3(p2,p4,l2); - DiffV3(p3,p5,l3); - double tmp[4]; - tmp[0]=SqNormV3(l0); tmp[1]=SqNormV3(l1); tmp[2]=SqNormV3(l2); tmp[3]=SqNormV3(l3); - return std::sqrt(*std::max_element(tmp,tmp+4)); - } - else - throw Exception("DiameterCalulatorHEXA8::ComputeForOneCellInternal : input connectivity must be of size 8 !"); -} - -void DiameterCalulatorHEXA8::computeForListOfCellIdsUMeshFrmt(const int *bgIds, const int *endIds, const int *indPtr, const int *connPtr, const double *coordsPtr, double *resPtr) const -{ - ComputeForListOfCellIdsUMeshFrmt(bgIds,endIds,indPtr,connPtr,coordsPtr,resPtr); -} - -void DiameterCalulatorHEXA8::computeForRangeOfCellIdsUMeshFrmt(int bgId, int endId, const int *indPtr, const int *connPtr, const double *coordsPtr, double *resPtr) const -{ - ComputeForRangeOfCellIdsUMeshFrmt(bgId,endId,indPtr,connPtr,coordsPtr,resPtr); -} - -void DiameterCalulatorHEXA8::computeFor1SGTUMeshFrmt(int nbOfCells, const int *connPtr, const double *coordsPtr, double *resPtr) const -{ - ComputeFor1SGTUMeshFrmt(nbOfCells,connPtr,coordsPtr,resPtr); -} - -//================================================================= - -double DiameterCalulatorHEXA20::ComputeForOneCellInternal(const int *bg, const int *endd, const double *coordsPtr) -{ - if(std::distance(bg,endd)==20) - return DiameterCalulatorHEXA8::ComputeForOneCellInternal(bg,bg+8,coordsPtr); - else - throw Exception("DiameterCalulatorHEXA20::ComputeForOneCellInternal : input connectivity must be of size 20 !"); -} - -void DiameterCalulatorHEXA20::computeForListOfCellIdsUMeshFrmt(const int *bgIds, const int *endIds, const int *indPtr, const int *connPtr, const double *coordsPtr, double *resPtr) const -{ - ComputeForListOfCellIdsUMeshFrmt(bgIds,endIds,indPtr,connPtr,coordsPtr,resPtr); -} - -void DiameterCalulatorHEXA20::computeForRangeOfCellIdsUMeshFrmt(int bgId, int endId, const int *indPtr, const int *connPtr, const double *coordsPtr, double *resPtr) const -{ - ComputeForRangeOfCellIdsUMeshFrmt(bgId,endId,indPtr,connPtr,coordsPtr,resPtr); -} - -void DiameterCalulatorHEXA20::computeFor1SGTUMeshFrmt(int nbOfCells, const int *connPtr, const double *coordsPtr, double *resPtr) const -{ - ComputeFor1SGTUMeshFrmt(nbOfCells,connPtr,coordsPtr,resPtr); -} - -//================================================================= - -double DiameterCalulatorHEXA27::ComputeForOneCellInternal(const int *bg, const int *endd, const double *coordsPtr) -{ - if(std::distance(bg,endd)==27) - return DiameterCalulatorHEXA8::ComputeForOneCellInternal(bg,bg+8,coordsPtr); - else - throw Exception("DiameterCalulatorHEXA27::ComputeForOneCellInternal : input connectivity must be of size 27 !"); -} - -void DiameterCalulatorHEXA27::computeForListOfCellIdsUMeshFrmt(const int *bgIds, const int *endIds, const int *indPtr, const int *connPtr, const double *coordsPtr, double *resPtr) const -{ - ComputeForListOfCellIdsUMeshFrmt(bgIds,endIds,indPtr,connPtr,coordsPtr,resPtr); -} - -void DiameterCalulatorHEXA27::computeForRangeOfCellIdsUMeshFrmt(int bgId, int endId, const int *indPtr, const int *connPtr, const double *coordsPtr, double *resPtr) const -{ - ComputeForRangeOfCellIdsUMeshFrmt(bgId,endId,indPtr,connPtr,coordsPtr,resPtr); -} - -void DiameterCalulatorHEXA27::computeFor1SGTUMeshFrmt(int nbOfCells, const int *connPtr, const double *coordsPtr, double *resPtr) const -{ - ComputeFor1SGTUMeshFrmt(nbOfCells,connPtr,coordsPtr,resPtr); -} - -//================================================================= - -double DiameterCalulatorPENTA6::ComputeForOneCellInternal(const int *bg, const int *endd, const double *coordsPtr) -{ - if(std::distance(bg,endd)==6) - { - const double *p0(coordsPtr+3*bg[0]),*p1(coordsPtr+3*bg[1]),*p2(coordsPtr+3*bg[2]),*p3(coordsPtr+3*bg[3]),*p4(coordsPtr+3*bg[4]),*p5(coordsPtr+3*bg[5]); - double l0[3],l1[3],l2[3],l3[3],l4[3],l5[3]; - DiffV3(p0,p4,l0); - DiffV3(p1,p3,l1); - DiffV3(p1,p5,l2); - DiffV3(p2,p4,l3); - DiffV3(p0,p5,l4); - DiffV3(p2,p3,l5); - double tmp[6]; - tmp[0]=SqNormV3(l0); tmp[1]=SqNormV3(l1); tmp[2]=SqNormV3(l2); tmp[3]=SqNormV3(l3); tmp[4]=SqNormV3(l4); tmp[5]=SqNormV3(l5); - return std::sqrt(*std::max_element(tmp,tmp+6)); - } - else - throw Exception("DiameterCalulatorPENTA6::ComputeForOneCellInternal : input connectivity must be of size 6 !"); -} - -void DiameterCalulatorPENTA6::computeForListOfCellIdsUMeshFrmt(const int *bgIds, const int *endIds, const int *indPtr, const int *connPtr, const double *coordsPtr, double *resPtr) const -{ - ComputeForListOfCellIdsUMeshFrmt(bgIds,endIds,indPtr,connPtr,coordsPtr,resPtr); -} - -void DiameterCalulatorPENTA6::computeForRangeOfCellIdsUMeshFrmt(int bgId, int endId, const int *indPtr, const int *connPtr, const double *coordsPtr, double *resPtr) const -{ - ComputeForRangeOfCellIdsUMeshFrmt(bgId,endId,indPtr,connPtr,coordsPtr,resPtr); -} - -void DiameterCalulatorPENTA6::computeFor1SGTUMeshFrmt(int nbOfCells, const int *connPtr, const double *coordsPtr, double *resPtr) const -{ - ComputeFor1SGTUMeshFrmt(nbOfCells,connPtr,coordsPtr,resPtr); -} - -//================================================================= - -double DiameterCalulatorPENTA15::ComputeForOneCellInternal(const int *bg, const int *endd, const double *coordsPtr) -{ - if(std::distance(bg,endd)==15) - return DiameterCalulatorPENTA6::ComputeForOneCellInternal(bg,bg+6,coordsPtr); - else - throw Exception("DiameterCalulatorPENTA15::ComputeForOneCellInternal : input connectivity must be of size 15 !"); -} - -void DiameterCalulatorPENTA15::computeForListOfCellIdsUMeshFrmt(const int *bgIds, const int *endIds, const int *indPtr, const int *connPtr, const double *coordsPtr, double *resPtr) const -{ - ComputeForListOfCellIdsUMeshFrmt(bgIds,endIds,indPtr,connPtr,coordsPtr,resPtr); -} - -void DiameterCalulatorPENTA15::computeForRangeOfCellIdsUMeshFrmt(int bgId, int endId, const int *indPtr, const int *connPtr, const double *coordsPtr, double *resPtr) const -{ - ComputeForRangeOfCellIdsUMeshFrmt(bgId,endId,indPtr,connPtr,coordsPtr,resPtr); -} - -void DiameterCalulatorPENTA15::computeFor1SGTUMeshFrmt(int nbOfCells, const int *connPtr, const double *coordsPtr, double *resPtr) const -{ - ComputeFor1SGTUMeshFrmt(nbOfCells,connPtr,coordsPtr,resPtr); -} - -//================================================================= - -double DiameterCalulatorPYRA5::ComputeForOneCellInternal(const int *bg, const int *endd, const double *coordsPtr) -{ - if(std::distance(bg,endd)==5) - { - const double *p0(coordsPtr+3*bg[0]),*p1(coordsPtr+3*bg[1]),*p2(coordsPtr+3*bg[2]),*p3(coordsPtr+3*bg[3]),*p4(coordsPtr+3*bg[4]); - double l0[3],l1[3],l2[3],l3[3],l4[3],l5[3]; - DiffV3(p0,p2,l0); - DiffV3(p1,p3,l1); - DiffV3(p0,p4,l2); - DiffV3(p1,p4,l3); - DiffV3(p2,p4,l4); - DiffV3(p3,p4,l5); - double tmp[6]; - tmp[0]=SqNormV3(l0); tmp[1]=SqNormV3(l1); tmp[2]=SqNormV3(l2); tmp[3]=SqNormV3(l3); tmp[4]=SqNormV3(l4); tmp[5]=SqNormV3(l5); - return std::sqrt(*std::max_element(tmp,tmp+6)); - } - else - throw Exception("DiameterCalulatorPYRA5::ComputeForOneCellInternal : input connectivity must be of size 5 !"); -} - -void DiameterCalulatorPYRA5::computeForListOfCellIdsUMeshFrmt(const int *bgIds, const int *endIds, const int *indPtr, const int *connPtr, const double *coordsPtr, double *resPtr) const -{ - ComputeForListOfCellIdsUMeshFrmt(bgIds,endIds,indPtr,connPtr,coordsPtr,resPtr); -} - -void DiameterCalulatorPYRA5::computeForRangeOfCellIdsUMeshFrmt(int bgId, int endId, const int *indPtr, const int *connPtr, const double *coordsPtr, double *resPtr) const -{ - ComputeForRangeOfCellIdsUMeshFrmt(bgId,endId,indPtr,connPtr,coordsPtr,resPtr); -} - -void DiameterCalulatorPYRA5::computeFor1SGTUMeshFrmt(int nbOfCells, const int *connPtr, const double *coordsPtr, double *resPtr) const -{ - ComputeFor1SGTUMeshFrmt(nbOfCells,connPtr,coordsPtr,resPtr); -} - -//================================================================= - -double DiameterCalulatorPYRA13::ComputeForOneCellInternal(const int *bg, const int *endd, const double *coordsPtr) -{ - if(std::distance(bg,endd)==13) - return DiameterCalulatorPYRA5::ComputeForOneCellInternal(bg,bg+5,coordsPtr); - else - throw Exception("DiameterCalulatorPYRA13::ComputeForOneCellInternal : input connectivity must be of size 13 !"); -} - -void DiameterCalulatorPYRA13::computeForListOfCellIdsUMeshFrmt(const int *bgIds, const int *endIds, const int *indPtr, const int *connPtr, const double *coordsPtr, double *resPtr) const -{ - ComputeForListOfCellIdsUMeshFrmt(bgIds,endIds,indPtr,connPtr,coordsPtr,resPtr); -} - -void DiameterCalulatorPYRA13::computeForRangeOfCellIdsUMeshFrmt(int bgId, int endId, const int *indPtr, const int *connPtr, const double *coordsPtr, double *resPtr) const -{ - ComputeForRangeOfCellIdsUMeshFrmt(bgId,endId,indPtr,connPtr,coordsPtr,resPtr); -} - -void DiameterCalulatorPYRA13::computeFor1SGTUMeshFrmt(int nbOfCells, const int *connPtr, const double *coordsPtr, double *resPtr) const -{ - ComputeFor1SGTUMeshFrmt(nbOfCells,connPtr,coordsPtr,resPtr); -} diff --git a/src/INTERP_KERNEL/DiameterCalculator.hxx b/src/INTERP_KERNEL/DiameterCalculator.hxx deleted file mode 100644 index a2a0a19f1..000000000 --- a/src/INTERP_KERNEL/DiameterCalculator.hxx +++ /dev/null @@ -1,315 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 -// 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 (EDF R&D) - -#ifndef __DIAMETERCALCULATOR_HXX__ -#define __DIAMETERCALCULATOR_HXX__ - -#include "INTERPKERNELDefines.hxx" - -#include "NormalizedGeometricTypes" - -namespace INTERP_KERNEL -{ - class DiameterCalculator - { - public: - INTERPKERNEL_EXPORT virtual ~DiameterCalculator() { } - INTERPKERNEL_EXPORT virtual NormalizedCellType getType() const = 0; - INTERPKERNEL_EXPORT virtual double computeForOneCell(const int *bg, const int *endd, const double *coordsPtr) const = 0; - INTERPKERNEL_EXPORT virtual void computeForListOfCellIdsUMeshFrmt(const int *bgIds, const int *endIds, const int *indPtr, const int *connPtr, const double *coordsPtr, double *resPtr) const = 0; - INTERPKERNEL_EXPORT virtual void computeForRangeOfCellIdsUMeshFrmt(int bgId, int endId, const int *indPtr, const int *connPtr, const double *coordsPtr, double *resPtr) const = 0; - INTERPKERNEL_EXPORT virtual void computeFor1SGTUMeshFrmt(int nbOfCells, const int *connPtr, const double *coordsPtr, double *resPtr) const = 0; - }; - - class DiameterCalulatorTRI3S2 : public DiameterCalculator - { - public: - NormalizedCellType getType() const { return TYPE; } - double computeForOneCell(const int *bg, const int *endd, const double *coordsPtr) const { return ComputeForOneCellInternal(bg,endd,coordsPtr); } - static double ComputeForOneCellInternal(const int *bg, const int *endd, const double *coordsPtr); - void computeForListOfCellIdsUMeshFrmt(const int *bgIds, const int *endIds, const int *indPtr, const int *connPtr, const double *coordsPtr, double *resPtr) const; - void computeForRangeOfCellIdsUMeshFrmt(int bgId, int endId, const int *indPtr, const int *connPtr, const double *coordsPtr, double *resPtr) const; - void computeFor1SGTUMeshFrmt(int nbOfCells, const int *connPtr, const double *coordsPtr, double *resPtr) const; - public: - static NormalizedCellType TYPE; - }; - - class DiameterCalulatorTRI3S3 : public DiameterCalculator - { - public: - NormalizedCellType getType() const { return TYPE; } - double computeForOneCell(const int *bg, const int *endd, const double *coordsPtr) const { return ComputeForOneCellInternal(bg,endd,coordsPtr); } - static double ComputeForOneCellInternal(const int *bg, const int *endd, const double *coordsPtr); - void computeForListOfCellIdsUMeshFrmt(const int *bgIds, const int *endIds, const int *indPtr, const int *connPtr, const double *coordsPtr, double *resPtr) const; - void computeForRangeOfCellIdsUMeshFrmt(int bgId, int endId, const int *indPtr, const int *connPtr, const double *coordsPtr, double *resPtr) const; - void computeFor1SGTUMeshFrmt(int nbOfCells, const int *connPtr, const double *coordsPtr, double *resPtr) const; - public: - static NormalizedCellType TYPE; - }; - - class DiameterCalulatorTRI6S2 : public DiameterCalculator - { - public: - NormalizedCellType getType() const { return TYPE; } - double computeForOneCell(const int *bg, const int *endd, const double *coordsPtr) const { return ComputeForOneCellInternal(bg,endd,coordsPtr); } - static double ComputeForOneCellInternal(const int *bg, const int *endd, const double *coordsPtr); - void computeForListOfCellIdsUMeshFrmt(const int *bgIds, const int *endIds, const int *indPtr, const int *connPtr, const double *coordsPtr, double *resPtr) const; - void computeForRangeOfCellIdsUMeshFrmt(int bgId, int endId, const int *indPtr, const int *connPtr, const double *coordsPtr, double *resPtr) const; - void computeFor1SGTUMeshFrmt(int nbOfCells, const int *connPtr, const double *coordsPtr, double *resPtr) const; - public: - static NormalizedCellType TYPE; - }; - - class DiameterCalulatorTRI6S3 : public DiameterCalculator - { - public: - NormalizedCellType getType() const { return TYPE; } - double computeForOneCell(const int *bg, const int *endd, const double *coordsPtr) const { return ComputeForOneCellInternal(bg,endd,coordsPtr); } - static double ComputeForOneCellInternal(const int *bg, const int *endd, const double *coordsPtr); - void computeForListOfCellIdsUMeshFrmt(const int *bgIds, const int *endIds, const int *indPtr, const int *connPtr, const double *coordsPtr, double *resPtr) const; - void computeForRangeOfCellIdsUMeshFrmt(int bgId, int endId, const int *indPtr, const int *connPtr, const double *coordsPtr, double *resPtr) const; - void computeFor1SGTUMeshFrmt(int nbOfCells, const int *connPtr, const double *coordsPtr, double *resPtr) const; - public: - static NormalizedCellType TYPE; - }; - - class DiameterCalulatorTRI7S2 : public DiameterCalculator - { - public: - NormalizedCellType getType() const { return TYPE; } - double computeForOneCell(const int *bg, const int *endd, const double *coordsPtr) const { return ComputeForOneCellInternal(bg,endd,coordsPtr); } - static double ComputeForOneCellInternal(const int *bg, const int *endd, const double *coordsPtr); - void computeForListOfCellIdsUMeshFrmt(const int *bgIds, const int *endIds, const int *indPtr, const int *connPtr, const double *coordsPtr, double *resPtr) const; - void computeForRangeOfCellIdsUMeshFrmt(int bgId, int endId, const int *indPtr, const int *connPtr, const double *coordsPtr, double *resPtr) const; - void computeFor1SGTUMeshFrmt(int nbOfCells, const int *connPtr, const double *coordsPtr, double *resPtr) const; - public: - static NormalizedCellType TYPE; - }; - - class DiameterCalulatorTRI7S3 : public DiameterCalculator - { - public: - NormalizedCellType getType() const { return TYPE; } - double computeForOneCell(const int *bg, const int *endd, const double *coordsPtr) const { return ComputeForOneCellInternal(bg,endd,coordsPtr); } - static double ComputeForOneCellInternal(const int *bg, const int *endd, const double *coordsPtr); - void computeForListOfCellIdsUMeshFrmt(const int *bgIds, const int *endIds, const int *indPtr, const int *connPtr, const double *coordsPtr, double *resPtr) const; - void computeForRangeOfCellIdsUMeshFrmt(int bgId, int endId, const int *indPtr, const int *connPtr, const double *coordsPtr, double *resPtr) const; - void computeFor1SGTUMeshFrmt(int nbOfCells, const int *connPtr, const double *coordsPtr, double *resPtr) const; - public: - static NormalizedCellType TYPE; - }; - - class DiameterCalulatorQUAD4S2 : public DiameterCalculator - { - public: - NormalizedCellType getType() const { return TYPE; } - double computeForOneCell(const int *bg, const int *endd, const double *coordsPtr) const { return ComputeForOneCellInternal(bg,endd,coordsPtr); } - static double ComputeForOneCellInternal(const int *bg, const int *endd, const double *coordsPtr); - void computeForListOfCellIdsUMeshFrmt(const int *bgIds, const int *endIds, const int *indPtr, const int *connPtr, const double *coordsPtr, double *resPtr) const; - void computeForRangeOfCellIdsUMeshFrmt(int bgId, int endId, const int *indPtr, const int *connPtr, const double *coordsPtr, double *resPtr) const; - void computeFor1SGTUMeshFrmt(int nbOfCells, const int *connPtr, const double *coordsPtr, double *resPtr) const; - public: - static NormalizedCellType TYPE; - }; - - class DiameterCalulatorQUAD4S3 : public DiameterCalculator - { - public: - NormalizedCellType getType() const { return TYPE; } - double computeForOneCell(const int *bg, const int *endd, const double *coordsPtr) const { return ComputeForOneCellInternal(bg,endd,coordsPtr); } - static double ComputeForOneCellInternal(const int *bg, const int *endd, const double *coordsPtr); - void computeForListOfCellIdsUMeshFrmt(const int *bgIds, const int *endIds, const int *indPtr, const int *connPtr, const double *coordsPtr, double *resPtr) const; - void computeForRangeOfCellIdsUMeshFrmt(int bgId, int endId, const int *indPtr, const int *connPtr, const double *coordsPtr, double *resPtr) const; - void computeFor1SGTUMeshFrmt(int nbOfCells, const int *connPtr, const double *coordsPtr, double *resPtr) const; - public: - static NormalizedCellType TYPE; - }; - - class DiameterCalulatorQUAD8S2 : public DiameterCalculator - { - public: - NormalizedCellType getType() const { return TYPE; } - double computeForOneCell(const int *bg, const int *endd, const double *coordsPtr) const { return ComputeForOneCellInternal(bg,endd,coordsPtr); } - static double ComputeForOneCellInternal(const int *bg, const int *endd, const double *coordsPtr); - void computeForListOfCellIdsUMeshFrmt(const int *bgIds, const int *endIds, const int *indPtr, const int *connPtr, const double *coordsPtr, double *resPtr) const; - void computeForRangeOfCellIdsUMeshFrmt(int bgId, int endId, const int *indPtr, const int *connPtr, const double *coordsPtr, double *resPtr) const; - void computeFor1SGTUMeshFrmt(int nbOfCells, const int *connPtr, const double *coordsPtr, double *resPtr) const; - public: - static NormalizedCellType TYPE; - }; - - class DiameterCalulatorQUAD8S3 : public DiameterCalculator - { - public: - NormalizedCellType getType() const { return TYPE; } - double computeForOneCell(const int *bg, const int *endd, const double *coordsPtr) const { return ComputeForOneCellInternal(bg,endd,coordsPtr); } - static double ComputeForOneCellInternal(const int *bg, const int *endd, const double *coordsPtr); - void computeForListOfCellIdsUMeshFrmt(const int *bgIds, const int *endIds, const int *indPtr, const int *connPtr, const double *coordsPtr, double *resPtr) const; - void computeForRangeOfCellIdsUMeshFrmt(int bgId, int endId, const int *indPtr, const int *connPtr, const double *coordsPtr, double *resPtr) const; - void computeFor1SGTUMeshFrmt(int nbOfCells, const int *connPtr, const double *coordsPtr, double *resPtr) const; - public: - static NormalizedCellType TYPE; - }; - - class DiameterCalulatorQUAD9S2 : public DiameterCalculator - { - public: - NormalizedCellType getType() const { return TYPE; } - double computeForOneCell(const int *bg, const int *endd, const double *coordsPtr) const { return ComputeForOneCellInternal(bg,endd,coordsPtr); } - static double ComputeForOneCellInternal(const int *bg, const int *endd, const double *coordsPtr); - void computeForListOfCellIdsUMeshFrmt(const int *bgIds, const int *endIds, const int *indPtr, const int *connPtr, const double *coordsPtr, double *resPtr) const; - void computeForRangeOfCellIdsUMeshFrmt(int bgId, int endId, const int *indPtr, const int *connPtr, const double *coordsPtr, double *resPtr) const; - void computeFor1SGTUMeshFrmt(int nbOfCells, const int *connPtr, const double *coordsPtr, double *resPtr) const; - public: - static NormalizedCellType TYPE; - }; - - class DiameterCalulatorQUAD9S3 : public DiameterCalculator - { - public: - NormalizedCellType getType() const { return TYPE; } - double computeForOneCell(const int *bg, const int *endd, const double *coordsPtr) const { return ComputeForOneCellInternal(bg,endd,coordsPtr); } - static double ComputeForOneCellInternal(const int *bg, const int *endd, const double *coordsPtr); - void computeForListOfCellIdsUMeshFrmt(const int *bgIds, const int *endIds, const int *indPtr, const int *connPtr, const double *coordsPtr, double *resPtr) const; - void computeForRangeOfCellIdsUMeshFrmt(int bgId, int endId, const int *indPtr, const int *connPtr, const double *coordsPtr, double *resPtr) const; - void computeFor1SGTUMeshFrmt(int nbOfCells, const int *connPtr, const double *coordsPtr, double *resPtr) const; - public: - static NormalizedCellType TYPE; - }; - - class DiameterCalulatorTETRA4 : public DiameterCalculator - { - public: - NormalizedCellType getType() const { return TYPE; } - double computeForOneCell(const int *bg, const int *endd, const double *coordsPtr) const { return ComputeForOneCellInternal(bg,endd,coordsPtr); } - static double ComputeForOneCellInternal(const int *bg, const int *endd, const double *coordsPtr); - void computeForListOfCellIdsUMeshFrmt(const int *bgIds, const int *endIds, const int *indPtr, const int *connPtr, const double *coordsPtr, double *resPtr) const; - void computeForRangeOfCellIdsUMeshFrmt(int bgId, int endId, const int *indPtr, const int *connPtr, const double *coordsPtr, double *resPtr) const; - void computeFor1SGTUMeshFrmt(int nbOfCells, const int *connPtr, const double *coordsPtr, double *resPtr) const; - public: - static NormalizedCellType TYPE; - }; - - class DiameterCalulatorTETRA10 : public DiameterCalculator - { - public: - NormalizedCellType getType() const { return TYPE; } - double computeForOneCell(const int *bg, const int *endd, const double *coordsPtr) const { return ComputeForOneCellInternal(bg,endd,coordsPtr); } - static double ComputeForOneCellInternal(const int *bg, const int *endd, const double *coordsPtr); - void computeForListOfCellIdsUMeshFrmt(const int *bgIds, const int *endIds, const int *indPtr, const int *connPtr, const double *coordsPtr, double *resPtr) const; - void computeForRangeOfCellIdsUMeshFrmt(int bgId, int endId, const int *indPtr, const int *connPtr, const double *coordsPtr, double *resPtr) const; - void computeFor1SGTUMeshFrmt(int nbOfCells, const int *connPtr, const double *coordsPtr, double *resPtr) const; - public: - static NormalizedCellType TYPE; - }; - - class DiameterCalulatorHEXA8 : public DiameterCalculator - { - public: - NormalizedCellType getType() const { return TYPE; } - double computeForOneCell(const int *bg, const int *endd, const double *coordsPtr) const { return ComputeForOneCellInternal(bg,endd,coordsPtr); } - static double ComputeForOneCellInternal(const int *bg, const int *endd, const double *coordsPtr); - void computeForListOfCellIdsUMeshFrmt(const int *bgIds, const int *endIds, const int *indPtr, const int *connPtr, const double *coordsPtr, double *resPtr) const; - void computeForRangeOfCellIdsUMeshFrmt(int bgId, int endId, const int *indPtr, const int *connPtr, const double *coordsPtr, double *resPtr) const; - void computeFor1SGTUMeshFrmt(int nbOfCells, const int *connPtr, const double *coordsPtr, double *resPtr) const; - public: - static NormalizedCellType TYPE; - }; - - class DiameterCalulatorHEXA20 : public DiameterCalculator - { - public: - NormalizedCellType getType() const { return TYPE; } - double computeForOneCell(const int *bg, const int *endd, const double *coordsPtr) const { return ComputeForOneCellInternal(bg,endd,coordsPtr); } - static double ComputeForOneCellInternal(const int *bg, const int *endd, const double *coordsPtr); - void computeForListOfCellIdsUMeshFrmt(const int *bgIds, const int *endIds, const int *indPtr, const int *connPtr, const double *coordsPtr, double *resPtr) const; - void computeForRangeOfCellIdsUMeshFrmt(int bgId, int endId, const int *indPtr, const int *connPtr, const double *coordsPtr, double *resPtr) const; - void computeFor1SGTUMeshFrmt(int nbOfCells, const int *connPtr, const double *coordsPtr, double *resPtr) const; - public: - static NormalizedCellType TYPE; - }; - - class DiameterCalulatorHEXA27 : public DiameterCalculator - { - public: - NormalizedCellType getType() const { return TYPE; } - double computeForOneCell(const int *bg, const int *endd, const double *coordsPtr) const { return ComputeForOneCellInternal(bg,endd,coordsPtr); } - static double ComputeForOneCellInternal(const int *bg, const int *endd, const double *coordsPtr); - void computeForListOfCellIdsUMeshFrmt(const int *bgIds, const int *endIds, const int *indPtr, const int *connPtr, const double *coordsPtr, double *resPtr) const; - void computeForRangeOfCellIdsUMeshFrmt(int bgId, int endId, const int *indPtr, const int *connPtr, const double *coordsPtr, double *resPtr) const; - void computeFor1SGTUMeshFrmt(int nbOfCells, const int *connPtr, const double *coordsPtr, double *resPtr) const; - public: - static NormalizedCellType TYPE; - }; - - class DiameterCalulatorPENTA6 : public DiameterCalculator - { - public: - NormalizedCellType getType() const { return TYPE; } - double computeForOneCell(const int *bg, const int *endd, const double *coordsPtr) const { return ComputeForOneCellInternal(bg,endd,coordsPtr); } - static double ComputeForOneCellInternal(const int *bg, const int *endd, const double *coordsPtr); - void computeForListOfCellIdsUMeshFrmt(const int *bgIds, const int *endIds, const int *indPtr, const int *connPtr, const double *coordsPtr, double *resPtr) const; - void computeForRangeOfCellIdsUMeshFrmt(int bgId, int endId, const int *indPtr, const int *connPtr, const double *coordsPtr, double *resPtr) const; - void computeFor1SGTUMeshFrmt(int nbOfCells, const int *connPtr, const double *coordsPtr, double *resPtr) const; - public: - static NormalizedCellType TYPE; - }; - - class DiameterCalulatorPENTA15 : public DiameterCalculator - { - public: - NormalizedCellType getType() const { return TYPE; } - double computeForOneCell(const int *bg, const int *endd, const double *coordsPtr) const { return ComputeForOneCellInternal(bg,endd,coordsPtr); } - static double ComputeForOneCellInternal(const int *bg, const int *endd, const double *coordsPtr); - void computeForListOfCellIdsUMeshFrmt(const int *bgIds, const int *endIds, const int *indPtr, const int *connPtr, const double *coordsPtr, double *resPtr) const; - void computeForRangeOfCellIdsUMeshFrmt(int bgId, int endId, const int *indPtr, const int *connPtr, const double *coordsPtr, double *resPtr) const; - void computeFor1SGTUMeshFrmt(int nbOfCells, const int *connPtr, const double *coordsPtr, double *resPtr) const; - public: - static NormalizedCellType TYPE; - }; - - class DiameterCalulatorPYRA5 : public DiameterCalculator - { - public: - NormalizedCellType getType() const { return TYPE; } - double computeForOneCell(const int *bg, const int *endd, const double *coordsPtr) const { return ComputeForOneCellInternal(bg,endd,coordsPtr); } - static double ComputeForOneCellInternal(const int *bg, const int *endd, const double *coordsPtr); - void computeForListOfCellIdsUMeshFrmt(const int *bgIds, const int *endIds, const int *indPtr, const int *connPtr, const double *coordsPtr, double *resPtr) const; - void computeForRangeOfCellIdsUMeshFrmt(int bgId, int endId, const int *indPtr, const int *connPtr, const double *coordsPtr, double *resPtr) const; - void computeFor1SGTUMeshFrmt(int nbOfCells, const int *connPtr, const double *coordsPtr, double *resPtr) const; - public: - static NormalizedCellType TYPE; - }; - - class DiameterCalulatorPYRA13 : public DiameterCalculator - { - public: - NormalizedCellType getType() const { return TYPE; } - double computeForOneCell(const int *bg, const int *endd, const double *coordsPtr) const { return ComputeForOneCellInternal(bg,endd,coordsPtr); } - static double ComputeForOneCellInternal(const int *bg, const int *endd, const double *coordsPtr); - void computeForListOfCellIdsUMeshFrmt(const int *bgIds, const int *endIds, const int *indPtr, const int *connPtr, const double *coordsPtr, double *resPtr) const; - void computeForRangeOfCellIdsUMeshFrmt(int bgId, int endId, const int *indPtr, const int *connPtr, const double *coordsPtr, double *resPtr) const; - void computeFor1SGTUMeshFrmt(int nbOfCells, const int *connPtr, const double *coordsPtr, double *resPtr) const; - public: - static NormalizedCellType TYPE; - }; -} - -#endif diff --git a/src/INTERP_KERNEL/DirectedBoundingBox.cxx b/src/INTERP_KERNEL/DirectedBoundingBox.cxx deleted file mode 100644 index 113a905f1..000000000 --- a/src/INTERP_KERNEL/DirectedBoundingBox.cxx +++ /dev/null @@ -1,757 +0,0 @@ -// Copyright (C) 2009-2015 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, 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 -// 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 -// -// File : DirectedBoundingBox.cxx -// Created : Mon Apr 12 14:41:22 2010 -// Author : Edward AGAPOV (eap) - -#include "DirectedBoundingBox.hxx" - -#include "InterpolationUtils.hxx" - -#define __TENSOR(i,j) tensor[(i)*_dim+(j)] -#define __AXIS(i) (&_axes[(i)*_dim]) -#define __MIN(i) _minmax[i*2] -#define __MAX(i) _minmax[i*2+1] -#define __MYID (long(this)%10000) -#define __DMP(msg) \ - // cout << msg << endl - -using namespace std; - -namespace -{ - //================================================================================ - /*! - * \brief Add point coordinates to inertia tensor in 3D space - */ - //================================================================================ - - inline void addPointToInertiaTensor3D(const double* coord, - const double* gc, - vector& tensor) - { - // we fill the upper triangle of tensor only - const int _dim = 3; - double x = coord[0] - gc[0], y = coord[1] - gc[1], z = coord[2] - gc[2]; - __TENSOR(0,0) += y*y + z*z; - __TENSOR(1,1) += x*x + z*z; - __TENSOR(2,2) += x*x + y*y; - __TENSOR(0,1) -= x*y; - __TENSOR(0,2) -= x*z; - __TENSOR(1,2) -= y*z; - } - //================================================================================ - /*! - * \brief Add point coordinates to inertia tensor in 2D space - */ - //================================================================================ - - inline void addPointToInertiaTensor2D(const double* coord, - const double* gc, - vector& tensor) - { - // we fill the upper triangle of tensor only - const int _dim = 2; - double x = coord[0] - gc[0], y = coord[1] - gc[1]; - __TENSOR(0,0) += y*y; - __TENSOR(1,1) += x*x; - __TENSOR(0,1) -= x*y; - } - - //================================================================================ - /*! - * \brief Find eigenvectors of tensor using Jacobi's method - */ - //================================================================================ - - bool JacobiEigenvectorsSearch( const int _dim, vector& tensor, vector& _axes) - { - if ( _dim == 3 ) - { - __DMP( "Tensor : {" - << "{ "<<__TENSOR(0,0) << ", "<<__TENSOR(0,1) << ", "<<__TENSOR(0,2) << "} " - << "{ "<<__TENSOR(1,0) << ", "<<__TENSOR(1,1) << ", "<<__TENSOR(1,2) << "} " - << "{ "<<__TENSOR(2,0) << ", "<<__TENSOR(2,1) << ", "<<__TENSOR(2,2) << "}} "); - } - else - { - __DMP( "Tensor : {" - << "{ "<<__TENSOR(0,0) << ", "<<__TENSOR(0,1) << "} " - << "{ "<<__TENSOR(1,0) << ", "<<__TENSOR(1,1) << "}} "); - } - - const int maxRot = 5*_dim*_dim; // limit on number of rotations - const double tol = 1e-9; - - // set _axes to identity - int i,j; - for ( i = 0; i < _dim; ++i ) - for ( j = 0; j < _dim; ++j ) - __AXIS(i)[j] = ( i==j ? 1. : 0 ); - - bool solved = false; - for ( int iRot = 0; iRot < maxRot; ++ iRot ) - { - // find max off-diagonal element of the tensor - int k = 0, l = 0; - double max = 0.; - for ( i = 0; i < _dim-1; ++i ) - for ( j = i+1; j < _dim; ++j ) - if ( fabs( __TENSOR(i,j)) > max ) - max = fabs( __TENSOR(i,j) ), k = i, l = j; - solved = ( max < tol ); - if ( solved ) - break; - - // Rotate to make __TENSOR(k,l) == 0 - - double diff = __TENSOR(l,l) - __TENSOR(k,k); - double t; // tangent of rotation angle - if ( fabs(__TENSOR(k,l)) < abs(diff)*1.0e-36) - { - t = __TENSOR(k,l)/diff; - } - else - { - double phi = diff/(2.0*__TENSOR(k,l)); - t = 1.0/(abs(phi) + sqrt(phi*phi + 1.0)); - if ( phi < 0.0) t = -t; - } - double c = 1.0/sqrt(t*t + 1.0); // cosine of rotation angle - double s = t*c; // sine of rotation angle - double tau = s/(1.0 + c); - __TENSOR(k,k) -= t*__TENSOR(k,l); - __TENSOR(l,l) += t*__TENSOR(k,l); - __TENSOR(k,l) = 0.0; - -#define __ROTATE(T,r1,c1,r2,c2) \ -{ \ -int i1 = r1*_dim+c1, i2 = r2*_dim+c2; \ -double t1 = T[i1], t2 = T[i2]; \ -T[i1] -= s * ( t2 + tau * t1);\ -T[i2] += s * ( t1 - tau * t2);\ -} - for ( i = 0; i < k; ++i ) // Case of i < k - __ROTATE(tensor, i,k,i,l); - - for ( i = k+1; i < l; ++i ) // Case of k < i < l - __ROTATE(tensor, k,i,i,l); - - for ( i = l + 1; i < _dim; ++i ) // Case of i > l - __ROTATE(tensor, k,i,l,i); - - for ( i = 0; i < _dim; ++i ) // Update transformation matrix - __ROTATE(_axes, i,k,i,l); - } - - __DMP( "Solved = " << solved ); - if ( _dim == 3 ) { - __DMP( " Eigen " << __TENSOR(0,0)<<", "<<__TENSOR(1,1)<<", "<<__TENSOR(2,2) ); - for ( int ii=0; ii <3; ++ii ) - __DMP( ii << ": " << __AXIS(ii)[0] << ", " << __AXIS(ii)[1] << ", " << __AXIS(ii)[2] ); - } - else { - __DMP( " Eigen " << __TENSOR(0,0) << ", " << __TENSOR(1,1) ); - for ( int ii=0; ii <2; ++ii ) - __DMP( ii << ": " << __AXIS(ii)[0] << ", " << __AXIS(ii)[1] ); - } - - return solved; - } - - //================================================================================ - /*! - * \brief Return true if two minmaxes do not intersect - */ - //================================================================================ - - inline bool isMinMaxOut(const double* minmax1, - const double* minmax2, - int dim) - { - for ( int i = 0; i < dim; ++i ) - { - if ( minmax1[i*2] > minmax2[i*2+1] || - minmax1[i*2+1] < minmax2[i*2] ) - return true; - } - return false; - } - -} // noname namespace - -namespace INTERP_KERNEL -{ - - //================================================================================ - /*! - * \brief Creates empty box intended to further initalization via setData() - */ - //================================================================================ - - DirectedBoundingBox::DirectedBoundingBox():_dim(0) - { - } - - //================================================================================ - /*! - * \brief Creates bounding box of a mesh - * \param pts - coordinates of points in full interlace - * \param numPts - number of points in the mesh - * \param dim - space dimension - */ - //================================================================================ - - DirectedBoundingBox::DirectedBoundingBox(const double* pts, - const unsigned numPts, - const unsigned dim) - : _dim(dim), _axes(dim*dim), _minmax(2*dim) - { - // init box extremities - for ( unsigned i = 0; i < _dim; ++i ) - _minmax[1+i*2] = -numeric_limits::max(), - _minmax[i*2] = numeric_limits::max(); - - if ( numPts < 1 ) return; - - __DMP( "DirectedBoundingBox " << __MYID ); - - const double* coord = pts; - const double* coordEnd = coord + numPts * dim; - - // compute gravity center of points - double gc[3] = {0,0,0}; - if ( dim > 1 ) - { - for ( coord = pts; coord < coordEnd; ) - for ( int i = 0; i < (int)dim; ++i ) - gc[i] += *coord++; - for ( int j = 0; j < (int)dim; ++j ) - gc[j] /= numPts; - - } - - // compute axes and box extremities - vector tensor( dim * dim, 0.); - switch ( dim ) - { - case 3: - for ( coord = pts; coord < coordEnd; coord += dim ) - addPointToInertiaTensor3D( coord, gc, tensor ); - - //computeAxes3D(tensor); - JacobiEigenvectorsSearch(_dim, tensor, _axes); - - for ( coord = pts; coord < coordEnd; coord += dim ) - addPointToBox( coord ); - - break; - - case 2: - for ( coord = pts; coord < coordEnd; coord += dim ) - addPointToInertiaTensor2D( coord, gc, tensor ); - - //computeAxes2D(tensor); - JacobiEigenvectorsSearch(_dim, tensor, _axes); - - for ( coord = pts; coord < coordEnd; coord += dim ) - addPointToBox( coord ); - - break; - - default: - for ( coord = pts; coord < coordEnd; coord += dim ) - { - if ( *coord < _minmax[0] ) _minmax[0] = *coord; - if ( *coord > _minmax[1] ) _minmax[1] = *coord; - } - } - } - - //================================================================================ - /*! - * \brief Creates bounding box of an element - * \param pts - coordinates of points of element - * \param numPts - number of points in the element - * \param dim - space dimension - */ - //================================================================================ - - DirectedBoundingBox::DirectedBoundingBox(const double** pts, - const unsigned numPts, - const unsigned dim) - : _dim(dim), _axes(dim*dim), _minmax(2*dim) - { - // init box extremities - for ( unsigned i = 0; i < _dim; ++i ) - _minmax[1+i*2] = -numeric_limits::max(), - _minmax[i*2] = numeric_limits::max(); - - if ( numPts < 1 ) return; - - __DMP( "DirectedBoundingBox " << __MYID ); - - // compute gravity center of points - double gc[3] = {0,0,0}; - if ( dim > 1 ) - { - for ( unsigned i = 0; i < numPts; ++i ) - for ( int j = 0; j < (int)dim; ++j ) - gc[j] += pts[i][j]; - for ( int j = 0; j < (int)dim; ++j ) - gc[j] /= numPts; - } - - // compute axes and box extremities - vector tensor( dim * dim, 0.); - switch ( dim ) - { - case 3: - for ( unsigned i = 0; i < numPts; ++i ) - addPointToInertiaTensor3D( pts[i], gc, tensor ); - - //computeAxes3D(tensor); - JacobiEigenvectorsSearch(_dim, tensor, _axes); - - for ( unsigned i = 0; i < numPts; ++i ) - addPointToBox( pts[i] ); - - break; - case 2: - for ( unsigned i = 0; i < numPts; ++i ) - addPointToInertiaTensor2D( pts[i], gc, tensor ); - - //computeAxes2D(tensor); - JacobiEigenvectorsSearch(_dim, tensor, _axes); - - for ( unsigned i = 0; i < numPts; ++i ) - addPointToBox( pts[i] ); - - break; - default: - for ( unsigned i = 0; i < numPts; ++i ) - { - if ( pts[i][0] < _minmax[0] ) _minmax[0] = pts[i][0]; - if ( pts[i][0] > _minmax[1] ) _minmax[1] = pts[i][0]; - } - _axes[0] = 1.0; - } - } - - //================================================================================ - /*! - * \brief Compute eigenvectors of inertia tensor - */ - //================================================================================ - - // void DirectedBoundingBox::computeAxes3D(const std::vector& tensor) -// { -// // compute principal moments of inertia which are eigenvalues of the tensor -// double eig[3]; -// { -// // coefficients of polynomial equation det(tensor-eig*I) = 0 -// double a = -1; -// double b = __TENSOR(0,0)+__TENSOR(1,1)+__TENSOR(2,2); -// double c = -// __TENSOR(0,1)*__TENSOR(0,1) + -// __TENSOR(0,2)*__TENSOR(0,2) + -// __TENSOR(1,2)*__TENSOR(1,2) - -// __TENSOR(0,0)*__TENSOR(1,1) - -// __TENSOR(0,0)*__TENSOR(2,2) - -// __TENSOR(1,1)*__TENSOR(2,2); -// double d = -// __TENSOR(0,0)*__TENSOR(1,1)*__TENSOR(2,2) - -// __TENSOR(0,0)*__TENSOR(1,2)*__TENSOR(1,2) - -// __TENSOR(1,1)*__TENSOR(0,2)*__TENSOR(0,2) - -// __TENSOR(2,2)*__TENSOR(0,1)*__TENSOR(0,1) + -// __TENSOR(0,1)*__TENSOR(0,2)*__TENSOR(1,2)*2; - -// // find eigenvalues which are roots of characteristic polynomial -// double x = (3*c/a - b*b/(a*a))/3; -// double y = (2*b*b*b/(a*a*a) - 9*b*c/(a*a) + 27*d/a)/27; -// double z = y*y/4 + x*x*x/27; - -// double i = sqrt(y*y/4 - z) + 1e-300; -// double j = -pow(i,1/3.); -// double y2 = -y/(2*i); -// if ( y2 > 1.0) y2 = 1.; else if ( y2 < -1.0) y2 = -1.; -// double k = acos(y2); -// double m = cos(k/3); -// double n = sqrt(3)*sin(k/3); -// double p = -b/(3*a); - -// eig[0] = -2*j*m + p; -// eig[1] = j *(m + n) + p; -// eig[2] = j *(m - n) + p; -// } -// // compute eigenvector of the tensor at each eigenvalue -// // by solving system [tensor-eig*I]*[axis] = 0 -// bool ok = true; -// __DMP( "Tensor : {" -// << "{ "<<__TENSOR(0,0) << ", "<<__TENSOR(0,1) << ", "<<__TENSOR(0,2) << "} " -// << "{ "<<__TENSOR(1,0) << ", "<<__TENSOR(1,1) << ", "<<__TENSOR(1,2) << "} " -// << "{ "<<__TENSOR(2,0) << ", "<<__TENSOR(2,1) << ", "<<__TENSOR(2,2) << "}} "); -// for ( int i = 0; i < 3 && ok; ++i ) // loop on 3 eigenvalues -// { -// // [tensor-eig*I] -// double T[3][3]= -// {{ __TENSOR(0,0)-eig[i],__TENSOR(0,1), __TENSOR(0,2), }, -// { __TENSOR(0,1), __TENSOR(1,1)-eig[i],__TENSOR(1,2), }, -// { __TENSOR(0,2), __TENSOR(1,2), __TENSOR(2,2)-eig[i]}}; -// // The determinant of T is zero, so that the equations are not linearly independent. -// // Therefore, we assign an arbitrary value (1.) to i-th component of eigenvector -// // and use two of the equations to compute the other two components -// double M[2][3], sol[2]; -// for ( int j = 0, c = 0; j < 3; ++j ) -// if ( i == j ) -// M[0][2] = -T[0][j], M[1][2] = -T[1][j]; -// else -// M[0][c] = T[0][j], M[1][c] = T[1][j], c++; - -// ok = solveSystemOfEquations<2>( M, sol ); - -// double* eigenVec = __AXIS(i); -// for ( int j = 0, c = 0; j < 3; ++j ) -// eigenVec[j] = ( i == j ) ? 1. : sol[c++]; - -// // normilize -// double size = sqrt(eigenVec[0]*eigenVec[0] + -// eigenVec[1]*eigenVec[1] + -// eigenVec[2]*eigenVec[2] ); -// if ((ok = (size > numeric_limits::min() ))) -// { -// eigenVec[0] /= size; -// eigenVec[1] /= size; -// eigenVec[2] /= size; -// } -// } -// if ( !ok ) -// { -// __DMP( " solve3EquationSystem() - KO " ); -// _axes = vector( _dim*_dim, 0); -// __AXIS(0)[0] = __AXIS(1)[1] = __AXIS(2)[2] = 1.; -// } -// __DMP( " Eigen " << eig[0] << ", " << eig[1] << ", " << eig[2] ); -// for ( int i=0; i <3; ++i ) -// __DMP( i << ": " << __AXIS(i)[0] << ", " << __AXIS(i)[1] << ", " << __AXIS(i)[2] ); - -// double* a0 = __AXIS(0), *a1 = __AXIS(1); -// double cross[3] = { a0[1]*a1[2]-a1[1]*a0[2], -// a0[2]*a1[0]-a1[2]*a0[0], -// a0[0]*a1[1]-a1[0]*a0[1] }; -// __DMP( " Cross a1^a2 " << cross[0] << ", " << cross[1] << ", " << cross[2] ); -// } - - //================================================================================ - /*! - * \brief Compute eigenvectors of inertia tensor - */ - //================================================================================ - - // void DirectedBoundingBox::computeAxes2D(const std::vector& tensor) -// { -// // compute principal moments of inertia which are eigenvalues of the tensor -// // by solving square equation det(tensor-eig*I) -// double X = (__TENSOR(0,0)+__TENSOR(1,1))/2; -// double Y = sqrt(4*__TENSOR(0,1)*__TENSOR(0,1) + -// (__TENSOR(0,0)-__TENSOR(1,1)) * (__TENSOR(0,0)-__TENSOR(1,1)))/2; -// double eig[2] = -// { -// X + Y, -// X - Y -// }; -// // compute eigenvector of the tensor at each eigenvalue -// // by solving system [tensor-eig*I]*[axis] = 0 -// bool ok = true; -// for ( int i = 0; i < 2 && ok; ++i ) -// { -// // [tensor-eig*I] -// double T[2][2]= -// {{ __TENSOR(0,0)-eig[i],__TENSOR(0,1) }, -// { __TENSOR(0,1), __TENSOR(1,1)-eig[i] }}; - -// // The determinant of T is zero, so that the equations are not linearly independent. -// // Therefore, we assign an arbitrary value (1.) to i-th component of eigenvector -// // and use one equation to compute the other component -// double* eigenVec = __AXIS(i); -// eigenVec[i] = 1.; -// int j = 1-i; -// if ((ok = ( fabs( T[j][j] ) > numeric_limits::min() ))) -// eigenVec[j] = -T[j][i] / T[j][j]; -// } -// if ( !ok ) -// { -// _axes = vector( _dim*_dim, 0); -// __AXIS(0)[0] = __AXIS(1)[1] = 1.; -// } -// } - - //================================================================================ - /*! - * \brief Convert point coordinates into local coordinate system of the box - */ - //================================================================================ - - void DirectedBoundingBox::toLocalCS(const double* p, double* pLoc) const - { - switch ( _dim ) - { - case 3: - pLoc[0] = dotprod<3>( p, __AXIS(0)); - pLoc[1] = dotprod<3>( p, __AXIS(1)); - pLoc[2] = dotprod<3>( p, __AXIS(2)); - break; - case 2: - pLoc[0] = dotprod<2>( p, __AXIS(0)); - pLoc[1] = dotprod<2>( p, __AXIS(1)); - break; - default: - pLoc[0] = p[0]; - } - } - - //================================================================================ - /*! - * \brief Convert point coordinates from local coordinate system of the box to global CS - */ - //================================================================================ - - void DirectedBoundingBox::fromLocalCS(const double* p, double* pGlob) const - { - switch ( _dim ) - { - case 3: - pGlob[0] = p[0] * __AXIS(0)[0] + p[1] * __AXIS(1)[0] + p[2] * __AXIS(2)[0]; - pGlob[1] = p[0] * __AXIS(0)[1] + p[1] * __AXIS(1)[1] + p[2] * __AXIS(2)[1]; - pGlob[2] = p[0] * __AXIS(0)[2] + p[1] * __AXIS(1)[2] + p[2] * __AXIS(2)[2]; - break; - case 2: - pGlob[0] = p[0] * __AXIS(0)[0] + p[1] * __AXIS(1)[0]; - pGlob[1] = p[0] * __AXIS(0)[1] + p[1] * __AXIS(1)[1]; - break; - default: - pGlob[0] = p[0]; - } - } - - //================================================================================ - /*! - * \brief Enlarge box size by given value - */ - //================================================================================ - - void DirectedBoundingBox::enlarge(const double tol) - { - for ( unsigned i = 0; i < _dim; ++i ) - __MIN(i) -= tol, __MAX(i) += tol; - } - - //================================================================================ - /*! - * \brief Return coordinates of corners of bounding box - */ - //================================================================================ - - void DirectedBoundingBox::getCorners(std::vector& corners, - const double* minmax) const - { - int iC, nbCorners = 1; - for ( int i=0;i<(int)_dim;++i ) nbCorners *= 2; - corners.resize( nbCorners * _dim ); - // each coordinate is filled with either min or max, nbSwap is number of corners - // after which min and max swap - int nbSwap = nbCorners/2; - for ( unsigned i = 0; i < _dim; ++i ) - { - iC = 0; - while ( iC < nbCorners ) - { - for (int j = 0; j < nbSwap; ++j, ++iC ) corners[iC*_dim+i] = minmax[i*2]; - for (int j = 0; j < nbSwap; ++j, ++iC ) corners[iC*_dim+i] = minmax[i*2+1]; - } - nbSwap /= 2; - } - } - - //================================================================================ - /*! - * \brief Test if this box intersects with the other - * \retval bool - true if there is no intersection - */ - //================================================================================ - - bool DirectedBoundingBox::isDisjointWith(const DirectedBoundingBox& box) const - { - if ( _dim < 1 || box._dim < 1 ) return false; // empty box includes all - if ( _dim == 1 ) - return isMinMaxOut( &box._minmax[0], &this->_minmax[0], _dim ); - - // boxes are disjoined if their minmaxes in local CS of either of boxes do not intersect - for ( int isThisCS = 0; isThisCS < 2; ++isThisCS ) - { - const DirectedBoundingBox* axisBox = isThisCS ? this : &box; - const DirectedBoundingBox* cornerBox = isThisCS ? &box : this; - - // find minmax of cornerBox in the CS of axisBox - - DirectedBoundingBox mmBox((double*)0,0,_dim); //!< empty box with CS == axisBox->_axes - mmBox._axes = axisBox->_axes; - - vector corners; - getCorners( corners, &cornerBox->_minmax[0] ); - - double globCorner[3]; - for ( int iC = 0, nC = corners.size()/_dim; iC < nC; ++iC) - { - cornerBox->fromLocalCS( &corners[iC*_dim], globCorner ); - mmBox.addPointToBox( globCorner ); - } - if ( isMinMaxOut( &mmBox._minmax[0], &axisBox->_minmax[0], _dim )) - return true; - } - return false; - } - - //================================================================================ - /*! - * \brief Test if this box intersects with an non-directed box - * \retval bool - true if there is no intersection - */ - //================================================================================ - - bool DirectedBoundingBox::isDisjointWith(const double* box) const - { - if ( _dim < 1 ) return false; // empty box includes all - if ( _dim == 1 ) - return isMinMaxOut( &_minmax[0], box, _dim ); - - // boxes are disjoined if their minmaxes in local CS of either of boxes do not intersect - - // compare minmaxes in locals CS of this directed box - { - vector cornersOther; - getCorners( cornersOther, box ); - DirectedBoundingBox mmBox((double*)0,0,_dim); //!< empty box with CS == this->_axes - mmBox._axes = this->_axes; - for ( int iC = 0, nC = cornersOther.size()/_dim; iC < nC; ++iC) - mmBox.addPointToBox( &cornersOther[iC*_dim] ); - - if ( isMinMaxOut( &mmBox._minmax[0], &this->_minmax[0], _dim )) - return true; - } - - // compare minmaxes in global CS - { - vector cornersThis; - getCorners( cornersThis, &_minmax[0] ); - DirectedBoundingBox mmBox((double*)0,0,_dim); //!< initailized _minmax - double globCorner[3]; - for ( int iC = 0, nC = cornersThis.size()/_dim; iC < nC; ++iC) - { - fromLocalCS( &cornersThis[iC*_dim], globCorner ); - for ( int i = 0; i < (int)_dim; ++i ) - { - if ( globCorner[i] < mmBox._minmax[i*2] ) mmBox._minmax[i*2] = globCorner[i]; - if ( globCorner[i] > mmBox._minmax[i*2+1] ) mmBox._minmax[i*2+1] = globCorner[i]; - } - } - if ( isMinMaxOut( &mmBox._minmax[0], box, _dim )) - return true; - } - return false; - } - - //================================================================================ - /*! - * \brief Return true if given point is out of this box - */ - //================================================================================ - - bool DirectedBoundingBox::isOut(const double* point) const - { - if ( _dim < 1 ) return false; // empty box includes all - - double pLoc[3]; - toLocalCS( point, pLoc ); - bool out = isLocalOut( pLoc ); -#ifdef _DEBUG_ - switch (_dim) - { - case 3: - __DMP(__MYID<<": "< DirectedBoundingBox::getData() const - { - vector data(1, _dim); - if ( _dim > 0 ) - { - data.insert( data.end(), &_axes[0], &_axes[0] + _axes.size()); - data.insert( data.end(), &_minmax[0], &_minmax[0] + _minmax.size()); - } - if ( data.size() < (unsigned)dataSize( _dim )) - data.resize( dataSize( _dim ), 0 ); - return data; - } - - //================================================================================ - /*! - * \brief Initializes self with data retrieved via getData() - */ - //================================================================================ - - void DirectedBoundingBox::setData(const double* data) - { - _dim = unsigned( *data++ ); - if ( _dim > 0 ) - { - _axes.assign( data, data+_dim*_dim ); data += _dim*_dim; - _minmax.assign( data, data+2*_dim ); - } - else - { - _axes.clear(); - _minmax.clear(); - } - } - - //================================================================================ - /*! - * \brief Return size of internal data returned by getData() depending on space dim - */ - //================================================================================ - - int DirectedBoundingBox::dataSize(int dim) - { - return 1 + dim*dim + 2*dim; // : _dim + _axes + _minmax - } -} diff --git a/src/INTERP_KERNEL/DirectedBoundingBox.hxx b/src/INTERP_KERNEL/DirectedBoundingBox.hxx deleted file mode 100644 index 50501cd17..000000000 --- a/src/INTERP_KERNEL/DirectedBoundingBox.hxx +++ /dev/null @@ -1,119 +0,0 @@ -// Copyright (C) 2009-2015 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, 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 -// 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 __DIRECTEDBOUNDINGBOX_HXX__ -#define __DIRECTEDBOUNDINGBOX_HXX__ - -#include "INTERPKERNELDefines.hxx" - -#include - -namespace INTERP_KERNEL -{ - - /** - * \brief Class representing the bounding box of a number of points - * with box axes parallel to principal axes of inertia of points - */ - class DirectedBoundingBox - { - public: - - INTERPKERNEL_EXPORT DirectedBoundingBox(); - - INTERPKERNEL_EXPORT DirectedBoundingBox(const double* pts, const unsigned numPts, const unsigned dim); - - INTERPKERNEL_EXPORT DirectedBoundingBox(const double** pts, const unsigned numPts, const unsigned dim); - - //~DirectedBoundingBox(); - - INTERPKERNEL_EXPORT void enlarge(const double tol); - - INTERPKERNEL_EXPORT bool isDisjointWith(const DirectedBoundingBox& box) const; - - INTERPKERNEL_EXPORT bool isDisjointWith(const double* box) const; - - INTERPKERNEL_EXPORT bool isOut(const double* point) const; - - - // return internal data - INTERPKERNEL_EXPORT std::vector getData() const; - - // initialize with data returned by getData() - INTERPKERNEL_EXPORT void setData(const double* data); - - // return size of internal data - INTERPKERNEL_EXPORT static int dataSize(int dim); - - private: - - //void computeAxes3D(const std::vector& tensor); - - //void computeAxes2D(const std::vector& tensor); - - inline void addPointToBox(const double* coord); - - void toLocalCS(const double* p, double* pLoc) const; - - void fromLocalCS(const double* p, double* pGlob) const; - - inline bool isLocalOut(const double* pLoc) const; - - void getCorners(std::vector& corners, const double* minmax) const; - - unsigned _dim; - - std::vector _axes; //!< principal axes of inertia in full interlace - std::vector _minmax; //!< pairs of min an max coordinates along the axes - - }; - - //================================================================================ - /*! - * \brief Test point in local CS against box extremities - * - */ - //================================================================================ - - inline bool DirectedBoundingBox::isLocalOut(const double* pLoc) const - { - for ( int i = 0; i < (int)_dim; ++i ) - if ( pLoc[i] < _minmax[i*2] || pLoc[i] > _minmax[i*2+1] ) - return true; - return false; - } - - //================================================================================ - /*! - * \brief Update box extremities - */ - //================================================================================ - - inline void DirectedBoundingBox::addPointToBox(const double* coord) - { - for ( int i = 0; i < (int)_dim; ++i ) - { - double c = 0; - for ( int j = 0; j < (int)_dim; ++j ) c += coord[j]*_axes[i*_dim+j]; - if ( c < _minmax[i*2] ) _minmax[i*2] = c; - if ( c > _minmax[i*2+1] ) _minmax[i*2+1] = c; - } - } -} -#endif diff --git a/src/INTERP_KERNEL/ExprEval/InterpKernelAsmX86.cxx b/src/INTERP_KERNEL/ExprEval/InterpKernelAsmX86.cxx deleted file mode 100644 index aaeeabf14..000000000 --- a/src/INTERP_KERNEL/ExprEval/InterpKernelAsmX86.cxx +++ /dev/null @@ -1,495 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 -// 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 "InterpKernelAsmX86.hxx" - -#include -#include -#include - -#ifdef _POSIX_MAPPED_FILES -#include -#else -#ifdef WIN32 -#include -#endif -#endif - -const char *INTERP_KERNEL::AsmX86::OPS[NB_OF_OPS]={"mov","push","pop","fld","faddp","fsubp","fmulp","fdivp","fcos","fsin","fabs","fchs","fsqrt","sub","add","ret","leave","movsd","fst"}; - -std::vector INTERP_KERNEL::AsmX86::convertIntoMachineLangage(const std::vector& asmb) const -{ - std::vector ret; - for(std::vector::const_iterator iter=asmb.begin();iter!=asmb.end();iter++) - convertOneInstructionInML(*iter,ret); - return ret; -} - -char *INTERP_KERNEL::AsmX86::copyToExecMemZone(const std::vector& ml, unsigned& offset) const -{ - char *ret=0; - int lgth=ml.size(); -#ifdef _POSIX_MAPPED_FILES - ret=(char *)mmap(0,lgth,PROT_EXEC | PROT_WRITE,MAP_ANONYMOUS | MAP_PRIVATE,-1,0); -#else -#ifdef WIN32 - HANDLE h=CreateFileMapping(INVALID_HANDLE_VALUE,NULL,PAGE_EXECUTE_READWRITE,0,lgth,NULL); - ret=(char *)MapViewOfFile(h,FILE_MAP_EXECUTE | FILE_MAP_READ | FILE_MAP_WRITE,0,0,lgth); -#endif -#endif - if(ret) - std::copy(ml.begin(),ml.end(),ret); - return ret; -} - -void INTERP_KERNEL::AsmX86::convertOneInstructionInML(const std::string& inst, std::vector& ml) const -{ - std::string::size_type pos=inst.find_first_of(' '); - std::string op; - std::string param; - if(pos!=std::string::npos) - { - op=inst.substr(0,pos); - param=inst.substr(pos+1); - } - else - op=inst; - int id=0; - for(const char **it=OPS;it!=OPS+NB_OF_OPS;it++,id++) - { - std::string tmp(*it); - if(op==tmp) - break; - } - switch(id) - { - case 0: - convertMov(param,ml); - break; - case 1: - convertPush(param,ml); - break; - case 2: - convertPop(param,ml); - break; - case 3: - convertFld(param,ml); - break; - case 4: - convertFaddp(param,ml); - break; - case 5: - convertFsubp(param,ml); - break; - case 6: - convertFmulp(param,ml); - break; - case 7: - convertFdivp(param,ml); - break; - case 8: - convertFcos(param,ml); - break; - case 9: - convertFsin(param,ml); - break; - case 10: - convertFabs(param,ml); - break; - case 11: - convertFchs(param,ml); - break; - case 12: - convertFsqrt(param,ml); - break; - case 13: - convertSub(param,ml); - break; - case 14: - convertAdd(param,ml); - break; - case 15: - convertRet(param,ml); - break; - case 16: - convertLeave(param,ml); - break; - case 17: - convertMovsd(param,ml); - break; - case 18: - convertFst(param,ml); - break; - default: - { - std::ostringstream oss; oss << "Unrecognized op : " << op << " in assembly line : " << inst; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - } -} - -#include - -void INTERP_KERNEL::AsmX86::convertMov(const std::string& inst, std::vector& ml) -{ - const char ASM1[]="ebp,esp"; - const unsigned char ML1[2]={0x89,0xe5}; - if(inst==ASM1) - { - ml.insert(ml.end(),ML1,ML1+sizeof(ML1)); - return ; - } - const char ASM2[]="rbp,rsp"; - const unsigned char ML2[3]={0x48,0x89,0xe5}; - if(inst==ASM2) - { - ml.insert(ml.end(),ML2,ML2+sizeof(ML2)); - return ; - } - std::string::size_type pos=inst.find_first_of(' '); - if(pos==std::string::npos) - { - std::ostringstream oss; oss << "not recognized instruction mov : " << inst; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - std::string inst2=inst.substr(pos+1); - pos=inst2.find_first_of(','); - if(pos==std::string::npos) - { - std::ostringstream oss; oss << "not recognized instruction mov : " << inst; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - std::string inst3=inst2.substr(0,pos); - std::string inst4=inst2.substr(pos+1); - convertMovToEsp(inst3,inst4,ml); -} - -void INTERP_KERNEL::AsmX86::convertMovToEsp(const std::string& inst1, const std::string& inst2, std::vector& ml) -{ - if(inst1[0]!='[' || inst1[inst1.length()-1]!=']') - throw INTERP_KERNEL::Exception("not recognized convertMovToEsp exp !"); - std::string inst1bis=inst1.substr(1,inst1.length()-2); - const char ASM1[]="esp"; - const unsigned char ML1[3]={0xc7,0x04,0x24}; - if(inst1bis==ASM1) - {//mov dword [esp],0x3ff3c0ca - ml.insert(ml.end(),ML1,ML1+sizeof(ML1)); - appendAddress(inst2,4,ml); - return ; - } - if(inst1bis.substr(0,3)==ASM1) - { - if(inst1bis[3]=='+') - {//mov dword [esp+4],0x3ff3c0ca - const unsigned char ML2[3]={0xc7,0x44,0x24}; - ml.insert(ml.end(),ML2,ML2+sizeof(ML2)); - std::string::size_type pos=inst1bis.find_first_of(']'); - std::string inst1_1=inst1bis.substr(4,pos-4-1); - appendAddress(inst1_1,1,ml); - appendAddress(inst2,4,ml); - return; - } - else - throw INTERP_KERNEL::Exception("Not recognized exp : mov [esp@..],..."); - } - const char ASM3[]="rsp"; - const unsigned char ML3[3]={0xc7,0x04,0x24}; - if(inst1bis==ASM3) - {//mov dword [rsp],0x3ff3c0ca - ml.insert(ml.end(),ML3,ML3+sizeof(ML3)); - appendAddress(inst2,4,ml); - return ; - } - if(inst1bis.substr(0,3)==ASM3) - { - if(inst1bis[3]=='+') - {//mov dword [rsp+4],0x3ff3c0ca - const unsigned char ML2[3]={0xc7,0x44,0x24}; - ml.insert(ml.end(),ML2,ML2+sizeof(ML2)); - std::string::size_type pos=inst1bis.find_first_of(']'); - std::string inst1_1=inst1bis.substr(4,pos-4-1); - appendAddress(inst1_1,1,ml); - appendAddress(inst2,4,ml); - return; - } - else - throw INTERP_KERNEL::Exception("Not recognized exp : mov [esp@..],..."); - } - throw INTERP_KERNEL::Exception("Not recognized exp : mov"); -} - -void INTERP_KERNEL::AsmX86::convertPush(const std::string& inst, std::vector& ml) -{ - std::string::size_type pos=inst.find_first_of(' '); - std::string inst2=inst.substr(pos+1); - const char ASM1[]="ebp"; - const unsigned char ML1[1]={0x55}; - if(inst2==ASM1) - {//push ebp - ml.insert(ml.end(),ML1,ML1+sizeof(ML1)); - return ; - } - const char ASM2[]="ebx"; - const unsigned char ML2[1]={0x53}; - if(inst2==ASM2) - {//push ebx - ml.insert(ml.end(),ML2,ML2+sizeof(ML2)); - return ; - } - const char ASM3[]="rbp"; - const unsigned char ML3[1]={0x55}; - if(inst2==ASM3) - {//push rbp - ml.insert(ml.end(),ML3,ML3+sizeof(ML3)); - return ; - } - throw INTERP_KERNEL::Exception("Unrecognized push instruction"); -} - -void INTERP_KERNEL::AsmX86::convertPop(const std::string& inst, std::vector& ml) -{ - std::string::size_type pos=inst.find_first_of(' '); - std::string inst2=inst.substr(pos+1); - const char ASM1[]="ebp"; - const unsigned char ML1[1]={0x5d}; - if(inst2==ASM1) - {//push ebp - ml.insert(ml.end(),ML1,ML1+sizeof(ML1)); - return ; - } - const char ASM2[]="ebx"; - const unsigned char ML2[1]={0x5b}; - if(inst2==ASM2) - {//push ebx - ml.insert(ml.end(),ML2,ML2+sizeof(ML2)); - return ; - } - throw INTERP_KERNEL::Exception("Unrecognized pop instruction"); -} - -void INTERP_KERNEL::AsmX86::convertFld(const std::string& inst, std::vector& ml) -{ - std::string::size_type pos=inst.find_first_of(' '); - std::string params=inst.substr(pos+1); - std::string params2=params.substr(1,params.length()-2); - if(params2.substr(0,3)=="esp") - { - const unsigned char ML1[3]={0xdd,0x04,0x24}; - if(params2.length()==3) - {//fld qword [esp] - ml.insert(ml.end(),ML1,ML1+sizeof(ML1)); - return ; - } - pos=params2.find_first_of('+'); - if(pos!=std::string::npos) - {//fld qword [esp+@] - ml.insert(ml.end(),ML1,ML1+sizeof(ML1)); - std::string params3=params2.substr(pos+1); - appendAddress(params3,1,ml); - return ; - } - throw INTERP_KERNEL::Exception("Unrecognized fld esp..."); - } - if(params2.substr(0,3)=="ebp") - { - const unsigned char ML2[2]={0xdd,0x45}; - if(params2.length()==3) - {//fld qword [ebp] - ml.insert(ml.end(),ML2,ML2+sizeof(ML2)); - ml.push_back(0); - return ; - } - pos=params2.find_first_of('+'); - if(pos!=std::string::npos) - {//fld qword [esp+@] - ml.insert(ml.end(),ML2,ML2+sizeof(ML2)); - std::string params3=params2.substr(pos+1); - appendAddress(params3,1,ml); - return ; - } - throw INTERP_KERNEL::Exception("Unrecognized fld ebp..."); - } - if(params2.substr(0,3)=="rsp") - { - const unsigned char ML2[3]={0xdd,0x04,0x24}; - ml.insert(ml.end(),ML2,ML2+sizeof(ML2));// to improve ! no fully managed ! - return ; - } - throw INTERP_KERNEL::Exception("Unrecognized fld instruction"); -} - -void INTERP_KERNEL::AsmX86::convertFaddp(const std::string& inst, std::vector& ml) -{ - const unsigned char ML1[2]={0xde,0xc1}; - ml.insert(ml.end(),ML1,ML1+sizeof(ML1)); -} - -void INTERP_KERNEL::AsmX86::convertFsubp(const std::string& inst, std::vector& ml) -{ - const unsigned char ML1[2]={0xde,0xe9}; - ml.insert(ml.end(),ML1,ML1+sizeof(ML1)); -} - -void INTERP_KERNEL::AsmX86::convertFmulp(const std::string& inst, std::vector& ml) -{ - const unsigned char ML1[2]={0xde,0xc9}; - ml.insert(ml.end(),ML1,ML1+sizeof(ML1)); -} - -void INTERP_KERNEL::AsmX86::convertFdivp(const std::string& inst, std::vector& ml) -{ - const unsigned char ML1[2]={0xde,0xf9}; - ml.insert(ml.end(),ML1,ML1+sizeof(ML1)); -} - -void INTERP_KERNEL::AsmX86::convertFcos(const std::string& inst, std::vector& ml) -{ - const unsigned char ML[2]={0xd9,0xff}; - ml.insert(ml.end(),ML,ML+sizeof(ML)); -} - -void INTERP_KERNEL::AsmX86::convertFsin(const std::string& inst, std::vector& ml) -{ - const unsigned char ML[2]={0xd9,0xfe}; - ml.insert(ml.end(),ML,ML+sizeof(ML)); -} - -void INTERP_KERNEL::AsmX86::convertFabs(const std::string& inst, std::vector& ml) -{ - const unsigned char ML[2]={0xd9,0xe1}; - ml.insert(ml.end(),ML,ML+sizeof(ML)); -} - -void INTERP_KERNEL::AsmX86::convertFchs(const std::string& inst, std::vector& ml) -{ - const unsigned char ML[2]={0xd9,0xe0}; - ml.insert(ml.end(),ML,ML+sizeof(ML)); -} - -void INTERP_KERNEL::AsmX86::convertFsqrt(const std::string& inst, std::vector& ml) -{ - const unsigned char ML[2]={0xd9,0xfa}; - ml.insert(ml.end(),ML,ML+sizeof(ML)); -} - -void INTERP_KERNEL::AsmX86::convertSub(const std::string& inst, std::vector& ml) -{ - if(inst.substr(0,4)=="esp,") - { - const unsigned char ML[2]={0x81,0xec}; - ml.insert(ml.end(),ML,ML+sizeof(ML)); - std::string inst2=inst.substr(4); - appendAddress(inst2,4,ml); - return; - } - if(inst.substr(0,4)=="rsp,") - { - const unsigned char ML[4]={0x48,0x83,0xec,0x08}; - ml.insert(ml.end(),ML,ML+sizeof(ML)); // to improve 8 statically put (last of element of ML) !!!! - return; - } - throw INTERP_KERNEL::Exception("Not recognized sub instruction."); -} - -void INTERP_KERNEL::AsmX86::convertAdd(const std::string& inst, std::vector& ml) -{ - if(inst.substr(0,4)=="esp,") - { - const unsigned char ML[2]={0x81,0xc4}; - ml.insert(ml.end(),ML,ML+sizeof(ML)); - std::string inst2=inst.substr(4); - appendAddress(inst2,4,ml); - return; - } - if(inst.substr(0,4)=="rsp,") - { - const unsigned char ML[4]={0x48,0x83,0xc4,0x08}; - ml.insert(ml.end(),ML,ML+sizeof(ML)); // to improve 8 statically put (last of element of ML) !!!! - return; - } - throw INTERP_KERNEL::Exception("Not recognized add instruction."); -} - -void INTERP_KERNEL::AsmX86::convertRet(const std::string& inst, std::vector& ml) -{ - const unsigned char ML[1]={0xc3}; - ml.insert(ml.end(),ML,ML+sizeof(ML)); -} - -void INTERP_KERNEL::AsmX86::convertLeave(const std::string& inst, std::vector& ml) -{ - const unsigned char ML[1]={0xc9}; - ml.insert(ml.end(),ML,ML+sizeof(ML)); -} - -void INTERP_KERNEL::AsmX86::convertMovsd(const std::string& inst, std::vector& ml) -{ - const char ASM1[]="[rsp],xmm0"; - const unsigned char ML1[5]={0xf2,0x0f,0x11,0x04,0x24}; - if(inst==ASM1) - { - ml.insert(ml.end(),ML1,ML1+sizeof(ML1)); - return ; - } - const char ASM2[]="xmm0,[rsp]"; - const unsigned char ML2[5]={0xf2,0x0f,0x10,0x04,0x24}; - if(inst==ASM2) - { - ml.insert(ml.end(),ML2,ML2+sizeof(ML2)); - return ; - } - std::ostringstream oss; oss << "not recognized instruction movsd : " << inst; - throw INTERP_KERNEL::Exception(oss.str().c_str()); -} - -void INTERP_KERNEL::AsmX86::convertFst(const std::string& inst, std::vector& ml) -{ - const char ASM1[]="qword [rsp]"; - const unsigned char ML1[3]={0xdd,0x14,0x24}; - if(inst==ASM1) - { - ml.insert(ml.end(),ML1,ML1+sizeof(ML1)); - return ; - } - std::ostringstream oss; oss << "not recognized instruction fst : " << inst; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - //tony -} - - -void INTERP_KERNEL::AsmX86::appendAddress(const std::string& addr, int nbOfByte, std::vector& ml) -{ - int i,j; - char v; - std::istringstream iss(addr); - if(addr.length()>2) - { - if(addr[0]=='0' && addr[1]=='x') - iss >> std::hex; - } - iss >> i; - for(int k=0;k>=8; - } -} diff --git a/src/INTERP_KERNEL/ExprEval/InterpKernelAsmX86.hxx b/src/INTERP_KERNEL/ExprEval/InterpKernelAsmX86.hxx deleted file mode 100644 index 7620686a2..000000000 --- a/src/INTERP_KERNEL/ExprEval/InterpKernelAsmX86.hxx +++ /dev/null @@ -1,68 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 -// 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 __INTERPKERNELASMX86_HXX__ -#define __INTERPKERNELASMX86_HXX__ - -#include "INTERPKERNELDefines.hxx" -#include "InterpKernelException.hxx" - -#include -#include - -namespace INTERP_KERNEL -{ - class AsmX86 - { - public: - std::vector convertIntoMachineLangage(const std::vector& asmb) const; - char *copyToExecMemZone(const std::vector& ml, unsigned& offset) const; - private: - void convertOneInstructionInML(const std::string& inst, std::vector& ml) const; - private: - static void convertMov(const std::string& inst, std::vector& ml); - static void convertPush(const std::string& inst, std::vector& ml); - static void convertPop(const std::string& inst, std::vector& ml); - static void convertFld(const std::string& inst, std::vector& ml); - static void convertFaddp(const std::string& inst, std::vector& ml); - static void convertFsubp(const std::string& inst, std::vector& ml); - static void convertFmulp(const std::string& inst, std::vector& ml); - static void convertFdivp(const std::string& inst, std::vector& ml); - static void convertFcos(const std::string& inst, std::vector& ml); - static void convertFsin(const std::string& inst, std::vector& ml); - static void convertFabs(const std::string& inst, std::vector& ml); - static void convertFchs(const std::string& inst, std::vector& ml); - static void convertFsqrt(const std::string& inst, std::vector& ml); - static void convertSub(const std::string& inst, std::vector& ml); - static void convertAdd(const std::string& inst, std::vector& ml); - static void convertRet(const std::string& inst, std::vector& ml); - static void convertLeave(const std::string& inst, std::vector& ml); - static void convertMovsd(const std::string& inst, std::vector& ml); - static void convertFst(const std::string& inst, std::vector& ml); - // - static void convertMovToEsp(const std::string& inst1, const std::string& inst2, std::vector& ml); - static void appendAddress(const std::string& addr, int nbOfByte, std::vector& ml); - private: - static const int NB_OF_OPS=19; - static const char *OPS[NB_OF_OPS]; - }; -} - -#endif diff --git a/src/INTERP_KERNEL/ExprEval/InterpKernelExprParser.cxx b/src/INTERP_KERNEL/ExprEval/InterpKernelExprParser.cxx deleted file mode 100644 index e1cce1a91..000000000 --- a/src/INTERP_KERNEL/ExprEval/InterpKernelExprParser.cxx +++ /dev/null @@ -1,1201 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 -// 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 "InterpKernelExprParser.hxx" -#include "InterpKernelValue.hxx" -#include "InterpKernelAsmX86.hxx" -#include "InterpKernelAutoPtr.hxx" - -#include -#include -#include -#include -#include -#include -#include - -using namespace INTERP_KERNEL; - -const char LeafExprVar::END_OF_RECOGNIZED_VAR[]="Vec"; - -const char ExprParser::WHITE_SPACES[]=" \n"; - -const char ExprParser::EXPR_PARSE_ERR_MSG[]="Invalid expression detected : "; - -LeafExpr *LeafExpr::buildInstanceFrom(const std::string& expr) -{ - std::istringstream stream; - stream.str(expr); - double val; - stream >> val; - if(!stream.fail()) - if(stream.eof()) - return new LeafExprVal(val); - else - { - std::ostringstream errMsg; - char MSGTYP6[]="Error following expression is not consedered as a double value : "; - errMsg << MSGTYP6 << expr; - throw INTERP_KERNEL::Exception(errMsg.str().c_str()); - } - else - return new LeafExprVar(expr); -} - -LeafExpr::~LeafExpr() -{ -} - -LeafExprVal::LeafExprVal(double value):_value(value) -{ -} - -LeafExprVal::~LeafExprVal() -{ -} - -void LeafExprVal::fillValue(Value *val) const -{ - val->setDouble(_value); -} - -void LeafExprVal::replaceValues(const std::vector& valuesInExpr) -{ - int pos=(int)_value; - int lgth=(int)valuesInExpr.size(); - if(pos>=lgth || pos<0) - throw INTERP_KERNEL::Exception("LeafExprVal::replaceValues : Big Problem detected ! Send expression to Salome support with expression !"); - _value=valuesInExpr[pos]; -} - -LeafExprVal *LeafExprVal::deepCpy() const -{ - return new LeafExprVal(*this); -} - -LeafExprVar::LeafExprVar(const std::string& var):_fast_pos(-1),_var_name(var),_val(0) -{ -} - -void LeafExprVar::fillValue(Value *val) const -{ - if(_val) - val->setDouble(_val[_fast_pos]); - else - val->setVarname(_fast_pos,_var_name); - -} - -void LeafExprVar::prepareExprEvaluation(const std::vector& vars, int nbOfCompo, int targetNbOfCompo) const -{ - std::vector::const_iterator iter=std::find(vars.begin(),vars.end(),_var_name); - if(iter==vars.end()) - { - if(!isRecognizedKeyVar(_var_name,_fast_pos)) - { - std::ostringstream oss; oss << "Var : " << _var_name << " not in : "; - std::copy(vars.begin(),vars.end(),std::ostream_iterator(oss,", ")); - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - else - { - int relPos=-7-_fast_pos; - if(relPos>=targetNbOfCompo) - { - std::ostringstream oss; oss << "LeafExprVar::prepareExprEvaluation : Found recognized unitary vector \"" << _var_name << "\" which implies that component #" << relPos; - oss << " exists, but it is not the case component id should be in [0," << targetNbOfCompo << ") !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - else - return; - } - } - _fast_pos=(int)std::distance(vars.begin(),iter); - if(_fast_pos>=nbOfCompo) - { - std::ostringstream oss; oss << "LeafExprVar::prepareExprEvaluation : Found var \"" << _var_name << "\" on place " << _fast_pos << " whereas only must be in [0," << nbOfCompo << ") !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } -} - -/*! - * \param [in] vars - the sorted list of vars - * \param [in] nbOfCompo - the size of the input tuples (it is used to scan if no problem occurs) - * \param [in] targetNbOfCompo - the size of the output tuple (it is used to check that no problem occurs) - * \param [in] refPos - is an integer in [0,targetNbOfCompo), that tell the id of \a this. It is for multi interpreters. - * \sa evaluateDouble - */ -void LeafExprVar::prepareExprEvaluationDouble(const std::vector& vars, int nbOfCompo, int targetNbOfCompo, int refPos, const double *ptOfInputStart, const double *ptOfInputEnd) const -{ - if((int)vars.size()!=std::distance(ptOfInputStart,ptOfInputEnd)) - throw INTERP_KERNEL::Exception("LeafExprVar::prepareExprEvaluationDouble : size of input vector must be equal to the input vector !"); - prepareExprEvaluation(vars,nbOfCompo,targetNbOfCompo); - _ref_pos=refPos; - _val=ptOfInputStart; -} - -void LeafExprVar::prepareExprEvaluationVec() const -{ - if(!isRecognizedKeyVar(_var_name,_fast_pos)) - _fast_pos=-2; -} - -bool LeafExprVar::isRecognizedKeyVar(const std::string& var, int& pos) -{ - if(var.length()!=sizeof(END_OF_RECOGNIZED_VAR)) - return false; - std::string end=var.substr(1); - if(end!=END_OF_RECOGNIZED_VAR) - return false; - char first=var[0]; - if(first<'I' || first>'Z') - return false; - pos=-7-(first-'I'); - return true; -} - -LeafExprVar *LeafExprVar::deepCpy() const -{ - return new LeafExprVar(*this); -} - -/*! - * Nothing to do it is not a bug. - */ -void LeafExprVar::replaceValues(const std::vector& valuesInExpr) -{ -} - -LeafExprVar::~LeafExprVar() -{ -} - -void ExprParserOfEval::clearSortedMemory() -{ - delete _leaf; - for(std::vector::iterator it=_sub_parts.begin();it!=_sub_parts.end();it++) - (*it).clearSortedMemory(); - for(std::vector::iterator it=_funcs.begin();it!=_funcs.end();it++) - delete *it; -} - -void ExprParserOfEval::sortMemory() -{ - for(std::vector::iterator it=_sub_parts.begin();it!=_sub_parts.end();it++) - (*it).sortMemory(); - if(_leaf) - _leaf=_leaf->deepCpy(); - for(std::vector::iterator it=_funcs.begin();it!=_funcs.end();it++) - if(*it) - *it=(*it)->deepCpy(); -} - -ExprParser::ExprParser(const std::string& expr, ExprParser *father):_father(father),_is_parsed(false),_leaf(0),_is_parsing_ok(false),_expr(expr) -{ - _expr=deleteWhiteSpaces(_expr); -} - -//! For \b NOT null terminated strings coming from FORTRAN. -ExprParser::ExprParser(const char *expr, int lgth, ExprParser *father):_father(father),_is_parsed(false),_leaf(0),_is_parsing_ok(false) -{ - _expr=buildStringFromFortran(expr,lgth); - _expr=deleteWhiteSpaces(_expr); -} - -ExprParser::~ExprParser() -{ - delete _leaf; - _for_eval.clearSortedMemory(); - releaseFunctions(); -} - -std::size_t ExprParser::FindCorrespondingOpenBracket(const std::string& expr, std::size_t posOfCloseBracket) -{ - int level=0; - for(std::size_t iter=0;iter valuesInExpr; - fillValuesInExpr(valuesInExpr); - checkBracketsParity(); - if(!simplify()) - parseDeeper(); - replaceValues(valuesInExpr); - _expr=tmp; - } - reverseThis(); - _is_parsing_ok=true; -} - -double ExprParser::evaluate() const -{ - AutoCppPtr gen(new ValueDouble); - AutoCppPtr res(static_cast(evaluateLowLev(gen))); - return res->getData(); -} - -DecompositionInUnitBase ExprParser::evaluateUnit() const -{ - Value *gen=new ValueUnit; - ValueUnit *res=0; - try - { - res=(ValueUnit *)evaluateLowLev(gen); - } - catch(INTERP_KERNEL::Exception& e) - { - delete gen; - throw e; - } - delete gen; - DecompositionInUnitBase ret=res->getData(); - delete res; - return ret; -} - -void ExprParser::evaluateExpr(int szOfOutParam, const double *inParam, double *outParam) const -{ - AutoCppPtr gen(new ValueDoubleExpr(szOfOutParam,inParam)); - AutoCppPtr res(static_cast(evaluateLowLev(gen))); - std::copy(res->getData(),res->getData()+szOfOutParam,outParam); -} - -void ExprParser::prepareExprEvaluation(const std::vector& vars, int nbOfCompo, int targetNbOfCompo) const -{ - if(_leaf) - { - LeafExprVar *leafC=dynamic_cast(_leaf); - if(leafC) - leafC->prepareExprEvaluation(vars,nbOfCompo,targetNbOfCompo); - } - else - for(std::vector::const_iterator iter=_sub_expr.begin();iter!=_sub_expr.end();iter++) - (*iter).prepareExprEvaluation(vars,nbOfCompo,targetNbOfCompo); -} - -/*! - * \param [in] vars - the sorted list of vars - * \param [in] nbOfCompo - the size of the input tuples (it is used to scan if no problem occurs) - * \param [in] targetNbOfCompo - the size of the output tuple (it is used to check that no problem occurs) - * \param [in] refPos - is an integer in [0,targetNbOfCompo), that tell the id of \a this. It is for multi interpreters. - * \sa evaluateDouble - */ -void ExprParser::prepareExprEvaluationDouble(const std::vector& vars, int nbOfCompo, int targetNbOfCompo, int refPos, const double *ptOfInputStart, const double *ptOfInputEnd) const -{ - if((int)vars.size()!=std::distance(ptOfInputStart,ptOfInputEnd)) - throw INTERP_KERNEL::Exception("ExprParser::prepareExprEvaluationDouble : size of input vector must be equal to the input vector !"); - if(_leaf) - { - LeafExprVar *leafC=dynamic_cast(_leaf); - if(leafC) - leafC->prepareExprEvaluationDouble(vars,nbOfCompo,targetNbOfCompo,refPos,ptOfInputStart,ptOfInputEnd); - } - else - for(std::vector::const_iterator iter=_sub_expr.begin();iter!=_sub_expr.end();iter++) - (*iter).prepareExprEvaluationDouble(vars,nbOfCompo,targetNbOfCompo,refPos,ptOfInputStart,ptOfInputEnd); -} - -void ExprParser::prepareFastEvaluator() const -{ - _for_eval.clearSortedMemory(); - _for_eval=convertMeTo(); - _for_eval.sortMemory(); -} - -/*! - * \sa prepareExprEvaluationDouble - */ -double ExprParser::evaluateDouble() const -{ - checkForEvaluation(); - std::vector stackOfVal; - evaluateDoubleInternal(stackOfVal); - return stackOfVal.back(); -} - -void ExprParser::checkForEvaluation() const -{ - if(!_is_parsing_ok) - throw INTERP_KERNEL::Exception("checkForEvaluation : Parsing fails ! Invalid expression !"); - if(_sub_expr.empty() && !_leaf) - throw INTERP_KERNEL::Exception("checkForEvaluation : Empty expression !"); -} - -void ExprParser::prepareExprEvaluationVec() const -{ - std::set trueVars; - getTrueSetOfVars(trueVars); - if(trueVars.size()>1) - { - std::ostringstream oss; oss << "For this type of evaluation only one not keyword variable authorized : "; - oss << "having " << trueVars.size() << " : "; - std::copy(trueVars.begin(),trueVars.end(),std::ostream_iterator(oss," ")); oss << " !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - prepareExprEvaluationVecLowLev(); -} - -void ExprParser::prepareExprEvaluationVecLowLev() const -{ - if(_leaf) - { - LeafExprVar *leafC=dynamic_cast(_leaf); - if(leafC) - leafC->prepareExprEvaluationVec(); - } - else - for(std::vector::const_iterator iter=_sub_expr.begin();iter!=_sub_expr.end();iter++) - (*iter).prepareExprEvaluationVecLowLev(); -} - -Value *ExprParser::evaluateLowLev(Value *valGen) const -{ - checkForEvaluation(); - std::vector stackOfVal; - try - { - if(_leaf) - { - Value *ret=valGen->newInstance(); - try - { - _leaf->fillValue(ret); - } - catch(INTERP_KERNEL::Exception& e) - { - delete ret; - throw e; - } - stackOfVal.resize(1); - stackOfVal[0]=ret; - } - else - { - stackOfVal.resize(_sub_expr.size()); - std::vector::iterator iter2=stackOfVal.begin(); - for(std::vector::const_iterator iter=_sub_expr.begin();iter!=_sub_expr.end();iter++,iter2++) - *iter2=(*iter).evaluateLowLev(valGen); - } - for(std::vector::const_iterator iter3=_func_btw_sub_expr.begin();iter3!=_func_btw_sub_expr.end();iter3++) - (*iter3)->operate(stackOfVal); - } - catch(INTERP_KERNEL::Exception& e) - { - for(std::vector::iterator iter4=stackOfVal.begin();iter4!=stackOfVal.end();iter4++) - delete *iter4; - throw e; - } - return stackOfVal.back(); -} - -void ExprParser::reverseThis() -{ - if(_leaf) - return ; - for(std::vector::iterator iter=_sub_expr.begin();iter!=_sub_expr.end();iter++) - (*iter).reverseThis(); - AutoPtr buf(new char[sizeof(ExprParser)]); - char *loc(reinterpret_cast(&_sub_expr[0])),*bufPtr(buf); - std::size_t sz(_sub_expr.size()); - std::size_t nbOfTurn(sz/2); - for(std::size_t i=0;i subExpr(sz); - for(std::size_t i=0;i& vars) const -{ - if(_leaf) - { - LeafExprVar *leafC=dynamic_cast(_leaf); - if(leafC) - vars.insert(leafC->getVar()); - } - else - for(std::vector::const_iterator iter=_sub_expr.begin();iter!=_sub_expr.end();iter++) - (*iter).getSetOfVars(vars); -} - -void ExprParser::getTrueSetOfVars(std::set& trueVars) const -{ - std::set vars; - getSetOfVars(vars); - trueVars.clear(); - for(std::set::const_iterator iter=vars.begin();iter!=vars.end();iter++) - { - int tmp; - if(!LeafExprVar::isRecognizedKeyVar(*iter,tmp)) - trueVars.insert(*iter); - } -} - -void ExprParser::parseDeeper() -{ - for(std::vector::iterator iter=_sub_expr.begin();iter!=_sub_expr.end();iter++) - if(!(*iter).simplify()) - (*iter).parseDeeper(); -} - -/*! - * This method has the responsability to see if this->_expr can be seen as a unary function of something. - * Something defined as the contain of highest level barckets. - * Typically '(3*x+2)' and 'cos(4*l+p*n)' will be intercepted by this method whereas '3*x+2' not...etc.. - */ -void ExprParser::parseUnaryFunc() -{ - if(_expr[_expr.length()-1]!=')') - return ; - //at this level of code _expr - std::size_t pos1=_expr.find_first_of('('); - std::size_t pos4=FindCorrespondingOpenBracket(_expr,_expr.length()-1); - if(pos4!=pos1) - return ; - std::string funcName=_expr.substr(0,pos1); - std::size_t pos2=funcName.find_first_of("+-*/^><",0,7); - std::size_t pos3=funcName.find_first_not_of("+-*/^><",0,7); - if(pos2!=std::string::npos && pos3!=std::string::npos) - return ;//Bracket group is not alone, can't conclude not recursively. - std::string newExp2=_expr.substr(pos1+1,_expr.length()-pos1-2); - std::size_t nbOfParamsInFunc=std::count(newExp2.begin(),newExp2.end(),',')+1; - if(pos3!=std::string::npos) - _func_btw_sub_expr.push_back(FunctionsFactory::buildFuncFromString(funcName.c_str(),(int)nbOfParamsInFunc)); - else - { - std::size_t lgth=funcName.length(); - char tmp[2]; tmp[1]='\0'; - for(std::size_t i=0;i_expr is interpretable without any recursion. - * \return true if no recursion needed, false if this->_expr is too complex to be interpreted at this level. - * \throw exception if this->_expr is simple enough to try to interprate this and this expression contains an error. - */ -bool ExprParser::tryToInterpALeaf() -{ - std::size_t pos=_expr.find_first_not_of("+-",0,2); - std::string minimizedExpr=_expr.substr(pos); - std::size_t pos2=minimizedExpr.find_first_of("+-*/^()<>",0,9); - if(pos2!=std::string::npos) - return false; - delete _leaf; - _leaf=LeafExpr::buildInstanceFrom(minimizedExpr); - int nbOfNegs=0; - for(std::size_t i=0;i': - case '<': - { - isParsingSucceed=true; - if(!curPart.empty()) - { - _sub_expr.push_back(ExprParser(curPart.c_str(),this)); - curPart.clear(); - _func_btw_sub_expr.push_back(FunctionsFactory::buildBinaryFuncFromString(*iter)); - } - else - { - std::ostringstream errMsg; - char MSGTYP1[]="Error non unary function for '"; - errMsg << EXPR_PARSE_ERR_MSG << MSGTYP1 << *iter << "'"; - std::string tmp=_expr.substr(iter-_expr.begin()); - LocateError(errMsg,tmp,0); - throw INTERP_KERNEL::Exception(errMsg.str().c_str()); - } - break; - } - case '(': - curLevel++; - curPart+=*iter; - break; - case ')': - curLevel--; - curPart+=*iter; - break; - default: - curPart+=*iter; - } - } - if(isParsingSucceed) - { - if(!curPart.empty()) - { - _sub_expr.push_back(ExprParser(curPart.c_str(),this)); - _is_parsing_ok=true; - } - else - { - std::ostringstream errMsg; - char MSGTYP4[]="Error following expression finished by > / < without right part."; - errMsg << EXPR_PARSE_ERR_MSG << MSGTYP4 << _expr; - throw INTERP_KERNEL::Exception(errMsg.str().c_str()); - } - } -} - -void ExprParser::parseForAddMin() -{ - std::string::const_iterator iter; - int curLevel=0; - std::string curPart; - bool isParsingSucceed=false; - for(iter=_expr.begin();iter!=_expr.end();iter++) - { - switch(*iter) - { - case '+': - case '-': - if(curLevel!=0) - curPart+=*iter; - else - { - if(!curPart.empty()) - { - std::string::reverse_iterator accessor=curPart.rbegin(); - if(*accessor!='*' && *accessor!='/' && *accessor!='^') - { - isParsingSucceed=true; - _sub_expr.push_back(ExprParser(curPart.c_str(),this)); - curPart.clear(); - _func_btw_sub_expr.push_back(FunctionsFactory::buildBinaryFuncFromString(*iter)); - } - else - curPart+=*iter; - } - else - curPart+=*iter; - } - break; - case '(': - curLevel++; - curPart+=*iter; - break; - case ')': - curLevel--; - curPart+=*iter; - break; - default: - curPart+=*iter; - } - } - if(isParsingSucceed) - { - if(!curPart.empty()) - { - _sub_expr.push_back(ExprParser(curPart.c_str(),this)); - _is_parsing_ok=true; - } - else - { - std::ostringstream errMsg; - char MSGTYP4[]="Error following expression finished by +/- without right part."; - errMsg << EXPR_PARSE_ERR_MSG << MSGTYP4 << _expr; - throw INTERP_KERNEL::Exception(errMsg.str().c_str()); - } - } -} - -void ExprParser::parseForMulDiv() -{ - std::string::const_iterator iter; - int curLevel=0; - std::string curPart; - bool isParsingSucceed=false; - for(iter=_expr.begin();iter!=_expr.end();iter++) - { - switch(*iter) - { - case '/': - case '*': - if(curLevel!=0) - curPart+=*iter; - else - { - isParsingSucceed=true; - if(!curPart.empty()) - { - _sub_expr.push_back(ExprParser(curPart.c_str(),this)); - curPart.clear(); - _func_btw_sub_expr.push_back(FunctionsFactory::buildBinaryFuncFromString(*iter)); - } - else - { - std::ostringstream errMsg; - char MSGTYP1[]="Error non unary function for '"; - errMsg << EXPR_PARSE_ERR_MSG << MSGTYP1 << *iter << "'"; - std::string tmp=_expr.substr(iter-_expr.begin()); - LocateError(errMsg,tmp,0); - throw INTERP_KERNEL::Exception(errMsg.str().c_str()); - } - } - break; - case '(': - curLevel++; - curPart+=*iter; - break; - case ')': - curLevel--; - curPart+=*iter; - break; - default: - curPart+=*iter; - } - } - if(isParsingSucceed) - { - if(!curPart.empty()) - { - _sub_expr.push_back(ExprParser(curPart.c_str(),this)); - _is_parsing_ok=true; - } - else - { - std::ostringstream errMsg; - char MSGTYP5[]="Error following expression finished by *// without right part."; - errMsg << EXPR_PARSE_ERR_MSG << MSGTYP5 << _expr; - throw INTERP_KERNEL::Exception(errMsg.str().c_str()); - } - } -} - -void ExprParser::parseForPow() -{ - std::string::const_iterator iter; - int curLevel=0; - std::string curPart; - bool isParsingSucceed=false; - for(iter=_expr.begin();iter!=_expr.end();iter++) - { - switch(*iter) - { - case '^': - if(curLevel!=0) - curPart+=*iter; - else - if(!curPart.empty()) - { - isParsingSucceed=true; - _sub_expr.push_back(ExprParser(curPart.c_str(),this)); - curPart.clear(); - _func_btw_sub_expr.push_back(FunctionsFactory::buildBinaryFuncFromString(*iter)); - } - else - { - std::ostringstream errMsg; - char MSGTYP1[]="Error non unary function for '"; - errMsg << EXPR_PARSE_ERR_MSG << MSGTYP1 << *iter << "'"; - std::string tmp=_expr.substr(iter-_expr.begin()); - LocateError(errMsg,tmp,0);curPart+=*iter; - throw INTERP_KERNEL::Exception(errMsg.str().c_str()); - } - break; - case '(': - curLevel++; - curPart+=*iter; - break; - case ')': - curLevel--; - curPart+=*iter; - break; - default: - curPart+=*iter; - } - } - if(isParsingSucceed) - { - if(!curPart.empty()) - { - _sub_expr.push_back(ExprParser(curPart.c_str(),this)); - _is_parsing_ok=true; - } - else - { - std::ostringstream errMsg; - char MSGTYP6[]="Error following expression finished by ^ without right part."; - errMsg << EXPR_PARSE_ERR_MSG << MSGTYP6 << _expr; - throw INTERP_KERNEL::Exception(errMsg.str().c_str()); - } - } -} - -void ExprParser::releaseFunctions() -{ - for(std::vector::iterator iter=_func_btw_sub_expr.begin();iter!=_func_btw_sub_expr.end();iter++) - delete *iter; - _func_btw_sub_expr.clear(); -} - -/*! - * This method parse this->_expr at the current level. - * This method first try to see if this->_expr is a leaf, if not it try a unary function of something (see INTERP_KERNEL::ExprParser::parseUnaryFunc method) - * If true is returned, no deeper parsing needed, if false is returned for a full parsing of this->_expr INTERP_KERNEL::ExprParser::parseDeeper call needed. - */ -bool ExprParser::simplify() -{ - if(tryToInterpALeaf()) - return true; - parseUnaryFunc(); - if(!_is_parsing_ok) - { - parseForCmp(); - if(!_is_parsing_ok) - { - parseForAddMin(); - if(!_is_parsing_ok) - { - parseForMulDiv(); - if(!_is_parsing_ok) - parseForPow(); - } - } - } - if(!_is_parsing_ok) - { - std::ostringstream errMsg; - char MSGTYP3[]="Error in interpreting : "; - errMsg << EXPR_PARSE_ERR_MSG << MSGTYP3 << _expr; - LocateError(errMsg,_expr,0); - throw INTERP_KERNEL::Exception(errMsg.str().c_str()); - } - return false; -} - -void ExprParser::checkBracketsParity() const -{ - std::string::const_iterator iter; - int curLevel=0; - for(iter=_expr.begin();iter!=_expr.end();iter++) - { - if(*iter=='(') - curLevel++; - else if(*iter==')') - { - if(curLevel==0) - { - std::ostringstream errMsg; - char MSGTYP1[]="Error in brackets : closing brackets ')' before openning '('"; - errMsg << EXPR_PARSE_ERR_MSG << MSGTYP1; - LocateError(errMsg,_expr,(int)std::distance(_expr.begin(),iter)); - throw INTERP_KERNEL::Exception(errMsg.str().c_str()); - } - curLevel--; - } - } - if(curLevel!=0) - { - std::ostringstream errMsg; - char MSGTYP2[]="Error in brackets : not finally closed expr."; - errMsg << EXPR_PARSE_ERR_MSG << MSGTYP2; - throw INTERP_KERNEL::Exception(errMsg.str().c_str()); - } -} - -/*! - * This method substitutes part in [bg,end) in expr by the content of (str(id)) and returns the double value representation in expr[bg,end). - * If double representation is invalid an exception is thrown. - * This method returns a delta that is the delta to operate to pos in expr after substitution. - */ -double ExprParser::ReplaceAndTraduce(std::string& expr, int id, std::size_t bg, std::size_t end, int& delta) -{ - static const char MSG[]="Interal error : A string expected to be a float is not one ! Bug to signal !"; - std::istringstream stream; - std::ostringstream oss; - std::size_t end2=end!=std::string::npos?end-bg:end; - std::string tmp=expr.substr(bg,end2); - stream.str(tmp); - double ret=std::numeric_limits::max(); - stream >> ret; - if(stream.fail()) - throw INTERP_KERNEL::Exception(MSG); - if(!stream.eof()) - throw INTERP_KERNEL::Exception(MSG); - oss << id; - std::string tmp2(oss.str()); - std::size_t l1=tmp.length(); - delta=(int)tmp2.length()-(int)l1; - expr.replace(bg,l1,tmp2); - return ret; -} - -/*! - * This method makes the assumption that _expr has no white space. - * This method scans _expr finding in greedy mode the following pattern : - * {0..9}+{.}?{0..9}*{{eE}{-}?{0..9}+}? - */ -void ExprParser::fillValuesInExpr(std::vector& valuesInExpr) -{ - const char FIGURES[]="0123456789"; - const std::string other("+-*^/(<>,"); - std::size_t lgth=_expr.length(); - int id=0,delta; - for(std::size_t pos=0;pos!=std::string::npos;id++) - { - std::size_t pos2=_expr.find_first_of(FIGURES,pos,10); - if(pos2==std::string::npos) - break; - if(pos2>0) - {//treat case of "x*log10(x)" -> "10" should NOT be intercepted by this - if(other.find_first_of(_expr[pos2-1])==std::string::npos) - { - pos=_expr.find_first_not_of(FIGURES,pos2,10); - id--; - continue; - } - if(_expr[pos2-1]==')') - { - pos=_expr.find_first_not_of(FIGURES,pos2,10); - std::ostringstream oss; oss << "Problem on parsing : Number \"" << _expr.substr(pos2,pos!=std::string::npos?pos2-pos:std::string::npos); - oss << "\" is right after close parenthesis... ')'"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - } - std::size_t pos3=_expr.find_first_not_of(FIGURES,pos2,10); - if(pos3==std::string::npos) - {//"x+1223442320" - valuesInExpr.push_back(ReplaceAndTraduce(_expr,id,pos2,std::string::npos,delta)); - break; - } - if(_expr[pos3]=='.') - pos3++; - if(pos3=lgth) - {//"x+1223334.223e+" or "1223334.223E-" - std::ostringstream oss; oss << "Invalid expr : float number at the end of expr is invalid lacking number after exponential and sign ! -> \"" << _expr.substr(pos2) << "\""; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - std::size_t pos5=_expr.find_first_not_of(FIGURES,pos4,10); - if(pos4==pos5) - {//"x+1223334.223e+x" or "1223334.223E-y" - std::ostringstream oss; oss << "Invalid expr : float number in expr is invalid lacking number after exponential ! -> \"" << _expr.substr(pos2,pos4-pos2) << "\""; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - //OK, normal case - valuesInExpr.push_back(ReplaceAndTraduce(_expr,id,pos2,pos5,delta)); - pos=pos5+delta; - continue; - } - else//"x+1223334.223e" - { - std::ostringstream oss; oss << "Invalid expr : float number at the end of expr is invalid lacking number after exponential ! " << _expr.substr(pos2); - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - } - } - } - else - {//"x+1223334." - valuesInExpr.push_back(ReplaceAndTraduce(_expr,id,pos2,std::string::npos,delta)); - break; - } - } -} - -void ExprParser::replaceValues(const std::vector& valuesInExpr) -{ - if(_leaf) - _leaf->replaceValues(valuesInExpr); - else - { - for(std::vector::iterator iter=_sub_expr.begin();iter!=_sub_expr.end();iter++) - (*iter).replaceValues(valuesInExpr); - } -} - -void ExprParser::LocateError(std::ostream& stringToDisp, const std::string& srcOfErr, int posOfErr) -{ - stringToDisp << "Position is " << posOfErr << " of string : \"" << srcOfErr << "\"" << std::endl; -} - -char *ExprParser::compileX86() const -{ - std::vector ass; - //need in stack - ass.push_back("push ebp"); - ass.push_back("mov ebp,esp"); - compileX86LowLev(ass); - ass.push_back("pop ebp"); - ass.push_back("ret"); - std::cout << std::endl; - for(std::vector::const_iterator iter=ass.begin();iter!=ass.end();iter++) - std::cout << " " << *iter << std::endl; - AsmX86 asmb; - std::vector output=asmb.convertIntoMachineLangage(ass); - for(std::vector::const_iterator iter=output.begin();iter!=output.end();iter++) - std::cout << std::hex << (int)((unsigned char)(*iter)) << " "; - std::cout << std::endl; - unsigned offset; - return asmb.copyToExecMemZone(output,offset); -} - -char *ExprParser::compileX86_64() const -{ - std::vector ass; - //need in stack - ass.push_back("push rbp"); - ass.push_back("mov rbp,rsp"); - compileX86_64LowLev(ass); - ass.push_back("sub rsp,8"); - ass.push_back("fst qword [rsp]"); - ass.push_back("movsd xmm0,[rsp]"); - ass.push_back("add rsp,8"); - ass.push_back("leave"); - ass.push_back("ret"); - std::cout << std::endl; - for(std::vector::const_iterator iter=ass.begin();iter!=ass.end();iter++) - std::cout << " " << *iter << std::endl; - AsmX86 asmb; - std::vector output=asmb.convertIntoMachineLangage(ass); - for(std::vector::const_iterator iter=output.begin();iter!=output.end();iter++) - std::cout << std::hex << (int)((unsigned char)(*iter)) << " "; - std::cout << std::endl; - unsigned offset; - return asmb.copyToExecMemZone(output,offset); -} - -void ExprParser::compileX86LowLev(std::vector& ass) const -{ - if(_leaf) - _leaf->compileX86(ass); - else - { - for(std::vector::const_iterator iter=_sub_expr.begin();iter!=_sub_expr.end();iter++) - (*iter).compileX86LowLev(ass); - } - for(std::vector::const_iterator iter2=_func_btw_sub_expr.begin();iter2!=_func_btw_sub_expr.end();iter2++) - (*iter2)->operateX86(ass); -} - -void ExprParser::compileX86_64LowLev(std::vector& ass) const -{ - if(_leaf) - _leaf->compileX86_64(ass); - else - { - for(std::vector::const_iterator iter=_sub_expr.begin();iter!=_sub_expr.end();iter++) - (*iter).compileX86_64LowLev(ass); - } - for(std::vector::const_iterator iter2=_func_btw_sub_expr.begin();iter2!=_func_btw_sub_expr.end();iter2++) - (*iter2)->operateX86(ass); -} - -double LeafExprVal::getDoubleValue() const -{ - return _value; -} - -void LeafExprVal::compileX86(std::vector& ass) const -{ - ass.push_back("sub esp,8"); - const int *b=reinterpret_cast(&_value),*c=reinterpret_cast(&_value); - c++; - std::ostringstream oss; - oss << std::hex; - oss << "mov dword [esp+4],0x" << *c; - ass.push_back(oss.str()); - oss.str(""); - oss << "mov dword [esp],0x" << *b; - ass.push_back(oss.str()); - ass.push_back("fld qword [esp]"); - ass.push_back("add esp,8"); -} - -void LeafExprVal::compileX86_64(std::vector& ass) const -{ - ass.push_back("sub rsp,8"); - const int *b=reinterpret_cast(&_value),*c=reinterpret_cast(&_value); - c++; - std::ostringstream oss; - oss << std::hex; - oss << "mov dword [rsp+4],0x" << *c; - ass.push_back(oss.str()); - oss.str(""); - oss << "mov dword [rsp],0x" << *b; - ass.push_back(oss.str()); - ass.push_back("fld qword [rsp]"); - ass.push_back("add rsp,8"); -} - -double LeafExprVar::getDoubleValue() const -{ - if(_fast_pos>=0) - return _val[_fast_pos]; - else - { - int pos(-7-_fast_pos); - return pos==_ref_pos?1.:0.; - } -} - -void LeafExprVar::compileX86(std::vector& ass) const -{ - ass.push_back("fld qword [ebp+8]"); -} - -void LeafExprVar::compileX86_64(std::vector& ass) const -{ - ass.push_back("sub rsp,8"); - ass.push_back("movsd [rsp],xmm0"); - ass.push_back("fld qword [rsp]"); - ass.push_back("add rsp,8"); -} - -int ExprParser::getStackSizeToPlayX86(const ExprParser *asker) const -{ - if(asker) - { - int sz=_father->getStackSizeToPlayX86(this); - int i=0; - for(std::vector::const_reverse_iterator iter=_sub_expr.rbegin();iter!=_sub_expr.rend();iter++,i++) - { - const ExprParser& obj=(*iter); - const ExprParser *pt=&obj; - if(pt==asker) - return sz-i; - } - throw INTERP_KERNEL::Exception("error getStackSizeToPlayX86 an object ExprParser called as father, whereas it is not one !"); - } - else - { - if(!_father) - return MAX_X86_FP_ST; - return _father->getStackSizeToPlayX86(this); - } -} diff --git a/src/INTERP_KERNEL/ExprEval/InterpKernelExprParser.hxx b/src/INTERP_KERNEL/ExprEval/InterpKernelExprParser.hxx deleted file mode 100644 index 0b1642a14..000000000 --- a/src/INTERP_KERNEL/ExprEval/InterpKernelExprParser.hxx +++ /dev/null @@ -1,192 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 -// 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 __INTERPKERNELEXPRPARSER_HXX__ -#define __INTERPKERNELEXPRPARSER_HXX__ - -#include "INTERPKERNELDefines.hxx" -#include "InterpKernelUnit.hxx" -#include "InterpKernelException.hxx" -#include "InterpKernelFunction.hxx" - -#include -#include -#include -#include - -namespace INTERP_KERNEL -{ - class ValueDouble; - - class LeafExpr - { - public: - INTERPKERNEL_EXPORT virtual ~LeafExpr(); - INTERPKERNEL_EXPORT virtual double getDoubleValue() const = 0; - INTERPKERNEL_EXPORT virtual void fillValue(Value *val) const = 0; - INTERPKERNEL_EXPORT virtual void compileX86(std::vector& ass) const = 0; - INTERPKERNEL_EXPORT virtual void compileX86_64(std::vector& ass) const = 0; - INTERPKERNEL_EXPORT virtual void replaceValues(const std::vector& valuesInExpr) = 0; - INTERPKERNEL_EXPORT virtual LeafExpr *deepCpy() const = 0; - INTERPKERNEL_EXPORT static LeafExpr *buildInstanceFrom(const std::string& expr); - }; - - class LeafExprVal : public LeafExpr - { - public: - INTERPKERNEL_EXPORT LeafExprVal(double value); - INTERPKERNEL_EXPORT ~LeafExprVal(); - INTERPKERNEL_EXPORT double getDoubleValue() const; - INTERPKERNEL_EXPORT void compileX86(std::vector& ass) const; - INTERPKERNEL_EXPORT void compileX86_64(std::vector& ass) const; - INTERPKERNEL_EXPORT void fillValue(Value *val) const; - INTERPKERNEL_EXPORT void replaceValues(const std::vector& valuesInExpr); - INTERPKERNEL_EXPORT LeafExprVal *deepCpy() const; - private: - double _value; - }; - - class LeafExprVar : public LeafExpr - { - public: - INTERPKERNEL_EXPORT LeafExprVar(const LeafExprVar& other):_fast_pos(other._fast_pos),_ref_pos(other._ref_pos),_var_name(other._var_name),_val(other._val) { } - INTERPKERNEL_EXPORT LeafExprVar(const std::string& var); - INTERPKERNEL_EXPORT ~LeafExprVar(); - INTERPKERNEL_EXPORT double getDoubleValue() const; - INTERPKERNEL_EXPORT void compileX86(std::vector& ass) const; - INTERPKERNEL_EXPORT void compileX86_64(std::vector& ass) const; - INTERPKERNEL_EXPORT void fillValue(Value *val) const; - INTERPKERNEL_EXPORT std::string getVar() const { return _var_name; } - INTERPKERNEL_EXPORT void prepareExprEvaluation(const std::vector& vars, int nbOfCompo, int targetNbOfCompo) const; - INTERPKERNEL_EXPORT void prepareExprEvaluationDouble(const std::vector& vars, int nbOfCompo, int targetNbOfCompo, int refPos, const double *ptOfInputStart, const double *ptOfInputEnd) const; - INTERPKERNEL_EXPORT void prepareExprEvaluationVec() const; - INTERPKERNEL_EXPORT void replaceValues(const std::vector& valuesInExpr); - INTERPKERNEL_EXPORT static bool isRecognizedKeyVar(const std::string& var, int& pos); - INTERPKERNEL_EXPORT LeafExprVar *deepCpy() const; - public: - static const char END_OF_RECOGNIZED_VAR[]; - private: - mutable int _fast_pos; - mutable int _ref_pos; - std::string _var_name; - mutable const double *_val; - }; - - class ExprParserOfEval - { - public: - ExprParserOfEval():_leaf(0) { } - ExprParserOfEval(LeafExpr *leaf, const std::vector& subParts, const std::vector& funcs):_leaf(leaf),_sub_parts(subParts),_funcs(funcs) { } - void evaluateDoubleInternal(std::vector& stck) const - { - if(_leaf) - stck.push_back(_leaf->getDoubleValue()); - else - for(std::vector::const_iterator iter=_sub_parts.begin();iter!=_sub_parts.end();iter++) - (*iter).evaluateDoubleInternal(stck); - for(std::vector::const_iterator iter3=_funcs.begin();iter3!=_funcs.end();iter3++) - (*iter3)->operateStackOfDouble(stck); - } - void evaluateDoubleInternalSafe(std::vector& stck) const - { - if(_leaf) - stck.push_back(_leaf->getDoubleValue()); - else - for(std::vector::const_iterator iter=_sub_parts.begin();iter!=_sub_parts.end();iter++) - (*iter).evaluateDoubleInternalSafe(stck); - for(std::vector::const_iterator iter3=_funcs.begin();iter3!=_funcs.end();iter3++) - (*iter3)->operateStackOfDoubleSafe(stck); - } - void clearSortedMemory(); - void sortMemory(); - private: - LeafExpr *_leaf; - std::vector _sub_parts; - std::vector _funcs; - }; - - class ExprParser - { - public: - INTERPKERNEL_EXPORT ExprParser(const std::string& expr, ExprParser *father=0); - INTERPKERNEL_EXPORT ExprParser(const char *expr, int lgth, ExprParser *father=0); - INTERPKERNEL_EXPORT ~ExprParser(); - INTERPKERNEL_EXPORT void parse(); - INTERPKERNEL_EXPORT bool isParsingSuccessfull() const { return _is_parsing_ok; } - INTERPKERNEL_EXPORT double evaluate() const; - INTERPKERNEL_EXPORT DecompositionInUnitBase evaluateUnit() const; - INTERPKERNEL_EXPORT void prepareExprEvaluation(const std::vector& vars, int nbOfCompo, int targetNbOfCompo) const; - INTERPKERNEL_EXPORT void prepareExprEvaluationDouble(const std::vector& vars, int nbOfCompo, int targetNbOfCompo, int refPos, const double *ptOfInputStart, const double *ptOfInputEnd) const; - INTERPKERNEL_EXPORT void prepareFastEvaluator() const; - INTERPKERNEL_EXPORT void prepareExprEvaluationVec() const; - INTERPKERNEL_EXPORT double evaluateDouble() const; - INTERPKERNEL_EXPORT void evaluateDoubleInternal(std::vector& stck) const { _for_eval.evaluateDoubleInternal(stck); } - INTERPKERNEL_EXPORT void evaluateDoubleInternalSafe(std::vector& stck) const { _for_eval.evaluateDoubleInternalSafe(stck); } - INTERPKERNEL_EXPORT void checkForEvaluation() const; - INTERPKERNEL_EXPORT void evaluateExpr(int szOfOutParam, const double *inParam, double *outParam) const; - INTERPKERNEL_EXPORT void getSetOfVars(std::set& vars) const; - INTERPKERNEL_EXPORT void getTrueSetOfVars(std::set& vars) const; - // - INTERPKERNEL_EXPORT char *compileX86() const; - INTERPKERNEL_EXPORT char *compileX86_64() const; - INTERPKERNEL_EXPORT void compileX86LowLev(std::vector& ass) const; - INTERPKERNEL_EXPORT void compileX86_64LowLev(std::vector& ass) const; - INTERPKERNEL_EXPORT int getStackSizeToPlayX86(const ExprParser *asker) const; - // - INTERPKERNEL_EXPORT static std::string buildStringFromFortran(const char *expr, int lgth); - INTERPKERNEL_EXPORT static std::string deleteWhiteSpaces(const std::string& expr); - private: - Value *evaluateLowLev(Value *valGen) const; - void reverseThis(); - ExprParserOfEval convertMeTo() const; - private: - void prepareExprEvaluationVecLowLev() const; - bool tryToInterpALeaf(); - void parseUnaryFunc(); - void parseForCmp(); - void parseForAddMin(); - void parseForMulDiv(); - void parseForPow(); - void parseDeeper(); - bool simplify(); - void releaseFunctions(); - void checkBracketsParity() const; - void fillValuesInExpr(std::vector& valuesInExpr); - void replaceValues(const std::vector& valuesInExpr); - static double ReplaceAndTraduce(std::string& expr, int id, std::size_t bg, std::size_t end, int& delta); - static std::size_t FindCorrespondingOpenBracket(const std::string& expr, std::size_t posOfCloseBracket); - static void LocateError(std::ostream& stringToDisp, const std::string& srcOfErr, int posOfErr); - private: - ExprParser *_father; - bool _is_parsed; - LeafExpr *_leaf; - bool _is_parsing_ok; - std::string _expr; - mutable ExprParserOfEval _for_eval; - std::vector _sub_expr; - std::vector _func_btw_sub_expr; - private: - static const int MAX_X86_FP_ST=8; - static const char WHITE_SPACES[]; - static const char EXPR_PARSE_ERR_MSG[]; - }; -} - -#endif diff --git a/src/INTERP_KERNEL/ExprEval/InterpKernelFunction.cxx b/src/INTERP_KERNEL/ExprEval/InterpKernelFunction.cxx deleted file mode 100644 index 5af091240..000000000 --- a/src/INTERP_KERNEL/ExprEval/InterpKernelFunction.cxx +++ /dev/null @@ -1,1292 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 -// 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 "InterpKernelFunction.hxx" -#include "InterpKernelValue.hxx" - -#include -#include - -using namespace INTERP_KERNEL; - -const char IdentityFunction::REPR[]="Id"; - -const char PositiveFunction::REPR[]="+"; - -const char NegateFunction::REPR[]="-"; - -const char CosFunction::REPR[]="cos"; - -const char SinFunction::REPR[]="sin"; - -const char TanFunction::REPR[]="tan"; - -const char ACosFunction::REPR[]="acos"; - -const char ASinFunction::REPR[]="asin"; - -const char ATanFunction::REPR[]="atan"; - -const char CoshFunction::REPR[]="cosh"; - -const char SinhFunction::REPR[]="sinh"; - -const char TanhFunction::REPR[]="tanh"; - -const char SqrtFunction::REPR[]="sqrt"; - -const char AbsFunction::REPR[]="abs"; - -const char PlusFunction::REPR[]="+"; - -const char MinusFunction::REPR[]="-"; - -const char MultFunction::REPR[]="*"; - -const char DivFunction::REPR[]="/"; - -const char PowFunction::REPR[]="^"; - -const char ExpFunction::REPR[]="exp"; - -const char LnFunction::REPR[]="ln"; - -const char LogFunction::REPR[]="log"; - -const char Log10Function::REPR[]="log10"; - -const char MaxFunction::REPR[]="max"; - -const char MinFunction::REPR[]="min"; - -const char GreaterThanFunction::REPR[]=">"; - -const char LowerThanFunction::REPR[]="<"; - -const char IfFunction::REPR[]="if"; - -Function *FunctionsFactory::buildFuncFromString(const char *type, int nbOfParams) -{ - switch(nbOfParams) - { - case 1: - return buildUnaryFuncFromString(type); - case 2: - return buildBinaryFuncFromString(type); - case 3: - return buildTernaryFuncFromString(type); - default: - throw INTERP_KERNEL::Exception("Invalid number of params detected : limited to 2 !"); - } -} - -Function *FunctionsFactory::buildUnaryFuncFromString(const char *type) -{ - std::string tmp(type); - if(tmp.empty()) - return new IdentityFunction; - if(tmp==CosFunction::REPR) - return new CosFunction; - if(tmp==SinFunction::REPR) - return new SinFunction; - if(tmp==TanFunction::REPR) - return new TanFunction; - if(tmp==ACosFunction::REPR) - return new ACosFunction; - if(tmp==ASinFunction::REPR) - return new ASinFunction; - if(tmp==ATanFunction::REPR) - return new ATanFunction; - if(tmp==CoshFunction::REPR) - return new CoshFunction; - if(tmp==SinhFunction::REPR) - return new SinhFunction; - if(tmp==TanhFunction::REPR) - return new TanhFunction; - if(tmp==SqrtFunction::REPR) - return new SqrtFunction; - if(tmp==AbsFunction::REPR) - return new AbsFunction; - if(tmp==PositiveFunction::REPR) - return new PositiveFunction; - if(tmp==NegateFunction::REPR) - return new NegateFunction; - if(tmp==ExpFunction::REPR) - return new ExpFunction; - if(tmp==LnFunction::REPR) - return new LnFunction; - if(tmp==LogFunction::REPR) - return new LogFunction; - if(tmp==Log10Function::REPR) - return new Log10Function; - // - std::string msg("Invalid unary function detected : \""); - msg+=type; msg+="\""; - throw INTERP_KERNEL::Exception(msg.c_str()); -} - -Function *FunctionsFactory::buildBinaryFuncFromString(const char *type) -{ - std::string tmp(type); - if(tmp==PositiveFunction::REPR) - return new PlusFunction; - if(tmp==NegateFunction::REPR) - return new MinusFunction; - if(tmp==MultFunction::REPR) - return new MultFunction; - if(tmp==DivFunction::REPR) - return new DivFunction; - if(tmp==PowFunction::REPR) - return new PowFunction; - if(tmp==MaxFunction::REPR) - return new MaxFunction; - if(tmp==MinFunction::REPR) - return new MinFunction; - if(tmp==GreaterThanFunction::REPR) - return new GreaterThanFunction; - if(tmp==LowerThanFunction::REPR) - return new LowerThanFunction; - std::string msg("Invalid binary function detected : \""); - msg+=type; msg+="\""; - throw INTERP_KERNEL::Exception(msg.c_str()); -} - -Function *FunctionsFactory::buildTernaryFuncFromString(const char *type) -{ - std::string tmp(type); - if(tmp==IfFunction::REPR) - return new IfFunction(); - std::string msg("Invalid ternary function detected : \""); - msg+=type; msg+="\""; - throw INTERP_KERNEL::Exception(msg.c_str()); -} - -Function *FunctionsFactory::buildBinaryFuncFromString(char type) -{ - char tmp[2]; tmp[0]=type; tmp[1]='\0'; - return buildBinaryFuncFromString(tmp); -} - -Function::~Function() -{ -} - -IdentityFunction::~IdentityFunction() -{ -} - -void IdentityFunction::operate(std::vector& stck) const -{ -} - -void IdentityFunction::operateX86(std::vector& asmb) const -{ -} - -void IdentityFunction::operateStackOfDouble(std::vector& stck) const -{ -} - -const char *IdentityFunction::getRepr() const -{ - return REPR; -} - -bool IdentityFunction::isACall() const -{ - return false; -} - -PositiveFunction::~PositiveFunction() -{ -} - -int UnaryFunction::getNbInputParams() const -{ - return 1; -} - -void PositiveFunction::operate(std::vector& stck) const -{ -} - -void PositiveFunction::operateX86(std::vector& asmb) const -{ -} - -void PositiveFunction::operateStackOfDouble(std::vector& stck) const -{ -} - -const char *PositiveFunction::getRepr() const -{ - return REPR; -} - -bool PositiveFunction::isACall() const -{ - return false; -} - -NegateFunction::~NegateFunction() -{ -} - -void NegateFunction::operate(std::vector& stck) const -{ - Value *val=stck.back(); - val->negate(); -} - -void NegateFunction::operateX86(std::vector& asmb) const -{ - asmb.push_back("fchs"); -} - -void NegateFunction::operateStackOfDouble(std::vector& stck) const -{ - double v(stck.back()); - stck.back()=-v; -} - -const char *NegateFunction::getRepr() const -{ - return REPR; -} - -bool NegateFunction::isACall() const -{ - return false; -} - -CosFunction::~CosFunction() -{ -} - -void CosFunction::operate(std::vector& stck) const -{ - Value *val=stck.back(); - val->cos(); -} - -void CosFunction::operateX86(std::vector& asmb) const -{ - asmb.push_back("fcos"); -} - -void CosFunction::operateStackOfDouble(std::vector& stck) const -{ - double v(stck.back()); - stck.back()=cos(v); -} - -const char *CosFunction::getRepr() const -{ - return REPR; -} - -bool CosFunction::isACall() const -{ - return true; -} - -SinFunction::~SinFunction() -{ -} - -void SinFunction::operate(std::vector& stck) const -{ - Value *val=stck.back(); - val->sin(); -} - -void SinFunction::operateX86(std::vector& asmb) const -{ - asmb.push_back("fsin"); -} - -void SinFunction::operateStackOfDouble(std::vector& stck) const -{ - double v(stck.back()); - stck.back()=sin(v); -} - -const char *SinFunction::getRepr() const -{ - return REPR; -} - -bool SinFunction::isACall() const -{ - return true; -} - -TanFunction::~TanFunction() -{ -} - -void TanFunction::operate(std::vector& stck) const -{ - Value *val=stck.back(); - val->tan(); -} - -void TanFunction::operateX86(std::vector& asmb) const -{ - throw INTERP_KERNEL::Exception("Assembly Not implemented yet !"); -} - -void TanFunction::operateStackOfDouble(std::vector& stck) const -{ - double v(stck.back()); - stck.back()=tan(v); -} - -const char *TanFunction::getRepr() const -{ - return REPR; -} - -bool TanFunction::isACall() const -{ - return true; -} - -ACosFunction::~ACosFunction() -{ -} - -void ACosFunction::operate(std::vector& stck) const -{ - Value *val=stck.back(); - val->acos(); -} - -void ACosFunction::operateX86(std::vector& asmb) const -{ - throw INTERP_KERNEL::Exception("Assembly Not implemented yet !"); -} - -void ACosFunction::operateStackOfDouble(std::vector& stck) const -{ - double v(stck.back()); - stck.back()=acos(v); -} - -void ACosFunction::operateStackOfDoubleSafe(std::vector& stck) const -{ - double v(stck.back()); - if(fabs(v)>1.) - throw INTERP_KERNEL::Exception("acos on a value which absolute is > 1 !"); - stck.back()=acos(v); -} - -const char *ACosFunction::getRepr() const -{ - return REPR; -} - -bool ACosFunction::isACall() const -{ - return true; -} - -ASinFunction::~ASinFunction() -{ -} - -void ASinFunction::operate(std::vector& stck) const -{ - Value *val=stck.back(); - val->asin(); -} - -void ASinFunction::operateX86(std::vector& asmb) const -{ - throw INTERP_KERNEL::Exception("Assembly Not implemented yet !"); -} - -void ASinFunction::operateStackOfDouble(std::vector& stck) const -{ - double v(stck.back()); - stck.back()=asin(v); -} - -void ASinFunction::operateStackOfDoubleSafe(std::vector& stck) const -{ - double v(stck.back()); - if(fabs(v)>1.) - throw INTERP_KERNEL::Exception("asin on a value which absolute is > 1 !"); - stck.back()=asin(v); -} - -const char *ASinFunction::getRepr() const -{ - return REPR; -} - -bool ASinFunction::isACall() const -{ - return true; -} - -ATanFunction::~ATanFunction() -{ -} - -void ATanFunction::operate(std::vector& stck) const -{ - Value *val=stck.back(); - val->atan(); -} - -void ATanFunction::operateX86(std::vector& asmb) const -{ - throw INTERP_KERNEL::Exception("Assembly Not implemented yet !"); -} - -void ATanFunction::operateStackOfDouble(std::vector& stck) const -{ - double v(stck.back()); - stck.back()=atan(v); -} - -const char *ATanFunction::getRepr() const -{ - return REPR; -} - -bool ATanFunction::isACall() const -{ - return true; -} - -CoshFunction::~CoshFunction() -{ -} - -void CoshFunction::operate(std::vector& stck) const -{ - Value *val=stck.back(); - val->cosh(); -} - -void CoshFunction::operateX86(std::vector& asmb) const -{ - throw INTERP_KERNEL::Exception("Assembly Not implemented yet !"); -} - -void CoshFunction::operateStackOfDouble(std::vector& stck) const -{ - double v(stck.back()); - stck.back()=cosh(v); -} - -const char *CoshFunction::getRepr() const -{ - return REPR; -} - -bool CoshFunction::isACall() const -{ - return true; -} - -SinhFunction::~SinhFunction() -{ -} - -void SinhFunction::operate(std::vector& stck) const -{ - Value *val=stck.back(); - val->sinh(); -} - -void SinhFunction::operateX86(std::vector& asmb) const -{ - throw INTERP_KERNEL::Exception("Assembly Not implemented yet !"); -} - -void SinhFunction::operateStackOfDouble(std::vector& stck) const -{ - double v(stck.back()); - stck.back()=sinh(v); -} - -const char *SinhFunction::getRepr() const -{ - return REPR; -} - -bool SinhFunction::isACall() const -{ - return true; -} - -TanhFunction::~TanhFunction() -{ -} - -void TanhFunction::operate(std::vector& stck) const -{ - Value *val=stck.back(); - val->tanh(); -} - -void TanhFunction::operateX86(std::vector& asmb) const -{ - throw INTERP_KERNEL::Exception("Assembly Not implemented yet !"); -} - -void TanhFunction::operateStackOfDouble(std::vector& stck) const -{ - double v(stck.back()); - stck.back()=tanh(v); -} - -const char *TanhFunction::getRepr() const -{ - return REPR; -} - -bool TanhFunction::isACall() const -{ - return true; -} - -SqrtFunction::~SqrtFunction() -{ -} - -void SqrtFunction::operate(std::vector& stck) const -{ - Value *val=stck.back(); - val->sqrt(); -} - -void SqrtFunction::operateX86(std::vector& asmb) const -{ - asmb.push_back("fsqrt"); -} - -void SqrtFunction::operateStackOfDouble(std::vector& stck) const -{ - double v(stck.back()); - stck.back()=sqrt(v); -} - -void SqrtFunction::operateStackOfDoubleSafe(std::vector& stck) const -{ - double v(stck.back()); - if(v<0.) - throw INTERP_KERNEL::Exception("sqrt on a value < 0. !"); - stck.back()=sqrt(v); -} - -const char *SqrtFunction::getRepr() const -{ - return REPR; -} - -bool SqrtFunction::isACall() const -{ - return true; -} - -AbsFunction::~AbsFunction() -{ -} - -void AbsFunction::operate(std::vector& stck) const -{ - Value *val=stck.back(); - val->abs(); -} - -void AbsFunction::operateX86(std::vector& asmb) const -{ - asmb.push_back("fabs"); -} - -void AbsFunction::operateStackOfDouble(std::vector& stck) const -{ - double v(stck.back()); - stck.back()=fabs(v); -} - -const char *AbsFunction::getRepr() const -{ - return REPR; -} - -bool AbsFunction::isACall() const -{ - return false; -} - -void ExpFunction::operate(std::vector& stck) const -{ - Value *val=stck.back(); - val->exp(); -} - -void ExpFunction::operateX86(std::vector& asmb) const -{ - throw INTERP_KERNEL::Exception("Assembly Not implemented yet !"); -} - -void ExpFunction::operateStackOfDouble(std::vector& stck) const -{ - double v(stck.back()); - stck.back()=std::exp(v); -} - -const char *ExpFunction::getRepr() const -{ - return REPR; -} - -bool ExpFunction::isACall() const -{ - return true; -} - -LnFunction::~LnFunction() -{ -} - -void LnFunction::operate(std::vector& stck) const -{ - Value *val=stck.back(); - val->ln(); -} - -void LnFunction::operateX86(std::vector& asmb) const -{ - throw INTERP_KERNEL::Exception("Assembly Not implemented yet !"); -} - -void LnFunction::operateStackOfDouble(std::vector& stck) const -{ - double v(stck.back()); - stck.back()=std::log(v); -} - -void LnFunction::operateStackOfDoubleSafe(std::vector& stck) const -{ - double v(stck.back()); - if(v<0.) - throw INTERP_KERNEL::Exception("ln on a value < 0. !"); - stck.back()=std::log(v); -} - -const char *LnFunction::getRepr() const -{ - return REPR; -} - -bool LnFunction::isACall() const -{ - return true; -} - -LogFunction::~LogFunction() -{ -} - -void LogFunction::operate(std::vector& stck) const -{ - Value *val=stck.back(); - val->ln(); -} - -void LogFunction::operateX86(std::vector& asmb) const -{ - throw INTERP_KERNEL::Exception("Assembly for log Not implemented yet !"); -} - -void LogFunction::operateStackOfDouble(std::vector& stck) const -{ - double v(stck.back()); - stck.back()=std::log(v); -} - -void LogFunction::operateStackOfDoubleSafe(std::vector& stck) const -{ - double v(stck.back()); - if(v<0.) - throw INTERP_KERNEL::Exception("log on a value < 0. !"); - stck.back()=std::log(v); -} - -const char *LogFunction::getRepr() const -{ - return REPR; -} - -bool LogFunction::isACall() const -{ - return true; -} - -Log10Function::~Log10Function() -{ -} - -void Log10Function::operate(std::vector& stck) const -{ - Value *val=stck.back(); - val->log10(); -} - -void Log10Function::operateX86(std::vector& asmb) const -{ - throw INTERP_KERNEL::Exception("Assembly for log Not implemented yet !"); -} - -void Log10Function::operateStackOfDouble(std::vector& stck) const -{ - double v(stck.back()); - stck.back()=std::log10(v); -} - -void Log10Function::operateStackOfDoubleSafe(std::vector& stck) const -{ - double v(stck.back()); - if(v<0.) - throw INTERP_KERNEL::Exception("log10 on a value < 0. !"); - stck.back()=std::log10(v); -} - -const char *Log10Function::getRepr() const -{ - return REPR; -} - -bool Log10Function::isACall() const -{ - return true; -} - -int BinaryFunction::getNbInputParams() const -{ - return 2; -} - -PlusFunction::~PlusFunction() -{ -} - -void PlusFunction::operate(std::vector& stck) const -{ - Value *val1=stck.back(); - stck.pop_back(); - Value *& val2=stck.back(); - Value *val3; - try - { - val3=val1->plus(val2); - } - catch(INTERP_KERNEL::Exception& e) - { - delete val1; - throw e; - } - delete val1; - delete val2; - val2=val3; -} - -void PlusFunction::operateX86(std::vector& asmb) const -{ - asmb.push_back("faddp st1"); -} - -void PlusFunction::operateStackOfDouble(std::vector& stck) const -{ - double a(stck.back()); - stck.pop_back(); - stck.back()=a+stck.back(); -} - -const char *PlusFunction::getRepr() const -{ - return REPR; -} - -bool PlusFunction::isACall() const -{ - return false; -} - -MinusFunction::~MinusFunction() -{ -} - -void MinusFunction::operate(std::vector& stck) const -{ - Value *val1=stck.back(); - stck.pop_back(); - Value *& val2=stck.back(); - Value *val3; - try - { - val3=val1->minus(val2); - } - catch(INTERP_KERNEL::Exception& e) - { - delete val1; - throw e; - } - delete val1; - delete val2; - val2=val3; -} - -void MinusFunction::operateX86(std::vector& asmb) const -{ - asmb.push_back("fsubp st1"); -} - -void MinusFunction::operateStackOfDouble(std::vector& stck) const -{ - double a(stck.back()); - stck.pop_back(); - stck.back()=a-stck.back(); -} - -const char *MinusFunction::getRepr() const -{ - return REPR; -} - -bool MinusFunction::isACall() const -{ - return false; -} - -MultFunction::~MultFunction() -{ -} - -void MultFunction::operate(std::vector& stck) const -{ - Value *val1=stck.back(); - stck.pop_back(); - Value *& val2=stck.back(); - Value *val3=val1->mult(val2); - delete val1; - delete val2; - val2=val3; -} - -void MultFunction::operateX86(std::vector& asmb) const -{ - asmb.push_back("fmulp st1"); -} - -void MultFunction::operateStackOfDouble(std::vector& stck) const -{ - double a(stck.back()); - stck.pop_back(); - stck.back()=a*stck.back(); -} - -const char *MultFunction::getRepr() const -{ - return REPR; -} - -bool MultFunction::isACall() const -{ - return false; -} - -DivFunction::~DivFunction() -{ -} - -void DivFunction::operate(std::vector& stck) const -{ - Value *val1=stck.back(); - stck.pop_back(); - Value *& val2=stck.back(); - Value *val3; - try - { - val3=val1->div(val2); - } - catch(INTERP_KERNEL::Exception& e) - { - delete val1; - throw e; - } - delete val1; - delete val2; - val2=val3; -} - -void DivFunction::operateX86(std::vector& asmb) const -{ - asmb.push_back("fdivp st1"); -} - -void DivFunction::operateStackOfDouble(std::vector& stck) const -{ - double a(stck.back()); - stck.pop_back(); - stck.back()=a/stck.back(); -} - -void DivFunction::operateStackOfDoubleSafe(std::vector& stck) const -{ - double a(stck.back()); - stck.pop_back(); - if(stck.back()==0.) - throw INTERP_KERNEL::Exception("division by 0. !"); - stck.back()=a/stck.back(); -} - -const char *DivFunction::getRepr() const -{ - return REPR; -} - -bool DivFunction::isACall() const -{ - return false; -} - -PowFunction::~PowFunction() -{ -} - -void PowFunction::operate(std::vector& stck) const -{ - Value *val1=stck.back(); - stck.pop_back(); - Value *& val2=stck.back(); - Value *val3; - try - { - val3=val1->pow(val2); - } - catch(INTERP_KERNEL::Exception& e) - { - delete val1; - throw e; - } - delete val1; - delete val2; - val2=val3; -} - -void PowFunction::operateX86(std::vector& asmb) const -{ - throw INTERP_KERNEL::Exception("Assembly Not implemented yet !"); -} - -void PowFunction::operateStackOfDouble(std::vector& stck) const -{ - double a(stck.back()); - stck.pop_back(); - stck.back()=std::pow(a,stck.back()); -} - -void PowFunction::operateStackOfDoubleSafe(std::vector& stck) const -{ - double a(stck.back()); - stck.pop_back(); - double b(stck.back()); - if(a<0.) - throw INTERP_KERNEL::Exception("pow with val < 0. !"); - stck.back()=std::pow(a,b); -} - -const char *PowFunction::getRepr() const -{ - return REPR; -} - -bool PowFunction::isACall() const -{ - return true; -} - -ExpFunction::~ExpFunction() -{ -} - -MaxFunction::~MaxFunction() -{ -} - -void MaxFunction::operate(std::vector& stck) const -{ - Value *val1=stck.back(); - stck.pop_back(); - Value *& val2=stck.back(); - Value *val3; - try - { - val3=val1->max(val2); - } - catch(INTERP_KERNEL::Exception& e) - { - delete val1; - throw e; - } - delete val1; - delete val2; - val2=val3; -} - -void MaxFunction::operateX86(std::vector& asmb) const -{ - throw INTERP_KERNEL::Exception("Assembly Not implemented yet !"); -} - -void MaxFunction::operateStackOfDouble(std::vector& stck) const -{ - double a(stck.back()); - stck.pop_back(); - stck.back()=std::max(stck.back(),a); -} - -const char *MaxFunction::getRepr() const -{ - return REPR; -} - -bool MaxFunction::isACall() const -{ - return false; -} - -MinFunction::~MinFunction() -{ -} - -void MinFunction::operate(std::vector& stck) const -{ - Value *val1=stck.back(); - stck.pop_back(); - Value *& val2=stck.back(); - Value *val3; - try - { - val3=val1->min(val2); - } - catch(INTERP_KERNEL::Exception& e) - { - delete val1; - throw e; - } - delete val1; - delete val2; - val2=val3; -} - -void MinFunction::operateX86(std::vector& asmb) const -{ - throw INTERP_KERNEL::Exception("Assembly Not implemented yet !"); -} - -void MinFunction::operateStackOfDouble(std::vector& stck) const -{ - double a(stck.back()); - stck.pop_back(); - stck.back()=std::min(stck.back(),a); -} - -const char *MinFunction::getRepr() const -{ - return REPR; -} - -bool MinFunction::isACall() const -{ - return false; -} - -GreaterThanFunction::~GreaterThanFunction() -{ -} - -void GreaterThanFunction::operate(std::vector& stck) const -{ - Value *val1=stck.back(); - stck.pop_back(); - Value *& val2=stck.back(); - Value *val3; - try - { - val3=val1->greaterThan(val2); - } - catch(INTERP_KERNEL::Exception& e) - { - delete val1; - throw e; - } - delete val1; - delete val2; - val2=val3; -} - -void GreaterThanFunction::operateX86(std::vector& asmb) const -{ - throw INTERP_KERNEL::Exception("Assembly Not implemented yet !"); -} - -void GreaterThanFunction::operateStackOfDouble(std::vector& stck) const -{ - double a(stck.back()); - stck.pop_back(); - double b(stck.back()); - stck.back()=a>b?std::numeric_limits::max():-std::numeric_limits::max(); -} - -const char *GreaterThanFunction::getRepr() const -{ - return REPR; -} - -bool GreaterThanFunction::isACall() const -{ - return false; -} - -LowerThanFunction::~LowerThanFunction() -{ -} - -void LowerThanFunction::operate(std::vector& stck) const -{ - Value *val1=stck.back(); - stck.pop_back(); - Value *& val2=stck.back(); - Value *val3; - try - { - val3=val1->lowerThan(val2); - } - catch(INTERP_KERNEL::Exception& e) - { - delete val1; - throw e; - } - delete val1; - delete val2; - val2=val3; -} - -void LowerThanFunction::operateX86(std::vector& asmb) const -{ - throw INTERP_KERNEL::Exception("Assembly Not implemented yet !"); -} - -void LowerThanFunction::operateStackOfDouble(std::vector& stck) const -{ - double a(stck.back()); - stck.pop_back(); - double b(stck.back()); - stck.back()=a::max():-std::numeric_limits::max(); -} - -const char *LowerThanFunction::getRepr() const -{ - return REPR; -} - -bool LowerThanFunction::isACall() const -{ - return false; -} - -int TernaryFunction::getNbInputParams() const -{ - return 3; -} - -IfFunction::~IfFunction() -{ -} - -void IfFunction::operate(std::vector& stck) const -{ - Value *val1=stck.back(); - stck.pop_back(); - Value *val2=stck.back(); - stck.pop_back(); - Value *&val3=stck.back(); - Value *val4; - try - { - val4=val1->ifFunc(val2,val3); - } - catch(INTERP_KERNEL::Exception& e) - { - delete val1; - delete val2; - throw e; - } - delete val1; - delete val2; - delete val3; - val3=val4; -} - -void IfFunction::operateX86(std::vector& asmb) const -{ - throw INTERP_KERNEL::Exception("Assembly Not implemented yet !"); -} - -void IfFunction::operateStackOfDouble(std::vector& stck) const -{ - double cond(stck.back()); - stck.pop_back(); - double the(stck.back()); - stck.pop_back(); - if(cond==std::numeric_limits::max()) - stck.back()=the; -} - -void IfFunction::operateStackOfDoubleSafe(std::vector& stck) const -{ - double cond(stck.back()); - stck.pop_back(); - double the(stck.back()); - stck.pop_back(); - if(cond!=std::numeric_limits::max() && cond!=-std::numeric_limits::max()) - throw INTERP_KERNEL::Exception("ifFunc : first parameter of ternary func is NOT a consequence of a boolean op !"); - if(cond==std::numeric_limits::max()) - stck.back()=the; -} - -const char *IfFunction::getRepr() const -{ - return REPR; -} - -bool IfFunction::isACall() const -{ - return false; -} - diff --git a/src/INTERP_KERNEL/ExprEval/InterpKernelFunction.hxx b/src/INTERP_KERNEL/ExprEval/InterpKernelFunction.hxx deleted file mode 100644 index 8f5cf489e..000000000 --- a/src/INTERP_KERNEL/ExprEval/InterpKernelFunction.hxx +++ /dev/null @@ -1,479 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 -// 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 __INTERPKERNELFUNCTION_HXX__ -#define __INTERPKERNELFUNCTION_HXX__ - -#include "INTERPKERNELDefines.hxx" -#include "InterpKernelException.hxx" - -#include - -namespace INTERP_KERNEL -{ - class Value; - class Function; - - class INTERPKERNEL_EXPORT FunctionsFactory - { - public: - static Function *buildFuncFromString(const char *type, int nbOfParams); - static Function *buildUnaryFuncFromString(const char *type); - //static Function *buildUnaryFuncFromString(char type); - static Function *buildBinaryFuncFromString(const char *type); - static Function *buildBinaryFuncFromString(char type); - static Function *buildTernaryFuncFromString(const char *type); - }; - - class INTERPKERNEL_EXPORT Function - { - public: - virtual ~Function(); - virtual int getNbInputParams() const = 0; - virtual void operate(std::vector& stck) const = 0; - virtual void operateX86(std::vector& asmb) const = 0; - virtual void operateStackOfDouble(std::vector& stck) const = 0; - virtual void operateStackOfDoubleSafe(std::vector& stck) const { operateStackOfDouble(stck); } - virtual const char *getRepr() const = 0; - virtual bool isACall() const = 0; - virtual Function *deepCpy() const = 0; - }; - - class INTERPKERNEL_EXPORT UnaryFunction : public Function - { - public: - int getNbInputParams() const; - }; - - class INTERPKERNEL_EXPORT IdentityFunction : public UnaryFunction - { - public: - ~IdentityFunction(); - void operate(std::vector& stck) const; - void operateX86(std::vector& asmb) const; - void operateStackOfDouble(std::vector& stck) const; - const char *getRepr() const; - bool isACall() const; - IdentityFunction *deepCpy() const { return new IdentityFunction; } - public: - static const char REPR[]; - }; - - class INTERPKERNEL_EXPORT PositiveFunction : public UnaryFunction - { - public: - ~PositiveFunction(); - void operate(std::vector& stck) const; - void operateX86(std::vector& asmb) const; - void operateStackOfDouble(std::vector& stck) const; - const char *getRepr() const; - bool isACall() const; - PositiveFunction *deepCpy() const { return new PositiveFunction; } - public: - static const char REPR[]; - }; - - class INTERPKERNEL_EXPORT NegateFunction : public UnaryFunction - { - public: - ~NegateFunction(); - void operate(std::vector& stck) const; - void operateX86(std::vector& asmb) const; - void operateStackOfDouble(std::vector& stck) const; - const char *getRepr() const; - bool isACall() const; - NegateFunction *deepCpy() const { return new NegateFunction; } - public: - static const char REPR[]; - }; - - class INTERPKERNEL_EXPORT CosFunction : public UnaryFunction - { - public: - ~CosFunction(); - void operate(std::vector& stck) const; - void operateX86(std::vector& asmb) const; - void operateStackOfDouble(std::vector& stck) const; - const char *getRepr() const; - bool isACall() const; - CosFunction *deepCpy() const { return new CosFunction; } - public: - static const char REPR[]; - }; - - class INTERPKERNEL_EXPORT SinFunction : public UnaryFunction - { - public: - ~SinFunction(); - void operate(std::vector& stck) const; - void operateX86(std::vector& asmb) const; - void operateStackOfDouble(std::vector& stck) const; - const char *getRepr() const; - bool isACall() const; - SinFunction *deepCpy() const { return new SinFunction; } - public: - static const char REPR[]; - }; - - class INTERPKERNEL_EXPORT TanFunction : public UnaryFunction - { - public: - ~TanFunction(); - void operate(std::vector& stck) const; - void operateX86(std::vector& asmb) const; - void operateStackOfDouble(std::vector& stck) const; - const char *getRepr() const; - bool isACall() const; - TanFunction *deepCpy() const { return new TanFunction; } - public: - static const char REPR[]; - }; - - class INTERPKERNEL_EXPORT ACosFunction : public UnaryFunction - { - public: - ~ACosFunction(); - void operate(std::vector& stck) const; - void operateX86(std::vector& asmb) const; - void operateStackOfDouble(std::vector& stck) const; - void operateStackOfDoubleSafe(std::vector& stck) const; - const char *getRepr() const; - bool isACall() const; - ACosFunction *deepCpy() const { return new ACosFunction; } - public: - static const char REPR[]; - }; - - class INTERPKERNEL_EXPORT ASinFunction : public UnaryFunction - { - public: - ~ASinFunction(); - void operate(std::vector& stck) const; - void operateX86(std::vector& asmb) const; - void operateStackOfDouble(std::vector& stck) const; - void operateStackOfDoubleSafe(std::vector& stck) const; - const char *getRepr() const; - bool isACall() const; - ASinFunction *deepCpy() const { return new ASinFunction; } - public: - static const char REPR[]; - }; - - class INTERPKERNEL_EXPORT ATanFunction : public UnaryFunction - { - public: - ~ATanFunction(); - void operate(std::vector& stck) const; - void operateX86(std::vector& asmb) const; - void operateStackOfDouble(std::vector& stck) const; - const char *getRepr() const; - bool isACall() const; - ATanFunction *deepCpy() const { return new ATanFunction; } - public: - static const char REPR[]; - }; - - class INTERPKERNEL_EXPORT CoshFunction : public UnaryFunction - { - public: - ~CoshFunction(); - void operate(std::vector& stck) const; - void operateX86(std::vector& asmb) const; - void operateStackOfDouble(std::vector& stck) const; - const char *getRepr() const; - bool isACall() const; - CoshFunction *deepCpy() const { return new CoshFunction; } - public: - static const char REPR[]; - }; - - class INTERPKERNEL_EXPORT SinhFunction : public UnaryFunction - { - public: - ~SinhFunction(); - void operate(std::vector& stck) const; - void operateX86(std::vector& asmb) const; - void operateStackOfDouble(std::vector& stck) const; - const char *getRepr() const; - bool isACall() const; - SinhFunction *deepCpy() const { return new SinhFunction; } - public: - static const char REPR[]; - }; - - class INTERPKERNEL_EXPORT TanhFunction : public UnaryFunction - { - public: - ~TanhFunction(); - void operate(std::vector& stck) const; - void operateX86(std::vector& asmb) const; - void operateStackOfDouble(std::vector& stck) const; - const char *getRepr() const; - bool isACall() const; - TanhFunction *deepCpy() const { return new TanhFunction; } - public: - static const char REPR[]; - }; - - class INTERPKERNEL_EXPORT SqrtFunction : public UnaryFunction - { - public: - ~SqrtFunction(); - void operateX86(std::vector& asmb) const; - void operate(std::vector& stck) const; - void operateStackOfDouble(std::vector& stck) const; - void operateStackOfDoubleSafe(std::vector& stck) const; - const char *getRepr() const; - bool isACall() const; - SqrtFunction *deepCpy() const { return new SqrtFunction; } - public: - static const char REPR[]; - }; - - class INTERPKERNEL_EXPORT AbsFunction : public UnaryFunction - { - public: - ~AbsFunction(); - void operate(std::vector& stck) const; - void operateX86(std::vector& asmb) const; - void operateStackOfDouble(std::vector& stck) const; - const char *getRepr() const; - bool isACall() const; - AbsFunction *deepCpy() const { return new AbsFunction; } - public: - static const char REPR[]; - }; - - class INTERPKERNEL_EXPORT ExpFunction : public UnaryFunction - { - public: - ~ExpFunction(); - void operate(std::vector& stck) const; - void operateX86(std::vector& asmb) const; - void operateStackOfDouble(std::vector& stck) const; - const char *getRepr() const; - bool isACall() const; - ExpFunction *deepCpy() const { return new ExpFunction; } - public: - static const char REPR[]; - }; - - class INTERPKERNEL_EXPORT LnFunction : public UnaryFunction - { - public: - ~LnFunction(); - void operate(std::vector& stck) const; - void operateX86(std::vector& asmb) const; - void operateStackOfDouble(std::vector& stck) const; - void operateStackOfDoubleSafe(std::vector& stck) const; - const char *getRepr() const; - bool isACall() const; - LnFunction *deepCpy() const { return new LnFunction; } - public: - static const char REPR[]; - }; - - class INTERPKERNEL_EXPORT LogFunction : public UnaryFunction - { - public: - ~LogFunction(); - void operate(std::vector& stck) const; - void operateX86(std::vector& asmb) const; - void operateStackOfDouble(std::vector& stck) const; - void operateStackOfDoubleSafe(std::vector& stck) const; - const char *getRepr() const; - bool isACall() const; - LogFunction *deepCpy() const { return new LogFunction; } - public: - static const char REPR[]; - }; - - class INTERPKERNEL_EXPORT Log10Function : public UnaryFunction - { - public: - ~Log10Function(); - void operate(std::vector& stck) const; - void operateX86(std::vector& asmb) const; - void operateStackOfDouble(std::vector& stck) const; - void operateStackOfDoubleSafe(std::vector& stck) const; - const char *getRepr() const; - bool isACall() const; - Log10Function *deepCpy() const { return new Log10Function; } - public: - static const char REPR[]; - }; - - class INTERPKERNEL_EXPORT BinaryFunction : public Function - { - public: - int getNbInputParams() const; - }; - - class PlusFunction : public BinaryFunction - { - public: - ~PlusFunction(); - void operate(std::vector& stck) const; - void operateX86(std::vector& asmb) const; - void operateStackOfDouble(std::vector& stck) const; - const char *getRepr() const; - bool isACall() const; - PlusFunction *deepCpy() const { return new PlusFunction; } - public: - static const char REPR[]; - }; - - class INTERPKERNEL_EXPORT MinusFunction : public BinaryFunction - { - public: - ~MinusFunction(); - void operate(std::vector& stck) const; - void operateX86(std::vector& asmb) const; - void operateStackOfDouble(std::vector& stck) const; - const char *getRepr() const; - bool isACall() const; - MinusFunction *deepCpy() const { return new MinusFunction; } - public: - static const char REPR[]; - }; - - class INTERPKERNEL_EXPORT MultFunction : public BinaryFunction - { - public: - ~MultFunction(); - void operate(std::vector& stck) const; - void operateX86(std::vector& asmb) const; - void operateStackOfDouble(std::vector& stck) const; - const char *getRepr() const; - bool isACall() const; - MultFunction *deepCpy() const { return new MultFunction; } - public: - static const char REPR[]; - }; - - class INTERPKERNEL_EXPORT DivFunction : public BinaryFunction - { - public: - ~DivFunction(); - void operate(std::vector& stck) const; - void operateX86(std::vector& asmb) const; - void operateStackOfDouble(std::vector& stck) const; - void operateStackOfDoubleSafe(std::vector& stck) const; - const char *getRepr() const; - bool isACall() const; - DivFunction *deepCpy() const { return new DivFunction; } - public: - static const char REPR[]; - }; - - class INTERPKERNEL_EXPORT PowFunction : public BinaryFunction - { - public: - ~PowFunction(); - void operate(std::vector& stck) const; - void operateX86(std::vector& asmb) const; - void operateStackOfDouble(std::vector& stck) const; - void operateStackOfDoubleSafe(std::vector& stck) const; - const char *getRepr() const; - bool isACall() const; - PowFunction *deepCpy() const { return new PowFunction; } - public: - static const char REPR[]; - }; - - class INTERPKERNEL_EXPORT MaxFunction : public BinaryFunction - { - public: - ~MaxFunction(); - void operate(std::vector& stck) const; - void operateX86(std::vector& asmb) const; - void operateStackOfDouble(std::vector& stck) const; - const char *getRepr() const; - bool isACall() const; - MaxFunction *deepCpy() const { return new MaxFunction; } - public: - static const char REPR[]; - }; - - class INTERPKERNEL_EXPORT MinFunction : public BinaryFunction - { - public: - ~MinFunction(); - void operate(std::vector& stck) const; - void operateX86(std::vector& asmb) const; - void operateStackOfDouble(std::vector& stck) const; - const char *getRepr() const; - bool isACall() const; - MinFunction *deepCpy() const { return new MinFunction; } - public: - static const char REPR[]; - }; - - class INTERPKERNEL_EXPORT GreaterThanFunction : public BinaryFunction - { - public: - ~GreaterThanFunction(); - void operate(std::vector& stck) const; - void operateX86(std::vector& asmb) const; - void operateStackOfDouble(std::vector& stck) const; - const char *getRepr() const; - bool isACall() const; - GreaterThanFunction *deepCpy() const { return new GreaterThanFunction; } - public: - static const char REPR[]; - }; - - class INTERPKERNEL_EXPORT LowerThanFunction : public BinaryFunction - { - public: - ~LowerThanFunction(); - void operate(std::vector& stck) const; - void operateX86(std::vector& asmb) const; - void operateStackOfDouble(std::vector& stck) const; - const char *getRepr() const; - bool isACall() const; - LowerThanFunction *deepCpy() const { return new LowerThanFunction; } - public: - static const char REPR[]; - }; - - class INTERPKERNEL_EXPORT TernaryFunction : public Function - { - public: - int getNbInputParams() const; - }; - - class INTERPKERNEL_EXPORT IfFunction : public TernaryFunction - { - public: - ~IfFunction(); - void operate(std::vector& stck) const; - void operateX86(std::vector& asmb) const; - void operateStackOfDouble(std::vector& stck) const; - void operateStackOfDoubleSafe(std::vector& stck) const; - const char *getRepr() const; - bool isACall() const; - IfFunction *deepCpy() const { return new IfFunction; } - public: - static const char REPR[]; - }; -} - -#endif diff --git a/src/INTERP_KERNEL/ExprEval/InterpKernelUnit.cxx b/src/INTERP_KERNEL/ExprEval/InterpKernelUnit.cxx deleted file mode 100644 index 44e08f49f..000000000 --- a/src/INTERP_KERNEL/ExprEval/InterpKernelUnit.cxx +++ /dev/null @@ -1,372 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 -// 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 "InterpKernelUnit.hxx" -#include "InterpKernelExprParser.hxx" - -#include -#include -#include -#include - -using namespace INTERP_KERNEL; - -UnitDataBase UnitDataBase::_uniqueMapForExpr; - -static const char InterpKernelMuAscii[2]={-0x4B,0x0}; - -static const char InterpKernelMuUnicode[3]={-0x3E,-0x4B,0x0}; - -const char *UnitDataBase::PREF_POW10[NB_OF_PREF_POW10]={"y","z","a","f","p","n",InterpKernelMuAscii,InterpKernelMuUnicode,"u","m","c","d", - "da","h","k","M","G","T","P","E","Z","Y"}; - -const double UnitDataBase::POW10[NB_OF_PREF_POW10]={1e-24,1e-21,1e-18,1e-15,1e-12,1e-9,1e-6,1e-6,1e-6,1e-3,1e-2,1e-1, - 1e1,1e2,1e3,1e6,1e9,1e12,1e15,1e18,1e21,1e24}; - -static const char InterpKernelDegreeCAscii[3]={-0x50,0x43,0x0}; - -static const char InterpKernelDegreeCUnicode[4]={-0x3E,-0x50,0x43,0x0}; - -static const char InterpKernelDegreeCUnicodeWin[3]={-0x08,0x43,0x0}; - -const char *UnitDataBase::UNITS_RECOGN[NB_OF_UNITS_RECOGN]={"g","m","s","A","K", - "W","J","Hz","V","h","min","t","N","dyn", - "eV","Pa","atm","bar",InterpKernelDegreeCAscii,"C","ohm","F","S", - "T","H","P","St",InterpKernelDegreeCUnicode,InterpKernelDegreeCUnicodeWin}; - -const short UnitDataBase::PROJ_IN_BASE[NB_OF_UNITS_RECOGN][SIZE_OF_UNIT_BASE]= - { - {1,0,0,0,0},//g - {0,1,0,0,0},//m - {0,0,1,0,0},//s - {0,0,0,1,0},//A - {0,0,0,0,1},//K - {1,2,-3,0,0},//W - {1,2,-2,0,0},//J - {0,0,-1,0,0},//Hz - {1,2,-3,-1,0},//V - {0,0,1,0,0},//h - {0,0,1,0,0},//min - {1,0,0,0,0},//t - {1,1,-2,0,0},//N - {1,1,-2,0,0},//dyn - {1,2,-2,0,0},//eV - {1,-1,-2,0,0},//Pa - {1,-1,-2,0,0},//atm - {1,-1,-2,0,0},//bar - {0,0,0,0,1},//degree C - {0,0,1,1,0},//C - {1,2,-3,-2,0},//ohm - {-1,-2,4,2,0},//F - {-1,-2,3,2,0},//S - {1,0,-2,-1,0},//T - {1,2,-2,-2,0},//H - {1,-1,-1,0,0},//P - {0,2,-1,0,0},//St - {0,0,0,0,1},//degree C - {0,0,0,0,1}//degree C - }; - -const double UnitDataBase::MUL_COEFF[NB_OF_UNITS_RECOGN]= - { 1.,1.,1.,1.,1., - 1000.,1000.,1.,1000.,3600.,3600.,1e6,1000.,1e-2, - 1.60217733e-16,1000.,1.01325e8,1e8,1.,1.,1000.,1e-3, - 1000.,1000.,100.,1.,1.,1.,1.}; - -const double UnitDataBase::ADD_COEFF[NB_OF_UNITS_RECOGN]= - { 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 273.15, 0., 0., 0., 0., 0., 0., 0., 0., 273.15 ,273.15}; - -UnitDataBase::UnitDataBase() -{ - for(int i=0;i::const_iterator iter=_units_semantic.find(work); - if(iter!=_units_semantic.end()) - { - ret=(*iter).second; - std::map::const_iterator iter2=_units_add.find(work); - addFact=(*iter2).second; - std::map::const_iterator iter3=_units_mul.find(work); - mFact=(*iter3).second; - work2=unit.substr(0,i); - } - } - if(!ret) - { - std::ostringstream os; - os << "Unit : " << unit << " not recognized !"; - throw INTERP_KERNEL::Exception(os.str().c_str()); - } - if(!work2.empty()) - { - std::map::const_iterator iter4=_prefix_pow_10.find(work2); - if(iter4==_prefix_pow_10.end()) - { - std::ostringstream os; - os << "Unit : " << unit << " not fully recognized : \"" << work << "\" detected as core unit and \""; - os << work2 << "\" not recognized prefix !"; - throw INTERP_KERNEL::Exception(os.str().c_str()); - } - addFact=0.; - mFact*=(*iter4).second; - } - return ret; -} - -DecompositionInUnitBase::DecompositionInUnitBase():_add_to_base(0.),_mult_fact_to_base(1.) -{ - _value[0]=0; - _value[1]=0; - _value[2]=0; - _value[3]=0; - _value[4]=0; -} - -void DecompositionInUnitBase::setInfo(const short *vals, double addFact, double mFact) -{ - _add_to_base=addFact; - _mult_fact_to_base=mFact; - _value[0]=vals[0]; - _value[1]=vals[1]; - _value[2]=vals[2]; - _value[3]=vals[3]; - _value[4]=vals[4]; -} - -bool DecompositionInUnitBase::operator==(const DecompositionInUnitBase& other) const -{ - return _value[0]==other._value[0] && _value[1]==other._value[1] && _value[2]==other._value[2] && _value[3]==other._value[3] && _value[4]==other._value[4]; -} - -void DecompositionInUnitBase::getTranslationParams(const DecompositionInUnitBase& other, double& mul, double& add) const -{ - if((*this)==other) - { - mul=_mult_fact_to_base/other._mult_fact_to_base; - add=_add_to_base/other._mult_fact_to_base-other._add_to_base; - } - else - { - mul=std::numeric_limits::max(); - add=std::numeric_limits::max(); - } -} - -bool DecompositionInUnitBase::isEqual(short mass, short lgth, short time, short intensity, short temp, double add, double mult) -{ - bool ret1=mass==_value[0]; - bool ret2=lgth==_value[1]; - bool ret3=time==_value[2]; - bool ret4=intensity==_value[3]; - bool ret5=temp==_value[4]; - bool ret6=areDoubleEquals(add,_add_to_base); - bool ret7=areDoubleEquals(mult,_mult_fact_to_base); - return ret1 && ret2 && ret3 && ret4 && ret5 && ret6 && ret7; -} - -void DecompositionInUnitBase::negate() -{ - _mult_fact_to_base=-_mult_fact_to_base; -} - -bool DecompositionInUnitBase::isAdimensional() const -{ - return _value[0]==0 && _value[1]==0 && _value[2]==0 && _value[3]==0 && _value[4]==0; -} - -bool DecompositionInUnitBase::isUnitary() const -{ - return areDoubleEquals(_add_to_base,0.) && areDoubleEquals(_mult_fact_to_base,1.); -} - -void DecompositionInUnitBase::tryToConvertInUnit(double val) -{ - int valI=(int)val; - if((val-(double)valI)!=0.) - { - std::ostringstream os; - os << "Double value " << val << " can't be considered as integer. Not admitable for units !"; - throw INTERP_KERNEL::Exception(os.str().c_str()); - } - _value[0]=0; - _value[1]=0; - _value[2]=0; - _value[3]=0; - _value[4]=0; - _add_to_base=0; - _mult_fact_to_base=valI; -} - -DecompositionInUnitBase &DecompositionInUnitBase::operator*(const DecompositionInUnitBase& other) -{ - _value[0]+=other._value[0]; _value[1]+=other._value[1]; _value[2]+=other._value[2]; _value[3]+=other._value[3]; _value[4]+=other._value[4]; - _mult_fact_to_base*=other._mult_fact_to_base; - _add_to_base=0.; - return *this; -} - -DecompositionInUnitBase &DecompositionInUnitBase::operator/(const DecompositionInUnitBase& other) -{ - _value[0]-=other._value[0]; _value[1]-=other._value[1]; _value[2]-=other._value[2]; _value[3]-=other._value[3]; _value[4]-=other._value[4]; - _mult_fact_to_base/=other._mult_fact_to_base; - _add_to_base=0.; - return *this; -} - -DecompositionInUnitBase &DecompositionInUnitBase::operator^(const DecompositionInUnitBase& other) -{ - if(!other.isAdimensional()) - throw INTERP_KERNEL::Exception("Trying to execute operator ^ with a second member not adimensionnal"); - int exp=couldItBeConsideredAsInt(other._mult_fact_to_base); - _value[0]*=exp; _value[1]*=exp; _value[2]*=exp; _value[3]*=exp; _value[4]*=exp; - _mult_fact_to_base=powInt(_mult_fact_to_base,exp); - _add_to_base=0.; - return *this; -} - -void DecompositionInUnitBase::dealWithAddFactor(const DecompositionInUnitBase& other) -{ - if(!areDoubleEquals(_add_to_base,0.)) - if(other.isAdimensional()) - if(areDoubleEquals(other._mult_fact_to_base,1.)) - return ; - if(!other.areDoubleEquals(_add_to_base,0.)) - if(isAdimensional()) - if(areDoubleEquals(_mult_fact_to_base,1.)) - return ; - _add_to_base=0.; -} - -double DecompositionInUnitBase::powInt(double val, int exp) -{ - double work=1.; - if(exp==0) - return 1.; - if(exp>0) - for(int i=0;i::max(); -} - -std::string Unit::getCoarseRepr() const -{ - return _coarse_repr; -} diff --git a/src/INTERP_KERNEL/ExprEval/InterpKernelUnit.hxx b/src/INTERP_KERNEL/ExprEval/InterpKernelUnit.hxx deleted file mode 100644 index 4af8759b5..000000000 --- a/src/INTERP_KERNEL/ExprEval/InterpKernelUnit.hxx +++ /dev/null @@ -1,117 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 -// 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 __INTERPKERNELUNIT_HXX__ -#define __INTERPKERNELUNIT_HXX__ - -#include "INTERPKERNELDefines.hxx" -#include "InterpKernelException.hxx" - -#include -#include - -namespace INTERP_KERNEL -{ - class UnitDataBase - { - public: - INTERPKERNEL_EXPORT UnitDataBase(); - INTERPKERNEL_EXPORT const short *getInfoForUnit(const std::string& unit, double& addFact, double& mFact) const; - INTERPKERNEL_EXPORT static UnitDataBase _uniqueMapForExpr; - INTERPKERNEL_EXPORT static const int SIZE_OF_UNIT_BASE=5; - private: - std::map _prefix_pow_10; - std::map _units_semantic; - std::map _units_mul; - std::map _units_add; - private: - static const int NB_OF_PREF_POW10=22; - static const char *PREF_POW10[NB_OF_PREF_POW10]; - static const double POW10[NB_OF_PREF_POW10]; - static const int NB_OF_UNITS_RECOGN=29; - static const char *UNITS_RECOGN[NB_OF_UNITS_RECOGN]; - static const short PROJ_IN_BASE[NB_OF_UNITS_RECOGN][SIZE_OF_UNIT_BASE]; - static const double MUL_COEFF[NB_OF_UNITS_RECOGN]; - static const double ADD_COEFF[NB_OF_UNITS_RECOGN]; - }; - - class DecompositionInUnitBase - { - public: - INTERPKERNEL_EXPORT DecompositionInUnitBase(); - INTERPKERNEL_EXPORT void setInfo(const short *vals, double addFact, double mFact); - INTERPKERNEL_EXPORT short operator[](int i) const { return _value[i]; } - INTERPKERNEL_EXPORT bool operator==(const DecompositionInUnitBase& other) const; - INTERPKERNEL_EXPORT void getTranslationParams(const DecompositionInUnitBase& other, double& mul, double& add) const; - INTERPKERNEL_EXPORT bool isEqual(short mass, short lgth, short time, short intensity, short temp, - double add, double mult); - INTERPKERNEL_EXPORT bool isUnitary() const; - //! \b WARNING no test is done on the fact that unit is adimensionnal. - INTERPKERNEL_EXPORT void negate(); - INTERPKERNEL_EXPORT bool isAdimensional() const; - INTERPKERNEL_EXPORT void tryToConvertInUnit(double val); - INTERPKERNEL_EXPORT DecompositionInUnitBase &operator*(const DecompositionInUnitBase& other); - INTERPKERNEL_EXPORT DecompositionInUnitBase &operator/(const DecompositionInUnitBase& other); - INTERPKERNEL_EXPORT DecompositionInUnitBase &operator^(const DecompositionInUnitBase& other); - private: - void dealWithAddFactor(const DecompositionInUnitBase& other); - static int couldItBeConsideredAsInt(double val); - static bool areDoubleEquals(double a, double b); - static double powInt(double val, int exp); - private: - short _value[UnitDataBase::SIZE_OF_UNIT_BASE]; - double _add_to_base; - double _mult_fact_to_base; - }; - - /*! - * This class deals with units. - * This class has two main responsabilities : - * - interprete units by giving simply their representation in string type. - * - performing operations on these units. - * - * All the possible units are represented with a unique tuple with 5 elements - * representing the unique decomposition of a unit in the following base. - * - * dimension 0 stands for mass in g (\b NOT kg to simplify parsing). - * dimension 1 stands for length in m. - * dimension 2 stands for time in s. - * dimension 3 stands for elec intensity A. - * dimension 4 stands for temperature in K. - */ - class Unit - { - public: - INTERPKERNEL_EXPORT Unit(const char *reprC, bool tryToInterp=true); - INTERPKERNEL_EXPORT Unit(const char *reprFortran, int sizeOfRepr, bool tryToInterp=true); - INTERPKERNEL_EXPORT void tryToInterprate() const; - INTERPKERNEL_EXPORT bool isInterpretationOK() const; - INTERPKERNEL_EXPORT bool isCompatibleWith(const Unit& other) const; - INTERPKERNEL_EXPORT double convert(const Unit& target, double sourceVal) const; - INTERPKERNEL_EXPORT std::string getCoarseRepr() const; - private: - std::string _coarse_repr; - mutable bool _is_interpreted; - mutable bool _is_interpretation_ok; - mutable DecompositionInUnitBase _decomp_in_base; - }; -} - -#endif diff --git a/src/INTERP_KERNEL/ExprEval/InterpKernelValue.cxx b/src/INTERP_KERNEL/ExprEval/InterpKernelValue.cxx deleted file mode 100644 index 3006fc941..000000000 --- a/src/INTERP_KERNEL/ExprEval/InterpKernelValue.cxx +++ /dev/null @@ -1,641 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 -// 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 "InterpKernelValue.hxx" -#include "InterpKernelFunction.hxx" - -#include -#include -#include - -using namespace INTERP_KERNEL; - -ValueDouble::ValueDouble():_data(std::numeric_limits::max()) -{ -} - -Value *ValueDouble::newInstance() const -{ - return new ValueDouble; -} - -ValueDouble::ValueDouble(double val):_data(val) -{ -} - -void ValueDouble::setDouble(double val) -{ - _data=val; -} - -void ValueDouble::setVarname(int fastPos, const std::string& var) -{ - std::string msg("Error var : "); msg+=var; msg+=" not numeric : use another expression evaluator !"; - throw INTERP_KERNEL::Exception(msg.c_str()); -} - -void ValueDouble::positive() -{ -} - -void ValueDouble::negate() -{ - _data=-_data; -} - -void ValueDouble::sqrt() -{ - _data=std::sqrt(_data); -} - -void ValueDouble::cos() -{ - _data=std::cos(_data); -} - -void ValueDouble::sin() -{ - _data=std::sin(_data); -} - -void ValueDouble::tan() -{ - _data=std::tan(_data); -} - -void ValueDouble::acos() -{ - _data=std::acos(_data); -} - -void ValueDouble::asin() -{ - _data=std::asin(_data); -} - -void ValueDouble::atan() -{ - _data=std::atan(_data); -} - -void ValueDouble::cosh() -{ - _data=std::cosh(_data); -} - -void ValueDouble::sinh() -{ - _data=std::sinh(_data); -} - -void ValueDouble::tanh() -{ - _data=std::tanh(_data); -} - -void ValueDouble::abs() -{ - if(_data<0.) - _data=-_data; -} - -void ValueDouble::exp() -{ - _data=std::exp(_data); -} - -void ValueDouble::ln() -{ - _data=std::log(_data); -} - -void ValueDouble::log10() -{ - _data=std::log10(_data); -} - -Value *ValueDouble::plus(const Value *other) const -{ - const ValueDouble *valC=checkSameType(other); - return new ValueDouble(_data+valC->_data); -} - -Value *ValueDouble::minus(const Value *other) const -{ - const ValueDouble *valC=checkSameType(other); - return new ValueDouble(_data-valC->_data); -} - -Value *ValueDouble::mult(const Value *other) const -{ - const ValueDouble *valC=checkSameType(other); - return new ValueDouble(_data*valC->_data); -} - -Value *ValueDouble::div(const Value *other) const -{ - const ValueDouble *valC=checkSameType(other); - return new ValueDouble(_data/valC->_data); -} - -Value *ValueDouble::pow(const Value *other) const -{ - const ValueDouble *valC=checkSameType(other); - return new ValueDouble(std::pow(_data,valC->_data)); -} - -Value *ValueDouble::max(const Value *other) const -{ - const ValueDouble *valC=checkSameType(other); - return new ValueDouble(std::max(_data,valC->_data)); -} - -Value *ValueDouble::min(const Value *other) const -{ - const ValueDouble *valC=checkSameType(other); - return new ValueDouble(std::min(_data,valC->_data)); -} - -Value *ValueDouble::greaterThan(const Value *other) const -{ - const ValueDouble *valC=checkSameType(other); - return new ValueDouble(_data>valC->_data?std::numeric_limits::max():-std::numeric_limits::max()); -} - -Value *ValueDouble::lowerThan(const Value *other) const -{ - const ValueDouble *valC=checkSameType(other); - return new ValueDouble(_data_data?std::numeric_limits::max():-std::numeric_limits::max()); -} - -Value *ValueDouble::ifFunc(const Value *the, const Value *els) const -{ - const ValueDouble *theC=checkSameType(the); - const ValueDouble *elsC=checkSameType(els); - if(_data==std::numeric_limits::max()) - return new ValueDouble(theC->_data); - if(_data==-std::numeric_limits::max()) - return new ValueDouble(elsC->_data); - throw INTERP_KERNEL::Exception("ValueDouble::ifFunc : The fist element of ternary function if is not a binary op !"); -} - -const ValueDouble *ValueDouble::checkSameType(const Value *val) -{ - const ValueDouble *valC=dynamic_cast(val); - if(!valC) - throw INTERP_KERNEL::Exception("Trying to operate on non homogeneous Values (double with other type) !"); - return valC; -} - -ValueUnit::ValueUnit() -{ -} - -Value *ValueUnit::newInstance() const -{ - return new ValueUnit; -} - -ValueUnit::ValueUnit(const DecompositionInUnitBase& unit):_data(unit) -{ -} - -void ValueUnit::setDouble(double val) -{ - _data.tryToConvertInUnit(val); -} - -void ValueUnit::setVarname(int fastPos, const std::string& var) -{ - double add,mul; - const short *projInBase=UnitDataBase::_uniqueMapForExpr.getInfoForUnit(var,add,mul); - _data.setInfo(projInBase,add,mul); -} - -void ValueUnit::positive() -{ - unsupportedOp(PositiveFunction::REPR); -} - -void ValueUnit::negate() -{ - _data.negate(); -} - -void ValueUnit::sqrt() -{ - unsupportedOp(SqrtFunction::REPR); -} - -void ValueUnit::cos() -{ - unsupportedOp(CosFunction::REPR); -} - -void ValueUnit::sin() -{ - unsupportedOp(SinFunction::REPR); -} - -void ValueUnit::tan() -{ - unsupportedOp(TanFunction::REPR); -} - -void ValueUnit::acos() -{ - unsupportedOp(ACosFunction::REPR); -} - -void ValueUnit::asin() -{ - unsupportedOp(ASinFunction::REPR); -} - -void ValueUnit::atan() -{ - unsupportedOp(ATanFunction::REPR); -} - -void ValueUnit::cosh() -{ - unsupportedOp(CoshFunction::REPR); -} - -void ValueUnit::sinh() -{ - unsupportedOp(SinhFunction::REPR); -} - -void ValueUnit::tanh() -{ - unsupportedOp(TanhFunction::REPR); -} - -void ValueUnit::abs() -{ - unsupportedOp(AbsFunction::REPR); -} - -void ValueUnit::exp() -{ - unsupportedOp(ExpFunction::REPR); -} - -void ValueUnit::ln() -{ - unsupportedOp(LnFunction::REPR); -} - -void ValueUnit::log10() -{ - unsupportedOp(Log10Function::REPR); -} - -Value *ValueUnit::plus(const Value *other) const -{ - unsupportedOp(PlusFunction::REPR); - return 0; -} - -Value *ValueUnit::minus(const Value *other) const -{ - unsupportedOp(MinusFunction::REPR); - return 0; -} - -Value *ValueUnit::greaterThan(const Value *other) const -{ - unsupportedOp(GreaterThanFunction::REPR); - return 0; -} - -Value *ValueUnit::lowerThan(const Value *other) const -{ - unsupportedOp(LowerThanFunction::REPR); - return 0; -} - -Value *ValueUnit::ifFunc(const Value *the, const Value *els) const -{ - unsupportedOp(IfFunction::REPR); - return 0; -} - -Value *ValueUnit::mult(const Value *other) const -{ - const ValueUnit *valC=checkSameType(other); - DecompositionInUnitBase tmp=_data; - tmp*valC->getData(); - return new ValueUnit(tmp); -} - -Value *ValueUnit::div(const Value *other) const -{ - const ValueUnit *valC=checkSameType(other); - DecompositionInUnitBase tmp=_data; - tmp/valC->getData(); - return new ValueUnit(tmp); -} - -Value *ValueUnit::pow(const Value *other) const -{ - const ValueUnit *valC=checkSameType(other); - DecompositionInUnitBase tmp=_data; - tmp^valC->getData(); - return new ValueUnit(tmp); -} - -Value *ValueUnit::max(const Value *other) const -{ - unsupportedOp(MaxFunction::REPR); - return 0; -} - -Value *ValueUnit::min(const Value *other) const -{ - unsupportedOp(MinFunction::REPR); - return 0; -} - -const ValueUnit *ValueUnit::checkSameType(const Value *val) -{ - const ValueUnit *valC=dynamic_cast(val); - if(!valC) - throw INTERP_KERNEL::Exception("Trying to operate on non homogeneous Values (Units with other type) !"); - return valC; -} - -void ValueUnit::unsupportedOp(const char *type) -{ - const char msg[]="Unsupported operation for units :"; - std::string msgStr(msg); - msgStr+=type; - throw INTERP_KERNEL::Exception(msgStr.c_str()); -} - -ValueDoubleExpr::ValueDoubleExpr(int szDestData, const double *srcData):_sz_dest_data(szDestData),_dest_data(new double[_sz_dest_data]),_src_data(srcData) -{ -} - -ValueDoubleExpr::~ValueDoubleExpr() -{ - delete [] _dest_data; -} - -Value *ValueDoubleExpr::newInstance() const -{ - return new ValueDoubleExpr(_sz_dest_data,_src_data); -} - -void ValueDoubleExpr::setDouble(double val) -{ - std::fill(_dest_data,_dest_data+_sz_dest_data,val); -} - -void ValueDoubleExpr::setVarname(int fastPos, const std::string& var) -{ - if(fastPos==-2) - std::copy(_src_data,_src_data+_sz_dest_data,_dest_data); - else if(fastPos>-2) - std::fill(_dest_data,_dest_data+_sz_dest_data,_src_data[fastPos]); - else - { - std::fill(_dest_data,_dest_data+_sz_dest_data,0.); - _dest_data[-7-fastPos]=1.; - } -} - -void ValueDoubleExpr::positive() -{ -} - -void ValueDoubleExpr::negate() -{ - std::transform(_dest_data,_dest_data+_sz_dest_data,_dest_data,std::negate()); -} - -void ValueDoubleExpr::sqrt() -{ - double *it=std::find_if(_dest_data,_dest_data+_sz_dest_data,std::bind2nd(std::less(),0.)); - if(it!=_dest_data+_sz_dest_data) - throw INTERP_KERNEL::Exception("Trying to apply sqrt on < 0. value !"); - std::transform(_dest_data,_dest_data+_sz_dest_data,_dest_data,std::ptr_fun(std::sqrt)); -} - -void ValueDoubleExpr::cos() -{ - std::transform(_dest_data,_dest_data+_sz_dest_data,_dest_data,std::ptr_fun(std::cos)); -} - -void ValueDoubleExpr::sin() -{ - std::transform(_dest_data,_dest_data+_sz_dest_data,_dest_data,std::ptr_fun(std::sin)); -} - -void ValueDoubleExpr::tan() -{ - std::transform(_dest_data,_dest_data+_sz_dest_data,_dest_data,std::ptr_fun(std::tan)); -} - -void ValueDoubleExpr::acos() -{ - double *it=std::find_if(_dest_data,_dest_data+_sz_dest_data,std::bind2nd(std::less(),-1.)); - if(it!=_dest_data+_sz_dest_data) - throw INTERP_KERNEL::Exception("Trying to apply acos on < 1. value !"); - it=std::find_if(_dest_data,_dest_data+_sz_dest_data,std::bind2nd(std::greater(),1.)); - if(it!=_dest_data+_sz_dest_data) - throw INTERP_KERNEL::Exception("Trying to apply acos on > 1. value !"); - std::transform(_dest_data,_dest_data+_sz_dest_data,_dest_data,std::ptr_fun(std::acos)); -} - -void ValueDoubleExpr::asin() -{ - double *it=std::find_if(_dest_data,_dest_data+_sz_dest_data,std::bind2nd(std::less(),-1.)); - if(it!=_dest_data+_sz_dest_data) - throw INTERP_KERNEL::Exception("Trying to apply asin on < 1. value !"); - it=std::find_if(_dest_data,_dest_data+_sz_dest_data,std::bind2nd(std::greater(),1.)); - if(it!=_dest_data+_sz_dest_data) - throw INTERP_KERNEL::Exception("Trying to apply asin on > 1. value !"); - std::transform(_dest_data,_dest_data+_sz_dest_data,_dest_data,std::ptr_fun(std::asin)); -} - -void ValueDoubleExpr::atan() -{ - std::transform(_dest_data,_dest_data+_sz_dest_data,_dest_data,std::ptr_fun(std::atan)); -} - -void ValueDoubleExpr::cosh() -{ - std::transform(_dest_data,_dest_data+_sz_dest_data,_dest_data,std::ptr_fun(std::cosh)); -} - -void ValueDoubleExpr::sinh() -{ - std::transform(_dest_data,_dest_data+_sz_dest_data,_dest_data,std::ptr_fun(std::sinh)); -} - -void ValueDoubleExpr::tanh() -{ - std::transform(_dest_data,_dest_data+_sz_dest_data,_dest_data,std::ptr_fun(std::tanh)); -} - -void ValueDoubleExpr::abs() -{ - std::transform(_dest_data,_dest_data+_sz_dest_data,_dest_data,std::ptr_fun(fabs)); -} - -void ValueDoubleExpr::exp() -{ - std::transform(_dest_data,_dest_data+_sz_dest_data,_dest_data,std::ptr_fun(std::exp)); -} - -void ValueDoubleExpr::ln() -{ - double *it=std::find_if(_dest_data,_dest_data+_sz_dest_data,std::bind2nd(std::less_equal(),0.)); - if(it!=_dest_data+_sz_dest_data) - throw INTERP_KERNEL::Exception("Trying to apply neperian/natural log on <= 0. value !"); - std::transform(_dest_data,_dest_data+_sz_dest_data,_dest_data,std::ptr_fun(std::log)); -} - -void ValueDoubleExpr::log10() -{ - double *it=std::find_if(_dest_data,_dest_data+_sz_dest_data,std::bind2nd(std::less_equal(),0.)); - if(it!=_dest_data+_sz_dest_data) - throw INTERP_KERNEL::Exception("Trying to apply log10 on <= 0. value !"); - std::transform(_dest_data,_dest_data+_sz_dest_data,_dest_data,std::ptr_fun(std::log10)); -} - -Value *ValueDoubleExpr::plus(const Value *other) const -{ - const ValueDoubleExpr *otherC=static_cast(other); - ValueDoubleExpr *ret=new ValueDoubleExpr(_sz_dest_data,_src_data); - std::transform(_dest_data,_dest_data+_sz_dest_data,otherC->getData(),ret->getData(),std::plus()); - return ret; -} - -Value *ValueDoubleExpr::minus(const Value *other) const -{ - const ValueDoubleExpr *otherC=static_cast(other); - ValueDoubleExpr *ret=new ValueDoubleExpr(_sz_dest_data,_src_data); - std::transform(_dest_data,_dest_data+_sz_dest_data,otherC->getData(),ret->getData(),std::minus()); - return ret; -} - -Value *ValueDoubleExpr::mult(const Value *other) const -{ - const ValueDoubleExpr *otherC=static_cast(other); - ValueDoubleExpr *ret=new ValueDoubleExpr(_sz_dest_data,_src_data); - std::transform(_dest_data,_dest_data+_sz_dest_data,otherC->getData(),ret->getData(),std::multiplies()); - return ret; -} - -Value *ValueDoubleExpr::div(const Value *other) const -{ - const ValueDoubleExpr *otherC=static_cast(other); - double *it=std::find(otherC->getData(),otherC->getData()+_sz_dest_data,0.); - if(it!=otherC->getData()+_sz_dest_data) - throw INTERP_KERNEL::Exception("Trying to operate division by 0. !"); - ValueDoubleExpr *ret=new ValueDoubleExpr(_sz_dest_data,_src_data); - std::transform(_dest_data,_dest_data+_sz_dest_data,otherC->getData(),ret->getData(),std::divides()); - return ret; -} - -Value *ValueDoubleExpr::pow(const Value *other) const -{ - const ValueDoubleExpr *otherC=static_cast(other); - double p=otherC->getData()[0]; - double *it=std::find_if(_dest_data,_dest_data+_sz_dest_data,std::bind2nd(std::less(),0.)); - if(it!=_dest_data+_sz_dest_data) - throw INTERP_KERNEL::Exception("Trying to operate pow(a,b) with a<0. !"); - ValueDoubleExpr *ret=new ValueDoubleExpr(_sz_dest_data,_src_data); - std::transform(_dest_data,_dest_data+_sz_dest_data,ret->getData(),std::bind2nd(std::ptr_fun(std::pow),p)); - return ret; -} - -Value *ValueDoubleExpr::max(const Value *other) const -{ - const ValueDoubleExpr *otherC=static_cast(other); - ValueDoubleExpr *ret=new ValueDoubleExpr(_sz_dest_data,_src_data); - std::transform(_dest_data,_dest_data+_sz_dest_data,otherC->getData(),ret->getData(),std::ptr_fun(std::max)); - return ret; -} - -Value *ValueDoubleExpr::min(const Value *other) const -{ - const ValueDoubleExpr *otherC=static_cast(other); - ValueDoubleExpr *ret=new ValueDoubleExpr(_sz_dest_data,_src_data); - std::transform(_dest_data,_dest_data+_sz_dest_data,otherC->getData(),ret->getData(),std::ptr_fun(std::min)); - return ret; -} - -Value *ValueDoubleExpr::greaterThan(const Value *other) const -{ - const ValueDoubleExpr *otherC=static_cast(other); - ValueDoubleExpr *ret=new ValueDoubleExpr(_sz_dest_data,_src_data); - for(int i=0;i<_sz_dest_data;i++) - if(_dest_data[i]<=otherC->getData()[i]) - { - std::fill(ret->getData(),ret->getData()+_sz_dest_data,-std::numeric_limits::max()); - return ret; - } - std::fill(ret->getData(),ret->getData()+_sz_dest_data,std::numeric_limits::max()); - return ret; -} - -Value *ValueDoubleExpr::lowerThan(const Value *other) const -{ - const ValueDoubleExpr *otherC=static_cast(other); - ValueDoubleExpr *ret=new ValueDoubleExpr(_sz_dest_data,_src_data); - for(int i=0;i<_sz_dest_data;i++) - if(_dest_data[i]>=otherC->getData()[i]) - { - std::fill(ret->getData(),ret->getData()+_sz_dest_data,-std::numeric_limits::max()); - return ret; - } - std::fill(ret->getData(),ret->getData()+_sz_dest_data,std::numeric_limits::max()); - return ret; -} - -Value *ValueDoubleExpr::ifFunc(const Value *the, const Value *els) const -{ - const ValueDoubleExpr *theC=static_cast(the); - const ValueDoubleExpr *elsC=static_cast(els); - ValueDoubleExpr *ret=new ValueDoubleExpr(_sz_dest_data,_src_data); - bool okmax=true; - bool okmin=true; - for(int i=0;i<_sz_dest_data && (okmax || okmin);i++) - { - okmax=_dest_data[i]==std::numeric_limits::max(); - okmin=_dest_data[i]==-std::numeric_limits::max(); - } - if(okmax || okmin) - { - if(okmax) - std::copy(theC->getData(),theC->getData()+_sz_dest_data,ret->getData()); - else - std::copy(elsC->getData(),elsC->getData()+_sz_dest_data,ret->getData()); - return ret; - } - else - { - throw INTERP_KERNEL::Exception("ValueDoubleExpr::ifFunc : first parameter of ternary func is NOT a consequence of a boolean op !"); - } -} diff --git a/src/INTERP_KERNEL/ExprEval/InterpKernelValue.hxx b/src/INTERP_KERNEL/ExprEval/InterpKernelValue.hxx deleted file mode 100644 index ecc6d1118..000000000 --- a/src/INTERP_KERNEL/ExprEval/InterpKernelValue.hxx +++ /dev/null @@ -1,202 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 -// 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 __INTERPKERNELVALUE_HXX__ -#define __INTERPKERNELVALUE_HXX__ - -#include "INTERPKERNELDefines.hxx" -#include "InterpKernelException.hxx" -#include "InterpKernelUnit.hxx" - -namespace INTERP_KERNEL -{ - class INTERPKERNEL_EXPORT Value - { - public: - virtual Value *newInstance() const = 0; - virtual ~Value() { } - virtual void setDouble(double val) = 0; - virtual void setVarname(int fastPos, const std::string& var) = 0; - //unary - virtual void positive() = 0; - virtual void negate() = 0; - virtual void sqrt() = 0; - virtual void cos() = 0; - virtual void sin() = 0; - virtual void tan() = 0; - virtual void acos() = 0; - virtual void asin() = 0; - virtual void atan() = 0; - virtual void cosh() = 0; - virtual void sinh() = 0; - virtual void tanh() = 0; - virtual void abs() = 0; - virtual void exp() = 0; - virtual void ln() = 0; - virtual void log10() = 0; - //binary - virtual Value *plus(const Value *other) const = 0; - virtual Value *minus(const Value *other) const = 0; - virtual Value *mult(const Value *other) const = 0; - virtual Value *div(const Value *other) const = 0; - virtual Value *pow(const Value *other) const = 0; - virtual Value *max(const Value *other) const = 0; - virtual Value *min(const Value *other) const = 0; - virtual Value *greaterThan(const Value *other) const = 0; - virtual Value *lowerThan(const Value *other) const = 0; - //ternary - virtual Value *ifFunc(const Value *the, const Value *els) const = 0; - }; - - class INTERPKERNEL_EXPORT ValueDouble : public Value - { - public: - ValueDouble(); - Value *newInstance() const; - void setDouble(double val); - void setVarname(int fastPos, const std::string& var); - // - double getData() const { return _data; } - void positive(); - void negate(); - void sqrt(); - void cos(); - void sin(); - void tan(); - void acos(); - void asin(); - void atan(); - void cosh(); - void sinh(); - void tanh(); - void abs(); - void exp(); - void ln(); - void log10(); - // - Value *plus(const Value *other) const; - Value *minus(const Value *other) const; - Value *mult(const Value *other) const; - Value *div(const Value *other) const; - Value *pow(const Value *other) const; - Value *max(const Value *other) const; - Value *min(const Value *other) const; - Value *greaterThan(const Value *other) const; - Value *lowerThan(const Value *other) const; - // - Value *ifFunc(const Value *the, const Value *els) const; - private: - ValueDouble(double val); - static const ValueDouble *checkSameType(const Value *val); - private: - double _data; - }; - - class ValueUnit : public Value - { - public: - INTERPKERNEL_EXPORT ValueUnit(); - INTERPKERNEL_EXPORT Value *newInstance() const; - INTERPKERNEL_EXPORT void setDouble(double val); - INTERPKERNEL_EXPORT void setVarname(int fastPos, const std::string& var); - // - INTERPKERNEL_EXPORT DecompositionInUnitBase getData() const { return _data; } - INTERPKERNEL_EXPORT void positive(); - INTERPKERNEL_EXPORT void negate(); - INTERPKERNEL_EXPORT void sqrt(); - INTERPKERNEL_EXPORT void cos(); - INTERPKERNEL_EXPORT void sin(); - INTERPKERNEL_EXPORT void tan(); - INTERPKERNEL_EXPORT void acos(); - INTERPKERNEL_EXPORT void asin(); - INTERPKERNEL_EXPORT void atan(); - INTERPKERNEL_EXPORT void cosh(); - INTERPKERNEL_EXPORT void sinh(); - INTERPKERNEL_EXPORT void tanh(); - INTERPKERNEL_EXPORT void abs(); - INTERPKERNEL_EXPORT void exp(); - INTERPKERNEL_EXPORT void ln(); - INTERPKERNEL_EXPORT void log10(); - // - INTERPKERNEL_EXPORT Value *plus(const Value *other) const; - INTERPKERNEL_EXPORT Value *minus(const Value *other) const; - INTERPKERNEL_EXPORT Value *mult(const Value *other) const; - INTERPKERNEL_EXPORT Value *div(const Value *other) const; - INTERPKERNEL_EXPORT Value *pow(const Value *other) const; - INTERPKERNEL_EXPORT Value *max(const Value *other) const; - INTERPKERNEL_EXPORT Value *min(const Value *other) const; - INTERPKERNEL_EXPORT Value *greaterThan(const Value *other) const; - INTERPKERNEL_EXPORT Value *lowerThan(const Value *other) const; - // - INTERPKERNEL_EXPORT Value *ifFunc(const Value *the, const Value *els) const; - private: - ValueUnit(const DecompositionInUnitBase& unit); - static void unsupportedOp(const char *type); - static const ValueUnit *checkSameType(const Value *val); - private: - DecompositionInUnitBase _data; - }; - - class INTERPKERNEL_EXPORT ValueDoubleExpr : public Value - { - public: - ValueDoubleExpr(int szDestData, const double *srcData); - ~ValueDoubleExpr(); - double *getData() const { return _dest_data; } - Value *newInstance() const; - void setDouble(double val); - void setVarname(int fastPos, const std::string& var); - // - void positive(); - void negate(); - void sqrt(); - void cos(); - void sin(); - void tan(); - void acos(); - void asin(); - void atan(); - void cosh(); - void sinh(); - void tanh(); - void abs(); - void exp(); - void ln(); - void log10(); - // - Value *plus(const Value *other) const; - Value *minus(const Value *other) const; - Value *mult(const Value *other) const; - Value *div(const Value *other) const; - Value *pow(const Value *other) const; - Value *max(const Value *other) const; - Value *min(const Value *other) const; - Value *greaterThan(const Value *other) const; - Value *lowerThan(const Value *other) const; - // - Value *ifFunc(const Value *the, const Value *els) const; - private: - int _sz_dest_data; - double *_dest_data; - const double *_src_data; - }; -} - -#endif diff --git a/src/INTERP_KERNEL/GaussPoints/InterpKernelGaussCoords.cxx b/src/INTERP_KERNEL/GaussPoints/InterpKernelGaussCoords.cxx deleted file mode 100644 index 618e9e8b8..000000000 --- a/src/INTERP_KERNEL/GaussPoints/InterpKernelGaussCoords.cxx +++ /dev/null @@ -1,2823 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 -// 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 -// - -//Local includes -#include "InterpKernelGaussCoords.hxx" -#include "CellModel.hxx" - -//STL includes -#include -#include -#include - -using namespace INTERP_KERNEL; - -//Define common part of the code in the MACRO -//--------------------------------------------------------------- -#define LOCAL_COORD_MACRO_BEGIN \ - _my_local_reference_coord.resize( _my_local_ref_dim*_my_local_nb_ref ); \ - for( int refId = 0; refId < _my_local_nb_ref; refId++ ) \ - { \ - double* coords = &_my_local_reference_coord[ refId*_my_local_ref_dim ]; \ - switch(refId) \ - { - -//--------------------------------------------------------------- -#define LOCAL_COORD_MACRO_END \ - } \ -} - -//--------------------------------------------------------------- -#define SHAPE_FUN_MACRO_BEGIN \ - for( int gaussId = 0 ; gaussId < _my_nb_gauss ; gaussId++ ) \ - { \ - double* funValue = &_my_function_value[ gaussId * _my_nb_ref ]; \ - const double* gc = &_my_gauss_coord[ gaussId * getGaussCoordDim() ]; - -//--------------------------------------------------------------- -#define SHAPE_FUN_MACRO_END \ - } - -#define CHECK_MACRO \ - if( ! aSatify ) \ - { \ - std::ostringstream stream; \ - stream << "Error in the gauss localization for the cell with type "; \ - stream << cellModel.getRepr(); \ - stream << " !!!"; \ - throw INTERP_KERNEL::Exception(stream.str().c_str()); \ - } - - -//--------------------------------------------------------------- -static bool IsEqual(double theLeft, double theRight) -{ - static double EPS = 1.0E-3; - if(fabs(theLeft) + fabs(theRight) > EPS) - return fabs(theLeft-theRight)/(fabs(theLeft)+fabs(theRight)) < EPS; - return true; -} - - -//////////////////////////////////////////////////////////////////////////////////////////////// -// GAUSS INFO CLASS // -//////////////////////////////////////////////////////////////////////////////////////////////// - -/*! - * Constructor of the GaussInfo - */ -GaussInfo::GaussInfo( NormalizedCellType theGeometry, - const DataVector& theGaussCoord, - int theNbGauss, - const DataVector& theReferenceCoord, - int theNbRef ) : - _my_geometry(theGeometry), - _my_nb_gauss(theNbGauss), - _my_gauss_coord(theGaussCoord), - _my_nb_ref(theNbRef), - _my_reference_coord(theReferenceCoord) -{ - - //Allocate shape function values - _my_function_value.resize( _my_nb_gauss * _my_nb_ref ); -} - -/*! - * Destructor - */ -GaussInfo::~GaussInfo() -{ -} - -/*! - * Return dimension of the gauss coordinates - */ -int GaussInfo::getGaussCoordDim() const -{ - if( _my_nb_gauss ) - { - return _my_gauss_coord.size()/_my_nb_gauss; - } - else - { - return 0; - } -} - -/*! - * Return dimension of the reference coordinates - */ -int GaussInfo::getReferenceCoordDim() const -{ - if( _my_nb_ref ) - { - return _my_reference_coord.size()/_my_nb_ref; - } - else - { - return 0; - } -} - -/*! - * Return type of the cell. - */ -NormalizedCellType GaussInfo::getCellType() const -{ - return _my_geometry; -} - -/*! - * Return Nb of the gauss points. - */ -int GaussInfo::getNbGauss() const -{ - return _my_nb_gauss; -} - -/*! - * Return Nb of the reference coordinates. - */ -int GaussInfo::getNbRef() const -{ - return _my_nb_ref; -} - -/*! - * Check coordinates - */ -bool GaussInfo::isSatisfy() -{ - - bool anIsSatisfy = ((_my_local_nb_ref == _my_nb_ref) && (_my_local_ref_dim == getReferenceCoordDim())); - //Check coordinates - if(anIsSatisfy) - { - for( int refId = 0; refId < _my_local_nb_ref; refId++ ) - { - double* refCoord = &_my_reference_coord[ refId*_my_local_ref_dim ]; - double* localRefCoord = &_my_local_reference_coord[ refId*_my_local_ref_dim ]; - bool anIsEqual = false; - for( int dimId = 0; dimId < _my_local_ref_dim; dimId++ ) - { - anIsEqual = IsEqual( localRefCoord[dimId], refCoord[dimId]); - if(!anIsEqual ) - { - return false; - } - } - } - } - return anIsSatisfy; -} - -std::vector GaussInfo::NormalizeCoordinatesIfNecessary(NormalizedCellType ct, int inputDim, const std::vector& inputArray) -{ - std::size_t sz(inputArray.size()),dim((std::size_t)inputDim); - if(dim==0) - throw INTERP_KERNEL::Exception("GaussInfo::NormalizeCoordinatesIfNecessary : invalid dimension ! Must be !=0 !"); - if(sz%dim!=0) - throw INTERP_KERNEL::Exception("GaussInfo::NormalizeCoordinatesIfNecessary : invalid input array ! Inconsistent with the given dimension !"); - const CellModel& cm(CellModel::GetCellModel(ct)); - std::size_t baseDim((std::size_t)cm.getDimension()); - if(baseDim==dim) - return inputArray; - std::size_t nbOfItems(sz/dim); - std::vector ret(nbOfItems*baseDim); - if(baseDim>dim) - { - for(std::size_t i=0;igetCellType() == theGeometry ) - { - break; - } - } - - DataVector aGaussCoord; - for(int i = 0 ; i < theNbGauss*coordDim; i++ ) - aGaussCoord.push_back(theGaussCoord[i]); - - DataVector aReferenceCoord; - for(int i = 0 ; i < theNbRef*coordDim; i++ ) - aReferenceCoord.push_back(theReferenceCoord[i]); - - - GaussInfo* info = new GaussInfo( theGeometry, aGaussCoord, theNbGauss, aReferenceCoord, theNbRef); - info->initLocalInfo(); - - //If info with cell type doesn't exist add it - if( it == _my_gauss_info.end() ) - { - _my_gauss_info.push_back(info); - - // If information exists, update it - } - else - { - int index = std::distance(_my_gauss_info.begin(),it); - delete (*it); - _my_gauss_info[index] = info; - } -} - - -/*! - * Calculate gauss points coordinates - */ -double* GaussCoords::calculateCoords( NormalizedCellType theGeometry, - const double *theNodeCoords, - const int theSpaceDim, - const int *theIndex) -{ - const GaussInfo *info = getInfoGivenCellType(theGeometry); - int nbCoords = theSpaceDim * info->getNbGauss(); - double *aCoords = new double[nbCoords]; - calculateCoordsAlg(info,theNodeCoords,theSpaceDim,theIndex,aCoords); - return aCoords; -} - - -void GaussCoords::calculateCoords( NormalizedCellType theGeometry, const double *theNodeCoords, const int theSpaceDim, const int *theIndex, double *result) -{ - const GaussInfo *info = getInfoGivenCellType(theGeometry); - calculateCoordsAlg(info,theNodeCoords,theSpaceDim,theIndex,result); -} - -void GaussCoords::calculateCoordsAlg(const GaussInfo *info, const double* theNodeCoords, const int theSpaceDim, const int *theIndex, double *result) -{ - int aConn = info->getNbRef(); - - int nbCoords = theSpaceDim * info->getNbGauss(); - std::fill(result,result+nbCoords,0.); - - for( int gaussId = 0; gaussId < info->getNbGauss(); gaussId++ ) - { - double *coord=result+gaussId*theSpaceDim; - const double *function=info->getFunctionValues(gaussId); - for ( int connId = 0; connId < aConn ; connId++ ) - { - const double* nodeCoord = theNodeCoords + (theIndex[connId]*theSpaceDim); - for( int dimId = 0; dimId < theSpaceDim; dimId++ ) - coord[dimId] += nodeCoord[dimId]*function[connId]; - } - } -} - -const GaussInfo *GaussCoords::getInfoGivenCellType(NormalizedCellType cellType) -{ - GaussInfoVector::const_iterator it = _my_gauss_info.begin(); - //Try to find gauss localization info - for( ; it != _my_gauss_info.end() ; it++ ) - if( (*it)->getCellType()==cellType) - return (*it); - throw INTERP_KERNEL::Exception("Can't find gauss localization information !"); -} diff --git a/src/INTERP_KERNEL/GaussPoints/InterpKernelGaussCoords.hxx b/src/INTERP_KERNEL/GaussPoints/InterpKernelGaussCoords.hxx deleted file mode 100644 index 12c706e82..000000000 --- a/src/INTERP_KERNEL/GaussPoints/InterpKernelGaussCoords.hxx +++ /dev/null @@ -1,189 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 -// 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 __INTERPKERNELGAUSSCOORDS_HXX__ -#define __INTERPKERNELGAUSSCOORDS_HXX__ - -#include "INTERPKERNELDefines.hxx" -#include "NormalizedUnstructuredMesh.hxx" -#include "InterpKernelException.hxx" - -#include - -namespace INTERP_KERNEL -{ - typedef std::vector DataVector; - typedef std::vector IndexVector; - - //Class to store Gauss Points information - class GaussInfo - { - public: - INTERPKERNEL_EXPORT GaussInfo( NormalizedCellType theGeometry, - const DataVector& theGaussCoord, - int theNbGauss, - const DataVector& theReferenceCoord, - int theNbRef - ); - INTERPKERNEL_EXPORT ~GaussInfo(); - - INTERPKERNEL_EXPORT NormalizedCellType getCellType() const; - - INTERPKERNEL_EXPORT int getGaussCoordDim() const; - INTERPKERNEL_EXPORT int getReferenceCoordDim() const; - - INTERPKERNEL_EXPORT int getNbGauss() const; - INTERPKERNEL_EXPORT int getNbRef() const; - - INTERPKERNEL_EXPORT const double* getFunctionValues( const int theGaussId ) const; - - INTERPKERNEL_EXPORT void initLocalInfo(); - - INTERPKERNEL_EXPORT static std::vector NormalizeCoordinatesIfNecessary(NormalizedCellType ct, int inputDim, const std::vector& inputArray); - - protected: - - bool isSatisfy(); - - void point1Init(); - - //1D - void seg2Init(); - void seg3Init(); - - //2D - void tria3aInit(); - void tria3bInit(); - void tria6aInit(); - void tria6bInit(); - void tria7aInit(); - - void quad4aInit(); - static void Quad4aInit(GaussInfo& obj) { obj.quad4aInit(); } - void quad4bInit(); - static void Quad4bInit(GaussInfo& obj) { obj.quad4bInit(); } - void quad4cInit(); - static void Quad4cInit(GaussInfo& obj) { obj.quad4cInit(); } - void quad4DegSeg2Init(); - static void Quad4DegSeg2Init(GaussInfo& obj) { obj.quad4DegSeg2Init(); } - void quad8aInit(); - void quad8bInit(); - void quad9aInit(); - - //3D - void tetra4aInit(); - void tetra4bInit(); - void tetra10aInit(); - void tetra10bInit(); - - void pyra5aInit(); - void pyra5bInit(); - void pyra13aInit(); - void pyra13bInit(); - - void penta6aInit(); - static void Penta6aInit(GaussInfo& obj) { obj.penta6aInit(); } - void penta6bInit(); - static void Penta6bInit(GaussInfo& obj) { obj.penta6bInit(); } - void penta6DegTria3aInit(); - static void Penta6DegTria3aInit(GaussInfo& obj) { obj.penta6DegTria3aInit(); } - void penta6DegTria3bInit(); - static void Penta6DegTria3bInit(GaussInfo& obj) { obj.penta6DegTria3bInit(); } - - void penta15aInit(); - static void Penta15aInit(GaussInfo& obj) { obj.penta15aInit(); } - void penta15bInit(); - static void Penta15bInit(GaussInfo& obj) { obj.penta15bInit(); } - - void hexa8aInit(); - static void Hexa8aInit(GaussInfo& obj) { obj.hexa8aInit(); } - void hexa8bInit(); - static void Hexa8bInit(GaussInfo& obj) { obj.hexa8bInit(); } - void hexa8DegQuad4aInit(); - static void Hexa8DegQuad4aInit(GaussInfo& obj) { obj.hexa8DegQuad4aInit(); } - void hexa8DegQuad4bInit(); - static void Hexa8DegQuad4bInit(GaussInfo& obj) { obj.hexa8DegQuad4bInit(); } - void hexa8DegQuad4cInit(); - static void Hexa8DegQuad4cInit(GaussInfo& obj) { obj.hexa8DegQuad4cInit(); } - void hexa20aInit(); - void hexa20bInit(); - void hexa27aInit(); - - private: - //INFORMATION from MEDMEM - NormalizedCellType _my_geometry; //Cell type - - int _my_nb_gauss; //Nb of the gauss points for element - DataVector _my_gauss_coord; //Gauss coordinates - - int _my_nb_ref; //Nb of the nodes for element: - //NORM_SEG2 - 2 - //NORM_SEG3 - 3 - //NORM_TRI3 - 3 - //............. - - DataVector _my_reference_coord; //Reference coordinates - - //LOCAL INFORMATION - DataVector _my_local_reference_coord; //Vector to store reference coordinates - int _my_local_ref_dim; //Dimension of the local reference coordinates: - // (x) - 1D case - // (x, y) - 2D case - // (x, y, z) - 3D case - int _my_local_nb_ref; //Nb of the local reference coordinates - - DataVector _my_function_value; //Shape Function values - }; - - - //Class for calculation of the coordinates of the gauss points - class GaussCoords - { - public: - - INTERPKERNEL_EXPORT GaussCoords(); - INTERPKERNEL_EXPORT ~GaussCoords(); - - INTERPKERNEL_EXPORT void addGaussInfo( NormalizedCellType theGeometry, - int coordDim, - const double* theGaussCoord, - int theNbGauss, - const double* theReferenceCoord, - int theNbRef); - - INTERPKERNEL_EXPORT double* calculateCoords( NormalizedCellType theGeometry, - const double* theNodeCoords, - const int theSpaceDim, - const int* theIndex); - - INTERPKERNEL_EXPORT void calculateCoords( NormalizedCellType theGeometry, - const double* theNodeCoords, - const int theSpaceDim, - const int* theIndex, - double *result); - private: - const GaussInfo *getInfoGivenCellType(NormalizedCellType cellType); - void calculateCoordsAlg(const GaussInfo *info, const double* theNodeCoords, const int theSpaceDim, const int *theIndex, - double *result); - private: - typedef std::vector GaussInfoVector; - GaussInfoVector _my_gauss_info; - }; -} -#endif //INTERPKERNELGAUSSCOORDS diff --git a/src/INTERP_KERNEL/GenMathFormulae.hxx b/src/INTERP_KERNEL/GenMathFormulae.hxx deleted file mode 100644 index a53aacfca..000000000 --- a/src/INTERP_KERNEL/GenMathFormulae.hxx +++ /dev/null @@ -1,96 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 -// 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 __GENMATHFORMULAE_HXX__ -#define __GENMATHFORMULAE_HXX__ - -#include "InterpKernelException.hxx" - -#include - -namespace INTERP_KERNEL -{ - /*! - * This method computes eigenvalues of a 3x3 symetric matrix stored with 6 values in 'matrix'. The convension chosen for 'matrix' is described here: - * matrix[0]=m_xx, matrix[1]=m_yy, matrix[2]=m_zz, - * matrix[3]=m_xy, matrix[4]=m_yz, matrix[5]=m_xz - * This method returns the 3 eigenvalues in 'eigenVals'. - */ - void computeEigenValues6(const double *matrix, double *eigenVals) - { - double tr=(matrix[0]+matrix[1]+matrix[2])/3.; - double K[6]={matrix[0]-tr,matrix[1]-tr,matrix[2]-tr,matrix[3],matrix[4],matrix[5]}; - double q=(K[0]*K[1]*K[2]+2.*K[4]*K[5]*K[3]-K[0]*K[4]*K[4]-K[2]*K[3]*K[3]-K[1]*K[5]*K[5])/2.; - double p=K[0]*K[0]+K[1]*K[1]+K[2]*K[2]+2*(K[3]*K[3]+K[4]*K[4]+K[5]*K[5]); - p/=6.; - double sqp=sqrt(p); - double tmp=p*sqp; - double phi; - if(fabs(q)<=fabs(tmp)) - phi=1./3.*acos(q/tmp); - else - phi=0.; - if(phi<0.) - phi+=M_PI/3.; - eigenVals[0]=tr+2.*sqp*cos(phi); - eigenVals[1]=tr-sqp*(cos(phi)+sqrt(3.)*sin(phi)); - eigenVals[2]=tr-sqp*(cos(phi)-sqrt(3.)*sin(phi)); - } - - /*! - * This method computes one eigenvector of a 3x3 symetric matrix stored with 6 values in 'matrix'. The convension chosen for 'matrix' is described here: - * matrix[0]=m_xx, matrix[1]=m_yy, matrix[2]=m_zz, - * matrix[3]=m_xy, matrix[4]=m_yz, matrix[5]=m_xz - * This method returns the eigenvector of the corresponding eigenvalue in 'eigenVal'. The returned eigenValue is normalized. - */ - void computeEigenVectorForEigenValue6(const double *matrix, double eigenVal, double eps, double *eigenVector) - { - //if(fabs(eigenVal)>eps) - { - const double m9[9]={matrix[0]-eigenVal,matrix[3],matrix[5],matrix[3],matrix[1]-eigenVal,matrix[4],matrix[5],matrix[4],matrix[2]-eigenVal}; - for(int i=0;i<3;i++) - { - double w[9]={m9[0+3*i],m9[1+3*i],m9[2+3*i],m9[0+(3*(i+1))%6],m9[1+(3*(i+1))%6],m9[2+(3*(i+1))%6],1.,1.,1.}; - double det=w[0]*w[4]*w[8]+w[1]*w[5]*w[6]+w[2]*w[3]*w[7]-w[0]*w[5]*w[7]-w[1]*w[3]*w[8]-w[2]*w[4]*w[6]; - if(fabs(det)>eps) - { - eigenVector[0]=(w[1]*w[5]-w[4]*w[2])/det; - eigenVector[1]=(w[2]*w[3]-w[0]*w[5])/det; - eigenVector[2]=(w[0]*w[4]-w[1]*w[3])/det; - double norm=sqrt(eigenVector[0]*eigenVector[0]+eigenVector[1]*eigenVector[1]+eigenVector[2]*eigenVector[2]); - eigenVector[0]/=norm; - eigenVector[1]/=norm; - eigenVector[2]/=norm; - return; - } - } - } - //else - { - eigenVector[0]=0.; - eigenVector[1]=0.; - eigenVector[2]=0.; - return; - } - //throw INTERP_KERNEL::Exception("computeEigenVector : Do not succed in finding eigen vector !"); - } -} - -#endif diff --git a/src/INTERP_KERNEL/Geometric2D/InterpKernelGeo2DAbstractEdge.cxx b/src/INTERP_KERNEL/Geometric2D/InterpKernelGeo2DAbstractEdge.cxx deleted file mode 100644 index af84365f3..000000000 --- a/src/INTERP_KERNEL/Geometric2D/InterpKernelGeo2DAbstractEdge.cxx +++ /dev/null @@ -1,118 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 -// 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 "InterpKernelGeo2DAbstractEdge.hxx" -#include "InterpKernelGeo2DComposedEdge.hxx" -#include "InterpKernelGeo2DElementaryEdge.hxx" - -using namespace INTERP_KERNEL; - -IteratorOnComposedEdge::IteratorOnComposedEdge():_list_handle(0) -{ -} - -IteratorOnComposedEdge::IteratorOnComposedEdge(ComposedEdge *compEdges):_list_handle(compEdges->getListBehind()) -{ - first(); -} - -void IteratorOnComposedEdge::operator=(const IteratorOnComposedEdge& other) -{ - _deep_it=other._deep_it; - _list_handle=other._list_handle; -} - -void IteratorOnComposedEdge::last() -{ - _deep_it=_list_handle->end(); - _deep_it--; -} - -void IteratorOnComposedEdge::nextLoop() -{ - _deep_it++; - if(_deep_it==_list_handle->end()) - first(); -} - -void IteratorOnComposedEdge::previousLoop() -{ - if(_deep_it!=_list_handle->begin()) - _deep_it--; - else - last(); -} - -bool IteratorOnComposedEdge::goToNextInOn(bool direction, int& i, int nbMax) -{ - TypeOfEdgeLocInPolygon loc=current()->getLoc(); - if(direction) - { - while(loc==FULL_OUT_1 && igetLoc(); - } - if(i==nbMax) - return false; - return true; - } - else - { - while(loc==FULL_OUT_1 && igetLoc(); - } - if(i==nbMax) - return false; - while(loc!=FULL_OUT_1 && igetLoc(); - } - nextLoop(); i--; - return true; - } -} - -void IteratorOnComposedEdge::assignMySelfToAllElems(ComposedEdge *elems) -{ - std::list *myList=elems->getListBehind(); - for(std::list::iterator iter=myList->begin();iter!=myList->end();iter++) - (*iter)->getIterator()=(*this); -} - -void IteratorOnComposedEdge::insertElemEdges(ComposedEdge *elems, bool changeMySelf) -{ - std::list *myListToInsert=elems->getListBehind(); - std::list::iterator iter=myListToInsert->begin(); - *_deep_it=*iter; - _deep_it++; - iter++; - int sizeOfMyList=myListToInsert->size(); - _list_handle->insert(_deep_it,iter,myListToInsert->end()); - if(!changeMySelf) - { - for(int i=0;i -#include -#include - -namespace INTERP_KERNEL -{ - class Edge; - class Node; - class Bounds; - - class ComposedEdge; - class ElementaryEdge; - - /*! - * Asumption is done with this iterator that we iterate on a container containing more than one edge. - */ - class IteratorOnComposedEdge - { - friend class ComposedEdge; - friend class ElementaryEdge; - friend class QuadraticPolygon; - public: - INTERPKERNEL_EXPORT IteratorOnComposedEdge(); - INTERPKERNEL_EXPORT IteratorOnComposedEdge(ComposedEdge *compEdges); - INTERPKERNEL_EXPORT bool isValid() const { return _list_handle!=0; } - INTERPKERNEL_EXPORT void operator=(const IteratorOnComposedEdge& other); - INTERPKERNEL_EXPORT void first() { _deep_it=_list_handle->begin(); } - INTERPKERNEL_EXPORT void next() { _deep_it++; } - INTERPKERNEL_EXPORT void last(); - INTERPKERNEL_EXPORT void nextLoop(); - INTERPKERNEL_EXPORT void previousLoop(); - INTERPKERNEL_EXPORT bool finished() const { return _deep_it==_list_handle->end(); } - INTERPKERNEL_EXPORT bool goToNextInOn(bool direction, int& i, int nbMax); - INTERPKERNEL_EXPORT ElementaryEdge *current() { return *_deep_it; } - INTERPKERNEL_EXPORT void assignMySelfToAllElems(ComposedEdge *elems); - INTERPKERNEL_EXPORT void insertElemEdges(ComposedEdge *elems, bool changeMySelf); - private: - std::list::iterator _deep_it; - std::list* _list_handle; - }; -} - -#endif diff --git a/src/INTERP_KERNEL/Geometric2D/InterpKernelGeo2DBounds.cxx b/src/INTERP_KERNEL/Geometric2D/InterpKernelGeo2DBounds.cxx deleted file mode 100644 index 72e4dec32..000000000 --- a/src/INTERP_KERNEL/Geometric2D/InterpKernelGeo2DBounds.cxx +++ /dev/null @@ -1,212 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 -// 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 "InterpKernelGeo2DBounds.hxx" -#include "InterpKernelException.hxx" -#include "InterpKernelGeo2DEdgeArcCircle.hxx" -#include "InterpKernelGeo2DNode.hxx" - -using namespace INTERP_KERNEL; - -const double& Bounds::operator[](int i) const -{ - switch(i) - { - case 0: - return _x_min; - case 1: - return _x_max; - case 2: - return _y_min; - case 3: - return _y_max; - } - throw Exception("internal error occurs !"); -} - -double &Bounds::operator[](int i) -{ - switch(i) - { - case 0: - return _x_min; - case 1: - return _x_max; - case 2: - return _y_min; - case 3: - return _y_max; - } - throw Exception("internal error occurs !"); -} - -double Bounds::getDiagonal() const -{ - double a=_x_max-_x_min; - double b=_y_max-_y_min; - return sqrt(a*a+b*b); -} - -/*! - * See Node::applySimilarity to see signification of params. - */ -void Bounds::applySimilarity(double xBary, double yBary, double dimChar) -{ - _x_min=(_x_min-xBary)/dimChar; - _x_max=(_x_max-xBary)/dimChar; - _y_min=(_y_min-yBary)/dimChar; - _y_max=(_y_max-yBary)/dimChar; -} - -/*! - * See Node::unApplySimilarity to see signification of params. - */ -void Bounds::unApplySimilarity(double xBary, double yBary, double dimChar) -{ - _x_min=_x_min*dimChar+xBary; - _x_max=_x_max*dimChar+xBary; - _y_min=_y_min*dimChar+yBary; - _y_max=_y_max*dimChar+yBary; -} - -void Bounds::getBarycenter(double& xBary, double& yBary) const -{ - xBary=(_x_min+_x_max)/2.; - yBary=(_y_max+_y_min)/2.; -} - -void Bounds::prepareForAggregation() -{ - _x_min=1e200; _x_max=-1e200; _y_min=1e200; _y_max=-1e200; -} - -/*! - * Given an arc defined by 'center', 'radius' and 'intrcptArcDelta' in radian, returns (by outputs intrcptArcAngle0 and intrcptArcDelta) - * the intercepted angle of 'this' from 'center' point of view. - * If diagonal of 'this' is the same order of 2*radius, intrcptArcAngle0 and intrcptArcDelta remains unchanged. - * @param center IN parameter. - * @param radius IN parameter. - * @param [out] intrcptArcAngle0 OUT parameter. - * @param [out] intrcptArcDelta OUT parameter. - */ -void Bounds::getInterceptedArc(const double *center, double radius, double& intrcptArcAngle0, double& intrcptArcDelta) const -{ - double diag=getDiagonal(); - if(diag<2.*radius) - { - double v1[2],v2[2],w1[2],w2[2]; - v1[0]=_x_min-center[0]; v1[1]=_y_max-center[1]; v2[0]=_x_max-center[0]; v2[1]=_y_min-center[1]; - w1[0]=v1[0]; w1[1]=_y_min-center[1]; w2[0]=v2[0]; w2[1]=_y_max-center[1]; - double delta1=EdgeArcCircle::SafeAsin(v1[0]*v2[1]-v1[1]*v2[0]); - double delta2=EdgeArcCircle::SafeAsin(w1[0]*w2[1]-w1[1]*w2[0]); - double tmp; - if(fabs(delta1)>fabs(delta2)) - { - intrcptArcDelta=delta1; - intrcptArcAngle0=EdgeArcCircle::GetAbsoluteAngle(v1,tmp); - } - else - { - intrcptArcDelta=delta2; - intrcptArcAngle0=EdgeArcCircle::GetAbsoluteAngle(w1,tmp); - } - } -} - -double Bounds::fitXForXFigD(double val, int res) const -{ - double delta=std::max(_x_max-_x_min,_y_max-_y_min)/2.; - double ret=val-(_x_max+_x_min)/2.+delta; - delta=11.1375*res/(2.*delta); - return ret*delta; -} - -double Bounds::fitYForXFigD(double val, int res) const -{ - double delta=std::max(_x_max-_x_min,_y_max-_y_min)/2.; - double ret=(_y_max+_y_min)/2.-val+delta; - delta=11.1375*res/(2.*delta); - return ret*delta; -} - -Bounds *Bounds::nearlyAmIIntersectingWith(const Bounds& other) const -{ - if( (other._x_min > _x_max+QUADRATIC_PLANAR::_precision) || (other._x_max < _x_min-QUADRATIC_PLANAR::_precision) || (other._y_min > _y_max+QUADRATIC_PLANAR::_precision) - || (other._y_max < _y_min-QUADRATIC_PLANAR::_precision) ) - return 0; - if( (other._x_min >= _x_max ) || (other._x_max <= _x_min) || (other._y_min >= _y_max) || (other._y_max <= _y_min) ) - { - return new Bounds(std::max(_x_min-QUADRATIC_PLANAR::_precision,other._x_min), - std::min(_x_max+QUADRATIC_PLANAR::_precision,other._x_max), - std::max(_y_min-QUADRATIC_PLANAR::_precision,other._y_min), - std::min(_y_max+QUADRATIC_PLANAR::_precision,other._y_max));//In approx cases. - } - else - return new Bounds(std::max(_x_min,other._x_min),std::min(_x_max,other._x_max),std::max(_y_min,other._y_min),std::min(_y_max,other._y_max)); -} - -Bounds *Bounds::amIIntersectingWith(const Bounds& other) const -{ - if( (other._x_min > _x_max) || (other._x_max < _x_min) || (other._y_min > _y_max) || (other._y_max < _y_min) ) - return 0; - return new Bounds(std::max(_x_min,other._x_min),std::min(_x_max,other._x_max),std::max(_y_min,other._y_min),std::min(_y_max,other._y_max)); -} - -Position Bounds::where(double x, double y) const -{ - if((x>=_x_min && x<=_x_max) && (y>=_y_min && y<=_y_max)) - return IN; - else - return OUT; -} - -Position Bounds::nearlyWhere(double x, double y) const -{ - bool thinX=Node::areDoubleEquals(_x_min,_x_max); - bool thinY=Node::areDoubleEquals(_y_min,_y_max); - if(!thinX) - { - if((Node::areDoubleEquals(x,_x_min) || Node::areDoubleEquals(x,_x_max)) && ((y<_y_max+QUADRATIC_PLANAR::_precision) && (y>_y_min-QUADRATIC_PLANAR::_precision))) - return ON_BOUNDARY_POS; - } - else - if(!Node::areDoubleEquals(_x_min,x) && !Node::areDoubleEquals(_x_max,x)) - return OUT; - if(!thinY) - { - if((Node::areDoubleEquals(y,_y_min) || Node::areDoubleEquals(y,_y_max)) && ((x<_x_max+QUADRATIC_PLANAR::_precision) && (x>_x_min-QUADRATIC_PLANAR::_precision))) - return ON_BOUNDARY_POS; - } - else - if(!Node::areDoubleEquals(_y_min,y) && !Node::areDoubleEquals(_y_max,y)) - return OUT; - if(thinX && thinY) - return ON_BOUNDARY_POS; - if((x>=_x_min && x<=_x_max) && (y>=_y_min && y<=_y_max)) - return IN; - else - return OUT; -} - -void Bounds::aggregate(const Bounds& other) -{ - _x_min=std::min(_x_min,other._x_min); _x_max=std::max(_x_max,other._x_max); - _y_min=std::min(_y_min,other._y_min); _y_max=std::max(_y_max,other._y_max); -} diff --git a/src/INTERP_KERNEL/Geometric2D/InterpKernelGeo2DBounds.hxx b/src/INTERP_KERNEL/Geometric2D/InterpKernelGeo2DBounds.hxx deleted file mode 100644 index 914391a9f..000000000 --- a/src/INTERP_KERNEL/Geometric2D/InterpKernelGeo2DBounds.hxx +++ /dev/null @@ -1,80 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 -// 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 __INTERPKERNELGEO2DBOUNDS_HXX__ -#define __INTERPKERNELGEO2DBOUNDS_HXX__ - -#include "INTERPKERNELDefines.hxx" - -#include - -namespace INTERP_KERNEL -{ - /*! - * Relative LOC - */ - typedef enum - { - IN = 0, - OUT = 1, - ON_BOUNDARY_POS = 2, - ON_BOUNDARY_NEG = 3 - } Position; - - class INTERPKERNEL_EXPORT Bounds - { - public: - Bounds():_x_min(0.),_x_max(0.),_y_min(0.),_y_max(0.) { } - double &operator[](int i); - const double& operator[](int i) const; - double getXMin() const { return _x_min; } - double getXMax() const { return _x_max; } - double getYMin() const { return _y_min; } - double getYMax() const { return _y_max; } - double getDiagonal() const; - void getBarycenter(double& xBary, double& yBary) const; - void applySimilarity(double xBary, double yBary, double dimChar); - void unApplySimilarity(double xBary, double yBary, double dimChar); - Bounds& operator=(const Bounds& other) { _x_min=other._x_min; _x_max=other._x_max; _y_min=other._y_min; _y_max=other._y_max; return *this; } - Bounds(double xMin, double xMax, double yMin, double yMax):_x_min(xMin),_x_max(xMax),_y_min(yMin),_y_max(yMax) { } - void setValues(double xMin, double xMax, double yMin, double yMax) { _x_min=xMin; _x_max=xMax; _y_min=yMin; _y_max=yMax; } - void prepareForAggregation(); - void getInterceptedArc(const double *center, double radius, double& intrcptArcAngle0, double& intrcptArcDelta) const; - int fitXForXFig(double val, int res) const { return (int)fitXForXFigD(val,res); } - int fitYForXFig(double val, int res) const { return (int)fitYForXFigD(val,res); } - double fitXForXFigD(double val, int res) const; - double fitYForXFigD(double val, int res) const; - Bounds *nearlyAmIIntersectingWith(const Bounds& other) const; - Bounds *amIIntersectingWith(const Bounds& other) const; - //! No approximations. - Position where(double x, double y) const; - //! Idem where method but with approximations. - Position nearlyWhere(double x, double y) const; - void aggregate(const Bounds& other); - double getCaracteristicDim() const { return std::max(_x_max-_x_min,_y_max-_y_min); } - protected: - double _x_min; - double _x_max; - double _y_min; - double _y_max; - }; -} - -#endif diff --git a/src/INTERP_KERNEL/Geometric2D/InterpKernelGeo2DComposedEdge.cxx b/src/INTERP_KERNEL/Geometric2D/InterpKernelGeo2DComposedEdge.cxx deleted file mode 100644 index 9c310bbca..000000000 --- a/src/INTERP_KERNEL/Geometric2D/InterpKernelGeo2DComposedEdge.cxx +++ /dev/null @@ -1,672 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 -// 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 "InterpKernelGeo2DComposedEdge.hxx" -#include "InterpKernelGeo2DElementaryEdge.hxx" -#include "InterpKernelGeo2DEdgeArcCircle.hxx" -#include "InterpKernelGeo2DEdgeInfLin.hxx" -#include "InterpKernelException.hxx" - -#include -#include -#include -#include - -using namespace INTERP_KERNEL; - -ComposedEdge::ComposedEdge(const ComposedEdge& other) -{ - for(std::list::const_iterator iter=other._sub_edges.begin();iter!=other._sub_edges.end();iter++) - _sub_edges.push_back((*iter)->clone()); -} - -ComposedEdge::~ComposedEdge() -{ - clearAll(_sub_edges.begin()); -} - -void ComposedEdge::setValueAt(int i, Edge *e, bool direction) -{ - std::list::iterator it=_sub_edges.begin(); - for(int j=0;jgetPtr()==_b1->getPtr();} - - ElementaryEdge *_b1; -}; -/*! \endcond */ - -double ComposedEdge::getCommonLengthWith(const ComposedEdge& other) const -{ - double ret=0.; - for(std::list::const_iterator iter=_sub_edges.begin();iter!=_sub_edges.end();iter++) - { - if(find_if(other._sub_edges.begin(),other._sub_edges.end(),AbsEdgeCmp(*iter))!=other._sub_edges.end()) - { - const ElementaryEdge *tmp=static_cast(*iter); - ret+=tmp->getCurveLength(); - } - } - return ret; -} - -void ComposedEdge::clear() -{ - clearAll(_sub_edges.begin()); - _sub_edges.clear(); -} - -void ComposedEdge::pushBack(Edge *edge, bool direction) -{ - _sub_edges.push_back(new ElementaryEdge(edge,direction)); -} - -void ComposedEdge::pushBack(ElementaryEdge *elem) -{ - _sub_edges.push_back(elem); -} - -void ComposedEdge::pushBack(ComposedEdge *elem) -{ - std::list *elemsOfElem=elem->getListBehind(); - _sub_edges.insert(_sub_edges.end(),elemsOfElem->begin(),elemsOfElem->end()); -} - -ElementaryEdge *ComposedEdge::operator[](int i) const -{ - std::list::const_iterator iter=_sub_edges.begin(); - for(int ii=0;ii::iterator iter=_sub_edges.begin();iter!=_sub_edges.end();iter++) - (*iter)->reverse(); -} - -bool ComposedEdge::presenceOfOn() const -{ - bool ret=false; - for(std::list::const_iterator iter=_sub_edges.begin();iter!=_sub_edges.end() && !ret;iter++) - ret=((*iter)->getLoc()==FULL_ON_1); - return ret; -} - -bool ComposedEdge::presenceOfQuadraticEdge() const -{ - bool ret=false; - for(std::list::const_iterator iter=_sub_edges.begin();iter!=_sub_edges.end() && !ret;iter++) - { - Edge *e=(*iter)->getPtr(); - if(e) - ret=dynamic_cast(e)!=0; - } - return ret; -} - -void ComposedEdge::initLocations() const -{ - for(std::list::const_iterator iter=_sub_edges.begin();iter!=_sub_edges.end();iter++) - (*iter)->initLocations(); -} - -/** - * Reset the status of all edges (OUT, IN, ON) because they were potentially assigned - * by the previous candidate processing. - */ -void ComposedEdge::InitLocationsWithOther(const ComposedEdge& first, const ComposedEdge& other) -{ - std::set s1,s2; - for(std::list::const_iterator it1=first._sub_edges.begin();it1!=first._sub_edges.end();it1++) - s1.insert((*it1)->getPtr()); - for(std::list::const_iterator it2=other._sub_edges.begin();it2!=other._sub_edges.end();it2++) - s2.insert((*it2)->getPtr()); - first.initLocations(); - other.initLocations(); - std::vector s3; - std::set_intersection(s1.begin(),s1.end(),s2.begin(),s2.end(),std::back_insert_iterator< std::vector >(s3)); - for(std::vector::const_iterator it3=s3.begin();it3!=s3.end();it3++) - (*it3)->declareOn(); -} - -ComposedEdge *ComposedEdge::clone() const -{ - return new ComposedEdge(*this); -} - -bool ComposedEdge::isNodeIn(Node *n) const -{ - bool ret=false; - for(std::list::const_iterator iter=_sub_edges.begin();iter!=_sub_edges.end() && !ret;iter++) - ret=(*iter)->isNodeIn(n); - return ret; -} - -/*! - * This method computes the area of 'this'. - * By definition : - * \f[ - * Area=\int_{Polygon} dS - * \f] - * Thanks to Green's theorem we have. - * \f[ - * \int_{Polygon} x \cdot dS=\sum_{0 \leq i < nb of edges} -\int_{Edge_{i}}ydx=\sum_{0 \leq i < nb of edges} AreaOfZone_{Edge_{i}} - * \f] - * Where \f$ AreaOfZone_{i} \f$ is computed virtually by INTERP_KERNEL::Edge::getAreaOfZone with following formula : - * \f[ - * AreaOfZone_{i}=\int_{Edge_{i}} -ydx - * \f] - */ -double ComposedEdge::getArea() const -{ - double ret=0.; - for(std::list::const_iterator iter=_sub_edges.begin();iter!=_sub_edges.end();iter++) - ret+=(*iter)->getAreaOfZone(); - return ret; -} - -double ComposedEdge::getPerimeter() const -{ - double ret=0.; - for(std::list::const_iterator iter=_sub_edges.begin();iter!=_sub_edges.end();iter++) - ret+=(*iter)->getCurveLength(); - return ret; -} - -double ComposedEdge::getHydraulicDiameter() const -{ - return 4*fabs(getArea())/getPerimeter(); -} - -/*! - * This method computes barycenter of 'this' by returning xG in bary[0] and yG in bary[1]. - * By definition : - * \f[ - * Area \cdot x_{G}=\int_{Polygon} x \cdot dS - * \f] - * \f[ - * Area \cdot y_{G}=\int_{Polygon} y \cdot dS - * \f] - * Thanks to Green's theorem we have. - * \f[ - * \int_{Polygon} x \cdot dS=\sum_{0 \leq i < nb of edges} -\int_{Edge_{i}}yxdx - * \f] - * \f[ - * \int_{Polygon} y \cdot dS=\sum_{0 \leq i < nb of edges} -\int_{Edge_{i}}\frac{y^{2}}{2}dx - * \f] - * Area is computed using the same principle than described in INTERP_KERNEL::ComposedEdge::getArea method. - * \f$ -\int_{Edge_{i}}yxdx \f$ and \f$ -\int_{Edge_{i}}\frac{y^{2}}{2}dx \f$ are computed virtually with INTERP_KERNEL::Edge::getBarycenterOfZone. - */ -void ComposedEdge::getBarycenter(double *bary) const -{ - bary[0]=0.; - bary[1]=0.; - double area=0.; - for(std::list::const_iterator iter=_sub_edges.begin();iter!=_sub_edges.end();iter++) - { - (*iter)->getBarycenterOfZone(bary); - area+=(*iter)->getAreaOfZone(); - } - bary[0]/=area; - bary[1]/=area; -} - -/*! - * Idem ComposedEdge::getBarycenter except that the special case where _sub_edges==1 is dealt here. - */ -void ComposedEdge::getBarycenterGeneral(double *bary) const -{ - if(_sub_edges.empty()) - throw INTERP_KERNEL::Exception("ComposedEdge::getBarycenterGeneral called on an empty polygon !"); - if(_sub_edges.size()>2) - return getBarycenter(bary); - double w; - _sub_edges.back()->getBarycenter(bary,w); -} - -double ComposedEdge::normalizeMe(double& xBary, double& yBary) -{ - Bounds b; - b.prepareForAggregation(); - fillBounds(b); - double dimChar=b.getCaracteristicDim(); - b.getBarycenter(xBary,yBary); - applyGlobalSimilarity(xBary,yBary,dimChar); - return dimChar; -} - -double ComposedEdge::normalize(ComposedEdge *other, double& xBary, double& yBary) -{ - Bounds b; - b.prepareForAggregation(); - fillBounds(b); - other->fillBounds(b); - double dimChar=b.getCaracteristicDim(); - b.getBarycenter(xBary,yBary); - applyGlobalSimilarity(xBary,yBary,dimChar); - other->applyGlobalSimilarity(xBary,yBary,dimChar); - return dimChar; -} - -/*! - * This method operates the opposite operation than ComposedEdge::applyGlobalSimilarity. - */ -void ComposedEdge::unApplyGlobalSimilarityExt(ComposedEdge& other, double xBary, double yBary, double fact) -{ - initNodeHitStatus(); - other.initNodeHitStatus(); - unApplySimilarityOnMyNodes(xBary,yBary,fact); - other.unApplySimilarityOnMyNodesIfNotAlreadyHit(xBary,yBary,fact); - initEdgeHitStatus(); - other.initEdgeHitStatus(); - unApplySimilarityOnMyEdges(xBary,yBary,fact); - other.unApplySimilarityOnMyEdgesIfNotAlreadyHit(xBary,yBary,fact); -} - -double ComposedEdge::normalizeExt(ComposedEdge *other, double& xBary, double& yBary) -{ - Bounds b; - b.prepareForAggregation(); - fillBounds(b); - other->fillBounds(b); - double dimChar=b.getCaracteristicDim(); - b.getBarycenter(xBary,yBary); - applyGlobalSimilarity2(other,xBary,yBary,dimChar); - return dimChar; -} - -void ComposedEdge::dumpInXfigFile(std::ostream& stream, int resolution, const Bounds& box) const -{ - stream.precision(10); - for(std::list::const_iterator iter=_sub_edges.begin();iter!=_sub_edges.end();iter++) - (*iter)->dumpInXfigFile(stream,resolution,box); -} - -Node *ComposedEdge::getEndNode() const -{ - return _sub_edges.back()->getEndNode(); -} - -Node *ComposedEdge::getStartNode() const -{ - return _sub_edges.front()->getStartNode(); -} - -bool ComposedEdge::changeEndNodeWith(Node *node) const -{ - return _sub_edges.back()->changeEndNodeWith(node); -} - -bool ComposedEdge::changeStartNodeWith(Node *node) const -{ - return _sub_edges.front()->changeStartNodeWith(node); -} - -void ComposedEdge::fillBounds(Bounds& output) const -{ - for(std::list::const_iterator iter=_sub_edges.begin();iter!=_sub_edges.end();iter++) - (*iter)->fillBounds(output); -} - -/*! - * \b WARNING : applies similarity \b ONLY on edges without any change on Nodes. To perform a global similarity call applyGlobalSimilarity. - */ -void ComposedEdge::applySimilarity(double xBary, double yBary, double dimChar) -{ - for(std::list::iterator iter=_sub_edges.begin();iter!=_sub_edges.end();iter++) - (*iter)->applySimilarity(xBary,yBary,dimChar); -} - -/*! - * Perform Similarity transformation on all elements of this Nodes and Edges. - */ -void ComposedEdge::applyGlobalSimilarity(double xBary, double yBary, double dimChar) -{ - std::set allNodes; - getAllNodes(allNodes); - for(std::set::iterator iter=allNodes.begin();iter!=allNodes.end();iter++) - (*iter)->applySimilarity(xBary,yBary,dimChar); - for(std::list::iterator iter=_sub_edges.begin();iter!=_sub_edges.end();iter++) - (*iter)->applySimilarity(xBary,yBary,dimChar); -} - -/*! - * Perform Similarity transformation on all elements of this Nodes and Edges on 'this' and 'other'. - * Nodes can be shared between 'this' and 'other'. - */ -void ComposedEdge::applyGlobalSimilarity2(ComposedEdge *other, double xBary, double yBary, double dimChar) -{ - initNodeHitStatus(); - other->initNodeHitStatus(); - applySimilarityOnMyNodes(xBary,yBary,dimChar); - other->applySimilarityOnMyNodesIfNotAlreadyHit(xBary,yBary,dimChar); - initEdgeHitStatus(); - other->initEdgeHitStatus(); - applySimilarityOnMyEdges(xBary,yBary,dimChar); - other->applySimilarityOnMyEdgesIfNotAlreadyHit(xBary,yBary,dimChar); -} - -/*! - * This method append to param 'partConsidered' the part of length of subedges IN or ON. - * @param partConsidered INOUT param. - */ -void ComposedEdge::dispatchPerimeter(double& partConsidered) const -{ - for(std::list::const_iterator iter=_sub_edges.begin();iter!=_sub_edges.end();iter++) - { - TypeOfEdgeLocInPolygon loc=(*iter)->getLoc(); - if(loc==FULL_IN_1 || loc==FULL_ON_1) - partConsidered+=(*iter)->getCurveLength(); - } -} - -/*! - * Idem dispatchPerimeterExcl except that when a subedge is declared as ON this subedge is counted in commonPart. - */ -void ComposedEdge::dispatchPerimeterExcl(double& partConsidered, double& commonPart) const -{ - for(std::list::const_iterator iter=_sub_edges.begin();iter!=_sub_edges.end();iter++) - { - TypeOfEdgeLocInPolygon loc=(*iter)->getLoc(); - if(loc==FULL_IN_1) - partConsidered+=(*iter)->getCurveLength(); - if(loc==FULL_ON_1) - commonPart+=(*iter)->getCurveLength(); - } -} - -void ComposedEdge::getAllNodes(std::set& output) const -{ - std::list::const_iterator iter=_sub_edges.begin(); - for(;iter!=_sub_edges.end();iter++) - (*iter)->getAllNodes(output); -} - -void ComposedEdge::initNodeHitStatus() const -{ - for(std::list::const_iterator iter=_sub_edges.begin();iter!=_sub_edges.end();iter++) - { - (*iter)->getStartNode()->initHitStatus(); - (*iter)->getEndNode()->initHitStatus(); - } -} - -void ComposedEdge::applySimilarityOnMyNodes(double xBary, double yBary, double dimChar) const -{ - for(std::list::const_iterator iter=_sub_edges.begin();iter!=_sub_edges.end();iter++) - { - (*iter)->getStartNode()->hitMeAlone(xBary,yBary,dimChar); - (*iter)->getEndNode()->hitMeAlone(xBary,yBary,dimChar); - } -} - -void ComposedEdge::unApplySimilarityOnMyNodes(double xBary, double yBary, double dimChar) const -{ - for(std::list::const_iterator iter=_sub_edges.begin();iter!=_sub_edges.end();iter++) - { - (*iter)->getStartNode()->unHitMeAlone(xBary,yBary,dimChar); - (*iter)->getEndNode()->unHitMeAlone(xBary,yBary,dimChar); - } -} - -void ComposedEdge::applySimilarityOnMyNodesIfNotAlreadyHit(double xBary, double yBary, double dimChar) const -{ - for(std::list::const_iterator iter=_sub_edges.begin();iter!=_sub_edges.end();iter++) - { - (*iter)->getStartNode()->hitMeAfter(xBary,yBary,dimChar); - (*iter)->getEndNode()->hitMeAfter(xBary,yBary,dimChar); - } -} - -void ComposedEdge::unApplySimilarityOnMyNodesIfNotAlreadyHit(double xBary, double yBary, double dimChar) const -{ - for(std::list::const_iterator iter=_sub_edges.begin();iter!=_sub_edges.end();iter++) - { - (*iter)->getStartNode()->unHitMeAfter(xBary,yBary,dimChar); - (*iter)->getEndNode()->unHitMeAfter(xBary,yBary,dimChar); - } -} - -void ComposedEdge::initEdgeHitStatus() const -{ - for(std::list::const_iterator iter=_sub_edges.begin();iter!=_sub_edges.end();iter++) - (*iter)->getPtr()->initHitStatus(); -} - -void ComposedEdge::applySimilarityOnMyEdges(double xBary, double yBary, double dimChar) const -{ - for(std::list::const_iterator iter=_sub_edges.begin();iter!=_sub_edges.end();iter++) - (*iter)->getPtr()->hitMeAlone(xBary,yBary,dimChar); -} - -void ComposedEdge::unApplySimilarityOnMyEdges(double xBary, double yBary, double dimChar) const -{ - for(std::list::const_iterator iter=_sub_edges.begin();iter!=_sub_edges.end();iter++) - (*iter)->getPtr()->unHitMeAlone(xBary,yBary,dimChar); -} - -void ComposedEdge::applySimilarityOnMyEdgesIfNotAlreadyHit(double xBary, double yBary, double dimChar) const -{ - for(std::list::const_iterator iter=_sub_edges.begin();iter!=_sub_edges.end();iter++) - (*iter)->getPtr()->hitMeAfter(xBary,yBary,dimChar); -} - -void ComposedEdge::unApplySimilarityOnMyEdgesIfNotAlreadyHit(double xBary, double yBary, double dimChar) const -{ - for(std::list::const_iterator iter=_sub_edges.begin();iter!=_sub_edges.end();iter++) - (*iter)->getPtr()->unHitMeAfter(xBary,yBary,dimChar); -} - -void ComposedEdge::getBarycenter(double *bary, double& weigh) const -{ - weigh=0.; bary[0]=0.; bary[1]=0.; - double tmp1,tmp2[2]; - for(std::list::const_iterator iter=_sub_edges.begin();iter!=_sub_edges.end();iter++) - { - (*iter)->getBarycenter(tmp2,tmp1); - weigh+=tmp1; - bary[0]+=tmp1*tmp2[0]; - bary[1]+=tmp1*tmp2[1]; - } - bary[0]/=weigh; - bary[1]/=weigh; -} - -/*! - * This method makes the hypothesis that \a nodeToTest can be either IN or OUT. - * - * \sa ComposedEdge::isInOrOut2 - */ -bool ComposedEdge::isInOrOut(Node *nodeToTest) const -{ - Bounds b; b.prepareForAggregation(); - fillBounds(b); - if(b.nearlyWhere((*nodeToTest)[0],(*nodeToTest)[1])==OUT) - return false; - std::set< IntersectElement > inOutSwitch; - double ref(isInOrOutAlg(nodeToTest,inOutSwitch)); - bool ret(false); - for(std::set< IntersectElement >::iterator iter4=inOutSwitch.begin();iter4!=inOutSwitch.end();iter4++) - { - if((*iter4).getVal1()getLoc()==ON_1) - ret=!ret; - } - else - break; - } - return ret; -} - -/*! - * This method is close to ComposedEdge::isInOrOut behaviour except that here EPSILON is taken into account to detect if it is IN or OUT. - * If \a nodeToTest is close to an edge in \a this, true will be returned even if it is outside informatically from \a this. - * - * \sa ComposedEdge::isInOrOut - */ -bool ComposedEdge::isInOrOut2(Node *nodeToTest) const -{ - std::set< IntersectElement > inOutSwitch; - double ref(isInOrOutAlg(nodeToTest,inOutSwitch)); - bool ret(false); - for(std::set< IntersectElement >::iterator iter4=inOutSwitch.begin();iter4!=inOutSwitch.end();iter4++) - { - double val((*iter4).getVal1()); - if(fabs(val-ref)>=QUADRATIC_PLANAR::_precision) - { - if(valgetLoc()==ON_1) - ret=!ret; - } - else - break; - } - else - return true; - } - return ret; -} - -double ComposedEdge::isInOrOutAlg(Node *nodeToTest, std::set< IntersectElement >& inOutSwitch) const -{ - // searching for e1 - std::set nodes; - getAllNodes(nodes); - std::set radialDistributionOfNodes; - std::set::const_iterator iter; - for(iter=nodes.begin();iter!=nodes.end();iter++) - radialDistributionOfNodes.insert(nodeToTest->getSlope(*(*iter))); - std::vector radialDistrib(radialDistributionOfNodes.begin(),radialDistributionOfNodes.end()); - radialDistributionOfNodes.clear(); - std::vector radialDistrib2(radialDistrib.size()); - copy(radialDistrib.begin()+1,radialDistrib.end(),radialDistrib2.begin()); - radialDistrib2.back()=M_PI+radialDistrib.front(); - std::vector radialDistrib3(radialDistrib.size()); - std::transform(radialDistrib2.begin(),radialDistrib2.end(),radialDistrib.begin(),radialDistrib3.begin(),std::minus()); - std::vector::iterator iter3=max_element(radialDistrib3.begin(),radialDistrib3.end()); - int i=iter3-radialDistrib3.begin(); - // ok for e1 - Let's go. - EdgeInfLin *e1=new EdgeInfLin(nodeToTest,radialDistrib[i]+radialDistrib3[i]/2.); - double ref=e1->getCharactValue(*nodeToTest); - for(std::list::const_iterator iter4=_sub_edges.begin();iter4!=_sub_edges.end();iter4++) - { - ElementaryEdge *val=(*iter4); - if(val) - { - Edge *e=val->getPtr(); - std::auto_ptr intersc(Edge::BuildIntersectorWith(e1,e)); - bool obviousNoIntersection,areOverlapped; - intersc->areOverlappedOrOnlyColinears(0,obviousNoIntersection,areOverlapped); // first parameter never used - if(obviousNoIntersection) - { - continue; - } - if(!areOverlapped) - { - std::list< IntersectElement > listOfIntesc=intersc->getIntersectionsCharacteristicVal(); - for(std::list< IntersectElement >::iterator iter2=listOfIntesc.begin();iter2!=listOfIntesc.end();iter2++) - if((*iter2).isIncludedByBoth()) - inOutSwitch.insert(*iter2); - } - //if overlapped we can forget - } - else - throw Exception("Invalid use of ComposedEdge::isInOrOutAlg : only one level supported !"); - } - e1->decrRef(); - return ref; -} - -/*bool ComposedEdge::isInOrOut(Node *aNodeOn, Node *nodeToTest) const -{ - - EdgeInfLin *e1=new EdgeInfLin(aNodeOn,nodeToTest); - double ref=e1->getCharactValue(*nodeToTest); - set< IntersectElement > inOutSwitch; - for(vector::const_iterator iter=_sub_edges.begin();iter!=_sub_edges.end();iter++) - { - ElementaryEdge *val=dynamic_cast(*iter); - if(val) - { - Edge *e=val->getPtr(); - auto_ptr intersc(Edge::buildIntersectorWith(e1,e)); - bool obviousNoIntersection,areOverlapped; - intersc->areOverlappedOrOnlyColinears(0,obviousNoIntersection,areOverlapped); - if(obviousNoIntersection) - { - continue; - } - if(!areOverlapped) - { - list< IntersectElement > listOfIntesc=intersc->getIntersectionsCharacteristicVal(); - for(list< IntersectElement >::iterator iter2=listOfIntesc.begin();iter2!=listOfIntesc.end();iter2++) - if((*iter2).isIncludedByBoth()) - inOutSwitch.insert(*iter2); - } - //if overlapped we can forget - } - else - throw Exception("Invalid use of ComposedEdge::isInOrOut : only one level supported !"); - } - e1->decrRef(); - bool ret=false; - for(set< IntersectElement >::iterator iter=inOutSwitch.begin();iter!=inOutSwitch.end();iter++) - { - if((*iter).getVal1()getLoc()==ON_1) - ret=!ret; - } - else - break; - } - return ret; -}*/ - -bool ComposedEdge::getDirection() const -{ - throw Exception("ComposedEdge::getDirection : no sense"); -} - -bool ComposedEdge::intresincEqCoarse(const Edge *other) const -{ - if(_sub_edges.size()!=1) - return false; - return _sub_edges.front()->intresincEqCoarse(other); -} - -void ComposedEdge::clearAll(std::list::iterator startToDel) -{ - for(std::list::iterator iter=startToDel;iter!=_sub_edges.end();iter++) - delete (*iter); -} diff --git a/src/INTERP_KERNEL/Geometric2D/InterpKernelGeo2DComposedEdge.hxx b/src/INTERP_KERNEL/Geometric2D/InterpKernelGeo2DComposedEdge.hxx deleted file mode 100644 index f4c56fbac..000000000 --- a/src/INTERP_KERNEL/Geometric2D/InterpKernelGeo2DComposedEdge.hxx +++ /dev/null @@ -1,124 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 -// 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 __INTERPKERNELGEO2DCOMPOSEDNODE_HXX__ -#define __INTERPKERNELGEO2DCOMPOSEDNODE_HXX__ - -#include "INTERPKERNELDefines.hxx" -#include "InterpKernelGeo2DEdge.hxx" - -#include -#include -#include -#include - -namespace INTERP_KERNEL -{ - class Node; - class Edge; - class Bounds; - class ElementaryEdge; - class IteratorOnComposedEdge; - - /** - * A set of quadratic or linear edges, described mainly by their connectivity - * The set is assumed to be connected, but not necessarily closed (i.e. not necessarily forming a closed polygon). - * Some methods however requires a closed form. - */ - class ComposedEdge - { - friend class IteratorOnComposedEdge; - public: - INTERPKERNEL_EXPORT ComposedEdge() { } - INTERPKERNEL_EXPORT ComposedEdge(const ComposedEdge& other); - INTERPKERNEL_EXPORT ComposedEdge(int sz):_sub_edges(sz) { } - INTERPKERNEL_EXPORT static void Delete(ComposedEdge *pt) { delete pt; } - INTERPKERNEL_EXPORT static void SoftDelete(ComposedEdge *pt) { pt->_sub_edges.clear(); delete pt; } - INTERPKERNEL_EXPORT void reverse(); - INTERPKERNEL_EXPORT int recursiveSize() const { return (int)_sub_edges.size(); } - INTERPKERNEL_EXPORT bool presenceOfOn() const; - INTERPKERNEL_EXPORT bool presenceOfQuadraticEdge() const; - INTERPKERNEL_EXPORT void initLocations() const; - INTERPKERNEL_EXPORT static void InitLocationsWithOther(const ComposedEdge& first, const ComposedEdge& other); - INTERPKERNEL_EXPORT ComposedEdge *clone() const; - INTERPKERNEL_EXPORT bool isNodeIn(Node *n) const; - INTERPKERNEL_EXPORT double getArea() const; - INTERPKERNEL_EXPORT double getPerimeter() const; - INTERPKERNEL_EXPORT double getHydraulicDiameter() const; - INTERPKERNEL_EXPORT void getBarycenter(double *bary) const; - INTERPKERNEL_EXPORT void getBarycenterGeneral(double *bary) const; - INTERPKERNEL_EXPORT double normalizeMe(double& xBary, double& yBary); - INTERPKERNEL_EXPORT double normalize(ComposedEdge *other, double& xBary, double& yBary); - INTERPKERNEL_EXPORT double normalizeExt(ComposedEdge *other, double& xBary, double& yBary); - INTERPKERNEL_EXPORT void unApplyGlobalSimilarityExt(ComposedEdge& other, double xBary, double yBary, double fact); - INTERPKERNEL_EXPORT void fillBounds(Bounds& output) const; - INTERPKERNEL_EXPORT void applySimilarity(double xBary, double yBary, double dimChar); - INTERPKERNEL_EXPORT void applyGlobalSimilarity(double xBary, double yBary, double dimChar); - INTERPKERNEL_EXPORT void applyGlobalSimilarity2(ComposedEdge *other, double xBary, double yBary, double dimChar); - INTERPKERNEL_EXPORT void dispatchPerimeter(double& partConsidered) const; - INTERPKERNEL_EXPORT void dispatchPerimeterExcl(double& partConsidered, double& commonPart) const; - INTERPKERNEL_EXPORT double dispatchPerimeterAdv(const ComposedEdge& father, std::vector& result) const; - INTERPKERNEL_EXPORT void getAllNodes(std::set& output) const; - INTERPKERNEL_EXPORT void initNodeHitStatus() const; - INTERPKERNEL_EXPORT void applySimilarityOnMyNodes(double xBary, double yBary, double dimChar) const; - INTERPKERNEL_EXPORT void unApplySimilarityOnMyNodes(double xBary, double yBary, double dimChar) const; - INTERPKERNEL_EXPORT void applySimilarityOnMyNodesIfNotAlreadyHit(double xBary, double yBary, double dimChar) const; - INTERPKERNEL_EXPORT void unApplySimilarityOnMyNodesIfNotAlreadyHit(double xBary, double yBary, double dimChar) const; - INTERPKERNEL_EXPORT void initEdgeHitStatus() const; - INTERPKERNEL_EXPORT void applySimilarityOnMyEdges(double xBary, double yBary, double dimChar) const; - INTERPKERNEL_EXPORT void unApplySimilarityOnMyEdges(double xBary, double yBary, double dimChar) const; - INTERPKERNEL_EXPORT void applySimilarityOnMyEdgesIfNotAlreadyHit(double xBary, double yBary, double dimChar) const; - INTERPKERNEL_EXPORT void unApplySimilarityOnMyEdgesIfNotAlreadyHit(double xBary, double yBary, double dimChar) const; - INTERPKERNEL_EXPORT void getBarycenter(double *bary, double& weigh) const; - INTERPKERNEL_EXPORT bool completed() const { return getEndNode()==getStartNode(); } - INTERPKERNEL_EXPORT void setValueAt(int i, Edge *e, bool direction=true); - INTERPKERNEL_EXPORT double getCommonLengthWith(const ComposedEdge& other) const; - INTERPKERNEL_EXPORT void clear(); - INTERPKERNEL_EXPORT bool empty() const { return _sub_edges.empty(); } - INTERPKERNEL_EXPORT ElementaryEdge *front() const { return _sub_edges.front(); } - INTERPKERNEL_EXPORT ElementaryEdge *back() const { return _sub_edges.back(); } - INTERPKERNEL_EXPORT void resize(int i) { _sub_edges.resize(i); } - INTERPKERNEL_EXPORT void pushBack(Edge *edge, bool direction=true); - INTERPKERNEL_EXPORT void pushBack(ElementaryEdge *elem); - INTERPKERNEL_EXPORT void pushBack(ComposedEdge *elem); - INTERPKERNEL_EXPORT int size() const { return (int)_sub_edges.size(); } - INTERPKERNEL_EXPORT ElementaryEdge *operator[](int i) const; - INTERPKERNEL_EXPORT Node *getEndNode() const; - INTERPKERNEL_EXPORT Node *getStartNode() const; - INTERPKERNEL_EXPORT bool changeEndNodeWith(Node *node) const; - INTERPKERNEL_EXPORT bool changeStartNodeWith(Node *node) const; - INTERPKERNEL_EXPORT void dumpInXfigFile(std::ostream& stream, int resolution, const Bounds& box) const; - INTERPKERNEL_EXPORT bool isInOrOut(Node *nodeToTest) const; - INTERPKERNEL_EXPORT bool isInOrOut2(Node *nodeToTest) const; - INTERPKERNEL_EXPORT bool getDirection() const; - INTERPKERNEL_EXPORT bool intresincEqCoarse(const Edge *other) const; - private: - std::list* getListBehind() { return &_sub_edges; } - double isInOrOutAlg(Node *nodeToTest, std::set< IntersectElement >& inOutSwitch) const; - protected: - ~ComposedEdge(); - private: - void clearAll(std::list::iterator startToDel); - protected: - std::list _sub_edges; - }; -} - -#endif diff --git a/src/INTERP_KERNEL/Geometric2D/InterpKernelGeo2DEdge.cxx b/src/INTERP_KERNEL/Geometric2D/InterpKernelGeo2DEdge.cxx deleted file mode 100644 index 166252287..000000000 --- a/src/INTERP_KERNEL/Geometric2D/InterpKernelGeo2DEdge.cxx +++ /dev/null @@ -1,1032 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 -// 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 "InterpKernelGeo2DEdge.hxx" -#include "InterpKernelGeo2DEdgeLin.hxx" -#include "InterpKernelGeo2DEdgeInfLin.hxx" -//#include "EdgeParabol.hxx" -#include "InterpKernelGeo2DEdgeArcCircle.hxx" -#include "InterpKernelGeo2DComposedEdge.hxx" -#include "InterpKernelException.hxx" - -#include - -using namespace INTERP_KERNEL; - -MergePoints::MergePoints():_ass1Start1(0),_ass1End1(0),_ass1Start2(0),_ass1End2(0), - _ass2Start1(0),_ass2End1(0),_ass2Start2(0),_ass2End2(0) -{ -} - -void MergePoints::start1Replaced() -{ - unsigned nbOfAsso=getNumberOfAssociations(); - if(nbOfAsso==0) - _ass1Start1=1; - else - _ass2Start1=1; -} - -void MergePoints::end1Replaced() -{ - unsigned nbOfAsso=getNumberOfAssociations(); - if(nbOfAsso==0) - _ass1End1=1; - else - _ass2End1=1; -} - -void MergePoints::start1OnStart2() -{ - unsigned nbOfAsso=getNumberOfAssociations(); - if(nbOfAsso==0) - { - _ass1Start1=1; - _ass1Start2=1; - } - else - { - _ass2Start1=1; - _ass2Start2=1; - } -} - -void MergePoints::start1OnEnd2() -{ - unsigned nbOfAsso=getNumberOfAssociations(); - if(nbOfAsso==0) - { - _ass1Start1=1; - _ass1End2=1; - } - else - { - _ass2Start1=1; - _ass2End2=1; - } -} - -void MergePoints::end1OnStart2() -{ - unsigned nbOfAsso=getNumberOfAssociations(); - if(nbOfAsso==0) - { - _ass1End1=1; - _ass1Start2=1; - } - else - { - _ass2End1=1; - _ass2Start2=1; - } -} - -void MergePoints::end1OnEnd2() -{ - unsigned nbOfAsso=getNumberOfAssociations(); - if(nbOfAsso==0) - { - _ass1End1=1; - _ass1End2=1; - } - else - { - _ass2End1=1; - _ass2End2=1; - } -} - -bool MergePoints::isStart1(unsigned rk) const -{ - if(rk==0) - return _ass1Start1; - else - return _ass2Start1; -} - -bool MergePoints::isEnd1(unsigned rk) const -{ - if(rk==0) - return _ass1End1; - else - return _ass2End1; -} - -bool MergePoints::isStart2(unsigned rk) const -{ - if(rk==0) - return _ass1Start2; - else - return _ass2Start2; -} - -bool MergePoints::isEnd2(unsigned rk) const -{ - if(rk==0) - return _ass1End2; - else - return _ass2End2; -} - -void MergePoints::clear() -{ - _ass1Start1=0;_ass1End1=0;_ass1Start2=0;_ass1End2=0; - _ass2Start1=0;_ass2End1=0;_ass2Start2=0;_ass2End2=0; -} - -unsigned MergePoints::getNumberOfAssociations() const -{ - unsigned ret=0; - unsigned subTot=_ass1Start1+_ass1End1+_ass1Start2+_ass1End2; - if(subTot!=0) - ret++; - subTot=_ass2Start1+_ass2End1+_ass2Start2+_ass2End2; - if(subTot!=0) - ret++; - return ret; -} - -void MergePoints::PushInMap(int key, int value, std::map& mergedNodes) -{ - if(key!=-1 && value!=-1) - mergedNodes[key]=value; -} - -void MergePoints::updateMergedNodes(int e1Start, int e1End, int e2Start, int e2End, std::map& mergedNodes) -{ - unsigned subTot(_ass1Start1+_ass1End1+_ass1Start2+_ass1End2); - if(subTot!=0) - { - if(_ass1Start1 && _ass1Start2) - PushInMap(e2Start,e1Start,mergedNodes); - if(_ass1Start1 && _ass1End2) - PushInMap(e2End,e1Start,mergedNodes); - if(_ass1End1 && _ass1Start2) - PushInMap(e2Start,e1End,mergedNodes); - if(_ass1End1 && _ass1End2) - PushInMap(e2End,e1End,mergedNodes); - } - subTot=_ass2Start1+_ass2End1+_ass2Start2+_ass2End2; - if(subTot!=0) - { - if(_ass2Start1 && _ass2Start2) - PushInMap(e2Start,e1Start,mergedNodes); - if(_ass2Start1 && _ass2End2) - PushInMap(e2End,e1Start,mergedNodes); - if(_ass2End1 && _ass2Start2) - PushInMap(e2Start,e1End,mergedNodes); - if(_ass2End1 && _ass2End2) - PushInMap(e2End,e1End,mergedNodes); - } -} - -IntersectElement::IntersectElement(double val1, double val2, bool start1, bool end1, bool start2, bool end2, Node *node - , const Edge& e1, const Edge& e2, bool keepOrder):_1S(keepOrder?start1:start2), - _1E(keepOrder?end1:end2), - _2S(keepOrder?start2:start1), - _2E(keepOrder?end2:end1), - _chararct_val_for_e1(keepOrder?val1:val2), - _chararct_val_for_e2(keepOrder?val2:val1), - _node(node),_loc_of_node(node->getLoc()),_e1(keepOrder?e1:e2), - _e2(keepOrder?e2:e1) -{ -} - -IntersectElement::IntersectElement(const IntersectElement& other):_1S(other._1S),_1E(other._1E),_2S(other._2S),_2E(other._2E), - _chararct_val_for_e1(other._chararct_val_for_e1), - _chararct_val_for_e2(other._chararct_val_for_e2),_node(other._node), - _loc_of_node(other._loc_of_node),_e1(other._e1), _e2(other._e2) -{ - if(_node) - _node->incrRef(); -} - -IntersectElement& IntersectElement::operator=(const IntersectElement& other) -{ - _1S=other._1S;_1E=other._1E; _2S=other._2S; _2E=other._2E; - _chararct_val_for_e1=other._chararct_val_for_e1; - _chararct_val_for_e2=other._chararct_val_for_e2; - setNode(other._node); - return *this; -} - -bool IntersectElement::operator<(const IntersectElement& other) const -{ - return _e1.isLower(_chararct_val_for_e1,other._chararct_val_for_e1); -} - -IntersectElement::~IntersectElement() -{ - if(_node) - _node->decrRef(); -} - -/*! - * Returns 0 or 1. - */ -bool IntersectElement::isOnMergedExtremity() const -{ - if( (_1S && _2S) || (_1S && _2E) || (_1E && _2S) || (_1E && _2E) ) - return true; - return false; -} - -/*! - * To call if isOnMergedExtremity returned true. - */ -void IntersectElement::performMerging(MergePoints& commonNode) const -{ - if(_1S && _2S) - { - if(_e1.changeStartNodeWith(_e2.getStartNode())) - { - _e2.getStartNode()->declareOnLim(); - commonNode.start1OnStart2(); - } - } - else if(_1S && _2E) - { - if(_e1.changeStartNodeWith(_e2.getEndNode())) - { - _e2.getEndNode()->declareOnLim(); - commonNode.start1OnEnd2(); - } - } - else if(_1E && _2S) - { - if(_e1.changeEndNodeWith(_e2.getStartNode())) - { - _e2.getStartNode()->declareOnLim(); - commonNode.end1OnStart2(); - } - } - else if(_1E && _2E) - { - if(_e1.changeEndNodeWith(_e2.getEndNode())) - { - _e2.getEndNode()->declareOnLim(); - commonNode.end1OnEnd2(); - } - } -} - -/*! - * This methode is const because 'node' is supposed to be equal geomitrically to _node. - */ -void IntersectElement::setNode(Node *node) const -{ - if(node!=_node) - { - if(_node) - ((Node *)_node)->decrRef(); - (const_cast(this))->_node=node; - if(_node) - _node->incrRef(); - } -} - -bool IntersectElement::isLowerOnOther(const IntersectElement& other) const -{ - return _e2.isLower(_chararct_val_for_e2,other._chararct_val_for_e2); -} - -unsigned IntersectElement::isOnExtrForAnEdgeAndInForOtherEdge() const -{ - if(( _1S && !(_2S || _2E) ) || ( _1E && !(_2S || _2E) )) - { - if(_1S && !(_2S || _2E)) - setNode(_e1.getStartNode()); - else - setNode(_e1.getEndNode()); - if(_e2.isIn(_chararct_val_for_e2)) - return LIMIT_ON; - return LIMIT_ALONE; - } - if(( _2S && !(_1S || _1E) ) || ( _2E && !(_1S || _1E))) - { - if(_2S && !(_1S || _1E)) - setNode(_e2.getStartNode()); - else - setNode(_e2.getEndNode()); - if(_e1.isIn(_chararct_val_for_e1)) - return LIMIT_ON; - return LIMIT_ALONE; - } - return NO_LIMIT; -} - -bool IntersectElement::isIncludedByBoth() const -{ - return _e1.isIn(_chararct_val_for_e1) && _e2.isIn(_chararct_val_for_e2); -} - -bool EdgeIntersector::intersect(const Bounds *whereToFind, std::vector& newNodes, bool& order, MergePoints& commonNode) -{ - std::list< IntersectElement > listOfIntesc=getIntersectionsCharacteristicVal(); - std::list< IntersectElement >::iterator iter; - for(iter=listOfIntesc.begin();iter!=listOfIntesc.end();) - { - if((*iter).isOnMergedExtremity()) - { - (*iter).performMerging(commonNode); - iter=listOfIntesc.erase(iter); - continue; - } - unsigned tmp=(*iter).isOnExtrForAnEdgeAndInForOtherEdge(); - if(tmp==IntersectElement::LIMIT_ALONE) - { - iter=listOfIntesc.erase(iter); - continue; - } - else if(tmp==IntersectElement::LIMIT_ON) - { - (*iter).attachLoc(); - iter++; - continue; - } - if(!(*iter).isIncludedByBoth()) - { - iter=listOfIntesc.erase(iter); - continue; - } - (*iter).attachLoc(); - iter++; - } - if(listOfIntesc.size()==0) - return false; - if(listOfIntesc.size()==1) - { - order=true;//useless - newNodes.push_back(listOfIntesc.front().getNodeAndReleaseIt()); - } - else - { - std::vector vecOfIntesc(listOfIntesc.begin(),listOfIntesc.end()); - listOfIntesc.clear(); - sort(vecOfIntesc.begin(),vecOfIntesc.end()); - for(std::vector::iterator iterV=vecOfIntesc.begin();iterV!=vecOfIntesc.end();iterV++) - newNodes.push_back((*iterV).getNodeAndReleaseIt()); - order=vecOfIntesc.front().isLowerOnOther(vecOfIntesc.back()); - } - return true; -} - -/*! - * Locates 'node' regarding edge this->_e1. If node is located close to (with distant lt epsilon) start or end point of _e1, - * 'node' takes its place. In this case 'obvious' is set to true and 'commonNode' stores information of merge point and finally 'where' is set. - * Furthermore 'node' is declared as ON LIMIT to indicate in locating process that an absolute location computation will have to be done. - * If 'node' is not close to start or end point of _e1, 'obvious' is set to false and 'commonNode' and 'where' are let unchanged. - */ -void EdgeIntersector::obviousCaseForCurvAbscisse(Node *node, TypeOfLocInEdge& where, MergePoints& commonNode, bool& obvious) const -{ - obvious=true; - if(node->isEqual(*_e1.getStartNode())) - { - where=START; - if(_e1.changeStartNodeWith(node)) - { - commonNode.start1Replaced(); - node->declareOnLim(); - } - return ; - } - if(node->isEqual(*_e1.getEndNode())) - { - where=END; - if(_e1.changeEndNodeWith(node)) - { - commonNode.end1Replaced(); - node->declareOnLim(); - } - return ; - } - obvious=false; -} - -Edge::Edge(double sX, double sY, double eX, double eY):_cnt(1),_loc(FULL_UNKNOWN),_start(new Node(sX,sY)),_end(new Node(eX,eY)) -{ -} - -Edge::~Edge() -{ - _start->decrRef(); - if(_end) - _end->decrRef(); -} - -bool Edge::decrRef() -{ - bool ret=(--_cnt==0); - if(ret) - delete this; - return ret; -} - -void Edge::declareOn() const -{ - if(_loc==FULL_UNKNOWN) - { - _loc=FULL_ON_1; - _start->declareOn(); - _end->declareOn(); - } -} - -void Edge::declareIn() const -{ - if(_loc==FULL_UNKNOWN) - { - _loc=FULL_IN_1; - _start->declareIn(); - _end->declareIn(); - } -} - -void Edge::declareOut() const -{ - if(_loc==FULL_UNKNOWN) - { - _loc=FULL_OUT_1; - _start->declareOut(); - _end->declareOut(); - } -} - -void Edge::fillXfigStreamForLoc(std::ostream& stream) const -{ - switch(_loc) - { - case FULL_IN_1: - stream << '2';//Green - break; - case FULL_OUT_1: - stream << '1';//Bleue - break; - case FULL_ON_1: - stream << '4';//Red - break; - default: - stream << '0'; - } -} - -bool Edge::changeStartNodeWith(Node *otherStartNode) const -{ - if(_start==otherStartNode) - return true; - if(_start->isEqual(*otherStartNode)) - { - ((const_cast(this))->_start)->decrRef();//un-const cast Ok thanks to 2 lines above. - ((const_cast(this))->_start)=otherStartNode; - _start->incrRef(); - return true; - } - return false; -} - -bool Edge::changeStartNodeWithAndKeepTrack(Node *otherStartNode, std::vector& track) const -{ - if(_start==otherStartNode) - return true; - if(_start->isEqualAndKeepTrack(*otherStartNode,track)) - { - ((const_cast(this))->_start)->decrRef();//un-const cast Ok thanks to 2 lines above. - ((const_cast(this))->_start)=otherStartNode; - otherStartNode->incrRef(); - return true; - } - return false; -} - -bool Edge::changeEndNodeWith(Node *otherEndNode) const -{ - if(_end==otherEndNode) - return true; - if(_end->isEqual(*otherEndNode)) - { - ((const_cast(this))->_end)->decrRef(); - ((const_cast(this))->_end)=otherEndNode; - _end->incrRef(); - return true; - } - return false; -} - -bool Edge::changeEndNodeWithAndKeepTrack(Node *otherEndNode, std::vector& track) const -{ - if(_end==otherEndNode) - return true; - if(_end->isEqualAndKeepTrack(*otherEndNode,track)) - { - ((const_cast(this))->_end)->decrRef(); - ((const_cast(this))->_end)=otherEndNode; - otherEndNode->incrRef(); - return true; - } - return false; -} - -/*! - * Precondition : 'start' and 'end' are lying on the same curve than 'this'. - * Add in vec the sub edge lying on this. - * If 'start' is equal (by pointer) to '_end' and 'end' is equal to '_end' too nothing is added. - * If 'start' is equal (by pointer) to '_start' and 'end' is equal to '_start' too nothing is added. - * If 'start' is equal (by pointer) to '_start' and 'end' is equal to '_end' this is added in vec. - */ -void Edge::addSubEdgeInVector(Node *start, Node *end, ComposedEdge& vec) const -{ - if((start==_start && end==_start) || (start==_end && end==_end)) - return ; - if(start==_start && end==_end) - { - incrRef(); - vec.pushBack(const_cast(this)); - return ; - } - vec.pushBack(buildEdgeLyingOnMe(start,end,true)); -} - -/*! - * Retrieves a vector 'vectOutput' that is normal to 'this'. 'vectOutput' is normalized. - */ -void Edge::getNormalVector(double *vectOutput) const -{ - std::copy((const double *)(*_end),(const double *)(*_end)+2,vectOutput); - std::transform(vectOutput,vectOutput+2,(const double *)(*_start),vectOutput,std::minus()); - double norm=1./Node::norm(vectOutput); - std::transform(vectOutput,vectOutput+2,vectOutput,bind2nd(std::multiplies(),norm)); - double tmp=vectOutput[0]; - vectOutput[0]=vectOutput[1]; - 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); -} - -Edge *Edge::BuildFromXfigLine(std::istream& str) -{ - unsigned char type; - str >> type; - if(type=='2') - return new EdgeLin(str); - else if(type=='5') - return new EdgeArcCircle(str); - else - { - std::cerr << "Unknown line found..."; - return 0; - } -} - -/*! - * \param other The Edge with which we are going to intersect. - * \param commonNode Output. The common nodes found during operation of intersecting. - * \param outVal1 Output filled in case true is returned. It specifies the new or not new edges by which 'this' is replaced after intersecting op. - * \param outVal2 Output filled in case true is returned. It specifies the new or not new edges by which 'other' is replaced after intersecting op. - * return true if the intersection between this. - */ -bool Edge::intersectWith(const Edge *other, MergePoints& commonNode, - ComposedEdge& outVal1, ComposedEdge& outVal2) const -{ - bool ret=true; - Bounds *merge=_bounds.nearlyAmIIntersectingWith(other->getBounds()); - if(!merge) - return false; - delete merge; - merge=0; - EdgeIntersector *intersector=BuildIntersectorWith(this,other); - ret=Intersect(this,other,intersector,merge,commonNode,outVal1,outVal2); - delete intersector; - return ret; -} - -bool Edge::IntersectOverlapped(const Edge *f1, const Edge *f2, EdgeIntersector *intersector, MergePoints& commonNode, - ComposedEdge& outValForF1, ComposedEdge& outValForF2) -{ - bool rev=intersector->haveTheySameDirection(); - Node *f2Start=f2->getNode(rev?START:END); - Node *f2End=f2->getNode(rev?END:START); - TypeOfLocInEdge place1, place2; - intersector->getPlacements(f2Start,f2End,place1,place2,commonNode); - int codeForIntersectionCase=CombineCodes(place1,place2); - return SplitOverlappedEdges(f1,f2,f2Start,f2End,rev,codeForIntersectionCase,outValForF1,outValForF2); -} - -/*! - * Perform 1D linear interpolation. Warning distrib1 and distrib2 are expected to be in ascending mode. - */ -void Edge::Interpolate1DLin(const std::vector& distrib1, const std::vector& distrib2, std::map >& result) -{ - int nbOfV1=distrib1.size()-1; - int nbOfV2=distrib2.size()-1; - Node *n1=new Node(0.,0.); Node *n3=new Node(0.,0.); - Node *n2=new Node(0.,0.); Node *n4=new Node(0.,0.); - MergePoints commonNode; - for(int i=0;i::const_iterator iter=find_if(distrib2.begin()+1,distrib2.end(),bind2nd(std::greater_equal(),distrib1[i])); - if(iter!=distrib2.end()) - { - for(int j=(iter-1)-distrib2.begin();jsetNewCoords(distrib1[i],0.); n2->setNewCoords(distrib1[i+1],0.); - n3->setNewCoords(distrib2[j],0.); n4->setNewCoords(distrib2[j+1],0.); - ComposedEdge *f1=new ComposedEdge; - ComposedEdge *f2=new ComposedEdge; - SegSegIntersector inters(*e1,*e2); - bool b1,b2; - inters.areOverlappedOrOnlyColinears(0,b1,b2); - if(IntersectOverlapped(e1,e2,&inters,commonNode,*f1,*f2)) - { - result[i][j]=f1->getCommonLengthWith(*f2)/e1->getCurveLength(); - } - ComposedEdge::Delete(f1); ComposedEdge::Delete(f2); - e1->decrRef(); e2->decrRef(); - } - } - } - } - n1->decrRef(); n2->decrRef(); n3->decrRef(); n4->decrRef(); -} - -EdgeIntersector *Edge::BuildIntersectorWith(const Edge *e1, const Edge *e2) -{ - EdgeIntersector *ret=0; - const EdgeLin *tmp1=0; - const EdgeArcCircle *tmp2=0; - unsigned char type1=e1->getTypeOfFunc(); - e1->dynCastFunction(tmp1,tmp2); - unsigned char type2=e2->getTypeOfFunc(); - e2->dynCastFunction(tmp1,tmp2); - type1|=type2; - switch(type1) - { - case 1:// Intersection seg/seg - ret=new SegSegIntersector((const EdgeLin &)(*e1),(const EdgeLin &)(*e2)); - break; - case 5:// Intersection seg/arc of circle - ret=new ArcCSegIntersector(*tmp2,*tmp1,tmp2==e1); - break; - case 4:// Intersection arc/arc of circle - ret=new ArcCArcCIntersector((const EdgeArcCircle &)(*e1),(const EdgeArcCircle &)(*e2)); - break; - default: - //Should never happen - throw Exception("A non managed association of edge has been detected. Go work for intersection computation implementation."); - } - return ret; -} - -/*! - * See Node::applySimilarity to see signification of params. - */ -void Edge::applySimilarity(double xBary, double yBary, double dimChar) -{ - _bounds.applySimilarity(xBary,yBary,dimChar); -} - -void Edge::unApplySimilarity(double xBary, double yBary, double dimChar) -{ - _bounds.unApplySimilarity(xBary,yBary,dimChar); -} - -void Edge::getMiddleOfPointsOriented(const double *p1, const double *p2, double *mid) const -{ - return getMiddleOfPoints(p1, p2, mid); -} - -bool Edge::Intersect(const Edge *f1, const Edge *f2, EdgeIntersector *intersector, const Bounds *whereToFind, MergePoints& commonNode, - ComposedEdge& outValForF1, ComposedEdge& outValForF2) -{ - bool obviousNoIntersection; - bool areOverlapped; - intersector->areOverlappedOrOnlyColinears(whereToFind,obviousNoIntersection,areOverlapped); - if(areOverlapped) - return IntersectOverlapped(f1,f2,intersector,commonNode,outValForF1,outValForF2); - if(obviousNoIntersection) - return false; - std::vector newNodes; - bool order; - if(intersector->intersect(whereToFind,newNodes,order,commonNode)) - { - if(newNodes.empty()) - throw Exception("Internal error occured - error in intersector implementation!");// This case should never happen - std::vector::iterator iter=newNodes.begin(); - std::vector::reverse_iterator iterR=newNodes.rbegin(); - f1->addSubEdgeInVector(f1->getStartNode(),*iter,outValForF1); - f2->addSubEdgeInVector(f2->getStartNode(),order?*iter:*iterR,outValForF2); - for(std::vector::iterator iter2=newNodes.begin();iter2!=newNodes.end();iter2++,iterR++) - { - if((iter2+1)==newNodes.end()) - { - f1->addSubEdgeInVector(*iter2,f1->getEndNode(),outValForF1); - (*iter2)->decrRef(); - f2->addSubEdgeInVector(order?*iter2:*iterR,f2->getEndNode(),outValForF2); - } - else - { - f1->addSubEdgeInVector(*iter2,*(iter2+1),outValForF1); - (*iter2)->decrRef(); - f2->addSubEdgeInVector(order?*iter2:*iterR,order?*(iter2+1):*(iterR+1),outValForF2); - } - } - return true; - } - else//no intersection inside whereToFind - return false; -} - -int Edge::CombineCodes(TypeOfLocInEdge code1, TypeOfLocInEdge code2) -{ - int ret=(int)code1; - ret*=OFFSET_FOR_TYPEOFLOCINEDGE; - ret+=(int)code2; - return ret; -} - -/*! - * This method splits e1 and e2 into pieces as much sharable as possible. The precondition to the call of this method - * is that e1 and e2 have been declared as overlapped by corresponding intersector built from e1 and e2 type. - * - * @param nS start node of e2 with the SAME DIRECTION as e1. The pointer nS should be equal to start node of e2 or to its end node. - * @param nE end node of e2 with the SAME DIRECTION as e1. The pointer nE should be equal to start node of e2 or to its end node. - * @param direction is param that specifies if e2 and e1 have same directions (true) or opposed (false). - * @param code is the code returned by method Edge::combineCodes. - */ -bool Edge::SplitOverlappedEdges(const Edge *e1, const Edge *e2, Node *nS, Node *nE, bool direction, int code, - ComposedEdge& outVal1, ComposedEdge& outVal2) -{ - Edge *tmp; - switch(code) - { - case OUT_BEFORE*OFFSET_FOR_TYPEOFLOCINEDGE+START: // OUT_BEFORE - START - case OUT_BEFORE*OFFSET_FOR_TYPEOFLOCINEDGE+OUT_BEFORE: // OUT_BEFORE - OUT_BEFORE - case OUT_AFTER*OFFSET_FOR_TYPEOFLOCINEDGE+OUT_AFTER: // OUT_AFTER - OUT_AFTER - case END*OFFSET_FOR_TYPEOFLOCINEDGE+OUT_AFTER: // END - OUT_AFTER - case END*OFFSET_FOR_TYPEOFLOCINEDGE+START: // END - START - return false; - case INSIDE*OFFSET_FOR_TYPEOFLOCINEDGE+OUT_AFTER: // INSIDE - OUT_AFTER - outVal1.pushBack(e1->buildEdgeLyingOnMe(e1->getStartNode(),nS,true)); - tmp=e1->buildEdgeLyingOnMe(nS,e1->getEndNode()); tmp->incrRef(); - outVal1.pushBack(tmp); - outVal2.resize(2); - outVal2.setValueAt(direction?0:1,tmp,direction); tmp->declareOn(); - outVal2.setValueAt(direction?1:0,e1->buildEdgeLyingOnMe(e1->getEndNode(),nE,direction)); - return true; - case INSIDE*OFFSET_FOR_TYPEOFLOCINEDGE+INSIDE: // INSIDE - INSIDE - { - if(!e2->isIn(e2->getCharactValue(*(e1->getStartNode())))) - { - e2->incrRef(); e2->incrRef(); - outVal1.resize(3); - outVal1.setValueAt(0,e1->buildEdgeLyingOnMe(e1->getStartNode(),nS)); - outVal1.setValueAt(1,const_cast(e2),direction); - outVal1.setValueAt(2,e1->buildEdgeLyingOnMe(nE,e1->getEndNode())); - outVal2.pushBack(const_cast(e2)); e2->declareOn(); - return true; - } - else - { - outVal1.resize(3); - outVal2.resize(3); - tmp=e1->buildEdgeLyingOnMe(e1->getStartNode(),nE); tmp->incrRef(); tmp->declareOn(); - outVal1.setValueAt(0,tmp,true); outVal2.setValueAt(direction?2:0,tmp,direction); - outVal1.setValueAt(1,e1->buildEdgeLyingOnMe(nE,nS)); - tmp=e1->buildEdgeLyingOnMe(nS,e1->getEndNode()); tmp->incrRef(); tmp->declareOn(); - outVal1.setValueAt(2,tmp,true); outVal2.setValueAt(direction?0:2,tmp,direction); - tmp=e1->buildEdgeLyingOnMe(e1->getEndNode(),e1->getStartNode()); - outVal2.setValueAt(1,tmp,direction); - return true; - } - } - case OUT_BEFORE*OFFSET_FOR_TYPEOFLOCINEDGE+INSIDE: // OUT_BEFORE - INSIDE - { - tmp=e1->buildEdgeLyingOnMe(e1->getStartNode(),nE); tmp->incrRef(); - outVal1.pushBack(tmp); - outVal1.pushBack(e1->buildEdgeLyingOnMe(nE,e1->getEndNode())); - outVal2.resize(2); - outVal2.setValueAt(direction?0:1,e1->buildEdgeLyingOnMe(nS,e1->getStartNode(),direction)); - outVal2.setValueAt(direction?1:0,tmp,direction); tmp->declareOn(); - return true; - } - case OUT_BEFORE*OFFSET_FOR_TYPEOFLOCINEDGE+OUT_AFTER: // OUT_BEFORE - OUT_AFTER - { - e1->incrRef(); e1->incrRef(); - outVal1.pushBack(const_cast(e1)); - outVal2.resize(3); - outVal2.setValueAt(direction?0:2,e1->buildEdgeLyingOnMe(nS,e1->getStartNode(),direction)); - outVal2.setValueAt(1,const_cast(e1),direction); e1->declareOn(); - outVal2.setValueAt(direction?2:0,e1->buildEdgeLyingOnMe(e1->getEndNode(),nE,direction)); - return true; - } - case START*OFFSET_FOR_TYPEOFLOCINEDGE+END: // START - END - { - e1->incrRef(); e1->incrRef(); - outVal1.pushBack(const_cast(e1)); - outVal2.pushBack(const_cast(e1),direction); e1->declareOn(); - return true; - } - case START*OFFSET_FOR_TYPEOFLOCINEDGE+OUT_AFTER: // START - OUT_AFTER - { - e1->incrRef(); e1->incrRef(); - outVal1.pushBack(const_cast(e1)); - outVal2.resize(2); - outVal2.setValueAt(direction?0:1,const_cast(e1),direction); e1->declareOn(); - outVal2.setValueAt(direction?1:0,e1->buildEdgeLyingOnMe(e1->getEndNode(),nE,direction)); - return true; - } - case INSIDE*OFFSET_FOR_TYPEOFLOCINEDGE+END: // INSIDE - END - { - e2->incrRef(); e2->incrRef(); - outVal1.pushBack(e1->buildEdgeLyingOnMe(e1->getStartNode(),nS,true)); - outVal1.pushBack(const_cast(e2),direction); - outVal2.pushBack(const_cast(e2)); e2->declareOn(); - return true; - } - case OUT_BEFORE*OFFSET_FOR_TYPEOFLOCINEDGE+END: // OUT_BEFORE - END - { - e1->incrRef(); e1->incrRef(); - outVal1.pushBack(const_cast(e1)); - outVal2.resize(2); - outVal2.setValueAt(direction?0:1,e1->buildEdgeLyingOnMe(nS,e1->getStartNode(),direction)); - outVal2.setValueAt(direction?1:0,const_cast(e1),direction); e1->declareOn(); - return true; - } - case START*OFFSET_FOR_TYPEOFLOCINEDGE+INSIDE: // START - INSIDE - { - e2->incrRef(); e2->incrRef(); - outVal1.pushBack(const_cast(e2),direction); - outVal1.pushBack(e1->buildEdgeLyingOnMe(nE,e1->getEndNode())); - outVal2.pushBack(const_cast(e2)); e2->declareOn(); - return true; - } - case INSIDE*OFFSET_FOR_TYPEOFLOCINEDGE+START: // INSIDE - START - { - outVal1.resize(2); - outVal2.resize(2); - tmp=e1->buildEdgeLyingOnMe(nS,e1->getEndNode()); tmp->incrRef(); tmp->declareOn(); - outVal1.setValueAt(0,e1->buildEdgeLyingOnMe(e1->getStartNode(),nS)); - outVal1.setValueAt(1,tmp); - outVal2.setValueAt(direction?0:1,tmp,direction); - outVal2.setValueAt(direction?1:0,e1->buildEdgeLyingOnMe(e1->getEndNode(),nE,direction)); - return true; - } - case END*OFFSET_FOR_TYPEOFLOCINEDGE+INSIDE: // END - INSIDE - { - outVal1.resize(2); - outVal2.resize(2); - tmp=e1->buildEdgeLyingOnMe(e1->getStartNode(),nE); tmp->incrRef(); tmp->declareOn(); - outVal1.setValueAt(0,tmp); - outVal1.setValueAt(1,e1->buildEdgeLyingOnMe(nE,e1->getEndNode())); - outVal2.setValueAt(direction?0:1,e1->buildEdgeLyingOnMe(e1->getEndNode(),e1->getStartNode(),direction)); - outVal2.setValueAt(direction?1:0,tmp,direction); - return true; - } - default: - throw Exception("Unexpected situation of overlapping edges : internal error occurs ! "); - } -} - -bool Edge::isEqual(const Edge& other) const -{ - return _start->isEqual(*other._start) && _end->isEqual(*other._end); -} - -inline bool eqpair(const std::pair& p1, const std::pair& p2) -{ - return fabs(p1.first-p2.first)& subNodes) -{ - Bounds b; - b.prepareForAggregation(); - b.aggregate(getBounds()); - double xBary,yBary; - double dimChar(b.getCaracteristicDim()); - b.getBarycenter(xBary,yBary); - applySimilarity(xBary,yBary,dimChar); - _start->applySimilarity(xBary,yBary,dimChar); - _end->applySimilarity(xBary,yBary,dimChar); - // - std::size_t sz(subNodes.size()),i(0); - std::vector< std::pair > an2(sz); - std::map m; - for(std::vector::const_iterator it=subNodes.begin();it!=subNodes.end();it++,i++) - { - Node *n(new Node(coo[2*(*it)],coo[2*(*it)+1])); - n->applySimilarity(xBary,yBary,dimChar); - m[n]=*it; - an2[i]=std::pair(getCharactValueBtw0And1(*n),n); - } - std::sort(an2.begin(),an2.end()); - // - bool ret(false); - for(i=0;i::const_iterator it2=m.begin();it2!=m.end();it2++) - (*it2).first->decrRef(); - return ret; -} - -/** - * Sort nodes so that they all lie consecutively on the edge that has been cut. - */ -void Edge::sortIdsAbs(const std::vector& addNodes, const std::map& mapp1, - const std::map& mapp2, std::vector& edgesThis) -{ - Bounds b; - b.prepareForAggregation(); - b.aggregate(getBounds()); - double xBary,yBary; - double dimChar=b.getCaracteristicDim(); - b.getBarycenter(xBary,yBary); - for(std::vector::const_iterator iter=addNodes.begin();iter!=addNodes.end();iter++) - (*iter)->applySimilarity(xBary,yBary,dimChar); - applySimilarity(xBary,yBary,dimChar); - _start->applySimilarity(xBary,yBary,dimChar); - _end->applySimilarity(xBary,yBary,dimChar); - std::size_t sz=addNodes.size(); - std::vector< std::pair > an2(sz); - for(std::size_t i=0;i(getCharactValueBtw0And1(*addNodes[i]),addNodes[i]); - std::sort(an2.begin(),an2.end()); - int startId=(*mapp1.find(_start)).second; - int endId=(*mapp1.find(_end)).second; - std::vector tmpp; - std::vector< std::pair >::const_iterator itend=std::unique(an2.begin(),an2.end(),eqpair); - for(std::vector< std::pair >::const_iterator it=an2.begin();it!=itend;it++) - { - int idd=(*mapp2.find((*it).second)).second; - if((*it).first1-QUADRATIC_PLANAR::_precision) - { - endId=idd; - continue; - } - tmpp.push_back(idd); - } - std::vector tmpp2(tmpp.size()+2); - tmpp2[0]=startId; - std::copy(tmpp.begin(),tmpp.end(),tmpp2.begin()+1); - tmpp2[tmpp.size()+1]=endId; - std::vector::iterator itt=std::unique(tmpp2.begin(),tmpp2.end()); - tmpp2.resize(std::distance(tmpp2.begin(),itt)); - int nbOfEdges=tmpp2.size()-1; - for(int i=0;i -#include -#include -#include - -namespace INTERP_KERNEL -{ - typedef enum - { - SEG = 1, - ARC_CIRCLE = 4, - ARC_PARABOL = 8 - } TypeOfFunction; - - typedef enum - { - CIRCLE = 0 , - PARABOL = 1 - } TypeOfMod4QuadEdge; - - typedef enum - { - START = 5, - END = 1, - INSIDE = 2, - OUT_BEFORE = 3, - OUT_AFTER = 4 - } TypeOfLocInEdge; //see Edge::OFFSET_FOR_TYPEOFLOCINEDGE - - typedef enum - { - FULL_IN_1 = 1, - FULL_ON_1 = 4, - FULL_OUT_1 = 2, - FULL_UNKNOWN = 3 - } TypeOfEdgeLocInPolygon; - - class INTERPKERNEL_EXPORT MergePoints - { - public: - MergePoints(); - - //methods called during intersection edge-edge - void start1Replaced(); - void end1Replaced(); - void start1OnStart2(); - void start1OnEnd2(); - void end1OnStart2(); - void end1OnEnd2(); - //methods to be called during aggregation - bool isStart1(unsigned rk) const; - bool isEnd1(unsigned rk) const; - bool isStart2(unsigned rk) const; - bool isEnd2(unsigned rk) const; - void clear(); - unsigned getNumberOfAssociations() const; - void updateMergedNodes(int e1Start, int e1End, int e2Start, int e2End, std::map& mergedNodes); - private: - static void PushInMap(int key, int value, std::map& mergedNodes); - private: - unsigned _ass1Start1 : 1; - unsigned _ass1End1 : 1; - unsigned _ass1Start2 : 1; - unsigned _ass1End2 : 1; - unsigned _ass2Start1 : 1; - unsigned _ass2End1 : 1; - unsigned _ass2Start2 : 1; - unsigned _ass2End2 : 1; - }; - - class Edge; - class ComposedEdge; - /*! - * This class is in charge to store an intersection point as result of \b non oververlapping edge intersection. - * This class manages the cases when intersect element is one of the extrimities of edge1 and/or edge2. - */ - class INTERPKERNEL_EXPORT IntersectElement - { - public: - IntersectElement(double val1, double val2, bool start1, bool end1, bool start2, bool end2, Node *node, const Edge& e1, const Edge& e2, bool keepOrder); - IntersectElement(const IntersectElement& other); - //! The sort operator is done on the edge 1 \b not edge 2. - bool operator<(const IntersectElement& other) const; - IntersectElement& operator=(const IntersectElement& other); - double getVal1() const { return _chararct_val_for_e1; } - double getVal2() const { return _chararct_val_for_e2; } - //! idem operator< method except that the orientation is done on edge 2 \b not edge 1. - bool isLowerOnOther(const IntersectElement& other) const; - unsigned isOnExtrForAnEdgeAndInForOtherEdge() const; - void attachLoc() { _node->setLoc(_loc_of_node); } - bool isOnMergedExtremity() const; - bool isIncludedByBoth() const; - void setNode(Node *node) const; - void performMerging(MergePoints& commonNode) const; - Node *getNodeOnly() const { return _node; } - Node *getNodeAndReleaseIt() { Node *tmp=_node; _node=0; return tmp; } - ~IntersectElement(); - private: - bool _1S; - bool _1E; - bool _2S; - bool _2E; - double _chararct_val_for_e1; - double _chararct_val_for_e2; - Node *_node; - TypeOfLocInPolygon _loc_of_node; - const Edge& _e1; - const Edge& _e2; - public: - static const unsigned LIMIT_ALONE = 22; - static const unsigned LIMIT_ON = 73; - static const unsigned NO_LIMIT = 19; - }; - - /*! - * This abstract interface specifies all the methods to be overloaded of all possibilities edge-intersection. - */ - class INTERPKERNEL_EXPORT EdgeIntersector - { - protected: - //! All non symetric methods are relative to 'e1'. - EdgeIntersector(const Edge& e1, const Edge& e2):_e1(e1),_e2(e2) { } - public: - virtual ~EdgeIntersector() { } - virtual bool keepOrder() const = 0; - virtual bool areColinears() const = 0; - //!to call only if 'areOverlapped' have been set to true when areOverlappedOrOnlyColinears was called - virtual bool haveTheySameDirection() const = 0; - //!to call only if 'areOverlapped' have been set to true when areOverlappedOrOnlyColinears was called - virtual void getPlacements(Node *start, Node *end, TypeOfLocInEdge& whereStart, TypeOfLocInEdge& whereEnd, MergePoints& commonNode) const = 0; - //! When true is returned, newNodes should contains at least 1 element. All merging nodes betw _e1 and _e2 extremities must be done. - bool intersect(const Bounds *whereToFind, std::vector& newNodes, bool& order, MergePoints& commonNode); - //! Should be called only once per association. - virtual void areOverlappedOrOnlyColinears(const Bounds *whereToFind, bool& obviousNoIntersection, bool& areOverlapped) = 0; - //! The size of returned vector is equal to number of potential intersections point. The values are so that their are interpretable by virtual Edge::isIn method. - virtual std::list< IntersectElement > getIntersectionsCharacteristicVal() const = 0; - protected: - void obviousCaseForCurvAbscisse(Node *node, TypeOfLocInEdge& where, MergePoints& commonNode, bool& obvious) const; - protected: - const Edge& _e1; - const Edge& _e2; - }; - - class INTERPKERNEL_EXPORT SameTypeEdgeIntersector : public EdgeIntersector - { - protected: - SameTypeEdgeIntersector(const Edge& e1, const Edge& e2):EdgeIntersector(e1,e2) { } - bool keepOrder() const { return true; } - }; - - class INTERPKERNEL_EXPORT CrossTypeEdgeIntersector : public EdgeIntersector - { - protected: - CrossTypeEdgeIntersector(const Edge& e1, const Edge& e2, bool reverse):EdgeIntersector(e1,e2),_reverse(reverse) { } - bool keepOrder() const { return _reverse; } - bool haveTheySameDirection() const { throw Exception("Cross type intersector is not supposed to deal with overlapped in cross type."); } - const Edge *myE1() { if(_reverse) return &_e1; else return &_e2; } - const Edge *myE2() { if(_reverse) return &_e2; else return &_e1; } - protected: - //! boolean to inform intersector that unsymetrics treatments reverse of e1 and e2 should be done. - bool _reverse; - }; - - class EdgeLin; - class EdgeInfLin; - class EdgeArcCircle; - - /*! - * Deal with an oriented edge of a polygon. - * An Edge is defined with a start node, an end node and an equation of 1D curve. - * All other attributes are mutable because they don't impact these 3 invariant attributes. - * To be exact start and end nodes can change (address) but their location remain - * the same (at precision). - */ - class INTERPKERNEL_EXPORT Edge - { - public: - Edge(Node *start, Node *end, bool direction=true):_cnt(1),_loc(FULL_UNKNOWN) { if(direction) { _start=start; _end=end; } else { _start=end; _end=start; } _start->incrRef(); _end->incrRef(); } - Edge(double sX, double sY, double eX, double eY); - TypeOfEdgeLocInPolygon getLoc() const { return _loc; } - void incrRef() const { _cnt++; } - bool decrRef(); - void initLocs() const { _loc=FULL_UNKNOWN; _start->initLocs(); _end->initLocs(); } - void declareOn() const; - void declareIn() const; - void declareOut() const; - void initHitStatus() const { _hit=false; } - bool getHitStatus() const { return _hit; } - void hitMeAlone(double xBary, double yBary, double dimChar) { _hit=true; applySimilarity(xBary,yBary,dimChar); } - void unHitMeAlone(double xBary, double yBary, double dimChar) { _hit=true; unApplySimilarity(xBary,yBary,dimChar); } - void hitMeAfter(double xBary, double yBary, double dimChar) { if(!_hit) hitMeAlone(xBary,yBary,dimChar); } - void unHitMeAfter(double xBary, double yBary, double dimChar) { if(!_hit) unHitMeAlone(xBary,yBary,dimChar); } - const Bounds& getBounds() const { return _bounds; } - void fillXfigStreamForLoc(std::ostream& stream) const; - Node *getNode(TypeOfLocInEdge where) const { if(where==START) return _start; else if(where==END) return _end; else return 0; } - Node *getStartNode() const { return _start; } - Node *getEndNode() const { return _end; } - void setEndNodeWithoutChange(Node *newEnd); - void setStartNodeWithoutChange(Node *newStart); - bool changeStartNodeWith(Node *otherStartNode) const; - bool changeStartNodeWithAndKeepTrack(Node *otherStartNode, std::vector& track) const; - bool changeEndNodeWith(Node *otherEndNode) const; - bool changeEndNodeWithAndKeepTrack(Node *otherEndNode, std::vector& track) const; - void addSubEdgeInVector(Node *start, Node *end, ComposedEdge& vec) const; - void getNormalVector(double *vectOutput) const; - static EdgeIntersector *BuildIntersectorWith(const Edge *e1, const Edge *e2); - static Edge *BuildFromXfigLine(std::istream& str); - 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; - //! apply a similiraty transformation on 'this' - virtual void applySimilarity(double xBary, double yBary, double dimChar); - //! apply the inverse similiraty transformation on 'this' - virtual void unApplySimilarity(double xBary, double yBary, double dimChar); - //! return the length of arc. Value is always > 0. ! - virtual double getCurveLength() const = 0; - virtual void getBarycenter(double *bary) const = 0; - virtual void getBarycenterOfZone(double *bary) const = 0; - //! return the middle of two points - virtual void getMiddleOfPoints(const double *p1, const double *p2, double *mid) const = 0; - //! return the middle of two points respecting the orientation defined by this (relevant for arc of circle). By default same as getMiddleOfPoints() - virtual void getMiddleOfPointsOriented(const double *p1, const double *p2, double *mid) const; - //! Retrieves a point that is owning to this, well placed for IN/OUT detection of this. Typically midlle of this is returned. - virtual Node *buildRepresentantOfMySelf() const = 0; - //! Given a magnitude specified by sub-type returns if in or not. See getCharactValue method. - virtual bool isIn(double characterVal) const = 0; - //! With the same magnitude as defined in 'isIn' method perform a compararison. Precondition : val1 and val2 are different and exactly INSIDE this. - virtual bool isLower(double val1, double val2) const = 0; - //! node is expected to lay on 'this'. It returns a characteristic magnitude usable by isIn method. - virtual double getCharactValue(const Node& node) const = 0; - //! node is expected to lay on 'this'. It returns a characteristic magnitude between 0 and 1. - virtual double getCharactValueBtw0And1(const Node& node) const = 0; - //! retrieves the distance to this : The min distance from pt and any point of this. - virtual double getDistanceToPoint(const double *pt) const = 0; - //! return if node with coords 'coordOfNode' is on this (with precision). - virtual bool isNodeLyingOn(const double *coordOfNode) const = 0; - virtual TypeOfFunction getTypeOfFunc() const = 0; - virtual void dynCastFunction(const EdgeLin * &seg, - const EdgeArcCircle * &arcSeg) const = 0; - bool intersectWith(const Edge *other, MergePoints& commonNode, - ComposedEdge& outVal1, ComposedEdge& outVal2) const; - static bool IntersectOverlapped(const Edge *f1, const Edge *f2, EdgeIntersector *intersector, MergePoints& commonNode, - ComposedEdge& outValForF1, ComposedEdge& outValForF2); - static void Interpolate1DLin(const std::vector& distrib1, const std::vector& distrib2, - std::map >& result); - virtual void dumpInXfigFile(std::ostream& stream, bool direction, int resolution, const Bounds& box) const = 0; - bool isEqual(const Edge& other) const; - public: - bool sortSubNodesAbs(const double *coo, std::vector& subNodes); - void sortIdsAbs(const std::vector& addNodes, const std::map& mapp1, const std::map& mapp2, std::vector& edgesThis); - virtual void fillGlobalInfoAbs(bool direction, const std::map& mapThis, const std::map& mapOther, int offset1, int offset2, double fact, double baryX, double baryY, - std::vector& edgesThis, std::vector& addCoo, std::map mapAddCoo) const = 0; - virtual void fillGlobalInfoAbs2(const std::map& mapThis, const std::map& mapOther, int offset1, int offset2, double fact, double baryX, double baryY, - std::vector& edgesOther, std::vector& addCoo, std::map& mapAddCoo) const = 0; - virtual Edge *buildEdgeLyingOnMe(Node *start, Node *end, bool direction=true) const = 0; - protected: - Edge():_cnt(1),_loc(FULL_UNKNOWN),_start(0),_end(0) { } - virtual ~Edge(); - static int CombineCodes(TypeOfLocInEdge code1, TypeOfLocInEdge code2); - static bool Intersect(const Edge *f1, const Edge *f2, EdgeIntersector *intersector, const Bounds *whereToFind, MergePoints& commonNode, - ComposedEdge& outValForF1, ComposedEdge& outValForF2); - //! The code 'code' is built by method combineCodes - static bool SplitOverlappedEdges(const Edge *e1, const Edge *e2, Node *nS, Node *nE, bool direction, int code, - ComposedEdge& outVal1, ComposedEdge& outVal2); - protected: - mutable bool _hit; - mutable unsigned char _cnt; - mutable TypeOfEdgeLocInPolygon _loc; - Bounds _bounds; - Node *_start; - Node *_end; - protected: - //In relation with max possible value of TypeOfLocInEdge. - static const int OFFSET_FOR_TYPEOFLOCINEDGE = 8; - }; -} - -#endif diff --git a/src/INTERP_KERNEL/Geometric2D/InterpKernelGeo2DEdge.txx b/src/INTERP_KERNEL/Geometric2D/InterpKernelGeo2DEdge.txx deleted file mode 100644 index c76b18134..000000000 --- a/src/INTERP_KERNEL/Geometric2D/InterpKernelGeo2DEdge.txx +++ /dev/null @@ -1,31 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 -// 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 __INTERPKERNELGEO2DEDGE_TXX__ -#define __INTERPKERNELGEO2DEDGE_TXX__ - -#include "InterpKernelGeo2DEdgeArcCircle.hxx" - -template -INTERP_KERNEL::Edge *INTERP_KERNEL::Edge::BuildEdgeFrom(Node *start, Node *middle, Node *end) -{ - return new INTERP_KERNEL::EdgeArcCircle(start,middle,end); -} - -#endif diff --git a/src/INTERP_KERNEL/Geometric2D/InterpKernelGeo2DEdgeArcCircle.cxx b/src/INTERP_KERNEL/Geometric2D/InterpKernelGeo2DEdgeArcCircle.cxx deleted file mode 100644 index 491ff1578..000000000 --- a/src/INTERP_KERNEL/Geometric2D/InterpKernelGeo2DEdgeArcCircle.cxx +++ /dev/null @@ -1,841 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 -// 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 "InterpKernelGeo2DEdgeArcCircle.hxx" -#include "InterpKernelGeo2DEdgeLin.hxx" -#include "InterpKernelException.hxx" -#include "InterpKernelGeo2DNode.hxx" -#include "NormalizedUnstructuredMesh.hxx" - -#include -#include - -using namespace INTERP_KERNEL; - -ArcCArcCIntersector::ArcCArcCIntersector(const EdgeArcCircle& e1, const EdgeArcCircle& e2):SameTypeEdgeIntersector(e1,e2),_dist(0.) -{ -} - -bool ArcCArcCIntersector::haveTheySameDirection() const -{ - return (getE1().getAngle()>0. && getE2().getAngle()>0.) || (getE1().getAngle()<0. && getE2().getAngle()<0.); -} - -bool ArcCArcCIntersector::areColinears() const -{ - double radiusL,radiusB; - double centerL[2],centerB[2]; - double tmp,cst; - return internalAreColinears(getE1(),getE2(),tmp,cst,radiusL,centerL,radiusB,centerB); -} - -/*! - * Precondition 'start' and 'end' are on the same curve than this. - */ -void ArcCArcCIntersector::getPlacements(Node *start, Node *end, TypeOfLocInEdge& whereStart, TypeOfLocInEdge& whereEnd, MergePoints& commonNode) const -{ - bool obvious1,obvious2; - obviousCaseForCurvAbscisse(start,whereStart,commonNode,obvious1); - obviousCaseForCurvAbscisse(end,whereEnd,commonNode,obvious2); - if(obvious1 && obvious2) - return ; - double angleInRadStart=getAngle(start); - double angleInRadEnd=getAngle(end); - if(obvious1 || obvious2) - { - if(obvious1) - { - if(EdgeArcCircle::IsIn2Pi(getE1().getAngle0(),getE1().getAngle(),angleInRadEnd)) - whereEnd=INSIDE; - else - whereEnd=OUT_AFTER; - return ; - } - else - { - if(EdgeArcCircle::IsIn2Pi(getE1().getAngle0(),getE1().getAngle(),angleInRadStart)) - whereStart=INSIDE; - else - whereStart=OUT_BEFORE; - return ; - } - } - if(EdgeArcCircle::IsIn2Pi(getE1().getAngle0(),getE1().getAngle(),angleInRadStart)) - { - whereStart=INSIDE; - if(EdgeArcCircle::IsIn2Pi(getE1().getAngle0(),getE1().getAngle(),angleInRadEnd)) - whereEnd=INSIDE; - else - whereEnd=OUT_AFTER; - } - else - {//we are out in start. - if(EdgeArcCircle::IsIn2Pi(getE1().getAngle0(),getE1().getAngle(),angleInRadEnd)) - { - whereStart=OUT_BEFORE; - whereEnd=INSIDE; - } - else - { - if(EdgeArcCircle::IsIn2Pi(getE2().getAngle0(),getE2().getAngle(),getE1().getAngle0())) - {//_e2 contains stictly _e1 - whereStart=OUT_BEFORE; - whereEnd=OUT_AFTER; - } - else - {//_e2 is outside from _e1 - whereStart=OUT_BEFORE; - whereEnd=OUT_BEFORE; - } - } - } -} - -/*! - * Return angle between ]-Pi;Pi[ - */ -double ArcCArcCIntersector::getAngle(Node *node) const -{ - return EdgeArcCircle::GetAbsoluteAngleOfNormalizedVect(((*node)[0]-getE1().getCenter()[0])/getE1().getRadius(),((*node)[1]-getE1().getCenter()[1])/getE1().getRadius()); -} - -bool ArcCArcCIntersector::internalAreColinears(const EdgeArcCircle& a1, const EdgeArcCircle& a2, double& distBetweenCenters, double& cst, - double& radiusL, double centerL[2], double& radiusB, double centerB[2]) -{ - double lgth1=fabs(a1.getAngle()*a1.getRadius()); - double lgth2=fabs(a2.getAngle()*a2.getRadius()); - if(lgth1getInterceptedArc(centerL,radiusL,angle0L,angleL); - delete merge; - // - tmp=sqrt(tmp); - if(Node::areDoubleEqualsWP(tmp,0.,1/(10*std::max(radiusL,radiusB)))) - return Node::areDoubleEquals(radiusL,radiusB); - double phi=EdgeArcCircle::GetAbsoluteAngleOfNormalizedVect((centerL[0]-centerB[0])/tmp,(centerL[1]-centerB[1])/tmp); - double cst2=2*radiusL*tmp/(radiusB*radiusB); - double cmpContainer[4]; - int sizeOfCmpContainer=2; - cmpContainer[0]=cst+cst2*cos(phi-angle0L); - cmpContainer[1]=cst+cst2*cos(phi-angle0L+angleL); - double a=EdgeArcCircle::NormalizeAngle(phi-angle0L); - if(EdgeArcCircle::IsIn2Pi(angle0L,angleL,a)) - cmpContainer[sizeOfCmpContainer++]=cst+cst2; - a=EdgeArcCircle::NormalizeAngle(phi-angle0L+M_PI); - if(EdgeArcCircle::IsIn2Pi(angle0L,angleL,a)) - cmpContainer[sizeOfCmpContainer++]=cst-cst2; - a=*std::max_element(cmpContainer,cmpContainer+sizeOfCmpContainer); - return Node::areDoubleEqualsWP(a,1.,2.); -} - -void ArcCArcCIntersector::areOverlappedOrOnlyColinears(const Bounds *whereToFind, bool& obviousNoIntersection, bool& areOverlapped) -{ - _dist=Node::distanceBtw2Pt(getE1().getCenter(),getE2().getCenter()); - double radius1=getE1().getRadius(); double radius2=getE2().getRadius(); - if(_dist>radius1+radius2+QUADRATIC_PLANAR::_precision || _dist+std::min(radius1,radius2)+QUADRATIC_PLANAR::_precision ArcCArcCIntersector::getIntersectionsCharacteristicVal() const -{ - std::list< IntersectElement > ret; - const double *center1=getE1().getCenter(); - const double *center2=getE2().getCenter(); - double radius1=getE1().getRadius(); double radius2=getE2().getRadius(); - double d1_1=(_dist*_dist-radius2*radius2+radius1*radius1)/(2.*_dist); - double u[2];//u is normalized vector from center1 to center2. - u[0]=(center2[0]-center1[0])/_dist; u[1]=(center2[1]-center1[1])/_dist; - double d1_1y=EdgeArcCircle::SafeSqrt(radius1*radius1-d1_1*d1_1); - double angleE1=EdgeArcCircle::NormalizeAngle(getE1().getAngle0()+getE1().getAngle()); - double angleE2=EdgeArcCircle::NormalizeAngle(getE2().getAngle0()+getE2().getAngle()); - if(!Node::areDoubleEquals(d1_1y,0)) - { - //2 intersections - double v1[2],v2[2]; - v1[0]=u[0]*d1_1-u[1]*d1_1y; v1[1]=u[1]*d1_1+u[0]*d1_1y; - v2[0]=u[0]*d1_1+u[1]*d1_1y; v2[1]=u[1]*d1_1-u[0]*d1_1y; - Node *node1=new Node(center1[0]+v1[0],center1[1]+v1[1]); node1->declareOn(); - Node *node2=new Node(center1[0]+v2[0],center1[1]+v2[1]); node2->declareOn(); - double angle1_1=EdgeArcCircle::GetAbsoluteAngleOfNormalizedVect(v1[0]/radius1,v1[1]/radius1); - double angle2_1=EdgeArcCircle::GetAbsoluteAngleOfNormalizedVect(v2[0]/radius1,v2[1]/radius1); - double v3[2],v4[2]; - v3[0]=center1[0]-center2[0]+v1[0]; v3[1]=center1[1]-center2[1]+v1[1]; - v4[0]=center1[0]-center2[0]+v2[0]; v4[1]=center1[1]-center2[1]+v2[1]; - double angle1_2=EdgeArcCircle::GetAbsoluteAngleOfNormalizedVect(v3[0]/radius2,v3[1]/radius2); - double angle2_2=EdgeArcCircle::GetAbsoluteAngleOfNormalizedVect(v4[0]/radius2,v4[1]/radius2); - // - bool e1_1S=Node::areDoubleEqualsWP(angle1_1,getE1().getAngle0(),radius1); - bool e1_1E=Node::areDoubleEqualsWP(angle1_1,angleE1,radius1); - bool e1_2S=Node::areDoubleEqualsWP(angle1_2,getE2().getAngle0(),radius1); - bool e1_2E=Node::areDoubleEqualsWP(angle1_2,angleE2,radius1); - // - bool e2_1S=Node::areDoubleEqualsWP(angle2_1,getE1().getAngle0(),radius2); - bool e2_1E=Node::areDoubleEqualsWP(angle2_1,angleE1,radius2); - bool e2_2S=Node::areDoubleEqualsWP(angle2_2,getE2().getAngle0(),radius2); - bool e2_2E=Node::areDoubleEqualsWP(angle2_2,angleE2,radius2); - ret.push_back(IntersectElement(angle1_1,angle1_2,e1_1S,e1_1E,e1_2S,e1_2E,node1,_e1,_e2,keepOrder())); - ret.push_back(IntersectElement(angle2_1,angle2_2,e2_1S,e2_1E,e2_2S,e2_2E,node2,_e1,_e2,keepOrder())); - } - else - { - //tangent intersection - double v1[2],v2[2]; - v1[0]=d1_1*u[0]; v1[1]=d1_1*u[1]; - v2[0]=center1[0]-center2[0]+v1[0]; v2[1]=center1[1]-center2[1]+v1[1]; - double angle0_1=EdgeArcCircle::GetAbsoluteAngleOfNormalizedVect(v1[0]/radius1,v1[1]/radius1); - double angle0_2=EdgeArcCircle::GetAbsoluteAngleOfNormalizedVect(v2[0]/radius2,v2[1]/radius2); - bool e0_1S=Node::areDoubleEqualsWP(angle0_1,getE1().getAngle0(),radius1); - bool e0_1E=Node::areDoubleEqualsWP(angle0_1,angleE1,radius1); - bool e0_2S=Node::areDoubleEqualsWP(angle0_2,getE2().getAngle0(),radius2); - bool e0_2E=Node::areDoubleEqualsWP(angle0_2,angleE2,radius2); - Node *node=new Node(center1[0]+d1_1*u[0],center1[1]+d1_1*u[1]); node->declareOnTangent(); - ret.push_back(IntersectElement(angle0_1,angle0_2,e0_1S,e0_1E,e0_2S,e0_2E,node,_e1,_e2,keepOrder())); - } - return ret; -} -/*double angle0_2; - double signDeltaAngle2; - double d1_2; - if(u[1]<0.) - angle0_1=-angle0_1; - if(d1_1>=0.) - { - if(_dist>radius1) - { - angle0_2=angle0_1+M_PI; - signDeltaAngle2=-1.; - } - else - { - angle0_2=angle0_1; - signDeltaAngle2=1.; - } - } - else - { - angle0_1+=M_PI; - angle0_2=angle0_1; - signDeltaAngle2=1.; - } - angle0_1=NormalizeAngle(angle0_1); - angle0_2=NormalizeAngle(angle0_2); - double angleE1=NormalizeAngle(getE1().getAngle0()+getE1().getAngle()); - double angleE2=NormalizeAngle(getE2().getAngle0()+getE2().getAngle()); - if(!(Node::areDoubleEquals(d1_1,radius1) || Node::areDoubleEquals(d1_1,-radius1)) ) - { - //2 intersections - double deltaAngle1=EdgeArcCircle::SafeAcos(fabs(d1_1)/radius1); //owns to 0;Pi/2 by construction - double deltaAngle2=EdgeArcCircle::SafeAcos(fabs(d1_2)/radius2); //owns to 0;Pi/2 by construction - double angle1_1=NormalizeAngle(angle0_1+deltaAngle1);// Intersection 1 seen for _e1 - double angle2_1=NormalizeAngle(angle0_1-deltaAngle1);// Intersection 2 seen for _e1 - double angle1_2=NormalizeAngle(angle0_2+signDeltaAngle2*deltaAngle2);// Intersection 1 seen for _e2 - double angle2_2=NormalizeAngle(angle0_2-signDeltaAngle2*deltaAngle2);// Intersection 2 seen for _e2 - // - bool e1_1S=Node::areDoubleEqualsWP(angle1_1,getE1().getAngle0(),radius1); - bool e1_1E=Node::areDoubleEqualsWP(angle1_1,angleE1,radius1); - bool e1_2S=Node::areDoubleEqualsWP(angle1_2,getE2().getAngle0(),radius1); - bool e1_2E=Node::areDoubleEqualsWP(angle1_2,angleE2,radius1); - // - bool e2_1S=Node::areDoubleEqualsWP(angle2_1,getE1().getAngle0(),radius2); - bool e2_1E=Node::areDoubleEqualsWP(angle2_1,angleE1,radius2); - bool e2_2S=Node::areDoubleEqualsWP(angle2_2,getE2().getAngle0(),radius2); - bool e2_2E=Node::areDoubleEqualsWP(angle2_2,angleE2,radius2); - Node *node1=new Node(center1[0]+radius1*cos(angle1_1),center1[0]+radius1*sin(angle1_1)); node1->declareOn(); - Node *node2=new Node(center1[0]+radius1*cos(angle2_1),center1[0]+radius1*sin(angle2_1)); node2->declareOn(); - ret.push_back(IntersectElement(angle1_1,angle1_2,e1_1S,e1_1E,e1_2S,e1_2E,node1,_e1,_e2,keepOrder())); - ret.push_back(IntersectElement(angle2_1,angle2_2,e2_1S,e2_1E,e2_2S,e2_2E,node2,_e1,_e2,keepOrder())); - } - else - //tangent intersection - { - bool e0_1S=Node::areDoubleEqualsWP(angle0_1,getE1().getAngle0(),radius1); - bool e0_1E=Node::areDoubleEqualsWP(angle0_1,angleE1,radius1); - bool e0_2S=Node::areDoubleEqualsWP(angle0_2,getE2().getAngle0(),radius2); - bool e0_2E=Node::areDoubleEqualsWP(angle0_2,angleE2,radius2); - Node *node=new Node(center1[0]+radius1*cos(angle0_1),center1[0]+radius1*sin(angle0_1)); node->declareOnTangent(); - ret.push_back(IntersectElement(angle0_1,angle0_2,e0_1S,e0_1E,e0_2S,e0_2E,node,_e1,_e2,keepOrder())); - } - return ret;*/ - -ArcCSegIntersector::ArcCSegIntersector(const EdgeArcCircle& e1, const EdgeLin& e2, bool reverse):CrossTypeEdgeIntersector(e1,e2,reverse) -{ -} - -void ArcCSegIntersector::areOverlappedOrOnlyColinears(const Bounds *whereToFind, bool& obviousNoIntersection, bool& areOverlapped) -{ - areOverlapped=false;//No overlapping by construction - const double *center=getE1().getCenter(); - _dx=(*(_e2.getEndNode()))[0]-(*(_e2.getStartNode()))[0]; - _dy=(*(_e2.getEndNode()))[1]-(*(_e2.getStartNode()))[1]; - _drSq=_dx*_dx+_dy*_dy; - _cross= - ((*(_e2.getStartNode()))[0]-center[0])*((*(_e2.getEndNode()))[1]-center[1])- - ((*(_e2.getStartNode()))[1]-center[1])*((*(_e2.getEndNode()))[0]-center[0]); - _determinant=getE1().getRadius()*getE1().getRadius()/_drSq-_cross*_cross/(_drSq*_drSq); - if(_determinant>-2*QUADRATIC_PLANAR::_precision)//QUADRATIC_PLANAR::_precision*QUADRATIC_PLANAR::_precision*_drSq*_drSq/(2.*_dx*_dx)) - obviousNoIntersection=false; - else - obviousNoIntersection=true; -} - -/*! - * By construction, no chance that an arc of circle and line to be colinear. - */ -bool ArcCSegIntersector::areColinears() const -{ - return false; -} - -void ArcCSegIntersector::getPlacements(Node *start, Node *end, TypeOfLocInEdge& whereStart, TypeOfLocInEdge& whereEnd, MergePoints& commonNode) const -{ - throw Exception("Internal error. Should never been called : no overlapping possible between arc of circle and a segment."); -} - -std::list< IntersectElement > ArcCSegIntersector::getIntersectionsCharacteristicVal() const -{ - std::list< IntersectElement > ret; - const double *center=getE1().getCenter(); - if(!(fabs(_determinant)<(2.*QUADRATIC_PLANAR::_precision)))//QUADRATIC_PLANAR::_precision*QUADRATIC_PLANAR::_precision*_drSq*_drSq/(2.*_dx*_dx)) - { - double determinant=EdgeArcCircle::SafeSqrt(_determinant); - double x1=(_cross*_dy/_drSq+Node::sign(_dy)*_dx*determinant)+center[0]; - double y1=(-_cross*_dx/_drSq+fabs(_dy)*determinant)+center[1]; - Node *intersect1=new Node(x1,y1); intersect1->declareOn(); - bool i1_1S=_e1.getStartNode()->isEqual(*intersect1); - bool i1_1E=_e1.getEndNode()->isEqual(*intersect1); - bool i1_2S=_e2.getStartNode()->isEqual(*intersect1); - bool i1_2E=_e2.getEndNode()->isEqual(*intersect1); - ret.push_back(IntersectElement(getE1().getCharactValue(*intersect1),getE2().getCharactValue(*intersect1),i1_1S,i1_1E,i1_2S,i1_2E,intersect1,_e1,_e2,keepOrder())); - // - double x2=(_cross*_dy/_drSq-Node::sign(_dy)*_dx*determinant)+center[0]; - double y2=(-_cross*_dx/_drSq-fabs(_dy)*determinant)+center[1]; - Node *intersect2=new Node(x2,y2); intersect2->declareOn(); - bool i2_1S=_e1.getStartNode()->isEqual(*intersect2); - bool i2_1E=_e1.getEndNode()->isEqual(*intersect2); - bool i2_2S=_e2.getStartNode()->isEqual(*intersect2); - bool i2_2E=_e2.getEndNode()->isEqual(*intersect2); - ret.push_back(IntersectElement(getE1().getCharactValue(*intersect2),getE2().getCharactValue(*intersect2),i2_1S,i2_1E,i2_2S,i2_2E,intersect2,_e1,_e2,keepOrder())); - } - else//tangent intersection - { - double x=(_cross*_dy)/_drSq+center[0]; - double y=(-_cross*_dx)/_drSq+center[1]; - Node *intersect3=new Node(x,y); intersect3->declareOnTangent(); - bool i_1S=_e1.getStartNode()->isEqual(*intersect3); - bool i_1E=_e1.getEndNode()->isEqual(*intersect3); - bool i_2S=_e2.getStartNode()->isEqual(*intersect3); - bool i_2E=_e2.getEndNode()->isEqual(*intersect3); - ret.push_back(IntersectElement(_e1.getCharactValue(*intersect3),_e2.getCharactValue(*intersect3),i_1S,i_1E,i_2S,i_2E,intersect3,_e1,_e2,keepOrder())); - } - return ret; -} - -EdgeArcCircle::EdgeArcCircle(std::istream& lineInXfig) -{ - const unsigned NB_OF_SKIP_FIELDS=15; - std::string tmpS; - for(unsigned i=0;i> tmpS; - _start=new Node(lineInXfig); - Node *middle=new Node(lineInXfig); - _end=new Node(lineInXfig); - GetArcOfCirclePassingThru(*_start,*middle,*_end,_center,_radius,_angle,_angle0); - middle->decrRef(); - updateBounds(); -} - -EdgeArcCircle::EdgeArcCircle(Node *start, Node *middle, Node *end, bool direction):Edge(start,end, direction) -{ - GetArcOfCirclePassingThru(*_start,*middle,*_end,_center,_radius,_angle,_angle0); - updateBounds(); -} - -EdgeArcCircle::EdgeArcCircle(double sX, double sY, double mX, double mY, double eX, double eY):Edge(sX,sY,eX,eY) -{ - double middle[2]; middle[0]=mX; middle[1]=mY; - GetArcOfCirclePassingThru(*_start,middle,*_end,_center,_radius,_angle,_angle0); - updateBounds(); -} - -/*! - * @param angle0 in ]-Pi;Pi[ - * @param deltaAngle in ]-2.*Pi;2.*Pi[ - */ -EdgeArcCircle::EdgeArcCircle(Node *start, Node *end, const double *center, double radius, double angle0, double deltaAngle, bool direction):Edge(start,end,direction),_angle(deltaAngle), - _angle0(angle0),_radius(radius) -{ - _center[0]=center[0]; - _center[1]=center[1]; - updateBounds(); -} - -void EdgeArcCircle::changeMiddle(Node *newMiddle) -{ - GetArcOfCirclePassingThru(*_start,*newMiddle,*_end,_center,_radius,_angle,_angle0); - updateBounds(); -} - -Edge *EdgeArcCircle::buildEdgeLyingOnMe(Node *start, Node *end, bool direction) const -{ - double sx=((*start)[0]-_center[0])/_radius; - double sy=((*start)[1]-_center[1])/_radius; - double ex=((*end)[0]-_center[0])/_radius; - double ey=((*end)[1]-_center[1])/_radius; - double angle0=GetAbsoluteAngleOfNormalizedVect(direction?sx:ex,direction?sy:ey); - double deltaAngle=GetAbsoluteAngleOfNormalizedVect(sx*ex+sy*ey,sx*ey-sy*ex); - if(deltaAngle>0. && _angle<0.) - deltaAngle-=2.*M_PI; - else if(deltaAngle<0. && _angle>0.) - deltaAngle+=2.*M_PI; - deltaAngle=direction?deltaAngle:-deltaAngle; - return new EdgeArcCircle(start,end,_center,_radius,angle0,deltaAngle,direction); -} - -void EdgeArcCircle::applySimilarity(double xBary, double yBary, double dimChar) -{ - Edge::applySimilarity(xBary,yBary,dimChar); - _radius/=dimChar; - _center[0]=(_center[0]-xBary)/dimChar; - _center[1]=(_center[1]-yBary)/dimChar; -} - -void EdgeArcCircle::unApplySimilarity(double xBary, double yBary, double dimChar) -{ - Edge::unApplySimilarity(xBary,yBary,dimChar); - _radius*=dimChar; - _center[0]=_center[0]*dimChar+xBary; - _center[1]=_center[1]*dimChar+yBary; -} - -/*! - * 'eps' is expected to be > 0. - * 'conn' is of size 3. conn[0] is start id, conn[1] is end id and conn[2] is middle id. - * 'offset' is typically the number of nodes already existing in global 2D curve mesh. Additionnal coords 'addCoo' ids will be put after the already existing. - */ -void EdgeArcCircle::tesselate(const int *conn, int offset, double eps, std::vector& newConn, std::vector& addCoo) const -{ - newConn.push_back(INTERP_KERNEL::NORM_POLYL); - int nbOfSubDiv=(int)(fabs(_angle)/eps); - if(nbOfSubDiv<=2) - { - newConn.push_back(conn[0]); newConn.push_back(conn[2]); newConn.push_back(conn[1]); - return ; - } - double signOfAngle=_angle>0.?1.:-1.; - int offset2=offset+((int)addCoo.size())/2; - newConn.push_back(conn[0]); - for(int i=1;idecrRef(); middle->decrRef(); end->decrRef(); - return 0; - } - else - { - EdgeArcCircle *ret=new EdgeArcCircle(start,middle,end); - start->decrRef(); middle->decrRef(); end->decrRef(); - return ret; - } -} - -/*! - * Given an \b NON normalized vector 'vect', returns its norm 'normVect' and its - * angle in ]-Pi,Pi] relative to Ox axe. - */ -double EdgeArcCircle::GetAbsoluteAngle(const double *vect, double& normVect) -{ - normVect=Node::norm(vect); - return GetAbsoluteAngleOfNormalizedVect(vect[0]/normVect,vect[1]/normVect); -} - -/*! - * Given a \b normalized vector defined by (ux,uy) returns its angle in ]-Pi;Pi]. - * So before using this method ux*ux+uy*uy should as much as possible close to 1. - * This methods is quite time consuming in order to keep as much as possible precision. - * It is NOT ALWAYS possible to do that only in one call of acos. Sometimes call to asin is necessary - * due to imperfection of acos near 0. and Pi (cos x ~ 1-x*x/2.) - */ -double EdgeArcCircle::GetAbsoluteAngleOfNormalizedVect(double ux, double uy) -{ - return atan2(uy, ux); -} - -void EdgeArcCircle::GetArcOfCirclePassingThru(const double *start, const double *middle, const double *end, - double *center, double& radius, double& angleInRad, double& angleInRad0) -{ - double delta=(middle[0]-start[0])*(end[1]-middle[1])-(end[0]-middle[0])*(middle[1]-start[1]); - double b1=(middle[1]*middle[1]+middle[0]*middle[0]-start[0]*start[0]-start[1]*start[1])/2; - double b2=(end[1]*end[1]+end[0]*end[0]-middle[0]*middle[0]-middle[1]*middle[1])/2; - center[0]=((end[1]-middle[1])*b1+(start[1]-middle[1])*b2)/delta; - center[1]=((middle[0]-end[0])*b1+(middle[0]-start[0])*b2)/delta; - radius=SafeSqrt((start[0]-center[0])*(start[0]-center[0])+(start[1]-center[1])*(start[1]-center[1])); - angleInRad0=GetAbsoluteAngleOfNormalizedVect((start[0]-center[0])/radius,(start[1]-center[1])/radius); - double angleInRadM=GetAbsoluteAngleOfNormalizedVect((middle[0]-center[0])/radius,(middle[1]-center[1])/radius); - angleInRad=GetAbsoluteAngleOfNormalizedVect(((start[0]-center[0])*(end[0]-center[0])+(start[1]-center[1])*(end[1]-center[1]))/(radius*radius), - ((start[0]-center[0])*(end[1]-center[1])-(start[1]-center[1])*(end[0]-center[0]))/(radius*radius)); - if(IsAngleNotIn(angleInRad0,angleInRad,angleInRadM)) - angleInRad=angleInRad<0?2*M_PI+angleInRad:angleInRad-2*M_PI; -} - -void EdgeArcCircle::dumpInXfigFile(std::ostream& stream, bool direction, int resolution, const Bounds& box) const -{ - stream << "5 1 0 1 "; - fillXfigStreamForLoc(stream); - stream << " 7 50 -1 -1 0.000 0 "; - if( (direction && (-_angle)>=0) || (!direction && (-_angle)<0)) - stream << '0';//'0' - else - stream << '1';//'1' - stream << " 1 0 "; - stream << box.fitXForXFigD(_center[0],resolution) << " " << box.fitYForXFigD(_center[1],resolution) << " "; - direction?_start->dumpInXfigFile(stream,resolution,box):_end->dumpInXfigFile(stream,resolution,box); - Node *middle=buildRepresentantOfMySelf(); - middle->dumpInXfigFile(stream,resolution,box); - middle->decrRef(); - direction?_end->dumpInXfigFile(stream,resolution,box):_start->dumpInXfigFile(stream,resolution,box); - stream << std::endl << "1 1 2.00 120.00 180.00" << std::endl; -} - -void EdgeArcCircle::update(Node *m) -{ - GetArcOfCirclePassingThru(*_start,*m,*_end,_center,_radius,_angle,_angle0); - updateBounds(); -} - -/*! - * This methods computes : - * \f[ - * \int_{Current Edge} -ydx - * \f] - */ -double EdgeArcCircle::getAreaOfZone() const -{ - return -_radius*_radius*(sin(_angle)-_angle)/2.+((*_start)[0]-(*_end)[0])*((*_start)[1]+(*_end)[1])/2.; -} - -double EdgeArcCircle::getCurveLength() const -{ - return fabs(_angle*_radius); -} - -void EdgeArcCircle::getBarycenter(double *bary) const -{ - bary[0]=_center[0]+_radius*cos(_angle0+_angle/2.); - bary[1]=_center[1]+_radius*sin(_angle0+_angle/2.); -} - -/*! - * \f[ - * bary[0]=\int_{Current Edge} -yxdx - * \f] - * \f[ - * bary[1]=\int_{Current Edge} -\frac{y^{2}}{2}dx - * \f] - * To compute these 2 expressions in this class we have : - * \f[ - * x=x_{0}+Radius \cdot cos(\theta) - * \f] - * \f[ - * y=y_{0}+Radius \cdot sin(\theta) - * \f] - * \f[ - * dx=-Radius \cdot sin(\theta) \cdot d\theta - * \f] - */ -void EdgeArcCircle::getBarycenterOfZone(double *bary) const -{ - double x0=_center[0]; - double y0=_center[1]; - double angle1=_angle0+_angle; - double tmp1=sin(angle1); - double tmp0=sin(_angle0); - double tmp2=_radius*_radius*_radius; - double tmp3=cos(angle1); - double tmp4=cos(_angle0); - bary[0]=_radius*x0*y0*(tmp4-tmp3)+_radius*_radius*(y0*(cos(2*_angle0)-cos(2*angle1))/4.+ - x0*(_angle/2.+(sin(2.*_angle0)-sin(2.*angle1))/4.)) - +tmp2*(tmp1*tmp1*tmp1-tmp0*tmp0*tmp0)/3.; - bary[1]=y0*y0*_radius*(tmp4-tmp3)/2.+_radius*_radius*y0*(_angle/2.+(sin(2.*_angle0)-sin(2.*angle1))/4.) - +tmp2*(tmp4-tmp3+(tmp3*tmp3*tmp3-tmp4*tmp4*tmp4)/3.)/2.; -} - -/** - * Compute the "middle" of two points on the arc of circle. - * The order (p1,p2) or (p2,p1) doesn't matter. p1 and p2 have to be localized on the edge defined by this. - * \param[out] mid the point located half-way between p1 and p2 on the arc defined by this. - * \sa getMiddleOfPointsOriented() a generalisation working also when p1 and p2 are not on the arc. - */ -void EdgeArcCircle::getMiddleOfPoints(const double *p1, const double *p2, double *mid) const -{ - double dx1((p1[0]-_center[0])/_radius),dy1((p1[1]-_center[1])/_radius),dx2((p2[0]-_center[0])/_radius),dy2((p2[1]-_center[1])/_radius); - double angle1(GetAbsoluteAngleOfNormalizedVect(dx1,dy1)),angle2(GetAbsoluteAngleOfNormalizedVect(dx2,dy2)); - // - double myDelta1(angle1-_angle0),myDelta2(angle2-_angle0); - if(_angle>0.) - { myDelta1=myDelta1>-QUADRATIC_PLANAR::_precision?myDelta1:myDelta1+2.*M_PI; myDelta2=myDelta2>-QUADRATIC_PLANAR::_precision?myDelta2:myDelta2+2.*M_PI; } - else - { myDelta1=myDelta1_angle (i.e. by the orientation of the arc). - * This function is sensitive to the ordering of p1 and p2. - * \param[out] mid the point located half-way between p1 and p2 - * \sa getMiddleOfPoints() to be used when the order of p1 and p2 is not relevant. - */ -void EdgeArcCircle::getMiddleOfPointsOriented(const double *p1, const double *p2, double *mid) const -{ - double dx1((p1[0]-_center[0])/_radius),dy1((p1[1]-_center[1])/_radius),dx2((p2[0]-_center[0])/_radius),dy2((p2[1]-_center[1])/_radius); - double angle1(GetAbsoluteAngleOfNormalizedVect(dx1,dy1)),angle2(GetAbsoluteAngleOfNormalizedVect(dx2,dy2)); - - if (angle1 <= 0.0) - angle1 += 2.*M_PI; - if (angle2 <= 0.0) - angle2 += 2.*M_PI; - - double avg; - if((_angle>0. && angle1 <= angle2) || (_angle<=0. && angle1 >= angle2)) - avg = (angle1+angle2)/2.; - else - avg = (angle1+angle2)/2. - M_PI; - - mid[0]=_center[0]+_radius*cos(avg); - mid[1]=_center[1]+_radius*sin(avg); -} - - -/*! - * Characteristic value used is angle in ]_Pi;Pi[ from axe 0x. - */ -bool EdgeArcCircle::isIn(double characterVal) const -{ - return IsIn2Pi(_angle0,_angle,characterVal); -} - -Node *EdgeArcCircle::buildRepresentantOfMySelf() const -{ - return new Node(_center[0]+_radius*cos(_angle0+_angle/2.),_center[1]+_radius*sin(_angle0+_angle/2.)); -} - -/*! - * Characteristic value used is angle in ]_Pi;Pi[ from axe 0x. - * 'val1' and 'val2' have been detected previously as owning to this. - */ -bool EdgeArcCircle::isLower(double val1, double val2) const -{ - double myDelta1=val1-_angle0; - double myDelta2=val2-_angle0; - if(_angle>0.) - { - myDelta1=myDelta1>-(_radius*QUADRATIC_PLANAR::_precision)?myDelta1:myDelta1+2.*M_PI;//in some cases val1 or val2 are so close to angle0 that myDelta is close to 0. but negative. - myDelta2=myDelta2>-(_radius*QUADRATIC_PLANAR::_precision)?myDelta2:myDelta2+2.*M_PI; - return myDelta10.) - myDelta=myDelta>=0.?myDelta:myDelta+2.*M_PI; - else - myDelta=myDelta<=0.?myDelta:myDelta-2.*M_PI; - return myDelta/_angle; -} - -double EdgeArcCircle::getDistanceToPoint(const double *pt) const -{ - double angle=Node::computeAngle(_center,pt); - if(IsIn2Pi(_angle0,_angle,angle)) - return fabs(Node::distanceBtw2Pt(_center,pt)-_radius); - else - { - double dist1=Node::distanceBtw2Pt(*_start,pt); - double dist2=Node::distanceBtw2Pt(*_end,pt); - return std::min(dist1,dist2); - } -} - -bool EdgeArcCircle::isNodeLyingOn(const double *coordOfNode) const -{ - double dist=Node::distanceBtw2Pt(_center,coordOfNode); - if(Node::areDoubleEquals(dist,_radius)) - { - double angle=Node::computeAngle(_center,coordOfNode); - return IsIn2Pi(_angle0,_angle,angle); - } - else - return false; -} - -/*! - * Idem IsAngleNotIn except that here 'start' in ]-Pi;Pi[ and delta in ]-2*Pi;2Pi[. - * @param angleIn in ]-Pi;Pi[. - */ -bool EdgeArcCircle::IsIn2Pi(double start, double delta, double angleIn) -{ - double myDelta=angleIn-start; - if(delta>0.) - { - myDelta=myDelta>=0.?myDelta:myDelta+2.*M_PI; - return myDelta>0. && myDeltadelta; - } -} - -/*! - * Given the arc 'a' defined by 'start' angle and a 'delta' [-Pi;Pi] states for the angle 'angleIn' [-Pi;Pi] if it owns or not 'a'. - */ -bool EdgeArcCircle::IsAngleNotIn(double start, double delta, double angleIn) -{ - double tmp=start; - if(tmp<0.) - tmp+=2*M_PI; - double tmp2=angleIn; - if(tmp2<0.) - tmp2+=2*M_PI; - if(tmp+delta>=2.*M_PI) - return (tmp2tmp+delta-2*M_PI); - else if(tmp+delta>=0.) - return (tmp2std::max(tmp,tmp+delta)); - else - return (tmp2>tmp) && (tmp2<(tmp+delta+2.*M_PI)); -} - -void EdgeArcCircle::updateBounds() -{ - _bounds.setValues(std::min((*_start)[0],(*_end)[0]),std::max((*_start)[0],(*_end)[0]),std::min((*_start)[1],(*_end)[1]),std::max((*_start)[1],(*_end)[1])); - if(IsIn2Pi(_angle0,_angle,M_PI/2)) - _bounds[3]=_center[1]+_radius; - if(IsIn2Pi(_angle0,_angle,-M_PI/2)) - _bounds[2]=_center[1]-_radius; - if(IsIn2Pi(_angle0,_angle,0.)) - _bounds[1]=_center[0]+_radius; - if(IsIn2Pi(_angle0,_angle,M_PI)) - _bounds[0]=_center[0]-_radius; -} - -void EdgeArcCircle::fillGlobalInfoAbs(bool direction, const std::map& mapThis, const std::map& mapOther, int offset1, int offset2, double fact, double baryX, double baryY, - std::vector& edgesThis, std::vector& addCoo, std::map mapAddCoo) const -{ - int tmp[2]; - _start->fillGlobalInfoAbs(mapThis,mapOther,offset1,offset2,fact,baryX,baryY,addCoo,mapAddCoo,tmp); - _end->fillGlobalInfoAbs(mapThis,mapOther,offset1,offset2,fact,baryX,baryY,addCoo,mapAddCoo,tmp+1); - if(direction) - { - edgesThis.push_back(tmp[0]); - edgesThis.push_back(tmp[1]); - } - else - { - edgesThis.push_back(tmp[1]); - edgesThis.push_back(tmp[0]); - } -} - -void EdgeArcCircle::fillGlobalInfoAbs2(const std::map& mapThis, const std::map& mapOther, int offset1, int offset2, double fact, double baryX, double baryY, - std::vector& edgesOther, std::vector& addCoo, std::map& mapAddCoo) const -{ - _start->fillGlobalInfoAbs2(mapThis,mapOther,offset1,offset2,fact,baryX,baryY,addCoo,mapAddCoo,edgesOther); - _end->fillGlobalInfoAbs2(mapThis,mapOther,offset1,offset2,fact,baryX,baryY,addCoo,mapAddCoo,edgesOther); -} diff --git a/src/INTERP_KERNEL/Geometric2D/InterpKernelGeo2DEdgeArcCircle.hxx b/src/INTERP_KERNEL/Geometric2D/InterpKernelGeo2DEdgeArcCircle.hxx deleted file mode 100644 index 382077bc4..000000000 --- a/src/INTERP_KERNEL/Geometric2D/InterpKernelGeo2DEdgeArcCircle.hxx +++ /dev/null @@ -1,138 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 -// 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 __INTERPKERNELGEO2DEDGEARCCIRCLE_HXX__ -#define __INTERPKERNELGEO2DEDGEARCCIRCLE_HXX__ - -#include "INTERPKERNELDefines.hxx" -#include "InterpKernelGeo2DEdge.hxx" - -namespace INTERP_KERNEL -{ - class INTERPKERNEL_EXPORT ArcCArcCIntersector : public SameTypeEdgeIntersector - { - public: - ArcCArcCIntersector(const EdgeArcCircle& e1, const EdgeArcCircle& e2); - bool haveTheySameDirection() const; - bool areColinears() const; - void getPlacements(Node *start, Node *end, TypeOfLocInEdge& whereStart, TypeOfLocInEdge& whereEnd, MergePoints& commonNode) const; - void areOverlappedOrOnlyColinears(const Bounds *whereToFind, bool& obviousNoIntersection, bool& areOverlapped); - std::list< IntersectElement > getIntersectionsCharacteristicVal() const; - private: - //! return angle in ]-Pi;Pi[ - 'node' must be on curve of '_e1' - double getAngle(Node *node) const; - static bool internalAreColinears(const EdgeArcCircle& a1, const EdgeArcCircle& a2, double& distBetweenCenters, double& cst, double& radiusL, double centerL[2], double& raduisB, double centerB[2]); - static bool areArcsOverlapped(const EdgeArcCircle& a1, const EdgeArcCircle& a2); - private: - const EdgeArcCircle& getE1() const { return (const EdgeArcCircle&)_e1; } - const EdgeArcCircle& getE2() const { return (const EdgeArcCircle&)_e2; } - private: - double _dist; - }; - - class INTERPKERNEL_EXPORT ArcCSegIntersector : public CrossTypeEdgeIntersector - { - public: - ArcCSegIntersector(const EdgeArcCircle& e1, const EdgeLin& e2, bool reverse=true); - //virtual overloading - bool areColinears() const; - void getPlacements(Node *start, Node *end, TypeOfLocInEdge& whereStart, TypeOfLocInEdge& whereEnd, MergePoints& commonNode) const; - void areOverlappedOrOnlyColinears(const Bounds *whereToFind, bool& obviousNoIntersection, bool& areOverlapped); - std::list< IntersectElement > getIntersectionsCharacteristicVal() const; - private: - const EdgeArcCircle& getE1() const { return (const EdgeArcCircle&)_e1; } - const EdgeLin& getE2() const { return (const EdgeLin&)_e2; } - private: - double _dx; - double _dy; - double _drSq; - double _cross; - double _determinant; - }; - - class INTERPKERNEL_EXPORT EdgeArcCircle : public Edge - { - public: - EdgeArcCircle(std::istream& lineInXfig); - EdgeArcCircle(Node *start, Node *middle, Node *end, bool direction = true); - EdgeArcCircle(double sX, double sY, double mX, double mY, double eX, double eY); - EdgeArcCircle(Node *start, Node *end, const double *center, double radius, double angle0, double deltaAngle, bool direction=true); - //! for tests - void changeMiddle(Node *newMiddle); - void dumpInXfigFile(std::ostream& stream, bool direction, int resolution, const Bounds& box) const; - void update(Node *m); - double getAreaOfZone() const; - double getCurveLength() const; - void getBarycenter(double *bary) const; - void getBarycenterOfZone(double *bary) const; - void getMiddleOfPoints(const double *p1, const double *p2, double *mid) const; - void getMiddleOfPointsOriented(const double *p1, const double *p2, double *mid) const; - bool isIn(double characterVal) const; - Node *buildRepresentantOfMySelf() const; - bool isLower(double val1, double val2) const; - double getCharactValue(const Node& node) const; - double getCharactValueBtw0And1(const Node& node) const; - double getDistanceToPoint(const double *pt) const; - bool isNodeLyingOn(const double *coordOfNode) const; - TypeOfFunction getTypeOfFunc() const { return ARC_CIRCLE; } - void dynCastFunction(const EdgeLin * &seg, - const EdgeArcCircle * &arcSeg) const { arcSeg=this; } - const double *getCenter() const { return _center; } - void getCenter(double *center) const { center[0]=_center[0]; center[1]=_center[1]; } - bool doIHaveSameDirectionAs(const Edge& other) const { return false; } - void applySimilarity(double xBary, double yBary, double dimChar); - void unApplySimilarity(double xBary, double yBary, double dimChar); - double getAngle0() const { return _angle0; } - double getRadius() const { return _radius; } - double getAngle() const { return _angle; } - void tesselate(const int *conn, int offset, double eps, std::vector& newConn, std::vector& addCoo) const; - static EdgeArcCircle *BuildFromNodes(Node *start, Node *middle, Node *end); - static double GetAbsoluteAngle(const double *vect, double& normVect); - static double GetAbsoluteAngleOfNormalizedVect(double ux, double uy); - static void GetArcOfCirclePassingThru(const double *start, const double *middle, const double *end, - double *center, double& radius, double& angleInRad, double& angleInRad0); - //! To avoid in aggressive optimizations nan. - static double SafeSqrt(double val) { double ret=std::max(val,0.); return sqrt(ret); } - static double SafeAcos(double cosAngle) { double ret=std::min(cosAngle,1.); ret=std::max(ret,-1.); return acos(ret); } - static double SafeAsin(double sinAngle) { double ret=std::min(sinAngle,1.); ret=std::max(ret,-1.); return asin(ret); } - //! @param start and @param angleIn in ]-Pi;Pi] and @param delta in ]-2*Pi,2*Pi[ - static bool IsIn2Pi(double start, double delta, double angleIn); - //! 'delta' 'start' in ]-Pi;Pi[ - static bool IsAngleNotIn(double start, double delta, double angleIn); - //! for an angle 'angle' in ]-3*Pi;3*Pi[ returns angle in ]-Pi;Pi[ - static double NormalizeAngle(double angle) { if(angle>M_PI) return angle-2.*M_PI; if(angle<-M_PI) return angle+2.*M_PI; return angle; } - protected: - void updateBounds(); - Edge *buildEdgeLyingOnMe(Node *start, Node *end, bool direction=true) const; - void fillGlobalInfoAbs(bool direction, const std::map& mapThis, const std::map& mapOther, int offset1, int offset2, double fact, double baryX, double baryY, - std::vector& edgesThis, std::vector& addCoo, std::map mapAddCoo) const; - void fillGlobalInfoAbs2(const std::map& mapThis, const std::map& mapOther, int offset1, int offset2, double fact, double baryX, double baryY, - std::vector& edgesOther, std::vector& addCoo, std::map& mapAddCoo) const; - protected: - //!Value between -2Pi and 2Pi - double _angle; - //!Value between -Pi and Pi - double _angle0; - double _radius; - double _center[2]; - }; -} - -#endif diff --git a/src/INTERP_KERNEL/Geometric2D/InterpKernelGeo2DEdgeInfLin.cxx b/src/INTERP_KERNEL/Geometric2D/InterpKernelGeo2DEdgeInfLin.cxx deleted file mode 100644 index 9f669194d..000000000 --- a/src/INTERP_KERNEL/Geometric2D/InterpKernelGeo2DEdgeInfLin.cxx +++ /dev/null @@ -1,30 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 -// 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 "InterpKernelGeo2DEdgeInfLin.hxx" - -using namespace INTERP_KERNEL; - -EdgeInfLin::EdgeInfLin(Node *pointPassingThrough, double slope) -{ - _start=pointPassingThrough; - _start->incrRef(); - _end=new Node((*_start)[0]+cos(slope),(*_start)[1]+sin(slope)); -} diff --git a/src/INTERP_KERNEL/Geometric2D/InterpKernelGeo2DEdgeInfLin.hxx b/src/INTERP_KERNEL/Geometric2D/InterpKernelGeo2DEdgeInfLin.hxx deleted file mode 100644 index c4942765f..000000000 --- a/src/INTERP_KERNEL/Geometric2D/InterpKernelGeo2DEdgeInfLin.hxx +++ /dev/null @@ -1,41 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 -// 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 __INTERPKERNELGEO2DEDGEINFLIN_HXX__ -#define __INTERPKERNELGEO2DEDGEINFLIN_HXX__ - -#include "InterpKernelGeo2DEdgeLin.hxx" - -namespace INTERP_KERNEL -{ - class EdgeInfLin : public EdgeLin - { - public: - EdgeInfLin(Node *start, Node *end):EdgeLin(start,end,true) { } - EdgeInfLin(Node *pointPassingThrough, double slope); - bool isIn(double characterVal) const { return true; } - void dynCastFunction(const EdgeLin * &seg, - const EdgeArcCircle * &arcSeg) const { seg=this; } - protected: - ~EdgeInfLin() { } - }; -} - -#endif diff --git a/src/INTERP_KERNEL/Geometric2D/InterpKernelGeo2DEdgeLin.cxx b/src/INTERP_KERNEL/Geometric2D/InterpKernelGeo2DEdgeLin.cxx deleted file mode 100644 index 0ea63b722..000000000 --- a/src/INTERP_KERNEL/Geometric2D/InterpKernelGeo2DEdgeLin.cxx +++ /dev/null @@ -1,335 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 -// 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 "InterpKernelGeo2DEdgeLin.hxx" -#include "InterpKernelGeo2DNode.hxx" -#include "InterpKernelException.hxx" -#include "NormalizedUnstructuredMesh.hxx" - -using namespace INTERP_KERNEL; - -namespace INTERP_KERNEL -{ - extern const unsigned MAX_SIZE_OF_LINE_XFIG_FILE=1024; -} - -SegSegIntersector::SegSegIntersector(const EdgeLin& e1, const EdgeLin& e2):SameTypeEdgeIntersector(e1,e2) -{ - _matrix[0]=(*(e2.getStartNode()))[0]-(*(e2.getEndNode()))[0]; - _matrix[1]=(*(e1.getEndNode()))[0]-(*(e1.getStartNode()))[0]; - _matrix[2]=(*(e2.getStartNode()))[1]-(*(e2.getEndNode()))[1]; - _matrix[3]=(*(e1.getEndNode()))[1]-(*(e1.getStartNode()))[1]; - _col[0]=_matrix[3]*(*(e1.getStartNode()))[0]-_matrix[1]*(*(e1.getStartNode()))[1]; - _col[1]=-_matrix[2]*(*(e2.getStartNode()))[0]+_matrix[0]*(*(e2.getStartNode()))[1]; - //Little trick to avoid problems if 'e1' and 'e2' are colinears and along Ox or Oy axes. - if(fabs(_matrix[3])>fabs(_matrix[1])) - _ind=0; - else - _ind=1; -} - -/*! - * Must be called when 'this' and 'other' have been detected to be at least colinear. Typically they are overlapped. - * Must be called after call of areOverlappedOrOnlyColinears. - */ -bool SegSegIntersector::haveTheySameDirection() const -{ - return (_matrix[3]*_matrix[1]+_matrix[2]*_matrix[0])>0.; - //return (_matrix[_ind?1:0]>0. && _matrix[_ind?3:2]>0.) || (_matrix[_ind?1:0]<0. && _matrix[_ind?3:2]<0.); -} - -/*! - * Precondition start and end must be so that there predecessor was in the same direction than 'e1' - */ -void SegSegIntersector::getPlacements(Node *start, Node *end, TypeOfLocInEdge& whereStart, TypeOfLocInEdge& whereEnd, MergePoints& commonNode) const -{ - getCurveAbscisse(start,whereStart,commonNode); - getCurveAbscisse(end,whereEnd,commonNode); -} - -void SegSegIntersector::getCurveAbscisse(Node *node, TypeOfLocInEdge& where, MergePoints& commonNode) const -{ - bool obvious; - obviousCaseForCurvAbscisse(node,where,commonNode,obvious); - if(obvious) - return ; - double ret=((*node)[!_ind]-(*_e1.getStartNode())[!_ind])/((*_e1.getEndNode())[!_ind]-(*_e1.getStartNode())[!_ind]); - if(ret>0. && ret <1.) - where=INSIDE; - else if(ret<0.) - where=OUT_BEFORE; - else - where=OUT_AFTER; -} - -/*! - * areColinears method should be called before with a returned colinearity equal to false to avoid bad news. - */ -std::list< IntersectElement > SegSegIntersector::getIntersectionsCharacteristicVal() const -{ - std::list< IntersectElement > ret; - double x=_matrix[0]*_col[0]+_matrix[1]*_col[1]; - double y=_matrix[2]*_col[0]+_matrix[3]*_col[1]; - //Only one intersect point possible - Node *node=new Node(x,y); - node->declareOn(); - bool i_1S=_e1.getStartNode()->isEqual(*node); - bool i_1E=_e1.getEndNode()->isEqual(*node); - bool i_2S=_e2.getStartNode()->isEqual(*node); - bool i_2E=_e2.getEndNode()->isEqual(*node); - ret.push_back(IntersectElement(_e1.getCharactValue(*node), - _e2.getCharactValue(*node), - i_1S,i_1E,i_2S,i_2E,node,_e1,_e2,keepOrder())); - return ret; -} - -/*! - * retrieves if segs are colinears. - * WARNING !!! Contrary to areOverlappedOrOnlyColinears method, this method use an - * another precision to detect colinearity ! - */ -bool SegSegIntersector::areColinears() const -{ - double determinant=_matrix[0]*_matrix[3]-_matrix[1]*_matrix[2]; - return fabs(determinant)2.*QUADRATIC_PLANAR::_precision)//2*_precision due to max of offset on _start and _end - { - colinearity=false; areOverlapped=false; - _matrix[0]/=determinant; _matrix[1]/=determinant; _matrix[2]/=determinant; _matrix[3]/=determinant; - } - else - { - colinearity=true; - //retrieving initial matrix - double tmp=_matrix[0]; _matrix[0]=_matrix[3]; _matrix[3]=tmp; - _matrix[1]=-_matrix[1]; _matrix[2]=-_matrix[2]; - // - double deno=sqrt(_matrix[0]*_matrix[0]+_matrix[1]*_matrix[1]); - double x=(*(_e1.getStartNode()))[0]-(*(_e2.getStartNode()))[0]; - double y=(*(_e1.getStartNode()))[1]-(*(_e2.getStartNode()))[1]; - areOverlapped=fabs((_matrix[1]*y+_matrix[0]*x)/deno)0. && characterVal<1.; -} - -Node *EdgeLin::buildRepresentantOfMySelf() const -{ - return new Node(((*(_start))[0]+(*(_end))[0])/2.,((*(_start))[1]+(*(_end))[1])/2.); -} - -double EdgeLin::getCharactValue(const Node& node) const -{ - return getCharactValueEng(node); -} - -double EdgeLin::getCharactValueBtw0And1(const Node& node) const -{ - return getCharactValueEng(node); -} - -double EdgeLin::getDistanceToPoint(const double *pt) const -{ - double loc=getCharactValueEng(pt); - if(loc>0. && loc<1.) - { - double tmp[2]; - tmp[0]=(*_start)[0]*(1-loc)+loc*(*_end)[0]; - tmp[1]=(*_start)[1]*(1-loc)+loc*(*_end)[1]; - return Node::distanceBtw2Pt(pt,tmp); - } - else - { - double dist1=Node::distanceBtw2Pt(*_start,pt); - double dist2=Node::distanceBtw2Pt(*_end,pt); - return std::min(dist1,dist2); - } -} - -bool EdgeLin::isNodeLyingOn(const double *coordOfNode) const -{ - double dBase=sqrt(_start->distanceWithSq(*_end)); - double d1=Node::distanceBtw2Pt(*_start,coordOfNode); - d1+=Node::distanceBtw2Pt(*_end,coordOfNode); - return Node::areDoubleEquals(dBase,d1); -} - -void EdgeLin::dumpInXfigFile(std::ostream& stream, bool direction, int resolution, const Bounds& box) const -{ - stream << "2 1 0 1 "; - fillXfigStreamForLoc(stream); - stream << " 7 50 -1 -1 0.000 0 0 -1 1 0 2" << std::endl << "1 1 1.00 60.00 120.00" << std::endl; - direction?_start->dumpInXfigFile(stream,resolution,box):_end->dumpInXfigFile(stream,resolution,box); - direction?_end->dumpInXfigFile(stream,resolution,box):_start->dumpInXfigFile(stream,resolution,box); - stream << std::endl; -} - -void EdgeLin::update(Node *m) -{ - updateBounds(); -} - -double EdgeLin::getNormSq() const -{ - return _start->distanceWithSq(*_end); -} - -/*! - * This methods computes : - * \f[ - * \int_{Current Edge} -ydx - * \f] - */ -double EdgeLin::getAreaOfZone() const -{ - return ((*_start)[0]-(*_end)[0])*((*_start)[1]+(*_end)[1])/2.; -} - -void EdgeLin::getBarycenter(double *bary) const -{ - bary[0]=((*_start)[0]+(*_end)[0])/2.; - bary[1]=((*_start)[1]+(*_end)[1])/2.; -} - -/*! - * \f[ - * bary[0]=\int_{Current Edge} -yxdx - * \f] - * \f[ - * bary[1]=\int_{Current Edge} -\frac{y^{2}}{2}dx - * \f] - * To compute these 2 expressions in this class we have : - * \f[ - * y=y_{1}+\frac{y_{2}-y_{1}}{x_{2}-x_{1}}(x-x_{1}) - * \f] - */ -void EdgeLin::getBarycenterOfZone(double *bary) const -{ - double x1=(*_start)[0]; - double y1=(*_start)[1]; - double x2=(*_end)[0]; - double y2=(*_end)[1]; - bary[0]=(x1-x2)*(y1*(2.*x1+x2)+y2*(2.*x2+x1))/6.; - //bary[0]+=(y1-y2)*(x2*x2/3.-(x1*x2+x1*x1)/6.)+y1*(x1*x1-x2*x2)/2.; - //bary[0]+=(y1-y2)*((x2*x2+x1*x2+x1*x1)/3.-(x2+x1)*x1/2.)+y1*(x1*x1-x2*x2)/2.; - bary[1]=(x1-x2)*(y1*(y1+y2)+y2*y2)/6.; -} - -/*! - * Here \a this is not used (contrary to EdgeArcCircle class). - */ -void EdgeLin::getMiddleOfPoints(const double *p1, const double *p2, double *mid) const -{ - mid[0]=(p1[0]+p2[0])/2.; - mid[1]=(p1[1]+p2[1])/2.; -} - -double EdgeLin::getCurveLength() const -{ - double x=(*_start)[0]-(*_end)[0]; - double y=(*_start)[1]-(*_end)[1]; - return sqrt(x*x+y*y); -} - -Edge *EdgeLin::buildEdgeLyingOnMe(Node *start, Node *end, bool direction) const -{ - return new EdgeLin(start,end,direction); -} - -/*! - * No precision should be introduced here. Just think as if precision was perfect. - */ -void EdgeLin::updateBounds() -{ - _bounds.setValues(std::min((*_start)[0],(*_end)[0]),std::max((*_start)[0],(*_end)[0]),std::min((*_start)[1],(*_end)[1]),std::max((*_start)[1],(*_end)[1])); -} - -double EdgeLin::getCharactValueEng(const double *node) const -{ - double car1_1x=node[0]-(*(_start))[0]; double car1_2x=(*(_end))[0]-(*(_start))[0]; - double car1_1y=node[1]-(*(_start))[1]; double car1_2y=(*(_end))[1]-(*(_start))[1]; - return (car1_1x*car1_2x+car1_1y*car1_2y)/(car1_2x*car1_2x+car1_2y*car1_2y); -} - -void EdgeLin::fillGlobalInfoAbs(bool direction, const std::map& mapThis, const std::map& mapOther, int offset1, int offset2, double fact, double baryX, double baryY, - std::vector& edgesThis, std::vector& addCoo, std::map mapAddCoo) const -{ - int tmp[2]; - _start->fillGlobalInfoAbs(mapThis,mapOther,offset1,offset2,fact,baryX,baryY,addCoo,mapAddCoo,tmp); - _end->fillGlobalInfoAbs(mapThis,mapOther,offset1,offset2,fact,baryX,baryY,addCoo,mapAddCoo,tmp+1); - if(direction) - { - edgesThis.push_back(tmp[0]); - edgesThis.push_back(tmp[1]); - } - else - { - edgesThis.push_back(tmp[1]); - edgesThis.push_back(tmp[0]); - } -} - -void EdgeLin::fillGlobalInfoAbs2(const std::map& mapThis, const std::map& mapOther, int offset1, int offset2, double fact, double baryX, double baryY, - std::vector& edgesOther, std::vector& addCoo, std::map& mapAddCoo) const -{ - _start->fillGlobalInfoAbs2(mapThis,mapOther,offset1,offset2,fact,baryX,baryY,addCoo,mapAddCoo,edgesOther); - _end->fillGlobalInfoAbs2(mapThis,mapOther,offset1,offset2,fact,baryX,baryY,addCoo,mapAddCoo,edgesOther); -} diff --git a/src/INTERP_KERNEL/Geometric2D/InterpKernelGeo2DEdgeLin.hxx b/src/INTERP_KERNEL/Geometric2D/InterpKernelGeo2DEdgeLin.hxx deleted file mode 100644 index fad4ada11..000000000 --- a/src/INTERP_KERNEL/Geometric2D/InterpKernelGeo2DEdgeLin.hxx +++ /dev/null @@ -1,87 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 -// 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 __INTERPKERNELGEO2DEDGELIN_HXX__ -#define __INTERPKERNELGEO2DEDGELIN_HXX__ - -#include "INTERPKERNELDefines.hxx" -#include "InterpKernelGeo2DEdge.hxx" - -namespace INTERP_KERNEL -{ - class INTERPKERNEL_EXPORT SegSegIntersector : SameTypeEdgeIntersector - { - friend class Edge; - public: - SegSegIntersector(const EdgeLin& e1, const EdgeLin& e2); - bool areColinears() const; - bool haveTheySameDirection() const; - void getPlacements(Node *start, Node *end, TypeOfLocInEdge& whereStart, TypeOfLocInEdge& whereEnd, MergePoints& commonNode) const; - void areOverlappedOrOnlyColinears(const Bounds *whereToFind, bool& obviousNoIntersection, bool& areOverlapped); - std::list< IntersectElement > getIntersectionsCharacteristicVal() const; - private: - void getCurveAbscisse(Node *node, TypeOfLocInEdge& where, MergePoints& commonNode) const; - private: - //! index on which all single index op will be performed. Filled in case colinearity is equal to true. - int _ind; - double _col[2]; - double _matrix[4];//SPACEDIM*SPACEDIM - }; - - class INTERPKERNEL_EXPORT EdgeLin : public Edge - { - friend class SegSegIntersector; - public: - EdgeLin(std::istream& lineInXfig); - EdgeLin(Node *start, Node *end, bool direction=true); - EdgeLin(double sX, double sY, double eX, double eY); - ~EdgeLin(); - TypeOfFunction getTypeOfFunc() const { return SEG; } - void dumpInXfigFile(std::ostream& stream, bool direction, int resolution, const Bounds& box) const; - void update(Node *m); - double getNormSq() const; - double getAreaOfZone() const; - double getCurveLength() const; - void getBarycenter(double *bary) const; - void getBarycenterOfZone(double *bary) const; - void getMiddleOfPoints(const double *p1, const double *p2, double *mid) const; - bool isIn(double characterVal) const; - Node *buildRepresentantOfMySelf() const; - double getCharactValue(const Node& node) const; - double getCharactValueBtw0And1(const Node& node) const; - double getDistanceToPoint(const double *pt) const; - bool isNodeLyingOn(const double *coordOfNode) const; - bool isLower(double val1, double val2) const { return val1& mapThis, const std::map& mapOther, int offset1, int offset2, double fact, double baryX, double baryY, - std::vector& edgesThis, std::vector& addCoo, std::map mapAddCoo) const; - void fillGlobalInfoAbs2(const std::map& mapThis, const std::map& mapOther, int offset1, int offset2, double fact, double baryX, double baryY, - std::vector& edgesOther, std::vector& addCoo, std::map& mapAddCoo) const; - }; -} - -#endif diff --git a/src/INTERP_KERNEL/Geometric2D/InterpKernelGeo2DElementaryEdge.cxx b/src/INTERP_KERNEL/Geometric2D/InterpKernelGeo2DElementaryEdge.cxx deleted file mode 100644 index 04089b219..000000000 --- a/src/INTERP_KERNEL/Geometric2D/InterpKernelGeo2DElementaryEdge.cxx +++ /dev/null @@ -1,232 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 -// 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 "InterpKernelGeo2DElementaryEdge.hxx" -#include "InterpKernelException.hxx" -#include "InterpKernelGeo2DEdge.hxx" -#include "InterpKernelGeo2DComposedEdge.hxx" - -using namespace INTERP_KERNEL; - -ElementaryEdge::ElementaryEdge(const ElementaryEdge& other):_direction(other._direction),_ptr(other._ptr) -{ - _ptr->incrRef(); -} - -ElementaryEdge::~ElementaryEdge() -{ - if(_ptr) - _ptr->decrRef(); -} - -bool ElementaryEdge::isNodeIn(Node *n) const -{ - return _ptr->getStartNode()==n || _ptr->getEndNode()==n; -} - -/*! - * \b WARNING contrary to INTERP_KERNEL::Edge::getBarycenterOfZone method called, - * this one is cumulative. - */ -void ElementaryEdge::getBarycenterOfZone(double *bary) const -{ - double tmp[2]; - _ptr->getBarycenterOfZone(tmp); - if(_direction) - { - bary[0]+=tmp[0]; - bary[1]+=tmp[1]; - } - else - { - bary[0]-=tmp[0]; - bary[1]-=tmp[1]; - } -} - -void ElementaryEdge::fillBounds(Bounds& output) const -{ - output.aggregate(_ptr->getBounds()); -} - -void ElementaryEdge::getAllNodes(std::set& output) const -{ - output.insert(_ptr->getStartNode()); - output.insert(_ptr->getEndNode()); -} - -void ElementaryEdge::getBarycenter(double *bary, double& weigh) const -{ - _ptr->getBarycenter(bary); - weigh=_ptr->getCurveLength(); -} - -ElementaryEdge *ElementaryEdge::clone() const -{ - return new ElementaryEdge(*this); -} - -void ElementaryEdge::initLocations() const -{ - _ptr->initLocs(); -} - -/*! - * WARNING use this method if and only if this is so that it is completely in/out/on of @param pol. - */ -TypeOfEdgeLocInPolygon ElementaryEdge::locateFullyMySelf(const ComposedEdge& pol, TypeOfEdgeLocInPolygon precEdgeLoc) const -{ - if(getLoc()!=FULL_UNKNOWN) - return getLoc(); - //obvious cases - if(precEdgeLoc==FULL_IN_1) - { - if(getStartNode()->getLoc()==ON_1) - { - declareOut(); - return getLoc(); - } - else if(getStartNode()->getLoc()==IN_1 || getStartNode()->getLoc()==ON_TANG_1) - { - declareIn(); - return getLoc(); - } - } - if(precEdgeLoc==FULL_OUT_1) - { - if(getStartNode()->getLoc()==ON_1) - { - declareIn(); - return getLoc(); - } - else if(getStartNode()->getLoc()==IN_1 || getStartNode()->getLoc()==ON_TANG_1) - { - declareOut(); - return getLoc(); - } - } - if(getStartNode()->getLoc()==IN_1 || getEndNode()->getLoc()==IN_1) - { - declareIn(); - return getLoc(); - } - if(getStartNode()->getLoc()==OUT_1 || getEndNode()->getLoc()==OUT_1) - { - declareOut(); - return getLoc(); - } - //a seek is requested - return locateFullyMySelfAbsolute(pol); -} - -TypeOfEdgeLocInPolygon ElementaryEdge::locateFullyMySelfAbsolute(const ComposedEdge& pol) const -{ - Node *node=_ptr->buildRepresentantOfMySelf(); // build barycenter used to detect if the edge is IN or OUT - if(pol.isInOrOut(node)) - declareIn(); - else - declareOut(); - node->decrRef(); - return getLoc(); -} - -Node *ElementaryEdge::getEndNode() const -{ - if(_direction) - return _ptr->getEndNode(); - else return _ptr->getStartNode(); -} - -Node *ElementaryEdge::getStartNode() const -{ - if(_direction) - return _ptr->getStartNode(); - else - return _ptr->getEndNode(); -} - -bool ElementaryEdge::changeEndNodeWith(Node *node) const -{ - if(_direction) - return _ptr->changeEndNodeWith(node); - else - return _ptr->changeStartNodeWith(node); -} - -bool ElementaryEdge::changeStartNodeWith(Node *node) const -{ - if(_direction) - return _ptr->changeStartNodeWith(node); - else - return _ptr->changeEndNodeWith(node); -} - -void ElementaryEdge::dumpInXfigFile(std::ostream& stream, int resolution, const Bounds& box) const -{ - _ptr->dumpInXfigFile(stream,_direction,resolution,box); -} - -bool ElementaryEdge::intresicEqual(const ElementaryEdge *other) const -{ - return _ptr==other->_ptr; -} - -bool ElementaryEdge::intresicEqualDirSensitive(const ElementaryEdge *other) const -{ - return ( _direction==other->_direction ) && (_ptr==other->_ptr); -} - -bool ElementaryEdge::intresincEqCoarse(const Edge *other) const -{ - return _ptr==other; -} - -bool ElementaryEdge::isEqual(const ElementaryEdge& other) const -{ - return _ptr->isEqual(*other._ptr); -} - -/*! - * Called by QuadraticPolygon::splitAbs method. - */ -void ElementaryEdge::fillGlobalInfoAbs(const std::map& mapThis, const std::map& mapOther, int offset1, int offset2, double fact, double baryX, double baryY, - std::vector& edgesThis, std::vector& addCoo, std::map mapAddCoo) const -{ - _ptr->fillGlobalInfoAbs(_direction,mapThis,mapOther,offset1,offset2,fact,baryX,baryY,edgesThis,addCoo,mapAddCoo); -} - -/*! - * Called by QuadraticPolygon::splitAbs method. Close to ElementaryEdge::fillGlobalInfoAbs method expect that here edgesOther (that replace edgesThis) is here an in/out parameter that only contains nodes - * unsorted because the "other" mesh is not subdivided yet. - */ -void ElementaryEdge::fillGlobalInfoAbs2(const std::map& mapThis, const std::map& mapOther, int offset1, int offset2, double fact, double baryX, double baryY, - std::vector& edgesOther, std::vector& addCoo, std::map& mapAddCoo) const -{ - _ptr->fillGlobalInfoAbs2(mapThis,mapOther,offset1,offset2,fact,baryX,baryY,edgesOther,addCoo,mapAddCoo); -} - -/*! - * This method builds from a \a start node, an \a end node and a direction a new ElementaryEdge. - */ -ElementaryEdge *ElementaryEdge::BuildEdgeFromStartEndDir(bool direction, INTERP_KERNEL::Node *start, INTERP_KERNEL::Node *end) -{ - Edge *ptr=Edge::BuildEdgeFrom(start,end); - return new ElementaryEdge(ptr,direction); -} diff --git a/src/INTERP_KERNEL/Geometric2D/InterpKernelGeo2DElementaryEdge.hxx b/src/INTERP_KERNEL/Geometric2D/InterpKernelGeo2DElementaryEdge.hxx deleted file mode 100644 index 1c3cdefa9..000000000 --- a/src/INTERP_KERNEL/Geometric2D/InterpKernelGeo2DElementaryEdge.hxx +++ /dev/null @@ -1,83 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 -// 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 __INTERPKERNELGEO2DELEMENTARYEDGE_HXX__ -#define __INTERPKERNELGEO2DELEMENTARYEDGE_HXX__ - -#include "INTERPKERNELDefines.hxx" -#include "InterpKernelException.hxx" -#include "InterpKernelGeo2DAbstractEdge.hxx" -#include "InterpKernelGeo2DEdge.hxx" - -namespace INTERP_KERNEL -{ - class ElementaryEdge - { - public: - INTERPKERNEL_EXPORT ElementaryEdge(Edge *ptr, bool direction):_direction(direction),_ptr(ptr) { } - INTERPKERNEL_EXPORT ElementaryEdge(const ElementaryEdge& other); - INTERPKERNEL_EXPORT ~ElementaryEdge(); - INTERPKERNEL_EXPORT bool isThereStartPoint() const { return _iterator.isValid(); } - INTERPKERNEL_EXPORT IteratorOnComposedEdge& getIterator() { return _iterator; } - INTERPKERNEL_EXPORT bool completed() const { return false; } - INTERPKERNEL_EXPORT void declareOn() const { _ptr->declareOn(); } - INTERPKERNEL_EXPORT void declareIn() const { _ptr->declareIn(); } - INTERPKERNEL_EXPORT void declareOut() const { _ptr->declareOut(); } - INTERPKERNEL_EXPORT TypeOfEdgeLocInPolygon getLoc() const { return _ptr->getLoc(); } - INTERPKERNEL_EXPORT Edge *getPtr() const { return _ptr; } - INTERPKERNEL_EXPORT void reverse() { _direction=(!_direction); } - INTERPKERNEL_EXPORT bool isNodeIn(Node *n) const; - INTERPKERNEL_EXPORT double getAreaOfZone() const { double ret=_ptr->getAreaOfZone(); return _direction?ret:-ret; } - INTERPKERNEL_EXPORT void getBarycenterOfZone(double *bary) const; - INTERPKERNEL_EXPORT void fillBounds(Bounds& output) const; - INTERPKERNEL_EXPORT void applySimilarity(double xBary, double yBary, double dimChar) { _ptr->applySimilarity(xBary,yBary,dimChar); } - INTERPKERNEL_EXPORT void unApplySimilarity(double xBary, double yBary, double dimChar) { _ptr->unApplySimilarity(xBary,yBary,dimChar); } - INTERPKERNEL_EXPORT void getAllNodes(std::set& output) const; - INTERPKERNEL_EXPORT void getBarycenter(double *bary, double& weigh) const; - INTERPKERNEL_EXPORT ElementaryEdge *clone() const; - INTERPKERNEL_EXPORT void initLocations() const; - INTERPKERNEL_EXPORT int size() const; - INTERPKERNEL_EXPORT TypeOfEdgeLocInPolygon locateFullyMySelfAbsolute(const ComposedEdge& pol) const; - INTERPKERNEL_EXPORT TypeOfEdgeLocInPolygon locateFullyMySelf(const ComposedEdge& pol, TypeOfEdgeLocInPolygon precEdgeLoc) const; - INTERPKERNEL_EXPORT Node *getEndNode() const; - INTERPKERNEL_EXPORT Node *getStartNode() const; - INTERPKERNEL_EXPORT double getCurveLength() const { return _ptr->getCurveLength(); } - INTERPKERNEL_EXPORT bool changeEndNodeWith(Node *node) const; - INTERPKERNEL_EXPORT bool changeStartNodeWith(Node *node) const; - INTERPKERNEL_EXPORT bool intresicEqual(const ElementaryEdge *other) const; - INTERPKERNEL_EXPORT bool intresicEqualDirSensitive(const ElementaryEdge *other) const; - INTERPKERNEL_EXPORT void dumpInXfigFile(std::ostream& stream, int resolution, const Bounds& box) const; - INTERPKERNEL_EXPORT bool getDirection() const { return _direction; } - INTERPKERNEL_EXPORT bool intresincEqCoarse(const Edge *other) const; - INTERPKERNEL_EXPORT bool isEqual(const ElementaryEdge& other) const; - public: - INTERPKERNEL_EXPORT void fillGlobalInfoAbs(const std::map& mapThis, const std::map& mapOther, int offset1, int offset2, double fact, double baryX, double baryY, - std::vector& edgesThis, std::vector& addCoo, std::map mapAddCoo) const; - INTERPKERNEL_EXPORT void fillGlobalInfoAbs2(const std::map& mapThis, const std::map& mapOther, int offset1, int offset2, double fact, double baryX, double baryY, - std::vector& edgesOther, std::vector& addCoo, std::map& mapAddCoo) const; - INTERPKERNEL_EXPORT static ElementaryEdge *BuildEdgeFromStartEndDir(bool direction, INTERP_KERNEL::Node *start, INTERP_KERNEL::Node *end); - private: - bool _direction; - Edge *_ptr; - IteratorOnComposedEdge _iterator; - }; -} - -#endif diff --git a/src/INTERP_KERNEL/Geometric2D/InterpKernelGeo2DNode.cxx b/src/INTERP_KERNEL/Geometric2D/InterpKernelGeo2DNode.cxx deleted file mode 100644 index 72072b9c2..000000000 --- a/src/INTERP_KERNEL/Geometric2D/InterpKernelGeo2DNode.cxx +++ /dev/null @@ -1,198 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 -// 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 "InterpKernelGeo2DNode.hxx" -#include "InterpKernelGeo2DEdgeArcCircle.hxx" - -using namespace INTERP_KERNEL; - -Node::Node(double x, double y):_cnt(1),_loc(UNKNOWN) -{ - _coords[0]=x; _coords[1]=y; -} - -Node::Node(const double *coords):_cnt(1),_loc(UNKNOWN) -{ - _coords[0]=coords[0]; - _coords[1]=coords[1]; -} - -Node::Node(std::istream& stream):_cnt(1),_loc(UNKNOWN) -{ - int tmp; - stream >> tmp; - _coords[0]=((double) tmp)/1e4; - stream >> tmp; - _coords[1]=((double) tmp)/1e4; -} - -Node::~Node() -{ -} - -bool Node::decrRef() -{ - bool ret=(--_cnt==0); - if(ret) - delete this; - return ret; -} - -bool Node::isEqual(const Node& other) const -{ - const unsigned SPACEDIM=2; - bool ret=true; - for(unsigned i=0;i& track) const -{ - bool ret=isEqual(other); - if(ret) - track.push_back(const_cast(&other)); - return ret; -} - -void Node::dumpInXfigFile(std::ostream& stream, int resolution, const Bounds& box) const -{ - stream << box.fitXForXFig(_coords[0],resolution) << " " << box.fitYForXFig(_coords[1],resolution) << " "; -} - -double Node::distanceWithSq(const Node& other) const -{ - return (_coords[0]-other._coords[0])*(_coords[0]-other._coords[0])+(_coords[1]-other._coords[1])*(_coords[1]-other._coords[1]); -} - -/*! - * WARNING different from 'computeAngle' method ! The returned value are not in the same interval ! - * Here in [0; Pi). Typically this method returns the same value by exchanging pt1 and pt2. - * Use in process of detection of a point in or not in polygon. - */ -double Node::computeSlope(const double *pt1, const double *pt2) -{ - double x=pt2[0]-pt1[0]; - double y=pt2[1]-pt1[1]; - double norm=sqrt(x*x+y*y); - double ret=EdgeArcCircle::SafeAcos(fabs(x)/norm); - if( (x>=0. && y>=0.) || (x<0. && y<0.) ) - return ret; - else - return M_PI-ret; -} - -/*! - * WARNING different from 'computeSlope' method. Here angle in -Pi;Pi is returned. - * This method is anti-symetric. - */ -double Node::computeAngle(const double *pt1, const double *pt2) -{ - double x=pt2[0]-pt1[0]; - double y=pt2[1]-pt1[1]; - double norm=sqrt(x*x+y*y); - return EdgeArcCircle::GetAbsoluteAngleOfNormalizedVect(x/norm,y/norm); -} - -/*! - * apply a Similarity transformation on this. - * @param xBary is the opposite of the X translation to do. - * @param yBary is the opposite of the Y translation to do. - * @param dimChar is the reduction factor. - */ -void Node::applySimilarity(double xBary, double yBary, double dimChar) -{ - _coords[0]=(_coords[0]-xBary)/dimChar; - _coords[1]=(_coords[1]-yBary)/dimChar; -} - -/*! - * apply the reverse Similarity transformation on this. - * This method is the opposite of Node::applySimilarity method to retrieve the initial state. - * @param xBary is the opposite of the X translation to do. - * @param yBary is the opposite of the Y translation to do. - * @param dimChar is the reduction factor. - */ -void Node::unApplySimilarity(double xBary, double yBary, double dimChar) -{ - _coords[0]=_coords[0]*dimChar+xBary; - _coords[1]=_coords[1]*dimChar+yBary; -} - -/*! - * Called by QuadraticPolygon::splitAbs method. - */ -void Node::fillGlobalInfoAbs(const std::map& mapThis, const std::map& mapOther, int offset1, int offset2, double fact, double baryX, double baryY, - std::vector& addCoo, std::map& mapAddCoo, int *nodeId) const -{ - std::map::const_iterator it=mapThis.find(const_cast(this)); - if(it!=mapThis.end()) - { - *nodeId=(*it).second; - return; - } - it=mapOther.find(const_cast(this)); - if(it!=mapOther.end()) - { - *nodeId=(*it).second+offset1; - return; - } - it=mapAddCoo.find(const_cast(this)); - if(it!=mapAddCoo.end()) - { - *nodeId=(*it).second; - return; - } - int id=(int)addCoo.size()/2; - addCoo.push_back(fact*_coords[0]+baryX); - addCoo.push_back(fact*_coords[1]+baryY); - *nodeId=offset2+id; - mapAddCoo[const_cast(this)]=offset2+id; -} - -/*! - * Called by QuadraticPolygon::splitAbs method. - */ -void Node::fillGlobalInfoAbs2(const std::map& mapThis, const std::map& mapOther, int offset1, int offset2, double fact, double baryX, double baryY, - std::vector& addCoo, std::map& mapAddCoo, std::vector& pointsOther) const -{ - int tmp; - std::size_t sz1=addCoo.size(); - fillGlobalInfoAbs(mapThis,mapOther,offset1,offset2,fact,baryX,baryY,addCoo,mapAddCoo,&tmp); - if(sz1!=addCoo.size()) - { - pointsOther.push_back(tmp); - return ; - } - std::vector::const_iterator it=std::find(pointsOther.begin(),pointsOther.end(),tmp); - if(it!=pointsOther.end()) - return ; - if(tmp -#include -#include -#include - -namespace INTERP_KERNEL -{ - typedef enum - { - IN_1 = 7, - ON_1 = 8, - ON_LIM_1 = 12, - ON_TANG_1 = 9, - OUT_1 = 10, - UNKNOWN = 11 - } TypeOfLocInPolygon; - - class Bounds; - - /*! - * Representation of a 2D point, and potentially its location relative to a polygon. - * As nodes can be shared between edges it is handled with ref counting. - */ - class INTERPKERNEL_EXPORT Node - { - public: - Node(double x, double y); - Node(const double *coords); - Node(std::istream& stream); - void incrRef() const { _cnt++; } - bool decrRef(); - void initHitStatus() const { _hit=0; } - char getHitStatus() const { return _hit; } - void hitMeAlone(double xBary, double yBary, double dimChar) { if(_hit==0) { _hit=1; applySimilarity(xBary,yBary,dimChar); } } - void unHitMeAlone(double xBary, double yBary, double dimChar) { if(_hit==0) { _hit=1; unApplySimilarity(xBary,yBary,dimChar); } } - void hitMeAfter(double xBary, double yBary, double dimChar) { if(_hit==0) { hitMeAlone(xBary,yBary,dimChar); _hit=2; } else if(_hit==1) declareOn(); } - void unHitMeAfter(double xBary, double yBary, double dimChar) { if(_hit==0) { unHitMeAlone(xBary,yBary,dimChar); _hit=2; } } - void initLocs() const { _loc=UNKNOWN; } - void setLoc(TypeOfLocInPolygon loc) const { _loc=loc; } - TypeOfLocInPolygon getLoc() const { return _loc; } - void declareIn() const { if(_loc==UNKNOWN) _loc=IN_1; } - void declareOn() const { if(_loc==UNKNOWN) _loc=ON_1; } - void declareOnLim() const { if(_loc==UNKNOWN || _loc==ON_1) _loc=ON_LIM_1; } - void declareOut() { if(_loc==UNKNOWN) _loc=OUT_1; } - void declareOnTangent() { _loc=ON_TANG_1; } - operator const double*() const { return _coords; } - bool isEqual(const Node& other) const; - //returns an angle in -Pi/2;Pi/2. - double getSlope(const Node& other) const; - bool isEqualAndKeepTrack(const Node& other, std::vector& track) const; - void dumpInXfigFile(std::ostream& stream, int resolution, const Bounds& box) const; - double distanceWithSq(const Node& other) const; - double operator[](int i) const { return _coords[i]; } - //! use with caution - void setNewCoords(double x, double y) { _coords[0]=x; _coords[1]=y; } - //returns an angle in -Pi/2;Pi/2. - static double computeSlope(const double *pt1, const double *pt2); - //returns an angle in -Pi;Pi - static double computeAngle(const double *pt1, const double *pt2); - void applySimilarity(double xBary, double yBary, double dimChar); - void unApplySimilarity(double xBary, double yBary, double dimChar); - static double dot(const double *vect1, const double *vect2) { return vect1[0]*vect2[0]+vect1[1]*vect2[1]; } - static double sign(double val) { if(val>=0) return 1.; else return -1.; } - static double norm(const double *vect) { return sqrt(vect[0]*vect[0]+vect[1]*vect[1]); } - static bool areDoubleEquals(double a, double b) { return fabs(a-b) < QUADRATIC_PLANAR::_precision; } - //! idem areDoubleEquals except that precision of comparison is modified. - static bool areDoubleEqualsWP(double a, double b, double k) { return fabs(a-b) < k*QUADRATIC_PLANAR::_precision; } - static double distanceBtw2Pt(const double *a, const double *b) { return sqrt((a[0]-b[0])*(a[0]-b[0])+(a[1]-b[1])*(a[1]-b[1])); } - static double distanceBtw2PtSq(const double *a, const double *b) { return (a[0]-b[0])*(a[0]-b[0])+(a[1]-b[1])*(a[1]-b[1]); } - // - void fillGlobalInfoAbs(const std::map& mapThis, const std::map& mapOther, int offset1, int offset2, double fact, double baryX, double baryY, - std::vector& addCoo, std::map& mapAddCoo, int *nodeId) const; - void fillGlobalInfoAbs2(const std::map& mapThis, const std::map& mapOther, int offset1, int offset2, double fact, double baryX, double baryY, - std::vector& addCoo, std::map& mapAddCoo, std::vector& pointsOther) const; - protected: - ~Node(); - protected: - mutable char _hit; - mutable unsigned char _cnt; - mutable TypeOfLocInPolygon _loc; - double _coords[2]; - }; -} - -#endif diff --git a/src/INTERP_KERNEL/Geometric2D/InterpKernelGeo2DPrecision.cxx b/src/INTERP_KERNEL/Geometric2D/InterpKernelGeo2DPrecision.cxx deleted file mode 100644 index 14666d9d9..000000000 --- a/src/INTERP_KERNEL/Geometric2D/InterpKernelGeo2DPrecision.cxx +++ /dev/null @@ -1,35 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 -// 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 "InterpKernelGeo2DPrecision.hxx" - -double INTERP_KERNEL::QUADRATIC_PLANAR::_precision=1e-14; - -double INTERP_KERNEL::QUADRATIC_PLANAR::_arc_detection_precision=1e-14; - -void INTERP_KERNEL::QUADRATIC_PLANAR::setPrecision(double precision) -{ - INTERP_KERNEL::QUADRATIC_PLANAR::_precision=precision; -} - -void INTERP_KERNEL::QUADRATIC_PLANAR::setArcDetectionPrecision(double precision) -{ - INTERP_KERNEL::QUADRATIC_PLANAR::_arc_detection_precision=precision; -} diff --git a/src/INTERP_KERNEL/Geometric2D/InterpKernelGeo2DPrecision.hxx b/src/INTERP_KERNEL/Geometric2D/InterpKernelGeo2DPrecision.hxx deleted file mode 100644 index 4d494abce..000000000 --- a/src/INTERP_KERNEL/Geometric2D/InterpKernelGeo2DPrecision.hxx +++ /dev/null @@ -1,38 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 -// 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 __INTERPKERNELGEO2DPRECISION_HXX__ -#define __INTERPKERNELGEO2DPRECISION_HXX__ - -#include "INTERPKERNELDefines.hxx" - -namespace INTERP_KERNEL -{ - class INTERPKERNEL_EXPORT QUADRATIC_PLANAR - { - public: - static double _precision; - static double _arc_detection_precision; - static void setPrecision(double precision); - static void setArcDetectionPrecision(double precision); - }; -} - -#endif diff --git a/src/INTERP_KERNEL/Geometric2D/InterpKernelGeo2DQuadraticPolygon.cxx b/src/INTERP_KERNEL/Geometric2D/InterpKernelGeo2DQuadraticPolygon.cxx deleted file mode 100644 index caed9530b..000000000 --- a/src/INTERP_KERNEL/Geometric2D/InterpKernelGeo2DQuadraticPolygon.cxx +++ /dev/null @@ -1,1286 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 -// 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 "InterpKernelGeo2DQuadraticPolygon.hxx" -#include "InterpKernelGeo2DElementaryEdge.hxx" -#include "InterpKernelGeo2DEdgeArcCircle.hxx" -#include "InterpKernelGeo2DAbstractEdge.hxx" -#include "InterpKernelGeo2DEdgeLin.hxx" -#include "InterpKernelGeo2DBounds.hxx" -#include "InterpKernelGeo2DEdge.txx" - -#include "NormalizedUnstructuredMesh.hxx" - -#include -#include -#include -#include -#include - -using namespace INTERP_KERNEL; - -namespace INTERP_KERNEL -{ - const unsigned MAX_SIZE_OF_LINE_XFIG_FILE=1024; -} - -QuadraticPolygon::QuadraticPolygon(const char *file) -{ - char currentLine[MAX_SIZE_OF_LINE_XFIG_FILE]; - std::ifstream stream(file); - stream.exceptions(std::ios_base::eofbit); - try - { - do - stream.getline(currentLine,MAX_SIZE_OF_LINE_XFIG_FILE); - while(strcmp(currentLine,"1200 2")!=0); - do - { - Edge *newEdge=Edge::BuildFromXfigLine(stream); - if(!empty()) - newEdge->changeStartNodeWith(back()->getEndNode()); - pushBack(newEdge); - } - while(1); - } - catch(std::ifstream::failure&) - { - } - front()->changeStartNodeWith(back()->getEndNode()); -} - -QuadraticPolygon::~QuadraticPolygon() -{ -} - -QuadraticPolygon *QuadraticPolygon::BuildLinearPolygon(std::vector& nodes) -{ - QuadraticPolygon *ret(new QuadraticPolygon); - std::size_t size=nodes.size(); - for(std::size_t i=0;ipushBack(new EdgeLin(nodes[i],nodes[(i+1)%size])); - nodes[i]->decrRef(); - } - return ret; -} - -QuadraticPolygon *QuadraticPolygon::BuildArcCirclePolygon(std::vector& nodes) -{ - QuadraticPolygon *ret(new QuadraticPolygon); - std::size_t size=nodes.size(); - for(std::size_t i=0;ipushBack(new EdgeLin(nodes[i],nodes[(i+1)%(size/2)])); - else - ret->pushBack(new EdgeArcCircle(nodes[i],nodes[i+size/2],nodes[(i+1)%(size/2)])); - nodes[i]->decrRef(); nodes[i+size/2]->decrRef(); - } - return ret; -} - -Edge *QuadraticPolygon::BuildLinearEdge(std::vector& nodes) -{ - if(nodes.size()!=2) - throw INTERP_KERNEL::Exception("QuadraticPolygon::BuildLinearEdge : input vector is expected to be of size 2 !"); - Edge *ret(new EdgeLin(nodes[0],nodes[1])); - nodes[0]->decrRef(); nodes[1]->decrRef(); - return ret; -} - -Edge *QuadraticPolygon::BuildArcCircleEdge(std::vector& nodes) -{ - if(nodes.size()!=3) - throw INTERP_KERNEL::Exception("QuadraticPolygon::BuildArcCircleEdge : input vector is expected to be of size 3 !"); - EdgeLin *e1(new EdgeLin(nodes[0],nodes[2])),*e2(new EdgeLin(nodes[2],nodes[1])); - SegSegIntersector inters(*e1,*e2); - bool colinearity=inters.areColinears(); - delete e1; delete e2; - Edge *ret(0); - if(colinearity) - ret=new EdgeLin(nodes[0],nodes[1]); - else - ret=new EdgeArcCircle(nodes[0],nodes[2],nodes[1]); - nodes[0]->decrRef(); nodes[1]->decrRef(); nodes[2]->decrRef(); - return ret; -} - -void QuadraticPolygon::BuildDbgFile(const std::vector& nodes, const char *fileName) -{ - std::ofstream file(fileName); - file << std::setprecision(16); - file << " double coords[]=" << std::endl << " { "; - for(std::vector::const_iterator iter=nodes.begin();iter!=nodes.end();iter++) - { - if(iter!=nodes.begin()) - file << "," << std::endl << " "; - file << (*(*iter))[0] << ", " << (*(*iter))[1]; - } - file << "};" << std::endl; -} - -void QuadraticPolygon::closeMe() const -{ - if(!front()->changeStartNodeWith(back()->getEndNode())) - throw(Exception("big error: not closed polygon...")); -} - -void QuadraticPolygon::circularPermute() -{ - if(_sub_edges.size()>1) - { - ElementaryEdge *first=_sub_edges.front(); - _sub_edges.pop_front(); - _sub_edges.push_back(first); - } -} - -bool QuadraticPolygon::isButterflyAbs() -{ - INTERP_KERNEL::Bounds b; - double xBary,yBary; - b.prepareForAggregation(); - fillBounds(b); - double dimChar=b.getCaracteristicDim(); - b.getBarycenter(xBary,yBary); - applyGlobalSimilarity(xBary,yBary,dimChar); - // - return isButterfly(); -} - -bool QuadraticPolygon::isButterfly() const -{ - for(std::list::const_iterator it=_sub_edges.begin();it!=_sub_edges.end();it++) - { - Edge *e1=(*it)->getPtr(); - std::list::const_iterator it2=it; - it2++; - for(;it2!=_sub_edges.end();it2++) - { - MergePoints commonNode; - ComposedEdge *outVal1=new ComposedEdge; - ComposedEdge *outVal2=new ComposedEdge; - Edge *e2=(*it2)->getPtr(); - if(e1->intersectWith(e2,commonNode,*outVal1,*outVal2)) - { - Delete(outVal1); - Delete(outVal2); - return true; - } - Delete(outVal1); - Delete(outVal2); - } - } - return false; -} - -void QuadraticPolygon::dumpInXfigFileWithOther(const ComposedEdge& other, const char *fileName) const -{ - std::ofstream file(fileName); - const int resolution=1200; - Bounds box; - box.prepareForAggregation(); - fillBounds(box); - other.fillBounds(box); - dumpInXfigFile(file,resolution,box); - other.ComposedEdge::dumpInXfigFile(file,resolution,box); -} - -void QuadraticPolygon::dumpInXfigFile(const char *fileName) const -{ - std::ofstream file(fileName); - const int resolution=1200; - Bounds box; - box.prepareForAggregation(); - fillBounds(box); - dumpInXfigFile(file,resolution,box); -} - -void QuadraticPolygon::dumpInXfigFile(std::ostream& stream, int resolution, const Bounds& box) const -{ - stream << "#FIG 3.2 Produced by xfig version 3.2.5-alpha5" << std::endl; - stream << "Landscape" << std::endl; - stream << "Center" << std::endl; - stream << "Metric" << std::endl; - stream << "Letter" << std::endl; - stream << "100.00" << std::endl; - stream << "Single" << std::endl; - stream << "-2" << std::endl; - stream << resolution << " 2" << std::endl; - ComposedEdge::dumpInXfigFile(stream,resolution,box); -} - -/*! - * Warning contrary to intersectWith method this method is \b NOT const. 'this' and 'other' are modified after call of this method. - */ -double QuadraticPolygon::intersectWithAbs(QuadraticPolygon& other) -{ - double ret=0.,xBaryBB,yBaryBB; - double fact=normalize(&other,xBaryBB,yBaryBB); - std::vector polygs=intersectMySelfWith(other); - for(std::vector::iterator iter=polygs.begin();iter!=polygs.end();iter++) - { - ret+=fabs((*iter)->getArea()); - delete *iter; - } - return ret*fact*fact; -} - -/*! - * This method splits 'this' with 'other' into smaller pieces localizable. 'mapThis' is a map that gives the correspondance - * between nodes contained in 'this' and node ids in a global mesh. - * In the same way, 'mapOther' gives the correspondance between nodes contained in 'other' and node ids in a - * global mesh from wich 'other' is extracted. - * This method has 1 out paramater : 'edgesThis', After the call of this method, it contains the nodal connectivity (including type) - * of 'this' into globlal "this mesh". - * This method has 2 in/out parameters : 'subDivOther' and 'addCoo'.'otherEdgeIds' is useful to put values in - * 'edgesThis', 'subDivOther' and 'addCoo'. - * Size of 'otherEdgeIds' has to be equal to number of ElementaryEdges in 'other'. No check of that will be done. - * The term 'abs' in the name recalls that we normalize the mesh (spatially) so that node coordinates fit into [0;1]. - * @param offset1 is the number of nodes contained in global mesh from which 'this' is extracted. - * @param offset2 is the sum of nodes contained in global mesh from which 'this' is extracted and 'other' is extracted. - * @param edgesInOtherColinearWithThis will be appended at the end of the vector with colinear edge ids of other (if any) - * @param otherEdgeIds is a vector with the same size than other before calling this method. It gives in the same order - * the cell id in global other mesh. - */ -void QuadraticPolygon::splitAbs(QuadraticPolygon& other, - const std::map& mapThis, const std::map& mapOther, - int offset1, int offset2 , - const std::vector& otherEdgeIds, - std::vector& edgesThis, int cellIdThis, - std::vector< std::vector >& edgesInOtherColinearWithThis, std::vector< std::vector >& subDivOther, - std::vector& addCoo, std::map& mergedNodes) -{ - double xBaryBB, yBaryBB; - double fact=normalizeExt(&other, xBaryBB, yBaryBB); - // - IteratorOnComposedEdge it1(this),it3(&other); - MergePoints merge; - ComposedEdge *c1=new ComposedEdge; - ComposedEdge *c2=new ComposedEdge; - int i=0; - std::map mapAddCoo; - for(it3.first();!it3.finished();it3.next(),i++)//iteration over 'other' _sub_edges - { - QuadraticPolygon otherTmp; - ElementaryEdge* curE3=it3.current(); - otherTmp.pushBack(new ElementaryEdge(curE3->getPtr(),curE3->getDirection())); curE3->getPtr()->incrRef(); - IteratorOnComposedEdge it2(&otherTmp); - for(it2.first();!it2.finished();it2.next())//iteration on subedges of 'other->_sub_edge' - { - ElementaryEdge* curE2=it2.current(); - if(!curE2->isThereStartPoint()) - it1.first(); - else - it1=curE2->getIterator(); - for(;!it1.finished();)//iteration over 'this' _sub_edges - { - ElementaryEdge* curE1=it1.current(); - merge.clear(); - // - std::map::const_iterator thisStart(mapThis.find(curE1->getStartNode())),thisEnd(mapThis.find(curE1->getEndNode())),otherStart(mapOther.find(curE2->getStartNode())),otherEnd(mapOther.find(curE2->getEndNode())); - int thisStart2(thisStart==mapThis.end()?-1:(*thisStart).second),thisEnd2(thisEnd==mapThis.end()?-1:(*thisEnd).second),otherStart2(otherStart==mapOther.end()?-1:(*otherStart).second+offset1),otherEnd2(otherEnd==mapOther.end()?-1:(*otherEnd).second+offset1); - // - if(curE1->getPtr()->intersectWith(curE2->getPtr(),merge,*c1,*c2)) - { - if(!curE1->getDirection()) c1->reverse(); - if(!curE2->getDirection()) c2->reverse(); - UpdateNeighbours(merge,it1,it2,c1,c2); - //Substitution of simple edge by sub-edges. - delete curE1; // <-- destroying simple edge coming from pol1 - delete curE2; // <-- destroying simple edge coming from pol2 - it1.insertElemEdges(c1,true);// <-- 2nd param is true to go next. - it2.insertElemEdges(c2,false);// <-- 2nd param is false to avoid to go next. - curE2=it2.current(); - // - it1.assignMySelfToAllElems(c2);//To avoid that others - SoftDelete(c1); - SoftDelete(c2); - c1=new ComposedEdge; - c2=new ComposedEdge; - } - else - { - UpdateNeighbours(merge,it1,it2,curE1,curE2); - it1.next(); - } - merge.updateMergedNodes(thisStart2,thisEnd2,otherStart2,otherEnd2,mergedNodes); - } - } - if(otherTmp.presenceOfOn()) - edgesInOtherColinearWithThis[otherEdgeIds[i]].push_back(cellIdThis); - if(otherTmp._sub_edges.size()>1) - { - for(std::list::const_iterator it=otherTmp._sub_edges.begin();it!=otherTmp._sub_edges.end();it++) - (*it)->fillGlobalInfoAbs2(mapThis,mapOther,offset1,offset2,/**/fact,xBaryBB,yBaryBB,/**/subDivOther[otherEdgeIds[i]],addCoo,mapAddCoo); - } - } - Delete(c1); - Delete(c2); - // - for(std::list::const_iterator it=_sub_edges.begin();it!=_sub_edges.end();it++) - (*it)->fillGlobalInfoAbs(mapThis,mapOther,offset1,offset2,/**/fact,xBaryBB,yBaryBB,/**/edgesThis,addCoo,mapAddCoo); - // -} - -/*! - * This method builds 'this' from its descending conn stored in crude mode (MEDCoupling). - * Descending conn is in FORTRAN relative mode in order to give the - * orientation of edge (see buildDescendingConnectivity2() method). - * See appendEdgeFromCrudeDataArray() for params description. - */ -void QuadraticPolygon::buildFromCrudeDataArray(const std::map& mapp, bool isQuad, const int *nodalBg, const double *coords, - const int *descBg, const int *descEnd, const std::vector >& intersectEdges) -{ - std::size_t nbOfSeg=std::distance(descBg,descEnd); - for(std::size_t i=0;i& mapp, bool isQuad, - const int *nodalBg, const double *coords, - const int *descBg, const int *descEnd, const std::vector >& intersectEdges) -{ - if(!isQuad) - { - bool direct=descBg[edgePos]>0; - int edgeId=abs(descBg[edgePos])-1; // back to C indexing mode - const std::vector& subEdge=intersectEdges[edgeId]; - std::size_t nbOfSubEdges=subEdge.size()/2; - for(std::size_t j=0;j0; - int edgeId=abs(descBg[edgePos])-1; - const std::vector& subEdge=intersectEdges[edgeId]; - std::size_t nbOfSubEdges=subEdge.size()/2; - if(colinearity) - { - for(std::size_t j=0;jdecrRef(); - } - st0->decrRef(); endd0->decrRef(); middle0->decrRef(); - } -} - -void QuadraticPolygon::appendSubEdgeFromCrudeDataArray(Edge *baseEdge, std::size_t j, bool direct, int edgeId, const std::vector& subEdge, const std::map& mapp) -{ - std::size_t nbOfSubEdges=subEdge.size()/2; - if(!baseEdge) - {//it is not a quadratic subedge - Node *start=(*mapp.find(direct?subEdge[2*j]:subEdge[2*nbOfSubEdges-2*j-1])).second; - Node *end=(*mapp.find(direct?subEdge[2*j+1]:subEdge[2*nbOfSubEdges-2*j-2])).second; - ElementaryEdge *e=ElementaryEdge::BuildEdgeFromStartEndDir(true,start,end); - pushBack(e); - } - else - {//it is a quadratic subedge - Node *start=(*mapp.find(direct?subEdge[2*j]:subEdge[2*nbOfSubEdges-2*j-1])).second; - Node *end=(*mapp.find(direct?subEdge[2*j+1]:subEdge[2*nbOfSubEdges-2*j-2])).second; - Edge *ee=baseEdge->buildEdgeLyingOnMe(start,end); - ElementaryEdge *eee=new ElementaryEdge(ee,true); - pushBack(eee); - } -} - -/*! - * This method builds from descending conn of a quadratic polygon stored in crude mode (MEDCoupling). Descending conn is in FORTRAN relative mode in order to give the - * orientation of edge. - */ -void QuadraticPolygon::buildFromCrudeDataArray2(const std::map& mapp, bool isQuad, const int *nodalBg, const double *coords, const int *descBg, const int *descEnd, const std::vector >& intersectEdges, - const INTERP_KERNEL::QuadraticPolygon& pol1, const int *descBg1, const int *descEnd1, const std::vector >& intersectEdges1, - const std::vector< std::vector >& colinear1, - std::map >& alreadyExistingIn2) -{ - std::size_t nbOfSeg=std::distance(descBg,descEnd); - for(std::size_t i=0;i0; - int edgeId=abs(descBg[i])-1;//current edge id of pol2 - std::map >::const_iterator it1=alreadyExistingIn2.find(descBg[i]),it2=alreadyExistingIn2.find(-descBg[i]); - if(it1!=alreadyExistingIn2.end() || it2!=alreadyExistingIn2.end()) - { - bool sameDir=(it1!=alreadyExistingIn2.end()); - const std::vector& edgesAlreadyBuilt=sameDir?(*it1).second:(*it2).second; - if(sameDir) - { - for(std::vector::const_iterator it3=edgesAlreadyBuilt.begin();it3!=edgesAlreadyBuilt.end();it3++) - { - Edge *ee=(*it3)->getPtr(); ee->incrRef(); - pushBack(new ElementaryEdge(ee,(*it3)->getDirection())); - } - } - else - { - for(std::vector::const_reverse_iterator it4=edgesAlreadyBuilt.rbegin();it4!=edgesAlreadyBuilt.rend();it4++) - { - Edge *ee=(*it4)->getPtr(); ee->incrRef(); - pushBack(new ElementaryEdge(ee,!(*it4)->getDirection())); - } - } - continue; - } - bool directos=colinear1[edgeId].empty(); - std::vector > > idIns1; - int offset1=0; - if(!directos) - {// if the current edge of pol2 has one or more colinear edges part into pol1 - const std::vector& c=colinear1[edgeId]; - std::size_t nbOfEdgesIn1=std::distance(descBg1,descEnd1); - for(std::size_t j=0;j >(edgeId1,std::pair(descBg1[j]>0,offset1)));// it exists an edge into pol1 given by tuple (idIn1,direct1) that is colinear at edge 'edgeId' in pol2 - //std::pair0; - } - offset1+=intersectEdges1[edgeId1].size()/2;//offset1 is used to find the INTERP_KERNEL::Edge * instance into pol1 that will be part of edge into pol2 - } - directos=idIns1.empty(); - } - if(directos) - {//no subpart of edge 'edgeId' of pol2 is in pol1 so let's operate the same thing that QuadraticPolygon::buildFromCrudeDataArray method - std::size_t oldSz=_sub_edges.size(); - appendEdgeFromCrudeDataArray(i,mapp,isQuad,nodalBg,coords,descBg,descEnd,intersectEdges); - std::size_t newSz=_sub_edges.size(); - std::size_t zeSz=newSz-oldSz; - alreadyExistingIn2[descBg[i]].resize(zeSz); - std::list::const_reverse_iterator it5=_sub_edges.rbegin(); - for(std::size_t p=0;p& subEdge=intersectEdges[edgeId]; - std::size_t nbOfSubEdges=subEdge.size()/2; - for(std::size_t j=0;j > >::const_iterator it=idIns1.begin();it!=idIns1.end() && !found;it++) - { - int idIn1=(*it).first;//store if needed the cell id in 1 - direct1=(*it).second.first; - offset1=(*it).second.second; - const std::vector& subEdge1PossiblyAlreadyIn1=intersectEdges1[idIn1]; - nbOfSubEdges1=subEdge1PossiblyAlreadyIn1.size()/2; - offset2=0; - for(std::size_t k=0;k build new Edge instance - //appendEdgeFromCrudeDataArray(j,mapp,isQuad,nodalBg,coords,descBg,descEnd,intersectEdges); - Node *start=(*mapp.find(idBg)).second; - Node *end=(*mapp.find(idEnd)).second; - ElementaryEdge *e=ElementaryEdge::BuildEdgeFromStartEndDir(true,start,end); - pushBack(e); - alreadyExistingIn2[descBg[i]].push_back(e); - } - else - {//the current subedge of edge 'edgeId' of pol2 is part of the colinear edge 'idIn1' of pol1 -> reuse Edge instance of pol1 - ElementaryEdge *e=pol1[offset1+(direct1?offset2:nbOfSubEdges1-offset2-1)]; - Edge *ee=e->getPtr(); - ee->incrRef(); - ElementaryEdge *e2=new ElementaryEdge(ee,!(direct1^direction11)); - pushBack(e2); - alreadyExistingIn2[descBg[i]].push_back(e2); - } - } - } - } -} - -/*! - * Method expected to be called on pol2. Every params not suffixed by numbered are supposed to refer to pol2 (this). - * Method to find edges that are ON. - */ -void QuadraticPolygon::updateLocOfEdgeFromCrudeDataArray2(const int *descBg, const int *descEnd, const std::vector >& intersectEdges, - const INTERP_KERNEL::QuadraticPolygon& pol1, const int *descBg1, const int *descEnd1, - const std::vector >& intersectEdges1, const std::vector< std::vector >& colinear1) const -{ - std::size_t nbOfSeg=std::distance(descBg,descEnd); - for(std::size_t i=0;i0; - int edgeId=abs(descBg[i])-1;//current edge id of pol2 - const std::vector& c=colinear1[edgeId]; - if(c.empty()) - continue; - const std::vector& subEdge=intersectEdges[edgeId]; - std::size_t nbOfSubEdges=subEdge.size()/2; - // - std::size_t nbOfEdgesIn1=std::distance(descBg1,descEnd1); - int offset1=0; - for(std::size_t j=0;j0; - const std::vector& subEdge1PossiblyAlreadyIn1=intersectEdges1[idIn1]; - std::size_t nbOfSubEdges1=subEdge1PossiblyAlreadyIn1.size()/2; - int offset2=0; - bool found=false; - for(std::size_t kk=0;kkgetPtr()->declareOn(); - } - } - } - offset1+=intersectEdges1[edgeId1].size()/2;//offset1 is used to find the INTERP_KERNEL::Edge * instance into pol1 that will be part of edge into pol2 - } - } -} - -void QuadraticPolygon::appendCrudeData(const std::map& mapp, double xBary, double yBary, double fact, int offset, std::vector& addCoordsQuadratic, std::vector& conn, std::vector& connI) const -{ - int nbOfNodesInPg=0; - bool presenceOfQuadratic=presenceOfQuadraticEdge(); - conn.push_back(presenceOfQuadratic?NORM_QPOLYG:NORM_POLYGON); - for(std::list::const_iterator it=_sub_edges.begin();it!=_sub_edges.end();it++) - { - Node *tmp=0; - tmp=(*it)->getStartNode(); - std::map::const_iterator it1=mapp.find(tmp); - conn.push_back((*it1).second); - nbOfNodesInPg++; - } - if(presenceOfQuadratic) - { - int j=0; - int off=offset+((int)addCoordsQuadratic.size())/2; - for(std::list::const_iterator it=_sub_edges.begin();it!=_sub_edges.end();it++,j++,nbOfNodesInPg++) - { - INTERP_KERNEL::Node *node=(*it)->getPtr()->buildRepresentantOfMySelf(); - node->unApplySimilarity(xBary,yBary,fact); - addCoordsQuadratic.push_back((*node)[0]); - addCoordsQuadratic.push_back((*node)[1]); - conn.push_back(off+j); - node->decrRef(); - } - } - connI.push_back(connI.back()+nbOfNodesInPg+1); -} - -/*! - * This method make the hypothesis that \a this and \a other are split at the minimum into edges that are fully IN, OUT or ON. - * This method returns newly created polygons in \a conn and \a connI and the corresponding ids ( \a idThis, \a idOther) are stored respectively into \a nbThis and \a nbOther. - * @param [in,out] edgesThis, parameter that keep informed the caller about the edges in this not shared by the result of intersection of \a this with \a other - * @param [in,out] edgesBoundaryOther, parameter that stores all edges in result of intersection that are not - */ -void QuadraticPolygon::buildPartitionsAbs(QuadraticPolygon& other, std::set& edgesThis, std::set& edgesBoundaryOther, const std::map& mapp, int idThis, int idOther, int offset, std::vector& addCoordsQuadratic, std::vector& conn, std::vector& connI, std::vector& nbThis, std::vector& nbOther) -{ - double xBaryBB, yBaryBB; - double fact=normalizeExt(&other, xBaryBB, yBaryBB); - //Locate \a this relative to \a other (edges of \a this, aka \a pol1 are marked as IN or OUT) - other.performLocatingOperationSlow(*this); // without any assumption - std::vector res=buildIntersectionPolygons(other,*this); - for(std::vector::iterator it=res.begin();it!=res.end();it++) - { - (*it)->appendCrudeData(mapp,xBaryBB,yBaryBB,fact,offset,addCoordsQuadratic,conn,connI); - INTERP_KERNEL::IteratorOnComposedEdge it1(*it); - for(it1.first();!it1.finished();it1.next()) - { - Edge *e=it1.current()->getPtr(); - if(edgesThis.find(e)!=edgesThis.end()) - edgesThis.erase(e); - else - { - if(edgesBoundaryOther.find(e)!=edgesBoundaryOther.end()) - edgesBoundaryOther.erase(e); - else - edgesBoundaryOther.insert(e); - } - } - nbThis.push_back(idThis); - nbOther.push_back(idOther); - delete *it; - } - unApplyGlobalSimilarityExt(other,xBaryBB,yBaryBB,fact); -} - -/*! - * Warning This method is \b NOT const. 'this' and 'other' are modified after call of this method. - * 'other' is a QuadraticPolygon of \b non closed edges. - */ -double QuadraticPolygon::intersectWithAbs1D(QuadraticPolygon& other, bool& isColinear) -{ - double ret = 0., xBaryBB, yBaryBB; - double fact = normalize(&other, xBaryBB, yBaryBB); - - QuadraticPolygon cpyOfThis(*this); - QuadraticPolygon cpyOfOther(other); - int nbOfSplits = 0; - SplitPolygonsEachOther(cpyOfThis, cpyOfOther, nbOfSplits); - //At this point cpyOfThis and cpyOfOther have been splited at maximum edge so that in/out can been done. - performLocatingOperation(cpyOfOther); - isColinear = false; - for(std::list::const_iterator it=cpyOfOther._sub_edges.begin();it!=cpyOfOther._sub_edges.end();it++) - { - switch((*it)->getLoc()) - { - case FULL_IN_1: - { - ret += fabs((*it)->getPtr()->getCurveLength()); - break; - } - case FULL_ON_1: - { - isColinear=true; - ret += fabs((*it)->getPtr()->getCurveLength()); - break; - } - default: - { - } - } - } - return ret * fact; -} - -/*! - * Warning contrary to intersectWith method this method is \b NOT const. 'this' and 'other' are modified after call of this method. - */ -double QuadraticPolygon::intersectWithAbs(QuadraticPolygon& other, double* barycenter) -{ - double ret=0.,bary[2],area,xBaryBB,yBaryBB; - barycenter[0] = barycenter[1] = 0.; - double fact=normalize(&other,xBaryBB,yBaryBB); - std::vector polygs=intersectMySelfWith(other); - for(std::vector::iterator iter=polygs.begin();iter!=polygs.end();iter++) - { - area=fabs((*iter)->getArea()); - (*iter)->getBarycenter(bary); - delete *iter; - ret+=area; - barycenter[0] += bary[0]*area; - barycenter[1] += bary[1]*area; - } - if ( ret > std::numeric_limits::min() ) - { - barycenter[0]=barycenter[0]/ret*fact+xBaryBB; - barycenter[1]=barycenter[1]/ret*fact+yBaryBB; - - } - return ret*fact*fact; -} - -/*! - * \b WARNING this method is const and other is const too. \b BUT location of Edges in 'this' and 'other' are nevertheless modified. - * This is possible because loc attribute in Edge class is mutable. - * This implies that if 'this' or/and 'other' are reused for intersect* method initLocations has to be called on each of this/them. - */ -double QuadraticPolygon::intersectWith(const QuadraticPolygon& other) const -{ - double ret=0.; - std::vector polygs=intersectMySelfWith(other); - for(std::vector::iterator iter=polygs.begin();iter!=polygs.end();iter++) - { - ret+=fabs((*iter)->getArea()); - delete *iter; - } - return ret; -} - -/*! - * \b WARNING this method is const and other is const too. \b BUT location of Edges in 'this' and 'other' are nevertheless modified. - * This is possible because loc attribute in Edge class is mutable. - * This implies that if 'this' or/and 'other' are reused for intersect* method initLocations has to be called on each of this/them. - */ -double QuadraticPolygon::intersectWith(const QuadraticPolygon& other, double* barycenter) const -{ - double ret=0., bary[2]; - barycenter[0] = barycenter[1] = 0.; - std::vector polygs=intersectMySelfWith(other); - for(std::vector::iterator iter=polygs.begin();iter!=polygs.end();iter++) - { - double area = fabs((*iter)->getArea()); - (*iter)->getBarycenter(bary); - delete *iter; - ret+=area; - barycenter[0] += bary[0]*area; - barycenter[1] += bary[1]*area; - } - if ( ret > std::numeric_limits::min() ) - { - barycenter[0] /= ret; - barycenter[1] /= ret; - } - return ret; -} - -/*! - * \b WARNING this method is const and other is const too. \b BUT location of Edges in 'this' and 'other' are nevertheless modified. - * This is possible because loc attribute in Edge class is mutable. - * This implies that if 'this' or/and 'other' are reused for intersect* method initLocations has to be called on each of this/them. - */ -void QuadraticPolygon::intersectForPerimeter(const QuadraticPolygon& other, double& perimeterThisPart, double& perimeterOtherPart, double& perimeterCommonPart) const -{ - perimeterThisPart=0.; perimeterOtherPart=0.; perimeterCommonPart=0.; - QuadraticPolygon cpyOfThis(*this); - QuadraticPolygon cpyOfOther(other); int nbOfSplits=0; - SplitPolygonsEachOther(cpyOfThis,cpyOfOther,nbOfSplits); - performLocatingOperation(cpyOfOther); - other.performLocatingOperation(cpyOfThis); - cpyOfThis.dispatchPerimeterExcl(perimeterThisPart,perimeterCommonPart); - cpyOfOther.dispatchPerimeterExcl(perimeterOtherPart,perimeterCommonPart); - perimeterCommonPart/=2.; -} - -/*! - * \b WARNING this method is const and other is const too. \b BUT location of Edges in 'this' and 'other' are nevertheless modified. - * This is possible because loc attribute in Edge class is mutable. - * This implies that if 'this' or/and 'other' are reused for intersect* method initLocations has to be called on each of this/them. - * - * polThis.size()==this->size() and polOther.size()==other.size(). - * For each ElementaryEdge of 'this', the corresponding contribution in resulting polygon is in 'polThis'. - * For each ElementaryEdge of 'other', the corresponding contribution in resulting polygon is in 'polOther'. - * As consequence common part are counted twice (in polThis \b and in polOther). - */ -void QuadraticPolygon::intersectForPerimeterAdvanced(const QuadraticPolygon& other, std::vector< double >& polThis, std::vector< double >& polOther) const -{ - polThis.resize(size()); - polOther.resize(other.size()); - IteratorOnComposedEdge it1(const_cast(this)); - int edgeId=0; - for(it1.first();!it1.finished();it1.next(),edgeId++) - { - ElementaryEdge* curE1=it1.current(); - QuadraticPolygon cpyOfOther(other); - QuadraticPolygon tmp; - tmp.pushBack(curE1->clone()); - int tmp2; - SplitPolygonsEachOther(tmp,cpyOfOther,tmp2); - other.performLocatingOperation(tmp); - tmp.dispatchPerimeter(polThis[edgeId]); - } - // - IteratorOnComposedEdge it2(const_cast(&other)); - edgeId=0; - for(it2.first();!it2.finished();it2.next(),edgeId++) - { - ElementaryEdge* curE2=it2.current(); - QuadraticPolygon cpyOfThis(*this); - QuadraticPolygon tmp; - tmp.pushBack(curE2->clone()); - int tmp2; - SplitPolygonsEachOther(tmp,cpyOfThis,tmp2); - performLocatingOperation(tmp); - tmp.dispatchPerimeter(polOther[edgeId]); - } -} - - -/*! - * numberOfCreatedPointsPerEdge is resized to the number of edges of 'this'. - * This method returns in ordered maner the number of newly created points per edge. - * This method performs a split process between 'this' and 'other' that gives the result PThis. - * Then for each edges of 'this' this method counts how many edges in Pthis have the same id. - */ -void QuadraticPolygon::intersectForPoint(const QuadraticPolygon& other, std::vector< int >& numberOfCreatedPointsPerEdge) const -{ - numberOfCreatedPointsPerEdge.resize(size()); - IteratorOnComposedEdge it1(const_cast(this)); - int edgeId=0; - for(it1.first();!it1.finished();it1.next(),edgeId++) - { - ElementaryEdge* curE1=it1.current(); - QuadraticPolygon cpyOfOther(other); - QuadraticPolygon tmp; - tmp.pushBack(curE1->clone()); - int tmp2; - SplitPolygonsEachOther(tmp,cpyOfOther,tmp2); - numberOfCreatedPointsPerEdge[edgeId]=tmp.recursiveSize()-1; - } -} - -/*! - * \b WARNING this method is const and other is const too. \b BUT location of Edges in 'this' and 'other' are nevertheless modified. - * This is possible because loc attribute in Edge class is mutable. - * This implies that if 'this' or/and 'other' are reused for intersect* method initLocations has to be called on each of this/them. - */ -std::vector QuadraticPolygon::intersectMySelfWith(const QuadraticPolygon& other) const -{ - QuadraticPolygon cpyOfThis(*this); - QuadraticPolygon cpyOfOther(other); int nbOfSplits=0; - SplitPolygonsEachOther(cpyOfThis,cpyOfOther,nbOfSplits); - //At this point cpyOfThis and cpyOfOther have been splited at maximum edge so that in/out can been done. - performLocatingOperation(cpyOfOther); - return other.buildIntersectionPolygons(cpyOfThis,cpyOfOther); -} - -/*! - * This method is typically the first step of boolean operations between pol1 and pol2. - * This method perform the minimal splitting so that at the end each edges constituting pol1 are fully either IN or OUT or ON. - * @param pol1 IN/OUT param that is equal to 'this' when called. - */ -void QuadraticPolygon::SplitPolygonsEachOther(QuadraticPolygon& pol1, QuadraticPolygon& pol2, int& nbOfSplits) -{ - IteratorOnComposedEdge it1(&pol1),it2(&pol2); - MergePoints merge; - ComposedEdge *c1=new ComposedEdge; - ComposedEdge *c2=new ComposedEdge; - for(it2.first();!it2.finished();it2.next()) - { - ElementaryEdge* curE2=it2.current(); - if(!curE2->isThereStartPoint()) - it1.first(); - else - it1=curE2->getIterator(); - for(;!it1.finished();) - { - - ElementaryEdge* curE1=it1.current(); - merge.clear(); nbOfSplits++; - if(curE1->getPtr()->intersectWith(curE2->getPtr(),merge,*c1,*c2)) - { - if(!curE1->getDirection()) c1->reverse(); - if(!curE2->getDirection()) c2->reverse(); - UpdateNeighbours(merge,it1,it2,c1,c2); - //Substitution of simple edge by sub-edges. - delete curE1; // <-- destroying simple edge coming from pol1 - delete curE2; // <-- destroying simple edge coming from pol2 - it1.insertElemEdges(c1,true);// <-- 2nd param is true to go next. - it2.insertElemEdges(c2,false);// <-- 2nd param is false to avoid to go next. - curE2=it2.current(); - // - it1.assignMySelfToAllElems(c2);//To avoid that others - SoftDelete(c1); - SoftDelete(c2); - c1=new ComposedEdge; - c2=new ComposedEdge; - } - else - { - UpdateNeighbours(merge,it1,it2,curE1,curE2); - it1.next(); - } - } - } - Delete(c1); - Delete(c2); -} - -void QuadraticPolygon::performLocatingOperation(QuadraticPolygon& pol1) const -{ - IteratorOnComposedEdge it(&pol1); - TypeOfEdgeLocInPolygon loc=FULL_ON_1; - for(it.first();!it.finished();it.next()) - { - ElementaryEdge *cur=it.current(); - loc=cur->locateFullyMySelf(*this,loc);//*this=pol2=other - } -} - -void QuadraticPolygon::performLocatingOperationSlow(QuadraticPolygon& pol2) const -{ - IteratorOnComposedEdge it(&pol2); - for(it.first();!it.finished();it.next()) - { - ElementaryEdge *cur=it.current(); - cur->locateFullyMySelfAbsolute(*this); - } -} - -/*! - * Given 2 polygons \a pol1 and \a pol2 (localized) the resulting polygons are returned. - * - * this : pol2 simplified. - * @param [in] pol1 pol1 split. - * @param [in] pol2 pol2 split. - */ -std::vector QuadraticPolygon::buildIntersectionPolygons(const QuadraticPolygon& pol1, const QuadraticPolygon& pol2) const -{ - std::vector ret; - std::list pol2Zip=pol2.zipConsecutiveInSegments(); - if(!pol2Zip.empty()) - ClosePolygons(pol2Zip,pol1,*this,ret); - else - {//borders of pol2 do not cross pol1,and pol2 borders are outside of pol1. That is to say, either pol2 and pol1 - //do not overlap or pol1 is fully inside pol2. So in the first case no intersection, in the other case - //the intersection is pol1. - ElementaryEdge *e1FromPol1=pol1[0]; - TypeOfEdgeLocInPolygon loc=FULL_ON_1; - loc=e1FromPol1->locateFullyMySelf(*this,loc); - if(loc==FULL_IN_1) - ret.push_back(new QuadraticPolygon(pol1)); - } - return ret; -} - -/*! - * Returns parts of potentially non closed-polygons. Each returned polygons are not mergeable. - * this : pol2 split and locallized. - */ -std::list QuadraticPolygon::zipConsecutiveInSegments() const -{ - std::list ret; - IteratorOnComposedEdge it(const_cast(this)); - int nbOfTurns=recursiveSize(); - int i=0; - if(!it.goToNextInOn(false,i,nbOfTurns)) - return ret; - i=0; - // - while(igetLoc(); - while(loc!=FULL_OUT_1 && iclone(); - tmp1->pushBack(tmp3); - it.nextLoop(); i++; - loc=it.current()->getLoc(); - } - if(tmp1->empty()) - { - delete tmp1; - continue; - } - ret.push_back(tmp1); - it.goToNextInOn(true,i,nbOfTurns); - } - return ret; -} - -/*! - * @param [in] pol2zip is a list of set of edges (=an opened polygon) coming from split polygon 2. - * @param [in] pol1 is split pol1. - * @param [in] pol2 should be considered as pol2Simplified. - * @param [out] results the resulting \b CLOSED polygons. - */ -void QuadraticPolygon::ClosePolygons(std::list& pol2Zip, const QuadraticPolygon& pol1, const QuadraticPolygon& pol2, - std::vector& results) -{ - bool directionKnownInPol1=false; - bool directionInPol1; - for(std::list::iterator iter=pol2Zip.begin();iter!=pol2Zip.end();) - { - if((*iter)->completed()) - { - results.push_back(*iter); - directionKnownInPol1=false; - iter=pol2Zip.erase(iter); - continue; - } - if(!directionKnownInPol1) - { - if(!(*iter)->haveIAChanceToBeCompletedBy(pol1,pol2,directionInPol1)) - { delete *iter; iter=pol2Zip.erase(iter); continue; } - else - directionKnownInPol1=true; - } - std::list::iterator iter2=iter; iter2++; - std::list::iterator iter3=(*iter)->fillAsMuchAsPossibleWith(pol1,iter2,pol2Zip.end(),directionInPol1); - if(iter3!=pol2Zip.end()) - { - (*iter)->pushBack(*iter3); - SoftDelete(*iter3); - pol2Zip.erase(iter3); - } - } -} - -/*! - * 'this' is expected to be set of edges (not closed) of pol2 split. - */ -bool QuadraticPolygon::haveIAChanceToBeCompletedBy(const QuadraticPolygon& pol1Splitted,const QuadraticPolygon& pol2NotSplitted, bool& direction) -{ - IteratorOnComposedEdge it(const_cast(&pol1Splitted)); - bool found=false; - Node *n=getEndNode(); - ElementaryEdge *cur=it.current(); - for(it.first();!it.finished() && !found;) - { - cur=it.current(); - found=(cur->getStartNode()==n); - if(!found) - it.next(); - } - if(!found) - throw Exception("Internal error: polygons incompatible with each others. Should never happen!"); - //Ok we found correspondance between this and pol1. Searching for right direction to close polygon. - ElementaryEdge *e=_sub_edges.back(); - if(e->getLoc()==FULL_ON_1) - { - if(e->getPtr()==cur->getPtr()) - { - direction=false; - it.previousLoop(); - cur=it.current(); - Node *repr=cur->getPtr()->buildRepresentantOfMySelf(); - bool ret=pol2NotSplitted.isInOrOut(repr); - repr->decrRef(); - return ret; - } - else - { - direction=true; - Node *repr=cur->getPtr()->buildRepresentantOfMySelf(); - bool ret=pol2NotSplitted.isInOrOut(repr); - repr->decrRef(); - return ret; - } - } - else - direction=cur->locateFullyMySelfAbsolute(pol2NotSplitted)==FULL_IN_1; - return true; -} - -/*! - * This method fills as much as possible \a this (a sub-part of pol2 split) with edges of \a pol1Splitted. - */ -std::list::iterator QuadraticPolygon::fillAsMuchAsPossibleWith(const QuadraticPolygon& pol1Splitted, - std::list::iterator iStart, - std::list::iterator iEnd, - bool direction) -{ - IteratorOnComposedEdge it(const_cast(&pol1Splitted)); - bool found=false; - Node *n=getEndNode(); - ElementaryEdge *cur; - for(it.first();!it.finished() && !found;) - { - cur=it.current(); - found=(cur->getStartNode()==n); - if(!found) - it.next(); - } - if(!direction) - it.previousLoop(); - Node *nodeToTest; - int szMax(pol1Splitted.size()+1),ii(0);// here a protection against agressive users of IntersectMeshes of invalid input meshes - std::list::iterator ret; - do - { - cur=it.current(); - ElementaryEdge *tmp=cur->clone(); - if(!direction) - tmp->reverse(); - pushBack(tmp); - nodeToTest=tmp->getEndNode(); - direction?it.nextLoop():it.previousLoop(); - ret=CheckInList(nodeToTest,iStart,iEnd); - if(completed()) - return iEnd; - ii++; - } - while(ret==iEnd && ii::iterator QuadraticPolygon::CheckInList(Node *n, std::list::iterator iStart, - std::list::iterator iEnd) -{ - for(std::list::iterator iter=iStart;iter!=iEnd;iter++) - if((*iter)->isNodeIn(n)) - return iter; - return iEnd; -} - -void QuadraticPolygon::ComputeResidual(const QuadraticPolygon& pol1, const std::set& notUsedInPol1, const std::set& edgesInPol2OnBoundary, const std::map& mapp, int offset, int idThis, - std::vector& addCoordsQuadratic, std::vector& conn, std::vector& connI, std::vector& nb1, std::vector& nb2) -{ - pol1.initLocations(); - for(std::set::const_iterator it9=notUsedInPol1.begin();it9!=notUsedInPol1.end();it9++) - { (*it9)->initLocs(); (*it9)->declareOn(); } - for(std::set::const_iterator itA=edgesInPol2OnBoundary.begin();itA!=edgesInPol2OnBoundary.end();itA++) - { (*itA)->initLocs(); (*itA)->declareIn(); } - //// - std::set notUsedInPol1L(notUsedInPol1); - IteratorOnComposedEdge it(const_cast(&pol1)); - int sz=pol1.size(); - std::list pol1Zip; - if(pol1.size()==(int)notUsedInPol1.size() && edgesInPol2OnBoundary.empty()) - { - pol1.appendCrudeData(mapp,0.,0.,1.,offset,addCoordsQuadratic,conn,connI); nb1.push_back(idThis); nb2.push_back(-1); - return ; - } - while(!notUsedInPol1L.empty()) - { - for(int i=0;igetStartNode()->getLoc()!=IN_1 || it.current()->getLoc()!=FULL_ON_1);i++) - it.nextLoop(); - if(it.current()->getStartNode()->getLoc()!=IN_1 || it.current()->getLoc()!=FULL_ON_1) - throw INTERP_KERNEL::Exception("Presence of a target polygon fully included in source polygon ! The partition of this leads to a non simply connex cell (with hole) ! Impossible ! Such resulting cell cannot be stored in MED cell format !"); - QuadraticPolygon *tmp1=new QuadraticPolygon; - do - { - Edge *ee=it.current()->getPtr(); - if(ee->getLoc()==FULL_ON_1) - { - ee->incrRef(); notUsedInPol1L.erase(ee); - tmp1->pushBack(new ElementaryEdge(ee,it.current()->getDirection())); - } - it.nextLoop(); - } - while(it.current()->getStartNode()->getLoc()!=IN_1 && !notUsedInPol1L.empty()); - pol1Zip.push_back(tmp1); - } - //// - std::list retPolsUnderContruction; - std::list edgesInPol2OnBoundaryL(edgesInPol2OnBoundary.begin(),edgesInPol2OnBoundary.end()); - std::map > pol1ZipConsumed; - 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();) - { - if((*it1)->getStartNode()==(*it1)->getEndNode()) - { - it1++; - continue; - } - Node *curN=(*it1)->getEndNode(); - bool smthHappened=false; - for(std::list::iterator it2=edgesInPol2OnBoundaryL.begin();it2!=edgesInPol2OnBoundaryL.end();) - { - if(curN==(*it2)->getStartNode()) - { (*it2)->incrRef(); (*it1)->pushBack(new ElementaryEdge(*it2,true)); curN=(*it2)->getEndNode(); smthHappened=true; it2=edgesInPol2OnBoundaryL.erase(it2); } - else if(curN==(*it2)->getEndNode()) - { (*it2)->incrRef(); (*it1)->pushBack(new ElementaryEdge(*it2,false)); curN=(*it2)->getStartNode(); smthHappened=true; it2=edgesInPol2OnBoundaryL.erase(it2); } - else - it2++; - } - if(smthHappened) - { - for(std::list::iterator it3=pol1Zip.begin();it3!=pol1Zip.end();) - { - if(curN==(*it3)->getStartNode()) - { - for(std::list::const_iterator it4=(*it3)->_sub_edges.begin();it4!=(*it3)->_sub_edges.end();it4++) - { (*it4)->getPtr()->incrRef(); bool dir=(*it4)->getDirection(); (*it1)->pushBack(new ElementaryEdge((*it4)->getPtr(),dir)); } - smthHappened=true; - pol1ZipConsumed[*it1].push_back(*it3); - curN=(*it3)->getEndNode(); - it3=pol1Zip.erase(it3); - } - else - it3++; - } - } - if(!smthHappened) - { - for(std::list::const_iterator it5=(*it1)->_sub_edges.begin();it5!=(*it1)->_sub_edges.end();it5++) - { - Edge *ee=(*it5)->getPtr(); - if(edgesInPol2OnBoundary.find(ee)!=edgesInPol2OnBoundary.end()) - edgesInPol2OnBoundaryL.push_back(ee); - } - for(std::list::iterator it6=pol1ZipConsumed[*it1].begin();it6!=pol1ZipConsumed[*it1].end();it6++) - pol1Zip.push_front(*it6); - pol1ZipConsumed.erase(*it1); - delete *it1; - it1=retPolsUnderContruction.erase(it1); - } - } - if(!pol1Zip.empty()) - { - QuadraticPolygon *tmp=new QuadraticPolygon; - QuadraticPolygon *first=*(pol1Zip.begin()); - for(std::list::const_iterator it4=first->_sub_edges.begin();it4!=first->_sub_edges.end();it4++) - { (*it4)->getPtr()->incrRef(); bool dir=(*it4)->getDirection(); tmp->pushBack(new ElementaryEdge((*it4)->getPtr(),dir)); } - pol1ZipConsumed[tmp].push_back(first); - 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++) - { - if((*it1)->getStartNode()==(*it1)->getEndNode()) - { - (*it1)->appendCrudeData(mapp,0.,0.,1.,offset,addCoordsQuadratic,conn,connI); nb1.push_back(idThis); nb2.push_back(-1); - for(std::list::iterator it6=pol1ZipConsumed[*it1].begin();it6!=pol1ZipConsumed[*it1].end();it6++) - delete *it6; - delete *it1; - } - } -} diff --git a/src/INTERP_KERNEL/Geometric2D/InterpKernelGeo2DQuadraticPolygon.hxx b/src/INTERP_KERNEL/Geometric2D/InterpKernelGeo2DQuadraticPolygon.hxx deleted file mode 100644 index ee9ca5bc0..000000000 --- a/src/INTERP_KERNEL/Geometric2D/InterpKernelGeo2DQuadraticPolygon.hxx +++ /dev/null @@ -1,126 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 -// 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 __INTERPKERNELGEO2DQUADRATICPOLYGON_HXX__ -#define __INTERPKERNELGEO2DQUADRATICPOLYGON_HXX__ - -#include "INTERPKERNELDefines.hxx" - -#include "InterpKernelGeo2DComposedEdge.hxx" -#include "InterpKernelGeo2DAbstractEdge.hxx" -#include "InterpKernelGeo2DElementaryEdge.hxx" - -#include -#include - -namespace INTERP_KERNEL -{ - class Edge; - class MergePoints; - - /** - * A set of quadratic or linear edges, not necessarily connected to form a closed polygon. - * Some methods however requires a closed form. - * Class ComposedEdge focuses more on connectivity aspect. - */ - class QuadraticPolygon : public ComposedEdge - { - public: - INTERPKERNEL_EXPORT QuadraticPolygon() { } - INTERPKERNEL_EXPORT QuadraticPolygon(const QuadraticPolygon& other):ComposedEdge(other) { } - INTERPKERNEL_EXPORT QuadraticPolygon(const char *fileName); - INTERPKERNEL_EXPORT static QuadraticPolygon *BuildLinearPolygon(std::vector& nodes); - INTERPKERNEL_EXPORT static QuadraticPolygon *BuildArcCirclePolygon(std::vector& nodes); - INTERPKERNEL_EXPORT static Edge *BuildLinearEdge(std::vector& nodes); - INTERPKERNEL_EXPORT static Edge *BuildArcCircleEdge(std::vector& nodes); - INTERPKERNEL_EXPORT static void BuildDbgFile(const std::vector& nodes, const char *fileName); - INTERPKERNEL_EXPORT ~QuadraticPolygon(); - INTERPKERNEL_EXPORT void closeMe() const; - INTERPKERNEL_EXPORT void circularPermute(); - INTERPKERNEL_EXPORT bool isButterflyAbs(); - INTERPKERNEL_EXPORT bool isButterfly() const; - INTERPKERNEL_EXPORT void dumpInXfigFile(const char *fileName) const; - INTERPKERNEL_EXPORT void dumpInXfigFileWithOther(const ComposedEdge& other, const char *fileName) const; - //! Before intersecting as intersectWith a normalization is done. - INTERPKERNEL_EXPORT double intersectWithAbs(QuadraticPolygon& other); - INTERPKERNEL_EXPORT double intersectWithAbs1D(QuadraticPolygon& other, bool& isColinear); - //! Before intersecting as intersectWith a normalization is done. - INTERPKERNEL_EXPORT double intersectWithAbs(QuadraticPolygon& other, double* barycenter); - INTERPKERNEL_EXPORT void splitAbs(QuadraticPolygon& other, const std::map& mapThis, const std::map& mapOther, int offset1, int offset2, const std::vector& otherEdgeIds, - std::vector& edgesThis, int cellIdThis, std::vector< std::vector >& edgesInOtherColinearWithThis, std::vector< std::vector >& subDivOther, std::vector& addCoo, std::map& mergedNodes); - INTERPKERNEL_EXPORT void buildFromCrudeDataArray(const std::map& mapp, bool isQuad, const int *nodalBg, const double *coords, - const int *descBg, const int *descEnd, const std::vector >& intersectEdges); - INTERPKERNEL_EXPORT void buildFromCrudeDataArray2(const std::map& mapp, bool isQuad, const int *nodalBg, const double *coords, const int *descBg, const int *descEnd, const std::vector >& intersectEdges, - const INTERP_KERNEL::QuadraticPolygon& pol1, const int *descBg1, const int *descEnd1, const std::vector >& intersectEdges1, - const std::vector< std::vector >& colinear1, - std::map >& alreadyExistingIn2); - INTERPKERNEL_EXPORT void updateLocOfEdgeFromCrudeDataArray2(const int *descBg, const int *descEnd, const std::vector >& intersectEdges, const INTERP_KERNEL::QuadraticPolygon& pol1, const int *descBg1, const int *descEnd1, const std::vector >& intersectEdges1, const std::vector< std::vector >& colinear1) const; - INTERPKERNEL_EXPORT void appendEdgeFromCrudeDataArray(std::size_t edgeId, const std::map& mapp, bool isQuad, const int *nodalBg, const double *coords, - const int *descBg, const int *descEnd, const std::vector >& intersectEdges); - INTERPKERNEL_EXPORT void appendSubEdgeFromCrudeDataArray(Edge *baseEdge, std::size_t j, bool direct, int edgeId, const std::vector& subEdge, const std::map& mapp); - INTERPKERNEL_EXPORT void appendCrudeData(const std::map& mapp, double xBary, double yBary, double fact, int offset, std::vector& addCoordsQuadratic, std::vector& conn, std::vector& connI) const; - INTERPKERNEL_EXPORT void buildPartitionsAbs(QuadraticPolygon& other, std::set& edgesThis, std::set& edgesBoundaryOther, const std::map& mapp, int idThis, int idOther, int offset, - std::vector& addCoordsQuadratic, std::vector& conn, std::vector& connI, std::vector& nb1, std::vector& nb2); - // - INTERPKERNEL_EXPORT double intersectWith(const QuadraticPolygon& other) const; - INTERPKERNEL_EXPORT double intersectWith(const QuadraticPolygon& other, double* barycenter) const; - INTERPKERNEL_EXPORT std::vector intersectMySelfWith(const QuadraticPolygon& other) const; - INTERPKERNEL_EXPORT void intersectForPerimeter(const QuadraticPolygon& other, double& perimeterThisPart, double& perimeterOtherPart, double& perimeterCommonPart) const; - INTERPKERNEL_EXPORT void intersectForPerimeterAdvanced(const QuadraticPolygon& other, std::vector< double >& polThis, std::vector< double >& polOther) const; - INTERPKERNEL_EXPORT void intersectForPoint(const QuadraticPolygon& other, std::vector< int >& numberOfCreatedPointsPerEdge) const; - public://Only public for tests reasons - INTERPKERNEL_EXPORT void performLocatingOperation(QuadraticPolygon& pol2) const; - INTERPKERNEL_EXPORT void performLocatingOperationSlow(QuadraticPolygon& pol2) const; - INTERPKERNEL_EXPORT static void SplitPolygonsEachOther(QuadraticPolygon& pol1, QuadraticPolygon& pol2, int& nbOfSplits); - INTERPKERNEL_EXPORT std::vector buildIntersectionPolygons(const QuadraticPolygon& pol1, const QuadraticPolygon& pol2) const; - INTERPKERNEL_EXPORT bool haveIAChanceToBeCompletedBy(const QuadraticPolygon& pol1Splitted, const QuadraticPolygon& pol2NotSplitted, bool& direction); - INTERPKERNEL_EXPORT static void ComputeResidual(const QuadraticPolygon& pol1, const std::set& notUsedInPol1, const std::set& edgesInPol2OnBoundary, const std::map& mapp, int offset, int idThis, - std::vector& addCoordsQuadratic, std::vector& conn, std::vector& connI, std::vector& nb1, std::vector& nb2); - protected: - std::list zipConsecutiveInSegments() const; - void dumpInXfigFile(std::ostream& stream, int resolution, const Bounds& box) const; - static void ClosePolygons(std::list& pol2Zip, const QuadraticPolygon& pol1, const QuadraticPolygon& pol2, std::vector& results); - template - static void UpdateNeighbours(const MergePoints& merger, IteratorOnComposedEdge it1, IteratorOnComposedEdge it2, - const EDGES *e1, const EDGES *e2); - std::list::iterator fillAsMuchAsPossibleWith(const QuadraticPolygon& pol1Splitted, - std::list::iterator iStart, - std::list::iterator iEnd, - bool direction); - static std::list::iterator CheckInList(Node *n, std::list::iterator iStart, - std::list::iterator iEnd); - }; -} - -namespace INTERP_KERNEL -{ - template - void QuadraticPolygon::UpdateNeighbours(const MergePoints& merger, IteratorOnComposedEdge it1, IteratorOnComposedEdge it2, - const EDGES *e1, const EDGES *e2) - { - it1.previousLoop(); it2.previousLoop(); - ElementaryEdge *curE1=it1.current(); ElementaryEdge *curE2=it2.current(); - curE1->changeEndNodeWith(e1->getStartNode()); curE2->changeEndNodeWith(e2->getStartNode()); - it1.nextLoop(); it1.nextLoop(); it2.nextLoop(); it2.nextLoop(); - curE1->changeStartNodeWith(e1->getEndNode()); curE2->changeStartNodeWith(e2->getEndNode()); - } -} - -#endif diff --git a/src/INTERP_KERNEL/Geometric2DIntersector.hxx b/src/INTERP_KERNEL/Geometric2DIntersector.hxx deleted file mode 100644 index 1de6c446f..000000000 --- a/src/INTERP_KERNEL/Geometric2DIntersector.hxx +++ /dev/null @@ -1,60 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 -// 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 __GEOMETRIC2DINTERSECTOR_HXX__ -#define __GEOMETRIC2DINTERSECTOR_HXX__ - -#include "PlanarIntersectorP0P0.hxx" -#include "PlanarIntersectorP0P1.hxx" -#include "PlanarIntersectorP1P0.hxx" -#include "PlanarIntersectorP1P1.hxx" -#include "PlanarIntersectorP1P0Bary.hxx" -#include "PlanarIntersectorP0P1Bary.hxx" - -namespace INTERP_KERNEL -{ - class QuadraticPolygon; - - template class InterpType> - class Geometric2DIntersector : public InterpType > - { - public: - static const int SPACEDIM=MyMeshType::MY_SPACEDIM; - static const int MESHDIM=MyMeshType::MY_MESHDIM; - typedef typename MyMeshType::MyConnType ConnType; - static const NumberingPolicy numPol=MyMeshType::My_numPol; - public: - Geometric2DIntersector(const MyMeshType& meshT, const MyMeshType& meshS, - double dimCaracteristic, double md3DSurf, double minDot3DSurf, double medianPlane, double precision, int orientation); - double intersectGeometry(ConnType icellT, ConnType icellS, ConnType nbNodesT, ConnType nbNodesS); - double intersectGeometry1D(ConnType icellT, ConnType icellS, ConnType nbNodesT, ConnType nbNodesS, - bool& isColinear); - double intersectGeometryWithQuadrangle(const double *quadrangle, const std::vector& sourceCoords, bool isSourceQuad); - double intersectGeometryGeneral(const std::vector& targetCoords, const std::vector& sourceCoords); - double intersectGeoBary(const std::vector& targetCell, bool targetCellQuadratic, const double *sourceCell, std::vector& res); - private: - QuadraticPolygon *buildPolygonFrom(const std::vector& coords, NormalizedCellType type); - QuadraticPolygon *buildPolygonOfOneEdgeFrom(const std::vector& coords, NormalizedCellType type); - QuadraticPolygon *buildPolygonAFrom(ConnType cell, int nbOfPoints, NormalizedCellType type); - QuadraticPolygon *buildPolygonBFrom(ConnType cell, int nbOfPoints, NormalizedCellType type); - }; -} - -#endif diff --git a/src/INTERP_KERNEL/Geometric2DIntersector.txx b/src/INTERP_KERNEL/Geometric2DIntersector.txx deleted file mode 100644 index 81998de5e..000000000 --- a/src/INTERP_KERNEL/Geometric2DIntersector.txx +++ /dev/null @@ -1,250 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 -// 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 __GEOMETRIC2DINTERSECTOR_TXX__ -#define __GEOMETRIC2DINTERSECTOR_TXX__ - -#include "Geometric2DIntersector.hxx" -#include "PlanarIntersectorP0P0.txx" -#include "Planar2D1DIntersectorP0P0.txx" -#include "PlanarIntersectorP0P1.txx" -#include "PlanarIntersectorP1P0.txx" -#include "PlanarIntersectorP1P1.txx" -#include "PlanarIntersectorP1P0Bary.txx" -#include "PlanarIntersectorP0P1Bary.txx" -#include "CellModel.hxx" - -#include "InterpKernelGeo2DQuadraticPolygon.hxx" -#include "InterpKernelGeo2DEdgeArcCircle.hxx" -#include "InterpKernelGeo2DEdgeLin.hxx" -#include "InterpKernelGeo2DNode.hxx" - -#define GEO2D_INTERSECTOR Geometric2DIntersector -#define INTERSECTOR_TEMPLATE template class InterpType> - -namespace INTERP_KERNEL -{ - INTERSECTOR_TEMPLATE - GEO2D_INTERSECTOR::Geometric2DIntersector(const MyMeshType& meshT, const MyMeshType& meshS, - double dimCaracteristic, double md3DSurf, double minDot3DSurf, double medianPlane, - double precision, int orientation): - InterpType(meshT,meshS,dimCaracteristic, precision, md3DSurf, minDot3DSurf, medianPlane, true, orientation, 0) - { - QUADRATIC_PLANAR::_precision=precision; - } - - INTERSECTOR_TEMPLATE - double GEO2D_INTERSECTOR::intersectGeometry(ConnType icellT, ConnType icellS, - ConnType nbNodesT, ConnType nbNodesS) - { - int orientation = 1; - std::vector CoordsT; - std::vector CoordsS; - PlanarIntersector::getRealCoordinates(icellT,icellS,nbNodesT,nbNodesS,CoordsT,CoordsS,orientation); - NormalizedCellType tT=PlanarIntersector::_meshT.getTypeOfElement(icellT); - NormalizedCellType tS=PlanarIntersector::_meshS.getTypeOfElement(icellS); - QuadraticPolygon *p1=buildPolygonFrom(CoordsT,tT); - QuadraticPolygon *p2=buildPolygonFrom(CoordsS,tS); - double ret=p1->intersectWithAbs(*p2); - delete p1; delete p2; - return orientation*ret; - } - - INTERSECTOR_TEMPLATE - double GEO2D_INTERSECTOR::intersectGeometry1D(ConnType icellT, ConnType icellS, - ConnType nbNodesT, ConnType nbNodesS, - bool& isColinear) - { - int orientation = 1; - std::vector CoordsT; - std::vector CoordsS; - PlanarIntersector::getRealCoordinates(icellT,icellS,nbNodesT,nbNodesS,CoordsT,CoordsS,orientation); - NormalizedCellType tT=PlanarIntersector::_meshT.getTypeOfElement(icellT); - NormalizedCellType tS=PlanarIntersector::_meshS.getTypeOfElement(icellS); - QuadraticPolygon *p1=buildPolygonFrom(CoordsT,tT); - QuadraticPolygon *p2=buildPolygonOfOneEdgeFrom(CoordsS,tS); - double ret=p1->intersectWithAbs1D(*p2, isColinear); - delete p1; delete p2; - return orientation*ret; - } - - INTERSECTOR_TEMPLATE - double GEO2D_INTERSECTOR::intersectGeometryWithQuadrangle(const double * quadrangle, - const std::vector& sourceCoords, - bool isSourceQuad) - { - std::vector nodes(4); - nodes[0]=new Node(quadrangle[0],quadrangle[1]); - nodes[1]=new Node(quadrangle[SPACEDIM],quadrangle[SPACEDIM+1]); - nodes[2]=new Node(quadrangle[2*SPACEDIM],quadrangle[2*SPACEDIM+1]); - nodes[3]=new Node(quadrangle[3*SPACEDIM],quadrangle[3*SPACEDIM+1]); - int nbOfSourceNodes=sourceCoords.size()/SPACEDIM; - std::vector nodes2(nbOfSourceNodes); - for(int i=0;iintersectWithAbs(*p2); - delete p1; delete p2; - return ret; - } - - INTERSECTOR_TEMPLATE - double GEO2D_INTERSECTOR::intersectGeometryGeneral(const std::vector& targetCoords, - const std::vector& sourceCoords) - { - int nbOfTargetNodes=targetCoords.size()/SPACEDIM; - std::vector nodes(nbOfTargetNodes); - for(int i=0;i nodes2(nbOfSourceNodes); - for(int i=0;iintersectWithAbs(*p2); - delete p1; delete p2; - return ret; - } - - //================================================================================ - /*! - * \brief Intersect a triangle and a polygon for P1P0 barycentric algorithm - * \param targetCell - list of coordinates of target polygon in full interlace - * \param targetCellQuadratic - specifies if target polygon is quadratic or not - * \param sourceTria - list of coordinates of source triangle - * \param res - coefficients a,b and c associated to nodes of sourceTria - */ - //================================================================================ - - INTERSECTOR_TEMPLATE - double GEO2D_INTERSECTOR::intersectGeoBary(const std::vector& targetCell, - bool targetCellQuadratic, - const double * sourceTria, - std::vector& res) - { - std::vector nodes(3); - nodes[0]=new Node(sourceTria[0*SPACEDIM],sourceTria[0*SPACEDIM+1]); - nodes[1]=new Node(sourceTria[1*SPACEDIM],sourceTria[1*SPACEDIM+1]); - nodes[2]=new Node(sourceTria[2*SPACEDIM],sourceTria[2*SPACEDIM+1]); - int nbOfTargetNodes=targetCell.size()/SPACEDIM; - std::vector nodes2(nbOfTargetNodes); - for(int i=0;iintersectWithAbs(*p2,barycenter); - delete p1; delete p2; - if ( ret > std::numeric_limits::min() ) - { - std::vector sourceCell(3); - sourceCell[0] = &sourceTria[0]; - sourceCell[1] = &sourceTria[SPACEDIM]; - sourceCell[2] = &sourceTria[SPACEDIM*2]; - res.resize(3); - barycentric_coords( sourceCell, barycenter, &res[0]); - res[0] *= ret; - res[1] *= ret; - res[2] *= ret; - } - else - { - ret = 0; - } - return ret; - } - - INTERSECTOR_TEMPLATE - QuadraticPolygon *GEO2D_INTERSECTOR::buildPolygonFrom(const std::vector& coords, NormalizedCellType type) - { - int nbNodes=coords.size()/SPACEDIM; - std::vector nodes(nbNodes); - for(int i=0;i& coords, NormalizedCellType type) - { - if(type==NORM_SEG2) - { - Node *node0=new Node(coords[0],coords[1]); - Node *node1=new Node(coords[SPACEDIM],coords[SPACEDIM+1]); - QuadraticPolygon *ret=new QuadraticPolygon; - ret->pushBack(new EdgeLin(node0,node1)); - node0->decrRef(); node1->decrRef(); - return ret; - } - else if(type==NORM_SEG3) - { - Node *nodeBg=new Node(coords[0],coords[1]); - Node *nodeEnd=new Node(coords[SPACEDIM],coords[SPACEDIM+1]); - Node *nodeMiddle=new Node(coords[2*SPACEDIM],coords[2*SPACEDIM+1]); - QuadraticPolygon *ret=new QuadraticPolygon; - ret->pushBack(new EdgeArcCircle(nodeBg,nodeMiddle,nodeEnd)); - nodeBg->decrRef(); nodeEnd->decrRef(); nodeMiddle->decrRef(); - return ret; - } - else - throw INTERP_KERNEL::Exception("buildPolygonOfOneEdgeFrom : trying to build such non close QuadraticPolygon with 1D type !"); - } - - INTERSECTOR_TEMPLATE - QuadraticPolygon *GEO2D_INTERSECTOR::buildPolygonAFrom(ConnType cell, int nbOfPoints, NormalizedCellType type) - { - const ConnType *startOfCellNodeConn=PlanarIntersector::_connectT+OTT::conn2C(PlanarIntersector::_connIndexT[OTT::ind2C(cell)]); - std::vector nodes(nbOfPoints); - for(int i=0;i::_coordsT+OTT::coo2C(startOfCellNodeConn[i])*SPACEDIM); - if(CellModel::GetCellModel(type).isQuadratic()) - return QuadraticPolygon::BuildLinearPolygon(nodes); - else - return QuadraticPolygon::BuildArcCirclePolygon(nodes); - } - - INTERSECTOR_TEMPLATE - QuadraticPolygon *GEO2D_INTERSECTOR::buildPolygonBFrom(ConnType cell, int nbOfPoints, NormalizedCellType type) - { - const ConnType *startOfCellNodeConn=PlanarIntersector::_connectS+OTT::conn2C(PlanarIntersector::_connIndexS[OTT::ind2C(cell)]); - std::vector nodes(nbOfPoints); - for(int i=0;i::_coordsS+OTT::coo2C(startOfCellNodeConn[i])*SPACEDIM); - const CellModel& cm=CellModel::GetCellModel(type); - if(!cm.isQuadratic()) - return QuadraticPolygon::BuildLinearPolygon(nodes); - else - return QuadraticPolygon::BuildArcCirclePolygon(nodes); - } -} - -#endif diff --git a/src/INTERP_KERNEL/INTERPKERNELDefines.hxx b/src/INTERP_KERNEL/INTERPKERNELDefines.hxx deleted file mode 100644 index 45a3e9afc..000000000 --- a/src/INTERP_KERNEL/INTERPKERNELDefines.hxx +++ /dev/null @@ -1,34 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 -// 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 __INTERPKERNELDEFINES_HXX__ -#define __INTERPKERNELDEFINES_HXX__ - -//export symbols -#ifdef WIN32 -# if defined INTERPKERNEL_EXPORTS || defined interpkernel_EXPORTS -# define INTERPKERNEL_EXPORT __declspec(dllexport) -# else -# define INTERPKERNEL_EXPORT __declspec(dllimport) -# endif -#else -# define INTERPKERNEL_EXPORT -#endif - -#endif diff --git a/src/INTERP_KERNEL/IntegralUniformIntersector.hxx b/src/INTERP_KERNEL/IntegralUniformIntersector.hxx deleted file mode 100644 index 171fa99be..000000000 --- a/src/INTERP_KERNEL/IntegralUniformIntersector.hxx +++ /dev/null @@ -1,72 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 -// 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 __INTEGRALUNIFORMINTERSECTOR_HXX__ -#define __INTEGRALUNIFORMINTERSECTOR_HXX__ - -#include "TargetIntersector.hxx" - -#include - -namespace INTERP_KERNEL -{ - template - class IntegralUniformIntersector : public TargetIntersector - { - public: - typedef typename MyMeshType::MyConnType ConnType; - public: - IntegralUniformIntersector(const MyMeshType& mesh, bool isAbs); - double performNormalization(double val) const { if(_is_abs) return fabs(val); else return val; } - void setFromTo(bool val) { _from_to=val; } - void putValueIn(ConnType i, double val, MyMatrix& res) const; - protected: - const MyMeshType& _mesh; - //! if false means fromIntegralUniform if true means toIntegralUniform - bool _from_to; - bool _is_abs; - }; - - template - class IntegralUniformIntersectorP0 : public IntegralUniformIntersector - { - public: - typedef typename MyMeshType::MyConnType ConnType; - public: - IntegralUniformIntersectorP0(const MyMeshType& mesh, bool isAbs); - int getNumberOfRowsOfResMatrix() const; - int getNumberOfColsOfResMatrix() const; - void intersectCells(ConnType targetCell, const std::vector& srcCells, MyMatrix& res); - }; - - template - class IntegralUniformIntersectorP1 : public IntegralUniformIntersector - { - public: - typedef typename MyMeshType::MyConnType ConnType; - public: - IntegralUniformIntersectorP1(const MyMeshType& mesh, bool isAbs); - int getNumberOfRowsOfResMatrix() const; - int getNumberOfColsOfResMatrix() const; - void intersectCells(ConnType targetCell, const std::vector& srcCells, MyMatrix& res); - }; -} - -#endif diff --git a/src/INTERP_KERNEL/IntegralUniformIntersector.txx b/src/INTERP_KERNEL/IntegralUniformIntersector.txx deleted file mode 100644 index 279776323..000000000 --- a/src/INTERP_KERNEL/IntegralUniformIntersector.txx +++ /dev/null @@ -1,156 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 -// 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 __INTEGRALUNIFORMINTERSECTOR_TXX__ -#define __INTEGRALUNIFORMINTERSECTOR_TXX__ - -#include "IntegralUniformIntersector.hxx" -#include "VolSurfUser.txx" - -namespace INTERP_KERNEL -{ - template - IntegralUniformIntersector::IntegralUniformIntersector(const MyMeshType& mesh, bool isAbs):_mesh(mesh),_from_to(false),_is_abs(isAbs) - { - } - - template - void IntegralUniformIntersector::putValueIn(ConnType iInCMode, double val1, MyMatrix& res) const - { - static const NumberingPolicy numPol=MyMeshType::My_numPol; - double val=performNormalization(val1); - if(_from_to) - { - typename MyMatrix::value_type& resRow=res[0]; - typename MyMatrix::value_type::const_iterator iterRes=resRow.find(OTT::indFC(iInCMode)); - if(iterRes==resRow.end()) - resRow.insert(std::make_pair(OTT::indFC(iInCMode),val)); - else - { - double val2=(*iterRes).second+val; - resRow.erase(OTT::indFC(iInCMode)); - resRow.insert(std::make_pair(OTT::indFC(iInCMode),val2)); - } - } - else - { - typename MyMatrix::value_type& resRow=res[iInCMode]; - typename MyMatrix::value_type::const_iterator iterRes=resRow.find(OTT::indFC(0)); - if(iterRes==resRow.end()) - resRow.insert(std::make_pair(OTT::indFC(0),val)); - else - { - double val2=(*iterRes).second+val; - resRow.erase(OTT::indFC(0)); - resRow.insert(std::make_pair(OTT::indFC(0),val2)); - } - } - } - - template - IntegralUniformIntersectorP0::IntegralUniformIntersectorP0(const MyMeshType& mesh, bool isAbs):IntegralUniformIntersector(mesh,isAbs) - { - } - - template - int IntegralUniformIntersectorP0::getNumberOfRowsOfResMatrix() const - { - if(IntegralUniformIntersector::_from_to) - return 1; - else - return IntegralUniformIntersector::_mesh.getNumberOfElements(); - } - - template - int IntegralUniformIntersectorP0::getNumberOfColsOfResMatrix() const - { - if(IntegralUniformIntersector::_from_to) - return IntegralUniformIntersector::_mesh.getNumberOfElements(); - else - return 1; - } - - template - void IntegralUniformIntersectorP0::intersectCells(ConnType targetCell, const std::vector& srcCells, MyMatrix& res) - { - static const NumberingPolicy numPol=MyMeshType::My_numPol; - res.resize(getNumberOfRowsOfResMatrix()); - unsigned long nbelem=IntegralUniformIntersector::_mesh.getNumberOfElements(); - const ConnType *connIndx=IntegralUniformIntersector::_mesh.getConnectivityIndexPtr(); - const ConnType *conn=IntegralUniformIntersector::_mesh.getConnectivityPtr(); - const double *coords=IntegralUniformIntersector::_mesh.getCoordinatesPtr(); - for(unsigned long i=0;i::_mesh.getTypeOfElement(OTT::indFC(i)); - double val=computeVolSurfOfCell(t,conn+OTT::ind2C(connIndx[i]),connIndx[i+1]-connIndx[i],coords); - IntegralUniformIntersector::putValueIn(i,val,res); - } - } - - template - IntegralUniformIntersectorP1::IntegralUniformIntersectorP1(const MyMeshType& mesh, bool isAbs):IntegralUniformIntersector(mesh,isAbs) - { - } - - template - int IntegralUniformIntersectorP1::getNumberOfRowsOfResMatrix() const - { - if(IntegralUniformIntersector::_from_to) - return 1; - else - return IntegralUniformIntersector::_mesh.getNumberOfNodes(); - } - - template - int IntegralUniformIntersectorP1::getNumberOfColsOfResMatrix() const - { - if(IntegralUniformIntersector::_from_to) - return IntegralUniformIntersector::_mesh.getNumberOfNodes(); - else - return 1; - } - - template - void IntegralUniformIntersectorP1::intersectCells(ConnType targetCell, const std::vector& srcCells, MyMatrix& res) - { - static const NumberingPolicy numPol=MyMeshType::My_numPol; - res.resize(getNumberOfRowsOfResMatrix()); - unsigned long nbelem=IntegralUniformIntersector::_mesh.getNumberOfElements(); - const ConnType *connIndx=IntegralUniformIntersector::_mesh.getConnectivityIndexPtr(); - const ConnType *conn=IntegralUniformIntersector::_mesh.getConnectivityPtr(); - const double *coords=IntegralUniformIntersector::_mesh.getCoordinatesPtr(); - for(unsigned long i=0;i::_mesh.getTypeOfElement(OTT::indFC(i)); - int lgth=connIndx[i+1]-connIndx[i]; - const ConnType *locConn=conn+OTT::ind2C(connIndx[i]); - double val=computeVolSurfOfCell(t,locConn,lgth,coords); - if(t==NORM_TRI3) - val/=3.; - else if(t==NORM_TETRA4) - val/=4.; - else - throw INTERP_KERNEL::Exception("Invalid cell type detected : must be TRI3 or TETRA4 ! "); - for(int j=0;j::putValueIn(OTT::coo2C(locConn[j]),val,res); - } - } -} - -#endif diff --git a/src/INTERP_KERNEL/InterpKernelCellSimplify.cxx b/src/INTERP_KERNEL/InterpKernelCellSimplify.cxx deleted file mode 100644 index dd985b501..000000000 --- a/src/INTERP_KERNEL/InterpKernelCellSimplify.cxx +++ /dev/null @@ -1,511 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 -// 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 "InterpKernelCellSimplify.hxx" -#include "CellModel.hxx" - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -using namespace INTERP_KERNEL; - -/*! - * This method takes as input a cell with type 'type' and whose connectivity is defined by (conn,lgth) - * It retrieves the same cell with a potentially different type (in return) whose connectivity is defined by (retConn,retLgth) - * \b WARNING for optimization reason the arrays 'retConn' and 'conn' can overlapped ! - */ -INTERP_KERNEL::NormalizedCellType CellSimplify::simplifyDegeneratedCell(INTERP_KERNEL::NormalizedCellType type, const int *conn, int lgth, int *retConn, int& retLgth) -{ - const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(type); - std::set c(conn,conn+lgth); - c.erase(-1); - bool isObviousNonDegeneratedCell=((int)c.size()==lgth); - if(cm.isQuadratic() || isObviousNonDegeneratedCell) - {//quadratic do nothing for the moment. - retLgth=lgth; - int *tmp=new int[lgth];//no direct std::copy ! overlapping of conn and retConn ! - std::copy(conn,conn+lgth,tmp); - std::copy(tmp,tmp+lgth,retConn); - delete [] tmp; - return type; - } - if(cm.getDimension()==2) - { - int *tmp=new int[lgth]; - tmp[0]=conn[0]; - int newPos=1; - for(int i=1;i faces; - for(unsigned j=0;j nodes(conn,conn+lgth); - nodes.erase(-1); - int nbOfNodes=(int)nodes.size(); - int magicNumber=100*nbOfNodes+nbOfFaces; - switch(magicNumber) - { - case 806: - return tryToUnPolyHex8(conn,nbOfFaces,lgth,retConn,retLgth); - case 1208: - return tryToUnPolyHexp12(conn,nbOfFaces,lgth,retConn,retLgth); - case 605: - return tryToUnPolyPenta6(conn,nbOfFaces,lgth,retConn,retLgth); - case 505: - return tryToUnPolyPyra5(conn,nbOfFaces,lgth,retConn,retLgth); - case 404: - return tryToUnPolyTetra4(conn,nbOfFaces,lgth,retConn,retLgth); - default: - retLgth=lgth; - std::copy(conn,conn+lgth,retConn); - return INTERP_KERNEL::NORM_POLYHED; - } -} - -bool CellSimplify::orientOppositeFace(const int *baseFace, int *retConn, const int *sideFace, int lgthBaseFace) -{ - std::vector tmp2; - std::set bases(baseFace,baseFace+lgthBaseFace); - std::set sides(sideFace,sideFace+4); - std::set_intersection(bases.begin(),bases.end(),sides.begin(),sides.end(),std::back_insert_iterator< std::vector >(tmp2)); - if(tmp2.size()!=2) - return false; - std::vector< std::pair > baseEdges(lgthBaseFace); - std::vector< std::pair > oppEdges(lgthBaseFace); - std::vector< std::pair > sideEdges(4); - for(int i=0;i(baseFace[i],baseFace[(i+1)%lgthBaseFace]); - oppEdges[i]=std::pair(retConn[i],retConn[(i+1)%lgthBaseFace]); - } - for(int i=0;i<4;i++) - sideEdges[i]=std::pair(sideFace[i],sideFace[(i+1)%4]); - std::vector< std::pair > tmp; - std::set< std::pair > baseEdgesS(baseEdges.begin(),baseEdges.end()); - std::set< std::pair > sideEdgesS(sideEdges.begin(),sideEdges.end()); - std::set_intersection(baseEdgesS.begin(),baseEdgesS.end(),sideEdgesS.begin(),sideEdgesS.end(),std::back_insert_iterator< std::vector< std::pair > >(tmp)); - if(tmp.empty()) - { - //reverse sideFace - for(int i=0;i<4;i++) - { - std::pair p=sideEdges[i]; - std::pair r(p.second,p.first); - sideEdges[i]=r; - } - //end reverse sideFace - std::set< std::pair > baseEdgesS2(baseEdges.begin(),baseEdges.end()); - std::set< std::pair > sideEdgesS2(sideEdges.begin(),sideEdges.end()); - std::set_intersection(baseEdgesS2.begin(),baseEdgesS2.end(),sideEdgesS2.begin(),sideEdgesS2.end(),std::back_insert_iterator< std::vector< std::pair > >(tmp)); - if(tmp.empty()) - return false; - } - if(tmp.size()!=1) - return false; - bool found=false; - std::pair pInOpp; - for(int i=0;i<4 && !found;i++) - {//finding the pair(edge) in sideFace that do not include any node of tmp[0] edge - found=(tmp[0].first!=sideEdges[i].first && tmp[0].first!=sideEdges[i].second && - tmp[0].second!=sideEdges[i].first && tmp[0].second!=sideEdges[i].second); - if(found) - {//found ! reverse it - pInOpp.first=sideEdges[i].second; - pInOpp.second=sideEdges[i].first; - } - } - if(!found) - return false; - int pos=(int)std::distance(baseEdges.begin(),std::find(baseEdges.begin(),baseEdges.end(),tmp[0])); - std::vector< std::pair >::iterator it=std::find(oppEdges.begin(),oppEdges.end(),pInOpp); - if(it==oppEdges.end())//the opposite edge of side face is not found opposite face ... maybe problem of orientation of polyhedron - return false; - int pos2=(int)std::distance(oppEdges.begin(),it); - int offset=pos-pos2; - if(offset<0) - offset+=lgthBaseFace; - //this is the end copy the result - int *tmp3=new int[lgthBaseFace]; - for(int i=0;i(),(int)INTERP_KERNEL::NORM_QUAD4))==conn+lgth+nbOfFaces) - {//6 faces are QUAD4. - int oppositeFace=-1; - std::set conn1(conn,conn+4); - for(int i=1;i<6 && oppositeFace<0;i++) - { - std::vector tmp; - std::set conn2(conn+5*i,conn+5*i+4); - std::set_intersection(conn1.begin(),conn1.end(),conn2.begin(),conn2.end(),std::back_insert_iterator< std::vector >(tmp)); - if(tmp.empty()) - oppositeFace=i; - } - if(oppositeFace>=1) - {//oppositeFace of face#0 found. - int tmp2[4]; - if(tryToArrangeOppositeFace(conn,lgth,4,conn,conn+5*oppositeFace,6,tmp2)) - { - std::copy(conn,conn+4,retConn); - std::copy(tmp2,tmp2+4,retConn+4); - retLgth=8; - return INTERP_KERNEL::NORM_HEXA8; - } - } - } - retLgth=lgth; - std::copy(conn,conn+lgth,retConn); - return INTERP_KERNEL::NORM_POLYHED; -} - -INTERP_KERNEL::NormalizedCellType CellSimplify::tryToUnPolyHexp12(const int *conn, int nbOfFaces, int lgth, int *retConn, int& retLgth) -{ - std::size_t nbOfHexagon=std::count(conn+lgth,conn+lgth+nbOfFaces,(int)INTERP_KERNEL::NORM_POLYGON); - std::size_t nbOfQuad=std::count(conn+lgth,conn+lgth+nbOfFaces,(int)INTERP_KERNEL::NORM_QUAD4); - if(nbOfQuad==6 && nbOfHexagon==2) - { - const int *hexag0=std::find(conn+lgth,conn+lgth+nbOfFaces,(int)INTERP_KERNEL::NORM_POLYGON); - std::size_t hexg0Id=std::distance(conn+lgth,hexag0); - const int *hexag1=std::find(hexag0+1,conn+lgth+nbOfFaces,(int)INTERP_KERNEL::NORM_POLYGON); - std::size_t hexg1Id=std::distance(conn+lgth,hexag1); - const int *connHexag0=conn+5*hexg0Id; - std::size_t lgthH0=std::distance(connHexag0,std::find(connHexag0,conn+lgth,-1)); - if(lgthH0==6) - { - const int *connHexag1=conn+5*hexg0Id+7+(hexg1Id-hexg0Id-1)*5; - std::size_t lgthH1=std::distance(connHexag1,std::find(connHexag1,conn+lgth,-1)); - if(lgthH1==6) - { - std::vector tmp; - std::set conn1(connHexag0,connHexag0+6); - std::set conn2(connHexag1,connHexag1+6); - std::set_intersection(conn1.begin(),conn1.end(),conn2.begin(),conn2.end(),std::back_insert_iterator< std::vector >(tmp)); - if(tmp.empty()) - { - int tmp2[6]; - if(tryToArrangeOppositeFace(conn,lgth,6,connHexag0,connHexag1,8,tmp2)) - { - std::copy(connHexag0,connHexag0+6,retConn); - std::copy(tmp2,tmp2+6,retConn+6); - retLgth=12; - return INTERP_KERNEL::NORM_HEXGP12; - } - } - } - } - } - retLgth=lgth; - std::copy(conn,conn+lgth,retConn); - return INTERP_KERNEL::NORM_POLYHED; -} - -/*! - * Cell with 'conn' connectivity has been detected as a good candidate. Full check of this. If yes NORM_PENTA6 is returned. - * If fails a POLYHED is returned. - */ -INTERP_KERNEL::NormalizedCellType CellSimplify::tryToUnPolyPenta6(const int *conn, int nbOfFaces, int lgth, int *retConn, int& retLgth) -{ - std::size_t nbOfTriFace=std::count(conn+lgth,conn+lgth+nbOfFaces,(int)INTERP_KERNEL::NORM_TRI3); - std::size_t nbOfQuadFace=std::count(conn+lgth,conn+lgth+nbOfFaces,(int)INTERP_KERNEL::NORM_QUAD4); - if(nbOfTriFace==2 && nbOfQuadFace==3) - { - std::size_t tri3_0=std::distance(conn+lgth,std::find(conn+lgth,conn+lgth+nbOfFaces,(int)INTERP_KERNEL::NORM_TRI3)); - std::size_t tri3_1=std::distance(conn+lgth,std::find(conn+lgth+tri3_0+1,conn+lgth+nbOfFaces,(int)INTERP_KERNEL::NORM_TRI3)); - const int *tri_0=0,*tri_1=0; - const int *w=conn; - for(std::size_t i=0;i<5;i++) - { - if(i==tri3_0) - tri_0=w; - if(i==tri3_1) - tri_1=w; - w=std::find(w,conn+lgth,-1); - w++; - } - std::vector tmp; - std::set conn1(tri_0,tri_0+3); - std::set conn2(tri_1,tri_1+3); - std::set_intersection(conn1.begin(),conn1.end(),conn2.begin(),conn2.end(),std::back_insert_iterator< std::vector >(tmp)); - if(tmp.empty()) - { - int tmp2[3]; - if(tryToArrangeOppositeFace(conn,lgth,3,tri_0,tri_1,5,tmp2)) - { - std::copy(tri_0,tri_0+3,retConn); - std::copy(tmp2,tmp2+3,retConn+3); - retLgth=6; - return INTERP_KERNEL::NORM_PENTA6; - } - } - } - retLgth=lgth; - std::copy(conn,conn+lgth,retConn); - return INTERP_KERNEL::NORM_POLYHED; -} - -/*! - * Cell with 'conn' connectivity has been detected as a good candidate. Full check of this. If yes NORM_PYRA5 is returned. - * If fails a POLYHED is returned. - */ -INTERP_KERNEL::NormalizedCellType CellSimplify::tryToUnPolyPyra5(const int *conn, int nbOfFaces, int lgth, int *retConn, int& retLgth) -{ - std::size_t nbOfTriFace=std::count(conn+lgth,conn+lgth+nbOfFaces,(int)INTERP_KERNEL::NORM_TRI3); - std::size_t nbOfQuadFace=std::count(conn+lgth,conn+lgth+nbOfFaces,(int)INTERP_KERNEL::NORM_QUAD4); - if(nbOfTriFace==4 && nbOfQuadFace==1) - { - std::size_t quad4_pos=std::distance(conn+lgth,std::find(conn+lgth,conn+lgth+nbOfFaces,(int)INTERP_KERNEL::NORM_QUAD4)); - const int *quad4=0; - const int *w=conn; - for(std::size_t i=0;i<5 && quad4==0;i++) - { - if(i==quad4_pos) - quad4=w; - w=std::find(w,conn+lgth,-1); - w++; - } - std::set quad4S(quad4,quad4+4); - w=conn; - bool ok=true; - int point=-1; - for(std::size_t i=0;i<5 && ok;i++) - { - if(i!=quad4_pos) - { - std::vector tmp; - std::set conn2(w,w+3); - std::set_intersection(conn2.begin(),conn2.end(),quad4S.begin(),quad4S.end(),std::back_insert_iterator< std::vector >(tmp)); - ok=tmp.size()==2; - tmp.clear(); - std::set_difference(conn2.begin(),conn2.end(),quad4S.begin(),quad4S.end(),std::back_insert_iterator< std::vector >(tmp)); - ok=ok && tmp.size()==1; - if(ok) - { - if(point>=0) - ok=point==tmp[0]; - else - point=tmp[0]; - } - } - w=std::find(w,conn+lgth,-1); - w++; - } - if(ok && point>=0) - { - std::copy(quad4,quad4+4,retConn); - retConn[4]=point; - retLgth=5; - return INTERP_KERNEL::NORM_PYRA5; - } - } - retLgth=lgth; - std::copy(conn,conn+lgth,retConn); - return INTERP_KERNEL::NORM_POLYHED; -} - -/*! - * Cell with 'conn' connectivity has been detected as a good candidate. Full check of this. If yes NORM_TETRA4 is returned. - * If fails a POLYHED is returned. - */ -INTERP_KERNEL::NormalizedCellType CellSimplify::tryToUnPolyTetra4(const int *conn, int nbOfFaces, int lgth, int *retConn, int& retLgth) -{ - if(std::find_if(conn+lgth,conn+lgth+nbOfFaces,std::bind2nd(std::not_equal_to(),(int)INTERP_KERNEL::NORM_TRI3))==conn+lgth+nbOfFaces) - { - std::set tribase(conn,conn+3); - int point=-1; - bool ok=true; - for(int i=1;i<4 && ok;i++) - { - std::vector tmp; - std::set conn2(conn+i*4,conn+4*i+3); - std::set_intersection(conn2.begin(),conn2.end(),tribase.begin(),tribase.end(),std::back_insert_iterator< std::vector >(tmp)); - ok=tmp.size()==2; - tmp.clear(); - std::set_difference(conn2.begin(),conn2.end(),tribase.begin(),tribase.end(),std::back_insert_iterator< std::vector >(tmp)); - ok=ok && tmp.size()==1; - if(ok) - { - if(point>=0) - ok=point==tmp[0]; - else - point=tmp[0]; - } - } - if(ok && point>=0) - { - std::copy(conn,conn+3,retConn); - retConn[3]=point; - retLgth=4; - return INTERP_KERNEL::NORM_TETRA4; - } - } - retLgth=lgth; - std::copy(conn,conn+lgth,retConn); - return INTERP_KERNEL::NORM_POLYHED; -} diff --git a/src/INTERP_KERNEL/InterpKernelCellSimplify.hxx b/src/INTERP_KERNEL/InterpKernelCellSimplify.hxx deleted file mode 100644 index 94d3163c1..000000000 --- a/src/INTERP_KERNEL/InterpKernelCellSimplify.hxx +++ /dev/null @@ -1,49 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 -// 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 __INTERPKERNELCELLSIMPLIFY_HXX__ -#define __INTERPKERNELCELLSIMPLIFY_HXX__ - -#include "INTERPKERNELDefines.hxx" -#include "NormalizedUnstructuredMesh.hxx" -#include "InterpKernelException.hxx" - -namespace INTERP_KERNEL -{ - class INTERPKERNEL_EXPORT CellSimplify - { - public: - static INTERP_KERNEL::NormalizedCellType simplifyDegeneratedCell(INTERP_KERNEL::NormalizedCellType type, const int *conn, int lgth, int *retConn, int& retLgth); - static int *getFullPolyh3DCell(INTERP_KERNEL::NormalizedCellType type, const int *conn, int lgth, - int& retNbOfFaces, int& retLgth); - static INTERP_KERNEL::NormalizedCellType tryToUnPoly2D(bool isQuad, const int *conn, int lgth, int *retConn, int& retLgth); - static INTERP_KERNEL::NormalizedCellType tryToUnPoly3D(const int *conn, int nbOfFaces, int lgth, int *retConn, int& retLgth); - static INTERP_KERNEL::NormalizedCellType tryToUnPolyHex8(const int *conn, int nbOfFaces, int lgth, int *retConn, int& retLgth); - static INTERP_KERNEL::NormalizedCellType tryToUnPolyHexp12(const int *conn, int nbOfFaces, int lgth, int *retConn, int& retLgth); - static INTERP_KERNEL::NormalizedCellType tryToUnPolyPenta6(const int *conn, int nbOfFaces, int lgth, int *retConn, int& retLgth); - static INTERP_KERNEL::NormalizedCellType tryToUnPolyPyra5(const int *conn, int nbOfFaces, int lgth, int *retConn, int& retLgth); - static INTERP_KERNEL::NormalizedCellType tryToUnPolyTetra4(const int *conn, int nbOfFaces, int lgth, int *retConn, int& retLgth); - static bool tryToArrangeOppositeFace(const int *conn, int lgth, int lgthBaseFace, const int *baseFace, const int *oppFaceId, int nbOfFaces, int *retConnOfOppFace); - static bool isWellOriented(const int *baseFace, int *retConn, const int *sideFace, int lgthBaseFace); - static bool orientOppositeFace(const int *baseFace, int *retConn, const int *sideFace, int lgthBaseFace); - }; -} - -#endif diff --git a/src/INTERP_KERNEL/InterpKernelMatrix.hxx b/src/INTERP_KERNEL/InterpKernelMatrix.hxx deleted file mode 100755 index 6a65f8b81..000000000 --- a/src/INTERP_KERNEL/InterpKernelMatrix.hxx +++ /dev/null @@ -1,439 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 -// 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 __INTERPKERNELMATRIX_HXX_ -#define __INTERPKERNELMATRIX_HXX__ - -#include "InterpolationUtils.hxx" - -#include -#include -#include -#include -#include - -namespace INTERP_KERNEL -{ - template - class Matrix; - - template - std::ostream& operator<<(std::ostream& in, const Matrix& m); - template - std::istream& operator>>(std::istream& in, Matrix& m); - - template - class Matrix - { - - class KeyComparator - { - public: - KeyComparator(int val):_val(val) { } - bool operator()(const typename std::pair& val) { return val.first==_val; } - protected: - int _val; - }; - - class Row : public std::vector< std::pair > - { - public: - Row():std::vector< std::pair >(){}; - Row (const Row& row) - { - this->resize(row.size()); - for (int i=0; isize(); i++) - (*this)[i]=row[i]; - } - Row& operator= (const Row& row) - { - this->resize(row.size()); - for (int i=0; isize(); i++) - (*this)[i]=row[i]; - return *this; - } - typename std::vector< std::pair >::const_iterator find(int elem) const - { - return std::find_if(std::vector< std::pair >::begin(),std::vector< std::pair >::end(),KeyComparator(elem)); - } - - void erase(int elem) { std::vector< std::pair >::erase(std::find_if(std::vector< std::pair >::begin(),std::vector< std::pair >::end(),KeyComparator(elem))); } - - void insert(const std::pair& myPair) { vector >::push_back(myPair); } - }; - - private: - unsigned int _nb_rows; - T* _coeffs; - unsigned int* _cols; - std::vector _ncols_offset; - std::vector< Row > _auxiliary_matrix; - friend std::ostream& operator<<<>(std::ostream& in, const Matrix& m); - friend std::istream& operator>><>(std::istream& in, Matrix& m); - bool _is_configured; - public: - typedef Row value_type; - public: - Matrix():_coeffs(0), _cols(0), _nb_rows(0), _is_configured(false) - { } - Matrix(int nbrows):_coeffs(0), _cols(0), _is_configured(false) - { _nb_rows=nbrows; } - Matrix(std::vector > & matrix) : - _coeffs(0), _cols(0), _is_configured(false) - { - _nb_rows=matrix.size(); - _auxiliary_matrix.resize(_nb_rows); - for (int i=0; i<_nb_rows; i++) - { - typename std::map::iterator it; - for (it=matrix[i].begin(); it != matrix[i].end(); it++) - _auxiliary_matrix[i].push_back(*it);//MN: pq push_back plutot que simple affectation? - } - } - /*!Copy constructor - */ - Matrix(const Matrix & m) - { - _is_configured=m._is_configured; - _nb_rows=m._nb_rows; - _auxiliary_matrix=m._auxiliary_matrix; - _ncols_offset=m._ncols_offset; - if (_is_configured) - { - int size=_ncols_offset[_nb_rows]; - _coeffs = new double[size]; - _cols = new unsigned int[size]; - memcpy(_coeffs, m._coeffs, size*sizeof(double)); - memcpy(_cols, m._cols, size*sizeof(int)); - } - } - - ~Matrix() - { - delete[] _coeffs; - delete[] _cols; - } - - Matrix& operator=(const Matrix& m) - { - _is_configured=m._is_configured; - _nb_rows=m._nb_rows; - _auxiliary_matrix=m._auxiliary_matrix; - _ncols_offset=m._ncols_offset; - if (_is_configured) - { - int size=_ncols_offset[_nb_rows]; - _coeffs = new double[size]; - _cols = new unsigned int[size]; - memcpy(_coeffs, m._coeffs, size*sizeof(double)); - memcpy(_cols, m._cols, size*sizeof(int)); - } - return this; - } - - /*! declares a method that specifies the number of rows */ - void resize(unsigned int nbrows) - { - _nb_rows=nbrows; - _auxiliary_matrix.resize(nbrows); - } - - /*! sets (i,j) coefficient to \a value */ - void setIJ(int irow, int icol, T value) - { - if (_is_configured) - throw Exception("filling a configured matrix"); - if (_auxiliary_matrix.empty()) - _auxiliary_matrix.resize(_nb_rows); - - for (unsigned int i=0; i< _auxiliary_matrix[OTT::ind2C(irow)].size(); i++) - if (_auxiliary_matrix[OTT::ind2C(irow)][i].first == icol) - { - _auxiliary_matrix[OTT::ind2C(irow)][i].second = value; - return; - } - _auxiliary_matrix[OTT::ind2C(irow)].push_back(std::make_pair(icol, value)); - } - - /*! - Matrix multiplies vector \a input and stores the result in - vector \a output. - The vector pointed by \a input must be dimensioned - to the number of columns while the vector pointed by output must be - dimensioned to the number of rows. - */ - void multiply(const T* const input, T* const output) - { - if (!_is_configured) - configure(); - - for (int i=0; i< _nb_rows; i++) - { - output[i]=0.; - for (unsigned int j=_ncols_offset[i]; j< _ncols_offset[i+1]; j++) - { - int icol = _cols[j]; - output[i]+=input[icol]*_coeffs[j]; - } - } - } - - /*! - Matrix multiplies vector \a input and stores the result in - vector \a output. - input and output are supposed to represent the same field - discretised on two different on meshes. - nb_comp is the number of components of the fields input and output - The vector pointed by \a input must be dimensioned - to the number of columns times nb_comp while the vector pointed by output must be - dimensioned to the number of rows times nb_comp. - */ - void multiply(const T* const input, T* const output, int nb_comp) - { - if (!_is_configured) - configure(); - - for (int i=0; i< _nb_rows; i++) - { - for(int comp = 0; comp < nb_comp; comp++) - output[i*nb_comp+comp]=0.; - for (unsigned int j=_ncols_offset[i]; j< _ncols_offset[i+1]; j++) - { - int icol = _cols[j]; - for(int comp = 0; comp < nb_comp; comp++) - output[i*nb_comp+comp]+=input[icol*nb_comp+comp]*_coeffs[j]; - } - } - } - /*! - Transpose-multiplies vector \a input and stores the result in - vector \a output. - nb_cols is the number of columns of the matrix, (it is not an attribute of the class) - The vector pointed by \a input must be dimensioned - to the number of lines _nb_rows while the vector pointed by output must be - dimensioned to the number of columns nb_cols. - */ - void transposeMultiply(const T* const input, T* const output, int nb_cols) - { - if (!_is_configured) - configure(); - - for (int icol=0; icol< nb_cols; icol++) - output[icol]=0.; - for (int i=0; i< _nb_rows; i++) - { - for (unsigned int j=_ncols_offset[i]; j< _ncols_offset[i+1]; j++) - { - int icol = _cols[j]; - output[icol]+=input[i]*_coeffs[j]; - } - } - } - /*! - Transpose-multiplies vector \a input and stores the result in - vector \a output. - input and output are supposed to represent the same field - discretised on two different on meshes. - nb_comp is the number of components of the fields input and output - nb_cols is the number of columns of the matrix, (it is not an attribute of the class) - The vector pointed by \a input must be dimensioned - to _nb_rows*nb_comp while the vector pointed by output must be - dimensioned to nb_cols*nb_comp. - */ - void transposeMultiply(const T* const input, T* const output, int nb_cols, int nb_comp) - { - if (!_is_configured) - configure(); - - for (int icol=0; icol< nb_cols; icol++) - for(int comp = 0; comp < nb_comp; comp++) - output[icol*nb_comp+comp]=0.; - - for (int i=0; i< _nb_rows; i++) - { - for (unsigned int j=_ncols_offset[i]; j< _ncols_offset[i+1]; j++) - { - int icol = _cols[j]; - for(int comp = 0; comp < nb_comp; comp++) - output[icol*nb_comp+comp]+=input[i*nb_comp+comp]*_coeffs[j]; - } - } - } - /* - Sums the coefficients of each column of the matrix - nb_cols is the number of columns of the matrix, (it is not an attribute of the class) - The vector output must be dimensioned to nb_cols - */ - void colSum(std::vector< T >& output, int nb_cols) - { - if (!_is_configured) - configure(); - for (int icol=0; icol< nb_cols; icol++) - output[icol]=0.; - for (int i=0; i< _nb_rows; i++) - { - for (unsigned int j=_ncols_offset[i]; j< _ncols_offset[i+1]; j++) - { - int icol = _cols[j]; - output[icol]+=_coeffs[j]; - } - } - } - - /* - Sums the coefficients of each row of the matrix - The vector output must be dimensioned to _nb_rows - */ - void rowSum(std::vector< T >& output) - { - if (!_is_configured) - configure(); - for (int i=0; i< _nb_rows; i++) - { - output[i]=0; - for (unsigned int j=_ncols_offset[i]; j< _ncols_offset[i+1]; j++) - output[i]+=_coeffs[j]; - } - } - - /*! This operation freezes the profile of the matrix - and puts it under a CSR form so that it becomes - efficient both in terms of memory occupation and - in terms of multiplication */ - - void configure() - { - _ncols_offset.resize(_nb_rows+1); - _ncols_offset[0]=0; - for (unsigned int i=0; i<_nb_rows; i++) - _ncols_offset[i+1]=_ncols_offset[i]+_auxiliary_matrix[i].size(); - int nbcoeffs= _ncols_offset[_nb_rows]; - _cols=new unsigned int[nbcoeffs]; - _coeffs=new T[nbcoeffs]; - unsigned int* cols_ptr=_cols; - T* coeffs_ptr=_coeffs; - for (unsigned int i=0; i<_nb_rows; i++) - { - for (unsigned int j=0; j<_auxiliary_matrix[i].size(); j++) - { - *cols_ptr++ = OTT::ind2C(_auxiliary_matrix[i][j].first); - *coeffs_ptr++ = _auxiliary_matrix[i][j].second; - } - } - _auxiliary_matrix.clear(); - _is_configured=true; - } - - /*! - * 0 <= irow < n - */ - Row &operator [] (unsigned int irow) - { - return _auxiliary_matrix[irow]; - } - - int getNbRows() - { - return _nb_rows; - } - - }; - - /*! output to an ascii file - only nonzero elements are written - - the first line contains the indexing (0 or 1) - - the second line contains the number of rows. - - for each row, a line contains: - - the number of nonzero coeffs - - and for each coeff : icol, value - - for instance, matrix - | 1.0 0.0 0.5 | - | 0.0 1.0 0.0 | - | 0.2 0.0 1.0 | - will be displayed in 0-indexing as - 0 - 3 - 2 0 1.0 2 0.5 - 1 1 1.0 - 2 0 0.2 2 1.0 - */ - - template - std::ostream& operator<<(std::ostream& out, const Matrix& m) - { - if (m._is_configured) - { - out << OTT::indFC(0) <::indFC(m._cols[j]) <<"\t"<::indFC(0) <<"\n"; - out << m._nb_rows <<"\n"; - for (unsigned int i=0; i - std::istream& operator>>(std::istream& in, Matrix& m) - { - int index_base_test; - in >> index_base_test; - if (index_base_test!=OTT::indFC(0)) - { - std::cerr << "file index is "<> m._nb_rows; - m._auxiliary_matrix.resize(m._nb_rows); - for (unsigned int i=0; i> ncols; - m._auxiliary_matrix[i].resize(ncols); - double value; - unsigned int col; - for (unsigned int j=0; j>col; - in>>value; - m._auxiliary_matrix[i].push_back(std::make_pair(col, value)); - } - } - return in; - } -} - -#endif diff --git a/src/INTERP_KERNEL/InterpKernelMatrixTools.cxx b/src/INTERP_KERNEL/InterpKernelMatrixTools.cxx deleted file mode 100644 index 59cfecaa3..000000000 --- a/src/INTERP_KERNEL/InterpKernelMatrixTools.cxx +++ /dev/null @@ -1,425 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 -// 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 "InterpKernelMatrixTools.hxx" -#include "InterpKernelException.hxx" -#include "InterpKernelAutoPtr.hxx" - -#include -#include - -namespace INTERP_KERNEL -{ - /* - * Computes the dot product of two vectors. - * This routine uses unrolled loops for increments equal to one. - * - * Reference: - * - * Jack Dongarra, Jim Bunch, Cleve Moler, Pete Stewart, - * LINPACK User's Guide, - * SIAM, 1979, - * ISBN13: 978-0-898711-72-1, - * LC: QA214.L56. - * - * Charles Lawson, Richard Hanson, David Kincaid, Fred Krogh, - * Basic Linear Algebra Subprograms for Fortran Usage, - * Algorithm 539, - * ACM Transactions on Mathematical Software, - * Volume 5, Number 3, September 1979, pages 308-323. - * - * \param [in] n the number of entries in the vectors. - * \param [in] dx the first vector. - * \param [in] incx the increment between successive entries in \a dx. - * \param [in] dy the second vector. - * \param [in] incy the increment between successive entries in \a dy. - * \return the sum of the product of the corresponding entries of \a dx and \a dy. - */ - double ddot(int n, const double *dx, int incx, const double *dy, int incy) - { - double dtemp=0.0; - int i,ix,iy,m; - if(n<=0) - return dtemp; - // Code for unequal increments or equal increments not equal to 1. - if(incx!=1 || incy!=1) - { - if (incx>=0) - ix=0; - else - ix=(-n+1)*incx; - - if(incy>=0) - iy=0; - else - iy=(-n+1)*incy; - for(i=0;i=0.0) - return x; - else - return -x; - } - - void dswap(int n, double *x, int incx, double *y, int incy) - { - int i,ix,iy,m; - double temp; - - if(n<=0) { } - else if(incx==1 && incy==1) - { - m=n%3; - for(i=0;i=0;k--) - { - for(int i=k+1;i ipvt=new int[n]; - INTERP_KERNEL::AutoPtr work=new double[n*n]; - std::copy(A,A+n*n,iA); - dgefa(iA,n,n,ipvt); - dgedi(iA,n,n,ipvt,work); - } -} diff --git a/src/INTERP_KERNEL/InterpKernelMatrixTools.hxx b/src/INTERP_KERNEL/InterpKernelMatrixTools.hxx deleted file mode 100644 index 95fb28f23..000000000 --- a/src/INTERP_KERNEL/InterpKernelMatrixTools.hxx +++ /dev/null @@ -1,33 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 -// 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 __INTERPKERNELMATRIXTOOLS_HXX__ -#define __INTERPKERNELMATRIXTOOLS_HXX__ - -#include "INTERPKERNELDefines.hxx" - -namespace INTERP_KERNEL -{ - void INTERPKERNEL_EXPORT matrixProduct(const double *A, int n1, int p1, const double *B, int n2, int p2, double *C); - void INTERPKERNEL_EXPORT inverseMatrix(const double *A, int n, double *iA); - void INTERPKERNEL_EXPORT daxpy(int n, double da, const double *dx, int incx, double *dy, int incy); -} - -#endif diff --git a/src/INTERP_KERNEL/InterpKernelMeshQuality.cxx b/src/INTERP_KERNEL/InterpKernelMeshQuality.cxx deleted file mode 100644 index f09c0ff26..000000000 --- a/src/INTERP_KERNEL/InterpKernelMeshQuality.cxx +++ /dev/null @@ -1,210 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 -// 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 "InterpKernelMeshQuality.hxx" - -#include -#include -#include -#include - -double INTERP_KERNEL::quadSkew(const double *coo) -{ - double pa0[3]={ - coo[3]+coo[6]-coo[0]-coo[9], - coo[4]+coo[7]-coo[1]-coo[10], - coo[5]+coo[8]-coo[2]-coo[11] - }; - double pa1[3]={ - coo[6]+coo[9]-coo[0]-coo[3], - coo[7]+coo[10]-coo[1]-coo[4], - coo[8]+coo[11]-coo[2]-coo[5], - }; - double l0=sqrt(pa0[0]*pa0[0]+pa0[1]*pa0[1]+pa0[2]*pa0[2]); - double l1=sqrt(pa1[0]*pa1[0]+pa1[1]*pa1[1]+pa1[2]*pa1[2]); - if(l0<1.e-15) - return 0.; - if(l1<1.e-15) - return 0.; - pa0[0]/=l0; pa0[1]/=l0; pa0[2]/=l0; - pa1[0]/=l1; pa1[1]/=l1; pa1[2]/=l1; - return pa0[0]*pa1[0]+pa0[1]*pa1[1]+pa0[2]*pa1[2]; -} - -double INTERP_KERNEL::quadEdgeRatio(const double *coo) -{ - double a2=(coo[3]-coo[0])*(coo[3]-coo[0])+(coo[4]-coo[1])*(coo[4]-coo[1])+(coo[5]-coo[2])*(coo[5]-coo[2]); - double b2=(coo[6]-coo[3])*(coo[6]-coo[3])+(coo[7]-coo[4])*(coo[7]-coo[4])+(coo[8]-coo[5])*(coo[8]-coo[5]); - double c2=(coo[9]-coo[6])*(coo[9]-coo[6])+(coo[10]-coo[7])*(coo[10]-coo[7])+(coo[11]-coo[8])*(coo[11]-coo[8]); - double d2=(coo[0]-coo[9])*(coo[0]-coo[9])+(coo[1]-coo[10])*(coo[1]-coo[10])+(coo[2]-coo[11])*(coo[2]-coo[11]); - double mab=a2Mcd?Mab:Mcd; - if(m2>1.e-15) - return sqrt(M2/m2); - else - return std::numeric_limits::max(); -} - -double INTERP_KERNEL::quadAspectRatio(const double *coo) -{ - double a=sqrt((coo[3]-coo[0])*(coo[3]-coo[0])+(coo[4]-coo[1])*(coo[4]-coo[1])+(coo[5]-coo[2])*(coo[5]-coo[2])); - double b=sqrt((coo[6]-coo[3])*(coo[6]-coo[3])+(coo[7]-coo[4])*(coo[7]-coo[4])+(coo[8]-coo[5])*(coo[8]-coo[5])); - double c=sqrt((coo[9]-coo[6])*(coo[9]-coo[6])+(coo[10]-coo[7])*(coo[10]-coo[7])+(coo[11]-coo[8])*(coo[11]-coo[8])); - double d=sqrt((coo[0]-coo[9])*(coo[0]-coo[9])+(coo[1]-coo[10])*(coo[1]-coo[10])+(coo[2]-coo[11])*(coo[2]-coo[11])); - double ma=a>b?a:b; - double mb=c>d?c:d; - double hm=ma>mb?ma:mb; - double ab[3]={(coo[4]-coo[1])*(coo[8]-coo[5])-(coo[7]-coo[4])*(coo[5]-coo[2]), - (coo[5]-coo[2])*(coo[6]-coo[3])-(coo[3]-coo[0])*(coo[8]-coo[5]), - (coo[3]-coo[0])*(coo[7]-coo[4])-(coo[4]-coo[1])*(coo[6]-coo[3])}; - double cd[3]={(coo[10]-coo[7])*(coo[2]-coo[11])-(coo[1]-coo[10])*(coo[11]-coo[8]), - (coo[11]-coo[8])*(coo[0]-coo[9])-(coo[9]-coo[6])*(coo[2]-coo[11]), - (coo[9]-coo[6])*(coo[1]-coo[10])-(coo[10]-coo[7])*(coo[0]-coo[9])}; - double e=sqrt(ab[0]*ab[0]+ab[1]*ab[1]+ab[2]*ab[2])+sqrt(cd[0]*cd[0]+cd[1]*cd[1]+cd[2]*cd[2]); - if(d>1e-15) - return 0.5*(a+b+c+d)*hm/e; - else - return std::numeric_limits::max(); -} - -double INTERP_KERNEL::quadWarp(const double *coo) -{ - double e0[3]={coo[3]-coo[0],coo[4]-coo[1],coo[5]-coo[2]}; - double e1[3]={coo[6]-coo[3],coo[7]-coo[4],coo[8]-coo[5]}; - double e2[3]={coo[9]-coo[6],coo[10]-coo[7],coo[11]-coo[8]}; - double e3[3]={coo[0]-coo[9],coo[1]-coo[10],coo[2]-coo[11]}; - - double n0[3]={e3[1]*e0[2]-e3[2]*e0[1],e3[2]*e0[0]-e3[0]*e0[2],e3[0]*e0[1]-e3[1]*e0[0]}; - double n1[3]={e0[1]*e1[2]-e0[2]*e1[1],e0[2]*e1[0]-e0[0]*e1[2],e0[0]*e1[1]-e0[1]*e1[0]}; - double n2[3]={e1[1]*e2[2]-e1[2]*e2[1],e1[2]*e2[0]-e1[0]*e2[2],e1[0]*e2[1]-e1[1]*e2[0]}; - double n3[3]={e2[1]*e3[2]-e2[2]*e3[1],e2[2]*e3[0]-e2[0]*e3[2],e2[0]*e3[1]-e2[1]*e3[0]}; - - double l0=sqrt(n0[0]*n0[0]+n0[1]*n0[1]+n0[2]*n0[2]); - double l1=sqrt(n1[0]*n1[0]+n1[1]*n1[1]+n1[2]*n1[2]); - double l2=sqrt(n2[0]*n2[0]+n2[1]*n2[1]+n2[2]*n2[2]); - double l3=sqrt(n3[0]*n3[0]+n3[1]*n3[1]+n3[2]*n3[2]); - - if(l0<1.e-15 || l1<1.e-15 || l2<1.e-15 || l3<1e-15) - return std::numeric_limits::min(); - - double warp=std::min(n0[0]/l0*n2[0]/l2+n0[1]/l0*n2[1]/l2+n0[2]/l0*n2[2]/l2,n1[0]/l1*n3[0]/l3+n1[1]/l1*n3[1]/l3+n1[2]/l1*n3[2]/l3); - return warp*warp*warp; -} - -double INTERP_KERNEL::triEdgeRatio(const double *coo) -{ - double a2=(coo[3]-coo[0])*(coo[3]-coo[0])+(coo[4]-coo[1])*(coo[4]-coo[1])+(coo[5]-coo[2])*(coo[5]-coo[2]); - double b2=(coo[6]-coo[3])*(coo[6]-coo[3])+(coo[7]-coo[4])*(coo[7]-coo[4])+(coo[8]-coo[5])*(coo[8]-coo[5]); - double c2=(coo[0]-coo[6])*(coo[0]-coo[6])+(coo[1]-coo[7])*(coo[1]-coo[7])+(coo[2]-coo[8])*(coo[2]-coo[8]); - double mab=a2mab?mab:c2; - double M2=c2>Mab?c2:Mab; - if(m2>1.e-15) - return sqrt(M2/m2); - else - return std::numeric_limits::max(); -} - -double INTERP_KERNEL::triAspectRatio(const double *coo) -{ - double a=sqrt((coo[3]-coo[0])*(coo[3]-coo[0])+(coo[4]-coo[1])*(coo[4]-coo[1])+(coo[5]-coo[2])*(coo[5]-coo[2])); - double b=sqrt((coo[6]-coo[3])*(coo[6]-coo[3])+(coo[7]-coo[4])*(coo[7]-coo[4])+(coo[8]-coo[5])*(coo[8]-coo[5])); - double c=sqrt((coo[0]-coo[6])*(coo[0]-coo[6])+(coo[1]-coo[7])*(coo[1]-coo[7])+(coo[2]-coo[8])*(coo[2]-coo[8])); - - double hm=a>b?a:b; - hm=hm>c?hm:c; - - double ab[3]={(coo[4]-coo[1])*(coo[8]-coo[5])-(coo[7]-coo[4])*(coo[5]-coo[2]), - (coo[5]-coo[2])*(coo[6]-coo[3])-(coo[3]-coo[0])*(coo[8]-coo[5]), - (coo[3]-coo[0])*(coo[7]-coo[4])-(coo[4]-coo[1])*(coo[6]-coo[3])}; - double d=sqrt(ab[0]*ab[0]+ab[1]*ab[1]+ab[2]*ab[2]); - static const double normalizeCoeff=sqrt(3.)/6.; - if(d>1.e-15) - return normalizeCoeff*hm*(a+b+c)/d; - else - return std::numeric_limits::max(); -} - -double INTERP_KERNEL::tetraEdgeRatio(const double *coo) -{ - double a[3]={coo[3]-coo[0],coo[4]-coo[1],coo[5]-coo[2]}; - double b[3]={coo[6]-coo[3],coo[7]-coo[4],coo[8]-coo[5]}; - double c[3]={coo[0]-coo[6],coo[1]-coo[7],coo[2]-coo[8]}; - double d[3]={coo[9]-coo[0],coo[10]-coo[1],coo[11]-coo[2]}; - double e[3]={coo[9]-coo[3],coo[10]-coo[4],coo[11]-coo[5]}; - double f[3]={coo[9]-coo[6],coo[10]-coo[7],coo[11]-coo[8]}; - - double l2[6]= - {a[0]*a[0]+a[1]*a[1]+a[2]*a[2], - b[0]*b[0]+b[1]*b[1]+b[2]*b[2], - c[0]*c[0]+c[1]*c[1]+c[2]*c[2], - d[0]*d[0]+d[1]*d[1]+d[2]*d[2], - e[0]*e[0]+e[1]*e[1]+e[2]*e[2], - f[0]*f[0]+f[1]*f[1]+f[2]*f[2]}; - - double M2=*std::max_element(l2,l2+6); - double m2=*std::min_element(l2,l2+6); - if(m2>1e-15) - return sqrt(M2/m2); - else - return std::numeric_limits::max(); -} - -double INTERP_KERNEL::tetraAspectRatio(const double *coo) -{ - static const double normalizeCoeff=sqrt(6.)/12.; - double ab[3]={coo[3]-coo[0],coo[4]-coo[1],coo[5]-coo[2]}; - double ac[3]={coo[6]-coo[0],coo[7]-coo[1],coo[8]-coo[2]}; - double ad[3]={coo[9]-coo[0],coo[10]-coo[1],coo[11]-coo[2]}; - double detTet=(ab[0]*(ac[1]*ad[2]-ac[2]*ad[1]))+(ab[1]*(ac[2]*ad[0]-ac[0]*ad[2]))+(ab[2]*(ac[0]*ad[1]-ac[1]*ad[0])); - //if(detTet<1.e-15) - // return std::numeric_limits::max(); - double bc[3]={coo[6]-coo[3],coo[7]-coo[4],coo[8]-coo[5]}; - double bd[3]={coo[9]-coo[3],coo[10]-coo[4],coo[11]-coo[5]}; - double cd[3]={coo[9]-coo[6],coo[10]-coo[7],coo[11]-coo[8]}; - - double ab2=ab[0]*ab[0]+ab[1]*ab[1]+ab[2]*ab[2]; - double bc2=bc[0]*bc[0]+bc[1]*bc[1]+bc[2]*bc[2]; - double ac2=ac[0]*ac[0]+ac[1]*ac[1]+ac[2]*ac[2]; - double ad2=ad[0]*ad[0]+ad[1]*ad[1]+ad[2]*ad[2]; - double bd2=bd[0]*bd[0]+bd[1]*bd[1]+bd[2]*bd[2]; - double cd2=cd[0]*cd[0]+cd[1]*cd[1]+cd[2]*cd[2]; - - double A=ab2>bc2?ab2:bc2; - double B=ac2>ad2?ac2:ad2; - double C=bd2>cd2?bd2:cd2; - double D=A>B?A:B; - double hm=D>C?sqrt(D):sqrt(C); - - bd[0]=ab[1]*bc[2]-ab[2]*bc[1]; bd[1]=ab[2]*bc[0]-ab[0]*bc[2]; bd[2]=ab[0]*bc[1]-ab[1]*bc[0]; - A=sqrt(bd[0]*bd[0]+bd[1]*bd[1]+bd[2]*bd[2]); - bd[0]=ab[1]*ad[2]-ab[2]*ad[1]; bd[1]=ab[2]*ad[0]-ab[0]*ad[2]; bd[2]=ab[0]*ad[1]-ab[1]*ad[0]; - B=sqrt(bd[0]*bd[0]+bd[1]*bd[1]+bd[2]*bd[2]); - bd[0]=ac[1]*ad[2]-ac[2]*ad[1]; bd[1]=ac[2]*ad[0]-ac[0]*ad[2]; bd[2]=ac[0]*ad[1]-ac[1]*ad[0]; - C=sqrt(bd[0]*bd[0]+bd[1]*bd[1]+bd[2]*bd[2]); - bd[0]=bc[1]*cd[2]-bc[2]*cd[1]; bd[1]=bc[2]*cd[0]-bc[0]*cd[2]; bd[2]=bc[0]*cd[1]-bc[1]*cd[0]; - D=sqrt(bd[0]*bd[0]+bd[1]*bd[1]+bd[2]*bd[2]); - return normalizeCoeff*hm*(A+B+C+D)/fabs(detTet); -} diff --git a/src/INTERP_KERNEL/InterpKernelMeshQuality.hxx b/src/INTERP_KERNEL/InterpKernelMeshQuality.hxx deleted file mode 100644 index 88afc15d9..000000000 --- a/src/INTERP_KERNEL/InterpKernelMeshQuality.hxx +++ /dev/null @@ -1,38 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 -// 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 __INTERPKERNELMESHQUALITY_HXX_ -#define __INTERPKERNELMESHQUALITY_HXX__ - -#include "INTERPKERNELDefines.hxx" - -namespace INTERP_KERNEL -{ - INTERPKERNEL_EXPORT double quadSkew(const double *coo); - INTERPKERNEL_EXPORT double quadEdgeRatio(const double *coo); - INTERPKERNEL_EXPORT double quadAspectRatio(const double *coo); - INTERPKERNEL_EXPORT double quadWarp(const double *coo); - INTERPKERNEL_EXPORT double triEdgeRatio(const double *coo); - INTERPKERNEL_EXPORT double triAspectRatio(const double *coo); - INTERPKERNEL_EXPORT double tetraEdgeRatio(const double *coo); - INTERPKERNEL_EXPORT double tetraAspectRatio(const double *coo); -} - -#endif diff --git a/src/INTERP_KERNEL/InterpKernelUtilities.hxx b/src/INTERP_KERNEL/InterpKernelUtilities.hxx deleted file mode 100644 index 44ee02ab1..000000000 --- a/src/INTERP_KERNEL/InterpKernelUtilities.hxx +++ /dev/null @@ -1,38 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 -// 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 __INTERPKERNELUTILITIES_HXX__ -#define __INTERPKERNELUTILITIES_HXX__ - -//! DON'T INCLUDE THIS FILE IN .h NOR IN .hxx FILES !!!!!!!!! -#ifdef _DEBUG_ -# define MESSAGE(chain) {HERE ; cerr << chain << endl ;} -#else -# define MESSAGE(chain) -#endif - -#ifdef _DEBUG_ -# define HERE {cout< (message) , __FILE__ , __LINE__ - -#endif diff --git a/src/INTERP_KERNEL/Interpolation.hxx b/src/INTERP_KERNEL/Interpolation.hxx deleted file mode 100644 index 16415593b..000000000 --- a/src/INTERP_KERNEL/Interpolation.hxx +++ /dev/null @@ -1,56 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 -// 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 __INTERPOLATION_HXX__ -#define __INTERPOLATION_HXX__ - -#include "INTERPKERNELDefines.hxx" -#include "InterpolationOptions.hxx" -#include "InterpKernelException.hxx" - -#include - -namespace INTERP_KERNEL -{ - template - class Interpolation : public InterpolationOptions - { - public: - Interpolation() { } - Interpolation(const InterpolationOptions& io) :InterpolationOptions(io){} - //interpolation of two triangular meshes. - template - int interpolateMeshes(const MyMeshType& meshS, const MyMeshType& meshT, MatrixType& result) - { return asLeaf().interpolateMeshes(meshS,meshT,result); } - template - int fromIntegralUniform(const MyMeshType& meshT, MatrixType& result, const std::string& method) { return fromToIntegralUniform(false,meshT,result,method); } - template - int toIntegralUniform(const MyMeshType& meshS, MatrixType& result, const std::string& method) { return fromToIntegralUniform(true,meshS,result,method); } - template - static double CalculateCharacteristicSizeOfMeshes(const MyMeshType& myMeshS, const MyMeshType& myMeshT, const int printLevel); - protected: - template - int fromToIntegralUniform(bool fromTo, const MyMeshType& mesh, MatrixType& result, const std::string& method); - protected: - TrueMainInterpolator& asLeaf() { return static_cast(*this); } - }; -} - -#endif diff --git a/src/INTERP_KERNEL/Interpolation.txx b/src/INTERP_KERNEL/Interpolation.txx deleted file mode 100644 index 65a9fb4d3..000000000 --- a/src/INTERP_KERNEL/Interpolation.txx +++ /dev/null @@ -1,97 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 -// 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 __INTERPOLATION_TXX__ -#define __INTERPOLATION_TXX__ - -#include "Interpolation.hxx" -#include "IntegralUniformIntersector.hxx" -#include "IntegralUniformIntersector.txx" -#include "VectorUtils.hxx" - -namespace INTERP_KERNEL -{ - template - template - int Interpolation::fromToIntegralUniform(bool fromTo, const MyMeshType& mesh, MatrixType& result, const std::string& method) - { - typedef typename MyMeshType::MyConnType ConnType; - int ret=-1; - if(method=="P0") - { - IntegralUniformIntersectorP0 intersector(mesh,InterpolationOptions::getMeasureAbsStatus()); - intersector.setFromTo(fromTo); - std::vector tmp; - intersector.intersectCells(0,tmp,result); - ret=intersector.getNumberOfColsOfResMatrix(); - } - else if(method=="P1") - { - IntegralUniformIntersectorP1 intersector(mesh,InterpolationOptions::getMeasureAbsStatus()); - intersector.setFromTo(fromTo); - std::vector tmp; - intersector.intersectCells(0,tmp,result); - ret=intersector.getNumberOfColsOfResMatrix(); - } - else - throw INTERP_KERNEL::Exception("Invalid method specified in fromIntegralUniform : must be in { \"P0\", \"P1\"}"); - return ret; - } - - template - template - double Interpolation::CalculateCharacteristicSizeOfMeshes(const MyMeshType& myMeshS, const MyMeshType& myMeshT, const int printLevel) - { - static const int SPACEDIM=MyMeshType::MY_SPACEDIM; - - long nbMailleS=myMeshS.getNumberOfElements(); - long nbMailleT=myMeshT.getNumberOfElements(); - - /**************************************************/ - /* Search the characteristic size of the meshes */ - /**************************************************/ - - double BoxS[2*SPACEDIM]; myMeshS.getBoundingBox(BoxS); - double BoxT[2*SPACEDIM]; myMeshT.getBoundingBox(BoxT); - double diagonalS,dimCaracteristicS=std::numeric_limits::max(); - if(nbMailleS!=0) - { - diagonalS=getDistanceBtw2Pts(BoxS+SPACEDIM,BoxS); - dimCaracteristicS=diagonalS/nbMailleS; - } - double diagonalT,dimCaracteristicT=std::numeric_limits::max(); - if(nbMailleT!=0) - { - diagonalT=getDistanceBtw2Pts(BoxT+SPACEDIM,BoxT); - dimCaracteristicT=diagonalT/nbMailleT; - } - if (printLevel>=1) - { - std::cout << " - Characteristic size of the source mesh : " << dimCaracteristicS << std::endl; - std::cout << " - Characteristic size of the target mesh: " << dimCaracteristicT << std::endl; - } - - return std::min(dimCaracteristicS, dimCaracteristicT); - - } - -} - -#endif - diff --git a/src/INTERP_KERNEL/Interpolation1D.hxx b/src/INTERP_KERNEL/Interpolation1D.hxx deleted file mode 100755 index 351cb4296..000000000 --- a/src/INTERP_KERNEL/Interpolation1D.hxx +++ /dev/null @@ -1,36 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 -// 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 __INTERPOLATION1D_HXX__ -#define __INTERPOLATION1D_HXX__ - -#include "InterpolationCurve.hxx" - -namespace INTERP_KERNEL -{ - class Interpolation1D : public InterpolationCurve - { - public: - Interpolation1D() { } - Interpolation1D(const InterpolationOptions& io):InterpolationCurve(io) {} - }; -} - -#endif diff --git a/src/INTERP_KERNEL/Interpolation1D.txx b/src/INTERP_KERNEL/Interpolation1D.txx deleted file mode 100644 index dcc4f77ff..000000000 --- a/src/INTERP_KERNEL/Interpolation1D.txx +++ /dev/null @@ -1,27 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 -// 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 __INTERPOLATION1D_TXX__ -#define __INTERPOLATION1D_TXX__ - -#include "Interpolation1D.hxx" - -#include "InterpolationCurve.txx" - -#endif diff --git a/src/INTERP_KERNEL/Interpolation2D.hxx b/src/INTERP_KERNEL/Interpolation2D.hxx deleted file mode 100755 index 82a8980b3..000000000 --- a/src/INTERP_KERNEL/Interpolation2D.hxx +++ /dev/null @@ -1,41 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 -// 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 __INTERPOLATION2D_HXX__ -#define __INTERPOLATION2D_HXX__ - -#include "InterpolationPlanar.hxx" - -namespace INTERP_KERNEL -{ - class Interpolation2D : public InterpolationPlanar - { - public: - Interpolation2D() { } - Interpolation2D(const InterpolationOptions& io):InterpolationPlanar(io) { } - public: - bool doRotate() const { return false; } - double medianPlane() const { return 0.; } - template - void performAdjustmentOfBB(PlanarIntersector* intersector, std::vector& bbox) const { } - }; -} - -#endif diff --git a/src/INTERP_KERNEL/Interpolation2D.txx b/src/INTERP_KERNEL/Interpolation2D.txx deleted file mode 100644 index fa871e5b9..000000000 --- a/src/INTERP_KERNEL/Interpolation2D.txx +++ /dev/null @@ -1,27 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 -// 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 __INTERPOLATION2D_TXX__ -#define __INTERPOLATION2D_TXX__ - -#include "Interpolation2D.hxx" - -#include "InterpolationPlanar.txx" - -#endif diff --git a/src/INTERP_KERNEL/Interpolation2D1D.hxx b/src/INTERP_KERNEL/Interpolation2D1D.hxx deleted file mode 100644 index 2ef88f89c..000000000 --- a/src/INTERP_KERNEL/Interpolation2D1D.hxx +++ /dev/null @@ -1,63 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 -// 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 __INTERPOLATION2D1D_HXX__ -#define __INTERPOLATION2D1D_HXX__ - -#include "Interpolation.hxx" -#include "Planar2D1DIntersectorP0P0.hxx" -#include "NormalizedUnstructuredMesh.hxx" -#include "InterpolationOptions.hxx" - -namespace INTERP_KERNEL -{ - /*! - * Contrary to its name this class deals with 1D mesh in source and 2D mesh in target. - * The meshdim of 'MyMeshType' in input is ignored that's why 'meshS' and 'meshT' - * have the same type. - * '_duplicate_faces' attribute stores duplicated faces in the following format. - * The key of '_duplicate_faces' represents the 1D cellId that is shared by - * more than one 2D target cell, and the value of '_duplicate_faces' - * the 2D target cells. The size of the value of '_duplicate_faces' is more than or equal to 2. - */ - class Interpolation2D1D : public Interpolation - { - public: - typedef std::map > DuplicateFacesType; - - Interpolation2D1D() { setOrientation(2); } - Interpolation2D1D(const InterpolationOptions& io):Interpolation(io) { } - public: - - // Main function to interpolate triangular and quadratic meshes - template - int interpolateMeshes(const MyMeshType& meshS, const MyMeshType& meshT, MatrixType& result, const std::string& method); - DuplicateFacesType retrieveDuplicateFaces() const - { - return _duplicate_faces; - } - private: - DuplicateFacesType _duplicate_faces; - private: - double _dim_caracteristic; - }; -} - -#endif diff --git a/src/INTERP_KERNEL/Interpolation2D1D.txx b/src/INTERP_KERNEL/Interpolation2D1D.txx deleted file mode 100644 index 482a88250..000000000 --- a/src/INTERP_KERNEL/Interpolation2D1D.txx +++ /dev/null @@ -1,157 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 -// 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 __INTERPOLATION2D1D_TXX__ -#define __INTERPOLATION2D1D_TXX__ - -#include "Interpolation2D1D.hxx" - -namespace INTERP_KERNEL -{ - - /** \brief Main function to interpolate triangular or quadrangular meshes. - \details The algorithm proceeds in two steps: first a filtering process reduces the number of pairs of elements for which the - * calculation must be carried out by eliminating pairs that do not intersect based on their bounding boxes. Then, the - * volume of intersection is calculated by an object of type IntersectorPlanar for the remaining pairs, and entered into the - * intersection matrix. - * - * The matrix is partially sparse : it is a vector of maps of integer - double pairs. - * The length of the vector is equal to the number of target elements - for each target element there is a map, regardless - * of whether the element intersects any source elements or not. But in the maps there are only entries for those source elements - * which have a non-zero intersection volume with the target element. The vector has indices running from - * 0 to (#target elements - 1), meaning that the map for target element i is stored at index i - 1. In the maps, however, - * the indexing is more natural : the intersection volume of the target element i with source element j is found at matrix[i-1][j]. - * - - * @param myMeshS Planar source mesh - * @Param myMeshT Planar target mesh - * @return vector containing for each element i of the source mesh, a map giving for each element j - * of the target mesh which i intersects, the area of the intersection - * - */ - template - int Interpolation2D1D::interpolateMeshes(const MyMeshType& myMeshS, const MyMeshType& myMeshT, MatrixType& result, const std::string& method) - { - static const int SPACEDIM=MyMeshType::MY_SPACEDIM; - typedef typename MyMeshType::MyConnType ConnType; - static const NumberingPolicy numPol=MyMeshType::My_numPol; - - long global_start =clock(); - int counter=0; - /***********************************************************/ - /* Check both meshes are made of triangles and quadrangles */ - /***********************************************************/ - - long nbMailleS=myMeshS.getNumberOfElements(); - - /**************************************************/ - /* Search the characteristic size of the meshes */ - /**************************************************/ - - int printLevel = InterpolationOptions::getPrintLevel(); - _dim_caracteristic = CalculateCharacteristicSizeOfMeshes(myMeshS, myMeshT, printLevel); - if (printLevel>=1) - { - std::cout << "Interpolation2D1D::computation of the intersections" << std::endl; - } - - PlanarIntersector* intersector=0; - std::string meth = InterpolationOptions::filterInterpolationMethod(method); - if(meth=="P0P0") - { - switch (InterpolationOptions::getIntersectionType()) - { - case Geometric2D: - intersector=new Geometric2DIntersector(myMeshT, myMeshS, _dim_caracteristic, - InterpolationOptions::getMaxDistance3DSurfIntersect(), - InterpolationOptions::getMinDotBtwPlane3DSurfIntersect(), - InterpolationOptions::getMedianPlane(), - InterpolationOptions::getPrecision(), - InterpolationOptions::getOrientation()); - break; - default: - throw INTERP_KERNEL::Exception("Invalid intersection type ! Must be : Geometric2D"); - } - } - else - throw INTERP_KERNEL::Exception("Invalid method specified or intersection type ! Must be : \"P0P0\""); - - /****************************************************************/ - /* Create a search tree based on the bounding boxes */ - /* Instanciate the intersector and initialise the result vector */ - /****************************************************************/ - - long start_filtering=clock(); - - std::vector bbox; - intersector->createBoundingBoxes(myMeshS,bbox); // create the bounding boxes - const double *bboxPtr=0; - if(nbMailleS>0) - bboxPtr=&bbox[0]; - BBTree my_tree(bboxPtr, 0, 0,nbMailleS, -getPrecision());//creating the search structure - - long end_filtering=clock(); - - result.resize(intersector->getNumberOfRowsOfResMatrix());//on initialise. - - /****************************************************/ - /* Loop on the target cells - core of the algorithm */ - /****************************************************/ - long start_intersection=clock(); - long nbelem_type=myMeshT.getNumberOfElements(); - const ConnType *connIndxT=myMeshT.getConnectivityIndexPtr(); - for(int iT=0; iT intersecting_elems; - double bb[2*SPACEDIM]; - intersector->getElemBB(bb,myMeshT,OTT::indFC(iT),nb_nodesT); - my_tree.getIntersectingElems(bb, intersecting_elems); - intersector->intersectCells(iT,intersecting_elems,result); - counter+=intersecting_elems.size(); - intersecting_elems.clear(); - } - int ret=intersector->getNumberOfColsOfResMatrix(); - - const DuplicateFacesType& intersectFaces = *intersector->getIntersectFaces(); - DuplicateFacesType::const_iterator iter; - for (iter = intersectFaces.begin(); iter != intersectFaces.end(); ++iter) - { - if (iter->second.size() > 1) - { - _duplicate_faces.insert(std::make_pair(iter->first, iter->second)); - } - } - - delete intersector; - - if (InterpolationOptions::getPrintLevel() >=1) - { - long end_intersection=clock(); - std::cout << "Filtering time= " << end_filtering-start_filtering << std::endl; - std::cout << "Intersection time= " << end_intersection-start_intersection << std::endl; - long global_end =clock(); - std::cout << "Number of computed intersections = " << counter << std::endl; - std::cout << "Global time= " << global_end - global_start << std::endl; - } - return ret; - } - -} -#endif diff --git a/src/INTERP_KERNEL/Interpolation2DCurve.cxx b/src/INTERP_KERNEL/Interpolation2DCurve.cxx deleted file mode 100644 index 0db047975..000000000 --- a/src/INTERP_KERNEL/Interpolation2DCurve.cxx +++ /dev/null @@ -1,60 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 -// 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 "Interpolation2DCurve.hxx" -#include "InterpolationCurve.txx" - -namespace INTERP_KERNEL -{ - Interpolation2DCurve::Interpolation2DCurve() - { - // to have non-zero default thickness of target element - InterpolationOptions::setBoundingBoxAdjustmentAbs( InterpolationOptions::getPrecision() ); - } - - Interpolation2DCurve::Interpolation2DCurve - (const InterpolationOptions& io):InterpolationCurve(io) - { - // to have non-zero default thickness of target element - InterpolationOptions::setBoundingBoxAdjustmentAbs( InterpolationOptions::getPrecision() ); - } - - /** - * \brief Function used to set the options for the intersection calculation - * \details The following options can be modified: - * -# Precision: Level of precision of the computations. - * - Values: positive real number. - * - Default: 1.0E-12. - * -# Tolerance: Thickness of target element. - * - Values: positive real number. - * - Default: 1.0E-12. - * -# Median line: Position of the median line where both segments will be projected. - * - Values: real number between 0.0 and 1.0. - * - Default: 0.5 - */ - void Interpolation2DCurve::setOptions (double precision, - double tolerance, - double medianLine) - { - InterpolationOptions::setPrecision(precision); - InterpolationOptions::setBoundingBoxAdjustmentAbs(tolerance); - InterpolationOptions::setMedianPlane(medianLine); - } -} diff --git a/src/INTERP_KERNEL/Interpolation2DCurve.hxx b/src/INTERP_KERNEL/Interpolation2DCurve.hxx deleted file mode 100644 index d0348bebe..000000000 --- a/src/INTERP_KERNEL/Interpolation2DCurve.hxx +++ /dev/null @@ -1,39 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 -// 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 __INTERPOLATION2DCURVE_HXX__ -#define __INTERPOLATION2DCURVE_HXX__ - -#include "InterpolationCurve.hxx" -#include "InterpolationOptions.hxx" - -namespace INTERP_KERNEL -{ - class INTERPKERNEL_EXPORT Interpolation2DCurve : public InterpolationCurve - { - public: - Interpolation2DCurve(); - Interpolation2DCurve(const InterpolationOptions& io); - // geometric precision, intersection tolerance, coice of the median line, - void setOptions(double precision, double tolerance, double medianLine); - }; -} - -#endif diff --git a/src/INTERP_KERNEL/Interpolation3D.cxx b/src/INTERP_KERNEL/Interpolation3D.cxx deleted file mode 100644 index 16bd09cc0..000000000 --- a/src/INTERP_KERNEL/Interpolation3D.cxx +++ /dev/null @@ -1,41 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 -// 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 "Interpolation3D.hxx" -#include "Interpolation3D.txx" - -namespace INTERP_KERNEL -{ - /** - * \class Interpolation3D - * \brief Class used to calculate the volumes of intersection between the elements of two 3D meshes. - * - */ - /** - * Default constructor - * - */ - Interpolation3D::Interpolation3D() - { - } - Interpolation3D::Interpolation3D(const InterpolationOptions& io):Interpolation(io) - { - } -} diff --git a/src/INTERP_KERNEL/Interpolation3D.hxx b/src/INTERP_KERNEL/Interpolation3D.hxx deleted file mode 100644 index 828c63c76..000000000 --- a/src/INTERP_KERNEL/Interpolation3D.hxx +++ /dev/null @@ -1,43 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 -// 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 __INTERPOLATION3D_HXX__ -#define __INTERPOLATION3D_HXX__ - -#include "INTERPKERNELDefines.hxx" -#include "Interpolation.hxx" -#include "NormalizedUnstructuredMesh.hxx" -#include "InterpolationOptions.hxx" - -namespace INTERP_KERNEL -{ - class INTERPKERNEL_EXPORT Interpolation3D : public Interpolation - { - public: - Interpolation3D(); - Interpolation3D(const InterpolationOptions& io); - template - int interpolateMeshes(const MyMeshType& srcMesh, const MyMeshType& targetMesh, MatrixType& result, const std::string& method); - private: - SplittingPolicy _splitting_policy; - }; -} - -#endif diff --git a/src/INTERP_KERNEL/Interpolation3D.txx b/src/INTERP_KERNEL/Interpolation3D.txx deleted file mode 100644 index bc68b525c..000000000 --- a/src/INTERP_KERNEL/Interpolation3D.txx +++ /dev/null @@ -1,370 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 -// 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 __INTERPOLATION3D_TXX__ -#define __INTERPOLATION3D_TXX__ - -#include "Interpolation3D.hxx" -#include "Interpolation.txx" -#include "MeshElement.txx" -#include "TransformedTriangle.hxx" -#include "PolyhedronIntersectorP0P0.txx" -#include "PointLocator3DIntersectorP0P0.txx" -#include "PolyhedronIntersectorP0P1.txx" -#include "PointLocator3DIntersectorP0P1.txx" -#include "PolyhedronIntersectorP1P0.txx" -#include "PolyhedronIntersectorP1P0Bary.txx" -#include "PointLocator3DIntersectorP1P0.txx" -#include "PolyhedronIntersectorP1P1.txx" -#include "PointLocator3DIntersectorP1P1.txx" -#include "Barycentric3DIntersectorP1P1.txx" -#include "Log.hxx" -// If defined, use recursion to traverse the binary search tree, else use the BBTree class -//#define USE_RECURSIVE_BBOX_FILTER - -#ifdef USE_RECURSIVE_BBOX_FILTER -#include "MeshRegion.txx" -#include "RegionNode.hxx" -#include - -#else // use BBTree class - -#include "BBTree.txx" - -#endif - -namespace INTERP_KERNEL -{ - /** - * Calculates the matrix of volumes of intersection between the elements of srcMesh and the elements of targetMesh. - * The calculation is done in two steps. First a filtering process reduces the number of pairs of elements for which the - * calculation must be carried out by eliminating pairs that do not intersect based on their bounding boxes. Then, the - * volume of intersection is calculated by an object of type Intersector3D for the remaining pairs, and entered into the - * intersection matrix. - * - * The matrix is partially sparse : it is a vector of maps of integer - double pairs. - * It can also be an INTERP_KERNEL::Matrix object. - * The length of the vector is equal to the number of target elements - for each target element there is a map, regardless - * of whether the element intersects any source elements or not. But in the maps there are only entries for those source elements - * which have a non-zero intersection volume with the target element. The vector has indices running from - * 0 to (nb target elements - 1), meaning that the map for target element i is stored at index i - 1. In the maps, however, - * the indexing is more natural : the intersection volume of the target element i with source element j is found at matrix[i-1][j]. - * - - * @param srcMesh 3-dimensional source mesh - * @param targetMesh 3-dimesional target mesh, containing only tetraedra - * @param result matrix in which the result is stored - * - */ - template - int Interpolation3D::interpolateMeshes(const MyMeshType& srcMesh, const MyMeshType& targetMesh, MatrixType& result, const std::string& method) - { - typedef typename MyMeshType::MyConnType ConnType; - // create MeshElement objects corresponding to each element of the two meshes - const unsigned long numSrcElems = srcMesh.getNumberOfElements(); - const unsigned long numTargetElems = targetMesh.getNumberOfElements(); - - LOG(2, "Source mesh has " << numSrcElems << " elements and target mesh has " << numTargetElems << " elements "); - - std::vector*> srcElems(numSrcElems); - std::vector*> targetElems(numTargetElems); - - std::map*, int> indices; - - for(unsigned long i = 0 ; i < numSrcElems ; ++i) - srcElems[i] = new MeshElement(i, srcMesh); - - for(unsigned long i = 0 ; i < numTargetElems ; ++i) - targetElems[i] = new MeshElement(i, targetMesh); - - Intersector3D* intersector=0; - std::string methC = InterpolationOptions::filterInterpolationMethod(method); - if(methC=="P0P0") - { - switch(InterpolationOptions::getIntersectionType()) - { - case Triangulation: - intersector=new PolyhedronIntersectorP0P0(targetMesh, srcMesh, getSplittingPolicy()); - break; - case PointLocator: - intersector=new PointLocator3DIntersectorP0P0(targetMesh, srcMesh, getPrecision()); - break; - default: - throw INTERP_KERNEL::Exception("Invalid 3D intersection type for P0P0 interp specified : must be Triangle or PointLocator."); - } - } - else if(methC=="P0P1") - { - switch(InterpolationOptions::getIntersectionType()) - { - case Triangulation: - intersector=new PolyhedronIntersectorP0P1(targetMesh, srcMesh, getSplittingPolicy()); - break; - case PointLocator: - intersector=new PointLocator3DIntersectorP0P1(targetMesh, srcMesh, getPrecision()); - break; - default: - throw INTERP_KERNEL::Exception("Invalid 3D intersection type for P0P1 interp specified : must be Triangle or PointLocator."); - } - } - else if(methC=="P1P0") - { - switch(InterpolationOptions::getIntersectionType()) - { - case Triangulation: - intersector=new PolyhedronIntersectorP1P0(targetMesh, srcMesh, getSplittingPolicy()); - break; - case PointLocator: - intersector=new PointLocator3DIntersectorP1P0(targetMesh, srcMesh, getPrecision()); - break; - case Barycentric: - intersector=new PolyhedronIntersectorP1P0Bary(targetMesh, srcMesh, getSplittingPolicy()); - break; - default: - throw INTERP_KERNEL::Exception("Invalid 3D intersection type for P1P0 interp specified : must be Triangle, PointLocator or Barycentric."); - } - } - else if(methC=="P1P1") - { - switch(InterpolationOptions::getIntersectionType()) - { - case Triangulation: - intersector=new PolyhedronIntersectorP1P1(targetMesh, srcMesh, getSplittingPolicy()); - break; - case PointLocator: - intersector=new PointLocator3DIntersectorP1P1(targetMesh, srcMesh, getPrecision()); - break; - case Barycentric: - intersector=new Barycentric3DIntersectorP1P1(targetMesh, srcMesh, getPrecision()); - break; - default: - throw INTERP_KERNEL::Exception("Invalid 3D intersection type for P1P1 interp specified : must be Triangle or PointLocator."); - } - } - else - throw Exception("Invalid method choosed must be in \"P0P0\", \"P0P1\", \"P1P0\" or \"P1P1\"."); - // create empty maps for all source elements - result.resize(intersector->getNumberOfRowsOfResMatrix()); - -#ifdef USE_RECURSIVE_BBOX_FILTER - - /* - * Performs a depth-first search over srcMesh, using bounding boxes to recursively eliminate the elements of targetMesh - * which cannot intersect smaller and smaller regions of srcMesh. At each level, each region is divided in two, forming - * a binary search tree with leaves consisting of only one element of the source mesh together with the elements of the - * target mesh that can intersect it. The recursion is implemented with a stack of RegionNodes, each one containing a - * source region and a target region. Each region has an associated bounding box and a vector of pointers to the elements - * that belong to it. Each MeshElement contains a bounding box and the global number of the corresponding element in the mesh. - */ - - // create initial RegionNode and fill up its source region with all the source mesh elements and - // its target region with all the target mesh elements whose bounding box - // intersects that of the source region - - RegionNode* firstNode = new RegionNode(); - - MeshRegion& srcRegion = firstNode->getSrcRegion(); - - for(unsigned long i = 0 ; i < numSrcElems ; ++i) - { - srcRegion.addElement(srcElems[i], srcMesh); - } - - MeshRegion& targetRegion = firstNode->getTargetRegion(); - - for(unsigned long i = 0 ; i < numTargetElems ; ++i) - { - if(!srcRegion.isDisjointWithElementBoundingBox( *(targetElems[i]) )) - { - targetRegion.addElement(targetElems[i], targetMesh); - } - } - - // Using a stack, descend recursively, creating at each step two new RegionNodes having as source region the left and - // right part of the source region of the current node (created using MeshRegion::split()) and as target region all the - // elements of the target mesh whose bounding box intersects the corresponding part - // Continue until the source region contains only one element, at which point the intersection volumes are - // calculated with all the remaining target mesh elements and stored in the matrix if they are non-zero. - - std::stack< RegionNode* > nodes; - nodes.push(firstNode); - - while(!nodes.empty()) - { - RegionNode* currNode = nodes.top(); - nodes.pop(); - LOG(4, "Popping node "); - - if(currNode->getTargetRegion().getNumberOfElements() == 1) - { - // calculate volumes - LOG(4, " - One element"); - - MeshElement* targetElement = *(currNode->getTargetRegion().getBeginElements()); - std::vector intersectElems; - for(typename std::vector< MeshElement* >::const_iterator iter = currNode->getSrcRegion().getBeginElements();iter != currNode->getSrcRegion().getEndElements();++iter) - intersectElems.push_back((*iter)->getIndex()); - intersector->intersectCells(targetElement->getIndex(),intersectElems,result); - } - else // recursion - { - - LOG(4, " - Recursion"); - - RegionNode* leftNode = new RegionNode(); - RegionNode* rightNode = new RegionNode(); - - // split current source region - //} decide on axis - static BoundingBox::BoxCoord axis = BoundingBox::XMAX; - - currNode->getTargetRegion().split(leftNode->getTargetRegion(), rightNode->getTargetRegion(), axis, targetMesh); - - LOG(5, "After split, left target region has " << leftNode->getTargetRegion().getNumberOfElements() - << " elements and right target region has " << rightNode->getTargetRegion().getNumberOfElements() - << " elements"); - - // ugly hack to avoid problem with enum which does not start at 0 - // I guess I ought to implement ++ for it instead ... - // Anyway, it basically chooses the next axis, cyclically - axis = (axis != BoundingBox::ZMAX) ? static_cast(axis + 1) : BoundingBox::XMAX; - - // add source elements of current node that overlap the target regions of the new nodes - LOG(5, " -- Adding source elements"); - int numLeftElements = 0; - int numRightElements = 0; - for(typename std::vector*>::const_iterator iter = currNode->getSrcRegion().getBeginElements() ; - iter != currNode->getSrcRegion().getEndElements() ; ++iter) - { - LOG(6, " --- New target node"); - - if(!leftNode->getTargetRegion().isDisjointWithElementBoundingBox(**iter)) - { - leftNode->getSrcRegion().addElement(*iter, srcMesh); - ++numLeftElements; - } - - if(!rightNode->getTargetRegion().isDisjointWithElementBoundingBox(**iter)) - { - rightNode->getSrcRegion().addElement(*iter, srcMesh); - ++numRightElements; - } - - } - - LOG(5, "Left src region has " << numLeftElements << " elements and right src region has " - << numRightElements << " elements"); - - // push new nodes on stack - if(numLeftElements != 0) - { - nodes.push(leftNode); - } - else - { - delete leftNode; - } - - if(numRightElements != 0) - { - nodes.push(rightNode); - } - else - { - delete rightNode; - } - } - - // all nodes are deleted here - delete currNode; - - LOG(4, "Next iteration. Nodes left : " << nodes.size()); - } - -#else // Use BBTree - - // create BBTree structure - // - get bounding boxes - double* bboxes = new double[6 * numSrcElems]; - int* srcElemIdx = new int[numSrcElems]; - for(unsigned long i = 0; i < numSrcElems ; ++i) - { - // get source bboxes in right order - const BoundingBox* box = srcElems[i]->getBoundingBox(); - bboxes[6*i+0] = box->getCoordinate(BoundingBox::XMIN); - bboxes[6*i+1] = box->getCoordinate(BoundingBox::XMAX); - bboxes[6*i+2] = box->getCoordinate(BoundingBox::YMIN); - bboxes[6*i+3] = box->getCoordinate(BoundingBox::YMAX); - bboxes[6*i+4] = box->getCoordinate(BoundingBox::ZMIN); - bboxes[6*i+5] = box->getCoordinate(BoundingBox::ZMAX); - - // source indices have to begin with zero for BBox, I think - srcElemIdx[i] = srcElems[i]->getIndex(); - } - - BBTree<3,ConnType> tree(bboxes, srcElemIdx, 0, numSrcElems); - - // for each target element, get source elements with which to calculate intersection - // - calculate intersection by calling intersectCells - for(unsigned long i = 0; i < numTargetElems; ++i) - { - const BoundingBox* box = targetElems[i]->getBoundingBox(); - const int targetIdx = targetElems[i]->getIndex(); - - // get target bbox in right order - double targetBox[6]; - targetBox[0] = box->getCoordinate(BoundingBox::XMIN); - targetBox[1] = box->getCoordinate(BoundingBox::XMAX); - targetBox[2] = box->getCoordinate(BoundingBox::YMIN); - targetBox[3] = box->getCoordinate(BoundingBox::YMAX); - targetBox[4] = box->getCoordinate(BoundingBox::ZMIN); - targetBox[5] = box->getCoordinate(BoundingBox::ZMAX); - - std::vector intersectElems; - - tree.getIntersectingElems(targetBox, intersectElems); - - if ( !intersectElems.empty() ) - intersector->intersectCells(targetIdx,intersectElems,result); - } - - delete [] bboxes; - delete [] srcElemIdx; - -#endif - // free allocated memory - int ret=intersector->getNumberOfColsOfResMatrix(); - - delete intersector; - - for(unsigned long i = 0 ; i < numSrcElems ; ++i) - { - delete srcElems[i]; - } - for(unsigned long i = 0 ; i < numTargetElems ; ++i) - { - delete targetElems[i]; - } - return ret; - - } -} - -#endif diff --git a/src/INTERP_KERNEL/Interpolation3D2D.cxx b/src/INTERP_KERNEL/Interpolation3D2D.cxx deleted file mode 100644 index 4e8cee7f7..000000000 --- a/src/INTERP_KERNEL/Interpolation3D2D.cxx +++ /dev/null @@ -1,34 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// - -#include "Interpolation3D2D.hxx" - -namespace INTERP_KERNEL -{ - /** - * Default constructor - * - */ - Interpolation3D2D::Interpolation3D2D() - { - } - Interpolation3D2D::Interpolation3D2D(const InterpolationOptions& io):Interpolation(io) - { - } -} diff --git a/src/INTERP_KERNEL/Interpolation3D2D.hxx b/src/INTERP_KERNEL/Interpolation3D2D.hxx deleted file mode 100644 index 761c37f34..000000000 --- a/src/INTERP_KERNEL/Interpolation3D2D.hxx +++ /dev/null @@ -1,61 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 -// 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 __INTERPOLATION3D2D_HXX__ -#define __INTERPOLATION3D2D_HXX__ - -#include -#include - -#include "INTERPKERNELDefines.hxx" -#include "Interpolation.hxx" -#include "NormalizedUnstructuredMesh.hxx" -#include "InterpolationOptions.hxx" - -namespace INTERP_KERNEL -{ - /*! - * Contrary to its name this class deals with 2D mesh in source and 3D mesh in target. - * The meshdim of 'MyMeshType' in input is ignored that's why 'meshS' and 'meshT' - * have the same type. - * '_duplicate_faces' attribute stores duplicated faces in the following format. - * The key of '_duplicate_faces' represents the 2D cellId that is shared by - * more than one 3D target cell, and the value of '_duplicate_faces' - * the 3D target cells. The size of the value of '_duplicate_faces' is more than or equal to 2. - */ - class Interpolation3D2D : public Interpolation - { - public: - typedef std::map > DuplicateFacesType; - - INTERPKERNEL_EXPORT Interpolation3D2D(); - INTERPKERNEL_EXPORT Interpolation3D2D(const InterpolationOptions& io); - template - int interpolateMeshes(const MyMeshType& srcMesh, - const MyMeshType& targetMesh, - MyMatrixType& matrix, - const std::string& method); - INTERPKERNEL_EXPORT DuplicateFacesType retrieveDuplicateFaces() const { return _duplicate_faces; } - private: - SplittingPolicy _splitting_policy; - DuplicateFacesType _duplicate_faces; - }; -} - -#endif diff --git a/src/INTERP_KERNEL/Interpolation3D2D.txx b/src/INTERP_KERNEL/Interpolation3D2D.txx deleted file mode 100644 index 674317e1a..000000000 --- a/src/INTERP_KERNEL/Interpolation3D2D.txx +++ /dev/null @@ -1,190 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 -// 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 __INTERPOLATION3D2D_TXX__ -#define __INTERPOLATION3D2D_TXX__ - -#include "Interpolation3D2D.hxx" -#include "Interpolation.txx" -#include "MeshElement.txx" -#include "TransformedTriangle.hxx" -#include "Polyhedron3D2DIntersectorP0P0.txx" -#include "PointLocator3DIntersectorP0P0.txx" -#include "PolyhedronIntersectorP0P1.txx" -#include "PointLocator3DIntersectorP0P1.txx" -#include "PolyhedronIntersectorP1P0.txx" -#include "PolyhedronIntersectorP1P0Bary.txx" -#include "PointLocator3DIntersectorP1P0.txx" -#include "PolyhedronIntersectorP1P1.txx" -#include "PointLocator3DIntersectorP1P1.txx" -#include "Log.hxx" - -#include "BBTree.txx" - -namespace INTERP_KERNEL -{ - /** - * Calculates the matrix of volumes of intersection between the elements of srcMesh and the elements of targetMesh. - * The calculation is done in two steps. First a filtering process reduces the number of pairs of elements for which the - * calculation must be carried out by eliminating pairs that do not intersect based on their bounding boxes. Then, the - * volume of intersection is calculated by an object of type Intersector3D for the remaining pairs, and entered into the - * intersection matrix. - * - * The matrix is partially sparse : it is a vector of maps of integer - double pairs. - * It can also be an INTERP_KERNEL::Matrix object. - * The length of the vector is equal to the number of target elements - for each target element there is a map, regardless - * of whether the element intersects any source elements or not. But in the maps there are only entries for those source elements - * which have a non-zero intersection volume with the target element. The vector has indices running from - * 0 to (nb target elements - 1), meaning that the map for target element i is stored at index i - 1. In the maps, however, - * the indexing is more natural : the intersection volume of the target element i with source element j is found at matrix[i-1][j]. - * - - * @param srcMesh 3-dimensional source mesh - * @param targetMesh 3-dimesional target mesh, containing only tetraedra - * @param matrix matrix in which the result is stored - * - */ - template - int Interpolation3D2D::interpolateMeshes(const MyMeshType& srcMesh, - const MyMeshType& targetMesh, - MyMatrixType& matrix, - const std::string& method) - { - typedef typename MyMeshType::MyConnType ConnType; - // create MeshElement objects corresponding to each element of the two meshes - const unsigned long numSrcElems = srcMesh.getNumberOfElements(); - const unsigned long numTargetElems = targetMesh.getNumberOfElements(); - - LOG(2, "Source mesh has " << numSrcElems << " elements and target mesh has " << numTargetElems << " elements "); - - std::vector*> srcElems(numSrcElems); - std::vector*> targetElems(numTargetElems); - - std::map*, int> indices; - DuplicateFacesType intersectFaces; - - for(unsigned long i = 0 ; i < numSrcElems ; ++i) - srcElems[i] = new MeshElement(i, srcMesh); - - for(unsigned long i = 0 ; i < numTargetElems ; ++i) - targetElems[i] = new MeshElement(i, targetMesh); - - Intersector3D* intersector=0; - std::string methC = InterpolationOptions::filterInterpolationMethod(method); - const double dimCaracteristic = CalculateCharacteristicSizeOfMeshes(srcMesh, targetMesh, InterpolationOptions::getPrintLevel()); - if(methC=="P0P0") - { - switch(InterpolationOptions::getIntersectionType()) - { - case Triangulation: - intersector=new Polyhedron3D2DIntersectorP0P0(targetMesh, - srcMesh, - dimCaracteristic, - getPrecision(), - intersectFaces, - getSplittingPolicy()); - break; - case PointLocator: - intersector=new PointLocator3DIntersectorP0P0(targetMesh,srcMesh,getPrecision()); - break; - default: - throw INTERP_KERNEL::Exception("Invalid 3D to 2D intersection type for P0P0 interp specified : must be Triangulation or PointLocator."); - } - } - else - throw Exception("Invalid method choosed must be in \"P0P0\"."); - // create empty maps for all source elements - matrix.resize(intersector->getNumberOfRowsOfResMatrix()); - - // create BBTree structure - // - get bounding boxes - double* bboxes = new double[6 * numSrcElems]; - int* srcElemIdx = new int[numSrcElems]; - for(unsigned long i = 0; i < numSrcElems ; ++i) - { - // get source bboxes in right order - const BoundingBox* box = srcElems[i]->getBoundingBox(); - bboxes[6*i+0] = box->getCoordinate(BoundingBox::XMIN); - bboxes[6*i+1] = box->getCoordinate(BoundingBox::XMAX); - bboxes[6*i+2] = box->getCoordinate(BoundingBox::YMIN); - bboxes[6*i+3] = box->getCoordinate(BoundingBox::YMAX); - bboxes[6*i+4] = box->getCoordinate(BoundingBox::ZMIN); - bboxes[6*i+5] = box->getCoordinate(BoundingBox::ZMAX); - - // source indices have to begin with zero for BBox, I think - srcElemIdx[i] = srcElems[i]->getIndex(); - } - - BBTree<3,ConnType> tree(bboxes, srcElemIdx, 0, numSrcElems, 0.); - - // for each target element, get source elements with which to calculate intersection - // - calculate intersection by calling intersectCells - for(unsigned long i = 0; i < numTargetElems; ++i) - { - const BoundingBox* box = targetElems[i]->getBoundingBox(); - const int targetIdx = targetElems[i]->getIndex(); - - // get target bbox in right order - double targetBox[6]; - targetBox[0] = box->getCoordinate(BoundingBox::XMIN); - targetBox[1] = box->getCoordinate(BoundingBox::XMAX); - targetBox[2] = box->getCoordinate(BoundingBox::YMIN); - targetBox[3] = box->getCoordinate(BoundingBox::YMAX); - targetBox[4] = box->getCoordinate(BoundingBox::ZMIN); - targetBox[5] = box->getCoordinate(BoundingBox::ZMAX); - - std::vector intersectElems; - - tree.getIntersectingElems(targetBox, intersectElems); - - if ( !intersectElems.empty() ) - intersector->intersectCells(targetIdx, intersectElems, matrix); - - } - - delete [] bboxes; - delete [] srcElemIdx; - - DuplicateFacesType::iterator iter; - for (iter = intersectFaces.begin(); iter != intersectFaces.end(); ++iter) - { - if (iter->second.size() > 1) - { - _duplicate_faces.insert(std::make_pair(iter->first, iter->second)); - } - } - - // free allocated memory - int ret=intersector->getNumberOfColsOfResMatrix(); - - delete intersector; - - for(unsigned long i = 0 ; i < numSrcElems ; ++i) - { - delete srcElems[i]; - } - for(unsigned long i = 0 ; i < numTargetElems ; ++i) - { - delete targetElems[i]; - } - return ret; - - } -} - -#endif diff --git a/src/INTERP_KERNEL/Interpolation3DSurf.cxx b/src/INTERP_KERNEL/Interpolation3DSurf.cxx deleted file mode 100644 index 708d11a37..000000000 --- a/src/INTERP_KERNEL/Interpolation3DSurf.cxx +++ /dev/null @@ -1,61 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 -// 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 "Interpolation3DSurf.hxx" -#include "InterpolationPlanar.txx" - -namespace INTERP_KERNEL -{ - Interpolation3DSurf::Interpolation3DSurf() - { - } - - Interpolation3DSurf::Interpolation3DSurf(const InterpolationOptions& io):InterpolationPlanar(io) - { - } - - - /** - \brief Function used to set the options for the intersection calculation - \details The following options can be modified: - -# intersectionType: the type of algorithm to be used in the computation of the cell-cell intersections. - - Values: Triangle, Convex. - - Default: Triangle. - -# medianPlan: Position of the median plane where both cells will be projected - - Values: between 0 and 1. - - Default: 0.5. - -# doRotat: rotate the coordinate system such that the target cell is in the Oxy plane. - - Values: true (necessarilly if Intersection_type=Triangle), false. - - Default: true (as default Intersection_type=Triangle) - -# precision: Level of precision of the computations is precision times the characteristic size of the mesh. - - Values: positive real number. - - Default: 1.0E-12. - -# printLevel: Level of verboseness during the computations. - - Values: interger between 0 and 3. - - Default: 0. - */ - void Interpolation3DSurf::setOptions(double precision, int printLevel, double medianPlan, - IntersectionType intersectionType, bool doRotat, int orientation) - { - InterpolationPlanar::setOptions(precision,printLevel,intersectionType, orientation); - InterpolationPlanar::setDoRotate(doRotat); - InterpolationPlanar::setMedianPlane(medianPlan); - } -} diff --git a/src/INTERP_KERNEL/Interpolation3DSurf.hxx b/src/INTERP_KERNEL/Interpolation3DSurf.hxx deleted file mode 100644 index fda0fdd61..000000000 --- a/src/INTERP_KERNEL/Interpolation3DSurf.hxx +++ /dev/null @@ -1,44 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 -// 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 __INTERPOLATION3DSURF_HXX__ -#define __INTERPOLATION3DSURF_HXX__ - -#include "InterpolationPlanar.txx" -#include "INTERPKERNELDefines.hxx" -#include "InterpolationOptions.hxx" - -namespace INTERP_KERNEL -{ - class INTERPKERNEL_EXPORT Interpolation3DSurf : public InterpolationPlanar - { - public: - Interpolation3DSurf(); - Interpolation3DSurf(const InterpolationOptions& io); - void setOptions(double precision, int printLevel, double medianPlane, - IntersectionType intersectionType, bool doRotate, int orientation=0); - public: - template - void performAdjustmentOfBB(PlanarIntersector* intersector, std::vector& bbox) const - { intersector->adjustBoundingBoxes(bbox,InterpolationPlanar::getBoundingBoxAdjustment(),InterpolationPlanar::getBoundingBoxAdjustmentAbs()); } - }; -} - -#endif diff --git a/src/INTERP_KERNEL/InterpolationCC.hxx b/src/INTERP_KERNEL/InterpolationCC.hxx deleted file mode 100644 index 62f844b06..000000000 --- a/src/INTERP_KERNEL/InterpolationCC.hxx +++ /dev/null @@ -1,51 +0,0 @@ -// Copyright (C) 2009-2015 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, 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 -// 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 -// - -// File : InterpolationCC.hxx -// Created : Fri Aug 14 11:33:17 2009 -// Author : Edward AGAPOV (eap) -// -#ifndef __InterpolationCC_HXX__ -#define __InterpolationCC_HXX__ - -#include "Interpolation.hxx" - -namespace INTERP_KERNEL -{ - /*! - * \brief Interpolator of cartesian/cartesian meshes - */ - class InterpolationCC : public Interpolation - { -// static const int SPACEDIM=MyMeshType::MY_SPACEDIM; -// static const int MESHDIM=MyMeshType::MY_MESHDIM; -// typedef typename MyMeshType::MyConnType ConnType; -// static const NumberingPolicy numPol=MyMeshType::My_numPol; - public: - InterpolationCC(); - InterpolationCC(const InterpolationOptions& io); - template - int interpolateMeshes(const MyMeshType& srcMesh, const MyMeshType& targetMesh, MatrixType& result, const char *method); - - private: - }; -} - - -#endif diff --git a/src/INTERP_KERNEL/InterpolationCC.txx b/src/INTERP_KERNEL/InterpolationCC.txx deleted file mode 100644 index ea75faced..000000000 --- a/src/INTERP_KERNEL/InterpolationCC.txx +++ /dev/null @@ -1,252 +0,0 @@ -// Copyright (C) 2009-2015 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, 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 -// 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 -// -// File : InterpolationCC.txx -// Created : Fri Aug 14 11:39:27 2009 -// Author : Edward AGAPOV (eap) -// - -#include "InterpolationCC.hxx" -#include "InterpolationUtils.hxx" - -// convert index "From Mesh Index" -#define _FMI(i) OTT::ind2C((i)) -// convert index "To Mesh Index" -#define _TMI(i) OTT::indFC((i)) - -namespace INTERP_KERNEL -{ - //================================================================================ - /*! - * \brief Constructor does nothing - */ - //================================================================================ - InterpolationCC::InterpolationCC() - { - } - - InterpolationCC::InterpolationCC(const InterpolationOptions& io):Interpolation(io) - { - } - - //================================================================================ - /*! - * \brief An 1D intersection result - */ - //================================================================================ - - struct Interference - { - int _src_index; // source cell index along an axis - int _tgt_index; // target cell index along an axis - double _length; // interference length - Interference(int is = -1, int it = -1, double l = 0):_src_index(is),_tgt_index(it),_length(l){} - }; - - //================================================================================ - /*! - * \brief Fills the matrix by precomputed cell interferences along axes - * \param inter_of_axis - cell/cell interferences along each axis - * \param result - matrix to fill in - * \param src_nb_cells[] - nb of cells along each of axes in the source mesh - * \param tgt_nb_cells[] - nb of cells along each of axes in the target mesh - * \param src_i_cell - source cell number accumulated by previous axes - * \param tgt_i_cell - target cell number accumulated by previous axes - * \param src_prev_area - factor by which this axis icreases cell number - * \param tgt_prev_area - factor by which this axis icreases cell number - * \param axis - the axis to treat - * \param prev_value - intersection size computed by previous axes - */ - //================================================================================ - - template - void fillMatrix(const std::list< Interference > inter_of_axis[dim], - MatrixType& result, - const int src_nb_cells[dim], - const int tgt_nb_cells[dim], - const int src_i_cell = 0, - const int tgt_i_cell = 0, - const int src_prev_area = 1, - const int tgt_prev_area = 1, - const int axis = 0, - const double prev_value = 1.0) - { - typedef std::list < Interference >::const_iterator TIntIterator; - - if ( axis + 1 == dim ) - { - for ( TIntIterator i = inter_of_axis[axis].begin(); i != inter_of_axis[axis].end(); ++i ) - { - double value = i->_length * prev_value; - int src_i = i->_src_index * src_prev_area + src_i_cell; - int tgt_i = i->_tgt_index * tgt_prev_area + tgt_i_cell; - - result[ tgt_i ].insert( std::make_pair( _TMI( src_i ), value )); - } - } - else - { - int src_prev_area_next = src_prev_area * src_nb_cells[ axis ]; - int tgt_prev_area_next = tgt_prev_area * tgt_nb_cells[ axis ]; - - for ( TIntIterator i = inter_of_axis[axis].begin(); i != inter_of_axis[axis].end(); ++i ) - { - double value = i->_length * prev_value; - int src_i = i->_src_index * src_prev_area + src_i_cell; - int tgt_i = i->_tgt_index * tgt_prev_area + tgt_i_cell; - - // call for the next axis - fillMatrix(inter_of_axis, result, - src_nb_cells, tgt_nb_cells, src_i, tgt_i, - src_prev_area_next, tgt_prev_area_next, - axis+1, value ); - } - } - } - - //================================================================================ - /*! - * \brief Calculates the matrix of volumes of intersection between the elements of - * src_mesh and the elements of targetMesh - * \param src_mesh - source mesh - * \param tgt_mesh - target mesh - * \param result - matrix in which the result is stored - * \param method - interpolation method, not used as only "P0P0" is implemented so far - * - * The matrix is partially sparse : it is a vector of maps of integer - double pairs. - * It can also be an INTERP_KERNEL::Matrix object. - * The length of the vector is equal to the number of target elements - for each target - * element there is a map, regardless of whether the element intersects any source - * elements or not. But in the maps there are only entries for those source elements - * which have a non-zero intersection volume with the target element. The vector has - * indices running from 0 to (nb target elements - 1), meaning that the map for target - * element i is stored at index i - 1. In the maps, however, the indexing is more natural: - * the intersection volume of the target element i with source element j is found at matrix[i-1][j] - */ - //================================================================================ - - template - int InterpolationCC::interpolateMeshes(const MyMeshType& src_mesh, - const MyMeshType& tgt_mesh, - MatrixType& result, - const char * method) - { - if ( std::string("P0P0") != method ) - throw Exception("Only P0P0 method is implemented so far"); - - // create empty maps for all target elements - result.resize( tgt_mesh.getNumberOfElements() ); - - const int ret = src_mesh.getNumberOfElements(); - - const double eps = getPrecision(); - const int dim = MyMeshType::MY_MESHDIM; - //const NumberingPolicy numPol = MyMeshType::My_numPol; - - const double* src_coords[ dim ]; - const double* tgt_coords[ dim ]; - int src_nb_cells[ dim ]; - int tgt_nb_cells[ dim ]; - for ( int j = 0; j < dim; ++j ) - { - src_coords[ j ] = src_mesh.getCoordsAlongAxis( _TMI( j )); - tgt_coords[ j ] = tgt_mesh.getCoordsAlongAxis( _TMI( j )); - src_nb_cells[ j ] = src_mesh.nbCellsAlongAxis( _TMI( j )); - tgt_nb_cells[ j ] = tgt_mesh.nbCellsAlongAxis( _TMI( j )); - } - - // ============================================ - // Calculate cell interferences along the axes - // ============================================ - - std::list < Interference > interferences[ dim ]; - - for ( int j = 0; j < dim; ++j ) // loop on axes of castesian space - { - std::list < Interference >& axis_interferences = interferences[j]; - - int it = 0, is = 0; - double x1t, x2t, x1s, x2s; // left and right ordinates of target and source cells - - // look for the first interference - // -------------------------------- - bool intersection = false; - while ( !intersection && it < tgt_nb_cells[j] && is < src_nb_cells[j] ) - { - x1s = src_coords[ j ][ is ]; - x2t = tgt_coords[ j ][ it+1 ]; - if ( x2t < x1s+eps ) - { - it++; // source lays on the right of target - continue; - } - x1t = tgt_coords[ j ][ it ]; - x2s = src_coords[ j ][ is+1 ]; - if ( x2s < x1t+eps ) - { - is++; // source lays on the left of target - continue; - } - intersection = true; - } - if ( !intersection ) return ret; // no intersections - - // get all interferences - // ---------------------- - while ( intersection ) - { - x1s = src_coords[ j ][ is ]; - x1t = tgt_coords[ j ][ it ]; - x2t = tgt_coords[ j ][ it+1 ]; - x2s = src_coords[ j ][ is+1 ]; - - double x1 = std::max( x1s ,x1t ); - double x2 = std::min( x2s ,x2t ); - axis_interferences.push_back( Interference( is, it, x2 - x1 )); - - // to the next target and/or source cell - double diff2 = x2s - x2t; - if ( diff2 > -eps ) - intersection = ( ++it < tgt_nb_cells[j] ); - if ( diff2 < eps ) - intersection = ( ++is < src_nb_cells[j] && intersection); - } - } - - // ================ - // Fill the matrix - // ================ - - switch ( dim ) - { - case 3: - fillMatrix( interferences, result, src_nb_cells,tgt_nb_cells ); - break; - - case 2: - fillMatrix( interferences, result, src_nb_cells,tgt_nb_cells ); - break; - - case 1: - fillMatrix( interferences, result, src_nb_cells,tgt_nb_cells ); - break; - } - - return ret; - } -} diff --git a/src/INTERP_KERNEL/InterpolationCU.hxx b/src/INTERP_KERNEL/InterpolationCU.hxx deleted file mode 100644 index 1b9589777..000000000 --- a/src/INTERP_KERNEL/InterpolationCU.hxx +++ /dev/null @@ -1,47 +0,0 @@ -// Copyright (C) 2009-2015 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, 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 -// 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 -// - -// File : InterpolationCU.hxx -// Created : Mon Dec 14 16:52:53 2009 -// Author : Edward AGAPOV (eap) -// -#ifndef __InterpolationCU_HXX__ -#define __InterpolationCU_HXX__ - -#include "Interpolation.hxx" -#include "NormalizedUnstructuredMesh.hxx" - -namespace INTERP_KERNEL -{ - class InterpolationCU : public Interpolation< InterpolationCU > - { - public: - InterpolationCU(); - InterpolationCU(const InterpolationOptions & io); - - template - int interpolateMeshes(const MyCMeshType& meshS, const MyUMeshType& meshT, MatrixType& result, const char *method); - - template - int interpolateMeshesRev(const MyUMeshType& meshS, const MyCMeshType& meshT, MatrixType& result, const char *method); - - }; -} - -#endif diff --git a/src/INTERP_KERNEL/InterpolationCU.txx b/src/INTERP_KERNEL/InterpolationCU.txx deleted file mode 100644 index 51b30bfbd..000000000 --- a/src/INTERP_KERNEL/InterpolationCU.txx +++ /dev/null @@ -1,236 +0,0 @@ -// Copyright (C) 2009-2015 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, 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 -// 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 -// -// File : InterpolationCU.txx -// Created : Mon Dec 14 17:30:25 2009 -// Author : Edward AGAPOV (eap) - -#ifndef __InterpolationCU_TXX__ -#define __InterpolationCU_TXX__ - -#include "InterpolationCU.hxx" - -#include "Interpolation.txx" -#include "IntersectorCU1D.txx" -#include "IntersectorCU2D.txx" -#include "IntersectorCU3D.txx" - -#include - -// // convert index "From Mesh Index" -#define _FMIU(i) OTT::ind2C((i)) -#define _FMIC(i) OTT::ind2C((i)) -// convert index "To Mesh Index" -#define _TMIU(i) OTT::indFC((i)) -#define _TMIC(i) OTT::indFC((i)) -// convert coord "From Mesh Coord" -#define _FMCOO(i) OTT::coo2C((i)) -// convert connectivity "From Mesh Connectivity" -#define _FMCON(i) OTT::conn2C((i)) - -namespace INTERP_KERNEL -{ - /** - * \defgroup InterpolationCU InterpolationCU - * \class InterpolationCU - * \brief Class used to calculate the volumes of intersection between the elements of a cartesian and an unstructured meshes. - * - */ - //================================================================================ - /** - * Default constructor - * - */ - //================================================================================ - - InterpolationCU::InterpolationCU() - { - } - - InterpolationCU::InterpolationCU(const InterpolationOptions & io) - :Interpolation(io) - { - } - - //================================================================================ - /** - * Calculates the matrix of volumes of intersection between the elements of srcMesh and the elements of targetMesh. - * The calculation is done in two steps. First a filtering process reduces the number of pairs of elements for which the - * calculation must be carried out by eliminating pairs that do not intersect based on their bounding boxes. Then, the - * volume of intersection is calculated for the remaining pairs, and entered into the - * intersection matrix. - * - * The matrix is partially sparse : it is a vector of maps of integer - double pairs. - * It can also be an INTERP_KERNEL::Matrix object. - * The length of the vector is equal to the number of target elements - for each target element there is a map, regardless - * of whether the element intersects any source elements or not. But in the maps there are only entries for those source elements - * which have a non-zero intersection volume with the target element. The vector has indices running from - * 0 to (nb target elements - 1), meaning that the map for target element i is stored at index i - 1. In the maps, however, - * the indexing is more natural : the intersection volume of the target element i with source element j is found at matrix[i-1][j]. - * - - * @param srcMesh cartesian source mesh - * @param targetMesh unstructured target mesh - * @param result matrix in which the result is stored - * @param method interpolation method - */ - //================================================================================ - - template - int InterpolationCU::interpolateMeshes(const MyCMeshType& src_mesh, - const MyUMeshType& tgt_mesh, - MatrixType& result, - const char * method) - { - typedef typename MyCMeshType::MyConnType CConnType; - - if ( std::string("P0P0") != method ) - throw Exception("Only P0P0 method is implemented so far"); - if ( MyCMeshType::MY_SPACEDIM != MyUMeshType::MY_SPACEDIM || - MyCMeshType::MY_SPACEDIM != MyUMeshType::MY_MESHDIM ) - throw Exception("InterpolationCU::interpolateMeshes(): dimension of meshes must be same"); - - const double eps = getPrecision(); - const int dim = MyCMeshType::MY_SPACEDIM; - - TargetIntersector* intersector = 0; - switch( dim ) - { - case 1: intersector = new IntersectorCU1D( src_mesh, tgt_mesh ); break; - case 2: intersector = new IntersectorCU2D( src_mesh, tgt_mesh ); break; - case 3: intersector = new IntersectorCU3D( src_mesh, tgt_mesh, getSplittingPolicy() ); break; - } - // create empty maps for all target elements - result.resize( intersector->getNumberOfRowsOfResMatrix() ); - const int ret = intersector->getNumberOfColsOfResMatrix(); - - const double* src_coords[ dim ]; - int src_nb_coords[ dim ]; - std::map< double, int> src_coord_to_index[ dim ]; - for ( int j = 0; j < dim; ++j ) - { - src_coords [j] = src_mesh.getCoordsAlongAxis( _TMIC( j )); - src_nb_coords[j] = src_mesh.nbCellsAlongAxis ( _TMIC( j )) + 1; - for (int i = 0; i < src_nb_coords[j]; ++i ) - src_coord_to_index[j].insert( std::make_pair( src_coords[j][i], i )); - } - - const unsigned long tgtu_nb_cells = tgt_mesh.getNumberOfElements(); - - IntersectorCU bbHelper(src_mesh, tgt_mesh); - double bb[2*dim]; - - // loop on unstructured tgt cells - - for(unsigned int iT=0; iT src_coords[j][0] + eps; - if ( !doItersect ) - continue; // no intersection - - // find structured src cells intersecting iT cell - std::vector< std::vector< CConnType > > structIndices(1); - std::map< double, int>::iterator coo_ind; - for ( int j = 0; j < dim; ++j ) - { - coo_ind = src_coord_to_index[j].lower_bound( bb[2*j+1] - eps ); - if ( coo_ind == src_coord_to_index[j].end() ) - --coo_ind; - int max_i = coo_ind->second; - - coo_ind = src_coord_to_index[j].upper_bound( bb[2*j ] + eps ); - if ( coo_ind != src_coord_to_index[j].begin() ) - --coo_ind; - int min_i = coo_ind->second; - - std::vector< std::vector< CConnType > > newStructIndices; - for ( unsigned int iInd = 0; iInd < structIndices.size(); ++iInd ) - { - for ( int i = min_i; i < max_i; ++i ) - { - std::vector< CConnType > index = structIndices[iInd]; - index.push_back( i ); - newStructIndices.push_back( index ); - } - } - structIndices.swap( newStructIndices ); - } - - // perform intersection - - for ( unsigned int iInd = 0; iInd < structIndices.size(); ++iInd ) - intersector->intersectCells( iT, structIndices[iInd], result ); - } - delete intersector; - return ret; - } - - //================================================================================ - /** - * Calculates the matrix of volumes of intersection between the elements of srcMesh and the elements of targetMesh. - * The calculation is done in two steps. First a filtering process reduces the number of pairs of elements for which the - * calculation must be carried out by eliminating pairs that do not intersect based on their bounding boxes. Then, the - * volume of intersection is calculated for the remaining pairs, and entered into the - * intersection matrix. - * - * The matrix is partially sparse : it is a vector of maps of integer - double pairs. - * It can also be an INTERP_KERNEL::Matrix object. - * The length of the vector is equal to the number of target elements - for each target element there is a map, regardless - * of whether the element intersects any source elements or not. But in the maps there are only entries for those source elements - * which have a non-zero intersection volume with the target element. The vector has indices running from - * 0 to (nb target elements - 1), meaning that the map for target element i is stored at index i - 1. In the maps, however, - * the indexing is more natural : the intersection volume of the target element i with source element j is found at matrix[i-1][j]. - * - - * @param srcMesh 2-dimesional unstructured target mesh - * @param targetMesh 2-dimensional cartesian source mesh - * @param result matrix in which the result is stored - * @param method interpolation method - */ - //================================================================================ - - template - int InterpolationCU::interpolateMeshesRev(const MyUMeshType& meshS, const MyCMeshType& meshT, MatrixType& result, const char *method) - { - MatrixType revResult; - int sizeT = interpolateMeshes( meshT, meshS, revResult, method ); - int sizeS = revResult.size(); - result.resize( sizeT ); - - for ( int iS = 0; iS < sizeS; ++iS ) - { - typename MatrixType::value_type & row = revResult[iS]; - typename MatrixType::value_type::iterator iT_surf = row.begin(); - for ( ; iT_surf != row.end(); ++iT_surf ) - result[ iT_surf->first ][ iS ] = iT_surf->second; - } - return sizeS; - } - -} - -#endif diff --git a/src/INTERP_KERNEL/InterpolationCurve.hxx b/src/INTERP_KERNEL/InterpolationCurve.hxx deleted file mode 100644 index 5bdc1a9d5..000000000 --- a/src/INTERP_KERNEL/InterpolationCurve.hxx +++ /dev/null @@ -1,44 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 -// 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 __INTERPOLATIONCURVE_HXX__ -#define __INTERPOLATIONCURVE_HXX__ - -#include "Interpolation.hxx" -#include "InterpolationOptions.hxx" - -namespace INTERP_KERNEL -{ - template - class InterpolationCurve : public Interpolation< InterpolationCurve > - { - public: - InterpolationCurve(); - InterpolationCurve(const InterpolationOptions & io); - - // Main function to interpolate - template - int interpolateMeshes(const MyMeshType& meshS, const MyMeshType& meshT, - MatrixType& result, const std::string& method); - - }; -} - -#endif diff --git a/src/INTERP_KERNEL/InterpolationCurve.txx b/src/INTERP_KERNEL/InterpolationCurve.txx deleted file mode 100644 index 239370a61..000000000 --- a/src/INTERP_KERNEL/InterpolationCurve.txx +++ /dev/null @@ -1,216 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 -// 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 __INTERPOLATIONCURVE_TXX__ -#define __INTERPOLATIONCURVE_TXX__ - -#include "InterpolationCurve.hxx" -#include "InterpolationOptions.hxx" -#include "CurveIntersectorP0P0.txx" -#include "CurveIntersectorP1P0.txx" -#include "CurveIntersectorP0P1.txx" -#include "CurveIntersectorP1P1.txx" -#include "CurveIntersectorP1P1PL.txx" -#include "BBTree.txx" - -#include - -namespace INTERP_KERNEL -{ - /** - * \defgroup interpolationCurve InterpolationCurve - * - * \class InterpolationCurve - * \brief Class used to compute the coefficients of the interpolation matrix between - * two local meshes in two dimensions. - */ - template - InterpolationCurve::InterpolationCurve() - { - } - - template - InterpolationCurve::InterpolationCurve (const InterpolationOptions& io) - :Interpolation< InterpolationCurve >(io) - { - } - - /** \brief Main function to interpolate 1D meshes. - \details The algorithm proceeds in two steps: first a filtering process reduces the number of pairs of elements for which the - * calculation must be carried out by eliminating pairs that do not intersect based on their bounding boxes. Then, the - * volume of intersection is calculated by an object of type IntersectorPlanar for the remaining pairs, and entered into the - * intersection matrix. - * - * The matrix is partially sparse : it is a vector of maps of integer - double pairs. - * The length of the vector is equal to the number of target elements - for each target element there is a map, regardless - * of whether the element intersects any source elements or not. But in the maps there are only entries for those source elements - * which have a non-zero intersection volume with the target element. The vector has indices running from - * 0 to (#target elements - 1), meaning that the map for target element i is stored at index i - 1. In the maps, however, - * the indexing is more natural : the intersection volume of the target element i with source element j is found at matrix[i-1][j]. - * - - * @param myMeshS Planar source mesh - * @Param myMeshT Planar target mesh - * @return vector containing for each element i of the source mesh, a map giving for each element j - * of the target mesh which i intersects, the area of the intersection - * - */ - template - template - int InterpolationCurve::interpolateMeshes (const MyMeshType& myMeshS, - const MyMeshType& myMeshT, - MatrixType& result, - const std::string& method) - { - static const int SPACEDIM=MyMeshType::MY_SPACEDIM; - typedef typename MyMeshType::MyConnType ConnType; - static const NumberingPolicy numPol = MyMeshType::My_numPol; - - long global_start = clock(); - int counter=0; - - long nbMailleS = myMeshS.getNumberOfElements(); - long nbMailleT = myMeshT.getNumberOfElements(); - - CurveIntersector* intersector=0; - if(method=="P0P0") - { - switch (InterpolationOptions::getIntersectionType()) - { - case Triangulation: - { - intersector = new CurveIntersectorP0P0(myMeshT, myMeshS, - InterpolationOptions::getPrecision(), - InterpolationOptions::getBoundingBoxAdjustmentAbs(), - InterpolationOptions::getMedianPlane(), - InterpolationOptions::getPrintLevel()); - break; - } - default: - throw INTERP_KERNEL::Exception("For P0P0 in 1D or 2D curve only Triangulation supported for the moment !"); - } - } - else if(method=="P0P1") - { - switch (InterpolationOptions::getIntersectionType()) - { - case Triangulation: - { - intersector = new CurveIntersectorP0P1(myMeshT, myMeshS, - InterpolationOptions::getPrecision(), - InterpolationOptions::getBoundingBoxAdjustmentAbs(), - InterpolationOptions::getMedianPlane(), - InterpolationOptions::getPrintLevel()); - break; - } - default: - throw INTERP_KERNEL::Exception("For P0P1 in 1D or 2D curve only Triangulation supported for the moment !"); - } - } - else if(method=="P1P0") - { - switch (InterpolationOptions::getIntersectionType()) - { - case Triangulation: - { - intersector = new CurveIntersectorP1P0(myMeshT, myMeshS, - InterpolationOptions::getPrecision(), - InterpolationOptions::getBoundingBoxAdjustmentAbs(), - InterpolationOptions::getMedianPlane(), - InterpolationOptions::getPrintLevel()); - break; - } - default: - throw INTERP_KERNEL::Exception("For P1P0 in 1D or 2D curve only Triangulation supported for the moment !"); - } - } - else if(method=="P1P1") - { - switch (InterpolationOptions::getIntersectionType()) - { - case Triangulation: - intersector = new CurveIntersectorP1P1 - (myMeshT, myMeshS, - InterpolationOptions::getPrecision(), - InterpolationOptions::getBoundingBoxAdjustmentAbs(), - InterpolationOptions::getMedianPlane(), - InterpolationOptions::getPrintLevel()); - break; - case PointLocator: - intersector = new CurveIntersectorP1P1PL - (myMeshT, myMeshS, - InterpolationOptions::getPrecision(), - InterpolationOptions::getBoundingBoxAdjustmentAbs(), - InterpolationOptions::getMedianPlane(), - InterpolationOptions::getPrintLevel()); - break; - default: - throw INTERP_KERNEL::Exception("For P1P1 in 1D or 2D curve only Triangulation and PointLocator supported !"); - } - } - else - throw INTERP_KERNEL::Exception("Invalid method specified ! Must be in : \"P0P0\" \"P0P1\" \"P1P0\" or \"P1P1\""); - /****************************************************************/ - /* Create a search tree based on the bounding boxes */ - /* Instanciate the intersector and initialise the result vector */ - /****************************************************************/ - - long start_filtering=clock(); - - std::vector bbox; - intersector->createBoundingBoxes(myMeshS,bbox); // create the bounding boxes - intersector->adjustBoundingBoxes(bbox, InterpolationOptions::getBoundingBoxAdjustmentAbs()); - BBTree my_tree(&bbox[0], 0, 0, nbMailleS);//creating the search structure - - long end_filtering = clock(); - - result.resize(intersector->getNumberOfRowsOfResMatrix());//on initialise. - - /****************************************************/ - /* Loop on the target cells - core of the algorithm */ - /****************************************************/ - long start_intersection = clock(); - const ConnType *connIndxT = myMeshT.getConnectivityIndexPtr(); - for(int iT=0; iT intersecting_elems; - double bb[2*SPACEDIM]; - intersector->getElemBB(bb,myMeshT,OTT::indFC(iT),nb_nodesT); - my_tree.getIntersectingElems(bb, intersecting_elems); - intersector->intersectCells(iT,intersecting_elems,result); - counter += intersecting_elems.size(); - } - int ret = intersector->getNumberOfColsOfResMatrix(); - delete intersector; - - if (InterpolationOptions::getPrintLevel() >= 1) - { - long end_intersection=clock(); - std::cout << "Filtering time= " << end_filtering-start_filtering << std::endl; - std::cout << "Intersection time= " << end_intersection-start_intersection << std::endl; - long global_end =clock(); - std::cout << "Number of computed intersections = " << counter << std::endl; - std::cout << "Global time= " << global_end - global_start << std::endl; - } - return ret; - } -} - -#endif diff --git a/src/INTERP_KERNEL/InterpolationOptions.cxx b/src/INTERP_KERNEL/InterpolationOptions.cxx deleted file mode 100644 index ae1c14e10..000000000 --- a/src/INTERP_KERNEL/InterpolationOptions.cxx +++ /dev/null @@ -1,333 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 -// 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 "InterpolationOptions.hxx" -#include "InterpKernelGeo2DPrecision.hxx" -#include "InterpKernelException.hxx" - -#include - -const double INTERP_KERNEL::InterpolationOptions::DFT_MEDIAN_PLANE=0.5; - -const double INTERP_KERNEL::InterpolationOptions::DFT_SURF3D_ADJ_EPS=1.e-4; - -const double INTERP_KERNEL::InterpolationOptions::DFT_MAX_DIST_3DSURF_INTERSECT=-1.; - -const double INTERP_KERNEL::InterpolationOptions::DFT_MIN_DOT_BTW_3DSURF_INTERSECT=-1.; - -const char INTERP_KERNEL::InterpolationOptions::PRECISION_STR[]="Precision"; - -const char INTERP_KERNEL::InterpolationOptions::ARC_DETECTION_PRECISION_STR[]="ArcDetectionPrecision"; - -const char INTERP_KERNEL::InterpolationOptions::MEDIANE_PLANE_STR[]="MedianPlane"; - -const char INTERP_KERNEL::InterpolationOptions::BOUNDING_BOX_ADJ_STR[]="BoundingBoxAdjustment"; - -const char INTERP_KERNEL::InterpolationOptions::BOUNDING_BOX_ADJ_ABS_STR[]="BoundingBoxAdjustmentAbs"; - -const char INTERP_KERNEL::InterpolationOptions::MAX_DISTANCE_3DSURF_INSECT_STR[]="MaxDistance3DSurfIntersect"; - -const char INTERP_KERNEL::InterpolationOptions::MIN_DOT_BTW_3DSURF_INSECT_STR[]="MinDotBetween3DSurfIntersect"; - -const char INTERP_KERNEL::InterpolationOptions::PRINT_LEV_STR[]="PrintLevel"; - -const char INTERP_KERNEL::InterpolationOptions::DO_ROTATE_STR[]="DoRotate"; - -const char INTERP_KERNEL::InterpolationOptions::ORIENTATION_STR[]="Orientation"; - -const char INTERP_KERNEL::InterpolationOptions::MEASURE_ABS_STR[]="MeasureAbs"; - -const char INTERP_KERNEL::InterpolationOptions::INTERSEC_TYPE_STR[]="IntersectionType"; - -const char INTERP_KERNEL::InterpolationOptions::SPLITTING_POLICY_STR[]="SplittingPolicy"; - -const char INTERP_KERNEL::InterpolationOptions::TRIANGULATION_INTERSECT2D_STR[]="Triangulation"; - -const char INTERP_KERNEL::InterpolationOptions::CONVEX_INTERSECT2D_STR[]="Convex"; - -const char INTERP_KERNEL::InterpolationOptions::GEOMETRIC_INTERSECT2D_STR[]="Geometric2D"; - -const char INTERP_KERNEL::InterpolationOptions::POINTLOCATOR_INTERSECT_STR[]="PointLocator"; - -const char INTERP_KERNEL::InterpolationOptions::BARYCENTRIC_INTERSECT_STR[]="Barycentric"; - -const char INTERP_KERNEL::InterpolationOptions::BARYCENTRICGEO2D_INTERSECT_STR[]="BarycentricGeo2D"; - -const char INTERP_KERNEL::InterpolationOptions::PLANAR_SPLIT_FACE_5_STR[]="PLANAR_FACE_5"; - -const char INTERP_KERNEL::InterpolationOptions::PLANAR_SPLIT_FACE_6_STR[]="PLANAR_FACE_6"; - -const char INTERP_KERNEL::InterpolationOptions::GENERAL_SPLIT_24_STR[]="GENERAL_24"; - -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; - _min_dot_btw_3Dsurf_intersect=DFT_MIN_DOT_BTW_3DSURF_INTERSECT; - _orientation=0; - _measure_abs=true; - _splitting_policy=PLANAR_FACE_5; -} - -double INTERP_KERNEL::InterpolationOptions::getArcDetectionPrecision() const -{ - return INTERP_KERNEL::QUADRATIC_PLANAR::_arc_detection_precision; -} - -void INTERP_KERNEL::InterpolationOptions::setArcDetectionPrecision(double p) -{ - INTERP_KERNEL::QUADRATIC_PLANAR::_arc_detection_precision=p; -} - -std::string INTERP_KERNEL::InterpolationOptions::getIntersectionTypeRepr() const -{ - if(_intersection_type==INTERP_KERNEL::Triangulation) - return std::string(TRIANGULATION_INTERSECT2D_STR); - else if(_intersection_type==INTERP_KERNEL::Convex) - return std::string(CONVEX_INTERSECT2D_STR); - else if(_intersection_type==INTERP_KERNEL::Geometric2D) - return std::string(GEOMETRIC_INTERSECT2D_STR); - else if(_intersection_type==INTERP_KERNEL::PointLocator) - return std::string(POINTLOCATOR_INTERSECT_STR); - else if(_intersection_type==INTERP_KERNEL::Barycentric) - return std::string(BARYCENTRIC_INTERSECT_STR); - else if(_intersection_type==INTERP_KERNEL::BarycentricGeo2D) - return std::string(BARYCENTRICGEO2D_INTERSECT_STR); - else - return std::string("UNKNOWN_INTERSECT_TYPE"); -} - -bool INTERP_KERNEL::InterpolationOptions::setOptionDouble(const std::string& key, double value) -{ - if(key==PRECISION_STR) - { - setPrecision(value); - return true; - } - if(key==ARC_DETECTION_PRECISION_STR) - { - setArcDetectionPrecision(value); - return true; - } - else if(key==MEDIANE_PLANE_STR) - { - setMedianPlane(value); - return true; - } - else if(key==BOUNDING_BOX_ADJ_STR) - { - setBoundingBoxAdjustment(value); - return true; - } - else if(key==BOUNDING_BOX_ADJ_ABS_STR) - { - setBoundingBoxAdjustmentAbs(value); - return true; - } - else if(key==MAX_DISTANCE_3DSURF_INSECT_STR) - { - setMaxDistance3DSurfIntersect(value); - return true; - } - else if(key==MIN_DOT_BTW_3DSURF_INSECT_STR) - { - setMinDotBtwPlane3DSurfIntersect(value); - return true; - } - else - return false; -} - -bool INTERP_KERNEL::InterpolationOptions::setOptionInt(const std::string& key, int value) -{ - if(key==PRINT_LEV_STR) - { - setPrintLevel(value); - return true; - } - else if(key==DO_ROTATE_STR) - { - setDoRotate(value != 0); - return true; - } - else if(key==ORIENTATION_STR) - { - setOrientation(value); - return true; - } - else if(key==MEASURE_ABS_STR) - { - bool valBool=(value!=0); - setMeasureAbsStatus(valBool); - return true; - } - else - return false; -} - -bool INTERP_KERNEL::InterpolationOptions::setOptionString(const std::string& key, const std::string& value) -{ - if(key==INTERSEC_TYPE_STR) - { - if(value==TRIANGULATION_INTERSECT2D_STR) - { - setIntersectionType(INTERP_KERNEL::Triangulation); - return true; - } - else if(value==CONVEX_INTERSECT2D_STR) - { - setIntersectionType(INTERP_KERNEL::Convex); - return true; - } - else if(value==GEOMETRIC_INTERSECT2D_STR) - { - setIntersectionType(INTERP_KERNEL::Geometric2D); - return true; - } - else if(value==POINTLOCATOR_INTERSECT_STR) - { - setIntersectionType(INTERP_KERNEL::PointLocator); - return true; - } - else if(value==BARYCENTRIC_INTERSECT_STR) - { - setIntersectionType(INTERP_KERNEL::Barycentric); - return true; - } - else if(value==BARYCENTRICGEO2D_INTERSECT_STR) - { - setIntersectionType(INTERP_KERNEL::BarycentricGeo2D); - return true; - } - } - else if(key==SPLITTING_POLICY_STR) - { - if(value==PLANAR_SPLIT_FACE_5_STR) - { - setSplittingPolicy(INTERP_KERNEL::PLANAR_FACE_5); - return true; - } - else if(value==PLANAR_SPLIT_FACE_6_STR) - { - setSplittingPolicy(INTERP_KERNEL::PLANAR_FACE_6); - return true; - } - else if(value==GENERAL_SPLIT_24_STR) - { - setSplittingPolicy(INTERP_KERNEL::GENERAL_24); - return true; - } - else if(value==GENERAL_SPLIT_48_STR) - { - setSplittingPolicy(INTERP_KERNEL::GENERAL_48); - return true; - } - else - return false; - } - return false; -} - -std::string INTERP_KERNEL::InterpolationOptions::getSplittingPolicyRepr() const -{ - if(_splitting_policy==INTERP_KERNEL::PLANAR_FACE_5) - return std::string(PLANAR_SPLIT_FACE_5_STR); - else if(_splitting_policy==INTERP_KERNEL::PLANAR_FACE_6) - return std::string(PLANAR_SPLIT_FACE_6_STR); - else if(_splitting_policy==INTERP_KERNEL::GENERAL_24) - return std::string(GENERAL_SPLIT_24_STR); - else if(_splitting_policy==INTERP_KERNEL::GENERAL_48) - return std::string(GENERAL_SPLIT_48_STR); - else - return std::string("UNKNOWN_SPLITTING_POLICY"); -} - -std::string INTERP_KERNEL::InterpolationOptions::filterInterpolationMethod(const std::string& meth) const -{ - return std::string(meth); -} - -bool INTERP_KERNEL::InterpolationOptions::setInterpolationOptions(long print_level, - std::string intersection_type, - double precision, - double median_plane, - bool do_rotate, - double bounding_box_adjustment, - double bounding_box_adjustment_abs, - double max_distance_for_3Dsurf_intersect, - long orientation, - bool measure_abs, - std::string splitting_policy) -{ - _print_level=print_level; - _precision=precision; - _median_plane=median_plane; - _do_rotate=do_rotate; - _bounding_box_adjustment=bounding_box_adjustment; - _bounding_box_adjustment_abs=bounding_box_adjustment_abs; - _max_distance_for_3Dsurf_intersect=max_distance_for_3Dsurf_intersect; - _orientation=orientation; - _measure_abs=measure_abs; - return(setOptionString(INTERSEC_TYPE_STR,intersection_type) && setOptionString(SPLITTING_POLICY_STR,splitting_policy)); -} - -std::string INTERP_KERNEL::InterpolationOptions::printOptions() const -{ - std::ostringstream oss; oss.precision(15); oss << "Interpolation Options ******" << std::endl; - oss << "Print level : " << _print_level << std::endl; - oss << "Intersection type : " << getIntersectionTypeRepr() << std::endl; - oss << "Precision : " << _precision << std::endl; - oss << "Arc Detection Precision : " << getArcDetectionPrecision() << std::endl; - oss << "Median plane : " << _median_plane << std::endl; - oss << "Do Rotate status : " << std::boolalpha << _do_rotate << std::endl; - oss << "Bounding box adj : " << _bounding_box_adjustment << std::endl; - oss << "Bounding box adj abs : " << _bounding_box_adjustment_abs << std::endl; - oss << "Max distance for 3DSurf intersect : " << _max_distance_for_3Dsurf_intersect << std::endl; - oss << "Min dot between plane for 3DSurf intersect : " << _min_dot_btw_3Dsurf_intersect << std::endl; - oss << "Orientation : " << _orientation << std::endl; - oss << "Measure abs : " << _measure_abs << std::endl; - oss << "Splitting policy : " << getSplittingPolicyRepr() << std::endl; - oss << "****************************" << std::endl; - return oss.str(); -} - -void INTERP_KERNEL::InterpolationOptions::CheckAndSplitInterpolationMethod(const std::string& method, std::string& srcMeth, std::string& trgMeth) -{ - const int NB_OF_METH_MANAGED=4; - const char *METH_MANAGED[NB_OF_METH_MANAGED]={"P0P0","P0P1","P1P0","P1P1"}; - bool found=false; - for(int i=0;i - -namespace INTERP_KERNEL -{ - typedef enum { Triangulation, Convex, Geometric2D, PointLocator, Barycentric, BarycentricGeo2D } IntersectionType; - - /*! - * \class InterpolationOptions - * Class defining the options for all interpolation algorithms. - * - * List of options, possible values and default values can be found on this page: - * \ref InterpKerIntersectors - */ - class INTERPKERNEL_EXPORT InterpolationOptions - { - private: - int _print_level ; - IntersectionType _intersection_type; - double _precision; - double _median_plane ; - bool _do_rotate ; - //! this measure is relative to the caracteristic dimension - double _bounding_box_adjustment ; - //! this measure is absolute \b not relative to the cell size - double _bounding_box_adjustment_abs ; - double _max_distance_for_3Dsurf_intersect; - double _min_dot_btw_3Dsurf_intersect; - int _orientation ; - bool _measure_abs; - SplittingPolicy _splitting_policy ; - public: - InterpolationOptions() { init(); } - int getPrintLevel() const { return _print_level; } - void setPrintLevel(int pl) { _print_level=pl; } - - IntersectionType getIntersectionType() const { return _intersection_type; } - void setIntersectionType(IntersectionType it) { _intersection_type=it; } - std::string getIntersectionTypeRepr() const; - - double getPrecision() const { return _precision; } - void setPrecision(double p) { _precision=p; } - - double getArcDetectionPrecision() const; - void setArcDetectionPrecision(double p); - - double getMedianPlane() const { return _median_plane; } - void setMedianPlane(double mp) { _median_plane=mp; } - - bool getDoRotate() const { return _do_rotate; } - void setDoRotate( bool dr) { _do_rotate = dr; } - - double getBoundingBoxAdjustment() const { return _bounding_box_adjustment; } - void setBoundingBoxAdjustment(double bba) { _bounding_box_adjustment=bba; } - - double getBoundingBoxAdjustmentAbs() const { return _bounding_box_adjustment_abs; } - void setBoundingBoxAdjustmentAbs(double bba) { _bounding_box_adjustment_abs=bba; } - - double getMaxDistance3DSurfIntersect() const { return _max_distance_for_3Dsurf_intersect; } - void setMaxDistance3DSurfIntersect(double bba) { _max_distance_for_3Dsurf_intersect=bba; } - - double getMinDotBtwPlane3DSurfIntersect() const { return _min_dot_btw_3Dsurf_intersect; } - void setMinDotBtwPlane3DSurfIntersect(double v) { _min_dot_btw_3Dsurf_intersect=v; } - - int getOrientation() const { return _orientation; } - void setOrientation(int o) { _orientation=o; } - - bool getMeasureAbsStatus() const { return _measure_abs; } - void setMeasureAbsStatus(bool newStatus) { _measure_abs=newStatus; } - - SplittingPolicy getSplittingPolicy() const { return _splitting_policy; } - void setSplittingPolicy(SplittingPolicy sp) { _splitting_policy=sp; } - std::string getSplittingPolicyRepr() const; - - std::string filterInterpolationMethod(const std::string& meth) const; - - void init(); - - bool setInterpolationOptions(long print_level, - std::string intersection_type, - double precision, - double median_plane, - bool do_rotate, - double bounding_box_adjustment, - double bounding_box_adjustment_abs, - double max_distance_for_3Dsurf_intersect, - long orientation, - bool measure_abs, - std::string splitting_policy); - void copyOptions(const InterpolationOptions & other) { *this = other; } - bool setOptionDouble(const std::string& key, double value); - bool setOptionInt(const std::string& key, int value); - bool setOptionString(const std::string& key, const std::string& value); - std::string printOptions() const; - public: - static void CheckAndSplitInterpolationMethod(const std::string& method, std::string& srcMeth, std::string& trgMeth); - private: - static const double DFT_MEDIAN_PLANE; - static const double DFT_SURF3D_ADJ_EPS; - static const double DFT_MAX_DIST_3DSURF_INTERSECT; - static const double DFT_MIN_DOT_BTW_3DSURF_INTERSECT; - public: - static const char PRECISION_STR[]; - static const char ARC_DETECTION_PRECISION_STR[]; - static const char MEDIANE_PLANE_STR[]; - static const char BOUNDING_BOX_ADJ_STR[]; - static const char BOUNDING_BOX_ADJ_ABS_STR[]; - static const char MAX_DISTANCE_3DSURF_INSECT_STR[]; - static const char MIN_DOT_BTW_3DSURF_INSECT_STR[]; - static const char PRINT_LEV_STR[]; - static const char DO_ROTATE_STR[]; - static const char ORIENTATION_STR[]; - static const char MEASURE_ABS_STR[]; - static const char INTERSEC_TYPE_STR[]; - static const char SPLITTING_POLICY_STR[]; - static const char TRIANGULATION_INTERSECT2D_STR[]; - static const char CONVEX_INTERSECT2D_STR[]; - static const char GEOMETRIC_INTERSECT2D_STR[]; - static const char POINTLOCATOR_INTERSECT_STR[]; - static const char BARYCENTRIC_INTERSECT_STR[]; - static const char BARYCENTRICGEO2D_INTERSECT_STR[]; - static const char PLANAR_SPLIT_FACE_5_STR[]; - static const char PLANAR_SPLIT_FACE_6_STR[]; - static const char GENERAL_SPLIT_24_STR[]; - static const char GENERAL_SPLIT_48_STR[]; - }; - -} -#endif diff --git a/src/INTERP_KERNEL/InterpolationPlanar.hxx b/src/INTERP_KERNEL/InterpolationPlanar.hxx deleted file mode 100755 index 1505c46e4..000000000 --- a/src/INTERP_KERNEL/InterpolationPlanar.hxx +++ /dev/null @@ -1,59 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 -// 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 __INTERPOLATIONPLANAR_HXX__ -#define __INTERPOLATIONPLANAR_HXX__ - -#include "Interpolation.hxx" -#include "PlanarIntersector.hxx" -#include "NormalizedUnstructuredMesh.hxx" -#include "InterpolationOptions.hxx" - -namespace INTERP_KERNEL -{ - template - class InterpolationPlanar : public Interpolation< InterpolationPlanar > - { - private: - double _dim_caracteristic; - public: - InterpolationPlanar(); - InterpolationPlanar(const InterpolationOptions & io); - - // geometric precision, debug print level, coice of the median plane, intersection etc ... - void setOptions(double precision, int printLevel, - IntersectionType intersectionType, int orientation=0); - - // Main function to interpolate triangular and quadratic meshes - template - int interpolateMeshes(const MyMeshType& meshS, const MyMeshType& meshT, MatrixType& result, const std::string& method); - public: - bool doRotate() const { return asLeafInterpPlanar().doRotate(); } - double medianPlane() const { return asLeafInterpPlanar().medianPlane(); } - template - void performAdjustmentOfBB(PlanarIntersector* intersector, std::vector& bbox) const - { return asLeafInterpPlanar().performAdjustmentOfBB(intersector,bbox); } - protected: - RealPlanar& asLeafInterpPlanar() { return static_cast(*this); } - const RealPlanar& asLeafInterpPlanar() const { return static_cast< const RealPlanar& >(*this); } - }; -} - -#endif diff --git a/src/INTERP_KERNEL/InterpolationPlanar.txx b/src/INTERP_KERNEL/InterpolationPlanar.txx deleted file mode 100644 index d7a1fea20..000000000 --- a/src/INTERP_KERNEL/InterpolationPlanar.txx +++ /dev/null @@ -1,417 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 -// 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 __INTERPOLATIONPLANAR_TXX__ -#define __INTERPOLATIONPLANAR_TXX__ - -#include "InterpolationPlanar.hxx" -#include "Interpolation.txx" -#include "InterpolationOptions.hxx" -#include "PlanarIntersector.hxx" -#include "PlanarIntersector.txx" -#include "TriangulationIntersector.hxx" -#include "TriangulationIntersector.txx" -#include "ConvexIntersector.hxx" -#include "ConvexIntersector.txx" -#include "Geometric2DIntersector.hxx" -#include "Geometric2DIntersector.txx" -#include "PointLocator2DIntersector.hxx" -#include "PointLocator2DIntersector.txx" -#include "PlanarIntersectorP0P1PL.hxx" -#include "PlanarIntersectorP0P1PL.txx" -#include "PlanarIntersectorP1P0PL.hxx" -#include "PlanarIntersectorP1P0PL.txx" -#include "PlanarIntersectorP1P1PL.hxx" -#include "PlanarIntersectorP1P1PL.txx" -#include "VectorUtils.hxx" -#include "BBTree.txx" - -#include -#include - -namespace INTERP_KERNEL -{ - /** - * \defgroup interpolationPlanar InterpolationPlanar - * - * \class InterpolationPlanar - * \brief Class used to compute the coefficients of the interpolation matrix between - * two local meshes in two dimensions. Meshes can contain mixed triangular and quadrangular elements. - */ - template - InterpolationPlanar::InterpolationPlanar():_dim_caracteristic(1) - - { - } - - template - InterpolationPlanar::InterpolationPlanar(const InterpolationOptions& io):Interpolation< InterpolationPlanar >(io),_dim_caracteristic(1) - - { - } - - /** - * \brief Function used to set the options for the intersection calculation - * \details The following options can be modified: - * -# Intersection_type: the type of algorithm to be used in the computation of the cell-cell intersections. - * - Values: Triangle, Convex. - * - Default: Triangle. - * -# Precision: Level of precision of the computations is precision times the characteristic size of the mesh. - * - Values: positive real number. - * - Default: 1.0E-12. - * -# PrintLevel: Level of verboseness during the computations. - * - Values: interger between 0 and 3. - * - Default: 0. - */ - template - void InterpolationPlanar::setOptions(double precision, int printLevel, IntersectionType intersectionType, int orientation) - { - InterpolationOptions::setPrecision(precision); - InterpolationOptions::setPrintLevel(printLevel); - InterpolationOptions::setIntersectionType(intersectionType); - InterpolationOptions::setOrientation(orientation); - } - - - /** \brief Main function to interpolate triangular or quadrangular meshes. - \details The algorithm proceeds in two steps: first a filtering process reduces the number of pairs of elements for which the - * calculation must be carried out by eliminating pairs that do not intersect based on their bounding boxes. Then, the - * volume of intersection is calculated by an object of type IntersectorPlanar for the remaining pairs, and entered into the - * intersection matrix. - * - * The matrix is partially sparse : it is a vector of maps of integer - double pairs. - * The length of the vector is equal to the number of target elements - for each target element there is a map, regardless - * of whether the element intersects any source elements or not. But in the maps there are only entries for those source elements - * which have a non-zero intersection volume with the target element. The vector has indices running from - * 0 to (#target elements - 1), meaning that the map for target element i is stored at index i - 1. In the maps, however, - * the indexing is more natural : the intersection volume of the target element i with source element j is found at matrix[i-1][j]. - * - - * @param myMeshS Planar source mesh - * @Param myMeshT Planar target mesh - * @return vector containing for each element i of the source mesh, a map giving for each element j - * of the target mesh which i intersects, the area of the intersection - * - */ - template - template - int InterpolationPlanar::interpolateMeshes(const MyMeshType& myMeshS, const MyMeshType& myMeshT, MatrixType& result, const std::string& method) - { - static const int SPACEDIM=MyMeshType::MY_SPACEDIM; - typedef typename MyMeshType::MyConnType ConnType; - static const NumberingPolicy numPol=MyMeshType::My_numPol; - - long global_start =clock(); - int counter=0; - /***********************************************************/ - /* Check both meshes are made of triangles and quadrangles */ - /***********************************************************/ - - long nbMailleS=myMeshS.getNumberOfElements(); - long nbMailleT=myMeshT.getNumberOfElements(); - - /**************************************************/ - /* Search the characteristic size of the meshes */ - /**************************************************/ - - double BoxS[2*SPACEDIM]; myMeshS.getBoundingBox(BoxS); - double BoxT[2*SPACEDIM]; myMeshT.getBoundingBox(BoxT); - double diagonalS,dimCaracteristicS=std::numeric_limits::max(); - if(nbMailleS!=0) - { - diagonalS=getDistanceBtw2Pts(BoxS+SPACEDIM,BoxS); - dimCaracteristicS=diagonalS/nbMailleS; - } - double diagonalT,dimCaracteristicT=std::numeric_limits::max(); - if(nbMailleT!=0) - { - diagonalT=getDistanceBtw2Pts(BoxT+SPACEDIM,BoxT); - dimCaracteristicT=diagonalT/nbMailleT; - } - - _dim_caracteristic=std::min(dimCaracteristicS, dimCaracteristicT); - if (InterpolationOptions::getPrintLevel()>=1) - { - std::cout << " - Characteristic size of the source mesh : " << dimCaracteristicS << std::endl; - std::cout << " - Characteristic size of the target mesh: " << dimCaracteristicT << std::endl; - std::cout << "InterpolationPlanar::computation of the intersections" << std::endl; - } - - PlanarIntersector* intersector=0; - std::string meth = InterpolationOptions::filterInterpolationMethod(method); - if(meth=="P0P0") - { - switch (InterpolationOptions::getIntersectionType()) - { - case Triangulation: - intersector=new TriangulationIntersector(myMeshT,myMeshS,_dim_caracteristic, - InterpolationOptions::getPrecision(), - InterpolationOptions::getMaxDistance3DSurfIntersect(), - InterpolationOptions::getMinDotBtwPlane3DSurfIntersect(), - InterpolationOptions::getMedianPlane(), - InterpolationOptions::getOrientation(), - InterpolationOptions::getPrintLevel()); - break; - case Convex: - intersector=new ConvexIntersector(myMeshT,myMeshS,_dim_caracteristic, - InterpolationOptions::getPrecision(), - InterpolationOptions::getMaxDistance3DSurfIntersect(), - InterpolationOptions::getMinDotBtwPlane3DSurfIntersect(), - InterpolationOptions::getMedianPlane(), - InterpolationOptions::getDoRotate(), - InterpolationOptions::getOrientation(), - InterpolationOptions::getPrintLevel()); - break; - case Geometric2D: - intersector=new Geometric2DIntersector(myMeshT, myMeshS, _dim_caracteristic, - InterpolationOptions::getMaxDistance3DSurfIntersect(), - InterpolationOptions::getMinDotBtwPlane3DSurfIntersect(), - InterpolationOptions::getMedianPlane(), - InterpolationOptions::getPrecision(), - InterpolationOptions::getOrientation()); - break; - case PointLocator: - intersector=new PointLocator2DIntersector(myMeshT, myMeshS, _dim_caracteristic, - InterpolationOptions::getMaxDistance3DSurfIntersect(), - InterpolationOptions::getMinDotBtwPlane3DSurfIntersect(), - InterpolationOptions::getMedianPlane(), - InterpolationOptions::getPrecision(), - InterpolationOptions::getOrientation()); - break; - default: - throw INTERP_KERNEL::Exception("For P0P0 planar interpolation possibities are : Triangulation, Convex, Geometric2D, PointLocator !"); - } - } - else if(meth=="P0P1") - { - switch (InterpolationOptions::getIntersectionType()) - { - case Triangulation: - intersector=new TriangulationIntersector(myMeshT,myMeshS,_dim_caracteristic, - InterpolationOptions::getPrecision(), - InterpolationOptions::getMaxDistance3DSurfIntersect(), - InterpolationOptions::getMinDotBtwPlane3DSurfIntersect(), - InterpolationOptions::getMedianPlane(), - InterpolationOptions::getOrientation(), - InterpolationOptions::getPrintLevel()); - break; - case Convex: - intersector=new ConvexIntersector(myMeshT,myMeshS,_dim_caracteristic, - InterpolationOptions::getPrecision(), - InterpolationOptions::getMaxDistance3DSurfIntersect(), - InterpolationOptions::getMinDotBtwPlane3DSurfIntersect(), - InterpolationOptions::getMedianPlane(), - InterpolationOptions::getDoRotate(), - InterpolationOptions::getOrientation(), - InterpolationOptions::getPrintLevel()); - break; - case Geometric2D: - intersector=new Geometric2DIntersector(myMeshT, myMeshS, _dim_caracteristic, - InterpolationOptions::getMaxDistance3DSurfIntersect(), - InterpolationOptions::getMinDotBtwPlane3DSurfIntersect(), - InterpolationOptions::getMedianPlane(), - InterpolationOptions::getPrecision(), - InterpolationOptions::getOrientation()); - break; - case PointLocator: - intersector=new PlanarIntersectorP0P1PL(myMeshT, myMeshS, _dim_caracteristic, - InterpolationOptions::getMaxDistance3DSurfIntersect(), - InterpolationOptions::getMinDotBtwPlane3DSurfIntersect(), - InterpolationOptions::getMedianPlane(), - InterpolationOptions::getPrecision(), - InterpolationOptions::getOrientation()); - break; - case Barycentric: - intersector=new TriangulationIntersector(myMeshT,myMeshS,_dim_caracteristic, - InterpolationOptions::getPrecision(), - InterpolationOptions::getMaxDistance3DSurfIntersect(), - InterpolationOptions::getMinDotBtwPlane3DSurfIntersect(), - InterpolationOptions::getMedianPlane(), - InterpolationOptions::getOrientation(), - InterpolationOptions::getPrintLevel()); - break; - case BarycentricGeo2D: - intersector=new Geometric2DIntersector(myMeshT, myMeshS, _dim_caracteristic, - InterpolationOptions::getMaxDistance3DSurfIntersect(), - InterpolationOptions::getMinDotBtwPlane3DSurfIntersect(), - InterpolationOptions::getMedianPlane(), - InterpolationOptions::getPrecision(), - InterpolationOptions::getOrientation()); - break; - default: - throw INTERP_KERNEL::Exception("For P0P1 planar interpolation possibities are : Triangulation, Convex, Geometric2D, PointLocator, Barycentric, BarycentricGeo2D !"); - } - } - else if(meth=="P1P0") - { - switch (InterpolationOptions::getIntersectionType()) - { - case Triangulation: - intersector=new TriangulationIntersector(myMeshT,myMeshS,_dim_caracteristic, - InterpolationOptions::getPrecision(), - InterpolationOptions::getMaxDistance3DSurfIntersect(), - InterpolationOptions::getMinDotBtwPlane3DSurfIntersect(), - InterpolationOptions::getMedianPlane(), - InterpolationOptions::getOrientation(), - InterpolationOptions::getPrintLevel()); - break; - case Convex: - intersector=new ConvexIntersector(myMeshT,myMeshS,_dim_caracteristic, - InterpolationOptions::getPrecision(), - InterpolationOptions::getMaxDistance3DSurfIntersect(), - InterpolationOptions::getMinDotBtwPlane3DSurfIntersect(), - InterpolationOptions::getMedianPlane(), - InterpolationOptions::getDoRotate(), - InterpolationOptions::getOrientation(), - InterpolationOptions::getPrintLevel()); - break; - case Geometric2D: - intersector=new Geometric2DIntersector(myMeshT, myMeshS, _dim_caracteristic, - InterpolationOptions::getMaxDistance3DSurfIntersect(), - InterpolationOptions::getMinDotBtwPlane3DSurfIntersect(), - InterpolationOptions::getMedianPlane(), - InterpolationOptions::getPrecision(), - InterpolationOptions::getOrientation()); - break; - case PointLocator: - intersector=new PlanarIntersectorP1P0PL(myMeshT, myMeshS, _dim_caracteristic, - InterpolationOptions::getMaxDistance3DSurfIntersect(), - InterpolationOptions::getMinDotBtwPlane3DSurfIntersect(), - InterpolationOptions::getMedianPlane(), - InterpolationOptions::getPrecision(), - InterpolationOptions::getOrientation()); - break; - case Barycentric: - intersector=new TriangulationIntersector(myMeshT,myMeshS,_dim_caracteristic, - InterpolationOptions::getPrecision(), - InterpolationOptions::getMaxDistance3DSurfIntersect(), - InterpolationOptions::getMinDotBtwPlane3DSurfIntersect(), - InterpolationOptions::getMedianPlane(), - InterpolationOptions::getOrientation(), - InterpolationOptions::getPrintLevel()); - break; - case BarycentricGeo2D: - intersector=new Geometric2DIntersector(myMeshT, myMeshS, _dim_caracteristic, - InterpolationOptions::getMaxDistance3DSurfIntersect(), - InterpolationOptions::getMinDotBtwPlane3DSurfIntersect(), - InterpolationOptions::getMedianPlane(), - InterpolationOptions::getPrecision(), - InterpolationOptions::getOrientation()); - break; - } - } - else if(meth=="P1P1") - { - switch (InterpolationOptions::getIntersectionType()) - { - case Triangulation: - intersector=new TriangulationIntersector(myMeshT,myMeshS,_dim_caracteristic, - InterpolationOptions::getPrecision(), - InterpolationOptions::getMaxDistance3DSurfIntersect(), - InterpolationOptions::getMinDotBtwPlane3DSurfIntersect(), - InterpolationOptions::getMedianPlane(), - InterpolationOptions::getOrientation(), - InterpolationOptions::getPrintLevel()); - break; - case Convex: - intersector=new ConvexIntersector(myMeshT,myMeshS,_dim_caracteristic, - InterpolationOptions::getPrecision(), - InterpolationOptions::getMaxDistance3DSurfIntersect(), - InterpolationOptions::getMinDotBtwPlane3DSurfIntersect(), - InterpolationOptions::getMedianPlane(), - InterpolationOptions::getDoRotate(), - InterpolationOptions::getOrientation(), - InterpolationOptions::getPrintLevel()); - break; - case Geometric2D: - intersector=new Geometric2DIntersector(myMeshT, myMeshS, _dim_caracteristic, - InterpolationOptions::getMaxDistance3DSurfIntersect(), - InterpolationOptions::getMinDotBtwPlane3DSurfIntersect(), - InterpolationOptions::getMedianPlane(), - InterpolationOptions::getPrecision(), - InterpolationOptions::getOrientation()); - break; - case PointLocator: - intersector=new PlanarIntersectorP1P1PL(myMeshT, myMeshS, _dim_caracteristic, - InterpolationOptions::getMaxDistance3DSurfIntersect(), - InterpolationOptions::getMinDotBtwPlane3DSurfIntersect(), - InterpolationOptions::getMedianPlane(), - InterpolationOptions::getPrecision(), - InterpolationOptions::getOrientation()); - break; - default: - throw INTERP_KERNEL::Exception("For P1P1 planar interpolation possibities are : Triangulation, Convex, Geometric2D, PointLocator !"); - } - } - else - throw INTERP_KERNEL::Exception("Invalid method specified or intersection type ! Must be in : \"P0P0\" \"P0P1\" \"P1P0\" or \"P1P1\""); - /****************************************************************/ - /* Create a search tree based on the bounding boxes */ - /* Instanciate the intersector and initialise the result vector */ - /****************************************************************/ - - long start_filtering=clock(); - - std::vector bbox; - intersector->createBoundingBoxes(myMeshS,bbox); // create the bounding boxes - performAdjustmentOfBB(intersector,bbox); - const double *bboxPtr=0; - if(nbMailleS>0) - bboxPtr=&bbox[0]; - BBTree my_tree(bboxPtr, 0, 0,nbMailleS);//creating the search structure - - long end_filtering=clock(); - - result.resize(intersector->getNumberOfRowsOfResMatrix());//on initialise. - - /****************************************************/ - /* Loop on the target cells - core of the algorithm */ - /****************************************************/ - long start_intersection=clock(); - long nbelem_type=myMeshT.getNumberOfElements(); - const ConnType *connIndxT=myMeshT.getConnectivityIndexPtr(); - for(int iT=0; iT intersecting_elems; - double bb[2*SPACEDIM]; - intersector->getElemBB(bb,myMeshT,OTT::indFC(iT),nb_nodesT); - my_tree.getIntersectingElems(bb, intersecting_elems); - intersector->intersectCells(iT,intersecting_elems,result); - counter+=intersecting_elems.size(); - intersecting_elems.clear(); - } - int ret=intersector->getNumberOfColsOfResMatrix(); - delete intersector; - - if (InterpolationOptions::getPrintLevel() >=1) - { - long end_intersection=clock(); - std::cout << "Filtering time= " << end_filtering-start_filtering << std::endl; - std::cout << "Intersection time= " << end_intersection-start_intersection << std::endl; - long global_end =clock(); - std::cout << "Number of computed intersections = " << counter << std::endl; - std::cout << "Global time= " << global_end - global_start << std::endl; - } - return ret; - } -} - -#endif diff --git a/src/INTERP_KERNEL/InterpolationUtils.hxx b/src/INTERP_KERNEL/InterpolationUtils.hxx deleted file mode 100644 index dd3ffef94..000000000 --- a/src/INTERP_KERNEL/InterpolationUtils.hxx +++ /dev/null @@ -1,1110 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 -// 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 __INTERPOLATIONUTILS_HXX__ -#define __INTERPOLATIONUTILS_HXX__ - -#include "INTERPKERNELDefines.hxx" -#include "InterpKernelException.hxx" - -#include "NormalizedUnstructuredMesh.hxx" - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -namespace INTERP_KERNEL -{ - template - class OTT//OffsetToolTrait - { - }; - - template - class OTT - { - public: - static ConnType indFC(ConnType i) { return i; } - static ConnType ind2C(ConnType i) { return i; } - static ConnType conn2C(ConnType i) { return i; } - static ConnType coo2C(ConnType i) { return i; } - }; - - template - class OTT - { - public: - static ConnType indFC(ConnType i) { return i+1; } - static ConnType ind2C(ConnType i) { return i-1; } - static ConnType conn2C(ConnType i) { return i-1; } - static ConnType coo2C(ConnType i) { return i-1; } - }; - - /*_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ */ - /* calcul la surface d'un triangle */ - /*_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ */ - - inline double Surf_Tri(const double* P_1,const double* P_2,const double* P_3) - { - double A=(P_3[1]-P_1[1])*(P_2[0]-P_1[0])-(P_2[1]-P_1[1])*(P_3[0]-P_1[0]); - double Surface = 0.5*fabs(A); - return Surface; - } - - /*_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ */ - /* fonction qui calcul le determinant */ - /* de deux vecteur(cf doc CGAL). */ - /*_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _*/ - - //fonction qui calcul le determinant des vecteurs: P3P1 et P3P2 - //(cf doc CGAL). - - inline double mon_determinant(const double* P_1, - const double* P_2, - const double* P_3) - { - double mon_det=(P_1[0]-P_3[0])*(P_2[1]-P_3[1])-(P_2[0]-P_3[0])*(P_1[1]-P_3[1]); - return mon_det; - } - - /*_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _*/ - //calcul la norme du vecteur P1P2 - - inline double norme_vecteur(const double* P_1,const double* P_2) - { - double X=P_1[0]-P_2[0]; - double Y=P_1[1]-P_2[1]; - double norme=sqrt(X*X+Y*Y); - return norme; - } - - /*_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ */ - /* calcul le cos et le sin de l'angle P1P2,P1P3 */ - /*_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ */ - - inline std::vector calcul_cos_et_sin(const double* P_1, - const double* P_2, - const double* P_3) - { - - std::vector Vect; - double P1_P2=norme_vecteur(P_1,P_2); - double P2_P3=norme_vecteur(P_2,P_3); - double P3_P1=norme_vecteur(P_3,P_1); - - double N=P1_P2*P1_P2+P3_P1*P3_P1-P2_P3*P2_P3; - double D=2.0*P1_P2*P3_P1; - double COS=N/D; - if (COS>1.0) COS=1.0; - if (COS<-1.0) COS=-1.0; - Vect.push_back(COS); - double V=mon_determinant(P_2,P_3,P_1); - double D_1=P1_P2*P3_P1; - double SIN=V/D_1; - if (SIN>1.0) SIN=1.0; - if (SIN<-1.0) SIN=-1.0; - Vect.push_back(SIN); - - return Vect; - - } - - /*! - * This method builds a quadrangle built with the first point of 'triIn' the barycenter of two edges starting or ending with - * the first point of 'triIn' and the barycenter of 'triIn'. - * - * @param triIn is a 6 doubles array in full interlace mode, that represents a triangle. - * @param quadOut is a 8 doubles array filled after the following call. - */ - template - inline void fillDualCellOfTri(const double *triIn, double *quadOut) - { - //1st point - std::copy(triIn,triIn+SPACEDIM,quadOut); - double tmp[SPACEDIM]; - std::transform(triIn,triIn+SPACEDIM,triIn+SPACEDIM,tmp,std::plus()); - //2nd point - std::transform(tmp,tmp+SPACEDIM,quadOut+SPACEDIM,std::bind2nd(std::multiplies(),0.5)); - std::transform(tmp,tmp+SPACEDIM,triIn+2*SPACEDIM,tmp,std::plus()); - //3rd point - std::transform(tmp,tmp+SPACEDIM,quadOut+2*SPACEDIM,std::bind2nd(std::multiplies(),1/3.)); - //4th point - std::transform(triIn,triIn+SPACEDIM,triIn+2*SPACEDIM,tmp,std::plus()); - std::transform(tmp,tmp+SPACEDIM,quadOut+3*SPACEDIM,std::bind2nd(std::multiplies(),0.5)); - } - - /*! - * This method builds a potentially non-convex polygon cell built with the first point of 'triIn' the barycenter of two edges starting or ending with - * the first point of 'triIn' and the barycenter of 'triIn'. - * - * @param triIn is a 6 doubles array in full interlace mode, that represents a triangle. - * @param quadOut is a 8 doubles array filled after the following call. - */ - template - inline void fillDualCellOfPolyg(const double *polygIn, int nPtsPolygonIn, double *polygOut) - { - //1st point - std::copy(polygIn,polygIn+SPACEDIM,polygOut); - std::transform(polygIn,polygIn+SPACEDIM,polygIn+SPACEDIM,polygOut+SPACEDIM,std::plus()); - //2nd point - std::transform(polygOut+SPACEDIM,polygOut+2*SPACEDIM,polygOut+SPACEDIM,std::bind2nd(std::multiplies(),0.5)); - double tmp[SPACEDIM]; - // - for(int i=0;i()); - std::transform(tmp,tmp+SPACEDIM,polygOut+(2*i+3)*SPACEDIM,std::bind2nd(std::multiplies(),0.5)); - std::transform(polygIn+(i+1)*SPACEDIM,polygIn+(i+2)*SPACEDIM,tmp,tmp,std::plus()); - std::transform(tmp,tmp+SPACEDIM,polygOut+(2*i+2)*SPACEDIM,std::bind2nd(std::multiplies(),1./3.)); - } - } - - /*_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ */ - /* calcul les coordonnees du barycentre d'un polygone */ - /* le vecteur en entree est constitue des coordonnees */ - /* des sommets du polygone */ - /*_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ */ - - inline std::vector bary_poly(const std::vector& V) - { - std::vector Bary; - long taille=V.size(); - double x=0; - double y=0; - - for(long i=0;i - bool solveSystemOfEquations(double M[nbRow][nbRow+1], double* sol) - { - const int nbCol=nbRow+1; - - // make upper triangular matrix (forward elimination) - - int iR[nbRow];// = { 0, 1, 2 }; - for ( int i = 0; i < (int) nbRow; ++i ) - iR[i] = i; - for ( int i = 0; i < (int)(nbRow-1); ++i ) // nullify nbRow-1 rows - { - // swap rows to have max value of i-th column in i-th row - double max = std::fabs( M[ iR[i] ][i] ); - for ( int r = i+1; r < (int)nbRow; ++r ) - { - double m = std::fabs( M[ iR[r] ][i] ); - if ( m > max ) - { - max = m; - std::swap( iR[r], iR[i] ); - } - } - if ( max < std::numeric_limits::min() ) - { - //sol[0]=1; sol[1]=sol[2]=sol[3]=0; - return false; // no solution - } - // make 0 below M[i][i] (actually we do not modify i-th column) - double* tUpRow = M[ iR[i] ]; - for ( int r = i+1; r < (int)nbRow; ++r ) - { - double* mRow = M[ iR[r] ]; - double coef = mRow[ i ] / tUpRow[ i ]; - for ( int c = i+1; c < nbCol; ++c ) - mRow[ c ] -= tUpRow[ c ] * coef; - } - } - double* mRow = M[ iR[nbRow-1] ]; - if ( std::fabs( mRow[ nbRow-1 ] ) < std::numeric_limits::min() ) - { - //sol[0]=1; sol[1]=sol[2]=sol[3]=0; - return false; // no solution - } - mRow[ nbRow ] /= mRow[ nbRow-1 ]; - - // calculate solution (back substitution) - - sol[ nbRow-1 ] = mRow[ nbRow ]; - - for ( int i = nbRow-2; i+1; --i ) - { - mRow = M[ iR[i] ]; - sol[ i ] = mRow[ nbRow ]; - for ( int j = nbRow-1; j > i; --j ) - sol[ i ] -= sol[j]*mRow[ j ]; - sol[ i ] /= mRow[ i ]; - } - - return true; - } - - - /*! - * \brief Solve system equation in matrix form using Gaussian elimination algorithm - * \param M - N x N+NB_OF_VARS matrix - * \param sol - vector of N solutions - * \retval bool - true if succeeded - */ - template - bool solveSystemOfEquations2(const double *matrix, double *solutions, double eps) - { - unsigned k,j; - int nr,n,m,np; - double s,g; - int mb; - // - double B[SZ*(SZ+NB_OF_RES)]; - std::copy(matrix,matrix+SZ*(SZ+NB_OF_RES),B); - // - nr=SZ+NB_OF_RES; - for(k=0;keps) - {/* Rows permutation */ - for(m=0;m(),s)); - for(j=0;j - inline void barycentric_coords(const double* triaCoords, const double* p, double* bc) - { - // matrix 2x2 - double - T11 = triaCoords[0]-triaCoords[2*SPACEDIM], T12 = triaCoords[SPACEDIM]-triaCoords[2*SPACEDIM], - T21 = triaCoords[1]-triaCoords[2*SPACEDIM+1], T22 = triaCoords[SPACEDIM+1]-triaCoords[2*SPACEDIM+1]; - // matrix determinant - double Tdet = T11*T22 - T12*T21; - if ( fabs( Tdet ) < std::numeric_limits::min() ) { - bc[0]=1; bc[1]=0; bc[2]=0; - return; - } - // matrix inverse - double t11 = T22, t12 = -T12, t21 = -T21, t22 = T11; - // vector - double r11 = p[0]-triaCoords[2*SPACEDIM], r12 = p[1]-triaCoords[2*SPACEDIM+1]; - // barycentric coordinates: mutiply matrix by vector - bc[0] = (t11 * r11 + t12 * r12)/Tdet; - bc[1] = (t21 * r11 + t22 * r12)/Tdet; - bc[2] = 1. - bc[0] - bc[1]; - } - - /*! - * Calculate barycentric coordinates of a point p with respect to triangle or tetra verices. - * This method makes 2 assumptions : - * - this is a simplex - * - spacedim == meshdim. For TRI3 and TRI6 spaceDim is expected to be equal to 2 and for TETRA4 spaceDim is expected to be equal to 3. - * If not the case (3D surf for example) a previous projection should be done before. - */ - inline void barycentric_coords(const std::vector& n, const double *p, double *bc) - { - enum { _X, _Y, _Z }; - switch(n.size()) - { - case 2: - {// SEG 2 - double delta=n[0][0]-n[1][0]; - bc[0]=fabs((*p-n[1][0])/delta); - bc[1]=fabs((*p-n[0][0])/delta); - break; - } - case 3: - { // TRIA3 - // matrix 2x2 - double - T11 = n[0][_X]-n[2][_X], T12 = n[1][_X]-n[2][_X], - T21 = n[0][_Y]-n[2][_Y], T22 = n[1][_Y]-n[2][_Y]; - // matrix determinant - double Tdet = T11*T22 - T12*T21; - if ( (std::fabs( Tdet) ) < (std::numeric_limits::min()) ) - { - bc[0]=1; bc[1]=bc[2]=0; // no solution - return; - } - // matrix inverse - double t11 = T22, t12 = -T12, t21 = -T21, t22 = T11; - // vector - double r11 = p[_X]-n[2][_X], r12 = p[_Y]-n[2][_Y]; - // barycentric coordinates: mutiply matrix by vector - bc[0] = (t11 * r11 + t12 * r12)/Tdet; - bc[1] = (t21 * r11 + t22 * r12)/Tdet; - bc[2] = 1. - bc[0] - bc[1]; - break; - } - case 4: - { // TETRA4 - // Find bc by solving system of 3 equations using Gaussian elimination algorithm - // bc1*( x1 - x4 ) + bc2*( x2 - x4 ) + bc3*( x3 - x4 ) = px - x4 - // bc1*( y1 - y4 ) + bc2*( y2 - y4 ) + bc3*( y3 - y4 ) = px - y4 - // bc1*( z1 - z4 ) + bc2*( z2 - z4 ) + bc3*( z3 - z4 ) = px - z4 - - double T[3][4]= - {{ n[0][_X]-n[3][_X], n[1][_X]-n[3][_X], n[2][_X]-n[3][_X], p[_X]-n[3][_X] }, - { n[0][_Y]-n[3][_Y], n[1][_Y]-n[3][_Y], n[2][_Y]-n[3][_Y], p[_Y]-n[3][_Y] }, - { n[0][_Z]-n[3][_Z], n[1][_Z]-n[3][_Z], n[2][_Z]-n[3][_Z], p[_Z]-n[3][_Z] }}; - - if ( !solveSystemOfEquations<3>( T, bc ) ) - bc[0]=1., bc[1] = bc[2] = bc[3] = 0; - else - bc[ 3 ] = 1. - bc[0] - bc[1] - bc[2]; - break; - } - case 6: - { - // TRIA6 - double matrix2[48]={1., 0., 0., 0., 0., 0., 0., 0., - 1., 0., 0., 0., 0., 0., 1., 0., - 1., 0., 0., 0., 0., 0., 0., 1., - 1., 0., 0., 0., 0., 0., 0.5, 0., - 1., 0., 0., 0., 0., 0., 0.5, 0.5, - 1., 0., 0., 0., 0., 0., 0.,0.5}; - for(int i=0;i<6;i++) - { - matrix2[8*i+1]=n[i][0]; - matrix2[8*i+2]=n[i][1]; - matrix2[8*i+3]=n[i][0]*n[i][0]; - matrix2[8*i+4]=n[i][0]*n[i][1]; - matrix2[8*i+5]=n[i][1]*n[i][1]; - } - double res[12]; - solveSystemOfEquations2<6,2>(matrix2,res,std::numeric_limits::min()); - double refCoo[2]; - refCoo[0]=computeTria6RefBase(res,p); - refCoo[1]=computeTria6RefBase(res+6,p); - computeWeightedCoeffsInTria6FromRefBase(refCoo,bc); - break; - } - case 10: - {//TETRA10 - double matrix2[130]={1., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., - 1., 0., 0., 0., 0., 0., 0., 0., 0., 0., 1., 0., 0., - 1., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 1., 0., - 1., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 1., - 1., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.5, 0., 0., - 1., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.5, 0.5, 0., - 1., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.,0.5, 0., - 1., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.5, - 1., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.5, 0., 0.5, - 1., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.5, 0.5}; - for(int i=0;i<10;i++) - { - matrix2[13*i+1]=n[i][0]; - matrix2[13*i+2]=n[i][1]; - matrix2[13*i+3]=n[i][2]; - matrix2[13*i+4]=n[i][0]*n[i][0]; - matrix2[13*i+5]=n[i][0]*n[i][1]; - matrix2[13*i+6]=n[i][0]*n[i][2]; - matrix2[13*i+7]=n[i][1]*n[i][1]; - matrix2[13*i+8]=n[i][1]*n[i][2]; - matrix2[13*i+9]=n[i][2]*n[i][2]; - } - double res[30]; - solveSystemOfEquations2<10,3>(matrix2,res,std::numeric_limits::min()); - double refCoo[3]; - refCoo[0]=computeTetra10RefBase(res,p); - refCoo[1]=computeTetra10RefBase(res+10,p); - refCoo[2]=computeTetra10RefBase(res+20,p); - computeWeightedCoeffsInTetra10FromRefBase(refCoo,bc); - break; - } - default: - throw INTERP_KERNEL::Exception("INTERP_KERNEL::barycentric_coords : unrecognized simplex !"); - } - } - - /*_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ */ - /* calcul la surface d'un polygone. */ - /*_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ */ - - inline double Surf_Poly(const std::vector& Poly) - { - - double Surface=0; - for(unsigned long i=0; i<(Poly.size())/2-2; i++) - { - double Surf=Surf_Tri( &Poly[0],&Poly[2*(i+1)],&Poly[2*(i+2)] ); - Surface=Surface + Surf ; - } - return Surface ; - } - - /*_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ */ - /* fonction qui teste si un point est dans une maille */ - /* point: P_0 */ - /* P_1, P_2, P_3 sommet des mailles */ - /*_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ */ - - inline bool point_dans_triangle(const double* P_0,const double* P_1, - const double* P_2,const double* P_3, - double eps) - { - - bool A=false; - double det_1=mon_determinant(P_1,P_3,P_0); - double det_2=mon_determinant(P_3,P_2,P_0); - double det_3=mon_determinant(P_2,P_1,P_0); - if( (det_1>=-eps && det_2>=-eps && det_3>=-eps) || (det_1<=eps && det_2<=eps && det_3<=eps) ) - { - A=true; - } - - return A; - } - - /*_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ */ - /*fonction pour verifier qu'un point n'a pas deja ete considerer dans */ - /* le vecteur et le rajouter au vecteur sinon. */ - /*_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ */ - - inline void verif_point_dans_vect(const double* P, std::vector& V, double absolute_precision ) - { - long taille=V.size(); - bool isPresent=false; - for(long i=0;i& V, double dim_caracteristic, double precision) - { - - double absolute_precision = precision*dim_caracteristic; - bool A_1=INTERP_KERNEL::point_dans_triangle(P_1,P_4,P_5,P_6,absolute_precision); - if(A_1) - verif_point_dans_vect(P_1,V,absolute_precision); - bool A_2=INTERP_KERNEL::point_dans_triangle(P_2,P_4,P_5,P_6,absolute_precision); - if(A_2) - verif_point_dans_vect(P_2,V,absolute_precision); - bool A_3=INTERP_KERNEL::point_dans_triangle(P_3,P_4,P_5,P_6,absolute_precision); - if(A_3) - verif_point_dans_vect(P_3,V,absolute_precision); - } - - - /*_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _*/ - /* calcul de l'intersection de deux segments: segments P1P2 avec P3P4 */ - /* . Si l'intersection est non nulle et si celle-ci n'est */ - /* n'est pas deja contenue dans Vect on la rajoute a Vect */ - /*_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _*/ - - inline void inters_de_segment(const double * P_1,const double * P_2, - const double * P_3,const double * P_4, - std::vector& Vect, - double dim_caracteristic, double precision) - { - // calcul du determinant de P_1P_2 et P_3P_4. - double det=(P_2[0]-P_1[0])*(P_4[1]-P_3[1])-(P_4[0]-P_3[0])*(P_2[1]-P_1[1]); - - double absolute_precision = dim_caracteristic*precision; - if(fabs(det)>absolute_precision) - { - double k_1=-((P_3[1]-P_4[1])*(P_3[0]-P_1[0])+(P_4[0]-P_3[0])*(P_3[1]-P_1[1]))/det; - - if (k_1 >= -absolute_precision && k_1 <= 1+absolute_precision) - //if( k_1 >= -precision && k_1 <= 1+precision) - { - double k_2= ((P_1[1]-P_2[1])*(P_1[0]-P_3[0])+(P_2[0]-P_1[0])*(P_1[1]-P_3[1]))/det; - - if (k_2 >= -absolute_precision && k_2 <= 1+absolute_precision) - //if( k_2 >= -precision && k_2 <= 1+precision) - { - double P_0[2]; - P_0[0]=P_1[0]+k_1*(P_2[0]-P_1[0]); - P_0[1]=P_1[1]+k_1*(P_2[1]-P_1[1]); - verif_point_dans_vect(P_0,Vect,absolute_precision); - } - } - } - } - - - - /*_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _*/ - /* calcul l'intersection de deux triangles */ - /* P_1, P_2, P_3: sommets du premier triangle */ - /* P_4, P_5, P_6: sommets du deuxi�me triangle */ - /*_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _*/ - - inline void intersec_de_triangle(const double* P_1,const double* P_2, const double* P_3, - const double* P_4,const double* P_5,const double* P_6, - std::vector& Vect, double dim_caracteristic, double precision) - { - inters_de_segment(P_1,P_2,P_4,P_5,Vect, dim_caracteristic, precision); - inters_de_segment(P_1,P_2,P_5,P_6,Vect, dim_caracteristic, precision); - inters_de_segment(P_1,P_2,P_6,P_4,Vect, dim_caracteristic, precision); - inters_de_segment(P_2,P_3,P_4,P_5,Vect, dim_caracteristic, precision); - inters_de_segment(P_2,P_3,P_5,P_6,Vect, dim_caracteristic, precision); - inters_de_segment(P_2,P_3,P_6,P_4,Vect, dim_caracteristic, precision); - inters_de_segment(P_3,P_1,P_4,P_5,Vect, dim_caracteristic, precision); - inters_de_segment(P_3,P_1,P_5,P_6,Vect, dim_caracteristic, precision); - inters_de_segment(P_3,P_1,P_6,P_4,Vect, dim_caracteristic, precision); - rajou_sommet_triangl(P_1,P_2,P_3,P_4,P_5,P_6,Vect, dim_caracteristic, precision); - rajou_sommet_triangl(P_4,P_5,P_6,P_1,P_2,P_3,Vect, dim_caracteristic, precision); - } - - /*_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _*/ - /* fonction pour verifier qu'un node maille n'a pas deja ete considerer */ - /* dans le vecteur et le rajouter au vecteur sinon. */ - /*_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _*/ - - inline void verif_maill_dans_vect(int Num, std::vector& V) - { - long taille=V.size(); - int A=0; - for(long i=0;itheta1, std::pair theta2) - { - double norm1 = sqrt(theta1.first*theta1.first +theta1.second*theta1.second); - double norm2 = sqrt(theta2.first*theta2.first +theta2.second*theta2.second); - - double epsilon = 1.e-12; - - if( norm1 < epsilon || norm2 < epsilon ) - std::cout << "Warning InterpolationUtils.hxx: AngleLess : Vector with zero norm, cannot define the angle !!!! " << std::endl; - - return theta1.second*(norm2 + theta2.first) < theta2.second*(norm1 + theta1.first); - - } - }; - - - /*_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ */ - /* fonction pour reconstituer un polygone convexe a partir */ - /* d'un nuage de point. */ - /*_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ */ - - inline std::vector reconstruct_polygon(const std::vector& V) - { - - int taille((int)V.size()); - - //VB : why 6 ? - - if(taille<=6) - {return V;} - else - { - double *COS=new double[taille/2]; - double *SIN=new double[taille/2]; - //double *angle=new double[taille/2]; - std::vector Bary=bary_poly(V); - COS[0]=1.0; - SIN[0]=0.0; - //angle[0]=0.0; - for(int i=0; i Trigo=calcul_cos_et_sin(&Bary[0],&V[0],&V[2*(i+1)]); - COS[i+1]=Trigo[0]; - SIN[i+1]=Trigo[1]; - //if(SIN[i+1]>=0) - // {angle[i+1]=atan2(SIN[i+1],COS[i+1]);} - // else - // {angle[i+1]=-atan2(SIN[i+1],COS[i+1]);} - } - - //ensuite on ordonne les angles. - std::vector Pt_ordonne; - Pt_ordonne.reserve(taille); - // std::multimap Ordre; - std::multimap,int, AngleLess> CosSin; - for(int i=0;i::iterator mi; - std::multimap,int, AngleLess>::iterator micossin; - // for(mi=Ordre.begin();mi!=Ordre.end();mi++) - // { - // int j=(*mi).second; - // Pt_ordonne.push_back(V[2*j]); - // Pt_ordonne.push_back(V[2*j+1]); - // } - for(micossin=CosSin.begin();micossin!=CosSin.end();micossin++) - { - int j=(*micossin).second; - Pt_ordonne.push_back(V[2*j]); - Pt_ordonne.push_back(V[2*j+1]); - } - delete [] COS; - delete [] SIN; - // delete [] angle; - return Pt_ordonne; - } - } - - template - inline void getElemBB(double* bb, const double *coordsOfMesh, int iP, int nb_nodes) - { - bb[0]=std::numeric_limits::max(); - bb[1]=-std::numeric_limits::max(); - bb[2]=std::numeric_limits::max(); - bb[3]=-std::numeric_limits::max(); - bb[4]=std::numeric_limits::max(); - bb[5]=-std::numeric_limits::max(); - - for (int i=0; ibb[1])?x:bb[1]; - bb[2]=(ybb[3])?y:bb[3]; - bb[4]=(zbb[5])?z:bb[5]; - } - } - - /*_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _*/ - /* Computes the dot product of a and b */ - /*_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _*/ - template - inline double dotprod( const double * a, const double * b) - { - double result=0; - for(int idim = 0; idim < dim ; idim++) result += a[idim]*b[idim]; - return result; - } - /*_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _*/ - /* Computes the norm of vector v */ - /*_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _*/ - template - inline double norm(const double * v) - { - double result =0; - for(int idim =0; idim - inline double distance2( const double * a, const double * b) - { - double result =0; - for(int idim =0; idim - inline double distance2( T * a, int inda, T * b, int indb) - { - double result =0; - for(int idim =0; idim inline void crossprod( const double * A, const double * B, const double * C, double * V); - - template<> inline - void crossprod<2>( const double * A, const double * B, const double * C, double * V) - { - double AB[2]; - double AC[2]; - for(int idim =0; idim<2; idim++) AB[idim] = B[idim]-A[idim];//B-A - for(int idim =0; idim<2; idim++) AC[idim] = C[idim]-A[idim];//C-A; - - V[0]=determinant(AB,AC); - V[1]=0; - } - template<> inline - void crossprod<3>( const double * A, const double * B, const double * C, double * V) - { - double AB[3]; - double AC[3]; - for(int idim =0; idim<3; idim++) AB[idim] = B[idim]-A[idim];//B-A - for(int idim =0; idim<3; idim++) AC[idim] = C[idim]-A[idim];//C-A; - - V[0]=AB[1]*AC[2]-AB[2]*AC[1]; - V[1]=-AB[0]*AC[2]+AB[2]*AC[0]; - V[2]=AB[0]*AC[1]-AB[1]*AC[0]; - } - template<> inline - void crossprod<1>( const double * /*A*/, const double * /*B*/, const double * /*C*/, double * /*V*/) - { - // just to be able to compile - } - - /*_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _*/ - /* Checks wether point A is inside the quadrangle BCDE */ - /*_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _*/ - - template inline double check_inside(const double* A,const double* B,const double* C,const double* D, - const double* E,double* ABC, double* ADE) - { - crossprod(A,B,C,ABC); - crossprod(A,D,E,ADE); - return dotprod(ABC,ADE); - } - - - /*_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _*/ - /* Computes the geometric angle (in [0,Pi]) between two non zero vectors AB and AC */ - /*_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _*/ - template inline double angle(const double * A, const double * B, const double * C, double * n) - { - double AB[dim]; - double AC[dim]; - double orthAB[dim]; - - for(int idim =0; idim(AB); - for(int idim =0; idim(AC); - double AB_dot_AC=dotprod(AB,AC); - for(int idim =0; idim(orthAB); - - return 2*atan2(numer,denom); - } - - /*_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _*/ - /* Tells whether the frame constituted of vectors AB, AC and n is direct */ - /*_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _*/ - template inline double direct_frame(const double * A, const double * B, const double * C, double * n); - template<> inline - double direct_frame<2>(const double * A, const double * B, const double * C, double * n) - { - double AB[2]; - double AC[2]; - for(int idim =0; idim<2; idim++) AB[idim] = B[idim]-A[idim];//B-A; - for(int idim =0; idim<2; idim++) AC[idim] = C[idim]-A[idim];//C-A; - - return determinant(AB,AC)*n[0]; - } - template<> inline - double direct_frame<3>(const double * A, const double * B, const double * C, double * n) - { - double AB[3]; - double AC[3]; - for(int idim =0; idim<3; idim++) AB[idim] = B[idim]-A[idim];//B-A; - for(int idim =0; idim<3; idim++) AC[idim] = C[idim]-A[idim];//C-A; - - return determinant(AB,AC,n)>0; - } - - /*_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _*/ - /* calcul l'intersection de deux polygones COPLANAIRES */ - /* en dimension DIM (2 ou 3). Si DIM=3 l'algorithme ne considere*/ - /* que les deux premieres coordonnees de chaque point */ - /*_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _*/ - template inline void intersec_de_polygone(const double * Coords_A, const double * Coords_B, - int nb_NodesA, int nb_NodesB, - std::vector& inter, - double dim_caracteristic, double precision) - { - for(int i_A = 1; i_A3) inter=INTERP_KERNEL::reconstruct_polygon(inter); - } - - /*_ _ _ _ _ _ _ _ _ - *_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ - * fonctions qui calcule l'aire d'un polygone en dimension 2 ou 3 - *_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ */ - template inline double polygon_area(std::vector& inter) - { - double result=0.; - double area[DIM]; - - for(int i = 1; i<(int)inter.size()/DIM-1; i++) - { - INTERP_KERNEL::crossprod(&inter[0],&inter[DIM*i],&inter[DIM*(i+1)],area); - result +=0.5*norm(area); - } - return result; - } - - template inline double polygon_area(std::deque& inter) - { - double result=0.; - double area[DIM]; - - for(int i = 1; i<(int)inter.size()/DIM-1; i++) - { - INTERP_KERNEL::crossprod(&inter[0],&inter[DIM*i],&inter[DIM*(i+1)],area); - result +=0.5*norm(area); - } - return result; - } - - /*! Computes the triple product (XA^XB).XC (in 3D)*/ - inline double triple_product(const double* A, const double*B, const double*C, const double*X) - { - double XA[3]; - XA[0]=A[0]-X[0]; - XA[1]=A[1]-X[1]; - XA[2]=A[2]-X[2]; - double XB[3]; - XB[0]=B[0]-X[0]; - XB[1]=B[1]-X[1]; - XB[2]=B[2]-X[2]; - double XC[3]; - XC[0]=C[0]-X[0]; - XC[1]=C[1]-X[1]; - XC[2]=C[2]-X[2]; - - return - (XA[1]*XB[2]-XA[2]*XB[1])*XC[0]+ - (XA[2]*XB[0]-XA[0]*XB[2])*XC[1]+ - (XA[0]*XB[1]-XA[1]*XB[0])*XC[2]; - } - - /*! Subroutine of checkEqualPolygins that tests if two list of nodes (not necessarily distincts) describe the same polygon, assuming they share a comon point.*/ - /*! Indexes istart1 and istart2 designate two points P1 in L1 and P2 in L2 that have identical coordinates. Generally called with istart1=0.*/ - /*! Integer sign ( 1 or -1) indicate the direction used in going all over L2. */ - template - bool checkEqualPolygonsOneDirection(T * L1, T * L2, int size1, int size2, int istart1, int istart2, double epsilon, int sign) - { - int i1 = istart1; - int i2 = istart2; - int i1next = ( i1 + 1 ) % size1; - int i2next = ( i2 + sign +size2) % size2; - - while(true) - { - while( i1next!=istart1 && distance2(L1,i1*dim, L1,i1next*dim) < epsilon ) i1next = ( i1next + 1 ) % size1; - while( i2next!=istart2 && distance2(L2,i2*dim, L2,i2next*dim) < epsilon ) i2next = ( i2next + sign +size2 ) % size2; - - if(i1next == istart1) - { - if(i2next == istart2) - return true; - else return false; - } - else - if(i2next == istart2) - return false; - else - { - if(distance2(L1,i1next*dim, L2,i2next*dim) > epsilon ) - return false; - else - { - i1 = i1next; - i2 = i2next; - i1next = ( i1 + 1 ) % size1; - i2next = ( i2 + sign + size2 ) % size2; - } - } - } - } - - /*! Tests if two list of nodes (not necessarily distincts) describe the same polygon.*/ - /*! Existence of multiple points in the list is considered.*/ - template - bool checkEqualPolygons(T * L1, T * L2, double epsilon) - { - if(L1==NULL || L2==NULL) - { - std::cout << "Warning InterpolationUtils.hxx:checkEqualPolygonsPointer: Null pointer " << std::endl; - throw(Exception("big error: not closed polygon...")); - } - - int size1 = (*L1).size()/dim; - int size2 = (*L2).size()/dim; - int istart1 = 0; - int istart2 = 0; - - while( istart2 < size2 && distance2(L1,istart1*dim, L2,istart2*dim) > epsilon ) istart2++; - - if(istart2 == size2) - { - return (size1 == 0) && (size2 == 0); - } - else - return checkEqualPolygonsOneDirection( L1, L2, size1, size2, istart1, istart2, epsilon, 1) - || checkEqualPolygonsOneDirection( L1, L2, size1, size2, istart1, istart2, epsilon, -1); - - } -} - - -#endif diff --git a/src/INTERP_KERNEL/Intersector3D.hxx b/src/INTERP_KERNEL/Intersector3D.hxx deleted file mode 100644 index c9b74ffe7..000000000 --- a/src/INTERP_KERNEL/Intersector3D.hxx +++ /dev/null @@ -1,49 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 -// 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 __INTERSECTOR3D_HXX__ -#define __INTERSECTOR3D_HXX__ - -#include "TargetIntersector.hxx" - -namespace INTERP_KERNEL -{ - template - class Intersector3D : public TargetIntersector - { - public: - static const int SPACEDIM=MyMeshType::MY_SPACEDIM; - static const int MESHDIM=MyMeshType::MY_MESHDIM; - typedef typename MyMeshType::MyConnType ConnType; - static const NumberingPolicy numPol=MyMeshType::My_numPol; - public: - Intersector3D(const MyMeshType& targetMesh, const MyMeshType& srcMesh); - void getRealTargetCoordinates(ConnType icellT, std::vector& coordsT) const; - void getRealSourceCoordinates(ConnType icellT, std::vector& coordsT) const; - const ConnType *getStartConnOfTargetCell(ConnType icellT) const; - const ConnType *getStartConnOfSourceCell(ConnType icellS) const; - void getConnOfSourceCell(ConnType icellS, typename std::vector& res) const; - protected: - const MyMeshType& _target_mesh; - const MyMeshType& _src_mesh; - }; -} - -#endif diff --git a/src/INTERP_KERNEL/Intersector3D.txx b/src/INTERP_KERNEL/Intersector3D.txx deleted file mode 100644 index 92ff0a56a..000000000 --- a/src/INTERP_KERNEL/Intersector3D.txx +++ /dev/null @@ -1,107 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 -// 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 __INTERSECTOR3D_TXX__ -#define __INTERSECTOR3D_TXX__ - -#include "Intersector3D.hxx" - -#include - -namespace INTERP_KERNEL -{ - template - Intersector3D::Intersector3D(const MyMeshType& targetMesh, const MyMeshType& srcMesh):_target_mesh(targetMesh),_src_mesh(srcMesh) - { - } - - /*! - * @param icellT in format of MyMeshType. - */ - template - void Intersector3D::getRealTargetCoordinates(ConnType icellT, std::vector& coordsT) const - { - int nbNodesT=_target_mesh.getNumberOfNodesOfElement(icellT); - coordsT.resize(SPACEDIM*nbNodesT); - std::vector::iterator iter=coordsT.begin(); - for (ConnType iT=0; iT - void Intersector3D::getRealSourceCoordinates(ConnType icellS, std::vector& coordsS) const - { - int nbNodesS=_src_mesh.getNumberOfNodesOfElement(icellS); - coordsS.resize(SPACEDIM*nbNodesS); - std::vector::iterator iter=coordsS.begin(); - for (ConnType iS=0; iS - const typename MyMeshType::MyConnType *Intersector3D::getStartConnOfTargetCell(ConnType icellT) const - { - const ConnType *myConectT=_target_mesh.getConnectivityPtr(); - const ConnType *myConIndexT=_target_mesh.getConnectivityIndexPtr(); - return myConectT+OTT::conn2C(myConIndexT[icellT]); - } - - /*! - * @param icellT in C format. - * @return is in format of MyMeshType - */ - template - const typename MyMeshType::MyConnType *Intersector3D::getStartConnOfSourceCell(ConnType icellS) const - { - const ConnType *myConectS=_src_mesh.getConnectivityPtr(); - const ConnType *myConIndexS=_src_mesh.getConnectivityIndexPtr(); - return myConectS+OTT::conn2C(myConIndexS[icellS]); - } - - /*! - * @param icellS in format of MyMeshType. - * @param res ; out param in format of MyMeshType. - */ - template - void Intersector3D::getConnOfSourceCell(ConnType icellS, typename std::vector& res) const - { - const ConnType *myConectS=_src_mesh.getConnectivityPtr(); - const ConnType *myConIndexS=_src_mesh.getConnectivityIndexPtr(); - ConnType start=myConIndexS[OTT::ind2C(icellS)]; - ConnType end=myConIndexS[OTT::ind2C(icellS)+1]; - int nbNodesS=end-start; - res.resize(nbNodesS); - std::copy(myConectS+OTT::conn2C(start),myConectS+OTT::conn2C(end),res.begin()); - } -} - -#endif diff --git a/src/INTERP_KERNEL/Intersector3DP0P0.hxx b/src/INTERP_KERNEL/Intersector3DP0P0.hxx deleted file mode 100644 index ede6b02ae..000000000 --- a/src/INTERP_KERNEL/Intersector3DP0P0.hxx +++ /dev/null @@ -1,38 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 -// 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 __INTERSECTOR3DP0P0_HXX__ -#define __INTERSECTOR3DP0P0_HXX__ - -#include "Intersector3D.hxx" - -namespace INTERP_KERNEL -{ - template - class Intersector3DP0P0 : public Intersector3D - { - public: - Intersector3DP0P0(const MyMeshType& targetMesh, const MyMeshType& srcMesh); - int getNumberOfRowsOfResMatrix() const; - int getNumberOfColsOfResMatrix() const; - }; -} - -#endif diff --git a/src/INTERP_KERNEL/Intersector3DP0P0.txx b/src/INTERP_KERNEL/Intersector3DP0P0.txx deleted file mode 100644 index 86f1a17d5..000000000 --- a/src/INTERP_KERNEL/Intersector3DP0P0.txx +++ /dev/null @@ -1,46 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 -// 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 __INTERSECTOR3DP0P0_TXX__ -#define __INTERSECTOR3DP0P0_TXX__ - -#include "Intersector3DP0P0.hxx" -#include "Intersector3D.txx" - -namespace INTERP_KERNEL -{ - template - Intersector3DP0P0::Intersector3DP0P0(const MyMeshType& targetMesh, const MyMeshType& srcMesh):Intersector3D(targetMesh,srcMesh) - { - } - - template - int Intersector3DP0P0::getNumberOfRowsOfResMatrix() const - { - return Intersector3D::_target_mesh.getNumberOfElements(); - } - - template - int Intersector3DP0P0::getNumberOfColsOfResMatrix() const - { - return Intersector3D::_src_mesh.getNumberOfElements(); - } -} - -#endif diff --git a/src/INTERP_KERNEL/Intersector3DP0P1.hxx b/src/INTERP_KERNEL/Intersector3DP0P1.hxx deleted file mode 100644 index 8ba8b6cc4..000000000 --- a/src/INTERP_KERNEL/Intersector3DP0P1.hxx +++ /dev/null @@ -1,38 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 -// 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 __INTERSECTOR3DP0P1_HXX__ -#define __INTERSECTOR3DP0P1_HXX__ - -#include "Intersector3D.hxx" - -namespace INTERP_KERNEL -{ - template - class Intersector3DP0P1 : public Intersector3D - { - public: - Intersector3DP0P1(const MyMeshType& targetMesh, const MyMeshType& srcMesh); - int getNumberOfRowsOfResMatrix() const; - int getNumberOfColsOfResMatrix() const; - }; -} - -#endif diff --git a/src/INTERP_KERNEL/Intersector3DP0P1.txx b/src/INTERP_KERNEL/Intersector3DP0P1.txx deleted file mode 100644 index cd44920ce..000000000 --- a/src/INTERP_KERNEL/Intersector3DP0P1.txx +++ /dev/null @@ -1,46 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 -// 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 __INTERSECTOR3DP0P1_TXX__ -#define __INTERSECTOR3DP0P1_TXX__ - -#include "Intersector3DP0P1.hxx" -#include "Intersector3D.txx" - -namespace INTERP_KERNEL -{ - template - Intersector3DP0P1::Intersector3DP0P1(const MyMeshType& targetMesh, const MyMeshType& srcMesh):Intersector3D(targetMesh,srcMesh) - { - } - - template - int Intersector3DP0P1::getNumberOfRowsOfResMatrix() const - { - return Intersector3D::_target_mesh.getNumberOfNodes(); - } - - template - int Intersector3DP0P1::getNumberOfColsOfResMatrix() const - { - return Intersector3D::_src_mesh.getNumberOfElements(); - } -} - -#endif diff --git a/src/INTERP_KERNEL/Intersector3DP1P0.hxx b/src/INTERP_KERNEL/Intersector3DP1P0.hxx deleted file mode 100644 index 8ba6bf53c..000000000 --- a/src/INTERP_KERNEL/Intersector3DP1P0.hxx +++ /dev/null @@ -1,38 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 -// 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 __INTERSECTOR3DP1P0_HXX__ -#define __INTERSECTOR3DP1P0_HXX__ - -#include "Intersector3D.hxx" - -namespace INTERP_KERNEL -{ - template - class Intersector3DP1P0 : public Intersector3D - { - public: - Intersector3DP1P0(const MyMeshType& targetMesh, const MyMeshType& srcMesh); - int getNumberOfRowsOfResMatrix() const; - int getNumberOfColsOfResMatrix() const; - }; -} - -#endif diff --git a/src/INTERP_KERNEL/Intersector3DP1P0.txx b/src/INTERP_KERNEL/Intersector3DP1P0.txx deleted file mode 100644 index 9db664d67..000000000 --- a/src/INTERP_KERNEL/Intersector3DP1P0.txx +++ /dev/null @@ -1,46 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 -// 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 __INTERSECTOR3DP1P0_TXX__ -#define __INTERSECTOR3DP1P0_TXX__ - -#include "Intersector3DP1P0.hxx" -#include "Intersector3D.txx" - -namespace INTERP_KERNEL -{ - template - Intersector3DP1P0::Intersector3DP1P0(const MyMeshType& targetMesh, const MyMeshType& srcMesh):Intersector3D(targetMesh,srcMesh) - { - } - - template - int Intersector3DP1P0::getNumberOfRowsOfResMatrix() const - { - return Intersector3D::_target_mesh.getNumberOfElements(); - } - - template - int Intersector3DP1P0::getNumberOfColsOfResMatrix() const - { - return Intersector3D::_src_mesh.getNumberOfNodes(); - } -} - -#endif diff --git a/src/INTERP_KERNEL/Intersector3DP1P0Bary.hxx b/src/INTERP_KERNEL/Intersector3DP1P0Bary.hxx deleted file mode 100644 index 8b69793dc..000000000 --- a/src/INTERP_KERNEL/Intersector3DP1P0Bary.hxx +++ /dev/null @@ -1,38 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 -// 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 __Intersector3DP1P0Bary_HXX__ -#define __Intersector3DP1P0Bary_HXX__ - -#include "Intersector3D.hxx" - -namespace INTERP_KERNEL -{ - template - class Intersector3DP1P0Bary : public Intersector3D - { - public: - Intersector3DP1P0Bary(const MyMeshType& targetMesh, const MyMeshType& srcMesh); - int getNumberOfRowsOfResMatrix() const; - int getNumberOfColsOfResMatrix() const; - }; -} - -#endif diff --git a/src/INTERP_KERNEL/Intersector3DP1P0Bary.txx b/src/INTERP_KERNEL/Intersector3DP1P0Bary.txx deleted file mode 100644 index 31e7f2401..000000000 --- a/src/INTERP_KERNEL/Intersector3DP1P0Bary.txx +++ /dev/null @@ -1,46 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 -// 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 __Intersector3DP1P0Bary_TXX__ -#define __Intersector3DP1P0Bary_TXX__ - -#include "Intersector3DP1P0Bary.hxx" -#include "Intersector3D.txx" - -namespace INTERP_KERNEL -{ - template - Intersector3DP1P0Bary::Intersector3DP1P0Bary(const MyMeshType& targetMesh, const MyMeshType& srcMesh):Intersector3D(targetMesh,srcMesh) - { - } - - template - int Intersector3DP1P0Bary::getNumberOfRowsOfResMatrix() const - { - return Intersector3D::_target_mesh.getNumberOfElements(); - } - - template - int Intersector3DP1P0Bary::getNumberOfColsOfResMatrix() const - { - return Intersector3D::_src_mesh.getNumberOfNodes(); - } -} - -#endif diff --git a/src/INTERP_KERNEL/Intersector3DP1P1.hxx b/src/INTERP_KERNEL/Intersector3DP1P1.hxx deleted file mode 100644 index ff5977fa7..000000000 --- a/src/INTERP_KERNEL/Intersector3DP1P1.hxx +++ /dev/null @@ -1,38 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 -// 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 __Intersector3DP1P1_HXX__ -#define __Intersector3DP1P1_HXX__ - -#include "Intersector3D.hxx" - -namespace INTERP_KERNEL -{ - template - class Intersector3DP1P1 : public Intersector3D - { - public: - Intersector3DP1P1(const MyMeshType& targetMesh, const MyMeshType& srcMesh); - int getNumberOfRowsOfResMatrix() const; - int getNumberOfColsOfResMatrix() const; - }; -} - -#endif diff --git a/src/INTERP_KERNEL/Intersector3DP1P1.txx b/src/INTERP_KERNEL/Intersector3DP1P1.txx deleted file mode 100644 index a8aea3824..000000000 --- a/src/INTERP_KERNEL/Intersector3DP1P1.txx +++ /dev/null @@ -1,46 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 -// 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 __Intersector3DP1P1_TXX__ -#define __Intersector3DP1P1_TXX__ - -#include "Intersector3DP1P1.hxx" -#include "Intersector3D.txx" - -namespace INTERP_KERNEL -{ - template - Intersector3DP1P1::Intersector3DP1P1(const MyMeshType& targetMesh, const MyMeshType& srcMesh):Intersector3D(targetMesh,srcMesh) - { - } - - template - int Intersector3DP1P1::getNumberOfRowsOfResMatrix() const - { - return Intersector3D::_target_mesh.getNumberOfNodes(); - } - - template - int Intersector3DP1P1::getNumberOfColsOfResMatrix() const - { - return Intersector3D::_src_mesh.getNumberOfNodes(); - } -} - -#endif diff --git a/src/INTERP_KERNEL/IntersectorCU.hxx b/src/INTERP_KERNEL/IntersectorCU.hxx deleted file mode 100644 index 3bd09d120..000000000 --- a/src/INTERP_KERNEL/IntersectorCU.hxx +++ /dev/null @@ -1,78 +0,0 @@ -// Copyright (C) 2009-2015 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, 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 -// 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 -// -// File : IntersectorCU.hxx -// Created : Thu Dec 17 12:30:17 2009 -// Author : Edward AGAPOV (eap) -// - -#ifndef __IntersectorCU_HXX__ -#define __IntersectorCU_HXX__ - -#include "TargetIntersector.hxx" -#include "NormalizedUnstructuredMesh.hxx" - -namespace INTERP_KERNEL -{ - template class _StabIntersector; - - template > - class IntersectorCU : public TargetIntersector - { - public: - static const int SPACEDIM=MyCMeshType::MY_SPACEDIM; - static const int MESHDIM=MyCMeshType::MY_MESHDIM; - typedef typename MyUMeshType::MyConnType UConnType; - typedef typename MyCMeshType::MyConnType CConnType; - public: - //! \addtogroup InterpKerGrpIntCU @{ - IntersectorCU(const MyCMeshType& meshS, const MyUMeshType& meshT); - //! @} - virtual ~IntersectorCU(); - void getUElemBB(double* bb, UConnType iP); - void getUCoordinates(UConnType icell, std::vector& coords); - - int getNumberOfRowsOfResMatrix() const; - int getNumberOfColsOfResMatrix() const; - void intersectCells(CConnType icellU, const std::vector& icellC, MyMatrix& res); - double intersectGeometry(CConnType icellT, const std::vector& icellC) { return asLeaf().intersectGeometry(icellT,icellC); } - protected: - ConcreteIntersector& asLeaf() { return static_cast(*this); } - - protected: - const UConnType *_connectU; - const UConnType *_connIndexU; - const double * _coordsU; - const MyUMeshType& _meshU; - - const double * _coordsC[SPACEDIM]; - int _nbCellsC[SPACEDIM]; - const MyCMeshType& _meshC; - }; - - // class to enable usage of IntersectorCU not for intersection but for access to data it encapsulates - template - class _StabIntersector: public IntersectorCU > - { - public: - _StabIntersector(const MyCMeshType& meshS, const MyUMeshType& meshT) : IntersectorCU >(meshS, meshT) {} - double intersectGeometry(typename MyUMeshType::MyConnType icellT, const std::vector& icellC) { throw Exception("You must provide an intersector as the 4-th template argument of IntersectorCU"); return 0; } - }; -} - -#endif diff --git a/src/INTERP_KERNEL/IntersectorCU.txx b/src/INTERP_KERNEL/IntersectorCU.txx deleted file mode 100644 index b6111f732..000000000 --- a/src/INTERP_KERNEL/IntersectorCU.txx +++ /dev/null @@ -1,163 +0,0 @@ -// Copyright (C) 2009-2015 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, 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 -// 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 -// -// File : IntersectorCU.txx -// Created : Thu Dec 17 12:30:17 2009 -// Author : Edward AGAPOV (eap) -// -#ifndef __IntersectorCU_TXX__ -#define __IntersectorCU_TXX__ - -#include "IntersectorCU.hxx" - -// convert index "From Mesh Index" -#define _FMIU(i) OTT::ind2C((i)) -#define _FMIC(i) OTT::ind2C((i)) -// convert index "To Mesh Index" -#define _TMIU(i) OTT::indFC((i)) -#define _TMIC(i) OTT::indFC((i)) -// convert coord "From Mesh Coord" -#define _FMCOO(i) OTT::coo2C((i)) -// convert connectivity "From Mesh Connectivity" -#define _FMCON(i) OTT::conn2C((i)) - - -#define _CU_TEMPLATE \ -template -#define _INTERSECTOR_CU_ \ -IntersectorCU - -namespace INTERP_KERNEL -{ - //================================================================================ - /*! - * \brief Constructor - */ - //================================================================================ - - _CU_TEMPLATE - _INTERSECTOR_CU_::IntersectorCU(const MyCMeshType& meshS, const MyUMeshType& meshT): - _meshU(meshT), _meshC(meshS) - { - _connectU =meshT.getConnectivityPtr(); - _connIndexU=meshT.getConnectivityIndexPtr(); - _coordsU =meshT.getCoordinatesPtr(); - - for ( int j = 0; j < SPACEDIM; ++j ) - { - _coordsC [ j ] = _meshC.getCoordsAlongAxis( _TMIC( j )); - _nbCellsC[ j ] = _meshC.nbCellsAlongAxis ( _TMIC( j )); - } - } - - //================================================================================ - /*! - * \brief Destructor - */ - //================================================================================ - - _CU_TEMPLATE - _INTERSECTOR_CU_::~IntersectorCU() - { - } - - //================================================================================ - /*! - * \brief Return bounding box of an unstructured element - */ - //================================================================================ - - _CU_TEMPLATE - void _INTERSECTOR_CU_::getUElemBB(double* bb, UConnType icell) - { - //initializing bounding box limits - for(int idim=0; idim::max(); - bb[2*idim+1] = -std::numeric_limits::max(); - } - - UConnType nb_nodes = _connIndexU[icell+1] - _connIndexU[icell]; - for (UConnType i=0; i::coo2C(conn[OTT::conn2C(conn_index[OTT::ind2C(iP)]+i)])); - const double* coord_node=_coordsU+SPACEDIM*(_FMCOO( _connectU[_FMCON (_connIndexU[_FMIU(icell)]+i)])); - for(int idim=0; idimbb[2*idim+1])?x:bb[2*idim+1]; - } - } - } - - //================================================================================ - /*! - * \brief Return coordinates of nodes of an unstructured element - */ - //================================================================================ - - _CU_TEMPLATE - void _INTERSECTOR_CU_::getUCoordinates(UConnType icell, std::vector& coords) - { - UConnType nb_nodes = _connIndexU[icell+1] - _connIndexU[icell]; - coords.resize( SPACEDIM * nb_nodes ); - for (UConnType i=0; i& icellC, - MyMatrix& res) - { - double v = intersectGeometry(icellU, icellC); - - CConnType iC = icellC[0], area = _nbCellsC[0]; - for ( int j = 1; j < SPACEDIM; ++j ) - { - iC += icellC[j] * area; - area *= _nbCellsC[j]; - } - res[ icellU ][ iC ] = v; - } -} - -#endif diff --git a/src/INTERP_KERNEL/IntersectorCU1D.hxx b/src/INTERP_KERNEL/IntersectorCU1D.hxx deleted file mode 100644 index b22d4e5ab..000000000 --- a/src/INTERP_KERNEL/IntersectorCU1D.hxx +++ /dev/null @@ -1,47 +0,0 @@ -// Copyright (C) 2009-2015 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, 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 -// 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 -// - -// File : IntersectorCU1D.hxx -// Created : Thu Dec 17 14:10:00 2009 -// Author : Edward AGAPOV (eap) -// -#ifndef __IntersectorCU1D_HXX__ -#define __IntersectorCU1D_HXX__ - -#include "IntersectorCU.hxx" - -namespace INTERP_KERNEL -{ - template - class IntersectorCU1D : public IntersectorCU > - { - public: - typedef typename MyUMeshType::MyConnType UConnType; - typedef typename MyCMeshType::MyConnType CConnType; - public: - IntersectorCU1D(const MyCMeshType& meshS, const MyUMeshType& meshT); - ~IntersectorCU1D(); - double intersectGeometry(UConnType icellT, const std::vector& icellC); - - private: - }; -} - - -#endif diff --git a/src/INTERP_KERNEL/IntersectorCU1D.txx b/src/INTERP_KERNEL/IntersectorCU1D.txx deleted file mode 100644 index 832d7b3c1..000000000 --- a/src/INTERP_KERNEL/IntersectorCU1D.txx +++ /dev/null @@ -1,82 +0,0 @@ -// Copyright (C) 2009-2015 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, 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 -// 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 -// -// File : IntersectorCU1D.txx -// Created : Thu Dec 17 14:17:49 2009 -// Author : Edward AGAPOV (eap) - -#ifndef __IntersectorCU1D_TXX__ -#define __IntersectorCU1D_TXX__ - -#include "IntersectorCU1D.hxx" -#include "IntersectorCU.txx" - -#define IntersectorCU1D_TEMPLATE template -#define INTERSECTOR_CU1D IntersectorCU1D -#define _INTER_CU IntersectorCU > - -namespace INTERP_KERNEL -{ - //================================================================================ - /*! - * \brief intersector of the unstructured mesh and the cartesian mesh in 1D - */ - //================================================================================ - - IntersectorCU1D_TEMPLATE - INTERSECTOR_CU1D::IntersectorCU1D(const MyCMeshType& meshS, - const MyUMeshType& meshT): - _INTER_CU( meshS, meshT ) - { - if ( MyCMeshType::MY_SPACEDIM != 1 || MyCMeshType::MY_MESHDIM != 1 || - MyUMeshType::MY_SPACEDIM != 1 || MyUMeshType::MY_MESHDIM != 1 ) - throw Exception("IntersectorCU1D(): Invalid mesh dimension, it must be 1"); - } - - //================================================================================ - /*! - * \brief destructor - */ - //================================================================================ - - IntersectorCU1D_TEMPLATE - INTERSECTOR_CU1D::~IntersectorCU1D() - { - } - - //================================================================================ - /*! - * \brief Calculate length of intersection of an unstructured cell and a cartesian one. - * The cartesian cell is given by its [i,j,k] indices - */ - //================================================================================ - - IntersectorCU1D_TEMPLATE - double INTERSECTOR_CU1D::intersectGeometry(UConnType icellT, - const std::vector& icellS) - { - std::vector coordsU; - _INTER_CU::getUCoordinates(icellT, coordsU); - - const double* coordsC = & _INTER_CU::_coordsC[0][ _FMIC(icellS[0]) ]; - - double res = std::min( coordsU[1], coordsC[1] ) - std::max( coordsU[0], coordsC[0] ); - return res; - } -} -#endif diff --git a/src/INTERP_KERNEL/IntersectorCU2D.hxx b/src/INTERP_KERNEL/IntersectorCU2D.hxx deleted file mode 100644 index e034028fa..000000000 --- a/src/INTERP_KERNEL/IntersectorCU2D.hxx +++ /dev/null @@ -1,47 +0,0 @@ -// Copyright (C) 2009-2015 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, 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 -// 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 -// - -// File : IntersectorCU2D.hxx -// Created : Thu Dec 17 14:10:00 2009 -// Author : Edward AGAPOV (eap) -// -#ifndef __IntersectorCU2D_HXX__ -#define __IntersectorCU2D_HXX__ - -#include "IntersectorCU.hxx" - -namespace INTERP_KERNEL -{ - template - class IntersectorCU2D : public IntersectorCU > - { - public: - typedef typename MyUMeshType::MyConnType UConnType; - typedef typename MyCMeshType::MyConnType CConnType; - public: - IntersectorCU2D(const MyCMeshType& meshS, const MyUMeshType& meshT); - double intersectGeometry(UConnType icellT, const std::vector& icellC); - - private: - TriangulationIntersector _intersector; - }; -} - - -#endif diff --git a/src/INTERP_KERNEL/IntersectorCU2D.txx b/src/INTERP_KERNEL/IntersectorCU2D.txx deleted file mode 100644 index df7c7efb7..000000000 --- a/src/INTERP_KERNEL/IntersectorCU2D.txx +++ /dev/null @@ -1,76 +0,0 @@ -// Copyright (C) 2009-2015 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, 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 -// 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 -// -// File : IntersectorCU2D.txx -// Created : Thu Dec 17 14:17:49 2009 -// Author : Edward AGAPOV (eap) - -#ifndef __IntersectorCU2D_TXX__ -#define __IntersectorCU2D_TXX__ - -#include "IntersectorCU2D.hxx" -#include "IntersectorCU.txx" - -#define IntersectorCU2D_TEMPLATE template -#define INTERSECTOR_CU2D IntersectorCU2D -#define INTER_CU IntersectorCU > - - -namespace INTERP_KERNEL -{ - IntersectorCU2D_TEMPLATE - INTERSECTOR_CU2D::IntersectorCU2D(const MyCMeshType& meshS, - const MyUMeshType& meshT): - IntersectorCU >( meshS, meshT ), - _intersector(meshT, meshT, 0,0,0,0,0,0,0 ) - { - if ( MyCMeshType::MY_SPACEDIM != 2 || MyCMeshType::MY_MESHDIM != 2 || - MyUMeshType::MY_SPACEDIM != 2 || MyUMeshType::MY_MESHDIM != 2 ) - throw Exception("IntersectorCU2D(): Invalid mesh dimension, it must be 2"); - } - - - //================================================================================ - /*! - * \brief Calculate area of intersection of an unstructured cell and a cartesian one. - * The cartesian cell is given by its [i,j] indices - */ - //================================================================================ - - IntersectorCU2D_TEMPLATE - double INTERSECTOR_CU2D::intersectGeometry(UConnType icellT, - const std::vector& icellS) - { - std::vector uCoords; - this->getUCoordinates( icellT, uCoords ); - - NormalizedCellType tT = INTER_CU::_meshU.getTypeOfElement( _TMIU(icellT)); - bool is_tgt_quad = CellModel::GetCellModel(tT).isQuadratic(); - - double quad[8] = { INTER_CU::_coordsC[0][icellS[0]], INTER_CU::_coordsC[1][icellS[1]], - INTER_CU::_coordsC[0][icellS[0]+1], INTER_CU::_coordsC[1][icellS[1]], - INTER_CU::_coordsC[0][icellS[0]+1], INTER_CU::_coordsC[1][icellS[1]+1], - INTER_CU::_coordsC[0][icellS[0]], INTER_CU::_coordsC[1][icellS[1]+1] }; - - double surf = _intersector.intersectGeometryWithQuadrangle( quad, - uCoords, - is_tgt_quad); - return surf; - } -} -#endif diff --git a/src/INTERP_KERNEL/IntersectorCU3D.hxx b/src/INTERP_KERNEL/IntersectorCU3D.hxx deleted file mode 100644 index 32abb3d0c..000000000 --- a/src/INTERP_KERNEL/IntersectorCU3D.hxx +++ /dev/null @@ -1,55 +0,0 @@ -// Copyright (C) 2009-2015 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, 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 -// 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 -// - -// File : IntersectorCU3D.hxx -// Created : Thu Dec 17 14:10:00 2009 -// Author : Edward AGAPOV (eap) -// -#ifndef __IntersectorCU3D_HXX__ -#define __IntersectorCU3D_HXX__ - -#include "IntersectorCU.hxx" -#include "SplitterTetra.hxx" - -namespace INTERP_KERNEL -{ - class _Cartesian3D2UnstructHexMesh; - - template - class IntersectorCU3D : public IntersectorCU > - { - public: - typedef typename MyUMeshType::MyConnType UConnType; - typedef typename MyCMeshType::MyConnType CConnType; - public: - IntersectorCU3D(const MyCMeshType& meshS, const MyUMeshType& meshT, SplittingPolicy splitting_policy); - ~IntersectorCU3D(); - double intersectGeometry(UConnType icellT, const std::vector& icellC); - - private: - - typedef SplitterTetra2 TSplitter; - typedef SplitterTetra <_Cartesian3D2UnstructHexMesh > TTetra; - _Cartesian3D2UnstructHexMesh* _uHexMesh; - TSplitter* _split; - }; -} - - -#endif diff --git a/src/INTERP_KERNEL/IntersectorCU3D.txx b/src/INTERP_KERNEL/IntersectorCU3D.txx deleted file mode 100644 index c271120f0..000000000 --- a/src/INTERP_KERNEL/IntersectorCU3D.txx +++ /dev/null @@ -1,156 +0,0 @@ -// Copyright (C) 2009-2015 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, 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 -// 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 -// -// File : IntersectorCU3D.txx -// Created : Thu Dec 17 14:17:49 2009 -// Author : Edward AGAPOV (eap) - -#ifndef __IntersectorCU3D_TXX__ -#define __IntersectorCU3D_TXX__ - -#include "IntersectorCU3D.hxx" -#include "IntersectorCU.txx" -#include "SplitterTetra.txx" - -#define IntersectorCU3D_TEMPLATE template -#define INTERSECTOR_CU3D IntersectorCU3D -#define _INTERSECTOR_CU IntersectorCU > - -namespace INTERP_KERNEL -{ - //================================================================================ - /*! - * \brief Unstructured hexahedral mesh derived from cartesian 3D mesh. - * Mesh contains one HEXA8 element - */ - //================================================================================ - - class _Cartesian3D2UnstructHexMesh - { - public: - static const int MY_SPACEDIM=3; - static const int MY_MESHDIM=3; - typedef int MyConnType; - static const NumberingPolicy My_numPol=ALL_C_MODE; - - _Cartesian3D2UnstructHexMesh(const double * coords[3]): _coordsC(coords) {} - void setHexa(int I, int J, int K) // indices in C mode - { - double* pCoord = _coordsU; - for ( int k = K; k < K+2; ++k ) - for ( int j = J; j < J+2; ++j ) - for ( int i = I; i < I+2; ++i ) - { - *pCoord++ = _coordsC[0][i]; - *pCoord++ = _coordsC[1][j]; - *pCoord++ = _coordsC[2][k]; - } - } - const int *getConnectivityPtr() const - { - static int conn[] = { 1,0,2,3,5,4,6,7 }; - return conn; - } - const int *getConnectivityIndexPtr() const - { - static int conInd[] = { 0,8 }; - return conInd; - } - void getBoundingBox(double *boundingBox) const - { - boundingBox[BoundingBox::XMIN] = _coordsU[0]; - boundingBox[BoundingBox::XMAX] = _coordsU[0+1*MY_SPACEDIM]; - boundingBox[BoundingBox::YMIN] = _coordsU[1]; - boundingBox[BoundingBox::YMAX] = _coordsU[1+2*MY_SPACEDIM]; - boundingBox[BoundingBox::ZMIN] = _coordsU[2]; - boundingBox[BoundingBox::ZMAX] = _coordsU[2+4*MY_SPACEDIM]; - } - NormalizedCellType getTypeOfElement(int eltId) const { return NORM_HEXA8; } - unsigned char getNumberOfNodesOfElement(int eltId) const { return 8; } - unsigned long getNumberOfElements() const { return 1; } - unsigned long getNumberOfNodes() const { return 8; } - const double *getCoordinatesPtr() const { return _coordsU; } - void releaseTempArrays() {} - private: - const double** _coordsC; - double _coordsU[3*8]; - }; - - //================================================================================ - /*! - * \brief intersector of the unstructured mesh and the cartesian mesh in 3D - */ - //================================================================================ - - IntersectorCU3D_TEMPLATE - INTERSECTOR_CU3D::IntersectorCU3D(const MyCMeshType& meshS, - const MyUMeshType& meshT, - SplittingPolicy splitting_policy): - _INTERSECTOR_CU( meshS, meshT ) - { - if ( MyCMeshType::MY_SPACEDIM != 3 || MyCMeshType::MY_MESHDIM != 3 || - MyUMeshType::MY_SPACEDIM != 3 || MyUMeshType::MY_MESHDIM != 3 ) - throw Exception("IntersectorCU3D(): Invalid mesh dimension, it must be 3"); - - _uHexMesh = new _Cartesian3D2UnstructHexMesh( _INTERSECTOR_CU::_coordsC ); - _split = new TSplitter( meshT, *_uHexMesh, splitting_policy ); - } - - //================================================================================ - /*! - * \brief destructor - */ - //================================================================================ - - IntersectorCU3D_TEMPLATE - INTERSECTOR_CU3D::~IntersectorCU3D() - { - delete _uHexMesh; _uHexMesh=0; - delete _split; _split=0; - } - - //================================================================================ - /*! - * \brief Calculate volume of intersection of an unstructured cell and a cartesian one. - * The cartesian cell is given by its [i,j,k] indices - */ - //================================================================================ - - IntersectorCU3D_TEMPLATE - double INTERSECTOR_CU3D::intersectGeometry(UConnType icellT, - const std::vector& icellS) - { - // split an unstructured cell into tetra - std::vector< TTetra* > tetra; - UConnType nb_nodes = - _INTERSECTOR_CU::_connIndexU[icellT+1] - _INTERSECTOR_CU::_connIndexU[icellT]; - _split->releaseArrays(); - _split->splitTargetCell( icellT, nb_nodes, tetra); - - // intersect a cartesian 3d cell with tetra - _uHexMesh->setHexa( _FMIC(icellS[0]),_FMIC(icellS[1]),_FMIC(icellS[2])); // set cell at i,j,k - double res = 0; - for ( unsigned int t = 0; t < tetra.size(); ++t ) - { - res += tetra[t]->intersectSourceCell( 0 ); - delete tetra[t]; - } - return res; - } -} -#endif diff --git a/src/INTERP_KERNEL/Log.hxx b/src/INTERP_KERNEL/Log.hxx deleted file mode 100644 index 3f0e35157..000000000 --- a/src/INTERP_KERNEL/Log.hxx +++ /dev/null @@ -1,66 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 -// 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 _LOG_H_ -#define _LOG_H_ - -/** - * \file Log.hxx - * \brief Simple pre-processor logging utility. - * - * Replaces LOG( lvl, x ) with "if(lvl <= LOG_LEVEL) std::cout << x << std::endl" when logging is active - * (LOG_LEVEL > 0 is defined). x is the level at which the message should be logged - if it is smaller or equal to - * LOG_LEVEL (which can be defined at compile-time for each file by passing option -DLOG_LEVEL=x to gcc) - * than the message is logged. - * - * - * - */ - -/// define LOG_LEVEL here if it is not already defined -#ifndef LOG_LEVEL -#define LOG_LEVEL 0 -#endif - -#if LOG_LEVEL > 0 - -#include - -/// write message msg to std::cout if x <= LOG_LEVEL -#define LOG(x, msg) if(x <= LOG_LEVEL) std::cout << msg << std::endl; -#define LOG3( x , msg1 , msg2 ) if(x <= LOG_LEVEL) std::cout << msg1, msg2 << std::endl; - -#else - -#define LOG( x , msg ) -#define LOG3( x , msg1 , msg2 ) - -#endif - - - - - - - - - - - -#endif diff --git a/src/INTERP_KERNEL/MeshElement.cxx b/src/INTERP_KERNEL/MeshElement.cxx deleted file mode 100644 index 696d30b18..000000000 --- a/src/INTERP_KERNEL/MeshElement.cxx +++ /dev/null @@ -1,37 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// - -#include "MeshElement.hxx" - -namespace INTERP_KERNEL -{ - ///////////////////////////////////////////////////////////////////// - /// ElementBBoxOrder ///////////// - ///////////////////////////////////////////////////////////////////// - /** - * Constructor - * - * @param coord BoundingBox coordinate (XMIN, XMAX, etc) on which to base the ordering - */ - ElementBBoxOrder::ElementBBoxOrder(BoundingBox::BoxCoord coord) - : _coord(coord) - { - } -} - diff --git a/src/INTERP_KERNEL/MeshElement.hxx b/src/INTERP_KERNEL/MeshElement.hxx deleted file mode 100644 index 3fb6ab652..000000000 --- a/src/INTERP_KERNEL/MeshElement.hxx +++ /dev/null @@ -1,87 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 -// 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 __MESHELEMENT_HXX__ -#define __MESHELEMENT_HXX__ - -#include "BoundingBox.hxx" - -namespace INTERP_KERNEL -{ - - /** - * \brief Class representing a single element of a mesh together with its bounding box. - * It gives access to the element's global number, type and bounding box and allows - * easy bounding box intersection tests between MeshElements and collections of MeshElement (MeshRegions) - */ - template - class MeshElement - { - - public: - template - MeshElement(const ConnType index, const MyMeshType& mesh); - - ~MeshElement(); - - ConnType getIndex() const { return _index; } - - unsigned char getNumberOfNodes() const { return _number; } - - const BoundingBox* getBoundingBox() const { return _box; } - - private: - /// disallow copying - MeshElement(const MeshElement& elem); - - /// disallow assignment - MeshElement& operator=(const MeshElement& elem); - - /// global number of the element - const ConnType _index; - - const unsigned char _number; - - /// bounding box of the element - does not change after having been initialised - BoundingBox* _box; - }; - - /** - * \brief Class defining an order for MeshElements based on their bounding boxes. - * The order defined between two elements is that between a given coordinate of - * their bounding boxes. For instance, if the order is based on YMIN, an element whose boxes - * has a smaller YMIN is sorted before one with a larger YMIN. - * - */ - class ElementBBoxOrder - { - public : - - ElementBBoxOrder(BoundingBox::BoxCoord coord); - template - bool operator()(MeshElement* elem1, MeshElement* elem2); - - private : - /// BoundingBox coordinate (XMIN, XMAX, etc) on which to base the ordering - BoundingBox::BoxCoord _coord; - }; - -} - -#endif diff --git a/src/INTERP_KERNEL/MeshElement.txx b/src/INTERP_KERNEL/MeshElement.txx deleted file mode 100644 index 0da39e0a0..000000000 --- a/src/INTERP_KERNEL/MeshElement.txx +++ /dev/null @@ -1,95 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 -// 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 __MESHELEMENT_TXX__ -#define __MESHELEMENT_TXX__ - -#include "MeshElement.hxx" - -#include "TetraAffineTransform.hxx" -#include "TransformedTriangle.hxx" -#include "MeshUtils.hxx" -#include "BoundingBox.hxx" -#include - -namespace INTERP_KERNEL -{ - - /** - * Constructor - * - * @param index global number of element in the mesh in C mode. - * @param mesh mesh that the element belongs to - */ - template - template - MeshElement::MeshElement(const ConnType index, const MyMeshType& mesh) - : _index(index), _number(mesh.getNumberOfNodesOfElement(OTT::indFC(index))), _box(0) - { - const double**vertices = new const double*[_number]; - - for(unsigned char i = 0 ; i < _number ; ++i) - vertices[i] = getCoordsOfNode(i , OTT::indFC(index), mesh); - - // create bounding box - _box = new BoundingBox(vertices,_number); - delete [] vertices; - } - - /** - * Destructor - * - */ - template - MeshElement::~MeshElement() - { - delete _box; - } - - - - ///////////////////////////////////////////////////////////////////// - /// ElementBBoxOrder ///////////// - ///////////////////////////////////////////////////////////////////// - - /** - * Comparison operator based on the bounding boxes of the elements - * - * @return true if the coordinate _coord of the bounding box of elem1 is - * strictly smaller than that of the bounding box of elem2 - */ - template - bool ElementBBoxOrder::operator()( MeshElement* elem1, MeshElement* elem2) - { - const BoundingBox* box1 = elem1->getBoundingBox(); - const BoundingBox* box2 = elem2->getBoundingBox(); - - assert(elem1 != 0); - assert(elem2 != 0); - assert(box1 != 0); - assert(box2 != 0); - - const double coord1 = box1->getCoordinate(_coord); - const double coord2 = box2->getCoordinate(_coord); - - return coord1 < coord2; - } - -} - -#endif diff --git a/src/INTERP_KERNEL/MeshRegion.hxx b/src/INTERP_KERNEL/MeshRegion.hxx deleted file mode 100644 index 6baf33e34..000000000 --- a/src/INTERP_KERNEL/MeshRegion.hxx +++ /dev/null @@ -1,93 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 -// 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 __MESHREGION_HXX__ -#define __MESHREGION_HXX__ - -#include "MeshElement.hxx" -#include "BoundingBox.hxx" -#include "NormalizedUnstructuredMesh.hxx" - -#include - -namespace INTERP_KERNEL -{ - /** - * \brief Class representing a set of elements in a mesh together with their bounding box. - * It permits to split itself in two, which is used in the depth-first search filtering process. - * - */ - template - class MeshRegion - { - public: - - MeshRegion(); - - ~MeshRegion(); - - template - void addElement(MeshElement* const element, const MyMeshType& mesh); - - template - void split(MeshRegion& region1, MeshRegion& region2, BoundingBox::BoxCoord coord, const MyMeshType& mesh); - - bool isDisjointWithElementBoundingBox(const MeshElement& elem) const; - /** - * Accessor to beginning of elements vector - * - * @return constant iterator pointing at the beginning of the vector or elements - */ - typename std::vector< MeshElement* >::const_iterator getBeginElements() const { return _elements.begin(); } - - /** - * Accessor to end of elements vector - * - * @return constant iterator pointing at the end of the vector or elements - */ - typename std::vector< MeshElement* >::const_iterator getEndElements() const { return _elements.end(); } - - /** - * Gives information on how many elements are contained in the region. - * - * @return the number of elements contained in the region - */ - unsigned getNumberOfElements() const { return _elements.size(); } - - private: - - /// disallow copying - MeshRegion(const MeshRegion& m); - - /// disallow assignment - MeshRegion& operator=(const MeshRegion& m); - - /// Vector of pointers to contained MeshElements. - /// NB : these pointers are not owned by the region object, and are thus - /// neither allocated or liberated in this class. The elements must therefore be allocated and liberated outside the class. - std::vector< MeshElement* > _elements; - - /// BoundingBox containing all the nodes of all the elements in the region. - BoundingBox* _box; - - }; - -} - -#endif diff --git a/src/INTERP_KERNEL/MeshRegion.txx b/src/INTERP_KERNEL/MeshRegion.txx deleted file mode 100644 index 6183b9b7c..000000000 --- a/src/INTERP_KERNEL/MeshRegion.txx +++ /dev/null @@ -1,153 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 -// 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 __MESHREGION_TXX__ -#define __MESHREGION_TXX__ - -#include "MeshRegion.hxx" - -#include "MeshElement.txx" -#include "MeshUtils.hxx" - -namespace INTERP_KERNEL -{ - - /** - * Default constructor - * - */ - template - MeshRegion::MeshRegion():_box(0) - { - } - - /** - * Destructor - * - */ - template - MeshRegion::~MeshRegion() - { - delete _box; - } - - /** - * Adds an element to the region, updating the bounding box. If the bounding box does not yet - * exist, it is created here. This creation is delayed to make it possible to have empty MeshRegions - * - * @param element pointer to element to add to region - * @param mesh mesh to which element belongs - * - */ - template - template - void MeshRegion::addElement(MeshElement* const element, const MyMeshType& mesh) - { - _elements.push_back(element); - - const unsigned char numNodes = element->getNumberOfNodes(); - const ConnType elemIdx = element->getIndex(); - - if(_box == 0) - { - const double** pts = new const double*[numNodes]; - - // get coordinates of the nodes of the element - for(unsigned char i = 0 ; i < numNodes ; ++i) - { - pts[i] = getCoordsOfNode(i, OTT::indFC(elemIdx), mesh); - } - - _box = new BoundingBox(pts, numNodes); - delete [] pts; - - } else { - - for(unsigned char i = 0 ; i < numNodes ; ++i) - { - const double* pt = getCoordsOfNode(i, OTT::indFC(elemIdx), mesh); - _box->updateWithPoint(pt); - } - } - } - - /** - * Splits the region in two along the given axis, copying the elements with bounding boxes whose maximum - * coordinate along the axis are smaller than the middle of the bounding box of this region in region1. The - * rest of the elements are copied to region2. - * - * @param region1 region in which to store one half of this region - * @param region2 region in which to store the other of this region - * @param coord coordinate of BoundingBox to use when splitting the region - * @param mesh mesh to which region belongs - * - */ - template - template - void MeshRegion::split(MeshRegion& region1, MeshRegion& region2, BoundingBox::BoxCoord coord, const MyMeshType& mesh) - { - // create ordering - ElementBBoxOrder cmp(coord); - - // sort elements by their bounding boxes - std::sort(_elements.begin(), _elements.end(), cmp); - - // put the first half of the elements in region1 and the - // rest in region2 - typename std::vector< MeshElement *>::const_iterator iter = _elements.begin(); - int elemCount = 0; - - while(elemCount < static_cast(_elements.size() / 2)) - { - region1.addElement(*iter, mesh); - ++iter; - ++elemCount; - } - - while(iter != _elements.end()) - { - region2.addElement(*iter, mesh); - ++iter; - } - } - - /** - * Determines if a given element can intersect the elements of this region by - * testing whether the bounding box of the region intersects the bounding box of the element. - * Note that the test is only true in one direction : if the bounding boxes are disjoint, the - * element cannot intersect any of the elements in the region, but if they are not disjoint, the - * element may or may not do so. - * - * @param elem Element with which to test for disjoint-ness - * @return true if the bounding box of the element is disjoint with the bounding box of the region, false otherwise - */ - template - bool MeshRegion::isDisjointWithElementBoundingBox(const MeshElement& elem) const - { - const BoundingBox* elemBox = elem.getBoundingBox(); - - assert(_box != 0); - assert(elemBox != 0); - - return _box->isDisjointWith(*elemBox); - } - - -} - -#endif diff --git a/src/INTERP_KERNEL/MeshUtils.hxx b/src/INTERP_KERNEL/MeshUtils.hxx deleted file mode 100644 index 6f751d134..000000000 --- a/src/INTERP_KERNEL/MeshUtils.hxx +++ /dev/null @@ -1,114 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 -// 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 __MESHUTILS_HXX__ -#define __MESHUTILS_HXX__ - -#include "InterpolationUtils.hxx" - -namespace INTERP_KERNEL -{ - /** - * Returns the global number of the node of an element. - * - * @param node the node for which the global number is sought (ALWAYS in C mode) - * @param element an element of the mesh (in numPol policy) - * @param mesh a mesh - * @return the node's global number so that (its coordinates in the coordinates array are at [SPACEDIM*globalNumber, SPACEDIM*globalNumber + SPACEDIM] - */ - template - inline typename MyMeshType::MyConnType getGlobalNumberOfNode(typename MyMeshType::MyConnType node, typename MyMeshType::MyConnType element, const MyMeshType& mesh) - { - typedef typename MyMeshType::MyConnType ConnType; - const NumberingPolicy numPol=MyMeshType::My_numPol; - const ConnType elemIdx=OTT::conn2C(mesh.getConnectivityIndexPtr()[OTT::ind2C(element)]); - if(mesh.getTypeOfElement(element)!=INTERP_KERNEL::NORM_POLYHED) - return OTT::coo2C(mesh.getConnectivityPtr()[elemIdx + node]); - else - { - const ConnType *startNodalConnOfElem=mesh.getConnectivityPtr()+elemIdx; - ConnType ptr=0,ret=0; - while(startNodalConnOfElem[ret]==-1 || ptr!=node) - { - ret++; - if(startNodalConnOfElem[ret]!=-1) - ptr++; - } - return OTT::coo2C(startNodalConnOfElem[ret]); - } - } - - /** - * Returns the coordinates of a node of an element - * - * @param node the node for which the coordinates are sought. In C mode. - * @param element an element of the mesh. In mesh policy. - * @param mesh a mesh - * @return pointer to an array of 3 doubles containing the coordinates of the node - */ - template - inline const double* getCoordsOfNode(typename MyMeshType::MyConnType node, typename MyMeshType::MyConnType element, const MyMeshType& mesh) - { - typedef typename MyMeshType::MyConnType ConnType; - const ConnType connIdx = getGlobalNumberOfNode(node, element, mesh); - const double *ret=mesh.getCoordinatesPtr()+MyMeshType::MY_SPACEDIM*connIdx; - return ret; - } - - /** - * Returns the coordinates of a node of an element - * - * @param node the node for which the coordinates are sought. In C mode. - * @param element an element of the mesh. In mesh policy. - * @param mesh a mesh - * @param nodeId globale nodeId in whole mesh point of view in C mode. - * @return pointer to an array of 3 doubles containing the coordinates of the node - */ - template - inline const double* getCoordsOfNode2(typename MyMeshType::MyConnType node, typename MyMeshType::MyConnType element, const MyMeshType& mesh, typename MyMeshType::MyConnType& nodeId) - { - nodeId= getGlobalNumberOfNode(node, element, mesh); - return mesh.getCoordinatesPtr()+MyMeshType::MY_SPACEDIM*nodeId; - } - - /** - * Returns the barycentric coordinates of a point within a triangle or tetrahedron - * - * @param point the point for which the barycentric coordinates are sought - * @param element an element of the mesh - * @param mesh a mesh - * @param barycentricCoords an array of 3 doubles containing the coordinates of the node - */ - template - inline void getBarycentricCoordinates(const double* point, - typename MyMeshType::MyConnType element, - const MyMeshType& mesh, - double* barycentricCoords) - { - std::vector nodes( NB_NODES ); - for ( int node = 0; node < NB_NODES; ++node ) - { - nodes[ node ] = getCoordsOfNode( node, element, mesh ); - } - barycentric_coords( nodes, point, barycentricCoords ); - } - -} - -#endif diff --git a/src/INTERP_KERNEL/Planar2D1DIntersectorP0P0.hxx b/src/INTERP_KERNEL/Planar2D1DIntersectorP0P0.hxx deleted file mode 100644 index 4356a1c21..000000000 --- a/src/INTERP_KERNEL/Planar2D1DIntersectorP0P0.hxx +++ /dev/null @@ -1,60 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 -// 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 __PLANAR2D1DINTERSECTORP0P0_HXX__ -#define __PLANAR2D1DINTERSECTORP0P0_HXX__ - -#include "PlanarIntersector.hxx" - -namespace INTERP_KERNEL -{ - template - class Planar2D1DIntersectorP0P0 : public PlanarIntersector - { - public: - static const int SPACEDIM=MyMeshType::MY_SPACEDIM; - static const int MESHDIM=MyMeshType::MY_MESHDIM; - typedef typename MyMeshType::MyConnType ConnType; - static const NumberingPolicy numPol=MyMeshType::My_numPol; - protected: - Planar2D1DIntersectorP0P0(const MyMeshType& meshT, const MyMeshType& meshS, - double dimCaracteristic, double precision, double md3DSurf, double minDot3DSurf, double medianPlane, bool doRotate, int orientation, int printLevel); - public: - int getNumberOfRowsOfResMatrix() const; - int getNumberOfColsOfResMatrix() const; - const typename PlanarIntersector::DuplicateFacesType* getIntersectFaces() const - { - return &_intersect_faces; - } - void intersectCells(ConnType icellT, const std::vector& icellsS, MyMatrix& res); - /*! - * Contrary to intersectCells method here icellS and icellT are \b not in \b C mode but in mode of MyMeshType. - */ - double intersectGeometry1D(ConnType icellT, ConnType icellS, ConnType nbNodesT, ConnType nbNodesS, - bool& isColinear) - { return asLeaf().intersectGeometry1D(icellT,icellS,nbNodesT,nbNodesS, isColinear); } - protected: - ConcreteP0P0Intersector& asLeaf() { return static_cast(*this); } - private: - typename PlanarIntersector::DuplicateFacesType _intersect_faces; - }; -} - -#endif diff --git a/src/INTERP_KERNEL/Planar2D1DIntersectorP0P0.txx b/src/INTERP_KERNEL/Planar2D1DIntersectorP0P0.txx deleted file mode 100644 index 848a8f592..000000000 --- a/src/INTERP_KERNEL/Planar2D1DIntersectorP0P0.txx +++ /dev/null @@ -1,81 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 -// 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 __PLANAR2D1DINTERSECTORP0P0_TXX__ -#define __PLANAR2D1DINTERSECTORP0P0_TXX__ - -#include "Planar2D1DIntersectorP0P0.hxx" - -namespace INTERP_KERNEL -{ - template - Planar2D1DIntersectorP0P0::Planar2D1DIntersectorP0P0(const MyMeshType& meshT, const MyMeshType& meshS, - double dimCaracteristic, double precision, double md3DSurf, double minDot3DSurf, double medianPlane, - bool doRotate, int orientation, int printLevel): - PlanarIntersector(meshT,meshS,dimCaracteristic,precision,md3DSurf,minDot3DSurf,medianPlane,doRotate,orientation,printLevel) - { - } - - template - int Planar2D1DIntersectorP0P0::getNumberOfRowsOfResMatrix() const - { - return PlanarIntersector::_meshT.getNumberOfElements(); - } - - template - int Planar2D1DIntersectorP0P0::getNumberOfColsOfResMatrix() const - { - return PlanarIntersector::_meshS.getNumberOfElements(); - } - - template - void Planar2D1DIntersectorP0P0::intersectCells(ConnType icellT, const std::vector& icellsS, MyMatrix& res) - { - int nbNodesT=PlanarIntersector::_connIndexT[icellT+1]-PlanarIntersector::_connIndexT[icellT]; - typename MyMatrix::value_type& resRow=res[icellT]; - for(typename std::vector::const_iterator iter=icellsS.begin();iter!=icellsS.end();iter++) - { - int iS=*iter; - int nbNodesS=PlanarIntersector::_connIndexS[iS+1]-PlanarIntersector::_connIndexS[iS]; - bool isColinear = false; - double surf=intersectGeometry1D(OTT::indFC(icellT),OTT::indFC(iS), - nbNodesT,nbNodesS, isColinear); - surf=PlanarIntersector::getValueRegardingOption(surf); - if(surf!=0.) - resRow.insert(std::make_pair(OTT::indFC(iS),surf)); - - if (isColinear) - { - typename PlanarIntersector::DuplicateFacesType::iterator intersectFacesIter = _intersect_faces.find(iS); - if (intersectFacesIter != _intersect_faces.end()) - { - intersectFacesIter->second.insert(icellT); - } - else - { - std::set targetCellSet; - targetCellSet.insert(icellT); - _intersect_faces.insert(std::make_pair(iS, targetCellSet)); - } - } - } - } -} - -#endif diff --git a/src/INTERP_KERNEL/PlanarIntersector.hxx b/src/INTERP_KERNEL/PlanarIntersector.hxx deleted file mode 100644 index b0662104c..000000000 --- a/src/INTERP_KERNEL/PlanarIntersector.hxx +++ /dev/null @@ -1,85 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 -// 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 __PLANARINTERSECTOR_HXX__ -#define __PLANARINTERSECTOR_HXX__ - -#include "TargetIntersector.hxx" -#include "NormalizedUnstructuredMesh.hxx" - -#include -#include - -namespace INTERP_KERNEL -{ - class TranslationRotationMatrix; - - template - class PlanarIntersector : public TargetIntersector - { - public: - static const int SPACEDIM=MyMeshType::MY_SPACEDIM; - static const int MESHDIM=MyMeshType::MY_MESHDIM; - typedef typename MyMeshType::MyConnType ConnType; - static const NumberingPolicy numPol=MyMeshType::My_numPol; - typedef typename std::map > DuplicateFacesType; - public: - PlanarIntersector(const MyMeshType& meshT, const MyMeshType& meshS, double dimCaracteristic, double precision, double md3DSurf, double minDot3DSurf, double medianPlane, bool doRotate, int orientation, int printLevel); - virtual ~PlanarIntersector(); - void createBoundingBoxes(const MyMeshType& mesh, std::vector& bbox); - void adjustBoundingBoxes(std::vector& bbox, double surf3DAdjustmentEps, double surf3DAdjustmentEpsAbs); - inline void getElemBB(double* bb, const MyMeshType& mesh, ConnType iP, ConnType nb_nodes); - static int Projection(double *Coords_A, double *Coords_B, - int nb_NodesA, int nb_NodesB, double epsilon, double md3DSurf, double minDot3DSurf, double median_plane, bool do_rotate); - virtual const DuplicateFacesType* getIntersectFaces() const - { - return NULL; - } - protected : - int projectionThis(double *Coords_A, double *Coords_B, int nb_NodesA, int nb_NodesB); - void getRealTargetCoordinates(ConnType icellT, std::vector& coordsT); - void getRealSourceCoordinates(ConnType icellS, std::vector& coordsS); - void getRealTargetCoordinatesPermute(ConnType icellT, int offset, std::vector& coordsT); - void getRealSourceCoordinatesPermute(ConnType icellS, int offset, std::vector& coordsS); - void getRealCoordinates(ConnType icellT, ConnType icellS, ConnType nbNodesT, ConnType nbNodesS, std::vector& coordsT, std::vector& coordsS, int& orientation); - double getValueRegardingOption(double val) const; - static void rotate3DTriangle( double* PP1, double*PP2, double*PP3, - TranslationRotationMatrix& rotation_matrix); - protected: - const ConnType *_connectT; - const ConnType *_connectS; - const double *_coordsT; - const double *_coordsS; - const ConnType *_connIndexT; - const ConnType *_connIndexS; - const MyMeshType& _meshT; - const MyMeshType& _meshS; - double _dim_caracteristic; - double _max_distance_3Dsurf_intersect; - double _min_dot_btw_3Dsurf_intersect; - double _precision; - double _median_plane; - bool _do_rotate; - int _orientation; - int _print_level; - }; -} - -#endif diff --git a/src/INTERP_KERNEL/PlanarIntersector.txx b/src/INTERP_KERNEL/PlanarIntersector.txx deleted file mode 100644 index ebaf24cb0..000000000 --- a/src/INTERP_KERNEL/PlanarIntersector.txx +++ /dev/null @@ -1,447 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 -// 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 __PLANARINTERSECTOR_TXX__ -#define __PLANARINTERSECTOR_TXX__ - -#include "PlanarIntersector.hxx" -#include "InterpolationUtils.hxx" -#include "TranslationRotationMatrix.hxx" - -#include -#include - -namespace INTERP_KERNEL -{ - template - PlanarIntersector::PlanarIntersector(const MyMeshType& meshT, const MyMeshType& meshS, double dimCaracteristic, double precision, double md3DSurf, double minDot3DSurf, double medianPlane, bool doRotate, int orientation, int printLevel): - _meshT(meshT),_meshS(meshS), - _dim_caracteristic(dimCaracteristic),_max_distance_3Dsurf_intersect(md3DSurf),_min_dot_btw_3Dsurf_intersect(minDot3DSurf),_precision(precision),_median_plane(medianPlane), - _do_rotate(doRotate),_orientation(orientation),_print_level(printLevel) - { - _connectT=meshT.getConnectivityPtr(); - _connectS=meshS.getConnectivityPtr(); - _connIndexT=meshT.getConnectivityIndexPtr(); - _connIndexS=meshS.getConnectivityIndexPtr(); - _coordsT=meshT.getCoordinatesPtr(); - _coordsS=meshS.getCoordinatesPtr(); - } - - template - PlanarIntersector::~PlanarIntersector() - { - } - - /*! - \brief creates the bounding boxes for all the cells of mesh \a mesh - - The method accepts mixed meshes (containing triangles and quadrangles). - The vector returned is of dimension 6*nb_elems with bounding boxes stored as xmin1, xmax1, ymin1, ymax1, zmin1, zmax1, xmin2, xmax2, ymin2,... - The returned pointer must be deleted by the calling code. - - \param mesh structure pointing to the mesh - \param bbox vector containing the bounding boxes - */ - template - void PlanarIntersector::createBoundingBoxes(const MyMeshType& mesh, std::vector& bbox) - { - /* We build the segment tree for locating possible matching intersections*/ - long nbelems = mesh.getNumberOfElements(); - bbox.resize(2*SPACEDIM* nbelems); - const double* coords = mesh.getCoordinatesPtr(); - const ConnType* conn = mesh.getConnectivityPtr(); - const ConnType* conn_index = mesh.getConnectivityIndexPtr(); - int ibox=0; - for(long icell=0; icell::max(); - bbox[2*SPACEDIM*ibox+2*idim+1] = -std::numeric_limits::max(); - } - //updating the bounding box with each node of the element - for (int j=0; j::coo2C(conn[OTT::conn2C(conn_index[icell]+j)]); - for(int idim=0; idimx)?bbox[ibox*2*SPACEDIM + 2*idim+1]:x; - } - } - ibox++; - } - } - - /*! - Computes the bouding box of a given element. iP in numPol mode. - */ - template - void PlanarIntersector::getElemBB(double* bb, const MyMeshType& mesh, ConnType iP, ConnType nb_nodes) - { - const double* coords = mesh.getCoordinatesPtr(); - const ConnType* conn_index = mesh.getConnectivityIndexPtr(); - const ConnType* conn = mesh.getConnectivityPtr(); - //initializing bounding box limits - for(int idim=0; idim::max(); - bb[2*idim+1] = -std::numeric_limits::max(); - } - - for (ConnType i=0; i::coo2C(conn[OTT::conn2C(conn_index[OTT::ind2C(iP)]+i)])); - for(int idim=0; idimbb[2*idim+1])?x:bb[2*idim+1]; - } - } - } - - /*! Readjusts a set of bounding boxes so that they are extended - in all dimensions for avoiding missing interesting intersections - - \param bbox vector containing the bounding boxes - */ - template - void PlanarIntersector::adjustBoundingBoxes(std::vector& bbox, double surf3DAdjustmentEps, double surf3DAdjustmentEpsAbs) - { - /* We build the segment tree for locating possible matching intersections*/ - - long size = bbox.size()/(2*SPACEDIM); - for (int i=0; i::max(); - for(int idim=0; idim - void PlanarIntersector::getRealTargetCoordinates(ConnType icellT, std::vector& coordsT) - { - int nbNodesT=_connIndexT[OTT::ind2C(icellT)+1]-_connIndexT[OTT::ind2C(icellT)]; - coordsT.resize(SPACEDIM*nbNodesT); - for (ConnType iT=0; iT::coo2C(_connectT[OTT::conn2C(_connIndexT[OTT::ind2C(icellT)]+iT)])+idim]; - } - - /*! - * @param icellS id in source mesh in format of MyMeshType. - * @param coordsS output val that stores coordinates of the source cell automatically resized to the right length. - */ - template - void PlanarIntersector::getRealSourceCoordinates(ConnType icellS, std::vector& coordsS) - { - int nbNodesS=_connIndexS[OTT::ind2C(icellS)+1]-_connIndexS[OTT::ind2C(icellS)]; - coordsS.resize(SPACEDIM*nbNodesS); - for (ConnType iS=0; iS::coo2C(_connectS[OTT::conn2C(_connIndexS[OTT::ind2C(icellS)]+iS)])+idim]; - } - - /*! - * @param icellT id in target mesh in format of MyMeshType. - * @param offset is a value in C format that indicates the number of circular permutation. - * @param coordsT output val that stores coordinates of the target cell automatically resized to the right length. - */ - template - void PlanarIntersector::getRealTargetCoordinatesPermute(ConnType icellT, int offset, std::vector& coordsT) - { - int nbNodesT=_connIndexT[OTT::ind2C(icellT)+1]-_connIndexT[OTT::ind2C(icellT)]; - coordsT.resize(SPACEDIM*nbNodesT); - for (ConnType iTTmp=0; iTTmp::coo2C(_connectT[OTT::conn2C(_connIndexT[OTT::ind2C(icellT)]+iT)])+idim]; - } - } - - /*! - * @param icellS id in source mesh in format of MyMeshType. - * @param offset is a value in C format that indicates the number of circular permutation. - * @param coordsS output val that stores coordinates of the source cell automatically resized to the right length. - */ - template - void PlanarIntersector::getRealSourceCoordinatesPermute(ConnType icellS, int offset, std::vector& coordsS) - { - int nbNodesS=_connIndexS[OTT::ind2C(icellS)+1]-_connIndexS[OTT::ind2C(icellS)]; - coordsS.resize(SPACEDIM*nbNodesS); - for (ConnType iSTmp=0; iSTmp::coo2C(_connectS[OTT::conn2C(_connIndexS[OTT::ind2C(icellS)]+iS)])+idim]; - } - } - - /*! - * @param icellT id in target mesh in format of MyMeshType. - * @param icellS id in source mesh in format of MyMeshType. - * @param nbNodesT nb of nodes of the target cell. - * @param nbNodesS nb of nodes of the source cell. - * @param coordsT output val that stores coordinates of the target cell automatically resized to the right length. - * @param coordsS output val that stores coordinates of the source cell automatically resized to the right length. - * @param orientation is an output value too, only set if SPACEDIM==3. - */ - template - void PlanarIntersector::getRealCoordinates(ConnType icellT, ConnType icellS, ConnType nbNodesT, ConnType nbNodesS, std::vector& coordsT, std::vector& coordsS, int& orientation) - { - coordsT.resize(SPACEDIM*nbNodesT); - coordsS.resize(SPACEDIM*nbNodesS); - for (int idim=0; idim::coo2C(_connectT[OTT::conn2C(_connIndexT[OTT::ind2C(icellT)]+iT)])+idim]; - for (ConnType iS=0; iS::coo2C(_connectS[OTT::conn2C(_connIndexS[OTT::ind2C(icellS)]+iS)])+idim]; - } - - //project cells T and S on the median plane and rotate the median plane - if(SPACEDIM==3) - orientation = projectionThis(&coordsT[0], &coordsS[0], nbNodesT, nbNodesS); - - //DEBUG PRINTS - if(_print_level >= 3) - { - std::cout << std::endl << "Cell coordinates (possibly after projection)" << std::endl; - std::cout << std::endl << "icellT= " << icellT << ", nb nodes T= " << nbNodesT << std::endl; - for(int iT =0; iT< nbNodesT; iT++) - {for (int idim=0; idim - double PlanarIntersector::getValueRegardingOption(double val) const - { - if(_orientation==0) - return val; - if(_orientation==2) - return fabs(val); - if (( val > 0.0 && _orientation==1) || ( val < 0.0 && _orientation==-1 )) - return _orientation*val; - return 0.; - } - - template - int PlanarIntersector::projectionThis(double *Coords_A, double *Coords_B, int nb_NodesA, int nb_NodesB) - { - return Projection(Coords_A,Coords_B,nb_NodesA,nb_NodesB,_dim_caracteristic*_precision,_max_distance_3Dsurf_intersect,_min_dot_btw_3Dsurf_intersect,_median_plane,_do_rotate); - } - - template - int PlanarIntersector::Projection(double *Coords_A, double *Coords_B, - int nb_NodesA, int nb_NodesB, double epsilon, double md3DSurf, double minDot3DSurf, double median_plane, bool do_rotate) - { - double normal_A[3]={0,0,0}; - double normal_B[3]={0,0,0}; - double linear_comb[3]; - double proj; - bool same_orientation; - - //Find the normal to cells A and B - int i_A1(1); - while(i_A1(Coords_A,&Coords_A[SPACEDIM*i_A1])< epsilon) - i_A1++; - int i_A2(i_A1+1); - crossprod(Coords_A, &Coords_A[SPACEDIM*i_A1], &Coords_A[SPACEDIM*i_A2],normal_A); - double normA(sqrt(dotprod(normal_A,normal_A))); - while(i_A2(Coords_A, &Coords_A[SPACEDIM*i_A1], &Coords_A[SPACEDIM*i_A2],normal_A); - i_A2++; - normA = sqrt(dotprod(normal_A,normal_A)); - - } - int i_B1(1); - while(i_B1(Coords_B,Coords_B+SPACEDIM*i_B1)< epsilon) - i_B1++; - int i_B2(i_B1+1); - crossprod(Coords_B, Coords_B+SPACEDIM*i_B1, Coords_B+SPACEDIM*i_B2,normal_B); - double normB(sqrt(dotprod(normal_B,normal_B))); - while(i_B2(Coords_B, Coords_B+SPACEDIM*i_B1, Coords_B+SPACEDIM*i_B2,normal_B); - i_B2++; - normB = sqrt(dotprod(normal_B,normal_B)); - } - - //fabien option - if(md3DSurf>0.) - { - double coords_GA[3]; - for(int i=0;i<3;i++) - { - coords_GA[i]=0.; - for (int j=0;jmd3DSurf) - return 0; - } - if(i_A2(normal_A,normal_B)/(normA*normB)); - - if(fabs(dotProd)=0); - - if(!same_orientation) - for(int idim =0; idim< SPACEDIM; idim++) - normal_A[idim] *=-1; - - double normBB(sqrt(dotprod(normal_B,normal_B))); - - for(int idim =0; idim< SPACEDIM; idim++) - linear_comb[idim] = median_plane*normal_A[idim]/normA + (1-median_plane)*normal_B[idim]/normBB; - double norm= sqrt(dotprod(linear_comb,linear_comb)); - - //Necessarily: norm>epsilon, no need to check - for(int idim =0; idim< SPACEDIM; idim++) - linear_comb[idim]/=norm; - - //Project the nodes of A and B on the median plane - for(int i_A=0; i_A(&Coords_A[SPACEDIM*i_A],linear_comb); - for(int idim =0; idim< SPACEDIM; idim++) - Coords_A[SPACEDIM*i_A+idim] -= proj*linear_comb[idim]; - } - for(int i_B=0; i_B(Coords_B+SPACEDIM*i_B,linear_comb); - for(int idim =0; idim< SPACEDIM; idim++) - Coords_B[SPACEDIM*i_B+idim] -= proj*linear_comb[idim]; - } - - //Buid the matrix sending A into the Oxy plane and apply it to A and B - if(do_rotate) - { - TranslationRotationMatrix rotation; - //rotate3DTriangle(Coords_A, &Coords_A[SPACEDIM*i_A1], &Coords_A[SPACEDIM*i_A2], rotation); - rotate3DTriangle(Coords_B, Coords_B+SPACEDIM*i_B1, Coords_B+SPACEDIM*i_B2, rotation); - for (int i=0; i(Coords_A,&Coords_A[i_A1])= " << distance2(Coords_A,&Coords_A[i_A1]) << std::endl; - std::cout << "abs(normal_A) = " << fabs(normal_A[0]) << " ; " <(&Coords_B[0],&Coords_B[i_B1])= " << distance2(Coords_B,Coords_B+i_B1) << std::endl; - std::cout << "normal_B = " << normal_B[0] << " ; " << normal_B[1] << " ; " << normal_B[2] << std::endl; - return 1; - } - } - - template - void PlanarIntersector::rotate3DTriangle(double* PP1, double*PP2, double*PP3, - TranslationRotationMatrix& rotation_matrix) - { - //initializes - rotation_matrix.translate(PP1); - - double P2w[3]; - double P3w[3]; - P2w[0]=PP2[0]; P2w[1]=PP2[1];P2w[2]=PP2[2]; - P3w[0]=PP3[0]; P3w[1]=PP3[1];P3w[2]=PP3[2]; - - // translating to set P1 at the origin - for (int i=0; i<3; i++) - { - P2w[i]-=PP1[i]; - P3w[i]-=PP1[i]; - } - - // rotating to set P2 on the Oxy plane - TranslationRotationMatrix A; - A.rotate_x(P2w); - A.rotate_vector(P3w); - rotation_matrix.multiply(A); - - //rotating to set P2 on the Ox axis - TranslationRotationMatrix B; - B.rotate_z(P2w); - B.rotate_vector(P3w); - rotation_matrix.multiply(B); - - //rotating to set P3 on the Oxy plane - TranslationRotationMatrix C; - C.rotate_x(P3w); - rotation_matrix.multiply(C); - } -} - -#endif diff --git a/src/INTERP_KERNEL/PlanarIntersectorP0P0.hxx b/src/INTERP_KERNEL/PlanarIntersectorP0P0.hxx deleted file mode 100644 index c20275ec6..000000000 --- a/src/INTERP_KERNEL/PlanarIntersectorP0P0.hxx +++ /dev/null @@ -1,51 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 -// 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 __PLANARINTERSECTORP0P0_HXX__ -#define __PLANARINTERSECTORP0P0_HXX__ - -#include "PlanarIntersector.hxx" - -namespace INTERP_KERNEL -{ - template - class PlanarIntersectorP0P0 : public PlanarIntersector - { - public: - static const int SPACEDIM=MyMeshType::MY_SPACEDIM; - static const int MESHDIM=MyMeshType::MY_MESHDIM; - typedef typename MyMeshType::MyConnType ConnType; - static const NumberingPolicy numPol=MyMeshType::My_numPol; - protected: - PlanarIntersectorP0P0(const MyMeshType& meshT, const MyMeshType& meshS, double dimCaracteristic, double precision, double md3DSurf, double minDot3DSurf, double medianPlane, bool doRotate, int orientation, int printLevel); - public: - int getNumberOfRowsOfResMatrix() const; - int getNumberOfColsOfResMatrix() const; - void intersectCells(ConnType icellT, const std::vector& icellsS, MyMatrix& res); - /*! - * Contrary to intersectCells method here icellS and icellT are \b not in \b C mode but in mode of MyMeshType. - */ - double intersectGeometry(ConnType icellT, ConnType icellS, ConnType nbNodesT, ConnType nbNodesS) { return asLeaf().intersectGeometry(icellT,icellS,nbNodesT,nbNodesS); } - protected: - ConcreteP0P0Intersector& asLeaf() { return static_cast(*this); } - }; -} - -#endif diff --git a/src/INTERP_KERNEL/PlanarIntersectorP0P0.txx b/src/INTERP_KERNEL/PlanarIntersectorP0P0.txx deleted file mode 100644 index 35e44ee80..000000000 --- a/src/INTERP_KERNEL/PlanarIntersectorP0P0.txx +++ /dev/null @@ -1,64 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 -// 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 __PLANARINTERSECTORP0P0_TXX__ -#define __PLANARINTERSECTORP0P0_TXX__ - -#include "PlanarIntersectorP0P0.hxx" - -namespace INTERP_KERNEL -{ - template - PlanarIntersectorP0P0::PlanarIntersectorP0P0(const MyMeshType& meshT, const MyMeshType& meshS, - double dimCaracteristic, double precision, double md3DSurf, double minDot3DSurf, double medianPlane, - bool doRotate, int orientation, int printLevel): - PlanarIntersector(meshT,meshS,dimCaracteristic,precision,md3DSurf,minDot3DSurf,medianPlane,doRotate,orientation,printLevel) - { - } - - template - int PlanarIntersectorP0P0::getNumberOfRowsOfResMatrix() const - { - return PlanarIntersector::_meshT.getNumberOfElements(); - } - - template - int PlanarIntersectorP0P0::getNumberOfColsOfResMatrix() const - { - return PlanarIntersector::_meshS.getNumberOfElements(); - } - - template - void PlanarIntersectorP0P0::intersectCells(ConnType icellT, const std::vector& icellsS, MyMatrix& res) - { - int nbNodesT=PlanarIntersector::_connIndexT[icellT+1]-PlanarIntersector::_connIndexT[icellT]; - typename MyMatrix::value_type& resRow=res[icellT]; - for(typename std::vector::const_iterator iter=icellsS.begin();iter!=icellsS.end();iter++) - { - int iS=*iter; - int nbNodesS=PlanarIntersector::_connIndexS[iS+1]-PlanarIntersector::_connIndexS[iS]; - double surf=intersectGeometry(OTT::indFC(icellT),OTT::indFC(iS),nbNodesT,nbNodesS); - surf=PlanarIntersector::getValueRegardingOption(surf); - if(surf!=0.) - resRow.insert(std::make_pair(OTT::indFC(iS),surf)); - } - } -} - -#endif diff --git a/src/INTERP_KERNEL/PlanarIntersectorP0P1.hxx b/src/INTERP_KERNEL/PlanarIntersectorP0P1.hxx deleted file mode 100644 index bedddac9d..000000000 --- a/src/INTERP_KERNEL/PlanarIntersectorP0P1.hxx +++ /dev/null @@ -1,51 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 -// 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 __PLANARINTERSECTORP0P1_HXX__ -#define __PLANARINTERSECTORP0P1_HXX__ - -#include "PlanarIntersector.hxx" - -namespace INTERP_KERNEL -{ - template - class PlanarIntersectorP0P1 : public PlanarIntersector - { - public: - static const int SPACEDIM=MyMeshType::MY_SPACEDIM; - static const int MESHDIM=MyMeshType::MY_MESHDIM; - typedef typename MyMeshType::MyConnType ConnType; - static const NumberingPolicy numPol=MyMeshType::My_numPol; - protected: - PlanarIntersectorP0P1(const MyMeshType& meshT, const MyMeshType& meshS, double dimCaracteristic, double precision, double md3DSurf, double minDot3DSurf, double medianPlane, bool doRotate, int orientation, int printLevel); - public: - void intersectCells(ConnType icellT, const std::vector& icellsS, MyMatrix& res); - int getNumberOfRowsOfResMatrix() const; - int getNumberOfColsOfResMatrix() const; - /*! - * Contrary to intersectCells method here icellS and icellT are \b not in \b C mode but in mode of MyMeshType. - */ - double intersectGeometryWithQuadrangle(const double *quadrangle, const std::vector& sourceCoords, bool isSourceQuad) { return asLeaf().intersectGeometryWithQuadrangle(quadrangle,sourceCoords,isSourceQuad); } - protected: - ConcreteP0P1Intersector& asLeaf() { return static_cast(*this); } - }; -} - -#endif diff --git a/src/INTERP_KERNEL/PlanarIntersectorP0P1.txx b/src/INTERP_KERNEL/PlanarIntersectorP0P1.txx deleted file mode 100644 index 427b14b98..000000000 --- a/src/INTERP_KERNEL/PlanarIntersectorP0P1.txx +++ /dev/null @@ -1,104 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 -// 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 __PLANARINTERSECTORP0P1_TXX__ -#define __PLANARINTERSECTORP0P1_TXX__ - -#include "PlanarIntersectorP0P1.hxx" -#include "InterpolationUtils.hxx" -#include "CellModel.hxx" - -namespace INTERP_KERNEL -{ - template - PlanarIntersectorP0P1::PlanarIntersectorP0P1(const MyMeshType& meshT, const MyMeshType& meshS, - double dimCaracteristic, double precision, double md3DSurf, double minDot3DSurf, double medianPlane, - bool doRotate, int orientation, int printLevel): - PlanarIntersector(meshT,meshS,dimCaracteristic,precision,md3DSurf,minDot3DSurf,medianPlane,doRotate,orientation,printLevel) - { - } - - template - int PlanarIntersectorP0P1::getNumberOfRowsOfResMatrix() const - { - return PlanarIntersector::_meshT.getNumberOfNodes(); - } - - template - int PlanarIntersectorP0P1::getNumberOfColsOfResMatrix() const - { - return PlanarIntersector::_meshS.getNumberOfElements(); - } - - /*! - * This methods split on the fly, into triangles in order to compute dual mesh of target cell (with icellT id in target mesh in C mode). - */ - template - void PlanarIntersectorP0P1::intersectCells(ConnType icellT, const std::vector& icellsS, MyMatrix& res) - { - int nbNodesT=PlanarIntersector::_connIndexT[icellT+1]-PlanarIntersector::_connIndexT[icellT]; - double triangle[9]; - double quadrangle[12]; - std::vector sourceCellCoords; - int orientation=1; - const ConnType *startOfCellNodeConn=PlanarIntersector::_connectT+OTT::conn2C(PlanarIntersector::_connIndexT[icellT]); - for(int nodeIdT=0;nodeIdT::coo2C(startOfCellNodeConn[nodeIdT]); - std::copy(PlanarIntersector::_coordsT+curNodeTInCmode*SPACEDIM, - PlanarIntersector::_coordsT+curNodeTInCmode*SPACEDIM+SPACEDIM,triangle); - typename MyMatrix::value_type& resRow=res[curNodeTInCmode]; - for(typename std::vector::const_iterator iter=icellsS.begin();iter!=icellsS.end();iter++) - { - int iS=*iter; - PlanarIntersector::getRealSourceCoordinates(OTT::indFC(iS),sourceCellCoords); - for(int subTriT=1;subTriT<=nbNodesT-2;subTriT++) - { - std::copy(PlanarIntersector::_coordsT+OTT::coo2C(startOfCellNodeConn[(nodeIdT+subTriT)%nbNodesT])*SPACEDIM, - PlanarIntersector::_coordsT+OTT::coo2C(startOfCellNodeConn[(nodeIdT+subTriT)%nbNodesT])*SPACEDIM+SPACEDIM, - triangle+SPACEDIM); - std::copy(PlanarIntersector::_coordsT+OTT::coo2C(startOfCellNodeConn[(nodeIdT+subTriT+1)%nbNodesT])*SPACEDIM, - PlanarIntersector::_coordsT+OTT::coo2C(startOfCellNodeConn[(nodeIdT+subTriT+1)%nbNodesT])*SPACEDIM+SPACEDIM, - triangle+2*SPACEDIM); - fillDualCellOfTri(triangle,quadrangle); - std::vector sourceCellCoordsTmp(sourceCellCoords); - if(SPACEDIM==3) - orientation=PlanarIntersector::projectionThis(&sourceCellCoordsTmp[0],quadrangle,sourceCellCoords.size()/SPACEDIM,4); - NormalizedCellType tS=PlanarIntersector::_meshS.getTypeOfElement(OTT::indFC(iS)); - double surf=orientation*intersectGeometryWithQuadrangle(quadrangle,sourceCellCoordsTmp,CellModel::GetCellModel(tS).isQuadratic()); - surf=PlanarIntersector::getValueRegardingOption(surf); - if(surf!=0.) - { - typename MyMatrix::value_type::const_iterator iterRes=resRow.find(OTT::indFC(iS)); - if(iterRes==resRow.end()) - resRow.insert(std::make_pair(OTT::indFC(iS),surf)); - else - { - double val=(*iterRes).second+surf; - resRow.erase(OTT::indFC(iS)); - resRow.insert(std::make_pair(OTT::indFC(iS),val)); - } - } - } - } - } - } -} - -#endif diff --git a/src/INTERP_KERNEL/PlanarIntersectorP0P1Bary.hxx b/src/INTERP_KERNEL/PlanarIntersectorP0P1Bary.hxx deleted file mode 100644 index b4380b164..000000000 --- a/src/INTERP_KERNEL/PlanarIntersectorP0P1Bary.hxx +++ /dev/null @@ -1,55 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 -// 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 __PlanarIntersectorP0P1Bary_HXX__ -#define __PlanarIntersectorP0P1Bary_HXX__ - -#include "PlanarIntersector.hxx" - -namespace INTERP_KERNEL -{ - template - class PlanarIntersectorP0P1Bary : public PlanarIntersector - { - public: - static const int SPACEDIM=MyMeshType::MY_SPACEDIM; - static const int MESHDIM=MyMeshType::MY_MESHDIM; - typedef typename MyMeshType::MyConnType ConnType; - static const NumberingPolicy numPol=MyMeshType::My_numPol; - protected: - PlanarIntersectorP0P1Bary(const MyMeshType& meshT, const MyMeshType& meshS, double dimCaracteristic, double precision, double md3DSurf, double minDot3DSurf, double medianPlane, bool doRotate, int orientation, int printLevel); - public: - void intersectCells(ConnType icellT, const std::vector& icellsS, MyMatrix& res); - int getNumberOfRowsOfResMatrix() const; - int getNumberOfColsOfResMatrix() const; - /*! - * Contrary to intersectCells method here icellS and icellT are \b not in \b C mode but in mode of MyMeshType. - */ - double intersectGeoBary(const std::vector& sourceCell, - bool sourceCellQuadratic, - const double * targetTria, - std::vector& res) - { return asLeaf().intersectGeoBary(sourceCell,sourceCellQuadratic,targetTria,res); } - protected: - ConcreteP0P1Intersector& asLeaf() { return static_cast(*this); } - }; -} - -#endif diff --git a/src/INTERP_KERNEL/PlanarIntersectorP0P1Bary.txx b/src/INTERP_KERNEL/PlanarIntersectorP0P1Bary.txx deleted file mode 100644 index 66c34174a..000000000 --- a/src/INTERP_KERNEL/PlanarIntersectorP0P1Bary.txx +++ /dev/null @@ -1,115 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 -// 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 __PlanarIntersectorP0P1Bary_TXX__ -#define __PlanarIntersectorP0P1Bary_TXX__ - -#include "PlanarIntersectorP0P1Bary.hxx" -#include "InterpolationUtils.hxx" - -namespace INTERP_KERNEL -{ - template - PlanarIntersectorP0P1Bary::PlanarIntersectorP0P1Bary(const MyMeshType& meshT, const MyMeshType& meshS, - double dimCaracteristic, double precision, - double md3DSurf, double minDot3DSurf, double medianPlane, - bool doRotate, int orientation, int printLevel): - PlanarIntersector(meshT,meshS,dimCaracteristic,precision,md3DSurf,minDot3DSurf, - medianPlane,doRotate,orientation,printLevel) - { - // SPEC: - // "Limitation. For the P0P1 barycentric improvement only triangle target cells in 2D and - // tetrahedrons in 3D will be supported by interpolators. If a non - // triangle/tetrahedron source cell is detected an INTERP_KERNEL::Exception should be thrown." - - // Check types of source elements here rather than in intersectCells() since a wrong type can be - // found late after a long time of calculation. - - const unsigned long numTrgElems = meshT.getNumberOfElements(); - for(unsigned long i = 0 ; i < numTrgElems ; ++i) - if ( meshT.getTypeOfElement( OTT::indFC( i )) != NORM_TRI3 ) - throw INTERP_KERNEL::Exception("P0P1 barycentric algorithm works only with triangular target meshes"); - } - - template - int PlanarIntersectorP0P1Bary::getNumberOfRowsOfResMatrix() const - { - return PlanarIntersector::_meshT.getNumberOfNodes(); - } - - template - int PlanarIntersectorP0P1Bary::getNumberOfColsOfResMatrix() const - { - return PlanarIntersector::_meshS.getNumberOfElements(); - } - - /*! - * This method computes a value per each node of each source triangle for target. - */ - template - void PlanarIntersectorP0P1Bary::intersectCells(ConnType icellT, const std::vector& icellsS, MyMatrix& res) - { - int orientation=1; - std::vector trgTriaCoords,trgTriaCoordsTmp; - // target cell data - PlanarIntersector::getRealTargetCoordinates(OTT::indFC(icellT),trgTriaCoords); - std::vector *tgtCoords(&trgTriaCoords); - const ConnType *startOfCellNodeConn=PlanarIntersector::_connectT+OTT::conn2C(PlanarIntersector::_connIndexT[icellT]); - // treat each source cells - for(typename std::vector::const_iterator iter=icellsS.begin();iter!=icellsS.end();iter++) - { - std::vector srcCellCoords,srcCellCoordsTmp,nodeCeffs; - int iS=*iter; - NormalizedCellType tS=PlanarIntersector::_meshS.getTypeOfElement(OTT::indFC(iS)); - bool isSourceQuad=CellModel::GetCellModel(tS).isQuadratic(); - PlanarIntersector::getRealSourceCoordinates(OTT::indFC(iS),srcCellCoords); - std::vector *srcCoords(&srcCellCoords); - int srcNbNodes = srcCellCoords.size()/SPACEDIM; - if(SPACEDIM==3) - { - srcCellCoordsTmp=srcCellCoords; - trgTriaCoordsTmp=trgTriaCoords; - srcCoords=&srcCellCoordsTmp; - tgtCoords=&trgTriaCoordsTmp; - orientation=PlanarIntersector::projectionThis(&trgTriaCoordsTmp[0],&srcCellCoordsTmp[0], - 3,srcNbNodes); - } - //double surf=orientation*intersectGeometryWithQuadrangle(quadrangle,targetCellCoordsTmp,isTargetQuad); - double surf=orientation*intersectGeoBary(*srcCoords,isSourceQuad,&((*tgtCoords)[0]),nodeCeffs); - surf=PlanarIntersector::getValueRegardingOption(surf); - if(surf!=0.) - { - for(int nodeIdT=0;nodeIdT<3;nodeIdT++) - { - ConnType curNodeT=startOfCellNodeConn[nodeIdT]; - typename MyMatrix::value_type& resRow=res[curNodeT]; - typename MyMatrix::value_type::const_iterator iterRes=resRow.find(*iter); - if(iterRes!=resRow.end()) - { - nodeCeffs[*iter] += iterRes->second; - resRow.erase(*iter); - } - resRow.insert(std::make_pair(*iter,nodeCeffs[nodeIdT])); - } - } - } - } -} -#endif diff --git a/src/INTERP_KERNEL/PlanarIntersectorP0P1PL.hxx b/src/INTERP_KERNEL/PlanarIntersectorP0P1PL.hxx deleted file mode 100644 index d04e2da59..000000000 --- a/src/INTERP_KERNEL/PlanarIntersectorP0P1PL.hxx +++ /dev/null @@ -1,44 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 -// 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 __PLANARINTERSECTORP0P1PL_HXX__ -#define __PLANARINTERSECTORP0P1PL_HXX__ - -#include "PlanarIntersector.hxx" - -namespace INTERP_KERNEL -{ - template - class PlanarIntersectorP0P1PL : public PlanarIntersector - { - public: - static const int SPACEDIM=MyMeshType::MY_SPACEDIM; - static const int MESHDIM=MyMeshType::MY_MESHDIM; - typedef typename MyMeshType::MyConnType ConnType; - static const NumberingPolicy numPol=MyMeshType::My_numPol; - public: - PlanarIntersectorP0P1PL(const MyMeshType& meshT, const MyMeshType& meshS, double dimCaracteristic, double md3DSurf, double minDot3DSurf, double medianPlane, double precision, int orientation); - void intersectCells(ConnType icellT, const std::vector& icellsS, MyMatrix& res); - int getNumberOfRowsOfResMatrix() const; - int getNumberOfColsOfResMatrix() const; - }; -} - -#endif diff --git a/src/INTERP_KERNEL/PlanarIntersectorP0P1PL.txx b/src/INTERP_KERNEL/PlanarIntersectorP0P1PL.txx deleted file mode 100644 index abb6cd8c5..000000000 --- a/src/INTERP_KERNEL/PlanarIntersectorP0P1PL.txx +++ /dev/null @@ -1,84 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 -// 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 __PLANARINTERSECTORP0P1PL_TXX__ -#define __PLANARINTERSECTORP0P1PL_TXX__ - -#include "PlanarIntersectorP0P1PL.hxx" -#include "PlanarIntersector.txx" -#include "CellModel.hxx" - -#include "PointLocatorAlgos.txx" - -namespace INTERP_KERNEL -{ - template - PlanarIntersectorP0P1PL::PlanarIntersectorP0P1PL(const MyMeshType& meshT, const MyMeshType& meshS, - double dimCaracteristic, double md3DSurf, double minDot3DSurf, - double medianPlane, double precision, int orientation): - PlanarIntersector(meshT,meshS,dimCaracteristic,precision,md3DSurf,minDot3DSurf,medianPlane,true,orientation,0) - { - } - - template - void PlanarIntersectorP0P1PL::intersectCells(ConnType icellT, const std::vector& icellsS, MyMatrix& res) - { - std::vector< std::vector > coordsOfSources(icellsS.size()); - int ii=0; - for(typename std::vector::const_iterator iter=icellsS.begin();iter!=icellsS.end();iter++,ii++) - PlanarIntersector::getRealSourceCoordinates(OTT::indFC(*iter),coordsOfSources[ii]); - const ConnType *startOfCellNodeConnT=PlanarIntersector::_connectT+OTT::conn2C(PlanarIntersector::_connIndexT[icellT]); - std::vector coordsTarget; - PlanarIntersector::getRealTargetCoordinates(OTT::indFC(icellT),coordsTarget); - int nbNodesT=coordsTarget.size()/SPACEDIM; - ii=0; - for(typename std::vector::const_iterator iter2=icellsS.begin();iter2!=icellsS.end();iter2++,ii++) - { - std::vector tmpSource(coordsOfSources[ii]); - std::vector tmpTarget(coordsTarget); - if(SPACEDIM==3) - PlanarIntersector::projectionThis(&tmpSource[0],&tmpTarget[0],tmpSource.size()/SPACEDIM,nbNodesT); - for(int nodeIdT=0;nodeIdT::isElementContainsPointAlg2D(&tmpTarget[0]+nodeIdT*SPACEDIM,&tmpSource[0],tmpSource.size()/SPACEDIM,PlanarIntersector::_precision)) - { - ConnType curNodeTInCmode=OTT::coo2C(startOfCellNodeConnT[nodeIdT]); - typename MyMatrix::value_type& resRow=res[curNodeTInCmode]; - typename MyMatrix::value_type::const_iterator iterRes=resRow.find(OTT::indFC(*iter2)); - if(iterRes==resRow.end()) - resRow.insert(std::make_pair(OTT::indFC(*iter2),1.)); - } - } - } - } - - template - int PlanarIntersectorP0P1PL::getNumberOfRowsOfResMatrix() const - { - return PlanarIntersector::_meshT.getNumberOfNodes(); - } - - template - int PlanarIntersectorP0P1PL::getNumberOfColsOfResMatrix() const - { - return PlanarIntersector::_meshS.getNumberOfElements(); - } -} - -#endif diff --git a/src/INTERP_KERNEL/PlanarIntersectorP1P0.hxx b/src/INTERP_KERNEL/PlanarIntersectorP1P0.hxx deleted file mode 100644 index f351143a4..000000000 --- a/src/INTERP_KERNEL/PlanarIntersectorP1P0.hxx +++ /dev/null @@ -1,51 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 -// 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 __PLANARINTERSECTORP1P0_HXX__ -#define __PLANARINTERSECTORP1P0_HXX__ - -#include "PlanarIntersector.hxx" - -namespace INTERP_KERNEL -{ - template - class PlanarIntersectorP1P0 : public PlanarIntersector - { - public: - static const int SPACEDIM=MyMeshType::MY_SPACEDIM; - static const int MESHDIM=MyMeshType::MY_MESHDIM; - typedef typename MyMeshType::MyConnType ConnType; - static const NumberingPolicy numPol=MyMeshType::My_numPol; - protected: - PlanarIntersectorP1P0(const MyMeshType& meshT, const MyMeshType& meshS, double dimCaracteristic, double precision, double md3DSurf, double minDot3DSurf, double medianPlane, bool doRotate, int orientation, int printLevel); - public: - void intersectCells(ConnType icellT, const std::vector& icellsS, MyMatrix& res); - int getNumberOfRowsOfResMatrix() const; - int getNumberOfColsOfResMatrix() const; - /*! - * Contrary to intersectCells method here icellS and icellT are \b not in \b C mode but in mode of MyMeshType. - */ - double intersectGeometryWithQuadrangle(const double *quadrangle, const std::vector& sourceCoords, bool isSourceQuad) { return asLeaf().intersectGeometryWithQuadrangle(quadrangle,sourceCoords,isSourceQuad); } - protected: - ConcreteP1P0Intersector& asLeaf() { return static_cast(*this); } - }; -} - -#endif diff --git a/src/INTERP_KERNEL/PlanarIntersectorP1P0.txx b/src/INTERP_KERNEL/PlanarIntersectorP1P0.txx deleted file mode 100644 index 60617aee6..000000000 --- a/src/INTERP_KERNEL/PlanarIntersectorP1P0.txx +++ /dev/null @@ -1,104 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 -// 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 __PLANARINTERSECTORP1P0_TXX__ -#define __PLANARINTERSECTORP1P0_TXX__ - -#include "PlanarIntersectorP1P0.hxx" -#include "InterpolationUtils.hxx" - -namespace INTERP_KERNEL -{ - template - PlanarIntersectorP1P0::PlanarIntersectorP1P0(const MyMeshType& meshT, const MyMeshType& meshS, - double dimCaracteristic, double precision, double md3DSurf, double minDot3DSurf, double medianPlane, - bool doRotate, int orientation, int printLevel): - PlanarIntersector(meshT,meshS,dimCaracteristic,precision,md3DSurf,minDot3DSurf,medianPlane,doRotate,orientation,printLevel) - { - } - - template - int PlanarIntersectorP1P0::getNumberOfRowsOfResMatrix() const - { - return PlanarIntersector::_meshT.getNumberOfElements(); - } - - template - int PlanarIntersectorP1P0::getNumberOfColsOfResMatrix() const - { - return PlanarIntersector::_meshS.getNumberOfNodes(); - } - - /*! - * This methods split on the fly, into triangles in order to compute dual mesh of target cell (with icellT id in target mesh in C mode). - */ - template - void PlanarIntersectorP1P0::intersectCells(ConnType icellT, const std::vector& icellsS, MyMatrix& res) - { - double triangle[9]; - double quadrangle[12]; - std::vector targetCellCoords; - int orientation=1; - PlanarIntersector::getRealTargetCoordinates(OTT::indFC(icellT),targetCellCoords); - NormalizedCellType tT=PlanarIntersector::_meshT.getTypeOfElement(OTT::indFC(icellT)); - bool isTargetQuad=CellModel::GetCellModel(tT).isQuadratic(); - typename MyMatrix::value_type& resRow=res[icellT]; - for(typename std::vector::const_iterator iter=icellsS.begin();iter!=icellsS.end();iter++) - { - int iS=*iter; - int nbNodesS=PlanarIntersector::_connIndexS[iS+1]-PlanarIntersector::_connIndexS[iS]; - const ConnType *startOfCellNodeConn=PlanarIntersector::_connectS+OTT::conn2C(PlanarIntersector::_connIndexS[iS]); - for(int nodeIdS=0;nodeIdS::coo2C(startOfCellNodeConn[nodeIdS]); - std::copy(PlanarIntersector::_coordsS+curNodeSInCmode*SPACEDIM, - PlanarIntersector::_coordsS+curNodeSInCmode*SPACEDIM+SPACEDIM,triangle); - for(int subTriS=1;subTriS<=nbNodesS-2;subTriS++) - { - std::copy(PlanarIntersector::_coordsS+OTT::coo2C(startOfCellNodeConn[(nodeIdS+subTriS)%nbNodesS])*SPACEDIM, - PlanarIntersector::_coordsS+OTT::coo2C(startOfCellNodeConn[(nodeIdS+subTriS)%nbNodesS])*SPACEDIM+SPACEDIM, - triangle+SPACEDIM); - std::copy(PlanarIntersector::_coordsS+OTT::coo2C(startOfCellNodeConn[(nodeIdS+subTriS+1)%nbNodesS])*SPACEDIM, - PlanarIntersector::_coordsS+OTT::coo2C(startOfCellNodeConn[(nodeIdS+subTriS+1)%nbNodesS])*SPACEDIM+SPACEDIM, - triangle+2*SPACEDIM); - fillDualCellOfTri(triangle,quadrangle); - std::vector targetCellCoordsTmp(targetCellCoords); - if(SPACEDIM==3) - orientation=PlanarIntersector::projectionThis(&targetCellCoordsTmp[0],quadrangle,targetCellCoords.size()/SPACEDIM,4); - double surf=orientation*intersectGeometryWithQuadrangle(quadrangle,targetCellCoordsTmp,isTargetQuad); - surf=PlanarIntersector::getValueRegardingOption(surf); - if(surf!=0.) - { - typename MyMatrix::value_type::const_iterator iterRes=resRow.find(OTT::indFC(curNodeSInCmode)); - if(iterRes==resRow.end()) - resRow.insert(std::make_pair(OTT::indFC(curNodeSInCmode),surf)); - else - { - double val=(*iterRes).second+surf; - resRow.erase(OTT::indFC(curNodeSInCmode)); - resRow.insert(std::make_pair(OTT::indFC(curNodeSInCmode),val)); - } - } - } - } - } - } -} - -#endif diff --git a/src/INTERP_KERNEL/PlanarIntersectorP1P0Bary.hxx b/src/INTERP_KERNEL/PlanarIntersectorP1P0Bary.hxx deleted file mode 100644 index ede9dc76f..000000000 --- a/src/INTERP_KERNEL/PlanarIntersectorP1P0Bary.hxx +++ /dev/null @@ -1,55 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 -// 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 __PlanarIntersectorP1P0Bary_HXX__ -#define __PlanarIntersectorP1P0Bary_HXX__ - -#include "PlanarIntersector.hxx" - -namespace INTERP_KERNEL -{ - template - class PlanarIntersectorP1P0Bary : public PlanarIntersector - { - public: - static const int SPACEDIM=MyMeshType::MY_SPACEDIM; - static const int MESHDIM=MyMeshType::MY_MESHDIM; - typedef typename MyMeshType::MyConnType ConnType; - static const NumberingPolicy numPol=MyMeshType::My_numPol; - protected: - PlanarIntersectorP1P0Bary(const MyMeshType& meshT, const MyMeshType& meshS, double dimCaracteristic, double precision, double md3DSurf, double minDot3DSurf, double medianPlane, bool doRotate, int orientation, int printLevel); - public: - void intersectCells(ConnType icellT, const std::vector& icellsS, MyMatrix& res); - int getNumberOfRowsOfResMatrix() const; - int getNumberOfColsOfResMatrix() const; - /*! - * Contrary to intersectCells method here icellS and icellT are \b not in \b C mode but in mode of MyMeshType. - */ - double intersectGeoBary(const std::vector& targetCell, - bool targetCellQuadratic, - const double * sourceTria, - std::vector& res) - { return asLeaf().intersectGeoBary(targetCell,targetCellQuadratic,sourceTria,res); } - protected: - ConcreteP1P0Intersector& asLeaf() { return static_cast(*this); } - }; -} - -#endif diff --git a/src/INTERP_KERNEL/PlanarIntersectorP1P0Bary.txx b/src/INTERP_KERNEL/PlanarIntersectorP1P0Bary.txx deleted file mode 100644 index ae0b94f51..000000000 --- a/src/INTERP_KERNEL/PlanarIntersectorP1P0Bary.txx +++ /dev/null @@ -1,118 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 -// 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 __PlanarIntersectorP1P0Bary_TXX__ -#define __PlanarIntersectorP1P0Bary_TXX__ - -#include "PlanarIntersectorP1P0Bary.hxx" -#include "InterpolationUtils.hxx" - -#define PLAN_INTERSECTOR PlanarIntersectorP1P0Bary -#define PLAN_INTER_TEMPLATE template - -namespace INTERP_KERNEL -{ - PLAN_INTER_TEMPLATE - PLAN_INTERSECTOR::PlanarIntersectorP1P0Bary(const MyMeshType& meshT, const MyMeshType& meshS, - double dimCaracteristic, double precision, - double md3DSurf, double minDot3DSurf, double medianPlane, - bool doRotate, int orientation, int printLevel): - PlanarIntersector(meshT,meshS,dimCaracteristic,precision,md3DSurf,minDot3DSurf, - medianPlane,doRotate,orientation,printLevel) - { - // SPEC: - // "Limitation. For the P1P0 barycentric improvement only triangle source cells in 2D and - // tetrahedrons in 3D will be supported by interpolators. If a non - // triangle/tetrahedron source cell is detected an INTERP_KERNEL::Exception should be thrown." - - // Check types of source elements here rather than in intersectCells() since a wrong type can be - // found late after a long time of calculation. - - const unsigned long numSrcElems = meshS.getNumberOfElements(); - for(unsigned long i = 0 ; i < numSrcElems ; ++i) - if ( meshS.getTypeOfElement( OTT::indFC( i )) != NORM_TRI3 ) - throw INTERP_KERNEL::Exception("P1P0 barycentric algorithm works only with triangular source meshes"); - } - - PLAN_INTER_TEMPLATE - int PLAN_INTERSECTOR::getNumberOfRowsOfResMatrix() const - { - return PlanarIntersector::_meshT.getNumberOfElements(); - } - - PLAN_INTER_TEMPLATE - int PLAN_INTERSECTOR::getNumberOfColsOfResMatrix() const - { - return PlanarIntersector::_meshS.getNumberOfNodes(); - } - - /*! - * This method computes a value per each node of each source triangle for target. - */ - PLAN_INTER_TEMPLATE - void PLAN_INTERSECTOR::intersectCells(ConnType icellT, - const std::vector& icellsS, - MyMatrix& res) - { - int orientation=1; - std::vector srcTriaCoords, tgtCellCoords, tgtCellCoordsTmp, nodeCeffs; - - // target cell data - PlanarIntersector::getRealTargetCoordinates(OTT::indFC(icellT),tgtCellCoords); - std::vector * tgtCoords = & tgtCellCoords; - int tgtNbNodes = tgtCellCoords.size()/SPACEDIM; - NormalizedCellType tT=PlanarIntersector::_meshT.getTypeOfElement(OTT::indFC(icellT)); - bool isTargetQuad=CellModel::GetCellModel(tT).isQuadratic(); - - typename MyMatrix::value_type& resRow=res[icellT]; - - // treat each source triangle - for(typename std::vector::const_iterator iter=icellsS.begin();iter!=icellsS.end();iter++) - { - int iS=*iter; - PlanarIntersector::getRealSourceCoordinates(OTT::indFC(iS),srcTriaCoords); - const ConnType *startOfCellNodeConn=PlanarIntersector::_connectS+OTT::conn2C(PlanarIntersector::_connIndexS[iS]); - if(SPACEDIM==3) - { - tgtCellCoordsTmp = tgtCellCoords; - tgtCoords = & tgtCellCoordsTmp; - orientation=PlanarIntersector::projectionThis(&tgtCellCoordsTmp[0], &srcTriaCoords[0], - tgtNbNodes, 3); - } - //double surf=orientation*intersectGeometryWithQuadrangle(quadrangle,targetCellCoordsTmp,isTargetQuad); - double surf=orientation*intersectGeoBary( *tgtCoords, isTargetQuad, &srcTriaCoords[0], nodeCeffs ); - surf=PlanarIntersector::getValueRegardingOption(surf); - if(surf!=0.) - { - for(int nodeIdS=0;nodeIdS<3;nodeIdS++) - { - ConnType curNodeS=startOfCellNodeConn[nodeIdS]; - typename MyMatrix::value_type::const_iterator iterRes=resRow.find(curNodeS); - if(iterRes!=resRow.end()) - { - nodeCeffs[nodeIdS] += iterRes->second; - resRow.erase( curNodeS ); - } - resRow.insert(std::make_pair(curNodeS,nodeCeffs[nodeIdS])); - } - } - } - } -} -#endif diff --git a/src/INTERP_KERNEL/PlanarIntersectorP1P0PL.hxx b/src/INTERP_KERNEL/PlanarIntersectorP1P0PL.hxx deleted file mode 100644 index 47e9121cb..000000000 --- a/src/INTERP_KERNEL/PlanarIntersectorP1P0PL.hxx +++ /dev/null @@ -1,44 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 -// 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 __PLANARINTERSECTORP1P0PL_HXX__ -#define __PLANARINTERSECTORP1P0PL_HXX__ - -#include "PlanarIntersector.hxx" - -namespace INTERP_KERNEL -{ - template - class PlanarIntersectorP1P0PL : public PlanarIntersector - { - public: - static const int SPACEDIM=MyMeshType::MY_SPACEDIM; - static const int MESHDIM=MyMeshType::MY_MESHDIM; - typedef typename MyMeshType::MyConnType ConnType; - static const NumberingPolicy numPol=MyMeshType::My_numPol; - public: - PlanarIntersectorP1P0PL(const MyMeshType& meshT, const MyMeshType& meshS, double dimCaracteristic, double md3DSurf, double minDot3DSurf, double medianPlane, double precision, int orientation); - void intersectCells(ConnType icellT, const std::vector& icellsS, MyMatrix& res); - int getNumberOfRowsOfResMatrix() const; - int getNumberOfColsOfResMatrix() const; - }; -} - -#endif diff --git a/src/INTERP_KERNEL/PlanarIntersectorP1P0PL.txx b/src/INTERP_KERNEL/PlanarIntersectorP1P0PL.txx deleted file mode 100644 index c86fa2c50..000000000 --- a/src/INTERP_KERNEL/PlanarIntersectorP1P0PL.txx +++ /dev/null @@ -1,108 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 -// 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 __PLANARINTERSECTORP1P0PL_TXX__ -#define __PLANARINTERSECTORP1P0PL_TXX__ - -#include "PlanarIntersectorP1P0PL.hxx" -#include "PlanarIntersector.txx" -#include "CellModel.hxx" - -#include "PointLocatorAlgos.txx" -#include "InterpKernelGeo2DQuadraticPolygon.hxx" -#include "MeshUtils.hxx" - -namespace INTERP_KERNEL -{ - template - PlanarIntersectorP1P0PL::PlanarIntersectorP1P0PL(const MyMeshType& meshT, const MyMeshType& meshS, - double dimCaracteristic, double md3DSurf, double minDot3DSurf, - double medianPlane, double precision, int orientation): - PlanarIntersector(meshT,meshS,dimCaracteristic,precision,md3DSurf,minDot3DSurf,medianPlane,true,orientation,0) - { - } - - template - void PlanarIntersectorP1P0PL::intersectCells(ConnType icellT, const std::vector& icellsS, MyMatrix& res) - { - std::vector CoordsT; - typename MyMatrix::value_type& resRow=res[icellT]; - PlanarIntersector::getRealTargetCoordinates(OTT::indFC(icellT),CoordsT); - double baryT[SPACEDIM]; - double baryTTmp[SPACEDIM]; - calculateBarycenterDyn2(&CoordsT[0],CoordsT.size()/SPACEDIM,baryT); - for(typename std::vector::const_iterator iter=icellsS.begin();iter!=icellsS.end();iter++) - { - NormalizedCellType tS=PlanarIntersector::_meshS.getTypeOfElement(OTT::indFC(*iter)); - if(tS!=NORM_TRI3) - throw INTERP_KERNEL::Exception("Invalid source cell detected for meshdim==2. Only TRI3 supported !"); - std::vector CoordsS; - PlanarIntersector::getRealSourceCoordinates(OTT::indFC(*iter),CoordsS); - if(SPACEDIM==2) - { - std::copy(baryT,baryT+SPACEDIM,baryTTmp); - } - else - { - double littleTargetCell[9]; - std::copy(baryT,baryT+SPACEDIM,littleTargetCell); - std::copy(CoordsT.begin(),CoordsT.begin()+3,littleTargetCell+3); - std::copy(CoordsT.begin()+3,CoordsT.begin()+6,littleTargetCell+6); - PlanarIntersector::projectionThis(&CoordsS[0],littleTargetCell,3,3); - std::copy(littleTargetCell,littleTargetCell+3,baryTTmp); - } - if(PointLocatorAlgos::isElementContainsPointAlg2D(baryTTmp,&CoordsS[0],3,PlanarIntersector::_precision)) - { - double resLoc[3]; - barycentric_coords(&CoordsS[0],baryTTmp,resLoc); - const ConnType *startOfCellNodeConnS=PlanarIntersector::_connectS+OTT::conn2C(PlanarIntersector::_connIndexS[*iter]); - for(int nodeIdS=0;nodeIdS<3;nodeIdS++) - { - if(fabs(resLoc[nodeIdS])>PlanarIntersector::_precision) - { - ConnType curNodeSInCmode=OTT::coo2C(startOfCellNodeConnS[nodeIdS]); - typename MyMatrix::value_type::const_iterator iterRes=resRow.find(OTT::indFC(curNodeSInCmode)); - if(iterRes==resRow.end()) - resRow.insert(std::make_pair(OTT::indFC(curNodeSInCmode),resLoc[nodeIdS])); - else - { - double val=(*iterRes).second+resLoc[nodeIdS]; - resRow.erase(OTT::indFC(curNodeSInCmode)); - resRow.insert(std::make_pair(OTT::indFC(curNodeSInCmode),val)); - } - } - } - } - } - } - - template - int PlanarIntersectorP1P0PL::getNumberOfRowsOfResMatrix() const - { - return PlanarIntersector::_meshT.getNumberOfElements(); - } - - template - int PlanarIntersectorP1P0PL::getNumberOfColsOfResMatrix() const - { - return PlanarIntersector::_meshS.getNumberOfNodes(); - } -} - -#endif diff --git a/src/INTERP_KERNEL/PlanarIntersectorP1P1.hxx b/src/INTERP_KERNEL/PlanarIntersectorP1P1.hxx deleted file mode 100644 index 6c8cb310a..000000000 --- a/src/INTERP_KERNEL/PlanarIntersectorP1P1.hxx +++ /dev/null @@ -1,49 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 -// 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 __PLANARINTERSECTORP1P1_HXX__ -#define __PLANARINTERSECTORP1P1_HXX__ - -#include "PlanarIntersector.hxx" - -namespace INTERP_KERNEL -{ - template - class PlanarIntersectorP1P1 : public PlanarIntersector - { - public: - static const int SPACEDIM=MyMeshType::MY_SPACEDIM; - static const int MESHDIM=MyMeshType::MY_MESHDIM; - typedef typename MyMeshType::MyConnType ConnType; - static const NumberingPolicy numPol=MyMeshType::My_numPol; - protected: - PlanarIntersectorP1P1(const MyMeshType& meshT, const MyMeshType& meshS, double dimCaracteristic, double precision, double md3DSurf, double minDot3DSurf, double medianPlane, bool doRotate, int orientation, int printLevel); - public: - void intersectCells(ConnType icellT, const std::vector& icellsS, MyMatrix& res); - int getNumberOfRowsOfResMatrix() const; - int getNumberOfColsOfResMatrix() const; - - double intersectGeometryGeneral(const std::vector& targetCoords, const std::vector& sourceCoords) { return asLeaf().intersectGeometryGeneral(targetCoords,sourceCoords); } - protected: - ConcreteP1P1Intersector& asLeaf() { return static_cast(*this); } - }; -} - -#endif diff --git a/src/INTERP_KERNEL/PlanarIntersectorP1P1.txx b/src/INTERP_KERNEL/PlanarIntersectorP1P1.txx deleted file mode 100644 index af1914139..000000000 --- a/src/INTERP_KERNEL/PlanarIntersectorP1P1.txx +++ /dev/null @@ -1,102 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 -// 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 __PLANARINTERSECTORP1P1_TXX__ -#define __PLANARINTERSECTORP1P1_TXX__ - -#include "PlanarIntersectorP1P1.hxx" -#include "InterpolationUtils.hxx" -#include "CellModel.hxx" - -namespace INTERP_KERNEL -{ - template - PlanarIntersectorP1P1::PlanarIntersectorP1P1(const MyMeshType& meshT, const MyMeshType& meshS, - double dimCaracteristic, double precision, double md3DSurf, double minDot3DSurf, double medianPlane, - bool doRotate, int orientation, int printLevel): - PlanarIntersector(meshT,meshS,dimCaracteristic,precision,md3DSurf,minDot3DSurf,medianPlane,doRotate,orientation,printLevel) - { - } - - template - int PlanarIntersectorP1P1::getNumberOfRowsOfResMatrix() const - { - return PlanarIntersector::_meshT.getNumberOfNodes(); - } - - template - int PlanarIntersectorP1P1::getNumberOfColsOfResMatrix() const - { - return PlanarIntersector::_meshS.getNumberOfNodes(); - } - - /*! - * This methods split on the fly, into triangles in order to compute dual mesh of target cell (with icellT id in target mesh in C mode). - */ - template - void PlanarIntersectorP1P1::intersectCells(ConnType icellT, const std::vector& icellsS, MyMatrix& res) - { - int nbNodesT=PlanarIntersector::_connIndexT[icellT+1]-PlanarIntersector::_connIndexT[icellT]; - int orientation=1; - const ConnType *startOfCellNodeConn=PlanarIntersector::_connectT+OTT::conn2C(PlanarIntersector::_connIndexT[icellT]); - std::vector polygT; - PlanarIntersector::getRealTargetCoordinates(OTT::indFC(icellT),polygT); - for(int nodeIdT=0;nodeIdT::coo2C(startOfCellNodeConn[nodeIdT]); - PlanarIntersector::getRealTargetCoordinatesPermute(OTT::indFC(icellT),nodeIdT,polygT); - std::vector polygDualT(SPACEDIM*2*(nbNodesT-1)); - fillDualCellOfPolyg(&polygT[0],polygT.size()/SPACEDIM,&polygDualT[0]); - typename MyMatrix::value_type& resRow=res[curNodeTInCmode]; - for(typename std::vector::const_iterator iter=icellsS.begin();iter!=icellsS.end();iter++) - { - int iS=*iter; - int nbNodesS=PlanarIntersector::_connIndexS[iS+1]-PlanarIntersector::_connIndexS[iS]; - const ConnType *startOfCellNodeConnS=PlanarIntersector::_connectS+OTT::conn2C(PlanarIntersector::_connIndexS[iS]); - for(int nodeIdS=0;nodeIdS::coo2C(startOfCellNodeConnS[nodeIdS]); - std::vector polygS; - PlanarIntersector::getRealSourceCoordinatesPermute(OTT::indFC(iS),nodeIdS,polygS); - std::vector polygDualS(SPACEDIM*2*(nbNodesS-1)); - fillDualCellOfPolyg(&polygS[0],polygS.size()/SPACEDIM,&polygDualS[0]); - std::vector polygDualTTmp(polygDualT); - if(SPACEDIM==3) - orientation=PlanarIntersector::projectionThis(&polygDualS[0],&polygDualTTmp[0],polygDualS.size()/SPACEDIM,polygDualT.size()/SPACEDIM); - double surf=orientation*intersectGeometryGeneral(polygDualTTmp,polygDualS); - surf=PlanarIntersector::getValueRegardingOption(surf); - if(surf!=0.) - { - typename MyMatrix::value_type::const_iterator iterRes=resRow.find(OTT::indFC(curNodeSInCmode)); - if(iterRes==resRow.end()) - resRow.insert(std::make_pair(OTT::indFC(curNodeSInCmode),surf)); - else - { - double val=(*iterRes).second+surf; - resRow.erase(OTT::indFC(curNodeSInCmode)); - resRow.insert(std::make_pair(OTT::indFC(curNodeSInCmode),val)); - } - } - } - } - } - } -} - -#endif diff --git a/src/INTERP_KERNEL/PlanarIntersectorP1P1PL.hxx b/src/INTERP_KERNEL/PlanarIntersectorP1P1PL.hxx deleted file mode 100644 index 226d89e32..000000000 --- a/src/INTERP_KERNEL/PlanarIntersectorP1P1PL.hxx +++ /dev/null @@ -1,44 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 -// 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 __PLANARINTERSECTORP1P1PL_HXX__ -#define __PLANARINTERSECTORP1P1PL_HXX__ - -#include "PlanarIntersector.hxx" - -namespace INTERP_KERNEL -{ - template - class PlanarIntersectorP1P1PL : public PlanarIntersector - { - public: - static const int SPACEDIM=MyMeshType::MY_SPACEDIM; - static const int MESHDIM=MyMeshType::MY_MESHDIM; - typedef typename MyMeshType::MyConnType ConnType; - static const NumberingPolicy numPol=MyMeshType::My_numPol; - public: - PlanarIntersectorP1P1PL(const MyMeshType& meshT, const MyMeshType& meshS, double dimCaracteristic, double md3DSurf, double minDot3DSurf, double medianPlane, double precision, int orientation); - void intersectCells(ConnType icellT, const std::vector& icellsS, MyMatrix& res); - int getNumberOfRowsOfResMatrix() const; - int getNumberOfColsOfResMatrix() const; - }; -} - -#endif diff --git a/src/INTERP_KERNEL/PlanarIntersectorP1P1PL.txx b/src/INTERP_KERNEL/PlanarIntersectorP1P1PL.txx deleted file mode 100644 index aa36f5cfe..000000000 --- a/src/INTERP_KERNEL/PlanarIntersectorP1P1PL.txx +++ /dev/null @@ -1,99 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 -// 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 __PLANARINTERSECTORP1P1PL_TXX__ -#define __PLANARINTERSECTORP1P1PL_TXX__ - -#include "PlanarIntersectorP1P1PL.hxx" -#include "PlanarIntersector.txx" -#include "CellModel.hxx" - -#include "PointLocatorAlgos.txx" -#include "MeshUtils.hxx" - -namespace INTERP_KERNEL -{ - template - PlanarIntersectorP1P1PL::PlanarIntersectorP1P1PL(const MyMeshType& meshT, const MyMeshType& meshS, - double dimCaracteristic, double md3DSurf, double minDot3DSurf, - double medianPlane, double precision, int orientation): - PlanarIntersector(meshT,meshS,dimCaracteristic,precision,md3DSurf,minDot3DSurf,medianPlane,true,orientation,0) - { - } - - template - void PlanarIntersectorP1P1PL::intersectCells(ConnType icellT, const std::vector& icellsS, MyMatrix& res) - { - std::vector CoordsT; - PlanarIntersector::getRealTargetCoordinates(OTT::indFC(icellT),CoordsT); - int nbOfNodesT=CoordsT.size()/SPACEDIM; - for(typename std::vector::const_iterator iter=icellsS.begin();iter!=icellsS.end();iter++) - { - NormalizedCellType tS=PlanarIntersector::_meshS.getTypeOfElement(OTT::indFC(*iter)); - if(tS!=NORM_TRI3) - throw INTERP_KERNEL::Exception("Invalid source cell detected for meshdim==2. Only TRI3 supported !"); - std::vector CoordsS; - PlanarIntersector::getRealSourceCoordinates(OTT::indFC(*iter),CoordsS); - std::vector CoordsTTmp(CoordsT); - if(SPACEDIM==3) - PlanarIntersector::projectionThis(&CoordsS[0],&CoordsTTmp[0],CoordsS.size()/SPACEDIM,nbOfNodesT); - const ConnType *startOfCellNodeConnT=PlanarIntersector::_connectT+OTT::conn2C(PlanarIntersector::_connIndexT[icellT]); - for(int nodeIdT=0;nodeIdT::ind2C(startOfCellNodeConnT[nodeIdT])]; - if( PointLocatorAlgos::isElementContainsPointAlg2D(&CoordsTTmp[nodeIdT*SPACEDIM],&CoordsS[0],3,PlanarIntersector::_precision) ) - { - double resLoc[3]; - barycentric_coords(&CoordsS[0],&CoordsTTmp[nodeIdT*SPACEDIM],resLoc); - const ConnType *startOfCellNodeConnS=PlanarIntersector::_connectS+OTT::conn2C(PlanarIntersector::_connIndexS[*iter]); - for(int nodeIdS=0;nodeIdS<3;nodeIdS++) - { - if(fabs(resLoc[nodeIdS])>PlanarIntersector::_precision) - { - ConnType curNodeSInCmode=OTT::coo2C(startOfCellNodeConnS[nodeIdS]); - typename MyMatrix::value_type::const_iterator iterRes=resRow.find(OTT::indFC(curNodeSInCmode)); - if(iterRes==resRow.end()) - resRow.insert(std::make_pair(OTT::indFC(curNodeSInCmode),resLoc[nodeIdS])); - else - { - double val=(*iterRes).second+resLoc[nodeIdS]; - resRow.erase(OTT::indFC(curNodeSInCmode)); - resRow.insert(std::make_pair(OTT::indFC(curNodeSInCmode),val)); - } - } - } - } - } - } - } - - template - int PlanarIntersectorP1P1PL::getNumberOfRowsOfResMatrix() const - { - return PlanarIntersector::_meshT.getNumberOfNodes(); - } - - template - int PlanarIntersectorP1P1PL::getNumberOfColsOfResMatrix() const - { - return PlanarIntersector::_meshS.getNumberOfNodes(); - } -} - -#endif diff --git a/src/INTERP_KERNEL/PointLocator2DIntersector.hxx b/src/INTERP_KERNEL/PointLocator2DIntersector.hxx deleted file mode 100644 index 51251c3ec..000000000 --- a/src/INTERP_KERNEL/PointLocator2DIntersector.hxx +++ /dev/null @@ -1,56 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 -// 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 __POINTLOCATORINTERSECTOR_HXX__ -#define __POINTLOCATORINTERSECTOR_HXX__ - -#include "PlanarIntersectorP0P0.hxx" -#include "PlanarIntersectorP0P1.hxx" -#include "PlanarIntersectorP1P0.hxx" -#include "PlanarIntersectorP1P1.hxx" -#include "PlanarIntersectorP1P0Bary.hxx" - -namespace INTERP_KERNEL -{ - class QuadraticPolygon; - - template class InterpType> - class PointLocator2DIntersector : public InterpType > - { - public: - static const int SPACEDIM=MyMeshType::MY_SPACEDIM; - static const int MESHDIM=MyMeshType::MY_MESHDIM; - typedef typename MyMeshType::MyConnType ConnType; - static const NumberingPolicy numPol=MyMeshType::My_numPol; - public: - PointLocator2DIntersector(const MyMeshType& meshT, const MyMeshType& meshS, - double dimCaracteristic, double md3DSurf, double minDot3DSurf, double medianPlane, double precision, int orientation); - double intersectGeometry(ConnType icellT, ConnType icellS, ConnType nbNodesT, ConnType nbNodesS); - double intersectGeometryWithQuadrangle(const double *quadrangle, const std::vector& sourceCoords, bool isSourceQuad); - double intersectGeometryGeneral(const std::vector& targetCoords, const std::vector& sourceCoords); - double intersectGeoBary(const std::vector& targetCell, bool targetCellQuadratic, const double *sourceCell, std::vector& res); - private: - QuadraticPolygon *buildPolygonFrom(const std::vector& coords, NormalizedCellType type); - QuadraticPolygon *buildPolygonAFrom(ConnType cell, int nbOfPoints, NormalizedCellType type); - QuadraticPolygon *buildPolygonBFrom(ConnType cell, int nbOfPoints, NormalizedCellType type); - }; -} - -#endif diff --git a/src/INTERP_KERNEL/PointLocator2DIntersector.txx b/src/INTERP_KERNEL/PointLocator2DIntersector.txx deleted file mode 100644 index 0f83435c6..000000000 --- a/src/INTERP_KERNEL/PointLocator2DIntersector.txx +++ /dev/null @@ -1,165 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 -// 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 __POINTLOCATORINTERSECTOR_TXX__ -#define __POINTLOCATORINTERSECTOR_TXX__ - -#include "PointLocator2DIntersector.hxx" -#include "PlanarIntersectorP0P0.txx" -#include "PlanarIntersectorP0P1.txx" -#include "PlanarIntersectorP1P0.txx" -#include "PlanarIntersectorP1P1.txx" -#include "PlanarIntersectorP1P0Bary.txx" -#include "CellModel.hxx" - -#include "InterpKernelGeo2DQuadraticPolygon.hxx" -#include "PointLocatorAlgos.txx" - -#define PTLOC2D_INTERSECTOR PointLocator2DIntersector -#define INTERSECTOR_TEMPLATE template class InterpType> - -namespace INTERP_KERNEL -{ - INTERSECTOR_TEMPLATE - PTLOC2D_INTERSECTOR::PointLocator2DIntersector(const MyMeshType& meshT, const MyMeshType& meshS, - double dimCaracteristic, double md3DSurf, double minDot3DSurf, double medianPlane, - double precision, int orientation): - InterpType(meshT,meshS,dimCaracteristic, precision, md3DSurf, minDot3DSurf, medianPlane, true, orientation, 0) - { - } - - INTERSECTOR_TEMPLATE - double PTLOC2D_INTERSECTOR::intersectGeometry(ConnType icellT, ConnType icellS, - ConnType nbNodesT, ConnType nbNodesS) - { - int orientation = 1; - std::vector CoordsT; - std::vector CoordsS; - PlanarIntersector::getRealCoordinates(icellT,icellS,nbNodesT,nbNodesS,CoordsT,CoordsS,orientation); - NormalizedCellType tT=PlanarIntersector::_meshT.getTypeOfElement(icellT); - QuadraticPolygon *pT=buildPolygonFrom(CoordsT,tT); - double baryT[SPACEDIM]; - pT->getBarycenterGeneral(baryT); - delete pT; - if(PointLocatorAlgos::isElementContainsPointAlg2D(baryT,&CoordsS[0],nbNodesS,InterpType::_precision)) - return 1.; - return 0.; - } - - INTERSECTOR_TEMPLATE - double PTLOC2D_INTERSECTOR::intersectGeometryWithQuadrangle(const double * quadrangle, - const std::vector& sourceCoords, - bool isSourceQuad) - { - int nbOfSourceNodes=sourceCoords.size()/SPACEDIM; - std::vector nodes2(nbOfSourceNodes); - for(int i=0;igetBarycenter(bary); - delete p2; - if( PointLocatorAlgos::isElementContainsPointAlg2D(bary,quadrangle,4) ) - return 1.; - return 0.; - } - - INTERSECTOR_TEMPLATE - double PTLOC2D_INTERSECTOR::intersectGeometryGeneral(const std::vector& targetCoords, - const std::vector& sourceCoords) - { - int nbOfTargetNodes=targetCoords.size()/SPACEDIM; - int nbOfSourceNodes=sourceCoords.size()/SPACEDIM; - std::vector nodes2(nbOfSourceNodes); - for(int i=0;igetBarycenterGeneral(bary); - delete p; - if( PointLocatorAlgos::isElementContainsPointAlg2D(bary,&targetCoords[0],nbOfTargetNodes) ) - return 1.; - return 0.; - } - - //================================================================================ - /*! - * \brief Intersect a triangle and a polygon for P1P0 barycentric algorithm - * \param targetCell - list of coordinates of target polygon in full interlace - * \param targetCellQuadratic - specifies if target polygon is quadratic or not - * \param sourceTria - list of coordinates of source triangle - * \param res - coefficients a,b and c associated to nodes of sourceTria - */ - //================================================================================ - - INTERSECTOR_TEMPLATE - double PTLOC2D_INTERSECTOR::intersectGeoBary(const std::vector& targetCell, - bool targetCellQuadratic, - const double * sourceTria, - std::vector& res) - { - throw INTERP_KERNEL::Exception("intersectGeoBary incompatible with PointLocator. Desactivate P1P0Bary to avoid the problem"); - return 0.; - } - - INTERSECTOR_TEMPLATE - QuadraticPolygon *PTLOC2D_INTERSECTOR::buildPolygonFrom(const std::vector& coords, NormalizedCellType type) - { - int nbNodes=coords.size()/SPACEDIM; - std::vector nodes(nbNodes); - for(int i=0;i::_connectT+OTT::conn2C(PlanarIntersector::_connIndexT[OTT::ind2C(cell)]); - std::vector nodes(nbOfPoints); - for(int i=0;i::_coordsT+OTT::coo2C(startOfCellNodeConn[i])*SPACEDIM); - if(CellModel::GetCellModel(type).isQuadratic()) - return QuadraticPolygon::BuildLinearPolygon(nodes); - else - return QuadraticPolygon::BuildArcCirclePolygon(nodes); - } - - INTERSECTOR_TEMPLATE - QuadraticPolygon *PTLOC2D_INTERSECTOR::buildPolygonBFrom(ConnType cell, int nbOfPoints, NormalizedCellType type) - { - const ConnType *startOfCellNodeConn=PlanarIntersector::_connectS+OTT::conn2C(PlanarIntersector::_connIndexS[OTT::ind2C(cell)]); - std::vector nodes(nbOfPoints); - for(int i=0;i::_coordsS+OTT::coo2C(startOfCellNodeConn[i])*SPACEDIM); - if(type!=NORM_TRI6 && type!=NORM_QUAD8) - return QuadraticPolygon::BuildLinearPolygon(nodes); - else - return QuadraticPolygon::BuildArcCirclePolygon(nodes); - } -} - -#endif diff --git a/src/INTERP_KERNEL/PointLocator3DIntersectorP0P0.hxx b/src/INTERP_KERNEL/PointLocator3DIntersectorP0P0.hxx deleted file mode 100644 index 54b46415d..000000000 --- a/src/INTERP_KERNEL/PointLocator3DIntersectorP0P0.hxx +++ /dev/null @@ -1,46 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 -// 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 __POINTLOCATOR3DINTERSECTORP0P0_HXX__ -#define __POINTLOCATOR3DINTERSECTORP0P0_HXX__ - -#include "Intersector3DP0P0.hxx" -#include "NormalizedUnstructuredMesh.hxx" - -namespace INTERP_KERNEL -{ - template - class PointLocator3DIntersectorP0P0 : public Intersector3DP0P0 - { - public: - static const int SPACEDIM=MyMeshType::MY_SPACEDIM; - static const int MESHDIM=MyMeshType::MY_MESHDIM; - typedef typename MyMeshType::MyConnType ConnType; - static const NumberingPolicy numPol=MyMeshType::My_numPol; - public: - PointLocator3DIntersectorP0P0(const MyMeshType& targetMesh, const MyMeshType& srcMesh, double precision); - ~PointLocator3DIntersectorP0P0(); - void intersectCells(ConnType targetCell, const std::vector& srcCells, MyMatrix& res); - protected: - double _precision; - }; -} - -#endif diff --git a/src/INTERP_KERNEL/PointLocator3DIntersectorP0P0.txx b/src/INTERP_KERNEL/PointLocator3DIntersectorP0P0.txx deleted file mode 100644 index 197e644dd..000000000 --- a/src/INTERP_KERNEL/PointLocator3DIntersectorP0P0.txx +++ /dev/null @@ -1,78 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 -// 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 __POINTLOCATOR3DINTERSECTORP0P0_TXX__ -#define __POINTLOCATOR3DINTERSECTORP0P0_TXX__ - -#include "PointLocator3DIntersectorP0P0.hxx" -#include "Intersector3DP0P0.txx" -#include "MeshUtils.hxx" - -#include "SplitterTetra.txx" -#include "PointLocatorAlgos.txx" - -namespace INTERP_KERNEL -{ - - /** - * @param targetMesh mesh containing the target elements - * @param srcMesh mesh containing the source elements - * @param policy splitting policy to be used - */ - template - PointLocator3DIntersectorP0P0::PointLocator3DIntersectorP0P0(const MyMeshType& targetMesh, const MyMeshType& srcMesh, double precision): - Intersector3DP0P0(targetMesh,srcMesh),_precision(precision) - { - } - - template - PointLocator3DIntersectorP0P0::~PointLocator3DIntersectorP0P0() - { - } - - /** - * - * @param targetCell in C mode. - * @param srcCells in C mode. - * - */ - template - void PointLocator3DIntersectorP0P0::intersectCells(ConnType targetCell, const std::vector& srcCells, MyMatrix& res) - { - std::vector CoordsT; - Intersector3DP0P0::getRealTargetCoordinates(OTT::indFC(targetCell),CoordsT); - double bary[SPACEDIM]; - calculateBarycenterDyn2(&CoordsT[0],CoordsT.size()/SPACEDIM,bary); - typename MyMatrix::value_type& resRow=res[targetCell]; - const double *coordsS=Intersector3DP0P0::_src_mesh.getCoordinatesPtr(); - for(typename std::vector::const_iterator iterCellS=srcCells.begin();iterCellS!=srcCells.end();iterCellS++) - { - NormalizedCellType tS=Intersector3DP0P0::_src_mesh.getTypeOfElement(OTT::indFC(*iterCellS)); - const CellModel& cmTypeS=CellModel::GetCellModel(tS); - std::vector connOfCurCellS; - Intersector3DP0P0::getConnOfSourceCell(OTT::indFC(*iterCellS),connOfCurCellS); - if(PointLocatorAlgos::isElementContainsPointAlg3D(bary,&connOfCurCellS[0],connOfCurCellS.size(),coordsS,cmTypeS,_precision)) - { - resRow.insert(std::make_pair(OTT::indFC(*iterCellS),1)); - } - } - } -} - -#endif diff --git a/src/INTERP_KERNEL/PointLocator3DIntersectorP0P1.hxx b/src/INTERP_KERNEL/PointLocator3DIntersectorP0P1.hxx deleted file mode 100644 index a7eb4fc19..000000000 --- a/src/INTERP_KERNEL/PointLocator3DIntersectorP0P1.hxx +++ /dev/null @@ -1,46 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 -// 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 __POINTLOCATOR3DINTERSECTORP0P1_HXX__ -#define __POINTLOCATOR3DINTERSECTORP0P1_HXX__ - -#include "Intersector3DP0P1.hxx" -#include "NormalizedUnstructuredMesh.hxx" - -namespace INTERP_KERNEL -{ - template - class PointLocator3DIntersectorP0P1 : public Intersector3DP0P1 - { - public: - static const int SPACEDIM=MyMeshType::MY_SPACEDIM; - static const int MESHDIM=MyMeshType::MY_MESHDIM; - typedef typename MyMeshType::MyConnType ConnType; - static const NumberingPolicy numPol=MyMeshType::My_numPol; - public: - PointLocator3DIntersectorP0P1(const MyMeshType& targetMesh, const MyMeshType& srcMesh, double precision); - ~PointLocator3DIntersectorP0P1(); - void intersectCells(ConnType targetCell, const std::vector& srcCells, MyMatrix& res); - protected: - double _precision; - }; -} - -#endif diff --git a/src/INTERP_KERNEL/PointLocator3DIntersectorP0P1.txx b/src/INTERP_KERNEL/PointLocator3DIntersectorP0P1.txx deleted file mode 100644 index 0b0e68eeb..000000000 --- a/src/INTERP_KERNEL/PointLocator3DIntersectorP0P1.txx +++ /dev/null @@ -1,81 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 -// 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 __POINTLOCATOR3DINTERSECTORP0P1_TXX__ -#define __POINTLOCATOR3DINTERSECTORP0P1_TXX__ - -#include "PointLocator3DIntersectorP0P1.hxx" -#include "Intersector3DP0P1.txx" -#include "MeshUtils.hxx" - -namespace INTERP_KERNEL -{ - - /** - * @param targetMesh mesh containing the target elements - * @param srcMesh mesh containing the source elements - * @param policy splitting policy to be used - */ - template - PointLocator3DIntersectorP0P1::PointLocator3DIntersectorP0P1(const MyMeshType& targetMesh, const MyMeshType& srcMesh, double precision): - Intersector3DP0P1(targetMesh,srcMesh),_precision(precision) - { - } - - template - PointLocator3DIntersectorP0P1::~PointLocator3DIntersectorP0P1() - { - } - - /** - * - * @param targetCell in C mode. - * @param srcCells in C mode. - * - */ - template - void PointLocator3DIntersectorP0P1::intersectCells(ConnType targetCell, const std::vector& srcCells, MyMatrix& res) - { - std::vector coordsTarget; - Intersector3DP0P1::getRealTargetCoordinates(OTT::indFC(targetCell),coordsTarget); - int nbNodesT=coordsTarget.size()/SPACEDIM; - const double *coordsS=Intersector3DP0P1::_src_mesh.getCoordinatesPtr(); - const ConnType *startOfCellNodeConnT=Intersector3DP0P1::getStartConnOfTargetCell(targetCell); - for(typename std::vector::const_iterator iterCellS=srcCells.begin();iterCellS!=srcCells.end();iterCellS++) - { - NormalizedCellType tS=Intersector3DP0P1::_src_mesh.getTypeOfElement(OTT::indFC(*iterCellS)); - const CellModel& cmTypeS=CellModel::GetCellModel(tS); - std::vector connOfCurCellS; - Intersector3DP0P1::getConnOfSourceCell(OTT::indFC(*iterCellS),connOfCurCellS); - for(int nodeIdT=0;nodeIdT::isElementContainsPointAlg3D(&coordsTarget[nodeIdT*SPACEDIM],&connOfCurCellS[0],connOfCurCellS.size(),coordsS,cmTypeS,_precision)) - { - ConnType curNodeTInCmode=OTT::coo2C(startOfCellNodeConnT[nodeIdT]); - typename MyMatrix::value_type& resRow=res[curNodeTInCmode]; - typename MyMatrix::value_type::const_iterator iterRes=resRow.find(OTT::indFC(*iterCellS)); - if(iterRes==resRow.end()) - resRow.insert(std::make_pair(OTT::indFC(*iterCellS),1.)); - } - } - } - } -} - -#endif diff --git a/src/INTERP_KERNEL/PointLocator3DIntersectorP1P0.hxx b/src/INTERP_KERNEL/PointLocator3DIntersectorP1P0.hxx deleted file mode 100644 index 012dc28c2..000000000 --- a/src/INTERP_KERNEL/PointLocator3DIntersectorP1P0.hxx +++ /dev/null @@ -1,46 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 -// 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 __POINTLOCATOR3DINTERSECTORP1P0_HXX__ -#define __POINTLOCATOR3DINTERSECTORP1P0_HXX__ - -#include "Intersector3DP1P0.hxx" -#include "NormalizedUnstructuredMesh.hxx" - -namespace INTERP_KERNEL -{ - template - class PointLocator3DIntersectorP1P0 : public Intersector3DP1P0 - { - public: - static const int SPACEDIM=MyMeshType::MY_SPACEDIM; - static const int MESHDIM=MyMeshType::MY_MESHDIM; - typedef typename MyMeshType::MyConnType ConnType; - static const NumberingPolicy numPol=MyMeshType::My_numPol; - public: - PointLocator3DIntersectorP1P0(const MyMeshType& targetMesh, const MyMeshType& srcMesh, double precision); - ~PointLocator3DIntersectorP1P0(); - void intersectCells(ConnType targetCell, const std::vector& srcCells, MyMatrix& res); - protected: - double _precision; - }; -} - -#endif diff --git a/src/INTERP_KERNEL/PointLocator3DIntersectorP1P0.txx b/src/INTERP_KERNEL/PointLocator3DIntersectorP1P0.txx deleted file mode 100644 index e611b8bee..000000000 --- a/src/INTERP_KERNEL/PointLocator3DIntersectorP1P0.txx +++ /dev/null @@ -1,99 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 -// 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 __POINTLOCATOR3DINTERSECTORP1P0_TXX__ -#define __POINTLOCATOR3DINTERSECTORP1P0_TXX__ - -#include "PointLocator3DIntersectorP1P0.hxx" -#include "Intersector3DP1P0.txx" -#include "MeshUtils.hxx" - -namespace INTERP_KERNEL -{ - /** - * @param targetMesh mesh containing the target elements - * @param srcMesh mesh containing the source elements - * @param policy splitting policy to be used - * - * WARNING : in _split attribute, sourceMesh and targetMesh are switched in order to fit intersectCells feature. - */ - template - PointLocator3DIntersectorP1P0::PointLocator3DIntersectorP1P0(const MyMeshType& targetMesh, const MyMeshType& srcMesh, double precision):Intersector3DP1P0(targetMesh,srcMesh),_precision(precision) - { - } - - template - PointLocator3DIntersectorP1P0::~PointLocator3DIntersectorP1P0() - { - } - - /** - * @param targetCell in C mode. - * @param srcCells in C mode. - * - * WARNING : for all methods on _split object source and target are switched ! - */ - template - void PointLocator3DIntersectorP1P0::intersectCells(ConnType targetCell, const std::vector& srcCells, MyMatrix& res) - { - std::vector CoordsT; - typename MyMatrix::value_type& resRow=res[targetCell]; - const double *coordsS=Intersector3DP1P0::_src_mesh.getCoordinatesPtr(); - Intersector3DP1P0::getRealTargetCoordinates(OTT::indFC(targetCell),CoordsT); - double baryT[SPACEDIM]; - calculateBarycenterDyn2(&CoordsT[0],CoordsT.size()/SPACEDIM,baryT); - for(typename std::vector::const_iterator iterCellS=srcCells.begin();iterCellS!=srcCells.end();iterCellS++) - { - NormalizedCellType tS=Intersector3DP1P0::_src_mesh.getTypeOfElement(OTT::indFC(*iterCellS)); - if(tS!=NORM_TETRA4) - throw INTERP_KERNEL::Exception("Invalid source cell detected for meshdim==3. Only TETRA4 supported !"); - const CellModel& cmTypeS=CellModel::GetCellModel(tS); - std::vector connOfCurCellS; - Intersector3DP1P0::getConnOfSourceCell(OTT::indFC(*iterCellS),connOfCurCellS); - if( PointLocatorAlgos::isElementContainsPointAlg3D(baryT,&connOfCurCellS[0],connOfCurCellS.size(),coordsS,cmTypeS,_precision) ) - { - double resLoc[4]; - std::vector srcCell; - Intersector3DP1P0::getRealSourceCoordinates(OTT::indFC(*iterCellS),srcCell); - std::vector eap(4); - eap[0]=&srcCell[0]; eap[1]=&srcCell[3]; eap[2]=&srcCell[6]; eap[3]=&srcCell[9]; - barycentric_coords(eap,baryT,resLoc); - const ConnType *startOfCellNodeConn=Intersector3DP1P0::getStartConnOfSourceCell(*iterCellS); - for(int nodeIdS=0;nodeIdS<4;nodeIdS++) - { - if(fabs(resLoc[nodeIdS])>_precision) - { - ConnType curNodeSInCmode=OTT::coo2C(startOfCellNodeConn[nodeIdS]); - typename MyMatrix::value_type::const_iterator iterRes=resRow.find(OTT::indFC(curNodeSInCmode)); - if(iterRes==resRow.end()) - resRow.insert(std::make_pair(OTT::indFC(curNodeSInCmode),resLoc[nodeIdS])); - else - { - double val=(*iterRes).second+resLoc[nodeIdS]; - resRow.erase(OTT::indFC(curNodeSInCmode)); - resRow.insert(std::make_pair(OTT::indFC(curNodeSInCmode),val)); - } - } - } - } - } - } -} - -#endif diff --git a/src/INTERP_KERNEL/PointLocator3DIntersectorP1P1.hxx b/src/INTERP_KERNEL/PointLocator3DIntersectorP1P1.hxx deleted file mode 100644 index 6eb18993f..000000000 --- a/src/INTERP_KERNEL/PointLocator3DIntersectorP1P1.hxx +++ /dev/null @@ -1,46 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 -// 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 __POINTLOCATOR3DINTERSECTORP1P1_HXX__ -#define __POINTLOCATOR3DINTERSECTORP1P1_HXX__ - -#include "Intersector3DP1P1.hxx" -#include "NormalizedUnstructuredMesh.hxx" - -namespace INTERP_KERNEL -{ - template - class PointLocator3DIntersectorP1P1 : public Intersector3DP1P1 - { - public: - static const int SPACEDIM=MyMeshType::MY_SPACEDIM; - static const int MESHDIM=MyMeshType::MY_MESHDIM; - typedef typename MyMeshType::MyConnType ConnType; - static const NumberingPolicy numPol=MyMeshType::My_numPol; - public: - PointLocator3DIntersectorP1P1(const MyMeshType& targetMesh, const MyMeshType& srcMesh, double precision); - ~PointLocator3DIntersectorP1P1(); - void intersectCells(ConnType targetCell, const std::vector& srcCells, MyMatrix& res); - protected: - double _precision; - }; -} - -#endif diff --git a/src/INTERP_KERNEL/PointLocator3DIntersectorP1P1.txx b/src/INTERP_KERNEL/PointLocator3DIntersectorP1P1.txx deleted file mode 100644 index ddc9c41b8..000000000 --- a/src/INTERP_KERNEL/PointLocator3DIntersectorP1P1.txx +++ /dev/null @@ -1,102 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 -// 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 __POINTLOCATOR3DINTERSECTORP1P1_TXX__ -#define __POINTLOCATOR3DINTERSECTORP1P1_TXX__ - -#include "PointLocator3DIntersectorP1P1.hxx" -#include "Intersector3DP1P1.txx" -#include "MeshUtils.hxx" - -namespace INTERP_KERNEL -{ - - /** - * Constructor creating object from target cell global number - * - * @param targetMesh mesh containing the target elements - * @param srcMesh mesh containing the source elements - * @param policy splitting policy to be used - */ - template - PointLocator3DIntersectorP1P1::PointLocator3DIntersectorP1P1(const MyMeshType& targetMesh, const MyMeshType& srcMesh, double precision): - Intersector3DP1P1(targetMesh,srcMesh),_precision(precision) - { - } - - template - PointLocator3DIntersectorP1P1::~PointLocator3DIntersectorP1P1() - { - } - - /** - * @param targetCell in C mode. - * @param srcCells in C mode. - */ - template - void PointLocator3DIntersectorP1P1::intersectCells(ConnType targetCell, const std::vector& srcCells, MyMatrix& res) - { - std::vector CoordsT; - Intersector3DP1P1::getRealTargetCoordinates(OTT::indFC(targetCell),CoordsT); - int nbOfNodesT=CoordsT.size()/SPACEDIM; - const double *coordsS=Intersector3DP1P1::_src_mesh.getCoordinatesPtr(); - for(typename std::vector::const_iterator iterCellS=srcCells.begin();iterCellS!=srcCells.end();iterCellS++) - { - NormalizedCellType tS=Intersector3DP1P1::_src_mesh.getTypeOfElement(OTT::indFC(*iterCellS)); - if(tS!=NORM_TETRA4) - throw INTERP_KERNEL::Exception("Invalid source cell detected for meshdim==3. Only TETRA4 supported !"); - const CellModel& cmTypeS=CellModel::GetCellModel(tS); - const ConnType *startOfCellNodeConnT=Intersector3DP1P1::getStartConnOfTargetCell(targetCell); - for(int nodeIdT=0;nodeIdT::ind2C(startOfCellNodeConnT[nodeIdT])]; - std::vector connOfCurCellS; - Intersector3DP1P1::getConnOfSourceCell(OTT::indFC(*iterCellS),connOfCurCellS); - if( PointLocatorAlgos::isElementContainsPointAlg3D(&CoordsT[nodeIdT*SPACEDIM],&connOfCurCellS[0],connOfCurCellS.size(),coordsS,cmTypeS,_precision) ) - { - double resLoc[4]; - std::vector localCoordsS; - Intersector3DP1P1::getRealSourceCoordinates(OTT::indFC(*iterCellS),localCoordsS); - std::vector eap(4); - eap[0]=&localCoordsS[0]; eap[1]=&localCoordsS[3]; eap[2]=&localCoordsS[6]; eap[3]=&localCoordsS[9]; - barycentric_coords(eap,&CoordsT[nodeIdT*SPACEDIM],resLoc); - const ConnType *startOfCellNodeConnS=Intersector3DP1P1::getStartConnOfSourceCell(*iterCellS); - for(int nodeIdS=0;nodeIdS<4;nodeIdS++) - { - if(fabs(resLoc[nodeIdS])>_precision) - { - ConnType curNodeSInCmode=OTT::coo2C(startOfCellNodeConnS[nodeIdS]); - typename MyMatrix::value_type::const_iterator iterRes=resRow.find(OTT::indFC(curNodeSInCmode)); - if(iterRes==resRow.end()) - resRow.insert(std::make_pair(OTT::indFC(curNodeSInCmode),resLoc[nodeIdS])); - else - { - double val=(*iterRes).second+resLoc[nodeIdS]; - resRow.erase(OTT::indFC(curNodeSInCmode)); - resRow.insert(std::make_pair(OTT::indFC(curNodeSInCmode),val)); - } - } - } - } - } - } - } -} - -#endif diff --git a/src/INTERP_KERNEL/PointLocatorAlgos.txx b/src/INTERP_KERNEL/PointLocatorAlgos.txx deleted file mode 100644 index 8a59aed65..000000000 --- a/src/INTERP_KERNEL/PointLocatorAlgos.txx +++ /dev/null @@ -1,326 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 -// 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 __POINTLOCATORALGOS_TXX__ -#define __POINTLOCATORALGOS_TXX__ - -#include "InterpolationUtils.hxx" -#include "CellModel.hxx" -#include "BBTree.txx" - -#include -#include -#include - -namespace INTERP_KERNEL -{ - class GenericPointLocatorAlgos - { - public: - virtual ~GenericPointLocatorAlgos() { } - virtual std::list locates(const double* x, double eps) = 0; - }; - - template - class PointLocatorAlgos: public GenericPointLocatorAlgos - { - private : - double* _bb; - BBTree* _tree; - const MyMeshType& _mesh; - public: - PointLocatorAlgos(const MyMeshType& mesh):_mesh(mesh) - { - typedef typename MyMeshType::MyConnType ConnType; - const int SPACEDIM=MyMeshType::MY_SPACEDIM; - const NumberingPolicy numPol=MyMeshType::My_numPol; - int nelem = _mesh.getNumberOfElements(); - _bb = new double[SPACEDIM*2*nelem]; - const ConnType* conn = _mesh.getConnectivityPtr(); - const ConnType* conn_index = _mesh.getConnectivityIndexPtr(); - const double* coords=_mesh.getCoordinatesPtr(); - for (int i=0; i::max(); - _bb[2*(i*SPACEDIM+idim)+1]=-std::numeric_limits::max(); - } - for (int index= conn_index[i]; index < conn_index[i+1];index++) - { - //coordelem points to the coordinates of the current node of the i-th element - const double* coordelem = coords+OTT::ind2C(conn[OTT::ind2C(index)])*SPACEDIM; - - //the bounding box is updated by checking wheher the node is at the min/max in exach dimension - for (int idim=0; idim_bb[2*(i*SPACEDIM+idim)+1])?coordelem[idim]:_bb[2*(i*SPACEDIM+idim)+1]; - } - } - } - _tree=new BBTree(_bb,0,0,nelem); - } - - ~PointLocatorAlgos() - { - delete[] _bb; - delete _tree; - } - - //returns the list of elements that contains - //the point pointed to by x - std::list locates(const double* x, double eps) - { - typedef typename MyMeshType::MyConnType ConnType; - const NumberingPolicy numPol=MyMeshType::My_numPol; - std::vector candidates; - _tree->getElementsAroundPoint(x,candidates); - std::list retlist; - for(unsigned int i=0; i< candidates.size(); i++) - { - int ielem=candidates[i]; - if (elementContainsPoint(ielem,x,eps)) - retlist.push_back(OTT::indFC(ielem)); - } - return retlist; - } - - static bool isElementContainsPointAlg2D(const double *ptToTest, const double *cellPts, int nbEdges, double eps) - { - /* with dimension 2, it suffices to check all the edges - and see if the sign of double products from the point - is always the same. - C - / \ - / \ - Xo / \ - A-------B - - here XA^XC and XC^XB have different signs*/ - const int SPACEDIM=MyMeshType::MY_SPACEDIM; - int* sign = new int[nbEdges]; - for (int iedge=0; iedgeeps) - sign[iedge]=1; - else - sign[iedge]=0; - } - bool ret=decideFromSign(sign, nbEdges); - delete [] sign; - return ret; - } - - static bool isElementContainsPointAlg3D(const double *ptToTest, const typename MyMeshType::MyConnType *conn_elem, int conn_elem_sz, const double *coords, const CellModel& cmType, double eps) - { - const int SPACEDIM=MyMeshType::MY_SPACEDIM; - typedef typename MyMeshType::MyConnType ConnType; - const NumberingPolicy numPol=MyMeshType::My_numPol; - - int nbfaces = cmType.getNumberOfSons2(conn_elem,conn_elem_sz); - int *sign = new int[nbfaces]; - int *connOfSon = new int[conn_elem_sz]; - for (int iface=0; iface::coo2C(connOfSon[0])); - const double* BB=coords+SPACEDIM*(OTT::coo2C(connOfSon[1])); - const double* CC=coords+SPACEDIM*(OTT::coo2C(connOfSon[2])); - double Vol=triple_product(AA,BB,CC,ptToTest); - if (Vol<-eps) - sign[iface]=-1; - else if (Vol>eps) - sign[iface]=1; - else - sign[iface]=0; - } - bool ret=decideFromSign(sign, nbfaces); - delete [] sign; - delete [] connOfSon; - return ret; - } - - static bool isElementContainsPoint(const double *ptToTest, NormalizedCellType type, const double *coords, const typename MyMeshType::MyConnType *conn_elem, int conn_elem_sz, double eps) - { - const int SPACEDIM=MyMeshType::MY_SPACEDIM; - typedef typename MyMeshType::MyConnType ConnType; - const NumberingPolicy numPol=MyMeshType::My_numPol; - - const CellModel& cmType=CellModel::GetCellModel(type); - // - if (SPACEDIM==2) - { - int nbEdges=cmType.getNumberOfSons(); - double *pts = new double[nbEdges*SPACEDIM]; - for (int iedge=0; iedge::ind2C(conn_elem[iedge])); - std::copy(a,a+SPACEDIM,pts+iedge*SPACEDIM); - } - bool ret=isElementContainsPointAlg2D(ptToTest,pts,nbEdges,eps); - delete [] pts; - return ret; - } - - if (SPACEDIM==3) - { - return isElementContainsPointAlg3D(ptToTest,conn_elem,conn_elem_sz,coords,cmType,eps); - } - - if(SPACEDIM==1) - { - double p1=coords[(OTT::ind2C(conn_elem[0]))]; - double p2=coords[(OTT::ind2C(conn_elem[1]))]; - double delta=fabs(p1-p2)+eps; - double val=*ptToTest-std::min(p1,p2); - return val>-eps && val::ind2C(conn_index[i]); - int conn_elem_sz=conn_index[i+1]-conn_index[i]; - NormalizedCellType type=_mesh.getTypeOfElement(OTT::indFC(i)); - return isElementContainsPoint(x,type,coords,conn_elem,conn_elem_sz,eps); - } - - static bool decideFromSign(const int* sign, int nbelem) - { - int min_sign = 1; - int max_sign = -1; - for (int i=0; imax_sign)?sign[i]:max_sign; - } - return (min_sign!=-1 || max_sign!=1); - } - }; - - template - class PointLocatorInSimplex : public PointLocatorAlgos - { - const MyMeshType& _mesh; - public: - PointLocatorInSimplex(const MyMeshType& mesh) - :PointLocatorAlgos(mesh),_mesh(mesh) - { - } - - //================================================================================ - /*! - * \brief Returns nodes composing the simplex the point x is in - */ - //================================================================================ - - virtual std::list locates(const double* x, double eps) - { - typedef typename MyMeshType::MyConnType ConnType; - const NumberingPolicy numPol=MyMeshType::My_numPol; - - std::list simplexNodes; - std::list candidates = PointLocatorAlgos::locates(x,eps); - std::list::iterator eIt = candidates.begin(); - for ( ; eIt != candidates.end(); ++eIt ) - { - const int i = OTT::ind2C( *eIt ); - const double* coords= _mesh.getCoordinatesPtr(); - const ConnType* conn=_mesh.getConnectivityPtr(); - const ConnType* conn_index= _mesh.getConnectivityIndexPtr(); - const ConnType* conn_elem=conn+OTT::ind2C(conn_index[i]); - int conn_elem_sz=conn_index[i+1]-conn_index[i]; - NormalizedCellType type=_mesh.getTypeOfElement(OTT::indFC(i)); - CellModel cell = CellModel::GetCellModel(type); - - if ( cell.isQuadratic() ) - throw Exception("P2 not implemented yet"); - - if ( cell.isSimplex()) - { - for ( int n = 0; n < conn_elem_sz; ++n ) - simplexNodes.push_back( conn_elem[ n ]); - } - else - { - NormalizedCellType simlexType = cell.getDimension()==3 ? NORM_TETRA4 : NORM_TRI3; - std::vector sonNodes; - NormalizedCellType sonType; - const unsigned nbSons = cell.getNumberOfSons2( conn_elem, conn_elem_sz ); - for ( unsigned s = 0; s < nbSons; ++s ) - { - sonNodes.resize( cell.getNumberOfNodesConstituentTheSon2( s, conn_elem, conn_elem_sz )); - cell.fillSonCellNodalConnectivity2( s, conn_elem, conn_elem_sz, &sonNodes[0], sonType ); - std::set sonNodesSet( sonNodes.begin(), sonNodes.end() ); - - std::set< std::set< ConnType > > checkedSonSimplex; - for ( unsigned sn = 0; sn < sonNodes.size(); ++sn ) - { - std::vector< ConnType > simplexConn( cell.getDimension() + 1 ); - unsigned n; - for ( n = 0; n < cell.getDimension()-1; ++n ) - simplexConn[n] = sonNodes[ (sn+n) % sonNodes.size() ]; - - for ( unsigned n2 = 0; n2 < sonNodes.size()-cell.getDimension()+1; ++n2 ) - { - simplexConn[n] = sonNodes[ (sn+n+n2) % sonNodes.size() ]; - std::set< ConnType > sonSimplex( simplexConn.begin(), --simplexConn.end()); - if ( checkedSonSimplex.insert( sonSimplex ).second ) - { - for ( unsigned cn = 0; cn < conn_elem_sz; ++cn ) - if ( !sonNodesSet.count( conn_elem[cn] )) - { - simplexConn.back() = conn_elem[cn]; - if ( this->isElementContainsPoint( x, simlexType, coords, - &simplexConn[0], simplexConn.size(), eps )) - { - simplexNodes.insert( simplexNodes.end(), - simplexConn.begin(), simplexConn.end()); - return simplexNodes; - } - } - } - } - } - } - } - } - return simplexNodes; - } - - }; -} - -#endif diff --git a/src/INTERP_KERNEL/PolygonAlgorithms.hxx b/src/INTERP_KERNEL/PolygonAlgorithms.hxx deleted file mode 100644 index bbb49362a..000000000 --- a/src/INTERP_KERNEL/PolygonAlgorithms.hxx +++ /dev/null @@ -1,94 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 -// 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 __POLYGONALGORITHMS_HXX__ -#define __POLYGONALGORITHMS_HXX__ - -#include -#include -#include - -namespace INTERP_KERNEL -{ - template - class VertexLess - { - public: - bool operator()(const double * P_1, const double * P_2) - { - for(int idim=0; idim P_2[idim]) return false; - } - return false; - } - }; - - template - class PolygonAlgorithms - { - public: - PolygonAlgorithms(double epsilon, double precision); - std::deque intersectConvexPolygons(const double* P_1,const double* P_2, int N1, int N2); - - //Not yet tested - int convexDecomposition(const double * P, int N, std::vector< std::map< int,int > >& components, - std::vector< int >& components_index, const double epsilon); - private: - void defineIndices(int& i_loc, int& i_next, int& i_prev, - const double *& Poly1, const double *& Poly2, - int& j1, int& j1_glob, int& j2, int& j2_glob, - int& j3, int& j3_glob, int& j4, int& j4_glob, - int& i_glob, int& i_next_glob, int& i_prev_glob, - const double * P_1, const double * P_2, - int N1, int N2, int sign); - void addCrossings( const double * A, const double * B, int i , int i_next, - const double * C, const double * D, int j1, int j2, - const double * E, const double * F, int j3, int j4, - const double * G); - void addCrossing0(const double * A, const double * B, int i, int i_next, - const double * C, const double * D, int j, int j_next); - void addCrossing( double * ABCD, std::pair< int,int > i_i_next, std::pair< int,int > j_j_next); - void addNewVertex( int i, int i_glob, int i_next_glob, int i_prev_glob, const double * P); - bool intersectSegmentSegment(const double * A, const double * B, const double * C, - const double * D, const double * E, double * V); - - - //Not yet tested - void convexDecomposition(const double* P, int N, double* n, std::vector< int > subP, int NsubP, - std::vector< std::map< int,int > >& components, std::vector< int >& components_index, - int& Ncomp, int sign, const double epsilon); - void convHull(const double *P, int N, double * n, std::map< int,int >& subP, - std::map< int,int >& not_in_hull, int& NsubP, const double epsilon); - private: - std::deque< double > _Inter;/* vertices of the intersection P1^P2 */ - std::vector< std::pair< int,int > > _End_segments; /* segments containing inter final edges */ - /* status list of segments (ending point, starting point) intersected by the sweeping line */ - /* and a boolean true if the ending point is in the intersection */ - std::multimap< int, std::pair< int,bool> > _Status; - bool _is_in_intersection; - bool _terminus; - double _vdouble[DIM]; - double _epsilon; - double _precision; - }; -} - -#endif diff --git a/src/INTERP_KERNEL/PolygonAlgorithms.txx b/src/INTERP_KERNEL/PolygonAlgorithms.txx deleted file mode 100644 index cda3f5b1f..000000000 --- a/src/INTERP_KERNEL/PolygonAlgorithms.txx +++ /dev/null @@ -1,824 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 -// 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 __POLYGONALGORITHMS_TXX__ -#define __POLYGONALGORITHMS_TXX__ - -#include "PolygonAlgorithms.hxx" -#include "InterpolationUtils.hxx" -#include -#include -#include - -namespace INTERP_KERNEL -{ - template - PolygonAlgorithms::PolygonAlgorithms(double epsilon, double precision)//: (0) - { - _is_in_intersection = false; - _epsilon = epsilon; - _precision = precision; - } - /*************************************************************/ - /* Computes the 3D intersection between two COPLANAR */ - /* Segments [A,B] and [C,D], stores the result in V. */ - /* If A belongs to [CD] then the vertex E (preceeding A) */ - /* is used to decide if the crossing is real. If A coincides */ - /* with C or D, a special treatment is performed */ - /*************************************************************/ - template - bool PolygonAlgorithms::intersectSegmentSegment(const double * A, const double * B, const double * C, - const double * D, const double * E, double * V) - { - double AB[DIM], DC[DIM], AC[DIM], det, t1, t2, inv_det; - - /******* Initialisation of the linear system t1*AB+t2*DC=AC ***********/ - for(int idim=0;idim_epsilon) - { - inv_det = 1/det; - t1 = determinant(AC,DC)*inv_det;//solves the linear system t1*AB+t2*DC=AC - t2 = determinant(AB,AC)*inv_det;//solves the linear system t1*AB+t2*DC=AC - } - else - { - switch(DIM) - { - case 2: - { - if(distance2(A,D)<_epsilon) - crossprod(A,C,E,_vdouble);//store the crossprod between vectors AC and AE (E=vertex preceding A) - return false;//case of paralell segments - } - case 3://beware AB and CD may belong to a vertical plane - det = determinant(&AB[1],&DC[1]);//determinant of the last two coefficients - if(fabs(det) > _epsilon) - { - inv_det = 1/det; - t1=(AC[1]*DC[DIM-1]-AC[DIM-1]*DC[1])*inv_det; - t2=(AB[1]*AC[DIM-1]-AB[DIM-1]*AC[1])*inv_det; - } - else //beware AB and CD may belong to a plane y = constant - { - det = AB[0]*DC[DIM-1]-AB[DIM-1]*DC[0]; - if(fabs(det) > _epsilon) - { - inv_det = 1/det; - t1=(AC[0]*DC[DIM-1]-AC[DIM-1]*DC[0])*inv_det; - t2=(AB[0]*AC[DIM-1]-AB[DIM-1]*AC[0])*inv_det; - } - else - { - if(distance2(A,D)<_epsilon) - crossprod(A,C,E,_vdouble);//store the crossprod between vectors AC and AE (E=vertex preceding A) - return false;//case of paralell segments - } - } - } - } - - if(t1>_precision && t1<1-_precision) - { - if( t2>_precision && t2<1-_precision) - { - for(int idim=0;idim_precision && t2<1-_precision)//vertex on an edge - { - double V12[DIM]; - double V34[DIM]; - crossprod(A,D,B,V12); - crossprod(A,D,E,V34); - double same_side =dotprod(V12, V34); - if( same_side < -_epsilon ) // <= epsilon or 0 ?//crossing - { - for(int idim=0;idim _epsilon ) _terminus= !_is_in_intersection;//reflexion - else //separation of overlaping edges - { - if(_Inter.empty() ) _terminus=true; - else if(!_is_in_intersection) - { - for(int idim=0;idim(A,C,E,_vdouble);//store the angle between vectors AC and AE (E=vertex preceding A) - else if(fabs(t2) <= _precision)//vertex on a vertex (A=C), second run - { - double Vdoublebis[DIM]; - //crossprod(A,C,E,_vdouble); - crossprod(A,B,D,Vdoublebis); - double in_between =dotprod(Vdoublebis,_vdouble); - if(in_between>_epsilon)//crossing - { - for(int idim=0;idim(Vdoublebis,Vdoublebis) > _epsilon) - //ie _vdouble=0, separation of overlaping edges at a double point - { - //crossprod(A,E,B,_vdouble); - if(dotprod(_vdouble,Vdoublebis) >=_epsilon )//crossing - { - if(_Inter.empty()) _terminus=true; - else if(!_is_in_intersection) - { - for(int idim=0;idim - inline void PolygonAlgorithms::addNewVertex( int i, int i_glob, int i_next_glob, int i_prev_glob, - const double * P) - { - /* Question:Should we add vertex i to the front or back ? */ - if( _End_segments[1].second == i_glob) - { - for(int idim=0;idim-1;idim--) _Inter.push_front(P[DIM*i+idim]); - _End_segments[0] = std::make_pair(i_glob, i_next_glob); - } - } - - /************************************************************/ - /* adds a crossing between two segments starting at i and j */ - /* to the double ended list inter in the correct order */ - /* according to endsegments, updates _End_segments */ - /************************************************************/ - template - inline void PolygonAlgorithms::addCrossing( double * ABCD, std::pair< int,int > i_i_next, - std::pair< int,int > j_j_next) - { - if(!_Inter.empty() ) - { - if(_End_segments[0] ==i_i_next) - { - for(int idim=DIM-1;idim>=0;idim--) _Inter.push_front(ABCD[idim]); - _terminus= (_End_segments[1]== j_j_next); - _End_segments[0] = j_j_next; - } - else - { - if( _End_segments[0]== j_j_next) - { - for(int idim=DIM-1;idim>=0;idim--) _Inter.push_front(ABCD[idim]); - _terminus= (_End_segments[1]== i_i_next); - _End_segments[0] = i_i_next; - } - else - { - for(int idim=0;idim - void PolygonAlgorithms::addCrossing0(const double * A, const double * B, int i, int i_next, - const double * C, const double * D, int j, int j_next) - { - double ABCD[DIM]; - if(intersectSegmentSegment(A,B,C,D,ABCD, ABCD)) - //fifth and sixth arguments are useless here - { - /* Updating _End_segments */ - std::pair< int,int > i_i_next = std::make_pair(i, i_next); - std::pair< int,int > j_j_next = std::make_pair(j, j_next); - if( _End_segments[0] == i_i_next) - { - for(int idim=DIM-1;idim>-1;idim--) _Inter.push_front(ABCD[idim]); - _End_segments[0] = j_j_next; - } - else - { - for(int idim=0;idim >::iterator mi =_Status.find(j_next); - ((* mi).second).second= !((* mi).second).second; - } - else _Status.insert(std::make_pair(i_next,std::make_pair(i,true))); - } - - /*******************************************************/ - /* adds the possible crossings between segments [A,B] (with end-point global indices i and i_next) */ - /*and segments [C,D] and [E,F] to the list inter and updates _End_segments */ - /* In cases of ambiguity, the vertex G is used to decide wether the crossing should be accepted */ - /*******************************************************/ - template - inline void PolygonAlgorithms::addCrossings( const double * A, const double * B, int i , int i_next, - const double * C, const double * D, int j1, int j2, - const double * E, const double * F, int j3, int j4, - const double * G) - { - double ABCD[DIM]; - double ABEF[DIM]; - std::multimap< int, std::pair< int,bool> >::iterator mi; - - if(intersectSegmentSegment(A,B,C,D,G,ABCD)) - { - if(intersectSegmentSegment(A,B,E,F,G,ABEF)) - { - VertexLess vl; - if (vl(ABCD,ABEF)) - { - addCrossing(ABCD, std::make_pair(i, i_next), std::make_pair(j1, j2)); - addCrossing(ABEF, std::make_pair(i, i_next), std::make_pair(j3, j4)); - } - else - { - addCrossing(ABEF, std::make_pair(i, i_next), std::make_pair(j3, j4)); - addCrossing(ABCD, std::make_pair(i, i_next), std::make_pair(j1, j2)); - } - _Status.insert(std::make_pair(i_next,std::make_pair(i, _is_in_intersection))); - mi=_Status.find(j2); - ((* mi).second).second= !((* mi).second).second; - mi=_Status.find(j4); - ((* mi).second).second= !((* mi).second).second; - } - else - { - addCrossing(ABCD, std::make_pair( i, i_next), std::make_pair(j1,j2)); - _Status.insert(std::make_pair(i_next,std::make_pair(i, !_is_in_intersection))); - mi=_Status.find(j2); - ((* mi).second).second= !((* mi).second).second; - } - } - else - { - if(intersectSegmentSegment(A,B,E,F,G, ABEF)) - { - addCrossing(ABEF, std::make_pair( i, i_next), std::make_pair( j3, j4)); - _Status.insert(std::make_pair(i_next,std::make_pair(i, !_is_in_intersection))); - mi=_Status.find(j4); - ((* mi).second).second= !((* mi).second).second; - } - else _Status.insert(std::make_pair(i_next,std::make_pair(i, _is_in_intersection))); - } - } - - - /* define various indices required in the function intersect_conv_polygon */ - /* vertices from the both polygons are supposed to be present in the status */ - template - inline void PolygonAlgorithms::defineIndices(int& i_loc, int& i_next, int& i_prev, - const double *& Poly1, const double *& Poly2, - int& j1, int& j1_glob, int& j2, int& j2_glob, - int& j3, int& j3_glob, int& j4, int& j4_glob, - int& i_glob, int& i_next_glob, int& i_prev_glob, - const double * P_1, const double * P_2, - int N1, int N2, int sign) - { - int N0, shift; - if(i_glob < N1) - { - N0 = N1; - shift = 0; - Poly1 = P_1; - Poly2 = P_2; - - std::multimap< int, std::pair< int,bool> >::reverse_iterator mi1=_Status.rbegin(); - j1_glob=((*mi1).second).first; - j1=j1_glob-N1; - j2_glob=(*mi1).first; - j2=j2_glob-N1; - mi1++; - j3_glob=((*mi1).second).first; - j3=j3_glob-N1; - j4_glob=(*mi1).first; - j4=j4_glob-N1; - } - else - { - N0 = N2; - shift = N1; - Poly1 = P_2; - Poly2 = P_1; - - std::multimap< int, std::pair< int,bool> >::iterator mi2= _Status.begin(); - j1_glob=((*mi2).second).first; - j1=j1_glob; - j2_glob=(*mi2).first; - j2=j2_glob; - mi2++; - j3_glob=((*mi2).second).first; - j3=j3_glob; - j4_glob=(*mi2).first; - j4=j4_glob; - } - i_loc = i_glob-shift; - i_next = (i_next_glob-shift+N0)%N0;//end-point of segment starting at i - i_prev = (i_prev_glob-shift+N0)%N0; - i_next_glob = i_next+shift; - i_prev_glob = i_prev+shift; - //warning: sign is either 1 or -1; - //To do: test and remove from Convex_intersecor.cxx - // while(distance2(&Poly1[DIM*i_loc],&Poly1[DIM*i_next])< _epsilon && i_next != i_loc) - // i_next =(i_next+sign+N0)%N0; - // while(distance2(&Poly1[DIM*i_loc],&Poly1[DIM*i_prev])< _epsilon && i_prev != i_loc) - // i_prev =(i_prev+sign+N0)%N0; - } - /*******************************************************/ - /* computes the vertices of the intersection of two COPLANAR */ - /* simple (no dble points)convex polygons using line sweep algorithm */ - /* P1 and P2 contain the 3D coordinates of the successive vertices */ - /*******************************************************/ - template - std::deque< double > PolygonAlgorithms::intersectConvexPolygons(const double* P_1,const double* P_2, - int N1, int N2) - { - int i_loc, i_glob, j1, j1_glob, j2,j2_glob, j3, j3_glob, j4,j4_glob, - i_prev, i_prev_glob, i_next, i_next_glob, nb_prev, sign, idim; - const double * Poly1, * Poly2; - bool four_neighbours=false; - _terminus = N1 < 3 || N2<3; - - /* list of future events ordered according to their coordinates (x,y,z) (lexicographical order) */ - std::multimap< const double *, int, VertexLess > mmap_events; - typename std::list< std::pair< const double *, int > >::iterator mi1,mi2; - - std::multimap< int, std::pair< int,bool> >::iterator mi; - - /********** Initalisation of events with P1 and P2 vertices ************/ - for(i_loc=0;i_loc > events(mmap_events.begin(),mmap_events.end()); - - if(!_terminus) - { - /******** Treatment of the first vertex ********/ - mi1=events.begin(); - i_glob = (* mi1).second; - bool which_start = i_glob < N1; - if(i_glob < N1){ i_next_glob = (i_glob +1)%N1; i_prev_glob = (i_glob -1+N1)%N1;} - else{ i_next_glob = (i_glob-N1+1)%N2 + N1;i_prev_glob = (i_glob-N1-1+N2)%N2 + N1;} - _Status.insert(std::make_pair(i_next_glob,std::make_pair(i_glob, false))); - _Status.insert(std::make_pair(i_prev_glob,std::make_pair(i_glob, false))); - mi1++; - //std::cout<< "nb_prev= "<< 0 << " i_glob= " << i_glob << std::endl; - - /******* Loop until the second polygon is reached *******/ - while( !four_neighbours) - { - i_glob=(* mi1).second;//global index of vertex i - nb_prev = _Status.count(i_glob);//counts the number of segments ending at i - - //std::cout<< "nb_prev= "<< nb_prev << " i_glob= " << i_glob << std::endl; - switch (nb_prev) - { - case 1 : - mi=_Status.find(i_glob);// pointer to the segment ending at i - i_prev_glob = ((*mi).second).first;//starting point of the segment ending at i - i_next= (i_prev_glob - i_glob > 0) == (abs(i_prev_glob - i_glob) == 1) ? i_glob - 1 : i_glob + 1; - if(i_glob < N1) i_next_glob = (i_next +N1)%N1; - else i_next_glob = (i_next-N1+N2)%N2 + N1; - _Status.erase(mi); - _Status.insert(std::make_pair(i_next_glob,std::make_pair(i_glob, false))); - mi1++; - break; - case 2 : - return _Inter; - case 0 : - if( (i_glob < N1) != which_start) - { - mi2=mi1; - mi2++; - /* detection of double points */ - if(distance2((* mi1).first, (*mi2).first) > _epsilon) - four_neighbours = true; - else /* Rare pothological case: */ - { - const std::pair< const double *, int > next_pt= *mi2; - events.erase(mi2); - mi1=events.insert(mi1,next_pt); - } - } - break; - default: - throw Exception("intersectConvexPolygon: sequence of nodes does not describe a simple polygon (1)"); - } - } - /******** Loop until a terminal point or crossing is reached ************/ - while( !_terminus) - { - //std::cout<< "nb_prev= "<< nb_prev<< " nb_inter= " << _Inter.size()/DIM << std::endl; - switch (nb_prev) - { - case 1 : - mi=_Status.find(i_glob);// pointer to the segment ending at i - i_prev_glob = ((*mi).second).first;//starting point of the segment ending at i - sign = (i_prev_glob - i_glob > 0) == (abs(i_prev_glob - i_glob) == 1) ? - 1 : + 1; - i_next_glob = i_glob+sign; - _is_in_intersection = ((*mi).second).second;//boolean that tells if i is in the intersection - _Status.erase(mi); - defineIndices(i_loc,i_next,i_prev, Poly1,Poly2, - j1,j1_glob,j2,j2_glob,j3,j3_glob,j4,j4_glob, - i_glob,i_next_glob,i_prev_glob, P_1,P_2, N1, N2, sign); - if( _is_in_intersection ) addNewVertex(i_loc, i_glob, i_next_glob, i_prev_glob, Poly1); - addCrossings(&Poly1[DIM*i_loc], &Poly1[DIM*i_next], i_glob, i_next_glob, - &Poly2[DIM*j1] , &Poly2[DIM*j2] , j1_glob,j2_glob, - &Poly2[DIM*j3] , &Poly2[DIM*j4] , j3_glob,j4_glob, &Poly1[DIM*i_prev]); - break; - case 2 : - if(!_Inter.empty()) - { - if(i_glob < N1) for(idim=0;idim(&Poly1[DIM*i_loc],&Poly2[DIM*j1],&Poly2[DIM*j2], - &Poly2[DIM*j3], &Poly2[DIM*j4],V12, V34); - _is_in_intersection=( inside < _epsilon ); // <= epsilon or 0 ? - - if(fabs(inside) > _epsilon)//vertex clearly inside or outside - { - //std::cout<<"coucou1" << std::endl; - if( _is_in_intersection) - { - for(int iidim=0;iidim(V34,V34) > _epsilon)//vertex i on edge (j1,j2), not on (j3,j4) - { - crossprod(&Poly1[DIM*i_loc], &Poly2[DIM*j2], &Poly1[DIM*i_next],Vnext); - crossprod(&Poly1[DIM*i_loc], &Poly2[DIM*j2], &Poly1[DIM*i_prev],Vprev); - is_inside_next= (dotprod(Vnext,V34)<0); - is_inside_prev= (dotprod(Vprev,V34)<0); - - if(!(is_inside_next || is_inside_prev)) return std::deque< double >(); - - if(is_inside_next) - { - _End_segments.push_back(std::make_pair(i_glob,i_next_glob)); - addCrossing0(&Poly1[DIM*i_loc], &Poly1[DIM*i_next], i_glob, i_next_glob, - &Poly2[DIM*j3] , &Poly2[DIM*j4] , j3_glob,j4_glob); - } - else - { - _End_segments.push_back(std::make_pair(j1_glob,j2_glob)); - _Status.insert(std::make_pair(i_next_glob,std::make_pair(i_glob, false))); - mi=_Status.find(j2_glob); - ((* mi).second).second= !((* mi).second).second; - } - if(is_inside_prev) - { - _End_segments.push_back(std::make_pair(i_glob,i_prev_glob)); - addCrossing0(&Poly1[DIM*i_loc], &Poly1[DIM*i_prev], i_glob, i_prev_glob, - &Poly2[DIM*j3] , &Poly2[DIM*j4] , j3_glob,j4_glob); - } - else - { - _End_segments.push_back(std::make_pair(j1_glob,j2_glob)); - _Status.insert(std::make_pair(i_prev_glob,std::make_pair(i_glob, false))); - mi=_Status.find(j2_glob); - ((* mi).second).second= !((* mi).second).second; - } - } - else if(dotprod(V12,V12) > _epsilon)//vertex i on a edge (j3,j4), not on (j1,j2) - { - crossprod(&Poly1[DIM*i_loc], &Poly2[DIM*j4], &Poly1[DIM*i_next],Vnext); - crossprod(&Poly1[DIM*i_loc], &Poly2[DIM*j4], &Poly1[DIM*i_prev],Vprev); - is_inside_next= dotprod(Vnext,V12)<0; - is_inside_prev= dotprod(Vprev,V12)<0; - - if(!(is_inside_next || is_inside_prev)) return std::deque< double >(); - - if(is_inside_next) - { - _End_segments.push_back(std::make_pair(i_glob,i_next_glob)); - addCrossing0(&Poly1[DIM*i_loc], &Poly1[DIM*i_next], i_glob, i_next_glob, - &Poly2[DIM*j1] , &Poly2[DIM*j2] , j1_glob,j2_glob); - } - else - { - _End_segments.push_back(std::make_pair(j3_glob,j4_glob)); - _Status.insert(std::make_pair(i_next_glob,std::make_pair(i_glob, false))); - mi=_Status.find(j4_glob); - ((* mi).second).second= ! ((* mi).second).second; - } - if(is_inside_prev) - { - _End_segments.push_back(std::make_pair(i_glob,i_prev_glob)); - addCrossing0(&Poly1[DIM*i_loc], &Poly1[DIM*i_prev], i_glob, i_prev_glob, - &Poly2[DIM*j1] , &Poly2[DIM*j2] , j1_glob,j2_glob); - } - else - { - _End_segments.push_back(std::make_pair(j3_glob,j4_glob)); - _Status.insert(std::make_pair(i_prev_glob,std::make_pair(i_glob, false))); - mi=_Status.find(j4_glob); - ((* mi).second).second= !((* mi).second).second; - } - } - else //vertices i, j1 and j3 share the same coordinates - { - crossprod(&Poly1[DIM*i_loc], &Poly2[DIM*j2], &Poly1[DIM*i_next],Vnext); - crossprod(&Poly1[DIM*i_loc], &Poly2[DIM*j2], &Poly1[DIM*i_prev],Vprev); - crossprod(&Poly1[DIM*i_loc], &Poly2[DIM*j4], &Poly1[DIM*i_next],V12); - crossprod(&Poly1[DIM*i_loc], &Poly2[DIM*j4], &Poly1[DIM*i_prev],V34); - - double inside_next= dotprod(Vnext,V12); - double inside_prev= dotprod(Vprev,V34); - double inside_j2 = dotprod(Vnext,Vprev); - double inside_j4 = dotprod(V12,V34); - - std::map > which_is_inside; - which_is_inside[inside_next] = std::make_pair(i_glob,i_next_glob); - which_is_inside[inside_prev] = std::make_pair(i_glob,i_prev_glob); - which_is_inside[inside_j2] = std::make_pair(j1_glob,j2_glob); - which_is_inside[inside_j4] = std::make_pair(j3_glob,j4_glob); - - std::map >::iterator min = which_is_inside.begin(); - std::map >::iterator minext = min; - minext++; - std::map >::reverse_iterator max = which_is_inside.rbegin(); - std::multimap< int, std::pair< int,bool> >::iterator j2_in_status = _Status.find(((*min).second).second); - std::multimap< int, std::pair< int,bool> >::iterator j4_in_status = _Status.find(((*minext).second).second); - - if((*min).first < -_epsilon) //there is someone clearly inside - { - _End_segments.push_back( (*min).second ); - _End_segments.push_back((* minext).second); - if(j2_in_status != _Status.end()) - ((*j2_in_status).second).second = ! ((*j2_in_status).second).second; - if(j4_in_status != _Status.end()) - ((*j4_in_status).second).second = ! ((*j4_in_status).second).second; - is_inside_next = ((*min).second).second == i_next_glob || ((*minext).second).second == i_next_glob; - is_inside_prev = ((*min).second).second == i_prev_glob || ((*minext).second).second == i_prev_glob; - } - else - if(fabs((*min).first) <= _epsilon) //nobody is clearly inside but two segments are superposed - { - if(fabs((*max).first) > _epsilon) - return std::deque< double >(); - else //all four segments are superposed - { - _End_segments.push_back(std::make_pair(i_glob,i_next_glob)); - _End_segments.push_back(std::make_pair(i_glob,i_prev_glob)); - is_inside_next= true; - is_inside_prev= true; - } - } - else //there is nobody inside - return std::deque< double >(); - - _Status.insert(std::make_pair(i_prev_glob,std::make_pair(i_glob,is_inside_prev))); - _Status.insert(std::make_pair(i_next_glob,std::make_pair(i_glob,is_inside_next))); - } - } - } - break; - default: - std::cout << "Problem: nbprev= " << nb_prev << " ; i_glob = " << i_glob << std::endl; - throw Exception("intersectConvexPolygon: sequence of nodes does not describe a simple polygon (2)"); - } - mi1++; - i_glob=(* mi1).second;//global index of vertex i - nb_prev = _Status.count(i_glob); - } - } - return _Inter; - } - - /**************************************************************************/ - /* computes the convex hull of a polygon subP which is a sub polygon of P */ - /* P is the array of coordinates, subP is a map containing initially the indices of a subpolygon of P */ - /* in the end, subP contains only the elements belonging to the convex hull, and not_in_hull the others */ - /**************************************************************************/ - template - inline void PolygonAlgorithms::convHull(const double *P, int N, double * normal, - std::map< int,int >& subP, std::map< int,int >& not_in_hull, - int& NsubP, const double epsilon) - { - if(NsubP>3) - { - std::map< int,int >::iterator mi_prev = subP.begin(); - std::map< int,int >::iterator mi = mi_prev; - mi++; - std::map< int,int >::iterator mi_next = mi; - mi_next++; - double directframe=0.; - - /* Check if the polygon subP is positively oriented */ - std::map< int,int >::iterator mi1=mi; - while(mi1 != subP.end() && distance2(&P[DIM*(*subP.begin()).second],&P[DIM*(*mi1).second])< epsilon) - mi1++; - std::map< int,int >::iterator mi2=mi1; - while(mi2 != subP.end() && fabs(directframe)(&P[DIM* (*mi1).second], - &P[DIM* (*subP.begin()).second], - &P[DIM* (*mi2).second], normal); - mi2++; - } - if(directframe < 0) for(int idim=0; idim< DIM; idim++) normal[idim] *= -1; - - /* Core of the algorithm */ - while(mi_next != subP.end()) - { - directframe = direct_frame(&P[DIM* (*mi).second], - &P[DIM* (*mi_prev).second], - &P[DIM* (*mi_next).second], normal); - if(directframe > -epsilon){ - mi ++; - mi_prev++; - mi_next++; - } - else - { - not_in_hull.insert(*mi); - subP.erase(mi); - NsubP--; - mi--; - } - } - directframe = direct_frame(&P[DIM*(*mi).second], - &P[DIM*(*mi_prev).second], - &P[DIM*(*subP.begin()).second], normal); - if(directframe < -epsilon) - { - not_in_hull.insert(*mi); - subP.erase(mi); - NsubP--; - } - } - } - - template - void PolygonAlgorithms::convexDecomposition(const double * P, int N, double *normal, std::vector< int > subP, int NsubP, - std::vector< std::map< int,int > >& components, std::vector< int >& components_index, - int& Ncomp, int sign, const double epsilon) - { - int i; - std::map< int, int > hull; - std::map< int, int > not_in_hull; - std::map< int, int >::iterator mi, mj; - std::vector< int > reflex_region; - int Nreflex; - int i_xmax=0; - const double * xmax=&P[DIM*subP[0]]; - /* checking an extremal point of subP */ - for(i=0; i xmax) - { - i_xmax=i; - xmax=&P[DIM*subP[i]]; - } - } - /* renumbering of SubP elements for the convex hull*/ - for(i=0; i - int PolygonAlgorithms::convexDecomposition(const double * P, int N, std::vector< std::map< int,int > >& components, - std::vector< int >& components_index, const double epsilon) - { - int Ncomp=0; - std::vector< int > subP(N); - double normal[3]={0,0,0}; - - for(int i = 0; i(&P[0],&P[i1])< epsilon) i1++; - int i2=i1+1; - while(i2(normal,normal))(&P[i1], &P[0], &P[i2],normal); - i2++; - } - - convexDecomposition(P, N, normal, subP, N, components, components_index, Ncomp, 1, epsilon); - return Ncomp; - } -} - -#endif diff --git a/src/INTERP_KERNEL/Polyhedron3D2DIntersectorP0P0.hxx b/src/INTERP_KERNEL/Polyhedron3D2DIntersectorP0P0.hxx deleted file mode 100644 index 6c5a2d1f9..000000000 --- a/src/INTERP_KERNEL/Polyhedron3D2DIntersectorP0P0.hxx +++ /dev/null @@ -1,79 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 -// 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 __POLYHEDRON3D2DINTERSECTORP0P0_HXX__ -#define __POLYHEDRON3D2DINTERSECTORP0P0_HXX__ - -#include "Intersector3DP0P0.hxx" -#include "SplitterTetra.hxx" -#include "NormalizedUnstructuredMesh.hxx" - -namespace INTERP_KERNEL -{ - - - /** - * \brief Class responsible for calculating intersection between a hexahedron target element and - * the source elements. - * - */ - template - class Polyhedron3D2DIntersectorP0P0 : public Intersector3DP0P0 - { - typedef typename std::map > DuplicateFacesType; - - public: - static const int SPACEDIM=MyMeshType::MY_SPACEDIM; - static const int MESHDIM=MyMeshType::MY_MESHDIM; - typedef typename MyMeshType::MyConnType ConnType; - static const NumberingPolicy numPol=MyMeshType::My_numPol; - - public: - - Polyhedron3D2DIntersectorP0P0(const MyMeshType& targetMesh, - const MyMeshType& srcMesh, - const double dimCaracteristic, - const double precision, - DuplicateFacesType& intersectFaces, - SplittingPolicy policy = PLANAR_FACE_5); - - ~Polyhedron3D2DIntersectorP0P0(); - - void intersectCells(ConnType targetCell, - const std::vector& srcCells, - MyMatrixType& matrix); - - private: - void releaseArrays(); - private: - /// pointers to the SplitterTetra objects representing the tetrahedra - /// that result from the splitting of the hexahedron target cell - std::vector< SplitterTetra* > _tetra; - - SplitterTetra2 _split; - - double _dim_caracteristic; - double _precision; - - DuplicateFacesType& _intersect_faces; - - }; -} - -#endif diff --git a/src/INTERP_KERNEL/Polyhedron3D2DIntersectorP0P0.txx b/src/INTERP_KERNEL/Polyhedron3D2DIntersectorP0P0.txx deleted file mode 100644 index 85d58450b..000000000 --- a/src/INTERP_KERNEL/Polyhedron3D2DIntersectorP0P0.txx +++ /dev/null @@ -1,169 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 -// 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 __POLYHEDRON3D2DINTERSECTORP0P0_TXX__ -#define __POLYHEDRON3D2DINTERSECTORP0P0_TXX__ - -#include "Polyhedron3D2DIntersectorP0P0.hxx" -#include "Intersector3DP0P0.txx" -#include "MeshUtils.hxx" - -#include "SplitterTetra.txx" - -namespace INTERP_KERNEL -{ - - /** - * Constructor creating object from target cell global number - * The constructor first calculates the necessary nodes, - * (depending on the splitting policy) and then splits the hexahedron into - * tetrahedra, placing these in the internal vector _tetra. - * - * @param targetMesh mesh containing the target elements - * @param srcMesh mesh containing the source elements - * @param policy splitting policy to be used - */ - template - Polyhedron3D2DIntersectorP0P0::Polyhedron3D2DIntersectorP0P0(const MyMeshType& targetMesh, - const MyMeshType& srcMesh, - const double dimCaracteristic, - const double precision, - DuplicateFacesType& intersectFaces, - SplittingPolicy policy) - : Intersector3DP0P0(targetMesh,srcMesh), - _split(targetMesh,srcMesh,policy), - _dim_caracteristic(dimCaracteristic), - _precision(precision), - _intersect_faces(intersectFaces) - { - } - - /** - * Destructor. - * Liberates the SplitterTetra objects and potential sub-node points that have been allocated. - * - */ - template - Polyhedron3D2DIntersectorP0P0::~Polyhedron3D2DIntersectorP0P0() - { - releaseArrays(); - } - - template - void Polyhedron3D2DIntersectorP0P0::releaseArrays() - { - for(typename std::vector< SplitterTetra* >::iterator iter = _tetra.begin(); iter != _tetra.end(); ++iter) - delete *iter; - _split.releaseArrays(); - _tetra.clear(); - } - - /** - * Calculates the volume of intersection of an element in the source mesh and the target element - * represented by the object. - * The calculation is performed by calling the corresponding method for - * each SplitterTetra object created by the splitting. - * - * @param targetCell in C mode. - * @param srcCells in C mode. - */ - template - void Polyhedron3D2DIntersectorP0P0::intersectCells(ConnType targetCell, - const std::vector& srcCells, - MyMatrixType& matrix) - { - int nbOfNodesT=Intersector3D::_target_mesh.getNumberOfNodesOfElement(OTT::indFC(targetCell)); - releaseArrays(); - _split.splitTargetCell(targetCell,nbOfNodesT,_tetra); - - for(typename std::vector::const_iterator iterCellS=srcCells.begin();iterCellS!=srcCells.end();iterCellS++) - { - double surface = 0.; - std::multiset listOfTetraFacesTreated; - std::set listOfTetraFacesColinear; - - // calculate the coordinates of the nodes - typename MyMeshType::MyConnType cellSrc = *iterCellS; - int cellSrcIdx = OTT::indFC(cellSrc); - NormalizedCellType normCellType=Intersector3D::_src_mesh.getTypeOfElement(cellSrcIdx); - const CellModel& cellModelCell=CellModel::GetCellModel(normCellType); - const MyMeshType& src_mesh = Intersector3D::_src_mesh; - unsigned nbOfNodes4Type=cellModelCell.isDynamic() ? src_mesh.getNumberOfNodesOfElement(cellSrcIdx) : cellModelCell.getNumberOfNodes(); - int *polyNodes=new int[nbOfNodes4Type]; - double **polyCoords = new double*[nbOfNodes4Type]; - for(int i = 0;i<(int)nbOfNodes4Type;++i) - { - // we could store mapping local -> global numbers too, but not sure it is worth it - const int globalNodeNum = getGlobalNumberOfNode(i, OTT::indFC(*iterCellS), src_mesh); - polyNodes[i] = globalNodeNum; - polyCoords[i] = const_cast(src_mesh.getCoordinatesPtr()+MyMeshType::MY_SPACEDIM*globalNodeNum); - } - - for(typename std::vector*>::iterator iter = _tetra.begin(); iter != _tetra.end(); ++iter) - surface += (*iter)->intersectSourceFace(normCellType, - nbOfNodes4Type, - polyNodes, - polyCoords, - _dim_caracteristic, - _precision, - listOfTetraFacesTreated, - listOfTetraFacesColinear); - - if(surface!=0.) - { - - matrix[targetCell].insert(std::make_pair(cellSrcIdx, surface)); - - bool isSrcFaceColinearWithFaceOfTetraTargetCell = false; - std::set::iterator iter; - for (iter = listOfTetraFacesColinear.begin(); iter != listOfTetraFacesColinear.end(); ++iter) - { - if (listOfTetraFacesTreated.count(*iter) != 1) - { - isSrcFaceColinearWithFaceOfTetraTargetCell = false; - break; - } - else - { - isSrcFaceColinearWithFaceOfTetraTargetCell = true; - } - } - - if (isSrcFaceColinearWithFaceOfTetraTargetCell) - { - DuplicateFacesType::iterator intersectFacesIter = _intersect_faces.find(cellSrcIdx); - if (intersectFacesIter != _intersect_faces.end()) - { - intersectFacesIter->second.insert(targetCell); - } - else - { - std::set targetCellSet; - targetCellSet.insert(targetCell); - _intersect_faces.insert(std::make_pair(cellSrcIdx, targetCellSet)); - } - } - } - delete [] polyNodes; - delete [] polyCoords; - } - _split.releaseArrays(); - } -} - -#endif diff --git a/src/INTERP_KERNEL/PolyhedronIntersectorP0P0.hxx b/src/INTERP_KERNEL/PolyhedronIntersectorP0P0.hxx deleted file mode 100644 index 35193ec13..000000000 --- a/src/INTERP_KERNEL/PolyhedronIntersectorP0P0.hxx +++ /dev/null @@ -1,65 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 -// 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 __POLYHEDRONINTERSECTORP0P0_HXX__ -#define __POLYHEDRONINTERSECTORP0P0_HXX__ - -#include "Intersector3DP0P0.hxx" -#include "SplitterTetra.hxx" -#include "NormalizedUnstructuredMesh.hxx" - -namespace INTERP_KERNEL -{ - - - /** - * \brief Class responsible for calculating intersection between a hexahedron target element and - * the source elements. - * - */ - template - class PolyhedronIntersectorP0P0 : public Intersector3DP0P0 - { - public: - static const int SPACEDIM=MyMeshType::MY_SPACEDIM; - static const int MESHDIM=MyMeshType::MY_MESHDIM; - typedef typename MyMeshType::MyConnType ConnType; - static const NumberingPolicy numPol=MyMeshType::My_numPol; - public: - - PolyhedronIntersectorP0P0(const MyMeshType& targetMesh, const MyMeshType& srcMesh, SplittingPolicy policy = PLANAR_FACE_5); - - ~PolyhedronIntersectorP0P0(); - - void intersectCells(ConnType targetCell, const std::vector& srcCells, MyMatrix& res); - - private: - void releaseArrays(); - private: - /// pointers to the SplitterTetra objects representing the tetrahedra - /// that result from the splitting of the hexahedron target cell - std::vector< SplitterTetra* > _tetra; - - SplitterTetra2 _split; - - }; -} - -#endif diff --git a/src/INTERP_KERNEL/PolyhedronIntersectorP0P0.txx b/src/INTERP_KERNEL/PolyhedronIntersectorP0P0.txx deleted file mode 100644 index 6ed792171..000000000 --- a/src/INTERP_KERNEL/PolyhedronIntersectorP0P0.txx +++ /dev/null @@ -1,97 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 -// 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 __POLYHEDRONINTERSECTORP0P0_TXX__ -#define __POLYHEDRONINTERSECTORP0P0_TXX__ - -#include "PolyhedronIntersectorP0P0.hxx" -#include "Intersector3DP0P0.txx" -#include "MeshUtils.hxx" - -#include "SplitterTetra.txx" - -namespace INTERP_KERNEL -{ - - /** - * Constructor creating object from target cell global number - * The constructor first calculates the necessary nodes, - * (depending on the splitting policy) and then splits the hexahedron into - * tetrahedra, placing these in the internal vector _tetra. - * - * @param targetMesh mesh containing the target elements - * @param srcMesh mesh containing the source elements - * @param policy splitting policy to be used - */ - template - PolyhedronIntersectorP0P0::PolyhedronIntersectorP0P0(const MyMeshType& targetMesh, const MyMeshType& srcMesh, SplittingPolicy policy):Intersector3DP0P0(targetMesh,srcMesh),_split(targetMesh,srcMesh,policy) - { - } - - /** - * Destructor. - * Liberates the SplitterTetra objects and potential sub-node points that have been allocated. - * - */ - template - PolyhedronIntersectorP0P0::~PolyhedronIntersectorP0P0() - { - releaseArrays(); - } - - template - void PolyhedronIntersectorP0P0::releaseArrays() - { - for(typename std::vector< SplitterTetra* >::iterator iter = _tetra.begin(); iter != _tetra.end(); ++iter) - delete *iter; - _split.releaseArrays(); - _tetra.clear(); - } - - /** - * Calculates the volume of intersection of an element in the source mesh and the target element - * represented by the object. - * The calculation is performed by calling the corresponding method for - * each SplitterTetra object created by the splitting. - * - * @param targetCell in C mode. - * @param srcCells in C mode. - * - */ - template - void PolyhedronIntersectorP0P0::intersectCells(ConnType targetCell, const std::vector& srcCells, MyMatrix& res) - { - releaseArrays(); - _split.splitTargetCell2(targetCell,_tetra); - for(typename std::vector::const_iterator iterCellS=srcCells.begin();iterCellS!=srcCells.end();iterCellS++) - { - 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)); - } - _split.releaseArrays(); - } -} - -#endif diff --git a/src/INTERP_KERNEL/PolyhedronIntersectorP0P1.hxx b/src/INTERP_KERNEL/PolyhedronIntersectorP0P1.hxx deleted file mode 100644 index 2bf2ec0b3..000000000 --- a/src/INTERP_KERNEL/PolyhedronIntersectorP0P1.hxx +++ /dev/null @@ -1,65 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 -// 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 __POLYHEDRONINTERSECTORP0P1_HXX__ -#define __POLYHEDRONINTERSECTORP0P1_HXX__ - -#include "Intersector3DP0P1.hxx" -#include "SplitterTetra.hxx" -#include "NormalizedUnstructuredMesh.hxx" - -namespace INTERP_KERNEL -{ - - - /** - * \brief Class responsible for calculating intersection between a hexahedron target element and - * the source elements. - * - */ - template - class PolyhedronIntersectorP0P1 : public Intersector3DP0P1 - { - public: - static const int SPACEDIM=MyMeshType::MY_SPACEDIM; - static const int MESHDIM=MyMeshType::MY_MESHDIM; - typedef typename MyMeshType::MyConnType ConnType; - static const NumberingPolicy numPol=MyMeshType::My_numPol; - public: - - PolyhedronIntersectorP0P1(const MyMeshType& targetMesh, const MyMeshType& srcMesh, SplittingPolicy policy = PLANAR_FACE_5); - - ~PolyhedronIntersectorP0P1(); - - void intersectCells(ConnType targetCell, const std::vector& srcCells, MyMatrix& res); - - private: - void releaseArrays(); - private: - /// pointers to the SplitterTetra objects representing the tetrahedra - /// that result from the splitting of the hexahedron target cell - std::vector< SplitterTetra* > _tetra; - - SplitterTetra2 _split; - - }; -} - -#endif diff --git a/src/INTERP_KERNEL/PolyhedronIntersectorP0P1.txx b/src/INTERP_KERNEL/PolyhedronIntersectorP0P1.txx deleted file mode 100644 index 43839bb45..000000000 --- a/src/INTERP_KERNEL/PolyhedronIntersectorP0P1.txx +++ /dev/null @@ -1,118 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 -// 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 __POLYHEDRONINTERSECTORP0P1_TXX__ -#define __POLYHEDRONINTERSECTORP0P1_TXX__ - -#include "PolyhedronIntersectorP0P1.hxx" -#include "Intersector3DP0P1.txx" -#include "MeshUtils.hxx" - -#include "SplitterTetra.txx" - -namespace INTERP_KERNEL -{ - - /** - * Constructor creating object from target cell global number - * The constructor first calculates the necessary nodes, - * (depending on the splitting policy) and then splits the hexahedron into - * tetrahedra, placing these in the internal vector _tetra. - * - * @param targetMesh mesh containing the target elements - * @param srcMesh mesh containing the source elements - * @param policy splitting policy to be used - */ - template - PolyhedronIntersectorP0P1::PolyhedronIntersectorP0P1(const MyMeshType& targetMesh, const MyMeshType& srcMesh, SplittingPolicy policy):Intersector3DP0P1(targetMesh,srcMesh),_split(targetMesh,srcMesh,policy) - { - } - - /** - * Destructor. - * Liberates the SplitterTetra objects and potential sub-node points that have been allocated. - * - */ - template - PolyhedronIntersectorP0P1::~PolyhedronIntersectorP0P1() - { - releaseArrays(); - } - - template - void PolyhedronIntersectorP0P1::releaseArrays() - { - for(typename std::vector< SplitterTetra* >::iterator iter = _tetra.begin(); iter != _tetra.end(); ++iter) - delete *iter; - _split.releaseArrays(); - _tetra.clear(); - } - - /** - * Calculates the volume of intersection of an element in the source mesh and the target element - * represented by the object. - * The calculation is performed by calling the corresponding method for - * each SplitterTetra object created by the splitting. - * - * @param targetCell in C mode. - * @param srcCells in C mode. - * - */ - template - void PolyhedronIntersectorP0P1::intersectCells(ConnType targetCell, const std::vector& srcCells, MyMatrix& res) - { - SplitterTetra* subTetras[24]; - releaseArrays(); - _split.splitTargetCell2(targetCell,_tetra); - for(typename std::vector::const_iterator iterCellS=srcCells.begin();iterCellS!=srcCells.end();iterCellS++) - { - for(typename std::vector*>::iterator iter = _tetra.begin(); iter != _tetra.end(); ++iter) - { - (*iter)->splitIntoDualCells(subTetras); - for(int i=0;i<24;i++) - { - SplitterTetra *tmp=subTetras[i]; - double volume = tmp->intersectSourceCell(*iterCellS); - if(volume!=0.) - { - int targetNodeId(tmp->getId(0)); - if(targetNodeId<0) - { - std::ostringstream oss; oss << "PolyhedronIntersectorP0P1::intersectCells : On target cell #" << targetCell << " the splitting into tetra4 leads to the creation of an additional point that interacts with source cell Id #" << *iterCellS << " !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - typename MyMatrix::value_type& resRow=res[targetNodeId]; - typename MyMatrix::value_type::const_iterator iterRes=resRow.find(OTT::indFC(*iterCellS)); - if(iterRes==resRow.end()) - resRow.insert(std::make_pair(OTT::indFC(*iterCellS),volume)); - else - { - double val=(*iterRes).second+volume; - resRow.erase(OTT::indFC(*iterCellS)); - resRow.insert(std::make_pair(OTT::indFC(*iterCellS),val)); - } - } - delete tmp; - } - } - } - } -} - -#endif diff --git a/src/INTERP_KERNEL/PolyhedronIntersectorP1P0.hxx b/src/INTERP_KERNEL/PolyhedronIntersectorP1P0.hxx deleted file mode 100644 index 4c9cb248a..000000000 --- a/src/INTERP_KERNEL/PolyhedronIntersectorP1P0.hxx +++ /dev/null @@ -1,65 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 -// 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 __POLYHEDRONINTERSECTORP1P0_HXX__ -#define __POLYHEDRONINTERSECTORP1P0_HXX__ - -#include "Intersector3DP1P0.hxx" -#include "SplitterTetra.hxx" -#include "NormalizedUnstructuredMesh.hxx" - -namespace INTERP_KERNEL -{ - - - /** - * \brief Class responsible for calculating intersection between a hexahedron target element and - * the source elements. - * - */ - template - class PolyhedronIntersectorP1P0 : public Intersector3DP1P0 - { - public: - static const int SPACEDIM=MyMeshType::MY_SPACEDIM; - static const int MESHDIM=MyMeshType::MY_MESHDIM; - typedef typename MyMeshType::MyConnType ConnType; - static const NumberingPolicy numPol=MyMeshType::My_numPol; - public: - - PolyhedronIntersectorP1P0(const MyMeshType& targetMesh, const MyMeshType& srcMesh, SplittingPolicy policy = PLANAR_FACE_5); - - ~PolyhedronIntersectorP1P0(); - - void intersectCells(ConnType targetCell, const std::vector& srcCells, MyMatrix& res); - - private: - void releaseArrays(); - private: - /// pointers to the SplitterTetra objects representing the tetrahedra - /// that result from the splitting of the hexahedron target cell - std::vector< SplitterTetra* > _tetra; - - SplitterTetra2 _split; - - }; -} - -#endif diff --git a/src/INTERP_KERNEL/PolyhedronIntersectorP1P0.txx b/src/INTERP_KERNEL/PolyhedronIntersectorP1P0.txx deleted file mode 100644 index 350f33252..000000000 --- a/src/INTERP_KERNEL/PolyhedronIntersectorP1P0.txx +++ /dev/null @@ -1,117 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 -// 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 __POLYHEDRONINTERSECTORP1P0_TXX__ -#define __POLYHEDRONINTERSECTORP1P0_TXX__ - -#include "PolyhedronIntersectorP1P0.hxx" -#include "Intersector3DP1P0.txx" -#include "MeshUtils.hxx" - -#include "SplitterTetra.txx" - -namespace INTERP_KERNEL -{ - - /** - * Constructor creating object from target cell global number - * The constructor first calculates the necessary nodes, - * (depending on the splitting policy) and then splits the hexahedron into - * tetrahedra, placing these in the internal vector _tetra. - * - * @param targetMesh mesh containing the target elements - * @param srcMesh mesh containing the source elements - * @param policy splitting policy to be used - * - * WARNING : in _split attribute, sourceMesh and targetMesh are switched in order to fit intersectCells feature. - */ - template - PolyhedronIntersectorP1P0::PolyhedronIntersectorP1P0(const MyMeshType& targetMesh, const MyMeshType& srcMesh, SplittingPolicy policy):Intersector3DP1P0(targetMesh,srcMesh),_split(srcMesh,targetMesh,policy) - { - } - - /** - * Destructor. - * Liberates the SplitterTetra objects and potential sub-node points that have been allocated. - * - */ - template - PolyhedronIntersectorP1P0::~PolyhedronIntersectorP1P0() - { - releaseArrays(); - } - - template - void PolyhedronIntersectorP1P0::releaseArrays() - { - for(typename std::vector< SplitterTetra* >::iterator iter = _tetra.begin(); iter != _tetra.end(); ++iter) - delete *iter; - _split.releaseArrays(); - _tetra.clear(); - } - - /** - * Calculates the volume of intersection of an element in the source mesh and the target element - * represented by the object. - * The calculation is performed by calling the corresponding method for - * each SplitterTetra object created by the splitting. - * - * @param targetCell in C mode. - * @param srcCells in C mode. - * - * WARNING : for all methods on _split object source and target are switched ! - */ - template - void PolyhedronIntersectorP1P0::intersectCells(ConnType targetCell, const std::vector& srcCells, MyMatrix& res) - { - SplitterTetra* subTetras[24]; - typename MyMatrix::value_type& resRow=res[targetCell]; - for(typename std::vector::const_iterator iterCellS=srcCells.begin();iterCellS!=srcCells.end();iterCellS++) - { - releaseArrays(); - int nbOfNodesS=Intersector3D::_src_mesh.getNumberOfNodesOfElement(OTT::indFC(*iterCellS)); - _split.splitTargetCell(*iterCellS,nbOfNodesS,_tetra); - for(typename std::vector*>::iterator iter = _tetra.begin(); iter != _tetra.end(); ++iter) - { - (*iter)->splitIntoDualCells(subTetras); - for(int i=0;i<24;i++) - { - SplitterTetra *tmp=subTetras[i]; - double volume = tmp->intersectSourceCell(targetCell); - ConnType sourceNode=tmp->getId(0); - if(volume!=0.) - { - typename MyMatrix::value_type::const_iterator iterRes=resRow.find(OTT::indFC(sourceNode)); - if(iterRes==resRow.end()) - resRow.insert(std::make_pair(OTT::indFC(sourceNode),volume)); - else - { - double val=(*iterRes).second+volume; - resRow.erase(OTT::indFC(sourceNode)); - resRow.insert(std::make_pair(OTT::indFC(sourceNode),val)); - } - } - delete tmp; - } - } - } - } -} - -#endif diff --git a/src/INTERP_KERNEL/PolyhedronIntersectorP1P0Bary.hxx b/src/INTERP_KERNEL/PolyhedronIntersectorP1P0Bary.hxx deleted file mode 100644 index 9dabe51fe..000000000 --- a/src/INTERP_KERNEL/PolyhedronIntersectorP1P0Bary.hxx +++ /dev/null @@ -1,65 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 -// 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 __PolyhedronIntersectorP1P0Bary_HXX__ -#define __PolyhedronIntersectorP1P0Bary_HXX__ - -#include "Intersector3DP1P0Bary.hxx" -#include "SplitterTetra.hxx" -#include "NormalizedUnstructuredMesh.hxx" - -namespace INTERP_KERNEL -{ - - - /** - * \brief Class responsible for calculating intersection between a hexahedron target element and - * the source elements. - * - */ - template - class PolyhedronIntersectorP1P0Bary : public Intersector3DP1P0Bary - { - public: - static const int SPACEDIM=MyMeshType::MY_SPACEDIM; - static const int MESHDIM=MyMeshType::MY_MESHDIM; - typedef typename MyMeshType::MyConnType ConnType; - static const NumberingPolicy numPol=MyMeshType::My_numPol; - public: - - PolyhedronIntersectorP1P0Bary(const MyMeshType& targetMesh, const MyMeshType& srcMesh, SplittingPolicy policy = PLANAR_FACE_5); - - ~PolyhedronIntersectorP1P0Bary(); - - void intersectCells(ConnType targetCell, const std::vector& srcCells, MyMatrix& res); - - private: - void releaseArrays(); - private: - /// pointers to the SplitterTetra objects representing the tetrahedra - /// that result from the splitting of the hexahedron target cell - std::vector< SplitterTetra* > _tetra; - - SplitterTetra2 _split; - - }; -} - -#endif diff --git a/src/INTERP_KERNEL/PolyhedronIntersectorP1P0Bary.txx b/src/INTERP_KERNEL/PolyhedronIntersectorP1P0Bary.txx deleted file mode 100644 index 6136b5ee9..000000000 --- a/src/INTERP_KERNEL/PolyhedronIntersectorP1P0Bary.txx +++ /dev/null @@ -1,154 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 -// 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 __PolyhedronIntersectorP1P0Bary_TXX__ -#define __PolyhedronIntersectorP1P0Bary_TXX__ - -#include "PolyhedronIntersectorP1P0Bary.hxx" -#include "Intersector3DP1P0Bary.txx" -#include "MeshUtils.hxx" - -#include "SplitterTetra.txx" - -namespace INTERP_KERNEL -{ - - /** - * Constructor creating object from target cell global number - * The constructor first calculates the necessary nodes, - * (depending on the splitting policy) and then splits the hexahedron into - * tetrahedra, placing these in the internal vector _tetra. - * - * @param targetMesh mesh containing the target elements - * @param srcMesh mesh containing the source elements - * @param policy splitting policy to be used - * - * WARNING : in _split attribute, sourceMesh and targetMesh are switched in order to fit intersectCells feature. - */ - template - PolyhedronIntersectorP1P0Bary::PolyhedronIntersectorP1P0Bary(const MyMeshType& targetMesh, - const MyMeshType& srcMesh, - SplittingPolicy policy) - :Intersector3DP1P0Bary(targetMesh,srcMesh),_split(targetMesh,srcMesh,policy) - { - // SPEC: - // "Limitation. For the P1P0 barycentric improvement only triangle source cells in 2D and - // tetrahedrons in 3D will be supported by interpolators. If a non - // triangle/tetrahedron source cell is detected an INTERP_KERNEL::Exception should be thrown." - - // Check types of source elements here rather than in intersectCells() since a wrong type can be - // found late after a long time of calculation. - - const unsigned long numSrcElems = srcMesh.getNumberOfElements(); - for(unsigned long i = 0 ; i < numSrcElems ; ++i) - if ( srcMesh.getTypeOfElement( OTT::indFC(i) ) != NORM_TETRA4 ) - throw INTERP_KERNEL::Exception("P1P0 barycentric algorithm works only with tetrahedral source meshes"); - } - - /** - * Destructor. - * Liberates the SplitterTetra objects and potential sub-node points that have been allocated. - * - */ - template - PolyhedronIntersectorP1P0Bary::~PolyhedronIntersectorP1P0Bary() - { - releaseArrays(); - } - - template - void PolyhedronIntersectorP1P0Bary::releaseArrays() - { - for(typename std::vector< SplitterTetra* >::iterator iter = _tetra.begin(); iter != _tetra.end(); ++iter) - delete *iter; - _split.releaseArrays(); - _tetra.clear(); - } - - //================================================================================ - /*! - * \brief This method computes a value per each node of source cell for each target cell. - * \param srcCell - a source tetrahedron - * \param tgtCells - target elements - * \param res - matrix to fill in - */ - //================================================================================ - - template - void PolyhedronIntersectorP1P0Bary::intersectCells(ConnType tgtCell, - const std::vector& srcCells, - MyMatrix& res) - { - typename MyMatrix::value_type& resRow=res[tgtCell]; - - int nbOfNodesT=Intersector3D::_target_mesh.getNumberOfNodesOfElement(OTT::indFC(tgtCell)); - releaseArrays(); - _split.splitTargetCell(tgtCell,nbOfNodesT,_tetra); - - for(typename std::vector::const_iterator iterCellS=srcCells.begin();iterCellS!=srcCells.end();iterCellS++) - { - // intersect a source tetrahedron with each target tetrahedron: get intersection volume and barycenter - double baryCentre[SPACEDIM], total_baryCentre[3] = { 0., 0., 0.}; - double interVolume = 0; - for(typename std::vector*>::iterator iterTetraT = _tetra.begin(); iterTetraT != _tetra.end(); ++iterTetraT) - { - SplitterTetra *tmp=*iterTetraT; - tmp->clearVolumesCache(); - double volume = tmp->intersectSourceCell(*iterCellS, baryCentre); - if ( volume > 0 ) - { - interVolume += volume; - for ( int i = 0; i < SPACEDIM; ++i ) - total_baryCentre[i] += baryCentre[i]*volume; - } - } - if(interVolume!=0) - { - for ( int i = 0; i < SPACEDIM; ++i ) - total_baryCentre[i] /= interVolume; - - // coordinates of the source tetrahedron - std::vector srcCellCoords(4); - for ( int n = 0; n < 4; ++n ) - srcCellCoords[ n ] = getCoordsOfNode( n, *iterCellS, Intersector3D::_src_mesh ); - - // compute barycentric coordinates - double baryCoords[4]; - barycentric_coords( srcCellCoords, total_baryCentre, baryCoords); - - // store coeffs of each node of the source tetrahedron - const ConnType *srcCellNodes=Intersector3D::_src_mesh.getConnectivityPtr()+OTT::conn2C(Intersector3D::_src_mesh.getConnectivityIndexPtr()[*iterCellS]); - for ( int n = 0; n < 4; ++n ) - { - double val = baryCoords[n] * interVolume; - ConnType curNodeS = srcCellNodes[n]; - typename MyMatrix::value_type::const_iterator iterRes=resRow.find(curNodeS); - if(iterRes!=resRow.end()) - { - val += iterRes->second; - resRow.erase( curNodeS ); - } - resRow.insert(std::make_pair(curNodeS,val)); - } - } - } - } -} - -#endif diff --git a/src/INTERP_KERNEL/PolyhedronIntersectorP1P1.hxx b/src/INTERP_KERNEL/PolyhedronIntersectorP1P1.hxx deleted file mode 100644 index 002a173ca..000000000 --- a/src/INTERP_KERNEL/PolyhedronIntersectorP1P1.hxx +++ /dev/null @@ -1,56 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 -// 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 __PolyhedronIntersectorP1P1_HXX__ -#define __PolyhedronIntersectorP1P1_HXX__ - -#include "Intersector3DP1P1.hxx" -#include "SplitterTetra.hxx" -#include "NormalizedUnstructuredMesh.hxx" - -namespace INTERP_KERNEL -{ - - - /** - * \brief Class responsible for calculating intersection between a hexahedron target element and - * the source elements. - * - */ - template - class PolyhedronIntersectorP1P1 : public Intersector3DP1P1 - { - public: - static const int SPACEDIM=MyMeshType::MY_SPACEDIM; - static const int MESHDIM=MyMeshType::MY_MESHDIM; - typedef typename MyMeshType::MyConnType ConnType; - static const NumberingPolicy numPol=MyMeshType::My_numPol; - public: - - PolyhedronIntersectorP1P1(const MyMeshType& targetMesh, const MyMeshType& srcMesh, SplittingPolicy policy = PLANAR_FACE_5); - - ~PolyhedronIntersectorP1P1(); - - void intersectCells(ConnType targetCell, const std::vector& srcCells, MyMatrix& res); - - }; -} - -#endif diff --git a/src/INTERP_KERNEL/PolyhedronIntersectorP1P1.txx b/src/INTERP_KERNEL/PolyhedronIntersectorP1P1.txx deleted file mode 100644 index f26320187..000000000 --- a/src/INTERP_KERNEL/PolyhedronIntersectorP1P1.txx +++ /dev/null @@ -1,134 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 -// 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 __PolyhedronIntersectorP1P1_TXX__ -#define __PolyhedronIntersectorP1P1_TXX__ - -#include "PolyhedronIntersectorP1P1.hxx" -#include "Intersector3DP1P1.txx" -#include "MeshUtils.hxx" - -#include "SplitterTetra.txx" - -namespace INTERP_KERNEL -{ - - /** - * Constructor creating object from target cell global number - * - * @param targetMesh mesh containing the target elements - * @param srcMesh mesh containing the source elements - * @param policy splitting policy to be used - */ - template - PolyhedronIntersectorP1P1::PolyhedronIntersectorP1P1(const MyMeshType& targetMesh, const MyMeshType& srcMesh, SplittingPolicy policy):Intersector3DP1P1(targetMesh,srcMesh) - { - // SPEC: - // "Limitation. Concerning P1P1 3D improvement only tetrahedron will be supported. - // If another type than tetrahedron is detected an INTERP_KERNEL::Exception should be thrown" - - // Check types of elements here rather than in intersectCells() since a wrong type can be - // found late after a long time of calculation. - - const unsigned long numSrcElems = srcMesh.getNumberOfElements(); - for(unsigned long i = 0 ; i < numSrcElems ; ++i) - if ( srcMesh.getTypeOfElement( OTT::indFC( i )) != NORM_TETRA4 ) - throw INTERP_KERNEL::Exception("P1P1 3D algorithm works only with tetrahedral meshes"); - - const unsigned long numTgtElems = targetMesh.getNumberOfElements(); - for(unsigned long i = 0 ; i < numTgtElems ; ++i) - if ( targetMesh.getTypeOfElement( OTT::indFC( i )) != NORM_TETRA4 ) - throw INTERP_KERNEL::Exception("P1P1 3D algorithm works only with tetrahedral meshes"); - } - - /** - * Destructor. - */ - template - PolyhedronIntersectorP1P1::~PolyhedronIntersectorP1P1() - { - } - - /** - * Calculates the volume of intersection of an element in the source mesh and the target element - * represented by the object. - * - * @param targetCell in C mode. - * @param srcCells in C mode. - */ - template - void PolyhedronIntersectorP1P1::intersectCells(ConnType targetCell, const std::vector& srcCells, MyMatrix& res) - { -#ifdef _DEBUG_ - UnitTetraIntersectionBary b; b.init(); -#endif - // split the targetCell into dual cells - std::pair< int, std::vector > subTetraNodes[24]; // a node of sub tetra and its coordinates - const double* nodes[4]; int conn[4]; - for(int node = 0; node < 4 ; ++node) - nodes[node]=getCoordsOfNode2(node, OTT::indFC(targetCell), - Intersector3D::_target_mesh,conn[node]); - SplitterTetra tgtTetra(Intersector3D::_src_mesh, nodes, conn); - for (int i=0; i<24; i++) - { - subTetraNodes[i].second.resize(12); - tgtTetra.splitMySelfForDual(&subTetraNodes[i].second[0],i,subTetraNodes[i].first); - } - // intersect each source tetrahedron with each of target dual cells - SplitterTetra* subTetrasS[24]; - for(typename std::vector::const_iterator iterCellS=srcCells.begin();iterCellS!=srcCells.end();iterCellS++) - { - // split a source cell into dual cells - for(int node = 0; node < 4 ; ++node) - nodes[node]=getCoordsOfNode2(node, OTT::indFC(*iterCellS), - Intersector3D::_src_mesh,conn[node]); - - SplitterTetra srcTetra(Intersector3D::_target_mesh, nodes, conn); - srcTetra.splitIntoDualCells(subTetrasS); - - // intersect each target subTetra with each source one - for(int i=0;i<24;i++) - { - SplitterTetra *tmp=subTetrasS[i]; - ConnType sourceNode=OTT::indFC(tmp->getId(0)); - for(int j=0;j<24;j++) - { - const double* tetraNodes12 = &subTetraNodes[j].second[0]; - const double* tetraNodesT[4]={ tetraNodes12, tetraNodes12+3, tetraNodes12+6, tetraNodes12+9 }; - double volume = tmp->intersectTetra( tetraNodesT ); - if(volume!=0.) - { - ConnType tgtNode=subTetraNodes[j].first; - typename MyMatrix::value_type& resRow = res[tgtNode]; - typename MyMatrix::value_type::const_iterator iterRes=resRow.find( sourceNode ); - if(iterRes!=resRow.end()) - { - volume += (*iterRes).second; - resRow.erase(sourceNode); - } - resRow.insert(std::make_pair(sourceNode,volume)); - } - } - delete tmp; - } - } - } -} - -#endif diff --git a/src/INTERP_KERNEL/RegionNode.hxx b/src/INTERP_KERNEL/RegionNode.hxx deleted file mode 100644 index c7aaf7532..000000000 --- a/src/INTERP_KERNEL/RegionNode.hxx +++ /dev/null @@ -1,68 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 -// 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 __REGIONNODE_HXX__ -#define __REGIONNODE_HXX__ - -#include "MeshRegion.hxx" - -namespace INTERP_KERNEL -{ - - /** - * \brief Class containing a tuplet of a source region and a target region. - * This is used as the object to put on the stack in the depth-first search - * in the bounding-box filtering process. - */ - template - class RegionNode - { - public: - - RegionNode() { } - - ~RegionNode() { } - - /** - * Accessor to source region - * - * @return reference to source region - */ - MeshRegion& getSrcRegion() { return _srcRegion; } - - /** - * Accessor to target region - * - * @return reference to target region - */ - MeshRegion& getTargetRegion() { return _targetRegion; } - - private: - - /// source region - MeshRegion _srcRegion; - - /// target region - MeshRegion _targetRegion; - - }; - -} - -#endif diff --git a/src/INTERP_KERNEL/SplitterTetra.cxx b/src/INTERP_KERNEL/SplitterTetra.cxx deleted file mode 100644 index 06dbb101e..000000000 --- a/src/INTERP_KERNEL/SplitterTetra.cxx +++ /dev/null @@ -1,217 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 -// 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 "SplitterTetra.hxx" - -namespace INTERP_KERNEL -{ - - void SplitHexa8IntoTetras(SplittingPolicy policy, const int *nodalConnBg, const int *nodalConnEnd, const double *coords, - std::vector& tetrasNodalConn, std::vector& addCoords) - { - if(std::distance(nodalConnBg,nodalConnEnd)!=8) - throw INTERP_KERNEL::Exception("SplitHexa8IntoTetras : input hexa do not have 8 nodes !"); - switch(policy) - { - case PLANAR_FACE_5: - { - tetrasNodalConn.resize(20); - int *conn(&tetrasNodalConn[0]); - conn[0]=nodalConnBg[SPLIT_NODES_5_WO[0]]; conn[1]=nodalConnBg[SPLIT_NODES_5_WO[1]]; conn[2]=nodalConnBg[SPLIT_NODES_5_WO[2]]; conn[3]=nodalConnBg[SPLIT_NODES_5_WO[3]]; - conn[4]=nodalConnBg[SPLIT_NODES_5_WO[4]]; conn[5]=nodalConnBg[SPLIT_NODES_5_WO[5]]; conn[6]=nodalConnBg[SPLIT_NODES_5_WO[6]]; conn[7]=nodalConnBg[SPLIT_NODES_5_WO[7]]; - conn[8]=nodalConnBg[SPLIT_NODES_5_WO[8]]; conn[9]=nodalConnBg[SPLIT_NODES_5_WO[9]]; conn[10]=nodalConnBg[SPLIT_NODES_5_WO[10]]; conn[11]=nodalConnBg[SPLIT_NODES_5_WO[11]]; - conn[12]=nodalConnBg[SPLIT_NODES_5_WO[12]]; conn[13]=nodalConnBg[SPLIT_NODES_5_WO[13]]; conn[14]=nodalConnBg[SPLIT_NODES_5_WO[14]]; conn[15]=nodalConnBg[SPLIT_NODES_5_WO[15]]; - conn[16]=nodalConnBg[SPLIT_NODES_5_WO[16]]; conn[17]=nodalConnBg[SPLIT_NODES_5_WO[17]]; conn[18]=nodalConnBg[SPLIT_NODES_5_WO[18]]; conn[19]=nodalConnBg[SPLIT_NODES_5_WO[19]]; - return ; - } - case PLANAR_FACE_6: - { - tetrasNodalConn.resize(24); - int *conn(&tetrasNodalConn[0]); - conn[0]=nodalConnBg[SPLIT_NODES_6_WO[0]]; conn[1]=nodalConnBg[SPLIT_NODES_6_WO[1]]; conn[2]=nodalConnBg[SPLIT_NODES_6_WO[2]]; conn[3]=nodalConnBg[SPLIT_NODES_6_WO[3]]; - conn[4]=nodalConnBg[SPLIT_NODES_6_WO[4]]; conn[5]=nodalConnBg[SPLIT_NODES_6_WO[5]]; conn[6]=nodalConnBg[SPLIT_NODES_6_WO[6]]; conn[7]=nodalConnBg[SPLIT_NODES_6_WO[7]]; - conn[8]=nodalConnBg[SPLIT_NODES_6_WO[8]]; conn[9]=nodalConnBg[SPLIT_NODES_6_WO[9]]; conn[10]=nodalConnBg[SPLIT_NODES_6_WO[10]]; conn[11]=nodalConnBg[SPLIT_NODES_6_WO[11]]; - conn[12]=nodalConnBg[SPLIT_NODES_6_WO[12]]; conn[13]=nodalConnBg[SPLIT_NODES_6_WO[13]]; conn[14]=nodalConnBg[SPLIT_NODES_6_WO[14]]; conn[15]=nodalConnBg[SPLIT_NODES_6_WO[15]]; - conn[16]=nodalConnBg[SPLIT_NODES_6_WO[16]]; conn[17]=nodalConnBg[SPLIT_NODES_6_WO[17]]; conn[18]=nodalConnBg[SPLIT_NODES_6_WO[18]]; conn[19]=nodalConnBg[SPLIT_NODES_6_WO[19]]; - conn[20]=nodalConnBg[SPLIT_NODES_6_WO[20]]; conn[21]=nodalConnBg[SPLIT_NODES_6_WO[21]]; conn[22]=nodalConnBg[SPLIT_NODES_6_WO[22]]; conn[23]=nodalConnBg[SPLIT_NODES_6_WO[23]]; - return ; - } - case GENERAL_24: - { - addCoords.resize(7*3); - tetrasNodalConn.resize(24*4); - int *conn(&tetrasNodalConn[0]); - double *tmp(&addCoords[18]); - tmp[0]=0.; tmp[1]=0.; tmp[2]=0.; - double *tmp2(&addCoords[0]); - for(int i=0;i<6;i++,tmp2+=3) - { - tmp2[0]=0.; tmp2[1]=0.; tmp2[2]=0.; - for(int j=0;j<4;j++,conn+=4) - { - int tmp3(nodalConnBg[GENERAL_24_SUB_NODES_WO[4*i+j]]); - tmp2[0]+=coords[3*tmp3+0]; - tmp2[1]+=coords[3*tmp3+1]; - tmp2[2]+=coords[3*tmp3+2]; - conn[0]=tmp3; - conn[1]=nodalConnBg[GENERAL_24_SUB_NODES_WO[4*i+(j+1)%4]]; - conn[2]=-(i+1); conn[3]=-7; - } - tmp2[0]/=4.; tmp2[1]/=4.; tmp2[2]/=4.; - tmp[0]+=tmp2[0]; tmp[1]+=tmp2[1]; tmp[2]+=tmp2[2]; - } - tmp[0]/=6.; tmp[1]/=6.; tmp[2]/=6.; - return ; - } - case GENERAL_48: - { - addCoords.resize(19*3); - tetrasNodalConn.resize(48*4); - double *tmp2(&addCoords[0]),*tmp(&addCoords[0]); - for(int i=0;i<12;i++,tmp2+=3) - { - tmp2[0]=(coords[3*nodalConnBg[GENERAL_48_SUB_NODES[2*i]]+0]+coords[3*nodalConnBg[GENERAL_48_SUB_NODES[2*i+1]]+0])/2.; - tmp2[1]=(coords[3*nodalConnBg[GENERAL_48_SUB_NODES[2*i]]+1]+coords[3*nodalConnBg[GENERAL_48_SUB_NODES[2*i+1]]+1])/2.; - tmp2[2]=(coords[3*nodalConnBg[GENERAL_48_SUB_NODES[2*i]]+2]+coords[3*nodalConnBg[GENERAL_48_SUB_NODES[2*i+1]]+2])/2.; - } - for(int i=0;i<7;i++,tmp2+=3) - { - tmp2[0]=(tmp[3*(GENERAL_48_SUB_NODES[2*i+24]-8)+0]+tmp[3*(GENERAL_48_SUB_NODES[2*i+25]-8)+0])/2.; - tmp2[1]=(tmp[3*(GENERAL_48_SUB_NODES[2*i+24]-8)+1]+tmp[3*(GENERAL_48_SUB_NODES[2*i+25]-8)+1])/2.; - tmp2[2]=(tmp[3*(GENERAL_48_SUB_NODES[2*i+24]-8)+2]+tmp[3*(GENERAL_48_SUB_NODES[2*i+25]-8)+2])/2.; - } - int *conn(&tetrasNodalConn[0]); - std::vector dummy; - for(int i=0;i<8;i++) - { - std::vector c; - SplitHexa8IntoTetras(PLANAR_FACE_6,GENERAL_48_SUBZONES_2+i*8,GENERAL_48_SUBZONES_2+(i+1)*8,coords,c,dummy); - int *conn2(&c[0]); - for(int j=0;j<6;j++,conn+=4,conn2+=4) - { - conn[0]=conn2[0]>=0?nodalConnBg[conn2[0]]:conn2[0]; - conn[1]=conn2[1]>=0?nodalConnBg[conn2[1]]:conn2[1]; - conn[2]=conn2[2]>=0?nodalConnBg[conn2[2]]:conn2[2]; - conn[3]=conn2[3]>=0?nodalConnBg[conn2[3]]:conn2[3]; - } - } - return ; - } - default: - throw INTERP_KERNEL::Exception("SplitHexa8IntoTetras : invalid input policy ! Should be in [PLANAR_FACE_5,PLANAR_FACE_6,GENERAL_24,GENERAL_48] !"); - } - } - - void SplitIntoTetras(SplittingPolicy policy, NormalizedCellType gt, const int *nodalConnBg, const int *nodalConnEnd, const double *coords, - std::vector& tetrasNodalConn, std::vector& addCoords) - { - switch(gt) - { - case NORM_TETRA4: - { - std::size_t sz(std::distance(nodalConnBg,nodalConnEnd)); - if(sz!=4) - throw INTERP_KERNEL::Exception("SplitIntoTetras : input tetra do not have 4 nodes !"); - tetrasNodalConn.insert(tetrasNodalConn.end(),nodalConnBg,nodalConnEnd); - return ; - } - case NORM_HEXA8: - { - SplitHexa8IntoTetras(policy,nodalConnBg,nodalConnEnd,coords,tetrasNodalConn,addCoords); - return ; - } - case NORM_PYRA5: - { - std::size_t sz(std::distance(nodalConnBg,nodalConnEnd)); - if(sz!=5) - throw INTERP_KERNEL::Exception("SplitIntoTetras : input pyra5 do not have 5 nodes !"); - tetrasNodalConn.resize(8); - int *conn(&tetrasNodalConn[0]); - conn[0]=nodalConnBg[0]; conn[1]=nodalConnBg[1]; conn[2]=nodalConnBg[2]; conn[3]=nodalConnBg[4]; - conn[4]=nodalConnBg[0]; conn[5]=nodalConnBg[2]; conn[6]=nodalConnBg[3]; conn[7]=nodalConnBg[4]; - return ; - } - case NORM_PENTA6: - { - std::size_t sz(std::distance(nodalConnBg,nodalConnEnd)); - if(sz!=6) - throw INTERP_KERNEL::Exception("SplitIntoTetras : input penta6 do not have 6 nodes !"); - tetrasNodalConn.resize(12); - int *conn(&tetrasNodalConn[0]); - conn[0]=nodalConnBg[0]; conn[1]=nodalConnBg[1]; conn[2]=nodalConnBg[2]; conn[3]=nodalConnBg[3]; - conn[4]=nodalConnBg[3]; conn[5]=nodalConnBg[5]; conn[6]=nodalConnBg[4]; conn[7]=nodalConnBg[2]; - conn[8]=nodalConnBg[4]; conn[9]=nodalConnBg[2]; conn[10]=nodalConnBg[1]; conn[11]=nodalConnBg[3]; - return ; - } - case NORM_HEXGP12: - { - std::size_t sz(std::distance(nodalConnBg,nodalConnEnd)); - if(sz!=12) - throw INTERP_KERNEL::Exception("SplitIntoTetras : input octa12 (hexagone prism) do not have 12 nodes !"); - tetrasNodalConn.resize(48); - int *conn(&tetrasNodalConn[0]); - conn[0]=nodalConnBg[0]; conn[1]=nodalConnBg[1]; conn[2]=nodalConnBg[5]; conn[3]=nodalConnBg[6]; - conn[4]=nodalConnBg[6]; conn[5]=nodalConnBg[11]; conn[6]=nodalConnBg[7]; conn[7]=nodalConnBg[5]; - conn[8]=nodalConnBg[7]; conn[9]=nodalConnBg[5]; conn[10]=nodalConnBg[1]; conn[11]=nodalConnBg[6]; - // - conn[12]=nodalConnBg[1]; conn[13]=nodalConnBg[4]; conn[14]=nodalConnBg[5]; conn[15]=nodalConnBg[7]; - conn[16]=nodalConnBg[7]; conn[17]=nodalConnBg[11]; conn[18]=nodalConnBg[10]; conn[19]=nodalConnBg[5]; - conn[20]=nodalConnBg[10]; conn[21]=nodalConnBg[5]; conn[22]=nodalConnBg[4]; conn[23]=nodalConnBg[7]; - // - conn[24]=nodalConnBg[1]; conn[25]=nodalConnBg[2]; conn[26]=nodalConnBg[4]; conn[27]=nodalConnBg[7]; - conn[28]=nodalConnBg[7]; conn[29]=nodalConnBg[10]; conn[30]=nodalConnBg[8]; conn[31]=nodalConnBg[4]; - conn[32]=nodalConnBg[8]; conn[33]=nodalConnBg[4]; conn[34]=nodalConnBg[2]; conn[35]=nodalConnBg[7]; - // - conn[36]=nodalConnBg[2]; conn[37]=nodalConnBg[3]; conn[38]=nodalConnBg[4]; conn[39]=nodalConnBg[8]; - conn[40]=nodalConnBg[8]; conn[41]=nodalConnBg[10]; conn[42]=nodalConnBg[9]; conn[43]=nodalConnBg[4]; - conn[44]=nodalConnBg[9]; conn[45]=nodalConnBg[4]; conn[46]=nodalConnBg[3]; conn[47]=nodalConnBg[8]; - return ; - } - case NORM_POLYHED: - { - std::size_t nbOfFaces(std::count(nodalConnBg,nodalConnEnd,-1)+1); - std::size_t nbOfTetra(std::distance(nodalConnBg,nodalConnEnd)-nbOfFaces+1); - addCoords.resize((nbOfFaces+1)*3); - tetrasNodalConn.resize(nbOfTetra*4); - int *conn(&tetrasNodalConn[0]); - const int *work(nodalConnBg); - double *tmp(&addCoords[0]),*tmp2(&addCoords[3*nbOfFaces]); - tmp2[0]=0.; tmp2[1]=0.; tmp2[2]=0.; - for(std::size_t i=0;i -#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 GENERAL_24_SUB_NODES_WO[28] = - { - 0,4,5,1,// sub-node 8 (face) - 0,1,2,3,// sub-node 9 (face) - 0,3,7,4,// sub-node 10 (face) - 1,5,6,2,// sub-node 11 (face) - 4,7,6,5,// sub-node 12 (face) - 2,6,7,3,// 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 - }; - - // Each sub-node is the barycenter of two other nodes. - // For the edges, these lie on the original mesh. - // For the faces, these are the edge sub-nodes. - // For the cell these are two face sub-nodes. - static const int GENERAL_48_SUB_NODES[38] = - { - 0,1, // sub-node 8 (edge) - 0,4, // sub-node 9 (edge) - 1,5, // sub-node 10 (edge) - 4,5, // sub-node 11 (edge) - 0,3, // sub-node 12 (edge) - 1,2, // sub-node 13 (edge) - 4,7, // sub-node 14 (edge) - 5,6, // sub-node 15 (edge) - 2,3, // sub-node 16 (edge) - 3,7, // sub-node 17 (edge) - 2,6, // sub-node 18 (edge) - 6,7, // sub-node 19 (edge) - 8,11, // sub-node 20 (face) - 12,13, // sub-node 21 (face) - 9,17, // sub-node 22 (face) - 10,18, // sub-node 23 (face) - 14,15, // sub-node 24 (face) - 16,19, // sub-node 25 (face) - 20,25 // sub-node 26 (cell) - }; - - // Define 8 hexahedral subzones as in Grandy, p449 - // the values correspond to the nodes that correspond to nodes 1,2,3,4,5,6,7,8 in the subcell - // For the correspondance of the nodes, see the GENERAL_48_SUB_NODES table in calculateSubNodes - static const int GENERAL_48_SUBZONES[64] = - { - 0,8,21,12,9,20,26,22, - 8,1,13,21,20,10,23,26, - 12,21,16,3,22,26,25,17, - 21,13,2,16,26,23,18,25, - 9,20,26,22,4,11,24,14, - 20,10,23,26,11,5,15,24, - 22,26,25,17,14,24,19,7, - 26,23,18,25,24,15,6,19 - }; - - static const int GENERAL_48_SUBZONES_2[64] = - { - 0,-1,-14,-5,-2,-13,-19,-15, - -1,1,-6,-14,-13,-3,-16,-19, - -5,-14,-9,3,-15,-19,-18,-10, - -14,-6,2,-9,-19,-16,-11,-18, - -2,-13,-19,-15,4,-4,-17,-7, - -13,-3,-16,-19,-4,5,-8,-17, - -15,-19,-18,-10,-7,-17,-12,7, - -19,-16,-11,-18,-17,-8,6,-12}; - - void SplitHexa8IntoTetras(SplittingPolicy policy, const int *nodalConnBg, const int *nodalConnEnd, const double *coords, - std::vector& tetrasNodalConn, std::vector& addCoords); - - INTERPKERNEL_EXPORT void SplitIntoTetras(SplittingPolicy policy, NormalizedCellType gt, const int *nodalConnBg, const int *nodalConnEnd, const double *coords, - std::vector& tetrasNodalConn, std::vector& addCoords); - - /** - * \brief Class representing a triangular face, used as key in caching hash map in SplitterTetra. - * - */ - class TriangleFaceKey - { - public: - - /** - * Constructor - * Sorts the given nodes (so that the order in which they are passed does not matter) and - * calculates a hash value for the key. - * - * @param node1 global number of the first node of the face - * @param node2 global number of the second node of the face - * @param node3 global number of the third node of the face - */ - TriangleFaceKey(int node1, int node2, int node3) - { - Sort3Ints(_nodes, node1, node2, node3); - _hashVal = ( _nodes[0] + _nodes[1] + _nodes[2] ) % 29; - } - - /** - * Equality comparison operator. - * Compares this TriangleFaceKey object to another and determines if they represent the same face. - * - * @param key TriangleFaceKey with which to compare - * @return true if key has the same three nodes as this object, false if not - */ - bool operator==(const TriangleFaceKey& key) const - { - return _nodes[0] == key._nodes[0] && _nodes[1] == key._nodes[1] && _nodes[2] == key._nodes[2]; - } - - /** - * Less than operator. - * - * @param key TriangleFaceKey with which to compare - * @return true if this object has the three nodes less than the nodes of the key object, false if not - */ - bool operator<(const TriangleFaceKey& key) const - { - for (int i = 0; i < 3; ++i) - { - if (_nodes[i] < key._nodes[i]) - { - return true; - } - else if (_nodes[i] > key._nodes[i]) - { - return false; - } - } - return false; - } - - /** - * Returns a hash value for the object, based on its three nodes. - * This value is not unique for each face. - * - * @return a hash value for the object - */ - int hashVal() const - { - return _hashVal; - } - - inline static void Sort3Ints(int* sorted, int node1, int node2, int node3); - - private: - /// global numbers of the three nodes, sorted in ascending order - int _nodes[3]; - - /// hash value for the object, calculated in the constructor - int _hashVal; - }; - - /** - * Method to sort three integers in ascending order - * - * @param sorted int[3] array in which to store the result - * @param x1 first integer - * @param x2 second integer - * @param x3 third integer - */ - inline void TriangleFaceKey::Sort3Ints(int* sorted, int x1, int x2, int x3) - { - if(x1 < x2) - { - if(x1 < x3) - { - // x1 is min - sorted[0] = x1; - sorted[1] = x2 < x3 ? x2 : x3; - sorted[2] = x2 < x3 ? x3 : x2; - } - else - { - // x3, x1, x2 - sorted[0] = x3; - sorted[1] = x1; - sorted[2] = x2; - } - } - else // x2 < x1 - { - if(x2 < x3) - { - // x2 is min - sorted[0] = x2; - sorted[1] = x1 < x3 ? x1 : x3; - sorted[2] = x1 < x3 ? x3 : x1; - } - else - { - // x3, x2, x1 - sorted[0] = x3; - sorted[1] = x2; - sorted[2] = x1; - } - } - } - - /** - * \brief Template specialization of INTERP_KERNEL::hash function object for use with a - * with TriangleFaceKey as key class. - * - */ - template<> class hash - { - public: - /** - * Operator() that returns the precalculated hashvalue of a TriangleFaceKey object. - * - * @param key a TriangleFaceKey object - * @return an integer hash value for key - */ - int operator()(const INTERP_KERNEL::TriangleFaceKey& key) const - { - return key.hashVal(); - } - }; -} - -namespace INTERP_KERNEL -{ - /** - * \brief Class calculating the volume of intersection between a tetrahedral target element and - * source elements with triangular or quadratilateral faces. - * - */ - template - class SplitterTetra - { - public: - - SplitterTetra(const MyMeshType& srcMesh, const double** tetraCorners, const typename MyMeshType::MyConnType *nodesId); - - SplitterTetra(const MyMeshType& srcMesh, const double tetraCorners[12], const int *conn = 0); - - ~SplitterTetra(); - - double intersectSourceCell(typename MyMeshType::MyConnType srcCell, double* baryCentre=0); - double intersectSourceFace(const NormalizedCellType polyType, - const int polyNodesNbr, - const int *const polyNodes, - const double *const *const polyCoords, - const double dimCaracteristic, - const double precision, - std::multiset& listOfTetraFacesTreated, - std::set& listOfTetraFacesColinear); - - double intersectTetra(const double** tetraCorners); - - typename MyMeshType::MyConnType getId(int id) { return _conn[id]; } - - void splitIntoDualCells(SplitterTetra **output); - - void splitMySelfForDual(double* output, int i, typename MyMeshType::MyConnType& nodeId); - - void clearVolumesCache(); - - private: - inline static void CheckIsOutside(const double* pt, bool* isOutside, const double errTol = DEFAULT_ABS_TOL); - inline static void CheckIsStrictlyOutside(const double* pt, bool* isStrictlyOutside, const double errTol = DEFAULT_ABS_TOL); - inline void calculateNode(typename MyMeshType::MyConnType globalNodeNum); - inline void calculateNode2(typename MyMeshType::MyConnType globalNodeNum, const double* node); - inline void calculateVolume(TransformedTriangle& tri, const TriangleFaceKey& key); - inline void calculateSurface(TransformedTriangle& tri, const TriangleFaceKey& key); - - static inline bool IsFacesCoplanar(const double *const planeNormal, const double planeConstant, - const double *const *const coordsFace, const double precision); - static inline double CalculateIntersectionSurfaceOfCoplanarTriangles(const double *const planeNormal, - const double planeConstant, - const double *const p1, const double *const p2, const double *const p3, - const double *const p4, const double *const p5, const double *const p6, - const double dimCaracteristic, const double precision); - - /// disallow copying - SplitterTetra(const SplitterTetra& t); - - /// disallow assignment - SplitterTetra& operator=(const SplitterTetra& t); - - // member variables - /// affine transform associated with this target element - TetraAffineTransform* _t; - - /// HashMap relating node numbers to transformed nodes, used for caching - HashMap< int , double* > _nodes; - - /// HashMap relating triangular faces to calculated volume contributions, used for caching - HashMap< TriangleFaceKey, double > _volumes; - - /// reference to the source mesh - const MyMeshType& _src_mesh; - - // node id of the first node in target mesh in C mode. - typename MyMeshType::MyConnType _conn[4]; - - double _coords[12]; - - /// Smallest volume of the intersecting elements in the transformed space that will be returned as non-zero. - /// Since the scale is always the same in the transformed space (the target tetrahedron is unitary), this number is independent of the scale of the meshes. - static const double SPARSE_TRUNCATION_LIMIT; - }; - - /** - * Function used to filter out elements by checking if they belong to one of the halfspaces - * x <= 0, x >= 1, y <= 0, y >= 1, z <= 0, z >= 1, (indexed 0 - 7). The function updates an array of boolean variables - * which indicates whether the points that have already been checked are all in a halfspace. For each halfspace, - * the corresponding array element will be true if and only if it was true when the method was called and pt lies in the halfspace. - * - * @param pt double[3] containing the coordiantes of a transformed point - * @param isOutside bool[8] which indicate the results of earlier checks. - */ - template - inline void SplitterTetra::CheckIsOutside(const double* pt, bool* isOutside, const double errTol) - { - isOutside[0] = isOutside[0] && (pt[0] < errTol); - isOutside[1] = isOutside[1] && (pt[0] > (1.0-errTol) ); - isOutside[2] = isOutside[2] && (pt[1] < errTol); - isOutside[3] = isOutside[3] && (pt[1] > (1.0-errTol)); - isOutside[4] = isOutside[4] && (pt[2] < errTol); - isOutside[5] = isOutside[5] && (pt[2] > (1.0-errTol)); - isOutside[6] = isOutside[6] && (1.0 - pt[0] - pt[1] - pt[2] < errTol); - isOutside[7] = isOutside[7] && (1.0 - pt[0] - pt[1] - pt[2] > (1.0-errTol) ); - } - - template - inline void SplitterTetra::CheckIsStrictlyOutside(const double* pt, bool* isStrictlyOutside, const double errTol) - { - isStrictlyOutside[0] = isStrictlyOutside[0] && (pt[0] < -errTol); - isStrictlyOutside[1] = isStrictlyOutside[1] && (pt[0] > (1.0 + errTol)); - isStrictlyOutside[2] = isStrictlyOutside[2] && (pt[1] < -errTol); - isStrictlyOutside[3] = isStrictlyOutside[3] && (pt[1] > (1.0 + errTol)); - isStrictlyOutside[4] = isStrictlyOutside[4] && (pt[2] < -errTol); - isStrictlyOutside[5] = isStrictlyOutside[5] && (pt[2] > (1.0 + errTol)); - isStrictlyOutside[6] = isStrictlyOutside[6] && (1.0 - pt[0] - pt[1] - pt[2] < -errTol); - isStrictlyOutside[7] = isStrictlyOutside[7] && (1.0 - pt[0] - pt[1] - pt[2] > (1.0 + errTol)); - } - - /** - * Calculates the transformed node with a given global node number. - * Gets the coordinates for the node in _src_mesh with the given global number and applies TetraAffineTransform - * _t to it. Stores the result in the cache _nodes. The non-existance of the node in _nodes should be verified before - * calling. - * - * @param globalNodeNum global node number of the node in the mesh _src_mesh - * - */ - template - inline void SplitterTetra::calculateNode(typename MyMeshType::MyConnType globalNodeNum) - { - const double* node = _src_mesh.getCoordinatesPtr()+MyMeshType::MY_SPACEDIM*globalNodeNum; - double* transformedNode = new double[MyMeshType::MY_SPACEDIM]; - assert(transformedNode != 0); - _t->apply(transformedNode, node); - _nodes[globalNodeNum] = transformedNode; - } - - - /** - * Calculates the transformed node with a given global node number. - * Applies TetraAffineTransform * _t to it. - * Stores the result in the cache _nodes. The non-existence of the node in _nodes should be verified before * calling. - * The only difference with the previous method calculateNode is that the coordinates of the node are passed in arguments - * and are not recalculated in order to optimize the method. - * - * @param globalNodeNum global node number of the node in the mesh _src_mesh - * - */ - template - inline void SplitterTetra::calculateNode2(typename MyMeshType::MyConnType globalNodeNum, const double* node) - { - double* transformedNode = new double[MyMeshType::MY_SPACEDIM]; - assert(transformedNode != 0); - _t->apply(transformedNode, node); - _nodes[globalNodeNum] = transformedNode; - } - - /** - * Calculates the volume contribution from the given TransformedTriangle and stores it with the given key in . - * Calls TransformedTriangle::calculateIntersectionVolume to perform the calculation. - * - * @param tri triangle for which to calculate the volume contribution - * @param key key associated with the face - */ - template - inline void SplitterTetra::calculateVolume(TransformedTriangle& tri, const TriangleFaceKey& key) - { - const double vol = tri.calculateIntersectionVolume(); - _volumes.insert(std::make_pair(key, vol)); - } - - /** - * Calculates the surface contribution from the given TransformedTriangle and stores it with the given key in. - * Calls TransformedTriangle::calculateIntersectionSurface to perform the calculation. - * - * @param tri triangle for which to calculate the surface contribution - * @param key key associated with the face - */ - template - inline void SplitterTetra::calculateSurface(TransformedTriangle& tri, const TriangleFaceKey& key) - { - const double surf = tri.calculateIntersectionSurface(_t); - _volumes.insert(std::make_pair(key, surf)); - } - - template - class SplitterTetra2 - { - public: - SplitterTetra2(const MyMeshTypeT& targetMesh, const MyMeshTypeS& srcMesh, SplittingPolicy policy); - ~SplitterTetra2(); - void releaseArrays(); - void splitTargetCell2(typename MyMeshTypeT::MyConnType targetCell, typename std::vector< SplitterTetra* >& tetra); - void splitTargetCell(typename MyMeshTypeT::MyConnType targetCell, typename MyMeshTypeT::MyConnType nbOfNodesT, - typename std::vector< SplitterTetra* >& tetra);//to suppress - void fiveSplit(const int* const subZone, typename std::vector< SplitterTetra* >& tetra);//to suppress - void sixSplit(const int* const subZone, typename std::vector< SplitterTetra* >& tetra);//to suppress - void calculateGeneral24Tetra(typename std::vector< SplitterTetra* >& tetra);//to suppress - void calculateGeneral48Tetra(typename std::vector< SplitterTetra* >& tetra);//to suppress - void splitPyram5(typename std::vector< SplitterTetra* >& tetra);//to suppress - void splitConvex(typename MyMeshTypeT::MyConnType targetCell,//to suppress - typename std::vector< SplitterTetra* >& tetra);//to suppress - void calculateSubNodes(const MyMeshTypeT& targetMesh, typename MyMeshTypeT::MyConnType targetCell);//to suppress - inline const double* getCoordsOfSubNode(typename MyMeshTypeT::MyConnType node);//to suppress - inline const double* getCoordsOfSubNode2(typename MyMeshTypeT::MyConnType node, typename MyMeshTypeT::MyConnType& nodeId);//to suppress - //template - inline void calcBarycenter(int n, double* barycenter, const typename MyMeshTypeT::MyConnType* pts);//to suppress - private: - const MyMeshTypeT& _target_mesh; - const MyMeshTypeS& _src_mesh; - SplittingPolicy _splitting_pol; - /// vector of pointers to double[3] containing the coordinates of the - /// (sub) - nodes of split target cell - std::vector _nodes; - std::vector _node_ids; - }; - - /** - * Calculates the barycenter of n (sub) - nodes - * - * @param n number of nodes for which to calculate barycenter - * @param barycenter pointer to double[3] array in which to store the result - * @param pts pointer to int[n] array containing the (sub)-nodes for which to calculate the barycenter - */ - template - //template - inline void SplitterTetra2::calcBarycenter(int n, double* barycenter, const typename MyMeshTypeT::MyConnType* pts) - { - barycenter[0] = barycenter[1] = barycenter[2] = 0.0; - for(int i = 0; i < n ; ++i) - { - const double* pt = getCoordsOfSubNode(pts[i]); - barycenter[0] += pt[0]; - barycenter[1] += pt[1]; - barycenter[2] += pt[2]; - } - - barycenter[0] /= n; - barycenter[1] /= n; - barycenter[2] /= n; - } - - /** - * Accessor to the coordinates of a given (sub)-node - * - * @param node local number of the (sub)-node 0,..,7 are the elements nodes, sub-nodes are numbered from 8,.. - * @return pointer to double[3] containing the coordinates of the nodes - */ - template - inline const double* SplitterTetra2::getCoordsOfSubNode(typename MyMeshTypeT::MyConnType node) - { - // replace "at()" with [] for unsafe but faster access - return _nodes.at(node); - } - - /** - * Accessor to the coordinates of a given (sub)-node - * - * @param node local number of the (sub)-node 0,..,7 are the elements nodes, sub-nodes are numbered from 8,.. - * @param nodeId is an output that is node id in target whole mesh in C mode. - * @return pointer to double[3] containing the coordinates of the nodes - */ - template - const double* SplitterTetra2::getCoordsOfSubNode2(typename MyMeshTypeT::MyConnType node, typename MyMeshTypeT::MyConnType& nodeId) - { - const double *ret=_nodes.at(node); - if(node<8) - nodeId=_node_ids[node]; - else - nodeId=-1; - return ret; - } -} - -#endif diff --git a/src/INTERP_KERNEL/SplitterTetra.txx b/src/INTERP_KERNEL/SplitterTetra.txx deleted file mode 100644 index 226a6264c..000000000 --- a/src/INTERP_KERNEL/SplitterTetra.txx +++ /dev/null @@ -1,1319 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 -// 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 __SPLITTERTETRA_TXX__ -#define __SPLITTERTETRA_TXX__ - -#include "SplitterTetra.hxx" - -#include "TetraAffineTransform.hxx" -#include "TransformedTriangle.hxx" -#include "MeshUtils.hxx" -#include "VectorUtils.hxx" -#include "CellModel.hxx" -#include "Log.hxx" -#include "UnitTetraIntersectionBary.hxx" -#include "VolSurfFormulae.hxx" - -#include -#include -#include -#include -#include - -namespace INTERP_KERNEL -{ - template - const double SplitterTetra::SPARSE_TRUNCATION_LIMIT=1.0e-14; - - /*! - * output is expected to be allocated with 24*sizeof(void*) in order to store the 24 tetras. - * These tetras have to be deallocated. - */ - template - void SplitterTetra::splitIntoDualCells(SplitterTetra **output) - { - double tmp[12]; - const double *tmp2[4]={tmp,tmp+3,tmp+6,tmp+9}; - typename MyMeshType::MyConnType conn[4]={-1,-1,-1,-1}; - for(int i=0;i<24;i++) - { - splitMySelfForDual(tmp,i,conn[0]); - output[i]=new SplitterTetra(_src_mesh,tmp2,conn); - } - } - - /** - * SplitterTetra class computes for a list of cell ids of a given mesh \a srcMesh (badly named) the intersection with a - * single TETRA4 cell given by \a tetraCorners (of length 4) and \a nodesId (of length 4 too). \a nodedIds is given only to establish - * if a partial computation of a triangle has already been performed (to increase performance). - * - * The \a srcMesh can contain polyhedron cells. - * - * - * Constructor creating object from the four corners of the tetrahedron. - * - * @param srcMesh mesh containing the source elements - * @param tetraCorners array of four pointers to double[3] arrays containing the coordinates of the - * corners of the tetrahedron - */ - template - SplitterTetra::SplitterTetra(const MyMeshType& srcMesh, const double** tetraCorners, const typename MyMeshType::MyConnType *nodesId) - : _t(0), _src_mesh(srcMesh) - { - std::copy(nodesId,nodesId+4,_conn); - _coords[0]=tetraCorners[0][0]; _coords[1]=tetraCorners[0][1]; _coords[2]=tetraCorners[0][2]; - _coords[3]=tetraCorners[1][0]; _coords[4]=tetraCorners[1][1]; _coords[5]=tetraCorners[1][2]; - _coords[6]=tetraCorners[2][0]; _coords[7]=tetraCorners[2][1]; _coords[8]=tetraCorners[2][2]; - _coords[9]=tetraCorners[3][0]; _coords[10]=tetraCorners[3][1]; _coords[11]=tetraCorners[3][2]; - // create the affine transform - _t=new TetraAffineTransform(_coords); - } - - /** - * SplitterTetra class computes for a list of cell ids of a given mesh \a srcMesh (badly named) the intersection with a - * single TETRA4 cell given by \a tetraCorners (of length 4) and \a nodesId (of length 4 too). \a nodedIds is given only to establish - * if a partial computation of a triangle has already been performed (to increase performance). - * - * The \a srcMesh can contain polyhedron cells. - * - * - * Constructor creating object from the four corners of the tetrahedron. - * - * \param [in] srcMesh mesh containing the source elements - * \param [in] tetraCorners array 4*3 doubles containing corners of input tetrahedron (P0X,P0Y,P0Y,P1X,P1Y,P1Z,P2X,P2Y,P2Z,P3X,P3Y,P3Z). - */ - template - SplitterTetra::SplitterTetra(const MyMeshType& srcMesh, const double tetraCorners[12], const int *conn): _t(0),_src_mesh(srcMesh) - { - if(!conn) - { _conn[0]=0; _conn[1]=1; _conn[2]=2; _conn[3]=3; } - else - { _conn[0]=conn[0]; _conn[1]=conn[1]; _conn[2]=conn[2]; _conn[3]=conn[3]; } - _coords[0]=tetraCorners[0]; _coords[1]=tetraCorners[1]; _coords[2]=tetraCorners[2]; _coords[3]=tetraCorners[3]; _coords[4]=tetraCorners[4]; _coords[5]=tetraCorners[5]; - _coords[6]=tetraCorners[6]; _coords[7]=tetraCorners[7]; _coords[8]=tetraCorners[8]; _coords[9]=tetraCorners[9]; _coords[10]=tetraCorners[10]; _coords[11]=tetraCorners[11]; - // create the affine transform - _t=new TetraAffineTransform(_coords); - } - - /** - * Destructor - * - * Deletes _t and the coordinates (double[3] vectors) in _nodes - * - */ - template - SplitterTetra::~SplitterTetra() - { - delete _t; - for(HashMap< int, double* >::iterator iter = _nodes.begin(); iter != _nodes.end() ; ++iter) - delete[] iter->second; - } - - /*! - * \Forget already calculated triangles, which is crucial for calculation of barycenter of intersection - */ - template - void SplitterTetra::clearVolumesCache() - { - _volumes.clear(); - } - - /*! - * This method destroys the 4 pointers pointed by tetraCorners[0],tetraCorners[1],tetraCorners[2] and tetraCorners[3] - * @param i is in 0..23 included. - * @param output is expected to be sized of 12 in order to. - */ - template - void SplitterTetra::splitMySelfForDual(double* output, int i, typename MyMeshType::MyConnType& nodeId) - { - double *tmp[4]; - int offset=i/6; - nodeId=_conn[offset]; - tmp[0]=_coords+3*offset; tmp[1]=_coords+((offset+1)%4)*3; tmp[2]=_coords+((offset+2)%4)*3; tmp[3]=_coords+((offset+3)%4)*3; - int caseToTreat=i%6; - int case1=caseToTreat/2; - int case2=caseToTreat%2; - const int tab[3][2]={{1,2},{3,2},{1,3}}; - const int *curTab=tab[case1]; - double pt0[3]; pt0[0]=(tmp[curTab[case2]][0]+tmp[0][0])/2.; pt0[1]=(tmp[curTab[case2]][1]+tmp[0][1])/2.; pt0[2]=(tmp[curTab[case2]][2]+tmp[0][2])/2.; - double pt1[3]; pt1[0]=(tmp[0][0]+tmp[curTab[0]][0]+tmp[curTab[1]][0])/3.; pt1[1]=(tmp[0][1]+tmp[curTab[0]][1]+tmp[curTab[1]][1])/3.; pt1[2]=(tmp[0][2]+tmp[curTab[0]][2]+tmp[curTab[1]][2])/3.; - double pt2[3]; pt2[0]=(tmp[0][0]+tmp[1][0]+tmp[2][0]+tmp[3][0])/4.; pt2[1]=(tmp[0][1]+tmp[1][1]+tmp[2][1]+tmp[3][1])/4.; pt2[2]=(tmp[0][2]+tmp[1][2]+tmp[2][2]+tmp[3][2])/4.; - std::copy(pt1,pt1+3,output+case2*3); - std::copy(pt0,pt0+3,output+(abs(case2-1))*3); - std::copy(pt2,pt2+3,output+2*3); - std::copy(tmp[0],tmp[0]+3,output+3*3); - } - - /** - * Calculates the volume of intersection of an element in the source mesh and the target element. - * It first calculates the transformation that takes the target tetrahedron into the unit tetrahedron. After that, the - * faces of the source element are triangulated and the calculated transformation is applied - * to each triangle. The algorithm of Grandy, implemented in INTERP_KERNEL::TransformedTriangle is used - * to calculate the contribution to the volume from each triangle. The volume returned is the sum of these contributions - * divided by the determinant of the transformation. - * - * The class will cache the intermediary calculations of transformed nodes of source cells and volumes associated - * with triangulated faces to avoid having to recalculate these. - * - * @param element global number of the source element in C mode. - */ - template - double SplitterTetra::intersectSourceCell(typename MyMeshType::MyConnType element, - double* baryCentre) - { - typedef typename MyMeshType::MyConnType ConnType; - const NumberingPolicy numPol=MyMeshType::My_numPol; - //{ could be done on outside? - // check if we have planar tetra element - if(_t->determinant() == 0.0) - { - // tetra is planar - LOG(2, "Planar tetra -- volume 0"); - return 0.0; - } - - // get type of cell - NormalizedCellType normCellType=_src_mesh.getTypeOfElement(OTT::indFC(element)); - const CellModel& cellModelCell=CellModel::GetCellModel(normCellType); - unsigned nbOfNodes4Type=cellModelCell.isDynamic() ? _src_mesh.getNumberOfNodesOfElement(OTT::indFC(element)) : cellModelCell.getNumberOfNodes(); - // halfspace filtering - bool isOutside[8] = {true, true, true, true, true, true, true, true}; - bool isTargetOutside = false; - - // calculate the coordinates of the nodes - int *cellNodes=new int[nbOfNodes4Type]; - for(int i = 0;i<(int)nbOfNodes4Type;++i) - { - // we could store mapping local -> global numbers too, but not sure it is worth it - const int globalNodeNum = getGlobalNumberOfNode(i, OTT::indFC(element), _src_mesh); - cellNodes[i]=globalNodeNum; - if(_nodes.find(globalNodeNum) == _nodes.end()) - { - //for(HashMap< int , double* >::iterator iter3=_nodes.begin();iter3!=_nodes.end();iter3++) - // std::cout << (*iter3).first << " "; - //std::cout << std::endl << "*** " << globalNodeNum << std::endl; - calculateNode(globalNodeNum); - } - CheckIsOutside(_nodes[globalNodeNum], isOutside); - } - - // halfspace filtering check - // NB : might not be beneficial for caching of triangles - for(int i = 0; i < 8; ++i) - { - if(isOutside[i]) - { - isTargetOutside = true; - } - } - - double totalVolume = 0.0; - - if(!isTargetOutside) - { - /// calculator of intersection barycentre - UnitTetraIntersectionBary baryCalculator( _t->determinant() < 0.); - - // get nb of sons of a cell - const ConnType* rawCellConn = _src_mesh.getConnectivityPtr() + OTT::conn2C( _src_mesh.getConnectivityIndexPtr()[ element ]); - const int rawNbCellNodes = _src_mesh.getConnectivityIndexPtr()[ element+1 ] - _src_mesh.getConnectivityIndexPtr()[ element ]; - unsigned nbOfSons = cellModelCell.getNumberOfSons2(rawCellConn, rawNbCellNodes); - - for(unsigned ii = 0 ; ii < nbOfSons; ++ii) - { - // get sons connectivity - NormalizedCellType faceType; - int *faceNodes, nbFaceNodes=-1; - if ( cellModelCell.isDynamic() ) - { - faceNodes=new int[nbOfNodes4Type]; - nbFaceNodes = cellModelCell.fillSonCellNodalConnectivity2(ii,rawCellConn,rawNbCellNodes,faceNodes,faceType); - for ( int i = 0; i < nbFaceNodes; ++i ) - faceNodes[i] = OTT::coo2C(faceNodes[i]); - } - else - { - faceType = cellModelCell.getSonType(ii); - const CellModel& faceModel=CellModel::GetCellModel(faceType); - assert(faceModel.getDimension() == 2); - faceNodes=new int[faceModel.getNumberOfNodes()]; - cellModelCell.fillSonCellNodalConnectivity(ii,cellNodes,faceNodes); - } - // intersect a son with the unit tetra - switch(faceType) - { - case NORM_TRI3: - { - // create the face key - TriangleFaceKey key = TriangleFaceKey(faceNodes[0], faceNodes[1], faceNodes[2]); - - // calculate the triangle if needed - if(_volumes.find(key) == _volumes.end()) - { - TransformedTriangle tri(_nodes[faceNodes[0]], _nodes[faceNodes[1]], _nodes[faceNodes[2]]); - calculateVolume(tri, key); - totalVolume += _volumes[key]; - if ( baryCentre ) - baryCalculator.addSide( tri ); - } else { - // count negative as face has reversed orientation - totalVolume -= _volumes[key]; - } - } - break; - - case NORM_QUAD4: - - // simple triangulation of faces along a diagonal : - // - // 2 ------ 3 - // | / | - // | / | - // | / | - // | / | - // | / | - // | / | - // 1 ------ 4 - // - //? not sure if this always works - { - // calculate the triangles if needed - - // local nodes 1, 2, 3 - TriangleFaceKey key1 = TriangleFaceKey(faceNodes[0], faceNodes[1], faceNodes[2]); - if(_volumes.find(key1) == _volumes.end()) - { - TransformedTriangle tri(_nodes[faceNodes[0]], _nodes[faceNodes[1]], _nodes[faceNodes[2]]); - calculateVolume(tri, key1); - totalVolume += _volumes[key1]; - } else { - // count negative as face has reversed orientation - totalVolume -= _volumes[key1]; - } - - // local nodes 1, 3, 4 - TriangleFaceKey key2 = TriangleFaceKey(faceNodes[0], faceNodes[2], faceNodes[3]); - if(_volumes.find(key2) == _volumes.end()) - { - TransformedTriangle tri(_nodes[faceNodes[0]], _nodes[faceNodes[2]], _nodes[faceNodes[3]]); - calculateVolume(tri, key2); - totalVolume += _volumes[key2]; - } - else - { - // count negative as face has reversed orientation - totalVolume -= _volumes[key2]; - } - } - break; - - case NORM_POLYGON: - { - int nbTria = nbFaceNodes - 2; // split polygon into nbTria triangles - for ( int iTri = 0; iTri < nbTria; ++iTri ) - { - TriangleFaceKey key = TriangleFaceKey(faceNodes[0], faceNodes[1+iTri], faceNodes[2+iTri]); - if(_volumes.find(key) == _volumes.end()) - { - TransformedTriangle tri(_nodes[faceNodes[0]], _nodes[faceNodes[1+iTri]], _nodes[faceNodes[2+iTri]]); - calculateVolume(tri, key); - totalVolume += _volumes[key]; - } - else - { - totalVolume -= _volumes[key]; - } - } - } - break; - - default: - std::cout << "+++ Error : Only elements with triangular and quadratilateral faces are supported at the moment." << std::endl; - assert(false); - } - delete [] faceNodes; - } - - if ( baryCentre ) { - baryCalculator.getBary( baryCentre ); - _t->reverseApply( baryCentre, baryCentre ); - } - } - delete [] cellNodes; - // reset if it is very small to keep the matrix sparse - // is this a good idea? - if(epsilonEqual(totalVolume, 0.0, SPARSE_TRUNCATION_LIMIT)) - { - totalVolume = 0.0; - } - - LOG(2, "Volume = " << totalVolume << ", det= " << _t->determinant()); - - // NB : fault in article, Grandy, [8] : it is the determinant of the inverse transformation - // that should be used (which is equivalent to dividing by the determinant) - return std::fabs(1.0 / _t->determinant() * totalVolume) ; - } - - /** - * Calculates the intersection surface of two coplanar triangles. - * - * @param palneNormal normal of the plane for the first triangle - * @param planeConstant constant of the equation of the plane for the first triangle - * @param p1 coordinates of the first node of the first triangle - * @param p2 coordinates of the second node of the first triangle - * @param p3 coordinates of the third node of the first triangle - * @param p4 coordinates of the first node of the second triangle - * @param p5 coordinates of the second node of the second triangle - * @param p6 coordinates of the third node of the second triangle - * @param dimCaracteristic characteristic size of the meshes containing the triangles - * @param precision precision for double float data used for comparison - */ - template - double SplitterTetra::CalculateIntersectionSurfaceOfCoplanarTriangles(const double *const planeNormal, - const double planeConstant, - const double *const p1, const double *const p2, const double *const p3, - const double *const p4, const double *const p5, const double *const p6, - const double dimCaracteristic, const double precision) - { - typedef typename MyMeshType::MyConnType ConnType; - typedef double Vect2[2]; - typedef double Triangle2[3][2]; - - const double *const tri0[3] = {p1, p2, p3}; - const double *const tri1[3] = {p4, p5, p6}; - - // Plane of the first triangle defined by the normal of the triangle and the constant - // Project triangles onto coordinate plane most aligned with plane normal - int maxNormal = 0; - double fmax = std::abs(planeNormal[0]); - double absMax = std::abs(planeNormal[1]); - if (absMax > fmax) - { - maxNormal = 1; - fmax = absMax; - } - absMax = std::abs(planeNormal[2]); - if (absMax > fmax) - { - maxNormal = 2; - } - - Triangle2 projTri0, projTri1; - int i; - - if (maxNormal == 0) - { - // Project onto yz-plane. - for (i = 0; i < 3; ++i) - { - projTri0[i][0] = tri0[i][1]; - projTri0[i][1] = tri0[i][2]; - projTri1[i][0] = tri1[i][1]; - projTri1[i][1] = tri1[i][2]; - } - } - else if (maxNormal == 1) - { - // Project onto xz-plane. - for (i = 0; i < 3; ++i) - { - projTri0[i][0] = tri0[i][0]; - projTri0[i][1] = tri0[i][2]; - projTri1[i][0] = tri1[i][0]; - projTri1[i][1] = tri1[i][2]; - } - } - else - { - // Project onto xy-plane. - for (i = 0; i < 3; ++i) - { - projTri0[i][0] = tri0[i][0]; - projTri0[i][1] = tri0[i][1]; - projTri1[i][0] = tri1[i][0]; - projTri1[i][1] = tri1[i][1]; - } - } - - // 2D triangle intersection routines require counterclockwise ordering. - Vect2 save; - Vect2 edge0; - Vect2 edge1; - for (int ii = 0; ii < 2; ++ii) - { - edge0[ii] = projTri0[1][ii] - projTri0[0][ii]; - edge1[ii] = projTri0[2][ii] - projTri0[0][ii]; - } - if ((edge0[0] * edge1[1] - edge0[1] * edge1[0]) < (double) 0.) - { - // Triangle is clockwise, reorder it. - for (int ii = 0; ii < 2; ++ii) - { - save[ii] = projTri0[1][ii]; - projTri0[1][ii] = projTri0[2][ii]; - projTri0[2][ii] = save[ii]; - } - } - - for (int ii = 0; ii < 2; ++ii) - { - edge0[ii] = projTri1[1][ii] - projTri1[0][ii]; - edge1[ii] = projTri1[2][ii] - projTri1[0][ii]; - } - if ((edge0[0] * edge1[1] - edge0[1] * edge1[0]) < (double) 0.) - { - // Triangle is clockwise, reorder it. - for (int ii = 0; ii < 2; ++ii) - { - save[ii] = projTri1[1][ii]; - projTri1[1][ii] = projTri1[2][ii]; - projTri1[2][ii] = save[ii]; - } - } - - std::vector inter2; - intersec_de_triangle(projTri0[0], projTri0[1], projTri0[2], - projTri1[0], projTri1[1], projTri1[2], - inter2, - dimCaracteristic, precision); - ConnType nb_inter=((ConnType)inter2.size())/2; - double surface = 0.; - if(nb_inter >3) inter2=reconstruct_polygon(inter2); - if (nb_inter > 0) - { - std::vector inter3; - inter3.resize(3 * nb_inter); - // Map 2D intersections back to the 3D triangle space. - if (maxNormal == 0) - { - double invNX = ((double) 1.) / planeNormal[0]; - for (i = 0; i < nb_inter; i++) - { - inter3[3 * i + 1] = inter2[2 * i]; - inter3[3 * i + 2] = inter2[2 * i + 1]; - inter3[3 * i] = invNX * (planeConstant - planeNormal[1] * inter3[3 * i + 1] - planeNormal[2] * inter3[3 * i + 2]); - } - } - else if (maxNormal == 1) - { - double invNY = ((double) 1.) / planeNormal[1]; - for (i = 0; i < nb_inter; i++) - { - inter3[3 * i] = inter2[2 * i]; - inter3[3 * i + 2] = inter2[2 * i + 1]; - inter3[3 * i + 1] = invNY * (planeConstant - planeNormal[0] * inter3[3 * i] - planeNormal[2] * inter3[3 * i + 2]); - } - } - else - { - double invNZ = ((double) 1.) / planeNormal[2]; - for (i = 0; i < nb_inter; i++) - { - inter3[3 * i] = inter2[2 * i]; - inter3[3 * i + 1] = inter2[2 * i + 1]; - inter3[3 * i + 2] = invNZ * (planeConstant - planeNormal[0] * inter3[3 * i] - planeNormal[1] * inter3[3 * i + 1]); - } - } - surface = polygon_area<3>(inter3); - } - return surface; - } - - /** - * Determine if a face is coplanar with a triangle. - * The first face is characterized by the equation of her plane - * - * @param palneNormal normal of the plane for the first triangle - * @param planeConstant constant of the equation of the plane for the first triangle - * @param coordsFace coordinates of the triangle face - * @param precision precision for double float data used for comparison - */ - template - bool SplitterTetra::IsFacesCoplanar(const double *const planeNormal, - const double planeConstant, - const double *const *const coordsFace, - const double precision) - { - // Compute the signed distances of triangle vertices to the plane. Use an epsilon-thick plane test. - // For faces not left - int counter = 0; - for (int i = 0; i < 3; ++i) - { - const double distance = dot(planeNormal, coordsFace[i]) - planeConstant; - if (epsilonEqual(distance, precision)) - { - counter++; - } - } - return counter == 3; - } - - /** - * Calculates the surface of intersection of a polygon face in the source mesh and a cell of the target mesh. - * It first calculates the transformation that takes the target tetrahedron into the unit tetrahedron. After that, the - * faces of the source element are triangulated and the calculated transformation is applied - * to each triangle. - * The algorithm is based on the algorithm of Grandy used in intersectSourceCell to compute - * the volume of intersection of two cell elements. - * The case with a source face colinear to one of the face of tetrahedrons is taking into account: - * the contribution of the face must not be counted two times. - * - * The class will cache the intermediary calculations of transformed nodes of source faces and surfaces associated - * with triangulated faces to avoid having to recalculate these. - * - * @param polyType type of the polygon source face - * @param polyNodesNbr number of the nodes of the polygon source face - * @param polyNodes numbers of the nodes of the polygon source face - * @param polyCoords coordinates of the nodes of the polygon source face - * @param dimCaracteristic characteristic size of the meshes containing the triangles - * @param precision precision for double float data used for comparison - * @param listOfTetraFacesTreated list of tetra faces treated - * @param listOfTetraFacesColinear list of tetra faces colinear with the polygon source faces - */ - template - double SplitterTetra::intersectSourceFace(const NormalizedCellType polyType, - const int polyNodesNbr, - const int *const polyNodes, - const double *const *const polyCoords, - const double dimCaracteristic, - const double precision, - std::multiset& listOfTetraFacesTreated, - std::set& listOfTetraFacesColinear) - { - double totalSurface = 0.0; - - // check if we have planar tetra element - if(_t->determinant() == 0.0) - { - // tetra is planar - LOG(2, "Planar tetra -- volume 0"); - return 0.0; - } - - // halfspace filtering - bool isOutside[8] = {true, true, true, true, true, true, true, true}; - bool isStrictlyOutside[8] = {true, true, true, true, true, true, true, true}; - bool isTargetStrictlyOutside = false; - bool isTargetOutside = false; - - // calculate the coordinates of the nodes - for(int i = 0;i<(int)polyNodesNbr;++i) - { - const int globalNodeNum = polyNodes[i]; - if(_nodes.find(globalNodeNum) == _nodes.end()) - { - calculateNode2(globalNodeNum, polyCoords[i]); - } - - CheckIsStrictlyOutside(_nodes[globalNodeNum], isStrictlyOutside, precision); - CheckIsOutside(_nodes[globalNodeNum], isOutside, precision); - } - - // halfspace filtering check - // NB : might not be beneficial for caching of triangles - for(int i = 0; i < 8; ++i) - { - if(isStrictlyOutside[i]) - { - isTargetStrictlyOutside = true; - break; - } - else if (isOutside[i]) - { - isTargetOutside = true; - } - } - - if (!isTargetStrictlyOutside) - { - - if (isTargetOutside) - { - // Faces are parallel - const int tetraFacesNodesConn[4][3] = { - { 0, 1, 2 }, - { 0, 2, 3 }, - { 0, 3, 1 }, - { 1, 2, 3 } }; - double planeNormal[3]; - for (int iTetraFace = 0; iTetraFace < 4; ++iTetraFace) - { - const int * const tetraFaceNodesConn = tetraFacesNodesConn[iTetraFace]; - TriangleFaceKey key = TriangleFaceKey(_conn[tetraFaceNodesConn[0]], - _conn[tetraFaceNodesConn[1]], - _conn[tetraFaceNodesConn[2]]); - if (listOfTetraFacesTreated.find(key) == listOfTetraFacesTreated.end()) - { - const double * const coordsTetraTriNode1 = _coords + tetraFaceNodesConn[0] * MyMeshType::MY_SPACEDIM; - const double * const coordsTetraTriNode2 = _coords + tetraFaceNodesConn[1] * MyMeshType::MY_SPACEDIM; - const double * const coordsTetraTriNode3 = _coords + tetraFaceNodesConn[2] * MyMeshType::MY_SPACEDIM; - calculateNormalForTria(coordsTetraTriNode1, coordsTetraTriNode2, coordsTetraTriNode3, planeNormal); - const double normOfTetraTriNormal = norm(planeNormal); - if (epsilonEqual(normOfTetraTriNormal, 0.)) - { - for (int i = 0; i < 3; ++i) - { - planeNormal[i] = 0.; - } - } - else - { - const double invNormOfTetraTriNormal = 1. / normOfTetraTriNormal; - for (int i = 0; i < 3; ++i) - { - planeNormal[i] *= invNormOfTetraTriNormal; - } - } - double planeConstant = dot(planeNormal, coordsTetraTriNode1); - if (IsFacesCoplanar(planeNormal, planeConstant, polyCoords, precision)) - { - int nbrPolyTri = polyNodesNbr - 2; // split polygon into nbrPolyTri triangles - for (int iTri = 0; iTri < nbrPolyTri; ++iTri) - { - double volume = CalculateIntersectionSurfaceOfCoplanarTriangles(planeNormal, - planeConstant, - polyCoords[0], - polyCoords[1 + iTri], - polyCoords[2 + iTri], - coordsTetraTriNode1, - coordsTetraTriNode2, - coordsTetraTriNode3, - dimCaracteristic, - precision); - if (!epsilonEqual(volume, 0.)) - { - totalSurface += volume; - listOfTetraFacesColinear.insert(key); - } - } - } - } - listOfTetraFacesTreated.insert(key); - } - } - else - { - // intersect a son with the unit tetra - switch (polyType) - { - case NORM_TRI3: - { - // create the face key - TriangleFaceKey key = TriangleFaceKey(polyNodes[0], polyNodes[1], polyNodes[2]); - - // calculate the triangle if needed - if (_volumes.find(key) == _volumes.end()) - { - TransformedTriangle tri(_nodes[polyNodes[0]], _nodes[polyNodes[1]], _nodes[polyNodes[2]]); - calculateSurface(tri, key); - totalSurface += _volumes[key]; - } - else - { - // count negative as face has reversed orientation - totalSurface -= _volumes[key]; - } - } - break; - - case NORM_QUAD4: - - // simple triangulation of faces along a diagonal : - // - // 2 ------ 3 - // | / | - // | / | - // | / | - // | / | - // | / | - // | / | - // 1 ------ 4 - // - //? not sure if this always works - { - // calculate the triangles if needed - - // local nodes 1, 2, 3 - TriangleFaceKey key1 = TriangleFaceKey(polyNodes[0], polyNodes[1], polyNodes[2]); - if (_volumes.find(key1) == _volumes.end()) - { - TransformedTriangle tri(_nodes[polyNodes[0]], _nodes[polyNodes[1]], _nodes[polyNodes[2]]); - calculateSurface(tri, key1); - totalSurface += _volumes[key1]; - } - else - { - // count negative as face has reversed orientation - totalSurface -= _volumes[key1]; - } - - // local nodes 1, 3, 4 - TriangleFaceKey key2 = TriangleFaceKey(polyNodes[0], polyNodes[2], polyNodes[3]); - if (_volumes.find(key2) == _volumes.end()) - { - TransformedTriangle tri(_nodes[polyNodes[0]], _nodes[polyNodes[2]], _nodes[polyNodes[3]]); - calculateSurface(tri, key2); - totalSurface += _volumes[key2]; - } - else - { - // count negative as face has reversed orientation - totalSurface -= _volumes[key2]; - } - } - break; - - case NORM_POLYGON: - { - int nbrPolyTri = polyNodesNbr - 2; // split polygon into nbrPolyTri triangles - for (int iTri = 0; iTri < nbrPolyTri; ++iTri) - { - TriangleFaceKey key = TriangleFaceKey(polyNodes[0], polyNodes[1 + iTri], polyNodes[2 + iTri]); - if (_volumes.find(key) == _volumes.end()) - { - TransformedTriangle tri(_nodes[polyNodes[0]], _nodes[polyNodes[1 + iTri]], - _nodes[polyNodes[2 + iTri]]); - calculateSurface(tri, key); - totalSurface += _volumes[key]; - } - else - { - totalSurface -= _volumes[key]; - } - } - } - break; - - default: - std::cout - << "+++ Error : Only elements with triangular and quadratilateral faces are supported at the moment." - << std::endl; - assert(false); - } - - } - } - - // reset if it is very small to keep the matrix sparse - // is this a good idea? - if(epsilonEqual(totalSurface, 0.0, SPARSE_TRUNCATION_LIMIT)) - { - totalSurface = 0.0; - } - - LOG(2, "Volume = " << totalSurface << ", det= " << _t->determinant()); - - return totalSurface; - } - - /** - * Calculates the volume of intersection of this tetrahedron with another one. - */ - template - double SplitterTetra::intersectTetra(const double** tetraCorners) - { - //{ could be done on outside? - // check if we have planar tetra element - if(_t->determinant() == 0.0) - { - // tetra is planar - LOG(2, "Planar tetra -- volume 0"); - return 0.0; - } - - const unsigned nbOfNodes4Type=4; - // halfspace filtering - bool isOutside[8] = {true, true, true, true, true, true, true, true}; - bool isTargetOutside = false; - - // calculate the transformed coordinates of the nodes - double nodes[nbOfNodes4Type][3]; - for(int i = 0;i<(int)nbOfNodes4Type;++i) - { - _t->apply(nodes[i], tetraCorners[i]); - CheckIsOutside(nodes[i], isOutside); - } - - // halfspace filtering check - // NB : might not be beneficial for caching of triangles - for(int i = 0; i < 8; ++i) - { - if(isOutside[i]) - { - isTargetOutside = true; - } - } - - double totalVolume = 0.0; - - if(!isTargetOutside) - { - const CellModel& cellModelCell=CellModel::GetCellModel(NORM_TETRA4); - int cellNodes[4] = { 0, 1, 2, 3 }, faceNodes[3]; - - for(unsigned ii = 0 ; ii < 4 ; ++ii) - { - cellModelCell.fillSonCellNodalConnectivity(ii,cellNodes,faceNodes); - - TransformedTriangle tri(nodes[faceNodes[0]], nodes[faceNodes[1]], nodes[faceNodes[2]]); - double vol = tri.calculateIntersectionVolume(); - totalVolume += vol; - } - - // reset if it is very small to keep the matrix sparse - // is this a good idea? - if(epsilonEqual(totalVolume, 0.0, SPARSE_TRUNCATION_LIMIT)) - { - totalVolume = 0.0; - } - } - LOG(2, "Volume = " << totalVolume << ", det= " << _t->determinant()); - - // NB : fault in article, Grandy, [8] : it is the determinant of the inverse transformation - // that should be used (which is equivalent to dividing by the determinant) - return std::fabs(1.0 / _t->determinant() * totalVolume) ; - } - - //////////////////////////////////////////////////////// - - template - SplitterTetra2::SplitterTetra2(const MyMeshTypeT& targetMesh, const MyMeshTypeS& srcMesh, SplittingPolicy policy) - :_target_mesh(targetMesh),_src_mesh(srcMesh),_splitting_pol(policy) - { - } - - template - SplitterTetra2::~SplitterTetra2() - { - releaseArrays(); - } - - template - void SplitterTetra2::releaseArrays() - { - // free potential sub-mesh nodes that have been allocated - typename MyMeshTypeT::MyConnType nbOfNodesT = _node_ids.size();// Issue 0020634. - if((int)_nodes.size()>=/*8*/nbOfNodesT) - { - std::vector::iterator iter = _nodes.begin() + /*8*/nbOfNodesT; - while(iter != _nodes.end()) - { - delete[] *iter; - ++iter; - } - } - _nodes.clear(); - } - - /*! - * \param [in] targetCell in C mode. - * \param [out] tetra is the output result tetra containers. - */ - template - void SplitterTetra2::splitTargetCell2(typename MyMeshTypeT::MyConnType targetCell, typename std::vector< SplitterTetra* >& tetra) - { - const int *refConn(_target_mesh.getConnectivityPtr()); - const int *cellConn(refConn+_target_mesh.getConnectivityIndexPtr()[targetCell]); - INTERP_KERNEL::NormalizedCellType gt(_target_mesh.getTypeOfElement(targetCell)); - std::vector tetrasNodalConn; - std::vector addCoords; - const double *coords(_target_mesh.getCoordinatesPtr()); - SplitIntoTetras(_splitting_pol,gt,cellConn,refConn+_target_mesh.getConnectivityIndexPtr()[targetCell+1],coords,tetrasNodalConn,addCoords); - std::size_t nbTetras(tetrasNodalConn.size()/4); tetra.resize(nbTetras); - double tmp[12]; - int tmp2[4]; - for(std::size_t i=0;i=0) - { - tmp[j*3+0]=coords[3*cellId+0]; - tmp[j*3+1]=coords[3*cellId+1]; - tmp[j*3+2]=coords[3*cellId+2]; - } - else - { - tmp[j*3+0]=addCoords[3*(-cellId-1)+0]; - tmp[j*3+1]=addCoords[3*(-cellId-1)+1]; - tmp[j*3+2]=addCoords[3*(-cellId-1)+2]; - } - } - tetra[i]=new SplitterTetra(_src_mesh,tmp,tmp2); - } - } - - /*! - * @param targetCell in C mode. - * @param tetra is the output result tetra containers. - */ - template - void SplitterTetra2::splitTargetCell(typename MyMeshTypeT::MyConnType targetCell, - typename MyMeshTypeT::MyConnType nbOfNodesT, - typename std::vector< SplitterTetra* >& tetra) - { - typedef typename MyMeshTypeT::MyConnType ConnType; - const NumberingPolicy numPol=MyMeshTypeT::My_numPol; - const int numTetra = static_cast(_splitting_pol); - if(nbOfNodesT==4) - { - _nodes.resize(8); - _node_ids.resize(8); - tetra.reserve(1); - const double *nodes[4]; - int conn[4]; - for(int node = 0; node < 4 ; ++node) - { - nodes[node]=getCoordsOfNode2(node, OTT::indFC(targetCell),_target_mesh,conn[node]); - } - std::copy(conn,conn+4,_node_ids.begin()); - SplitterTetra* t = new SplitterTetra(_src_mesh, nodes,conn); - tetra.push_back(t); - return ; - } - // Issue 0020634. To pass nbOfNodesT to calculateSubNodes (don't want to add an arg) - _node_ids.resize(nbOfNodesT); - - // pre-calculate nodes - calculateSubNodes(_target_mesh, OTT::indFC(targetCell)); - - tetra.reserve(numTetra); - _nodes.reserve(30); // we never have more than this - - switch ( nbOfNodesT ) - { - case 8: - { - switch(_splitting_pol) - { - case PLANAR_FACE_5: - { - const int subZone[8] = { 0, 1, 2, 3, 4, 5, 6, 7 }; - fiveSplit(subZone,tetra); - } - break; - - case PLANAR_FACE_6: - { - const int subZone[8] = { 0, 1, 2, 3, 4, 5, 6, 7 }; - sixSplit(subZone,tetra); - } - break; - - case GENERAL_24: - { - calculateGeneral24Tetra(tetra); - } - break; - - case GENERAL_48: - { - calculateGeneral48Tetra(tetra); - } - break; - default: - assert(false); - } - break; - } - case 5: - { - splitPyram5(tetra); - break; - } - default: - { - splitConvex(targetCell, tetra); - } - } - } - - /** - * Splits the hexahedron into five tetrahedra. - * This method adds five SplitterTetra objects to the vector tetra. - * - * @param subZone the local node numbers corresponding to the hexahedron corners - these are mapped onto {0,..,7}. Providing this allows the - * splitting to be reused on the subzones of the GENERAL_* types of splitting - */ - template - void SplitterTetra2::fiveSplit(const int* const subZone, typename std::vector< SplitterTetra* >& tetra) - { - // create tetrahedra - for(int i = 0; i < 5; ++i) - { - const double* nodes[4]; - int conn[4]; - for(int j = 0; j < 4; ++j) - { - conn[j] = subZone[ SPLIT_NODES_5[4*i+j] ]; - nodes[j] = getCoordsOfSubNode(conn[j]); - } - SplitterTetra* t = new SplitterTetra(_src_mesh, nodes,conn); - tetra.push_back(t); - } - } - - /** - * Splits the hexahedron into six tetrahedra. - * This method adds six SplitterTetra objects to the vector tetra. - * - * @param subZone the local node numbers corresponding to the hexahedron corners - these are mapped onto {0,..,7}. Providing this allows the - * splitting to be reused on the subzones of the GENERAL_* types of splitting - */ - template - void SplitterTetra2::sixSplit(const int* const subZone, typename std::vector< SplitterTetra* >& tetra) - { - for(int i = 0; i < 6; ++i) - { - const double* nodes[4]; - int conn[4]; - for(int j = 0; j < 4; ++j) - { - conn[j] = subZone[SPLIT_NODES_6[4*i+j]]; - nodes[j] = getCoordsOfSubNode(conn[j]); - } - SplitterTetra* t = new SplitterTetra(_src_mesh, nodes,conn); - tetra.push_back(t); - } - } - - /** - * Splits the hexahedron into 24 tetrahedra. - * The splitting is done by combining the barycenter of the tetrahedron, the barycenter of each face - * and the nodes of each edge of the face. This creates 6 faces * 4 edges / face = 24 tetrahedra. - * The submesh nodes introduced are the barycenters of the faces and the barycenter of the cell. - * - */ - template - void SplitterTetra2::calculateGeneral24Tetra(typename std::vector< SplitterTetra* >& tetra) - { - // 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 - - // nodes to use for tetrahedron - const double* nodes[4]; - int conn[4]; - // get the cell center - conn[0] = 14; - nodes[0] = getCoordsOfSubNode(conn[0]); - - for(int faceCenterNode = 8; faceCenterNode < 14; ++faceCenterNode) - { - // get the face center - conn[1] = faceCenterNode; - nodes[1] = getCoordsOfSubNode(conn[1]); - for(int j = 0; j < 4; ++j) - { - const int row = 4*(faceCenterNode - 8) + j; - 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]); - - SplitterTetra* t = new SplitterTetra(_src_mesh, nodes, conn); - tetra.push_back(t); - } - } - } - - - /** - * Splits the hexahedron into 48 tetrahedra. - * The splitting is done by introducing the midpoints of all the edges - * and the barycenter of the element as submesh nodes. The 8 hexahedral subzones thus defined - * are then split into 6 tetrahedra each, as in Grandy, p. 449. The division of the subzones - * is done by calling sixSplit(). - * - */ - template - void SplitterTetra2::calculateGeneral48Tetra(typename std::vector< SplitterTetra* >& tetra) - { - for(int i = 0; i < 8; ++i) - { - sixSplit(GENERAL_48_SUBZONES+8*i,tetra); - } - } - - /** - * Splits the NORM_PYRA5 into 2 tetrahedra. - */ - template - void SplitterTetra2::splitPyram5(typename std::vector< SplitterTetra* >& tetra) - { - static const int SPLIT_PYPA5[2][4] = - { - { - 0, 1, 2, 4 - }, - { - 0, 2, 3, 4 - } - }; - - // create tetrahedra - const double* nodes[4]; - int conn[4]; - for(int i = 0; i < 2; ++i) - { - for(int j = 0; j < 4; ++j) - nodes[j] = getCoordsOfSubNode2(SPLIT_PYPA5[i][j],conn[j]); - SplitterTetra* t = new SplitterTetra(_src_mesh, nodes,conn); - tetra.push_back(t); - } - } - - /** - * Splits a convex cell into tetrahedra. - */ - template - void SplitterTetra2::splitConvex(typename MyMeshTypeT::MyConnType targetCell, - typename std::vector< SplitterTetra* >& tetra) - { - // Each face of a cell is split into triangles and - // each of triangles and a cell barycenter form a tetrahedron. - - typedef typename MyMeshTypeT::MyConnType ConnType; - const NumberingPolicy numPol=MyMeshTypeT::My_numPol; - - // get type of cell and nb of cell nodes - NormalizedCellType normCellType=_target_mesh.getTypeOfElement(OTT::indFC(targetCell)); - const CellModel& cellModelCell=CellModel::GetCellModel(normCellType); - unsigned nbOfCellNodes=cellModelCell.isDynamic() ? _target_mesh.getNumberOfNodesOfElement(OTT::indFC(targetCell)) : cellModelCell.getNumberOfNodes(); - - // get nb of cell sons (faces) - const ConnType* rawCellConn = _target_mesh.getConnectivityPtr() + OTT::conn2C( _target_mesh.getConnectivityIndexPtr()[ targetCell ]); - const int rawNbCellNodes = _target_mesh.getConnectivityIndexPtr()[ targetCell+1 ] - _target_mesh.getConnectivityIndexPtr()[ targetCell ]; - unsigned nbOfSons = cellModelCell.getNumberOfSons2(rawCellConn, rawNbCellNodes); - - // indices of nodes of a son - static std::vector allNodeIndices; // == 0,1,2,...,nbOfCellNodes-1 - while ( allNodeIndices.size() < nbOfCellNodes ) - allNodeIndices.push_back( allNodeIndices.size() ); - std::vector classicFaceNodes(4); - if(cellModelCell.isQuadratic()) - throw INTERP_KERNEL::Exception("SplitterTetra2::splitConvex : quadratic 3D cells are not implemented yet !"); - int* faceNodes = cellModelCell.isDynamic() ? &allNodeIndices[0] : &classicFaceNodes[0]; - - // nodes of tetrahedron - int conn[4]; - const double* nodes[4]; - nodes[3] = getCoordsOfSubNode2( nbOfCellNodes,conn[3]); // barycenter - - for(unsigned ii = 0 ; ii < nbOfSons; ++ii) - { - // get indices of son's nodes: it's just next portion of allNodeIndices for polyhedron - // and some of allNodeIndices accodring to cell model for a classsic cell - unsigned nbFaceNodes = cellModelCell.getNumberOfNodesConstituentTheSon2(ii, rawCellConn, rawNbCellNodes); - if ( normCellType != NORM_POLYHED ) - cellModelCell.fillSonCellNodalConnectivity(ii,&allNodeIndices[0],faceNodes); - - int nbTetra = nbFaceNodes - 2; // split polygon into nbTetra triangles - - // create tetrahedra - for(int i = 0; i < nbTetra; ++i) - { - nodes[0] = getCoordsOfSubNode2( faceNodes[0], conn[0]); - nodes[1] = getCoordsOfSubNode2( faceNodes[1+i],conn[1]); - nodes[2] = getCoordsOfSubNode2( faceNodes[2+i],conn[2]); - SplitterTetra* t = new SplitterTetra(_src_mesh, nodes,conn); - tetra.push_back(t); - } - - if ( normCellType == NORM_POLYHED ) - faceNodes += nbFaceNodes; // go to the next face - } - } - - /** - * Precalculates all the nodes. - * Retrieves the mesh nodes and allocates the necessary sub-mesh - * nodes according to the splitting policy used. - * This method is meant to be called once by the constructor. - * - * @param targetMesh the target mesh - * @param targetCell the global number of the cell that the object represents, in targetMesh mode. - * @param policy the splitting policy of the object - * - */ - template - void SplitterTetra2::calculateSubNodes(const MyMeshTypeT& targetMesh, typename MyMeshTypeT::MyConnType targetCell) - { - // retrieve real mesh nodes - - typename MyMeshTypeT::MyConnType nbOfNodesT = _node_ids.size();// Issue 0020634. _node_ids.resize(8); - for(int node = 0; node < nbOfNodesT ; ++node) - { - // calculate only normal nodes - _nodes.push_back(getCoordsOfNode2(node, targetCell, targetMesh,_node_ids[node])); - } - - switch ( nbOfNodesT ) - { - case 8: - - // create sub-mesh nodes if needed - switch(_splitting_pol) - { - case GENERAL_24: - { - for(int i = 0; i < 7; ++i) - { - double* barycenter = new double[3]; - calcBarycenter(4, barycenter, &GENERAL_24_SUB_NODES[4*i]); - _nodes.push_back(barycenter); - } - } - break; - - case GENERAL_48: - { - for(int i = 0; i < 19; ++i) - { - double* barycenter = new double[3]; - calcBarycenter(2, barycenter, &GENERAL_48_SUB_NODES[2*i]); - _nodes.push_back(barycenter); - } - } - break; - - default: - break; - } - - case 5: // NORM_PYRA5 - break; - - default: // convex 3d cell - { - // add barycenter of a cell - std::vector allIndices(nbOfNodesT); - for ( int i = 0; i < nbOfNodesT; ++i ) allIndices[i] = i; - double* barycenter = new double[3]; - calcBarycenter(nbOfNodesT, barycenter, &allIndices[0]); - _nodes.push_back(barycenter); - } - } - - } -} - -#endif diff --git a/src/INTERP_KERNEL/TargetIntersector.hxx b/src/INTERP_KERNEL/TargetIntersector.hxx deleted file mode 100644 index e79d1e747..000000000 --- a/src/INTERP_KERNEL/TargetIntersector.hxx +++ /dev/null @@ -1,55 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 -// 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 __TARGETINTERSECTOR__HXX__ -#define __TARGETINTERSECTOR__HXX__ - -#include "INTERPKERNELDefines.hxx" - -#include - -namespace INTERP_KERNEL -{ - /** - * \brief Abstract base class of Intersector classes. - * These classes represent a target element and calculate its intersection - * with the source elements. - */ - template - class TargetIntersector - { - public: - typedef typename MyMeshType::MyConnType ConnType; - public: - /*! - * Tool for cell intersection, result is always positive. - * @param icellT id of cell in target mesh in \b C \b mode. - * @param icellsS ids of cells in source mesh in \b C \b mode. - * @param res is an IN/OUT parameter that represents the icellTth row in final matrix, fed with at most icellsS elements. - */ - virtual void intersectCells(ConnType targetCell, const std::vector& srcCells, MyMatrix& res) = 0; - - virtual int getNumberOfRowsOfResMatrix() const = 0; - virtual int getNumberOfColsOfResMatrix() const = 0; - virtual ~TargetIntersector() { } - }; -} - -#endif diff --git a/src/INTERP_KERNEL/TetraAffineTransform.cxx b/src/INTERP_KERNEL/TetraAffineTransform.cxx deleted file mode 100644 index f01b160d6..000000000 --- a/src/INTERP_KERNEL/TetraAffineTransform.cxx +++ /dev/null @@ -1,393 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// - -#include "TetraAffineTransform.hxx" -#include "VectorUtils.hxx" - -#include -#include -#include - -#include "Log.hxx" - -namespace INTERP_KERNEL -{ - ///////////////////////////////////////////////////////////////////////////////////////// - /// PUBLIC INTERFACE METHODS ////////////// - ///////////////////////////////////////////////////////////////////////////////////////// - - /** - * Constructor - * Create the TetraAffineTransform object from the tetrahedron - * with corners specified in pts. If the tetrahedron is degenerate or almost degenerate, - * construction succeeds, but the determinant of the transform is set to 0. - * - * @param pts a 4x3 matrix containing 4 points (P0X,P0Y,P0Z,P1X,P1Y,P1Z,...) of 3 coordinates each - */ - TetraAffineTransform::TetraAffineTransform(const double *pts) - { - - LOG(2,"Creating transform from tetraeder : "); - - // three last points -> linear transform - for(int i = 0; i < 3 ; ++i) - { - for(int j = 0 ; j < 3 ; ++j) - { - // NB we insert columns, not rows - _linear_transform[3*j + i] = pts[(i+1)*3+j] - pts[j]; - } - } - - // remember _linear_transform for the reverse transformation - memcpy( _back_linear_transform, _linear_transform, 9*sizeof(double)); - memcpy( _back_translation, pts, 3*sizeof(double)); - - calculateDeterminant(); - - LOG(3, "determinant before inverse = " << _determinant); - - // check that tetra is non-planar -> determinant is not zero - // otherwise set _determinant to zero to signal caller that transformation did not work - if(epsilonEqual(_determinant, 0.0)) - { - _determinant = 0.0; - return; - } - - // we need the inverse transform - invertLinearTransform(); - - // first point -> translation - // calculate here because translation takes place in "transformed space", - // or in other words b = -A*O where A is the linear transform - // and O is the position vector of the point that is mapped onto the origin - for(int i = 0 ; i < 3 ; ++i) - { - _translation[i] = -(_linear_transform[3*i]*pts[0] + _linear_transform[3*i+1]*pts[1] + _linear_transform[3*i+2]*pts[2]) ; - } - - // precalculate determinant (again after inversion of transform) - calculateDeterminant(); - -#ifdef INVERSION_SELF_CHECK - // debugging : check that applying the inversed transform to the original points - // gives us the unit tetrahedron - LOG(4, "transform determinant is " << _determinant); - LOG(4, "*Self-check : Applying transformation to original points ... "); - for(int i = 0; i < 4 ; ++i) - { - double v[3]; - apply(v, pts+3*i); - LOG(4, vToStr(v)) - for(int j = 0; j < 3; ++j) - { - assert(epsilonEqual(v[j], (3*i+j == 3 || 3*i+j == 7 || 3*i+j == 11 ) ? 1.0 : 0.0)); - } - } - - LOG(4, " ok"); -#endif - } - - /** - * Calculates the transform of point srcPt and stores the result in destPt. - * If destPt == srcPt, then srcPt is overwritten safely. - * - * - * @param destPt double[3] in which to store the transformed point - * @param srcPt double[3] containing coordinates of points to be transformed - * - */ - void TetraAffineTransform::apply(double* destPt, const double* srcPt) const - { - double* dest = destPt; - - // are we self-allocating ? - const bool selfAllocation = (destPt == srcPt); - - if(selfAllocation) - { - // alloc temporary memory - dest = new double[3]; - - LOG(6, "Info : Self-affectation in TetraAffineTransform::apply"); - } - - for(int i = 0 ; i < 3 ; ++i) - { - // matrix - vector multiplication - dest[i] = _linear_transform[3*i] * srcPt[0] + _linear_transform[3*i + 1] * srcPt[1] + _linear_transform[3*i + 2] * srcPt[2]; - - // translation - dest[i] += _translation[i]; - } - - if(selfAllocation) - { - // copy result back to destPt - for(int i = 0 ; i < 3 ; ++i) - { - destPt[i] = dest[i]; - } - delete[] dest; - } - } - - /** - * Calculates the reverse transform of point srcPt and stores the result in destPt. - * If destPt == srcPt, then srcPt is overwritten safely. - * - * @param destPt double[3] in which to store the transformed point - * @param srcPt double[3] containing coordinates of points to be transformed - */ - void TetraAffineTransform::reverseApply(double* destPt, const double* srcPt) const - { - double* dest = destPt; - - // are we self-allocating ? - const bool selfAllocation = (destPt == srcPt); - - if(selfAllocation) - { - // alloc temporary memory - dest = new double[3]; - - LOG(6, "Info : Self-affectation in TetraAffineTransform::reverseApply"); - } - - for(int i = 0 ; i < 3 ; ++i) - { - // matrix - vector multiplication - dest[i] = _back_linear_transform[3*i] * srcPt[0] + _back_linear_transform[3*i + 1] * srcPt[1] + _back_linear_transform[3*i + 2] * srcPt[2]; - - // translation - dest[i] += _back_translation[i]; - } - - if(selfAllocation) - { - // copy result back to destPt - for(int i = 0 ; i < 3 ; ++i) - { - destPt[i] = dest[i]; - } - delete[] dest; - } - } - - /** - * Returns the determinant of the linear part A of the transform. - * - * @return determinant of the transform - * - */ - double TetraAffineTransform::determinant() const - { - return _determinant; - } - - /** - * Outputs to std::cout the matrix A and the vector b - * of the transform Ax + b - * - */ - void TetraAffineTransform::dump() const - { - std::cout << "A = " << std::endl << "["; - for(int i = 0; i < 3; ++i) - { - std::cout << _linear_transform[3*i] << ", " << _linear_transform[3*i + 1] << ", " << _linear_transform[3*i + 2]; - if(i != 2 ) std::cout << std::endl; - } - std::cout << "]" << std::endl; - - std::cout << "b = " << "[" << _translation[0] << ", " << _translation[1] << ", " << _translation[2] << "]" << std::endl; - } - - ///////////////////////////////////////////////////////////////////////////////////////// - /// PRIVATE METHODS ////////////// - ///////////////////////////////////////////////////////////////////////////////////////// - - /** - * Calculates the inverse of the matrix A, stored in _linear_transform - * by LU-factorization and substitution - * - */ - void TetraAffineTransform::invertLinearTransform() - { - //{ we copy the matrix for the lu-factorization - // maybe inefficient - double lu[9]; - for(int i = 0 ; i < 9; ++i) - { - lu[i] = _linear_transform[i]; - } - - // calculate LU factorization - int idx[3]; - factorizeLU(lu, idx); - - // calculate inverse by forward and backward substitution - // store in _linear_transform - // NB _linear_transform cannot be overwritten with lu in the loop - for(int i = 0 ; i < 3 ; ++i) - { - // form standard base vector i - const double b[3] = - { - double ( int(i == 0) ), - double ( int(i == 1) ), - double ( int(i == 2) ), - }; - - LOG(6, "b = [" << b[0] << ", " << b[1] << ", " << b[2] << "]"); - - double y[3]; - forwardSubstitution(y, lu, b, idx); - - double x[3]; - backwardSubstitution(x, lu, y, idx); - - // copy to _linear_transform matrix - // NB : this is a column operation, so we cannot - // do this directly when we calculate x - for(int j = 0 ; j < 3 ; j++) - { - _linear_transform[3*j + i] = x[idx[j]]; - } - } - } - - /** - * Updates the member _determinant of the matrix A of the transformation. - * - */ - void TetraAffineTransform::calculateDeterminant() - { - const double subDet[3] = - { - _linear_transform[4] * _linear_transform[8] - _linear_transform[5] * _linear_transform[7], - _linear_transform[3] * _linear_transform[8] - _linear_transform[5] * _linear_transform[6], - _linear_transform[3] * _linear_transform[7] - _linear_transform[4] * _linear_transform[6] - }; - - _determinant = _linear_transform[0] * subDet[0] - _linear_transform[1] * subDet[1] + _linear_transform[2] * subDet[2]; - } - - - ///////////////////////////////////////////////// - /// Auxiliary methods for inverse calculation /// - ///////////////////////////////////////////////// - - - /** - * Calculates the LU-factorization of the matrix A (_linear_transform) - * and stores it in lu. Since partial pivoting is used, there are - * row swaps. This is represented by the index permutation vector idx : to access element - * (i,j) of lu, use lu[3*idx[i] + j] - * - * @param lu double[9] in which to store LU-factorization - * @param idx int[3] in which to store row permutation vector - */ - void TetraAffineTransform::factorizeLU(double* lu, int* idx) const - { - // 3 x 3 LU factorization - // initialise idx - for(int i = 0 ; i < 3 ; ++i) - { - idx[i] = i; - } - - for(int k = 0; k < 2 ; ++k) - { - - // find pivot - int i = k; - double max = std::fabs(lu[3*idx[k] + k]); - int row = i; - while(i < 3) - { - if(std::fabs(lu[3*idx[i] + k]) > max) - { - max = fabs(lu[3*idx[i] + k]); - row = i; - } - ++i; - } - - // swap rows in index vector - int tmp = idx[k]; - idx[k] = idx[row]; - idx[row] = tmp; - - // calculate row - for(int j = k + 1 ; j < 3 ; ++j) - { - // l_jk = u_jk / u_kk - lu[3*idx[j] + k] /= lu[3*idx[k] + k]; - for(int s = k + 1; s < 3 ; ++s) - { - // case s = k will always become zero, and then be replaced by - // the l-value - // there's no need to calculate this explicitly - - // u_js = u_js - l_jk * u_ks - lu[3*idx[j] + s] -= lu[3*idx[j] + k] * lu[3*idx[k] + s] ; - } - } - } - } - - /** - * Solves the system Lx = b, where L is lower unit-triangular (ones on the diagonal) - * - * @param x double[3] in which the solution is stored - * @param lu double[9] containing the LU-factorization - * @param b double[3] containing the right-hand side - * @param idx int[3] containing the permutation vector associated with lu - * - */ - void TetraAffineTransform::forwardSubstitution(double* x, const double* lu, const double* b, const int* idx) const - { - // divisions are not carried out explicitly because lu does not store - // the diagonal values of L, which are all 1 - // Compare with backwardSubstitution() - x[idx[0]] = ( b[idx[0]] ); // / lu[3*idx[0]] - x[idx[1]] = ( b[idx[1]] - lu[3*idx[1]] * x[idx[0]] ); // / lu[3*idx[1] + 1]; - x[idx[2]] = ( b[idx[2]] - lu[3*idx[2]] * x[idx[0]] - lu[3*idx[2] + 1] * x[idx[1]] ); // / lu[3*idx[2] + 2]; - } - - /** - * Solves the system Ux = b, where U is upper-triangular - * - * @param x double[3] in which the solution is stored - * @param lu double[9] containing the LU-factorization - * @param b double[3] containing the right-hand side - * @param idx int[3] containing the permutation vector associated with lu - * - */ - void TetraAffineTransform::backwardSubstitution(double* x, const double* lu, const double* b, const int* idx) const - { - x[idx[2]] = ( b[idx[2]] ) / lu[3*idx[2] + 2]; - x[idx[1]] = ( b[idx[1]] - lu[3*idx[1] + 2] * x[idx[2]] ) / lu[3*idx[1] + 1]; - x[idx[0]] = ( b[idx[0]] - lu[3*idx[0] + 1] * x[idx[1]] - lu[3*idx[0] + 2] * x[idx[2]] ) / lu[3*idx[0]]; - } - -} diff --git a/src/INTERP_KERNEL/TetraAffineTransform.hxx b/src/INTERP_KERNEL/TetraAffineTransform.hxx deleted file mode 100644 index fcdb152db..000000000 --- a/src/INTERP_KERNEL/TetraAffineTransform.hxx +++ /dev/null @@ -1,81 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 -// 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 __TETRA_AFFINE_TRANSFORM_HXX__ -#define __TETRA_AFFINE_TRANSFORM_HXX__ - -#include "INTERPKERNELDefines.hxx" - -#undef INVERSION_SELF_CHECK // debugging : check that calculated inverse is correct - -namespace INTERP_KERNEL -{ - /** - * \brief Class representing an affine transformation x -> Ax + b that transforms a given tetrahedron - * into the unit tetrahedron. - * - */ - class INTERPKERNEL_EXPORT TetraAffineTransform - { - - public: - TetraAffineTransform(const double *pts); - - void apply(double* destPt, const double* srcPt) const; - - void reverseApply(double* destPt, const double* srcPt) const; - - double determinant() const; - - void dump() const; - - private: - - void invertLinearTransform(); - - void calculateDeterminant(); - - void factorizeLU(double* lu, int* idx) const; - - void forwardSubstitution(double* x, const double* lu, const double* b, const int* idx) const; - - void backwardSubstitution(double* x, const double* lu, const double* b, const int* idx) const; - - // The affine transformation Ax + b is represented with _linear_transformation containing the elements of - // A in row-first ordering and _translation containing the elements of b - - /// 3x3 matrix A in affine transform x -> Ax + b - double _linear_transform[9]; - - /// 3x1 vector b in affine transform x -> Ax + b - double _translation[3]; - - /// The determinant of the matrix A is calculated at the construction of the object and cached. - double _determinant; - - /// 3x3 matrix AT is transposed A matrix used for y -> ATy - c transformation - double _back_linear_transform[9]; - - /// 3x1 vector c in affine transform y -> ATy - c - double _back_translation[3]; - - }; -} - -#endif diff --git a/src/INTERP_KERNEL/TransformedTriangle.cxx b/src/INTERP_KERNEL/TransformedTriangle.cxx deleted file mode 100644 index 8b735cb46..000000000 --- a/src/INTERP_KERNEL/TransformedTriangle.cxx +++ /dev/null @@ -1,842 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// - -#include "TransformedTriangle.hxx" -#include "VectorUtils.hxx" -#include "TetraAffineTransform.hxx" -#include -#include -#include -#include -#include -#include -#include -#include - -namespace INTERP_KERNEL -{ - - /** - * \brief Class representing a circular order of a set of points around their barycenter. - * It is used with the STL sort() algorithm to sort the point of the two polygons - * - */ - class ProjectedCentralCircularSortOrder - { - public: - - /// Enumeration of different planes to project on when calculating order - enum CoordType { XY, XZ, YZ }; - - /** - * Constructor - * - * @param barycenter double[3] containing the barycenter of the points to be compared - * @param type plane to project on when comparing. The comparison will not work if all the points are in a plane perpendicular - * to the plane being projected on - */ - ProjectedCentralCircularSortOrder(const double* barycenter, const CoordType type) - : _aIdx((type == YZ) ? 1 : 0), - _bIdx((type == XY) ? 1 : 2), - _a(barycenter[_aIdx]), - _b(barycenter[_bIdx]) - { - } - - /** - * Comparison operator. - * Compares the relative position between two points in their ordering around the barycenter. - * - * @param pt1 a double[3] representing a point - * @param pt2 a double[3] representing a point - * @return true if the angle of the difference vector between pt1 and the barycenter is greater than that - * of the difference vector between pt2 and the barycenter. - */ - bool operator()(const double* pt1, const double* pt2) - { - // calculate angles with the axis - const double ang1 = atan2(pt1[_aIdx] - _a, pt1[_bIdx] - _b); - const double ang2 = atan2(pt2[_aIdx] - _a, pt2[_bIdx] - _b); - - return ang1 > ang2; - } - - private: - /// index corresponding to first coordinate of plane on which points are projected - const int _aIdx; - - /// index corresponding to second coordinate of plane on which points are projected - const int _bIdx; - - /// value of first projected coordinate of the barycenter - const double _a; - - /// value of second projected coordinate of the barycenter - const double _b; - }; - - // ---------------------------------------------------------------------------------- - // TransformedTriangle PUBLIC - // ---------------------------------------------------------------------------------- - - /** - * Constructor - * - * The coordinates are copied to the internal member variables - * - * @param p array of three doubles containing coordinates of P - * @param q array of three doubles containing coordinates of Q - * @param r array of three doubles containing coordinates of R - */ - TransformedTriangle::TransformedTriangle(double* p, double* q, double* r) - : _is_double_products_calculated(false), _is_triple_products_calculated(false), _volume(0) - { - - for(int i = 0 ; i < 3 ; ++i) - { - // xyz coordinates - _coords[5*P + i] = p[i]; - _coords[5*Q + i] = q[i]; - _coords[5*R + i] = r[i]; - } - - // h coordinate - - _coords[5*P + 3] = 1 - p[0] - p[1] - p[2]; - _coords[5*Q + 3] = 1 - q[0] - q[1] - q[2]; - _coords[5*R + 3] = 1 - r[0] - r[1] - r[2]; - - // H coordinate - _coords[5*P + 4] = 1 - p[0] - p[1]; - _coords[5*Q + 4] = 1 - q[0] - q[1]; - _coords[5*R + 4] = 1 - r[0] - r[1]; - - resetNearZeroCoordinates(); - - // initialise rest of data - preCalculateDoubleProducts(); - - preCalculateTriangleSurroundsEdge(); - - preCalculateTripleProducts(); - - } - - /** - * Destructor - * - * Deallocates the memory used to store the points of the polygons. - * This memory is allocated in calculateIntersectionAndProjectionPolygons(). - */ - TransformedTriangle::~TransformedTriangle() - { - // delete elements of polygons - for(std::vector::iterator it = _polygonA.begin() ; it != _polygonA.end() ; ++it) - { - delete[] *it; - } - for(std::vector::iterator it = _polygonB.begin() ; it != _polygonB.end() ; ++it) - { - delete[] *it; - } - } - - /** - * Calculates the volume of intersection between the triangle and the - * unit tetrahedron. - * - * @return volume of intersection of this triangle with unit tetrahedron, - * as described in Grandy - * - */ - double TransformedTriangle::calculateIntersectionVolume() - { - // check first that we are not below z - plane - if(isTriangleBelowTetraeder()) - { - LOG(2, " --- Triangle is below tetraeder - V = 0.0"); - return 0.0; - } - - // get the sign of the volume - equal to the sign of the z-component of the normal - // of the triangle, u_x * v_y - u_y * v_x, where u = q - p and v = r - p - // if it is zero, the triangle is perpendicular to the z - plane and so the volume is zero -// const double uv_xy[4] = -// { -// _coords[5*Q] - _coords[5*P], _coords[5*Q + 1] - _coords[5*P + 1], // u_x, u_y -// _coords[5*R] - _coords[5*P], _coords[5*R + 1] - _coords[5*P + 1] // v_x, v_y -// }; - -// double sign = uv_xy[0] * uv_xy[3] - uv_xy[1] * uv_xy[2]; - int sign = isTriangleInclinedToFacet( OXY ); - - if(sign == 0 ) - { - LOG(2, " --- Triangle is perpendicular to z-plane - V = 0.0"); - return _volume = 0.0; - } - - - // normalize sign - //sign = sign > 0.0 ? 1.0 : -1.0; - - LOG(2, "-- Calculating intersection polygons ... "); - calculateIntersectionAndProjectionPolygons(); - - double barycenter[3]; - - // calculate volume under A - double volA = 0.0; - if(_polygonA.size() > 2) - { - LOG(2, "---- Treating polygon A ... "); - calculatePolygonBarycenter(A, barycenter); - sortIntersectionPolygon(A, barycenter); - volA = calculateVolumeUnderPolygon(A, barycenter); - LOG(2, "Volume is " << sign * volA); - } - - double volB = 0.0; - // if triangle is not in h = 0 plane, calculate volume under B - if(_polygonB.size() > 2 && !isTriangleInPlaneOfFacet(XYZ)) - { - LOG(2, "---- Treating polygon B ... "); - - calculatePolygonBarycenter(B, barycenter); - sortIntersectionPolygon(B, barycenter); - volB = calculateVolumeUnderPolygon(B, barycenter); - LOG(2, "Volume is " << sign * volB); - } - - LOG(2, "volA + volB = " << sign * (volA + volB) << std::endl << "***********"); - - return _volume = sign * (volA + volB); - - } - - /** - * Calculates the volume of intersection between the triangle and the - * unit tetrahedron. - * - * @return volume of intersection of this triangle with unit tetrahedron, - * as described in Grandy - * - */ - double TransformedTriangle::calculateIntersectionSurface(TetraAffineTransform* tat) - { - // check first that we are not below z - plane - if(isTriangleBelowTetraeder()) - { - LOG(2, " --- Triangle is below tetraeder - V = 0.0"); - return 0.0; - } - - LOG(2, "-- Calculating intersection polygon ... "); - calculateIntersectionPolygon(); - - _volume = 0.; - if(_polygonA.size() > 2) { - double barycenter[3]; - calculatePolygonBarycenter(A, barycenter); - sortIntersectionPolygon(A, barycenter); - const std::size_t nbPoints = _polygonA.size(); - for(std::size_t i = 0 ; i < nbPoints ; ++i) - tat->reverseApply(_polygonA[i], _polygonA[i]); - _volume = calculateSurfacePolygon(); - } - - return _volume; - } - - // ---------------------------------------------------------------------------------- - // TransformedTriangle PRIVATE - // ---------------------------------------------------------------------------------- - - /** - * Calculates the intersection polygons A and B, performing the intersection tests - * and storing the corresponding points in the vectors _polygonA and _polygonB. - * - * @post _polygonA contains the intersection polygon A and _polygonB contains the - * intersection polygon B. - * - */ - void TransformedTriangle::calculateIntersectionAndProjectionPolygons() - { - assert(_polygonA.size() == 0); - assert(_polygonB.size() == 0); - // avoid reallocations in push_back() by pre-allocating enough memory - // we should never have more than 20 points - _polygonA.reserve(20); - _polygonB.reserve(20); - // -- surface intersections - // surface - edge - for(TetraEdge edge = OX ; edge <= ZX ; edge = TetraEdge(edge + 1)) - { - if(testSurfaceEdgeIntersection(edge)) - { - double* ptA = new double[3]; - calcIntersectionPtSurfaceEdge(edge, ptA); - _polygonA.push_back(ptA); - LOG(3,"Surface-edge : " << vToStr(ptA) << " added to A "); - if(edge >= XY) - { - double* ptB = new double[3]; - copyVector3(ptA, ptB); - _polygonB.push_back(ptB); - LOG(3,"Surface-edge : " << vToStr(ptB) << " added to B "); - } - - } - } - - // surface - ray - for(TetraCorner corner = X ; corner < NO_TET_CORNER ; corner = TetraCorner(corner + 1)) - { - if(testSurfaceRayIntersection(corner)) - { - double* ptB = new double[3]; - copyVector3(&COORDS_TET_CORNER[3 * corner], ptB); - _polygonB.push_back(ptB); - LOG(3,"Surface-ray : " << vToStr(ptB) << " added to B"); - } - } - - // -- segment intersections - for(TriSegment seg = PQ ; seg < NO_TRI_SEGMENT ; seg = TriSegment(seg + 1)) - { - - bool isZero[NO_DP]; - - // check beforehand which double-products are zero - for(DoubleProduct dp = C_YZ; dp < NO_DP; dp = DoubleProduct(dp + 1)) - { - isZero[dp] = (calcStableC(seg, dp) == 0.0); - } - - // segment - facet - for(TetraFacet facet = OYZ ; facet < NO_TET_FACET ; facet = TetraFacet(facet + 1)) - { - // is this test worth it? - const bool doTest = - !isZero[DP_FOR_SEG_FACET_INTERSECTION[3*facet]] && - !isZero[DP_FOR_SEG_FACET_INTERSECTION[3*facet + 1]] && - !isZero[DP_FOR_SEG_FACET_INTERSECTION[3*facet + 2]]; - - if(doTest && testSegmentFacetIntersection(seg, facet)) - { - double* ptA = new double[3]; - calcIntersectionPtSegmentFacet(seg, facet, ptA); - _polygonA.push_back(ptA); - LOG(3,"Segment-facet : " << vToStr(ptA) << " added to A"); - if(facet == XYZ) - { - double* ptB = new double[3]; - copyVector3(ptA, ptB); - _polygonB.push_back(ptB); - LOG(3,"Segment-facet : " << vToStr(ptB) << " added to B"); - } - - } - } - - // segment - edge - for(TetraEdge edge = OX ; edge <= ZX ; edge = TetraEdge(edge + 1)) - { - const DoubleProduct edge_dp = DoubleProduct(edge); - - if(isZero[edge_dp] && testSegmentEdgeIntersection(seg, edge)) - { - double* ptA = new double[3]; - calcIntersectionPtSegmentEdge(seg, edge, ptA); - _polygonA.push_back(ptA); - LOG(3,"Segment-edge : " << vToStr(ptA) << " added to A"); - if(edge >= XY) - { - double* ptB = new double[3]; - copyVector3(ptA, ptB); - _polygonB.push_back(ptB); - } - } - } - - // segment - corner - for(TetraCorner corner = O ; corner < NO_TET_CORNER ; corner = TetraCorner(corner + 1)) - { - const bool doTest = - isZero[DoubleProduct( EDGES_FOR_CORNER[3*corner] )] && - isZero[DoubleProduct( EDGES_FOR_CORNER[3*corner+1] )] && - isZero[DoubleProduct( EDGES_FOR_CORNER[3*corner+2] )]; - - if(doTest && testSegmentCornerIntersection(seg, corner)) - { - double* ptA = new double[3]; - copyVector3(&COORDS_TET_CORNER[3 * corner], ptA); - _polygonA.push_back(ptA); - LOG(3,"Segment-corner : " << vToStr(ptA) << " added to A"); - if(corner != O) - { - double* ptB = new double[3]; - _polygonB.push_back(ptB); - copyVector3(&COORDS_TET_CORNER[3 * corner], ptB); - LOG(3,"Segment-corner : " << vToStr(ptB) << " added to B"); - } - } - } - - // segment - ray - for(TetraCorner corner = X ; corner < NO_TET_CORNER ; corner = TetraCorner(corner + 1)) - { - if(isZero[DP_SEGMENT_RAY_INTERSECTION[7*(corner-1)]] && testSegmentRayIntersection(seg, corner)) - { - double* ptB = new double[3]; - copyVector3(&COORDS_TET_CORNER[3 * corner], ptB); - _polygonB.push_back(ptB); - LOG(3,"Segment-ray : " << vToStr(ptB) << " added to B"); - } - } - - // segment - halfstrip - for(TetraEdge edge = XY ; edge <= ZX ; edge = TetraEdge(edge + 1)) - { - -#if 0 - const int edgeIdx = int(edge) - 3; // offset since we only care for edges XY - ZX - const bool doTest = - !isZero[DP_FOR_HALFSTRIP_INTERSECTION[4*edgeIdx]] && - !isZero[DP_FOR_HALFSTRIP_INTERSECTION[4*edgeIdx+1]]; - - - if(doTest && testSegmentHalfstripIntersection(seg, edge)) -#endif - if(testSegmentHalfstripIntersection(seg, edge)) - { - double* ptB = new double[3]; - calcIntersectionPtSegmentHalfstrip(seg, edge, ptB); - _polygonB.push_back(ptB); - LOG(3,"Segment-halfstrip : " << vToStr(ptB) << " added to B"); - } - } - } - - // inclusion tests - for(TriCorner corner = P ; corner < NO_TRI_CORNER ; corner = TriCorner(corner + 1)) - { - // { XYZ - inclusion only possible if in Tetrahedron? - // tetrahedron - if(testCornerInTetrahedron(corner)) - { - double* ptA = new double[3]; - copyVector3(&_coords[5*corner], ptA); - _polygonA.push_back(ptA); - LOG(3,"Inclusion tetrahedron : " << vToStr(ptA) << " added to A"); - } - - // XYZ - plane - if(testCornerOnXYZFacet(corner)) - { - double* ptB = new double[3]; - copyVector3(&_coords[5*corner], ptB); - _polygonB.push_back(ptB); - LOG(3,"Inclusion XYZ-plane : " << vToStr(ptB) << " added to B"); - } - - // projection on XYZ - facet - if(testCornerAboveXYZFacet(corner)) - { - double* ptB = new double[3]; - copyVector3(&_coords[5*corner], ptB); - ptB[2] = 1 - ptB[0] - ptB[1]; - assert(epsilonEqual(ptB[0]+ptB[1]+ptB[2] - 1, 0.0)); - _polygonB.push_back(ptB); - LOG(3,"Projection XYZ-plane : " << vToStr(ptB) << " added to B"); - } - - } - - } - - /** - * Calculates the intersection polygon A, performing the intersection tests - * and storing the corresponding point in the vector _polygonA. - * - * @post _polygonA contains the intersection polygon A. - * - */ - void TransformedTriangle::calculateIntersectionPolygon() - { - assert(_polygonA.size() == 0); - // avoid reallocations in push_back() by pre-allocating enough memory - // we should never have more than 20 points - _polygonA.reserve(20); - // -- surface intersections - // surface - edge - for(TetraEdge edge = OX ; edge <= ZX ; edge = TetraEdge(edge + 1)) - { - if(testSurfaceEdgeIntersection(edge)) - { - double* ptA = new double[3]; - calcIntersectionPtSurfaceEdge(edge, ptA); - _polygonA.push_back(ptA); - LOG(3,"Surface-edge : " << vToStr(ptA) << " added to A "); - } - } - - // -- segment intersections - for(TriSegment seg = PQ ; seg < NO_TRI_SEGMENT ; seg = TriSegment(seg + 1)) - { - - bool isZero[NO_DP]; - - // check beforehand which double-products are zero - for(DoubleProduct dp = C_YZ; dp < NO_DP; dp = DoubleProduct(dp + 1)) - { - isZero[dp] = (calcStableC(seg, dp) == 0.0); - } - - // segment - facet - for(TetraFacet facet = OYZ ; facet < NO_TET_FACET ; facet = TetraFacet(facet + 1)) - { - // is this test worth it? - const bool doTest = - !isZero[DP_FOR_SEG_FACET_INTERSECTION[3*facet]] && - !isZero[DP_FOR_SEG_FACET_INTERSECTION[3*facet + 1]] && - !isZero[DP_FOR_SEG_FACET_INTERSECTION[3*facet + 2]]; - - if(doTest && testSegmentFacetIntersection(seg, facet)) - { - double* ptA = new double[3]; - calcIntersectionPtSegmentFacet(seg, facet, ptA); - _polygonA.push_back(ptA); - LOG(3,"Segment-facet : " << vToStr(ptA) << " added to A"); - } - } - - // segment - edge - for(TetraEdge edge = OX ; edge <= ZX ; edge = TetraEdge(edge + 1)) - { - const DoubleProduct edge_dp = DoubleProduct(edge); - - if(isZero[edge_dp] && testSegmentEdgeIntersection(seg, edge)) - { - double* ptA = new double[3]; - calcIntersectionPtSegmentEdge(seg, edge, ptA); - _polygonA.push_back(ptA); - LOG(3,"Segment-edge : " << vToStr(ptA) << " added to A"); - } - } - - // segment - corner - for(TetraCorner corner = O ; corner < NO_TET_CORNER ; corner = TetraCorner(corner + 1)) - { - const bool doTest = - isZero[DoubleProduct( EDGES_FOR_CORNER[3*corner] )] && - isZero[DoubleProduct( EDGES_FOR_CORNER[3*corner+1] )] && - isZero[DoubleProduct( EDGES_FOR_CORNER[3*corner+2] )]; - - if(doTest && testSegmentCornerIntersection(seg, corner)) - { - double* ptA = new double[3]; - copyVector3(&COORDS_TET_CORNER[3 * corner], ptA); - _polygonA.push_back(ptA); - LOG(3,"Segment-corner : " << vToStr(ptA) << " added to A"); - } - } - - } - - // inclusion tests - for(TriCorner corner = P ; corner < NO_TRI_CORNER ; corner = TriCorner(corner + 1)) - { - // { XYZ - inclusion only possible if in Tetrahedron? - // tetrahedron - if(testCornerInTetrahedron(corner)) - { - double* ptA = new double[3]; - copyVector3(&_coords[5*corner], ptA); - _polygonA.push_back(ptA); - LOG(3,"Inclusion tetrahedron : " << vToStr(ptA) << " added to A"); - } - - } - - } - - - /** - * Returns the surface of polygon A. - * - * @return the surface of polygon A. - */ - double TransformedTriangle::calculateSurfacePolygon() - { - const std::size_t nbPoints = _polygonA.size(); - double pdt[3]; - double sum[3] = {0., 0., 0.}; - - for(std::size_t i = 0 ; i < nbPoints ; ++i) - { - const double *const ptCurr = _polygonA[i]; // pt "i" - const double *const ptNext = _polygonA[(i + 1) % nbPoints]; // pt "i+1" (pt nbPoints == pt 0) - - cross(ptCurr, ptNext, pdt); - add(pdt, sum); - } - - const double surface = norm(sum) * 0.5; - LOG(2,"Surface is " << surface); - return surface; - } - - /** - * Calculates the barycenters of the given intersection polygon. - * - * @pre the intersection polygons have been calculated with calculateIntersectionAndProjectionPolygons() - * - * @param poly one of the two intersection polygons - * @param barycenter array of three doubles where barycenter is stored - * - */ - void TransformedTriangle::calculatePolygonBarycenter(const IntersectionPolygon poly, double* barycenter) - { - LOG(3,"--- Calculating polygon barycenter"); - - // get the polygon points - std::vector& polygon = (poly == A) ? _polygonA : _polygonB; - - // calculate barycenter - const std::size_t m = polygon.size(); - - for(int j = 0 ; j < 3 ; ++j) - { - barycenter[j] = 0.0; - } - - if(m != 0) - { - for(std::size_t i = 0 ; i < m ; ++i) - { - const double* pt = polygon[i]; - for(int j = 0 ; j < 3 ; ++j) - { - barycenter[j] += pt[j] / double(m); - } - } - } - LOG(3,"Barycenter is " << vToStr(barycenter)); - } - - /** - * Sorts the given intersection polygon in circular order around its barycenter. - * @pre the intersection polygons have been calculated with calculateIntersectionAndProjectionPolygons() - * @post the vertices in _polygonA and _polygonB are sorted in circular order around their - * respective barycenters - * - * @param poly one of the two intersection polygons - * @param barycenter array of three doubles with the coordinates of the barycenter - * - */ - void TransformedTriangle::sortIntersectionPolygon(const IntersectionPolygon poly, const double* barycenter) - { - LOG(3,"--- Sorting polygon ..."); - - using INTERP_KERNEL::ProjectedCentralCircularSortOrder; - typedef ProjectedCentralCircularSortOrder SortOrder; // change is only necessary here and in constructor - typedef SortOrder::CoordType CoordType; - - // get the polygon points - std::vector& polygon = (poly == A) ? _polygonA : _polygonB; - - if(polygon.size() == 0) - return; - - // determine type of sorting - CoordType type = SortOrder::XY; - if(poly == A && !isTriangleInclinedToFacet( OXY )) // B is on h = 0 plane -> ok - { - // NB : the following test is never true if we have eliminated the - // triangles parallel to x == 0 and y == 0 in calculateIntersectionVolume(). - // We keep the test here anyway, to avoid interdependency. - - // is triangle inclined to x == 0 ? - if(isTriangleInclinedToFacet(OZX)) - { - type = SortOrder::XZ; - } - else //if(isTriangleParallelToFacet(OYZ)) - { - type = SortOrder::YZ; - } - } - - // create order object - SortOrder order(barycenter, type); - - // sort vector with this object - // NB : do not change place of first object, with respect to which the order - // is defined - sort((polygon.begin()), polygon.end(), order); - - LOG(3,"Sorted polygon is "); - for(size_t i = 0 ; i < polygon.size() ; ++i) - { - LOG(3,vToStr(polygon[i])); - } - - } - - /** - * Calculates the volume between the given polygon and the z = 0 plane. - * - * @pre the intersection polygones have been calculated with calculateIntersectionAndProjectionPolygons(), - * and they have been sorted in circular order with sortIntersectionPolygons(void) - * - * @param poly one of the two intersection polygons - * @param barycenter array of three doubles with the coordinates of the barycenter - * @return the volume between the polygon and the z = 0 plane - * - */ - double TransformedTriangle::calculateVolumeUnderPolygon(IntersectionPolygon poly, const double* barycenter) - { - LOG(2,"--- Calculating volume under polygon"); - - // get the polygon points - std::vector& polygon = (poly == A) ? _polygonA : _polygonB; - - double vol = 0.0; - const std::size_t m = polygon.size(); - - for(std::size_t i = 0 ; i < m ; ++i) - { - const double* ptCurr = polygon[i]; // pt "i" - const double* ptNext = polygon[(i + 1) % m]; // pt "i+1" (pt m == pt 0) - - const double factor1 = ptCurr[2] + ptNext[2] + barycenter[2]; - const double factor2 = - ptCurr[0]*(ptNext[1] - barycenter[1]) - + ptNext[0]*(barycenter[1] - ptCurr[1]) - + barycenter[0]*(ptCurr[1] - ptNext[1]); - vol += (factor1 * factor2) / 6.0; - } - - LOG(2,"Abs. Volume is " << vol); - return vol; - } - - - //////////////////////////////////////////////////////////////////////////////////// - // Detection of (very) degenerate cases ///////////// - //////////////////////////////////////////////////////////////////////////////////// - - /** - * Checks if the triangle lies in the plane of a given facet - * - * @param facet one of the facets of the tetrahedron - * @return true if PQR lies in the plane of the facet, false if not - */ - bool TransformedTriangle::isTriangleInPlaneOfFacet(const TetraFacet facet) const - { - - // coordinate to check - const int coord = static_cast(facet); - - for(TriCorner c = P ; c < NO_TRI_CORNER ; c = TriCorner(c + 1)) - { - if(_coords[5*c + coord] != 0.0) - { - return false; - } - } - - return true; - } - - /** - * Checks if the triangle is parallel to the given facet - * - * @param facet one of the facets of the unit tetrahedron - * @return true if triangle is parallel to facet, false if not - */ - bool TransformedTriangle::isTriangleParallelToFacet(const TetraFacet facet) const - { - // coordinate to check - const int coord = static_cast(facet); - return (_coords[5*P + coord] == _coords[5*Q + coord]) && (_coords[5*P + coord] == _coords[5*R + coord]); - } - - /** - * Checks if the triangle is not perpedicular to the given facet - * - * @param facet one of the facets of the unit tetrahedron - * @return zero if the triangle is perpendicular to the facet, - * else 1 or -1 depending on the sign of cross product of facet edges - */ - int TransformedTriangle::isTriangleInclinedToFacet(const TetraFacet facet) const - { - // coordinate to check - const int coord = static_cast(facet); - const int ind1 = ( coord+1 ) % 3, ind2 = ( coord+2 ) % 3; - const double uv_xy[4] = - { - // u_x, u_y - _coords[5*Q+ind1] - _coords[5*P+ind1], _coords[5*Q+ind2] - _coords[5*P+ind2], - // v_x, v_y - _coords[5*R+ind1] - _coords[5*P+ind1], _coords[5*R+ind2] - _coords[5*P+ind2] - }; - - double sign = uv_xy[0] * uv_xy[3] - uv_xy[1] * uv_xy[2]; - if(epsilonEqual(sign, 0.)) - { - sign = 0.; - } - return (sign < 0.) ? -1 : (sign > 0.) ? 1 : 0; - } - - /** - * Determines whether the triangle is below the z-plane. - * - * @return true if the z-coordinate of the three corners of the triangle are all less than 0, false otherwise. - */ - bool TransformedTriangle::isTriangleBelowTetraeder() const - { - for(TriCorner c = P ; c < NO_TRI_CORNER ; c = TriCorner(c + 1)) - { - // check z-coords for all points - if(_coords[5*c + 2] >= 0.0) - { - return false; - } - } - return true; - } - - /** - * Prints the coordinates of the triangle to std::cout - * - */ - void TransformedTriangle::dumpCoords() const - { - std::cout << "Coords : "; - for(int i = 0 ; i < 3; ++i) - { - std::cout << vToStr(&_coords[5*i]) << ","; - } - std::cout << std::endl; - } - - } // NAMESPACE diff --git a/src/INTERP_KERNEL/TransformedTriangle.hxx b/src/INTERP_KERNEL/TransformedTriangle.hxx deleted file mode 100644 index 51433c9d2..000000000 --- a/src/INTERP_KERNEL/TransformedTriangle.hxx +++ /dev/null @@ -1,389 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 -// 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 __TRANSFORMED_TRIANGLE_HXX__ -#define __TRANSFORMED_TRIANGLE_HXX__ - -#include "INTERPKERNELDefines.hxx" - -#include - -// Levels : -// 1 - overview of algorithm + volume result -// 2 - algorithm detail -// 3 - intersection polygon results detail -// 4 - intersection polygon search detail -// higher -> misc. gory details of calculation - -#include "Log.hxx" - -#ifdef WIN32 -#pragma warning(disable:4251) -#endif - -namespace INTERP_TEST -{ - class TransformedTriangleTest; - class TransformedTriangleIntersectTest; -} - - -namespace INTERP_KERNEL -{ - class TetraAffineTransform; - - /** \class TransformedTriangle - * \brief Class representing one of the faces of the triangulated source polyhedron after having been transformed - * with the affine transform that takes the target tetrahedron to the unit tetrahedron. It contains the - * logic for calculating the volume of intersection between the triangle and the unit tetrahedron. - * - * \see TransformedTriangle.hxx - * - * Reference : J. Grandy, "Conservative Remapping and Region Overlays by Intersecting Arbitrary Polyhedra", - * Journal of Computational Physics (1999) - * - */ - - /** \file TransformedTriangle.hxx - * - * OVERVIEW of how the class works : (details can be found in the documentation of each method) - * - * Constructor : - * The constructor takes as arguments three pointers to double[3] vectors holding the transformed - * coordinates of the corners of the triangle. It copies their coordinates and then proceeds to pre-calculating certain - * entities used in the intersection calculation : the double products, triple products and the values of the function E - * (Grandy, [53]). - * - * calculateIntersectionVolume() : - * This is the only method in the public interface. It calculates the volume under the intersection polygons - * between the triangle and the unit tetrahedron, as described in Grandy, pp. 435-447. It does this by first calculating the - * intersection polygons A and B, with the method calculateIntersectionPolygons(). It then calculates the barycenter of each - * polygon in calculatePolygonBarycenter(), and sorts their points in a circular order around the barycenter in - * sortIntersecionPolygon(). The sorting is done with STL sort, using the order defined in the class - * ProjectedCentralCircularSortOrder. The volume under each polygon is then calculated with calculateVolumeUnderPolygon(), which - * implements formula [34] in Grandy. - * - * calculateIntersectionPolygons() : - * This method goes through all the possible ways in which the triangle can intersect the tetrahedron and tests for these - * types of intersections in accordance with the formulas described in Grandy. These tests are implemented in the test* - methods. - * The formulas in the article are stated for one case each only, while the calculation must take into account all cases. - * To this end, a number of tables, implemented as static const arrays of different types, are used. The tables - * mainly contain values of the different enumeration types described at the beginning of the class interface. For example, - * the formula Grandy gives for the segment-halfstrip intersection tests ([30]) is for use with the halfstrip above the zx edge. - * For the other two halfstrips (above the xy and yz edges), other double products are used, which - * are stored in the table DP_FOR_HALFSTRIP_INTERSECTION. This allows us to treat - * all the edges equally, avoiding switch() - statements. It is the careful choice of order of the enumeration types that makes this - * possible. Notably, there is a correspondance between the TetraEdge type and the DoubleProduct type (see Grandy, table III) that - * is used throughout the code, permitting statements such as DoubleProduct(some_edge) to work. - * When an intersection point has been detected it is calculated with a corresponding calc* - method in the cases where it - * is not known directly. It is then added to the polygon A and/or B as necessary. - * - * OPTIMIZE : - * If OPTIMIZE is defined, a large number of methods will be prefixed with inline and some optimizations concerning the tests - * with zero double products will be used. - */ - class INTERPKERNEL_EXPORT TransformedTriangle - { - - - public: - - friend class INTERP_TEST::TransformedTriangleTest; - friend class INTERP_TEST::TransformedTriangleIntersectTest; - /* - * Enumerations representing the different geometric elements of the unit tetrahedron - * and the triangle. The end element, NO_* gives the number of elements in the enumeration - * and can be used as end element in loops. - */ - - /// Corners of tetrahedron - enum TetraCorner { O = 0, X, Y, Z, NO_TET_CORNER }; - - /// Edges of tetrahedron - enum TetraEdge { OX = 0, OY, OZ, XY, YZ, ZX, H01, H10, NO_TET_EDGE }; - - /// Facets (faces) of tetrahedron - enum TetraFacet { OYZ = 0, OZX, OXY, XYZ, NO_TET_FACET }; - - /// Corners of triangle - enum TriCorner { P = 0, Q, R, NO_TRI_CORNER }; - - /// Segments (edges) of triangle - enum TriSegment { PQ = 0, QR, RP, NO_TRI_SEGMENT }; - - /// Intersection polygons - enum IntersectionPolygon{ A = 0, B, NO_INTERSECTION_POLYGONS }; - - /// Double products - /// NB : order corresponds to TetraEdges (Grandy, table III) - enum DoubleProduct { C_YZ = 0, C_ZX, C_XY, C_ZH, C_XH, C_YH, C_01, C_10, NO_DP }; - - TransformedTriangle(double* p, double* q, double* r); - ~TransformedTriangle(); - - double calculateIntersectionVolume(); - double calculateIntersectionSurface(TetraAffineTransform* tat); - - void dumpCoords() const; - - // Queries of member values used by UnitTetraIntersectionBary - - const double* getCorner(TriCorner corner) const { return _coords + 5*corner; } - - const std::vector& getPolygonA() const { return _polygonA; } - - double getVolume() const { return _volume; } - - protected: - - TransformedTriangle() { } - - // ---------------------------------------------------------------------------------- - // High-level methods called directly by calculateIntersectionVolume() - // ---------------------------------------------------------------------------------- - void calculateIntersectionAndProjectionPolygons(); - - void calculatePolygonBarycenter(const IntersectionPolygon poly, double* barycenter); - - void sortIntersectionPolygon(const IntersectionPolygon poly, const double* barycenter); - - double calculateVolumeUnderPolygon(IntersectionPolygon poly, const double* barycenter); - - // ---------------------------------------------------------------------------------- - // High-level methods called directly by calculateIntersectionSurface() - // ---------------------------------------------------------------------------------- - void calculateIntersectionPolygon(); - - double calculateSurfacePolygon(); - - // ---------------------------------------------------------------------------------- - // Detection of degenerate triangles - // ---------------------------------------------------------------------------------- - - bool isTriangleInPlaneOfFacet(const TetraFacet facet) const; - - bool isTriangleParallelToFacet(const TetraFacet facet) const; - - int isTriangleInclinedToFacet(const TetraFacet facet) const; - - bool isTriangleBelowTetraeder() const; - - // ---------------------------------------------------------------------------------- - // Intersection test methods and intersection point calculations - // ---------------------------------------------------------------------------------- - - inline bool testSurfaceEdgeIntersection(const TetraEdge edge) const; - - void calcIntersectionPtSurfaceEdge(const TetraEdge edge, double* pt) const; - - inline bool testSegmentFacetIntersection(const TriSegment seg, const TetraFacet facet) const; - - void calcIntersectionPtSegmentFacet(const TriSegment seg, const TetraFacet facet, double* pt) const; - - bool testSegmentEdgeIntersection(const TriSegment seg, const TetraEdge edge) const; - - void calcIntersectionPtSegmentEdge(const TriSegment seg, const TetraEdge edge, double* pt) const ; - - bool testSegmentCornerIntersection(const TriSegment seg, const TetraCorner corner) const ; - - inline bool testSurfaceRayIntersection(const TetraCorner corner) const; - - bool testSegmentHalfstripIntersection(const TriSegment seg, const TetraEdge edg); - - void calcIntersectionPtSegmentHalfstrip(const TriSegment seg, const TetraEdge edge, double* pt) const; - - bool testSegmentRayIntersection(const TriSegment seg, const TetraCorner corner) const; - - inline bool testCornerInTetrahedron(const TriCorner corner) const; - - inline bool testCornerOnXYZFacet(const TriCorner corner) const; - - inline bool testCornerAboveXYZFacet(const TriCorner corner) const; - - // ---------------------------------------------------------------------------------- - // Utility methods used in intersection tests - // ---------------------------------------------------------------------------------- - - bool testTriangleSurroundsEdge(const TetraEdge edge) const; - - inline bool testEdgeIntersectsTriangle(const TetraEdge edge) const; - - inline bool testFacetSurroundsSegment(const TriSegment seg, const TetraFacet facet) const; - - inline bool testSegmentIntersectsFacet(const TriSegment seg, const TetraFacet facet) const; - - bool testSegmentIntersectsHPlane(const TriSegment seg) const; - - bool testSurfaceAboveCorner(const TetraCorner corner) const; - - bool testTriangleSurroundsRay(const TetraCorner corner) const; - - // ---------------------------------------------------------------------------------- - // Double and triple product calculations - // ---------------------------------------------------------------------------------- - - void resetNearZeroCoordinates(); - - bool areDoubleProductsConsistent(const TriSegment seg) const; - - void preCalculateDoubleProducts(void); - - inline void resetDoubleProducts(const TriSegment seg, const TetraCorner corner); - - double calculateDistanceCornerSegment(const TetraCorner corner, const TriSegment seg) const; - - void preCalculateTripleProducts(void); - - double calculateAngleEdgeTriangle(const TetraEdge edge) const; - - inline double calcStableC(const TriSegment seg, const DoubleProduct dp) const; - - inline double calcStableT(const TetraCorner corner) const; - - inline double calcUnstableC(const TriSegment seg, const DoubleProduct dp) const; - - double calcTByDevelopingRow(const TetraCorner corner, const int row = 1, const bool project = false) const; - - // ---------------------------------------------------------------------------------- - // Member variables - // ---------------------------------------------------------------------------------- - protected: - - /// Array holding the coordinates of the triangle's three corners - /// order : - /// [ p_x, p_y, p_z, p_h, p_H, q_x, q_y, q_z, q_h, q_H, r_x, r_y, r_z, r_h, r_H ] - double _coords[15]; - - /// Flag showing whether the double products have been calculated yet - bool _is_double_products_calculated; - - /// Flag showing whether the triple products have been calculated yet - bool _is_triple_products_calculated; - - /// Array containing the 24 double products. - /// order : c^PQ_YZ, ... ,cPQ_10, ... c^QR_YZ, ... c^RP_YZ - /// following order in enumeration DoubleProduct - double _doubleProducts[24]; - - /// Array containing the 4 triple products. - /// order : t_O, t_X, t_Y, t_Z - double _tripleProducts[4]; - - /// Vector holding the points of the intersection polygon A. - /// these points are allocated in calculateIntersectionPolygons() and liberated in the destructor - std::vector _polygonA; - - /// Vector holding the points of the intersection polygon B. - /// These points are allocated in calculateIntersectionPolygons() and liberated in the destructor - std::vector _polygonB; - - /// Array holding the coordinates of the barycenter of the polygon A - /// This point is calculated in calculatePolygonBarycenter - double _barycenterA[3]; - - /// Array holding the coordinates of the barycenter of the polygon B - /// This point is calculated in calculatePolygonBarycenter - //double _barycenterB[3]; - - /// Array of flags indicating which of the four triple products have been correctly calculated. - /// Used for asserts in debug mode - bool _validTP[4]; - - /// calculated volume for use of UnitTetraIntersectionBary - double _volume; - - /** - * Calls TransformedTriangle::testTriangleSurroundsEdge for edges OX to ZX and stores the result in - * member variable array_triangleSurroundsEdgeCache. - * - */ - void preCalculateTriangleSurroundsEdge(); - - /// Array holding results of the test testTriangleSurroundsEdge() for all the edges. - /// These are calculated in preCalculateTriangleSurroundsEdge(). - bool _triangleSurroundsEdgeCache[NO_TET_EDGE]; - - // ---------------------------------------------------------------------------------- - // Constants - // ---------------------------------------------------------------------------------- - - // offsets : 0 -> x, 1 -> y, 2 -> z, 3 -> h, 4 -> H - // corresponds to order of double products in DoubleProduct - // so that offset[C_*] gives the right coordinate - static const int DP_OFFSET_1[8]; - static const int DP_OFFSET_2[8]; - - // the coordinates used in the expansion of triple products by a given row - // in constellation (corner, row-1) - // (0,1,2,3) <=> (x,y,z,h) - static const int COORDINATE_FOR_DETERMINANT_EXPANSION[12]; - - // contains the edge of the double product used when - // expanding the triple product determinant associated with each corner - // by a given row - static const DoubleProduct DP_FOR_DETERMINANT_EXPANSION[12]; - - // values used to decide how imprecise the double products - // should be to set them to 0.0 - static const long double MACH_EPS; // machine epsilon - static const long double MULT_PREC_F; // precision of multiplications (Grandy : f) - static const long double THRESHOLD_F; // threshold for zeroing (Grandy : F/f) - - static const double TRIPLE_PRODUCT_ANGLE_THRESHOLD; - - // correspondance facet - double product - // Grandy, table IV - static const DoubleProduct DP_FOR_SEG_FACET_INTERSECTION[12]; - - // signs associated with entries in DP_FOR_SEGMENT_FACET_INTERSECTION - static const double SIGN_FOR_SEG_FACET_INTERSECTION[12]; - - // coordinates of corners of tetrahedron - static const double COORDS_TET_CORNER[12]; - - // indices to use in tables DP_FOR_SEG_FACET_INTERSECTION and SIGN_FOR_SEG_FACET_INTERSECTION - // for the calculation of the coordinates (x,y,z) of the intersection points - // for Segment-Facet and Segment-Edge intersections - static const int DP_INDEX[12]; - - // correspondance edge - corners - static const TetraCorner CORNERS_FOR_EDGE[12]; - - // correspondance edge - facets - // facets shared by each edge - static const TetraFacet FACET_FOR_EDGE[12]; - - // correspondance edge - corners - static const TetraEdge EDGES_FOR_CORNER[12]; - - // double products used in segment-halfstrip test - static const DoubleProduct DP_FOR_HALFSTRIP_INTERSECTION[12]; - - // double products used in segment - ray test - static const DoubleProduct DP_SEGMENT_RAY_INTERSECTION[21]; - - }; - - // include definitions of inline methods - -#include "TransformedTriangleInline.hxx" -} - - -#endif diff --git a/src/INTERP_KERNEL/TransformedTriangleInline.hxx b/src/INTERP_KERNEL/TransformedTriangleInline.hxx deleted file mode 100644 index 3f473ec75..000000000 --- a/src/INTERP_KERNEL/TransformedTriangleInline.hxx +++ /dev/null @@ -1,284 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 -// 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 __TRANSFORMEDTRIANGLEINLINE_HXX__ -#define __TRANSFORMEDTRIANGLEINLINE_HXX__ - -// This file contains inline versions of some of the methods in the TransformedTriangle*.cxx files. -// It replaces those methods if OPTIMIZE is defined. -// NB : most of these methods have documentation in their corresponding .cxx - file. - -// ---------------------------------------------------------------------------------- -// Optimization methods. These are only defined and used if OPTIMIZE is defined. -// ----------------------------------------------------------------------------------- - - -inline void TransformedTriangle::preCalculateTriangleSurroundsEdge() -{ - for(TetraEdge edge = OX ; edge <= ZX ; edge = TetraEdge(edge + 1)) - { - _triangleSurroundsEdgeCache[edge] = testTriangleSurroundsEdge(edge); - } -} - - -// ---------------------------------------------------------------------------------- -// TransformedTriangle_math.cxx -// ---------------------------------------------------------------------------------- - -inline void TransformedTriangle::resetDoubleProducts(const TriSegment seg, const TetraCorner corner) -{ - // set the three corresponding double products to 0.0 - static const DoubleProduct DOUBLE_PRODUCTS[12] = - { - C_YZ, C_ZX, C_XY, // O - C_YZ, C_ZH, C_YH, // X - C_ZX, C_ZH, C_XH, // Y - C_XY, C_YH, C_XH // Z - }; - - for(int i = 0 ; i < 3 ; ++i) { - const DoubleProduct dp = DOUBLE_PRODUCTS[3*corner + i]; - - LOG(6, std::endl << "resetting inconsistent dp :" << dp << " for corner " << corner); - _doubleProducts[8*seg + dp] = 0.0; - }; -} - -inline double TransformedTriangle::calcStableC(const TriSegment seg, const DoubleProduct dp) const -{ - return _doubleProducts[8*seg + dp]; -} - -inline double TransformedTriangle::calcStableT(const TetraCorner corner) const -{ - // assert(_isTripleProductsCalculated); - // assert(_validTP[corner]); - return _tripleProducts[corner]; -} - -inline double TransformedTriangle::calcUnstableC(const TriSegment seg, const DoubleProduct dp) const -{ - - // find the points of the triangle - // 0 -> P, 1 -> Q, 2 -> R - const int pt1 = seg; - const int pt2 = (seg + 1) % 3; - - // find offsets - const int off1 = DP_OFFSET_1[dp]; - const int off2 = DP_OFFSET_2[dp]; - - return _coords[5*pt1 + off1] * _coords[5*pt2 + off2] - _coords[5*pt1 + off2] * _coords[5*pt2 + off1]; -} - -// ---------------------------------------------------------------------------------- -// TransformedTriangle_intersect.cxx -// ---------------------------------------------------------------------------------- -inline bool TransformedTriangle::testSurfaceEdgeIntersection(const TetraEdge edge) const -{ - return _triangleSurroundsEdgeCache[edge] && testEdgeIntersectsTriangle(edge); -} - -inline bool TransformedTriangle::testSegmentFacetIntersection(const TriSegment seg, const TetraFacet facet) const -{ - return testFacetSurroundsSegment(seg, facet) && testSegmentIntersectsFacet(seg, facet); -} - -inline bool TransformedTriangle::testSurfaceRayIntersection(const TetraCorner corner) const -{ - return testTriangleSurroundsRay( corner ) && testSurfaceAboveCorner( corner ); -} - -inline bool TransformedTriangle::testCornerInTetrahedron(const TriCorner corner) const -{ - const double pt[4] = - { - _coords[5*corner], // x - _coords[5*corner + 1], // y - _coords[5*corner + 2], // z - _coords[5*corner + 3] // z - }; - - for(int i = 0 ; i < 4 ; ++i) - { - if(pt[i] < 0.0 || pt[i] > 1.0) - { - return false; - } - } - return true; -} - -inline bool TransformedTriangle::testCornerOnXYZFacet(const TriCorner corner) const -{ -#if 0 - const double pt[4] = - { - _coords[5*corner], // x - _coords[5*corner + 1], // y - _coords[5*corner + 2], // z - _coords[5*corner + 3] // h - }; -#endif - const double* pt = &_coords[5*corner]; - - if(pt[3] != 0.0) - { - return false; - } - - for(int i = 0 ; i < 3 ; ++i) - { - if(pt[i] < 0.0 || pt[i] > 1.0) - { - return false; - } - } - return true; -} - -inline bool TransformedTriangle::testCornerAboveXYZFacet(const TriCorner corner) const -{ - const double x = _coords[5*corner]; - const double y = _coords[5*corner + 1]; - const double h = _coords[5*corner + 3]; - const double H = _coords[5*corner + 4]; - - return h < 0.0 && H >= 0.0 && x >= 0.0 && y >= 0.0; - -} - -inline bool TransformedTriangle::testEdgeIntersectsTriangle(const TetraEdge edge) const -{ - - // assert(edge < H01); - - // correspondance edge - triple products - // for edges OX, ..., ZX (Grandy, table III) - static const TetraCorner TRIPLE_PRODUCTS[12] = - { - X, O, // OX - Y, O, // OY - Z, O, // OZ - X, Y, // XY - Y, Z, // YZ - Z, X, // ZX - }; - - // Grandy, [16] - const double t1 = calcStableT(TRIPLE_PRODUCTS[2*edge]); - const double t2 = calcStableT(TRIPLE_PRODUCTS[2*edge + 1]); - - //? should equality with zero use epsilon? - LOG(5, "testEdgeIntersectsTriangle : t1 = " << t1 << " t2 = " << t2 ); - return (t1*t2 <= 0.0) && (t1 - t2 != 0.0); -} - -inline bool TransformedTriangle::testFacetSurroundsSegment(const TriSegment seg, const TetraFacet facet) const -{ -#if 0 - const double signs[3] = - { - SIGN_FOR_SEG_FACET_INTERSECTION[3*facet], - SIGN_FOR_SEG_FACET_INTERSECTION[3*facet + 1], - SIGN_FOR_SEG_FACET_INTERSECTION[3*facet + 2] - }; -#endif - - const double* signs = &SIGN_FOR_SEG_FACET_INTERSECTION[3*facet]; - const double c1 = signs[0]*calcStableC(seg, DP_FOR_SEG_FACET_INTERSECTION[3*facet]); - const double c2 = signs[1]*calcStableC(seg, DP_FOR_SEG_FACET_INTERSECTION[3*facet + 1]); - const double c3 = signs[2]*calcStableC(seg, DP_FOR_SEG_FACET_INTERSECTION[3*facet + 2]); - - return (c1*c3 > 0.0) && (c2*c3 > 0.0); -} - -inline bool TransformedTriangle::testSegmentIntersectsFacet(const TriSegment seg, const TetraFacet facet) const -{ - // use correspondance facet a = 0 <=> offset for coordinate a in _coords - // and also correspondance segment AB => corner A - const double coord1 = _coords[5*seg + facet]; - const double coord2 = _coords[5*( (seg + 1) % 3) + facet]; - - //? should we use epsilon-equality here in second test? - LOG(5, "coord1 : " << coord1 << " coord2 : " << coord2 ); - - return (coord1*coord2 <= 0.0) && (coord1 != coord2); -} - -inline bool TransformedTriangle::testSegmentIntersectsHPlane(const TriSegment seg) const -{ - // get the H - coordinates - const double coord1 = _coords[5*seg + 4]; - const double coord2 = _coords[5*( (seg + 1) % 3) + 4]; - //? should we use epsilon-equality here in second test? - LOG(5, "coord1 : " << coord1 << " coord2 : " << coord2 ); - - return (coord1*coord2 <= 0.0) && (coord1 != coord2); -} - -inline bool TransformedTriangle::testSurfaceAboveCorner(const TetraCorner corner) const -{ - // ? There seems to be an error in Grandy -> it should be C_XY instead of C_YZ in [28]. - // ? I haven't really figured out why, but it seems to work. - const double normal = calcStableC(PQ, C_XY) + calcStableC(QR, C_XY) + calcStableC(RP, C_XY); - - LOG(6, "surface above corner " << corner << " : " << "n = " << normal << ", t = [" << calcTByDevelopingRow(corner, 1, false) << ", " << calcTByDevelopingRow(corner, 2, false) << ", " << calcTByDevelopingRow(corner, 3, false) ); - LOG(6, "] - stable : " << calcStableT(corner) ); - - //? we don't care here if the triple product is "invalid", that is, the triangle does not surround one of the - // edges going out from the corner (Grandy [53]) - if(!_validTP[corner]) - { - return ( calcTByDevelopingRow(corner, 1, false) * normal ) >= 0.0; - } - else - { - return ( calcStableT(corner) * normal ) >= 0.0; - } -} - -inline bool TransformedTriangle::testTriangleSurroundsRay(const TetraCorner corner) const -{ - // assert(corner == X || corner == Y || corner == Z); - - // double products to use for the possible corners - static const DoubleProduct DP_FOR_RAY_INTERSECTION[4] = - { - DoubleProduct(0), // O - only here to fill out and make indices match - C_10, // X - C_01, // Y - C_XY // Z - }; - - const DoubleProduct dp = DP_FOR_RAY_INTERSECTION[corner]; - - const double cPQ = calcStableC(PQ, dp); - const double cQR = calcStableC(QR, dp); - const double cRP = calcStableC(RP, dp); - - //? NB here we have no correction for precision - is this good? - // Our authority Grandy says nothing - LOG(5, "dp in triSurrRay for corner " << corner << " = [" << cPQ << ", " << cQR << ", " << cRP << "]" ); - - return ( cPQ*cQR > 0.0 ) && ( cPQ*cRP > 0.0 ); - -} -#endif diff --git a/src/INTERP_KERNEL/TransformedTriangleIntersect.cxx b/src/INTERP_KERNEL/TransformedTriangleIntersect.cxx deleted file mode 100644 index fa4c8a535..000000000 --- a/src/INTERP_KERNEL/TransformedTriangleIntersect.cxx +++ /dev/null @@ -1,586 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// - -#include "TransformedTriangle.hxx" -#include -#include -#include -#include -#include "VectorUtils.hxx" - -namespace INTERP_KERNEL -{ - - // ---------------------------------------------------------------------------------- - // Correspondance tables describing all the variations of formulas. - // ---------------------------------------------------------------------------------- - - /// \brief Correspondance between facets and double products. - /// - /// This table encodes Grandy, table IV. Use 3*facet + {0,1,2} as index - const TransformedTriangle::DoubleProduct TransformedTriangle::DP_FOR_SEG_FACET_INTERSECTION[12] = - { - C_XH, C_XY, C_ZX, // OYZ - C_YH, C_YZ, C_XY, // OZX - C_ZH, C_ZX, C_YZ, // OXY - C_XH, C_YH, C_ZH // XYZ - }; - - /// \brief Signs associated with entries in DP_FOR_SEGMENT_FACET_INTERSECTION. - /// - /// This table encodes Grandy, table IV. Use 3*facet + {0,1,2} as index - const double TransformedTriangle::SIGN_FOR_SEG_FACET_INTERSECTION[12] = - { - 1.0, 1.0, -1.0, - 1.0, 1.0, -1.0, - 1.0, 1.0, -1.0, - 1.0, 1.0, 1.0 - }; - - /// \brief Coordinates of corners of tetrahedron. - /// - /// Use 3*Corner + coordinate as index - const double TransformedTriangle::COORDS_TET_CORNER[12] = - { - 0.0, 0.0, 0.0, - 1.0, 0.0, 0.0, - 0.0, 1.0, 0.0, - 0.0, 0.0, 1.0 - }; - - /// \brief Indices to use in tables DP_FOR_SEG_FACET_INTERSECTION and SIGN_FOR_SEG_FACET_INTERSECTION - /// for the calculation of the coordinates (x,y,z) of the intersection points - /// for Segment-Facet and Segment-Edge intersections. - /// - /// Use 3*facet + coordinate as index. -1 indicates that the coordinate is 0. - const int TransformedTriangle::DP_INDEX[12] = - { - // x, y, z - -1, 1, 2, // OYZ - 5, -1, 4, // OZX - 7, 8, -1, // OXY - 9, 10, 11 // XYZ - }; - - /// \brief Correspondance edge - corners. - /// - /// Gives the two corners associated with each edge - /// Use 2*edge + {0, 1} as index - const TransformedTriangle::TetraCorner TransformedTriangle::CORNERS_FOR_EDGE[12] = - { - O, X, // OX - O, Y, // OY - O, Z, // OZ - X, Y, // XY - Y, Z, // YZ - Z, X // ZX - }; - - /// \brief Correspondance edge - facets. - /// - /// Gives the two facets shared by and edge. Use 2*facet + {0, 1} as index - const TransformedTriangle::TetraFacet TransformedTriangle::FACET_FOR_EDGE[12] = - { - OXY, OZX, // OX - OXY, OYZ, // OY - OZX, OYZ, // OZ - OXY, XYZ, // XY - OYZ, XYZ, // YZ - OZX, XYZ // ZX - }; - - /// \brief Correspondance corners - edges. - /// - /// Gives edges meeting at a given corner. Use 3*corner + {0,1,2} as index - const TransformedTriangle::TetraEdge TransformedTriangle::EDGES_FOR_CORNER[12] = - { - OX, OY, OZ, // O - OX, XY, ZX, // X - OY, XY, YZ, // Y - OZ, ZX, YZ // Z - }; - - /// \brief Double products to use in halfstrip intersection tests. - /// - /// Use 4*(offset_edge) + {0,1,2,3} as index. offset_edge = edge - 3 (so that XY -> 0, YZ -> 1, ZX -> 2) - /// Entries with offset 0 and 1 are for the first condition (positive product) - /// and those with offset 2 and 3 are for the second condition (negative product). - const TransformedTriangle::DoubleProduct TransformedTriangle::DP_FOR_HALFSTRIP_INTERSECTION[12] = - { - C_10, C_01, C_ZH, C_10, // XY - C_01, C_XY, C_XH, C_01, // YZ - C_XY, C_10, C_YH, C_XY // ZX - }; - - /// \brief Double products to use in segment-ray test. - /// - /// Use 7*corner_offset + {0,1,2,3,4,5,6} as index. corner_offset = corner - 1 (so that X -> 0, Y-> 1, Z->2) - /// Entries with offset 0 are for first condition (zero double product) and the rest are for condition 3 (in the same - /// order as in the article) - const TransformedTriangle::DoubleProduct TransformedTriangle::DP_SEGMENT_RAY_INTERSECTION[21] = - { - C_10, C_YH, C_ZH, C_01, C_XY, C_YH, C_XY, // X - C_01, C_XH, C_ZH, C_XY, C_10, C_ZH, C_10, // Y - C_XY, C_YH, C_XH, C_10, C_01, C_XH, C_01 // Z - }; - - /** - * Calculates the point of intersection between the given edge of the tetrahedron and the - * triangle PQR. (Grandy, eq [22]) - * - * @pre testSurfaceEdgeIntersection(edge) returns true - * @param edge edge of tetrahedron - * @param pt array of three doubles in which to store the coordinates of the intersection point - */ - void TransformedTriangle::calcIntersectionPtSurfaceEdge(const TetraEdge edge, double* pt) const - { - assert(edge < H01); - - // barycentric interpolation between points A and B - // : (x,y,z)* = (1-alpha)*A + alpha*B where - // alpha = t_A / (t_A - t_B) - - const TetraCorner corners[2] = - { - CORNERS_FOR_EDGE[2*edge], - CORNERS_FOR_EDGE[2*edge + 1] - }; - - // calculate alpha - const double tA = calcStableT(corners[0]); - const double tB = calcStableT(corners[1]); - const double alpha = tA / (tA - tB); - - // calculate point - LOG(4, "corner A = " << corners[0] << " corner B = " << corners[1] ); - LOG(4, "tA = " << tA << " tB = " << tB << " alpha= " << alpha ); - for(int i = 0; i < 3; ++i) - { - - pt[i] = (1 - alpha) * COORDS_TET_CORNER[3*corners[0] + i] + - alpha * COORDS_TET_CORNER[3*corners[1] + i]; -#if 0 - pt[i] = (1 - alpha) * getCoordinateForTetCorner() + - alpha * getCoordinateForTetCorner(); -#endif - LOG(6, pt[i] ); - assert(pt[i] >= 0.0); - assert(pt[i] <= 1.0); - } - } - - /** - * Calculates the point of intersection between the given segment of the triangle - * and the given facet of the tetrahedron. (Grandy, eq. [23]) - * - * @pre testSurfaceEdgeIntersection(seg, facet) returns true - * - * @param seg segment of the triangle - * @param facet facet of the tetrahedron - * @param pt array of three doubles in which to store the coordinates of the intersection point - */ - void TransformedTriangle::calcIntersectionPtSegmentFacet(const TriSegment seg, const TetraFacet facet, double* pt) const - { - // calculate s - double s = 0.0; - for(int i = 0; i < 3; ++i) - { - const DoubleProduct dp = DP_FOR_SEG_FACET_INTERSECTION[3*facet + i]; - const double sign = SIGN_FOR_SEG_FACET_INTERSECTION[3*facet + i]; - s -= sign * calcStableC(seg, dp); - } - - assert(s != 0.0); - - // calculate coordinates of intersection point - for(int i = 0 ; i < 3; ++i) - { - const int dpIdx = DP_INDEX[3*facet + i]; - - if(dpIdx < 0) - { - pt[i] = 0.0; - } - else - { - const DoubleProduct dp = DP_FOR_SEG_FACET_INTERSECTION[dpIdx]; - const double sign = SIGN_FOR_SEG_FACET_INTERSECTION[dpIdx]; - pt[i] = -( sign * calcStableC(seg, dp) ) / s; - - LOG(4, "SegmentFacetIntPtCalc : pt[" << i << "] = " << pt[i] ); - LOG(4, "c(" << seg << ", " << dp << ") = " << sign * calcStableC(seg, dp) ); - assert(pt[i] >= 0.0); - assert(pt[i] <= 1.0); - } - } - - } - - /** - * Tests if the given segment of the triangle intersects the given edge of the tetrahedron (Grandy, eq. [20] - * If the OPTIMIZE is defined, it does not do the test the double product that should be zero. - * @param seg segment of the triangle - * @param edge edge of tetrahedron - * @return true if the segment intersects the edge - */ - bool TransformedTriangle::testSegmentEdgeIntersection(const TriSegment seg, const TetraEdge edge) const - { - { - // check condition that the double products for one of the two - // facets adjacent to the edge has a positive product - bool isFacetCondVerified = false; - TetraFacet facet[2]; - for(int i = 0 ; i < 2 ; ++i) - { - facet[i] = FACET_FOR_EDGE[2*edge + i]; - - // find the two c-values -> the two for the other edges of the facet - int idx1 = 0 ; - int idx2 = 1; - DoubleProduct dp1 = DP_FOR_SEG_FACET_INTERSECTION[3*facet[i] + idx1]; - DoubleProduct dp2 = DP_FOR_SEG_FACET_INTERSECTION[3*facet[i] + idx2]; - - if(dp1 == DoubleProduct( edge )) - { - idx1 = 2; - dp1 = DP_FOR_SEG_FACET_INTERSECTION[3*facet[i] + idx1]; - } - else if(dp2 == DoubleProduct( edge )) - { - idx2 = 2; - dp2 = DP_FOR_SEG_FACET_INTERSECTION[3*facet[i] + idx2]; - } - - const double c1 = SIGN_FOR_SEG_FACET_INTERSECTION[3*facet[i] + idx1]*calcStableC(seg, dp1); - const double c2 = SIGN_FOR_SEG_FACET_INTERSECTION[3*facet[i] + idx2]*calcStableC(seg, dp2); - - //isFacetCondVerified = isFacetCondVerified || c1*c2 > 0.0; - if(c1*c2 > 0.0) - { - isFacetCondVerified = true; - } - } - - if(!isFacetCondVerified) - { - return false; - } - else - { - return testSegmentIntersectsFacet(seg, facet[0]) || testSegmentIntersectsFacet(seg, facet[1]); - } - } - } - - /** - * Calculates the point of intersection between the given segment of the triangle - * and the given edge of the tetrahedron. (Grandy, eq. [25]) - * - * @pre testSegmentEdgeIntersection(seg, edge) returns true - * - * @param seg segment of the triangle - * @param edge edge of the tetrahedron - * @param pt array of three doubles in which to store the coordinates of the intersection point - */ - void TransformedTriangle::calcIntersectionPtSegmentEdge(const TriSegment seg, const TetraEdge edge, double* pt) const - { - assert(edge < H01); - - // get the two facets associated with the edge - static const TetraFacet FACETS_FOR_EDGE[12] = - { - OXY, OZX, // OX - OXY, OYZ, // OY - OZX, OYZ, // OZ - OXY, XYZ, // XY - OYZ, XYZ, // YZ - OZX, XYZ // ZX - }; - - const TetraFacet facets[2] = - { - FACETS_FOR_EDGE[2*edge], - FACETS_FOR_EDGE[2*edge + 1] - }; - - // calculate s for the two edges - double s[2]; - for(int i = 0; i < 2; ++i) - { - s[i] = 0.0; - for(int j = 0; j < 3; ++j) - { - const DoubleProduct dp = DP_FOR_SEG_FACET_INTERSECTION[3*facets[i] + j]; - const double sign = SIGN_FOR_SEG_FACET_INTERSECTION[3*facets[i] + j]; - s[i] += sign * calcStableC(seg, dp); - } - } - - // calculate denominator - const double denominator = s[0]*s[0] + s[1]*s[1]; - - // calculate intersection point - for(int i = 0; i < 3; ++i) - { - // calculate double product values for the two faces - double c[2]; - for(int j = 0 ; j < 2; ++j) - { - const int dpIdx = DP_INDEX[3*facets[j] + i]; - const DoubleProduct dp = DP_FOR_SEG_FACET_INTERSECTION[dpIdx]; - const double sign = SIGN_FOR_SEG_FACET_INTERSECTION[dpIdx]; - c[j] = dpIdx < 0.0 ? 0.0 : sign * calcStableC(seg, dp); - } - - // pt[i] = (c1*s1 + c2*s2) / (s1^2 + s2^2) - - pt[i] = (c[0] * s[0] + c[1] * s[1]) / denominator; - - // strange bug with -O2 enabled : assertion fails when we don't have the following - // trace - line - //std::cout << "pt[i] = " << pt[i] << std::endl; - //assert(pt[i] >= 0.0); // check we are in tetraeder - //assert(pt[i] <= 1.0); - - } - } - - - /** - * Tests if the given segment of the triangle intersects the given corner of the tetrahedron. - * (Grandy, eq. [21]). If OPTIMIZE is defined, the double products that should be zero are not verified. - * - * @param seg segment of the triangle - * @param corner corner of the tetrahedron - * @return true if the segment intersects the corner - */ - bool TransformedTriangle::testSegmentCornerIntersection(const TriSegment seg, const TetraCorner corner) const - { - - - // facets meeting at a given corner - static const TetraFacet FACETS_FOR_CORNER[12] = - { - OXY, OYZ, OZX, // O - OZX, OXY, XYZ, // X - OYZ, XYZ, OXY, // Y - OZX, XYZ, OYZ // Z - }; - - // check segment intersect a facet - for(int i = 0 ; i < 3 ; ++i) - { - const TetraFacet facet = FACETS_FOR_CORNER[3*corner + i]; - if(testSegmentIntersectsFacet(seg, facet)) - { - return true; - } - } - - return false; - } - - /** - * Tests if the given segment of the triangle intersects the half-strip above the - * given edge of the h = 0 plane. (Grandy, eq. [30]) - * - * @param seg segment of the triangle - * @param edge edge of the h = 0 plane of the tetrahedron (XY, YZ, ZX) - * @return true if the upwards ray from the corner intersects the triangle. - */ - bool TransformedTriangle::testSegmentHalfstripIntersection(const TriSegment seg, const TetraEdge edge) - { - // get right index here to avoid "filling out" array - const int edgeIndex = static_cast(edge) - 3; - - // double products used in test - // products 1 and 2 for each edge -> first condition in Grandy [30] - // products 3 and 4 for each edge -> third condition - // NB : some uncertainty whether these last are correct - // DP_FOR_HALFSTRIP_INTERSECTION - - // facets to use in second condition (S_m) - static const TetraFacet FACET_FOR_HALFSTRIP_INTERSECTION[3] = - { - NO_TET_FACET, // XY -> special case : test with plane H = 0 - OYZ, // YZ - OZX // ZX - }; - - const double cVals[4] = - { - calcStableC(seg, DP_FOR_HALFSTRIP_INTERSECTION[4*edgeIndex]), - calcStableC(seg, DP_FOR_HALFSTRIP_INTERSECTION[4*edgeIndex + 1]), - calcStableC(seg, DP_FOR_HALFSTRIP_INTERSECTION[4*edgeIndex + 2]), - calcStableC(seg, DP_FOR_HALFSTRIP_INTERSECTION[4*edgeIndex + 3]) - }; - - const TetraFacet facet = FACET_FOR_HALFSTRIP_INTERSECTION[edgeIndex]; - - - // special case : facet H = 0 - const bool cond2 = (facet == NO_TET_FACET) ? testSegmentIntersectsHPlane(seg) : testSegmentIntersectsFacet(seg, facet); - LOG(4, "Halfstrip tests (" << seg << ", " << edge << ") : " << (cVals[0]*cVals[1] < 0.0) << ", " << cond2 << ", " << (cVals[2]*cVals[3] > 0.0) ); - LOG(4, "c2 = " << cVals[2] << ", c3 = " << cVals[3] ); - - return (cVals[0]*cVals[1] < 0.0) && cond2 && (cVals[2]*cVals[3] > 0.0); - } - - /** - * Calculates the point of intersection between the given segment of the triangle - * and the halfstrip above the given edge of the tetrahedron. (Grandy, eq. [31]) - * - * @pre testSegmentHalfstripIntersection(seg, edge) returns true - * - * @param seg segment of the triangle - * @param edge edge of the tetrahedron defining the halfstrip - * @param pt array of three doubles in which to store the coordinates of the intersection point - */ - void TransformedTriangle::calcIntersectionPtSegmentHalfstrip(const TriSegment seg, const TetraEdge edge, double* pt) const - { - assert(edge > OZ); - assert(edge < H01); - - // get right index here to avoid "filling out" array - const int edgeIndex = static_cast(edge) - 3; - assert(edgeIndex >= 0); - assert(edgeIndex < 3); - - // Barycentric interpolation on the edge - // for edge AB : (x,y,z)* = (1-alpha) * A + alpha * B - // where alpha = cB / (cB - cA) - - const double cA = calcStableC(seg, DP_FOR_HALFSTRIP_INTERSECTION[4*edgeIndex]); - const double cB = calcStableC(seg, DP_FOR_HALFSTRIP_INTERSECTION[4*edgeIndex + 1]); - assert(cA != cB); - - const double alpha = cA / (cA - cB); - - for(int i = 0; i < 3; ++i) - { - const TetraCorner corners[2] = - { - CORNERS_FOR_EDGE[2*edge], - CORNERS_FOR_EDGE[2*edge + 1] - }; - - const double cornerCoords[2] = - { - COORDS_TET_CORNER[3*corners[0] + i], - COORDS_TET_CORNER[3*corners[1] + i] - }; - - pt[i] = (1 - alpha) * cornerCoords[0] + alpha * cornerCoords[1]; - LOG(6, pt[i] ); - assert(pt[i] >= 0.0); - assert(pt[i] <= 1.0); - } - assert(epsilonEqualRelative(pt[0] + pt[1] + pt[2], 1.0)); - } - - /** - * Tests if the given segment of triangle PQR intersects the ray pointing - * in the upwards z - direction from the given corner of the tetrahedron. (Grandy eq. [29]) - * If OPTIMIZE is defined, the double product that should be zero is not verified. - * - * @param seg segment of the triangle PQR - * @param corner corner of the tetrahedron on the h = 0 facet (X, Y, or Z) - * @return true if the upwards ray from the corner intersects the segment. - */ - bool TransformedTriangle::testSegmentRayIntersection(const TriSegment seg, const TetraCorner corner) const - { - assert(corner == X || corner == Y || corner == Z); - LOG(4, "Testing seg - ray intersection for seg = " << seg << ", corner = " << corner ); - - // readjust index since O is not used - const int cornerIdx = static_cast(corner) - 1; - - // facets to use - //? not sure this is correct - static const TetraFacet FIRST_FACET_SEGMENT_RAY_INTERSECTION[3] = - { - OZX, // X - OYZ, // Y - OZX, // Z - }; - - // cond 2 - const bool cond21 = testSegmentIntersectsFacet(seg, FIRST_FACET_SEGMENT_RAY_INTERSECTION[cornerIdx]); - const bool cond22 = (corner == Z) ? testSegmentIntersectsFacet(seg, OYZ) : testSegmentIntersectsHPlane(seg); - - if(!(cond21 || cond22)) - { - LOG(4, "SR fails at cond 2 : cond21 = " << cond21 << ", cond22 = " << cond22 ); - return false; - } - - // cond 3 - const double cVals[6] = - { - calcStableC(seg, DP_SEGMENT_RAY_INTERSECTION[7*cornerIdx + 1]), - calcStableC(seg, DP_SEGMENT_RAY_INTERSECTION[7*cornerIdx + 2]), - calcStableC(seg, DP_SEGMENT_RAY_INTERSECTION[7*cornerIdx + 3]), - calcStableC(seg, DP_SEGMENT_RAY_INTERSECTION[7*cornerIdx + 4]), - calcStableC(seg, DP_SEGMENT_RAY_INTERSECTION[7*cornerIdx + 5]), - calcStableC(seg, DP_SEGMENT_RAY_INTERSECTION[7*cornerIdx + 6]), - }; - - // cond. 3 - if(( (cVals[0] + cVals[1])*(cVals[2] - cVals[3]) - cVals[4]*cVals[5] ) >= 0.0) - { - LOG(4, "SR fails at cond 3 : " << (cVals[0] + cVals[1])*(cVals[2] - cVals[3]) - cVals[4]*cVals[5] ); - } - return ( (cVals[0] + cVals[1])*(cVals[2] - cVals[3]) - cVals[4]*cVals[5] ) < 0.0; - - } - - // ///////////////////////////////////////////////////////////////////////////////// - // Utility methods used in intersection tests /////////////// - // ///////////////////////////////////////////////////////////////////////////////// - /** - * Tests if the triangle PQR surrounds the axis on which the - * given edge of the tetrahedron lies. - * - * @param edge edge of tetrahedron - * @return true if PQR surrounds edge, false if not (see Grandy, eq. [53]) - */ - bool TransformedTriangle::testTriangleSurroundsEdge(const TetraEdge edge) const - { - // NB DoubleProduct enum corresponds to TetraEdge enum according to Grandy, table III - // so we can use the edge directly - - const double cPQ = calcStableC(PQ, DoubleProduct(edge)); - const double cQR = calcStableC(QR, DoubleProduct(edge)); - const double cRP = calcStableC(RP, DoubleProduct(edge)); - - LOG(5, "TriangleSurroundsEdge : edge = " << edge << " c = [" << cPQ << ", " << cQR << ", " << cRP << "]" ); - - // if two or more c-values are zero we disallow x-edge intersection - // Grandy, p.446 - const int numZeros = (cPQ == 0.0 ? 1 : 0) + (cQR == 0.0 ? 1 : 0) + (cRP == 0.0 ? 1 : 0); - - if(numZeros >= 2 ) - { - LOG(5, "TriangleSurroundsEdge test fails due to too many 0 dp" ); - } - - return (cPQ*cQR >= 0.0) && (cQR*cRP >= 0.0) && (cRP*cPQ >= 0.0) && numZeros < 2; - } - -} // NAMESPACE diff --git a/src/INTERP_KERNEL/TransformedTriangleMath.cxx b/src/INTERP_KERNEL/TransformedTriangleMath.cxx deleted file mode 100644 index b61edc1cd..000000000 --- a/src/INTERP_KERNEL/TransformedTriangleMath.cxx +++ /dev/null @@ -1,503 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// - -#include "TransformedTriangle.hxx" -#include -#include -#include -#include -#include -#include -#include - -#include "VectorUtils.hxx" - -namespace INTERP_KERNEL -{ - - // ---------------------------------------------------------------------------------- - // Tables - // ---------------------------------------------------------------------------------- - - /// Table with first coordinate (a) used to calculate double product c^pq_ab = p_a * q_b - p_b * q_a (index to be used : DoubleProduct) - const int TransformedTriangle::DP_OFFSET_1[8] = {1, 2, 0, 2, 0, 1, 4, 1}; - - /// Table with second coordinate (b) used to calculate double product c^pq_ab = p_a * q_b - p_b * q_a (index to be used : DoubleProduct) - const int TransformedTriangle::DP_OFFSET_2[8] = {2, 0, 1, 3, 3, 3, 0, 4}; - - /// Coordinates used to calculate triple products by the expanding one of the three rows of the determinant (index to be used : 3*Corner + row) - const int TransformedTriangle::COORDINATE_FOR_DETERMINANT_EXPANSION[12] = - { - // row 1, 2, 3 - 0, 1, 2, // O - 3, 1, 2, // X - 0, 3, 2, // Y - 0, 1, 3 // Z - }; - - /// Double products used to calculate triple products by expanding one of the three rows of the determinant (index to be used : 3*Corner + row) - const TransformedTriangle::DoubleProduct TransformedTriangle::DP_FOR_DETERMINANT_EXPANSION[12] = - { - // row 1, 2, 3 - C_YZ, C_ZX, C_XY, // O - C_YZ, C_ZH, C_YH, // X - C_ZH, C_ZX, C_XH, // Y - C_YH, C_XH, C_XY // Z - }; - - /// The machine epsilon, used in precision corrections - const long double TransformedTriangle::MACH_EPS = std::numeric_limits::epsilon(); - - /// 4.0 * the machine epsilon, represents the precision of multiplication when performing corrections corrections ( f in Grandy ) - const long double TransformedTriangle::MULT_PREC_F = 4.0 * TransformedTriangle::MACH_EPS; - - /// Threshold for resetting double and triple products to zero; ( F / f in Grandy ) - const long double TransformedTriangle::THRESHOLD_F = 500.0; - - /// Threshold for what is considered a small enough angle to warrant correction of triple products by Grandy, [57] - const double TransformedTriangle::TRIPLE_PRODUCT_ANGLE_THRESHOLD = 0.1; - - - // after transformation to the U-space, coordinates are inaccurate - // small variations around zero should not be taken into account - void TransformedTriangle::resetNearZeroCoordinates() - { - for (int i=0; i<15; i++) - if (fabs(_coords[i]) distances; - - // -- (1) for each segment : check that double products satisfy Grandy, [46] - // -- and make corrections if not - for(TriSegment seg = PQ ; seg <= RP ; seg = TriSegment(seg + 1)) - { - if(!areDoubleProductsConsistent(seg)) - { - LOG(4, "inconsistent! "); - for(TetraCorner corner = O ; corner <= Z ; corner = TetraCorner(corner + 1)) - { - // calculate distance corner - segment axis - const double dist = calculateDistanceCornerSegment(corner, seg); - distances.insert( std::make_pair( dist, corner ) ); - } - - // first element -> minimum distance - const TetraCorner minCorner = distances.begin()->second; - resetDoubleProducts(seg, minCorner); - distances.clear(); - } - } - - // -- (2) check that each double product statisfies Grandy, [47], else set to 0 - for(TriSegment seg = PQ ; seg <= RP ; seg = TriSegment(seg + 1)) - { - for(DoubleProduct dp = C_YZ ; dp <= C_10 ; dp = DoubleProduct(dp + 1)) - { - // find the points of the triangle - // 0 -> P, 1 -> Q, 2 -> R - const int pt1 = seg; - const int pt2 = (seg + 1) % 3; - - // find offsets - const int off1 = DP_OFFSET_1[dp]; - const int off2 = DP_OFFSET_2[dp]; - - const double term1 = _coords[5*pt1 + off1] * _coords[5*pt2 + off2]; - const double term2 = _coords[5*pt1 + off2] * _coords[5*pt2 + off1]; - - const long double delta = MULT_PREC_F * ( std::fabs(term1) + std::fabs(term2) ); - - if( epsilonEqual(_doubleProducts[8*seg + dp], 0.0, THRESHOLD_F * delta)) - { - // debug output -#if LOG_LEVEL >= 5 - if(_doubleProducts[8*seg + dp] != 0.0) - { - LOG(5, "Double product for (seg,dp) = (" << seg << ", " << dp << ") = " ); - LOG(5, std::fabs(_doubleProducts[8*seg + dp]) << " is imprecise, reset to 0.0" ); - } -#endif - - - _doubleProducts[8*seg + dp] = 0.0; - - } - } - } - - _is_double_products_calculated = true; - } - - /** - * Checks if the double products for a given segment are consistent, as defined by - * Grandy, [46]. - * - * @param seg Segment for which to check consistency of double products - * @return true if the double products are consistent, false if not - */ - bool TransformedTriangle::areDoubleProductsConsistent(const TriSegment seg) const - { - const double term1 = _doubleProducts[8*seg + C_YZ] * _doubleProducts[8*seg + C_XH]; - const double term2 = _doubleProducts[8*seg + C_ZX] * _doubleProducts[8*seg + C_YH]; - const double term3 = _doubleProducts[8*seg + C_XY] * _doubleProducts[8*seg + C_ZH]; - - LOG(2, "for seg " << seg << " consistency " << term1 + term2 + term3 ); - LOG(2, "term1 :" << term1 << " term2 :" << term2 << " term3: " << term3 ); - - const int num_zero = (term1 == 0.0 ? 1 : 0) + (term2 == 0.0 ? 1 : 0) + (term3 == 0.0 ? 1 : 0); - const int num_neg = (term1 < 0.0 ? 1 : 0) + (term2 < 0.0 ? 1 : 0) + (term3 < 0.0 ? 1 : 0); - const int num_pos = (term1 > 0.0 ? 1 : 0) + (term2 > 0.0 ? 1 : 0) + (term3 > 0.0 ? 1 : 0); - - assert( num_zero + num_neg + num_pos == 3 ); - - // calculated geometry is inconsistent if we have one of the following cases - // * one term zero and the other two of the same sign - // * two terms zero - // * all terms positive - // * all terms negative - if(((num_zero == 1 && num_neg != 1) || num_zero == 2 || (num_neg == 0 && num_zero != 3) || num_neg == 3 )) - { - LOG(4, "inconsistent dp found" ); - } - return !((num_zero == 1 && num_neg != 1) || num_zero == 2 || (num_neg == 0 && num_zero != 3) || num_neg == 3 ); - - } - - /** - * Calculate the shortest distance between a tetrahedron corner and a triangle segment. - * - * @param corner corner of the tetrahedron - * @param seg segment of the triangle - * @return shortest distance from the corner to the segment - */ - double TransformedTriangle::calculateDistanceCornerSegment(const TetraCorner corner, const TriSegment seg) const - { - // NB uses fact that TriSegment <=> TriCorner that is first point of segment (PQ <=> P) - const TriCorner ptP_idx = TriCorner(seg); - const TriCorner ptQ_idx = TriCorner( (seg + 1) % 3); - - const double ptP[3] = { _coords[5*ptP_idx], _coords[5*ptP_idx + 1], _coords[5*ptP_idx + 2] }; - const double ptQ[3] = { _coords[5*ptQ_idx], _coords[5*ptQ_idx + 1], _coords[5*ptQ_idx + 2] }; - - // coordinates of corner - const double ptTetCorner[3] = - { - COORDS_TET_CORNER[3*corner ], - COORDS_TET_CORNER[3*corner + 1], - COORDS_TET_CORNER[3*corner + 2] - }; - - // dist^2 = ( PQ x CP )^2 / |PQ|^2 where C is the corner point - - // difference vectors - const double diffPQ[3] = { ptQ[0] - ptP[0], ptQ[1] - ptP[1], ptQ[2] - ptP[2] }; - const double diffCornerP[3] = { ptP[0] - ptTetCorner[0], ptP[1] - ptTetCorner[1], ptP[2] - ptTetCorner[2] }; - - // cross product of difference vectors - double crossProd[3]; - cross(diffPQ, diffCornerP, crossProd); - - const double cross_squared = dot(crossProd, crossProd); - const double norm_diffPQ_squared = dot(diffPQ, diffPQ); - - assert(norm_diffPQ_squared != 0.0); - - return cross_squared / norm_diffPQ_squared; - } - - /** - * Pre-calculates all triple products for the tetrahedron with respect to - * this triangle, and stores them internally. This method takes into account - * the problem of errors due to cancellation. - * - */ - void TransformedTriangle::preCalculateTripleProducts(void) - { - if(_is_triple_products_calculated) - { - return; - } - - // find edge / row to use -> that whose edge makes the smallest angle to the triangle - // use a map to find the minimum - std::map anglesForRows; - - LOG(4, "Precalculating triple products" ); - for(TetraCorner corner = O ; corner <= Z ; corner = TetraCorner(corner + 1)) - { - LOG(6, "- Triple product for corner " << corner ); - - for(int row = 1 ; row < 4 ; ++row) - { - const DoubleProduct dp = DP_FOR_DETERMINANT_EXPANSION[3*corner + (row - 1)]; - - // get edge by using correspondance between Double Product and Edge - TetraEdge edge = TetraEdge(dp); - - // use edge only if it is surrounded by the surface - if( _triangleSurroundsEdgeCache[edge] ) - { - // -- calculate angle between edge and PQR - const double angle = calculateAngleEdgeTriangle(edge); - anglesForRows.insert(std::make_pair(angle, row)); - } - } - - if(anglesForRows.size() != 0) // we have found a good row - { - const double minAngle = anglesForRows.begin()->first; - const int minRow = anglesForRows.begin()->second; - - if(minAngle < TRIPLE_PRODUCT_ANGLE_THRESHOLD) - { - _tripleProducts[corner] = calcTByDevelopingRow(corner, minRow, true); - } - else - { - _tripleProducts[corner] = calcTByDevelopingRow(corner, minRow, false); - } - _validTP[corner] = true; - } - else - { - // this value will not be used - // we set it to whatever - LOG(6, "Triple product not calculated for corner " << corner ); - _tripleProducts[corner] = -3.14159265; - _validTP[corner] = false; - - } - anglesForRows.clear(); - - } - - _is_triple_products_calculated = true; - } - - /** - * Calculates the angle between an edge of the tetrahedron and the triangle - * - * @param edge edge of the tetrahedron - * @return angle between triangle and edge - */ - double TransformedTriangle::calculateAngleEdgeTriangle(const TetraEdge edge) const - { - // find normal to PQR - cross PQ and PR - const double pq[3] = - { - _coords[5*Q] - _coords[5*P], - _coords[5*Q + 1] - _coords[5*P + 1], - _coords[5*Q + 2] - _coords[5*P + 2] - }; - - const double pr[3] = - { - _coords[5*R] - _coords[5*P], - _coords[5*R + 1] - _coords[5*P + 1], - _coords[5*R + 2] - _coords[5*P + 2] - }; - - double normal[3]; - - cross(pq, pr, normal); - - static const double EDGE_VECTORS[18] = - { - 1.0, 0.0, 0.0, // OX - 0.0, 1.0, 0.0, // OY - 0.0, 0.0, 1.0, // OZ - -1.0, 1.0, 0.0, // XY - 0.0,-1.0, 1.0, // YZ - 1.0, 0.0,-1.0 // ZX - }; - - const double edgeVec[3] = { - EDGE_VECTORS[3*edge], - EDGE_VECTORS[3*edge + 1], - EDGE_VECTORS[3*edge + 2], - }; - - //return angleBetweenVectors(normal, edgeVec); - - const double lenNormal = norm(normal); - const double lenEdgeVec = norm(edgeVec); - const double dotProd = dot(normal, edgeVec); - - //? is this more stable? -> no subtraction - // return asin( dotProd / ( lenNormal * lenEdgeVec ) ) + 3.141592625358979 / 2.0; - double tmp=dotProd / ( lenNormal * lenEdgeVec ); - tmp=std::max(tmp,-1.); - tmp=std::min(tmp,1.); - return atan(1.0)*4.0 - acos(tmp); - - } - - /** - * Calculates triple product associated with the given corner of tetrahedron, developing - * the determinant by the given row. The triple product gives the signed volume of - * the tetrahedron between this corner and the triangle PQR. If the flag project is true, - * one coordinate is projected out in order to eliminate errors in the intersection point - * calculation due to cancellation. - * - * @pre double products have already been calculated - * @param corner corner for which the triple product is calculated - * @param row row (1 <= row <= 3) used to calculate the determinant - * @param project indicates whether or not to perform projection as inidicated in Grandy, p.446 - * @return triple product associated with corner (see Grandy, [50]-[52]) - */ - double TransformedTriangle::calcTByDevelopingRow(const TetraCorner corner, const int row, const bool project) const - { - - // OVERVIEW OF CALCULATION - // --- sign before the determinant - // the sign used depends on the sign in front of the triple product (Grandy, [15]), - // and the convention used in the definition of the double products - - // the sign in front of the determinant gives the following schema for the three terms (I): - // corner/row 1 2 3 - // O (sign:+) + - + - // X (sign:-) - + - - // Y (sign:-) - + - - // Z (sign:-) - + - - - // the 2x2 determinants are the following (C_AB <=> A_p*B_q - B_p*A_q, etc) - // corner/row 1 2 3 - // O (sign:+) C_YZ C_XZ C_XY - // X (sign:-) C_YZ C_HZ C_HY - // Y (sign:-) C_HZ C_XZ C_XH - // Z (sign:-) C_YH C_XH C_XY - - // these are represented in DP_FOR_DETERMINANT_EXPANSION, - // except for the fact that certain double products are inversed (C_AB <-> C_BA) - - // comparing with the DOUBLE_PRODUCTS and using the fact that C_AB = -C_BA - // we deduce the following schema (II) : - // corner/row 1 2 3 - // O (sign:+) + - + - // X (sign:-) + - - - // Y (sign:-) - - + - // Z (sign:-) + + + - - // comparing the two schemas (I) and (II) gives us the following matrix of signs, - // putting 1 when the signs in (I) and (II) are equal and -1 when they are different : - - static const int SIGNS[12] = - { - 1, 1, 1, - -1,-1, 1, - 1,-1,-1, - -1, 1,-1 - }; - - // find the offsets of the rows of the determinant - const int offset = COORDINATE_FOR_DETERMINANT_EXPANSION[3 * corner + (row - 1)]; - - const DoubleProduct dp = DP_FOR_DETERMINANT_EXPANSION[3 * corner + (row - 1)]; - - const int sign = SIGNS[3 * corner + (row - 1)]; - - const double cQR = calcStableC(QR, dp); - const double cRP = calcStableC(RP, dp); - const double cPQ = calcStableC(PQ, dp); - - double alpha = 0.0; - - // coordinate to use for projection (Grandy, [57]) with edges - // OX, OY, OZ, XY, YZ, ZX in order : - // (y, z, x, h, h, h) - // for the first three we could also use {2, 0, 1} - static const int PROJECTION_COORDS[6] = { 1, 2, 0, 3, 3, 3 } ; - - const int coord = PROJECTION_COORDS[ dp ]; - - // coordinate values for P, Q and R - const double coordValues[3] = { _coords[5*P + coord], _coords[5*Q + coord], _coords[5*R + coord] }; - - if(project) - { - // products coordinate values with corresponding double product - const double coordDPProd[3] = { coordValues[0] * cQR, coordValues[1] * cRP, coordValues[2] * cPQ }; - - const double sumDPProd = coordDPProd[0] + coordDPProd[1] + coordDPProd[2]; - const double sumDPProdSq = dot(coordDPProd, coordDPProd); - - // alpha = sumDPProd / sumDPProdSq; - alpha = (sumDPProdSq != 0.0) ? sumDPProd / sumDPProdSq : 0.0; - } - - const double cQRbar = cQR * (1.0 - alpha * coordValues[0] * cQR); - const double cRPbar = cRP * (1.0 - alpha * coordValues[1] * cRP); - const double cPQbar = cPQ * (1.0 - alpha * coordValues[2] * cPQ); - - // check sign of barred products - should not change - // assert(cQRbar * cQR >= 0.0); - //assert(cRPbar * cRP >= 0.0); - //assert(cPQbar * cPQ >= 0.0); - - const double p_term = _coords[5*P + offset] * cQRbar; - const double q_term = _coords[5*Q + offset] * cRPbar; - const double r_term = _coords[5*R + offset] * cPQbar; - - // check that we are not so close to zero that numerical errors could take over, - // otherwise reset to zero (cf Grandy, p. 446) -#ifdef FIXED_DELTA - const double delta = FIXED_DELTA; -#else - const long double delta = MULT_PREC_F * (std::fabs(p_term) + std::fabs(q_term) + std::fabs(r_term)); -#endif - - if( epsilonEqual( p_term + q_term + r_term, 0.0, THRESHOLD_F * delta) ) - { - LOG(4, "Reset imprecise triple product for corner " << corner << " to zero" ); - return 0.0; - } - else - { - // NB : using plus also for the middle term compensates for a double product - // which is inversely ordered - LOG(6, "Triple product for corner " << corner << ", row " << row << " = " << sign*( p_term + q_term + r_term ) ); - return sign*( p_term + q_term + r_term ); - } - - } - -} diff --git a/src/INTERP_KERNEL/TranslationRotationMatrix.cxx b/src/INTERP_KERNEL/TranslationRotationMatrix.cxx deleted file mode 100644 index 345df1096..000000000 --- a/src/INTERP_KERNEL/TranslationRotationMatrix.cxx +++ /dev/null @@ -1,22 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// - -#include "TranslationRotationMatrix.hxx" - -const double INTERP_KERNEL::TranslationRotationMatrix::EPS=1e-12; diff --git a/src/INTERP_KERNEL/TranslationRotationMatrix.hxx b/src/INTERP_KERNEL/TranslationRotationMatrix.hxx deleted file mode 100644 index a0e4a0ebc..000000000 --- a/src/INTERP_KERNEL/TranslationRotationMatrix.hxx +++ /dev/null @@ -1,132 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 -// 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 __TRANSLATIONROTATIONMATRIX_HXX__ -#define __TRANSLATIONROTATIONMATRIX_HXX__ - -#include "INTERPKERNELDefines.hxx" - -#include - -namespace INTERP_KERNEL -{ - class INTERPKERNEL_EXPORT TranslationRotationMatrix - { - - public: - - TranslationRotationMatrix() - { - unsigned i; - for(i=0;i class InterpType > - class TriangulationIntersector : public InterpType > - { - public: - static const int SPACEDIM=MyMeshType::MY_SPACEDIM; - static const int MESHDIM=MyMeshType::MY_MESHDIM; - typedef typename MyMeshType::MyConnType ConnType; - static const NumberingPolicy numPol=MyMeshType::My_numPol; - public: - TriangulationIntersector(const MyMeshType& meshT, const MyMeshType& meshS, - double dimCaracteristic, double precision, double md3DSurf, double minDot3DSurf, double medianPlane, int orientation, int printLevel); - double intersectGeometry(ConnType icellT, ConnType icellS, ConnType nbNodesT, ConnType nbNodesS); - double intersectGeometryWithQuadrangle(const double *quadrangle, const std::vector& sourceCoords, bool isSourceQuad); - double intersectGeometryGeneral(const std::vector& targetCoords, const std::vector& sourceCoords); - double intersectGeoBary(const std::vector& targetCell, bool targetCellQuadratic, const double *sourceCell, std::vector& res); - - }; -} - -#endif diff --git a/src/INTERP_KERNEL/TriangulationIntersector.txx b/src/INTERP_KERNEL/TriangulationIntersector.txx deleted file mode 100644 index a7a080b28..000000000 --- a/src/INTERP_KERNEL/TriangulationIntersector.txx +++ /dev/null @@ -1,236 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 -// 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 __TRIANGULATIONINTERSECTOR_TXX__ -#define __TRIANGULATIONINTERSECTOR_TXX__ - -#include "TriangulationIntersector.hxx" -#include "PlanarIntersectorP0P0.txx" -#include "PlanarIntersectorP0P1.txx" -#include "PlanarIntersectorP1P0.txx" -#include "PlanarIntersectorP1P0Bary.txx" - -#include "InterpolationUtils.hxx" -#include "PlanarIntersector.hxx" - -#include - -#define TRI_INTERSECTOR TriangulationIntersector -#define TRI_INTER_TEMPLATE template class InterpType> - -namespace INTERP_KERNEL -{ - TRI_INTER_TEMPLATE - TRI_INTERSECTOR::TriangulationIntersector(const MyMeshType& meshT, const MyMeshType& meshS, - double DimCaracteristic, double Precision, double md3DSurf, double minDot3DSurf, - double MedianPlane, int orientation, int PrintLevel) - :InterpType(meshT,meshS,DimCaracteristic, Precision, md3DSurf, minDot3DSurf, - MedianPlane, true, orientation, PrintLevel) - { - if(PlanarIntersector::_print_level >= 1) - { - std::cout << " - intersection type = triangles " << std::endl; - if(SPACEDIM==3) std::cout << "_do_rotate = true"<< std::endl; - } - } - - TRI_INTER_TEMPLATE - double TRI_INTERSECTOR::intersectGeometry(ConnType icellT, ConnType icellS, - ConnType nbNodesT, ConnType nbNodesS) - { - double result = 0.; - int orientation = 1; - - //Obtain the coordinates of T and S - std::vector CoordsT; - std::vector CoordsS; - PlanarIntersector::getRealCoordinates(icellT,icellS,nbNodesT,nbNodesS,CoordsT,CoordsS,orientation); - //Compute the intersection area - double area[SPACEDIM]; - for(ConnType iT = 1; iT inter; - INTERP_KERNEL::intersec_de_triangle(&CoordsT[0],&CoordsT[SPACEDIM*iT],&CoordsT[SPACEDIM*(iT+1)], - &CoordsS[0],&CoordsS[SPACEDIM*iS],&CoordsS[SPACEDIM*(iS+1)], - inter, PlanarIntersector::_dim_caracteristic, - PlanarIntersector::_precision); - ConnType nb_inter=((ConnType)inter.size())/2; - if(nb_inter >3) inter=reconstruct_polygon(inter); - for(ConnType i = 1; i(&inter[0],&inter[2*i],&inter[2*(i+1)],area); - result +=0.5*fabs(area[0]); - } - //DEBUG prints - if(PlanarIntersector::_print_level >= 3) - { - std::cout << std::endl << "Number of nodes of the intersection = "<< nb_inter << std::endl; - for(ConnType i=0; i< nb_inter; i++) - {for (int idim=0; idim<2; idim++) std::cout << inter[2*i+idim] << " "; std::cout << std::endl; } - } - } - } - - //DEBUG PRINTS - if(PlanarIntersector::_print_level >= 3) - std::cout << std::endl <<"Intersection area = " << result << std::endl; - - return orientation*result; - } - - TRI_INTER_TEMPLATE - double TRI_INTERSECTOR::intersectGeometryWithQuadrangle(const double * quadrangle, - const std::vector& sourceCoords, - bool isSourceQuad) - { - double result = 0.; - ConnType nbNodesS=sourceCoords.size()/SPACEDIM; - //Compute the intersection area - double area[SPACEDIM]; - for(ConnType iT = 1; iT<3; iT++) - { - for(ConnType iS = 1; iS inter; - INTERP_KERNEL::intersec_de_triangle(quadrangle,&quadrangle[SPACEDIM*iT],&quadrangle[SPACEDIM*(iT+1)], - &sourceCoords[0],&sourceCoords[SPACEDIM*iS],&sourceCoords[SPACEDIM*(iS+1)], - inter, PlanarIntersector::_dim_caracteristic, - PlanarIntersector::_precision); - ConnType nb_inter=((ConnType)inter.size())/2; - if(nb_inter >3) inter=reconstruct_polygon(inter); - for(ConnType i = 1; i(&inter[0],&inter[2*i],&inter[2*(i+1)],area); - result +=0.5*fabs(area[0]); - } - //DEBUG prints - if(PlanarIntersector::_print_level >= 3) - { - std::cout << std::endl << "Number of nodes of the intersection = "<< nb_inter << std::endl; - for(ConnType i=0; i< nb_inter; i++) - {for (int idim=0; idim<2; idim++) std::cout << inter[2*i+idim] << " "; std::cout << std::endl; } - } - } - } - - //DEBUG PRINTS - if(PlanarIntersector::_print_level >= 3) - std::cout << std::endl <<"Intersection area = " << result << std::endl; - - return result; - } - - TRI_INTER_TEMPLATE - double TRI_INTERSECTOR::intersectGeometryGeneral(const std::vector& targetCoords, - const std::vector& sourceCoords) - { - double result = 0.; - ConnType nbNodesS=sourceCoords.size()/SPACEDIM; - ConnType nbNodesT=targetCoords.size()/SPACEDIM; - //Compute the intersection area - double area[SPACEDIM]; - for(ConnType iT = 1; iT inter; - INTERP_KERNEL::intersec_de_triangle(&targetCoords[0],&targetCoords[SPACEDIM*iT],&targetCoords[SPACEDIM*(iT+1)], - &sourceCoords[0],&sourceCoords[SPACEDIM*iS],&sourceCoords[SPACEDIM*(iS+1)], - inter, PlanarIntersector::_dim_caracteristic, - PlanarIntersector::_precision); - ConnType nb_inter=((ConnType)inter.size())/2; - if(nb_inter >3) inter=reconstruct_polygon(inter); - for(ConnType i = 1; i(&inter[0],&inter[2*i],&inter[2*(i+1)],area); - result +=0.5*fabs(area[0]); - } - } - } - return result; - } - - //================================================================================ - /*! - * \brief Intersect a triangle and a polygon for P1P0 barycentric algorithm - * \param targetCell - list of coordinates of target polygon in full interlace - * \param targetCellQuadratic - specifies if target polygon is quadratic or not - * \param sourceTria - list of coordinates of source triangle - * \param res - coefficients a,b and c associated to nodes of sourceTria - */ - //================================================================================ - - TRI_INTER_TEMPLATE - double TRI_INTERSECTOR::intersectGeoBary(const std::vector& targetCell, - bool targetCellQuadratic, - const double * sourceTria, - std::vector& res) - { - std::vector sourceCell(3); - sourceCell[0] = &sourceTria[0]; - sourceCell[1] = &sourceTria[SPACEDIM]; - sourceCell[2] = &sourceTria[SPACEDIM*2]; - - //Compute the intersection area - double inter_area[SPACEDIM], total_area = 0.; - double total_barycenter[SPACEDIM]={0.,0.}; - - const ConnType nbNodesT=targetCell.size()/SPACEDIM; - for(ConnType iT = 1; iT inter; - INTERP_KERNEL::intersec_de_triangle(&targetCell[0],&targetCell[SPACEDIM*iT],&targetCell[SPACEDIM*(iT+1)], - sourceCell[0], sourceCell[1], sourceCell[2], - inter, PlanarIntersector::_dim_caracteristic, - PlanarIntersector::_precision); - ConnType nb_inter=((ConnType)inter.size())/2; - if(nb_inter >3) inter=reconstruct_polygon(inter); - for(ConnType i = 1; i(&inter[0],&inter[2*i],&inter[2*(i+1)],inter_area); - inter_area[0] = 0.5 * fabs( inter_area[0] ); - total_area += inter_area[0]; - std::vector inter_bary=INTERP_KERNEL::bary_poly(inter); - total_barycenter[0] += inter_area[0] * inter_bary[0]; - total_barycenter[1] += inter_area[0] * inter_bary[1]; - } - } - if ( total_area > std::numeric_limits::min() ) - { - total_barycenter[0] /= total_area; - total_barycenter[1] /= total_area; - res.resize(3); - barycentric_coords( sourceCell, &total_barycenter[0], &res[0]); - res[0] *= total_area; - res[1] *= total_area; - res[2] *= total_area; - } - else - { - total_area = 0; - } - return total_area; - } - -} - -#endif diff --git a/src/INTERP_KERNEL/UnitTetraIntersectionBary.cxx b/src/INTERP_KERNEL/UnitTetraIntersectionBary.cxx deleted file mode 100644 index 4cd663089..000000000 --- a/src/INTERP_KERNEL/UnitTetraIntersectionBary.cxx +++ /dev/null @@ -1,755 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 -// 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 -// - -// File : UnitTetraIntersectionBary.cxx -// Created : Tue Dec 9 16:48:49 2008 -// Author : Edward AGAPOV (eap) -// -#include "UnitTetraIntersectionBary.hxx" - -#include "VectorUtils.hxx" -#include "InterpolationUtils.hxx" -#include "VolSurfFormulae.hxx" - -#define NB_TETRA_SIDES 4 -#define NB_TETRA_NODES 4 - -//#define DMP_UNITTETRAINTERSECTIONBARY - - -namespace INTERP_KERNEL -{ - enum { _X=0, _Y, _Z }; - - inline bool samePoint( const double* p1, const double* p2 ) - { - return ( epsilonEqual( p1[0], p2[0]) && - epsilonEqual( p1[1], p2[1]) && - epsilonEqual( p1[2], p2[2])); - } - - //================================================================================ - /*! - * \brief Creates a ready-to-use tool - */ - //================================================================================ - - UnitTetraIntersectionBary::UnitTetraIntersectionBary(bool isTetraInversed) - :TransformedTriangle(),_int_volume(0),_isTetraInversed( isTetraInversed ) - { - //init(); - } - //================================================================================ - /*! - * \brief Initializes fields - */ - //================================================================================ - - void UnitTetraIntersectionBary::init(bool isTetraInversed) - { - _int_volume = 0; - _isTetraInversed = isTetraInversed; - _faces.clear(); - _polyNormals.clear(); - } - - //================================================================================ - /*! - * \brief Stores a part of triangle common with the unit tetrahedron - * \param triangle - triangle side of other cell - */ - //================================================================================ - - void UnitTetraIntersectionBary::addSide(const TransformedTriangle& triangle) - { - _int_volume += triangle.getVolume(); - - double triNormal[3], polyNormal[3]; - crossprod<3>( triangle.getCorner(P),triangle.getCorner(Q),triangle.getCorner(R), triNormal); - - const std::vector * pPolygonA = &triangle.getPolygonA(); - if ( pPolygonA->size() < 3 ) - { - if ( !epsilonEqual( triNormal[_Z], 0 )) - return; // not vertical triangle does not intersect the unit tetra - - // Vertical triangle. Use inherited methods of TransformedTriangle to - // calculate intesection polygon - *((TransformedTriangle*)this) = triangle; // copy triangle fields - _polygonA.clear(); - _polygonB.clear(); - calculateIntersectionAndProjectionPolygons(); - if (this->_polygonA.size() < 3) - return; - calculatePolygonBarycenter(A, _barycenterA); - sortIntersectionPolygon(A, _barycenterA); - pPolygonA = & _polygonA; - } - - // check if polygon orientation is same as the one of triangle - std::vector::const_iterator p = pPolygonA->begin(), pEnd = pPolygonA->end(); -#ifdef DMP_UNITTETRAINTERSECTIONBARY - std::cout.precision(18); - std::cout << "**** int polygon() " << std::endl; - while ( p != pEnd ) - { - double* pp = *p++; - std::cout << pEnd - p << ": ( " << pp[0] << ", " << pp[1] << ", " << pp[2] << " )" << std::endl; - } - p = pPolygonA->begin(); -#endif - double* p1 = *p++; - double* p2 = *p; - while ( samePoint( p1, p2 ) && ++p != pEnd ) - p2 = *p; - if ( p == pEnd ) - { -#ifdef DMP_UNITTETRAINTERSECTIONBARY - std::cout << "All points equal" << std::endl; -#endif - clearPolygons(); - return; - } - double* p3 = *p; - while (( samePoint( p2, p3 ) || samePoint( p1, p3 )) && ++p != pEnd ) - p3 = *p; - if ( p == pEnd ) - { -#ifdef DMP_UNITTETRAINTERSECTIONBARY - std::cout << "Only two points differ" << std::endl; -#endif - clearPolygons(); - return ; - } - crossprod<3>( p1, p2, p3, polyNormal ); - bool reverse = ( dotprod<3>( triNormal, polyNormal ) < 0.0 ); - if (_isTetraInversed) reverse = !reverse; - - // store polygon - _faces.push_back( std::vector< double* > () ); - std::vector< double* >& faceCorner = _faces.back(); - faceCorner.resize( pPolygonA->size()/* + 1*/ ); - - int i = 0; - if ( reverse ) - { - std::vector::const_reverse_iterator polyF = pPolygonA->rbegin(), polyEnd; - for ( polyEnd = pPolygonA->rend(); polyF != polyEnd; ++i, ++polyF ) - if ( i==0 || !samePoint( *polyF, faceCorner[i-1] )) - copyVector3( *polyF, faceCorner[i] = new double[3] ); - else - --i; - polyNormal[0] *= -1.; - polyNormal[1] *= -1.; - polyNormal[2] *= -1.; - } - else - { - std::vector::const_iterator polyF = pPolygonA->begin(), polyEnd; - for ( polyEnd = pPolygonA->end(); polyF != polyEnd; ++i, ++polyF ) - if ( i==0 || !samePoint( *polyF, faceCorner[i-1] )) - copyVector3( *polyF, faceCorner[i] = new double[3] ); - else - --i; - } - if ( i < 3 ) - { - clearPolygons(); // free memory of _polygonA - _polygonA = faceCorner; - _faces.pop_back(); - } - else - { - if ( i < (int)pPolygonA->size() ) - faceCorner.resize( i ); - - if ( _polyNormals.empty() ) - _polyNormals.reserve(4); - _polyNormals.push_back( std::vector< double >( polyNormal, polyNormal+3 )); - } - -#ifdef DMP_UNITTETRAINTERSECTIONBARY - std::cout << "**** addSide() " << _faces.size() << std::endl; - for ( int i = 0; i < faceCorner.size(); ++i ) - { - double* p = faceCorner[i]; - std::cout << i << ": ( " << p[0] << ", " << p[1] << ", " << p[2] << " )" << std::endl; - } - std::cout << "NORM: ( " << _polyNormals.back()[0] << ", " << _polyNormals.back()[1] << ", " << _polyNormals.back()[2] << " )" << std::endl; -#endif - clearPolygons(); - } - - //================================================================================ - /*! - * \brief Computes and returns coordinates of barycentre - */ - //================================================================================ - - bool UnitTetraIntersectionBary::getBary(double* baryCenter) - { - baryCenter[0] = baryCenter[1] = baryCenter[2] = -1.0; - if ( addSideFaces() < NB_TETRA_SIDES ) - { - // tetra is not intersected - if ( fabs(_int_volume) > 1e-10 ) - { - // tetra is fully inside the other cell - baryCenter[0] = baryCenter[1] = baryCenter[2] = 0.25; - _int_volume = 0.16666666666666666; - return true; - } - return false; - } - // Algo: - // - pick up one point P among the summits of the polyhedron - // - for each face of the polyhedron which does not contain the point : - // - compute the barycenter of the volume obtained by forming the "pyramid" with - // the face as a base and point P as a summit - // - compute the volume of the "pyramid" - // - Add up all barycenter positions weighting them with the volumes. - - baryCenter[0] = baryCenter[1] = baryCenter[2] = 0.; - - std::list< std::vector< double* > >::iterator f = _faces.begin(), fEnd = _faces.end(); - double * PP = f->at(0); - - for ( ++f; f != fEnd; ++f ) - { - std::vector< double* >& polygon = *f; - if ( polygon.empty() ) - continue; - - bool pBelongsToPoly = false; - std::vector::iterator v = polygon.begin(), vEnd = polygon.end(); - for ( ; !pBelongsToPoly && v != vEnd; ++v ) - pBelongsToPoly = samePoint( PP, *v ); - if ( pBelongsToPoly ) - continue; - - // Compute the barycenter of the volume. Barycenter of pyramid is on line - // ( barycenter of polygon -> PP ) with 1/4 of pyramid height from polygon. - - double bary[] = { 0, 0, 0 }; - - // base polygon bary - for ( v = polygon.begin(); v != vEnd ; ++v ) - { - double* p = *v; - bary[0] += p[0]; - bary[1] += p[1]; - bary[2] += p[2]; - } - bary[0] /= (int)polygon.size(); - bary[1] /= (int)polygon.size(); - bary[2] /= (int)polygon.size(); - - // pyramid volume - double vol = 0; - for ( int i = 0; i < (int)polygon.size(); ++i ) - { - double* p1 = polygon[i]; - double* p2 = polygon[(i+1)%polygon.size()]; - vol += std::fabs( calculateVolumeForTetra( p1, p2, bary, PP )); - } - - // put bary on the line ( barycenter of polygon -> PP ) and multiply by volume - baryCenter[0] += ( bary[0] * 0.75 + PP[0] * 0.25 ) * vol; - baryCenter[1] += ( bary[1] * 0.75 + PP[1] * 0.25 ) * vol; - baryCenter[2] += ( bary[2] * 0.75 + PP[2] * 0.25 ) * vol; - } - if ( _int_volume < 0. ) - _int_volume = -_int_volume; - baryCenter[0] /= _int_volume; - baryCenter[1] /= _int_volume; - baryCenter[2] /= _int_volume; - -#ifdef DMP_UNITTETRAINTERSECTIONBARY - std::cout.precision(5); - std::cout << "**** Barycenter " << baryCenter[0] <<", "<< baryCenter[1] <<", "<< baryCenter[2] - << "\t **** Volume " << _int_volume << std::endl; - std::cout << "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~" << std::endl; -#endif - return true; - } - - //================================================================================ - /*! - * \brief Add faces of the intersection polyhedron formed on faces of the - * unit tetrahedron by sides of already added faces - * \retval int - number of faces of intersection polyhedron - */ - //================================================================================ - - int UnitTetraIntersectionBary::addSideFaces() - { - int nbPolyhedraFaces = 0; - - if ( _faces.empty() ) - return nbPolyhedraFaces; - - // ------------------------------------------- - // Detect polygons laying on sides of a tetra - // ------------------------------------------- - - bool sideAdded[NB_TETRA_SIDES] = { false, false, false, false }; - int nbAddedSides = 0; - std::list< std::vector< double* > >::iterator f = _faces.begin(), fEnd = _faces.end(); - for ( ; f != fEnd; ++f ) - { - std::vector< double* >& polygon = *f; - double coordSum[3] = {0,0,0}; - for ( int i = 0; i < (int)polygon.size(); ++i ) - { - double* p = polygon[i]; - coordSum[0] += p[0]; - coordSum[1] += p[1]; - coordSum[2] += p[2]; - } - for ( int j = 0; j < 3 && !sideAdded[j]; ++j ) - { - if ( epsilonEqual( coordSum[j], 0.0 )) - sideAdded[j] = ++nbAddedSides != 0 ; - } - if ( !sideAdded[3] && - ( epsilonEqual( (coordSum[0]+coordSum[1]+coordSum[2]) / (int)polygon.size(), 1. ))) - sideAdded[3] = ++nbAddedSides != 0 ; - } - if ( nbAddedSides == NB_TETRA_SIDES ) - return nbAddedSides; - - // --------------------------------------------------------------------------------- - // Add segments of already added polygons to future polygonal faces on sides of tetra - // --------------------------------------------------------------------------------- - - std::size_t nbIntersectPolygs = _faces.size(); - - std::vector< double* > * sideFaces[ 4 ]; // future polygons on sides of tetra - for ( int i = 0; i < NB_TETRA_SIDES; ++i ) - { - sideFaces[ i ]=0; - if ( !sideAdded[ i ] ) - { - _faces.push_back( std::vector< double* > () ); - sideFaces[ i ] = &_faces.back(); - } - } - f = _faces.begin(), fEnd = _faces.end(); - for ( std::size_t iF = 0; iF < nbIntersectPolygs; ++f, ++iF ) // loop on added intersection polygons - { - std::vector< double* >& polygon = *f; - for ( std::size_t i = 0; i < polygon.size(); ++i ) - { - // segment ends - double* p1 = polygon[i]; - double* p2 = polygon[(i+1)%polygon.size()]; - bool p1OnSide, p2OnSide;//, onZeroSide = false; - for ( int j = 0; j < 3; ++j ) - { - if ( !sideFaces[ j ] ) - continue; - p1OnSide = epsilonEqual( p1[j], 0. ); - p2OnSide = epsilonEqual( p2[j], 0. ); - if ( p1OnSide && p2OnSide ) - { - // segment p1-p2 is on j-th orthogonal side of tetra - sideFaces[j]->push_back( new double[3] ); - copyVector3( p1, sideFaces[j]->back() ); - sideFaces[j]->push_back( new double[3] ); - copyVector3( p2, sideFaces[j]->back() ); - //break; - } - } - // check if the segment p1-p2 is on the inclined side - if ( sideFaces[3] && - epsilonEqual( p1[_X] + p1[_Y] + p1[_Z], 1.0 ) && - epsilonEqual( p2[_X] + p2[_Y] + p2[_Z], 1.0 )) - { - sideFaces[3]->push_back( new double[3] ); - copyVector3( p1, sideFaces[3]->back() ); - sideFaces[3]->push_back( new double[3] ); - copyVector3( p2, sideFaces[3]->back() ); - } - } - } -#ifdef DMP_UNITTETRAINTERSECTIONBARY - std::cout << "**** after Add segments to sides " << std::endl; - for ( int i = 0; i < NB_TETRA_SIDES; ++i ) - { - std::cout << "\t Side " << i << std::endl; - if ( !sideFaces[i] ) - { - std::cout << "\t cut by triagle" << std::endl; - } - else - { - std::vector< double* >& sideFace = *sideFaces[i]; - for ( int i = 0; i < sideFace.size(); ++i ) - { - double* p = sideFace[i]; - std::cout << "\t" << i << ": ( " << p[0] << ", " << p[1] << ", " << p[2] << " )" << std::endl; - } - } - } -#endif - - // --------------------------------------------------------------------------- - // Make closed polygons on tetra sides by adding not cut off corners of tetra - // --------------------------------------------------------------------------- - - double origin[3] = { 0,0,0 }; - - // find corners of tetra cut off by triangles of other tetra - // --------------------------------------------------------- - - // corners are coded like this: index = 1*X + 2*Y + 3*Z - // (0,0,0) -> index == 0; (0,0,1) -> index == 3 - int cutOffCorners[NB_TETRA_NODES] = { false, false, false, false }; - int passedCorners[NB_TETRA_NODES] = { false, false, false, false }; - - // find cutOffCorners by normals of intersection polygons - int nbCutOffCorners = 0; - for ( int ic = 0; ic < NB_TETRA_NODES; ++ic ) - { - f = _faces.begin(), fEnd = _faces.end(); - for ( std::size_t iF = 0; iF < nbIntersectPolygs; ++f, ++iF ) // loop on added intersection polygons - { - std::vector< double* >& polygon = *f; - - double corner2Poly[3] = { polygon[0][0], polygon[0][1], polygon[0][2] }; - if ( ic ) corner2Poly[ ic-1 ] -= 1.0; - - // _polyNormals are outside of a tetrahedron - double dot = dotprod<3>( corner2Poly, &_polyNormals[iF][0] ); - if ( dot < -DEFAULT_ABS_TOL*DEFAULT_ABS_TOL ) - { -#ifdef DMP_UNITTETRAINTERSECTIONBARY - std::cout << "side " << iF+1 << ": cut " << ic << std::endl; -#endif - cutOffCorners[ ic ] = true; - nbCutOffCorners++; - break; - } - } - } - - for ( int i = 0; i < 3; ++i ) // loop on orthogonal faces of the unit tetra - { - if ( !sideFaces[i] ) continue; - std::vector< double* >& sideFace = *sideFaces[i]; - - std::size_t nbPoints = sideFace.size(); - if ( nbPoints == 0 ) - continue; // not intersected face at all - no cut off corners can be detected - - int ind1 = (i+1)%3, ind2 = (i+2)%3; // indices of coords on i-th tetra side - - int nbCutOnSide = 0; - bool isSegmentOnEdge=false; - for ( std::size_t ip = 0; ip < nbPoints; ++ip ) - { - std::size_t isSegmentEnd = ( ip % 2 ); - - double* p = sideFace[ ip ]; - double* p2 = isSegmentEnd ? 0 : sideFace[ip+1]; - - if ( !isSegmentEnd ) - isSegmentOnEdge = false; // initialize - - int cutOffIndex = -1, passThIndex = -1;// no cut off neither pass through - int pCut[] = { 0,0,0 }, pPass[] = { 0,0,0 }; - - if ( epsilonEqual( p[ind1], 0.)) - { - // point is on orthogonal edge - if ( !isSegmentEnd && epsilonEqual( p2[ind1], 0. )) - isSegmentOnEdge = true; - - if ( !isSegmentOnEdge ) - { // segment ends are on different edges - pCut[ind2] = (int)isSegmentEnd; // believe that cutting triangles are well oriented - cutOffIndex = pCut[0] + 2*pCut[1] + 3*pCut[2]; - } - if ( epsilonEqual( p[ind2], 0.) || epsilonEqual( p[ind2], 1.)) - { - pPass[ind2] = ( p[ind2] < 0.5 ) ? 0 : 1; - passThIndex = pPass[0] + 2*pPass[1] + 3*pPass[2]; - } - } - else if ( epsilonEqual( p[ind2], 0.)) - { - // point is on orthogonal edge - if ( !isSegmentEnd && epsilonEqual( p2[ind2], 0. )) - isSegmentOnEdge = true; - if ( !isSegmentEnd ) - {// segment ends are on different edges - pCut[ind1] = 1-(int)isSegmentEnd; - cutOffIndex = pCut[0] + 2*pCut[1] + 3*pCut[2]; - } - if ( epsilonEqual( p[ind1], 0.) || epsilonEqual( p[ind1], 1.)) - { - pPass[ind1] = ( p[ind1] < 0.5 ) ? 0 : 1; - passThIndex = pPass[0] + 2*pPass[1] + 3*pPass[2]; - } - } - else if ( epsilonEqual(p[ind1] + p[ind2], 1.0 )) - { - // point is on inclined edge - if ( !isSegmentEnd && epsilonEqual(p2[ind1] + p2[ind2], 1.0 )) - isSegmentOnEdge = true; - if ( !isSegmentOnEdge ) - { //segment ends are on different edges - pCut[ind1] = (int)isSegmentEnd; - pCut[ind2] = 1-(int)isSegmentEnd; - cutOffIndex = pCut[0] + 2*pCut[1] + 3*pCut[2]; - } - } - else - { - continue; - } - // remember cut off and passed through points - if ( passThIndex >= 0 ) - { - passedCorners[ passThIndex ] = true; - if ( cutOffCorners[ passThIndex ] ) - { - nbCutOffCorners--; - cutOffCorners[ passThIndex ] = false; -#ifdef DMP_UNITTETRAINTERSECTIONBARY - std::cout << "PASS THROUGH " << passThIndex << std::endl; -#endif - } - } - if ( cutOffIndex >= 0 ) - { - nbCutOnSide++; - if ( !passedCorners[ cutOffIndex ] && !cutOffCorners[ cutOffIndex ] ) - { - nbCutOffCorners++; - cutOffCorners[ cutOffIndex ] = true; - } - } - } // loop on points on a unit tetra side - - if ( nbCutOnSide == 0 && nbPoints <= 2 ) - continue; // one segment laying on edge at most - - if ( nbCutOffCorners == NB_TETRA_NODES ) - break; // all tetra corners are cut off - - if ( /*nbCutOnSide <= 2 &&*/ nbPoints >= 6 ) - { - // at least 3 segments - all corners of a side are cut off - for (int cutIndex = 0; cutIndex < NB_TETRA_NODES; ++cutIndex ) - if ( cutIndex != i+1 && !passedCorners[ cutIndex ] && !cutOffCorners[ cutIndex ]) - cutOffCorners[ cutIndex ] = ++nbCutOffCorners != 0 ; - } - - } - // loop on orthogonal faces of tetra - - // check if all corners are cut off on the inclined tetra side - if ( sideFaces[ XYZ ] && sideFaces[ XYZ ]->size() >= 6 ) - { - for (int cutIndex = 1; cutIndex < NB_TETRA_NODES; ++cutIndex ) - if ( !passedCorners[ cutIndex ] && !cutOffCorners[ cutIndex ]) - cutOffCorners[ cutIndex ] = ++nbCutOffCorners != 0 ; - } - - // Add to faces on tetra sides the corners not cut off by segments of intersection polygons - // ---------------------------------------------------------------------------------- - if ( nbCutOffCorners > 0 ) - { - for ( int i = 0; i < NB_TETRA_SIDES; ++i ) - { - if ( !sideFaces[ i ] ) continue; - std::vector< double* >& sideFace = *sideFaces[i]; - - int excludeCorner = (i + 1) % NB_TETRA_NODES; - for ( int ic = 0; ic < NB_TETRA_NODES; ++ic ) - { - if ( !cutOffCorners[ ic ] && ic != excludeCorner ) - { - sideFace.push_back( new double[3] ); - copyVector3( origin, sideFace.back() ); - if ( ic ) - sideFace.back()[ ic-1 ] = 1.0; - } - } - } - } - -#ifdef DMP_UNITTETRAINTERSECTIONBARY - std::cout << "**** after Add corners to sides " << std::endl; - for ( int i = 0; i < NB_TETRA_SIDES; ++i ) - { - std::cout << "\t Side " << i << std::endl; - if ( !sideFaces[i] ) { - std::cout << "\t cut by triagle" << std::endl; - } - else - { - std::vector< double* >& sideFace = *sideFaces[i]; - for ( int i = 0; i < sideFace.size(); ++i ) - { - double* p = sideFace[i]; - std::cout << "\t" << i << ": ( " << p[0] << ", " << p[1] << ", " << p[2] << " )" << std::endl; - } - } - } - std::cout << "Cut off corners: "; - if ( nbCutOffCorners == 0 ) - std::cout << "NO"; - else - for ( int ic = 0; ic < NB_TETRA_NODES; ++ic ) - std::cout << cutOffCorners[ ic ]; - std::cout << std::endl; -#endif - // ------------------------------------------------------------------------ - // Sort corners of filled up faces on tetra sides and exclude equal points - // ------------------------------------------------------------------------ - - std::size_t iF = 0; - for ( f = _faces.begin(); f != fEnd; ++f, ++iF ) - { - std::vector< double* >& face = *f; - if ( face.size() >= 3 ) - { - clearPolygons(); // free memory of _polygonA - _polygonA = face; - face.clear(); - face.reserve( _polygonA.size() ); - if ( iF >= nbIntersectPolygs ) - { // sort points of side faces - calculatePolygonBarycenter( A, _barycenterA ); - setTriangleOnSide( (int)(iF-nbIntersectPolygs) ); - sortIntersectionPolygon( A, _barycenterA ); - } - // exclude equal points - std::vector< double* >::iterator v = _polygonA.begin(), vEnd = _polygonA.end(); - face.push_back( *v ); - *v = 0; - for ( ++v; v != vEnd; ++v ) - { - double* pPrev = face.back(); - double* p = *v; - if ( !samePoint( p, pPrev )) - { - face.push_back( p ); - *v = 0; - } - } - } - if ( face.size() < 3 ) - { // size could decrease - clearPolygons(); // free memory of _polygonA - _polygonA = face; - face.clear(); - } - else - { - nbPolyhedraFaces++; - } - } -#ifdef DMP_UNITTETRAINTERSECTIONBARY - std::cout << "**** after HEALING all faces " << std::endl; - for (iF=0, f = _faces.begin(); f != fEnd; ++f, ++iF ) - { - std::cout << "\t Side " << iF << std::endl; - std::vector< double* >& sideFace = *f; - for ( int i = 0; i < sideFace.size(); ++i ) - { - double* p = sideFace[i]; - std::cout << "\t" << i << ": ( " << p[0] << ", " << p[1] << ", " << p[2] << " )" << std::endl; - } - } -#endif - return nbPolyhedraFaces; - } - - //================================================================================ - /*! - * \brief set corners of inherited TransformedTriangle as corners of i-th side of - * the Unit tetra. It is necessary to sort points of faces on sides of the unit - * tetrahedron using sortIntersectionPolygon(A) - */ - //================================================================================ - - void UnitTetraIntersectionBary::setTriangleOnSide(int iSide) - { - if ( iSide >= 3 ) - iSide = 0; - for(int i = 0 ; i < 3 ; ++i) - { - _coords[5*i] = _coords[5*i + 1] = _coords[5*i + 2] = 0.; - if ( i != iSide ) - _coords[5*i + i] = 1.; - } - } - - //================================================================================ - /*! - * \brief Free memory of polygons - */ - //================================================================================ - - void UnitTetraIntersectionBary::clearPolygons(bool andFaces) - { - for(std::vector::iterator it = _polygonA.begin() ; it != _polygonA.end() ; ++it) - { delete[] *it; - *it = 0; - } - for(std::vector::iterator it = _polygonB.begin() ; it != _polygonB.end() ; ++it) - { - delete[] *it; - *it = 0; - } - - _polygonA.clear(); - _polygonB.clear(); - - if ( andFaces ) - { - std::list< std::vector< double* > >::iterator f = this->_faces.begin(), fEnd = this->_faces.end(); - for ( ; f != fEnd; ++f ) - { - std::vector< double* >& polygon = *f; - for(std::vector::iterator it = polygon.begin() ; it != polygon.end() ; ++it) - { - delete[] *it; - *it = 0; - } - } - this->_faces.clear(); - } - } - - //================================================================================ - /*! - * \brief Destructor clears coordinates of faces - */ - //================================================================================ - - UnitTetraIntersectionBary::~UnitTetraIntersectionBary() - { - clearPolygons(/*andFaces=*/true ); - } - -} diff --git a/src/INTERP_KERNEL/UnitTetraIntersectionBary.hxx b/src/INTERP_KERNEL/UnitTetraIntersectionBary.hxx deleted file mode 100644 index c1446832d..000000000 --- a/src/INTERP_KERNEL/UnitTetraIntersectionBary.hxx +++ /dev/null @@ -1,81 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 -// 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 -// - -// File : UnitTetraIntersectionBary.hxx -// Created : Tue Dec 9 16:06:33 2008 -// Author : Edward AGAPOV (eap) -// -#ifndef __UNITTETRAINTERSECTIONBARY_HXX__ -#define __UNITTETRAINTERSECTIONBARY_HXX__ - -#include "TransformedTriangle.hxx" -#include "INTERPKERNELDefines.hxx" - -#include -#include - -namespace INTERP_KERNEL -{ - class UnitTetraIntersectionBary : protected TransformedTriangle - { - public: - INTERPKERNEL_EXPORT UnitTetraIntersectionBary(bool isTetraInversed=false); - - INTERPKERNEL_EXPORT void init(bool isTetraInversed=false); - /*! - * \brief Stores a part of triangle common with the unit tetrahedron - * \param triangle - triangle side of other cell, whose calculateIntersectionVolume() - * must have already been called - */ - INTERPKERNEL_EXPORT void addSide(const TransformedTriangle& triangle); - - /*! - * \brief Computes and return coordinates of barycentre - */ - INTERPKERNEL_EXPORT bool getBary(double* baryCenter); - - /*! - * \brief Returns volume of intersection - * \retval double - - */ - INTERPKERNEL_EXPORT inline double getVolume() const { return _int_volume; } - - INTERPKERNEL_EXPORT virtual ~UnitTetraIntersectionBary(); - - private: - - int addSideFaces(); - - void setTriangleOnSide(int i); - - void clearPolygons(bool andFaces=false); - - /// volume of intersection - double _int_volume; - - /// faces of intersection polyhedron - std::list< std::vector< double* > > _faces; - std::vector< std::vector< double > > _polyNormals; - - bool _isTetraInversed; - }; - -} - -#endif diff --git a/src/INTERP_KERNEL/VTKNormalizedUnstructuredMesh.hxx b/src/INTERP_KERNEL/VTKNormalizedUnstructuredMesh.hxx deleted file mode 100644 index 678ab55db..000000000 --- a/src/INTERP_KERNEL/VTKNormalizedUnstructuredMesh.hxx +++ /dev/null @@ -1,56 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 -// 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 __VTKNORMALIZEDUNSTRUCTUREDMESH_HXX__ -#define __VTKNORMALIZEDUNSTRUCTUREDMESH_HXX__ - -#include "NormalizedUnstructuredMesh.hxx" - -#include "vtkType.h" - -class vtkUnstructuredGrid; - -template -class INTERPKERNEL_EXPORT VTKNormalizedUnstructuredMesh -{ -public: - static const int MY_SPACEDIM=3; - static const int MY_MESHDIM=MESHDIM; - typedef vtkIdType MyConnType; - static const INTERP_KERNEL::NumberingPolicy My_numPol=INTERP_KERNEL::ALL_C_MODE; -public: - VTKNormalizedUnstructuredMesh(vtkUnstructuredGrid *mesh); - ~VTKNormalizedUnstructuredMesh(); - void getBoundingBox(double *boundingBox) const; - NormalizedCellType getTypeOfElement(vtkIdType eltId) const; - unsigned long getNumberOfElements() const; - unsigned long getNumberOfNodes() const; - const vtkIdType *getConnectivityPtr() const; - const double *getCoordinatesPtr() const; - const vtkIdType *getConnectivityIndexPtr() const; - void releaseTempArrays(); -protected: - void putinMEDFormat() const; -protected: - vtkUnstructuredGrid *_mesh_in_vtk_mode; - mutable vtkIdType *_tmp_index_array; -}; - -#endif diff --git a/src/INTERP_KERNEL/VTKNormalizedUnstructuredMesh.txx b/src/INTERP_KERNEL/VTKNormalizedUnstructuredMesh.txx deleted file mode 100644 index 96482ff7e..000000000 --- a/src/INTERP_KERNEL/VTKNormalizedUnstructuredMesh.txx +++ /dev/null @@ -1,133 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 -// 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 __VTKNORMALIZEDUNSTRUCTUREDMESH_TXX__ -#define __VTKNORMALIZEDUNSTRUCTUREDMESH_TXX__ - -#include "VTKNormalizedUnstructuredMesh.hxx" - -#include "vtkUnstructuredGrid.h" -#include "vtkCellArray.h" -#include "vtkPoints.h" - -template -VTKNormalizedUnstructuredMesh::VTKNormalizedUnstructuredMesh(vtkUnstructuredGrid *mesh):_mesh_in_vtk_mode(mesh), - _tmp_index_array(0) -{ -} - -template -VTKNormalizedUnstructuredMesh::~VTKNormalizedUnstructuredMesh() -{ - _mesh_in_vtk_mode->Delete(); - releaseTempArrays(); -} - -template -void VTKNormalizedUnstructuredMesh::getBoundingBox(double *boundingBox) const -{ - double tmp[6]; - _mesh_in_vtk_mode->GetBounds(tmp); - for(unsigned i=0;i<3;i++) - { - boundingBox[i]=tmp[2*i]; - boundingBox[3+i]=tmp[2*i+1]; - } -} - -template -NormalizedCellType VTKNormalizedUnstructuredMesh::getTypeOfElement(vtkIdType eltId) const -{ - int cellType=_mesh_in_vtk_mode->GetCellType(eltId); - int convTab[30]={0,0,0,0,0,(int)NORM_TRI3,0,(int)NORM_POLYGON,0,(int)NORM_QUAD4,(int)NORM_TETRA4,0,(int)NORM_HEXA8 - 0,(int)NORM_PYRA5,0,0,0,(int)NORM_TRI6,(int)NORM_QUAD8,}; -} - -template -unsigned long VTKNormalizedUnstructuredMesh::getNumberOfElements() const -{ - return _mesh_in_vtk_mode->GetNumberOfCells(); -} - -template -unsigned long VTKNormalizedUnstructuredMesh::getNumberOfNodes() const -{ - return _mesh_in_vtk_mode->GetNumberOfPoints(); -} - -template -const vtkIdType *VTKNormalizedUnstructuredMesh::getConnectivityPtr() const -{ - vtkIdType *ret=_mesh_in_vtk_mode->GetCells()->GetPointer(); - if(_tmp_index_array) - return ret; - else - { - putinMEDFormat(); - return ret; - } -} - -template -const double *VTKNormalizedUnstructuredMesh::getCoordinatesPtr() const -{ - return (const double *)_mesh_in_vtk_mode->GetPoints()->GetVoidPointer(0); -} - -template -const vtkIdType *VTKNormalizedUnstructuredMesh::getConnectivityIndexPtr() const -{ - if(_tmp_index_array) - return _tmp_index_array; - else - { - putinMEDFormat(); - return _tmp_index_array; - } -} - -template -void VTKNormalizedUnstructuredMesh::putinMEDFormat() const -{ - long nbOfElem=getNumberOfElements(); - _tmp_index_array=new vtkIdType[nbOfElem+1]; - _tmp_index_array[0]=0; - vtkIdType *coarseConn=_mesh_in_vtk_mode->GetCells()->GetPointer(); - long ptInCC=0; - vtkIdType *finalConn=coarseConn; - for(long i=0;i -void VTKNormalizedUnstructuredMesh::releaseTempArrays() -{ - delete [] _tmp_index_array; - _tmp_index_array=0; -} - -#endif diff --git a/src/INTERP_KERNEL/VectorUtils.hxx b/src/INTERP_KERNEL/VectorUtils.hxx deleted file mode 100644 index 21d69803a..000000000 --- a/src/INTERP_KERNEL/VectorUtils.hxx +++ /dev/null @@ -1,175 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 -// 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 __VECTORUTILS_HXX__ -#define __VECTORUTILS_HXX__ - -#include -#include -#include -#include -#include - -namespace INTERP_KERNEL -{ - /// Precision used for tests of 3D part of INTERP_KERNEL - const double VOL_PREC = 1.0e-6; - - /// Default relative tolerance in epsilonEqualRelative - const double DEFAULT_REL_TOL = 1.0e-6; - - /// Default absolute tolerance in epsilonEqual and epsilonEqualRelative - const double DEFAULT_ABS_TOL = 5.0e-12; - - /** - * @param a first point. Should point on a array of size at least equal to SPACEDIM. - * @param b second point. Should point on a array of size at least equal to SPACEDIM. - */ - template - inline double getDistanceBtw2Pts(const double *a, const double *b) - { - double ret2=0.; - for(int i=0;i -#include - -namespace INTERP_KERNEL -{ - inline void calculateBarycenterDyn(const double **pts, int nbPts, - int dim, double *bary); - - inline double calculateAreaForPolyg(const double **coords, int nbOfPtsInPolygs, - int spaceDim); - - - inline double calculateAreaForQPolyg(const double **coords, int nbOfPtsInPolygs, - int spaceDim); - - inline double calculateLgthForSeg2(const double *p1, const double *p2, int spaceDim) - { - if(spaceDim==1) - return *p2-*p1; - else - { - double ret=0; - for(int i=0;igetCurveLength(); ed->decrRef(); - return ret; - } - else - return calculateLgthForSeg2(begin,end,spaceDim); - } - - // =========================== - // Calculate Area for triangle - // =========================== - inline double calculateAreaForTria(const double *p1, const double *p2, - const double *p3, int spaceDim) - { - double area ; - - if ( spaceDim == 2 ) - { - area = -((p2[0]-p1[0])*(p3[1]-p1[1]) - (p3[0]-p1[0])*(p2[1]-p1[1]))/2.0; - } - else - { - area = sqrt(((p2[1]-p1[1])*(p3[2]-p1[2]) - (p3[1]-p1[1])*(p2[2]-p1[2]))* - ((p2[1]-p1[1])*(p3[2]-p1[2]) - (p3[1]-p1[1])*(p2[2]-p1[2])) - + - ((p3[0]-p1[0])*(p2[2]-p1[2]) - (p2[0]-p1[0])*(p3[2]-p1[2]))* - ((p3[0]-p1[0])*(p2[2]-p1[2]) - (p2[0]-p1[0])*(p3[2]-p1[2])) - + - ((p2[0]-p1[0])*(p3[1]-p1[1]) - (p3[0]-p1[0])*(p2[1]-p1[1]))* - ((p2[0]-p1[0])*(p3[1]-p1[1]) - (p3[0]-p1[0])*(p2[1]-p1[1])))/2.0; - } - - return area ; - } - - // ============================= - // Calculate Area for quadrangle - // ============================= - inline double calculateAreaForQuad(const double *p1, const double *p2, - const double *p3, const double *p4, - int spaceDim) - { - double area ; - - if (spaceDim==2) - { - double a1 = (p2[0]-p1[0])/4.0, a2 = (p2[1]-p1[1])/4.0; - double b1 = (p3[0]-p4[0])/4.0, b2 = (p3[1]-p4[1])/4.0; - double c1 = (p3[0]-p2[0])/4.0, c2 = (p3[1]-p2[1])/4.0; - double d1 = (p4[0]-p1[0])/4.0, d2 = (p4[1]-p1[1])/4.0; - - area = - 4.0*( b1*c2 - c1*b2 + a1*c2 - c1*a2 - + b1*d2 - d1*b2 + a1*d2 - d1*a2); - } - else - { - area = (sqrt(((p2[1]-p1[1])*(p4[2]-p1[2]) - (p4[1]-p1[1])*(p2[2]-p1[2]))* - ((p2[1]-p1[1])*(p4[2]-p1[2]) - (p4[1]-p1[1])*(p2[2]-p1[2])) - + ((p4[0]-p1[0])*(p2[2]-p1[2]) - (p2[0]-p1[0])*(p4[2]-p1[2]))* - ((p4[0]-p1[0])*(p2[2]-p1[2]) - (p2[0]-p1[0])*(p4[2]-p1[2])) - + ((p2[0]-p1[0])*(p4[1]-p1[1]) - (p4[0]-p1[0])*(p2[1]-p1[1]))* - ((p2[0]-p1[0])*(p4[1]-p1[1]) - (p4[0]-p1[0])*(p2[1]-p1[1]))) - + - sqrt(((p4[1]-p3[1])*(p2[2]-p3[2]) - (p2[1]-p3[1])*(p4[2]-p3[2]))* - ((p4[1]-p3[1])*(p2[2]-p3[2]) - (p2[1]-p3[1])*(p4[2]-p3[2])) - + ((p2[0]-p3[0])*(p4[2]-p3[2]) - (p4[0]-p3[0])*(p2[2]-p3[2]))* - ((p2[0]-p3[0])*(p4[2]-p3[2]) - (p4[0]-p3[0])*(p2[2]-p3[2])) - + ((p4[0]-p3[0])*(p2[1]-p3[1]) - (p2[0]-p3[0])*(p4[1]-p3[1]))* - ((p4[0]-p3[0])*(p2[1]-p3[1]) - (p2[0]-p3[0])*(p4[1]-p3[1]))) - )/2.0; - } - - return area ; - } - - // ==================================== - // Calculate Normal Vector for Triangle - // ==================================== - inline void calculateNormalForTria(const double *p1, const double *p2, - const double *p3, double *normal) - { - normal[0] = ((p2[1]-p1[1])*(p3[2]-p1[2]) - (p3[1]-p1[1])*(p2[2]-p1[2]))/2.0; - normal[1] = ((p3[0]-p1[0])*(p2[2]-p1[2]) - (p2[0]-p1[0])*(p3[2]-p1[2]))/2.0; - normal[2] = ((p2[0]-p1[0])*(p3[1]-p1[1]) - (p3[0]-p1[0])*(p2[1]-p1[1]))/2.0; - } - - // ====================================== - // Calculate Normal Vector for Quadrangle - // ====================================== - inline void calculateNormalForQuad(const double *p1, const double *p2, - const double *p3, const double *p4, - double *normal) - { - double xnormal1 = (p2[1]-p1[1])*(p4[2]-p1[2]) - (p4[1]-p1[1])*(p2[2]-p1[2]); - double xnormal2 = (p4[0]-p1[0])*(p2[2]-p1[2]) - (p2[0]-p1[0])*(p4[2]-p1[2]); - double xnormal3 = (p2[0]-p1[0])*(p4[1]-p1[1]) - (p4[0]-p1[0])*(p2[1]-p1[1]); - double xarea = sqrt(xnormal1*xnormal1 + xnormal2*xnormal2 + xnormal3*xnormal3); - xnormal1 = xnormal1/xarea; - xnormal2 = xnormal2/xarea; - xnormal3 = xnormal3/xarea; - xarea = calculateAreaForQuad(p1,p2,p3,p4,3); - normal[0] = xnormal1*xarea ; - normal[1] = xnormal2*xarea ; - normal[2] = xnormal3*xarea ; - } - - // =================================== - // Calculate Normal Vector for Polygon - // =================================== - inline void calculateNormalForPolyg(const double **coords, int nbOfPtsInPolygs, - double *normal) - { - double coordOfBary[3]; - - calculateBarycenterDyn(coords,nbOfPtsInPolygs,3,coordOfBary); - double xnormal1 = (coords[0][1]-coords[1][1]) * (coordOfBary[2]-coords[1][2]) - - (coords[0][2]-coords[1][2]) * (coordOfBary[1]-coords[1][1]); - - double xnormal2 = (coords[0][2]-coords[1][2]) * (coordOfBary[0]-coords[1][0]) - - (coords[0][0]-coords[1][0]) * (coordOfBary[2]-coords[1][2]); - - double xnormal3 = (coords[0][0]-coords[1][0]) * (coordOfBary[1]-coords[1][1]) - - (coords[0][1]-coords[1][1]) * (coordOfBary[0]-coords[1][0]); - - double xarea=sqrt(xnormal1*xnormal1 + xnormal2*xnormal2 + xnormal3*xnormal3); - - if ( xarea < 1.e-6 ) - { - //std::string diagnosis"Can not calculate normal - polygon is singular"; - throw std::exception(); - } - - xnormal1 = -xnormal1/xarea; - xnormal2 = -xnormal2/xarea; - xnormal3 = -xnormal3/xarea; - xarea = calculateAreaForPolyg(coords,nbOfPtsInPolygs,3); - normal[0] = xnormal1*xarea ; - normal[1] = xnormal2*xarea ; - normal[2] = xnormal3*xarea ; - } - - // ========================== - // Calculate Area for Polygon - // ========================== - inline double calculateAreaForPolyg(const double **coords, int nbOfPtsInPolygs, - int spaceDim) - { - double ret=0.; - double coordOfBary[3]; - - calculateBarycenterDyn(coords,nbOfPtsInPolygs,spaceDim,coordOfBary); - for ( int i=0; i nodes(nbOfPtsInPolygs); - for(int i=0;igetArea(); - delete pol; - return -ret; - } - else - return calculateAreaForPolyg(coords,nbOfPtsInPolygs/2,spaceDim); - } - else - { - std::ostringstream oss; oss << "INTERP_KERNEL::calculateAreaForQPolyg : nb of points in quadratic polygon is " << nbOfPtsInPolygs << " should be even !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - } - - // ========================== - // Calculate Volume for Tetra - // ========================== - inline double calculateVolumeForTetra(const double *p1, const double *p2, - const double *p3, const double *p4) - { - return ( (p3[0]-p1[0])*( (p2[1]-p1[1])*(p4[2]-p1[2]) - - (p2[2]-p1[2])*(p4[1]-p1[1]) ) - - (p2[0]-p1[0])*( (p3[1]-p1[1])*(p4[2]-p1[2]) - - (p3[2]-p1[2])*(p4[1]-p1[1]) ) - + (p4[0]-p1[0])*( (p3[1]-p1[1])*(p2[2]-p1[2]) - - (p3[2]-p1[2])*(p2[1]-p1[1]) ) - ) / 6.0 ; - } - - // ========================= - // Calculate Volume for Pyra - // ========================= - inline double calculateVolumeForPyra(const double *p1, const double *p2, - const double *p3, const double *p4, - const double *p5) - { - return ( ((p3[0]-p1[0])*( (p2[1]-p1[1])*(p5[2]-p1[2]) - - (p2[2]-p1[2])*(p5[1]-p1[1]) ) - -(p2[0]-p1[0])*( (p3[1]-p1[1])*(p5[2]-p1[2]) - - (p3[2]-p1[2])*(p5[1]-p1[1]) ) - +(p5[0]-p1[0])*( (p3[1]-p1[1])*(p2[2]-p1[2]) - - (p3[2]-p1[2])*(p2[1]-p1[1]) )) - + - ((p4[0]-p1[0])*( (p3[1]-p1[1])*(p5[2]-p1[2]) - - (p3[2]-p1[2])*(p5[1]-p1[1]) ) - -(p3[0]-p1[0])*( (p4[1]-p1[1])*(p5[2]-p1[2]) - - (p4[2]-p1[2])*(p5[1]-p1[1])) - +(p5[0]-p1[0])*( (p4[1]-p1[1])*(p3[2]-p1[2]) - - (p4[2]-p1[2])*(p3[1]-p1[1]) )) - ) / 6.0 ; - } - - // ========================== - // Calculate Volume for Penta - // ========================== - inline double calculateVolumeForPenta(const double *p1, const double *p2, - const double *p3, const double *p4, - const double *p5, const double *p6) - { - double a1 = (p2[0]-p3[0])/2.0, a2 = (p2[1]-p3[1])/2.0, a3 = (p2[2]-p3[2])/2.0; - double b1 = (p5[0]-p6[0])/2.0, b2 = (p5[1]-p6[1])/2.0, b3 = (p5[2]-p6[2])/2.0; - double c1 = (p4[0]-p1[0])/2.0, c2 = (p4[1]-p1[1])/2.0, c3 = (p4[2]-p1[2])/2.0; - double d1 = (p5[0]-p2[0])/2.0, d2 = (p5[1]-p2[1])/2.0, d3 = (p5[2]-p2[2])/2.0; - double e1 = (p6[0]-p3[0])/2.0, e2 = (p6[1]-p3[1])/2.0, e3 = (p6[2]-p3[2])/2.0; - double f1 = (p1[0]-p3[0])/2.0, f2 = (p1[1]-p3[1])/2.0, f3 = (p1[2]-p3[2])/2.0; - double h1 = (p4[0]-p6[0])/2.0, h2 = (p4[1]-p6[1])/2.0, h3 = (p4[2]-p6[2])/2.0; - - double A = a1*c2*f3 - a1*c3*f2 - a2*c1*f3 + a2*c3*f1 + a3*c1*f2 - a3*c2*f1; - double B = b1*c2*h3 - b1*c3*h2 - b2*c1*h3 + b2*c3*h1 + b3*c1*h2 - b3*c2*h1; - double C = (a1*c2*h3 + b1*c2*f3) - (a1*c3*h2 + b1*c3*f2) - - (a2*c1*h3 + b2*c1*f3) + (a2*c3*h1 + b2*c3*f1) - + (a3*c1*h2 + b3*c1*f2) - (a3*c2*h1 + b3*c2*f1); - double D = a1*d2*f3 - a1*d3*f2 - a2*d1*f3 + a2*d3*f1 + a3*d1*f2 - a3*d2*f1; - double E = b1*d2*h3 - b1*d3*h2 - b2*d1*h3 + b2*d3*h1 + b3*d1*h2 - b3*d2*h1; - double F = (a1*d2*h3 + b1*d2*f3) - (a1*d3*h2 + b1*d3*f2) - - (a2*d1*h3 + b2*d1*f3) + (a2*d3*h1 + b2*d3*f1) - + (a3*d1*h2 + b3*d1*f2) - (a3*d2*h1 + b3*d2*f1); - double G = a1*e2*f3 - a1*e3*f2 - a2*e1*f3 + a2*e3*f1 + a3*e1*f2 - a3*e2*f1; - double H = b1*e2*h3 - b1*e3*h2 - b2*e1*h3 + b2*e3*h1 + b3*e1*h2 - b3*e2*h1; - double P = (a1*e2*h3 + b1*e2*f3) - (a1*e3*h2 + b1*e3*f2) - - (a2*e1*h3 + b2*e1*f3) + (a2*e3*h1 + b2*e3*f1) - + (a3*e1*h2 + b3*e1*f2) - (a3*e2*h1 + b3*e2*f1); - - return (-2.0*(2.0*(A + B + D + E + G + H) + C + F + P)/9.0); - } - - // ========================= - // Calculate Volume for Hexa - // ========================= - inline double calculateVolumeForHexa(const double *pt1, const double *pt2, - const double *pt3, const double *pt4, - const double *pt5, const double *pt6, - const double *pt7, const double *pt8) - { - double a1=(pt3[0]-pt4[0])/8.0, a2=(pt3[1]-pt4[1])/8.0, a3=(pt3[2]-pt4[2])/8.0; - double b1=(pt2[0]-pt1[0])/8.0, b2=(pt2[1]-pt1[1])/8.0, b3=(pt2[2]-pt1[2])/8.0; - double c1=(pt7[0]-pt8[0])/8.0, c2=(pt7[1]-pt8[1])/8.0, c3=(pt7[2]-pt8[2])/8.0; - double d1=(pt6[0]-pt5[0])/8.0, d2=(pt6[1]-pt5[1])/8.0, d3=(pt6[2]-pt5[2])/8.0; - double e1=(pt3[0]-pt2[0])/8.0, e2=(pt3[1]-pt2[1])/8.0, e3=(pt3[2]-pt2[2])/8.0; - double f1=(pt4[0]-pt1[0])/8.0, f2=(pt4[1]-pt1[1])/8.0, f3=(pt4[2]-pt1[2])/8.0; - double h1=(pt7[0]-pt6[0])/8.0, h2=(pt7[1]-pt6[1])/8.0, h3=(pt7[2]-pt6[2])/8.0; - double p1=(pt8[0]-pt5[0])/8.0, p2=(pt8[1]-pt5[1])/8.0, p3=(pt8[2]-pt5[2])/8.0; - double q1=(pt3[0]-pt7[0])/8.0, q2=(pt3[1]-pt7[1])/8.0, q3=(pt3[2]-pt7[2])/8.0; - double r1=(pt4[0]-pt8[0])/8.0, r2=(pt4[1]-pt8[1])/8.0, r3=(pt4[2]-pt8[2])/8.0; - double s1=(pt2[0]-pt6[0])/8.0, s2=(pt2[1]-pt6[1])/8.0, s3=(pt2[2]-pt6[2])/8.0; - double t1=(pt1[0]-pt5[0])/8.0, t2=(pt1[1]-pt5[1])/8.0, t3=(pt1[2]-pt5[2])/8.0; - - double A = a1*e2*q3 - a1*e3*q2 - a2*e1*q3 + a2*e3*q1 + a3*e1*q2 - a3*e2*q1; - double B = c1*h2*q3 - c1*h3*q2 - c2*h1*q3 + c2*h3*q1 + c3*h1*q2 - c3*h2*q1; - double C = (a1*h2 + c1*e2)*q3 - (a1*h3 + c1*e3)*q2 - - (a2*h1 + c2*e1)*q3 + (a2*h3 + c2*e3)*q1 - + (a3*h1 + c3*e1)*q2 - (a3*h2 + c3*e2)*q1; - double D = b1*e2*s3 - b1*e3*s2 - b2*e1*s3 + b2*e3*s1 + b3*e1*s2 - b3*e2*s1; - double E = d1*h2*s3 - d1*h3*s2 - d2*h1*s3 + d2*h3*s1 + d3*h1*s2 - d3*h2*s1; - double F = (b1*h2 + d1*e2)*s3 - (b1*h3 + d1*e3)*s2 - - (b2*h1 + d2*e1)*s3 + (b2*h3 + d2*e3)*s1 - + (b3*h1 + d3*e1)*s2 - (b3*h2 + d3*e2)*s1; - double G = (a1*e2*s3 + b1*e2*q3) - (a1*e3*s2 + b1*e3*q2) - - (a2*e1*s3 + b2*e1*q3) + (a2*e3*s1 + b2*e3*q1) - + (a3*e1*s2 + b3*e1*q2) - (a3*e2*s1 + b3*e2*q1); - double H = (c1*h2*s3 + d1*h2*q3) - (c1*h3*s2 + d1*h3*q2) - - (c2*h1*s3 + d2*h1*q3) + (c2*h3*s1 + d2*h3*q1) - + (c3*h1*s2 + d3*h1*q2) - (c3*h2*s1 + d3*h2*q1); - double I = ((a1*h2 + c1*e2)*s3 + (b1*h2 + d1*e2)*q3) - - ((a1*h3 + c1*e3)*s2 + (b1*h3 + d1*e3)*q2) - - ((a2*h1 + c2*e1)*s3 + (b2*h1 + d2*e1)*q3) - + ((a2*h3 + c2*e3)*s1 + (b2*h3 + d2*e3)*q1) - + ((a3*h1 + c3*e1)*s2 + (b3*h1 + d3*e1)*q2) - - ((a3*h2 + c3*e2)*s1 + (b3*h2 + d3*e2)*q1); - double J = a1*f2*r3 - a1*f3*r2 - a2*f1*r3 + a2*f3*r1 + a3*f1*r2 - a3*f2*r1; - double K = c1*p2*r3 - c1*p3*r2 - c2*p1*r3 + c2*p3*r1 + c3*p1*r2 - c3*p2*r1; - double L = (a1*p2 + c1*f2)*r3 - (a1*p3 + c1*f3)*r2 - - (a2*p1 + c2*f1)*r3 + (a2*p3 + c2*f3)*r1 - + (a3*p1 + c3*f1)*r2 - (a3*p2 + c3*f2)*r1; - double M = b1*f2*t3 - b1*f3*t2 - b2*f1*t3 + b2*f3*t1 + b3*f1*t2 - b3*f2*t1; - double N = d1*p2*t3 - d1*p3*t2 - d2*p1*t3 + d2*p3*t1 + d3*p1*t2 - d3*p2*t1; - double O = (b1*p2 + d1*f2)*t3 - (b1*p3 + d1*f3)*t2 - - (b2*p1 + d2*f1)*t3 + (b2*p3 + d2*f3)*t1 - + (b3*p1 + d3*f1)*t2 - (b3*p2 + d3*f2)*t1; - double P = (a1*f2*t3 + b1*f2*r3) - (a1*f3*t2 + b1*f3*r2) - - (a2*f1*t3 + b2*f1*r3) + (a2*f3*t1 + b2*f3*r1) - + (a3*f1*t2 + b3*f1*r2) - (a3*f2*t1 + b3*f2*r1); - double Q = (c1*p2*t3 + d1*p2*r3) - (c1*p3*t2 + d1*p3*r2) - - (c2*p1*t3 + d2*p1*r3) + (c2*p3*t1 + d2*p3*r1) - + (c3*p1*t2 + d3*p1*r2) - (c3*p2*t1 + d3*p2*r1); - double R = ((a1*p2 + c1*f2)*t3 + (b1*p2 + d1*f2)*r3) - - ((a1*p3 + c1*f3)*t2 + (b1*p3 + d1*f3)*r2) - - ((a2*p1 + c2*f1)*t3 + (b2*p1 + d2*f1)*r3) - + ((a2*p3 + c2*f3)*t1 + (b2*p3 + d2*f3)*r1) - + ((a3*p1 + c3*f1)*t2 + (b3*p1 + d3*f1)*r2) - - ((a3*p2 + c3*f2)*t1 + (b3*p2 + d3*f2)*r1); - double S = (a1*e2*r3 + a1*f2*q3) - (a1*e3*r2 + a1*f3*q2) - - (a2*e1*r3 + a2*f1*q3) + (a2*e3*r1 + a2*f3*q1) - + (a3*e1*r2 + a3*f1*q2) - (a3*e2*r1 + a3*f2*q1); - double T = (c1*h2*r3 + c1*p2*q3) - (c1*h3*r2 + c1*p3*q2) - - (c2*h1*r3 + c2*p1*q3) + (c2*h3*r1 + c2*p3*q1) - + (c3*h1*r2 + c3*p1*q2) - (c3*h2*r1 + c3*p2*q1); - double U = ((a1*h2 + c1*e2)*r3 + (a1*p2 + c1*f2)*q3) - - ((a1*h3 + c1*e3)*r2 + (a1*p3 + c1*f3)*q2) - - ((a2*h1 + c2*e1)*r3 + (a2*p1 + c2*f1)*q3) - + ((a2*h3 + c2*e3)*r1 + (a2*p3 + c2*f3)*q1) - + ((a3*h1 + c3*e1)*r2 + (a3*p1 + c3*f1)*q2) - - ((a3*h2 + c3*e2)*r1 + (a3*p2 + c3*f2)*q1); - double V = (b1*e2*t3 + b1*f2*s3) - (b1*e3*t2 + b1*f3*s2) - - (b2*e1*t3 + b2*f1*s3) + (b2*e3*t1 + b2*f3*s1) - + (b3*e1*t2 + b3*f1*s2) - (b3*e2*t1 + b3*f2*s1); - double W = (d1*h2*t3 + d1*p2*s3) - (d1*h3*t2 + d1*p3*s2) - - (d2*h1*t3 + d2*p1*s3) + (d2*h3*t1 + d2*p3*s1) - + (d3*h1*t2 + d3*p1*s2) - (d3*h2*t1 + d3*p2*s1); - double X = ((b1*h2 + d1*e2)*t3 + (b1*p2 + d1*f2)*s3) - - ((b1*h3 + d1*e3)*t2 + (b1*p3 + d1*f3)*s2) - - ((b2*h1 + d2*e1)*t3 + (b2*p1 + d2*f1)*s3) - + ((b2*h3 + d2*e3)*t1 + (b2*p3 + d2*f3)*s1) - + ((b3*h1 + d3*e1)*t2 + (b3*p1 + d3*f1)*s2) - - ((b3*h2 + d3*e2)*t1 + (b3*p2 + d3*f2)*s1); - double Y = (a1*e2*t3 + a1*f2*s3 + b1*e2*r3 + b1*f2*q3) - - (a1*e3*t2 + a1*f3*s2 + b1*e3*r2 + b1*f3*q2) - - (a2*e1*t3 + a2*f1*s3 + b2*e1*r3 + b2*f1*q3) - + (a2*e3*t1 + a2*f3*s1 + b2*e3*r1 + b2*f3*q1) - + (a3*e1*t2 + a3*f1*s2 + b3*e1*r2 + b3*f1*q2) - - (a3*e2*t1 + a3*f2*s1 + b3*e2*r1 + b3*f2*q1); - double Z = (c1*h2*t3 + c1*p2*s3 + d1*h2*r3 + d1*p2*q3) - - (c1*h3*t2 + c1*p3*s2 + d1*h3*r2 + d1*p3*q2) - - (c2*h1*t3 + c2*p1*s3 + d2*h1*r3 + d2*p1*q3) - + (c2*h3*t1 + c2*p3*s1 + d2*h3*r1 + d2*p3*q1) - + (c3*h1*t2 + c3*p1*s2 + d3*h1*r2 + d3*p1*q2) - - (c3*h2*t1 + c3*p2*s1 + d3*h2*r1 + d3*p2*q1); - double AA = ((a1*h2 + c1*e2)*t3 + (a1*p2 + c1*f2)*s3 - +(b1*h2 + d1*e2)*r3 + (b1*p2 + d1*f2)*q3) - - ((a1*h3 + c1*e3)*t2 + (a1*p3 + c1*f3)*s2 - +(b1*h3 + d1*e3)*r2 + (b1*p3 + d1*f3)*q2) - - ((a2*h1 + c2*e1)*t3 + (a2*p1 + c2*f1)*s3 - +(b2*h1 + d2*e1)*r3 + (b2*p1 + d2*f1)*q3) - + ((a2*h3 + c2*e3)*t1 + (a2*p3 + c2*f3)*s1 - +(b2*h3 + d2*e3)*r1 + (b2*p3 + d2*f3)*q1) - + ((a3*h1 + c3*e1)*t2 + (a3*p1 + c3*f1)*s2 - +(b3*h1 + d3*e1)*r2 + (b3*p1 + d3*f1)*q2) - - ((a3*h2 + c3*e2)*t1 + (a3*p2 + c3*f2)*s1 - + (b3*h2 + d3*e2)*r1 + (b3*p2 + d3*f2)*q1); - - return 64.0*( 8.0*(A + B + D + E + J + K + M + N) - + 4.0*(C + F + G + H + L + O + P + Q + S + T + V + W) - + 2.0*(I + R + U + X + Y + Z) + AA ) / 27.0 ; - } - - // ========================================================================================================================= - // Calculate Volume for Generic Polyedron, even not convex one, WARNING !!! The polyedron's faces must be correctly ordered - // ========================================================================================================================= - inline double calculateVolumeForPolyh(const double ***pts, - const int *nbOfNodesPerFaces, - int nbOfFaces, - const double *bary) - { - double volume=0.; - - for ( int i=0; i - inline double calculateVolumeForPolyh2(const ConnType *connec, int lgth, const double *coords) - { - std::size_t nbOfFaces=std::count(connec,connec+lgth,-1)+1; - double volume=0.; - const int *work=connec; - for(std::size_t iFace=0;iFace::coo2C(work[ptId]); - const double *pti1=coords+3*OTT::coo2C(work[(ptId+1)%nbOfNodesOfCurFace]); - areaVector[0]+=pti[1]*pti1[2]-pti[2]*pti1[1]; - areaVector[1]+=pti[2]*pti1[0]-pti[0]*pti1[2]; - areaVector[2]+=pti[0]*pti1[1]-pti[1]*pti1[0]; - } - const double *pt=coords+3*work[0]; - volume+=pt[0]*areaVector[0]+pt[1]*areaVector[1]+pt[2]*areaVector[2]; - work=work2+1; - } - return volume/6.; - } - - /*! - * This method returns the area oriented vector of a polygon. This method is useful for normal computation without - * any troubles if several edges are colinears. - * @param res must be of size at least 3 to store the result. - */ - template - inline void areaVectorOfPolygon(const ConnType *connec, int lgth, const double *coords, double *res) - { - res[0]=0.; res[1]=0.; res[2]=0.; - for(int ptId=0;ptId::coo2C(connec[ptId]); - const double *pti1=coords+3*OTT::coo2C(connec[(ptId+1)%lgth]); - res[0]+=pti[1]*pti1[2]-pti[2]*pti1[1]; - res[1]+=pti[2]*pti1[0]-pti[0]*pti1[2]; - res[2]+=pti[0]*pti1[1]-pti[1]*pti1[0]; - } - } - - 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))+ - 4.*C*(A*(2*u1*v1+u2*v1+u1*v2+2.*u2*v2)+B*(v1*v1+v1*v2+v2*v2))+A*B*(u1*(3.*v1*v1+2.*v1*v2+v2*v2)+u2*(v1*v1+2.*v1*v2+3.*v2*v2)))/24.; - } - - template - inline void barycenterOfPolyhedron(const ConnType *connec, int lgth, const double *coords, double *res) - { - std::size_t nbOfFaces=std::count(connec,connec+lgth,-1)+1; - res[0]=0.; res[1]=0.; res[2]=0.; - const int *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; - 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]); - double c=normal[2]; - if(fabs(s)>1e-12) - { - u[0]/=std::abs(s); u[1]/=std::abs(s); - } - else - { u[0]=1.; u[1]=0.; } - //C : high in plane of polyhedron face : always constant - double w=normal[0]*coords[3*OTT::coo2C(work[0])]+ - normal[1]*coords[3*OTT::coo2C(work[0])+1]+ - normal[2]*coords[3*OTT::coo2C(work[0])+2]; - // A,B,D,F,G,H,L,M,N coeffs of rotation matrix defined by (u,c,s) - double A=u[0]*u[0]*(1-c)+c; - double B=u[0]*u[1]*(1-c); - double D=u[1]*s; - double F=B; - double G=u[1]*u[1]*(1-c)+c; - double H=-u[0]*s; - double L=-u[1]*s; - double M=u[0]*s; - double N=c; - double CX=-w*D; - double CY=-w*H; - double CZ=-w*N; - for(int j=0;j::coo2C(work[j]); - const double *p2=coords+3*OTT::coo2C(work[(j+1)%nbOfNodesOfCurFace]); - double u1=A*p1[0]+B*p1[1]+D*p1[2]; - double u2=A*p2[0]+B*p2[1]+D*p2[2]; - double v1=F*p1[0]+G*p1[1]+H*p1[2]; - double v2=F*p2[0]+G*p2[1]+H*p2[2]; - // - double gx=integrationOverA3DLine(u1,v1,u2,v2,A,B,CX); - double gy=integrationOverA3DLine(u1,v1,u2,v2,F,G,CY); - double gz=integrationOverA3DLine(u1,v1,u2,v2,L,M,CZ); - res[0]+=gx*normal[0]; - res[1]+=gy*normal[1]; - res[2]+=gz*normal[2]; - } - work=work2+1; - } - double vol=calculateVolumeForPolyh2(connec,lgth,coords); - 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; - } - } - - // ============================================================================================================================================ - // Calculate Volume for NON Generic Polyedron. Only polydrons with bary included in pts is supported by this method. Result is always positive. - // ============================================================================================================================================ - inline double calculateVolumeForPolyhAbs(const double ***pts, - const int *nbOfNodesPerFaces, - int nbOfFaces, - const double *bary) - { - double volume=0.; - - for ( int i=0; i - inline double addComponentsOfVec(const double **pts, int rk) - { - return pts[N-1][rk]+addComponentsOfVec(pts,rk); - } - - template<> - inline double addComponentsOfVec<1>(const double **pts, int rk) - { - return pts[0][rk]; - } - - template - inline void calculateBarycenter(const double **pts, double *bary) - { - bary[DIM-1]=addComponentsOfVec(pts,DIM-1)/N; - calculateBarycenter(pts,bary); - } - - template<> - inline void calculateBarycenter<2,0>(const double ** /*pts*/, double * /*bary*/) - { - } - - template<> - inline void calculateBarycenter<3,0>(const double ** /*pts*/, double * /*bary*/) - { - } - - template<> - inline void calculateBarycenter<4,0>(const double ** /*pts*/, double * /*bary*/) - { - } - - template<> - inline void calculateBarycenter<5,0>(const double ** /*pts*/, double * /*bary*/) - { - } - - template<> - inline void calculateBarycenter<6,0>(const double ** /*pts*/, double * /*bary*/) - { - } - - template<> - inline void calculateBarycenter<7,0>(const double ** /*pts*/, double * /*bary*/) - { - } - - template<> - inline void calculateBarycenter<8,0>(const double ** /*pts*/, double * /*bary*/) - { - } - - inline void calculateBarycenterDyn(const double **pts, int nbPts, - int dim, double *bary) - { - for(int i=0;i - inline void calculateBarycenterDyn2(const double *pts, int nbPts, double *bary) - { - for(int i=0;i - inline void computePolygonBarycenter2D(const ConnType *connec, int lgth, const double *coords, double *res) - { - double **coords2=new double *[lgth]; - for(int i=0;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) - { - if(spaceDim==2) - { - 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()); - } - } -} - -#endif diff --git a/src/INTERP_KERNEL/VolSurfUser.cxx b/src/INTERP_KERNEL/VolSurfUser.cxx deleted file mode 100644 index dcbf7b6f4..000000000 --- a/src/INTERP_KERNEL/VolSurfUser.cxx +++ /dev/null @@ -1,137 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 -// 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 -#include - -namespace INTERP_KERNEL -{ - double SquareDistanceFromPtToSegInSpaceDim2(const double *pt, const double *pt0Seg2, const double *pt1Seg2, std::size_t &nbOfHint) - { - 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) - { - 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 - double computeVolSurfOfCell(NormalizedCellType type, const ConnType *connec, int lgth, const double *coords); - - template - double computeVolSurfOfCell2(NormalizedCellType type, const ConnType *connec, int lgth, const double *coords, int spaceDim); - - template - void computeBarycenter(NormalizedCellType type, const ConnType *connec, int lgth, const double *coords, double *res); - - template - void computeBarycenter2(NormalizedCellType type, const ConnType *connec, int lgth, const double *coords, int spaceDim, double *res); - - double INTERPKERNEL_EXPORT SquareDistanceFromPtToSegInSpaceDim2(const double *pt, const double *pt0Seg2, const double *pt1Seg2, std::size_t &nbOfHint); - - double INTERPKERNEL_EXPORT DistanceFromPtToTriInSpaceDim3(const double *pt, const double *pt0Tri3, const double *pt1Tri3, const double *pt2Tri3); - - double INTERPKERNEL_EXPORT DistanceFromPtToPolygonInSpaceDim3(const double *pt, const int *connOfPolygonBg, const int *connOfPolygonEnd, const double *coords); - - 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 deleted file mode 100644 index c3f1aa4b0..000000000 --- a/src/INTERP_KERNEL/VolSurfUser.txx +++ /dev/null @@ -1,438 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 -// 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 __VOLSURFUSER_TXX__ -#define __VOLSURFUSER_TXX__ - -#include "VolSurfUser.hxx" -#include "VolSurfFormulae.hxx" -#include "InterpolationUtils.hxx" - -#include - -namespace INTERP_KERNEL -{ - template - double computeVolSurfOfCell(NormalizedCellType type, const ConnType *connec, int lgth, const double *coords) - { - switch(type) - { - case INTERP_KERNEL::NORM_SEG2 : - 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]); - int N2 = OTT::coo2C(connec[1]); - int N3 = OTT::coo2C(connec[2]); - - return INTERP_KERNEL::calculateAreaForTria(coords+(SPACEDIM*N1), - coords+(SPACEDIM*N2), - coords+(SPACEDIM*N3), - SPACEDIM); - } - break; - - case INTERP_KERNEL::NORM_TRI6 : - case INTERP_KERNEL::NORM_TRI7 : - { - const double *pts[6]; - pts[0] = coords+SPACEDIM*OTT::coo2C(connec[0]); - pts[1] = coords+SPACEDIM*OTT::coo2C(connec[1]); - pts[2] = coords+SPACEDIM*OTT::coo2C(connec[2]); - pts[3] = coords+SPACEDIM*OTT::coo2C(connec[3]); - pts[4] = coords+SPACEDIM*OTT::coo2C(connec[4]); - pts[5] = coords+SPACEDIM*OTT::coo2C(connec[5]); - return INTERP_KERNEL::calculateAreaForQPolyg(pts,6,SPACEDIM); - } - break; - case INTERP_KERNEL::NORM_QUAD4 : - { - int N1 = OTT::coo2C(connec[0]); - int N2 = OTT::coo2C(connec[1]); - int N3 = OTT::coo2C(connec[2]); - int N4 = OTT::coo2C(connec[3]); - - return INTERP_KERNEL::calculateAreaForQuad(coords+SPACEDIM*N1, - coords+SPACEDIM*N2, - coords+SPACEDIM*N3, - coords+SPACEDIM*N4, - SPACEDIM); - } - break; - case INTERP_KERNEL::NORM_QUAD8 : - case INTERP_KERNEL::NORM_QUAD9 : - { - const double *pts[8]; - pts[0] = coords+SPACEDIM*OTT::coo2C(connec[0]); - pts[1] = coords+SPACEDIM*OTT::coo2C(connec[1]); - pts[2] = coords+SPACEDIM*OTT::coo2C(connec[2]); - pts[3] = coords+SPACEDIM*OTT::coo2C(connec[3]); - pts[4] = coords+SPACEDIM*OTT::coo2C(connec[4]); - pts[5] = coords+SPACEDIM*OTT::coo2C(connec[5]); - pts[6] = coords+SPACEDIM*OTT::coo2C(connec[6]); - pts[7] = coords+SPACEDIM*OTT::coo2C(connec[7]); - return INTERP_KERNEL::calculateAreaForQPolyg(pts,8,SPACEDIM); - } - break; - case INTERP_KERNEL::NORM_POLYGON : - { - const double **pts=new const double *[lgth]; - for(int inod=0;inod::coo2C(connec[inod]); - double val=INTERP_KERNEL::calculateAreaForPolyg(pts,lgth,SPACEDIM); - delete [] pts; - return val; - } - break; - case INTERP_KERNEL::NORM_QPOLYG : - { - const double **pts=new const double *[lgth]; - for(int inod=0;inod::coo2C(connec[inod]); - double val=INTERP_KERNEL::calculateAreaForQPolyg(pts,lgth,SPACEDIM); - delete [] pts; - return val; - } - break; - case INTERP_KERNEL::NORM_TETRA4 : - case INTERP_KERNEL::NORM_TETRA10 : - { - int N1 = OTT::coo2C(connec[0]); - int N2 = OTT::coo2C(connec[1]); - int N3 = OTT::coo2C(connec[2]); - int N4 = OTT::coo2C(connec[3]); - - return INTERP_KERNEL::calculateVolumeForTetra(coords+SPACEDIM*N1, - coords+SPACEDIM*N2, - coords+SPACEDIM*N3, - coords+SPACEDIM*N4); - } - break; - - case INTERP_KERNEL::NORM_PYRA5 : - case INTERP_KERNEL::NORM_PYRA13 : - { - int N1 = OTT::coo2C(connec[0]); - int N2 = OTT::coo2C(connec[1]); - int N3 = OTT::coo2C(connec[2]); - int N4 = OTT::coo2C(connec[3]); - int N5 = OTT::coo2C(connec[4]); - - return INTERP_KERNEL::calculateVolumeForPyra(coords+SPACEDIM*N1, - coords+SPACEDIM*N2, - coords+SPACEDIM*N3, - coords+SPACEDIM*N4, - coords+SPACEDIM*N5); - } - break; - - case INTERP_KERNEL::NORM_PENTA6 : - case INTERP_KERNEL::NORM_PENTA15 : - { - int N1 = OTT::coo2C(connec[0]); - int N2 = OTT::coo2C(connec[1]); - int N3 = OTT::coo2C(connec[2]); - int N4 = OTT::coo2C(connec[3]); - int N5 = OTT::coo2C(connec[4]); - int N6 = OTT::coo2C(connec[5]); - - return INTERP_KERNEL::calculateVolumeForPenta(coords+SPACEDIM*N1, - coords+SPACEDIM*N2, - coords+SPACEDIM*N3, - coords+SPACEDIM*N4, - coords+SPACEDIM*N5, - coords+SPACEDIM*N6); - } - break; - - case INTERP_KERNEL::NORM_HEXA8 : - case INTERP_KERNEL::NORM_HEXA20 : - case INTERP_KERNEL::NORM_HEXA27 : - { - int N1 = OTT::coo2C(connec[0]); - int N2 = OTT::coo2C(connec[1]); - int N3 = OTT::coo2C(connec[2]); - int N4 = OTT::coo2C(connec[3]); - int N5 = OTT::coo2C(connec[4]); - int N6 = OTT::coo2C(connec[5]); - int N7 = OTT::coo2C(connec[6]); - int N8 = OTT::coo2C(connec[7]); - - return INTERP_KERNEL::calculateVolumeForHexa(coords+SPACEDIM*N1, - coords+SPACEDIM*N2, - coords+SPACEDIM*N3, - coords+SPACEDIM*N4, - coords+SPACEDIM*N5, - coords+SPACEDIM*N6, - coords+SPACEDIM*N7, - coords+SPACEDIM*N8); - } - break; - case INTERP_KERNEL::NORM_HEXGP12: - { - const int connecHexa12[43]={ - OTT::coo2C(connec[0]),OTT::coo2C(connec[1]),OTT::coo2C(connec[2]),OTT::coo2C(connec[3]),OTT::coo2C(connec[4]),OTT::coo2C(connec[5]),-1, - OTT::coo2C(connec[6]),OTT::coo2C(connec[11]),OTT::coo2C(connec[10]),OTT::coo2C(connec[9]),OTT::coo2C(connec[8]),OTT::coo2C(connec[7]),-1, - OTT::coo2C(connec[0]),OTT::coo2C(connec[6]),OTT::coo2C(connec[7]),OTT::coo2C(connec[1]),-1, - OTT::coo2C(connec[1]),OTT::coo2C(connec[7]),OTT::coo2C(connec[8]),OTT::coo2C(connec[2]),-1, - OTT::coo2C(connec[2]),OTT::coo2C(connec[8]),OTT::coo2C(connec[9]),OTT::coo2C(connec[3]),-1, - OTT::coo2C(connec[3]),OTT::coo2C(connec[9]),OTT::coo2C(connec[10]),OTT::coo2C(connec[4]),-1, - OTT::coo2C(connec[4]),OTT::coo2C(connec[10]),OTT::coo2C(connec[11]),OTT::coo2C(connec[5]),-1, - OTT::coo2C(connec[5]),OTT::coo2C(connec[11]),OTT::coo2C(connec[6]),OTT::coo2C(connec[0])}; - return calculateVolumeForPolyh2(connecHexa12,43,coords); - } - case INTERP_KERNEL::NORM_POLYHED : - { - return calculateVolumeForPolyh2(connec,lgth,coords); - } - break; - default: - throw INTERP_KERNEL::Exception("Not recognized cell type to get Length/Area/Volume on it !"); - } - } - - template - double computeVolSurfOfCell2(NormalizedCellType type, const ConnType *connec, int lgth, const double *coords, int spaceDim) - { - if(spaceDim==3) - return computeVolSurfOfCell(type,connec,lgth,coords); - if(spaceDim==2) - return computeVolSurfOfCell(type,connec,lgth,coords); - if(spaceDim==1) - return computeVolSurfOfCell(type,connec,lgth,coords); - throw INTERP_KERNEL::Exception("Invalid spaceDim specified : must be 1, 2 or 3"); - } - - - template - void computeBarycenter(NormalizedCellType type, const ConnType *connec, int lgth, const double *coords, double *res) - { - switch(type) - { - case NORM_SEG2: - case NORM_SEG4: - { - 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)); - 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_TRI7: - { - 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,coords+SPACEDIM*OTT::coo2C(connec[2]),res,std::plus()); - 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: - { - if(SPACEDIM==2) - computePolygonBarycenter2D(connec,lgth,coords,res); - else if(SPACEDIM==3) - computePolygonBarycenter3D(connec,lgth,coords,res); - else - throw INTERP_KERNEL::Exception("Impossible spacedim linked to cell 2D Cell !"); - break; - } - case NORM_QUAD8: - { - if(SPACEDIM==2) - { - 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])]; - res[1]=coords[3*OTT::coo2C(connec[0])+1]; - res[2]=coords[3*OTT::coo2C(connec[0])+2]; - res[0]+=coords[3*OTT::coo2C(connec[1])]; - res[1]+=coords[3*OTT::coo2C(connec[1])+1]; - res[2]+=coords[3*OTT::coo2C(connec[1])+2]; - res[0]+=coords[3*OTT::coo2C(connec[2])]; - res[1]+=coords[3*OTT::coo2C(connec[2])+1]; - res[2]+=coords[3*OTT::coo2C(connec[2])+2]; - res[0]+=coords[3*OTT::coo2C(connec[3])]; - res[1]+=coords[3*OTT::coo2C(connec[3])+1]; - res[2]+=coords[3*OTT::coo2C(connec[3])+2]; - res[0]*=0.25; res[1]*=0.25; res[2]*=0.25; - break; - } - case NORM_PYRA5: - { - double tmp[3]; - computePolygonBarycenter3D(connec,lgth-1,coords,tmp); - res[0]=(coords[3*OTT::coo2C(connec[4])]+3.*tmp[0])/4.; - res[1]=(coords[3*OTT::coo2C(connec[4])+1]+3.*tmp[1])/4.; - res[2]=(coords[3*OTT::coo2C(connec[4])+2]+3.*tmp[2])/4.; - break; - } - case NORM_HEXA8: - { - const int conn[29]={ - OTT::coo2C(connec[0]),OTT::coo2C(connec[1]),OTT::coo2C(connec[2]),OTT::coo2C(connec[3]),-1, - OTT::coo2C(connec[4]),OTT::coo2C(connec[7]),OTT::coo2C(connec[6]),OTT::coo2C(connec[5]),-1, - OTT::coo2C(connec[0]),OTT::coo2C(connec[3]),OTT::coo2C(connec[7]),OTT::coo2C(connec[4]),-1, - OTT::coo2C(connec[3]),OTT::coo2C(connec[2]),OTT::coo2C(connec[6]),OTT::coo2C(connec[7]),-1, - OTT::coo2C(connec[2]),OTT::coo2C(connec[1]),OTT::coo2C(connec[5]),OTT::coo2C(connec[6]),-1, - OTT::coo2C(connec[0]),OTT::coo2C(connec[4]),OTT::coo2C(connec[5]),OTT::coo2C(connec[1]), - }; - barycenterOfPolyhedron(conn,29,coords,res); - break; - } - case NORM_PENTA6: - { - const int conn[22]={ - OTT::coo2C(connec[0]),OTT::coo2C(connec[1]),OTT::coo2C(connec[2]),-1, - OTT::coo2C(connec[3]),OTT::coo2C(connec[5]),OTT::coo2C(connec[4]),-1, - OTT::coo2C(connec[0]),OTT::coo2C(connec[2]),OTT::coo2C(connec[5]),OTT::coo2C(connec[3]),-1, - OTT::coo2C(connec[2]),OTT::coo2C(connec[1]),OTT::coo2C(connec[4]),OTT::coo2C(connec[5]),-1, - OTT::coo2C(connec[1]),OTT::coo2C(connec[0]),OTT::coo2C(connec[3]),OTT::coo2C(connec[4]) - }; - barycenterOfPolyhedron(conn,22,coords,res); - break; - } - case INTERP_KERNEL::NORM_HEXGP12: - { - const int connecHexa12[43]={ - OTT::coo2C(connec[0]),OTT::coo2C(connec[1]),OTT::coo2C(connec[2]),OTT::coo2C(connec[3]),OTT::coo2C(connec[4]),OTT::coo2C(connec[5]),-1, - OTT::coo2C(connec[6]),OTT::coo2C(connec[11]),OTT::coo2C(connec[10]),OTT::coo2C(connec[9]),OTT::coo2C(connec[8]),OTT::coo2C(connec[7]),-1, - OTT::coo2C(connec[0]),OTT::coo2C(connec[6]),OTT::coo2C(connec[7]),OTT::coo2C(connec[1]),-1, - OTT::coo2C(connec[1]),OTT::coo2C(connec[7]),OTT::coo2C(connec[8]),OTT::coo2C(connec[2]),-1, - OTT::coo2C(connec[2]),OTT::coo2C(connec[8]),OTT::coo2C(connec[9]),OTT::coo2C(connec[3]),-1, - OTT::coo2C(connec[3]),OTT::coo2C(connec[9]),OTT::coo2C(connec[10]),OTT::coo2C(connec[4]),-1, - OTT::coo2C(connec[4]),OTT::coo2C(connec[10]),OTT::coo2C(connec[11]),OTT::coo2C(connec[5]),-1, - OTT::coo2C(connec[5]),OTT::coo2C(connec[11]),OTT::coo2C(connec[6]),OTT::coo2C(connec[0])}; - barycenterOfPolyhedron(connecHexa12,43,coords,res); - break; - } - case NORM_POLYHED: - { - barycenterOfPolyhedron(connec,lgth,coords,res); - break; - } - default: - throw INTERP_KERNEL::Exception("Not recognized cell type to get Barycenter on it !"); - } - } - - template - void computeBarycenter2(NormalizedCellType type, const ConnType *connec, int lgth, const double *coords, int spaceDim, double *res) - { - if(spaceDim==3) - return computeBarycenter(type,connec,lgth,coords,res); - if(spaceDim==2) - return computeBarycenter(type,connec,lgth,coords,res); - if(spaceDim==1) - return computeBarycenter(type,connec,lgth,coords,res); - throw INTERP_KERNEL::Exception("Invalid spaceDim specified for compute barycenter : must be 1, 2 or 3"); - } -} - -#endif diff --git a/src/INTERP_KERNELTest/BBTreeTest.cxx b/src/INTERP_KERNELTest/BBTreeTest.cxx deleted file mode 100644 index a4420571a..000000000 --- a/src/INTERP_KERNELTest/BBTreeTest.cxx +++ /dev/null @@ -1,307 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// - -#include "BBTreeTest.hxx" -#include -#include -#include "DirectedBoundingBox.hxx" - -namespace INTERP_TEST -{ - - - void BBTreeTest::setUp() - { - } - - - void BBTreeTest::tearDown() - { - } - - /** - * Test that creates a tree in 2D and check that - * the results are correct in three - * cases : - * a non matching search - * a standard case - * a bbox overlapping the bboxes of the tree - */ - void BBTreeTest::test_BBTree() { - //bbox tree creation - const int N=10; - double* bbox=new double[4*N*N]; - for (int i=0; i tree(bbox,0,0,N*N); - std::vector elems; - - //box outside the tree - double bbox1[4]={-2.0, -1.0, 0.0, 1.0}; - tree.getIntersectingElems(bbox1,elems); - CPPUNIT_ASSERT_EQUAL(0,(int)elems.size()); - elems.clear(); - - //box intersecting 4 tree elems - double bbox2[4]={2.5, 3.5, 0.5, 1.5}; - tree.getIntersectingElems(bbox2,elems); - CPPUNIT_ASSERT_EQUAL(4,(int)elems.size()); - elems.clear(); - - //box exactly superimposed to two tree elems - double bbox3[4]={5.0,6.0,7.0,9.0}; - tree.getIntersectingElems(bbox3,elems); - CPPUNIT_ASSERT_EQUAL(2,(int)elems.size()); - elems.clear(); - - double xx[2]={1.0,1.0}; - tree.getElementsAroundPoint(xx,elems); - CPPUNIT_ASSERT_EQUAL(4,(int)elems.size()); - - delete[] bbox; - } - - void BBTreeTest::test_DirectedBB_3D() - { - // a rectangle 1x2 extruded along vector (10,0,10) - const int nbP = 8, dim = 3; - double coords[nbP*dim] = - { - 0,0,0, 2,0,0, 2,1,0, 0,1,0, - 10,0,10, 12,0,10, 12,1,10, 10,1,10 - }; - INTERP_KERNEL::DirectedBoundingBox bb( coords, nbP, dim); - bb.enlarge( 1e-12 ); - - // corners of extrusion are IN - for ( int i = 0; i < nbP*dim; i+=dim ) - CPPUNIT_ASSERT( !bb.isOut( coords + i )); - - // points near corners of extrusion are OUT - double p[nbP*dim] = - { - 0,0,3, 6,0,3, 5,1,2, 0,1,2, - 8,0,9, 11,0,8, 11,0.5,8, 8,0.5,9 - }; - for ( int i = 0; i < nbP*dim; i+=dim ) - CPPUNIT_ASSERT( bb.isOut( p + i )); - - // the extrusions shifted by 3 in XOY plane are OUT - double shifted_X[nbP*dim] = - { - 3,0,0, 5,0,0, 5,1,0, 3,1,0, - 13,0,10, 15,0,10, 15,1,10, 13,1,10 - }; - double shifted_x[nbP*dim] = - { - -3,0,0, -1,0,0, -1,1,0, -3,1,0, - 7,0,10, 9,0,10, 9,1,10, 7,1,10 - }; - double shifted_Y[nbP*dim] = - { - 0,3,0, 2,3,0, 2,4,0, 0,4,0, - 10,3,10, 12,3,10, 12,4,10, 10,4,10 - }; - double shifted_y[nbP*dim] = - { - 0,-3,0, 2,-3,0, 2,-2,0, 0,-2,0, - 10,-3,10, 12,-3,10, 12,-2,10, 10,-2,10 - }; - INTERP_KERNEL::DirectedBoundingBox shiftedBB_x( shifted_x, nbP, dim); - INTERP_KERNEL::DirectedBoundingBox shiftedBB_X( shifted_X, nbP, dim); - INTERP_KERNEL::DirectedBoundingBox shiftedBB_y( shifted_y, nbP, dim); - INTERP_KERNEL::DirectedBoundingBox shiftedBB_Y( shifted_Y, nbP, dim); - - CPPUNIT_ASSERT( bb.isDisjointWith( shiftedBB_x )); - CPPUNIT_ASSERT( bb.isDisjointWith( shiftedBB_X )); - CPPUNIT_ASSERT( bb.isDisjointWith( shiftedBB_y )); - CPPUNIT_ASSERT( bb.isDisjointWith( shiftedBB_Y )); - - // intersecting box is IN - double inters_coords[nbP*dim] = - { - 0,0,0, 2,0,0, 2,1,0, 0,1,0, - 0,0,2, 2,0,2, 2,1,2, 0,1,2 - }; - INTERP_KERNEL::DirectedBoundingBox ibb( inters_coords, nbP, dim); - CPPUNIT_ASSERT( !bb.isDisjointWith( ibb )); - - // overlapping non-directed BB - double overlappingBB[2*dim] = - { - 5,6, 0, 1, -5,4 - }; - CPPUNIT_ASSERT( !bb.isDisjointWith( overlappingBB )); - - // non-overlapping non-directed BB - double nonoverlappingBB_1[2*dim] = - { - 5,6, 0,1, -5,2 - }; - CPPUNIT_ASSERT( bb.isDisjointWith( nonoverlappingBB_1 )); - double nonoverlappingBB_2[2*dim] = - { - 5,6, 0,1, 7,20 - }; - CPPUNIT_ASSERT( bb.isDisjointWith( nonoverlappingBB_2 )); - } - - void BBTreeTest::test_DirectedBB_2D() - { - // a segment of length 2 extruded along vector (10,10) - const int nbP = 4, dim = 2; - double coords[nbP*dim] = - { - 0,0, 2,0, - 10,10, 12,10, - }; - INTERP_KERNEL::DirectedBoundingBox bb( coords, nbP, dim); - bb.enlarge( 1e-12 ); - - // corners of extrusion are IN - for ( int i = 0; i < nbP*dim; i+=dim ) - CPPUNIT_ASSERT( !bb.isOut( coords + i )); - - // points near corners of extrusion are OUT - double p[nbP*dim] = - { - 1,2, 4,1, - 11,8, 8,9, - }; - for ( int i = 0; i < nbP*dim; i+=dim ) - CPPUNIT_ASSERT( bb.isOut( p + i )); - - // the extrusions shifted by 3 along OX are OUT - double shifted_X[nbP*dim] = - { - 3,0, 5,0, - 13,10, 15,10, - }; - double shifted_x[nbP*dim] = - { - -3,0, -1,0, - 7,10, 9,10, - }; - INTERP_KERNEL::DirectedBoundingBox shiftedBB_x( shifted_x, nbP, dim); - INTERP_KERNEL::DirectedBoundingBox shiftedBB_X( shifted_X, nbP, dim); - - CPPUNIT_ASSERT( bb.isDisjointWith( shiftedBB_x )); - CPPUNIT_ASSERT( bb.isDisjointWith( shiftedBB_X )); - - // intersecting box is IN - double inters_coords[nbP*dim] = - { - 0,0, 2,0, - 0,2, 2,2 - }; - INTERP_KERNEL::DirectedBoundingBox ibb( inters_coords, nbP, dim); - CPPUNIT_ASSERT( !bb.isDisjointWith( ibb )); - - // overlapping non-directed BB - double overlappingBB[2*dim] = - { - 5,6, -5,4 - }; - CPPUNIT_ASSERT( !bb.isDisjointWith( overlappingBB )); - - // non-overlapping non-directed BB - double nonoverlappingBB_1[2*dim] = - { - 5,6, -5,2 - }; - CPPUNIT_ASSERT( bb.isDisjointWith( nonoverlappingBB_1 )); - double nonoverlappingBB_2[2*dim] = - { - 5,6, 7,20 - }; - CPPUNIT_ASSERT( bb.isDisjointWith( nonoverlappingBB_2 )); - } - - void BBTreeTest::test_DirectedBB_1D() - { - const int nbP = 2, dim = 1; - double coords[nbP*dim] = - { - 0, 10 - }; - INTERP_KERNEL::DirectedBoundingBox bb( coords, nbP, dim); - bb.enlarge( 1e-12 ); - - // coords are IN - for ( int i = 0; i < nbP*dim; i+=dim ) - CPPUNIT_ASSERT( !bb.isOut( coords + i )); - - // points near ends are OUT - double p[nbP*dim] = - { - -0.0001, 10.1 - }; - for ( int i = 0; i < nbP*dim; i+=dim ) - CPPUNIT_ASSERT( bb.isOut( p + i )); - - // shifted boxes are OUT - double shifted_X[nbP*dim] = - { - 10.1, 11 - }; - double shifted_x[nbP*dim] = - { - -3.0, -0.001 - }; - INTERP_KERNEL::DirectedBoundingBox shiftedBB_x( shifted_x, nbP, dim); - INTERP_KERNEL::DirectedBoundingBox shiftedBB_X( shifted_X, nbP, dim); - - CPPUNIT_ASSERT( bb.isDisjointWith( shiftedBB_x )); - CPPUNIT_ASSERT( bb.isDisjointWith( shiftedBB_X )); - - // intersecting box is IN - double inters_coords[nbP*dim] = - { - -2,2 - }; - INTERP_KERNEL::DirectedBoundingBox ibb( inters_coords, nbP, dim); - CPPUNIT_ASSERT( !bb.isDisjointWith( ibb )); - - // overlapping non-directed BB - double overlappingBB[2*dim] = - { - -5,4 - }; - CPPUNIT_ASSERT( !bb.isDisjointWith( overlappingBB )); - - // non-overlapping non-directed BB - double nonoverlappingBB_1[2*dim] = - { - -5,-2 - }; - CPPUNIT_ASSERT( bb.isDisjointWith( nonoverlappingBB_1 )); - double nonoverlappingBB_2[2*dim] = - { - 11,16 - }; - CPPUNIT_ASSERT( bb.isDisjointWith( nonoverlappingBB_2 )); - } - -} diff --git a/src/INTERP_KERNELTest/BBTreeTest.hxx b/src/INTERP_KERNELTest/BBTreeTest.hxx deleted file mode 100644 index 89f98835e..000000000 --- a/src/INTERP_KERNELTest/BBTreeTest.hxx +++ /dev/null @@ -1,66 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 -// 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 __TU_BB_TREE_HXX__ -#define __TU_BB_TREE_HXX__ - -#include - -#include "InterpKernelTestExport.hxx" -#include "BBTree.txx" - -namespace INTERP_TEST -{ - - /** - * \brief Test suite testing some of the low level methods of TransformedTriangle. - * - */ - class INTERPKERNELTEST_EXPORT BBTreeTest : public CppUnit::TestFixture - { - - CPPUNIT_TEST_SUITE( BBTreeTest ); - CPPUNIT_TEST( test_BBTree ); - CPPUNIT_TEST( test_DirectedBB_1D ); - CPPUNIT_TEST( test_DirectedBB_2D ); - CPPUNIT_TEST( test_DirectedBB_3D ); - CPPUNIT_TEST_SUITE_END(); - - - public: - void setUp(); - - void tearDown(); - - // tests - void test_BBTree(); - void test_DirectedBB_1D(); - void test_DirectedBB_2D(); - void test_DirectedBB_3D(); - - }; - - - - -} - - - -#endif diff --git a/src/INTERP_KERNELTest/BasicMainTest.hxx b/src/INTERP_KERNELTest/BasicMainTest.hxx deleted file mode 100644 index e1a78e6c9..000000000 --- a/src/INTERP_KERNELTest/BasicMainTest.hxx +++ /dev/null @@ -1,96 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 -// 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 _BASICMAINTEST_HXX_ -#define _BASICMAINTEST_HXX_ - -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include - -#ifndef WIN32 -#include -#endif - -// ============================================================================ -/*! - * Main program source for Unit Tests with cppunit package does not depend - * on actual tests, so we use the same for all partial unit tests. - */ -// ============================================================================ - -int main(int argc, char* argv[]) -{ -#ifndef WIN32 - fpu_control_t cw = _FPU_DEFAULT & ~(_FPU_MASK_IM | _FPU_MASK_ZM | _FPU_MASK_OM); - _FPU_SETCW(cw); -#endif - // --- Create the event manager and test controller - CPPUNIT_NS::TestResult controller; - - // --- Add a listener that colllects test result - CPPUNIT_NS::TestResultCollector result; - controller.addListener( &result ); - - // --- Add a listener that print dots as test run. -#ifdef WIN32 - CPPUNIT_NS::TextTestProgressListener progress; -#else - CPPUNIT_NS::BriefTestProgressListener progress; -#endif - controller.addListener( &progress ); - - // --- Get the top level suite from the registry - - CPPUNIT_NS::Test *suite = - CPPUNIT_NS::TestFactoryRegistry::getRegistry().makeTest(); - - // --- Adds the test to the list of test to run - - CPPUNIT_NS::TestRunner runner; - runner.addTest( suite ); - runner.run( controller); - - // --- Print test in a compiler compatible format. - - std::ofstream testFile; - testFile.open("UnitTestsResult", std::ios::out | std::ios::trunc); - //CPPUNIT_NS::CompilerOutputter outputter( &result, std::cerr ); - CPPUNIT_NS::CompilerOutputter outputter( &result, testFile ); - outputter.write(); - - // --- Run the tests. - - bool wasSucessful = result.wasSuccessful(); - testFile.close(); - - // --- Return error code 1 if the one of test failed. - - return wasSucessful ? 0 : 1; -} - -#endif diff --git a/src/INTERP_KERNELTest/CMakeLists.txt b/src/INTERP_KERNELTest/CMakeLists.txt deleted file mode 100644 index 2f125d40e..000000000 --- a/src/INTERP_KERNELTest/CMakeLists.txt +++ /dev/null @@ -1,97 +0,0 @@ -# Copyright (C) 2012-2015 CEA/DEN, EDF 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, 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 -# 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) - -ADD_DEFINITIONS(${HDF5_DEFINITIONS} ${MEDFILE_DEFINITIONS} ${XDR_DEFINITIONS} ${CPPUNIT_DEFINITIONS}) - -INCLUDE_DIRECTORIES( - ${CPPUNIT_INCLUDE_DIRS} - ${HDF5_INCLUDE_DIRS} - ${MEDFILE_INCLUDE_DIRS} - ${XDR_INCLUDE_DIRS} - ${CMAKE_CURRENT_SOURCE_DIR}/../MEDLoader - ${CMAKE_CURRENT_SOURCE_DIR}/../MEDCoupling - ${CMAKE_CURRENT_SOURCE_DIR}/../INTERP_KERNEL - ${CMAKE_CURRENT_SOURCE_DIR}/../INTERP_KERNEL/Bases - ${CMAKE_CURRENT_SOURCE_DIR}/../INTERP_KERNEL/ExprEval - ${CMAKE_CURRENT_SOURCE_DIR}/../INTERP_KERNEL/GaussPoints - ${CMAKE_CURRENT_SOURCE_DIR}/../INTERP_KERNEL/Geometric2D - ) - -SET(InterpKernelTest_SOURCES - BBTreeTest.cxx - CppUnitTest.cxx - ExprEvalInterpTest.cxx - QuadraticPlanarInterpTest.cxx - QuadraticPlanarInterpTest2.cxx - QuadraticPlanarInterpTest3.cxx - QuadraticPlanarInterpTest4.cxx - QuadraticPlanarInterpTest5.cxx - SingleElementPlanarTests.cxx - TransformedTriangleIntersectTest.cxx - TransformedTriangleTest.cxx - UnitTetra3D2DIntersectionTest.cxx - UnitTetraIntersectionBaryTest.cxx - TestInterpKernelUtils.cxx - ThreeDSurfProjectionTest.cxx -) - -SET(TestINTERP_KERNEL_SOURCES - TestInterpKernel.cxx - ) - -SET(PerfTest_SOURCES - PerfTest.cxx - ) - -IF(NOT MED_ENABLE_MICROMED) - SET(InterpKernelTest_SOURCES - ${InterpKernelTest_SOURCES} - InterpolationOptionsTest.cxx - MEDMeshMaker.cxx - ) - - SET(PerfTest_SOURCES - PerfTest.cxx - ) - ADD_EXECUTABLE(PerfTest ${PerfTest_SOURCES}) - TARGET_LINK_LIBRARIES(PerfTest InterpKernelTest ${CPPUNIT_LIBRARIES} ${PLATFORM_LIBS}) - INSTALL(TARGETS PerfTest DESTINATION ${SALOME_INSTALL_BINS}) -ENDIF(NOT MED_ENABLE_MICROMED) - -ADD_LIBRARY(InterpKernelTest SHARED ${InterpKernelTest_SOURCES}) -TARGET_LINK_LIBRARIES(InterpKernelTest medloader medcoupling interpkernel ${CPPUNIT_LIBRARIES}) - -ADD_EXECUTABLE(TestINTERP_KERNEL ${TestINTERP_KERNEL_SOURCES}) -TARGET_LINK_LIBRARIES(TestINTERP_KERNEL InterpKernelTest ${CPPUNIT_LIBRARIES} ${PLATFORM_LIBS}) -ADD_TEST(TestINTERP_KERNEL TestINTERP_KERNEL) -SALOME_GENERATE_TESTS_ENVIRONMENT(tests_env) -SET_TESTS_PROPERTIES(TestINTERP_KERNEL PROPERTIES ENVIRONMENT "${tests_env}") - -INSTALL(TARGETS TestINTERP_KERNEL DESTINATION ${SALOME_INSTALL_BINS}) -INSTALL(TARGETS InterpKernelTest DESTINATION ${SALOME_INSTALL_LIBS}) - -# Application tests - -SET(TEST_INSTALL_DIRECTORY ${SALOME_INSTALL_SCRIPT_SCRIPTS}/test/MEDCoupling/INTERP_KERNELTest) -INSTALL(TARGETS TestINTERP_KERNEL InterpKernelTest DESTINATION ${TEST_INSTALL_DIRECTORY}) - -INSTALL(FILES CTestTestfileInstall.cmake - DESTINATION ${TEST_INSTALL_DIRECTORY} - RENAME CTestTestfile.cmake) diff --git a/src/INTERP_KERNELTest/CTestTestfileInstall.cmake b/src/INTERP_KERNELTest/CTestTestfileInstall.cmake deleted file mode 100644 index 1152205af..000000000 --- a/src/INTERP_KERNELTest/CTestTestfileInstall.cmake +++ /dev/null @@ -1,21 +0,0 @@ -# Copyright (C) 2015 CEA/DEN, EDF 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, 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 -# 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_TEST(TestINTERP_KERNEL TestINTERP_KERNEL) -SET_TESTS_PROPERTIES(TestINTERP_KERNEL PROPERTIES LABELS "${COMPONENT_NAME}") diff --git a/src/INTERP_KERNELTest/CppUnitTest.cxx b/src/INTERP_KERNELTest/CppUnitTest.cxx deleted file mode 100644 index 18cbc1531..000000000 --- a/src/INTERP_KERNELTest/CppUnitTest.cxx +++ /dev/null @@ -1,20 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// - -#include "CppUnitTest.hxx" diff --git a/src/INTERP_KERNELTest/CppUnitTest.hxx b/src/INTERP_KERNELTest/CppUnitTest.hxx deleted file mode 100644 index 14f16c78d..000000000 --- a/src/INTERP_KERNELTest/CppUnitTest.hxx +++ /dev/null @@ -1,87 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 -// 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 __TU_TEST_CPPUNIT_HXX__ -#define __TU_TEST_CPPUNIT_HXX__ - -#include - -#include "InterpKernelTestExport.hxx" - -/** - * \brief Class tested by TestBogusClass : not very useful - */ -class INTERPKERNELTEST_EXPORT BogusClass { - friend class TestBogusClass; - -public: - BogusClass(double _x) : x(_x) {;} - - double getX() { return x; } - -private: - double x; -}; - -/** - * \brief Class used to figure out CppUnit : not very useful - * - */ -class INTERPKERNELTEST_EXPORT TestBogusClass : public CppUnit::TestFixture -{ - - CPPUNIT_TEST_SUITE( TestBogusClass ); - CPPUNIT_TEST( test1 ); - CPPUNIT_TEST( test2 ); - CPPUNIT_TEST_SUITE_END(); - -public: - void setUp() { - obj = new BogusClass(3.14); - } - - void tearDown() { - delete obj; - } - - void test1() { - // test something - CPPUNIT_ASSERT(obj->x == 3.14); - CPPUNIT_ASSERT(obj->getX() == obj->x); - } - - void test2() { - // test something else - obj->x += 2.6; - CPPUNIT_ASSERT(obj->getX() > 3.14); - } - -private: - BogusClass* obj; - -}; - - - - - - - - -#endif diff --git a/src/INTERP_KERNELTest/ExprEvalInterpTest.cxx b/src/INTERP_KERNELTest/ExprEvalInterpTest.cxx deleted file mode 100644 index c5753d73e..000000000 --- a/src/INTERP_KERNELTest/ExprEvalInterpTest.cxx +++ /dev/null @@ -1,696 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 -// 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 "ExprEvalInterpTest.hxx" -#include "InterpKernelExprParser.hxx" - -#include -#include - -using namespace INTERP_TEST; - -void ExprEvalInterpTest::testBuildStringFromFortran() -{ - char toto1[]="123456 "; - char result[]="123456"; - std::string titi; - titi=INTERP_KERNEL::ExprParser::buildStringFromFortran(toto1,8); - CPPUNIT_ASSERT_EQUAL(6,(int)titi.length()); - CPPUNIT_ASSERT(titi==result); - // - char toto2[]=" 23456 "; - char result2[]=" 23456"; - titi=INTERP_KERNEL::ExprParser::buildStringFromFortran(toto2,8); - CPPUNIT_ASSERT(titi==result2); - CPPUNIT_ASSERT_EQUAL(6,(int)titi.length()); - // - char toto3[]=" 3456 "; - char result3[]=" 3456"; - titi=INTERP_KERNEL::ExprParser::buildStringFromFortran(toto3,8); - CPPUNIT_ASSERT(titi==result3); - CPPUNIT_ASSERT_EQUAL(6,(int)titi.length()); - // - char toto4[]=" "; - titi=INTERP_KERNEL::ExprParser::buildStringFromFortran(toto4,8); - CPPUNIT_ASSERT_EQUAL(0,(int)titi.length()); - // - char toto5[]=" 345677"; - titi=INTERP_KERNEL::ExprParser::buildStringFromFortran(toto5,8); - CPPUNIT_ASSERT(titi==toto5); - CPPUNIT_ASSERT_EQUAL(8,(int)titi.length()); -} - -void ExprEvalInterpTest::testDeleteWhiteSpaces() -{ - char toto[]=" jkhjkh ooooppp l "; - char result[]="jkhjkhoooopppl"; - std::string totoS(toto); - std::string totoR=INTERP_KERNEL::ExprParser::deleteWhiteSpaces(totoS); - CPPUNIT_ASSERT(totoR==result); - CPPUNIT_ASSERT_EQUAL(14,(int)totoR.length()); - // - char toto2[]=" jkhjkh ooooppp l "; - totoS=toto2; - totoR=INTERP_KERNEL::ExprParser::deleteWhiteSpaces(totoS); - CPPUNIT_ASSERT(totoR==result); - CPPUNIT_ASSERT_EQUAL(14,(int)totoR.length()); - // - char toto3[]=" jkhjkh oooo pppl "; - totoS=toto3; - totoR=INTERP_KERNEL::ExprParser::deleteWhiteSpaces(totoS); - CPPUNIT_ASSERT(totoR==result); - CPPUNIT_ASSERT_EQUAL(14,(int)totoR.length()); - // - char toto4[]=" jkhjkh oooo pppl"; - totoS=toto4; - totoR=INTERP_KERNEL::ExprParser::deleteWhiteSpaces(totoS); - CPPUNIT_ASSERT(totoR==result); - CPPUNIT_ASSERT_EQUAL(14,(int)totoR.length()); - // - char toto5[]="jkhjkh oooo pppl"; - totoS=toto5; - totoR=INTERP_KERNEL::ExprParser::deleteWhiteSpaces(totoS); - CPPUNIT_ASSERT(totoR==result); - CPPUNIT_ASSERT_EQUAL(14,(int)totoR.length()); - // - totoS=result; - totoR=INTERP_KERNEL::ExprParser::deleteWhiteSpaces(totoS); - CPPUNIT_ASSERT(totoR==result); - CPPUNIT_ASSERT_EQUAL(14,(int)totoR.length()); - // - char toto6[]="j k h j k h o o o o p p p l"; - totoS=toto6; - totoR=INTERP_KERNEL::ExprParser::deleteWhiteSpaces(totoS); - CPPUNIT_ASSERT(totoR==result); - CPPUNIT_ASSERT_EQUAL(14,(int)totoR.length()); - // - char toto7[]="j k h j k h o o o o p pp l"; - totoS=toto7; - totoR=INTERP_KERNEL::ExprParser::deleteWhiteSpaces(totoS); - CPPUNIT_ASSERT(totoR==result); - CPPUNIT_ASSERT_EQUAL(14,(int)totoR.length()); - // - char toto8[]=" "; - totoS=toto8; - totoR=INTERP_KERNEL::ExprParser::deleteWhiteSpaces(totoS); - CPPUNIT_ASSERT(totoR.empty()); - // - char toto9[]=""; - totoS=toto9; - totoR=INTERP_KERNEL::ExprParser::deleteWhiteSpaces(totoS); - CPPUNIT_ASSERT(totoR.empty()); - // - char toto10[]="j\n k \nh\nj \n\n k\nh \n o \no\n o\n o \np\n\npp \n\n l"; - totoS=toto10; - totoR=INTERP_KERNEL::ExprParser::deleteWhiteSpaces(totoS); - CPPUNIT_ASSERT(totoR==result); - CPPUNIT_ASSERT_EQUAL(14,(int)totoR.length()); -} - -void ExprEvalInterpTest::testInterpreter0() -{ - INTERP_KERNEL::ExprParser expr1("3*-2"); - expr1.parse(); - CPPUNIT_ASSERT_DOUBLES_EQUAL(-6.,expr1.evaluate(),1e-15); - INTERP_KERNEL::ExprParser expr2("-2.3"); - expr2.parse(); - CPPUNIT_ASSERT_DOUBLES_EQUAL(-2.3,expr2.evaluate(),1e-15); - INTERP_KERNEL::ExprParser expr3("--2.3"); - expr3.parse(); - CPPUNIT_ASSERT_DOUBLES_EQUAL(2.3,expr3.evaluate(),1e-15); - INTERP_KERNEL::ExprParser expr4("-++2.3"); - expr4.parse(); - CPPUNIT_ASSERT_DOUBLES_EQUAL(-2.3,expr4.evaluate(),1e-15); - INTERP_KERNEL::ExprParser expr5("+2.3"); - expr5.parse(); - CPPUNIT_ASSERT_DOUBLES_EQUAL(2.3,expr5.evaluate(),1e-15); - INTERP_KERNEL::ExprParser expr6("3^-1"); - expr6.parse(); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.33333333333333333,expr6.evaluate(),1e-15); -} - -void ExprEvalInterpTest::testInterpreter1() -{ - INTERP_KERNEL::ExprParser expr1("3+2*5"); - expr1.parse(); - CPPUNIT_ASSERT_DOUBLES_EQUAL(13.,expr1.evaluate(),1e-14); - INTERP_KERNEL::ExprParser expr2("3+2^3*5"); - expr2.parse(); - CPPUNIT_ASSERT_DOUBLES_EQUAL(43.,expr2.evaluate(),1e-14); - INTERP_KERNEL::ExprParser expr3("3+2^(2*5)"); - expr3.parse(); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1027.,expr3.evaluate(),1e-14); - INTERP_KERNEL::ExprParser expr4("(3.2+4.3)*(1.3+2.3*7.8)"); - expr4.parse(); - CPPUNIT_ASSERT_DOUBLES_EQUAL(144.3,expr4.evaluate(),1e-10); - INTERP_KERNEL::ExprParser expr5("(3.2+4.3)*cos(1.3+2.3*7.8)"); - expr5.parse(); - CPPUNIT_ASSERT_DOUBLES_EQUAL(6.9355510138337619,expr5.evaluate(),1e-14); - INTERP_KERNEL::ExprParser expr6("3+2-4-7+4.3"); - expr6.parse(); - CPPUNIT_ASSERT_DOUBLES_EQUAL(-1.7,expr6.evaluate(),1e-14); - INTERP_KERNEL::ExprParser expr7("3.2*4.5/3.3/2.2"); - expr7.parse(); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1.9834710743801653,expr7.evaluate(),1e-14); - INTERP_KERNEL::ExprParser expr8("3.2*4.5/3.3/2.2"); - expr8.parse(); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1.9834710743801653,expr8.evaluate(),1e-14); - INTERP_KERNEL::ExprParser expr9("(((1.23456789)))"); - expr9.parse(); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1.23456789,expr9.evaluate(),1e-14); - INTERP_KERNEL::ExprParser expr10("3.2*((2*5.2+6.)+(1.2*1.2+3.))"); - expr10.parse(); - CPPUNIT_ASSERT_DOUBLES_EQUAL(66.688,expr10.evaluate(),1e-13); - INTERP_KERNEL::ExprParser expr11("((3.2*(((2*5.2+6.)+(1.2*1.2+3.)))))"); - expr11.parse(); - CPPUNIT_ASSERT_DOUBLES_EQUAL(66.688,expr11.evaluate(),1e-13); - INTERP_KERNEL::ExprParser expr12("((3.2*(cos((2*5.2+6.)+(1.2*1.2+3.)))))"); - expr12.parse(); - CPPUNIT_ASSERT_DOUBLES_EQUAL(-1.3038041398761016,expr12.evaluate(),1e-14); - INTERP_KERNEL::ExprParser expr13("((3.2*(sin((2*5.2+6.)+(1.2*1.2+3.)))))"); - expr13.parse(); - CPPUNIT_ASSERT_DOUBLES_EQUAL(2.9223440531261784,expr13.evaluate(),1e-14); - INTERP_KERNEL::ExprParser expr14("((3.2*(tan((2*5.2+6.)+(1.2*1.2+3.)))))"); - expr14.parse(); - CPPUNIT_ASSERT_DOUBLES_EQUAL(-7.1724737512280257,expr14.evaluate(),1e-14); - INTERP_KERNEL::ExprParser expr15("((3.2*(sqrt((2*5.2+6.)+(1.2*1.2+3.)))))"); - expr15.parse(); - CPPUNIT_ASSERT_DOUBLES_EQUAL(14.608271629457059,expr15.evaluate(),1e-13); - INTERP_KERNEL::ExprParser expr16("-((3.2*(sqrt((2*5.2+6.)+(1.2*1.2+3.)))))"); - expr16.parse(); - CPPUNIT_ASSERT_DOUBLES_EQUAL(-14.608271629457059,expr16.evaluate(),1e-13); - INTERP_KERNEL::ExprParser expr17("(-(3.2*(sqrt((2*5.2+6.)+(1.2*1.2+3.)))))"); - expr17.parse(); - CPPUNIT_ASSERT_DOUBLES_EQUAL(-14.608271629457059,expr17.evaluate(),1e-13); - INTERP_KERNEL::ExprParser expr18("((-3.2*(sqrt((2*5.2+6.)+(1.2*1.2+3.)))))"); - expr18.parse(); - CPPUNIT_ASSERT_DOUBLES_EQUAL(-14.608271629457059,expr18.evaluate(),1e-13); - INTERP_KERNEL::ExprParser expr19("((3.2*(exp((6.+2*5.2)+(1.2*1.2+3.)))))"); - expr19.parse(); - CPPUNIT_ASSERT_DOUBLES_EQUAL(3596226038.1784945,expr19.evaluate(),1e-6); - INTERP_KERNEL::ExprParser expr20("((3.2*(ln((2*5.2+6.)+(1.2*1.2+3.)))))"); - expr20.parse(); - CPPUNIT_ASSERT_DOUBLES_EQUAL(9.7179974940325309,expr20.evaluate(),1e-14); - INTERP_KERNEL::ExprParser expr21("max(3.2,4.5)"); - expr21.parse(); - CPPUNIT_ASSERT_DOUBLES_EQUAL(4.5,expr21.evaluate(),1e-14); - INTERP_KERNEL::ExprParser expr22("3.*max(((3.2*(ln((2*5.2+6.)+(1.2*1.2+3.))))),((3.2*(exp((6.+2*5.2)+(1.2*1.2+3.))))))"); - expr22.parse(); - CPPUNIT_ASSERT_DOUBLES_EQUAL(10788678114.535484,expr22.evaluate(),1e-5); - INTERP_KERNEL::ExprParser expr23("min(3.2,4.5)"); - expr23.parse(); - CPPUNIT_ASSERT_DOUBLES_EQUAL(3.2,expr23.evaluate(),1e-14); -} - -void ExprEvalInterpTest::testInterpreter2() -{ - INTERP_KERNEL::ExprParser expr1("3.5*x+x*x*x/(2+x)+2*5*y"); - expr1.parse(); - std::set res,expected; - expr1.getSetOfVars(res); - CPPUNIT_ASSERT_EQUAL(2,(int)res.size()); - expected.insert("x"); expected.insert("y"); - CPPUNIT_ASSERT(std::equal(res.begin(),res.end(),expected.begin())); - double xyValue[2]={1.,3.}; - double res1; - std::vector vars; vars.push_back("x"); vars.push_back("y"); - expr1.prepareExprEvaluation(vars,2,1); - expr1.evaluateExpr(1,xyValue,&res1); - CPPUNIT_ASSERT_DOUBLES_EQUAL(33.833333333333336,res1,1e-13); - xyValue[0]=-2.; - CPPUNIT_ASSERT_THROW(expr1.evaluateExpr(1,xyValue,&res1),INTERP_KERNEL::Exception); - double res2[2]; - xyValue[0]=1.; - expr1.evaluateExpr(2,xyValue,res2); - CPPUNIT_ASSERT_DOUBLES_EQUAL(33.833333333333336,res2[0],1e-13); - CPPUNIT_ASSERT_DOUBLES_EQUAL(33.833333333333336,res2[1],1e-13); - INTERP_KERNEL::ExprParser expr2("3.5*tan(2.3*x)*IVec+(cos(1.2+y/x)*JVec)"); - expr2.parse(); - res.clear(); expected.clear(); - expr2.getSetOfVars(res); - CPPUNIT_ASSERT_EQUAL(4,(int)res.size()); - expected.insert("x"); expected.insert("y"); expected.insert("IVec"); expected.insert("JVec"); - CPPUNIT_ASSERT(std::equal(res.begin(),res.end(),expected.begin())); - expr2.prepareExprEvaluation(vars,2,2); - expr2.evaluateExpr(2,xyValue,res2); - CPPUNIT_ASSERT_DOUBLES_EQUAL(-3.9172477460694637,res2[0],1e-14); - CPPUNIT_ASSERT_DOUBLES_EQUAL(-0.49026082134069943,res2[1],1e-14); - INTERP_KERNEL::ExprParser expr3("3.5*u+u^2.4+2."); - expr3.parse(); - expr3.prepareExprEvaluationVec(); - expr3.evaluateExpr(2,xyValue,res2); - CPPUNIT_ASSERT_DOUBLES_EQUAL(6.5,res2[0],1e-14); - CPPUNIT_ASSERT_DOUBLES_EQUAL(26.466610165238237,res2[1],1e-14); - INTERP_KERNEL::ExprParser expr4("3.5*v+u^2.4+2."); - expr4.parse(); - CPPUNIT_ASSERT_THROW(expr4.prepareExprEvaluationVec(),INTERP_KERNEL::Exception); -} - -void ExprEvalInterpTest::testInterpreterUnit0() -{ - INTERP_KERNEL::ExprParser expr1("kg"); - expr1.parse(); - INTERP_KERNEL::DecompositionInUnitBase unit=expr1.evaluateUnit(); - CPPUNIT_ASSERT(unit.isEqual(1,0,0,0,0,0.,1000.)); - INTERP_KERNEL::ExprParser expr2("kgT"); - expr2.parse(); - CPPUNIT_ASSERT_THROW(expr2.evaluateUnit(),INTERP_KERNEL::Exception); - INTERP_KERNEL::ExprParser expr3("g"); - expr3.parse(); - unit=expr3.evaluateUnit(); - CPPUNIT_ASSERT(unit.isEqual(1,0,0,0,0,0.,1.)); - INTERP_KERNEL::ExprParser expr4("g*m"); - expr4.parse(); - unit=expr4.evaluateUnit(); - CPPUNIT_ASSERT(unit.isEqual(1,1,0,0,0,0.,1.)); - INTERP_KERNEL::ExprParser expr5("g*m/K"); - expr5.parse(); - unit=expr5.evaluateUnit(); - CPPUNIT_ASSERT(unit.isEqual(1,1,0,0,-1,0.,1.)); - INTERP_KERNEL::ExprParser expr6("g*m/K^2"); - expr6.parse(); - unit=expr6.evaluateUnit(); - CPPUNIT_ASSERT(unit.isEqual(1,1,0,0,-2,0.,1.)); - INTERP_KERNEL::ExprParser expr7("g/K^2*m"); - expr7.parse(); - unit=expr7.evaluateUnit(); - CPPUNIT_ASSERT(unit.isEqual(1,1,0,0,-2,0.,1.)); - INTERP_KERNEL::ExprParser expr8("g/(K^2*m)"); - expr8.parse(); - unit=expr8.evaluateUnit(); - CPPUNIT_ASSERT(unit.isEqual(1,-1,0,0,-2,0.,1.)); - INTERP_KERNEL::ExprParser expr9("km/h"); - expr9.parse(); - unit=expr9.evaluateUnit(); - CPPUNIT_ASSERT(unit.isEqual(0,1,-1,0,0,0.,0.27777777777777779)); - INTERP_KERNEL::ExprParser expr10("m/s"); - expr10.parse(); - unit=expr10.evaluateUnit(); - CPPUNIT_ASSERT(unit.isEqual(0,1,-1,0,0,0.,1.)); - INTERP_KERNEL::ExprParser expr11("m+s"); - expr11.parse(); - CPPUNIT_ASSERT_THROW(expr11.evaluateUnit(),INTERP_KERNEL::Exception); - INTERP_KERNEL::ExprParser expr12("m-m"); - expr12.parse(); - CPPUNIT_ASSERT_THROW(expr12.evaluateUnit(),INTERP_KERNEL::Exception); - const char expr13C[3]={-0x50,0x43,0x0}; - INTERP_KERNEL::ExprParser expr13(expr13C); - expr13.parse(); - unit=expr13.evaluateUnit(); - CPPUNIT_ASSERT(unit.isEqual(0,0,0,0,1,273.15,1.)); - const char expr14C[4]={-0x3E,-0x50,0x43,0x0}; - INTERP_KERNEL::ExprParser expr14(expr14C); - expr14.parse(); - unit=expr14.evaluateUnit(); - CPPUNIT_ASSERT(unit.isEqual(0,0,0,0,1,273.15,1.)); - INTERP_KERNEL::ExprParser expr15("kN/kg"); - expr15.parse(); - unit=expr15.evaluateUnit(); - CPPUNIT_ASSERT(unit.isEqual(0,1,-2,0,0,0.,1000.)); - INTERP_KERNEL::ExprParser expr16("cm"); - expr16.parse(); - unit=expr16.evaluateUnit(); - CPPUNIT_ASSERT(unit.isEqual(0,1,0,0,0,0.,0.01)); - INTERP_KERNEL::ExprParser expr17("m"); - expr17.parse(); - unit=expr17.evaluateUnit(); - CPPUNIT_ASSERT(unit.isEqual(0,1,0,0,0,0.,1)); - const char expr18C[3]={-0x08,0x43,0x0}; - INTERP_KERNEL::ExprParser expr18(expr18C); - expr18.parse(); - unit=expr18.evaluateUnit(); - CPPUNIT_ASSERT(unit.isEqual(0,0,0,0,1,273.15,1.)); - const char expr19C[6]={-0x50,0x43,0x2F,-0x50,0x43,0x0}; - INTERP_KERNEL::ExprParser expr19(expr19C); - expr19.parse(); - unit=expr19.evaluateUnit(); - CPPUNIT_ASSERT(unit.isEqual(0,0,0,0,0,0.,1.)); - const char expr20C[9]={-0x50,0x43,0x2A,-0x50,0x43,0x2F,-0x50,0x43,0x0}; - INTERP_KERNEL::ExprParser expr20(expr20C); - expr20.parse(); - unit=expr20.evaluateUnit(); - CPPUNIT_ASSERT(unit.isEqual(0,0,0,0,1,0.,1.)); -} - -void ExprEvalInterpTest::testInterpreterUnit1() -{ - INTERP_KERNEL::Unit unit1("m/s"); - INTERP_KERNEL::Unit unit2("km/h"); - CPPUNIT_ASSERT(unit1.isCompatibleWith(unit2) && unit2.isCompatibleWith(unit1)); - CPPUNIT_ASSERT_DOUBLES_EQUAL(360,unit1.convert(unit2,100.),1e-10); - INTERP_KERNEL::Unit unit3("J/s"); - INTERP_KERNEL::Unit unit4("kW"); - CPPUNIT_ASSERT(unit3.isCompatibleWith(unit4) && unit4.isCompatibleWith(unit3)); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,unit3.convert(unit4,1000.),1e-10); - CPPUNIT_ASSERT(unit4.getCoarseRepr()=="kW"); - INTERP_KERNEL::Unit unit5("kpT"); - CPPUNIT_ASSERT(!unit5.isInterpretationOK()); - CPPUNIT_ASSERT(unit5.getCoarseRepr()=="kpT"); - INTERP_KERNEL::Unit unit6("m*kpT"); - CPPUNIT_ASSERT(!unit6.isInterpretationOK()); - INTERP_KERNEL::Unit unit7("m*s^-1"); - CPPUNIT_ASSERT(unit7.isCompatibleWith(unit2) && unit2.isCompatibleWith(unit7)); - CPPUNIT_ASSERT_DOUBLES_EQUAL(360,unit7.convert(unit2,100.),1e-10); - const char unit8C[3]={-0x50,0x43,0x0}; - INTERP_KERNEL::Unit unit8(unit8C); - INTERP_KERNEL::Unit unit9("K"); - CPPUNIT_ASSERT(unit9.isCompatibleWith(unit8) && unit8.isCompatibleWith(unit9)); - CPPUNIT_ASSERT_DOUBLES_EQUAL(335.15,unit8.convert(unit9,62.),1e-10); - CPPUNIT_ASSERT_DOUBLES_EQUAL(-16.37,unit9.convert(unit8,256.78),1e-10); - INTERP_KERNEL::Unit unit10("m"); - INTERP_KERNEL::Unit unit11("cm"); - CPPUNIT_ASSERT(unit10.isCompatibleWith(unit11) && unit11.isCompatibleWith(unit10)); - CPPUNIT_ASSERT_DOUBLES_EQUAL(6200.,unit10.convert(unit11,62.),1e-8); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.62,unit11.convert(unit10,62.),1e-15); - INTERP_KERNEL::Unit unit12("m-m"); - CPPUNIT_ASSERT(!unit12.isInterpretationOK()); -} - -void ExprEvalInterpTest::testInterpreter3() -{ - std::set res; - double input[3]; - double res2[3]; - INTERP_KERNEL::ExprParser expr1("2.3+x>5."); - expr1.parse(); - expr1.getSetOfVars(res); - CPPUNIT_ASSERT_EQUAL(1,(int)res.size()); - CPPUNIT_ASSERT(*(res.begin())=="x"); - expr1.prepareExprEvaluationVec(); - input[0]=0.; - expr1.evaluateExpr(1,input,res2); - CPPUNIT_ASSERT(-std::numeric_limits::max()==res2[0]); - input[0]=2.8; - expr1.evaluateExpr(1,input,res2); - CPPUNIT_ASSERT(std::numeric_limits::max()==res2[0]); - input[0]=2.6; - expr1.evaluateExpr(1,input,res2); - CPPUNIT_ASSERT(-std::numeric_limits::max()==res2[0]); - // - INTERP_KERNEL::ExprParser expr2("2.3+x<5."); - expr2.parse(); - res.clear(); - expr2.getSetOfVars(res); - CPPUNIT_ASSERT_EQUAL(1,(int)res.size()); - CPPUNIT_ASSERT(*(res.begin())=="x"); - expr2.prepareExprEvaluationVec(); - input[0]=0.; - expr2.evaluateExpr(1,input,res2); - CPPUNIT_ASSERT(std::numeric_limits::max()==res2[0]); - input[0]=2.8; - expr2.evaluateExpr(1,input,res2); - CPPUNIT_ASSERT(-std::numeric_limits::max()==res2[0]); - input[0]=2.6; - expr2.evaluateExpr(1,input,res2); - CPPUNIT_ASSERT(std::numeric_limits::max()==res2[0]); - // - INTERP_KERNEL::ExprParser expr3("if(2.3+x<5.,2+3*x,3+x/2)"); - expr3.parse(); - res.clear(); - expr3.getSetOfVars(res); - CPPUNIT_ASSERT_EQUAL(1,(int)res.size()); - CPPUNIT_ASSERT(*(res.begin())=="x"); - expr3.prepareExprEvaluationVec(); - input[0]=0.; - expr3.evaluateExpr(1,input,res2); - CPPUNIT_ASSERT_DOUBLES_EQUAL(2.,res2[0],1e-12); - input[0]=2.8; - expr3.evaluateExpr(1,input,res2); - CPPUNIT_ASSERT_DOUBLES_EQUAL(4.4,res2[0],1e-12); - input[0]=2.6; - expr3.evaluateExpr(1,input,res2); - CPPUNIT_ASSERT_DOUBLES_EQUAL(9.8,res2[0],1e-12); - // - INTERP_KERNEL::ExprParser expr4("if(x>1000,2*x,x/3)"); - expr4.parse(); - res.clear(); - expr4.getSetOfVars(res); - CPPUNIT_ASSERT_EQUAL(1,(int)res.size()); - CPPUNIT_ASSERT(*(res.begin())=="x"); - expr4.prepareExprEvaluationVec(); - input[0]=2.7; - expr4.evaluateExpr(1,input,res2); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.9,res2[0],1e-12); - input[0]=999.; - expr4.evaluateExpr(1,input,res2); - CPPUNIT_ASSERT_DOUBLES_EQUAL(333.,res2[0],1e-12); - input[0]=1002.; - expr4.evaluateExpr(1,input,res2); - CPPUNIT_ASSERT_DOUBLES_EQUAL(2004.,res2[0],1e-12); - // - INTERP_KERNEL::ExprParser expr5("4.4*x*log10(x)*10"); - expr5.parse(); - res.clear(); - expr5.getSetOfVars(res); - CPPUNIT_ASSERT_EQUAL(1,(int)res.size()); - CPPUNIT_ASSERT(*(res.begin())=="x"); - expr5.prepareExprEvaluationVec(); - input[0]=273.15; - expr5.evaluateExpr(1,input,res2); - CPPUNIT_ASSERT_DOUBLES_EQUAL(29282.131520617437,res2[0],1e-9); - input[0]=0.; - CPPUNIT_ASSERT_THROW(expr5.evaluateExpr(1,input,res2),INTERP_KERNEL::Exception); -} - -/*! - * Bug detected by Marc concerning expressions with blanks. - */ -void ExprEvalInterpTest::testInterpreter4() -{ - INTERP_KERNEL::ExprParser expr("2*x + 1"); - double vals[3]={0.1,0.2,0.3}; - std::vector varsV(3); - varsV[0] = "x"; - varsV[1] = "y"; - varsV[2] = "z"; - expr.parse(); - expr.prepareExprEvaluation(varsV,3,1); - double result; - expr.evaluateExpr(1,vals, &result); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1.2,result,1e-12); -} - -/*! - * Allowing scientific format for floats. - */ -void ExprEvalInterpTest::testInterpreter5() -{ - std::set res; - double input[3]; - double res2[3]; - INTERP_KERNEL::ExprParser expr1("1.85e-3*x"); - expr1.parse(); - expr1.getSetOfVars(res); - CPPUNIT_ASSERT_EQUAL(1,(int)res.size()); - CPPUNIT_ASSERT(*(res.begin())=="x"); - input[0]=56.7; - expr1.prepareExprEvaluationVec(); - expr1.evaluateExpr(1,input,res2); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.104895,res2[0],1e-12); - input[0]=-65.7; - expr1.evaluateExpr(1,input,res2); - CPPUNIT_ASSERT_DOUBLES_EQUAL(-0.121545,res2[0],1e-12); - // - INTERP_KERNEL::ExprParser expr2("x*1.85e-3"); - expr2.parse(); - expr2.getSetOfVars(res); - CPPUNIT_ASSERT_EQUAL(1,(int)res.size()); - CPPUNIT_ASSERT(*(res.begin())=="x"); - input[0]=56.7; - expr2.prepareExprEvaluationVec(); - expr2.evaluateExpr(1,input,res2); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.104895,res2[0],1e-12); - input[0]=-65.7; - expr2.evaluateExpr(1,input,res2); - CPPUNIT_ASSERT_DOUBLES_EQUAL(-0.121545,res2[0],1e-12); - // - INTERP_KERNEL::ExprParser expr3("2.6E+1+x*1.85e-3"); - expr3.parse(); - expr3.getSetOfVars(res); - CPPUNIT_ASSERT_EQUAL(1,(int)res.size()); - CPPUNIT_ASSERT(*(res.begin())=="x"); - input[0]=56.7; - expr3.prepareExprEvaluationVec(); - expr3.evaluateExpr(1,input,res2); - CPPUNIT_ASSERT_DOUBLES_EQUAL(26.104895,res2[0],1e-12); - input[0]=-65.7; - expr3.evaluateExpr(1,input,res2); - CPPUNIT_ASSERT_DOUBLES_EQUAL(25.878455,res2[0],1e-12); - // - INTERP_KERNEL::ExprParser expr4("3.*max(((3.2e+1*(ln((2*5.2E-02+6.)+(1.2E-001*1.2E+2+3e-4))))),((3.2E-2*(exp((6e-1+2*5.2e-2)+(1.2E001*1.2+3.))))))"); - expr4.parse(); - CPPUNIT_ASSERT_DOUBLES_EQUAL(6994207.8359543988,expr4.evaluate(),1e-5); -} - -/*! - * Test focusing on fast evaluator. - */ -void ExprEvalInterpTest::testInterpreter6() -{ - std::vector stackOfVal; - // - stackOfVal.clear(); - INTERP_KERNEL::ExprParser expr1("1.-2./3."); - expr1.parse(); - expr1.prepareFastEvaluator(); - expr1.evaluateDoubleInternal(stackOfVal); - CPPUNIT_ASSERT_EQUAL(1,(int)stackOfVal.size()); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.33333333333333333,stackOfVal.back(),1e-14); - // - stackOfVal.clear(); - INTERP_KERNEL::ExprParser expr2("1.-2.^3."); - expr2.parse(); - expr2.prepareFastEvaluator(); - expr2.evaluateDoubleInternal(stackOfVal); - CPPUNIT_ASSERT_EQUAL(1,(int)stackOfVal.size()); - CPPUNIT_ASSERT_DOUBLES_EQUAL(-7.,stackOfVal.back(),1e-14); - // - stackOfVal.clear(); - INTERP_KERNEL::ExprParser expr3("(7.-2.)^3."); - expr3.parse(); - expr3.prepareFastEvaluator(); - expr3.evaluateDoubleInternal(stackOfVal); - CPPUNIT_ASSERT_EQUAL(1,(int)stackOfVal.size()); - CPPUNIT_ASSERT_DOUBLES_EQUAL(125.,stackOfVal.back(),1e-12); - // now playing with one parameter - calling several times - stackOfVal.clear(); - INTERP_KERNEL::ExprParser expr4("1.2/(7.-2.*cos(x/3))"); - expr4.parse(); - expr4.prepareFastEvaluator(); - double z; - expr4.prepareExprEvaluationDouble(std::vector(1,"x"),1,1,0,&z,&z+1); - expr4.prepareFastEvaluator(); - z=0.77; - expr4.evaluateDoubleInternal(stackOfVal); - CPPUNIT_ASSERT_EQUAL(1,(int)stackOfVal.size()); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.23689586281558844,stackOfVal.back(),1e-12); - stackOfVal.pop_back(); - z=0.55; - expr4.evaluateDoubleInternal(stackOfVal); - CPPUNIT_ASSERT_EQUAL(1,(int)stackOfVal.size()); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.2384018932069258,stackOfVal.back(),1e-12); - // - stackOfVal.clear(); - INTERP_KERNEL::ExprParser expr5("x-2*cos(y/3.)"); - expr5.parse(); - expr5.prepareFastEvaluator(); - double *aa(new double[2]); - std::vector vv(2); vv[0]="x"; vv[1]="y"; - expr5.prepareExprEvaluationDouble(vv,2,1,0,aa,aa+2); - expr5.prepareFastEvaluator(); - aa[0]=0.3; aa[1]=0.5; - expr5.evaluateDoubleInternal(stackOfVal); - CPPUNIT_ASSERT_EQUAL(1,(int)stackOfVal.size()); - CPPUNIT_ASSERT_DOUBLES_EQUAL(-1.67228646312585,stackOfVal.back(),1e-14); - stackOfVal.pop_back(); - aa[0]=0.5; aa[1]=0.3; - expr5.evaluateDoubleInternal(stackOfVal); - CPPUNIT_ASSERT_EQUAL(1,(int)stackOfVal.size()); - CPPUNIT_ASSERT_DOUBLES_EQUAL(-1.4900083305560516,stackOfVal.back(),1e-14); - stackOfVal.pop_back(); - delete [] aa; - // - stackOfVal.clear(); - INTERP_KERNEL::ExprParser expr6("x*IVec-2*cos(y/3.)*JVec"); - expr6.parse(); - aa=new double[2]; - vv.resize(2); vv[0]="x"; vv[1]="y"; - expr6.prepareExprEvaluationDouble(vv,2,2,0,aa,aa+2);//emulate 1st interpreter - expr6.prepareFastEvaluator(); - aa[0]=0.3; aa[1]=0.5; - expr6.evaluateDoubleInternal(stackOfVal); - CPPUNIT_ASSERT_EQUAL(1,(int)stackOfVal.size()); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.3,stackOfVal.back(),1e-14); - stackOfVal.pop_back(); - expr6.prepareExprEvaluationDouble(vv,2,2,1,aa,aa+2);//emulate 2nd interpreter - expr6.prepareFastEvaluator(); - expr6.evaluateDoubleInternal(stackOfVal); - CPPUNIT_ASSERT_EQUAL(1,(int)stackOfVal.size()); - CPPUNIT_ASSERT_DOUBLES_EQUAL(-1.97228646312585,stackOfVal.back(),1e-14); - stackOfVal.pop_back(); - delete [] aa; - // - stackOfVal.clear(); - INTERP_KERNEL::ExprParser expr7("if(x>3.,-6,7.)"); - expr7.parse(); - expr7.prepareExprEvaluationDouble(std::vector(1,"x"),1,1,0,&z,&z+1); - expr7.prepareFastEvaluator(); - z=3.1; - expr7.evaluateDoubleInternal(stackOfVal); - CPPUNIT_ASSERT_EQUAL(1,(int)stackOfVal.size()); - CPPUNIT_ASSERT_DOUBLES_EQUAL(-6.,stackOfVal.back(),1e-14); - stackOfVal.pop_back(); - z=2.8; - expr7.evaluateDoubleInternal(stackOfVal); - CPPUNIT_ASSERT_EQUAL(1,(int)stackOfVal.size()); - CPPUNIT_ASSERT_DOUBLES_EQUAL(7.,stackOfVal.back(),1e-14); - stackOfVal.pop_back(); - // - stackOfVal.clear(); - INTERP_KERNEL::ExprParser expr8("if(x<3.,-6,7.)"); - expr8.parse(); - expr8.prepareExprEvaluationDouble(std::vector(1,"x"),1,1,0,&z,&z+1); - expr8.prepareFastEvaluator(); - z=3.1; - expr8.evaluateDoubleInternal(stackOfVal); - CPPUNIT_ASSERT_EQUAL(1,(int)stackOfVal.size()); - CPPUNIT_ASSERT_DOUBLES_EQUAL(7.,stackOfVal.back(),1e-14); - stackOfVal.pop_back(); - z=2.8; - expr8.evaluateDoubleInternal(stackOfVal); - CPPUNIT_ASSERT_EQUAL(1,(int)stackOfVal.size()); - CPPUNIT_ASSERT_DOUBLES_EQUAL(-6.,stackOfVal.back(),1e-14); - stackOfVal.pop_back(); - // - stackOfVal.clear(); - INTERP_KERNEL::ExprParser expr9("x*x/2");//this test is very important to test for iso priority with more than one - expr9.parse(); - expr9.prepareExprEvaluationDouble(std::vector(1,"x"),1,1,0,&z,&z+1); - expr9.prepareFastEvaluator(); - z=3.; - expr9.evaluateDoubleInternal(stackOfVal); - CPPUNIT_ASSERT_EQUAL(1,(int)stackOfVal.size()); - CPPUNIT_ASSERT_DOUBLES_EQUAL(4.5,stackOfVal.back(),1e-14); - stackOfVal.pop_back(); - // - stackOfVal.clear(); - INTERP_KERNEL::ExprParser expr10("2./3./4./5."); - expr10.parse(); - expr10.prepareFastEvaluator(); - expr10.evaluateDoubleInternal(stackOfVal); - CPPUNIT_ASSERT_EQUAL(1,(int)stackOfVal.size()); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.03333333333333333,stackOfVal.back(),1e-13); - // - stackOfVal.clear(); - INTERP_KERNEL::ExprParser expr11("2./3./4.*5."); - expr11.parse(); - expr11.prepareFastEvaluator(); - expr11.evaluateDoubleInternal(stackOfVal); - CPPUNIT_ASSERT_EQUAL(1,(int)stackOfVal.size()); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.83333333333333333,stackOfVal.back(),1e-14); - // - stackOfVal.clear(); - INTERP_KERNEL::ExprParser expr12("2./3.*4.*5."); - expr12.parse(); - expr12.prepareFastEvaluator(); - expr12.evaluateDoubleInternal(stackOfVal); - CPPUNIT_ASSERT_EQUAL(1,(int)stackOfVal.size()); - CPPUNIT_ASSERT_DOUBLES_EQUAL(13.333333333333333,stackOfVal.back(),1e-14); -} diff --git a/src/INTERP_KERNELTest/ExprEvalInterpTest.hxx b/src/INTERP_KERNELTest/ExprEvalInterpTest.hxx deleted file mode 100644 index 5d5bd0ef8..000000000 --- a/src/INTERP_KERNELTest/ExprEvalInterpTest.hxx +++ /dev/null @@ -1,63 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 -// 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 _EXPREVALINTERPTEST_HXX_ -#define _EXPREVALINTERPTEST_HXX_ - -#include - -#include "InterpKernelTestExport.hxx" - -namespace INTERP_TEST -{ - class INTERPKERNELTEST_EXPORT ExprEvalInterpTest : public CppUnit::TestFixture - { - CPPUNIT_TEST_SUITE( ExprEvalInterpTest ); - CPPUNIT_TEST( testBuildStringFromFortran ); - CPPUNIT_TEST( testDeleteWhiteSpaces ); - CPPUNIT_TEST( testInterpreter0 ); - CPPUNIT_TEST( testInterpreter1 ); - CPPUNIT_TEST( testInterpreter2 ); - CPPUNIT_TEST( testInterpreterUnit0 ); - CPPUNIT_TEST( testInterpreterUnit1 ); - CPPUNIT_TEST( testInterpreter3 ); - CPPUNIT_TEST( testInterpreter4 ); - CPPUNIT_TEST( testInterpreter5 ); - CPPUNIT_TEST( testInterpreter6 ); - CPPUNIT_TEST_SUITE_END(); - public: - void setUp() { } - void tearDown() { } - void cleanUp() { } - void testBuildStringFromFortran(); - void testDeleteWhiteSpaces(); - void testInterpreter0(); - void testInterpreter1(); - void testInterpreter2(); - void testInterpreter3(); - void testInterpreter4(); - void testInterpreter5(); - void testInterpreter6(); - void testInterpreterUnit0(); - void testInterpreterUnit1(); - }; -} - -#endif diff --git a/src/INTERP_KERNELTest/HexaTests.hxx b/src/INTERP_KERNELTest/HexaTests.hxx deleted file mode 100644 index 3edcbd326..000000000 --- a/src/INTERP_KERNELTest/HexaTests.hxx +++ /dev/null @@ -1,76 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 -// 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 __HEXA_TESTS_HXX_ -#define __HEXA_TESTS_HXX_ - -#include "InterpolationTestSuite.hxx" - -namespace INTERP_TEST -{ - /** - * \brief Class performing intersection tests on meshes with hexahedral elements. - * - */ - class HexaTests : public InterpolationTestSuite<3,3> - { - CPPUNIT_TEST_SUITE( HexaTests ); - - CPPUNIT_TEST( simpleHexaBox ); - //VB : slightly inaccurate so that it triggers a failure of the test - // should be investigated in the future - // CPPUNIT_TEST( reflexiveHexaBox ); - CPPUNIT_TEST( hexaBoxes ); - CPPUNIT_TEST( hexaBoxesMoved ); - - CPPUNIT_TEST_SUITE_END(); - - public: - - /// Intersection between two boxes, aligned with the axes.One has 60 hexahedral elements and the other has 39 tetrahedral elements - /// \brief Status : pass - void simpleHexaBox() - { - _testTools->intersectMeshes("BoxHexa1", "BoxTetra2", 65250, 1.0e-5); - } - - /// Intersection of a box with 60 hexahedral elements with itself - /// \brief Status : pass - void reflexiveHexaBox() - { - _testTools->intersectMeshes("BoxHexa1", "BoxHexa1", 204000); - } - - /// Intersection between two boxes, aligned with the axes.Both have hexahedral elements : one 36, the other 60 - /// \brief Status : pass - void hexaBoxes() - { - _testTools->intersectMeshes("BoxHexa1", "BoxHexa2", 65250); - } - - /// Intersection between two boxes in general position with hexahedral elements. One has 200 elements and the other 420. - /// \brief Status : fails - reason unknown. The matrix does not fulfil the transpose requirement : that W_AB = W_BA^T - void hexaBoxesMoved() - { - _testTools->intersectMeshes("MovedHexaBox1", "MovedHexaBox2", 65250); - } - - }; -} -#endif diff --git a/src/INTERP_KERNELTest/InterpKernelTestExport.hxx b/src/INTERP_KERNELTest/InterpKernelTestExport.hxx deleted file mode 100644 index f34c58fe4..000000000 --- a/src/INTERP_KERNELTest/InterpKernelTestExport.hxx +++ /dev/null @@ -1,33 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 -// 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 _INTERPKERNELTESTEXPORT_HXX_ -#define _INTERPKERNELTESTEXPORT_HXX_ - -#ifdef WIN32 -# if defined InterpKernelTest_EXPORTS -# define INTERPKERNELTEST_EXPORT __declspec( dllexport ) -# else -# define INTERPKERNELTEST_EXPORT __declspec( dllimport ) -# endif -#else -# define INTERPKERNELTEST_EXPORT -#endif - -#endif diff --git a/src/INTERP_KERNELTest/Interpolation3DTest.cxx b/src/INTERP_KERNELTest/Interpolation3DTest.cxx deleted file mode 100644 index db32ed895..000000000 --- a/src/INTERP_KERNELTest/Interpolation3DTest.cxx +++ /dev/null @@ -1,344 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// - -#include "Interpolation3DTest.hxx" - -#include "MEDFileMesh.hxx" -#include "MEDCouplingUMesh.hxx" -#include "MEDCouplingFieldDouble.hxx" - -#include -#include -#include -#include -#include - -#include "VectorUtils.hxx" - -// levels : -// 1 - titles and volume results -// 2 - symmetry / diagonal results and intersection matrix output -// 3 - empty -// 4 - empty -// 5 - misc -#include "Log.hxx" - - -//#define VOL_PREC 1.0e-6 - -using namespace ParaMEDMEM; -using namespace INTERP_KERNEL; - -double Interpolation3DTest::sumRow(const IntersectionMatrix& m, int i) const -{ - double vol = 0.0; - for(IntersectionMatrix::const_iterator iter = m.begin() ; iter != m.end() ; ++iter) - { - if(iter->count(i) != 0.0) - { - std::map::const_iterator iter2 = iter->find(i); - vol += iter2->second; - } - } - return vol; -} - -double Interpolation3DTest::sumCol(const IntersectionMatrix& m, int i) const -{ - double vol = 0.0; - const std::map& col = m[i]; - for(std::map::const_iterator iter = col.begin() ; iter != col.end() ; ++iter) - { - vol += std::fabs(iter->second); - } - return vol; -} - - -void Interpolation3DTest::getVolumes(ParaMEDMEM::MEDCouplingUMesh& mesh, double *tab) const -{ - MEDCouplingAutoRefCountObjectPtr vol=mesh->getMeasureField(true); - std::copy(vol->getArray()->begin(),vol->getArray()->end(),tab); -} - -double Interpolation3DTest::sumVolume(const IntersectionMatrix& m) const -{ - - std::vector volumes; - for(IntersectionMatrix::const_iterator iter = m.begin() ; iter != m.end() ; ++iter) - { - for(std::map::const_iterator iter2 = iter->begin() ; iter2 != iter->end() ; ++iter2) - { - volumes.push_back(iter2->second); - // vol += std::abs(iter2->second); - } - } - - // sum in ascending order to avoid rounding errors - - sort(volumes.begin(), volumes.end()); - const double vol = accumulate(volumes.begin(), volumes.end(), 0.0); - - return vol; -} - -bool Interpolation3DTest::testVolumes(const IntersectionMatrix& m, MEDCouplingUMesh& sMesh, MEDCouplingUMesh& tMesh) const -{ - bool ok = true; - - // source elements - double* sVol = new double[sMesh.getNumberOfCells()]; - getVolumes(sMesh, sVol); - - for(int i = 0; i < sMesh.getNumberOfCells(); ++i) - { - const double sum_row = sumRow(m, i+1); - if(!epsilonEqualRelative(sum_row, sVol[i], VOL_PREC)) - { - LOG(1, "Source volume inconsistent : vol of cell " << i << " = " << sVol[i] << " but the row sum is " << sum_row ); - ok = false; - } - LOG(1, "diff = " <::const_iterator iter2 = iter->begin() ; iter2 != iter->end() ; ++iter2) - { - int j = iter2->first; - const double v1 = iter2->second; - //if(m2[j - 1].count(i+1) > 0) - // { - std::map theMap = m2.at(j-1); - const double v2 = theMap[i + 1]; - if(v1 != v2) - { - LOG(2, "V1( " << i << ", " << j << ") = " << v1 << " which is different from V2( " << j - 1 << ", " << i + 1 << ") = " << v2 << " | diff = " << v1 - v2 ); - if(!epsilonEqualRelative(v1, v2, VOL_PREC)) - { - LOG(2, "(" << i << ", " << j << ") fails"); - isSymmetric = false; - } - } - } - ++i; - } - if(!isSymmetric) - { - LOG(1, "*** matrices are not symmetric"); - } - return isSymmetric; -} - -bool Interpolation3DTest::testDiagonal(const IntersectionMatrix& m) const -{ - LOG(1, "Checking if matrix is diagonal" ); - int i = 1; - bool isDiagonal = true; - for(IntersectionMatrix::const_iterator iter = m.begin() ; iter != m.end() ; ++iter) - { - for(std::map::const_iterator iter2 = iter->begin() ; iter2 != iter->end() ; ++iter2) - { - int j = iter2->first; - const double vol = iter2->second; - if(vol != 0.0 && (i != j)) - { - LOG(2, "V( " << i - 1 << ", " << j << ") = " << vol << " which is not zero" ); - if(!epsilonEqual(vol, 0.0, VOL_PREC)) - { - LOG(2, "(" << i << ", " << j << ") fails"); - isDiagonal = false; - } - } - } - ++i; - } - if(!isDiagonal) - { - LOG(1, "*** matrix is not diagonal"); - } - return isDiagonal; -} - -void Interpolation3DTest::dumpIntersectionMatrix(const IntersectionMatrix& m) const -{ - int i = 0; - std::cout << "Intersection matrix is " << std::endl; - for(IntersectionMatrix::const_iterator iter = m.begin() ; iter != m.end() ; ++iter) - { - for(std::map::const_iterator iter2 = iter->begin() ; iter2 != iter->end() ; ++iter2) - { - - std::cout << "V(" << i << ", " << iter2->first << ") = " << iter2->second << std::endl; - - } - ++i; - } - std::cout << "Sum of volumes = " << sumVolume(m) << std::endl; -} - -void Interpolation3DTest::setUp() -{ - interpolator = new Interpolation3D(); -} - -void Interpolation3DTest::tearDown() -{ - delete interpolator; -} - -void Interpolation3DTest::calcIntersectionMatrix(const char* mesh1path, const char* mesh1, const char* mesh2path, const char* mesh2, IntersectionMatrix& m) const -{ - const string dataBaseDir = getenv("MED_ROOT_DIR"); - const string dataDir = dataBaseDir + "/share/salome/resources/med/"; - - LOG(1, std::endl << "=== -> intersecting src = " << mesh1 << ", target = " << mesh2 ); - - LOG(5, "Loading " << mesh1 << " from " << mesh1path); - MESH sMesh(MED_DRIVER, dataDir+mesh1path, mesh1); - - LOG(5, "Loading " << mesh2 << " from " << mesh2path); - MESH tMesh(MED_DRIVER, dataDir+mesh2path, mesh2); - - m = interpolator->interpolateMeshes(sMesh, tMesh); - - // if reflexive, check volumes - if(strcmp(mesh1path,mesh2path) == 0) - { - const bool row_and_col_sums_ok = testVolumes(m, sMesh, tMesh); - CPPUNIT_ASSERT_EQUAL_MESSAGE("Row or column sums incorrect", true, row_and_col_sums_ok); - } - - LOG(1, "Intersection calculation done. " << std::endl ); - -} - -void Interpolation3DTest::intersectMeshes(const char* mesh1path, const char* mesh1, const char* mesh2path, const char* mesh2, const double correctVol, const double prec, bool doubleTest) const -{ - LOG(1, std::endl << std::endl << "=============================" ); - - using std::string; - const string path1 = string(mesh1path) + string(mesh1); - const string path2 = string(mesh2path) + string(mesh2); - - const bool isTestReflexive = (path1.compare(path2) == 0); - - IntersectionMatrix matrix1; - calcIntersectionMatrix(mesh1path, mesh1, mesh2path, mesh2, matrix1); - -#if LOG_LEVEL >= 2 - dumpIntersectionMatrix(matrix1); -#endif - - std::cout.precision(16); - - const double vol1 = sumVolume(matrix1); - - if(!doubleTest) - { - LOG(1, "vol = " << vol1 <<" correctVol = " << correctVol ); - CPPUNIT_ASSERT_DOUBLES_EQUAL(correctVol, vol1, prec * std::max(correctVol, vol1)); - - if(isTestReflexive) - { - CPPUNIT_ASSERT_EQUAL_MESSAGE("Reflexive test failed", true, testDiagonal(matrix1)); - } - } - else - { - - IntersectionMatrix matrix2; - calcIntersectionMatrix(mesh2path, mesh2, mesh1path, mesh1, matrix2); - -#if LOG_LEVEL >= 2 - dumpIntersectionMatrix(matrix2); -#endif - - const double vol2 = sumVolume(matrix2); - - LOG(1, "vol1 = " << vol1 << ", vol2 = " << vol2 << ", correctVol = " << correctVol ); - - CPPUNIT_ASSERT_DOUBLES_EQUAL(correctVol, vol1, prec * std::max(vol1, correctVol)); - CPPUNIT_ASSERT_DOUBLES_EQUAL(correctVol, vol2, prec * std::max(vol2, correctVol)); - CPPUNIT_ASSERT_DOUBLES_EQUAL(vol1, vol2, prec * std::max(vol1, vol2)); - CPPUNIT_ASSERT_EQUAL_MESSAGE("Symmetry test failed", true, testSymmetric(matrix1, matrix2)); - } - -} - - - diff --git a/src/INTERP_KERNELTest/Interpolation3DTest.hxx b/src/INTERP_KERNELTest/Interpolation3DTest.hxx deleted file mode 100644 index 6680f94e9..000000000 --- a/src/INTERP_KERNELTest/Interpolation3DTest.hxx +++ /dev/null @@ -1,49 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 -// 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 __TU_INTERPOLATION_3D_TEST_HXX__ -#define __TU_INTERPOLATION_3D_TEST_HXX__ - -#include -#include "Interpolation3D.hxx" - -#define ERR_TOL 1.0e-8 - -/// \brief OBSOLETE - renamed Interpolation3DTestSuite -class Interpolation3DTest : public CppUnit::TestFixture -{ - -public: - void setUp() - { - _testTools = new MeshTestToolkit(); - } - - void tearDown() - { - delete _testTools; - } - -protected: - - MeshToolkit* _testTools; - -}; - -#endif diff --git a/src/INTERP_KERNELTest/InterpolationOptionsTest.cxx b/src/INTERP_KERNELTest/InterpolationOptionsTest.cxx deleted file mode 100644 index 9bc5c7406..000000000 --- a/src/INTERP_KERNELTest/InterpolationOptionsTest.cxx +++ /dev/null @@ -1,90 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// - -#include "MEDFileMesh.hxx" -#include "MEDCouplingFieldDouble.hxx" - -#include "InterpolationOptionsTest.hxx" -#include "MEDCouplingNormalizedUnstructuredMesh.txx" -#include "Interpolation2D.txx" -#include "TestInterpKernelUtils.hxx" - -#include -#include - -using namespace ParaMEDMEM; - -namespace INTERP_TEST -{ - void InterpolationOptionsTest::setUp() - { - } - - - void InterpolationOptionsTest::tearDown() - { - } - - /** - * Test that creates a tree in 2D and check that - * the results are correct in three - * cases : - * a non matching search - * a standard case - * a bbox overlapping the bboxes of the tree - */ - void InterpolationOptionsTest::test_InterpolationOptions() - { - std::string sourcename=INTERP_TEST::getResourceFile("square1.med"); - MEDFileUMesh *source_mesh=MEDFileUMesh::New(sourcename.c_str(),"Mesh_2"); - - std::string targetname=INTERP_TEST::getResourceFile("square2.med"); - MEDFileUMesh *target_mesh=MEDFileUMesh::New(targetname.c_str(),"Mesh_3"); - - MEDCouplingUMesh *source_mesh_mc=source_mesh->getMeshAtLevel(0); - MEDCouplingFieldDouble *source_field=MEDCouplingFieldDouble::New(ON_CELLS); - source_field->setMesh(source_mesh_mc); source_mesh_mc->decrRef(); - DataArrayDouble *arr=DataArrayDouble::New(); arr->alloc(source_mesh_mc->getNumberOfCells(),1); - source_field->setArray(arr); arr->decrRef(); - double *value=arr->getPointer(); - for(int i=0; igetNumberOfCells(); i++) - value[i]=1.0; - MEDCouplingUMesh *target_mesh_mc=target_mesh->getMeshAtLevel(0); - MEDCouplingFieldDouble *target_field=MEDCouplingFieldDouble::New(ON_CELLS); - target_field->setMesh(target_mesh_mc); target_mesh_mc->decrRef(); - arr=DataArrayDouble::New(); arr->alloc(target_mesh_mc->getNumberOfCells(),1); - target_field->setArray(arr); arr->decrRef(); - double* targetvalue=arr->getPointer(); - for(int i=0; igetNumberOfCells(); i++) - targetvalue[i]=0.0; - // Ok at this point we have our mesh in MED-Memory format. - // Go to wrap med_source_mesh and med_target_mesh. - MEDCouplingNormalizedUnstructuredMesh<2,2> wrap_source_mesh(source_mesh_mc); - MEDCouplingNormalizedUnstructuredMesh<2,2> wrap_target_mesh(target_mesh_mc); - // Go for interpolation... - INTERP_KERNEL::Interpolation2D myInterpolator; - //optionnal call to parametrize your interpolation. First precision, tracelevel, intersector wanted. - myInterpolator.setPrecision(1e-7); - myInterpolator.setPrintLevel(1); - source_mesh->decrRef(); - source_field->decrRef(); - target_field->decrRef(); - target_mesh->decrRef(); - } -} diff --git a/src/INTERP_KERNELTest/InterpolationOptionsTest.hxx b/src/INTERP_KERNELTest/InterpolationOptionsTest.hxx deleted file mode 100644 index d97856a59..000000000 --- a/src/INTERP_KERNELTest/InterpolationOptionsTest.hxx +++ /dev/null @@ -1,62 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 -// 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 __TU_INTERPOLATIONOPTIONS_HXX__ -#define __TU_INTERPOLATIONOPTIONS_HXX__ - -#include - -#include "InterpKernelTestExport.hxx" -#include "InterpolationOptions.hxx" - -namespace INTERP_TEST -{ - - /** - * \brief Test suite testing some of the low level methods of TransformedTriangle. - * - */ - class INTERPKERNELTEST_EXPORT InterpolationOptionsTest : public CppUnit::TestFixture - { - - CPPUNIT_TEST_SUITE( InterpolationOptionsTest ); - CPPUNIT_TEST( test_InterpolationOptions ); - CPPUNIT_TEST_SUITE_END(); - - - public: - void setUp(); - - void tearDown(); - - // tests - void test_InterpolationOptions(); - - private: - - }; - - - - -} - - - -#endif diff --git a/src/INTERP_KERNELTest/InterpolationPlanarTestSuite.hxx b/src/INTERP_KERNELTest/InterpolationPlanarTestSuite.hxx deleted file mode 100644 index 6d9c84f9e..000000000 --- a/src/INTERP_KERNELTest/InterpolationPlanarTestSuite.hxx +++ /dev/null @@ -1,127 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 -// 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 __TU_INTERPOLATION_PLANAR_TEST_SUITE_HXX__ -#define __TU_INTERPOLATION_PLANAR_TEST_SUITE_HXX__ - -#include -#include -#include -#include - -namespace INTERP_TEST -{ - - /** - * \brief Base class for planar mesh intersection test suites. - * - */ - class InterpolationPlanarTestSuite : public CppUnit::TestFixture - { - - public: - double _Epsilon; - double _Precision; - - /** - * Sets up the test suite. - * - */ - void setUp() - { - _Epsilon = 1.e-6; - _Precision = 1.e-6; - } - void tearDown() {} - - // bool checkDequesEqual(std::deque< double > deque1, std::deque< double > deque2, double epsilon); - // bool checkVectorsEqual(std::vector< double > Vect1, std::vector< double > Vect2, double epsilon); - // void dequePrintOut(std::deque< double > deque1); - // void vectPrintOut(std::vector< double > vect); - // void tabPrintOut( const double * tab, int size); - - bool checkDequesEqual(std::deque< double > deque1, - std::deque< double > deque2, double epsilon) - { - int size1 = deque1.size(); - int size2 = deque2.size(); - bool are_equal = size1 == size2; - - if(are_equal) - for(int i = 0; i < size1 && are_equal; i++) - are_equal = fabs(deque1[i] - deque2[i]) < epsilon; - - return are_equal; - } - bool checkVectorsEqual(std::vector< double > vect1, - std::vector< double > vect2, double epsilon) - { - int size1 = vect1.size(); - int size2 = vect2.size(); - bool are_equal = size1 == size2; - - if(are_equal) - for(int i = 0; i < size1 && are_equal; i++) - are_equal = fabs(vect1[i] - vect2[i]) < epsilon; - - return are_equal; - } - void dequePrintOut(std::deque< double > deque1) - { - for(int i = 0; i< (int)deque1.size(); i++) - { - std::cerr << deque1[i] << " "; - } - std::cerr<< std::endl; - } - void vectPrintOut(std::vector< double > vect) - { - for(int i = 0; i< (int)vect.size(); i++) - { - std::cerr << vect[i] << " "; - } - std::cerr<< std::endl; - } - void tabPrintOut( const double * tab,int size) - { - for(int i = 0; i< size; i++) - { - std::cerr << tab[i] << " "; - } - std::cerr<< std::endl; - } - - /** - * Cleans up after the test suite. - * Liberates the MeshTestToolkit object used by the tests. - */ - // void tearDown() - // { - // delete _testTools; - // } - - - - // protected: - // /// MeshTestToolkit object to which the tests are delegated - // MeshTestToolkit* _testTools; - - }; -} -#endif diff --git a/src/INTERP_KERNELTest/InterpolationTestSuite.hxx b/src/INTERP_KERNELTest/InterpolationTestSuite.hxx deleted file mode 100644 index 9c4ec7a7b..000000000 --- a/src/INTERP_KERNELTest/InterpolationTestSuite.hxx +++ /dev/null @@ -1,66 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 -// 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 __TU_INTERPOLATION_TEST_SUITE_HXX__ -#define __TU_INTERPOLATION_TEST_SUITE_HXX__ - -#include "MeshTestToolkit.txx" - -#include - -namespace INTERP_TEST -{ - - /** - * \brief Base class for mesh intersection test suites. - * - */ - template - class InterpolationTestSuite : public CppUnit::TestFixture - { - - public: - /** - * Sets up the test suite. - * Creates the MeshTestToolkit object used by the tests. - * - */ - void setUp() - { - _testTools = new MeshTestToolkit(); - } - - /** - * Cleans up after the test suite. - * Liberates the MeshTestToolkit object used by the tests. - */ - void tearDown() - { - delete _testTools; - } - - - - protected: - /// MeshTestToolkit object to which the tests are delegated - MeshTestToolkit* _testTools; - - }; -} -#endif diff --git a/src/INTERP_KERNELTest/MEDMeshMaker.cxx b/src/INTERP_KERNELTest/MEDMeshMaker.cxx deleted file mode 100644 index f0538b113..000000000 --- a/src/INTERP_KERNELTest/MEDMeshMaker.cxx +++ /dev/null @@ -1,48 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// - -#include "MEDCouplingAutoRefCountObjectPtr.hxx" -#include "MEDCouplingCMesh.hxx" - -#include "MEDMeshMaker.hxx" - -using namespace ParaMEDMEM; - -ParaMEDMEM::MEDCouplingUMesh *MEDMeshMaker(int dim, int nbedge) -{ - MEDCouplingAutoRefCountObjectPtr c=MEDCouplingCMesh::New(); - MEDCouplingAutoRefCountObjectPtr arr=DataArrayDouble::New(); - arr->alloc(nbedge+1,1); arr->iota(0.); arr->applyLin(1./double(nbedge),0.); - switch(dim) - { - case 2: - { - c->setCoords(arr,arr); - break; - } - case 3: - { - c->setCoords(arr,arr,arr); - break; - } - default: - throw INTERP_KERNEL::Exception("MEDMeshMaker : only dim 2 or 3 supported !"); - } - return c->buildUnstructured(); -} diff --git a/src/INTERP_KERNELTest/MEDMeshMaker.hxx b/src/INTERP_KERNELTest/MEDMeshMaker.hxx deleted file mode 100644 index 44bcdf19b..000000000 --- a/src/INTERP_KERNELTest/MEDMeshMaker.hxx +++ /dev/null @@ -1,22 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// - -#include "MEDCouplingUMesh.hxx" - -ParaMEDMEM::MEDCouplingUMesh *MEDMeshMaker(int dim, int nbedge); diff --git a/src/INTERP_KERNELTest/MeshTestToolkit.hxx b/src/INTERP_KERNELTest/MeshTestToolkit.hxx deleted file mode 100644 index 0144c9d0f..000000000 --- a/src/INTERP_KERNELTest/MeshTestToolkit.hxx +++ /dev/null @@ -1,90 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 -// 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 __TU_MESH_TEST_TOOLKIT_HXX__ -#define __TU_MESH_TEST_TOOLKIT_HXX__ - -#include "Interpolation3D.hxx" -#include "Interpolation3D.txx" -#include "InterpolationPlanar.hxx" - -#include -#include - -#define ERR_TOL 1.0e-8 - -typedef std::vector > IntersectionMatrix; - -namespace INTERP_KERNEL -{ - class Interpolation3D; -} - - -namespace ParaMEDMEM -{ - class MEDCouplingUMesh; -} - -namespace INTERP_TEST -{ - /** - * \brief Class providing services for mesh intersection tests. - * - */ - template - class MeshTestToolkit - { - - public: - double _precision; - INTERP_KERNEL::IntersectionType _intersectionType;//Used only in the case MESHDIM==2 (planar intersections) - - MeshTestToolkit():_precision(1.e-6),_intersectionType(INTERP_KERNEL::Triangulation) {} - - ~MeshTestToolkit() {} - - void intersectMeshes(const char* mesh1, const char* mesh2, const double correctVol, const double prec = 1.0e-5, bool doubleTest = true) const; - - // 1.0e-5 here is due to limited precision of "correct" volumes calculated in Salome - void intersectMeshes(const char* mesh1path, const char* mesh1, const char* mesh2path, const char* mesh2, const double correctVol, const double prec = 1.0e-5, bool doubleTest = true) const; - - void dumpIntersectionMatrix(const IntersectionMatrix& m) const; - - double sumRow(const IntersectionMatrix& m, int i) const; - - double sumCol(const IntersectionMatrix& m, int i) const; - - void getVolumes(ParaMEDMEM::MEDCouplingUMesh& mesh, double* tab) const; - - bool testVolumes(const IntersectionMatrix& m, ParaMEDMEM::MEDCouplingUMesh& sMesh, ParaMEDMEM::MEDCouplingUMesh& tMesh) const; - - double sumVolume(const IntersectionMatrix& m) const; - - bool areCompatitable( const IntersectionMatrix& m1, const IntersectionMatrix& m2) const; - - bool testTranspose(const IntersectionMatrix& m1, const IntersectionMatrix& m2) const; - - bool testDiagonal(const IntersectionMatrix& m) const; - - void calcIntersectionMatrix(const char* mesh1path, const char* mesh1, const char* mesh2path, const char* mesh2, IntersectionMatrix& m) const; - - }; -} -#endif diff --git a/src/INTERP_KERNELTest/MeshTestToolkit.txx b/src/INTERP_KERNELTest/MeshTestToolkit.txx deleted file mode 100644 index 9096963ce..000000000 --- a/src/INTERP_KERNELTest/MeshTestToolkit.txx +++ /dev/null @@ -1,483 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// -#include "TestInterpKernelUtils.hxx" - -#include "MeshTestToolkit.hxx" - -#include "MEDFileMesh.hxx" - -#include "MEDCouplingNormalizedUnstructuredMesh.hxx" -#include "MEDCouplingNormalizedUnstructuredMesh.txx" -#include "MEDCouplingFieldDouble.hxx" - -#include "Interpolation3DSurf.hxx" -#include "Interpolation2D.txx" -#include "Interpolation3D.txx" - -#include -#include -#include -#include -#include -#include - - -// levels : -// 1 - titles and volume results -// 2 - symmetry / diagonal results and intersection matrix output -// 3 - empty -// 4 - empty -// 5 - misc -#include "Log.hxx" - -#include - -//#define VOL_PREC 1.0e-6 -using namespace ParaMEDMEM; -using namespace INTERP_KERNEL; - -namespace INTERP_TEST -{ - /** - * Calculates the sum of a row of an intersection matrix - * - * @param m an intersection matrix - * @param i the index of the row (1 <= i <= no. rows) - * @return the sum of the values of row i - * - */ - template - double MeshTestToolkit::sumRow(const IntersectionMatrix& m, int i) const - { - double vol = 0.0; - for(IntersectionMatrix::const_iterator iter = m.begin() ; iter != m.end() ; ++iter) - { - if(iter->count(i) != 0.0) - { - std::map::const_iterator iter2 = iter->find(i); - vol += fabs(iter2->second); - } - } - return vol; - } - - /** - * Calculates the sum of a column of an intersection matrix - * - * @param m an intersection matrix - * @param i the index of the column (0 <= i <= no. rows - 1) - * @return the sum of the values of column i - * - */ - template - double MeshTestToolkit::sumCol(const IntersectionMatrix& m, int i) const - { - double vol = 0.0; - const std::map& col = m[i]; - for(std::map::const_iterator iter = col.begin() ; iter != col.end() ; ++iter) - { - vol += fabs(iter->second); - } - return vol; - } - - /** - * Gets the volumes of the elements in a mesh. - * - * @param mesh the mesh - * @param tab pointer to double[no. elements of mesh] array in which to store the volumes - */ - template - void MeshTestToolkit::getVolumes(ParaMEDMEM::MEDCouplingUMesh& mesh, double *tab) const - { - MEDCouplingAutoRefCountObjectPtr vol=mesh.getMeasureField(true); - std::copy(vol->getArray()->begin(),vol->getArray()->end(),tab); - } - - /** - * Sums all the elements (volumes) of an intersection matrix - * - * @param m the intersection matrix - * @return the sum of the elements of m - */ - - template - double MeshTestToolkit::sumVolume(const IntersectionMatrix& m) const - { - std::vector volumes; - for(IntersectionMatrix::const_iterator iter = m.begin() ; iter != m.end() ; ++iter) - { - for(std::map::const_iterator iter2 = iter->begin() ; iter2 != iter->end() ; ++iter2) - { - volumes.push_back(fabs(iter2->second)); - } - } - - // sum in ascending order to avoid rounding errors - - sort(volumes.begin(), volumes.end()); - const double vol = accumulate(volumes.begin(), volumes.end(), 0.0); - - return vol; - } - - /** - * Verifies if for a given intersection matrix the sum of each row is equal to the volumes - * of the corresponding source elements and the sum of each column is equal to the volumes - * of the corresponding target elements. This will be true as long as the meshes correspond - * to the same geometry. The equalities are in the "epsilon-sense", making sure the relative - * error is small enough. - * - * @param m the intersection matrix - * @param sMesh the source mesh - * @param tMesh the target mesh - * @return true if the condition is verified, false if not. - */ - template - bool MeshTestToolkit::testVolumes(const IntersectionMatrix& m, ParaMEDMEM::MEDCouplingUMesh& sMesh, ParaMEDMEM::MEDCouplingUMesh& tMesh) const - { - bool ok = true; - - // source elements - double* sVol = new double[sMesh.getNumberOfCells()]; - getVolumes(sMesh, sVol); - - for(int i = 0; i < sMesh.getNumberOfCells(); ++i) - { - const double sum_row = sumRow(m, i); - if(!epsilonEqualRelative(sum_row, fabs(sVol[i]), _precision)) - { - LOG(1, "Source volume inconsistent : vol of cell " << i << " = " << sVol[i] << " but the row sum is " << sum_row ); - ok = false; - } - LOG(1, "diff = " < - bool MeshTestToolkit::testTranspose(const IntersectionMatrix& m1, const IntersectionMatrix& m2) const - { - int i = 0; - bool isSymmetric = true; - - LOG(1, "Checking symmetry src - target" ); - isSymmetric = isSymmetric & areCompatitable(m1, m2) ; - LOG(1, "Checking symmetry target - src" ); - isSymmetric = isSymmetric & areCompatitable(m2, m1); - - for(IntersectionMatrix::const_iterator iter = m1.begin() ; iter != m1.end() ; ++iter) - { - for(std::map::const_iterator iter2 = iter->begin() ; iter2 != iter->end() ; ++iter2) - { - int j = iter2->first; - const double v1 = fabs(iter2->second); - //if(m2[j - 1].count(i+1) > 0) - // { - std::map theMap = m2.at(j); - const double v2 = fabs(theMap[i]); - if(v1 != v2) - { - LOG(2, "V1( " << i << ", " << j << ") = " << v1 << " which is different from V2( " << j << ", " << i << ") = " << v2 << " | diff = " << v1 - v2 ); - if(!epsilonEqualRelative(v1, v2, _precision)) - { - LOG(2, "(" << i << ", " << j << ") fails"); - isSymmetric = false; - } - } - } - ++i; - } - if(!isSymmetric) - { - LOG(1, "*** matrices are not symmetric"); - } - return isSymmetric; - } - - /** - * Tests if an intersection matrix is diagonal. - * - * @param m the intersection matrix - * @return true if m is diagonal; false if not - * - */ - template - bool MeshTestToolkit::testDiagonal(const IntersectionMatrix& m) const - { - LOG(1, "Checking if matrix is diagonal" ); - int i = 0; - bool isDiagonal = true; - for(IntersectionMatrix::const_iterator iter = m.begin() ; iter != m.end() ; ++iter) - { - for(std::map::const_iterator iter2 = iter->begin() ; iter2 != iter->end() ; ++iter2) - { - int j = iter2->first; - const double vol = iter2->second; - if(vol != 0.0 && (i != j)) - { - LOG(2, "V( " << i << ", " << j << ") = " << vol << " which is not zero" ); - if(!epsilonEqual(vol, 0.0, _precision)) - { - LOG(2, "(" << i << ", " << j << ") fails"); - isDiagonal = false; - } - } - } - ++i; - } - if(!isDiagonal) - { - LOG(1, "*** matrix is not diagonal"); - } - return isDiagonal; - } - - /** - * Outputs the intersection matrix as a list of all its elements to std::cout. - * - * @param m the intersection matrix to output - */ - template - void MeshTestToolkit::dumpIntersectionMatrix(const IntersectionMatrix& m) const - { - int i = 0; - std::cout << "Intersection matrix is " << std::endl; - for(IntersectionMatrix::const_iterator iter = m.begin() ; iter != m.end() ; ++iter) - { - for(std::map::const_iterator iter2 = iter->begin() ; iter2 != iter->end() ; ++iter2) - { - std::cout << "V(" << i << ", " << iter2->first << ") = " << iter2->second << std::endl; - } - ++i; - } - std::cout << "Sum of volumes = " << sumVolume(m) << std::endl; - } - - /** - * Calculates the intersection matrix for two meshes. - * If the source and target meshes are the same, a CppUnit assertion raised if testVolumes() returns false. - * - * @param mesh1path the path to the file containing the source mesh, relative to {$MED_ROOT_DIR}/share/salome/resources/med/ - * @param mesh1 the name of the source mesh - * @param mesh2path the path to the file containing the target mesh, relative to {$MED_ROOT_DIR}/share/salome/resources/med/ - * @param mesh2 the name of the target mesh - * @param m intersection matrix in which to store the result of the intersection - */ - template - void MeshTestToolkit::calcIntersectionMatrix(const char* mesh1path, const char* mesh1, const char* mesh2path, const char* mesh2, IntersectionMatrix& m) const - { - LOG(1, std::endl << "=== -> intersecting src = " << mesh1path << ", target = " << mesh2path ); - - LOG(5, "Loading " << mesh1 << " from " << mesh1path); - MEDCouplingAutoRefCountObjectPtr sMeshML=MEDFileUMesh::New(INTERP_TEST::getResourceFile(mesh1path).c_str(),mesh1); - MEDCouplingAutoRefCountObjectPtr sMesh=sMeshML->getMeshAtLevel(0); - - LOG(5, "Loading " << mesh2 << " from " << mesh2path); - MEDCouplingAutoRefCountObjectPtr tMeshML=MEDFileUMesh::New(INTERP_TEST::getResourceFile(mesh2path).c_str(),mesh2); - MEDCouplingAutoRefCountObjectPtr tMesh=tMeshML->getMeshAtLevel(0); - - MEDCouplingNormalizedUnstructuredMesh sMesh_wrapper(sMesh); - MEDCouplingNormalizedUnstructuredMesh tMesh_wrapper(tMesh); - - if (SPACEDIM==2 && MESHDIM==2) - { - Interpolation2D interpolator; - interpolator.setOptions(_precision, LOG_LEVEL, _intersectionType,1); - interpolator.interpolateMeshes(sMesh_wrapper, tMesh_wrapper,m,"P0P0"); - } - else if (SPACEDIM==3 && MESHDIM==2) - { - Interpolation3DSurf interpolator; - interpolator.setOptions(_precision,LOG_LEVEL, 0.5,_intersectionType,false,1); - interpolator.interpolateMeshes(sMesh_wrapper, tMesh_wrapper,m,"P0P0"); - } - else if (SPACEDIM==3 && MESHDIM==3) - { - Interpolation3D interpolator; - interpolator.interpolateMeshes(sMesh_wrapper, tMesh_wrapper,m,"P0P0"); - } - else - { - throw INTERP_KERNEL::Exception("Wrong dimensions"); - } - // if reflexive, check volumes - if(strcmp(mesh1path,mesh2path) == 0) - { - const bool row_and_col_sums_ok = testVolumes(m, *sMesh, *tMesh); - CPPUNIT_ASSERT_EQUAL_MESSAGE("Row or column sums incorrect", true, row_and_col_sums_ok); - const bool is_diagonal =testDiagonal(m); - CPPUNIT_ASSERT_EQUAL_MESSAGE("Self intersection matrix is not diagonal", true, is_diagonal); - } - - LOG(1, "Intersection calculation done. " << std::endl ); - } - - /** - * Tests the intersection algorithm for two meshes. - * Depending on the nature of the meshes, different tests will be performed. The sum of the elements will - * be compared to the given total volume of the intersection in all cases. If the two meshes are the same, then - * it will be confirmed that the intersection matrix is diagonal, otherwise the intersection matrices will be - * calculated once which each mesh as source mesh, and it will be verified that the they are each others' transpose. - * - * @param mesh1path the path to the file containing the source mesh, relative to {$MED_ROOT_DIR}/share/salome/resources/med/ - * @param mesh1 the name of the source mesh - * @param mesh2path the path to the file containing the target mesh, relative to {$MED_ROOT_DIR}/share/salome/resources/med/ - * @param mesh2 the name of the target mesh - * @param correctVol the total volume of the intersection of the two meshes - * @param prec maximum relative error to be tolerated in volume comparisions - * @param doubleTest if false, only the test with mesh 1 as the source mesh and mesh 2 as the target mesh will be performed - * - */ - template - void MeshTestToolkit::intersectMeshes(const char* mesh1path, const char* mesh1, const char* mesh2path, const char* mesh2, const double correctVol, const double prec, bool doubleTest) const - { - LOG(1, std::endl << std::endl << "=============================" ); - - using std::string; - const string path1 = string(mesh1path) + string(mesh1); - const string path2 = string(mesh2path) + string(mesh2); - - const bool isTestReflexive = (path1.compare(path2) == 0); - - IntersectionMatrix matrix1; - calcIntersectionMatrix(mesh1path, mesh1, mesh2path, mesh2, matrix1); - -#if LOG_LEVEL >= 2 - dumpIntersectionMatrix(matrix1); -#endif - - std::cout.precision(16); - - const double vol1 = sumVolume(matrix1); - - if(!doubleTest) - { - LOG(1, "vol = " << vol1 <<" correctVol = " << correctVol ); - CPPUNIT_ASSERT_DOUBLES_EQUAL(correctVol, vol1, prec * std::max(correctVol, vol1)); - - if(isTestReflexive) - { - CPPUNIT_ASSERT_EQUAL_MESSAGE("Reflexive test failed", true, testDiagonal(matrix1)); - } - } - else - { - IntersectionMatrix matrix2; - calcIntersectionMatrix(mesh2path, mesh2, mesh1path, mesh1, matrix2); - -#if LOG_LEVEL >= 2 - dumpIntersectionMatrix(matrix2); -#endif - - const double vol2 = sumVolume(matrix2); - - LOG(1, "vol1 = " << vol1 << ", vol2 = " << vol2 << ", correctVol = " << correctVol ); - - CPPUNIT_ASSERT_EQUAL_MESSAGE("Symmetry test failed", true, testTranspose(matrix1, matrix2)); - CPPUNIT_ASSERT_DOUBLES_EQUAL(correctVol, vol1, prec * std::max(vol1, correctVol)); - CPPUNIT_ASSERT_DOUBLES_EQUAL(correctVol, vol2, prec * std::max(vol2, correctVol)); - CPPUNIT_ASSERT_DOUBLES_EQUAL(vol1, vol2, prec * std::max(vol1, vol2)); - } - } - - /** - * Utility method used to facilitate the call to intersect meshes. - * It calls intersectMeshes, using "mesh1.med" as file name for the mesh with name "mesh1" and - * "mesh2.med" as file name for the mesh with name "mesh2". The rest of the arguments are passed - * along as they are. - * - * @param mesh1 the name of the source mesh - * @param mesh2 the name of the target mesh - * @param correctVol the total volume of the intersection of the two meshes - * @param prec maximum relative error to be tolerated in volume comparisions - * @param doubleTest if false, only the test with mesh 1 as the source mesh and mesh 2 as the target mesh will be performed - * - */ - template - void MeshTestToolkit::intersectMeshes(const char* mesh1, const char* mesh2, const double correctVol, const double prec, bool doubleTest) const - { - const std::string path1 = std::string(mesh1) + std::string(".med"); - std::cout << "here :" << path1 << std::endl; - const std::string path2 = std::string(mesh2) + std::string(".med"); - - intersectMeshes(path1.c_str(), mesh1, path2.c_str(), mesh2, correctVol, prec, doubleTest); - } -} diff --git a/src/INTERP_KERNELTest/MultiElement2DTests.hxx b/src/INTERP_KERNELTest/MultiElement2DTests.hxx deleted file mode 100644 index 12d3036ef..000000000 --- a/src/INTERP_KERNELTest/MultiElement2DTests.hxx +++ /dev/null @@ -1,63 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 -// 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 __MULTI_ELEMENT_2D_TESTS_HXX_ -#define __MULTI_ELEMENT_2D_TESTS_HXX_ - -#include "InterpolationTestSuite.hxx" - -namespace INTERP_TEST -{ - /** - * \brief Class testing algorithm by intersecting meshes of several - * polygonal elements - up to a few thousand. This serves to check the - * filtering methods and the matrix assemblage, as well as verifying - * that computation errors do not become unmanageable. It uses mehes of - * different geometries : triangle, quadrilateral. - * - */ - class MultiElement2DTests : public InterpolationTestSuite<2,2> - { - CPPUNIT_TEST_SUITE( MultiElement2DTests ); - - CPPUNIT_TEST(SymetryTranspose2DTest); - CPPUNIT_TEST(SelfIntersection2DTest); - - CPPUNIT_TEST_SUITE_END(); - - public: - void SymetryTranspose2DTest() - { - _testTools->_intersectionType=INTERP_KERNEL::Triangulation; - _testTools->intersectMeshes("square1.med", "Mesh_2","square2.med","Mesh_3", 10000.); - _testTools->_intersectionType=INTERP_KERNEL::Convex; - _testTools->intersectMeshes("square1.med", "Mesh_2","square2.med","Mesh_3", 10000.); - } - void SelfIntersection2DTest() - { - IntersectionMatrix m; - _testTools->_intersectionType=INTERP_KERNEL::Triangulation; - _testTools->calcIntersectionMatrix("square1.med", "Mesh_2","square1.med","Mesh_2", m); - //_testTools->_intersectionType=INTERP_KERNEL::Convex;// valgrind complains ! - //_testTools->calcIntersectionMatrix("square1.med", "Mesh_2","square1.med","Mesh_2", m); - } - }; -} - -#endif diff --git a/src/INTERP_KERNELTest/MultiElement3DSurfTests.hxx b/src/INTERP_KERNELTest/MultiElement3DSurfTests.hxx deleted file mode 100644 index 6308c046c..000000000 --- a/src/INTERP_KERNELTest/MultiElement3DSurfTests.hxx +++ /dev/null @@ -1,63 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 -// 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 __MULTI_ELEMENT_3DSurf_TESTS_HXX_ -#define __MULTI_ELEMENT_3DSurf_TESTS_HXX_ - -#include "InterpolationTestSuite.hxx" - -namespace INTERP_TEST -{ - /** - * \brief Class testing algorithm by intersecting meshes of several - * polygonal elements - up to a few thousand. This serves to check the - * filtering methods and the matrix assemblage, as well as verifying - * that computation errors do not become unmanageable. It uses mehes of - * different geometries : triangle, quadrilateral. - * - */ - class MultiElement2DTests : public InterpolationTestSuite<3,2> - { - CPPUNIT_TEST_SUITE( MultiElement3DSurfTests ); - - CPPUNIT_TEST(SymetryTranspose3DSurfTest); - CPPUNIT_TEST(SelfIntersection3DSurfTest); - - CPPUNIT_TEST_SUITE_END(); - - public: - void SymetryTranspose3DSurfTest() - { - _testTools->_intersectionType=INTERP_KERNEL::Triangulation; - _testTools->intersectMeshes("square1.med", "Mesh_2","square2.med","Mesh_3", 10000.); - _testTools->_intersectionType=INTERP_KERNEL::Convex; - _testTools->intersectMeshes("square1.med", "Mesh_2","square2.med","Mesh_3", 10000.); - } - void SelfIntersection3DSurfTest() - { - IntersectionMatrix m; - _testTools->_intersectionType=INTERP_KERNEL::Triangulation; - _testTools->calcIntersectionMatrix("square1.med", "Mesh_2","square1.med","Mesh_2", m); - _testTools->_intersectionType=INTERP_KERNEL::Convex; - _testTools->calcIntersectionMatrix("square1.med", "Mesh_2","square1.med","Mesh_2", m); - } - }; -} - -#endif diff --git a/src/INTERP_KERNELTest/MultiElementTetraTests.hxx b/src/INTERP_KERNELTest/MultiElementTetraTests.hxx deleted file mode 100644 index d901eb332..000000000 --- a/src/INTERP_KERNELTest/MultiElementTetraTests.hxx +++ /dev/null @@ -1,159 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 -// 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 __MULTI_ELEMENT_TETRA_TESTS_HXX_ -#define __MULTI_ELEMENT_TETRA_TESTS_HXX_ - -#include "InterpolationTestSuite.hxx" - -namespace INTERP_TEST -{ - /** - * \brief Class testing algorithm by intersecting meshes of several - * elements (all tetrahedra) - up to a few thousand. This serves to check the - * filtering methods and the matrix assemblage, as well as verifying - * that computation errors do not become unmanageable. It uses mehes of - * different geometries : tetrahedra, boxes and cylinders. - * - */ - class MultiElementTetraTests : public InterpolationTestSuite<3,3> - { - CPPUNIT_TEST_SUITE( MultiElementTetraTests ); - - CPPUNIT_TEST( tetraComplexIncluded ); - CPPUNIT_TEST( dividedUnitTetraSimplerReflexive ); - CPPUNIT_TEST( dividedUnitTetraReflexive ); - CPPUNIT_TEST( nudgedDividedUnitTetraSimpler ); - CPPUNIT_TEST( nudgedDividedUnitTetra ); - CPPUNIT_TEST( dividedGenTetra ); - CPPUNIT_TEST( tinyBoxReflexive ); - CPPUNIT_TEST( moderateBoxEvenSmallerReflexive ); - CPPUNIT_TEST( moderateBoxSmallReflexive ); - CPPUNIT_TEST( boxReflexive ); - CPPUNIT_TEST( boxReflexiveModerate ); - CPPUNIT_TEST( tetraBoxes ); - CPPUNIT_TEST( moderateBoxesSmaller ); - CPPUNIT_TEST( moderateBoxes ); - - CPPUNIT_TEST_SUITE_END(); - - public: - - /// Tetrahedron situated totally inside another - /// \brief Status : pass - void tetraComplexIncluded() - { - _testTools->intersectMeshes("ComplexIncludedTetra", "ComplexIncludingTetra", 17.0156); - } - - /// Unit tetrahedron divided in 4 elements intersecting itself. - /// \brief Status : pass - void dividedUnitTetraSimplerReflexive() - { - _testTools->intersectMeshes("DividedUnitTetraSimpler", "DividedUnitTetraSimpler", 0.1666667); - } - - /// Unit tetrahedron divided in 14 elements intersecting itself. - /// \brief Status : pass - void dividedUnitTetraReflexive() - { - _testTools->intersectMeshes("DividedUnitTetra", "DividedUnitTetra", 0.1666667); - } - - /// Unit tetrahedron divided in 4 elements intersecting slightly displaced version of itself. - /// \brief Status : pass - void nudgedDividedUnitTetraSimpler() - { - _testTools->intersectMeshes("NudgedDividedUnitTetraSimpler", "DividedUnitTetraSimpler", 0.150191); - } - - /// Unit tetrahedron divided in 14 elements intersecting slightly displaced version of itself. - /// \brief Status : pass - void nudgedDividedUnitTetra() - { - _testTools->intersectMeshes("NudgedDividedUnitTetra", "DividedUnitTetra", 0.150191); - } - - /// Two intersecting tetrahedra in general position, one with 23 elements, the other with 643 elements - /// \brief Status : pass - void dividedGenTetra() - { - _testTools->intersectMeshes("DividedGenTetra1", "DividedGenTetra2", 0.546329); - } - - /// Large box in general position with 12 elements intersecting itself - /// \brief Status : pass - void tinyBoxReflexive() - { - _testTools->intersectMeshes("TinyBox", "TinyBox", 979200); - } - - /// Small box in general position with 33 elements intersecting itself - /// \brief Status : pass - void boxReflexive() - { - _testTools->intersectMeshes("Box3", "Box3", 13.9954); - } - - /// Box in general position with 67 elements intersecting itself - /// \brief Status : pass - void moderateBoxEvenSmallerReflexive() - { - _testTools->intersectMeshes("BoxEvenSmaller1", "BoxEvenSmaller1", 1.44018e6); - } - - /// Box in general position with 544 elements intersecting itself - /// \brief Status : pass - void moderateBoxSmallReflexive() - { - _testTools->intersectMeshes("BoxModSmall1", "BoxModSmall1", 1.44018e6); - } - - /// Large box in general position with 2943 elements intersecting itself - /// \brief Status : pass - void boxReflexiveModerate() - { - _testTools->intersectMeshes("Box1Moderate", "Box1Moderate", 1.0e6); - } - - /// Two intersecting boxes in general position with 12 and 18 elements - /// \brief Status : pass - void tetraBoxes() - { - _testTools->intersectMeshes("Box1", "Box2", 124.197); - } - - /// Two intersecting boxes in general position with 430 and 544 elements - /// \brief Status : pass - void moderateBoxesSmaller() - { - _testTools->intersectMeshes("BoxModSmall1", "BoxModSmall2", 321853); - } - - /// Two intersecting boxes in general position with 2943 and 3068 elements - /// \brief Status : pass - void moderateBoxes() - { - _testTools->intersectMeshes("Box1Moderate", "Box2Moderate", 376856); - } - - }; -} - -#endif diff --git a/src/INTERP_KERNELTest/PerfTest.cxx b/src/INTERP_KERNELTest/PerfTest.cxx deleted file mode 100644 index 85d67be1a..000000000 --- a/src/INTERP_KERNELTest/PerfTest.cxx +++ /dev/null @@ -1,155 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// - -#include "Interpolation3D.hxx" -#include "Interpolation3D.txx" -#include "MeshTestToolkit.txx" -#include "Log.hxx" -#include "VectorUtils.hxx" -#include "TestInterpKernelUtils.hxx" - -#include "MEDCouplingNormalizedUnstructuredMesh.hxx" - -#include -#include - -/** - * \file PerfTest.cxx - * Test program which takes two meshes and calculates their intersection matrix. - * - * USAGE : PerfTest mesh1 mesh2 - * where mesh1 and mesh2 are the names of two meshes located in - * the files mesh1.med, mesh2.med in {$MED_ROOT_DIR}/share/salome/resources/med/ - * - */ - -namespace INTERP_TEST -{ - /** - * \brief Specialization of MeshTestToolkit for the purposes of performance testing. - * - */ - class PerfTestToolkit : public MeshTestToolkit<3,3> - { - - public: - - /** - * Calculates the intersection matrix for two meshes. - * Outputs the names of the meshes intersected, the number of elements in each mesh, - * the number of matrix elements and the number of non-zero matrix elements, etc. - * These values help to determine how well the filtering algorithm is working. - * - * @param mesh1path the path to the file containing the source mesh, relative to {$MED_ROOT_DIR}/share/salome/resources/med/ - * @param mesh1 the name of the source mesh - * @param mesh2path the path to the file containing the target mesh, relative to {$MED_ROOT_DIR}/share/salome/resources/med/ - * @param mesh2 the name of the target mesh - * @param m intersection matrix in which to store the result of the intersection - */ - void calcIntersectionMatrix(const char* mesh1path, const char* mesh1, const char* mesh2path, const char* mesh2, IntersectionMatrix& m) - { - LOG(1, std::endl << "=== -> intersecting src = " << mesh1 << ", target = " << mesh2 ); - - LOG(5, "Loading " << mesh1 << " from " << mesh1path); - MEDCouplingAutoRefCountObjectPtr sMeshML=MEDFileUMesh::New(INTERP_TEST::getResourceFile(mesh1path).c_str(),mesh1); - MEDCouplingAutoRefCountObjectPtr sMesh=sMeshML->getMeshAtLevel(0); - - - LOG(5, "Loading " << mesh2 << " from " << mesh2path); - MEDCouplingAutoRefCountObjectPtr tMeshML=MEDFileUMesh::New(INTERP_TEST::getResourceFile(mesh2path).c_str(),mesh2); - MEDCouplingAutoRefCountObjectPtr tMesh=tMeshML->getMeshAtLevel(0); - - MEDCouplingNormalizedUnstructuredMesh<3,3> sMesh_wrapper(sMesh); - MEDCouplingNormalizedUnstructuredMesh<3,3> tMesh_wrapper(tMesh); - - Interpolation3D interpolator; - interpolator.interpolateMeshes(sMesh_wrapper, tMesh_wrapper,m,"P0P0"); - - std::pair eff = countNumberOfMatrixEntries(m); - LOG(1, eff.first << " of " << numTargetElems * numSrcElems << " intersections calculated : ratio = " - << double(eff.first) / double(numTargetElems * numSrcElems)); - LOG(1, eff.second << " non-zero elements of " << eff.first << " total : filter efficiency = " - << double(eff.second) / double(eff.first)); - - LOG(1, "Intersection calculation done. " << std::endl ); - - } - - /** - * Counts the number of elements in an intersection matrix, and the number of these which are non-zero. - * - * @param m the intersection matrix - * @return pair containing as its first element the number of elements in m and as its second element the - * number these which are non-zero - */ - std::pair countNumberOfMatrixEntries(const IntersectionMatrix& m) - { - - int numElems = 0; - int numNonZero = 0; - for(IntersectionMatrix::const_iterator iter = m.begin() ; iter != m.end() ; ++iter) - { - numElems += iter->size(); - for(std::map::const_iterator iter2 = iter->begin() ; iter2 != iter->end() ; ++iter2) - { - if(!INTERP_KERNEL::epsilonEqual(iter2->second, 0.0, VOL_PREC)) - { - ++numNonZero; - } - } - } - return std::make_pair(numElems, numNonZero); - } - - }; -} - -/** - * Main method of the program. - * Intersects the meshes and outputs some information about the calculation as well as the - * intersection matrix on std::cout. - * - * @param argc number of arguments given to the program (should be 3, the user giving 2 mesh names) - * @param argv vector to the arguments as strings. - */ -int main(int argc, char** argv) -{ - using INTERP_TEST::PerfTestToolkit; - - assert(argc == 3); - - // load meshes - const std::string mesh1 = argv[1]; - const std::string mesh2 = argv[2]; - - const std::string mesh1path = mesh1 + ".med"; - const std::string mesh2path = mesh2 + ".med"; - - IntersectionMatrix m; - - PerfTestToolkit testTools; - - testTools.calcIntersectionMatrix(mesh1path.c_str(), mesh1.c_str(), mesh2path.c_str(), mesh2.c_str(), m); - - testTools.dumpIntersectionMatrix(m); - - return 0; - -} - diff --git a/src/INTERP_KERNELTest/QuadraticPlanarInterpTest.cxx b/src/INTERP_KERNELTest/QuadraticPlanarInterpTest.cxx deleted file mode 100644 index 3a1f8a46a..000000000 --- a/src/INTERP_KERNELTest/QuadraticPlanarInterpTest.cxx +++ /dev/null @@ -1,1023 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 -// 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 "QuadraticPlanarInterpTest.hxx" -#include "InterpKernelGeo2DQuadraticPolygon.hxx" -#include "InterpKernelGeo2DEdgeArcCircle.hxx" -#include "InterpKernelGeo2DElementaryEdge.hxx" -#include "InterpKernelGeo2DComposedEdge.hxx" -#include "InterpKernelGeo2DEdgeLin.hxx" -#include "TestInterpKernelUtils.hxx" - -#include -#include - -using namespace INTERP_KERNEL; - -namespace INTERP_TEST -{ - -static const double ADMISSIBLE_ERROR = 1.e-14; - -void QuadraticPlanarInterpTest::setUp() -{ -} - -void QuadraticPlanarInterpTest::tearDown() -{ -} - -void QuadraticPlanarInterpTest::cleanUp() -{ -} - -void QuadraticPlanarInterpTest::ReadWriteInXfigElementary() -{ - //Testing bounds calculation. For Seg2 - std::istringstream stream("2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 2\n3200 3400 4500 4700"); - EdgeLin *e1=new EdgeLin(stream); - Bounds bound=e1->getBounds(); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.32,bound[0],ADMISSIBLE_ERROR); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.45,bound[1],ADMISSIBLE_ERROR); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.34,bound[2],ADMISSIBLE_ERROR); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.47,bound[3],ADMISSIBLE_ERROR); - e1->decrRef(); - std::istringstream stream2("2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 2\n4500 4700 3200 3400"); - e1=new EdgeLin(stream2); - bound=e1->getBounds(); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.32,bound[0],ADMISSIBLE_ERROR); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.45,bound[1],ADMISSIBLE_ERROR); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.34,bound[2],ADMISSIBLE_ERROR); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.47,bound[3],ADMISSIBLE_ERROR); - e1->decrRef(); - //Testing bounds calculation For Arc of circle. - -} - -void QuadraticPlanarInterpTest::ReadWriteInXfigGlobal() -{ - QuadraticPolygon pol1(INTERP_TEST::getResourceFile("Pol1.fig").c_str()); - pol1.dumpInXfigFile("Pol1_gen.fig"); - QuadraticPolygon pol2(INTERP_TEST::getResourceFile("Pol2.fig").c_str()); - pol2.dumpInXfigFile("Pol2_gen.fig"); - QuadraticPolygon pol3(INTERP_TEST::getResourceFile("Pol3.fig").c_str()); - pol3.dumpInXfigFile("Pol3_gen.fig"); - QuadraticPolygon pol4(INTERP_TEST::getResourceFile("Pol4.fig").c_str()); - CPPUNIT_ASSERT_EQUAL(1,pol4.size()); - ElementaryEdge *edge1=dynamic_cast(pol4[0]); - CPPUNIT_ASSERT(edge1); - Edge *edge2=edge1->getPtr(); - EdgeArcCircle *edge=dynamic_cast(edge2); - CPPUNIT_ASSERT(edge); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.24375,edge->getRadius(),ADMISSIBLE_ERROR); - CPPUNIT_ASSERT_DOUBLES_EQUAL(5.7857653289925404,edge->getAngle(),ADMISSIBLE_ERROR); - double center[2]; - edge->getCenter(center); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.48,center[0],ADMISSIBLE_ERROR); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.48375,center[1],ADMISSIBLE_ERROR); - const double *start=*edge->getStartNode(); - Node *n1=new Node(start[0]+2*(center[0]-start[0]),start[1]+2*(center[1]-start[1])); - edge->changeMiddle(n1); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.24375,edge->getRadius(),ADMISSIBLE_ERROR); - CPPUNIT_ASSERT_DOUBLES_EQUAL(5.7857653289925404,edge->getAngle(),ADMISSIBLE_ERROR); - n1->decrRef(); - n1=new Node(center[0],center[1]+0.24375); - edge->changeMiddle(n1); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.24375,edge->getRadius(),ADMISSIBLE_ERROR); - CPPUNIT_ASSERT_DOUBLES_EQUAL(-0.49741997818704586,edge->getAngle(),ADMISSIBLE_ERROR);//5.7857653289925404 + 2*PI - n1->decrRef(); - //A half circle. - EdgeArcCircle *e=new EdgeArcCircle(0.84,0.54,0.78,0.6,0.84,0.66); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.06,e->getRadius(),ADMISSIBLE_ERROR); - CPPUNIT_ASSERT_DOUBLES_EQUAL(-3.1415925921507317,e->getAngle(),1e-5); - e->decrRef(); - e=new EdgeArcCircle(0.84,0.54,0.9,0.6,0.84,0.66); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.06,e->getRadius(),ADMISSIBLE_ERROR); - CPPUNIT_ASSERT_DOUBLES_EQUAL(3.1415925921507317,e->getAngle(),1e-5); - e->decrRef(); -} - -void QuadraticPlanarInterpTest::BasicGeometricTools() -{ - Node *n1=new Node(1.,1.); - Node *n2=new Node(4.,2.); - EdgeLin *e1=new EdgeLin(n1,n2); - double tmp[2]; - e1->getNormalVector(tmp); - CPPUNIT_ASSERT_DOUBLES_EQUAL(-0.94868329805051377,tmp[1],ADMISSIBLE_ERROR); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.31622776601683794,tmp[0],ADMISSIBLE_ERROR); - e1->decrRef(); - n1->decrRef(); n2->decrRef(); - n1=new Node(1.,1.); - n2=new Node(0.,4.); - e1=new EdgeLin(n1,n2); - double tmp2[2]; - e1->getNormalVector(tmp2); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.,Node::dot(tmp,tmp2),1e-10); - tmp[0]=0.5; tmp[1]=2.5; - CPPUNIT_ASSERT(e1->isNodeLyingOn(tmp)); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.,e1->getDistanceToPoint(tmp),1e-12); - tmp[1]=2.55; CPPUNIT_ASSERT(!e1->isNodeLyingOn(tmp)); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.0158113883008418,e1->getDistanceToPoint(tmp),1e-12); - tmp[0]=0.; tmp[1]=5.; - CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,e1->getDistanceToPoint(tmp),1e-12); - EdgeArcCircle *e=new EdgeArcCircle(4.,3.,0.,5.,-5.,0.); - tmp[0]=-4.; tmp[1]=3.; - CPPUNIT_ASSERT(e->isNodeLyingOn(tmp)); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.,e->getDistanceToPoint(tmp),1e-12); - tmp[1]=3.1; CPPUNIT_ASSERT(!e->isNodeLyingOn(tmp)); - CPPUNIT_ASSERT_DOUBLES_EQUAL(6.0632371551998077e-2,e->getDistanceToPoint(tmp),1e-12); - tmp[0]=-4.; tmp[1]=-3.; - CPPUNIT_ASSERT(!e->isNodeLyingOn(tmp)); - CPPUNIT_ASSERT_DOUBLES_EQUAL(3.1622776601683795,e->getDistanceToPoint(tmp),1e-12); - e->decrRef(); - e1->decrRef(); - n1->decrRef(); n2->decrRef(); -} - -void QuadraticPlanarInterpTest::IntersectionBasics() -{ - //Testing intersection of Bounds. - std::istringstream stream1("2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 2\n3200 3400 4500 4800"); - EdgeLin *e1=new EdgeLin(stream1); - std::istringstream stream2("2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 2\n3200 3400 4500 4800"); - EdgeLin *e2=new EdgeLin(stream2); - Bounds *bound=e1->getBounds().amIIntersectingWith(e2->getBounds()); CPPUNIT_ASSERT(bound); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.32,(*bound)[0],ADMISSIBLE_ERROR); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.45,(*bound)[1],ADMISSIBLE_ERROR); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.34,(*bound)[2],ADMISSIBLE_ERROR); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.48,(*bound)[3],ADMISSIBLE_ERROR); - delete bound; - e2->decrRef(); e1->decrRef(); - // - std::istringstream stream3("2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 2\n3000 7200 6000 3700"); - EdgeLin *e3=new EdgeLin(stream3); - std::istringstream stream4("2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 2\n4800 6600 7200 4200"); - EdgeLin *e4=new EdgeLin(stream4); - bound=e3->getBounds().amIIntersectingWith(e4->getBounds()); CPPUNIT_ASSERT(bound); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.48,(*bound)[0],ADMISSIBLE_ERROR); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.6,(*bound)[1],ADMISSIBLE_ERROR); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.42,(*bound)[2],ADMISSIBLE_ERROR); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.66,(*bound)[3],ADMISSIBLE_ERROR); - delete bound; - e3->decrRef(); e4->decrRef(); -} - -void QuadraticPlanarInterpTest::EdgeLinUnitary() -{ - EdgeLin *e1=new EdgeLin(0.5,0.5,3.7,4.1); - Node *n=new Node(2.1,2.3); - CPPUNIT_ASSERT_DOUBLES_EQUAL(e1->getCharactValue(*n),0.5,1e-8); - n->decrRef(); - n=new Node(3.7,4.1); - CPPUNIT_ASSERT_DOUBLES_EQUAL(e1->getCharactValue(*n),1.,1e-8); - n->decrRef(); - n=new Node(0.5,0.5); - CPPUNIT_ASSERT_DOUBLES_EQUAL(e1->getCharactValue(*n),0.,1e-8); - n->decrRef(); - n=new Node(-1.1,-1.3); - CPPUNIT_ASSERT_DOUBLES_EQUAL(e1->getCharactValue(*n),-0.5,1e-8); - n->decrRef(); - n=new Node(5.3,5.9); - CPPUNIT_ASSERT_DOUBLES_EQUAL(e1->getCharactValue(*n),1.5,1e-8); - n->decrRef(); e1->decrRef(); -} - -/*! - * Here two things are tested. - * 1 ) One the overlapping calculation capability of edge/edge intersector. - * 2 ) Then the capability to handle the case where 2 segs (whatever their type) are overlapped. - * All the configuration of full or part overlapping have been tested. - */ -void QuadraticPlanarInterpTest::IntersectionEdgeOverlapUnitarySegSeg() -{ - ComposedEdge& v1=*(new ComposedEdge); - ComposedEdge& v2=*(new ComposedEdge); - MergePoints v3; - //Testing merge of geometric equals seg2. - Edge *e1=new EdgeLin(0.5,0.5,1.,1.); Edge *e2=new EdgeLin(0.5,0.5,1.,1.); - CPPUNIT_ASSERT(e1->intersectWith(e2,v3,v1,v2)); - CPPUNIT_ASSERT_EQUAL(2,(int)v3.getNumberOfAssociations()); - CPPUNIT_ASSERT_EQUAL(1,(int)v1.size()); CPPUNIT_ASSERT_EQUAL(1,(int)v2.size()); - CPPUNIT_ASSERT(v1[0]->intresincEqCoarse(e1) && v1[0]->getDirection()); CPPUNIT_ASSERT(v2[0]->intresincEqCoarse(e1) && v2[0]->getDirection()); - v1.clear(); v2.clear(); v3.clear(); - // - testing by adding some noise - e1->decrRef(); e1=new EdgeLin(0.5+5.e-15,0.5-5.e-15,1.,1.+7.e-15); - CPPUNIT_ASSERT(e1->intersectWith(e2,v3,v1,v2)); - CPPUNIT_ASSERT_EQUAL(2,(int)v3.getNumberOfAssociations()); - CPPUNIT_ASSERT_EQUAL(1,(int)v1.size()); CPPUNIT_ASSERT_EQUAL(1,(int)v2.size()); - CPPUNIT_ASSERT(v1[0]->intresincEqCoarse(e1) && v1[0]->getDirection()); CPPUNIT_ASSERT(v2[0]->intresincEqCoarse(e1) && v2[0]->getDirection()); - e2->decrRef(); e1->decrRef(); - v1.clear(); v2.clear(); v3.clear(); - //Testing merge of geometric equals seg2 but now with opposite direction - e1=new EdgeLin(0.5,0.5,0.7,0.7); e2=new EdgeLin(0.7+6.e-15,0.7-2.e-15,0.5+3.e-15,0.5-4.e-15); - CPPUNIT_ASSERT(e1->intersectWith(e2,v3,v1,v2)); - CPPUNIT_ASSERT_EQUAL(2,(int)v3.getNumberOfAssociations()); - CPPUNIT_ASSERT_EQUAL(1,(int)v1.size()); CPPUNIT_ASSERT_EQUAL(1,(int)v2.size()); - CPPUNIT_ASSERT(v1[0]->intresincEqCoarse(e1) && v1[0]->getDirection()); CPPUNIT_ASSERT(v2[0]->intresincEqCoarse(e1) && !v2[0]->getDirection());//compared 8 lines above !v2[0]->getDirection() - e2->decrRef(); e1->decrRef(); - v1.clear(); v2.clear(); v3.clear(); - //Test 0 - //Test 1 - OUT_AFTER - OUT_AFTER | same dir. - 0° - e1=new EdgeLin(0.,0.,1.,0.); e2=new EdgeLin(1.5,0.,2.,0.); - CPPUNIT_ASSERT(!e1->intersectWith(e2,v3,v1,v2)); - CPPUNIT_ASSERT_EQUAL(0,(int)v3.getNumberOfAssociations()); - CPPUNIT_ASSERT_EQUAL(0,(int)v1.size()); - CPPUNIT_ASSERT_EQUAL(0,(int)v2.size()); - e2->decrRef(); e1->decrRef(); - v1.clear(); v2.clear(); v3.clear(); - //Test 2 - INSIDE - OUT_AFTER | same dir. - 0° - e1=new EdgeLin(0.,0.,1.,0.); e2=new EdgeLin(0.5,0.,1.5,0.); - CPPUNIT_ASSERT(e1->intersectWith(e2,v3,v1,v2)); - CPPUNIT_ASSERT_EQUAL(0,(int)v3.getNumberOfAssociations()); - CPPUNIT_ASSERT_EQUAL(2,(int)v1.size()); - CPPUNIT_ASSERT_EQUAL(2,(int)v2.size()); - CPPUNIT_ASSERT(v1[1]->intresicEqualDirSensitive(v2[0])); - CPPUNIT_ASSERT(v1[0]->getEndNode()==v1[1]->getStartNode()); CPPUNIT_ASSERT(e1->getStartNode()==v1[0]->getStartNode()); CPPUNIT_ASSERT(e1->getEndNode()==v1[1]->getEndNode()); - CPPUNIT_ASSERT(v2[0]->getEndNode()==v2[1]->getStartNode()); CPPUNIT_ASSERT(e2->getStartNode()==v2[0]->getStartNode()); CPPUNIT_ASSERT(e2->getEndNode()==v2[1]->getEndNode()); - CPPUNIT_ASSERT(e1->getStartNode()==v1.front()->getStartNode() && e1->getEndNode()==v1.back()->getEndNode()); - CPPUNIT_ASSERT(e2->getStartNode()==v2.front()->getStartNode() && e2->getEndNode()==v2.back()->getEndNode()); - e2->decrRef(); e1->decrRef(); - v1.clear(); v2.clear(); v3.clear(); - //Test 2 - INSIDE - OUT_AFTER | same dir. - 90° - e1=new EdgeLin(0.,0.,0.,1.); e2=new EdgeLin(0.,0.5,0.,1.5); - CPPUNIT_ASSERT(e1->intersectWith(e2,v3,v1,v2)); - CPPUNIT_ASSERT_EQUAL(0,(int)v3.getNumberOfAssociations()); - CPPUNIT_ASSERT_EQUAL(2,(int)v1.size()); - CPPUNIT_ASSERT_EQUAL(2,(int)v2.size()); - CPPUNIT_ASSERT(v1[1]->intresicEqualDirSensitive(v2[0])); - CPPUNIT_ASSERT(v1[0]->getEndNode()==v1[1]->getStartNode()); CPPUNIT_ASSERT(e1->getStartNode()==v1[0]->getStartNode()); CPPUNIT_ASSERT(e1->getEndNode()==v1[1]->getEndNode()); - CPPUNIT_ASSERT(v2[0]->getEndNode()==v2[1]->getStartNode()); CPPUNIT_ASSERT(e2->getStartNode()==v2[0]->getStartNode()); CPPUNIT_ASSERT(e2->getEndNode()==v2[1]->getEndNode()); - CPPUNIT_ASSERT(e1->getStartNode()==v1.front()->getStartNode() && e1->getEndNode()==v1.back()->getEndNode()); - CPPUNIT_ASSERT(e2->getStartNode()==v2.front()->getStartNode() && e2->getEndNode()==v2.back()->getEndNode()); - e2->decrRef(); e1->decrRef(); - v1.clear(); v2.clear(); v3.clear(); - //Test 2 - INSIDE - OUT_AFTER | same dir. - 45° - e1=new EdgeLin(0.,0.,1.,1.); e2=new EdgeLin(0.5,0.5,1.5,1.5); - CPPUNIT_ASSERT(e1->intersectWith(e2,v3,v1,v2)); - CPPUNIT_ASSERT_EQUAL(0,(int)v3.getNumberOfAssociations()); - CPPUNIT_ASSERT_EQUAL(2,(int)v1.size()); - CPPUNIT_ASSERT_EQUAL(2,(int)v2.size()); - CPPUNIT_ASSERT(v1[1]->intresicEqualDirSensitive(v2[0])); - CPPUNIT_ASSERT(v1[0]->getEndNode()==v1[1]->getStartNode()); CPPUNIT_ASSERT(e1->getStartNode()==v1[0]->getStartNode()); CPPUNIT_ASSERT(e1->getEndNode()==v1[1]->getEndNode()); - CPPUNIT_ASSERT(v2[0]->getEndNode()==v2[1]->getStartNode()); CPPUNIT_ASSERT(e2->getStartNode()==v2[0]->getStartNode()); CPPUNIT_ASSERT(e2->getEndNode()==v2[1]->getEndNode()); - e2->decrRef(); e1->decrRef(); - v1.clear(); v2.clear(); v3.clear(); - //Test 2 - INSIDE - OUT_AFTER | opp. dir. - 45° - e1=new EdgeLin(0.,0.,1.,1.); e2=new EdgeLin(1.5,1.5,0.5,0.5); - CPPUNIT_ASSERT(e1->intersectWith(e2,v3,v1,v2)); - CPPUNIT_ASSERT_EQUAL(0,(int)v3.getNumberOfAssociations()); - CPPUNIT_ASSERT_EQUAL(2,(int)v1.size()); - CPPUNIT_ASSERT_EQUAL(2,(int)v2.size()); - CPPUNIT_ASSERT(!v1[1]->intresicEqualDirSensitive(v2[1]) && v1[1]->intresicEqual(v2[1])); - CPPUNIT_ASSERT(v1[0]->getEndNode()==v1[1]->getStartNode()); CPPUNIT_ASSERT(e1->getStartNode()==v1[0]->getStartNode()); CPPUNIT_ASSERT(e1->getEndNode()==v1[1]->getEndNode()); - CPPUNIT_ASSERT(v2[0]->getEndNode()==v2[1]->getStartNode()); CPPUNIT_ASSERT(e2->getStartNode()==v2[0]->getStartNode()); CPPUNIT_ASSERT(e2->getEndNode()==v2[1]->getEndNode()); - CPPUNIT_ASSERT(e1->getStartNode()==v1.front()->getStartNode() && e1->getEndNode()==v1.back()->getEndNode()); - CPPUNIT_ASSERT(e2->getStartNode()==v2.front()->getStartNode() && e2->getEndNode()==v2.back()->getEndNode()); - e2->decrRef(); e1->decrRef(); - v1.clear(); v2.clear(); v3.clear(); - //Test 3 - INSIDE - INSIDE | same dir. - 0° - e1=new EdgeLin(0.,0.,1.,0.); e2=new EdgeLin(0.25,0.,0.75,0.); - CPPUNIT_ASSERT(e1->intersectWith(e2,v3,v1,v2)); - CPPUNIT_ASSERT_EQUAL(0,(int)v3.getNumberOfAssociations()); - CPPUNIT_ASSERT_EQUAL(3,(int)v1.size()); - CPPUNIT_ASSERT_EQUAL(1,(int)v2.size()); - CPPUNIT_ASSERT(v1[1]->intresincEqCoarse(e2) && v1[1]->getDirection()); - CPPUNIT_ASSERT(v1[0]->getEndNode()==v1[1]->getStartNode()); CPPUNIT_ASSERT(v1[1]->getEndNode()==v1[2]->getStartNode()); - CPPUNIT_ASSERT(v1[0]->getStartNode()== e1->getStartNode()); CPPUNIT_ASSERT(v1[2]->getEndNode()== e1->getEndNode()); - CPPUNIT_ASSERT(v1[0]->getEndNode()==e2->getStartNode()); CPPUNIT_ASSERT(v1[1]->getEndNode()==e2->getEndNode()); - CPPUNIT_ASSERT(e1->getStartNode()==v1.front()->getStartNode() && e1->getEndNode()==v1.back()->getEndNode()); - CPPUNIT_ASSERT(e2->getStartNode()==v2.front()->getStartNode() && e2->getEndNode()==v2.back()->getEndNode()); - e2->decrRef(); e1->decrRef(); - v1.clear(); v2.clear(); v3.clear(); - //Test 3 - INSIDE - INSIDE | same dir. - 90° - e1=new EdgeLin(0.,0.,0.,1.); e2=new EdgeLin(0.,0.25,0.,0.75); - CPPUNIT_ASSERT(e1->intersectWith(e2,v3,v1,v2)); - CPPUNIT_ASSERT_EQUAL(0,(int)v3.getNumberOfAssociations()); - CPPUNIT_ASSERT_EQUAL(3,(int)v1.size()); - CPPUNIT_ASSERT_EQUAL(1,(int)v2.size()); - CPPUNIT_ASSERT(v1[1]->intresincEqCoarse(e2) && v1[1]->getDirection()); - CPPUNIT_ASSERT(v1[0]->getEndNode()==v1[1]->getStartNode()); CPPUNIT_ASSERT(v1[1]->getEndNode()==v1[2]->getStartNode()); - CPPUNIT_ASSERT(v1[0]->getStartNode()== e1->getStartNode()); CPPUNIT_ASSERT(v1[2]->getEndNode()== e1->getEndNode()); - CPPUNIT_ASSERT(v1[0]->getEndNode()==e2->getStartNode()); CPPUNIT_ASSERT(v1[1]->getEndNode()==e2->getEndNode()); - CPPUNIT_ASSERT(e1->getStartNode()==v1.front()->getStartNode() && e1->getEndNode()==v1.back()->getEndNode()); - CPPUNIT_ASSERT(e2->getStartNode()==v2.front()->getStartNode() && e2->getEndNode()==v2.back()->getEndNode()); - e2->decrRef(); e1->decrRef(); - v1.clear(); v2.clear(); v3.clear(); - //Test 3 - INSIDE - INSIDE | same dir. - 45° - e1=new EdgeLin(0.,0.,1.,1.); e2=new EdgeLin(0.25,0.25,0.75,0.75); - CPPUNIT_ASSERT(e1->intersectWith(e2,v3,v1,v2)); - CPPUNIT_ASSERT_EQUAL(0,(int)v3.getNumberOfAssociations()); - CPPUNIT_ASSERT_EQUAL(3,(int)v1.size()); - CPPUNIT_ASSERT_EQUAL(1,(int)v2.size()); - CPPUNIT_ASSERT(v1[1]->intresincEqCoarse(e2) && v1[1]->getDirection()); - CPPUNIT_ASSERT(v1[0]->getEndNode()==v1[1]->getStartNode()); CPPUNIT_ASSERT(v1[1]->getEndNode()==v1[2]->getStartNode()); - CPPUNIT_ASSERT(v1[0]->getStartNode()== e1->getStartNode()); CPPUNIT_ASSERT(v1[2]->getEndNode()== e1->getEndNode()); - CPPUNIT_ASSERT(v1[0]->getEndNode()==e2->getStartNode()); CPPUNIT_ASSERT(v1[1]->getEndNode()==e2->getEndNode()); - CPPUNIT_ASSERT(e1->getStartNode()==v1.front()->getStartNode() && e1->getEndNode()==v1.back()->getEndNode()); - CPPUNIT_ASSERT(e2->getStartNode()==v2.front()->getStartNode() && e2->getEndNode()==v2.back()->getEndNode()); - e2->decrRef(); e1->decrRef(); - v1.clear(); v2.clear(); v3.clear(); - //Test 3 - INSIDE - INSIDE | opp dir. - 45° - e1=new EdgeLin(0.,0.,1.,1.); e2=new EdgeLin(0.75,0.75,0.25,0.25); - CPPUNIT_ASSERT(e1->intersectWith(e2,v3,v1,v2)); - CPPUNIT_ASSERT_EQUAL(0,(int)v3.getNumberOfAssociations()); - CPPUNIT_ASSERT_EQUAL(3,(int)v1.size()); - CPPUNIT_ASSERT_EQUAL(1,(int)v2.size()); - CPPUNIT_ASSERT(v1[1]->intresincEqCoarse(e2) && !v1[1]->getDirection()); - CPPUNIT_ASSERT(v1[0]->getEndNode()==v1[1]->getStartNode()); CPPUNIT_ASSERT(v1[1]->getEndNode()==v1[2]->getStartNode()); - CPPUNIT_ASSERT(v1[0]->getStartNode()== e1->getStartNode()); CPPUNIT_ASSERT(v1[2]->getEndNode()== e1->getEndNode()); - CPPUNIT_ASSERT(v1[0]->getEndNode()==e2->getEndNode()); CPPUNIT_ASSERT(v1[1]->getEndNode()==e2->getStartNode()); - CPPUNIT_ASSERT(e1->getStartNode()==v1.front()->getStartNode() && e1->getEndNode()==v1.back()->getEndNode()); - CPPUNIT_ASSERT(e2->getStartNode()==v2.front()->getStartNode() && e2->getEndNode()==v2.back()->getEndNode()); - e2->decrRef(); e1->decrRef(); - v1.clear(); v2.clear(); v3.clear(); - //Test 3bis - INSIDE - INSIDE - Bis | opp dir. - double center[2]={0.,0.}; - double radius=1.; - e1=buildArcOfCircle(center,radius,-M_PI,0); e2=buildArcOfCircle(center,radius,-2*M_PI/3.+2*M_PI,-M_PI/3.); - CPPUNIT_ASSERT_DOUBLES_EQUAL(M_PI,e1->getCurveLength(),1e-12); CPPUNIT_ASSERT_DOUBLES_EQUAL(5.*M_PI/3.,e2->getCurveLength(),1e-12);// To check that in the previous line +2.M_PI has done its job. - CPPUNIT_ASSERT(e1->intersectWith(e2,v3,v1,v2)); - CPPUNIT_ASSERT_EQUAL(0,(int)v3.getNumberOfAssociations()); - CPPUNIT_ASSERT_EQUAL(3,(int)v1.size()); - CPPUNIT_ASSERT_EQUAL(3,(int)v2.size()); - CPPUNIT_ASSERT(v1[0]->intresincEqCoarse(v2[0]->getPtr())); CPPUNIT_ASSERT(v1[0]->getDirection()); CPPUNIT_ASSERT(!v2[0]->getDirection()); - CPPUNIT_ASSERT(v1[2]->intresincEqCoarse(v2[2]->getPtr())); CPPUNIT_ASSERT(v1[2]->getDirection()); CPPUNIT_ASSERT(!v2[2]->getDirection()); - CPPUNIT_ASSERT_DOUBLES_EQUAL(M_PI,v2[1]->getCurveLength(),1.e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(M_PI/3.,v1[1]->getCurveLength(),1.e-12); - CPPUNIT_ASSERT(v2[1]->getStartNode()==e1->getStartNode()); - CPPUNIT_ASSERT(v2[1]->getEndNode()==e1->getEndNode()); - CPPUNIT_ASSERT(v1[0]->getStartNode()==e1->getStartNode()); - CPPUNIT_ASSERT(v1[0]->getEndNode()==e2->getStartNode()); - CPPUNIT_ASSERT(v1[1]->getStartNode()==e2->getStartNode()); - CPPUNIT_ASSERT(v1[1]->getEndNode()==e2->getEndNode()); - e2->decrRef(); e1->decrRef(); - v1.clear(); v2.clear(); v3.clear(); - //Test 3bis - INSIDE - INSIDE - Bis | same dir. - e1=buildArcOfCircle(center,radius,-M_PI,0); e2=buildArcOfCircle(center,radius,-M_PI/3.,-2*M_PI/3.+2*M_PI); - CPPUNIT_ASSERT_DOUBLES_EQUAL(M_PI,e1->getCurveLength(),1e-12); CPPUNIT_ASSERT_DOUBLES_EQUAL(5.*M_PI/3.,e2->getCurveLength(),1e-12);// To check that in the previous line +2.M_PI has done its job. - CPPUNIT_ASSERT(e1->intersectWith(e2,v3,v1,v2)); - CPPUNIT_ASSERT_EQUAL(0,(int)v3.getNumberOfAssociations()); - CPPUNIT_ASSERT_EQUAL(3,(int)v1.size()); - CPPUNIT_ASSERT_EQUAL(3,(int)v2.size()); - CPPUNIT_ASSERT(v1[0]->intresincEqCoarse(v2[2]->getPtr())); CPPUNIT_ASSERT(v1[0]->getDirection()); CPPUNIT_ASSERT(v2[2]->getDirection()); - CPPUNIT_ASSERT(v1[2]->intresincEqCoarse(v2[0]->getPtr())); CPPUNIT_ASSERT(v1[2]->getDirection()); CPPUNIT_ASSERT(v2[0]->getDirection()); - CPPUNIT_ASSERT_DOUBLES_EQUAL(M_PI,v2[1]->getCurveLength(),1.e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(M_PI/3.,v1[1]->getCurveLength(),1.e-12); - CPPUNIT_ASSERT(v2[1]->getStartNode()==e1->getEndNode()); - CPPUNIT_ASSERT(v2[1]->getEndNode()==e1->getStartNode()); - CPPUNIT_ASSERT(v1[0]->getStartNode()==e1->getStartNode()); - CPPUNIT_ASSERT(v1[0]->getEndNode()==e2->getEndNode()); - CPPUNIT_ASSERT(v1[1]->getStartNode()==e2->getEndNode()); - CPPUNIT_ASSERT(v1[1]->getEndNode()==e2->getStartNode()); - e2->decrRef(); e1->decrRef(); - v1.clear(); v2.clear(); v3.clear(); - //Test 3bis - INSIDE - INSIDE - Bis | opp dir. | e1<->e2 to test symetry - e1=buildArcOfCircle(center,radius,-M_PI,0); e2=buildArcOfCircle(center,radius,-2*M_PI/3.+2*M_PI,-M_PI/3.); - CPPUNIT_ASSERT_DOUBLES_EQUAL(M_PI,e1->getCurveLength(),1e-12); CPPUNIT_ASSERT_DOUBLES_EQUAL(5.*M_PI/3.,e2->getCurveLength(),1e-12);// To check that in the previous line +2.M_PI has done its job. - CPPUNIT_ASSERT(e2->intersectWith(e1,v3,v2,v1)); - CPPUNIT_ASSERT_EQUAL(0,(int)v3.getNumberOfAssociations()); - CPPUNIT_ASSERT_EQUAL(3,(int)v1.size()); - CPPUNIT_ASSERT_EQUAL(3,(int)v2.size()); - CPPUNIT_ASSERT(v1[0]->intresincEqCoarse(v2[0]->getPtr())); CPPUNIT_ASSERT(!v1[0]->getDirection()); CPPUNIT_ASSERT(v2[0]->getDirection()); - CPPUNIT_ASSERT(v1[2]->intresincEqCoarse(v2[2]->getPtr())); CPPUNIT_ASSERT(!v1[2]->getDirection()); CPPUNIT_ASSERT(v2[2]->getDirection()); - CPPUNIT_ASSERT_DOUBLES_EQUAL(M_PI,v2[1]->getCurveLength(),1.e-5); // << not maximal precision because node switching - CPPUNIT_ASSERT_DOUBLES_EQUAL(M_PI/3.,v1[1]->getCurveLength(),1.e-12); - CPPUNIT_ASSERT(v2[1]->getStartNode()==e1->getStartNode()); - CPPUNIT_ASSERT(v2[1]->getEndNode()==e1->getEndNode()); - CPPUNIT_ASSERT(v1[0]->getStartNode()==e1->getStartNode()); - CPPUNIT_ASSERT(v1[0]->getEndNode()==e2->getStartNode()); - CPPUNIT_ASSERT(v1[1]->getStartNode()==e2->getStartNode()); - CPPUNIT_ASSERT(v1[1]->getEndNode()==e2->getEndNode()); - e2->decrRef(); e1->decrRef(); - v1.clear(); v2.clear(); v3.clear(); - //Test 3bis - INSIDE - INSIDE - Bis | same dir. | e1<->e2 to test symetry - e1=buildArcOfCircle(center,radius,-M_PI,0); e2=buildArcOfCircle(center,radius,-M_PI/3.,-2*M_PI/3.+2*M_PI); - CPPUNIT_ASSERT_DOUBLES_EQUAL(M_PI,e1->getCurveLength(),1e-12); CPPUNIT_ASSERT_DOUBLES_EQUAL(5.*M_PI/3.,e2->getCurveLength(),1e-12);// To check that in the previous line +2.M_PI has done its job. - CPPUNIT_ASSERT(e2->intersectWith(e1,v3,v2,v1)); - CPPUNIT_ASSERT_EQUAL(0,(int)v3.getNumberOfAssociations()); - CPPUNIT_ASSERT_EQUAL(3,(int)v1.size()); - CPPUNIT_ASSERT_EQUAL(3,(int)v2.size()); - CPPUNIT_ASSERT(v1[0]->intresincEqCoarse(v2[2]->getPtr())); CPPUNIT_ASSERT(v1[0]->getDirection()); CPPUNIT_ASSERT(v2[2]->getDirection()); - CPPUNIT_ASSERT(v1[2]->intresincEqCoarse(v2[0]->getPtr())); CPPUNIT_ASSERT(v1[2]->getDirection()); CPPUNIT_ASSERT(v2[0]->getDirection()); - CPPUNIT_ASSERT_DOUBLES_EQUAL(M_PI,v2[1]->getCurveLength(),1.e-5); // << not maximal precision because node switching - CPPUNIT_ASSERT_DOUBLES_EQUAL(M_PI/3.,v1[1]->getCurveLength(),1.e-12); - CPPUNIT_ASSERT(v2[1]->getStartNode()==e1->getEndNode()); - CPPUNIT_ASSERT(v2[1]->getEndNode()==e1->getStartNode()); - CPPUNIT_ASSERT(v1[0]->getStartNode()==e1->getStartNode()); - CPPUNIT_ASSERT(v1[0]->getEndNode()==e2->getEndNode()); - CPPUNIT_ASSERT(v1[1]->getStartNode()==e2->getEndNode()); - CPPUNIT_ASSERT(v1[1]->getEndNode()==e2->getStartNode()); - e2->decrRef(); e1->decrRef(); - v1.clear(); v2.clear(); v3.clear(); - //Test 4 - OUT_BEFORE - OUT_BEFORE | same dir. - 0 ° - e1=new EdgeLin(0.,0.,1.,0.); e2=new EdgeLin(-1.,0.,-0.5,0.); - CPPUNIT_ASSERT(!e1->intersectWith(e2,v3,v1,v2)); - CPPUNIT_ASSERT_EQUAL(0,(int)v3.getNumberOfAssociations()); - CPPUNIT_ASSERT_EQUAL(0,(int)v1.size()); - CPPUNIT_ASSERT_EQUAL(0,(int)v2.size()); - e2->decrRef(); e1->decrRef(); - v1.clear(); v2.clear(); v3.clear(); - //Test 5 - OUT_BEFORE - INSIDE | same dir. - 0° - e1=new EdgeLin(0.,0.,1.,0.); e2=new EdgeLin(-0.5,0.,0.5,0.); - CPPUNIT_ASSERT(e1->intersectWith(e2,v3,v1,v2)); - CPPUNIT_ASSERT_EQUAL(0,(int)v3.getNumberOfAssociations()); - CPPUNIT_ASSERT_EQUAL(2,(int)v1.size()); - CPPUNIT_ASSERT_EQUAL(2,(int)v2.size()); - CPPUNIT_ASSERT(v1[0]->intresicEqualDirSensitive(v2[1])); - CPPUNIT_ASSERT(v1[0]->getEndNode()==v1[1]->getStartNode()); CPPUNIT_ASSERT(v2[0]->getEndNode()==v2[1]->getStartNode()); - CPPUNIT_ASSERT(e1->getStartNode()==v1.front()->getStartNode() && e1->getEndNode()==v1.back()->getEndNode()); - CPPUNIT_ASSERT(e2->getStartNode()==v2.front()->getStartNode() && e2->getEndNode()==v2.back()->getEndNode()); - e2->decrRef(); e1->decrRef(); - v1.clear(); v2.clear(); v3.clear(); - //Test 5 - OUT_BEFORE - INSIDE | same dir. - 90° - e1=new EdgeLin(0.,0.,0.,1.); e2=new EdgeLin(0,-0.5,0.,0.5); - CPPUNIT_ASSERT(e1->intersectWith(e2,v3,v1,v2)); - CPPUNIT_ASSERT_EQUAL(0,(int)v3.getNumberOfAssociations()); - CPPUNIT_ASSERT_EQUAL(2,(int)v1.size()); - CPPUNIT_ASSERT_EQUAL(2,(int)v2.size()); - CPPUNIT_ASSERT(v1[0]->intresicEqualDirSensitive(v2[1])); - CPPUNIT_ASSERT(v1[0]->getEndNode()==v1[1]->getStartNode()); CPPUNIT_ASSERT(v2[0]->getEndNode()==v2[1]->getStartNode()); - CPPUNIT_ASSERT(e1->getStartNode()==v1.front()->getStartNode() && e1->getEndNode()==v1.back()->getEndNode()); - CPPUNIT_ASSERT(e2->getStartNode()==v2.front()->getStartNode() && e2->getEndNode()==v2.back()->getEndNode()); - e2->decrRef(); e1->decrRef(); - v1.clear(); v2.clear(); v3.clear(); - //Test 5 - OUT_BEFORE - INSIDE | same dir. - 45° - e1=new EdgeLin(0.,0.,1.,1.); e2=new EdgeLin(-0.5,-0.5,0.5,0.5); - CPPUNIT_ASSERT(e1->intersectWith(e2,v3,v1,v2)); - CPPUNIT_ASSERT_EQUAL(0,(int)v3.getNumberOfAssociations()); - CPPUNIT_ASSERT_EQUAL(2,(int)v1.size()); - CPPUNIT_ASSERT_EQUAL(2,(int)v2.size()); - CPPUNIT_ASSERT(v1[0]->intresicEqualDirSensitive(v2[1])); - CPPUNIT_ASSERT(v1[0]->getEndNode()==v1[1]->getStartNode()); CPPUNIT_ASSERT(v2[0]->getEndNode()==v2[1]->getStartNode()); - CPPUNIT_ASSERT(e1->getStartNode()==v1.front()->getStartNode() && e1->getEndNode()==v1.back()->getEndNode()); - CPPUNIT_ASSERT(e2->getStartNode()==v2.front()->getStartNode() && e2->getEndNode()==v2.back()->getEndNode()); - e2->decrRef(); e1->decrRef(); - v1.clear(); v2.clear(); v3.clear(); - //Test 5 - OUT_BEFORE - INSIDE | opp dir. - 45° - e1=new EdgeLin(0.,0.,1.,1.); e2=new EdgeLin(0.5,0.5,-0.5,-0.5); - CPPUNIT_ASSERT(e1->intersectWith(e2,v3,v1,v2)); - CPPUNIT_ASSERT_EQUAL(0,(int)v3.getNumberOfAssociations()); - CPPUNIT_ASSERT_EQUAL(2,(int)v1.size()); - CPPUNIT_ASSERT_EQUAL(2,(int)v2.size()); - CPPUNIT_ASSERT(!v1[0]->intresicEqualDirSensitive(v2[0]) && v1[0]->intresicEqual(v2[0]) ); - CPPUNIT_ASSERT(v1[0]->getEndNode()==v1[1]->getStartNode()); CPPUNIT_ASSERT(v2[0]->getEndNode()==v2[1]->getStartNode()); - CPPUNIT_ASSERT(e1->getStartNode()==v1.front()->getStartNode() && e1->getEndNode()==v1.back()->getEndNode()); - CPPUNIT_ASSERT(e2->getStartNode()==v2.front()->getStartNode() && e2->getEndNode()==v2.back()->getEndNode()); - e2->decrRef(); e1->decrRef(); - v1.clear(); v2.clear(); v3.clear(); - //Test 6 - OUT_BEFORE - OUT_AFTER | same dir. - 0° - e1=new EdgeLin(0.,0.,1.,0.); e2=new EdgeLin(-0.5,0.,1.5,0.); - CPPUNIT_ASSERT(e1->intersectWith(e2,v3,v1,v2)); - CPPUNIT_ASSERT_EQUAL(0,(int)v3.getNumberOfAssociations()); - CPPUNIT_ASSERT_EQUAL(1,(int)v1.size()); - CPPUNIT_ASSERT_EQUAL(3,(int)v2.size()); - CPPUNIT_ASSERT(v1[0]->intresincEqCoarse(e1) && v1[0]->getDirection()); - CPPUNIT_ASSERT(v2[1]->intresincEqCoarse(e1) && v2[1]->getDirection()); - CPPUNIT_ASSERT(v2[0]->getEndNode()==v2[1]->getStartNode() && v2[1]->getEndNode()==v2[2]->getStartNode()); - CPPUNIT_ASSERT(e1->getStartNode()==v1.front()->getStartNode() && e1->getEndNode()==v1.back()->getEndNode()); - CPPUNIT_ASSERT(e2->getStartNode()==v2.front()->getStartNode() && e2->getEndNode()==v2.back()->getEndNode()); - e2->decrRef(); e1->decrRef(); - v1.clear(); v2.clear(); v3.clear(); - //Test 6 - OUT_BEFORE - OUT_AFTER | same dir. - 90° - e1=new EdgeLin(0.,0.,0.,1.); e2=new EdgeLin(0.,-0.5,0.,1.5); - CPPUNIT_ASSERT(e1->intersectWith(e2,v3,v1,v2)); - CPPUNIT_ASSERT_EQUAL(0,(int)v3.getNumberOfAssociations()); - CPPUNIT_ASSERT_EQUAL(1,(int)v1.size()); - CPPUNIT_ASSERT_EQUAL(3,(int)v2.size()); - CPPUNIT_ASSERT(v1[0]->intresincEqCoarse(e1) && v1[0]->getDirection()); - CPPUNIT_ASSERT(v2[1]->intresincEqCoarse(e1) && v2[1]->getDirection()); - CPPUNIT_ASSERT(v2[0]->getEndNode()==v2[1]->getStartNode() && v2[1]->getEndNode()==v2[2]->getStartNode()); - CPPUNIT_ASSERT(e1->getStartNode()==v1.front()->getStartNode() && e1->getEndNode()==v1.back()->getEndNode()); - CPPUNIT_ASSERT(e2->getStartNode()==v2.front()->getStartNode() && e2->getEndNode()==v2.back()->getEndNode()); - e2->decrRef(); e1->decrRef(); - v1.clear(); v2.clear(); v3.clear(); - //Test 6 - OUT_BEFORE - OUT_AFTER | same dir. - 45° - e1=new EdgeLin(0.,0.,1.,1.); e2=new EdgeLin(-0.5,-0.5,1.5,1.5); - CPPUNIT_ASSERT(e1->intersectWith(e2,v3,v1,v2)); - CPPUNIT_ASSERT_EQUAL(0,(int)v3.getNumberOfAssociations()); - CPPUNIT_ASSERT_EQUAL(1,(int)v1.size()); - CPPUNIT_ASSERT_EQUAL(3,(int)v2.size()); - CPPUNIT_ASSERT(v1[0]->intresincEqCoarse(e1) && v1[0]->getDirection()); - CPPUNIT_ASSERT(v2[1]->intresincEqCoarse(e1) && v2[1]->getDirection()); - CPPUNIT_ASSERT(v2[0]->getEndNode()==v2[1]->getStartNode() && v2[1]->getEndNode()==v2[2]->getStartNode()); - CPPUNIT_ASSERT(e1->getStartNode()==v1.front()->getStartNode() && e1->getEndNode()==v1.back()->getEndNode()); - CPPUNIT_ASSERT(e2->getStartNode()==v2.front()->getStartNode() && e2->getEndNode()==v2.back()->getEndNode()); - e2->decrRef(); e1->decrRef(); - v1.clear(); v2.clear(); v3.clear(); - //Test 6 - OUT_BEFORE - OUT_AFTER | opp dir. - 45° - e1=new EdgeLin(0.,0.,1.,1.); e2=new EdgeLin(1.5,1.5,-0.5,-0.5); - CPPUNIT_ASSERT(e1->intersectWith(e2,v3,v1,v2)); - CPPUNIT_ASSERT_EQUAL(0,(int)v3.getNumberOfAssociations()); - CPPUNIT_ASSERT_EQUAL(1,(int)v1.size()); - CPPUNIT_ASSERT_EQUAL(3,(int)v2.size()); - CPPUNIT_ASSERT(v1[0]->intresincEqCoarse(e1) && v1[0]->getDirection()); - CPPUNIT_ASSERT(v2[1]->intresincEqCoarse(e1) && !v2[1]->getDirection()); - CPPUNIT_ASSERT(v2[0]->getEndNode()==v2[1]->getStartNode() && v2[1]->getEndNode()==v2[2]->getStartNode()); - CPPUNIT_ASSERT(e1->getStartNode()==v1.front()->getStartNode() && e1->getEndNode()==v1.back()->getEndNode()); - CPPUNIT_ASSERT(e2->getStartNode()==v2.front()->getStartNode() && e2->getEndNode()==v2.back()->getEndNode()); - e2->decrRef(); e1->decrRef(); - v1.clear(); v2.clear(); v3.clear(); - //Test 7 - END - OUT_AFTER | same dir. - 0° - e1=new EdgeLin(0.,0.,1.,0.); e2=new EdgeLin(1.,0.,1.5,0.); - CPPUNIT_ASSERT(!e1->intersectWith(e2,v3,v1,v2)); - CPPUNIT_ASSERT_EQUAL(1,(int)v3.getNumberOfAssociations()); - CPPUNIT_ASSERT_EQUAL(0,(int)v1.size()); - CPPUNIT_ASSERT_EQUAL(0,(int)v2.size()); - e2->decrRef(); e1->decrRef(); - v1.clear(); v2.clear(); v3.clear(); - //Test 7 - END - OUT_AFTER | opp dir. - 0° - e1=new EdgeLin(0.,0.,1.,0.); e2=new EdgeLin(1.5,0.,1.,0.); - CPPUNIT_ASSERT(!e1->intersectWith(e2,v3,v1,v2)); - CPPUNIT_ASSERT_EQUAL(1,(int)v3.getNumberOfAssociations()); - CPPUNIT_ASSERT_EQUAL(0,(int)v1.size()); - CPPUNIT_ASSERT_EQUAL(0,(int)v2.size()); - CPPUNIT_ASSERT(e1->getEndNode()==e2->getEndNode()); - e2->decrRef(); e1->decrRef(); - v1.clear(); v2.clear(); v3.clear(); - //Test 8 - START - END | same dir. - 0° - e1=new EdgeLin(0.,0.,0.7,0.); e2=new EdgeLin(0.,0.,0.7,0.); - CPPUNIT_ASSERT(e1->intersectWith(e2,v3,v1,v2)); - CPPUNIT_ASSERT_EQUAL(2,(int)v3.getNumberOfAssociations()); - CPPUNIT_ASSERT_EQUAL(1,(int)v1.size()); - CPPUNIT_ASSERT_EQUAL(1,(int)v2.size()); - CPPUNIT_ASSERT(v1[0]->intresincEqCoarse(e1) && v1[0]->getDirection()); CPPUNIT_ASSERT(v2[0]->intresincEqCoarse(e1) && v2[0]->getDirection()); - CPPUNIT_ASSERT(e1->getStartNode()==e2->getStartNode()); CPPUNIT_ASSERT(e1->getEndNode()==e2->getEndNode()); - CPPUNIT_ASSERT(e1->getStartNode()==v1.front()->getStartNode() && e1->getEndNode()==v1.back()->getEndNode()); - CPPUNIT_ASSERT(e2->getStartNode()==v2.front()->getStartNode() && e2->getEndNode()==v2.back()->getEndNode()); - e2->decrRef(); e1->decrRef(); - v1.clear(); v2.clear(); v3.clear(); - //Test 8 - START - END | same dir. - 90° - e1=new EdgeLin(0.,0.,0.,0.7); e2=new EdgeLin(0.,0.,0.,0.7); - CPPUNIT_ASSERT(e1->intersectWith(e2,v3,v1,v2)); - CPPUNIT_ASSERT_EQUAL(2,(int)v3.getNumberOfAssociations()); - CPPUNIT_ASSERT_EQUAL(1,(int)v1.size()); - CPPUNIT_ASSERT_EQUAL(1,(int)v2.size()); - CPPUNIT_ASSERT(v1[0]->intresincEqCoarse(e1) && v1[0]->getDirection()); CPPUNIT_ASSERT(v2[0]->intresincEqCoarse(e1) && v2[0]->getDirection()); - CPPUNIT_ASSERT(e1->getStartNode()==e2->getStartNode()); CPPUNIT_ASSERT(e1->getEndNode()==e2->getEndNode()); - CPPUNIT_ASSERT(e1->getStartNode()==v1.front()->getStartNode() && e1->getEndNode()==v1.back()->getEndNode()); - CPPUNIT_ASSERT(e2->getStartNode()==v2.front()->getStartNode() && e2->getEndNode()==v2.back()->getEndNode()); - e2->decrRef(); e1->decrRef(); - v1.clear(); v2.clear(); v3.clear(); - //Test 8 - START - END | same dir. - 45° - e1=new EdgeLin(0.,0.,0.7,0.7); e2=new EdgeLin(0.,0.,0.7,0.7); - CPPUNIT_ASSERT(e1->intersectWith(e2,v3,v1,v2)); - CPPUNIT_ASSERT_EQUAL(2,(int)v3.getNumberOfAssociations()); - CPPUNIT_ASSERT_EQUAL(1,(int)v1.size()); - CPPUNIT_ASSERT_EQUAL(1,(int)v2.size()); - CPPUNIT_ASSERT(v1[0]->intresincEqCoarse(e1) && v1[0]->getDirection()); CPPUNIT_ASSERT(v2[0]->intresincEqCoarse(e1) && v2[0]->getDirection()); - CPPUNIT_ASSERT(e1->getStartNode()==e2->getStartNode()); CPPUNIT_ASSERT(e1->getEndNode()==e2->getEndNode()); - CPPUNIT_ASSERT(e1->getStartNode()==v1.front()->getStartNode() && e1->getEndNode()==v1.back()->getEndNode()); - CPPUNIT_ASSERT(e2->getStartNode()==v2.front()->getStartNode() && e2->getEndNode()==v2.back()->getEndNode()); - e2->decrRef(); e1->decrRef(); - v1.clear(); v2.clear(); v3.clear(); - //Test 8 - START - END | opp. dir. - 45° - e1=new EdgeLin(0.,0.,0.7,0.7); e2=new EdgeLin(0.7,0.7,0.,0.); - CPPUNIT_ASSERT(e1->intersectWith(e2,v3,v1,v2)); - CPPUNIT_ASSERT_EQUAL(2,(int)v3.getNumberOfAssociations()); - CPPUNIT_ASSERT_EQUAL(1,(int)v1.size()); - CPPUNIT_ASSERT_EQUAL(1,(int)v2.size()); - CPPUNIT_ASSERT(v1[0]->intresincEqCoarse(e1) && v1[0]->getDirection()); CPPUNIT_ASSERT(v2[0]->intresincEqCoarse(e1) && !v2[0]->getDirection()); - CPPUNIT_ASSERT(e1->getStartNode()==e2->getEndNode()); CPPUNIT_ASSERT(e1->getEndNode()==e2->getStartNode()); - CPPUNIT_ASSERT(e1->getStartNode()==v1.front()->getStartNode() && e1->getEndNode()==v1.back()->getEndNode()); - CPPUNIT_ASSERT(e2->getStartNode()==v2.front()->getStartNode() && e2->getEndNode()==v2.back()->getEndNode()); - e2->decrRef(); e1->decrRef(); - v1.clear(); v2.clear(); v3.clear(); - //Test 9 - OUT_BEFORE - START | same dir. - e1=new EdgeLin(0.,0.,1.,0.); e2=new EdgeLin(-0.5,0.,0.,0.); - CPPUNIT_ASSERT(!e1->intersectWith(e2,v3,v1,v2)); - CPPUNIT_ASSERT_EQUAL(1,(int)v3.getNumberOfAssociations()); - CPPUNIT_ASSERT_EQUAL(0,(int)v1.size()); - CPPUNIT_ASSERT_EQUAL(0,(int)v2.size()); - CPPUNIT_ASSERT(e2->getEndNode()==e1->getStartNode()); - e2->decrRef(); e1->decrRef(); - v1.clear(); v2.clear(); v3.clear(); - //Test 10 - START - OUT_AFTER | same dir. - 0° - e1=new EdgeLin(0.,0.,0.7,0.); e2=new EdgeLin(0.,0.,1.,0.); - CPPUNIT_ASSERT(e1->intersectWith(e2,v3,v1,v2)); - CPPUNIT_ASSERT_EQUAL(1,(int)v3.getNumberOfAssociations()); - CPPUNIT_ASSERT_EQUAL(1,(int)v1.size()); - CPPUNIT_ASSERT_EQUAL(2,(int)v2.size()); - CPPUNIT_ASSERT(v1[0]->intresincEqCoarse(e1) && v1[0]->getDirection()); CPPUNIT_ASSERT(v2[0]->intresincEqCoarse(e1) && v2[0]->getDirection()); - CPPUNIT_ASSERT(e1->getStartNode()==v1[0]->getStartNode()); CPPUNIT_ASSERT(e1->getStartNode()==e2->getStartNode()); CPPUNIT_ASSERT(v2[1]->getEndNode()==e2->getEndNode()); - CPPUNIT_ASSERT(v2[0]->getEndNode()==v2[1]->getStartNode()); - CPPUNIT_ASSERT(e1->getStartNode()==v1.front()->getStartNode() && e1->getEndNode()==v1.back()->getEndNode()); - CPPUNIT_ASSERT(e2->getStartNode()==v2.front()->getStartNode() && e2->getEndNode()==v2.back()->getEndNode()); - e2->decrRef(); e1->decrRef(); - v1.clear(); v2.clear(); v3.clear(); - //Test 10 - START - OUT_AFTER | same dir. - 90° - e1=new EdgeLin(0.,0.,0.,0.7); e2=new EdgeLin(0.,0.,0.,1.); - CPPUNIT_ASSERT(e1->intersectWith(e2,v3,v1,v2)); - CPPUNIT_ASSERT_EQUAL(1,(int)v3.getNumberOfAssociations()); - CPPUNIT_ASSERT_EQUAL(1,(int)v1.size()); - CPPUNIT_ASSERT_EQUAL(2,(int)v2.size()); - CPPUNIT_ASSERT(v1[0]->intresincEqCoarse(e1) && v1[0]->getDirection()); CPPUNIT_ASSERT(v2[0]->intresincEqCoarse(e1) && v2[0]->getDirection()); - CPPUNIT_ASSERT(e1->getStartNode()==v1[0]->getStartNode()); CPPUNIT_ASSERT(e1->getStartNode()==e2->getStartNode()); CPPUNIT_ASSERT(v2[1]->getEndNode()==e2->getEndNode()); - CPPUNIT_ASSERT(v2[0]->getEndNode()==v2[1]->getStartNode()); - CPPUNIT_ASSERT(e1->getStartNode()==v1.front()->getStartNode() && e1->getEndNode()==v1.back()->getEndNode()); - CPPUNIT_ASSERT(e2->getStartNode()==v2.front()->getStartNode() && e2->getEndNode()==v2.back()->getEndNode()); - e2->decrRef(); e1->decrRef(); - v1.clear(); v2.clear(); v3.clear(); - //Test 10 - START - OUT_AFTER | same dir. - 45° - e1=new EdgeLin(0.,0.,0.7,0.7); e2=new EdgeLin(0.,0.,1.,1.); - CPPUNIT_ASSERT(e1->intersectWith(e2,v3,v1,v2)); - CPPUNIT_ASSERT_EQUAL(1,(int)v3.getNumberOfAssociations()); - CPPUNIT_ASSERT_EQUAL(1,(int)v1.size()); - CPPUNIT_ASSERT_EQUAL(2,(int)v2.size()); - CPPUNIT_ASSERT(v1[0]->intresincEqCoarse(e1) && v1[0]->getDirection()); CPPUNIT_ASSERT(v2[0]->intresincEqCoarse(e1) && v2[0]->getDirection()); - CPPUNIT_ASSERT(e1->getStartNode()==v1[0]->getStartNode()); CPPUNIT_ASSERT(e1->getStartNode()==e2->getStartNode()); CPPUNIT_ASSERT(v2[1]->getEndNode()==e2->getEndNode()); - CPPUNIT_ASSERT(v2[0]->getEndNode()==v2[1]->getStartNode()); - CPPUNIT_ASSERT(e1->getStartNode()==v1.front()->getStartNode() && e1->getEndNode()==v1.back()->getEndNode()); - CPPUNIT_ASSERT(e2->getStartNode()==v2.front()->getStartNode() && e2->getEndNode()==v2.back()->getEndNode()); - e2->decrRef(); e1->decrRef(); - v1.clear(); v2.clear(); v3.clear(); - //Test 10 - START - OUT_AFTER | opp dir. - 45° - e1=new EdgeLin(0.,0.,0.7,0.7); e2=new EdgeLin(1.,1.,0.,0.); - CPPUNIT_ASSERT(e1->intersectWith(e2,v3,v1,v2)); - CPPUNIT_ASSERT_EQUAL(1,(int)v3.getNumberOfAssociations()); - CPPUNIT_ASSERT_EQUAL(1,(int)v1.size()); - CPPUNIT_ASSERT_EQUAL(2,(int)v2.size()); - CPPUNIT_ASSERT(v1[0]->intresincEqCoarse(e1) && v1[0]->getDirection()); CPPUNIT_ASSERT(v2[1]->intresincEqCoarse(e1) && !v2[1]->getDirection()); - CPPUNIT_ASSERT(e1->getStartNode()==v1[0]->getStartNode()); CPPUNIT_ASSERT(e1->getStartNode()==e2->getEndNode()); CPPUNIT_ASSERT(v2[1]->getEndNode()==e2->getEndNode()); - CPPUNIT_ASSERT(v2[0]->getEndNode()==v2[1]->getStartNode()); - CPPUNIT_ASSERT(e1->getStartNode()==v1.front()->getStartNode() && e1->getEndNode()==v1.back()->getEndNode()); - CPPUNIT_ASSERT(e2->getStartNode()==v2.front()->getStartNode() && e2->getEndNode()==v2.back()->getEndNode()); - e2->decrRef(); e1->decrRef(); - v1.clear(); v2.clear(); v3.clear(); - //Test 11 - INSIDE - END | same dir. - 0° - e1=new EdgeLin(0.,0.,1.,0.); e2=new EdgeLin(0.7,0.,1.,0.); - CPPUNIT_ASSERT(e1->intersectWith(e2,v3,v1,v2)); - CPPUNIT_ASSERT_EQUAL(1,(int)v3.getNumberOfAssociations()); - CPPUNIT_ASSERT_EQUAL(2,(int)v1.size()); - CPPUNIT_ASSERT_EQUAL(1,(int)v2.size()); - CPPUNIT_ASSERT(v1[1]->intresincEqCoarse(e2) && v1[1]->getDirection()); CPPUNIT_ASSERT(v2[0]->intresincEqCoarse(e2) && v2[0]->getDirection()); - CPPUNIT_ASSERT(e1->getStartNode()==v1[0]->getStartNode()); CPPUNIT_ASSERT(e1->getEndNode()==v1[1]->getEndNode()); CPPUNIT_ASSERT(e1->getEndNode()==e2->getEndNode()); - CPPUNIT_ASSERT(v1[0]->getEndNode()==v1[1]->getStartNode()); - CPPUNIT_ASSERT(e1->getStartNode()==v1.front()->getStartNode() && e1->getEndNode()==v1.back()->getEndNode()); - CPPUNIT_ASSERT(e2->getStartNode()==v2.front()->getStartNode() && e2->getEndNode()==v2.back()->getEndNode()); - e2->decrRef(); e1->decrRef(); - v1.clear(); v2.clear(); v3.clear(); - //Test 11 - INSIDE - END | same dir. - 90° - e1=new EdgeLin(0.,0.,0.,1.); e2=new EdgeLin(0.,0.7,0.,1.); - CPPUNIT_ASSERT(e1->intersectWith(e2,v3,v1,v2)); - CPPUNIT_ASSERT_EQUAL(1,(int)v3.getNumberOfAssociations()); - CPPUNIT_ASSERT_EQUAL(2,(int)v1.size()); - CPPUNIT_ASSERT_EQUAL(1,(int)v2.size()); - CPPUNIT_ASSERT(v1[1]->intresincEqCoarse(e2) && v1[1]->getDirection()); CPPUNIT_ASSERT(v2[0]->intresincEqCoarse(e2) && v2[0]->getDirection()); - CPPUNIT_ASSERT(e1->getStartNode()==v1[0]->getStartNode()); CPPUNIT_ASSERT(e1->getEndNode()==v1[1]->getEndNode()); CPPUNIT_ASSERT(e1->getEndNode()==e2->getEndNode()); - CPPUNIT_ASSERT(v1[0]->getEndNode()==v1[1]->getStartNode()); - CPPUNIT_ASSERT(e1->getStartNode()==v1.front()->getStartNode() && e1->getEndNode()==v1.back()->getEndNode()); - CPPUNIT_ASSERT(e2->getStartNode()==v2.front()->getStartNode() && e2->getEndNode()==v2.back()->getEndNode()); - e2->decrRef(); e1->decrRef(); - v1.clear(); v2.clear(); v3.clear(); - //Test 11 - INSIDE - END | same dir. - 45° - e1=new EdgeLin(0.,0.,1.,1.); e2=new EdgeLin(0.7,0.7,1.,1.); - CPPUNIT_ASSERT(e1->intersectWith(e2,v3,v1,v2)); - CPPUNIT_ASSERT_EQUAL(1,(int)v3.getNumberOfAssociations()); - CPPUNIT_ASSERT_EQUAL(2,(int)v1.size()); - CPPUNIT_ASSERT_EQUAL(1,(int)v2.size()); - CPPUNIT_ASSERT(v1[1]->intresincEqCoarse(e2) && v1[1]->getDirection()); CPPUNIT_ASSERT(v2[0]->intresincEqCoarse(e2) && v2[0]->getDirection()); - CPPUNIT_ASSERT(e1->getStartNode()==v1[0]->getStartNode()); CPPUNIT_ASSERT(e1->getEndNode()==v1[1]->getEndNode()); CPPUNIT_ASSERT(e1->getEndNode()==e2->getEndNode()); - CPPUNIT_ASSERT(v1[0]->getEndNode()==v1[1]->getStartNode()); - CPPUNIT_ASSERT(e1->getStartNode()==v1.front()->getStartNode() && e1->getEndNode()==v1.back()->getEndNode()); - CPPUNIT_ASSERT(e2->getStartNode()==v2.front()->getStartNode() && e2->getEndNode()==v2.back()->getEndNode()); - e2->decrRef(); e1->decrRef(); - v1.clear(); v2.clear(); v3.clear(); - //Test 11 - INSIDE - END | opp dir. - 45° - e1=new EdgeLin(0.,0.,1.,1.); e2=new EdgeLin(1.,1.,0.7,0.7); - CPPUNIT_ASSERT(e1->intersectWith(e2,v3,v1,v2)); - CPPUNIT_ASSERT_EQUAL(1,(int)v3.getNumberOfAssociations()); - CPPUNIT_ASSERT_EQUAL(2,(int)v1.size()); - CPPUNIT_ASSERT_EQUAL(1,(int)v2.size()); - CPPUNIT_ASSERT(e1->getStartNode()==v1[0]->getStartNode()); CPPUNIT_ASSERT(e1->getEndNode()==v1[1]->getEndNode()); CPPUNIT_ASSERT(e1->getEndNode()==e2->getStartNode()); - CPPUNIT_ASSERT(v1[1]->intresincEqCoarse(e2) && !v1[1]->getDirection()); CPPUNIT_ASSERT(v2[0]->intresincEqCoarse(e2) && v2[0]->getDirection()); - CPPUNIT_ASSERT(v1[0]->getEndNode()==v1[1]->getStartNode()); - CPPUNIT_ASSERT(e1->getStartNode()==v1.front()->getStartNode() && e1->getEndNode()==v1.back()->getEndNode()); - CPPUNIT_ASSERT(e2->getStartNode()==v2.front()->getStartNode() && e2->getEndNode()==v2.back()->getEndNode()); - e2->decrRef(); e1->decrRef(); - v1.clear(); v2.clear(); v3.clear(); - //Test 12 - OUT_BEFORE - END | same dir. - 0° - e1=new EdgeLin(0.,0.,1.,0.); e2=new EdgeLin(-0.5,0.,1.,0.); - CPPUNIT_ASSERT(e1->intersectWith(e2,v3,v1,v2)); - CPPUNIT_ASSERT_EQUAL(1,(int)v3.getNumberOfAssociations()); - CPPUNIT_ASSERT_EQUAL(1,(int)v1.size()); - CPPUNIT_ASSERT_EQUAL(2,(int)v2.size()); - CPPUNIT_ASSERT(v1[0]->intresincEqCoarse(e1) && v1[0]->getDirection()); CPPUNIT_ASSERT(v2[1]->intresincEqCoarse(e1) && v2[1]->getDirection()); - CPPUNIT_ASSERT(e2->getStartNode()==v2[0]->getStartNode()); CPPUNIT_ASSERT(e1->getEndNode()==e2->getEndNode()); CPPUNIT_ASSERT(e2->getEndNode()==v2[1]->getEndNode()); - CPPUNIT_ASSERT(v2[0]->getEndNode()==v2[1]->getStartNode()); - CPPUNIT_ASSERT(e1->getStartNode()==v1.front()->getStartNode() && e1->getEndNode()==v1.back()->getEndNode()); - CPPUNIT_ASSERT(e2->getStartNode()==v2.front()->getStartNode() && e2->getEndNode()==v2.back()->getEndNode()); - e2->decrRef(); e1->decrRef(); - v1.clear(); v2.clear(); v3.clear(); - //Test 12 - OUT_BEFORE - END | same dir. - 90° - e1=new EdgeLin(0.,0.,0.,1.); e2=new EdgeLin(0.,-0.5,0.,1.); - CPPUNIT_ASSERT(e1->intersectWith(e2,v3,v1,v2)); - CPPUNIT_ASSERT_EQUAL(1,(int)v3.getNumberOfAssociations()); - CPPUNIT_ASSERT_EQUAL(1,(int)v1.size()); - CPPUNIT_ASSERT_EQUAL(2,(int)v2.size()); - CPPUNIT_ASSERT(v1[0]->intresincEqCoarse(e1) && v1[0]->getDirection()); CPPUNIT_ASSERT(v2[1]->intresincEqCoarse(e1) && v2[1]->getDirection()); - CPPUNIT_ASSERT(e2->getStartNode()==v2[0]->getStartNode()); CPPUNIT_ASSERT(e1->getEndNode()==e2->getEndNode()); CPPUNIT_ASSERT(e2->getEndNode()==v2[1]->getEndNode()); - CPPUNIT_ASSERT(v2[0]->getEndNode()==v2[1]->getStartNode()); - CPPUNIT_ASSERT(e1->getStartNode()==v1.front()->getStartNode() && e1->getEndNode()==v1.back()->getEndNode()); - CPPUNIT_ASSERT(e2->getStartNode()==v2.front()->getStartNode() && e2->getEndNode()==v2.back()->getEndNode()); - e2->decrRef(); e1->decrRef(); - v1.clear(); v2.clear(); v3.clear(); - //Test 12 - OUT_BEFORE - END | same dir. - 45° - e1=new EdgeLin(0.,0.,1.,1.); e2=new EdgeLin(-0.5,-0.5,1.,1.); - CPPUNIT_ASSERT(e1->intersectWith(e2,v3,v1,v2)); - CPPUNIT_ASSERT_EQUAL(1,(int)v3.getNumberOfAssociations()); - CPPUNIT_ASSERT_EQUAL(1,(int)v1.size()); - CPPUNIT_ASSERT_EQUAL(2,(int)v2.size()); - CPPUNIT_ASSERT(v1[0]->intresincEqCoarse(e1) && v1[0]->getDirection()); CPPUNIT_ASSERT(v2[1]->intresincEqCoarse(e1) && v2[1]->getDirection()); - CPPUNIT_ASSERT(e2->getStartNode()==v2[0]->getStartNode()); CPPUNIT_ASSERT(e1->getEndNode()==e2->getEndNode()); CPPUNIT_ASSERT(e2->getEndNode()==v2[1]->getEndNode()); - CPPUNIT_ASSERT(v2[0]->getEndNode()==v2[1]->getStartNode()); - CPPUNIT_ASSERT(e1->getStartNode()==v1.front()->getStartNode() && e1->getEndNode()==v1.back()->getEndNode()); - CPPUNIT_ASSERT(e2->getStartNode()==v2.front()->getStartNode() && e2->getEndNode()==v2.back()->getEndNode()); - e2->decrRef(); e1->decrRef(); - v1.clear(); v2.clear(); v3.clear(); - //Test 12 - OUT_BEFORE - END | opp dir. - 45° - e1=new EdgeLin(0.,0.,1.,1.); e2=new EdgeLin(1.,1.,-0.5,-0.5); - CPPUNIT_ASSERT(e1->intersectWith(e2,v3,v1,v2)); - CPPUNIT_ASSERT_EQUAL(1,(int)v3.getNumberOfAssociations()); - CPPUNIT_ASSERT_EQUAL(1,(int)v1.size()); - CPPUNIT_ASSERT_EQUAL(2,(int)v2.size()); - CPPUNIT_ASSERT(v1[0]->intresincEqCoarse(e1) && v1[0]->getDirection()); CPPUNIT_ASSERT(v2[0]->intresincEqCoarse(e1) && !v2[0]->getDirection()); - CPPUNIT_ASSERT(e2->getStartNode()==v2[0]->getStartNode()); CPPUNIT_ASSERT(e1->getEndNode()==e2->getStartNode()); CPPUNIT_ASSERT(e2->getEndNode()==v2[1]->getEndNode()); - CPPUNIT_ASSERT(v2[0]->getEndNode()==v2[1]->getStartNode()); - CPPUNIT_ASSERT(e1->getStartNode()==v1.front()->getStartNode() && e1->getEndNode()==v1.back()->getEndNode()); - CPPUNIT_ASSERT(e2->getStartNode()==v2.front()->getStartNode() && e2->getEndNode()==v2.back()->getEndNode()); - e2->decrRef(); e1->decrRef(); - v1.clear(); v2.clear(); v3.clear(); - //Test 13 - START - INSIDE | same dir. - 0° - e1=new EdgeLin(0.,0.,1.,0.); e2=new EdgeLin(0.,0.,0.5,0.); - CPPUNIT_ASSERT(e1->intersectWith(e2,v3,v1,v2)); - CPPUNIT_ASSERT_EQUAL(1,(int)v3.getNumberOfAssociations()); - CPPUNIT_ASSERT_EQUAL(2,(int)v1.size()); - CPPUNIT_ASSERT_EQUAL(1,(int)v2.size()); - CPPUNIT_ASSERT(v1[0]->intresincEqCoarse(e2) && v1[0]->getDirection()); CPPUNIT_ASSERT(v2[0]->intresincEqCoarse(e2) && v2[0]->getDirection()); - CPPUNIT_ASSERT(e2->getStartNode()==v1[0]->getStartNode()); CPPUNIT_ASSERT(e1->getStartNode()==e2->getStartNode()); CPPUNIT_ASSERT(e1->getEndNode()==v1[1]->getEndNode()); - CPPUNIT_ASSERT(v1[0]->getEndNode()==v1[1]->getStartNode()); - CPPUNIT_ASSERT(e1->getStartNode()==v1.front()->getStartNode() && e1->getEndNode()==v1.back()->getEndNode()); - CPPUNIT_ASSERT(e2->getStartNode()==v2.front()->getStartNode() && e2->getEndNode()==v2.back()->getEndNode()); - e2->decrRef(); e1->decrRef(); - v1.clear(); v2.clear(); v3.clear(); - //Test 13 - START - INSIDE | same dir. - 90° - e1=new EdgeLin(0.,0.,0.,1.); e2=new EdgeLin(0.,0.,0.,0.5); - CPPUNIT_ASSERT(e1->intersectWith(e2,v3,v1,v2)); - CPPUNIT_ASSERT_EQUAL(1,(int)v3.getNumberOfAssociations()); - CPPUNIT_ASSERT_EQUAL(2,(int)v1.size()); - CPPUNIT_ASSERT_EQUAL(1,(int)v2.size()); - CPPUNIT_ASSERT(v1[0]->intresincEqCoarse(e2) && v1[0]->getDirection()); CPPUNIT_ASSERT(v2[0]->intresincEqCoarse(e2) && v2[0]->getDirection()); - CPPUNIT_ASSERT(e2->getStartNode()==v1[0]->getStartNode()); CPPUNIT_ASSERT(e1->getStartNode()==e2->getStartNode()); CPPUNIT_ASSERT(e1->getEndNode()==v1[1]->getEndNode()); - CPPUNIT_ASSERT(v1[0]->getEndNode()==v1[1]->getStartNode()); - CPPUNIT_ASSERT(e1->getStartNode()==v1.front()->getStartNode() && e1->getEndNode()==v1.back()->getEndNode()); - CPPUNIT_ASSERT(e2->getStartNode()==v2.front()->getStartNode() && e2->getEndNode()==v2.back()->getEndNode()); - e2->decrRef(); e1->decrRef(); - v1.clear(); v2.clear(); v3.clear(); - //Test 13 - START - INSIDE | same dir. - 45° - e1=new EdgeLin(0.,0.,1.,1.); e2=new EdgeLin(0.,0.,0.5,0.5); - CPPUNIT_ASSERT(e1->intersectWith(e2,v3,v1,v2)); - CPPUNIT_ASSERT_EQUAL(1,(int)v3.getNumberOfAssociations()); - CPPUNIT_ASSERT_EQUAL(2,(int)v1.size()); - CPPUNIT_ASSERT_EQUAL(1,(int)v2.size()); - CPPUNIT_ASSERT(v1[0]->intresincEqCoarse(e2) && v1[0]->getDirection()); CPPUNIT_ASSERT(v2[0]->intresincEqCoarse(e2) && v2[0]->getDirection()); - CPPUNIT_ASSERT(e2->getStartNode()==v1[0]->getStartNode()); CPPUNIT_ASSERT(e1->getStartNode()==e2->getStartNode()); CPPUNIT_ASSERT(e1->getEndNode()==v1[1]->getEndNode()); - CPPUNIT_ASSERT(v1[0]->getEndNode()==v1[1]->getStartNode()); - CPPUNIT_ASSERT(e1->getStartNode()==v1.front()->getStartNode() && e1->getEndNode()==v1.back()->getEndNode()); - CPPUNIT_ASSERT(e2->getStartNode()==v2.front()->getStartNode() && e2->getEndNode()==v2.back()->getEndNode()); - e2->decrRef(); e1->decrRef(); - v1.clear(); v2.clear(); v3.clear(); - //Test 13 - START - INSIDE | opp dir. - 45° - e1=new EdgeLin(0.,0.,1.,1.); e2=new EdgeLin(0.5,0.5,0.,0.); - CPPUNIT_ASSERT(e1->intersectWith(e2,v3,v1,v2)); - CPPUNIT_ASSERT_EQUAL(1,(int)v3.getNumberOfAssociations()); - CPPUNIT_ASSERT_EQUAL(2,(int)v1.size()); - CPPUNIT_ASSERT_EQUAL(1,(int)v2.size()); - CPPUNIT_ASSERT(v1[0]->intresincEqCoarse(e2) && !v1[0]->getDirection()); CPPUNIT_ASSERT(v2[0]->intresincEqCoarse(e2) && v2[0]->getDirection()); - CPPUNIT_ASSERT(e2->getEndNode()==v1[0]->getStartNode()); CPPUNIT_ASSERT(e1->getStartNode()==e2->getEndNode()); CPPUNIT_ASSERT(e1->getEndNode()==v1[1]->getEndNode()); - CPPUNIT_ASSERT(v1[0]->getEndNode()==v1[1]->getStartNode()); - CPPUNIT_ASSERT(e1->getStartNode()==v1.front()->getStartNode() && e1->getEndNode()==v1.back()->getEndNode()); - CPPUNIT_ASSERT(e2->getStartNode()==v2.front()->getStartNode() && e2->getEndNode()==v2.back()->getEndNode()); - e2->decrRef(); e1->decrRef(); - v1.clear(); v2.clear(); v3.clear(); - //Test 14 - INSIDE - START | same dir. - e1=buildArcOfCircle(center,radius,-M_PI,2.*M_PI); e2=buildArcOfCircle(center,radius,M_PI/3.,-M_PI); - CPPUNIT_ASSERT_DOUBLES_EQUAL(M_PI,e1->getCurveLength(),1e-12); CPPUNIT_ASSERT_DOUBLES_EQUAL(4.*M_PI/3.,e2->getCurveLength(),1e-12); - CPPUNIT_ASSERT(e1->intersectWith(e2,v3,v1,v2)); - CPPUNIT_ASSERT_EQUAL(1,(int)v3.getNumberOfAssociations()); - CPPUNIT_ASSERT_EQUAL(2,(int)v1.size()); - CPPUNIT_ASSERT_EQUAL(2,(int)v2.size()); - CPPUNIT_ASSERT(v1[1]->intresicEqual(v2[0])); - CPPUNIT_ASSERT(v2[1]->getEndNode()==e1->getStartNode()); - CPPUNIT_ASSERT(v1[0]->getStartNode()==e1->getStartNode()); - CPPUNIT_ASSERT(v1[1]->getEndNode()==e1->getEndNode()); - CPPUNIT_ASSERT(v2[1]->getStartNode()==e1->getEndNode()); - CPPUNIT_ASSERT_DOUBLES_EQUAL(2*M_PI/3.,v1[0]->getCurveLength(),1.e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(M_PI/3.,v2[0]->getCurveLength(),1.e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(M_PI,v2[1]->getCurveLength(),1.e-12); - e2->decrRef(); e1->decrRef(); - v1.clear(); v2.clear(); v3.clear(); - //Test 14 - INSIDE - START | opp dir. - e1=buildArcOfCircle(center,radius,-M_PI,2.*M_PI); e2=buildArcOfCircle(center,radius,-M_PI,M_PI/3.); - CPPUNIT_ASSERT_DOUBLES_EQUAL(M_PI,e1->getCurveLength(),1e-12); CPPUNIT_ASSERT_DOUBLES_EQUAL(4.*M_PI/3.,e2->getCurveLength(),1e-12); - CPPUNIT_ASSERT(e1->intersectWith(e2,v3,v1,v2)); - CPPUNIT_ASSERT_EQUAL(1,(int)v3.getNumberOfAssociations()); - CPPUNIT_ASSERT_EQUAL(2,(int)v1.size()); - CPPUNIT_ASSERT_EQUAL(2,(int)v2.size()); - CPPUNIT_ASSERT(v1[1]->intresincEqCoarse(v2[1]->getPtr()) && !v2[1]->getDirection() && v1[1]->getDirection()); - CPPUNIT_ASSERT(v2[0]->getStartNode()==e1->getStartNode()); - CPPUNIT_ASSERT(v1[0]->getStartNode()==e1->getStartNode()); - CPPUNIT_ASSERT(v1[1]->getEndNode()==e1->getEndNode()); - CPPUNIT_ASSERT(v2[1]->getStartNode()==e1->getEndNode()); - CPPUNIT_ASSERT(v2[0]->getEndNode()==e1->getEndNode()); - CPPUNIT_ASSERT_DOUBLES_EQUAL(2*M_PI/3.,v1[0]->getCurveLength(),1.e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(M_PI/3.,v2[1]->getCurveLength(),1.e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(M_PI,v2[0]->getCurveLength(),1.e-12); - e2->decrRef(); e1->decrRef(); - v1.clear(); v2.clear(); v3.clear(); - //Test 15 - END - INSIDE | same dir. - e1=buildArcOfCircle(center,radius,-M_PI,2.*M_PI); e2=buildArcOfCircle(center,radius,0.,-4.*M_PI/3); - CPPUNIT_ASSERT_DOUBLES_EQUAL(M_PI,e1->getCurveLength(),1e-12); CPPUNIT_ASSERT_DOUBLES_EQUAL(4.*M_PI/3.,e2->getCurveLength(),1e-12); - CPPUNIT_ASSERT(e1->intersectWith(e2,v3,v1,v2)); - CPPUNIT_ASSERT_EQUAL(1,(int)v3.getNumberOfAssociations()); - CPPUNIT_ASSERT_EQUAL(2,(int)v1.size()); - CPPUNIT_ASSERT_EQUAL(2,(int)v2.size()); - CPPUNIT_ASSERT(v1[0]->intresicEqual(v2[1])); - CPPUNIT_ASSERT(v2[0]->getEndNode()==e1->getStartNode()); - CPPUNIT_ASSERT(v1[0]->getStartNode()==e1->getStartNode()); - CPPUNIT_ASSERT(v1[1]->getEndNode()==e1->getEndNode()); - CPPUNIT_ASSERT(v2[0]->getStartNode()==e1->getEndNode()); - CPPUNIT_ASSERT_DOUBLES_EQUAL(M_PI/3.,v1[0]->getCurveLength(),1.e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(M_PI,v2[0]->getCurveLength(),1.e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(2.*M_PI/3.,v1[1]->getCurveLength(),1.e-12); - e2->decrRef(); e1->decrRef(); - v1.clear(); v2.clear(); v3.clear(); - //Test 15 - END - INSIDE | opp dir. - e1=buildArcOfCircle(center,radius,-M_PI,2.*M_PI); e2=buildArcOfCircle(center,radius,-4.*M_PI/3,0.); - CPPUNIT_ASSERT_DOUBLES_EQUAL(M_PI,e1->getCurveLength(),1e-12); CPPUNIT_ASSERT_DOUBLES_EQUAL(4.*M_PI/3.,e2->getCurveLength(),1e-12); - CPPUNIT_ASSERT(e1->intersectWith(e2,v3,v1,v2)); - CPPUNIT_ASSERT_EQUAL(1,(int)v3.getNumberOfAssociations()); - CPPUNIT_ASSERT_EQUAL(2,(int)v1.size()); - CPPUNIT_ASSERT_EQUAL(2,(int)v2.size()); - CPPUNIT_ASSERT(v1[0]->intresincEqCoarse(v2[0]->getPtr()) && !v2[0]->getDirection() && v1[0]->getDirection()); - CPPUNIT_ASSERT(v2[0]->getEndNode()==e1->getStartNode()); - CPPUNIT_ASSERT(v1[0]->getStartNode()==e1->getStartNode()); - CPPUNIT_ASSERT(v1[1]->getEndNode()==e1->getEndNode()); - CPPUNIT_ASSERT(v2[1]->getEndNode()==e1->getEndNode()); - CPPUNIT_ASSERT_DOUBLES_EQUAL(M_PI/3.,v1[0]->getCurveLength(),1.e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(M_PI,v2[1]->getCurveLength(),1.e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(2.*M_PI/3.,v1[1]->getCurveLength(),1.e-12); - e2->decrRef(); e1->decrRef(); - v1.clear(); v2.clear(); v3.clear(); - // - ComposedEdge::Delete(&v1); - ComposedEdge::Delete(&v2); -} - -/*! - * Here there is test of cases where between 2 edges intersects only in points not on edge. - */ -void QuadraticPlanarInterpTest::IntersectionPointOnlyUnitarySegSeg() -{ - // 0° - classical - EdgeLin *e1=new EdgeLin(0.,0.,1.,0.); - EdgeLin *e2=new EdgeLin(0.3,0.3,0.5,-0.3); - ComposedEdge& v1=*(new ComposedEdge); - ComposedEdge& v2=*(new ComposedEdge); MergePoints v3; - CPPUNIT_ASSERT(e1->intersectWith(e2,v3,v1,v2)); - CPPUNIT_ASSERT_EQUAL(0,(int)v3.getNumberOfAssociations()); - CPPUNIT_ASSERT_EQUAL(2,(int)v1.size()); - CPPUNIT_ASSERT_EQUAL(2,(int)v2.size()); - CPPUNIT_ASSERT(v1[0]->getEndNode()==v1[1]->getStartNode()); CPPUNIT_ASSERT(v2[0]->getEndNode()==v2[1]->getStartNode()); - CPPUNIT_ASSERT(e1->getStartNode()==v1.front()->getStartNode() && e1->getEndNode()==v1.back()->getEndNode()); - CPPUNIT_ASSERT(e2->getStartNode()==v2.front()->getStartNode() && e2->getEndNode()==v2.back()->getEndNode()); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.4,(*v1[0]->getEndNode())[0],ADMISSIBLE_ERROR); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.,(*v1[0]->getEndNode())[1],ADMISSIBLE_ERROR); - e2->decrRef(); e1->decrRef(); - v1.clear(); v2.clear(); v3.clear(); - // 90° - classical - e1=new EdgeLin(0.,0.,0.,1.); - e2=new EdgeLin(-0.3,0.3,0.3,0.5); - CPPUNIT_ASSERT(e1->intersectWith(e2,v3,v1,v2)); - CPPUNIT_ASSERT_EQUAL(0,(int)v3.getNumberOfAssociations()); - CPPUNIT_ASSERT_EQUAL(2,(int)v1.size()); - CPPUNIT_ASSERT_EQUAL(2,(int)v2.size()); - CPPUNIT_ASSERT(v1[0]->getEndNode()==v1[1]->getStartNode()); CPPUNIT_ASSERT(v2[0]->getEndNode()==v2[1]->getStartNode()); - CPPUNIT_ASSERT(e1->getStartNode()==v1.front()->getStartNode() && e1->getEndNode()==v1.back()->getEndNode()); - CPPUNIT_ASSERT(e2->getStartNode()==v2.front()->getStartNode() && e2->getEndNode()==v2.back()->getEndNode()); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.,(*v1[0]->getEndNode())[0],ADMISSIBLE_ERROR); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.4,(*v1[0]->getEndNode())[1],ADMISSIBLE_ERROR); - e2->decrRef(); e1->decrRef(); - v1.clear(); v2.clear(); v3.clear(); - //Test 1 - 0° - e1=new EdgeLin(0.,0.,1.,0.); e2=new EdgeLin(0.,0.,0.,1.); - CPPUNIT_ASSERT(!e1->intersectWith(e2,v3,v1,v2)); - CPPUNIT_ASSERT_EQUAL(1,(int)v3.getNumberOfAssociations()); - CPPUNIT_ASSERT(v3.isStart1(0)); CPPUNIT_ASSERT(v3.isStart2(0)); - e2->decrRef(); e1->decrRef(); - v1.clear(); v2.clear(); v3.clear(); - //Test 1 - 90° - e1=new EdgeLin(0.,0.,0.,1.); e2=new EdgeLin(0.,0.,1.,0.); - CPPUNIT_ASSERT(!e1->intersectWith(e2,v3,v1,v2)); - CPPUNIT_ASSERT_EQUAL(1,(int)v3.getNumberOfAssociations()); - CPPUNIT_ASSERT(v3.isStart1(0)); CPPUNIT_ASSERT(v3.isStart2(0)); - e2->decrRef(); e1->decrRef(); - v1.clear(); v2.clear(); v3.clear(); - //Test 1 - 45° - e1=new EdgeLin(0.,0.,1.,1.); e2=new EdgeLin(0.,0.,1.,-1.); - CPPUNIT_ASSERT(!e1->intersectWith(e2,v3,v1,v2)); - CPPUNIT_ASSERT_EQUAL(1,(int)v3.getNumberOfAssociations()); - CPPUNIT_ASSERT(v3.isStart1(0)); CPPUNIT_ASSERT(v3.isStart2(0)); - e2->decrRef(); e1->decrRef(); - v1.clear(); v2.clear(); v3.clear(); - //Test 2 - e1=new EdgeLin(0.,0.,1.,0.); e2=new EdgeLin(1.,1.,1.,0.); - CPPUNIT_ASSERT(!e1->intersectWith(e2,v3,v1,v2)); - CPPUNIT_ASSERT_EQUAL(1,(int)v3.getNumberOfAssociations()); - CPPUNIT_ASSERT(v3.isEnd1(0)); CPPUNIT_ASSERT(v3.isEnd2(0)); - e2->decrRef(); e1->decrRef(); - v1.clear(); v2.clear(); v3.clear(); - //Test 3 - e1=new EdgeLin(0.,0.,1.,0.); e2=new EdgeLin(1.,0.,1.,1.); - CPPUNIT_ASSERT(!e1->intersectWith(e2,v3,v1,v2)); - CPPUNIT_ASSERT_EQUAL(1,(int)v3.getNumberOfAssociations()); - CPPUNIT_ASSERT(v3.isEnd1(0)); CPPUNIT_ASSERT(v3.isStart2(0)); - e2->decrRef(); e1->decrRef(); - v1.clear(); v2.clear(); v3.clear(); - //Test 4 - e1=new EdgeLin(0.,0.,1.,1.); e2=new EdgeLin(1.,-1.,0.,0.); - CPPUNIT_ASSERT(!e1->intersectWith(e2,v3,v1,v2)); - CPPUNIT_ASSERT_EQUAL(1,(int)v3.getNumberOfAssociations()); - CPPUNIT_ASSERT(v3.isStart1(0)); CPPUNIT_ASSERT(v3.isEnd2(0)); - e2->decrRef(); e1->decrRef(); - v1.clear(); v2.clear(); v3.clear(); - //Intersection extremity of one edge and inside of other edge. 2 End. - e1=new EdgeLin(0.,0.,1.,0.); - e2=new EdgeLin(0.5,1.,0.5,0.); - CPPUNIT_ASSERT(e1->intersectWith(e2,v3,v1,v2)); - CPPUNIT_ASSERT_EQUAL(2,(int)v1.size()); - CPPUNIT_ASSERT_EQUAL(1,(int)v2.size()); - CPPUNIT_ASSERT_EQUAL(0,(int)v3.getNumberOfAssociations()); - CPPUNIT_ASSERT(v2[0]->intresincEqCoarse(e2) && v2[0]->getDirection()); - CPPUNIT_ASSERT(v1[0]->getStartNode()==e1->getStartNode() && v1[0]->getEndNode()==e2->getEndNode() && v1[1]->getStartNode()==e2->getEndNode() && v1[1]->getEndNode()==e1->getEndNode()); - CPPUNIT_ASSERT(v1[0]->getDirection() && v1[1]->getDirection()); - e2->decrRef(); e1->decrRef(); - v1.clear(); v2.clear(); v3.clear(); - //Intersection extremity of one edge and inside of other edge. 2 Start. - e1=new EdgeLin(0.,0.,1.,0.); - e2=new EdgeLin(0.5,0.,0.5,1.); - CPPUNIT_ASSERT(e1->intersectWith(e2,v3,v1,v2)); - CPPUNIT_ASSERT_EQUAL(2,(int)v1.size()); - CPPUNIT_ASSERT_EQUAL(1,(int)v2.size()); - CPPUNIT_ASSERT_EQUAL(0,(int)v3.getNumberOfAssociations()); - CPPUNIT_ASSERT(v2[0]->intresincEqCoarse(e2) && v2[0]->getDirection()); - CPPUNIT_ASSERT(v1[0]->getStartNode()==e1->getStartNode() && v1[0]->getEndNode()==e2->getStartNode() && v1[1]->getStartNode()==e2->getStartNode() && v1[1]->getEndNode()==e1->getEndNode()); - CPPUNIT_ASSERT(v1[0]->getDirection() && v1[1]->getDirection()); - e2->decrRef(); e1->decrRef(); - v1.clear(); v2.clear(); v3.clear(); - //Intersection extremity of one edge and inside of other edge. 1 Start. - e1=new EdgeLin(0.5,0.,0.5,1.); - e2=new EdgeLin(0.,0.,1.,0.); - CPPUNIT_ASSERT(e1->intersectWith(e2,v3,v1,v2)); - CPPUNIT_ASSERT_EQUAL(1,(int)v1.size()); - CPPUNIT_ASSERT_EQUAL(2,(int)v2.size()); - CPPUNIT_ASSERT_EQUAL(0,(int)v3.getNumberOfAssociations()); - CPPUNIT_ASSERT(v1[0]->intresincEqCoarse(e1) && v1[0]->getDirection()); - CPPUNIT_ASSERT(v2[0]->getStartNode()==e2->getStartNode() && v2[0]->getEndNode()==e1->getStartNode() && v2[1]->getStartNode()==e1->getStartNode() && v2[1]->getEndNode()==e2->getEndNode()); - CPPUNIT_ASSERT(v2[0]->getDirection() && v2[1]->getDirection()); - e2->decrRef(); e1->decrRef(); - v1.clear(); v2.clear(); v3.clear(); - //Intersection extremity of one edge and inside of other edge. 1 End. - e1=new EdgeLin(0.5,1.,0.5,0.); - e2=new EdgeLin(0.,0.,1.,0.); - CPPUNIT_ASSERT(e1->intersectWith(e2,v3,v1,v2)); - CPPUNIT_ASSERT_EQUAL(1,(int)v1.size()); - CPPUNIT_ASSERT_EQUAL(2,(int)v2.size()); - CPPUNIT_ASSERT_EQUAL(0,(int)v3.getNumberOfAssociations()); - CPPUNIT_ASSERT(v1[0]->intresincEqCoarse(e1) && v1[0]->getDirection()); - CPPUNIT_ASSERT(v2[0]->getStartNode()==e2->getStartNode() && v2[0]->getEndNode()==e1->getEndNode() && v2[1]->getStartNode()==e1->getEndNode() && v2[1]->getEndNode()==e2->getEndNode()); - CPPUNIT_ASSERT(v2[0]->getDirection() && v2[1]->getDirection()); - e2->decrRef(); e1->decrRef(); - v1.clear(); v2.clear(); v3.clear(); - ComposedEdge::Delete(&v2); - ComposedEdge::Delete(&v1); -} - -} diff --git a/src/INTERP_KERNELTest/QuadraticPlanarInterpTest.hxx b/src/INTERP_KERNELTest/QuadraticPlanarInterpTest.hxx deleted file mode 100644 index 991e47b28..000000000 --- a/src/INTERP_KERNELTest/QuadraticPlanarInterpTest.hxx +++ /dev/null @@ -1,214 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 -// 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 _QUADRATICPLANARINTERPTEST_HXX_ -#define _QUADRATICPLANARINTERPTEST_HXX_ - -#include - -#include "InterpKernelTestExport.hxx" -#include "InterpKernelGeo2DEdgeArcCircle.hxx" -#include "InterpKernelGeo2DQuadraticPolygon.hxx" - -namespace INTERP_TEST -{ - class INTERPKERNELTEST_EXPORT QuadraticPlanarInterpTest : public CppUnit::TestFixture - { - CPPUNIT_TEST_SUITE( QuadraticPlanarInterpTest ); - CPPUNIT_TEST( ReadWriteInXfigElementary ); - CPPUNIT_TEST( ReadWriteInXfigGlobal ); - CPPUNIT_TEST( BasicGeometricTools ); - CPPUNIT_TEST( IntersectionBasics ); - CPPUNIT_TEST( EdgeLinUnitary ); - CPPUNIT_TEST( IntersectionEdgeOverlapUnitarySegSeg ); - CPPUNIT_TEST( IntersectionPointOnlyUnitarySegSeg ); - CPPUNIT_TEST( IntersectArcCircleBase ); - CPPUNIT_TEST( IntersectArcCircleFull ); - CPPUNIT_TEST( IntersectArcCircleSegumentBase ); - CPPUNIT_TEST( checkInOutDetection ); - CPPUNIT_TEST( checkAssemblingBases1 ); - CPPUNIT_TEST( checkAssemblingBases2 ); - CPPUNIT_TEST( checkPolygonsIntersection1 ); - CPPUNIT_TEST( checkPolygonsIntersection2 ); - CPPUNIT_TEST( checkAreasCalculations ); - CPPUNIT_TEST( checkBarycenterCalculations ); - CPPUNIT_TEST( checkHighLevelFunctionTest1 ); - CPPUNIT_TEST( check1DInterpLin ); - CPPUNIT_TEST( checkEpsilonCoherency1 ); - CPPUNIT_TEST( checkNonRegression1 ); - CPPUNIT_TEST( checkNonRegression2 ); - CPPUNIT_TEST( checkNonRegression3 ); - CPPUNIT_TEST( checkNonRegression4 ); - CPPUNIT_TEST( checkNonRegression5 ); - CPPUNIT_TEST( checkNonRegression6 ); - CPPUNIT_TEST( checkNonRegression7 ); - CPPUNIT_TEST( checkNonRegression8 ); - CPPUNIT_TEST( checkNonRegression9 ); - CPPUNIT_TEST( checkNonRegression10 ); - CPPUNIT_TEST( checkNonRegression11 ); - CPPUNIT_TEST( checkNonRegression12 ); - CPPUNIT_TEST ( checkNonRegression13 ); - CPPUNIT_TEST ( checkNonRegression14 ); - CPPUNIT_TEST ( checkNonRegression15 ); - CPPUNIT_TEST ( checkNonRegression16 ); - CPPUNIT_TEST ( checkNonRegression17 ); - // - CPPUNIT_TEST ( checkNonRegressionOmar0000 ); - CPPUNIT_TEST ( checkNonRegressionOmar0001 ); - CPPUNIT_TEST ( checkNonRegressionOmar0002 ); - CPPUNIT_TEST ( checkNonRegressionOmar0003 ); - CPPUNIT_TEST ( checkNonRegressionOmar0004 ); - CPPUNIT_TEST ( checkNonRegressionOmar0005 ); - CPPUNIT_TEST ( checkNonRegressionOmar0006 ); - CPPUNIT_TEST ( checkNonRegressionOmar0007 ); - CPPUNIT_TEST ( checkNonRegressionOmar0008 ); - CPPUNIT_TEST ( checkNonRegressionOmar0009 ); - CPPUNIT_TEST ( checkNonRegressionOmar0010 ); - CPPUNIT_TEST ( checkNonRegressionOmar0011 ); - CPPUNIT_TEST ( checkNonRegressionOmar2511 ); - CPPUNIT_TEST ( checkNonRegressionOmar0012 ); - CPPUNIT_TEST ( checkNonRegressionOmar0013 ); - CPPUNIT_TEST ( checkNonRegressionOmar0014 ); - CPPUNIT_TEST ( checkNonRegressionOmar0015 ); - CPPUNIT_TEST ( checkNonRegressionOmar0016 ); - CPPUNIT_TEST ( checkNonRegressionOmar0017 ); - CPPUNIT_TEST ( checkNonRegressionOmar0018 ); - CPPUNIT_TEST ( checkNonRegressionOmar0019 ); - CPPUNIT_TEST ( checkNonRegressionOmar0020 ); - CPPUNIT_TEST ( checkNonRegressionOmar0021 ); - CPPUNIT_TEST ( checkNonRegressionOmar0022 ); - CPPUNIT_TEST ( checkNonRegressionOmar0023 ); - CPPUNIT_TEST ( checkNonRegressionOmar0024 ); - CPPUNIT_TEST ( checkNonRegressionOmar2524 ); - CPPUNIT_TEST ( checkNonRegressionOmar0025 ); - CPPUNIT_TEST ( checkNonRegressionOmar0026 ); - CPPUNIT_TEST ( checkNonRegressionOmar0027 ); - CPPUNIT_TEST ( checkNonRegressionOmar0028 ); - CPPUNIT_TEST ( checkNonRegressionOmar0029 ); - CPPUNIT_TEST ( checkNonRegressionOmar0030 ); - // - CPPUNIT_TEST( checkNormalize ); - CPPUNIT_TEST( checkMakePartitionAbs1 ); - // - CPPUNIT_TEST( checkIsInOrOut ); - CPPUNIT_TEST( checkGetMiddleOfPoints ); - CPPUNIT_TEST( checkGetMiddleOfPointsOriented ); - CPPUNIT_TEST_SUITE_END(); - public: - void setUp(); - void tearDown(); - void cleanUp(); - // - void ReadWriteInXfigElementary(); - void ReadWriteInXfigGlobal(); - void BasicGeometricTools(); - void IntersectionBasics(); - void EdgeLinUnitary(); - void IntersectionEdgeOverlapUnitarySegSeg(); - void IntersectionPointOnlyUnitarySegSeg(); - // - void IntersectArcCircleBase(); - void IntersectArcCircleFull(); - void IntersectArcCircleSegumentBase(); - // - void checkInOutDetection(); - // - void checkAssemblingBases1(); - void checkAssemblingBases2(); - // - void checkPolygonsIntersection1(); - void checkPolygonsIntersection2(); - void checkAreasCalculations(); - void checkBarycenterCalculations(); - // - void checkHighLevelFunctionTest1(); - // - void check1DInterpLin(); - // - void checkEpsilonCoherency1(); - // - void checkNonRegression1(); - void checkNonRegression2(); - void checkNonRegression3(); - void checkNonRegression4(); - void checkNonRegression5(); - void checkNonRegression6(); - void checkNonRegression7(); - void checkNonRegression8(); - void checkNonRegression9(); - void checkNonRegression10(); - void checkNonRegression11(); - void checkNonRegression12(); - void checkNonRegression13(); - void checkNonRegression14(); - void checkNonRegression15(); - void checkNonRegression16(); - void checkNonRegression17(); - // - void checkNonRegressionOmar0000(); - void checkNonRegressionOmar0001(); - void checkNonRegressionOmar0002(); - void checkNonRegressionOmar0003(); - void checkNonRegressionOmar0004(); - void checkNonRegressionOmar0005(); - void checkNonRegressionOmar0006(); - void checkNonRegressionOmar0007(); - void checkNonRegressionOmar0008(); - void checkNonRegressionOmar0009(); - void checkNonRegressionOmar0010(); - void checkNonRegressionOmar0011(); - void checkNonRegressionOmar2511(); - void checkNonRegressionOmar0012(); - void checkNonRegressionOmar0013(); - void checkNonRegressionOmar0014(); - void checkNonRegressionOmar0015(); - void checkNonRegressionOmar0016(); - void checkNonRegressionOmar0017(); - void checkNonRegressionOmar0018(); - void checkNonRegressionOmar0019(); - void checkNonRegressionOmar0020(); - void checkNonRegressionOmar0021(); - void checkNonRegressionOmar0022(); - void checkNonRegressionOmar0023(); - void checkNonRegressionOmar0024(); - void checkNonRegressionOmar2524(); - void checkNonRegressionOmar0025(); - void checkNonRegressionOmar0026(); - void checkNonRegressionOmar0027(); - void checkNonRegressionOmar0028(); - void checkNonRegressionOmar0029(); - void checkNonRegressionOmar0030(); - // - void checkNormalize(); - void checkMakePartitionAbs1(); - // From Adrien: - void checkIsInOrOut(); - void checkGetMiddleOfPoints(); - void checkGetMiddleOfPointsOriented(); - - private: - INTERP_KERNEL::QuadraticPolygon *buildQuadraticPolygonCoarseInfo(const double *coords, const int *conn, int lgth); - INTERP_KERNEL::EdgeArcCircle *buildArcOfCircle(const double *center, double radius, double alphaStart, double alphaEnd); - double btw2NodesAndACenter(const INTERP_KERNEL::Node& n1, const INTERP_KERNEL::Node& n2, const double *center); - void checkBasicsOfPolygons(INTERP_KERNEL::QuadraticPolygon& pol1, INTERP_KERNEL::QuadraticPolygon& pol2, bool checkDirection); - }; -} - -#endif diff --git a/src/INTERP_KERNELTest/QuadraticPlanarInterpTest2.cxx b/src/INTERP_KERNELTest/QuadraticPlanarInterpTest2.cxx deleted file mode 100644 index a41827b15..000000000 --- a/src/INTERP_KERNELTest/QuadraticPlanarInterpTest2.cxx +++ /dev/null @@ -1,675 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 -// 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 "QuadraticPlanarInterpTest.hxx" -#include "InterpKernelGeo2DQuadraticPolygon.hxx" -#include "InterpKernelGeo2DEdgeArcCircle.hxx" -#include "InterpKernelGeo2DEdgeLin.hxx" - -#include -#include -#include - -using namespace INTERP_KERNEL; - -namespace INTERP_TEST -{ - -static const double ADMISSIBLE_ERROR = 1.e-14; - -void QuadraticPlanarInterpTest::IntersectArcCircleBase() -{ - double center[2]={0.5,0.5}; - double radius=0.3; - EdgeArcCircle *e1=buildArcOfCircle(center,radius,M_PI/4.,M_PI/3.); - CPPUNIT_ASSERT_DOUBLES_EQUAL(e1->getBounds()[0],center[0]+radius*cos(M_PI/3),ADMISSIBLE_ERROR); - CPPUNIT_ASSERT_DOUBLES_EQUAL(e1->getBounds()[1],center[0]+radius*cos(M_PI/4),ADMISSIBLE_ERROR); - CPPUNIT_ASSERT_DOUBLES_EQUAL(e1->getBounds()[2],center[1]+radius*sin(M_PI/4),ADMISSIBLE_ERROR); - CPPUNIT_ASSERT_DOUBLES_EQUAL(e1->getBounds()[3],center[1]+radius*sin(M_PI/3),ADMISSIBLE_ERROR); - e1->decrRef(); - // - e1=buildArcOfCircle(center,radius,M_PI/3.,M_PI/2.); - CPPUNIT_ASSERT_DOUBLES_EQUAL(e1->getBounds()[0],center[0]+radius*cos(M_PI/2),ADMISSIBLE_ERROR); - CPPUNIT_ASSERT_DOUBLES_EQUAL(e1->getBounds()[1],center[0]+radius*cos(M_PI/3),ADMISSIBLE_ERROR); - CPPUNIT_ASSERT_DOUBLES_EQUAL(e1->getBounds()[2],center[1]+radius*sin(M_PI/3),ADMISSIBLE_ERROR); - CPPUNIT_ASSERT_DOUBLES_EQUAL(e1->getBounds()[3],center[1]+radius*sin(M_PI/2),ADMISSIBLE_ERROR); - e1->decrRef(); - // - e1=buildArcOfCircle(center,radius,M_PI/3.,3.*M_PI/4.); - CPPUNIT_ASSERT_DOUBLES_EQUAL(e1->getBounds()[0],center[0]+radius*cos(3*M_PI/4),ADMISSIBLE_ERROR); - CPPUNIT_ASSERT_DOUBLES_EQUAL(e1->getBounds()[1],center[0]+radius*cos(M_PI/3),ADMISSIBLE_ERROR); - CPPUNIT_ASSERT_DOUBLES_EQUAL(e1->getBounds()[2],center[1]+radius*sin(3*M_PI/4),ADMISSIBLE_ERROR); - CPPUNIT_ASSERT_DOUBLES_EQUAL(e1->getBounds()[3],center[1]+radius*sin(M_PI/2),ADMISSIBLE_ERROR);//<< - e1->decrRef(); - // - e1=buildArcOfCircle(center,radius,3*M_PI/4,7*M_PI/8); - CPPUNIT_ASSERT_DOUBLES_EQUAL(e1->getBounds()[0],center[0]+radius*cos(7*M_PI/8),ADMISSIBLE_ERROR); - CPPUNIT_ASSERT_DOUBLES_EQUAL(e1->getBounds()[1],center[0]+radius*cos(3*M_PI/4),ADMISSIBLE_ERROR); - CPPUNIT_ASSERT_DOUBLES_EQUAL(e1->getBounds()[2],center[1]+radius*sin(7*M_PI/8),ADMISSIBLE_ERROR); - CPPUNIT_ASSERT_DOUBLES_EQUAL(e1->getBounds()[3],center[1]+radius*sin(3*M_PI/4),ADMISSIBLE_ERROR); - e1->decrRef(); - // - e1=buildArcOfCircle(center,radius,7.*M_PI/8.,9.*M_PI/8.); - CPPUNIT_ASSERT_DOUBLES_EQUAL(e1->getBounds()[0],center[0]+radius*cos(M_PI),ADMISSIBLE_ERROR);//<< - CPPUNIT_ASSERT_DOUBLES_EQUAL(e1->getBounds()[1],center[0]+radius*cos(7*M_PI/8),ADMISSIBLE_ERROR); - CPPUNIT_ASSERT_DOUBLES_EQUAL(e1->getBounds()[2],center[1]+radius*sin(9*M_PI/8),ADMISSIBLE_ERROR); - CPPUNIT_ASSERT_DOUBLES_EQUAL(e1->getBounds()[3],center[1]+radius*sin(7*M_PI/8),ADMISSIBLE_ERROR); - e1->decrRef(); - // - e1=buildArcOfCircle(center,radius,9.*M_PI/8.,11.*M_PI/8.); - CPPUNIT_ASSERT_DOUBLES_EQUAL(e1->getBounds()[0],center[0]+radius*cos(9*M_PI/8),ADMISSIBLE_ERROR); - CPPUNIT_ASSERT_DOUBLES_EQUAL(e1->getBounds()[1],center[0]+radius*cos(11*M_PI/8),ADMISSIBLE_ERROR); - CPPUNIT_ASSERT_DOUBLES_EQUAL(e1->getBounds()[2],center[1]+radius*sin(11*M_PI/8),ADMISSIBLE_ERROR); - CPPUNIT_ASSERT_DOUBLES_EQUAL(e1->getBounds()[3],center[1]+radius*sin(9*M_PI/8),ADMISSIBLE_ERROR); - e1->decrRef(); - // - e1=buildArcOfCircle(center,radius,11.*M_PI/8.,7.*M_PI/4.); - CPPUNIT_ASSERT_DOUBLES_EQUAL(e1->getBounds()[0],center[0]+radius*cos(11*M_PI/8),ADMISSIBLE_ERROR); - CPPUNIT_ASSERT_DOUBLES_EQUAL(e1->getBounds()[1],center[0]+radius*cos(7*M_PI/4),ADMISSIBLE_ERROR); - CPPUNIT_ASSERT_DOUBLES_EQUAL(e1->getBounds()[2],center[1]+radius*sin(3*M_PI/2),ADMISSIBLE_ERROR);//<< - CPPUNIT_ASSERT_DOUBLES_EQUAL(e1->getBounds()[3],center[1]+radius*sin(7*M_PI/4),ADMISSIBLE_ERROR); - e1->decrRef(); - // - e1=buildArcOfCircle(center,radius,7.*M_PI/4.,15.*M_PI/8.); - CPPUNIT_ASSERT_DOUBLES_EQUAL(e1->getBounds()[0],center[0]+radius*cos(7*M_PI/4),ADMISSIBLE_ERROR); - CPPUNIT_ASSERT_DOUBLES_EQUAL(e1->getBounds()[1],center[0]+radius*cos(15*M_PI/8),ADMISSIBLE_ERROR); - CPPUNIT_ASSERT_DOUBLES_EQUAL(e1->getBounds()[2],center[1]+radius*sin(7*M_PI/4),ADMISSIBLE_ERROR); - CPPUNIT_ASSERT_DOUBLES_EQUAL(e1->getBounds()[3],center[1]+radius*sin(15*M_PI/8),ADMISSIBLE_ERROR); - e1->decrRef(); - // - e1=buildArcOfCircle(center,radius,-M_PI/8.,M_PI/4.); - CPPUNIT_ASSERT_DOUBLES_EQUAL(e1->getBounds()[0],center[0]+radius*cos(M_PI/4),ADMISSIBLE_ERROR); - CPPUNIT_ASSERT_DOUBLES_EQUAL(e1->getBounds()[1],center[0]+radius*cos(0.),ADMISSIBLE_ERROR); //<< - CPPUNIT_ASSERT_DOUBLES_EQUAL(e1->getBounds()[2],center[1]+radius*sin(15*M_PI/8),ADMISSIBLE_ERROR); - CPPUNIT_ASSERT_DOUBLES_EQUAL(e1->getBounds()[3],center[1]+radius*sin(M_PI/4),ADMISSIBLE_ERROR); - e1->decrRef(); - // - // ArcCArcCIntersector - // - TypeOfLocInEdge where1,where2; - std::vector v4; - MergePoints v3; - EdgeArcCircle *e2; - ArcCArcCIntersector *intersector=0; - for(unsigned k=0;k<8;k++) - { - e1=buildArcOfCircle(center,radius,M_PI/4.+k*M_PI/4.,M_PI/3.+k*M_PI/4.); - e2=buildArcOfCircle(center,radius,M_PI/4.+k*M_PI/4.,M_PI/3.+k*M_PI/4.); - intersector=new ArcCArcCIntersector(*e1,*e2); - intersector->getPlacements(e2->getStartNode(),e2->getEndNode(),where1,where2,v3); - CPPUNIT_ASSERT(where1==START && where2==END); - delete intersector; v3.clear(); e2->decrRef(); - // - e2=buildArcOfCircle(center,radius,7*M_PI/24.+k*M_PI/4.,M_PI/3.+k*M_PI/4.); - intersector=new ArcCArcCIntersector(*e1,*e2); - intersector->getPlacements(e2->getStartNode(),e2->getEndNode(),where1,where2,v3); - CPPUNIT_ASSERT(where1==INSIDE && where2==END); - delete intersector; v3.clear(); e2->decrRef(); - // - e2=buildArcOfCircle(center,radius,M_PI/4.+k*M_PI/4.,7*M_PI/24.+k*M_PI/4.); - intersector=new ArcCArcCIntersector(*e1,*e2); - intersector->getPlacements(e2->getStartNode(),e2->getEndNode(),where1,where2,v3); - CPPUNIT_ASSERT(where1==START && where2==INSIDE); - delete intersector; v3.clear(); e2->decrRef(); - // - e2=buildArcOfCircle(center,radius,13.*M_PI/48.+k*M_PI/4.,15*M_PI/48.+k*M_PI/4.); - intersector=new ArcCArcCIntersector(*e1,*e2); - intersector->getPlacements(e2->getStartNode(),e2->getEndNode(),where1,where2,v3); - CPPUNIT_ASSERT(where1==INSIDE && where2==INSIDE); - delete intersector; v3.clear(); e2->decrRef(); - // - e2=buildArcOfCircle(center,radius,-M_PI/4.+k*M_PI/4.,M_PI/6.+k*M_PI/4.); - intersector=new ArcCArcCIntersector(*e1,*e2); - intersector->getPlacements(e2->getStartNode(),e2->getEndNode(),where1,where2,v3); - CPPUNIT_ASSERT(where1==OUT_BEFORE && where2==OUT_BEFORE); - delete intersector; v3.clear(); e2->decrRef(); - // - e2=buildArcOfCircle(center,radius,0+k*M_PI/4.,5*M_PI/6.+k*M_PI/4.); - intersector=new ArcCArcCIntersector(*e1,*e2); - intersector->getPlacements(e2->getStartNode(),e2->getEndNode(),where1,where2,v3); - CPPUNIT_ASSERT(where1==OUT_BEFORE && where2==OUT_AFTER); - delete intersector; v3.clear(); e2->decrRef(); - e1->decrRef(); - } - // Ok now let's see intersection only. 2 intersections R1 > R2 ; dist(circle1,circle2)>R1; Opposite order. - for(unsigned k=0;k<8;k++) - { - center[0]=0.; center[1]=0.; - double center2[2]; center2[0]=3.8*cos(k*M_PI/4.); center2[1]=3.8*sin(k*M_PI/4.); - e1=buildArcOfCircle(center,3.,(k-1)*M_PI/4.,(k+1)*M_PI/4.); - e2=buildArcOfCircle(center2,1.,M_PI+(k-1)*M_PI/4.,M_PI+(k+1)*M_PI/4.); - intersector=new ArcCArcCIntersector(*e1,*e2); - bool order; - bool obvious,areOverlapped; - intersector->areOverlappedOrOnlyColinears(0,obvious,areOverlapped); - CPPUNIT_ASSERT(!obvious && !areOverlapped); - CPPUNIT_ASSERT(intersector->intersect(0,v4,order,v3)); CPPUNIT_ASSERT(!order); - CPPUNIT_ASSERT_EQUAL(2,(int)v4.size()); CPPUNIT_ASSERT_EQUAL(0,(int)v3.getNumberOfAssociations()); - CPPUNIT_ASSERT_DOUBLES_EQUAL(e1->getRadius(),Node::distanceBtw2Pt(e1->getCenter(),(*(v4[0]))),ADMISSIBLE_ERROR); - CPPUNIT_ASSERT_DOUBLES_EQUAL(e2->getRadius(),Node::distanceBtw2Pt(e2->getCenter(),(*(v4[0]))),ADMISSIBLE_ERROR); - CPPUNIT_ASSERT_DOUBLES_EQUAL(e1->getRadius(),Node::distanceBtw2Pt(e1->getCenter(),(*(v4[1]))),ADMISSIBLE_ERROR); - CPPUNIT_ASSERT_DOUBLES_EQUAL(e2->getRadius(),Node::distanceBtw2Pt(e2->getCenter(),(*(v4[1]))),ADMISSIBLE_ERROR); - CPPUNIT_ASSERT(!v4[0]->isEqual(*v4[1])); - CPPUNIT_ASSERT_DOUBLES_EQUAL(btw2NodesAndACenter(*v4[0],*v4[1],e1->getCenter()),0.35587863972199624,1e-10); - for(std::vector::iterator iter=v4.begin();iter!=v4.end();iter++) - (*iter)->decrRef(); - v4.clear(); v3.clear(); - delete intersector; e2->decrRef(); e1->decrRef(); - } - // Ok now let's see intersection only. 2 intersections R1 > R2 ; dist(circle1,circle2)>R1; Same order. - for(unsigned k=0;k<7;k++) - { - center[0]=0.; center[1]=0.; - double center2[2]; center2[0]=3.8*cos(k*M_PI/4.); center2[1]=3.8*sin(k*M_PI/4.); - e1=buildArcOfCircle(center,3.,(k-1)*M_PI/4.,(k+1)*M_PI/4.); - e2=buildArcOfCircle(center2,1.,M_PI+(k+1)*M_PI/4.,M_PI+(k-1)*M_PI/4.); - intersector=new ArcCArcCIntersector(*e1,*e2); - bool order; - bool obvious,areOverlapped; - intersector->areOverlappedOrOnlyColinears(0,obvious,areOverlapped); - CPPUNIT_ASSERT(!obvious && !areOverlapped); - CPPUNIT_ASSERT(intersector->intersect(0,v4,order,v3)); CPPUNIT_ASSERT(order); - CPPUNIT_ASSERT_EQUAL(2,(int)v4.size()); CPPUNIT_ASSERT_EQUAL(0,(int)v3.getNumberOfAssociations()); - CPPUNIT_ASSERT_DOUBLES_EQUAL(e1->getRadius(),Node::distanceBtw2Pt(e1->getCenter(),(*(v4[0]))),ADMISSIBLE_ERROR); - CPPUNIT_ASSERT_DOUBLES_EQUAL(e2->getRadius(),Node::distanceBtw2Pt(e2->getCenter(),(*(v4[0]))),ADMISSIBLE_ERROR); - CPPUNIT_ASSERT_DOUBLES_EQUAL(e1->getRadius(),Node::distanceBtw2Pt(e1->getCenter(),(*(v4[1]))),ADMISSIBLE_ERROR); - CPPUNIT_ASSERT_DOUBLES_EQUAL(e2->getRadius(),Node::distanceBtw2Pt(e2->getCenter(),(*(v4[1]))),ADMISSIBLE_ERROR); - CPPUNIT_ASSERT(!v4[0]->isEqual(*v4[1])); - CPPUNIT_ASSERT_DOUBLES_EQUAL(btw2NodesAndACenter(*v4[0],*v4[1],e1->getCenter()),0.35587863972199624,1e-10); - for(std::vector::iterator iter=v4.begin();iter!=v4.end();iter++) - (*iter)->decrRef(); - v4.clear(); v3.clear(); - delete intersector; e2->decrRef(); e1->decrRef(); - } - // 2 intersections R1>R2 ; dist(circle1,circle2)areOverlappedOrOnlyColinears(0,obvious,areOverlapped); - CPPUNIT_ASSERT(!obvious && !areOverlapped); - CPPUNIT_ASSERT(intersector->intersect(0,v4,order,v3)); CPPUNIT_ASSERT(order); - CPPUNIT_ASSERT_EQUAL(2,(int)v4.size()); CPPUNIT_ASSERT_EQUAL(0,(int)v3.getNumberOfAssociations()); - CPPUNIT_ASSERT_DOUBLES_EQUAL(e1->getRadius(),Node::distanceBtw2Pt(e1->getCenter(),(*(v4[0]))),ADMISSIBLE_ERROR); - CPPUNIT_ASSERT_DOUBLES_EQUAL(e2->getRadius(),Node::distanceBtw2Pt(e2->getCenter(),(*(v4[0]))),ADMISSIBLE_ERROR); - CPPUNIT_ASSERT_DOUBLES_EQUAL(e1->getRadius(),Node::distanceBtw2Pt(e1->getCenter(),(*(v4[1]))),ADMISSIBLE_ERROR); - CPPUNIT_ASSERT_DOUBLES_EQUAL(e2->getRadius(),Node::distanceBtw2Pt(e2->getCenter(),(*(v4[1]))),ADMISSIBLE_ERROR); - CPPUNIT_ASSERT(!v4[0]->isEqual(*v4[1])); - CPPUNIT_ASSERT_DOUBLES_EQUAL(btw2NodesAndACenter(*v4[0],*v4[1],e1->getCenter()),0.6793851523346941,1e-10); - for(std::vector::iterator iter=v4.begin();iter!=v4.end();iter++) - (*iter)->decrRef(); - v4.clear(); v3.clear(); - delete intersector; e2->decrRef(); e1->decrRef(); - } - // 2 intersections R1>R2 ; dist(circle1,circle2)areOverlappedOrOnlyColinears(0,obvious,areOverlapped); - CPPUNIT_ASSERT(!obvious && !areOverlapped); - CPPUNIT_ASSERT(intersector->intersect(0,v4,order,v3)); CPPUNIT_ASSERT(!order); - CPPUNIT_ASSERT_EQUAL(2,(int)v4.size()); CPPUNIT_ASSERT_EQUAL(0,(int)v3.getNumberOfAssociations()); - CPPUNIT_ASSERT_DOUBLES_EQUAL(e1->getRadius(),Node::distanceBtw2Pt(e1->getCenter(),(*(v4[0]))),ADMISSIBLE_ERROR); - CPPUNIT_ASSERT_DOUBLES_EQUAL(e2->getRadius(),Node::distanceBtw2Pt(e2->getCenter(),(*(v4[0]))),ADMISSIBLE_ERROR); - CPPUNIT_ASSERT_DOUBLES_EQUAL(e1->getRadius(),Node::distanceBtw2Pt(e1->getCenter(),(*(v4[1]))),ADMISSIBLE_ERROR); - CPPUNIT_ASSERT_DOUBLES_EQUAL(e2->getRadius(),Node::distanceBtw2Pt(e2->getCenter(),(*(v4[1]))),ADMISSIBLE_ERROR); - CPPUNIT_ASSERT(!v4[0]->isEqual(*v4[1])); - CPPUNIT_ASSERT_DOUBLES_EQUAL(btw2NodesAndACenter(*v4[0],*v4[1],e1->getCenter()),0.6793851523346941,1e-10); - for(std::vector::iterator iter=v4.begin();iter!=v4.end();iter++) - (*iter)->decrRef(); - v4.clear(); v3.clear(); - delete intersector; e2->decrRef(); e1->decrRef(); - } - // Ok now let's see intersection only. 2 intersections R1 < R2 ; dist(circle1,circle2)>R2; Opposite order. - for(unsigned k=0;k<1;k++) - { - double center2[2]; center[0]=0.; center[1]=0.; - center2[0]=3.8*cos(k*M_PI/4.); center2[1]=3.8*sin(k*M_PI/4.); - e1=buildArcOfCircle(center,1.,(k-1)*M_PI/4.,(k+1)*M_PI/4.); - e2=buildArcOfCircle(center2,3.,M_PI+(k-1)*M_PI/4.,M_PI+(k+1)*M_PI/4.); - intersector=new ArcCArcCIntersector(*e1,*e2); - bool order; - bool obvious,areOverlapped; - intersector->areOverlappedOrOnlyColinears(0,obvious,areOverlapped); - CPPUNIT_ASSERT(!obvious && !areOverlapped); - CPPUNIT_ASSERT(intersector->intersect(0,v4,order,v3)); CPPUNIT_ASSERT(!order); - CPPUNIT_ASSERT_EQUAL(2,(int)v4.size()); CPPUNIT_ASSERT_EQUAL(0,(int)v3.getNumberOfAssociations()); - CPPUNIT_ASSERT_DOUBLES_EQUAL(e1->getRadius(),Node::distanceBtw2Pt(e1->getCenter(),(*(v4[0]))),ADMISSIBLE_ERROR); - CPPUNIT_ASSERT_DOUBLES_EQUAL(e2->getRadius(),Node::distanceBtw2Pt(e2->getCenter(),(*(v4[0]))),ADMISSIBLE_ERROR); - CPPUNIT_ASSERT_DOUBLES_EQUAL(e1->getRadius(),Node::distanceBtw2Pt(e1->getCenter(),(*(v4[1]))),ADMISSIBLE_ERROR); - CPPUNIT_ASSERT_DOUBLES_EQUAL(e2->getRadius(),Node::distanceBtw2Pt(e2->getCenter(),(*(v4[1]))),ADMISSIBLE_ERROR); - CPPUNIT_ASSERT(!v4[0]->isEqual(*v4[1])); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1.1195732971845034,btw2NodesAndACenter(*v4[0],*v4[1],e1->getCenter()),1e-10); - for(std::vector::iterator iter=v4.begin();iter!=v4.end();iter++) - (*iter)->decrRef(); - v4.clear(); v3.clear(); - delete intersector; e2->decrRef(); e1->decrRef(); - } - // Ok now let's see intersection only. 2 intersections R1 < R2 ; dist(circle1,circle2)>R2; same order. - for(unsigned k=0;k<8;k++) - { - double center2[2]; center[0]=0.; center[1]=0.; - center2[0]=3.8*cos(k*M_PI/4.); center2[1]=3.8*sin(k*M_PI/4.); - e1=buildArcOfCircle(center,1.,(k+1)*M_PI/4.,(k-1)*M_PI/4.); - e2=buildArcOfCircle(center2,3.,M_PI+(k-1)*M_PI/4.,M_PI+(k+1)*M_PI/4.); - intersector=new ArcCArcCIntersector(*e1,*e2); - bool order; - bool obvious,areOverlapped; - intersector->areOverlappedOrOnlyColinears(0,obvious,areOverlapped); - CPPUNIT_ASSERT(!obvious && !areOverlapped); - CPPUNIT_ASSERT(intersector->intersect(0,v4,order,v3)); CPPUNIT_ASSERT(order); - CPPUNIT_ASSERT_EQUAL(2,(int)v4.size()); CPPUNIT_ASSERT_EQUAL(0,(int)v3.getNumberOfAssociations()); - CPPUNIT_ASSERT_DOUBLES_EQUAL(e1->getRadius(),Node::distanceBtw2Pt(e1->getCenter(),(*(v4[0]))),ADMISSIBLE_ERROR); - CPPUNIT_ASSERT_DOUBLES_EQUAL(e2->getRadius(),Node::distanceBtw2Pt(e2->getCenter(),(*(v4[0]))),ADMISSIBLE_ERROR); - CPPUNIT_ASSERT_DOUBLES_EQUAL(e1->getRadius(),Node::distanceBtw2Pt(e1->getCenter(),(*(v4[1]))),ADMISSIBLE_ERROR); - CPPUNIT_ASSERT_DOUBLES_EQUAL(e2->getRadius(),Node::distanceBtw2Pt(e2->getCenter(),(*(v4[1]))),ADMISSIBLE_ERROR); - CPPUNIT_ASSERT(!v4[0]->isEqual(*v4[1])); - CPPUNIT_ASSERT_DOUBLES_EQUAL(-1.1195732971845034,btw2NodesAndACenter(*v4[0],*v4[1],e1->getCenter()),1e-10); - for(std::vector::iterator iter=v4.begin();iter!=v4.end();iter++) - (*iter)->decrRef(); - v4.clear(); v3.clear(); - delete intersector; e2->decrRef(); e1->decrRef(); - } - // Ok now let's see intersection only. 2 intersections R1 < R2 ; dist(circle1,circle2)areOverlappedOrOnlyColinears(0,obvious,areOverlapped); - CPPUNIT_ASSERT(!obvious && !areOverlapped); - CPPUNIT_ASSERT(intersector->intersect(0,v4,order,v3)); CPPUNIT_ASSERT(order); - CPPUNIT_ASSERT_EQUAL(2,(int)v4.size()); CPPUNIT_ASSERT_EQUAL(0,(int)v3.getNumberOfAssociations()); - CPPUNIT_ASSERT_DOUBLES_EQUAL(e1->getRadius(),Node::distanceBtw2Pt(e1->getCenter(),(*(v4[0]))),ADMISSIBLE_ERROR); - CPPUNIT_ASSERT_DOUBLES_EQUAL(e2->getRadius(),Node::distanceBtw2Pt(e2->getCenter(),(*(v4[0]))),ADMISSIBLE_ERROR); - CPPUNIT_ASSERT_DOUBLES_EQUAL(e1->getRadius(),Node::distanceBtw2Pt(e1->getCenter(),(*(v4[1]))),ADMISSIBLE_ERROR); - CPPUNIT_ASSERT_DOUBLES_EQUAL(e2->getRadius(),Node::distanceBtw2Pt(e2->getCenter(),(*(v4[1]))),ADMISSIBLE_ERROR); - CPPUNIT_ASSERT(!v4[0]->isEqual(*v4[1])); - CPPUNIT_ASSERT_DOUBLES_EQUAL(-3.0844420190512074,btw2NodesAndACenter(*v4[0],*v4[1],e1->getCenter()),1e-10); - for(std::vector::iterator iter=v4.begin();iter!=v4.end();iter++) - (*iter)->decrRef(); - v4.clear(); v3.clear(); - delete intersector; e2->decrRef(); e1->decrRef(); - } - // Ok now let's see intersection only. 2 intersections R1 < R2 ; dist(circle1,circle2)areOverlappedOrOnlyColinears(0,obvious,areOverlapped); - CPPUNIT_ASSERT(!obvious && !areOverlapped); - CPPUNIT_ASSERT(intersector->intersect(0,v4,order,v3)); CPPUNIT_ASSERT(!order); - CPPUNIT_ASSERT_EQUAL(2,(int)v4.size()); CPPUNIT_ASSERT_EQUAL(0,(int)v3.getNumberOfAssociations()); - CPPUNIT_ASSERT_DOUBLES_EQUAL(e1->getRadius(),Node::distanceBtw2Pt(e1->getCenter(),(*(v4[0]))),ADMISSIBLE_ERROR); - CPPUNIT_ASSERT_DOUBLES_EQUAL(e2->getRadius(),Node::distanceBtw2Pt(e2->getCenter(),(*(v4[0]))),ADMISSIBLE_ERROR); - CPPUNIT_ASSERT_DOUBLES_EQUAL(e1->getRadius(),Node::distanceBtw2Pt(e1->getCenter(),(*(v4[1]))),ADMISSIBLE_ERROR); - CPPUNIT_ASSERT_DOUBLES_EQUAL(e2->getRadius(),Node::distanceBtw2Pt(e2->getCenter(),(*(v4[1]))),ADMISSIBLE_ERROR); - CPPUNIT_ASSERT(!v4[0]->isEqual(*v4[1])); - CPPUNIT_ASSERT_DOUBLES_EQUAL(-3.0844420190512074,btw2NodesAndACenter(*v4[0],*v4[1],e1->getCenter()),1e-10); - for(std::vector::iterator iter=v4.begin();iter!=v4.end();iter++) - (*iter)->decrRef(); - v4.clear(); v3.clear(); - delete intersector; e2->decrRef(); e1->decrRef(); - } - // Tangent intersection - QUADRATIC_PLANAR::setPrecision(1e-5); - for(unsigned k=0;k<8;k++) - { - double center2[2]; center[0]=0.; center[1]=0.; - center2[0]=4.*cos(k*M_PI/4.); center2[1]=4.*sin(k*M_PI/4.); - e1=buildArcOfCircle(center,1.,(k+1)*M_PI/4.,(k-1)*M_PI/4.); - e2=buildArcOfCircle(center2,3.,M_PI+(k-1)*M_PI/4.,M_PI+(k+1)*M_PI/4.); - intersector=new ArcCArcCIntersector(*e1,*e2); - bool order; - bool obvious,areOverlapped; - intersector->areOverlappedOrOnlyColinears(0,obvious,areOverlapped); - CPPUNIT_ASSERT(!obvious && !areOverlapped); - CPPUNIT_ASSERT(intersector->intersect(0,v4,order,v3)); CPPUNIT_ASSERT(order); // order has no sence here because v4.size() expected to 1 but for valgrind serenity test. - CPPUNIT_ASSERT_EQUAL(1,(int)v4.size()); CPPUNIT_ASSERT_EQUAL(0,(int)v3.getNumberOfAssociations()); - CPPUNIT_ASSERT_DOUBLES_EQUAL(e1->getRadius(),Node::distanceBtw2Pt(e1->getCenter(),(*(v4[0]))),ADMISSIBLE_ERROR); - CPPUNIT_ASSERT_DOUBLES_EQUAL(e2->getRadius(),Node::distanceBtw2Pt(e2->getCenter(),(*(v4[0]))),ADMISSIBLE_ERROR); - for(std::vector::iterator iter=v4.begin();iter!=v4.end();iter++) - (*iter)->decrRef(); - v4.clear(); v4.clear(); - delete intersector; e2->decrRef(); e1->decrRef(); - } - QUADRATIC_PLANAR::setPrecision(1e-14); - // Extremities # 1 - for(unsigned k=0;k<8;k++) - { - center[0]=0.; center[1]=0.; - double center2[2]; center2[0]=3.8*cos(k*M_PI/4.); center2[1]=3.8*sin(k*M_PI/4.); - e1=buildArcOfCircle(center,3.,k*M_PI/4.-0.17793931986099812,k*M_PI/4.+0.17793931986099812); - e2=buildArcOfCircle(center2,1.,M_PI+k*M_PI/4.-0.55978664859225125,M_PI+k*M_PI/4.+0.55978664859225125); - intersector=new ArcCArcCIntersector(*e1,*e2); - bool order; - bool obvious,areOverlapped; - intersector->areOverlappedOrOnlyColinears(0,obvious,areOverlapped); - CPPUNIT_ASSERT(!obvious && !areOverlapped); - CPPUNIT_ASSERT(!intersector->intersect(0,v4,order,v3)); CPPUNIT_ASSERT_EQUAL(0,(int)v4.size()); CPPUNIT_ASSERT_EQUAL(2,(int)v3.getNumberOfAssociations()); - CPPUNIT_ASSERT(e1->getStartNode()==e2->getEndNode()); CPPUNIT_ASSERT(e2->getStartNode()==e1->getEndNode()); - v4.clear(); v3.clear(); - delete intersector; e2->decrRef(); e1->decrRef(); - } - for(unsigned k=0;k<8;k++) - { - center[0]=0.; center[1]=0.; - double center2[2]; center2[0]=3.8*cos(k*M_PI/4.); center2[1]=3.8*sin(k*M_PI/4.); - e1=buildArcOfCircle(center,3.,k*M_PI/4.-0.17793931986099812,k*M_PI/4.+0.17793931986099812); - e2=buildArcOfCircle(center2,1.,M_PI+k*M_PI/4.+0.55978664859225125,M_PI+k*M_PI/4.-0.55978664859225125); - intersector=new ArcCArcCIntersector(*e1,*e2); - bool order; - bool obvious,areOverlapped; - intersector->areOverlappedOrOnlyColinears(0,obvious,areOverlapped); - CPPUNIT_ASSERT(!obvious && !areOverlapped); - CPPUNIT_ASSERT(!intersector->intersect(0,v4,order,v3)); CPPUNIT_ASSERT_EQUAL(0,(int)v4.size()); CPPUNIT_ASSERT_EQUAL(2,(int)v3.getNumberOfAssociations()); - CPPUNIT_ASSERT(e1->getStartNode()==e2->getStartNode()); CPPUNIT_ASSERT(e2->getEndNode()==e1->getEndNode()); - v4.clear(); v3.clear(); - delete intersector; e2->decrRef(); e1->decrRef(); - } - // Extremities # 2 - for(unsigned k=0;k<8;k++) - { - center[0]=0.; center[1]=0.; - double center2[2]; center2[0]=3.8*cos(k*M_PI/4.); center2[1]=3.8*sin(k*M_PI/4.); - e1=buildArcOfCircle(center,3.,k*M_PI/4.-0.17793931986099812,k*M_PI/4.+0.17793931986099812); - e2=buildArcOfCircle(center2,1.,M_PI+k*M_PI/4.+0.55978664859225125,M_PI+k*M_PI/4.-0.7); - intersector=new ArcCArcCIntersector(*e1,*e2); - bool order; - bool obvious,areOverlapped; - intersector->areOverlappedOrOnlyColinears(0,obvious,areOverlapped); - CPPUNIT_ASSERT(!obvious && !areOverlapped); - CPPUNIT_ASSERT(intersector->intersect(0,v4,order,v3)); - CPPUNIT_ASSERT(order); CPPUNIT_ASSERT_EQUAL(1,(int)v4.size()); CPPUNIT_ASSERT_EQUAL(1,(int)v3.getNumberOfAssociations()); - CPPUNIT_ASSERT(e1->getStartNode()==e2->getStartNode()); CPPUNIT_ASSERT(e1->getEndNode()==v4[0]); - v4[0]->decrRef(); - v4.clear(); v3.clear(); - delete intersector; e2->decrRef(); e1->decrRef(); - } - // Extremities # 3 - for(unsigned k=0;k<8;k++) - { - center[0]=0.; center[1]=0.; - double center2[2]; center2[0]=3.8*cos(k*M_PI/4.); center2[1]=3.8*sin(k*M_PI/4.); - e1=buildArcOfCircle(center,3.,k*M_PI/4.-0.17793931986099812,k*M_PI/4.+0.17793931986099812); - e2=buildArcOfCircle(center2,1.,M_PI+k*M_PI/4.+0.7,M_PI+k*M_PI/4.-0.7); - intersector=new ArcCArcCIntersector(*e1,*e2); - bool order; - bool obvious,areOverlapped; - intersector->areOverlappedOrOnlyColinears(0,obvious,areOverlapped); - CPPUNIT_ASSERT(!obvious && !areOverlapped); - CPPUNIT_ASSERT(intersector->intersect(0,v4,order,v3)); CPPUNIT_ASSERT(order); CPPUNIT_ASSERT_EQUAL(2,(int)v4.size()); CPPUNIT_ASSERT_EQUAL(0,(int)v3.getNumberOfAssociations()); - CPPUNIT_ASSERT(e1->getStartNode()==v4[0]); CPPUNIT_ASSERT(e1->getEndNode()==v4[1]); - v4[0]->decrRef(); v4[1]->decrRef(); - v4.clear(); v3.clear(); - delete intersector; e2->decrRef(); e1->decrRef(); - } - // Extremities # 4 - for(unsigned k=0;k<8;k++) - { - center[0]=0.; center[1]=0.; - double center2[2]; center2[0]=3.8*cos(k*M_PI/4.); center2[1]=3.8*sin(k*M_PI/4.); - Node *nodeS=new Node(center[0]+3.*cos(k*M_PI/4.-0.17793931986099812),center[1]+3.*sin(k*M_PI/4.-0.17793931986099812)); - Node *nodeE=new Node(center[0]+3.*cos(k*M_PI/4.),center[1]+3.*sin(k*M_PI/4.)); - double angle=k*M_PI/4.-0.17793931986099812; - angle=angle>M_PI?angle-2.*M_PI:angle; - e1=new EdgeArcCircle(nodeS,nodeE,//Problem of precision 1e-14 to easily reached. - center,3.,angle,0.17793931986099812); - nodeS->decrRef(); nodeE->decrRef(); - e2=buildArcOfCircle(center2,1.,M_PI+k*M_PI/4.+0.7,M_PI+k*M_PI/4.-0.7); - intersector=new ArcCArcCIntersector(*e1,*e2); - bool order; - bool obvious,areOverlapped; - intersector->areOverlappedOrOnlyColinears(0,obvious,areOverlapped); - CPPUNIT_ASSERT(!obvious && !areOverlapped); - CPPUNIT_ASSERT(intersector->intersect(0,v4,order,v3)); CPPUNIT_ASSERT(order); CPPUNIT_ASSERT_EQUAL(1,(int)v4.size()); CPPUNIT_ASSERT_EQUAL(0,(int)v3.getNumberOfAssociations()); - CPPUNIT_ASSERT(e1->getStartNode()==v4[0]); - v4[0]->decrRef(); - v4.clear(); v3.clear(); - delete intersector; e2->decrRef(); e1->decrRef(); - } - //Extremities # 5 - for(unsigned k=0;k<8;k++) - { - center[0]=0.; center[1]=0.; - double center2[2]; center2[0]=3.8*cos(k*M_PI/4.); center2[1]=3.8*sin(k*M_PI/4.); - Node *nodeS=new Node(center[0]+3.*cos(k*M_PI/4.-0.17793931986099812),center[1]+3.*sin(k*M_PI/4.-0.17793931986099812)); - Node *nodeE=new Node(center[0]+3.*cos(k*M_PI/4.)+0.5,center[1]+3.*sin(k*M_PI/4.)); - double angle=k*M_PI/4.-0.17793931986099812; - angle=angle>M_PI?angle-2.*M_PI:angle; - e1=new EdgeArcCircle(nodeS,nodeE,//Problem of precision 1e-14 to easily reached. - center,3.,angle,0.67793931986099812); - nodeS->decrRef(); nodeE->decrRef(); - e2=buildArcOfCircle(center2,1.,M_PI+k*M_PI/4.+0.7,M_PI+k*M_PI/4.-0.7); - intersector=new ArcCArcCIntersector(*e1,*e2); - bool order; - bool obvious,areOverlapped; - intersector->areOverlappedOrOnlyColinears(0,obvious,areOverlapped); - CPPUNIT_ASSERT(!obvious && !areOverlapped); - CPPUNIT_ASSERT(intersector->intersect(0,v4,order,v3)); CPPUNIT_ASSERT(order); CPPUNIT_ASSERT_EQUAL(2,(int)v4.size()); CPPUNIT_ASSERT_EQUAL(0,(int)v3.getNumberOfAssociations()); - CPPUNIT_ASSERT(e1->getStartNode()==v4[0]); - v4[0]->decrRef(); v4[1]->decrRef(); - v4.clear(); v3.clear(); - delete intersector; e2->decrRef(); e1->decrRef(); - } -} - -void QuadraticPlanarInterpTest::IntersectArcCircleFull() -{ - double center1[2]; center1[0]=0.; center1[1]=0.; double radius1=3.; - double center2[2]; center2[0]=0.75; center2[1]=-2.6; double radius2=1.; - EdgeArcCircle *e1=buildArcOfCircle(center1,radius1,-M_PI/3.,4.*M_PI/3.); - EdgeArcCircle *e2=buildArcOfCircle(center2,radius2,0.,M_PI/2.); - MergePoints commonNode; - QuadraticPolygon pol1; QuadraticPolygon pol2; - QuadraticPolygon pol3; QuadraticPolygon pol4; - pol3.pushBack(e1); pol4.pushBack(e2); - CPPUNIT_ASSERT_DOUBLES_EQUAL(15.707963267948966,pol3.getPerimeter(),1e-6); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1.5707963267949,pol4.getPerimeter(),1e-6); - CPPUNIT_ASSERT_DOUBLES_EQUAL(19.6648305849,pol3.getArea(),1e-6); - CPPUNIT_ASSERT_DOUBLES_EQUAL(-1.8146018366,pol4.getArea(),1e-6); - CPPUNIT_ASSERT(e1->intersectWith(e2,commonNode,pol1,pol2)); - CPPUNIT_ASSERT_EQUAL(2,pol1.size()); - CPPUNIT_ASSERT_EQUAL(2,pol2.size()); - CPPUNIT_ASSERT_DOUBLES_EQUAL(19.6648305849,pol1.getArea(),1e-6); - CPPUNIT_ASSERT_DOUBLES_EQUAL(-1.8146018366,pol2.getArea(),1e-6); - CPPUNIT_ASSERT_DOUBLES_EQUAL(15.707963267948966,pol1.getPerimeter(),1e-6); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1.5707963267949,pol2.getPerimeter(),1e-6); - // - e1=buildArcOfCircle(center1,radius1,-2*M_PI/3.,-7.*M_PI/3.); - e2=buildArcOfCircle(center2,radius2,0.,M_PI/2.); - commonNode.clear(); - QuadraticPolygon pol5; QuadraticPolygon pol6; - QuadraticPolygon pol7; QuadraticPolygon pol8; - pol7.pushBack(e1); pol8.pushBack(e2); - CPPUNIT_ASSERT_DOUBLES_EQUAL(15.707963267948966,pol7.getPerimeter(),1e-6); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1.5707963267949,pol8.getPerimeter(),1e-6); - CPPUNIT_ASSERT_DOUBLES_EQUAL(-19.6648305849,pol7.getArea(),1e-6); - CPPUNIT_ASSERT_DOUBLES_EQUAL(-1.8146018366,pol8.getArea(),1e-6); - CPPUNIT_ASSERT(e1->intersectWith(e2,commonNode,pol5,pol6)); - CPPUNIT_ASSERT_EQUAL(2,pol5.size()); - CPPUNIT_ASSERT_EQUAL(2,pol6.size()); - CPPUNIT_ASSERT_DOUBLES_EQUAL(-19.6648305849,pol5.getArea(),1e-6); - CPPUNIT_ASSERT_DOUBLES_EQUAL(-1.8146018366,pol6.getArea(),1e-6); - CPPUNIT_ASSERT_DOUBLES_EQUAL(15.707963267948966,pol5.getPerimeter(),1e-6); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1.5707963267949,pol6.getPerimeter(),1e-6); - // - center2[0]=3.5; center2[1]=0.; - e1=buildArcOfCircle(center1,radius1,-2*M_PI/3.,-7.*M_PI/3.); - e2=buildArcOfCircle(center2,radius2,M_PI/2.,3*M_PI/2.); - commonNode.clear(); - QuadraticPolygon pol9; QuadraticPolygon pol10; - QuadraticPolygon pol11; QuadraticPolygon pol12; - pol11.pushBack(e1); pol12.pushBack(e2); - CPPUNIT_ASSERT_DOUBLES_EQUAL(15.707963267948966,pol11.getPerimeter(),1e-6); - CPPUNIT_ASSERT_DOUBLES_EQUAL(3.1415926535897931,pol12.getPerimeter(),1e-6); - CPPUNIT_ASSERT_DOUBLES_EQUAL(-19.6648305849,pol11.getArea(),1e-6); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1.5707963267949,pol12.getArea(),1e-6); - CPPUNIT_ASSERT(e1->intersectWith(e2,commonNode,pol9,pol10)); - CPPUNIT_ASSERT_EQUAL(3,pol9.size()); - CPPUNIT_ASSERT_EQUAL(3,pol10.size()); - CPPUNIT_ASSERT_DOUBLES_EQUAL(15.707963267948966,pol9.getPerimeter(),1e-6); - CPPUNIT_ASSERT_DOUBLES_EQUAL(3.1415926535897931,pol10.getPerimeter(),1e-6); - CPPUNIT_ASSERT_DOUBLES_EQUAL(-19.6648305849,pol9.getArea(),1e-6); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1.5707963267949,pol10.getArea(),1e-6); - // - center2[0]=0.; center2[1]=0.; radius2=radius1; - e1=buildArcOfCircle(center1,radius1,-2*M_PI/3.,-7.*M_PI/3.); - e2=buildArcOfCircle(center2,radius2,M_PI/3.,2*M_PI/3.); - commonNode.clear(); - QuadraticPolygon pol13; QuadraticPolygon pol14; - QuadraticPolygon pol15; QuadraticPolygon pol16; - pol15.pushBack(e1); pol16.pushBack(e2); - CPPUNIT_ASSERT_DOUBLES_EQUAL(15.707963267948966,pol15.getPerimeter(),1e-6); - CPPUNIT_ASSERT_DOUBLES_EQUAL(3.1415926535897931,pol16.getPerimeter(),1e-6); - CPPUNIT_ASSERT_DOUBLES_EQUAL(-19.6648305849,pol15.getArea(),1e-6); - CPPUNIT_ASSERT_DOUBLES_EQUAL(8.6095032974147,pol16.getArea(),1e-6); - CPPUNIT_ASSERT(e1->intersectWith(e2,commonNode,pol13,pol14)); - CPPUNIT_ASSERT_EQUAL(3,pol13.size()); - CPPUNIT_ASSERT_EQUAL(1,pol14.size()); - CPPUNIT_ASSERT_DOUBLES_EQUAL(15.707963267948966,pol13.getPerimeter(),1e-6); - CPPUNIT_ASSERT_DOUBLES_EQUAL(-19.6648305849,pol13.getArea(),1e-6); - CPPUNIT_ASSERT_DOUBLES_EQUAL(3.1415926535897931,pol14.getPerimeter(),1e-6); - CPPUNIT_ASSERT_DOUBLES_EQUAL(8.6095032974147,pol14.getArea(),1e-6); - // - e1=buildArcOfCircle(center1,radius1,-2*M_PI/3.,-7.*M_PI/3.); - e2=buildArcOfCircle(center2,radius2,2*M_PI/3.,M_PI/3.); - commonNode.clear(); - QuadraticPolygon pol17; QuadraticPolygon pol18; - QuadraticPolygon pol19; QuadraticPolygon pol20; - pol19.pushBack(e1); pol20.pushBack(e2); - CPPUNIT_ASSERT_DOUBLES_EQUAL(15.707963267948966,pol19.getPerimeter(),1e-6); - CPPUNIT_ASSERT_DOUBLES_EQUAL(3.1415926535897931,pol20.getPerimeter(),1e-6); - CPPUNIT_ASSERT_DOUBLES_EQUAL(-19.6648305849,pol19.getArea(),1e-6); - CPPUNIT_ASSERT_DOUBLES_EQUAL(-8.6095032974147,pol20.getArea(),1e-6); - CPPUNIT_ASSERT(e1->intersectWith(e2,commonNode,pol17,pol18)); - CPPUNIT_ASSERT_EQUAL(3,pol17.size()); - CPPUNIT_ASSERT_EQUAL(1,pol18.size()); - CPPUNIT_ASSERT_DOUBLES_EQUAL(15.707963267948966,pol17.getPerimeter(),1e-6); - CPPUNIT_ASSERT_DOUBLES_EQUAL(-19.6648305849,pol17.getArea(),1e-6); - CPPUNIT_ASSERT_DOUBLES_EQUAL(3.1415926535897931,pol18.getPerimeter(),1e-6); - CPPUNIT_ASSERT_DOUBLES_EQUAL(-8.6095032974147,pol18.getArea(),1e-6); - //no intersection #1 - center2[0]=4.277; center2[1]=-4.277; - e1=buildArcOfCircle(center1,radius1,-2*M_PI/3.,-7.*M_PI/3.); - e2=buildArcOfCircle(center2,radius2,M_PI/4.,5*M_PI/4.); - QuadraticPolygon polTemp1; QuadraticPolygon polTemp2; - CPPUNIT_ASSERT(!e1->intersectWith(e2,commonNode,polTemp1,polTemp2)); - e1->decrRef(); e2->decrRef(); - //no intersection #2 - center2[0]=1.; center2[1]=-1.; radius2=0.2; - e1=buildArcOfCircle(center1,radius1,-2*M_PI/3.,-7.*M_PI/3.); - e2=buildArcOfCircle(center2,radius2,M_PI/4.,5*M_PI/4.); - CPPUNIT_ASSERT(!e1->intersectWith(e2,commonNode,polTemp1,polTemp2)); - e1->decrRef(); e2->decrRef(); -} - -void QuadraticPlanarInterpTest::IntersectArcCircleSegumentBase() -{ - double center[2]={2.,2.}; - EdgeArcCircle *e1=buildArcOfCircle(center,2.3,M_PI/4.,5.*M_PI/4.); - EdgeLin *e2=new EdgeLin(-1.3,1.,3.,5.3); - EdgeIntersector *intersector=new ArcCSegIntersector(*e1,*e2); - bool order; - bool obvious,areOverlapped; - intersector->areOverlappedOrOnlyColinears(0,obvious,areOverlapped); - CPPUNIT_ASSERT(!obvious && !areOverlapped); - std::vector v4; - MergePoints v3; - CPPUNIT_ASSERT(intersector->intersect(0,v4,order,v3)); CPPUNIT_ASSERT(!order); CPPUNIT_ASSERT_EQUAL(2,(int)v4.size()); CPPUNIT_ASSERT_EQUAL(0,(int)v3.getNumberOfAssociations()); - CPPUNIT_ASSERT_DOUBLES_EQUAL(2.,(*v4[0])[0],1e-10); CPPUNIT_ASSERT_DOUBLES_EQUAL(4.3,(*v4[0])[1],1e-10); - CPPUNIT_ASSERT_DOUBLES_EQUAL(-0.3,(*v4[1])[0],1e-10); CPPUNIT_ASSERT_DOUBLES_EQUAL(2.,(*v4[1])[1],1e-10); - v4[0]->decrRef(); v4[1]->decrRef(); e2->decrRef(); v3.clear(); v4.clear(); delete intersector; - // - e2=new EdgeLin(3.,5.3,-1.3,1.); - intersector=new ArcCSegIntersector(*e1,*e2); - intersector->areOverlappedOrOnlyColinears(0,obvious,areOverlapped); CPPUNIT_ASSERT(!obvious && !areOverlapped); - CPPUNIT_ASSERT(intersector->intersect(0,v4,order,v3)); CPPUNIT_ASSERT(order); CPPUNIT_ASSERT_EQUAL(2,(int)v4.size()); CPPUNIT_ASSERT_EQUAL(0,(int)v3.getNumberOfAssociations()); - CPPUNIT_ASSERT_DOUBLES_EQUAL(2.,(*v4[0])[0],1e-10); CPPUNIT_ASSERT_DOUBLES_EQUAL(4.3,(*v4[0])[1],1e-10); - CPPUNIT_ASSERT_DOUBLES_EQUAL(-0.3,(*v4[1])[0],1e-10); CPPUNIT_ASSERT_DOUBLES_EQUAL(2.,(*v4[1])[1],1e-10); - v4[0]->decrRef(); v4[1]->decrRef(); e2->decrRef(); v3.clear(); v4.clear(); delete intersector; - // tangent intersection - e2=new EdgeLin(-1.,4.3,3.,4.3); - intersector=new ArcCSegIntersector(*e1,*e2); - intersector->areOverlappedOrOnlyColinears(0,obvious,areOverlapped); CPPUNIT_ASSERT(!obvious && !areOverlapped); - CPPUNIT_ASSERT(intersector->intersect(0,v4,order,v3)); CPPUNIT_ASSERT(order); CPPUNIT_ASSERT_EQUAL(1,(int)v4.size()); CPPUNIT_ASSERT_EQUAL(0,(int)v3.getNumberOfAssociations()); - CPPUNIT_ASSERT_DOUBLES_EQUAL(2.,(*v4[0])[0],1e-10); CPPUNIT_ASSERT_DOUBLES_EQUAL(4.3,(*v4[0])[1],1e-10); - v4[0]->decrRef(); e2->decrRef(); v3.clear(); delete intersector; - // no intersection - e2=new EdgeLin(-2.,-2.,-1.,-3.); - intersector=new ArcCSegIntersector(*e1,*e2); - intersector->areOverlappedOrOnlyColinears(0,obvious,areOverlapped); CPPUNIT_ASSERT(obvious && !areOverlapped); - e2->decrRef(); v3.clear(); delete intersector; - // - e1->decrRef(); -} - -QuadraticPolygon *QuadraticPlanarInterpTest::buildQuadraticPolygonCoarseInfo(const double *coords, const int *conn, int lgth) -{ - std::vector nodes; - for(int i=0;i -#include -#include - -using namespace INTERP_KERNEL; - -namespace INTERP_TEST -{ - -void QuadraticPlanarInterpTest::checkInOutDetection() -{ - Node *n1=new Node(0.,0.); - Node *n2=new Node(1.,0.); - Node *n3=new Node(0.5,1.); - EdgeLin *e1=new EdgeLin(n1,n2); - EdgeLin *e2=new EdgeLin(n2,n3); - EdgeLin *e3=new EdgeLin(n3,n1); - ComposedEdge *tri=new ComposedEdge; - tri->pushBack(e1); tri->pushBack(e2); tri->pushBack(e3); - // - Node *where=new Node(0.4,0.1); - CPPUNIT_ASSERT(tri->isInOrOut(where)); where->decrRef(); - where=new Node(-0.1,1.); - CPPUNIT_ASSERT(!tri->isInOrOut(where)); where->decrRef(); - where=new Node(0.6,-0.1); - CPPUNIT_ASSERT(!tri->isInOrOut(where)); where->decrRef(); - //Clean-up - n1->decrRef(); n2->decrRef(); n3->decrRef(); - ComposedEdge::Delete(tri); -} - -/*! - * Check Iterators mechanism. - */ -void QuadraticPlanarInterpTest::checkAssemblingBases1() -{ - Node *n1=new Node(0.,0.); - Node *n2=new Node(0.1,0.); EdgeLin *e1_2=new EdgeLin(n1,n2); - Node *n3=new Node(0.2,0.); EdgeLin *e2_3=new EdgeLin(n2,n3); - Node *n4=new Node(0.3,0.); EdgeLin *e3_4=new EdgeLin(n3,n4); - Node *n5=new Node(0.4,0.); EdgeLin *e4_5=new EdgeLin(n4,n5); - Node *n6=new Node(0.5,0.); EdgeLin *e5_6=new EdgeLin(n5,n6); - Node *n7=new Node(0.6,0.); EdgeLin *e6_7=new EdgeLin(n6,n7); - Node *n8=new Node(0.7,0.); EdgeLin *e7_8=new EdgeLin(n7,n8); - Node *n9=new Node(0.8,0.); EdgeLin *e8_9=new EdgeLin(n8,n9); - Node *n10=new Node(0.9,0.); EdgeLin *e9_10=new EdgeLin(n9,n10); - Node *n11=new Node(1.,0.); EdgeLin *e10_11=new EdgeLin(n10,n11); - Node *n12=new Node(0.5,1.); EdgeLin *e11_12=new EdgeLin(n11,n12); - EdgeLin *e12_1=new EdgeLin(n12,n1); - //Only one level - e1_2->incrRef(); e2_3->incrRef(); e3_4->incrRef(); e4_5->incrRef(); e5_6->incrRef(); e6_7->incrRef(); - e7_8->incrRef(); e8_9->incrRef(); e9_10->incrRef(); e10_11->incrRef(); e11_12->incrRef(); e12_1->incrRef(); - ComposedEdge *c=new ComposedEdge; - c->pushBack(e1_2); c->pushBack(e2_3); c->pushBack(e3_4); c->pushBack(e4_5); c->pushBack(e5_6); c->pushBack(e6_7); - c->pushBack(e7_8); c->pushBack(e8_9); c->pushBack(e9_10); c->pushBack(e10_11); c->pushBack(e11_12); c->pushBack(e12_1); - CPPUNIT_ASSERT_EQUAL(12,c->recursiveSize()); - IteratorOnComposedEdge it(c); - CPPUNIT_ASSERT(it.current()->getPtr()==e1_2); CPPUNIT_ASSERT(!it.finished()); - it.next(); CPPUNIT_ASSERT(it.current()->getPtr()==e2_3); CPPUNIT_ASSERT(!it.finished()); - it.next(); it.next(); CPPUNIT_ASSERT(it.current()->getPtr()==e4_5); CPPUNIT_ASSERT(!it.finished()); - it.previousLoop(); CPPUNIT_ASSERT(it.current()->getPtr()==e3_4); CPPUNIT_ASSERT(!it.finished()); - it.previousLoop(); CPPUNIT_ASSERT(it.current()->getPtr()==e2_3); CPPUNIT_ASSERT(!it.finished()); - it.previousLoop(); CPPUNIT_ASSERT(it.current()->getPtr()==e1_2); CPPUNIT_ASSERT(!it.finished()); - it.previousLoop(); CPPUNIT_ASSERT(it.current()->getPtr()==e12_1); CPPUNIT_ASSERT(!it.finished()); - it.next(); CPPUNIT_ASSERT(it.finished()); - it.first(); CPPUNIT_ASSERT(it.current()->getPtr()==e1_2); CPPUNIT_ASSERT(!it.finished()); - it.previousLoop(); CPPUNIT_ASSERT(it.current()->getPtr()==e12_1); CPPUNIT_ASSERT(!it.finished()); - it.nextLoop(); CPPUNIT_ASSERT(it.current()->getPtr()==e1_2); CPPUNIT_ASSERT(!it.finished()); - it.last(); CPPUNIT_ASSERT(it.current()->getPtr()==e12_1); CPPUNIT_ASSERT(!it.finished()); - //Multi-Level - ComposedEdge::Delete(c); - //(e1_2, (e2_3,(e3_4, e4_5, e5_6, e6_7, (e7_8, e8_9 ), ( e9_10 , e10_11 ), e11_12 ),e12_1 ) ) - e1_2->incrRef(); e2_3->incrRef(); e3_4->incrRef(); e4_5->incrRef(); e5_6->incrRef(); e6_7->incrRef(); - e7_8->incrRef(); e8_9->incrRef(); e9_10->incrRef(); e10_11->incrRef(); e11_12->incrRef(); e12_1->incrRef(); - ComposedEdge *c2_2_4=new ComposedEdge; c2_2_4->pushBack(e7_8); c2_2_4->pushBack(e8_9); - ComposedEdge *c2_2_5=new ComposedEdge; c2_2_5->pushBack(e9_10); c2_2_5->pushBack(e10_11); - ComposedEdge *c2_2=new ComposedEdge; c2_2->pushBack(e3_4); c2_2->pushBack(e4_5); c2_2->pushBack(e5_6); c2_2->pushBack(e6_7); c2_2->pushBack(c2_2_4); c2_2->pushBack(c2_2_5); c2_2->pushBack(e11_12); - ComposedEdge *c2=new ComposedEdge; c2->pushBack(e2_3); c2->pushBack(c2_2); c2->pushBack(e12_1); - c=new ComposedEdge; c->pushBack(e1_2); c->pushBack(c2); CPPUNIT_ASSERT_EQUAL(12,c->recursiveSize()); - IteratorOnComposedEdge it2(c); - CPPUNIT_ASSERT(it2.current()->getPtr()==e1_2); - it2.next(); CPPUNIT_ASSERT(it2.current()->getPtr()==e2_3); CPPUNIT_ASSERT(!it2.finished()); - it2.next(); CPPUNIT_ASSERT(it2.current()->getPtr()==e3_4); CPPUNIT_ASSERT(!it2.finished()); - it2.next(); CPPUNIT_ASSERT(it2.current()->getPtr()==e4_5); CPPUNIT_ASSERT(!it2.finished()); - it2.previousLoop(); CPPUNIT_ASSERT(it2.current()->getPtr()==e3_4); CPPUNIT_ASSERT(!it2.finished()); - it2.previousLoop(); CPPUNIT_ASSERT(it2.current()->getPtr()==e2_3); CPPUNIT_ASSERT(!it2.finished()); - it2.previousLoop(); CPPUNIT_ASSERT(it2.current()->getPtr()==e1_2); CPPUNIT_ASSERT(!it2.finished()); - it2.previousLoop(); CPPUNIT_ASSERT(it2.current()->getPtr()==e12_1); CPPUNIT_ASSERT(!it2.finished()); - it2.next(); CPPUNIT_ASSERT(it2.finished()); - it2.first(); CPPUNIT_ASSERT(it2.current()->getPtr()==e1_2); CPPUNIT_ASSERT(!it2.finished()); - it2.previousLoop(); CPPUNIT_ASSERT(it2.current()->getPtr()==e12_1); CPPUNIT_ASSERT(!it2.finished()); - it2.nextLoop(); CPPUNIT_ASSERT(it2.current()->getPtr()==e1_2); CPPUNIT_ASSERT(!it2.finished()); - it2.last(); CPPUNIT_ASSERT(it2.current()->getPtr()==e12_1); CPPUNIT_ASSERT(!it2.finished()); - it2.first(); CPPUNIT_ASSERT(it2.current()->getPtr()==e1_2); CPPUNIT_ASSERT(!it2.finished()); - it2.nextLoop(); CPPUNIT_ASSERT(it2.current()->getPtr()==e2_3); CPPUNIT_ASSERT(!it2.finished()); - it2.nextLoop(); CPPUNIT_ASSERT(it2.current()->getPtr()==e3_4); CPPUNIT_ASSERT(!it2.finished()); - it2.nextLoop(); CPPUNIT_ASSERT(it2.current()->getPtr()==e4_5); CPPUNIT_ASSERT(!it2.finished()); - // substitutions. - /*it2.first(); CPPUNIT_ASSERT(it2.current()->getPtr()==e1_2); CPPUNIT_ASSERT(!it2.finished()); - ElementaryEdge *&tmp=it2.current(); CPPUNIT_ASSERT(it2.current()->getPtr()==e1_2); CPPUNIT_ASSERT(!it2.finished()); - ComposedEdge *c1=new ComposedEdge; Node *n1_bis=new Node(0.,0.05); EdgeLin *e1_1bis=new EdgeLin(n1,n1_bis); EdgeLin *e1bis_2=new EdgeLin(n1_bis,n2); e1_1bis->incrRef(); e1bis_2->incrRef(); - c1->pushBack(e1_1bis); c1->pushBack(e1bis_2); delete tmp; tmp=(ElementaryEdge *)c1; CPPUNIT_ASSERT_EQUAL(13,c->recursiveSize()); - CPPUNIT_ASSERT(it2.current()->getPtr()==e1_1bis); CPPUNIT_ASSERT(!it2.finished());// here testing capability of Iterator.'current' method to deal with change of hierarchy. - it2.next(); CPPUNIT_ASSERT(it2.current()->getPtr()==e1bis_2); CPPUNIT_ASSERT(!it2.finished()); - it2.next(); CPPUNIT_ASSERT(it2.current()->getPtr()==e2_3); CPPUNIT_ASSERT(!it2.finished()); - it2.previousLoop(); CPPUNIT_ASSERT(it2.current()->getPtr()==e1bis_2); CPPUNIT_ASSERT(!it2.finished()); - it2.previousLoop(); CPPUNIT_ASSERT(it2.current()->getPtr()==e1_1bis); CPPUNIT_ASSERT(!it2.finished()); - it2.previousLoop(); CPPUNIT_ASSERT(it2.current()->getPtr()==e12_1); CPPUNIT_ASSERT(!it2.finished()); - it2.previousLoop(); CPPUNIT_ASSERT(it2.current()->getPtr()==e11_12); CPPUNIT_ASSERT(!it2.finished()); - it2.previousLoop(); CPPUNIT_ASSERT(it2.current()->getPtr()==e10_11); CPPUNIT_ASSERT(!it2.finished()); - it2.previousLoop(); CPPUNIT_ASSERT(it2.current()->getPtr()==e9_10); CPPUNIT_ASSERT(!it2.finished()); - it2.previousLoop(); CPPUNIT_ASSERT(it2.current()->getPtr()==e8_9); CPPUNIT_ASSERT(!it2.finished()); - it2.previousLoop(); CPPUNIT_ASSERT(it2.current()->getPtr()==e7_8); CPPUNIT_ASSERT(!it2.finished()); - it2.previousLoop(); CPPUNIT_ASSERT(it2.current()->getPtr()==e6_7); CPPUNIT_ASSERT(!it2.finished()); - it2.previousLoop(); CPPUNIT_ASSERT(it2.current()->getPtr()==e5_6); CPPUNIT_ASSERT(!it2.finished()); - it2.previousLoop(); CPPUNIT_ASSERT(it2.current()->getPtr()==e4_5); CPPUNIT_ASSERT(!it2.finished()); - it2.previousLoop(); CPPUNIT_ASSERT(it2.current()->getPtr()==e3_4); CPPUNIT_ASSERT(!it2.finished()); - it2.previousLoop(); CPPUNIT_ASSERT(it2.current()->getPtr()==e2_3); CPPUNIT_ASSERT(!it2.finished()); - it2.previousLoop(); CPPUNIT_ASSERT(it2.current()->getPtr()==e1bis_2); CPPUNIT_ASSERT(!it2.finished()); - it2.previousLoop(); CPPUNIT_ASSERT(it2.current()->getPtr()==e1_1bis); CPPUNIT_ASSERT(!it2.finished()); - it2.previousLoop(); CPPUNIT_ASSERT(it2.current()->getPtr()==e12_1); CPPUNIT_ASSERT(!it2.finished()); - //go forward - it2.nextLoop(); CPPUNIT_ASSERT(it2.current()->getPtr()==e1_1bis); CPPUNIT_ASSERT(!it2.finished()); - it2.nextLoop(); CPPUNIT_ASSERT(it2.current()->getPtr()==e1bis_2); CPPUNIT_ASSERT(!it2.finished()); - it2.nextLoop(); CPPUNIT_ASSERT(it2.current()->getPtr()==e2_3); CPPUNIT_ASSERT(!it2.finished()); - it2.nextLoop(); CPPUNIT_ASSERT(it2.current()->getPtr()==e3_4); CPPUNIT_ASSERT(!it2.finished()); - it2.nextLoop(); CPPUNIT_ASSERT(it2.current()->getPtr()==e4_5); CPPUNIT_ASSERT(!it2.finished()); - it2.nextLoop(); CPPUNIT_ASSERT(it2.current()->getPtr()==e5_6); CPPUNIT_ASSERT(!it2.finished()); - it2.nextLoop(); CPPUNIT_ASSERT(it2.current()->getPtr()==e6_7); CPPUNIT_ASSERT(!it2.finished()); - it2.nextLoop(); CPPUNIT_ASSERT(it2.current()->getPtr()==e7_8); CPPUNIT_ASSERT(!it2.finished()); - it2.nextLoop(); CPPUNIT_ASSERT(it2.current()->getPtr()==e8_9); CPPUNIT_ASSERT(!it2.finished()); - it2.nextLoop(); CPPUNIT_ASSERT(it2.current()->getPtr()==e9_10); CPPUNIT_ASSERT(!it2.finished()); - it2.nextLoop(); CPPUNIT_ASSERT(it2.current()->getPtr()==e10_11); CPPUNIT_ASSERT(!it2.finished()); - it2.nextLoop(); CPPUNIT_ASSERT(it2.current()->getPtr()==e11_12); CPPUNIT_ASSERT(!it2.finished()); - it2.nextLoop(); CPPUNIT_ASSERT(it2.current()->getPtr()==e12_1); CPPUNIT_ASSERT(!it2.finished()); - it2.nextLoop(); CPPUNIT_ASSERT(it2.current()->getPtr()==e1_1bis); CPPUNIT_ASSERT(!it2.finished());*/ - ComposedEdge::SoftDelete(c2_2_4); - ComposedEdge::SoftDelete(c2_2_5); - ComposedEdge::SoftDelete(c2_2); - ComposedEdge::SoftDelete(c2); - ComposedEdge::Delete(c); - //clean-up - //e1_1bis->decrRef(); e1bis_2->decrRef(); - e1_2->decrRef(); e2_3->decrRef(); e3_4->decrRef(); e4_5->decrRef(); e5_6->decrRef(); e6_7->decrRef(); - e7_8->decrRef(); e8_9->decrRef(); e9_10->decrRef(); e10_11->decrRef(); e11_12->decrRef(); e12_1->decrRef(); - //n1_bis->decrRef(); - n1->decrRef(); n2->decrRef(); n3->decrRef(); n4->decrRef(); n5->decrRef(); n6->decrRef(); - n7->decrRef(); n8->decrRef(); n9->decrRef(); n10->decrRef(); n11->decrRef(); n12->decrRef(); -} - -/*! - * Check splitting of 2 polygons. After this operation, all ElementaryEdge are either in/out/on. - */ -void QuadraticPlanarInterpTest::checkAssemblingBases2() -{ - //The "most" basic test1 - Node *n1=new Node(0.,0.); Node *n4=new Node(0.,-0.3); - Node *n2=new Node(1.,0.); Node *n5=new Node(1.,-0.3); - Node *n3=new Node(0.5,1.); Node *n6=new Node(0.5,0.7); - EdgeLin *e1_2=new EdgeLin(n1,n2); EdgeLin *e4_5=new EdgeLin(n4,n5); - EdgeLin *e2_3=new EdgeLin(n2,n3); EdgeLin *e5_6=new EdgeLin(n5,n6); - EdgeLin *e3_1=new EdgeLin(n3,n1); EdgeLin *e6_4=new EdgeLin(n6,n4); - // - e1_2->incrRef(); e2_3->incrRef(); e3_1->incrRef(); e4_5->incrRef(); e5_6->incrRef(); e6_4->incrRef(); - QuadraticPolygon pol1; pol1.pushBack(e1_2); pol1.pushBack(e2_3); pol1.pushBack(e3_1); - QuadraticPolygon pol2; pol2.pushBack(e4_5); pol2.pushBack(e5_6); pol2.pushBack(e6_4); - QuadraticPolygon cpyPol1(pol1); int nbOfSplits=0; - cpyPol1.SplitPolygonsEachOther(pol1,pol2,nbOfSplits); - CPPUNIT_ASSERT_EQUAL(5,pol1.recursiveSize()); - CPPUNIT_ASSERT_EQUAL(5,pol2.recursiveSize());CPPUNIT_ASSERT_EQUAL(15,nbOfSplits); - checkBasicsOfPolygons(pol1,pol2,true); - CPPUNIT_ASSERT(pol2[1]->getEndNode()==pol1[1]->getEndNode()); - CPPUNIT_ASSERT(pol2[1]->getEndNode()->getLoc()==ON_1); - CPPUNIT_ASSERT(pol2[3]->getEndNode()==pol1[0]->getEndNode()); - CPPUNIT_ASSERT(pol2[3]->getEndNode()->getLoc()==ON_1); - cpyPol1.performLocatingOperation(pol2); - ElementaryEdge *tmp=dynamic_cast(pol2[0]); CPPUNIT_ASSERT(tmp); CPPUNIT_ASSERT(tmp->getPtr()==e4_5); - CPPUNIT_ASSERT(tmp->getLoc()==FULL_OUT_1); - CPPUNIT_ASSERT(tmp->getLoc()==FULL_OUT_1); - tmp=dynamic_cast(pol2[1]); CPPUNIT_ASSERT(tmp); - CPPUNIT_ASSERT(tmp->getLoc()==FULL_OUT_1); - tmp=dynamic_cast(pol2[2]); CPPUNIT_ASSERT(tmp); - CPPUNIT_ASSERT(tmp->getLoc()==FULL_IN_1); - tmp=dynamic_cast(pol2[3]); CPPUNIT_ASSERT(tmp); - CPPUNIT_ASSERT(tmp->getLoc()==FULL_IN_1); - tmp=dynamic_cast(pol2[4]); CPPUNIT_ASSERT(tmp); - CPPUNIT_ASSERT(tmp->getLoc()==FULL_OUT_1); - //clean-up for test1 - e1_2->decrRef(); e2_3->decrRef(); e3_1->decrRef(); e4_5->decrRef(); e5_6->decrRef(); e6_4->decrRef(); - n1->decrRef(); n2->decrRef(); n3->decrRef(); n4->decrRef(); n5->decrRef(); n6->decrRef(); - - //Deeper test some extremities of pol2 are on edges of pol1. - - n1=new Node(0.,0.); n4=new Node(1.5,-0.5); - n2=new Node(1.,0.); n5=new Node(0.5,0.); - n3=new Node(0.5,1.); n6=new Node(0.75,0.5); Node *n7=new Node(2.,0.5); - e1_2=new EdgeLin(n1,n2); e2_3=new EdgeLin(n2,n3); e3_1=new EdgeLin(n3,n1); - EdgeLin *e5_4=new EdgeLin(n5,n4); EdgeLin *e4_7=new EdgeLin(n4,n7); EdgeLin *e7_6=new EdgeLin(n7,n6); EdgeLin *e6_5=new EdgeLin(n6,n5); - // - e1_2->incrRef(); e2_3->incrRef(); e3_1->incrRef(); e5_4->incrRef(); e4_7->incrRef(); e7_6->incrRef(); e6_5->incrRef(); - QuadraticPolygon pol3; pol3.pushBack(e1_2); pol3.pushBack(e2_3); pol3.pushBack(e3_1); - QuadraticPolygon pol4; pol4.pushBack(e5_4); pol4.pushBack(e4_7); pol4.pushBack(e7_6); pol4.pushBack(e6_5); - QuadraticPolygon cpyPol3(pol3); nbOfSplits=0; - cpyPol3.SplitPolygonsEachOther(pol3,pol4,nbOfSplits); - CPPUNIT_ASSERT_EQUAL(5,pol3.recursiveSize()); - CPPUNIT_ASSERT_EQUAL(4,pol4.recursiveSize());CPPUNIT_ASSERT_EQUAL(16,nbOfSplits); - checkBasicsOfPolygons(pol3,pol4,true); - CPPUNIT_ASSERT(pol4[0]->getStartNode()==pol3[0]->getEndNode()); CPPUNIT_ASSERT(pol4[0]->getStartNode()==n5); - CPPUNIT_ASSERT(n5->getLoc()==ON_LIM_1); - CPPUNIT_ASSERT(pol4[2]->getEndNode()==pol3[2]->getEndNode()); CPPUNIT_ASSERT(pol4[2]->getEndNode()==n6); - CPPUNIT_ASSERT(n6->getLoc()==ON_LIM_1); - cpyPol3.performLocatingOperation(pol4); - tmp=dynamic_cast(pol4[1]); CPPUNIT_ASSERT(tmp); CPPUNIT_ASSERT(tmp->getPtr()==e4_7); - CPPUNIT_ASSERT(tmp->getLoc()==FULL_OUT_1); - tmp=dynamic_cast(pol4[3]); CPPUNIT_ASSERT(tmp); CPPUNIT_ASSERT(tmp->getPtr()==e6_5); - tmp=dynamic_cast(pol4[0]); CPPUNIT_ASSERT(tmp); CPPUNIT_ASSERT(tmp->getPtr()==e5_4); - CPPUNIT_ASSERT(tmp->getLoc()==FULL_OUT_1); - tmp=dynamic_cast(pol4[2]); CPPUNIT_ASSERT(tmp); CPPUNIT_ASSERT(tmp->getPtr()==e7_6); - CPPUNIT_ASSERT(tmp->getLoc()==FULL_OUT_1); - tmp=dynamic_cast(pol4[3]); CPPUNIT_ASSERT(tmp); CPPUNIT_ASSERT(tmp->getPtr()==e6_5); - CPPUNIT_ASSERT(tmp->getLoc()==FULL_IN_1); - //clean-up for test2 - e1_2->decrRef(); e2_3->decrRef(); e3_1->decrRef(); e5_4->decrRef(); e4_7->decrRef(); e7_6->decrRef(); e6_5->decrRef(); - n1->decrRef(); n2->decrRef(); n3->decrRef(); n4->decrRef(); n5->decrRef(); n6->decrRef(); n7->decrRef(); - - //Test with one edge of pol2 is included in pol1. - - n1=new Node(0.,0.); n4=new Node(-0.5,0.); - n2=new Node(1.,0.); n5=new Node(0.,-1.); - n3=new Node(0.5,1.); n6=new Node(0.5,0.); - e1_2=new EdgeLin(n1,n2); e2_3=new EdgeLin(n2,n3); e3_1=new EdgeLin(n3,n1); - e4_5=new EdgeLin(n4,n5); e5_6=new EdgeLin(n5,n6); e6_4=new EdgeLin(n6,n4); - e1_2->incrRef(); e2_3->incrRef(); e3_1->incrRef(); e4_5->incrRef(); e5_6->incrRef(); e6_4->incrRef(); - QuadraticPolygon pol5; pol5.pushBack(e1_2); pol5.pushBack(e2_3); pol5.pushBack(e3_1); - QuadraticPolygon pol6; pol6.pushBack(e4_5); pol6.pushBack(e5_6); pol6.pushBack(e6_4); - QuadraticPolygon cpyPol5(pol5); nbOfSplits=0; - cpyPol5.SplitPolygonsEachOther(pol5,pol6,nbOfSplits); - CPPUNIT_ASSERT_EQUAL(4,pol5.recursiveSize()); - CPPUNIT_ASSERT_EQUAL(4,pol6.recursiveSize()); CPPUNIT_ASSERT_EQUAL(13,nbOfSplits); - checkBasicsOfPolygons(pol5,pol6,false); - CPPUNIT_ASSERT(pol6[2]->getStartNode()==pol5[0]->getEndNode()); CPPUNIT_ASSERT(pol6[2]->getStartNode()==n6); - CPPUNIT_ASSERT(n6->getLoc()==ON_LIM_1); - CPPUNIT_ASSERT(pol6[2]->getEndNode()==pol5[0]->getStartNode()); CPPUNIT_ASSERT(pol5[0]->getStartNode()==n1); - CPPUNIT_ASSERT(n1->getLoc()==ON_LIM_1); - cpyPol5.performLocatingOperation(pol6); - tmp=dynamic_cast(pol6[0]); CPPUNIT_ASSERT(tmp); CPPUNIT_ASSERT(tmp->getPtr()==e4_5); - CPPUNIT_ASSERT(tmp->getLoc()==FULL_OUT_1); - tmp=dynamic_cast(pol6[1]); CPPUNIT_ASSERT(tmp); CPPUNIT_ASSERT(tmp->getPtr()==e5_6); - CPPUNIT_ASSERT(tmp->getLoc()==FULL_OUT_1); - tmp=dynamic_cast(pol6[2]); CPPUNIT_ASSERT(tmp); - CPPUNIT_ASSERT(tmp->getLoc()==FULL_ON_1); - tmp=dynamic_cast(pol6[3]); CPPUNIT_ASSERT(tmp); - CPPUNIT_ASSERT(tmp->getLoc()==FULL_OUT_1); - //clean-up test3 - e1_2->decrRef(); e2_3->decrRef(); e3_1->decrRef(); e4_5->decrRef(); e5_6->decrRef(); e6_4->decrRef(); - n1->decrRef(); n2->decrRef(); n3->decrRef(); n4->decrRef(); n5->decrRef(); n6->decrRef(); - - //Test of full overlapped polygons. - - n1=new Node(0.,0.); n4=new Node(0.,0.); - n2=new Node(1.,0.); n5=new Node(1.,0.); - n3=new Node(0.5,1.); n6=new Node(0.5,1.); - e1_2=new EdgeLin(n1,n2); e2_3=new EdgeLin(n2,n3); e3_1=new EdgeLin(n3,n1); - e4_5=new EdgeLin(n4,n5); e5_6=new EdgeLin(n5,n6); e6_4=new EdgeLin(n6,n4); - e1_2->incrRef(); e2_3->incrRef(); e3_1->incrRef(); e4_5->incrRef(); e5_6->incrRef(); e6_4->incrRef(); - QuadraticPolygon pol7; pol7.pushBack(e1_2); pol7.pushBack(e2_3); pol7.pushBack(e3_1); - QuadraticPolygon pol8; pol8.pushBack(e4_5); pol8.pushBack(e5_6); pol8.pushBack(e6_4); - QuadraticPolygon cpyPol7(pol7); nbOfSplits=0; - cpyPol7.SplitPolygonsEachOther(pol7,pol8,nbOfSplits); - tmp=dynamic_cast(pol8[0]); CPPUNIT_ASSERT(tmp); CPPUNIT_ASSERT(tmp->getPtr()==e1_2); - CPPUNIT_ASSERT(tmp->getLoc()==FULL_ON_1); - tmp=dynamic_cast(pol8[1]); CPPUNIT_ASSERT(tmp); CPPUNIT_ASSERT(tmp->getPtr()==e2_3); - CPPUNIT_ASSERT(tmp->getLoc()==FULL_ON_1); - tmp=dynamic_cast(pol8[2]); CPPUNIT_ASSERT(tmp); CPPUNIT_ASSERT(tmp->getPtr()==e3_1); - CPPUNIT_ASSERT(tmp->getLoc()==FULL_ON_1); - //clean-up test4 - e1_2->decrRef(); e2_3->decrRef(); e3_1->decrRef(); e4_5->decrRef(); e5_6->decrRef(); e6_4->decrRef(); - n1->decrRef(); n2->decrRef(); n3->decrRef(); n4->decrRef(); n5->decrRef(); n6->decrRef(); -} - -void QuadraticPlanarInterpTest::checkBasicsOfPolygons(QuadraticPolygon& pol1, QuadraticPolygon& pol2, bool checkDirection) -{ - IteratorOnComposedEdge it1(&pol1),it2(&pol2); it1.previousLoop(); it2.previousLoop(); - Node *nIter1=it1.current()->getEndNode(); Node *nIter2=it2.current()->getEndNode(); - for(it2.first();!it2.finished();it2.next()) - { - CPPUNIT_ASSERT(nIter2==it2.current()->getStartNode()); - if(checkDirection) - CPPUNIT_ASSERT(it2.current()->getDirection()); - nIter2=it2.current()->getEndNode(); - } - for(it1.first();!it1.finished();it1.next()) - { - CPPUNIT_ASSERT(nIter1==it1.current()->getStartNode()); - if(checkDirection) - CPPUNIT_ASSERT(it1.current()->getDirection()); - nIter1=it1.current()->getEndNode(); - } -} - -} diff --git a/src/INTERP_KERNELTest/QuadraticPlanarInterpTest4.cxx b/src/INTERP_KERNELTest/QuadraticPlanarInterpTest4.cxx deleted file mode 100644 index c9c34bd27..000000000 --- a/src/INTERP_KERNELTest/QuadraticPlanarInterpTest4.cxx +++ /dev/null @@ -1,1685 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 -// 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 "QuadraticPlanarInterpTest.hxx" -#include "InterpKernelGeo2DQuadraticPolygon.hxx" -#include "InterpKernelGeo2DElementaryEdge.hxx" -#include "InterpKernelGeo2DEdgeArcCircle.hxx" -#include "InterpKernelGeo2DEdgeLin.hxx" - -#include -#include -#include -#include - -using namespace INTERP_KERNEL; - -namespace INTERP_TEST -{ - -void QuadraticPlanarInterpTest::checkPolygonsIntersection1() -{ - //The "most" basic test1 - Node *n1=new Node(0.,0.); Node *n4=new Node(0.,-0.3); - Node *n2=new Node(1.,0.); Node *n5=new Node(1.,-0.3); - Node *n3=new Node(0.5,1.); Node *n6=new Node(0.5,0.7); - EdgeLin *e1_2=new EdgeLin(n1,n2); EdgeLin *e4_5=new EdgeLin(n4,n5); - EdgeLin *e2_3=new EdgeLin(n2,n3); EdgeLin *e5_6=new EdgeLin(n5,n6); - EdgeLin *e3_1=new EdgeLin(n3,n1); EdgeLin *e6_4=new EdgeLin(n6,n4); - // - std::vector result; - for(int k=0;k<2;k++) - for(int i=0;i<3;i++) - { - for(int j=0;j<1;j++) - { - e1_2->incrRef(); e2_3->incrRef(); e3_1->incrRef(); e4_5->incrRef(); e5_6->incrRef(); e6_4->incrRef(); - QuadraticPolygon pol1; pol1.circularPermute(); pol1.pushBack(e1_2); pol1.pushBack(e2_3); pol1.pushBack(e3_1); - for(int i1=0;i1recursiveSize()); - double tmp1=0.,tmp2=0.,tmp3=0.; - pol1.intersectForPerimeter(pol2,tmp1,tmp2,tmp3); - std::vector v1,v2; - std::vector v3; - pol1.intersectForPerimeterAdvanced(pol2,v1,v2);//no common edge - pol1.intersectForPoint(pol2,v3); - CPPUNIT_ASSERT_EQUAL(3,(int)v1.size()); - CPPUNIT_ASSERT_EQUAL(3,(int)v2.size()); - CPPUNIT_ASSERT_EQUAL(3,(int)v3.size()); - if(k==0) - { - CPPUNIT_ASSERT_EQUAL(2,v3[(3-i)%3]); - CPPUNIT_ASSERT_EQUAL(0,v3[(4-i)%3]); - CPPUNIT_ASSERT_EQUAL(0,v3[(5-i)%3]); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.7,v1[(3-i)%3],1.e-14); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.,v1[(4-i)%3],1.e-14); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.,v1[(5-i)%3],1.e-14); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.,v2[0],1.e-14); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.78262379212492639,v2[1],1.e-14); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.78262379212492639,v2[2],1.e-14); - } - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.7,tmp1,1.e-14); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1.5652475842498528,tmp2,1.e-14); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.,tmp3,1.e-14);//no common edge - delete result[0]; - } - } - //clean-up for test1 - e1_2->decrRef(); e2_3->decrRef(); e3_1->decrRef(); e4_5->decrRef(); e5_6->decrRef(); e6_4->decrRef(); - n1->decrRef(); n2->decrRef(); n3->decrRef(); n4->decrRef(); n5->decrRef(); n6->decrRef(); - - //Deeper test some extremities of pol2 are on edges of pol1. - - n1=new Node(0.,0.); n4=new Node(1.5,-0.5); - n2=new Node(1.,0.); n5=new Node(0.5,0.); - n3=new Node(0.5,1.); n6=new Node(0.75,0.5); Node *n7=new Node(2.,0.5); - e1_2=new EdgeLin(n1,n2); e2_3=new EdgeLin(n2,n3); e3_1=new EdgeLin(n3,n1); - EdgeLin *e5_4=new EdgeLin(n5,n4); EdgeLin *e4_7=new EdgeLin(n4,n7); EdgeLin *e7_6=new EdgeLin(n7,n6); EdgeLin *e6_5=new EdgeLin(n6,n5); - // - for(int k=0;k<2;k++) - for(int i=0;i<3;i++) - { - for(int j=0;j<4;j++) - { - e1_2->incrRef(); e2_3->incrRef(); e3_1->incrRef(); e5_4->incrRef(); e4_7->incrRef(); e7_6->incrRef(); e6_5->incrRef(); - QuadraticPolygon pol3; pol3.pushBack(e1_2); pol3.pushBack(e2_3); pol3.pushBack(e3_1); - for(int i1=0;i1recursiveSize()); - delete result[0]; - } - } - //clean-up for test2 - e1_2->decrRef(); e2_3->decrRef(); e3_1->decrRef(); e5_4->decrRef(); e4_7->decrRef(); e7_6->decrRef(); e6_5->decrRef(); - n1->decrRef(); n2->decrRef(); n3->decrRef(); n4->decrRef(); n5->decrRef(); n6->decrRef(); n7->decrRef(); - - //Test with one edge of pol2 is included in pol1. - - n1=new Node(0.,0.); n4=new Node(-0.5,0.); - n2=new Node(1.,0.); n5=new Node(0.,-1.); - n3=new Node(0.5,1.); n6=new Node(0.5,0.); - e1_2=new EdgeLin(n1,n2); e2_3=new EdgeLin(n2,n3); e3_1=new EdgeLin(n3,n1); - e4_5=new EdgeLin(n4,n5); e5_6=new EdgeLin(n5,n6); e6_4=new EdgeLin(n6,n4); - for(int k=0;k<2;k++) - for(int i=0;i<3;i++) - { - for(int j=0;j<3;j++) - { - e1_2->incrRef(); e2_3->incrRef(); e3_1->incrRef(); e4_5->incrRef(); e5_6->incrRef(); e6_4->incrRef(); - QuadraticPolygon pol5; pol5.pushBack(e1_2); pol5.pushBack(e2_3); pol5.pushBack(e3_1); - for(int i1=0;i1decrRef(); e2_3->decrRef(); e3_1->decrRef(); e4_5->decrRef(); e5_6->decrRef(); e6_4->decrRef(); - n1->decrRef(); n2->decrRef(); n3->decrRef(); n4->decrRef(); n5->decrRef(); n6->decrRef(); - - //Test of full overlapped polygons. - - n1=new Node(0.,0.); n4=new Node(0.,0.); - n2=new Node(1.,0.); n5=new Node(1.,0.); - n3=new Node(0.5,1.); n6=new Node(0.5,1.); - e1_2=new EdgeLin(n1,n2); e2_3=new EdgeLin(n2,n3); e3_1=new EdgeLin(n3,n1); - e4_5=new EdgeLin(n4,n5); e5_6=new EdgeLin(n5,n6); e6_4=new EdgeLin(n6,n4); - for(int k=0;k<2;k++) - for(int i=0;i<3;i++) - { - for(int j=0;j<3;j++) - { - e1_2->incrRef(); e2_3->incrRef(); e3_1->incrRef(); e4_5->incrRef(); e5_6->incrRef(); e6_4->incrRef(); - QuadraticPolygon pol7; pol7.pushBack(e1_2); pol7.pushBack(e2_3); pol7.pushBack(e3_1); - for(int i1=0;i1recursiveSize()); - delete result[0]; - double tmp1=0.,tmp2=0.,tmp3=0.; - pol7.intersectForPerimeter(pol8,tmp1,tmp2,tmp3); - std::vector v1,v2; - pol7.intersectForPerimeterAdvanced(pol8,v1,v2);//only common edges. - CPPUNIT_ASSERT_DOUBLES_EQUAL(3.2360679774997898,v1[0]+v1[1]+v1[2],1.e-14); - CPPUNIT_ASSERT_DOUBLES_EQUAL(3.2360679774997898,v2[0]+v2[1]+v2[2],1.e-14); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.,tmp1,1.e-14); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.,tmp2,1.e-14); - CPPUNIT_ASSERT_DOUBLES_EQUAL(3.2360679774997898,tmp3,1.e-14); - } - } - //clean-up test4 - e1_2->decrRef(); e2_3->decrRef(); e3_1->decrRef(); e4_5->decrRef(); e5_6->decrRef(); e6_4->decrRef(); - n1->decrRef(); n2->decrRef(); n3->decrRef(); n4->decrRef(); n5->decrRef(); n6->decrRef(); - - //Test of closing process - - n1=new Node(0.,0.); n4=new Node(0.539,-0.266); - n2=new Node(1.,0.); n5=new Node(1.039,0.6); - n3=new Node(0.5,1.); n6=new Node(-0.077,0.667); - e1_2=new EdgeLin(n1,n2); e2_3=new EdgeLin(n2,n3); e3_1=new EdgeLin(n3,n1); - e4_5=new EdgeLin(n4,n5); e5_6=new EdgeLin(n5,n6); e6_4=new EdgeLin(n6,n4); - for(int k=0;k<2;k++) - for(int i=0;i<3;i++) - { - for(int j=0;j<3;j++) - { - e1_2->incrRef(); e2_3->incrRef(); e3_1->incrRef(); e4_5->incrRef(); e5_6->incrRef(); e6_4->incrRef(); - QuadraticPolygon pol9; pol9.pushBack(e1_2); pol9.pushBack(e2_3); pol9.pushBack(e3_1); - for(int i1=0;i1recursiveSize()); - delete result[0]; - } - } - //clean-up test5 - e1_2->decrRef(); e2_3->decrRef(); e3_1->decrRef(); e4_5->decrRef(); e5_6->decrRef(); e6_4->decrRef(); - n1->decrRef(); n2->decrRef(); n3->decrRef(); n4->decrRef(); n5->decrRef(); n6->decrRef(); - - // Full in case - - n1=new Node(0.,0.); n4=new Node(0.3,0.1); - n2=new Node(1.,0.); n5=new Node(0.7,0.1); - n3=new Node(0.5,1.); n6=new Node(0.5,0.7); - e1_2=new EdgeLin(n1,n2); e2_3=new EdgeLin(n2,n3); e3_1=new EdgeLin(n3,n1); - e4_5=new EdgeLin(n4,n5); e5_6=new EdgeLin(n5,n6); e6_4=new EdgeLin(n6,n4); - for(int k=0;k<2;k++) - for(int i=0;i<3;i++) - { - for(int j=0;j<3;j++) - { - e1_2->incrRef(); e2_3->incrRef(); e3_1->incrRef(); e4_5->incrRef(); e5_6->incrRef(); e6_4->incrRef(); - QuadraticPolygon pol11; pol11.pushBack(e1_2); pol11.pushBack(e2_3); pol11.pushBack(e3_1); - for(int i1=0;i1recursiveSize()); - delete result[0]; - } - } - //clean-up test6 - e1_2->decrRef(); e2_3->decrRef(); e3_1->decrRef(); e4_5->decrRef(); e5_6->decrRef(); e6_4->decrRef(); - n1->decrRef(); n2->decrRef(); n3->decrRef(); n4->decrRef(); n5->decrRef(); n6->decrRef(); - - // Full out case - - n1=new Node(0.,0.); n4=new Node(-2,0.); - n2=new Node(1.,0.); n5=new Node(-1.,0.); - n3=new Node(0.5,1.); n6=new Node(-1.5,1.); - e1_2=new EdgeLin(n1,n2); e2_3=new EdgeLin(n2,n3); e3_1=new EdgeLin(n3,n1); - e4_5=new EdgeLin(n4,n5); e5_6=new EdgeLin(n5,n6); e6_4=new EdgeLin(n6,n4); - for(int k=0;k<2;k++) - for(int i=0;i<3;i++) - { - for(int j=0;j<3;j++) - { - e1_2->incrRef(); e2_3->incrRef(); e3_1->incrRef(); e4_5->incrRef(); e5_6->incrRef(); e6_4->incrRef(); - QuadraticPolygon pol13; pol13.pushBack(e1_2); pol13.pushBack(e2_3); pol13.pushBack(e3_1); - for(int i1=0;i1decrRef(); e2_3->decrRef(); e3_1->decrRef(); e4_5->decrRef(); e5_6->decrRef(); e6_4->decrRef(); - n1->decrRef(); n2->decrRef(); n3->decrRef(); n4->decrRef(); n5->decrRef(); n6->decrRef(); - - //Multi polygons - - n1=new Node(0.,0.); - n2=new Node(1.,0.); - n3=new Node(1.,1.); - n4=new Node(0.,1.); - // - n5=new Node(0.2,0.7); - n6=new Node(0.4,0.7); - n7=new Node(0.4,1.3); - Node *n8=new Node(0.6,1.3); - Node *n9=new Node(0.6,0.7); - Node *n10=new Node(0.9,0.7); - Node *n11=new Node(0.9,2.); - Node *n12=new Node(0.2,2.); - // - e1_2=new EdgeLin(n1,n2); e2_3=new EdgeLin(n2,n3); Edge *e3_4=new EdgeLin(n3,n4); Edge *e4_1=new EdgeLin(n4,n1); - e5_6=new EdgeLin(n5,n6); Edge *e6_7=new EdgeLin(n6,n7); Edge *e7_8=new EdgeLin(n7,n8); Edge *e8_9=new EdgeLin(n8,n9); Edge *e9_10=new EdgeLin(n9,n10); Edge *e10_11=new EdgeLin(n10,n11); - Edge *e11_12=new EdgeLin(n11,n12); Edge *e12_1=new EdgeLin(n12,n5); - // - for(int k=0;k<2;k++) - for(int i=0;i<4;i++) - { - for(int j=0;j<8;j++) - { - e1_2->incrRef(); e2_3->incrRef(); e3_4->incrRef(); e4_1->incrRef(); e5_6->incrRef(); e6_7->incrRef(); e7_8->incrRef(); e8_9->incrRef(); e9_10->incrRef(); e10_11->incrRef(); e11_12->incrRef(); e12_1->incrRef(); - QuadraticPolygon pol15; pol15.pushBack(e1_2); pol15.pushBack(e2_3); pol15.pushBack(e3_4); pol15.pushBack(e4_1); - for(int i1=0;i1recursiveSize()); CPPUNIT_ASSERT_EQUAL(4,result[1]->recursiveSize()); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.15,result[0]->getArea()+result[1]->getArea(),1e-10); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.03,fabs(result[0]->getArea()-result[1]->getArea()),1e-10); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.15,pol15.intersectWith(pol16),1e-10); - delete result[0]; delete result[1]; - } - } - //clean-up test8 - e1_2->decrRef(); e2_3->decrRef(); e3_4->decrRef(); e4_1->decrRef(); e5_6->decrRef(); e6_7->decrRef(); e7_8->decrRef(); e8_9->decrRef(); e9_10->decrRef(); e10_11->decrRef(); e11_12->decrRef(); e12_1->decrRef(); - n1->decrRef(); n2->decrRef(); n3->decrRef(); n4->decrRef(); n5->decrRef(); n6->decrRef(); n7->decrRef(); n8->decrRef(); n9->decrRef(); n10->decrRef(); n11->decrRef(); n12->decrRef(); -} - -/*! - * Testing case where a polygon pol1 is included in an onother polygon pol2. - */ -void QuadraticPlanarInterpTest::checkPolygonsIntersection2() -{ - Node *n1=new Node(0.,0.); Node *n4=new Node(0.2,0.2); - Node *n2=new Node(1.,0.); Node *n5=new Node(0.8,0.2); - Node *n3=new Node(0.5,1.); Node *n6=new Node(0.5,0.8); - Edge *e1_2=new EdgeLin(n1,n2); Edge *e4_5=new EdgeLin(n4,n5); - Edge *e2_3=new EdgeLin(n2,n3); Edge *e5_6=new EdgeLin(n5,n6); - Edge *e3_1=new EdgeLin(n3,n1); Edge *e6_4=new EdgeLin(n6,n4); - // - QuadraticPolygon pol1; pol1.pushBack(e1_2); pol1.pushBack(e2_3); pol1.pushBack(e3_1); - QuadraticPolygon pol2; pol2.pushBack(e4_5); pol2.pushBack(e5_6); pol2.pushBack(e6_4); - std::vector result=pol1.intersectMySelfWith(pol2); - CPPUNIT_ASSERT_EQUAL(1,(int)result.size()); - CPPUNIT_ASSERT_EQUAL(3,result[0]->recursiveSize()); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.18,result[0]->getArea(),1e-10); - delete result[0]; - result.clear(); - pol1.initLocations(); - pol2.initLocations(); - result=pol2.intersectMySelfWith(pol1); - CPPUNIT_ASSERT_EQUAL(1,(int)result.size()); - CPPUNIT_ASSERT_EQUAL(3,result[0]->recursiveSize()); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.18,result[0]->getArea(),1e-10); - delete result[0]; - //clean-up - n1->decrRef(); n2->decrRef(); n3->decrRef(); n4->decrRef(); n5->decrRef(); n6->decrRef(); -} - -void QuadraticPlanarInterpTest::checkAreasCalculations() -{ - Node *n1=new Node(0.,0.); - Node *n2=new Node(1.,0.); - Node *n3=new Node(0.5,1.); - Edge *e1_2=new EdgeLin(n1,n2); - Edge *e2_3=new EdgeLin(n2,n3); - Edge *e3_1=new EdgeLin(n3,n1); - // - e1_2->incrRef(); e2_3->incrRef(); e3_1->incrRef(); - QuadraticPolygon pol1; pol1.pushBack(e1_2); pol1.pushBack(e2_3); pol1.pushBack(e3_1); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.5,pol1.getArea(),1e-10); - CPPUNIT_ASSERT_DOUBLES_EQUAL(3.2360679774997898,pol1.getPerimeter(),1e-10); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.61803398874989479,pol1.getHydraulicDiameter(),1e-10); - pol1.reverse(); - CPPUNIT_ASSERT_DOUBLES_EQUAL(-0.5,pol1.getArea(),1e-10); - CPPUNIT_ASSERT_DOUBLES_EQUAL(3.2360679774997898,pol1.getPerimeter(),1e-10); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.61803398874989479,pol1.getHydraulicDiameter(),1e-10); - //clean-up - e1_2->decrRef(); e2_3->decrRef(); e3_1->decrRef(); - n1->decrRef(); n2->decrRef(); n3->decrRef(); - - //case 2 - - n1=new Node(0.,0.); - n2=new Node(1.,0.); - Node *n3m=new Node(1.5,0.5); - n3=new Node(1.,1.); - Node *n4=new Node(0.,1.); - e1_2=new EdgeLin(n1,n2); - e2_3=new EdgeArcCircle(n2,n3m,n3); - Edge *e3_4=new EdgeLin(n3,n4); - Edge *e4_1=new EdgeLin(n4,n1); - // - for(int k=0;k<8;k++) - { - n2->setNewCoords(cos(k*M_PI/4),sin(k*M_PI/4)); - n3->setNewCoords(sqrt(2.)*cos((k+1)*M_PI/4),sqrt(2.)*sin((k+1)*M_PI/4)); - n3m->setNewCoords(1.5811388300841898*cos(0.3217505543966423+k*M_PI/4),1.5811388300841898*sin(0.3217505543966423+k*M_PI/4)); - n4->setNewCoords(cos(k*M_PI/4+M_PI/2),sin(k*M_PI/4+M_PI/2)); - e1_2->update(n3m); e2_3->update(n3m); e3_4->update(n3m); e4_1->update(n3m); - e1_2->incrRef(); e2_3->incrRef(); e3_4->incrRef(); e4_1->incrRef(); - QuadraticPolygon pol2; pol2.pushBack(e1_2); pol2.pushBack(e2_3); pol2.pushBack(e3_4); pol2.pushBack(e4_1); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1.3926990816987241,pol2.getArea(),1e-6); - CPPUNIT_ASSERT_DOUBLES_EQUAL(4.5707963267948966,pol2.getPerimeter(),1e-6); - pol2.reverse(); - CPPUNIT_ASSERT_DOUBLES_EQUAL(-1.3926990816987241,pol2.getArea(),1e-6); - CPPUNIT_ASSERT_DOUBLES_EQUAL(4.5707963267948966,pol2.getPerimeter(),1e-6); - } - //clean-up case2 - e1_2->decrRef(); e2_3->decrRef(); e3_4->decrRef(); e4_1->decrRef(); - n1->decrRef(); n2->decrRef(); n3->decrRef(); n3m->decrRef(); n4->decrRef(); - - //case 3 - - const double radius1=0.7; - const double radius2=0.9; - n1=new Node(1.+radius1*cos(-2.*M_PI/3.),1.+radius1*sin(-2.*M_PI/3.)); - n2=new Node(1.+radius1*cos(-M_PI/3.),1.+radius1*sin(-M_PI/3.)); - Node *n2m=new Node(1.+radius1*cos(M_PI/2.),1.+radius1*sin(M_PI/2.)); - n3=new Node(1.+radius2*cos(-M_PI/3.),1.+radius2*sin(-M_PI/3.)); - n3m=new Node(1.+radius2*cos(M_PI/2.),1.+radius2*sin(M_PI/2.)); - n4=new Node(1.+radius2*cos(-2.*M_PI/3.),1.+radius2*sin(-2.*M_PI/3.)); - e1_2=new EdgeArcCircle(n1,n2m,n2); - e2_3=new EdgeLin(n2,n3); - e3_4=new EdgeArcCircle(n3,n3m,n4); - e4_1=new EdgeLin(n4,n1); - // - e1_2->incrRef(); e2_3->incrRef(); e3_4->incrRef(); e4_1->incrRef(); - QuadraticPolygon pol3; pol3.pushBack(e1_2); pol3.pushBack(e2_3); pol3.pushBack(e3_4); pol3.pushBack(e4_1); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.83775804095727857,pol3.getArea(),1e-10); - CPPUNIT_ASSERT_DOUBLES_EQUAL(8.7775804095727832,pol3.getPerimeter(),1e-10); - pol3.reverse(); - CPPUNIT_ASSERT_DOUBLES_EQUAL(-0.83775804095727857,pol3.getArea(),1e-10); - CPPUNIT_ASSERT_DOUBLES_EQUAL(8.7775804095727832,pol3.getPerimeter(),1e-10); - //clean-up case3 - e1_2->decrRef(); e2_3->decrRef(); e3_4->decrRef(); e4_1->decrRef(); - n1->decrRef(); n2->decrRef(); n2m->decrRef(); n3->decrRef(); n3m->decrRef(); n4->decrRef(); -} - -void QuadraticPlanarInterpTest::checkBarycenterCalculations() -{ - Node *n1=new Node(3.,7.); - Node *n2=new Node(5.,7.); - Node *n3=new Node(4.,8.); - Edge *e1_2=new EdgeLin(n1,n2); - Edge *e2_3=new EdgeLin(n2,n3); - Edge *e3_1=new EdgeLin(n3,n1); - // - double bary[2]; - e1_2->incrRef(); e2_3->incrRef(); e3_1->incrRef(); - QuadraticPolygon pol1; pol1.pushBack(e1_2); pol1.pushBack(e2_3); pol1.pushBack(e3_1); - bary[0]=0.; bary[1]=0.; - e1_2->getBarycenterOfZone(bary); - CPPUNIT_ASSERT_DOUBLES_EQUAL(-56.,bary[0],1.e-10); - bary[0]=0.; bary[1]=0.; - e2_3->getBarycenterOfZone(bary); - CPPUNIT_ASSERT_DOUBLES_EQUAL(33.66666666666667,bary[0],1.e-10); - CPPUNIT_ASSERT_DOUBLES_EQUAL(28.16666666666667,bary[1],1.e-10); - bary[0]=0.; bary[1]=0.; - e3_1->getBarycenterOfZone(bary); - CPPUNIT_ASSERT_DOUBLES_EQUAL(26.333333333333336,bary[0],1.e-10); - CPPUNIT_ASSERT_DOUBLES_EQUAL(28.1666666666667,bary[1],1.e-10); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,pol1.getArea(),1e-10); - pol1.getBarycenter(bary); - CPPUNIT_ASSERT_DOUBLES_EQUAL(4.,bary[0],1.e-10); - CPPUNIT_ASSERT_DOUBLES_EQUAL(7.333333333333333,bary[1],1.e-10); - // - e1_2->incrRef(); e2_3->incrRef(); e3_1->incrRef(); - QuadraticPolygon pol4; pol4.pushBack(e3_1,false); pol4.pushBack(e2_3,false); pol4.pushBack(e1_2,false); - CPPUNIT_ASSERT_DOUBLES_EQUAL(-1.,pol4.getArea(),1e-10); - pol4.getBarycenter(bary); - CPPUNIT_ASSERT_DOUBLES_EQUAL(4.,bary[0],1.e-10); - CPPUNIT_ASSERT_DOUBLES_EQUAL(7.333333333333333,bary[1],1.e-10); - //clean-up - e1_2->decrRef(); e2_3->decrRef(); e3_1->decrRef(); - n1->decrRef(); n2->decrRef(); n3->decrRef(); - //Inverting polygon - n1=new Node(3.,7.); - n2=new Node(5.,7.); - n3=new Node(4.,8.); - e1_2=new EdgeLin(n1,n3); - e2_3=new EdgeLin(n3,n2); - e3_1=new EdgeLin(n2,n1); - e1_2->incrRef(); e2_3->incrRef(); e3_1->incrRef(); - QuadraticPolygon pol3; pol3.pushBack(e1_2); pol3.pushBack(e2_3); pol3.pushBack(e3_1); - bary[0]=0.; bary[1]=0.; - pol3.getBarycenter(bary); - CPPUNIT_ASSERT_DOUBLES_EQUAL(-1.,pol3.getArea(),1e-10); - CPPUNIT_ASSERT_DOUBLES_EQUAL(4.,bary[0],1.e-10); - CPPUNIT_ASSERT_DOUBLES_EQUAL(7.333333333333333,bary[1],1.e-10); - //clean-up - e1_2->decrRef(); e2_3->decrRef(); e3_1->decrRef(); - n1->decrRef(); n2->decrRef(); n3->decrRef(); - // - double center[2]={3.,7.}; - e1_2=buildArcOfCircle(center,4.,M_PI/3.,4.*M_PI/3.); - bary[0]=0.; bary[1]=0.; - e1_2->getBarycenterOfZone(bary); - CPPUNIT_ASSERT_DOUBLES_EQUAL(131.685410765053,bary[0],1.e-10); - CPPUNIT_ASSERT_DOUBLES_EQUAL(303.262521934362,bary[1],1.e-10); - n1=new Node(0.99999999999999822,3.5358983848622465); - n2=new Node(5.,10.4641016151377544); - Edge *e2_1=new EdgeLin(n1,n2); - // - e1_2->incrRef(); e2_1->incrRef(); - QuadraticPolygon pol2; pol2.pushBack(e1_2); pol2.pushBack(e2_1); - pol2.getBarycenter(bary); - CPPUNIT_ASSERT_DOUBLES_EQUAL(25.132741228718345,pol2.getArea(),1e-10); - //4*radius/(3.*pi) - CPPUNIT_ASSERT_DOUBLES_EQUAL(1.5297896122085546,bary[0],1.e-10); - CPPUNIT_ASSERT_DOUBLES_EQUAL(7.8488263631567756,bary[1],1.e-10); - //clean-up - e1_2->decrRef(); e2_1->decrRef(); - n1->decrRef(); n2->decrRef(); -} - -/*! - * Testing user interface high level function. - */ -void QuadraticPlanarInterpTest::checkHighLevelFunctionTest1() -{ - QUADRATIC_PLANAR::setPrecision(1e-12); - QUADRATIC_PLANAR::setArcDetectionPrecision(1e-9); - double coords[]={ - 8.8334591186000004, 5.0999999999999996, - 7.1014083111000001, 6.0999999999999996, - 7.8334591186000004, 6.8320508074999999, - 7.9674337149000003, 5.5999999999999996, - 7.4192455562999999, 6.5142135623000001, - 8.3334591186000004, 5.9660254036999998 - }; - std::vector nodes; - nodes.push_back(new Node(coords)); - nodes.push_back(new Node(coords+2)); - nodes.push_back(new Node(coords+4)); - nodes.push_back(new Node(coords+6)); - nodes.push_back(new Node(coords+8)); - nodes.push_back(new Node(coords+10)); - QuadraticPolygon *pol=QuadraticPolygon::BuildArcCirclePolygon(nodes); - CPPUNIT_ASSERT_DOUBLES_EQUAL(-1.04719755,pol->getArea(),1e-5); - CPPUNIT_ASSERT_EQUAL(3,pol->size()); - ElementaryEdge *e0=dynamic_cast((*pol)[0]); - ElementaryEdge *e1=dynamic_cast((*pol)[1]); - ElementaryEdge *e2=dynamic_cast((*pol)[0]); - CPPUNIT_ASSERT(e0); CPPUNIT_ASSERT(e1); CPPUNIT_ASSERT(e2); - CPPUNIT_ASSERT(dynamic_cast(e0->getPtr()));//<- testing detection of colinearity - CPPUNIT_ASSERT(dynamic_cast(e1->getPtr())); - CPPUNIT_ASSERT(dynamic_cast(e2->getPtr()));//<- testing detection of colinearity - nodes.clear(); - delete pol; - nodes.push_back(new Node(coords)); - nodes.push_back(new Node(coords+4)); - nodes.push_back(new Node(coords+2)); - nodes.push_back(new Node(coords+10)); - nodes.push_back(new Node(coords+8)); - nodes.push_back(new Node(coords+6)); - pol=QuadraticPolygon::BuildArcCirclePolygon(nodes); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1.04719755,pol->getArea(),1e-5); - CPPUNIT_ASSERT_EQUAL(3,pol->size()); - e0=dynamic_cast((*pol)[0]); - e1=dynamic_cast((*pol)[1]); - e2=dynamic_cast((*pol)[0]); - CPPUNIT_ASSERT(e0); CPPUNIT_ASSERT(e1); CPPUNIT_ASSERT(e2); - CPPUNIT_ASSERT(dynamic_cast(e0->getPtr()));//<- testing detection of colinearity - CPPUNIT_ASSERT(dynamic_cast(e1->getPtr())); - CPPUNIT_ASSERT(dynamic_cast(e2->getPtr()));//<- testing detection of colinearity - delete pol; - const double coords2[]={ - 0.,0., - 1.5,0., - 1.5,1., - 0.,1. - }; - nodes.clear(); - nodes.push_back(new Node(coords2)); - nodes.push_back(new Node(coords2+2)); - nodes.push_back(new Node(coords2+4)); - nodes.push_back(new Node(coords2+6)); - pol=QuadraticPolygon::BuildLinearPolygon(nodes); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1.5,pol->getArea(),1e-12); - double tmp[2],tmp2; - pol->getBarycenter(tmp,tmp2); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.75,tmp[0],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.5,tmp[1],1e-12); - delete pol; - const double coords3[]={ - 1.0999999999000001, -1.9052558882999999, - 1.9052558881999999, -1.0999999999000001, - 1.7320508075000001, -0.99999999989999999, - 0.99999999989999999, -1.7320508075000001, - 1.5556349186, -1.5556349185, - 1.8186533478, -1.0499999999, - 1.4142135623000001, -1.4142135623000001, - 1.0499999999, -1.8186533479 - }; - nodes.clear(); - nodes.push_back(new Node(coords3)); - nodes.push_back(new Node(coords3+2)); - nodes.push_back(new Node(coords3+4)); - nodes.push_back(new Node(coords3+6)); - nodes.push_back(new Node(coords3+8)); - nodes.push_back(new Node(coords3+10)); - nodes.push_back(new Node(coords3+12)); - nodes.push_back(new Node(coords3+14)); - pol=QuadraticPolygon::BuildArcCirclePolygon(nodes); - pol->getBarycenter(tmp,tmp2); - delete pol; - QUADRATIC_PLANAR::setPrecision(1e-14); -} - -void QuadraticPlanarInterpTest::check1DInterpLin() -{ - QUADRATIC_PLANAR::setPrecision(1e-7); - QUADRATIC_PLANAR::setArcDetectionPrecision(1e-9); - const int NB_OF_CELL_AXIAL_1=30; - static const double Z_VALS_1[NB_OF_CELL_AXIAL_1+1]= - { -0.1550 , -0.1356, -0.1162, -0.0969, -0.0775 ,-0.0581, -0.0387, -0.0194, 0.0000 , 0.0500, - 0.1000 , 0.1500 , 0.2000 , 0.2500, 0.3000, 0.3500, 0.4000, 0.4500, 0.5000, 0.5500, - 0.6000, 0.6500, 0.7000, 0.7194, 0.7388, 0.7581, 0.7775, 0.7969, 0.8163, 0.8356, - 0.8550}; - std::vector zLev1(Z_VALS_1,Z_VALS_1+NB_OF_CELL_AXIAL_1+1); - - const int NB_OF_CELL_AXIAL_2=46; - static const double Z_VALS_2[NB_OF_CELL_AXIAL_2+1]= - { -0.3050 ,-0.2863,-0.2675,-0.2488,-0.2300,-0.2113,-0.1925,-0.1738,-0.1550,-0.1356 - , -0.1162,-0.0969,-0.0775,-0.0581,-0.0387,-0.0194,0.0000, 0.0500, 0.1 ,0.15 - , 0.20, 0.25, 0.30, 0.350 ,0.40 ,0.450 ,0.500 , 0.550, 0.600 ,0.650 ,0.700 - , 0.7194 ,0.7388 ,0.7581 ,0.7775 ,0.7969 ,0.8163 ,0.8356, 0.8550 - , 0.8738 ,0.8925 ,0.9113 ,0.9300 ,0.9488 ,0.9675 ,0.9863, 1.0050}; - std::vector zLev2(Z_VALS_2,Z_VALS_2+NB_OF_CELL_AXIAL_2+1); - std::map > m; - Edge::Interpolate1DLin(zLev1,zLev2,m); - CPPUNIT_ASSERT_EQUAL(30,(int)m.size()); - double ret=0; - for(int i=0;i<30;i++) - { - CPPUNIT_ASSERT_EQUAL(1,(int)m[i].size()); - CPPUNIT_ASSERT(m[i][8+i] > 0.15); - ret+=m[i][8+i]; - } - CPPUNIT_ASSERT_DOUBLES_EQUAL(ret,30.,1e-12); - // - m.clear(); - const int NB_OF_CELL_AXIAL_3=13; - static const double Z_VALS_3[NB_OF_CELL_AXIAL_3+1]={ - 0.,0.01,0.05,0.10,0.15,0.20,0.25,0.30, - 0.35,0.40,0.45,0.50,0.55,0.60 }; - std::vector zLev3(Z_VALS_3,Z_VALS_3+NB_OF_CELL_AXIAL_3+1); - Edge::Interpolate1DLin(zLev3,zLev1,m); - CPPUNIT_ASSERT_EQUAL(13,(int)m.size()); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,m[0][8],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,m[1][8],1e-12); - for(int i=0;i<11;i++) - { - CPPUNIT_ASSERT_EQUAL(1,(int)m[i+2].size()); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,m[i+2][i+9],1e-12); - } - QUADRATIC_PLANAR::setPrecision(1e-14); -} - -/*! - * This test looks if intersectors are in coherency. - */ -void QuadraticPlanarInterpTest::checkEpsilonCoherency1() -{ - INTERP_KERNEL::QUADRATIC_PLANAR::setPrecision(1e-12); - INTERP_KERNEL::QUADRATIC_PLANAR::setArcDetectionPrecision(1e-5); - - const double pol1[]={ - -2.1083388455000001, 1.2172499999999999, - -1.7320508075000001, 1, - -1.9201948265, 1.108625 - }; - - const double pol2[]={ - -2.2379999998, 0, - -1.9381648534, 1.1189999998, - -2.1617419990000002, 0.57923702298000002, - -1.9381648534, 1.1189999998, - -1.9909924031999999, 1.1494999999, - -1.9645786283, 1.1342499998 - }; - // - Node *n1=new Node(pol1[0],pol1[1]); - Node *n2=new Node(pol1[2],pol1[3]); - Node *n3; - // - Edge *e1=new EdgeLin(n1,n2); n1->decrRef(); n2->decrRef(); - n1=new Node(pol2[0],pol2[1]); - n2=new Node(pol2[4],pol2[5]); - n3=new Node(pol2[2],pol2[3]); - Edge *e2=new EdgeArcCircle(n1,n2,n3); n1->decrRef(); n2->decrRef(); n3->decrRef(); - e2->decrRef(); - e1->decrRef(); -} - -/*! - * Tests to avoid regressions : Basic one. - */ -void QuadraticPlanarInterpTest::checkNonRegression1() -{ - const double coords1[]= - { - 16.1732057215, -25.110999999800001, - 16.02555485246479, -25.340997988918762 - }; - Node *nS1=new Node(coords1); - Node *nE1=new Node(coords1+2); - const double radius1=2.902; - const double angleS1=-0.49999999950907054; const double angleL1=-0.0942156629996692; - const double center1[2]={13.66, -23.66}; - EdgeArcCircle *e1=new EdgeArcCircle(nS1,nE1,center1,radius1,angleS1,angleL1); - // - const double coords2[]= - { - 16.041579804000001, -25.350249998999999, - 16.367740958999999, -24.132999999999999 - }; - Node *nS2=new Node(coords2); - Node *nE2=new Node(coords2+2); - const double radius2=2.4345; - const double angleS2=-0.523598776190207; const double angleL2=0.5235987755846041; - const double center2[]={ 13.933240960547204, -24.132999998525658 }; - EdgeArcCircle *e2=new EdgeArcCircle(nS2,nE2,center2,radius2,angleS2,angleL2); - MergePoints merge; - QuadraticPolygon c1,c2; - e1->intersectWith(e2,merge,c1,c2); - CPPUNIT_ASSERT_EQUAL(2,c1.size()); CPPUNIT_ASSERT_EQUAL(2,c2.size()); - CPPUNIT_ASSERT_DOUBLES_EQUAL(e1->getCurveLength(),c1.getPerimeter(),1e-5); - //clean-up - nS1->decrRef(); nE1->decrRef(); nS2->decrRef(); nE2->decrRef(); e1->decrRef(); e2->decrRef(); -} - -void QuadraticPlanarInterpTest::checkNonRegression2() -{ - QUADRATIC_PLANAR::setPrecision(1e-12); - QUADRATIC_PLANAR::setArcDetectionPrecision(1e-9); - double coords1[]= - { - 15.141499999899999, -26.226033271399999, - 16.226033271199999, -25.141499999800001, - 16.1732057215, -25.110999999800001, - 15.110999999899999, -26.1732057217, - 15.755157392699999, -25.755157392499999, - 16.199619496299999, -25.126249999799999, - 15.7120238788, -25.712023879099998, - 15.126249999899999, -26.199619496499999 - }; - double coords2[]= - { - 15.933240959000001, -24.132999999999999, - 15.665291765999999, -25.132999998999999, - 16.041579804000001, -25.350249998999999, - 16.367740958999999, -24.132999999999999, - 15.865092611, -24.650638091000001, - 15.853435785, -25.241624998999999, - 16.284787383000001, -24.763094964, - 16.150490958999999, -24.132999999999999 - }; - std::vector nodes1; - nodes1.push_back(new Node(coords1)); - nodes1.push_back(new Node(coords1+2)); - nodes1.push_back(new Node(coords1+4)); - nodes1.push_back(new Node(coords1+6)); - nodes1.push_back(new Node(coords1+8)); - nodes1.push_back(new Node(coords1+10)); - nodes1.push_back(new Node(coords1+12)); - nodes1.push_back(new Node(coords1+14)); - QuadraticPolygon *pol1=QuadraticPolygon::BuildArcCirclePolygon(nodes1); - std::vector nodes2; - nodes2.push_back(new Node(coords2)); - nodes2.push_back(new Node(coords2+2)); - nodes2.push_back(new Node(coords2+4)); - nodes2.push_back(new Node(coords2+6)); - nodes2.push_back(new Node(coords2+8)); - nodes2.push_back(new Node(coords2+10)); - nodes2.push_back(new Node(coords2+12)); - nodes2.push_back(new Node(coords2+14)); - QuadraticPolygon *pol2=QuadraticPolygon::BuildArcCirclePolygon(nodes2); - std::vector v=pol1->intersectMySelfWith(*pol2); - CPPUNIT_ASSERT_EQUAL(1,(int)v.size()); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.00173945,v[0]->getArea(),1e-7); - delete v[0]; - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.00173945,pol1->intersectWith(*pol2),1e-7); - delete pol1; - delete pol2; -} - -/*! - * Tests to avoid regressions : Basic one. - */ -void QuadraticPlanarInterpTest::checkNonRegression3() -{ - const double coords1[]= - { - 10.962340811000001, -22.417749999000002, - 12.217990959, -21.162099852000001 - }; - Node *nS1=new Node(coords1); - Node *nE1=new Node(coords1+2); - const double radius1=3.4304999897666599; - const double angleS1=2.6179938783536514; const double angleL1=-0.52359877711901204; - const double center1[2]={13.933240950441375, -24.132999992807399}; - EdgeArcCircle *e1=new EdgeArcCircle(nS1,nE1,center1,radius1,angleS1,angleL1); - // - const double coords2[]= - { - 11.1467942784, -22.2090000002, - 11.0939667286, -22.178500000099998 - }; - Node *nS2=new Node(coords2); - Node *nE2=new Node(coords2+2); - EdgeLin *e2=new EdgeLin(nS2,nE2); - MergePoints merge; - QuadraticPolygon c1,c2; - CPPUNIT_ASSERT(e1->intersectWith(e2,merge,c1,c2)); - CPPUNIT_ASSERT_EQUAL(2,c1.size()); - CPPUNIT_ASSERT_EQUAL(2,c2.size()); - ElementaryEdge *tmp1=dynamic_cast(c1.front()); CPPUNIT_ASSERT(tmp1); - EdgeArcCircle *tmp2=dynamic_cast(tmp1->getPtr()); CPPUNIT_ASSERT(tmp2); - CPPUNIT_ASSERT_DOUBLES_EQUAL(2.6179938783536514,tmp2->getAngle0(),1e-14); - //clean-up - nS1->decrRef(); nE1->decrRef(); nS2->decrRef(); nE2->decrRef(); e1->decrRef(); e2->decrRef(); -} - -void QuadraticPlanarInterpTest::checkNonRegression4() -{ - QUADRATIC_PLANAR::setPrecision(1e-12); - QUADRATIC_PLANAR::setArcDetectionPrecision(1e-9); - double coords1[]= - { - 10.962340811000001, -22.417749999000002, - 12.217990959, -21.162099852000001, - 12.051990958999999, -20.874579418, - 10.674820377, -22.251749999000001, - 11.507511146000001, -21.707270185999999, - 12.134990959, -21.018339635, - 11.272751694, -21.472510735, - 10.818580594, -22.334749999 - }; - - double coords2[]= - { - 10.758000000199999, -23.66, - 11.1467942784, -22.2090000002, - 11.0939667286, -22.178500000099998, - 10.696999999999999, -23.66, - 10.856883252299999, -22.908907131159999, - 11.1203805035, -22.1937500001, - 10.797961776699999, -22.893119169449999, - 10.727500000099999, -23.66 - }; - std::vector nodes1; - nodes1.push_back(new Node(coords1)); - nodes1.push_back(new Node(coords1+2)); - nodes1.push_back(new Node(coords1+4)); - nodes1.push_back(new Node(coords1+6)); - nodes1.push_back(new Node(coords1+8)); - nodes1.push_back(new Node(coords1+10)); - nodes1.push_back(new Node(coords1+12)); - nodes1.push_back(new Node(coords1+14)); - QuadraticPolygon *pol1=QuadraticPolygon::BuildArcCirclePolygon(nodes1); - std::vector nodes2; - nodes2.push_back(new Node(coords2)); - nodes2.push_back(new Node(coords2+2)); - nodes2.push_back(new Node(coords2+4)); - nodes2.push_back(new Node(coords2+6)); - nodes2.push_back(new Node(coords2+8)); - nodes2.push_back(new Node(coords2+10)); - nodes2.push_back(new Node(coords2+12)); - nodes2.push_back(new Node(coords2+14)); - QuadraticPolygon *pol2=QuadraticPolygon::BuildArcCirclePolygon(nodes2); - std::vector v=pol1->intersectMySelfWith(*pol2); - CPPUNIT_ASSERT_EQUAL(1,(int)v.size()); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.00164773941455998,v[0]->getArea(),1e-7); - delete v[0]; - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.00164773941455998,pol1->intersectWith(*pol2),1e-7); - delete pol1; - delete pol2; -} - -void QuadraticPlanarInterpTest::checkNonRegression5() -{ - INTERP_KERNEL::QUADRATIC_PLANAR::setPrecision(1e-12); - INTERP_KERNEL::QUADRATIC_PLANAR::setArcDetectionPrecision(1e-5); - double coords1[]= - { - -1.7320508075000001, 1, - -1, 1.7320508075000001 , - -1.2172499999999999, 2.1083388455000001, - -2.1083388455000001, 1.2172499999999999, - -1.4142135623000001, 1.4142135623000001, - -1.108625, 1.9201948265, - -1.7214514588000001, 1.7214514588000001, - -1.9201948265, 1.108625}; - - double coords2[]= - { - -2.2379999998, 0, - -1.9381648534, 1.1189999998, - -1.9909924031999999, 1.1494999999, - -2.2989999998999999, 0, - -2.1617419990000002, 0.57923702298000002, - -1.9645786283, 1.1342499998, - -2.2206634745999998, 0.59502498461999997, - -2.2684999997999999, 0}; - //Edge1_of_pol2 inter Edge4_of_pol1 = {-1.9381648533711939, 1.1189999998498941} - //Edge4_of_pol1 _angle = -0.523598775922546, _angle0 = -3.1415926535897931, _radius = 2.2379999983074721, _center = {-1.4925279436059493e-09, 1.3300635705141101e-10}} - std::vector nodes1; - nodes1.push_back(new Node(coords1)); - nodes1.push_back(new Node(coords1+2)); - nodes1.push_back(new Node(coords1+4)); - nodes1.push_back(new Node(coords1+6)); - nodes1.push_back(new Node(coords1+8)); - nodes1.push_back(new Node(coords1+10)); - nodes1.push_back(new Node(coords1+12)); - nodes1.push_back(new Node(coords1+14)); - QuadraticPolygon *pol1=QuadraticPolygon::BuildArcCirclePolygon(nodes1); - std::vector nodes2; - nodes2.push_back(new Node(coords2)); - nodes2.push_back(new Node(coords2+2)); - nodes2.push_back(new Node(coords2+4)); - nodes2.push_back(new Node(coords2+6)); - nodes2.push_back(new Node(coords2+8)); - nodes2.push_back(new Node(coords2+10)); - nodes2.push_back(new Node(coords2+12)); - nodes2.push_back(new Node(coords2+14)); - QuadraticPolygon *pol2=QuadraticPolygon::BuildArcCirclePolygon(nodes2); - std::vector v=pol1->intersectMySelfWith(*pol2); - CPPUNIT_ASSERT_EQUAL(0,(int)v.size()); - //CPPUNIT_ASSERT_DOUBLES_EQUAL(0.00164773941455998,v[0]->getArea(),1e-7); - //delete v[0]; - //CPPUNIT_ASSERT_DOUBLES_EQUAL(0.00164773941455998,pol1->intersectWith(*pol2),1e-7); - delete pol1; - delete pol2; -} - -void QuadraticPlanarInterpTest::checkNonRegression6() -{ - QUADRATIC_PLANAR::setPrecision(1e-12); - QUADRATIC_PLANAR::setArcDetectionPrecision(1e-5); - double coords1[]= - { - 10.962340811000001, -22.417749999000002, - 12.217990959, -21.162099852000001, - 12.051990958999999, -20.874579418, - 10.674820377, -22.251749999000001, - 11.507511146000001, -21.707270185999999, - 12.134990959, -21.018339635, - 11.272751694, -21.472510735, - 10.818580594, -22.334749999 - }; - double coords2[]= - { 10.426, -23.66, - 10.859273844199999, -22.043000000100001, - 10.806446294799999, -22.012500000199999, - 10.3650000002, -23.66, - 10.536195877799999, -22.822979208099998, - 10.832860069499999, -22.027750000200001, - 10.477274402499999, -22.80719124657, - 10.3955000001, -23.66}; - std::vector nodes1; - nodes1.push_back(new Node(coords1)); - nodes1.push_back(new Node(coords1+2)); - nodes1.push_back(new Node(coords1+4)); - nodes1.push_back(new Node(coords1+6)); - nodes1.push_back(new Node(coords1+8)); - nodes1.push_back(new Node(coords1+10)); - nodes1.push_back(new Node(coords1+12)); - nodes1.push_back(new Node(coords1+14)); - QuadraticPolygon *pol1=QuadraticPolygon::BuildArcCirclePolygon(nodes1); - std::vector nodes2; - nodes2.push_back(new Node(coords2)); - nodes2.push_back(new Node(coords2+2)); - nodes2.push_back(new Node(coords2+4)); - nodes2.push_back(new Node(coords2+6)); - nodes2.push_back(new Node(coords2+8)); - nodes2.push_back(new Node(coords2+10)); - nodes2.push_back(new Node(coords2+12)); - nodes2.push_back(new Node(coords2+14)); - QuadraticPolygon *pol2=QuadraticPolygon::BuildArcCirclePolygon(nodes2); - std::vector v=pol1->intersectMySelfWith(*pol2); - CPPUNIT_ASSERT_EQUAL(1,(int)v.size()); - CPPUNIT_ASSERT_DOUBLES_EQUAL(v[0]->getArea(),0.0150659,1e-7); - delete v[0]; - delete pol1; - delete pol2; -} - -void QuadraticPlanarInterpTest::checkNonRegression7() -{ - QUADRATIC_PLANAR::setPrecision(1e-5); - QUADRATIC_PLANAR::setArcDetectionPrecision(1e-5); - double coords1[]= - { - -2., 0, - -1.7320508075000001, 1, - -2.1083388455000001, 1.2172499999999999, - -2.4344999999999999, 0, - -1.9318516525603098, 0.51763809027157182, - -1.9201948265, 1.108625, - -2.3515464241024469, 0.63009496529570408, - -2.2172499999999999, 0 - }; - double coords2[]= - { -2.3369999999000002, 0, - -2.0239013684999998, 1.1684999999000001, - -2.1927763221999998, 1.2659999998, - -2.5319999998, 0, - -2.2573686559260442, 0.60486010843437632, - -2.1083388453499996, 1.2172499998499999, - -2.445724191994314, 0.65532982205982326, - -2.4344999998499999, 0 }; - std::vector nodes1; - nodes1.push_back(new Node(coords1)); - nodes1.push_back(new Node(coords1+2)); - nodes1.push_back(new Node(coords1+4)); - nodes1.push_back(new Node(coords1+6)); - nodes1.push_back(new Node(coords1+8)); - nodes1.push_back(new Node(coords1+10)); - nodes1.push_back(new Node(coords1+12)); - nodes1.push_back(new Node(coords1+14)); - QuadraticPolygon *pol1=QuadraticPolygon::BuildArcCirclePolygon(nodes1); - std::vector nodes2; - nodes2.push_back(new Node(coords2)); - nodes2.push_back(new Node(coords2+2)); - nodes2.push_back(new Node(coords2+4)); - nodes2.push_back(new Node(coords2+6)); - nodes2.push_back(new Node(coords2+8)); - nodes2.push_back(new Node(coords2+10)); - nodes2.push_back(new Node(coords2+12)); - nodes2.push_back(new Node(coords2+14)); - QuadraticPolygon *pol2=QuadraticPolygon::BuildArcCirclePolygon(nodes2); - std::vector v=pol1->intersectMySelfWith(*pol2); - CPPUNIT_ASSERT_EQUAL(1,(int)v.size()); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.121795,v[0]->getArea(),1.e-6); - delete v[0]; - delete pol1; - delete pol2; -} - -void QuadraticPlanarInterpTest::checkNonRegression8() -{ - QUADRATIC_PLANAR::setPrecision(1e-3); - QUADRATIC_PLANAR::setArcDetectionPrecision(1e-5); - double coords1[]= - { - -13.933240959000001, -28.559499999, - -16.146490959000001, -27.966461449000001, - -16.383240958999998, -28.376524478, - -13.933240959000001, -29.032999999000001, - -15.078903461873765, -28.408670669106311, - -16.264865958999998, -28.1714929635, - -15.201454280317435, -28.866036547696734, - -13.933240959000001, -28.796249999 }; - double coords2[]= - { -16.382999999950002, -28.376524478457149, - -13.933000000014729, -29.03299999982551, - -13.93300000006697, -28.793999999915993, - -16.263500000000001, -28.169544407039268, - -15.201213320921273, -28.866036548734634, - -13.933000000040851, -28.913499999870751, - -15.139355569325469, -28.635180276305853, - -16.323249999975001, -28.273034442748209 }; - std::vector nodes1; - nodes1.push_back(new Node(coords1)); - nodes1.push_back(new Node(coords1+2)); - nodes1.push_back(new Node(coords1+4)); - nodes1.push_back(new Node(coords1+6)); - nodes1.push_back(new Node(coords1+8)); - nodes1.push_back(new Node(coords1+10)); - nodes1.push_back(new Node(coords1+12)); - nodes1.push_back(new Node(coords1+14)); - QuadraticPolygon *pol1=QuadraticPolygon::BuildArcCirclePolygon(nodes1); - std::vector nodes2; - nodes2.push_back(new Node(coords2)); - nodes2.push_back(new Node(coords2+2)); - nodes2.push_back(new Node(coords2+4)); - nodes2.push_back(new Node(coords2+6)); - nodes2.push_back(new Node(coords2+8)); - nodes2.push_back(new Node(coords2+10)); - nodes2.push_back(new Node(coords2+12)); - nodes2.push_back(new Node(coords2+14)); - QuadraticPolygon *pol2=QuadraticPolygon::BuildArcCirclePolygon(nodes2); - std::vector v=pol1->intersectMySelfWith(*pol2); - CPPUNIT_ASSERT_EQUAL(1,(int)v.size()); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.598232,v[0]->getArea(),1.e-6); - delete v[0]; - delete pol1; - delete pol2; -} - -void QuadraticPlanarInterpTest::checkNonRegression9() -{ - QUADRATIC_PLANAR::setPrecision(1e-7); - QUADRATIC_PLANAR::setArcDetectionPrecision(1e-8); - double coords1[]= - { - -0.04476229252902969, -0.085118027765365603, - -0.046952683430894329, -0.085704941238358354, - -0.046952683430894329, -0.088063823748058725, - -0.043582851274179504, -0.087160879944491371, - -0.045818853668170414, -0.085555669718918592, - -0.046952683430894329, -0.086884382493208526, - -0.045208329947517549, -0.087834175256748526, - -0.044172571901604597, -0.086139453854928494 }; - - double coords2[]= - { -0.05065868681155701, -0.087744551996665671, - -0.046951871439587615, -0.088737790182236015, - -0.046951871439683469, -0.088063823751059062, - -0.050321703596054014, -0.087160879946116557, - -0.0488706602695924, -0.08848517684025306, - -0.046951871439635542, -0.088400806966647538, - -0.048696224921445964, -0.087834175258503858, - -0.050490195203805516, -0.087452715971391121}; - - std::vector nodes1; - nodes1.push_back(new Node(coords1)); - nodes1.push_back(new Node(coords1+2)); - nodes1.push_back(new Node(coords1+4)); - nodes1.push_back(new Node(coords1+6)); - nodes1.push_back(new Node(coords1+8)); - nodes1.push_back(new Node(coords1+10)); - nodes1.push_back(new Node(coords1+12)); - nodes1.push_back(new Node(coords1+14)); - QuadraticPolygon *pol1=QuadraticPolygon::BuildArcCirclePolygon(nodes1); - std::vector nodes2; - nodes2.push_back(new Node(coords2)); - nodes2.push_back(new Node(coords2+2)); - nodes2.push_back(new Node(coords2+4)); - nodes2.push_back(new Node(coords2+6)); - nodes2.push_back(new Node(coords2+8)); - nodes2.push_back(new Node(coords2+10)); - nodes2.push_back(new Node(coords2+12)); - nodes2.push_back(new Node(coords2+14)); - QuadraticPolygon *pol2=QuadraticPolygon::BuildArcCirclePolygon(nodes2); - std::vector v=pol1->intersectMySelfWith(*pol2); - CPPUNIT_ASSERT_EQUAL(0,(int)v.size()); - delete pol1; - delete pol2; -} - -void QuadraticPlanarInterpTest::checkNonRegression10() -{ - INTERP_KERNEL::QUADRATIC_PLANAR::setPrecision(1e-7); - INTERP_KERNEL::QUADRATIC_PLANAR::setArcDetectionPrecision(1e-7); - double coords1[]= - { -0.002269581957210453, -0.09851030343724453, - -0.004268022334182935, -0.1059685844580936, - -0.002777851483521377, -0.1023709937816271}; - double coords2[]= - { -0.004114727297178323, -0.1049870239624718, - -0.003544545103522544, -0.1053162188055505}; - Node *n1_1=new Node(coords1); - Node *n2_1=new Node(coords1+2); - Node *n3_1=new Node(coords1+4); - Node *n1_2=new Node(coords2); - Node *n2_2=new Node(coords2+2); - EdgeArcCircle *e1=new EdgeArcCircle(n1_1,n3_1,n2_1); - EdgeLin *e2=new EdgeLin(n1_2,n2_2); - MergePoints merge; - ComposedEdge *c1=new ComposedEdge; - ComposedEdge *c2=new ComposedEdge; - CPPUNIT_ASSERT(e1->intersectWith(e2,merge,*c1,*c2)); - CPPUNIT_ASSERT_EQUAL(2,c1->size()); - CPPUNIT_ASSERT_EQUAL(2,c2->size()); - ComposedEdge::Delete(c1); ComposedEdge::Delete(c2); - n1_1->decrRef(); n2_1->decrRef(); n3_1->decrRef(); - n1_2->decrRef(); n2_2->decrRef(); - e1->decrRef(); e2->decrRef(); -} - -void QuadraticPlanarInterpTest::checkNonRegression11() -{ - INTERP_KERNEL::QUADRATIC_PLANAR::setPrecision(1e-7); - INTERP_KERNEL::QUADRATIC_PLANAR::setArcDetectionPrecision(1e-7); - double coords1[]= - { -0.002269581957210453, -0.09851030343724453, - -0.004268022334182935, -0.1059685844580936, - -0.002886178753789801, -0.1067663922211958, - -0.0006739664310059821, -0.09851030343724453, - -0.002777851483521377, -0.1023709937816271, - -0.003577100543986368, -0.1063674883396447, - -0.001236605237717319, -0.1027839694676665, - -0.001471774194108217, -0.09851030343724453}; - double coords2[]= - { -0.003544545103522544, -0.1053162188055505, - -0.001941023322604723, -0.09851030343724451, - -0.002598140593501099, -0.09851030343724451, - -0.004114727297178323, -0.1049870239624718, - -0.002347317802266182, -0.1020064358043286, - -0.002269581958052911, -0.09851030343724451, - -0.002982346712452072, -0.1018362598405457, - -0.003829636200350435, -0.1051516213840111}; - - std::vector nodes1; - nodes1.push_back(new Node(coords1)); - nodes1.push_back(new Node(coords1+2)); - nodes1.push_back(new Node(coords1+4)); - nodes1.push_back(new Node(coords1+6)); - nodes1.push_back(new Node(coords1+8)); - nodes1.push_back(new Node(coords1+10)); - nodes1.push_back(new Node(coords1+12)); - nodes1.push_back(new Node(coords1+14)); - QuadraticPolygon *pol1=QuadraticPolygon::BuildArcCirclePolygon(nodes1); - std::vector nodes2; - nodes2.push_back(new Node(coords2)); - nodes2.push_back(new Node(coords2+2)); - nodes2.push_back(new Node(coords2+4)); - nodes2.push_back(new Node(coords2+6)); - nodes2.push_back(new Node(coords2+8)); - nodes2.push_back(new Node(coords2+10)); - nodes2.push_back(new Node(coords2+12)); - nodes2.push_back(new Node(coords2+14)); - QuadraticPolygon *pol2=QuadraticPolygon::BuildArcCirclePolygon(nodes2); - std::vector v=pol1->intersectMySelfWith(*pol2); - CPPUNIT_ASSERT_EQUAL(1,(int)v.size()); - CPPUNIT_ASSERT_DOUBLES_EQUAL(2.28973e-06,v[0]->getArea(),1.e-11); - delete v[0]; - delete pol1; - delete pol2; -} - -void QuadraticPlanarInterpTest::checkNonRegression12() -{ - INTERP_KERNEL::QUADRATIC_PLANAR::setPrecision(1e-6); - INTERP_KERNEL::QUADRATIC_PLANAR::setArcDetectionPrecision(1e-7); - double coords1[]= - { -0.5032251558760915, -0.8716087994449138, - -0.4695268343089433, -0.8806382374805872, - -0.4695268343089433, -0.8570494123835835, - -0.4914307433275896, -0.8511802776536561, - -0.4869703691141082, -0.8783417525751493, - -0.4695268343089433, -0.8688438249320853, - -0.480865131947653, -0.8555566971861125, - -0.4973279496018406, -0.8613945385492849}; - - double coords2[]= - { -0.5065868681155701, -0.8774455199666568, - -0.4695187143958762, -0.8873779018223601, - -0.4695187143968347, -0.8806382375105907, - -0.5032170359605401, -0.8716087994611657, - -0.488706602695924, -0.8848517684025307, - -0.4695187143963554, -0.8840080696664754, - -0.4869622492144596, -0.8783417525850385, - -0.5049019520380551, -0.8745271597139112}; - - std::vector nodes1; - nodes1.push_back(new Node(coords1)); - nodes1.push_back(new Node(coords1+2)); - nodes1.push_back(new Node(coords1+4)); - nodes1.push_back(new Node(coords1+6)); - nodes1.push_back(new Node(coords1+8)); - nodes1.push_back(new Node(coords1+10)); - nodes1.push_back(new Node(coords1+12)); - nodes1.push_back(new Node(coords1+14)); - QuadraticPolygon *pol1=QuadraticPolygon::BuildArcCirclePolygon(nodes1); - std::vector nodes2; - nodes2.push_back(new Node(coords2)); - nodes2.push_back(new Node(coords2+2)); - nodes2.push_back(new Node(coords2+4)); - nodes2.push_back(new Node(coords2+6)); - nodes2.push_back(new Node(coords2+8)); - nodes2.push_back(new Node(coords2+10)); - nodes2.push_back(new Node(coords2+12)); - nodes2.push_back(new Node(coords2+14)); - QuadraticPolygon *pol2=QuadraticPolygon::BuildArcCirclePolygon(nodes2); - std::vector v=pol1->intersectMySelfWith(*pol2); - CPPUNIT_ASSERT_EQUAL(1,(int)v.size()); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.,v[0]->getArea(),1.e-6); - delete v[0]; - delete pol1; - delete pol2; -} - -void QuadraticPlanarInterpTest::checkNonRegression13() -{ - INTERP_KERNEL::QUADRATIC_PLANAR::setPrecision(1e-7); - INTERP_KERNEL::QUADRATIC_PLANAR::setArcDetectionPrecision(1e-6); - - double coords_1[194]={ - 0, 0, 0.304375, -7.454791178893722e-17, 0.2152256265236553, -0.2152256265236555, -5.591093384170291e-17, -0.304375, - -0.2152256265236555, -0.2152256265236554, -0.304375, 3.727395589446861e-17, -0.2152256265236554, 0.2152256265236554, 1.86369779472343e-17, 0.304375, - 0.2152256265236554, 0.2152256265236554, 0.60875, -1.490958235778744e-16, 0.5624116654162459, -0.2329585394522483, 0.4304512530473107, -0.4304512530473109, - 0.2329585394522485, -0.5624116654162458, -1.118218676834058e-16, -0.60875, -0.2329585394522482, -0.5624116654162459, -0.4304512530473109, -0.4304512530473108, - -0.5624116654162459, -0.2329585394522483, -0.60875, 7.454791178893722e-17, -0.5624116654162458, 0.2329585394522485, -0.4304512530473108, 0.4304512530473109, - -0.2329585394522484, 0.5624116654162458, 3.727395589446861e-17, 0.60875, 0.2329585394522485, 0.5624116654162458, 0.4304512530473109, 0.4304512530473108, - 0.5624116654162458, 0.2329585394522484, 0.913125, -2.236437353668116e-16, 0.645676879570966, -0.6456768795709663, -1.677328015251087e-16, -0.913125, - -0.6456768795709663, -0.6456768795709661, -0.913125, 1.118218676834058e-16, -0.6456768795709661, 0.6456768795709662, 5.591093384170291e-17, 0.913125, - 0.6456768795709662, 0.6456768795709661, 1.2175, -2.981916471557489e-16, 1.124823330832492, -0.4659170789044966, 0.8609025060946214, -0.8609025060946218, - 0.4659170789044971, -1.124823330832492, -2.236437353668116e-16, -1.2175, -0.4659170789044965, -1.124823330832492, -0.8609025060946218, -0.8609025060946216, - -1.124823330832492, -0.4659170789044967, -1.2175, 1.490958235778744e-16, -1.124823330832492, 0.465917078904497, -0.8609025060946216, 0.8609025060946217, - -0.4659170789044967, 1.124823330832492, 7.454791178893722e-17, 1.2175, 0.4659170789044969, 1.124823330832492, 0.8609025060946217, 0.8609025060946216, - 1.124823330832492, 0.4659170789044968, 1.521875, -3.727395589446861e-16, 1.076128132618277, -1.076128132618277, -2.795546692085146e-16, -1.521875, - -1.076128132618277, -1.076128132618277, -1.521875, 1.86369779472343e-16, -1.076128132618277, 1.076128132618277, 9.318488973617152e-17, 1.521875, - 1.076128132618277, 1.076128132618277, 1.82625, -4.472874707336233e-16, 1.687234996248738, -0.6988756183567448, 1.291353759141932, -1.291353759141933, - 0.6988756183567456, -1.687234996248737, -3.354656030502175e-16, -1.82625, -0.6988756183567447, -1.687234996248738, -1.291353759141933, -1.291353759141932, - -1.687234996248738, -0.6988756183567449, -1.82625, 2.236437353668116e-16, -1.687234996248737, 0.6988756183567454, -1.291353759141932, 1.291353759141932, - -0.6988756183567451, 1.687234996248737, 1.118218676834058e-16, 1.82625, 0.6988756183567453, 1.687234996248737, 1.291353759141932, 1.291353759141932, - 1.687234996248737, 0.6988756183567452, 2.130625, -5.218353825225606e-16, 1.506579385665588, -1.506579385665588, -3.913765368919204e-16, -2.130625, - -1.506579385665588, -1.506579385665588, -2.130625, 2.609176912612803e-16, -1.506579385665588, 1.506579385665588, 1.304588456306401e-16, 2.130625, - 1.506579385665588, 1.506579385665588, 2.435, -5.963832943114977e-16, 2.249646661664984, -0.9318341578089931, 1.721805012189243, -1.721805012189244, - 0.9318341578089941, -2.249646661664983, -4.472874707336233e-16, -2.435, -0.9318341578089929, -2.249646661664984, -1.721805012189244, -1.721805012189243, - -2.249646661664984, -0.9318341578089934, -2.435, 2.981916471557489e-16, -2.249646661664983, 0.9318341578089939, -1.721805012189243, 1.721805012189243, - -0.9318341578089935, 2.249646661664983, 1.490958235778744e-16, 2.435, 0.9318341578089938, 2.249646661664983, 1.721805012189243, 1.721805012189243, - 2.249646661664983, 0.9318341578089936 }; - - int tab6_1[48]={ - 0, 9, 11, 1, 10, 2, 0, 11, 13, 2, 12, 3, 0, 13, 15, 3, 14, 4, 0, 15, - 17, 4, 16, 5, 0, 17, 19, 5, 18, 6, 0, 19, 21, 6, 20, 7, 0, 21, 23, 7, - 22, 8, 0, 23, 9, 8, 24, 1 }; - - int tab8_1[192]={ - 9, 33, 35, 11, 25, 34, 26, 10, 11, 35, 37, 13, 26, 36, 27, 12, 13, 37, 39, 15, - 27, 38, 28, 14, 15, 39, 41, 17, 28, 40, 29, 16, 17, 41, 43, 19, 29, 42, 30, 18, - 19, 43, 45, 21, 30, 44, 31, 20, 21, 45, 47, 23, 31, 46, 32, 22, 23, 47, 33, 9, - 32, 48, 25, 24, 33, 57, 59, 35, 49, 58, 50, 34, 35, 59, 61, 37, 50, 60, 51, 36, - 37, 61, 63, 39, 51, 62, 52, 38, 39, 63, 65, 41, 52, 64, 53, 40, 41, 65, 67, 43, - 53, 66, 54, 42, 43, 67, 69, 45, 54, 68, 55, 44, 45, 69, 71, 47, 55, 70, 56, 46, - 47, 71, 57, 33, 56, 72, 49, 48, 57, 81, 83, 59, 73, 82, 74, 58, 59, 83, 85, 61, - 74, 84, 75, 60, 61, 85, 87, 63, 75, 86, 76, 62, 63, 87, 89, 65, 76, 88, 77, 64, - 65, 89, 91, 67, 77, 90, 78, 66, 67, 91, 93, 69, 78, 92, 79, 68, 69, 93, 95, 71, - 79, 94, 80, 70, 71, 95, 81, 57, 80, 96, 73, 72 }; - - double coords_2[20]={ - 0.5159941860137611, 0, 0, -0.5159941860137611, -0.5159941860137611, 0, 0, 0.5159941860137611, - 0.6684941860137611, 0, 0, -0.6684941860137611, -0.6684941860137611, 0, 0, 0.6684941860137611, - 0.5922441860137611, 0, -0.5922441860137611, 0 }; - - int tab8_2[16]={ - 0, 4, 6, 2, 8, 5, 9, 1, 2, 6, 4, 0, 9, 7, 8, 3 }; - - double perimeterFromPol1,perimeterFromPol2,perimeterFromPol1AndPol2; - - const int *work1=tab6_1; - for(int i=0;i<8;i++,work1+=6) - { - QuadraticPolygon *pol1=buildQuadraticPolygonCoarseInfo(coords_1,work1,6); - const int *work2=tab8_2; - for(int j=0;j<2;j++,work2+=8) - { - QuadraticPolygon *pol2=buildQuadraticPolygonCoarseInfo(coords_2,work2,8); - //std::vector tmp; - //pol1->intersectForPoint(*pol2,tmp); - pol1->intersectForPerimeter(*pol2,perimeterFromPol1,perimeterFromPol2,perimeterFromPol1AndPol2); - //pol1->intersectMySelfWith(*pol2); - delete pol2; - } - delete pol1; - } - work1=tab8_1; - for(int i=0;i<24;i++,work1+=8) - { - QuadraticPolygon *pol1=buildQuadraticPolygonCoarseInfo(coords_1,work1,8); - const int *work2=tab8_2; - for(int j=0;j<2;j++,work2+=8) - { - - QuadraticPolygon *pol2=buildQuadraticPolygonCoarseInfo(coords_2,work2,8); - //std::vector tmp; - //pol1->intersectForPoint(*pol2,tmp); - pol1->intersectForPerimeter(*pol2,perimeterFromPol1,perimeterFromPol2,perimeterFromPol1AndPol2); - delete pol2; - } - delete pol1; - } -} - -/*! - Some overlapping cases for intersectForPoint. -*/ -void QuadraticPlanarInterpTest::checkNonRegression14() -{ - INTERP_KERNEL::QUADRATIC_PLANAR::setPrecision(1e-7); - INTERP_KERNEL::QUADRATIC_PLANAR::setArcDetectionPrecision(1e-6); - - double coords[72]={ - 1.,0.,1.3,0.,-1.3,0.,-1.,0.,1.15,0.,0.,1.3,-1.15,0.,0.,1., - -0.91923881554251186,-0.91923881554251186,-0.91923881554251186,0.91923881554251186,-1.0606601717798214,1.0606601717798214,-1.0606601717798214,-1.0606601717798214,-1.5,0., - -0.98994949366116658,-0.98994949366116658,-0.98994949366116658,0.98994949366116658, - 0.91923881554251186,0.91923881554251186,1.0606601717798214,1.0606601717798214,0.98994949366116658,0.98994949366116658, 0., 1.5, - -0.83562389259250125,0.99585777605467141, -0.65, 1.1258330249197703, -1.2216004070216808, 0.44462618632336953, -1.1258330249197703, 0.65, - -0.74564936725635955, 1.0648976575756897, -1.6770646146510724, 1.4072242996141826, -1.1782001231476449, 0.54940374026290939, -1.5873847317707279, 0.74020965686300877, - -1.1782001231476449, 0.54940374026290939, -1.0648976575756894, 0.74564936725635977, -1.2950531075192693, -0.11330246557195534, -1.2950531075192693, 0.11330246557195565, - -1.1258330249197703, 0.65, -2.1146554070041046, 0.56662020857685746, -1.6918048488667423, 0.45331774300490169, - 0.,-1.3,0.,-1.5 - }; - int tab[48]={ - 0,1,2,3,4,5,6,7, - 8,9,10,11,2,14,12,13, - 9,15,16,10,5,17,18,14, - 9,15,16,10,34,17,35,14, - 19,20,21,22,23,24,25,26, - 27,28,29,30,31,32,2,33 - }; - QuadraticPolygon *pol1,*pol2; - std::vector goalOfTest; - // - pol1=buildQuadraticPolygonCoarseInfo(coords,tab,8); - // Level 1 - pol2=buildQuadraticPolygonCoarseInfo(coords,tab+8,8); - pol1->intersectForPoint(*pol2,goalOfTest); - const int res1[4]={0,1,0,0}; - CPPUNIT_ASSERT_EQUAL(4,(int)goalOfTest.size()); - CPPUNIT_ASSERT(equal(goalOfTest.begin(),goalOfTest.end(),res1)); - delete pol2; - // Level 2 - pol2=buildQuadraticPolygonCoarseInfo(coords,tab+16,8); - pol1->intersectForPoint(*pol2,goalOfTest); - const int res2[4]={0,2,0,0}; - CPPUNIT_ASSERT_EQUAL(4,(int)goalOfTest.size()); - CPPUNIT_ASSERT(equal(goalOfTest.begin(),goalOfTest.end(),res2)); - delete pol2; - //Level 2 bis - pol2=buildQuadraticPolygonCoarseInfo(coords,tab+24,8); - pol1->intersectForPoint(*pol2,goalOfTest); - const int res2Bis[4]={0,2,0,0}; - CPPUNIT_ASSERT_EQUAL(4,(int)goalOfTest.size()); - CPPUNIT_ASSERT(equal(goalOfTest.begin(),goalOfTest.end(),res2Bis)); - delete pol2; - // Level 3 - pol2=buildQuadraticPolygonCoarseInfo(coords,tab+40,8); - pol1->intersectForPoint(*pol2,goalOfTest); - const int res3[4]={0,3,0,0}; - CPPUNIT_ASSERT_EQUAL(4,(int)goalOfTest.size()); - CPPUNIT_ASSERT(equal(goalOfTest.begin(),goalOfTest.end(),res3)); - delete pol2; - // Level 4 - pol2=buildQuadraticPolygonCoarseInfo(coords,tab+32,8); - pol1->intersectForPoint(*pol2,goalOfTest); - const int res4[4]={0,4,0,0}; - CPPUNIT_ASSERT_EQUAL(4,(int)goalOfTest.size()); - CPPUNIT_ASSERT(equal(goalOfTest.begin(),goalOfTest.end(),res4)); - delete pol2; - // - delete pol1; -} - -/*! - * This test is one of the most complicated intersection configuration. - */ -void QuadraticPlanarInterpTest::checkNonRegression15() -{ - INTERP_KERNEL::QUADRATIC_PLANAR::setPrecision(1e-7); - INTERP_KERNEL::QUADRATIC_PLANAR::setArcDetectionPrecision(1e-6); - - double coords[72]={ - 1.,0.,1.3,0.,-1.3,0.,-1.,0.,1.15,0.,0.,1.3,-1.15,0.,0.,1., - -0.91923881554251186,-0.91923881554251186,-0.91923881554251186,0.91923881554251186,-1.0606601717798214,1.0606601717798214,-1.0606601717798214,-1.0606601717798214,-1.5,0., - -0.98994949366116658,-0.98994949366116658,-0.98994949366116658,0.98994949366116658, - 0.91923881554251186,0.91923881554251186,1.0606601717798214,1.0606601717798214,0.98994949366116658,0.98994949366116658, 0., 1.5, - -0.83562389259250125,0.99585777605467141, -0.65, 1.1258330249197703, -1.2216004070216808, 0.44462618632336953, -1.1258330249197703, 0.65, - -0.74564936725635955, 1.0648976575756897, -1.6770646146510724, 1.4072242996141826, -1.1782001231476449, 0.54940374026290939, -1.5873847317707279, 0.74020965686300877, - -1.1782001231476449, 0.54940374026290939, -1.0648976575756894, 0.74564936725635977, -1.2950531075192693, -0.11330246557195534, -1.2950531075192693, 0.11330246557195565, - -1.1258330249197703, 0.65, -2.1146554070041046, 0.56662020857685746, -1.6918048488667423, 0.45331774300490169, - 0.,-1.3,0.,-1.5 - }; - - int tab[24]={ - 0,1,2,3,4,5,6,7, - 9,15,16,10,7,17,5,14, - 9,10,16,15,14,5,17,7 - }; - - const double RefLgth=3.88995883524451; - const double RefArea=0.383185168001075; - // - QuadraticPolygon *pol1,*pol2; - //pol1 and pol2 in same orientation - pol1=buildQuadraticPolygonCoarseInfo(coords,tab,8); - pol2=buildQuadraticPolygonCoarseInfo(coords,tab+8,8); - std::vector res=pol1->intersectMySelfWith(*pol2); - CPPUNIT_ASSERT_EQUAL(1,(int)res.size()); - CPPUNIT_ASSERT_EQUAL(4,res[0]->recursiveSize()); - CPPUNIT_ASSERT_DOUBLES_EQUAL(RefLgth,res[0]->getPerimeter(),1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(RefArea,res[0]->getArea(),1e-12); - delete res[0]; - //pol1 and pol2 in same orientation but inversing intersection call pol1<->pol2 - res=pol2->intersectMySelfWith(*pol1); - CPPUNIT_ASSERT_EQUAL(1,(int)res.size()); - CPPUNIT_ASSERT_EQUAL(4,res[0]->recursiveSize()); - CPPUNIT_ASSERT_DOUBLES_EQUAL(RefLgth,res[0]->getPerimeter(),1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(RefArea,res[0]->getArea(),1e-12); - delete res[0]; - delete pol2; - //pol1 and pol2 in opposite orientation - pol2=buildQuadraticPolygonCoarseInfo(coords,tab+16,8); - res=pol1->intersectMySelfWith(*pol2); - CPPUNIT_ASSERT_EQUAL(1,(int)res.size()); - CPPUNIT_ASSERT_EQUAL(4,res[0]->recursiveSize()); - CPPUNIT_ASSERT_DOUBLES_EQUAL(RefLgth,res[0]->getPerimeter(),1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(-RefArea,res[0]->getArea(),1e-12); - delete res[0]; - //pol1 and pol2 in opposite orientation but inversing intersection call pol1<->pol2 - res=pol2->intersectMySelfWith(*pol1); - CPPUNIT_ASSERT_EQUAL(1,(int)res.size()); - CPPUNIT_ASSERT_EQUAL(4,res[0]->recursiveSize()); - CPPUNIT_ASSERT_DOUBLES_EQUAL(RefLgth,res[0]->getPerimeter(),1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(RefArea,res[0]->getArea(),1e-12); - delete res[0]; - delete pol2; - // - delete pol1; -} - -class DoubleEqual -{ -public: - DoubleEqual(double eps):_eps(eps) { } - bool operator()(double x, double y) { return fabs(x-y)<_eps; } -private: - double _eps; -}; - -/*! - * This test is to see the reuse of a polygon in intersect* methods. initLocation needed ... - */ -void QuadraticPlanarInterpTest::checkNonRegression16() -{ - INTERP_KERNEL::QUADRATIC_PLANAR::setPrecision(1e-7); - INTERP_KERNEL::QUADRATIC_PLANAR::setArcDetectionPrecision(1e-7); - double coords1[194]={ - 0, 0, 0.304375, 0, 0.2152256265236554, 0.2152256265236554, 1.86369779472343e-17, 0.304375, - -0.2152256265236554, 0.2152256265236554, -0.304375, 3.727395589446861e-17, -0.2152256265236555, -0.2152256265236554, -5.591093384170291e-17, -0.304375, - 0.2152256265236553, -0.2152256265236555, 0.60875, 0, 0.5624116654162458, 0.2329585394522484, 0.4304512530473109, 0.4304512530473108, - 0.2329585394522485, 0.5624116654162458, 3.727395589446861e-17, 0.60875, -0.2329585394522484, 0.5624116654162458, -0.4304512530473108, 0.4304512530473109, - -0.5624116654162458, 0.2329585394522485, -0.60875, 7.454791178893722e-17, -0.5624116654162459, -0.2329585394522483, -0.4304512530473109, -0.4304512530473108, - -0.2329585394522482, -0.5624116654162459, -1.118218676834058e-16, -0.60875, 0.2329585394522485, -0.5624116654162458, 0.4304512530473107, -0.4304512530473109, - 0.5624116654162459, -0.2329585394522483, 0.913125, 0, 0.6456768795709662, 0.6456768795709661, 5.591093384170291e-17, 0.913125, - -0.6456768795709661, 0.6456768795709662, -0.913125, 1.118218676834058e-16, -0.6456768795709663, -0.6456768795709661, -1.677328015251087e-16, -0.913125, - 0.645676879570966, -0.6456768795709663, 1.2175, 0, 1.124823330832492, 0.4659170789044968, 0.8609025060946217, 0.8609025060946216, - 0.4659170789044969, 1.124823330832492, 7.454791178893722e-17, 1.2175, -0.4659170789044967, 1.124823330832492, -0.8609025060946216, 0.8609025060946217, - -1.124823330832492, 0.465917078904497, -1.2175, 1.490958235778744e-16, -1.124823330832492, -0.4659170789044967, -0.8609025060946218, -0.8609025060946216, - -0.4659170789044965, -1.124823330832492, -2.236437353668116e-16, -1.2175, 0.4659170789044971, -1.124823330832492, 0.8609025060946214, -0.8609025060946218, - 1.124823330832492, -0.4659170789044966, 1.521875, 0, 1.076128132618277, 1.076128132618277, 9.318488973617152e-17, 1.521875, - -1.076128132618277, 1.076128132618277, -1.521875, 1.86369779472343e-16, -1.076128132618277, -1.076128132618277, -2.795546692085146e-16, -1.521875, - 1.076128132618277, -1.076128132618277, 1.82625, 0, 1.687234996248737, 0.6988756183567452, 1.291353759141932, 1.291353759141932, - 0.6988756183567453, 1.687234996248737, 1.118218676834058e-16, 1.82625, -0.6988756183567451, 1.687234996248737, -1.291353759141932, 1.291353759141932, - -1.687234996248737, 0.6988756183567454, -1.82625, 2.236437353668116e-16, -1.687234996248738, -0.6988756183567449, -1.291353759141933, -1.291353759141932, - -0.6988756183567447, -1.687234996248738, -3.354656030502175e-16, -1.82625, 0.6988756183567456, -1.687234996248737, 1.291353759141932, -1.291353759141933, - 1.687234996248738, -0.6988756183567448, 2.130625, 0, 1.506579385665588, 1.506579385665588, 1.304588456306401e-16, 2.130625, - -1.506579385665588, 1.506579385665588, -2.130625, 2.609176912612803e-16, -1.506579385665588, -1.506579385665588, -3.913765368919204e-16, -2.130625, - 1.506579385665588, -1.506579385665588, 2.435, 0, 2.249646661664983, 0.9318341578089936, 1.721805012189243, 1.721805012189243, - 0.9318341578089938, 2.249646661664983, 1.490958235778744e-16, 2.435, -0.9318341578089935, 2.249646661664983, -1.721805012189243, 1.721805012189243, - -2.249646661664983, 0.9318341578089939, -2.435, 2.981916471557489e-16, -2.249646661664984, -0.9318341578089934, -1.721805012189244, -1.721805012189243, - -0.9318341578089929, -2.249646661664984, -4.472874707336233e-16, -2.435, 0.9318341578089941, -2.249646661664983, 1.721805012189243, -1.721805012189244, - 2.249646661664984, -0.9318341578089931, }; - - int tab1_8[192]={ - 11, 35, 33, 9, 26, 34, 25, 10, 13, 37, 35, 11, 27, 36, 26, 12, 15, 39, 37, 13, - 28, 38, 27, 14, 17, 41, 39, 15, 29, 40, 28, 16, 19, 43, 41, 17, 30, 42, 29, 18, - 21, 45, 43, 19, 31, 44, 30, 20, 23, 47, 45, 21, 32, 46, 31, 22, 9, 33, 47, 23, - 25, 48, 32, 24, 35, 59, 57, 33, 50, 58, 49, 34, 37, 61, 59, 35, 51, 60, 50, 36, - 39, 63, 61, 37, 52, 62, 51, 38, 41, 65, 63, 39, 53, 64, 52, 40, 43, 67, 65, 41, - 54, 66, 53, 42, 45, 69, 67, 43, 55, 68, 54, 44, 47, 71, 69, 45, 56, 70, 55, 46, - 33, 57, 71, 47, 49, 72, 56, 48, 59, 83, 81, 57, 74, 82, 73, 58, 61, 85, 83, 59, - 75, 84, 74, 60, 63, 87, 85, 61, 76, 86, 75, 62, 65, 89, 87, 63, 77, 88, 76, 64, - 67, 91, 89, 65, 78, 90, 77, 66, 69, 93, 91, 67, 79, 92, 78, 68, 71, 95, 93, 69, - 80, 94, 79, 70, 57, 81, 95, 71, 73, 96, 80, 72, }; - - double coords2[20]={ - 2.435, 0, 0, -2.435, -2.435, 0, 0, 2.435, - 2.6925, 0, 0, -2.6925, -2.6925, 0, 0, 2.6925, - 2.56375, 0, -2.56375, 0, }; - - int tab2_8[16]={ 0, 4, 6, 2, 8, 5, 9, 1, 2, 6, 4, 0, 9, 7, 8, 3 }; - - QuadraticPolygon *pol1,*pol2; - //pol1 and pol2 in same orientation - std::vector test1,test2; - for(int ii=0;ii<24;ii++) - { - pol1=buildQuadraticPolygonCoarseInfo(coords1,tab1_8+8*ii,8); - for(int jj=0;jj<2;jj++) - { - pol2=buildQuadraticPolygonCoarseInfo(coords2,tab2_8+jj*8,8); - // - std::vector v1,v2; - pol1->initLocations(); - pol1->intersectForPerimeterAdvanced(*pol2,v1,v2); - if(ii==16 && jj==1) - test1=v1; - if(ii==20 && jj==1) - test2=v1; - delete pol2; - } - delete pol1; - } - const double test1_res[4]={0.,1.9124445278727873,0.,0.}; - CPPUNIT_ASSERT(std::equal(test1.begin(),test1.end(),test1_res,DoubleEqual(1e-10))); - const double test2_res[4]={0.,0.,0.,0.}; - CPPUNIT_ASSERT(std::equal(test2.begin(),test2.end(),test2_res,DoubleEqual(1e-10))); -} - -/*! - * This test checks overlapped intersections END-INSIDE and INSIDE-START with same and opposite orientation. - */ -void QuadraticPlanarInterpTest::checkNonRegression17() -{ - INTERP_KERNEL::QUADRATIC_PLANAR::setPrecision(1e-7); - INTERP_KERNEL::QUADRATIC_PLANAR::setArcDetectionPrecision(1e-7); - double coords[16]={ - -1., 0., 1., 0. , 1.5, 0., -1.5, 0., - 0. , 1., 1.25, 0., 0., 1.5, -1.25, 0.}; - - double coords2[16]={ - 0.70710678118654757, 0.70710678118654757, -1., 0., -1.25, 0., 0.88388347648318444, 0.88388347648318444, - 0., -1., -1.125, 0., 0., -1.25, 0.79549512883486606, 0.79549512883486606 }; - - double coords3[16]={ - 0.70710678118654757, 0.70710678118654757, 0.88388347648318444, 0.88388347648318444, -1.25, 0., -1., 0., - 0.79549512883486606, 0.79549512883486606, 0., -1.25, -1.125, 0., 0., -1. }; - - int tab8[8]={ - 0, 1, 2, 3, 4, 5, 6, 7 }; - QuadraticPolygon *pol1=buildQuadraticPolygonCoarseInfo(coords,tab8,8); - QuadraticPolygon *pol2=buildQuadraticPolygonCoarseInfo(coords2,tab8,8); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.22089323345553233,pol1->intersectWith(*pol2),1.e-13); - delete pol1; - delete pol2; - pol1=buildQuadraticPolygonCoarseInfo(coords,tab8,8); - pol2=buildQuadraticPolygonCoarseInfo(coords2,tab8,8); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.22089323345553233,pol2->intersectWith(*pol1),1.e-13); - delete pol1; - delete pol2; - pol1=buildQuadraticPolygonCoarseInfo(coords,tab8,8); - pol2=buildQuadraticPolygonCoarseInfo(coords3,tab8,8); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.22089323345553233,pol1->intersectWith(*pol2),1.e-13); - delete pol1; - delete pol2; - pol1=buildQuadraticPolygonCoarseInfo(coords,tab8,8); - pol2=buildQuadraticPolygonCoarseInfo(coords3,tab8,8); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.22089323345553233,pol2->intersectWith(*pol1),1.e-13); - delete pol1; - delete pol2; -} - -void QuadraticPlanarInterpTest::checkNormalize() -{ - INTERP_KERNEL::QUADRATIC_PLANAR::setPrecision(1e-14); - Node *n1=new Node(0.,0.); Node *n4=new Node(0.,-3.); - Node *n2=new Node(10.,0.); Node *n5=new Node(10.,-3.); - Node *n3=new Node(5.,10.); Node *n6=new Node(5.,7.); - EdgeLin *e1_2=new EdgeLin(n1,n2); EdgeLin *e4_5=new EdgeLin(n4,n5); - EdgeLin *e2_3=new EdgeLin(n2,n3); EdgeLin *e5_6=new EdgeLin(n5,n6); - EdgeLin *e3_1=new EdgeLin(n3,n1); EdgeLin *e6_4=new EdgeLin(n6,n4); - // - QuadraticPolygon pol1; pol1.pushBack(e1_2); pol1.pushBack(e2_3); pol1.pushBack(e3_1); - QuadraticPolygon pol2; pol2.pushBack(e4_5); pol2.pushBack(e5_6); pol2.pushBack(e6_4); - n1->decrRef(); n2->decrRef(); n3->decrRef(); n4->decrRef(); n5->decrRef(); n6->decrRef(); - double area1Start=pol1.getArea(); - double xb,yb; - double fact=pol1.normalize(&pol2,xb,yb); - double area1End=pol1.getArea(); - CPPUNIT_ASSERT_DOUBLES_EQUAL(area1Start,area1End*fact*fact,1e-14); - CPPUNIT_ASSERT_DOUBLES_EQUAL(13.,fact,1.e-14); - double area=pol1.intersectWith(pol2); - CPPUNIT_ASSERT_DOUBLES_EQUAL(24.5,area*fact*fact,1e-14); - // - n1=new Node(0.,0.); n4=new Node(0.,-3.); - n2=new Node(10.,0.); n5=new Node(10.,-3.); - n3=new Node(5.,10.); n6=new Node(5.,7.); - e1_2=new EdgeLin(n1,n2); e4_5=new EdgeLin(n4,n5); - e2_3=new EdgeLin(n2,n3); e5_6=new EdgeLin(n5,n6); - e3_1=new EdgeLin(n3,n1); e6_4=new EdgeLin(n6,n4); - QuadraticPolygon pol3; pol3.pushBack(e1_2); pol3.pushBack(e2_3); pol3.pushBack(e3_1); - QuadraticPolygon pol4; pol4.pushBack(e4_5); pol4.pushBack(e5_6); pol4.pushBack(e6_4); - n1->decrRef(); n2->decrRef(); n3->decrRef(); n4->decrRef(); n5->decrRef(); n6->decrRef(); - CPPUNIT_ASSERT_DOUBLES_EQUAL(24.5,pol3.intersectWithAbs(pol4),1.e-14); - // Ok testing EdgeArcCircle update. - double center[2]={5.,5.}; - double radius=300.; - EdgeArcCircle *e1=buildArcOfCircle(center,radius,M_PI/4.,M_PI/3.); - const Bounds& b=e1->getBounds(); - double x,y,fact2; - fact2=b.getCaracteristicDim(); - b.getBarycenter(x,y); - CPPUNIT_ASSERT_DOUBLES_EQUAL(78.539816339744817,e1->getCurveLength(),1e-13); - CPPUNIT_ASSERT_DOUBLES_EQUAL(15106.061037591669,e1->getAreaOfZone(),1e-10); - e1->getStartNode()->applySimilarity(x,y,fact2); - e1->getEndNode()->applySimilarity(x,y,fact2); - e1->applySimilarity(x,y,fact2); - CPPUNIT_ASSERT_DOUBLES_EQUAL(62.132034355964237,fact2,1e-13); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1.2640792652913602,e1->getCurveLength(),1e-14); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.034741420428165526,e1->getAreaOfZone(),1e-13); - e1->decrRef(); -} - -void QuadraticPlanarInterpTest::checkMakePartitionAbs1() -{ - INTERP_KERNEL::QUADRATIC_PLANAR::setPrecision(1e-14); - Node *n0=new Node(0.,0.); Node *n4=new Node(0.5,0.25); - Node *n1=new Node(0.,0.5); Node *n5=new Node(0.3,1.2); - Node *n2=new Node(1.,0.5); Node *n6=new Node(1.1,1.3); - Node *n3=new Node(1.,0.); Node *n7=new Node(-0.1,0.9); - EdgeLin *e0_1=new EdgeLin(n0,n1); - EdgeLin *e1_2=new EdgeLin(n1,n2); EdgeLin *e4_5=new EdgeLin(n4,n5); - EdgeLin *e2_3=new EdgeLin(n2,n3); EdgeLin *e5_6=new EdgeLin(n5,n6); - EdgeLin *e3_0=new EdgeLin(n3,n0); EdgeLin *e6_4=new EdgeLin(n6,n4); - EdgeLin *e4_7=new EdgeLin(n4,n7); EdgeLin *e7_5=new EdgeLin(n7,n5); - QuadraticPolygon pol1; pol1.pushBack(e0_1); pol1.pushBack(e1_2); pol1.pushBack(e2_3); pol1.pushBack(e3_0); - QuadraticPolygon pol2; pol2.pushBack(e4_5); pol2.pushBack(e5_6); pol2.pushBack(e6_4); - pol2.pushBack(e7_5); e4_5->incrRef(); pol2.pushBack(new ElementaryEdge(e4_5,false)); pol2.pushBack(e4_7); - n0->decrRef(); n1->decrRef(); n2->decrRef(); n3->decrRef(); n4->decrRef(); n5->decrRef(); n6->decrRef(); n7->decrRef(); - pol1.dumpInXfigFileWithOther(pol2,"tony.fig"); -} - -} diff --git a/src/INTERP_KERNELTest/QuadraticPlanarInterpTest5.cxx b/src/INTERP_KERNELTest/QuadraticPlanarInterpTest5.cxx deleted file mode 100644 index 615969ffb..000000000 --- a/src/INTERP_KERNELTest/QuadraticPlanarInterpTest5.cxx +++ /dev/null @@ -1,1286 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 -// 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 "QuadraticPlanarInterpTest.hxx" -#include "InterpKernelGeo2DQuadraticPolygon.hxx" -#include "InterpKernelGeo2DElementaryEdge.hxx" -#include "InterpKernelGeo2DEdgeArcCircle.hxx" -#include "InterpKernelGeo2DEdgeLin.hxx" - -#include -#include -#include -#include - -using namespace INTERP_KERNEL; - -namespace INTERP_TEST -{ - -class DoubleEqual -{ -public: - DoubleEqual(double eps):_eps(eps) { } - bool operator()(double x, double y) { return fabs(x-y)<_eps; } -private: - double _eps; -}; - -void QuadraticPlanarInterpTest::checkNonRegressionOmar0000() -{ - INTERP_KERNEL::QUADRATIC_PLANAR::setPrecision(1e-7); - INTERP_KERNEL::QUADRATIC_PLANAR::setArcDetectionPrecision(1e-7); - double coords[16]={ - -0.383022221559489, 0.3213938048432697, -0.5745333323392334, 0.4820907072649046, 0.5745333323392335, 0.4820907072649044, 0.383022221559489, 0.3213938048432696, - -0.4787777769493612, 0.4017422560540872, 4.592273826833915e-17, 0.75, 0.4787777769493612, 0.401742256054087, 3.061515884555943e-17, 0.5 }; - - double coords2[16]={ - -0.383022221559489, -0.1786061951567303, -0.5745333323392334, -0.01790929273509539, 0.5745333323392335, -0.01790929273509556, 0.383022221559489, -0.1786061951567304, - -0.4787777769493612, -0.0982577439459128, 4.592273826833915e-17, 0.25, 0.4787777769493612, -0.09825774394591297, 3.061515884555943e-17, 0 }; - - int tab8[8]={ - 0, 1, 2, 3, 4, 5, 6, 7 }; - QuadraticPolygon *pol1=buildQuadraticPolygonCoarseInfo(coords,tab8,8); - QuadraticPolygon *pol2=buildQuadraticPolygonCoarseInfo(coords2,tab8,8); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.,pol1->intersectWith(*pol2),1.e-13); - delete pol1; - delete pol2; - pol1=buildQuadraticPolygonCoarseInfo(coords,tab8,8); - pol2=buildQuadraticPolygonCoarseInfo(coords2,tab8,8); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.,pol2->intersectWith(*pol1),1.e-13); - delete pol1; - delete pol2; -} - -void QuadraticPlanarInterpTest::checkNonRegressionOmar0001() -{ - INTERP_KERNEL::QUADRATIC_PLANAR::setPrecision(1e-7); - INTERP_KERNEL::QUADRATIC_PLANAR::setArcDetectionPrecision(1e-7); - double coords[16]={ - -0.383022221559489, 0.3213938048432697, -0.5745333323392334, 0.4820907072649046, 0.5745333323392335, 0.4820907072649044, 0.383022221559489, 0.3213938048432696, - -0.4787777769493612, 0.4017422560540872, 4.592273826833915e-17, 0.75, 0.4787777769493612, 0.401742256054087, 3.061515884555943e-17, 0.5 }; - - double coords2[16]={ - -0.383022221559489, 0.3213938048432697, -0.5745333323392334, 0.4820907072649046, 0.5745333323392335, 0.4820907072649044, 0.383022221559489, 0.3213938048432696, - -0.4787777769493612, 0.4017422560540872, 4.592273826833915e-17, 0.75, 0.4787777769493612, 0.401742256054087, 3.061515884555943e-17, 0.5 }; - - int tab8[8]={ - 0, 1, 2, 3, 4, 5, 6, 7 }; - QuadraticPolygon *pol1=buildQuadraticPolygonCoarseInfo(coords,tab8,8); - QuadraticPolygon *pol2=buildQuadraticPolygonCoarseInfo(coords2,tab8,8); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.272708,pol1->intersectWith(*pol2),1.e-6); - delete pol1; - delete pol2; - pol1=buildQuadraticPolygonCoarseInfo(coords,tab8,8); - pol2=buildQuadraticPolygonCoarseInfo(coords2,tab8,8); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.272708,pol2->intersectWith(*pol1),1.e-6); - delete pol1; - delete pol2; -} - -void QuadraticPlanarInterpTest::checkNonRegressionOmar0002() -{ - INTERP_KERNEL::QUADRATIC_PLANAR::setPrecision(1e-7); - INTERP_KERNEL::QUADRATIC_PLANAR::setArcDetectionPrecision(1e-7); - double coords[16]={ - -0.383022221559489, 0.3213938048432697, -0.5745333323392334, 0.4820907072649046, 0.5745333323392335, 0.4820907072649044, 0.383022221559489, 0.3213938048432696, - -0.4787777769493612, 0.4017422560540872, 4.592273826833915e-17, 0.75, 0.4787777769493612, 0.401742256054087, 3.061515884555943e-17, 0.5 }; - - double coords2[16]={ - -0.4979288880273356, 0.4178119462962507, -0.6128355544951823, 0.5142300877492316, 0.6128355544951825, 0.5142300877492314, 0.4979288880273357, 0.4178119462962505, - -0.555382221261259, 0.4660210170227412, 4.898425415289509e-17, 0.8, 0.5553822212612591, 0.466021017022741, 3.979970649922726e-17, 0.65 }; - - int tab8[8]={ - 0, 1, 2, 3, 4, 5, 6, 7 }; - QuadraticPolygon *pol1=buildQuadraticPolygonCoarseInfo(coords,tab8,8); - QuadraticPolygon *pol2=buildQuadraticPolygonCoarseInfo(coords2,tab8,8); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.122173,pol1->intersectWith(*pol2),1.e-6); - delete pol1; - delete pol2; - pol1=buildQuadraticPolygonCoarseInfo(coords,tab8,8); - pol2=buildQuadraticPolygonCoarseInfo(coords2,tab8,8); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.122173,pol2->intersectWith(*pol1),1.e-6); - delete pol1; - delete pol2; -} - -void QuadraticPlanarInterpTest::checkNonRegressionOmar0003() -{ - INTERP_KERNEL::QUADRATIC_PLANAR::setPrecision(1e-7); - INTERP_KERNEL::QUADRATIC_PLANAR::setArcDetectionPrecision(1e-7); - double coords[16]={ - -0.3535533905932737, 0.3535533905932738, -0.5303300858899106, 0.5303300858899107, 0.5303300858899107, 0.5303300858899106, 0.3535533905932738, 0.3535533905932737, - -0.4419417382415922, 0.4419417382415922, 4.592273826833915e-17, 0.75, 0.4419417382415922, 0.4419417382415922, 3.061515884555943e-17, 0.5 }; - - double coords2[16]={ - -0.4979288880273356, 0.4178119462962507, -0.6128355544951823, 0.5142300877492316, 0.6128355544951825, 0.5142300877492314, 0.4979288880273357, 0.4178119462962505, - -0.555382221261259, 0.4660210170227412, 4.898425415289509e-17, 0.8, 0.5553822212612591, 0.466021017022741, 3.979970649922726e-17, 0.65 }; - - int tab8[8]={ - 0, 1, 2, 3, 4, 5, 6, 7 }; - QuadraticPolygon *pol1=buildQuadraticPolygonCoarseInfo(coords,tab8,8); - QuadraticPolygon *pol2=buildQuadraticPolygonCoarseInfo(coords2,tab8,8); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.109956,pol1->intersectWith(*pol2),1.e-6); - delete pol1; - delete pol2; - pol1=buildQuadraticPolygonCoarseInfo(coords,tab8,8); - pol2=buildQuadraticPolygonCoarseInfo(coords2,tab8,8); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.109956,pol2->intersectWith(*pol1),1.e-6); - delete pol1; - delete pol2; -} - -void QuadraticPlanarInterpTest::checkNonRegressionOmar0004() -{ - INTERP_KERNEL::QUADRATIC_PLANAR::setPrecision(1e-7); - INTERP_KERNEL::QUADRATIC_PLANAR::setArcDetectionPrecision(1e-7); - double coords[16]={ - -0.4596194077712559, 0.4596194077712559, -0.5303300858899106, 0.5303300858899107, 0.5303300858899107, 0.5303300858899106, 0.4596194077712559, 0.4596194077712559, - -0.4949747468305832, 0.4949747468305833, 4.592273826833915e-17, 0.75, 0.4949747468305833, 0.4949747468305832, 3.979970649922726e-17, 0.65 }; - - double coords2[16]={ - -0.383022221559489, 0.3213938048432697, -0.6128355544951823, 0.5142300877492316, 0.6128355544951825, 0.5142300877492314, 0.383022221559489, 0.3213938048432696, - -0.4979288880273356, 0.4178119462962507, 4.898425415289509e-17, 0.8, 0.4979288880273357, 0.4178119462962505, 3.061515884555943e-17, 0.5 }; - - int tab8[8]={ - 0, 1, 2, 3, 4, 5, 6, 7 }; - QuadraticPolygon *pol1=buildQuadraticPolygonCoarseInfo(coords,tab8,8); - QuadraticPolygon *pol2=buildQuadraticPolygonCoarseInfo(coords2,tab8,8); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.109956,pol1->intersectWith(*pol2),1.e-6); - delete pol1; - delete pol2; - pol1=buildQuadraticPolygonCoarseInfo(coords,tab8,8); - pol2=buildQuadraticPolygonCoarseInfo(coords2,tab8,8); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.109956,pol2->intersectWith(*pol1),1.e-6); - delete pol1; - delete pol2; -} - -void QuadraticPlanarInterpTest::checkNonRegressionOmar0005() -{ - INTERP_KERNEL::QUADRATIC_PLANAR::setPrecision(1e-7); - INTERP_KERNEL::QUADRATIC_PLANAR::setArcDetectionPrecision(1e-7); - double coords[16]={ - -0.383022221559489, 0.3213938048432697, -0.6128355544951823, 0.5142300877492316, 0.6128355544951825, 0.5142300877492314, 0.383022221559489, 0.3213938048432696, - -0.4979288880273356, 0.4178119462962507, 4.898425415289509e-17, 0.8, 0.4979288880273357, 0.4178119462962505, 3.061515884555943e-17, 0.5 }; - - double coords2[16]={ - -0.4596194077712559, 0.4596194077712559, -0.5303300858899106, 0.5303300858899107, 0.5303300858899107, 0.5303300858899106, 0.4596194077712559, 0.4596194077712559, - -0.4949747468305832, 0.4949747468305833, 4.592273826833915e-17, 0.75, 0.4949747468305833, 0.4949747468305832, 3.979970649922726e-17, 0.65 }; - - int tab8[8]={ - 0, 1, 2, 3, 4, 5, 6, 7 }; - QuadraticPolygon *pol1=buildQuadraticPolygonCoarseInfo(coords,tab8,8); - QuadraticPolygon *pol2=buildQuadraticPolygonCoarseInfo(coords2,tab8,8); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.109956,pol1->intersectWith(*pol2),1.e-6); - delete pol1; - delete pol2; - pol1=buildQuadraticPolygonCoarseInfo(coords,tab8,8); - pol2=buildQuadraticPolygonCoarseInfo(coords2,tab8,8); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.109956,pol2->intersectWith(*pol1),1.e-6); - delete pol1; - delete pol2; -} - -void QuadraticPlanarInterpTest::checkNonRegressionOmar0006() -{ - INTERP_KERNEL::QUADRATIC_PLANAR::setPrecision(1e-7); - INTERP_KERNEL::QUADRATIC_PLANAR::setArcDetectionPrecision(1e-7); - double coords[16]={ - -0.383022221559489, 0.3213938048432697, -0.5362311101832845, 0.4499513267805776, 0.5362311101832846, 0.4499513267805774, 0.383022221559489, 0.3213938048432696, - -0.4596266658713867, 0.3856725658119237, 4.28612223837832e-17, 0.7, 0.4596266658713868, 0.3856725658119236, 3.061515884555943e-17, 0.5 }; - - double coords2[16]={ - -0.1811733315717646, 0.6761480784023478, -0.2070552360820167, 0.7727406610312547, 0.2070552360820166, 0.7727406610312547, 0.1811733315717645, 0.6761480784023478, - -0.1941142838268906, 0.7244443697168013, 4.898425415289509e-17, 0.8, 0.1941142838268906, 0.7244443697168013, 4.28612223837832e-17, 0.7 }; - - int tab8[8]={ - 0, 1, 2, 3, 4, 5, 6, 7 }; - QuadraticPolygon *pol1=buildQuadraticPolygonCoarseInfo(coords,tab8,8); - QuadraticPolygon *pol2=buildQuadraticPolygonCoarseInfo(coords2,tab8,8); - std::vector val1,val2; - pol1->intersectForPerimeterAdvanced(*pol2,val1,val2); - double test1_res[4]={0.,0.366519,0.,0.}; - double test2_res[4]={0.,0.,0.,0.366519}; - CPPUNIT_ASSERT(std::equal(val1.begin(),val1.end(),test1_res,DoubleEqual(1e-6))); - CPPUNIT_ASSERT(std::equal(val2.begin(),val2.end(),test2_res,DoubleEqual(1e-6))); - delete pol1; - delete pol2; -} - -void QuadraticPlanarInterpTest::checkNonRegressionOmar0007() -{ - INTERP_KERNEL::QUADRATIC_PLANAR::setPrecision(1e-7); - INTERP_KERNEL::QUADRATIC_PLANAR::setArcDetectionPrecision(1e-7); - double coords[16]={ - -0.383022221559489, 0.3213938048432697, -0.5362311101832845, 0.4499513267805776, 0.5362311101832846, 0.4499513267805774, 0.383022221559489, 0.3213938048432696, - -0.4596266658713867, 0.3856725658119237, 4.28612223837832e-17, 0.7, 0.4596266658713868, 0.3856725658119236, 3.061515884555943e-17, 0.5 }; - - double coords2[16]={ - -0.4499513267805775, 0.5362311101832846, -0.5142300877492315, 0.6128355544951825, -0.1389185421335442, 0.7878462024097664, -0.1215537243668512, 0.6893654271085455, - -0.4820907072649045, 0.5745333323392335, -0.3380946093925595, 0.7250462296293201, -0.1302361332501977, 0.738605814759156, -0.2958327832184895, 0.634415450925655 }; - - int tab8[8]={ - 0, 1, 2, 3, 4, 5, 6, 7 }; - QuadraticPolygon *pol1=buildQuadraticPolygonCoarseInfo(coords,tab8,8); - QuadraticPolygon *pol2=buildQuadraticPolygonCoarseInfo(coords2,tab8,8); - std::vector val1,val2; - pol1->intersectForPerimeterAdvanced(*pol2,val1,val2); - double test1_res[4]={0.,0.366519,0.,0.}; - double test2_res[4]={0.,0.,0.,0.366519}; - CPPUNIT_ASSERT(std::equal(val1.begin(),val1.end(),test1_res,DoubleEqual(1e-6))); - CPPUNIT_ASSERT(std::equal(val2.begin(),val2.end(),test2_res,DoubleEqual(1e-6))); - delete pol1; - delete pol2; -} - -void QuadraticPlanarInterpTest::checkNonRegressionOmar0008() -{ - INTERP_KERNEL::QUADRATIC_PLANAR::setPrecision(1e-7); - INTERP_KERNEL::QUADRATIC_PLANAR::setArcDetectionPrecision(1e-7); - double coords[16]={ - -0.383022221559489, 0.3213938048432697, -0.5362311101832845, 0.4499513267805776, 0.5362311101832846, 0.4499513267805774, 0.383022221559489, 0.3213938048432696, - -0.4596266658713867, 0.3856725658119237, 4.28612223837832e-17, 0.7, 0.4596266658713868, 0.3856725658119236, 3.061515884555943e-17, 0.5 }; - - double coords2[16]={ - -0.6344154509256549, 0.2958327832184896, -0.72504622962932, 0.3380946093925596, -0.4588611490808367, 0.6553216354311937, -0.401503505445732, 0.5734064310022944, - -0.6797308402774874, 0.3169636963055246, -0.6128355544951823, 0.5142300877492316, -0.4301823272632844, 0.614364033216744, -0.5362311101832845, 0.4499513267805776 }; - - int tab8[8]={ - 0, 1, 2, 3, 4, 5, 6, 7 }; - QuadraticPolygon *pol1=buildQuadraticPolygonCoarseInfo(coords,tab8,8); - QuadraticPolygon *pol2=buildQuadraticPolygonCoarseInfo(coords2,tab8,8); - std::vector val1,val2; - pol1->intersectForPerimeterAdvanced(*pol2,val1,val2); - double test1_res[4]={0.,0.18326,0.,0.}; - double test2_res[4]={0.,0.,0.,0.18326}; - CPPUNIT_ASSERT(std::equal(val1.begin(),val1.end(),test1_res,DoubleEqual(1e-5))); - CPPUNIT_ASSERT(std::equal(val2.begin(),val2.end(),test2_res,DoubleEqual(1e-5))); - delete pol1; - delete pol2; -} - -void QuadraticPlanarInterpTest::checkNonRegressionOmar0009() -{ - INTERP_KERNEL::QUADRATIC_PLANAR::setPrecision(1e-7); - INTERP_KERNEL::QUADRATIC_PLANAR::setArcDetectionPrecision(1e-7); - double coords[16]={ - -0.3863703305156274, -0.1035276180410081, -0.4829629131445342, -0.1294095225512602, 0.4829629131445342, -0.1294095225512604, 0.3863703305156274, -0.1035276180410083, - -0.4346666218300808, -0.1164685702961342, 1.416374613080751e-16, 0.5, 0.4346666218300808, -0.1164685702961343, 1.133099690464601e-16, 0.4 }; - double coords2[16]={ - 0.5, -1.224606353822377e-16, 0.6, -1.469527624586853e-16, -0.6, 7.347638122934263e-17, -0.5, 6.123031769111886e-17, - 0.55, -1.347066989204615e-16, -1.102145718440139e-16, -0.6, -0.55, 6.735334946023075e-17, -9.184547653667829e-17, -0.5 }; - - int tab8[8]={ - 0, 1, 2, 3, 4, 5, 6, 7 }; - QuadraticPolygon *pol1=buildQuadraticPolygonCoarseInfo(coords,tab8,8); - QuadraticPolygon *pol2=buildQuadraticPolygonCoarseInfo(coords2,tab8,8); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.,pol1->intersectWith(*pol2),1.e-13); - delete pol1; - delete pol2; - pol1=buildQuadraticPolygonCoarseInfo(coords,tab8,8); - pol2=buildQuadraticPolygonCoarseInfo(coords2,tab8,8); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.,pol2->intersectWith(*pol1),1.e-13); - delete pol1; - delete pol2; -} - -void QuadraticPlanarInterpTest::checkNonRegressionOmar0010() -{ - INTERP_KERNEL::QUADRATIC_PLANAR::setPrecision(1e-7); - INTERP_KERNEL::QUADRATIC_PLANAR::setArcDetectionPrecision(1e-7); - double coords[16]={ - -0.3863703305156274, -0.1035276180410081, -0.4829629131445342, -0.1294095225512602, 0.4829629131445342, -0.1294095225512604, 0.3863703305156274, -0.1035276180410083, --0.4346666218300808, -0.1164685702961342, 1.416374613080751e-16, 0.5, 0.4346666218300808, -0.1164685702961343, 1.133099690464601e-16, 0.4 }; - double coords2[16]={ - 0.4346666218300808, -0.1164685702961343, 0.579555495773441, -0.1552914270615124, -0.579555495773441, -0.1552914270615122, -0.4346666218300808, -0.1164685702961342, -0.5071110588017609, -0.1358799986788234, -1.102145718440139e-16, -0.6, -0.507111058801761, -0.1358799986788232, -8.266092888301047e-17, -0.45 }; - - int tab8[8]={ - 0, 1, 2, 3, 4, 5, 6, 7 }; - QuadraticPolygon *pol1=buildQuadraticPolygonCoarseInfo(coords,tab8,8); - QuadraticPolygon *pol2=buildQuadraticPolygonCoarseInfo(coords2,tab8,8); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.,pol1->intersectWith(*pol2),1.e-13); - delete pol1; - delete pol2; - pol1=buildQuadraticPolygonCoarseInfo(coords,tab8,8); - pol2=buildQuadraticPolygonCoarseInfo(coords2,tab8,8); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.,pol2->intersectWith(*pol1),1.e-13); - delete pol1; - delete pol2; -} - -void QuadraticPlanarInterpTest::checkNonRegressionOmar0011() -{ - INTERP_KERNEL::QUADRATIC_PLANAR::setPrecision(1e-7); - INTERP_KERNEL::QUADRATIC_PLANAR::setArcDetectionPrecision(1e-7); - double coords[16]={ - -0.3863703305156274, -0.1035276180410081, -0.4829629131445342, -0.1294095225512602, 0.4829629131445342, -0.1294095225512604, 0.3863703305156274, -0.1035276180410083, --0.4346666218300808, -0.1164685702961342, 1.416374613080751e-16, 0.5, 0.4346666218300808, -0.1164685702961343, 1.133099690464601e-16, 0.4 }; - double coords2[16]={ - 0.4829629131445342, -0.1294095225512603, 0.579555495773441, -0.1552914270615124, -0.579555495773441, -0.1552914270615122, -0.4829629131445342, -0.1294095225512602, -0.5312592044589877, -0.1423504748063864, -1.102145718440139e-16, -0.6, -0.5312592044589877, -0.1423504748063862, -9.184547653667829e-17, -0.5 }; - - int tab8[8]={ - 0, 1, 2, 3, 4, 5, 6, 7 }; - QuadraticPolygon *pol1=buildQuadraticPolygonCoarseInfo(coords,tab8,8); - QuadraticPolygon *pol2=buildQuadraticPolygonCoarseInfo(coords2,tab8,8); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.,pol1->intersectWith(*pol2),1.e-13); - double val1,val2,val3; - pol1->intersectForPerimeter(*pol2,val1,val2,val3); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.,val1,1.e-13); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.,val2,1.e-13); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.,val3,1.e-13); - std::vector val4,val5; - pol1->intersectForPerimeterAdvanced(*pol2,val4,val5); - double test1_res[4]={0.,0.,0.,0.}; - CPPUNIT_ASSERT(std::equal(val4.begin(),val4.end(),test1_res,DoubleEqual(1e-13))); - CPPUNIT_ASSERT(std::equal(val5.begin(),val5.end(),test1_res,DoubleEqual(1e-13))); - delete pol1; - delete pol2; - pol1=buildQuadraticPolygonCoarseInfo(coords,tab8,8); - pol2=buildQuadraticPolygonCoarseInfo(coords2,tab8,8); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.,pol2->intersectWith(*pol1),1.e-13); - pol1->intersectForPerimeter(*pol2,val1,val2,val3); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.,val1,1.e-13); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.,val2,1.e-13); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.,val3,1.e-13); - val4.clear(); val5.clear(); - pol1->intersectForPerimeterAdvanced(*pol2,val4,val5); - CPPUNIT_ASSERT(std::equal(val4.begin(),val4.end(),test1_res,DoubleEqual(1e-13))); - CPPUNIT_ASSERT(std::equal(val5.begin(),val5.end(),test1_res,DoubleEqual(1e-13))); - delete pol1; - delete pol2; -} - -void QuadraticPlanarInterpTest::checkNonRegressionOmar2511() -{ - INTERP_KERNEL::QUADRATIC_PLANAR::setPrecision(1e-7); - INTERP_KERNEL::QUADRATIC_PLANAR::setArcDetectionPrecision(1e-7); - double coords[16]={ - -0.3863703305156274, -0.1035276180410081, -0.4829629131445342, -0.1294095225512602, 0.4829629131445342, -0.1294095225512604, 0.3863703305156274, -0.1035276180410083, - -0.4346666218300808, -0.1164685702961342, 1.416374613080751e-16, 0.5, 0.4346666218300808, -0.1164685702961343, 1.133099690464601e-16, 0.4, }; - - double coords2[16]={ - 0.579555495773441, -0.1552914270615124, -0.579555495773441, -0.1552914270615122, -0.4829629131445342, -0.1294095225512602, 0.4829629131445342, -0.1294095225512603, - -1.102145718440139e-16, -0.6, -0.5312592044589877, -0.1423504748063862, -9.184547653667829e-17, -0.5, 0.5312592044589877, -0.1423504748063864, }; - - int tab8[8]={ - 0, 1, 2, 3, 4, 5, 6, 7 }; - QuadraticPolygon *pol1=buildQuadraticPolygonCoarseInfo(coords,tab8,8); - QuadraticPolygon *pol2=buildQuadraticPolygonCoarseInfo(coords2,tab8,8); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.,pol1->intersectWith(*pol2),1.e-13); - double val1,val2,val3; - pol1->intersectForPerimeter(*pol2,val1,val2,val3); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.,val1,1.e-13); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.,val2,1.e-13); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.,val3,1.e-13); - std::vector val4,val5; - pol1->intersectForPerimeterAdvanced(*pol2,val4,val5); - double test1_res[4]={0.,0.,0.,0.}; - CPPUNIT_ASSERT(std::equal(val4.begin(),val4.end(),test1_res,DoubleEqual(1e-13))); - CPPUNIT_ASSERT(std::equal(val5.begin(),val5.end(),test1_res,DoubleEqual(1e-13))); - delete pol1; - delete pol2; - pol1=buildQuadraticPolygonCoarseInfo(coords,tab8,8); - pol2=buildQuadraticPolygonCoarseInfo(coords2,tab8,8); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.,pol2->intersectWith(*pol1),1.e-13); - pol1->intersectForPerimeter(*pol2,val1,val2,val3); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.,val1,1.e-13); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.,val2,1.e-13); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.,val3,1.e-13); - val4.clear(); val5.clear(); - pol1->intersectForPerimeterAdvanced(*pol2,val4,val5); - CPPUNIT_ASSERT(std::equal(val4.begin(),val4.end(),test1_res,DoubleEqual(1e-13))); - CPPUNIT_ASSERT(std::equal(val5.begin(),val5.end(),test1_res,DoubleEqual(1e-13))); - delete pol1; - delete pol2; -} - -void QuadraticPlanarInterpTest::checkNonRegressionOmar0012() -{ - INTERP_KERNEL::QUADRATIC_PLANAR::setPrecision(1e-7); - INTERP_KERNEL::QUADRATIC_PLANAR::setArcDetectionPrecision(1e-7); - double coords[16]={ - -1, 1.224606353822377e-16, -1.6, 1.959370166115804e-16, 9.796850830579018e-17, 1.6, 6.123031769111886e-17, 1, - -1.3, 1.591988259969091e-16, -1.131370849898476, 1.131370849898476, 7.959941299845453e-17, 1.3, -0.7071067811865475, 0.7071067811865476 }; - - double coords2[16]={ - 6.123031769111886e-18, 1.85, 1.224606353822377e-17, 1.95, 1.224606353822377e-17, 1.55, 6.123031769111886e-18, 1.65, - 9.18454765366783e-18, 1.9, 0.2, 1.75, 9.18454765366783e-18, 1.6, 0.1, 1.75 }; - - int tab8[8]={ - 0, 1, 2, 3, 4, 5, 6, 7 }; - QuadraticPolygon *pol1=buildQuadraticPolygonCoarseInfo(coords,tab8,8); - QuadraticPolygon *pol2=buildQuadraticPolygonCoarseInfo(coords2,tab8,8); - std::vector val1,val2; - pol1->intersectForPerimeterAdvanced(*pol2,val1,val2); - double test1_res[4]={0.,0.,0.05,0.}; - double test2_res[4]={0.,0.,0.05,0.}; - CPPUNIT_ASSERT(std::equal(val1.begin(),val1.end(),test1_res,DoubleEqual(1e-13))); - CPPUNIT_ASSERT(std::equal(val2.begin(),val2.end(),test2_res,DoubleEqual(1e-13))); - delete pol1; - delete pol2; - std::vector val3; - pol1=buildQuadraticPolygonCoarseInfo(coords,tab8,8); - pol2=buildQuadraticPolygonCoarseInfo(coords2,tab8,8); - pol1->intersectForPoint(*pol2,val3); - int test3_res[4]={0,0,1,0}; - CPPUNIT_ASSERT(std::equal(val3.begin(),val3.end(),test3_res)); - delete pol1; - delete pol2; -} - -void QuadraticPlanarInterpTest::checkNonRegressionOmar0013() -{ - INTERP_KERNEL::QUADRATIC_PLANAR::setPrecision(1e-7); - INTERP_KERNEL::QUADRATIC_PLANAR::setArcDetectionPrecision(1e-7); - double coords[16]={ - -1, 1.224606353822377e-16, -1.6, 1.959370166115804e-16, 9.796850830579018e-17, 1.6, 6.123031769111886e-17, 1, - -1.3, 1.591988259969091e-16, -1.131370849898476, 1.131370849898476, 7.959941299845453e-17, 1.3, -0.7071067811865475, 0.7071067811865476 }; - - double coords2[16]={ - 6.123031769111886e-18, 1.7, 1.224606353822377e-17, 1.8, 1.224606353822377e-17, 1.4, 6.123031769111886e-18, 1.5, - 9.18454765366783e-18, 1.75, 0.2, 1.6, 9.18454765366783e-18, 1.45, 0.1, 1.6 }; - - int tab8[8]={ - 0, 1, 2, 3, 4, 5, 6, 7 }; - QuadraticPolygon *pol1=buildQuadraticPolygonCoarseInfo(coords,tab8,8); - QuadraticPolygon *pol2=buildQuadraticPolygonCoarseInfo(coords2,tab8,8); - std::vector val1,val2; - pol1->intersectForPerimeterAdvanced(*pol2,val1,val2); - double test1_res[4]={0.,0.,0.1,0.}; - double test2_res[4]={0.,0.,0.1,0.}; - CPPUNIT_ASSERT(std::equal(val1.begin(),val1.end(),test1_res,DoubleEqual(1e-13))); - CPPUNIT_ASSERT(std::equal(val2.begin(),val2.end(),test2_res,DoubleEqual(1e-13))); - delete pol1; - delete pol2; - std::vector val3; - pol1=buildQuadraticPolygonCoarseInfo(coords,tab8,8); - pol2=buildQuadraticPolygonCoarseInfo(coords2,tab8,8); - pol1->intersectForPoint(*pol2,val3); - int test3_res[4]={0,0,2,0}; - CPPUNIT_ASSERT(std::equal(val3.begin(),val3.end(),test3_res)); - delete pol1; - delete pol2; -} - -void QuadraticPlanarInterpTest::checkNonRegressionOmar0014() -{ - INTERP_KERNEL::QUADRATIC_PLANAR::setPrecision(1e-7); - INTERP_KERNEL::QUADRATIC_PLANAR::setArcDetectionPrecision(1e-7); - double coords[16]={ - -1, 1.224606353822377e-16, -1.6, 1.959370166115804e-16, 9.796850830579018e-17, 1.6, 6.123031769111886e-17, 1, --1.3, 1.591988259969091e-16, -1.131370849898476, 1.131370849898476, 7.959941299845453e-17, 1.3, -0.7071067811865475, 0.7071067811865476 }; - double coords2[16]={ - 6.123031769111886e-18, 1.55, 1.224606353822377e-17, 1.65, 1.224606353822377e-17, 1.25, 6.123031769111886e-18, 1.35, -9.18454765366783e-18, 1.6, 0.2, 1.45, 9.18454765366783e-18, 1.3, 0.1, 1.45 }; - - int tab8[8]={ - 0, 1, 2, 3, 4, 5, 6, 7 }; - QuadraticPolygon *pol1=buildQuadraticPolygonCoarseInfo(coords,tab8,8); - QuadraticPolygon *pol2=buildQuadraticPolygonCoarseInfo(coords2,tab8,8); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.,pol1->intersectWith(*pol2),1.e-13); - delete pol1; - delete pol2; - pol1=buildQuadraticPolygonCoarseInfo(coords,tab8,8); - pol2=buildQuadraticPolygonCoarseInfo(coords2,tab8,8); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.,pol2->intersectWith(*pol1),1.e-13); - delete pol1; - delete pol2; - // - pol1=buildQuadraticPolygonCoarseInfo(coords,tab8,8); - pol2=buildQuadraticPolygonCoarseInfo(coords2,tab8,8); - std::vector val1,val2; - pol1->intersectForPerimeterAdvanced(*pol2,val1,val2); - double test1_res[4]={0.,0.,0.15,0.}; - double test2_res[4]={0.05,0.,0.1,0.}; - CPPUNIT_ASSERT(std::equal(val1.begin(),val1.end(),test1_res,DoubleEqual(1e-13))); - CPPUNIT_ASSERT(std::equal(val2.begin(),val2.end(),test2_res,DoubleEqual(1e-13))); - delete pol1; - delete pol2; - std::vector val3; - pol1=buildQuadraticPolygonCoarseInfo(coords,tab8,8); - pol2=buildQuadraticPolygonCoarseInfo(coords2,tab8,8); - pol1->intersectForPoint(*pol2,val3); - int test3_res[4]={0,0,3,0}; - CPPUNIT_ASSERT(std::equal(val3.begin(),val3.end(),test3_res)); - delete pol1; - delete pol2; -} - -void QuadraticPlanarInterpTest::checkNonRegressionOmar0015() -{ - INTERP_KERNEL::QUADRATIC_PLANAR::setPrecision(1e-7); - INTERP_KERNEL::QUADRATIC_PLANAR::setArcDetectionPrecision(1e-7); - double coords[16]={ - -1, 1.224606353822377e-16, -1.6, 1.959370166115804e-16, 9.796850830579018e-17, 1.6, 6.123031769111886e-17, 1, --1.3, 1.591988259969091e-16, -1.131370849898476, 1.131370849898476, 7.959941299845453e-17, 1.3, -0.7071067811865475, 0.7071067811865476 }; - double coords2[16]={ - 6.123031769111886e-18, 1.4, 1.224606353822377e-17, 1.5, 1.224606353822377e-17, 1.1, 6.123031769111886e-18, 1.2, -9.18454765366783e-18, 1.45, 0.2, 1.3, 9.18454765366783e-18, 1.15, 0.1, 1.3 }; - - int tab8[8]={ - 0, 1, 2, 3, 4, 5, 6, 7 }; - QuadraticPolygon *pol1=buildQuadraticPolygonCoarseInfo(coords,tab8,8); - QuadraticPolygon *pol2=buildQuadraticPolygonCoarseInfo(coords2,tab8,8); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.,pol1->intersectWith(*pol2),1.e-13); - delete pol1; - delete pol2; - pol1=buildQuadraticPolygonCoarseInfo(coords,tab8,8); - pol2=buildQuadraticPolygonCoarseInfo(coords2,tab8,8); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.,pol2->intersectWith(*pol1),1.e-13); - delete pol1; - delete pol2; - // - pol1=buildQuadraticPolygonCoarseInfo(coords,tab8,8); - pol2=buildQuadraticPolygonCoarseInfo(coords2,tab8,8); - std::vector val1,val2; - pol1->intersectForPerimeterAdvanced(*pol2,val1,val2); - double test1_res[4]={0.,0.,0.2,0.}; - double test2_res[4]={0.1,0.,0.1,0.}; - CPPUNIT_ASSERT(std::equal(val1.begin(),val1.end(),test1_res,DoubleEqual(1e-13))); - CPPUNIT_ASSERT(std::equal(val2.begin(),val2.end(),test2_res,DoubleEqual(1e-13))); - delete pol1; - delete pol2; - std::vector val3; - pol1=buildQuadraticPolygonCoarseInfo(coords,tab8,8); - pol2=buildQuadraticPolygonCoarseInfo(coords2,tab8,8); - pol1->intersectForPoint(*pol2,val3); - int test3_res[4]={0,0,4,0}; - CPPUNIT_ASSERT(std::equal(val3.begin(),val3.end(),test3_res)); - delete pol1; - delete pol2; -} - -void QuadraticPlanarInterpTest::checkNonRegressionOmar0016() -{ - INTERP_KERNEL::QUADRATIC_PLANAR::setPrecision(1e-7); - INTERP_KERNEL::QUADRATIC_PLANAR::setArcDetectionPrecision(1e-7); - double coords[16]={ - -1, 1.224606353822377e-16, -1.6, 1.959370166115804e-16, 9.796850830579018e-17, 1.6, 6.123031769111886e-17, 1, --1.3, 1.591988259969091e-16, -1.131370849898476, 1.131370849898476, 7.959941299845453e-17, 1.3, -0.7071067811865475, 0.7071067811865476 }; - double coords2[16]={ - 6.123031769111886e-18, 1.25, 1.224606353822377e-17, 1.35, 1.224606353822377e-17, 0.95, 6.123031769111886e-18, 1.05, -9.18454765366783e-18, 1.3, 0.2, 1.15, 9.18454765366783e-18, 0.9999999999999999, 0.1, 1.15 }; - - int tab8[8]={ - 0, 1, 2, 3, 4, 5, 6, 7 }; - QuadraticPolygon *pol1=buildQuadraticPolygonCoarseInfo(coords,tab8,8); - QuadraticPolygon *pol2=buildQuadraticPolygonCoarseInfo(coords2,tab8,8); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.,pol1->intersectWith(*pol2),1.e-13); - delete pol1; - delete pol2; - pol1=buildQuadraticPolygonCoarseInfo(coords,tab8,8); - pol2=buildQuadraticPolygonCoarseInfo(coords2,tab8,8); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.,pol2->intersectWith(*pol1),1.e-13); - delete pol1; - delete pol2; - // - pol1=buildQuadraticPolygonCoarseInfo(coords,tab8,8); - pol2=buildQuadraticPolygonCoarseInfo(coords2,tab8,8); - std::vector val1,val2; - pol1->intersectForPerimeterAdvanced(*pol2,val1,val2); - double test1_res[4]={0.,0.,0.15,0.}; - double test2_res[4]={0.1,0.,0.05,0.}; - CPPUNIT_ASSERT(std::equal(val1.begin(),val1.end(),test1_res,DoubleEqual(1e-13))); - CPPUNIT_ASSERT(std::equal(val2.begin(),val2.end(),test2_res,DoubleEqual(1e-13))); - delete pol1; - delete pol2; - std::vector val3; - pol1=buildQuadraticPolygonCoarseInfo(coords,tab8,8); - pol2=buildQuadraticPolygonCoarseInfo(coords2,tab8,8); - pol1->intersectForPoint(*pol2,val3); - int test3_res[4]={0,0,3,0}; - CPPUNIT_ASSERT(std::equal(val3.begin(),val3.end(),test3_res)); - delete pol1; - delete pol2; -} - -void QuadraticPlanarInterpTest::checkNonRegressionOmar0017() -{ - INTERP_KERNEL::QUADRATIC_PLANAR::setPrecision(1e-7); - INTERP_KERNEL::QUADRATIC_PLANAR::setArcDetectionPrecision(1e-7); - double coords[16]={ - -1, 1.224606353822377e-16, -1.6, 1.959370166115804e-16, 9.796850830579018e-17, 1.6, 6.123031769111886e-17, 1, - -1.3, 1.591988259969091e-16, -1.131370849898476, 1.131370849898476, 7.959941299845453e-17, 1.3, -0.7071067811865475, 0.7071067811865476 }; - - double coords2[16]={ - 6.123031769111886e-18, 1.1, 1.224606353822377e-17, 1.2, 1.224606353822377e-17, 0.8, 6.123031769111886e-18, 0.9, - 9.18454765366783e-18, 1.15, 0.2, 1, 9.18454765366783e-18, 0.85, 0.1, 1 }; - - int tab8[8]={ - 0, 1, 2, 3, 4, 5, 6, 7 }; - QuadraticPolygon *pol1=buildQuadraticPolygonCoarseInfo(coords,tab8,8); - QuadraticPolygon *pol2=buildQuadraticPolygonCoarseInfo(coords2,tab8,8); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.,pol1->intersectWith(*pol2),1.e-13); - delete pol1; - delete pol2; - pol1=buildQuadraticPolygonCoarseInfo(coords,tab8,8); - pol2=buildQuadraticPolygonCoarseInfo(coords2,tab8,8); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.,pol2->intersectWith(*pol1),1.e-13); - delete pol1; - delete pol2; - // - pol1=buildQuadraticPolygonCoarseInfo(coords,tab8,8); - pol2=buildQuadraticPolygonCoarseInfo(coords2,tab8,8); - std::vector val1,val2; - pol1->intersectForPerimeterAdvanced(*pol2,val1,val2); - double test1_res[4]={0.,0.,0.1,0.}; - double test2_res[4]={0.1,0.,0.,0.}; - CPPUNIT_ASSERT(std::equal(val1.begin(),val1.end(),test1_res,DoubleEqual(1e-13))); - CPPUNIT_ASSERT(std::equal(val2.begin(),val2.end(),test2_res,DoubleEqual(1e-13))); - delete pol1; - delete pol2; - std::vector val3; - pol1=buildQuadraticPolygonCoarseInfo(coords,tab8,8); - pol2=buildQuadraticPolygonCoarseInfo(coords2,tab8,8); - pol1->intersectForPoint(*pol2,val3); - int test3_res[4]={0,0,2,0}; - CPPUNIT_ASSERT(std::equal(val3.begin(),val3.end(),test3_res)); - delete pol1; - delete pol2; -} - -void QuadraticPlanarInterpTest::checkNonRegressionOmar0018() -{ - INTERP_KERNEL::QUADRATIC_PLANAR::setPrecision(1e-7); - INTERP_KERNEL::QUADRATIC_PLANAR::setArcDetectionPrecision(1e-7); - double coords[16]={ - -1, 1.224606353822377e-16, -1.6, 1.959370166115804e-16, 9.796850830579018e-17, 1.6, 6.123031769111886e-17, 1, - -1.3, 1.591988259969091e-16, -1.131370849898476, 1.131370849898476, 7.959941299845453e-17, 1.3, -0.7071067811865475, 0.7071067811865476 }; - - double coords2[16]={ - 6.123031769111886e-18, 0.95, 1.224606353822377e-17, 1.05, 1.224606353822377e-17, 0.6499999999999999, 6.123031769111886e-18, 0.75, - 9.18454765366783e-18, 1, 0.2, 0.85, 9.18454765366783e-18, 0.7, 0.1, 0.85 }; - - int tab8[8]={ - 0, 1, 2, 3, 4, 5, 6, 7 }; - QuadraticPolygon *pol1=buildQuadraticPolygonCoarseInfo(coords,tab8,8); - QuadraticPolygon *pol2=buildQuadraticPolygonCoarseInfo(coords2,tab8,8); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.,pol1->intersectWith(*pol2),1.e-13); - delete pol1; - delete pol2; - pol1=buildQuadraticPolygonCoarseInfo(coords,tab8,8); - pol2=buildQuadraticPolygonCoarseInfo(coords2,tab8,8); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.,pol2->intersectWith(*pol1),1.e-13); - delete pol1; - delete pol2; - // - pol1=buildQuadraticPolygonCoarseInfo(coords,tab8,8); - pol2=buildQuadraticPolygonCoarseInfo(coords2,tab8,8); - std::vector val1,val2; - pol1->intersectForPerimeterAdvanced(*pol2,val1,val2); - double test1_res[4]={0.,0.,0.05,0.}; - double test2_res[4]={0.05,0.,0.,0.}; - CPPUNIT_ASSERT(std::equal(val1.begin(),val1.end(),test1_res,DoubleEqual(1e-13))); - CPPUNIT_ASSERT(std::equal(val2.begin(),val2.end(),test2_res,DoubleEqual(1e-13))); - delete pol1; - delete pol2; - std::vector val3; - pol1=buildQuadraticPolygonCoarseInfo(coords,tab8,8); - pol2=buildQuadraticPolygonCoarseInfo(coords2,tab8,8); - pol1->intersectForPoint(*pol2,val3); - int test3_res[4]={0,0,1,0}; - CPPUNIT_ASSERT(std::equal(val3.begin(),val3.end(),test3_res)); - delete pol1; - delete pol2; -} - -void QuadraticPlanarInterpTest::checkNonRegressionOmar0019() -{ - INTERP_KERNEL::QUADRATIC_PLANAR::setPrecision(1e-7); - INTERP_KERNEL::QUADRATIC_PLANAR::setArcDetectionPrecision(1e-7); - double coords[16]={ - -0.5, 6.123031769111886e-17, -0.8, 9.796850830579018e-17, 0.8, 0, 0.5, 0, - -0.65, 7.959941299845453e-17, 4.898425415289509e-17, 0.8, 0.65, 0, 3.061515884555943e-17, 0.5 }; - - double coords2[16]={ - 0.9500000000000001, 1.836909530733566e-17, 0.8, 3.673819061467131e-17, 1.4, 0, 1.25, 0, - 0.8750000000000001, 2.755364296100349e-17, 1.1, 0.3, 1.325, 0, 1.1, 0.15 }; - - int tab8[8]={ - 0, 1, 2, 3, 4, 5, 6, 7 }; - QuadraticPolygon *pol1=buildQuadraticPolygonCoarseInfo(coords,tab8,8); - QuadraticPolygon *pol2=buildQuadraticPolygonCoarseInfo(coords2,tab8,8); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.,pol1->intersectWith(*pol2),1.e-13); - delete pol1; - delete pol2; - pol1=buildQuadraticPolygonCoarseInfo(coords,tab8,8); - pol2=buildQuadraticPolygonCoarseInfo(coords2,tab8,8); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.,pol2->intersectWith(*pol1),1.e-13); - delete pol1; - delete pol2; -} - -void QuadraticPlanarInterpTest::checkNonRegressionOmar0020() -{ - INTERP_KERNEL::QUADRATIC_PLANAR::setPrecision(1e-7); - INTERP_KERNEL::QUADRATIC_PLANAR::setArcDetectionPrecision(1e-7); - double coords[16]={ - -0.5, 6.123031769111886e-17, -0.8, 9.796850830579018e-17, 0.8, 0, 0.5, 0, - -0.65, 7.959941299845453e-17, 4.898425415289509e-17, 0.8, 0.65, 0, 3.061515884555943e-17, 0.5 }; - - double coords2[16]={ - 0.05000000000000002, 1.836909530733566e-17, -0.09999999999999998, 3.673819061467131e-17, 0.5, 0, 0.35, 0, - -0.02499999999999997, 2.755364296100349e-17, 0.2, 0.3, 0.425, 0, 0.2, 0.15 }; - - int tab8[8]={ - 0, 1, 2, 3, 4, 5, 6, 7 }; - QuadraticPolygon *pol1=buildQuadraticPolygonCoarseInfo(coords,tab8,8); - QuadraticPolygon *pol2=buildQuadraticPolygonCoarseInfo(coords2,tab8,8); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.,pol1->intersectWith(*pol2),1.e-13); - delete pol1; - delete pol2; - pol1=buildQuadraticPolygonCoarseInfo(coords,tab8,8); - pol2=buildQuadraticPolygonCoarseInfo(coords2,tab8,8); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.,pol2->intersectWith(*pol1),1.e-13); - delete pol1; - delete pol2; - // - pol1=buildQuadraticPolygonCoarseInfo(coords,tab8,8); - pol2=buildQuadraticPolygonCoarseInfo(coords2,tab8,8); - std::vector val1,val2; - pol1->intersectForPerimeterAdvanced(*pol2,val1,val2); - double test1_res[4]={0.,0.,0.,0.}; - double test2_res[4]={0.,0.,0.,0.}; - CPPUNIT_ASSERT(std::equal(val1.begin(),val1.end(),test1_res,DoubleEqual(1e-6))); - CPPUNIT_ASSERT(std::equal(val2.begin(),val2.end(),test2_res,DoubleEqual(1e-6))); - delete pol1; - delete pol2; - std::vector val3; - pol1=buildQuadraticPolygonCoarseInfo(coords,tab8,8); - pol2=buildQuadraticPolygonCoarseInfo(coords2,tab8,8); - pol1->intersectForPoint(*pol2,val3); - int test3_res[4]={0,0,0,0}; - CPPUNIT_ASSERT(std::equal(val3.begin(),val3.end(),test3_res)); - delete pol1; - delete pol2; -} - -void QuadraticPlanarInterpTest::checkNonRegressionOmar0021() -{ - INTERP_KERNEL::QUADRATIC_PLANAR::setPrecision(1e-7); - INTERP_KERNEL::QUADRATIC_PLANAR::setArcDetectionPrecision(1e-7); - double coords[16]={ - -0.5, 6.123031769111886e-17, -0.8, 9.796850830579018e-17, 0.8, 0, 0.5, 0, - -0.65, 7.959941299845453e-17, 4.898425415289509e-17, 0.8, 0.65, 0, 3.061515884555943e-17, 0.5 }; - - double coords2[16]={ - -1, -0.07999999999999999, -1.15, -0.07999999999999996, -0.55, -0.08, -0.7, -0.08, - -1.075, -0.07999999999999997, -0.85, 0.22, -0.625, -0.08, -0.85, 0.06999999999999999 }; - - int tab8[8]={ - 0, 1, 2, 3, 4, 5, 6, 7 }; - QuadraticPolygon *pol1=buildQuadraticPolygonCoarseInfo(coords,tab8,8); - QuadraticPolygon *pol2=buildQuadraticPolygonCoarseInfo(coords2,tab8,8); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.0311485,pol1->intersectWith(*pol2),1.e-7); - delete pol1; - delete pol2; - pol1=buildQuadraticPolygonCoarseInfo(coords,tab8,8); - pol2=buildQuadraticPolygonCoarseInfo(coords2,tab8,8); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.0311485,pol2->intersectWith(*pol1),1.e-7); - delete pol1; - delete pol2; - // - pol1=buildQuadraticPolygonCoarseInfo(coords,tab8,8); - pol2=buildQuadraticPolygonCoarseInfo(coords2,tab8,8); - std::vector val1,val2; - pol1->intersectForPerimeterAdvanced(*pol2,val1,val2); - double test1_res[4]={0.162251,0.151523,0.,0.}; - double test2_res[4]={0.,0.311383,0.,0.0978193}; - CPPUNIT_ASSERT(std::equal(val1.begin(),val1.end(),test1_res,DoubleEqual(1e-6))); - CPPUNIT_ASSERT(std::equal(val2.begin(),val2.end(),test2_res,DoubleEqual(1e-6))); - delete pol1; - delete pol2; - std::vector val3; - pol1=buildQuadraticPolygonCoarseInfo(coords,tab8,8); - pol2=buildQuadraticPolygonCoarseInfo(coords2,tab8,8); - pol1->intersectForPoint(*pol2,val3); - int test3_res[4]={2,2,0,0}; - CPPUNIT_ASSERT(std::equal(val3.begin(),val3.end(),test3_res)); - delete pol1; - delete pol2; -} -void QuadraticPlanarInterpTest::checkNonRegressionOmar0022() -{ - INTERP_KERNEL::QUADRATIC_PLANAR::setPrecision(1e-7); - INTERP_KERNEL::QUADRATIC_PLANAR::setArcDetectionPrecision(1e-7); - double coords[16]={ - -0.5, 6.123031769111886e-17, -0.8, 9.796850830579018e-17, 0.8, 0, 0.5, 0, - -0.65, 7.959941299845453e-17, 4.898425415289509e-17, 0.8, 0.65, 0, 3.061515884555943e-17, 0.5 }; - - double coords2[16]={ - 0.15, -0.07999999999999999, 0, -0.07999999999999996, 0.6, -0.08, 0.45, -0.08, - 0.07500000000000001, -0.07999999999999997, 0.3, 0.22, 0.5249999999999999, -0.08, 0.3, 0.06999999999999999 }; - - int tab8[8]={ - 0, 1, 2, 3, 4, 5, 6, 7 }; - QuadraticPolygon *pol1=buildQuadraticPolygonCoarseInfo(coords,tab8,8); - QuadraticPolygon *pol2=buildQuadraticPolygonCoarseInfo(coords2,tab8,8); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.00902229,pol1->intersectWith(*pol2),1.e-8); - delete pol1; - delete pol2; - pol1=buildQuadraticPolygonCoarseInfo(coords,tab8,8); - pol2=buildQuadraticPolygonCoarseInfo(coords2,tab8,8); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.00902229,pol2->intersectWith(*pol1),1.e-8); - delete pol1; - delete pol2; -} - -void QuadraticPlanarInterpTest::checkNonRegressionOmar0023() -{ - INTERP_KERNEL::QUADRATIC_PLANAR::setPrecision(1e-7); - INTERP_KERNEL::QUADRATIC_PLANAR::setArcDetectionPrecision(1e-7); - double coords[16]={ - -0.5, 6.123031769111886e-17, -0.8, 9.796850830579018e-17, 0.8, 0, 0.5, 0, - -0.65, 7.959941299845453e-17, 4.898425415289509e-17, 0.8, 0.65, 0, 3.061515884555943e-17, 0.5, }; - - double coords2[16]={ - 0.4156854249492381, 0.5656854249492381, 0.2656854249492381, 0.5656854249492381, 0.8656854249492381, 0.5656854249492381, 0.7156854249492381, 0.5656854249492381, - 0.3406854249492381, 0.5656854249492381, 0.5656854249492381, 0.8656854249492381, 0.7906854249492381, 0.5656854249492381, 0.5656854249492381, 0.7156854249492381 }; - - int tab8[8]={ - 0, 1, 2, 3, 4, 5, 6, 7 }; - QuadraticPolygon *pol1=buildQuadraticPolygonCoarseInfo(coords,tab8,8); - QuadraticPolygon *pol2=buildQuadraticPolygonCoarseInfo(coords2,tab8,8); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.0215659,pol1->intersectWith(*pol2),1.e-7); - delete pol1; - delete pol2; - pol1=buildQuadraticPolygonCoarseInfo(coords,tab8,8); - pol2=buildQuadraticPolygonCoarseInfo(coords2,tab8,8); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.0215659,pol2->intersectWith(*pol1),1.e-7); - delete pol1; - delete pol2; -} - -void QuadraticPlanarInterpTest::checkNonRegressionOmar0024() -{ - INTERP_KERNEL::QUADRATIC_PLANAR::setPrecision(1e-7); - INTERP_KERNEL::QUADRATIC_PLANAR::setArcDetectionPrecision(1e-7); - double coords[16]={ - -0.5, 6.123031769111886e-17, -0.8, 9.796850830579018e-17, 0.8, 0, 0.5, 0, --0.65, 7.959941299845453e-17, 4.898425415289509e-17, 0.8, 0.65, 0, 3.061515884555943e-17, 0.5 }; - double coords2[16]={ - 0.5656854249492381, 0.5656854249492381, 0.4156854249492382, 0.5656854249492381, 1.015685424949238, 0.5656854249492381, 0.8656854249492382, 0.5656854249492381, -0.4906854249492382, 0.5656854249492381, 0.7156854249492381, 0.8656854249492381, 0.9406854249492381, 0.5656854249492381, 0.7156854249492381, 0.7156854249492381 }; - - int tab8[8]={ - 0, 1, 2, 3, 4, 5, 6, 7 }; - QuadraticPolygon *pol1=buildQuadraticPolygonCoarseInfo(coords,tab8,8); - QuadraticPolygon *pol2=buildQuadraticPolygonCoarseInfo(coords2,tab8,8); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.00877657,pol1->intersectWith(*pol2),1.e-8); - delete pol1; - delete pol2; - pol1=buildQuadraticPolygonCoarseInfo(coords,tab8,8); - pol2=buildQuadraticPolygonCoarseInfo(coords2,tab8,8); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.00877657,pol2->intersectWith(*pol1),1.e-8); - delete pol1; - delete pol2; -} - -void QuadraticPlanarInterpTest::checkNonRegressionOmar2524() -{ - INTERP_KERNEL::QUADRATIC_PLANAR::setPrecision(1e-7); - INTERP_KERNEL::QUADRATIC_PLANAR::setArcDetectionPrecision(1e-7); - double coords[16]={ - -0.5, 6.123031769111886e-17, -0.8, 9.796850830579018e-17, 0.8, 0, 0.5, 0, --0.65, 7.959941299845453e-17, 4.898425415289509e-17, 0.8, 0.65, 0, 3.061515884555943e-17, 0.5 }; - double coords2[16]={ - 0.4156854249492382, 0.5656854249492381, 1.015685424949238, 0.5656854249492381, 0.8656854249492382, 0.5656854249492381, 0.5656854249492381, 0.5656854249492381, -0.7156854249492381, 0.8656854249492381, 0.9406854249492381, 0.5656854249492381, 0.7156854249492381, 0.7156854249492381, 0.4906854249492382, 0.5656854249492381 }; - - int tab8[8]={ - 0, 1, 2, 3, 4, 5, 6, 7 }; - QuadraticPolygon *pol1=buildQuadraticPolygonCoarseInfo(coords,tab8,8); - QuadraticPolygon *pol2=buildQuadraticPolygonCoarseInfo(coords2,tab8,8); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.00877657,pol1->intersectWith(*pol2),1.e-8); - delete pol1; - delete pol2; - pol1=buildQuadraticPolygonCoarseInfo(coords,tab8,8); - pol2=buildQuadraticPolygonCoarseInfo(coords2,tab8,8); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.00877657,pol2->intersectWith(*pol1),1.e-8); - delete pol1; - delete pol2; -} - -void QuadraticPlanarInterpTest::checkNonRegressionOmar0025() -{ - INTERP_KERNEL::QUADRATIC_PLANAR::setPrecision(1e-7); - INTERP_KERNEL::QUADRATIC_PLANAR::setArcDetectionPrecision(1e-7); - double coords[16]={ - -0.5, 6.123031769111886e-17, -0.8, 9.796850830579018e-17, 0.8, 0, 0.5, 0, - -0.65, 7.959941299845453e-17, 4.898425415289509e-17, 0.8, 0.65, 0, 3.061515884555943e-17, 0.5 }; - - double coords2[16]={ - 0.715685424949238, 0.5656854249492381, 0.565685424949238, 0.5656854249492381, 1.165685424949238, 0.5656854249492381, 1.015685424949238, 0.5656854249492381, - 0.6406854249492381, 0.5656854249492381, 0.8656854249492381, 0.8656854249492381, 1.090685424949238, 0.5656854249492381, 0.8656854249492381, 0.7156854249492381 }; - - int tab8[8]={ - 0, 1, 2, 3, 4, 5, 6, 7 }; - QuadraticPolygon *pol1=buildQuadraticPolygonCoarseInfo(coords,tab8,8); - QuadraticPolygon *pol2=buildQuadraticPolygonCoarseInfo(coords2,tab8,8); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.,pol1->intersectWith(*pol2),1.e-13); - delete pol1; - delete pol2; - pol1=buildQuadraticPolygonCoarseInfo(coords,tab8,8); - pol2=buildQuadraticPolygonCoarseInfo(coords2,tab8,8); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.,pol2->intersectWith(*pol1),1.e-13); - delete pol1; - delete pol2; - // - std::vector val3; - pol1=buildQuadraticPolygonCoarseInfo(coords,tab8,8); - pol2=buildQuadraticPolygonCoarseInfo(coords2,tab8,8); - pol1->intersectForPoint(*pol2,val3); - int test3_res[4]={0,1,0,0}; - CPPUNIT_ASSERT(std::equal(val3.begin(),val3.end(),test3_res)); - delete pol1; - delete pol2; -} - -void QuadraticPlanarInterpTest::checkNonRegressionOmar0026() -{ - INTERP_KERNEL::QUADRATIC_PLANAR::setPrecision(1e-7); - INTERP_KERNEL::QUADRATIC_PLANAR::setArcDetectionPrecision(1e-7); - double coords[16]={ - -0.4, 4.898425415289509e-17, -0.75, 9.184547653667829e-17, 0.75, 0, 0.4, 0, - -0.575, 7.041486534478669e-17, 4.592273826833915e-17, 0.75, 0.575, 0, 2.449212707644755e-17, 0.4 }; - - double coords2[16]={ - 0.1, 0.95, 0.2, 0.95, -0.2, 0.95, -0.1, 0.95, - 0.15, 0.95, 1.224606353822377e-17, 0.75, -0.15, 0.95, 6.123031769111886e-18, 0.85 }; - - int tab8[8]={ - 0, 1, 2, 3, 4, 5, 6, 7 }; - QuadraticPolygon *pol1=buildQuadraticPolygonCoarseInfo(coords,tab8,8); - QuadraticPolygon *pol2=buildQuadraticPolygonCoarseInfo(coords2,tab8,8); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.,pol1->intersectWith(*pol2),1.e-13); - delete pol1; - delete pol2; - pol1=buildQuadraticPolygonCoarseInfo(coords,tab8,8); - pol2=buildQuadraticPolygonCoarseInfo(coords2,tab8,8); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.,pol2->intersectWith(*pol1),1.e-13); - delete pol1; - delete pol2; - // - std::vector val3; - pol1=buildQuadraticPolygonCoarseInfo(coords,tab8,8); - pol2=buildQuadraticPolygonCoarseInfo(coords2,tab8,8); - pol1->intersectForPoint(*pol2,val3); - int test3_res[4]={0,1,0,0}; - CPPUNIT_ASSERT(std::equal(val3.begin(),val3.end(),test3_res)); - delete pol1; - delete pol2; -} - -void QuadraticPlanarInterpTest::checkNonRegressionOmar0027() -{ - INTERP_KERNEL::QUADRATIC_PLANAR::setPrecision(1e-7); - INTERP_KERNEL::QUADRATIC_PLANAR::setArcDetectionPrecision(1e-7); - double coords[16]={ - -0.4, 4.898425415289509e-17, -0.75, 9.184547653667829e-17, 0.75, 0, 0.4, 0, - -0.575, 7.041486534478669e-17, 4.592273826833915e-17, 0.75, 0.575, 0, 2.449212707644755e-17, 0.4 }; - - double coords2[16]={ - -0.1, 0.7, -0.2, 0.7, 0.2, 0.7, 0.1, 0.7, - -0.15, 0.7, 1.224606353822377e-17, 0.8999999999999999, 0.15, 0.7, 6.123031769111886e-18, 0.7999999999999999 }; - - int tab8[8]={ - 0, 1, 2, 3, 4, 5, 6, 7 }; - QuadraticPolygon *pol1=buildQuadraticPolygonCoarseInfo(coords,tab8,8); - QuadraticPolygon *pol2=buildQuadraticPolygonCoarseInfo(coords2,tab8,8); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.00712309,pol1->intersectWith(*pol2),1.e-8); - delete pol1; - delete pol2; - pol1=buildQuadraticPolygonCoarseInfo(coords,tab8,8); - pol2=buildQuadraticPolygonCoarseInfo(coords2,tab8,8); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.00712309,pol2->intersectWith(*pol1),1.e-8); - delete pol1; - delete pol2; - // - pol1=buildQuadraticPolygonCoarseInfo(coords,tab8,8); - pol2=buildQuadraticPolygonCoarseInfo(coords2,tab8,8); - std::vector val1,val2; - pol1->intersectForPerimeterAdvanced(*pol2,val1,val2); - double test1_res[4]={0.,0.222704,0.,0.}; - double test2_res[4]={0.1,0.0465335,0.1,0.092554}; - CPPUNIT_ASSERT(std::equal(val1.begin(),val1.end(),test1_res,DoubleEqual(1e-6))); - CPPUNIT_ASSERT(std::equal(val2.begin(),val2.end(),test2_res,DoubleEqual(1e-6))); - delete pol1; - delete pol2; - std::vector val3; - pol1=buildQuadraticPolygonCoarseInfo(coords,tab8,8); - pol2=buildQuadraticPolygonCoarseInfo(coords2,tab8,8); - pol1->intersectForPoint(*pol2,val3); - int test3_res[4]={0,4,0,0}; - CPPUNIT_ASSERT(std::equal(val3.begin(),val3.end(),test3_res)); - delete pol1; - delete pol2; -} - -void QuadraticPlanarInterpTest::checkNonRegressionOmar0028() -{ - INTERP_KERNEL::QUADRATIC_PLANAR::setPrecision(1e-7); - INTERP_KERNEL::QUADRATIC_PLANAR::setArcDetectionPrecision(1e-7); - double coords[16]={ - -0.4, 4.898425415289509e-17, -0.75, 9.184547653667829e-17, 0.75, 0, 0.4, 0, - -0.575, 7.041486534478669e-17, 4.592273826833915e-17, 0.75, 0.575, 0, 2.449212707644755e-17, 0.4 }; - - double coords2[16]={ - -0.07071067811865477, 0.4792893218813453, -0.1414213562373095, 0.4085786437626905, 0.1414213562373095, 0.6914213562373095, 0.07071067811865477, 0.6207106781186548, - -0.1060660171779822, 0.4439339828220179, -0.1414213562373095, 0.6914213562373096, 0.1060660171779822, 0.6560660171779822, -0.07071067811865475, 0.6207106781186548 }; - - int tab8[8]={ - 0, 1, 2, 3, 4, 5, 6, 7 }; - QuadraticPolygon *pol1=buildQuadraticPolygonCoarseInfo(coords,tab8,8); - QuadraticPolygon *pol2=buildQuadraticPolygonCoarseInfo(coords2,tab8,8); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.0471239,pol1->intersectWith(*pol2),1.e-7); - delete pol1; - delete pol2; - pol1=buildQuadraticPolygonCoarseInfo(coords,tab8,8); - pol2=buildQuadraticPolygonCoarseInfo(coords2,tab8,8); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.0471239,pol2->intersectWith(*pol1),1.e-7); - delete pol1; - delete pol2; - // - pol1=buildQuadraticPolygonCoarseInfo(coords,tab8,8); - pol2=buildQuadraticPolygonCoarseInfo(coords2,tab8,8); - std::vector val1,val2; - pol1->intersectForPerimeterAdvanced(*pol2,val1,val2); - double test1_res[4]={0.,0.,0.,0.}; - double test2_res[4]={0.1,0.628319,0.1,0.314159}; - CPPUNIT_ASSERT(std::equal(val1.begin(),val1.end(),test1_res,DoubleEqual(1e-6))); - CPPUNIT_ASSERT(std::equal(val2.begin(),val2.end(),test2_res,DoubleEqual(1e-6))); - delete pol1; - delete pol2; - std::vector val3; - pol1=buildQuadraticPolygonCoarseInfo(coords,tab8,8); - pol2=buildQuadraticPolygonCoarseInfo(coords2,tab8,8); - pol1->intersectForPoint(*pol2,val3); - int test3_res[4]={0,1,0,0}; - CPPUNIT_ASSERT(std::equal(val3.begin(),val3.end(),test3_res)); - delete pol1; - delete pol2; -} - -void QuadraticPlanarInterpTest::checkNonRegressionOmar0029() -{ - INTERP_KERNEL::QUADRATIC_PLANAR::setPrecision(1e-7); - INTERP_KERNEL::QUADRATIC_PLANAR::setArcDetectionPrecision(1e-7); - double coords[16]={ - -0.4, 4.898425415289509e-17, -0.75, 9.184547653667829e-17, 0.75, 0, 0.4, 0, - -0.575, 7.041486534478669e-17, 4.592273826833915e-17, 0.75, 0.575, 0, 2.449212707644755e-17, 0.4 }; - - double coords2[16]={ - -0.07071067811865477, 0.1292893218813453, -0.1414213562373095, 0.05857864376269051, 0.1414213562373095, 0.3414213562373095, 0.07071067811865477, 0.2707106781186548, - -0.1060660171779822, 0.09393398282201787, -0.1414213562373095, 0.3414213562373095, 0.1060660171779822, 0.3060660171779822, -0.07071067811865475, 0.2707106781186548 }; - - int tab8[8]={ - 0, 1, 2, 3, 4, 5, 6, 7 }; - QuadraticPolygon *pol1=buildQuadraticPolygonCoarseInfo(coords,tab8,8); - QuadraticPolygon *pol2=buildQuadraticPolygonCoarseInfo(coords2,tab8,8); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.,pol1->intersectWith(*pol2),1.e-13); - delete pol1; - delete pol2; - pol1=buildQuadraticPolygonCoarseInfo(coords,tab8,8); - pol2=buildQuadraticPolygonCoarseInfo(coords2,tab8,8); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.,pol2->intersectWith(*pol1),1.e-13); - delete pol1; - delete pol2; - // - pol1=buildQuadraticPolygonCoarseInfo(coords,tab8,8); - pol2=buildQuadraticPolygonCoarseInfo(coords2,tab8,8); - std::vector val1,val2; - pol1->intersectForPerimeterAdvanced(*pol2,val1,val2); - double test1_res[4]={0.,0.,0.,0.}; - double test2_res[4]={0.,0.,0.,0.}; - CPPUNIT_ASSERT(std::equal(val1.begin(),val1.end(),test1_res,DoubleEqual(1e-13))); - CPPUNIT_ASSERT(std::equal(val2.begin(),val2.end(),test2_res,DoubleEqual(1e-13))); - delete pol1; - delete pol2; - std::vector val3; - pol1=buildQuadraticPolygonCoarseInfo(coords,tab8,8); - pol2=buildQuadraticPolygonCoarseInfo(coords2,tab8,8); - pol1->intersectForPoint(*pol2,val3); - int test3_res[4]={0,0,0,1}; - CPPUNIT_ASSERT(std::equal(val3.begin(),val3.end(),test3_res)); - delete pol1; - delete pol2; -} - -void QuadraticPlanarInterpTest::checkNonRegressionOmar0030() -{ - INTERP_KERNEL::QUADRATIC_PLANAR::setPrecision(1e-7); - INTERP_KERNEL::QUADRATIC_PLANAR::setArcDetectionPrecision(1e-7); - double coords[16]={ - -0.4, 4.898425415289509e-17, -0.75, 9.184547653667829e-17, 0.75, 0, 0.4, 0, - -0.575, 7.041486534478669e-17, 4.592273826833915e-17, 0.75, 0.575, 0, 2.449212707644755e-17, 0.4 }; - - double coords2[16]={ - -0.4889087296526012, 0.3889087296526012, -0.5889087296526012, 0.3889087296526012, -0.1889087296526012, 0.3889087296526012, -0.2889087296526012, 0.3889087296526012, - -0.5389087296526012, 0.3889087296526012, -0.3889087296526012, 0.5889087296526012, -0.2389087296526012, 0.3889087296526012, -0.3889087296526012, 0.4889087296526012 }; - - int tab8[8]={ - 0, 1, 2, 3, 4, 5, 6, 7 }; - QuadraticPolygon *pol1=buildQuadraticPolygonCoarseInfo(coords,tab8,8); - QuadraticPolygon *pol2=buildQuadraticPolygonCoarseInfo(coords2,tab8,8); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.0471239,pol1->intersectWith(*pol2),1.e-7); - delete pol1; - delete pol2; - pol1=buildQuadraticPolygonCoarseInfo(coords,tab8,8); - pol2=buildQuadraticPolygonCoarseInfo(coords2,tab8,8); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.0471239,pol2->intersectWith(*pol1),1.e-7); - delete pol1; - delete pol2; - // - pol1=buildQuadraticPolygonCoarseInfo(coords,tab8,8); - pol2=buildQuadraticPolygonCoarseInfo(coords2,tab8,8); - std::vector val1,val2; - pol1->intersectForPerimeterAdvanced(*pol2,val1,val2); - double test1_res[4]={0.,0.,0.,0.}; - double test2_res[4]={0.1,0.628319,0.1,0.314159}; - CPPUNIT_ASSERT(std::equal(val1.begin(),val1.end(),test1_res,DoubleEqual(1e-6))); - CPPUNIT_ASSERT(std::equal(val2.begin(),val2.end(),test2_res,DoubleEqual(1e-6))); - delete pol1; - delete pol2; - std::vector val3; - pol1=buildQuadraticPolygonCoarseInfo(coords,tab8,8); - pol2=buildQuadraticPolygonCoarseInfo(coords2,tab8,8); - pol1->intersectForPoint(*pol2,val3); - int test3_res[4]={0,1,0,0}; - CPPUNIT_ASSERT(std::equal(val3.begin(),val3.end(),test3_res)); - delete pol1; - delete pol2; -} - -void QuadraticPlanarInterpTest::checkIsInOrOut() -{ - double coords[8]={ 0.30662641093707971, -0.47819928619088981, - -0.47819928619088964, 0.30662641093707987, - 0.0, 0.0, - 0.4, 0.4 - }; - coords[4] = (coords[0] + coords[2]) / 2.0; - coords[5] = (coords[1] + coords[3]) / 2.0; - - int tab4[4]={ 0, 1, 2, 3}; - QuadraticPolygon *pol1=buildQuadraticPolygonCoarseInfo(coords,tab4,4); - Node * n = new Node(0.3175267678416348, -0.4890996430954449); - - CPPUNIT_ASSERT(! pol1->isInOrOut(n)); // node should be out - n->decrRef(); - delete pol1; -} - -void QuadraticPlanarInterpTest::checkGetMiddleOfPoints() -{ - { // from testIntersect2DMeshWith1DLine6() - double p1[] = {0.51641754716735844, 2.0}; - double p2[] = {0.0, 1.0}; - double e_center[] = {-0.71, 2.0}; - double mid[] = {0.0,0.0}; // out - double mide[] = {0.0,0.0}; // expected - - Node * start = new Node(0.,0.); Node * end = new Node(0.,0.); // unused - // start, end, center_x, center_y, radius, angle0, angle - EdgeArcCircle e(start, end, e_center, 1.2264175471673588, -0.9533904350433241, 0.95339043504332388); - - e.getMiddleOfPoints(p1, p2, mid); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.37969180470645592, mid[0], 1.e-7); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1.4372640310451197, mid[1], 1.e-7); - - e.getMiddleOfPoints(p2, p1, mid); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.37969180470645592, mid[0], 1.e-7); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1.4372640310451197, mid[1], 1.e-7); - - start->decrRef(); end->decrRef(); - } - { // from testSwig2Intersect2DMeshWith1DLine11() - double p1[] = {-1., 0.23453685964236054}; - double p2[] = {-0.23453685964235979, 1.0}; - double e_center[] = {-4.85, 4.85}; - double mid[] = {0.0,0.0}; // out - - Node * start = new Node(0.,0.); Node * end = new Node(0.,0.); // unused - // start, end, center_x, center_y, radius, angle0, angle - EdgeArcCircle e(start, end, e_center, 6.0104076400856474, -0.69522150912422953, -0.18035330854643861); - - e.getMiddleOfPoints(p1, p2, mid); - CPPUNIT_ASSERT_DOUBLES_EQUAL(-0.6, mid[0], 1.e-7); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.6, mid[1], 1.e-7); - - e.getMiddleOfPoints(p2, p1, mid); - CPPUNIT_ASSERT_DOUBLES_EQUAL(-0.6, mid[0], 1.e-7); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.6, mid[1], 1.e-7); - - start->decrRef(); end->decrRef(); - } - { // from testSwig2Intersect2DMeshWith1DLine11() - double p1[] = {-0.1303327636866019, -1.0}; - double p2[] = {-1.0, -0.1303327636866019}; - double e_center[] = {-1.9833333333333298, -1.9833333333333298}; - double mid[] = {0.0,0.0}; // out - - Node * start = new Node(0.,0.); Node * end = new Node(0.,0.); // unused - // start, end, center_x, center_y, radius, angle0, angle - EdgeArcCircle e(start, end, e_center, 2.0977501175200861, 1.0829141821052615, -0.59503203741562627); - - e.getMiddleOfPoints(p1, p2, mid); - CPPUNIT_ASSERT_DOUBLES_EQUAL(-0.5, mid[0], 1.e-7); - CPPUNIT_ASSERT_DOUBLES_EQUAL(-0.5, mid[1], 1.e-7); - - e.getMiddleOfPoints(p2, p1, mid); - CPPUNIT_ASSERT_DOUBLES_EQUAL(-0.5, mid[0], 1.e-7); - CPPUNIT_ASSERT_DOUBLES_EQUAL(-0.5, mid[1], 1.e-7); - - start->decrRef(); end->decrRef(); - } -} - -void QuadraticPlanarInterpTest::checkGetMiddleOfPointsOriented() -{ - { // from testSwig2Colinearize2D3() - double p1[] = {-0.70710678118654746, 0.70710678118654757}; - double p2[] = {-0.70710678118654768, -0.70710678118654746}; - double e_center[] = {0., 0.}; - double mid[] = {0.0,0.0}; // out - - Node * start = new Node(0.,0.); Node * end = new Node(0.,0.); // unused - // start, end, center_x, center_y, radius, angle0, angle - EdgeArcCircle e(start, end, e_center, 1.0, -0.7853981633974485, -1.5707963267948966); - - e.getMiddleOfPointsOriented(p1, p2, mid); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1., mid[0], 1.e-7); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0., mid[1], 1.e-7); - - e.getMiddleOfPoints(p1, p2, mid); - CPPUNIT_ASSERT_DOUBLES_EQUAL(-1., mid[0], 1.e-7); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0., mid[1], 1.e-7); - - e.getMiddleOfPointsOriented(p2, p1, mid); - CPPUNIT_ASSERT_DOUBLES_EQUAL(-1., mid[0], 1.e-7); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0., mid[1], 1.e-7); - - start->decrRef(); end->decrRef(); - } -} - -} diff --git a/src/INTERP_KERNELTest/SingleElementPlanarTests.cxx b/src/INTERP_KERNELTest/SingleElementPlanarTests.cxx deleted file mode 100644 index 185b9accd..000000000 --- a/src/INTERP_KERNELTest/SingleElementPlanarTests.cxx +++ /dev/null @@ -1,1053 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// - -#include "SingleElementPlanarTests.hxx" -#include "InterpolationUtils.hxx" -#include "PolygonAlgorithms.hxx" -#include "PolygonAlgorithms.txx" -#include "InterpolationPlanarTestSuite.hxx" -#include - -using namespace INTERP_KERNEL; - -namespace INTERP_TEST -{ - const double _Epsilon = 1.e-12; - const double _Precision = 1.e-12; - const double _losange1[8] = { 1,0, 0,1, -1,0, 0,-1 }; - const double _losange2[8] = { 2,0, 1,1, 0,0, 1,-1 }; - const double _losange3[8] = {2.5,0.5,1.5,1.5,0.5,0.5,1.5,-0.5 }; - const double _square1[8] = { -1,-1, -1,1, 1,1, 1,-1}; - const double _square2[8] = {1,-0.25,0,-0.25,0,0.25,1,0.25 }; - const double _losange4[8] = { 3,0, 2,1, 1,0, 2,-1 }; - const double _losange5[8] = { 1.5,0, 0,1.5,-1.5,0, 0,-1.5 }; - const double _losange6[12]= { 2,0, 1,1, 0.5,0.5,0,0, 0.5,-0.5, 1,-1 }; - const double _losange7[10]= { 1,0, 0,1, -1,0, 0,-1, 0.5,-0.5 }; - const double _square3[10] = { -1,-1, -1,1, 0.5,1, 1,1, 1,-1, }; - const double _square4[8] = {-0.5,-1,-0.5,1,1.5,1,1.5,-1 }; - const double _square5[10] = { -1,-1, -1,1, 0,1, 1,1, 1,-1 }; - const double _losange8[8] = { 0,1, 1,-1, 0,-1.5,-0.5,-1 }; - const double _losange9[8] = {0.5,0, 0,1, -1.5,0, 0,-1 }; - const double _hexagon1[12]= { -2,0, -1,-1, 1,-1, 2,0, 1,1, -1,1 }; - const double _hexagon2[12]= {-1.5,0.5,-1,-1, 1,-1, 2,1, 1,1, -1,1 }; - const double _hexagon3[12]= { -2,2, -1,1, 1,1, 2,2, 1,3, -1,3 }; - const double _square6[8] = { -1,1, -1,3, 0.5,3,0.5,1 }; - const double _losange10[8]= { 0,-1, 1,-2, 0,-3, -1,-2 }; - const double _triangle1[6]= {0.5,0, 1,1, 0,1 }; - const double _triangle2[6]= { 0,0.5, 0,-0.5,1.5,0 }; - const double _triangle3[9]= {-1,2,0, 1,2,0, 0,2,1 }; - const double _triangle4[9]= {1./2,2,0, 1, 2, 1, 1, 2, 0.5 }; - const double _parallel1[8] = {-1,0, -0.5,1, 0.5,1, 0,0}; - const double _parallel2[8]= {-0.5,1, 0,0, 1.,0, 0.5,1 }; - const double _parallel3[8]= {-0.5,-1, 0,0, 1,0, 0.5,-1}; - const double _triangle5[6]= { 0,0, 0,0.5, 0.5,0.5 }; - const double _triangle6[6]= { 1./3,1./3, 1./3,2./3, 2./3,2./3 }; - const double _triangle7[6]= {0.5,2, 1,1, 0,1 }; - const double _triangle8[6]= {22.4601,35.2129, 13.9921,34.693, 18.2853,26.2812 }; - const double _triangle9[6]= {13.9921,34.693, 22.4601,35.2129, 18.2785,42.3869 }; - const double _triangle10[6]= {84.8575,98.2042, 80,100, 82.2601,95.7202}; - const double _triangle11[6]= {80,100, 76.6659,91.9804, 85.3912,92.5061 }; - - // Two diamonds intersecting without degeneracy (two distinct crossing points) - // /\ /\ - // / \/ \ - // / /\ \ - // / / \ \ - // \ \ / / - // \ \/ / - // \ /\ / - // \/ \/ - - - // \brief Status : pass - void SingleElementPlanarTests::diamondsBasic() - { - INTERP_KERNEL::PolygonAlgorithms<2> intersector (_Epsilon, _Precision);; - std::deque< double > actual_result = intersector.intersectConvexPolygons(_losange1,_losange2,4,4); - std::deque< double > expected_result; - - expected_result.push_back(0.5);expected_result.push_back(-0.5); - expected_result.push_back(0);expected_result.push_back(0); - expected_result.push_back(0.5);expected_result.push_back(0.5); - expected_result.push_back(1);expected_result.push_back(0); - - CPPUNIT_ASSERT_MESSAGE("Basic diamond crossing test failed (CONVEX)", - (INTERP_KERNEL::checkEqualPolygons,2>(&actual_result, &expected_result, _Epsilon))); - } - - void SingleElementPlanarTests::diamondsBasic_Triangulation() - { - std::vector< double > actual_result; - INTERP_KERNEL::intersec_de_polygone<2>(_losange1,_losange2,4,4,actual_result,_Epsilon/_Precision, _Precision ); - - std::vector< double > expected_result; - expected_result.push_back(1);expected_result.push_back(0); - expected_result.push_back(0.5);expected_result.push_back(0.5); - expected_result.push_back(0);expected_result.push_back(0); - expected_result.push_back(0.5);expected_result.push_back(-0.5); - - CPPUNIT_ASSERT_MESSAGE("Basic diamond crossing test failed (TRIANGULATION)", - (INTERP_KERNEL::checkEqualPolygons,2>(&actual_result, &expected_result, _Epsilon))); - } - - - // Two diamonds with overlapping edges in an exclusion configuration - // /\ - // / \ - // /\ / \ - // / \/ \ - // / \ / - // / \ / - // \ /\ / - // \ / \/ - // \ / - // \/ - // \brief Status : pass - void SingleElementPlanarTests::tangentDiamonds() - { - INTERP_KERNEL::PolygonAlgorithms<2> intersector (_Epsilon, _Precision);; - std::deque< double > actual_result = intersector.intersectConvexPolygons(_losange1,_losange3,4,4); - std::deque< double > expected_result; - - CPPUNIT_ASSERT_MESSAGE("Diamond exclusion tangency test failed (CONVEX)", - (INTERP_KERNEL::checkEqualPolygons,2>(&actual_result, &expected_result, _Epsilon))); - } - void SingleElementPlanarTests::tangentDiamonds_Triangulation() - { - std::vector< double > actual_result; - INTERP_KERNEL::intersec_de_polygone<2>(_losange1,_losange3,4,4,actual_result,_Epsilon/_Precision, _Precision ); - - std::vector< double > expected_result; - expected_result.push_back(0.5);expected_result.push_back(0.5); - expected_result.push_back(1);expected_result.push_back(0); - - CPPUNIT_ASSERT_MESSAGE("Diamond exclusion tangency test failed (TRIANGULATION)", - (INTERP_KERNEL::checkEqualPolygons,2>(&actual_result, &expected_result, _Epsilon))); - } - - // Two tangent squares with overlapping edges, in an inclusion configuration - // _____________ - // | | - // | _______| - // | | | - // | |_______| - // | | - // |_____________| - - // \brief Status : pass - void SingleElementPlanarTests::tangentSquares() - { - INTERP_KERNEL::PolygonAlgorithms<2> intersector (_Epsilon, _Precision);; - std::deque< double > actual_result = intersector.intersectConvexPolygons(_square1,_square2,4,4); - std::deque< double > expected_result; - - expected_result.push_back(0.);expected_result.push_back(0.25); - expected_result.push_back(0.);expected_result.push_back(-0.25); - expected_result.push_back(1.);expected_result.push_back(-0.25); - expected_result.push_back(1.);expected_result.push_back(0.25); - - CPPUNIT_ASSERT_MESSAGE("Squares inclusion tangency test failed (CONVEX)", - (INTERP_KERNEL::checkEqualPolygons,2>(&actual_result, &expected_result, _Epsilon))); - } - void SingleElementPlanarTests::tangentSquares_Triangulation() - { - std::vector< double > actual_result; - INTERP_KERNEL::intersec_de_polygone<2>(_square1,_square2,4,4,actual_result,_Epsilon/_Precision, _Precision ); - - std::vector< double > expected_result; - - expected_result.push_back(1.);expected_result.push_back(0.25); - expected_result.push_back(0.25);expected_result.push_back(0.25); - expected_result.push_back(1./6);expected_result.push_back(1./6); - expected_result.push_back(0.);expected_result.push_back(0.25); - expected_result.push_back(0.);expected_result.push_back(0.); - expected_result.push_back(0.);expected_result.push_back(-0.25); - expected_result.push_back(1.);expected_result.push_back(-0.25); - - CPPUNIT_ASSERT_MESSAGE("Squares inclusion tangency test failed (TRIANGULATION)", - (INTERP_KERNEL::checkEqualPolygons,2>(&actual_result, &expected_result, _Epsilon))); - } - - // Two diamonds sharing a vertex in an exclusion configuration - // /\ /\ - // / \ / \ - // / \ / \ - // / \/ \ - // \ /\ / - // \ / \ / - // \ / \ / - // \/ \/ - - - // \brief Status : pass - void SingleElementPlanarTests::diamondsSharingVertex1() - { - INTERP_KERNEL::PolygonAlgorithms<2> intersector (_Epsilon, _Precision);; - std::deque< double > actual_result = intersector.intersectConvexPolygons(_losange1,_losange4,4,4); - std::deque< double > expected_result; - - CPPUNIT_ASSERT_MESSAGE("Diamond sharing (1) vertex test failed (CONVEX)", - (INTERP_KERNEL::checkEqualPolygons,2>(&actual_result, &expected_result, _Epsilon))); - } - void SingleElementPlanarTests::diamondsSharingVertex1_Triangulation() - { - std::vector< double > actual_result; - INTERP_KERNEL::intersec_de_polygone<2>(_losange1,_losange4,4,4,actual_result,_Epsilon/_Precision, _Precision ); - - std::vector< double > expected_result; - expected_result.push_back(1.);expected_result.push_back(0.); - - CPPUNIT_ASSERT_MESSAGE("Diamonds sharing (1) vertex test failed (TRIANGULATION)", - (INTERP_KERNEL::checkEqualPolygons,2>(&actual_result, &expected_result, _Epsilon))); - } - - // Two identical squares - // _____________ - // | | - // | | - // | | - // | | - // | | - // |_____________| - - // \brief Status : pass - void SingleElementPlanarTests::identicalSquares() - { - INTERP_KERNEL::PolygonAlgorithms<2> intersector (_Epsilon, _Precision);; - /* - ////////////////// TEST DESACTIVATED by A. GEAY because memory fault : - // conditional jump INTERP_KERNEL::PolygonAlgorithms<2>::intersectConvexPolygons(double const*, double const*, int, int) (PolygonAlgorithms.txx:629) - std::deque< double > actual_result = intersector.intersectConvexPolygons(_square1,_square1,4,4); - std::deque< double > expected_result; - - expected_result.push_back(-1.);expected_result.push_back(1.); - expected_result.push_back(-1.);expected_result.push_back(-1.); - expected_result.push_back(1.);expected_result.push_back(-1.); - expected_result.push_back(1.);expected_result.push_back(1.); - - CPPUNIT_ASSERT_MESSAGE("Identical squares test failed (CONVEX)", - (INTERP_KERNEL::checkEqualPolygons,2>(&actual_result, &expected_result, _Epsilon))); - */ - } - void SingleElementPlanarTests::identicalSquares_Triangulation() - { - std::vector< double > actual_result; - INTERP_KERNEL::intersec_de_polygone<2>(_square1,_square1,4,4,actual_result,_Epsilon/_Precision, _Precision ); - - std::vector< double > expected_result; - - expected_result.push_back(1.);expected_result.push_back(1.); - expected_result.push_back(-1.);expected_result.push_back(1.); - expected_result.push_back(-1.);expected_result.push_back(-1.); - expected_result.push_back(1.);expected_result.push_back(-1.); - - CPPUNIT_ASSERT_MESSAGE("Identical squares test failed (TRIANGULATION)", - (INTERP_KERNEL::checkEqualPolygons,2>(&actual_result, &expected_result, _Epsilon))); - } - // Square and diamond intersecting with no degeneracy - // /\ - // / \ - // / \ - // __/______\__ - // | / \ | - // |/ \| - // / \ - // /| |\ - // \| |/ - // \ / - // |\ /| - // |_\________/_| - // \ / - // \ / - // \ / - // \/ - // \brief Status : pass - void SingleElementPlanarTests::squareAndDiamondBasic() - { - INTERP_KERNEL::PolygonAlgorithms<2> intersector (_Epsilon, _Precision);; - std::deque< double > actual_result = intersector.intersectConvexPolygons(_square1,_losange5,4,4); - std::deque< double > expected_result; - - expected_result.push_back(1.);expected_result.push_back(0.5); - expected_result.push_back(0.5);expected_result.push_back(1.); - expected_result.push_back(-0.5);expected_result.push_back(1.); - expected_result.push_back(-1.);expected_result.push_back(0.5); - expected_result.push_back(-1.);expected_result.push_back(-0.5); - expected_result.push_back(-0.5);expected_result.push_back(-1.); - expected_result.push_back(0.5);expected_result.push_back(-1.); - expected_result.push_back(1.);expected_result.push_back(-0.5); - - CPPUNIT_ASSERT_MESSAGE("Square and diamond basic test failed (CONVEX)", - (INTERP_KERNEL::checkEqualPolygons,2>(&actual_result, &expected_result, _Epsilon))); - } - void SingleElementPlanarTests::squareAndDiamondBasic_Triangulation() - { - std::vector< double > actual_result; - INTERP_KERNEL::intersec_de_polygone<2>(_square1,_losange5,4,4,actual_result,_Epsilon/_Precision, _Precision ); - - std::vector< double > expected_result; - - expected_result.push_back(1.);expected_result.push_back(0.); - expected_result.push_back(1.);expected_result.push_back(0.5); - expected_result.push_back(0.75);expected_result.push_back(0.75); - expected_result.push_back(0.5);expected_result.push_back(1.); - expected_result.push_back(0.);expected_result.push_back(0.); - expected_result.push_back(-0.5);expected_result.push_back(1.); - expected_result.push_back(-1.);expected_result.push_back(0.5); - expected_result.push_back(-1.);expected_result.push_back(0.); - expected_result.push_back(-1.);expected_result.push_back(-0.5); - expected_result.push_back(-0.75);expected_result.push_back(-0.75); - expected_result.push_back(-0.5);expected_result.push_back(-1.); - expected_result.push_back(0.5);expected_result.push_back(-1.); - expected_result.push_back(1.);expected_result.push_back(-0.5); - - - // EAP: different place of (0,0) point on 32 and 64-bits platforms - // we comment it for the sake of "make check" to pass - //CPPUNIT_ASSERT_MESSAGE("Square and diamond basic test failed (TRIANGULATION), maybe not significant (0,0) should be removed", - //(INTERP_KERNEL::checkEqualPolygons,2>(&actual_result, &expected_result, _Epsilon))); - } - // square and diamond intersecting at four degenerated pointss - // ______ - // | /\ | - // | / \ | - // |/ \| - // |\ /| - // | \ / | - // |__\/__| - // \brief Status : pass - - void SingleElementPlanarTests::squareAndDiamondCritical() - { - INTERP_KERNEL::PolygonAlgorithms<2> intersector (_Epsilon, _Precision);; - std::deque< double > actual_result = intersector.intersectConvexPolygons(_square1,_losange1,4,4); - std::deque< double > expected_result; - - expected_result.push_back(0.);expected_result.push_back(-1.); - expected_result.push_back(-1.);expected_result.push_back(0.); - expected_result.push_back(0.);expected_result.push_back(1.); - expected_result.push_back(1.);expected_result.push_back(0.); - - CPPUNIT_ASSERT_MESSAGE("Square and diamond critical tangency test failed (CONVEX)", - (INTERP_KERNEL::checkEqualPolygons,2>(&actual_result, &expected_result, _Epsilon))); - } - void SingleElementPlanarTests::squareAndDiamondCritical_Triangulation() - { - std::vector< double > actual_result; - INTERP_KERNEL::intersec_de_polygone<2>(_square1,_losange1,4,4,actual_result,_Epsilon/_Precision, _Precision ); - - std::vector< double > expected_result; - - expected_result.push_back(0.5);expected_result.push_back(0.5); - expected_result.push_back(0.);expected_result.push_back(1.); - expected_result.push_back(0);expected_result.push_back(0); - expected_result.push_back(-1.);expected_result.push_back(0.); - expected_result.push_back(-0.5);expected_result.push_back(-0.5); - expected_result.push_back(0.);expected_result.push_back(-1.); - expected_result.push_back(1.);expected_result.push_back(0.); - - // 0020208: Unit Test of MED failed -// CPPUNIT_ASSERT_MESSAGE("Square and diamond basic test failed (TRIANGULATION) maybe not significant (0,0) should be removed", -// (INTERP_KERNEL::checkEqualPolygons,2>(&actual_result, &expected_result, _Epsilon))); - } - // Two diamonds intersecting at one vertex on edge and one double vertex - // /\ /\ - // / \ / \ - // / ¤ \ - // / / \ \ - // \ \ / / - // \ * / - // \ / \ / - // \/ \/ - - - // \brief Status : pass - void SingleElementPlanarTests::diamondsCritical() - { - - INTERP_KERNEL::PolygonAlgorithms<2> intersector (_Epsilon, _Precision);; - std::deque< double > actual_result = intersector.intersectConvexPolygons(_losange6,_losange7,6,5); - std::deque< double > expected_result; - - expected_result.push_back(0.5);expected_result.push_back(-0.5); - expected_result.push_back(0.5);expected_result.push_back(-0.5); - expected_result.push_back(0);expected_result.push_back(0); - expected_result.push_back(0.5);expected_result.push_back(0.5); - expected_result.push_back(0.5);expected_result.push_back(0.5); - expected_result.push_back(1);expected_result.push_back(0); - - CPPUNIT_ASSERT_MESSAGE("Basic diamond crossing test failed (CONVEX)", - (INTERP_KERNEL::checkEqualPolygons,2>(&actual_result, &expected_result, _Epsilon))); - } - void SingleElementPlanarTests::diamondsCritical_Triangulation() - { - std::vector< double > actual_result; - INTERP_KERNEL::intersec_de_polygone<2>(_losange6,_losange7,6,5,actual_result,_Epsilon/_Precision, _Precision ); - - std::vector< double > expected_result; - - expected_result.push_back(1);expected_result.push_back(0); - expected_result.push_back(0.5);expected_result.push_back(0.5); - expected_result.push_back(0);expected_result.push_back(0); - expected_result.push_back(0.5);expected_result.push_back(-0.5); - - CPPUNIT_ASSERT_MESSAGE("Basic diamond crossing test failed (TRIANGULATION)", - (INTERP_KERNEL::checkEqualPolygons,2>(&actual_result, &expected_result, _Epsilon))); - } - - // Two tangent squares with starting and ending vertices on edges - // _____ ___.___ ______ - // | | | | - // | | | | - // | | | | - // | | | | - // | | | | - // |_____|_______|______| - - // \brief Status : pass - void SingleElementPlanarTests::quadranglesCritical() - { - INTERP_KERNEL::PolygonAlgorithms<2> intersector (_Epsilon, _Precision);; - std::deque< double > actual_result = intersector.intersectConvexPolygons(_square4,_square3,4,5); - std::deque< double > expected_result; - - expected_result.push_back(-0.5);expected_result.push_back(1.); - expected_result.push_back(-0.5);expected_result.push_back(-1.); - expected_result.push_back(1.);expected_result.push_back(-1.); - expected_result.push_back(1.);expected_result.push_back(1.); - - CPPUNIT_ASSERT_MESSAGE("Critical quadrangles with tangency test failed (CONVEX)", - (INTERP_KERNEL::checkEqualPolygons,2>(&actual_result, &expected_result, _Epsilon))); - } - void SingleElementPlanarTests::quadranglesCritical_Triangulation() - { - std::vector< double > actual_result; - INTERP_KERNEL::intersec_de_polygone<2>(_square4,_square3,4,5,actual_result,_Epsilon/_Precision, _Precision ); - - std::vector< double > expected_result; - - expected_result.push_back(1.);expected_result.push_back(-1.); - expected_result.push_back(1.);expected_result.push_back(0.5); - expected_result.push_back(1.);expected_result.push_back(1.); - expected_result.push_back(0.5);expected_result.push_back(1.); - expected_result.push_back(-0.5);expected_result.push_back(1.); - expected_result.push_back(-0.5);expected_result.push_back(-1./3); - expected_result.push_back(-0.5);expected_result.push_back(-0.5); - expected_result.push_back(-0.5);expected_result.push_back(-1.); - - CPPUNIT_ASSERT_MESSAGE("Critical quadrangles with tangency test failed (TRIANGULATION)", - (INTERP_KERNEL::checkEqualPolygons,2>(&actual_result, &expected_result, _Epsilon))); - } - - - // square and diamond crossing and tangency at double vertices, starting vertex on edge - // _____.____ - // | / \ | - // | / \ | - // | / \ | - // |_/_______\| - // \ / - // \ / - // \ / - // \ / - // \brief Status : pass - void SingleElementPlanarTests::quadrangleAndDiamondCritical() - { - INTERP_KERNEL::PolygonAlgorithms<2> intersector (_Epsilon, _Precision);; - std::deque< double > actual_result = intersector.intersectConvexPolygons(_square5,_losange8,5,4); - std::deque< double > expected_result; - - expected_result.push_back(0.);expected_result.push_back(1.); - expected_result.push_back(-0.5);expected_result.push_back(-1.); - expected_result.push_back(1.);expected_result.push_back(-1.); - expected_result.push_back(1.);expected_result.push_back(-1.); - - CPPUNIT_ASSERT_MESSAGE("Square and diamond critical tangency test failed (CONVEX)", - (INTERP_KERNEL::checkEqualPolygons,2>(&actual_result, &expected_result, _Epsilon))); - } - void SingleElementPlanarTests::quadrangleAndDiamondCritical_Triangulation() - { - std::vector< double > actual_result; - INTERP_KERNEL::intersec_de_polygone<2>(_square5,_losange8,5,4,actual_result,_Epsilon/_Precision, _Precision ); - - std::vector< double > expected_result; - - expected_result.push_back(1.);expected_result.push_back(-1.); - expected_result.push_back(1./3);expected_result.push_back(1./3); - expected_result.push_back(0.);expected_result.push_back(1.); - expected_result.push_back(0.);expected_result.push_back(0.); - expected_result.push_back(-1./3);expected_result.push_back(-1./3); - expected_result.push_back(-0.5);expected_result.push_back(-1.); - expected_result.push_back(0.);expected_result.push_back(-1.); - - CPPUNIT_ASSERT_MESSAGE("Square and diamond critical tangency test failed (TRIANGULATION)", - (INTERP_KERNEL::checkEqualPolygons,2>(&actual_result, &expected_result, _Epsilon))); - } // square and diamond intersecting at four degenerated pointss - // - // ²/²\ - // ² / ² \ - // ² / ² \ - // ² \ ² / - // ² \ ² / - // ²\²/ - // \brief Status : pass - - void SingleElementPlanarTests::diamondsCritical2() - { - INTERP_KERNEL::PolygonAlgorithms<2> intersector (_Epsilon, _Precision);; - std::deque< double > actual_result = intersector.intersectConvexPolygons(_losange1,_losange9,4,4); - std::deque< double > expected_result; - - expected_result.push_back(0.);expected_result.push_back(-1.); - expected_result.push_back(0.);expected_result.push_back(-1.); - expected_result.push_back(-1.);expected_result.push_back(0.); - expected_result.push_back(0.);expected_result.push_back(1.); - expected_result.push_back(0.);expected_result.push_back(1.); - expected_result.push_back(0.5);expected_result.push_back(0.); - - CPPUNIT_ASSERT_MESSAGE("Diamonds with crossing at double vertex test failed (CONVEX)", - (INTERP_KERNEL::checkEqualPolygons,2>(&actual_result, &expected_result, _Epsilon))); - } - void SingleElementPlanarTests::diamondsCritical2_Triangulation() - { - std::vector< double > actual_result; - INTERP_KERNEL::intersec_de_polygone<2>(_losange1,_losange9,4,4,actual_result,_Epsilon/_Precision, _Precision ); - - std::vector< double > expected_result; - - expected_result.push_back(0.);expected_result.push_back(-1.); - expected_result.push_back(0.5);expected_result.push_back(0.); - expected_result.push_back(0.);expected_result.push_back(1.); - expected_result.push_back(-1.);expected_result.push_back(0.); - - CPPUNIT_ASSERT_MESSAGE("Diamonds with crossing at double vertex test failed (TRIANGULATION)", - (INTERP_KERNEL::checkEqualPolygons,2>(&actual_result, &expected_result, _Epsilon))); - } - - // Two tangent hexagons with double vertices and a critical starting vertex on edge - // _________ - // / \²²² - // ² \² - // / \ - // / ² ² \ - // \ / - // \ ² ² / - // \ / - // \²_______²/ - - - // \brief Status : pass - void SingleElementPlanarTests::hexagonsCritical1() - { - - INTERP_KERNEL::PolygonAlgorithms<2> intersector (_Epsilon, _Precision);; - std::deque< double > actual_result = intersector.intersectConvexPolygons(_hexagon1,_hexagon2,6,6); - std::deque< double > expected_result; - - expected_result.push_back(5./3);expected_result.push_back(1./3); - expected_result.push_back(1.);expected_result.push_back(-1.); - expected_result.push_back(-1.);expected_result.push_back(-1.); - expected_result.push_back(-1.5);expected_result.push_back(0.5); - expected_result.push_back(-1.);expected_result.push_back(1.); - expected_result.push_back(1.);expected_result.push_back(1.); - - CPPUNIT_ASSERT_MESSAGE("First hexagon critical crossing test failed (CONVEX)", - (INTERP_KERNEL::checkEqualPolygons,2>(&actual_result, &expected_result, _Epsilon))); - } - void SingleElementPlanarTests::hexagonsCritical1_Triangulation() - { - std::vector< double > actual_result; - INTERP_KERNEL::intersec_de_polygone<2>(_hexagon1,_hexagon2,6,6,actual_result,_Epsilon/_Precision, _Precision ); - - std::vector< double > expected_result; - - expected_result.push_back(-1.);expected_result.push_back(1.); - expected_result.push_back(-1.5);expected_result.push_back(0.5); - expected_result.push_back(-8./7);expected_result.push_back(2./7); - expected_result.push_back(-1.4);expected_result.push_back(0.2); - expected_result.push_back(-4./3);expected_result.push_back(0.); - expected_result.push_back(-2./3);expected_result.push_back(0.); - expected_result.push_back(-1.25);expected_result.push_back(-0.25); - expected_result.push_back(-1.);expected_result.push_back(-1.); - expected_result.push_back(1.);expected_result.push_back(-1.); - expected_result.push_back(1.5);expected_result.push_back(0.); - expected_result.push_back(5./3);expected_result.push_back(1./3); - expected_result.push_back(1.125);expected_result.push_back(0.875); - expected_result.push_back(1.);expected_result.push_back(1.); - expected_result.push_back(0.25);expected_result.push_back(0.75); - - CPPUNIT_ASSERT_MESSAGE("First hexagon critical crossing test failed (TRIANGULATION)", - (INTERP_KERNEL::checkEqualPolygons,2>(&actual_result, &expected_result, _Epsilon))); - } - - // Two tangent hexagons with double vertices and a critical starting vertex on edge - // _______ - // / \ - // / \ - // \ / - // \_______/ - // / \ - // / \ - // \ / - // \_______/ - - - // \brief Status : pass - void SingleElementPlanarTests::hexagonsCritical2() - { - INTERP_KERNEL::PolygonAlgorithms<2> intersector (_Epsilon, _Precision);; - std::deque< double > actual_result = intersector.intersectConvexPolygons(_hexagon1,_hexagon3,6,6); - std::deque< double > expected_result; - - CPPUNIT_ASSERT_MESSAGE("Second hexagon critical crossing test failed (CONVEX)", - (INTERP_KERNEL::checkEqualPolygons,2>(&actual_result, &expected_result, _Epsilon))); - } - void SingleElementPlanarTests::hexagonsCritical2_Triangulation() - { - std::vector< double > actual_result; - INTERP_KERNEL::intersec_de_polygone<2>(_hexagon1,_hexagon3,6,6,actual_result,_Epsilon/_Precision, _Precision ); - - std::vector< double > expected_result; - expected_result.push_back(1.);expected_result.push_back(1.); - expected_result.push_back(-1.);expected_result.push_back(1.); - - CPPUNIT_ASSERT_MESSAGE("Second hexagon critical crossing test failed (TRIANGULATION)", - (INTERP_KERNEL::checkEqualPolygons,2>(&actual_result, &expected_result, _Epsilon))); - } - - // Square and quadrilateron with outer tangency - // ________ - // | | - // | | - // | | - // |________|___ - // | | - // | | - // | | - // | | - // | | - // |____________| - - // \brief Status : pass - void SingleElementPlanarTests::squareAndQuadrangleCritical() - { - INTERP_KERNEL::PolygonAlgorithms<2> intersector (_Epsilon, _Precision);; - std::deque< double > actual_result = intersector.intersectConvexPolygons(_square1,_square6,4,4); - std::deque< double > expected_result; - - CPPUNIT_ASSERT_MESSAGE("Identical squares test failed (CONVEX)", (INTERP_KERNEL::checkEqualPolygons,2>(&actual_result, &expected_result, _Epsilon))); - } - void SingleElementPlanarTests::squareAndQuadrangleCritical_Triangulation() - { - std::vector< double > actual_result; - INTERP_KERNEL::intersec_de_polygone<2>(_square1,_square6,4,4,actual_result,_Epsilon/_Precision, _Precision ); - - std::vector< double > expected_result; - expected_result.push_back(-1.);expected_result.push_back(1.); - expected_result.push_back(0.5);expected_result.push_back(1.); - - CPPUNIT_ASSERT_MESSAGE("Identical squares test failed (TRIANGULATION)", - (INTERP_KERNEL::checkEqualPolygons,2>(&actual_result, &expected_result, _Epsilon))); - } - // Two diamonds sharing a vertex in an exclusion configuration - // /\ - // / \ - // / \ - // / \ - // \ / - // \ / - // \ / - // \/ - // /\ - // / \ - // / \ - // / \ - // \ / - // \ / - // \ / - // \/ - - - // \brief Status : pass - void SingleElementPlanarTests:: diamondsSharingVertex2() - { - INTERP_KERNEL::PolygonAlgorithms<2> intersector (_Epsilon, _Precision);; - std::deque< double > actual_result = intersector.intersectConvexPolygons(_losange1,_losange10,4,4); - std::deque< double > expected_result; - - CPPUNIT_ASSERT_MESSAGE("Diamond sharing vertex (2) test failed (CONVEX)", - (INTERP_KERNEL::checkEqualPolygons,2>(&actual_result, &expected_result, _Epsilon))); - } - void SingleElementPlanarTests:: diamondsSharingVertex2_Triangulation() - { - std::vector< double > actual_result; - INTERP_KERNEL::intersec_de_polygone<2>(_losange1,_losange10,4,4,actual_result,_Epsilon/_Precision, _Precision ); - - std::vector< double > expected_result; - expected_result.push_back(0.);expected_result.push_back(-1.); - - CPPUNIT_ASSERT_MESSAGE("Diamond sharing vertex (2) test failed (TRIANGULATION)", - (INTERP_KERNEL::checkEqualPolygons,2>(&actual_result, &expected_result, _Epsilon))); - } - - // Triangle and diamond with a critical crossing at double starting vertex - // ____ - // /|\ / - // / | \/ - // / | /\ - // / |/ \ - // \ / - // \ / - // \ / - // \ / - - // \brief Status : pass - void SingleElementPlanarTests:: triangleAndDiamondCritical() - { - INTERP_KERNEL::PolygonAlgorithms<2> intersector (_Epsilon, _Precision);; - std::deque< double > actual_result = intersector.intersectConvexPolygons(_losange1,_triangle1,4,3); - std::deque< double > expected_result; - - expected_result.push_back(2./3);expected_result.push_back(1./3); - expected_result.push_back(0.5);expected_result.push_back(0.); - expected_result.push_back(0.);expected_result.push_back(1.); - - CPPUNIT_ASSERT_MESSAGE("Triangle and diamonds critical test failed (CONVEX)", - (INTERP_KERNEL::checkEqualPolygons,2>(&actual_result, &expected_result, _Epsilon))); - } - void SingleElementPlanarTests:: triangleAndDiamondCritical_Triangulation() - { - std::vector< double > actual_result; - INTERP_KERNEL::intersec_de_polygone<2>(_losange1,_triangle1,4,3,actual_result,_Epsilon/_Precision, _Precision ); - - std::vector< double > expected_result; - - expected_result.push_back(2./3);expected_result.push_back(1./3); - expected_result.push_back(0.);expected_result.push_back(1.); - expected_result.push_back(0.5);expected_result.push_back(0.); - - CPPUNIT_ASSERT_MESSAGE("Triangle and diamonds critical test failed (TRIANGULATION)", - (INTERP_KERNEL::checkEqualPolygons,2>(&actual_result, &expected_result, _Epsilon))); - } - - // Basic triangle and square intersection (two distinct points) - // __________ - // | | - // | |\ | - // | | \| - // | | \ - // | | |\ - // | | |/ - // | | / - // | | /| - // | |/ | - // |__________| - - // \brief Status : pass - void SingleElementPlanarTests::triangleAndSquareBasic() - { - INTERP_KERNEL::PolygonAlgorithms<2> intersector (_Epsilon, _Precision);; - std::deque< double > actual_result = intersector.intersectConvexPolygons(_square1,_triangle2,4,3); - std::deque< double > expected_result; - - expected_result.push_back(1.);expected_result.push_back(1./6); - expected_result.push_back(1.);expected_result.push_back(-1./6); - expected_result.push_back(0.);expected_result.push_back(-0.5); - expected_result.push_back(0.);expected_result.push_back(0.5); - - CPPUNIT_ASSERT_MESSAGE("Identical squares test failed (CONVEX)", - (INTERP_KERNEL::checkEqualPolygons,2>(&actual_result, &expected_result, _Epsilon))); - } - - void SingleElementPlanarTests::triangleAndSquareBasic_Triangulation() - { - std::vector< double > actual_result; - INTERP_KERNEL::intersec_de_polygone<2>(_square1,_triangle2,4,3,actual_result,_Epsilon/_Precision, _Precision ); - - std::vector< double > expected_result; - - expected_result.push_back(1.);expected_result.push_back(1./6); - expected_result.push_back(0.375);expected_result.push_back(0.375); - expected_result.push_back(0.);expected_result.push_back(0.5); - expected_result.push_back(0.);expected_result.push_back(0.); - expected_result.push_back(0.);expected_result.push_back(-0.5); - expected_result.push_back(1.);expected_result.push_back(-1./6); - - CPPUNIT_ASSERT_MESSAGE("Identical squares test failed (TRIANGULATION)", - (INTERP_KERNEL::checkEqualPolygons,2>(&actual_result, &expected_result, _Epsilon))); - } - // Two triangles with a starting vertex on edge - - // /\ ²²²² - // / ² ² - // / ² ² - // /__²___\ - - // \brief Status : pass - void SingleElementPlanarTests::trianglesCritical() - { - INTERP_KERNEL::PolygonAlgorithms<3> intersector (_Epsilon, _Precision);; - std::deque< double > actual_result = intersector.intersectConvexPolygons(_triangle3,_triangle4,3,3); - std::deque< double > expected_result; - - expected_result.push_back(2./3);expected_result.push_back(2.);expected_result.push_back(1./3); - expected_result.push_back(0.5);expected_result.push_back(2.);expected_result.push_back(0.); - expected_result.push_back(0.75);expected_result.push_back(2.);expected_result.push_back(0.25); - - CPPUNIT_ASSERT_MESSAGE("Triangles critical test failed (CONVEX)", - (INTERP_KERNEL::checkEqualPolygons,3>(&actual_result, &expected_result, _Epsilon))); - } - void SingleElementPlanarTests::trianglesCritical_Triangulation() - { - std::vector< double > actual_result; - double _triangle3rotated[6],_triangle4rotated[6]; - for (int i=0; i<3; i++)_triangle3rotated[2*i] = _triangle3[3*i]; - for (int i=0; i<3; i++)_triangle3rotated[2*i+1] = _triangle3[3*i+2]; - for (int i=0; i<3; i++)_triangle4rotated[2*i] = _triangle4[3*i]; - for (int i=0; i<3; i++)_triangle4rotated[2*i+1] = _triangle4[3*i+2]; - - INTERP_KERNEL::intersec_de_polygone<2>(_triangle3rotated,_triangle4rotated,3,3,actual_result,_Epsilon/_Precision, _Precision ); - - std::vector< double > expected_result; - - expected_result.push_back(0.5);expected_result.push_back(0.); - expected_result.push_back(2./3);expected_result.push_back(1./3); - expected_result.push_back(0.75);expected_result.push_back(0.25); - - CPPUNIT_ASSERT_MESSAGE("Triangles critical test failed (TRIANGULATION)", - (INTERP_KERNEL::checkEqualPolygons,2>(&actual_result, &expected_result, _Epsilon))); - } - - // Two tangent paralellograms intersecting at 3 double vertices (one being a starting vertex) - // _______ - // /\ /\ - // / \ / \ - // / \ / \ - // /______\/______\ - - - // \brief Status : pass - void SingleElementPlanarTests::paralellogramsCritical1() - { - INTERP_KERNEL::PolygonAlgorithms<2> intersector (_Epsilon, _Precision);; - std::deque< double > actual_result = intersector.intersectConvexPolygons(_parallel1,_parallel2,4,4); - std::deque< double > expected_result; - - expected_result.push_back(0.);expected_result.push_back(0.); - expected_result.push_back(0.);expected_result.push_back(0.); - expected_result.push_back(-0.5);expected_result.push_back(1.); - expected_result.push_back(0.5);expected_result.push_back(1.); - - CPPUNIT_ASSERT_MESSAGE("Paralellogram tangency test (1) failed (CONVEX)", - (INTERP_KERNEL::checkEqualPolygons,2>(&actual_result, &expected_result, _Epsilon))); - } - void SingleElementPlanarTests::paralellogramsCritical1_Triangulation() - { - std::vector< double > actual_result; - INTERP_KERNEL::intersec_de_polygone<2>(_parallel1,_parallel2,4,4,actual_result,_Epsilon/_Precision, _Precision ); - - std::vector< double > expected_result; - - expected_result.push_back(0.25);expected_result.push_back(0.5); - expected_result.push_back(0.5);expected_result.push_back(1.); - expected_result.push_back(0.);expected_result.push_back(2./3); - expected_result.push_back(-0.5);expected_result.push_back(1.); - expected_result.push_back(-0.25);expected_result.push_back(0.5); - expected_result.push_back(0.);expected_result.push_back(0.); - - CPPUNIT_ASSERT_MESSAGE("Paralellogram tangency test (1) failed (TRIANGULATION)", - (INTERP_KERNEL::checkEqualPolygons,2>(&actual_result, &expected_result, _Epsilon))); - } - - // Two paralellograms sharing a vertex in an exclusion configuration - // ________ - // / / - // / / - // / / - // /_______/_______ - // / / - // / / - // / / - // /_______/ - - - // \brief Status : pass - void SingleElementPlanarTests::paralellogramsCritical2() - { - INTERP_KERNEL::PolygonAlgorithms<2> intersector (_Epsilon, _Precision);; - std::deque< double > actual_result = intersector.intersectConvexPolygons(_parallel1,_parallel3,4,4); - std::deque< double > expected_result; - - CPPUNIT_ASSERT_MESSAGE("Paralellogram tangency test failed (CONVEX)", - (INTERP_KERNEL::checkEqualPolygons,2>(&actual_result, &expected_result, _Epsilon))); - } - void SingleElementPlanarTests::paralellogramsCritical2_Triangulation() - { - std::vector< double > actual_result; - INTERP_KERNEL::intersec_de_polygone<2>(_parallel1,_parallel3,4,4,actual_result,_Epsilon/_Precision, _Precision ); - - std::vector< double > expected_result; - - expected_result.push_back(0.);expected_result.push_back(0.); - - CPPUNIT_ASSERT_MESSAGE("Paralellogram tangency test failed (TRIANGULATION)", - (INTERP_KERNEL::checkEqualPolygons,2>(&actual_result, &expected_result, _Epsilon))); - } - - // Two triangles in a tangency configuration with a starting vertex on edge - - // _____ - // | / - // __|___/ - // | | / - // | | / - // | |/ - // | / - // | / - // |/ - - // \brief Status : pass - void SingleElementPlanarTests::trianglesTangencyCritical() - { - INTERP_KERNEL::PolygonAlgorithms<2> intersector (_Epsilon, _Precision);; - std::deque< double > actual_result = intersector.intersectConvexPolygons(_triangle5,_triangle6,3,3); - std::deque< double > expected_result; - - expected_result.push_back(1./3);expected_result.push_back(1./2); - expected_result.push_back(1./3);expected_result.push_back(1./3); - expected_result.push_back(1./2);expected_result.push_back(1./2); - - CPPUNIT_ASSERT_MESSAGE("Triangles tangency critical test failed (CONVEX)", - (INTERP_KERNEL::checkEqualPolygons,2>(&actual_result, &expected_result, _Epsilon))); - } - void SingleElementPlanarTests::trianglesTangencyCritical_Triangulation() - { - std::vector< double > actual_result; - INTERP_KERNEL::intersec_de_polygone<2>(_triangle5,_triangle6,3,3,actual_result,_Epsilon/_Precision, _Precision ); - - std::vector< double > expected_result; - - expected_result.push_back(1./3);expected_result.push_back(1./2); - expected_result.push_back(1./2);expected_result.push_back(1./2); - expected_result.push_back(1./3);expected_result.push_back(1./3); - - CPPUNIT_ASSERT_MESSAGE("Triangles tangency critical test failed (TRIANGULATION)", - (INTERP_KERNEL::checkEqualPolygons,2>(&actual_result, &expected_result, _Epsilon))); - } - - // Two triangles with double starting point in an outer tangency configuration - // /\ - // / \ - // / \ - // /______\ - // \ / - // \ / - // \ / - // \/ - - - // \brief Status : pass - void SingleElementPlanarTests::trianglesTangencyCritical2() - { - INTERP_KERNEL::PolygonAlgorithms<2> intersector (_Epsilon, _Precision);; - std::deque< double > actual_result = intersector.intersectConvexPolygons(_triangle1,_triangle7,3,3); - std::deque< double > expected_result; - - // if(!checkDequesEqual(actual_result,expected_result, _Epsilon)) - // { - // std::cerr<< "CPP_UNIT expected result= " << std::endl; - // dequePrintOut(expected_result); - // std::cerr<< "CPP_UNIT actual result= " << std::endl; - // dequePrintOut(actual_result); - // } - - CPPUNIT_ASSERT_MESSAGE("Triangles tangency critical (2) test failed (CONVEX)", - (INTERP_KERNEL::checkEqualPolygons,2>(&actual_result, &expected_result, _Epsilon))); - } - void SingleElementPlanarTests::trianglesTangencyCritical2_Triangulation() - { - std::vector< double > actual_result; - INTERP_KERNEL::intersec_de_polygone<2>(_triangle1,_triangle7,3,3,actual_result,_Epsilon/_Precision, _Precision ); - - std::vector< double > expected_result; - expected_result.push_back(1.);expected_result.push_back(1.); - expected_result.push_back(0.);expected_result.push_back(1.); - - // if(!checkVectorsEqual(actual_result,expected_result, _Epsilon)) - // { - // cerr<< "CPP_UNIT expected result= " << endl; - // vectPrintOut(expected_result); - // cerr<< "CPP_UNIT actual result= " << endl; - // vectPrintOut(actual_result); - // } - - CPPUNIT_ASSERT_MESSAGE("Triangles tangency critical (2) test failed (TRIANGULATION)", - (INTERP_KERNEL::checkEqualPolygons,2>(&actual_result, &expected_result, _Epsilon))); - } - // \brief Status : pass - void SingleElementPlanarTests::trianglesTangencyCritical3() - { - INTERP_KERNEL::PolygonAlgorithms<2> intersector (_Epsilon, _Precision);; - std::deque< double > actual_result = intersector.intersectConvexPolygons(_triangle8,_triangle9,3,3); - std::deque< double > expected_result; - - CPPUNIT_ASSERT_MESSAGE("Triangles tangency critical (3) test failed (CONVEX)", - (INTERP_KERNEL::checkEqualPolygons,2>(&actual_result, &expected_result, _Epsilon))); - } - void SingleElementPlanarTests::trianglesTangencyCritical3_Triangulation() - { - std::vector< double > actual_result; - INTERP_KERNEL::intersec_de_polygone<2>(_triangle8,_triangle9,3,3,actual_result,_Epsilon/_Precision, _Precision ); - - std::vector< double > expected_result; - expected_result.push_back(22.4601);expected_result.push_back(35.2129); - expected_result.push_back(13.9921);expected_result.push_back(34.693); - - CPPUNIT_ASSERT_MESSAGE("Triangles tangency critical (3) test failed (TRIANGULATION)", - (INTERP_KERNEL::checkEqualPolygons,2>(&actual_result, &expected_result, _Epsilon))); - } - void SingleElementPlanarTests::trianglesTangencyCritical4() - { - INTERP_KERNEL::PolygonAlgorithms<2> intersector (_Epsilon, _Precision);; - std::deque< double > actual_result = intersector.intersectConvexPolygons(_triangle10,_triangle11,3,3); - - std::deque< double > expected_result; - expected_result.push_back(82.745193090443536);expected_result.push_back(96.184114390029166); - expected_result.push_back(82.260099999999994);expected_result.push_back(95.720200000000006); - expected_result.push_back(80);expected_result.push_back(100.); - - - CPPUNIT_ASSERT_MESSAGE("Triangles tangency critical (4) test failed (CONVEX)", - (INTERP_KERNEL::checkEqualPolygons,2>(&actual_result, &expected_result, _Epsilon))); - } - void SingleElementPlanarTests::trianglesTangencyCritical4_Triangulation() - { - std::vector< double > actual_result; - INTERP_KERNEL::intersec_de_polygone<2>(_triangle10,_triangle11,3,3,actual_result,_Epsilon/_Precision, _Precision ); - - std::vector< double > expected_result; - expected_result.push_back(80);expected_result.push_back(100.); - expected_result.push_back(82.745193090443536);expected_result.push_back(96.184114390029166); - expected_result.push_back(82.260099999999994);expected_result.push_back(95.720200000000006); - - CPPUNIT_ASSERT_MESSAGE("Triangles tangency critical (4) test failed (TRIANGULATION)", - (INTERP_KERNEL::checkEqualPolygons,2>(&actual_result, &expected_result, _Epsilon))); - } - -} diff --git a/src/INTERP_KERNELTest/SingleElementPlanarTests.hxx b/src/INTERP_KERNELTest/SingleElementPlanarTests.hxx deleted file mode 100644 index 446781f24..000000000 --- a/src/INTERP_KERNELTest/SingleElementPlanarTests.hxx +++ /dev/null @@ -1,140 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 -// 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 __SINGLE_ELEMENT_PLANAR_TESTS_HXX_ -#define __SINGLE_ELEMENT_PLANAR_TESTS_HXX_ - -#include "InterpKernelTestExport.hxx" -#include "InterpolationPlanarTestSuite.hxx" - -namespace INTERP_TEST -{ - /** - * \brief Class testing algorithm by intersecting simple meshes having only one planar element each. - * This serves mainly to verify that the volume calculations between elements is correct. - * - */ - class INTERPKERNELTEST_EXPORT SingleElementPlanarTests : public InterpolationPlanarTestSuite - { - CPPUNIT_TEST_SUITE( SingleElementPlanarTests ); - - CPPUNIT_TEST( diamondsBasic ); - CPPUNIT_TEST( tangentDiamonds ); - CPPUNIT_TEST( tangentSquares ); - CPPUNIT_TEST( diamondsSharingVertex1 ); - CPPUNIT_TEST( identicalSquares ); - CPPUNIT_TEST( squareAndDiamondBasic ); - CPPUNIT_TEST( squareAndDiamondCritical ); - CPPUNIT_TEST( diamondsCritical ); - CPPUNIT_TEST( quadranglesCritical ); - CPPUNIT_TEST( quadrangleAndDiamondCritical ); - CPPUNIT_TEST( diamondsCritical2 ); - CPPUNIT_TEST( hexagonsCritical1 ); - CPPUNIT_TEST( hexagonsCritical2 ); - CPPUNIT_TEST( squareAndQuadrangleCritical ); - CPPUNIT_TEST( diamondsSharingVertex2 ); - CPPUNIT_TEST( triangleAndDiamondCritical ); - CPPUNIT_TEST( triangleAndSquareBasic ); - CPPUNIT_TEST( trianglesCritical ); - CPPUNIT_TEST( paralellogramsCritical1 ); - CPPUNIT_TEST( paralellogramsCritical2 ); - CPPUNIT_TEST( trianglesTangencyCritical ); - CPPUNIT_TEST( trianglesTangencyCritical2 ); - CPPUNIT_TEST( trianglesTangencyCritical3 ); - CPPUNIT_TEST( trianglesTangencyCritical4 ); - CPPUNIT_TEST( diamondsBasic_Triangulation ); - CPPUNIT_TEST( tangentDiamonds_Triangulation ); - CPPUNIT_TEST( tangentSquares_Triangulation ); - CPPUNIT_TEST( diamondsSharingVertex1_Triangulation ); - CPPUNIT_TEST( identicalSquares_Triangulation ); - //CPPUNIT_TEST( squareAndDiamondBasic_Triangulation ); - //CPPUNIT_TEST( squareAndDiamondCritical_Triangulation ); - CPPUNIT_TEST( diamondsCritical_Triangulation ); - CPPUNIT_TEST( quadranglesCritical_Triangulation ); - CPPUNIT_TEST( quadrangleAndDiamondCritical_Triangulation ); - CPPUNIT_TEST( diamondsCritical2_Triangulation ); - CPPUNIT_TEST( hexagonsCritical1_Triangulation ); - CPPUNIT_TEST( hexagonsCritical2_Triangulation ); - CPPUNIT_TEST( squareAndQuadrangleCritical_Triangulation ); - CPPUNIT_TEST( diamondsSharingVertex2_Triangulation ); - CPPUNIT_TEST( triangleAndDiamondCritical_Triangulation ); - CPPUNIT_TEST( triangleAndSquareBasic_Triangulation ); - CPPUNIT_TEST( trianglesCritical_Triangulation ); - CPPUNIT_TEST( paralellogramsCritical1_Triangulation ); - CPPUNIT_TEST( paralellogramsCritical2_Triangulation ); - CPPUNIT_TEST( trianglesTangencyCritical_Triangulation ); - CPPUNIT_TEST( trianglesTangencyCritical2_Triangulation ); - CPPUNIT_TEST( trianglesTangencyCritical3_Triangulation ); - CPPUNIT_TEST( trianglesTangencyCritical4_Triangulation ); - - CPPUNIT_TEST_SUITE_END(); - - public: - - void diamondsBasic(); - void tangentDiamonds(); - void tangentSquares(); - void diamondsSharingVertex1(); - void identicalSquares(); - void squareAndDiamondBasic(); - void squareAndDiamondCritical(); - void diamondsCritical(); - void quadranglesCritical(); - void quadrangleAndDiamondCritical(); - void diamondsCritical2(); - void hexagonsCritical1(); - void hexagonsCritical2(); - void squareAndQuadrangleCritical(); - void diamondsSharingVertex2(); - void triangleAndDiamondCritical(); - void triangleAndSquareBasic(); - void trianglesCritical(); - void paralellogramsCritical1(); - void paralellogramsCritical2(); - void trianglesTangencyCritical(); - void trianglesTangencyCritical2(); - void trianglesTangencyCritical3(); - void trianglesTangencyCritical4(); - void diamondsBasic_Triangulation(); - void tangentDiamonds_Triangulation(); - void tangentSquares_Triangulation(); - void diamondsSharingVertex1_Triangulation(); - void identicalSquares_Triangulation(); - void squareAndDiamondBasic_Triangulation(); - void squareAndDiamondCritical_Triangulation(); - void diamondsCritical_Triangulation(); - void quadranglesCritical_Triangulation(); - void quadrangleAndDiamondCritical_Triangulation(); - void diamondsCritical2_Triangulation(); - void hexagonsCritical1_Triangulation(); - void hexagonsCritical2_Triangulation(); - void squareAndQuadrangleCritical_Triangulation(); - void diamondsSharingVertex2_Triangulation(); - void triangleAndDiamondCritical_Triangulation(); - void triangleAndSquareBasic_Triangulation(); - void trianglesCritical_Triangulation(); - void paralellogramsCritical1_Triangulation(); - void paralellogramsCritical2_Triangulation(); - void trianglesTangencyCritical_Triangulation(); - void trianglesTangencyCritical2_Triangulation(); - void trianglesTangencyCritical3_Triangulation(); - void trianglesTangencyCritical4_Triangulation(); - }; -} -#endif diff --git a/src/INTERP_KERNELTest/SingleElementTetraTests.hxx b/src/INTERP_KERNELTest/SingleElementTetraTests.hxx deleted file mode 100644 index 023b7a2ab..000000000 --- a/src/INTERP_KERNELTest/SingleElementTetraTests.hxx +++ /dev/null @@ -1,170 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 -// 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 __SINGLE_ELEMENT_TETRA_TESTS_HXX_ -#define __SINGLE_ELEMENT_TETRA_TESTS_HXX_ - -#include "InterpolationTestSuite.hxx" - -namespace INTERP_TEST -{ - /** - * \brief Class testing algorithm by intersecting simple meshes having only one element each. This serves mainly to verify that - * the volume calculations between elements is correct. - * - */ - class SingleElementTetraTests : public InterpolationTestSuite<3,3> - { - CPPUNIT_TEST_SUITE( SingleElementTetraTests ); - - CPPUNIT_TEST( tetraReflexiveUnit ); - CPPUNIT_TEST( tetraReflexiveGeneral ); - CPPUNIT_TEST( tetraNudgedSimpler ); - CPPUNIT_TEST( tetraNudged ); - CPPUNIT_TEST( tetraCorner ); - CPPUNIT_TEST( tetraSimpleIncluded ); - CPPUNIT_TEST( tetraDegenEdge ); - CPPUNIT_TEST( tetraDegenFace ); - CPPUNIT_TEST( tetraDegenTranslatedInPlane ); - CPPUNIT_TEST( tetraHalfstripOnly ); - CPPUNIT_TEST( tetraHalfstripOnly2 ); - CPPUNIT_TEST( tetraSimpleHalfstripOnly ); - CPPUNIT_TEST( generalTetra ); - CPPUNIT_TEST( trickyTetra1 ); - // CPPUNIT_TEST( inconsistentTetra ); - - CPPUNIT_TEST_SUITE_END(); - - public: - - /// Unit tetrahedron mesh intersecting itself - /// \brief Status : pass - void tetraReflexiveUnit() - { - _testTools->intersectMeshes("UnitTetra", "UnitTetra", 1.0/6.0); - } - - /// Tetrahedron mesh with itself - /// \brief Status : pass - void tetraReflexiveGeneral() - { - _testTools->intersectMeshes("GeneralTetra", "GeneralTetra", 0.428559); - } - - /// Unit tetrahedron mesh intersecting slightly displaced copy of itself - /// \brief Status : pass - void tetraNudged() - { - _testTools->intersectMeshes("UnitTetra", "NudgedTetra", 0.142896); - } - - /// Single-element unit tetrahedron mesh intersecting even slightly displaced (along one axis only) copy of itself - /// \brief Status : pass - void tetraNudgedSimpler() - { - _testTools->intersectMeshes("UnitTetra", "NudgedSimpler", 0.152112); - } - - /// Tetrahedron intersecting unit tetrahedron with in non-degenerate way around corner O - /// \brief Status : pass - void tetraCorner() - { - _testTools->intersectMeshes("UnitTetra", "CornerTetra", 0.0135435); - } - - /// Tetrahedron situated totally inside another - /// \brief Status : pass - void tetraSimpleIncluded() - { - _testTools->intersectMeshes("SimpleIncludedTetra", "SimpleIncludingTetra", 17.0156); - } - - /// Displaced unit tetrahedron intersecting another unit tetrahedron with which it shares an edge - /// \brief Status : pass - void tetraDegenEdge() - { - _testTools->intersectMeshes("UnitTetraDegenT", "DegenEdgeXY", 0.0); - } - - /// Displaced unit tetrahedron intersecting another unit tetrahedron with which it shares a face - /// \brief Status : pass - void tetraDegenFace() - { - _testTools->intersectMeshes("UnitTetraDegenT", "DegenFaceXYZ", 0.0); - } - - /// Displaced unit tetrahedron intersecting another unit tetrahedron with which it shares a part of the face XYZ - /// \brief Status : pass - void tetraDegenTranslatedInPlane() - { - _testTools->intersectMeshes("UnitTetraDegenT", "DegenTranslatedInPlane", 0.0571667); - } - - /// Tetrahedron having only half-strip intersections with the unit tetrahedron - /// \brief Status : pass, but does not really test what it should - does not check that the intersections are detected. No longer needed. - void tetraHalfstripOnly() - { - // NB this test is not completely significant : we should also verify that - // there are triangles on the element that give a non-zero volume - _testTools->intersectMeshes("HalfstripOnly", "UnitTetra", 0.0); - } - - /// Tetrahedron having only half-strip intersections with the unit tetrahedron - /// \brief Status : pass, but does not really test what it should - does not check that the intersections are detected. No longer needed. - void tetraHalfstripOnly2() - { - // NB this test is not completely significant : we should also verify that - // there are triangles on the element that give a non-zero volume - _testTools->intersectMeshes("HalfstripOnly2", "UnitTetra", 0.0); - } - - /// Tetrahedron having only half-strip intersections with the unit tetrahedron - /// \brief Status : pass, but does not really test what it should - does not check that the intersections are detected. No longer needed. - void tetraSimpleHalfstripOnly() - { - // NB this test is not completely significant : we should also verify that - // there are triangles on the element that give a non-zero volume - _testTools->intersectMeshes("SimpleHalfstripOnly", "UnitTetra", 0.0); - } - - /// Two intersecting tetrahedra situated in a general position in space - /// \brief Status : pass - void generalTetra() - { - _testTools->intersectMeshes("GenTetra1", "GenTetra2", 4.91393); - } - - /// Tetrahedron which is in a tricky position relative to unit tetrahedron. - /// \brief Status : pass - void trickyTetra1() - { - _testTools->intersectMeshes("UnitTetra", "TrickyTetra1", 0.0); - } - - /// Two large tetrahedra which nearly share part of an edge and intersect at the origin. Created with goal of getting the as-of-yet uncovered "consistency" test - /// part of the correction of double products covered. However, it does not succeed with this. - /// \brief Status : fails, but is quite far-fetched as far as typical use cases are concerned - void inconsistentTetra() - { - _testTools->intersectMeshes("LargeUnitTetra.med", "LargeUnitTetra", "LargeInconsistentTetra.med", "LargeInconsistent", 7.86231e7); - } - - }; -} -#endif diff --git a/src/INTERP_KERNELTest/TestInterpKernel.cxx b/src/INTERP_KERNELTest/TestInterpKernel.cxx deleted file mode 100644 index bfc450a26..000000000 --- a/src/INTERP_KERNELTest/TestInterpKernel.cxx +++ /dev/null @@ -1,58 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// - -#include "CppUnitTest.hxx" -#include "BBTreeTest.hxx" -#include "ExprEvalInterpTest.hxx" -#include "QuadraticPlanarInterpTest.hxx" -#include "SingleElementPlanarTests.hxx" -#include "TransformedTriangleIntersectTest.hxx" -#include "TransformedTriangleTest.hxx" -#include "UnitTetraIntersectionBaryTest.hxx" -#include "UnitTetra3D2DIntersectionTest.hxx" - -#include "HexaTests.hxx" -#include "InterpolationOptionsTest.hxx" -#include "MultiElement2DTests.hxx" -#include "MultiElementTetraTests.hxx" -#include "SingleElementTetraTests.hxx" -#include "ThreeDSurfProjectionTest.hxx" - -using namespace INTERP_TEST; - -//--- Registers the fixture into the 'registry' - -CPPUNIT_TEST_SUITE_REGISTRATION( BBTreeTest ); -CPPUNIT_TEST_SUITE_REGISTRATION( ExprEvalInterpTest ); -CPPUNIT_TEST_SUITE_REGISTRATION( QuadraticPlanarInterpTest ); -CPPUNIT_TEST_SUITE_REGISTRATION( SingleElementPlanarTests ); -CPPUNIT_TEST_SUITE_REGISTRATION( TransformedTriangleIntersectTest ); -CPPUNIT_TEST_SUITE_REGISTRATION( TransformedTriangleTest ); -CPPUNIT_TEST_SUITE_REGISTRATION( UnitTetraIntersectionBaryTest ); -CPPUNIT_TEST_SUITE_REGISTRATION( UnitTetra3D2DIntersectionTest ); - -CPPUNIT_TEST_SUITE_REGISTRATION( InterpolationOptionsTest ); -CPPUNIT_TEST_SUITE_REGISTRATION( HexaTests ); -CPPUNIT_TEST_SUITE_REGISTRATION( MultiElement2DTests ); -CPPUNIT_TEST_SUITE_REGISTRATION( MultiElementTetraTests ); -CPPUNIT_TEST_SUITE_REGISTRATION( SingleElementTetraTests ); -CPPUNIT_TEST_SUITE_REGISTRATION( ThreeDSurfProjectionTest ); -// --- generic Main program from KERNEL_SRC/src/Basics/Test - -#include "BasicMainTest.hxx" diff --git a/src/INTERP_KERNELTest/TestInterpKernelUtils.cxx b/src/INTERP_KERNELTest/TestInterpKernelUtils.cxx deleted file mode 100644 index d82a4c273..000000000 --- a/src/INTERP_KERNELTest/TestInterpKernelUtils.cxx +++ /dev/null @@ -1,44 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// - -#include "TestInterpKernelUtils.hxx" - -#include - -namespace INTERP_TEST -{ - std::string getResourceFile( const std::string& filename ) - { - std::string resourceFile = ""; - - if ( getenv("top_srcdir") ) { - // we are in 'make test' step - resourceFile = getenv("top_srcdir"); - resourceFile += "/resources/"; - } - else if ( getenv("MED_ROOT_DIR") ) { - // use MED_ROOT_DIR env.var - resourceFile = getenv("MED_ROOT_DIR"); - resourceFile += "/share/salome/resources/med/"; - } - resourceFile += filename; - return resourceFile; - } - -} // namespace INTERP_TEST diff --git a/src/INTERP_KERNELTest/TestInterpKernelUtils.hxx b/src/INTERP_KERNELTest/TestInterpKernelUtils.hxx deleted file mode 100644 index d17240a7f..000000000 --- a/src/INTERP_KERNELTest/TestInterpKernelUtils.hxx +++ /dev/null @@ -1,34 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 -// 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 _TESTINTERPKERNELUTILS_HXX_ -#define _TESTINTERPKERNELUTILS_HXX_ - -#include "InterpKernelTestExport.hxx" - -#include - -namespace INTERP_TEST -{ - - INTERPKERNELTEST_EXPORT std::string getResourceFile( const std::string& ); - -} // namespace INTERP_TEST - -#endif // _TESTINTERPKERNELUTILS_HXX_ diff --git a/src/INTERP_KERNELTest/ThreeDSurfProjectionTest.cxx b/src/INTERP_KERNELTest/ThreeDSurfProjectionTest.cxx deleted file mode 100644 index 2a84b503a..000000000 --- a/src/INTERP_KERNELTest/ThreeDSurfProjectionTest.cxx +++ /dev/null @@ -1,128 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// - -#include "ThreeDSurfProjectionTest.hxx" -#include "PlanarIntersector.txx" - -class MyMeshType -{ -public: - static const int MY_SPACEDIM=3; - static const int MY_MESHDIM=3; - static const INTERP_KERNEL::NumberingPolicy My_numPol=INTERP_KERNEL::ALL_C_MODE; - typedef int MyConnType; -}; - -class MyMatrixType -{ -}; - -void INTERP_TEST::ThreeDSurfProjectionTest::test1() -{ - // Two triangles coo and coo2 are perfectly // each others with a distance equal to 1e-6. - // A little rotation to make it more funny. - //coo=DataArrayDouble([0.,0.,0.,1.,0.,0.,0.,1.,0.],3,3) - //eps=1e-6 - //coo2=DataArrayDouble([0.,0.,eps,1.,0.,eps,0.,1.,eps],3,3) - //MEDCouplingPointSet.Rotate3DAlg([0.,0.,0.],[2.,1.,3.],0.3,coo) - //MEDCouplingPointSet.Rotate3DAlg([0.,0.,0.],[2.,1.,3.],0.3,coo2) - const double coo[9]={0.,0.,0.,0.96809749223257568,0.24332379388106262,-0.059839592782071335,-0.23056279077409292,0.95852673990234838,0.16753294721527912}; - const double coo2[9]={9.8122602102980502e-08,-1.4839144255482456e-7,9.8404874611628791e-7,0.96809759035517784,0.24332364548962007,-0.059838608733325221,-0.23056269265149082,0.9585265915109058,0.16753393126402524}; - double *tmp0(new double[9]),*tmp1(new double[9]); - int ret; - //eps=1e-2. eps is a tolerance to detect that two points are the same or not in a same polygon. - // here the max 3D distance is 1e-5 > 1e-6 so 1 is expected - std::copy(coo,coo+9,tmp0); - std::copy(coo2,coo2+9,tmp1); - ret=INTERP_KERNEL::PlanarIntersector::Projection(tmp0,tmp1,3,3,1e-2,1e-5/* <- */,-1.,0.5,true); - CPPUNIT_ASSERT_EQUAL(1,ret); - const double expected0[9]={0.,0.,0.,1.,0.,0.,0.,1.,0.}; - for(int i=0;i<9;i++) - { - CPPUNIT_ASSERT_DOUBLES_EQUAL(expected0[i],tmp0[i],1e-15); - CPPUNIT_ASSERT_DOUBLES_EQUAL(expected0[i],tmp1[i],1e-15); - } - // here the max 3D distance is 1e-8 < 1e-6 so 0 is expected - std::copy(coo,coo+9,tmp0); - std::copy(coo2,coo2+9,tmp1); - ret=INTERP_KERNEL::PlanarIntersector::Projection(tmp0,tmp1,3,3,1e-2,1e-8/* <- */,-1.,0.5,true); - CPPUNIT_ASSERT_EQUAL(0,ret); - // here testing when max 3D distance is 1e-5 > 1e-6 with inverted cells - std::copy(coo,coo+9,tmp0); - std::copy(coo2,coo2+3,tmp1+6); std::copy(coo2+3,coo2+6,tmp1+3); std::copy(coo2+6,coo2+9,tmp1); - ret=INTERP_KERNEL::PlanarIntersector::Projection(tmp0,tmp1,3,3,1e-2,1e-5/* <- */,-1.,0.5,true); - CPPUNIT_ASSERT_EQUAL(-1,ret); - const double expected1[9]={-0.7071067811865476,-0.7071067811865476,0.,0.,-1.4142135623730951,0.,-1.4142135623730951,-1.4142135623730951,0.}; - const double expected2[9]={-1.4142135623730951,-1.4142135623730951,0.,0.,-1.4142135623730951,0.,-0.7071067811865476,-0.7071067811865476,0.}; - for(int i=0;i<9;i++) - { - CPPUNIT_ASSERT_DOUBLES_EQUAL(expected1[i],tmp0[i],1e-14); - CPPUNIT_ASSERT_DOUBLES_EQUAL(expected2[i],tmp1[i],1e-14); - } - // - delete [] tmp0; - delete [] tmp1; -} - -void INTERP_TEST::ThreeDSurfProjectionTest::test2() -{// here the two triangles have their center of inertia very close (eps) but the angle between the two planes is "big" - //coo=DataArrayDouble([0.,0.,0.,1.,0.,0.,0.,1.,0.],3,3) - //coocpy=coo.deepCpy() - //MEDCouplingPointSet.Rotate3DAlg([0.,0.,0.],[-1,-1.,0.],pi/3,coocpy) - //coocpy+=[eps*sqrt(3)/2,eps/2,eps*0.] - // - const double coo[9]={0.,0.,0.,0.96809749223257568,0.24332379388106262,-0.059839592782071335,-0.23056279077409292,0.95852673990234838,0.16753294721527912}; - const double coo2[9]={7.2311562622637225e-07,6.8998795679738294e-07,3.1943866106249849e-08,0.72852072144314628,0.33125439126063028,0.5996079016637561,0.0090154262465889021,0.87059752249869415,-0.49191448334281612}; - double *tmp0(new double[9]),*tmp1(new double[9]); - int ret; - //eps=1e-2. eps is a tolerance to detect that two points are the same or not in a same polygon. - // here the max 3D distance is 1e-5 > 1e-6 so 1 is expected - std::copy(coo,coo+9,tmp0); - std::copy(coo2,coo2+9,tmp1); - ret=INTERP_KERNEL::PlanarIntersector::Projection(tmp0,tmp1,3,3,1e-2,1e-5/* <- */,-1.,0.5,true); - CPPUNIT_ASSERT_EQUAL(1,ret); - // here the max 3D distance is 1e-8 < 1e-6 so 0 is expected - std::copy(coo,coo+9,tmp0); - std::copy(coo2,coo2+9,tmp1); - ret=INTERP_KERNEL::PlanarIntersector::Projection(tmp0,tmp1,3,3,1e-2,1e-8/* <- */,-1.,0.5,true); - CPPUNIT_ASSERT_EQUAL(0,ret); - // again max 3D distance is 1e-5 > 1e-6 so 1 is expected - std::copy(coo,coo+9,tmp0); - std::copy(coo2,coo2+9,tmp1); - ret=INTERP_KERNEL::PlanarIntersector::Projection(tmp0,tmp1,3,3,1e-2,1e-5/* <- */,-1.,0.5,true); - CPPUNIT_ASSERT_EQUAL(1,ret); - // again max 3D distance is 1e-5 > 1e-6 but minDot set to 0.8. 0 expected. because the angle is pi/4 so cos(pi/3) > 0.8 - std::copy(coo,coo+9,tmp0); - std::copy(coo2,coo2+9,tmp1); - ret=INTERP_KERNEL::PlanarIntersector::Projection(tmp0,tmp1,3,3,1e-2,1e-5/* <- */,0.8/* <- */,0.5,true); - CPPUNIT_ASSERT_EQUAL(0,ret); - // again max 3D distance is 1e-5 > 1e-6 but minDot set to 0.7. 1 expected. because the angle is pi/4 so cos(pi/3) < 0.49 - std::copy(coo,coo+9,tmp0); - std::copy(coo2,coo2+9,tmp1); - ret=INTERP_KERNEL::PlanarIntersector::Projection(tmp0,tmp1,3,3,1e-2,1e-5/* <- */,0.49/* <- */,0.5,true); - CPPUNIT_ASSERT_EQUAL(1,ret); - // again max 3D distance is 1e-5 > 1e-6 but minDot set to 0.7. 0 expected. because the angle is pi/4 so cos(pi/3) > 0.51 - std::copy(coo,coo+9,tmp0); - std::copy(coo2,coo2+9,tmp1); - ret=INTERP_KERNEL::PlanarIntersector::Projection(tmp0,tmp1,3,3,1e-2,1e-5/* <- */,0.51/* <- */,0.5,true); - CPPUNIT_ASSERT_EQUAL(0,ret); - // - delete [] tmp0; - delete [] tmp1; -} diff --git a/src/INTERP_KERNELTest/ThreeDSurfProjectionTest.hxx b/src/INTERP_KERNELTest/ThreeDSurfProjectionTest.hxx deleted file mode 100644 index 40d27a587..000000000 --- a/src/INTERP_KERNELTest/ThreeDSurfProjectionTest.hxx +++ /dev/null @@ -1,44 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 -// 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 __THREEDSURFPROJECTIONTEST_HXX__ -#define __THREEDSURFPROJECTIONTEST_HXX__ - -#include - -#include "InterpKernelTestExport.hxx" - -namespace INTERP_TEST -{ - /** - * \brief Class dedicated of the test of the preprocessing of 3D surf cells before performing invoking 2D algorithms. - */ - class INTERPKERNELTEST_EXPORT ThreeDSurfProjectionTest : public CppUnit::TestFixture - { - CPPUNIT_TEST_SUITE( ThreeDSurfProjectionTest ); - CPPUNIT_TEST ( test1 ); - CPPUNIT_TEST ( test2 ); - CPPUNIT_TEST_SUITE_END(); - public: - void test1(); - void test2(); - }; -} - -#endif diff --git a/src/INTERP_KERNELTest/TransformedTriangleIntersectTest.cxx b/src/INTERP_KERNELTest/TransformedTriangleIntersectTest.cxx deleted file mode 100644 index 8fdc77df3..000000000 --- a/src/INTERP_KERNELTest/TransformedTriangleIntersectTest.cxx +++ /dev/null @@ -1,2284 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// - -#include "TransformedTriangleIntersectTest.hxx" -#include - -#include "Log.hxx" - -/// macro to test for zero double products outside the segment-edge intersection test method -/// as is done in TransformedTriangle when OPTIMIZE is defined -#define TEST_ZERO_DP_EDGE(seg, edge) isZero[TT::NO_DP*int(seg) + int(DoubleProduct(edge))] - -/// macro to test for zero double products outside the segment-corner intersection test method -/// as is done in TransformedTriangle when OPTIMIZE is defined -#define TEST_ZERO_DP_CORNER(seg, corner) \ - isZero[DoubleProduct(TT::NO_DP*int(seg) + TT::EDGES_FOR_CORNER[3*corner] )] && \ - isZero[DoubleProduct(TT::NO_DP*int(seg) + TT::EDGES_FOR_CORNER[3*corner+1] )] && \ - isZero[DoubleProduct(TT::NO_DP*int(seg) + TT::EDGES_FOR_CORNER[3*corner+2] )] - -/// macro to test for zero double products outside the segment-ray intersection test method -/// as is done in TransformedTriangle when OPTIMIZE is defined -#define TEST_ZERO_DP_RAY(seg, corner) isZero[TT::NO_DP*int(seg) + TT::DP_SEGMENT_RAY_INTERSECTION[7*(corner-1)]] - -using namespace INTERP_KERNEL; - -namespace INTERP_TEST -{ - - //////////////////////////////////////////////////////////////////////////////////////////////////////// - /// \class TransformedTriangleIntersectTest - /// \brief Class testing the intersection detection methods of TransformedTriangle. - /// - /// This class contains unit tests for the intersection methods of the TransformedTriangle class. - //////////////////////////////////////////////////////////////////////////////////////////////////////// - /// Each method in the class runs all the intersection tests with some triangle. The goal is to cover all - /// the different types of intersections between a triangle and a tetrahedron. The table below gives a - /// a summary of what is being tested. Before each method, there is also a summary of what how the - /// triangle in the method intersects the unit tetrahedron. - /// - /// Since performing all tests would require a large number of triangles, we have limited our coverage to - /// be such that each column and each row in the table below has at least one entry for each type of - /// intersection. The intersection forumlae are totally symmetric with respect to changing the segment - /// (PQ, QR, or RP) of the triangle, so they only enter in a very simple way in the code. Testing - /// all these cases is therefore of low priority. - //////////////////////////////////////////////////////////////////////////////////////////////////////// - /// - //////////////////////////////////////////////////////////////////////////////////////////////////////// - /// Intersections tested (number indicates first triangle which contains the intersection): - ///
-  /// -----------------------------------------------------------------------------------------------------
-  /// CI  ->  P: 3      Q: 4     R: 7
-  /// COH ->  P: 9      Q: 8     R: 10
-  /// CAH ->  P: 4      Q: 10    R: 9
-  /// -----------------------------------------------------------------------------------------------------
-  /// SF  ->  (PQ, OZX) : 1   (PQ, OYZ) : 2   (PQ, OXY) : 1   (PQ, XYZ) : 3
-  ///     ->  (QR, OZX) : 8   (QR, OYZ) : -   (QR, OXY) : 4   (QR, XYZ) : 7
-  ///     ->  (RP, OZX) : 1   (RP, OYZ) : 3   (RP, OXY) : 7   (RP, XYZ) : 1
-  /// -----------------------------------------------------------------------------------------------------
-  /// SE  ->  (PQ, OX)  : 11  (PQ, OY)  : -   (PQ, OZ)  : 12  (PQ, XY)  : 2   (PQ, ZX)  : -  (PQ, YZ)  : 10
-  ///     ->  (QR, OX)  : -   (QR, OY)  : -   (QR, OZ)  : -   (QR, XY)  : -   (QR, ZX)  : 9  (QR, YZ)  : -
-  ///     ->  (RP, OX)  : -   (RP, OY)  : 12  (RP, OZ)  : -   (RP, XY)  : -   (RP, ZX)  : -  (RP, YZ)  : -
-  /// -----------------------------------------------------------------------------------------------------
-  /// SC  ->  (PQ, O)   : -   (PQ, X)   : -   (PQ, Y)   : 8   (PQ, Z)   : -
-  ///     ->  (QR, O)   : -   (QR, X)   : 2   (QR, Y)   : -   (QR, Z)   : 13
-  ///     ->  (RP, O)   : 11  (RP, X)   : -   (RP, Y)   : -   (RP, Z)   : -
-  /// -----------------------------------------------------------------------------------------------------
-  /// SHS ->  (PQ, XY)  : 3   (PQ, ZX)  : -   (PQ, YZ)  : 13
-  ///     ->  (QR, XY)  : 3   (QR, ZX)  : 5   (QR, YZ)  : 3
-  ///     ->  (RP, XY)  : 1   (RP, ZX)  : 4   (RP, YZ)  : -
-  /// -----------------------------------------------------------------------------------------------------
-  /// SR  ->  (PQ, X)   : 6   (PQ, Y)   : 5   (PQ, Z)   : -
-  ///     ->  (QR, X)   : -   (QR, Y)   : -   (QR, Z)   : 6
-  ///     ->  (RP, X)   : -   (RP, Y)   : -   (RP, Z)   : -
-  /// -----------------------------------------------------------------------------------------------------
-  /// TE  ->  OX : 4   OY : 7    OZ : 8     XY : 1     ZX : 4    YZ : 3
-  /// -----------------------------------------------------------------------------------------------------
-  /// TR  ->  X  : 7    Y : 6     Z : 5
-  /// -----------------------------------------------------------------------------------------------------
-  /// 
- //////////////////////////////////////////////////////////////////////////////////////////////////////// - - //////////////////////////////////////////////////////////////////////////////////////////////////////// - /// Key to triangle descriptions : - /// CI = Triangle corner contained in tetrahedron - /// COH = Triangle corner on h = 0 face of tetrahedron - /// CAH = Triangle corner above h = 0 face of tetrahedron in z-direction - /// SF = Segment - facet intersection - /// SE = Segment - edge intersection - /// SC = Segment - corner intersection - /// SHS = Segment - halfstrip intersection - /// SR = Segment - ray intersection - /// TE = Tetrahedron edge intersects triangle (surface - edge intersection) - /// TR = Surface - ray intersection - /// - /// In the descriptions for each triangle, square brackets indicate superfluous but allowed intersections - /// that arise as by-products of for instance segment-corner intersections. - /// E.g. A segment - corner intersection can imply three surface - edge intersections - /// Since these "extra" intersections arise under special circumstances, they are not counted in the - /// table above - //////////////////////////////////////////////////////////////////////////////////////////////////////// - - - //////////////////////////////////////////////////////////////////////////////////////////////////////// - /// Triangle 1 has the following intersections - ///
-  /// CI     -
-  /// COH    -
-  /// CAH    -
-  /// SF     (PQ, OXY), (PQ, OZX), (RP, XYZ), (RP, OZX)
-  /// SE     -
-  /// SC     - 
-  /// SHS    (RP, XY)
-  /// SR     - 
-  /// TE     XY
-  /// TR     - 
-  /// 
- /// \brief Status : pass - void TransformedTriangleIntersectTest::testTriangle1() - { - LOG(1, "+++++++ Testing triangle 1" ); - - typedef TransformedTriangle TT; - - double coords[9] = - { - 0.4,-0.5, 0.5, // P - 0.4, 2.5,-1.0, // Q - 0.4, 2.5, 0.5 // R - }; - - TransformedTriangle* tri = new TransformedTriangle(&coords[0], &coords[3], &coords[6]); - - // run all intersection tests and ensure that the ones - // listed with yes in the tables above return true and - // that the ones listed with no or not listed at all return false - - bool isZero[TT::NO_TRI_SEGMENT * TT::NO_DP]; - - for(TriSegment seg = TT::PQ ; seg < TT::NO_TRI_SEGMENT ; seg = TT::TriSegment(seg + 1)) - { - // check beforehand which double-products are zero - for(DoubleProduct dp = TT::C_YZ; dp < TT::NO_DP; dp = DoubleProduct(dp + 1)) - { - isZero[TT::NO_DP*int(seg) + int(dp)] = (tri->calcStableC(seg, dp) == 0.0); - } - } - - // corner in tetrahedron (3 possibilities) - CPPUNIT_ASSERT_EQUAL(false, tri->testCornerInTetrahedron(TT::P)); - CPPUNIT_ASSERT_EQUAL(false, tri->testCornerInTetrahedron(TT::Q)); - CPPUNIT_ASSERT_EQUAL(false, tri->testCornerInTetrahedron(TT::R)); - - // corner on XYZ facet (3 possibilities) - CPPUNIT_ASSERT_EQUAL(false, tri->testCornerOnXYZFacet(TT::P)); - CPPUNIT_ASSERT_EQUAL(false, tri->testCornerOnXYZFacet(TT::Q)); - CPPUNIT_ASSERT_EQUAL(false, tri->testCornerOnXYZFacet(TT::R)); - - // corner above XYZ facet (3 possibilities) - CPPUNIT_ASSERT_EQUAL(false, tri->testCornerAboveXYZFacet(TT::P)); - CPPUNIT_ASSERT_EQUAL(false, tri->testCornerAboveXYZFacet(TT::Q)); - CPPUNIT_ASSERT_EQUAL(false, tri->testCornerAboveXYZFacet(TT::R)); - - // segment-facet (9 possibilities) - CPPUNIT_ASSERT_EQUAL(true , tri->testSegmentFacetIntersection(TT::PQ, TT::OZX)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::PQ, TT::OYZ)); - CPPUNIT_ASSERT_EQUAL(true , tri->testSegmentFacetIntersection(TT::PQ, TT::OXY)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::PQ, TT::XYZ)); - - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::QR, TT::OZX)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::QR, TT::OYZ)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::QR, TT::OXY)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::QR, TT::XYZ)); - - CPPUNIT_ASSERT_EQUAL(true , tri->testSegmentFacetIntersection(TT::RP, TT::OZX)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::RP, TT::OYZ)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::RP, TT::OXY)); - CPPUNIT_ASSERT_EQUAL(true , tri->testSegmentFacetIntersection(TT::RP, TT::XYZ)); - - // segment-edge (18 possibilities) - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::PQ, TT::OX) && tri->testSegmentEdgeIntersection(TT::PQ, TT::OX)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::PQ, TT::OY) && tri->testSegmentEdgeIntersection(TT::PQ, TT::OY)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::PQ, TT::OZ) && tri->testSegmentEdgeIntersection(TT::PQ, TT::OZ)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::PQ, TT::YZ) && tri->testSegmentEdgeIntersection(TT::PQ, TT::YZ)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::PQ, TT::ZX) && tri->testSegmentEdgeIntersection(TT::PQ, TT::ZX)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::PQ, TT::XY) && tri->testSegmentEdgeIntersection(TT::PQ, TT::XY)); - - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::QR, TT::OX) && tri->testSegmentEdgeIntersection(TT::QR, TT::OX)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::QR, TT::OY) && tri->testSegmentEdgeIntersection(TT::QR, TT::OY)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::QR, TT::OZ) && tri->testSegmentEdgeIntersection(TT::QR, TT::OZ)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::QR, TT::YZ) && tri->testSegmentEdgeIntersection(TT::QR, TT::YZ)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::QR, TT::ZX) && tri->testSegmentEdgeIntersection(TT::QR, TT::ZX)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::QR, TT::XY) && tri->testSegmentEdgeIntersection(TT::QR, TT::XY)); - - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::RP, TT::OX) && tri->testSegmentEdgeIntersection(TT::RP, TT::OX)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::RP, TT::OY) && tri->testSegmentEdgeIntersection(TT::RP, TT::OY)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::RP, TT::OZ) && tri->testSegmentEdgeIntersection(TT::RP, TT::OZ)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::RP, TT::YZ) && tri->testSegmentEdgeIntersection(TT::RP, TT::YZ)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::RP, TT::ZX) && tri->testSegmentEdgeIntersection(TT::RP, TT::ZX)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::RP, TT::XY) && tri->testSegmentEdgeIntersection(TT::RP, TT::XY)); - - // segment - corner (12 possibilities) - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::PQ, TT::O) && tri->testSegmentCornerIntersection(TT::PQ, TT::O)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::PQ, TT::X) && tri->testSegmentCornerIntersection(TT::PQ, TT::X)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::PQ, TT::Y) && tri->testSegmentCornerIntersection(TT::PQ, TT::Y)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::PQ, TT::Z) && tri->testSegmentCornerIntersection(TT::PQ, TT::Z)); - - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::QR, TT::O) && tri->testSegmentCornerIntersection(TT::QR, TT::O)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::QR, TT::X) && tri->testSegmentCornerIntersection(TT::QR, TT::X)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::QR, TT::Y) && tri->testSegmentCornerIntersection(TT::QR, TT::Y)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::QR, TT::Z) && tri->testSegmentCornerIntersection(TT::QR, TT::Z)); - - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::RP, TT::O) && tri->testSegmentCornerIntersection(TT::RP, TT::O)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::RP, TT::X) && tri->testSegmentCornerIntersection(TT::RP, TT::X)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::RP, TT::Y) && tri->testSegmentCornerIntersection(TT::RP, TT::Y)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::RP, TT::Z) && tri->testSegmentCornerIntersection(TT::RP, TT::Z)); - - // segment-halfstrip (9 possibilities) - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentHalfstripIntersection(TT::PQ, TT::YZ)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentHalfstripIntersection(TT::PQ, TT::ZX)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentHalfstripIntersection(TT::PQ, TT::XY)); - - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentHalfstripIntersection(TT::QR, TT::YZ)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentHalfstripIntersection(TT::QR, TT::ZX)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentHalfstripIntersection(TT::QR, TT::XY)); - - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentHalfstripIntersection(TT::RP, TT::YZ)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentHalfstripIntersection(TT::RP, TT::ZX)); - CPPUNIT_ASSERT_EQUAL(true , tri->testSegmentHalfstripIntersection(TT::RP, TT::XY)); - - // segment-ray (9 possibilities) - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_RAY(TT::PQ, TT::X) && tri->testSegmentRayIntersection(TT::PQ, TT::X)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_RAY(TT::PQ, TT::Y) && tri->testSegmentRayIntersection(TT::PQ, TT::Y)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_RAY(TT::PQ, TT::Z) && tri->testSegmentRayIntersection(TT::PQ, TT::Z)); - - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_RAY(TT::QR, TT::X) && tri->testSegmentRayIntersection(TT::QR, TT::X)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_RAY(TT::QR, TT::Y) && tri->testSegmentRayIntersection(TT::QR, TT::Y)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_RAY(TT::QR, TT::Z) && tri->testSegmentRayIntersection(TT::QR, TT::Z)); - - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_RAY(TT::RP, TT::X) && tri->testSegmentRayIntersection(TT::RP, TT::X)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_RAY(TT::RP, TT::Y) && tri->testSegmentRayIntersection(TT::RP, TT::Y)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_RAY(TT::RP, TT::Z) && tri->testSegmentRayIntersection(TT::RP, TT::Z)); - - // surface-edge (6 possibilities) - CPPUNIT_ASSERT_EQUAL(false, tri->testSurfaceEdgeIntersection(TT::OX)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSurfaceEdgeIntersection(TT::OY)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSurfaceEdgeIntersection(TT::OZ)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSurfaceEdgeIntersection(TT::YZ)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSurfaceEdgeIntersection(TT::ZX)); - CPPUNIT_ASSERT(tri->testSurfaceEdgeIntersection(TT::XY)); - - // surface-ray (3 possibilities) - CPPUNIT_ASSERT_EQUAL(false, tri->testSurfaceRayIntersection(TT::X)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSurfaceRayIntersection(TT::Y)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSurfaceRayIntersection(TT::Z)); - - delete tri; - - } - - /// Triangle 2 has the following intersections - ///
-  /// CI     -
-  /// COH    -
-  /// CAH    -
-  /// SF     (PQ, OYZ)
-  /// SE     (PQ, XY)
-  /// SC     (QR, X)
-  /// SHS    -
-  /// SR     - 
-  /// TE     [OX, OZ, ZX]
-  /// TR     - 
-  /// 
- /// \brief Status: pass - void TransformedTriangleIntersectTest::testTriangle2() - { - LOG(1, "+++++++ Testing triangle 2" ); - typedef TransformedTriangle TT; - - double coords[9] = - { - -0.5, 0.5, 0.25, // P - 1.5, 0.5,-0.25, // Q - -0.5,-1.5, 0.75 // R - }; - TransformedTriangle* tri = new TransformedTriangle(&coords[0], &coords[3], &coords[6]); - - // run all intersection tests and ensure that the ones - // listed with yes in the tables above return true and - // that the ones listed with no or not listed at all return false - - bool isZero[TT::NO_TRI_SEGMENT * TT::NO_DP]; - - for(TriSegment seg = TT::PQ ; seg < TT::NO_TRI_SEGMENT ; seg = TT::TriSegment(seg + 1)) - { - // check beforehand which double-products are zero - for(DoubleProduct dp = TT::C_YZ; dp < TT::NO_DP; dp = DoubleProduct(dp + 1)) - { - isZero[TT::NO_DP*int(seg) + int(dp)] = (tri->calcStableC(seg, dp) == 0.0); - } - } - - // corner in tetrahedron (3 possibilities) - CPPUNIT_ASSERT_EQUAL(false, tri->testCornerInTetrahedron(TT::P)); - CPPUNIT_ASSERT_EQUAL(false, tri->testCornerInTetrahedron(TT::Q)); - CPPUNIT_ASSERT_EQUAL(false, tri->testCornerInTetrahedron(TT::R)); - - // corner on XYZ facet (3 possibilities) - CPPUNIT_ASSERT_EQUAL(false, tri->testCornerOnXYZFacet(TT::P)); - CPPUNIT_ASSERT_EQUAL(false, tri->testCornerOnXYZFacet(TT::Q)); - CPPUNIT_ASSERT_EQUAL(false, tri->testCornerOnXYZFacet(TT::R)); - - // corner above XYZ facet (3 possibilities) - CPPUNIT_ASSERT_EQUAL(false, tri->testCornerAboveXYZFacet(TT::P)); - CPPUNIT_ASSERT_EQUAL(false, tri->testCornerAboveXYZFacet(TT::Q)); - CPPUNIT_ASSERT_EQUAL(false, tri->testCornerAboveXYZFacet(TT::R)); - - // segment-facet (9 possibilities) - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::PQ, TT::OZX)); - CPPUNIT_ASSERT_EQUAL(true , tri->testSegmentFacetIntersection(TT::PQ, TT::OYZ)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::PQ, TT::OXY)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::PQ, TT::XYZ)); - - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::QR, TT::OZX)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::QR, TT::OYZ)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::QR, TT::OXY)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::QR, TT::XYZ)); - - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::RP, TT::OZX)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::RP, TT::OYZ)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::RP, TT::OXY)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::RP, TT::XYZ)); - - // segment-edge (18 possibilities) - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::PQ, TT::OX) && tri->testSegmentEdgeIntersection(TT::PQ, TT::OX)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::PQ, TT::OY) && tri->testSegmentEdgeIntersection(TT::PQ, TT::OY)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::PQ, TT::OZ) && tri->testSegmentEdgeIntersection(TT::PQ, TT::OZ)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::PQ, TT::YZ) && tri->testSegmentEdgeIntersection(TT::PQ, TT::YZ)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::PQ, TT::ZX) && tri->testSegmentEdgeIntersection(TT::PQ, TT::ZX)); - CPPUNIT_ASSERT_EQUAL(true , TEST_ZERO_DP_EDGE(TT::PQ, TT::XY) && tri->testSegmentEdgeIntersection(TT::PQ, TT::XY)); - - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::QR, TT::OX) && tri->testSegmentEdgeIntersection(TT::QR, TT::OX)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::QR, TT::OY) && tri->testSegmentEdgeIntersection(TT::QR, TT::OY)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::QR, TT::OZ) && tri->testSegmentEdgeIntersection(TT::QR, TT::OZ)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::QR, TT::YZ) && tri->testSegmentEdgeIntersection(TT::QR, TT::YZ)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::QR, TT::ZX) && tri->testSegmentEdgeIntersection(TT::QR, TT::ZX)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::QR, TT::XY) && tri->testSegmentEdgeIntersection(TT::QR, TT::XY)); - - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::RP, TT::OX) && tri->testSegmentEdgeIntersection(TT::RP, TT::OX)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::RP, TT::OY) && tri->testSegmentEdgeIntersection(TT::RP, TT::OY)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::RP, TT::OZ) && tri->testSegmentEdgeIntersection(TT::RP, TT::OZ)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::RP, TT::YZ) && tri->testSegmentEdgeIntersection(TT::RP, TT::YZ)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::RP, TT::ZX) && tri->testSegmentEdgeIntersection(TT::RP, TT::ZX)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::RP, TT::XY) && tri->testSegmentEdgeIntersection(TT::RP, TT::XY)); - - // segment - corner (12 possibilities) - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::PQ, TT::O) && tri->testSegmentCornerIntersection(TT::PQ, TT::O)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::PQ, TT::X) && tri->testSegmentCornerIntersection(TT::PQ, TT::X)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::PQ, TT::Y) && tri->testSegmentCornerIntersection(TT::PQ, TT::Y)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::PQ, TT::Z) && tri->testSegmentCornerIntersection(TT::PQ, TT::Z)); - - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::QR, TT::O) && tri->testSegmentCornerIntersection(TT::QR, TT::O)); - CPPUNIT_ASSERT_EQUAL(true , TEST_ZERO_DP_CORNER(TT::QR, TT::X) && tri->testSegmentCornerIntersection(TT::QR, TT::X)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::QR, TT::Y) && tri->testSegmentCornerIntersection(TT::QR, TT::Y)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::QR, TT::Z) && tri->testSegmentCornerIntersection(TT::QR, TT::Z)); - - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::RP, TT::O) && tri->testSegmentCornerIntersection(TT::RP, TT::O)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::RP, TT::X) && tri->testSegmentCornerIntersection(TT::RP, TT::X)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::RP, TT::Y) && tri->testSegmentCornerIntersection(TT::RP, TT::Y)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::RP, TT::Z) && tri->testSegmentCornerIntersection(TT::RP, TT::Z)); - - // segment-halfstrip (9 possibilities) - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentHalfstripIntersection(TT::PQ, TT::YZ)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentHalfstripIntersection(TT::PQ, TT::ZX)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentHalfstripIntersection(TT::PQ, TT::XY)); - - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentHalfstripIntersection(TT::QR, TT::YZ)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentHalfstripIntersection(TT::QR, TT::ZX)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentHalfstripIntersection(TT::QR, TT::XY)); - - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentHalfstripIntersection(TT::RP, TT::YZ)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentHalfstripIntersection(TT::RP, TT::ZX)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentHalfstripIntersection(TT::RP, TT::XY)); - - // segment-ray (9 possibilities) - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_RAY(TT::PQ, TT::X) && tri->testSegmentRayIntersection(TT::PQ, TT::X)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_RAY(TT::PQ, TT::Y) && tri->testSegmentRayIntersection(TT::PQ, TT::Y)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_RAY(TT::PQ, TT::Z) && tri->testSegmentRayIntersection(TT::PQ, TT::Z)); - - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_RAY(TT::QR, TT::X) && tri->testSegmentRayIntersection(TT::QR, TT::X)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_RAY(TT::QR, TT::Y) && tri->testSegmentRayIntersection(TT::QR, TT::Y)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_RAY(TT::QR, TT::Z) && tri->testSegmentRayIntersection(TT::QR, TT::Z)); - - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_RAY(TT::RP, TT::X) && tri->testSegmentRayIntersection(TT::RP, TT::X)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_RAY(TT::RP, TT::Y) && tri->testSegmentRayIntersection(TT::RP, TT::Y)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_RAY(TT::RP, TT::Z) && tri->testSegmentRayIntersection(TT::RP, TT::Z)); - - // surface-edge (6 possibilities) - CPPUNIT_ASSERT_EQUAL(true , tri->testSurfaceEdgeIntersection(TT::OX)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSurfaceEdgeIntersection(TT::OY)); - CPPUNIT_ASSERT_EQUAL(true , tri->testSurfaceEdgeIntersection(TT::OZ)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSurfaceEdgeIntersection(TT::YZ)); - CPPUNIT_ASSERT_EQUAL(true , tri->testSurfaceEdgeIntersection(TT::ZX)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSurfaceEdgeIntersection(TT::XY)); - - // surface-ray (3 possibilities) - CPPUNIT_ASSERT_EQUAL(false, tri->testSurfaceRayIntersection(TT::X)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSurfaceRayIntersection(TT::Y)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSurfaceRayIntersection(TT::Z)); - - delete tri; - } - - /// Triangle 3 has the following intersections - ///
-  /// CI     P
-  /// COH    -
-  /// CAH    -
-  /// SF     (PQ, XYZ), (RP, OYZ)
-  /// SE     -
-  /// SC     -
-  /// SHS    (PQ, XY), (QR, YZ), (QR, XY)
-  /// SR     - 
-  /// TE     YZ
-  /// TR     - 
-  /// 
- /// \brief Status : pass - void TransformedTriangleIntersectTest::testTriangle3() - { - LOG(1, "+++++++ Testing triangle 3" ); - typedef TransformedTriangle TT; - - double coords[9] = - { - 0.35, 0.15, 0.1, // P - 0.8, 0.8, 0.8, // Q - -0.4, 0.3, 0.9 // R - }; - - TransformedTriangle* tri = new TransformedTriangle(&coords[0], &coords[3], &coords[6]); - - // run all intersection tests and ensure that the ones - // listed with yes in the tables above return true and - // that the ones listed with no or not listed at all return false - - bool isZero[TT::NO_TRI_SEGMENT * TT::NO_DP]; - - for(TriSegment seg = TT::PQ ; seg < TT::NO_TRI_SEGMENT ; seg = TT::TriSegment(seg + 1)) - { - // check beforehand which double-products are zero - for(DoubleProduct dp = TT::C_YZ; dp < TT::NO_DP; dp = DoubleProduct(dp + 1)) - { - isZero[TT::NO_DP*int(seg) + int(dp)] = (tri->calcStableC(seg, dp) == 0.0); - } - } - - // corner in tetrahedron (3 possibilities) - CPPUNIT_ASSERT_EQUAL(true , tri->testCornerInTetrahedron(TT::P)); - CPPUNIT_ASSERT_EQUAL(false, tri->testCornerInTetrahedron(TT::Q)); - CPPUNIT_ASSERT_EQUAL(false, tri->testCornerInTetrahedron(TT::R)); - - // corner on XYZ facet (3 possibilities) - CPPUNIT_ASSERT_EQUAL(false, tri->testCornerOnXYZFacet(TT::P)); - CPPUNIT_ASSERT_EQUAL(false, tri->testCornerOnXYZFacet(TT::Q)); - CPPUNIT_ASSERT_EQUAL(false, tri->testCornerOnXYZFacet(TT::R)); - - // corner above XYZ facet (3 possibilities) - CPPUNIT_ASSERT_EQUAL(false, tri->testCornerAboveXYZFacet(TT::P)); - CPPUNIT_ASSERT_EQUAL(false, tri->testCornerAboveXYZFacet(TT::Q)); - CPPUNIT_ASSERT_EQUAL(false, tri->testCornerAboveXYZFacet(TT::R)); - - // segment-facet (9 possibilities) - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::PQ, TT::OZX)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::PQ, TT::OYZ)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::PQ, TT::OXY)); - CPPUNIT_ASSERT_EQUAL(true , tri->testSegmentFacetIntersection(TT::PQ, TT::XYZ)); - - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::QR, TT::OZX)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::QR, TT::OYZ)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::QR, TT::OXY)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::QR, TT::XYZ)); - - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::RP, TT::OZX)); - CPPUNIT_ASSERT_EQUAL(true , tri->testSegmentFacetIntersection(TT::RP, TT::OYZ)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::RP, TT::OXY)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::RP, TT::XYZ)); - - // segment-edge (18 possibilities) - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::PQ, TT::OX) && tri->testSegmentEdgeIntersection(TT::PQ, TT::OX)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::PQ, TT::OY) && tri->testSegmentEdgeIntersection(TT::PQ, TT::OY)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::PQ, TT::OZ) && tri->testSegmentEdgeIntersection(TT::PQ, TT::OZ)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::PQ, TT::YZ) && tri->testSegmentEdgeIntersection(TT::PQ, TT::YZ)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::PQ, TT::ZX) && tri->testSegmentEdgeIntersection(TT::PQ, TT::ZX)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::PQ, TT::XY) && tri->testSegmentEdgeIntersection(TT::PQ, TT::XY)); - - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::QR, TT::OX) && tri->testSegmentEdgeIntersection(TT::QR, TT::OX)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::QR, TT::OY) && tri->testSegmentEdgeIntersection(TT::QR, TT::OY)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::QR, TT::OZ) && tri->testSegmentEdgeIntersection(TT::QR, TT::OZ)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::QR, TT::YZ) && tri->testSegmentEdgeIntersection(TT::QR, TT::YZ)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::QR, TT::ZX) && tri->testSegmentEdgeIntersection(TT::QR, TT::ZX)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::QR, TT::XY) && tri->testSegmentEdgeIntersection(TT::QR, TT::XY)); - - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::RP, TT::OX) && tri->testSegmentEdgeIntersection(TT::RP, TT::OX)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::RP, TT::OY) && tri->testSegmentEdgeIntersection(TT::RP, TT::OY)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::RP, TT::OZ) && tri->testSegmentEdgeIntersection(TT::RP, TT::OZ)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::RP, TT::YZ) && tri->testSegmentEdgeIntersection(TT::RP, TT::YZ)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::RP, TT::ZX) && tri->testSegmentEdgeIntersection(TT::RP, TT::ZX)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::RP, TT::XY) && tri->testSegmentEdgeIntersection(TT::RP, TT::XY)); - - // segment - corner (12 possibilities) - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::PQ, TT::O) && tri->testSegmentCornerIntersection(TT::PQ, TT::O)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::PQ, TT::X) && tri->testSegmentCornerIntersection(TT::PQ, TT::X)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::PQ, TT::Y) && tri->testSegmentCornerIntersection(TT::PQ, TT::Y)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::PQ, TT::Z) && tri->testSegmentCornerIntersection(TT::PQ, TT::Z)); - - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::QR, TT::O) && tri->testSegmentCornerIntersection(TT::QR, TT::O)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::QR, TT::X) && tri->testSegmentCornerIntersection(TT::QR, TT::X)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::QR, TT::Y) && tri->testSegmentCornerIntersection(TT::QR, TT::Y)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::QR, TT::Z) && tri->testSegmentCornerIntersection(TT::QR, TT::Z)); - - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::RP, TT::O) && tri->testSegmentCornerIntersection(TT::RP, TT::O)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::RP, TT::X) && tri->testSegmentCornerIntersection(TT::RP, TT::X)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::RP, TT::Y) && tri->testSegmentCornerIntersection(TT::RP, TT::Y)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::RP, TT::Z) && tri->testSegmentCornerIntersection(TT::RP, TT::Z)); - - // segment-halfstrip (9 possibilities) - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentHalfstripIntersection(TT::PQ, TT::YZ)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentHalfstripIntersection(TT::PQ, TT::ZX)); - CPPUNIT_ASSERT_EQUAL(true , tri->testSegmentHalfstripIntersection(TT::PQ, TT::XY)); - - CPPUNIT_ASSERT_EQUAL(true , tri->testSegmentHalfstripIntersection(TT::QR, TT::YZ)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentHalfstripIntersection(TT::QR, TT::ZX)); - CPPUNIT_ASSERT_EQUAL(true , tri->testSegmentHalfstripIntersection(TT::QR, TT::XY)); - - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentHalfstripIntersection(TT::RP, TT::YZ)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentHalfstripIntersection(TT::RP, TT::ZX)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentHalfstripIntersection(TT::RP, TT::XY)); - - // segment-ray (9 possibilities) - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_RAY(TT::PQ, TT::X) && tri->testSegmentRayIntersection(TT::PQ, TT::X)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_RAY(TT::PQ, TT::Y) && tri->testSegmentRayIntersection(TT::PQ, TT::Y)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_RAY(TT::PQ, TT::Z) && tri->testSegmentRayIntersection(TT::PQ, TT::Z)); - - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_RAY(TT::QR, TT::X) && tri->testSegmentRayIntersection(TT::QR, TT::X)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_RAY(TT::QR, TT::Y) && tri->testSegmentRayIntersection(TT::QR, TT::Y)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_RAY(TT::QR, TT::Z) && tri->testSegmentRayIntersection(TT::QR, TT::Z)); - - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_RAY(TT::RP, TT::X) && tri->testSegmentRayIntersection(TT::RP, TT::X)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_RAY(TT::RP, TT::Y) && tri->testSegmentRayIntersection(TT::RP, TT::Y)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_RAY(TT::RP, TT::Z) && tri->testSegmentRayIntersection(TT::RP, TT::Z)); - - // surface-edge (6 possibilities) - CPPUNIT_ASSERT_EQUAL(false, tri->testSurfaceEdgeIntersection(TT::OX)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSurfaceEdgeIntersection(TT::OY)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSurfaceEdgeIntersection(TT::OZ)); - CPPUNIT_ASSERT_EQUAL(true , tri->testSurfaceEdgeIntersection(TT::YZ)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSurfaceEdgeIntersection(TT::ZX)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSurfaceEdgeIntersection(TT::XY)); - - // surface-ray (3 possibilities) - CPPUNIT_ASSERT_EQUAL(false, tri->testSurfaceRayIntersection(TT::X)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSurfaceRayIntersection(TT::Y)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSurfaceRayIntersection(TT::Z)); - - delete tri; - } - - /// Triangle 4 has the following intersections - ///
-  /// CI     Q
-  /// COH    -
-  /// CAH    P
-  /// SF     (PQ, XYZ), (QR, OXY)
-  /// SE     -
-  /// SC     -
-  /// SHS    (RP, ZX)
-  /// SR     - 
-  /// TE     (OX, ZX)
-  /// TR     - 
-  /// 
- /// \brief Status : pass - void TransformedTriangleIntersectTest::testTriangle4() - { - LOG(1, "+++++++ Testing triangle 4" ); - typedef TransformedTriangle TT; - - double coords[9] = - { - 0.3, 0.3, 1.8, // P - 0.75, 0.1, 0.1, // Q - 0.2, -1.3, -1.4 // R - }; - - TransformedTriangle* tri = new TransformedTriangle(&coords[0], &coords[3], &coords[6]); - - // run all intersection tests and ensure that the ones - // listed with yes in the tables above return true and - // that the ones listed with no or not listed at all return false - - bool isZero[TT::NO_TRI_SEGMENT * TT::NO_DP]; - - for(TriSegment seg = TT::PQ ; seg < TT::NO_TRI_SEGMENT ; seg = TT::TriSegment(seg + 1)) - { - // check beforehand which double-products are zero - for(DoubleProduct dp = TT::C_YZ; dp < TT::NO_DP; dp = DoubleProduct(dp + 1)) - { - isZero[TT::NO_DP*int(seg) + int(dp)] = (tri->calcStableC(seg, dp) == 0.0); - } - } - - // corner in tetrahedron (3 possibilities) - CPPUNIT_ASSERT_EQUAL(false, tri->testCornerInTetrahedron(TT::P)); - CPPUNIT_ASSERT_EQUAL(true , tri->testCornerInTetrahedron(TT::Q)); - CPPUNIT_ASSERT_EQUAL(false, tri->testCornerInTetrahedron(TT::R)); - - // corner on XYZ facet (3 possibilities) - CPPUNIT_ASSERT_EQUAL(false, tri->testCornerOnXYZFacet(TT::P)); - CPPUNIT_ASSERT_EQUAL(false, tri->testCornerOnXYZFacet(TT::Q)); - CPPUNIT_ASSERT_EQUAL(false, tri->testCornerOnXYZFacet(TT::R)); - - // corner above XYZ facet (3 possibilities) - CPPUNIT_ASSERT_EQUAL(true , tri->testCornerAboveXYZFacet(TT::P)); - CPPUNIT_ASSERT_EQUAL(false, tri->testCornerAboveXYZFacet(TT::Q)); - CPPUNIT_ASSERT_EQUAL(false, tri->testCornerAboveXYZFacet(TT::R)); - - // segment-facet (9 possibilities) - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::PQ, TT::OZX)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::PQ, TT::OYZ)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::PQ, TT::OXY)); - CPPUNIT_ASSERT_EQUAL(true , tri->testSegmentFacetIntersection(TT::PQ, TT::XYZ)); - - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::QR, TT::OZX)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::QR, TT::OYZ)); - CPPUNIT_ASSERT_EQUAL(true , tri->testSegmentFacetIntersection(TT::QR, TT::OXY)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::QR, TT::XYZ)); - - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::RP, TT::OZX)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::RP, TT::OYZ)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::RP, TT::OXY)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::RP, TT::XYZ)); - - // segment-edge (18 possibilities) - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::PQ, TT::OX) && tri->testSegmentEdgeIntersection(TT::PQ, TT::OX)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::PQ, TT::OY) && tri->testSegmentEdgeIntersection(TT::PQ, TT::OY)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::PQ, TT::OZ) && tri->testSegmentEdgeIntersection(TT::PQ, TT::OZ)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::PQ, TT::YZ) && tri->testSegmentEdgeIntersection(TT::PQ, TT::YZ)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::PQ, TT::ZX) && tri->testSegmentEdgeIntersection(TT::PQ, TT::ZX)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::PQ, TT::XY) && tri->testSegmentEdgeIntersection(TT::PQ, TT::XY)); - - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::QR, TT::OX) && tri->testSegmentEdgeIntersection(TT::QR, TT::OX)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::QR, TT::OY) && tri->testSegmentEdgeIntersection(TT::QR, TT::OY)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::QR, TT::OZ) && tri->testSegmentEdgeIntersection(TT::QR, TT::OZ)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::QR, TT::YZ) && tri->testSegmentEdgeIntersection(TT::QR, TT::YZ)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::QR, TT::ZX) && tri->testSegmentEdgeIntersection(TT::QR, TT::ZX)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::QR, TT::XY) && tri->testSegmentEdgeIntersection(TT::QR, TT::XY)); - - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::RP, TT::OX) && tri->testSegmentEdgeIntersection(TT::RP, TT::OX)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::RP, TT::OY) && tri->testSegmentEdgeIntersection(TT::RP, TT::OY)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::RP, TT::OZ) && tri->testSegmentEdgeIntersection(TT::RP, TT::OZ)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::RP, TT::YZ) && tri->testSegmentEdgeIntersection(TT::RP, TT::YZ)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::RP, TT::ZX) && tri->testSegmentEdgeIntersection(TT::RP, TT::ZX)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::RP, TT::XY) && tri->testSegmentEdgeIntersection(TT::RP, TT::XY)); - - // segment - corner (12 possibilities) - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::PQ, TT::O) && tri->testSegmentCornerIntersection(TT::PQ, TT::O)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::PQ, TT::X) && tri->testSegmentCornerIntersection(TT::PQ, TT::X)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::PQ, TT::Y) && tri->testSegmentCornerIntersection(TT::PQ, TT::Y)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::PQ, TT::Z) && tri->testSegmentCornerIntersection(TT::PQ, TT::Z)); - - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::QR, TT::O) && tri->testSegmentCornerIntersection(TT::QR, TT::O)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::QR, TT::X) && tri->testSegmentCornerIntersection(TT::QR, TT::X)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::QR, TT::Y) && tri->testSegmentCornerIntersection(TT::QR, TT::Y)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::QR, TT::Z) && tri->testSegmentCornerIntersection(TT::QR, TT::Z)); - - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::RP, TT::O) && tri->testSegmentCornerIntersection(TT::RP, TT::O)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::RP, TT::X) && tri->testSegmentCornerIntersection(TT::RP, TT::X)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::RP, TT::Y) && tri->testSegmentCornerIntersection(TT::RP, TT::Y)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::RP, TT::Z) && tri->testSegmentCornerIntersection(TT::RP, TT::Z)); - - - // segment-halfstrip (9 possibilities) - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentHalfstripIntersection(TT::PQ, TT::YZ)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentHalfstripIntersection(TT::PQ, TT::ZX)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentHalfstripIntersection(TT::PQ, TT::XY)); - - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentHalfstripIntersection(TT::QR, TT::YZ)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentHalfstripIntersection(TT::QR, TT::ZX)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentHalfstripIntersection(TT::QR, TT::XY)); - - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentHalfstripIntersection(TT::RP, TT::YZ)); - CPPUNIT_ASSERT_EQUAL(true , tri->testSegmentHalfstripIntersection(TT::RP, TT::ZX)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentHalfstripIntersection(TT::RP, TT::XY)); - - // segment-ray (9 possibilities) - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_RAY(TT::PQ, TT::X) && tri->testSegmentRayIntersection(TT::PQ, TT::X)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_RAY(TT::PQ, TT::Y) && tri->testSegmentRayIntersection(TT::PQ, TT::Y)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_RAY(TT::PQ, TT::Z) && tri->testSegmentRayIntersection(TT::PQ, TT::Z)); - - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_RAY(TT::QR, TT::X) && tri->testSegmentRayIntersection(TT::QR, TT::X)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_RAY(TT::QR, TT::Y) && tri->testSegmentRayIntersection(TT::QR, TT::Y)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_RAY(TT::QR, TT::Z) && tri->testSegmentRayIntersection(TT::QR, TT::Z)); - - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_RAY(TT::RP, TT::X) && tri->testSegmentRayIntersection(TT::RP, TT::X)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_RAY(TT::RP, TT::Y) && tri->testSegmentRayIntersection(TT::RP, TT::Y)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_RAY(TT::RP, TT::Z) && tri->testSegmentRayIntersection(TT::RP, TT::Z)); - - // surface-edge (6 possibilities) - CPPUNIT_ASSERT_EQUAL(true , tri->testSurfaceEdgeIntersection(TT::OX)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSurfaceEdgeIntersection(TT::OY)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSurfaceEdgeIntersection(TT::OZ)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSurfaceEdgeIntersection(TT::YZ)); - CPPUNIT_ASSERT_EQUAL(true , tri->testSurfaceEdgeIntersection(TT::ZX)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSurfaceEdgeIntersection(TT::XY)); - - // surface-ray (3 possibilities) - CPPUNIT_ASSERT_EQUAL(false, tri->testSurfaceRayIntersection(TT::X)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSurfaceRayIntersection(TT::Y)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSurfaceRayIntersection(TT::Z)); - - delete tri; - } - - /// Triangle 5 has the following intersections - ///
-  /// CI     -
-  /// COH    -
-  /// CAH    -
-  /// SF     -
-  /// SE     -
-  /// SC     -
-  /// SHS    (QR, ZX), (QR, XY)
-  /// SR     (PQ, Y)
-  /// TE     -
-  /// TR     Z
-  /// 
- /// \brief Status : pass - void TransformedTriangleIntersectTest::testTriangle5() - { - LOG(1, "+++++++ Testing triangle 5" ); - - typedef TransformedTriangle TT; - - double coords[9] = - { - -0.5, 0.5, 2.3, // P - 0.5, 1.5, 2.8, // Q - 0.5, -2.6, 1.3 // R - }; - - TransformedTriangle* tri = new TransformedTriangle(&coords[0], &coords[3], &coords[6]); - - // run all intersection tests and ensure that the ones - // listed with yes in the tables above return true and - // that the ones listed with no or not listed at all return false - - bool isZero[TT::NO_TRI_SEGMENT * TT::NO_DP]; - - for(TriSegment seg = TT::PQ ; seg < TT::NO_TRI_SEGMENT ; seg = TT::TriSegment(seg + 1)) - { - // check beforehand which double-products are zero - for(DoubleProduct dp = TT::C_YZ; dp < TT::NO_DP; dp = DoubleProduct(dp + 1)) - { - isZero[TT::NO_DP*int(seg) + int(dp)] = (tri->calcStableC(seg, dp) == 0.0); - } - } - - // corner in tetrahedron (3 possibilities) - CPPUNIT_ASSERT_EQUAL(false, tri->testCornerInTetrahedron(TT::P)); - CPPUNIT_ASSERT_EQUAL(false, tri->testCornerInTetrahedron(TT::Q)); - CPPUNIT_ASSERT_EQUAL(false, tri->testCornerInTetrahedron(TT::R)); - - // corner on XYZ facet (3 possibilities) - CPPUNIT_ASSERT_EQUAL(false, tri->testCornerOnXYZFacet(TT::P)); - CPPUNIT_ASSERT_EQUAL(false, tri->testCornerOnXYZFacet(TT::Q)); - CPPUNIT_ASSERT_EQUAL(false, tri->testCornerOnXYZFacet(TT::R)); - - // corner above XYZ facet (3 possibilities) - CPPUNIT_ASSERT_EQUAL(false, tri->testCornerAboveXYZFacet(TT::P)); - CPPUNIT_ASSERT_EQUAL(false, tri->testCornerAboveXYZFacet(TT::Q)); - CPPUNIT_ASSERT_EQUAL(false, tri->testCornerAboveXYZFacet(TT::R)); - - // segment-facet (9 possibilities) - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::PQ, TT::OZX)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::PQ, TT::OYZ)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::PQ, TT::OXY)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::PQ, TT::XYZ)); - - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::QR, TT::OZX)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::QR, TT::OYZ)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::QR, TT::OXY)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::QR, TT::XYZ)); - - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::RP, TT::OZX)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::RP, TT::OYZ)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::RP, TT::OXY)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::RP, TT::XYZ)); - - // segment-edge (18 possibilities) - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::PQ, TT::OX) && tri->testSegmentEdgeIntersection(TT::PQ, TT::OX)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::PQ, TT::OY) && tri->testSegmentEdgeIntersection(TT::PQ, TT::OY)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::PQ, TT::OZ) && tri->testSegmentEdgeIntersection(TT::PQ, TT::OZ)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::PQ, TT::YZ) && tri->testSegmentEdgeIntersection(TT::PQ, TT::YZ)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::PQ, TT::ZX) && tri->testSegmentEdgeIntersection(TT::PQ, TT::ZX)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::PQ, TT::XY) && tri->testSegmentEdgeIntersection(TT::PQ, TT::XY)); - - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::QR, TT::OX) && tri->testSegmentEdgeIntersection(TT::QR, TT::OX)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::QR, TT::OY) && tri->testSegmentEdgeIntersection(TT::QR, TT::OY)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::QR, TT::OZ) && tri->testSegmentEdgeIntersection(TT::QR, TT::OZ)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::QR, TT::YZ) && tri->testSegmentEdgeIntersection(TT::QR, TT::YZ)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::QR, TT::ZX) && tri->testSegmentEdgeIntersection(TT::QR, TT::ZX)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::QR, TT::XY) && tri->testSegmentEdgeIntersection(TT::QR, TT::XY)); - - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::RP, TT::OX) && tri->testSegmentEdgeIntersection(TT::RP, TT::OX)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::RP, TT::OY) && tri->testSegmentEdgeIntersection(TT::RP, TT::OY)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::RP, TT::OZ) && tri->testSegmentEdgeIntersection(TT::RP, TT::OZ)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::RP, TT::YZ) && tri->testSegmentEdgeIntersection(TT::RP, TT::YZ)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::RP, TT::ZX) && tri->testSegmentEdgeIntersection(TT::RP, TT::ZX)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::RP, TT::XY) && tri->testSegmentEdgeIntersection(TT::RP, TT::XY)); - - // segment - corner (12 possibilities) - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::PQ, TT::O) && tri->testSegmentCornerIntersection(TT::PQ, TT::O)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::PQ, TT::X) && tri->testSegmentCornerIntersection(TT::PQ, TT::X)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::PQ, TT::Y) && tri->testSegmentCornerIntersection(TT::PQ, TT::Y)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::PQ, TT::Z) && tri->testSegmentCornerIntersection(TT::PQ, TT::Z)); - - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::QR, TT::O) && tri->testSegmentCornerIntersection(TT::QR, TT::O)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::QR, TT::X) && tri->testSegmentCornerIntersection(TT::QR, TT::X)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::QR, TT::Y) && tri->testSegmentCornerIntersection(TT::QR, TT::Y)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::QR, TT::Z) && tri->testSegmentCornerIntersection(TT::QR, TT::Z)); - - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::RP, TT::O) && tri->testSegmentCornerIntersection(TT::RP, TT::O)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::RP, TT::X) && tri->testSegmentCornerIntersection(TT::RP, TT::X)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::RP, TT::Y) && tri->testSegmentCornerIntersection(TT::RP, TT::Y)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::RP, TT::Z) && tri->testSegmentCornerIntersection(TT::RP, TT::Z)); - - // segment-halfstrip (9 possibilities) - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentHalfstripIntersection(TT::PQ, TT::YZ)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentHalfstripIntersection(TT::PQ, TT::ZX)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentHalfstripIntersection(TT::PQ, TT::XY)); - - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentHalfstripIntersection(TT::QR, TT::YZ)); - CPPUNIT_ASSERT_EQUAL(true , tri->testSegmentHalfstripIntersection(TT::QR, TT::ZX)); - CPPUNIT_ASSERT_EQUAL(true , tri->testSegmentHalfstripIntersection(TT::QR, TT::XY)); - - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentHalfstripIntersection(TT::RP, TT::YZ)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentHalfstripIntersection(TT::RP, TT::ZX)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentHalfstripIntersection(TT::RP, TT::XY)); - - // segment-ray (9 possibilities) - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_RAY(TT::PQ, TT::X) && tri->testSegmentRayIntersection(TT::PQ, TT::X)); - CPPUNIT_ASSERT_EQUAL(true , TEST_ZERO_DP_RAY(TT::PQ, TT::Y) && tri->testSegmentRayIntersection(TT::PQ, TT::Y)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_RAY(TT::PQ, TT::Z) && tri->testSegmentRayIntersection(TT::PQ, TT::Z)); - - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_RAY(TT::QR, TT::X) && tri->testSegmentRayIntersection(TT::QR, TT::X)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_RAY(TT::QR, TT::Y) && tri->testSegmentRayIntersection(TT::QR, TT::Y)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_RAY(TT::QR, TT::Z) && tri->testSegmentRayIntersection(TT::QR, TT::Z)); - - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_RAY(TT::RP, TT::X) && tri->testSegmentRayIntersection(TT::RP, TT::X)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_RAY(TT::RP, TT::Y) && tri->testSegmentRayIntersection(TT::RP, TT::Y)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_RAY(TT::RP, TT::Z) && tri->testSegmentRayIntersection(TT::RP, TT::Z)); - - // surface-edge (6 possibilities) - CPPUNIT_ASSERT_EQUAL(false, tri->testSurfaceEdgeIntersection(TT::OX)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSurfaceEdgeIntersection(TT::OY)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSurfaceEdgeIntersection(TT::OZ)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSurfaceEdgeIntersection(TT::YZ)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSurfaceEdgeIntersection(TT::ZX)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSurfaceEdgeIntersection(TT::XY)); - - // surface-ray (3 possibilities) - CPPUNIT_ASSERT_EQUAL(false, tri->testSurfaceRayIntersection(TT::X)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSurfaceRayIntersection(TT::Y)); - CPPUNIT_ASSERT_EQUAL(true , tri->testSurfaceRayIntersection(TT::Z)); - - delete tri; - } - - /// Triangle 6 has the following intersections - ///
-  /// CI     -
-  /// COH    -
-  /// CAH    -
-  /// SF     -
-  /// SE     -
-  /// SC     -
-  /// SHS    -
-  /// SR     (PQ, X), (QR, Z) 
-  /// TE     -
-  /// TR     Y 
-  /// 
- /// \brief Status : pass - void TransformedTriangleIntersectTest::testTriangle6() - { - LOG(1, "+++++++ Testing triangle 6" ); - - typedef TransformedTriangle TT; - - double coords[9] = - { - 1.5, 0.5, 1.35, // P - 0.5, -0.5, 2.1, // Q - -3.0, 3.0, -0.5 // R - }; - - TransformedTriangle* tri = new TransformedTriangle(&coords[0], &coords[3], &coords[6]); - - // run all intersection tests and ensure that the ones - // listed with yes in the tables above return true and - // that the ones listed with no or not listed at all return false - - bool isZero[TT::NO_TRI_SEGMENT * TT::NO_DP]; - - for(TriSegment seg = TT::PQ ; seg < TT::NO_TRI_SEGMENT ; seg = TT::TriSegment(seg + 1)) - { - // check beforehand which double-products are zero - for(DoubleProduct dp = TT::C_YZ; dp < TT::NO_DP; dp = DoubleProduct(dp + 1)) - { - isZero[TT::NO_DP*int(seg) + int(dp)] = (tri->calcStableC(seg, dp) == 0.0); - } - } - - // corner in tetrahedron (3 possibilities) - CPPUNIT_ASSERT_EQUAL(false, tri->testCornerInTetrahedron(TT::P)); - CPPUNIT_ASSERT_EQUAL(false, tri->testCornerInTetrahedron(TT::Q)); - CPPUNIT_ASSERT_EQUAL(false, tri->testCornerInTetrahedron(TT::R)); - - // corner on XYZ facet (3 possibilities) - CPPUNIT_ASSERT_EQUAL(false, tri->testCornerOnXYZFacet(TT::P)); - CPPUNIT_ASSERT_EQUAL(false, tri->testCornerOnXYZFacet(TT::Q)); - CPPUNIT_ASSERT_EQUAL(false, tri->testCornerOnXYZFacet(TT::R)); - - // corner above XYZ facet (3 possibilities) - CPPUNIT_ASSERT_EQUAL(false, tri->testCornerAboveXYZFacet(TT::P)); - CPPUNIT_ASSERT_EQUAL(false, tri->testCornerAboveXYZFacet(TT::Q)); - CPPUNIT_ASSERT_EQUAL(false, tri->testCornerAboveXYZFacet(TT::R)); - - // segment-facet (9 possibilities) - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::PQ, TT::OZX)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::PQ, TT::OYZ)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::PQ, TT::OXY)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::PQ, TT::XYZ)); - - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::QR, TT::OZX)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::QR, TT::OYZ)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::QR, TT::OXY)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::QR, TT::XYZ)); - - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::RP, TT::OZX)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::RP, TT::OYZ)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::RP, TT::OXY)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::RP, TT::XYZ)); - - // segment-edge (18 possibilities) - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::PQ, TT::OX) && tri->testSegmentEdgeIntersection(TT::PQ, TT::OX)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::PQ, TT::OY) && tri->testSegmentEdgeIntersection(TT::PQ, TT::OY)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::PQ, TT::OZ) && tri->testSegmentEdgeIntersection(TT::PQ, TT::OZ)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::PQ, TT::YZ) && tri->testSegmentEdgeIntersection(TT::PQ, TT::YZ)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::PQ, TT::ZX) && tri->testSegmentEdgeIntersection(TT::PQ, TT::ZX)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::PQ, TT::XY) && tri->testSegmentEdgeIntersection(TT::PQ, TT::XY)); - - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::QR, TT::OX) && tri->testSegmentEdgeIntersection(TT::QR, TT::OX)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::QR, TT::OY) && tri->testSegmentEdgeIntersection(TT::QR, TT::OY)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::QR, TT::OZ) && tri->testSegmentEdgeIntersection(TT::QR, TT::OZ)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::QR, TT::YZ) && tri->testSegmentEdgeIntersection(TT::QR, TT::YZ)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::QR, TT::ZX) && tri->testSegmentEdgeIntersection(TT::QR, TT::ZX)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::QR, TT::XY) && tri->testSegmentEdgeIntersection(TT::QR, TT::XY)); - - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::RP, TT::OX) && tri->testSegmentEdgeIntersection(TT::RP, TT::OX)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::RP, TT::OY) && tri->testSegmentEdgeIntersection(TT::RP, TT::OY)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::RP, TT::OZ) && tri->testSegmentEdgeIntersection(TT::RP, TT::OZ)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::RP, TT::YZ) && tri->testSegmentEdgeIntersection(TT::RP, TT::YZ)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::RP, TT::ZX) && tri->testSegmentEdgeIntersection(TT::RP, TT::ZX)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::RP, TT::XY) && tri->testSegmentEdgeIntersection(TT::RP, TT::XY)); - - // segment - corner (12 possibilities) - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::PQ, TT::O) && tri->testSegmentCornerIntersection(TT::PQ, TT::O)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::PQ, TT::X) && tri->testSegmentCornerIntersection(TT::PQ, TT::X)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::PQ, TT::Y) && tri->testSegmentCornerIntersection(TT::PQ, TT::Y)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::PQ, TT::Z) && tri->testSegmentCornerIntersection(TT::PQ, TT::Z)); - - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::QR, TT::O) && tri->testSegmentCornerIntersection(TT::QR, TT::O)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::QR, TT::X) && tri->testSegmentCornerIntersection(TT::QR, TT::X)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::QR, TT::Y) && tri->testSegmentCornerIntersection(TT::QR, TT::Y)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::QR, TT::Z) && tri->testSegmentCornerIntersection(TT::QR, TT::Z)); - - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::RP, TT::O) && tri->testSegmentCornerIntersection(TT::RP, TT::O)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::RP, TT::X) && tri->testSegmentCornerIntersection(TT::RP, TT::X)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::RP, TT::Y) && tri->testSegmentCornerIntersection(TT::RP, TT::Y)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::RP, TT::Z) && tri->testSegmentCornerIntersection(TT::RP, TT::Z)); - - // segment-halfstrip (9 possibilities) - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentHalfstripIntersection(TT::PQ, TT::YZ)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentHalfstripIntersection(TT::PQ, TT::ZX)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentHalfstripIntersection(TT::PQ, TT::XY)); - - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentHalfstripIntersection(TT::QR, TT::YZ)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentHalfstripIntersection(TT::QR, TT::ZX)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentHalfstripIntersection(TT::QR, TT::XY)); - - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentHalfstripIntersection(TT::RP, TT::YZ)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentHalfstripIntersection(TT::RP, TT::ZX)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentHalfstripIntersection(TT::RP, TT::XY)); - - // segment-ray (9 possibilities) - CPPUNIT_ASSERT_EQUAL(true , TEST_ZERO_DP_RAY(TT::PQ, TT::X) && tri->testSegmentRayIntersection(TT::PQ, TT::X)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_RAY(TT::PQ, TT::Y) && tri->testSegmentRayIntersection(TT::PQ, TT::Y)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_RAY(TT::PQ, TT::Z) && tri->testSegmentRayIntersection(TT::PQ, TT::Z)); - - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_RAY(TT::QR, TT::X) && tri->testSegmentRayIntersection(TT::QR, TT::X)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_RAY(TT::QR, TT::Y) && tri->testSegmentRayIntersection(TT::QR, TT::Y)); - CPPUNIT_ASSERT_EQUAL(true , TEST_ZERO_DP_RAY(TT::QR, TT::Z) && tri->testSegmentRayIntersection(TT::QR, TT::Z)); - - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_RAY(TT::RP, TT::X) && tri->testSegmentRayIntersection(TT::RP, TT::X)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_RAY(TT::RP, TT::Y) && tri->testSegmentRayIntersection(TT::RP, TT::Y)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_RAY(TT::RP, TT::Z) && tri->testSegmentRayIntersection(TT::RP, TT::Z)); - - // surface-edge (6 possibilities) - CPPUNIT_ASSERT_EQUAL(false, tri->testSurfaceEdgeIntersection(TT::OX)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSurfaceEdgeIntersection(TT::OY)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSurfaceEdgeIntersection(TT::OZ)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSurfaceEdgeIntersection(TT::YZ)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSurfaceEdgeIntersection(TT::ZX)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSurfaceEdgeIntersection(TT::XY)); - - // surface-ray (3 possibilities) - CPPUNIT_ASSERT_EQUAL(false, tri->testSurfaceRayIntersection(TT::X)); - CPPUNIT_ASSERT_EQUAL(true , tri->testSurfaceRayIntersection(TT::Y)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSurfaceRayIntersection(TT::Z)); - - delete tri; - } - - /// Triangle 7 has the following intersections - ///
-  /// CI     R
-  /// COH    -
-  /// CAH    -
-  /// SF     (RP, OXY),(QR,XYZ)
-  /// SE     -
-  /// SC     -
-  /// SHS    (QR, XY)
-  /// SR     - 
-  /// TE     OX, ZX
-  /// TR     X 
-  /// 
- /// \brief Status : pass - void TransformedTriangleIntersectTest::testTriangle7() - { - - LOG(1, "+++++++ Testing triangle 7" ); - typedef TransformedTriangle TT; - - double coords[9] = - { - -2.3, -1.5, -2.5, // P - 3.1, 0.15, 0.8, // Q - 0.3, 0.4, 0.2 // R - }; - - TransformedTriangle* tri = new TransformedTriangle(&coords[0], &coords[3], &coords[6]); - - // run all intersection tests and ensure that the ones - // listed with yes in the tables above return true and - // that the ones listed with no or not listed at all return false - - bool isZero[TT::NO_TRI_SEGMENT * TT::NO_DP]; - - for(TriSegment seg = TT::PQ ; seg < TT::NO_TRI_SEGMENT ; seg = TT::TriSegment(seg + 1)) - { - // check beforehand which double-products are zero - for(DoubleProduct dp = TT::C_YZ; dp < TT::NO_DP; dp = DoubleProduct(dp + 1)) - { - isZero[TT::NO_DP*int(seg) + int(dp)] = (tri->calcStableC(seg, dp) == 0.0); - } - } - - // corner in tetrahedron (3 possibilities) - CPPUNIT_ASSERT_EQUAL(false, tri->testCornerInTetrahedron(TT::P)); - CPPUNIT_ASSERT_EQUAL(false, tri->testCornerInTetrahedron(TT::Q)); - CPPUNIT_ASSERT_EQUAL(true , tri->testCornerInTetrahedron(TT::R)); - - // corner on XYZ facet (3 possibilities) - CPPUNIT_ASSERT_EQUAL(false, tri->testCornerOnXYZFacet(TT::P)); - CPPUNIT_ASSERT_EQUAL(false, tri->testCornerOnXYZFacet(TT::Q)); - CPPUNIT_ASSERT_EQUAL(false, tri->testCornerOnXYZFacet(TT::R)); - - // corner above XYZ facet (3 possibilities) - CPPUNIT_ASSERT_EQUAL(false, tri->testCornerAboveXYZFacet(TT::P)); - CPPUNIT_ASSERT_EQUAL(false, tri->testCornerAboveXYZFacet(TT::Q)); - CPPUNIT_ASSERT_EQUAL(false, tri->testCornerAboveXYZFacet(TT::R)); - - // segment-facet (9 possibilities) - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::PQ, TT::OZX)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::PQ, TT::OYZ)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::PQ, TT::OXY)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::PQ, TT::XYZ)); - - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::QR, TT::OZX)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::QR, TT::OYZ)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::QR, TT::OXY)); - CPPUNIT_ASSERT_EQUAL(true , tri->testSegmentFacetIntersection(TT::QR, TT::XYZ)); - - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::RP, TT::OZX)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::RP, TT::OYZ)); - CPPUNIT_ASSERT_EQUAL(true , tri->testSegmentFacetIntersection(TT::RP, TT::OXY)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::RP, TT::XYZ)); - - // segment-edge (18 possibilities) - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::PQ, TT::OX) && tri->testSegmentEdgeIntersection(TT::PQ, TT::OX)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::PQ, TT::OY) && tri->testSegmentEdgeIntersection(TT::PQ, TT::OY)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::PQ, TT::OZ) && tri->testSegmentEdgeIntersection(TT::PQ, TT::OZ)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::PQ, TT::YZ) && tri->testSegmentEdgeIntersection(TT::PQ, TT::YZ)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::PQ, TT::ZX) && tri->testSegmentEdgeIntersection(TT::PQ, TT::ZX)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::PQ, TT::XY) && tri->testSegmentEdgeIntersection(TT::PQ, TT::XY)); - - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::QR, TT::OX) && tri->testSegmentEdgeIntersection(TT::QR, TT::OX)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::QR, TT::OY) && tri->testSegmentEdgeIntersection(TT::QR, TT::OY)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::QR, TT::OZ) && tri->testSegmentEdgeIntersection(TT::QR, TT::OZ)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::QR, TT::YZ) && tri->testSegmentEdgeIntersection(TT::QR, TT::YZ)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::QR, TT::ZX) && tri->testSegmentEdgeIntersection(TT::QR, TT::ZX)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::QR, TT::XY) && tri->testSegmentEdgeIntersection(TT::QR, TT::XY)); - - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::RP, TT::OX) && tri->testSegmentEdgeIntersection(TT::RP, TT::OX)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::RP, TT::OY) && tri->testSegmentEdgeIntersection(TT::RP, TT::OY)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::RP, TT::OZ) && tri->testSegmentEdgeIntersection(TT::RP, TT::OZ)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::RP, TT::YZ) && tri->testSegmentEdgeIntersection(TT::RP, TT::YZ)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::RP, TT::ZX) && tri->testSegmentEdgeIntersection(TT::RP, TT::ZX)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::RP, TT::XY) && tri->testSegmentEdgeIntersection(TT::RP, TT::XY)); - - // segment - corner (12 possibilities) - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::PQ, TT::O) && tri->testSegmentCornerIntersection(TT::PQ, TT::O)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::PQ, TT::X) && tri->testSegmentCornerIntersection(TT::PQ, TT::X)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::PQ, TT::Y) && tri->testSegmentCornerIntersection(TT::PQ, TT::Y)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::PQ, TT::Z) && tri->testSegmentCornerIntersection(TT::PQ, TT::Z)); - - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::QR, TT::O) && tri->testSegmentCornerIntersection(TT::QR, TT::O)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::QR, TT::X) && tri->testSegmentCornerIntersection(TT::QR, TT::X)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::QR, TT::Y) && tri->testSegmentCornerIntersection(TT::QR, TT::Y)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::QR, TT::Z) && tri->testSegmentCornerIntersection(TT::QR, TT::Z)); - - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::RP, TT::O) && tri->testSegmentCornerIntersection(TT::RP, TT::O)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::RP, TT::X) && tri->testSegmentCornerIntersection(TT::RP, TT::X)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::RP, TT::Y) && tri->testSegmentCornerIntersection(TT::RP, TT::Y)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::RP, TT::Z) && tri->testSegmentCornerIntersection(TT::RP, TT::Z)); - - - // segment-halfstrip (9 possibilities) - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentHalfstripIntersection(TT::PQ, TT::YZ)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentHalfstripIntersection(TT::PQ, TT::ZX)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentHalfstripIntersection(TT::PQ, TT::XY)); - - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentHalfstripIntersection(TT::QR, TT::YZ)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentHalfstripIntersection(TT::QR, TT::ZX)); - CPPUNIT_ASSERT_EQUAL(true , tri->testSegmentHalfstripIntersection(TT::QR, TT::XY)); - - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentHalfstripIntersection(TT::RP, TT::YZ)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentHalfstripIntersection(TT::RP, TT::ZX)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentHalfstripIntersection(TT::RP, TT::XY)); - - // segment-ray (9 possibilities) - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_RAY(TT::PQ, TT::X) && tri->testSegmentRayIntersection(TT::PQ, TT::X)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_RAY(TT::PQ, TT::Y) && tri->testSegmentRayIntersection(TT::PQ, TT::Y)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_RAY(TT::PQ, TT::Z) && tri->testSegmentRayIntersection(TT::PQ, TT::Z)); - - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_RAY(TT::QR, TT::X) && tri->testSegmentRayIntersection(TT::QR, TT::X)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_RAY(TT::QR, TT::Y) && tri->testSegmentRayIntersection(TT::QR, TT::Y)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_RAY(TT::QR, TT::Z) && tri->testSegmentRayIntersection(TT::QR, TT::Z)); - - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_RAY(TT::RP, TT::X) && tri->testSegmentRayIntersection(TT::RP, TT::X)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_RAY(TT::RP, TT::Y) && tri->testSegmentRayIntersection(TT::RP, TT::Y)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_RAY(TT::RP, TT::Z) && tri->testSegmentRayIntersection(TT::RP, TT::Z)); - - // surface-edge (6 possibilities) - CPPUNIT_ASSERT_EQUAL(true , tri->testSurfaceEdgeIntersection(TT::OX)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSurfaceEdgeIntersection(TT::OY)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSurfaceEdgeIntersection(TT::OZ)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSurfaceEdgeIntersection(TT::YZ)); - CPPUNIT_ASSERT_EQUAL(true , tri->testSurfaceEdgeIntersection(TT::ZX)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSurfaceEdgeIntersection(TT::XY)); - - // surface-ray (3 possibilities) - CPPUNIT_ASSERT_EQUAL(true , tri->testSurfaceRayIntersection(TT::X)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSurfaceRayIntersection(TT::Y)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSurfaceRayIntersection(TT::Z)); - - delete tri; - } - - /// Triangle 8 has the following intersections - ///
-  /// CI     [Q] 
-  /// COH    Q
-  /// CAH    -
-  /// SF     (QR, OZX), [ (QR, XYZ) ]
-  /// SE     -
-  /// SC     (PQ,Y)
-  /// SHS    -
-  /// SR     - 
-  /// TE     OZ, [YZ,OY,XY]
-  /// TR     - 
-  /// 
- /// \brief Status : pass - void TransformedTriangleIntersectTest::testTriangle8() - { - LOG(1, "+++++++ Testing triangle 8" ); - typedef TransformedTriangle TT; - - double coords[9] = - { - -0.75, 3.25, -1.5, // P - 0.25, 0.25, 0.5, // Q - -0.1, -0.4, 0.9 // R - }; - - TransformedTriangle* tri = new TransformedTriangle(&coords[0], &coords[3], &coords[6]); - - // run all intersection tests and ensure that the ones - // listed with yes in the tables above return true and - // that the ones listed with no or not listed at all return false - - bool isZero[TT::NO_TRI_SEGMENT * TT::NO_DP]; - - for(TriSegment seg = TT::PQ ; seg < TT::NO_TRI_SEGMENT ; seg = TT::TriSegment(seg + 1)) - { - // check beforehand which double-products are zero - for(DoubleProduct dp = TT::C_YZ; dp < TT::NO_DP; dp = DoubleProduct(dp + 1)) - { - isZero[TT::NO_DP*int(seg) + int(dp)] = (tri->calcStableC(seg, dp) == 0.0); - } - } - - // corner in tetrahedron (3 possibilities) - CPPUNIT_ASSERT_EQUAL(false, tri->testCornerInTetrahedron(TT::P)); - CPPUNIT_ASSERT_EQUAL(true , tri->testCornerInTetrahedron(TT::Q)); - CPPUNIT_ASSERT_EQUAL(false, tri->testCornerInTetrahedron(TT::R)); - - // corner on XYZ facet (3 possibilities) - CPPUNIT_ASSERT_EQUAL(false, tri->testCornerOnXYZFacet(TT::P)); - CPPUNIT_ASSERT_EQUAL(true , tri->testCornerOnXYZFacet(TT::Q)); - CPPUNIT_ASSERT_EQUAL(false, tri->testCornerOnXYZFacet(TT::R)); - - // corner above XYZ facet (3 possibilities) - CPPUNIT_ASSERT_EQUAL(false, tri->testCornerAboveXYZFacet(TT::P)); - CPPUNIT_ASSERT_EQUAL(false, tri->testCornerAboveXYZFacet(TT::Q)); - CPPUNIT_ASSERT_EQUAL(false, tri->testCornerAboveXYZFacet(TT::R)); - - // segment-facet (9 possibilities) - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::PQ, TT::OZX)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::PQ, TT::OYZ)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::PQ, TT::OXY)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::PQ, TT::XYZ)); - - CPPUNIT_ASSERT_EQUAL(true , tri->testSegmentFacetIntersection(TT::QR, TT::OZX)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::QR, TT::OYZ)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::QR, TT::OXY)); - CPPUNIT_ASSERT_EQUAL(true , tri->testSegmentFacetIntersection(TT::QR, TT::XYZ)); - - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::RP, TT::OZX)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::RP, TT::OYZ)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::RP, TT::OXY)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::RP, TT::XYZ)); - - // segment-edge (18 possibilities) - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::PQ, TT::OX) && tri->testSegmentEdgeIntersection(TT::PQ, TT::OX)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::PQ, TT::OY) && tri->testSegmentEdgeIntersection(TT::PQ, TT::OY)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::PQ, TT::OZ) && tri->testSegmentEdgeIntersection(TT::PQ, TT::OZ)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::PQ, TT::YZ) && tri->testSegmentEdgeIntersection(TT::PQ, TT::YZ)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::PQ, TT::ZX) && tri->testSegmentEdgeIntersection(TT::PQ, TT::ZX)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::PQ, TT::XY) && tri->testSegmentEdgeIntersection(TT::PQ, TT::XY)); - - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::QR, TT::OX) && tri->testSegmentEdgeIntersection(TT::QR, TT::OX)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::QR, TT::OY) && tri->testSegmentEdgeIntersection(TT::QR, TT::OY)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::QR, TT::OZ) && tri->testSegmentEdgeIntersection(TT::QR, TT::OZ)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::QR, TT::YZ) && tri->testSegmentEdgeIntersection(TT::QR, TT::YZ)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::QR, TT::ZX) && tri->testSegmentEdgeIntersection(TT::QR, TT::ZX)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::QR, TT::XY) && tri->testSegmentEdgeIntersection(TT::QR, TT::XY)); - - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::RP, TT::OX) && tri->testSegmentEdgeIntersection(TT::RP, TT::OX)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::RP, TT::OY) && tri->testSegmentEdgeIntersection(TT::RP, TT::OY)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::RP, TT::OZ) && tri->testSegmentEdgeIntersection(TT::RP, TT::OZ)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::RP, TT::YZ) && tri->testSegmentEdgeIntersection(TT::RP, TT::YZ)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::RP, TT::ZX) && tri->testSegmentEdgeIntersection(TT::RP, TT::ZX)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::RP, TT::XY) && tri->testSegmentEdgeIntersection(TT::RP, TT::XY)); - - // segment - corner (12 possibilities) - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::PQ, TT::O) && tri->testSegmentCornerIntersection(TT::PQ, TT::O)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::PQ, TT::X) && tri->testSegmentCornerIntersection(TT::PQ, TT::X)); - CPPUNIT_ASSERT_EQUAL(true , TEST_ZERO_DP_CORNER(TT::PQ, TT::Y) && tri->testSegmentCornerIntersection(TT::PQ, TT::Y)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::PQ, TT::Z) && tri->testSegmentCornerIntersection(TT::PQ, TT::Z)); - - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::QR, TT::O) && tri->testSegmentCornerIntersection(TT::QR, TT::O)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::QR, TT::X) && tri->testSegmentCornerIntersection(TT::QR, TT::X)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::QR, TT::Y) && tri->testSegmentCornerIntersection(TT::QR, TT::Y)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::QR, TT::Z) && tri->testSegmentCornerIntersection(TT::QR, TT::Z)); - - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::RP, TT::O) && tri->testSegmentCornerIntersection(TT::RP, TT::O)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::RP, TT::X) && tri->testSegmentCornerIntersection(TT::RP, TT::X)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::RP, TT::Y) && tri->testSegmentCornerIntersection(TT::RP, TT::Y)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::RP, TT::Z) && tri->testSegmentCornerIntersection(TT::RP, TT::Z)); - - // segment-halfstrip (9 possibilities) - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentHalfstripIntersection(TT::PQ, TT::YZ)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentHalfstripIntersection(TT::PQ, TT::ZX)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentHalfstripIntersection(TT::PQ, TT::XY)); - - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentHalfstripIntersection(TT::QR, TT::YZ)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentHalfstripIntersection(TT::QR, TT::ZX)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentHalfstripIntersection(TT::QR, TT::XY)); - - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentHalfstripIntersection(TT::RP, TT::YZ)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentHalfstripIntersection(TT::RP, TT::ZX)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentHalfstripIntersection(TT::RP, TT::XY)); - - // segment-ray (9 possibilities) - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_RAY(TT::PQ, TT::X) && tri->testSegmentRayIntersection(TT::PQ, TT::X)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_RAY(TT::PQ, TT::Y) && tri->testSegmentRayIntersection(TT::PQ, TT::Y)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_RAY(TT::PQ, TT::Z) && tri->testSegmentRayIntersection(TT::PQ, TT::Z)); - - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_RAY(TT::QR, TT::X) && tri->testSegmentRayIntersection(TT::QR, TT::X)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_RAY(TT::QR, TT::Y) && tri->testSegmentRayIntersection(TT::QR, TT::Y)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_RAY(TT::QR, TT::Z) && tri->testSegmentRayIntersection(TT::QR, TT::Z)); - - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_RAY(TT::RP, TT::X) && tri->testSegmentRayIntersection(TT::RP, TT::X)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_RAY(TT::RP, TT::Y) && tri->testSegmentRayIntersection(TT::RP, TT::Y)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_RAY(TT::RP, TT::Z) && tri->testSegmentRayIntersection(TT::RP, TT::Z)); - - // surface-edge (6 possibilities) - CPPUNIT_ASSERT_EQUAL(false, tri->testSurfaceEdgeIntersection(TT::OX)); - CPPUNIT_ASSERT_EQUAL(true , tri->testSurfaceEdgeIntersection(TT::OY)); - CPPUNIT_ASSERT_EQUAL(true , tri->testSurfaceEdgeIntersection(TT::OZ)); - CPPUNIT_ASSERT_EQUAL(true , tri->testSurfaceEdgeIntersection(TT::YZ)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSurfaceEdgeIntersection(TT::ZX)); - CPPUNIT_ASSERT_EQUAL(true , tri->testSurfaceEdgeIntersection(TT::XY)); - - // surface-ray (3 possibilities) - CPPUNIT_ASSERT_EQUAL(false, tri->testSurfaceRayIntersection(TT::X)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSurfaceRayIntersection(TT::Y)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSurfaceRayIntersection(TT::Z)); - - delete tri; - } - - /// Triangle 9 has the following intersections - ///
-  /// CI     [P]
-  /// COH    P
-  /// CAH    R
-  /// SF     (PQ, OZX), [(PQ, XYZ), (RP,XYZ)]
-  /// SE     (QR, ZX)
-  /// SC     -
-  /// SHS    -
-  /// SR     - 
-  /// TE     [ZX]
-  /// TR     - 
-  /// 
- /// \brief Status : pass - void TransformedTriangleIntersectTest::testTriangle9() - { - LOG(1, "+++++++ Testing triangle 9" ); - typedef TransformedTriangle TT; - - double coords[9] = - { - 0.6, 0.2, 0.2, // P - 0.3, -0.2, 0.8, // Q - 0.1, 0.2, 0.8 // R - }; - - TransformedTriangle* tri = new TransformedTriangle(&coords[0], &coords[3], &coords[6]); - - // run all intersection tests and ensure that the ones - // listed with yes in the tables above return true and - // that the ones listed with no or not listed at all return false - - bool isZero[TT::NO_TRI_SEGMENT * TT::NO_DP]; - - for(TriSegment seg = TT::PQ ; seg < TT::NO_TRI_SEGMENT ; seg = TT::TriSegment(seg + 1)) - { - // check beforehand which double-products are zero - for(DoubleProduct dp = TT::C_YZ; dp < TT::NO_DP; dp = DoubleProduct(dp + 1)) - { - isZero[TT::NO_DP*int(seg) + int(dp)] = (tri->calcStableC(seg, dp) == 0.0); - } - } - - // corner in tetrahedron (3 possibilities) - CPPUNIT_ASSERT_EQUAL(true , tri->testCornerInTetrahedron(TT::P)); - CPPUNIT_ASSERT_EQUAL(false, tri->testCornerInTetrahedron(TT::Q)); - CPPUNIT_ASSERT_EQUAL(false, tri->testCornerInTetrahedron(TT::R)); - - // corner on XYZ facet (3 possibilities) - CPPUNIT_ASSERT_EQUAL(true , tri->testCornerOnXYZFacet(TT::P)); - CPPUNIT_ASSERT_EQUAL(false, tri->testCornerOnXYZFacet(TT::Q)); - CPPUNIT_ASSERT_EQUAL(false, tri->testCornerOnXYZFacet(TT::R)); - - // corner above XYZ facet (3 possibilities) - CPPUNIT_ASSERT_EQUAL(false, tri->testCornerAboveXYZFacet(TT::P)); - CPPUNIT_ASSERT_EQUAL(false, tri->testCornerAboveXYZFacet(TT::Q)); - CPPUNIT_ASSERT_EQUAL(true , tri->testCornerAboveXYZFacet(TT::R)); - - // segment-facet (9 possibilities) - CPPUNIT_ASSERT_EQUAL(true , tri->testSegmentFacetIntersection(TT::PQ, TT::OZX)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::PQ, TT::OYZ)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::PQ, TT::OXY)); - CPPUNIT_ASSERT_EQUAL(true , tri->testSegmentFacetIntersection(TT::PQ, TT::XYZ)); - - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::QR, TT::OZX)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::QR, TT::OYZ)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::QR, TT::OXY)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::QR, TT::XYZ)); - - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::RP, TT::OZX)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::RP, TT::OYZ)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::RP, TT::OXY)); - CPPUNIT_ASSERT_EQUAL(true , tri->testSegmentFacetIntersection(TT::RP, TT::XYZ)); - - // segment-edge (18 possibilities) - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::PQ, TT::OX) && tri->testSegmentEdgeIntersection(TT::PQ, TT::OX)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::PQ, TT::OY) && tri->testSegmentEdgeIntersection(TT::PQ, TT::OY)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::PQ, TT::OZ) && tri->testSegmentEdgeIntersection(TT::PQ, TT::OZ)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::PQ, TT::YZ) && tri->testSegmentEdgeIntersection(TT::PQ, TT::YZ)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::PQ, TT::ZX) && tri->testSegmentEdgeIntersection(TT::PQ, TT::ZX)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::PQ, TT::XY) && tri->testSegmentEdgeIntersection(TT::PQ, TT::XY)); - - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::QR, TT::OX) && tri->testSegmentEdgeIntersection(TT::QR, TT::OX)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::QR, TT::OY) && tri->testSegmentEdgeIntersection(TT::QR, TT::OY)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::QR, TT::OZ) && tri->testSegmentEdgeIntersection(TT::QR, TT::OZ)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::QR, TT::YZ) && tri->testSegmentEdgeIntersection(TT::QR, TT::YZ)); - CPPUNIT_ASSERT_EQUAL(true , TEST_ZERO_DP_EDGE(TT::QR, TT::ZX) && tri->testSegmentEdgeIntersection(TT::QR, TT::ZX)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::QR, TT::XY) && tri->testSegmentEdgeIntersection(TT::QR, TT::XY)); - - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::RP, TT::OX) && tri->testSegmentEdgeIntersection(TT::RP, TT::OX)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::RP, TT::OY) && tri->testSegmentEdgeIntersection(TT::RP, TT::OY)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::RP, TT::OZ) && tri->testSegmentEdgeIntersection(TT::RP, TT::OZ)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::RP, TT::YZ) && tri->testSegmentEdgeIntersection(TT::RP, TT::YZ)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::RP, TT::ZX) && tri->testSegmentEdgeIntersection(TT::RP, TT::ZX)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::RP, TT::XY) && tri->testSegmentEdgeIntersection(TT::RP, TT::XY)); - - // segment - corner (12 possibilities) - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::PQ, TT::O) && tri->testSegmentCornerIntersection(TT::PQ, TT::O)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::PQ, TT::X) && tri->testSegmentCornerIntersection(TT::PQ, TT::X)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::PQ, TT::Y) && tri->testSegmentCornerIntersection(TT::PQ, TT::Y)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::PQ, TT::Z) && tri->testSegmentCornerIntersection(TT::PQ, TT::Z)); - - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::QR, TT::O) && tri->testSegmentCornerIntersection(TT::QR, TT::O)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::QR, TT::X) && tri->testSegmentCornerIntersection(TT::QR, TT::X)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::QR, TT::Y) && tri->testSegmentCornerIntersection(TT::QR, TT::Y)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::QR, TT::Z) && tri->testSegmentCornerIntersection(TT::QR, TT::Z)); - - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::RP, TT::O) && tri->testSegmentCornerIntersection(TT::RP, TT::O)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::RP, TT::X) && tri->testSegmentCornerIntersection(TT::RP, TT::X)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::RP, TT::Y) && tri->testSegmentCornerIntersection(TT::RP, TT::Y)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::RP, TT::Z) && tri->testSegmentCornerIntersection(TT::RP, TT::Z)); - - // segment-halfstrip (9 possibilities) - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentHalfstripIntersection(TT::PQ, TT::YZ)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentHalfstripIntersection(TT::PQ, TT::ZX)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentHalfstripIntersection(TT::PQ, TT::XY)); - - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentHalfstripIntersection(TT::QR, TT::YZ)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentHalfstripIntersection(TT::QR, TT::ZX)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentHalfstripIntersection(TT::QR, TT::XY)); - - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentHalfstripIntersection(TT::RP, TT::YZ)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentHalfstripIntersection(TT::RP, TT::ZX)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentHalfstripIntersection(TT::RP, TT::XY)); - - // segment-ray (9 possibilities) - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_RAY(TT::PQ, TT::X) && tri->testSegmentRayIntersection(TT::PQ, TT::X)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_RAY(TT::PQ, TT::Y) && tri->testSegmentRayIntersection(TT::PQ, TT::Y)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_RAY(TT::PQ, TT::Z) && tri->testSegmentRayIntersection(TT::PQ, TT::Z)); - - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_RAY(TT::QR, TT::X) && tri->testSegmentRayIntersection(TT::QR, TT::X)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_RAY(TT::QR, TT::Y) && tri->testSegmentRayIntersection(TT::QR, TT::Y)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_RAY(TT::QR, TT::Z) && tri->testSegmentRayIntersection(TT::QR, TT::Z)); - - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_RAY(TT::RP, TT::X) && tri->testSegmentRayIntersection(TT::RP, TT::X)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_RAY(TT::RP, TT::Y) && tri->testSegmentRayIntersection(TT::RP, TT::Y)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_RAY(TT::RP, TT::Z) && tri->testSegmentRayIntersection(TT::RP, TT::Z)); - - // surface-edge (6 possibilities) - CPPUNIT_ASSERT_EQUAL(false, tri->testSurfaceEdgeIntersection(TT::OX)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSurfaceEdgeIntersection(TT::OY)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSurfaceEdgeIntersection(TT::OZ)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSurfaceEdgeIntersection(TT::YZ)); - CPPUNIT_ASSERT_EQUAL(true , tri->testSurfaceEdgeIntersection(TT::ZX)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSurfaceEdgeIntersection(TT::XY)); - - // surface-ray (3 possibilities) - CPPUNIT_ASSERT_EQUAL(false, tri->testSurfaceRayIntersection(TT::X)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSurfaceRayIntersection(TT::Y)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSurfaceRayIntersection(TT::Z)); - - delete tri; - } - - - /// Triangle 10 has the following intersections - ///
-  /// CI     [R]
-  /// COH    R
-  /// CAH    Q
-  /// SF     (RP, OYZ), [ (RP, XYZ), (QR, XYZ) ]
-  /// SE     (PQ, YZ)
-  /// SC     -
-  /// SHS    -
-  /// SR     - 
-  /// TE     [YZ]
-  /// TR     - 
-  /// 
- /// \brief Status : pass - void TransformedTriangleIntersectTest::testTriangle10() - { - LOG(1, "+++++++ Testing triangle 10" ); - typedef TransformedTriangle TT; - - double coords[9] = - { - -0.1, 0.3, 0.6, // P - 0.1, 0.1, 1.0, // Q - 0.4, 0.3, 0.3 // R - }; - - TransformedTriangle* tri = new TransformedTriangle(&coords[0], &coords[3], &coords[6]); - - // run all intersection tests and ensure that the ones - // listed with yes in the tables above return true and - // that the ones listed with no or not listed at all return false - - bool isZero[TT::NO_TRI_SEGMENT * TT::NO_DP]; - - for(TriSegment seg = TT::PQ ; seg < TT::NO_TRI_SEGMENT ; seg = TT::TriSegment(seg + 1)) - { - // check beforehand which double-products are zero - for(DoubleProduct dp = TT::C_YZ; dp < TT::NO_DP; dp = DoubleProduct(dp + 1)) - { - isZero[TT::NO_DP*int(seg) + int(dp)] = (tri->calcStableC(seg, dp) == 0.0); - } - } - - // corner in tetrahedron (3 possibilities) - CPPUNIT_ASSERT_EQUAL(false, tri->testCornerInTetrahedron(TT::P)); - CPPUNIT_ASSERT_EQUAL(false, tri->testCornerInTetrahedron(TT::Q)); - CPPUNIT_ASSERT_EQUAL(true , tri->testCornerInTetrahedron(TT::R)); - - // corner on XYZ facet (3 possibilities) - CPPUNIT_ASSERT_EQUAL(false, tri->testCornerOnXYZFacet(TT::P)); - CPPUNIT_ASSERT_EQUAL(false, tri->testCornerOnXYZFacet(TT::Q)); - CPPUNIT_ASSERT_EQUAL(true , tri->testCornerOnXYZFacet(TT::R)); - - // corner above XYZ facet (3 possibilities) - CPPUNIT_ASSERT_EQUAL(false, tri->testCornerAboveXYZFacet(TT::P)); - CPPUNIT_ASSERT_EQUAL(true , tri->testCornerAboveXYZFacet(TT::Q)); - CPPUNIT_ASSERT_EQUAL(false, tri->testCornerAboveXYZFacet(TT::R)); - - // segment-facet (9 possibilities) - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::PQ, TT::OZX)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::PQ, TT::OYZ)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::PQ, TT::OXY)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::PQ, TT::XYZ)); - - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::QR, TT::OZX)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::QR, TT::OYZ)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::QR, TT::OXY)); - CPPUNIT_ASSERT_EQUAL(true , tri->testSegmentFacetIntersection(TT::QR, TT::XYZ)); - - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::RP, TT::OZX)); - CPPUNIT_ASSERT_EQUAL(true , tri->testSegmentFacetIntersection(TT::RP, TT::OYZ)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::RP, TT::OXY)); - CPPUNIT_ASSERT_EQUAL(true , tri->testSegmentFacetIntersection(TT::RP, TT::XYZ)); - - // segment-edge (18 possibilities) - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::PQ, TT::OX) && tri->testSegmentEdgeIntersection(TT::PQ, TT::OX)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::PQ, TT::OY) && tri->testSegmentEdgeIntersection(TT::PQ, TT::OY)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::PQ, TT::OZ) && tri->testSegmentEdgeIntersection(TT::PQ, TT::OZ)); - CPPUNIT_ASSERT_EQUAL(true , TEST_ZERO_DP_EDGE(TT::PQ, TT::YZ) && tri->testSegmentEdgeIntersection(TT::PQ, TT::YZ)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::PQ, TT::ZX) && tri->testSegmentEdgeIntersection(TT::PQ, TT::ZX)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::PQ, TT::XY) && tri->testSegmentEdgeIntersection(TT::PQ, TT::XY)); - - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::QR, TT::OX) && tri->testSegmentEdgeIntersection(TT::QR, TT::OX)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::QR, TT::OY) && tri->testSegmentEdgeIntersection(TT::QR, TT::OY)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::QR, TT::OZ) && tri->testSegmentEdgeIntersection(TT::QR, TT::OZ)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::QR, TT::YZ) && tri->testSegmentEdgeIntersection(TT::QR, TT::YZ)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::QR, TT::ZX) && tri->testSegmentEdgeIntersection(TT::QR, TT::ZX)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::QR, TT::XY) && tri->testSegmentEdgeIntersection(TT::QR, TT::XY)); - - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::RP, TT::OX) && tri->testSegmentEdgeIntersection(TT::RP, TT::OX)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::RP, TT::OY) && tri->testSegmentEdgeIntersection(TT::RP, TT::OY)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::RP, TT::OZ) && tri->testSegmentEdgeIntersection(TT::RP, TT::OZ)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::RP, TT::YZ) && tri->testSegmentEdgeIntersection(TT::RP, TT::YZ)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::RP, TT::ZX) && tri->testSegmentEdgeIntersection(TT::RP, TT::ZX)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::RP, TT::XY) && tri->testSegmentEdgeIntersection(TT::RP, TT::XY)); - - // segment - corner (12 possibilities) - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::PQ, TT::O) && tri->testSegmentCornerIntersection(TT::PQ, TT::O)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::PQ, TT::X) && tri->testSegmentCornerIntersection(TT::PQ, TT::X)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::PQ, TT::Y) && tri->testSegmentCornerIntersection(TT::PQ, TT::Y)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::PQ, TT::Z) && tri->testSegmentCornerIntersection(TT::PQ, TT::Z)); - - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::QR, TT::O) && tri->testSegmentCornerIntersection(TT::QR, TT::O)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::QR, TT::X) && tri->testSegmentCornerIntersection(TT::QR, TT::X)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::QR, TT::Y) && tri->testSegmentCornerIntersection(TT::QR, TT::Y)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::QR, TT::Z) && tri->testSegmentCornerIntersection(TT::QR, TT::Z)); - - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::RP, TT::O) && tri->testSegmentCornerIntersection(TT::RP, TT::O)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::RP, TT::X) && tri->testSegmentCornerIntersection(TT::RP, TT::X)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::RP, TT::Y) && tri->testSegmentCornerIntersection(TT::RP, TT::Y)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::RP, TT::Z) && tri->testSegmentCornerIntersection(TT::RP, TT::Z)); - - // segment-halfstrip (9 possibilities) - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentHalfstripIntersection(TT::PQ, TT::YZ)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentHalfstripIntersection(TT::PQ, TT::ZX)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentHalfstripIntersection(TT::PQ, TT::XY)); - - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentHalfstripIntersection(TT::QR, TT::YZ)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentHalfstripIntersection(TT::QR, TT::ZX)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentHalfstripIntersection(TT::QR, TT::XY)); - - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentHalfstripIntersection(TT::RP, TT::YZ)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentHalfstripIntersection(TT::RP, TT::ZX)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentHalfstripIntersection(TT::RP, TT::XY)); - - // segment-ray (9 possibilities) - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_RAY(TT::PQ, TT::X) && tri->testSegmentRayIntersection(TT::PQ, TT::X)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_RAY(TT::PQ, TT::Y) && tri->testSegmentRayIntersection(TT::PQ, TT::Y)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_RAY(TT::PQ, TT::Z) && tri->testSegmentRayIntersection(TT::PQ, TT::Z)); - - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_RAY(TT::QR, TT::X) && tri->testSegmentRayIntersection(TT::QR, TT::X)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_RAY(TT::QR, TT::Y) && tri->testSegmentRayIntersection(TT::QR, TT::Y)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_RAY(TT::QR, TT::Z) && tri->testSegmentRayIntersection(TT::QR, TT::Z)); - - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_RAY(TT::RP, TT::X) && tri->testSegmentRayIntersection(TT::RP, TT::X)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_RAY(TT::RP, TT::Y) && tri->testSegmentRayIntersection(TT::RP, TT::Y)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_RAY(TT::RP, TT::Z) && tri->testSegmentRayIntersection(TT::RP, TT::Z)); - - // surface-edge (6 possibilities) - CPPUNIT_ASSERT_EQUAL(false, tri->testSurfaceEdgeIntersection(TT::OX)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSurfaceEdgeIntersection(TT::OY)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSurfaceEdgeIntersection(TT::OZ)); - CPPUNIT_ASSERT_EQUAL(true , tri->testSurfaceEdgeIntersection(TT::YZ)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSurfaceEdgeIntersection(TT::ZX)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSurfaceEdgeIntersection(TT::XY)); - - // surface-ray (3 possibilities) - CPPUNIT_ASSERT_EQUAL(false, tri->testSurfaceRayIntersection(TT::X)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSurfaceRayIntersection(TT::Y)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSurfaceRayIntersection(TT::Z)); - - delete tri; - } - - /// Triangle 11 has the following intersections - ///
-  /// CI     Q, R
-  /// COH    -
-  /// CAH    -
-  /// SF     -
-  /// SE     (PQ, OX)
-  /// SC     (RP, O)
-  /// SHS    -
-  /// SR     - 
-  /// TE     [OY, OZ]
-  /// TR     - 
-  /// 
- /// \brief Status : pass - void TransformedTriangleIntersectTest::testTriangle11() - { - LOG(1, "+++++++ Testing triangle 11" ); - typedef TransformedTriangle TT; - - double coords[9] = - { - -0.2, -0.2, -0.2, // P - 0.2, 0.1, 0.1, // Q - 0.3, 0.3, 0.3 // R - }; - - TransformedTriangle* tri = new TransformedTriangle(&coords[0], &coords[3], &coords[6]); - - // run all intersection tests and ensure that the ones - // listed with yes in the tables above return true and - // that the ones listed with no or not listed at all return false - - bool isZero[TT::NO_TRI_SEGMENT * TT::NO_DP]; - - for(TriSegment seg = TT::PQ ; seg < TT::NO_TRI_SEGMENT ; seg = TT::TriSegment(seg + 1)) - { - // check beforehand which double-products are zero - for(DoubleProduct dp = TT::C_YZ; dp < TT::NO_DP; dp = DoubleProduct(dp + 1)) - { - isZero[TT::NO_DP*int(seg) + int(dp)] = (tri->calcStableC(seg, dp) == 0.0); - } - } - - // corner in tetrahedron (3 possibilities) - CPPUNIT_ASSERT_EQUAL(false, tri->testCornerInTetrahedron(TT::P)); - CPPUNIT_ASSERT_EQUAL(true , tri->testCornerInTetrahedron(TT::Q)); - CPPUNIT_ASSERT_EQUAL(true , tri->testCornerInTetrahedron(TT::R)); - - // corner on XYZ facet (3 possibilities) - CPPUNIT_ASSERT_EQUAL(false, tri->testCornerOnXYZFacet(TT::P)); - CPPUNIT_ASSERT_EQUAL(false, tri->testCornerOnXYZFacet(TT::Q)); - CPPUNIT_ASSERT_EQUAL(false, tri->testCornerOnXYZFacet(TT::R)); - - // corner above XYZ facet (3 possibilities) - CPPUNIT_ASSERT_EQUAL(false, tri->testCornerAboveXYZFacet(TT::P)); - CPPUNIT_ASSERT_EQUAL(false, tri->testCornerAboveXYZFacet(TT::Q)); - CPPUNIT_ASSERT_EQUAL(false, tri->testCornerAboveXYZFacet(TT::R)); - - // segment-facet (9 possibilities) - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::PQ, TT::OZX)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::PQ, TT::OYZ)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::PQ, TT::OXY)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::PQ, TT::XYZ)); - - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::QR, TT::OZX)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::QR, TT::OYZ)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::QR, TT::OXY)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::QR, TT::XYZ)); - - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::RP, TT::OZX)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::RP, TT::OYZ)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::RP, TT::OXY)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::RP, TT::XYZ)); - - // segment-edge (18 possibilities) - CPPUNIT_ASSERT_EQUAL(true , TEST_ZERO_DP_EDGE(TT::PQ, TT::OX) && tri->testSegmentEdgeIntersection(TT::PQ, TT::OX)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::PQ, TT::OY) && tri->testSegmentEdgeIntersection(TT::PQ, TT::OY)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::PQ, TT::OZ) && tri->testSegmentEdgeIntersection(TT::PQ, TT::OZ)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::PQ, TT::YZ) && tri->testSegmentEdgeIntersection(TT::PQ, TT::YZ)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::PQ, TT::ZX) && tri->testSegmentEdgeIntersection(TT::PQ, TT::ZX)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::PQ, TT::XY) && tri->testSegmentEdgeIntersection(TT::PQ, TT::XY)); - - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::QR, TT::OX) && tri->testSegmentEdgeIntersection(TT::QR, TT::OX)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::QR, TT::OY) && tri->testSegmentEdgeIntersection(TT::QR, TT::OY)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::QR, TT::OZ) && tri->testSegmentEdgeIntersection(TT::QR, TT::OZ)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::QR, TT::YZ) && tri->testSegmentEdgeIntersection(TT::QR, TT::YZ)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::QR, TT::ZX) && tri->testSegmentEdgeIntersection(TT::QR, TT::ZX)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::QR, TT::XY) && tri->testSegmentEdgeIntersection(TT::QR, TT::XY)); - - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::RP, TT::OX) && tri->testSegmentEdgeIntersection(TT::RP, TT::OX)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::RP, TT::OY) && tri->testSegmentEdgeIntersection(TT::RP, TT::OY)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::RP, TT::OZ) && tri->testSegmentEdgeIntersection(TT::RP, TT::OZ)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::RP, TT::YZ) && tri->testSegmentEdgeIntersection(TT::RP, TT::YZ)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::RP, TT::ZX) && tri->testSegmentEdgeIntersection(TT::RP, TT::ZX)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::RP, TT::XY) && tri->testSegmentEdgeIntersection(TT::RP, TT::XY)); - - // segment - corner (12 possibilities) - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::PQ, TT::O) && tri->testSegmentCornerIntersection(TT::PQ, TT::O)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::PQ, TT::X) && tri->testSegmentCornerIntersection(TT::PQ, TT::X)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::PQ, TT::Y) && tri->testSegmentCornerIntersection(TT::PQ, TT::Y)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::PQ, TT::Z) && tri->testSegmentCornerIntersection(TT::PQ, TT::Z)); - - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::QR, TT::O) && tri->testSegmentCornerIntersection(TT::QR, TT::O)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::QR, TT::X) && tri->testSegmentCornerIntersection(TT::QR, TT::X)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::QR, TT::Y) && tri->testSegmentCornerIntersection(TT::QR, TT::Y)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::QR, TT::Z) && tri->testSegmentCornerIntersection(TT::QR, TT::Z)); - - CPPUNIT_ASSERT_EQUAL(true , TEST_ZERO_DP_CORNER(TT::RP, TT::O) && tri->testSegmentCornerIntersection(TT::RP, TT::O)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::RP, TT::X) && tri->testSegmentCornerIntersection(TT::RP, TT::X)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::RP, TT::Y) && tri->testSegmentCornerIntersection(TT::RP, TT::Y)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::RP, TT::Z) && tri->testSegmentCornerIntersection(TT::RP, TT::Z)); - - // segment-halfstrip (9 possibilities) - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentHalfstripIntersection(TT::PQ, TT::YZ)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentHalfstripIntersection(TT::PQ, TT::ZX)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentHalfstripIntersection(TT::PQ, TT::XY)); - - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentHalfstripIntersection(TT::QR, TT::YZ)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentHalfstripIntersection(TT::QR, TT::ZX)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentHalfstripIntersection(TT::QR, TT::XY)); - - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentHalfstripIntersection(TT::RP, TT::YZ)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentHalfstripIntersection(TT::RP, TT::ZX)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentHalfstripIntersection(TT::RP, TT::XY)); - - // segment-ray (9 possibilities) - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_RAY(TT::PQ, TT::X) && tri->testSegmentRayIntersection(TT::PQ, TT::X)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_RAY(TT::PQ, TT::Y) && tri->testSegmentRayIntersection(TT::PQ, TT::Y)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_RAY(TT::PQ, TT::Z) && tri->testSegmentRayIntersection(TT::PQ, TT::Z)); - - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_RAY(TT::QR, TT::X) && tri->testSegmentRayIntersection(TT::QR, TT::X)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_RAY(TT::QR, TT::Y) && tri->testSegmentRayIntersection(TT::QR, TT::Y)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_RAY(TT::QR, TT::Z) && tri->testSegmentRayIntersection(TT::QR, TT::Z)); - - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_RAY(TT::RP, TT::X) && tri->testSegmentRayIntersection(TT::RP, TT::X)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_RAY(TT::RP, TT::Y) && tri->testSegmentRayIntersection(TT::RP, TT::Y)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_RAY(TT::RP, TT::Z) && tri->testSegmentRayIntersection(TT::RP, TT::Z)); - - // surface-edge (6 possibilities) - CPPUNIT_ASSERT_EQUAL(false, tri->testSurfaceEdgeIntersection(TT::OX)); - CPPUNIT_ASSERT_EQUAL(true , tri->testSurfaceEdgeIntersection(TT::OY)); - CPPUNIT_ASSERT_EQUAL(true, tri->testSurfaceEdgeIntersection(TT::OZ)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSurfaceEdgeIntersection(TT::YZ)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSurfaceEdgeIntersection(TT::ZX)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSurfaceEdgeIntersection(TT::XY)); - - // surface-ray (3 possibilities) - CPPUNIT_ASSERT_EQUAL(false, tri->testSurfaceRayIntersection(TT::X)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSurfaceRayIntersection(TT::Y)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSurfaceRayIntersection(TT::Z)); - - delete tri; - } - - - /// Triangle 12 has the following intersections - ///
-  /// CI     -
-  /// COH    -
-  /// CAH    -
-  /// SF     (QR, OXY), (QR, OZX)
-  /// SE     (RP, OY), (PQ, OZ)
-  /// SC     -
-  /// SHS    -
-  /// SR     - 
-  /// TE     [OY], [OZ]
-  /// TR     - 
-  /// 
- /// \brief Status : pass - void TransformedTriangleIntersectTest::testTriangle12() - { - LOG(1, "+++++++ Testing triangle 12" ); - typedef TransformedTriangle TT; - - double coords[9] = - { - -0.2, 0.2, 0.2, // P - 0.2, -0.2, 0.3, // Q - 0.6, 0.6, -0.6 // R - }; - - TransformedTriangle* tri = new TransformedTriangle(&coords[0], &coords[3], &coords[6]); - - // run all intersection tests and ensure that the ones - // listed with yes in the tables above return true and - // that the ones listed with no or not listed at all return false - - bool isZero[TT::NO_TRI_SEGMENT * TT::NO_DP]; - - for(TriSegment seg = TT::PQ ; seg < TT::NO_TRI_SEGMENT ; seg = TT::TriSegment(seg + 1)) - { - // check beforehand which double-products are zero - for(DoubleProduct dp = TT::C_YZ; dp < TT::NO_DP; dp = DoubleProduct(dp + 1)) - { - isZero[TT::NO_DP*int(seg) + int(dp)] = (tri->calcStableC(seg, dp) == 0.0); - } - } - - // corner in tetrahedron (3 possibilities) - CPPUNIT_ASSERT_EQUAL(false, tri->testCornerInTetrahedron(TT::P)); - CPPUNIT_ASSERT_EQUAL(false, tri->testCornerInTetrahedron(TT::Q)); - CPPUNIT_ASSERT_EQUAL(false, tri->testCornerInTetrahedron(TT::R)); - - // corner on XYZ facet (3 possibilities) - CPPUNIT_ASSERT_EQUAL(false, tri->testCornerOnXYZFacet(TT::P)); - CPPUNIT_ASSERT_EQUAL(false, tri->testCornerOnXYZFacet(TT::Q)); - CPPUNIT_ASSERT_EQUAL(false, tri->testCornerOnXYZFacet(TT::R)); - - // corner above XYZ facet (3 possibilities) - CPPUNIT_ASSERT_EQUAL(false, tri->testCornerAboveXYZFacet(TT::P)); - CPPUNIT_ASSERT_EQUAL(false, tri->testCornerAboveXYZFacet(TT::Q)); - CPPUNIT_ASSERT_EQUAL(false, tri->testCornerAboveXYZFacet(TT::R)); - - // segment-facet (9 possibilities) - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::PQ, TT::OZX)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::PQ, TT::OYZ)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::PQ, TT::OXY)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::PQ, TT::XYZ)); - - CPPUNIT_ASSERT_EQUAL(true , tri->testSegmentFacetIntersection(TT::QR, TT::OZX)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::QR, TT::OYZ)); - CPPUNIT_ASSERT_EQUAL(true , tri->testSegmentFacetIntersection(TT::QR, TT::OXY)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::QR, TT::XYZ)); - - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::RP, TT::OZX)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::RP, TT::OYZ)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::RP, TT::OXY)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::RP, TT::XYZ)); - // segment-edge (18 possibilities) - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::PQ, TT::OX) && tri->testSegmentEdgeIntersection(TT::PQ, TT::OX)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::PQ, TT::OY) && tri->testSegmentEdgeIntersection(TT::PQ, TT::OY)); - CPPUNIT_ASSERT_EQUAL(true , TEST_ZERO_DP_EDGE(TT::PQ, TT::OZ) && tri->testSegmentEdgeIntersection(TT::PQ, TT::OZ)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::PQ, TT::YZ) && tri->testSegmentEdgeIntersection(TT::PQ, TT::YZ)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::PQ, TT::ZX) && tri->testSegmentEdgeIntersection(TT::PQ, TT::ZX)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::PQ, TT::XY) && tri->testSegmentEdgeIntersection(TT::PQ, TT::XY)); - - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::QR, TT::OX) && tri->testSegmentEdgeIntersection(TT::QR, TT::OX)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::QR, TT::OY) && tri->testSegmentEdgeIntersection(TT::QR, TT::OY)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::QR, TT::OZ) && tri->testSegmentEdgeIntersection(TT::QR, TT::OZ)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::QR, TT::YZ) && tri->testSegmentEdgeIntersection(TT::QR, TT::YZ)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::QR, TT::ZX) && tri->testSegmentEdgeIntersection(TT::QR, TT::ZX)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::QR, TT::XY) && tri->testSegmentEdgeIntersection(TT::QR, TT::XY)); - - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::RP, TT::OX) && tri->testSegmentEdgeIntersection(TT::RP, TT::OX)); - CPPUNIT_ASSERT_EQUAL(true , TEST_ZERO_DP_EDGE(TT::RP, TT::OY) && tri->testSegmentEdgeIntersection(TT::RP, TT::OY)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::RP, TT::OZ) && tri->testSegmentEdgeIntersection(TT::RP, TT::OZ)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::RP, TT::YZ) && tri->testSegmentEdgeIntersection(TT::RP, TT::YZ)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::RP, TT::ZX) && tri->testSegmentEdgeIntersection(TT::RP, TT::ZX)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::RP, TT::XY) && tri->testSegmentEdgeIntersection(TT::RP, TT::XY)); - - // segment - corner (12 possibilities) - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::PQ, TT::O) && tri->testSegmentCornerIntersection(TT::PQ, TT::O)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::PQ, TT::X) && tri->testSegmentCornerIntersection(TT::PQ, TT::X)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::PQ, TT::Y) && tri->testSegmentCornerIntersection(TT::PQ, TT::Y)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::PQ, TT::Z) && tri->testSegmentCornerIntersection(TT::PQ, TT::Z)); - - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::QR, TT::O) && tri->testSegmentCornerIntersection(TT::QR, TT::O)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::QR, TT::X) && tri->testSegmentCornerIntersection(TT::QR, TT::X)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::QR, TT::Y) && tri->testSegmentCornerIntersection(TT::QR, TT::Y)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::QR, TT::Z) && tri->testSegmentCornerIntersection(TT::QR, TT::Z)); - - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::RP, TT::O) && tri->testSegmentCornerIntersection(TT::RP, TT::O)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::RP, TT::X) && tri->testSegmentCornerIntersection(TT::RP, TT::X)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::RP, TT::Y) && tri->testSegmentCornerIntersection(TT::RP, TT::Y)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::RP, TT::Z) && tri->testSegmentCornerIntersection(TT::RP, TT::Z)); - - // segment-halfstrip (9 possibilities) - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentHalfstripIntersection(TT::PQ, TT::YZ)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentHalfstripIntersection(TT::PQ, TT::ZX)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentHalfstripIntersection(TT::PQ, TT::XY)); - - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentHalfstripIntersection(TT::QR, TT::YZ)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentHalfstripIntersection(TT::QR, TT::ZX)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentHalfstripIntersection(TT::QR, TT::XY)); - - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentHalfstripIntersection(TT::RP, TT::YZ)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentHalfstripIntersection(TT::RP, TT::ZX)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentHalfstripIntersection(TT::RP, TT::XY)); - - // segment-ray (9 possibilities) - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_RAY(TT::PQ, TT::X) && tri->testSegmentRayIntersection(TT::PQ, TT::X)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_RAY(TT::PQ, TT::Y) && tri->testSegmentRayIntersection(TT::PQ, TT::Y)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_RAY(TT::PQ, TT::Z) && tri->testSegmentRayIntersection(TT::PQ, TT::Z)); - - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_RAY(TT::QR, TT::X) && tri->testSegmentRayIntersection(TT::QR, TT::X)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_RAY(TT::QR, TT::Y) && tri->testSegmentRayIntersection(TT::QR, TT::Y)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_RAY(TT::QR, TT::Z) && tri->testSegmentRayIntersection(TT::QR, TT::Z)); - - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_RAY(TT::RP, TT::X) && tri->testSegmentRayIntersection(TT::RP, TT::X)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_RAY(TT::RP, TT::Y) && tri->testSegmentRayIntersection(TT::RP, TT::Y)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_RAY(TT::RP, TT::Z) && tri->testSegmentRayIntersection(TT::RP, TT::Z)); - - // surface-edge (6 possibilities) - CPPUNIT_ASSERT_EQUAL(false, tri->testSurfaceEdgeIntersection(TT::OX)); - CPPUNIT_ASSERT_EQUAL(true , tri->testSurfaceEdgeIntersection(TT::OY)); - CPPUNIT_ASSERT_EQUAL(true , tri->testSurfaceEdgeIntersection(TT::OZ)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSurfaceEdgeIntersection(TT::YZ)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSurfaceEdgeIntersection(TT::ZX)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSurfaceEdgeIntersection(TT::XY)); - - // surface-ray (3 possibilities) - CPPUNIT_ASSERT_EQUAL(false, tri->testSurfaceRayIntersection(TT::X)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSurfaceRayIntersection(TT::Y)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSurfaceRayIntersection(TT::Z)); - - delete tri; - } - - - /// Triangle 13 has the following intersections - ///
-  /// CI     -
-  /// COH    -
-  /// CAH    -
-  /// SF     (QR, OYZ), (PQ, OXY), (PQ, XYZ)
-  /// SE     -
-  /// SC     (QR, Z)
-  /// SHS    (PQ, YZ)
-  /// SR     - 
-  /// TE     [OZ, YZ, ZX]
-  /// TR     - 
-  /// 
- /// \brief Status : pass - void TransformedTriangleIntersectTest::testTriangle13() - { - LOG(1, "+++++++ Testing triangle 13" ); - typedef TransformedTriangle TT; - - double coords[9] = - { - -0.2, 0.3, 5.0, // P - 0.2, 0.1, -1.0, // Q - -0.2, -0.1, 3.0 // R - }; - - TransformedTriangle* tri = new TransformedTriangle(&coords[0], &coords[3], &coords[6]); - - // run all intersection tests and ensure that the ones - // listed with yes in the tables above return true and - // that the ones listed with no or not listed at all return false - - bool isZero[TT::NO_TRI_SEGMENT * TT::NO_DP]; - - for(TriSegment seg = TT::PQ ; seg < TT::NO_TRI_SEGMENT ; seg = TT::TriSegment(seg + 1)) - { - // check beforehand which double-products are zero - for(DoubleProduct dp = TT::C_YZ; dp < TT::NO_DP; dp = DoubleProduct(dp + 1)) - { - isZero[TT::NO_DP*int(seg) + int(dp)] = (tri->calcStableC(seg, dp) == 0.0); - } - } - - // corner in tetrahedron (3 possibilities) - CPPUNIT_ASSERT_EQUAL(false, tri->testCornerInTetrahedron(TT::P)); - CPPUNIT_ASSERT_EQUAL(false, tri->testCornerInTetrahedron(TT::Q)); - CPPUNIT_ASSERT_EQUAL(false, tri->testCornerInTetrahedron(TT::R)); - - // corner on XYZ facet (3 possibilities) - CPPUNIT_ASSERT_EQUAL(false, tri->testCornerOnXYZFacet(TT::P)); - CPPUNIT_ASSERT_EQUAL(false, tri->testCornerOnXYZFacet(TT::Q)); - CPPUNIT_ASSERT_EQUAL(false, tri->testCornerOnXYZFacet(TT::R)); - - // corner above XYZ facet (3 possibilities) - CPPUNIT_ASSERT_EQUAL(false, tri->testCornerAboveXYZFacet(TT::P)); - CPPUNIT_ASSERT_EQUAL(false, tri->testCornerAboveXYZFacet(TT::Q)); - CPPUNIT_ASSERT_EQUAL(false, tri->testCornerAboveXYZFacet(TT::R)); - - // segment-facet (9 possibilities) - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::PQ, TT::OZX)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::PQ, TT::OYZ)); - CPPUNIT_ASSERT_EQUAL(true , tri->testSegmentFacetIntersection(TT::PQ, TT::OXY)); - CPPUNIT_ASSERT_EQUAL(true , tri->testSegmentFacetIntersection(TT::PQ, TT::XYZ)); - - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::QR, TT::OZX)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::QR, TT::OYZ)); - CPPUNIT_ASSERT_EQUAL(true , tri->testSegmentFacetIntersection(TT::QR, TT::OXY)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::QR, TT::XYZ)); - - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::RP, TT::OZX)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::RP, TT::OYZ)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::RP, TT::OXY)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::RP, TT::XYZ)); - - // segment-edge (18 possibilities) - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::PQ, TT::OX) && tri->testSegmentEdgeIntersection(TT::PQ, TT::OX)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::PQ, TT::OY) && tri->testSegmentEdgeIntersection(TT::PQ, TT::OY)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::PQ, TT::OZ) && tri->testSegmentEdgeIntersection(TT::PQ, TT::OZ)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::PQ, TT::YZ) && tri->testSegmentEdgeIntersection(TT::PQ, TT::YZ)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::PQ, TT::ZX) && tri->testSegmentEdgeIntersection(TT::PQ, TT::ZX)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::PQ, TT::XY) && tri->testSegmentEdgeIntersection(TT::PQ, TT::XY)); - - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::QR, TT::OX) && tri->testSegmentEdgeIntersection(TT::QR, TT::OX)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::QR, TT::OY) && tri->testSegmentEdgeIntersection(TT::QR, TT::OY)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::QR, TT::OZ) && tri->testSegmentEdgeIntersection(TT::QR, TT::OZ)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::QR, TT::YZ) && tri->testSegmentEdgeIntersection(TT::QR, TT::YZ)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::QR, TT::ZX) && tri->testSegmentEdgeIntersection(TT::QR, TT::ZX)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::QR, TT::XY) && tri->testSegmentEdgeIntersection(TT::QR, TT::XY)); - - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::RP, TT::OX) && tri->testSegmentEdgeIntersection(TT::RP, TT::OX)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::RP, TT::OY) && tri->testSegmentEdgeIntersection(TT::RP, TT::OY)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::RP, TT::OZ) && tri->testSegmentEdgeIntersection(TT::RP, TT::OZ)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::RP, TT::YZ) && tri->testSegmentEdgeIntersection(TT::RP, TT::YZ)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::RP, TT::ZX) && tri->testSegmentEdgeIntersection(TT::RP, TT::ZX)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::RP, TT::XY) && tri->testSegmentEdgeIntersection(TT::RP, TT::XY)); - - // segment - corner (12 possibilities) - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::PQ, TT::O) && tri->testSegmentCornerIntersection(TT::PQ, TT::O)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::PQ, TT::X) && tri->testSegmentCornerIntersection(TT::PQ, TT::X)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::PQ, TT::Y) && tri->testSegmentCornerIntersection(TT::PQ, TT::Y)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::PQ, TT::Z) && tri->testSegmentCornerIntersection(TT::PQ, TT::Z)); - - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::QR, TT::O) && tri->testSegmentCornerIntersection(TT::QR, TT::O)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::QR, TT::X) && tri->testSegmentCornerIntersection(TT::QR, TT::X)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::QR, TT::Y) && tri->testSegmentCornerIntersection(TT::QR, TT::Y)); - CPPUNIT_ASSERT_EQUAL(true , TEST_ZERO_DP_CORNER(TT::QR, TT::Z) && tri->testSegmentCornerIntersection(TT::QR, TT::Z)); - - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::RP, TT::O) && tri->testSegmentCornerIntersection(TT::RP, TT::O)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::RP, TT::X) && tri->testSegmentCornerIntersection(TT::RP, TT::X)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::RP, TT::Y) && tri->testSegmentCornerIntersection(TT::RP, TT::Y)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::RP, TT::Z) && tri->testSegmentCornerIntersection(TT::RP, TT::Z)); - - // segment-halfstrip (9 possibilities) - CPPUNIT_ASSERT_EQUAL(true , tri->testSegmentHalfstripIntersection(TT::PQ, TT::YZ)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentHalfstripIntersection(TT::PQ, TT::ZX)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentHalfstripIntersection(TT::PQ, TT::XY)); - - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentHalfstripIntersection(TT::QR, TT::YZ)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentHalfstripIntersection(TT::QR, TT::ZX)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentHalfstripIntersection(TT::QR, TT::XY)); - - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentHalfstripIntersection(TT::RP, TT::YZ)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentHalfstripIntersection(TT::RP, TT::ZX)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentHalfstripIntersection(TT::RP, TT::XY)); - - // segment-ray (9 possibilities) - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_RAY(TT::PQ, TT::X) && tri->testSegmentRayIntersection(TT::PQ, TT::X)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_RAY(TT::PQ, TT::Y) && tri->testSegmentRayIntersection(TT::PQ, TT::Y)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_RAY(TT::PQ, TT::Z) && tri->testSegmentRayIntersection(TT::PQ, TT::Z)); - - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_RAY(TT::QR, TT::X) && tri->testSegmentRayIntersection(TT::QR, TT::X)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_RAY(TT::QR, TT::Y) && tri->testSegmentRayIntersection(TT::QR, TT::Y)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_RAY(TT::QR, TT::Z) && tri->testSegmentRayIntersection(TT::QR, TT::Z)); - - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_RAY(TT::RP, TT::X) && tri->testSegmentRayIntersection(TT::RP, TT::X)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_RAY(TT::RP, TT::Y) && tri->testSegmentRayIntersection(TT::RP, TT::Y)); - CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_RAY(TT::RP, TT::Z) && tri->testSegmentRayIntersection(TT::RP, TT::Z)); - - // surface-edge (6 possibilities) - CPPUNIT_ASSERT_EQUAL(false, tri->testSurfaceEdgeIntersection(TT::OX)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSurfaceEdgeIntersection(TT::OY)); - CPPUNIT_ASSERT_EQUAL(true , tri->testSurfaceEdgeIntersection(TT::OZ)); - CPPUNIT_ASSERT_EQUAL(true , tri->testSurfaceEdgeIntersection(TT::YZ)); - CPPUNIT_ASSERT_EQUAL(true , tri->testSurfaceEdgeIntersection(TT::ZX)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSurfaceEdgeIntersection(TT::XY)); - - // surface-ray (3 possibilities) - CPPUNIT_ASSERT_EQUAL(false, tri->testSurfaceRayIntersection(TT::X)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSurfaceRayIntersection(TT::Y)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSurfaceRayIntersection(TT::Z)); - - delete tri; - } - - -} // NAMESPACE - - - - - - - -///// TEMPLATE /////////////////////////////// - - - -#if 0 -// Triangle x has the following intersections -// CI - -// COH - -// CAH - -// SF - -// SE - -// SC - -// SHS - -// SR - -// TE - -// TR - - -void TransformedTriangleIntersectTest::testTriangleX() -{ - LOG(1, "+++++++ Testing triangle X" ); - typedef TransformedTriangle TT; - - double coords[9] = - { - 0.0, 0.0, 0.0, // P - 0.0, 0.0, 0.0, // Q - 0.0, 0.0, 0.0 // R - }; - - TransformedTriangle* tri = new TransformedTriangle(&coords[0], &coords[3], &coords[6]); - - // run all intersection tests and ensure that the ones - // listed with yes in the tables above return true and - // that the ones listed with no or not listed at all return false - - // corner in tetrahedron (3 possibilities) - CPPUNIT_ASSERT_EQUAL(false, tri->testCornerInTetrahedron(TT::P)); - CPPUNIT_ASSERT_EQUAL(false, tri->testCornerInTetrahedron(TT::Q)); - CPPUNIT_ASSERT_EQUAL(false, tri->testCornerInTetrahedron(TT::R)); - - // corner on XYZ facet (3 possibilities) - CPPUNIT_ASSERT_EQUAL(false, tri->testCornerOnXYZFacet(TT::P)); - CPPUNIT_ASSERT_EQUAL(false, tri->testCornerOnXYZFacet(TT::Q)); - CPPUNIT_ASSERT_EQUAL(false, tri->testCornerOnXYZFacet(TT::R)); - - // corner above XYZ facet (3 possibilities) - CPPUNIT_ASSERT_EQUAL(false, tri->testCornerAboveXYZFacet(TT::P)); - CPPUNIT_ASSERT_EQUAL(false, tri->testCornerAboveXYZFacet(TT::Q)); - CPPUNIT_ASSERT_EQUAL(false, tri->testCornerAboveXYZFacet(TT::R)); - - // segment-facet (9 possibilities) - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::PQ, TT::OZX)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::PQ, TT::OYZ)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::PQ, TT::OXY)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::PQ, TT::XYZ)); - - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::QR, TT::OZX)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::QR, TT::OYZ)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::QR, TT::OXY)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::QR, TT::XYZ)); - - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::RP, TT::OZX)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::RP, TT::OYZ)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::RP, TT::OXY)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::RP, TT::XYZ)); - - // segment-edge (18 possibilities) - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentEdgeIntersection(TT::PQ, TT::OX)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentEdgeIntersection(TT::PQ, TT::OY)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentEdgeIntersection(TT::PQ, TT::OZ)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentEdgeIntersection(TT::PQ, TT::YZ)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentEdgeIntersection(TT::PQ, TT::ZX)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentEdgeIntersection(TT::PQ, TT::XY)); - - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentEdgeIntersection(TT::QR, TT::OX)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentEdgeIntersection(TT::QR, TT::OY)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentEdgeIntersection(TT::QR, TT::OZ)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentEdgeIntersection(TT::QR, TT::YZ)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentEdgeIntersection(TT::QR, TT::ZX)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentEdgeIntersection(TT::QR, TT::XY)); - - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentEdgeIntersection(TT::RP, TT::OX)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentEdgeIntersection(TT::RP, TT::OY)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentEdgeIntersection(TT::RP, TT::OZ)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentEdgeIntersection(TT::RP, TT::YZ)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentEdgeIntersection(TT::RP, TT::ZX)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentEdgeIntersection(TT::RP, TT::XY)); - - // segment - corner (12 possibilities) - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentCornerIntersection(TT::PQ, TT::O)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentCornerIntersection(TT::PQ, TT::X)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentCornerIntersection(TT::PQ, TT::Y)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentCornerIntersection(TT::PQ, TT::Z)); - - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentCornerIntersection(TT::QR, TT::O)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentCornerIntersection(TT::QR, TT::X)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentCornerIntersection(TT::QR, TT::Y)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentCornerIntersection(TT::QR, TT::Z)); - - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentCornerIntersection(TT::RP, TT::O)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentCornerIntersection(TT::RP, TT::X)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentCornerIntersection(TT::RP, TT::Y)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentCornerIntersection(TT::RP, TT::Z)); - - // segment-halfstrip (9 possibilities) - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentHalfstripIntersection(TT::PQ, TT::YZ)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentHalfstripIntersection(TT::PQ, TT::ZX)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentHalfstripIntersection(TT::PQ, TT::XY)); - - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentHalfstripIntersection(TT::QR, TT::YZ)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentHalfstripIntersection(TT::QR, TT::ZX)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentHalfstripIntersection(TT::QR, TT::XY)); - - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentHalfstripIntersection(TT::RP, TT::YZ)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentHalfstripIntersection(TT::RP, TT::ZX)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentHalfstripIntersection(TT::RP, TT::XY)); - - // segment-ray (9 possibilities) - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentRayIntersection(TT::PQ, TT::X)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentRayIntersection(TT::PQ, TT::Y)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentRayIntersection(TT::PQ, TT::Z)); - - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentRayIntersection(TT::QR, TT::X)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentRayIntersection(TT::QR, TT::Y)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentRayIntersection(TT::QR, TT::Z)); - - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentRayIntersection(TT::RP, TT::X)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentRayIntersection(TT::RP, TT::Y)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentRayIntersection(TT::RP, TT::Z)); - - // surface-edge (6 possibilities) - CPPUNIT_ASSERT_EQUAL(false, tri->testSurfaceEdgeIntersection(TT::OX)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSurfaceEdgeIntersection(TT::OY)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSurfaceEdgeIntersection(TT::OZ)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSurfaceEdgeIntersection(TT::YZ)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSurfaceEdgeIntersection(TT::ZX)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSurfaceEdgeIntersection(TT::XY)); - - // surface-ray (3 possibilities) - CPPUNIT_ASSERT_EQUAL(false, tri->testSurfaceRayIntersection(TT::X)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSurfaceRayIntersection(TT::Y)); - CPPUNIT_ASSERT_EQUAL(false, tri->testSurfaceRayIntersection(TT::Z)); - - delete tri; -} -#endif diff --git a/src/INTERP_KERNELTest/TransformedTriangleIntersectTest.hxx b/src/INTERP_KERNELTest/TransformedTriangleIntersectTest.hxx deleted file mode 100644 index 8ff1196d9..000000000 --- a/src/INTERP_KERNELTest/TransformedTriangleIntersectTest.hxx +++ /dev/null @@ -1,94 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 -// 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 __TU_TRANSFORMED_TRIANGLE_INTERSECT_HXX__ -#define __TU_TRANSFORMED_TRIANGLE_INTERSECT_HXX__ - -#include - -#include "InterpKernelTestExport.hxx" -#include "TransformedTriangle.hxx" - -namespace INTERP_TEST -{ - - class INTERPKERNELTEST_EXPORT TransformedTriangleIntersectTest : public CppUnit::TestFixture - { - - CPPUNIT_TEST_SUITE( TransformedTriangleIntersectTest ); - - CPPUNIT_TEST( testTriangle1 ); - CPPUNIT_TEST( testTriangle2 ); - CPPUNIT_TEST( testTriangle3 ); - CPPUNIT_TEST( testTriangle4 ); - CPPUNIT_TEST( testTriangle5 ); - CPPUNIT_TEST( testTriangle6 ); - CPPUNIT_TEST( testTriangle7 ); - CPPUNIT_TEST( testTriangle8 ); - CPPUNIT_TEST( testTriangle9 ); - CPPUNIT_TEST( testTriangle10 ); - CPPUNIT_TEST( testTriangle11 ); - CPPUNIT_TEST( testTriangle12 ); - CPPUNIT_TEST( testTriangle13 ); - - CPPUNIT_TEST_SUITE_END(); - - typedef INTERP_KERNEL::TransformedTriangle::TriSegment TriSegment; - typedef INTERP_KERNEL::TransformedTriangle::DoubleProduct DoubleProduct; - - public: - - void testTriangle1(); - - void testTriangle2(); - - void testTriangle3(); - - void testTriangle4(); - - void testTriangle5(); - - void testTriangle6(); - - void testTriangle7(); - - void testTriangle8(); - - void testTriangle9(); - - void testTriangle10(); - - void testTriangle11(); - - void testTriangle12(); - - void testTriangle13(); - - private: - - }; - -} - - - - - - -#endif diff --git a/src/INTERP_KERNELTest/TransformedTriangleTest.cxx b/src/INTERP_KERNELTest/TransformedTriangleTest.cxx deleted file mode 100644 index ee4eb20c2..000000000 --- a/src/INTERP_KERNELTest/TransformedTriangleTest.cxx +++ /dev/null @@ -1,355 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// - -#include "TransformedTriangleTest.hxx" - -#include - -using namespace INTERP_KERNEL; - -namespace INTERP_TEST -{ - - /** - * Creates the TransformedTriangle objects used by the tests. - * - */ - void TransformedTriangleTest::setUp() - { - // tri1 -> no unstable double products - no changes brought about by preCalculateDoubleProducts - // this allows the testing of calcUnstableT - // tri2 -> unstable double products - for testing calcStableC / preCalculateDoubleProducts - - // triangle to test unstable C and T calculations - p1[0] = -1.5 ; p1[1] = 0.5; p1[2] = 0.5; - q1[0] = 2.0 ; q1[1] = 0.4; q1[2] = 0.6; - r1[0] = 1.0 ; r1[1] = 2.4; r1[2] = 1.2; - hp1 = 1 - p1[0] - p1[1] - p1[2]; - hq1 = 1 - q1[0] - q1[1] - q1[2]; - hr1 = 1 - r1[0] - r1[1] - r1[2]; - Hp1 = 1 - p1[0] - p1[1]; - Hq1 = 1 - q1[0] - q1[1]; - Hr1 = 1 - r1[0] - r1[1]; - - // std::cout <_coords[i], ERR_TOL); - CPPUNIT_ASSERT_DOUBLES_EQUAL(good_values2[i], tri2->_coords[i], ERR_TOL); - } - - CPPUNIT_ASSERT_EQUAL(true, tri1->_is_double_products_calculated); - CPPUNIT_ASSERT_EQUAL(true, tri2->_is_double_products_calculated); - } - - /// Tests the calculation of double products (without the corrections) - /// \brief Status : pass - void TransformedTriangleTest::test_calcUnstableC() { - typedef TransformedTriangle::TriSegment TriSegment; - - // test that the correct c-values are calculated - - double correct_c_vals[24] = - { - p1[0] * q1[1] - p1[1] * q1[0], - p1[1] * q1[2] - p1[2] * q1[1], - p1[2] * q1[0] - p1[0] * q1[2], - p1[0] * hq1 - hp1 * q1[0], - p1[1] * hq1 - hp1 * q1[1], - p1[2] * hq1 - hp1 * q1[2], - Hp1 * q1[0] - p1[0] * Hq1, - p1[1] * Hq1 - Hp1 * q1[1], - q1[0] * r1[1] - q1[1] * r1[0], - q1[1] * r1[2] - q1[2] * r1[1], - q1[2] * r1[0] - q1[0] * r1[2], - q1[0] * hr1 - hq1 * r1[0], - q1[1] * hr1 - hq1 * r1[1], - q1[2] * hr1 - hq1 * r1[2], - Hq1 * r1[0] - q1[0] * Hr1, - q1[1] * Hr1 - Hq1 * r1[1], - r1[0]*p1[1]-r1[1]*p1[0], - r1[1]*p1[2]-r1[2]*p1[1], - r1[2]*p1[0]-r1[0]*p1[2], - r1[0] * hp1 - hr1 * p1[0], - r1[1] * hp1 - hr1 * p1[1], - r1[2] * hp1 - hr1 * p1[2], - Hr1 * p1[0] - r1[0] * Hp1, - r1[1] * Hp1 - Hr1 * p1[1] - }; - - double c_vals[3 * 8]; - for(TriSegment seg = TransformedTriangle::PQ ; seg <= TransformedTriangle::RP ; seg = TriSegment(seg + 1)) { - - c_vals[seg*8 + 0] = tri1->calcUnstableC(seg, TransformedTriangle::C_XY); - c_vals[seg*8 + 1] = tri1->calcUnstableC(seg, TransformedTriangle::C_YZ); - c_vals[seg*8 + 2] = tri1->calcUnstableC(seg, TransformedTriangle::C_ZX); - c_vals[seg*8 + 3] = tri1->calcUnstableC(seg, TransformedTriangle::C_XH); - c_vals[seg*8 + 4] = tri1->calcUnstableC(seg, TransformedTriangle::C_YH); - c_vals[seg*8 + 5] = tri1->calcUnstableC(seg, TransformedTriangle::C_ZH); - c_vals[seg*8 + 6] = tri1->calcUnstableC(seg, TransformedTriangle::C_01); - c_vals[seg*8 + 7] = tri1->calcUnstableC(seg, TransformedTriangle::C_10); - - } - - for(int i = 0 ; i < 3*8 ; ++i) { - CPPUNIT_ASSERT_DOUBLES_EQUAL( correct_c_vals[i], c_vals[i], ERR_TOL ); - } - - - } - - /// Tests the calculation of triple products (without corrections) - /// \brief Status : pass - void TransformedTriangleTest::test_calcUnstableT() - { - typedef TransformedTriangle::TetraCorner TetraCorner; - - // correct values calculated by determinants (Grandy, [15]) - const double correct_t_vals[4] = - { - p1[0]*(q1[1]*r1[2] - q1[2]*r1[1]) - - q1[0]*(p1[1]*r1[2] - p1[2]*r1[1]) + - r1[0]*(p1[1]*q1[2] - p1[2]*q1[1]), - - -(hp1*(q1[1]*r1[2] - q1[2]*r1[1]) - - hq1*(p1[1]*r1[2] - p1[2]*r1[1]) + - hr1*(p1[1]*q1[2] - p1[2]*q1[1])), - - -(p1[0]*(hq1*r1[2] - q1[2]*hr1) - - q1[0]*(hp1*r1[2] - p1[2]*hr1) + - r1[0]*(hp1*q1[2] - p1[2]*hq1)), - - -(p1[0]*(q1[1]*hr1 - r1[1]*hq1) - - q1[0]*(p1[1]*hr1 - r1[1]*hp1) + - r1[0]*(p1[1]*hq1 - q1[1]*hp1)) - }; - - - // test that triple products are correctly calculated - for(TetraCorner corner = TransformedTriangle::O ; corner <= TransformedTriangle::Z ; corner = TetraCorner(corner + 1)) - { - - for(int row = 1 ; row < 4 ; ++row) - { - const double t = tri1->calcTByDevelopingRow(corner, row, false); - // std::cout << std::endl << " Corner = " << corner << " Row = " << row << " got: " << t << - // " expected: " << correct_t_vals[corner]<< std::endl; - CPPUNIT_ASSERT_DOUBLES_EQUAL(correct_t_vals[corner], t, ERR_TOL); - } - } - } - - /// Tests the consistency correction - /// \brief Status : fails because it is not significant - the consistency correction is not brought into play - void TransformedTriangleTest::test_calcStableC_Consistency() - { - - typedef TransformedTriangle::TriSegment TriSegment; - typedef TransformedTriangle::TetraCorner TetraCorner; - - // grandy, eq 14 - double correct_c_vals[24] = - { - p2[0] * q2[1] - p2[1] * q2[0], - p2[1] * q2[2] - p2[2] * q2[1], - p2[2] * q2[0] - p2[0] * q2[2], - p2[0] * hq2 - hp2 * q2[0], - p2[1] * hq2 - hp2 * q2[1], - p2[2] * hq2 - hp2 * q2[2], - Hp2 * q2[0] - p2[0] * Hq2, - p2[1] * Hq2 - Hp2 * q2[1], - q2[0] * r2[1] - q2[1] * r2[0], - q2[1] * r2[2] - q2[2] * r2[1], - q2[2] * r2[0] - q2[0] * r2[2], - q2[0] * hr2 - hq2 * r2[0], - q2[1] * hr2 - hq2 * r2[1], - q2[2] * hr2 - hq2 * r2[2], - Hq2 * r2[0] - q2[0] * Hr2, - q2[1] * Hr2 - Hq2 * r2[1], - r2[0]*p2[1]-r2[1]*p2[0], - r2[1]*p2[2]-r2[2]*p2[1], - r2[2]*p2[0]-r2[0]*p2[2], - r2[0] * hp2 - hr2 * p2[0], - r2[1] * hp2 - hr2 * p2[1], - r2[2] * hp2 - hr2 * p2[2], - Hr2 * p2[0] - r2[0] * Hp2, - r2[1] * Hp2 - Hr2 * p2[1] - }; - - - // number of inconsistent cases found : - // should be (at least) 1 for the test to be meaningful - int num_cases = 0; - - // find unstable products to check for consistency (Grandy [46]) - for(TriSegment seg = TransformedTriangle::PQ ; seg <= TransformedTriangle::RP ; seg = TriSegment(seg + 1)) - { - const double c_xy = tri2->calcUnstableC(seg, TransformedTriangle::C_XY); - const double c_yz = tri2->calcUnstableC(seg, TransformedTriangle::C_YZ); - const double c_zx = tri2->calcUnstableC(seg, TransformedTriangle::C_ZX); - const double c_xh = tri2->calcUnstableC(seg, TransformedTriangle::C_XH); - const double c_yh = tri2->calcUnstableC(seg, TransformedTriangle::C_YH); - const double c_zh = tri2->calcUnstableC(seg, TransformedTriangle::C_ZH); - - const int num_zero = (c_yz*c_xh == 0.0 ? 1 : 0) + (c_zx*c_yh == 0.0 ? 1 : 0) + (c_xy*c_zh == 0.0 ? 1 : 0); - const int num_neg = (c_yz*c_xh < 0.0 ? 1 : 0) + (c_zx*c_yh < 0.0 ? 1 : 0) + (c_xy*c_zh < 0.0 ? 1 : 0); - - if((num_zero == 1 && num_neg != 1) || num_zero == 2 || num_neg == 0 && num_zero !=3 || num_neg == 3 ) - { - ++num_cases; - - double min_dist = -1.0; // initialised first time through loop - TetraCorner min_corner = TransformedTriangle::O; - - for(TetraCorner corner = TransformedTriangle::O ; corner <= TransformedTriangle::Z ; corner = TetraCorner(corner + 1)) - { - // calculate distance from each corner of tetraeder to the segment - // formula : ( (Q-P) x (P - corner) )^2 / norm(Q-P)^2 - - const double ptP[3] = { tri2->_coords[5*seg], tri2->_coords[5*seg + 1], tri2->_coords[5*seg + 2] }; - const double ptQ[3] = { tri2->_coords[5*( (seg+1) % 3)], tri2->_coords[5*( (seg+1) % 3) + 1], tri2->_coords[5*( (seg+1) % 3) + 2] }; - const double ptCorner[3] = { - corner == TransformedTriangle::X ? 1.0 : 0.0, - corner == TransformedTriangle::Y ? 1.0 : 0.0, - corner == TransformedTriangle::Z ? 1.0 : 0.0, - }; - - const double diff_21[3] = { ptQ[0] - ptP[0], ptQ[1] - ptP[1], ptQ[2] - ptP[2] }; - const double diff_1_corner[3] = { ptP[0] - ptCorner[0], ptP[1] - ptCorner[1], ptP[2] - ptCorner[2] }; - - const double cross[3] = { - diff_21[1]*diff_1_corner[2] - diff_21[2]*diff_1_corner[1], - diff_21[2]*diff_1_corner[0] - diff_21[0]*diff_1_corner[2], - diff_21[0]*diff_1_corner[1] - diff_21[1]*diff_1_corner[0] - }; - - const double cross_sq = cross[0]*cross[0] + cross[1]*cross[1] + cross[2]*cross[2]; - - const double norm_pq = diff_21[0]*diff_21[0] + diff_21[1]*diff_21[1] + diff_21[2]*diff_21[2]; - - if(corner == TransformedTriangle::O || (cross_sq / norm_pq) < min_dist) - { - min_dist = cross_sq / norm_pq; - min_corner = corner; - } - } - - // now check if the corresponding double products are zero - static const DoubleProduct DOUBLE_PRODUCTS[12] = - { - TransformedTriangle::C_YZ, TransformedTriangle::C_XY, TransformedTriangle::C_ZX, // O - TransformedTriangle::C_ZH, TransformedTriangle::C_YZ, TransformedTriangle::C_YH, // X - TransformedTriangle::C_ZH, TransformedTriangle::C_ZX, TransformedTriangle::C_XH, // Y - TransformedTriangle::C_XY, TransformedTriangle::C_YH, TransformedTriangle::C_XH // Z - }; - - for(int i = 0; i < 3 ; ++i) - { - DoubleProduct dp = DOUBLE_PRODUCTS[3*min_corner + i]; - // std::cout << std::endl << "in test inconsistent (seg,dp) :(" << seg <<", " << dp << ")" << std::endl; - CPPUNIT_ASSERT_EQUAL(0.0, tri2->calcStableC(seg, dp)); - correct_c_vals[8*seg + dp] = 0.0; - } - } - - } - - if(num_cases < 1) - { - CPPUNIT_FAIL("Consistency test not pertinent"); - } - - // std::cout << std::endl << "Number of geometric inconsistencies : " << num_cases << std::endl; - - // check that all other double products have right value too - double c_vals[8*3]; - - for(TriSegment seg = TransformedTriangle::PQ ; seg <= TransformedTriangle::RP ; seg = TriSegment(seg + 1)) { - - c_vals[seg*8 + 0] = tri2->calcStableC(seg, TransformedTriangle::C_XY); - c_vals[seg*8 + 1] = tri2->calcStableC(seg, TransformedTriangle::C_YZ); - c_vals[seg*8 + 2] = tri2->calcStableC(seg, TransformedTriangle::C_ZX); - c_vals[seg*8 + 3] = tri2->calcStableC(seg, TransformedTriangle::C_XH); - c_vals[seg*8 + 4] = tri2->calcStableC(seg, TransformedTriangle::C_YH); - c_vals[seg*8 + 5] = tri2->calcStableC(seg, TransformedTriangle::C_ZH); - c_vals[seg*8 + 6] = tri2->calcStableC(seg, TransformedTriangle::C_01); - c_vals[seg*8 + 7] = tri2->calcStableC(seg, TransformedTriangle::C_10); - - } - - for(int i = 0 ; i < 24 ; ++i) - { - CPPUNIT_ASSERT_DOUBLES_EQUAL(correct_c_vals[i], c_vals[i], ERR_TOL); - } - } - -} diff --git a/src/INTERP_KERNELTest/TransformedTriangleTest.hxx b/src/INTERP_KERNELTest/TransformedTriangleTest.hxx deleted file mode 100644 index 064f4059c..000000000 --- a/src/INTERP_KERNELTest/TransformedTriangleTest.hxx +++ /dev/null @@ -1,88 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 -// 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 __TU_TRANSFORMED_TRIANGLE_HXX__ -#define __TU_TRANSFORMED_TRIANGLE_HXX__ - -#include - -#include "InterpKernelTestExport.hxx" -#include "TransformedTriangle.hxx" - -#define ERR_TOL 1.0e-8 - -namespace INTERP_TEST -{ - - /** - * \brief Test suite testing some of the low level methods of TransformedTriangle. - * - */ - class INTERPKERNELTEST_EXPORT TransformedTriangleTest : public CppUnit::TestFixture - { - - CPPUNIT_TEST_SUITE( TransformedTriangleTest ); - CPPUNIT_TEST( test_constructor ); - CPPUNIT_TEST( test_calcUnstableC ); - CPPUNIT_TEST( test_calcUnstableT ); - //removed because the test fails to enter the desired code branch - // CPPUNIT_TEST( test_calcStableC_Consistency ); - CPPUNIT_TEST_SUITE_END(); - - typedef INTERP_KERNEL::TransformedTriangle::TriSegment TriSegment; - typedef INTERP_KERNEL::TransformedTriangle::DoubleProduct DoubleProduct; - - public: - void setUp(); - - void tearDown(); - - // tests - void test_constructor(); - - void test_calcUnstableC(); - - void test_calcUnstableT(); - - void test_calcStableC_Consistency(); - - double p1[3], q1[3], r1[3]; - double hp1, hq1, hr1; - double Hp1, Hq1, Hr1; - - double p2[3], q2[3], r2[3]; - double hp2, hq2, hr2; - double Hp2, Hq2, Hr2; - - double stable_c2[24]; - - private: - INTERP_KERNEL::TransformedTriangle* tri1; - INTERP_KERNEL::TransformedTriangle* tri2; - - }; - - - - -} - - - -#endif diff --git a/src/INTERP_KERNELTest/UnitTetra3D2DIntersectionTest.cxx b/src/INTERP_KERNELTest/UnitTetra3D2DIntersectionTest.cxx deleted file mode 100644 index 031becc04..000000000 --- a/src/INTERP_KERNELTest/UnitTetra3D2DIntersectionTest.cxx +++ /dev/null @@ -1,176 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// - -#include "UnitTetra3D2DIntersectionTest.hxx" - -#include "TetraAffineTransform.hxx" -#include "InterpolationUtils.hxx" -#include "SplitterTetra.txx" - -#include - -using namespace INTERP_KERNEL; - -namespace INTERP_TEST -{ - struct __MESH_DUMMY - { - typedef int MyConnType; - static const int MY_SPACEDIM=3; - }; - - static SplitterTetra<__MESH_DUMMY>* buildSplitterTetra() - { - const int conn[4] = { 0,1,2,3 }; - - const double targetCoords[] = { -20., 0.,10., - -20.,10.,10., - -12., 0.,10., - -20., 0.,18. }; - - const double* tetraCoords[]={ targetCoords, targetCoords+3, targetCoords+6, targetCoords+9 }; - - __MESH_DUMMY dummyMesh; - SplitterTetra<__MESH_DUMMY>* targetTetra = new SplitterTetra<__MESH_DUMMY>( dummyMesh, tetraCoords, conn ); - return targetTetra; - } - - void UnitTetra3D2DIntersectionTest::test_UnitTetra3D2DIntersection_1() - { - const int conn[4] = { 0,1,2 }; - - const double sourceCoords[] = { -20., 0., 10., - -12., 0., 10., - -20.,10., 10. }; - - SplitterTetra<__MESH_DUMMY>* targetTetra = buildSplitterTetra(); - const double dimCaracteristic = 1.; - const double precision = 1.e-12; - std::multiset listOfTetraFacesTreated; - std::set listOfTetraFacesColinear; - - const double* sourceTriCoords[] = { sourceCoords, sourceCoords+3, sourceCoords+6 }; - double surface = targetTetra->intersectSourceFace(NORM_TRI3, - 3, - conn, - sourceTriCoords, - dimCaracteristic, - precision, - listOfTetraFacesTreated, - listOfTetraFacesColinear); - delete targetTetra; - CPPUNIT_ASSERT_DOUBLES_EQUAL(40.,surface,precision); - - CPPUNIT_ASSERT_EQUAL(4,(int)listOfTetraFacesTreated.size()); - std::multiset correctListOfTetraFacesTreated; - TriangleFaceKey key1 = TriangleFaceKey(0, 1, 2); - correctListOfTetraFacesTreated.insert(key1); - TriangleFaceKey key2 = TriangleFaceKey(0, 1, 3); - correctListOfTetraFacesTreated.insert(key2); - TriangleFaceKey key3 = TriangleFaceKey(0, 2, 3); - correctListOfTetraFacesTreated.insert(key3); - TriangleFaceKey key4 = TriangleFaceKey(1, 2, 3); - correctListOfTetraFacesTreated.insert(key4); - CPPUNIT_ASSERT(correctListOfTetraFacesTreated == listOfTetraFacesTreated); - - CPPUNIT_ASSERT_EQUAL(1,(int)listOfTetraFacesColinear.size()); - std::set correctListOfTetraFacesColinear; - correctListOfTetraFacesColinear.insert(key1); - CPPUNIT_ASSERT(correctListOfTetraFacesColinear == listOfTetraFacesColinear); - - } - - void UnitTetra3D2DIntersectionTest::test_UnitTetra3D2DIntersection_2() - { - const int conn[4] = { 0,1,2,3 }; - - const double sourceCoords[] = { -20., 0., 10., - -12., 0., 10., - -12.,10., 10., - -20.,10., 10. }; - - SplitterTetra<__MESH_DUMMY>* targetTetra = buildSplitterTetra(); - const double dimCaracteristic = 1.; - const double precision = 1.e-12; - std::multiset listOfTetraFacesTreated; - std::set listOfTetraFacesColinear; - - const double* sourceQuadCoords[] = { sourceCoords, sourceCoords+3, sourceCoords+6, sourceCoords+9 }; - double surface = targetTetra->intersectSourceFace(NORM_QUAD4, - 4, - conn, - sourceQuadCoords, - dimCaracteristic, - precision, - listOfTetraFacesTreated, - listOfTetraFacesColinear); - delete targetTetra; - CPPUNIT_ASSERT_DOUBLES_EQUAL(40.,surface,precision); - - CPPUNIT_ASSERT_EQUAL(4,(int)listOfTetraFacesTreated.size()); - std::multiset correctListOfTetraFacesTreated; - TriangleFaceKey key1 = TriangleFaceKey(0, 1, 2); - correctListOfTetraFacesTreated.insert(key1); - TriangleFaceKey key2 = TriangleFaceKey(0, 1, 3); - correctListOfTetraFacesTreated.insert(key2); - TriangleFaceKey key3 = TriangleFaceKey(0, 2, 3); - correctListOfTetraFacesTreated.insert(key3); - TriangleFaceKey key4 = TriangleFaceKey(1, 2, 3); - correctListOfTetraFacesTreated.insert(key4); - CPPUNIT_ASSERT(correctListOfTetraFacesTreated == listOfTetraFacesTreated); - - CPPUNIT_ASSERT_EQUAL(1,(int)listOfTetraFacesColinear.size()); - std::set correctListOfTetraFacesColinear; - correctListOfTetraFacesColinear.insert(key1); - CPPUNIT_ASSERT(correctListOfTetraFacesColinear == listOfTetraFacesColinear); - - } - - void UnitTetra3D2DIntersectionTest::test_UnitTetra3D2DIntersection_3() - { - const int conn[4] = { 0,1,2 }; - - const double sourceCoords[] = { -20., 0., 16., - -18., 0., 16., - -20.,2.5, 16. }; - - SplitterTetra<__MESH_DUMMY>* targetTetra = buildSplitterTetra(); - const double dimCaracteristic = 1.; - const double precision = 1.e-12; - std::multiset listOfTetraFacesTreated; - std::set listOfTetraFacesColinear; - - const double* sourceTri2Coords[] = { sourceCoords, sourceCoords+3, sourceCoords+6 }; - double surface = targetTetra->intersectSourceFace(NORM_TRI3, - 3, - conn, - sourceTri2Coords, - dimCaracteristic, - precision, - listOfTetraFacesTreated, - listOfTetraFacesColinear); - delete targetTetra; - CPPUNIT_ASSERT_DOUBLES_EQUAL(2.5,surface,precision); - - CPPUNIT_ASSERT_EQUAL(0,(int)listOfTetraFacesTreated.size()); - - CPPUNIT_ASSERT_EQUAL(0,(int)listOfTetraFacesColinear.size()); - } - -} diff --git a/src/INTERP_KERNELTest/UnitTetra3D2DIntersectionTest.hxx b/src/INTERP_KERNELTest/UnitTetra3D2DIntersectionTest.hxx deleted file mode 100644 index 7ccc1219e..000000000 --- a/src/INTERP_KERNELTest/UnitTetra3D2DIntersectionTest.hxx +++ /dev/null @@ -1,47 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 -// 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 __UNITTETRA3D2DINTERSECTIONTEST_HXX__ -#define __UNITTETRA3D2DINTERSECTIONTEST_HXX__ - -#include - -#include "InterpKernelTestExport.hxx" - -namespace INTERP_TEST -{ - /** - * \brief Test suite testing UnitTetra3D2DIntersection class. - * - */ - class INTERPKERNELTEST_EXPORT UnitTetra3D2DIntersectionTest : public CppUnit::TestFixture - { - CPPUNIT_TEST_SUITE( UnitTetra3D2DIntersectionTest ); - CPPUNIT_TEST( test_UnitTetra3D2DIntersection_1 ); - CPPUNIT_TEST( test_UnitTetra3D2DIntersection_2 ); - CPPUNIT_TEST( test_UnitTetra3D2DIntersection_3 ); - CPPUNIT_TEST_SUITE_END(); - public: - void test_UnitTetra3D2DIntersection_1(); - void test_UnitTetra3D2DIntersection_2(); - void test_UnitTetra3D2DIntersection_3(); - }; -} - -#endif diff --git a/src/INTERP_KERNELTest/UnitTetraIntersectionBaryTest.cxx b/src/INTERP_KERNELTest/UnitTetraIntersectionBaryTest.cxx deleted file mode 100644 index d901f218a..000000000 --- a/src/INTERP_KERNELTest/UnitTetraIntersectionBaryTest.cxx +++ /dev/null @@ -1,346 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 -// 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 -// - -// File : UnitTetraIntersectionBaryTest.cxx -// Created : Thu Dec 11 15:54:41 2008 -// Author : Edward AGAPOV (eap) -// -#include "UnitTetraIntersectionBaryTest.hxx" - -#include "UnitTetraIntersectionBary.hxx" -#include "TetraAffineTransform.hxx" -#include "InterpolationUtils.hxx" -#include "SplitterTetra.txx" - -#include - -using namespace INTERP_KERNEL; - -namespace INTERP_TEST -{ - void fill_UnitTetraIntersectionBary(UnitTetraIntersectionBary& bary, double nodes[][3]) - { - int faceConn[4][3] = { { 0, 1, 2 },// inverse order - { 0, 3, 1 }, - { 1, 3, 2 }, - { 3, 0, 2 } }; -// int faceConn[4][3] = { { 0, 2, 1 }, -// { 0, 1, 3 }, -// { 1, 2, 3 }, -// { 3, 2, 0 } }; - bary.init(true); - for ( int i = 0; i < 4; ++i ) { - int* faceNodes = faceConn[ i ]; - TransformedTriangle tri(nodes[faceNodes[0]], nodes[faceNodes[1]], nodes[faceNodes[2]]); - tri.calculateIntersectionVolume(); - bary.addSide( tri ); - } - } - void UnitTetraIntersectionBaryTest::test_UnitTetraIntersectionBary_1() - { - // cutting tetra coincides with the unit one - double nodes[4][3] = { { 0.0, 0.0, 0.0 }, - { 1.0, 0.0, 0.0 }, - { 0.0, 1.0, 0.0 }, - { 0.0, 0.0, 1.0 } }; - UnitTetraIntersectionBary bary; - fill_UnitTetraIntersectionBary(bary,nodes); - double baryCenter[3]; - bool ok = bary.getBary( baryCenter ); - double vol = bary.getVolume(); - CPPUNIT_ASSERT( ok ); - CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.166667, vol, 1e-5); - CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.25, baryCenter[0], 1e-5); - CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.25, baryCenter[1], 1e-5); - CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.25, baryCenter[2], 1e-5); - } - void UnitTetraIntersectionBaryTest::test_UnitTetraIntersectionBary_2() - { - // cutting tetra fully include the unit one - double nodes[4][3] = { {-0.1,-0.1,-0.1 }, - { 1.5,-0.1,-0.1 }, - {-0.1, 1.5,-0.1 }, - {-0.1,-0.1, 1.5 } }; - UnitTetraIntersectionBary bary; - fill_UnitTetraIntersectionBary(bary,nodes); - double baryCenter[3]; - bool ok = bary.getBary( baryCenter ); - double vol = bary.getVolume(); - CPPUNIT_ASSERT( ok ); - CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.166667, vol, 1e-5); - CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.25, baryCenter[0], 1e-5); - CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.25, baryCenter[1], 1e-5); - CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.25, baryCenter[2], 1e-5); - } - void UnitTetraIntersectionBaryTest::test_UnitTetraIntersectionBary_3() - { - // cutting tetra is same as the unit one but moved up by 0.5 - double nodes[4][3] = { { 0.0, 0.0, 0.5 }, - { 1.0, 0.0, 0.5 }, - { 0.0, 1.0, 0.5 }, - { 0.0, 0.0, 1.5 } }; - UnitTetraIntersectionBary bary; - fill_UnitTetraIntersectionBary(bary,nodes); - double baryCenter[3]; - bool ok = bary.getBary( baryCenter ); - double vol = bary.getVolume(); - CPPUNIT_ASSERT( ok ); - CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.020833333333333332, vol, 1e-5); - CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.125, baryCenter[0], 1e-5); - CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.125, baryCenter[1], 1e-5); - CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.625, baryCenter[2], 1e-5); - } - void UnitTetraIntersectionBaryTest::test_UnitTetraIntersectionBary_4() - { - // same as previous but no cutting sides lay on the sides of unit tetra - double nodes[4][3] = { {-0.2,-0.2, 0.5 }, - { 1.0, 0.0, 0.5 }, - { 0.0, 1.0, 0.5 }, - { 0.0, 0.0, 2.0 } }; - UnitTetraIntersectionBary bary; - fill_UnitTetraIntersectionBary(bary,nodes); - double baryCenter[3]; - bool ok = bary.getBary( baryCenter ); - double vol = bary.getVolume(); - CPPUNIT_ASSERT( ok ); - CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.020833333333333332, vol, 1e-5); - CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.125, baryCenter[0], 1e-5); - CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.125, baryCenter[1], 1e-5); - CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.625, baryCenter[2], 1e-5); - } - void UnitTetraIntersectionBaryTest::test_UnitTetraIntersectionBary_5() - { - // cutting tetra is similar and parallel to the UT but moved (-0.1,-0.1,-0.1) - double nodes[4][3] = { {-0.1,-0.1,-0.1 }, - { 1.1,-0.1,-0.1 }, - {-0.1, 1.1,-0.1 }, - {-0.1,-0.1, 1.1 } }; - UnitTetraIntersectionBary bary; - fill_UnitTetraIntersectionBary(bary,nodes); - double baryCenter[3]; - bool ok = bary.getBary( baryCenter ); - double vol = bary.getVolume(); - CPPUNIT_ASSERT( ok ); - CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.1215, vol, 1e-5); - CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.225, baryCenter[0], 1e-5); - CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.225, baryCenter[1], 1e-5); - CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.225, baryCenter[2], 1e-5); - } - void UnitTetraIntersectionBaryTest::test_UnitTetraIntersectionBary_6() - { - // cutting tetra is deeped into the UT with one corner - double nodes[4][3] = { { 0.2, 0.2, 0.2 }, - { 1.0, 0.2, 0.2 }, - { 0.9, 1.0, 0.2 }, - { 0.9, 9.0, 1.0 } }; - UnitTetraIntersectionBary bary; - fill_UnitTetraIntersectionBary(bary,nodes); - double baryCenter[3]; - bool ok = bary.getBary( baryCenter ); - double vol = bary.getVolume(); - CPPUNIT_ASSERT( ok ); - CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.000441855, vol, 1e-5); - CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.353463 , baryCenter[0], 1e-5 ); - CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.33877 , baryCenter[1], 1e-5 ); - CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.207767 , baryCenter[2], 1e-5 ); - } - void UnitTetraIntersectionBaryTest::test_UnitTetraIntersectionBary_7() - { - // cutting tetra passes through the UT with one corner - double nodes[4][3] = { {-0.2, 0.2, 0.2 }, - { 1.0, 0.2, 0.2 }, - { 0.9, 1.0, 0.2 }, - { 0.9, 0.9, 1.0 } }; - UnitTetraIntersectionBary bary; - fill_UnitTetraIntersectionBary(bary,nodes); - double baryCenter[3]; - bool ok = bary.getBary( baryCenter ); - double vol = bary.getVolume(); - CPPUNIT_ASSERT( ok ); - CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.0103501, vol, 1e-5); - CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.215578 , baryCenter[0], 1e-5 ); - CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.341363 , baryCenter[1], 1e-5 ); - CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.263903 , baryCenter[2], 1e-5 ); - } - void UnitTetraIntersectionBaryTest::test_UnitTetraIntersectionBary_8() - { - // cutting tetra passes through the UT with one edge - double nodes[4][3] = { { 0.5, 0.2, -0.2 }, // O - {-0.5,-0.2, -0.2 }, // OX - { 1.0,-0.5, -0.2 }, // OY - { 0.5, 0.2, 1.5 } };//OZ - UnitTetraIntersectionBary bary; - fill_UnitTetraIntersectionBary(bary,nodes); - double baryCenter[3]; - bool ok = bary.getBary( baryCenter ); - double vol = bary.getVolume(); - CPPUNIT_ASSERT( ok ); - CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.0349217, vol, 1e-5); - CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.332275 , baryCenter[0], 1e-2 ); - CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.0565892 , baryCenter[1], 1e-3 ); - CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.308713 , baryCenter[2], 1e-2 ); - } - void UnitTetraIntersectionBaryTest::test_UnitTetraIntersectionBary_9() - { - // cutting tetra touches the UT at an edge, intersection volume == 0 - double nodes[4][3] = { { 1.0, 0.0, 0.0 }, // 0 - {-1.0, 2.0, 2.0 }, // OX - {-1.0,-2.0, 2.0 }, // OY - { 1.0, 0.0, 2.0 } };//OZ - UnitTetraIntersectionBary bary; - fill_UnitTetraIntersectionBary(bary,nodes); - double baryCenter[3]; - bool ok = bary.getBary( baryCenter ); - double vol = bary.getVolume(); - CPPUNIT_ASSERT( !ok ); - CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.0, vol, 1e-15); - CPPUNIT_ASSERT_DOUBLES_EQUAL( -1. , baryCenter[0], 1e-5 ); - CPPUNIT_ASSERT_DOUBLES_EQUAL( -1. , baryCenter[1], 1e-5 ); - CPPUNIT_ASSERT_DOUBLES_EQUAL( -1. , baryCenter[2], 1e-5 ); - } - void UnitTetraIntersectionBaryTest::test_UnitTetraIntersectionBary_10() - { - // cutting tetra fully includes theUT and touches it at an edge - double nodes[4][3] = { { 1.0, 0.0, 0.0 }, // 0 - {-1.0,-4.0, 2.0 }, // OX - {-1.0, 4.0, 2.0 }, // OY - { 1.0, 0.0,-2.0 } };//OZ - UnitTetraIntersectionBary bary; - fill_UnitTetraIntersectionBary(bary,nodes); - double baryCenter[3]; - bool ok = bary.getBary( baryCenter ); - double vol = bary.getVolume(); - CPPUNIT_ASSERT( ok ); - CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.166667, vol, 1e-5); - CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.25, baryCenter[0], 1e-5); - CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.25, baryCenter[1], 1e-5); - CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.25, baryCenter[2], 1e-5); - } - void UnitTetraIntersectionBaryTest::test_UnitTetraIntersectionBary_11() - { - // cutting tetra intersects the UT and touches it at an edge - double nodes[4][3] = { { 1.0, 0.0, 0.0 }, // 0 - {-1.0,-4.0, 2.0 }, // OX - {-1.0, 4.0, 2.0 }, // OY - {-1.0, 0.0,-1.0 } };//OZ - UnitTetraIntersectionBary bary; - fill_UnitTetraIntersectionBary(bary,nodes); - double baryCenter[3]; - bool ok = bary.getBary( baryCenter ); - double vol = bary.getVolume(); - CPPUNIT_ASSERT( ok ); - CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.15873 , vol, 1e-5); - CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.250000, baryCenter[0], 1e-5); - CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.230952, baryCenter[1], 1e-5); - CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.260714, baryCenter[2], 1e-5); - } - void UnitTetraIntersectionBaryTest::test_UnitTetraIntersectionBary_12() - { - // cutting tetra has one corner inside the UT and one its side passes through an UT edge - double nodes[4][3] = { { 0.25, 0.25, 0.25 }, // 0 - { 1.75,-0.25,-0.25 }, // OX - { 0.5 , 0.25, 0.25 }, // OY - { 0.5 , 0 , 0.5 } };//OZ - UnitTetraIntersectionBary bary; - fill_UnitTetraIntersectionBary(bary,nodes); - double baryCenter[3]; - bool ok = bary.getBary( baryCenter ); - double vol = bary.getVolume(); - CPPUNIT_ASSERT( ok ); - CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.005208 , vol, 1e-5); - CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.562500, baryCenter[0], 1e-5); - CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.125000, baryCenter[1], 1e-5); - CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.250000, baryCenter[2], 1e-5); - } - - struct __MESH_DUMMY - { - typedef int MyConnType; - }; - - void UnitTetraIntersectionBaryTest::test_UnitTetraIntersectionBary_13() - { - double T[] = { - 66.6666666666666714,133.333333333333343,66.6666666666666714, - 100,200,100, - 100,100,100, - 200,200,0 }; - - double S[] = { - 100,166.666666666666657,66.6666666666666714, - 100,150,50, - 75,150,75, - 100,100,100}; - - int conn[4] = { 0,1,2,3 }; - - const double* tnodes[4]={ T, T+3, T+6, T+9 }; - const double* snodes[4]={ S, S+3, S+6, S+9 }; - - __MESH_DUMMY dummyMesh; - SplitterTetra<__MESH_DUMMY> src( dummyMesh, snodes, conn ); - double volume = src.intersectTetra( tnodes ); - CPPUNIT_ASSERT_DOUBLES_EQUAL(6944.4444444444443,volume,1e-9); - } - - void UnitTetraIntersectionBaryTest::test_TetraAffineTransform_reverseApply() - { - double nodes[12] = { -4.0, 9.0, 3.0, - 11.0, 0.0, 2.0, - 0.0, 0.0, 0.0, - 2.0, 1.0,10.0 }; - // double pSrc[3] = { -4.0, 9.0, 3.0 }; - double pSrc[3] = { 40., -20., 100. }; - double pDest[] = {1,1,1}; - TetraAffineTransform a(nodes); - a.apply( pDest, pSrc ); - a.reverseApply( pDest, pDest ); - CPPUNIT_ASSERT_DOUBLES_EQUAL( pSrc[0], pDest[0], 1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL( pSrc[1], pDest[1], 1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL( pSrc[2], pDest[2], 1e-12); - } - - void UnitTetraIntersectionBaryTest::test_barycentric_coords() - { - // compute barycentric coordinates - double nodes[4][3] = { {11.0, 0.0, 2.0 }, - {-4.0, 9.0, 3.0 }, - { 0.0, 0.0, 0.0 }, - { 6.0, 1.0,10.0 }}; - std::vector n (4); - n[0] = &nodes[0][0]; - n[1] = &nodes[1][0]; - n[2] = &nodes[2][0]; - n[3] = &nodes[3][0]; - double p [3] = { 2, 2, 5 }, bc[4]; - barycentric_coords(n, p, bc); - double bcSum = 0; - double p2 [3] = { 0,0,0 }; - for ( int i = 0; i < 4; ++i ) { - bcSum += bc[i]; - p2[0] += bc[i]*n[i][0]; - p2[1] += bc[i]*n[i][1]; - p2[2] += bc[i]*n[i][2]; - } - CPPUNIT_ASSERT_DOUBLES_EQUAL( 1., bcSum, 1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL( p[0], p2[0], 1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL( p[1], p2[1], 1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL( p[2], p2[2], 1e-12); - } -} diff --git a/src/INTERP_KERNELTest/UnitTetraIntersectionBaryTest.hxx b/src/INTERP_KERNELTest/UnitTetraIntersectionBaryTest.hxx deleted file mode 100644 index 220da14bc..000000000 --- a/src/INTERP_KERNELTest/UnitTetraIntersectionBaryTest.hxx +++ /dev/null @@ -1,75 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 -// 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 -// - -// File : UnitTetraIntersectionBaryTests.hxx -// Created : Thu Nov 6 17:11:27 2008 -// Author : Edward AGAPOV (eap) -// -#ifndef __UNITTETRAINTERSECTIONBARYTEST_HXX__ -#define __UNITTETRAINTERSECTIONBARYTEST_HXX__ - -#include - -#include "InterpKernelTestExport.hxx" - -namespace INTERP_TEST -{ - /** - * \brief Test suite testing UnitTetraIntersectionBary class. - * - */ - class INTERPKERNELTEST_EXPORT UnitTetraIntersectionBaryTest : public CppUnit::TestFixture - { - CPPUNIT_TEST_SUITE( UnitTetraIntersectionBaryTest ); - CPPUNIT_TEST( test_UnitTetraIntersectionBary_13 ); - CPPUNIT_TEST( test_UnitTetraIntersectionBary_12 ); - CPPUNIT_TEST( test_UnitTetraIntersectionBary_1 ); - CPPUNIT_TEST( test_UnitTetraIntersectionBary_2 ); - CPPUNIT_TEST( test_UnitTetraIntersectionBary_3 ); - CPPUNIT_TEST( test_UnitTetraIntersectionBary_4 ); - CPPUNIT_TEST( test_UnitTetraIntersectionBary_5 ); - CPPUNIT_TEST( test_UnitTetraIntersectionBary_6 ); - CPPUNIT_TEST( test_UnitTetraIntersectionBary_7 ); - CPPUNIT_TEST( test_UnitTetraIntersectionBary_8 ); - CPPUNIT_TEST( test_UnitTetraIntersectionBary_9 ); - CPPUNIT_TEST( test_UnitTetraIntersectionBary_10 ); - CPPUNIT_TEST( test_UnitTetraIntersectionBary_11 ); - CPPUNIT_TEST( test_TetraAffineTransform_reverseApply ); - CPPUNIT_TEST( test_barycentric_coords ); - CPPUNIT_TEST_SUITE_END(); - public: - void test_UnitTetraIntersectionBary_1(); - void test_UnitTetraIntersectionBary_2(); - void test_UnitTetraIntersectionBary_3(); - void test_UnitTetraIntersectionBary_4(); - void test_UnitTetraIntersectionBary_5(); - void test_UnitTetraIntersectionBary_6(); - void test_UnitTetraIntersectionBary_7(); - void test_UnitTetraIntersectionBary_8(); - void test_UnitTetraIntersectionBary_9(); - void test_UnitTetraIntersectionBary_10(); - void test_UnitTetraIntersectionBary_11(); - void test_UnitTetraIntersectionBary_12(); - void test_UnitTetraIntersectionBary_13(); - void test_TetraAffineTransform_reverseApply(); - void test_barycentric_coords(); - }; -} - -#endif diff --git a/src/INTERP_KERNELTest/perf_test.py b/src/INTERP_KERNELTest/perf_test.py deleted file mode 100755 index 97f5579b0..000000000 --- a/src/INTERP_KERNELTest/perf_test.py +++ /dev/null @@ -1,146 +0,0 @@ -#! /bin/env python -# Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 -# 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 -# - -import re -import sys -import time -import subprocess - -RES_FILE="perf_OPTIMIZE" - -def test_pair(par1,par2): - c=re.compile("[\D]*(?P[\d]+)") - val1=c.match(par1).group("num") - val2=c.match(par2).group("num") - st="%s %s"%(val1,val2) - ret=subprocess.call(["./PerfTest",par1,par2]) - if ret!=0: - f=file(RES_FILE,"w") ; f.write("Error on case %s %s !!!!\n"%(par1,par2)) ; del f - sys.exit(ret) - pass - return st - -def test_box_box(): - st="PerfBox PerfBox\n" - st+=test_pair("PerfBox1495","PerfBox1495") - st+=test_pair("PerfBox2506","PerfBox2506") - st+=test_pair("PerfBox5708","PerfBox5708") - st+=test_pair("PerfBox13461","PerfBox13461") - st+=test_pair("PerfBox30808","PerfBox30808") - st+=test_pair("PerfBox47176","PerfBox47176") - st+=test_pair("PerfBox1495","PerfBox2506") - st+=test_pair("PerfBox1495","PerfBox5708") - st+=test_pair("PerfBox1495","PerfBox13461") - st+=test_pair("PerfBox1495","PerfBox30808") - st+=test_pair("PerfBox1495","PerfBox47176") - st+=test_pair("PerfBox2506","PerfBox5708") - st+=test_pair("PerfBox2506","PerfBox13461") - st+=test_pair("PerfBox2506","PerfBox30808") - st+=test_pair("PerfBox2506","PerfBox47176") - st+=test_pair("PerfBox5708","PerfBox13461") - st+=test_pair("PerfBox5708","PerfBox30808") - st+=test_pair("PerfBox5708","PerfBox47176") - st+=test_pair("PerfBox13461","PerfBox30808") - st+=test_pair("PerfBox13461","PerfBox47176") - st+=test_pair("PerfBox30808","PerfBox47176") - pass - -def test_cyl_cyl(): - st="PerfCyl PerfCyl\n" - st+=test_pair("PerfCyl1047","PerfCyl1047") - st+=test_pair("PerfCyl3020","PerfCyl3020") - st+=test_pair("PerfCyl6556","PerfCyl6556") - st+=test_pair("PerfCyl9766","PerfCyl9766") - st+=test_pair("PerfCyl25745","PerfCyl25745") - st+=test_pair("PerfCyl47601","PerfCyl47601") - st+=test_pair("PerfCyl1047","PerfCyl3020") - st+=test_pair("PerfCyl1047","PerfCyl6556") - st+=test_pair("PerfCyl1047","PerfCyl9766") - st+=test_pair("PerfCyl1047","PerfCyl25745") - st+=test_pair("PerfCyl1047","PerfCyl47601") - st+=test_pair("PerfCyl3020","PerfCyl6556") - st+=test_pair("PerfCyl3020","PerfCyl9766") - st+=test_pair("PerfCyl3020","PerfCyl25745") - st+=test_pair("PerfCyl3020","PerfCyl47601") - st+=test_pair("PerfCyl6556","PerfCyl9766") - st+=test_pair("PerfCyl6556","PerfCyl25745") - st+=test_pair("PerfCyl6556","PerfCyl47601") - st+=test_pair("PerfCyl9766","PerfCyl25745") - st+=test_pair("PerfCyl9766","PerfCyl47601") - st+=test_pair("PerfCyl25745","PerfCyl47601") - return st - -def test_box_cyl(): - st="PerfBox PerfCyl\n" - st+=test_pair("PerfBox1495","PerfCyl1047") - st+=test_pair("PerfBox1495","PerfCyl3020") - st+=test_pair("PerfBox1495","PerfCyl6556") - st+=test_pair("PerfBox1495","PerfCyl9766") - st+=test_pair("PerfBox1495","PerfCyl25745") - st+=test_pair("PerfBox1495","PerfCyl47601") - st+=test_pair("PerfBox2506","PerfCyl1047") - st+=test_pair("PerfBox2506","PerfCyl3020") - st+=test_pair("PerfBox2506","PerfCyl6556") - st+=test_pair("PerfBox2506","PerfCyl9766") - st+=test_pair("PerfBox2506","PerfCyl25745") - st+=test_pair("PerfBox2506","PerfCyl47601") - st+=test_pair("PerfBox5708","PerfCyl1047") - st+=test_pair("PerfBox5708","PerfCyl3020") - st+=test_pair("PerfBox5708","PerfCyl6556") - st+=test_pair("PerfBox5708","PerfCyl9766") - st+=test_pair("PerfBox5708","PerfCyl25745") - st+=test_pair("PerfBox5708","PerfCyl47601") - st+=test_pair("PerfBox13461","PerfCyl1047") - st+=test_pair("PerfBox13461","PerfCyl3020") - st+=test_pair("PerfBox13461","PerfCyl6556") - st+=test_pair("PerfBox13461","PerfCyl9766") - st+=test_pair("PerfBox13461","PerfCyl25745") - st+=test_pair("PerfBox13461","PerfCyl47601") - st+=test_pair("PerfBox30808","PerfCyl1047") - st+=test_pair("PerfBox30808","PerfCyl3020") - st+=test_pair("PerfBox30808","PerfCyl6556") - st+=test_pair("PerfBox30808","PerfCyl9766") - st+=test_pair("PerfBox30808","PerfCyl25745") - st+=test_pair("PerfBox30808","PerfCyl47601") - st+=test_pair("PerfBox47176","PerfCyl1047") - st+=test_pair("PerfBox47176","PerfCyl3020") - st+=test_pair("PerfBox47176","PerfCyl6556") - st+=test_pair("PerfBox47176","PerfCyl9766") - st+=test_pair("PerfBox47176","PerfCyl25745") - st+=test_pair("PerfBox47176","PerfCyl47601") - return st - -def test_box_transbox(): - st=" PerfBox PerfBoxT\n" - st+=test_pair("PerfBox1495","PerfBoxT1493") - st+=test_pair("PerfBox2506","PerfBoxT2676") - st+=test_pair("PerfBox5708","PerfBoxT5717") - st+=test_pair("PerfBox13461","PerfBoxT12469") - st+=test_pair("PerfBox30808","PerfBoxT29019") - st+=test_pair("PerfBox47176","PerfBoxT47278") - return st - -gm=time.strftime("%a. %B %H:%M:%S",gm).lower()+time.strftime(" CET %Y",gm) -st="PerfTest execution on %s\n"%(time.strftime("%a. %B %H:%M:%S",gm).lower()+time.strftime(" CET %Y",gm)) -st+=test_box_cyl() -st+=test_box_box() -st+=test_cyl_cyl() -st+=test_box_transbox() -f=file(RES_FILE,"w") diff --git a/src/INTERP_KERNELTest/perf_test.sh b/src/INTERP_KERNELTest/perf_test.sh deleted file mode 100755 index d65415e1d..000000000 --- a/src/INTERP_KERNELTest/perf_test.sh +++ /dev/null @@ -1,166 +0,0 @@ -#!/bin/bash -# Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 -# 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 -# - -# should be run from the build directory, so that ./PerfTest is available -# output file -# -RES_FILE=perf_OPTIMIZE - -#outputs lines of form : -#"no. source elems no. target elems user time" -function test_pair { - echo -n $1 | sed 's/\(PerfCyl\)\([0-9]*\)/\2/' | sed 's/\(PerfBoxT\)\([0-9]*\)/\2/' | sed 's/\(PerfBox\)\([0-9]*\)/\2/' >> $RES_FILE - echo -n " " >> $RES_FILE - echo -n $2 | sed 's/\(PerfCyl\)\([0-9]*\)/\2/' | sed 's/\(PerfBoxT\)\([0-9]*\)/\2/' | sed 's/\(PerfBox\)\([0-9]*\)/\2/' >> $RES_FILE - echo -n " " >> $RES_FILE - time -o $RES_FILE --append -f"%U" ./PerfTest $1 $2 - echo -} - -function test_box_box { -echo PerfBox PerfBox >> $RES_FILE - -test_pair PerfBox1495 PerfBox1495 -test_pair PerfBox2506 PerfBox2506 -test_pair PerfBox5708 PerfBox5708 -test_pair PerfBox13461 PerfBox13461 -test_pair PerfBox30808 PerfBox30808 -test_pair PerfBox47176 PerfBox47176 - -test_pair PerfBox1495 PerfBox2506 -test_pair PerfBox1495 PerfBox5708 -test_pair PerfBox1495 PerfBox13461 -test_pair PerfBox1495 PerfBox30808 -test_pair PerfBox1495 PerfBox47176 - -test_pair PerfBox2506 PerfBox5708 -test_pair PerfBox2506 PerfBox13461 -test_pair PerfBox2506 PerfBox30808 -test_pair PerfBox2506 PerfBox47176 - -test_pair PerfBox5708 PerfBox13461 -test_pair PerfBox5708 PerfBox30808 -test_pair PerfBox5708 PerfBox47176 - -test_pair PerfBox13461 PerfBox30808 -test_pair PerfBox13461 PerfBox47176 - -test_pair PerfBox30808 PerfBox47176 - -} - -function test_cyl_cyl { -echo PerfCyl PerfCyl >> $RES_FILE - -test_pair PerfCyl1047 PerfCyl1047 -test_pair PerfCyl3020 PerfCyl3020 -test_pair PerfCyl6556 PerfCyl6556 -test_pair PerfCyl9766 PerfCyl9766 -test_pair PerfCyl25745 PerfCyl25745 -test_pair PerfCyl47601 PerfCyl47601 - -test_pair PerfCyl1047 PerfCyl3020 -test_pair PerfCyl1047 PerfCyl6556 -test_pair PerfCyl1047 PerfCyl9766 -test_pair PerfCyl1047 PerfCyl25745 -test_pair PerfCyl1047 PerfCyl47601 - -test_pair PerfCyl3020 PerfCyl6556 -test_pair PerfCyl3020 PerfCyl9766 -test_pair PerfCyl3020 PerfCyl25745 -test_pair PerfCyl3020 PerfCyl47601 - -test_pair PerfCyl6556 PerfCyl9766 -test_pair PerfCyl6556 PerfCyl25745 -test_pair PerfCyl6556 PerfCyl47601 - -test_pair PerfCyl9766 PerfCyl25745 -test_pair PerfCyl9766 PerfCyl47601 - -test_pair PerfCyl25745 PerfCyl47601 - -} - -function test_box_cyl { - echo PerfBox PerfCyl >> $RES_FILE - test_pair PerfBox1495 PerfCyl1047 - test_pair PerfBox1495 PerfCyl3020 - test_pair PerfBox1495 PerfCyl6556 - test_pair PerfBox1495 PerfCyl9766 - test_pair PerfBox1495 PerfCyl25745 - test_pair PerfBox1495 PerfCyl47601 - - test_pair PerfBox2506 PerfCyl1047 - test_pair PerfBox2506 PerfCyl3020 - test_pair PerfBox2506 PerfCyl6556 - test_pair PerfBox2506 PerfCyl9766 - test_pair PerfBox2506 PerfCyl25745 - test_pair PerfBox2506 PerfCyl47601 - - test_pair PerfBox5708 PerfCyl1047 - test_pair PerfBox5708 PerfCyl3020 - test_pair PerfBox5708 PerfCyl6556 - test_pair PerfBox5708 PerfCyl9766 - test_pair PerfBox5708 PerfCyl25745 - test_pair PerfBox5708 PerfCyl47601 - - test_pair PerfBox13461 PerfCyl1047 - test_pair PerfBox13461 PerfCyl3020 - test_pair PerfBox13461 PerfCyl6556 - test_pair PerfBox13461 PerfCyl9766 - test_pair PerfBox13461 PerfCyl25745 - test_pair PerfBox13461 PerfCyl47601 - - test_pair PerfBox30808 PerfCyl1047 - test_pair PerfBox30808 PerfCyl3020 - test_pair PerfBox30808 PerfCyl6556 - test_pair PerfBox30808 PerfCyl9766 - test_pair PerfBox30808 PerfCyl25745 - test_pair PerfBox30808 PerfCyl47601 - - test_pair PerfBox47176 PerfCyl1047 - test_pair PerfBox47176 PerfCyl3020 - test_pair PerfBox47176 PerfCyl6556 - test_pair PerfBox47176 PerfCyl9766 - test_pair PerfBox47176 PerfCyl25745 - test_pair PerfBox47176 PerfCyl47601 -} - -function test_box_transbox { - echo PerfBox PerfBoxT >> $RES_FILE - test_pair PerfBox1495 PerfBoxT1493 - test_pair PerfBox2506 PerfBoxT2676 - test_pair PerfBox5708 PerfBoxT5717 - test_pair PerfBox13461 PerfBoxT12469 - test_pair PerfBox30808 PerfBoxT29019 - test_pair PerfBox47176 PerfBoxT47278 -} - - - -#functions to execute : - -echo PerfTest execution on `date` > $RES_FILE -test_box_cyl -test_box_box -test_cyl_cyl -test_box_transbox - -cat $RES_FILE \ No newline at end of file diff --git a/src/MEDCoupling/CMakeLists.txt b/src/MEDCoupling/CMakeLists.txt deleted file mode 100644 index 014f69a41..000000000 --- a/src/MEDCoupling/CMakeLists.txt +++ /dev/null @@ -1,83 +0,0 @@ -# Copyright (C) 2012-2015 CEA/DEN, EDF 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, 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 -# 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) - -IF(SALOME_BUILD_TESTS) - ADD_SUBDIRECTORY(Test) -ENDIF(SALOME_BUILD_TESTS) - -INCLUDE_DIRECTORIES( - ${CMAKE_CURRENT_BINARY_DIR}/../.. - ${CMAKE_CURRENT_SOURCE_DIR}/../INTERP_KERNEL - ${CMAKE_CURRENT_SOURCE_DIR}/../INTERP_KERNEL/Bases - ${CMAKE_CURRENT_SOURCE_DIR}/../INTERP_KERNEL/Geometric2D - ${CMAKE_CURRENT_SOURCE_DIR}/../INTERP_KERNEL/ExprEval - ${CMAKE_CURRENT_SOURCE_DIR}/../INTERP_KERNEL/GaussPoints - ) - -SET(medcoupling_SOURCES - MEDCouplingField.cxx - MEDCouplingFieldDouble.cxx - MEDCouplingUMesh.cxx - MEDCoupling1GTUMesh.cxx - MEDCouplingMemArray.cxx - MEDCouplingMemArrayChar.cxx - MEDCouplingTimeLabel.cxx - MEDCouplingCMesh.cxx - MEDCouplingIMesh.cxx - MEDCouplingCurveLinearMesh.cxx - MEDCouplingStructuredMesh.cxx - MEDCouplingTimeDiscretization.cxx - MEDCouplingFieldDiscretization.cxx - MEDCouplingRefCountObject.cxx - MEDCouplingPointSet.cxx - MEDCouplingFieldTemplate.cxx - MEDCouplingExtrudedMesh.cxx - MEDCouplingMesh.cxx - MEDCouplingGaussLocalization.cxx - MEDCouplingNatureOfField.cxx - MEDCouplingMultiFields.cxx - MEDCouplingDefinitionTime.cxx - MEDCouplingFieldOverTime.cxx - MEDCouplingCartesianAMRMesh.cxx - MEDCouplingAMRAttribute.cxx - MEDCouplingMatrix.cxx - MEDCouplingPartDefinition.cxx - MEDCouplingSkyLineArray.cxx - ) - -SET(medcouplingremapper_SOURCES - MEDCouplingRemapper.cxx - ) - -ADD_LIBRARY(medcoupling SHARED ${medcoupling_SOURCES}) -TARGET_LINK_LIBRARIES(medcoupling interpkernel) -INSTALL(TARGETS medcoupling EXPORT ${PROJECT_NAME}TargetGroup DESTINATION ${SALOME_INSTALL_LIBS}) - -ADD_LIBRARY(medcouplingremapper SHARED ${medcouplingremapper_SOURCES}) -TARGET_LINK_LIBRARIES(medcouplingremapper medcoupling) -INSTALL(TARGETS medcouplingremapper EXPORT ${PROJECT_NAME}TargetGroup DESTINATION ${SALOME_INSTALL_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} MEDCouplingNatureOfFieldEnum DESTINATION ${SALOME_INSTALL_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 deleted file mode 100644 index 813515ac8..000000000 --- a/src/MEDCoupling/MEDCoupling.hxx +++ /dev/null @@ -1,48 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 -// 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 _MEDCOUPLING_HXX_ -#define _MEDCOUPLING_HXX_ - -#ifdef WIN32 -# if defined medcoupling_EXPORTS -# define MEDCOUPLING_EXPORT __declspec( dllexport ) -# else -# define MEDCOUPLING_EXPORT __declspec( dllimport ) -# endif -#else -# define MEDCOUPLING_EXPORT -#endif - -#ifdef WIN32 -# if defined medcouplingremapper_EXPORTS -# define MEDCOUPLINGREMAPPER_EXPORT __declspec( dllexport ) -# else -# define MEDCOUPLINGREMAPPER_EXPORT __declspec( dllimport ) -# endif -#else -# define MEDCOUPLINGREMAPPER_EXPORT -#endif - -#ifdef WIN32 -#pragma warning( disable : 4290 ) -#endif - -#endif diff --git a/src/MEDCoupling/MEDCoupling1GTUMesh.cxx b/src/MEDCoupling/MEDCoupling1GTUMesh.cxx deleted file mode 100644 index 38eae7a7e..000000000 --- a/src/MEDCoupling/MEDCoupling1GTUMesh.cxx +++ /dev/null @@ -1,3740 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 -// 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 "MEDCoupling1GTUMesh.hxx" -#include "MEDCouplingUMesh.hxx" -#include "MEDCouplingFieldDouble.hxx" -#include "MEDCouplingCMesh.hxx" - -#include "SplitterTetra.hxx" -#include "DiameterCalculator.hxx" -#include "InterpKernelAutoPtr.hxx" - -using namespace ParaMEDMEM; - -const int MEDCoupling1SGTUMesh::HEXA8_FACE_PAIRS[6]={0,1,2,4,3,5}; - -MEDCoupling1GTUMesh::MEDCoupling1GTUMesh():_cm(0) -{ -} - -MEDCoupling1GTUMesh::MEDCoupling1GTUMesh(const std::string& name, const INTERP_KERNEL::CellModel& cm):_cm(&cm) -{ - setName(name); -} - -MEDCoupling1GTUMesh::MEDCoupling1GTUMesh(const MEDCoupling1GTUMesh& other, bool recDeepCpy):MEDCouplingPointSet(other,recDeepCpy),_cm(other._cm) -{ -} - -MEDCoupling1GTUMesh *MEDCoupling1GTUMesh::New(const std::string& name, INTERP_KERNEL::NormalizedCellType type) -{ - if(type==INTERP_KERNEL::NORM_ERROR) - throw INTERP_KERNEL::Exception("MEDCoupling1GTUMesh::New : NORM_ERROR is not a valid type to be used as base geometric type for a mesh !"); - const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(type); - if(!cm.isDynamic()) - return MEDCoupling1SGTUMesh::New(name,type); - else - return MEDCoupling1DGTUMesh::New(name,type); -} - -MEDCoupling1GTUMesh *MEDCoupling1GTUMesh::New(const MEDCouplingUMesh *m) -{ - if(!m) - throw INTERP_KERNEL::Exception("MEDCoupling1GTUMesh::New : input mesh is null !"); - std::set gts(m->getAllGeoTypes()); - if(gts.size()!=1) - throw INTERP_KERNEL::Exception("MEDCoupling1GTUMesh::New : input mesh must have exactly one geometric type !"); - const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(*gts.begin()); - if(!cm.isDynamic()) - return MEDCoupling1SGTUMesh::New(m); - else - return MEDCoupling1DGTUMesh::New(m); -} - -const INTERP_KERNEL::CellModel& MEDCoupling1GTUMesh::getCellModel() const -{ - return *_cm; -} - -INTERP_KERNEL::NormalizedCellType MEDCoupling1GTUMesh::getCellModelEnum() const -{ - return _cm->getEnum(); -} - -int MEDCoupling1GTUMesh::getMeshDimension() const -{ - return (int)_cm->getDimension(); -} - -/*! - * This method returns a newly allocated array containing cell ids (ascendingly sorted) whose geometric type are equal to type. - * This method does not throw exception if geometric type \a type is not in \a this. - * This method throws an INTERP_KERNEL::Exception if meshdimension of \b this is not equal to those of \b type. - * The coordinates array is not considered here. - * - * \param [in] type the geometric type - * \return cell ids in this having geometric type \a type. - */ -DataArrayInt *MEDCoupling1GTUMesh::giveCellsWithType(INTERP_KERNEL::NormalizedCellType type) const -{ - MEDCouplingAutoRefCountObjectPtr ret=DataArrayInt::New(); - if(type==getCellModelEnum()) - ret->alloc(getNumberOfCells(),1); - else - ret->alloc(0,1); - ret->iota(); - return ret.retn(); -} - -/*! - * Returns nb of cells having the geometric type \a type. No throw if no cells in \a this has the geometric type \a type. - */ -int MEDCoupling1GTUMesh::getNumberOfCellsWithType(INTERP_KERNEL::NormalizedCellType type) const -{ - return type==getCellModelEnum()?getNumberOfCells():0; -} - -/*! - * Returns a type of a cell by its id. - * \param [in] cellId - the id of the cell of interest. - * \return INTERP_KERNEL::NormalizedCellType - enumeration item describing the cell type. - * \throw If \a cellId is invalid. Valid range is [0, \a this->getNumberOfCells() ). - */ -INTERP_KERNEL::NormalizedCellType MEDCoupling1GTUMesh::getTypeOfCell(int cellId) const -{ - if(cellId>=0 && cellId - the set of cell types. - * \warning this method does not throw any exception even if \a this is not defined. - */ -std::set MEDCoupling1GTUMesh::getAllGeoTypes() const -{ - std::set ret; - ret.insert(getCellModelEnum()); - return ret; -} - -/*! - * This method expects that \a this is sorted by types. If not an exception will be thrown. - * This method returns in the same format as code (see MEDCouplingUMesh::checkTypeConsistencyAndContig or MEDCouplingUMesh::splitProfilePerType) how - * \a this is composed in cell types. - * The returned array is of size 3*n where n is the number of different types present in \a this. - * For every k in [0,n] ret[3*k+2]==-1 because it has no sense here. - * This parameter is kept only for compatibility with other methode listed above. - */ -std::vector MEDCoupling1GTUMesh::getDistributionOfTypes() const -{ - std::vector ret(3); - ret[0]=(int)getCellModelEnum(); ret[1]=getNumberOfCells(); ret[2]=-1; - return ret; -} - -/*! - * This method is the opposite of MEDCouplingUMesh::checkTypeConsistencyAndContig method. Given a list of cells in \a profile it returns a list of sub-profiles sorted by geo type. - * The result is put in the array \a idsPerType. In the returned parameter \a code, foreach i \a code[3*i+2] refers (if different from -1) to a location into the \a idsPerType. - * This method has 1 input \a profile and 3 outputs \a code \a idsInPflPerType and \a idsPerType. - * - * \param [out] code is a vector of size 3*n where n is the number of different geometric type in \a this \b reduced to the profile \a profile. \a code has exactly the same semantic than in MEDCouplingUMesh::checkTypeConsistencyAndContig method. - * \param [out] idsInPflPerType is a vector of size of different geometric type in the subpart defined by \a profile of \a this ( equal to \a code.size()/3). For each i, - * \a idsInPflPerType[i] stores the tuple ids in \a profile that correspond to the geometric type code[3*i+0] - * \param [out] idsPerType is a vector of size of different sub profiles needed to be defined to represent the profile \a profile for a given geometric type. - * This vector can be empty in case of all geometric type cells are fully covered in ascending in the given input \a profile. - * - * \warning for performance reasons no deep copy will be performed, if \a profile can been used as this in output parameters \a idsInPflPerType and \a idsPerType. - * - * \throw if \a profile has not exactly one component. It throws too, if \a profile contains some values not in [0,getNumberOfCells()) or if \a this is not fully defined - * - * \b Example1:
- * - Before \a this has 3 cells \a profile contains [0,1,2] - * - After \a code contains [NORM_...,nbCells,-1], \a idsInPflPerType [[0,1,2]] and \a idsPerType is empty
- * - * \b Example2:
- * - Before \a this has 3 cells \a profile contains [1,2] - * - After \a code contains [NORM_...,nbCells,0], \a idsInPflPerType [[0,1]] and \a idsPerType is [[1,2]]
- - */ -void MEDCoupling1GTUMesh::splitProfilePerType(const DataArrayInt *profile, std::vector& code, std::vector& idsInPflPerType, std::vector& idsPerType) const -{ - if(!profile) - throw INTERP_KERNEL::Exception("MEDCoupling1GTUMesh::splitProfilePerType : input profile is NULL !"); - if(profile->getNumberOfComponents()!=1) - throw INTERP_KERNEL::Exception("MEDCoupling1GTUMesh::splitProfilePerType : input profile should have exactly one component !"); - int nbTuples=profile->getNumberOfTuples(); - int nbOfCells=getNumberOfCells(); - code.resize(3); idsInPflPerType.resize(1); - code[0]=(int)getCellModelEnum(); code[1]=nbTuples; - idsInPflPerType.resize(1); - if(profile->isIdentity() && nbTuples==nbOfCells) - { - code[2]=-1; - idsInPflPerType[0]=const_cast(profile); idsInPflPerType[0]->incrRef(); - idsPerType.clear(); - return ; - } - code[2]=0; - profile->checkAllIdsInRange(0,nbOfCells); - idsPerType.resize(1); - idsPerType[0]=const_cast(profile); idsPerType[0]->incrRef(); - idsInPflPerType[0]=DataArrayInt::Range(0,nbTuples,1); -} - -/*! - * This method tries to minimize at most the number of deep copy. - * So if \a idsPerType is not empty it can be returned directly (without copy, but with ref count incremented) in return. - * - * \sa MEDCouplingUMesh::checkTypeConsistencyAndContig - */ -DataArrayInt *MEDCoupling1GTUMesh::checkTypeConsistencyAndContig(const std::vector& code, const std::vector& idsPerType) const -{ - int nbOfCells=getNumberOfCells(); - if(code.size()!=3) - throw INTERP_KERNEL::Exception("MEDCoupling1GTUMesh::checkTypeConsistencyAndContig : invalid input code should be exactly of size 3 !"); - if(code[0]!=(int)getCellModelEnum()) - { - std::ostringstream oss; oss << "MEDCoupling1GTUMesh::checkTypeConsistencyAndContig : Mismatch of geometric type ! Asking for " << code[0] << " whereas the geometric type is \a this is " << getCellModelEnum() << " (" << _cm->getRepr() << ") !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - if(code[2]==-1) - { - if(code[1]==nbOfCells) - return 0; - else - { - std::ostringstream oss; oss << "MEDCoupling1GTUMesh::checkTypeConsistencyAndContig : mismatch between the number of cells in this (" << nbOfCells << ") and the number of non profile (" << code[1] << ") !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - } - if(code[2]!=0) - throw INTERP_KERNEL::Exception("MEDCoupling1GTUMesh::checkTypeConsistencyAndContig : single geo type mesh ! 0 or -1 is expected at pos #2 of input code !"); - if(idsPerType.size()!=1) - throw INTERP_KERNEL::Exception("MEDCoupling1GTUMesh::checkTypeConsistencyAndContig : input code points to DataArrayInt #0 whereas the size of idsPerType is not equal to 1 !"); - const DataArrayInt *pfl=idsPerType[0]; - if(!pfl) - throw INTERP_KERNEL::Exception("MEDCoupling1GTUMesh::checkTypeConsistencyAndContig : the input code points to a NULL DataArrayInt at rank 0 !"); - if(pfl->getNumberOfComponents()!=1) - throw INTERP_KERNEL::Exception("MEDCoupling1GTUMesh::checkTypeConsistencyAndContig : input profile should have exactly one component !"); - pfl->checkAllIdsInRange(0,nbOfCells); - pfl->incrRef(); - return const_cast(pfl); -} - -void MEDCoupling1GTUMesh::writeVTKLL(std::ostream& ofs, const std::string& cellData, const std::string& pointData, DataArrayByte *byteData) const -{ - MEDCouplingAutoRefCountObjectPtr m=buildUnstructured(); - m->writeVTKLL(ofs,cellData,pointData,byteData); -} - -std::string MEDCoupling1GTUMesh::getVTKDataSetType() const -{ - return std::string("UnstructuredGrid"); -} - -std::string MEDCoupling1GTUMesh::getVTKFileExtension() const -{ - return std::string("vtu"); -} - -std::size_t MEDCoupling1GTUMesh::getHeapMemorySizeWithoutChildren() const -{ - return MEDCouplingPointSet::getHeapMemorySizeWithoutChildren(); -} - -bool MEDCoupling1GTUMesh::isEqualIfNotWhy(const MEDCouplingMesh *other, double prec, std::string& reason) const -{ - if(!MEDCouplingPointSet::isEqualIfNotWhy(other,prec,reason)) - return false; - if(!other) - throw INTERP_KERNEL::Exception("MEDCoupling1GTUMesh::isEqualIfNotWhy : input other pointer is null !"); - const MEDCoupling1GTUMesh *otherC=dynamic_cast(other); - if(!otherC) - { - reason="mesh given in input is not castable in MEDCouplingSGTUMesh !"; - return false; - } - if(_cm!=otherC->_cm) - { - reason="mismatch in geometric type !"; - return false; - } - return true; -} - -bool MEDCoupling1GTUMesh::isEqualWithoutConsideringStr(const MEDCouplingMesh *other, double prec) const -{ - if(!MEDCouplingPointSet::isEqualWithoutConsideringStr(other,prec)) - return false; - if(!other) - throw INTERP_KERNEL::Exception("MEDCoupling1GTUMesh::isEqualWithoutConsideringStr : input other pointer is null !"); - const MEDCoupling1GTUMesh *otherC=dynamic_cast(other); - if(!otherC) - return false; - if(_cm!=otherC->_cm) - return false; - return true; -} - -void MEDCoupling1GTUMesh::checkCoherency() const -{ - MEDCouplingPointSet::checkCoherency(); -} - -DataArrayDouble *MEDCoupling1GTUMesh::getBarycenterAndOwner() const -{ - MEDCouplingAutoRefCountObjectPtr m=buildUnstructured(); - MEDCouplingAutoRefCountObjectPtr ret=m->getBarycenterAndOwner(); - return ret.retn(); -} - -MEDCouplingFieldDouble *MEDCoupling1GTUMesh::getMeasureField(bool isAbs) const -{ - MEDCouplingAutoRefCountObjectPtr m=buildUnstructured(); - MEDCouplingAutoRefCountObjectPtr ret=m->getMeasureField(isAbs); - ret->setMesh(this); - return ret.retn(); -} - -MEDCouplingFieldDouble *MEDCoupling1GTUMesh::getMeasureFieldOnNode(bool isAbs) const -{ - MEDCouplingAutoRefCountObjectPtr m=buildUnstructured(); - MEDCouplingAutoRefCountObjectPtr ret=m->getMeasureFieldOnNode(isAbs); - ret->setMesh(this); - return ret.retn(); -} - -/*! - * to improve perf ! - */ -int MEDCoupling1GTUMesh::getCellContainingPoint(const double *pos, double eps) const -{ - MEDCouplingAutoRefCountObjectPtr m=buildUnstructured(); - return m->getCellContainingPoint(pos,eps); -} - -MEDCouplingFieldDouble *MEDCoupling1GTUMesh::buildOrthogonalField() const -{ - MEDCouplingAutoRefCountObjectPtr m=buildUnstructured(); - MEDCouplingAutoRefCountObjectPtr ret=m->buildOrthogonalField(); - ret->setMesh(this); - return ret.retn(); -} - -DataArrayInt *MEDCoupling1GTUMesh::getCellsInBoundingBox(const double *bbox, double eps) const -{ - MEDCouplingAutoRefCountObjectPtr m=buildUnstructured(); - return m->getCellsInBoundingBox(bbox,eps); -} - -DataArrayInt *MEDCoupling1GTUMesh::getCellsInBoundingBox(const INTERP_KERNEL::DirectedBoundingBox& bbox, double eps) -{ - MEDCouplingAutoRefCountObjectPtr m=buildUnstructured(); - return m->getCellsInBoundingBox(bbox,eps); -} - -MEDCouplingPointSet *MEDCoupling1GTUMesh::buildFacePartOfMySelfNode(const int *start, const int *end, bool fullyIn) const -{ - MEDCouplingAutoRefCountObjectPtr m=buildUnstructured(); - return m->buildFacePartOfMySelfNode(start,end,fullyIn); -} - -DataArrayInt *MEDCoupling1GTUMesh::findBoundaryNodes() const -{ - MEDCouplingAutoRefCountObjectPtr m=buildUnstructured(); - return m->findBoundaryNodes(); -} - -MEDCouplingPointSet *MEDCoupling1GTUMesh::buildBoundaryMesh(bool keepCoords) const -{ - MEDCouplingAutoRefCountObjectPtr m=buildUnstructured(); - return m->buildBoundaryMesh(keepCoords); -} - -void MEDCoupling1GTUMesh::findCommonCells(int compType, int startCellId, DataArrayInt *& commonCellsArr, DataArrayInt *& commonCellsIArr) const -{ - MEDCouplingAutoRefCountObjectPtr m=buildUnstructured(); - m->findCommonCells(compType,startCellId,commonCellsArr,commonCellsIArr); -} - -int MEDCoupling1GTUMesh::getNodalConnectivityLength() const -{ - const DataArrayInt *c1(getNodalConnectivity()); - if(!c1) - throw INTERP_KERNEL::Exception("MEDCoupling1GTUMesh::getNodalConnectivityLength : no connectivity set !"); - if(c1->getNumberOfComponents()!=1) - throw INTERP_KERNEL::Exception("MEDCoupling1GTUMesh::getNodalConnectivityLength : Nodal connectivity array set must have exactly one component !"); - if(!c1->isAllocated()) - throw INTERP_KERNEL::Exception("MEDCoupling1GTUMesh::getNodalConnectivityLength : Nodal connectivity array must be allocated !"); - return c1->getNumberOfTuples(); -} - -/*! - * This method aggregates all the meshes in \a parts to put them in a single unstructured mesh (those returned). - * The order of cells is the returned instance is those in the order of instances in \a parts. - * - * \param [in] parts - all not null parts of single geo type meshes to be aggreagated having the same mesh dimension and same coordinates. - * \return MEDCouplingUMesh * - new object to be dealt by the caller. - * - * \throw If one element is null in \a parts. - * \throw If not all the parts do not have the same mesh dimension. - * \throw If not all the parts do not share the same coordinates. - * \throw If not all the parts have their connectivity set properly. - * \throw If \a parts is empty. - */ -MEDCouplingUMesh *MEDCoupling1GTUMesh::AggregateOnSameCoordsToUMesh(const std::vector< const MEDCoupling1GTUMesh *>& parts) -{ - if(parts.empty()) - throw INTERP_KERNEL::Exception("MEDCoupling1GTUMesh::AggregateOnSameCoordsToUMesh : input parts vector is empty !"); - const MEDCoupling1GTUMesh *firstPart(parts[0]); - if(!firstPart) - throw INTERP_KERNEL::Exception("MEDCoupling1GTUMesh::AggregateOnSameCoordsToUMesh : the first instance in input parts is null !"); - const DataArrayDouble *coords(firstPart->getCoords()); - int meshDim(firstPart->getMeshDimension()); - MEDCouplingAutoRefCountObjectPtr ret(MEDCouplingUMesh::New(firstPart->getName(),meshDim)); ret->setDescription(firstPart->getDescription()); - ret->setCoords(coords); - int nbOfCells(0),connSize(0); - for(std::vector< const MEDCoupling1GTUMesh *>::const_iterator it=parts.begin();it!=parts.end();it++) - { - if(!(*it)) - throw INTERP_KERNEL::Exception("MEDCoupling1GTUMesh::AggregateOnSameCoordsToUMesh : presence of null pointer in input vector !"); - if((*it)->getMeshDimension()!=meshDim) - throw INTERP_KERNEL::Exception("MEDCoupling1GTUMesh::AggregateOnSameCoordsToUMesh : all the instances in input vector must have same mesh dimension !"); - if((*it)->getCoords()!=coords) - throw INTERP_KERNEL::Exception("MEDCoupling1GTUMesh::AggregateOnSameCoordsToUMesh : all the instances must share the same coordinates pointer !"); - nbOfCells+=(*it)->getNumberOfCells(); - connSize+=(*it)->getNodalConnectivityLength(); - } - MEDCouplingAutoRefCountObjectPtr conn(DataArrayInt::New()),connI(DataArrayInt::New()); - connI->alloc(nbOfCells+1,1); conn->alloc(connSize+nbOfCells,1); - int *c(conn->getPointer()),*ci(connI->getPointer()); *ci=0; - for(std::vector< const MEDCoupling1GTUMesh *>::const_iterator it=parts.begin();it!=parts.end();it++) - { - int curNbCells((*it)->getNumberOfCells()); - int geoType((int)(*it)->getCellModelEnum()); - const int *cinPtr((*it)->getNodalConnectivity()->begin()); - const MEDCoupling1SGTUMesh *ps(dynamic_cast(*it)); - const MEDCoupling1DGTUMesh *pd(dynamic_cast(*it)); - if(ps && !pd) - { - int nNodesPerCell(ps->getNumberOfNodesPerCell()); - for(int i=0;igetNodalConnectivityIndex()->begin()); - for(int i=0;isetConnectivity(conn,connI,true); - return ret.retn(); -} - -//== - -MEDCoupling1SGTUMesh::MEDCoupling1SGTUMesh(const MEDCoupling1SGTUMesh& other, bool recDeepCpy):MEDCoupling1GTUMesh(other,recDeepCpy),_conn(other._conn) -{ - if(recDeepCpy) - { - const DataArrayInt *c(other._conn); - if(c) - _conn=c->deepCpy(); - } -} - -MEDCoupling1SGTUMesh::MEDCoupling1SGTUMesh(const std::string& name, const INTERP_KERNEL::CellModel& cm):MEDCoupling1GTUMesh(name,cm) -{ -} - -MEDCoupling1SGTUMesh::MEDCoupling1SGTUMesh() -{ -} - -MEDCoupling1SGTUMesh *MEDCoupling1SGTUMesh::New() -{ - return new MEDCoupling1SGTUMesh; -} - -MEDCoupling1SGTUMesh *MEDCoupling1SGTUMesh::New(const std::string& name, INTERP_KERNEL::NormalizedCellType type) -{ - if(type==INTERP_KERNEL::NORM_ERROR) - throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::New : NORM_ERROR is not a valid type to be used as base geometric type for a mesh !"); - const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(type); - if(cm.isDynamic()) - { - std::ostringstream oss; oss << "MEDCoupling1SGTUMesh::New : the input geometric type " << cm.getRepr() << " is dynamic ! Only static types are allowed here !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - return new MEDCoupling1SGTUMesh(name,cm); -} - -MEDCoupling1SGTUMesh *MEDCoupling1SGTUMesh::New(const MEDCouplingUMesh *m) -{ - if(!m) - throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::New : input mesh is null !"); - std::set gts(m->getAllGeoTypes()); - if(gts.size()!=1) - throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::New : input mesh must have exactly one geometric type !"); - int geoType((int)*gts.begin()); - MEDCouplingAutoRefCountObjectPtr ret(MEDCoupling1SGTUMesh::New(m->getName(),*gts.begin())); - ret->setCoords(m->getCoords()); ret->setDescription(m->getDescription()); - int nbCells(m->getNumberOfCells()); - int nbOfNodesPerCell(ret->getNumberOfNodesPerCell()); - MEDCouplingAutoRefCountObjectPtr conn(DataArrayInt::New()); conn->alloc(nbCells*nbOfNodesPerCell,1); - int *c(conn->getPointer()); - const int *cin(m->getNodalConnectivity()->begin()),*ciin(m->getNodalConnectivityIndex()->begin()); - for(int i=0;isetNodalConnectivity(conn); - try - { ret->copyTinyInfoFrom(m); } - catch(INTERP_KERNEL::Exception&) { } - return ret.retn(); -} - -MEDCoupling1SGTUMesh *MEDCoupling1SGTUMesh::clone(bool recDeepCpy) const -{ - return new MEDCoupling1SGTUMesh(*this,recDeepCpy); -} - -/*! - * This method behaves mostly like MEDCoupling1SGTUMesh::deepCpy method, except that only nodal connectivity arrays are deeply copied. - * The coordinates are shared between \a this and the returned instance. - * - * \return MEDCouplingUMesh * - A new object instance holding the copy of \a this (deep for connectivity, shallow for coordiantes) - * \sa MEDCoupling1SGTUMesh::deepCpy - */ -MEDCouplingPointSet *MEDCoupling1SGTUMesh::deepCpyConnectivityOnly() const -{ - checkCoherency(); - MEDCouplingAutoRefCountObjectPtr ret(clone(false)); - MEDCouplingAutoRefCountObjectPtr c(_conn->deepCpy()); - ret->setNodalConnectivity(c); - return ret.retn(); -} - -void MEDCoupling1SGTUMesh::shallowCopyConnectivityFrom(const MEDCouplingPointSet *other) -{ - if(!other) - throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::shallowCopyConnectivityFrom : input pointer is null !"); - const MEDCoupling1SGTUMesh *otherC=dynamic_cast(other); - if(!otherC) - throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::shallowCopyConnectivityFrom : input pointer is not an MEDCoupling1SGTUMesh instance !"); - setNodalConnectivity(otherC->getNodalConnectivity()); -} - -void MEDCoupling1SGTUMesh::updateTime() const -{ - MEDCoupling1GTUMesh::updateTime(); - const DataArrayInt *c(_conn); - if(c) - updateTimeWith(*c); -} - -std::size_t MEDCoupling1SGTUMesh::getHeapMemorySizeWithoutChildren() const -{ - return MEDCoupling1GTUMesh::getHeapMemorySizeWithoutChildren(); -} - -std::vector MEDCoupling1SGTUMesh::getDirectChildrenWithNull() const -{ - std::vector ret(MEDCoupling1GTUMesh::getDirectChildrenWithNull()); - ret.push_back((const DataArrayInt *)_conn); - return ret; -} - -MEDCouplingMesh *MEDCoupling1SGTUMesh::deepCpy() const -{ - return clone(true); -} - -bool MEDCoupling1SGTUMesh::isEqualIfNotWhy(const MEDCouplingMesh *other, double prec, std::string& reason) const -{ - if(!other) - throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::isEqualIfNotWhy : input other pointer is null !"); - std::ostringstream oss; oss.precision(15); - const MEDCoupling1SGTUMesh *otherC=dynamic_cast(other); - if(!otherC) - { - reason="mesh given in input is not castable in MEDCoupling1SGTUMesh !"; - return false; - } - if(!MEDCoupling1GTUMesh::isEqualIfNotWhy(other,prec,reason)) - return false; - const DataArrayInt *c1(_conn),*c2(otherC->_conn); - if(c1==c2) - return true; - if(!c1 || !c2) - { - reason="in connectivity of single static geometric type exactly one among this and other is null !"; - return false; - } - if(!c1->isEqualIfNotWhy(*c2,reason)) - { - reason.insert(0,"Nodal connectivity DataArrayInt differ : "); - return false; - } - return true; -} - -bool MEDCoupling1SGTUMesh::isEqualWithoutConsideringStr(const MEDCouplingMesh *other, double prec) const -{ - if(!other) - throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::isEqualWithoutConsideringStr : input other pointer is null !"); - const MEDCoupling1SGTUMesh *otherC=dynamic_cast(other); - if(!otherC) - return false; - if(!MEDCoupling1GTUMesh::isEqualWithoutConsideringStr(other,prec)) - return false; - const DataArrayInt *c1(_conn),*c2(otherC->_conn); - if(c1==c2) - return true; - if(!c1 || !c2) - return false; - if(!c1->isEqualWithoutConsideringStr(*c2)) - return false; - return true; -} - -void MEDCoupling1SGTUMesh::checkCoherencyOfConnectivity() const -{ - const DataArrayInt *c1(_conn); - if(c1) - { - if(c1->getNumberOfComponents()!=1) - throw INTERP_KERNEL::Exception("Nodal connectivity array is expected to be with number of components set to one !"); - if(c1->getInfoOnComponent(0)!="") - throw INTERP_KERNEL::Exception("Nodal connectivity array is expected to have no info on its single component !"); - c1->checkAllocated(); - } - else - throw INTERP_KERNEL::Exception("Nodal connectivity array not defined !"); -} - -void MEDCoupling1SGTUMesh::checkCoherency() const -{ - MEDCouplingPointSet::checkCoherency(); - checkCoherencyOfConnectivity(); -} - -void MEDCoupling1SGTUMesh::checkCoherency1(double eps) const -{ - checkCoherency(); - const DataArrayInt *c1(_conn); - int nbOfTuples=c1->getNumberOfTuples(); - int nbOfNodesPerCell=(int)_cm->getNumberOfNodes(); - if(nbOfTuples%nbOfNodesPerCell!=0) - { - std::ostringstream oss; oss << "MEDCoupling1SGTUMesh::checkCoherency1 : the nb of tuples in conn is " << nbOfTuples << " and number of nodes per cell is " << nbOfNodesPerCell << ". But " << nbOfTuples << "%" << nbOfNodesPerCell << " !=0 !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - int nbOfNodes=getNumberOfNodes(); - int nbOfCells=nbOfTuples/nbOfNodesPerCell; - const int *w(c1->begin()); - for(int i=0;i=nbOfNodes) - { - std::ostringstream oss; oss << "At node #" << j << " of cell #" << i << ", is equal to " << *w << " must be in [0," << nbOfNodes << ") !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - } -} - -void MEDCoupling1SGTUMesh::checkCoherency2(double eps) const -{ - checkCoherency1(eps); -} - -int MEDCoupling1SGTUMesh::getNumberOfCells() const -{ - int nbOfTuples=getNodalConnectivityLength(); - int nbOfNodesPerCell=getNumberOfNodesPerCell(); - if(nbOfTuples%nbOfNodesPerCell!=0) - { - std::ostringstream oss; oss << "MEDCoupling1SGTUMesh:getNumberOfCells: : the nb of tuples in conn is " << nbOfTuples << " and number of nodes per cell is " << nbOfNodesPerCell << ". But " << nbOfTuples << "%" << nbOfNodesPerCell << " !=0 !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - return nbOfTuples/nbOfNodesPerCell; -} - -int MEDCoupling1SGTUMesh::getNumberOfNodesInCell(int cellId) const -{ - return getNumberOfNodesPerCell(); -} - -int MEDCoupling1SGTUMesh::getNumberOfNodesPerCell() const -{ - checkNonDynamicGeoType(); - return (int)_cm->getNumberOfNodes(); -} - -DataArrayInt *MEDCoupling1SGTUMesh::computeNbOfNodesPerCell() const -{ - checkNonDynamicGeoType(); - MEDCouplingAutoRefCountObjectPtr ret=DataArrayInt::New(); - ret->alloc(getNumberOfCells(),1); - ret->fillWithValue((int)_cm->getNumberOfNodes()); - return ret.retn(); -} - -DataArrayInt *MEDCoupling1SGTUMesh::computeNbOfFacesPerCell() const -{ - checkNonDynamicGeoType(); - MEDCouplingAutoRefCountObjectPtr ret=DataArrayInt::New(); - ret->alloc(getNumberOfCells(),1); - ret->fillWithValue((int)_cm->getNumberOfSons()); - return ret.retn(); -} - -DataArrayInt *MEDCoupling1SGTUMesh::computeEffectiveNbOfNodesPerCell() const -{ - checkNonDynamicGeoType(); - MEDCouplingAutoRefCountObjectPtr ret=DataArrayInt::New(); - int nbCells(getNumberOfCells()); - ret->alloc(nbCells,1); - int *retPtr(ret->getPointer()); - int nbNodesPerCell(getNumberOfNodesPerCell()); - const int *conn(_conn->begin()); - for(int i=0;i s(conn,conn+nbNodesPerCell); - *retPtr=(int)s.size(); - } - return ret.retn(); -} - -void MEDCoupling1SGTUMesh::getNodeIdsOfCell(int cellId, std::vector& conn) const -{ - int sz=getNumberOfNodesPerCell(); - conn.resize(sz); - if(cellId>=0 && cellIdbegin()+cellId*sz,_conn->begin()+(cellId+1)*sz,conn.begin()); - else - { - std::ostringstream oss; oss << "MEDCoupling1SGTUMesh::getNodeIdsOfCell : request for cellId #" << cellId << " must be in [0," << getNumberOfCells() << ") !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } -} - -void MEDCoupling1SGTUMesh::checkNonDynamicGeoType() const -{ - if(_cm->isDynamic()) - throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::checkNonDynamicGeoType : internal error ! the internal geo type is dynamic ! should be static !"); -} - -std::string MEDCoupling1SGTUMesh::simpleRepr() const -{ - static const char msg0[]="No coordinates specified !"; - std::ostringstream ret; - ret << "Single static geometic type (" << _cm->getRepr() << ") unstructured 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 << "Mesh dimension : " << getMeshDimension() << "\nSpace dimension : "; - if(_coords!=0) - { - const int spaceDim=getSpaceDimension(); - ret << spaceDim << "\nInfo attached on space dimension : "; - for(int i=0;igetInfoOnComponent(i) << "\" "; - ret << "\n"; - } - else - ret << msg0 << "\n"; - ret << "Number of nodes : "; - if(_coords!=0) - ret << getNumberOfNodes() << "\n"; - else - ret << msg0 << "\n"; - ret << "Number of cells : "; - if((const DataArrayInt *)_conn) - { - if(_conn->isAllocated()) - { - if(_conn->getNumberOfComponents()==1) - ret << getNumberOfCells() << "\n"; - else - ret << "Nodal connectivity array specified and allocated but with not exactly one component !" << "\n"; - } - else - ret << "Nodal connectivity array specified but not allocated !" << "\n"; - } - else - ret << "No connectivity specified !" << "\n"; - ret << "Cell type : " << _cm->getRepr() << "\n"; - return ret.str(); -} - -std::string MEDCoupling1SGTUMesh::advancedRepr() const -{ - std::ostringstream ret; - ret << simpleRepr(); - ret << "\nCoordinates array : \n___________________\n\n"; - if(_coords) - _coords->reprWithoutNameStream(ret); - else - ret << "No array set !\n"; - ret << "\n\nConnectivity array : \n____________________\n\n"; - // - if((const DataArrayInt *)_conn) - { - if(_conn->isAllocated()) - { - if(_conn->getNumberOfComponents()==1) - { - int nbOfCells=getNumberOfCells(); - int sz=getNumberOfNodesPerCell(); - const int *connPtr=_conn->begin(); - for(int i=0;i(ret," ")); - ret << "\n"; - } - } - else - ret << "Nodal connectivity array specified and allocated but with not exactly one component !" << "\n"; - } - else - ret << "Nodal connectivity array specified but not allocated !" << "\n"; - } - else - ret << "No connectivity specified !" << "\n"; - return ret.str(); -} - -DataArrayDouble *MEDCoupling1SGTUMesh::computeIsoBarycenterOfNodesPerCell() const -{ - MEDCouplingAutoRefCountObjectPtr ret=DataArrayDouble::New(); - int spaceDim=getSpaceDimension(); - int nbOfCells=getNumberOfCells();//checkCoherency() - int nbOfNodes=getNumberOfNodes(); - ret->alloc(nbOfCells,spaceDim); - double *ptToFill=ret->getPointer(); - const double *coor=_coords->begin(); - const int *nodal=_conn->begin(); - int sz=getNumberOfNodesPerCell(); - double coeff=1./(double)sz; - for(int i=0;i=0 && *nodal()); - else - { - std::ostringstream oss; oss << "MEDCoupling1SGTUMesh::computeIsoBarycenterOfNodesPerCell : on cell #" << i << " presence of nodeId #" << *nodal << " should be in [0," << nbOfNodes << ") !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - std::transform(ptToFill,ptToFill+spaceDim,ptToFill,std::bind2nd(std::multiplies(),coeff)); - } - return ret.retn(); -} - -void MEDCoupling1SGTUMesh::renumberCells(const int *old2NewBg, bool check) -{ - int nbCells=getNumberOfCells(); - MEDCouplingAutoRefCountObjectPtr o2n=DataArrayInt::New(); - o2n->useArray(old2NewBg,false,C_DEALLOC,nbCells,1); - if(check) - o2n=o2n->checkAndPreparePermutation(); - // - const int *conn=_conn->begin(); - MEDCouplingAutoRefCountObjectPtr n2o=o2n->invertArrayO2N2N2O(nbCells); - const int *n2oPtr=n2o->begin(); - MEDCouplingAutoRefCountObjectPtr newConn=DataArrayInt::New(); - newConn->alloc(_conn->getNumberOfTuples(),1); - newConn->copyStringInfoFrom(*_conn); - int sz=getNumberOfNodesPerCell(); - // - int *newC=newConn->getPointer(); - for(int i=0;i cellIdsKept=DataArrayInt::New(); cellIdsKept->alloc(0,1); - int tmp=-1; - int sz=_conn->getMaxValue(tmp); sz=std::max(sz,0)+1; - std::vector fastFinder(sz,false); - for(const int *work=begin;work!=end;work++) - if(*work>=0 && *workbegin(); - int nbNodesPerCell=getNumberOfNodesPerCell(); - for(int i=0;i=0) - { - ref++; - if(fastFinder[conn[j]]) - nbOfHit++; - } - if((ref==nbOfHit && fullyIn) || (nbOfHit!=0 && !fullyIn)) - cellIdsKept->pushBackSilent(i); - } - cellIdsKeptArr=cellIdsKept.retn(); -} - -MEDCouplingMesh *MEDCoupling1SGTUMesh::mergeMyselfWith(const MEDCouplingMesh *other) const -{ - if(other->getType()!=SINGLE_STATIC_GEO_TYPE_UNSTRUCTURED) - throw INTERP_KERNEL::Exception("Merge of umesh only available with umesh single static geo type each other !"); - const MEDCoupling1SGTUMesh *otherC=static_cast(other); - return Merge1SGTUMeshes(this,otherC); -} - -MEDCouplingUMesh *MEDCoupling1SGTUMesh::buildUnstructured() const -{ - MEDCouplingAutoRefCountObjectPtr ret=MEDCouplingUMesh::New(getName(),getMeshDimension()); - ret->setCoords(getCoords()); - const int *nodalConn=_conn->begin(); - int nbCells=getNumberOfCells(); - int nbNodesPerCell=getNumberOfNodesPerCell(); - int geoType=(int)getCellModelEnum(); - MEDCouplingAutoRefCountObjectPtr c=DataArrayInt::New(); c->alloc(nbCells*(nbNodesPerCell+1),1); - int *cPtr=c->getPointer(); - for(int i=0;i cI=DataArrayInt::Range(0,(nbCells+1)*(nbNodesPerCell+1),nbNodesPerCell+1); - ret->setConnectivity(c,cI,true); - try - { ret->copyTinyInfoFrom(this); } - catch(INTERP_KERNEL::Exception&) { } - return ret.retn(); -} - -DataArrayInt *MEDCoupling1SGTUMesh::simplexize(int policy) -{ - switch(policy) - { - case 0: - return simplexizePol0(); - case 1: - return simplexizePol1(); - case (int) INTERP_KERNEL::PLANAR_FACE_5: - return simplexizePlanarFace5(); - case (int) INTERP_KERNEL::PLANAR_FACE_6: - return simplexizePlanarFace6(); - default: - throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::simplexize : unrecognized policy ! Must be :\n - 0 or 1 (only available for meshdim=2) \n - PLANAR_FACE_5, PLANAR_FACE_6 (only for meshdim=3)"); - } -} - -/// @cond INTERNAL - -struct MEDCouplingAccVisit -{ - MEDCouplingAccVisit():_new_nb_of_nodes(0) { } - int operator()(int val) { if(val!=-1) return _new_nb_of_nodes++; else return -1; } - int _new_nb_of_nodes; -}; - -/// @endcond - -/*! - * This method returns all node ids used in \b this. The data array returned has to be dealt by the caller. - * The returned node ids are sortes ascendingly. This method is closed to MEDCoupling1SGTUMesh::getNodeIdsInUse except - * the format of returned DataArrayInt instance. - * - * \return a newly allocated DataArrayInt sorted ascendingly of fetched node ids. - * \sa MEDCoupling1SGTUMesh::getNodeIdsInUse, areAllNodesFetched - */ -DataArrayInt *MEDCoupling1SGTUMesh::computeFetchedNodeIds() const -{ - checkCoherencyOfConnectivity(); - int nbNodes(getNumberOfNodes()); - std::vector fetchedNodes(nbNodes,false); - computeNodeIdsAlg(fetchedNodes); - int sz((int)std::count(fetchedNodes.begin(),fetchedNodes.end(),true)); - MEDCouplingAutoRefCountObjectPtr ret(DataArrayInt::New()); ret->alloc(sz,1); - int *retPtr(ret->getPointer()); - for(int i=0;igetNumberOfNodes(). It holds for each node of \a this mesh either -1 - * if the node is unused or a new id else. The caller is to delete this - * array using decrRef() as it is no more needed. - * \throw If the coordinates array is not set. - * \throw If the nodal connectivity of cells is not defined. - * \throw If the nodal connectivity includes an invalid id. - * \sa MEDCoupling1SGTUMesh::computeFetchedNodeIds, areAllNodesFetched - */ -DataArrayInt *MEDCoupling1SGTUMesh::getNodeIdsInUse(int& nbrOfNodesInUse) const -{ - nbrOfNodesInUse=-1; - int nbOfNodes=getNumberOfNodes(); - int nbOfCells=getNumberOfCells(); - MEDCouplingAutoRefCountObjectPtr ret(DataArrayInt::New()); - ret->alloc(nbOfNodes,1); - int *traducer=ret->getPointer(); - std::fill(traducer,traducer+nbOfNodes,-1); - const int *conn=_conn->begin(); - int nbNodesPerCell=getNumberOfNodesPerCell(); - for(int i=0;i=0 && *connapplyLin(1,offset); - updateTime(); -} - -/*! - * Same than renumberNodesInConn(const int *) except that here the format of old-to-new traducer is using map instead - * of array. This method is dedicated for renumbering from a big set of nodes the a tiny set of nodes which is the case during extraction - * of a big mesh. - */ -void MEDCoupling1SGTUMesh::renumberNodesInConn(const INTERP_KERNEL::HashMap& newNodeNumbersO2N) -{ - getNumberOfCells();//only to check that all is well defined. - int *begPtr(_conn->getPointer()); - int nbElt(_conn->getNumberOfTuples()); - int *endPtr(begPtr+nbElt); - for(int *it=begPtr;it!=endPtr;it++) - { - INTERP_KERNEL::HashMap::const_iterator it2(newNodeNumbersO2N.find(*it)); - if(it2!=newNodeNumbersO2N.end()) - { - *it=(*it2).second; - } - else - { - std::ostringstream oss; oss << "MEDCoupling1SGTUMesh::renumberNodesInConn : At pos #" << std::distance(begPtr,it) << " of nodal connectivity value is " << *it << ". Not in map !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - } - updateTime(); -} - -/*! - * Changes ids of nodes within the nodal connectivity arrays according to a permutation - * array in "Old to New" mode. The node coordinates array is \b not changed by this method. - * This method is a generalization of shiftNodeNumbersInConn(). - * \warning This method performs no check of validity of new ids. **Use it with care !** - * \param [in] newNodeNumbersO2N - a permutation array, of length \a - * this->getNumberOfNodes(), in "Old to New" mode. - * See \ref numbering for more info on renumbering modes. - * \throw If the nodal connectivity of cells is not defined. - */ -void MEDCoupling1SGTUMesh::renumberNodesInConn(const int *newNodeNumbersO2N) -{ - getNumberOfCells();//only to check that all is well defined. - _conn->transformWithIndArr(newNodeNumbersO2N,newNodeNumbersO2N+getNumberOfNodes()); - updateTime(); -} - -MEDCoupling1SGTUMesh *MEDCoupling1SGTUMesh::Merge1SGTUMeshes(const MEDCoupling1SGTUMesh *mesh1, const MEDCoupling1SGTUMesh *mesh2) -{ - std::vector tmp(2); - tmp[0]=const_cast(mesh1); tmp[1]=const_cast(mesh2); - return Merge1SGTUMeshes(tmp); -} - -MEDCoupling1SGTUMesh *MEDCoupling1SGTUMesh::Merge1SGTUMeshes(std::vector& a) -{ - std::size_t sz=a.size(); - if(sz==0) - return Merge1SGTUMeshesLL(a); - for(std::size_t ii=0;iigetCellModel()); - for(std::size_t ii=0;iigetCellModel())!=cm) - throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::Merge1SGTUMeshes : all items must have the same geo type !"); - std::vector< MEDCouplingAutoRefCountObjectPtr > bb(sz); - std::vector< const MEDCoupling1SGTUMesh * > aa(sz); - int spaceDim=-3; - for(std::size_t i=0;igetCoords(); - if(coo) - spaceDim=coo->getNumberOfComponents(); - } - if(spaceDim==-3) - throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::Merge1SGTUMeshes : no spaceDim specified ! unable to perform merge !"); - for(std::size_t i=0;ibuildSetInstanceFromThis(spaceDim); - aa[i]=bb[i]; - } - return Merge1SGTUMeshesLL(aa); -} - -/*! - * \throw If presence of a null instance in the input vector \a a. - * \throw If a is empty - */ -MEDCoupling1SGTUMesh *MEDCoupling1SGTUMesh::Merge1SGTUMeshesOnSameCoords(std::vector& a) -{ - if(a.empty()) - throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::Merge1SGTUMeshesOnSameCoords : input array must be NON EMPTY !"); - std::vector::const_iterator it=a.begin(); - if(!(*it)) - throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::Merge1SGTUMeshesOnSameCoords : null instance in the first element of input vector !"); - std::vector ncs(a.size()); - (*it)->getNumberOfCells();//to check that all is OK - const DataArrayDouble *coords=(*it)->getCoords(); - const INTERP_KERNEL::CellModel *cm=&((*it)->getCellModel()); - ncs[0]=(*it)->getNodalConnectivity(); - it++; - for(int i=1;it!=a.end();i++,it++) - { - if(!(*it)) - throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::Merge1SGTUMeshesOnSameCoords : presence of a null instance in the input vector !"); - if(cm!=&((*it)->getCellModel())) - throw INTERP_KERNEL::Exception("Geometric types mismatches, Merge1SGTUMeshes impossible !"); - (*it)->getNumberOfCells();//to check that all is OK - ncs[i]=(*it)->getNodalConnectivity(); - if(coords!=(*it)->getCoords()) - throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::Merge1SGTUMeshesOnSameCoords : not lying on same coords !"); - } - MEDCouplingAutoRefCountObjectPtr ret(new MEDCoupling1SGTUMesh("merge",*cm)); - ret->setCoords(coords); - ret->_conn=DataArrayInt::Aggregate(ncs); - return ret.retn(); -} - -/*! - * Assume that all instances in \a a are non null. If null it leads to a crash. That's why this method is assigned to be low level (LL) - */ -MEDCoupling1SGTUMesh *MEDCoupling1SGTUMesh::Merge1SGTUMeshesLL(std::vector& a) -{ - if(a.empty()) - throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::Merge1SGTUMeshes : input array must be NON EMPTY !"); - std::vector::const_iterator it=a.begin(); - int nbOfCells=(*it)->getNumberOfCells(); - const INTERP_KERNEL::CellModel *cm=&((*it)->getCellModel()); - int nbNodesPerCell=(*it)->getNumberOfNodesPerCell(); - it++; - for(;it!=a.end();it++) - { - if(cm!=&((*it)->getCellModel())) - throw INTERP_KERNEL::Exception("Geometric types mismatches, Merge1SGTUMeshes impossible !"); - nbOfCells+=(*it)->getNumberOfCells(); - } - std::vector aps(a.size()); - std::copy(a.begin(),a.end(),aps.begin()); - MEDCouplingAutoRefCountObjectPtr pts=MergeNodesArray(aps); - MEDCouplingAutoRefCountObjectPtr ret(new MEDCoupling1SGTUMesh("merge",*cm)); - ret->setCoords(pts); - MEDCouplingAutoRefCountObjectPtr c=DataArrayInt::New(); - c->alloc(nbOfCells*nbNodesPerCell,1); - int *cPtr=c->getPointer(); - int offset=0; - for(it=a.begin();it!=a.end();it++) - { - int curConnLgth=(*it)->getNodalConnectivityLength(); - const int *curC=(*it)->_conn->begin(); - cPtr=std::transform(curC,curC+curConnLgth,cPtr,std::bind2nd(std::plus(),offset)); - offset+=(*it)->getNumberOfNodes(); - } - // - ret->setNodalConnectivity(c); - return ret.retn(); -} - -MEDCouplingPointSet *MEDCoupling1SGTUMesh::buildPartOfMySelfKeepCoords(const int *begin, const int *end) const -{ - int ncell=getNumberOfCells(); - MEDCouplingAutoRefCountObjectPtr ret(new MEDCoupling1SGTUMesh(getName(),*_cm)); - ret->setCoords(_coords); - std::size_t nbOfElemsRet=std::distance(begin,end); - const int *inConn=_conn->getConstPointer(); - int sz=getNumberOfNodesPerCell(); - MEDCouplingAutoRefCountObjectPtr connRet=DataArrayInt::New(); connRet->alloc((int)nbOfElemsRet*sz,1); - int *connPtr=connRet->getPointer(); - for(const int *work=begin;work!=end;work++,connPtr+=sz) - { - if(*work>=0 && *work_conn=connRet; - ret->copyTinyInfoFrom(this); - return ret.retn(); -} - -MEDCouplingPointSet *MEDCoupling1SGTUMesh::buildPartOfMySelfKeepCoords2(int start, int end, int step) const -{ - int ncell=getNumberOfCells(); - int nbOfElemsRet=DataArray::GetNumberOfItemGivenBESRelative(start,end,step,"MEDCoupling1SGTUMesh::buildPartOfMySelfKeepCoords2 : "); - MEDCouplingAutoRefCountObjectPtr ret(new MEDCoupling1SGTUMesh(getName(),*_cm)); - ret->setCoords(_coords); - const int *inConn=_conn->getConstPointer(); - int sz=getNumberOfNodesPerCell(); - MEDCouplingAutoRefCountObjectPtr connRet=DataArrayInt::New(); connRet->alloc((int)nbOfElemsRet*sz,1); - int *connPtr=connRet->getPointer(); - int curId=start; - for(int i=0;i=0 && curId_conn=connRet; - ret->copyTinyInfoFrom(this); - return ret.retn(); -} - -void MEDCoupling1SGTUMesh::computeNodeIdsAlg(std::vector& nodeIdsInUse) const -{ - int sz((int)nodeIdsInUse.size()); - for(const int *conn=_conn->begin();conn!=_conn->end();conn++) - { - if(*conn>=0 && *connbegin(),conn) << " value is " << *conn << " must be in [0," << sz << ") !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - } -} - -MEDCoupling1SGTUMesh *MEDCoupling1SGTUMesh::buildSetInstanceFromThis(int spaceDim) const -{ - MEDCouplingAutoRefCountObjectPtr ret(new MEDCoupling1SGTUMesh(getName(),*_cm)); - MEDCouplingAutoRefCountObjectPtr tmp1; - const DataArrayInt *nodalConn(_conn); - if(!nodalConn) - { - tmp1=DataArrayInt::New(); tmp1->alloc(0,1); - } - else - tmp1=_conn; - ret->_conn=tmp1; - if(!_coords) - { - MEDCouplingAutoRefCountObjectPtr coords=DataArrayDouble::New(); coords->alloc(0,spaceDim); - ret->setCoords(coords); - } - else - ret->setCoords(_coords); - return ret.retn(); -} - -DataArrayInt *MEDCoupling1SGTUMesh::simplexizePol0() -{ - int nbOfCells=getNumberOfCells(); - if(getCellModelEnum()!=INTERP_KERNEL::NORM_QUAD4) - return DataArrayInt::Range(0,nbOfCells,1); - MEDCouplingAutoRefCountObjectPtr newConn=DataArrayInt::New(); newConn->alloc(2*3*nbOfCells,1); - MEDCouplingAutoRefCountObjectPtr ret=DataArrayInt::New(); ret->alloc(2*nbOfCells,1); - const int *c(_conn->begin()); - int *retPtr(ret->getPointer()),*newConnPtr(newConn->getPointer()); - for(int i=0;i newConn=DataArrayInt::New(); newConn->alloc(2*3*nbOfCells,1); - MEDCouplingAutoRefCountObjectPtr ret=DataArrayInt::New(); ret->alloc(2*nbOfCells,1); - const int *c(_conn->begin()); - int *retPtr(ret->getPointer()),*newConnPtr(newConn->getPointer()); - for(int i=0;i newConn=DataArrayInt::New(); newConn->alloc(5*4*nbOfCells,1); - MEDCouplingAutoRefCountObjectPtr ret=DataArrayInt::New(); ret->alloc(5*nbOfCells,1); - const int *c(_conn->begin()); - int *retPtr(ret->getPointer()),*newConnPtr(newConn->getPointer()); - for(int i=0;i newConn=DataArrayInt::New(); newConn->alloc(6*4*nbOfCells,1); - MEDCouplingAutoRefCountObjectPtr ret=DataArrayInt::New(); ret->alloc(6*nbOfCells,1); - const int *c(_conn->begin()); - int *retPtr(ret->getPointer()),*newConnPtr(newConn->getPointer()); - for(int i=0;iisAllocated()) - { stream << " Coordinates set but not allocated !"; return ; } - stream << " Space dimension : " << _coords->getNumberOfComponents() << "." << std::endl; - stream << "Number of nodes : " << _coords->getNumberOfTuples() << "."; - if(!(const DataArrayInt *)_conn) - { stream << std::endl << "Nodal connectivity NOT set !"; return ; } - if(_conn->isAllocated()) - { - if(_conn->getNumberOfComponents()==1) - stream << std::endl << "Number of cells : " << getNumberOfCells() << "."; - } -} - -void MEDCoupling1SGTUMesh::checkFullyDefined() const -{ - if(!((const DataArrayInt *)_conn) || !((const DataArrayDouble *)_coords)) - throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::checkFullyDefined : part of this is not fully defined."); -} - -/*! - * First step of unserialization process. - */ -bool MEDCoupling1SGTUMesh::isEmptyMesh(const std::vector& tinyInfo) const -{ - throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::isEmptyMesh : not implemented yet !"); -} - -void MEDCoupling1SGTUMesh::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,littleStrings3; - if((const DataArrayDouble *)_coords) - _coords->getTinySerializationStrInformation(littleStrings2); - if((const DataArrayInt *)_conn) - _conn->getTinySerializationStrInformation(littleStrings3); - int sz0((int)littleStrings2.size()),sz1((int)littleStrings3.size()); - littleStrings.insert(littleStrings.end(),littleStrings2.begin(),littleStrings2.end()); - littleStrings.insert(littleStrings.end(),littleStrings3.begin(),littleStrings3.end()); - // - tinyInfo.push_back(getCellModelEnum()); - tinyInfo.push_back(it); - tinyInfo.push_back(order); - std::vector tinyInfo2,tinyInfo3; - if((const DataArrayDouble *)_coords) - _coords->getTinySerializationIntInformation(tinyInfo2); - if((const DataArrayInt *)_conn) - _conn->getTinySerializationIntInformation(tinyInfo3); - int sz2((int)tinyInfo2.size()),sz3((int)tinyInfo3.size()); - tinyInfo.push_back(sz0); tinyInfo.push_back(sz1); tinyInfo.push_back(sz2); tinyInfo.push_back(sz3); - tinyInfo.insert(tinyInfo.end(),tinyInfo2.begin(),tinyInfo2.end()); - tinyInfo.insert(tinyInfo.end(),tinyInfo3.begin(),tinyInfo3.end()); - // - tinyInfoD.push_back(time); -} - -void MEDCoupling1SGTUMesh::resizeForUnserialization(const std::vector& tinyInfo, DataArrayInt *a1, DataArrayDouble *a2, std::vector& littleStrings) const -{ - std::vector tinyInfo2(tinyInfo.begin()+7,tinyInfo.begin()+7+tinyInfo[5]); - std::vector tinyInfo1(tinyInfo.begin()+7+tinyInfo[5],tinyInfo.begin()+7+tinyInfo[5]+tinyInfo[6]); - a1->resizeForUnserialization(tinyInfo1); - a2->resizeForUnserialization(tinyInfo2); -} - -void MEDCoupling1SGTUMesh::serialize(DataArrayInt *&a1, DataArrayDouble *&a2) const -{ - int sz(0); - if((const DataArrayInt *)_conn) - if(_conn->isAllocated()) - sz=_conn->getNbOfElems(); - a1=DataArrayInt::New(); - a1->alloc(sz,1); - if(sz!=0 && (const DataArrayInt *)_conn) - std::copy(_conn->begin(),_conn->end(),a1->getPointer()); - 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 MEDCoupling1SGTUMesh::unserialization(const std::vector& tinyInfoD, const std::vector& tinyInfo, const DataArrayInt *a1, DataArrayDouble *a2, - const std::vector& littleStrings) -{ - INTERP_KERNEL::NormalizedCellType gt((INTERP_KERNEL::NormalizedCellType)tinyInfo[0]); - _cm=&INTERP_KERNEL::CellModel::GetCellModel(gt); - setName(littleStrings[0]); - setDescription(littleStrings[1]); - setTimeUnit(littleStrings[2]); - setTime(tinyInfoD[0],tinyInfo[1],tinyInfo[2]); - int sz0(tinyInfo[3]),sz1(tinyInfo[4]),sz2(tinyInfo[5]),sz3(tinyInfo[6]); - // - _coords=DataArrayDouble::New(); - std::vector tinyInfo2(tinyInfo.begin()+7,tinyInfo.begin()+7+sz2); - _coords->resizeForUnserialization(tinyInfo2); - std::copy(a2->begin(),a2->end(),_coords->getPointer()); - _conn=DataArrayInt::New(); - std::vector tinyInfo3(tinyInfo.begin()+7+sz2,tinyInfo.begin()+7+sz2+sz3); - _conn->resizeForUnserialization(tinyInfo3); - std::copy(a1->begin(),a1->end(),_conn->getPointer()); - std::vector littleStrings2(littleStrings.begin()+3,littleStrings.begin()+3+sz0); - _coords->finishUnserialization(tinyInfo2,littleStrings2); - std::vector littleStrings3(littleStrings.begin()+3+sz0,littleStrings.begin()+3+sz0+sz1); - _conn->finishUnserialization(tinyInfo3,littleStrings3); -} - -/*! - * 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 MEDCoupling1SGTUMesh::checkFastEquivalWith(const MEDCouplingMesh *other, double prec) const -{ - MEDCouplingPointSet::checkFastEquivalWith(other,prec); - const MEDCoupling1SGTUMesh *otherC=dynamic_cast(other); - if(!otherC) - throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::checkFastEquivalWith : Two meshes are not unstructured with single static geometric type !"); - const DataArrayInt *c1(_conn),*c2(otherC->_conn); - if(c1==c2) - return; - if(!c1 || !c2) - throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::checkFastEquivalWith : presence of nodal connectivity only in one of the 2 meshes !"); - if((c1->isAllocated() && !c2->isAllocated()) || (!c1->isAllocated() && c2->isAllocated())) - throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::checkFastEquivalWith : in nodal connectivity, only one is allocated !"); - if(c1->getNumberOfComponents()!=1 || c1->getNumberOfComponents()!=1) - throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::checkFastEquivalWith : in nodal connectivity, must have 1 and only 1 component !"); - if(c1->getHashCode()!=c2->getHashCode()) - throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::checkFastEquivalWith : nodal connectivity differs"); -} - -MEDCouplingPointSet *MEDCoupling1SGTUMesh::mergeMyselfWithOnSameCoords(const MEDCouplingPointSet *other) const -{ - if(!other) - throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::mergeMyselfWithOnSameCoords : input other is null !"); - const MEDCoupling1SGTUMesh *otherC=dynamic_cast(other); - if(!otherC) - throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::mergeMyselfWithOnSameCoords : the input other mesh is not of type single statuc geo type unstructured !"); - std::vector ms(2); - ms[0]=this; - ms[1]=otherC; - return Merge1SGTUMeshesOnSameCoords(ms); -} - -void MEDCoupling1SGTUMesh::getReverseNodalConnectivity(DataArrayInt *revNodal, DataArrayInt *revNodalIndx) const -{ - checkFullyDefined(); - int nbOfNodes=getNumberOfNodes(); - 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=_conn->begin(); - int nbOfCells=getNumberOfCells(); - int nbOfEltsInRevNodal=0; - int nbOfNodesPerCell=getNumberOfNodesPerCell(); - for(int eltId=0;eltId=0 && conn[0]()); - conn=_conn->begin(); - 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;eltId(),-1))=eltId; - } - } -} - -/*! - * Use \a nodalConn array as nodal connectivity of \a this. The input \a nodalConn pointer can be null. - */ -void MEDCoupling1SGTUMesh::setNodalConnectivity(DataArrayInt *nodalConn) -{ - if(nodalConn) - nodalConn->incrRef(); - _conn=nodalConn; - declareAsNew(); -} - -/*! - * \return DataArrayInt * - the internal reference to the nodal connectivity. The caller is not reponsible to deallocate it. - */ -DataArrayInt *MEDCoupling1SGTUMesh::getNodalConnectivity() const -{ - const DataArrayInt *ret(_conn); - return const_cast(ret); -} - -/*! - * Allocates memory to store an estimation of the given number of cells. Closer is the estimation to the number of cells effectively inserted, - * less will be the needs to realloc. If the number of cells to be inserted is not known simply put 0 to this parameter. - * If a nodal connectivity previouly existed before the call of this method, it will be reset. - * - * \param [in] nbOfCells - estimation of the number of cell \a this mesh will contain. - */ -void MEDCoupling1SGTUMesh::allocateCells(int nbOfCells) -{ - if(nbOfCells<0) - throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::allocateCells : the input number of cells should be >= 0 !"); - _conn=DataArrayInt::New(); - _conn->reserve(getNumberOfNodesPerCell()*nbOfCells); - declareAsNew(); -} - -/*! - * Appends at the end of \a this a cell having nodal connectivity array defined in [ \a nodalConnOfCellBg, \a nodalConnOfCellEnd ). - * - * \param [in] nodalConnOfCellBg - the begin (included) of nodal connectivity of the cell to add. - * \param [in] nodalConnOfCellEnd - the end (excluded) of nodal connectivity of the cell to add. - * \throw If the length of the input nodal connectivity array of the cell to add is not equal to number of nodes per cell relative to the unique geometric type - * attached to \a this. - * \thow If the nodal connectivity array in \a this is null (call MEDCoupling1SGTUMesh::allocateCells before). - */ -void MEDCoupling1SGTUMesh::insertNextCell(const int *nodalConnOfCellBg, const int *nodalConnOfCellEnd) -{ - int sz=(int)std::distance(nodalConnOfCellBg,nodalConnOfCellEnd); - int ref=getNumberOfNodesPerCell(); - if(sz==ref) - { - DataArrayInt *c(_conn); - if(c) - c->pushBackValsSilent(nodalConnOfCellBg,nodalConnOfCellEnd); - else - throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::insertNextCell : nodal connectivity array is null ! Call MEDCoupling1SGTUMesh::allocateCells before !"); - } - else - { - std::ostringstream oss; oss << "MEDCoupling1SGTUMesh::insertNextCell : input nodal size (" << sz << ") does not match number of nodes per cell of this ("; - oss << ref << ") !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } -} - -/*! - * This method builds the dual mesh of \a this and returns it. - * - * \return MEDCoupling1SGTUMesh * - newly object created to be managed by the caller. - * \throw If \a this is not a mesh containing only simplex cells. - * \throw If \a this is not correctly allocated (coordinates and connectivities have to be correctly set !). - * \throw If at least one node in \a this is orphan (without any simplex cell lying on it !) - */ -MEDCoupling1GTUMesh *MEDCoupling1SGTUMesh::computeDualMesh() const -{ - const INTERP_KERNEL::CellModel& cm(getCellModel()); - if(!cm.isSimplex()) - throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::computeDualMesh : this mesh is not a simplex mesh ! Please invoke simplexize of tetrahedrize on this before calling this method !"); - switch(getMeshDimension()) - { - case 3: - return computeDualMesh3D(); - case 2: - return computeDualMesh2D(); - default: - throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::computeDualMesh : meshdimension must be in [2,3] !"); - } -} - -/*! - * This method explode each NORM_HEXA8 cells in \a this into 6 NORM_QUAD4 cells and put the result into the MEDCoupling1SGTUMesh returned instance. - * - * \return MEDCoupling1SGTUMesh * - a newly allocated instances (to be managed by the caller) storing the result of the explosion. - * \throw If \a this is not a mesh containing only NORM_HEXA8 cells. - * \throw If \a this is not properly allocated. - */ -MEDCoupling1SGTUMesh *MEDCoupling1SGTUMesh::explodeEachHexa8To6Quad4() const -{ - const INTERP_KERNEL::CellModel& cm(getCellModel()); - if(cm.getEnum()!=INTERP_KERNEL::NORM_HEXA8) - throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::explodeEachHexa8To6Quad4 : this method can be applied only on HEXA8 mesh !"); - int nbHexa8(getNumberOfCells()); - const int *inConnPtr(getNodalConnectivity()->begin()); - MEDCouplingAutoRefCountObjectPtr ret(MEDCoupling1SGTUMesh::New(getName(),INTERP_KERNEL::NORM_QUAD4)); - MEDCouplingAutoRefCountObjectPtr c(DataArrayInt::New()); c->alloc(nbHexa8*6*4,1); - int *cPtr(c->getPointer()); - for(int i=0;isetCoords(getCoords()); - ret->setNodalConnectivity(c); - return ret.retn(); -} - -/*! - * This method starts from an unstructured mesh that hides in reality a cartesian mesh. - * If it is not the case, an exception will be thrown. - * This method returns three objects : The cartesian mesh geometrically equivalent to \a this (within a precision of \a eps) and a permutation of cells - * and a permutation of nodes. - * - * - this[cellPerm[i]]=ret[i] - * - * \param [out] cellPerm the permutation array of size \c this->getNumberOfCells() - * \param [out] nodePerm the permutation array of size \c this->getNumberOfNodes() - * \return MEDCouplingCMesh * - a newly allocated mesh that is the result of the structurization of \a this. - */ -MEDCouplingCMesh *MEDCoupling1SGTUMesh::structurizeMe(DataArrayInt *& cellPerm, DataArrayInt *& nodePerm, double eps) const -{ - checkCoherency(); - int spaceDim(getSpaceDimension()),meshDim(getMeshDimension()),nbNodes(getNumberOfNodes()); - if(MEDCouplingStructuredMesh::GetGeoTypeGivenMeshDimension(meshDim)!=getCellModelEnum()) - throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::structurizeMe : the unique geo type in this is not compatible with the geometric type regarding mesh dimension !"); - MEDCouplingAutoRefCountObjectPtr cm(MEDCouplingCMesh::New()); - for(int i=0;i tmp(1,i); - MEDCouplingAutoRefCountObjectPtr elt(static_cast(getCoords()->keepSelectedComponents(tmp))); - elt=elt->getDifferentValues(eps); - elt->sort(true); - cm->setCoordsAt(i,elt); - } - if(nbNodes!=cm->getNumberOfNodes()) - throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::structurizeMe : considering the number of nodes after split per components in space this can't be a cartesian mesh ! Maybe your epsilon parameter is invalid ?"); - try - { cm->copyTinyInfoFrom(this); } - catch(INTERP_KERNEL::Exception&) { } - MEDCouplingAutoRefCountObjectPtr um(cm->buildUnstructured()),self(buildUnstructured()); - self->checkGeoEquivalWith(um,12,eps,cellPerm,nodePerm); - return cm.retn(); -} - -/// @cond INTERNAL - -bool UpdateHexa8Cell(int validAxis, int neighId, const int *validConnQuad4NeighSide, int *allFacesNodalConn, int *myNeighbours) -{ - static const int TAB[48]={ - 0,1,2,3,4,5,6,7,//0 - 4,7,6,5,0,3,2,1,//1 - 0,3,7,4,1,2,6,5,//2 - 4,0,3,7,5,1,2,6,//3 - 5,1,0,4,6,2,3,7,//4 - 3,7,4,0,2,6,5,1 //5 - }; - static const int TAB2[6]={0,0,3,3,3,3}; - if(myNeighbours[validAxis]==neighId && allFacesNodalConn[4*validAxis+0]==validConnQuad4NeighSide[TAB2[validAxis]]) - return true; - int oldAxis((int)std::distance(myNeighbours,std::find(myNeighbours,myNeighbours+6,neighId))); - std::size_t pos(std::distance(MEDCoupling1SGTUMesh::HEXA8_FACE_PAIRS,std::find(MEDCoupling1SGTUMesh::HEXA8_FACE_PAIRS,MEDCoupling1SGTUMesh::HEXA8_FACE_PAIRS+6,oldAxis))); - std::size_t pos0(pos/2),pos1(pos%2); - int oldAxisOpp(MEDCoupling1SGTUMesh::HEXA8_FACE_PAIRS[2*pos0+(pos1+1)%2]); - int oldConn[8],myConn2[8]={-1,-1,-1,-1,-1,-1,-1,-1},myConn[8],edgeConn[2],allFacesTmp[24],neighTmp[6]; - oldConn[0]=allFacesNodalConn[0]; oldConn[1]=allFacesNodalConn[1]; oldConn[2]=allFacesNodalConn[2]; oldConn[3]=allFacesNodalConn[3]; - oldConn[4]=allFacesNodalConn[4]; oldConn[5]=allFacesNodalConn[7]; oldConn[6]=allFacesNodalConn[6]; oldConn[7]=allFacesNodalConn[5]; - const INTERP_KERNEL::CellModel& cm(INTERP_KERNEL::CellModel::GetCellModel(INTERP_KERNEL::NORM_HEXA8)); - for(int i=0;i<4;i++) - myConn2[i]=validConnQuad4NeighSide[(4-i+TAB2[validAxis])%4]; - for(int i=0;i<4;i++) - { - int nodeId(myConn2[i]);//the node id for which the opposite one will be found - bool found(false); - INTERP_KERNEL::NormalizedCellType typeOfSon; - for(int j=0;j<12 && !found;j++) - { - cm.fillSonEdgesNodalConnectivity3D(j,oldConn,-1,edgeConn,typeOfSon); - if(edgeConn[0]==nodeId || edgeConn[1]==nodeId) - { - if(std::find(allFacesNodalConn+4*oldAxisOpp,allFacesNodalConn+4*oldAxisOpp+4,edgeConn[0]==nodeId?edgeConn[1]:edgeConn[0])!=allFacesNodalConn+4*oldAxisOpp+4) - { - myConn2[i+4]=edgeConn[0]==nodeId?edgeConn[1]:edgeConn[0]; - found=true; - } - } - } - if(!found) - throw INTERP_KERNEL::Exception("UpdateHexa8Cell : Internal Error !"); - } - const int *myTab(TAB+8*validAxis); - for(int i=0;i<8;i++) - myConn[i]=myConn2[myTab[i]]; - for(int i=0;i<6;i++) - { - cm.fillSonCellNodalConnectivity(i,myConn,allFacesTmp+4*i); - std::set s(allFacesTmp+4*i,allFacesTmp+4*i+4); - bool found(false); - for(int j=0;j<6 && !found;j++) - { - std::set s1(allFacesNodalConn+4*j,allFacesNodalConn+4*j+4); - if(s==s1) - { - neighTmp[i]=myNeighbours[j]; - found=true; - } - } - if(!found) - throw INTERP_KERNEL::Exception("UpdateHexa8Cell : Internal Error #2 !"); - } - std::copy(allFacesTmp,allFacesTmp+24,allFacesNodalConn); - std::copy(neighTmp,neighTmp+6,myNeighbours); - return false; -} - -/// @endcond - -/*! - * This method expects the \a this contains NORM_HEXA8 cells only. This method will sort each cells in \a this so that their numbering was - * homogeneous. If it succeeds the result of MEDCouplingUMesh::tetrahedrize will return a conform mesh. - * - * \return DataArrayInt * - a newly allocated array (to be managed by the caller) containing renumbered cell ids. - * - * \throw If \a this is not a mesh containing only NORM_HEXA8 cells. - * \throw If \a this is not properly allocated. - * \sa MEDCouplingUMesh::tetrahedrize, MEDCouplingUMesh::simplexize. - */ -DataArrayInt *MEDCoupling1SGTUMesh::sortHexa8EachOther() -{ - MEDCouplingAutoRefCountObjectPtr quads(explodeEachHexa8To6Quad4());//checks that only hexa8 - int nbHexa8(getNumberOfCells()),*cQuads(quads->getNodalConnectivity()->getPointer()); - MEDCouplingAutoRefCountObjectPtr neighOfQuads(DataArrayInt::New()); neighOfQuads->alloc(nbHexa8*6,1); neighOfQuads->fillWithValue(-1); - int *ptNeigh(neighOfQuads->getPointer()); - {//neighOfQuads tells for each face of each Quad8 which cell (if!=-1) is connected to this face. - MEDCouplingAutoRefCountObjectPtr quadsTmp(quads->buildUnstructured()); - MEDCouplingAutoRefCountObjectPtr ccSafe,cciSafe; - DataArrayInt *cc(0),*cci(0); - quadsTmp->findCommonCells(3,0,cc,cci); - ccSafe=cc; cciSafe=cci; - const int *ccPtr(ccSafe->begin()),nbOfPair(cci->getNumberOfTuples()-1); - for(int i=0;i ret(DataArrayInt::New()); ret->alloc(0,1); - std::vector fetched(nbHexa8,false); - std::vector::iterator it(std::find(fetched.begin(),fetched.end(),false)); - while(it!=fetched.end())//it will turns as time as number of connected zones - { - int cellId((int)std::distance(fetched.begin(),it));//it is the seed of the connected zone. - std::set s; s.insert(cellId);//s contains already organized. - while(!s.empty()) - { - std::set sNext; - for(std::set::const_iterator it0=s.begin();it0!=s.end();it0++) - { - fetched[*it0]=true; - int *myNeighb(ptNeigh+6*(*it0)); - for(int i=0;i<6;i++) - { - if(myNeighb[i]!=-1 && !fetched[myNeighb[i]]) - { - std::size_t pos(std::distance(HEXA8_FACE_PAIRS,std::find(HEXA8_FACE_PAIRS,HEXA8_FACE_PAIRS+6,i))); - std::size_t pos0(pos/2),pos1(pos%2); - if(!UpdateHexa8Cell(HEXA8_FACE_PAIRS[2*pos0+(pos1+1)%2],*it0,cQuads+6*4*(*it0)+4*i,cQuads+6*4*myNeighb[i],ptNeigh+6*myNeighb[i])) - ret->pushBackSilent(myNeighb[i]); - fetched[myNeighb[i]]=true; - sNext.insert(myNeighb[i]); - } - } - } - s=sNext; - } - it=std::find(fetched.begin(),fetched.end(),false); - } - if(!ret->empty()) - { - int *conn(getNodalConnectivity()->getPointer()); - for(const int *pt=ret->begin();pt!=ret->end();pt++) - { - int cellId(*pt); - conn[8*cellId+0]=cQuads[24*cellId+0]; conn[8*cellId+1]=cQuads[24*cellId+1]; conn[8*cellId+2]=cQuads[24*cellId+2]; conn[8*cellId+3]=cQuads[24*cellId+3]; - conn[8*cellId+4]=cQuads[24*cellId+4]; conn[8*cellId+5]=cQuads[24*cellId+7]; conn[8*cellId+6]=cQuads[24*cellId+6]; conn[8*cellId+7]=cQuads[24*cellId+5]; - } - declareAsNew(); - } - return ret.retn(); -} - -MEDCoupling1DGTUMesh *MEDCoupling1SGTUMesh::computeDualMesh3D() const -{ - static const int DUAL_TETRA_0[36]={ - 4,1,0, 6,0,3, 7,3,1, - 4,0,1, 5,2,0, 8,1,2, - 6,3,0, 5,0,2, 9,2,3, - 7,1,3, 9,3,2, 8,2,1 - }; - static const int DUAL_TETRA_1[36]={ - 8,4,10, 11,5,8, 10,7,11, - 9,4,8, 8,5,12, 12,6,9, - 10,4,9, 9,6,13, 13,7,10, - 12,5,11, 13,6,12, 11,7,13 - }; - static const int FACEID_NOT_SH_NODE[4]={2,3,1,0}; - if(getCellModelEnum()!=INTERP_KERNEL::NORM_TETRA4) - throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::computeDualMesh3D : only TETRA4 supported !"); - checkFullyDefined(); - MEDCouplingAutoRefCountObjectPtr thisu(buildUnstructured()); - MEDCouplingAutoRefCountObjectPtr revNodArr(DataArrayInt::New()),revNodIArr(DataArrayInt::New()); - thisu->getReverseNodalConnectivity(revNodArr,revNodIArr); - const int *revNod(revNodArr->begin()),*revNodI(revNodIArr->begin()),*nodal(_conn->begin()); - MEDCouplingAutoRefCountObjectPtr d1Arr(DataArrayInt::New()),di1Arr(DataArrayInt::New()),rd1Arr(DataArrayInt::New()),rdi1Arr(DataArrayInt::New()); - MEDCouplingAutoRefCountObjectPtr edges(thisu->explode3DMeshTo1D(d1Arr,di1Arr,rd1Arr,rdi1Arr)); - const int *d1(d1Arr->begin()); - MEDCouplingAutoRefCountObjectPtr d2Arr(DataArrayInt::New()),di2Arr(DataArrayInt::New()),rd2Arr(DataArrayInt::New()),rdi2Arr(DataArrayInt::New()); - MEDCouplingAutoRefCountObjectPtr faces(thisu->buildDescendingConnectivity(d2Arr,di2Arr,rd2Arr,rdi2Arr)); thisu=0; - const int *d2(d2Arr->begin()),*rdi2(rdi2Arr->begin()); - MEDCouplingAutoRefCountObjectPtr edgesBaryArr(edges->getBarycenterAndOwner()),facesBaryArr(faces->getBarycenterAndOwner()),baryArr(getBarycenterAndOwner()); - const int nbOfNodes(getNumberOfNodes()),offset0(nbOfNodes+faces->getNumberOfCells()),offset1(offset0+edges->getNumberOfCells()); - edges=0; faces=0; - std::vector v(4); v[0]=getCoords(); v[1]=facesBaryArr; v[2]=edgesBaryArr; v[3]=baryArr; - MEDCouplingAutoRefCountObjectPtr zeArr(DataArrayDouble::Aggregate(v)); baryArr=0; edgesBaryArr=0; facesBaryArr=0; - std::string name("DualOf_"); name+=getName(); - MEDCouplingAutoRefCountObjectPtr ret(MEDCoupling1DGTUMesh::New(name,INTERP_KERNEL::NORM_POLYHED)); ret->setCoords(zeArr); - MEDCouplingAutoRefCountObjectPtr cArr(DataArrayInt::New()),ciArr(DataArrayInt::New()); ciArr->alloc(nbOfNodes+1,1); ciArr->setIJ(0,0,0); cArr->alloc(0,1); - for(int i=0;ipushBackSilent(-1); - int tmp[14]; - // - tmp[0]=d1[6*curCellId+DUAL_TETRA_0[nodePosInCurCell*9+0]-4]+offset0; tmp[1]=d2[4*curCellId+DUAL_TETRA_0[nodePosInCurCell*9+1]]+nbOfNodes; - tmp[2]=curCellId+offset1; tmp[3]=d2[4*curCellId+DUAL_TETRA_0[nodePosInCurCell*9+2]]+nbOfNodes; - tmp[4]=-1; - tmp[5]=d1[6*curCellId+DUAL_TETRA_0[nodePosInCurCell*9+3]-4]+offset0; tmp[6]=d2[4*curCellId+DUAL_TETRA_0[nodePosInCurCell*9+4]]+nbOfNodes; - tmp[7]=curCellId+offset1; tmp[8]=d2[4*curCellId+DUAL_TETRA_0[nodePosInCurCell*9+5]]+nbOfNodes; - tmp[9]=-1; - tmp[10]=d1[6*curCellId+DUAL_TETRA_0[nodePosInCurCell*9+6]-4]+offset0; tmp[11]=d2[4*curCellId+DUAL_TETRA_0[nodePosInCurCell*9+7]]+nbOfNodes; - tmp[12]=curCellId+offset1; tmp[13]=d2[4*curCellId+DUAL_TETRA_0[nodePosInCurCell*9+8]]+nbOfNodes; - cArr->insertAtTheEnd(tmp,tmp+14); - int kk(0); - for(int k=0;k<4;k++) - { - if(FACEID_NOT_SH_NODE[nodePosInCurCell]!=k) - { - const int *faceId(d2+4*curCellId+k); - if(rdi2[*faceId+1]-rdi2[*faceId]==1) - { - int tmp2[5]; tmp2[0]=-1; tmp2[1]=i; - tmp2[2]=d1[6*curCellId+DUAL_TETRA_1[9*nodePosInCurCell+3*kk+0]-8]+offset0; - tmp2[3]=d2[4*curCellId+DUAL_TETRA_1[9*nodePosInCurCell+3*kk+1]-4]+nbOfNodes; - tmp2[4]=d1[6*curCellId+DUAL_TETRA_1[9*nodePosInCurCell+3*kk+2]-8]+offset0; - cArr->insertAtTheEnd(tmp2,tmp2+5); - } - kk++; - } - } - } - ciArr->setIJ(i+1,0,cArr->getNumberOfTuples()); - } - ret->setNodalConnectivity(cArr,ciArr); - return ret.retn(); -} - -MEDCoupling1DGTUMesh *MEDCoupling1SGTUMesh::computeDualMesh2D() const -{ - static const int DUAL_TRI_0[6]={0,2, 1,0, 2,1}; - static const int DUAL_TRI_1[6]={-3,+5, +3,-4, +4,-5}; - static const int FACEID_NOT_SH_NODE[3]={1,2,0}; - if(getCellModelEnum()!=INTERP_KERNEL::NORM_TRI3) - throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::computeDualMesh2D : only TRI3 supported !"); - checkFullyDefined(); - MEDCouplingAutoRefCountObjectPtr thisu(buildUnstructured()); - MEDCouplingAutoRefCountObjectPtr revNodArr(DataArrayInt::New()),revNodIArr(DataArrayInt::New()); - thisu->getReverseNodalConnectivity(revNodArr,revNodIArr); - const int *revNod(revNodArr->begin()),*revNodI(revNodIArr->begin()),*nodal(_conn->begin()); - MEDCouplingAutoRefCountObjectPtr d2Arr(DataArrayInt::New()),di2Arr(DataArrayInt::New()),rd2Arr(DataArrayInt::New()),rdi2Arr(DataArrayInt::New()); - MEDCouplingAutoRefCountObjectPtr edges(thisu->buildDescendingConnectivity(d2Arr,di2Arr,rd2Arr,rdi2Arr)); thisu=0; - const int *d2(d2Arr->begin()),*rdi2(rdi2Arr->begin()); - MEDCouplingAutoRefCountObjectPtr edgesBaryArr(edges->getBarycenterAndOwner()),baryArr(getBarycenterAndOwner()); - const int nbOfNodes(getNumberOfNodes()),offset0(nbOfNodes+edges->getNumberOfCells()); - edges=0; - std::vector v(3); v[0]=getCoords(); v[1]=edgesBaryArr; v[2]=baryArr; - MEDCouplingAutoRefCountObjectPtr zeArr(DataArrayDouble::Aggregate(v)); baryArr=0; edgesBaryArr=0; - std::string name("DualOf_"); name+=getName(); - MEDCouplingAutoRefCountObjectPtr ret(MEDCoupling1DGTUMesh::New(name,INTERP_KERNEL::NORM_POLYGON)); ret->setCoords(zeArr); - MEDCouplingAutoRefCountObjectPtr cArr(DataArrayInt::New()),ciArr(DataArrayInt::New()); ciArr->alloc(nbOfNodes+1,1); ciArr->setIJ(0,0,0); cArr->alloc(0,1); - for(int i=0;i > polyg; - for(int j=0;j locV(3); - locV[0]=d2[3*curCellId+DUAL_TRI_0[2*nodePosInCurCell+0]]+nbOfNodes; locV[1]=curCellId+offset0; locV[2]=d2[3*curCellId+DUAL_TRI_0[2*nodePosInCurCell+1]]+nbOfNodes; - polyg.push_back(locV); - int kk(0); - for(int k=0;k<3;k++) - { - if(FACEID_NOT_SH_NODE[nodePosInCurCell]!=k) - { - const int *edgeId(d2+3*curCellId+k); - if(rdi2[*edgeId+1]-rdi2[*edgeId]==1) - { - std::vector locV2(2); - int zeLocEdgeIdRel(DUAL_TRI_1[2*nodePosInCurCell+kk]); - if(zeLocEdgeIdRel>0) - { locV2[0]=d2[3*curCellId+zeLocEdgeIdRel-3]+nbOfNodes; locV2[1]=i; } - else - { locV2[0]=i; locV2[1]=d2[3*curCellId-zeLocEdgeIdRel-3]+nbOfNodes; } - polyg.push_back(locV2); - } - kk++; - } - } - } - std::vector zePolyg(MEDCoupling1DGTUMesh::BuildAPolygonFromParts(polyg)); - cArr->insertAtTheEnd(zePolyg.begin(),zePolyg.end()); - ciArr->setIJ(i+1,0,cArr->getNumberOfTuples()); - } - ret->setNodalConnectivity(cArr,ciArr); - return ret.retn(); -} - -/*! - * This method aggregate the bbox of each cell and put it into bbox - * - * \param [in] arcDetEps - a parameter specifying in case of 2D quadratic polygon cell the detection limit between linear and arc circle. (By default 1e-12) - * For all other cases this input parameter is ignored. - * \return DataArrayDouble * - newly created object (to be managed by the caller) \a this number of cells tuples and 2*spacedim components. - * - * \throw If \a this is not fully set (coordinates and connectivity). - * \throw If a cell in \a this has no valid nodeId. - */ -DataArrayDouble *MEDCoupling1SGTUMesh::getBoundingBoxForBBTree(double arcDetEps) const -{ - int spaceDim(getSpaceDimension()),nbOfCells(getNumberOfCells()),nbOfNodes(getNumberOfNodes()),nbOfNodesPerCell(getNumberOfNodesPerCell()); - MEDCouplingAutoRefCountObjectPtr ret(DataArrayDouble::New()); ret->alloc(nbOfCells,2*spaceDim); - double *bbox(ret->getPointer()); - for(int i=0;i::max(); - bbox[2*i+1]=-std::numeric_limits::max(); - } - const double *coordsPtr(_coords->getConstPointer()); - const int *conn(_conn->getConstPointer()); - for(int i=0;i=0 && nodeId ret(MEDCouplingFieldDouble::New(ON_CELLS,ONE_TIME)); - int nbCells(getNumberOfCells()); - MEDCouplingAutoRefCountObjectPtr arr(DataArrayDouble::New()); - arr->alloc(nbCells,1); - INTERP_KERNEL::AutoCppPtr dc(_cm->buildInstanceOfDiameterCalulator(getSpaceDimension())); - dc->computeFor1SGTUMeshFrmt(nbCells,_conn->begin(),getCoords()->begin(),arr->getPointer()); - ret->setMesh(this); - ret->setArray(arr); - ret->setName("Diameter"); - return ret.retn(); -} - -//== - -MEDCoupling1DGTUMesh *MEDCoupling1DGTUMesh::New() -{ - return new MEDCoupling1DGTUMesh; -} - -MEDCoupling1DGTUMesh *MEDCoupling1DGTUMesh::New(const std::string& name, INTERP_KERNEL::NormalizedCellType type) -{ - if(type==INTERP_KERNEL::NORM_ERROR) - throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::New : NORM_ERROR is not a valid type to be used as base geometric type for a mesh !"); - const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(type); - if(!cm.isDynamic()) - { - std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::New : the input geometric type " << cm.getRepr() << " is static ! Only dynamic types are allowed here !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - return new MEDCoupling1DGTUMesh(name,cm); -} - -MEDCoupling1DGTUMesh::MEDCoupling1DGTUMesh() -{ -} - -MEDCoupling1DGTUMesh::MEDCoupling1DGTUMesh(const std::string& name, const INTERP_KERNEL::CellModel& cm):MEDCoupling1GTUMesh(name,cm) -{ -} - -MEDCoupling1DGTUMesh::MEDCoupling1DGTUMesh(const MEDCoupling1DGTUMesh& other, bool recDeepCpy):MEDCoupling1GTUMesh(other,recDeepCpy),_conn(other._conn) -{ - if(recDeepCpy) - { - const DataArrayInt *c(other._conn); - if(c) - _conn=c->deepCpy(); - c=other._conn_indx; - if(c) - _conn_indx=c->deepCpy(); - } -} - -MEDCoupling1DGTUMesh *MEDCoupling1DGTUMesh::clone(bool recDeepCpy) const -{ - return new MEDCoupling1DGTUMesh(*this,recDeepCpy); -} - -/*! - * This method behaves mostly like MEDCoupling1DGTUMesh::deepCpy method, except that only nodal connectivity arrays are deeply copied. - * The coordinates are shared between \a this and the returned instance. - * - * \return MEDCouplingUMesh * - A new object instance holding the copy of \a this (deep for connectivity, shallow for coordiantes) - * \sa MEDCoupling1DGTUMesh::deepCpy - */ -MEDCouplingPointSet *MEDCoupling1DGTUMesh::deepCpyConnectivityOnly() const -{ - checkCoherency(); - MEDCouplingAutoRefCountObjectPtr ret(clone(false)); - MEDCouplingAutoRefCountObjectPtr c(_conn->deepCpy()),ci(_conn_indx->deepCpy()); - ret->setNodalConnectivity(c,ci); - return ret.retn(); -} - -void MEDCoupling1DGTUMesh::updateTime() const -{ - MEDCoupling1GTUMesh::updateTime(); - const DataArrayInt *c(_conn); - if(c) - updateTimeWith(*c); - c=_conn_indx; - if(c) - updateTimeWith(*c); -} - -std::size_t MEDCoupling1DGTUMesh::getHeapMemorySizeWithoutChildren() const -{ - return MEDCoupling1GTUMesh::getHeapMemorySizeWithoutChildren(); -} - -std::vector MEDCoupling1DGTUMesh::getDirectChildrenWithNull() const -{ - std::vector ret(MEDCoupling1GTUMesh::getDirectChildrenWithNull()); - ret.push_back((const DataArrayInt *)_conn); - ret.push_back((const DataArrayInt *)_conn_indx); - return ret; -} - -MEDCouplingMesh *MEDCoupling1DGTUMesh::deepCpy() const -{ - return clone(true); -} - -bool MEDCoupling1DGTUMesh::isEqualIfNotWhy(const MEDCouplingMesh *other, double prec, std::string& reason) const -{ - if(!other) - throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::isEqualIfNotWhy : input other pointer is null !"); - std::ostringstream oss; oss.precision(15); - const MEDCoupling1DGTUMesh *otherC=dynamic_cast(other); - if(!otherC) - { - reason="mesh given in input is not castable in MEDCoupling1DGTUMesh !"; - return false; - } - if(!MEDCoupling1GTUMesh::isEqualIfNotWhy(other,prec,reason)) - return false; - const DataArrayInt *c1(_conn),*c2(otherC->_conn); - if(c1==c2) - return true; - if(!c1 || !c2) - { - reason="in connectivity of single dynamic geometric type exactly one among this and other is null !"; - return false; - } - if(!c1->isEqualIfNotWhy(*c2,reason)) - { - reason.insert(0,"Nodal connectivity DataArrayInt differs : "); - return false; - } - c1=_conn_indx; c2=otherC->_conn_indx; - if(c1==c2) - return true; - if(!c1 || !c2) - { - reason="in connectivity index of single dynamic geometric type exactly one among this and other is null !"; - return false; - } - if(!c1->isEqualIfNotWhy(*c2,reason)) - { - reason.insert(0,"Nodal connectivity index DataArrayInt differs : "); - return false; - } - return true; -} - -bool MEDCoupling1DGTUMesh::isEqualWithoutConsideringStr(const MEDCouplingMesh *other, double prec) const -{ - if(!other) - throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::isEqualWithoutConsideringStr : input other pointer is null !"); - const MEDCoupling1DGTUMesh *otherC=dynamic_cast(other); - if(!otherC) - return false; - if(!MEDCoupling1GTUMesh::isEqualWithoutConsideringStr(other,prec)) - return false; - const DataArrayInt *c1(_conn),*c2(otherC->_conn); - if(c1==c2) - return true; - if(!c1 || !c2) - return false; - if(!c1->isEqualWithoutConsideringStr(*c2)) - return false; - return true; - c1=_conn_indx; c2=otherC->_conn_indx; - if(c1==c2) - return true; - if(!c1 || !c2) - return false; - if(!c1->isEqualWithoutConsideringStr(*c2)) - return false; - return true; -} - -/*! - * 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 MEDCoupling1DGTUMesh::checkFastEquivalWith(const MEDCouplingMesh *other, double prec) const -{ - MEDCouplingPointSet::checkFastEquivalWith(other,prec); - const MEDCoupling1DGTUMesh *otherC=dynamic_cast(other); - if(!otherC) - throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::checkFastEquivalWith : Two meshes are not unstructured with single dynamic geometric type !"); - const DataArrayInt *c1(_conn),*c2(otherC->_conn); - if(c1!=c2) - { - if(!c1 || !c2) - throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::checkFastEquivalWith : presence of nodal connectivity only in one of the 2 meshes !"); - if((c1->isAllocated() && !c2->isAllocated()) || (!c1->isAllocated() && c2->isAllocated())) - throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::checkFastEquivalWith : in nodal connectivity, only one is allocated !"); - if(c1->getNumberOfComponents()!=1 || c1->getNumberOfComponents()!=1) - throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::checkFastEquivalWith : in nodal connectivity, must have 1 and only 1 component !"); - if(c1->getHashCode()!=c2->getHashCode()) - throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::checkFastEquivalWith : nodal connectivity differs"); - } - c1=_conn_indx; c2=otherC->_conn_indx; - if(c1!=c2) - { - if(!c1 || !c2) - throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::checkFastEquivalWith : presence of nodal connectivity index only in one of the 2 meshes !"); - if((c1->isAllocated() && !c2->isAllocated()) || (!c1->isAllocated() && c2->isAllocated())) - throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::checkFastEquivalWith : in nodal connectivity index, only one is allocated !"); - if(c1->getNumberOfComponents()!=1 || c1->getNumberOfComponents()!=1) - throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::checkFastEquivalWith : in nodal connectivity index, must have 1 and only 1 component !"); - if(c1->getHashCode()!=c2->getHashCode()) - throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::checkFastEquivalWith : nodal connectivity index differs"); - } -} - -void MEDCoupling1DGTUMesh::checkCoherencyOfConnectivity() const -{ - const DataArrayInt *c1(_conn); - if(c1) - { - if(c1->getNumberOfComponents()!=1) - throw INTERP_KERNEL::Exception("Nodal connectivity array is expected to be with number of components set to one !"); - if(c1->getInfoOnComponent(0)!="") - throw INTERP_KERNEL::Exception("Nodal connectivity array is expected to have no info on its single component !"); - c1->checkAllocated(); - } - else - throw INTERP_KERNEL::Exception("Nodal connectivity array not defined !"); - // - int sz2=_conn->getNumberOfTuples(); - c1=_conn_indx; - if(c1) - { - if(c1->getNumberOfComponents()!=1) - throw INTERP_KERNEL::Exception("Nodal connectivity index array is expected to be with number of components set to one !"); - c1->checkAllocated(); - if(c1->getNumberOfTuples()<1) - throw INTERP_KERNEL::Exception("Nodal connectivity index array is expected to have a a size of 1 at least !"); - if(c1->getInfoOnComponent(0)!="") - throw INTERP_KERNEL::Exception("Nodal connectivity index array is expected to have no info on its single component !"); - int f=c1->front(),ll=c1->back(); - if(f<0 || f>=sz2) - { - std::ostringstream oss; oss << "Nodal connectivity index array first value (" << f << ") is expected to be exactly in [0," << sz2 << ") !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - if(ll<0 || ll>sz2) - { - std::ostringstream oss; oss << "Nodal connectivity index array last value (" << ll << ") is expected to be exactly in [0," << sz2 << "] !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - if(f>ll) - { - std::ostringstream oss; oss << "Nodal connectivity index array looks very bad (not increasing monotonic) because front (" << f << ") is greater that back (" << ll << ") !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - } - else - throw INTERP_KERNEL::Exception("Nodal connectivity index array not defined !"); - int szOfC1Exp=_conn_indx->back(); - if(sz2getNumberOfTuples() << " !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } -} - -/*! - * If \a this pass this method, you are sure that connectivity arrays are not null, with exactly one component, no name, no component name, allocated. - * In addition you are sure that the length of nodal connectivity index array is bigger than or equal to one. - * In addition you are also sure that length of nodal connectivity is coherent with the content of the last value in the index array. - */ -void MEDCoupling1DGTUMesh::checkCoherency() const -{ - MEDCouplingPointSet::checkCoherency(); - checkCoherencyOfConnectivity(); -} - -void MEDCoupling1DGTUMesh::checkCoherency1(double eps) const -{ - checkCoherency(); - const DataArrayInt *c1(_conn),*c2(_conn_indx); - if(!c2->isMonotonic(true)) - throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::checkCoherency1 : the nodal connectivity index is expected to be increasing monotinic !"); - // - int nbOfTuples=c1->getNumberOfTuples(); - int nbOfNodes=getNumberOfNodes(); - const int *w(c1->begin()); - for(int i=0;i=nbOfNodes) - { - std::ostringstream oss; oss << "At pos #" << i << " of nodal connectivity array references to node id #" << *w << " must be in [0," << nbOfNodes << ") !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - } -} - -void MEDCoupling1DGTUMesh::checkCoherency2(double eps) const -{ - checkCoherency1(eps); -} - -int MEDCoupling1DGTUMesh::getNumberOfCells() const -{ - checkCoherencyOfConnectivity();//do not remove - return _conn_indx->getNumberOfTuples()-1; -} - -/*! - * This method returns a newly allocated array containing this->getNumberOfCells() tuples and 1 component. - * For each cell in \b this the number of nodes constituting cell is computed. - * For each polyhedron cell, the sum of the number of nodes of each face constituting polyhedron cell is returned. - * So for pohyhedrons some nodes can be counted several times in the returned result. - * - * \return a newly allocated array - */ -DataArrayInt *MEDCoupling1DGTUMesh::computeNbOfNodesPerCell() const -{ - checkCoherency(); - _conn_indx->checkMonotonic(true); - if(getCellModelEnum()!=INTERP_KERNEL::NORM_POLYHED) - return _conn_indx->deltaShiftIndex(); - // for polyhedrons - int nbOfCells=_conn_indx->getNumberOfTuples()-1; - MEDCouplingAutoRefCountObjectPtr ret=DataArrayInt::New(); - ret->alloc(nbOfCells,1); - int *retPtr=ret->getPointer(); - const int *ci=_conn_indx->begin(),*c=_conn->begin(); - for(int i=0;igetNumberOfCells() tuples and 1 component. - * For each cell in \b this the number of faces constituting (entity of dimension this->getMeshDimension()-1) cell is computed. - * - * \return a newly allocated array - */ -DataArrayInt *MEDCoupling1DGTUMesh::computeNbOfFacesPerCell() const -{ - checkCoherency(); - _conn_indx->checkMonotonic(true); - if(getCellModelEnum()!=INTERP_KERNEL::NORM_POLYHED && getCellModelEnum()!=INTERP_KERNEL::NORM_QPOLYG) - return _conn_indx->deltaShiftIndex(); - if(getCellModelEnum()==INTERP_KERNEL::NORM_QPOLYG) - { - MEDCouplingAutoRefCountObjectPtr ret=_conn_indx->deltaShiftIndex(); - ret->applyDivideBy(2); - return ret.retn(); - } - // for polyhedrons - int nbOfCells=_conn_indx->getNumberOfTuples()-1; - MEDCouplingAutoRefCountObjectPtr ret=DataArrayInt::New(); - ret->alloc(nbOfCells,1); - int *retPtr=ret->getPointer(); - const int *ci=_conn_indx->begin(),*c=_conn->begin(); - for(int i=0;icheckMonotonic(true); - int nbOfCells(_conn_indx->getNumberOfTuples()-1); - MEDCouplingAutoRefCountObjectPtr ret=DataArrayInt::New(); - ret->alloc(nbOfCells,1); - int *retPtr(ret->getPointer()); - const int *ci(_conn_indx->begin()),*c(_conn->begin()); - if(getCellModelEnum()!=INTERP_KERNEL::NORM_POLYHED) - { - for(int i=0;i s(c+ci[0],c+ci[1]); - *retPtr=(int)s.size(); - } - } - else - { - for(int i=0;i s(c+ci[0],c+ci[1]); s.erase(-1); - *retPtr=(int)s.size(); - } - } - return ret.retn(); -} - -void MEDCoupling1DGTUMesh::getNodeIdsOfCell(int cellId, std::vector& conn) const -{ - int nbOfCells(getNumberOfCells());//performs checks - if(cellId>=0 && cellIdgetIJ(cellId,0),stp=_conn_indx->getIJ(cellId+1,0); - int nbOfNodes=stp-strt; - if(nbOfNodes<0) - throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::getNodeIdsOfCell : the index array is invalid ! Should be increasing monotonic !"); - conn.resize(nbOfNodes); - std::copy(_conn->begin()+strt,_conn->begin()+stp,conn.begin()); - } - else - { - std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::getNodeIdsOfCell : request for cellId #" << cellId << " must be in [0," << nbOfCells << ") !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } -} - -int MEDCoupling1DGTUMesh::getNumberOfNodesInCell(int cellId) const -{ - int nbOfCells(getNumberOfCells());//performs checks - if(cellId>=0 && cellIdbegin()); - int strt=_conn_indx->getIJ(cellId,0),stp=_conn_indx->getIJ(cellId+1,0); - return stp-strt-std::count(conn+strt,conn+stp,-1); - } - else - { - std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::getNumberOfNodesInCell : request for cellId #" << cellId << " must be in [0," << nbOfCells << ") !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } -} - -std::string MEDCoupling1DGTUMesh::simpleRepr() const -{ - static const char msg0[]="No coordinates specified !"; - std::ostringstream ret; - ret << "Single dynamic geometic type (" << _cm->getRepr() << ") unstructured 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 << "Mesh dimension : " << getMeshDimension() << "\nSpace dimension : "; - if(_coords!=0) - { - const int spaceDim=getSpaceDimension(); - ret << spaceDim << "\nInfo attached on space dimension : "; - for(int i=0;igetInfoOnComponent(i) << "\" "; - ret << "\n"; - } - else - ret << msg0 << "\n"; - ret << "Number of nodes : "; - if(_coords!=0) - ret << getNumberOfNodes() << "\n"; - else - ret << msg0 << "\n"; - ret << "Number of cells : "; - bool isOK=true; - try { checkCoherency(); } catch(INTERP_KERNEL::Exception& /* e */) - { - ret << "Nodal connectivity arrays are not set or badly set !\n"; - isOK=false; - } - if(isOK) - ret << getNumberOfCells() << "\n"; - ret << "Cell type : " << _cm->getRepr() << "\n"; - return ret.str(); -} - -std::string MEDCoupling1DGTUMesh::advancedRepr() const -{ - std::ostringstream ret; - ret << simpleRepr(); - ret << "\nCoordinates array : \n___________________\n\n"; - if(_coords) - _coords->reprWithoutNameStream(ret); - else - ret << "No array set !\n"; - ret << "\n\nNodal Connectivity : \n____________________\n\n"; - // - bool isOK=true; - try { checkCoherency1(); } catch(INTERP_KERNEL::Exception& /* e */) - { - ret << "Nodal connectivity arrays are not set or badly set !\n"; - isOK=false; - } - if(!isOK) - return ret.str(); - int nbOfCells=getNumberOfCells(); - const int *ci=_conn_indx->begin(),*c=_conn->begin(); - for(int i=0;i(ret," ")); - ret << "\n"; - } - return ret.str(); -} - -DataArrayDouble *MEDCoupling1DGTUMesh::computeIsoBarycenterOfNodesPerCell() const -{ - MEDCouplingAutoRefCountObjectPtr ret=DataArrayDouble::New(); - int spaceDim=getSpaceDimension(); - int nbOfCells=getNumberOfCells();//checkCoherency() - int nbOfNodes=getNumberOfNodes(); - ret->alloc(nbOfCells,spaceDim); - double *ptToFill=ret->getPointer(); - const double *coor=_coords->begin(); - const int *nodal=_conn->begin(),*nodali=_conn_indx->begin(); - nodal+=nodali[0]; - if(getCellModelEnum()!=INTERP_KERNEL::NORM_POLYHED) - { - for(int i=0;i= to avoid division by 0. - { - for(int j=nodali[0];j=0 && *nodal()); - else - { - std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::computeIsoBarycenterOfNodesPerCell : on cell #" << i << " presence of nodeId #" << *nodal << " should be in [0," << nbOfNodes << ") !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - std::transform(ptToFill,ptToFill+spaceDim,ptToFill,std::bind2nd(std::multiplies(),1./(nodali[1]-nodali[0]))); - } - } - else - { - std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::computeIsoBarycenterOfNodesPerCell : at cell #" << i << " the nodal index array is invalid !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - } - } - else - { - for(int i=0;i= to avoid division by 0. - { - int nbOfNod=0; - for(int j=nodali[0];j=0 && *nodal()); - nbOfNod++; - } - else - { - std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::computeIsoBarycenterOfNodesPerCell (polyhedron) : on cell #" << i << " presence of nodeId #" << *nodal << " should be in [0," << nbOfNodes << ") !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - } - if(nbOfNod!=0) - std::transform(ptToFill,ptToFill+spaceDim,ptToFill,std::bind2nd(std::multiplies(),1./nbOfNod)); - else - { - std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::computeIsoBarycenterOfNodesPerCell (polyhedron) : no nodes in cell #" << i << " !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - } - else - { - std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::computeIsoBarycenterOfNodesPerCell (polyhedron) : at cell #" << i << " the nodal index array is invalid !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - } - } - return ret.retn(); -} - -void MEDCoupling1DGTUMesh::renumberCells(const int *old2NewBg, bool check) -{ - int nbCells=getNumberOfCells(); - MEDCouplingAutoRefCountObjectPtr o2n=DataArrayInt::New(); - o2n->useArray(old2NewBg,false,C_DEALLOC,nbCells,1); - if(check) - o2n=o2n->checkAndPreparePermutation(); - // - const int *o2nPtr=o2n->getPointer(); - const int *conn=_conn->begin(),*conni=_conn_indx->begin(); - MEDCouplingAutoRefCountObjectPtr newConn=DataArrayInt::New(); - MEDCouplingAutoRefCountObjectPtr newConnI=DataArrayInt::New(); - newConn->alloc(_conn->getNumberOfTuples(),1); newConnI->alloc(nbCells,1); - newConn->copyStringInfoFrom(*_conn); newConnI->copyStringInfoFrom(*_conn_indx); - // - int *newC=newConn->getPointer(),*newCI=newConnI->getPointer(); - for(int i=0;i=0) - newCI[newPos]=sz; - else - { - std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::renumberCells : the index nodal array is invalid for cell #" << i << " !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - } - newConnI->computeOffsets2(); newCI=newConnI->getPointer(); - // - for(int i=0;igetType()!=SINGLE_DYNAMIC_GEO_TYPE_UNSTRUCTURED) - throw INTERP_KERNEL::Exception("Merge of umesh only available with umesh single dynamic geo type each other !"); - const MEDCoupling1DGTUMesh *otherC=static_cast(other); - return Merge1DGTUMeshes(this,otherC); -} - -MEDCouplingUMesh *MEDCoupling1DGTUMesh::buildUnstructured() const -{ - MEDCouplingAutoRefCountObjectPtr ret=MEDCouplingUMesh::New(getName(),getMeshDimension()); - ret->setCoords(getCoords()); - const int *nodalConn=_conn->begin(),*nodalConnI=_conn_indx->begin(); - int nbCells=getNumberOfCells();//checkCoherency - int geoType=(int)getCellModelEnum(); - MEDCouplingAutoRefCountObjectPtr c=DataArrayInt::New(); c->alloc(nbCells+_conn->getNumberOfTuples(),1); - MEDCouplingAutoRefCountObjectPtr cI=DataArrayInt::New(); cI->alloc(nbCells+1); - int *cPtr=c->getPointer(),*ciPtr=cI->getPointer(); - ciPtr[0]=0; - for(int i=0;i=0) - { - *cPtr++=geoType; - cPtr=std::copy(nodalConn+nodalConnI[i],nodalConn+nodalConnI[i+1],cPtr); - ciPtr[1]=ciPtr[0]+sz+1; - } - else - { - std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::buildUnstructured : Invalid for nodal index for cell #" << i << " !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - } - ret->setConnectivity(c,cI,true); - try - { ret->copyTinyInfoFrom(this); } - catch(INTERP_KERNEL::Exception&) { } - return ret.retn(); -} - -/*! - * Do nothing for the moment, because there is no policy that allows to split polygons, polyhedrons ... into simplexes - */ -DataArrayInt *MEDCoupling1DGTUMesh::simplexize(int policy) -{ - int nbOfCells=getNumberOfCells(); - MEDCouplingAutoRefCountObjectPtr ret=DataArrayInt::New(); - ret->alloc(nbOfCells,1); - ret->iota(0); - return ret.retn(); -} - -void MEDCoupling1DGTUMesh::reprQuickOverview(std::ostream& stream) const -{ - stream << "MEDCoupling1DGTUMesh C++ instance at " << this << ". Type=" << _cm->getRepr() << ". Name : \"" << getName() << "\"."; - stream << " Mesh dimension : " << getMeshDimension() << "."; - if(!_coords) - { stream << " No coordinates set !"; return ; } - if(!_coords->isAllocated()) - { stream << " Coordinates set but not allocated !"; return ; } - stream << " Space dimension : " << _coords->getNumberOfComponents() << "." << std::endl; - stream << "Number of nodes : " << _coords->getNumberOfTuples() << "."; - bool isOK=true; - try { checkCoherency(); } catch(INTERP_KERNEL::Exception& /* e */) - { - stream << std::endl << "Nodal connectivity NOT set properly !\n"; - isOK=false; - } - if(isOK) - stream << std::endl << "Number of cells : " << getNumberOfCells() << "."; -} - -void MEDCoupling1DGTUMesh::shallowCopyConnectivityFrom(const MEDCouplingPointSet *other) -{ - if(!other) - throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::shallowCopyConnectivityFrom : input pointer is null !"); - const MEDCoupling1DGTUMesh *otherC=dynamic_cast(other); - if(!otherC) - throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::shallowCopyConnectivityFrom : input pointer is not an MEDCoupling1DGTUMesh instance !"); - setNodalConnectivity(otherC->getNodalConnectivity(),otherC->getNodalConnectivityIndex()); -} - -MEDCouplingPointSet *MEDCoupling1DGTUMesh::mergeMyselfWithOnSameCoords(const MEDCouplingPointSet *other) const -{ - if(!other) - throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::mergeMyselfWithOnSameCoords : input other is null !"); - const MEDCoupling1DGTUMesh *otherC=dynamic_cast(other); - if(!otherC) - throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::mergeMyselfWithOnSameCoords : the input other mesh is not of type single statuc geo type unstructured !"); - std::vector ms(2); - ms[0]=this; - ms[1]=otherC; - return Merge1DGTUMeshesOnSameCoords(ms); -} - -MEDCouplingPointSet *MEDCoupling1DGTUMesh::buildPartOfMySelfKeepCoords(const int *begin, const int *end) const -{ - checkCoherency(); - MEDCouplingAutoRefCountObjectPtr ret(new MEDCoupling1DGTUMesh(getName(),*_cm)); - ret->setCoords(_coords); - DataArrayInt *c=0,*ci=0; - MEDCouplingUMesh::ExtractFromIndexedArrays(begin,end,_conn,_conn_indx,c,ci); - MEDCouplingAutoRefCountObjectPtr cSafe(c),ciSafe(ci); - ret->setNodalConnectivity(c,ci); - return ret.retn(); -} - -MEDCouplingPointSet *MEDCoupling1DGTUMesh::buildPartOfMySelfKeepCoords2(int start, int end, int step) const -{ - checkCoherency(); - MEDCouplingAutoRefCountObjectPtr ret(new MEDCoupling1DGTUMesh(getName(),*_cm)); - ret->setCoords(_coords); - DataArrayInt *c=0,*ci=0; - MEDCouplingUMesh::ExtractFromIndexedArrays2(start,end,step,_conn,_conn_indx,c,ci); - MEDCouplingAutoRefCountObjectPtr cSafe(c),ciSafe(ci); - ret->setNodalConnectivity(c,ci); - return ret.retn(); -} - -void MEDCoupling1DGTUMesh::computeNodeIdsAlg(std::vector& nodeIdsInUse) const -{ - checkCoherency2(); - int sz((int)nodeIdsInUse.size()); - for(const int *conn=_conn->begin();conn!=_conn->end();conn++) - { - if(*conn>=0 && *connbegin(),conn) << " value is " << *conn << " must be in [0," << sz << ") !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - } - } -} - -void MEDCoupling1DGTUMesh::getReverseNodalConnectivity(DataArrayInt *revNodal, DataArrayInt *revNodalIndx) const -{ - checkFullyDefined(); - int nbOfNodes=getNumberOfNodes(); - 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=_conn->begin(),*conni=_conn_indx->begin(); - int nbOfCells=getNumberOfCells(); - int nbOfEltsInRevNodal=0; - for(int eltId=0;eltId=0) - { - for(int j=0;j=0 && nodeId()); - conn=_conn->begin(); - 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;eltId(),-1))=eltId; - } - } -} - -void MEDCoupling1DGTUMesh::checkFullyDefined() const -{ - if(!((const DataArrayInt *)_conn) || !((const DataArrayInt *)_conn_indx) || !((const DataArrayDouble *)_coords)) - throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::checkFullyDefined : part of this is not fully defined."); -} - -bool MEDCoupling1DGTUMesh::isEmptyMesh(const std::vector& tinyInfo) const -{ - throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::isEmptyMesh : not implemented yet !"); -} - -void MEDCoupling1DGTUMesh::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,littleStrings3,littleStrings4; - if((const DataArrayDouble *)_coords) - _coords->getTinySerializationStrInformation(littleStrings2); - if((const DataArrayInt *)_conn) - _conn->getTinySerializationStrInformation(littleStrings3); - if((const DataArrayInt *)_conn_indx) - _conn_indx->getTinySerializationStrInformation(littleStrings4); - int sz0((int)littleStrings2.size()),sz1((int)littleStrings3.size()),sz2((int)littleStrings4.size()); - littleStrings.insert(littleStrings.end(),littleStrings2.begin(),littleStrings2.end()); - littleStrings.insert(littleStrings.end(),littleStrings3.begin(),littleStrings3.end()); - littleStrings.insert(littleStrings.end(),littleStrings4.begin(),littleStrings4.end()); - // - tinyInfo.push_back(getCellModelEnum()); - tinyInfo.push_back(it); - tinyInfo.push_back(order); - std::vector tinyInfo2,tinyInfo3,tinyInfo4; - if((const DataArrayDouble *)_coords) - _coords->getTinySerializationIntInformation(tinyInfo2); - if((const DataArrayInt *)_conn) - _conn->getTinySerializationIntInformation(tinyInfo3); - if((const DataArrayInt *)_conn_indx) - _conn_indx->getTinySerializationIntInformation(tinyInfo4); - int sz3((int)tinyInfo2.size()),sz4((int)tinyInfo3.size()),sz5((int)tinyInfo4.size()); - tinyInfo.push_back(sz0); tinyInfo.push_back(sz1); tinyInfo.push_back(sz2); tinyInfo.push_back(sz3); tinyInfo.push_back(sz4); tinyInfo.push_back(sz5); - tinyInfo.insert(tinyInfo.end(),tinyInfo2.begin(),tinyInfo2.end()); - tinyInfo.insert(tinyInfo.end(),tinyInfo3.begin(),tinyInfo3.end()); - tinyInfo.insert(tinyInfo.end(),tinyInfo4.begin(),tinyInfo4.end()); - // - tinyInfoD.push_back(time); -} - -void MEDCoupling1DGTUMesh::resizeForUnserialization(const std::vector& tinyInfo, DataArrayInt *a1, DataArrayDouble *a2, std::vector& littleStrings) const -{ - std::vector tinyInfo2(tinyInfo.begin()+9,tinyInfo.begin()+9+tinyInfo[6]); - std::vector tinyInfo1(tinyInfo.begin()+9+tinyInfo[6],tinyInfo.begin()+9+tinyInfo[6]+tinyInfo[7]); - std::vector tinyInfo12(tinyInfo.begin()+9+tinyInfo[6]+tinyInfo[7],tinyInfo.begin()+9+tinyInfo[6]+tinyInfo[7]+tinyInfo[8]); - MEDCouplingAutoRefCountObjectPtr p1(DataArrayInt::New()); p1->resizeForUnserialization(tinyInfo1); - MEDCouplingAutoRefCountObjectPtr p2(DataArrayInt::New()); p2->resizeForUnserialization(tinyInfo12); - std::vector v(2); v[0]=p1; v[1]=p2; - p2=DataArrayInt::Aggregate(v); - a2->resizeForUnserialization(tinyInfo2); - a1->alloc(p2->getNbOfElems(),1); -} - -void MEDCoupling1DGTUMesh::serialize(DataArrayInt *&a1, DataArrayDouble *&a2) const -{ - int sz(0); - if((const DataArrayInt *)_conn) - if(_conn->isAllocated()) - sz=_conn->getNbOfElems(); - if((const DataArrayInt *)_conn_indx) - if(_conn_indx->isAllocated()) - sz+=_conn_indx->getNbOfElems(); - a1=DataArrayInt::New(); - a1->alloc(sz,1); - int *work(a1->getPointer()); - if(sz!=0 && (const DataArrayInt *)_conn) - work=std::copy(_conn->begin(),_conn->end(),a1->getPointer()); - if(sz!=0 && (const DataArrayInt *)_conn_indx) - std::copy(_conn_indx->begin(),_conn_indx->end(),work); - 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 MEDCoupling1DGTUMesh::unserialization(const std::vector& tinyInfoD, const std::vector& tinyInfo, const DataArrayInt *a1, DataArrayDouble *a2, - const std::vector& littleStrings) -{ - INTERP_KERNEL::NormalizedCellType gt((INTERP_KERNEL::NormalizedCellType)tinyInfo[0]); - _cm=&INTERP_KERNEL::CellModel::GetCellModel(gt); - setName(littleStrings[0]); - setDescription(littleStrings[1]); - setTimeUnit(littleStrings[2]); - setTime(tinyInfoD[0],tinyInfo[1],tinyInfo[2]); - int sz0(tinyInfo[3]),sz1(tinyInfo[4]),sz2(tinyInfo[5]),sz3(tinyInfo[6]),sz4(tinyInfo[7]),sz5(tinyInfo[8]); - // - _coords=DataArrayDouble::New(); - std::vector tinyInfo2(tinyInfo.begin()+9,tinyInfo.begin()+9+sz3); - _coords->resizeForUnserialization(tinyInfo2); - std::copy(a2->begin(),a2->end(),_coords->getPointer()); - _conn=DataArrayInt::New(); - std::vector tinyInfo3(tinyInfo.begin()+9+sz3,tinyInfo.begin()+9+sz3+sz4); - _conn->resizeForUnserialization(tinyInfo3); - std::copy(a1->begin(),a1->begin()+_conn->getNbOfElems(),_conn->getPointer()); - _conn_indx=DataArrayInt::New(); - std::vector tinyInfo4(tinyInfo.begin()+9+sz3+sz4,tinyInfo.begin()+9+sz3+sz4+sz5); - _conn_indx->resizeForUnserialization(tinyInfo4); - std::copy(a1->begin()+_conn->getNbOfElems(),a1->end(),_conn_indx->getPointer()); - std::vector littleStrings2(littleStrings.begin()+3,littleStrings.begin()+3+sz0); - _coords->finishUnserialization(tinyInfo2,littleStrings2); - std::vector littleStrings3(littleStrings.begin()+3+sz0,littleStrings.begin()+3+sz0+sz1); - _conn->finishUnserialization(tinyInfo3,littleStrings3); - std::vector littleStrings4(littleStrings.begin()+3+sz0+sz1,littleStrings.begin()+3+sz0+sz1+sz2); - _conn_indx->finishUnserialization(tinyInfo4,littleStrings4); -} - -/*! - * Finds nodes not used in any cell and returns an array giving a new id to every node - * by excluding the unused nodes, for which the array holds -1. The result array is - * a mapping in "Old to New" mode. - * \param [out] nbrOfNodesInUse - number of node ids present in the nodal connectivity. - * \return DataArrayInt * - a new instance of DataArrayInt. Its length is \a - * this->getNumberOfNodes(). It holds for each node of \a this mesh either -1 - * if the node is unused or a new id else. The caller is to delete this - * array using decrRef() as it is no more needed. - * \throw If the coordinates array is not set. - * \throw If the nodal connectivity of cells is not defined. - * \throw If the nodal connectivity includes an invalid id. - * \sa MEDCoupling1DGTUMesh::getNodeIdsInUse, areAllNodesFetched - */ -DataArrayInt *MEDCoupling1DGTUMesh::computeFetchedNodeIds() const -{ - checkCoherency2(); - int nbNodes(getNumberOfNodes()); - std::vector fetchedNodes(nbNodes,false); - computeNodeIdsAlg(fetchedNodes); - int sz((int)std::count(fetchedNodes.begin(),fetchedNodes.end(),true)); - MEDCouplingAutoRefCountObjectPtr ret(DataArrayInt::New()); ret->alloc(sz,1); - int *retPtr(ret->getPointer()); - for(int i=0;igetNumberOfNodes(). It holds for each node of \a this mesh either -1 - * if the node is unused or a new id else. The caller is to delete this - * array using decrRef() as it is no more needed. - * \throw If the coordinates array is not set. - * \throw If the nodal connectivity of cells is not defined. - * \throw If the nodal connectivity includes an invalid id. - * \sa MEDCoupling1DGTUMesh::computeFetchedNodeIds, areAllNodesFetched - */ -DataArrayInt *MEDCoupling1DGTUMesh::getNodeIdsInUse(int& nbrOfNodesInUse) const -{ - nbrOfNodesInUse=-1; - int nbOfNodes=getNumberOfNodes(); - int nbOfCells=getNumberOfCells();//checkCoherency - MEDCouplingAutoRefCountObjectPtr ret=DataArrayInt::New(); - ret->alloc(nbOfNodes,1); - int *traducer=ret->getPointer(); - std::fill(traducer,traducer+nbOfNodes,-1); - const int *conn=_conn->begin(),*conni(_conn_indx->begin()); - for(int i=0;i=0 && nodeIdgetNumberOfTuples()); - int *pt(_conn->getPointer()); - for(int i=0;i& newNodeNumbersO2N) -{ - getNumberOfCells();//only to check that all is well defined. - // - int nbElemsIn(getNumberOfNodes()),nbOfTuples(_conn->getNumberOfTuples()); - int *pt(_conn->getPointer()); - for(int i=0;i=0 && *pt::const_iterator it(newNodeNumbersO2N.find(*pt)); - if(it!=newNodeNumbersO2N.end()) - *pt=(*it).second; - else - { - std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::renumberNodesInConn : At pos #" << i << " of connectivity, node id is " << *pt << ". Not in keys of input map !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - } - else - { - std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::renumberNodesInConn : error on tuple #" << i << " value is " << *pt << " and indirectionnal array as a size equal to " << nbElemsIn; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - } - // - updateTime(); -} - -/*! - * Changes ids of nodes within the nodal connectivity arrays according to a permutation - * array in "Old to New" mode. The node coordinates array is \b not changed by this method. - * This method is a generalization of shiftNodeNumbersInConn(). - * \warning This method performs no check of validity of new ids. **Use it with care !** - * \param [in] newNodeNumbersO2N - a permutation array, of length \a - * this->getNumberOfNodes(), in "Old to New" mode. - * See \ref numbering for more info on renumbering modes. - * \throw If the nodal connectivity of cells is not defined. - */ -void MEDCoupling1DGTUMesh::renumberNodesInConn(const int *newNodeNumbersO2N) -{ - getNumberOfCells();//only to check that all is well defined. - // - int nbElemsIn(getNumberOfNodes()),nbOfTuples(_conn->getNumberOfTuples()); - int *pt(_conn->getPointer()); - for(int i=0;i=0 && *pt cellIdsKept=DataArrayInt::New(); cellIdsKept->alloc(0,1); - int tmp=-1; - int sz=_conn->getMaxValue(tmp); sz=std::max(sz,0)+1; - std::vector fastFinder(sz,false); - for(const int *work=begin;work!=end;work++) - if(*work>=0 && *workbegin(),*conni=_conn_indx->begin(); - for(int i=0;i=0) - { - for(int j=0;j=0) - { - ref++; - if(fastFinder[nodeId]) - nbOfHit++; - } - } - } - else - { - std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::fillCellIdsToKeepFromNodeIds : invalid index array for cell #" << i << " !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - if((ref==nbOfHit && fullyIn) || (nbOfHit!=0 && !fullyIn)) - cellIdsKept->pushBackSilent(i); - } - cellIdsKeptArr=cellIdsKept.retn(); -} - -void MEDCoupling1DGTUMesh::allocateCells(int nbOfCells) -{ - if(nbOfCells<0) - throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::allocateCells : the input number of cells should be >= 0 !"); - _conn=DataArrayInt::New(); - _conn->reserve(nbOfCells*3); - _conn_indx=DataArrayInt::New(); - _conn_indx->reserve(nbOfCells+1); _conn_indx->pushBackSilent(0); - declareAsNew(); -} - -/*! - * Appends at the end of \a this a cell having nodal connectivity array defined in [ \a nodalConnOfCellBg, \a nodalConnOfCellEnd ). - * - * \param [in] nodalConnOfCellBg - the begin (included) of nodal connectivity of the cell to add. - * \param [in] nodalConnOfCellEnd - the end (excluded) of nodal connectivity of the cell to add. - * \throw If the length of the input nodal connectivity array of the cell to add is not equal to number of nodes per cell relative to the unique geometric type - * attached to \a this. - * \thow If the nodal connectivity array in \a this is null (call MEDCoupling1SGTUMesh::allocateCells before). - */ -void MEDCoupling1DGTUMesh::insertNextCell(const int *nodalConnOfCellBg, const int *nodalConnOfCellEnd) -{ - int sz=(int)std::distance(nodalConnOfCellBg,nodalConnOfCellEnd); - DataArrayInt *c(_conn),*c2(_conn_indx); - if(c && c2) - { - int pos=c2->back(); - if(pos==c->getNumberOfTuples()) - { - c->pushBackValsSilent(nodalConnOfCellBg,nodalConnOfCellEnd); - c2->pushBackSilent(pos+sz); - } - else - { - std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::insertNextCell : The nodal index array (end=" << pos << ") mismatches with nodal array (length=" << c->getNumberOfTuples() << ") !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - } - else - throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::insertNextCell : nodal connectivity array is null ! Call MEDCoupling1DGTUMesh::allocateCells before !"); -} - -void MEDCoupling1DGTUMesh::setNodalConnectivity(DataArrayInt *nodalConn, DataArrayInt *nodalConnIndex) -{ - if(nodalConn) - nodalConn->incrRef(); - _conn=nodalConn; - if(nodalConnIndex) - nodalConnIndex->incrRef(); - _conn_indx=nodalConnIndex; - declareAsNew(); -} - -/*! - * \return DataArrayInt * - the internal reference to the nodal connectivity. The caller is not reponsible to deallocate it. - */ -DataArrayInt *MEDCoupling1DGTUMesh::getNodalConnectivity() const -{ - const DataArrayInt *ret(_conn); - return const_cast(ret); -} - -/*! - * \return DataArrayInt * - the internal reference to the nodal connectivity index. The caller is not reponsible to deallocate it. - */ -DataArrayInt *MEDCoupling1DGTUMesh::getNodalConnectivityIndex() const -{ - const DataArrayInt *ret(_conn_indx); - return const_cast(ret); -} - -/*! - * See the definition of the nodal connectivity pack \ref MEDCoupling1DGTUMesh::isPacked "here". - * This method tries to build a new instance geometrically equivalent to \a this, by limiting at most the number of new object (nodal connectivity). - * Geometrically the returned mesh is equal to \a this. So if \a this is already packed, the return value is a shallow copy of \a this. - * - * Whatever the status of pack of \a this, the coordinates array of the returned newly created instance is the same than those in \a this. - * - * \param [out] isShallowCpyOfNodalConnn - tells if the returned instance share the same pair of nodal connectivity arrays (true) or if nodal - * connectivity arrays are different (false) - * \return a new object to be managed by the caller. - * - * \sa MEDCoupling1DGTUMesh::retrievePackedNodalConnectivity, MEDCoupling1DGTUMesh::isPacked - */ -MEDCoupling1DGTUMesh *MEDCoupling1DGTUMesh::copyWithNodalConnectivityPacked(bool& isShallowCpyOfNodalConnn) const -{ - MEDCouplingAutoRefCountObjectPtr ret(new MEDCoupling1DGTUMesh(getName(),*_cm)); - DataArrayInt *nc=0,*nci=0; - isShallowCpyOfNodalConnn=retrievePackedNodalConnectivity(nc,nci); - MEDCouplingAutoRefCountObjectPtr ncs(nc),ncis(nci); - ret->_conn=ncs; ret->_conn_indx=ncis; - ret->setCoords(getCoords()); - return ret.retn(); -} - -/*! - * This method allows to compute, if needed, the packed nodal connectivity pair. - * Indeed, it is possible to store in \a this a nodal connectivity array bigger than ranges convered by nodal connectivity index array. - * It is typically the case when nodalConnIndx starts with an id greater than 0, and finishes with id less than number of tuples in \c this->_conn. - * - * If \a this looks packed (the front of nodal connectivity index equal to 0 and back of connectivity index equal to number of tuple of nodal connectivity array) - * true will be returned and respectively \a this->_conn and \a this->_conn_indx (with ref counter incremented). This is the classical case. - * - * If nodal connectivity index points to a subpart of nodal connectivity index the packed pair of arrays will be computed (new objects) and returned and false - * will be returned. - * - * This method return 3 elements. - * \param [out] nodalConn - a pointer that can be equal to \a this->_conn if true is returned (general case). Whatever the value of return parameter - * this pointer can be seen as a new object, that is to managed by the caller. - * \param [out] nodalConnIndx - a pointer that can be equal to \a this->_conn_indx if true is returned (general case). Whatever the value of return parameter - * this pointer can be seen as a new object, that is to managed by the caller. - * \return bool - an indication of the content of the 2 output parameters. If true, \a this looks packed (general case), if true, \a this is not packed then - * output parameters are newly created objects. - * - * \throw if \a this does not pass MEDCoupling1DGTUMesh::checkCoherency test - */ -bool MEDCoupling1DGTUMesh::retrievePackedNodalConnectivity(DataArrayInt *&nodalConn, DataArrayInt *&nodalConnIndx) const -{ - if(isPacked())//performs the checkCoherency - { - const DataArrayInt *c0(_conn),*c1(_conn_indx); - nodalConn=const_cast(c0); nodalConnIndx=const_cast(c1); - nodalConn->incrRef(); nodalConnIndx->incrRef(); - return true; - } - int bg=_conn_indx->front(),end=_conn_indx->back(); - MEDCouplingAutoRefCountObjectPtr nc(_conn->selectByTupleId2(bg,end,1)); - MEDCouplingAutoRefCountObjectPtr nci(_conn_indx->deepCpy()); - nci->applyLin(1,-bg); - nodalConn=nc.retn(); nodalConnIndx=nci.retn(); - return false; -} - -/* - * If \a this looks packed (the front of nodal connectivity index equal to 0 and back of connectivity index equal to number of tuple of nodal connectivity array) - * true will be returned and respectively \a this->_conn and \a this->_conn_indx (with ref counter incremented). This is the classical case. - * If nodal connectivity index points to a subpart of nodal connectivity index false will be returned. - * \return bool - true if \a this looks packed, false is not. - * - * \throw if \a this does not pass MEDCoupling1DGTUMesh::checkCoherency test - */ -bool MEDCoupling1DGTUMesh::isPacked() const -{ - checkCoherency(); - return _conn_indx->front()==0 && _conn_indx->back()==_conn->getNumberOfTuples(); -} - -MEDCoupling1DGTUMesh *MEDCoupling1DGTUMesh::Merge1DGTUMeshes(const MEDCoupling1DGTUMesh *mesh1, const MEDCoupling1DGTUMesh *mesh2) -{ - std::vector tmp(2); - tmp[0]=const_cast(mesh1); tmp[1]=const_cast(mesh2); - return Merge1DGTUMeshes(tmp); -} - -MEDCoupling1DGTUMesh *MEDCoupling1DGTUMesh::Merge1DGTUMeshes(std::vector& a) -{ - std::size_t sz=a.size(); - if(sz==0) - return Merge1DGTUMeshesLL(a); - for(std::size_t ii=0;iigetCellModel()); - for(std::size_t ii=0;iigetCellModel())!=cm) - throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::Merge1DGTUMeshes : all items must have the same geo type !"); - std::vector< MEDCouplingAutoRefCountObjectPtr > bb(sz); - std::vector< const MEDCoupling1DGTUMesh * > aa(sz); - int spaceDim=-3; - for(std::size_t i=0;igetCoords(); - if(coo) - spaceDim=coo->getNumberOfComponents(); - } - if(spaceDim==-3) - throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::Merge1DGTUMeshes : no spaceDim specified ! unable to perform merge !"); - for(std::size_t i=0;ibuildSetInstanceFromThis(spaceDim); - aa[i]=bb[i]; - } - return Merge1DGTUMeshesLL(aa); -} - -/*! - * \throw If presence of a null instance in the input vector \a a. - * \throw If a is empty - */ -MEDCoupling1DGTUMesh *MEDCoupling1DGTUMesh::Merge1DGTUMeshesOnSameCoords(std::vector& a) -{ - if(a.empty()) - throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::Merge1DGTUMeshesOnSameCoords : input array must be NON EMPTY !"); - std::vector::const_iterator it=a.begin(); - if(!(*it)) - throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::Merge1DGTUMeshesOnSameCoords : null instance in the first element of input vector !"); - std::vector< MEDCouplingAutoRefCountObjectPtr > objs(a.size()); - std::vector ncs(a.size()),ncis(a.size()); - (*it)->getNumberOfCells();//to check that all is OK - const DataArrayDouble *coords=(*it)->getCoords(); - const INTERP_KERNEL::CellModel *cm=&((*it)->getCellModel()); - bool tmp; - objs[0]=(*it)->copyWithNodalConnectivityPacked(tmp); - ncs[0]=objs[0]->getNodalConnectivity(); ncis[0]=objs[0]->getNodalConnectivityIndex(); - it++; - for(int i=1;it!=a.end();i++,it++) - { - if(!(*it)) - throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::Merge1DGTUMeshesOnSameCoords : presence of null instance !"); - if(cm!=&((*it)->getCellModel())) - throw INTERP_KERNEL::Exception("Geometric types mismatches, Merge1DGTUMeshes impossible !"); - (*it)->getNumberOfCells();//to check that all is OK - objs[i]=(*it)->copyWithNodalConnectivityPacked(tmp); - ncs[i]=objs[i]->getNodalConnectivity(); ncis[i]=objs[i]->getNodalConnectivityIndex(); - if(coords!=(*it)->getCoords()) - throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::Merge1DGTUMeshesOnSameCoords : not lying on same coords !"); - } - MEDCouplingAutoRefCountObjectPtr ret(new MEDCoupling1DGTUMesh("merge",*cm)); - ret->setCoords(coords); - ret->_conn=DataArrayInt::Aggregate(ncs); - ret->_conn_indx=DataArrayInt::AggregateIndexes(ncis); - return ret.retn(); -} - -/*! - * Assume that all instances in \a a are non null. If null it leads to a crash. That's why this method is assigned to be low level (LL) - */ -MEDCoupling1DGTUMesh *MEDCoupling1DGTUMesh::Merge1DGTUMeshesLL(std::vector& a) -{ - if(a.empty()) - throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::Merge1DGTUMeshes : input array must be NON EMPTY !"); - std::vector< MEDCouplingAutoRefCountObjectPtr > objs(a.size()); - std::vector ncs(a.size()),ncis(a.size()); - std::vector::const_iterator it=a.begin(); - std::vector nbNodesPerElt(a.size()); - int nbOfCells=(*it)->getNumberOfCells(); - bool tmp; - objs[0]=(*it)->copyWithNodalConnectivityPacked(tmp); - ncs[0]=objs[0]->getNodalConnectivity(); ncis[0]=objs[0]->getNodalConnectivityIndex(); - nbNodesPerElt[0]=0; - int prevNbOfNodes=(*it)->getNumberOfNodes(); - const INTERP_KERNEL::CellModel *cm=&((*it)->getCellModel()); - it++; - for(int i=1;it!=a.end();i++,it++) - { - if(cm!=&((*it)->getCellModel())) - throw INTERP_KERNEL::Exception("Geometric types mismatches, Merge1DGTUMeshes impossible !"); - objs[i]=(*it)->copyWithNodalConnectivityPacked(tmp); - ncs[i]=objs[i]->getNodalConnectivity(); ncis[i]=objs[i]->getNodalConnectivityIndex(); - nbOfCells+=(*it)->getNumberOfCells(); - nbNodesPerElt[i]=nbNodesPerElt[i-1]+prevNbOfNodes; - prevNbOfNodes=(*it)->getNumberOfNodes(); - } - std::vector aps(a.size()); - std::copy(a.begin(),a.end(),aps.begin()); - MEDCouplingAutoRefCountObjectPtr pts=MergeNodesArray(aps); - MEDCouplingAutoRefCountObjectPtr ret(new MEDCoupling1DGTUMesh("merge",*cm)); - ret->setCoords(pts); - ret->_conn=AggregateNodalConnAndShiftNodeIds(ncs,nbNodesPerElt); - ret->_conn_indx=DataArrayInt::AggregateIndexes(ncis); - return ret.retn(); -} - -MEDCoupling1DGTUMesh *MEDCoupling1DGTUMesh::buildSetInstanceFromThis(int spaceDim) const -{ - MEDCouplingAutoRefCountObjectPtr ret(new MEDCoupling1DGTUMesh(getName(),*_cm)); - MEDCouplingAutoRefCountObjectPtr tmp1,tmp2; - const DataArrayInt *nodalConn(_conn),*nodalConnI(_conn_indx); - if(!nodalConn) - { - tmp1=DataArrayInt::New(); tmp1->alloc(0,1); - } - else - tmp1=_conn; - ret->_conn=tmp1; - // - if(!nodalConnI) - { - tmp2=DataArrayInt::New(); tmp2->alloc(1,1); tmp2->setIJ(0,0,0); - } - else - tmp2=_conn_indx; - ret->_conn_indx=tmp2; - // - if(!_coords) - { - MEDCouplingAutoRefCountObjectPtr coords=DataArrayDouble::New(); coords->alloc(0,spaceDim); - ret->setCoords(coords); - } - else - ret->setCoords(_coords); - return ret.retn(); -} - -/*! - * This method aggregate the bbox of each cell and put it into bbox parameter. - * - * \param [in] arcDetEps - a parameter specifying in case of 2D quadratic polygon cell the detection limit between linear and arc circle. (By default 1e-12) - * For all other cases this input parameter is ignored. - * \return DataArrayDouble * - newly created object (to be managed by the caller) \a this number of cells tuples and 2*spacedim components. - * - * \throw If \a this is not fully set (coordinates and connectivity). - * \throw If a cell in \a this has no valid nodeId. - */ -DataArrayDouble *MEDCoupling1DGTUMesh::getBoundingBoxForBBTree(double arcDetEps) const -{ - checkFullyDefined(); - int spaceDim(getSpaceDimension()),nbOfCells(getNumberOfCells()),nbOfNodes(getNumberOfNodes()); - MEDCouplingAutoRefCountObjectPtr ret(DataArrayDouble::New()); ret->alloc(nbOfCells,2*spaceDim); - double *bbox(ret->getPointer()); - for(int i=0;i::max(); - bbox[2*i+1]=-std::numeric_limits::max(); - } - const double *coordsPtr(_coords->getConstPointer()); - const int *conn(_conn->getConstPointer()),*connI(_conn_indx->getConstPointer()); - for(int i=0;i=0 && nodeId MEDCoupling1DGTUMesh::BuildAPolygonFromParts(const std::vector< std::vector >& parts) -{ - std::vector ret; - if(parts.empty()) - return ret; - ret.insert(ret.end(),parts[0].begin(),parts[0].end()); - int ref(ret.back()); - std::size_t sz(parts.size()),nbh(1); - std::vector b(sz,true); b[0]=false; - while(nbh& nodalConns, const std::vector& offsetInNodeIdsPerElt) -{ - std::size_t sz1(nodalConns.size()),sz2(offsetInNodeIdsPerElt.size()); - if(sz1!=sz2) - throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::AggregateNodalConnAndShiftNodeIds : input vectors do not have the same size !"); - if(sz1==0) - throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::AggregateNodalConnAndShiftNodeIds : empty vectors in input !"); - int nbOfTuples=0; - for(std::vector::const_iterator it=nodalConns.begin();it!=nodalConns.end();it++) - { - if(!(*it)) - throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::AggregateNodalConnAndShiftNodeIds : presence of null pointer in input vector !"); - if(!(*it)->isAllocated()) - throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::AggregateNodalConnAndShiftNodeIds : presence of non allocated array in input vector !"); - if((*it)->getNumberOfComponents()!=1) - throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::AggregateNodalConnAndShiftNodeIds : presence of array with not exactly one component !"); - nbOfTuples+=(*it)->getNumberOfTuples(); - } - MEDCouplingAutoRefCountObjectPtr ret=DataArrayInt::New(); ret->alloc(nbOfTuples,1); - int *pt=ret->getPointer(); - int i=0; - for(std::vector::const_iterator it=nodalConns.begin();it!=nodalConns.end();it++,i++) - { - int curNbt=(*it)->getNumberOfTuples(); - const int *inPt=(*it)->begin(); - int offset=offsetInNodeIdsPerElt[i]; - for(int j=0;j gts(m->getAllGeoTypes()); - if(gts.size()!=1) - throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::New : input mesh must have exactly one geometric type !"); - int geoType((int)*gts.begin()); - MEDCouplingAutoRefCountObjectPtr ret(MEDCoupling1DGTUMesh::New(m->getName(),*gts.begin())); - ret->setCoords(m->getCoords()); ret->setDescription(m->getDescription()); - int nbCells(m->getNumberOfCells()); - MEDCouplingAutoRefCountObjectPtr conn(DataArrayInt::New()),connI(DataArrayInt::New()); - conn->alloc(m->getMeshLength()-nbCells,1); connI->alloc(nbCells+1,1); - int *c(conn->getPointer()),*ci(connI->getPointer()); *ci=0; - const int *cin(m->getNodalConnectivity()->begin()),*ciin(m->getNodalConnectivityIndex()->begin()); - for(int i=0;i=1) - { - c=std::copy(cin+ciin[0]+1,cin+ciin[1],c); - ci[1]=ci[0]+ciin[1]-ciin[0]-1; - } - else - { - std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::New(const MEDCouplingUMesh *m) : something is wrong in the input mesh at cell #" << i << " ! The size of cell is not >=0 !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - } - else - { - std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::New(const MEDCouplingUMesh *m) : something is wrong in the input mesh at cell #" << i << " ! The geometric type is not those expected !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - } - ret->setNodalConnectivity(conn,connI); - return ret.retn(); -} diff --git a/src/MEDCoupling/MEDCoupling1GTUMesh.hxx b/src/MEDCoupling/MEDCoupling1GTUMesh.hxx deleted file mode 100644 index 9928bc48f..000000000 --- a/src/MEDCoupling/MEDCoupling1GTUMesh.hxx +++ /dev/null @@ -1,270 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 -// 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_MEDCOUPLING1GTUMESH_HXX__ -#define __PARAMEDMEM_MEDCOUPLING1GTUMESH_HXX__ - -#include "MEDCoupling.hxx" -#include "MEDCouplingPointSet.hxx" -#include "MEDCouplingMemArray.hxx" -#include "MEDCouplingAutoRefCountObjectPtr.hxx" - -#include "CellModel.hxx" - -namespace ParaMEDMEM -{ - class MEDCoupling1GTUUMeshCellIterator; - - class MEDCoupling1GTUMesh : public MEDCouplingPointSet - { - public: - MEDCOUPLING_EXPORT static MEDCoupling1GTUMesh *New(const std::string& name, INTERP_KERNEL::NormalizedCellType type); - MEDCOUPLING_EXPORT static MEDCoupling1GTUMesh *New(const MEDCouplingUMesh *m); - MEDCOUPLING_EXPORT const INTERP_KERNEL::CellModel& getCellModel() const; - MEDCOUPLING_EXPORT INTERP_KERNEL::NormalizedCellType getCellModelEnum() const; - MEDCOUPLING_EXPORT int getMeshDimension() const; - MEDCOUPLING_EXPORT DataArrayInt *giveCellsWithType(INTERP_KERNEL::NormalizedCellType type) const; - MEDCOUPLING_EXPORT int getNumberOfCellsWithType(INTERP_KERNEL::NormalizedCellType type) const; - MEDCOUPLING_EXPORT INTERP_KERNEL::NormalizedCellType getTypeOfCell(int cellId) const; - MEDCOUPLING_EXPORT std::set getAllGeoTypes() const; - MEDCOUPLING_EXPORT std::vector getDistributionOfTypes() const; - MEDCOUPLING_EXPORT void splitProfilePerType(const DataArrayInt *profile, std::vector& code, std::vector& idsInPflPerType, std::vector& idsPerType) const; - MEDCOUPLING_EXPORT DataArrayInt *checkTypeConsistencyAndContig(const std::vector& code, const std::vector& idsPerType) const; - MEDCOUPLING_EXPORT void writeVTKLL(std::ostream& ofs, const std::string& cellData, const std::string& pointData, DataArrayByte *byteData) const; - MEDCOUPLING_EXPORT std::string getVTKDataSetType() const; - MEDCOUPLING_EXPORT std::string getVTKFileExtension() const; - // - MEDCOUPLING_EXPORT std::size_t getHeapMemorySizeWithoutChildren() const; - MEDCOUPLING_EXPORT int getNodalConnectivityLength() const; - MEDCOUPLING_EXPORT bool isEqualIfNotWhy(const MEDCouplingMesh *other, double prec, std::string& reason) const; - MEDCOUPLING_EXPORT bool isEqualWithoutConsideringStr(const MEDCouplingMesh *other, double prec) const; - MEDCOUPLING_EXPORT void checkCoherency() const; - MEDCOUPLING_EXPORT DataArrayDouble *getBarycenterAndOwner() const; - MEDCOUPLING_EXPORT MEDCouplingFieldDouble *getMeasureField(bool isAbs) const; - MEDCOUPLING_EXPORT MEDCouplingFieldDouble *getMeasureFieldOnNode(bool isAbs) const; - MEDCOUPLING_EXPORT int getCellContainingPoint(const double *pos, double eps) const; - MEDCOUPLING_EXPORT MEDCouplingFieldDouble *buildOrthogonalField() const; - MEDCOUPLING_EXPORT DataArrayInt *getCellsInBoundingBox(const double *bbox, double eps) const; - MEDCOUPLING_EXPORT DataArrayInt *getCellsInBoundingBox(const INTERP_KERNEL::DirectedBoundingBox& bbox, double eps); - MEDCOUPLING_EXPORT MEDCouplingPointSet *buildFacePartOfMySelfNode(const int *start, const int *end, bool fullyIn) const; - MEDCOUPLING_EXPORT DataArrayInt *findBoundaryNodes() const; - MEDCOUPLING_EXPORT MEDCouplingPointSet *buildBoundaryMesh(bool keepCoords) const; - MEDCOUPLING_EXPORT void findCommonCells(int compType, int startCellId, DataArrayInt *& commonCellsArr, DataArrayInt *& commonCellsIArr) const; - MEDCOUPLING_EXPORT static MEDCouplingUMesh *AggregateOnSameCoordsToUMesh(const std::vector< const MEDCoupling1GTUMesh *>& parts); - public: - MEDCOUPLING_EXPORT virtual void allocateCells(int nbOfCells=0) = 0; - MEDCOUPLING_EXPORT virtual void insertNextCell(const int *nodalConnOfCellBg, const int *nodalConnOfCellEnd) = 0; - MEDCOUPLING_EXPORT virtual DataArrayInt *getNodalConnectivity() const = 0; - MEDCOUPLING_EXPORT virtual void checkCoherencyOfConnectivity() const = 0; - protected: - MEDCoupling1GTUMesh(const std::string& name, const INTERP_KERNEL::CellModel& cm); - MEDCoupling1GTUMesh(const MEDCoupling1GTUMesh& other, bool recDeepCpy); - MEDCoupling1GTUMesh(); - protected: - const INTERP_KERNEL::CellModel *_cm; - }; - - class MEDCoupling1DGTUMesh; - class MEDCouplingCMesh; - - class MEDCoupling1SGTUMesh : public MEDCoupling1GTUMesh - { - public: - MEDCOUPLING_EXPORT static MEDCoupling1SGTUMesh *New(const std::string& name, INTERP_KERNEL::NormalizedCellType type); - MEDCOUPLING_EXPORT static MEDCoupling1SGTUMesh *New(const MEDCouplingUMesh *m); - //! useless constructor only for CORBA -> not swigged - MEDCOUPLING_EXPORT static MEDCoupling1SGTUMesh *New(); - MEDCOUPLING_EXPORT MEDCoupling1SGTUMesh *clone(bool recDeepCpy) const; - MEDCOUPLING_EXPORT MEDCouplingPointSet *deepCpyConnectivityOnly() const; - // overload of TimeLabel and RefCountObject - MEDCOUPLING_EXPORT void updateTime() const; - MEDCOUPLING_EXPORT std::size_t getHeapMemorySizeWithoutChildren() const; - MEDCOUPLING_EXPORT std::vector getDirectChildrenWithNull() const; - // overload of MEDCouplingMesh - MEDCOUPLING_EXPORT MEDCouplingMeshType getType() const { return SINGLE_STATIC_GEO_TYPE_UNSTRUCTURED; } - MEDCOUPLING_EXPORT MEDCouplingMesh *deepCpy() const; - MEDCOUPLING_EXPORT bool isEqualIfNotWhy(const MEDCouplingMesh *other, double prec, std::string& reason) const; - MEDCOUPLING_EXPORT bool isEqualWithoutConsideringStr(const MEDCouplingMesh *other, double prec) const; - MEDCOUPLING_EXPORT void checkFastEquivalWith(const MEDCouplingMesh *other, double prec) const; - MEDCOUPLING_EXPORT void checkCoherency() const; - MEDCOUPLING_EXPORT void checkCoherency1(double eps=1e-12) const; - MEDCOUPLING_EXPORT void checkCoherency2(double eps=1e-12) const; - MEDCOUPLING_EXPORT int getNumberOfCells() const; - MEDCOUPLING_EXPORT DataArrayInt *computeNbOfNodesPerCell() const; - MEDCOUPLING_EXPORT DataArrayInt *computeNbOfFacesPerCell() const; - MEDCOUPLING_EXPORT DataArrayInt *computeEffectiveNbOfNodesPerCell() const; - MEDCOUPLING_EXPORT void getNodeIdsOfCell(int cellId, std::vector& conn) const; - MEDCOUPLING_EXPORT std::string simpleRepr() const; - MEDCOUPLING_EXPORT std::string advancedRepr() const; - MEDCOUPLING_EXPORT DataArrayDouble *computeIsoBarycenterOfNodesPerCell() const; - MEDCOUPLING_EXPORT void renumberCells(const int *old2NewBg, bool check=true); - MEDCOUPLING_EXPORT MEDCouplingMesh *mergeMyselfWith(const MEDCouplingMesh *other) const; - MEDCOUPLING_EXPORT MEDCouplingUMesh *buildUnstructured() const; - MEDCOUPLING_EXPORT DataArrayInt *simplexize(int policy); - MEDCOUPLING_EXPORT void reprQuickOverview(std::ostream& stream) const; - // overload of MEDCouplingPointSet - MEDCOUPLING_EXPORT void shallowCopyConnectivityFrom(const MEDCouplingPointSet *other); - MEDCOUPLING_EXPORT MEDCouplingPointSet *mergeMyselfWithOnSameCoords(const MEDCouplingPointSet *other) const; - MEDCOUPLING_EXPORT MEDCouplingPointSet *buildPartOfMySelfKeepCoords(const int *begin, const int *end) const; - MEDCOUPLING_EXPORT MEDCouplingPointSet *buildPartOfMySelfKeepCoords2(int start, int end, int step) const; - MEDCOUPLING_EXPORT void computeNodeIdsAlg(std::vector& nodeIdsInUse) const; - MEDCOUPLING_EXPORT void getReverseNodalConnectivity(DataArrayInt *revNodal, DataArrayInt *revNodalIndx) const; - MEDCOUPLING_EXPORT void checkFullyDefined() const; - MEDCOUPLING_EXPORT bool isEmptyMesh(const std::vector& tinyInfo) const; - MEDCOUPLING_EXPORT DataArrayInt *computeFetchedNodeIds() const; - MEDCOUPLING_EXPORT DataArrayInt *getNodeIdsInUse(int& nbrOfNodesInUse) const; - MEDCOUPLING_EXPORT void renumberNodesWithOffsetInConn(int offset); - MEDCOUPLING_EXPORT void renumberNodesInConn(const INTERP_KERNEL::HashMap& newNodeNumbersO2N); - MEDCOUPLING_EXPORT void renumberNodesInConn(const int *newNodeNumbersO2N); - MEDCOUPLING_EXPORT void fillCellIdsToKeepFromNodeIds(const int *begin, const int *end, bool fullyIn, DataArrayInt *&cellIdsKeptArr) const; - MEDCOUPLING_EXPORT int getNumberOfNodesInCell(int cellId) const; - MEDCOUPLING_EXPORT DataArrayDouble *getBoundingBoxForBBTree(double arcDetEps=1e-12) const; - MEDCOUPLING_EXPORT MEDCouplingFieldDouble *computeDiameterField() const; - // overload of MEDCoupling1GTUMesh - MEDCOUPLING_EXPORT void checkCoherencyOfConnectivity() const; - MEDCOUPLING_EXPORT void allocateCells(int nbOfCells=0); - MEDCOUPLING_EXPORT void insertNextCell(const int *nodalConnOfCellBg, const int *nodalConnOfCellEnd); - public://specific - MEDCOUPLING_EXPORT void setNodalConnectivity(DataArrayInt *nodalConn); - MEDCOUPLING_EXPORT DataArrayInt *getNodalConnectivity() const; - MEDCOUPLING_EXPORT int getNumberOfNodesPerCell() const; - MEDCOUPLING_EXPORT static MEDCoupling1SGTUMesh *Merge1SGTUMeshes(const MEDCoupling1SGTUMesh *mesh1, const MEDCoupling1SGTUMesh *mesh2); - MEDCOUPLING_EXPORT static MEDCoupling1SGTUMesh *Merge1SGTUMeshes(std::vector& a); - MEDCOUPLING_EXPORT static MEDCoupling1SGTUMesh *Merge1SGTUMeshesOnSameCoords(std::vector& a); - MEDCOUPLING_EXPORT MEDCoupling1SGTUMesh *buildSetInstanceFromThis(int spaceDim) const; - MEDCOUPLING_EXPORT MEDCoupling1GTUMesh *computeDualMesh() const; - MEDCOUPLING_EXPORT DataArrayInt *sortHexa8EachOther(); - MEDCOUPLING_EXPORT MEDCoupling1SGTUMesh *explodeEachHexa8To6Quad4() const; - MEDCOUPLING_EXPORT MEDCouplingCMesh *structurizeMe(DataArrayInt *& cellPerm, DataArrayInt *& nodePerm, double eps=1e-12) const; - public://serialization - MEDCOUPLING_EXPORT void getTinySerializationInformation(std::vector& tinyInfoD, std::vector& tinyInfo, std::vector& littleStrings) const; - MEDCOUPLING_EXPORT void resizeForUnserialization(const std::vector& tinyInfo, DataArrayInt *a1, DataArrayDouble *a2, std::vector& littleStrings) const; - MEDCOUPLING_EXPORT void serialize(DataArrayInt *&a1, DataArrayDouble *&a2) const; - MEDCOUPLING_EXPORT void unserialization(const std::vector& tinyInfoD, const std::vector& tinyInfo, const DataArrayInt *a1, DataArrayDouble *a2, - const std::vector& littleStrings); - private: - MEDCoupling1SGTUMesh(const std::string& name, const INTERP_KERNEL::CellModel& cm); - MEDCoupling1SGTUMesh(const MEDCoupling1SGTUMesh& other, bool recDeepCpy); - MEDCoupling1SGTUMesh(); - private: - void checkNonDynamicGeoType() const; - static MEDCoupling1SGTUMesh *Merge1SGTUMeshesLL(std::vector& a); - DataArrayInt *simplexizePol0(); - DataArrayInt *simplexizePol1(); - DataArrayInt *simplexizePlanarFace5(); - DataArrayInt *simplexizePlanarFace6(); - MEDCoupling1DGTUMesh *computeDualMesh3D() const; - MEDCoupling1DGTUMesh *computeDualMesh2D() const; - private: - MEDCouplingAutoRefCountObjectPtr _conn; - public: - static const int HEXA8_FACE_PAIRS[6]; - }; - - class MEDCoupling1DGTUMesh : public MEDCoupling1GTUMesh - { - public: - MEDCOUPLING_EXPORT static MEDCoupling1DGTUMesh *New(const std::string& name, INTERP_KERNEL::NormalizedCellType type); - MEDCOUPLING_EXPORT static MEDCoupling1DGTUMesh *New(const MEDCouplingUMesh *m); - //! useless constructor only for CORBA -> not swigged - MEDCOUPLING_EXPORT static MEDCoupling1DGTUMesh *New(); - MEDCOUPLING_EXPORT MEDCoupling1DGTUMesh *clone(bool recDeepCpy) const; - MEDCOUPLING_EXPORT MEDCouplingPointSet *deepCpyConnectivityOnly() const; - // overload of TimeLabel and RefCountObject - MEDCOUPLING_EXPORT void updateTime() const; - MEDCOUPLING_EXPORT std::size_t getHeapMemorySizeWithoutChildren() const; - MEDCOUPLING_EXPORT std::vector getDirectChildrenWithNull() const; - // overload of MEDCouplingMesh - MEDCOUPLING_EXPORT MEDCouplingMeshType getType() const { return SINGLE_DYNAMIC_GEO_TYPE_UNSTRUCTURED; } - MEDCOUPLING_EXPORT MEDCouplingMesh *deepCpy() const; - MEDCOUPLING_EXPORT bool isEqualIfNotWhy(const MEDCouplingMesh *other, double prec, std::string& reason) const; - MEDCOUPLING_EXPORT bool isEqualWithoutConsideringStr(const MEDCouplingMesh *other, double prec) const; - MEDCOUPLING_EXPORT void checkFastEquivalWith(const MEDCouplingMesh *other, double prec) const; - MEDCOUPLING_EXPORT void checkCoherency() const; - MEDCOUPLING_EXPORT void checkCoherency1(double eps=1e-12) const; - MEDCOUPLING_EXPORT void checkCoherency2(double eps=1e-12) const; - MEDCOUPLING_EXPORT int getNumberOfCells() const; - MEDCOUPLING_EXPORT DataArrayInt *computeNbOfNodesPerCell() const; - MEDCOUPLING_EXPORT DataArrayInt *computeNbOfFacesPerCell() const; - MEDCOUPLING_EXPORT DataArrayInt *computeEffectiveNbOfNodesPerCell() const; - MEDCOUPLING_EXPORT void getNodeIdsOfCell(int cellId, std::vector& conn) const; - MEDCOUPLING_EXPORT std::string simpleRepr() const; - MEDCOUPLING_EXPORT std::string advancedRepr() const; - MEDCOUPLING_EXPORT DataArrayDouble *computeIsoBarycenterOfNodesPerCell() const; - MEDCOUPLING_EXPORT void renumberCells(const int *old2NewBg, bool check=true); - MEDCOUPLING_EXPORT MEDCouplingMesh *mergeMyselfWith(const MEDCouplingMesh *other) const; - MEDCOUPLING_EXPORT MEDCouplingUMesh *buildUnstructured() const; - MEDCOUPLING_EXPORT DataArrayInt *simplexize(int policy); - MEDCOUPLING_EXPORT void reprQuickOverview(std::ostream& stream) const; - // overload of MEDCouplingPointSet - MEDCOUPLING_EXPORT void shallowCopyConnectivityFrom(const MEDCouplingPointSet *other); - MEDCOUPLING_EXPORT MEDCouplingPointSet *mergeMyselfWithOnSameCoords(const MEDCouplingPointSet *other) const; - MEDCOUPLING_EXPORT MEDCouplingPointSet *buildPartOfMySelfKeepCoords(const int *begin, const int *end) const; - MEDCOUPLING_EXPORT MEDCouplingPointSet *buildPartOfMySelfKeepCoords2(int start, int end, int step) const; - MEDCOUPLING_EXPORT void computeNodeIdsAlg(std::vector& nodeIdsInUse) const; - MEDCOUPLING_EXPORT void getReverseNodalConnectivity(DataArrayInt *revNodal, DataArrayInt *revNodalIndx) const; - MEDCOUPLING_EXPORT void checkFullyDefined() const; - MEDCOUPLING_EXPORT bool isEmptyMesh(const std::vector& tinyInfo) const; - MEDCOUPLING_EXPORT DataArrayInt *computeFetchedNodeIds() const; - MEDCOUPLING_EXPORT DataArrayInt *getNodeIdsInUse(int& nbrOfNodesInUse) const; - MEDCOUPLING_EXPORT void renumberNodesWithOffsetInConn(int offset); - MEDCOUPLING_EXPORT void renumberNodesInConn(const INTERP_KERNEL::HashMap& newNodeNumbersO2N); - MEDCOUPLING_EXPORT void renumberNodesInConn(const int *newNodeNumbersO2N); - MEDCOUPLING_EXPORT void fillCellIdsToKeepFromNodeIds(const int *begin, const int *end, bool fullyIn, DataArrayInt *&cellIdsKeptArr) const; - MEDCOUPLING_EXPORT int getNumberOfNodesInCell(int cellId) const; - MEDCOUPLING_EXPORT DataArrayDouble *getBoundingBoxForBBTree(double arcDetEps=1e-12) const; - MEDCOUPLING_EXPORT MEDCouplingFieldDouble *computeDiameterField() const; - // overload of MEDCoupling1GTUMesh - MEDCOUPLING_EXPORT void checkCoherencyOfConnectivity() const; - MEDCOUPLING_EXPORT void allocateCells(int nbOfCells=0); - MEDCOUPLING_EXPORT void insertNextCell(const int *nodalConnOfCellBg, const int *nodalConnOfCellEnd); - public://specific - MEDCOUPLING_EXPORT void setNodalConnectivity(DataArrayInt *nodalConn, DataArrayInt *nodalConnIndex); - MEDCOUPLING_EXPORT DataArrayInt *getNodalConnectivity() const; - MEDCOUPLING_EXPORT DataArrayInt *getNodalConnectivityIndex() const; - MEDCOUPLING_EXPORT MEDCoupling1DGTUMesh *copyWithNodalConnectivityPacked(bool& isShallowCpyOfNodalConnn) const; - MEDCOUPLING_EXPORT bool retrievePackedNodalConnectivity(DataArrayInt *&nodalConn, DataArrayInt *&nodalConnIndx) const; - MEDCOUPLING_EXPORT bool isPacked() const; - MEDCOUPLING_EXPORT static MEDCoupling1DGTUMesh *Merge1DGTUMeshes(const MEDCoupling1DGTUMesh *mesh1, const MEDCoupling1DGTUMesh *mesh2); - MEDCOUPLING_EXPORT static MEDCoupling1DGTUMesh *Merge1DGTUMeshes(std::vector& a); - MEDCOUPLING_EXPORT static MEDCoupling1DGTUMesh *Merge1DGTUMeshesOnSameCoords(std::vector& a); - MEDCOUPLING_EXPORT static DataArrayInt *AggregateNodalConnAndShiftNodeIds(const std::vector& nodalConns, const std::vector& offsetInNodeIdsPerElt); - MEDCOUPLING_EXPORT static std::vector BuildAPolygonFromParts(const std::vector< std::vector >& parts); - MEDCOUPLING_EXPORT MEDCoupling1DGTUMesh *buildSetInstanceFromThis(int spaceDim) const; - public://serialization - MEDCOUPLING_EXPORT void getTinySerializationInformation(std::vector& tinyInfoD, std::vector& tinyInfo, std::vector& littleStrings) const; - MEDCOUPLING_EXPORT void resizeForUnserialization(const std::vector& tinyInfo, DataArrayInt *a1, DataArrayDouble *a2, std::vector& littleStrings) const; - MEDCOUPLING_EXPORT void serialize(DataArrayInt *&a1, DataArrayDouble *&a2) const; - MEDCOUPLING_EXPORT void unserialization(const std::vector& tinyInfoD, const std::vector& tinyInfo, const DataArrayInt *a1, DataArrayDouble *a2, - const std::vector& littleStrings); - private: - MEDCoupling1DGTUMesh(const std::string& name, const INTERP_KERNEL::CellModel& cm); - MEDCoupling1DGTUMesh(const MEDCoupling1DGTUMesh& other, bool recDeepCpy); - MEDCoupling1DGTUMesh(); - private: - void checkDynamicGeoT2ype() const; - static MEDCoupling1DGTUMesh *Merge1DGTUMeshesLL(std::vector& a); - private: - MEDCouplingAutoRefCountObjectPtr _conn_indx; - MEDCouplingAutoRefCountObjectPtr _conn; - }; -} - -#endif diff --git a/src/MEDCoupling/MEDCouplingAMRAttribute.cxx b/src/MEDCoupling/MEDCouplingAMRAttribute.cxx deleted file mode 100644 index 0a9844669..000000000 --- a/src/MEDCoupling/MEDCouplingAMRAttribute.cxx +++ /dev/null @@ -1,1537 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 -// 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 - -#include "MEDCouplingAMRAttribute.hxx" -#include "MEDCouplingFieldDouble.hxx" -#include "MEDCouplingMemArray.hxx" -#include "MEDCouplingIMesh.hxx" - -#include -#include - -using namespace ParaMEDMEM; - -DataArrayDoubleCollection *DataArrayDoubleCollection::New(const std::vector< std::pair >& fieldNames) -{ - return new DataArrayDoubleCollection(fieldNames); -} - -DataArrayDoubleCollection *DataArrayDoubleCollection::deepCpy() const -{ - return new DataArrayDoubleCollection(*this); -} - -void DataArrayDoubleCollection::allocTuples(int nbOfTuples) -{ - std::size_t sz(_arrs.size()); - for(std::size_t i=0;ireAlloc(nbOfTuples); -} - -void DataArrayDoubleCollection::dellocTuples() -{ - std::size_t sz(_arrs.size()); - for(std::size_t i=0;ireAlloc(0); -} - -void DataArrayDoubleCollection::copyFrom(const DataArrayDoubleCollection& other) -{ - std::size_t sz(_arrs.size()); - if(sz!=other._arrs.size()) - throw INTERP_KERNEL::Exception("DataArrayDoubleCollection::copyFrom : size are not the same !"); - for(std::size_t i=0;icpyFrom(*otherArr); - } -} - -void DataArrayDoubleCollection::spillInfoOnComponents(const std::vector< std::vector >& compNames) -{ - std::size_t sz(_arrs.size()); - if(sz!=compNames.size()) - throw INTERP_KERNEL::Exception("DataArrayDoubleCollection::spillInfoOnComponents : first size of compNames has to be equal to the number of fields defined !"); - for(std::size_t i=0;i& names(compNames[i]); - _arrs[i].first->setInfoOnComponents(names); - } -} - -void DataArrayDoubleCollection::spillNatures(const std::vector& nfs) -{ - std::size_t sz(_arrs.size()); - if(sz!=nfs.size()) - throw INTERP_KERNEL::Exception("DataArrayDoubleCollection::spillNatures : first size of vector of NatureOfField has to be equal to the number of fields defined !"); - for(std::size_t i=0;i > > DataArrayDoubleCollection::getInfoOnComponents() const -{ - std::size_t sz(_arrs.size()); - std::vector< std::pair < std::string, std::vector > > ret(sz); - for(std::size_t i=0;i >(elt->getName(),elt->getInfoOnComponents()); - } - return ret; -} - -std::vector DataArrayDoubleCollection::getNatures() const -{ - std::size_t sz(_arrs.size()); - std::vector ret(sz); - for(std::size_t i=0;i DataArrayDoubleCollection::retrieveFields() const -{ - std::size_t sz(_arrs.size()); - std::vector ret(sz); - for(std::size_t i=0;i(tmp); - if(ret[i]) - ret[i]->incrRef(); - } - return ret; -} - -const DataArrayDouble *DataArrayDoubleCollection::getFieldWithName(const std::string& name) const -{ - std::vector vec; - for(std::vector< std::pair< MEDCouplingAutoRefCountObjectPtr, NatureOfField > >::const_iterator it=_arrs.begin();it!=_arrs.end();it++) - { - const DataArrayDouble *obj((*it).first); - if(obj) - { - if(obj->getName()==name) - return obj; - else - vec.push_back(obj->getName()); - } - } - std::ostringstream oss; oss << "DataArrayDoubleCollection::getFieldWithName : fieldName \"" << name << "\" does not exist in this ! Possibilities are :"; - std::copy(vec.begin(),vec.end(),std::ostream_iterator(oss," ")); - throw INTERP_KERNEL::Exception(oss.str().c_str()); -} - -DataArrayDouble *DataArrayDoubleCollection::getFieldWithName(const std::string& name) -{ - std::vector vec; - for(std::vector< std::pair< MEDCouplingAutoRefCountObjectPtr, NatureOfField > >::iterator it=_arrs.begin();it!=_arrs.end();it++) - { - DataArrayDouble *obj((*it).first); - if(obj) - { - if(obj->getName()==name) - return obj; - else - vec.push_back(obj->getName()); - } - } - std::ostringstream oss; oss << "DataArrayDoubleCollection::getFieldWithName non const : fieldName \"" << name << "\" does not exist in this ! Possibilities are :"; - std::copy(vec.begin(),vec.end(),std::ostream_iterator(oss," ")); - throw INTERP_KERNEL::Exception(oss.str().c_str()); -} - -DataArrayDouble *DataArrayDoubleCollection::at(int pos) -{ - if(pos<0 || pos>=(int)_arrs.size()) - throw INTERP_KERNEL::Exception("DataArrayDoubleCollection::at (non const) : pos must be in [0,nbOfFields) !"); - return _arrs[pos].first; -} - -const DataArrayDouble *DataArrayDoubleCollection::at(int pos) const -{ - if(pos<0 || pos>=(int)_arrs.size()) - throw INTERP_KERNEL::Exception("DataArrayDoubleCollection::at : pos must be in [0,nbOfFields) !"); - return _arrs[pos].first; -} - -int DataArrayDoubleCollection::size() const -{ - return (int)_arrs.size(); -} - -void DataArrayDoubleCollection::SynchronizeFineToCoarse(int ghostLev, const MEDCouplingCartesianAMRMeshGen *fatherOfFineMesh, int patchId, const DataArrayDoubleCollection *fine, DataArrayDoubleCollection *coarse) -{ - if(!fine || !coarse) - throw INTERP_KERNEL::Exception("DataArrayDoubleCollection::SynchronizeFineToCoarse : the input DataArrayDouble collections must be non NULL !"); - std::size_t sz(coarse->_arrs.size()); - if(fine->_arrs.size()!=sz) - throw INTERP_KERNEL::Exception("DataArrayDoubleCollection::SynchronizeFineToCoarse : the input DataArrayDouble collection must have the same size !"); - for(std::size_t i=0;i_arrs[i].second,coarse->_arrs[i].second); - fatherOfFineMesh->fillCellFieldComingFromPatchGhost(patchId,fine->_arrs[i].first,coarse->_arrs[i].first,ghostLev,IsConservativeNature(coarse->_arrs[i].second)); - } -} - -void DataArrayDoubleCollection::SynchronizeCoarseToFine(int ghostLev, const MEDCouplingCartesianAMRMeshGen *fatherOfFineMesh, int patchId, const DataArrayDoubleCollection *coarse, DataArrayDoubleCollection *fine) -{ - if(!fine || !coarse) - throw INTERP_KERNEL::Exception("DataArrayDoubleCollection::SynchronizeCoarseToFine : the input DataArrayDouble collections must be non NULL !"); - std::size_t sz(coarse->_arrs.size()); - if(fine->_arrs.size()!=sz) - throw INTERP_KERNEL::Exception("DataArrayDoubleCollection::SynchronizeCoarseToFine : the input DataArrayDouble collection must have the same size !"); - for(std::size_t i=0;i_arrs[i].second,coarse->_arrs[i].second); - fatherOfFineMesh->fillCellFieldOnPatchGhost(patchId,coarse->_arrs[i].first,fine->_arrs[i].first,ghostLev,IsConservativeNature(coarse->_arrs[i].second)); - } -} - -void DataArrayDoubleCollection::SynchronizeFineEachOther(int patchId, int ghostLev, const MEDCouplingCartesianAMRMeshGen *fatherOfFineMesh, const std::vector& children, const std::vector& fieldsOnFine) -{ - if(!fatherOfFineMesh) - throw INTERP_KERNEL::Exception("DataArrayDoubleCollection::SynchronizeFineEachOther : father is NULL !"); - std::size_t sz(children.size()); - if(fieldsOnFine.size()!=sz) - throw INTERP_KERNEL::Exception("DataArrayDoubleCollection::SynchronizeFineEachOther : sizes of vectors mismatch !"); - if(sz<=1) - return ; - std::size_t nbOfCall(fieldsOnFine[0]->_arrs.size()); - for(std::size_t i=0;igetPatchIdFromChildMesh(children[i])!=(int)i) - throw INTERP_KERNEL::Exception("DataArrayDoubleCollection::SynchronizeFineEachOther : internal error !"); - for(std::size_t i=1;i_arrs.size()) - throw INTERP_KERNEL::Exception("DataArrayDoubleCollection::SynchronizeFineEachOther : the collection of DataArrayDouble must have all the same size !"); - for(std::size_t i=0;i arrs(sz); - for(std::size_t j=0;j_arrs[i].first; - fatherOfFineMesh->fillCellFieldOnPatchOnlyGhostAdv(patchId,ghostLev,arrs); - } -} - -/*! - * This method updates \a p1dac ghost zone parts using \a p2dac (which is really const). \a p2 is in the neighborhood of \a p1 (which size is defined by \a ghostLev). - */ -void DataArrayDoubleCollection::SynchronizeGhostZoneOfOneUsingTwo(int ghostLev, const MEDCouplingCartesianAMRPatch *p1, const DataArrayDoubleCollection *p1dac, const MEDCouplingCartesianAMRPatch *p2, const DataArrayDoubleCollection *p2dac) -{ - if(!p1 || !p1dac || !p2 || !p2dac) - throw INTERP_KERNEL::Exception("DataArrayDoubleCollection::SynchronizeGhostZoneOfOneUsingTwo : input pointer must be not NULL !"); - std::size_t sz(p1dac->_arrs.size()); - if(p2dac->_arrs.size()!=sz) - throw INTERP_KERNEL::Exception("DataArrayDoubleCollection::SynchronizeGhostZoneOfOneUsingTwo : size of DataArrayDouble Collection must be the same !"); - for(std::size_t i=0;i_arrs[i].first); - DataArrayDoubleCollection::CheckSameNatures(p1dac->_arrs[i].second,p2dac->_arrs[i].second); - bool isConservative(DataArrayDoubleCollection::IsConservativeNature(p1dac->_arrs[i].second)); - MEDCouplingCartesianAMRPatch::UpdateNeighborsOfOneWithTwoMixedLev(ghostLev,p1,p2,const_cast(zeArrWhichGhostsWillBeUpdated),p2dac->_arrs[i].first,isConservative); - } -} - -void DataArrayDoubleCollection::SynchronizeCoarseToFineOnlyInGhostZone(int ghostLev, const MEDCouplingCartesianAMRMeshGen *fatherOfFineMesh, int patchId, const DataArrayDoubleCollection *coarse, DataArrayDoubleCollection *fine) -{ - if(!fine || !coarse) - throw INTERP_KERNEL::Exception("DataArrayDoubleCollection::SynchronizeCoarseToFineOnlyInGhostZone : the input DataArrayDouble collections must be non NULL !"); - std::size_t sz(coarse->_arrs.size()); - if(fine->_arrs.size()!=sz) - throw INTERP_KERNEL::Exception("DataArrayDoubleCollection::SynchronizeCoarseToFineOnlyInGhostZone : the input DataArrayDouble collection must have the same size !"); - for(std::size_t i=0;ifillCellFieldOnPatchOnlyOnGhostZone(patchId,coarse->_arrs[i].first,fine->_arrs[i].first,ghostLev); -} - -void DataArrayDoubleCollection::synchronizeMyGhostZoneUsing(int ghostLev, const DataArrayDoubleCollection& other, const MEDCouplingCartesianAMRPatch *thisp, const MEDCouplingCartesianAMRPatch *otherp, const MEDCouplingCartesianAMRMeshGen *father) const -{ - DataArrayDoubleCollection *thisNC(const_cast(this)); - std::size_t sz(_arrs.size()); - if(other._arrs.size()!=sz) - throw INTERP_KERNEL::Exception("DataArrayDoubleCollection::synchronizeMyGhostZoneUsing : sizes of collections must match !"); - for(std::size_t i=0;ifillCellFieldOnPatchOnlyOnGhostZoneWith(ghostLev,thisp,otherp,thisNC->_arrs[i].first,other._arrs[i].first); -} - -void DataArrayDoubleCollection::synchronizeMyGhostZoneUsingExt(int ghostLev, const DataArrayDoubleCollection& other, const MEDCouplingCartesianAMRPatch *thisp, const MEDCouplingCartesianAMRPatch *otherp) const -{ - DataArrayDoubleCollection *thisNC(const_cast(this)); - std::size_t sz(_arrs.size()); - if(other._arrs.size()!=sz) - throw INTERP_KERNEL::Exception("DataArrayDoubleCollection::synchronizeMyGhostZoneUsingExt : sizes of collections must match !"); - for(std::size_t i=0;i_arrs[i].first,other._arrs[i].first); -} - -DataArrayDoubleCollection::DataArrayDoubleCollection(const std::vector< std::pair >& fieldNames):_arrs(fieldNames.size()) -{ - std::size_t sz(fieldNames.size()); - std::vector names(sz); - for(std::size_t i=0;i& info(fieldNames[i]); - if(info.second<=0) - { - std::ostringstream oss; oss << "DataArrayDoubleCollection constructor : At pos #" << i << " the array with name \"" << info.first << "\" as a number of components equal to " << info.second; - oss << " It has to be >=1 !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - _arrs[i].first=DataArrayDouble::New(); - _arrs[i].first->alloc(0,info.second); - _arrs[i].first->setName(info.first); - names[i]=info.second; - _arrs[i].second=ConservativeVolumic; - } - CheckDiscriminantNames(names); -} - -DataArrayDoubleCollection::DataArrayDoubleCollection(const DataArrayDoubleCollection& other):RefCountObject(other),_arrs(other._arrs.size()) -{ - std::size_t sz(other._arrs.size()); - for(std::size_t i=0;ideepCpy(); - } -} - -std::size_t DataArrayDoubleCollection::getHeapMemorySizeWithoutChildren() const -{ - std::size_t ret(sizeof(DataArrayDoubleCollection)); - ret+=_arrs.capacity()*sizeof(MEDCouplingAutoRefCountObjectPtr); - return ret; -} - -std::vector DataArrayDoubleCollection::getDirectChildrenWithNull() const -{ - std::vector ret; - for(std::vector< std::pair< MEDCouplingAutoRefCountObjectPtr, NatureOfField > >::const_iterator it=_arrs.begin();it!=_arrs.end();it++) - ret.push_back((const DataArrayDouble *)(*it).first); - return ret; -} - -void DataArrayDoubleCollection::updateTime() const -{ - for(std::vector< std::pair< MEDCouplingAutoRefCountObjectPtr, NatureOfField > >::const_iterator it=_arrs.begin();it!=_arrs.end();it++) - { - const DataArrayDouble *pt((*it).first); - if(pt) - updateTimeWith(*pt); - } -} - -void DataArrayDoubleCollection::CheckDiscriminantNames(const std::vector& names) -{ - std::set s(names.begin(),names.end()); - if(s.size()!=names.size()) - throw INTERP_KERNEL::Exception("DataArrayDoubleCollection::CheckDiscriminantNames : The names of fields must be different each other ! It is not the case !"); -} - -bool DataArrayDoubleCollection::IsConservativeNature(NatureOfField n) -{ - CheckValidNature(n); - return n==RevIntegral || n==IntegralGlobConstraint; -} - -void DataArrayDoubleCollection::CheckSameNatures(NatureOfField n1, NatureOfField n2) -{ - CheckValidNature(n1); - CheckValidNature(n2); - if(n1!=n2) - throw INTERP_KERNEL::Exception("DataArrayDoubleCollection::CheckSameNatures : natures are not the same !"); -} - -void DataArrayDoubleCollection::CheckValidNature(NatureOfField n) -{ - if(n!=ConservativeVolumic && n!=Integral && n!=IntegralGlobConstraint && n!=RevIntegral) - throw INTERP_KERNEL::Exception("DataArrayDoubleCollection::CheckValidNature : unrecognized nature !"); -} - -MEDCouplingGridCollection *MEDCouplingGridCollection::New(const std::vector& ms, const std::vector< std::pair >& fieldNames) -{ - return new MEDCouplingGridCollection(ms,fieldNames); -} - -MEDCouplingGridCollection *MEDCouplingGridCollection::deepCpy(const MEDCouplingCartesianAMRMeshGen *newGf, const MEDCouplingCartesianAMRMeshGen *oldGf) const -{ - return new MEDCouplingGridCollection(*this,newGf,oldGf); -} - -void MEDCouplingGridCollection::alloc(int ghostLev) -{ - for(std::vector< std::pair > >::iterator it=_map_of_dadc.begin();it!=_map_of_dadc.end();it++) - { - int nbTuples((*it).first->getNumberOfCellsAtCurrentLevelGhost(ghostLev)); - DataArrayDoubleCollection *dadc((*it).second); - if(dadc) - dadc->allocTuples(nbTuples); - else - throw INTERP_KERNEL::Exception("MEDCouplingGridCollection::alloc : internal error !"); - } -} - -void MEDCouplingGridCollection::dealloc() -{ - for(std::vector< std::pair > >::iterator it=_map_of_dadc.begin();it!=_map_of_dadc.end();it++) - { - DataArrayDoubleCollection *dadc((*it).second); - if(dadc) - dadc->dellocTuples(); - else - throw INTERP_KERNEL::Exception("MEDCouplingGridCollection::dealloc : internal error !"); - } -} - -void MEDCouplingGridCollection::spillInfoOnComponents(const std::vector< std::vector >& compNames) -{ - for(std::vector< std::pair > >::iterator it=_map_of_dadc.begin();it!=_map_of_dadc.end();it++) - (*it).second->spillInfoOnComponents(compNames); -} - -void MEDCouplingGridCollection::spillNatures(const std::vector& nfs) -{ - for(std::vector< std::pair > >::iterator it=_map_of_dadc.begin();it!=_map_of_dadc.end();it++) - (*it).second->spillNatures(nfs); -} - -std::vector< std::pair > > MEDCouplingGridCollection::getInfoOnComponents() const -{ - if(_map_of_dadc.empty()) - throw INTERP_KERNEL::Exception("MEDCouplingGridCollection::getInfoOnComponents : empty map !"); - const DataArrayDoubleCollection *elt(_map_of_dadc[0].second); - if(!elt) - throw INTERP_KERNEL::Exception("MEDCouplingGridCollection::getInfoOnComponents : null pointer !"); - return elt->getInfoOnComponents(); -} - -std::vector MEDCouplingGridCollection::getNatures() const -{ - if(_map_of_dadc.empty()) - throw INTERP_KERNEL::Exception("MEDCouplingGridCollection::getNatures : empty map !"); - const DataArrayDoubleCollection *elt(_map_of_dadc[0].second); - if(!elt) - throw INTERP_KERNEL::Exception("MEDCouplingGridCollection::getNatures : null pointer !"); - return elt->getNatures(); -} - -bool MEDCouplingGridCollection::presenceOf(const MEDCouplingCartesianAMRMeshGen *m, int& pos) const -{ - int ret(0); - for(std::vector< std::pair > >::const_iterator it=_map_of_dadc.begin();it!=_map_of_dadc.end();it++,ret++) - { - if((*it).first==m) - { - pos=ret; - return true; - } - } - return false; -} - -const DataArrayDoubleCollection& MEDCouplingGridCollection::getFieldsAt(int pos) const -{ - if(pos<0 || pos>(int)_map_of_dadc.size()) - throw INTERP_KERNEL::Exception("MEDCouplingGridCollection::getFieldsAt : invalid pos given in input ! Must be in [0,size) !"); - return *_map_of_dadc[pos].second; -} - -DataArrayDoubleCollection& MEDCouplingGridCollection::getFieldsAt(int pos) -{ - if(pos<0 || pos>(int)_map_of_dadc.size()) - throw INTERP_KERNEL::Exception("MEDCouplingGridCollection::getFieldsAt (non const) : invalid pos given in input ! Must be in [0,size) !"); - return *_map_of_dadc[pos].second; -} - -/*! - * This method copies for all grids intersecting themselves (between \a this and \a other), the values of fields of \a other to the intersecting - * part of fields of \a this. The fields are expected to be the same between \a other and \a this. - * This methods makes the hypothesis that \a this and \a other share two god father that are compatible each other that is to say with the same cell grid structure. - */ -void MEDCouplingGridCollection::copyOverlappedZoneFrom(int ghostLev, const MEDCouplingGridCollection& other) -{ - for(std::vector< std::pair > >::iterator it=_map_of_dadc.begin();it!=_map_of_dadc.end();it++) - { - std::vector deltaThis,deltaOther; - std::vector< std::pair > rgThis((*it).first->positionRelativeToGodFather(deltaThis)); - std::vector thisSt((*it).first->getImageMesh()->getCellGridStructure()); - std::transform(thisSt.begin(),thisSt.end(),thisSt.begin(),std::bind2nd(std::plus(),2*ghostLev)); - for(std::vector< std::pair > >::const_iterator it2=other._map_of_dadc.begin();it2!=other._map_of_dadc.end();it2++) - { - std::vector< std::pair > rgOther((*it2).first->positionRelativeToGodFather(deltaOther)); - if(MEDCouplingStructuredMesh::AreRangesIntersect(rgThis,rgOther)) - { - std::vector< std::pair > isect(MEDCouplingStructuredMesh::IntersectRanges(rgThis,rgOther)); - std::vector< std::pair > pThis,pOther; - MEDCouplingStructuredMesh::ChangeReferenceFromGlobalOfCompactFrmt(rgThis,isect,pThis,true); - MEDCouplingStructuredMesh::ChangeReferenceFromGlobalOfCompactFrmt(rgOther,isect,pOther,true); - std::vector otherSt((*it2).first->getImageMesh()->getCellGridStructure()); - MEDCouplingStructuredMesh::ApplyGhostOnCompactFrmt(pThis,ghostLev); - MEDCouplingStructuredMesh::ApplyGhostOnCompactFrmt(pOther,ghostLev); - std::transform(otherSt.begin(),otherSt.end(),otherSt.begin(),std::bind2nd(std::plus(),2*ghostLev)); - int sz((*it2).second->size()); - for(int i=0;iat(i)); - DataArrayDouble *thisArr((*it).second->at(i)); - MEDCouplingAutoRefCountObjectPtr partOfOther(MEDCouplingStructuredMesh::ExtractFieldOfDoubleFrom(otherSt,otherArr,pOther)); - MEDCouplingStructuredMesh::AssignPartOfFieldOfDoubleUsing(thisSt,thisArr,pThis,partOfOther); - } - } - } - } -} - -void MEDCouplingGridCollection::SynchronizeFineToCoarse(int ghostLev, const MEDCouplingGridCollection *fine, const MEDCouplingGridCollection *coarse) -{ - if(!fine || !coarse) - throw INTERP_KERNEL::Exception("MEDCouplingGridCollection::SynchronizeFineToCoarse : one or more input pointer is NULL !"); - const std::vector< std::pair > >& mf(fine->_map_of_dadc); - const std::vector< std::pair > >& mc(coarse->_map_of_dadc); - for(std::vector< std::pair > >::const_iterator it=mf.begin();it!=mf.end();it++) - { - const MEDCouplingCartesianAMRMeshGen *fineMesh((*it).first); - const MEDCouplingCartesianAMRMeshGen *fatherOfFineMesh(fineMesh->getFather()); - bool found(false); - for(std::vector< std::pair > >::const_iterator it0=mc.begin();it0!=mc.end() && !found;it0++) - { - if((*it0).first==fatherOfFineMesh) - { - found=true; - int patchId(fatherOfFineMesh->getPatchIdFromChildMesh(fineMesh)); - const DataArrayDoubleCollection *coarseDaCol((*it0).second); - DataArrayDoubleCollection *coarseModified(const_cast(coarseDaCol));//coarse values in DataArrayDouble will be altered - DataArrayDoubleCollection::SynchronizeFineToCoarse(ghostLev,fatherOfFineMesh,patchId,(*it).second,coarseModified); - } - } - if(!found) - throw INTERP_KERNEL::Exception("MEDCouplingGridCollection::SynchronizeFineToCoarse : a fine mesh is orphan regarding given coarse meshes !"); - } -} - -void MEDCouplingGridCollection::SynchronizeCoarseToFine(int ghostLev, const MEDCouplingGridCollection *coarse, const MEDCouplingGridCollection *fine) -{ - if(!fine || !coarse) - throw INTERP_KERNEL::Exception("MEDCouplingGridCollection::SynchronizeCoarseToFine : one or more input pointer is NULL !"); - const std::vector< std::pair > >& mf(fine->_map_of_dadc); - const std::vector< std::pair > >& mc(coarse->_map_of_dadc); - for(std::vector< std::pair > >::const_iterator it=mf.begin();it!=mf.end();it++) - { - const MEDCouplingCartesianAMRMeshGen *fineMesh((*it).first); - const MEDCouplingCartesianAMRMeshGen *fatherOfFineMesh(fineMesh->getFather()); - bool found(false); - for(std::vector< std::pair > >::const_iterator it0=mc.begin();it0!=mc.end() && !found;it0++) - { - if((*it0).first==fatherOfFineMesh) - { - found=true; - int patchId(fatherOfFineMesh->getPatchIdFromChildMesh(fineMesh)); - const DataArrayDoubleCollection *fineDaCol((*it).second); - DataArrayDoubleCollection *fineModified(const_cast(fineDaCol));//fine values in DataArrayDouble will be altered - DataArrayDoubleCollection::SynchronizeCoarseToFine(ghostLev,fatherOfFineMesh,patchId,(*it0).second,fineModified); - } - } - if(!found) - throw INTERP_KERNEL::Exception("MEDCouplingGridCollection::SynchronizeCoarseToFine : a fine mesh is orphan regarding given coarse meshes !"); - } -} - -/*! - * All the pairs in \a ps must share the same father. If not call synchronizeFineEachOtherExt instead. - * - * \sa synchronizeFineEachOtherExt - */ -void MEDCouplingGridCollection::synchronizeFineEachOther(int ghostLev, const std::vector< std::pair >& ps) const -{ - for(std::vector< std::pair >::const_iterator it=ps.begin();it!=ps.end();it++) - { - int p1,p2; - if(!presenceOf((*it).first->getMesh(),p1)) - throw INTERP_KERNEL::Exception("MEDCouplingGridCollection::synchronizeFineEachOther : internal error #1 !"); - if(!presenceOf((*it).second->getMesh(),p2)) - throw INTERP_KERNEL::Exception("MEDCouplingGridCollection::synchronizeFineEachOther : internal error #2 !"); - const DataArrayDoubleCollection& col1(getFieldsAt(p1)); - const DataArrayDoubleCollection& col2(getFieldsAt(p2)); - col1.synchronizeMyGhostZoneUsing(ghostLev,col2,(*it).first,(*it).second,(*it).first->getMesh()->getFather()); - } -} - -/*! - * This method is a generalization of synchronizeFineEachOther because elements in pairs are \b not sharing the same father but are neighbors nevertheless. - * - * \sa synchronizeFineEachOther - */ -void MEDCouplingGridCollection::synchronizeFineEachOtherExt(int ghostLev, const std::vector< std::pair >& ps) const -{ - for(std::vector< std::pair >::const_iterator it=ps.begin();it!=ps.end();it++) - { - int p1,p2; - if(!presenceOf((*it).first->getMesh(),p1)) - throw INTERP_KERNEL::Exception("MEDCouplingGridCollection::synchronizeFineEachOtherExt : internal error #1 !"); - if(!presenceOf((*it).second->getMesh(),p2)) - throw INTERP_KERNEL::Exception("MEDCouplingGridCollection::synchronizeFineEachOtherExt : internal error #2 !"); - const DataArrayDoubleCollection& col1(getFieldsAt(p1)); - const DataArrayDoubleCollection& col2(getFieldsAt(p2)); - col1.synchronizeMyGhostZoneUsingExt(ghostLev,col2,(*it).first,(*it).second); - } -} - -/*! - * The pairs returned share the same direct father. The number of returned elements must be even. - */ -std::vector< std::pair > MEDCouplingGridCollection::findNeighbors(int ghostLev) const -{ - std::vector< std::pair > ret; - std::map > m; - for(std::vector< std::pair > >::const_iterator it=_map_of_dadc.begin();it!=_map_of_dadc.end();it++) - { - const MEDCouplingCartesianAMRMeshGen *fineMesh((*it).first); - const MEDCouplingCartesianAMRMeshGen *fatherOfFineMesh(fineMesh->getFather()); - m[fatherOfFineMesh].push_back(fineMesh); - } - for(std::map >::const_iterator it0=m.begin();it0!=m.end();it0++) - { - for(std::vector::const_iterator it1=(*it0).second.begin();it1!=(*it0).second.end();it1++) - { - int patchId((*it0).first->getPatchIdFromChildMesh(*it1)); - std::vector neighs((*it0).first->getPatchIdsInTheNeighborhoodOf(patchId,ghostLev)); - const MEDCouplingCartesianAMRPatch *pRef((*it0).first->getPatch(patchId)); - for(std::vector::const_iterator it2=neighs.begin();it2!=neighs.end();it2++) - { - const MEDCouplingCartesianAMRPatch *pLoc((*it0).first->getPatch(*it2)); - ret.push_back(std::pair(pRef,pLoc)); - } - } - } - if(ret.size()%2!=0) - throw INTERP_KERNEL::Exception("MEDCouplingGridCollection::findNeighbors : something is wrong ! The number of neighbor pairs must be %2 ==0 !"); - return ret; -} - -void MEDCouplingGridCollection::SynchronizeCoarseToFineOnlyInGhostZone(int ghostLev, const MEDCouplingGridCollection *coarse, const MEDCouplingGridCollection *fine) -{ - if(!fine || !coarse) - throw INTERP_KERNEL::Exception("MEDCouplingGridCollection::SynchronizeCoarseToFineOnlyInGhostZone : one or more input pointer is NULL !"); - const std::vector< std::pair > >& mf(fine->_map_of_dadc); - const std::vector< std::pair > >& mc(coarse->_map_of_dadc); - for(std::vector< std::pair > >::const_iterator it=mf.begin();it!=mf.end();it++) - { - const MEDCouplingCartesianAMRMeshGen *fineMesh((*it).first); - const MEDCouplingCartesianAMRMeshGen *fatherOfFineMesh(fineMesh->getFather()); - bool found(false); - for(std::vector< std::pair > >::const_iterator it0=mc.begin();it0!=mc.end() && !found;it0++) - { - if((*it0).first==fatherOfFineMesh) - { - found=true; - int patchId(fatherOfFineMesh->getPatchIdFromChildMesh(fineMesh)); - const DataArrayDoubleCollection *fineDaCol((*it).second); - DataArrayDoubleCollection *fineModified(const_cast(fineDaCol));//fine values in DataArrayDouble will be altered - DataArrayDoubleCollection::SynchronizeCoarseToFineOnlyInGhostZone(ghostLev,fatherOfFineMesh,patchId,(*it0).second,fineModified); - } - } - if(!found) - throw INTERP_KERNEL::Exception("MEDCouplingGridCollection::SynchronizeCoarseToFineOnlyInGhostZone : a fine mesh is orphan regarding given coarse meshes !"); - } -} - -void MEDCouplingGridCollection::fillIfInTheProgenyOf(const std::string& fieldName, const MEDCouplingCartesianAMRMeshGen *head, std::vector& recurseArrs) const -{ - for(std::vector< std::pair > >::const_iterator it=_map_of_dadc.begin();it!=_map_of_dadc.end();it++) - { - const MEDCouplingCartesianAMRMeshGen *a((*it).first); - if(head==a || head->isObjectInTheProgeny(a)) - { - const DataArrayDoubleCollection *gc((*it).second); - recurseArrs.push_back(gc->getFieldWithName(fieldName)); - } - } -} - -MEDCouplingGridCollection::MEDCouplingGridCollection(const std::vector& ms, const std::vector< std::pair >& fieldNames):_map_of_dadc(ms.size()) -{ - std::size_t sz(ms.size()); - for(std::size_t i=0;i pos(other._map_of_dadc[i].first->getPositionRelativeTo(oldGf)); - _map_of_dadc[i].first=newGf->getMeshAtPosition(pos); - const DataArrayDoubleCollection *dac(other._map_of_dadc[i].second); - if(dac) - _map_of_dadc[i].second=dac->deepCpy(); - } -} - -std::size_t MEDCouplingGridCollection::getHeapMemorySizeWithoutChildren() const -{ - std::size_t ret(sizeof(MEDCouplingGridCollection)); - ret+=_map_of_dadc.capacity()*sizeof(std::pair >); - return ret; -} - -std::vector MEDCouplingGridCollection::getDirectChildrenWithNull() const -{ - std::vector ret; - for(std::vector< std::pair > >::const_iterator it=_map_of_dadc.begin();it!=_map_of_dadc.end();it++) - ret.push_back((const DataArrayDoubleCollection *)(*it).second); - return ret; -} - -void MEDCouplingGridCollection::updateTime() const -{ - for(std::vector< std::pair > >::const_iterator it=_map_of_dadc.begin();it!=_map_of_dadc.end();it++) - { - const MEDCouplingCartesianAMRMeshGen *a((*it).first); - if(a) - updateTimeWith(*a); - const DataArrayDoubleCollection *b((*it).second); - if(b) - updateTimeWith(*b); - } -} - -MEDCouplingCartesianAMRMesh *MEDCouplingDataForGodFather::getMyGodFather() -{ - return _gf; -} - -const MEDCouplingCartesianAMRMesh *MEDCouplingDataForGodFather::getMyGodFather() const -{ - return _gf; -} - -MEDCouplingDataForGodFather::MEDCouplingDataForGodFather(MEDCouplingCartesianAMRMesh *gf):_gf(gf),_tlc(gf) -{ - if(!gf) - throw INTERP_KERNEL::Exception("MEDCouplingDataForGodFather constructor : A data has to be attached to a AMR Mesh instance !"); - gf->incrRef(); -} - -void MEDCouplingDataForGodFather::checkGodFatherFrozen() const -{ - _tlc.checkConst(); -} - -bool MEDCouplingDataForGodFather::changeGodFather(MEDCouplingCartesianAMRMesh *gf) -{ - bool ret(_tlc.keepTrackOfNewTL(gf)); - if(ret) - { - _gf=gf; - if(gf) - gf->incrRef(); - } - return ret; -} - -MEDCouplingDataForGodFather::MEDCouplingDataForGodFather(const MEDCouplingDataForGodFather& other, bool deepCpyGF):RefCountObject(other),_gf(other._gf),_tlc(other._gf) -{ - other._tlc.checkConst(); - if(deepCpyGF) - { - const MEDCouplingCartesianAMRMesh *gf(other._gf); - if(gf) - _gf=gf->deepCpy(0); - _tlc.keepTrackOfNewTL(_gf); - } -} - -/*! - * This method creates, attach to a main AMR mesh \a gf ( called god father :-) ) and returns a data linked to \a gf ready for the computation. - */ -MEDCouplingAMRAttribute *MEDCouplingAMRAttribute::New(MEDCouplingCartesianAMRMesh *gf, const std::vector< std::pair >& fieldNames, int ghostLev) -{ - return new MEDCouplingAMRAttribute(gf,fieldNames,ghostLev); -} - -MEDCouplingAMRAttribute *MEDCouplingAMRAttribute::New(MEDCouplingCartesianAMRMesh *gf, const std::vector< std::pair > >& fieldNames, int ghostLev) -{ - std::size_t sz(fieldNames.size()); - std::vector< std::pair > fieldNames2(sz); - std::vector< std::vector > compNames(sz); - for(std::size_t i=0;i ret(New(gf,fieldNames2,ghostLev)); - ret->spillInfoOnComponents(compNames); - return ret.retn(); -} - -/*! - * Assign the info on components for all DataArrayDouble instance recursively stored in \a this. - * The first dim of input \a compNames is the field id in the same order than those implicitely specified in \a fieldNames parameter of MEDCouplingAMRAttribute::New. - * The second dim of \a compNames represent the component names component per component corresponding to the field. The size of this 2nd dimension has - * to perfectly fit with those specified in MEDCouplingAMRAttribute::New. - */ -void MEDCouplingAMRAttribute::spillInfoOnComponents(const std::vector< std::vector >& compNames) -{ - _tlc.checkConst(); - for(std::vector< MEDCouplingAutoRefCountObjectPtr >::iterator it=_levs.begin();it!=_levs.end();it++) - (*it)->spillInfoOnComponents(compNames); -} - -/*! - * Assign nature for each fields in \a this. - * \param [in] nfs - */ -void MEDCouplingAMRAttribute::spillNatures(const std::vector& nfs) -{ - _tlc.checkConst(); - for(std::vector< MEDCouplingAutoRefCountObjectPtr >::iterator it=_levs.begin();it!=_levs.end();it++) - (*it)->spillNatures(nfs); -} - -MEDCouplingAMRAttribute *MEDCouplingAMRAttribute::deepCpy() const -{ - return new MEDCouplingAMRAttribute(*this,true); -} - -MEDCouplingAMRAttribute *MEDCouplingAMRAttribute::deepCpyWithoutGodFather() const -{ - return new MEDCouplingAMRAttribute(*this,false); -} - -/*! - * Returns the number of levels by \b only \b considering \a this (god father instance is considered only to see if it has not changed still last update of \a this). - * - */ -int MEDCouplingAMRAttribute::getNumberOfLevels() const -{ - checkGodFatherFrozen(); - return (int)_levs.size(); -} - -/*! - * This method returns all DataArrayDouble instances lying on the specified mesh \a mesh. - * If \a mesh is not part of the progeny of god father object given at construction of \a this an exception will be thrown. - * - * \return std::vector - DataArrayDouble instances to be deallocated by the caller (using decrRef). - * \sa retrieveFieldOn - */ -std::vector MEDCouplingAMRAttribute::retrieveFieldsOn(MEDCouplingCartesianAMRMeshGen *mesh) const -{ - for(std::vector< MEDCouplingAutoRefCountObjectPtr >::const_iterator it=_levs.begin();it!=_levs.end();it++) - { - int tmp(-1); - if((*it)->presenceOf(mesh,tmp)) - { - const DataArrayDoubleCollection& ddc((*it)->getFieldsAt(tmp)); - return ddc.retrieveFields(); - } - } - throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::retrieveFieldsOn : the mesh specified is not in the progeny of this !"); -} - -/*! - * \sa retrieveFieldsOn - */ -const DataArrayDouble *MEDCouplingAMRAttribute::getFieldOn(MEDCouplingCartesianAMRMeshGen *mesh, const std::string& fieldName) const -{ - for(std::vector< MEDCouplingAutoRefCountObjectPtr >::const_iterator it=_levs.begin();it!=_levs.end();it++) - { - int tmp(-1); - if((*it)->presenceOf(mesh,tmp)) - { - const DataArrayDoubleCollection& ddc((*it)->getFieldsAt(tmp)); - return ddc.getFieldWithName(fieldName); - } - } - throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::getFieldOn : the mesh specified is not in the progeny of this !"); -} - -DataArrayDouble *MEDCouplingAMRAttribute::getFieldOn(MEDCouplingCartesianAMRMeshGen *mesh, const std::string& fieldName) -{ - for(std::vector< MEDCouplingAutoRefCountObjectPtr >::iterator it=_levs.begin();it!=_levs.end();it++) - { - int tmp(-1); - if((*it)->presenceOf(mesh,tmp)) - { - DataArrayDoubleCollection& ddc((*it)->getFieldsAt(tmp)); - return ddc.getFieldWithName(fieldName); - } - } - throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::getFieldOn non const : the mesh specified is not in the progeny of this !"); -} - -/*! - * This method returns a field on an unstructured mesh the most refined as possible without overlap. - * Ghost part are not visible here. - * - * \return MEDCouplingFieldDouble * - a field on cells that the caller has to deal with (deallocate it). - */ -MEDCouplingFieldDouble *MEDCouplingAMRAttribute::buildCellFieldOnRecurseWithoutOverlapWithoutGhost(MEDCouplingCartesianAMRMeshGen *mesh, const std::string& fieldName) const -{ - std::vector recurseArrs; - std::size_t lev(0); - for(std::vector< MEDCouplingAutoRefCountObjectPtr >::const_iterator it=_levs.begin();it!=_levs.end();it++,lev++) - { - int tmp(-1); - if((*it)->presenceOf(mesh,tmp)) - { - const DataArrayDoubleCollection& ddc((*it)->getFieldsAt(tmp)); - recurseArrs.push_back(ddc.getFieldWithName(fieldName)); - break; - } - } - lev++; - for(std::size_t i=lev;i<_levs.size();i++) - { - const MEDCouplingGridCollection *gc(_levs[i]); - gc->fillIfInTheProgenyOf(fieldName,mesh,recurseArrs); - } - return mesh->buildCellFieldOnRecurseWithoutOverlapWithoutGhost(_ghost_lev,recurseArrs); -} - -/*! - * This method builds a newly created field on cell just lying on mesh \a mesh without its eventual refinement. - * The output field also displays ghost cells. - * - * \return MEDCouplingFieldDouble * - a field on cells that the caller has to deal with (deallocate it). - * - * \sa buildCellFieldOnWithoutGhost - */ -MEDCouplingFieldDouble *MEDCouplingAMRAttribute::buildCellFieldOnWithGhost(MEDCouplingCartesianAMRMeshGen *mesh, const std::string& fieldName) const -{ - const DataArrayDouble *arr(0); - for(std::vector< MEDCouplingAutoRefCountObjectPtr >::const_iterator it=_levs.begin();it!=_levs.end();it++) - { - int tmp(-1); - if((*it)->presenceOf(mesh,tmp)) - { - const DataArrayDoubleCollection& ddc((*it)->getFieldsAt(tmp)); - arr=ddc.getFieldWithName(fieldName); - } - } - if(!arr) - throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::buildCellFieldOnWithGhost : the mesh specified is not in the progeny of this !"); - MEDCouplingAutoRefCountObjectPtr im(mesh->getImageMesh()->buildWithGhost(_ghost_lev)); - MEDCouplingAutoRefCountObjectPtr ret(MEDCouplingFieldDouble::New(ON_CELLS)); - ret->setMesh(im); - ret->setArray(const_cast(arr)); - ret->setName(arr->getName()); - return ret.retn(); -} - -/*! - * This method builds a newly created field on cell just lying on mesh \a mesh without its eventual refinement. - * The output field does not display ghost cells. - * - * \return MEDCouplingFieldDouble * - a field on cells that the caller has to deal with (deallocate it). - * - * \sa buildCellFieldOnWithGhost - */ -MEDCouplingFieldDouble *MEDCouplingAMRAttribute::buildCellFieldOnWithoutGhost(MEDCouplingCartesianAMRMeshGen *mesh, const std::string& fieldName) const -{ - const DataArrayDouble *arr(0); - for(std::vector< MEDCouplingAutoRefCountObjectPtr >::const_iterator it=_levs.begin();it!=_levs.end();it++) - { - int tmp(-1); - if((*it)->presenceOf(mesh,tmp)) - { - const DataArrayDoubleCollection& ddc((*it)->getFieldsAt(tmp)); - arr=ddc.getFieldWithName(fieldName); - } - } - if(!arr) - throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::buildCellFieldOnWithoutGhost : the mesh specified is not in the progeny of this !"); - // - MEDCouplingAutoRefCountObjectPtr im(mesh->getImageMesh()->buildWithGhost(_ghost_lev)); - std::vector cgs(mesh->getImageMesh()->getCellGridStructure()),cgsWG(im->getCellGridStructure()); - MEDCouplingAutoRefCountObjectPtr arr2(DataArrayDouble::New()); - arr2->alloc(mesh->getImageMesh()->getNumberOfCells(),arr->getNumberOfComponents()); - std::vector< std::pair > cgs2(MEDCouplingStructuredMesh::GetCompactFrmtFromDimensions(cgs)); - MEDCouplingStructuredMesh::ApplyGhostOnCompactFrmt(cgs2,_ghost_lev); - std::vector fakeFactors(mesh->getImageMesh()->getSpaceDimension(),1); - MEDCouplingIMesh::SpreadCoarseToFine(arr,cgsWG,arr2,cgs2,fakeFactors); - arr2->copyStringInfoFrom(*arr); - // - MEDCouplingAutoRefCountObjectPtr ret(MEDCouplingFieldDouble::New(ON_CELLS)); - ret->setMesh(mesh->getImageMesh()); - ret->setArray(arr2); - ret->setName(arr->getName()); - return ret.retn(); -} - - -std::string MEDCouplingAMRAttribute::writeVTHB(const std::string& fileName) const -{ - static const char EXT[]=".vthb"; - std::string baseName,extName,zeFileName; - MEDCouplingMesh::SplitExtension(fileName,baseName,extName); - if(extName==EXT) - zeFileName=fileName; - else - { zeFileName=baseName; zeFileName+=EXT; } - // - std::ofstream ofs(fileName.c_str()); - ofs << "\n"; - const MEDCouplingCartesianAMRMesh *gf(getMyGodFather()); - ofs << " getImageMesh()); - std::vector orig(gfm->getOrigin()); - std::vector spacing(gfm->getDXYZ()); - int dim((int)orig.size()); - std::copy(orig.begin(),orig.end(),std::ostream_iterator(ofs," ")); ofs << "\" grid_description=\""; - for(int i=0;i\n"; - // - int maxLev(gf->getMaxNumberOfLevelsRelativeToThis()),kk(0); - for(int i=0;i patches(gf->retrieveGridsAt(i)); - std::size_t sz(patches.size()); - std::vector< MEDCouplingAutoRefCountObjectPtr > patchesSafe(sz); - for(std::size_t j=0;j(ofs," ")); - ofs << "\">\n"; - if(i!=maxLev-1) - { - std::vector factors(patches[0]->getMesh()->getFactors()); - for(int k=0;k::const_iterator it=patches.begin();it!=patches.end();it++,jj++,kk++) - { - ofs << " (*it)); - const MEDCouplingCartesianAMRMeshGen *mesh((*it)->getMesh()); - if(patchCast) - { - const std::vector< std::pair >& bltr(patchCast->getBLTRRangeRelativeToGF()); - for(int pp=0;ppgetMesh()->getImageMesh()); - std::vector cgs(im->getCellGridStructure()); - for(int pp=0;pppresenceOf((*it)->getMesh(),tmp)) - { - const DataArrayDoubleCollection& ddc(_levs[i]->getFieldsAt(tmp)); - std::vector arrs(ddc.retrieveFields()); - std::size_t nbFields(arrs.size()); - std::vector< MEDCouplingAutoRefCountObjectPtr > arrsSafe(nbFields),arrs2Safe(nbFields); - std::vector< const MEDCouplingFieldDouble *> fields(nbFields); - std::vector< MEDCouplingAutoRefCountObjectPtr > fieldsSafe(nbFields); - for(std::size_t pp=0;pp im(mesh->getImageMesh()->buildWithGhost(_ghost_lev)); - std::vector cgs(mesh->getImageMesh()->getCellGridStructure()),cgsWG(im->getCellGridStructure()); - arrs2Safe[pp]=DataArrayDouble::New(); - arrs2Safe[pp]->alloc(mesh->getImageMesh()->getNumberOfCells(),arrs[pp]->getNumberOfComponents()); - std::vector< std::pair > cgs2(MEDCouplingStructuredMesh::GetCompactFrmtFromDimensions(cgs)); - MEDCouplingStructuredMesh::ApplyGhostOnCompactFrmt(cgs2,_ghost_lev); - std::vector fakeFactors(mesh->getImageMesh()->getSpaceDimension(),1); - MEDCouplingIMesh::SpreadCoarseToFine(arrs[pp],cgsWG,arrs2Safe[pp],cgs2,fakeFactors); - arrs2Safe[pp]->copyStringInfoFrom(*arrs[pp]); - // - fieldsSafe[pp]=MEDCouplingFieldDouble::New(ON_CELLS); fields[pp]=fieldsSafe[pp]; - fieldsSafe[pp]->setMesh(mesh->getImageMesh()); - fieldsSafe[pp]->setArray(arrs2Safe[pp]); - fieldsSafe[pp]->setName(arrs[pp]->getName()); - } - std::ostringstream vtiFileName; vtiFileName << baseName << "_" << kk << ".vti"; - MEDCouplingFieldDouble::WriteVTK(vtiFileName.str(),fields,true); - // - ofs << vtiFileName.str() << "\">\n"; - ofs << " \n \n"; - } - } - ofs << " \n"; - } - // - ofs << " \n"; - ofs << "\n"; - return zeFileName; -} - - /*! - * This method is useful just after a remesh after a time step computation to project values in \a this to the new - * mesh \a targetGF. - * - * This method performs a projection from \a this to a target AMR mesh \a targetGF. - * This method performs the projection by trying to transfer the finest information to \a targetGF. - * \b WARNING this method does not update the ghost zone, if any. - * The level0 of \a this god father must have the same structure than those of \a targetGF. - * - * This method makes checks that ghost size of \a this and \a targetGF are the same, and that - * the number of levels in \a this and in \a targetGF are also the same. - */ -MEDCouplingAMRAttribute *MEDCouplingAMRAttribute::projectTo(MEDCouplingCartesianAMRMesh *targetGF) const -{ - if(!targetGF) - throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::projectTo : given other target god is NULL !"); - if(_levs.empty()) - throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::projectTo : no levels in this !"); - const MEDCouplingGridCollection *lev0(_levs[0]); - if(!lev0) - throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::projectTo : lev0 is NULL !"); - std::vector< std::pair < std::string, std::vector > > fieldNames(lev0->getInfoOnComponents()); - MEDCouplingAutoRefCountObjectPtr ret(MEDCouplingAMRAttribute::New(targetGF,fieldNames,_ghost_lev)); - ret->spillNatures(lev0->getNatures()); - ret->alloc(); - int nbLevs(getNumberOfLevels()); - if(targetGF->getMaxNumberOfLevelsRelativeToThis()!=nbLevs) - throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::projectTo : number of levels of this and targetGF must be the same !"); - // first step copy level0 - if(getMyGodFather()->getImageMesh()->getCellGridStructure()!=targetGF->getImageMesh()->getCellGridStructure()) - throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::projectTo : god father of this and target ones do not have the same structure !"); - const DataArrayDoubleCollection& col(lev0->getFieldsAt(0)); - DataArrayDoubleCollection& colTarget(ret->_levs[0]->getFieldsAt(0)); - colTarget.copyFrom(col); - // then go deeper and deeper - for(int i=1;isynchronizeCoarseToFineByOneLevel(i-1); - MEDCouplingGridCollection *targetCol(ret->_levs[i]); - if(!targetCol) - throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::projectTo : null lev of target !"); - const MEDCouplingGridCollection *thisCol(_levs[i]); - if(!thisCol) - throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::projectTo : null lev of this !"); - targetCol->copyOverlappedZoneFrom(_ghost_lev,*thisCol); - } - return ret.retn(); -} - -/*! - * This method synchronizes from fine to coarse direction arrays. This method makes the hypothesis that \a this has been allocated before using - * MEDCouplingAMRAttribute::alloc method. - * This method \b DOES \b NOT \b UPDATE the ghost zones (neither the fine not the coarse) - * - * \sa synchronizeFineToCoarseBetween - */ -void MEDCouplingAMRAttribute::synchronizeFineToCoarse() -{ - if(_levs.empty()) - throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::synchronizeFineToCoarse : not any levels in this !"); - std::size_t sz(_levs.size()); - // - while(sz>1) - { - sz--; - synchronizeFineToCoarseByOneLevel((int)sz); - } -} - -/*! - * This method allows to synchronizes fields on fine patches on level \a fromLev to coarser patches at \a toLev level. - * This method operates step by step performing the synchronization the \a fromLev to \a fromLev - 1, then \a fromLev -1 to \a fromLev - 2 ... - * until reaching \a toLev level. - * This method \b DOES \b NOT \b UPDATE the ghost zones (neither the fine not the coarse). - * - * \param [in] fromLev - an existing level considered as fine so bigger than \a toLev - * \param [in] toLev - an existing level considered as the target level to reach. - * - */ -void MEDCouplingAMRAttribute::synchronizeFineToCoarseBetween(int fromLev, int toLev) -{ - int nbl(getNumberOfLevels()); - if(fromLev<0 || toLev<0 || fromLev>=nbl || toLev>=nbl) - throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::synchronizeFineToCoarseBetween : fromLev and toLev must be >= 0 and lower than number of levels in this !"); - if(fromLev==toLev) - return ;//nothing to do - if(fromLevtoLev;i--) - synchronizeFineToCoarseByOneLevel(i); -} - -/*! - * This method synchronizes from coarse to fine arrays and fine to fine each other (if _ghost_lev is >0). This method makes the hypothesis that \a this has been allocated before using - * MEDCouplingAMRAttribute::alloc method. - * This method \b DOES \b UPDATE \b the \b ghost \b zone (contrary to synchronizeFineToCoarse method) - */ -void MEDCouplingAMRAttribute::synchronizeCoarseToFine() -{ - if(_levs.empty()) - throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::synchronizeCoarseToFine : not any levels in this !"); - std::size_t sz(_levs.size()); - // - for(std::size_t i=0;i=nbl || toLev>=nbl) - throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::synchronizeCoarseToFineBetween : fromLev and toLev must be >= 0 and lower than number of levels in this !"); - if(fromLev==toLev) - return ;//nothing to do - if(fromLev>toLev) - throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::synchronizeCoarseToFineBetween : the fromLev level is greater than toLev level ! Call synchronizeFineToCoarseBetween instead !"); - for(int i=fromLev;isynchronizeFineEachOther(_ghost_lev,_neighbors[i]); - } - // 3rd - mixed level - for(std::vector< std::pair >::const_iterator it=_mixed_lev_neighbors.begin();it!=_mixed_lev_neighbors.end();it++) - { - const DataArrayDoubleCollection *firstDAC(&findCollectionAttachedTo((*it).first->getMesh())),*secondDAC(&findCollectionAttachedTo((*it).second->getMesh())); - DataArrayDoubleCollection::SynchronizeGhostZoneOfOneUsingTwo(_ghost_lev,(*it).first,firstDAC,(*it).second,secondDAC); - } - // 4th - same level but with far ancestor. - for(int i=1;isynchronizeFineEachOtherExt(_ghost_lev,_cross_lev_neighbors[i]); - } -} - -/*! - * This method works \b ONLY \b ON \b DIRECT \b SONS \b OF \a mesh. So only a part of patches at a given level is updated here. - * The ghost zone of all of these sons of \a mesh are updated using the brother patches (the patches sharing the \b SAME \a mesh). - * It is sometimes possible that a ghost zone of some sons of \a mesh are covered by a patch of same level but different father. - * For such cases, the ghost zones are \b NOT updated. If you need a more thorough (but more costly) ghost zone update use synchronizeAllGhostZonesAtASpecifiedLevel method instead. - * - * \param [in] mesh - an element in the progeny of god father in \a this, which the ghost zone of its sons will be updated each other. - * - */ -void MEDCouplingAMRAttribute::synchronizeAllGhostZonesOfDirectChidrenOf(const MEDCouplingCartesianAMRMeshGen *mesh) -{ - if(!mesh) - throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::synchronizeAllGhostZonesOfDirectChidrenOf : input mesh is NULL !"); - int level(mesh->getAbsoluteLevelRelativeTo(_gf)),sz(getNumberOfLevels()); - if(level<0 || level>=sz-1) - throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::synchronizeAllGhostZonesOfDirectChidrenOf : the specified level does not exist ! Must be in [0,nbOfLevelsOfThis-1) !"); - const std::vector< std::pair >& itemsToFilter(_neighbors[level+1]); - std::vector< std::pair > itemsToSync; itemsToSync.reserve(itemsToFilter.size()); - for(std::vector< std::pair >::const_iterator it=itemsToFilter.begin();it!=itemsToFilter.end();it++) - { - if((*it).first->getMesh()->getFather()==mesh && (*it).second->getMesh()->getFather()==mesh) - itemsToSync.push_back(std::pair((*it).first,(*it).second)); - } - const MEDCouplingGridCollection *curLev(_levs[level+1]); - if(!curLev) - throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::synchronizeAllGhostZonesOfDirectChidrenOf : presence of a NULL element !"); - curLev->synchronizeFineEachOther(_ghost_lev,itemsToSync); -} - -/*! - * This method updates \b all the patches at level \a level each other without consideration of their father. - * So this method is more time consuming than synchronizeAllGhostZonesOfDirectChidrenOf. - */ -void MEDCouplingAMRAttribute::synchronizeAllGhostZonesAtASpecifiedLevel(int level) -{ - int maxLev(getNumberOfLevels()); - if(level<0 || level>=maxLev) - throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::synchronizeAllGhostZonesAtASpecifiedLevel : the specified level must be in [0,maxLevel) !"); - if(level==0) - return ;//at level 0 only one patch -> no need to update - // 1st step - updates all patches pairs at level \a level sharing the same father - const std::vector< std::pair >& items(_neighbors[level]); - const MEDCouplingGridCollection *curLev(_levs[level]); - if(!curLev) - throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::synchronizeAllGhostZonesAtASpecifiedLevel : presence of a NULL element !"); - curLev->synchronizeFineEachOther(_ghost_lev,items); - //2nd step - updates all patches pairs at level \a level not sharing the same father - const std::vector< std::pair >& items2(_cross_lev_neighbors[level]); - curLev->synchronizeFineEachOtherExt(_ghost_lev,items2); -} - -/*! - * This method updates ghost zones of patches at level \a level whatever their father \b using \b father \b patches \b ONLY (at level \b level - 1). - * This method is useful to propagate to the ghost zone of childhood the modification. - */ -void MEDCouplingAMRAttribute::synchronizeAllGhostZonesAtASpecifiedLevelUsingOnlyFather(int level) -{ - int maxLev(getNumberOfLevels()); - if(level<=0 || level>=maxLev) - throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::synchronizeAllGhostZonesAtASpecifiedLevelUsingOnlyFather : the specified level must be in (0,maxLevel) !"); - const MEDCouplingGridCollection *fine(_levs[level]),*coarse(_levs[level-1]); - MEDCouplingGridCollection::SynchronizeCoarseToFineOnlyInGhostZone(_ghost_lev,coarse,fine); - //_cross_lev_neighbors is not needed. -} - -/*! - * This method allocates all DataArrayDouble instances stored recursively in \a this. - * - * \sa dealloc - */ -void MEDCouplingAMRAttribute::alloc() -{ - _tlc.resetState(); - for(std::vector< MEDCouplingAutoRefCountObjectPtr >::iterator it=_levs.begin();it!=_levs.end();it++) - { - MEDCouplingGridCollection *elt(*it); - if(elt) - elt->alloc(_ghost_lev); - else - throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::alloc : internal error !"); - } -} - -/*! - * This method deallocates all DataArrayDouble instances stored recursively in \a this. - * \sa alloc - */ -void MEDCouplingAMRAttribute::dealloc() -{ - _tlc.checkConst(); - for(std::vector< MEDCouplingAutoRefCountObjectPtr >::iterator it=_levs.begin();it!=_levs.end();it++) - { - MEDCouplingGridCollection *elt(*it); - if(elt) - elt->dealloc(); - else - throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::dealloc : internal error !"); - } -} - -bool MEDCouplingAMRAttribute::changeGodFather(MEDCouplingCartesianAMRMesh *gf) -{ - bool ret(MEDCouplingDataForGodFather::changeGodFather(gf)); - return ret; -} - -std::size_t MEDCouplingAMRAttribute::getHeapMemorySizeWithoutChildren() const -{ - std::size_t ret(sizeof(MEDCouplingAMRAttribute)); - ret+=_levs.capacity()*sizeof(MEDCouplingAutoRefCountObjectPtr); - return ret; -} - -std::vector MEDCouplingAMRAttribute::getDirectChildrenWithNull() const -{ - std::vector ret; - for(std::vector< MEDCouplingAutoRefCountObjectPtr >::const_iterator it=_levs.begin();it!=_levs.end();it++) - ret.push_back((const MEDCouplingGridCollection *)*it); - return ret; -} - -void MEDCouplingAMRAttribute::updateTime() const -{//tony -} - -MEDCouplingAMRAttribute::MEDCouplingAMRAttribute(MEDCouplingCartesianAMRMesh *gf, const std::vector< std::pair >& fieldNames, int ghostLev):MEDCouplingDataForGodFather(gf),_ghost_lev(ghostLev) -{ - //gf non empty, checked by constructor - int maxLev(gf->getMaxNumberOfLevelsRelativeToThis()); - _levs.resize(maxLev); - for(int i=0;i patches(gf->retrieveGridsAt(i)); - std::size_t sz(patches.size()); - std::vector< MEDCouplingAutoRefCountObjectPtr > patchesSafe(patches.size()); - for(std::size_t j=0;j ms(sz); - for(std::size_t j=0;jgetMesh(); - } - _levs[i]=MEDCouplingGridCollection::New(ms,fieldNames); - } - // updates cross levels neighbors - _neighbors.resize(_levs.size()); - _cross_lev_neighbors.resize(_levs.size()); - if(_levs.empty()) - throw INTERP_KERNEL::Exception("constructor of MEDCouplingAMRAttribute : not any levels in this !"); - std::size_t sz(_levs.size()); - for(std::size_t i=1;ifindNeighbors(_ghost_lev); - if(i!=sz-1) - { - for(std::vector< std::pair >::const_iterator it=_neighbors[i].begin();it!=_neighbors[i].end();it++) - { - MEDCouplingCartesianAMRPatch::FindNeighborsOfSubPatchesOf(_ghost_lev,(*it).first,(*it).second,_mixed_lev_neighbors); - std::vector< std::vector < std::pair > > neighs2(MEDCouplingCartesianAMRPatch::FindNeighborsOfSubPatchesOfSameLev(_ghost_lev,(*it).first,(*it).second)); - std::size_t fullLev(i+neighs2.size()); - if(fullLev>=sz) - throw INTERP_KERNEL::Exception("constructor of MEDCouplingAMRAttribute : internal error ! something is wrong in computation of cross level neighbors !"); - std::size_t ii(i+1); - for(std::vector< std::vector< std::pair > >::const_iterator it0=neighs2.begin();it0!=neighs2.end();it0++,ii++) - _cross_lev_neighbors[ii].insert(_cross_lev_neighbors[ii].end(),(*it0).begin(),(*it0).end()); - } - } - } -} - -MEDCouplingAMRAttribute::MEDCouplingAMRAttribute(const MEDCouplingAMRAttribute& other, bool deepCpyGF):MEDCouplingDataForGodFather(other,deepCpyGF),_ghost_lev(other._ghost_lev),_levs(other._levs.size()),_neighbors(other._neighbors),_mixed_lev_neighbors(other._mixed_lev_neighbors),_cross_lev_neighbors(other._cross_lev_neighbors) -{ - std::size_t sz(other._levs.size()); - for(std::size_t i=0;ideepCpy(_gf,other._gf); - } - } - //_cross_lev_neighbors(other._cross_lev_neighbors) - sz=other._neighbors.size(); - for(std::size_t i=0;i >& neigh2(other._neighbors[i]); - std::size_t sz2(neigh2.size()); - std::vector< std::pair >& neigh3(_neighbors[i]); - for(std::size_t j=0;j pp1(p1->getMesh()->getPositionRelativeTo(other._gf)),pp2(p2->getMesh()->getPositionRelativeTo(other._gf)); - neigh3[j].first=_gf->getPatchAtPosition(pp1); - neigh3[j].second=_gf->getPatchAtPosition(pp2); - } - } - // - sz=other._mixed_lev_neighbors.size(); - for(std::size_t i=0;i pp1(p1->getMesh()->getPositionRelativeTo(other._gf)),pp2(p2->getMesh()->getPositionRelativeTo(other._gf)); - _mixed_lev_neighbors[i].first=_gf->getPatchAtPosition(pp1); - _mixed_lev_neighbors[i].second=_gf->getPatchAtPosition(pp2); - } - // - sz=other._cross_lev_neighbors.size(); - for(std::size_t i=0;i >& neigh2(other._cross_lev_neighbors[i]); - std::size_t sz2(neigh2.size()); - std::vector< std::pair >& neigh3(_cross_lev_neighbors[i]); - for(std::size_t j=0;j pp1(p1->getMesh()->getPositionRelativeTo(other._gf)),pp2(p2->getMesh()->getPositionRelativeTo(other._gf)); - neigh3[j].first=_gf->getPatchAtPosition(pp1); - neigh3[j].second=_gf->getPatchAtPosition(pp2); - } - } -} - -const DataArrayDoubleCollection& MEDCouplingAMRAttribute::findCollectionAttachedTo(const MEDCouplingCartesianAMRMeshGen *m) const -{ - for(std::vector< MEDCouplingAutoRefCountObjectPtr >::const_iterator it=_levs.begin();it!=_levs.end();it++) - { - const MEDCouplingGridCollection *elt(*it); - if(elt) - { - int tmp(-1); - if(elt->presenceOf(m,tmp)) - { - return elt->getFieldsAt(tmp); - } - } - } - throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::findCollectionAttachedTo : unable to find such part of mesh in this !"); -} - -void MEDCouplingAMRAttribute::synchronizeFineToCoarseByOneLevel(int level) -{ - int nbl(getNumberOfLevels()); - if(level<=0 || level>=nbl) - throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::synchronizeFineToCoarseByOneLevel : the input level must be in ]0,nb_of_levels[ !"); - const MEDCouplingGridCollection *fine(_levs[level]),*coarse(_levs[level-1]); - MEDCouplingGridCollection::SynchronizeFineToCoarse(_ghost_lev,fine,coarse); -} - -void MEDCouplingAMRAttribute::synchronizeCoarseToFineByOneLevel(int level) -{ - int nbl(getNumberOfLevels()); - if(level<0 || level>=nbl-1) - throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::synchronizeFineToCoarseByOneLevel : the input level must be in [0,nb_of_levels[ !"); - const MEDCouplingGridCollection *fine(_levs[level+1]),*coarse(_levs[level]); - MEDCouplingGridCollection::SynchronizeCoarseToFine(_ghost_lev,coarse,fine); -} diff --git a/src/MEDCoupling/MEDCouplingAMRAttribute.hxx b/src/MEDCoupling/MEDCouplingAMRAttribute.hxx deleted file mode 100644 index 2af4d3b92..000000000 --- a/src/MEDCoupling/MEDCouplingAMRAttribute.hxx +++ /dev/null @@ -1,182 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 -// 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 - -#ifndef __MEDCOUPLINGAMRATTRIBUTE_HXX__ -#define __MEDCOUPLINGAMRATTRIBUTE_HXX__ - -#include "MEDCoupling.hxx" -#include "MEDCouplingNatureOfFieldEnum" -#include "MEDCouplingCartesianAMRMesh.hxx" - -namespace ParaMEDMEM -{ - /// @cond INTERNAL - class DataArrayDoubleCollection : public RefCountObject, public TimeLabel - { - public: - static DataArrayDoubleCollection *New(const std::vector< std::pair >& fieldNames); - DataArrayDoubleCollection *deepCpy() const; - void allocTuples(int nbOfTuples); - void dellocTuples(); - void copyFrom(const DataArrayDoubleCollection& other); - void spillInfoOnComponents(const std::vector< std::vector >& compNames); - void spillNatures(const std::vector& nfs); - std::vector< std::pair > > getInfoOnComponents() const; - std::vector getNatures() const; - std::vector retrieveFields() const; - const DataArrayDouble *getFieldWithName(const std::string& name) const; - DataArrayDouble *getFieldWithName(const std::string& name); - DataArrayDouble *at(int pos); - const DataArrayDouble *at(int pos) const; - int size() const; - static void SynchronizeFineToCoarse(int ghostLev, const MEDCouplingCartesianAMRMeshGen *fatherOfFineMesh, int patchId, const DataArrayDoubleCollection *fine, DataArrayDoubleCollection *coarse); - static void SynchronizeCoarseToFine(int ghostLev, const MEDCouplingCartesianAMRMeshGen *fatherOfFineMesh, int patchId, const DataArrayDoubleCollection *coarse, DataArrayDoubleCollection *fine); - static void SynchronizeFineEachOther(int patchId, int ghostLev, const MEDCouplingCartesianAMRMeshGen *fatherOfFineMesh, const std::vector& children, const std::vector& fieldsOnFine); - static void SynchronizeCoarseToFineOnlyInGhostZone(int ghostLev, const MEDCouplingCartesianAMRMeshGen *fatherOfFineMesh, int patchId, const DataArrayDoubleCollection *coarse, DataArrayDoubleCollection *fine); - static void SynchronizeGhostZoneOfOneUsingTwo(int ghostLev, const MEDCouplingCartesianAMRPatch *p1, const DataArrayDoubleCollection *p1dac, const MEDCouplingCartesianAMRPatch *p2, const DataArrayDoubleCollection *p2dac); - void synchronizeMyGhostZoneUsing(int ghostLev, const DataArrayDoubleCollection& other, const MEDCouplingCartesianAMRPatch *thisp, const MEDCouplingCartesianAMRPatch *otherp, const MEDCouplingCartesianAMRMeshGen *father) const; - void synchronizeMyGhostZoneUsingExt(int ghostLev, const DataArrayDoubleCollection& other, const MEDCouplingCartesianAMRPatch *thisp, const MEDCouplingCartesianAMRPatch *otherp) const; - private: - DataArrayDoubleCollection(const std::vector< std::pair >& fieldNames); - DataArrayDoubleCollection(const DataArrayDoubleCollection& other); - std::size_t getHeapMemorySizeWithoutChildren() const; - std::vector getDirectChildrenWithNull() const; - void updateTime() const; - static void CheckDiscriminantNames(const std::vector& names); - static bool IsConservativeNature(NatureOfField n); - static void CheckSameNatures(NatureOfField n1, NatureOfField n2); - static void CheckValidNature(NatureOfField n); - private: - std::vector< std::pair< MEDCouplingAutoRefCountObjectPtr, NatureOfField > > _arrs; - }; - - class MEDCouplingGridCollection : public RefCountObject, public TimeLabel - { - public: - static MEDCouplingGridCollection *New(const std::vector& ms, const std::vector< std::pair >& fieldNames); - MEDCouplingGridCollection *deepCpy(const MEDCouplingCartesianAMRMeshGen *newGf, const MEDCouplingCartesianAMRMeshGen *oldGf) const; - void alloc(int ghostLev); - void dealloc(); - void spillInfoOnComponents(const std::vector< std::vector >& compNames); - void spillNatures(const std::vector& nfs); - std::vector< std::pair > > getInfoOnComponents() const; - std::vector getNatures() const; - bool presenceOf(const MEDCouplingCartesianAMRMeshGen *m, int& pos) const; - const DataArrayDoubleCollection& getFieldsAt(int pos) const; - DataArrayDoubleCollection& getFieldsAt(int pos); - void copyOverlappedZoneFrom(int ghostLev, const MEDCouplingGridCollection& other); - static void SynchronizeFineToCoarse(int ghostLev, const MEDCouplingGridCollection *fine, const MEDCouplingGridCollection *coarse); - static void SynchronizeCoarseToFine(int ghostLev, const MEDCouplingGridCollection *coarse, const MEDCouplingGridCollection *fine); - void synchronizeFineEachOther(int ghostLev, const std::vector< std::pair >& ps) const; - void synchronizeFineEachOtherExt(int ghostLev, const std::vector< std::pair >& ps) const; - std::vector< std::pair > findNeighbors(int ghostLev) const; - static void SynchronizeCoarseToFineOnlyInGhostZone(int ghostLev, const MEDCouplingGridCollection *coarse, const MEDCouplingGridCollection *fine); - void fillIfInTheProgenyOf(const std::string& fieldName, const MEDCouplingCartesianAMRMeshGen *head, std::vector& recurseArrs) const; - private: - MEDCouplingGridCollection(const std::vector& ms, const std::vector< std::pair >& fieldNames); - MEDCouplingGridCollection(const MEDCouplingGridCollection& other, const MEDCouplingCartesianAMRMeshGen *newGf, const MEDCouplingCartesianAMRMeshGen *oldGf); - std::size_t getHeapMemorySizeWithoutChildren() const; - std::vector getDirectChildrenWithNull() const; - void updateTime() const; - private: - std::vector< std::pair > > _map_of_dadc; - }; - - /// @endcond - - class MEDCouplingDataForGodFather : public RefCountObject - { - friend class MEDCouplingCartesianAMRMesh; - public: - MEDCOUPLING_EXPORT MEDCouplingCartesianAMRMesh *getMyGodFather(); - MEDCOUPLING_EXPORT const MEDCouplingCartesianAMRMesh *getMyGodFather() const; - MEDCOUPLING_EXPORT virtual void synchronizeFineToCoarse() = 0; - MEDCOUPLING_EXPORT virtual void synchronizeFineToCoarseBetween(int fromLev, int toLev) = 0; - MEDCOUPLING_EXPORT virtual void synchronizeCoarseToFine() = 0; - MEDCOUPLING_EXPORT virtual void synchronizeCoarseToFineBetween(int fromLev, int toLev) = 0; - MEDCOUPLING_EXPORT virtual void synchronizeAllGhostZones() = 0; - MEDCOUPLING_EXPORT virtual void synchronizeAllGhostZonesOfDirectChidrenOf(const MEDCouplingCartesianAMRMeshGen *mesh) = 0; - MEDCOUPLING_EXPORT virtual void synchronizeAllGhostZonesAtASpecifiedLevel(int level) = 0; - MEDCOUPLING_EXPORT virtual void synchronizeAllGhostZonesAtASpecifiedLevelUsingOnlyFather(int level) = 0; - MEDCOUPLING_EXPORT virtual void alloc() = 0; - MEDCOUPLING_EXPORT virtual void dealloc() = 0; - protected: - MEDCouplingDataForGodFather(MEDCouplingCartesianAMRMesh *gf); - void checkGodFatherFrozen() const; - protected: - virtual bool changeGodFather(MEDCouplingCartesianAMRMesh *gf); - MEDCouplingDataForGodFather(const MEDCouplingDataForGodFather& other, bool deepCpyGF); - protected: - MEDCouplingAutoRefCountObjectPtr _gf; - TimeLabelConstOverseer _tlc; - }; - - class MEDCouplingAMRAttribute : public MEDCouplingDataForGodFather, public TimeLabel - { - public: - MEDCOUPLING_EXPORT static MEDCouplingAMRAttribute *New(MEDCouplingCartesianAMRMesh *gf, const std::vector< std::pair >& fieldNames, int ghostLev); - MEDCOUPLING_EXPORT static MEDCouplingAMRAttribute *New(MEDCouplingCartesianAMRMesh *gf, const std::vector< std::pair > >& fieldNames, int ghostLev); - MEDCOUPLING_EXPORT void spillInfoOnComponents(const std::vector< std::vector >& compNames); - MEDCOUPLING_EXPORT void spillNatures(const std::vector& nfs); - MEDCOUPLING_EXPORT MEDCouplingAMRAttribute *deepCpy() const; - MEDCOUPLING_EXPORT MEDCouplingAMRAttribute *deepCpyWithoutGodFather() const; - MEDCOUPLING_EXPORT int getNumberOfLevels() const; - MEDCOUPLING_EXPORT std::vector retrieveFieldsOn(MEDCouplingCartesianAMRMeshGen *mesh) const; - MEDCOUPLING_EXPORT const DataArrayDouble *getFieldOn(MEDCouplingCartesianAMRMeshGen *mesh, const std::string& fieldName) const; - MEDCOUPLING_EXPORT DataArrayDouble *getFieldOn(MEDCouplingCartesianAMRMeshGen *mesh, const std::string& fieldName); - MEDCOUPLING_EXPORT MEDCouplingFieldDouble *buildCellFieldOnRecurseWithoutOverlapWithoutGhost(MEDCouplingCartesianAMRMeshGen *mesh, const std::string& fieldName) const; - MEDCOUPLING_EXPORT MEDCouplingFieldDouble *buildCellFieldOnWithGhost(MEDCouplingCartesianAMRMeshGen *mesh, const std::string& fieldName) const; - MEDCOUPLING_EXPORT MEDCouplingFieldDouble *buildCellFieldOnWithoutGhost(MEDCouplingCartesianAMRMeshGen *mesh, const std::string& fieldName) const; - MEDCOUPLING_EXPORT std::string writeVTHB(const std::string& fileName) const; - // - MEDCOUPLING_EXPORT MEDCouplingAMRAttribute *projectTo(MEDCouplingCartesianAMRMesh *targetGF) const; - // - MEDCOUPLING_EXPORT void synchronizeFineToCoarse(); - MEDCOUPLING_EXPORT void synchronizeFineToCoarseBetween(int fromLev, int toLev); - MEDCOUPLING_EXPORT void synchronizeCoarseToFine(); - MEDCOUPLING_EXPORT void synchronizeCoarseToFineBetween(int fromLev, int toLev); - MEDCOUPLING_EXPORT void synchronizeAllGhostZones(); - MEDCOUPLING_EXPORT void synchronizeAllGhostZonesOfDirectChidrenOf(const MEDCouplingCartesianAMRMeshGen *mesh); - MEDCOUPLING_EXPORT void synchronizeAllGhostZonesAtASpecifiedLevel(int level); - MEDCOUPLING_EXPORT void synchronizeAllGhostZonesAtASpecifiedLevelUsingOnlyFather(int level); - // - MEDCOUPLING_EXPORT void alloc(); - MEDCOUPLING_EXPORT void dealloc(); - MEDCOUPLING_EXPORT bool changeGodFather(MEDCouplingCartesianAMRMesh *gf); - // - MEDCOUPLING_EXPORT std::size_t getHeapMemorySizeWithoutChildren() const; - MEDCOUPLING_EXPORT std::vector getDirectChildrenWithNull() const; - MEDCOUPLING_EXPORT void updateTime() const; - private: - MEDCouplingAMRAttribute(MEDCouplingCartesianAMRMesh *gf, const std::vector< std::pair >& fieldNames, int ghostLev); - MEDCouplingAMRAttribute(const MEDCouplingAMRAttribute& other, bool deepCpyGF); - const DataArrayDoubleCollection& findCollectionAttachedTo(const MEDCouplingCartesianAMRMeshGen *m) const; - void synchronizeFineToCoarseByOneLevel(int level); - void synchronizeCoarseToFineByOneLevel(int level); - private: - int _ghost_lev; - std::vector< MEDCouplingAutoRefCountObjectPtr > _levs; - std::vector< std::vector< std::pair > > _neighbors; - std::vector< std::pair > _mixed_lev_neighbors; - std::vector< std::vector< std::pair > > _cross_lev_neighbors; - }; -} - -#endif diff --git a/src/MEDCoupling/MEDCouplingAutoRefCountObjectPtr.hxx b/src/MEDCoupling/MEDCouplingAutoRefCountObjectPtr.hxx deleted file mode 100644 index 02719b50b..000000000 --- a/src/MEDCoupling/MEDCouplingAutoRefCountObjectPtr.hxx +++ /dev/null @@ -1,79 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 -// 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_MEDCOUPLINGAUTOREFCOUNTOBJECTPTR_HXX__ -#define __PARAMEDMEM_MEDCOUPLINGAUTOREFCOUNTOBJECTPTR_HXX__ - -#include "MEDCouplingRefCountObject.hxx" -#include "InterpKernelException.hxx" - -namespace ParaMEDMEM -{ - template - class MEDCouplingAutoRefCountObjectPtr - { - public: - MEDCouplingAutoRefCountObjectPtr(const MEDCouplingAutoRefCountObjectPtr& other):_ptr(0) { referPtr(other._ptr); } - MEDCouplingAutoRefCountObjectPtr(T *ptr=0):_ptr(ptr) { } - ~MEDCouplingAutoRefCountObjectPtr() { destroyPtr(); } - bool operator==(const MEDCouplingAutoRefCountObjectPtr& other) const { return _ptr==other._ptr; } - bool operator==(const T *other) const { return _ptr==other; } - MEDCouplingAutoRefCountObjectPtr &operator=(const MEDCouplingAutoRefCountObjectPtr& other) { if(_ptr!=other._ptr) { destroyPtr(); referPtr(other._ptr); } return *this; } - MEDCouplingAutoRefCountObjectPtr &operator=(T *ptr) { if(_ptr!=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; } - 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(); } - private: - T *_ptr; - }; - - template - typename ParaMEDMEM::MEDCouplingAutoRefCountObjectPtr DynamicCast(typename ParaMEDMEM::MEDCouplingAutoRefCountObjectPtr& autoSubPtr) throw() - { - T *subPtr(autoSubPtr); - U *ptr(dynamic_cast(subPtr)); - typename ParaMEDMEM::MEDCouplingAutoRefCountObjectPtr ret(ptr); - if(ptr) - ptr->incrRef(); - return ret; - } - - template - typename ParaMEDMEM::MEDCouplingAutoRefCountObjectPtr DynamicCastSafe(typename ParaMEDMEM::MEDCouplingAutoRefCountObjectPtr& autoSubPtr) - { - T *subPtr(autoSubPtr); - U *ptr(dynamic_cast(subPtr)); - if(subPtr && !ptr) - throw INTERP_KERNEL::Exception("DynamicCastSafe : U is not a subtype of T !"); - typename ParaMEDMEM::MEDCouplingAutoRefCountObjectPtr ret(ptr); - if(ptr) - ptr->incrRef(); - return ret; - } -} - -#endif diff --git a/src/MEDCoupling/MEDCouplingCMesh.cxx b/src/MEDCoupling/MEDCouplingCMesh.cxx deleted file mode 100644 index 597b682a6..000000000 --- a/src/MEDCoupling/MEDCouplingCMesh.cxx +++ /dev/null @@ -1,923 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 -// 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 "MEDCouplingCMesh.hxx" -#include "MEDCouplingMemArray.hxx" -#include "MEDCouplingFieldDouble.hxx" - -#include -#include -#include -#include - -using namespace ParaMEDMEM; - -MEDCouplingCMesh::MEDCouplingCMesh():_x_array(0),_y_array(0),_z_array(0) -{ -} - -MEDCouplingCMesh::MEDCouplingCMesh(const MEDCouplingCMesh& other, bool deepCopy):MEDCouplingStructuredMesh(other,deepCopy) -{ - if(deepCopy) - { - if(other._x_array) - _x_array=other._x_array->deepCpy(); - else - _x_array=0; - if(other._y_array) - _y_array=other._y_array->deepCpy(); - else - _y_array=0; - if(other._z_array) - _z_array=other._z_array->deepCpy(); - else - _z_array=0; - } - else - { - _x_array=other._x_array; - if(_x_array) - _x_array->incrRef(); - _y_array=other._y_array; - if(_y_array) - _y_array->incrRef(); - _z_array=other._z_array; - if(_z_array) - _z_array->incrRef(); - } -} - -MEDCouplingCMesh::~MEDCouplingCMesh() -{ - if(_x_array) - _x_array->decrRef(); - if(_y_array) - _y_array->decrRef(); - if(_z_array) - _z_array->decrRef(); -} - -MEDCouplingCMesh *MEDCouplingCMesh::New() -{ - return new MEDCouplingCMesh; -} - -MEDCouplingCMesh *MEDCouplingCMesh::New(const std::string& meshName) -{ - MEDCouplingCMesh *ret=new MEDCouplingCMesh; - ret->setName(meshName); - return ret; -} - -MEDCouplingMesh *MEDCouplingCMesh::deepCpy() const -{ - return clone(true); -} - -MEDCouplingCMesh *MEDCouplingCMesh::clone(bool recDeepCpy) const -{ - return new MEDCouplingCMesh(*this,recDeepCpy); -} - -void MEDCouplingCMesh::updateTime() const -{ - if(_x_array) - updateTimeWith(*_x_array); - if(_y_array) - updateTimeWith(*_y_array); - if(_z_array) - updateTimeWith(*_z_array); -} - -std::size_t MEDCouplingCMesh::getHeapMemorySizeWithoutChildren() const -{ - return MEDCouplingStructuredMesh::getHeapMemorySizeWithoutChildren(); -} - -std::vector MEDCouplingCMesh::getDirectChildrenWithNull() const -{ - std::vector ret; - ret.push_back(_x_array); - ret.push_back(_y_array); - ret.push_back(_z_array); - return ret; -} - -/*! - * This method copyies all tiny strings from other (name and components name). - * @throw if other and this have not same mesh type. - */ -void MEDCouplingCMesh::copyTinyStringsFrom(const MEDCouplingMesh *other) -{ - MEDCouplingStructuredMesh::copyTinyStringsFrom(other); - const MEDCouplingCMesh *otherC(dynamic_cast(other)); - if(!otherC) - throw INTERP_KERNEL::Exception("MEDCouplingCMesh::copyTinyStringsFrom : meshes have not same type !"); - if(_x_array && otherC->_x_array) - _x_array->copyStringInfoFrom(*otherC->_x_array); - if(_y_array && otherC->_y_array) - _y_array->copyStringInfoFrom(*otherC->_y_array); - if(_z_array && otherC->_z_array) - _z_array->copyStringInfoFrom(*otherC->_z_array); -} - -bool MEDCouplingCMesh::isEqualIfNotWhy(const MEDCouplingMesh *other, double prec, std::string& reason) const -{ - if(!other) - throw INTERP_KERNEL::Exception("MEDCouplingCMesh::isEqualIfNotWhy : input other pointer is null !"); - const MEDCouplingCMesh *otherC=dynamic_cast(other); - if(!otherC) - { - reason="mesh given in input is not castable in MEDCouplingCMesh !"; - return false; - } - if(!MEDCouplingStructuredMesh::isEqualIfNotWhy(other,prec,reason)) - return false; - const DataArrayDouble *thisArr[3]={_x_array,_y_array,_z_array}; - const DataArrayDouble *otherArr[3]={otherC->_x_array,otherC->_y_array,otherC->_z_array}; - std::ostringstream oss; oss.precision(15); - for(int i=0;i<3;i++) - { - if((thisArr[i]!=0 && otherArr[i]==0) || (thisArr[i]==0 && otherArr[i]!=0)) - { - oss << "Only one CMesh between the two this and other has its coordinates of rank" << i << " defined !"; - reason=oss.str(); - return false; - } - if(thisArr[i]) - if(!thisArr[i]->isEqualIfNotWhy(*otherArr[i],prec,reason)) - { - oss << "Coordinates DataArrayDouble of rank #" << i << " differ :"; - reason.insert(0,oss.str()); - return false; - } - } - return true; -} - -bool MEDCouplingCMesh::isEqualWithoutConsideringStr(const MEDCouplingMesh *other, double prec) const -{ - const MEDCouplingCMesh *otherC=dynamic_cast(other); - if(!otherC) - return false; - const DataArrayDouble *thisArr[3]={_x_array,_y_array,_z_array}; - const DataArrayDouble *otherArr[3]={otherC->_x_array,otherC->_y_array,otherC->_z_array}; - for(int i=0;i<3;i++) - { - if((thisArr[i]!=0 && otherArr[i]==0) || (thisArr[i]==0 && otherArr[i]!=0)) - return false; - if(thisArr[i]) - if(!thisArr[i]->isEqualWithoutConsideringStr(*otherArr[i],prec)) - return false; - } - return true; -} - -void MEDCouplingCMesh::checkDeepEquivalWith(const MEDCouplingMesh *other, int cellCompPol, double prec, - DataArrayInt *&cellCor, DataArrayInt *&nodeCor) const -{ - if(!isEqualWithoutConsideringStr(other,prec)) - throw INTERP_KERNEL::Exception("MEDCouplingCMesh::checkDeepEquivalWith : Meshes are not the same !"); -} - -/*! - * Nothing is done here (except to check that the other is a ParaMEDMEM::MEDCouplingCMesh instance too). - * The user intend that the nodes are the same, so by construction of ParaMEDMEM::MEDCouplingCMesh, \a this and \a other are the same ! - */ -void MEDCouplingCMesh::checkDeepEquivalOnSameNodesWith(const MEDCouplingMesh *other, int cellCompPol, double prec, - DataArrayInt *&cellCor) const -{ - if(!isEqualWithoutConsideringStr(other,prec)) - throw INTERP_KERNEL::Exception("MEDCouplingCMesh::checkDeepEquivalOnSameNodesWith : Meshes are not the same !"); -} - -void MEDCouplingCMesh::checkCoherency() const -{ - const char msg0[]="Invalid "; - const char msg1[]=" array ! Must contain more than 1 element."; - const char msg2[]=" array ! Must be with only one component."; - getSpaceDimension();// here to check that no holes in arrays ! - if(_x_array) - { - if(_x_array->getNbOfElems()<2) - { - std::ostringstream os; os << msg0 << 'X' << msg1; - throw INTERP_KERNEL::Exception(os.str().c_str()); - } - if(_x_array->getNumberOfComponents()!=1) - { - std::ostringstream os; os << msg0 << 'X' << msg2; - throw INTERP_KERNEL::Exception(os.str().c_str()); - } - } - if(_y_array) - { - if(_y_array->getNbOfElems()<2) - { - std::ostringstream os; os << msg0 << 'Y' << msg1; - throw INTERP_KERNEL::Exception(os.str().c_str()); - } - if(_y_array->getNumberOfComponents()!=1) - { - std::ostringstream os; os << msg0 << 'Y' << msg2; - throw INTERP_KERNEL::Exception(os.str().c_str()); - } - } - if(_z_array) - { - if(_z_array->getNbOfElems()<2) - { - std::ostringstream os; os << msg0 << 'Z' << msg1; - throw INTERP_KERNEL::Exception(os.str().c_str()); - } - if(_z_array->getNumberOfComponents()!=1) - { - std::ostringstream os; os << msg0 << 'Z' << msg2; - throw INTERP_KERNEL::Exception(os.str().c_str()); - } - } -} - -void MEDCouplingCMesh::checkCoherency1(double eps) const -{ - checkCoherency(); - if(_x_array) - _x_array->checkMonotonic(true, eps); - if(_y_array) - _y_array->checkMonotonic(true, eps); - if(_z_array) - _z_array->checkMonotonic(true, eps); -} - -void MEDCouplingCMesh::checkCoherency2(double eps) const -{ - checkCoherency1(eps); -} - -void MEDCouplingCMesh::getNodeGridStructure(int *res) const -{ - std::vector ret(getNodeGridStructure()); - std::copy(ret.begin(),ret.end(),res); -} - -std::vector MEDCouplingCMesh::getNodeGridStructure() const -{ - static const char MSG[]="MEDCouplingCMesh::getNodeGridStructure : mesh is invalid ! null vectors (X, Y or Z) must be put contiguously at the end !"; - std::vector ret; - bool isOK(true); - if(_x_array) - { - if(!_x_array->isAllocated() || _x_array->getNumberOfComponents()!=1) - throw INTERP_KERNEL::Exception("MEDCouplingCMesh::getNodeGridStructure : X array exits but it is not allocated or with nb of components equal to one !"); - ret.push_back(_x_array->getNumberOfTuples()); - } - else - isOK=false; - if(_y_array) - { - if(!_y_array->isAllocated() || _y_array->getNumberOfComponents()!=1) - throw INTERP_KERNEL::Exception("MEDCouplingCMesh::getNodeGridStructure : Y array exits but it is not allocated or with nb of components equal to one !"); - if(!isOK) - throw INTERP_KERNEL::Exception(MSG); - ret.push_back(_y_array->getNumberOfTuples()); - } - else - isOK=false; - if(_z_array) - { - if(!_z_array->isAllocated() || _z_array->getNumberOfComponents()!=1) - throw INTERP_KERNEL::Exception("MEDCouplingCMesh::getNodeGridStructure : Z array exits but it is not allocated or with nb of components equal to one !"); - if(!isOK) - throw INTERP_KERNEL::Exception(MSG); - ret.push_back(_z_array->getNumberOfTuples()); - } - return ret; -} - -MEDCouplingStructuredMesh *MEDCouplingCMesh::buildStructuredSubPart(const std::vector< std::pair >& cellPart) const -{ - checkCoherency(); - int dim(getSpaceDimension()); - if(dim!=(int)cellPart.size()) - { - std::ostringstream oss; oss << "MEDCouplingCMesh::buildStructuredSubPart : the space dimension is " << dim << " and cell part size is " << cellPart.size() << " !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - MEDCouplingAutoRefCountObjectPtr ret(dynamic_cast(deepCpy())); - for(int i=0;i tmp(ret->getCoordsAt(i)->selectByTupleId2(cellPart[i].first,cellPart[i].second+1,1)); - ret->setCoordsAt(i,tmp); - } - return ret.retn(); -} - -/*! - * Return the space dimension of \a this. It only considers the arrays along X, Y and Z to deduce that. - * This method throws exceptions if the not null arrays defining this are not contiguously at the end. For example X!=0,Y==0,Z!=0 will throw. - */ -int MEDCouplingCMesh::getSpaceDimension() const -{ - return (int)getNodeGridStructure().size(); -} - -void MEDCouplingCMesh::getCoordinatesOfNode(int nodeId, std::vector& coo) const -{ - int tmp[3]; - int spaceDim=getSpaceDimension(); - getSplitNodeValues(tmp); - const DataArrayDouble *tabs[3]={getCoordsAt(0),getCoordsAt(1),getCoordsAt(2)}; - int tmp2[3]; - GetPosFromId(nodeId,spaceDim,tmp,tmp2); - for(int j=0;jgetConstPointer()[tmp2[j]]); -} - -std::string MEDCouplingCMesh::simpleRepr() const -{ - std::ostringstream ret; - ret << "Cartesian 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 << "Space dimension : " << getSpaceDimension() << "\n\nArrays :\n________\n\n"; - if(_x_array) - { - ret << "X Array :\n"; - _x_array->reprZipWithoutNameStream(ret); - } - if(_y_array) - { - ret << "Y Array :\n"; - _y_array->reprZipWithoutNameStream(ret); - } - if(_z_array) - { - ret << "Z Array :\n"; - _z_array->reprZipWithoutNameStream(ret); - } - return ret.str(); -} - -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]. - * - * \if ENABLE_EXAMPLES - * \ref cpp_mccmesh_getCoordsAt "Here is a C++ example".
- * \ref py_mccmesh_getCoordsAt "Here is a Python example". - * \endif - */ -const DataArrayDouble *MEDCouplingCMesh::getCoordsAt(int i) const -{ - switch(i) - { - case 0: - return _x_array; - case 1: - return _y_array; - case 2: - return _z_array; - default: - throw INTERP_KERNEL::Exception("Invalid rank specified must be 0 or 1 or 2."); - } -} - -/*! - * 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]. - * - * \if ENABLE_EXAMPLES - * \ref cpp_mccmesh_getCoordsAt "Here is a C++ example".
- * \ref py_mccmesh_getCoordsAt "Here is a Python example". - * \endif - */ -DataArrayDouble *MEDCouplingCMesh::getCoordsAt(int i) -{ - switch(i) - { - case 0: - return _x_array; - case 1: - return _y_array; - case 2: - return _z_array; - default: - throw INTERP_KERNEL::Exception("Invalid rank specified must be 0 or 1 or 2."); - } -} - -/*! - * 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]. - * - * \if ENABLE_EXAMPLES - * \ref medcouplingcppexamplesCmeshStdBuild1 "Here is a C++ example".
- * \ref medcouplingpyexamplesCmeshStdBuild1 "Here is a Python example". - * \endif - */ -void MEDCouplingCMesh::setCoordsAt(int i, const DataArrayDouble *arr) -{ - if(arr) - arr->checkNbOfComps(1,"MEDCouplingCMesh::setCoordsAt"); - DataArrayDouble **thisArr[3]={&_x_array,&_y_array,&_z_array}; - if(i<0 || i>2) - throw INTERP_KERNEL::Exception("Invalid rank specified must be 0 or 1 or 2."); - if(arr!=*(thisArr[i])) - { - if(*(thisArr[i])) - (*(thisArr[i]))->decrRef(); - (*(thisArr[i]))=const_cast(arr); - if(*(thisArr[i])) - (*(thisArr[i]))->incrRef(); - declareAsNew(); - } -} - -/*! - * 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. - * - * \if ENABLE_EXAMPLES - * \ref medcouplingcppexamplesCmeshStdBuild1 "Here is a C++ example".
- * \ref medcouplingpyexamplesCmeshStdBuild1 "Here is a Python example". - * \endif - */ -void MEDCouplingCMesh::setCoords(const DataArrayDouble *coordsX, const DataArrayDouble *coordsY, const DataArrayDouble *coordsZ) -{ - if(coordsX) - coordsX->checkNbOfComps(1,"MEDCouplingCMesh::setCoords : coordsX"); - if(coordsY) - coordsY->checkNbOfComps(1,"MEDCouplingCMesh::setCoords : coordsY"); - if(coordsZ) - coordsZ->checkNbOfComps(1,"MEDCouplingCMesh::setCoords : coordsZ"); - if(_x_array) - _x_array->decrRef(); - _x_array=const_cast(coordsX); - if(_x_array) - _x_array->incrRef(); - if(_y_array) - _y_array->decrRef(); - _y_array=const_cast(coordsY); - if(_y_array) - _y_array->incrRef(); - if(_z_array) - _z_array->decrRef(); - _z_array=const_cast(coordsZ); - if(_z_array) - _z_array->incrRef(); - declareAsNew(); -} - -void MEDCouplingCMesh::getBoundingBox(double *bbox) const -{ - int dim=getSpaceDimension(); - int j=0; - for (int idim=0; idimgetConstPointer(); - int nb=c->getNbOfElems(); - bbox[2*j]=coords[0]; - bbox[2*j+1]=coords[nb-1]; - j++; - } - } -} - -/*! - * 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,ONE_TIME); - field->setName(name); - DataArrayDouble* array=DataArrayDouble::New(); - array->alloc(nbelem,1); - double *area_vol=array->getPointer(); - field->setArray(array) ; - array->decrRef(); - field->setMesh(const_cast(this)); - field->synchronizeTimeWithMesh(); - int tmp[3]; - getSplitCellValues(tmp); - int dim=getSpaceDimension(); - const double **thisArr=new const double *[dim]; - const DataArrayDouble *thisArr2[3]={_x_array,_y_array,_z_array}; - for(int i=0;igetConstPointer(); - for(int icell=0;icellgetConstPointer(); - int nbOfNodes=getCoordsAt(i)->getNbOfElems(); - double ref=pos[i]; - const double *w=std::find_if(d,d+nbOfNodes,std::bind2nd(std::greater_equal(),ref)); - int w2=(int)std::distance(d,w); - if(w2d[0]-eps) - w2=1; - else - return -1; - } - ret+=coeff*(w2-1); - coeff*=nbOfNodes-1; - } - else - return -1; - } - return ret; -} - -void MEDCouplingCMesh::rotate(const double *center, const double *vector, double angle) -{ - throw INTERP_KERNEL::Exception("No rotation available on CMesh : Traduce it to untructured mesh 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) - std::transform(_x_array->getConstPointer(),_x_array->getConstPointer()+_x_array->getNbOfElems(), - _x_array->getPointer(),std::bind2nd(std::plus(),vector[0])); - if(_y_array) - std::transform(_y_array->getConstPointer(),_y_array->getConstPointer()+_y_array->getNbOfElems(), - _y_array->getPointer(),std::bind2nd(std::plus(),vector[1])); - if(_z_array) - std::transform(_z_array->getConstPointer(),_z_array->getConstPointer()+_z_array->getNbOfElems(), - _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++) - { - DataArrayDouble *c=getCoordsAt(i); - if(c) - { - double *coords=c->getPointer(); - int lgth=c->getNbOfElems(); - std::transform(coords,coords+lgth,coords,std::bind2nd(std::minus(),point[i])); - std::transform(coords,coords+lgth,coords,std::bind2nd(std::multiplies(),factor)); - std::transform(coords,coords+lgth,coords,std::bind2nd(std::plus(),point[i])); - c->declareAsNew(); - } - } - updateTime(); -} - -MEDCouplingMesh *MEDCouplingCMesh::mergeMyselfWith(const MEDCouplingMesh *other) const -{ - //not implemented yet ! - 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(); - int spaceDim=getSpaceDimension(); - int nbNodes=getNumberOfNodes(); - ret->alloc(nbNodes,spaceDim); - double *pt=ret->getPointer(); - int tmp[3]; - getSplitNodeValues(tmp); - const DataArrayDouble *tabs[3]={getCoordsAt(0),getCoordsAt(1),getCoordsAt(2)}; - const double *tabsPtr[3]; - for(int j=0;jgetConstPointer(); - ret->setInfoOnComponent(j,tabs[j]->getInfoOnComponent(0)); - } - int tmp2[3]; - for(int i=0;igetNumberOfCells() 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(); - int spaceDim=getSpaceDimension(); - int nbCells=getNumberOfCells(); - ret->alloc(nbCells,spaceDim); - double *pt=ret->getPointer(); - int tmp[3]; - getSplitCellValues(tmp); - const DataArrayDouble *tabs[3]={getCoordsAt(0),getCoordsAt(1),getCoordsAt(2)}; - std::vector tabsPtr[3]; - for(int j=0;jgetNbOfElems()-1; - ret->setInfoOnComponent(j,tabs[j]->getInfoOnComponent(0)); - const double *srcPtr=tabs[j]->getConstPointer(); - tabsPtr[j].insert(tabsPtr[j].end(),srcPtr,srcPtr+sz); - std::transform(tabsPtr[j].begin(),tabsPtr[j].end(),srcPtr+1,tabsPtr[j].begin(),std::plus()); - std::transform(tabsPtr[j].begin(),tabsPtr[j].end(),tabsPtr[j].begin(),std::bind2nd(std::multiplies(),0.5)); - } - int tmp2[3]; - for(int i=0;i& 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()); - const DataArrayDouble *thisArr[3]={_x_array,_y_array,_z_array}; - for(int i=0;i<3;i++) - { - int val=-1; - std::string st; - if(thisArr[i]) - { - val=thisArr[i]->getNumberOfTuples(); - st=thisArr[i]->getInfoOnComponent(0); - } - tinyInfo.push_back(val); - littleStrings.push_back(st); - } - tinyInfo.push_back(it); - tinyInfo.push_back(order); - tinyInfoD.push_back(time); -} - -void MEDCouplingCMesh::resizeForUnserialization(const std::vector& tinyInfo, DataArrayInt *a1, DataArrayDouble *a2, std::vector& littleStrings) const -{ - a1->alloc(0,1); - int sum=0; - for(int i=0;i<3;i++) - if(tinyInfo[i]!=-1) - sum+=tinyInfo[i]; - a2->alloc(sum,1); -} - -void MEDCouplingCMesh::serialize(DataArrayInt *&a1, DataArrayDouble *&a2) const -{ - a1=DataArrayInt::New(); - a1->alloc(0,1); - const DataArrayDouble *thisArr[3]={_x_array,_y_array,_z_array}; - int sz=0; - for(int i=0;i<3;i++) - { - if(thisArr[i]) - sz+=thisArr[i]->getNumberOfTuples(); - } - a2=DataArrayDouble::New(); - a2->alloc(sz,1); - double *a2Ptr=a2->getPointer(); - for(int i=0;i<3;i++) - if(thisArr[i]) - a2Ptr=std::copy(thisArr[i]->getConstPointer(),thisArr[i]->getConstPointer()+thisArr[i]->getNumberOfTuples(),a2Ptr); -} - -void MEDCouplingCMesh::unserialization(const std::vector& tinyInfoD, const std::vector& tinyInfo, const DataArrayInt *a1, DataArrayDouble *a2, - const std::vector& littleStrings) -{ - setName(littleStrings[0]); - setDescription(littleStrings[1]); - setTimeUnit(littleStrings[2]); - DataArrayDouble **thisArr[3]={&_x_array,&_y_array,&_z_array}; - const double *data=a2->getConstPointer(); - for(int i=0;i<3;i++) - { - if(tinyInfo[i]!=-1) - { - (*(thisArr[i]))=DataArrayDouble::New(); - (*(thisArr[i]))->alloc(tinyInfo[i],1); - (*(thisArr[i]))->setInfoOnComponent(0,littleStrings[i+3]); - std::copy(data,data+tinyInfo[i],(*(thisArr[i]))->getPointer()); - data+=tinyInfo[i]; - } - } - setTime(tinyInfoD[0],tinyInfo[3],tinyInfo[4]); -} - -void MEDCouplingCMesh::writeVTKLL(std::ostream& ofs, const std::string& cellData, const std::string& pointData, DataArrayByte *byteData) const -{ - 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",byteData); - else - { - MEDCouplingAutoRefCountObjectPtr coo=DataArrayDouble::New(); coo->alloc(1,1); - coo->setIJ(0,0,0.); - coo->writeVTK(ofs,8,"Array",byteData); - } - } - ofs << " \n"; - ofs << " \n"; - ofs << " \n"; -} - -void MEDCouplingCMesh::reprQuickOverview(std::ostream& stream) const -{ - 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::getVTKFileExtension() const -{ - return std::string("vtr"); -} - -std::string MEDCouplingCMesh::getVTKDataSetType() const -{ - return std::string("RectilinearGrid"); -} diff --git a/src/MEDCoupling/MEDCouplingCMesh.hxx b/src/MEDCoupling/MEDCouplingCMesh.hxx deleted file mode 100644 index 81811212f..000000000 --- a/src/MEDCoupling/MEDCouplingCMesh.hxx +++ /dev/null @@ -1,98 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 -// 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_MEDCOUPLINGCMESH_HXX__ -#define __PARAMEDMEM_MEDCOUPLINGCMESH_HXX__ - -#include "MEDCoupling.hxx" -#include "MEDCouplingStructuredMesh.hxx" - -namespace ParaMEDMEM -{ - class MEDCouplingCMesh : public MEDCouplingStructuredMesh - { - public: - MEDCOUPLING_EXPORT static MEDCouplingCMesh *New(); - MEDCOUPLING_EXPORT static MEDCouplingCMesh *New(const std::string& meshName); - MEDCOUPLING_EXPORT MEDCouplingMesh *deepCpy() const; - MEDCOUPLING_EXPORT MEDCouplingCMesh *clone(bool recDeepCpy) const; - MEDCOUPLING_EXPORT void updateTime() const; - MEDCOUPLING_EXPORT std::size_t getHeapMemorySizeWithoutChildren() const; - MEDCOUPLING_EXPORT std::vector getDirectChildrenWithNull() const; - MEDCOUPLING_EXPORT MEDCouplingMeshType getType() const { return CARTESIAN; } - MEDCOUPLING_EXPORT void copyTinyStringsFrom(const MEDCouplingMesh *other); - MEDCOUPLING_EXPORT bool isEqualIfNotWhy(const MEDCouplingMesh *other, double prec, std::string& reason) const; - MEDCOUPLING_EXPORT bool isEqualWithoutConsideringStr(const MEDCouplingMesh *other, double prec) const; - MEDCOUPLING_EXPORT void checkDeepEquivalWith(const MEDCouplingMesh *other, int cellCompPol, double prec, - DataArrayInt *&cellCor, DataArrayInt *&nodeCor) const; - MEDCOUPLING_EXPORT void checkDeepEquivalOnSameNodesWith(const MEDCouplingMesh *other, int cellCompPol, double prec, - DataArrayInt *&cellCor) const; - MEDCOUPLING_EXPORT void checkCoherency() const; - MEDCOUPLING_EXPORT void checkCoherency1(double eps=1e-12) const; - MEDCOUPLING_EXPORT void checkCoherency2(double eps=1e-12) const; - MEDCOUPLING_EXPORT int getSpaceDimension() const; - MEDCOUPLING_EXPORT void getCoordinatesOfNode(int nodeId, std::vector& coo) const; - MEDCOUPLING_EXPORT std::string simpleRepr() const; - MEDCOUPLING_EXPORT std::string advancedRepr() const; - MEDCOUPLING_EXPORT const DataArrayDouble *getCoordsAt(int i) const; - MEDCOUPLING_EXPORT DataArrayDouble *getCoordsAt(int i); - MEDCOUPLING_EXPORT void setCoordsAt(int i, const DataArrayDouble *arr); - MEDCOUPLING_EXPORT void setCoords(const DataArrayDouble *coordsX, - const DataArrayDouble *coordsY=0, - const DataArrayDouble *coordsZ=0); - // tools - MEDCOUPLING_EXPORT void getBoundingBox(double *bbox) const; - MEDCOUPLING_EXPORT MEDCouplingFieldDouble *getMeasureField(bool isAbs) const; - MEDCOUPLING_EXPORT MEDCouplingFieldDouble *getMeasureFieldOnNode(bool isAbs) const; - MEDCOUPLING_EXPORT int getCellContainingPoint(const double *pos, double eps) const; - MEDCOUPLING_EXPORT void rotate(const double *center, const double *vector, double angle); - MEDCOUPLING_EXPORT void translate(const double *vector); - MEDCOUPLING_EXPORT void scale(const double *point, double factor); - MEDCOUPLING_EXPORT MEDCouplingMesh *mergeMyselfWith(const MEDCouplingMesh *other) const; - MEDCOUPLING_EXPORT DataArrayDouble *getCoordinatesAndOwner() const; - MEDCOUPLING_EXPORT DataArrayDouble *getBarycenterAndOwner() const; - MEDCOUPLING_EXPORT DataArrayDouble *computeIsoBarycenterOfNodesPerCell() const; - MEDCOUPLING_EXPORT void renumberCells(const int *old2NewBg, bool check=true); - //some useful methods - MEDCOUPLING_EXPORT void getNodeGridStructure(int *res) const; - MEDCOUPLING_EXPORT std::vector getNodeGridStructure() const; - MEDCouplingStructuredMesh *buildStructuredSubPart(const std::vector< std::pair >& cellPart) const; - //serialisation-unserialization - MEDCOUPLING_EXPORT void getTinySerializationInformation(std::vector& tinyInfoD, std::vector& tinyInfo, std::vector& littleStrings) const; - MEDCOUPLING_EXPORT void resizeForUnserialization(const std::vector& tinyInfo, DataArrayInt *a1, DataArrayDouble *a2, std::vector& littleStrings) const; - MEDCOUPLING_EXPORT void serialize(DataArrayInt *&a1, DataArrayDouble *&a2) const; - MEDCOUPLING_EXPORT void unserialization(const std::vector& tinyInfoD, const std::vector& tinyInfo, const DataArrayInt *a1, DataArrayDouble *a2, - const std::vector& littleStrings); - MEDCOUPLING_EXPORT void reprQuickOverview(std::ostream& stream) const; - MEDCOUPLING_EXPORT std::string getVTKFileExtension() const; - private: - MEDCouplingCMesh(); - MEDCouplingCMesh(const MEDCouplingCMesh& other, bool deepCpy); - ~MEDCouplingCMesh(); - void writeVTKLL(std::ostream& ofs, const std::string& cellData, const std::string& pointData, DataArrayByte *byteData) const; - std::string getVTKDataSetType() const; - private: - DataArrayDouble *_x_array; - DataArrayDouble *_y_array; - DataArrayDouble *_z_array; - }; -} - -#endif diff --git a/src/MEDCoupling/MEDCouplingCartesianAMRMesh.cxx b/src/MEDCoupling/MEDCouplingCartesianAMRMesh.cxx deleted file mode 100644 index cf8a37b37..000000000 --- a/src/MEDCoupling/MEDCouplingCartesianAMRMesh.cxx +++ /dev/null @@ -1,1978 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 -// 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 - -#include "MEDCouplingCartesianAMRMesh.hxx" -#include "MEDCouplingAMRAttribute.hxx" -#include "MEDCouplingFieldDouble.hxx" -#include "MEDCoupling1GTUMesh.hxx" -#include "MEDCouplingIMesh.hxx" -#include "MEDCouplingUMesh.hxx" - -#include -#include -#include - -using namespace ParaMEDMEM; - -/// @cond INTERNAL - -int MEDCouplingCartesianAMRPatchGen::getNumberOfCellsRecursiveWithOverlap() const -{ - return _mesh->getNumberOfCellsRecursiveWithOverlap(); -} - -int MEDCouplingCartesianAMRPatchGen::getNumberOfCellsRecursiveWithoutOverlap() const -{ - return _mesh->getNumberOfCellsRecursiveWithoutOverlap(); -} - -int MEDCouplingCartesianAMRPatchGen::getMaxNumberOfLevelsRelativeToThis() const -{ - return _mesh->getMaxNumberOfLevelsRelativeToThis(); -} - -MEDCouplingCartesianAMRPatchGen::MEDCouplingCartesianAMRPatchGen(MEDCouplingCartesianAMRMeshGen *mesh) -{ - if(!mesh) - throw INTERP_KERNEL::Exception("MEDCouplingCartesianAMRPatchGen constructor : input mesh is NULL !"); - _mesh=mesh; _mesh->incrRef(); -} - -MEDCouplingCartesianAMRPatchGen::MEDCouplingCartesianAMRPatchGen(const MEDCouplingCartesianAMRPatchGen& other, MEDCouplingCartesianAMRMeshGen *father):RefCountObject(other),_mesh(other._mesh) -{ - const MEDCouplingCartesianAMRMeshGen *mesh(other._mesh); - if(mesh) - _mesh=mesh->deepCpy(father); -} - -const MEDCouplingCartesianAMRMeshGen *MEDCouplingCartesianAMRPatchGen::getMeshSafe() const -{ - const MEDCouplingCartesianAMRMeshGen *mesh(_mesh); - if(!mesh) - throw INTERP_KERNEL::Exception("MEDCouplingCartesianAMRPatchGen::getMeshSafe const : the mesh is NULL !"); - return mesh; -} - -MEDCouplingCartesianAMRMeshGen *MEDCouplingCartesianAMRPatchGen::getMeshSafe() -{ - MEDCouplingCartesianAMRMeshGen *mesh(_mesh); - if(!mesh) - throw INTERP_KERNEL::Exception("MEDCouplingCartesianAMRPatchGen::getMeshSafe : the mesh is NULL !"); - return mesh; -} - -std::vector MEDCouplingCartesianAMRPatchGen::getDirectChildrenWithNull() const -{ - std::vector ret; - ret.push_back((const MEDCouplingCartesianAMRMeshGen *)_mesh); - return ret; -} - -/*! - * \param [in] mesh not null pointer of refined mesh replacing the cell range of \a father defined by the bottom left and top right just after. - * \param [in] bottomLeftTopRight a vector equal to the space dimension of \a mesh that specifies for each dimension, the included cell start of the range for the first element of the pair, - * a the end cell (\b excluded) of the range for the second element of the pair. - */ -MEDCouplingCartesianAMRPatch::MEDCouplingCartesianAMRPatch(MEDCouplingCartesianAMRMeshGen *mesh, const std::vector< std::pair >& bottomLeftTopRight):MEDCouplingCartesianAMRPatchGen(mesh),_bl_tr(bottomLeftTopRight) -{ - int dim((int)bottomLeftTopRight.size()),dimExp(_mesh->getSpaceDimension()); - if(dim!=dimExp) - throw INTERP_KERNEL::Exception("MEDCouplingCartesianAMRPatch constructor : space dimension of father and input bottomLeft/topRight size mismatches !"); -} - -MEDCouplingCartesianAMRPatch *MEDCouplingCartesianAMRPatch::deepCpy(MEDCouplingCartesianAMRMeshGen *father) const -{ - return new MEDCouplingCartesianAMRPatch(*this,father); -} - -void MEDCouplingCartesianAMRPatch::addPatch(const std::vector< std::pair >& bottomLeftTopRight, const std::vector& factors) -{ - return getMeshSafe()->addPatch(bottomLeftTopRight,factors); -} - -int MEDCouplingCartesianAMRPatch::getNumberOfOverlapedCellsForFather() const -{ - return MEDCouplingStructuredMesh::DeduceNumberOfGivenRangeInCompactFrmt(_bl_tr); -} - -/*! - * This method states if \a other patch is in the neighborhood of \a this. The neighborhood zone is defined by \a ghostLev parameter - * the must be >= 0. \b WARNING this method only works if \a this and \a other share the same father (no check of this will be done !). - * Call isInMyNeighborhoodExt to deal with 2 patches not sharing directly the same father. - * - * \param [in] other - The other patch - * \param [in] ghostLev - The size of the neighborhood zone. - * - * \throw if \a this or \a other are invalid (end before start). - * \throw if \a ghostLev is \b not >= 0 . - * \throw if \a this and \a other have not the same space dimension. - * - * \sa isInMyNeighborhoodExt - */ -bool MEDCouplingCartesianAMRPatch::isInMyNeighborhood(const MEDCouplingCartesianAMRPatch *other, int ghostLev) const -{ - if(ghostLev<0) - throw INTERP_KERNEL::Exception("MEDCouplingCartesianAMRPatch::isInMyNeighborhood : the size of the neighborhood must be >= 0 !"); - if(!other) - throw INTERP_KERNEL::Exception("MEDCouplingCartesianAMRPatch::isInMyNeighborhood : the input patch is NULL !"); - const std::vector< std::pair >& thisp(getBLTRRange()); - const std::vector< std::pair >& otherp(other->getBLTRRange()); - return IsInMyNeighborhood(ghostLev==0?0:1,thisp,otherp);//make hypothesis that nb this->_mesh->getFather->getFactors() is >= ghostLev -} - -/*! - * This method states if \a other patch is in the neighborhood of \a this. The neighborhood zone is defined by \a ghostLev parameter - * the must be >= 0. This method works even if \a this and \a other does not share the same father. But the level between their common - * ancestor must be the same. If they don't have the same ancestor an exception will be thrown. - * - * \param [in] other - The other patch - * \param [in] ghostLev - The size of the neighborhood zone. - * - * \throw if \a this or \a other are invalid (end before start). - * \throw if \a ghostLev is \b not >= 0 . - * \throw if \a this and \a other have not the same space dimension. - * \throw if there is not common ancestor of \a this and \a other. - * - * \sa isInMyNeighborhood, isInMyNeighborhoodDiffLev - */ -bool MEDCouplingCartesianAMRPatch::isInMyNeighborhoodExt(const MEDCouplingCartesianAMRPatch *other, int ghostLev) const -{ - if(ghostLev<0) - throw INTERP_KERNEL::Exception("MEDCouplingCartesianAMRPatch::isInMyNeighborhoodExt : the size of the neighborhood must be >= 0 !"); - if(!other) - throw INTERP_KERNEL::Exception("MEDCouplingCartesianAMRPatch::isInMyNeighborhoodExt : the input patch is NULL !"); - int lev; - const MEDCouplingCartesianAMRMeshGen *com(FindCommonAncestor(this,other,lev));//check that factors are OK - if(lev==0) - return isInMyNeighborhood(other,ghostLev); - std::vector offset(ComputeOffsetFromTwoToOne(com,lev,this,other)); - const std::vector< std::pair >& thisp(getBLTRRange()); - std::vector< std::pair > otherp(other->getBLTRRange()); - otherp=MEDCouplingStructuredMesh::TranslateCompactFrmt(otherp,offset); - return IsInMyNeighborhood(ghostLev,thisp,otherp); -} - -/*! - * This method states if \a other patch is in the neighborhood of \a this. The neighborhood zone is defined by \a ghostLev parameter - * the must be >= 0. This method works even if \a this and \a other does not share the same father. - * \a this is expected to be more refined than \a other. That is to say lev of \a this is greater than level of \a other. - * - * \param [in] other - The other patch - * \param [in] ghostLev - The size of the neighborhood zone. - * - * \throw if \a this or \a other are invalid (end before start). - * \throw if \a ghostLev is \b not >= 0 . - * \throw if \a this and \a other have not the same space dimension. - * \throw if there is not common ancestor of \a this and \a other. - * - * \sa isInMyNeighborhoodExt - */ -bool MEDCouplingCartesianAMRPatch::isInMyNeighborhoodDiffLev(const MEDCouplingCartesianAMRPatch *other, int ghostLev) const -{ - std::vector< std::pair > thispp,otherpp; - std::vector factors; - ComputeZonesOfTwoRelativeToOneDiffLev(ghostLev,this,other,thispp,otherpp,factors); - return IsInMyNeighborhood(ghostLev>0?1:0,thispp,otherpp);//1 not ghostLev ! It is not a bug ( I hope :) ) ! Because as \a this is a refinement of \a other ghostLev is supposed to be <= factors -} - -std::vector< std::pair > MEDCouplingCartesianAMRPatch::getBLTRRangeRelativeToGF() const -{ - std::vector< std::pair > ret(_bl_tr); - const MEDCouplingCartesianAMRMeshGen *mesh(getMesh()); - if(!mesh) - throw INTERP_KERNEL::Exception("MEDCouplingCartesianAMRPatch::getBLTRRangeRelativeToGF : not valid !"); - const MEDCouplingCartesianAMRMeshGen *fath(mesh->getFather()); - if(!fath) - throw INTERP_KERNEL::Exception("MEDCouplingCartesianAMRPatch::getBLTRRangeRelativeToGF : not valid 2 !"); - std::vector factors(fath->getFactors()); - std::size_t sz(ret.size()); - for(std::size_t ii=0;iigetFather(); - while(fath) - { - int pos(fath->getPatchIdFromChildMesh(oldFather)); - const MEDCouplingCartesianAMRPatch *p(fath->getPatch(pos)); - const std::vector< std::pair >& tmp(p->getBLTRRange()); - const std::vector& factors2(fath->getFactors()); - std::transform(factors.begin(),factors.end(),factors2.begin(),factors.begin(),std::multiplies()); - for(std::size_t ii=0;iigetFather(); - } - return ret; -} - -std::vector MEDCouplingCartesianAMRPatch::computeCellGridSt() const -{ - const MEDCouplingCartesianAMRMeshGen *m(getMesh()); - if(!m) - throw INTERP_KERNEL::Exception("MEDCouplingCartesianAMRPatch::computeCellGridSt : no mesh held by this !"); - const MEDCouplingCartesianAMRMeshGen *father(m->getFather()); - if(!father) - throw INTERP_KERNEL::Exception("MEDCouplingCartesianAMRPatch::computeCellGridSt : no father help by underlying mesh !"); - const std::vector< std::pair >& bltr(getBLTRRange()); - const std::vector& factors(father->getFactors()); - std::vector ret(MEDCouplingStructuredMesh::GetDimensionsFromCompactFrmt(bltr)); - std::transform(ret.begin(),ret.end(),factors.begin(),ret.begin(),std::multiplies()); - return ret; -} - -bool MEDCouplingCartesianAMRPatch::IsInMyNeighborhood(int ghostLev, const std::vector< std::pair >& p1, const std::vector< std::pair >& p2) -{ - std::size_t thispsize(p1.size()); - if(thispsize!=p2.size()) - throw INTERP_KERNEL::Exception("MEDCouplingCartesianAMRPatch::isInMyNeighborhood : the dimensions must be the same !"); - for(std::size_t i=0;i& thispp(p1[i]); - const std::pair& otherpp(p2[i]); - if(thispp.second > > MEDCouplingCartesianAMRPatch::FindNeighborsOfSubPatchesOfSameLev(int ghostLev, const MEDCouplingCartesianAMRPatch *p1, const MEDCouplingCartesianAMRPatch *p2) -{ - if(!p1 || !p2) - throw INTERP_KERNEL::Exception("MEDCouplingCartesianAMRPatch::FindNeighborsOfSubPatchesOfSameLev : the input pointers must be not NULL !"); - std::vector< std::vector< std::pair > > ret; - std::vector< const MEDCouplingCartesianAMRPatch *> p1Work(p1->getMesh()->getPatches()),p2Work(p2->getMesh()->getPatches()); - while(!p1Work.empty()) - { - std::vector< std::pair > retTmp; - std::vector p1Work2,p2Work2; - for(std::vector::const_iterator it1=p1Work.begin();it1!=p1Work.end();it1++) - { - for(std::vector::const_iterator it2=p2Work.begin();it2!=p2Work.end();it2++) - { - if((*it1)->isInMyNeighborhoodExt(*it2,ghostLev>0?1:0))//1 not ghostLev ! It is not a bug ( I hope :) ) ! Because as \a this is a refinement of \a other ghostLev is supposed to be <= factors - retTmp.push_back(std::pair(*it1,*it2)); - } - std::vector tmp1((*it1)->getMesh()->getPatches()); - p1Work2.insert(p1Work2.end(),tmp1.begin(),tmp1.end()); - } - for(std::vector::const_iterator it2=p2Work.begin();it2!=p2Work.end();it2++) - { - std::vector tmp2((*it2)->getMesh()->getPatches()); - p2Work2.insert(p2Work2.end(),tmp2.begin(),tmp2.end()); - } - ret.push_back(retTmp); - p1Work=p1Work2; - p2Work=p2Work2; - } - return ret; -} - -/*! - * This method returns all pair of patches (pa,pb) so that pb is in the neighborhood of pa (size of neighborhood is \a ghostLev). - * pa is a refinement (a child) of \b p1 and pb is equal to \a p2. So the returned pair do not have the same level as it is the case for - * FindNeighborsOfSubPatchesOfSameLev. - * - * \sa FindNeighborsOfSubPatchesOfSameLev - */ -void MEDCouplingCartesianAMRPatch::FindNeighborsOfSubPatchesOf(int ghostLev, const MEDCouplingCartesianAMRPatch *p1, const MEDCouplingCartesianAMRPatch *p2, std::vector< std::pair >& ret) -{ - if(!p1 || !p2) - throw INTERP_KERNEL::Exception("MEDCouplingCartesianAMRPatch::FindNeighborsOfSubPatchesOf : the input pointers must be not NULL !"); - std::vector< const MEDCouplingCartesianAMRPatch *> p1Work(p1->getMesh()->getPatches()); - while(!p1Work.empty()) - { - std::vector p1Work2; - for(std::vector::const_iterator it0=p1Work.begin();it0!=p1Work.end();it0++) - { - if((*it0)->isInMyNeighborhoodDiffLev(p2,ghostLev)) - ret.push_back(std::pair(*it0,p2)); - std::vector tmp2((*it0)->getMesh()->getPatches()); - p1Work2.insert(p1Work2.end(),tmp2.begin(),tmp2.end()); - } - p1Work=p1Work2; - } -} - -/*! - * \a p1 and \a p2 are expected to be neighbors (inside the \a ghostLev zone). This method updates \a dataOnP1 only in the ghost part using a part of \a dataOnP2. - * - * \saUpdateNeighborsOfOneWithTwoExt - */ -void MEDCouplingCartesianAMRPatch::UpdateNeighborsOfOneWithTwo(int ghostLev, const std::vector& factors, const MEDCouplingCartesianAMRPatch *p1, const MEDCouplingCartesianAMRPatch *p2, DataArrayDouble *dataOnP1, const DataArrayDouble *dataOnP2) -{ - const std::vector< std::pair >& p1BLTR(p1->getBLTRRange()); - const std::vector< std::pair >& p2BLTR(p2->getBLTRRange()); - UpdateNeighborsOfOneWithTwoInternal(ghostLev,factors,p1BLTR,p2BLTR,dataOnP1,dataOnP2); -} - -/*! - * Idem than UpdateNeighborsOfOneWithTwo, except that here \a p1 and \a p2 are not sharing the same direct father. - * - * \sa UpdateNeighborsOfOneWithTwo - */ -void MEDCouplingCartesianAMRPatch::UpdateNeighborsOfOneWithTwoExt(int ghostLev, const MEDCouplingCartesianAMRPatch *p1, const MEDCouplingCartesianAMRPatch *p2, DataArrayDouble *dataOnP1, const DataArrayDouble *dataOnP2) -{ - const std::vector< std::pair >& p1BLTR(p1->getBLTRRange());//p1BLTR=[(10,12),(5,8)] - std::vector< std::pair > p2BLTR(p2->getBLTRRange());//p2BLTR=[(0,1),(0,5)] - int lev(0); - const MEDCouplingCartesianAMRMeshGen *ca(FindCommonAncestor(p1,p2,lev)); - std::vector offset(ComputeOffsetFromTwoToOne(ca,lev,p1,p2));//[12,4] - p2BLTR=MEDCouplingStructuredMesh::TranslateCompactFrmt(p2BLTR,offset);//p2BLTR=[(12,13),(4,9)] - UpdateNeighborsOfOneWithTwoInternal(ghostLev,p1->getMesh()->getFather()->getFactors(),p1BLTR,p2BLTR,dataOnP1,dataOnP2); -} - -/*! - * \a p1 is expected to be more refined than \a p2. \a p1 and \a p2 have to share a common ancestor. Compared to UpdateNeighborsOfOneWithTwoExt here \a p1 and \a p2 are \b not at the same level ! - */ -void MEDCouplingCartesianAMRPatch::UpdateNeighborsOfOneWithTwoMixedLev(int ghostLev, const MEDCouplingCartesianAMRPatch *p1, const MEDCouplingCartesianAMRPatch *p2, DataArrayDouble *dataOnP1, const DataArrayDouble *dataOnP2, bool isConservative) -{ - std::vector< std::pair > p1pp,p2pp; - std::vector factors; - ComputeZonesOfTwoRelativeToOneDiffLev(ghostLev,p1,p2,p1pp,p2pp,factors); - // - std::vector dimsP2NotRefined(p2->computeCellGridSt()); - std::vector dimsP2Refined(dimsP2NotRefined); - std::transform(dimsP2NotRefined.begin(),dimsP2NotRefined.end(),factors.begin(),dimsP2Refined.begin(),std::multiplies()); - std::vector< std::pair > p2RefinedAbs(MEDCouplingStructuredMesh::GetCompactFrmtFromDimensions(dimsP2NotRefined)); - std::vector dimsP2RefinedGhost(dimsP2Refined.size()); - std::transform(dimsP2Refined.begin(),dimsP2Refined.end(),dimsP2RefinedGhost.begin(),std::bind2nd(std::plus(),2*ghostLev)); - MEDCouplingAutoRefCountObjectPtr fineP2(DataArrayDouble::New()); fineP2->alloc(MEDCouplingStructuredMesh::DeduceNumberOfGivenStructure(dimsP2RefinedGhost),dataOnP2->getNumberOfComponents()); - MEDCouplingIMesh::SpreadCoarseToFineGhost(dataOnP2,dimsP2NotRefined,fineP2,p2RefinedAbs,factors,ghostLev); - if(isConservative) - { - int fact(MEDCouplingStructuredMesh::DeduceNumberOfGivenStructure(factors)); - std::transform(fineP2->begin(),fineP2->end(),fineP2->getPointer(),std::bind2nd(std::multiplies(),1./((double)fact))); - } - // - UpdateNeighborsOfOneWithTwoInternal(ghostLev,p1->getMesh()->getFather()->getFactors(),p1pp,p2pp,dataOnP1,fineP2); -} - -/*! - * \a p1 is expected to be more refined than \a p2. \a p1 and \a p2 have to share a common ancestor. Compared to UpdateNeighborsOfOneWithTwoExt here \a p1 and \a p2 are \b not at the same level ! - * This method has 3 outputs. 2 two first are the resp the position of \a p1 and \a p2 relative to \a p1. And \a factToApplyOn2 is the coeff of refinement to be applied on \a p2 to be virtualy - * on the same level as \a p1. - */ -void MEDCouplingCartesianAMRPatch::ComputeZonesOfTwoRelativeToOneDiffLev(int ghostLev, const MEDCouplingCartesianAMRPatch *p1, const MEDCouplingCartesianAMRPatch *p2, std::vector< std::pair >& p1Zone, std::vector< std::pair >& p2Zone, std::vector& factToApplyOn2) -{ - std::vector ancestorsOfThis; - const MEDCouplingCartesianAMRMeshGen *work(p1->getMesh()),*work2(0); - ancestorsOfThis.push_back(work); - while(work) - { - work=work->getFather(); - if(work) - ancestorsOfThis.push_back(work); - } - // - work=p2->getMesh(); - bool found(false); - std::size_t levThis(0),levOther(0); - while(work && !found) - { - work2=work; - work=work->getFather(); - if(work) - { - levOther++; - std::vector::iterator it(std::find(ancestorsOfThis.begin(),ancestorsOfThis.end(),work)); - if(it!=ancestorsOfThis.end()) - { - levThis=std::distance(ancestorsOfThis.begin(),it); - found=true; - } - } - } - if(!found) - throw INTERP_KERNEL::Exception("MEDCouplingCartesianAMRPatch::ComputeZonesOfTwoRelativeToOneDiffLev : no common ancestor found !"); - if(levThis<=levOther) - throw INTERP_KERNEL::Exception("MEDCouplingCartesianAMRPatch::ComputeZonesOfTwoRelativeToOneDiffLev : this method is not called correctly !"); - // - const MEDCouplingCartesianAMRMeshGen *comAncestor(ancestorsOfThis[levThis]); - int idThis(comAncestor->getPatchIdFromChildMesh(ancestorsOfThis[levThis-1])),idOther(comAncestor->getPatchIdFromChildMesh(work2)); - const MEDCouplingCartesianAMRPatch *thisp(comAncestor->getPatch(idThis)),*otherp(comAncestor->getPatch(idOther)); - std::vector offset(ComputeOffsetFromTwoToOne(comAncestor,levOther,thisp,otherp)); - p1Zone=thisp->getBLTRRange(); p2Zone=MEDCouplingStructuredMesh::TranslateCompactFrmt(otherp->getBLTRRange(),offset); - factToApplyOn2.resize(p1Zone.size()); std::fill(factToApplyOn2.begin(),factToApplyOn2.end(),1); - // - std::size_t nbOfTurn(levThis-levOther); - for(std::size_t i=0;i > tmp0; - MEDCouplingStructuredMesh::ChangeReferenceFromGlobalOfCompactFrmt(p1Zone,p2Zone,tmp0,false); - p2Zone=tmp0; - const MEDCouplingCartesianAMRMeshGen *curAncestor(ancestorsOfThis[levThis-i]); - ApplyFactorsOnCompactFrmt(p2Zone,curAncestor->getFactors()); - curAncestor=ancestorsOfThis[levThis-1-i]; - const std::vector& factors(curAncestor->getFactors()); - std::transform(factToApplyOn2.begin(),factToApplyOn2.end(),factors.begin(),factToApplyOn2.begin(),std::multiplies()); - int tmpId(curAncestor->getPatchIdFromChildMesh(ancestorsOfThis[levThis-2-i])); - p1Zone=curAncestor->getPatch(tmpId)->getBLTRRange(); - } -} - -std::size_t MEDCouplingCartesianAMRPatch::getHeapMemorySizeWithoutChildren() const -{ - std::size_t ret(sizeof(MEDCouplingCartesianAMRPatch)); - ret+=_bl_tr.capacity()*sizeof(std::pair); - return ret; -} - -const MEDCouplingCartesianAMRMeshGen *MEDCouplingCartesianAMRPatch::FindCommonAncestor(const MEDCouplingCartesianAMRPatch *p1, const MEDCouplingCartesianAMRPatch *p2, int& lev) -{ - const MEDCouplingCartesianAMRMeshGen *f1(p1->_mesh),*f2(p2->_mesh); - lev=0; - while(f1!=f2 || f1==0 || f2==0) - { - f1=f1->getFather(); f2=f2->getFather(); - if(f1->getFactors()!=f2->getFactors()) - throw INTERP_KERNEL::Exception("MEDCouplingCartesianAMRPatch::FindCommonAncestor : factors differ !"); - lev++; - } - if(f1!=f2) - throw INTERP_KERNEL::Exception("MEDCouplingCartesianAMRPatch::FindCommonAncestor : no common ancestor between p1 and p2 !"); - return f1; -} - -std::vector MEDCouplingCartesianAMRPatch::ComputeOffsetFromTwoToOne(const MEDCouplingCartesianAMRMeshGen *comAncestor, int lev, const MEDCouplingCartesianAMRPatch *p1, const MEDCouplingCartesianAMRPatch *p2) -{ - if(lev<=0) - throw INTERP_KERNEL::Exception("MEDCouplingCartesianAMRPatch::ComputeOffsetFromTwoToOne : this method is useful only for lev > 0 !"); - int zeLev(lev-1); - int dim(p1->getMesh()->getSpaceDimension()); - if(p2->getMesh()->getSpaceDimension()!=dim) - throw INTERP_KERNEL::Exception("MEDCouplingCartesianAMRPatch::ComputeOffsetFromTwoToOne : dimension must be the same !"); - std::vector< int > ret(dim,0); - for(int i=0;i_mesh),*f2(p2->_mesh); - const MEDCouplingCartesianAMRPatch *p1h(0),*p2h(0); - for(int j=0;jgetFather()),*f2tmp(f2->getFather()); - int pid1(f1tmp->getPatchIdFromChildMesh(f1)),pid2(f2tmp->getPatchIdFromChildMesh(f2)); - p1h=f1tmp->getPatch(pid1); p2h=f2tmp->getPatch(pid2); - f1=f1tmp; f2=f2tmp; - } - std::vector< std::pair > p2c(p2h->getBLTRRange()); - for(int k=0;kgetBLTRRange()[k].first; - ret[k]*=f1->getFactors()[k]; - } - } - return ret; -} - -void MEDCouplingCartesianAMRPatch::UpdateNeighborsOfOneWithTwoInternal(int ghostLev, const std::vector& factors, const std::vector< std::pair >&p1 ,const std::vector< std::pair >&p2, DataArrayDouble *dataOnP1, const DataArrayDouble *dataOnP2) -{//p1=[(1,4),(2,4)] p2=[(4,5),(3,4)] - int dim((int)factors.size()); - std::vector dimsCoarse(MEDCouplingStructuredMesh::GetDimensionsFromCompactFrmt(p1));//[3,2] - std::transform(dimsCoarse.begin(),dimsCoarse.end(),factors.begin(),dimsCoarse.begin(),std::multiplies());//[12,8] - std::transform(dimsCoarse.begin(),dimsCoarse.end(),dimsCoarse.begin(),std::bind2nd(std::plus(),2*ghostLev));//[14,10] - std::vector< std::pair > rangeCoarse(MEDCouplingStructuredMesh::GetCompactFrmtFromDimensions(dimsCoarse));//[(0,14),(0,10)] - std::vector fakeFactors(dim,1); - // - std::vector< std::pair > tmp0,tmp1,tmp2; - MEDCouplingStructuredMesh::ChangeReferenceFromGlobalOfCompactFrmt(p1,p2,tmp0,false);//tmp0=[(3,4),(1,2)] - ApplyFactorsOnCompactFrmt(tmp0,factors);//tmp0=[(12,16),(4,8)] - MEDCouplingStructuredMesh::ApplyGhostOnCompactFrmt(tmp0,ghostLev);//tmp0=[(13,17),(5,9)] - std::vector< std::pair > interstRange(MEDCouplingStructuredMesh::IntersectRanges(tmp0,rangeCoarse));//interstRange=[(13,14),(5,9)] - MEDCouplingStructuredMesh::ChangeReferenceFromGlobalOfCompactFrmt(p2,p1,tmp1,false);//tmp1=[(-3,0),(-1,1)] - ApplyFactorsOnCompactFrmt(tmp1,factors);//tmp1=[(-12,-4),(-4,0)] - MEDCouplingStructuredMesh::ChangeReferenceToGlobalOfCompactFrmt(tmp1,interstRange,tmp2,false);//tmp2=[(1,2),(1,5)] - // - std::vector< std::pair > dimsFine(p2); - ApplyFactorsOnCompactFrmt(dimsFine,factors); - ApplyAllGhostOnCompactFrmt(dimsFine,ghostLev); - // - MEDCouplingAutoRefCountObjectPtr ghostVals(MEDCouplingStructuredMesh::ExtractFieldOfDoubleFrom(MEDCouplingStructuredMesh::GetDimensionsFromCompactFrmt(dimsFine),dataOnP2,tmp2)); - MEDCouplingIMesh::CondenseFineToCoarse(dimsCoarse,ghostVals,interstRange,fakeFactors,dataOnP1); -} - -MEDCouplingCartesianAMRPatch::MEDCouplingCartesianAMRPatch(const MEDCouplingCartesianAMRPatch& other, MEDCouplingCartesianAMRMeshGen *father):MEDCouplingCartesianAMRPatchGen(other,father),_bl_tr(other._bl_tr) -{ -} - -/*! - * \param [in,out] partBeforeFact - the part of a image mesh in compact format that will be put in refined reference. - * \param [in] factors - the factors per axis. - */ -void MEDCouplingCartesianAMRPatch::ApplyFactorsOnCompactFrmt(std::vector< std::pair >& partBeforeFact, const std::vector& factors) -{ - std::size_t sz(factors.size()); - if(sz!=partBeforeFact.size()) - throw INTERP_KERNEL::Exception("MEDCouplingCartesianAMRPatch::ApplyFactorsOnCompactFrmt : size of input vectors must be the same !"); - for(std::size_t i=0;i >& partBeforeFact, int ghostSize) -{ - if(ghostSize<0) - throw INTERP_KERNEL::Exception("MEDCouplingCartesianAMRPatch::ApplyAllGhostOnCompactFrmt : ghost size must be >= 0 !"); - std::size_t sz(partBeforeFact.size()); - for(std::size_t i=0;igetSpaceDimension(); -} - -void MEDCouplingCartesianAMRMeshGen::setFactors(const std::vector& newFactors) -{ - if(getSpaceDimension()!=(int)newFactors.size()) - throw INTERP_KERNEL::Exception("MEDCouplingCartesianAMRMeshGen::setFactors : size of input factors is not equal to the space dimension !"); - if(_factors.empty()) - { - _factors=newFactors; - return ; - } - if(_factors==newFactors) - return ; - if(!_patches.empty()) - throw INTERP_KERNEL::Exception("MEDCouplingCartesianAMRMeshGen::setFactors : modification of factors is not allowed when presence of patches !"); - _factors=newFactors; - declareAsNew(); -} - -int MEDCouplingCartesianAMRMeshGen::getMaxNumberOfLevelsRelativeToThis() const -{ - int ret(1); - for(std::vector< MEDCouplingAutoRefCountObjectPtr >::const_iterator it=_patches.begin();it!=_patches.end();it++) - ret=std::max(ret,(*it)->getMaxNumberOfLevelsRelativeToThis()+1); - return ret; -} - -/*! - * This method returns the number of cells of \a this with the help of the MEDCouplingIMesh instance representing \a this. - * The patches in \a this are ignored here. - * \sa getNumberOfCellsAtCurrentLevelGhost, getNumberOfCellsRecursiveWithOverlap - */ -int MEDCouplingCartesianAMRMeshGen::getNumberOfCellsAtCurrentLevel() const -{ - return _mesh->getNumberOfCells(); -} - -/*! - * This method returns the number of cells of \a this with the help of the MEDCouplingIMesh instance representing \a this enlarged by \a ghostLev size - * to take into account of the ghost cells for future computation. - * The patches in \a this are ignored here. - * - * \sa getNumberOfCellsAtCurrentLevel - */ -int MEDCouplingCartesianAMRMeshGen::getNumberOfCellsAtCurrentLevelGhost(int ghostLev) const -{ - MEDCouplingAutoRefCountObjectPtr tmp(_mesh->buildWithGhost(ghostLev)); - return tmp->getNumberOfCells(); -} - -/*! - * This method returns the number of cells including the current level but \b also \b including recursively all cells of other levels - * starting from this. The set of cells which size is returned here are generally overlapping each other. - */ -int MEDCouplingCartesianAMRMeshGen::getNumberOfCellsRecursiveWithOverlap() const -{ - int ret(_mesh->getNumberOfCells()); - for(std::vector< MEDCouplingAutoRefCountObjectPtr >::const_iterator it=_patches.begin();it!=_patches.end();it++) - { - ret+=(*it)->getNumberOfCellsRecursiveWithOverlap(); - } - return ret; -} - -/*! - * This method returns the max number of cells covering all the space without overlapping. - * It returns the number of cells of the mesh with the highest resolution. - * The returned value is equal to the number of cells of mesh returned by buildUnstructured. - * - * \sa buildUnstructured - */ -int MEDCouplingCartesianAMRMeshGen::getNumberOfCellsRecursiveWithoutOverlap() const -{ - int ret(_mesh->getNumberOfCells()); - for(std::vector< MEDCouplingAutoRefCountObjectPtr >::const_iterator it=_patches.begin();it!=_patches.end();it++) - { - ret-=(*it)->getNumberOfOverlapedCellsForFather(); - ret+=(*it)->getNumberOfCellsRecursiveWithoutOverlap(); - } - return ret; -} - -/*! - * This method returns a vector of size equal to getAbsoluteLevelRelativeTo. It allows to find position an absolute position of \a this - * relative to \a ref (that is typically the god father). - * - * \sa getPatchAtPosition - */ -std::vector MEDCouplingCartesianAMRMeshGen::getPositionRelativeTo(const MEDCouplingCartesianAMRMeshGen *ref) const -{ - if(!ref) - throw INTERP_KERNEL::Exception("MEDCouplingCartesianAMRMeshGen::getPositionRelativeTo : input pointer is NULL !"); - std::vector ret; - getPositionRelativeToInternal(ref,ret); - std::reverse(ret.begin(),ret.end()); - return ret; -} - -/*! - * \sa getPositionRelativeTo, getMeshAtPosition - */ -const MEDCouplingCartesianAMRPatch *MEDCouplingCartesianAMRMeshGen::getPatchAtPosition(const std::vector& pos) const -{ - std::size_t sz(pos.size()); - if(sz==0) - throw INTERP_KERNEL::Exception("MEDCouplingCartesianAMRMeshGen::getPatchAtPosition : empty input -> no patch by definition !"); - int patchId(pos[0]); - const MEDCouplingCartesianAMRPatch *elt(getPatch(patchId)); - if(sz==1) - return elt; - if(!elt || !elt->getMesh()) - throw INTERP_KERNEL::Exception("MEDCouplingCartesianAMRMeshGen::getPatchAtPosition : NULL element found during walk !"); - std::vector pos2(pos.begin()+1,pos.end()); - return elt->getMesh()->getPatchAtPosition(pos2); -} - -const MEDCouplingCartesianAMRMeshGen *MEDCouplingCartesianAMRMeshGen::getMeshAtPosition(const std::vector& pos) const -{ - std::size_t sz(pos.size()); - if(sz==0) - return this; - int patchId(pos[0]); - const MEDCouplingCartesianAMRPatch *elt(getPatch(patchId)); - if(sz==1) - { - if(!elt) - throw INTERP_KERNEL::Exception("MEDCouplingCartesianAMRMeshGen::getMeshAtPosition : NULL patch !"); - return elt->getMesh(); - } - if(!elt || !elt->getMesh()) - throw INTERP_KERNEL::Exception("MEDCouplingCartesianAMRMeshGen::getPatchAtPosition : NULL element found during walk !"); - std::vector pos2(pos.begin()+1,pos.end()); - return elt->getMesh()->getMeshAtPosition(pos2); -} - -/*! - * This method returns grids relative to god father to specified level \a absoluteLev. - * - * \return std::vector - objects in vector are to be managed (decrRef) by the caller. - */ -std::vector MEDCouplingCartesianAMRMeshGen::retrieveGridsAt(int absoluteLev) const -{ - if(absoluteLev<0) - throw INTERP_KERNEL::Exception("MEDCouplingCartesianAMRMesh::retrieveGridsAt : absolute level must be >=0 !"); - return getGodFather()->retrieveGridsAt(absoluteLev); -} - -/*! - * \param [in] bottomLeftTopRight a vector equal to the space dimension of \a mesh that specifies for each dimension, the included cell start of the range for the first element of the pair, - * a the end cell (\b excluded) of the range for the second element of the pair. - * \param [in] factors The factor of refinement per axis (different from 0). - */ -void MEDCouplingCartesianAMRMeshGen::addPatch(const std::vector< std::pair >& bottomLeftTopRight, const std::vector& factors) -{ - checkFactorsAndIfNotSetAssign(factors); - MEDCouplingAutoRefCountObjectPtr mesh(static_cast(_mesh->buildStructuredSubPart(bottomLeftTopRight))); - mesh->refineWithFactor(factors); - MEDCouplingAutoRefCountObjectPtr zeMesh(new MEDCouplingCartesianAMRMeshSub(this,mesh)); - MEDCouplingAutoRefCountObjectPtr elt(new MEDCouplingCartesianAMRPatch(zeMesh,bottomLeftTopRight)); - _patches.push_back(elt); - declareAsNew(); -} - -/// @cond INTERNAL - -class InternalPatch : public RefCountObjectOnly -{ -public: - InternalPatch():_nb_of_true(0) { } - int getDimension() const { return (int)_part.size(); } - double getEfficiency() const { return (double)_nb_of_true/(double)_crit.size(); } - int getNumberOfCells() const { return (int)_crit.size(); } - void setNumberOfTrue(int nboft) { _nb_of_true=nboft; } - std::vector& getCriterion() { return _crit; } - const std::vector& getConstCriterion() const { return _crit; } - void setPart(const std::vector< std::pair >& part) { _part=part; } - std::vector< std::pair >& getPart() { return _part; } - const std::vector< std::pair >& getConstPart() const { return _part; } - bool presenceOfTrue() const { return _nb_of_true>0; } - std::vector computeCGS() const { return MEDCouplingStructuredMesh::GetDimensionsFromCompactFrmt(_part); } - std::vector< std::vector > computeSignature() const { return MEDCouplingStructuredMesh::ComputeSignaturePerAxisOf(computeCGS(),getConstCriterion()); } - double getEfficiencyPerAxis(int axisId) const { return (double)_nb_of_true/((double)(_part[axisId].second-_part[axisId].first)); } - void zipToFitOnCriterion(int minPatchLgth); - void updateNumberOfTrue() const; - MEDCouplingAutoRefCountObjectPtr extractPart(const std::vector< std::pair >&partInGlobal) const; - MEDCouplingAutoRefCountObjectPtr deepCpy() const; -protected: - ~InternalPatch() { } -private: - mutable int _nb_of_true; - std::vector _crit; - //! _part is global - std::vector< std::pair > _part; -}; - -void InternalPatch::zipToFitOnCriterion(int minPatchLgth) -{ - std::vector cgs(computeCGS()); - std::vector newCrit; - std::vector< std::pair > newPart,newPart2; - int newNbOfTrue(MEDCouplingStructuredMesh::FindMinimalPartOf(minPatchLgth,cgs,_crit,newCrit,newPart)); - MEDCouplingStructuredMesh::ChangeReferenceToGlobalOfCompactFrmt(_part,newPart,newPart2); - if(newNbOfTrue!=_nb_of_true) - throw INTERP_KERNEL::Exception("InternalPatch::zipToFitOnCrit : internal error !"); - _crit=newCrit; _part=newPart2; -} - -void InternalPatch::updateNumberOfTrue() const -{ - _nb_of_true=(int)std::count(_crit.begin(),_crit.end(),true); -} - -MEDCouplingAutoRefCountObjectPtr InternalPatch::extractPart(const std::vector< std::pair >&partInGlobal) const -{ - MEDCouplingAutoRefCountObjectPtr ret(new InternalPatch); - std::vector cgs(computeCGS()); - std::vector< std::pair > newPart; - MEDCouplingStructuredMesh::ChangeReferenceFromGlobalOfCompactFrmt(_part,partInGlobal,newPart); - MEDCouplingStructuredMesh::ExtractFieldOfBoolFrom(cgs,_crit,newPart,ret->getCriterion()); - ret->setPart(partInGlobal); - ret->updateNumberOfTrue(); - return ret; -} - -MEDCouplingAutoRefCountObjectPtr InternalPatch::deepCpy() const -{ - MEDCouplingAutoRefCountObjectPtr ret(new InternalPatch); - (*ret)=*this; - return ret; -} - -void DissectBigPatch(const INTERP_KERNEL::BoxSplittingOptions& bso, const InternalPatch *patchToBeSplit, int axisId, int largestLength, int& cutPlace) -{ - int minimumPatchLength(bso.getMinimumPatchLength()); - std::vector ratio(largestLength-minimumPatchLength,std::numeric_limits::max()); - int index_min = -1; - double minSemiEfficiencyRatio(std::numeric_limits::max()); - double efficiencyPerAxis[2]; - - for(int i=minimumPatchLength-1;i > rectH(patchToBeSplit->getConstPart()); - if(h==0) - rectH[axisId].second=patchToBeSplit->getConstPart()[axisId].first+i; - else - rectH[axisId].first=patchToBeSplit->getConstPart()[axisId].first+i; - MEDCouplingAutoRefCountObjectPtr p(patchToBeSplit->deepCpy()); - p->zipToFitOnCriterion(bso.getMinimumPatchLength()); - efficiencyPerAxis[h]=p->getEfficiencyPerAxis(axisId); - } - ratio[i]=std::max(efficiencyPerAxis[0], efficiencyPerAxis[1]) / std::min(efficiencyPerAxis[0], efficiencyPerAxis[1]); - if(ratio[i]getConstPart()[axisId].first; -} - -bool FindHole(const INTERP_KERNEL::BoxSplittingOptions& bso, const InternalPatch *patchToBeSplit, int axisId, int& cutPlace) -{ - cutPlace=-1; - int minimumPatchLength(bso.getMinimumPatchLength()); - const int dim(patchToBeSplit->getDimension()); - std::vector< std::vector > signatures(patchToBeSplit->computeSignature()); - for(int id=0;id& signature(signatures[id]); - std::vector hole; - std::vector distance; - int len((int)signature.size()); - for(int i=minimumPatchLength-1;igetConstPart()[axisId].first; - return true; - } - } - return false; -} - -bool FindInflection(const INTERP_KERNEL::BoxSplittingOptions& bso, const InternalPatch *patchToBeSplit, int& cutPlace, int& axisId) -{ - bool cutFound(false); cutPlace=-1;// do not set axisId before to be sure that cutFound was set to true - const std::vector< std::pair >& part(patchToBeSplit->getConstPart()); - int sign,minimumPatchLength(bso.getMinimumPatchLength()); - const int dim(patchToBeSplit->getDimension()); - - std::vector zeroCrossDims(dim,-1); - std::vector zeroCrossVals(dim,-1); - std::vector< std::vector > signatures(patchToBeSplit->computeSignature()); - for (int id=0;id& signature(signatures[id]); - - std::vector derivate_second_order,gradient_absolute,zero_cross,edge,max_cross_list ; - std::vector distance ; - - for(std::size_t i=1;i 0 ) - sign = 1 ; - if (derivate_second_order[i]*derivate_second_order[i+1] == 0 ) - sign = 0 ; - if ( sign==0 || sign==-1 ) - if ( i >= (std::size_t)minimumPatchLength-2 && i <= signature.size()-minimumPatchLength-2 ) - { - zero_cross.push_back(i) ; - edge.push_back(gradient_absolute[i]) ; - } - } - if ( zero_cross.size() > 0 ) - { - int max_cross=*max_element(edge.begin(),edge.end()) ; - for (unsigned int i=0;i=0 ) - { - zeroCrossDims[id] = best_place ; - zeroCrossVals[id] = max_cross ; - } - } - derivate_second_order.clear() ; - gradient_absolute.clear() ; - zero_cross.clear() ; - edge.clear() ; - max_cross_list.clear() ; - distance.clear() ; - } - - if ( zeroCrossDims[0]!=-1 || zeroCrossDims[1]!=-1 ) - { - int max_cross_dims = *max_element(zeroCrossVals.begin(),zeroCrossVals.end()) ; - - if (zeroCrossVals[0]==max_cross_dims && zeroCrossVals[1]==max_cross_dims ) - { - int nl_left(part[0].second-part[0].first); - int nc_left(part[1].second-part[1].first); - if ( nl_left >= nc_left ) - max_cross_dims = 0 ; - else - max_cross_dims = 1 ; - } - else - max_cross_dims=std::find(zeroCrossVals.begin(),zeroCrossVals.end(),max_cross_dims)-zeroCrossVals.begin(); - cutFound=true; - cutPlace=zeroCrossDims[max_cross_dims]; - axisId=max_cross_dims ; - } - return cutFound; -} - -bool TryAction4(const INTERP_KERNEL::BoxSplittingOptions& bso, const InternalPatch *patchToBeSplit, int axisId, int rangeOfAxisId, int& cutPlace) -{ - if(patchToBeSplit->getEfficiency()<=bso.getEfficiencyGoal()) - { - if(rangeOfAxisId>=2*bso.getMinimumPatchLength()) - { - cutPlace=rangeOfAxisId/2+patchToBeSplit->getConstPart()[axisId].first-1; - } - else - return false; - } - else - { - if(patchToBeSplit->getNumberOfCells()>bso.getMaximumNbOfCellsInPatch() || rangeOfAxisId>bso.getMaximumPatchLength()) - { - DissectBigPatch(bso,patchToBeSplit,axisId,rangeOfAxisId,cutPlace); - } - else - return false; - } - return true; -} - -MEDCouplingAutoRefCountObjectPtr DealWithNoCut(const InternalPatch *patch) -{ - MEDCouplingAutoRefCountObjectPtr ret(const_cast(patch)); - ret->incrRef(); - return ret; -} - -void DealWithCut(double minPatchLgth, const InternalPatch *patchToBeSplit, int axisId, int cutPlace, std::vector >& listOfPatches) -{ - MEDCouplingAutoRefCountObjectPtr leftPart,rightPart; - std::vector< std::pair > rect(patchToBeSplit->getConstPart()); - std::vector< std::pair > leftRect(rect),rightRect(rect); - leftRect[axisId].second=cutPlace+1; - rightRect[axisId].first=cutPlace+1; - leftPart=patchToBeSplit->extractPart(leftRect); - rightPart=patchToBeSplit->extractPart(rightRect); - leftPart->zipToFitOnCriterion(minPatchLgth); rightPart->zipToFitOnCriterion(minPatchLgth); - listOfPatches.push_back(leftPart); - listOfPatches.push_back(rightPart); -} - -/// @endcond - -void MEDCouplingCartesianAMRMeshGen::removeAllPatches() -{ - _patches.clear(); - declareAsNew(); -} - -void MEDCouplingCartesianAMRMeshGen::removePatch(int patchId) -{ - checkPatchId(patchId); - int sz((int)_patches.size()),j(0); - std::vector< MEDCouplingAutoRefCountObjectPtr > patches(sz-1); - for(int i=0;i(_patches[patchId]->getMesh()))->detachFromFather(); - _patches=patches; - declareAsNew(); -} - -int MEDCouplingCartesianAMRMeshGen::getNumberOfPatches() const -{ - return (int)_patches.size(); -} - -/*! - * This method is a generic algorithm to create patches in \a this (by destroying the patches if any). - * This method uses \a criterion array as a field on cells on this level. - * This method only create patches at level 0 relative to \a this. - * - * This generic algorithm can be degenerated into three child ones, depending on the arguments given; in particular depending - * on whether they are equal to 0 or not. - * 1/ If minimumPatchLength = maximumPatchLength = maximumPatchVolume = 0, then we have the Berger-Rigoutsos algorithm. - * This algorithm was developed in 1991 and seems appropriate for sequential programming. - * 2/ If maximumPatchLength = 0, then we have the Livne algorithm. - * This algorithm was developed in 2004 and is an improvement of the Berger-Rigoutsos algorithm. - * 3/ If maximumPatchVolume = 0, the we have the lmin-lmax algorithm. - * This algorithm was developed by Arthur TALPAERT in 2014 and is an improvement of the Livne algorithm. It is especially - * appropriate for parallel computing, where one patch would be given to one CPU. See Arthur TALPAERT's 2014 CANUM poster - * for more information. - * - */ -void MEDCouplingCartesianAMRMeshGen::createPatchesFromCriterion(const INTERP_KERNEL::BoxSplittingOptions& bso, const std::vector& criterion, const std::vector& factors) -{ - int nbCells(getNumberOfCellsAtCurrentLevel()); - if(nbCells!=(int)criterion.size()) - throw INTERP_KERNEL::Exception("MEDCouplingCartesianAMRMeshGen::createPatchesFromCriterion : the number of tuples of criterion array must be equal to the number of cells at the current level !"); - _patches.clear(); - std::vector cgs(_mesh->getCellGridStructure()); - std::vector< MEDCouplingAutoRefCountObjectPtr > listOfPatches,listOfPatchesOK; - // - MEDCouplingAutoRefCountObjectPtr p(new InternalPatch); - p->setNumberOfTrue(MEDCouplingStructuredMesh::FindMinimalPartOf(bso.getMinimumPatchLength(),cgs,criterion,p->getCriterion(),p->getPart())); - if(p->presenceOfTrue()) - listOfPatches.push_back(p); - while(!listOfPatches.empty()) - { - std::vector< MEDCouplingAutoRefCountObjectPtr > listOfPatchesTmp; - for(std::vector< MEDCouplingAutoRefCountObjectPtr >::iterator it=listOfPatches.begin();it!=listOfPatches.end();it++) - { - // - int axisId,largestLength,cutPlace; - MEDCouplingStructuredMesh::FindTheWidestAxisOfGivenRangeInCompactFrmt((*it)->getConstPart(),axisId,largestLength); - if((*it)->getEfficiency()>=bso.getEfficiencyThreshold() && ((*it)->getNumberOfCells()>bso.getMaximumNbOfCellsInPatch() || largestLength>bso.getMaximumPatchLength())) - { - DissectBigPatch(bso,*it,axisId,largestLength,cutPlace); - DealWithCut(bso.getMinimumPatchLength(),*it,axisId,cutPlace,listOfPatchesTmp); - continue; - }//action 1 - if(FindHole(bso,*it,axisId,cutPlace))//axisId overwritten here if FindHole equal to true ! - { DealWithCut(bso.getMinimumPatchLength(),*it,axisId,cutPlace,listOfPatchesTmp); continue; }//action 2 - if(FindInflection(bso,*it,cutPlace,axisId))//axisId overwritten here if cutFound equal to true ! - { DealWithCut(bso.getMinimumPatchLength(),*it,axisId,cutPlace,listOfPatchesTmp); continue; }//action 3 - if(TryAction4(bso,*it,axisId,largestLength,cutPlace)) - { DealWithCut(bso.getMinimumPatchLength(),*it,axisId,cutPlace,listOfPatchesTmp); continue; }//action 4 - else - listOfPatchesOK.push_back(DealWithNoCut(*it)); - } - listOfPatches=listOfPatchesTmp; - } - for(std::vector< MEDCouplingAutoRefCountObjectPtr >::const_iterator it=listOfPatchesOK.begin();it!=listOfPatchesOK.end();it++) - addPatch((*it)->getConstPart(),factors); - declareAsNew(); -} - -/*! - * This method creates patches in \a this (by destroying the patches if any). This method uses \a criterion array as a field on cells on this level. - * This method only create patches at level 0 relative to \a this. - */ -void MEDCouplingCartesianAMRMeshGen::createPatchesFromCriterion(const INTERP_KERNEL::BoxSplittingOptions& bso, const DataArrayByte *criterion, const std::vector& factors) -{ - if(!criterion || !criterion->isAllocated()) - throw INTERP_KERNEL::Exception("MEDCouplingCartesianAMRMeshGen::createPatchesFromCriterion : the criterion DataArrayByte instance must be allocated and not NULL !"); - std::vector crit(criterion->toVectorOfBool());//check that criterion has one component. - createPatchesFromCriterion(bso,crit,factors); - declareAsNew(); -} - -void MEDCouplingCartesianAMRMeshGen::createPatchesFromCriterion(const INTERP_KERNEL::BoxSplittingOptions& bso, const DataArrayDouble *criterion, const std::vector& factors, double eps) -{ - if(!criterion) - throw INTERP_KERNEL::Exception("MEDCouplingCartesianAMRMeshGen::createPatchesFromCriterion : null criterion pointer !"); - std::vector inp(criterion->toVectorOfBool(eps)); - createPatchesFromCriterion(bso,inp,factors); -} - -int MEDCouplingCartesianAMRMeshGen::getPatchIdFromChildMesh(const MEDCouplingCartesianAMRMeshGen *mesh) const -{ - int ret(0); - for(std::vector< MEDCouplingAutoRefCountObjectPtr >::const_iterator it=_patches.begin();it!=_patches.end();it++,ret++) - { - if((*it)->getMesh()==mesh) - return ret; - } - throw INTERP_KERNEL::Exception("MEDCouplingCartesianAMRMeshGen::getPatchIdFromChildMesh : no such a mesh in my direct progeny !"); -} - -std::vector< const MEDCouplingCartesianAMRPatch *> MEDCouplingCartesianAMRMeshGen::getPatches() const -{ - std::size_t sz(_patches.size()); - std::vector< const MEDCouplingCartesianAMRPatch *> ret(sz); - for(std::size_t i=0;iisInMyNeighborhood(p2,ghostLev); -} - -/*! - * This method creates a new cell field array on given \a patchId patch in \a this starting from a coarse cell field on \a this \a cellFieldOnThis. - * This method can be seen as a fast projection from the cell field \a cellFieldOnThis on \c this->getImageMesh() to a refined part of \a this - * defined by the patch with id \a patchId. - * - * \param [in] patchId - The id of the patch \a cellFieldOnThis has to be put on. - * \param [in] cellFieldOnThis - The array of the cell field on \c this->getImageMesh() to be projected to patch having id \a patchId. - * \return DataArrayDouble * - The array of the cell field on the requested patch - * - * \throw if \a patchId is not in [ 0 , \c this->getNumberOfPatches() ) - * \throw if \a cellFieldOnThis is NULL or not allocated - * \sa fillCellFieldOnPatch, MEDCouplingIMesh::SpreadCoarseToFine - */ -DataArrayDouble *MEDCouplingCartesianAMRMeshGen::createCellFieldOnPatch(int patchId, const DataArrayDouble *cellFieldOnThis) const -{ - if(!cellFieldOnThis || !cellFieldOnThis->isAllocated()) - throw INTERP_KERNEL::Exception("MEDCouplingCartesianAMRMesh::createCellFieldOnPatch : the input cell field array is NULL or not allocated !"); - const MEDCouplingCartesianAMRPatch *patch(getPatch(patchId)); - const MEDCouplingIMesh *fine(patch->getMesh()->getImageMesh()); - MEDCouplingAutoRefCountObjectPtr ret(DataArrayDouble::New()); ret->alloc(fine->getNumberOfCells(),cellFieldOnThis->getNumberOfComponents()); - ret->copyStringInfoFrom(*cellFieldOnThis); - MEDCouplingIMesh::SpreadCoarseToFine(cellFieldOnThis,_mesh->getCellGridStructure(),ret,patch->getBLTRRange(),getFactors()); - return ret.retn(); -} - -/*! - * This method is equivalent to MEDCouplingCartesianAMRMesh::createCellFieldOnPatch except that here instead of creating a new instance - * it fills the value into the \a cellFieldOnPatch data. - * - * \param [in] patchId - The id of the patch \a cellFieldOnThis has to be put on. - * \param [in] cellFieldOnThis - The array of the cell field on \c this->getImageMesh() to be projected to patch having id \a patchId. - * \param [in,out] cellFieldOnPatch - The array of the cell field on the requested patch to be filled. - * - * \sa createCellFieldOnPatch, fillCellFieldComingFromPatch - */ -void MEDCouplingCartesianAMRMeshGen::fillCellFieldOnPatch(int patchId, const DataArrayDouble *cellFieldOnThis, DataArrayDouble *cellFieldOnPatch, bool isConservative) const -{ - if(!cellFieldOnThis || !cellFieldOnThis->isAllocated()) - throw INTERP_KERNEL::Exception("MEDCouplingCartesianAMRMesh::createCellFieldOnPatch : the input cell field array is NULL or not allocated !"); - const MEDCouplingCartesianAMRPatch *patch(getPatch(patchId)); - MEDCouplingIMesh::SpreadCoarseToFine(cellFieldOnThis,_mesh->getCellGridStructure(),cellFieldOnPatch,patch->getBLTRRange(),getFactors()); - if(isConservative) - { - int fact(MEDCouplingStructuredMesh::DeduceNumberOfGivenStructure(getFactors())); - std::transform(cellFieldOnPatch->begin(),cellFieldOnPatch->end(),cellFieldOnPatch->getPointer(),std::bind2nd(std::multiplies(),1./((double)fact))); - } -} - -/*! - * This method is the generalization of fillCellFieldOnPatch method. This method only projects coarse to fine without considering the - * potential neighbor patches covered by the ghost cells of patch with id \a patchId. - * - * \param [in] patchId - The id of the patch \a cellFieldOnThis has to be put on. - * \param [in] cellFieldOnThis - The array of the cell field on \c this->getImageMesh() to be projected to patch having id \a patchId. - * \param [in,out] cellFieldOnPatch - The array of the cell field on the requested patch to be filled. - * \param [in] ghostLev - The size of the ghost zone (must be >=0 !) - * - * \sa fillCellFieldOnPatch, fillCellFieldOnPatchGhostAdv - */ -void MEDCouplingCartesianAMRMeshGen::fillCellFieldOnPatchGhost(int patchId, const DataArrayDouble *cellFieldOnThis, DataArrayDouble *cellFieldOnPatch, int ghostLev, bool isConservative) const -{ - if(!cellFieldOnThis || !cellFieldOnThis->isAllocated()) - throw INTERP_KERNEL::Exception("MEDCouplingCartesianAMRMesh::createCellFieldOnPatchGhost : the input cell field array is NULL or not allocated !"); - const MEDCouplingCartesianAMRPatch *patch(getPatch(patchId)); - MEDCouplingIMesh::SpreadCoarseToFineGhost(cellFieldOnThis,_mesh->getCellGridStructure(),cellFieldOnPatch,patch->getBLTRRange(),getFactors(),ghostLev); - if(isConservative) - { - int fact(MEDCouplingStructuredMesh::DeduceNumberOfGivenStructure(getFactors())); - std::transform(cellFieldOnPatch->begin(),cellFieldOnPatch->end(),cellFieldOnPatch->getPointer(),std::bind2nd(std::multiplies(),1./((double)fact))); - } -} - -/*! - * This method is equivalent to fillCellFieldOnPatchGhost except that here \b ONLY \b the \b ghost \b zone will be updated - * in \a cellFieldOnPatch. - * - * \param [in] patchId - The id of the patch \a cellFieldOnThis has to be put on. - * \param [in] cellFieldOnThis - The array of the cell field on \c this->getImageMesh() to be projected to patch having id \a patchId. - * \param [in,out] cellFieldOnPatch - The array of the cell field on the requested patch to be filled \b only \b in \b the \b ghost \b zone. - * \param [in] ghostLev - The size of the ghost zone (must be >=0 !) - */ -void MEDCouplingCartesianAMRMeshGen::fillCellFieldOnPatchOnlyOnGhostZone(int patchId, const DataArrayDouble *cellFieldOnThis, DataArrayDouble *cellFieldOnPatch, int ghostLev) const -{ - if(!cellFieldOnThis || !cellFieldOnThis->isAllocated()) - throw INTERP_KERNEL::Exception("MEDCouplingCartesianAMRMesh::fillCellFieldOnPatchOnlyOnGhostZone : the input cell field array is NULL or not allocated !"); - const MEDCouplingCartesianAMRPatch *patch(getPatch(patchId)); - MEDCouplingIMesh::SpreadCoarseToFineGhostZone(cellFieldOnThis,_mesh->getCellGridStructure(),cellFieldOnPatch,patch->getBLTRRange(),getFactors(),ghostLev); -} - -/*! - * This method is a refinement of fillCellFieldOnPatchGhost. fillCellFieldOnPatchGhost is first called. - * Then for all other patches than those pointed by \a patchId that overlap the ghost zone of the patch impact the ghost zone adequately. - * - * \param [in] patchId - The id of the patch \a cellFieldOnThis has to be put on. - * \param [in] cellFieldOnThis - The array of the cell field on \c this->getImageMesh() to be projected to patch having id \a patchId. - * \param [in,out] cellFieldOnPatch - The array of the cell field on the requested patch to be filled. - * \param [in] ghostLev - The size of the ghost zone (must be >=0 !) - * \param [in] arrsOnPatches - \b WARNING arrsOnPatches[patchId] is \b NOT \b const. All others are const. - * - * \sa fillCellFieldOnPatchOnlyGhostAdv - */ -void MEDCouplingCartesianAMRMeshGen::fillCellFieldOnPatchGhostAdv(int patchId, const DataArrayDouble *cellFieldOnThis, int ghostLev, const std::vector& arrsOnPatches, bool isConservative) const -{ - int nbp(getNumberOfPatches()); - if(nbp!=(int)arrsOnPatches.size()) - { - std::ostringstream oss; oss << "MEDCouplingCartesianAMRMesh::fillCellFieldOnPatchGhostAdv : there are " << nbp << " patches in this and " << arrsOnPatches.size() << " arrays in the last parameter !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - DataArrayDouble *theFieldToFill(const_cast(arrsOnPatches[patchId])); - // first, do as usual - fillCellFieldOnPatchGhost(patchId,cellFieldOnThis,theFieldToFill,ghostLev,isConservative); - fillCellFieldOnPatchOnlyGhostAdv(patchId,ghostLev,arrsOnPatches); -} - -/*! - * This method updates the patch with id \a patchId considering the only the all the patches in \a this to fill ghost zone. - * So \b warning, the DataArrayDouble instance \a arrsOnPatches[patchId] is non const. - * - * \sa getPatchIdsInTheNeighborhoodOf - */ -void MEDCouplingCartesianAMRMeshGen::fillCellFieldOnPatchOnlyGhostAdv(int patchId, int ghostLev, const std::vector& arrsOnPatches) const -{ - int nbp(getNumberOfPatches()); - if(nbp!=(int)arrsOnPatches.size()) - { - std::ostringstream oss; oss << "MEDCouplingCartesianAMRMesh::fillCellFieldOnPatchOnlyGhostAdv : there are " << nbp << " patches in this and " << arrsOnPatches.size() << " arrays in the last parameter !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - const MEDCouplingCartesianAMRPatch *refP(getPatch(patchId)); - DataArrayDouble *theFieldToFill(const_cast(arrsOnPatches[patchId])); - std::vector ids(getPatchIdsInTheNeighborhoodOf(patchId,ghostLev)); - for(std::vector::const_iterator it=ids.begin();it!=ids.end();it++) - { - const MEDCouplingCartesianAMRPatch *otherP(getPatch(*it)); - MEDCouplingCartesianAMRPatch::UpdateNeighborsOfOneWithTwo(ghostLev,_factors,refP,otherP,theFieldToFill,arrsOnPatches[*it]); - } -} - -void MEDCouplingCartesianAMRMeshGen::fillCellFieldOnPatchOnlyOnGhostZoneWith(int ghostLev, const MEDCouplingCartesianAMRPatch *patchToBeModified, const MEDCouplingCartesianAMRPatch *neighborPatch, DataArrayDouble *cellFieldOnPatch, const DataArrayDouble *cellFieldNeighbor) const -{ - MEDCouplingCartesianAMRPatch::UpdateNeighborsOfOneWithTwo(ghostLev,_factors,patchToBeModified,neighborPatch,cellFieldOnPatch,cellFieldNeighbor); -} - -/*! - * This method updates \a cellFieldOnThis part of values coming from the cell field \a cellFieldOnPatch lying on patch having id \a patchId. - * - * \param [in] patchId - The id of the patch \a cellFieldOnThis has to be put on. - * \param [in] cellFieldOnPatch - The array of the cell field on patch with id \a patchId. - * \param [in,out] cellFieldOnThis The array of the cell field on \a this to be updated only on the part concerning the patch with id \a patchId. - * \param [in] isConservative - true if the field needs to be conserved. false if maximum principle has to be applied. - * - * \throw if \a patchId is not in [ 0 , \c this->getNumberOfPatches() ) - * \throw if \a cellFieldOnPatch is NULL or not allocated - * \sa createCellFieldOnPatch, MEDCouplingIMesh::CondenseFineToCoarse,fillCellFieldComingFromPatchGhost - */ -void MEDCouplingCartesianAMRMeshGen::fillCellFieldComingFromPatch(int patchId, const DataArrayDouble *cellFieldOnPatch, DataArrayDouble *cellFieldOnThis, bool isConservative) const -{ - if(!cellFieldOnPatch || !cellFieldOnPatch->isAllocated()) - throw INTERP_KERNEL::Exception("MEDCouplingCartesianAMRMesh::fillCellFieldComingFromPatch : the input cell field array is NULL or not allocated !"); - const MEDCouplingCartesianAMRPatch *patch(getPatch(patchId)); - MEDCouplingIMesh::CondenseFineToCoarse(_mesh->getCellGridStructure(),cellFieldOnPatch,patch->getBLTRRange(),getFactors(),cellFieldOnThis); - if(!isConservative) - { - int fact(MEDCouplingStructuredMesh::DeduceNumberOfGivenStructure(getFactors())); - MEDCouplingStructuredMesh::MultiplyPartOf(_mesh->getCellGridStructure(),patch->getBLTRRange(),1./((double)fact),cellFieldOnThis); - } -} - -/*! - * This method is the extension of MEDCouplingCartesianAMRMesh::fillCellFieldComingFromPatch managing the ghost cells. If this - * method is called with \a ghostLev equal to 0 it behaves exactly as MEDCouplingCartesianAMRMesh::fillCellFieldComingFromPatch. - * - * \param [in] patchId - The id of the patch \a cellFieldOnThis has to be put on. - * \param [in] cellFieldOnPatch - The array of the cell field on patch with id \a patchId. - * \param [in,out] cellFieldOnThis The array of the cell field on \a this to be updated only on the part concerning the patch with id \a patchId. - * \param [in] ghostLev The size of ghost zone (must be >= 0 !) - * \param [in] isConservative - true if the field needs to be conserved. false if maximum principle has to be applied. - * - * \throw if \a patchId is not in [ 0 , \c this->getNumberOfPatches() ) - * \throw if \a cellFieldOnPatch is NULL or not allocated - * \sa fillCellFieldComingFromPatch - */ -void MEDCouplingCartesianAMRMeshGen::fillCellFieldComingFromPatchGhost(int patchId, const DataArrayDouble *cellFieldOnPatch, DataArrayDouble *cellFieldOnThis, int ghostLev, bool isConservative) const -{ - if(!cellFieldOnPatch || !cellFieldOnPatch->isAllocated()) - throw INTERP_KERNEL::Exception("MEDCouplingCartesianAMRMesh::fillCellFieldComingFromPatchGhost : the input cell field array is NULL or not allocated !"); - const MEDCouplingCartesianAMRPatch *patch(getPatch(patchId)); - MEDCouplingIMesh::CondenseFineToCoarseGhost(_mesh->getCellGridStructure(),cellFieldOnPatch,patch->getBLTRRange(),getFactors(),cellFieldOnThis,ghostLev); - if(!isConservative) - { - int fact(MEDCouplingStructuredMesh::DeduceNumberOfGivenStructure(getFactors())); - MEDCouplingStructuredMesh::MultiplyPartOfByGhost(_mesh->getCellGridStructure(),patch->getBLTRRange(),ghostLev,1./((double)fact),cellFieldOnThis); - } -} - -/*! - * This method finds all patches (located by their ids) that are in the neighborhood of patch with id \a patchId. The neighborhood size is - * defined by ghostLev. - * - * \param [in] patchId - the id of the considered patch. - * \param [in] ghostLev - the size of the neighborhood. - * \return DataArrayInt * - the newly allocated array containing the list of patches in the neighborhood of the considered patch. This array is to be deallocated by the caller. - */ -DataArrayInt *MEDCouplingCartesianAMRMeshGen::findPatchesInTheNeighborhoodOf(int patchId, int ghostLev) const -{ - int nbp(getNumberOfPatches()); - MEDCouplingAutoRefCountObjectPtr ret(DataArrayInt::New()); ret->alloc(0,1); - for(int i=0;ipushBackSilent(i); - } - return ret.retn(); -} - -MEDCouplingUMesh *MEDCouplingCartesianAMRMeshGen::buildUnstructured() const -{ - MEDCouplingAutoRefCountObjectPtr part(_mesh->buildUnstructured()); - std::vector bs(_mesh->getNumberOfCells(),false); - std::vector cgs(_mesh->getCellGridStructure()); - std::vector< MEDCouplingAutoRefCountObjectPtr > msSafe(_patches.size()+1); - std::size_t ii(0); - for(std::vector< MEDCouplingAutoRefCountObjectPtr >::const_iterator it=_patches.begin();it!=_patches.end();it++,ii++) - { - MEDCouplingStructuredMesh::SwitchOnIdsFrom(cgs,(*it)->getBLTRRange(),bs); - msSafe[ii+1]=(*it)->getMesh()->buildUnstructured(); - } - MEDCouplingAutoRefCountObjectPtr eltsOff(DataArrayInt::BuildListOfSwitchedOff(bs)); - msSafe[0]=static_cast(part->buildPartOfMySelf(eltsOff->begin(),eltsOff->end(),false)); - std::vector< const MEDCouplingUMesh * > ms(msSafe.size()); - for(std::size_t i=0;i cells; - std::vector< MEDCouplingAutoRefCountObjectPtr > cellsSafe; - for(std::vector< MEDCouplingAutoRefCountObjectPtr >::const_iterator it=_patches.begin();it!=_patches.end();it++) - { - const MEDCouplingCartesianAMRPatch *patch(*it); - if(patch) - { - MEDCouplingAutoRefCountObjectPtr cell(patch->getMesh()->getImageMesh()->asSingleCell()); - MEDCouplingAutoRefCountObjectPtr cell1SGT(cell->build1SGTUnstructured()); - cellsSafe.push_back(cell1SGT); cells.push_back(cell1SGT); - } - } - return MEDCoupling1SGTUMesh::Merge1SGTUMeshes(cells); -} - -MEDCoupling1SGTUMesh *MEDCouplingCartesianAMRMeshGen::buildMeshOfDirectChildrenOnly() const -{ - std::vector patches; - std::vector< MEDCouplingAutoRefCountObjectPtr > patchesSafe; - for(std::vector< MEDCouplingAutoRefCountObjectPtr >::const_iterator it=_patches.begin();it!=_patches.end();it++) - { - const MEDCouplingCartesianAMRPatch *patch(*it); - if(patch) - { - MEDCouplingAutoRefCountObjectPtr patchMesh(patch->getMesh()->getImageMesh()->build1SGTUnstructured()); - patchesSafe.push_back(patchMesh); patches.push_back(patchMesh); - } - } - return MEDCoupling1SGTUMesh::Merge1SGTUMeshes(patches); -} - -/*! - * This method works same as buildUnstructured except that arrays are given in input to build a field on cell in output. - * \return MEDCouplingFieldDouble * - a newly created instance the caller has reponsability to deal with. - * \sa buildUnstructured - */ -MEDCouplingFieldDouble *MEDCouplingCartesianAMRMeshGen::buildCellFieldOnRecurseWithoutOverlapWithoutGhost(int ghostSz, const std::vector& recurseArrs) const -{ - if(recurseArrs.empty()) - throw INTERP_KERNEL::Exception("MEDCouplingCartesianAMRMeshGen::buildCellFieldOnRecurseWithoutOverlapWithoutGhost : array is empty ! Should never happen !"); - // - std::vector bs(_mesh->getNumberOfCells(),false); - std::vector cgs(_mesh->getCellGridStructure()); - std::vector< MEDCouplingAutoRefCountObjectPtr > msSafe(_patches.size()+1); - std::size_t ii(0); - for(std::vector< MEDCouplingAutoRefCountObjectPtr >::const_iterator it=_patches.begin();it!=_patches.end();it++,ii++) - { - MEDCouplingStructuredMesh::SwitchOnIdsFrom(cgs,(*it)->getBLTRRange(),bs); - std::vector tmpArrs(extractSubTreeFromGlobalFlatten((*it)->getMesh(),recurseArrs)); - msSafe[ii+1]=(*it)->getMesh()->buildCellFieldOnRecurseWithoutOverlapWithoutGhost(ghostSz,tmpArrs); - } - MEDCouplingAutoRefCountObjectPtr eltsOff(DataArrayInt::BuildListOfSwitchedOff(bs)); - // - MEDCouplingAutoRefCountObjectPtr ret(MEDCouplingFieldDouble::New(ON_CELLS)); - MEDCouplingAutoRefCountObjectPtr arr2(extractGhostFrom(ghostSz,recurseArrs[0])); - arr2=arr2->selectByTupleIdSafe(eltsOff->begin(),eltsOff->end()); - ret->setArray(arr2); - ret->setName(arr2->getName()); - MEDCouplingAutoRefCountObjectPtr part(_mesh->buildUnstructured()); - MEDCouplingAutoRefCountObjectPtr mesh(part->buildPartOfMySelf(eltsOff->begin(),eltsOff->end(),false)); - ret->setMesh(mesh); - msSafe[0]=ret; - // - std::vector< const MEDCouplingFieldDouble * > ms(msSafe.size()); - for(std::size_t i=0;ibuildWithGhost(ghostSz). - */ -DataArrayDouble *MEDCouplingCartesianAMRMeshGen::extractGhostFrom(int ghostSz, const DataArrayDouble *arr) const -{ - std::vector st(_mesh->getCellGridStructure()); - std::vector< std::pair > p(MEDCouplingStructuredMesh::GetCompactFrmtFromDimensions(st)); - std::transform(st.begin(),st.end(),st.begin(),std::bind2nd(std::plus(),2*ghostSz)); - MEDCouplingStructuredMesh::ApplyGhostOnCompactFrmt(p,ghostSz); - MEDCouplingAutoRefCountObjectPtr ret(MEDCouplingStructuredMesh::ExtractFieldOfDoubleFrom(st,arr,p)); - return ret.retn(); -} - -/*! - * This method returns all the patches in \a this not equal to \a patchId that are in neighborhood of patch with id \a patchId. - * - * \sa fillCellFieldOnPatchOnlyGhostAdv - */ -std::vector MEDCouplingCartesianAMRMeshGen::getPatchIdsInTheNeighborhoodOf(int patchId, int ghostLev) const -{ - std::vector ret; - int nbp(getNumberOfPatches()); - // - for(int i=0;igetName() << "\"," << getSpaceDimension() << ",["; - std::vector ngs(getImageMesh()->getNodeGridStructure()); - std::vector orig(getImageMesh()->getOrigin()),dxyz(getImageMesh()->getDXYZ()); - std::copy(ngs.begin(),ngs.end(),std::ostream_iterator(oss,",")); - oss << "],["; - std::copy(orig.begin(),orig.end(),std::ostream_iterator(oss,",")); - oss << "],["; - std::copy(dxyz.begin(),dxyz.end(),std::ostream_iterator(oss,",")); - oss << "])\n"; - dumpPatchesOf("amr",oss); - return oss.str(); -} - -MEDCouplingCartesianAMRMeshGen::MEDCouplingCartesianAMRMeshGen(const MEDCouplingCartesianAMRMeshGen& other):RefCountObject(other),_mesh(other._mesh),_patches(other._patches),_factors(other._factors) -{ - const MEDCouplingIMesh *mesh(other._mesh); - if(mesh) - _mesh=static_cast(mesh->deepCpy()); - std::size_t sz(other._patches.size()); - for(std::size_t i=0;ideepCpy(this); - } -} - -MEDCouplingCartesianAMRMeshGen::MEDCouplingCartesianAMRMeshGen(const std::string& meshName, int spaceDim, const int *nodeStrctStart, const int *nodeStrctStop, - const double *originStart, const double *originStop, const double *dxyzStart, const double *dxyzStop) -{ - _mesh=MEDCouplingIMesh::New(meshName,spaceDim,nodeStrctStart,nodeStrctStop,originStart,originStop,dxyzStart,dxyzStop); -} - -MEDCouplingCartesianAMRMeshGen::MEDCouplingCartesianAMRMeshGen(MEDCouplingIMesh *mesh) -{ - if(!mesh) - throw INTERP_KERNEL::Exception("MEDCouplingCartesianAMRMeshGen(MEDCouplingIMesh *mesh) constructor : The input mesh is null !"); - mesh->checkCoherency(); - _mesh=mesh; _mesh->incrRef(); -} - -void MEDCouplingCartesianAMRMeshGen::checkPatchId(int patchId) const -{ - int sz(getNumberOfPatches()); - if(patchId<0 || patchId>=sz) - { - std::ostringstream oss; oss << "MEDCouplingCartesianAMRMeshGen::checkPatchId : invalid patchId (" << patchId << ") ! Must be in [0," << sz << ") !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } -} - -void MEDCouplingCartesianAMRMeshGen::checkFactorsAndIfNotSetAssign(const std::vector& factors) -{ - if(getSpaceDimension()!=(int)factors.size()) - throw INTERP_KERNEL::Exception("MEDCouplingCartesianAMRMeshGen::checkFactorsAndIfNotSetAssign : invalid size of factors ! size must be equal to the spaceDimension !"); - if(_factors.empty()) - { - _factors=factors; - } - else - { - if(_factors!=factors) - throw INTERP_KERNEL::Exception("MEDCouplingCartesianAMRMesh::checkFactorsAndIfNotSetAssign : the factors "); - } -} - -void MEDCouplingCartesianAMRMeshGen::retrieveGridsAtInternal(int lev, std::vector< MEDCouplingAutoRefCountObjectPtr >& grids) const -{ - if(lev==0) - { - const MEDCouplingCartesianAMRMesh *thisc(dynamic_cast(this));//tony - MEDCouplingAutoRefCountObjectPtr elt(new MEDCouplingCartesianAMRPatchGF(const_cast(thisc))); - grids.push_back(DynamicCastSafe(elt)); - } - else if(lev==1) - { - for(std::vector< MEDCouplingAutoRefCountObjectPtr >::const_iterator it=_patches.begin();it!=_patches.end();it++) - { - const MEDCouplingCartesianAMRPatch *pt(*it); - if(pt) - { - MEDCouplingAutoRefCountObjectPtr tmp1(*it); - grids.push_back(DynamicCastSafe(tmp1)); - } - } - } - else - { - for(std::vector< MEDCouplingAutoRefCountObjectPtr >::const_iterator it=_patches.begin();it!=_patches.end();it++) - { - const MEDCouplingCartesianAMRPatch *pt(*it); - if(pt) - pt->getMesh()->retrieveGridsAtInternal(lev-1,grids); - } - } -} - -int MEDCouplingCartesianAMRMeshGen::GetGhostLevelInFineRef(int ghostLev, const std::vector& factors) -{ - if(ghostLev<0) - throw INTERP_KERNEL::Exception("MEDCouplingCartesianAMRMesh::GetGhostLevelInFineRef : the ghost size must be >=0 !"); - if(factors.empty()) - throw INTERP_KERNEL::Exception("MEDCouplingCartesianAMRMesh::GetGhostLevelInFineRef : no factors defined !"); - int ghostLevInPatchRef; - if(ghostLev==0) - ghostLevInPatchRef=0; - else - { - ghostLevInPatchRef=(ghostLev-1)/factors[0]+1; - for(std::size_t i=0;i MEDCouplingCartesianAMRMeshGen::extractSubTreeFromGlobalFlatten(const MEDCouplingCartesianAMRMeshGen *head, const std::vector& all) const -{ - int maxLev(getMaxNumberOfLevelsRelativeToThis()); - std::vector ret; - std::vector meshes(1,this); - std::size_t kk(0); - for(int i=0;i meshesTmp; - for(std::vector::const_iterator it=meshes.begin();it!=meshes.end();it++) - { - if((*it)==head || head->isObjectInTheProgeny(*it)) - ret.push_back(all[kk]); - kk++; - std::vector< const MEDCouplingCartesianAMRPatch *> ps((*it)->getPatches()); - for(std::vector< const MEDCouplingCartesianAMRPatch *>::const_iterator it0=ps.begin();it0!=ps.end();it0++) - { - const MEDCouplingCartesianAMRMeshGen *mesh((*it0)->getMesh()); - meshesTmp.push_back(mesh); - } - } - meshes=meshesTmp; - } - if(kk!=all.size()) - throw INTERP_KERNEL::Exception("MEDCouplingCartesianAMRMeshGen::extractSubTreeFromGlobalFlatten : the size of input vector is not compatible with number of leaves in this !"); - return ret; -} - -void MEDCouplingCartesianAMRMeshGen::dumpPatchesOf(const std::string& varName, std::ostream& oss) const -{ - std::size_t j(0); - for(std::vector< MEDCouplingAutoRefCountObjectPtr >::const_iterator it=_patches.begin();it!=_patches.end();it++) - { - const MEDCouplingCartesianAMRPatch *patch(*it); - if(patch) - { - std::ostringstream oss2; oss2 << varName << ".addPatch(["; - const std::vector< std::pair >& bltr(patch->getBLTRRange()); - std::size_t sz(bltr.size()); - for(std::size_t i=0;i(oss2,",")); - oss2 << "])\n"; - oss << oss2.str(); - std::ostringstream oss3; oss3 << varName << "[" << j++ << "]"; - patch->getMesh()->dumpPatchesOf(oss3.str(),oss); - } - } -} - -std::size_t MEDCouplingCartesianAMRMeshGen::getHeapMemorySizeWithoutChildren() const -{ - return sizeof(MEDCouplingCartesianAMRMeshGen); -} - -std::vector MEDCouplingCartesianAMRMeshGen::getDirectChildrenWithNull() const -{ - std::vector ret; - ret.push_back((const MEDCouplingIMesh *)_mesh); - for(std::vector< MEDCouplingAutoRefCountObjectPtr >::const_iterator it=_patches.begin();it!=_patches.end();it++) - ret.push_back((const MEDCouplingCartesianAMRPatch*)*it); - return ret; -} - -void MEDCouplingCartesianAMRMeshGen::updateTime() const -{ - if((const MEDCouplingIMesh *)_mesh) - updateTimeWith(*_mesh); - for(std::vector< MEDCouplingAutoRefCountObjectPtr >::const_iterator it=_patches.begin();it!=_patches.end();it++) - { - const MEDCouplingCartesianAMRPatch *elt(*it); - if(!elt) - continue; - const MEDCouplingCartesianAMRMeshGen *mesh(elt->getMesh()); - if(mesh) - updateTimeWith(*mesh); - } -} - -MEDCouplingCartesianAMRMeshSub::MEDCouplingCartesianAMRMeshSub(MEDCouplingCartesianAMRMeshGen *father, MEDCouplingIMesh *mesh):MEDCouplingCartesianAMRMeshGen(mesh),_father(father) -{ - if(!_father) - throw INTERP_KERNEL::Exception("MEDCouplingCartesianAMRMeshSub(MEDCouplingCartesianAMRMeshGen *father, MEDCouplingIMesh *mesh) constructor : empty father !"); -} - -const MEDCouplingCartesianAMRMeshGen *MEDCouplingCartesianAMRMeshSub::getFather() const -{ - return _father; -} - -const MEDCouplingCartesianAMRMeshGen *MEDCouplingCartesianAMRMeshSub::getGodFather() const -{ - if(!_father) - throw INTERP_KERNEL::Exception("MEDCouplingCartesianAMRMeshSub::getGodFather : Impossible to find a god father because there is a hole in chain !"); - return _father->getGodFather(); -} - -/*! - * This method returns the level of \a this. 0 for god father. 1 for children of god father ... - */ -int MEDCouplingCartesianAMRMeshSub::getAbsoluteLevel() const -{ - if(!_father) - throw INTERP_KERNEL::Exception("MEDCouplingCartesianAMRMeshSub::getAbsoluteLevel : Impossible to find a god father because there is a hole in chain !"); - return _father->getAbsoluteLevel()+1; -} - -void MEDCouplingCartesianAMRMeshSub::detachFromFather() -{ - _father=0; - declareAsNew(); -} - -std::vector< std::pair > MEDCouplingCartesianAMRMeshSub::positionRelativeToGodFather(std::vector& st) const -{ - st=_father->getFactors(); - std::size_t dim(st.size()); - std::vector prev(st); - int id(_father->getPatchIdFromChildMesh(this)); - const MEDCouplingCartesianAMRPatch *p(_father->getPatch(id)); - std::vector< std::pair > ret(p->getBLTRRange()); - std::vector delta(MEDCouplingStructuredMesh::GetDimensionsFromCompactFrmt(ret)),start(dim); - std::transform(delta.begin(),delta.end(),prev.begin(),delta.begin(),std::multiplies()); - for(std::size_t i=0;i()); - const MEDCouplingCartesianAMRMeshGen *it(_father); - while(!dynamic_cast(it)) - { - const MEDCouplingCartesianAMRMeshSub *itc(static_cast(it)); - int id2(itc->_father->getPatchIdFromChildMesh(itc)); - const MEDCouplingCartesianAMRPatch *p2(itc->_father->getPatch(id2)); - const std::vector< std::pair >& start2(p2->getBLTRRange()); - std::vector tmp(dim); - for(std::size_t i=0;i_father->getFactors(); - std::transform(st.begin(),st.end(),prev.begin(),st.begin(),std::multiplies()); - std::transform(st.begin(),st.end(),tmp.begin(),tmp.begin(),std::multiplies()); - std::transform(start.begin(),start.end(),tmp.begin(),start.begin(),std::plus()); - it=itc->_father; - } - for(std::size_t i=0;igetAbsoluteLevelRelativeTo(ref)+1; -} - -MEDCouplingCartesianAMRMeshSub::MEDCouplingCartesianAMRMeshSub(const MEDCouplingCartesianAMRMeshSub& other, MEDCouplingCartesianAMRMeshGen *father):MEDCouplingCartesianAMRMeshGen(other),_father(father) -{ -} - -MEDCouplingCartesianAMRMeshSub *MEDCouplingCartesianAMRMeshSub::deepCpy(MEDCouplingCartesianAMRMeshGen *fath) const -{ - return new MEDCouplingCartesianAMRMeshSub(*this,fath); -} - -/*! - * \sa getPositionRelativeTo - */ -void MEDCouplingCartesianAMRMeshSub::getPositionRelativeToInternal(const MEDCouplingCartesianAMRMeshGen *ref, std::vector& ret) const -{ - if(this==ref) - return ; - if(!_father) - throw INTERP_KERNEL::Exception("MEDCouplingCartesianAMRMeshSub::getPositionRelativeToInternal : ref is not in the progeny of this !"); - int myId(_father->getPatchIdFromChildMesh(this)); - ret.push_back(myId); - _father->getPositionRelativeToInternal(ref,ret); -} - -MEDCouplingCartesianAMRMesh *MEDCouplingCartesianAMRMesh::New(const std::string& meshName, int spaceDim, const int *nodeStrctStart, const int *nodeStrctStop, - const double *originStart, const double *originStop, const double *dxyzStart, const double *dxyzStop) -{ - return new MEDCouplingCartesianAMRMesh(meshName,spaceDim,nodeStrctStart,nodeStrctStop,originStart,originStop,dxyzStart,dxyzStop); -} - -MEDCouplingCartesianAMRMesh *MEDCouplingCartesianAMRMesh::New(MEDCouplingIMesh *mesh) -{ - return new MEDCouplingCartesianAMRMesh(mesh); -} - -const MEDCouplingCartesianAMRMeshGen *MEDCouplingCartesianAMRMesh::getFather() const -{ - //I'm god father ! No father ! - return 0; -} - -const MEDCouplingCartesianAMRMeshGen *MEDCouplingCartesianAMRMesh::getGodFather() const -{ - return this; -} - -int MEDCouplingCartesianAMRMesh::getAbsoluteLevel() const -{ - return 0; -} - -void MEDCouplingCartesianAMRMesh::detachFromFather() -{//not a bug - do nothing -} - -std::vector< std::pair > MEDCouplingCartesianAMRMesh::positionRelativeToGodFather(std::vector& st) const -{ - st=_mesh->getCellGridStructure(); - return MEDCouplingStructuredMesh::GetCompactFrmtFromDimensions(st); -} - -int MEDCouplingCartesianAMRMesh::getAbsoluteLevelRelativeTo(const MEDCouplingCartesianAMRMeshGen *ref) const -{ - if(this==ref) - return 0; - throw INTERP_KERNEL::Exception("MEDCouplingCartesianAMRMesh::getAbsoluteLevelRelativeTo : ref is not in the progeny of this !"); -} - -std::vector MEDCouplingCartesianAMRMesh::retrieveGridsAt(int absoluteLev) const -{ - std::vector< MEDCouplingAutoRefCountObjectPtr > rets; - retrieveGridsAtInternal(absoluteLev,rets); - std::vector< MEDCouplingCartesianAMRPatchGen * > ret(rets.size()); - for(std::size_t i=0;i& bso, const DataArrayDouble *criterion, const std::vector< std::vector >& factors, double eps) -{ - std::size_t nbOfLevs(bso.size()); - if(nbOfLevs!=factors.size()) - throw INTERP_KERNEL::Exception("MEDCouplingCartesianAMRMesh::createPatchesFromCriterionML : size of vectors must be the same !"); - if(nbOfLevs==0) - return ; - if(!bso[0]) - throw INTERP_KERNEL::Exception("MEDCouplingCartesianAMRMesh::createPatchesFromCriterionML : pointers in 1st arg must be not NULL !"); - createPatchesFromCriterion(*bso[0],criterion,factors[0],eps); - for(std::size_t i=1;i elts(retrieveGridsAt((int)(i))); - std::size_t sz(elts.size()); - std::vector< MEDCouplingAutoRefCountObjectPtr > elts2(sz); - std::vector< MEDCouplingAutoRefCountObjectPtr > elts3(sz); - for(std::size_t ii=0;ii > fieldNames(1); fieldNames[0].first=TMP_STR; fieldNames[0].second=1; - MEDCouplingAutoRefCountObjectPtr att(MEDCouplingAMRAttribute::New(this,fieldNames,0)); - att->alloc(); - DataArrayDouble *tmpDa(const_cast(att->getFieldOn(this,TMP_STR))); - tmpDa->cpyFrom(*criterion); - att->synchronizeCoarseToFine(); - for(std::size_t ii=0;iigetFieldOn(const_cast(elts[ii]->getMesh()),TMP_STR)); - elts3[ii]=const_cast(critOnLeaf); elts3[ii]->incrRef(); - } - att=0; - for(std::size_t ii=0;ii(elts[ii]->getMesh())->createPatchesFromCriterion(*bso[i],elts3[ii],factors[i],eps); - } -} - -void MEDCouplingCartesianAMRMesh::getPositionRelativeToInternal(const MEDCouplingCartesianAMRMeshGen *ref, std::vector& ret) const -{ - -} - -MEDCouplingCartesianAMRMesh::MEDCouplingCartesianAMRMesh(const MEDCouplingCartesianAMRMesh& other):MEDCouplingCartesianAMRMeshGen(other) -{ -} - -MEDCouplingCartesianAMRMesh::MEDCouplingCartesianAMRMesh(const std::string& meshName, int spaceDim, const int *nodeStrctStart, const int *nodeStrctStop, - const double *originStart, const double *originStop, const double *dxyzStart, const double *dxyzStop):MEDCouplingCartesianAMRMeshGen(meshName,spaceDim,nodeStrctStart,nodeStrctStop,originStart,originStop,dxyzStart,dxyzStop) -{ -} - -MEDCouplingCartesianAMRMesh::MEDCouplingCartesianAMRMesh(MEDCouplingIMesh *mesh):MEDCouplingCartesianAMRMeshGen(mesh) -{ -} - -std::vector MEDCouplingCartesianAMRMesh::getDirectChildrenWithNull() const -{ - std::vector ret(MEDCouplingCartesianAMRMeshGen::getDirectChildrenWithNull()); - return ret; -} - -MEDCouplingCartesianAMRMesh::~MEDCouplingCartesianAMRMesh() -{ -} diff --git a/src/MEDCoupling/MEDCouplingCartesianAMRMesh.hxx b/src/MEDCoupling/MEDCouplingCartesianAMRMesh.hxx deleted file mode 100644 index f67e08064..000000000 --- a/src/MEDCoupling/MEDCouplingCartesianAMRMesh.hxx +++ /dev/null @@ -1,258 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 -// 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 - -#ifndef __MEDCOUPLINGCARTESIANAMRMESH_HXX__ -#define __MEDCOUPLINGCARTESIANAMRMESH_HXX__ - -#include "MEDCoupling.hxx" -#include "MEDCouplingTimeLabel.hxx" -#include "MEDCouplingRefCountObject.hxx" -#include "MEDCouplingAutoRefCountObjectPtr.hxx" - -#include "BoxSplittingOptions.hxx" -#include "InterpKernelException.hxx" - -namespace ParaMEDMEM -{ - class MEDCouplingIMesh; - class MEDCouplingUMesh; - class DataArrayInt; - class DataArrayByte; - class DataArrayDouble; - class MEDCoupling1SGTUMesh; - class MEDCouplingFieldDouble; - class MEDCouplingCartesianAMRMesh; - class MEDCouplingCartesianAMRMeshGen; - - /// @cond INTERNAL - - /*! - * This class does not inherit from TimeLabel so only const method should exist. - */ - class MEDCouplingCartesianAMRPatchGen : public RefCountObject - { - public: - MEDCOUPLING_EXPORT virtual MEDCouplingCartesianAMRPatchGen *deepCpy(MEDCouplingCartesianAMRMeshGen *father) const = 0; - MEDCOUPLING_EXPORT int getNumberOfCellsRecursiveWithOverlap() const; - MEDCOUPLING_EXPORT int getNumberOfCellsRecursiveWithoutOverlap() const; - MEDCOUPLING_EXPORT int getMaxNumberOfLevelsRelativeToThis() const; - MEDCOUPLING_EXPORT const MEDCouplingCartesianAMRMeshGen *getMesh() const { return _mesh; } - protected: - MEDCouplingCartesianAMRPatchGen(const MEDCouplingCartesianAMRPatchGen& other, MEDCouplingCartesianAMRMeshGen *father); - MEDCouplingCartesianAMRPatchGen(MEDCouplingCartesianAMRMeshGen *mesh); - const MEDCouplingCartesianAMRMeshGen *getMeshSafe() const; - MEDCouplingCartesianAMRMeshGen *getMeshSafe(); - private: - std::vector getDirectChildrenWithNull() const; - protected: - MEDCouplingAutoRefCountObjectPtr _mesh; - }; - - /*! - * This class does not inherit from TimeLabel so only const method should exist. - */ - class MEDCouplingCartesianAMRPatch : public MEDCouplingCartesianAMRPatchGen - { - public: - MEDCouplingCartesianAMRPatch(MEDCouplingCartesianAMRMeshGen *mesh, const std::vector< std::pair >& bottomLeftTopRight); - MEDCouplingCartesianAMRPatch *deepCpy(MEDCouplingCartesianAMRMeshGen *father) const; - // direct forward to _mesh - MEDCOUPLING_EXPORT void addPatch(const std::vector< std::pair >& bottomLeftTopRight, const std::vector& factors); - // end of direct forward to _mesh - MEDCOUPLING_EXPORT int getNumberOfOverlapedCellsForFather() const; - MEDCOUPLING_EXPORT bool isInMyNeighborhood(const MEDCouplingCartesianAMRPatch *other, int ghostLev) const; - MEDCOUPLING_EXPORT bool isInMyNeighborhoodExt(const MEDCouplingCartesianAMRPatch *other, int ghostLev) const; - MEDCOUPLING_EXPORT bool isInMyNeighborhoodDiffLev(const MEDCouplingCartesianAMRPatch *other, int ghostLev) const; - // basic set/get - MEDCOUPLING_EXPORT const std::vector< std::pair >& getBLTRRange() const { return _bl_tr; } - MEDCOUPLING_EXPORT std::vector< std::pair > getBLTRRangeRelativeToGF() const; - MEDCOUPLING_EXPORT std::vector computeCellGridSt() const; - MEDCOUPLING_EXPORT static bool IsInMyNeighborhood(int ghostLev, const std::vector< std::pair >& p1, const std::vector< std::pair >& p2); - // - static std::vector< std::vector< std::pair > > FindNeighborsOfSubPatchesOfSameLev(int ghostLev, const MEDCouplingCartesianAMRPatch *p1, const MEDCouplingCartesianAMRPatch *p2); - static void FindNeighborsOfSubPatchesOf(int ghostLev, const MEDCouplingCartesianAMRPatch *p1, const MEDCouplingCartesianAMRPatch *p2, std::vector< std::pair >& ret); - static void UpdateNeighborsOfOneWithTwo(int ghostLev, const std::vector& factors, const MEDCouplingCartesianAMRPatch *p1, const MEDCouplingCartesianAMRPatch *p2, DataArrayDouble *dataOnP1, const DataArrayDouble *dataOnP2); - static void UpdateNeighborsOfOneWithTwoExt(int ghostLev, const MEDCouplingCartesianAMRPatch *p1, const MEDCouplingCartesianAMRPatch *p2, DataArrayDouble *dataOnP1, const DataArrayDouble *dataOnP2); - static void UpdateNeighborsOfOneWithTwoMixedLev(int ghostLev, const MEDCouplingCartesianAMRPatch *p1, const MEDCouplingCartesianAMRPatch *p2, DataArrayDouble *dataOnP1, const DataArrayDouble *dataOnP2, bool isConservative); - private: - static void ComputeZonesOfTwoRelativeToOneDiffLev(int ghostLev, const MEDCouplingCartesianAMRPatch *p1, const MEDCouplingCartesianAMRPatch *p2, std::vector< std::pair >& p1Zone, std::vector< std::pair >& p2Zone, std::vector& factToApplyOn2); - private: - std::size_t getHeapMemorySizeWithoutChildren() const; - static const MEDCouplingCartesianAMRMeshGen *FindCommonAncestor(const MEDCouplingCartesianAMRPatch *p1, const MEDCouplingCartesianAMRPatch *p2, int& lev); - static std::vector ComputeOffsetFromTwoToOne(const MEDCouplingCartesianAMRMeshGen *comAncestor, int lev, const MEDCouplingCartesianAMRPatch *p1, const MEDCouplingCartesianAMRPatch *p2); - static void UpdateNeighborsOfOneWithTwoInternal(int ghostLev, const std::vector& factors, const std::vector< std::pair >&p1 ,const std::vector< std::pair >&p2, DataArrayDouble *dataOnP1, const DataArrayDouble *dataOnP2); - public: - static void ApplyFactorsOnCompactFrmt(std::vector< std::pair >& partBeforeFact, const std::vector& factors); - static void ApplyAllGhostOnCompactFrmt(std::vector< std::pair >& partBeforeFact, int ghostSize); - private: - MEDCouplingCartesianAMRPatch(const MEDCouplingCartesianAMRPatch& other, MEDCouplingCartesianAMRMeshGen *father); - private: - //! bottom left/top right cell range relative to \a _father - std::vector< std::pair > _bl_tr; - }; - - /*! - * This class does not inherit from TimeLabel so only const method should exist. - */ - class MEDCouplingCartesianAMRPatchGF : public MEDCouplingCartesianAMRPatchGen - { - public: - MEDCouplingCartesianAMRPatchGF(MEDCouplingCartesianAMRMesh *mesh); - MEDCouplingCartesianAMRPatchGF *deepCpy(MEDCouplingCartesianAMRMeshGen *father) const; - private: - std::size_t getHeapMemorySizeWithoutChildren() const; - private: - MEDCouplingCartesianAMRPatchGF(const MEDCouplingCartesianAMRPatchGF& other, MEDCouplingCartesianAMRMeshGen *father); - }; - - /// @endcond - - /*! - * This class is the base class dedicated to AMR using Adaptative Hierarchical Overlapped image Grid. - * This class does \b NOT inherit from MEDCouplingMesh because this class overlaps image grid structured meshes to perform adaptative mesh refinement. - * But this class aggregates MEDCouplingMesh instances ! - */ - class MEDCouplingCartesianAMRMeshGen : public RefCountObject, public TimeLabel - { - public: - MEDCOUPLING_EXPORT virtual MEDCouplingCartesianAMRMeshGen *deepCpy(MEDCouplingCartesianAMRMeshGen *father) const = 0; - MEDCOUPLING_EXPORT int getSpaceDimension() const; - MEDCOUPLING_EXPORT const std::vector& getFactors() const { return _factors; } - MEDCOUPLING_EXPORT void setFactors(const std::vector& newFactors); - MEDCOUPLING_EXPORT int getMaxNumberOfLevelsRelativeToThis() const; - MEDCOUPLING_EXPORT int getNumberOfCellsAtCurrentLevel() const; - MEDCOUPLING_EXPORT int getNumberOfCellsAtCurrentLevelGhost(int ghostLev) const; - MEDCOUPLING_EXPORT int getNumberOfCellsRecursiveWithOverlap() const; - MEDCOUPLING_EXPORT int getNumberOfCellsRecursiveWithoutOverlap() const; - MEDCOUPLING_EXPORT const MEDCouplingIMesh *getImageMesh() const { return _mesh; } - // - MEDCOUPLING_EXPORT virtual const MEDCouplingCartesianAMRMeshGen *getFather() const = 0; - MEDCOUPLING_EXPORT virtual const MEDCouplingCartesianAMRMeshGen *getGodFather() const = 0; - MEDCOUPLING_EXPORT virtual int getAbsoluteLevel() const = 0; - MEDCOUPLING_EXPORT virtual void detachFromFather() = 0; - MEDCOUPLING_EXPORT virtual std::vector< std::pair > positionRelativeToGodFather(std::vector& st) const = 0; - MEDCOUPLING_EXPORT virtual int getAbsoluteLevelRelativeTo(const MEDCouplingCartesianAMRMeshGen *ref) const = 0; - MEDCOUPLING_EXPORT std::vector getPositionRelativeTo(const MEDCouplingCartesianAMRMeshGen *ref) const; - MEDCOUPLING_EXPORT const MEDCouplingCartesianAMRPatch *getPatchAtPosition(const std::vector& pos) const; - MEDCOUPLING_EXPORT const MEDCouplingCartesianAMRMeshGen *getMeshAtPosition(const std::vector& pos) const; - MEDCOUPLING_EXPORT virtual std::vector retrieveGridsAt(int absoluteLev) const; - MEDCOUPLING_EXPORT void addPatch(const std::vector< std::pair >& bottomLeftTopRight, const std::vector& factors); - MEDCOUPLING_EXPORT void removeAllPatches(); - MEDCOUPLING_EXPORT void removePatch(int patchId); - MEDCOUPLING_EXPORT int getNumberOfPatches() const; - MEDCOUPLING_EXPORT void createPatchesFromCriterion(const INTERP_KERNEL::BoxSplittingOptions& bso, const std::vector& criterion, const std::vector& factors); - MEDCOUPLING_EXPORT void createPatchesFromCriterion(const INTERP_KERNEL::BoxSplittingOptions& bso, const DataArrayByte *criterion, const std::vector& factors); - MEDCOUPLING_EXPORT void createPatchesFromCriterion(const INTERP_KERNEL::BoxSplittingOptions& bso, const DataArrayDouble *criterion, const std::vector& factors, double eps); - MEDCOUPLING_EXPORT int getPatchIdFromChildMesh(const MEDCouplingCartesianAMRMeshGen *mesh) const; - MEDCOUPLING_EXPORT std::vector< const MEDCouplingCartesianAMRPatch *> getPatches() const; - MEDCOUPLING_EXPORT const MEDCouplingCartesianAMRPatch *getPatch(int patchId) const; - MEDCOUPLING_EXPORT bool isPatchInNeighborhoodOf(int patchId1, int patchId2, int ghostLev) const; - MEDCOUPLING_EXPORT DataArrayDouble *createCellFieldOnPatch(int patchId, const DataArrayDouble *cellFieldOnThis) const; - // coarse to fine - MEDCOUPLING_EXPORT void fillCellFieldOnPatch(int patchId, const DataArrayDouble *cellFieldOnThis, DataArrayDouble *cellFieldOnPatch, bool isConservative=true) const; - MEDCOUPLING_EXPORT void fillCellFieldOnPatchGhost(int patchId, const DataArrayDouble *cellFieldOnThis, DataArrayDouble *cellFieldOnPatch, int ghostLev, bool isConservative=true) const; - MEDCOUPLING_EXPORT void fillCellFieldOnPatchOnlyOnGhostZone(int patchId, const DataArrayDouble *cellFieldOnThis, DataArrayDouble *cellFieldOnPatch, int ghostLev) const; - // coarse to fine + fine to fine - MEDCOUPLING_EXPORT void fillCellFieldOnPatchGhostAdv(int patchId, const DataArrayDouble *cellFieldOnThis, int ghostLev, const std::vector& arrsOnPatches, bool isConservative=true) const; - // fine to fine - MEDCOUPLING_EXPORT void fillCellFieldOnPatchOnlyGhostAdv(int patchId, int ghostLev, const std::vector& arrsOnPatches) const; - MEDCOUPLING_EXPORT void fillCellFieldOnPatchOnlyOnGhostZoneWith(int ghostLev, const MEDCouplingCartesianAMRPatch *patchToBeModified, const MEDCouplingCartesianAMRPatch *neighborPatch, DataArrayDouble *cellFieldOnPatch, const DataArrayDouble *cellFieldNeighbor) const; - // fine to coarse - MEDCOUPLING_EXPORT void fillCellFieldComingFromPatch(int patchId, const DataArrayDouble *cellFieldOnPatch, DataArrayDouble *cellFieldOnThis, bool isConservative=true) const; - MEDCOUPLING_EXPORT void fillCellFieldComingFromPatchGhost(int patchId, const DataArrayDouble *cellFieldOnPatch, DataArrayDouble *cellFieldOnThis, int ghostLev, bool isConservative=true) const; - // - MEDCOUPLING_EXPORT DataArrayInt *findPatchesInTheNeighborhoodOf(int patchId, int ghostLev) const; - // - MEDCOUPLING_EXPORT MEDCouplingUMesh *buildUnstructured() const; - MEDCOUPLING_EXPORT MEDCoupling1SGTUMesh *buildMeshFromPatchEnvelop() const; - MEDCOUPLING_EXPORT MEDCoupling1SGTUMesh *buildMeshOfDirectChildrenOnly() const; - MEDCOUPLING_EXPORT MEDCouplingFieldDouble *buildCellFieldOnRecurseWithoutOverlapWithoutGhost(int ghostSz, const std::vector& recurseArrs) const; - MEDCOUPLING_EXPORT DataArrayDouble *extractGhostFrom(int ghostSz, const DataArrayDouble *arr) const; - MEDCOUPLING_EXPORT std::vector getPatchIdsInTheNeighborhoodOf(int patchId, int ghostLev) const; - MEDCOUPLING_EXPORT std::string buildPythonDumpOfThis() const; - protected: - MEDCouplingCartesianAMRMeshGen(const MEDCouplingCartesianAMRMeshGen& other); - MEDCouplingCartesianAMRMeshGen(const std::string& meshName, int spaceDim, const int *nodeStrctStart, const int *nodeStrctStop, - const double *originStart, const double *originStop, const double *dxyzStart, const double *dxyzStop); - MEDCouplingCartesianAMRMeshGen(MEDCouplingIMesh *mesh); - void checkPatchId(int patchId) const; - void checkFactorsAndIfNotSetAssign(const std::vector& factors); - void retrieveGridsAtInternal(int lev, std::vector< MEDCouplingAutoRefCountObjectPtr >& grids) const; - static int GetGhostLevelInFineRef(int ghostLev, const std::vector& factors); - std::vector extractSubTreeFromGlobalFlatten(const MEDCouplingCartesianAMRMeshGen *head, const std::vector& all) const; - void dumpPatchesOf(const std::string& varName, std::ostream& oss) const; - public: - virtual void getPositionRelativeToInternal(const MEDCouplingCartesianAMRMeshGen *ref, std::vector& ret) const = 0; - protected: - MEDCOUPLING_EXPORT std::size_t getHeapMemorySizeWithoutChildren() const; - MEDCOUPLING_EXPORT std::vector getDirectChildrenWithNull() const; - MEDCOUPLING_EXPORT void updateTime() const; - protected: - MEDCouplingAutoRefCountObjectPtr _mesh; - std::vector< MEDCouplingAutoRefCountObjectPtr > _patches; - std::vector _factors; - }; - - class MEDCouplingCartesianAMRMeshSub : public MEDCouplingCartesianAMRMeshGen - { - public: - MEDCouplingCartesianAMRMeshSub(MEDCouplingCartesianAMRMeshGen *father, MEDCouplingIMesh *mesh); - MEDCOUPLING_EXPORT const MEDCouplingCartesianAMRMeshGen *getFather() const; - MEDCOUPLING_EXPORT const MEDCouplingCartesianAMRMeshGen *getGodFather() const; - MEDCOUPLING_EXPORT int getAbsoluteLevel() const; - MEDCOUPLING_EXPORT void detachFromFather(); - MEDCOUPLING_EXPORT std::vector< std::pair > positionRelativeToGodFather(std::vector& st) const; - MEDCOUPLING_EXPORT int getAbsoluteLevelRelativeTo(const MEDCouplingCartesianAMRMeshGen *ref) const; - private: - MEDCouplingCartesianAMRMeshSub(const MEDCouplingCartesianAMRMeshSub& other, MEDCouplingCartesianAMRMeshGen *father); - MEDCouplingCartesianAMRMeshSub *deepCpy(MEDCouplingCartesianAMRMeshGen *father) const; - void getPositionRelativeToInternal(const MEDCouplingCartesianAMRMeshGen *ref, std::vector& ret) const; - protected: - MEDCouplingCartesianAMRMeshGen *_father; - }; - - class MEDCouplingCartesianAMRMesh : public MEDCouplingCartesianAMRMeshGen - { - public: - MEDCOUPLING_EXPORT static MEDCouplingCartesianAMRMesh *New(const std::string& meshName, int spaceDim, const int *nodeStrctStart, const int *nodeStrctStop, - const double *originStart, const double *originStop, const double *dxyzStart, const double *dxyzStop); - MEDCOUPLING_EXPORT static MEDCouplingCartesianAMRMesh *New(MEDCouplingIMesh *mesh); - MEDCOUPLING_EXPORT const MEDCouplingCartesianAMRMeshGen *getFather() const; - MEDCOUPLING_EXPORT const MEDCouplingCartesianAMRMeshGen *getGodFather() const; - MEDCOUPLING_EXPORT int getAbsoluteLevel() const; - MEDCOUPLING_EXPORT void detachFromFather(); - MEDCOUPLING_EXPORT std::vector< std::pair > positionRelativeToGodFather(std::vector& st) const; - MEDCOUPLING_EXPORT int getAbsoluteLevelRelativeTo(const MEDCouplingCartesianAMRMeshGen *ref) const; - MEDCOUPLING_EXPORT std::vector retrieveGridsAt(int absoluteLev) const; - MEDCouplingCartesianAMRMesh *deepCpy(MEDCouplingCartesianAMRMeshGen *father) const; - MEDCOUPLING_EXPORT void createPatchesFromCriterionML(const std::vector& bso, const DataArrayDouble *criterion, const std::vector< std::vector >& factors, double eps); - private: - void getPositionRelativeToInternal(const MEDCouplingCartesianAMRMeshGen *ref, std::vector& ret) const; - MEDCouplingCartesianAMRMesh(const MEDCouplingCartesianAMRMesh& other); - MEDCouplingCartesianAMRMesh(const std::string& meshName, int spaceDim, const int *nodeStrctStart, const int *nodeStrctStop, - const double *originStart, const double *originStop, const double *dxyzStart, const double *dxyzStop); - MEDCouplingCartesianAMRMesh(MEDCouplingIMesh *mesh); - MEDCOUPLING_EXPORT std::vector getDirectChildrenWithNull() const; - ~MEDCouplingCartesianAMRMesh(); - }; -} - -#endif - diff --git a/src/MEDCoupling/MEDCouplingCurveLinearMesh.cxx b/src/MEDCoupling/MEDCouplingCurveLinearMesh.cxx deleted file mode 100644 index 601ea910d..000000000 --- a/src/MEDCoupling/MEDCouplingCurveLinearMesh.cxx +++ /dev/null @@ -1,936 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 -// 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 std::string& 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::getHeapMemorySizeWithoutChildren() const -{ - std::size_t ret(MEDCouplingStructuredMesh::getHeapMemorySizeWithoutChildren()); - ret+=_structure.capacity()*sizeof(int); - return ret; -} - -std::vector MEDCouplingCurveLinearMesh::getDirectChildrenWithNull() const -{ - std::vector ret; - ret.push_back((const DataArrayDouble *)_coords); - return 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) -{ - 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 -{ - 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 -{ - 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, \a this and \a other are the same ! - */ -void MEDCouplingCurveLinearMesh::checkDeepEquivalOnSameNodesWith(const MEDCouplingMesh *other, int cellCompPol, double prec, - DataArrayInt *&cellCor) const -{ - if(!isEqualWithoutConsideringStr(other,prec)) - throw INTERP_KERNEL::Exception("MEDCouplingCurveLinearMesh::checkDeepEquivalOnSameNodesWith : Meshes are not the same !"); -} - -void MEDCouplingCurveLinearMesh::checkCoherency() const -{ - 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 -{ - checkCoherency(); -} - -void MEDCouplingCurveLinearMesh::checkCoherency2(double eps) const -{ - checkCoherency1(eps); -} - -int MEDCouplingCurveLinearMesh::getNumberOfCells() const -{ - checkCoherency(); - return MEDCouplingStructuredMesh::getNumberOfCells(); -} - -int MEDCouplingCurveLinearMesh::getNumberOfNodes() const -{ - checkCoherency(); - return MEDCouplingStructuredMesh::getNumberOfNodes(); -} - -void MEDCouplingCurveLinearMesh::getNodeGridStructure(int *res) const -{ - std::copy(_structure.begin(),_structure.end(),res); -} - -/*! - * MEDCouplingCurveLinearMesh has the property to define 2 space dimensions. One coming from its coordinates. The other coming from the node structure. - * Normally they should be equal ! This method returns the space dimension from coordinates. If the other one is requested call getSpaceDimensionOnNodeStruct. - * - * \sa MEDCouplingStructuredMesh::getSpaceDimensionOnNodeStruct - */ -int MEDCouplingCurveLinearMesh::getSpaceDimension() const -{ - if(!((const DataArrayDouble *)_coords)) - throw INTERP_KERNEL::Exception("MEDCouplingCurveLinearMesh::getSpaceDimension : no array set ! impossible to deduce a space dimension !"); - return _coords->getNumberOfComponents(); -} - -void MEDCouplingCurveLinearMesh::getCoordinatesOfNode(int nodeId, std::vector& coo) const -{ - 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() -{ - return _coords; -} - -const DataArrayDouble *MEDCouplingCurveLinearMesh::getCoords() const -{ - return _coords; -} - -void MEDCouplingCurveLinearMesh::setCoords(const DataArrayDouble *coords) -{ - if(coords!=(const DataArrayDouble *)_coords) - { - _coords=const_cast(coords); - if(coords) - coords->incrRef(); - declareAsNew(); - } -} - -void MEDCouplingCurveLinearMesh::setNodeGridStructure(const int *gridStructBg, const int *gridStructEnd) -{ - 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 -{ - return _structure; -} - -MEDCouplingStructuredMesh *MEDCouplingCurveLinearMesh::buildStructuredSubPart(const std::vector< std::pair >& cellPart) const -{ - checkCoherency(); - int dim(getSpaceDimension()); - std::vector dims(getMeshDimension()); - if(dim!=(int)cellPart.size()) - { - std::ostringstream oss; oss << "MEDCouplingCurveLinearMesh::buildStructuredSubPart : the space dimension is " << dim << " and cell part size is " << cellPart.size() << " !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - std::vector< std::pair > nodePartFormat(cellPart); - for(std::vector< std::pair >::iterator it=nodePartFormat.begin();it!=nodePartFormat.end();it++) - (*it).second++; - MEDCouplingAutoRefCountObjectPtr tmp1(BuildExplicitIdsFrom(getNodeGridStructure(),nodePartFormat)); - MEDCouplingAutoRefCountObjectPtr ret(dynamic_cast(deepCpy())); - const DataArrayDouble *coo(ret->getCoords()); - if(coo) - { - MEDCouplingAutoRefCountObjectPtr coo2(coo->selectByTupleIdSafe(tmp1->begin(),tmp1->end())); - ret->setCoords(coo2); - } - for(int i=0;isetNodeGridStructure(&dims[0],&dims[0]+dims.size()); - return ret.retn(); -} - -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); 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 -{ - 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 -{ - 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 -{ - 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 -{ - 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("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]); - setDescription(littleStrings[1]); - setTimeUnit(littleStrings[2]); - 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, DataArrayByte *byteData) const -{ - 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",byteData); - else - { - MEDCouplingAutoRefCountObjectPtr coo=_coords->changeNbOfComponents(3,0.); - coo->writeVTK(ofs,8,"Points",byteData); - } - ofs << " \n"; - ofs << " \n"; - ofs << " \n"; -} - -void MEDCouplingCurveLinearMesh::reprQuickOverview(std::ostream& stream) const -{ - 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()); - int nbOfCompoExp(-1); - try - { - nbOfCompoExp=getSpaceDimension(); - } - catch(INTERP_KERNEL::Exception& e) - { - } - if(nbOfCompo!=nbOfCompoExp) - { 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::getVTKFileExtension() const -{ - return std::string("vts"); -} - -std::string MEDCouplingCurveLinearMesh::getVTKDataSetType() const -{ - return std::string("StructuredGrid"); -} diff --git a/src/MEDCoupling/MEDCouplingCurveLinearMesh.hxx b/src/MEDCoupling/MEDCouplingCurveLinearMesh.hxx deleted file mode 100644 index 341075947..000000000 --- a/src/MEDCoupling/MEDCouplingCurveLinearMesh.hxx +++ /dev/null @@ -1,106 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 -// 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 MEDCouplingCurveLinearMesh : public MEDCouplingStructuredMesh - { - public: - MEDCOUPLING_EXPORT static MEDCouplingCurveLinearMesh *New(); - MEDCOUPLING_EXPORT static MEDCouplingCurveLinearMesh *New(const std::string& meshName); - MEDCOUPLING_EXPORT MEDCouplingMesh *deepCpy() const; - MEDCOUPLING_EXPORT MEDCouplingCurveLinearMesh *clone(bool recDeepCpy) const; - MEDCOUPLING_EXPORT void updateTime() const; - MEDCOUPLING_EXPORT std::size_t getHeapMemorySizeWithoutChildren() const; - MEDCOUPLING_EXPORT std::vector getDirectChildrenWithNull() const; - MEDCOUPLING_EXPORT MEDCouplingMeshType getType() const { return CURVE_LINEAR; } - MEDCOUPLING_EXPORT void copyTinyStringsFrom(const MEDCouplingMesh *other); - MEDCOUPLING_EXPORT bool isEqualIfNotWhy(const MEDCouplingMesh *other, double prec, std::string& reason) const; - MEDCOUPLING_EXPORT bool isEqualWithoutConsideringStr(const MEDCouplingMesh *other, double prec) const; - MEDCOUPLING_EXPORT void checkDeepEquivalWith(const MEDCouplingMesh *other, int cellCompPol, double prec, - DataArrayInt *&cellCor, DataArrayInt *&nodeCor) const; - MEDCOUPLING_EXPORT void checkDeepEquivalOnSameNodesWith(const MEDCouplingMesh *other, int cellCompPol, double prec, - DataArrayInt *&cellCor) const; - MEDCOUPLING_EXPORT void checkCoherency() const; - MEDCOUPLING_EXPORT void checkCoherency1(double eps=1e-12) const; - MEDCOUPLING_EXPORT void checkCoherency2(double eps=1e-12) const; - MEDCOUPLING_EXPORT int getNumberOfCells() const; - MEDCOUPLING_EXPORT int getNumberOfNodes() const; - MEDCOUPLING_EXPORT int getSpaceDimension() const; - MEDCOUPLING_EXPORT void getCoordinatesOfNode(int nodeId, std::vector& coo) const; - MEDCOUPLING_EXPORT std::string simpleRepr() const; - MEDCOUPLING_EXPORT std::string advancedRepr() const; - MEDCOUPLING_EXPORT DataArrayDouble *getCoords(); - MEDCOUPLING_EXPORT const DataArrayDouble *getCoords() const; - MEDCOUPLING_EXPORT void setCoords(const DataArrayDouble *coords); - MEDCOUPLING_EXPORT void setNodeGridStructure(const int *gridStructBg, const int *gridStructEnd); - MEDCOUPLING_EXPORT std::vector getNodeGridStructure() const; - MEDCOUPLING_EXPORT MEDCouplingStructuredMesh *buildStructuredSubPart(const std::vector< std::pair >& cellPart) const; - // tools - MEDCOUPLING_EXPORT void getBoundingBox(double *bbox) const; - MEDCOUPLING_EXPORT MEDCouplingFieldDouble *getMeasureField(bool isAbs) const; - MEDCOUPLING_EXPORT MEDCouplingFieldDouble *getMeasureFieldOnNode(bool isAbs) const; - MEDCOUPLING_EXPORT MEDCouplingFieldDouble *buildOrthogonalField() const; - MEDCOUPLING_EXPORT int getCellContainingPoint(const double *pos, double eps) const; - MEDCOUPLING_EXPORT void rotate(const double *center, const double *vector, double angle); - MEDCOUPLING_EXPORT void translate(const double *vector); - MEDCOUPLING_EXPORT void scale(const double *point, double factor); - MEDCOUPLING_EXPORT MEDCouplingMesh *mergeMyselfWith(const MEDCouplingMesh *other) const; - MEDCOUPLING_EXPORT DataArrayDouble *getCoordinatesAndOwner() const; - MEDCOUPLING_EXPORT DataArrayDouble *getBarycenterAndOwner() const; - MEDCOUPLING_EXPORT DataArrayDouble *computeIsoBarycenterOfNodesPerCell() const; - MEDCOUPLING_EXPORT void renumberCells(const int *old2NewBg, bool check=true); - //some useful methods - MEDCOUPLING_EXPORT void getNodeGridStructure(int *res) const; - //serialisation-unserialization - MEDCOUPLING_EXPORT void getTinySerializationInformation(std::vector& tinyInfoD, std::vector& tinyInfo, std::vector& littleStrings) const; - MEDCOUPLING_EXPORT void resizeForUnserialization(const std::vector& tinyInfo, DataArrayInt *a1, DataArrayDouble *a2, std::vector& littleStrings) const; - MEDCOUPLING_EXPORT void serialize(DataArrayInt *&a1, DataArrayDouble *&a2) const; - MEDCOUPLING_EXPORT void unserialization(const std::vector& tinyInfoD, const std::vector& tinyInfo, const DataArrayInt *a1, DataArrayDouble *a2, - const std::vector& littleStrings); - MEDCOUPLING_EXPORT void reprQuickOverview(std::ostream& stream) const; - MEDCOUPLING_EXPORT std::string getVTKFileExtension() const; - private: - void getMeasureFieldMeshDim1(bool isAbs, MEDCouplingFieldDouble *field) const; - void getMeasureFieldMeshDim2(bool isAbs, MEDCouplingFieldDouble *field) const; - void getMeasureFieldMeshDim3(bool isAbs, MEDCouplingFieldDouble *field) const; - 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, DataArrayByte *byteData) const; - std::string getVTKDataSetType() const; - private: - MEDCouplingAutoRefCountObjectPtr _coords; - std::vector _structure; - }; -} - -#endif diff --git a/src/MEDCoupling/MEDCouplingDefinitionTime.cxx b/src/MEDCoupling/MEDCouplingDefinitionTime.cxx deleted file mode 100644 index bbc7021d0..000000000 --- a/src/MEDCoupling/MEDCouplingDefinitionTime.cxx +++ /dev/null @@ -1,622 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 -// 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 "MEDCouplingDefinitionTime.hxx" -#include "MEDCouplingFieldDouble.hxx" - -#include - -using namespace ParaMEDMEM; - -const double MEDCouplingDefinitionTime::EPS_DFT=1e-15; - -MEDCouplingDefinitionTimeSlice *MEDCouplingDefinitionTimeSlice::New(const MEDCouplingFieldDouble *f, int meshId, const std::vector& arrId, int fieldId) -{ - static const char msg[]="TimeSlice::New : mismatch of arrays number of a fieldDouble and its policy !!! Internal error !!!"; - if(!f) - throw INTERP_KERNEL::Exception("MEDCouplingDefinitionTimeSlice::New : empty field !"); - switch(f->getTimeDiscretization()) - { - case ONE_TIME: - { - if(arrId.size()!=1) - throw INTERP_KERNEL::Exception(msg); - return new MEDCouplingDefinitionTimeSliceInst(f,meshId,arrId[0],fieldId); - } - case CONST_ON_TIME_INTERVAL: - { - if(arrId.size()!=1) - throw INTERP_KERNEL::Exception(msg); - return new MEDCouplingDefinitionTimeSliceCstOnTI(f,meshId,arrId[0],fieldId); - } - case LINEAR_TIME: - { - if(arrId.size()!=2) - throw INTERP_KERNEL::Exception(msg); - return new MEDCouplingDefinitionTimeSliceLT(f,meshId,arrId[0],arrId[1],fieldId); - } - case NO_TIME: - throw INTERP_KERNEL::Exception("Invalide time discretization ! NO_TIME ! Impossible to build a definition time slice !"); - default: - throw INTERP_KERNEL::Exception("Invalide time discretization : Not recognized !"); - } -} - -MEDCouplingDefinitionTimeSlice *MEDCouplingDefinitionTimeSlice::New(TypeOfTimeDiscretization type, const std::vector& tiI, const std::vector& tiD) -{ - switch(type) - { - case ONE_TIME: - return MEDCouplingDefinitionTimeSliceInst::New(tiI,tiD); - case CONST_ON_TIME_INTERVAL: - return MEDCouplingDefinitionTimeSliceCstOnTI::New(tiI,tiD); - case LINEAR_TIME: - return MEDCouplingDefinitionTimeSliceLT::New(tiI,tiD); - default: - throw INTERP_KERNEL::Exception("MEDCouplingDefinitionTimeSlice::New : unrecognized time discretization type !"); - } -} - -bool MEDCouplingDefinitionTimeSlice::isEqual(const MEDCouplingDefinitionTimeSlice& other, double eps) const -{ - if(_mesh_id!=other._mesh_id) - return false; - if(_array_id!=other._array_id) - return false; - if(_field_id!=other._field_id) - return false; - return true; -} - -int MEDCouplingDefinitionTimeSlice::getStartId() const -{ - return _array_id; -} - -int MEDCouplingDefinitionTimeSlice::getEndId() const -{ - return _array_id; -} - -void MEDCouplingDefinitionTimeSlice::appendRepr(std::ostream& stream) const -{ - stream << " *** MeshId : " << _mesh_id << " ArrayId : " << _array_id; -} - -MEDCouplingDefinitionTimeSlice::MEDCouplingDefinitionTimeSlice(const MEDCouplingFieldDouble *f, int meshId, int arrId, int fieldId):_mesh_id(meshId),_array_id(arrId),_field_id(fieldId) -{ - int tmp1,tmp2; - double t1=f->getStartTime(tmp1,tmp2); - double t2=f->getEndTime(tmp1,tmp2); - if(t2 MEDCouplingDefinitionTimeSlice::getDirectChildrenWithNull() const -{ - return std::vector(); -} - -bool MEDCouplingDefinitionTimeSlice::isFullyIncludedInMe(const MEDCouplingDefinitionTimeSlice *other, double eps) const -{ - double t1=getStartTime(); - double t2=getEndTime(); - double o1=other->getStartTime(); - double o2=other->getEndTime(); - return o1>t1-eps && o2getStartTime(); - double o2=other->getEndTime(); - return (o1t2-eps && o2>t2-eps); -} - -bool MEDCouplingDefinitionTimeSlice::isAfterMe(const MEDCouplingDefinitionTimeSlice *other, double eps) const -{ - double t2=getEndTime(); - double o1=other->getStartTime(); - double o2=other->getEndTime(); - return (o1>t2-eps && o2>t2-eps); -} - -bool MEDCouplingDefinitionTimeSlice::isBeforeMe(const MEDCouplingDefinitionTimeSlice *other, double eps) const -{ - double t1=getStartTime(); - double o1=other->getStartTime(); - double o2=other->getEndTime(); - return (o1& tiI, const std::vector& tiD) -{ - MEDCouplingDefinitionTimeSliceInst *ret=new MEDCouplingDefinitionTimeSliceInst; - ret->unserialize(tiI,tiD); - return ret; -} - -void MEDCouplingDefinitionTimeSliceInst::getTinySerializationInformation(std::vector& tiI, std::vector& tiD) const -{ - tiI.resize(3); - tiI[0]=_mesh_id; tiI[1]=_array_id; tiI[2]=_field_id; - tiD.resize(1); - tiD[0]=_instant; -} - -void MEDCouplingDefinitionTimeSliceInst::unserialize(const std::vector& tiI, const std::vector& tiD) -{ - _mesh_id=tiI[0]; _array_id=tiI[1]; _field_id=tiI[2]; - _instant=tiD[0]; -} - -TypeOfTimeDiscretization MEDCouplingDefinitionTimeSliceInst::getTimeType() const -{ - return ONE_TIME; -} - -MEDCouplingDefinitionTimeSlice *MEDCouplingDefinitionTimeSliceInst::copy() const -{ - return new MEDCouplingDefinitionTimeSliceInst(*this); -} - -bool MEDCouplingDefinitionTimeSliceInst::isEqual(const MEDCouplingDefinitionTimeSlice& other, double eps) const -{ - if(!MEDCouplingDefinitionTimeSlice::isEqual(other,eps)) - return false; - const MEDCouplingDefinitionTimeSliceInst *otherC=dynamic_cast(&other); - if(!otherC) - return false; - return fabs(otherC->_instant-_instant)& ret) const -{ - ret.resize(1); - ret[0]=_instant; -} - -void MEDCouplingDefinitionTimeSliceInst::getIdsOnTime(double tm, double eps, int& meshId, int& arrId, int& arrIdInField, int& fieldId) const -{ - meshId=_mesh_id; - arrId=_array_id; - arrIdInField=0; - fieldId=_field_id; -} - -bool MEDCouplingDefinitionTimeSliceInst::isContaining(double tmp, double eps) const -{ - return fabs(tmp-_instant)getStartTime(tmp1,tmp2); - double t2=f->getEndTime(tmp1,tmp2); - double eps=f->getTimeTolerance(); - if(fabs(t1-t2)>eps) - throw INTERP_KERNEL::Exception("MEDCouplingDefinitionTimeSliceInst : times differs in this"); - _instant=t1; -} - -MEDCouplingDefinitionTimeSliceCstOnTI *MEDCouplingDefinitionTimeSliceCstOnTI::New(const std::vector& tiI, const std::vector& tiD) -{ - MEDCouplingDefinitionTimeSliceCstOnTI *ret=new MEDCouplingDefinitionTimeSliceCstOnTI; - ret->unserialize(tiI,tiD); - return ret; -} - -MEDCouplingDefinitionTimeSlice *MEDCouplingDefinitionTimeSliceCstOnTI::copy() const -{ - return new MEDCouplingDefinitionTimeSliceCstOnTI(*this); -} - -bool MEDCouplingDefinitionTimeSliceCstOnTI::isEqual(const MEDCouplingDefinitionTimeSlice& other, double eps) const -{ - if(!MEDCouplingDefinitionTimeSlice::isEqual(other,eps)) - return false; - const MEDCouplingDefinitionTimeSliceCstOnTI *otherC=dynamic_cast(&other); - if(!otherC) - return false; - if(fabs(otherC->_start-_start)>eps) - return false; - return fabs(otherC->_end-_end)& ret) const -{ - ret.resize(1); - ret[0]=(_start+_end)/2.; -} - -void MEDCouplingDefinitionTimeSliceCstOnTI::getIdsOnTime(double tm, double eps, int& meshId, int& arrId, int& arrIdInField, int& fieldId) const -{ - meshId=_mesh_id; - arrId=_array_id; - arrIdInField=0; - fieldId=_field_id; -} - -bool MEDCouplingDefinitionTimeSliceCstOnTI::isContaining(double tmp, double eps) const -{ - return _start-epstmp; -} - -void MEDCouplingDefinitionTimeSliceCstOnTI::appendRepr(std::ostream& stream) const -{ - stream << "Constant on time interval [" << _start << "," << _end << "]"; - MEDCouplingDefinitionTimeSlice::appendRepr(stream); -} - -double MEDCouplingDefinitionTimeSliceCstOnTI::getStartTime() const -{ - return _start; -} - -double MEDCouplingDefinitionTimeSliceCstOnTI::getEndTime() const -{ - return _end; -} - -void MEDCouplingDefinitionTimeSliceCstOnTI::getTinySerializationInformation(std::vector& tiI, std::vector& tiD) const -{ - tiI.resize(3); - tiI[0]=_mesh_id; tiI[1]=_array_id; tiI[2]=_field_id; - tiD.resize(2); - tiD[0]=_start; tiD[1]=_end; -} - -void MEDCouplingDefinitionTimeSliceCstOnTI::unserialize(const std::vector& tiI, const std::vector& tiD) -{ - _mesh_id=tiI[0]; _array_id=tiI[1]; _field_id=tiI[2]; - _start=tiD[0]; _end=tiD[1]; -} - -TypeOfTimeDiscretization MEDCouplingDefinitionTimeSliceCstOnTI::getTimeType() const -{ - return CONST_ON_TIME_INTERVAL; -} - -MEDCouplingDefinitionTimeSliceCstOnTI::MEDCouplingDefinitionTimeSliceCstOnTI(const MEDCouplingFieldDouble *f, int meshId, int arrId, int fieldId):MEDCouplingDefinitionTimeSlice(f,meshId,arrId,fieldId) -{ - int tmp1,tmp2; - double t1=f->getStartTime(tmp1,tmp2); - double t2=f->getEndTime(tmp1,tmp2); - _start=t1; - _end=t2; -} - -MEDCouplingDefinitionTimeSliceLT *MEDCouplingDefinitionTimeSliceLT::New(const std::vector& tiI, const std::vector& tiD) -{ - MEDCouplingDefinitionTimeSliceLT *ret=new MEDCouplingDefinitionTimeSliceLT; - ret->unserialize(tiI,tiD); - return ret; -} - -MEDCouplingDefinitionTimeSlice *MEDCouplingDefinitionTimeSliceLT::copy() const -{ - return new MEDCouplingDefinitionTimeSliceLT(*this); -} - -bool MEDCouplingDefinitionTimeSliceLT::isEqual(const MEDCouplingDefinitionTimeSlice& other, double eps) const -{ - if(!MEDCouplingDefinitionTimeSlice::isEqual(other,eps)) - return false; - const MEDCouplingDefinitionTimeSliceLT *otherC=dynamic_cast(&other); - if(!otherC) - return false; - if(_array_id_end!=otherC->_array_id_end) - return false; - if(fabs(otherC->_start-_start)>eps) - return false; - return fabs(otherC->_end-_end)& ret) const -{ - ret.resize(2); - ret[0]=_start; - ret[1]=_end; -} - -void MEDCouplingDefinitionTimeSliceLT::getIdsOnTime(double tm, double eps, int& meshId, int& arrId, int& arrIdInField, int& fieldId) const -{ - if(fabs(tm-_start)tmp; -} - -void MEDCouplingDefinitionTimeSliceLT::appendRepr(std::ostream& stream) const -{ - stream << "Linear on time interval [" << _start << "," << _end << "]"; - MEDCouplingDefinitionTimeSlice::appendRepr(stream); - stream << " EndArrayId : " << _array_id_end; -} - -double MEDCouplingDefinitionTimeSliceLT::getStartTime() const -{ - return _start; -} - -double MEDCouplingDefinitionTimeSliceLT::getEndTime() const -{ - return _end; -} - -int MEDCouplingDefinitionTimeSliceLT::getEndId() const -{ - return _array_id_end; -} - -void MEDCouplingDefinitionTimeSliceLT::getTinySerializationInformation(std::vector& tiI, std::vector& tiD) const -{ - tiI.resize(4); - tiI[0]=_mesh_id; tiI[1]=_array_id; tiI[2]=_field_id; tiI[3]=_array_id_end; - tiD.resize(2); - tiD[0]=_start; tiD[1]=_end; -} - -void MEDCouplingDefinitionTimeSliceLT::unserialize(const std::vector& tiI, const std::vector& tiD) -{ - _mesh_id=tiI[0]; _array_id=tiI[1]; _field_id=tiI[2]; _array_id_end=tiI[3]; - _start=tiD[0]; _end=tiD[1]; -} - -TypeOfTimeDiscretization MEDCouplingDefinitionTimeSliceLT::getTimeType() const -{ - return LINEAR_TIME; -} - -MEDCouplingDefinitionTimeSliceLT::MEDCouplingDefinitionTimeSliceLT(const MEDCouplingFieldDouble *f, int meshId, int arrId, int arr2Id, int fieldId):MEDCouplingDefinitionTimeSlice(f,meshId,arrId,fieldId),_array_id_end(arr2Id) -{ - int tmp1,tmp2; - double t1=f->getStartTime(tmp1,tmp2); - double t2=f->getEndTime(tmp1,tmp2); - _start=t1; - _end=t2; -} - -MEDCouplingDefinitionTime::MEDCouplingDefinitionTime():_eps(EPS_DFT) -{ -} - -MEDCouplingDefinitionTime::MEDCouplingDefinitionTime(const std::vector& fs, const std::vector& meshRefs, const std::vector >& arrRefs) -{ - std::size_t sz=fs.size(); - if(sz!=arrRefs.size()) - throw INTERP_KERNEL::Exception("MEDCouplingDefinitionTime constructor : internal error ! should never happen !"); - _slices.resize(sz); - for(std::size_t i=0;igetTimeTolerance(); - for(std::size_t i=1;iisAfterMe(_slices[i],_eps)) - throw INTERP_KERNEL::Exception("MEDCouplingDefinitionTime constructors : the sequences of fields does NOT defines a stricly ascendant monotonic time sequence !"); - // double t1=ref->getEndTime(); - // double t2=_slices[i]->getStartTime(); - // if(fabs(t1-t2)<_eps) - // if(ref->getEndId() != _slices[i]->getStartId()) - // throw INTERP_KERNEL::Exception("MEDCouplingDefinitionTime constructor : 2 slices refers to the same time and underlying arrays differs !"); - ref=_slices[i]; - } -} - -std::size_t MEDCouplingDefinitionTime::getHeapMemorySizeWithoutChildren() const -{ - return _slices.capacity()*(sizeof(MEDCouplingDefinitionTimeSlice)+sizeof(int)); -} - -std::vector MEDCouplingDefinitionTime::getDirectChildrenWithNull() const -{ - return std::vector(); -} - -void MEDCouplingDefinitionTime::assign(const MEDCouplingDefinitionTime& other) -{ - std::size_t sz=other._slices.size(); - _slices.resize(sz); - for(std::size_t i=0;icopy(); -} - -bool MEDCouplingDefinitionTime::isEqual(const MEDCouplingDefinitionTime& other) const -{ - std::size_t sz=_slices.size(); - if(sz!=other._slices.size()) - return false; - for(std::size_t i=0;iisEqual(*other._slices[i],_eps)) - return false; - return true; -} - -void MEDCouplingDefinitionTime::getIdsOnTimeRight(double tm, int& meshId, int& arrId, int& arrIdInField, int& fieldId) const -{ - std::vector meshIds; - std::vector arrIds; - std::vector arrIdsInField; - std::vector fieldIds; - getIdsOnTime(tm,meshIds,arrIds,arrIdsInField,fieldIds); - meshId=meshIds.back(); - arrId=arrIds.back(); - arrIdInField=arrIdsInField.back(); - fieldId=fieldIds.back(); -} - -void MEDCouplingDefinitionTime::getIdsOnTimeLeft(double tm, int& meshId, int& arrId, int& arrIdInField, int& fieldId) const -{ - std::vector meshIds; - std::vector arrIds; - std::vector arrIdsInField; - std::vector fieldIds; - getIdsOnTime(tm,meshIds,arrIds,arrIdsInField,fieldIds); - meshId=meshIds.front(); - arrId=arrIds.front(); - arrIdInField=arrIdsInField.front(); - fieldId=fieldIds.front(); -} - -void MEDCouplingDefinitionTime::getIdsOnTime(double tm, std::vector& meshIds, std::vector& arrIds, std::vector& arrIdsInField, std::vector& fieldIds) const -{ - std::vector ids; - int id=0; - for(std::vector< MEDCouplingAutoRefCountObjectPtr >::const_iterator it=_slices.begin();it!=_slices.end();it++,id++) - if((*it)->isContaining(tm,_eps)) - ids.push_back(id); - if(ids.empty()) - throw INTERP_KERNEL::Exception("MEDCouplingDefinitionTime::getIdsOnTime : No matching slice for such time !"); - std::size_t sz=ids.size(); - if(sz>2) - throw INTERP_KERNEL::Exception("MEDCouplingDefinitionTime::getIdsOnTime : Too many slices match this time !"); - // - meshIds.resize(sz); - arrIds.resize(sz); - arrIdsInField.resize(sz); - fieldIds.resize(sz); - for(std::size_t i=0;igetIdsOnTime(tm,_eps,meshIds[i],arrIds[i],arrIdsInField[i],fieldIds[i]); -} - -std::vector MEDCouplingDefinitionTime::getHotSpotsTime() const -{ - std::vector ret; - for(std::vector< MEDCouplingAutoRefCountObjectPtr >::const_iterator it=_slices.begin();it!=_slices.end();it++) - { - std::vector tmp; - (*it)->getHotSpotsTime(tmp); - if(!ret.empty()) - { - if(fabs(ret.back()-tmp.front())>_eps) - ret.insert(ret.end(),tmp.begin(),tmp.end()); - else - ret.insert(ret.end(),tmp.begin()+1,tmp.end()); - } - else - ret.insert(ret.end(),tmp.begin(),tmp.end()); - } - return ret; -} - -void MEDCouplingDefinitionTime::appendRepr(std::ostream& stream) const -{ - stream << "Time definition :\n"; - for(std::vector< MEDCouplingAutoRefCountObjectPtr >::const_iterator it=_slices.begin();it!=_slices.end();it++) - { - stream << " - "; - (*it)->appendRepr(stream); - stream << std::endl; - } -} - -void MEDCouplingDefinitionTime::getTinySerializationInformation(std::vector& tinyInfoI, std::vector& tinyInfoD) const -{ - int sz=(int)_slices.size(); - tinyInfoD.resize(1); - tinyInfoD[0]=_eps; - tinyInfoI.resize(3*sz+2); - tinyInfoI[0]=sz; - std::vector coreData; - for(int i=0;i tmp1; - std::vector tmp2; - tinyInfoI[i+2]=(int)_slices[i]->getTimeType(); - _slices[i]->getTinySerializationInformation(tmp1,tmp2); - tinyInfoI[i+sz+2]=(int)tmp1.size(); - tinyInfoI[i+2*sz+2]=(int)tmp2.size(); - coreData.insert(coreData.end(),tmp1.begin(),tmp1.end()); - tinyInfoD.insert(tinyInfoD.end(),tmp2.begin(),tmp2.end()); - } - tinyInfoI[1]=(int)coreData.size(); - tinyInfoI.insert(tinyInfoI.end(),coreData.begin(),coreData.end()); -} - -void MEDCouplingDefinitionTime::unserialize(const std::vector& tinyInfoI, const std::vector& tinyInfoD) -{ - int sz=tinyInfoI[0]; - _slices.resize(sz); - _eps=tinyInfoD[0]; - int offset1=0; - int offset2=1; - for(int i=0;i tmp1(tinyInfoI.begin()+3*sz+2+offset1,tinyInfoI.begin()+3*sz+2+offset1+sz1); - std::vector tmp2(tinyInfoD.begin()+offset2,tinyInfoD.begin()+offset2+sz2); - MEDCouplingDefinitionTimeSlice *pt=MEDCouplingDefinitionTimeSlice::New(ty,tmp1,tmp2); - _slices[i]=pt; - offset1+=sz1; - offset2+=sz2; - } -} - diff --git a/src/MEDCoupling/MEDCouplingDefinitionTime.hxx b/src/MEDCoupling/MEDCouplingDefinitionTime.hxx deleted file mode 100644 index ab2536b70..000000000 --- a/src/MEDCoupling/MEDCouplingDefinitionTime.hxx +++ /dev/null @@ -1,167 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 -// 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_MEDCOUPLINGDEFINITIONTIME_HXX__ -#define __PARAMEDMEM_MEDCOUPLINGDEFINITIONTIME_HXX__ - -#include "MEDCouplingRefCountObject.hxx" -#include "MEDCouplingAutoRefCountObjectPtr.hxx" - -#include "InterpKernelException.hxx" - -#include -#include - -namespace ParaMEDMEM -{ - class MEDCouplingFieldDouble; - - class MEDCouplingDefinitionTimeSlice : public RefCountObject - { - public: - MEDCOUPLING_EXPORT static MEDCouplingDefinitionTimeSlice *New(const MEDCouplingFieldDouble *f, int meshId, const std::vector& arrId, int fieldId); - MEDCOUPLING_EXPORT static MEDCouplingDefinitionTimeSlice *New(TypeOfTimeDiscretization type, const std::vector& tiI, const std::vector& tiD); - MEDCOUPLING_EXPORT int getArrayId() const { return _array_id; } - MEDCOUPLING_EXPORT virtual MEDCouplingDefinitionTimeSlice *copy() const = 0; - MEDCOUPLING_EXPORT virtual bool isEqual(const MEDCouplingDefinitionTimeSlice& other, double eps) const; - MEDCOUPLING_EXPORT virtual void getHotSpotsTime(std::vector& ret) const = 0; - MEDCOUPLING_EXPORT virtual void getIdsOnTime(double tm, double eps, int& meshId, int& arrId, int& arrIdInField, int& fieldId) const = 0; - MEDCOUPLING_EXPORT virtual bool isContaining(double tmp, double eps) const = 0; - MEDCOUPLING_EXPORT virtual int getStartId() const; - MEDCOUPLING_EXPORT virtual int getEndId() const; - MEDCOUPLING_EXPORT virtual void appendRepr(std::ostream& stream) const; - MEDCOUPLING_EXPORT virtual double getStartTime() const = 0; - MEDCOUPLING_EXPORT virtual double getEndTime() const = 0; - MEDCOUPLING_EXPORT virtual void getTinySerializationInformation(std::vector& tiI, std::vector& tiD) const = 0; - MEDCOUPLING_EXPORT virtual TypeOfTimeDiscretization getTimeType() const = 0; - MEDCOUPLING_EXPORT std::size_t getHeapMemorySizeWithoutChildren() const; - MEDCOUPLING_EXPORT std::vector getDirectChildrenWithNull() const; - MEDCOUPLING_EXPORT bool isFullyIncludedInMe(const MEDCouplingDefinitionTimeSlice *other, double eps) const; - MEDCOUPLING_EXPORT bool isOverllapingWithMe(const MEDCouplingDefinitionTimeSlice *other, double eps) const; - MEDCOUPLING_EXPORT bool isAfterMe(const MEDCouplingDefinitionTimeSlice *other, double eps) const; - MEDCOUPLING_EXPORT bool isBeforeMe(const MEDCouplingDefinitionTimeSlice *other, double eps) const; - protected: - MEDCOUPLING_EXPORT MEDCouplingDefinitionTimeSlice() { } - MEDCOUPLING_EXPORT MEDCouplingDefinitionTimeSlice(const MEDCouplingFieldDouble *f, int meshId, int arrId, int fieldId); - protected: - int _mesh_id; - int _array_id; - int _field_id; - }; - - class MEDCouplingDefinitionTimeSliceInst : public MEDCouplingDefinitionTimeSlice - { - public: - static MEDCouplingDefinitionTimeSliceInst *New(const std::vector& tiI, const std::vector& tiD); - MEDCouplingDefinitionTimeSlice *copy() const; - bool isEqual(const MEDCouplingDefinitionTimeSlice& other, double eps) const; - void getHotSpotsTime(std::vector& ret) const; - void getIdsOnTime(double tm, double eps, int& meshId, int& arrId, int& arrIdInField, int& fieldId) const; - bool isContaining(double tmp, double eps) const; - void appendRepr(std::ostream& stream) const; - double getStartTime() const; - double getEndTime() const; - void getTinySerializationInformation(std::vector& tiI, std::vector& tiD) const; - void unserialize(const std::vector& tiI, const std::vector& tiD); - TypeOfTimeDiscretization getTimeType() const; - public: - MEDCouplingDefinitionTimeSliceInst(const MEDCouplingFieldDouble *f, int meshId, int arrId, int fieldId); - protected: - MEDCouplingDefinitionTimeSliceInst() { } - protected: - double _instant; - }; - - class MEDCouplingDefinitionTimeSliceCstOnTI : public MEDCouplingDefinitionTimeSlice - { - public: - static MEDCouplingDefinitionTimeSliceCstOnTI *New(const std::vector& tiI, const std::vector& tiD); - MEDCouplingDefinitionTimeSlice *copy() const; - bool isEqual(const MEDCouplingDefinitionTimeSlice& other, double eps) const; - void getHotSpotsTime(std::vector& ret) const; - void getIdsOnTime(double tm, double eps, int& meshId, int& arrId, int& arrIdInField, int& fieldId) const; - bool isContaining(double tmp, double eps) const; - void appendRepr(std::ostream& stream) const; - double getStartTime() const; - double getEndTime() const; - void getTinySerializationInformation(std::vector& tiI, std::vector& tiD) const; - void unserialize(const std::vector& tiI, const std::vector& tiD); - TypeOfTimeDiscretization getTimeType() const; - public: - MEDCouplingDefinitionTimeSliceCstOnTI(const MEDCouplingFieldDouble *f, int meshId, int arrId, int fieldId); - protected: - MEDCouplingDefinitionTimeSliceCstOnTI() { } - protected: - double _start; - double _end; - }; - - class MEDCouplingDefinitionTimeSliceLT : public MEDCouplingDefinitionTimeSlice - { - public: - static MEDCouplingDefinitionTimeSliceLT *New(const std::vector& tiI, const std::vector& tiD); - MEDCouplingDefinitionTimeSlice *copy() const; - bool isEqual(const MEDCouplingDefinitionTimeSlice& other, double eps) const; - void getHotSpotsTime(std::vector& ret) const; - void getIdsOnTime(double tm, double eps, int& meshId, int& arrId, int& arrIdInField, int& fieldId) const; - bool isContaining(double tmp, double eps) const; - void appendRepr(std::ostream& stream) const; - double getStartTime() const; - double getEndTime() const; - int getEndId() const; - void getTinySerializationInformation(std::vector& tiI, std::vector& tiD) const; - void unserialize(const std::vector& tiI, const std::vector& tiD); - TypeOfTimeDiscretization getTimeType() const; - public: - MEDCouplingDefinitionTimeSliceLT(const MEDCouplingFieldDouble *f, int meshId, int arrId, int arr2Id, int fieldId); - protected: - MEDCouplingDefinitionTimeSliceLT() { } - protected: - int _array_id_end; - double _start; - double _end; - }; - - class MEDCouplingDefinitionTime - { - public: - MEDCOUPLING_EXPORT MEDCouplingDefinitionTime(); - MEDCOUPLING_EXPORT MEDCouplingDefinitionTime(const std::vector& fs, const std::vector& meshRefs, const std::vector >& arrRefs); - MEDCOUPLING_EXPORT std::size_t getHeapMemorySizeWithoutChildren() const; - MEDCOUPLING_EXPORT std::vector getDirectChildrenWithNull() const; - MEDCOUPLING_EXPORT void assign(const MEDCouplingDefinitionTime& other); - MEDCOUPLING_EXPORT bool isEqual(const MEDCouplingDefinitionTime& other) const; - MEDCOUPLING_EXPORT double getTimeResolution() const { return _eps; } - MEDCOUPLING_EXPORT void getIdsOnTimeRight(double tm, int& meshId, int& arrId, int& arrIdInField, int& fieldId) const; - MEDCOUPLING_EXPORT void getIdsOnTimeLeft(double tm, int& meshId, int& arrId, int& arrIdInField, int& fieldId) const; - MEDCOUPLING_EXPORT void getIdsOnTime(double tm, std::vector& meshIds, std::vector& arrIds, std::vector& arrIdsInField, std::vector& fieldIds) const; - MEDCOUPLING_EXPORT std::vector getHotSpotsTime() const; - MEDCOUPLING_EXPORT void appendRepr(std::ostream& stream) const; - public: - MEDCOUPLING_EXPORT void getTinySerializationInformation(std::vector& tinyInfoI, std::vector& tinyInfoD) const; - MEDCOUPLING_EXPORT void unserialize(const std::vector& tinyInfoI, const std::vector& tinyInfoD); - private: - double _eps; - std::vector< MEDCouplingAutoRefCountObjectPtr > _slices; - static const double EPS_DFT; - }; -} - -#endif diff --git a/src/MEDCoupling/MEDCouplingExtrudedMesh.cxx b/src/MEDCoupling/MEDCouplingExtrudedMesh.cxx deleted file mode 100644 index 3df24b33b..000000000 --- a/src/MEDCoupling/MEDCouplingExtrudedMesh.cxx +++ /dev/null @@ -1,961 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 -// 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 "MEDCouplingExtrudedMesh.hxx" -#include "MEDCouplingUMesh.hxx" -#include "MEDCouplingMemArray.hxx" -#include "MEDCouplingFieldDouble.hxx" -#include "MEDCouplingAutoRefCountObjectPtr.hxx" -#include "CellModel.hxx" - -#include "InterpolationUtils.hxx" - -#include -#include -#include -#include -#include -#include -#include -#include - -using namespace ParaMEDMEM; - -/*! - * Build an extruded mesh instance from 3D and 2D unstructured mesh lying on the \b same \b coords. - * @param mesh3D 3D unstructured mesh. - * @param mesh2D 2D unstructured mesh lying on the same coordinates than mesh3D. \b Warning mesh2D is \b not \b const - * because the mesh is aggregated and potentially modified by rotate or translate method. - * @param cell2DId Id of cell in mesh2D mesh where the computation of 1D mesh will be done. - */ -MEDCouplingExtrudedMesh *MEDCouplingExtrudedMesh::New(const MEDCouplingUMesh *mesh3D, const MEDCouplingUMesh *mesh2D, int cell2DId) -{ - return new MEDCouplingExtrudedMesh(mesh3D,mesh2D,cell2DId); -} - -/*! - * This constructor is here only for unserialisation process. - * This constructor is normally completely useless for end user. - */ -MEDCouplingExtrudedMesh *MEDCouplingExtrudedMesh::New() -{ - return new MEDCouplingExtrudedMesh; -} - -MEDCouplingMeshType MEDCouplingExtrudedMesh::getType() const -{ - return EXTRUDED; -} - -std::size_t MEDCouplingExtrudedMesh::getHeapMemorySizeWithoutChildren() const -{ - return MEDCouplingMesh::getHeapMemorySizeWithoutChildren(); -} - -std::vector MEDCouplingExtrudedMesh::getDirectChildrenWithNull() const -{ - std::vector ret; - ret.push_back(_mesh2D); - ret.push_back(_mesh1D); - ret.push_back(_mesh3D_ids); - return ret; -} - -/*! - * This method copyies all tiny strings from other (name and components name). - * @throw if other and this have not same mesh type. - */ -void MEDCouplingExtrudedMesh::copyTinyStringsFrom(const MEDCouplingMesh *other) -{ - const MEDCouplingExtrudedMesh *otherC=dynamic_cast(other); - if(!otherC) - throw INTERP_KERNEL::Exception("MEDCouplingExtrudedMesh::copyTinyStringsFrom : meshes have not same type !"); - MEDCouplingMesh::copyTinyStringsFrom(other); - _mesh2D->copyTinyStringsFrom(otherC->_mesh2D); - _mesh1D->copyTinyStringsFrom(otherC->_mesh1D); -} - -MEDCouplingExtrudedMesh::MEDCouplingExtrudedMesh(const MEDCouplingUMesh *mesh3D, const MEDCouplingUMesh *mesh2D, int cell2DId) -try:_mesh2D(const_cast(mesh2D)),_mesh1D(MEDCouplingUMesh::New()),_mesh3D_ids(0),_cell_2D_id(cell2DId) -{ - if(_mesh2D!=0) - _mesh2D->incrRef(); - computeExtrusion(mesh3D); - setName(mesh3D->getName()); -} -catch(INTERP_KERNEL::Exception& e) -{ - if(_mesh2D) - _mesh2D->decrRef(); - if(_mesh1D) - _mesh1D->decrRef(); - if(_mesh3D_ids) - _mesh3D_ids->decrRef(); - throw e; -} - -MEDCouplingExtrudedMesh::MEDCouplingExtrudedMesh():_mesh2D(0),_mesh1D(0),_mesh3D_ids(0),_cell_2D_id(-1) -{ -} - -MEDCouplingExtrudedMesh::MEDCouplingExtrudedMesh(const MEDCouplingExtrudedMesh& other, bool deepCopy):MEDCouplingMesh(other),_cell_2D_id(other._cell_2D_id) -{ - if(deepCopy) - { - _mesh2D=other._mesh2D->clone(true); - _mesh1D=other._mesh1D->clone(true); - _mesh3D_ids=other._mesh3D_ids->deepCpy(); - } - else - { - _mesh2D=other._mesh2D; - if(_mesh2D) - _mesh2D->incrRef(); - _mesh1D=other._mesh1D; - if(_mesh1D) - _mesh1D->incrRef(); - _mesh3D_ids=other._mesh3D_ids; - if(_mesh3D_ids) - _mesh3D_ids->incrRef(); - } -} - -int MEDCouplingExtrudedMesh::getNumberOfCells() const -{ - return _mesh2D->getNumberOfCells()*_mesh1D->getNumberOfCells(); -} - -int MEDCouplingExtrudedMesh::getNumberOfNodes() const -{ - return _mesh2D->getNumberOfNodes(); -} - -int MEDCouplingExtrudedMesh::getSpaceDimension() const -{ - return 3; -} - -int MEDCouplingExtrudedMesh::getMeshDimension() const -{ - return 3; -} - -MEDCouplingMesh *MEDCouplingExtrudedMesh::deepCpy() const -{ - return clone(true); -} - -MEDCouplingExtrudedMesh *MEDCouplingExtrudedMesh::clone(bool recDeepCpy) const -{ - return new MEDCouplingExtrudedMesh(*this,recDeepCpy); -} - -bool MEDCouplingExtrudedMesh::isEqualIfNotWhy(const MEDCouplingMesh *other, double prec, std::string& reason) const -{ - if(!other) - throw INTERP_KERNEL::Exception("MEDCouplingExtrudedMesh::isEqualIfNotWhy : input other pointer is null !"); - const MEDCouplingExtrudedMesh *otherC=dynamic_cast(other); - std::ostringstream oss; - if(!otherC) - { - reason="mesh given in input is not castable in MEDCouplingExtrudedMesh !"; - return false; - } - if(!MEDCouplingMesh::isEqualIfNotWhy(other,prec,reason)) - return false; - if(!_mesh2D->isEqualIfNotWhy(otherC->_mesh2D,prec,reason)) - { - reason.insert(0,"Mesh2D unstructured meshes differ : "); - return false; - } - if(!_mesh1D->isEqualIfNotWhy(otherC->_mesh1D,prec,reason)) - { - reason.insert(0,"Mesh1D unstructured meshes differ : "); - return false; - } - if(!_mesh3D_ids->isEqualIfNotWhy(*otherC->_mesh3D_ids,reason)) - { - reason.insert(0,"Mesh3D ids DataArrayInt instances differ : "); - return false; - } - if(_cell_2D_id!=otherC->_cell_2D_id) - { - oss << "Cell 2D id of the two extruded mesh differ : this = " << _cell_2D_id << " other = " << otherC->_cell_2D_id; - reason=oss.str(); - return false; - } - return true; -} - -bool MEDCouplingExtrudedMesh::isEqualWithoutConsideringStr(const MEDCouplingMesh *other, double prec) const -{ - const MEDCouplingExtrudedMesh *otherC=dynamic_cast(other); - if(!otherC) - return false; - if(!_mesh2D->isEqualWithoutConsideringStr(otherC->_mesh2D,prec)) - return false; - if(!_mesh1D->isEqualWithoutConsideringStr(otherC->_mesh1D,prec)) - return false; - if(!_mesh3D_ids->isEqualWithoutConsideringStr(*otherC->_mesh3D_ids)) - return false; - if(_cell_2D_id!=otherC->_cell_2D_id) - return false; - return true; -} - -void MEDCouplingExtrudedMesh::checkDeepEquivalWith(const MEDCouplingMesh *other, int cellCompPol, double prec, - DataArrayInt *&cellCor, DataArrayInt *&nodeCor) const -{ - throw INTERP_KERNEL::Exception("MEDCouplingExtrudedMesh::checkDeepEquivalWith : not implemented yet !"); -} - -void MEDCouplingExtrudedMesh::checkDeepEquivalOnSameNodesWith(const MEDCouplingMesh *other, int cellCompPol, double prec, - DataArrayInt *&cellCor) const -{ - throw INTERP_KERNEL::Exception("MEDCouplingExtrudedMesh::checkDeepEquivalOnSameNodesWith : not implemented yet !"); -} - -INTERP_KERNEL::NormalizedCellType MEDCouplingExtrudedMesh::getTypeOfCell(int cellId) const -{ - const int *ids=_mesh3D_ids->getConstPointer(); - int nbOf3DCells=_mesh3D_ids->getNumberOfTuples(); - const int *where=std::find(ids,ids+nbOf3DCells,cellId); - if(where==ids+nbOf3DCells) - throw INTERP_KERNEL::Exception("Invalid cellId specified >= getNumberOfCells() !"); - int nbOfCells2D=_mesh2D->getNumberOfCells(); - int locId=((int)std::distance(ids,where))%nbOfCells2D; - INTERP_KERNEL::NormalizedCellType tmp=_mesh2D->getTypeOfCell(locId); - return INTERP_KERNEL::CellModel::GetCellModel(tmp).getExtrudedType(); -} - -std::set MEDCouplingExtrudedMesh::getAllGeoTypes() const -{ - std::set ret2D(_mesh2D->getAllGeoTypes()); - std::set ret; - for(std::set::const_iterator it=ret2D.begin();it!=ret2D.end();it++) - ret.insert(INTERP_KERNEL::CellModel::GetCellModel(*it).getExtrudedType()); - return ret; -} - -DataArrayInt *MEDCouplingExtrudedMesh::giveCellsWithType(INTERP_KERNEL::NormalizedCellType type) const -{ - 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 -{ - 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 -{ - 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()); -} - -DataArrayInt *MEDCouplingExtrudedMesh::computeEffectiveNbOfNodesPerCell() const -{ - return computeNbOfNodesPerCell(); -} - -int MEDCouplingExtrudedMesh::getNumberOfCellsWithType(INTERP_KERNEL::NormalizedCellType type) const -{ - int ret=0; - int nbOfCells2D=_mesh2D->getNumberOfCells(); - for(int i=0;igetTypeOfCell(i); - if(INTERP_KERNEL::CellModel::GetCellModel(t).getExtrudedType()==type) - ret++; - } - return ret*_mesh1D->getNumberOfCells(); -} - -void MEDCouplingExtrudedMesh::getNodeIdsOfCell(int cellId, std::vector& conn) const -{ - int nbOfCells2D=_mesh2D->getNumberOfCells(); - int nbOfNodes2D=_mesh2D->getNumberOfNodes(); - int locId=cellId%nbOfCells2D; - int lev=cellId/nbOfCells2D; - std::vector tmp,tmp2; - _mesh2D->getNodeIdsOfCell(locId,tmp); - tmp2=tmp; - std::transform(tmp.begin(),tmp.end(),tmp.begin(),std::bind2nd(std::plus(),nbOfNodes2D*lev)); - std::transform(tmp2.begin(),tmp2.end(),tmp2.begin(),std::bind2nd(std::plus(),nbOfNodes2D*(lev+1))); - conn.insert(conn.end(),tmp.begin(),tmp.end()); - conn.insert(conn.end(),tmp2.begin(),tmp2.end()); -} - -void MEDCouplingExtrudedMesh::getCoordinatesOfNode(int nodeId, std::vector& coo) const -{ - int nbOfNodes2D=_mesh2D->getNumberOfNodes(); - int locId=nodeId%nbOfNodes2D; - int lev=nodeId/nbOfNodes2D; - std::vector tmp,tmp2; - _mesh2D->getCoordinatesOfNode(locId,tmp); - tmp2=tmp; - int spaceDim=_mesh1D->getSpaceDimension(); - const double *z=_mesh1D->getCoords()->getConstPointer(); - std::transform(tmp.begin(),tmp.end(),z+lev*spaceDim,tmp.begin(),std::plus()); - std::transform(tmp2.begin(),tmp2.end(),z+(lev+1)*spaceDim,tmp2.begin(),std::plus()); - coo.insert(coo.end(),tmp.begin(),tmp.end()); - coo.insert(coo.end(),tmp2.begin(),tmp2.end()); -} - -std::string MEDCouplingExtrudedMesh::simpleRepr() const -{ - std::ostringstream ret; - ret << "3D Extruded mesh from a 2D Surf 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 << "Cell id where 1D mesh has been deduced : " << _cell_2D_id << "\n"; - ret << "Number of cells : " << getNumberOfCells() << "(" << _mesh2D->getNumberOfCells() << "x" << _mesh1D->getNumberOfCells() << ")\n"; - ret << "1D Mesh info : _____________________\n\n\n"; - ret << _mesh1D->simpleRepr(); - ret << "\n\n\n2D Mesh info : _____________________\n\n\n" << _mesh2D->simpleRepr() << "\n\n\n"; - return ret.str(); -} - -std::string MEDCouplingExtrudedMesh::advancedRepr() const -{ - std::ostringstream ret; - ret << "3D Extruded mesh from a 2D Surf 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 << "Cell id where 1D mesh has been deduced : " << _cell_2D_id << "\n"; - ret << "Number of cells : " << getNumberOfCells() << "(" << _mesh2D->getNumberOfCells() << "x" << _mesh1D->getNumberOfCells() << ")\n"; - ret << "1D Mesh info : _____________________\n\n\n"; - ret << _mesh1D->advancedRepr(); - ret << "\n\n\n2D Mesh info : _____________________\n\n\n" << _mesh2D->advancedRepr() << "\n\n\n"; - ret << "3D cell ids per level :\n"; - return ret.str(); -} - -void MEDCouplingExtrudedMesh::checkCoherency() const -{ -} - -void MEDCouplingExtrudedMesh::checkCoherency1(double eps) const -{ - checkCoherency(); -} - -void MEDCouplingExtrudedMesh::checkCoherency2(double eps) const -{ - checkCoherency1(eps); -} - -void MEDCouplingExtrudedMesh::getBoundingBox(double *bbox) const -{ - double bbox2D[6]; - _mesh2D->getBoundingBox(bbox2D); - const double *nodes1D=_mesh1D->getCoords()->getConstPointer(); - int nbOfNodes1D=_mesh1D->getNumberOfNodes(); - double bbox1DMin[3],bbox1DMax[3],tmp[3]; - std::fill(bbox1DMin,bbox1DMin+3,std::numeric_limits::max()); - std::fill(bbox1DMax,bbox1DMax+3,-(std::numeric_limits::max())); - for(int i=0;i(std::min)); - std::transform(nodes1D+3*i,nodes1D+3*(i+1),bbox1DMax,bbox1DMax,static_cast(std::max)); - } - std::transform(bbox1DMax,bbox1DMax+3,bbox1DMin,tmp,std::minus()); - int id=(int)std::distance(tmp,std::max_element(tmp,tmp+3)); - bbox[0]=bbox1DMin[0]; bbox[1]=bbox1DMax[0]; - bbox[2]=bbox1DMin[1]; bbox[3]=bbox1DMax[1]; - bbox[4]=bbox1DMin[2]; bbox[5]=bbox1DMax[2]; - bbox[2*id+1]+=tmp[id]; -} - -void MEDCouplingExtrudedMesh::updateTime() const -{ - if(_mesh2D) - { - updateTimeWith(*_mesh2D); - } - if(_mesh1D) - { - updateTimeWith(*_mesh1D); - } -} - -void MEDCouplingExtrudedMesh::renumberCells(const int *old2NewBg, bool check) -{ - throw INTERP_KERNEL::Exception("Functionnality of renumbering cells unavailable for ExtrudedMesh"); -} - -MEDCouplingUMesh *MEDCouplingExtrudedMesh::build3DUnstructuredMesh() const -{ - MEDCouplingUMesh *ret=_mesh2D->buildExtrudedMesh(_mesh1D,0); - const int *renum=_mesh3D_ids->getConstPointer(); - ret->renumberCells(renum,false); - ret->setName(getName()); - return ret; -} - -MEDCouplingUMesh *MEDCouplingExtrudedMesh::buildUnstructured() const -{ - return build3DUnstructuredMesh(); -} - -MEDCouplingFieldDouble *MEDCouplingExtrudedMesh::getMeasureField(bool) const -{ - std::string name="MeasureOfMesh_"; - name+=getName(); - MEDCouplingFieldDouble *ret2D=_mesh2D->getMeasureField(true); - MEDCouplingFieldDouble *ret1D=_mesh1D->getMeasureField(true); - const double *ret2DPtr=ret2D->getArray()->getConstPointer(); - const double *ret1DPtr=ret1D->getArray()->getConstPointer(); - int nbOf2DCells=_mesh2D->getNumberOfCells(); - int nbOf1DCells=_mesh1D->getNumberOfCells(); - int nbOf3DCells=nbOf2DCells*nbOf1DCells; - const int *renum=_mesh3D_ids->getConstPointer(); - 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(); - for(int i=0;isetArray(da); - da->decrRef(); - ret->setName(name); - ret2D->decrRef(); - ret1D->decrRef(); - return ret; -} - -MEDCouplingFieldDouble *MEDCouplingExtrudedMesh::getMeasureFieldOnNode(bool isAbs) const -{ - //not implemented yet - return 0; -} - -MEDCouplingFieldDouble *MEDCouplingExtrudedMesh::buildOrthogonalField() const -{ - throw INTERP_KERNEL::Exception("MEDCouplingExtrudedMesh::buildOrthogonalField : This method has no sense for MEDCouplingExtrudedMesh that is 3D !"); -} - -int MEDCouplingExtrudedMesh::getCellContainingPoint(const double *pos, double eps) const -{ - throw INTERP_KERNEL::Exception("MEDCouplingExtrudedMesh::getCellContainingPoint : not implemented yet !"); -} - -MEDCouplingExtrudedMesh::~MEDCouplingExtrudedMesh() -{ - if(_mesh2D) - _mesh2D->decrRef(); - if(_mesh1D) - _mesh1D->decrRef(); - if(_mesh3D_ids) - _mesh3D_ids->decrRef(); -} - -void MEDCouplingExtrudedMesh::computeExtrusion(const MEDCouplingUMesh *mesh3D) -{ - const char errMsg1[]="2D mesh is empty unable to compute extrusion !"; - const char errMsg2[]="Coords between 2D and 3D meshes are not the same ! Try MEDCouplingPointSet::tryToShareSameCoords method"; - const char errMsg3[]="No chance to find extrusion pattern in mesh3D,mesh2D couple because nbCells3D%nbCells2D!=0 !"; - if(_mesh2D==0 || mesh3D==0) - throw INTERP_KERNEL::Exception(errMsg1); - if(_mesh2D->getCoords()!=mesh3D->getCoords()) - throw INTERP_KERNEL::Exception(errMsg2); - if(mesh3D->getNumberOfCells()%_mesh2D->getNumberOfCells()!=0) - throw INTERP_KERNEL::Exception(errMsg3); - if(!_mesh3D_ids) - _mesh3D_ids=DataArrayInt::New(); - if(!_mesh1D) - _mesh1D=MEDCouplingUMesh::New(); - computeExtrusionAlg(mesh3D); -} - -void MEDCouplingExtrudedMesh::build1DExtrusion(int idIn3DDesc, int newId, int nbOf1DLev, MEDCouplingUMesh *subMesh, - const int *desc3D, const int *descIndx3D, - const int *revDesc3D, const int *revDescIndx3D, - bool computeMesh1D) -{ - int nbOf2DCells=_mesh2D->getNumberOfCells(); - int start=revDescIndx3D[idIn3DDesc]; - int end=revDescIndx3D[idIn3DDesc+1]; - if(end-start!=1) - { - std::ostringstream ost; ost << "Invalid bases 2D mesh specified : 2D cell # " << idIn3DDesc; - ost << " shared by more than 1 3D cell !!!"; - throw INTERP_KERNEL::Exception(ost.str().c_str()); - } - int current3DCell=revDesc3D[start]; - int current2DCell=idIn3DDesc; - int *mesh3DIDs=_mesh3D_ids->getPointer(); - mesh3DIDs[newId]=current3DCell; - const int *conn2D=subMesh->getNodalConnectivity()->getConstPointer(); - const int *conn2DIndx=subMesh->getNodalConnectivityIndex()->getConstPointer(); - for(int i=1;i conn(conn2D+conn2DIndx[current2DCell]+1,conn2D+conn2DIndx[current2DCell+1]); - std::sort(conn.begin(),conn.end()); - if(computeMesh1D) - computeBaryCenterOfFace(conn,i-1); - current2DCell=findOppositeFaceOf(current2DCell,current3DCell,conn, - desc3D,descIndx3D,conn2D,conn2DIndx); - start=revDescIndx3D[current2DCell]; - end=revDescIndx3D[current2DCell+1]; - if(end-start!=2) - { - std::ostringstream ost; ost << "Expecting to have 2 3D cells attached to 2D cell " << current2DCell << "!"; - ost << " : Impossible or call tryToShareSameCoords method !"; - throw INTERP_KERNEL::Exception(ost.str().c_str()); - } - if(revDesc3D[start]!=current3DCell) - current3DCell=revDesc3D[start]; - else - current3DCell=revDesc3D[start+1]; - mesh3DIDs[i*nbOf2DCells+newId]=current3DCell; - } - if(computeMesh1D) - { - std::vector conn(conn2D+conn2DIndx[current2DCell]+1,conn2D+conn2DIndx[current2DCell+1]); - std::sort(conn.begin(),conn.end()); - computeBaryCenterOfFace(conn,nbOf1DLev-1); - current2DCell=findOppositeFaceOf(current2DCell,current3DCell,conn, - desc3D,descIndx3D,conn2D,conn2DIndx); - conn.clear(); - conn.insert(conn.end(),conn2D+conn2DIndx[current2DCell]+1,conn2D+conn2DIndx[current2DCell+1]); - std::sort(conn.begin(),conn.end()); - computeBaryCenterOfFace(conn,nbOf1DLev); - } -} - -int MEDCouplingExtrudedMesh::findOppositeFaceOf(int current2DCell, int current3DCell, const std::vector& connSorted, - const int *desc3D, const int *descIndx3D, - const int *conn2D, const int *conn2DIndx) -{ - int start=descIndx3D[current3DCell]; - int end=descIndx3D[current3DCell+1]; - bool found=false; - for(const int *candidate2D=desc3D+start;candidate2D!=desc3D+end && !found;candidate2D++) - { - if(*candidate2D!=current2DCell) - { - std::vector conn2(conn2D+conn2DIndx[*candidate2D]+1,conn2D+conn2DIndx[*candidate2D+1]); - std::sort(conn2.begin(),conn2.end()); - std::list intersect; - std::set_intersection(connSorted.begin(),connSorted.end(),conn2.begin(),conn2.end(), - std::insert_iterator< std::list >(intersect,intersect.begin())); - if(intersect.empty()) - return *candidate2D; - } - } - std::ostringstream ost; ost << "Impossible to find an opposite 2D face of face # " << current2DCell; - ost << " in 3D cell # " << current3DCell << " : Impossible or call tryToShareSameCoords method !"; - throw INTERP_KERNEL::Exception(ost.str().c_str()); -} - -void MEDCouplingExtrudedMesh::computeBaryCenterOfFace(const std::vector& nodalConnec, int lev1DId) -{ - double *zoneToUpdate=_mesh1D->getCoords()->getPointer()+lev1DId*3; - std::fill(zoneToUpdate,zoneToUpdate+3,0.); - const double *coords=_mesh2D->getCoords()->getConstPointer(); - for(std::vector::const_iterator iter=nodalConnec.begin();iter!=nodalConnec.end();iter++) - std::transform(zoneToUpdate,zoneToUpdate+3,coords+3*(*iter),zoneToUpdate,std::plus()); - std::transform(zoneToUpdate,zoneToUpdate+3,zoneToUpdate,std::bind2nd(std::multiplies(),(double)(1./(int)nodalConnec.size()))); -} - -int MEDCouplingExtrudedMesh::FindCorrespCellByNodalConn(const std::vector& nodalConnec, const int *revNodalPtr, const int *revNodalIndxPtr) -{ - std::vector::const_iterator iter=nodalConnec.begin(); - std::set s1(revNodalPtr+revNodalIndxPtr[*iter],revNodalPtr+revNodalIndxPtr[*iter+1]); - iter++; - for(;iter!=nodalConnec.end();iter++) - { - std::set s2(revNodalPtr+revNodalIndxPtr[*iter],revNodalPtr+revNodalIndxPtr[*iter+1]); - std::set s3; - std::set_intersection(s1.begin(),s1.end(),s2.begin(),s2.end(),std::insert_iterator< std::set >(s3,s3.end())); - s1=s3; - } - if(s1.size()==1) - return *(s1.begin()); - std::ostringstream ostr; - ostr << "Cell with nodal connec : "; - std::copy(nodalConnec.begin(),nodalConnec.end(),std::ostream_iterator(ostr," ")); - ostr << " is not part of mesh"; - throw INTERP_KERNEL::Exception(ostr.str().c_str()); -} - -/*! - * This method is callable on 1Dmeshes (meshDim==1 && spaceDim==3) returned by MEDCouplingExtrudedMesh::getMesh1D typically. - * These 1Dmeshes (meshDim==1 && spaceDim==3) have a special semantic because these meshes do not specify a static location but a translation along a path. - * This method checks that 'm1' and 'm2' are compatible, if not an exception is thrown. In case these meshes ('m1' and 'm2') are compatible 2 corresponding meshes - * are created ('m1r' and 'm2r') that can be used for interpolation. - * @param m1 input mesh with meshDim==1 and spaceDim==3 - * @param m2 input mesh with meshDim==1 and spaceDim==3 - * @param eps tolerance acceptable to determine compatibility - * @param m1r output mesh with ref count equal to 1 with meshDim==1 and spaceDim==1 - * @param m2r output mesh with ref count equal to 1 with meshDim==1 and spaceDim==1 - * @param v is the output normalized vector of the common direction of 'm1' and 'm2' - * @throw in case that m1 and m2 are not compatible each other. - */ -void MEDCouplingExtrudedMesh::Project1DMeshes(const MEDCouplingUMesh *m1, const MEDCouplingUMesh *m2, double eps, - MEDCouplingUMesh *&m1r, MEDCouplingUMesh *&m2r, double *v) -{ - if(m1->getSpaceDimension()!=3 || m1->getSpaceDimension()!=3) - throw INTERP_KERNEL::Exception("Input meshes are expected to have a spaceDim==3 for Projec1D !"); - m1r=m1->clone(true); - m2r=m2->clone(true); - m1r->changeSpaceDimension(1); - m2r->changeSpaceDimension(1); - std::vector c; - std::vector ref,ref2; - m1->getNodeIdsOfCell(0,c); - m1->getCoordinatesOfNode(c[0],ref); - m1->getCoordinatesOfNode(c[1],ref2); - std::transform(ref2.begin(),ref2.end(),ref.begin(),v,std::minus()); - double n=INTERP_KERNEL::norm<3>(v); - std::transform(v,v+3,v,std::bind2nd(std::multiplies(),1/n)); - m1->project1D(&ref[0],v,eps,m1r->getCoords()->getPointer()); - m2->project1D(&ref[0],v,eps,m2r->getCoords()->getPointer()); -} - -void MEDCouplingExtrudedMesh::rotate(const double *center, const double *vector, double angle) -{ - _mesh2D->rotate(center,vector,angle); - _mesh1D->rotate(center,vector,angle); -} - -void MEDCouplingExtrudedMesh::translate(const double *vector) -{ - _mesh2D->translate(vector); - _mesh1D->translate(vector); -} - -void MEDCouplingExtrudedMesh::scale(const double *point, double factor) -{ - _mesh2D->scale(point,factor); - _mesh1D->scale(point,factor); -} - -std::vector MEDCouplingExtrudedMesh::getDistributionOfTypes() const -{ - throw INTERP_KERNEL::Exception("Not implemented yet !"); -} - -DataArrayInt *MEDCouplingExtrudedMesh::checkTypeConsistencyAndContig(const std::vector& code, const std::vector& idsPerType) const -{ - throw INTERP_KERNEL::Exception("Not implemented yet !"); -} - -void MEDCouplingExtrudedMesh::splitProfilePerType(const DataArrayInt *profile, std::vector& code, std::vector& idsInPflPerType, std::vector& idsPerType) const -{ - throw INTERP_KERNEL::Exception("Not implemented yet !"); -} - -MEDCouplingMesh *MEDCouplingExtrudedMesh::buildPart(const int *start, const int *end) const -{ - // not implemented yet ! - return 0; -} - -MEDCouplingMesh *MEDCouplingExtrudedMesh::buildPartAndReduceNodes(const int *start, const int *end, DataArrayInt*& arr) const -{ - // not implemented yet ! - return 0; -} - -DataArrayInt *MEDCouplingExtrudedMesh::simplexize(int policy) -{ - throw INTERP_KERNEL::Exception("MEDCouplingExtrudedMesh::simplexize : unavailable for such a type of mesh : Extruded !"); -} - -MEDCouplingMesh *MEDCouplingExtrudedMesh::mergeMyselfWith(const MEDCouplingMesh *other) const -{ - // not implemented yet ! - return 0; -} - -DataArrayDouble *MEDCouplingExtrudedMesh::getCoordinatesAndOwner() const -{ - DataArrayDouble *arr2D=_mesh2D->getCoords(); - DataArrayDouble *arr1D=_mesh1D->getCoords(); - DataArrayDouble *ret=DataArrayDouble::New(); - ret->alloc(getNumberOfNodes(),3); - int nbOf1DLev=_mesh1D->getNumberOfNodes(); - int nbOf2DNodes=_mesh2D->getNumberOfNodes(); - const double *ptSrc=arr2D->getConstPointer(); - double *pt=ret->getPointer(); - std::copy(ptSrc,ptSrc+3*nbOf2DNodes,pt); - for(int i=1;igetConstPointer()+3*i,arr1D->getConstPointer()+3*(i+1),vec); - std::transform(arr1D->getConstPointer()+3*(i-1),arr1D->getConstPointer()+3*i,vec,vec,std::minus()); - for(int j=0;j()); - } - return ret; -} - -DataArrayDouble *MEDCouplingExtrudedMesh::getBarycenterAndOwner() const -{ - throw INTERP_KERNEL::Exception("MEDCouplingExtrudedMesh::getBarycenterAndOwner : not yet implemented !"); -} - -DataArrayDouble *MEDCouplingExtrudedMesh::computeIsoBarycenterOfNodesPerCell() const -{ - throw INTERP_KERNEL::Exception("MEDCouplingExtrudedMesh::computeIsoBarycenterOfNodesPerCell: not yet implemented !"); -} - -void MEDCouplingExtrudedMesh::getReverseNodalConnectivity(DataArrayInt *revNodal, DataArrayInt *revNodalIndx) const -{ - MEDCouplingAutoRefCountObjectPtr m(buildUnstructured()); - m->getReverseNodalConnectivity(revNodal,revNodalIndx); -} - -void MEDCouplingExtrudedMesh::computeExtrusionAlg(const MEDCouplingUMesh *mesh3D) -{ - _mesh3D_ids->alloc(mesh3D->getNumberOfCells(),1); - int nbOf1DLev=mesh3D->getNumberOfCells()/_mesh2D->getNumberOfCells(); - _mesh1D->setMeshDimension(1); - _mesh1D->allocateCells(nbOf1DLev); - int tmpConn[2]; - for(int i=0;iinsertNextCell(INTERP_KERNEL::NORM_SEG2,2,tmpConn); - } - _mesh1D->finishInsertingCells(); - DataArrayDouble *myCoords=DataArrayDouble::New(); - myCoords->alloc(nbOf1DLev+1,3); - _mesh1D->setCoords(myCoords); - myCoords->decrRef(); - DataArrayInt *desc,*descIndx,*revDesc,*revDescIndx; - desc=DataArrayInt::New(); descIndx=DataArrayInt::New(); revDesc=DataArrayInt::New(); revDescIndx=DataArrayInt::New(); - MEDCouplingUMesh *subMesh=mesh3D->buildDescendingConnectivity(desc,descIndx,revDesc,revDescIndx); - DataArrayInt *revNodal2D,*revNodalIndx2D; - revNodal2D=DataArrayInt::New(); revNodalIndx2D=DataArrayInt::New(); - subMesh->getReverseNodalConnectivity(revNodal2D,revNodalIndx2D); - const int *nodal2D=_mesh2D->getNodalConnectivity()->getConstPointer(); - const int *nodal2DIndx=_mesh2D->getNodalConnectivityIndex()->getConstPointer(); - const int *revNodal2DPtr=revNodal2D->getConstPointer(); - const int *revNodalIndx2DPtr=revNodalIndx2D->getConstPointer(); - const int *descP=desc->getConstPointer(); - const int *descIndxP=descIndx->getConstPointer(); - const int *revDescP=revDesc->getConstPointer(); - const int *revDescIndxP=revDescIndx->getConstPointer(); - // - int nbOf2DCells=_mesh2D->getNumberOfCells(); - for(int i=0;i nodalConnec(nodal2D+nodal2DIndx[i]+1,nodal2D+nodal2DIndx[i+1]); - try - { - idInSubMesh=FindCorrespCellByNodalConn(nodalConnec,revNodal2DPtr,revNodalIndx2DPtr); - } - catch(INTERP_KERNEL::Exception& e) - { - std::ostringstream ostr; ostr << "mesh2D cell # " << i << " is not part of any cell of 3D mesh !\n"; - ostr << e.what(); - throw INTERP_KERNEL::Exception(ostr.str().c_str()); - } - build1DExtrusion(idInSubMesh,i,nbOf1DLev,subMesh,descP,descIndxP,revDescP,revDescIndxP,i==_cell_2D_id); - } - // - revNodal2D->decrRef(); - revNodalIndx2D->decrRef(); - subMesh->decrRef(); - desc->decrRef(); - descIndx->decrRef(); - revDesc->decrRef(); - revDescIndx->decrRef(); -} - -void MEDCouplingExtrudedMesh::getTinySerializationInformation(std::vector& tinyInfoD, std::vector& tinyInfo, std::vector& littleStrings) const -{ - std::vector tinyInfo1; - std::vector ls1; - std::vector ls3; - _mesh2D->getTinySerializationInformation(ls3,tinyInfo1,ls1); - std::vector tinyInfo2; - std::vector ls2; - std::vector ls4; - _mesh1D->getTinySerializationInformation(ls4,tinyInfo2,ls2); - tinyInfo.clear(); littleStrings.clear(); - tinyInfo.insert(tinyInfo.end(),tinyInfo1.begin(),tinyInfo1.end()); - littleStrings.insert(littleStrings.end(),ls1.begin(),ls1.end()); - tinyInfo.insert(tinyInfo.end(),tinyInfo2.begin(),tinyInfo2.end()); - littleStrings.insert(littleStrings.end(),ls2.begin(),ls2.end()); - tinyInfo.push_back(_cell_2D_id); - tinyInfo.push_back((int)tinyInfo1.size()); - tinyInfo.push_back(_mesh3D_ids->getNbOfElems()); - littleStrings.push_back(getName()); - littleStrings.push_back(getDescription()); -} - -void MEDCouplingExtrudedMesh::resizeForUnserialization(const std::vector& tinyInfo, DataArrayInt *a1, DataArrayDouble *a2, std::vector& littleStrings) const -{ - std::size_t sz=tinyInfo.size(); - int sz1=tinyInfo[sz-2]; - std::vector ti1(tinyInfo.begin(),tinyInfo.begin()+sz1); - std::vector ti2(tinyInfo.begin()+sz1,tinyInfo.end()-3); - MEDCouplingUMesh *um=MEDCouplingUMesh::New(); - DataArrayInt *a1tmp=DataArrayInt::New(); - DataArrayDouble *a2tmp=DataArrayDouble::New(); - int la1=0,la2=0; - std::vector ls1,ls2; - um->resizeForUnserialization(ti1,a1tmp,a2tmp,ls1); - la1+=a1tmp->getNbOfElems(); la2+=a2tmp->getNbOfElems(); - a1tmp->decrRef(); a2tmp->decrRef(); - a1tmp=DataArrayInt::New(); a2tmp=DataArrayDouble::New(); - um->resizeForUnserialization(ti2,a1tmp,a2tmp,ls2); - la1+=a1tmp->getNbOfElems(); la2+=a2tmp->getNbOfElems(); - a1tmp->decrRef(); a2tmp->decrRef(); - um->decrRef(); - // - a1->alloc(la1+tinyInfo[sz-1],1); - a2->alloc(la2,1); - littleStrings.resize(ls1.size()+ls2.size()+2); -} - -void MEDCouplingExtrudedMesh::serialize(DataArrayInt *&a1, DataArrayDouble *&a2) const -{ - a1=DataArrayInt::New(); a2=DataArrayDouble::New(); - DataArrayInt *a1_1=0,*a1_2=0; - DataArrayDouble *a2_1=0,*a2_2=0; - _mesh2D->serialize(a1_1,a2_1); - _mesh1D->serialize(a1_2,a2_2); - a1->alloc(a1_1->getNbOfElems()+a1_2->getNbOfElems()+_mesh3D_ids->getNbOfElems(),1); - int *ptri=a1->getPointer(); - ptri=std::copy(a1_1->getConstPointer(),a1_1->getConstPointer()+a1_1->getNbOfElems(),ptri); - a1_1->decrRef(); - ptri=std::copy(a1_2->getConstPointer(),a1_2->getConstPointer()+a1_2->getNbOfElems(),ptri); - a1_2->decrRef(); - std::copy(_mesh3D_ids->getConstPointer(),_mesh3D_ids->getConstPointer()+_mesh3D_ids->getNbOfElems(),ptri); - a2->alloc(a2_1->getNbOfElems()+a2_2->getNbOfElems(),1); - double *ptrd=a2->getPointer(); - ptrd=std::copy(a2_1->getConstPointer(),a2_1->getConstPointer()+a2_1->getNbOfElems(),ptrd); - a2_1->decrRef(); - std::copy(a2_2->getConstPointer(),a2_2->getConstPointer()+a2_2->getNbOfElems(),ptrd); - a2_2->decrRef(); -} - -void MEDCouplingExtrudedMesh::unserialization(const std::vector& tinyInfoD, const std::vector& tinyInfo, const DataArrayInt *a1, DataArrayDouble *a2, const std::vector& littleStrings) -{ - setName(littleStrings[littleStrings.size()-2]); - setDescription(littleStrings.back()); - std::size_t sz=tinyInfo.size(); - int sz1=tinyInfo[sz-2]; - _cell_2D_id=tinyInfo[sz-3]; - std::vector ti1(tinyInfo.begin(),tinyInfo.begin()+sz1); - std::vector ti2(tinyInfo.begin()+sz1,tinyInfo.end()-3); - DataArrayInt *a1tmp=DataArrayInt::New(); - DataArrayDouble *a2tmp=DataArrayDouble::New(); - const int *a1Ptr=a1->getConstPointer(); - const double *a2Ptr=a2->getConstPointer(); - _mesh2D=MEDCouplingUMesh::New(); - std::vector ls1,ls2; - _mesh2D->resizeForUnserialization(ti1,a1tmp,a2tmp,ls1); - std::copy(a2Ptr,a2Ptr+a2tmp->getNbOfElems(),a2tmp->getPointer()); - std::copy(a1Ptr,a1Ptr+a1tmp->getNbOfElems(),a1tmp->getPointer()); - a2Ptr+=a2tmp->getNbOfElems(); - a1Ptr+=a1tmp->getNbOfElems(); - ls2.insert(ls2.end(),littleStrings.begin(),littleStrings.begin()+ls1.size()); - std::vector d1(1); - _mesh2D->unserialization(d1,ti1,a1tmp,a2tmp,ls2); - a1tmp->decrRef(); a2tmp->decrRef(); - // - ls2.clear(); - ls2.insert(ls2.end(),littleStrings.begin()+ls1.size(),littleStrings.end()-2); - _mesh1D=MEDCouplingUMesh::New(); - a1tmp=DataArrayInt::New(); a2tmp=DataArrayDouble::New(); - _mesh1D->resizeForUnserialization(ti2,a1tmp,a2tmp,ls1); - std::copy(a2Ptr,a2Ptr+a2tmp->getNbOfElems(),a2tmp->getPointer()); - std::copy(a1Ptr,a1Ptr+a1tmp->getNbOfElems(),a1tmp->getPointer()); - a1Ptr+=a1tmp->getNbOfElems(); - _mesh1D->unserialization(d1,ti2,a1tmp,a2tmp,ls2); - a1tmp->decrRef(); a2tmp->decrRef(); - // - _mesh3D_ids=DataArrayInt::New(); - int szIds=(int)std::distance(a1Ptr,a1->getConstPointer()+a1->getNbOfElems()); - _mesh3D_ids->alloc(szIds,1); - std::copy(a1Ptr,a1Ptr+szIds,_mesh3D_ids->getPointer()); -} - -void MEDCouplingExtrudedMesh::writeVTKLL(std::ostream& ofs, const std::string& cellData, const std::string& pointData, DataArrayByte *byteData) const -{ - MEDCouplingAutoRefCountObjectPtr m=buildUnstructured(); - m->writeVTKLL(ofs,cellData,pointData,byteData); -} - -void MEDCouplingExtrudedMesh::reprQuickOverview(std::ostream& stream) const -{ - stream << "MEDCouplingExtrudedMesh C++ instance at " << this << ". Name : \"" << getName() << "\"."; -} - -std::string MEDCouplingExtrudedMesh::getVTKFileExtension() const -{ - return _mesh2D->getVTKFileExtension(); -} - -std::string MEDCouplingExtrudedMesh::getVTKDataSetType() const -{ - return _mesh2D->getVTKDataSetType(); -} diff --git a/src/MEDCoupling/MEDCouplingExtrudedMesh.hxx b/src/MEDCoupling/MEDCouplingExtrudedMesh.hxx deleted file mode 100644 index c72f42cf4..000000000 --- a/src/MEDCoupling/MEDCouplingExtrudedMesh.hxx +++ /dev/null @@ -1,135 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 -// 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_MEDCOUPLINGEXTRUDEDMESH_HXX__ -#define __PARAMEDMEM_MEDCOUPLINGEXTRUDEDMESH_HXX__ - -#include "MEDCoupling.hxx" -#include "MEDCouplingMesh.hxx" - -#include - -namespace ParaMEDMEM -{ - class DataArrayInt; - class DataArrayDouble; - class MEDCouplingUMesh; - class MEDCouplingFieldDouble; - - class MEDCouplingExtrudedMesh : public MEDCouplingMesh - { - public: - MEDCOUPLING_EXPORT static MEDCouplingExtrudedMesh *New(const MEDCouplingUMesh *mesh3D, const MEDCouplingUMesh *mesh2D, int cell2DId); - MEDCOUPLING_EXPORT static MEDCouplingExtrudedMesh *New(); - MEDCOUPLING_EXPORT MEDCouplingMeshType getType() const; - MEDCOUPLING_EXPORT std::size_t getHeapMemorySizeWithoutChildren() const; - MEDCOUPLING_EXPORT std::vector getDirectChildrenWithNull() const; - MEDCOUPLING_EXPORT void copyTinyStringsFrom(const MEDCouplingMesh *other); - MEDCOUPLING_EXPORT int getNumberOfCells() const; - MEDCOUPLING_EXPORT int getNumberOfNodes() const; - MEDCOUPLING_EXPORT int getSpaceDimension() const; - MEDCOUPLING_EXPORT int getMeshDimension() const; - MEDCOUPLING_EXPORT MEDCouplingMesh *deepCpy() const; - MEDCouplingExtrudedMesh *clone(bool recDeepCpy) const; - MEDCOUPLING_EXPORT bool isEqualIfNotWhy(const MEDCouplingMesh *other, double prec, std::string& reason) const; - MEDCOUPLING_EXPORT bool isEqualWithoutConsideringStr(const MEDCouplingMesh *other, double prec) const; - MEDCOUPLING_EXPORT void checkDeepEquivalWith(const MEDCouplingMesh *other, int cellCompPol, double prec, - DataArrayInt *&cellCor, DataArrayInt *&nodeCor) const; - MEDCOUPLING_EXPORT void checkDeepEquivalOnSameNodesWith(const MEDCouplingMesh *other, int cellCompPol, double prec, - DataArrayInt *&cellCor) const; - MEDCOUPLING_EXPORT INTERP_KERNEL::NormalizedCellType getTypeOfCell(int cellId) const; - MEDCOUPLING_EXPORT std::set getAllGeoTypes() const; - MEDCOUPLING_EXPORT DataArrayInt *giveCellsWithType(INTERP_KERNEL::NormalizedCellType type) const; - MEDCOUPLING_EXPORT DataArrayInt *computeNbOfNodesPerCell() const; - MEDCOUPLING_EXPORT DataArrayInt *computeNbOfFacesPerCell() const; - MEDCOUPLING_EXPORT DataArrayInt *computeEffectiveNbOfNodesPerCell() const; - MEDCOUPLING_EXPORT int getNumberOfCellsWithType(INTERP_KERNEL::NormalizedCellType type) const; - MEDCOUPLING_EXPORT void getNodeIdsOfCell(int cellId, std::vector& conn) const; - MEDCOUPLING_EXPORT void getCoordinatesOfNode(int nodeId, std::vector& coo) const; - MEDCOUPLING_EXPORT std::string simpleRepr() const; - MEDCOUPLING_EXPORT std::string advancedRepr() const; - MEDCOUPLING_EXPORT void checkCoherency() const; - MEDCOUPLING_EXPORT void checkCoherency1(double eps=1e-12) const; - MEDCOUPLING_EXPORT void checkCoherency2(double eps=1e-12) const; - MEDCOUPLING_EXPORT void getBoundingBox(double *bbox) const; - MEDCOUPLING_EXPORT void updateTime() const; - MEDCOUPLING_EXPORT void renumberCells(const int *old2NewBg, bool check=true); - MEDCOUPLING_EXPORT MEDCouplingUMesh *getMesh2D() const { return _mesh2D; } - MEDCOUPLING_EXPORT MEDCouplingUMesh *getMesh1D() const { return _mesh1D; } - MEDCOUPLING_EXPORT DataArrayInt *getMesh3DIds() const { return _mesh3D_ids; } - MEDCOUPLING_EXPORT MEDCouplingUMesh *build3DUnstructuredMesh() const; - MEDCOUPLING_EXPORT MEDCouplingUMesh *buildUnstructured() const; - MEDCOUPLING_EXPORT MEDCouplingFieldDouble *getMeasureField(bool) const; - MEDCOUPLING_EXPORT MEDCouplingFieldDouble *getMeasureFieldOnNode(bool) const; - MEDCOUPLING_EXPORT MEDCouplingFieldDouble *buildOrthogonalField() const; - MEDCOUPLING_EXPORT int getCellContainingPoint(const double *pos, double eps) const; - MEDCOUPLING_EXPORT static int FindCorrespCellByNodalConn(const std::vector& nodalConnec, - const int *revNodalPtr, const int *revNodalIndxPtr); - MEDCOUPLING_EXPORT static void Project1DMeshes(const MEDCouplingUMesh *m1, const MEDCouplingUMesh *m2, double eps, - MEDCouplingUMesh *&m1r, MEDCouplingUMesh *&m2r, double *v); - MEDCOUPLING_EXPORT void rotate(const double *center, const double *vector, double angle); - MEDCOUPLING_EXPORT void translate(const double *vector); - MEDCOUPLING_EXPORT void scale(const double *point, double factor); - MEDCOUPLING_EXPORT std::vector getDistributionOfTypes() const; - MEDCOUPLING_EXPORT DataArrayInt *checkTypeConsistencyAndContig(const std::vector& code, const std::vector& idsPerType) const; - MEDCOUPLING_EXPORT void splitProfilePerType(const DataArrayInt *profile, std::vector& code, std::vector& idsInPflPerType, std::vector& idsPerType) const; - MEDCOUPLING_EXPORT MEDCouplingMesh *buildPart(const int *start, const int *end) const; - MEDCOUPLING_EXPORT MEDCouplingMesh *buildPartAndReduceNodes(const int *start, const int *end, DataArrayInt*& arr) const; - MEDCOUPLING_EXPORT DataArrayInt *simplexize(int policy); - MEDCOUPLING_EXPORT MEDCouplingMesh *mergeMyselfWith(const MEDCouplingMesh *other) const; - MEDCOUPLING_EXPORT DataArrayDouble *getCoordinatesAndOwner() const; - MEDCOUPLING_EXPORT DataArrayDouble *getBarycenterAndOwner() const; - MEDCOUPLING_EXPORT DataArrayDouble *computeIsoBarycenterOfNodesPerCell() const; - MEDCOUPLING_EXPORT void getReverseNodalConnectivity(DataArrayInt *revNodal, DataArrayInt *revNodalIndx) const; - //Serialization unserialisation - MEDCOUPLING_EXPORT void getTinySerializationInformation(std::vector& tinyInfoD, std::vector& tinyInfo, std::vector& littleStrings) const; - MEDCOUPLING_EXPORT void resizeForUnserialization(const std::vector& tinyInfo, DataArrayInt *a1, DataArrayDouble *a2, std::vector& littleStrings) const; - MEDCOUPLING_EXPORT void serialize(DataArrayInt *&a1, DataArrayDouble *&a2) const; - MEDCOUPLING_EXPORT void unserialization(const std::vector& tinyInfoD, const std::vector& tinyInfo, const DataArrayInt *a1, DataArrayDouble *a2, - const std::vector& littleStrings); - MEDCOUPLING_EXPORT void reprQuickOverview(std::ostream& stream) const; - MEDCOUPLING_EXPORT std::string getVTKFileExtension() const; - private: - MEDCouplingExtrudedMesh(const MEDCouplingUMesh *mesh3D, const MEDCouplingUMesh *mesh2D, int cell2DId); - MEDCouplingExtrudedMesh(const MEDCouplingExtrudedMesh& other, bool deepCopy); - MEDCouplingExtrudedMesh(); - void computeExtrusion(const MEDCouplingUMesh *mesh3D); - void computeExtrusionAlg(const MEDCouplingUMesh *mesh3D); - void build1DExtrusion(int idIn3DDesc, int newId, int nbOf1DLev, MEDCouplingUMesh *subMesh, - const int *desc3D, const int *descIndx3D, - const int *revDesc3D, const int *revDescIndx3D, - bool computeMesh1D); - int findOppositeFaceOf(int current2DCell, int current3DCell, const std::vector& connSorted, - const int *desc3D, const int *descIndx3D, - const int *conn2D, const int *conn2DIndx); - void computeBaryCenterOfFace(const std::vector& nodalConnec, int lev1DId); - ~MEDCouplingExtrudedMesh(); - void writeVTKLL(std::ostream& ofs, const std::string& cellData, const std::string& pointData, DataArrayByte *byteData) const; - std::string getVTKDataSetType() const; - private: - MEDCouplingUMesh *_mesh2D; - MEDCouplingUMesh *_mesh1D; - //! New to old 3D cell Ids Array - DataArrayInt *_mesh3D_ids; - int _cell_2D_id; - }; -} - -#endif diff --git a/src/MEDCoupling/MEDCouplingField.cxx b/src/MEDCoupling/MEDCouplingField.cxx deleted file mode 100644 index 463a44bbb..000000000 --- a/src/MEDCoupling/MEDCouplingField.cxx +++ /dev/null @@ -1,635 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 -// 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 "MEDCouplingField.hxx" -#include "MEDCouplingMesh.hxx" -#include "MEDCouplingFieldDiscretization.hxx" - -#include - -using namespace ParaMEDMEM; - -bool MEDCouplingField::isEqualIfNotWhy(const MEDCouplingField *other, double meshPrec, double valsPrec, std::string& reason) const -{ - if(!other) - throw INTERP_KERNEL::Exception("MEDCouplingField::isEqualIfNotWhy : other instance is NULL !"); - std::ostringstream oss; oss.precision(15); - if(_name!=other->_name) - { - oss << "Field names differ : this name = \"" << _name << "\" and other name = \"" << other->_name << "\" !"; - reason=oss.str(); - return false; - } - if(_desc!=other->_desc) - { - oss << "Field descriptions differ : this description = \"" << _desc << "\" and other description = \"" << other->_desc << "\" !"; - reason=oss.str(); - return false; - } - if(_nature!=other->_nature) - { - oss << "Field nature differ : this nature = \"" << MEDCouplingNatureOfField::GetRepr(_nature) << "\" and other nature = \"" << MEDCouplingNatureOfField::GetRepr(other->_nature) << "\" !"; - reason=oss.str(); - return false; - } - if(!_type->isEqualIfNotWhy(other->_type,valsPrec,reason)) - { - reason.insert(0,"Spatial discretizations differ :"); - return false; - } - if(_mesh==0 && other->_mesh==0) - return true; - if(_mesh==0 || other->_mesh==0) - { - reason="Only one field between the two this and other has its underlying mesh defined !"; - return false; - } - if(_mesh==other->_mesh) - return true; - bool ret=_mesh->isEqualIfNotWhy(other->_mesh,meshPrec,reason); - if(!ret) - reason.insert(0,"Underlying meshes of fields differ for the following reason : "); - 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) - return false; - if(_mesh==0 && other->_mesh==0) - return true; - if(_mesh==0 || other->_mesh==0) - return false; - if(_mesh==other->_mesh) - return true; - return _mesh->isEqualWithoutConsideringStr(other->_mesh,meshPrec); -} - -/*! - * This method states if 'this' and 'other' are compatibles each other before performing any treatment. - * This method is good for methods like : mergeFields. - * This method is not very demanding compared to areStrictlyCompatible that is better for operation on fields. - */ -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) - return false; - if(_mesh==other->_mesh) - return true; - return _mesh->areCompatibleForMerge(other->_mesh); -} - -/*! - * This method is more strict than MEDCouplingField::areCompatibleForMerge method. - * This method is used for operation on fields to operate a first check before attempting operation. - */ -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) - return false; - return _mesh==other->_mesh; -} - -/*! - * This method is less strict than MEDCouplingField::areStrictlyCompatible method. - * The difference is that the nature is not checked. - * This method is used for multiplication and division on fields to operate a first check before attempting operation. - */ -bool MEDCouplingField::areStrictlyCompatibleForMulDiv(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; - return _mesh==other->_mesh; -} - - -void MEDCouplingField::updateTime() const -{ - if(_mesh) - updateTimeWith(*_mesh); - if(_type) - updateTimeWith(*_type); -} - -std::size_t MEDCouplingField::getHeapMemorySizeWithoutChildren() const -{ - std::size_t ret=0; - ret+=_name.capacity(); - ret+=_desc.capacity(); - return ret; -} - -std::vector MEDCouplingField::getDirectChildrenWithNull() const -{ - std::vector ret; - ret.push_back(_mesh); - ret.push_back((const MEDCouplingFieldDiscretization *)_type); - 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. - * \throw If the geometric type is empty. - */ -TypeOfField MEDCouplingField::getTypeOfField() const -{ - if(!((const MEDCouplingFieldDiscretization *)_type)) - throw INTERP_KERNEL::Exception("MEDCouplingField::getTypeOfField : spatial discretization is null !"); - return _type->getEnum(); -} - -/*! - * 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 -{ - return _nature; -} - -/*! - * 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) -{ - MEDCouplingNatureOfField::GetRepr(nat);//generate a throw if nat not recognized - _nature=nat; -} - -/*! - * 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 -{ - 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); -} - -/*! - * 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 -{ - 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) - { - if(_mesh) - _mesh->decrRef(); - _mesh=mesh; - declareAsNew(); - if(_mesh) - { - _mesh->incrRef(); - updateTimeWith(*_mesh); - } - } -} - -/*! - * 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) -{ - 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); -} - -/*! - * 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) -{ - 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); -} - -/*! - * 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. - */ -void MEDCouplingField::clearGaussLocalizations() -{ - if(!((const MEDCouplingFieldDiscretization *)_type)) - throw INTERP_KERNEL::Exception("Spatial discretization not set ! Impossible to call clearGaussLocalizations method !"); - _type->clearGaussLocalizations(); -} - -/*! - * 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 ParaMEDMEM::MEDCouplingGaussLocalization "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. - */ -MEDCouplingGaussLocalization& MEDCouplingField::getGaussLocalization(int locId) -{ - if(!((const MEDCouplingFieldDiscretization *)_type)) - throw INTERP_KERNEL::Exception("Spatial discretization not set ! Impossible to call getGaussLocalization method !"); - return _type->getGaussLocalization(locId); -} - -/*! - * 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 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 -{ - 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 - */ -std::set MEDCouplingField::getGaussLocalizationIdsOfOneType(INTERP_KERNEL::NormalizedCellType type) const -{ - if(!((const MEDCouplingFieldDiscretization *)_type)) - throw INTERP_KERNEL::Exception("Spatial discretization not set ! Impossible to call getGaussLocalizationIdsOfOneType method !"); - return _type->getGaussLocalizationIdsOfOneType(type); -} - -/*! - * 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. - */ -int MEDCouplingField::getNbOfGaussLocalization() const -{ - if(!((const MEDCouplingFieldDiscretization *)_type)) - throw INTERP_KERNEL::Exception("Spatial discretization not set ! Impossible to call getNbOfGaussLocalization method !"); - return _type->getNbOfGaussLocalization(); -} - -/*! - * 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 no Gauss localization object found for the given cell. - */ -int MEDCouplingField::getGaussLocalizationIdOfOneCell(int cellId) const -{ - if(!((const MEDCouplingFieldDiscretization *)_type)) - throw INTERP_KERNEL::Exception("Spatial discretization not set ! Impossible to call getGaussLocalizationIdOfOneCell method !"); - return _type->getGaussLocalizationIdOfOneCell(cellId); -} - -/*! - * 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. - */ -void MEDCouplingField::getCellIdsHavingGaussLocalization(int locId, std::vector& cellIds) const -{ - cellIds.clear(); - if(!((const MEDCouplingFieldDiscretization *)_type)) - throw INTERP_KERNEL::Exception("Spatial discretization not set ! Impossible to call getCellIdsHavingGaussLocalization method !"); - _type->getCellIdsHavingGaussLocalization(locId,cellIds); -} - -/*! - * 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 const \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. - */ -const MEDCouplingGaussLocalization& MEDCouplingField::getGaussLocalization(int locId) const -{ - if(!((const MEDCouplingFieldDiscretization *)_type)) - throw INTERP_KERNEL::Exception("Spatial discretization not set ! Impossible to call getGaussLocalization method !"); - return _type->getGaussLocalization(locId); -} - -MEDCouplingField::~MEDCouplingField() -{ - if(_mesh) - _mesh->decrRef(); -} - -MEDCouplingField::MEDCouplingField(MEDCouplingFieldDiscretization *type, NatureOfField nature):_nature(nature),_mesh(0),_type(type) -{ -} - -MEDCouplingField::MEDCouplingField(TypeOfField type):_nature(NoNature),_mesh(0),_type(MEDCouplingFieldDiscretization::New(type)) -{ -} - -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; -} - -/*! - * 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); -} - -/*! - * Returns number of tuples expected regarding the spatial discretization of \a this - * field and number of entities in the underlying mesh. This method behaves exactly as MEDCouplingFieldDouble::getNumberOfTuples. - * \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 -{ - 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(); -} - -/*! - * 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 -{ - 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) -{ - if(other) - { - setName(other->_name); - setDescription(other->_desc); - } -} - -/*! - * This method computes the number of tuples a DataArrayDouble instance should have to build a correct MEDCouplingFieldDouble instance starting from a - * submesh of a virtual mesh on which a substraction per type had been applied regarding the spatial discretization in \a this. - * - * For spatial discretization \b not equal to ON_GAUSS_NE this method will make the hypothesis that any positive entity id in \a code \a idsPerType is valid. - * So in those cases attribute \a _mesh of \a this is ignored. - * - * For spatial discretization equal to ON_GAUSS_NE \a _mesh attribute will be taken into account. - * - * The input code is those implemented in MEDCouplingUMesh::splitProfilePerType. - * - * \param [in] code - a code with format described above. - * \param [in] idsPerType - a list of subparts - * \throw If \a this has no spatial discretization set. - * \throw If input code point to invalid zones in spatial discretization. - * \throw If spatial discretization in \a this requires a mesh and those mesh is invalid (null,...) - */ -int MEDCouplingField::getNumberOfTuplesExpectedRegardingCode(const std::vector& code, const std::vector& idsPerType) const -{ - const MEDCouplingFieldDiscretization *t(_type); - if(!t) - throw INTERP_KERNEL::Exception("MEDCouplingField::getNumberOfTuplesExpectedRegardingCode : no spatial discretization set !"); - return t->getNumberOfTuplesExpectedRegardingCode(code,idsPerType); -} diff --git a/src/MEDCoupling/MEDCouplingField.hxx b/src/MEDCoupling/MEDCouplingField.hxx deleted file mode 100644 index 9154f56c2..000000000 --- a/src/MEDCoupling/MEDCouplingField.hxx +++ /dev/null @@ -1,108 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 -// 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_MEDCOUPLINGFIELD_HXX__ -#define __PARAMEDMEM_MEDCOUPLINGFIELD_HXX__ - -#include "MEDCoupling.hxx" -#include "MEDCouplingTimeLabel.hxx" -#include "MEDCouplingNatureOfField.hxx" -#include "MEDCouplingRefCountObject.hxx" -#include "NormalizedUnstructuredMesh.hxx" -#include "MEDCouplingAutoRefCountObjectPtr.hxx" -#include "MEDCouplingFieldDiscretization.hxx" -#include "InterpKernelException.hxx" - -#include -#include - -namespace ParaMEDMEM -{ - class DataArrayInt; - class DataArrayDouble; - class MEDCouplingMesh; - class MEDCouplingFieldDouble; - class MEDCouplingGaussLocalization; - - class MEDCouplingField : public RefCountObject, public TimeLabel - { - public: - MEDCOUPLING_EXPORT virtual void checkCoherency() const = 0; - MEDCOUPLING_EXPORT virtual bool areCompatibleForMerge(const MEDCouplingField *other) const; - MEDCOUPLING_EXPORT virtual bool areStrictlyCompatible(const MEDCouplingField *other) const; - MEDCOUPLING_EXPORT virtual bool areStrictlyCompatibleForMulDiv(const MEDCouplingField *other) const; - MEDCOUPLING_EXPORT virtual bool isEqualIfNotWhy(const MEDCouplingField *other, double meshPrec, double valsPrec, std::string& reason) const; - MEDCOUPLING_EXPORT virtual bool isEqual(const MEDCouplingField *other, double meshPrec, double valsPrec) const; - MEDCOUPLING_EXPORT virtual bool isEqualWithoutConsideringStr(const MEDCouplingField *other, double meshPrec, double valsPrec) const; - MEDCOUPLING_EXPORT virtual void copyTinyStringsFrom(const MEDCouplingField *other); - MEDCOUPLING_EXPORT void setMesh(const ParaMEDMEM::MEDCouplingMesh *mesh); - MEDCOUPLING_EXPORT const ParaMEDMEM::MEDCouplingMesh *getMesh() const { return _mesh; } - MEDCOUPLING_EXPORT ParaMEDMEM::MEDCouplingMesh *getMesh() { return const_cast(_mesh); } - MEDCOUPLING_EXPORT void setName(const std::string& name) { _name=name; } - MEDCOUPLING_EXPORT std::string getDescription() const { return _desc; } - MEDCOUPLING_EXPORT void setDescription(const std::string& desc) { _desc=desc; } - MEDCOUPLING_EXPORT std::string getName() const { return _name; } - MEDCOUPLING_EXPORT TypeOfField getTypeOfField() const; - MEDCOUPLING_EXPORT NatureOfField getNature() const; - MEDCOUPLING_EXPORT virtual void setNature(NatureOfField nat); - MEDCOUPLING_EXPORT DataArrayDouble *getLocalizationOfDiscr() const; - MEDCOUPLING_EXPORT MEDCouplingFieldDouble *buildMeasureField(bool isAbs) const; - MEDCOUPLING_EXPORT MEDCouplingMesh *buildSubMeshData(const int *start, const int *end, DataArrayInt *&di) const; - MEDCOUPLING_EXPORT MEDCouplingMesh *buildSubMeshDataRange(int begin, int end, int step, int& beginOut, int& endOut, int& stepOut, DataArrayInt *&di) const; - MEDCOUPLING_EXPORT DataArrayInt *computeTupleIdsToSelectFromCellIds(const int *startCellIds, const int *endCellIds) const; - MEDCOUPLING_EXPORT const MEDCouplingFieldDiscretization *getDiscretization() const { return _type; } - MEDCOUPLING_EXPORT MEDCouplingFieldDiscretization *getDiscretization() { return _type; } - MEDCOUPLING_EXPORT void setDiscretization(MEDCouplingFieldDiscretization *newDisc); - MEDCOUPLING_EXPORT int getNumberOfTuplesExpected() const; - MEDCOUPLING_EXPORT int getNumberOfMeshPlacesExpected() const; - // Gauss point specific methods - MEDCOUPLING_EXPORT void setGaussLocalizationOnType(INTERP_KERNEL::NormalizedCellType type, const std::vector& refCoo, - const std::vector& gsCoo, const std::vector& wg); - MEDCOUPLING_EXPORT void setGaussLocalizationOnCells(const int *begin, const int *end, const std::vector& refCoo, - const std::vector& gsCoo, const std::vector& wg); - MEDCOUPLING_EXPORT void clearGaussLocalizations(); - MEDCOUPLING_EXPORT MEDCouplingGaussLocalization& getGaussLocalization(int locId); - MEDCOUPLING_EXPORT int getGaussLocalizationIdOfOneType(INTERP_KERNEL::NormalizedCellType type) const; - MEDCOUPLING_EXPORT std::set getGaussLocalizationIdsOfOneType(INTERP_KERNEL::NormalizedCellType type) const; - MEDCOUPLING_EXPORT int getNbOfGaussLocalization() const; - MEDCOUPLING_EXPORT int getGaussLocalizationIdOfOneCell(int cellId) const; - MEDCOUPLING_EXPORT void getCellIdsHavingGaussLocalization(int locId, std::vector& cellIds) const; - MEDCOUPLING_EXPORT const MEDCouplingGaussLocalization& getGaussLocalization(int locId) const; - MEDCOUPLING_EXPORT void updateTime() const; - MEDCOUPLING_EXPORT std::size_t getHeapMemorySizeWithoutChildren() const; - MEDCOUPLING_EXPORT std::vector getDirectChildrenWithNull() const; - // for MED file RW - MEDCOUPLING_EXPORT int getNumberOfTuplesExpectedRegardingCode(const std::vector& code, const std::vector& idsPerType) const; - MEDCOUPLING_EXPORT virtual void reprQuickOverview(std::ostream& stream) const = 0; - protected: - MEDCOUPLING_EXPORT MEDCouplingField(TypeOfField type); - MEDCOUPLING_EXPORT MEDCouplingField(const MEDCouplingField& other, bool deepCopy=true); - MEDCOUPLING_EXPORT MEDCouplingField(MEDCouplingFieldDiscretization *type, NatureOfField nature=NoNature); - MEDCOUPLING_EXPORT virtual ~MEDCouplingField(); - protected: - std::string _name; - std::string _desc; - NatureOfField _nature; - const MEDCouplingMesh *_mesh; - MEDCouplingAutoRefCountObjectPtr _type; - }; -} - -#endif diff --git a/src/MEDCoupling/MEDCouplingFieldDiscretization.cxx b/src/MEDCoupling/MEDCouplingFieldDiscretization.cxx deleted file mode 100644 index 0be106c75..000000000 --- a/src/MEDCoupling/MEDCouplingFieldDiscretization.cxx +++ /dev/null @@ -1,3061 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 -// 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 "MEDCouplingFieldDiscretization.hxx" -#include "MEDCouplingCMesh.hxx" -#include "MEDCouplingUMesh.hxx" -#include "MEDCouplingFieldDouble.hxx" -#include "MEDCouplingAutoRefCountObjectPtr.hxx" - -#include "CellModel.hxx" -#include "InterpolationUtils.hxx" -#include "InterpKernelAutoPtr.hxx" -#include "InterpKernelGaussCoords.hxx" -#include "InterpKernelMatrixTools.hxx" - -#include -#include -#include -#include -#include -#include -#include - -using namespace ParaMEDMEM; - -const double MEDCouplingFieldDiscretization::DFLT_PRECISION=1.e-12; - -const char MEDCouplingFieldDiscretizationP0::REPR[]="P0"; - -const TypeOfField MEDCouplingFieldDiscretizationP0::TYPE=ON_CELLS; - -const char MEDCouplingFieldDiscretizationP1::REPR[]="P1"; - -const TypeOfField MEDCouplingFieldDiscretizationP1::TYPE=ON_NODES; - -const int MEDCouplingFieldDiscretizationPerCell::DFT_INVALID_LOCID_VALUE=-1; - -const char MEDCouplingFieldDiscretizationGauss::REPR[]="GAUSS"; - -const TypeOfField MEDCouplingFieldDiscretizationGauss::TYPE=ON_GAUSS_PT; - -const char MEDCouplingFieldDiscretizationGaussNE::REPR[]="GSSNE"; - -const TypeOfField MEDCouplingFieldDiscretizationGaussNE::TYPE=ON_GAUSS_NE; - -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_POINT1[1]={0.}; -const double MEDCouplingFieldDiscretizationGaussNE::FGP_SEG2[2]={1.,1.}; -const double MEDCouplingFieldDiscretizationGaussNE::FGP_SEG3[3]={0.5555555555555556,0.8888888888888888,0.5555555555555556}; -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_QUAD8[8]={1.,1.,1.,1.,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_TETRA10[10]={1.,1.,1.,1.,1.,1.,1.,1.,1.,1.};//to check -const double MEDCouplingFieldDiscretizationGaussNE::FGP_PENTA6[6]={0.16666666666666666,0.16666666666666666,0.16666666666666666,0.16666666666666666,0.16666666666666666,0.16666666666666666}; -const double MEDCouplingFieldDiscretizationGaussNE::FGP_PENTA15[15]={1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.};//to check -const double MEDCouplingFieldDiscretizationGaussNE::FGP_HEXA8[8]={1.,1.,1.,1.,1.,1.,1.,1.}; -const double MEDCouplingFieldDiscretizationGaussNE::FGP_HEXA20[20]={1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.}; -const double MEDCouplingFieldDiscretizationGaussNE::FGP_HEXA27[27]={1.,1.,1.,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::FGP_PYRA5[5]={0.13333333333333333,0.13333333333333333,0.13333333333333333,0.13333333333333333,0.13333333333333333}; -const double MEDCouplingFieldDiscretizationGaussNE::FGP_PYRA13[13]={1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.};//to check -const double MEDCouplingFieldDiscretizationGaussNE::REF_SEG2[2]={-1.,1.}; -const double MEDCouplingFieldDiscretizationGaussNE::REF_SEG3[3]={-1.,1.,0.}; -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.,-1.,0.,-1.,0.,1.,-1.,1.,0.,-1.,0.,-1.,-1.,-1.,0.,1.,0.,1.,1.,1.,0.,1.,0.,-1.,1.,-1.,-1.,0.,-1.,1.,0.,1.,1.,0.,1.,-1.,0.,0.,0.,-1.,-1.,0.,0.,0.,1.,0.,1.,0.,0.,0.,-1.,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}; -const double MEDCouplingFieldDiscretizationGaussNE::LOC_SEG2[2]={0.577350269189626,-0.577350269189626}; -const double MEDCouplingFieldDiscretizationGaussNE::LOC_SEG3[3]={-0.774596669241,0.,0.774596669241}; -const double MEDCouplingFieldDiscretizationGaussNE::LOC_SEG4[4]={0.339981043584856,-0.339981043584856,0.861136311594053,-0.861136311594053}; -const double MEDCouplingFieldDiscretizationGaussNE::LOC_TRI3[6]={0.16666666666666667,0.16666666666666667,0.6666666666666667,0.16666666666666667,0.16666666666666667,0.6666666666666667}; -const double MEDCouplingFieldDiscretizationGaussNE::LOC_TRI6[12]={0.091576213509771,0.091576213509771,0.816847572980458,0.091576213509771,0.091576213509771,0.816847572980458,0.445948490915965,0.10810301816807,0.445948490915965,0.445948490915965,0.10810301816807,0.445948490915965}; -const double MEDCouplingFieldDiscretizationGaussNE::LOC_TRI7[14]={0.3333333333333333,0.3333333333333333,0.470142064105115,0.470142064105115,0.05971587178977,0.470142064105115,0.470142064105115,0.05971587178977,0.101286507323456,0.101286507323456,0.797426985353088,0.101286507323456,0.101286507323456,0.797426985353088}; -const double MEDCouplingFieldDiscretizationGaussNE::LOC_QUAD4[8]={-0.774596669241483,-0.774596669241483,0.774596669241483,-0.774596669241483,0.774596669241483,0.774596669241483,-0.774596669241483,0.774596669241483}; -const double MEDCouplingFieldDiscretizationGaussNE::LOC_QUAD8[16]={-0.774596669241483,-0.774596669241483,0.774596669241483,-0.774596669241483,0.774596669241483,0.774596669241483,-0.774596669241483,0.774596669241483,0.,-0.774596669241483,0.774596669241483,0.,0.,0.774596669241483,-0.774596669241483,0.}; -const double MEDCouplingFieldDiscretizationGaussNE::LOC_QUAD9[18]={-0.774596669241483,-0.774596669241483,0.774596669241483,-0.774596669241483,0.774596669241483,0.774596669241483,-0.774596669241483,0.774596669241483,0.,-0.774596669241483,0.774596669241483,0.,0.,0.774596669241483,-0.774596669241483,0.,0.,0.}; -const double MEDCouplingFieldDiscretizationGaussNE::LOC_TETRA4[12]={0.1381966011250105,0.1381966011250105,0.1381966011250105,0.1381966011250105,0.1381966011250105,0.5854101966249685,0.1381966011250105,0.5854101966249685,0.1381966011250105,0.5854101966249685,0.1381966011250105,0.1381966011250105}; -const double MEDCouplingFieldDiscretizationGaussNE::LOC_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.};//to check -const double MEDCouplingFieldDiscretizationGaussNE::LOC_PENTA6[18]={-0.5773502691896258,0.5,0.5,-0.5773502691896258,0.,0.5,-0.5773502691896258,0.5,0.,0.5773502691896258,0.5,0.5,0.5773502691896258,0.,0.5,0.5773502691896258,0.5,0.}; -const double MEDCouplingFieldDiscretizationGaussNE::LOC_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.};//to check -const double MEDCouplingFieldDiscretizationGaussNE::LOC_HEXA8[24]={-0.5773502691896258,-0.5773502691896258,-0.5773502691896258,-0.5773502691896258,-0.5773502691896258,0.5773502691896258,-0.5773502691896258,0.5773502691896258,-0.5773502691896258,-0.5773502691896258,0.5773502691896258,0.5773502691896258,0.5773502691896258,-0.5773502691896258,-0.5773502691896258,0.5773502691896258,-0.5773502691896258,0.5773502691896258,0.5773502691896258,0.5773502691896258,-0.5773502691896258,0.5773502691896258,0.5773502691896258,0.5773502691896258}; -const double MEDCouplingFieldDiscretizationGaussNE::LOC_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.};//to check -const double MEDCouplingFieldDiscretizationGaussNE::LOC_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.,-1.,0.,-1.,0.,1.,-1.,1.,0.,-1.,0.,-1.,-1.,-1.,0.,1.,0.,1.,1.,1.,0.,1.,0.,-1.,1.,-1.,-1.,0.,-1.,1.,0.,1.,1.,0.,1.,-1.,0.,0.,0.,-1.,-1.,0.,0.,0.,1.,0.,1.,0.,0.,0.,-1.,0.,0.,0.,1.,0.,0.,0.}; -const double MEDCouplingFieldDiscretizationGaussNE::LOC_PYRA5[15]={0.5,0.,0.1531754163448146,0.,0.5,0.1531754163448146,-0.5,0.,0.1531754163448146,0.,-0.5,0.1531754163448146,0.,0.,0.6372983346207416}; -const double MEDCouplingFieldDiscretizationGaussNE::LOC_PYRA13[39]={1.,0.,0.,0.,-1.,0.,-1.,0.,0.,0.,1.,0.,0.,0.,0.999999999999,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};//to check 0.99999... to avoid nan ! on node #4 of PYRA13 - -MEDCouplingFieldDiscretization::MEDCouplingFieldDiscretization():_precision(DFLT_PRECISION) -{ -} - -MEDCouplingFieldDiscretization *MEDCouplingFieldDiscretization::New(TypeOfField type) -{ - switch(type) - { - case MEDCouplingFieldDiscretizationP0::TYPE: - return new MEDCouplingFieldDiscretizationP0; - case MEDCouplingFieldDiscretizationP1::TYPE: - return new MEDCouplingFieldDiscretizationP1; - case MEDCouplingFieldDiscretizationGauss::TYPE: - return new MEDCouplingFieldDiscretizationGauss; - case MEDCouplingFieldDiscretizationGaussNE::TYPE: - return new MEDCouplingFieldDiscretizationGaussNE; - case MEDCouplingFieldDiscretizationKriging::TYPE: - return new MEDCouplingFieldDiscretizationKriging; - default: - throw INTERP_KERNEL::Exception("Choosen discretization is not implemented yet."); - } -} - -TypeOfField MEDCouplingFieldDiscretization::GetTypeOfFieldFromStringRepr(const std::string& repr) -{ - if(repr==MEDCouplingFieldDiscretizationP0::REPR) - return MEDCouplingFieldDiscretizationP0::TYPE; - if(repr==MEDCouplingFieldDiscretizationP1::REPR) - return MEDCouplingFieldDiscretizationP1::TYPE; - if(repr==MEDCouplingFieldDiscretizationGauss::REPR) - return MEDCouplingFieldDiscretizationGauss::TYPE; - if(repr==MEDCouplingFieldDiscretizationGaussNE::REPR) - return MEDCouplingFieldDiscretizationGaussNE::TYPE; - if(repr==MEDCouplingFieldDiscretizationKriging::REPR) - return MEDCouplingFieldDiscretizationKriging::TYPE; - throw INTERP_KERNEL::Exception("Representation does not match with any field discretization !"); -} - -std::string MEDCouplingFieldDiscretization::GetTypeOfFieldRepr(TypeOfField type) -{ - if(type==MEDCouplingFieldDiscretizationP0::TYPE) - return MEDCouplingFieldDiscretizationP0::REPR; - if(type==MEDCouplingFieldDiscretizationP1::TYPE) - return MEDCouplingFieldDiscretizationP1::REPR; - if(type==MEDCouplingFieldDiscretizationGauss::TYPE) - return MEDCouplingFieldDiscretizationGauss::REPR; - if(type==MEDCouplingFieldDiscretizationGaussNE::TYPE) - return MEDCouplingFieldDiscretizationGaussNE::REPR; - if(type==MEDCouplingFieldDiscretizationKriging::TYPE) - return MEDCouplingFieldDiscretizationKriging::REPR; - throw INTERP_KERNEL::Exception("GetTypeOfFieldRepr : Representation does not match with any field discretization !"); -} - -bool MEDCouplingFieldDiscretization::isEqual(const MEDCouplingFieldDiscretization *other, double eps) const -{ - std::string reason; - return isEqualIfNotWhy(other,eps,reason); -} - -bool MEDCouplingFieldDiscretization::isEqualWithoutConsideringStr(const MEDCouplingFieldDiscretization *other, double eps) const -{ - 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. - */ -MEDCouplingFieldDiscretization *MEDCouplingFieldDiscretization::clonePart(const int *startCellIds, const int *endCellIds) 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. - */ -void MEDCouplingFieldDiscretization::updateTime() const -{ -} - -std::size_t MEDCouplingFieldDiscretization::getHeapMemorySizeWithoutChildren() const -{ - return 0; -} - -std::vector MEDCouplingFieldDiscretization::getDirectChildrenWithNull() const -{ - return std::vector(); -} - -/*! - * Computes normL1 of DataArrayDouble instance arr. - * @param res output parameter expected to be of size arr->getNumberOfComponents(); - * @throw when the field discretization fails on getMeasure fields (gauss points for example) - */ -void MEDCouplingFieldDiscretization::normL1(const MEDCouplingMesh *mesh, const DataArrayDouble *arr, double *res) const -{ - MEDCouplingAutoRefCountObjectPtr vol=getMeasureField(mesh,true); - int nbOfCompo=arr->getNumberOfComponents(); - int nbOfElems=getNumberOfTuples(mesh); - std::fill(res,res+nbOfCompo,0.); - const double *arrPtr=arr->getConstPointer(); - const double *volPtr=vol->getArray()->getConstPointer(); - double deno=0.; - for(int i=0;i(),1./deno)); -} - -/*! - * Computes normL2 of DataArrayDouble instance arr. - * @param res output parameter expected to be of size arr->getNumberOfComponents(); - * @throw when the field discretization fails on getMeasure fields (gauss points for example) - */ -void MEDCouplingFieldDiscretization::normL2(const MEDCouplingMesh *mesh, const DataArrayDouble *arr, double *res) const -{ - MEDCouplingAutoRefCountObjectPtr vol=getMeasureField(mesh,true); - int nbOfCompo=arr->getNumberOfComponents(); - int nbOfElems=getNumberOfTuples(mesh); - std::fill(res,res+nbOfCompo,0.); - const double *arrPtr=arr->getConstPointer(); - const double *volPtr=vol->getArray()->getConstPointer(); - double deno=0.; - for(int i=0;i(),1./deno)); - std::transform(res,res+nbOfCompo,res,std::ptr_fun(std::sqrt)); -} - -/*! - * Computes integral of DataArrayDouble instance arr. - * @param res output parameter expected to be of size arr->getNumberOfComponents(); - * @throw when the field discretization fails on getMeasure fields (gauss points for example) - */ -void MEDCouplingFieldDiscretization::integral(const MEDCouplingMesh *mesh, const DataArrayDouble *arr, bool isWAbs, double *res) const -{ - 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(); - INTERP_KERNEL::AutoPtr tmp=new double[nbOfCompo]; - for (int i=0;i(),volPtr[i])); - std::transform((double *)tmp,(double *)tmp+nbOfCompo,res,res,std::plus()); - } -} - -/*! - * 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 -{ - arr=0; -} - -/*! - * Empty : Not a bug - */ -void MEDCouplingFieldDiscretization::getTinySerializationIntInformation(std::vector& tinyInfo) const -{ -} - -/*! - * Empty : Not a bug - */ -void MEDCouplingFieldDiscretization::getTinySerializationDbleInformation(std::vector& tinyInfo) const -{ -} - -void MEDCouplingFieldDiscretization::resizeForUnserialization(const std::vector& tinyInfo, DataArrayInt *& arr) -{ - arr=0; -} - -/*! - * Empty : Not a bug - */ -void MEDCouplingFieldDiscretization::checkForUnserialization(const std::vector& tinyInfo, const DataArrayInt *arr) -{ -} - -/*! - * Empty : Not a bug - */ -void MEDCouplingFieldDiscretization::finishUnserialization(const std::vector& tinyInfo) -{ -} - -/*! - * This method is typically the first step of renumbering. The implementation is empty it is not a bug only gauss is impacted - * virtualy by this method. - */ -void MEDCouplingFieldDiscretization::renumberCells(const int *old2NewBg, bool check) -{ -} - -double MEDCouplingFieldDiscretization::getIJK(const MEDCouplingMesh *mesh, const DataArrayDouble *da, int cellId, int nodeIdInCell, int compoId) const -{ - throw INTERP_KERNEL::Exception("getIJK Invalid ! only for GaussPoint and GaussNE discretizations !"); -} - -void MEDCouplingFieldDiscretization::setGaussLocalizationOnType(const MEDCouplingMesh *m, INTERP_KERNEL::NormalizedCellType type, const std::vector& refCoo, - const std::vector& gsCoo, const std::vector& wg) -{ - throw INTERP_KERNEL::Exception("Invalid method for the corresponding field discretization : available only for GaussPoint discretization !"); -} - -void MEDCouplingFieldDiscretization::setGaussLocalizationOnCells(const MEDCouplingMesh *m, const int *begin, const int *end, const std::vector& refCoo, - const std::vector& gsCoo, const std::vector& wg) -{ - throw INTERP_KERNEL::Exception("Invalid method for the corresponding field discretization : available only for GaussPoint discretization !"); -} - -void MEDCouplingFieldDiscretization::clearGaussLocalizations() -{ - throw INTERP_KERNEL::Exception("Invalid method for the corresponding field discretization : available only for GaussPoint discretization !"); -} - -MEDCouplingGaussLocalization& MEDCouplingFieldDiscretization::getGaussLocalization(int locId) -{ - throw INTERP_KERNEL::Exception("Invalid method for the corresponding field discretization : available only for GaussPoint discretization !"); -} - -const MEDCouplingGaussLocalization& MEDCouplingFieldDiscretization::getGaussLocalization(int locId) const -{ - throw INTERP_KERNEL::Exception("Invalid method for the corresponding field discretization : available only for GaussPoint discretization !"); -} - -int MEDCouplingFieldDiscretization::getNbOfGaussLocalization() const -{ - throw INTERP_KERNEL::Exception("Invalid method for the corresponding field discretization : available only for GaussPoint discretization !"); -} - -int MEDCouplingFieldDiscretization::getGaussLocalizationIdOfOneCell(int cellId) const -{ - throw INTERP_KERNEL::Exception("Invalid method for the corresponding field discretization : available only for GaussPoint discretization !"); -} - -int MEDCouplingFieldDiscretization::getGaussLocalizationIdOfOneType(INTERP_KERNEL::NormalizedCellType type) const -{ - throw INTERP_KERNEL::Exception("Invalid method for the corresponding field discretization : available only for GaussPoint discretization !"); -} - -std::set MEDCouplingFieldDiscretization::getGaussLocalizationIdsOfOneType(INTERP_KERNEL::NormalizedCellType type) const -{ - throw INTERP_KERNEL::Exception("Invalid method for the corresponding field discretization : available only for GaussPoint discretization !"); -} - -void MEDCouplingFieldDiscretization::getCellIdsHavingGaussLocalization(int locId, std::vector& cellIds) const -{ - throw INTERP_KERNEL::Exception("Invalid method for the corresponding field discretization : available only for GaussPoint discretization !"); -} - -void MEDCouplingFieldDiscretization::RenumberEntitiesFromO2NArr(double eps, const int *old2NewPtr, int newNbOfEntity, DataArrayDouble *arr, const std::string& msg) -{ - if(!arr) - throw INTERP_KERNEL::Exception("MEDCouplingFieldDiscretization::RenumberEntitiesFromO2NArr : input array is NULL !"); - int oldNbOfElems=arr->getNumberOfTuples(); - int nbOfComp=arr->getNumberOfComponents(); - int newNbOfTuples=newNbOfEntity; - MEDCouplingAutoRefCountObjectPtr arrCpy=arr->deepCpy(); - const double *ptSrc=arrCpy->getConstPointer(); - arr->reAlloc(newNbOfTuples); - double *ptToFill=arr->getPointer(); - std::fill(ptToFill,ptToFill+nbOfComp*newNbOfTuples,std::numeric_limits::max()); - INTERP_KERNEL::AutoPtr tmp=new double[nbOfComp]; - for(int i=0;i=0)//if newNb<0 the node is considered as out. - { - if(std::find_if(ptToFill+newNb*nbOfComp,ptToFill+(newNb+1)*nbOfComp,std::bind2nd(std::not_equal_to(),std::numeric_limits::max())) - ==ptToFill+(newNb+1)*nbOfComp) - std::copy(ptSrc+i*nbOfComp,ptSrc+(i+1)*nbOfComp,ptToFill+newNb*nbOfComp); - else - { - std::transform(ptSrc+i*nbOfComp,ptSrc+(i+1)*nbOfComp,ptToFill+newNb*nbOfComp,(double *)tmp,std::minus()); - std::transform((double *)tmp,((double *)tmp)+nbOfComp,(double *)tmp,std::ptr_fun(fabs)); - //if(!std::equal(ptSrc+i*nbOfComp,ptSrc+(i+1)*nbOfComp,ptToFill+newNb*nbOfComp)) - if(*std::max_element((double *)tmp,((double *)tmp)+nbOfComp)>eps) - { - std::ostringstream oss; - oss << msg << " " << i << " and " << std::find(old2NewPtr,old2NewPtr+i,newNb)-old2NewPtr - << " have been merged and " << msg << " field on them are different !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - } - } - } -} - -void MEDCouplingFieldDiscretization::RenumberEntitiesFromN2OArr(const int *new2OldPtr, int new2OldSz, DataArrayDouble *arr, const std::string& msg) -{ - int nbOfComp=arr->getNumberOfComponents(); - MEDCouplingAutoRefCountObjectPtr arrCpy=arr->deepCpy(); - const double *ptSrc=arrCpy->getConstPointer(); - arr->reAlloc(new2OldSz); - double *ptToFill=arr->getPointer(); - for(int i=0;i(other); - bool ret=otherC!=0; - if(!ret) - reason="Spatial discrtization of this is ON_CELLS, which is not the case of other."; - return ret; -} - -int MEDCouplingFieldDiscretizationP0::getNumberOfTuples(const MEDCouplingMesh *mesh) const -{ - if(!mesh) - throw INTERP_KERNEL::Exception("MEDCouplingFieldDiscretizationP0::getNumberOfTuples : NULL input mesh !"); - return mesh->getNumberOfCells(); -} - -/*! - * This method returns the number of tuples regarding exclusively the input code \b without \b using \b a \b mesh \b in \b input. - * The input code coherency is also checked regarding spatial discretization of \a this. - * If an incoherency is detected, an exception will be thrown. If the input code is coherent, the number of tuples expected is returned. - * The number of tuples expected is equal to those to have a valid field lying on \a this and having a mesh fitting perfectly the input code (geometric type distribution). - */ -int MEDCouplingFieldDiscretizationP0::getNumberOfTuplesExpectedRegardingCode(const std::vector& code, const std::vector& idsPerType) const -{ - if(code.size()%3!=0) - throw INTERP_KERNEL::Exception("MEDCouplingFieldDiscretizationP0::getNumberOfTuplesExpectedRegardingCode : invalid input code !"); - int nbOfSplit=(int)idsPerType.size(); - int nbOfTypes=(int)code.size()/3; - int ret=0; - for(int i=0;i=nbOfSplit) - { - std::ostringstream oss; oss << "MEDCouplingFieldDiscretizationP0::getNumberOfTuplesExpectedRegardingCode : input code points to pos " << pos << " in typeid " << i << " ! Should be in [0," << nbOfSplit << ") !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - const DataArrayInt *ids(idsPerType[pos]); - if(!ids || !ids->isAllocated() || ids->getNumberOfComponents()!=1 || ids->getNumberOfTuples()!=nbOfEltInChunk || ids->getMinValueInArray()<0) - { - std::ostringstream oss; oss << "MEDCouplingFieldDiscretizationP0::getNumberOfTuplesExpectedRegardingCode : input pfl chunck at pos " << pos << " should have " << i << " tuples and one component and with ids all >=0 !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - } - ret+=nbOfEltInChunk; - } - return ret; -} - -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); - ret->iota(0); - return ret; -} - -void MEDCouplingFieldDiscretizationP0::renumberArraysForCell(const MEDCouplingMesh *mesh, const std::vector& arrays, - const int *old2NewBg, bool check) -{ - 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++) - { - if(*it) - (*it)->renumberInPlace(array); - } - if(check) - 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 *tupleIdsBg, const int *tupleIdsEnd, - DataArrayInt *&cellRestriction, DataArrayInt *&trueTupleRestriction) const -{ - 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 -{ - stream << "P0 spatial discretization."; -} - -void MEDCouplingFieldDiscretizationP0::checkCompatibilityWithNature(NatureOfField nat) const -{ -} - -void MEDCouplingFieldDiscretizationP0::checkCoherencyBetween(const MEDCouplingMesh *mesh, const DataArray *da) const -{ - if(!mesh || !da) - throw INTERP_KERNEL::Exception("MEDCouplingFieldDiscretizationP0::checkCoherencyBetween : NULL input mesh or DataArray !"); - if(mesh->getNumberOfCells()!=da->getNumberOfTuples()) - { - std::ostringstream message; - message << "Field on cells invalid because there are " << mesh->getNumberOfCells(); - message << " cells in mesh and " << da->getNumberOfTuples() << " tuples in field !"; - throw INTERP_KERNEL::Exception(message.str().c_str()); - } -} - -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 !"); - arr->getTuple(id,res); -} - -void MEDCouplingFieldDiscretizationP0::getValueOnPos(const DataArrayDouble *arr, const MEDCouplingMesh *mesh, int i, int j, int k, double *res) const -{ - const MEDCouplingCMesh *meshC=dynamic_cast(mesh); - if(!meshC) - throw INTERP_KERNEL::Exception("P0::getValueOnPos is only accessible for structured meshes !"); - int id=meshC->getCellIdFromPos(i,j,k); - arr->getTuple(id,res); -} - -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 !"); - MEDCouplingAutoRefCountObjectPtr eltsArr,eltsIndexArr; - mesh->getCellsContainingPoints(loc,nbOfPoints,_precision,eltsArr,eltsIndexArr); - const int *elts(eltsArr->begin()),*eltsIndex(eltsIndexArr->begin()); - int spaceDim=mesh->getSpaceDimension(); - int nbOfComponents=arr->getNumberOfComponents(); - MEDCouplingAutoRefCountObjectPtr ret=DataArrayDouble::New(); - ret->alloc(nbOfPoints,nbOfComponents); - double *ptToFill=ret->getPointer(); - for(int i=0;i=1) - arr->getTuple(elts[eltsIndex[i]],ptToFill); - else - { - std::ostringstream oss; oss << "Point #" << i << " with coordinates : ("; - std::copy(loc+i*spaceDim,loc+(i+1)*spaceDim,std::ostream_iterator(oss,", ")); - oss << ") detected outside mesh : unable to apply P0::getValueOnMulti ! "; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - return ret.retn(); -} - -/*! - * Nothing to do. It's not a bug. - */ -void MEDCouplingFieldDiscretizationP0::renumberValuesOnNodes(double , const int *, int newNbOfNodes, DataArrayDouble *) const -{ -} - -void MEDCouplingFieldDiscretizationP0::renumberValuesOnCells(double epsOnVals, const MEDCouplingMesh *mesh, const int *old2New, int newSz, DataArrayDouble *arr) const -{ - RenumberEntitiesFromO2NArr(epsOnVals,old2New,newSz,arr,"Cell"); -} - -void MEDCouplingFieldDiscretizationP0::renumberValuesOnCellsR(const MEDCouplingMesh *mesh, const int *new2old, int newSz, DataArrayDouble *arr) const -{ - RenumberEntitiesFromN2OArr(new2old,newSz,arr,"Cell"); -} - -/*! - * This method returns a tuple ids selection from cell ids selection [start;end). - * This method is called by MEDCouplingFieldDiscretizationP0::buildSubMeshData to return parameter \b di. - * Here for P0 it's very simple ! - * - * \return a newly allocated array containing ids to select into the DataArrayDouble of the field. - * - */ -DataArrayInt *MEDCouplingFieldDiscretizationP0::computeTupleIdsToSelectFromCellIds(const MEDCouplingMesh *mesh, const int *startCellIds, const int *endCellIds) const -{ - MEDCouplingAutoRefCountObjectPtr ret=DataArrayInt::New(); - ret->alloc((int)std::distance(startCellIds,endCellIds),1); - std::copy(startCellIds,endCellIds,ret->getPointer()); - 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 -{ - 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(); -} - -/*! - * 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 -{ - if(!mesh) - throw INTERP_KERNEL::Exception("MEDCouplingFieldDiscretizationNodes::getNumberOfTuples : NULL input mesh !"); - return mesh->getNumberOfNodes(); -} - -/*! - * This method returns the number of tuples regarding exclusively the input code \b without \b using \b a \b mesh \b in \b input. - * The input code coherency is also checked regarding spatial discretization of \a this. - * If an incoherency is detected, an exception will be thrown. If the input code is coherent, the number of tuples expected is returned. - * The number of tuples expected is equal to those to have a valid field lying on \a this and having a mesh fitting perfectly the input code (geometric type distribution). - */ -int MEDCouplingFieldDiscretizationOnNodes::getNumberOfTuplesExpectedRegardingCode(const std::vector& code, const std::vector& idsPerType) const -{ - if(code.size()%3!=0) - throw INTERP_KERNEL::Exception("MEDCouplingFieldDiscretizationOnNodes::getNumberOfTuplesExpectedRegardingCode : invalid input code !"); - int nbOfSplit=(int)idsPerType.size(); - int nbOfTypes=(int)code.size()/3; - int ret=0; - for(int i=0;i=nbOfSplit) - { - std::ostringstream oss; oss << "MEDCouplingFieldDiscretizationOnNodes::getNumberOfTuplesExpectedRegardingCode : input code points to pos " << pos << " in typeid " << i << " ! Should be in [0," << nbOfSplit << ") !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - const DataArrayInt *ids(idsPerType[pos]); - if(!ids || !ids->isAllocated() || ids->getNumberOfComponents()!=1 || ids->getNumberOfTuples()!=nbOfEltInChunk || ids->getMinValueInArray()<0) - { - std::ostringstream oss; oss << "MEDCouplingFieldDiscretizationOnNodes::getNumberOfTuplesExpectedRegardingCode : input pfl chunck at pos " << pos << " should have " << i << " tuples and one component and with ids all >=0 !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - } - ret+=nbOfEltInChunk; - } - return ret; -} - -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, - const int *old2NewBg, bool check) -{ -} - -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); - ret->iota(0); - return ret; -} - -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 *tupleIdsBg, const int *tupleIdsEnd, - DataArrayInt *&cellRestriction, DataArrayInt *&trueTupleRestriction) const -{ - 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 DataArray *da) const -{ - if(!mesh || !da) - throw INTERP_KERNEL::Exception("MEDCouplingFieldDiscretizationNodes::checkCoherencyBetween : NULL input mesh or DataArray !"); - if(mesh->getNumberOfNodes()!=da->getNumberOfTuples()) - { - std::ostringstream message; - message << "Field on nodes invalid because there are " << mesh->getNumberOfNodes(); - message << " nodes in mesh and " << da->getNumberOfTuples() << " tuples in field !"; - throw INTERP_KERNEL::Exception(message.str().c_str()); - } -} - -/*! - * 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 nodes ids) in mesh 'mesh' of entity in returned submesh. - * Example : The first node id of returned mesh has the (*di)[0] id in 'mesh' - */ -MEDCouplingMesh *MEDCouplingFieldDiscretizationOnNodes::buildSubMeshData(const MEDCouplingMesh *mesh, const int *start, const int *end, DataArrayInt *&di) const -{ - 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(); -} - -/*! - * This method returns a tuple ids selection from cell ids selection [start;end). - * This method is called by MEDCouplingFieldDiscretizationOnNodes::buildSubMeshData to return parameter \b di. - * Here for P1 only nodes fetched by submesh of mesh[startCellIds:endCellIds) is returned ! - * - * \return a newly allocated array containing ids to select into the DataArrayDouble of the field. - * - */ -DataArrayInt *MEDCouplingFieldDiscretizationOnNodes::computeTupleIdsToSelectFromCellIds(const MEDCouplingMesh *mesh, const int *startCellIds, const int *endCellIds) const -{ - if(!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(); -} - -void MEDCouplingFieldDiscretizationOnNodes::renumberValuesOnNodes(double epsOnVals, const int *old2NewPtr, int newNbOfNodes, DataArrayDouble *arr) const -{ - RenumberEntitiesFromO2NArr(epsOnVals,old2NewPtr,newNbOfNodes,arr,"Node"); -} - -/*! - * Nothing to do it's not a bug. - */ -void MEDCouplingFieldDiscretizationOnNodes::renumberValuesOnCells(double epsOnVals, const MEDCouplingMesh *mesh, const int *old2New, int newSz, DataArrayDouble *arr) const -{ -} - -/*! - * Nothing to do it's not a bug. - */ -void MEDCouplingFieldDiscretizationOnNodes::renumberValuesOnCellsR(const MEDCouplingMesh *mesh, const int *new2old, int newSz, DataArrayDouble *arr) const -{ -} - -void MEDCouplingFieldDiscretizationOnNodes::getValueOnPos(const DataArrayDouble *arr, const MEDCouplingMesh *mesh, int i, int j, int k, double *res) const -{ - const MEDCouplingCMesh *meshC=dynamic_cast(mesh); - if(!meshC) - throw INTERP_KERNEL::Exception("OnNodes::getValueOnPos(i,j,k) is only accessible for structured meshes !"); - int id=meshC->getNodeIdFromPos(i,j,k); - arr->getTuple(id,res); -} - -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; -} - -std::string MEDCouplingFieldDiscretizationP1::getStringRepr() const -{ - return std::string(REPR); -} - -const char *MEDCouplingFieldDiscretizationP1::getRepr() const -{ - return REPR; -} - -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) - reason="Spatial discrtization of this is ON_NODES, which is not the case of other."; - return ret; -} - -void MEDCouplingFieldDiscretizationP1::checkCompatibilityWithNature(NatureOfField nat) const -{ - if(nat!=ConservativeVolumic) - throw INTERP_KERNEL::Exception("Invalid nature for P1 field : expected ConservativeVolumic !"); -} - -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 !"); - INTERP_KERNEL::NormalizedCellType type=mesh->getTypeOfCell(id); - if(type!=INTERP_KERNEL::NORM_SEG2 && type!=INTERP_KERNEL::NORM_TRI3 && type!=INTERP_KERNEL::NORM_TETRA4) - throw INTERP_KERNEL::Exception("P1 getValueOn is not specified for not simplex cells !"); - getValueInCell(mesh,id,arr,loc,res); -} - -/*! - * This method localizes a point defined by 'loc' in a cell with id 'cellId' into mesh 'mesh'. - * The result is put into res expected to be of size at least arr->getNumberOfComponents() - */ -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); - for(std::vector::const_iterator iter=conn.begin();iter!=conn.end();iter++) - mesh->getCoordinatesOfNode(*iter,coo); - int spaceDim=mesh->getSpaceDimension(); - std::size_t nbOfNodes=conn.size(); - std::vector vec(nbOfNodes); - for(std::size_t i=0;i tmp=new double[nbOfNodes]; - INTERP_KERNEL::barycentric_coords(vec,loc,tmp); - int sz=arr->getNumberOfComponents(); - INTERP_KERNEL::AutoPtr tmp2=new double[sz]; - std::fill(res,res+sz,0.); - for(std::size_t i=0;igetTuple(conn[i],(double *)tmp2); - std::transform((double *)tmp2,((double *)tmp2)+sz,(double *)tmp2,std::bind2nd(std::multiplies(),tmp[i])); - std::transform(res,res+sz,(double *)tmp2,res,std::plus()); - } -} - -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 !"); - MEDCouplingAutoRefCountObjectPtr eltsArr,eltsIndexArr; - mesh->getCellsContainingPoints(loc,nbOfPoints,_precision,eltsArr,eltsIndexArr); - const int *elts(eltsArr->begin()),*eltsIndex(eltsIndexArr->begin()); - int spaceDim=mesh->getSpaceDimension(); - int nbOfComponents=arr->getNumberOfComponents(); - MEDCouplingAutoRefCountObjectPtr ret=DataArrayDouble::New(); - ret->alloc(nbOfPoints,nbOfComponents); - double *ptToFill=ret->getPointer(); - for(int i=0;i=1) - getValueInCell(mesh,elts[eltsIndex[i]],arr,loc+i*spaceDim,ptToFill+i*nbOfComponents); - else - { - std::ostringstream oss; oss << "Point #" << i << " with coordinates : ("; - std::copy(loc+i*spaceDim,loc+(i+1)*spaceDim,std::ostream_iterator(oss,", ")); - oss << ") detected outside mesh : unable to apply P1::getValueOnMulti ! "; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - return ret.retn(); -} - -void MEDCouplingFieldDiscretizationP1::reprQuickOverview(std::ostream& stream) const -{ - stream << "P1 spatial discretization."; -} - -MEDCouplingFieldDiscretizationPerCell::MEDCouplingFieldDiscretizationPerCell():_discr_per_cell(0) -{ -} - -MEDCouplingFieldDiscretizationPerCell::~MEDCouplingFieldDiscretizationPerCell() -{ - if(_discr_per_cell) - _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; - if(arr) - { - if(startCellIds==0 && endCellIds==0) - _discr_per_cell=arr->deepCpy(); - else - _discr_per_cell=arr->selectByTupleIdSafe(startCellIds,endCellIds); - } -} - -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); -} - -std::size_t MEDCouplingFieldDiscretizationPerCell::getHeapMemorySizeWithoutChildren() const -{ - std::size_t ret(MEDCouplingFieldDiscretization::getHeapMemorySizeWithoutChildren()); - return ret; -} - -std::vector MEDCouplingFieldDiscretizationPerCell::getDirectChildrenWithNull() const -{ - std::vector ret(MEDCouplingFieldDiscretization::getDirectChildrenWithNull()); - ret.push_back(_discr_per_cell); - return ret; -} - -void MEDCouplingFieldDiscretizationPerCell::checkCoherencyBetween(const MEDCouplingMesh *mesh, const DataArray *da) const -{ - 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 !"); -} - -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 discretization of this is ON_GAUSS, which is not the case of other."; - return false; - } - if(_discr_per_cell==0) - return otherC->_discr_per_cell==0; - if(otherC->_discr_per_cell==0) - return false; - bool ret=_discr_per_cell->isEqualIfNotWhy(*otherC->_discr_per_cell,reason); - if(!ret) - reason.insert(0,"Field discretization per cell DataArrayInt given the discid per cell :"); - return ret; -} - -bool MEDCouplingFieldDiscretizationPerCell::isEqualWithoutConsideringStr(const MEDCouplingFieldDiscretization *other, double eps) const -{ - const MEDCouplingFieldDiscretizationPerCell *otherC=dynamic_cast(other); - if(!otherC) - return false; - if(_discr_per_cell==0) - return otherC->_discr_per_cell==0; - if(otherC->_discr_per_cell==0) - return false; - return _discr_per_cell->isEqualWithoutConsideringStr(*otherC->_discr_per_cell); -} - -/*! - * This method is typically the first step of renumbering. The impact on _discr_per_cell is necessary here. - * virtualy by this method. - */ -void MEDCouplingFieldDiscretizationPerCell::renumberCells(const int *old2NewBg, bool check) -{ - int nbCells=_discr_per_cell->getNumberOfTuples(); - const int *array=old2NewBg; - if(check) - array=DataArrayInt::CheckAndPreparePermutation(old2NewBg,old2NewBg+nbCells); - // - DataArrayInt *dpc=_discr_per_cell->renumber(array); - _discr_per_cell->decrRef(); - _discr_per_cell=dpc; - // - if(check) - free(const_cast(array)); -} - -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=mesh->getNumberOfCells(); - _discr_per_cell->alloc(nbTuples,1); - int *ptr=_discr_per_cell->getPointer(); - std::fill(ptr,ptr+nbTuples,DFT_INVALID_LOCID_VALUE); - } -} - -void MEDCouplingFieldDiscretizationPerCell::checkNoOrphanCells() const -{ - if(!_discr_per_cell) - throw INTERP_KERNEL::Exception("MEDCouplingFieldDiscretizationPerCell::checkNoOrphanCells : no discretization defined !"); - MEDCouplingAutoRefCountObjectPtr test=_discr_per_cell->getIdsEqual(DFT_INVALID_LOCID_VALUE); - if(test->getNumberOfTuples()!=0) - 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 -{ - 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) -{ - 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() -{ -} - -MEDCouplingFieldDiscretizationGauss::MEDCouplingFieldDiscretizationGauss(const MEDCouplingFieldDiscretizationGauss& other, const int *startCellIds, const int *endCellIds):MEDCouplingFieldDiscretizationPerCell(other,startCellIds,endCellIds),_loc(other._loc) -{ -} - -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; -} - -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) - { - reason="Spatial discrtization of this is ON_GAUSS, which is not the case of other."; - return false; - } - if(!MEDCouplingFieldDiscretizationPerCell::isEqualIfNotWhy(other,eps,reason)) - return false; - if(_loc.size()!=otherC->_loc.size()) - { - reason="Gauss spatial discretization : localization sizes differ"; - return false; - } - std::size_t sz=_loc.size(); - for(std::size_t i=0;i_loc[i],eps)) - { - std::ostringstream oss; oss << "Gauss spatial discretization : Localization #" << i << " differ from this to other."; - reason=oss.str(); - return false; - } - return true; -} - -bool MEDCouplingFieldDiscretizationGauss::isEqualWithoutConsideringStr(const MEDCouplingFieldDiscretization *other, double eps) const -{ - const MEDCouplingFieldDiscretizationGauss *otherC=dynamic_cast(other); - if(!otherC) - return false; - if(!MEDCouplingFieldDiscretizationPerCell::isEqualWithoutConsideringStr(other,eps)) - return false; - if(_loc.size()!=otherC->_loc.size()) - return false; - std::size_t sz=_loc.size(); - for(std::size_t i=0;i_loc[i],eps)) - return false; - 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); -} - -MEDCouplingFieldDiscretization *MEDCouplingFieldDiscretizationGauss::clonePart(const int *startCellIds, const int *endCellIds) const -{ - 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; - if(_discr_per_cell) - { - if(_discr_per_cell->isAllocated()) - { - oss << "Discretization per cell : "; - std::copy(_discr_per_cell->begin(),_discr_per_cell->end(),std::ostream_iterator(oss,", ")); - oss << std::endl; - } - } - oss << "Presence of " << _loc.size() << " localizations." << std::endl; - int i=0; - for(std::vector::const_iterator it=_loc.begin();it!=_loc.end();it++,i++) - { - oss << "+++++ Localization #" << i << " +++++" << std::endl; - oss << (*it).getStringRepr(); - oss << "++++++++++" << std::endl; - } - return oss.str(); -} - -std::size_t MEDCouplingFieldDiscretizationGauss::getHeapMemorySizeWithoutChildren() const -{ - std::size_t ret(MEDCouplingFieldDiscretizationPerCell::getHeapMemorySizeWithoutChildren()); - ret+=_loc.capacity()*sizeof(MEDCouplingGaussLocalization); - for(std::vector::const_iterator it=_loc.begin();it!=_loc.end();it++) - ret+=(*it).getMemorySize(); - return ret; -} - -const char *MEDCouplingFieldDiscretizationGauss::getRepr() const -{ - return REPR; -} - -/*! - * This method returns the number of tuples regarding exclusively the input code \b without \b using \b a \b mesh \b in \b input. - * The input code coherency is also checked regarding spatial discretization of \a this. - * If an incoherency is detected, an exception will be thrown. If the input code is coherent, the number of tuples expected is returned. - * The number of tuples expected is equal to those to have a valid field lying on \a this and having a mesh fitting perfectly the input code (geometric type distribution). - */ -int MEDCouplingFieldDiscretizationGauss::getNumberOfTuplesExpectedRegardingCode(const std::vector& code, const std::vector& idsPerType) const -{ - if(!_discr_per_cell || !_discr_per_cell->isAllocated() || _discr_per_cell->getNumberOfComponents()!=1) - throw INTERP_KERNEL::Exception("MEDCouplingFieldDiscretizationGauss::getNumberOfTuplesExpectedRegardingCode"); - if(code.size()%3!=0) - throw INTERP_KERNEL::Exception("MEDCouplingFieldDiscretizationGauss::getNumberOfTuplesExpectedRegardingCode : invalid input code !"); - int nbOfSplit=(int)idsPerType.size(); - int nbOfTypes=(int)code.size()/3; - int ret=0; - for(int i=0;i=nbOfSplit) - { - std::ostringstream oss; oss << "MEDCouplingFieldDiscretizationGauss::getNumberOfTuplesExpectedRegardingCode : input code points to pos " << pos << " in typeid " << i << " ! Should be in [0," << nbOfSplit << ") !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - const DataArrayInt *ids(idsPerType[pos]); - if(!ids || !ids->isAllocated() || ids->getNumberOfComponents()!=1 || ids->getNumberOfTuples()!=nbOfEltInChunk || ids->getMinValueInArray()<0) - { - std::ostringstream oss; oss << "MEDCouplingFieldDiscretizationGauss::getNumberOfTuplesExpectedRegardingCode : input pfl chunck at pos " << pos << " should have " << i << " tuples and one component and with ids all >=0 !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - } - ret+=nbOfEltInChunk; - } - if(ret!=_discr_per_cell->getNumberOfTuples()) - { - std::ostringstream oss; oss << "MEDCouplingFieldDiscretizationGauss::getNumberOfTuplesExpectedRegardingCode : input code points to " << ret << " cells whereas discretization percell array lgth is " << _discr_per_cell->getNumberOfTuples() << " !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - return getNumberOfTuples(0);//0 is not an error ! It is to be sure that input mesh is not used -} - -int MEDCouplingFieldDiscretizationGauss::getNumberOfTuples(const MEDCouplingMesh *) const -{ - 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(); - int maxSz=(int)_loc.size(); - for(const int *w=dcPtr;w!=dcPtr+nbOfTuples;w++) - { - if(*w>=0 && *wgetNumberOfCells(); -} - -/*! - * 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); - int *retPtr=ret->getPointer(); - const int *start=_discr_per_cell->getConstPointer(); - if(_discr_per_cell->getNumberOfTuples()!=nbOfTuples) - throw INTERP_KERNEL::Exception("MEDCouplingFieldDiscretizationGauss::getOffsetArr : mismatch between the mesh and the discretization ids array length !"); - int maxPossible=(int)_loc.size(); - retPtr[0]=0; - for(int i=0;i=0 && *start& arrays, - const int *old2NewBg, bool check) -{ - if(!mesh) - throw INTERP_KERNEL::Exception("MEDCouplingFieldDiscretizationGauss::renumberArraysForCell : NULL input mesh !"); - const int *array=old2NewBg; - if(check) - array=DataArrayInt::CheckAndPreparePermutation(old2NewBg,old2NewBg+mesh->getNumberOfCells()); - int nbOfCells=_discr_per_cell->getNumberOfTuples(); - int nbOfTuples=getNumberOfTuples(0); - const int *dcPtr=_discr_per_cell->getConstPointer(); - int *array2=new int[nbOfTuples];//stores the final conversion array old2New to give to arrays in renumberInPlace. - int *array3=new int[nbOfCells];//store for each cell in present dcp array (already renumbered) the offset needed by each cell in new numbering. - array3[0]=0; - for(int i=1;i::const_iterator it=arrays.begin();it!=arrays.end();it++) - if(*it) - (*it)->renumberInPlace(array2); - delete [] array2; - if(check) - 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); - MEDCouplingAutoRefCountObjectPtr ret=DataArrayDouble::New(); - int spaceDim=mesh->getSpaceDimension(); - ret->alloc(nbOfTuples,spaceDim); - std::vector< int > locIds; - std::vector parts=splitIntoSingleGaussDicrPerCellType(locIds); - std::vector< MEDCouplingAutoRefCountObjectPtr > parts2(parts.size()); - std::copy(parts.begin(),parts.end(),parts2.begin()); - MEDCouplingAutoRefCountObjectPtr offsets=buildNbOfGaussPointPerCellField(); - offsets->computeOffsets(); - const int *ptrOffsets=offsets->getConstPointer(); - const double *coords=umesh->getCoords()->getConstPointer(); - const int *connI=umesh->getNodalConnectivityIndex()->getConstPointer(); - const int *conn=umesh->getNodalConnectivity()->getConstPointer(); - double *valsToFill=ret->getPointer(); - for(std::size_t i=0;i& wg=cli.getWeights(); - calculator.addGaussInfo(typ,INTERP_KERNEL::CellModel::GetCellModel(typ).getDimension(), - &cli.getGaussCoords()[0],(int)wg.size(),&cli.getRefCoords()[0], - INTERP_KERNEL::CellModel::GetCellModel(typ).getNumberOfNodes()); - // - int nbt=parts2[i]->getNumberOfTuples(); - for(const int *w=parts2[i]->getConstPointer();w!=parts2[i]->getConstPointer()+nbt;w++) - calculator.calculateCoords(cli.getType(),coords,spaceDim,conn+connI[*w]+1,valsToFill+spaceDim*(ptrOffsets[*w])); - } - ret->copyStringInfoFrom(*umesh->getCoords()); - return ret.retn(); -} - -void MEDCouplingFieldDiscretizationGauss::computeMeshRestrictionFromTupleIds(const MEDCouplingMesh *mesh, const int *tupleIdsBg, const int *tupleIdsEnd, - DataArrayInt *&cellRestriction, DataArrayInt *&trueTupleRestriction) const -{ - 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); -} - -/*! - * Empty : not a bug - */ -void MEDCouplingFieldDiscretizationGauss::checkCompatibilityWithNature(NatureOfField nat) const -{ -} - -void MEDCouplingFieldDiscretizationGauss::getTinySerializationIntInformation(std::vector& tinyInfo) const -{ - int val=-1; - if(_discr_per_cell) - val=_discr_per_cell->getNumberOfTuples(); - tinyInfo.push_back(val); - tinyInfo.push_back((int)_loc.size()); - if(_loc.empty()) - tinyInfo.push_back(-1); - else - tinyInfo.push_back(_loc[0].getDimension()); - for(std::vector::const_iterator iter=_loc.begin();iter!=_loc.end();iter++) - (*iter).pushTinySerializationIntInfo(tinyInfo); -} - -void MEDCouplingFieldDiscretizationGauss::getTinySerializationDbleInformation(std::vector& tinyInfo) const -{ - for(std::vector::const_iterator iter=_loc.begin();iter!=_loc.end();iter++) - (*iter).pushTinySerializationDblInfo(tinyInfo); -} - -void MEDCouplingFieldDiscretizationGauss::getSerializationIntArray(DataArrayInt *& arr) const -{ - arr=0; - if(_discr_per_cell) - arr=_discr_per_cell; -} - -void MEDCouplingFieldDiscretizationGauss::resizeForUnserialization(const std::vector& tinyInfo, DataArrayInt *& arr) -{ - int val=tinyInfo[0]; - if(val>=0) - { - _discr_per_cell=DataArrayInt::New(); - _discr_per_cell->alloc(val,1); - } - else - _discr_per_cell=0; - arr=_discr_per_cell; - commonUnserialization(tinyInfo); -} - -void MEDCouplingFieldDiscretizationGauss::checkForUnserialization(const std::vector& tinyInfo, const DataArrayInt *arr) -{ - static const char MSG[]="MEDCouplingFieldDiscretizationGauss::checkForUnserialization : expect to have one not null DataArrayInt !"; - int val=tinyInfo[0]; - if(val>=0) - { - if(!arr) - throw INTERP_KERNEL::Exception(MSG); - arr->checkNbOfTuplesAndComp(val,1,MSG); - _discr_per_cell=const_cast(arr); - _discr_per_cell->incrRef(); - } - else - _discr_per_cell=0; - commonUnserialization(tinyInfo); -} - -void MEDCouplingFieldDiscretizationGauss::finishUnserialization(const std::vector& tinyInfo) -{ - double *tmp=new double[tinyInfo.size()]; - std::copy(tinyInfo.begin(),tinyInfo.end(),tmp); - const double *work=tmp; - for(std::vector::iterator iter=_loc.begin();iter!=_loc.end();iter++) - work=(*iter).fillWithValues(work); - delete [] tmp; -} - -double MEDCouplingFieldDiscretizationGauss::getIJK(const MEDCouplingMesh *mesh, const DataArrayDouble *da, int cellId, int nodeIdInCell, int compoId) const -{ - int offset=getOffsetOfCell(cellId); - return da->getIJ(offset+nodeIdInCell,compoId); -} - -void MEDCouplingFieldDiscretizationGauss::checkCoherencyBetween(const MEDCouplingMesh *mesh, const DataArray *da) const -{ - 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(); - int nbOfDesc=(int)_loc.size(); - int nbOfCells=mesh->getNumberOfCells(); - const int *dc=_discr_per_cell->getConstPointer(); - for(int i=0;i=nbOfDesc) - { - std::ostringstream oss; oss << "Cell # " << i << " of mesh \"" << mesh->getName() << "\" has an undefined gauss location ! Should never happend !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - if(dc[i]<0) - { - std::ostringstream oss; oss << "Cell # " << i << " of mesh \"" << mesh->getName() << "\" has no gauss location !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - if(mesh->getTypeOfCell(i)!=_loc[dc[i]].getType()) - { - std::ostringstream oss; oss << "Types of mesh and gauss location mismatch for cell # " << i; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - } - int nbOfTuples=getNumberOfTuples(mesh); - if(nbOfTuples!=da->getNumberOfTuples()) - { - std::ostringstream oss; oss << "Invalid number of tuples in the array : expecting " << nbOfTuples << " !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } -} - -MEDCouplingFieldDouble *MEDCouplingFieldDiscretizationGauss::getMeasureField(const MEDCouplingMesh *mesh, bool isAbs) const -{ - 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 -{ - throw INTERP_KERNEL::Exception("Not implemented yet !"); -} - -void MEDCouplingFieldDiscretizationGauss::getValueOnPos(const DataArrayDouble *arr, const MEDCouplingMesh *mesh, int i, int j, int k, double *res) const -{ - throw INTERP_KERNEL::Exception("getValueOnPos(i,j,k) : Not applyable for Gauss points !"); -} - -DataArrayDouble *MEDCouplingFieldDiscretizationGauss::getValueOnMulti(const DataArrayDouble *arr, const MEDCouplingMesh *mesh, const double *loc, int nbOfPoints) const -{ - throw INTERP_KERNEL::Exception("getValueOnMulti : Not implemented yet for gauss points !"); -} - -MEDCouplingMesh *MEDCouplingFieldDiscretizationGauss::buildSubMeshData(const MEDCouplingMesh *mesh, const int *start, const int *end, DataArrayInt *&di) const -{ - 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(); -} - -/*! - * This method returns a tuple ids selection from cell ids selection [start;end). - * This method is called by MEDCouplingFieldDiscretizationGauss::buildSubMeshData to return parameter \b di. - * - * \return a newly allocated array containing ids to select into the DataArrayDouble of the field. - * - */ -DataArrayInt *MEDCouplingFieldDiscretizationGauss::computeTupleIdsToSelectFromCellIds(const MEDCouplingMesh *mesh, const int *startCellIds, const int *endCellIds) const -{ - if(!mesh) - throw INTERP_KERNEL::Exception("MEDCouplingFieldDiscretizationGauss::computeTupleIdsToSelectFromCellIds : null mesh !"); - 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 !"); - nbOfNodesPerCell->computeOffsets2(); - MEDCouplingAutoRefCountObjectPtr sel=DataArrayInt::New(); sel->useArray(startCellIds,false,CPP_DEALLOC,(int)std::distance(startCellIds,endCellIds),1); - return sel->buildExplicitArrByRanges(nbOfNodesPerCell); -} - -/*! - * No implementation needed ! - */ -void MEDCouplingFieldDiscretizationGauss::renumberValuesOnNodes(double , const int *, int newNbOfNodes, DataArrayDouble *) const -{ -} - -void MEDCouplingFieldDiscretizationGauss::renumberValuesOnCells(double epsOnVals, const MEDCouplingMesh *mesh, const int *old2New, int newSz, DataArrayDouble *arr) const -{ - throw INTERP_KERNEL::Exception("Not implemented yet !"); -} - -void MEDCouplingFieldDiscretizationGauss::renumberValuesOnCellsR(const MEDCouplingMesh *mesh, const int *new2old, int newSz, DataArrayDouble *arr) const -{ - 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 *mesh, INTERP_KERNEL::NormalizedCellType type, const std::vector& refCoo, - const std::vector& gsCoo, const std::vector& wg) -{ - 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()!=mesh->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(mesh); - int id=(int)_loc.size(); - MEDCouplingGaussLocalization elt(type,refCoo,gsCoo,wg); - _loc.push_back(elt); - int *ptr=_discr_per_cell->getPointer(); - int nbCells=mesh->getNumberOfCells(); - for(int i=0;igetTypeOfCell(i)==type) - ptr[i]=id; - zipGaussLocalizations(); -} - -void MEDCouplingFieldDiscretizationGauss::setGaussLocalizationOnCells(const MEDCouplingMesh *mesh, const int *begin, const int *end, const std::vector& refCoo, - const std::vector& gsCoo, const std::vector& wg) -{ - 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=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(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()); - } - } - // - for(const int *w2=begin;w2!=end;w2++) - ptr[*w2]=id; - // - _loc.push_back(elt); - zipGaussLocalizations(); -} - -void MEDCouplingFieldDiscretizationGauss::clearGaussLocalizations() -{ - if(_discr_per_cell) - { - _discr_per_cell->decrRef(); - _discr_per_cell=0; - } - _loc.clear(); -} - -void MEDCouplingFieldDiscretizationGauss::setGaussLocalization(int locId, const MEDCouplingGaussLocalization& loc) -{ - 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) -{ - 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) -{ - checkLocalizationId(locId); - return _loc[locId]; -} - -int MEDCouplingFieldDiscretizationGauss::getNbOfGaussLocalization() const -{ - return (int)_loc.size(); -} - -int MEDCouplingFieldDiscretizationGauss::getGaussLocalizationIdOfOneCell(int cellId) const -{ - if(!_discr_per_cell) - throw INTERP_KERNEL::Exception("No Gauss localization still set !"); - int locId=_discr_per_cell->begin()[cellId]; - if(locId<0) - throw INTERP_KERNEL::Exception("No Gauss localization set for the specified cell !"); - return locId; -} - -int MEDCouplingFieldDiscretizationGauss::getGaussLocalizationIdOfOneType(INTERP_KERNEL::NormalizedCellType type) const -{ - std::set ret=getGaussLocalizationIdsOfOneType(type); - if(ret.empty()) - throw INTERP_KERNEL::Exception("No gauss discretization found for the specified type !"); - if(ret.size()>1) - throw INTERP_KERNEL::Exception("Several gauss discretizations have been found for the specified type !"); - return *ret.begin(); -} - -std::set MEDCouplingFieldDiscretizationGauss::getGaussLocalizationIdsOfOneType(INTERP_KERNEL::NormalizedCellType type) const -{ - if(!_discr_per_cell) - throw INTERP_KERNEL::Exception("No Gauss localization still set !"); - std::set ret; - int id=0; - for(std::vector::const_iterator iter=_loc.begin();iter!=_loc.end();iter++,id++) - if((*iter).getType()==type) - ret.insert(id); - return ret; -} - -void MEDCouplingFieldDiscretizationGauss::getCellIdsHavingGaussLocalization(int locId, std::vector& cellIds) const -{ - if(locId<0 || locId>=(int)_loc.size()) - throw INTERP_KERNEL::Exception("Invalid locId given : must be in range [0:getNbOfGaussLocalization()) !"); - int nbOfTuples=_discr_per_cell->getNumberOfTuples(); - const int *ptr=_discr_per_cell->getConstPointer(); - for(int i=0;i=(int)_loc.size()) - throw INTERP_KERNEL::Exception("Invalid locId given : must be in range [0:getNbOfGaussLocalization()) !"); -} - -int MEDCouplingFieldDiscretizationGauss::getOffsetOfCell(int cellId) const -{ - int ret=0; - const int *start=_discr_per_cell->getConstPointer(); - for(const int *w=start;w!=start+cellId;w++) - ret+=_loc[*w].getNumberOfGaussPt(); - return ret; -} - -/*! - * This method do the assumption that there is no orphan cell. If there is an exception is thrown. - * This method makes the assumption too that '_discr_per_cell' is defined. If not an exception is thrown. - * This method returns a newly created array with number of tuples equals to '_discr_per_cell->getNumberOfTuples' and number of components equal to 1. - * The i_th tuple in returned array is the number of gauss point if the corresponding cell. - */ -DataArrayInt *MEDCouplingFieldDiscretizationGauss::buildNbOfGaussPointPerCellField() const -{ - if(!_discr_per_cell) - 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->begin(); - ret->alloc(nbOfTuples,1); - int *valsToFill=ret->getPointer(); - int nbMaxOfLocId=(int)_loc.size(); - for(int i=0;i=0 && *wbegin(); - int nbOfTuples=_discr_per_cell->getNumberOfTuples(); - INTERP_KERNEL::AutoPtr tmp=new int[_loc.size()]; - std::fill((int *)tmp,(int *)tmp+_loc.size(),-2); - for(const int *w=start;w!=start+nbOfTuples;w++) - if(*w>=0) - tmp[*w]=1; - int fid=0; - for(int i=0;i<(int)_loc.size();i++) - if(tmp[i]!=-2) - tmp[i]=fid++; - if(fid==(int)_loc.size()) - return; - // zip needed - int *start2=_discr_per_cell->getPointer(); - for(int *w2=start2;w2!=start2+nbOfTuples;w2++) - if(*w2>=0) - *w2=tmp[*w2]; - std::vector tmpLoc; - for(int i=0;i<(int)_loc.size();i++) - if(tmp[i]!=-2) - tmpLoc.push_back(_loc[i]); - _loc=tmpLoc; -} - -void MEDCouplingFieldDiscretizationGauss::commonUnserialization(const std::vector& tinyInfo) -{ - int nbOfLoc=tinyInfo[1]; - _loc.clear(); - int dim=tinyInfo[2]; - int delta=-1; - if(nbOfLoc>0) - delta=((int)tinyInfo.size()-3)/nbOfLoc; - for(int i=0;i tmp(tinyInfo.begin()+3+i*delta,tinyInfo.begin()+3+(i+1)*delta); - MEDCouplingGaussLocalization elt=MEDCouplingGaussLocalization::BuildNewInstanceFromTinyInfo(dim,tmp); - _loc.push_back(elt); - } -} - -MEDCouplingFieldDiscretizationGaussNE::MEDCouplingFieldDiscretizationGaussNE() -{ -} - -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); -} - -std::string MEDCouplingFieldDiscretizationGaussNE::getStringRepr() const -{ - return std::string(REPR); -} - -const char *MEDCouplingFieldDiscretizationGaussNE::getRepr() const -{ - return REPR; -} - -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) - reason="Spatial discrtization of this is ON_GAUSS_NE, which is not the case of other."; - return ret; -} - -/*! - * This method returns the number of tuples regarding exclusively the input code \b without \b using \b a \b mesh \b in \b input. - * The input code coherency is also checked regarding spatial discretization of \a this. - * If an incoherency is detected, an exception will be thrown. If the input code is coherent, the number of tuples expected is returned. - * The number of tuples expected is equal to those to have a valid field lying on \a this and having a mesh fitting perfectly the input code (geometric type distribution). - */ -int MEDCouplingFieldDiscretizationGaussNE::getNumberOfTuplesExpectedRegardingCode(const std::vector& code, const std::vector& idsPerType) const -{ - if(code.size()%3!=0) - throw INTERP_KERNEL::Exception("MEDCouplingFieldDiscretizationGaussNE::getNumberOfTuplesExpectedRegardingCode : invalid input code !"); - int nbOfSplit=(int)idsPerType.size(); - int nbOfTypes=(int)code.size()/3; - int ret(0); - for(int i=0;i=nbOfSplit) - { - std::ostringstream oss; oss << "MEDCouplingFieldDiscretizationGaussNE::getNumberOfTuplesExpectedRegardingCode : input code points to pos " << pos << " in typeid " << i << " ! Should be in [0," << nbOfSplit << ") !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - const DataArrayInt *ids(idsPerType[pos]); - if(!ids || !ids->isAllocated() || ids->getNumberOfComponents()!=1 || ids->getNumberOfTuples()!=nbOfEltInChunk || ids->getMinValueInArray()<0) - { - std::ostringstream oss; oss << "MEDCouplingFieldDiscretizationGaussNE::getNumberOfTuplesExpectedRegardingCode : input pfl chunck at pos " << pos << " should have " << i << " tuples and one component and with ids all >=0 !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - } - ret+=nbOfEltInChunk*(int)cm.getNumberOfNodes(); - } - return ret; -} - -int MEDCouplingFieldDiscretizationGaussNE::getNumberOfTuples(const MEDCouplingMesh *mesh) const -{ - if(!mesh) - throw INTERP_KERNEL::Exception("MEDCouplingFieldDiscretizationGaussNE::getNumberOfTuples : NULL input mesh !"); - int ret=0; - int nbOfCells=mesh->getNumberOfCells(); - for(int i=0;igetTypeOfCell(i); - const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(type); - if(cm.isDynamic()) - throw INTERP_KERNEL::Exception("Not implemented yet Gauss node on elements for polygons and polyedrons !"); - ret+=cm.getNumberOfNodes(); - } - return ret; -} - -int MEDCouplingFieldDiscretizationGaussNE::getNumberOfMeshPlaces(const MEDCouplingMesh *mesh) const -{ - if(!mesh) - throw INTERP_KERNEL::Exception("MEDCouplingFieldDiscretizationGaussNE::getNumberOfMeshPlaces : NULL input mesh !"); - return mesh->getNumberOfCells(); -} - -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); - int *retPtr=ret->getPointer(); - retPtr[0]=0; - for(int i=0;igetTypeOfCell(i); - const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(type); - if(cm.isDynamic()) - throw INTERP_KERNEL::Exception("Not implemented yet Gauss node on elements for polygons and polyedrons !"); - retPtr[i+1]=retPtr[i]+cm.getNumberOfNodes(); - } - return ret; -} - -void MEDCouplingFieldDiscretizationGaussNE::renumberArraysForCell(const MEDCouplingMesh *mesh, const std::vector& arrays, - const int *old2NewBg, bool check) -{ - if(!mesh) - throw INTERP_KERNEL::Exception("MEDCouplingFieldDiscretizationGaussNE::renumberArraysForCell : NULL input mesh !"); - const int *array=old2NewBg; - if(check) - array=DataArrayInt::CheckAndPreparePermutation(old2NewBg,old2NewBg+mesh->getNumberOfCells()); - int nbOfCells=mesh->getNumberOfCells(); - int nbOfTuples=getNumberOfTuples(mesh); - int *array2=new int[nbOfTuples];//stores the final conversion array old2New to give to arrays in renumberInPlace. - int *array3=new int[nbOfCells];//store for each cell in after renumbering the offset needed by each cell in new numbering. - array3[0]=0; - for(int i=1;igetTypeOfCell((int)std::distance(array,std::find(array,array+nbOfCells,i-1))); - const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(type); - array3[i]=array3[i-1]+cm.getNumberOfNodes(); - } - int j=0; - for(int i=0;igetTypeOfCell(i); - const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(type); - for(int k=0;k<(int)cm.getNumberOfNodes();k++,j++) - array2[j]=array3[array[i]]+k; - } - delete [] array3; - for(std::vector::const_iterator it=arrays.begin();it!=arrays.end();it++) - if(*it) - (*it)->renumberInPlace(array2); - delete [] array2; - if(check) - free(const_cast(array)); -} - -DataArrayDouble *MEDCouplingFieldDiscretizationGaussNE::getLocalizationOfDiscValues(const MEDCouplingMesh *mesh) const -{ - 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(); -} - -/*! - * 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 -{ - 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 -{ -} - -double MEDCouplingFieldDiscretizationGaussNE::getIJK(const MEDCouplingMesh *mesh, const DataArrayDouble *da, int cellId, int nodeIdInCell, int compoId) const -{ - if(!mesh) - throw INTERP_KERNEL::Exception("MEDCouplingFieldDiscretizationGaussNE::getIJK : NULL input mesh !"); - int offset=0; - for(int i=0;igetTypeOfCell(i); - const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(type); - offset+=cm.getNumberOfNodes(); - } - return da->getIJ(offset+nodeIdInCell,compoId); -} - -void MEDCouplingFieldDiscretizationGaussNE::checkCoherencyBetween(const MEDCouplingMesh *mesh, const DataArray *da) const -{ - int nbOfTuples=getNumberOfTuples(mesh); - if(nbOfTuples!=da->getNumberOfTuples()) - { - std::ostringstream oss; oss << "Invalid number of tuples in the array : expecting " << nbOfTuples << " !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } -} - -MEDCouplingFieldDouble *MEDCouplingFieldDiscretizationGaussNE::getMeasureField(const MEDCouplingMesh *mesh, bool isAbs) const -{ - 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 -{ - throw INTERP_KERNEL::Exception("Not implemented yet !"); -} - -void MEDCouplingFieldDiscretizationGaussNE::getValueOnPos(const DataArrayDouble *arr, const MEDCouplingMesh *mesh, int i, int j, int k, double *res) const -{ - throw INTERP_KERNEL::Exception("getValueOnPos(i,j,k) : Not applyable for Gauss points !"); -} - -DataArrayDouble *MEDCouplingFieldDiscretizationGaussNE::getValueOnMulti(const DataArrayDouble *arr, const MEDCouplingMesh *mesh, const double *loc, int nbOfPoints) const -{ - throw INTERP_KERNEL::Exception("getValueOnMulti : Not implemented for Gauss NE !"); -} - -MEDCouplingMesh *MEDCouplingFieldDiscretizationGaussNE::buildSubMeshData(const MEDCouplingMesh *mesh, const int *start, const int *end, DataArrayInt *&di) const -{ - 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. - * - * \return a newly allocated array containing ids to select into the DataArrayDouble of the field. - * - */ -DataArrayInt *MEDCouplingFieldDiscretizationGaussNE::computeTupleIdsToSelectFromCellIds(const MEDCouplingMesh *mesh, const int *startCellIds, const int *endCellIds) const -{ - if(!mesh) - throw INTERP_KERNEL::Exception("MEDCouplingFieldDiscretizationGaussNE::computeTupleIdsToSelectFromCellIds : null mesh !"); - 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); -} - -/*! - * No implementation needed ! - */ -void MEDCouplingFieldDiscretizationGaussNE::renumberValuesOnNodes(double , const int *, int newNbOfNodes, DataArrayDouble *) const -{ -} - -void MEDCouplingFieldDiscretizationGaussNE::renumberValuesOnCells(double epsOnVals, const MEDCouplingMesh *mesh, const int *old2New, int newSz, DataArrayDouble *arr) const -{ - throw INTERP_KERNEL::Exception("Not implemented yet !"); -} - -void MEDCouplingFieldDiscretizationGaussNE::renumberValuesOnCellsR(const MEDCouplingMesh *mesh, const int *new2old, int newSz, DataArrayDouble *arr) const -{ - throw INTERP_KERNEL::Exception("Not implemented yet !"); -} - -void MEDCouplingFieldDiscretizationGaussNE::reprQuickOverview(std::ostream& stream) const -{ - stream << "Gauss points on nodes per element spatial discretization."; -} - -MEDCouplingFieldDiscretizationGaussNE::MEDCouplingFieldDiscretizationGaussNE(const MEDCouplingFieldDiscretizationGaussNE& other):MEDCouplingFieldDiscretization(other) -{ -} - -TypeOfField MEDCouplingFieldDiscretizationKriging::getEnum() const -{ - return TYPE; -} - -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; -} - -std::string MEDCouplingFieldDiscretizationKriging::getStringRepr() const -{ - return std::string(REPR); -} - -void MEDCouplingFieldDiscretizationKriging::checkCompatibilityWithNature(NatureOfField nat) const -{ - if(nat!=ConservativeVolumic) - throw INTERP_KERNEL::Exception("Invalid nature for Kriging field : expected ConservativeVolumic !"); -} - -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) - reason="Spatial discrtization of this is ON_NODES_KR, which is not the case of other."; - return ret; -} - -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 !"); -} - -void MEDCouplingFieldDiscretizationKriging::getValueOn(const DataArrayDouble *arr, const MEDCouplingMesh *mesh, const double *loc, double *res) const -{ - MEDCouplingAutoRefCountObjectPtr res2=MEDCouplingFieldDiscretizationKriging::getValueOnMulti(arr,mesh,loc,1); - std::copy(res2->begin(),res2->end(),res); -} - -DataArrayDouble *MEDCouplingFieldDiscretizationKriging::getValueOnMulti(const DataArrayDouble *arr, const MEDCouplingMesh *mesh, const double *loc, int nbOfTargetPoints) const -{ - if(!arr || !arr->isAllocated()) - throw INTERP_KERNEL::Exception("MEDCouplingFieldDiscretizationKriging::getValueOnMulti : input array is null or not allocated !"); - int nbOfRows(getNumberOfMeshPlaces(mesh)); - if(arr->getNumberOfTuples()!=nbOfRows) - { - std::ostringstream oss; oss << "MEDCouplingFieldDiscretizationKriging::getValueOnMulti : input array does not have correct number of tuples ! Excepted " << nbOfRows << " having " << arr->getNumberOfTuples() << " !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - int nbCols(-1),nbCompo(arr->getNumberOfComponents()); - MEDCouplingAutoRefCountObjectPtr m(computeEvaluationMatrixOnGivenPts(mesh,loc,nbOfTargetPoints,nbCols)); - MEDCouplingAutoRefCountObjectPtr ret(DataArrayDouble::New()); - ret->alloc(nbOfTargetPoints,nbCompo); - INTERP_KERNEL::matrixProduct(m->begin(),nbOfTargetPoints,nbCols,arr->begin(),nbOfRows,nbCompo,ret->getPointer()); - return ret.retn(); -} - -void MEDCouplingFieldDiscretizationKriging::reprQuickOverview(std::ostream& stream) const -{ - stream << "Kriging spatial discretization."; -} - -/*! - * Returns the matrix of size nbRows = \a nbOfTargetPoints and \a nbCols = \a nbCols. This matrix is useful if - * - * \return the new result matrix to be deallocated by the caller. - */ -DataArrayDouble *MEDCouplingFieldDiscretizationKriging::computeEvaluationMatrixOnGivenPts(const MEDCouplingMesh *mesh, const double *loc, int nbOfTargetPoints, int& nbCols) const -{ - int isDrift(-1),nbRows(-1); - MEDCouplingAutoRefCountObjectPtr matrixInv(computeInverseMatrix(mesh,isDrift,nbRows)); - // - MEDCouplingAutoRefCountObjectPtr coords=getLocalizationOfDiscValues(mesh); - int nbOfPts(coords->getNumberOfTuples()),dimension(coords->getNumberOfComponents()); - MEDCouplingAutoRefCountObjectPtr locArr=DataArrayDouble::New(); - locArr->useArray(loc,false,CPP_DEALLOC,nbOfTargetPoints,dimension); - nbCols=nbOfPts; - // - MEDCouplingAutoRefCountObjectPtr matrix2=coords->buildEuclidianDistanceDenseMatrixWith(locArr); - operateOnDenseMatrix(mesh->getSpaceDimension(),nbOfTargetPoints*nbOfPts,matrix2->getPointer()); - // - MEDCouplingAutoRefCountObjectPtr matrix3=DataArrayDouble::New(); - matrix3->alloc(nbOfTargetPoints*nbRows,1); - double *work=matrix3->getPointer(); - const double *workCst(matrix2->begin()),*workCst2(loc); - for(int i=0;i ret(DataArrayDouble::New()); - ret->alloc(nbOfTargetPoints,nbRows); - INTERP_KERNEL::matrixProduct(matrix3->begin(),nbOfTargetPoints,nbRows,matrixInv->begin(),nbRows,nbRows,ret->getPointer()); - MEDCouplingAutoRefCountObjectPtr ret2(DataArrayDouble::New()); - ret2->alloc(nbOfTargetPoints*nbOfPts,1); - workCst=ret->begin(); work=ret2->getPointer(); - for(int i=0;i matrixWithDrift(computeMatrix(mesh,isDrift,matSz)); - MEDCouplingAutoRefCountObjectPtr matrixInv(DataArrayDouble::New()); - matrixInv->alloc(matSz*matSz,1); - INTERP_KERNEL::inverseMatrix(matrixWithDrift->getConstPointer(),matSz,matrixInv->getPointer()); - return matrixInv.retn(); -} - -/*! - * This method computes the kriging matrix. - * \return the new result matrix to be deallocated by the caller. - * \sa computeInverseMatrix - */ -DataArrayDouble *MEDCouplingFieldDiscretizationKriging::computeMatrix(const MEDCouplingMesh *mesh, int& isDrift, int& matSz) const -{ - if(!mesh) - throw INTERP_KERNEL::Exception("MEDCouplingFieldDiscretizationKriging::computeMatrix : NULL input mesh !"); - MEDCouplingAutoRefCountObjectPtr coords(getLocalizationOfDiscValues(mesh)); - int nbOfPts(coords->getNumberOfTuples()); - MEDCouplingAutoRefCountObjectPtr matrix(coords->buildEuclidianDistanceDenseMatrix()); - operateOnDenseMatrix(mesh->getSpaceDimension(),nbOfPts*nbOfPts,matrix->getPointer()); - // Drift - MEDCouplingAutoRefCountObjectPtr matrixWithDrift(performDrift(matrix,coords,isDrift)); - matSz=nbOfPts+isDrift; - return matrixWithDrift.retn(); -} - -/*! - * This method computes coefficients to apply to each representing points of \a mesh, that is to say the nodes of \a mesh given a field array \a arr whose - * number of tuples should be equal to the number of representing points in \a mesh. - * - * \param [in] mesh is the sources of nodes on which kriging will be done regarding the parameters and the value of \c this->getSpaceDimension() - * \param [in] arr input field DataArrayDouble whose number of tuples must be equal to the number of nodes in \a mesh - * \param [out] isDrift return if drift coefficients are present in the returned vector of coefficients. If different from 0 there is presence of drift coefficients. - * Whatever the value of \a isDrift the number of tuples of returned DataArrayDouble will be equal to \c arr->getNumberOfTuples() + \a isDrift. - * \return a newly allocated array containing coefficients including or not drift coefficient at the end depending the value of \a isDrift parameter. - */ -DataArrayDouble *MEDCouplingFieldDiscretizationKriging::computeVectorOfCoefficients(const MEDCouplingMesh *mesh, const DataArrayDouble *arr, int& isDrift) const -{ - int nbRows(-1); - MEDCouplingAutoRefCountObjectPtr matrixInv(computeInverseMatrix(mesh,isDrift,nbRows)); - MEDCouplingAutoRefCountObjectPtr KnewiK(DataArrayDouble::New()); - KnewiK->alloc(nbRows*1,1); - MEDCouplingAutoRefCountObjectPtr arr2(PerformDriftOfVec(arr,isDrift)); - INTERP_KERNEL::matrixProduct(matrixInv->getConstPointer(),nbRows,nbRows,arr2->getConstPointer(),arr2->getNumberOfTuples(),1,KnewiK->getPointer()); - return KnewiK.retn(); -} - -/*! - * Apply \f f(x) on each element x in \a matrixPtr. \a matrixPtr is expected to be a dense matrix represented by a chunck of memory of size at least equal to \a nbOfElems. - * - * \param [in] spaceDimension space dimension of the input mesh on which the Kriging has to be performed - * \param [in] nbOfElems is the result of the product of nb of rows and the nb of columns of matrix \a matrixPtr - * \param [in,out] matrixPtr is the dense matrix whose on each values the operation will be applied - */ -void MEDCouplingFieldDiscretizationKriging::operateOnDenseMatrix(int spaceDimension, int nbOfElems, double *matrixPtr) const -{ - switch(spaceDimension) - { - case 1: - { - OperateOnDenseMatrixH3(nbOfElems,matrixPtr); - break; - } - case 2: - { - OperateOnDenseMatrixH2Ln(nbOfElems,matrixPtr); - break; - } - case 3: - { - //nothing here : it is not a bug g(h)=h with spaceDim 3. - break; - } - default: - throw INTERP_KERNEL::Exception("MEDCouplingFieldDiscretizationKriging::operateOnDenseMatrix : only dimension 1, 2 and 3 implemented !"); - } -} - -void MEDCouplingFieldDiscretizationKriging::OperateOnDenseMatrixH3(int nbOfElems, double *matrixPtr) -{ - for(int i=0;iisAllocated() || matr->getNumberOfComponents()!=1) - throw INTERP_KERNEL::Exception("MEDCouplingFieldDiscretizationKriging::PerformDriftRect : invalid input dense matrix ! Must be allocated not NULL and with exactly one component !"); - if(!arr || !arr->isAllocated()) - throw INTERP_KERNEL::Exception("MEDCouplingFieldDiscretizationKriging::PerformDriftRect : invalid input array of coordiantes ! Must be allocated and not NULL !"); - int spaceDimension(arr->getNumberOfComponents()),nbOfPts(arr->getNumberOfTuples()),nbOfEltInMatrx(matr->getNumberOfTuples()); - delta=spaceDimension+1; - int nbOfCols(nbOfEltInMatrx/nbOfPts); - if(nbOfEltInMatrx%nbOfPts!=0) - throw INTERP_KERNEL::Exception("MEDCouplingFieldDiscretizationKriging::PerformDriftRect : size of input dense matrix and input arrays mismatch ! NbOfElems in matrix % nb of tuples in array must be equal to 0 !"); - MEDCouplingAutoRefCountObjectPtr ret(DataArrayDouble::New()); ret->alloc(nbOfPts*(nbOfCols+delta)); - double *retPtr(ret->getPointer()); - const double *mPtr(matr->begin()),*aPtr(arr->begin()); - for(int i=0;iisAllocated() || arr->getNumberOfComponents()!=1) - throw INTERP_KERNEL::Exception("MEDCouplingFieldDiscretizationKriging::PerformDriftOfVec : input array must be not NULL allocated and with one component !"); - if(isDrift<0) - throw INTERP_KERNEL::Exception("MEDCouplingFieldDiscretizationKriging::PerformDriftOfVec : isDrift parameter must be >=0 !"); - MEDCouplingAutoRefCountObjectPtr arr2(DataArrayDouble::New()); - arr2->alloc((arr->getNumberOfTuples()+isDrift)*1,1); - double *work(std::copy(arr->begin(),arr->end(),arr2->getPointer())); - std::fill(work,work+isDrift,0.); - return arr2.retn(); -} - -/*! - * Starting from a square matrix \a matr, this method returns a newly allocated dense square matrix whose \a matr is included in returned matrix - * in the top left corner, and in the remaining returned matrix the parameters to take into account about the kriging drift. - * For the moment only linear srift is implemented. - * - * \param [in] arr the position of points were input mesh geometry is considered for Kriging - * \param [in] matr input matrix whose drift part will be added - * \param [out] delta the difference between the size of the output matrix and the input matrix \a matr. - * \return a newly allocated matrix bigger than input matrix \a matr. - * \sa MEDCouplingFieldDiscretizationKriging::PerformDriftRect - */ -DataArrayDouble *MEDCouplingFieldDiscretizationKriging::performDrift(const DataArrayDouble *matr, const DataArrayDouble *arr, int& delta) const -{ - int spaceDimension=arr->getNumberOfComponents(); - delta=spaceDimension+1; - int szOfMatrix=arr->getNumberOfTuples(); - if(szOfMatrix*szOfMatrix!=matr->getNumberOfTuples()) - throw INTERP_KERNEL::Exception("MEDCouplingFieldDiscretizationKriging::performDrift : invalid size"); - MEDCouplingAutoRefCountObjectPtr ret=DataArrayDouble::New(); - ret->alloc((szOfMatrix+delta)*(szOfMatrix+delta),1); - const double *srcWork=matr->getConstPointer(); - const double *srcWork2=arr->getConstPointer(); - double *destWork=ret->getPointer(); - for(int i=0;i arrNoI=arr->toNoInterlace(); - srcWork2=arrNoI->getConstPointer(); - for(int i=0;i -#include - -namespace ParaMEDMEM -{ - class DataArray; - class DataArrayInt; - class MEDCouplingMesh; - class DataArrayDouble; - class MEDCouplingFieldDouble; - - class MEDCouplingFieldDiscretization : public RefCountObject, public TimeLabel - { - public: - MEDCOUPLING_EXPORT static MEDCouplingFieldDiscretization *New(TypeOfField type); - MEDCOUPLING_EXPORT double getPrecision() const { return _precision; } - MEDCOUPLING_EXPORT void setPrecision(double val) { _precision=val; } - MEDCOUPLING_EXPORT void updateTime() const; - MEDCOUPLING_EXPORT std::size_t getHeapMemorySizeWithoutChildren() const; - MEDCOUPLING_EXPORT std::vector getDirectChildrenWithNull() const; - MEDCOUPLING_EXPORT static TypeOfField GetTypeOfFieldFromStringRepr(const std::string& repr); - MEDCOUPLING_EXPORT static std::string GetTypeOfFieldRepr(TypeOfField type); - MEDCOUPLING_EXPORT virtual TypeOfField getEnum() const = 0; - MEDCOUPLING_EXPORT virtual bool isEqual(const MEDCouplingFieldDiscretization *other, double eps) const; - MEDCOUPLING_EXPORT virtual bool isEqualIfNotWhy(const MEDCouplingFieldDiscretization *other, double eps, std::string& reason) const = 0; - MEDCOUPLING_EXPORT virtual bool isEqualWithoutConsideringStr(const MEDCouplingFieldDiscretization *other, double eps) const; - MEDCOUPLING_EXPORT virtual MEDCouplingFieldDiscretization *deepCpy() const; - MEDCOUPLING_EXPORT virtual MEDCouplingFieldDiscretization *clone() const = 0; - MEDCOUPLING_EXPORT virtual MEDCouplingFieldDiscretization *clonePart(const int *startCellIds, const int *endCellIds) const; - MEDCOUPLING_EXPORT virtual MEDCouplingFieldDiscretization *clonePartRange(int beginCellIds, int endCellIds, int stepCellIds) const; - MEDCOUPLING_EXPORT virtual std::string getStringRepr() const = 0; - MEDCOUPLING_EXPORT virtual const char *getRepr() const = 0; - MEDCOUPLING_EXPORT virtual int getNumberOfTuplesExpectedRegardingCode(const std::vector& code, const std::vector& idsPerType) const = 0; - MEDCOUPLING_EXPORT virtual int getNumberOfTuples(const MEDCouplingMesh *mesh) const = 0; - MEDCOUPLING_EXPORT virtual int getNumberOfMeshPlaces(const MEDCouplingMesh *mesh) const = 0; - MEDCOUPLING_EXPORT virtual DataArrayInt *getOffsetArr(const MEDCouplingMesh *mesh) const = 0; - MEDCOUPLING_EXPORT virtual void normL1(const MEDCouplingMesh *mesh, const DataArrayDouble *arr, double *res) const; - MEDCOUPLING_EXPORT virtual void normL2(const MEDCouplingMesh *mesh, const DataArrayDouble *arr, double *res) const; - MEDCOUPLING_EXPORT virtual void integral(const MEDCouplingMesh *mesh, const DataArrayDouble *arr, bool isWAbs, double *res) const; - MEDCOUPLING_EXPORT virtual DataArrayDouble *getLocalizationOfDiscValues(const MEDCouplingMesh *mesh) const = 0; - MEDCOUPLING_EXPORT virtual void computeMeshRestrictionFromTupleIds(const MEDCouplingMesh *mesh, const int *tupleIdsBg, const int *tupleIdsEnd, - DataArrayInt *&cellRestriction, DataArrayInt *&trueTupleRestriction) const = 0; - MEDCOUPLING_EXPORT virtual void checkCompatibilityWithNature(NatureOfField nat) const = 0; - MEDCOUPLING_EXPORT virtual void renumberCells(const int *old2NewBg, bool check=true); - MEDCOUPLING_EXPORT virtual void renumberArraysForCell(const MEDCouplingMesh *mesh, const std::vector& arrays, - const int *old2NewBg, bool check) = 0; - MEDCOUPLING_EXPORT virtual double getIJK(const MEDCouplingMesh *mesh, const DataArrayDouble *da, int cellId, int nodeIdInCell, int compoId) const; - MEDCOUPLING_EXPORT virtual void checkCoherencyBetween(const MEDCouplingMesh *mesh, const DataArray *da) const = 0; - MEDCOUPLING_EXPORT virtual MEDCouplingFieldDouble *getMeasureField(const MEDCouplingMesh *mesh, bool isAbs) const = 0; - MEDCOUPLING_EXPORT virtual void getValueOn(const DataArrayDouble *arr, const MEDCouplingMesh *mesh, const double *loc, double *res) const = 0; - MEDCOUPLING_EXPORT virtual void getValueOnPos(const DataArrayDouble *arr, const MEDCouplingMesh *mesh, int i, int j, int k, double *res) const = 0; - MEDCOUPLING_EXPORT virtual DataArrayDouble *getValueOnMulti(const DataArrayDouble *arr, const MEDCouplingMesh *mesh, const double *loc, int nbOfPoints) const = 0; - MEDCOUPLING_EXPORT virtual DataArrayInt *computeTupleIdsToSelectFromCellIds(const MEDCouplingMesh *mesh, const int *startCellIds, const int *endCellIds) const = 0; - MEDCOUPLING_EXPORT virtual MEDCouplingMesh *buildSubMeshData(const MEDCouplingMesh *mesh, const int *start, const int *end, DataArrayInt *&di) const = 0; - MEDCOUPLING_EXPORT virtual MEDCouplingMesh *buildSubMeshDataRange(const MEDCouplingMesh *mesh, int beginCellIds, int endCellIds, int stepCellIds, int& beginOut, int& endOut, int& stepOut, DataArrayInt *&di) const; - MEDCOUPLING_EXPORT virtual void renumberValuesOnNodes(double epsOnVals, const int *old2New, int newNbOfNodes, DataArrayDouble *arr) const = 0; - MEDCOUPLING_EXPORT virtual void renumberValuesOnCells(double epsOnVals, const MEDCouplingMesh *mesh, const int *old2New, int newSz, DataArrayDouble *arr) const = 0; - MEDCOUPLING_EXPORT virtual void renumberValuesOnCellsR(const MEDCouplingMesh *mesh, const int *new2old, int newSz, DataArrayDouble *arr) const = 0; - MEDCOUPLING_EXPORT virtual void getSerializationIntArray(DataArrayInt *& arr) const; - MEDCOUPLING_EXPORT virtual void getTinySerializationIntInformation(std::vector& tinyInfo) const; - MEDCOUPLING_EXPORT virtual void getTinySerializationDbleInformation(std::vector& tinyInfo) const; - MEDCOUPLING_EXPORT virtual void finishUnserialization(const std::vector& tinyInfo); - MEDCOUPLING_EXPORT virtual void resizeForUnserialization(const std::vector& tinyInfo, DataArrayInt *& arr); - MEDCOUPLING_EXPORT virtual void checkForUnserialization(const std::vector& tinyInfo, const DataArrayInt *arr); - MEDCOUPLING_EXPORT virtual void setGaussLocalizationOnType(const MEDCouplingMesh *m, INTERP_KERNEL::NormalizedCellType type, const std::vector& refCoo, - const std::vector& gsCoo, const std::vector& wg); - MEDCOUPLING_EXPORT virtual void setGaussLocalizationOnCells(const MEDCouplingMesh *m, const int *begin, const int *end, const std::vector& refCoo, - const std::vector& gsCoo, const std::vector& wg); - MEDCOUPLING_EXPORT virtual void clearGaussLocalizations(); - MEDCOUPLING_EXPORT virtual MEDCouplingGaussLocalization& getGaussLocalization(int locId); - MEDCOUPLING_EXPORT virtual int getNbOfGaussLocalization() const; - MEDCOUPLING_EXPORT virtual int getGaussLocalizationIdOfOneCell(int cellId) const; - MEDCOUPLING_EXPORT virtual int getGaussLocalizationIdOfOneType(INTERP_KERNEL::NormalizedCellType type) const; - MEDCOUPLING_EXPORT virtual std::set getGaussLocalizationIdsOfOneType(INTERP_KERNEL::NormalizedCellType type) const; - MEDCOUPLING_EXPORT virtual void getCellIdsHavingGaussLocalization(int locId, std::vector& cellIds) const; - MEDCOUPLING_EXPORT virtual const MEDCouplingGaussLocalization& getGaussLocalization(int locId) const; - MEDCOUPLING_EXPORT virtual void reprQuickOverview(std::ostream& stream) const = 0; - MEDCOUPLING_EXPORT virtual ~MEDCouplingFieldDiscretization(); - protected: - MEDCOUPLING_EXPORT MEDCouplingFieldDiscretization(); - MEDCOUPLING_EXPORT static void RenumberEntitiesFromO2NArr(double epsOnVals, const int *old2NewPtr, int newNbOfEntity, DataArrayDouble *arr, const std::string& msg); - MEDCOUPLING_EXPORT static void RenumberEntitiesFromN2OArr(const int *new2OldPtr, int new2OldSz, DataArrayDouble *arr, const std::string& msg); - protected: - double _precision; - static const double DFLT_PRECISION; - }; - - class MEDCouplingFieldDiscretizationP0 : public MEDCouplingFieldDiscretization - { - public: - MEDCOUPLING_EXPORT TypeOfField getEnum() const; - MEDCOUPLING_EXPORT MEDCouplingFieldDiscretization *clone() const; - MEDCOUPLING_EXPORT std::string getStringRepr() const; - MEDCOUPLING_EXPORT const char *getRepr() const; - MEDCOUPLING_EXPORT bool isEqualIfNotWhy(const MEDCouplingFieldDiscretization *other, double eps, std::string& reason) const; - MEDCOUPLING_EXPORT int getNumberOfTuplesExpectedRegardingCode(const std::vector& code, const std::vector& idsPerType) const; - MEDCOUPLING_EXPORT int getNumberOfTuples(const MEDCouplingMesh *mesh) const; - MEDCOUPLING_EXPORT int getNumberOfMeshPlaces(const MEDCouplingMesh *mesh) const; - MEDCOUPLING_EXPORT DataArrayInt *getOffsetArr(const MEDCouplingMesh *mesh) const; - MEDCOUPLING_EXPORT void renumberArraysForCell(const MEDCouplingMesh *mesh, const std::vector& arrays, - const int *old2NewBg, bool check); - MEDCOUPLING_EXPORT DataArrayDouble *getLocalizationOfDiscValues(const MEDCouplingMesh *mesh) const; - MEDCOUPLING_EXPORT void checkCompatibilityWithNature(NatureOfField nat) const; - MEDCOUPLING_EXPORT void computeMeshRestrictionFromTupleIds(const MEDCouplingMesh *mesh, const int *tupleIdsBg, const int *tupleIdsEnd, - DataArrayInt *&cellRestriction, DataArrayInt *&trueTupleRestriction) const; - MEDCOUPLING_EXPORT void checkCoherencyBetween(const MEDCouplingMesh *mesh, const DataArray *da) const; - MEDCOUPLING_EXPORT MEDCouplingFieldDouble *getMeasureField(const MEDCouplingMesh *mesh, bool isAbs) const; - MEDCOUPLING_EXPORT void getValueOn(const DataArrayDouble *arr, const MEDCouplingMesh *mesh, const double *loc, double *res) const; - MEDCOUPLING_EXPORT void getValueOnPos(const DataArrayDouble *arr, const MEDCouplingMesh *mesh, int i, int j, int k, double *res) const; - MEDCOUPLING_EXPORT DataArrayDouble *getValueOnMulti(const DataArrayDouble *arr, const MEDCouplingMesh *mesh, const double *loc, int nbOfPoints) const; - MEDCOUPLING_EXPORT void renumberValuesOnNodes(double epsOnVals, const int *old2New, int newNbOfNodes, DataArrayDouble *arr) const; - MEDCOUPLING_EXPORT void renumberValuesOnCells(double epsOnVals, const MEDCouplingMesh *mesh, const int *old2New, int newSz, DataArrayDouble *arr) const; - MEDCOUPLING_EXPORT void renumberValuesOnCellsR(const MEDCouplingMesh *mesh, const int *new2old, int newSz, DataArrayDouble *arr) const; - MEDCOUPLING_EXPORT MEDCouplingMesh *buildSubMeshData(const MEDCouplingMesh *mesh, const int *start, const int *end, DataArrayInt *&di) const; - MEDCOUPLING_EXPORT MEDCouplingMesh *buildSubMeshDataRange(const MEDCouplingMesh *mesh, int beginCellIds, int endCellIds, int stepCellIds, int& beginOut, int& endOut, int& stepOut, DataArrayInt *&di) const; - MEDCOUPLING_EXPORT DataArrayInt *computeTupleIdsToSelectFromCellIds(const MEDCouplingMesh *mesh, const int *startCellIds, const int *endCellIds) const; - MEDCOUPLING_EXPORT void reprQuickOverview(std::ostream& stream) const; - public: - static const char REPR[]; - static const TypeOfField TYPE; - }; - - class MEDCouplingFieldDiscretizationOnNodes : public MEDCouplingFieldDiscretization - { - public: - MEDCOUPLING_EXPORT int getNumberOfTuples(const MEDCouplingMesh *mesh) const; - MEDCOUPLING_EXPORT int getNumberOfTuplesExpectedRegardingCode(const std::vector& code, const std::vector& idsPerType) const; - MEDCOUPLING_EXPORT int getNumberOfMeshPlaces(const MEDCouplingMesh *mesh) const; - MEDCOUPLING_EXPORT DataArrayInt *getOffsetArr(const MEDCouplingMesh *mesh) const; - MEDCOUPLING_EXPORT void renumberArraysForCell(const MEDCouplingMesh *mesh, const std::vector& arrays, - const int *old2NewBg, bool check); - MEDCOUPLING_EXPORT DataArrayDouble *getLocalizationOfDiscValues(const MEDCouplingMesh *mesh) const; - MEDCOUPLING_EXPORT void computeMeshRestrictionFromTupleIds(const MEDCouplingMesh *mesh, const int *tupleIdsBg, const int *tupleIdsEnd, - DataArrayInt *&cellRestriction, DataArrayInt *&trueTupleRestriction) const; - MEDCOUPLING_EXPORT void checkCoherencyBetween(const MEDCouplingMesh *mesh, const DataArray *da) const; - MEDCOUPLING_EXPORT MEDCouplingMesh *buildSubMeshData(const MEDCouplingMesh *mesh, const int *start, const int *end, DataArrayInt *&di) const; - MEDCOUPLING_EXPORT MEDCouplingMesh *buildSubMeshDataRange(const MEDCouplingMesh *mesh, int beginCellIds, int endCellIds, int stepCellIds, int& beginOut, int& endOut, int& stepOut, DataArrayInt *&di) const; - MEDCOUPLING_EXPORT DataArrayInt *computeTupleIdsToSelectFromCellIds(const MEDCouplingMesh *mesh, const int *startCellIds, const int *endCellIds) const; - MEDCOUPLING_EXPORT void renumberValuesOnNodes(double epsOnVals, const int *old2New, int newNbOfNodes, DataArrayDouble *arr) const; - MEDCOUPLING_EXPORT void renumberValuesOnCells(double epsOnVals, const MEDCouplingMesh *mesh, const int *old2New, int newSz, DataArrayDouble *arr) const; - MEDCOUPLING_EXPORT void renumberValuesOnCellsR(const MEDCouplingMesh *mesh, const int *new2old, int newSz, DataArrayDouble *arr) const; - public: - MEDCOUPLING_EXPORT void getValueOnPos(const DataArrayDouble *arr, const MEDCouplingMesh *mesh, int i, int j, int k, double *res) const; - }; - - class MEDCouplingFieldDiscretizationP1 : public MEDCouplingFieldDiscretizationOnNodes - { - public: - MEDCOUPLING_EXPORT TypeOfField getEnum() const; - MEDCOUPLING_EXPORT MEDCouplingFieldDiscretization *clone() const; - MEDCOUPLING_EXPORT std::string getStringRepr() const; - MEDCOUPLING_EXPORT const char *getRepr() const; - MEDCOUPLING_EXPORT void checkCompatibilityWithNature(NatureOfField nat) const; - MEDCOUPLING_EXPORT bool isEqualIfNotWhy(const MEDCouplingFieldDiscretization *other, double eps, std::string& reason) const; - MEDCOUPLING_EXPORT MEDCouplingFieldDouble *getMeasureField(const MEDCouplingMesh *mesh, bool isAbs) const; - MEDCOUPLING_EXPORT void getValueOn(const DataArrayDouble *arr, const MEDCouplingMesh *mesh, const double *loc, double *res) const; - MEDCOUPLING_EXPORT DataArrayDouble *getValueOnMulti(const DataArrayDouble *arr, const MEDCouplingMesh *mesh, const double *loc, int nbOfPoints) const; - MEDCOUPLING_EXPORT void reprQuickOverview(std::ostream& stream) const; - public: - static const char REPR[]; - static const TypeOfField TYPE; - protected: - MEDCOUPLING_EXPORT void getValueInCell(const MEDCouplingMesh *mesh, int cellId, const DataArrayDouble *arr, const double *loc, double *res) const; - }; - - /*! - * This class abstracts MEDCouplingFieldDiscretization that needs an information on each cell to perform their job. - * All classes that inherits from this are more linked to mesh. - */ - class MEDCouplingFieldDiscretizationPerCell : public MEDCouplingFieldDiscretization - { - public: - MEDCOUPLING_EXPORT const DataArrayInt *getArrayOfDiscIds() const; - MEDCOUPLING_EXPORT void setArrayOfDiscIds(const DataArrayInt *adids); - MEDCOUPLING_EXPORT void checkNoOrphanCells() const; - MEDCOUPLING_EXPORT std::vector splitIntoSingleGaussDicrPerCellType(std::vector< int >& locIds) const; - 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; - std::size_t getHeapMemorySizeWithoutChildren() const; - std::vector getDirectChildrenWithNull() const; - void checkCoherencyBetween(const MEDCouplingMesh *mesh, const DataArray *da) const; - 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); - protected: - void buildDiscrPerCellIfNecessary(const MEDCouplingMesh *mesh); - protected: - DataArrayInt *_discr_per_cell; - static const int DFT_INVALID_LOCID_VALUE; - }; - - class MEDCouplingFieldDiscretizationGauss : public MEDCouplingFieldDiscretizationPerCell - { - public: - MEDCOUPLING_EXPORT MEDCouplingFieldDiscretizationGauss(); - MEDCOUPLING_EXPORT TypeOfField getEnum() const; - MEDCOUPLING_EXPORT bool isEqualIfNotWhy(const MEDCouplingFieldDiscretization *other, double eps, std::string& reason) const; - MEDCOUPLING_EXPORT bool isEqualWithoutConsideringStr(const MEDCouplingFieldDiscretization *other, double eps) const; - MEDCOUPLING_EXPORT MEDCouplingFieldDiscretization *clone() const; - MEDCOUPLING_EXPORT MEDCouplingFieldDiscretization *clonePart(const int *startCellIds, const int *endCellIds) const; - MEDCOUPLING_EXPORT MEDCouplingFieldDiscretization *clonePartRange(int beginCellIds, int endCellIds, int stepCellIds) const; - MEDCOUPLING_EXPORT std::string getStringRepr() const; - MEDCOUPLING_EXPORT const char *getRepr() const; - MEDCOUPLING_EXPORT std::size_t getHeapMemorySizeWithoutChildren() const; - MEDCOUPLING_EXPORT int getNumberOfTuplesExpectedRegardingCode(const std::vector& code, const std::vector& idsPerType) const; - MEDCOUPLING_EXPORT int getNumberOfTuples(const MEDCouplingMesh *mesh) const; - MEDCOUPLING_EXPORT int getNumberOfMeshPlaces(const MEDCouplingMesh *mesh) const; - MEDCOUPLING_EXPORT DataArrayInt *getOffsetArr(const MEDCouplingMesh *mesh) const; - MEDCOUPLING_EXPORT void renumberArraysForCell(const MEDCouplingMesh *mesh, const std::vector& arrays, - const int *old2NewBg, bool check); - MEDCOUPLING_EXPORT DataArrayDouble *getLocalizationOfDiscValues(const MEDCouplingMesh *mesh) const; - MEDCOUPLING_EXPORT void computeMeshRestrictionFromTupleIds(const MEDCouplingMesh *mesh, const int *tupleIdsBg, const int *tupleIdsEnd, - DataArrayInt *&cellRestriction, DataArrayInt *&trueTupleRestriction) const; - MEDCOUPLING_EXPORT void checkCompatibilityWithNature(NatureOfField nat) const; - MEDCOUPLING_EXPORT void getTinySerializationIntInformation(std::vector& tinyInfo) const; - MEDCOUPLING_EXPORT void getTinySerializationDbleInformation(std::vector& tinyInfo) const; - MEDCOUPLING_EXPORT void finishUnserialization(const std::vector& tinyInfo); - MEDCOUPLING_EXPORT void getSerializationIntArray(DataArrayInt *& arr) const; - MEDCOUPLING_EXPORT void resizeForUnserialization(const std::vector& tinyInfo, DataArrayInt *& arr); - MEDCOUPLING_EXPORT void checkForUnserialization(const std::vector& tinyInfo, const DataArrayInt *arr); - MEDCOUPLING_EXPORT double getIJK(const MEDCouplingMesh *mesh, const DataArrayDouble *da, int cellId, int nodeIdInCell, int compoId) const; - MEDCOUPLING_EXPORT void checkCoherencyBetween(const MEDCouplingMesh *mesh, const DataArray *da) const; - MEDCOUPLING_EXPORT MEDCouplingFieldDouble *getMeasureField(const MEDCouplingMesh *mesh, bool isAbs) const; - MEDCOUPLING_EXPORT void getValueOn(const DataArrayDouble *arr, const MEDCouplingMesh *mesh, const double *loc, double *res) const; - MEDCOUPLING_EXPORT void getValueOnPos(const DataArrayDouble *arr, const MEDCouplingMesh *mesh, int i, int j, int k, double *res) const; - MEDCOUPLING_EXPORT DataArrayDouble *getValueOnMulti(const DataArrayDouble *arr, const MEDCouplingMesh *mesh, const double *loc, int nbOfPoints) const; - MEDCOUPLING_EXPORT MEDCouplingMesh *buildSubMeshData(const MEDCouplingMesh *mesh, const int *start, const int *end, DataArrayInt *&di) const; - MEDCOUPLING_EXPORT MEDCouplingMesh *buildSubMeshDataRange(const MEDCouplingMesh *mesh, int beginCellIds, int endCellIds, int stepCellIds, int& beginOut, int& endOut, int& stepOut, DataArrayInt *&di) const; - MEDCOUPLING_EXPORT DataArrayInt *computeTupleIdsToSelectFromCellIds(const MEDCouplingMesh *mesh, const int *startCellIds, const int *endCellIds) const; - MEDCOUPLING_EXPORT void renumberValuesOnNodes(double epsOnVals, const int *old2New, int newNbOfNodes, DataArrayDouble *arr) const; - MEDCOUPLING_EXPORT void renumberValuesOnCells(double epsOnVals, const MEDCouplingMesh *mesh, const int *old2New, int newSz, DataArrayDouble *arr) const; - MEDCOUPLING_EXPORT void renumberValuesOnCellsR(const MEDCouplingMesh *mesh, const int *new2old, int newSz, DataArrayDouble *arr) const; - MEDCOUPLING_EXPORT void setGaussLocalizationOnType(const MEDCouplingMesh *mesh, INTERP_KERNEL::NormalizedCellType type, const std::vector& refCoo, - const std::vector& gsCoo, const std::vector& wg); - MEDCOUPLING_EXPORT void setGaussLocalizationOnCells(const MEDCouplingMesh *mesh, const int *begin, const int *end, const std::vector& refCoo, - const std::vector& gsCoo, const std::vector& wg); - MEDCOUPLING_EXPORT void clearGaussLocalizations(); - MEDCOUPLING_EXPORT void setGaussLocalization(int locId, const MEDCouplingGaussLocalization& loc); - MEDCOUPLING_EXPORT void resizeLocalizationVector(int newSz); - MEDCOUPLING_EXPORT MEDCouplingGaussLocalization& getGaussLocalization(int locId); - MEDCOUPLING_EXPORT int getNbOfGaussLocalization() const; - MEDCOUPLING_EXPORT int getGaussLocalizationIdOfOneCell(int cellId) const; - MEDCOUPLING_EXPORT int getGaussLocalizationIdOfOneType(INTERP_KERNEL::NormalizedCellType type) const; - MEDCOUPLING_EXPORT std::set getGaussLocalizationIdsOfOneType(INTERP_KERNEL::NormalizedCellType type) const; - MEDCOUPLING_EXPORT void getCellIdsHavingGaussLocalization(int locId, std::vector& cellIds) const; - MEDCOUPLING_EXPORT const MEDCouplingGaussLocalization& getGaussLocalization(int locId) const; - MEDCOUPLING_EXPORT DataArrayInt *buildNbOfGaussPointPerCellField() const; - MEDCOUPLING_EXPORT void reprQuickOverview(std::ostream& stream) const; - 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; - void checkLocalizationId(int locId) const; - void commonUnserialization(const std::vector& tinyInfo); - public: - static const char REPR[]; - static const TypeOfField TYPE; - private: - std::vector _loc; - }; - - /*! - * Gauss with points of values located on nodes of element. This is a specialization of MEDCouplingFieldDiscretizationGauss. - */ - class MEDCouplingFieldDiscretizationGaussNE : public MEDCouplingFieldDiscretization - { - public: - MEDCOUPLING_EXPORT MEDCouplingFieldDiscretizationGaussNE(); - MEDCOUPLING_EXPORT TypeOfField getEnum() const; - MEDCOUPLING_EXPORT MEDCouplingFieldDiscretization *clone() const; - MEDCOUPLING_EXPORT std::string getStringRepr() const; - MEDCOUPLING_EXPORT const char *getRepr() const; - MEDCOUPLING_EXPORT bool isEqualIfNotWhy(const MEDCouplingFieldDiscretization *other, double eps, std::string& reason) const; - MEDCOUPLING_EXPORT int getNumberOfTuplesExpectedRegardingCode(const std::vector& code, const std::vector& idsPerType) const; - MEDCOUPLING_EXPORT int getNumberOfTuples(const MEDCouplingMesh *mesh) const; - MEDCOUPLING_EXPORT int getNumberOfMeshPlaces(const MEDCouplingMesh *mesh) const; - MEDCOUPLING_EXPORT DataArrayInt *getOffsetArr(const MEDCouplingMesh *mesh) const; - MEDCOUPLING_EXPORT void renumberArraysForCell(const MEDCouplingMesh *mesh, const std::vector& arrays, - const int *old2NewBg, bool check); - MEDCOUPLING_EXPORT DataArrayDouble *getLocalizationOfDiscValues(const MEDCouplingMesh *mesh) const; - MEDCOUPLING_EXPORT void integral(const MEDCouplingMesh *mesh, const DataArrayDouble *arr, bool isWAbs, double *res) const; - MEDCOUPLING_EXPORT void computeMeshRestrictionFromTupleIds(const MEDCouplingMesh *mesh, const int *tupleIdsBg, const int *tupleIdsEnd, - DataArrayInt *&cellRestriction, DataArrayInt *&trueTupleRestriction) const; - MEDCOUPLING_EXPORT void checkCompatibilityWithNature(NatureOfField nat) const; - MEDCOUPLING_EXPORT double getIJK(const MEDCouplingMesh *mesh, const DataArrayDouble *da, int cellId, int nodeIdInCell, int compoId) const; - MEDCOUPLING_EXPORT void checkCoherencyBetween(const MEDCouplingMesh *mesh, const DataArray *da) const; - MEDCOUPLING_EXPORT MEDCouplingFieldDouble *getMeasureField(const MEDCouplingMesh *mesh, bool isAbs) const; - MEDCOUPLING_EXPORT void getValueOn(const DataArrayDouble *arr, const MEDCouplingMesh *mesh, const double *loc, double *res) const; - MEDCOUPLING_EXPORT void getValueOnPos(const DataArrayDouble *arr, const MEDCouplingMesh *mesh, int i, int j, int k, double *res) const; - MEDCOUPLING_EXPORT DataArrayDouble *getValueOnMulti(const DataArrayDouble *arr, const MEDCouplingMesh *mesh, const double *loc, int nbOfPoints) const; - MEDCOUPLING_EXPORT MEDCouplingMesh *buildSubMeshData(const MEDCouplingMesh *mesh, const int *start, const int *end, DataArrayInt *&di) const; - MEDCOUPLING_EXPORT MEDCouplingMesh *buildSubMeshDataRange(const MEDCouplingMesh *mesh, int beginCellIds, int endCellIds, int stepCellIds, int& beginOut, int& endOut, int& stepOut, DataArrayInt *&di) const; - MEDCOUPLING_EXPORT DataArrayInt *computeTupleIdsToSelectFromCellIds(const MEDCouplingMesh *mesh, const int *startCellIds, const int *endCellIds) const; - MEDCOUPLING_EXPORT void renumberValuesOnNodes(double epsOnVals, const int *old2New, int newNbOfNodes, DataArrayDouble *arr) const; - MEDCOUPLING_EXPORT void renumberValuesOnCells(double epsOnVals, const MEDCouplingMesh *mesh, const int *old2New, int newSz, DataArrayDouble *arr) const; - MEDCOUPLING_EXPORT void renumberValuesOnCellsR(const MEDCouplingMesh *mesh, const int *new2old, int newSz, DataArrayDouble *arr) const; - MEDCOUPLING_EXPORT void reprQuickOverview(std::ostream& stream) const; - MEDCOUPLING_EXPORT static const double *GetWeightArrayFromGeometricType(INTERP_KERNEL::NormalizedCellType geoType, std::size_t& lgth); - MEDCOUPLING_EXPORT static const double *GetRefCoordsFromGeometricType(INTERP_KERNEL::NormalizedCellType geoType, std::size_t& lgth); - MEDCOUPLING_EXPORT static const double *GetLocsFromGeometricType(INTERP_KERNEL::NormalizedCellType geoType, std::size_t& lgth); - protected: - MEDCOUPLING_EXPORT MEDCouplingFieldDiscretizationGaussNE(const MEDCouplingFieldDiscretizationGaussNE& other); - public: - static const char REPR[]; - static const TypeOfField TYPE; - static const double FGP_POINT1[1]; - 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];//to check - static const double FGP_PENTA6[6]; - static const double FGP_PENTA15[15];//to check - static const double FGP_HEXA8[8]; - static const double FGP_HEXA20[20];//to check - static const double FGP_HEXA27[27]; - static const double FGP_PYRA5[5]; - static const double FGP_PYRA13[13];//to check - 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]; - static const double LOC_SEG2[2]; - static const double LOC_SEG3[3]; - static const double LOC_SEG4[4]; - static const double LOC_TRI3[6]; - static const double LOC_TRI6[12]; - static const double LOC_TRI7[14]; - static const double LOC_QUAD4[8]; - static const double LOC_QUAD8[16]; - static const double LOC_QUAD9[18]; - static const double LOC_TETRA4[12]; - static const double LOC_TETRA10[30];//to check - static const double LOC_PENTA6[18]; - static const double LOC_PENTA15[45];//to check - static const double LOC_HEXA8[24]; - static const double LOC_HEXA20[60];//to check - static const double LOC_HEXA27[81]; - static const double LOC_PYRA5[15]; - static const double LOC_PYRA13[39];//to check - }; - - class MEDCouplingFieldDiscretizationKriging : public MEDCouplingFieldDiscretizationOnNodes - { - public: - MEDCOUPLING_EXPORT TypeOfField getEnum() const; - MEDCOUPLING_EXPORT const char *getRepr() const; - MEDCOUPLING_EXPORT MEDCouplingFieldDiscretization *clone() const; - MEDCOUPLING_EXPORT std::string getStringRepr() const; - MEDCOUPLING_EXPORT void checkCompatibilityWithNature(NatureOfField nat) const; - MEDCOUPLING_EXPORT bool isEqualIfNotWhy(const MEDCouplingFieldDiscretization *other, double eps, std::string& reason) const; - MEDCOUPLING_EXPORT MEDCouplingFieldDouble *getMeasureField(const MEDCouplingMesh *mesh, bool isAbs) const; - MEDCOUPLING_EXPORT void getValueOn(const DataArrayDouble *arr, const MEDCouplingMesh *mesh, const double *loc, double *res) const; - MEDCOUPLING_EXPORT DataArrayDouble *getValueOnMulti(const DataArrayDouble *arr, const MEDCouplingMesh *mesh, const double *loc, int nbOfPoints) const; - MEDCOUPLING_EXPORT void reprQuickOverview(std::ostream& stream) const; - public://specific part - MEDCOUPLING_EXPORT DataArrayDouble *computeEvaluationMatrixOnGivenPts(const MEDCouplingMesh *mesh, const double *loc, int nbOfTargetPoints, int& nbCols) const; - MEDCOUPLING_EXPORT DataArrayDouble *computeInverseMatrix(const MEDCouplingMesh *mesh, int& isDrift, int& matSz) const; - MEDCOUPLING_EXPORT DataArrayDouble *computeMatrix(const MEDCouplingMesh *mesh, int& isDrift, int& matSz) const; - MEDCOUPLING_EXPORT DataArrayDouble *computeVectorOfCoefficients(const MEDCouplingMesh *mesh, const DataArrayDouble *arr, int& isDrift) const; - MEDCOUPLING_EXPORT void operateOnDenseMatrix(int spaceDimension, int nbOfElems, double *matrixPtr) const; - MEDCOUPLING_EXPORT DataArrayDouble *performDrift(const DataArrayDouble *matr, const DataArrayDouble *arr, int& delta) const; - MEDCOUPLING_EXPORT static void OperateOnDenseMatrixH3(int nbOfElems, double *matrixPtr); - MEDCOUPLING_EXPORT static void OperateOnDenseMatrixH2Ln(int nbOfElems, double *matrixPtr); - MEDCOUPLING_EXPORT static DataArrayDouble *PerformDriftRect(const DataArrayDouble *matr, const DataArrayDouble *arr, int& delta); - MEDCOUPLING_EXPORT static DataArrayDouble *PerformDriftOfVec(const DataArrayDouble *arr, int isDrift); - public: - static const char REPR[]; - static const TypeOfField TYPE; - }; -} - -#endif diff --git a/src/MEDCoupling/MEDCouplingFieldDouble.cxx b/src/MEDCoupling/MEDCouplingFieldDouble.cxx deleted file mode 100644 index 23d1314c6..000000000 --- a/src/MEDCoupling/MEDCouplingFieldDouble.cxx +++ /dev/null @@ -1,3356 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 -// 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 "MEDCouplingFieldDouble.hxx" -#include "MEDCouplingFieldTemplate.hxx" -#include "MEDCouplingUMesh.hxx" -#include "MEDCouplingTimeDiscretization.hxx" -#include "MEDCouplingFieldDiscretization.hxx" -#include "MEDCouplingAutoRefCountObjectPtr.hxx" -#include "MEDCouplingNatureOfField.hxx" - -#include "InterpKernelAutoPtr.hxx" - -#include -#include -#include -#include - -using namespace ParaMEDMEM; - - -/*! - * 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); -} - -/*! - * 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 std::string& unit) -{ - _time_discr->setTimeUnit(unit); -} - -/*! - * Returns a time unit of \a this field. - * \return a string describing units in which time is measured. - */ -std::string MEDCouplingFieldDouble::getTimeUnit() const -{ - return _time_discr->getTimeUnit(); -} - -/*! - * This method if possible the time information (time unit, time iteration, time unit and time value) with its support - * that is to say its mesh. - * - * \throw If \c this->_mesh is null an exception will be thrown. An exception will also be throw if the spatial discretization is - * NO_TIME. - */ -void MEDCouplingFieldDouble::synchronizeTimeWithSupport() -{ - _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". - * - * \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 -{ - return new MEDCouplingFieldDouble(*this,recDeepCpy); -} - -/*! - * 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". - * - * 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 -{ - MEDCouplingAutoRefCountObjectPtr ret=clone(recDeepCpy); - if(_mesh) - { - MEDCouplingAutoRefCountObjectPtr mCpy=_mesh->deepCpy(); - ret->setMesh(mCpy); - } - return ret.retn(); -} - -/*! - * 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. - * - * \if ENABLE_EXAMPLES - * \ref cpp_mcfielddouble_buildNewTimeReprFromThis "Here is a C++ example."
- * \ref py_mcfielddouble_buildNewTimeReprFromThis "Here is a Python example." - * \endif - * \sa clone() - */ -MEDCouplingFieldDouble *MEDCouplingFieldDouble::buildNewTimeReprFromThis(TypeOfTimeDiscretization td, bool deepCopy) const -{ - MEDCouplingTimeDiscretization *tdo=_time_discr->buildNewTimeReprFromThis(td,deepCopy); - 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.retn(); -} - -/*! - * This method converts a field on nodes (\a this) to a cell field (returned field). The convertion is a \b non \b conservative remapping ! - * This method is useful only for users that need a fast convertion from node to cell spatial discretization. The algorithm applied is simply to attach - * to each cell the average of values on nodes constituting this cell. - * - * \return MEDCouplingFieldDouble* - a new instance of MEDCouplingFieldDouble. The - * caller is to delete this field using decrRef() as it is no more needed. The returned field will share the same mesh object object than those in \a this. - * \throw If \a this spatial discretization is empty or not ON_NODES. - * \throw If \a this is not coherent (see MEDCouplingFieldDouble::checkCoherency). - * - * \warning This method is a \b non \b conservative method of remapping from node spatial discretization to cell spatial discretization. - * If a conservative method of interpolation is required ParaMEDMEM::MEDCouplingRemapper class should be used instead with "P1P0" method. - */ -MEDCouplingFieldDouble *MEDCouplingFieldDouble::nodeToCellDiscretization() const -{ - checkCoherency(); - TypeOfField tf(getTypeOfField()); - if(tf!=ON_NODES) - throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::nodeToCellDiscretization : this field is expected to be on ON_NODES !"); - MEDCouplingAutoRefCountObjectPtr ret(clone(false)); - MEDCouplingAutoRefCountObjectPtr nsp(new MEDCouplingFieldDiscretizationP0); - ret->setDiscretization(nsp); - const MEDCouplingMesh *m(getMesh());//m is non empty thanks to checkCoherency call - int nbCells(m->getNumberOfCells()); - std::vector arrs(getArrays()); - std::size_t sz(arrs.size()); - std::vector< MEDCouplingAutoRefCountObjectPtr > outArrsSafe(sz); std::vector outArrs(sz); - for(std::size_t j=0;jgetNumberOfComponents()); - outArrsSafe[j]=DataArrayDouble::New(); outArrsSafe[j]->alloc(nbCells,nbCompo); - outArrsSafe[j]->copyStringInfoFrom(*arrs[j]); - outArrs[j]=outArrsSafe[j]; - double *pt(outArrsSafe[j]->getPointer()); - const double *srcPt(arrs[j]->begin()); - for(int i=0;i nodeIds; - m->getNodeIdsOfCell(i,nodeIds); - std::fill(pt,pt+nbCompo,0.); - std::size_t nbNodesInCell(nodeIds.size()); - for(std::size_t k=0;k()); - if(nbNodesInCell!=0) - std::transform(pt,pt+nbCompo,pt,std::bind2nd(std::multiplies(),1./((double)nbNodesInCell))); - else - { - std::ostringstream oss; oss << "MEDCouplingFieldDouble::nodeToCellDiscretization : Cell id #" << i << " has been detected to have no nodes !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - } - } - ret->setArrays(outArrs); - return ret.retn(); -} - -/*! - * This method converts a field on cell (\a this) to a node field (returned field). The convertion is a \b non \b conservative remapping ! - * This method is useful only for users that need a fast convertion from cell to node spatial discretization. The algorithm applied is simply to attach - * to each node the average of values on cell sharing this node. If \a this lies on a mesh having orphan nodes the values applied on them will be NaN (division by 0.). - * - * \return MEDCouplingFieldDouble* - a new instance of MEDCouplingFieldDouble. The - * caller is to delete this field using decrRef() as it is no more needed. The returned field will share the same mesh object object than those in \a this. - * \throw If \a this spatial discretization is empty or not ON_CELLS. - * \throw If \a this is not coherent (see MEDCouplingFieldDouble::checkCoherency). - * - * \warning This method is a \b non \b conservative method of remapping from cell spatial discretization to node spatial discretization. - * If a conservative method of interpolation is required ParaMEDMEM::MEDCouplingRemapper class should be used instead with "P0P1" method. - */ -MEDCouplingFieldDouble *MEDCouplingFieldDouble::cellToNodeDiscretization() const -{ - checkCoherency(); - TypeOfField tf(getTypeOfField()); - if(tf!=ON_CELLS) - throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::cellToNodeDiscretization : this field is expected to be on ON_CELLS !"); - MEDCouplingAutoRefCountObjectPtr ret(clone(false)); - MEDCouplingAutoRefCountObjectPtr nsp(new MEDCouplingFieldDiscretizationP1); - ret->setDiscretization(nsp); - const MEDCouplingMesh *m(getMesh());//m is non empty thanks to checkCoherency call - MEDCouplingAutoRefCountObjectPtr rn(DataArrayInt::New()),rni(DataArrayInt::New()); - m->getReverseNodalConnectivity(rn,rni); - MEDCouplingAutoRefCountObjectPtr rni2(rni->deltaShiftIndex()); - MEDCouplingAutoRefCountObjectPtr rni3(rni2->convertToDblArr()); rni2=0; - std::vector arrs(getArrays()); - std::size_t sz(arrs.size()); - std::vector< MEDCouplingAutoRefCountObjectPtr > outArrsSafe(sz); std::vector outArrs(sz); - for(std::size_t j=0;j tmp(arrs[j]->selectByTupleIdSafe(rn->begin(),rn->end())); - outArrsSafe[j]=(tmp->accumulatePerChunck(rni->begin(),rni->end())); tmp=0; - outArrsSafe[j]->divideEqual(rni3); - outArrsSafe[j]->copyStringInfoFrom(*arrs[j]); - outArrs[j]=outArrsSafe[j]; - } - ret->setArrays(outArrs); - return ret.retn(); -} - -/*! - * 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 MEDCouplingField *other) -{ - MEDCouplingField::copyTinyStringsFrom(other); - const MEDCouplingFieldDouble *otherC=dynamic_cast(other); - if(otherC) - { - _time_discr->copyTinyStringsFrom(*otherC->_time_discr); - } -} - -/*! - * 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) -{ - if(other) - { - _time_discr->copyTinyAttrFrom(*other->_time_discr); - } -} - -void MEDCouplingFieldDouble::copyAllTinyAttrFrom(const MEDCouplingFieldDouble *other) -{ - 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"; - 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()) - { - 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(); - else - ret << "Mesh support information : No mesh set !\n"; - 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"; - 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) - ret << "Mesh support information :\n__________________________\n" << _mesh->advancedRepr(); - else - ret << "Mesh support information : No mesh set !\n"; - std::vector arrays; - _time_discr->getArrays(arrays); - int arrayId=0; - for(std::vector::const_iterator iter=arrays.begin();iter!=arrays.end();iter++,arrayId++) - { - ret << "Array #" << arrayId << " :\n__________\n"; - if(*iter) - (*iter)->reprWithoutNameStream(ret); - else - ret << "Array empty !"; - ret << "\n"; - } - return ret.str(); -} - -std::string MEDCouplingFieldDouble::writeVTK(const std::string& fileName, bool isBinary) const -{ - std::vector fs(1,this); - return MEDCouplingFieldDouble::WriteVTK(fileName,fs,isBinary); -} - -bool MEDCouplingFieldDouble::isEqualIfNotWhy(const MEDCouplingField *other, double meshPrec, double valsPrec, std::string& reason) const -{ - if(!other) - throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::isEqualIfNotWhy : other instance is NULL !"); - const MEDCouplingFieldDouble *otherC=dynamic_cast(other); - if(!otherC) - { - reason="field given in input is not castable in MEDCouplingFieldDouble !"; - return false; - } - if(!MEDCouplingField::isEqualIfNotWhy(other,meshPrec,valsPrec,reason)) - return false; - if(!_time_discr->isEqualIfNotWhy(otherC->_time_discr,valsPrec,reason)) - { - reason.insert(0,"In FieldDouble time discretizations differ :"); - return false; - } - 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); - if(!otherC) - return false; - if(!MEDCouplingField::isEqualWithoutConsideringStr(other,meshPrec,valsPrec)) - return false; - if(!_time_discr->isEqualWithoutConsideringStr(otherC->_time_discr,valsPrec)) - return false; - return true; -} - -/*! - * This method states if \a this and 'other' are compatibles each other before performing any treatment. - * This method is good for methods like : mergeFields. - * This method is not very demanding compared to areStrictlyCompatible that is better for operation on fields. - */ -bool MEDCouplingFieldDouble::areCompatibleForMerge(const MEDCouplingField *other) const -{ - if(!MEDCouplingField::areCompatibleForMerge(other)) - return false; - const MEDCouplingFieldDouble *otherC=dynamic_cast(other); - if(!otherC) - return false; - if(!_time_discr->areCompatible(otherC->_time_discr)) - return false; - return true; -} - -/*! - * This method is more strict than MEDCouplingField::areCompatibleForMerge method. - * This method is used for operation on fields to operate a first check before attempting operation. - */ -bool MEDCouplingFieldDouble::areStrictlyCompatible(const MEDCouplingField *other) const -{ - std::string tmp; - if(!MEDCouplingField::areStrictlyCompatible(other)) - return false; - const MEDCouplingFieldDouble *otherC=dynamic_cast(other); - if(!otherC) - return false; - if(!_time_discr->areStrictlyCompatible(otherC->_time_discr,tmp)) - return false; - return true; -} - -/*! - * Method with same principle than MEDCouplingFieldDouble::areStrictlyCompatibleForMulDiv method except that - * number of components between \a this and 'other' can be different here (for operator*). - */ -bool MEDCouplingFieldDouble::areCompatibleForMul(const MEDCouplingField *other) const -{ - if(!MEDCouplingField::areStrictlyCompatibleForMulDiv(other)) - return false; - const MEDCouplingFieldDouble *otherC=dynamic_cast(other); - if(!otherC) - return false; - if(!_time_discr->areStrictlyCompatibleForMul(otherC->_time_discr)) - return false; - return true; -} - -/*! - * Method with same principle than MEDCouplingFieldDouble::areStrictlyCompatibleForMulDiv method except that - * number of components between \a this and 'other' can be different here (for operator/). - */ -bool MEDCouplingFieldDouble::areCompatibleForDiv(const MEDCouplingField *other) const -{ - if(!MEDCouplingField::areStrictlyCompatibleForMulDiv(other)) - return false; - const MEDCouplingFieldDouble *otherC=dynamic_cast(other); - if(!otherC) - return false; - if(!_time_discr->areStrictlyCompatibleForDiv(otherC->_time_discr)) - return false; - return true; -} - -/*! - * This method is invocated before any attempt of melding. This method is very close to areStrictlyCompatible, - * except that \a this and other can have different number of components. - */ -bool MEDCouplingFieldDouble::areCompatibleForMeld(const MEDCouplingFieldDouble *other) const -{ - if(!MEDCouplingField::areStrictlyCompatible(other)) - return false; - if(!_time_discr->areCompatibleForMeld(other->_time_discr)) - return false; - return true; -} - -/*! - * 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. - * ** Warning, this method modifies the mesh aggreagated by \a this (by performing a deep copy ) **. - * - * \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). - * - * \if ENABLE_EXAMPLES - * \ref cpp_mcfielddouble_renumberCells "Here is a C++ example".
- * \ref py_mcfielddouble_renumberCells "Here is a Python example". - * \endif - */ -void MEDCouplingFieldDouble::renumberCells(const int *old2NewBg, bool check) -{ - renumberCellsWithoutMesh(old2NewBg,check); - MEDCouplingAutoRefCountObjectPtr m=_mesh->deepCpy(); - m->renumberCells(old2NewBg,check); - setMesh(m); - updateTime(); -} - -/*! - * 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) -{ - if(!_mesh) - 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); - std::vector arrays2(arrays.size()); std::copy(arrays.begin(),arrays.end(),arrays2.begin()); - _type->renumberArraysForCell(_mesh,arrays2,old2NewBg,check); - // - updateTime(); -} - -/*! - * 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. - * - * \if ENABLE_EXAMPLES - * \ref cpp_mcfielddouble_renumberNodes "Here is a C++ example".
- * \ref py_mcfielddouble_renumberNodes "Here is a Python example". - * \endif - */ -void MEDCouplingFieldDouble::renumberNodes(const int *old2NewBg, double eps) -{ - const MEDCouplingPointSet *meshC=dynamic_cast(_mesh); - if(!meshC) - throw INTERP_KERNEL::Exception("Invalid mesh to apply renumberNodes on it !"); - int nbOfNodes=meshC->getNumberOfNodes(); - MEDCouplingAutoRefCountObjectPtr meshC2((MEDCouplingPointSet *)meshC->deepCpy()); - int newNbOfNodes=*std::max_element(old2NewBg,old2NewBg+nbOfNodes)+1; - renumberNodesWithoutMesh(old2NewBg,newNbOfNodes,eps); - meshC2->renumberNodes(old2NewBg,newNbOfNodes); - setMesh(meshC2); -} - -/*! - * 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) -{ - 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++) - if(*iter) - _type->renumberValuesOnNodes(eps,old2NewBg,newNbOfNodes,*iter); -} - -/*! - * 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 -{ - if(getArray()==0) - throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::getIdsInRange : no default array set !"); - return getArray()->getIdsInRange(vmin,vmax); -} - -/*! - * 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 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. - * - * \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 ENABLE_EXAMPLES - * \ref cpp_mcfielddouble_subpart1 "Here is a C++ example".
- * \ref py_mcfielddouble_subpart1 "Here is a Python example". - * \endif - * \sa MEDCouplingFieldDouble::buildSubPartRange - */ - -MEDCouplingFieldDouble *MEDCouplingFieldDouble::buildSubPart(const DataArrayInt *part) const -{ - if(part==0) - throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::buildSubPart : not empty array must be passed to this method !"); - 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 \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"). - * - * 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(). - * - * 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 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 \a this->getMesh(). - * - * \if ENABLE_EXAMPLES - * \ref cpp_mcfielddouble_subpart1 "Here a C++ example."
- * \ref py_mcfielddouble_subpart1 "Here a Python example." - * \endif - * \sa ParaMEDMEM::MEDCouplingFieldDouble::buildSubPart(const DataArrayInt *) const, MEDCouplingFieldDouble::buildSubPartRange - */ -MEDCouplingFieldDouble *MEDCouplingFieldDouble::buildSubPart(const int *partBg, const int *partEnd) const -{ - 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); - MEDCouplingAutoRefCountObjectPtr ret=clone(false);//quick shallow copy. - const MEDCouplingFieldDiscretization *disc=getDiscretization(); - if(disc) - 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++) - { - DataArrayDouble *arr=0; - if(*iter) - arr=(*iter)->selectByTupleIdSafe(arrSelBg,arrSelEnd); - arrs.push_back(arr); arrsSafe.push_back(arr); - } - ret->_time_discr->setArrays(arrs,0); - 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 -{ - 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(); -} - -MEDCouplingFieldDouble::MEDCouplingFieldDouble(TypeOfField type, TypeOfTimeDiscretization td):MEDCouplingField(type), - _time_discr(MEDCouplingTimeDiscretization::New(td)) -{ -} - -/*! - * ** 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,deepCopy), - _time_discr(other._time_discr->performCpy(deepCopy)) -{ -} - -MEDCouplingFieldDouble::MEDCouplingFieldDouble(NatureOfField n, MEDCouplingTimeDiscretization *td, MEDCouplingFieldDiscretization *type):MEDCouplingField(type,n),_time_discr(td) -{ -} - -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 -{ - 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()); -} - -/*! - * 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 -{ - if(getArray()==0) - throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::accumulate : no default array defined !"); - return getArray()->accumulate(compId); -} - -/*! - * 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 -{ - if(getArray()==0) - throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::accumulate : no default array defined !"); - getArray()->accumulate(res); -} - -/*! - * 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 -{ - std::vector arrays; - _time_discr->getArrays(arrays); - double ret=-std::numeric_limits::max(); - bool isExistingArr=false; - for(std::vector::const_iterator iter=arrays.begin();iter!=arrays.end();iter++) - { - if(*iter) - { - isExistingArr=true; - int loc; - ret=std::max(ret,(*iter)->getMaxValue(loc)); - } - } - if(!isExistingArr) - throw INTERP_KERNEL::Exception("getMaxValue : No arrays defined !"); - return ret; -} - -/*! - * 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 -{ - std::vector arrays; - _time_discr->getArrays(arrays); - 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) - { - isExistingArr=true; - DataArrayInt *tmp; - ret=std::max(ret,(*iter)->getMaxValue2(tmp)); - MEDCouplingAutoRefCountObjectPtr tmpSafe(tmp); - if(!((const DataArrayInt *)ret1)) - ret1=tmpSafe; - } - } - if(!isExistingArr) - throw INTERP_KERNEL::Exception("getMaxValue2 : No arrays defined !"); - tupleIds=ret1.retn(); - return ret; -} - -/*! - * 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 -{ - std::vector arrays; - _time_discr->getArrays(arrays); - double ret=std::numeric_limits::max(); - bool isExistingArr=false; - for(std::vector::const_iterator iter=arrays.begin();iter!=arrays.end();iter++) - { - if(*iter) - { - isExistingArr=true; - int loc; - ret=std::min(ret,(*iter)->getMinValue(loc)); - } - } - if(!isExistingArr) - throw INTERP_KERNEL::Exception("getMinValue : No arrays defined !"); - return ret; -} - -/*! - * 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 -{ - std::vector arrays; - _time_discr->getArrays(arrays); - 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) - { - isExistingArr=true; - DataArrayInt *tmp; - ret=std::max(ret,(*iter)->getMinValue2(tmp)); - MEDCouplingAutoRefCountObjectPtr tmpSafe(tmp); - if(!((const DataArrayInt *)ret1)) - ret1=tmpSafe; - } - } - if(!isExistingArr) - throw INTERP_KERNEL::Exception("getMinValue2 : No arrays defined !"); - tupleIds=ret1.retn(); - return ret; -} - -/*! - * 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 -{ - if(getArray()==0) - throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::getAverageValue : no default array defined !"); - return getArray()->getAverageValue(); -} - -/*! - * This method returns the euclidean norm of \a this field. - * \f[ - * \sqrt{\sum_{0 \leq i < nbOfEntity}val[i]*val[i]} - * \f] - * \throw If the data array is not set. - */ -double MEDCouplingFieldDouble::norm2() const -{ - if(getArray()==0) - throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::norm2 : no default array defined !"); - return getArray()->norm2(); -} - -/*! - * This method returns the max norm of \a this field. - * \f[ - * \max_{0 \leq i < nbOfEntity}{abs(val[i])} - * \f] - * \throw If the data array is not set. - */ -double MEDCouplingFieldDouble::normMax() const -{ - if(getArray()==0) - throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::normMax : no default array defined !"); - return getArray()->normMax(); -} - -/*! - * Computes the weighted average of values of each component of \a this field, the weights being the - * 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 weights computed by - * buildMeasureField(). It makes this method slower. If you are sure that all - * the cells of the underlying mesh have a correct orientation (no negative volume), you can put \a isWAbs == - * \c false to speed up the method. - * \throw If the mesh is not set. - * \throw If the data array is not set. - */ -void MEDCouplingFieldDouble::getWeightedAverageValue(double *res, bool isWAbs) const -{ - if(getArray()==0) - throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::getWeightedAverageValue : no default array defined !"); - MEDCouplingAutoRefCountObjectPtr w=buildMeasureField(isWAbs); - double deno=w->getArray()->accumulate(0); - MEDCouplingAutoRefCountObjectPtr arr=getArray()->deepCpy(); - arr->multiplyEqual(w->getArray()); - arr->accumulate(res); - int nCompo = getArray()->getNumberOfComponents(); - std::transform(res,res+nCompo,res,std::bind2nd(std::multiplies(),1./deno)); -} - -/*! - * Computes the weighted average of values of a given component of \a this field, the weights being the - * 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 weights computed by - * buildMeasureField(). It makes this method slower. If you are sure that all - * the cells of the underlying mesh have a correct orientation (no negative volume), you can put \a isWAbs == - * \c false to speed up the 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 -{ - 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] - * \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 -{ - 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 !"); - int nbComps=getArray()->getNumberOfComponents(); - if(compId<0 || compId>=nbComps) - { - 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()); - } - INTERP_KERNEL::AutoPtr res=new double[nbComps]; - _type->normL1(_mesh,getArray(),res); - return res[compId]; -} - -/*! - * 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] - * \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 -{ - 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 \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] - * \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 -{ - 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<0 || compId>=nbComps) - { - 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()); - } - INTERP_KERNEL::AutoPtr res=new double[nbComps]; - _type->normL2(_mesh,getArray(),res); - return res[compId]; -} - -/*! - * 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] - * \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 -{ - 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); -} - -/*! - * 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 -{ - 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<0 || compId>=nbComps) - { - 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()); - } - INTERP_KERNEL::AutoPtr res=new double[nbComps]; - _type->integral(_mesh,getArray(),isWAbs,res); - return res[compId]; -} - -/*! - * 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 -{ - 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); -} - -/*! - * 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. - * - * \if ENABLE_EXAMPLES - * \ref cpp_mcfielddouble_getValueOnPos "Here is a C++ example".
- * \ref py_mcfielddouble_getValueOnPos "Here is a Python example". - * \endif - */ -void MEDCouplingFieldDouble::getValueOnPos(int i, int j, int k, double *res) const -{ - 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 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. - * - * \if ENABLE_EXAMPLES - * \ref cpp_mcfielddouble_getValueOn "Here is a C++ example".
- * \ref py_mcfielddouble_getValueOn "Here is a Python example". - * \endif - */ -void MEDCouplingFieldDouble::getValueOn(const double *spaceLoc, double *res) const -{ - 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 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. - * - * \if ENABLE_EXAMPLES - * \ref cpp_mcfielddouble_getValueOnMulti "Here is a C++ example".
- * \ref py_mcfielddouble_getValueOnMulti "Here is a Python example". - * \endif - */ -DataArrayDouble *MEDCouplingFieldDouble::getValueOnMulti(const double *spaceLoc, int nbOfPoints) const -{ - 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 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. - * - * \if ENABLE_EXAMPLES - * \ref cpp_mcfielddouble_getValueOn_time "Here is a C++ example".
- * \ref py_mcfielddouble_getValueOn_time "Here is a Python example". - * \endif - */ -void MEDCouplingFieldDouble::getValueOn(const double *spaceLoc, double time, double *res) const -{ - 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++) - { - int sz=(int)res2.size(); - res2.resize(sz+(*iter)->getNumberOfComponents()); - _type->getValueOn(*iter,_mesh,spaceLoc,&res2[sz]); - } - _time_discr->getValueForTime(time,res2,res); -} - -/*! - * Apply a linear 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) -{ - _time_discr->applyLin(a,b,compoId); -} - -/*! - * Apply a linear function to all components of \a this field, so that - * values (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 the data array(s) is(are) not set. - */ -void MEDCouplingFieldDouble::applyLin(double a, double b) -{ - _time_discr->applyLin(a,b); -} - -/*! - * This method sets \a this to a uniform scalar field with one component. - * All tuples will have the same value 'value'. - * An exception is thrown if no underlying mesh is defined. - */ -MEDCouplingFieldDouble &MEDCouplingFieldDouble::operator=(double value) -{ - 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->setOrCreateUniformValueOnAllComponents(nbOfTuple,value); - return *this; -} - -/*! - * 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. - * - * \if ENABLE_EXAMPLES - * \ref cpp_mcfielddouble_fillFromAnalytic_c_func "Here is a C++ example". - * \endif - */ -void MEDCouplingFieldDouble::fillFromAnalytic(int nbOfComp, FunctionToEvaluate func) -{ - 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); -} - -/*! - * 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. - * - * \if ENABLE_EXAMPLES - * \ref cpp_mcfielddouble_fillFromAnalytic "Here is a C++ example".
- * \ref py_mcfielddouble_fillFromAnalytic "Here is a Python example". - * \endif - */ -void MEDCouplingFieldDouble::fillFromAnalytic(int nbOfComp, const std::string& func) -{ - 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); -} - -/*! - * 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 std::string& 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. - * - * \if ENABLE_EXAMPLES - * \ref cpp_mcfielddouble_fillFromAnalytic2 "Here is a C++ example".
- * \ref py_mcfielddouble_fillFromAnalytic2 "Here is a Python example". - * \endif - */ -void MEDCouplingFieldDouble::fillFromAnalytic2(int nbOfComp, const std::string& func) -{ - 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); -} - -/*! - * 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 std::string& 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. - * - * \if ENABLE_EXAMPLES - * \ref cpp_mcfielddouble_fillFromAnalytic3 "Here is a C++ example".
- * \ref py_mcfielddouble_fillFromAnalytic3 "Here is a Python example". - * \endif - */ -void MEDCouplingFieldDouble::fillFromAnalytic3(int nbOfComp, const std::vector& varsOrder, const std::string& func) -{ - 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); -} - -/*! - * 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. - * - * \if ENABLE_EXAMPLES - * \ref cpp_mcfielddouble_applyFunc_c_func "Here is a C++ example". - * \endif - */ -void MEDCouplingFieldDouble::applyFunc(int nbOfComp, FunctionToEvaluate func) -{ - _time_discr->applyFunc(nbOfComp,func); -} - -/*! - * 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. - * - * \if ENABLE_EXAMPLES - * \ref cpp_mcfielddouble_applyFunc_val "Here is a C++ example".
- * \ref py_mcfielddouble_applyFunc_val "Here is a Python example". - * \endif - */ -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); -} - -/*! - * 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. - * - * \if ENABLE_EXAMPLES - * \ref cpp_mcfielddouble_applyFunc "Here is a C++ example".
- * \ref py_mcfielddouble_applyFunc "Here is a Python example". - * \endif - */ -void MEDCouplingFieldDouble::applyFunc(int nbOfComp, const std::string& func) -{ - _time_discr->applyFunc(nbOfComp,func); -} - - -/*! - * 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 std::string& 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. - * - * \if ENABLE_EXAMPLES - * \ref cpp_mcfielddouble_applyFunc2 "Here is a C++ example".
- * \ref py_mcfielddouble_applyFunc2 "Here is a Python example". - * \endif - */ -void MEDCouplingFieldDouble::applyFunc2(int nbOfComp, const std::string& func) -{ - _time_discr->applyFunc2(nbOfComp,func); -} - -/*! - * 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 std::string& 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. - * - * \if ENABLE_EXAMPLES - * \ref cpp_mcfielddouble_applyFunc3 "Here is a C++ example".
- * \ref py_mcfielddouble_applyFunc3 "Here is a Python example". - * \endif - */ -void MEDCouplingFieldDouble::applyFunc3(int nbOfComp, const std::vector& varsOrder, const std::string& func) -{ - _time_discr->applyFunc3(nbOfComp,varsOrder,func); -} - -/*! - * Modifies values of \a this field by applying a function to each atomic value of all - * data arrays. The function computes a new single value basing on an old single value. - * For more info on supported expressions that can be used in the function, see \ref - * MEDCouplingArrayApplyFuncExpr.
- * 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. - * - * \if ENABLE_EXAMPLES - * \ref cpp_mcfielddouble_applyFunc_same_nb_comp "Here is a C++ example".
- * \ref py_mcfielddouble_applyFunc_same_nb_comp "Here is a Python example". - * \endif - */ -void MEDCouplingFieldDouble::applyFunc(const std::string& func) -{ - _time_discr->applyFunc(func); -} - -/*! - * Applyies the function specified by the string repr 'func' on each tuples on all arrays contained in _time_discr. - * The field will contain exactly the same number of components after the call. - * Use is not warranted for the moment ! - */ -void MEDCouplingFieldDouble::applyFuncFast32(const std::string& func) -{ - _time_discr->applyFuncFast32(func); -} - -/*! - * Applyies the function specified by the string repr 'func' on each tuples on all arrays contained in _time_discr. - * The field will contain exactly the same number of components after the call. - * Use is not warranted for the moment ! - */ -void MEDCouplingFieldDouble::applyFuncFast64(const std::string& func) -{ - _time_discr->applyFuncFast64(func); -} - -/*! - * Returns number of components in the data array. For more info on the data arrays, - * see \ref arrays. - * \return int - the number of components in the data array. - * \throw If the data array is not set. - */ -int MEDCouplingFieldDouble::getNumberOfComponents() const -{ - if(getArray()==0) - throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::getNumberOfComponents : No array specified !"); - return getArray()->getNumberOfComponents(); -} - -/*! - * Use MEDCouplingField::getNumberOfTuplesExpected instead of this method. This method will be removed soon, because it is - * confusing compared to getNumberOfComponents() and getNumberOfValues() behaviour. - * - * 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 \b not \b 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 (Sorry, it is confusing !). - * So \b this \b method \b behaves \b exactly \b as MEDCouplingField::getNumberOfTuplesExpected \b method. - * - * \warning No checkCoherency() is done here. - * For more info on the data arrays, see \ref arrays. - * \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. - * \sa MEDCouplingField::getNumberOfTuplesExpected - */ -int MEDCouplingFieldDouble::getNumberOfTuples() const -{ - //std::cerr << " ******* MEDCouplingFieldDouble::getNumberOfTuples is deprecated : use MEDCouplingField::getNumberOfTuplesExpected instead ! ******" << std::endl; - 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); -} - -/*! - * Returns number of atomic double values in the data array of \a this field. - * For more info on the data arrays, see \ref arrays. - * \return int - (number of tuples) * (number of components) of the - * data array. - * \throw If the data array is not set. - */ -int MEDCouplingFieldDouble::getNumberOfValues() const -{ - if(getArray()==0) - throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::getNumberOfValues : No array specified !"); - 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::getHeapMemorySizeWithoutChildren() const -{ - return MEDCouplingField::getHeapMemorySizeWithoutChildren(); -} - -std::vector MEDCouplingFieldDouble::getDirectChildrenWithNull() const -{ - std::vector ret(MEDCouplingField::getDirectChildrenWithNull()); - if(_time_discr) - { - std::vector ret2(_time_discr->getDirectChildrenWithNull()); - ret.insert(ret.end(),ret2.begin(),ret2.end()); - } - return ret; -} - -/*! - * Sets \ref NatureOfField. - * \param [in] nat - an item of enum ParaMEDMEM::NatureOfField. - */ -void MEDCouplingFieldDouble::setNature(NatureOfField nat) -{ - MEDCouplingField::setNature(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() -{ - 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); -} - -/*! - * 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) -{ - _time_discr->setArrays(arrs,this); -} - -void MEDCouplingFieldDouble::getTinySerializationStrInformation(std::vector& tinyInfo) const -{ - tinyInfo.clear(); - _time_discr->getTinySerializationStrInformation(tinyInfo); - tinyInfo.push_back(_name); - tinyInfo.push_back(_desc); - tinyInfo.push_back(getTimeUnit()); -} - -/*! - * This method retrieves some critical values to resize and prepare remote instance. - * The first two elements returned in tinyInfo correspond to the parameters to give in constructor. - * @param tinyInfo out parameter resized correctly after the call. The length of this vector is tiny. - */ -void MEDCouplingFieldDouble::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)_time_discr->getEnum()); - tinyInfo.push_back((int)_nature); - _time_discr->getTinySerializationIntInformation(tinyInfo); - std::vector tinyInfo2; - _type->getTinySerializationIntInformation(tinyInfo2); - tinyInfo.insert(tinyInfo.end(),tinyInfo2.begin(),tinyInfo2.end()); - tinyInfo.push_back((int)tinyInfo2.size()); -} - -/*! - * This method retrieves some critical values to resize and prepare remote instance. - * @param tinyInfo out parameter resized correctly after the call. The length of this vector is tiny. - */ -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; - _type->getTinySerializationDbleInformation(tinyInfo2); - tinyInfo.insert(tinyInfo.end(),tinyInfo2.begin(),tinyInfo2.end()); - tinyInfo.push_back((int)tinyInfo2.size());//very bad, lack of time to improve it -} - -/*! - * This method has to be called to the new instance filled by CORBA, MPI, File... - * @param tinyInfoI is the value retrieves from distant result of getTinySerializationIntInformation on source instance to be copied. - * @param dataInt out parameter. If not null the pointer is already owned by \a this after the call of this method. In this case no decrRef must be applied. - * @param arrays out parameter is a vector resized to the right size. The pointers in the vector is already owned by \a this after the call of this method. - * No decrRef must be applied to every instances in returned vector. - * \sa checkForUnserialization - */ -void MEDCouplingFieldDouble::resizeForUnserialization(const 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(); - tinyInfoITmp.pop_back(); - std::vector tinyInfoITmp2(tinyInfoITmp.begin(),tinyInfoITmp.end()-sz); - std::vector tinyInfoI2(tinyInfoITmp2.begin()+3,tinyInfoITmp2.end()); - _time_discr->resizeForUnserialization(tinyInfoI2,arrays); - std::vector tinyInfoITmp3(tinyInfoITmp.end()-sz,tinyInfoITmp.end()); - _type->resizeForUnserialization(tinyInfoITmp3,dataInt); -} - -/*! - * This method is extremely close to resizeForUnserialization except that here the arrays in \a dataInt and in \a arrays are attached in \a this - * after having checked that size is correct. This method is used in python pickeling context to avoid copy of data. - * \sa resizeForUnserialization - */ -void MEDCouplingFieldDouble::checkForUnserialization(const std::vector& tinyInfoI, const DataArrayInt *dataInt, const std::vector& arrays) -{ - if(!((const MEDCouplingFieldDiscretization *)_type)) - throw INTERP_KERNEL::Exception("No spatial discretization underlying this field to perform resizeForUnserialization !"); - std::vector tinyInfoITmp(tinyInfoI); - int sz=tinyInfoITmp.back(); - tinyInfoITmp.pop_back(); - std::vector tinyInfoITmp2(tinyInfoITmp.begin(),tinyInfoITmp.end()-sz); - std::vector tinyInfoI2(tinyInfoITmp2.begin()+3,tinyInfoITmp2.end()); - _time_discr->checkForUnserialization(tinyInfoI2,arrays); - std::vector tinyInfoITmp3(tinyInfoITmp.end()-sz,tinyInfoITmp.end()); - _type->checkForUnserialization(tinyInfoITmp3,dataInt); -} - -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); - int sz=(int)tinyInfoD.back();//very bad, lack of time to improve it - tmp.pop_back(); - std::vector tmp1(tmp.begin(),tmp.end()-sz); - std::vector tmp2(tmp.end()-sz,tmp.end()); - // - _time_discr->finishUnserialization(tinyInfoI2,tmp1,tinyInfoS); - _nature=(NatureOfField)tinyInfoI[2]; - _type->finishUnserialization(tmp2); - int nbOfElemS=(int)tinyInfoS.size(); - _name=tinyInfoS[nbOfElemS-3]; - _desc=tinyInfoS[nbOfElemS-2]; - setTimeUnit(tinyInfoS[nbOfElemS-1]); -} - -/*! - * Contrary to MEDCouplingPointSet class the returned arrays are \b not the responsabilities of the caller. - * The values returned must be consulted only in readonly mode. - */ -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); -} - -/*! - * 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. - * - * \if ENABLE_EXAMPLES - * \ref cpp_mcfielddouble_changeUnderlyingMesh "Here is a C++ example".
- * \ref py_mcfielddouble_changeUnderlyingMesh "Here is a Python example". - * \endif - */ -void MEDCouplingFieldDouble::changeUnderlyingMesh(const MEDCouplingMesh *other, int levOfCheck, double precOnMesh, double eps) -{ - 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,precOnMesh,cellCor,nodeCor); - MEDCouplingAutoRefCountObjectPtr cellCor2(cellCor),nodeCor2(nodeCor); - if(cellCor) - renumberCellsWithoutMesh(cellCor->getConstPointer(),false); - if(nodeCor) - renumberNodesWithoutMesh(nodeCor->getConstPointer(),nodeCor->getMaxValueInArray()+1,eps); - setMesh(other); -} - -/*! - * 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. - * - * \if ENABLE_EXAMPLES - * \ref cpp_mcfielddouble_substractInPlaceDM "Here is a C++ example".
- * \ref py_mcfielddouble_substractInPlaceDM "Here is a Python example". - * \endif - * \sa changeUnderlyingMesh(). - */ -void MEDCouplingFieldDouble::substractInPlaceDM(const MEDCouplingFieldDouble *f, int levOfCheck, double precOnMesh, double eps) -{ - checkCoherency(); - if(!f) - throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::substractInPlaceDM : input field is NULL !"); - f->checkCoherency(); - if(!areCompatibleForMerge(f)) - throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::substractInPlaceDM : Fields are not compatible ; unable to apply mergeFields on them !"); - changeUnderlyingMesh(f->getMesh(),levOfCheck,precOnMesh,eps); - operator-=(*f); -} - -/*! - * 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) -{ - 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; - MEDCouplingAutoRefCountObjectPtr arr=meshC2->mergeNodes(eps,ret,ret2); - if(!ret)//no nodes have been merged. - return ret; - std::vector arrays; - _time_discr->getArrays(arrays); - for(std::vector::const_iterator iter=arrays.begin();iter!=arrays.end();iter++) - if(*iter) - _type->renumberValuesOnNodes(epsOnVals,arr->getConstPointer(),meshC2->getNumberOfNodes(),*iter); - setMesh(meshC2); - return true; -} - -/*! - * 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) -{ - 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; - MEDCouplingAutoRefCountObjectPtr arr=meshC2->mergeNodes2(eps,ret,ret2); - if(!ret)//no nodes have been merged. - return ret; - std::vector arrays; - _time_discr->getArrays(arrays); - for(std::vector::const_iterator iter=arrays.begin();iter!=arrays.end();iter++) - if(*iter) - _type->renumberValuesOnNodes(epsOnVals,arr->getConstPointer(),meshC2->getNumberOfNodes(),*iter); - setMesh(meshC2); - return true; -} - -/*! - * 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) -{ - 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(); - if(meshC2->getNumberOfNodes()!=oldNbOfNodes) - { - std::vector arrays; - _time_discr->getArrays(arrays); - for(std::vector::const_iterator iter=arrays.begin();iter!=arrays.end();iter++) - if(*iter) - _type->renumberValuesOnNodes(epsOnVals,arr->getConstPointer(),meshC2->getNumberOfNodes(),*iter); - setMesh(meshC2); - return true; - } - return false; -} - -/*! - * 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 - * MEDCouplingPointSet::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) -{ - const MEDCouplingUMesh *meshC=dynamic_cast(_mesh); - if(!meshC) - 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); - if(meshC2->getNumberOfCells()!=oldNbOfCells) - { - std::vector arrays; - _time_discr->getArrays(arrays); - for(std::vector::const_iterator iter=arrays.begin();iter!=arrays.end();iter++) - if(*iter) - _type->renumberValuesOnCells(epsOnVals,meshC,arr->getConstPointer(),meshC2->getNumberOfCells(),*iter); - setMesh(meshC2); - return true; - } - return false; -} - -/*! - * This method calls MEDCouplingUMesh::buildSlice3D method. So this method makes the assumption that underlying mesh exists. - * For the moment, this method is implemented for fields on cells. - * - * \return a newly allocated field double containing the result that the user should deallocate. - */ -MEDCouplingFieldDouble *MEDCouplingFieldDouble::extractSlice3D(const double *origin, const double *vec, double eps) const -{ - const MEDCouplingMesh *mesh=getMesh(); - if(!mesh) - throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::extractSlice3D : underlying mesh is null !"); - if(getTypeOfField()!=ON_CELLS) - throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::extractSlice3D : only implemented for fields on cells !"); - const MEDCouplingAutoRefCountObjectPtr umesh(mesh->buildUnstructured()); - MEDCouplingAutoRefCountObjectPtr ret=clone(false); - ret->setMesh(umesh); - DataArrayInt *cellIds=0; - MEDCouplingAutoRefCountObjectPtr mesh2=umesh->buildSlice3D(origin,vec,eps,cellIds); - MEDCouplingAutoRefCountObjectPtr cellIds2=cellIds; - ret->setMesh(mesh2); - MEDCouplingAutoRefCountObjectPtr tupleIds=computeTupleIdsToSelectFromCellIds(cellIds->begin(),cellIds->end()); - std::vector arrays; - _time_discr->getArrays(arrays); - int i=0; - std::vector newArr(arrays.size()); - std::vector< MEDCouplingAutoRefCountObjectPtr > newArr2(arrays.size()); - for(std::vector::const_iterator iter=arrays.begin();iter!=arrays.end();iter++,i++) - { - if(*iter) - { - newArr2[i]=(*iter)->selectByTupleIdSafe(cellIds->begin(),cellIds->end()); - newArr[i]=newArr2[i]; - } - } - ret->setArrays(newArr); - return ret.retn(); -} - -/*! - * 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) -{ - 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); - int newNbOfCells=meshC2->getNumberOfCells(); - if(oldNbOfCells==newNbOfCells) - return false; - std::vector arrays; - _time_discr->getArrays(arrays); - for(std::vector::const_iterator iter=arrays.begin();iter!=arrays.end();iter++) - if(*iter) - _type->renumberValuesOnCellsR(_mesh,arr->getConstPointer(),arr->getNbOfElems(),*iter); - setMesh(meshC2); - 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 -{ - 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); - MEDCouplingAutoRefCountObjectPtr ret=new MEDCouplingFieldDouble(getNature(),td,_type->clone()); - ret->setName("DoublyContractedProduct"); - ret->setMesh(getMesh()); - 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 -{ - 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); - MEDCouplingAutoRefCountObjectPtr ret=new MEDCouplingFieldDouble(getNature(),td,_type->clone()); - ret->setName("Determinant"); - ret->setMesh(getMesh()); - 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 -{ - 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); - MEDCouplingAutoRefCountObjectPtr ret=new MEDCouplingFieldDouble(getNature(),td,_type->clone()); - ret->setName("EigenValues"); - ret->setMesh(getMesh()); - 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 -{ - 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); - MEDCouplingAutoRefCountObjectPtr ret=new MEDCouplingFieldDouble(getNature(),td,_type->clone()); - ret->setName("EigenVectors"); - ret->setMesh(getMesh()); - 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 -{ - 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); - MEDCouplingAutoRefCountObjectPtr ret=new MEDCouplingFieldDouble(getNature(),td,_type->clone()); - ret->setName("Inversion"); - ret->setMesh(getMesh()); - 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 -{ - 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); - MEDCouplingAutoRefCountObjectPtr ret=new MEDCouplingFieldDouble(getNature(),td,_type->clone()); - ret->setName("Trace"); - ret->setMesh(getMesh()); - 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 -{ - 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); - MEDCouplingAutoRefCountObjectPtr ret=new MEDCouplingFieldDouble(getNature(),td,_type->clone()); - ret->setName("Deviator"); - ret->setMesh(getMesh()); - 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 -{ - 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); - MEDCouplingAutoRefCountObjectPtr ret=new MEDCouplingFieldDouble(getNature(),td,_type->clone()); - ret->setName("Magnitude"); - ret->setMesh(getMesh()); - 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 -{ - 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); - MEDCouplingAutoRefCountObjectPtr ret=new MEDCouplingFieldDouble(getNature(),td,_type->clone()); - std::ostringstream oss; - oss << "Max_" << getName(); - ret->setName(oss.str()); - ret->setMesh(getMesh()); - 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) -{ - _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 -{ - 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); - MEDCouplingAutoRefCountObjectPtr ret=new MEDCouplingFieldDouble(getNature(),td,_type->clone()); - ret->setName(getName()); - ret->setMesh(getMesh()); - 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) -{ - _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) -{ - _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 the spatial discretization of \a f1 is NULL. - * \throw If the time discretization of \a f1 is NULL. - * - * \if ENABLE_EXAMPLES - * \ref cpp_mcfielddouble_MergeFields "Here is a C++ example".
- * \ref py_mcfielddouble_MergeFields "Here is a Python example". - * \endif - */ -MEDCouplingFieldDouble *MEDCouplingFieldDouble::MergeFields(const MEDCouplingFieldDouble *f1, const MEDCouplingFieldDouble *f2) -{ - if(!f1->areCompatibleForMerge(f2)) - throw INTERP_KERNEL::Exception("Fields are not compatible. Unable to apply MergeFields on them ! Check support mesh, field nature, and spatial and time discretisation."); - const MEDCouplingMesh *m1(f1->getMesh()),*m2(f2->getMesh()); - 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 !"); - MEDCouplingTimeDiscretization *td=f1->_time_discr->aggregate(f2->_time_discr); - td->copyTinyAttrFrom(*f1->_time_discr); - MEDCouplingAutoRefCountObjectPtr ret=new MEDCouplingFieldDouble(f1->getNature(),td,f1->_type->clone()); - ret->setName(f1->getName()); - ret->setDescription(f1->getDescription()); - if(m1) - { - MEDCouplingAutoRefCountObjectPtr m=m1->mergeMyselfWith(m2); - ret->setMesh(m); - } - 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. - * - * \if ENABLE_EXAMPLES - * \ref cpp_mcfielddouble_MergeFields "Here is a C++ example".
- * \ref py_mcfielddouble_MergeFields "Here is a Python example". - * \endif - */ -MEDCouplingFieldDouble *MEDCouplingFieldDouble::MergeFields(const std::vector& a) -{ - if(a.size()<1) - throw INTERP_KERNEL::Exception("FieldDouble::MergeFields : size of array must be >= 1 !"); - std::vector< MEDCouplingAutoRefCountObjectPtr > ms(a.size()); - std::vector< const MEDCouplingUMesh *> ms2(a.size()); - std::vector< const MEDCouplingTimeDiscretization *> 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! Check support mesh, field nature, and spatial and time discretisation."); - for(int i=0;i<(int)a.size();i++) - { - if(a[i]->getMesh()) - { ms[i]=a[i]->getMesh()->buildUnstructured(); ms2[i]=ms[i]; } - else - { ms[i]=0; ms2[i]=0; } - tds[i]=a[i]->_time_discr; - } - MEDCouplingTimeDiscretization *td=tds[0]->aggregate(tds); - td->copyTinyAttrFrom(*(a[0]->_time_discr)); - MEDCouplingAutoRefCountObjectPtr ret=new MEDCouplingFieldDouble(a[0]->getNature(),td,a[0]->_type->clone()); - ret->setName(a[0]->getName()); - ret->setDescription(a[0]->getDescription()); - if(ms2[0]) - { - MEDCouplingAutoRefCountObjectPtr m=MEDCouplingUMesh::MergeUMeshes(ms2); - m->copyTinyInfoFrom(ms2[0]); - ret->setMesh(m); - } - 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) -{ - if(!f1->areCompatibleForMeld(f2)) - throw INTERP_KERNEL::Exception("Fields are not compatible. Unable to apply MeldFields on them ! Check support mesh, field nature, and spatial and time discretisation."); - MEDCouplingTimeDiscretization *td=f1->_time_discr->meld(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(); -} - -/*! - * 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) -{ - if(!f1) - throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::DotFields : input field is NULL !"); - if(!f1->areStrictlyCompatibleForMulDiv(f2)) - throw INTERP_KERNEL::Exception("Fields are not compatible. Unable to apply DotFields on them! Check support mesh, and spatial and time discretisation."); - MEDCouplingTimeDiscretization *td=f1->_time_discr->dot(f2->_time_discr); - td->copyTinyAttrFrom(*f1->_time_discr); - MEDCouplingFieldDouble *ret=new MEDCouplingFieldDouble(NoNature,td,f1->_type->clone()); - ret->setMesh(f1->getMesh()); - 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) -{ - if(!f1) - throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::CrossProductFields : input field is NULL !"); - if(!f1->areStrictlyCompatibleForMulDiv(f2)) - throw INTERP_KERNEL::Exception("Fields are not compatible. Unable to apply CrossProductFields on them! Check support mesh, and spatial and time discretisation."); - MEDCouplingTimeDiscretization *td=f1->_time_discr->crossProduct(f2->_time_discr); - td->copyTinyAttrFrom(*f1->_time_discr); - MEDCouplingAutoRefCountObjectPtr ret=new MEDCouplingFieldDouble(NoNature,td,f1->_type->clone()); - ret->setMesh(f1->getMesh()); - 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. - * - * \if ENABLE_EXAMPLES - * \ref cpp_mcfielddouble_MaxFields "Here is a C++ example".
- * \ref py_mcfielddouble_MaxFields "Here is a Python example". - * \endif - */ -MEDCouplingFieldDouble *MEDCouplingFieldDouble::MaxFields(const MEDCouplingFieldDouble *f1, const MEDCouplingFieldDouble *f2) -{ - 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! Check support mesh, field nature, and spatial and time discretisation."); - MEDCouplingTimeDiscretization *td=f1->_time_discr->max(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(); -} - -/*! - * 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. - * - * \if ENABLE_EXAMPLES - * \ref cpp_mcfielddouble_MaxFields "Here is a C++ example".
- * \ref py_mcfielddouble_MaxFields "Here is a Python example". - * \endif - */ -MEDCouplingFieldDouble *MEDCouplingFieldDouble::MinFields(const MEDCouplingFieldDouble *f1, const MEDCouplingFieldDouble *f2) -{ - 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! Check support mesh, field nature, and spatial and time discretisation."); - MEDCouplingTimeDiscretization *td=f1->_time_discr->min(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(); -} - -/*! - * 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 -{ - 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) -{ - 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! Check support mesh, field nature, and spatial and time discretisation."); - MEDCouplingTimeDiscretization *td=f1->_time_discr->add(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(); -} - -/*! - * 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) -{ - if(!areStrictlyCompatible(&other)) - throw INTERP_KERNEL::Exception("Fields are not compatible. Unable to apply += on them! Check support mesh, field nature, and spatial and time discretisation."); - _time_discr->addEqual(other._time_discr); - 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) -{ - 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! Check support mesh, field nature, and spatial and time discretisation."); - MEDCouplingTimeDiscretization *td=f1->_time_discr->substract(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(); -} - -/*! - * 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) -{ - if(!areStrictlyCompatible(&other)) - throw INTERP_KERNEL::Exception("Fields are not compatible. Unable to apply -= on them! Check support mesh, field nature, and spatial and time discretisation."); - _time_discr->substractEqual(other._time_discr); - 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, with no nature set. - * 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 multiplication (areCompatibleForMul()), - * i.e. they differ not only in values and possibly number of components. - */ -MEDCouplingFieldDouble *MEDCouplingFieldDouble::MultiplyFields(const MEDCouplingFieldDouble *f1, const MEDCouplingFieldDouble *f2) -{ - 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! Check support mesh, and spatial and time discretisation."); - MEDCouplingTimeDiscretization *td=f1->_time_discr->multiply(f2->_time_discr); - td->copyTinyAttrFrom(*f1->_time_discr); - MEDCouplingAutoRefCountObjectPtr ret=new MEDCouplingFieldDouble(NoNature,td,f1->_type->clone()); - ret->setMesh(f1->getMesh()); - 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, with no nature set. - * 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 multiplication - * (areCompatibleForMul()), - * i.e. they differ not only in values and possibly in number of components. - */ -const MEDCouplingFieldDouble &MEDCouplingFieldDouble::operator*=(const MEDCouplingFieldDouble& other) -{ - if(!areCompatibleForMul(&other)) - throw INTERP_KERNEL::Exception("Fields are not compatible. Unable to apply *= on them! Check support mesh, and spatial and time discretisation."); - _time_discr->multiplyEqual(other._time_discr); - _nature = NoNature; - 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, with no nature set. - * 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) -{ - 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! Check support mesh, and spatial and time discretisation."); - MEDCouplingTimeDiscretization *td=f1->_time_discr->divide(f2->_time_discr); - td->copyTinyAttrFrom(*f1->_time_discr); - MEDCouplingAutoRefCountObjectPtr ret=new MEDCouplingFieldDouble(NoNature,td,f1->_type->clone()); - ret->setMesh(f1->getMesh()); - 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) -{ - if(!areCompatibleForDiv(&other)) - throw INTERP_KERNEL::Exception("Fields are not compatible. Unable to apply /= on them! Check support mesh, and spatial and time discretisation."); - _time_discr->divideEqual(other._time_discr); - _nature = NoNature; - return *this; -} - -/*! - * Directly called by MEDCouplingFieldDouble::operator^. - * - * \sa MEDCouplingFieldDouble::operator^ - */ -MEDCouplingFieldDouble *MEDCouplingFieldDouble::PowFields(const MEDCouplingFieldDouble *f1, const MEDCouplingFieldDouble *f2) -{ - 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! Check support mesh, and spatial and time discretisation."); - MEDCouplingTimeDiscretization *td=f1->_time_discr->pow(f2->_time_discr); - td->copyTinyAttrFrom(*f1->_time_discr); - MEDCouplingAutoRefCountObjectPtr ret=new MEDCouplingFieldDouble(NoNature,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 -{ - return PowFields(this,&other); -} - -const MEDCouplingFieldDouble &MEDCouplingFieldDouble::operator^=(const MEDCouplingFieldDouble& other) -{ - if(!areCompatibleForDiv(&other)) - throw INTERP_KERNEL::Exception("Fields are not compatible. Unable to apply ^= on them! Check support mesh, and spatial and time discretisation."); - _time_discr->powEqual(other._time_discr); - _nature = NoNature; - 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. - * \param [in] isBinary - specifies the VTK format of the written file. By default true (Binary mode) - * \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. - * - * \if ENABLE_EXAMPLES - * \ref cpp_mcfielddouble_WriteVTK "Here is a C++ example".
- * \ref py_mcfielddouble_WriteVTK "Here is a Python example". - * \endif - */ -std::string MEDCouplingFieldDouble::WriteVTK(const std::string& fileName, const std::vector& fs, bool isBinary) -{ - if(fs.empty()) - return std::string(); - 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."); - if(!m) - throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::WriteVTK : Fields are lying on a same mesh but it is empty !"); - std::string ret(m->getVTKFileNameOf(fileName)); - MEDCouplingAutoRefCountObjectPtr byteArr; - if(isBinary) - { byteArr=DataArrayByte::New(); byteArr->alloc(0,1); } - std::ostringstream coss,noss; - for(std::size_t i=0;igetName()); - if(name.empty()) - { - std::ostringstream oss; oss << "MEDCouplingFieldDouble::WriteVTK : Field in pos #" << i << " has no name !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - TypeOfField typ=cur->getTypeOfField(); - if(typ==ON_CELLS) - cur->getArray()->writeVTK(coss,8,cur->getName(),byteArr); - else if(typ==ON_NODES) - cur->getArray()->writeVTK(noss,8,cur->getName(),byteArr); - else - throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::WriteVTK : only node and cell fields supported for the moment !"); - } - m->writeVTKAdvanced(ret,coss.str(),noss.str(),byteArr); - return ret; -} - -void MEDCouplingFieldDouble::reprQuickOverview(std::ostream& stream) const -{ - 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 deleted file mode 100644 index ee9a2506a..000000000 --- a/src/MEDCoupling/MEDCouplingFieldDouble.hxx +++ /dev/null @@ -1,211 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 -// 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_MEDCOUPLINGFIELDDOUBLE_HXX__ -#define __PARAMEDMEM_MEDCOUPLINGFIELDDOUBLE_HXX__ - -#include "MEDCoupling.hxx" -#include "MEDCouplingField.hxx" -#include "MEDCouplingTimeDiscretization.hxx" -#include "MEDCouplingMemArray.hxx" - -namespace ParaMEDMEM -{ - class MEDCouplingFieldTemplate; - - class MEDCouplingFieldDouble : public MEDCouplingField - { - public: - MEDCOUPLING_EXPORT static MEDCouplingFieldDouble *New(TypeOfField type, TypeOfTimeDiscretization td=ONE_TIME); - MEDCOUPLING_EXPORT static MEDCouplingFieldDouble *New(const MEDCouplingFieldTemplate& ft, TypeOfTimeDiscretization td=ONE_TIME); - MEDCOUPLING_EXPORT void setTimeUnit(const std::string& unit); - MEDCOUPLING_EXPORT std::string getTimeUnit() const; - MEDCOUPLING_EXPORT void synchronizeTimeWithSupport(); - MEDCOUPLING_EXPORT void copyTinyStringsFrom(const MEDCouplingField *other); - MEDCOUPLING_EXPORT void copyTinyAttrFrom(const MEDCouplingFieldDouble *other); - MEDCOUPLING_EXPORT void copyAllTinyAttrFrom(const MEDCouplingFieldDouble *other); - MEDCOUPLING_EXPORT std::string simpleRepr() const; - MEDCOUPLING_EXPORT std::string advancedRepr() const; - MEDCOUPLING_EXPORT std::string writeVTK(const std::string& fileName, bool isBinary=true) const; - MEDCOUPLING_EXPORT bool isEqualIfNotWhy(const MEDCouplingField *other, double meshPrec, double valsPrec, std::string& reason) const; - MEDCOUPLING_EXPORT bool isEqualWithoutConsideringStr(const MEDCouplingField *other, double meshPrec, double valsPrec) const; - MEDCOUPLING_EXPORT bool areCompatibleForMerge(const MEDCouplingField *other) const; - MEDCOUPLING_EXPORT bool areStrictlyCompatible(const MEDCouplingField *other) const; - MEDCOUPLING_EXPORT bool areCompatibleForMul(const MEDCouplingField *other) const; - MEDCOUPLING_EXPORT bool areCompatibleForDiv(const MEDCouplingField *other) const; - MEDCOUPLING_EXPORT bool areCompatibleForMeld(const MEDCouplingFieldDouble *other) const; - MEDCOUPLING_EXPORT void renumberCells(const int *old2NewBg, bool check=true); - MEDCOUPLING_EXPORT void renumberCellsWithoutMesh(const int *old2NewBg, bool check=true); - MEDCOUPLING_EXPORT void renumberNodes(const int *old2NewBg, double eps=1e-15); - MEDCOUPLING_EXPORT void renumberNodesWithoutMesh(const int *old2NewBg, int newNbOfNodes, double eps=1e-15); - MEDCOUPLING_EXPORT DataArrayInt *getIdsInRange(double vmin, double vmax) const; - MEDCOUPLING_EXPORT MEDCouplingFieldDouble *buildSubPart(const DataArrayInt *part) const; - MEDCOUPLING_EXPORT MEDCouplingFieldDouble *buildSubPart(const int *partBg, const int *partEnd) const; - MEDCOUPLING_EXPORT MEDCouplingFieldDouble *buildSubPartRange(int begin, int end, int step) const; - MEDCOUPLING_EXPORT MEDCouplingFieldDouble *deepCpy() const; - MEDCOUPLING_EXPORT MEDCouplingFieldDouble *clone(bool recDeepCpy) const; - MEDCOUPLING_EXPORT MEDCouplingFieldDouble *cloneWithMesh(bool recDeepCpy) const; - MEDCOUPLING_EXPORT MEDCouplingFieldDouble *buildNewTimeReprFromThis(TypeOfTimeDiscretization td, bool deepCopy) const; - MEDCOUPLING_EXPORT MEDCouplingFieldDouble *nodeToCellDiscretization() const; - MEDCOUPLING_EXPORT MEDCouplingFieldDouble *cellToNodeDiscretization() const; - MEDCOUPLING_EXPORT TypeOfTimeDiscretization getTimeDiscretization() const; - MEDCOUPLING_EXPORT void checkCoherency() const; - MEDCOUPLING_EXPORT void setNature(NatureOfField nat); - MEDCOUPLING_EXPORT void setTimeTolerance(double val) { _time_discr->setTimeTolerance(val); } - MEDCOUPLING_EXPORT double getTimeTolerance() const { return _time_discr->getTimeTolerance(); } - MEDCOUPLING_EXPORT void setIteration(int it) { _time_discr->setIteration(it); } - MEDCOUPLING_EXPORT void setEndIteration(int it) { _time_discr->setEndIteration(it); } - MEDCOUPLING_EXPORT void setOrder(int order) { _time_discr->setOrder(order); } - MEDCOUPLING_EXPORT void setEndOrder(int order) { _time_discr->setEndOrder(order); } - MEDCOUPLING_EXPORT void setTimeValue(double val) { _time_discr->setTimeValue(val); } - MEDCOUPLING_EXPORT void setEndTimeValue(double val) { _time_discr->setEndTimeValue(val); } - MEDCOUPLING_EXPORT void setTime(double val, int iteration, int order) { _time_discr->setTime(val,iteration,order); } - MEDCOUPLING_EXPORT void synchronizeTimeWithMesh(); - MEDCOUPLING_EXPORT void setStartTime(double val, int iteration, int order) { _time_discr->setStartTime(val,iteration,order); } - MEDCOUPLING_EXPORT void setEndTime(double val, int iteration, int order) { _time_discr->setEndTime(val,iteration,order); } - MEDCOUPLING_EXPORT double getTime(int& iteration, int& order) const { return _time_discr->getTime(iteration,order); } - MEDCOUPLING_EXPORT double getStartTime(int& iteration, int& order) const { return _time_discr->getStartTime(iteration,order); } - MEDCOUPLING_EXPORT double getEndTime(int& iteration, int& order) const { return _time_discr->getEndTime(iteration,order); } - MEDCOUPLING_EXPORT double getIJ(int tupleId, int compoId) const { return getArray()->getIJ(tupleId,compoId); } - MEDCOUPLING_EXPORT double getIJK(int cellId, int nodeIdInCell, int compoId) const; - MEDCOUPLING_EXPORT void setArray(DataArrayDouble *array); - MEDCOUPLING_EXPORT void setEndArray(DataArrayDouble *array); - MEDCOUPLING_EXPORT void setArrays(const std::vector& arrs); - MEDCOUPLING_EXPORT const DataArrayDouble *getArray() const { return _time_discr->getArray(); } - MEDCOUPLING_EXPORT DataArrayDouble *getArray() { return _time_discr->getArray(); } - MEDCOUPLING_EXPORT const DataArrayDouble *getEndArray() const { return _time_discr->getEndArray(); } - MEDCOUPLING_EXPORT DataArrayDouble *getEndArray() { return _time_discr->getEndArray(); } - MEDCOUPLING_EXPORT std::vector getArrays() const { std::vector ret; _time_discr->getArrays(ret); return ret; } - MEDCOUPLING_EXPORT double accumulate(int compId) const; - MEDCOUPLING_EXPORT void accumulate(double *res) const; - MEDCOUPLING_EXPORT double getMaxValue() const; - MEDCOUPLING_EXPORT double getMaxValue2(DataArrayInt*& tupleIds) const; - MEDCOUPLING_EXPORT double getMinValue() const; - MEDCOUPLING_EXPORT double getMinValue2(DataArrayInt*& tupleIds) const; - MEDCOUPLING_EXPORT double getAverageValue() const; - MEDCOUPLING_EXPORT double norm2() const; - MEDCOUPLING_EXPORT double normMax() const; - MEDCOUPLING_EXPORT void getWeightedAverageValue(double *res, bool isWAbs=true) const; - MEDCOUPLING_EXPORT double getWeightedAverageValue(int compId, bool isWAbs=true) const; - MEDCOUPLING_EXPORT double normL1(int compId) const; - MEDCOUPLING_EXPORT void normL1(double *res) const; - MEDCOUPLING_EXPORT double normL2(int compId) const; - MEDCOUPLING_EXPORT void normL2(double *res) const; - MEDCOUPLING_EXPORT double integral(int compId, bool isWAbs) const; - MEDCOUPLING_EXPORT void integral(bool isWAbs, double *res) const; - MEDCOUPLING_EXPORT void getValueOnPos(int i, int j, int k, double *res) const; - MEDCOUPLING_EXPORT void getValueOn(const double *spaceLoc, double *res) const; - MEDCOUPLING_EXPORT void getValueOn(const double *spaceLoc, double time, double *res) const; - MEDCOUPLING_EXPORT DataArrayDouble *getValueOnMulti(const double *spaceLoc, int nbOfPoints) const; - MEDCOUPLING_EXPORT void applyLin(double a, double b, int compoId); - MEDCOUPLING_EXPORT void applyLin(double a, double b); - MEDCOUPLING_EXPORT MEDCouplingFieldDouble &operator=(double value); - MEDCOUPLING_EXPORT void fillFromAnalytic(int nbOfComp, FunctionToEvaluate func); - MEDCOUPLING_EXPORT void fillFromAnalytic(int nbOfComp, const std::string& func); - MEDCOUPLING_EXPORT void fillFromAnalytic2(int nbOfComp, const std::string& func); - MEDCOUPLING_EXPORT void fillFromAnalytic3(int nbOfComp, const std::vector& varsOrder, const std::string& func); - MEDCOUPLING_EXPORT void applyFunc(int nbOfComp, FunctionToEvaluate func); - MEDCOUPLING_EXPORT void applyFunc(int nbOfComp, double val); - MEDCOUPLING_EXPORT void applyFunc(int nbOfComp, const std::string& func); - MEDCOUPLING_EXPORT void applyFunc2(int nbOfComp, const std::string& func); - MEDCOUPLING_EXPORT void applyFunc3(int nbOfComp, const std::vector& varsOrder, const std::string& func); - MEDCOUPLING_EXPORT void applyFunc(const std::string& func); - MEDCOUPLING_EXPORT void applyFuncFast32(const std::string& func); - MEDCOUPLING_EXPORT void applyFuncFast64(const std::string& func); - MEDCOUPLING_EXPORT int getNumberOfComponents() const; - MEDCOUPLING_EXPORT int getNumberOfTuples() const; - MEDCOUPLING_EXPORT int getNumberOfValues() const; - MEDCOUPLING_EXPORT void updateTime() const; - MEDCOUPLING_EXPORT std::size_t getHeapMemorySizeWithoutChildren() const; - MEDCOUPLING_EXPORT std::vector getDirectChildrenWithNull() const; - // - MEDCOUPLING_EXPORT void getTinySerializationIntInformation(std::vector& tinyInfo) const; - MEDCOUPLING_EXPORT void getTinySerializationDbleInformation(std::vector& tinyInfo) const; - MEDCOUPLING_EXPORT void getTinySerializationStrInformation(std::vector& tinyInfo) const; - MEDCOUPLING_EXPORT void resizeForUnserialization(const std::vector& tinyInfoI, DataArrayInt *&dataInt, std::vector& arrays); - MEDCOUPLING_EXPORT void checkForUnserialization(const std::vector& tinyInfoI, const DataArrayInt *dataInt, const std::vector& arrays); - MEDCOUPLING_EXPORT void finishUnserialization(const std::vector& tinyInfoI, const std::vector& tinyInfoD, const std::vector& tinyInfoS); - MEDCOUPLING_EXPORT void serialize(DataArrayInt *&dataInt, std::vector& arrays) const; - // - MEDCOUPLING_EXPORT void changeUnderlyingMesh(const MEDCouplingMesh *other, int levOfCheck, double precOnMesh, double eps=1e-15); - MEDCOUPLING_EXPORT void substractInPlaceDM(const MEDCouplingFieldDouble *f, int levOfCheck, double precOnMesh, double eps=1e-15); - MEDCOUPLING_EXPORT bool mergeNodes(double eps, double epsOnVals=1e-15); - MEDCOUPLING_EXPORT bool mergeNodes2(double eps, double epsOnVals=1e-15); - MEDCOUPLING_EXPORT bool zipCoords(double epsOnVals=1e-15); - MEDCOUPLING_EXPORT bool zipConnectivity(int compType, double epsOnVals=1e-15); - MEDCOUPLING_EXPORT MEDCouplingFieldDouble *extractSlice3D(const double *origin, const double *vec, double eps) const; - MEDCOUPLING_EXPORT bool simplexize(int policy); - MEDCOUPLING_EXPORT MEDCouplingFieldDouble *doublyContractedProduct() const; - MEDCOUPLING_EXPORT MEDCouplingFieldDouble *determinant() const; - MEDCOUPLING_EXPORT MEDCouplingFieldDouble *eigenValues() const; - MEDCOUPLING_EXPORT MEDCouplingFieldDouble *eigenVectors() const; - MEDCOUPLING_EXPORT MEDCouplingFieldDouble *inverse() const; - MEDCOUPLING_EXPORT MEDCouplingFieldDouble *trace() const; - MEDCOUPLING_EXPORT MEDCouplingFieldDouble *deviator() const; - MEDCOUPLING_EXPORT MEDCouplingFieldDouble *magnitude() const; - MEDCOUPLING_EXPORT MEDCouplingFieldDouble *maxPerTuple() const; - MEDCOUPLING_EXPORT void changeNbOfComponents(int newNbOfComp, double dftValue=0.); - MEDCOUPLING_EXPORT MEDCouplingFieldDouble *keepSelectedComponents(const std::vector& compoIds) const; - MEDCOUPLING_EXPORT void setSelectedComponents(const MEDCouplingFieldDouble *f, const std::vector& compoIds); - MEDCOUPLING_EXPORT void sortPerTuple(bool asc); - MEDCOUPLING_EXPORT static MEDCouplingFieldDouble *MergeFields(const MEDCouplingFieldDouble *f1, const MEDCouplingFieldDouble *f2); - MEDCOUPLING_EXPORT static MEDCouplingFieldDouble *MergeFields(const std::vector& a); - MEDCOUPLING_EXPORT static MEDCouplingFieldDouble *MeldFields(const MEDCouplingFieldDouble *f1, const MEDCouplingFieldDouble *f2); - MEDCOUPLING_EXPORT static MEDCouplingFieldDouble *DotFields(const MEDCouplingFieldDouble *f1, const MEDCouplingFieldDouble *f2); - MEDCOUPLING_EXPORT MEDCouplingFieldDouble *dot(const MEDCouplingFieldDouble& other) const { return DotFields(this,&other); } - MEDCOUPLING_EXPORT static MEDCouplingFieldDouble *CrossProductFields(const MEDCouplingFieldDouble *f1, const MEDCouplingFieldDouble *f2); - MEDCOUPLING_EXPORT MEDCouplingFieldDouble *crossProduct(const MEDCouplingFieldDouble& other) const { return CrossProductFields(this,&other); } - MEDCOUPLING_EXPORT static MEDCouplingFieldDouble *MaxFields(const MEDCouplingFieldDouble *f1, const MEDCouplingFieldDouble *f2); - MEDCOUPLING_EXPORT MEDCouplingFieldDouble *max(const MEDCouplingFieldDouble& other) const { return MaxFields(this,&other); } - MEDCOUPLING_EXPORT static MEDCouplingFieldDouble *MinFields(const MEDCouplingFieldDouble *f1, const MEDCouplingFieldDouble *f2); - MEDCOUPLING_EXPORT MEDCouplingFieldDouble *min(const MEDCouplingFieldDouble& other) const { return MinFields(this,&other); } - MEDCOUPLING_EXPORT MEDCouplingFieldDouble *negate() const; - MEDCOUPLING_EXPORT MEDCouplingFieldDouble *operator+(const MEDCouplingFieldDouble& other) const throw(INTERP_KERNEL::Exception) { return AddFields(this,&other); } - MEDCOUPLING_EXPORT const MEDCouplingFieldDouble &operator+=(const MEDCouplingFieldDouble& other); - MEDCOUPLING_EXPORT static MEDCouplingFieldDouble *AddFields(const MEDCouplingFieldDouble *f1, const MEDCouplingFieldDouble *f2); - MEDCOUPLING_EXPORT MEDCouplingFieldDouble *operator-(const MEDCouplingFieldDouble& other) const throw(INTERP_KERNEL::Exception) { return SubstractFields(this,&other); } - MEDCOUPLING_EXPORT const MEDCouplingFieldDouble &operator-=(const MEDCouplingFieldDouble& other); - MEDCOUPLING_EXPORT static MEDCouplingFieldDouble *SubstractFields(const MEDCouplingFieldDouble *f1, const MEDCouplingFieldDouble *f2); - MEDCouplingFieldDouble *operator*(const MEDCouplingFieldDouble& other) const throw(INTERP_KERNEL::Exception) { return MultiplyFields(this,&other); } - MEDCOUPLING_EXPORT const MEDCouplingFieldDouble &operator*=(const MEDCouplingFieldDouble& other); - MEDCOUPLING_EXPORT static MEDCouplingFieldDouble *MultiplyFields(const MEDCouplingFieldDouble *f1, const MEDCouplingFieldDouble *f2); - MEDCOUPLING_EXPORT MEDCouplingFieldDouble *operator/(const MEDCouplingFieldDouble& other) const throw(INTERP_KERNEL::Exception) { return DivideFields(this,&other); } - MEDCOUPLING_EXPORT const MEDCouplingFieldDouble &operator/=(const MEDCouplingFieldDouble& other); - MEDCOUPLING_EXPORT static MEDCouplingFieldDouble *DivideFields(const MEDCouplingFieldDouble *f1, const MEDCouplingFieldDouble *f2); - MEDCOUPLING_EXPORT MEDCouplingFieldDouble *operator^(const MEDCouplingFieldDouble& other) const; - MEDCOUPLING_EXPORT const MEDCouplingFieldDouble &operator^=(const MEDCouplingFieldDouble& other); - MEDCOUPLING_EXPORT static MEDCouplingFieldDouble *PowFields(const MEDCouplingFieldDouble *f1, const MEDCouplingFieldDouble *f2); - MEDCOUPLING_EXPORT static std::string WriteVTK(const std::string& fileName, const std::vector& fs, bool isBinary=true); - public: - MEDCOUPLING_EXPORT const MEDCouplingTimeDiscretization *getTimeDiscretizationUnderGround() const { return _time_discr; } - MEDCOUPLING_EXPORT MEDCouplingTimeDiscretization *getTimeDiscretizationUnderGround() { return _time_discr; } - MEDCOUPLING_EXPORT void reprQuickOverview(std::ostream& stream) const; - private: - MEDCouplingFieldDouble(TypeOfField type, TypeOfTimeDiscretization td); - MEDCouplingFieldDouble(const MEDCouplingFieldTemplate& ft, TypeOfTimeDiscretization td); - MEDCouplingFieldDouble(const MEDCouplingFieldDouble& other, bool deepCopy); - MEDCouplingFieldDouble(NatureOfField n, MEDCouplingTimeDiscretization *td, MEDCouplingFieldDiscretization *type); - ~MEDCouplingFieldDouble(); - private: - MEDCouplingTimeDiscretization *_time_discr; - }; -} - -#endif diff --git a/src/MEDCoupling/MEDCouplingFieldOverTime.cxx b/src/MEDCoupling/MEDCouplingFieldOverTime.cxx deleted file mode 100644 index 20d5f283f..000000000 --- a/src/MEDCoupling/MEDCouplingFieldOverTime.cxx +++ /dev/null @@ -1,165 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 -// 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 "MEDCouplingFieldOverTime.hxx" -#include "MEDCouplingMesh.hxx" - -#include - -using namespace ParaMEDMEM; - -MEDCouplingFieldOverTime *MEDCouplingFieldOverTime::New(const std::vector& fs) -{ - return new MEDCouplingFieldOverTime(fs); -} - -double MEDCouplingFieldOverTime::getTimeTolerance() const -{ - std::vector< MEDCouplingAutoRefCountObjectPtr >::const_iterator it=_fs.begin(); - if(_fs.empty()) - throw INTERP_KERNEL::Exception("MEDCouplingFieldOverTime::getTimeTolerance : empty set !"); - for(;it!=_fs.end();it++) - if((const MEDCouplingFieldDouble *)(*it)!=0) - return (*it)->getTimeTolerance(); - throw INTERP_KERNEL::Exception("MEDCouplingFieldOverTime::getTimeTolerance : only empty fields in this !"); -} - -void MEDCouplingFieldOverTime::checkCoherency() const -{ - MEDCouplingMultiFields::checkCoherency(); - std::vector< MEDCouplingAutoRefCountObjectPtr >::const_iterator it=_fs.begin(); - for(;it!=_fs.end();it++) - if((*it)->getTimeDiscretization()==NO_TIME) - { - std::ostringstream oss; oss << "MEDCouplingFieldOverTime::checkCoherency : At rank #" << std::distance(_fs.begin(),it) << " the field has no time !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - if(_fs.empty()) - return ; - it=_fs.begin(); - const MEDCouplingFieldDouble& ref=*(*(it++)); - int tt1,tt2; - double reft=ref.getEndTime(tt1,tt2); - double eps=getTimeTolerance(); - int id=1; - for(;it!=_fs.end();it++,id++) - { - if(!ref.getMesh()->areCompatibleForMerge((*it)->getMesh())) - { - std::ostringstream oss; oss << "Field slice at rank #" << id << " is not compatible with the first !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - double curt=(*it)->getStartTime(tt1,tt2); - if(curtgetEndTime(tt1,tt2); - } -} - -std::string MEDCouplingFieldOverTime::simpleRepr() const -{ - std::ostringstream ret; - ret << "MEDCouplingFieldOverTime with name : \"" << getName() << "\"\n"; - ret << "Description of MEDCouplingFieldOverTime is : \"" << getDescription() << "\"\n"; - ret << "Number of discretization : " << _fs.size() << "\n"; - ret << "Number of different meshes : "; - std::vector ms; - std::vector refms; - try - { - ms=getDifferentMeshes(refms); - ret << ms.size() << "\n"; - } - catch(INTERP_KERNEL::Exception& /*e*/) - { ret << "Current instance is INVALID !\n"; } - try - { - MEDCouplingDefinitionTime dt=getDefinitionTimeZone(); - dt.appendRepr(ret); - } - catch(INTERP_KERNEL::Exception& /*e*/) - { ret << "Definition zone is INVALID !\n"; } - return ret.str(); -} - -bool MEDCouplingFieldOverTime::isEqual(const MEDCouplingMultiFields *other, double meshPrec, double valsPrec) const -{ - if(!MEDCouplingMultiFields::isEqual(other,meshPrec,valsPrec)) - return false; - const MEDCouplingFieldOverTime *otherC=dynamic_cast(other); - if(!otherC) - return false; - // to implement - return true; -} - -bool MEDCouplingFieldOverTime::isEqualWithoutConsideringStr(const MEDCouplingMultiFields *other, double meshPrec, double valsPrec) const -{ - if(!MEDCouplingMultiFields::isEqualWithoutConsideringStr(other,meshPrec,valsPrec)) - return false; - const MEDCouplingFieldOverTime *otherC=dynamic_cast(other); - if(!otherC) - return false; - // to implement - return true; -} - -std::vector MEDCouplingFieldOverTime::getMeshes() const -{ - checkCoherency(); - return MEDCouplingMultiFields::getMeshes(); -} - -std::vector MEDCouplingFieldOverTime::getDifferentMeshes(std::vector& refs) const -{ - checkCoherency(); - return MEDCouplingMultiFields::getDifferentMeshes(refs); -} - -std::vector MEDCouplingFieldOverTime::getArrays() const -{ - checkCoherency(); - return MEDCouplingMultiFields::getArrays(); -} - -std::vector MEDCouplingFieldOverTime::getDifferentArrays(std::vector< std::vector >& refs) const -{ - checkCoherency(); - return MEDCouplingMultiFields::getDifferentArrays(refs); -} - -MEDCouplingDefinitionTime MEDCouplingFieldOverTime::getDefinitionTimeZone() const -{ - std::vector< std::vector > tmp; - getDifferentArrays(tmp); - std::vector tmp2(_fs.begin(),_fs.end()); - std::vector tmp3; - getDifferentMeshes(tmp3); - return MEDCouplingDefinitionTime(tmp2,tmp3,tmp); -} - -MEDCouplingFieldOverTime::MEDCouplingFieldOverTime(const std::vector& fs):MEDCouplingMultiFields(fs) -{ - checkCoherency(); -} - -MEDCouplingFieldOverTime::MEDCouplingFieldOverTime() -{ -} diff --git a/src/MEDCoupling/MEDCouplingFieldOverTime.hxx b/src/MEDCoupling/MEDCouplingFieldOverTime.hxx deleted file mode 100644 index 4d4351ca7..000000000 --- a/src/MEDCoupling/MEDCouplingFieldOverTime.hxx +++ /dev/null @@ -1,56 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 -// 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_MEDCOUPLINGFIELDOVERTIME_HXX__ -#define __PARAMEDMEM_MEDCOUPLINGFIELDOVERTIME_HXX__ - -#include "MEDCouplingMultiFields.hxx" -#include "MEDCouplingDefinitionTime.hxx" -#include "MEDCouplingFieldDouble.hxx" - -#include - -namespace ParaMEDMEM -{ - class MEDCouplingFieldOverTime : public MEDCouplingMultiFields - { - public: - MEDCOUPLING_EXPORT static MEDCouplingFieldOverTime *New(const std::vector& fs); - MEDCOUPLING_EXPORT void checkCoherency() const; - MEDCOUPLING_EXPORT double getTimeTolerance() const; - MEDCOUPLING_EXPORT std::string simpleRepr() const; - MEDCOUPLING_EXPORT bool isEqual(const MEDCouplingMultiFields *other, double meshPrec, double valsPrec) const; - MEDCOUPLING_EXPORT bool isEqualWithoutConsideringStr(const MEDCouplingMultiFields *other, double meshPrec, double valsPrec) const; - //void getIdsToFetch(double time, int& fieldId, int& arrId, int& meshId) const; - //void setFieldOnId(int fieldId, MEDCouplingFieldDouble *f); - //void dispatchPointers(); - MEDCOUPLING_EXPORT std::vector getMeshes() const; - MEDCOUPLING_EXPORT std::vector getDifferentMeshes(std::vector& refs) const; - MEDCOUPLING_EXPORT std::vector getArrays() const; - MEDCOUPLING_EXPORT std::vector getDifferentArrays(std::vector< std::vector >& refs) const; - MEDCOUPLING_EXPORT MEDCouplingDefinitionTime getDefinitionTimeZone() const; - protected: - MEDCOUPLING_EXPORT MEDCouplingFieldOverTime(); - private: - MEDCouplingFieldOverTime(const std::vector& fs); - }; -} - -#endif diff --git a/src/MEDCoupling/MEDCouplingFieldTemplate.cxx b/src/MEDCoupling/MEDCouplingFieldTemplate.cxx deleted file mode 100644 index 4bb5a3974..000000000 --- a/src/MEDCoupling/MEDCouplingFieldTemplate.cxx +++ /dev/null @@ -1,159 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 -// 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 "MEDCouplingFieldTemplate.hxx" -#include "MEDCouplingMesh.hxx" -#include "MEDCouplingFieldDouble.hxx" -#include "MEDCouplingFieldDiscretization.hxx" - -#include - -using namespace ParaMEDMEM; - -MEDCouplingFieldTemplate *MEDCouplingFieldTemplate::New(const MEDCouplingFieldDouble& f) -{ - return new MEDCouplingFieldTemplate(f); -} - -/*! - * The user should \b not use this method. Only useful for CORBA serialization/unserialization. - */ -MEDCouplingFieldTemplate *MEDCouplingFieldTemplate::New(TypeOfField type) -{ - return new MEDCouplingFieldTemplate(type); -} - -MEDCouplingFieldTemplate::MEDCouplingFieldTemplate(const MEDCouplingFieldDouble& f):MEDCouplingField(f,false) -{ - forceTimeOfThis(f); - checkCoherency(); -} - -MEDCouplingFieldTemplate::MEDCouplingFieldTemplate(TypeOfField type):MEDCouplingField(type) -{ -} - -void MEDCouplingFieldTemplate::checkCoherency() const -{ - if(_mesh==0) - throw INTERP_KERNEL::Exception("MEDCouplingFieldTemplate::checkCoherency : Empty mesh !"); -} - -std::string MEDCouplingFieldTemplate::simpleRepr() const -{ - std::ostringstream ret; - ret << "FieldTemplate with name : \"" << getName() << "\"\n"; - ret << "Description of field is : \"" << getDescription() << "\"\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 - ret << "Mesh support information : No mesh set !\n"; - return ret.str(); -} - -std::string MEDCouplingFieldTemplate::advancedRepr() const -{ - return simpleRepr(); -} - -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); - std::vector tinyInfo2; - _type->getTinySerializationIntInformation(tinyInfo2); - tinyInfo.insert(tinyInfo.end(),tinyInfo2.begin(),tinyInfo2.end()); - tinyInfo.push_back((int)tinyInfo2.size()); -} - -void MEDCouplingFieldTemplate::getTinySerializationDbleInformation(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); -} - -void MEDCouplingFieldTemplate::getTinySerializationStrInformation(std::vector& tinyInfo) const -{ - tinyInfo.clear(); - tinyInfo.push_back(_name); - tinyInfo.push_back(_desc); -} - -void MEDCouplingFieldTemplate::resizeForUnserialization(const 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); -} - -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]; - _desc=tinyInfoS[1]; -} - -void MEDCouplingFieldTemplate::serialize(DataArrayInt *&dataInt) const -{ - _type->getSerializationIntArray(dataInt); -} - -void MEDCouplingFieldTemplate::reprQuickOverview(std::ostream& stream) const -{ - 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 deleted file mode 100644 index 8b3a3c8dd..000000000 --- a/src/MEDCoupling/MEDCouplingFieldTemplate.hxx +++ /dev/null @@ -1,59 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 -// 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_MEDCOUPLINGFIELDTEMPLATE_HXX__ -#define __PARAMEDMEM_MEDCOUPLINGFIELDTEMPLATE_HXX__ - -#include "MEDCouplingField.hxx" - -namespace ParaMEDMEM -{ - class MEDCouplingFieldDouble; - /*! - * \brief A field template can be seen as a field without array of values. - * - * A field template instance aggregates a MEDCouplingMesh instance and a spatial discretization object (instance of MEDCouplingFieldDiscretization). - * - * Instances of type MEDCouplingFieldTemplate are the most appropriate for preparation of matrix using MEDCouplingRemapper::prepareEx. - */ - class MEDCouplingFieldTemplate : public MEDCouplingField - { - public: - MEDCOUPLING_EXPORT static MEDCouplingFieldTemplate *New(const MEDCouplingFieldDouble& f); - MEDCOUPLING_EXPORT static MEDCouplingFieldTemplate *New(TypeOfField type); - MEDCOUPLING_EXPORT std::string simpleRepr() const; - MEDCOUPLING_EXPORT std::string advancedRepr() const; - MEDCOUPLING_EXPORT void checkCoherency() const; - // - MEDCOUPLING_EXPORT void getTinySerializationIntInformation(std::vector& tinyInfo) const; - MEDCOUPLING_EXPORT void getTinySerializationDbleInformation(std::vector& tinyInfo) const; - MEDCOUPLING_EXPORT void getTinySerializationStrInformation(std::vector& tinyInfo) const; - MEDCOUPLING_EXPORT void resizeForUnserialization(const std::vector& tinyInfoI, DataArrayInt *&dataInt); - MEDCOUPLING_EXPORT void finishUnserialization(const std::vector& tinyInfoI, const std::vector& tinyInfoD, const std::vector& tinyInfoS); - MEDCOUPLING_EXPORT void serialize(DataArrayInt *&dataInt) const; - // - MEDCOUPLING_EXPORT void reprQuickOverview(std::ostream& stream) const; - private: - MEDCouplingFieldTemplate(const MEDCouplingFieldDouble& f); - MEDCouplingFieldTemplate(TypeOfField type); - }; -} - -#endif diff --git a/src/MEDCoupling/MEDCouplingGaussLocalization.cxx b/src/MEDCoupling/MEDCouplingGaussLocalization.cxx deleted file mode 100644 index 4af4bd6c3..000000000 --- a/src/MEDCoupling/MEDCouplingGaussLocalization.cxx +++ /dev/null @@ -1,268 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 -// 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 "MEDCouplingGaussLocalization.hxx" -#include "CellModel.hxx" - -#include -#include -#include -#include -#include - -ParaMEDMEM::MEDCouplingGaussLocalization::MEDCouplingGaussLocalization(INTERP_KERNEL::NormalizedCellType type, const std::vector& refCoo, - const std::vector& gsCoo, const std::vector& w) -try:_type(type),_ref_coord(refCoo),_gauss_coord(gsCoo),_weight(w) -{ - checkCoherency(); -} -catch(INTERP_KERNEL::Exception& e) -{ - _type=INTERP_KERNEL::NORM_ERROR; - _ref_coord.clear(); - _gauss_coord.clear(); - _weight.clear(); - throw e; -} - -ParaMEDMEM::MEDCouplingGaussLocalization::MEDCouplingGaussLocalization(INTERP_KERNEL::NormalizedCellType typ) -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) -{ - INTERP_KERNEL::CellModel::GetCellModel(typ);//throws if not found. This is a check - _type=typ; -} - -void ParaMEDMEM::MEDCouplingGaussLocalization::checkCoherency() const -{ - const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(_type); - int nbNodes=cm.getNumberOfNodes(); - int dim=cm.getDimension(); - if(!cm.isDynamic()) - { - if((int)_ref_coord.size()!=nbNodes*dim) - { - std::ostringstream oss; oss << "Invalid size of refCoo : expecting to be : " << nbNodes << " (nbNodePerCell) * " << dim << " (dim) !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - } - if(_gauss_coord.size()!=dim*_weight.size()) - { - std::ostringstream oss; oss << "Invalid gsCoo size and weight size : gsCoo.size() must be equal to _weight.size() * " << dim << " (dim) !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } -} - -int ParaMEDMEM::MEDCouplingGaussLocalization::getDimension() const -{ - if(_weight.empty()) - return -1; - return (int)_gauss_coord.size()/(int)_weight.size(); -} - -int ParaMEDMEM::MEDCouplingGaussLocalization::getNumberOfPtsInRefCell() const -{ - int dim=getDimension(); - if(dim==0) - return -1; - return (int)_ref_coord.size()/dim; -} - -std::string ParaMEDMEM::MEDCouplingGaussLocalization::getStringRepr() const -{ - std::ostringstream oss; - oss << "CellType : " << INTERP_KERNEL::CellModel::GetCellModel(_type).getRepr() << std::endl; - oss << "Ref coords : "; std::copy(_ref_coord.begin(),_ref_coord.end(),std::ostream_iterator(oss,", ")); oss << std::endl; - oss << "Localization coords : "; std::copy(_gauss_coord.begin(),_gauss_coord.end(),std::ostream_iterator(oss,", ")); oss << std::endl; - oss << "Weight : "; std::copy(_weight.begin(),_weight.end(),std::ostream_iterator(oss,", ")); oss << std::endl; - return oss.str(); -} - -std::size_t ParaMEDMEM::MEDCouplingGaussLocalization::getMemorySize() 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) - return false; - if(!AreAlmostEqual(_ref_coord,other._ref_coord,eps)) - return false; - if(!AreAlmostEqual(_gauss_coord,other._gauss_coord,eps)) - return false; - if(!AreAlmostEqual(_weight,other._weight,eps)) - return false; - return true; -} - -double ParaMEDMEM::MEDCouplingGaussLocalization::getRefCoord(int ptIdInCell, int comp) const -{ - const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(_type); - int nbNodes=cm.getNumberOfNodes(); - int dim=cm.getDimension(); - if(ptIdInCell<0 || ptIdInCell>=nbNodes) - throw INTERP_KERNEL::Exception("ptIdInCell specified is invalid : must be in [0;nbNodesPerCell) !"); - if(comp<0 || comp>=dim) - throw INTERP_KERNEL::Exception("comp specified is invalid : must be in [0:dimOfCell) !"); - return _ref_coord[ptIdInCell*dim+comp]; -} - -double ParaMEDMEM::MEDCouplingGaussLocalization::getGaussCoord(int gaussPtIdInCell, int comp) const -{ - int dim=checkCoherencyOfRequest(gaussPtIdInCell,comp); - return _gauss_coord[gaussPtIdInCell*dim+comp]; -} - -double ParaMEDMEM::MEDCouplingGaussLocalization::getWeight(int gaussPtIdInCell, double newVal) const -{ - checkCoherencyOfRequest(gaussPtIdInCell,0); - return _weight[gaussPtIdInCell]; -} - -/*! - * Completely useless method for end user. Only for CORBA MPI serialization/unserialization. - * push at the end of tinyInfo its basic serialization info. The size of pushed data is always the same. - * @param tinyInfo inout parameter. - */ -void ParaMEDMEM::MEDCouplingGaussLocalization::pushTinySerializationIntInfo(std::vector& tinyInfo) const -{ - tinyInfo.push_back((int)_type); - tinyInfo.push_back(getNumberOfPtsInRefCell()); - tinyInfo.push_back(getNumberOfGaussPt()); -} - -/*! - * Completely useless method for end user. Only for CORBA MPI serialization/unserialization. - * push at the end of tinyInfo its basic serialization info. The size of pushed data is \b NOT always the same contrary to pushTinySerializationIntInfo. - * @param tinyInfo inout parameter. - */ -void ParaMEDMEM::MEDCouplingGaussLocalization::pushTinySerializationDblInfo(std::vector& tinyInfo) const -{ - tinyInfo.insert(tinyInfo.end(),_ref_coord.begin(),_ref_coord.end()); - tinyInfo.insert(tinyInfo.end(),_gauss_coord.begin(),_gauss_coord.end()); - tinyInfo.insert(tinyInfo.end(),_weight.begin(),_weight.end()); -} - -/*! - * This method operates the exact inverse operation than ParaMEDMEM::MEDCouplingGaussLocalization::pushTinySerializationDblInfo method. This is one of the last step of unserialization process. - * This method should be called on an object resized by buildNewInstanceFromTinyInfo static method. - * This method takes in argument a pointer 'vals' that point to the begin of double data pushed remotely by pushTinySerializationDblInfo method. - * This method returns the pointer 'vals' with an offset of size what it has been read in this method. - */ -const double *ParaMEDMEM::MEDCouplingGaussLocalization::fillWithValues(const double *vals) -{ - const double *work=vals; - std::copy(work,work+_ref_coord.size(),_ref_coord.begin()); - work+=_ref_coord.size(); - std::copy(work,work+_gauss_coord.size(),_gauss_coord.begin()); - work+=_gauss_coord.size(); - std::copy(work,work+_weight.size(),_weight.begin()); - work+=_weight.size(); - return work; -} - -/*! - * This method sets the comp_th component of ptIdInCell_th point coordinate of reference element of type this->_type. - * @throw if not 0<=ptIdInCell=nbNodes) - throw INTERP_KERNEL::Exception("ptIdInCell specified is invalid : must be in [0;nbNodesPerCell) !"); - if(comp<0 || comp>=dim) - throw INTERP_KERNEL::Exception("comp specified is invalid : must be in [0:dimOfCell) !"); - _ref_coord[ptIdInCell*dim+comp]=newVal; -} - -void ParaMEDMEM::MEDCouplingGaussLocalization::setGaussCoord(int gaussPtIdInCell, int comp, double newVal) -{ - int dim=checkCoherencyOfRequest(gaussPtIdInCell,comp); - _gauss_coord[gaussPtIdInCell*dim+comp]=newVal; -} - -void ParaMEDMEM::MEDCouplingGaussLocalization::setWeight(int gaussPtIdInCell, double newVal) -{ - checkCoherencyOfRequest(gaussPtIdInCell,0); - _weight[gaussPtIdInCell]=newVal; -} - -void ParaMEDMEM::MEDCouplingGaussLocalization::setRefCoords(const std::vector& refCoo) -{ - _ref_coord=refCoo; -} - -void ParaMEDMEM::MEDCouplingGaussLocalization::setGaussCoords(const std::vector& gsCoo) -{ - _gauss_coord=gsCoo; -} - -void ParaMEDMEM::MEDCouplingGaussLocalization::setWeights(const std::vector& w) -{ - _weight=w; -} - -/*! - * The format of 'tinyData' parameter is the same than pushed in method ParaMEDMEM::MEDCouplingGaussLocalization::pushTinySerializationIntInfo. - */ -ParaMEDMEM::MEDCouplingGaussLocalization ParaMEDMEM::MEDCouplingGaussLocalization::BuildNewInstanceFromTinyInfo(int dim, const std::vector& tinyData) -{ - std::vector v1(dim*tinyData[1]),v2(dim*tinyData[2]),v3(tinyData[2]); - return ParaMEDMEM::MEDCouplingGaussLocalization((INTERP_KERNEL::NormalizedCellType)tinyData[0],v1,v2,v3); -} - -int ParaMEDMEM::MEDCouplingGaussLocalization::checkCoherencyOfRequest(int gaussPtIdInCell, int comp) const -{ - const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(_type); - int dim=cm.getDimension(); - int nbGsPts=getNumberOfGaussPt(); - if(gaussPtIdInCell<0 || gaussPtIdInCell>=nbGsPts) - throw INTERP_KERNEL::Exception("gaussPtIdInCell specified is invalid : must be in [0:nbGsPts) !"); - if(comp<0 || comp>=dim) - throw INTERP_KERNEL::Exception("comp specified is invalid : must be in [0:dimOfCell) !"); - return dim; -} - -bool ParaMEDMEM::MEDCouplingGaussLocalization::AreAlmostEqual(const std::vector& v1, const std::vector& v2, double eps) -{ - std::size_t sz=v1.size(); - if(sz!=v2.size()) - return false; - std::vector tmp(sz); - std::transform(v1.begin(),v1.end(),v2.begin(),tmp.begin(),std::minus()); - std::transform(tmp.begin(),tmp.end(),tmp.begin(),std::ptr_fun(fabs)); - return *std::max_element(tmp.begin(),tmp.end()) - -namespace ParaMEDMEM -{ - class MEDCouplingMesh; - - class MEDCouplingGaussLocalization - { - public: - MEDCOUPLING_EXPORT MEDCouplingGaussLocalization(INTERP_KERNEL::NormalizedCellType type, const std::vector& refCoo, - const std::vector& gsCoo, const std::vector& w); - MEDCOUPLING_EXPORT MEDCouplingGaussLocalization(INTERP_KERNEL::NormalizedCellType typ); - MEDCOUPLING_EXPORT INTERP_KERNEL::NormalizedCellType getType() const { return _type; } - MEDCOUPLING_EXPORT void setType(INTERP_KERNEL::NormalizedCellType typ); - MEDCOUPLING_EXPORT int getNumberOfGaussPt() const { return (int)_weight.size(); } - MEDCOUPLING_EXPORT int getDimension() const; - MEDCOUPLING_EXPORT int getNumberOfPtsInRefCell() const; - MEDCOUPLING_EXPORT std::string getStringRepr() const; - MEDCOUPLING_EXPORT std::size_t getMemorySize() const; - MEDCOUPLING_EXPORT void checkCoherency() const; - MEDCOUPLING_EXPORT bool isEqual(const MEDCouplingGaussLocalization& other, double eps) const; - MEDCOUPLING_EXPORT void pushTinySerializationIntInfo(std::vector& tinyInfo) const; - MEDCOUPLING_EXPORT void pushTinySerializationDblInfo(std::vector& tinyInfo) const; - MEDCOUPLING_EXPORT const double *fillWithValues(const double *vals); - // - MEDCOUPLING_EXPORT const std::vector& getRefCoords() const { return _ref_coord; } - MEDCOUPLING_EXPORT double getRefCoord(int ptIdInCell, int comp) const; - MEDCOUPLING_EXPORT const std::vector& getGaussCoords() const { return _gauss_coord; } - MEDCOUPLING_EXPORT double getGaussCoord(int gaussPtIdInCell, int comp) const; - MEDCOUPLING_EXPORT const std::vector& getWeights() const { return _weight; } - MEDCOUPLING_EXPORT double getWeight(int gaussPtIdInCell, double newVal) const; - MEDCOUPLING_EXPORT void setRefCoord(int ptIdInCell, int comp, double newVal); - MEDCOUPLING_EXPORT void setGaussCoord(int gaussPtIdInCell, int comp, double newVal); - MEDCOUPLING_EXPORT void setWeight(int gaussPtIdInCell, double newVal); - MEDCOUPLING_EXPORT void setRefCoords(const std::vector& refCoo); - MEDCOUPLING_EXPORT void setGaussCoords(const std::vector& gsCoo); - MEDCOUPLING_EXPORT void setWeights(const std::vector& w); - // - MEDCOUPLING_EXPORT static MEDCouplingGaussLocalization BuildNewInstanceFromTinyInfo(int dim, const std::vector& tinyData); - MEDCOUPLING_EXPORT static bool AreAlmostEqual(const std::vector& v1, const std::vector& v2, double eps); - private: - int checkCoherencyOfRequest(int gaussPtIdInCell, int comp) const; - private: - INTERP_KERNEL::NormalizedCellType _type; - std::vector _ref_coord; - std::vector _gauss_coord; - std::vector _weight; - }; -} - -#endif diff --git a/src/MEDCoupling/MEDCouplingIMesh.cxx b/src/MEDCoupling/MEDCouplingIMesh.cxx deleted file mode 100644 index e7a4ae0ac..000000000 --- a/src/MEDCoupling/MEDCouplingIMesh.cxx +++ /dev/null @@ -1,1495 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 -// 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 "MEDCouplingIMesh.hxx" -#include "MEDCouplingCMesh.hxx" -#include "MEDCouplingMemArray.hxx" -#include "MEDCouplingFieldDouble.hxx" - -#include -#include -#include -#include - -using namespace ParaMEDMEM; - -MEDCouplingIMesh::MEDCouplingIMesh():_space_dim(-1) -{ - _origin[0]=0.; _origin[1]=0.; _origin[2]=0.; - _dxyz[0]=0.; _dxyz[1]=0.; _dxyz[2]=0.; - _structure[0]=0; _structure[1]=0; _structure[2]=0; -} - -MEDCouplingIMesh::MEDCouplingIMesh(const MEDCouplingIMesh& other, bool deepCopy):MEDCouplingStructuredMesh(other,deepCopy),_space_dim(other._space_dim),_axis_unit(other._axis_unit) -{ - _origin[0]=other._origin[0]; _origin[1]=other._origin[1]; _origin[2]=other._origin[2]; - _dxyz[0]=other._dxyz[0]; _dxyz[1]=other._dxyz[1]; _dxyz[2]=other._dxyz[2]; - _structure[0]=other._structure[0]; _structure[1]=other._structure[1]; _structure[2]=other._structure[2]; -} - -MEDCouplingIMesh::~MEDCouplingIMesh() -{ -} - -MEDCouplingIMesh *MEDCouplingIMesh::New() -{ - return new MEDCouplingIMesh; -} - -MEDCouplingIMesh *MEDCouplingIMesh::New(const std::string& meshName, int spaceDim, const int *nodeStrctStart, const int *nodeStrctStop, - const double *originStart, const double *originStop, const double *dxyzStart, const double *dxyzStop) -{ - MEDCouplingAutoRefCountObjectPtr ret(new MEDCouplingIMesh); - ret->setName(meshName); - ret->setSpaceDimension(spaceDim); - ret->setNodeStruct(nodeStrctStart,nodeStrctStop); - ret->setOrigin(originStart,originStop); - ret->setDXYZ(dxyzStart,dxyzStop); - return ret.retn(); -} - -MEDCouplingMesh *MEDCouplingIMesh::deepCpy() const -{ - return clone(true); -} - -MEDCouplingIMesh *MEDCouplingIMesh::clone(bool recDeepCpy) const -{ - return new MEDCouplingIMesh(*this,recDeepCpy); -} - -/*! - * This method creates a copy of \a this enlarged by \a ghostLev cells on each axis. - * If \a ghostLev equal to 0 this method behaves as MEDCouplingIMesh::clone. - * - * \param [in] ghostLev - the ghost level expected - * \return MEDCouplingIMesh * - a newly alloacted object to be managed by the caller. - * \throw if \a ghostLev < 0. - */ -MEDCouplingIMesh *MEDCouplingIMesh::buildWithGhost(int ghostLev) const -{ - if(ghostLev<0) - throw INTERP_KERNEL::Exception("MEDCouplingIMesh::buildWithGhost : the ghostLev must be >= 0 !"); - checkCoherency(); - int spaceDim(getSpaceDimension()); - double origin[3],dxyz[3]; - int structure[3]; - for(int i=0;i ret(MEDCouplingIMesh::New(getName(),spaceDim,structure,structure+spaceDim,origin,origin+spaceDim,dxyz,dxyz+spaceDim)); - ret->copyTinyInfoFrom(this); - return ret.retn(); -} - -void MEDCouplingIMesh::setNodeStruct(const int *nodeStrctStart, const int *nodeStrctStop) -{ - checkSpaceDimension(); - int sz((int)std::distance(nodeStrctStart,nodeStrctStop)); - if(sz!=_space_dim) - throw INTERP_KERNEL::Exception("MEDCouplingIMesh::setNodeStruct : input vector of node structure has not the right size ! Or change space dimension before calling it !"); - std::copy(nodeStrctStart,nodeStrctStop,_structure); - declareAsNew(); -} - -std::vector MEDCouplingIMesh::getNodeStruct() const -{ - checkSpaceDimension(); - return std::vector(_structure,_structure+_space_dim); -} - -void MEDCouplingIMesh::setOrigin(const double *originStart, const double *originStop) -{ - checkSpaceDimension(); - int sz((int)std::distance(originStart,originStop)); - if(sz!=_space_dim) - throw INTERP_KERNEL::Exception("MEDCouplingIMesh::setOrigin : input vector of origin vector has not the right size ! Or change space dimension before calling it !"); - std::copy(originStart,originStop,_origin); - declareAsNew(); -} - -std::vector MEDCouplingIMesh::getOrigin() const -{ - checkSpaceDimension(); - return std::vector(_origin,_origin+_space_dim); -} - -void MEDCouplingIMesh::setDXYZ(const double *dxyzStart, const double *dxyzStop) -{ - checkSpaceDimension(); - int sz((int)std::distance(dxyzStart,dxyzStop)); - if(sz!=_space_dim) - throw INTERP_KERNEL::Exception("MEDCouplingIMesh::setDXYZ : input vector of dxyz vector has not the right size ! Or change space dimension before calling it !"); - std::copy(dxyzStart,dxyzStop,_dxyz); - declareAsNew(); -} - -std::vector MEDCouplingIMesh::getDXYZ() const -{ - checkSpaceDimension(); - return std::vector(_dxyz,_dxyz+_space_dim); -} - -void MEDCouplingIMesh::setAxisUnit(const std::string& unitName) -{ - _axis_unit=unitName; - declareAsNew(); -} - -std::string MEDCouplingIMesh::getAxisUnit() const -{ - return _axis_unit; -} - -/*! - * This method returns the measure of any cell in \a this. - * This specific method of image grid mesh utilizes the fact that any cell in \a this have the same measure. - * The value returned by this method is those used to feed the returned field in the MEDCouplingIMesh::getMeasureField. - * - * \sa getMeasureField - */ -double MEDCouplingIMesh::getMeasureOfAnyCell() const -{ - checkCoherency(); - int dim(getSpaceDimension()); - double ret(1.); - for(int i=0;i ret(MEDCouplingCMesh::New()); - try - { ret->copyTinyInfoFrom(this); } - catch(INTERP_KERNEL::Exception& ) { } - int spaceDim(getSpaceDimension()); - std::vector infos(buildInfoOnComponents()); - for(int i=0;i arr(DataArrayDouble::New()); arr->alloc(_structure[i],1); arr->setInfoOnComponent(0,infos[i]); - arr->iota(); arr->applyLin(_dxyz[i],_origin[i]); - ret->setCoordsAt(i,arr); - } - return ret.retn(); -} - -/*! - * This method refines \a this uniformaly along all of its dimensions. In case of success the space covered by \a this will remain - * the same before the invocation except that the number of cells will be multiplied by \a factor ^ this->getMeshDimension(). - * The origin of \a this will be not touched only spacing and node structure will be changed. - * This method can be useful for AMR users. - */ -void MEDCouplingIMesh::refineWithFactor(const std::vector& factors) -{ - if((int)factors.size()!=_space_dim) - throw INTERP_KERNEL::Exception("MEDCouplingIMesh::refineWithFactor : refinement factors must have size equal to spaceDim !"); - checkCoherency(); - std::vector structure(_structure,_structure+3); - std::vector dxyz(_dxyz,_dxyz+3); - for(int i=0;i<_space_dim;i++) - { - if(factors[i]<=0) - { - std::ostringstream oss; oss << "MEDCouplingIMesh::refineWithFactor : factor for axis #" << i << " (" << factors[i] << ")is invalid ! Must be > 0 !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - int factAbs(std::abs(factors[i])); - double fact2(1./(double)factors[i]); - structure[i]=(_structure[i]-1)*factAbs+1; - dxyz[i]=fact2*_dxyz[i]; - } - std::copy(structure.begin(),structure.end(),_structure); - std::copy(dxyz.begin(),dxyz.end(),_dxyz); - declareAsNew(); -} - -/*! - * This method returns a newly created mesh containing a single cell in it. This returned cell covers exactly the space covered by \a this. - * - * \return MEDCouplingIMesh * - A newly created object (to be managed by the caller with decrRef) containing simply one cell. - * - * \throw if \a this does not pass the \c checkCoherency test. - */ -MEDCouplingIMesh *MEDCouplingIMesh::asSingleCell() const -{ - checkCoherency(); - int spaceDim(getSpaceDimension()),nodeSt[3]; - double dxyz[3]; - for(int i=0;i=2) - { - nodeSt[i]=2; - dxyz[i]=(_structure[i]-1)*_dxyz[i]; - } - else - { - nodeSt[i]=_structure[i]; - dxyz[i]=_dxyz[i]; - } - } - MEDCouplingAutoRefCountObjectPtr ret(MEDCouplingIMesh::New(getName(),getSpaceDimension(),nodeSt,nodeSt+spaceDim,_origin,_origin+spaceDim,dxyz,dxyz+spaceDim)); - ret->copyTinyInfoFrom(this); - return ret.retn(); -} - -/*! - * This static method is useful to condense field on cells of a MEDCouplingIMesh instance coming from a refinement ( MEDCouplingIMesh::refineWithFactor for example) - * to a coarse MEDCouplingIMesh instance. So this method can be seen as a specialization in P0P0 conservative interpolation non overlaping from fine image mesh - * to a coarse image mesh. Only tuples ( deduced from \a fineLocInCoarse ) of \a coarseDA will be modified. Other tuples of \a coarseDA will be let unchanged. - * - * \param [in] coarseSt The cell structure of coarse mesh. - * \param [in] fineDA The DataArray containing the cell field on uniformly refined mesh - * \param [in] fineLocInCoarse The cell localization of refined mesh into the coarse one. - * \param [in] facts The refinement coefficient per axis. - * \param [in,out] coarseDA The DataArrayDouble corresponding to the a cell field of a coarse mesh whose cell structure is defined by \a coarseSt. - * - * \sa CondenseFineToCoarseGhost,SpreadCoarseToFine - */ -void MEDCouplingIMesh::CondenseFineToCoarse(const std::vector& coarseSt, const DataArrayDouble *fineDA, const std::vector< std::pair >& fineLocInCoarse, const std::vector& facts, DataArrayDouble *coarseDA) -{ - if(coarseSt.size()!=fineLocInCoarse.size() || coarseSt.size()!=facts.size()) - throw INTERP_KERNEL::Exception("MEDCouplingIMesh::CondenseFineToCoarse : All input vectors (dimension) must have the same size !"); - if(!coarseDA || !coarseDA->isAllocated() || !fineDA || !fineDA->isAllocated()) - throw INTERP_KERNEL::Exception("MEDCouplingIMesh::CondenseFineToCoarse : the parameters 1 or 3 are NULL or not allocated !"); - int meshDim((int)coarseSt.size()),nbOfTuplesInCoarseExp(MEDCouplingStructuredMesh::DeduceNumberOfGivenStructure(coarseSt)),nbOfTuplesInFineExp(MEDCouplingStructuredMesh::DeduceNumberOfGivenRangeInCompactFrmt(fineLocInCoarse)); - int nbCompo(fineDA->getNumberOfComponents()); - if(coarseDA->getNumberOfComponents()!=nbCompo) - throw INTERP_KERNEL::Exception("MEDCouplingIMesh::CondenseFineToCoarse : the number of components of fine DA and coarse one mismatches !"); - if(meshDim!=(int)fineLocInCoarse.size() || meshDim!=(int)facts.size()) - throw INTERP_KERNEL::Exception("MEDCouplingIMesh::CondenseFineToCoarse : the size of fineLocInCoarse (4th param) and facts (5th param) must be equal to the sier of coarseSt (2nd param) !"); - if(coarseDA->getNumberOfTuples()!=nbOfTuplesInCoarseExp) - { - std::ostringstream oss; oss << "MEDCouplingIMesh::CondenseFineToCoarse : Expecting " << nbOfTuplesInCoarseExp << " tuples having " << coarseDA->getNumberOfTuples() << " !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - int nbTuplesFine(fineDA->getNumberOfTuples()); - if(nbOfTuplesInFineExp==0) - { - if(nbTuplesFine==0) - return ; - else - throw INTERP_KERNEL::Exception("MEDCouplingIMesh::CondenseFineToCoarse : Nothing to condense considering the range specified ! But DataArray is not empty !"); - } - if(nbTuplesFine%nbOfTuplesInFineExp!=0) - throw INTERP_KERNEL::Exception("MEDCouplingIMesh::CondenseFineToCoarse : Invalid nb of tuples in fine DataArray regarding its structure !"); - int fact(std::accumulate(facts.begin(),facts.end(),1,std::multiplies())); - if(nbTuplesFine!=fact*nbOfTuplesInFineExp) - { - std::ostringstream oss; oss << "MEDCouplingIMesh::CondenseFineToCoarse : Invalid number of tuples (" << nbTuplesFine << ") of fine dataarray is invalid ! Must be " << fact*nbOfTuplesInFineExp << "!"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - // to improve use jump-iterator. Factorizes with SwitchOnIdsFrom BuildExplicitIdsFrom - double *outPtr(coarseDA->getPointer()); - const double *inPtr(fineDA->begin()); - // - std::vector dims(MEDCouplingStructuredMesh::GetDimensionsFromCompactFrmt(fineLocInCoarse)); - switch(meshDim) - { - case 1: - { - int offset(fineLocInCoarse[0].first),fact0(facts[0]); - for(int i=0;i()); - else - std::copy(inPtr,inPtr+nbCompo,loc); - } - } - break; - } - case 2: - { - int kk(fineLocInCoarse[0].first+coarseSt[0]*fineLocInCoarse[1].first),fact1(facts[1]),fact0(facts[0]); - for(int j=0;j()); - else - std::copy(inPtr,inPtr+nbCompo,loc); - } - } - } - kk+=coarseSt[0]; - } - break; - } - case 3: - { - int kk(fineLocInCoarse[0].first+coarseSt[0]*fineLocInCoarse[1].first+coarseSt[0]*coarseSt[1]*fineLocInCoarse[2].first),fact2(facts[2]),fact1(facts[1]),fact0(facts[0]); - for(int k=0;k()); - else - std::copy(inPtr,inPtr+nbCompo,loc); - } - } - } - } - } - kk+=coarseSt[0]*coarseSt[1]; - } - break; - } - default: - throw INTERP_KERNEL::Exception("MEDCouplingIMesh::CondenseFineToCoarse : only dimensions 1, 2 and 3 supported !"); - } -} - -/*! - * This static method is useful to condense field on cells of a MEDCouplingIMesh instance coming from a refinement ( MEDCouplingIMesh::refineWithFactor for example) - * to a coarse MEDCouplingIMesh instance. So this method can be seen as a specialization in P0P0 conservative interpolation non overlaping from fine image mesh - * to a coarse image mesh. Only tuples ( deduced from \a fineLocInCoarse ) of \a coarseDA will be modified. Other tuples of \a coarseDA will be let unchanged. - * - * \param [in] coarseSt The cell structure of coarse mesh. - * \param [in] fineDA The DataArray containing the cell field on uniformly refined mesh - * \param [in] fineLocInCoarse The cell localization of refined mesh into the coarse one. - * \param [in] facts The refinement coefficient per axis. - * \param [in,out] coarseDA The DataArrayDouble corresponding to the a cell field of a coarse mesh whose cell structure is defined by \a coarseSt. - * \param [in] ghostSize - The size of the ghost zone. The ghost zone is expected to be the same for all axis and both for coarse and fine meshes. - * - * \sa CondenseFineToCoarse,SpreadCoarseToFineGhost - */ -void MEDCouplingIMesh::CondenseFineToCoarseGhost(const std::vector& coarseSt, const DataArrayDouble *fineDA, const std::vector< std::pair >& fineLocInCoarse, const std::vector& facts, DataArrayDouble *coarseDA, int ghostSize) -{ - if(ghostSize<0) - throw INTERP_KERNEL::Exception("MEDCouplingIMesh::CondenseFineToCoarseGhost : ghost level has to be >= 0 !"); - if(coarseSt.size()!=fineLocInCoarse.size() || coarseSt.size()!=facts.size()) - throw INTERP_KERNEL::Exception("MEDCouplingIMesh::CondenseFineToCoarseGhost : All input vectors (dimension) must have the same size !"); - if(!coarseDA || !coarseDA->isAllocated() || !fineDA || !fineDA->isAllocated()) - throw INTERP_KERNEL::Exception("MEDCouplingIMesh::CondenseFineToCoarseGhost : the parameters 1 or 3 are NULL or not allocated !"); - std::vector coarseStG(coarseSt.size()); std::transform(coarseSt.begin(),coarseSt.end(),coarseStG.begin(),std::bind2nd(std::plus(),2*ghostSize)); - int meshDim((int)coarseSt.size()),nbOfTuplesInCoarseExp(MEDCouplingStructuredMesh::DeduceNumberOfGivenStructure(coarseStG)); - int nbCompo(fineDA->getNumberOfComponents()); - if(coarseDA->getNumberOfComponents()!=nbCompo) - throw INTERP_KERNEL::Exception("MEDCouplingIMesh::CondenseFineToCoarseGhost : the number of components of fine DA and coarse one mismatches !"); - if(meshDim!=(int)fineLocInCoarse.size() || meshDim!=(int)facts.size()) - throw INTERP_KERNEL::Exception("MEDCouplingIMesh::CondenseFineToCoarseGhost : the size of fineLocInCoarse (4th param) and facts (5th param) must be equal to the sier of coarseSt (2nd param) !"); - if(coarseDA->getNumberOfTuples()!=nbOfTuplesInCoarseExp) - { - std::ostringstream oss; oss << "MEDCouplingIMesh::CondenseFineToCoarseGhost : Expecting " << nbOfTuplesInCoarseExp << " tuples in coarse DataArray having " << coarseDA->getNumberOfTuples() << " !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - // - std::vector fineStG(MEDCouplingStructuredMesh::GetDimensionsFromCompactFrmt(fineLocInCoarse)); - std::transform(fineStG.begin(),fineStG.end(),facts.begin(),fineStG.begin(),std::multiplies()); - std::transform(fineStG.begin(),fineStG.end(),fineStG.begin(),std::bind2nd(std::plus(),2*ghostSize)); - int nbTuplesFine(fineDA->getNumberOfTuples()),nbTuplesFineExp(MEDCouplingStructuredMesh::DeduceNumberOfGivenStructure(fineStG)); - if(fineDA->getNumberOfTuples()!=nbTuplesFineExp) - { - std::ostringstream oss; oss << "MEDCouplingIMesh::CondenseFineToCoarseGhost : Expecting " << nbTuplesFineExp << " tuples in fine DataArray having " << nbTuplesFine << " !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - // - double *outPtr(coarseDA->getPointer()); - const double *inPtr(fineDA->begin()); - // - std::vector dims(MEDCouplingStructuredMesh::GetDimensionsFromCompactFrmt(fineLocInCoarse)); - switch(meshDim) - { - case 1: - { - int offset(fineLocInCoarse[0].first+ghostSize),fact0(facts[0]); - inPtr+=ghostSize*nbCompo; - for(int i=0;i()); - else - std::copy(inPtr,inPtr+nbCompo,loc); - } - } - break; - } - case 2: - { - int nxwg(coarseSt[0]+2*ghostSize); - int kk(fineLocInCoarse[0].first+ghostSize+nxwg*(fineLocInCoarse[1].first+ghostSize)),fact1(facts[1]),fact0(facts[0]); - inPtr+=(dims[0]*fact0+2*ghostSize)*ghostSize*nbCompo; - for(int j=0;j()); - else - std::copy(inPtr,inPtr+nbCompo,loc); - } - } - inPtr+=ghostSize*nbCompo; - } - kk+=nxwg; - } - break; - } - case 3: - { - int nxwg(coarseSt[0]+2*ghostSize),nxywg((coarseSt[0]+2*ghostSize)*(coarseSt[1]+2*ghostSize)); - int kk(fineLocInCoarse[0].first+ghostSize+nxwg*(fineLocInCoarse[1].first+ghostSize)+nxywg*(fineLocInCoarse[2].first+ghostSize)),fact2(facts[2]),fact1(facts[1]),fact0(facts[0]); - inPtr+=(dims[0]*fact0+2*ghostSize)*(dims[1]*fact1+2*ghostSize)*ghostSize*nbCompo; - for(int k=0;k()); - else - std::copy(inPtr,inPtr+nbCompo,loc); - } - } - inPtr+=ghostSize*nbCompo; - } - } - inPtr+=ghostSize*(dims[0]*fact0+2*ghostSize)*nbCompo; - } - kk+=nxywg; - } - break; - } - default: - throw INTERP_KERNEL::Exception("MEDCouplingIMesh::CondenseFineToCoarseGhost : only dimensions 1, 2, 3 supported !"); - } -} - -/*! - * This method spreads the values of coarse data \a coarseDA into \a fineDA. - * - * \param [in] coarseDA The DataArrayDouble corresponding to the a cell field of a coarse mesh whose cell structure is defined by \a coarseSt. - * \param [in] coarseSt The cell structure of coarse mesh. - * \param [in,out] fineDA The DataArray containing the cell field on uniformly refined mesh - * \param [in] fineLocInCoarse The cell localization of refined mesh into the coarse one. - * \param [in] facts The refinement coefficient per axis. - * \sa SpreadCoarseToFineGhost, CondenseFineToCoarse - */ -void MEDCouplingIMesh::SpreadCoarseToFine(const DataArrayDouble *coarseDA, const std::vector& coarseSt, DataArrayDouble *fineDA, const std::vector< std::pair >& fineLocInCoarse, const std::vector& facts) -{ - if(coarseSt.size()!=fineLocInCoarse.size() || coarseSt.size()!=facts.size()) - throw INTERP_KERNEL::Exception("MEDCouplingIMesh::SpreadCoarseToFine : All input vectors (dimension) must have the same size !"); - if(!coarseDA || !coarseDA->isAllocated() || !fineDA || !fineDA->isAllocated()) - throw INTERP_KERNEL::Exception("MEDCouplingIMesh::SpreadCoarseToFine : the parameters 1 or 3 are NULL or not allocated !"); - int meshDim((int)coarseSt.size()),nbOfTuplesInCoarseExp(MEDCouplingStructuredMesh::DeduceNumberOfGivenStructure(coarseSt)),nbOfTuplesInFineExp(MEDCouplingStructuredMesh::DeduceNumberOfGivenRangeInCompactFrmt(fineLocInCoarse)); - int nbCompo(fineDA->getNumberOfComponents()); - if(coarseDA->getNumberOfComponents()!=nbCompo) - throw INTERP_KERNEL::Exception("MEDCouplingIMesh::SpreadCoarseToFine : the number of components of fine DA and coarse one mismatches !"); - if(meshDim!=(int)fineLocInCoarse.size() || meshDim!=(int)facts.size()) - throw INTERP_KERNEL::Exception("MEDCouplingIMesh::SpreadCoarseToFine : the size of fineLocInCoarse (4th param) and facts (5th param) must be equal to the sier of coarseSt (2nd param) !"); - if(coarseDA->getNumberOfTuples()!=nbOfTuplesInCoarseExp) - { - std::ostringstream oss; oss << "MEDCouplingIMesh::SpreadCoarseToFine : Expecting " << nbOfTuplesInCoarseExp << " tuples having " << coarseDA->getNumberOfTuples() << " !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - int nbTuplesFine(fineDA->getNumberOfTuples()); - if(nbTuplesFine%nbOfTuplesInFineExp!=0) - throw INTERP_KERNEL::Exception("MEDCouplingIMesh::SpreadCoarseToFine : Invalid nb of tuples in fine DataArray regarding its structure !"); - int fact(std::accumulate(facts.begin(),facts.end(),1,std::multiplies())); - if(nbTuplesFine!=fact*nbOfTuplesInFineExp) - { - std::ostringstream oss; oss << "MEDCouplingIMesh::SpreadCoarseToFine : Invalid number of tuples (" << nbTuplesFine << ") of fine dataarray is invalid ! Must be " << fact*nbOfTuplesInFineExp << "!"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - // to improve use jump-iterator. Factorizes with SwitchOnIdsFrom BuildExplicitIdsFrom - double *outPtr(fineDA->getPointer()); - const double *inPtr(coarseDA->begin()); - // - std::vector dims(MEDCouplingStructuredMesh::GetDimensionsFromCompactFrmt(fineLocInCoarse)); - switch(meshDim) - { - case 1: - { - int offset(fineLocInCoarse[0].first),fact0(facts[0]); - for(int i=0;i& coarseSt, DataArrayDouble *fineDA, const std::vector< std::pair >& fineLocInCoarse, const std::vector& facts, int ghostSize) -{ - if(ghostSize<0) - throw INTERP_KERNEL::Exception("MEDCouplingIMesh::SpreadCoarseToFineGhost : ghost level has to be >= 0 !"); - if(coarseSt.size()!=fineLocInCoarse.size() || coarseSt.size()!=facts.size()) - throw INTERP_KERNEL::Exception("MEDCouplingIMesh::SpreadCoarseToFineGhost : All input vectors (dimension) must have the same size !"); - if(!coarseDA || !coarseDA->isAllocated() || !fineDA || !fineDA->isAllocated()) - throw INTERP_KERNEL::Exception("MEDCouplingIMesh::SpreadCoarseToFineGhost : the parameters 1 or 3 are NULL or not allocated !"); - std::vector coarseStG(coarseSt.size()); std::transform(coarseSt.begin(),coarseSt.end(),coarseStG.begin(),std::bind2nd(std::plus(),2*ghostSize)); - int meshDim((int)coarseSt.size()),nbOfTuplesInCoarseExp(MEDCouplingStructuredMesh::DeduceNumberOfGivenStructure(coarseStG)); - int nbCompo(fineDA->getNumberOfComponents()); - if(coarseDA->getNumberOfComponents()!=nbCompo) - throw INTERP_KERNEL::Exception("MEDCouplingIMesh::SpreadCoarseToFineGhost : the number of components of fine DA and coarse one mismatches !"); - if(meshDim!=(int)fineLocInCoarse.size() || meshDim!=(int)facts.size()) - throw INTERP_KERNEL::Exception("MEDCouplingIMesh::SpreadCoarseToFineGhost : the size of fineLocInCoarse (4th param) and facts (5th param) must be equal to the sier of coarseSt (2nd param) !"); - if(coarseDA->getNumberOfTuples()!=nbOfTuplesInCoarseExp) - { - std::ostringstream oss; oss << "MEDCouplingIMesh::SpreadCoarseToFineGhost : Expecting " << nbOfTuplesInCoarseExp << " tuples having " << coarseDA->getNumberOfTuples() << " !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - // - std::vector fineStG(MEDCouplingStructuredMesh::GetDimensionsFromCompactFrmt(fineLocInCoarse)); - std::transform(fineStG.begin(),fineStG.end(),facts.begin(),fineStG.begin(),std::multiplies()); - std::transform(fineStG.begin(),fineStG.end(),fineStG.begin(),std::bind2nd(std::plus(),2*ghostSize)); - int nbTuplesFine(fineDA->getNumberOfTuples()),nbTuplesFineExp(MEDCouplingStructuredMesh::DeduceNumberOfGivenStructure(fineStG)); - if(fineDA->getNumberOfTuples()!=nbTuplesFineExp) - { - std::ostringstream oss; oss << "MEDCouplingIMesh::SpreadCoarseToFineGhost : Expecting " << nbTuplesFineExp << " tuples in fine DataArray having " << nbTuplesFine << " !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - // - double *outPtr(fineDA->getPointer()); - const double *inPtr(coarseDA->begin()); - // - switch(meshDim) - { - case 1: - { - std::vector dims(MEDCouplingStructuredMesh::GetDimensionsFromCompactFrmt(fineLocInCoarse)); - int offset(fineLocInCoarse[0].first+ghostSize-1),fact0(facts[0]);//offset is always >=0 thanks to the fact that ghostSize>=1 ! - for(int i=0;i dims(MEDCouplingStructuredMesh::GetDimensionsFromCompactFrmt(fineLocInCoarse)); - int fact0(facts[0]),fact1(facts[1]),fact2(facts[2]); - int nxyWgCoarse((coarseSt[0]+2*ghostSize)*(coarseSt[1]+2*ghostSize)),nxyWgFine((dims[0]*fact0+2*ghostSize)*(dims[1]*fact1+2*ghostSize)); - int offset((fineLocInCoarse[2].first+ghostSize-1)*nxyWgCoarse);//offset is always >=0 thanks to the fact that ghostSize>=1 ! - for(int i=0;i& coarseSt, DataArrayDouble *fineDA, const std::vector< std::pair >& fineLocInCoarse, const std::vector& facts, int ghostSize) -{ - if(ghostSize<0) - throw INTERP_KERNEL::Exception("MEDCouplingIMesh::SpreadCoarseToFineGhostZone : ghost level has to be >= 0 !"); - if(coarseSt.size()!=fineLocInCoarse.size() || coarseSt.size()!=facts.size()) - throw INTERP_KERNEL::Exception("MEDCouplingIMesh::SpreadCoarseToFineGhostZone : All input vectors (dimension) must have the same size !"); - if(!coarseDA || !coarseDA->isAllocated() || !fineDA || !fineDA->isAllocated()) - throw INTERP_KERNEL::Exception("MEDCouplingIMesh::SpreadCoarseToFineGhostZone : the parameters 1 or 3 are NULL or not allocated !"); - std::vector coarseStG(coarseSt.size()); std::transform(coarseSt.begin(),coarseSt.end(),coarseStG.begin(),std::bind2nd(std::plus(),2*ghostSize)); - int meshDim((int)coarseSt.size()),nbOfTuplesInCoarseExp(MEDCouplingStructuredMesh::DeduceNumberOfGivenStructure(coarseStG)); - int nbCompo(fineDA->getNumberOfComponents()); - if(coarseDA->getNumberOfComponents()!=nbCompo) - throw INTERP_KERNEL::Exception("MEDCouplingIMesh::SpreadCoarseToFineGhostZone : the number of components of fine DA and coarse one mismatches !"); - if(meshDim!=(int)fineLocInCoarse.size() || meshDim!=(int)facts.size()) - throw INTERP_KERNEL::Exception("MEDCouplingIMesh::SpreadCoarseToFineGhostZone : the size of fineLocInCoarse (4th param) and facts (5th param) must be equal to the sier of coarseSt (2nd param) !"); - if(coarseDA->getNumberOfTuples()!=nbOfTuplesInCoarseExp) - { - std::ostringstream oss; oss << "MEDCouplingIMesh::SpreadCoarseToFineGhostZone : Expecting " << nbOfTuplesInCoarseExp << " tuples having " << coarseDA->getNumberOfTuples() << " !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - // - std::vector fineStG(MEDCouplingStructuredMesh::GetDimensionsFromCompactFrmt(fineLocInCoarse)); - std::transform(fineStG.begin(),fineStG.end(),facts.begin(),fineStG.begin(),std::multiplies()); - std::transform(fineStG.begin(),fineStG.end(),fineStG.begin(),std::bind2nd(std::plus(),2*ghostSize)); - int nbTuplesFine(fineDA->getNumberOfTuples()),nbTuplesFineExp(MEDCouplingStructuredMesh::DeduceNumberOfGivenStructure(fineStG)); - if(fineDA->getNumberOfTuples()!=nbTuplesFineExp) - { - std::ostringstream oss; oss << "MEDCouplingIMesh::SpreadCoarseToFineGhostZone : Expecting " << nbTuplesFineExp << " tuples in fine DataArray having " << nbTuplesFine << " !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - // - double *outPtr(fineDA->getPointer()); - const double *inPtr(coarseDA->begin()); - // - std::vector dims(MEDCouplingStructuredMesh::GetDimensionsFromCompactFrmt(fineLocInCoarse)); - switch(meshDim) - { - case 1: - { - int offset(fineLocInCoarse[0].first+ghostSize-1),fact0(facts[0]);//offset is always >=0 thanks to the fact that ghostSize>=1 ! - for(int i=0;i=0 thanks to the fact that ghostSize>=1 ! - for(int i=0;i MEDCouplingIMesh::getDirectChildrenWithNull() const -{ - return std::vector(); -} - -/*! - * This method copyies all tiny strings from other (name and components name). - * @throw if other and this have not same mesh type. - */ -void MEDCouplingIMesh::copyTinyStringsFrom(const MEDCouplingMesh *other) -{ - const MEDCouplingIMesh *otherC=dynamic_cast(other); - if(!otherC) - throw INTERP_KERNEL::Exception("MEDCouplingIMesh::copyTinyStringsFrom : meshes have not same type !"); - MEDCouplingStructuredMesh::copyTinyStringsFrom(other); - declareAsNew(); -} - -bool MEDCouplingIMesh::isEqualIfNotWhy(const MEDCouplingMesh *other, double prec, std::string& reason) const -{ - if(!other) - throw INTERP_KERNEL::Exception("MEDCouplingIMesh::isEqualIfNotWhy : input other pointer is null !"); - const MEDCouplingIMesh *otherC(dynamic_cast(other)); - if(!otherC) - { - reason="mesh given in input is not castable in MEDCouplingIMesh !"; - return false; - } - if(!MEDCouplingStructuredMesh::isEqualIfNotWhy(other,prec,reason)) - return false; - if(!isEqualWithoutConsideringStrInternal(otherC,prec,reason)) - return false; - if(_axis_unit!=otherC->_axis_unit) - { - reason="The units of axis are not the same !"; - return false; - } - return true; -} - -bool MEDCouplingIMesh::isEqualWithoutConsideringStr(const MEDCouplingMesh *other, double prec) const -{ - const MEDCouplingIMesh *otherC=dynamic_cast(other); - if(!otherC) - return false; - std::string tmp; - return isEqualWithoutConsideringStrInternal(other,prec,tmp); -} - -bool MEDCouplingIMesh::isEqualWithoutConsideringStrInternal(const MEDCouplingMesh *other, double prec, std::string& reason) const -{ - const MEDCouplingIMesh *otherC=dynamic_cast(other); - if(!otherC) - return false; - if(_space_dim!=otherC->_space_dim) - { - std::ostringstream oss; - oss << "The spaceDimension of this (" << _space_dim << ") is not equal to those of other (" << otherC->_space_dim << ") !"; - return false; - } - checkSpaceDimension(); - for(int i=0;i<_space_dim;i++) - { - if(fabs(_origin[i]-otherC->_origin[i])>prec) - { - std::ostringstream oss; - oss << "The origin of this and other differs at " << i << " !"; - reason=oss.str(); - return false; - } - } - for(int i=0;i<_space_dim;i++) - { - if(fabs(_dxyz[i]-otherC->_dxyz[i])>prec) - { - std::ostringstream oss; - oss << "The delta of this and other differs at " << i << " !"; - reason=oss.str(); - return false; - } - } - for(int i=0;i<_space_dim;i++) - { - if(_structure[i]!=otherC->_structure[i]) - { - std::ostringstream oss; - oss << "The structure of this and other differs at " << i << " !"; - reason=oss.str(); - return false; - } - } - return true; -} - -void MEDCouplingIMesh::checkDeepEquivalWith(const MEDCouplingMesh *other, int cellCompPol, double prec, - DataArrayInt *&cellCor, DataArrayInt *&nodeCor) const -{ - if(!isEqualWithoutConsideringStr(other,prec)) - throw INTERP_KERNEL::Exception("MEDCouplingIMesh::checkDeepEquivalWith : Meshes are not the same !"); -} - -/*! - * Nothing is done here (except to check that the other is a ParaMEDMEM::MEDCouplingIMesh instance too). - * The user intend that the nodes are the same, so by construction of ParaMEDMEM::MEDCouplingIMesh, \a this and \a other are the same ! - */ -void MEDCouplingIMesh::checkDeepEquivalOnSameNodesWith(const MEDCouplingMesh *other, int cellCompPol, double prec, - DataArrayInt *&cellCor) const -{ - if(!isEqualWithoutConsideringStr(other,prec)) - throw INTERP_KERNEL::Exception("MEDCouplingIMesh::checkDeepEquivalOnSameNodesWith : Meshes are not the same !"); -} - -void MEDCouplingIMesh::checkCoherency() const -{ - checkSpaceDimension(); - for(int i=0;i<_space_dim;i++) - if(_structure[i]<1) - { - std::ostringstream oss; oss << "MEDCouplingIMesh::checkCoherency : On axis " << i << "/" << _space_dim << ", number of nodes is equal to " << _structure[i] << " ! must be >=1 !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } -} - -void MEDCouplingIMesh::checkCoherency1(double eps) const -{ - checkCoherency(); -} - -void MEDCouplingIMesh::checkCoherency2(double eps) const -{ - checkCoherency1(eps); -} - -void MEDCouplingIMesh::getNodeGridStructure(int *res) const -{ - checkSpaceDimension(); - std::copy(_structure,_structure+_space_dim,res); -} - -std::vector MEDCouplingIMesh::getNodeGridStructure() const -{ - checkSpaceDimension(); - std::vector ret(_structure,_structure+_space_dim); - return ret; -} - -MEDCouplingStructuredMesh *MEDCouplingIMesh::buildStructuredSubPart(const std::vector< std::pair >& cellPart) const -{ - checkCoherency(); - int dim(getSpaceDimension()); - if(dim!=(int)cellPart.size()) - { - std::ostringstream oss; oss << "MEDCouplingIMesh::buildStructuredSubPart : the space dimension is " << dim << " and cell part size is " << cellPart.size() << " !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - double retOrigin[3]={0.,0.,0.}; - int retStruct[3]={0,0,0}; - MEDCouplingAutoRefCountObjectPtr ret(dynamic_cast(deepCpy())); - for(int i=0;i=_structure[i]) - { - std::ostringstream oss; oss << "MEDCouplingIMesh::buildStructuredSubPart : At dimension #" << i << " the start node id is " << startNode << " it should be in [0," << _structure[i] << ") !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - if(myDelta<0 || myDelta>_structure[i]) - { - std::ostringstream oss; oss << "MEDCouplingIMesh::buildStructuredSubPart : Along dimension #" << i << " the number of nodes is " << _structure[i] << ", and you are requesting for " << myDelta << " nodes wide range !" << std::endl; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - retOrigin[i]=_origin[i]+startNode*_dxyz[i]; - retStruct[i]=myDelta; - } - ret->setNodeStruct(retStruct,retStruct+dim); - ret->setOrigin(retOrigin,retOrigin+dim); - ret->checkCoherency(); - return ret.retn(); -} - -/*! - * Return the space dimension of \a this. - */ -int MEDCouplingIMesh::getSpaceDimension() const -{ - return _space_dim; -} - -void MEDCouplingIMesh::getCoordinatesOfNode(int nodeId, std::vector& coo) const -{ - int tmp[3]; - int spaceDim(getSpaceDimension()); - getSplitNodeValues(tmp); - int tmp2[3]; - GetPosFromId(nodeId,spaceDim,tmp,tmp2); - for(int j=0;j3) - return ret.str(); - ret << "The nodal structure is : "; std::copy(_structure,_structure+spaceDim,std::ostream_iterator(ret," ")); ret << "\n"; - ret << "The origin position is [" << _axis_unit << "]: "; - std::copy(_origin,_origin+spaceDim,std::ostream_iterator(ret," ")); ret << "\n"; - ret << "The intervals along axis are : "; - std::copy(_dxyz,_dxyz+spaceDim,std::ostream_iterator(ret," ")); ret << "\n"; - return ret.str(); -} - -std::string MEDCouplingIMesh::advancedRepr() const -{ - return simpleRepr(); -} - -void MEDCouplingIMesh::getBoundingBox(double *bbox) const -{ - checkCoherency(); - int dim(getSpaceDimension()); - for(int idim=0; idim1) - coeff=_structure[idim]-1; - bbox[2*idim+1]=_origin[idim]+_dxyz[idim]*coeff; - } -} - -/*! - * 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 *MEDCouplingIMesh::getMeasureField(bool isAbs) const -{ - checkCoherency(); - std::string name="MeasureOfMesh_"; - name+=getName(); - int nbelem(getNumberOfCells()); - MEDCouplingFieldDouble *field(MEDCouplingFieldDouble::New(ON_CELLS,ONE_TIME)); - field->setName(name); - DataArrayDouble* array(DataArrayDouble::New()); - array->alloc(nbelem,1); - array->fillWithValue(getMeasureOfAnyCell()); - field->setArray(array) ; - array->decrRef(); - field->setMesh(const_cast(this)); - field->synchronizeTimeWithMesh(); - return field; -} - -/*! - * not implemented yet ! - */ -MEDCouplingFieldDouble *MEDCouplingIMesh::getMeasureFieldOnNode(bool isAbs) const -{ - throw INTERP_KERNEL::Exception("MEDCouplingIMesh::getMeasureFieldOnNode : not implemented yet !"); - //return 0; -} - -int MEDCouplingIMesh::getCellContainingPoint(const double *pos, double eps) const -{ - int dim(getSpaceDimension()),ret(0),coeff(1); - for(int i=0;i=0 && tmpgetSpaceDimension(). - */ -void MEDCouplingIMesh::translate(const double *vector) -{ - checkSpaceDimension(); - int dim(getSpaceDimension()); - std::transform(_origin,_origin+dim,vector,_origin,std::plus()); - declareAsNew(); -} - -/*! - * 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 MEDCouplingIMesh::scale(const double *point, double factor) -{ - checkSpaceDimension(); - int dim(getSpaceDimension()); - std::transform(_origin,_origin+dim,point,_origin,std::minus()); - std::transform(_origin,_origin+dim,_origin,std::bind2nd(std::multiplies(),factor)); - std::transform(_dxyz,_dxyz+dim,_dxyz,std::bind2nd(std::multiplies(),factor)); - std::transform(_origin,_origin+dim,point,_origin,std::plus()); - declareAsNew(); -} - -MEDCouplingMesh *MEDCouplingIMesh::mergeMyselfWith(const MEDCouplingMesh *other) const -{ - //not implemented yet ! - 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 *MEDCouplingIMesh::getCoordinatesAndOwner() const -{ - checkCoherency(); - MEDCouplingAutoRefCountObjectPtr ret(DataArrayDouble::New()); - int spaceDim(getSpaceDimension()),nbNodes(getNumberOfNodes()); - ret->alloc(nbNodes,spaceDim); - double *pt(ret->getPointer()); - ret->setInfoOnComponents(buildInfoOnComponents()); - int tmp2[3],tmp[3]; - getSplitNodeValues(tmp); - for(int i=0;igetNumberOfCells() tuples per \a this->getSpaceDimension() - * components. The caller is to delete this array using decrRef() as it is - * no more needed. - */ -DataArrayDouble *MEDCouplingIMesh::getBarycenterAndOwner() const -{ - checkCoherency(); - MEDCouplingAutoRefCountObjectPtr ret(DataArrayDouble::New()); - int spaceDim(getSpaceDimension()),nbCells(getNumberOfCells()),tmp[3],tmp2[3]; - ret->alloc(nbCells,spaceDim); - double *pt(ret->getPointer()),shiftOrigin[3]; - std::transform(_dxyz,_dxyz+spaceDim,shiftOrigin,std::bind2nd(std::multiplies(),0.5)); - std::transform(_origin,_origin+spaceDim,shiftOrigin,shiftOrigin,std::plus()); - getSplitCellValues(tmp); - ret->setInfoOnComponents(buildInfoOnComponents()); - for(int i=0;i& 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()); - littleStrings.push_back(getAxisUnit()); - tinyInfo.push_back(it); - tinyInfo.push_back(order); - tinyInfo.push_back(_space_dim); - tinyInfo.insert(tinyInfo.end(),_structure,_structure+3); - tinyInfoD.push_back(time); - tinyInfoD.insert(tinyInfoD.end(),_dxyz,_dxyz+3); - tinyInfoD.insert(tinyInfoD.end(),_origin,_origin+3); -} - -void MEDCouplingIMesh::resizeForUnserialization(const std::vector& tinyInfo, DataArrayInt *a1, DataArrayDouble *a2, std::vector& littleStrings) const -{ - a1->alloc(0,1); - a2->alloc(0,1); -} - -void MEDCouplingIMesh::serialize(DataArrayInt *&a1, DataArrayDouble *&a2) const -{ - a1=DataArrayInt::New(); - a1->alloc(0,1); - a2=DataArrayDouble::New(); - a2->alloc(0,1); -} - -void MEDCouplingIMesh::unserialization(const std::vector& tinyInfoD, const std::vector& tinyInfo, const DataArrayInt *a1, DataArrayDouble *a2, - const std::vector& littleStrings) -{ - setName(littleStrings[0]); - setDescription(littleStrings[1]); - setTimeUnit(littleStrings[2]); - setAxisUnit(littleStrings[3]); - setTime(tinyInfoD[0],tinyInfo[0],tinyInfo[1]); - _space_dim=tinyInfo[2]; - _structure[0]=tinyInfo[3]; _structure[1]=tinyInfo[4]; _structure[2]=tinyInfo[5]; - _dxyz[0]=tinyInfoD[1]; _dxyz[1]=tinyInfoD[2]; _dxyz[2]=tinyInfoD[3]; - _origin[0]=tinyInfoD[4]; _origin[1]=tinyInfoD[5]; _origin[2]=tinyInfoD[6]; - declareAsNew(); -} - -void MEDCouplingIMesh::writeVTKLL(std::ostream& ofs, const std::string& cellData, const std::string& pointData, DataArrayByte *byteData) const -{ - checkCoherency(); - std::ostringstream extent,origin,spacing; - for(int i=0;i<3;i++) - { - if(i<_space_dim) - { extent << "0 " << _structure[i]-1 << " "; origin << _origin[i] << " "; spacing << _dxyz[i] << " "; } - else - { extent << "0 0 "; origin << "0 "; spacing << "0 "; } - } - ofs << " <" << getVTKDataSetType() << " WholeExtent=\"" << extent.str() << "\" Origin=\"" << origin.str() << "\" Spacing=\"" << spacing.str() << "\">\n"; - ofs << " \n"; - ofs << " \n" << pointData << std::endl; - ofs << " \n"; - ofs << " \n" << cellData << std::endl; - ofs << " \n"; - ofs << " \n"; - ofs << " \n"; - ofs << " \n"; - ofs << " \n"; -} - -void MEDCouplingIMesh::reprQuickOverview(std::ostream& stream) const -{ - stream << "MEDCouplingIMesh C++ instance at " << this << ". Name : \"" << getName() << "\". Space dimension : " << _space_dim << "."; - if(_space_dim<0 || _space_dim>3) - return ; - stream << "\n"; - std::ostringstream stream0,stream1; - int nbNodes(1),nbCells(0); - bool isPb(false); - for(int i=0;i<_space_dim;i++) - { - char tmp('X'+i); - int tmpNodes(_structure[i]); - stream1 << "- Axis " << tmp << " : " << tmpNodes << " nodes (orig=" << _origin[i] << ", inter=" << _dxyz[i] << ")."; - if(i!=_space_dim-1) - stream1 << std::endl; - if(tmpNodes>=1) - nbNodes*=tmpNodes; - else - isPb=true; - if(tmpNodes>=2) - nbCells=nbCells==0?tmpNodes-1:nbCells*(tmpNodes-1); - } - if(!isPb) - { - stream0 << "Number of cells : " << nbCells << ", Number of nodes : " << nbNodes; - stream << stream0.str(); - if(_space_dim>0) - stream << std::endl; - } - stream << stream1.str(); -} - -std::string MEDCouplingIMesh::getVTKFileExtension() const -{ - return std::string("vti"); -} - -std::string MEDCouplingIMesh::getVTKDataSetType() const -{ - return std::string("ImageData"); -} - -std::vector MEDCouplingIMesh::buildInfoOnComponents() const -{ - checkSpaceDimension(); - int dim(getSpaceDimension()); - std::vector ret(dim); - for(int i=0;i3) - throw INTERP_KERNEL::Exception("MEDCouplingIMesh::CheckSpaceDimension : input spaceDim must be in [0,1,2,3] !"); -} - -int MEDCouplingIMesh::FindIntRoot(int val, int order) -{ - if(order==0) - return 1; - if(val<0) - throw INTERP_KERNEL::Exception("MEDCouplingIMesh::FindIntRoot : input val is < 0 ! Not possible to compute a root !"); - if(order==1) - return val; - if(order!=2 && order!=3) - throw INTERP_KERNEL::Exception("MEDCouplingIMesh::FindIntRoot : the order available are 0,1,2 or 3 !"); - double valf((double)val); - if(order==2) - { - double retf(sqrt(valf)); - int ret((int)retf); - if(ret*ret!=val) - throw INTERP_KERNEL::Exception("MEDCouplingIMesh::FindIntRoot : the input val is not a perfect square root !"); - return ret; - } - else//order==3 - { - double retf(std::pow(val,0.3333333333333333)); - int ret((int)retf),ret2(ret+1); - if(ret*ret*ret!=val && ret2*ret2*ret2!=val) - throw INTERP_KERNEL::Exception("MEDCouplingIMesh::FindIntRoot : the input val is not a perfect cublic root !"); - if(ret*ret*ret==val) - return ret; - else - return ret2; - } -} - -void MEDCouplingIMesh::SpreadCoarseToFineGhost2D(const double *inPtr, double *outPtr, int nbCompo, const std::vector& coarseSt, const std::vector< std::pair >& fineLocInCoarse, const std::vector& facts, int ghostSize) -{ - double *outPtrWork(outPtr); - std::vector dims(MEDCouplingStructuredMesh::GetDimensionsFromCompactFrmt(fineLocInCoarse)); - int nxwg(coarseSt[0]+2*ghostSize),fact0(facts[0]),fact1(facts[1]); - int kk(fineLocInCoarse[0].first+ghostSize-1+nxwg*(fineLocInCoarse[1].first+ghostSize-1));//kk is always >=0 thanks to the fact that ghostSize>=1 ! - for(int jg=0;jg= ghostlev - for(int i=0;i& coarseSt, const std::vector< std::pair >& fineLocInCoarse, const std::vector& facts, int ghostSize) -{ - double *outPtr2(outPtr); - std::vector dims(MEDCouplingStructuredMesh::GetDimensionsFromCompactFrmt(fineLocInCoarse)); - int nxwg(coarseSt[0]+2*ghostSize),fact0(facts[0]),fact1(facts[1]); - int kk(fineLocInCoarse[0].first+ghostSize-1+nxwg*(fineLocInCoarse[1].first+ghostSize-1));//kk is always >=0 thanks to the fact that ghostSize>=1 ! - for(int jg=0;jg= ghostlev - outPtr2+=fact0*nbCompo*dims[0]; - for(int ig=0;ig getNodeStruct() const; - MEDCOUPLING_EXPORT void setOrigin(const double *originStart, const double *originStop); - MEDCOUPLING_EXPORT std::vector getOrigin() const; - MEDCOUPLING_EXPORT void setDXYZ(const double *dxyzStart, const double *dxyzStop); - MEDCOUPLING_EXPORT std::vector getDXYZ() const; - MEDCOUPLING_EXPORT void setAxisUnit(const std::string& unitName); - MEDCOUPLING_EXPORT std::string getAxisUnit() const; - MEDCOUPLING_EXPORT double getMeasureOfAnyCell() const; - MEDCOUPLING_EXPORT MEDCouplingCMesh *convertToCartesian() const; - MEDCOUPLING_EXPORT void refineWithFactor(const std::vector& factors); - MEDCOUPLING_EXPORT MEDCouplingIMesh *asSingleCell() const; - MEDCOUPLING_EXPORT static void CondenseFineToCoarse(const std::vector& coarseSt, const DataArrayDouble *fineDA, const std::vector< std::pair >& fineLocInCoarse, const std::vector& facts, DataArrayDouble *coarseDA); - MEDCOUPLING_EXPORT static void CondenseFineToCoarseGhost(const std::vector& coarseSt, const DataArrayDouble *fineDA, const std::vector< std::pair >& fineLocInCoarse, const std::vector& facts, DataArrayDouble *coarseDA, int ghostSize); - MEDCOUPLING_EXPORT static void SpreadCoarseToFine(const DataArrayDouble *coarseDA, const std::vector& coarseSt, DataArrayDouble *fineDA, const std::vector< std::pair >& fineLocInCoarse, const std::vector& facts); - MEDCOUPLING_EXPORT static void SpreadCoarseToFineGhost(const DataArrayDouble *coarseDA, const std::vector& coarseSt, DataArrayDouble *fineDA, const std::vector< std::pair >& fineLocInCoarse, const std::vector& facts, int ghostSize); - MEDCOUPLING_EXPORT static void SpreadCoarseToFineGhostZone(const DataArrayDouble *coarseDA, const std::vector& coarseSt, DataArrayDouble *fineDA, const std::vector< std::pair >& fineLocInCoarse, const std::vector& facts, int ghostSize); - // - MEDCOUPLING_EXPORT MEDCouplingMesh *deepCpy() const; - MEDCOUPLING_EXPORT MEDCouplingIMesh *clone(bool recDeepCpy) const; - MEDCOUPLING_EXPORT MEDCouplingIMesh *buildWithGhost(int ghostLev) const; - MEDCOUPLING_EXPORT void updateTime() const; - MEDCOUPLING_EXPORT std::size_t getHeapMemorySizeWithoutChildren() const; - MEDCOUPLING_EXPORT std::vector getDirectChildrenWithNull() const; - MEDCOUPLING_EXPORT MEDCouplingMeshType getType() const { return IMAGE_GRID; } - MEDCOUPLING_EXPORT void copyTinyStringsFrom(const MEDCouplingMesh *other); - MEDCOUPLING_EXPORT bool isEqualIfNotWhy(const MEDCouplingMesh *other, double prec, std::string& reason) const; - MEDCOUPLING_EXPORT bool isEqualWithoutConsideringStr(const MEDCouplingMesh *other, double prec) const; - MEDCOUPLING_EXPORT void checkDeepEquivalWith(const MEDCouplingMesh *other, int cellCompPol, double prec, - DataArrayInt *&cellCor, DataArrayInt *&nodeCor) const; - MEDCOUPLING_EXPORT void checkDeepEquivalOnSameNodesWith(const MEDCouplingMesh *other, int cellCompPol, double prec, - DataArrayInt *&cellCor) const; - MEDCOUPLING_EXPORT void checkCoherency() const; - MEDCOUPLING_EXPORT void checkCoherency1(double eps=1e-12) const; - MEDCOUPLING_EXPORT void checkCoherency2(double eps=1e-12) const; - MEDCOUPLING_EXPORT int getSpaceDimension() const; - MEDCOUPLING_EXPORT void getCoordinatesOfNode(int nodeId, std::vector& coo) const; - MEDCOUPLING_EXPORT std::string simpleRepr() const; - MEDCOUPLING_EXPORT std::string advancedRepr() const; - // tools - MEDCOUPLING_EXPORT void getBoundingBox(double *bbox) const; - MEDCOUPLING_EXPORT MEDCouplingFieldDouble *getMeasureField(bool isAbs) const; - MEDCOUPLING_EXPORT MEDCouplingFieldDouble *getMeasureFieldOnNode(bool isAbs) const; - MEDCOUPLING_EXPORT int getCellContainingPoint(const double *pos, double eps) const; - MEDCOUPLING_EXPORT void rotate(const double *center, const double *vector, double angle); - MEDCOUPLING_EXPORT void translate(const double *vector); - MEDCOUPLING_EXPORT void scale(const double *point, double factor); - MEDCOUPLING_EXPORT MEDCouplingMesh *mergeMyselfWith(const MEDCouplingMesh *other) const; - MEDCOUPLING_EXPORT DataArrayDouble *getCoordinatesAndOwner() const; - MEDCOUPLING_EXPORT DataArrayDouble *getBarycenterAndOwner() const; - MEDCOUPLING_EXPORT DataArrayDouble *computeIsoBarycenterOfNodesPerCell() const; - MEDCOUPLING_EXPORT void renumberCells(const int *old2NewBg, bool check=true); - //some useful methods - MEDCOUPLING_EXPORT void getNodeGridStructure(int *res) const; - MEDCOUPLING_EXPORT std::vector getNodeGridStructure() const; - MEDCouplingStructuredMesh *buildStructuredSubPart(const std::vector< std::pair >& cellPart) const; - //serialisation-unserialization - MEDCOUPLING_EXPORT void getTinySerializationInformation(std::vector& tinyInfoD, std::vector& tinyInfo, std::vector& littleStrings) const; - MEDCOUPLING_EXPORT void resizeForUnserialization(const std::vector& tinyInfo, DataArrayInt *a1, DataArrayDouble *a2, std::vector& littleStrings) const; - MEDCOUPLING_EXPORT void serialize(DataArrayInt *&a1, DataArrayDouble *&a2) const; - MEDCOUPLING_EXPORT void unserialization(const std::vector& tinyInfoD, const std::vector& tinyInfo, const DataArrayInt *a1, DataArrayDouble *a2, - const std::vector& littleStrings); - MEDCOUPLING_EXPORT void reprQuickOverview(std::ostream& stream) const; - MEDCOUPLING_EXPORT std::string getVTKFileExtension() const; - private: - MEDCouplingIMesh(); - MEDCouplingIMesh(const MEDCouplingIMesh& other, bool deepCpy); - ~MEDCouplingIMesh(); - void writeVTKLL(std::ostream& ofs, const std::string& cellData, const std::string& pointData, DataArrayByte *byteData) const; - std::string getVTKDataSetType() const; - bool isEqualWithoutConsideringStrInternal(const MEDCouplingMesh *other, double prec, std::string& reason) const; - std::vector buildInfoOnComponents() const; - void checkSpaceDimension() const; - static void CheckSpaceDimension(int spaceDim); - static int FindIntRoot(int val, int order); - static void SpreadCoarseToFineGhost2D(const double *inPtr, double *outPtr, int nbCompo, const std::vector& coarseSt, const std::vector< std::pair >& fineLocInCoarse, const std::vector& facts, int ghostSize); - static void SpreadCoarseToFineGhostZone2D(const double *inPtr, double *outPtr, int nbCompo, const std::vector& coarseSt, const std::vector< std::pair >& fineLocInCoarse, const std::vector& facts, int ghostSize); - private: - int _space_dim; - double _origin[3]; - double _dxyz[3]; - int _structure[3]; - std::string _axis_unit; - }; -} - -#endif diff --git a/src/MEDCoupling/MEDCouplingMatrix.cxx b/src/MEDCoupling/MEDCouplingMatrix.cxx deleted file mode 100644 index 4f0172dc4..000000000 --- a/src/MEDCoupling/MEDCouplingMatrix.cxx +++ /dev/null @@ -1,324 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 -// 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 - -#include "MEDCouplingMatrix.hxx" - -#include "InterpKernelMatrixTools.hxx" - -using namespace ParaMEDMEM; - -DenseMatrix *DenseMatrix::New(int nbRows, int nbCols) -{ - return new DenseMatrix(nbRows,nbCols); -} - -DenseMatrix *DenseMatrix::New(DataArrayDouble *array, int nbRows, int nbCols) -{ - return new DenseMatrix(array,nbRows,nbCols); -} - -DenseMatrix *DenseMatrix::deepCpy() const -{ - MEDCouplingAutoRefCountObjectPtr arr(getData()->deepCpy()); - MEDCouplingAutoRefCountObjectPtr ret(DenseMatrix::New(arr,getNumberOfRows(),getNumberOfCols())); - return ret.retn(); -} - -DenseMatrix *DenseMatrix::shallowCpy() const -{ - MEDCouplingAutoRefCountObjectPtr ret(DenseMatrix::New(const_cast(getData()),getNumberOfRows(),getNumberOfCols())); - return ret.retn(); -} - -std::size_t DenseMatrix::getHeapMemorySizeWithoutChildren() const -{ - return sizeof(DenseMatrix); -} - -std::vector DenseMatrix::getDirectChildrenWithNull() const -{ - std::vector ret; - ret.push_back((const DataArrayDouble *)_data); - return ret; -} - -void DenseMatrix::updateTime() const -{ - const DataArrayDouble *pt(_data); - if(pt) - updateTimeWith(*pt); -} - -/*! - * This method scratch \a this to use a new input. The shape of \a this can be modified freely without any constraints. - * - * \param [in] array - The array containing data that is expected to be taken as new data. - * \param [in] nbRows - The new number of rows (>0 or -1). If -1, the current number of rows will be taken. - * \param [in] nbCols - The new number of columns (>0 or -1). If -1, the current number of cols will be taken. - * - * \sa reShape - */ -void DenseMatrix::reBuild(DataArrayDouble *array, int nbRows, int nbCols) -{ - int nbr(getNumberOfRowsExt(nbRows)),nbc(getNumberOfColsExt(nbCols)); - CheckArraySizes(array,nbr,nbc); - DataArrayDouble *data(_data); - if(data!=array) - { - _data=array; _data->incrRef(); - declareAsNew(); - } - if(nbr!=_nb_rows) - { - _nb_rows=nbr; - declareAsNew(); - } - if(nbc!=_nb_cols) - { - _nb_cols=nbc; - declareAsNew(); - } -} - -/*! - * This method does \b not change the content of the data in \a this. It only changes the shape (with a same number of elements in the matrix). - * If the number of elements needs to be changed call reBuild method instead. - * - * \param [in] nbRows - The new number of rows (>0) - * \param [in] nbCols - The new number of columns (>0) - * \throw if the \c nbRows*nbCols is not equal to \c this->getNbOfElems() - * \sa reBuild - */ -void DenseMatrix::reShape(int nbRows, int nbCols) -{ - if(nbRows<0 || nbCols<0) - throw INTERP_KERNEL::Exception("DenseMatrix::reShape : number of rows and number of cols must be > 0 both !"); - if(nbRows*nbCols!=getNbOfElems()) - throw INTERP_KERNEL::Exception("DenseMatrix::reShape : This method is designed to change only the shape ! Number of elements must remain the same !"); - if(_nb_rows!=nbRows) - { - _nb_rows=nbRows; - declareAsNew(); - } - if(_nb_cols!=nbCols) - { - _nb_cols=nbCols; - declareAsNew(); - } -} - -void DenseMatrix::transpose() -{ - const MemArray& mem(getData()->accessToMemArray()); - double *pt(mem.toNoInterlace(getNumberOfCols())); - std::copy(pt,pt+getNbOfElems(),getData()->getPointer());//declareAsNew done here automatically by getPointer - free(pt); - std::swap(_nb_rows,_nb_cols); - updateTime(); -} - -bool DenseMatrix::isEqual(const DenseMatrix& other, double eps) const -{ - std::string tmp; - return isEqualIfNotWhy(other,eps,tmp); -} - -bool DenseMatrix::isEqualIfNotWhy(const DenseMatrix& other, double eps, std::string& reason) const -{ - if(_nb_rows!=other._nb_rows) - { - std::ostringstream oss; oss << "Number of rows differs (" << _nb_rows << "!=" << other._nb_rows << ") !"; - reason+=oss.str(); - return false; - } - if(_nb_cols!=other._nb_cols) - { - std::ostringstream oss; oss << "Number of cols differs (" << _nb_cols << "!=" << other._nb_cols << ") !"; - reason+=oss.str(); - return false; - } - std::string tmp1; - if(!_data->isEqualIfNotWhy(*other._data,eps,tmp1)) - { - reason+="Data differs : "+tmp1; - return false; - } - return true; -} - -DataArrayDouble *DenseMatrix::matVecMult(const DataArrayDouble *vec) const -{ - return MatVecMult(this,vec); -} - -DataArrayDouble *DenseMatrix::MatVecMult(const DenseMatrix *mat, const DataArrayDouble *vec) -{ - if(!mat || !vec) - throw INTERP_KERNEL::Exception("DenseMatrix::MatVecMult : input matrix or vec is NULL !"); - vec->checkAllocated(); - if(vec->getNumberOfComponents()!=1) - throw INTERP_KERNEL::Exception("DenseMatrix::MatVecMult : input vector must have only one component !"); - if(vec->getNumberOfTuples()!=mat->getNumberOfCols()) - throw INTERP_KERNEL::Exception("DenseMatrix::MatVecMult : Number of columns of this must be equal to number of tuples of vec !"); - MEDCouplingAutoRefCountObjectPtr ret(DataArrayDouble::New()); ret->alloc(mat->getNumberOfRows(),1); - INTERP_KERNEL::matrixProduct(mat->getData()->begin(),mat->getNumberOfRows(),mat->getNumberOfCols(),vec->begin(),vec->getNumberOfTuples(),1,ret->getPointer()); - return ret.retn(); -} - -DenseMatrix *DenseMatrix::Add(const DenseMatrix *a1, const DenseMatrix *a2) -{ - if(!a1 || !a2) - throw INTERP_KERNEL::Exception("DenseMatrix::Add : input matrices must be not NULL !"); - CheckSameSize(a1,a2); - MEDCouplingAutoRefCountObjectPtr data(DataArrayDouble::Add(a1->getData(),a2->getData())); - MEDCouplingAutoRefCountObjectPtr ret(DenseMatrix::New(data,a1->getNumberOfRows(),a1->getNumberOfCols())); - return ret.retn(); -} - -void DenseMatrix::addEqual(const DenseMatrix *other) -{ - if(!other) - throw INTERP_KERNEL::Exception("DenseMatrix::addEqual : other must be not NULL !"); - CheckSameSize(this,other); - getData()->addEqual(other->getData()); -} - -DenseMatrix *DenseMatrix::Substract(const DenseMatrix *a1, const DenseMatrix *a2) -{ - if(!a1 || !a2) - throw INTERP_KERNEL::Exception("DenseMatrix::Substract : input matrices must be not NULL !"); - CheckSameSize(a1,a2); - MEDCouplingAutoRefCountObjectPtr data(DataArrayDouble::Substract(a1->getData(),a2->getData())); - MEDCouplingAutoRefCountObjectPtr ret(DenseMatrix::New(data,a1->getNumberOfRows(),a1->getNumberOfCols())); - return ret.retn(); -} - -void DenseMatrix::substractEqual(const DenseMatrix *other) -{ - if(!other) - throw INTERP_KERNEL::Exception("DenseMatrix::substractEqual : other must be not NULL !"); - CheckSameSize(this,other); - getData()->substractEqual(other->getData()); -} - -DenseMatrix *DenseMatrix::Multiply(const DenseMatrix *a1, const DenseMatrix *a2) -{ - if(!a1 || !a2) - throw INTERP_KERNEL::Exception("DenseMatrix::Multiply : input matrices must be not NULL !"); - CheckCompatibleSizeForMul(a1,a2); - int nbr(a1->getNumberOfRows()),nbc(a2->getNumberOfCols()); - MEDCouplingAutoRefCountObjectPtr data(DataArrayDouble::New()); data->alloc(nbr*nbc,1); - MEDCouplingAutoRefCountObjectPtr ret(DenseMatrix::New(data,a1->getNumberOfRows(),a2->getNumberOfCols())); - INTERP_KERNEL::matrixProduct(a1->getData()->begin(),a1->getNumberOfRows(),a1->getNumberOfCols(),a2->getData()->begin(),a2->getNumberOfRows(),a2->getNumberOfCols(),data->getPointer()); - return ret.retn(); -} - -DenseMatrix *DenseMatrix::Multiply(const DenseMatrix *a1, const DataArrayDouble *a2) -{ - if(!a1 || !a2 || !a2->isAllocated()) - throw INTERP_KERNEL::Exception("DenseMatrix::Multiply #2 : input matrices must be not NULL and a2 allocated !"); - if(a2->getNumberOfComponents()!=1) - throw INTERP_KERNEL::Exception("DenseMatrix::Multiply #2 : The 2nd member must have exactly one component !"); - MEDCouplingAutoRefCountObjectPtr a2Bis(DenseMatrix::New(const_cast(a2),a2->getNumberOfTuples(),1)); - return DenseMatrix::Multiply(a1,a2Bis); -} - -DenseMatrix::~DenseMatrix() -{ -} - -DenseMatrix::DenseMatrix(int nbRows, int nbCols):_nb_rows(nbRows),_nb_cols(nbCols),_data(DataArrayDouble::New()) -{ - if(_nb_rows<0 || _nb_cols<0) - throw INTERP_KERNEL::Exception("constructor of DenseMatrix : number of rows and number of cols must be > 0 both !"); - int nbOfTuples(_nb_rows*_nb_cols); - _data->alloc(nbOfTuples,1); -} - -DenseMatrix::DenseMatrix(DataArrayDouble *array, int nbRows, int nbCols):_nb_rows(nbRows),_nb_cols(nbCols) -{ - CheckArraySizes(array,_nb_rows,_nb_cols); - _data=array; _data->incrRef(); -} - -int DenseMatrix::getNumberOfRowsExt(int nbRows) const -{ - if(nbRows<-1) - throw INTERP_KERNEL::Exception("DenseMatrix::getNumberOfRowsExt : invalid input must be >= -1 !"); - if(nbRows==-1) - return _nb_rows; - else - return nbRows; -} - -int DenseMatrix::getNumberOfColsExt(int nbCols) const -{ - if(nbCols<-1) - throw INTERP_KERNEL::Exception("DenseMatrix::getNumberOfColsExt : invalid input must be >= -1 !"); - if(nbCols==-1) - return _nb_cols; - else - return nbCols; -} - -void DenseMatrix::checkValidData() const -{ - if(!getData()) - throw INTERP_KERNEL::Exception("DenseMatrix::checkValidData : data is NULL !"); - if(!getData()->isAllocated()) - throw INTERP_KERNEL::Exception("DenseMatrix::checkValidData : data is not allocated !"); - if(getData()->getNumberOfComponents()!=1) - throw INTERP_KERNEL::Exception("DenseMatrix::checkValidData : data has not 1 component !"); -} - -void DenseMatrix::CheckArraySizes(DataArrayDouble *array, int nbRows, int nbCols) -{ - if(nbRows<0 || nbCols<0) - throw INTERP_KERNEL::Exception("constructor #2 of DenseMatrix : number of rows and number of cols must be > 0 both !"); - if(!array || !array->isAllocated()) - throw INTERP_KERNEL::Exception("constructor #2 of DenseMatrix : input array is empty or not allocated !"); - if(array->getNumberOfComponents()!=1) - throw INTERP_KERNEL::Exception("constructor #2 of DenseMatrix : input array must have exactly one component !"); - std::size_t nbr((std::size_t)nbRows),nbc((std::size_t)nbCols); - if(nbr*nbc!=array->getNbOfElems()) - throw INTERP_KERNEL::Exception("constructor #2 of DenseMatrix : the number of elems in input array is not equal to the product of nbRows and nbCols !"); -} - -void DenseMatrix::CheckSameSize(const DenseMatrix *a1, const DenseMatrix *a2) -{ - if(!a1 || !a2) - throw INTERP_KERNEL::Exception("DenseMatrix::CheckSameSize : a1 or a2 is NULL !"); - a1->checkValidData(); a2->checkValidData(); - if(a1->getNumberOfRows()!=a2->getNumberOfRows()) - throw INTERP_KERNEL::Exception("DenseMatrix::CheckSameSize : number of rows mismatches !"); - if(a1->getNumberOfCols()!=a2->getNumberOfCols()) - throw INTERP_KERNEL::Exception("DenseMatrix::CheckSameSize : number of columns mismatches !"); - -} - -void DenseMatrix::CheckCompatibleSizeForMul(const DenseMatrix *a1, const DenseMatrix *a2) -{ - if(!a1 || !a2) - throw INTERP_KERNEL::Exception("DenseMatrix::CheckCompatibleSizeForMul : a1 or a2 is NULL !"); - a1->checkValidData(); a2->checkValidData(); - if(a1->getNumberOfCols()!=a2->getNumberOfRows()) - throw INTERP_KERNEL::Exception("DenseMatrix::CheckCompatibleSizeForMul : number of cols of a1 must be equal to number of rows of a2 !"); -} - diff --git a/src/MEDCoupling/MEDCouplingMatrix.hxx b/src/MEDCoupling/MEDCouplingMatrix.hxx deleted file mode 100644 index 93c7f6502..000000000 --- a/src/MEDCoupling/MEDCouplingMatrix.hxx +++ /dev/null @@ -1,86 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 -// 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 - -#ifndef __PARAMEDMEM_MEDCOUPLINGMATRIX_HXX__ -#define __PARAMEDMEM_MEDCOUPLINGMATRIX_HXX__ - -#include "MEDCoupling.hxx" -#include "MEDCouplingTimeLabel.hxx" -#include "MEDCouplingRefCountObject.hxx" -#include "MEDCouplingMemArray.hxx" -#include "MEDCouplingAutoRefCountObjectPtr.hxx" - -#include "InterpKernelException.hxx" - -namespace ParaMEDMEM -{ - /*! - * The aim of this class is \b NOT to reimplement all linear algebra but only to store a dense matrix. - * It only provides basic set/get and basic operations and bindings to linear algebra libraries (numpy/scipy) and a compatible format to Petsc. - */ - class DenseMatrix : public RefCountObject, public TimeLabel - { - public: - MEDCOUPLING_EXPORT static DenseMatrix *New(int nbRows, int nbCols); - MEDCOUPLING_EXPORT static DenseMatrix *New(DataArrayDouble *array, int nbRows, int nbCols); - MEDCOUPLING_EXPORT DenseMatrix *deepCpy() const; - MEDCOUPLING_EXPORT DenseMatrix *shallowCpy() const; - MEDCOUPLING_EXPORT std::size_t getHeapMemorySizeWithoutChildren() const; - MEDCOUPLING_EXPORT std::vector getDirectChildrenWithNull() const; - MEDCOUPLING_EXPORT void updateTime() const; - // - MEDCOUPLING_EXPORT int getNumberOfRows() const { return _nb_rows; } - MEDCOUPLING_EXPORT int getNumberOfCols() const { return _nb_cols; } - MEDCOUPLING_EXPORT int getNbOfElems() const { return _nb_rows*_nb_cols; } - MEDCOUPLING_EXPORT void reBuild(DataArrayDouble *array, int nbRows=-1, int nbCols=-1); - MEDCOUPLING_EXPORT void reShape(int nbRows, int nbCols); - MEDCOUPLING_EXPORT void transpose(); - // - MEDCOUPLING_EXPORT bool isEqual(const DenseMatrix& other, double eps) const; - MEDCOUPLING_EXPORT bool isEqualIfNotWhy(const DenseMatrix& other, double eps, std::string& reason) const; - MEDCOUPLING_EXPORT DataArrayDouble *matVecMult(const DataArrayDouble *vec) const; - MEDCOUPLING_EXPORT static DataArrayDouble *MatVecMult(const DenseMatrix *mat, const DataArrayDouble *vec); - MEDCOUPLING_EXPORT static DenseMatrix *Add(const DenseMatrix *a1, const DenseMatrix *a2); - MEDCOUPLING_EXPORT void addEqual(const DenseMatrix *other); - MEDCOUPLING_EXPORT static DenseMatrix *Substract(const DenseMatrix *a1, const DenseMatrix *a2); - MEDCOUPLING_EXPORT void substractEqual(const DenseMatrix *other); - MEDCOUPLING_EXPORT static DenseMatrix *Multiply(const DenseMatrix *a1, const DenseMatrix *a2); - MEDCOUPLING_EXPORT static DenseMatrix *Multiply(const DenseMatrix *a1, const DataArrayDouble *a2); - // - MEDCOUPLING_EXPORT const DataArrayDouble *getData() const { return _data; } - MEDCOUPLING_EXPORT DataArrayDouble *getData() { return _data; } - private: - ~DenseMatrix(); - DenseMatrix(int nbRows, int nbCols); - DenseMatrix(DataArrayDouble *array, int nbRows, int nbCols); - int getNumberOfRowsExt(int nbRows) const; - int getNumberOfColsExt(int nbCols) const; - void checkValidData() const; - static void CheckArraySizes(DataArrayDouble *array, int nbRows, int nbCols); - static void CheckSameSize(const DenseMatrix *a1, const DenseMatrix *a2); - static void CheckCompatibleSizeForMul(const DenseMatrix *a1, const DenseMatrix *a2); - private: - int _nb_rows; - int _nb_cols; - MEDCouplingAutoRefCountObjectPtr _data; - }; -} - -#endif diff --git a/src/MEDCoupling/MEDCouplingMemArray.cxx b/src/MEDCoupling/MEDCouplingMemArray.cxx deleted file mode 100644 index 751741283..000000000 --- a/src/MEDCoupling/MEDCouplingMemArray.cxx +++ /dev/null @@ -1,11860 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 -// 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 "BBTree.txx" -#include "GenMathFormulae.hxx" -#include "InterpKernelAutoPtr.hxx" -#include "InterpKernelExprParser.hxx" - -#include -#include -#include -#include -#include -#include - -typedef double (*MYFUNCPTR)(double); - -using namespace ParaMEDMEM; - -template -void DataArrayDouble::findCommonTuplesAlg(const double *bbox, int nbNodes, int limitNodeId, double prec, DataArrayInt *c, DataArrayInt *cI) const -{ - const double *coordsPtr=getConstPointer(); - BBTreePts myTree(bbox,0,0,nbNodes,prec); - std::vector isDone(nbNodes); - for(int i=0;i intersectingElems; - myTree.getElementsAroundPoint(coordsPtr+i*SPACEDIM,intersectingElems); - if(intersectingElems.size()>1) - { - std::vector commonNodes; - for(std::vector::const_iterator it=intersectingElems.begin();it!=intersectingElems.end();it++) - if(*it!=i) - if(*it>=limitNodeId) - { - commonNodes.push_back(*it); - isDone[*it]=true; - } - if(!commonNodes.empty()) - { - cI->pushBackSilent(cI->back()+(int)commonNodes.size()+1); - c->pushBackSilent(i); - c->insertAtTheEnd(commonNodes.begin(),commonNodes.end()); - } - } - } - } -} - -template -void DataArrayDouble::FindTupleIdsNearTuplesAlg(const BBTreePts& myTree, const double *pos, int nbOfTuples, double eps, - DataArrayInt *c, DataArrayInt *cI) -{ - for(int i=0;i intersectingElems; - myTree.getElementsAroundPoint(pos+i*SPACEDIM,intersectingElems); - std::vector commonNodes; - for(std::vector::const_iterator it=intersectingElems.begin();it!=intersectingElems.end();it++) - commonNodes.push_back(*it); - 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::getHeapMemorySizeWithoutChildren() 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; -} - -std::vector DataArray::getDirectChildrenWithNull() const -{ - return std::vector(); -} - -/*! - * 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 std::string& 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) -{ - if(_info_on_compo.size()!=other._info_on_compo.size()) - throw INTERP_KERNEL::Exception("Size of arrays mismatches on copyStringInfoFrom !"); - _name=other._name; - _info_on_compo=other._info_on_compo; -} - -void DataArray::copyPartOfStringInfoFrom(const DataArray& other, const std::vector& compoIds) -{ - int nbOfCompoOth=other.getNumberOfComponents(); - std::size_t newNbOfCompo=compoIds.size(); - for(std::size_t i=0;i=nbOfCompoOth || compoIds[i]<0) - { - std::ostringstream oss; oss << "Specified component id is out of range (" << compoIds[i] << ") compared with nb of actual components (" << nbOfCompoOth << ")"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - for(std::size_t i=0;i& compoIds, const DataArray& other) -{ - int nbOfCompo=getNumberOfComponents(); - std::size_t partOfCompoToSet=compoIds.size(); - if((int)partOfCompoToSet!=other.getNumberOfComponents()) - throw INTERP_KERNEL::Exception("Given compoIds has not the same size as number of components of given array !"); - for(std::size_t i=0;i=nbOfCompo || compoIds[i]<0) - { - std::ostringstream oss; oss << "Specified component id is out of range (" << compoIds[i] << ") compared with nb of actual components (" << nbOfCompo << ")"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - for(std::size_t i=0;i::const_iterator iter=_info_on_compo.begin();iter!=_info_on_compo.end();iter++) - stream << "\"" << *iter << "\" "; - stream << "\n"; -} - -std::string DataArray::cppRepr(const std::string& varName) const -{ - std::ostringstream ret; - reprCppStream(varName,ret); - 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) -{ - if(getNumberOfComponents()!=(int)info.size()) - { - std::ostringstream oss; oss << "DataArray::setInfoOnComponents : input is of size " << info.size() << " whereas number of components is equal to " << getNumberOfComponents() << " !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - _info_on_compo=info; -} - -/*! - * This method is only a dispatcher towards DataArrayDouble::setPartOfValues3, DataArrayInt::setPartOfValues3, DataArrayChar::setPartOfValues3 depending on the true - * type of \a this and \a aBase. - * - * \throw If \a aBase and \a this do not have the same type. - * - * \sa DataArrayDouble::setPartOfValues3, DataArrayInt::setPartOfValues3, DataArrayChar::setPartOfValues3. - */ -void DataArray::setPartOfValuesBase3(const DataArray *aBase, const int *bgTuples, const int *endTuples, int bgComp, int endComp, int stepComp, bool strictCompoCompare) -{ - if(!aBase) - throw INTERP_KERNEL::Exception("DataArray::setPartOfValuesBase3 : input aBase object is NULL !"); - DataArrayDouble *this1(dynamic_cast(this)); - DataArrayInt *this2(dynamic_cast(this)); - DataArrayChar *this3(dynamic_cast(this)); - const DataArrayDouble *a1(dynamic_cast(aBase)); - const DataArrayInt *a2(dynamic_cast(aBase)); - const DataArrayChar *a3(dynamic_cast(aBase)); - if(this1 && a1) - { - this1->setPartOfValues3(a1,bgTuples,endTuples,bgComp,endComp,stepComp,strictCompoCompare); - return ; - } - if(this2 && a2) - { - this2->setPartOfValues3(a2,bgTuples,endTuples,bgComp,endComp,stepComp,strictCompoCompare); - return ; - } - if(this3 && a3) - { - this3->setPartOfValues3(a3,bgTuples,endTuples,bgComp,endComp,stepComp,strictCompoCompare); - return ; - } - throw INTERP_KERNEL::Exception("DataArray::setPartOfValuesBase3 : input aBase object and this do not have the same type !"); -} - -std::vector DataArray::getVarsOnComponent() const -{ - int nbOfCompo=(int)_info_on_compo.size(); - std::vector ret(nbOfCompo); - for(int i=0;i DataArray::getUnitsOnComponent() const -{ - int nbOfCompo=(int)_info_on_compo.size(); - std::vector ret(nbOfCompo); - for(int i=0;i=0) - return _info_on_compo[i]; - else - { - std::ostringstream oss; oss << "DataArray::getInfoOnComponent : Specified component id is out of range (" << i << ") compared with nb of actual components (" << (int) _info_on_compo.size(); - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } -} - -/*! - * 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 -{ - if(i<(int)_info_on_compo.size() && i>=0) - { - return GetVarNameFromInfo(_info_on_compo[i]); - } - else - { - std::ostringstream oss; oss << "DataArray::getVarOnComponent : Specified component id is out of range (" << i << ") compared with nb of actual components (" << (int) _info_on_compo.size(); - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } -} - -/*! - * 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 -{ - if(i<(int)_info_on_compo.size() && i>=0) - { - return GetUnitFromInfo(_info_on_compo[i]); - } - else - { - std::ostringstream oss; oss << "DataArray::getUnitOnComponent : Specified component id is out of range (" << i << ") compared with nb of actual components (" << (int) _info_on_compo.size(); - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } -} - -/*! - * 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) -{ - std::size_t p1=info.find_last_of('['); - std::size_t p2=info.find_last_of(']'); - if(p1==std::string::npos || p2==std::string::npos) - return info; - if(p1>p2) - return info; - if(p1==0) - return std::string(); - std::size_t p3=info.find_last_not_of(' ',p1-1); - 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) -{ - std::size_t p1=info.find_last_of('['); - std::size_t p2=info.find_last_of(']'); - if(p1==std::string::npos || p2==std::string::npos) - return std::string(); - if(p1>p2) - return std::string(); - return info.substr(p1+1,p2-p1-1); -} - -/*! - * This method put in info format the result of the merge of \a var and \a unit. - * The standard format for that is "var [unit]". - * Inversely you can retrieve the var part or the unit part of info string using resp. GetVarNameFromInfo and GetUnitFromInfo. - */ -std::string DataArray::BuildInfoFromVarAndUnit(const std::string& var, const std::string& unit) -{ - std::ostringstream oss; - oss << var << " [" << unit << "]"; - return oss.str(); -} - -/*! - * Returns a new DataArray 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] arrs - a sequence of arrays to include in the result array. All arrays must have the same type. - * \return DataArray * - the new instance of DataArray (that can be either DataArrayInt, DataArrayDouble, DataArrayChar). - * The caller is to delete this result array using decrRef() as it is no more - * needed. - * \throw If all arrays within \a arrs are NULL. - * \throw If all not null arrays in \a arrs have not the same type. - * \throw If getNumberOfComponents() of arrays within \a arrs. - */ -DataArray *DataArray::Aggregate(const std::vector& arrs) -{ - std::vector arr2; - for(std::vector::const_iterator it=arrs.begin();it!=arrs.end();it++) - if(*it) - arr2.push_back(*it); - if(arr2.empty()) - throw INTERP_KERNEL::Exception("DataArray::Aggregate : only null instance in input vector !"); - std::vector arrd; - std::vector arri; - std::vector arrc; - for(std::vector::const_iterator it=arr2.begin();it!=arr2.end();it++) - { - const DataArrayDouble *a=dynamic_cast(*it); - if(a) - { arrd.push_back(a); continue; } - const DataArrayInt *b=dynamic_cast(*it); - if(b) - { arri.push_back(b); continue; } - const DataArrayChar *c=dynamic_cast(*it); - if(c) - { arrc.push_back(c); continue; } - throw INTERP_KERNEL::Exception("DataArray::Aggregate : presence of not null instance in inuput that is not in [DataArrayDouble, DataArrayInt, DataArrayChar] !"); - } - if(arr2.size()==arrd.size()) - return DataArrayDouble::Aggregate(arrd); - if(arr2.size()==arri.size()) - return DataArrayInt::Aggregate(arri); - if(arr2.size()==arrc.size()) - return DataArrayChar::Aggregate(arrc); - throw INTERP_KERNEL::Exception("DataArray::Aggregate : all input arrays must have the same type !"); -} - -/*! - * 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 std::string& info) -{ - if(i<(int)_info_on_compo.size() && i>=0) - _info_on_compo[i]=info; - else - { - std::ostringstream oss; oss << "DataArray::setInfoOnComponent : Specified component id is out of range (" << i << ") compared with nb of actual components (" << (int) _info_on_compo.size(); - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } -} - -/*! - * 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 in \a this only if \a this is not allocated. - * The condition of number of components must not be changed. - * - * 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) -{ - 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 std::string& msg) const -{ - if(getNumberOfTuples()!=nbOfTuples) - { - std::ostringstream oss; oss << msg << " : mismatch number of tuples : expected " << nbOfTuples << " having " << getNumberOfTuples() << " !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } -} - -void DataArray::checkNbOfComps(int nbOfCompo, const std::string& msg) const -{ - if(getNumberOfComponents()!=nbOfCompo) - { - std::ostringstream oss; oss << msg << " : mismatch number of components : expected " << nbOfCompo << " having " << getNumberOfComponents() << " !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } -} - -void DataArray::checkNbOfElems(std::size_t nbOfElems, const std::string& msg) const -{ - if(getNbOfElems()!=nbOfElems) - { - std::ostringstream oss; oss << msg << " : mismatch number of elems : Expected " << nbOfElems << " having " << getNbOfElems() << " !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } -} - -void DataArray::checkNbOfTuplesAndComp(const DataArray& other, const std::string& msg) const -{ - if(getNumberOfTuples()!=other.getNumberOfTuples()) - { - std::ostringstream oss; oss << msg << " : mismatch number of tuples : expected " << other.getNumberOfTuples() << " having " << getNumberOfTuples() << " !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - if(getNumberOfComponents()!=other.getNumberOfComponents()) - { - std::ostringstream oss; oss << msg << " : mismatch number of components : expected " << other.getNumberOfComponents() << " having " << getNumberOfComponents() << " !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } -} - -void DataArray::checkNbOfTuplesAndComp(int nbOfTuples, int nbOfCompo, const std::string& msg) const -{ - checkNbOfTuples(nbOfTuples,msg); - checkNbOfComps(nbOfCompo,msg); -} - -/*! - * Simply this method checks that \b value is in [0,\b ref). - */ -void DataArray::CheckValueInRange(int ref, int value, const std::string& msg) -{ - if(value<0 || value>=ref) - { - std::ostringstream oss; oss << "DataArray::CheckValueInRange : " << msg << " ! Expected in range [0," << ref << "[ having " << value << " !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } -} - -/*! - * This method checks that [\b start, \b end) is compliant with ref length \b value. - * typicaly start in [0,\b value) and end in [0,\b value). If value==start and start==end, it is supported. - */ -void DataArray::CheckValueInRangeEx(int value, int start, int end, const std::string& msg) -{ - if(start<0 || start>=value) - { - if(value!=start || end!=start) - { - 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::CheckValueInRangeEx : " << msg << " ! Expected end " << end << " of input range, in [0," << value << "] !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } -} - -void DataArray::CheckClosingParInRange(int ref, int value, const std::string& msg) -{ - if(value<0 || value>ref) - { - 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) -{ - 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 !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - return (end-1-begin)/step+1; -} - -int DataArray::GetNumberOfItemGivenBESRelative(int begin, int end, int step, const std::string& msg) -{ - if(step==0) - throw INTERP_KERNEL::Exception("DataArray::GetNumberOfItemGivenBES : step=0 is not allowed !"); - if(end0) - { - std::ostringstream oss; oss << msg << " : end before begin whereas step is positive !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - if(begin 0 !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - if(begin!=end) - return (std::max(begin,end)-1-std::min(begin,end))/std::abs(step)+1; - else - return 0; -} - -int DataArray::GetPosOfItemGivenBESRelativeNoThrow(int value, int begin, int end, int step) -{ - if(step!=0) - { - if(step>0) - { - if(begin<=value && value=value && value>end) - { - if((begin-value)%(-step)==0) - return (begin-value)/(-step); - else - return -1; - } - else - return -1; - } - } - else - 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; -} - -/*! - * 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 -{ - 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 -{ - if(!isAllocated()) - throw INTERP_KERNEL::Exception("DataArrayDouble::checkAllocated : Array is defined but not allocated ! Call alloc or setValues method first !"); -} - -/*! - * This method desallocated \a this without modification of informations relative to the components. - * After call of this method, DataArrayDouble::isAllocated will return false. - * If \a this is already not allocated, \a this is let unchanged. - */ -void DataArrayDouble::desallocate() -{ - _mem.destroy(); -} - -std::size_t DataArrayDouble::getHeapMemorySizeWithoutChildren() const -{ - std::size_t sz(_mem.getNbOfElemAllocated()); - sz*=sizeof(double); - return DataArray::getHeapMemorySizeWithoutChildren()+sz; -} - -/*! - * 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 -{ - if(isAllocated()) - { - if(getNbOfElems()==1) - { - return *getConstPointer(); - } - else - throw INTERP_KERNEL::Exception("DataArrayDouble::doubleValue : DataArrayDouble instance is allocated but number of elements is not equal to 1 !"); - } - else - throw INTERP_KERNEL::Exception("DataArrayDouble::doubleValue : DataArrayDouble instance is not allocated !"); -} - -/*! - * 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 -{ - checkAllocated(); - return getNumberOfTuples()==0; -} - -/*! - * 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 -{ - return new DataArrayDouble(*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 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 -{ - if(dCpy) - return deepCpy(); - else - { - incrRef(); - return const_cast(this); - } -} - -/*! - * 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) -{ - other.checkAllocated(); - int nbOfTuples=other.getNumberOfTuples(); - int nbOfComp=other.getNumberOfComponents(); - allocIfNecessary(nbOfTuples,nbOfComp); - std::size_t nbOfElems=(std::size_t)nbOfTuples*nbOfComp; - double *pt=getPointer(); - const double *ptI=other.getConstPointer(); - for(std::size_t i=0;igetNumberOfComponents() != 1 - * \throw If \a this is not allocated. - */ -void DataArrayDouble::iota(double init) -{ - checkAllocated(); - if(getNumberOfComponents()!=1) - throw INTERP_KERNEL::Exception("DataArrayDouble::iota : works only for arrays with only one component, you can call 'rearrange' method before !"); - double *ptr=getPointer(); - int ntuples=getNumberOfTuples(); - for(int i=0;igetNumberOfComponents() != 1 - * \throw If \a this is not allocated. - */ -bool DataArrayDouble::isUniform(double val, double eps) const -{ - checkAllocated(); - if(getNumberOfComponents()!=1) - throw INTERP_KERNEL::Exception("DataArrayDouble::isUniform : must be applied on DataArrayDouble with only one component, you can call 'rearrange' method before !"); - int nbOfTuples=getNumberOfTuples(); - const double *w=getConstPointer(); - const double *end2=w+nbOfTuples; - const double vmin=val-eps; - const double vmax=val+eps; - for(;w!=end2;w++) - if(*wvmax) - return false; - 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) -{ - 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() -{ - checkAllocated(); - _mem.reverse(getNumberOfComponents()); - declareAsNew(); -} - -/*! - * 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 -{ - if(!isMonotonic(increasing,eps)) - { - if (increasing) - throw INTERP_KERNEL::Exception("DataArrayDouble::checkMonotonic : 'this' is not INCREASING monotonic !"); - else - throw INTERP_KERNEL::Exception("DataArrayDouble::checkMonotonic : 'this' is not DECREASING monotonic !"); - } -} - -/*! - * 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 -{ - checkAllocated(); - if(getNumberOfComponents()!=1) - throw INTERP_KERNEL::Exception("DataArrayDouble::isMonotonic : only supported with 'this' array with ONE component !"); - int nbOfElements=getNumberOfTuples(); - const double *ptr=getConstPointer(); - if(nbOfElements==0) - return true; - double ref=ptr[0]; - double absEps=fabs(eps); - if(increasing) - { - for(int i=1;i(ref-absEps)) - return false; - ref=ptr[i]; - } - return true; - } -} - -/*! - * Returns a textual and human readable representation of \a this instance of - * DataArrayDouble. This text is shown when a DataArrayDouble is printed in Python. - * \return std::string - text describing \a this DataArrayDouble. - * - * \sa reprNotTooLong, reprZip - */ -std::string DataArrayDouble::repr() const -{ - std::ostringstream ret; - reprStream(ret); - return ret.str(); -} - -std::string DataArrayDouble::reprZip() const -{ - std::ostringstream ret; - reprZipStream(ret); - return ret.str(); -} - -/*! - * This method is close to repr method except that when \a this has more than 1000 tuples, all tuples are not - * printed out to avoid to consume too much space in interpretor. - * \sa repr - */ -std::string DataArrayDouble::reprNotTooLong() const -{ - std::ostringstream ret; - reprNotTooLongStream(ret); - return ret.str(); -} - -void DataArrayDouble::writeVTK(std::ostream& ofs, int indent, const std::string& nameInFile, DataArrayByte *byteArr) const -{ - static const char SPACE[4]={' ',' ',' ',' '}; - checkAllocated(); - std::string idt(indent,' '); - ofs.precision(17); - ofs << idt << "::const_iterator it=_info_on_compo.begin();it!=_info_on_compo.end();it++) - if(!(*it).empty()) - areAllEmpty=false; - if(!areAllEmpty) - for(std::size_t i=0;i<_info_on_compo.size();i++) - ofs << " ComponentName" << i << "=\"" << _info_on_compo[i] << "\""; - // - if(byteArr) - { - ofs << " format=\"appended\" offset=\"" << byteArr->getNumberOfTuples() << "\">"; - INTERP_KERNEL::AutoPtr tmp(new float[getNbOfElems()]); - float *pt(tmp); - // to make Visual C++ happy : instead of std::copy(begin(),end(),(float *)tmp); - for(const double *src=begin();src!=end();src++,pt++) - *pt=float(*src); - const char *data(reinterpret_cast((float *)tmp)); - std::size_t sz(getNbOfElems()*sizeof(float)); - byteArr->insertAtTheEnd(data,data+sz); - byteArr->insertAtTheEnd(SPACE,SPACE+4); - } - else - { - ofs << " RangeMin=\"" << getMinValueInArray() << "\" RangeMax=\"" << getMaxValueInArray() << "\" format=\"ascii\">\n" << idt; - std::copy(begin(),end(),std::ostream_iterator(ofs," ")); - } - ofs << std::endl << idt << "\n"; -} - -void DataArrayDouble::reprStream(std::ostream& stream) const -{ - stream << "Name of double array : \"" << _name << "\"\n"; - reprWithoutNameStream(stream); -} - -void DataArrayDouble::reprZipStream(std::ostream& stream) const -{ - stream << "Name of double array : \"" << _name << "\"\n"; - reprZipWithoutNameStream(stream); -} - -void DataArrayDouble::reprNotTooLongStream(std::ostream& stream) const -{ - stream << "Name of double array : \"" << _name << "\"\n"; - reprNotTooLongWithoutNameStream(stream); -} - -void DataArrayDouble::reprWithoutNameStream(std::ostream& stream) const -{ - DataArray::reprWithoutNameStream(stream); - stream.precision(17); - _mem.repr(getNumberOfComponents(),stream); -} - -void DataArrayDouble::reprZipWithoutNameStream(std::ostream& stream) const -{ - DataArray::reprWithoutNameStream(stream); - stream.precision(17); - _mem.reprZip(getNumberOfComponents(),stream); -} - -void DataArrayDouble::reprNotTooLongWithoutNameStream(std::ostream& stream) const -{ - DataArray::reprWithoutNameStream(stream); - stream.precision(17); - _mem.reprNotTooLong(getNumberOfComponents(),stream); -} - -void DataArrayDouble::reprCppStream(const std::string& varName, std::ostream& stream) const -{ - int nbTuples=getNumberOfTuples(),nbComp=getNumberOfComponents(); - const double *data=getConstPointer(); - stream.precision(17); - stream << "DataArrayDouble *" << varName << "=DataArrayDouble::New();" << std::endl; - if(nbTuples*nbComp>=1) - { - stream << "const double " << 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 DataArrayDouble::reprQuickOverview(std::ostream& stream) const -{ - 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 -{ - 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;j=0 !"); - 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 DataArrayInt. - */ -DataArrayInt *DataArrayDouble::convertToIntArr() const -{ - DataArrayInt *ret=DataArrayInt::New(); - ret->alloc(getNumberOfTuples(),getNumberOfComponents()); - int *dest=ret->getPointer(); - // to make Visual C++ happy : instead of std::size_t nbOfVals=getNbOfElems(); std::copy(src,src+nbOfVals,dest); - for(const double *src=begin();src!=end();src++,dest++) - *dest=(int)*src; - ret->copyStringInfoFrom(*this); - 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 -{ - 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,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 -{ - if(_mem.isNull()) - throw INTERP_KERNEL::Exception("DataArrayDouble::toNoInterlace : Not defined array !"); - double *tab=_mem.toNoInterlace(getNumberOfComponents()); - DataArrayDouble *ret=DataArrayDouble::New(); - ret->useArray(tab,true,C_DEALLOC,getNumberOfTuples(),getNumberOfComponents()); - 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 \c this one. - * If a permutation reduction is needed, substr() or selectByTupleId() should be used. - * For more info on renumbering see \ref numbering. - * \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) -{ - checkAllocated(); - int nbTuples=getNumberOfTuples(); - int nbOfCompo=getNumberOfComponents(); - double *tmp=new double[nbTuples*nbOfCompo]; - const double *iptr=getConstPointer(); - for(int i=0;i=0 && vgetNumberOfTuples() - * 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) -{ - checkAllocated(); - int nbTuples=getNumberOfTuples(); - int nbOfCompo=getNumberOfComponents(); - double *tmp=new double[nbTuples*nbOfCompo]; - const double *iptr=getConstPointer(); - for(int i=0;i=0 && vgetNumberOfTuples() - * 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 -{ - checkAllocated(); - int nbTuples=getNumberOfTuples(); - int nbOfCompo=getNumberOfComponents(); - MEDCouplingAutoRefCountObjectPtr ret=DataArrayDouble::New(); - ret->alloc(nbTuples,nbOfCompo); - ret->copyStringInfoFrom(*this); - const double *iptr=getConstPointer(); - double *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 \c this one. - * If a permutation reduction is needed, substr() or selectByTupleId() should be used. - * For more info on renumbering see \ref numbering. - * \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 -{ - checkAllocated(); - int nbTuples=getNumberOfTuples(); - int nbOfCompo=getNumberOfComponents(); - MEDCouplingAutoRefCountObjectPtr ret=DataArrayDouble::New(); - ret->alloc(nbTuples,nbOfCompo); - ret->copyStringInfoFrom(*this); - const double *iptr=getConstPointer(); - double *optr=ret->getPointer(); - for(int i=0;icopyStringInfoFrom(*this); - return ret.retn(); -} - -/*! - * 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 numbering. - * \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 -{ - checkAllocated(); - int nbTuples=getNumberOfTuples(); - int nbOfCompo=getNumberOfComponents(); - MEDCouplingAutoRefCountObjectPtr ret=DataArrayDouble::New(); - ret->alloc(newNbOfTuple,nbOfCompo); - const double *iptr=getConstPointer(); - double *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 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 numbering. - * \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 -{ - checkAllocated(); - MEDCouplingAutoRefCountObjectPtr ret=DataArrayDouble::New(); - int nbComp=getNumberOfComponents(); - ret->alloc((int)std::distance(new2OldBg,new2OldEnd),nbComp); - ret->copyStringInfoFrom(*this); - double *pt=ret->getPointer(); - const double *srcPt=getConstPointer(); - int i=0; - 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.retn(); -} - -/*! - * 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 numbering. - * \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 -{ - checkAllocated(); - MEDCouplingAutoRefCountObjectPtr ret=DataArrayDouble::New(); - int nbComp=getNumberOfComponents(); - int oldNbOfTuples=getNumberOfTuples(); - ret->alloc((int)std::distance(new2OldBg,new2OldEnd),nbComp); - ret->copyStringInfoFrom(*this); - double *pt=ret->getPointer(); - const double *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 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 numbering. - * \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 -{ - checkAllocated(); - MEDCouplingAutoRefCountObjectPtr ret=DataArrayDouble::New(); - int nbComp=getNumberOfComponents(); - 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); - return ret.retn(); -} - -/*! - * 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 numbering. - * \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. - */ -DataArray *DataArrayDouble::selectByTupleRanges(const std::vector >& ranges) const -{ - checkAllocated(); - int nbOfComp=getNumberOfComponents(); - int nbOfTuplesThis=getNumberOfTuples(); - if(ranges.empty()) - { - DataArrayDouble *ret=DataArrayDouble::New(); - ret->alloc(0,nbOfComp); - ret->copyStringInfoFrom(*this); - return ret; - } - 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 << "DataArrayDouble::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 << "DataArrayDouble::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=DataArrayDouble::New(); - ret->alloc(nbOfTuples,nbOfComp); - ret->copyStringInfoFrom(*this); - const double *src=getConstPointer(); - double *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 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 -{ - checkAllocated(); - int nbt=getNumberOfTuples(); - if(tupleIdBg<0) - throw INTERP_KERNEL::Exception("DataArrayDouble::substr : The tupleIdBg parameter must be greater than 0 !"); - if(tupleIdBg>nbt) - throw INTERP_KERNEL::Exception("DataArrayDouble::substr : The tupleIdBg parameter is greater than number of tuples !"); - int trueEnd=tupleIdEnd; - if(tupleIdEnd!=-1) - { - if(tupleIdEnd>nbt) - throw INTERP_KERNEL::Exception("DataArrayDouble::substr : The tupleIdBg parameter is greater or equal than number of tuples !"); - } - else - trueEnd=nbt; - int nbComp=getNumberOfComponents(); - MEDCouplingAutoRefCountObjectPtr ret=DataArrayDouble::New(); - 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. - */ -DataArrayDouble *DataArrayDouble::changeNbOfComponents(int newNbOfComp, double dftValue) const -{ - checkAllocated(); - MEDCouplingAutoRefCountObjectPtr ret=DataArrayDouble::New(); - ret->alloc(getNumberOfTuples(),newNbOfComp); - const double *oldc=getConstPointer(); - double *nc=ret->getPointer(); - int nbOfTuples=getNumberOfTuples(); - int oldNbOfComp=getNumberOfComponents(); - int dim=std::min(oldNbOfComp,newNbOfComp); - for(int i=0;isetName(getName()); - for(int i=0;isetInfoOnComponent(i,getInfoOnComponent(i)); - ret->setName(getName()); - return ret.retn(); -} - -/*! - * 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) -{ - checkAllocated(); - 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 !"); - 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(); -} - -/*! - * 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() -{ - checkAllocated(); - int nbOfTuples=getNumberOfTuples(); - rearrange(nbOfTuples); -} - -/*! - * 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(). - * - * \if ENABLE_EXAMPLES - * \ref py_mcdataarraydouble_KeepSelectedComponents "Here is a Python example". - * \endif - */ -DataArrayDouble *DataArrayDouble::keepSelectedComponents(const std::vector& compoIds) const -{ - checkAllocated(); - MEDCouplingAutoRefCountObjectPtr ret(DataArrayDouble::New()); - std::size_t newNbOfCompo=compoIds.size(); - int oldNbOfCompo=getNumberOfComponents(); - for(std::vector::const_iterator it=compoIds.begin();it!=compoIds.end();it++) - if((*it)<0 || (*it)>=oldNbOfCompo) - { - std::ostringstream oss; oss << "DataArrayDouble::keepSelectedComponents : invalid requested component : " << *it << " whereas it should be in [0," << oldNbOfCompo << ") !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - int nbOfTuples=getNumberOfTuples(); - ret->alloc(nbOfTuples,(int)newNbOfCompo); - ret->copyPartOfStringInfoFrom(*this,compoIds); - const double *oldc=getConstPointer(); - double *nc=ret->getPointer(); - for(int i=0;icheckAllocated(); - int nbOfTuples=getNumberOfTuples(); - if(nbOfTuples!=other->getNumberOfTuples()) - throw INTERP_KERNEL::Exception("DataArrayDouble::meldWith : mismatch of number of tuples !"); - int nbOfComp1=getNumberOfComponents(); - int nbOfComp2=other->getNumberOfComponents(); - double *newArr=(double *)malloc((nbOfTuples*(nbOfComp1+nbOfComp2))*sizeof(double)); - double *w=newArr; - const double *inp1=getConstPointer(); - const double *inp2=other->getConstPointer(); - for(int i=0;i compIds(nbOfComp2); - for(int i=0;igetNumberOfTuples() ) tuple #i in \a other is equal ( regarding input precision \a prec ) to tuple tupleIds[i] in \a this. - * - * \param [in] other - the array having the same number of components than \a this. - * \param [out] tupleIds - the tuple ids containing the same number of tuples than \a other has. - * \sa DataArrayDouble::findCommonTuples - */ -bool DataArrayDouble::areIncludedInMe(const DataArrayDouble *other, double prec, DataArrayInt *&tupleIds) const -{ - if(!other) - throw INTERP_KERNEL::Exception("DataArrayDouble::areIncludedInMe : input array is NULL !"); - checkAllocated(); other->checkAllocated(); - if(getNumberOfComponents()!=other->getNumberOfComponents()) - throw INTERP_KERNEL::Exception("DataArrayDouble::areIncludedInMe : the number of components does not match !"); - MEDCouplingAutoRefCountObjectPtr a=DataArrayDouble::Aggregate(this,other); - DataArrayInt *c=0,*ci=0; - a->findCommonTuples(prec,getNumberOfTuples(),c,ci); - MEDCouplingAutoRefCountObjectPtr cSafe(c),ciSafe(ci); - int newNbOfTuples=-1; - MEDCouplingAutoRefCountObjectPtr ids=DataArrayInt::BuildOld2NewArrayFromSurjectiveFormat2(a->getNumberOfTuples(),c->begin(),ci->begin(),ci->end(),newNbOfTuples); - MEDCouplingAutoRefCountObjectPtr ret1=ids->selectByTupleId2(getNumberOfTuples(),a->getNumberOfTuples(),1); - tupleIds=ret1.retn(); - return newNbOfTuples==getNumberOfTuples(); -} - -/*! - * Searches for tuples coincident within \a prec tolerance. Each tuple is considered - * as coordinates of a point in getNumberOfComponents()-dimensional space. The - * distance separating two points is computed with the infinite norm. - * - * 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,4]. - * - * \if ENABLE_EXAMPLES - * \ref cpp_mcdataarraydouble_findcommontuples "Here is a C++ example". - * - * \ref py_mcdataarraydouble_findcommontuples "Here is a Python example". - * \endif - * \sa DataArrayInt::BuildOld2NewArrayFromSurjectiveFormat2(), DataArrayDouble::areIncludedInMe - */ -void DataArrayDouble::findCommonTuples(double prec, int limitTupleId, DataArrayInt *&comm, DataArrayInt *&commIndex) const -{ - checkAllocated(); - int nbOfCompo=getNumberOfComponents(); - if ((nbOfCompo<1) || (nbOfCompo>4)) //test before work - throw INTERP_KERNEL::Exception("DataArrayDouble::findCommonTuples : Unexpected spacedim of coords. Must be 1, 2, 3 or 4."); - - int nbOfTuples=getNumberOfTuples(); - // - MEDCouplingAutoRefCountObjectPtr c(DataArrayInt::New()),cI(DataArrayInt::New()); c->alloc(0,1); cI->pushBackSilent(0); - switch(nbOfCompo) - { - case 4: - findCommonTuplesAlg<4>(begin(),nbOfTuples,limitTupleId,prec,c,cI); - break; - case 3: - findCommonTuplesAlg<3>(begin(),nbOfTuples,limitTupleId,prec,c,cI); - break; - case 2: - findCommonTuplesAlg<2>(begin(),nbOfTuples,limitTupleId,prec,c,cI); - break; - case 1: - findCommonTuplesAlg<1>(begin(),nbOfTuples,limitTupleId,prec,c,cI); - break; - default: - throw INTERP_KERNEL::Exception("DataArrayDouble::findCommonTuples : nb of components managed are 1,2,3 and 4 ! not implemented for other number of components !"); - } - comm=c.retn(); - commIndex=cI.retn(); -} - -/*! - * - * \param [in] nbTimes specifies the nb of times each tuples in \a this will be duplicated contiguouly in returned DataArrayDouble instance. - * \a nbTimes should be at least equal to 1. - * \return a newly allocated DataArrayDouble having one component and number of tuples equal to \a nbTimes * \c this->getNumberOfTuples. - * \throw if \a this is not allocated or if \a this has not number of components set to one or if \a nbTimes is lower than 1. - */ -DataArrayDouble *DataArrayDouble::duplicateEachTupleNTimes(int nbTimes) const -{ - checkAllocated(); - if(getNumberOfComponents()!=1) - throw INTERP_KERNEL::Exception("DataArrayDouble::duplicateEachTupleNTimes : this should have only one component !"); - if(nbTimes<1) - throw INTERP_KERNEL::Exception("DataArrayDouble::duplicateEachTupleNTimes : nb times should be >= 1 !"); - int nbTuples=getNumberOfTuples(); - const double *inPtr=getConstPointer(); - MEDCouplingAutoRefCountObjectPtr ret=DataArrayDouble::New(); ret->alloc(nbTimes*nbTuples,1); - double *retPtr=ret->getPointer(); - for(int i=0;icopyStringInfoFrom(*this); - return ret.retn(); -} - -/*! - * 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 [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 - */ -double DataArrayDouble::minimalDistanceTo(const DataArrayDouble *other, int& thisTupleId, int& otherTupleId) const -{ - 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 -{ - 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(); -} - -/*! - * This method expects that \a this and \a otherBBoxFrmt arrays are bounding box arrays ( as the output of MEDCouplingPointSet::getBoundingBoxForBBTree method ). - * This method will return a DataArrayInt array having the same number of tuples than \a this. This returned array tells for each cell in \a this - * how many bounding boxes in \a otherBBoxFrmt. - * So, this method expects that \a this and \a otherBBoxFrmt have the same number of components. - * - * \param [in] otherBBoxFrmt - It is an array . - * \param [in] eps - the absolute precision of the detection. when eps < 0 the bboxes are enlarged so more interactions are detected. Inversely when > 0 the bboxes are stretched. - * \sa MEDCouplingPointSet::getBoundingBoxForBBTree - * \throw If \a this and \a otherBBoxFrmt have not the same number of components. - * \throw If \a this and \a otherBBoxFrmt number of components is not even (BBox format). - */ -DataArrayInt *DataArrayDouble::computeNbOfInteractionsWith(const DataArrayDouble *otherBBoxFrmt, double eps) const -{ - if(!otherBBoxFrmt) - throw INTERP_KERNEL::Exception("DataArrayDouble::computeNbOfInteractionsWith : input array is NULL !"); - if(!isAllocated() || !otherBBoxFrmt->isAllocated()) - throw INTERP_KERNEL::Exception("DataArrayDouble::computeNbOfInteractionsWith : this and input array must be allocated !"); - int nbOfComp(getNumberOfComponents()),nbOfTuples(getNumberOfTuples()); - if(nbOfComp!=otherBBoxFrmt->getNumberOfComponents()) - { - std::ostringstream oss; oss << "DataArrayDouble::computeNbOfInteractionsWith : this number of components (" << nbOfComp << ") must be equal to the number of components of input array (" << otherBBoxFrmt->getNumberOfComponents() << ") !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - if(nbOfComp%2!=0) - { - std::ostringstream oss; oss << "DataArrayDouble::computeNbOfInteractionsWith : Number of components (" << nbOfComp << ") is not even ! It should be to be compatible with bbox format !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - MEDCouplingAutoRefCountObjectPtr ret(DataArrayInt::New()); ret->alloc(nbOfTuples,1); - const double *thisBBPtr(begin()); - int *retPtr(ret->getPointer()); - switch(nbOfComp/2) - { - case 3: - { - BBTree<3,int> bbt(otherBBoxFrmt->begin(),0,0,otherBBoxFrmt->getNumberOfTuples(),eps); - for(int i=0;i bbt(otherBBoxFrmt->begin(),0,0,otherBBoxFrmt->getNumberOfTuples(),eps); - for(int i=0;i bbt(otherBBoxFrmt->begin(),0,0,otherBBoxFrmt->getNumberOfTuples(),eps); - for(int i=0;i 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(). - * - * \if ENABLE_EXAMPLES - * \ref py_mcdataarraydouble_setselectedcomponents "Here is a Python example". - * \endif - */ -void DataArrayDouble::setSelectedComponents(const DataArrayDouble *a, const std::vector& compoIds) -{ - 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=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)). - * - * \if ENABLE_EXAMPLES - * \ref py_mcdataarraydouble_setpartofvalues1 "Here is a Python example". - * \endif - */ -void DataArrayDouble::setPartOfValues1(const DataArrayDouble *a, int bgTuples, int endTuples, int stepTuples, int bgComp, int endComp, int stepComp, bool strictCompoCompare) -{ - if(!a) - throw INTERP_KERNEL::Exception("DataArrayDouble::setPartOfValues1 : input DataArrayDouble is NULL !"); - const char msg[]="DataArrayDouble::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; - } - const double *srcPt=a->getConstPointer(); - double *pt=getPointer()+bgTuples*nbComp+bgComp; - 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). - * - * \if ENABLE_EXAMPLES - * \ref py_mcdataarraydouble_setpartofvalues2 "Here is a Python example". - * \endif - */ -void DataArrayDouble::setPartOfValues2(const DataArrayDouble *a, const int *bgTuples, const int *endTuples, const int *bgComp, const int *endComp, bool strictCompoCompare) -{ - if(!a) - throw INTERP_KERNEL::Exception("DataArrayDouble::setPartOfValues2 : input DataArrayDouble is NULL !"); - const char msg[]="DataArrayDouble::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; - } - double *pt=getPointer(); - const double *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 double *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. - * - * \if ENABLE_EXAMPLES - * \ref py_mcdataarraydouble_setpartofvaluessimple2 "Here is a Python example". - * \endif - */ -void DataArrayDouble::setPartOfValuesSimple2(double a, const int *bgTuples, const int *endTuples, const int *bgComp, const int *endComp) -{ - checkAllocated(); - int nbComp=getNumberOfComponents(); - int nbOfTuples=getNumberOfTuples(); - for(const int *z=bgComp;z!=endComp;z++) - DataArray::CheckValueInRange(nbComp,*z,"invalid component id"); - double *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 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 \c this array. - * - * \if ENABLE_EXAMPLES - * \ref py_mcdataarraydouble_setpartofvalues3 "Here is a Python example". - * \endif - */ -void DataArrayDouble::setPartOfValues3(const DataArrayDouble *a, const int *bgTuples, const int *endTuples, int bgComp, int endComp, int stepComp, bool strictCompoCompare) -{ - if(!a) - throw INTERP_KERNEL::Exception("DataArrayDouble::setPartOfValues3 : input DataArrayDouble is NULL !"); - const char msg[]="DataArrayDouble::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; - } - double *pt=getPointer()+bgComp; - const double *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 \c this array. - * - * \if ENABLE_EXAMPLES - * \ref py_mcdataarraydouble_setpartofvaluessimple3 "Here is a Python example". - * \endif - */ -void DataArrayDouble::setPartOfValuesSimple3(double a, const int *bgTuples, const int *endTuples, int bgComp, int endComp, int stepComp) -{ - const char msg[]="DataArrayDouble::setPartOfValuesSimple3"; - checkAllocated(); - int newNbOfComp=DataArray::GetNumberOfItemGivenBES(bgComp,endComp,stepComp,msg); - int nbComp=getNumberOfComponents(); - int nbOfTuples=getNumberOfTuples(); - DataArray::CheckValueInRangeEx(nbComp,bgComp,endComp,"invalid component value"); - double *pt=getPointer()+bgComp; - for(const int *w=bgTuples;w!=endTuples;w++) - 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::setPartOfValues4(const DataArrayDouble *a, int bgTuples, int endTuples, int stepTuples, const int *bgComp, const int *endComp, bool strictCompoCompare) -{ - 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) -{ - if(!a || !tuplesSelec) - throw INTERP_KERNEL::Exception("DataArrayDouble::setPartOfValuesAdv : input DataArrayDouble is NULL !"); - checkAllocated(); - a->checkAllocated(); - tuplesSelec->checkAllocated(); - int nbOfComp=getNumberOfComponents(); - if(nbOfComp!=a->getNumberOfComponents()) - throw INTERP_KERNEL::Exception("DataArrayDouble::setPartOfValuesAdv : This and a do not have the same number of components !"); - if(tuplesSelec->getNumberOfComponents()!=2) - throw INTERP_KERNEL::Exception("DataArrayDouble::setPartOfValuesAdv : Expecting to have a tuple selector DataArrayInt instance with exactly 2 components !"); - int thisNt=getNumberOfTuples(); - int aNt=a->getNumberOfTuples(); - double *valsToSet=getPointer(); - const double *valsSrc=a->getConstPointer(); - for(const int *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 << "DataArrayDouble::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 DataArrayDouble (\a aBase) 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] aBase - 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 aBase is NULL. - * \throw If \a aBase is not allocated. - * \throw If \a tuplesSelec is NULL. - * \throw If \a tuplesSelec is not allocated. - * \throw If this->getNumberOfComponents() != aBase->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 aBase array. - */ -void DataArrayDouble::setContigPartOfSelectedValues(int tupleIdStart, const DataArray *aBase, const DataArrayInt *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(); - int nbOfComp=getNumberOfComponents(); - if(nbOfComp!=a->getNumberOfComponents()) - throw INTERP_KERNEL::Exception("DataArrayDouble::setContigPartOfSelectedValues : This and a do not have the same number of components !"); - if(tuplesSelec->getNumberOfComponents()!=1) - throw INTERP_KERNEL::Exception("DataArrayDouble::setContigPartOfSelectedValues : Expecting to have a tuple selector DataArrayInt instance with exactly 1 component !"); - int thisNt=getNumberOfTuples(); - int aNt=a->getNumberOfTuples(); - int nbOfTupleToWrite=tuplesSelec->getNumberOfTuples(); - double *valsToSet=getPointer()+tupleIdStart*nbOfComp; - if(tupleIdStart+nbOfTupleToWrite>thisNt) - throw INTERP_KERNEL::Exception("DataArrayDouble::setContigPartOfSelectedValues : invalid number range of values to write !"); - const double *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 DataArrayDouble (\a aBase) 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] aBase - the array to copy values from. - * \param [in] bg - index of the first tuple to copy of the array \a aBase. - * \param [in] end2 - index of the tuple of \a aBase 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 aBase is NULL. - * \throw If \a aBase is not allocated. - * \throw If this->getNumberOfComponents() != aBase->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 aBase. - */ -void DataArrayDouble::setContigPartOfSelectedValues2(int tupleIdStart, const DataArray *aBase, int bg, int end2, int step) -{ - 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 DataArray aBase is not a DataArrayDouble !"); - checkAllocated(); - a->checkAllocated(); - int nbOfComp=getNumberOfComponents(); - const char msg[]="DataArrayDouble::setContigPartOfSelectedValues2"; - int nbOfTupleToWrite=DataArray::GetNumberOfItemGivenBES(bg,end2,step,msg); - if(nbOfComp!=a->getNumberOfComponents()) - throw INTERP_KERNEL::Exception("DataArrayDouble::setContigPartOfSelectedValues2 : This and a do not have the same number of components !"); - int thisNt=getNumberOfTuples(); - int aNt=a->getNumberOfTuples(); - double *valsToSet=getPointer()+tupleIdStart*nbOfComp; - if(tupleIdStart+nbOfTupleToWrite>thisNt) - throw INTERP_KERNEL::Exception("DataArrayDouble::setContigPartOfSelectedValues2 : invalid number range of values to write !"); - if(end2>aNt) - throw INTERP_KERNEL::Exception("DataArrayDouble::setContigPartOfSelectedValues2 : invalid range of values to read !"); - const double *valsSrc=a->getConstPointer()+bg*nbOfComp; - for(int i=0;i( 0 <= tupleId < this->getNumberOfTuples() ) is violated. - * \throw If condition ( 0 <= compoId < this->getNumberOfComponents() ) is violated. - */ -double DataArrayDouble::getIJSafe(int tupleId, int compoId) const -{ - checkAllocated(); - if(tupleId<0 || tupleId>=getNumberOfTuples()) - { - std::ostringstream oss; oss << "DataArrayDouble::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 << "DataArrayDouble::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 first 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::front() const -{ - checkAllocated(); - if(getNumberOfComponents()!=1) - throw INTERP_KERNEL::Exception("DataArrayDouble::front : number of components not equal to one !"); - int nbOfTuples=getNumberOfTuples(); - if(nbOfTuples<1) - throw INTERP_KERNEL::Exception("DataArrayDouble::front : number of tuples must be >= 1 !"); - return *(getConstPointer()); -} - -/*! - * 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 -{ - checkAllocated(); - if(getNumberOfComponents()!=1) - throw INTERP_KERNEL::Exception("DataArrayDouble::back : number of components not equal to one !"); - int nbOfTuples=getNumberOfTuples(); - if(nbOfTuples<1) - throw INTERP_KERNEL::Exception("DataArrayDouble::back : number of tuples must be >= 1 !"); - return *(getConstPointer()+nbOfTuples-1); -} - -void DataArrayDouble::SetArrayIn(DataArrayDouble *newArray, DataArrayDouble* &arrayToSet) -{ - if(newArray!=arrayToSet) - { - if(arrayToSet) - arrayToSet->decrRef(); - arrayToSet=newArray; - if(arrayToSet) - arrayToSet->incrRef(); - } -} - -/*! - * 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) -{ - _info_on_compo.resize(nbOfCompo); - _mem.useArray(array,ownership,type,(std::size_t)nbOfTuple*nbOfCompo); - declareAsNew(); -} - -void DataArrayDouble::useExternalArrayWithRWAccess(const double *array, int nbOfTuple, int nbOfCompo) -{ - _info_on_compo.resize(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 -{ - const double *tmp=getConstPointer(); - 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 !"); -} - -/*! - * 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 -{ - checkAllocated(); - int dim=getNumberOfComponents(); - for (int idim=0; idim::max(); - bounds[idim*2+1]=-std::numeric_limits::max(); - } - const double *ptr=getConstPointer(); - int nbOfTuples=getNumberOfTuples(); - for(int i=0;iptr[i*dim+idim]) - { - bounds[idim*2]=ptr[i*dim+idim]; - } - if(bounds[idim*2+1]getNumberOfTuples() tuples and 2 * \c this->getNumberOfComponent() components - * - * \throw If \a this is not allocated yet. - */ -DataArrayDouble *DataArrayDouble::computeBBoxPerTuple(double epsilon) const -{ - checkAllocated(); - const double *dataPtr=getConstPointer(); - int nbOfCompo=getNumberOfComponents(); - int nbTuples=getNumberOfTuples(); - MEDCouplingAutoRefCountObjectPtr bbox=DataArrayDouble::New(); - bbox->alloc(nbTuples,2*nbOfCompo); - double *bboxPtr=bbox->getPointer(); - for(int i=0;icheckAllocated(); - 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(); - MEDCouplingAutoRefCountObjectPtr cArr(DataArrayInt::New()),cIArr(DataArrayInt::New()); cArr->alloc(0,1); cIArr->pushBackSilent(0); - switch(nbOfCompo) - { - case 3: - { - BBTreePts<3,int> myTree(begin(),0,0,getNumberOfTuples(),eps); - FindTupleIdsNearTuplesAlg<3>(myTree,other->getConstPointer(),nbOfTuplesOther,eps,cArr,cIArr); - break; - } - case 2: - { - BBTreePts<2,int> myTree(begin(),0,0,getNumberOfTuples(),eps); - FindTupleIdsNearTuplesAlg<2>(myTree,other->getConstPointer(),nbOfTuplesOther,eps,cArr,cIArr); - break; - } - case 1: - { - 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(); -} - -/*! - * This method recenter tuples in \b this in order to be centered at the origin to benefit about the advantages of maximal precision to be around the box - * around origin of 'radius' 1. - * - * \param [in] eps absolute epsilon. under that value of delta between max and min no scale is performed. - */ -void DataArrayDouble::recenterForMaxPrecision(double eps) -{ - checkAllocated(); - int dim=getNumberOfComponents(); - std::vector bounds(2*dim); - getMinMaxPerComponent(&bounds[0]); - for(int i=0;ieps) - applyLin(1./delta,-offset/delta,i); - else - applyLin(1.,-offset,i); - } -} - -/*! - * 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 -{ - 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(); - if(nbOfTuples<=0) - throw INTERP_KERNEL::Exception("DataArrayDouble::getMaxValue : array exists but number of tuples must be > 0 !"); - const double *vals=getConstPointer(); - const double *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 double - the maximal value among all values of \a this array. - * \throw If \a this is not allocated. - */ -double DataArrayDouble::getMaxValueInArray() const -{ - checkAllocated(); - const double *loc=std::max_element(begin(),end()); - 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 -{ - int tmp; - tupleIds=0; - double ret=getMaxValue(tmp); - tupleIds=getIdsInRange(ret,ret); - 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 -{ - 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(); - if(nbOfTuples<=0) - throw INTERP_KERNEL::Exception("DataArrayDouble::getMinValue : array exists but number of tuples must be > 0 !"); - const double *vals=getConstPointer(); - const double *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 double - the minimal value among all values of \a this array. - * \throw If \a this is not allocated. - */ -double DataArrayDouble::getMinValueInArray() const -{ - checkAllocated(); - const double *loc=std::min_element(begin(),end()); - 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 -{ - int tmp; - tupleIds=0; - double ret=getMinValue(tmp); - tupleIds=getIdsInRange(ret,ret); - 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 -{ - 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 -{ - if(getNumberOfComponents()!=1) - throw INTERP_KERNEL::Exception("DataArrayDouble::getAverageValue : must be applied on DataArrayDouble with only one component, you can call 'rearrange' method before !"); - int nbOfTuples=getNumberOfTuples(); - if(nbOfTuples<=0) - throw INTERP_KERNEL::Exception("DataArrayDouble::getAverageValue : array exists but number of tuples must be > 0 !"); - const double *vals=getConstPointer(); - double ret=std::accumulate(vals,vals+nbOfTuples,0.); - 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 -{ - checkAllocated(); - double ret=0.; - std::size_t nbOfElems=getNbOfElems(); - const double *pt=getConstPointer(); - for(std::size_t i=0;iret) - ret=val; - } - return ret; -} - -/*! - * Returns the minimum norm (absolute value) of the vector defined by \a this array. - * This method works even if the number of components is diferent from one. - * If the number of elements in \a this is 0, std::numeric_limits::max() is returned. - * \return double - the value of the minimum norm, i.e. - * the minimal absolute value among values of \a this array (whatever its number of components). - * \throw If \a this is not allocated. - */ -double DataArrayDouble::normMin() const -{ - checkAllocated(); - double ret(std::numeric_limits::max()); - std::size_t nbOfElems(getNbOfElems()); - const double *pt(getConstPointer()); - for(std::size_t i=0;igetNumberOfComponents(), 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 -{ - checkAllocated(); - const double *ptr=getConstPointer(); - int nbTuple=getNumberOfTuples(); - int nbComps=getNumberOfComponents(); - std::fill(res,res+nbComps,0.); - for(int i=0;i()); -} - -/*! - * 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 -{ - 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 -{ - checkAllocated(); - const double *ptr=getConstPointer(); - int nbTuple=getNumberOfTuples(); - int nbComps=getNumberOfComponents(); - 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 -{ - 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 -{ - checkAllocated(); - int nbOfComp=getNumberOfComponents(); - if(nbOfComp!=2) - throw INTERP_KERNEL::Exception("DataArrayDouble::fromPolarToCart : must be an array with exactly 2 components !"); - int nbOfTuple=getNumberOfTuples(); - DataArrayDouble *ret=DataArrayDouble::New(); - ret->alloc(nbOfTuple,2); - double *w=ret->getPointer(); - const double *wIn=getConstPointer(); - for(int i=0;igetNumberOfComponents() != 3. - */ -DataArrayDouble *DataArrayDouble::fromCylToCart() const -{ - checkAllocated(); - int nbOfComp=getNumberOfComponents(); - if(nbOfComp!=3) - throw INTERP_KERNEL::Exception("DataArrayDouble::fromCylToCart : must be an array with exactly 3 components !"); - int nbOfTuple=getNumberOfTuples(); - DataArrayDouble *ret=DataArrayDouble::New(); - ret->alloc(getNumberOfTuples(),3); - double *w=ret->getPointer(); - const double *wIn=getConstPointer(); - for(int i=0;isetInfoOnComponent(2,getInfoOnComponent(2)); - 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 -{ - checkAllocated(); - int nbOfComp=getNumberOfComponents(); - if(nbOfComp!=3) - throw INTERP_KERNEL::Exception("DataArrayDouble::fromSpherToCart : must be an array with exactly 3 components !"); - int nbOfTuple=getNumberOfTuples(); - DataArrayDouble *ret=DataArrayDouble::New(); - ret->alloc(getNumberOfTuples(),3); - double *w=ret->getPointer(); - const double *wIn=getConstPointer(); - for(int i=0;i(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 -{ - checkAllocated(); - int nbOfComp=getNumberOfComponents(); - if(nbOfComp!=6) - throw INTERP_KERNEL::Exception("DataArrayDouble::doublyContractedProduct : must be an array with exactly 6 components !"); - DataArrayDouble *ret=DataArrayDouble::New(); - int nbOfTuple=getNumberOfTuples(); - ret->alloc(nbOfTuple,1); - const double *src=getConstPointer(); - double *dest=ret->getPointer(); - for(int i=0;igetNumberOfComponents() is not in [4,6,9]. - */ -DataArrayDouble *DataArrayDouble::determinant() const -{ - checkAllocated(); - DataArrayDouble *ret=DataArrayDouble::New(); - int nbOfTuple=getNumberOfTuples(); - ret->alloc(nbOfTuple,1); - const double *src=getConstPointer(); - double *dest=ret->getPointer(); - switch(getNumberOfComponents()) - { - case 6: - for(int i=0;idecrRef(); - throw INTERP_KERNEL::Exception("DataArrayDouble::determinant : Invalid number of components ! must be in 4,6,9 !"); - } -} - -/*! - * 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 -{ - checkAllocated(); - int nbOfComp=getNumberOfComponents(); - if(nbOfComp!=6) - throw INTERP_KERNEL::Exception("DataArrayDouble::eigenValues : must be an array with exactly 6 components !"); - DataArrayDouble *ret=DataArrayDouble::New(); - int nbOfTuple=getNumberOfTuples(); - ret->alloc(nbOfTuple,3); - const double *src=getConstPointer(); - double *dest=ret->getPointer(); - for(int i=0;igetNumberOfComponents() != 6. - */ -DataArrayDouble *DataArrayDouble::eigenVectors() const -{ - checkAllocated(); - int nbOfComp=getNumberOfComponents(); - if(nbOfComp!=6) - throw INTERP_KERNEL::Exception("DataArrayDouble::eigenVectors : must be an array with exactly 6 components !"); - DataArrayDouble *ret=DataArrayDouble::New(); - int nbOfTuple=getNumberOfTuples(); - ret->alloc(nbOfTuple,9); - const double *src=getConstPointer(); - double *dest=ret->getPointer(); - for(int i=0;igetNumberOfComponents() is not in [4,6,9]. - */ -DataArrayDouble *DataArrayDouble::inverse() const -{ - 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 !"); - DataArrayDouble *ret=DataArrayDouble::New(); - int nbOfTuple=getNumberOfTuples(); - ret->alloc(nbOfTuple,nbOfComp); - const double *src=getConstPointer(); - double *dest=ret->getPointer(); - if(nbOfComp==6) - for(int i=0;igetNumberOfComponents() is not in [4,6,9]. - */ -DataArrayDouble *DataArrayDouble::trace() const -{ - 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 !"); - DataArrayDouble *ret=DataArrayDouble::New(); - int nbOfTuple=getNumberOfTuples(); - ret->alloc(nbOfTuple,1); - const double *src=getConstPointer(); - double *dest=ret->getPointer(); - if(nbOfComp==6) - for(int i=0;igetNumberOfComponents() != 6. - */ -DataArrayDouble *DataArrayDouble::deviator() const -{ - checkAllocated(); - int nbOfComp=getNumberOfComponents(); - if(nbOfComp!=6) - throw INTERP_KERNEL::Exception("DataArrayDouble::deviator : must be an array with exactly 6 components !"); - DataArrayDouble *ret=DataArrayDouble::New(); - int nbOfTuple=getNumberOfTuples(); - ret->alloc(nbOfTuple,6); - const double *src=getConstPointer(); - double *dest=ret->getPointer(); - for(int i=0;ialloc(nbOfTuple,1); - const double *src=getConstPointer(); - double *dest=ret->getPointer(); - for(int i=0;i ret(DataArrayDouble::New()); - ret->alloc(nbOfTuple,1); - const double *src(getConstPointer()); - double *dest(ret->getPointer()); - for(int i=0;i ret=DataArrayDouble::New(); - int nbOfTuple=getNumberOfTuples(); - ret->alloc(nbOfTuple,1); - const double *src=getConstPointer(); - double *dest=ret->getPointer(); - for(int i=0;i 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. - * - * \throw If \a this is not allocated. - * - * \sa DataArrayDouble::buildEuclidianDistanceDenseMatrixWith - */ -DataArrayDouble *DataArrayDouble::buildEuclidianDistanceDenseMatrix() const -{ - checkAllocated(); - int nbOfComp=getNumberOfComponents(); - int nbOfTuples=getNumberOfTuples(); - const double *inData=getConstPointer(); - MEDCouplingAutoRefCountObjectPtr ret=DataArrayDouble::New(); - ret->alloc(nbOfTuples*nbOfTuples,1); - double *outData=ret->getPointer(); - for(int i=0;igetNumberOfTuples() * \c other->getNumberOfTuples() tuples. - * \n This returned array contains the euclidian distance for each tuple in \a other with each tuple in \a this. - * \n So the returned array can be seen as a dense rectangular matrix with \c other->getNumberOfTuples() rows and \c this->getNumberOfTuples() columns. - * \n Output rectangular matrix is sorted along rows. - * \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 ! - * - * \param [in] other DataArrayDouble instance having same number of components than \a this. - * \return A newly allocated (huge) ParaMEDMEM::DataArrayDouble instance that the caller should deal with. - * - * \throw If \a this is not allocated, or if \a other is null or if \a other is not allocated, or if number of components of \a other and \a this differs. - * - * \sa DataArrayDouble::buildEuclidianDistanceDenseMatrix - */ -DataArrayDouble *DataArrayDouble::buildEuclidianDistanceDenseMatrixWith(const DataArrayDouble *other) const -{ - if(!other) - throw INTERP_KERNEL::Exception("DataArrayDouble::buildEuclidianDistanceDenseMatrixWith : input parameter is null !"); - checkAllocated(); - other->checkAllocated(); - int nbOfComp=getNumberOfComponents(); - int otherNbOfComp=other->getNumberOfComponents(); - if(nbOfComp!=otherNbOfComp) - { - std::ostringstream oss; oss << "DataArrayDouble::buildEuclidianDistanceDenseMatrixWith : this nb of compo=" << nbOfComp << " and other nb of compo=" << otherNbOfComp << ". It should match !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - int nbOfTuples=getNumberOfTuples(); - int otherNbOfTuples=other->getNumberOfTuples(); - const double *inData=getConstPointer(); - const double *inDataOther=other->getConstPointer(); - MEDCouplingAutoRefCountObjectPtr ret=DataArrayDouble::New(); - ret->alloc(otherNbOfTuples*nbOfTuples,1); - double *outData=ret->getPointer(); - for(int i=0;i()); - declareAsNew(); -} - -/*! - * Converts every value of \a this array to its absolute value. - * \b WARNING this method is non const. If a new DataArrayDouble instance should be built containing the result of abs DataArrayDouble::computeAbs - * should be called instead. - * - * \throw If \a this is not allocated. - * \sa DataArrayDouble::computeAbs - */ -void DataArrayDouble::abs() -{ - checkAllocated(); - double *ptr(getPointer()); - std::size_t nbOfElems(getNbOfElems()); - std::transform(ptr,ptr+nbOfElems,ptr,std::ptr_fun(fabs)); - declareAsNew(); -} - -/*! - * This method builds a new instance of \a this object containing the result of std::abs applied of all elements in \a this. - * This method is a const method (that do not change any values in \a this) contrary to DataArrayDouble::abs method. - * - * \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. - * \sa DataArrayDouble::abs - */ -DataArrayDouble *DataArrayDouble::computeAbs() const -{ - checkAllocated(); - DataArrayDouble *newArr(DataArrayDouble::New()); - int nbOfTuples(getNumberOfTuples()); - int nbOfComp(getNumberOfComponents()); - newArr->alloc(nbOfTuples,nbOfComp); - std::transform(begin(),end(),newArr->getPointer(),std::ptr_fun(fabs)); - newArr->copyStringInfoFrom(*this); - return newArr; -} - -/*! - * Apply a linear 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, or \a compoId is not in [0,\c this->getNumberOfComponents() ). - */ -void DataArrayDouble::applyLin(double a, double b, int compoId) -{ - checkAllocated(); - double *ptr(getPointer()+compoId); - int nbOfComp(getNumberOfComponents()),nbOfTuple(getNumberOfTuples()); - if(compoId<0 || compoId>=nbOfComp) - { - std::ostringstream oss; oss << "DataArrayDouble::applyLin : The compoId requested (" << compoId << ") is not valid ! Must be in [0," << nbOfComp << ") !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - for(int i=0;istd::numeric_limits::min()) - { - *ptr=numerator/(*ptr); - } - else - { - std::ostringstream oss; oss << "DataArrayDouble::applyInv : presence of null value in tuple #" << i/getNumberOfComponents() << " component #" << i%getNumberOfComponents(); - oss << " !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - } - declareAsNew(); -} - -/*! - * 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 -{ - checkAllocated(); - DataArrayDouble *newArr=DataArrayDouble::New(); - int nbOfTuples=getNumberOfTuples(); - int nbOfComp=getNumberOfComponents(); - newArr->alloc(nbOfTuples,nbOfComp); - const double *cptr=getConstPointer(); - std::transform(cptr,cptr+nbOfTuples*nbOfComp,newArr->getPointer(),std::negate()); - newArr->copyStringInfoFrom(*this); - 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) -{ - 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;ialloc(nbOfTuples,nbOfComp); - const double *ptr=getConstPointer(); - double *ptrToFill=newArr->getPointer(); - for(int i=0;i(oss,", ")); - oss << ") : Evaluation of function failed !"; - newArr->decrRef(); - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - } - 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 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". - * \param [in] isSafe - By default true. If true invalid operation (division by 0. acos of value > 1. ...) leads to a throw of an exception. - * If false the computation is carried on without any notification. When false the evaluation is a little faster. - * \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 std::string& func, bool isSafe) const -{ - INTERP_KERNEL::ExprParser expr(func); - expr.parse(); - std::set vars; - expr.getTrueSetOfVars(vars); - std::vector varsV(vars.begin(),vars.end()); - return applyFunc3(nbOfComp,varsV,func,isSafe); -} - -/*! - * 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. This method works by tuples (whatever its size). - * If \a this is a one component array, call applyFuncOnThis instead that performs the same work faster. - * - * 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". - * \param [in] isSafe - By default true. If true invalid operation (division by 0. acos of value > 1. ...) leads to a throw of an exception. - * If false the computation is carried on without any notification. When false the evaluation is a little faster. - * \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. - * \sa applyFuncOnThis - * \throw If \a this is not allocated. - * \throw If computing \a func fails. - */ -DataArrayDouble *DataArrayDouble::applyFunc(const std::string& func, bool isSafe) const -{ - int nbOfComp(getNumberOfComponents()); - if(nbOfComp<=0) - throw INTERP_KERNEL::Exception("DataArrayDouble::applyFunc : output number of component must be > 0 !"); - checkAllocated(); - int nbOfTuples(getNumberOfTuples()); - MEDCouplingAutoRefCountObjectPtr newArr(DataArrayDouble::New()); - newArr->alloc(nbOfTuples,nbOfComp); - INTERP_KERNEL::ExprParser expr(func); - expr.parse(); - std::set vars; - expr.getTrueSetOfVars(vars); - if((int)vars.size()>1) - { - std::ostringstream oss; oss << "DataArrayDouble::applyFunc : this method works only with at most one var func expression ! If you need to map comps on variables please use applyFunc2 or applyFunc3 instead ! Vars in expr are : "; - std::copy(vars.begin(),vars.end(),std::ostream_iterator(oss," ")); - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - if(vars.empty()) - { - expr.prepareFastEvaluator(); - newArr->rearrange(1); - newArr->fillWithValue(expr.evaluateDouble()); - newArr->rearrange(nbOfComp); - return newArr.retn(); - } - std::vector vars2(vars.begin(),vars.end()); - double buff,*ptrToFill(newArr->getPointer()); - const double *ptr(begin()); - std::vector stck; - expr.prepareExprEvaluationDouble(vars2,1,1,0,&buff,&buff+1); - expr.prepareFastEvaluator(); - if(!isSafe) - { - for(int i=0;i 1. ...) leads to a throw of an exception. - * If false the computation is carried on without any notification. When false the evaluation is a little faster. - * - * \sa applyFunc - */ -void DataArrayDouble::applyFuncOnThis(const std::string& func, bool isSafe) -{ - int nbOfComp(getNumberOfComponents()); - if(nbOfComp<=0) - throw INTERP_KERNEL::Exception("DataArrayDouble::applyFuncOnThis : output number of component must be > 0 !"); - checkAllocated(); - int nbOfTuples(getNumberOfTuples()); - INTERP_KERNEL::ExprParser expr(func); - expr.parse(); - std::set vars; - expr.getTrueSetOfVars(vars); - if((int)vars.size()>1) - { - std::ostringstream oss; oss << "DataArrayDouble::applyFuncOnThis : this method works only with at most one var func expression ! If you need to map comps on variables please use applyFunc2 or applyFunc3 instead ! Vars in expr are : "; - std::copy(vars.begin(),vars.end(),std::ostream_iterator(oss," ")); - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - if(vars.empty()) - { - expr.prepareFastEvaluator(); - std::vector compInfo(getInfoOnComponents()); - rearrange(1); - fillWithValue(expr.evaluateDouble()); - rearrange(nbOfComp); - setInfoOnComponents(compInfo); - return ; - } - std::vector vars2(vars.begin(),vars.end()); - double buff,*ptrToFill(getPointer()); - const double *ptr(begin()); - std::vector stck; - expr.prepareExprEvaluationDouble(vars2,1,1,0,&buff,&buff+1); - expr.prepareFastEvaluator(); - if(!isSafe) - { - for(int i=0;i 1. ...) leads to a throw of an exception. - * If false the computation is carried on without any notification. When false the evaluation is a little faster. - * \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 std::string& func, bool isSafe) const -{ - return applyFunc3(nbOfComp,getVarsOnComponent(),func,isSafe); -} - -/*! - * 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". - * \param [in] isSafe - By default true. If true invalid operation (division by 0. acos of value > 1. ...) leads to a throw of an exception. - * If false the computation is carried on without any notification. When false the evaluation is a little faster. - * \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 std::string& func, bool isSafe) const -{ - if(nbOfComp<=0) - throw INTERP_KERNEL::Exception("DataArrayDouble::applyFunc3 : output number of component must be > 0 !"); - std::vector varsOrder2(varsOrder); - int oldNbOfComp(getNumberOfComponents()); - for(int i=(int)varsOrder.size();i vars; - expr.getTrueSetOfVars(vars); - if((int)vars.size()>oldNbOfComp) - { - std::ostringstream oss; oss << "The field has " << oldNbOfComp << " components and there are "; - oss << vars.size() << " variables : "; - std::copy(vars.begin(),vars.end(),std::ostream_iterator(oss," ")); - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - MEDCouplingAutoRefCountObjectPtr newArr(DataArrayDouble::New()); - newArr->alloc(nbOfTuples,nbOfComp); - INTERP_KERNEL::AutoPtr buff(new double[oldNbOfComp]); - double *buffPtr(buff),*ptrToFill; - std::vector stck; - for(int iComp=0;iCompgetPointer()+iComp; - if(!isSafe) - { - for(int i=0;i(oss,", ")); - oss << ") : Evaluation of function failed !" << e.what(); - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - } - } - } - return newArr.retn(); -} - -void DataArrayDouble::applyFuncFast32(const std::string& func) -{ - checkAllocated(); - INTERP_KERNEL::ExprParser expr(func); - expr.parse(); - char *funcStr=expr.compileX86(); - MYFUNCPTR funcPtr; - *((void **)&funcPtr)=funcStr;//he he... - // - double *ptr=getPointer(); - int nbOfComp=getNumberOfComponents(); - int nbOfTuples=getNumberOfTuples(); - int nbOfElems=nbOfTuples*nbOfComp; - for(int i=0;igetNumberOfComponents() != 1. - * - * \sa DataArrayDouble::getIdsNotInRange - * - * \if ENABLE_EXAMPLES - * \ref cpp_mcdataarraydouble_getidsinrange "Here is a C++ example".
- * \ref py_mcdataarraydouble_getidsinrange "Here is a Python example". - * \endif - */ -DataArrayInt *DataArrayDouble::getIdsInRange(double vmin, double vmax) const -{ - checkAllocated(); - if(getNumberOfComponents()!=1) - throw INTERP_KERNEL::Exception("DataArrayDouble::getIdsInRange : this must have exactly one component !"); - const double *cptr(begin()); - MEDCouplingAutoRefCountObjectPtr ret(DataArrayInt::New()); ret->alloc(0,1); - int nbOfTuples(getNumberOfTuples()); - for(int i=0;i=vmin && *cptr<=vmax) - ret->pushBackSilent(i); - return ret.retn(); -} - -/*! - * Returns a new DataArrayInt contating indices of tuples of \a this one-dimensional - * array whose values are not within a given range. Textual data is not copied. - * \param [in] vmin - a lowest not acceptable value (excluded). - * \param [in] vmax - a greatest not acceptable value (excluded). - * \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. - * - * \sa DataArrayDouble::getIdsInRange - */ -DataArrayInt *DataArrayDouble::getIdsNotInRange(double vmin, double vmax) const -{ - checkAllocated(); - if(getNumberOfComponents()!=1) - throw INTERP_KERNEL::Exception("DataArrayDouble::getIdsNotInRange : this must have exactly one component !"); - const double *cptr(begin()); - MEDCouplingAutoRefCountObjectPtr ret(DataArrayInt::New()); ret->alloc(0,1); - int nbOfTuples(getNumberOfTuples()); - for(int i=0;ivmax) - 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) -{ - std::vector tmp(2); - tmp[0]=a1; tmp[1]=a2; - 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. - * If the number of non null of elements in \a arr is equal to one the returned object is a copy of it - * not the object itself. - * \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) -{ - 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("DataArrayDouble::Aggregate : input list must contain at least one NON EMPTY DataArrayDouble !"); - 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("DataArrayDouble::Aggregate : Nb of components mismatch for array aggregation !"); - nbt+=(*it)->getNumberOfTuples(); - } - 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.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) -{ - std::vector arr(2); - arr[0]=a1; arr[1]=a2; - 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) -{ - 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("DataArrayDouble::Meld : input list must contain at least one NON EMPTY DataArrayDouble !"); - 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("DataArrayDouble::Meld : mismatch of number of tuples !"); - nbc[i]=(*it)->getNumberOfComponents(); - pts[i]=(*it)->getConstPointer(); - } - int totalNbOfComp=std::accumulate(nbc.begin(),nbc.end(),0); - DataArrayDouble *ret=DataArrayDouble::New(); - ret->alloc(nbOfTuples,totalNbOfComp); - double *retPtr=ret->getPointer(); - for(int i=0;isetInfoOnComponent(k,a[i]->getInfoOnComponent(j)); - return ret; -} - -/*! - * Returns a new DataArrayDouble containing a dot product of two given arrays, so that - * the i-th tuple of the result array is a sum of products of j-th components of i-th - * tuples of given arrays (\f$ a_i = \sum_{j=1}^n a1_j * a2_j \f$). - * Info on components and name 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 - 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 any given array is not allocated. - * \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() - * \throw If \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() - */ -DataArrayDouble *DataArrayDouble::Dot(const DataArrayDouble *a1, const DataArrayDouble *a2) -{ - if(!a1 || !a2) - throw INTERP_KERNEL::Exception("DataArrayDouble::Dot : input DataArrayDouble instance is NULL !"); - a1->checkAllocated(); - a2->checkAllocated(); - int nbOfComp=a1->getNumberOfComponents(); - if(nbOfComp!=a2->getNumberOfComponents()) - throw INTERP_KERNEL::Exception("Nb of components mismatch for array Dot !"); - int nbOfTuple=a1->getNumberOfTuples(); - if(nbOfTuple!=a2->getNumberOfTuples()) - throw INTERP_KERNEL::Exception("Nb of tuples mismatch for array Dot !"); - DataArrayDouble *ret=DataArrayDouble::New(); - ret->alloc(nbOfTuple,1); - double *retPtr=ret->getPointer(); - const double *a1Ptr=a1->getConstPointer(); - const double *a2Ptr=a2->getConstPointer(); - for(int i=0;isetInfoOnComponent(0,a1->getInfoOnComponent(0)); - ret->setName(a1->getName()); - 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) -{ - if(!a1 || !a2) - throw INTERP_KERNEL::Exception("DataArrayDouble::CrossProduct : input DataArrayDouble instance is NULL !"); - int nbOfComp=a1->getNumberOfComponents(); - if(nbOfComp!=a2->getNumberOfComponents()) - throw INTERP_KERNEL::Exception("Nb of components mismatch for array crossProduct !"); - if(nbOfComp!=3) - throw INTERP_KERNEL::Exception("Nb of components must be equal to 3 for array crossProduct !"); - int nbOfTuple=a1->getNumberOfTuples(); - if(nbOfTuple!=a2->getNumberOfTuples()) - throw INTERP_KERNEL::Exception("Nb of tuples mismatch for array crossProduct !"); - DataArrayDouble *ret=DataArrayDouble::New(); - ret->alloc(nbOfTuple,3); - double *retPtr=ret->getPointer(); - const double *a1Ptr=a1->getConstPointer(); - const double *a2Ptr=a2->getConstPointer(); - for(int i=0;icopyStringInfoFrom(*a1); - 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) -{ - if(!a1 || !a2) - throw INTERP_KERNEL::Exception("DataArrayDouble::Max : input DataArrayDouble instance is NULL !"); - int nbOfComp=a1->getNumberOfComponents(); - if(nbOfComp!=a2->getNumberOfComponents()) - throw INTERP_KERNEL::Exception("Nb of components mismatch for array Max !"); - int nbOfTuple=a1->getNumberOfTuples(); - if(nbOfTuple!=a2->getNumberOfTuples()) - throw INTERP_KERNEL::Exception("Nb of tuples mismatch for array Max !"); - DataArrayDouble *ret=DataArrayDouble::New(); - ret->alloc(nbOfTuple,nbOfComp); - double *retPtr=ret->getPointer(); - const double *a1Ptr=a1->getConstPointer(); - const double *a2Ptr=a2->getConstPointer(); - int nbElem=nbOfTuple*nbOfComp; - for(int i=0;icopyStringInfoFrom(*a1); - 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) -{ - if(!a1 || !a2) - throw INTERP_KERNEL::Exception("DataArrayDouble::Min : input DataArrayDouble instance is NULL !"); - int nbOfComp=a1->getNumberOfComponents(); - if(nbOfComp!=a2->getNumberOfComponents()) - throw INTERP_KERNEL::Exception("Nb of components mismatch for array min !"); - int nbOfTuple=a1->getNumberOfTuples(); - if(nbOfTuple!=a2->getNumberOfTuples()) - throw INTERP_KERNEL::Exception("Nb of tuples mismatch for array min !"); - DataArrayDouble *ret=DataArrayDouble::New(); - ret->alloc(nbOfTuple,nbOfComp); - double *retPtr=ret->getPointer(); - const double *a1Ptr=a1->getConstPointer(); - const double *a2Ptr=a2->getConstPointer(); - int nbElem=nbOfTuple*nbOfComp; - for(int i=0;icopyStringInfoFrom(*a1); - 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) -{ - if(!a1 || !a2) - throw INTERP_KERNEL::Exception("DataArrayDouble::Add : input DataArrayDouble instance is NULL !"); - int nbOfTuple=a1->getNumberOfTuples(); - int nbOfTuple2=a2->getNumberOfTuples(); - int nbOfComp=a1->getNumberOfComponents(); - int nbOfComp2=a2->getNumberOfComponents(); - MEDCouplingAutoRefCountObjectPtr ret=0; - if(nbOfTuple==nbOfTuple2) - { - if(nbOfComp==nbOfComp2) - { - ret=DataArrayDouble::New(); - ret->alloc(nbOfTuple,nbOfComp); - std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::plus()); - ret->copyStringInfoFrom(*a1); - } - else - { - int nbOfCompMin,nbOfCompMax; - const DataArrayDouble *aMin, *aMax; - if(nbOfComp>nbOfComp2) - { - nbOfCompMin=nbOfComp2; nbOfCompMax=nbOfComp; - aMin=a2; aMax=a1; - } - else - { - nbOfCompMin=nbOfComp; nbOfCompMax=nbOfComp2; - aMin=a1; aMax=a2; - } - if(nbOfCompMin==1) - { - ret=DataArrayDouble::New(); - ret->alloc(nbOfTuple,nbOfCompMax); - const double *aMinPtr=aMin->getConstPointer(); - const double *aMaxPtr=aMax->getConstPointer(); - double *res=ret->getPointer(); - for(int i=0;i(),aMinPtr[i])); - ret->copyStringInfoFrom(*aMax); - } - else - throw INTERP_KERNEL::Exception("Nb of components mismatch for array Add !"); - } - } - else if((nbOfTuple==1 && nbOfTuple2>1) || (nbOfTuple>1 && nbOfTuple2==1)) - { - if(nbOfComp==nbOfComp2) - { - int nbOfTupleMax=std::max(nbOfTuple,nbOfTuple2); - const DataArrayDouble *aMin=nbOfTuple>nbOfTuple2?a2:a1; - const DataArrayDouble *aMax=nbOfTuple>nbOfTuple2?a1:a2; - const double *aMinPtr=aMin->getConstPointer(),*aMaxPtr=aMax->getConstPointer(); - ret=DataArrayDouble::New(); - ret->alloc(nbOfTupleMax,nbOfComp); - double *res=ret->getPointer(); - for(int i=0;i()); - ret->copyStringInfoFrom(*aMax); - } - else - throw INTERP_KERNEL::Exception("Nb of components mismatch for array Add !"); - } - else - throw INTERP_KERNEL::Exception("Nb of tuples mismatch for array Add !"); - 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) -{ - 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(); - int nbOfComp2=other->getNumberOfComponents(); - if(nbOfTuple==nbOfTuple2) - { - if(nbOfComp==nbOfComp2) - { - std::transform(begin(),end(),other->begin(),getPointer(),std::plus()); - } - else if(nbOfComp2==1) - { - double *ptr=getPointer(); - const double *ptrc=other->getConstPointer(); - for(int i=0;i(),*ptrc++)); - } - else - throw INTERP_KERNEL::Exception(msg); - } - else if(nbOfTuple2==1) - { - if(nbOfComp2==nbOfComp) - { - double *ptr=getPointer(); - const double *ptrc=other->getConstPointer(); - for(int i=0;i()); - } - else - throw INTERP_KERNEL::Exception(msg); - } - else - throw INTERP_KERNEL::Exception(msg); - 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) -{ - if(!a1 || !a2) - throw INTERP_KERNEL::Exception("DataArrayDouble::Substract : input DataArrayDouble instance is NULL !"); - int nbOfTuple1=a1->getNumberOfTuples(); - int nbOfTuple2=a2->getNumberOfTuples(); - int nbOfComp1=a1->getNumberOfComponents(); - int nbOfComp2=a2->getNumberOfComponents(); - if(nbOfTuple2==nbOfTuple1) - { - if(nbOfComp1==nbOfComp2) - { - MEDCouplingAutoRefCountObjectPtr ret=DataArrayDouble::New(); - ret->alloc(nbOfTuple2,nbOfComp1); - std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::minus()); - ret->copyStringInfoFrom(*a1); - return ret.retn(); - } - else if(nbOfComp2==1) - { - MEDCouplingAutoRefCountObjectPtr ret=DataArrayDouble::New(); - ret->alloc(nbOfTuple1,nbOfComp1); - const double *a2Ptr=a2->getConstPointer(); - const double *a1Ptr=a1->getConstPointer(); - double *res=ret->getPointer(); - for(int i=0;i(),a2Ptr[i])); - ret->copyStringInfoFrom(*a1); - return ret.retn(); - } - else - { - a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Substract !"); - return 0; - } - } - else if(nbOfTuple2==1) - { - a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Substract !"); - MEDCouplingAutoRefCountObjectPtr ret=DataArrayDouble::New(); - ret->alloc(nbOfTuple1,nbOfComp1); - const double *a1ptr=a1->getConstPointer(),*a2ptr=a2->getConstPointer(); - double *pt=ret->getPointer(); - for(int i=0;i()); - ret->copyStringInfoFrom(*a1); - return ret.retn(); - } - else - { - a1->checkNbOfTuples(nbOfTuple2,"Nb of tuples mismatch for array Substract !");//will always throw an exception - return 0; - } -} - -/*! - * 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) -{ - 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(); - int nbOfComp2=other->getNumberOfComponents(); - if(nbOfTuple==nbOfTuple2) - { - if(nbOfComp==nbOfComp2) - { - std::transform(begin(),end(),other->begin(),getPointer(),std::minus()); - } - else if(nbOfComp2==1) - { - double *ptr=getPointer(); - const double *ptrc=other->getConstPointer(); - for(int i=0;i(),*ptrc++)); - } - else - throw INTERP_KERNEL::Exception(msg); - } - else if(nbOfTuple2==1) - { - if(nbOfComp2==nbOfComp) - { - double *ptr=getPointer(); - const double *ptrc=other->getConstPointer(); - for(int i=0;i()); - } - else - throw INTERP_KERNEL::Exception(msg); - } - else - throw INTERP_KERNEL::Exception(msg); - 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) -{ - if(!a1 || !a2) - throw INTERP_KERNEL::Exception("DataArrayDouble::Multiply : input DataArrayDouble instance is NULL !"); - int nbOfTuple=a1->getNumberOfTuples(); - int nbOfTuple2=a2->getNumberOfTuples(); - int nbOfComp=a1->getNumberOfComponents(); - int nbOfComp2=a2->getNumberOfComponents(); - MEDCouplingAutoRefCountObjectPtr ret=0; - if(nbOfTuple==nbOfTuple2) - { - if(nbOfComp==nbOfComp2) - { - ret=DataArrayDouble::New(); - ret->alloc(nbOfTuple,nbOfComp); - std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::multiplies()); - ret->copyStringInfoFrom(*a1); - } - else - { - int nbOfCompMin,nbOfCompMax; - const DataArrayDouble *aMin, *aMax; - if(nbOfComp>nbOfComp2) - { - nbOfCompMin=nbOfComp2; nbOfCompMax=nbOfComp; - aMin=a2; aMax=a1; - } - else - { - nbOfCompMin=nbOfComp; nbOfCompMax=nbOfComp2; - aMin=a1; aMax=a2; - } - if(nbOfCompMin==1) - { - ret=DataArrayDouble::New(); - ret->alloc(nbOfTuple,nbOfCompMax); - const double *aMinPtr=aMin->getConstPointer(); - const double *aMaxPtr=aMax->getConstPointer(); - double *res=ret->getPointer(); - for(int i=0;i(),aMinPtr[i])); - ret->copyStringInfoFrom(*aMax); - } - else - throw INTERP_KERNEL::Exception("Nb of components mismatch for array Multiply !"); - } - } - else if((nbOfTuple==1 && nbOfTuple2>1) || (nbOfTuple>1 && nbOfTuple2==1)) - { - if(nbOfComp==nbOfComp2) - { - int nbOfTupleMax=std::max(nbOfTuple,nbOfTuple2); - const DataArrayDouble *aMin=nbOfTuple>nbOfTuple2?a2:a1; - const DataArrayDouble *aMax=nbOfTuple>nbOfTuple2?a1:a2; - const double *aMinPtr=aMin->getConstPointer(),*aMaxPtr=aMax->getConstPointer(); - ret=DataArrayDouble::New(); - ret->alloc(nbOfTupleMax,nbOfComp); - double *res=ret->getPointer(); - for(int i=0;i()); - ret->copyStringInfoFrom(*aMax); - } - else - throw INTERP_KERNEL::Exception("Nb of components mismatch for array Multiply !"); - } - else - throw INTERP_KERNEL::Exception("Nb of tuples mismatch for array Multiply !"); - 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) -{ - 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(); - int nbOfComp2=other->getNumberOfComponents(); - if(nbOfTuple==nbOfTuple2) - { - if(nbOfComp==nbOfComp2) - { - std::transform(begin(),end(),other->begin(),getPointer(),std::multiplies()); - } - else if(nbOfComp2==1) - { - double *ptr=getPointer(); - const double *ptrc=other->getConstPointer(); - for(int i=0;i(),*ptrc++)); - } - else - throw INTERP_KERNEL::Exception(msg); - } - else if(nbOfTuple2==1) - { - if(nbOfComp2==nbOfComp) - { - double *ptr=getPointer(); - const double *ptrc=other->getConstPointer(); - for(int i=0;i()); - } - else - throw INTERP_KERNEL::Exception(msg); - } - else - throw INTERP_KERNEL::Exception(msg); - 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) -{ - if(!a1 || !a2) - throw INTERP_KERNEL::Exception("DataArrayDouble::Divide : input DataArrayDouble instance is NULL !"); - int nbOfTuple1=a1->getNumberOfTuples(); - int nbOfTuple2=a2->getNumberOfTuples(); - int nbOfComp1=a1->getNumberOfComponents(); - int nbOfComp2=a2->getNumberOfComponents(); - if(nbOfTuple2==nbOfTuple1) - { - if(nbOfComp1==nbOfComp2) - { - MEDCouplingAutoRefCountObjectPtr ret=DataArrayDouble::New(); - ret->alloc(nbOfTuple2,nbOfComp1); - std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::divides()); - ret->copyStringInfoFrom(*a1); - return ret.retn(); - } - else if(nbOfComp2==1) - { - MEDCouplingAutoRefCountObjectPtr ret=DataArrayDouble::New(); - ret->alloc(nbOfTuple1,nbOfComp1); - const double *a2Ptr=a2->getConstPointer(); - const double *a1Ptr=a1->getConstPointer(); - double *res=ret->getPointer(); - for(int i=0;i(),a2Ptr[i])); - ret->copyStringInfoFrom(*a1); - return ret.retn(); - } - else - { - a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Divide !"); - return 0; - } - } - else if(nbOfTuple2==1) - { - a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Divide !"); - MEDCouplingAutoRefCountObjectPtr ret=DataArrayDouble::New(); - ret->alloc(nbOfTuple1,nbOfComp1); - const double *a1ptr=a1->getConstPointer(),*a2ptr=a2->getConstPointer(); - double *pt=ret->getPointer(); - for(int i=0;i()); - ret->copyStringInfoFrom(*a1); - return ret.retn(); - } - else - { - a1->checkNbOfTuples(nbOfTuple2,"Nb of tuples mismatch for array Divide !");//will always throw an exception - return 0; - } -} - -/*! - * 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) -{ - 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(); - int nbOfComp2=other->getNumberOfComponents(); - if(nbOfTuple==nbOfTuple2) - { - if(nbOfComp==nbOfComp2) - { - std::transform(begin(),end(),other->begin(),getPointer(),std::divides()); - } - else if(nbOfComp2==1) - { - double *ptr=getPointer(); - const double *ptrc=other->getConstPointer(); - for(int i=0;i(),*ptrc++)); - } - else - throw INTERP_KERNEL::Exception(msg); - } - else if(nbOfTuple2==1) - { - if(nbOfComp2==nbOfComp) - { - double *ptr=getPointer(); - const double *ptrc=other->getConstPointer(); - for(int i=0;i()); - } - else - throw INTERP_KERNEL::Exception(msg); - } - else - throw INTERP_KERNEL::Exception(msg); - 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) -{ - 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) -{ - 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(); -} - -/*! - * This method is \b NOT wrapped into python because it can be useful only for performance reasons in C++ context. - * All values in \a this must be 0. or 1. within eps error. 0 means false, 1 means true. - * If an another value than 0 or 1 appear (within eps precision) an INTERP_KERNEL::Exception will be thrown. - * - * \throw if \a this is not allocated. - * \throw if \a this has not exactly one component. - */ -std::vector DataArrayDouble::toVectorOfBool(double eps) const -{ - checkAllocated(); - if(getNumberOfComponents()!=1) - throw INTERP_KERNEL::Exception("DataArrayDouble::toVectorOfBool : must be applied on single component array !"); - int nbt(getNumberOfTuples()); - std::vector ret(nbt); - const double *pt(begin()); - for(int i=0;i& tinyInfo) const -{ - tinyInfo.resize(2); - if(isAllocated()) - { - tinyInfo[0]=getNumberOfTuples(); - tinyInfo[1]=getNumberOfComponents(); - } - else - { - tinyInfo[0]=-1; - tinyInfo[1]=-1; - } -} - -/*! - * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class. - * Server side. - */ -void DataArrayDouble::getTinySerializationStrInformation(std::vector& tinyInfo) const -{ - if(isAllocated()) - { - int nbOfCompo=getNumberOfComponents(); - tinyInfo.resize(nbOfCompo+1); - tinyInfo[0]=getName(); - for(int i=0;i& tinyInfoI) -{ - int nbOfTuple=tinyInfoI[0]; - int nbOfComp=tinyInfoI[1]; - if(nbOfTuple!=-1 || nbOfComp!=-1) - { - alloc(nbOfTuple,nbOfComp); - return true; - } - return false; -} - -/*! - * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class. - */ -void DataArrayDouble::finishUnserialization(const std::vector& tinyInfoI, const std::vector& tinyInfoS) -{ - setName(tinyInfoS[0]); - if(isAllocated()) - { - int nbOfCompo=getNumberOfComponents(); - for(int i=0;iincrRef(); - if(_da->isAllocated()) - { - _nb_comp=da->getNumberOfComponents(); - _nb_tuple=da->getNumberOfTuples(); - _pt=da->getPointer(); - } - } -} - -DataArrayDoubleIterator::~DataArrayDoubleIterator() -{ - if(_da) - _da->decrRef(); -} - -DataArrayDoubleTuple *DataArrayDoubleIterator::nextt() -{ - if(_tuple_id<_nb_tuple) - { - _tuple_id++; - DataArrayDoubleTuple *ret=new DataArrayDoubleTuple(_pt,_nb_comp); - _pt+=_nb_comp; - return ret; - } - else - return 0; -} - -DataArrayDoubleTuple::DataArrayDoubleTuple(double *pt, int nbOfComp):_pt(pt),_nb_of_compo(nbOfComp) -{ -} - - -std::string DataArrayDoubleTuple::repr() const -{ - std::ostringstream oss; oss.precision(17); oss << "("; - for(int i=0;i<_nb_of_compo-1;i++) - oss << _pt[i] << ", "; - oss << _pt[_nb_of_compo-1] << ")"; - return oss.str(); -} - -double DataArrayDoubleTuple::doubleValue() const -{ - if(_nb_of_compo==1) - return *_pt; - throw INTERP_KERNEL::Exception("DataArrayDoubleTuple::doubleValue : DataArrayDoubleTuple instance has not exactly 1 component -> Not possible to convert it into a double precision float !"); -} - -/*! - * This method returns a newly allocated instance the caller should dealed with by a ParaMEDMEM::DataArrayDouble::decrRef. - * This method performs \b no copy of data. The content is only referenced using ParaMEDMEM::DataArrayDouble::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. - */ -DataArrayDouble *DataArrayDoubleTuple::buildDADouble(int nbOfTuples, int nbOfCompo) const -{ - if((_nb_of_compo==nbOfCompo && nbOfTuples==1) || (_nb_of_compo==nbOfTuples && nbOfCompo==1)) - { - DataArrayDouble *ret=DataArrayDouble::New(); - ret->useExternalArrayWithRWAccess(_pt,nbOfTuples,nbOfCompo); - return ret; - } - else - { - std::ostringstream oss; oss << "DataArrayDoubleTuple::buildDADouble : unable to build a requested DataArrayDouble 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 DataArrayInt. The caller is to delete this array - * using decrRef() as it is no more needed. - */ -DataArrayInt *DataArrayInt::New() -{ - return new DataArrayInt; -} - -/*! - * 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 -{ - 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 -{ - if(!isAllocated()) - throw INTERP_KERNEL::Exception("DataArrayInt::checkAllocated : Array is defined but not allocated ! Call alloc or setValues method first !"); -} - -/*! - * This method desallocated \a this without modification of informations relative to the components. - * After call of this method, DataArrayInt::isAllocated will return false. - * If \a this is already not allocated, \a this is let unchanged. - */ -void DataArrayInt::desallocate() -{ - _mem.destroy(); -} - -std::size_t DataArrayInt::getHeapMemorySizeWithoutChildren() const -{ - std::size_t sz(_mem.getNbOfElemAllocated()); - sz*=sizeof(int); - return DataArray::getHeapMemorySizeWithoutChildren()+sz; -} - -/*! - * 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 -{ - if(isAllocated()) - { - if(getNbOfElems()==1) - { - return *getConstPointer(); - } - else - throw INTERP_KERNEL::Exception("DataArrayInt::intValue : DataArrayInt instance is allocated but number of elements is not equal to 1 !"); - } - else - throw INTERP_KERNEL::Exception("DataArrayInt::intValue : DataArrayInt instance is not allocated !"); -} - -/*! - * 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 -{ - checkAllocated(); - 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(std::size_t i=0;i(this); - } -} - -/*! - * Copies all the data from another DataArrayInt. For more info see - * \ref MEDCouplingArrayBasicsCopyDeepAssign. - * \param [in] other - another instance of DataArrayInt to copy data from. - * \throw If the \a other is not allocated. - */ -void DataArrayInt::cpyFrom(const DataArrayInt& other) -{ - other.checkAllocated(); - int nbOfTuples=other.getNumberOfTuples(); - int nbOfComp=other.getNumberOfComponents(); - allocIfNecessary(nbOfTuples,nbOfComp); - std::size_t nbOfElems=(std::size_t)nbOfTuples*nbOfComp; - int *pt=getPointer(); - const int *ptI=other.getConstPointer(); - for(std::size_t i=0;igetNumberOfComponents() != 1 - * \throw If \a this is not allocated. - */ -void DataArrayInt::iota(int init) -{ - checkAllocated(); - if(getNumberOfComponents()!=1) - throw INTERP_KERNEL::Exception("DataArrayInt::iota : works only for arrays with only one component, you can call 'rearrange' method before !"); - int *ptr=getPointer(); - int ntuples=getNumberOfTuples(); - for(int i=0;igetNumberOfTuples() << "\">"; - if(std::string(type)=="Int32") - { - const char *data(reinterpret_cast(begin())); - std::size_t sz(getNbOfElems()*sizeof(int)); - byteArr->insertAtTheEnd(data,data+sz); - byteArr->insertAtTheEnd(SPACE,SPACE+4); - } - else if(std::string(type)=="Int8") - { - INTERP_KERNEL::AutoPtr tmp(new char[getNbOfElems()]); - std::copy(begin(),end(),(char *)tmp); - byteArr->insertAtTheEnd((char *)tmp,(char *)tmp+getNbOfElems()); - byteArr->insertAtTheEnd(SPACE,SPACE+4); - } - else if(std::string(type)=="UInt8") - { - INTERP_KERNEL::AutoPtr tmp(new unsigned char[getNbOfElems()]); - std::copy(begin(),end(),(unsigned char *)tmp); - byteArr->insertAtTheEnd((unsigned char *)tmp,(unsigned char *)tmp+getNbOfElems()); - byteArr->insertAtTheEnd(SPACE,SPACE+4); - } - else - throw INTERP_KERNEL::Exception("DataArrayInt::writeVTK : Only Int32, Int8 and UInt8 supported !"); - } - else - { - ofs << " RangeMin=\"" << getMinValueInArray() << "\" RangeMax=\"" << getMaxValueInArray() << "\" format=\"ascii\">\n" << idt; - std::copy(begin(),end(),std::ostream_iterator(ofs," ")); - } - ofs << std::endl << idt << "
\n"; -} - -void DataArrayInt::reprStream(std::ostream& stream) const -{ - stream << "Name of int array : \"" << _name << "\"\n"; - reprWithoutNameStream(stream); -} - -void DataArrayInt::reprZipStream(std::ostream& stream) const -{ - stream << "Name of int array : \"" << _name << "\"\n"; - reprZipWithoutNameStream(stream); -} - -void DataArrayInt::reprNotTooLongStream(std::ostream& stream) const -{ - stream << "Name of int array : \"" << _name << "\"\n"; - reprNotTooLongWithoutNameStream(stream); -} - -void DataArrayInt::reprWithoutNameStream(std::ostream& stream) const -{ - DataArray::reprWithoutNameStream(stream); - _mem.repr(getNumberOfComponents(),stream); -} - -void DataArrayInt::reprZipWithoutNameStream(std::ostream& stream) const -{ - DataArray::reprWithoutNameStream(stream); - _mem.reprZip(getNumberOfComponents(),stream); -} - -void DataArrayInt::reprNotTooLongWithoutNameStream(std::ostream& stream) const -{ - DataArray::reprWithoutNameStream(stream); - stream.precision(17); - _mem.reprNotTooLong(getNumberOfComponents(),stream); -} - -void DataArrayInt::reprCppStream(const std::string& varName, std::ostream& stream) const -{ - int nbTuples=getNumberOfTuples(),nbComp=getNumberOfComponents(); - const int *data=getConstPointer(); - stream << "DataArrayInt *" << varName << "=DataArrayInt::New();" << std::endl; - if(nbTuples*nbComp>=1) - { - stream << "const int " << 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 DataArrayInt::reprQuickOverview(std::ostream& stream) const -{ - 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 -{ - 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). - * - * \sa replaceOneValByInThis - */ -void DataArrayInt::transformWithIndArr(const int *indArrBg, const int *indArrEnd) -{ - 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)),nbOfTuples(getNumberOfTuples()),*pt(getPointer()); - for(int i=0;i=0 && *ptgetNumberOfComponents() != 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 -{ - 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(); - std::size_t nbOfCast=std::distance(arrBg,arrEnd); - if(nbOfCast<2) - throw INTERP_KERNEL::Exception("DataArrayInt::splitByValueRange : The input array giving the cast range values should be of size >=2 !"); - nbOfCast--; - const int *work=getConstPointer(); - typedef std::reverse_iterator rintstart; - 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(); - MEDCouplingAutoRefCountObjectPtr ret3=DataArrayInt::New(); - ret1->alloc(nbOfTuples,1); - ret2->alloc(nbOfTuples,1); - int *ret1Ptr=ret1->getPointer(); - int *ret2Ptr=ret2->getPointer(); - std::set castsDetected; - for(int i=0;i(), work[i])); - std::size_t pos=std::distance(bg,res); - std::size_t pos2=nbOfCast-pos; - if(pos2alloc((int)castsDetected.size(),1); - std::copy(castsDetected.begin(),castsDetected.end(),ret3->getPointer()); - castArr=ret1.retn(); - rankInsideCast=ret2.retn(); - castsPresent=ret3.retn(); -} - -/*! - * This method look at \a this if it can be considered as a range defined by the 3-tuple ( \a strt , \a sttoopp , \a stteepp ). - * If false is returned the tuple must be ignored. If true is returned \a this can be considered by a range( \a strt , \a sttoopp , \a stteepp ). - * This method works only if \a this is allocated and single component. If not an exception will be thrown. - * - * \param [out] strt - the start of the range (included) if true is returned. - * \param [out] sttoopp - the end of the range (not included) if true is returned. - * \param [out] stteepp - the step of the range if true is returned. - * \return the verdict of the check. - * - * \sa DataArray::GetNumberOfItemGivenBES - */ -bool DataArrayInt::isRange(int& strt, int& sttoopp, int& stteepp) const -{ - checkAllocated(); - if(getNumberOfComponents()!=1) - throw INTERP_KERNEL::Exception("DataArrayInt::isRange : this must be single component array !"); - int nbTuples(getNumberOfTuples()); - if(nbTuples==0) - { strt=0; sttoopp=0; stteepp=1; return true; } - const int *pt(begin()); - strt=*pt; - if(nbTuples==1) - { sttoopp=strt+1; stteepp=1; return true; } - strt=*pt; sttoopp=pt[nbTuples-1]; - if(strt==sttoopp) - return false; - if(sttoopp>strt) - { - sttoopp++; - int a(sttoopp-1-strt),tmp(strt); - if(a%(nbTuples-1)!=0) - return false; - stteepp=a/(nbTuples-1); - for(int i=0;igetNumberOfComponents() != 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 -{ - 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); - int nbOfTuples=getNumberOfTuples(); - const int *pt=getConstPointer(); - MEDCouplingAutoRefCountObjectPtr ret=DataArrayInt::New(); - ret->alloc(nbOfTuples,1); - ret->fillWithValue(-1); - int *tmp=ret->getPointer(); - for(int i=0;i=0 && *pt=0 && pos - * \ref py_mcdataarrayint_invertarrayo2n2n2o "Here is a Python example". - * \endif - */ -DataArrayInt *DataArrayInt::invertArrayO2N2N2O(int newNbOfElem) const -{ - MEDCouplingAutoRefCountObjectPtr ret=DataArrayInt::New(); - ret->alloc(newNbOfElem,1); - int nbOfOldNodes=getNumberOfTuples(); - const int *old2New=getConstPointer(); - int *pt=ret->getPointer(); - for(int i=0;i!=nbOfOldNodes;i++) - { - int newp(old2New[i]); - if(newp!=-1) - { - if(newp>=0 && newp 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--) - { - int newp(old2New[i]); - if(newp!=-1) - { - if(newp>=0 && newp ret=DataArrayInt::New(); - ret->alloc(oldNbOfElem,1); - const int *new2Old=getConstPointer(); - int *pt=ret->getPointer(); - std::fill(pt,pt+oldNbOfElem,-1); - int nbOfNewElems=getNumberOfTuples(); - for(int i=0;i=0 && v a=deepCpy(); - MEDCouplingAutoRefCountObjectPtr b=other.deepCpy(); - a->sort(); - b->sort(); - return a->isEqualWithoutConsideringStr(*b); -} - -/*! - * This method compares content of input vector \a v and \a this. - * If for each id in \a this v[id]==True and for all other ids id2 not in \a this v[id2]==False, true is returned. - * For performance reasons \a this is expected to be sorted ascendingly. If not an exception will be thrown. - * - * \param [in] v - the vector of 'flags' to be compared with \a this. - * - * \throw If \a this is not sorted ascendingly. - * \throw If \a this has not exactly one component. - * \throw If \a this is not allocated. - */ -bool DataArrayInt::isFittingWith(const std::vector& v) const -{ - checkAllocated(); - if(getNumberOfComponents()!=1) - throw INTERP_KERNEL::Exception("DataArrayInt::isFittingWith : number of components of this should be equal to one !"); - const int *w(begin()),*end2(end()); - int refVal=-std::numeric_limits::max(); - int i=0; - std::vector::const_iterator it(v.begin()); - for(;it!=v.end();it++,i++) - { - if(*it) - { - if(w!=end2) - { - if(*w++==i) - { - if(i>refVal) - refVal=i; - else - { - std::ostringstream oss; oss << "DataArrayInt::isFittingWith : At pos #" << std::distance(begin(),w-1) << " this is not sorted ascendingly !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - } - else - return false; - } - else - return false; - } - } - return w==end2; -} - -/*! - * This method assumes that \a this has one component and is allocated. This method scans all tuples in \a this and for all tuple equal to \a val - * put True to the corresponding entry in \a vec. - * \a vec is expected to be with the same size than the number of tuples of \a this. - */ -void DataArrayInt::switchOnTupleEqualTo(int val, std::vector& vec) const -{ - checkAllocated(); - if(getNumberOfComponents()!=1) - throw INTERP_KERNEL::Exception("DataArrayInt::switchOnTupleEqualTo : number of components of this should be equal to one !"); - int nbOfTuples(getNumberOfTuples()); - if(nbOfTuples!=(int)vec.size()) - throw INTERP_KERNEL::Exception("DataArrayInt::switchOnTupleEqualTo : number of tuples of this should be equal to size of input vector of bool !"); - const int *pt(begin()); - for(int i=0;igetNumberOfComponents() != 1. - */ -void DataArrayInt::sort(bool asc) -{ - checkAllocated(); - if(getNumberOfComponents()!=1) - throw INTERP_KERNEL::Exception("DataArrayInt::sort : only supported with 'this' array with ONE component !"); - _mem.sort(asc); - declareAsNew(); -} - -/*! - * Computes for each tuple the sum of number of components values in the tuple and return it. - * - * \return DataArrayInt * - the new instance of DataArrayInt 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. - */ -DataArrayInt *DataArrayInt::sumPerTuple() const -{ - checkAllocated(); - int nbOfComp(getNumberOfComponents()),nbOfTuple(getNumberOfTuples()); - MEDCouplingAutoRefCountObjectPtr ret(DataArrayInt::New()); - ret->alloc(nbOfTuple,1); - const int *src(getConstPointer()); - int *dest(ret->getPointer()); - for(int i=0;igetNumberOfComponents() < 1. - * \throw If \a this is not allocated. - */ -void DataArrayInt::reverse() -{ - 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 -{ - 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 -{ - 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;i 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. - * - * \if ENABLE_EXAMPLES - * \ref cpp_mcdataarrayint_buildpermutationarr "Here is a C++ example". - * - * \ref py_mcdataarrayint_buildpermutationarr "Here is a Python example". - * \endif - */ -DataArrayInt *DataArrayInt::buildPermutationArr(const DataArrayInt& other) const -{ - 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(); - ret->alloc(nbTuple,1); - ret->fillWithValue(-1); - const int *pt=getConstPointer(); - std::map mm; - for(int i=0;igetPointer(); - for(int i=0;i::const_iterator it=mm.find(pt[i]); - if(it==mm.end()) - { - std::ostringstream oss; oss << "DataArrayInt::buildPermutationArr : Arrays mismatch : element (" << pt[i] << ") in 'other' not findable in 'this' !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - retToFill[i]=(*it).second; - } - return ret.retn(); -} - -/*! - * 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) -{ - _info_on_compo.resize(nbOfCompo); - _mem.useArray(array,ownership,type,nbOfTuple*nbOfCompo); - declareAsNew(); -} - -void DataArrayInt::useExternalArrayWithRWAccess(const int *array, int nbOfTuple, int nbOfCompo) -{ - _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 -{ - 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,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 -{ - 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,C_DEALLOC,getNumberOfTuples(),getNumberOfComponents()); - 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 \c this one. - * If a permutation reduction is needed, substr() or selectByTupleId() should be used. - * For more info on renumbering see \ref numbering. - * \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) -{ - checkAllocated(); - int nbTuples=getNumberOfTuples(); - int nbOfCompo=getNumberOfComponents(); - int *tmp=new int[nbTuples*nbOfCompo]; - const int *iptr=getConstPointer(); - for(int i=0;i=0 && vgetNumberOfTuples() - * 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) -{ - checkAllocated(); - int nbTuples=getNumberOfTuples(); - int nbOfCompo=getNumberOfComponents(); - int *tmp=new int[nbTuples*nbOfCompo]; - const int *iptr=getConstPointer(); - for(int i=0;i=0 && vgetNumberOfTuples() - * 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 -{ - checkAllocated(); - int nbTuples=getNumberOfTuples(); - int nbOfCompo=getNumberOfComponents(); - MEDCouplingAutoRefCountObjectPtr ret=DataArrayInt::New(); - ret->alloc(nbTuples,nbOfCompo); - ret->copyStringInfoFrom(*this); - const int *iptr=getConstPointer(); - int *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 \c this one. - * If a permutation reduction is needed, substr() or selectByTupleId() should be used. - * For more info on renumbering see \ref numbering. - * \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 -{ - checkAllocated(); - int nbTuples=getNumberOfTuples(); - int nbOfCompo=getNumberOfComponents(); - MEDCouplingAutoRefCountObjectPtr ret=DataArrayInt::New(); - ret->alloc(nbTuples,nbOfCompo); - ret->copyStringInfoFrom(*this); - const int *iptr=getConstPointer(); - int *optr=ret->getPointer(); - for(int i=0;icopyStringInfoFrom(*this); - return ret.retn(); -} - -/*! - * 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 numbering. - * \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 -{ - checkAllocated(); - int nbTuples=getNumberOfTuples(); - int nbOfCompo=getNumberOfComponents(); - MEDCouplingAutoRefCountObjectPtr ret=DataArrayInt::New(); - ret->alloc(newNbOfTuple,nbOfCompo); - const int *iptr=getConstPointer(); - int *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 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 numbering. - * \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 -{ - checkAllocated(); - MEDCouplingAutoRefCountObjectPtr ret=DataArrayInt::New(); - int nbComp=getNumberOfComponents(); - ret->alloc((int)std::distance(new2OldBg,new2OldEnd),nbComp); - ret->copyStringInfoFrom(*this); - int *pt=ret->getPointer(); - const int *srcPt=getConstPointer(); - int i=0; - 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.retn(); -} - -/*! - * 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 numbering. - * \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 -{ - checkAllocated(); - MEDCouplingAutoRefCountObjectPtr ret=DataArrayInt::New(); - int nbComp=getNumberOfComponents(); - int oldNbOfTuples=getNumberOfTuples(); - ret->alloc((int)std::distance(new2OldBg,new2OldEnd),nbComp); - ret->copyStringInfoFrom(*this); - int *pt=ret->getPointer(); - const int *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 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 numbering. - * \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 -{ - checkAllocated(); - MEDCouplingAutoRefCountObjectPtr ret=DataArrayInt::New(); - int nbComp=getNumberOfComponents(); - 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); - return ret.retn(); -} - -/*! - * 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 numbering. - * \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. - */ -DataArray *DataArrayInt::selectByTupleRanges(const std::vector >& ranges) const -{ - checkAllocated(); - int nbOfComp=getNumberOfComponents(); - int nbOfTuplesThis=getNumberOfTuples(); - if(ranges.empty()) - { - MEDCouplingAutoRefCountObjectPtr ret=DataArrayInt::New(); - 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 << "DataArrayInt::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 << "DataArrayInt::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=DataArrayInt::New(); - ret->alloc(nbOfTuples,nbOfComp); - ret->copyStringInfoFrom(*this); - const int *src=getConstPointer(); - int *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 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 numbering. - * \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 -{ - checkAllocated(); - if(getNumberOfComponents()!=1) - throw INTERP_KERNEL::Exception("DataArrayInt::checkAndPreparePermutation : number of components must == 1 !"); - int nbTuples=getNumberOfTuples(); - const int *pt=getConstPointer(); - int *pt2=CheckAndPreparePermutation(pt,pt+nbTuples); - DataArrayInt *ret=DataArrayInt::New(); - ret->useArray(pt2,true,C_DEALLOC,nbTuples,1); - return ret; -} - -/*! - * This method tries to find the permutation to apply to the first input \a ids1 to obtain the same array (without considering strings informations) the second - * input array \a ids2. - * \a ids1 and \a ids2 are expected to be both a list of ids (both with number of components equal to one) not sorted and with values that can be negative. - * This method will throw an exception is no such permutation array can be obtained. It is typically the case if there is some ids in \a ids1 not in \a ids2 or - * inversely. - * In case of success (no throw) : \c ids1->renumber(ret)->isEqual(ids2) where \a ret is the return of this method. - * - * \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this - * array using decrRef() as it is no more needed. - * \throw If either ids1 or ids2 is null not allocated or not with one components. - * - */ -DataArrayInt *DataArrayInt::FindPermutationFromFirstToSecond(const DataArrayInt *ids1, const DataArrayInt *ids2) -{ - if(!ids1 || !ids2) - throw INTERP_KERNEL::Exception("DataArrayInt::FindPermutationFromFirstToSecond : the two input arrays must be not null !"); - if(!ids1->isAllocated() || !ids2->isAllocated()) - throw INTERP_KERNEL::Exception("DataArrayInt::FindPermutationFromFirstToSecond : the two input arrays must be allocated !"); - if(ids1->getNumberOfComponents()!=1 || ids2->getNumberOfComponents()!=1) - throw INTERP_KERNEL::Exception("DataArrayInt::FindPermutationFromFirstToSecond : the two input arrays have exactly one component !"); - if(ids1->getNumberOfTuples()!=ids2->getNumberOfTuples()) - { - std::ostringstream oss; oss << "DataArrayInt::FindPermutationFromFirstToSecond : first array has " << ids1->getNumberOfTuples() << " tuples and the second one " << ids2->getNumberOfTuples() << " tuples ! No chance to find a permutation between the 2 arrays !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - MEDCouplingAutoRefCountObjectPtr p1(ids1->deepCpy()); - MEDCouplingAutoRefCountObjectPtr p2(ids2->deepCpy()); - p1->sort(true); p2->sort(true); - if(!p1->isEqualWithoutConsideringStr(*p2)) - throw INTERP_KERNEL::Exception("DataArrayInt::FindPermutationFromFirstToSecond : the two arrays are not lying on same ids ! Impossible to find a permutation between the 2 arrays !"); - p1=ids1->checkAndPreparePermutation(); - p2=ids2->checkAndPreparePermutation(); - p2=p2->invertArrayO2N2N2O(p2->getNumberOfTuples()); - p2=p2->selectByTupleIdSafe(p1->begin(),p1->end()); - return p2.retn(); -} - -/*! - * 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 numbering.
- * \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 -{ - checkAllocated(); - if(getNumberOfComponents()!=1) - throw INTERP_KERNEL::Exception("DataArrayInt::changeSurjectiveFormat : number of components must == 1 !"); - int nbOfTuples=getNumberOfTuples(); - MEDCouplingAutoRefCountObjectPtr ret(DataArrayInt::New()); - MEDCouplingAutoRefCountObjectPtr retI(DataArrayInt::New()); - retI->alloc(targetNb+1,1); - const int *input=getConstPointer(); - std::vector< std::vector > tmp(targetNb); - for(int i=0;i=0 && tmp2getPointer(); - *retIPtr=0; - for(std::vector< std::vector >::const_iterator it1=tmp.begin();it1!=tmp.end();it1++,retIPtr++) - retIPtr[1]=retIPtr[0]+(int)((*it1).size()); - if(nbOfTuples!=retI->getIJ(targetNb,0)) - throw INTERP_KERNEL::Exception("DataArrayInt::changeSurjectiveFormat : big problem should never happen !"); - ret->alloc(nbOfTuples,1); - int *retPtr=ret->getPointer(); - for(std::vector< std::vector >::const_iterator it1=tmp.begin();it1!=tmp.end();it1++) - retPtr=std::copy((*it1).begin(),(*it1).end(),retPtr); - arr=ret.retn(); - arrI=retI.retn(); -} - - -/*! - * 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 numbering.
- * \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 [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 int *arr, const int *arrIBg, const int *arrIEnd, int &newNbOfTuples) -{ - MEDCouplingAutoRefCountObjectPtr ret=DataArrayInt::New(); - ret->alloc(nbOfOldTuples,1); - int *pt=ret->getPointer(); - std::fill(pt,pt+nbOfOldTuples,-1); - int nbOfGrps=((int)std::distance(arrIBg,arrIEnd))-1; - const int *cIPtr=arrIBg; - for(int i=0;i=0 && arr[j] - * \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 -{ - checkAllocated(); - if(getNumberOfComponents()!=1) - throw INTERP_KERNEL::Exception("DataArrayInt::buildPermArrPerLevel : number of components must == 1 !"); - int nbOfTuples=getNumberOfTuples(); - const int *pt=getConstPointer(); - std::map m; - MEDCouplingAutoRefCountObjectPtr ret=DataArrayInt::New(); - ret->alloc(nbOfTuples,1); - int *opt=ret->getPointer(); - for(int i=0;i::iterator it=m.find(val); - if(it!=m.end()) - { - *opt=(*it).second; - (*it).second++; - } - else - { - *opt=0; - m.insert(std::pair(val,1)); - } - } - int sum=0; - for(std::map::iterator it=m.begin();it!=m.end();it++) - { - int vt=(*it).second; - (*it).second=sum; - sum+=vt; - } - pt=getConstPointer(); - opt=ret->getPointer(); - for(int i=0;igetNumberOfTuples()) - * \throw If \a this is not allocated. - * \throw If \a this->getNumberOfComponents() != 1. - * \sa isIdentity2 - */ -bool DataArrayInt::isIdentity() const -{ - checkAllocated(); - if(getNumberOfComponents()!=1) - return false; - int nbOfTuples(getNumberOfTuples()); - const int *pt=getConstPointer(); - for(int i=0;igetNumberOfTuples()) and if \a this has \a sizeExpected tuples in it. - * - * \throw If \a this is not allocated. - * \throw If \a this->getNumberOfComponents() != 1. - * \sa isIdentity - */ -bool DataArrayInt::isIdentity2(int sizeExpected) const -{ - bool ret0(isIdentity()); - if(!ret0) - return false; - return getNumberOfTuples()==sizeExpected; -} - -/*! - * 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 -{ - checkAllocated(); - if(getNumberOfComponents()!=1) - throw INTERP_KERNEL::Exception("DataArrayInt::isUniform : must be applied on DataArrayInt with only one component, you can call 'rearrange' method before !"); - int nbOfTuples=getNumberOfTuples(); - const int *w=getConstPointer(); - const int *end2=w+nbOfTuples; - for(;w!=end2;w++) - if(*w!=val) - return false; - 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()); - std::size_t nbOfVals=getNbOfElems(); - const int *src=getConstPointer(); - double *dest=ret->getPointer(); - std::copy(src,src+nbOfVals,dest); - ret->copyStringInfoFrom(*this); - return ret; -} - -/*! - * 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 -{ - checkAllocated(); - int nbt=getNumberOfTuples(); - if(tupleIdBg<0) - throw INTERP_KERNEL::Exception("DataArrayInt::substr : The tupleIdBg parameter must be greater than 0 !"); - if(tupleIdBg>nbt) - throw INTERP_KERNEL::Exception("DataArrayInt::substr : The tupleIdBg parameter is greater than number of tuples !"); - int trueEnd=tupleIdEnd; - if(tupleIdEnd!=-1) - { - if(tupleIdEnd>nbt) - throw INTERP_KERNEL::Exception("DataArrayInt::substr : The tupleIdBg parameter is greater or equal than number of tuples !"); - } - else - trueEnd=nbt; - int nbComp=getNumberOfComponents(); - MEDCouplingAutoRefCountObjectPtr ret=DataArrayInt::New(); - ret->alloc(trueEnd-tupleIdBg,nbComp); - ret->copyStringInfoFrom(*this); - std::copy(getConstPointer()+tupleIdBg*nbComp,getConstPointer()+trueEnd*nbComp,ret->getPointer()); - return ret.retn(); -} - -/*! - * 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) -{ - checkAllocated(); - 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 !"); - 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(); -} - -/*! - * 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() -{ - checkAllocated(); - int nbOfTuples=getNumberOfTuples(); - rearrange(nbOfTuples); -} - -/*! - * 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 -{ - checkAllocated(); - MEDCouplingAutoRefCountObjectPtr ret=DataArrayInt::New(); - ret->alloc(getNumberOfTuples(),newNbOfComp); - const int *oldc=getConstPointer(); - int *nc=ret->getPointer(); - int nbOfTuples=getNumberOfTuples(); - int oldNbOfComp=getNumberOfComponents(); - int dim=std::min(oldNbOfComp,newNbOfComp); - for(int i=0;isetName(getName()); - for(int i=0;isetInfoOnComponent(i,getInfoOnComponent(i)); - ret->setName(getName()); - 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. - * \throw If \a nbOfTuples is negative. - */ -void DataArrayInt::reAlloc(int nbOfTuples) -{ - if(nbOfTuples<0) - throw INTERP_KERNEL::Exception("DataArrayInt::reAlloc : input new number of tuples should be >=0 !"); - checkAllocated(); - _mem.reAlloc(getNumberOfComponents()*(std::size_t)nbOfTuples); - declareAsNew(); -} - - -/*! - * 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(). - * - * \if ENABLE_EXAMPLES - * \ref py_mcdataarrayint_keepselectedcomponents "Here is a Python example". - * \endif - */ -DataArrayInt *DataArrayInt::keepSelectedComponents(const std::vector& compoIds) const -{ - checkAllocated(); - MEDCouplingAutoRefCountObjectPtr ret(DataArrayInt::New()); - 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 int *oldc=getConstPointer(); - int *nc=ret->getPointer(); - for(int i=0;icheckAllocated(); - int nbOfTuples=getNumberOfTuples(); - if(nbOfTuples!=other->getNumberOfTuples()) - throw INTERP_KERNEL::Exception("DataArrayInt::meldWith : mismatch of number of tuples !"); - int nbOfComp1=getNumberOfComponents(); - int nbOfComp2=other->getNumberOfComponents(); - int *newArr=(int *)malloc(nbOfTuples*(nbOfComp1+nbOfComp2)*sizeof(int)); - int *w=newArr; - const int *inp1=getConstPointer(); - const int *inp2=other->getConstPointer(); - for(int i=0;i compIds(nbOfComp2); - for(int i=0;igetNumberOfComponents(). - * \throw If \a compoIds[i] < 0 or \a compoIds[i] > \a this->getNumberOfComponents(). - * - * \if ENABLE_EXAMPLES - * \ref py_mcdataarrayint_setselectedcomponents "Here is a Python example". - * \endif - */ -void DataArrayInt::setSelectedComponents(const DataArrayInt *a, const std::vector& compoIds) -{ - 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=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)). - * - * \if ENABLE_EXAMPLES - * \ref py_mcdataarrayint_setpartofvalues1 "Here is a Python example". - * \endif - */ -void DataArrayInt::setPartOfValues1(const DataArrayInt *a, int bgTuples, int endTuples, int stepTuples, int bgComp, int endComp, int stepComp, bool strictCompoCompare) -{ - if(!a) - throw INTERP_KERNEL::Exception("DataArrayInt::setPartOfValues1 : DataArrayInt pointer in input is NULL !"); - const char msg[]="DataArrayInt::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; - } - int *pt=getPointer()+bgTuples*nbComp+bgComp; - const int *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). - * - * \if ENABLE_EXAMPLES - * \ref py_mcdataarrayint_setpartofvalues2 "Here is a Python example". - * \endif - */ -void DataArrayInt::setPartOfValues2(const DataArrayInt *a, const int *bgTuples, const int *endTuples, const int *bgComp, const int *endComp, bool strictCompoCompare) -{ - if(!a) - throw INTERP_KERNEL::Exception("DataArrayInt::setPartOfValues2 : DataArrayInt pointer in input is NULL !"); - const char msg[]="DataArrayInt::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; - } - int *pt=getPointer(); - const int *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 int *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. - * - * \if ENABLE_EXAMPLES - * \ref py_mcdataarrayint_setpartofvaluessimple2 "Here is a Python example". - * \endif - */ -void DataArrayInt::setPartOfValuesSimple2(int a, const int *bgTuples, const int *endTuples, const int *bgComp, const int *endComp) -{ - checkAllocated(); - int nbComp=getNumberOfComponents(); - int nbOfTuples=getNumberOfTuples(); - for(const int *z=bgComp;z!=endComp;z++) - DataArray::CheckValueInRange(nbComp,*z,"invalid component id"); - int *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 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 \c this array. - * - * \if ENABLE_EXAMPLES - * \ref py_mcdataarrayint_setpartofvalues3 "Here is a Python example". - * \endif - */ -void DataArrayInt::setPartOfValues3(const DataArrayInt *a, const int *bgTuples, const int *endTuples, int bgComp, int endComp, int stepComp, bool strictCompoCompare) -{ - if(!a) - throw INTERP_KERNEL::Exception("DataArrayInt::setPartOfValues3 : DataArrayInt pointer in input is NULL !"); - const char msg[]="DataArrayInt::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; - } - int *pt=getPointer()+bgComp; - const int *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 \c this array. - * - * \if ENABLE_EXAMPLES - * \ref py_mcdataarrayint_setpartofvaluessimple3 "Here is a Python example". - * \endif - */ -void DataArrayInt::setPartOfValuesSimple3(int a, const int *bgTuples, const int *endTuples, int bgComp, int endComp, int stepComp) -{ - const char msg[]="DataArrayInt::setPartOfValuesSimple3"; - checkAllocated(); - int newNbOfComp=DataArray::GetNumberOfItemGivenBES(bgComp,endComp,stepComp,msg); - int nbComp=getNumberOfComponents(); - int nbOfTuples=getNumberOfTuples(); - DataArray::CheckValueInRangeEx(nbComp,bgComp,endComp,"invalid component value"); - int *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 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) -{ - if(!a || !tuplesSelec) - throw INTERP_KERNEL::Exception("DataArrayInt::setPartOfValuesAdv : DataArrayInt pointer in input is NULL !"); - checkAllocated(); - a->checkAllocated(); - tuplesSelec->checkAllocated(); - int nbOfComp=getNumberOfComponents(); - if(nbOfComp!=a->getNumberOfComponents()) - throw INTERP_KERNEL::Exception("DataArrayInt::setPartOfValuesAdv : This and a do not have the same number of components !"); - if(tuplesSelec->getNumberOfComponents()!=2) - throw INTERP_KERNEL::Exception("DataArrayInt::setPartOfValuesAdv : Expecting to have a tuple selector DataArrayInt instance with exactly 2 components !"); - int thisNt=getNumberOfTuples(); - int aNt=a->getNumberOfTuples(); - int *valsToSet=getPointer(); - const int *valsSrc=a->getConstPointer(); - for(const int *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 << "DataArrayInt::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 DataArrayInt (\a aBase) 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] aBase - the array to copy values from. - * \param [in] tuplesSelec - the array specifying tuples of \a aBase to copy. - * \throw If \a this is not allocated. - * \throw If \a aBase is NULL. - * \throw If \a aBase 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 aBase array. - */ -void DataArrayInt::setContigPartOfSelectedValues(int tupleIdStart, const DataArray *aBase, const DataArrayInt *tuplesSelec) -{ - 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(); - int nbOfComp=getNumberOfComponents(); - if(nbOfComp!=a->getNumberOfComponents()) - throw INTERP_KERNEL::Exception("DataArrayInt::setContigPartOfSelectedValues : This and a do not have the same number of components !"); - if(tuplesSelec->getNumberOfComponents()!=1) - throw INTERP_KERNEL::Exception("DataArrayInt::setContigPartOfSelectedValues : Expecting to have a tuple selector DataArrayInt instance with exactly 1 component !"); - int thisNt=getNumberOfTuples(); - int aNt=a->getNumberOfTuples(); - int nbOfTupleToWrite=tuplesSelec->getNumberOfTuples(); - int *valsToSet=getPointer()+tupleIdStart*nbOfComp; - if(tupleIdStart+nbOfTupleToWrite>thisNt) - throw INTERP_KERNEL::Exception("DataArrayInt::setContigPartOfSelectedValues : invalid number range of values to write !"); - const int *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 DataArrayInt (\a aBase) 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] aBase - the array to copy values from. - * \param [in] bg - index of the first tuple to copy of the array \a aBase. - * \param [in] end2 - index of the tuple of \a aBase 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 aBase is NULL. - * \throw If \a aBase is not allocated. - * \throw If this->getNumberOfComponents() != aBase->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 aBase. - */ -void DataArrayInt::setContigPartOfSelectedValues2(int tupleIdStart, const DataArray *aBase, int bg, int end2, int step) -{ - 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(); - const char msg[]="DataArrayInt::setContigPartOfSelectedValues2"; - int nbOfTupleToWrite=DataArray::GetNumberOfItemGivenBES(bg,end2,step,msg); - if(nbOfComp!=a->getNumberOfComponents()) - throw INTERP_KERNEL::Exception("DataArrayInt::setContigPartOfSelectedValues2 : This and a do not have the same number of components !"); - int thisNt=getNumberOfTuples(); - int aNt=a->getNumberOfTuples(); - int *valsToSet=getPointer()+tupleIdStart*nbOfComp; - if(tupleIdStart+nbOfTupleToWrite>thisNt) - throw INTERP_KERNEL::Exception("DataArrayInt::setContigPartOfSelectedValues2 : invalid number range of values to write !"); - if(end2>aNt) - throw INTERP_KERNEL::Exception("DataArrayInt::setContigPartOfSelectedValues2 : invalid range of values to read !"); - const int *valsSrc=a->getConstPointer()+bg*nbOfComp; - for(int i=0;i( 0 <= tupleId < this->getNumberOfTuples() ) is violated. - * \throw If condition ( 0 <= compoId < this->getNumberOfComponents() ) is violated. - */ -int DataArrayInt::getIJSafe(int tupleId, int compoId) const -{ - checkAllocated(); - if(tupleId<0 || tupleId>=getNumberOfTuples()) - { - std::ostringstream oss; oss << "DataArrayInt::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 << "DataArrayInt::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 first value of \a this. - * \return int - 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::front() const -{ - checkAllocated(); - if(getNumberOfComponents()!=1) - throw INTERP_KERNEL::Exception("DataArrayInt::front : number of components not equal to one !"); - int nbOfTuples=getNumberOfTuples(); - if(nbOfTuples<1) - throw INTERP_KERNEL::Exception("DataArrayInt::front : number of tuples must be >= 1 !"); - return *(getConstPointer()); -} - -/*! - * Returns the last value of \a this. - * \return int - 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 -{ - checkAllocated(); - if(getNumberOfComponents()!=1) - throw INTERP_KERNEL::Exception("DataArrayInt::back : number of components not equal to one !"); - int nbOfTuples=getNumberOfTuples(); - if(nbOfTuples<1) - throw INTERP_KERNEL::Exception("DataArrayInt::back : number of tuples must be >= 1 !"); - 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) - { - if(arrayToSet) - arrayToSet->decrRef(); - arrayToSet=newArray; - if(arrayToSet) - arrayToSet->incrRef(); - } -} - -DataArrayIntIterator *DataArrayInt::iterator() -{ - return new DataArrayIntIterator(this); -} - -/*! - * Creates a new DataArrayInt containing IDs (indices) of tuples holding value equal to a - * given one. The ids are sorted in the ascending order. - * \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. - * \sa DataArrayInt::getIdsEqualTuple - */ -DataArrayInt *DataArrayInt::getIdsEqual(int val) const -{ - 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()); - MEDCouplingAutoRefCountObjectPtr ret(DataArrayInt::New()); ret->alloc(0,1); - int nbOfTuples=getNumberOfTuples(); - for(int i=0;ipushBackSilent(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 -{ - 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()); - MEDCouplingAutoRefCountObjectPtr ret(DataArrayInt::New()); ret->alloc(0,1); - int nbOfTuples=getNumberOfTuples(); - for(int i=0;ipushBackSilent(i); - return ret.retn(); -} - -/*! - * Creates a new DataArrayInt containing IDs (indices) of tuples holding tuple equal to those defined by [ \a tupleBg , \a tupleEnd ) - * This method is an extension of DataArrayInt::getIdsEqual method. - * - * \param [in] tupleBg - the begin (included) of the input tuple to find within \a this. - * \param [in] tupleEnd - the end (excluded) of the input tuple 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() != std::distance(tupleBg,tupleEnd). - * \throw If \a this->getNumberOfComponents() is equal to 0. - * \sa DataArrayInt::getIdsEqual - */ -DataArrayInt *DataArrayInt::getIdsEqualTuple(const int *tupleBg, const int *tupleEnd) const -{ - std::size_t nbOfCompoExp(std::distance(tupleBg,tupleEnd)); - checkAllocated(); - if(getNumberOfComponents()!=(int)nbOfCompoExp) - { - std::ostringstream oss; oss << "DataArrayInt::getIdsEqualTuple : mismatch of number of components. Input tuple has " << nbOfCompoExp << " whereas this array has " << getNumberOfComponents() << " components !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - if(nbOfCompoExp==0) - throw INTERP_KERNEL::Exception("DataArrayInt::getIdsEqualTuple : number of components should be > 0 !"); - MEDCouplingAutoRefCountObjectPtr ret(DataArrayInt::New()); ret->alloc(0,1); - const int *bg(begin()),*end2(end()),*work(begin()); - while(work!=end2) - { - work=std::search(work,end2,tupleBg,tupleEnd); - if(work!=end2) - { - std::size_t pos(std::distance(bg,work)); - if(pos%nbOfCompoExp==0) - ret->pushBackSilent(pos/nbOfCompoExp); - work++; - } - } - return ret.retn(); -} - -/*! - * 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) -{ - checkAllocated(); - if(getNumberOfComponents()!=1) - throw INTERP_KERNEL::Exception("DataArrayInt::changeValue : the array must have only one component, you can call 'rearrange' method before !"); - int *start=getPointer(); - int *end2=start+getNbOfElems(); - int ret=0; - for(int *val=start;val!=end2;val++) - { - if(*val==oldValue) - { - *val=newValue; - ret++; - } - } - 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 -{ - if(getNumberOfComponents()!=1) - throw INTERP_KERNEL::Exception("DataArrayInt::getIdsEqualList : the array must have only one component, you can call 'rearrange' method before !"); - std::set vals2(valsBg,valsEnd); - const int *cptr=getConstPointer(); - std::vector res; - int nbOfTuples=getNumberOfTuples(); - MEDCouplingAutoRefCountObjectPtr ret(DataArrayInt::New()); ret->alloc(0,1); - for(int i=0;ipushBackSilent(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 -{ - if(getNumberOfComponents()!=1) - throw INTERP_KERNEL::Exception("DataArrayInt::getIdsNotEqualList : the array must have only one component, you can call 'rearrange' method before !"); - std::set vals2(valsBg,valsEnd); - const int *cptr=getConstPointer(); - std::vector res; - int nbOfTuples=getNumberOfTuples(); - MEDCouplingAutoRefCountObjectPtr ret(DataArrayInt::New()); ret->alloc(0,1); - for(int i=0;ipushBackSilent(i); - return ret.retn(); -} - -/*! - * This method is an extension of DataArrayInt::locateValue method because this method works for DataArrayInt 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 DataArrayInt::search, DataArrayInt::presenceOfTuple. - */ -int DataArrayInt::locateTuple(const std::vector& tupl) const -{ - checkAllocated(); - int nbOfCompo=getNumberOfComponents(); - if(nbOfCompo==0) - throw INTERP_KERNEL::Exception("DataArrayInt::locateTuple : 0 components in 'this' !"); - if(nbOfCompo!=(int)tupl.size()) - { - std::ostringstream oss; oss << "DataArrayInt::locateTuple : 'this' contains " << nbOfCompo << " components and searching for a tuple of length " << tupl.size() << " !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - const int *cptr=getConstPointer(); - std::size_t nbOfVals=getNbOfElems(); - for(const int *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 searches the sequence specified in input parameter \b vals in \b this. - * This works only for DataArrayInt having number of components equal to one (if not an INTERP_KERNEL::Exception will be thrown). - * This method differs from DataArrayInt::locateTuple in that the position is internal raw data is not considered here contrary to DataArrayInt::locateTuple. - * \sa DataArrayInt::locateTuple - */ -int DataArrayInt::search(const std::vector& vals) const -{ - 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(); - 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); - 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 equal to \b value. - * If not any tuple contains \b value -1 is returned. - * \sa DataArrayInt::presenceOfValue - */ -int DataArrayInt::locateValue(int value) const -{ - 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(); - int nbOfTuples=getNumberOfTuples(); - const int *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 DataArrayInt::presenceOfValue - */ -int DataArrayInt::locateValue(const std::vector& vals) const -{ - 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; -} - -/*! - * 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 -{ - 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 -{ - 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 DataArrayInt::presenceOfValue(int value) const -{ - 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 DataArrayInt::locateValue - */ -bool DataArrayInt::presenceOfValue(const std::vector& vals) const -{ - 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 -{ - 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 -{ - 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 -{ - 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) - throw INTERP_KERNEL::Exception("DataArrayInt::Aggregate : input DataArrayInt instance is NULL !"); - int nbOfComp=a1->getNumberOfComponents(); - if(nbOfComp!=a2->getNumberOfComponents()) - throw INTERP_KERNEL::Exception("Nb of components mismatch for array Aggregation !"); - int nbOfTuple1=a1->getNumberOfTuples(); - int nbOfTuple2=a2->getNumberOfTuples(); - DataArrayInt *ret=DataArrayInt::New(); - ret->alloc(nbOfTuple1+nbOfTuple2-offsetA2,nbOfComp); - int *pt=std::copy(a1->getConstPointer(),a1->getConstPointer()+nbOfTuple1*nbOfComp,ret->getPointer()); - std::copy(a2->getConstPointer()+offsetA2*nbOfComp,a2->getConstPointer()+nbOfTuple2*nbOfComp,pt); - ret->copyStringInfoFrom(*a1); - 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. - * If the number of non null of elements in \a arr is equal to one the returned object is a copy of it - * not the object itself. - * \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) -{ - 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("DataArrayInt::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("DataArrayInt::Aggregate : Nb of components mismatch for array aggregation !"); - nbt+=(*it)->getNumberOfTuples(); - } - 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.retn(); -} - -/*! - * This method takes as input a list of DataArrayInt instances \a arrs that represent each a packed index arrays. - * A packed index array is an allocated array with one component, and at least one tuple. The first element - * of each array in \a arrs must be 0. Each array in \a arrs is expected to be increasingly monotonic. - * This method is useful for users that want to aggregate a pair of DataArrayInt representing an indexed data (typically nodal connectivity index in unstructured meshes. - * - * \return DataArrayInt * - a new object to be managed by the caller. - */ -DataArrayInt *DataArrayInt::AggregateIndexes(const std::vector& arrs) -{ - int retSz=1; - for(std::vector::const_iterator it4=arrs.begin();it4!=arrs.end();it4++) - { - if(*it4) - { - (*it4)->checkAllocated(); - if((*it4)->getNumberOfComponents()!=1) - { - std::ostringstream oss; oss << "DataArrayInt::AggregateIndexes : presence of a DataArrayInt instance with nb of compo != 1 at pos " << std::distance(arrs.begin(),it4) << " !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - int nbTupl=(*it4)->getNumberOfTuples(); - if(nbTupl<1) - { - std::ostringstream oss; oss << "DataArrayInt::AggregateIndexes : presence of a DataArrayInt instance with nb of tuples < 1 at pos " << std::distance(arrs.begin(),it4) << " !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - if((*it4)->front()!=0) - { - std::ostringstream oss; oss << "DataArrayInt::AggregateIndexes : presence of a DataArrayInt instance with front value != 0 at pos " << std::distance(arrs.begin(),it4) << " !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - retSz+=nbTupl-1; - } - else - { - std::ostringstream oss; oss << "DataArrayInt::AggregateIndexes : presence of a null instance at pos " << std::distance(arrs.begin(),it4) << " !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - } - if(arrs.empty()) - throw INTERP_KERNEL::Exception("DataArrayInt::AggregateIndexes : input list must be NON EMPTY !"); - MEDCouplingAutoRefCountObjectPtr ret=DataArrayInt::New(); - ret->alloc(retSz,1); - int *pt=ret->getPointer(); *pt++=0; - for(std::vector::const_iterator it=arrs.begin();it!=arrs.end();it++) - pt=std::transform((*it)->begin()+1,(*it)->end(),pt,std::bind2nd(std::plus(),pt[-1])); - ret->copyStringInfoFrom(*(arrs[0])); - 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 -{ - checkAllocated(); - if(getNumberOfComponents()!=1) - throw INTERP_KERNEL::Exception("DataArrayInt::getMaxValue : must be applied on DataArrayInt with only one component !"); - int nbOfTuples=getNumberOfTuples(); - if(nbOfTuples<=0) - throw INTERP_KERNEL::Exception("DataArrayInt::getMaxValue : array exists but number of tuples must be > 0 !"); - const int *vals=getConstPointer(); - const int *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 int - the maximal value among all values of \a this array. - * \throw If \a this is not allocated. - */ -int DataArrayInt::getMaxValueInArray() const -{ - checkAllocated(); - const int *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 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 -{ - checkAllocated(); - if(getNumberOfComponents()!=1) - throw INTERP_KERNEL::Exception("DataArrayInt::getMaxValue : must be applied on DataArrayInt with only one component !"); - int nbOfTuples=getNumberOfTuples(); - if(nbOfTuples<=0) - throw INTERP_KERNEL::Exception("DataArrayInt::getMaxValue : array exists but number of tuples must be > 0 !"); - const int *vals=getConstPointer(); - const int *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 int - the minimal value among all values of \a this array. - * \throw If \a this is not allocated. - */ -int DataArrayInt::getMinValueInArray() const -{ - checkAllocated(); - const int *loc=std::min_element(begin(),end()); - return *loc; -} - -/*! - * Returns in a single walk in \a this the min value and the max value in \a this. - * \a this is expected to be single component array. - * - * \param [out] minValue - the min value in \a this. - * \param [out] maxValue - the max value in \a this. - * - * \sa getMinValueInArray, getMinValue, getMaxValueInArray, getMaxValue - */ -void DataArrayInt::getMinMaxValues(int& minValue, int& maxValue) const -{ - checkAllocated(); - if(getNumberOfComponents()!=1) - throw INTERP_KERNEL::Exception("DataArrayInt::getMinMaxValues : must be applied on DataArrayInt with only one component !"); - int nbTuples(getNumberOfTuples()); - const int *pt(begin()); - minValue=std::numeric_limits::max(); maxValue=-std::numeric_limits::max(); - for(int i=0;imaxValue) - maxValue=*pt; - } -} - -/*! - * Converts every value of \a this array to its absolute value. - * \b WARNING this method is non const. If a new DataArrayInt instance should be built containing the result of abs DataArrayInt::computeAbs - * should be called instead. - * - * \throw If \a this is not allocated. - * \sa DataArrayInt::computeAbs - */ -void DataArrayInt::abs() -{ - checkAllocated(); - int *ptr(getPointer()); - std::size_t nbOfElems(getNbOfElems()); - std::transform(ptr,ptr+nbOfElems,ptr,std::ptr_fun(std::abs)); - declareAsNew(); -} - -/*! - * This method builds a new instance of \a this object containing the result of std::abs applied of all elements in \a this. - * This method is a const method (that do not change any values in \a this) contrary to DataArrayInt::abs method. - * - * \return DataArrayInt * - the new instance of DataArrayInt 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. - * \sa DataArrayInt::abs - */ -DataArrayInt *DataArrayInt::computeAbs() const -{ - checkAllocated(); - DataArrayInt *newArr(DataArrayInt::New()); - int nbOfTuples(getNumberOfTuples()); - int nbOfComp(getNumberOfComponents()); - newArr->alloc(nbOfTuples,nbOfComp); - std::transform(begin(),end(),newArr->getPointer(),std::ptr_fun(std::abs)); - newArr->copyStringInfoFrom(*this); - return newArr; -} - -/*! - * 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) -{ - checkAllocated(); - int *ptr=getPointer()+compoId; - int nbOfComp=getNumberOfComponents(); - int nbOfTuple=getNumberOfTuples(); - for(int i=0;ialloc(nbOfTuples,nbOfComp); - const int *cptr=getConstPointer(); - std::transform(cptr,cptr+nbOfTuples*nbOfComp,newArr->getPointer(),std::negate()); - newArr->copyStringInfoFrom(*this); - return newArr; -} - -/*! - * Modify all elements of \a this array, so that - * an element _x_ becomes \f$ numerator / x \f$. - * \warning If an exception is thrown because of presence of 0 element in \a this - * array, all elements processed before detection of the zero element remain - * modified. - * \param [in] numerator - the numerator used to modify array elements. - * \throw If \a this is not allocated. - * \throw If there is an element equal to 0 in \a this array. - */ -void DataArrayInt::applyInv(int numerator) -{ - checkAllocated(); - int *ptr=getPointer(); - std::size_t nbOfElems=getNbOfElems(); - for(std::size_t 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) -{ - if(val<=0) - throw INTERP_KERNEL::Exception("DataArrayInt::applyDivideBy : Trying to operate modulus on value <= 0 !"); - checkAllocated(); - int *ptr=getPointer(); - std::size_t nbOfElems=getNbOfElems(); - std::transform(ptr,ptr+nbOfElems,ptr,std::bind2nd(std::modulus(),val)); - declareAsNew(); -} - -/*! - * 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 (included). - * \param [in] 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. - * - * \sa DataArrayInt::getIdsNotInRange , DataArrayInt::getIdsStrictlyNegative - */ -DataArrayInt *DataArrayInt::getIdsInRange(int vmin, int vmax) const -{ - checkAllocated(); - if(getNumberOfComponents()!=1) - throw INTERP_KERNEL::Exception("DataArrayInt::getIdsInRange : this must have exactly one component !"); - const int *cptr(begin()); - MEDCouplingAutoRefCountObjectPtr ret(DataArrayInt::New()); ret->alloc(0,1); - int nbOfTuples(getNumberOfTuples()); - for(int i=0;i=vmin && *cptrpushBackSilent(i); - return ret.retn(); -} - -/*! - * 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] \b not in [\b vmin,\b vmax) - * - * \param [in] vmin begin of range. This value is \b not included in range (excluded). - * \param [in] vmax end of range. This value is included in range (included). - * \return a newly allocated data array that the caller should deal with. - * - * \sa DataArrayInt::getIdsInRange , DataArrayInt::getIdsStrictlyNegative - */ -DataArrayInt *DataArrayInt::getIdsNotInRange(int vmin, int vmax) const -{ - checkAllocated(); - if(getNumberOfComponents()!=1) - throw INTERP_KERNEL::Exception("DataArrayInt::getIdsNotInRange : this must have exactly one component !"); - const int *cptr(getConstPointer()); - MEDCouplingAutoRefCountObjectPtr ret(DataArrayInt::New()); ret->alloc(0,1); - int nbOfTuples(getNumberOfTuples()); - for(int i=0;i=vmax) - ret->pushBackSilent(i); - return ret.retn(); -} - -/*! - * This method works only on data array with one component. This method returns a newly allocated array storing stored ascendantly of tuple ids in \a this so that this[id]<0. - * - * \return a newly allocated data array that the caller should deal with. - * \sa DataArrayInt::getIdsInRange - */ -DataArrayInt *DataArrayInt::getIdsStrictlyNegative() const -{ - checkAllocated(); - if(getNumberOfComponents()!=1) - throw INTERP_KERNEL::Exception("DataArrayInt::getIdsStrictlyNegative : this must have exactly one component !"); - const int *cptr(getConstPointer()); - MEDCouplingAutoRefCountObjectPtr ret(DataArrayInt::New()); ret->alloc(0,1); - int nbOfTuples(getNumberOfTuples()); - for(int i=0;ipushBackSilent(i); - return ret.retn(); -} - -/*! - * This method works only on data array with one component. - * This method checks that all ids in \b this are in [ \b vmin, \b vmax ). If there is at least one element in \a this not in [ \b vmin, \b vmax ) an exception will be thrown. - * - * \param [in] vmin begin of range. This value is included in range (included). - * \param [in] vmax end of range. This value is \b not included in range (excluded). - * \return if all ids in \a this are so that (*this)[i]==i for all i in [ 0, \c this->getNumberOfTuples() ). */ -bool DataArrayInt::checkAllIdsInRange(int vmin, int vmax) const -{ - checkAllocated(); - if(getNumberOfComponents()!=1) - throw INTERP_KERNEL::Exception("DataArrayInt::checkAllIdsInRange : this must have exactly one component !"); - int nbOfTuples=getNumberOfTuples(); - bool ret=true; - const int *cptr=getConstPointer(); - for(int i=0;i=vmin && *cptr 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) -{ - checkAllocated(); - int *ptr=getPointer(); - std::size_t nbOfElems=getNbOfElems(); - for(std::size_t i=0;i0) - { - *ptr=val%(*ptr); - } - else - { - std::ostringstream oss; oss << "DataArrayInt::applyRModulus : presence of value <=0 in tuple #" << i/getNumberOfComponents() << " component #" << i%getNumberOfComponents(); - oss << " !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - } - 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) -{ - 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) -{ - std::vector arr(2); - arr[0]=a1; arr[1]=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) -{ - 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("DataArrayInt::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("DataArrayInt::meld : mismatch of number of tuples !"); - nbc[i]=(*it)->getNumberOfComponents(); - pts[i]=(*it)->getConstPointer(); - } - int totalNbOfComp=std::accumulate(nbc.begin(),nbc.end(),0); - DataArrayInt *ret=DataArrayInt::New(); - ret->alloc(nbOfTuples,totalNbOfComp); - int *retPtr=ret->getPointer(); - for(int i=0;isetInfoOnComponent(k,a[i]->getInfoOnComponent(j)); - return ret; -} - -/*! - * Returns a new DataArrayInt which is a minimal partition of elements of \a groups. - * The i-th item of the result array is an ID of a set of elements belonging to a - * unique set of groups, which the i-th element is a part of. This set of elements - * belonging to a unique set of groups is called \a family, so the result array contains - * IDs of families each element belongs to. - * - * \b Example: if we have two groups of elements: \a group1 [0,4] and \a group2 [ 0,1,2 ], - * then there are 3 families: - * - \a family1 (with ID 1) contains element [0] belonging to ( \a group1 + \a group2 ), - * - \a family2 (with ID 2) contains elements [4] belonging to ( \a group1 ), - * - \a family3 (with ID 3) contains element [1,2] belonging to ( \a group2 ),
- * 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 [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) -{ - std::vector groups2; - for(std::vector::const_iterator it4=groups.begin();it4!=groups.end();it4++) - if(*it4) - groups2.push_back(*it4); - MEDCouplingAutoRefCountObjectPtr ret=DataArrayInt::New(); - ret->alloc(newNb,1); - int *retPtr=ret->getPointer(); - std::fill(retPtr,retPtr+newNb,0); - int fid=1; - for(std::vector::const_iterator iter=groups2.begin();iter!=groups2.end();iter++) - { - const int *ptr=(*iter)->getConstPointer(); - std::size_t nbOfElem=(*iter)->getNbOfElems(); - int sfid=fid; - for(int j=0;j=0 && ptr[i]getName() << "\" in tuple #" << i << " value = " << ptr[i] << " ! Should be in [0," << newNb; - oss << ") !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - } - if(found) - fid++; - } - } - fidsOfGroups.clear(); - fidsOfGroups.resize(groups2.size()); - int grId=0; - for(std::vector::const_iterator iter=groups2.begin();iter!=groups2.end();iter++,grId++) - { - std::set tmp; - const int *ptr=(*iter)->getConstPointer(); - 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()); - } - 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) -{ - std::vector a; - for(std::vector::const_iterator it4=arr.begin();it4!=arr.end();it4++) - if(*it4) - a.push_back(*it4); - 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 !"); - } - // - std::set r; - for(std::vector::const_iterator it=a.begin();it!=a.end();it++) - { - const int *pt=(*it)->getConstPointer(); - int nbOfTuples=(*it)->getNumberOfTuples(); - r.insert(pt,pt+nbOfTuples); - } - DataArrayInt *ret=DataArrayInt::New(); - ret->alloc((int)r.size(),1); - std::copy(r.begin(),r.end(),ret->getPointer()); - 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) -{ - std::vector a; - for(std::vector::const_iterator it4=arr.begin();it4!=arr.end();it4++) - if(*it4) - a.push_back(*it4); - for(std::vector::const_iterator it=a.begin();it!=a.end();it++) - { - (*it)->checkAllocated(); - if((*it)->getNumberOfComponents()!=1) - throw INTERP_KERNEL::Exception("DataArrayInt::BuildIntersection : only single component allowed !"); - } - // - std::set r; - for(std::vector::const_iterator it=a.begin();it!=a.end();it++) - { - const int *pt=(*it)->getConstPointer(); - int nbOfTuples=(*it)->getNumberOfTuples(); - std::set s1(pt,pt+nbOfTuples); - if(it!=a.begin()) - { - std::set r2; - std::set_intersection(r.begin(),r.end(),s1.begin(),s1.end(),inserter(r2,r2.end())); - r=r2; - } - else - r=s1; - } - DataArrayInt *ret(DataArrayInt::New()); - ret->alloc((int)r.size(),1); - std::copy(r.begin(),r.end(),ret->getPointer()); - return ret; -} - -/// @cond INTERNAL -namespace ParaMEDMEMImpl -{ - class OpSwitchedOn - { - public: - OpSwitchedOn(int *pt):_pt(pt),_cnt(0) { } - void operator()(const bool& b) { if(b) *_pt++=_cnt; _cnt++; } - private: - int *_pt; - int _cnt; - }; - - class OpSwitchedOff - { - public: - OpSwitchedOff(int *pt):_pt(pt),_cnt(0) { } - void operator()(const bool& b) { if(!b) *_pt++=_cnt; _cnt++; } - private: - int *_pt; - int _cnt; - }; -} -/// @endcond - -/*! - * This method returns the list of ids in ascending mode so that v[id]==true. - */ -DataArrayInt *DataArrayInt::BuildListOfSwitchedOn(const std::vector& v) -{ - int sz((int)std::count(v.begin(),v.end(),true)); - MEDCouplingAutoRefCountObjectPtr ret(DataArrayInt::New()); ret->alloc(sz,1); - std::for_each(v.begin(),v.end(),ParaMEDMEMImpl::OpSwitchedOn(ret->getPointer())); - return ret.retn(); -} - -/*! - * This method returns the list of ids in ascending mode so that v[id]==false. - */ -DataArrayInt *DataArrayInt::BuildListOfSwitchedOff(const std::vector& v) -{ - int sz((int)std::count(v.begin(),v.end(),false)); - MEDCouplingAutoRefCountObjectPtr ret(DataArrayInt::New()); ret->alloc(sz,1); - std::for_each(v.begin(),v.end(),ParaMEDMEMImpl::OpSwitchedOff(ret->getPointer())); - return ret.retn(); -} - -/*! - * This method allows to put a vector of vector of integer into a more compact data stucture (skyline). - * This method is not available into python because no available optimized data structure available to map std::vector< std::vector >. - * - * \param [in] v the input data structure to be translate into skyline format. - * \param [out] data the first element of the skyline format. The user is expected to deal with newly allocated array. - * \param [out] dataIndex the second element of the skyline format. - */ -void DataArrayInt::PutIntoToSkylineFrmt(const std::vector< std::vector >& v, DataArrayInt *& data, DataArrayInt *& dataIndex) -{ - int sz((int)v.size()); - MEDCouplingAutoRefCountObjectPtr ret0(DataArrayInt::New()),ret1(DataArrayInt::New()); - ret1->alloc(sz+1,1); - int *pt(ret1->getPointer()); *pt=0; - for(int i=0;ialloc(ret1->back(),1); - pt=ret0->getPointer(); - for(int i=0;igetNumberOfComponents() != 1. - * \throw If any element \a x of \a this array violates condition ( 0 <= \a x < \a - * nbOfElement ). - */ -DataArrayInt *DataArrayInt::buildComplement(int nbOfElement) const -{ - checkAllocated(); - if(getNumberOfComponents()!=1) - throw INTERP_KERNEL::Exception("DataArrayInt::buildComplement : only single component allowed !"); - std::vector tmp(nbOfElement); - const int *pt=getConstPointer(); - int nbOfTuples=getNumberOfTuples(); - for(const int *w=pt;w!=pt+nbOfTuples;w++) - if(*w>=0 && *walloc(nbOfRetVal,1); - int j=0; - int *retPtr=ret->getPointer(); - for(int i=0;igetNumberOfComponents() != 1. - * \throw If \a this is not allocated. - * \throw If \a this->getNumberOfComponents() != 1. - * \sa DataArrayInt::buildSubstractionOptimized() - */ -DataArrayInt *DataArrayInt::buildSubstraction(const DataArrayInt *other) const -{ - if(!other) - throw INTERP_KERNEL::Exception("DataArrayInt::buildSubstraction : DataArrayInt pointer in input is NULL !"); - checkAllocated(); - other->checkAllocated(); - if(getNumberOfComponents()!=1) - throw INTERP_KERNEL::Exception("DataArrayInt::buildSubstraction : only single component allowed !"); - if(other->getNumberOfComponents()!=1) - throw INTERP_KERNEL::Exception("DataArrayInt::buildSubstraction : only single component allowed for other type !"); - const int *pt=getConstPointer(); - int nbOfTuples=getNumberOfTuples(); - std::set s1(pt,pt+nbOfTuples); - pt=other->getConstPointer(); - nbOfTuples=other->getNumberOfTuples(); - std::set s2(pt,pt+nbOfTuples); - std::vector r; - std::set_difference(s1.begin(),s1.end(),s2.begin(),s2.end(),std::back_insert_iterator< std::vector >(r)); - DataArrayInt *ret=DataArrayInt::New(); - ret->alloc((int)r.size(),1); - std::copy(r.begin(),r.end(),ret->getPointer()); - 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 -{ - 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()); - const int *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 -{ - std::vectorarrs(2); - arrs[0]=this; arrs[1]=other; - 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 -{ - std::vectorarrs(2); - arrs[0]=this; arrs[1]=other; - return BuildIntersection(arrs); -} - -/*! - * This method can be applied on allocated with one component DataArrayInt instance. - * This method is typically relevant for sorted arrays. All consecutive duplicated items in \a this will appear only once in returned DataArrayInt instance. - * Example : if \a this contains [1,2,2,3,3,3,3,4,5,5,7,7,7,19] the returned array will contain [1,2,3,4,5,7,19] - * - * \return a newly allocated array that contain the result of the unique operation applied on \a this. - * \throw if \a this is not allocated or if \a this has not exactly one component. - * \sa DataArrayInt::buildUniqueNotSorted - */ -DataArrayInt *DataArrayInt::buildUnique() const -{ - checkAllocated(); - if(getNumberOfComponents()!=1) - throw INTERP_KERNEL::Exception("DataArrayInt::buildUnique : only single component allowed !"); - int nbOfTuples=getNumberOfTuples(); - MEDCouplingAutoRefCountObjectPtr tmp=deepCpy(); - int *data=tmp->getPointer(); - int *last=std::unique(data,data+nbOfTuples); - MEDCouplingAutoRefCountObjectPtr ret=DataArrayInt::New(); - ret->alloc(std::distance(data,last),1); - std::copy(data,last,ret->getPointer()); - return ret.retn(); -} - -/*! - * This method can be applied on allocated with one component DataArrayInt instance. - * This method keep elements only once by keeping the same order in \a this that is not expected to be sorted. - * - * \return a newly allocated array that contain the result of the unique operation applied on \a this. - * - * \throw if \a this is not allocated or if \a this has not exactly one component. - * - * \sa DataArrayInt::buildUnique - */ -DataArrayInt *DataArrayInt::buildUniqueNotSorted() const -{ - checkAllocated(); - if(getNumberOfComponents()!=1) - throw INTERP_KERNEL::Exception("DataArrayInt::buildUniqueNotSorted : only single component allowed !"); - int minVal,maxVal; - getMinMaxValues(minVal,maxVal); - std::vector b(maxVal-minVal+1,false); - const int *ptBg(begin()),*endBg(end()); - MEDCouplingAutoRefCountObjectPtr ret(DataArrayInt::New()); ret->alloc(0,1); - for(const int *pt=ptBg;pt!=endBg;pt++) - { - if(!b[*pt-minVal]) - { - ret->pushBackSilent(*pt); - b[*pt-minVal]=true; - } - } - ret->copyStringInfoFrom(*this); - return ret.retn(); -} - -/*! - * 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. - * This method preforms the reverse operation of DataArrayInt::computeOffsets2. - * \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. - * - * \sa DataArrayInt::computeOffsets2 - */ -DataArrayInt *DataArrayInt::deltaShiftIndex() const -{ - checkAllocated(); - if(getNumberOfComponents()!=1) - throw INTERP_KERNEL::Exception("DataArrayInt::deltaShiftIndex : only single component allowed !"); - int nbOfTuples=getNumberOfTuples(); - if(nbOfTuples<2) - throw INTERP_KERNEL::Exception("DataArrayInt::deltaShiftIndex : 1 tuple at least must be present in 'this' !"); - const int *ptr=getConstPointer(); - DataArrayInt *ret=DataArrayInt::New(); - ret->alloc(nbOfTuples-1,1); - int *out=ret->getPointer(); - std::transform(ptr+1,ptr+nbOfTuples,ptr,out,std::minus()); - return ret; -} - -/*! - * 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() -{ - checkAllocated(); - if(getNumberOfComponents()!=1) - throw INTERP_KERNEL::Exception("DataArrayInt::computeOffsets : only single component allowed !"); - int nbOfTuples=getNumberOfTuples(); - if(nbOfTuples==0) - return ; - int *work=getPointer(); - int tmp=work[0]; - work[0]=0; - for(int i=1;i0 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. - * This method preforms the reverse operation of DataArrayInt::deltaShiftIndex. - * \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]
- * \sa DataArrayInt::deltaShiftIndex - */ -void DataArrayInt::computeOffsets2() -{ - checkAllocated(); - if(getNumberOfComponents()!=1) - throw INTERP_KERNEL::Exception("DataArrayInt::computeOffsets2 : only single component allowed !"); - int nbOfTuples=getNumberOfTuples(); - int *ret=(int *)malloc((nbOfTuples+1)*sizeof(int)); - if(nbOfTuples==0) - return ; - const int *work=getConstPointer(); - ret[0]=0; - for(int i=0;igetNumberOfComponents() 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 -{ - 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 -{ - if(!offsets) - throw INTERP_KERNEL::Exception("DataArrayInt::buildExplicitArrByRanges : DataArrayInt pointer in input is NULL !"); - checkAllocated(); - if(getNumberOfComponents()!=1) - throw INTERP_KERNEL::Exception("DataArrayInt::buildExplicitArrByRanges : only single component allowed !"); - offsets->checkAllocated(); - if(offsets->getNumberOfComponents()!=1) - throw INTERP_KERNEL::Exception("DataArrayInt::buildExplicitArrByRanges : input array should have only single component !"); - int othNbTuples=offsets->getNumberOfTuples()-1; - int nbOfTuples=getNumberOfTuples(); - int retNbOftuples=0; - const int *work=getConstPointer(); - const int *offPtr=offsets->getConstPointer(); - for(int i=0;i=0 && val=0) - retNbOftuples+=delta; - else - { - std::ostringstream oss; oss << "DataArrayInt::buildExplicitArrByRanges : Tuple #" << val << " of offset array has a delta < 0 !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - } - else - { - std::ostringstream oss; oss << "DataArrayInt::buildExplicitArrByRanges : Tuple #" << i << " in this contains " << val; - oss << " whereas offsets array is of size " << othNbTuples+1 << " !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - } - MEDCouplingAutoRefCountObjectPtr ret=DataArrayInt::New(); - ret->alloc(retNbOftuples,1); - int *retPtr=ret->getPointer(); - for(int i=0;igetNumberOfComponents() != 1. - * \throw If \a this->getNumberOfTuples() == 0. - * \throw If \a this is not monotonically increasing. - * \throw If any element of ids in ( \a bg \a stop \a step ) points outside the scale in \a this. - * - * \b Example:
- * - \a bg , \a stop and \a step : (0,5,2) - * - \a this: [0,3,6,10,14,20] - * - result array: [0,0,0, 2,2,2,2, 4,4,4,4,4,4] ==
- */ -DataArrayInt *DataArrayInt::buildExplicitArrOfSliceOnScaledArr(int bg, int stop, int step) const -{ - if(!isAllocated()) - throw INTERP_KERNEL::Exception("DataArrayInt::buildExplicitArrOfSliceOnScaledArr : not allocated array !"); - if(getNumberOfComponents()!=1) - throw INTERP_KERNEL::Exception("DataArrayInt::buildExplicitArrOfSliceOnScaledArr : number of components is expected to be equal to one !"); - int nbOfTuples(getNumberOfTuples()); - if(nbOfTuples==0) - throw INTERP_KERNEL::Exception("DataArrayInt::buildExplicitArrOfSliceOnScaledArr : number of tuples must be != 0 !"); - const int *ids(begin()); - int nbOfEltsInSlc(GetNumberOfItemGivenBESRelative(bg,stop,step,"DataArrayInt::buildExplicitArrOfSliceOnScaledArr")),sz(0),pos(bg); - for(int i=0;i=0 && pos ret(DataArrayInt::New()); ret->alloc(sz,1); - int *retPtr(ret->getPointer()); - pos=bg; - for(int i=0;igetIJ(i,0) and put the result - * in tuple **i** of returned DataArrayInt. - * If ranges overlapped (in theory it should not) this method do not detect it and always returns the first range. - * - * For example if \a this contains : [1,24,7,8,10,17] and \a ranges contains [(0,3),(3,8),(8,15),(15,22),(22,30)] - * The return DataArrayInt will contain : **[0,4,1,2,2,3]** - * - * \param [in] ranges typically come from output of MEDCouplingUMesh::ComputeRangesFromTypeDistribution. Each range is specified like this : 1st component is - * for lower value included and 2nd component is the upper value of corresponding range **excluded**. - * \throw If offsets is a null pointer or does not have 2 components or if \a this is not allocated or \a this do not have exactly one component. To finish an exception - * is thrown if no ranges in \a ranges contains value in \a this. - * - * \sa DataArrayInt::findIdInRangeForEachTuple - */ -DataArrayInt *DataArrayInt::findRangeIdForEachTuple(const DataArrayInt *ranges) const -{ - if(!ranges) - throw INTERP_KERNEL::Exception("DataArrayInt::findRangeIdForEachTuple : null input pointer !"); - if(ranges->getNumberOfComponents()!=2) - throw INTERP_KERNEL::Exception("DataArrayInt::findRangeIdForEachTuple : input DataArrayInt instance should have 2 components !"); - checkAllocated(); - if(getNumberOfComponents()!=1) - throw INTERP_KERNEL::Exception("DataArrayInt::findRangeIdForEachTuple : this should have only one component !"); - int nbTuples=getNumberOfTuples(); - MEDCouplingAutoRefCountObjectPtr ret=DataArrayInt::New(); ret->alloc(nbTuples,1); - int nbOfRanges=ranges->getNumberOfTuples(); - const int *rangesPtr=ranges->getConstPointer(); - int *retPtr=ret->getPointer(); - const int *inPtr=getConstPointer(); - for(int i=0;i=rangesPtr[2*j] && valgetIJ(i,0) and put the result - * in tuple **i** of returned DataArrayInt. - * If ranges overlapped (in theory it should not) this method do not detect it and always returns the sub position of the first range. - * - * For example if \a this contains : [1,24,7,8,10,17] and \a ranges contains [(0,3),(3,8),(8,15),(15,22),(22,30)] - * The return DataArrayInt will contain : **[1,2,4,0,2,2]** - * This method is often called in pair with DataArrayInt::findRangeIdForEachTuple method. - * - * \param [in] ranges typically come from output of MEDCouplingUMesh::ComputeRangesFromTypeDistribution. Each range is specified like this : 1st component is - * for lower value included and 2nd component is the upper value of corresponding range **excluded**. - * \throw If offsets is a null pointer or does not have 2 components or if \a this is not allocated or \a this do not have exactly one component. To finish an exception - * is thrown if no ranges in \a ranges contains value in \a this. - * \sa DataArrayInt::findRangeIdForEachTuple - */ -DataArrayInt *DataArrayInt::findIdInRangeForEachTuple(const DataArrayInt *ranges) const -{ - if(!ranges) - throw INTERP_KERNEL::Exception("DataArrayInt::findIdInRangeForEachTuple : null input pointer !"); - if(ranges->getNumberOfComponents()!=2) - throw INTERP_KERNEL::Exception("DataArrayInt::findIdInRangeForEachTuple : input DataArrayInt instance should have 2 components !"); - checkAllocated(); - if(getNumberOfComponents()!=1) - throw INTERP_KERNEL::Exception("DataArrayInt::findIdInRangeForEachTuple : this should have only one component !"); - int nbTuples=getNumberOfTuples(); - MEDCouplingAutoRefCountObjectPtr ret=DataArrayInt::New(); ret->alloc(nbTuples,1); - int nbOfRanges=ranges->getNumberOfTuples(); - const int *rangesPtr=ranges->getConstPointer(); - int *retPtr=ret->getPointer(); - const int *inPtr=getConstPointer(); - for(int i=0;i=rangesPtr[2*j] && valgetIJ(tid,0)==this->getIJ(tid-1,1) and \c this->getIJ(tid,1)==this->getIJ(tid+1,0). - * If it is impossible to reach such condition an exception will be thrown ! \b WARNING In case of throw \a this can be partially modified ! - * If this method has correctly worked, \a this will be able to be considered as a linked list. - * This method does nothing if number of tuples is lower of equal to 1. - * - * This method is useful for users having an unstructured mesh having only SEG2 to rearrange internaly the connectibity without any coordinates consideration. - * - * \sa MEDCouplingUMesh::orderConsecutiveCells1D - */ -void DataArrayInt::sortEachPairToMakeALinkedList() -{ - checkAllocated(); - if(getNumberOfComponents()!=2) - throw INTERP_KERNEL::Exception("DataArrayInt::sortEachPairToMakeALinkedList : Only works on DataArrayInt instance with nb of components equal to 2 !"); - int nbOfTuples(getNumberOfTuples()); - if(nbOfTuples<=1) - return ; - int *conn(getPointer()); - for(int i=1;i1) - { - if(conn[2]==conn[3]) - { - std::ostringstream oss; oss << "DataArrayInt::sortEachPairToMakeALinkedList : In the tuple #" << i << " presence of a pair filled with same ids !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - if(conn[2]!=conn[1] && conn[3]==conn[1] && conn[2]!=conn[0]) - std::swap(conn[2],conn[3]); - //not(conn[2]==conn[1] && conn[3]!=conn[1] && conn[3]!=conn[0]) - if(conn[2]!=conn[1] || conn[3]==conn[1] || conn[3]==conn[0]) - { - std::ostringstream oss; oss << "DataArrayInt::sortEachPairToMakeALinkedList : In the tuple #" << i << " something is invalid !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - } - else - { - if(conn[0]==conn[1] || conn[2]==conn[3]) - throw INTERP_KERNEL::Exception("DataArrayInt::sortEachPairToMakeALinkedList : In the 2 first tuples presence of a pair filled with same ids !"); - int tmp[4]; - std::set s; - s.insert(conn,conn+4); - if(s.size()!=3) - throw INTERP_KERNEL::Exception("DataArrayInt::sortEachPairToMakeALinkedList : This can't be considered as a linked list regarding 2 first tuples !"); - if(std::count(conn,conn+4,conn[0])==2) - { - tmp[0]=conn[1]; - tmp[1]=conn[0]; - tmp[2]=conn[0]; - if(conn[2]==conn[0]) - { tmp[3]=conn[3]; } - else - { tmp[3]=conn[2];} - std::copy(tmp,tmp+4,conn); - } - } - } -} - -/*! - * - * \param [in] nbTimes specifies the nb of times each tuples in \a this will be duplicated contiguouly in returned DataArrayInt instance. - * \a nbTimes should be at least equal to 1. - * \return a newly allocated DataArrayInt having one component and number of tuples equal to \a nbTimes * \c this->getNumberOfTuples. - * \throw if \a this is not allocated or if \a this has not number of components set to one or if \a nbTimes is lower than 1. - */ -DataArrayInt *DataArrayInt::duplicateEachTupleNTimes(int nbTimes) const -{ - checkAllocated(); - if(getNumberOfComponents()!=1) - throw INTERP_KERNEL::Exception("DataArrayInt::duplicateEachTupleNTimes : this should have only one component !"); - if(nbTimes<1) - throw INTERP_KERNEL::Exception("DataArrayInt::duplicateEachTupleNTimes : nb times should be >= 1 !"); - int nbTuples=getNumberOfTuples(); - const int *inPtr=getConstPointer(); - MEDCouplingAutoRefCountObjectPtr ret=DataArrayInt::New(); ret->alloc(nbTimes*nbTuples,1); - int *retPtr=ret->getPointer(); - for(int i=0;icopyStringInfoFrom(*this); - 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. - */ -DataArrayInt *DataArrayInt::getDifferentValues() const -{ - checkAllocated(); - std::set ret; - ret.insert(begin(),end()); - MEDCouplingAutoRefCountObjectPtr ret2=DataArrayInt::New(); ret2->alloc((int)ret.size(),1); - std::copy(ret.begin(),ret.end(),ret2->getPointer()); - return ret2.retn(); -} - -/*! - * This method is a refinement of DataArrayInt::getDifferentValues because it returns not only different values in \a this but also, for each of - * them it tells which tuple id have this id. - * This method works only on arrays with one component (if it is not the case call DataArrayInt::rearrange(1) ). - * This method returns two arrays having same size. - * The instances of DataArrayInt in the returned vector have be specially allocated and computed by this method. Each of them should be dealt by the caller of this method. - * Example : if this is equal to [1,0,1,2,0,2,2,-3,2] -> differentIds=[-3,0,1,2] and returned array will be equal to [[7],[1,4],[0,2],[3,5,6,8]] - */ -std::vector DataArrayInt::partitionByDifferentValues(std::vector& differentIds) const -{ - checkAllocated(); - if(getNumberOfComponents()!=1) - throw INTERP_KERNEL::Exception("DataArrayInt::partitionByDifferentValues : this should have only one component !"); - int id=0; - std::map m,m2,m3; - for(const int *w=begin();w!=end();w++) - m[*w]++; - differentIds.resize(m.size()); - std::vector ret(m.size()); - std::vector retPtr(m.size()); - for(std::map::const_iterator it=m.begin();it!=m.end();it++,id++) - { - m2[(*it).first]=id; - ret[id]=DataArrayInt::New(); - ret[id]->alloc((*it).second,1); - retPtr[id]=ret[id]->getPointer(); - differentIds[id]=(*it).first; - } - id=0; - for(const int *w=begin();w!=end();w++,id++) - { - retPtr[m2[*w]][m3[*w]++]=id; - } - return ret; -} - -/*! - * This method split ids in [0, \c this->getNumberOfTuples() ) using \a this array as a field of weight (>=0 each). - * The aim of this method is to return a set of \a nbOfSlices chunk of contiguous ids as balanced as possible. - * - * \param [in] nbOfSlices - number of slices expected. - * \return - a vector having a size equal to \a nbOfSlices giving the start (included) and the stop (excluded) of each chunks. - * - * \sa DataArray::GetSlice - * \throw If \a this is not allocated or not with exactly one component. - * \throw If an element in \a this if < 0. - */ -std::vector< std::pair > DataArrayInt::splitInBalancedSlices(int nbOfSlices) const -{ - if(!isAllocated() || getNumberOfComponents()!=1) - throw INTERP_KERNEL::Exception("DataArrayInt::splitInBalancedSlices : this array should have number of components equal to one and must be allocated !"); - if(nbOfSlices<=0) - throw INTERP_KERNEL::Exception("DataArrayInt::splitInBalancedSlices : number of slices must be >= 1 !"); - int sum(accumulate(0)),nbOfTuples(getNumberOfTuples()); - int sumPerSlc(sum/nbOfSlices),pos(0); - const int *w(begin()); - std::vector< std::pair > ret(nbOfSlices); - for(int i=0;i p(pos,-1); - int locSum(0); - while(locSumgetNumberOfTuples() != \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) -{ - if(!a1 || !a2) - throw INTERP_KERNEL::Exception("DataArrayInt::Add : input DataArrayInt instance is NULL !"); - int nbOfTuple=a1->getNumberOfTuples(); - int nbOfTuple2=a2->getNumberOfTuples(); - int nbOfComp=a1->getNumberOfComponents(); - int nbOfComp2=a2->getNumberOfComponents(); - MEDCouplingAutoRefCountObjectPtr ret=0; - if(nbOfTuple==nbOfTuple2) - { - if(nbOfComp==nbOfComp2) - { - ret=DataArrayInt::New(); - ret->alloc(nbOfTuple,nbOfComp); - std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::plus()); - ret->copyStringInfoFrom(*a1); - } - else - { - int nbOfCompMin,nbOfCompMax; - const DataArrayInt *aMin, *aMax; - if(nbOfComp>nbOfComp2) - { - nbOfCompMin=nbOfComp2; nbOfCompMax=nbOfComp; - aMin=a2; aMax=a1; - } - else - { - nbOfCompMin=nbOfComp; nbOfCompMax=nbOfComp2; - aMin=a1; aMax=a2; - } - if(nbOfCompMin==1) - { - ret=DataArrayInt::New(); - ret->alloc(nbOfTuple,nbOfCompMax); - const int *aMinPtr=aMin->getConstPointer(); - const int *aMaxPtr=aMax->getConstPointer(); - int *res=ret->getPointer(); - for(int i=0;i(),aMinPtr[i])); - ret->copyStringInfoFrom(*aMax); - } - else - throw INTERP_KERNEL::Exception("Nb of components mismatch for array Add !"); - } - } - else if((nbOfTuple==1 && nbOfTuple2>1) || (nbOfTuple>1 && nbOfTuple2==1)) - { - if(nbOfComp==nbOfComp2) - { - int nbOfTupleMax=std::max(nbOfTuple,nbOfTuple2); - const DataArrayInt *aMin=nbOfTuple>nbOfTuple2?a2:a1; - const DataArrayInt *aMax=nbOfTuple>nbOfTuple2?a1:a2; - const int *aMinPtr=aMin->getConstPointer(),*aMaxPtr=aMax->getConstPointer(); - ret=DataArrayInt::New(); - ret->alloc(nbOfTupleMax,nbOfComp); - int *res=ret->getPointer(); - for(int i=0;i()); - ret->copyStringInfoFrom(*aMax); - } - else - throw INTERP_KERNEL::Exception("Nb of components mismatch for array Add !"); - } - else - throw INTERP_KERNEL::Exception("Nb of tuples mismatch for array Add !"); - 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) -{ - 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(); - int nbOfComp2=other->getNumberOfComponents(); - if(nbOfTuple==nbOfTuple2) - { - if(nbOfComp==nbOfComp2) - { - std::transform(begin(),end(),other->begin(),getPointer(),std::plus()); - } - else if(nbOfComp2==1) - { - int *ptr=getPointer(); - const int *ptrc=other->getConstPointer(); - for(int i=0;i(),*ptrc++)); - } - else - throw INTERP_KERNEL::Exception(msg); - } - else if(nbOfTuple2==1) - { - if(nbOfComp2==nbOfComp) - { - int *ptr=getPointer(); - const int *ptrc=other->getConstPointer(); - for(int i=0;i()); - } - else - throw INTERP_KERNEL::Exception(msg); - } - else - throw INTERP_KERNEL::Exception(msg); - 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) -{ - if(!a1 || !a2) - throw INTERP_KERNEL::Exception("DataArrayInt::Substract : input DataArrayInt instance is NULL !"); - int nbOfTuple1=a1->getNumberOfTuples(); - int nbOfTuple2=a2->getNumberOfTuples(); - int nbOfComp1=a1->getNumberOfComponents(); - int nbOfComp2=a2->getNumberOfComponents(); - if(nbOfTuple2==nbOfTuple1) - { - if(nbOfComp1==nbOfComp2) - { - MEDCouplingAutoRefCountObjectPtr ret=DataArrayInt::New(); - ret->alloc(nbOfTuple2,nbOfComp1); - std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::minus()); - ret->copyStringInfoFrom(*a1); - return ret.retn(); - } - else if(nbOfComp2==1) - { - MEDCouplingAutoRefCountObjectPtr ret=DataArrayInt::New(); - ret->alloc(nbOfTuple1,nbOfComp1); - const int *a2Ptr=a2->getConstPointer(); - const int *a1Ptr=a1->getConstPointer(); - int *res=ret->getPointer(); - for(int i=0;i(),a2Ptr[i])); - ret->copyStringInfoFrom(*a1); - return ret.retn(); - } - else - { - a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Substract !"); - return 0; - } - } - else if(nbOfTuple2==1) - { - a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Substract !"); - MEDCouplingAutoRefCountObjectPtr ret=DataArrayInt::New(); - ret->alloc(nbOfTuple1,nbOfComp1); - const int *a1ptr=a1->getConstPointer(),*a2ptr=a2->getConstPointer(); - int *pt=ret->getPointer(); - for(int i=0;i()); - ret->copyStringInfoFrom(*a1); - return ret.retn(); - } - else - { - a1->checkNbOfTuples(nbOfTuple2,"Nb of tuples mismatch for array Substract !");//will always throw an exception - return 0; - } -} - -/*! - * 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) -{ - 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(); - int nbOfComp2=other->getNumberOfComponents(); - if(nbOfTuple==nbOfTuple2) - { - if(nbOfComp==nbOfComp2) - { - std::transform(begin(),end(),other->begin(),getPointer(),std::minus()); - } - else if(nbOfComp2==1) - { - int *ptr=getPointer(); - const int *ptrc=other->getConstPointer(); - for(int i=0;i(),*ptrc++)); - } - else - throw INTERP_KERNEL::Exception(msg); - } - else if(nbOfTuple2==1) - { - int *ptr=getPointer(); - const int *ptrc=other->getConstPointer(); - for(int i=0;i()); - } - else - throw INTERP_KERNEL::Exception(msg); - 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) -{ - if(!a1 || !a2) - throw INTERP_KERNEL::Exception("DataArrayInt::Multiply : input DataArrayInt instance is NULL !"); - int nbOfTuple=a1->getNumberOfTuples(); - int nbOfTuple2=a2->getNumberOfTuples(); - int nbOfComp=a1->getNumberOfComponents(); - int nbOfComp2=a2->getNumberOfComponents(); - MEDCouplingAutoRefCountObjectPtr ret=0; - if(nbOfTuple==nbOfTuple2) - { - if(nbOfComp==nbOfComp2) - { - ret=DataArrayInt::New(); - ret->alloc(nbOfTuple,nbOfComp); - std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::multiplies()); - ret->copyStringInfoFrom(*a1); - } - else - { - int nbOfCompMin,nbOfCompMax; - const DataArrayInt *aMin, *aMax; - if(nbOfComp>nbOfComp2) - { - nbOfCompMin=nbOfComp2; nbOfCompMax=nbOfComp; - aMin=a2; aMax=a1; - } - else - { - nbOfCompMin=nbOfComp; nbOfCompMax=nbOfComp2; - aMin=a1; aMax=a2; - } - if(nbOfCompMin==1) - { - ret=DataArrayInt::New(); - ret->alloc(nbOfTuple,nbOfCompMax); - const int *aMinPtr=aMin->getConstPointer(); - const int *aMaxPtr=aMax->getConstPointer(); - int *res=ret->getPointer(); - for(int i=0;i(),aMinPtr[i])); - ret->copyStringInfoFrom(*aMax); - } - else - throw INTERP_KERNEL::Exception("Nb of components mismatch for array Multiply !"); - } - } - else if((nbOfTuple==1 && nbOfTuple2>1) || (nbOfTuple>1 && nbOfTuple2==1)) - { - if(nbOfComp==nbOfComp2) - { - int nbOfTupleMax=std::max(nbOfTuple,nbOfTuple2); - const DataArrayInt *aMin=nbOfTuple>nbOfTuple2?a2:a1; - const DataArrayInt *aMax=nbOfTuple>nbOfTuple2?a1:a2; - const int *aMinPtr=aMin->getConstPointer(),*aMaxPtr=aMax->getConstPointer(); - ret=DataArrayInt::New(); - ret->alloc(nbOfTupleMax,nbOfComp); - int *res=ret->getPointer(); - for(int i=0;i()); - ret->copyStringInfoFrom(*aMax); - } - else - throw INTERP_KERNEL::Exception("Nb of components mismatch for array Multiply !"); - } - else - throw INTERP_KERNEL::Exception("Nb of tuples mismatch for array Multiply !"); - 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) -{ - 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(); - int nbOfComp2=other->getNumberOfComponents(); - if(nbOfTuple==nbOfTuple2) - { - if(nbOfComp==nbOfComp2) - { - std::transform(begin(),end(),other->begin(),getPointer(),std::multiplies()); - } - else if(nbOfComp2==1) - { - int *ptr=getPointer(); - const int *ptrc=other->getConstPointer(); - for(int i=0;i(),*ptrc++)); - } - else - throw INTERP_KERNEL::Exception(msg); - } - else if(nbOfTuple2==1) - { - if(nbOfComp2==nbOfComp) - { - int *ptr=getPointer(); - const int *ptrc=other->getConstPointer(); - for(int i=0;i()); - } - else - throw INTERP_KERNEL::Exception(msg); - } - else - throw INTERP_KERNEL::Exception(msg); - 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) -{ - if(!a1 || !a2) - throw INTERP_KERNEL::Exception("DataArrayInt::Divide : input DataArrayInt instance is NULL !"); - int nbOfTuple1=a1->getNumberOfTuples(); - int nbOfTuple2=a2->getNumberOfTuples(); - int nbOfComp1=a1->getNumberOfComponents(); - int nbOfComp2=a2->getNumberOfComponents(); - if(nbOfTuple2==nbOfTuple1) - { - if(nbOfComp1==nbOfComp2) - { - MEDCouplingAutoRefCountObjectPtr ret=DataArrayInt::New(); - ret->alloc(nbOfTuple2,nbOfComp1); - std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::divides()); - ret->copyStringInfoFrom(*a1); - return ret.retn(); - } - else if(nbOfComp2==1) - { - MEDCouplingAutoRefCountObjectPtr ret=DataArrayInt::New(); - ret->alloc(nbOfTuple1,nbOfComp1); - const int *a2Ptr=a2->getConstPointer(); - const int *a1Ptr=a1->getConstPointer(); - int *res=ret->getPointer(); - for(int i=0;i(),a2Ptr[i])); - ret->copyStringInfoFrom(*a1); - return ret.retn(); - } - else - { - a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Divide !"); - return 0; - } - } - else if(nbOfTuple2==1) - { - a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Divide !"); - MEDCouplingAutoRefCountObjectPtr ret=DataArrayInt::New(); - ret->alloc(nbOfTuple1,nbOfComp1); - const int *a1ptr=a1->getConstPointer(),*a2ptr=a2->getConstPointer(); - int *pt=ret->getPointer(); - for(int i=0;i()); - ret->copyStringInfoFrom(*a1); - return ret.retn(); - } - else - { - a1->checkNbOfTuples(nbOfTuple2,"Nb of tuples mismatch for array Divide !");//will always throw an exception - return 0; - } -} - -/*! - * 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) -{ - 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(); - int nbOfComp2=other->getNumberOfComponents(); - if(nbOfTuple==nbOfTuple2) - { - if(nbOfComp==nbOfComp2) - { - std::transform(begin(),end(),other->begin(),getPointer(),std::divides()); - } - else if(nbOfComp2==1) - { - int *ptr=getPointer(); - const int *ptrc=other->getConstPointer(); - for(int i=0;i(),*ptrc++)); - } - else - throw INTERP_KERNEL::Exception(msg); - } - else if(nbOfTuple2==1) - { - if(nbOfComp2==nbOfComp) - { - int *ptr=getPointer(); - const int *ptrc=other->getConstPointer(); - for(int i=0;i()); - } - else - throw INTERP_KERNEL::Exception(msg); - } - else - throw INTERP_KERNEL::Exception(msg); - 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) -{ - if(!a1 || !a2) - throw INTERP_KERNEL::Exception("DataArrayInt::Modulus : input DataArrayInt instance is NULL !"); - int nbOfTuple1=a1->getNumberOfTuples(); - int nbOfTuple2=a2->getNumberOfTuples(); - int nbOfComp1=a1->getNumberOfComponents(); - int nbOfComp2=a2->getNumberOfComponents(); - if(nbOfTuple2==nbOfTuple1) - { - if(nbOfComp1==nbOfComp2) - { - MEDCouplingAutoRefCountObjectPtr ret=DataArrayInt::New(); - ret->alloc(nbOfTuple2,nbOfComp1); - std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::modulus()); - ret->copyStringInfoFrom(*a1); - return ret.retn(); - } - else if(nbOfComp2==1) - { - MEDCouplingAutoRefCountObjectPtr ret=DataArrayInt::New(); - ret->alloc(nbOfTuple1,nbOfComp1); - const int *a2Ptr=a2->getConstPointer(); - const int *a1Ptr=a1->getConstPointer(); - int *res=ret->getPointer(); - for(int i=0;i(),a2Ptr[i])); - ret->copyStringInfoFrom(*a1); - return ret.retn(); - } - else - { - a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Modulus !"); - return 0; - } - } - else if(nbOfTuple2==1) - { - a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Modulus !"); - MEDCouplingAutoRefCountObjectPtr ret=DataArrayInt::New(); - ret->alloc(nbOfTuple1,nbOfComp1); - const int *a1ptr=a1->getConstPointer(),*a2ptr=a2->getConstPointer(); - int *pt=ret->getPointer(); - for(int i=0;i()); - ret->copyStringInfoFrom(*a1); - return ret.retn(); - } - else - { - a1->checkNbOfTuples(nbOfTuple2,"Nb of tuples mismatch for array Modulus !");//will always throw an exception - return 0; - } -} - -/*! - * 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) -{ - 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(); - int nbOfComp2=other->getNumberOfComponents(); - if(nbOfTuple==nbOfTuple2) - { - if(nbOfComp==nbOfComp2) - { - std::transform(begin(),end(),other->begin(),getPointer(),std::modulus()); - } - else if(nbOfComp2==1) - { - if(nbOfComp2==nbOfComp) - { - int *ptr=getPointer(); - const int *ptrc=other->getConstPointer(); - for(int i=0;i(),*ptrc++)); - } - else - throw INTERP_KERNEL::Exception(msg); - } - else - throw INTERP_KERNEL::Exception(msg); - } - else if(nbOfTuple2==1) - { - int *ptr=getPointer(); - const int *ptrc=other->getConstPointer(); - for(int i=0;i()); - } - else - throw INTERP_KERNEL::Exception(msg); - 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) -{ - 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) -{ - 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=(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; - 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=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) -{ - int nbOfTuples=GetNumberOfItemGivenBESRelative(begin,end,step,"DataArrayInt::Range"); - MEDCouplingAutoRefCountObjectPtr ret=DataArrayInt::New(); - ret->alloc(nbOfTuples,1); - int *ptr=ret->getPointer(); - if(step>0) - { - for(int i=begin;iend;i+=step,ptr++) - *ptr=i; - } - return ret.retn(); -} - -/*! - * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class. - * Server side. - */ -void DataArrayInt::getTinySerializationIntInformation(std::vector& tinyInfo) const -{ - tinyInfo.resize(2); - if(isAllocated()) - { - tinyInfo[0]=getNumberOfTuples(); - tinyInfo[1]=getNumberOfComponents(); - } - else - { - tinyInfo[0]=-1; - tinyInfo[1]=-1; - } -} - -/*! - * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class. - * Server side. - */ -void DataArrayInt::getTinySerializationStrInformation(std::vector& tinyInfo) const -{ - if(isAllocated()) - { - int nbOfCompo=getNumberOfComponents(); - tinyInfo.resize(nbOfCompo+1); - tinyInfo[0]=getName(); - for(int i=0;i& tinyInfoI) -{ - int nbOfTuple=tinyInfoI[0]; - int nbOfComp=tinyInfoI[1]; - if(nbOfTuple!=-1 || nbOfComp!=-1) - { - alloc(nbOfTuple,nbOfComp); - return true; - } - return false; -} - -/*! - * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class. - * This method returns if a feeding is needed. - */ -void DataArrayInt::finishUnserialization(const std::vector& tinyInfoI, const std::vector& tinyInfoS) -{ - setName(tinyInfoS[0]); - if(isAllocated()) - { - int nbOfCompo=tinyInfoI[1]; - for(int i=0;iincrRef(); - if(_da->isAllocated()) - { - _nb_comp=da->getNumberOfComponents(); - _nb_tuple=da->getNumberOfTuples(); - _pt=da->getPointer(); - } - } -} - -DataArrayIntIterator::~DataArrayIntIterator() -{ - if(_da) - _da->decrRef(); -} - -DataArrayIntTuple *DataArrayIntIterator::nextt() -{ - if(_tuple_id<_nb_tuple) - { - _tuple_id++; - DataArrayIntTuple *ret=new DataArrayIntTuple(_pt,_nb_comp); - _pt+=_nb_comp; - return ret; - } - else - return 0; -} - -DataArrayIntTuple::DataArrayIntTuple(int *pt, int nbOfComp):_pt(pt),_nb_of_compo(nbOfComp) -{ -} - -std::string DataArrayIntTuple::repr() const -{ - std::ostringstream oss; oss << "("; - for(int i=0;i<_nb_of_compo-1;i++) - oss << _pt[i] << ", "; - oss << _pt[_nb_of_compo-1] << ")"; - return oss.str(); -} - -int DataArrayIntTuple::intValue() const -{ - if(_nb_of_compo==1) - return *_pt; - throw INTERP_KERNEL::Exception("DataArrayIntTuple::intValue : DataArrayIntTuple instance has not exactly 1 component -> Not possible to convert it into an integer !"); -} - -/*! - * This method returns a newly allocated instance the caller should dealed with by a ParaMEDMEM::DataArrayInt::decrRef. - * This method performs \b no copy of data. The content is only referenced using ParaMEDMEM::DataArrayInt::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. - */ -DataArrayInt *DataArrayIntTuple::buildDAInt(int nbOfTuples, int nbOfCompo) const -{ - if((_nb_of_compo==nbOfCompo && nbOfTuples==1) || (_nb_of_compo==nbOfTuples && nbOfCompo==1)) - { - DataArrayInt *ret=DataArrayInt::New(); - ret->useExternalArrayWithRWAccess(_pt,nbOfTuples,nbOfCompo); - return ret; - } - else - { - std::ostringstream oss; oss << "DataArrayIntTuple::buildDAInt : unable to build a requested DataArrayInt 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/MEDCouplingMemArray.hxx b/src/MEDCoupling/MEDCouplingMemArray.hxx deleted file mode 100644 index 1fc39204c..000000000 --- a/src/MEDCoupling/MEDCouplingMemArray.hxx +++ /dev/null @@ -1,946 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 -// 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_MEDCOUPLINGMEMARRAY_HXX__ -#define __PARAMEDMEM_MEDCOUPLINGMEMARRAY_HXX__ - -#include "MEDCoupling.hxx" -#include "MEDCouplingTimeLabel.hxx" -#include "MEDCouplingRefCountObject.hxx" -#include "InterpKernelException.hxx" -#include "BBTreePts.txx" - -#include -#include -#include - -namespace ParaMEDMEM -{ - template - class MEDCouplingPointer - { - public: - MEDCouplingPointer():_internal(0),_external(0) { } - void null() { _internal=0; _external=0; } - bool isNull() const { return _internal==0 && _external==0; } - void setInternal(T *pointer); - void setExternal(const T *pointer); - const T *getConstPointer() const { if(_internal) return _internal; else return _external; } - 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; - const T *_external; - }; - - template - class MemArray - { - public: - 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(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[](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 reprNotTooLong(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(int nbOfComp); - void alloc(std::size_t nbOfElements); - void reserve(std::size_t newNbOfElements); - void reAlloc(std::size_t newNbOfElements); - 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); - T popBack(); - 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: - static void DestroyPointer(T *pt, Deallocator dealloc, void *param); - static Deallocator BuildFromType(DeallocType type); - private: - std::size_t _nb_of_elem; - std::size_t _nb_of_elem_alloc; - bool _ownership; - MEDCouplingPointer _pointer; - Deallocator _dealloc; - void *_param_for_deallocator; - }; - - class DataArrayInt; - class DataArrayByte; - - class DataArray : public RefCountObject, public TimeLabel - { - public: - MEDCOUPLING_EXPORT std::size_t getHeapMemorySizeWithoutChildren() const; - MEDCOUPLING_EXPORT std::vector getDirectChildrenWithNull() const; - MEDCOUPLING_EXPORT void setName(const std::string& name); - MEDCOUPLING_EXPORT void copyStringInfoFrom(const DataArray& other); - MEDCOUPLING_EXPORT void copyPartOfStringInfoFrom(const DataArray& other, const std::vector& compoIds); - MEDCOUPLING_EXPORT void copyPartOfStringInfoFrom2(const std::vector& compoIds, const DataArray& other); - MEDCOUPLING_EXPORT bool areInfoEqualsIfNotWhy(const DataArray& other, std::string& reason) const; - MEDCOUPLING_EXPORT bool areInfoEquals(const DataArray& other) const; - MEDCOUPLING_EXPORT std::string cppRepr(const std::string& varName) const; - 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); - MEDCOUPLING_EXPORT void setInfoAndChangeNbOfCompo(const std::vector& info); - MEDCOUPLING_EXPORT std::vector getVarsOnComponent() const; - MEDCOUPLING_EXPORT std::vector getUnitsOnComponent() const; - MEDCOUPLING_EXPORT std::string getInfoOnComponent(int i) const; - MEDCOUPLING_EXPORT std::string getVarOnComponent(int i) const; - MEDCOUPLING_EXPORT std::string getUnitOnComponent(int i) const; - MEDCOUPLING_EXPORT void setInfoOnComponent(int i, const std::string& info); - MEDCOUPLING_EXPORT int getNumberOfComponents() const { return (int)_info_on_compo.size(); } - MEDCOUPLING_EXPORT void setPartOfValuesBase3(const DataArray *aBase, const int *bgTuples, const int *endTuples, int bgComp, int endComp, int stepComp, bool strictCompoCompare=true); - MEDCOUPLING_EXPORT virtual DataArray *deepCpy() const = 0; - MEDCOUPLING_EXPORT virtual bool isAllocated() const = 0; - MEDCOUPLING_EXPORT virtual void checkAllocated() const = 0; - MEDCOUPLING_EXPORT virtual void desallocate() = 0; - MEDCOUPLING_EXPORT virtual int getNumberOfTuples() const = 0; - MEDCOUPLING_EXPORT virtual std::size_t getNbOfElems() const = 0; - MEDCOUPLING_EXPORT virtual std::size_t getNbOfElemAllocated() const = 0; - MEDCOUPLING_EXPORT virtual void alloc(int nbOfTuple, int nbOfCompo=1) = 0; - MEDCOUPLING_EXPORT virtual void reAlloc(int newNbOfTuple) = 0; - MEDCOUPLING_EXPORT virtual void renumberInPlace(const int *old2New) = 0; - MEDCOUPLING_EXPORT virtual void renumberInPlaceR(const int *new2Old) = 0; - MEDCOUPLING_EXPORT virtual void setContigPartOfSelectedValues(int tupleIdStart, const DataArray *aBase, const DataArrayInt *tuplesSelec) = 0; - MEDCOUPLING_EXPORT virtual void setContigPartOfSelectedValues2(int tupleIdStart, const DataArray *aBase, int bg, int end2, int step) = 0; - MEDCOUPLING_EXPORT virtual DataArray *selectByTupleRanges(const std::vector >& ranges) const = 0; - MEDCOUPLING_EXPORT virtual DataArray *keepSelectedComponents(const std::vector& compoIds) const = 0; - MEDCOUPLING_EXPORT virtual DataArray *selectByTupleId(const int *new2OldBg, const int *new2OldEnd) const = 0; - MEDCOUPLING_EXPORT virtual DataArray *selectByTupleIdSafe(const int *new2OldBg, const int *new2OldEnd) const = 0; - MEDCOUPLING_EXPORT virtual DataArray *selectByTupleId2(int bg, int end2, int step) const = 0; - MEDCOUPLING_EXPORT virtual void rearrange(int newNbOfCompo) = 0; - MEDCOUPLING_EXPORT void checkNbOfTuples(int nbOfTuples, const std::string& msg) const; - MEDCOUPLING_EXPORT void checkNbOfComps(int nbOfCompo, const std::string& msg) const; - MEDCOUPLING_EXPORT void checkNbOfTuplesAndComp(const DataArray& other, const std::string& msg) const; - MEDCOUPLING_EXPORT void checkNbOfTuplesAndComp(int nbOfTuples, int nbOfCompo, const std::string& msg) const; - MEDCOUPLING_EXPORT void checkNbOfElems(std::size_t nbOfElems, const std::string& msg) const; - MEDCOUPLING_EXPORT static void GetSlice(int start, int stop, int step, int sliceId, int nbOfSlices, int& startSlice, int& stopSlice); - MEDCOUPLING_EXPORT static int GetNumberOfItemGivenBES(int begin, int end, int step, const std::string& msg); - MEDCOUPLING_EXPORT static int GetNumberOfItemGivenBESRelative(int begin, int end, int step, const std::string& msg); - MEDCOUPLING_EXPORT static int GetPosOfItemGivenBESRelativeNoThrow(int value, int begin, int end, int step); - MEDCOUPLING_EXPORT static std::string GetVarNameFromInfo(const std::string& info); - MEDCOUPLING_EXPORT static std::string GetUnitFromInfo(const std::string& info); - MEDCOUPLING_EXPORT static std::string BuildInfoFromVarAndUnit(const std::string& var, const std::string& unit); - MEDCOUPLING_EXPORT static DataArray *Aggregate(const std::vector& arrs); - MEDCOUPLING_EXPORT virtual void reprStream(std::ostream& stream) const = 0; - MEDCOUPLING_EXPORT virtual void reprZipStream(std::ostream& stream) const = 0; - MEDCOUPLING_EXPORT virtual void reprWithoutNameStream(std::ostream& stream) const; - MEDCOUPLING_EXPORT virtual void reprZipWithoutNameStream(std::ostream& stream) const = 0; - MEDCOUPLING_EXPORT virtual void reprCppStream(const std::string& varName, std::ostream& stream) const = 0; - MEDCOUPLING_EXPORT virtual void reprQuickOverview(std::ostream& stream) const = 0; - MEDCOUPLING_EXPORT virtual void reprQuickOverviewData(std::ostream& stream, std::size_t maxNbOfByteInRepr) const = 0; - protected: - DataArray() { } - ~DataArray() { } - protected: - static void CheckValueInRange(int ref, int value, const std::string& msg); - static void CheckValueInRangeEx(int value, int start, int end, const std::string& msg); - static void CheckClosingParInRange(int ref, int value, const std::string& msg); - protected: - std::string _name; - std::vector _info_on_compo; - }; -} - -#include "MEDCouplingMemArray.txx" - -namespace ParaMEDMEM -{ - class DataArrayInt; - class DataArrayDoubleIterator; - class DataArrayDouble : public DataArray - { - public: - MEDCOUPLING_EXPORT static DataArrayDouble *New(); - MEDCOUPLING_EXPORT bool isAllocated() const; - MEDCOUPLING_EXPORT void checkAllocated() const; - MEDCOUPLING_EXPORT void desallocate(); - MEDCOUPLING_EXPORT int getNumberOfTuples() const { return _info_on_compo.empty()?0:_mem.getNbOfElem()/getNumberOfComponents(); } - MEDCOUPLING_EXPORT std::size_t getNbOfElems() const { return _mem.getNbOfElem(); } - MEDCOUPLING_EXPORT std::size_t getHeapMemorySizeWithoutChildren() const; - MEDCOUPLING_EXPORT double doubleValue() const; - MEDCOUPLING_EXPORT bool empty() const; - MEDCOUPLING_EXPORT DataArrayDouble *deepCpy() const; - MEDCOUPLING_EXPORT DataArrayDouble *performCpy(bool deepCpy) const; - MEDCOUPLING_EXPORT void cpyFrom(const DataArrayDouble& other); - MEDCOUPLING_EXPORT void reserve(std::size_t nbOfElems); - MEDCOUPLING_EXPORT void pushBackSilent(double val); - MEDCOUPLING_EXPORT void pushBackValsSilent(const double *valsBg, const double *valsEnd); - MEDCOUPLING_EXPORT double popBackSilent(); - MEDCOUPLING_EXPORT void pack() const; - MEDCOUPLING_EXPORT std::size_t getNbOfElemAllocated() const { return _mem.getNbOfElemAllocated(); } - MEDCOUPLING_EXPORT void alloc(int nbOfTuple, int nbOfCompo=1); - MEDCOUPLING_EXPORT void allocIfNecessary(int nbOfTuple, int nbOfCompo); - MEDCOUPLING_EXPORT void fillWithZero(); - MEDCOUPLING_EXPORT void fillWithValue(double val); - MEDCOUPLING_EXPORT void iota(double init=0.); - MEDCOUPLING_EXPORT bool isUniform(double val, double eps) const; - MEDCOUPLING_EXPORT void sort(bool asc=true); - MEDCOUPLING_EXPORT void reverse(); - MEDCOUPLING_EXPORT void checkMonotonic(bool increasing, double eps) const; - MEDCOUPLING_EXPORT bool isMonotonic(bool increasing, double eps) const; - MEDCOUPLING_EXPORT std::string repr() const; - MEDCOUPLING_EXPORT std::string reprZip() const; - MEDCOUPLING_EXPORT std::string reprNotTooLong() const; - MEDCOUPLING_EXPORT void writeVTK(std::ostream& ofs, int indent, const std::string& nameInFile, DataArrayByte *byteArr) const; - MEDCOUPLING_EXPORT void reprStream(std::ostream& stream) const; - MEDCOUPLING_EXPORT void reprZipStream(std::ostream& stream) const; - MEDCOUPLING_EXPORT void reprNotTooLongStream(std::ostream& stream) const; - MEDCOUPLING_EXPORT void reprWithoutNameStream(std::ostream& stream) const; - MEDCOUPLING_EXPORT void reprZipWithoutNameStream(std::ostream& stream) const; - MEDCOUPLING_EXPORT void reprNotTooLongWithoutNameStream(std::ostream& stream) const; - MEDCOUPLING_EXPORT void reprCppStream(const std::string& varName, std::ostream& stream) const; - MEDCOUPLING_EXPORT void reprQuickOverview(std::ostream& stream) const; - MEDCOUPLING_EXPORT void reprQuickOverviewData(std::ostream& stream, std::size_t maxNbOfByteInRepr) 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; - MEDCOUPLING_EXPORT void reAlloc(int nbOfTuples); - MEDCOUPLING_EXPORT DataArrayInt *convertToIntArr() const; - MEDCOUPLING_EXPORT DataArrayDouble *fromNoInterlace() const; - MEDCOUPLING_EXPORT DataArrayDouble *toNoInterlace() const; - 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 DataArrayDouble *selectByTupleId(const int *new2OldBg, const int *new2OldEnd) const; - MEDCOUPLING_EXPORT DataArrayDouble *selectByTupleIdSafe(const int *new2OldBg, const int *new2OldEnd) const; - MEDCOUPLING_EXPORT DataArrayDouble *selectByTupleId2(int bg, int end2, int step) const; - MEDCOUPLING_EXPORT DataArray *selectByTupleRanges(const std::vector >& ranges) const; - MEDCOUPLING_EXPORT DataArrayDouble *substr(int tupleIdBg, int tupleIdEnd=-1) const; - MEDCOUPLING_EXPORT void rearrange(int newNbOfCompo); - MEDCOUPLING_EXPORT void transpose(); - MEDCOUPLING_EXPORT DataArrayDouble *changeNbOfComponents(int newNbOfComp, double dftValue) const; - MEDCOUPLING_EXPORT DataArrayDouble *keepSelectedComponents(const std::vector& compoIds) const; - MEDCOUPLING_EXPORT void meldWith(const DataArrayDouble *other); - MEDCOUPLING_EXPORT bool areIncludedInMe(const DataArrayDouble *other, double prec, DataArrayInt *&tupleIds) const; - MEDCOUPLING_EXPORT void findCommonTuples(double prec, int limitTupleId, DataArrayInt *&comm, DataArrayInt *&commIndex) const; - MEDCOUPLING_EXPORT double minimalDistanceTo(const DataArrayDouble *other, int& thisTupleId, int& otherTupleId) const; - MEDCOUPLING_EXPORT DataArrayDouble *duplicateEachTupleNTimes(int nbTimes) const; - MEDCOUPLING_EXPORT DataArrayDouble *getDifferentValues(double prec, int limitTupleId=-1) const; - MEDCOUPLING_EXPORT DataArrayInt *findClosestTupleId(const DataArrayDouble *other) const; - MEDCOUPLING_EXPORT DataArrayInt *computeNbOfInteractionsWith(const DataArrayDouble *otherBBoxFrmt, double eps) const; - MEDCOUPLING_EXPORT void setSelectedComponents(const DataArrayDouble *a, const std::vector& compoIds); - MEDCOUPLING_EXPORT void setPartOfValues1(const DataArrayDouble *a, int bgTuples, int endTuples, int stepTuples, int bgComp, int endComp, int stepComp, bool strictCompoCompare=true); - MEDCOUPLING_EXPORT void setPartOfValuesSimple1(double a, int bgTuples, int endTuples, int stepTuples, int bgComp, int endComp, int stepComp); - MEDCOUPLING_EXPORT void setPartOfValues2(const DataArrayDouble *a, const int *bgTuples, const int *endTuples, const int *bgComp, const int *endComp, bool strictCompoCompare=true); - MEDCOUPLING_EXPORT void setPartOfValuesSimple2(double a, const int *bgTuples, const int *endTuples, const int *bgComp, const int *endComp); - MEDCOUPLING_EXPORT void setPartOfValues3(const DataArrayDouble *a, const int *bgTuples, const int *endTuples, int bgComp, int endComp, int stepComp, bool strictCompoCompare=true); - MEDCOUPLING_EXPORT void setPartOfValuesSimple3(double a, const int *bgTuples, const int *endTuples, int bgComp, int endComp, int stepComp); - MEDCOUPLING_EXPORT void setPartOfValues4(const DataArrayDouble *a, int bgTuples, int endTuples, int stepTuples, const int *bgComp, const int *endComp, bool strictCompoCompare=true); - MEDCOUPLING_EXPORT void setPartOfValuesSimple4(double a, int bgTuples, int endTuples, int stepTuples, const int *bgComp, const int *endComp); - MEDCOUPLING_EXPORT void setPartOfValuesAdv(const DataArrayDouble *a, const DataArrayInt *tuplesSelec); - MEDCOUPLING_EXPORT void setContigPartOfSelectedValues(int tupleIdStart, const DataArray *aBase, const DataArrayInt *tuplesSelec); - MEDCOUPLING_EXPORT void setContigPartOfSelectedValues2(int tupleIdStart, const DataArray *aBase, int bg, int end2, int step); - MEDCOUPLING_EXPORT void getTuple(int tupleId, double *res) const { 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 front() const; - MEDCOUPLING_EXPORT double back() const; - MEDCOUPLING_EXPORT double getIJSafe(int tupleId, int compoId) const; - MEDCOUPLING_EXPORT void setIJ(int tupleId, int compoId, double newVal) { _mem[tupleId*_info_on_compo.size()+compoId]=newVal; declareAsNew(); } - MEDCOUPLING_EXPORT void setIJSilent(int tupleId, int compoId, double newVal) { _mem[tupleId*_info_on_compo.size()+compoId]=newVal; } - MEDCOUPLING_EXPORT double *getPointer() { return _mem.getPointer(); declareAsNew(); } - 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); - template - void insertAtTheEnd(InputIterator first, InputIterator last); - 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; - MEDCOUPLING_EXPORT void getMinMaxPerComponent(double *bounds) const; - MEDCOUPLING_EXPORT DataArrayDouble *computeBBoxPerTuple(double epsilon=0.0) const; - MEDCOUPLING_EXPORT void computeTupleIdsNearTuples(const DataArrayDouble *other, double eps, DataArrayInt *& c, DataArrayInt *& cI) const; - MEDCOUPLING_EXPORT void recenterForMaxPrecision(double eps); - MEDCOUPLING_EXPORT double getMaxValue(int& tupleId) const; - MEDCOUPLING_EXPORT double getMaxValueInArray() const; - MEDCOUPLING_EXPORT double getMinValue(int& tupleId) const; - MEDCOUPLING_EXPORT double getMinValueInArray() const; - MEDCOUPLING_EXPORT double getMaxValue2(DataArrayInt*& tupleIds) const; - MEDCOUPLING_EXPORT double getMinValue2(DataArrayInt*& tupleIds) const; - MEDCOUPLING_EXPORT int count(double value, double eps) const; - MEDCOUPLING_EXPORT double getAverageValue() const; - MEDCOUPLING_EXPORT double norm2() const; - MEDCOUPLING_EXPORT double normMax() const; - MEDCOUPLING_EXPORT double normMin() const; - MEDCOUPLING_EXPORT void accumulate(double *res) const; - MEDCOUPLING_EXPORT double accumulate(int compId) const; - MEDCOUPLING_EXPORT DataArrayDouble *accumulatePerChunck(const int *bgOfIndex, const int *endOfIndex) const; - MEDCOUPLING_EXPORT double distanceToTuple(const double *tupleBg, const double *tupleEnd, int& tupleId) const; - MEDCOUPLING_EXPORT DataArrayDouble *fromPolarToCart() const; - MEDCOUPLING_EXPORT DataArrayDouble *fromCylToCart() const; - MEDCOUPLING_EXPORT DataArrayDouble *fromSpherToCart() const; - MEDCOUPLING_EXPORT DataArrayDouble *doublyContractedProduct() const; - MEDCOUPLING_EXPORT DataArrayDouble *determinant() const; - MEDCOUPLING_EXPORT DataArrayDouble *eigenValues() const; - MEDCOUPLING_EXPORT DataArrayDouble *eigenVectors() const; - MEDCOUPLING_EXPORT DataArrayDouble *inverse() const; - MEDCOUPLING_EXPORT DataArrayDouble *trace() const; - MEDCOUPLING_EXPORT DataArrayDouble *deviator() const; - MEDCOUPLING_EXPORT DataArrayDouble *magnitude() const; - MEDCOUPLING_EXPORT DataArrayDouble *sumPerTuple() const; - MEDCOUPLING_EXPORT DataArrayDouble *maxPerTuple() const; - MEDCOUPLING_EXPORT DataArrayDouble *maxPerTupleWithCompoId(DataArrayInt* &compoIdOfMaxPerTuple) const; - MEDCOUPLING_EXPORT DataArrayDouble *buildEuclidianDistanceDenseMatrix() const; - MEDCOUPLING_EXPORT DataArrayDouble *buildEuclidianDistanceDenseMatrixWith(const DataArrayDouble *other) const; - MEDCOUPLING_EXPORT void sortPerTuple(bool asc); - MEDCOUPLING_EXPORT void abs(); - MEDCOUPLING_EXPORT DataArrayDouble *computeAbs() const; - MEDCOUPLING_EXPORT void applyLin(double a, double b, int compoId); - MEDCOUPLING_EXPORT void applyLin(double a, double b); - MEDCOUPLING_EXPORT void applyInv(double numerator); - MEDCOUPLING_EXPORT void applyPow(double val); - MEDCOUPLING_EXPORT void applyRPow(double val); - MEDCOUPLING_EXPORT DataArrayDouble *negate() const; - MEDCOUPLING_EXPORT DataArrayDouble *applyFunc(int nbOfComp, FunctionToEvaluate func) const; - MEDCOUPLING_EXPORT DataArrayDouble *applyFunc(int nbOfComp, const std::string& func, bool isSafe=true) const; - MEDCOUPLING_EXPORT DataArrayDouble *applyFunc(const std::string& func, bool isSafe=true) const; - MEDCOUPLING_EXPORT void applyFuncOnThis(const std::string& func, bool isSafe=true); - MEDCOUPLING_EXPORT DataArrayDouble *applyFunc2(int nbOfComp, const std::string& func, bool isSafe=true) const; - MEDCOUPLING_EXPORT DataArrayDouble *applyFunc3(int nbOfComp, const std::vector& varsOrder, const std::string& func, bool isSafe=true) const; - MEDCOUPLING_EXPORT void applyFuncFast32(const std::string& func); - MEDCOUPLING_EXPORT void applyFuncFast64(const std::string& func); - MEDCOUPLING_EXPORT DataArrayInt *getIdsInRange(double vmin, double vmax) const; - MEDCOUPLING_EXPORT DataArrayInt *getIdsNotInRange(double vmin, double vmax) const; - MEDCOUPLING_EXPORT static DataArrayDouble *Aggregate(const DataArrayDouble *a1, const DataArrayDouble *a2); - MEDCOUPLING_EXPORT static DataArrayDouble *Aggregate(const std::vector& arr); - MEDCOUPLING_EXPORT static DataArrayDouble *Meld(const DataArrayDouble *a1, const DataArrayDouble *a2); - MEDCOUPLING_EXPORT static DataArrayDouble *Meld(const std::vector& arr); - MEDCOUPLING_EXPORT static DataArrayDouble *Dot(const DataArrayDouble *a1, const DataArrayDouble *a2); - MEDCOUPLING_EXPORT static DataArrayDouble *CrossProduct(const DataArrayDouble *a1, const DataArrayDouble *a2); - MEDCOUPLING_EXPORT static DataArrayDouble *Max(const DataArrayDouble *a1, const DataArrayDouble *a2); - MEDCOUPLING_EXPORT static DataArrayDouble *Min(const DataArrayDouble *a1, const DataArrayDouble *a2); - MEDCOUPLING_EXPORT static DataArrayDouble *Add(const DataArrayDouble *a1, const DataArrayDouble *a2); - MEDCOUPLING_EXPORT void addEqual(const DataArrayDouble *other); - MEDCOUPLING_EXPORT static DataArrayDouble *Substract(const DataArrayDouble *a1, const DataArrayDouble *a2); - MEDCOUPLING_EXPORT void substractEqual(const DataArrayDouble *other); - MEDCOUPLING_EXPORT static DataArrayDouble *Multiply(const DataArrayDouble *a1, const DataArrayDouble *a2); - MEDCOUPLING_EXPORT void multiplyEqual(const DataArrayDouble *other); - MEDCOUPLING_EXPORT static DataArrayDouble *Divide(const DataArrayDouble *a1, const DataArrayDouble *a2); - MEDCOUPLING_EXPORT void divideEqual(const DataArrayDouble *other); - MEDCOUPLING_EXPORT static DataArrayDouble *Pow(const DataArrayDouble *a1, const DataArrayDouble *a2); - MEDCOUPLING_EXPORT void powEqual(const DataArrayDouble *other); - MEDCOUPLING_EXPORT void updateTime() const { } - MEDCOUPLING_EXPORT MemArray& accessToMemArray() { return _mem; } - MEDCOUPLING_EXPORT const MemArray& accessToMemArray() const { return _mem; } - MEDCOUPLING_EXPORT std::vector toVectorOfBool(double eps) const; - 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); - public: - template - 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 BBTreePts& myTree, const double *pos, int nbOfTuples, double eps, - DataArrayInt *c, DataArrayInt *cI); - private: - ~DataArrayDouble() { } - DataArrayDouble() { } - private: - MemArray _mem; - }; - - class DataArrayDoubleTuple; - - class DataArrayDoubleIterator - { - public: - MEDCOUPLING_EXPORT DataArrayDoubleIterator(DataArrayDouble *da); - MEDCOUPLING_EXPORT ~DataArrayDoubleIterator(); - MEDCOUPLING_EXPORT DataArrayDoubleTuple *nextt(); - private: - DataArrayDouble *_da; - double *_pt; - int _tuple_id; - int _nb_comp; - int _nb_tuple; - }; - - class DataArrayDoubleTuple - { - public: - MEDCOUPLING_EXPORT DataArrayDoubleTuple(double *pt, int nbOfComp); - MEDCOUPLING_EXPORT std::string repr() const; - MEDCOUPLING_EXPORT int getNumberOfCompo() const { return _nb_of_compo; } - MEDCOUPLING_EXPORT const double *getConstPointer() const { return _pt; } - MEDCOUPLING_EXPORT double *getPointer() { return _pt; } - MEDCOUPLING_EXPORT double doubleValue() const; - MEDCOUPLING_EXPORT DataArrayDouble *buildDADouble(int nbOfTuples, int nbOfCompo) const; - private: - double *_pt; - int _nb_of_compo; - }; - - class DataArrayIntIterator; - - class DataArrayInt : public DataArray - { - public: - MEDCOUPLING_EXPORT static DataArrayInt *New(); - MEDCOUPLING_EXPORT bool isAllocated() const; - MEDCOUPLING_EXPORT void checkAllocated() const; - MEDCOUPLING_EXPORT void desallocate(); - MEDCOUPLING_EXPORT int getNumberOfTuples() const { return _info_on_compo.empty()?0:_mem.getNbOfElem()/getNumberOfComponents(); } - MEDCOUPLING_EXPORT std::size_t getNbOfElems() const { return _mem.getNbOfElem(); } - MEDCOUPLING_EXPORT std::size_t getHeapMemorySizeWithoutChildren() const; - MEDCOUPLING_EXPORT int intValue() const; - MEDCOUPLING_EXPORT int getHashCode() const; - MEDCOUPLING_EXPORT bool empty() const; - MEDCOUPLING_EXPORT DataArrayInt *deepCpy() const; - MEDCOUPLING_EXPORT DataArrayInt *performCpy(bool deepCpy) const; - MEDCOUPLING_EXPORT void cpyFrom(const DataArrayInt& other); - MEDCOUPLING_EXPORT void reserve(std::size_t nbOfElems); - MEDCOUPLING_EXPORT void pushBackSilent(int val); - MEDCOUPLING_EXPORT void pushBackValsSilent(const int *valsBg, const int *valsEnd); - MEDCOUPLING_EXPORT int popBackSilent(); - MEDCOUPLING_EXPORT void pack() const; - MEDCOUPLING_EXPORT std::size_t getNbOfElemAllocated() const { return _mem.getNbOfElemAllocated(); } - MEDCOUPLING_EXPORT void alloc(int nbOfTuple, int nbOfCompo=1); - 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 bool isEqualWithoutConsideringStrAndOrder(const DataArrayInt& other) const; - MEDCOUPLING_EXPORT bool isFittingWith(const std::vector& v) const; - MEDCOUPLING_EXPORT void switchOnTupleEqualTo(int val, std::vector& vec) const; - MEDCOUPLING_EXPORT DataArrayInt *buildPermutationArr(const DataArrayInt& other) const; - MEDCOUPLING_EXPORT DataArrayInt *sumPerTuple() const; - MEDCOUPLING_EXPORT void sort(bool asc=true); - MEDCOUPLING_EXPORT void reverse(); - MEDCOUPLING_EXPORT void checkMonotonic(bool increasing) const; - MEDCOUPLING_EXPORT bool isMonotonic(bool increasing) const; - MEDCOUPLING_EXPORT void checkStrictlyMonotonic(bool increasing) const; - MEDCOUPLING_EXPORT bool isStrictlyMonotonic(bool increasing) const; - MEDCOUPLING_EXPORT void fillWithZero(); - MEDCOUPLING_EXPORT void fillWithValue(int val); - MEDCOUPLING_EXPORT void iota(int init=0); - MEDCOUPLING_EXPORT std::string repr() const; - MEDCOUPLING_EXPORT std::string reprZip() const; - MEDCOUPLING_EXPORT std::string reprNotTooLong() const; - MEDCOUPLING_EXPORT void writeVTK(std::ostream& ofs, int indent, const std::string& type, const std::string& nameInFile, DataArrayByte *byteArr) const; - MEDCOUPLING_EXPORT void reprStream(std::ostream& stream) const; - MEDCOUPLING_EXPORT void reprZipStream(std::ostream& stream) const; - MEDCOUPLING_EXPORT void reprNotTooLongStream(std::ostream& stream) const; - MEDCOUPLING_EXPORT void reprWithoutNameStream(std::ostream& stream) const; - MEDCOUPLING_EXPORT void reprZipWithoutNameStream(std::ostream& stream) const; - MEDCOUPLING_EXPORT void reprNotTooLongWithoutNameStream(std::ostream& stream) const; - MEDCOUPLING_EXPORT void reprCppStream(const std::string& varName, std::ostream& stream) const; - MEDCOUPLING_EXPORT void reprQuickOverview(std::ostream& stream) const; - MEDCOUPLING_EXPORT void reprQuickOverviewData(std::ostream& stream, std::size_t maxNbOfByteInRepr) const; - MEDCOUPLING_EXPORT void transformWithIndArr(const int *indArrBg, const int *indArrEnd); - MEDCOUPLING_EXPORT void replaceOneValByInThis(int valToBeReplaced, int replacedBy); - MEDCOUPLING_EXPORT DataArrayInt *transformWithIndArrR(const int *indArrBg, const int *indArrEnd) const; - MEDCOUPLING_EXPORT void splitByValueRange(const int *arrBg, const int *arrEnd, - DataArrayInt *& castArr, DataArrayInt *& rankInsideCast, DataArrayInt *& castsPresent) const; - MEDCOUPLING_EXPORT bool isRange(int& strt, int& sttoopp, int& stteepp) const; - MEDCOUPLING_EXPORT DataArrayInt *invertArrayO2N2N2O(int newNbOfElem) const; - MEDCOUPLING_EXPORT DataArrayInt *invertArrayN2O2O2N(int oldNbOfElem) const; - MEDCOUPLING_EXPORT DataArrayInt *invertArrayO2N2N2OBis(int newNbOfElem) const; - MEDCOUPLING_EXPORT void reAlloc(int nbOfTuples); - MEDCOUPLING_EXPORT DataArrayDouble *convertToDblArr() const; - MEDCOUPLING_EXPORT DataArrayInt *fromNoInterlace() const; - MEDCOUPLING_EXPORT DataArrayInt *toNoInterlace() const; - 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 DataArrayInt *selectByTupleId(const int *new2OldBg, const int *new2OldEnd) const; - MEDCOUPLING_EXPORT DataArrayInt *selectByTupleIdSafe(const int *new2OldBg, const int *new2OldEnd) const; - MEDCOUPLING_EXPORT DataArrayInt *selectByTupleId2(int bg, int end, int step) const; - MEDCOUPLING_EXPORT DataArray *selectByTupleRanges(const std::vector >& ranges) const; - MEDCOUPLING_EXPORT DataArrayInt *checkAndPreparePermutation() const; - MEDCOUPLING_EXPORT static DataArrayInt *FindPermutationFromFirstToSecond(const DataArrayInt *ids1, const DataArrayInt *ids2); - MEDCOUPLING_EXPORT void changeSurjectiveFormat(int targetNb, DataArrayInt *&arr, DataArrayInt *&arrI) const; - MEDCOUPLING_EXPORT static DataArrayInt *BuildOld2NewArrayFromSurjectiveFormat2(int nbOfOldTuples, const int *arr, const int *arrIBg, const int *arrIEnd, int &newNbOfTuples); - MEDCOUPLING_EXPORT DataArrayInt *buildPermArrPerLevel() const; - MEDCOUPLING_EXPORT bool isIdentity() const; - MEDCOUPLING_EXPORT bool isIdentity2(int sizeExpected) const; - MEDCOUPLING_EXPORT bool isUniform(int val) const; - MEDCOUPLING_EXPORT DataArrayInt *substr(int tupleIdBg, int tupleIdEnd=-1) const; - MEDCOUPLING_EXPORT void rearrange(int newNbOfCompo); - MEDCOUPLING_EXPORT void transpose(); - MEDCOUPLING_EXPORT DataArrayInt *changeNbOfComponents(int newNbOfComp, int dftValue) const; - MEDCOUPLING_EXPORT DataArrayInt *keepSelectedComponents(const std::vector& compoIds) const; - MEDCOUPLING_EXPORT void meldWith(const DataArrayInt *other); - MEDCOUPLING_EXPORT void setSelectedComponents(const DataArrayInt *a, const std::vector& compoIds); - MEDCOUPLING_EXPORT void setPartOfValues1(const DataArrayInt *a, int bgTuples, int endTuples, int stepTuples, int bgComp, int endComp, int stepComp, bool strictCompoCompare=true); - MEDCOUPLING_EXPORT void setPartOfValuesSimple1(int a, int bgTuples, int endTuples, int stepTuples, int bgComp, int endComp, int stepComp); - MEDCOUPLING_EXPORT void setPartOfValues2(const DataArrayInt *a, const int *bgTuples, const int *endTuples, const int *bgComp, const int *endComp, bool strictCompoCompare=true); - MEDCOUPLING_EXPORT void setPartOfValuesSimple2(int a, const int *bgTuples, const int *endTuples, const int *bgComp, const int *endComp); - MEDCOUPLING_EXPORT void setPartOfValues3(const DataArrayInt *a, const int *bgTuples, const int *endTuples, int bgComp, int endComp, int stepComp, bool strictCompoCompare=true); - MEDCOUPLING_EXPORT void setPartOfValuesSimple3(int a, const int *bgTuples, const int *endTuples, int bgComp, int endComp, int stepComp); - MEDCOUPLING_EXPORT void setPartOfValues4(const DataArrayInt *a, int bgTuples, int endTuples, int stepTuples, const int *bgComp, const int *endComp, bool strictCompoCompare=true); - MEDCOUPLING_EXPORT void setPartOfValuesSimple4(int a, int bgTuples, int endTuples, int stepTuples, const int *bgComp, const int *endComp); - MEDCOUPLING_EXPORT void setPartOfValuesAdv(const DataArrayInt *a, const DataArrayInt *tuplesSelec); - MEDCOUPLING_EXPORT void setContigPartOfSelectedValues(int tupleIdStart, const DataArray *aBase, const DataArrayInt *tuplesSelec); - MEDCOUPLING_EXPORT void setContigPartOfSelectedValues2(int tupleIdStart, const DataArray *aBase, int bg, int end2, int step); - MEDCOUPLING_EXPORT void getTuple(int tupleId, int *res) const { 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 { return _mem[tupleId*_info_on_compo.size()+compoId]; } - MEDCOUPLING_EXPORT int getIJSafe(int tupleId, int compoId) const; - MEDCOUPLING_EXPORT int front() const; - MEDCOUPLING_EXPORT int back() const; - MEDCOUPLING_EXPORT void setIJ(int tupleId, int compoId, int newVal) { _mem[tupleId*_info_on_compo.size()+compoId]=newVal; declareAsNew(); } - MEDCOUPLING_EXPORT void setIJSilent(int tupleId, int compoId, int newVal) { _mem[tupleId*_info_on_compo.size()+compoId]=newVal; } - MEDCOUPLING_EXPORT int *getPointer() { return _mem.getPointer(); declareAsNew(); } - 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 DataArrayInt *getIdsEqual(int val) const; - MEDCOUPLING_EXPORT DataArrayInt *getIdsNotEqual(int val) const; - MEDCOUPLING_EXPORT DataArrayInt *getIdsEqualList(const int *valsBg, const int *valsEnd) const; - MEDCOUPLING_EXPORT DataArrayInt *getIdsNotEqualList(const int *valsBg, const int *valsEnd) const; - MEDCOUPLING_EXPORT DataArrayInt *getIdsEqualTuple(const int *tupleBg, const int *tupleEnd) const; - MEDCOUPLING_EXPORT int changeValue(int oldValue, int newValue); - MEDCOUPLING_EXPORT int locateTuple(const std::vector& tupl) const; - MEDCOUPLING_EXPORT int locateValue(int value) const; - MEDCOUPLING_EXPORT int locateValue(const std::vector& vals) const; - MEDCOUPLING_EXPORT int search(const std::vector& vals) const; - MEDCOUPLING_EXPORT bool presenceOfTuple(const std::vector& tupl) const; - MEDCOUPLING_EXPORT bool presenceOfValue(int value) const; - MEDCOUPLING_EXPORT bool presenceOfValue(const std::vector& vals) const; - MEDCOUPLING_EXPORT int count(int value) const; - MEDCOUPLING_EXPORT void accumulate(int *res) const; - MEDCOUPLING_EXPORT int accumulate(int compId) const; - MEDCOUPLING_EXPORT DataArrayInt *accumulatePerChunck(const int *bgOfIndex, const int *endOfIndex) const; - MEDCOUPLING_EXPORT int getMaxValue(int& tupleId) const; - MEDCOUPLING_EXPORT int getMaxValueInArray() const; - MEDCOUPLING_EXPORT int getMinValue(int& tupleId) const; - MEDCOUPLING_EXPORT int getMinValueInArray() const; - MEDCOUPLING_EXPORT void getMinMaxValues(int& minValue, int& maxValue) const; - MEDCOUPLING_EXPORT void abs(); - MEDCOUPLING_EXPORT DataArrayInt *computeAbs() const; - MEDCOUPLING_EXPORT void applyLin(int a, int b, int compoId); - MEDCOUPLING_EXPORT void applyLin(int a, int b); - MEDCOUPLING_EXPORT void applyInv(int numerator); - MEDCOUPLING_EXPORT DataArrayInt *negate() const; - MEDCOUPLING_EXPORT void applyDivideBy(int val); - MEDCOUPLING_EXPORT void applyModulus(int val); - MEDCOUPLING_EXPORT void applyRModulus(int val); - MEDCOUPLING_EXPORT void applyPow(int val); - MEDCOUPLING_EXPORT void applyRPow(int val); - MEDCOUPLING_EXPORT DataArrayInt *getIdsInRange(int vmin, int vmax) const; - MEDCOUPLING_EXPORT DataArrayInt *getIdsNotInRange(int vmin, int vmax) const; - MEDCOUPLING_EXPORT DataArrayInt *getIdsStrictlyNegative() const; - MEDCOUPLING_EXPORT bool checkAllIdsInRange(int vmin, int vmax) const; - MEDCOUPLING_EXPORT static DataArrayInt *Aggregate(const DataArrayInt *a1, const DataArrayInt *a2, int offsetA2); - MEDCOUPLING_EXPORT static DataArrayInt *Aggregate(const std::vector& arr); - MEDCOUPLING_EXPORT static DataArrayInt *AggregateIndexes(const std::vector& arrs); - MEDCOUPLING_EXPORT static DataArrayInt *Meld(const DataArrayInt *a1, const DataArrayInt *a2); - MEDCOUPLING_EXPORT static DataArrayInt *Meld(const std::vector& arr); - MEDCOUPLING_EXPORT static DataArrayInt *MakePartition(const std::vector& groups, int newNb, std::vector< std::vector >& fidsOfGroups); - MEDCOUPLING_EXPORT static DataArrayInt *BuildUnion(const std::vector& arr); - MEDCOUPLING_EXPORT static DataArrayInt *BuildIntersection(const std::vector& arr); - MEDCOUPLING_EXPORT static DataArrayInt *BuildListOfSwitchedOn(const std::vector& v); - MEDCOUPLING_EXPORT static DataArrayInt *BuildListOfSwitchedOff(const std::vector& v); - MEDCOUPLING_EXPORT static void PutIntoToSkylineFrmt(const std::vector< std::vector >& v, DataArrayInt *& data, DataArrayInt *& dataIndex); - MEDCOUPLING_EXPORT DataArrayInt *buildComplement(int nbOfElement) const; - MEDCOUPLING_EXPORT DataArrayInt *buildSubstraction(const DataArrayInt *other) const; - MEDCOUPLING_EXPORT DataArrayInt *buildSubstractionOptimized(const DataArrayInt *other) const; - MEDCOUPLING_EXPORT DataArrayInt *buildUnion(const DataArrayInt *other) const; - MEDCOUPLING_EXPORT DataArrayInt *buildIntersection(const DataArrayInt *other) const; - MEDCOUPLING_EXPORT DataArrayInt *buildUnique() const; - MEDCOUPLING_EXPORT DataArrayInt *buildUniqueNotSorted() const; - MEDCOUPLING_EXPORT DataArrayInt *deltaShiftIndex() const; - MEDCOUPLING_EXPORT void computeOffsets(); - MEDCOUPLING_EXPORT void computeOffsets2(); - MEDCOUPLING_EXPORT void searchRangesInListOfIds(const DataArrayInt *listOfIds, DataArrayInt *& rangeIdsFetched, DataArrayInt *& idsInInputListThatFetch) const; - MEDCOUPLING_EXPORT DataArrayInt *buildExplicitArrByRanges(const DataArrayInt *offsets) const; - MEDCOUPLING_EXPORT DataArrayInt *buildExplicitArrOfSliceOnScaledArr(int begin, int stop, int step) const; - MEDCOUPLING_EXPORT DataArrayInt *findRangeIdForEachTuple(const DataArrayInt *ranges) const; - MEDCOUPLING_EXPORT DataArrayInt *findIdInRangeForEachTuple(const DataArrayInt *ranges) const; - MEDCOUPLING_EXPORT void sortEachPairToMakeALinkedList(); - MEDCOUPLING_EXPORT DataArrayInt *duplicateEachTupleNTimes(int nbTimes) const; - MEDCOUPLING_EXPORT DataArrayInt *getDifferentValues() const; - MEDCOUPLING_EXPORT std::vector partitionByDifferentValues(std::vector& differentIds) const; - MEDCOUPLING_EXPORT std::vector< std::pair > splitInBalancedSlices(int nbOfSlices) const; - 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); - template - void insertAtTheEnd(InputIterator first, InputIterator last); - 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); - MEDCOUPLING_EXPORT void addEqual(const DataArrayInt *other); - MEDCOUPLING_EXPORT static DataArrayInt *Substract(const DataArrayInt *a1, const DataArrayInt *a2); - MEDCOUPLING_EXPORT void substractEqual(const DataArrayInt *other); - MEDCOUPLING_EXPORT static DataArrayInt *Multiply(const DataArrayInt *a1, const DataArrayInt *a2); - MEDCOUPLING_EXPORT void multiplyEqual(const DataArrayInt *other); - MEDCOUPLING_EXPORT static DataArrayInt *Divide(const DataArrayInt *a1, const DataArrayInt *a2); - MEDCOUPLING_EXPORT void divideEqual(const DataArrayInt *other); - MEDCOUPLING_EXPORT static DataArrayInt *Modulus(const DataArrayInt *a1, const DataArrayInt *a2); - MEDCOUPLING_EXPORT void modulusEqual(const DataArrayInt *other); - MEDCOUPLING_EXPORT static DataArrayInt *Pow(const DataArrayInt *a1, const DataArrayInt *a2); - MEDCOUPLING_EXPORT void powEqual(const DataArrayInt *other); - 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); - 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); - private: - ~DataArrayInt() { } - DataArrayInt() { } - private: - MemArray _mem; - }; - - class DataArrayIntTuple; - - class DataArrayIntIterator - { - public: - MEDCOUPLING_EXPORT DataArrayIntIterator(DataArrayInt *da); - MEDCOUPLING_EXPORT ~DataArrayIntIterator(); - MEDCOUPLING_EXPORT DataArrayIntTuple *nextt(); - private: - DataArrayInt *_da; - int *_pt; - int _tuple_id; - int _nb_comp; - int _nb_tuple; - }; - - class DataArrayIntTuple - { - public: - MEDCOUPLING_EXPORT DataArrayIntTuple(int *pt, int nbOfComp); - MEDCOUPLING_EXPORT std::string repr() const; - MEDCOUPLING_EXPORT int getNumberOfCompo() const { return _nb_of_compo; } - MEDCOUPLING_EXPORT const int *getConstPointer() const { return _pt; } - MEDCOUPLING_EXPORT int *getPointer() { return _pt; } - MEDCOUPLING_EXPORT int intValue() const; - MEDCOUPLING_EXPORT DataArrayInt *buildDAInt(int nbOfTuples, int nbOfCompo) const; - private: - int *_pt; - int _nb_of_compo; - }; - - class DataArrayChar : public DataArray - { - public: - MEDCOUPLING_EXPORT virtual DataArrayChar *buildEmptySpecializedDAChar() const = 0; - MEDCOUPLING_EXPORT bool isAllocated() const; - MEDCOUPLING_EXPORT void checkAllocated() const; - MEDCOUPLING_EXPORT void desallocate(); - MEDCOUPLING_EXPORT int getNumberOfTuples() const { return _info_on_compo.empty()?0:_mem.getNbOfElem()/getNumberOfComponents(); } - MEDCOUPLING_EXPORT std::size_t getNbOfElems() const { return _mem.getNbOfElem(); } - MEDCOUPLING_EXPORT std::size_t getHeapMemorySizeWithoutChildren() const; - MEDCOUPLING_EXPORT int getHashCode() const; - MEDCOUPLING_EXPORT bool empty() const; - MEDCOUPLING_EXPORT void cpyFrom(const DataArrayChar& other); - MEDCOUPLING_EXPORT void reserve(std::size_t nbOfElems); - MEDCOUPLING_EXPORT void pushBackSilent(char val); - MEDCOUPLING_EXPORT void pushBackValsSilent(const char *valsBg, const char *valsEnd); - MEDCOUPLING_EXPORT char popBackSilent(); - MEDCOUPLING_EXPORT void pack() const; - MEDCOUPLING_EXPORT std::size_t getNbOfElemAllocated() const { return _mem.getNbOfElemAllocated(); } - MEDCOUPLING_EXPORT void alloc(int nbOfTuple, int nbOfCompo=1); - MEDCOUPLING_EXPORT void allocIfNecessary(int nbOfTuple, int nbOfCompo); - MEDCOUPLING_EXPORT bool isEqual(const DataArrayChar& other) const; - MEDCOUPLING_EXPORT virtual bool isEqualIfNotWhy(const DataArrayChar& other, std::string& reason) const; - MEDCOUPLING_EXPORT bool isEqualWithoutConsideringStr(const DataArrayChar& other) const; - MEDCOUPLING_EXPORT void reverse(); - MEDCOUPLING_EXPORT void fillWithZero(); - MEDCOUPLING_EXPORT void fillWithValue(char val); - MEDCOUPLING_EXPORT std::string repr() const; - MEDCOUPLING_EXPORT std::string reprZip() const; - MEDCOUPLING_EXPORT void reAlloc(int nbOfTuples); - MEDCOUPLING_EXPORT DataArrayInt *convertToIntArr() const; - MEDCOUPLING_EXPORT void renumberInPlace(const int *old2New); - MEDCOUPLING_EXPORT void renumberInPlaceR(const int *new2Old); - MEDCOUPLING_EXPORT DataArrayChar *renumber(const int *old2New) const; - MEDCOUPLING_EXPORT DataArrayChar *renumberR(const int *new2Old) const; - MEDCOUPLING_EXPORT DataArrayChar *renumberAndReduce(const int *old2NewBg, int newNbOfTuple) const; - MEDCOUPLING_EXPORT DataArrayChar *selectByTupleId(const int *new2OldBg, const int *new2OldEnd) const; - MEDCOUPLING_EXPORT DataArrayChar *selectByTupleIdSafe(const int *new2OldBg, const int *new2OldEnd) const; - MEDCOUPLING_EXPORT DataArrayChar *selectByTupleId2(int bg, int end, int step) const; - MEDCOUPLING_EXPORT bool isUniform(char val) const; - MEDCOUPLING_EXPORT void rearrange(int newNbOfCompo); - MEDCOUPLING_EXPORT DataArrayChar *substr(int tupleIdBg, int tupleIdEnd=-1) const; - MEDCOUPLING_EXPORT DataArrayChar *changeNbOfComponents(int newNbOfComp, char dftValue) const; - MEDCOUPLING_EXPORT DataArrayChar *keepSelectedComponents(const std::vector& compoIds) const; - MEDCOUPLING_EXPORT void meldWith(const DataArrayChar *other); - MEDCOUPLING_EXPORT void setPartOfValues1(const DataArrayChar *a, int bgTuples, int endTuples, int stepTuples, int bgComp, int endComp, int stepComp, bool strictCompoCompare=true); - MEDCOUPLING_EXPORT void setPartOfValuesSimple1(char a, int bgTuples, int endTuples, int stepTuples, int bgComp, int endComp, int stepComp); - MEDCOUPLING_EXPORT void setPartOfValues2(const DataArrayChar *a, const int *bgTuples, const int *endTuples, const int *bgComp, const int *endComp, bool strictCompoCompare=true); - MEDCOUPLING_EXPORT void setPartOfValuesSimple2(char a, const int *bgTuples, const int *endTuples, const int *bgComp, const int *endComp); - MEDCOUPLING_EXPORT void setPartOfValues3(const DataArrayChar *a, const int *bgTuples, const int *endTuples, int bgComp, int endComp, int stepComp, bool strictCompoCompare=true); - MEDCOUPLING_EXPORT void setPartOfValuesSimple3(char a, const int *bgTuples, const int *endTuples, int bgComp, int endComp, int stepComp); - MEDCOUPLING_EXPORT void setPartOfValues4(const DataArrayChar *a, int bgTuples, int endTuples, int stepTuples, const int *bgComp, const int *endComp, bool strictCompoCompare=true); - MEDCOUPLING_EXPORT void setPartOfValuesSimple4(char a, int bgTuples, int endTuples, int stepTuples, const int *bgComp, const int *endComp); - MEDCOUPLING_EXPORT void setPartOfValuesAdv(const DataArrayChar *a, const DataArrayChar *tuplesSelec); - MEDCOUPLING_EXPORT void setContigPartOfSelectedValues(int tupleIdStart, const DataArray *aBase, const DataArrayInt *tuplesSelec); - MEDCOUPLING_EXPORT void setContigPartOfSelectedValues2(int tupleIdStart, const DataArray *aBase, int bg, int end2, int step); - MEDCOUPLING_EXPORT DataArray *selectByTupleRanges(const std::vector >& ranges) const; - 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; - MEDCOUPLING_EXPORT char front() const; - MEDCOUPLING_EXPORT char back() const; - 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(); declareAsNew(); } - MEDCOUPLING_EXPORT const char *getConstPointer() const { return _mem.getConstPointer(); } - MEDCOUPLING_EXPORT const char *begin() const { return getConstPointer(); } - MEDCOUPLING_EXPORT const char *end() const { return getConstPointer()+getNbOfElems(); } - MEDCOUPLING_EXPORT DataArrayInt *getIdsEqual(char val) const; - MEDCOUPLING_EXPORT DataArrayInt *getIdsNotEqual(char val) const; - MEDCOUPLING_EXPORT int search(const std::vector& vals) const; - MEDCOUPLING_EXPORT int locateTuple(const std::vector& tupl) const; - MEDCOUPLING_EXPORT int locateValue(char value) const; - MEDCOUPLING_EXPORT int locateValue(const std::vector& vals) const; - MEDCOUPLING_EXPORT bool presenceOfTuple(const std::vector& tupl) const; - MEDCOUPLING_EXPORT bool presenceOfValue(char value) const; - MEDCOUPLING_EXPORT bool presenceOfValue(const std::vector& vals) const; - MEDCOUPLING_EXPORT char getMaxValue(int& tupleId) const; - MEDCOUPLING_EXPORT char getMaxValueInArray() const; - MEDCOUPLING_EXPORT char getMinValue(int& tupleId) const; - MEDCOUPLING_EXPORT char getMinValueInArray() const; - MEDCOUPLING_EXPORT DataArrayInt *getIdsInRange(char vmin, char vmax) const; - MEDCOUPLING_EXPORT static DataArrayChar *Aggregate(const DataArrayChar *a1, const DataArrayChar *a2); - MEDCOUPLING_EXPORT static DataArrayChar *Aggregate(const std::vector& arr); - MEDCOUPLING_EXPORT static DataArrayChar *Meld(const DataArrayChar *a1, const DataArrayChar *a2); - MEDCOUPLING_EXPORT static DataArrayChar *Meld(const std::vector& arr); - MEDCOUPLING_EXPORT void useArray(const char *array, bool ownership, DeallocType type, int nbOfTuple, int nbOfCompo); - template - void insertAtTheEnd(InputIterator first, InputIterator last); - MEDCOUPLING_EXPORT void useExternalArrayWithRWAccess(const char *array, int nbOfTuple, int nbOfCompo); - 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; - MEDCOUPLING_EXPORT DataArrayByteIterator *iterator(); - MEDCOUPLING_EXPORT DataArrayByte *deepCpy() const; - MEDCOUPLING_EXPORT DataArrayByte *performCpy(bool deepCpy) const; - MEDCOUPLING_EXPORT char byteValue() const; - 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 std::string& varName, std::ostream& stream) const; - MEDCOUPLING_EXPORT void reprQuickOverview(std::ostream& stream) const; - MEDCOUPLING_EXPORT void reprQuickOverviewData(std::ostream& stream, std::size_t maxNbOfByteInRepr) const; - MEDCOUPLING_EXPORT bool isEqualIfNotWhy(const DataArrayChar& other, std::string& reason) const; - MEDCOUPLING_EXPORT std::vector toVectorOfBool() const; - private: - ~DataArrayByte() { } - DataArrayByte() { } - }; - - class DataArrayByteTuple; - - class DataArrayByteIterator - { - public: - MEDCOUPLING_EXPORT DataArrayByteIterator(DataArrayByte *da); - MEDCOUPLING_EXPORT ~DataArrayByteIterator(); - MEDCOUPLING_EXPORT DataArrayByteTuple *nextt(); - private: - DataArrayByte *_da; - char *_pt; - int _tuple_id; - int _nb_comp; - int _nb_tuple; - }; - - class DataArrayByteTuple - { - public: - MEDCOUPLING_EXPORT DataArrayByteTuple(char *pt, int nbOfComp); - MEDCOUPLING_EXPORT std::string repr() const; - MEDCOUPLING_EXPORT int getNumberOfCompo() const { return _nb_of_compo; } - MEDCOUPLING_EXPORT const char *getConstPointer() const { return _pt; } - MEDCOUPLING_EXPORT char *getPointer() { return _pt; } - MEDCOUPLING_EXPORT char byteValue() const; - MEDCOUPLING_EXPORT DataArrayByte *buildDAByte(int nbOfTuples, int nbOfCompo) const; - 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); - MEDCOUPLING_EXPORT static DataArrayAsciiChar *New(const std::vector& vst, char defaultChar); - MEDCOUPLING_EXPORT DataArrayChar *buildEmptySpecializedDAChar() const; - MEDCOUPLING_EXPORT DataArrayAsciiCharIterator *iterator(); - MEDCOUPLING_EXPORT DataArrayAsciiChar *deepCpy() const; - MEDCOUPLING_EXPORT DataArrayAsciiChar *performCpy(bool deepCpy) const; - MEDCOUPLING_EXPORT char asciiCharValue() const; - 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 std::string& varName, std::ostream& stream) const; - MEDCOUPLING_EXPORT void reprQuickOverview(std::ostream& stream) const; - MEDCOUPLING_EXPORT void reprQuickOverviewData(std::ostream& stream, std::size_t maxNbOfByteInRepr) const; - MEDCOUPLING_EXPORT bool isEqualIfNotWhy(const DataArrayChar& other, std::string& reason) const; - private: - ~DataArrayAsciiChar() { } - DataArrayAsciiChar() { } - DataArrayAsciiChar(const std::string& st); - DataArrayAsciiChar(const std::vector& vst, char defaultChar); - }; - - class DataArrayAsciiCharTuple; - - class DataArrayAsciiCharIterator - { - public: - MEDCOUPLING_EXPORT DataArrayAsciiCharIterator(DataArrayAsciiChar *da); - MEDCOUPLING_EXPORT ~DataArrayAsciiCharIterator(); - MEDCOUPLING_EXPORT DataArrayAsciiCharTuple *nextt(); - private: - DataArrayAsciiChar *_da; - char *_pt; - int _tuple_id; - int _nb_comp; - int _nb_tuple; - }; - - class DataArrayAsciiCharTuple - { - public: - MEDCOUPLING_EXPORT DataArrayAsciiCharTuple(char *pt, int nbOfComp); - MEDCOUPLING_EXPORT std::string repr() const; - MEDCOUPLING_EXPORT int getNumberOfCompo() const { return _nb_of_compo; } - MEDCOUPLING_EXPORT const char *getConstPointer() const { return _pt; } - MEDCOUPLING_EXPORT char *getPointer() { return _pt; } - MEDCOUPLING_EXPORT char asciiCharValue() const; - MEDCOUPLING_EXPORT DataArrayAsciiChar *buildDAAsciiChar(int nbOfTuples, int nbOfCompo) const; - private: - char *_pt; - int _nb_of_compo; - }; - - template - void DataArrayDouble::insertAtTheEnd(InputIterator first, InputIterator last) - { - 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) - { - 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 !"); - } - - template - void DataArrayChar::insertAtTheEnd(InputIterator first, InputIterator last) - { - 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("DataArrayChar::insertAtTheEnd : not available for DataArrayChar with number of components different than 1 !"); - } -} - -#endif diff --git a/src/MEDCoupling/MEDCouplingMemArray.txx b/src/MEDCoupling/MEDCouplingMemArray.txx deleted file mode 100644 index 693e6e4f0..000000000 --- a/src/MEDCoupling/MEDCouplingMemArray.txx +++ /dev/null @@ -1,495 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 -// 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_MEDCOUPLINGMEMARRAY_TXX__ -#define __PARAMEDMEM_MEDCOUPLINGMEMARRAY_TXX__ - -#include "MEDCouplingMemArray.hxx" -#include "NormalizedUnstructuredMesh.hxx" -#include "InterpKernelException.hxx" -#include "InterpolationUtils.hxx" - -#include -#include -#include - -namespace ParaMEDMEM -{ - template - void MEDCouplingPointer::setInternal(T *pointer) - { - _internal=pointer; - _external=0; - } - - template - void MEDCouplingPointer::setExternal(const T *pointer) - { - _external=pointer; - _internal=0; - } - - template - 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()) - { - _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,C_DEALLOC,other._nb_of_elem); - } - } - - template - void MemArray::useArray(const T *array, bool ownership, DeallocType type, std::size_t nbOfElem) - { - destroy(); - _nb_of_elem=nbOfElem; - _nb_of_elem_alloc=nbOfElem; - if(ownership) - _pointer.setInternal(const_cast(array)); - else - _pointer.setExternal(array); - _ownership=ownership; - _dealloc=BuildFromType(type); - } - - template - void MemArray::useExternalArrayWithRWAccess(const T *array, std::size_t nbOfElem) - { - destroy(); - _nb_of_elem=nbOfElem; - _nb_of_elem_alloc=nbOfElem; - _pointer.setInternal(const_cast(array)); - _ownership=false; - _dealloc=CPPDeallocator; - } - - template - void MemArray::writeOnPlace(std::size_t id, T element0, const T *others, std::size_t sizeOfOthers) - { - 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) - { - 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) - { - 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() - { - 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 - { - (const_cast * >(this))->reserve(_nb_of_elem); - } - - template - bool MemArray::isEqual(const MemArray& other, T prec, std::string& reason) const - { - std::ostringstream oss; oss.precision(15); - if(_nb_of_elem!=other._nb_of_elem) - { - oss << "Number of elements in coarse data of DataArray mismatch : this=" << _nb_of_elem << " other=" << other._nb_of_elem; - reason=oss.str(); - return false; - } - const T *pt1=_pointer.getConstPointer(); - const T *pt2=other._pointer.getConstPointer(); - if(pt1==0 && pt2==0) - return true; - if(pt1==0 || pt2==0) - { - oss << "coarse data pointer is defined for only one DataArray instance !"; - reason=oss.str(); - return false; - } - if(pt1==pt2) - return true; - 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]; - reason=oss.str(); - return false; - } - return true; - } - - /*! - * \param [in] sl is typically the number of components - * \return True if a not null pointer is present, False if not. - */ - template - bool MemArray::reprHeader(int sl, std::ostream& stream) const - { - stream << "Number of tuples : "; - if(!_pointer.isNull()) - { - if(sl!=0) - 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"; - 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) - { - std::size_t nbOfTuples=_nb_of_elem/std::abs(sl); - for(std::size_t i=0;i(stream," ")); - stream << "\n"; - data+=sl; - } - } - else - stream << "Empty Data\n"; - } - } - - /*! - * \param [in] sl is typically the number of components - */ - template - void MemArray::reprZip(int sl, std::ostream& stream) const - { - stream << "Number of tuples : "; - if(!_pointer.isNull()) - { - if(sl!=0) - stream << _nb_of_elem/sl; - else - stream << "Empty Data"; - } - else - stream << "No data"; - stream << "\n"; - stream << "Data content : "; - const T *data=getConstPointer(); - if(!_pointer.isNull()) - { - if(_nb_of_elem!=0 && sl!=0) - { - std::size_t nbOfTuples=_nb_of_elem/std::abs(sl); - for(std::size_t i=0;i(stream," ")); - stream << "| "; - data+=sl; - } - stream << "\n"; - } - else - stream << "Empty Data\n"; - } - else - stream << "No data !\n"; - } - - /*! - * \param [in] sl is typically the number of components - */ - template - void MemArray::reprNotTooLong(int sl, std::ostream& stream) const - { - if(reprHeader(sl,stream)) - { - const T *data=getConstPointer(); - if(_nb_of_elem!=0 && sl!=0) - { - std::size_t nbOfTuples=_nb_of_elem/std::abs(sl); - if(nbOfTuples<=1000) - { - for(std::size_t i=0;i(stream," ")); - stream << "\n"; - data+=sl; - } - } - else - {// too much tuples -> print the 3 first tuples and 3 last. - stream << "Tuple #0 : "; - std::copy(data,data+sl,std::ostream_iterator(stream," ")); stream << "\n"; - stream << "Tuple #1 : "; - std::copy(data+sl,data+2*sl,std::ostream_iterator(stream," ")); stream << "\n"; - stream << "Tuple #2 : "; - std::copy(data+2*sl,data+3*sl,std::ostream_iterator(stream," ")); stream << "\n"; - stream << "...\n"; - stream << "Tuple #" << nbOfTuples-3 << " : "; - std::copy(data+(nbOfTuples-3)*sl,data+(nbOfTuples-2)*sl,std::ostream_iterator(stream," ")); stream << "\n"; - stream << "Tuple #" << nbOfTuples-2 << " : "; - std::copy(data+(nbOfTuples-2)*sl,data+(nbOfTuples-1)*sl,std::ostream_iterator(stream," ")); stream << "\n"; - stream << "Tuple #" << nbOfTuples-1 << " : "; - std::copy(data+(nbOfTuples-1)*sl,data+nbOfTuples*sl,std::ostream_iterator(stream," ")); stream << "\n"; - } - } - else - stream << "Empty Data\n"; - } - } - - template - void MemArray::fillWithValue(const T& val) - { - T *pt=_pointer.getPointer(); - std::fill(pt,pt+_nb_of_elem,val); - } - - 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(); - std::size_t nbOfTuples=_nb_of_elem/nbOfComp; - T *ret=(T*)malloc(_nb_of_elem*sizeof(T)); - T *w=ret; - for(std::size_t 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(); - 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::sort(bool asc) - { - T *pt=_pointer.getPointer(); - if(asc) - std::sort(pt,pt+_nb_of_elem); - else - { - typename std::reverse_iterator it1(pt+_nb_of_elem); - typename std::reverse_iterator it2(pt); - std::sort(it1,it2); - } - } - - template - 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(); - 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(std::size_t nbOfElements) - { - destroy(); - _nb_of_elem=nbOfElements; - _nb_of_elem_alloc=nbOfElements; - _pointer.setInternal((T*)malloc(_nb_of_elem_alloc*sizeof(T))); - _ownership=true; - _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) - { - 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(std::size_t newNbOfElements) - { - 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,_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=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 - typename MemArray::Deallocator MemArray::BuildFromType(DeallocType type) - { - switch(type) - { - case CPP_DEALLOC: - return CPPDeallocator; - case C_DEALLOC: - return CDeallocator; - default: - 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,_param_for_deallocator);//Do not use getPointer because in case of _external - _pointer.null(); - _ownership=false; - _dealloc=NULL; - _param_for_deallocator=NULL; - _nb_of_elem=0; - _nb_of_elem_alloc=0; - } - - template - MemArray &MemArray::operator=(const MemArray& other) - { - alloc(other._nb_of_elem); - std::copy(other._pointer.getConstPointer(),other._pointer.getConstPointer()+_nb_of_elem,_pointer.getPointer()); - return *this; - } -} - -#endif diff --git a/src/MEDCoupling/MEDCouplingMemArrayChar.cxx b/src/MEDCoupling/MEDCouplingMemArrayChar.cxx deleted file mode 100644 index 59d29b2aa..000000000 --- a/src/MEDCoupling/MEDCouplingMemArrayChar.cxx +++ /dev/null @@ -1,2602 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 -// 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 -{ - 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 -{ - if(!isAllocated()) - throw INTERP_KERNEL::Exception("DataArrayChar::checkAllocated : Array is defined but not allocated ! Call alloc or setValues method first !"); -} - -/*! - * This method desallocated \a this without modification of informations relative to the components. - * After call of this method, DataArrayChar::isAllocated will return false. - * If \a this is already not allocated, \a this is let unchanged. - */ -void DataArrayChar::desallocate() -{ - _mem.destroy(); -} - -std::size_t DataArrayChar::getHeapMemorySizeWithoutChildren() const -{ - std::size_t sz(_mem.getNbOfElemAllocated()); - return DataArray::getHeapMemorySizeWithoutChildren()+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 -{ - 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() -{ - 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() -{ - 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) -{ - 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 -{ - std::ostringstream ret; - reprStream(ret); - return ret.str(); -} - -std::string DataArrayChar::reprZip() const -{ - 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. - * \throw If \a nbOfTuples is negative. - */ -void DataArrayChar::reAlloc(int nbOfTuples) -{ - if(nbOfTuples<0) - throw INTERP_KERNEL::Exception("DataArrayChar::reAlloc : input new number of tuples should be >=0 !"); - 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 -{ - 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 numbering. - * \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) -{ - 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) -{ - 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 -{ - 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 numbering. - * \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 -{ - 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 numbering. - * \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 -{ - 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. - * For more info on renumbering see \ref numbering. - * \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. - */ -DataArrayChar *DataArrayChar::selectByTupleId(const int *new2OldBg, const int *new2OldEnd) const -{ - return selectByTupleIdSafe(new2OldBg,new2OldEnd); -} - -/*! - * 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 numbering. - * \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 -{ - 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 numbering. - * \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 -{ - 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 -{ - 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) -{ - 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 -{ - 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 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::changeNbOfComponents(int newNbOfComp, char dftValue) const -{ - 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()); - for(int i=0;isetInfoOnComponent(i,getInfoOnComponent(i)); - ret->setName(getName()); - 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(). - * - * \if ENABLE_EXAMPLES - * \ref py_mcdataarrayint_keepselectedcomponents "Here is a Python example". - * \endif - */ -DataArrayChar *DataArrayChar::keepSelectedComponents(const std::vector& compoIds) const -{ - 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)). - * - * \if ENABLE_EXAMPLES - * \ref py_mcdataarrayint_setpartofvalues1 "Here is a Python example". - * \endif - */ -void DataArrayChar::setPartOfValues1(const DataArrayChar *a, int bgTuples, int endTuples, int stepTuples, int bgComp, int endComp, int stepComp, bool strictCompoCompare) -{ - 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). - * - * \if ENABLE_EXAMPLES - * \ref py_mcdataarrayint_setpartofvalues2 "Here is a Python example". - * \endif - */ -void DataArrayChar::setPartOfValues2(const DataArrayChar *a, const int *bgTuples, const int *endTuples, const int *bgComp, const int *endComp, bool strictCompoCompare) -{ - 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. - * - * \if ENABLE_EXAMPLES - * \ref py_mcdataarrayint_setpartofvaluessimple2 "Here is a Python example". - * \endif - */ -void DataArrayChar::setPartOfValuesSimple2(char a, const int *bgTuples, const int *endTuples, const int *bgComp, const int *endComp) -{ - 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. - * - * \if ENABLE_EXAMPLES - * \ref py_mcdataarrayint_setpartofvalues3 "Here is a Python example". - * \endif - */ -void DataArrayChar::setPartOfValues3(const DataArrayChar *a, const int *bgTuples, const int *endTuples, int bgComp, int endComp, int stepComp, bool strictCompoCompare) -{ - 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. - * - * \if ENABLE_EXAMPLES - * \ref py_mcdataarrayint_setpartofvaluessimple3 "Here is a Python example". - * \endif - */ -void DataArrayChar::setPartOfValuesSimple3(char a, const int *bgTuples, const int *endTuples, int bgComp, int endComp, int stepComp) -{ - 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) -{ - 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 aBase) 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] aBase - the array to copy values from. - * \param [in] tuplesSelec - the array specifying tuples of \a aBase to copy. - * \throw If \a this is not allocated. - * \throw If \a aBase is NULL. - * \throw If \a aBase is not allocated. - * \throw If \a tuplesSelec is NULL. - * \throw If \a tuplesSelec is not allocated. - * \throw If this->getNumberOfComponents() != aBase->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 aBase array. - */ -void DataArrayChar::setContigPartOfSelectedValues(int tupleIdStart, const DataArray *aBase, const DataArrayInt *tuplesSelec) -{ - 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 aBase) 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] aBase - the array to copy values from. - * \param [in] bg - index of the first tuple to copy of the array \a aBase. - * \param [in] end2 - index of the tuple of \a aBase 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 aBase is NULL. - * \throw If \a aBase is not allocated. - * \throw If this->getNumberOfComponents() != aBase->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 aBase. - */ -void DataArrayChar::setContigPartOfSelectedValues2(int tupleIdStart, const DataArray *aBase, int bg, int end2, int step) -{ - 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 -{ - 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 char - 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 -{ - 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 first value of \a this. - * \return char - 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::front() const -{ - checkAllocated(); - if(getNumberOfComponents()!=1) - throw INTERP_KERNEL::Exception("DataArrayChar::front : number of components not equal to one !"); - int nbOfTuples=getNumberOfTuples(); - if(nbOfTuples<1) - throw INTERP_KERNEL::Exception("DataArrayChar::front : number of tuples must be >= 1 !"); - return *(getConstPointer()); -} - -/*! - * Returns the last value of \a this. - * \return char - 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 -{ - 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 -{ - 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 -{ - 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 -{ - 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 -{ - 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 -{ - 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 -{ - 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 -{ - 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 -{ - 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 -{ - 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 char - 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 -{ - 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 -{ - 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 -{ - 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 -{ - 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 [in] 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 -{ - 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) -{ - 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) -{ - 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) -{ - 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)); - 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) -{ - _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) -{ - _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 char - the sole value stored in \a this array. - * \throw If at least one of conditions stated above is not fulfilled. - */ -char DataArrayByte::byteValue() const -{ - 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 -{ - return DataArrayByte::New(); -} - -void DataArrayByte::reprStream(std::ostream& stream) const -{ - stream << "Name of byte array : \"" << _name << "\"\n"; - reprWithoutNameStream(stream); -} - -void DataArrayByte::reprZipStream(std::ostream& stream) const -{ - stream << "Name of byte array : \"" << _name << "\"\n"; - reprZipWithoutNameStream(stream); -} - -void DataArrayByte::reprWithoutNameStream(std::ostream& stream) const -{ - 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 -{ - DataArray::reprWithoutNameStream(stream); - _mem.reprZip(getNumberOfComponents(),stream); -} - -void DataArrayByte::reprCppStream(const std::string& varName, std::ostream& stream) const -{ - 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 -{ - 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 -{ - 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); -} - -/*! - * This method is \b NOT wrapped into python because it can be useful only for performance reasons in C++ context. - * \throw if \a this is not allocated. - * \throw if \a this has not exactly one component. - */ -std::vector DataArrayByte::toVectorOfBool() const -{ - checkAllocated(); - if(getNumberOfComponents()!=1) - throw INTERP_KERNEL::Exception("DataArrayByte::toVectorOfBool : this method can be used only if this has one component !"); - int nbt(getNumberOfTuples()); - std::vector ret(nbt,false); - const char *pt(begin()); - for(int i=0;iincrRef(); - if(_da->isAllocated()) - { - _nb_comp=da->getNumberOfComponents(); - _nb_tuple=da->getNumberOfTuples(); - _pt=da->getPointer(); - } - } -} - -DataArrayByteIterator::~DataArrayByteIterator() -{ - if(_da) - _da->decrRef(); -} - -DataArrayByteTuple *DataArrayByteIterator::nextt() -{ - 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 -{ - 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 -{ - 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 -{ - 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) -{ - 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) -{ - 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) -{ - 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) -{ - 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 char - the sole value stored in \a this array. - * \throw If at least one of conditions stated above is not fulfilled. - */ -char DataArrayAsciiChar::asciiCharValue() const -{ - 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 -{ - return DataArrayAsciiChar::New(); -} - -void DataArrayAsciiChar::reprStream(std::ostream& stream) const -{ - stream << "Name of ASCII char array : \"" << _name << "\"\n"; - reprWithoutNameStream(stream); -} - -void DataArrayAsciiChar::reprZipStream(std::ostream& stream) const -{ - stream << "Name of ASCII char array : \"" << _name << "\"\n"; - reprZipWithoutNameStream(stream); -} - -void DataArrayAsciiChar::reprWithoutNameStream(std::ostream& stream) const -{ - 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 -{ - reprWithoutNameStream(stream); -} - -void DataArrayAsciiChar::reprCppStream(const std::string& varName, std::ostream& stream) const -{ - 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 -{ - 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 -{ - 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() -{ - 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 -{ - std::ostringstream oss; - std::copy(_pt,_pt+_nb_of_compo,std::ostream_iterator(oss)); - return oss.str(); -} - -char DataArrayAsciiCharTuple::asciiCharValue() const -{ - 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 -{ - 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 deleted file mode 100644 index ea60f27de..000000000 --- a/src/MEDCoupling/MEDCouplingMesh.cxx +++ /dev/null @@ -1,760 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 -// 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 "MEDCouplingMesh.hxx" -#include "MEDCouplingUMesh.hxx" -#include "MEDCouplingMemArray.hxx" -#include "MEDCouplingFieldDouble.hxx" -#include "MEDCouplingFieldDiscretization.hxx" -#include "MEDCouplingAutoRefCountObjectPtr.hxx" - -#include -#include -#include -#include -#include - -using namespace ParaMEDMEM; - -MEDCouplingMesh::MEDCouplingMesh():_time(0.),_iteration(-1),_order(-1) -{ -} - -MEDCouplingMesh::MEDCouplingMesh(const MEDCouplingMesh& other):RefCountObject(other),_name(other._name),_description(other._description), - _time(other._time),_iteration(other._iteration), - _order(other._order),_time_unit(other._time_unit) -{ -} - -std::size_t MEDCouplingMesh::getHeapMemorySizeWithoutChildren() const -{ - return _name.capacity()+_description.capacity()+_time_unit.capacity(); -} - -/*! - * This method is only for ParaMEDMEM in ParaFIELD constructor. - */ -bool MEDCouplingMesh::isStructured() const -{ - return getType()==CARTESIAN; -} - -bool MEDCouplingMesh::isEqualIfNotWhy(const MEDCouplingMesh *other, double prec, std::string& reason) const -{ - if(!other) - throw INTERP_KERNEL::Exception("MEDCouplingMesh::isEqualIfNotWhy : other instance is NULL !"); - std::ostringstream oss; oss.precision(15); - if(_name!=other->_name) - { - oss << "Mesh names differ : this name = \"" << _name << "\" and other name = \"" << other->_name << "\" !"; - reason=oss.str(); - return false; - } - if(_description!=other->_description) - { - oss << "Mesh descriptions differ : this description = \"" << _description << "\" and other description = \"" << other->_description << "\" !"; - reason=oss.str(); - return false; - } - if(_iteration!=other->_iteration) - { - oss << "Mesh iterations differ : this iteration = \"" << _iteration << "\" and other iteration = \"" << other->_iteration << "\" !"; - reason=oss.str(); - return false; - } - if(_order!=other->_order) - { - oss << "Mesh orders differ : this order = \"" << _order << "\" and other order = \"" << other->_order << "\" !"; - reason=oss.str(); - return false; - } - if(_time_unit!=other->_time_unit) - { - oss << "Mesh time units differ : this time unit = \"" << _time_unit << "\" and other time unit = \"" << other->_time_unit << "\" !"; - reason=oss.str(); - return false; - } - if(fabs(_time-other->_time)>=1e-12) - { - oss << "Mesh times differ : this time = \"" << _time << "\" and other time = \"" << other->_time << "\" !"; - reason=oss.str(); - return false; - } - 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 -{ - std::string tmp; - return isEqualIfNotWhy(other,prec,tmp); -} - -/*! - * 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. - * - * 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. \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 -{ - cellCor=0; - nodeCor=0; - if(this==other) - return ; - switch(levOfCheck) - { - case 0: - { - if(!isEqual(other,prec)) - throw INTERP_KERNEL::Exception("checkGeoFitWith : Meshes are not equal !"); - return ; - } - case 10: - case 11: - case 12: - { - checkDeepEquivalWith(other,levOfCheck-10,prec,cellCor,nodeCor); - return ; - } - case 20: - case 21: - case 22: - { - checkDeepEquivalOnSameNodesWith(other,levOfCheck-20,prec,cellCor); - return ; - } - case 1: - { - checkFastEquivalWith(other,prec); - return; - } - case 2: - { - if(!isEqualWithoutConsideringStr(other,prec)) - throw INTERP_KERNEL::Exception("checkGeoFitWith : Meshes are not equal without considering strings !"); - return ; - } - default: - throw INTERP_KERNEL::Exception("checkGeoFitWith : Invalid levOfCheck specified ! Value must be in 0,1,2,10,11 or 12."); - } -} - -/*! - * 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 -{ - std::vector crest; - std::set p(partBg,partEnd); - int nbOfCells=getNumberOfCells(); - for(int i=0;i conn; - getNodeIdsOfCell(i,conn); - bool cont=true; - for(std::vector::const_iterator iter=conn.begin();iter!=conn.end() && cont;iter++) - if(p.find(*iter)==p.end()) - cont=false; - if(cont) - crest.push_back(i); - } - DataArrayInt *ret=DataArrayInt::New(); - ret->alloc((int)crest.size(),1); - std::copy(crest.begin(),crest.end(),ret->getPointer()); - return ret; -} - -/*! - * 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 -{ - if(!other) - throw INTERP_KERNEL::Exception("MEDCouplingMesh::checkFastEquivalWith : input mesh is null !"); - if(getMeshDimension()!=other->getMeshDimension()) - throw INTERP_KERNEL::Exception("checkFastEquivalWith : Mesh dimensions are not equal !"); - if(getSpaceDimension()!=other->getSpaceDimension()) - throw INTERP_KERNEL::Exception("checkFastEquivalWith : Space dimensions are not equal !"); - if(getNumberOfCells()!=other->getNumberOfCells()) - throw INTERP_KERNEL::Exception("checkFastEquivalWith : number of cells are not equal !"); -} - -/*! - * 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 -{ - if(!other) - throw INTERP_KERNEL::Exception("MEDCouplingMesh::areCompatibleForMerge : input mesh is null !"); - if(getMeshDimension()!=other->getMeshDimension()) - return false; - if(getSpaceDimension()!=other->getSpaceDimension()) - return false; - return true; -} - -/*! - * 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. - * \b WARNING , there is a big difference compared to MEDCouplingMesh::buildPart method. - * If the input range is equal all cells in \a this, \a this is returned ! - * - * \return a new ref to be managed by the caller. Warning this ref can be equal to \a this if input slice is exactly equal to the whole cells in the same order. - * - * \sa MEDCouplingMesh::buildPart - */ -MEDCouplingMesh *MEDCouplingMesh::buildPartRange(int beginCellIds, int endCellIds, int stepCellIds) const -{ - if(beginCellIds==0 && endCellIds==getNumberOfCells() && stepCellIds==1) - { - MEDCouplingMesh *ret(const_cast(this)); - ret->incrRef(); - return ret; - } - else - { - 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 -{ - 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 - * evaluate. - * Contrary to other fillFromAnalytic methods this method requests a C++ function pointer as input. - * 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. - */ -MEDCouplingFieldDouble *MEDCouplingMesh::fillFromAnalytic(TypeOfField t, int nbOfComp, FunctionToEvaluate func) const -{ - MEDCouplingAutoRefCountObjectPtr ret=MEDCouplingFieldDouble::New(t,ONE_TIME); - ret->setMesh(this); - ret->fillFromAnalytic(nbOfComp,func); - ret->synchronizeTimeWithSupport(); - return ret.retn(); -} - -/*! - * This method copyies all tiny strings from other (name and components name). - * @throw if other and this have not same mesh type. - */ -void MEDCouplingMesh::copyTinyStringsFrom(const MEDCouplingMesh *other) -{ - if(!other) - throw INTERP_KERNEL::Exception("MEDCouplingMesh::copyTinyStringsFrom : input mesh is null !"); - _name=other->_name; - _description=other->_description; - _time_unit=other->_time_unit; -} - -/*! - * This method copies all attributes that are \b NOT arrays in this. - * All tiny attributes not usefully for state of \a this are ignored. - */ -void MEDCouplingMesh::copyTinyInfoFrom(const MEDCouplingMesh *other) -{ - _time=other->_time; - _iteration=other->_iteration; - _order=other->_order; - copyTinyStringsFrom(other); -} - -/*! - * \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.) - * - * \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. - * - * \if ENABLE_EXAMPLES - * \ref cpp_mcmesh_fillFromAnalytic "Here is a C++ example".
- * \ref py_mcmesh_fillFromAnalytic "Here is a Python example". - * \endif - */ -MEDCouplingFieldDouble *MEDCouplingMesh::fillFromAnalytic(TypeOfField t, int nbOfComp, const std::string& func) const -{ - MEDCouplingAutoRefCountObjectPtr ret=MEDCouplingFieldDouble::New(t,ONE_TIME); - ret->setMesh(this); - ret->fillFromAnalytic(nbOfComp,func); - ret->synchronizeTimeWithSupport(); - return ret.retn(); -} - -/*! - * 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 std::string& 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 [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. - * - * \if ENABLE_EXAMPLES - * \ref cpp_mcmesh_fillFromAnalytic2 "Here is a C++ example".
- * \ref py_mcmesh_fillFromAnalytic2 "Here is a Python example". - * \endif - */ -MEDCouplingFieldDouble *MEDCouplingMesh::fillFromAnalytic2(TypeOfField t, int nbOfComp, const std::string& func) const -{ - MEDCouplingAutoRefCountObjectPtr ret=MEDCouplingFieldDouble::New(t,ONE_TIME); - ret->setMesh(this); - ret->fillFromAnalytic2(nbOfComp,func); - ret->synchronizeTimeWithSupport(); - return ret.retn(); -} - -/*! - * 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. - * - * \if ENABLE_EXAMPLES - * \ref cpp_mcmesh_fillFromAnalytic3 "Here is a C++ example".
- * \ref py_mcmesh_fillFromAnalytic3 "Here is a Python example". - * \endif - */ -MEDCouplingFieldDouble *MEDCouplingMesh::fillFromAnalytic3(TypeOfField t, int nbOfComp, const std::vector& varsOrder, const std::string& func) const -{ - MEDCouplingAutoRefCountObjectPtr ret=MEDCouplingFieldDouble::New(t,ONE_TIME); - ret->setMesh(this); - ret->fillFromAnalytic3(nbOfComp,varsOrder,func); - ret->synchronizeTimeWithSupport(); - return ret.retn(); -} - -/*! - * 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) -{ - if(!mesh1) - throw INTERP_KERNEL::Exception("MEDCouplingMesh::MergeMeshes : first parameter is an empty mesh !"); - if(!mesh2) - throw INTERP_KERNEL::Exception("MEDCouplingMesh::MergeMeshes : second parameter is an empty mesh !"); - return mesh1->mergeMyselfWith(mesh2); -} - -/*! - * 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) -{ - std::vector< MEDCouplingAutoRefCountObjectPtr > ms1(meshes.size()); - std::vector< const MEDCouplingUMesh * > ms2(meshes.size()); - for(std::size_t i=0;ibuildUnstructured(); - ms1[i]=cur; ms2[i]=cur; - } - else - { - std::ostringstream oss; oss << "MEDCouplingMesh::MergeMeshes(std::vector& meshes) : mesh at pos #" << i << " of input vector of size " << meshes.size() << " is empty !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - } - return MEDCouplingUMesh::MergeUMeshes(ms2); -} - -/*! - * For example if \a type is INTERP_KERNEL::NORM_TRI3 , INTERP_KERNEL::NORM_POLYGON is returned. - * If \a type is INTERP_KERNEL::NORM_HEXA8 , INTERP_KERNEL::NORM_POLYHED is returned. - * - * \param [in] type the geometric type for which the corresponding dynamic type, is asked. - * \return the corresponding dynamic type, able to store the input \a type. - * - * \throw if type is equal to \c INTERP_KERNEL::NORM_ERROR or to an unexisting geometric type. - */ -INTERP_KERNEL::NormalizedCellType MEDCouplingMesh::GetCorrespondingPolyType(INTERP_KERNEL::NormalizedCellType type) -{ - const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(type); - return cm.getCorrespondingPolyType(); -} - -/*! - * \param [in] type the geometric type for which the number of nodes consituting it, is asked. - * \return number of nodes consituting the input geometric type \a type. - * - * \throw if type is dynamic as \c INTERP_KERNEL::NORM_POLYHED , \c INTERP_KERNEL::NORM_POLYGON , \c INTERP_KERNEL::NORM_QPOLYG - * \throw if type is equal to \c INTERP_KERNEL::NORM_ERROR or to an unexisting geometric type. - */ -int MEDCouplingMesh::GetNumberOfNodesOfGeometricType(INTERP_KERNEL::NormalizedCellType type) -{ - const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(type); - if(cm.isDynamic()) - throw INTERP_KERNEL::Exception("MEDCouplingMesh::GetNumberOfNodesOfGeometricType : the input geometric type is dynamic ! Impossible to return a fixed number of nodes constituting it !"); - return (int) cm.getNumberOfNodes(); -} - -/*! - * \param [in] type the geometric type for which the status static/dynamic is asked. - * \return true for static geometric type, false for dynamic geometric type. - * - * \throw if type is equal to \c INTERP_KERNEL::NORM_ERROR or to an unexisting geometric type. - */ -bool MEDCouplingMesh::IsStaticGeometricType(INTERP_KERNEL::NormalizedCellType type) -{ - const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(type); - return !cm.isDynamic(); -} - -bool MEDCouplingMesh::IsLinearGeometricType(INTERP_KERNEL::NormalizedCellType type) -{ - const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(type); - return !cm.isQuadratic(); -} - -/*! - * \param [in] type the geometric type for which the dimension is asked. - * \return the dimension associated to the input geometric type \a type. - * - * \throw if type is equal to \c INTERP_KERNEL::NORM_ERROR or to an unexisting geometric type. - */ -int MEDCouplingMesh::GetDimensionOfGeometricType(INTERP_KERNEL::NormalizedCellType type) -{ - const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(type); - return (int) cm.getDimension(); -} - -/*! - * \param [in] type the geometric type for which the representation is asked. - * \return the string representation corresponding to the input geometric type \a type. - * - * \throw if type is equal to \c INTERP_KERNEL::NORM_ERROR or to an unexisting geometric type. - */ -const char *MEDCouplingMesh::GetReprOfGeometricType(INTERP_KERNEL::NormalizedCellType type) -{ - const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(type); - return cm.getRepr(); -} - -/*! - * Finds cells in contact with a ball (i.e. a point with precision). - * \warning This method is suitable if the caller intends to evaluate only one - * point, for more points getCellsContainingPoints() is recommended as it is - * faster. - * \param [in] pos - array of coordinates of the ball central point. - * \param [in] eps - ball radius. - * \param [in,out] elts - vector returning ids of the found cells. It is cleared - * before inserting ids. - * - * \if ENABLE_EXAMPLES - * \ref cpp_mcumesh_getCellsContainingPoint "Here is a C++ example".
- * \ref py_mcumesh_getCellsContainingPoint "Here is a Python example". - * \endif - */ -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 [out] elts - vector returning ids of found cells. - * \param [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* ]. - * - * \if ENABLE_EXAMPLES - * \ref cpp_mcumesh_getCellsContainingPoints "Here is a C++ example".
- * \ref py_mcumesh_getCellsContainingPoints "Here is a Python example". - * \endif - */ -void MEDCouplingMesh::getCellsContainingPoints(const double *pos, int nbOfPoints, double eps, MEDCouplingAutoRefCountObjectPtr& elts, MEDCouplingAutoRefCountObjectPtr& eltsIndex) const -{ - eltsIndex=DataArrayInt::New(); elts=DataArrayInt::New(); eltsIndex->alloc(nbOfPoints+1,1); eltsIndex->setIJ(0,0,0); elts->alloc(0,1); - int *eltsIndexPtr(eltsIndex->getPointer()); - int spaceDim(getSpaceDimension()); - const double *work(pos); - for(int i=0;i=0) - { - elts->pushBackSilent(ret); - eltsIndexPtr[i+1]=eltsIndexPtr[i]+1; - } - else - eltsIndexPtr[i+1]=eltsIndexPtr[i]; - } -} - -/*! - * Writes \a this mesh into a VTK format file named as specified. - * \param [in] fileName - the name of the file to write in. If the extension is OK the fileName will be used directly. - * If extension is invalid or no extension the right extension will be appended. - * \return - the real fileName - * \throw If \a fileName is not a writable file. - * \sa getVTKFileNameOf - */ -std::string MEDCouplingMesh::writeVTK(const std::string& fileName, bool isBinary) const -{ - std::string ret(getVTKFileNameOf(fileName)); - // - std::string cda,pda; - MEDCouplingAutoRefCountObjectPtr byteArr; - if(isBinary) - { byteArr=DataArrayByte::New(); byteArr->alloc(0,1); } - writeVTKAdvanced(ret,cda,pda,byteArr); - return ret; -} - -/*! - * This method takes in input a file name \a fileName and considering the VTK extension of \a this (depending on the type of \a this) - * returns a right file name. If the input \a fileName has a valid extension the returned string is equal to \a fileName. - * - * \sa getVTKFileExtension - */ -std::string MEDCouplingMesh::getVTKFileNameOf(const std::string& fileName) const -{ - std::string ret; - std::string part0,part1; - SplitExtension(fileName,part0,part1); - std::string ext("."); ext+=getVTKFileExtension(); - if(part1==ext) - ret=fileName; - else - ret=fileName+ext; - return ret; -} - -void MEDCouplingMesh::writeVTKAdvanced(const std::string& fileName, const std::string& cda, const std::string& pda, DataArrayByte *byteData) const -{ - std::ofstream ofs(fileName.c_str()); - ofs << "\n"; - writeVTKLL(ofs,cda,pda,byteData); - if(byteData) - { - ofs << "\n_1234"; - ofs << std::flush; ofs.close(); - std::ofstream ofs2(fileName.c_str(),std::ios_base::binary | std::ios_base::app); - ofs2.write(byteData->begin(),byteData->getNbOfElems()); ofs2 << std::flush; ofs2.close(); - std::ofstream ofs3(fileName.c_str(),std::ios_base::app); ofs3 << "\n\n\n"; ofs3.close(); - } - else - { - ofs << "\n"; - ofs.close(); - } -} - -void MEDCouplingMesh::SplitExtension(const std::string& fileName, std::string& baseName, std::string& extension) -{ - std::size_t pos(fileName.find_last_of('.')); - if(pos==std::string::npos) - { - baseName=fileName; - extension.clear(); - return ; - } - baseName=fileName.substr(0,pos); - extension=fileName.substr(pos); -} diff --git a/src/MEDCoupling/MEDCouplingMesh.hxx b/src/MEDCoupling/MEDCouplingMesh.hxx deleted file mode 100644 index b4a20e705..000000000 --- a/src/MEDCoupling/MEDCouplingMesh.hxx +++ /dev/null @@ -1,172 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 -// 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_MEDCOUPLINGMESH_HXX__ -#define __PARAMEDMEM_MEDCOUPLINGMESH_HXX__ - -#include "MEDCoupling.hxx" -#include "MEDCouplingTimeLabel.hxx" -#include "MEDCouplingRefCountObject.hxx" -#include "NormalizedUnstructuredMesh.hxx" -#include "MEDCouplingAutoRefCountObjectPtr.hxx" - -#include "InterpKernelException.hxx" - -#include -#include - -namespace ParaMEDMEM -{ - typedef enum - { - UNSTRUCTURED = 5, - CARTESIAN = 7, - EXTRUDED = 8, - CURVE_LINEAR = 9, - SINGLE_STATIC_GEO_TYPE_UNSTRUCTURED = 10, - SINGLE_DYNAMIC_GEO_TYPE_UNSTRUCTURED = 11, - IMAGE_GRID = 12 - } MEDCouplingMeshType; - // -- WARNING this enum must be synchronized with MEDCouplingCommon.i file ! -- - - class DataArrayInt; - class DataArrayByte; - class DataArrayDouble; - class MEDCouplingUMesh; - class MEDCouplingFieldDouble; - - class MEDCouplingMesh : public RefCountObject, public TimeLabel - { - public: - MEDCOUPLING_EXPORT std::size_t getHeapMemorySizeWithoutChildren() const; - MEDCOUPLING_EXPORT void setName(const std::string& name) { _name=name; } - MEDCOUPLING_EXPORT std::string getName() const { return _name; } - MEDCOUPLING_EXPORT void setDescription(const std::string& descr) { _description=descr; } - MEDCOUPLING_EXPORT std::string getDescription() const { return _description; } - MEDCOUPLING_EXPORT double getTime(int& iteration, int& order) const { iteration=_iteration; order=_order; return _time; } - MEDCOUPLING_EXPORT void setTime(double val, int iteration, int order) { _time=val; _iteration=iteration; _order=order; } - MEDCOUPLING_EXPORT void setTimeUnit(const std::string& unit) { _time_unit=unit; } - MEDCOUPLING_EXPORT std::string getTimeUnit() const { return _time_unit; } - MEDCOUPLING_EXPORT virtual MEDCouplingMesh *deepCpy() const = 0; - MEDCOUPLING_EXPORT virtual MEDCouplingMeshType getType() const = 0; - MEDCOUPLING_EXPORT bool isStructured() const; - MEDCOUPLING_EXPORT virtual void copyTinyStringsFrom(const MEDCouplingMesh *other); - MEDCOUPLING_EXPORT virtual void copyTinyInfoFrom(const MEDCouplingMesh *other); - // comparison methods - MEDCOUPLING_EXPORT virtual bool isEqualIfNotWhy(const MEDCouplingMesh *other, double prec, std::string& reason) const; - MEDCOUPLING_EXPORT virtual bool isEqual(const MEDCouplingMesh *other, double prec) const; - MEDCOUPLING_EXPORT virtual bool isEqualWithoutConsideringStr(const MEDCouplingMesh *other, double prec) const = 0; - MEDCOUPLING_EXPORT virtual void checkDeepEquivalWith(const MEDCouplingMesh *other, int cellCompPol, double prec, - DataArrayInt *&cellCor, DataArrayInt *&nodeCor) const = 0; - MEDCOUPLING_EXPORT virtual void checkDeepEquivalOnSameNodesWith(const MEDCouplingMesh *other, int cellCompPol, double prec, - DataArrayInt *&cellCor) const = 0; - MEDCOUPLING_EXPORT virtual void checkFastEquivalWith(const MEDCouplingMesh *other, double prec) const; - MEDCOUPLING_EXPORT void checkGeoEquivalWith(const MEDCouplingMesh *other, int levOfCheck, double prec, - DataArrayInt *&cellCor, DataArrayInt *&nodeCor) const; - // - MEDCOUPLING_EXPORT virtual void checkCoherency() const = 0; - MEDCOUPLING_EXPORT virtual void checkCoherency1(double eps=1e-12) const = 0; - MEDCOUPLING_EXPORT virtual void checkCoherency2(double eps=1e-12) const = 0; - MEDCOUPLING_EXPORT virtual int getNumberOfCells() const = 0; - MEDCOUPLING_EXPORT virtual int getNumberOfNodes() const = 0; - MEDCOUPLING_EXPORT virtual int getSpaceDimension() const = 0; - MEDCOUPLING_EXPORT virtual int getMeshDimension() const = 0; - MEDCOUPLING_EXPORT virtual DataArrayDouble *getCoordinatesAndOwner() const = 0; - MEDCOUPLING_EXPORT virtual DataArrayDouble *getBarycenterAndOwner() const = 0; - MEDCOUPLING_EXPORT virtual DataArrayDouble *computeIsoBarycenterOfNodesPerCell() const = 0; - MEDCOUPLING_EXPORT virtual DataArrayInt *giveCellsWithType(INTERP_KERNEL::NormalizedCellType type) const = 0; - MEDCOUPLING_EXPORT virtual DataArrayInt *computeNbOfNodesPerCell() const = 0; - MEDCOUPLING_EXPORT virtual DataArrayInt *computeEffectiveNbOfNodesPerCell() const = 0; - MEDCOUPLING_EXPORT virtual DataArrayInt *computeNbOfFacesPerCell() const = 0; - MEDCOUPLING_EXPORT virtual int getNumberOfCellsWithType(INTERP_KERNEL::NormalizedCellType type) const = 0; - MEDCOUPLING_EXPORT virtual INTERP_KERNEL::NormalizedCellType getTypeOfCell(int cellId) const = 0; - MEDCOUPLING_EXPORT virtual std::set getAllGeoTypes() const = 0; - MEDCOUPLING_EXPORT virtual void getNodeIdsOfCell(int cellId, std::vector& conn) const = 0; - MEDCOUPLING_EXPORT virtual DataArrayInt *getCellIdsFullyIncludedInNodeIds(const int *partBg, const int *partEnd) const; - MEDCOUPLING_EXPORT virtual void getCoordinatesOfNode(int nodeId, std::vector& coo) const = 0; - MEDCOUPLING_EXPORT virtual std::string simpleRepr() const = 0; - MEDCOUPLING_EXPORT virtual std::string advancedRepr() const = 0; - // tools - MEDCOUPLING_EXPORT virtual std::vector getDistributionOfTypes() const = 0; - MEDCOUPLING_EXPORT virtual DataArrayInt *checkTypeConsistencyAndContig(const std::vector& code, const std::vector& idsPerType) const = 0; - MEDCOUPLING_EXPORT virtual void splitProfilePerType(const DataArrayInt *profile, std::vector& code, std::vector& idsInPflPerType, std::vector& idsPerType) const = 0; - MEDCOUPLING_EXPORT virtual void getBoundingBox(double *bbox) const = 0; - MEDCOUPLING_EXPORT virtual MEDCouplingFieldDouble *getMeasureField(bool isAbs) const = 0; - MEDCOUPLING_EXPORT virtual MEDCouplingFieldDouble *getMeasureFieldOnNode(bool isAbs) const = 0; - MEDCOUPLING_EXPORT virtual int getCellContainingPoint(const double *pos, double eps) const = 0; - MEDCOUPLING_EXPORT virtual void getCellsContainingPoint(const double *pos, double eps, std::vector& elts) const; - MEDCOUPLING_EXPORT virtual void getCellsContainingPoints(const double *pos, int nbOfPoints, double eps, MEDCouplingAutoRefCountObjectPtr& elts, MEDCouplingAutoRefCountObjectPtr& eltsIndex) const; - MEDCOUPLING_EXPORT virtual MEDCouplingFieldDouble *fillFromAnalytic(TypeOfField t, int nbOfComp, FunctionToEvaluate func) const; - MEDCOUPLING_EXPORT virtual MEDCouplingFieldDouble *fillFromAnalytic(TypeOfField t, int nbOfComp, const std::string& func) const; - MEDCOUPLING_EXPORT virtual MEDCouplingFieldDouble *fillFromAnalytic2(TypeOfField t, int nbOfComp, const std::string& func) const; - MEDCOUPLING_EXPORT virtual MEDCouplingFieldDouble *fillFromAnalytic3(TypeOfField t, int nbOfComp, const std::vector& varsOrder, const std::string& func) const; - MEDCOUPLING_EXPORT virtual MEDCouplingFieldDouble *buildOrthogonalField() const = 0; - MEDCOUPLING_EXPORT virtual void rotate(const double *center, const double *vector, double angle) = 0; - MEDCOUPLING_EXPORT virtual void translate(const double *vector) = 0; - MEDCOUPLING_EXPORT virtual void scale(const double *point, double factor) = 0; - MEDCOUPLING_EXPORT virtual void renumberCells(const int *old2NewBg, bool check=true) = 0; - MEDCOUPLING_EXPORT virtual MEDCouplingMesh *mergeMyselfWith(const MEDCouplingMesh *other) const = 0; - MEDCOUPLING_EXPORT virtual MEDCouplingMesh *buildPart(const int *start, const int *end) const = 0; - MEDCOUPLING_EXPORT virtual MEDCouplingMesh *buildPartAndReduceNodes(const int *start, const int *end, DataArrayInt*& arr) const = 0; - MEDCOUPLING_EXPORT virtual MEDCouplingMesh *buildPartRange(int beginCellIds, int endCellIds, int stepCellIds) const; - MEDCOUPLING_EXPORT virtual MEDCouplingMesh *buildPartRangeAndReduceNodes(int beginCellIds, int endCellIds, int stepCellIds, int& beginOut, int& endOut, int& stepOut, DataArrayInt*& arr) const; - MEDCOUPLING_EXPORT virtual MEDCouplingUMesh *buildUnstructured() const = 0; - MEDCOUPLING_EXPORT virtual DataArrayInt *simplexize(int policy) = 0; - MEDCOUPLING_EXPORT virtual void getReverseNodalConnectivity(DataArrayInt *revNodal, DataArrayInt *revNodalIndx) const = 0; - MEDCOUPLING_EXPORT virtual bool areCompatibleForMerge(const MEDCouplingMesh *other) const; - MEDCOUPLING_EXPORT static MEDCouplingMesh *MergeMeshes(const MEDCouplingMesh *mesh1, const MEDCouplingMesh *mesh2); - MEDCOUPLING_EXPORT static MEDCouplingMesh *MergeMeshes(std::vector& meshes); - MEDCOUPLING_EXPORT static bool IsStaticGeometricType(INTERP_KERNEL::NormalizedCellType type); - MEDCOUPLING_EXPORT static bool IsLinearGeometricType(INTERP_KERNEL::NormalizedCellType type); - MEDCOUPLING_EXPORT static INTERP_KERNEL::NormalizedCellType GetCorrespondingPolyType(INTERP_KERNEL::NormalizedCellType type); - MEDCOUPLING_EXPORT static int GetNumberOfNodesOfGeometricType(INTERP_KERNEL::NormalizedCellType type); - MEDCOUPLING_EXPORT static int GetDimensionOfGeometricType(INTERP_KERNEL::NormalizedCellType type); - MEDCOUPLING_EXPORT static const char *GetReprOfGeometricType(INTERP_KERNEL::NormalizedCellType type); - //serialisation-unserialization - MEDCOUPLING_EXPORT virtual void getTinySerializationInformation(std::vector& tinyInfoD, std::vector& tinyInfo, std::vector& littleStrings) const = 0; - MEDCOUPLING_EXPORT virtual void resizeForUnserialization(const std::vector& tinyInfo, DataArrayInt *a1, DataArrayDouble *a2, std::vector& littleStrings) const = 0; - MEDCOUPLING_EXPORT virtual void serialize(DataArrayInt *&a1, DataArrayDouble *&a2) const = 0; - MEDCOUPLING_EXPORT virtual void unserialization(const std::vector& tinyInfoD, const std::vector& tinyInfo, const DataArrayInt *a1, DataArrayDouble *a2, - const std::vector& littleStrings) = 0; - MEDCOUPLING_EXPORT std::string writeVTK(const std::string& fileName, bool isBinary=true) const; - MEDCOUPLING_EXPORT std::string getVTKFileNameOf(const std::string& fileName) const; - MEDCOUPLING_EXPORT virtual std::string getVTKFileExtension() const = 0; - /// @cond INTERNAL - MEDCOUPLING_EXPORT void writeVTKAdvanced(const std::string& fileName, const std::string& cda, const std::string& pda, DataArrayByte *byteData) const; - MEDCOUPLING_EXPORT static void SplitExtension(const std::string& fileName, std::string& baseName, std::string& extension); - /// @endcond - MEDCOUPLING_EXPORT virtual void writeVTKLL(std::ostream& ofs, const std::string& cellData, const std::string& pointData, DataArrayByte *byteData) const = 0; - MEDCOUPLING_EXPORT virtual void reprQuickOverview(std::ostream& stream) const = 0; - protected: - MEDCOUPLING_EXPORT MEDCouplingMesh(); - MEDCOUPLING_EXPORT MEDCouplingMesh(const MEDCouplingMesh& other); - MEDCOUPLING_EXPORT virtual std::string getVTKDataSetType() const = 0; - MEDCOUPLING_EXPORT virtual ~MEDCouplingMesh() { } - private: - std::string _name; - std::string _description; - double _time; - int _iteration; - int _order; - std::string _time_unit; - }; -} - -#endif diff --git a/src/MEDCoupling/MEDCouplingMultiFields.cxx b/src/MEDCoupling/MEDCouplingMultiFields.cxx deleted file mode 100644 index f493405d8..000000000 --- a/src/MEDCoupling/MEDCouplingMultiFields.cxx +++ /dev/null @@ -1,460 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 -// 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 "MEDCouplingMultiFields.hxx" -#include "MEDCouplingFieldTemplate.hxx" -#include "MEDCouplingFieldDouble.hxx" -#include "MEDCouplingMesh.hxx" -#include "MEDCouplingAutoRefCountObjectPtr.hxx" - -#include -#include - -using namespace ParaMEDMEM; - -MEDCouplingMultiFields *MEDCouplingMultiFields::New(const std::vector& fs) -{ - return new MEDCouplingMultiFields(fs); -} - -MEDCouplingMultiFields *MEDCouplingMultiFields::New() -{ - return new MEDCouplingMultiFields; -} - -MEDCouplingMultiFields *MEDCouplingMultiFields::deepCpy() const -{ - return new MEDCouplingMultiFields(*this); -} - -bool MEDCouplingMultiFields::isEqual(const MEDCouplingMultiFields *other, double meshPrec, double valsPrec) const -{ - std::size_t sz=_fs.size(); - if(sz!=other->_fs.size()) - return false; - for(std::size_t i=0;i_fs[i]; - if(f1!=f2) - { - if(f1==0 || f2==0) - return false; - if(!_fs[i]->isEqual(other->_fs[i],meshPrec,valsPrec)) - return false; - } - } - std::vector refs1,refs2; - std::vector ms1=getDifferentMeshes(refs1); - std::vector ms2=other->getDifferentMeshes(refs2); - if(ms1.size()!=ms2.size()) - return false; - if(refs1!=refs2) - return false; - std::vector< std::vector > refs3,refs4; - std::vector das1=getDifferentArrays(refs3); - std::vector das2=getDifferentArrays(refs4); - if(das1.size()!=das2.size()) - return false; - if(refs3!=refs4) - return false; - return true; -} - -std::string MEDCouplingMultiFields::getName() const -{ - std::vector< MEDCouplingAutoRefCountObjectPtr >::const_iterator it=_fs.begin(); - for(;it!=_fs.end();it++) - if((const MEDCouplingFieldDouble *)(*it)) - return (*it)->getName(); - return std::string(); -} - -std::string MEDCouplingMultiFields::getDescription() const -{ - std::vector< MEDCouplingAutoRefCountObjectPtr >::const_iterator it=_fs.begin(); - for(;it!=_fs.end();it++) - if((const MEDCouplingFieldDouble *)(*it)) - return (*it)->getDescription(); - return std::string(); -} - -std::string MEDCouplingMultiFields::getTimeUnit() const -{ - std::vector< MEDCouplingAutoRefCountObjectPtr >::const_iterator it=_fs.begin(); - for(;it!=_fs.end();it++) - if((const MEDCouplingFieldDouble *)(*it)) - return (*it)->getTimeUnit(); - return std::string(); -} - -double MEDCouplingMultiFields::getTimeResolution() const -{ - std::vector< MEDCouplingAutoRefCountObjectPtr >::const_iterator it=_fs.begin(); - for(;it!=_fs.end();it++) - if((const MEDCouplingFieldDouble *)(*it)) - return (*it)->getTimeTolerance(); - throw INTERP_KERNEL::Exception("MEDCouplingMultiFields::getTimeResolution : no not null field !"); -} - -std::string MEDCouplingMultiFields::simpleRepr() const -{ - std::ostringstream ret; - ret << "MEDCouplingMultiFields with name : \"" << getName() << "\"\n"; - ret << "Description of MEDCouplingMultiFields is : \"" << getDescription() << "\"\n"; - ret << "Number of discretization : " << _fs.size() << "\n"; - ret << "Number of different meshes : "; - std::vector ms; - std::vector refms; - try - { - ms=getDifferentMeshes(refms); - ret << ms.size() << "\n"; - } - catch(INTERP_KERNEL::Exception& /*e*/) - { ret << "Current instance is INVALID !\n"; } - return ret.str(); -} - -std::string MEDCouplingMultiFields::advancedRepr() const -{ - return simpleRepr(); -} - -bool MEDCouplingMultiFields::isEqualWithoutConsideringStr(const MEDCouplingMultiFields *other, double meshPrec, double valsPrec) const -{ - std::size_t sz=_fs.size(); - if(sz!=other->_fs.size()) - return false; - for(std::size_t i=0;iisEqualWithoutConsideringStr(other->_fs[i],meshPrec,valsPrec)) - return false; - return true; -} - -const MEDCouplingFieldDouble *MEDCouplingMultiFields::getFieldWithId(int id) const -{ - if(id>=(int)_fs.size() || id < 0) - throw INTERP_KERNEL::Exception("MEDCouplingMultiFields::getFieldWithId : invalid id outside boundaries !"); - return _fs[id]; -} - -std::vector MEDCouplingMultiFields::getFields() const -{ - std::vector ret(_fs.size()); - std::copy(_fs.begin(),_fs.end(),ret.begin()); - return ret; -} - -int MEDCouplingMultiFields::getNumberOfFields() const -{ - return (int)_fs.size(); -} - -const MEDCouplingFieldDouble *MEDCouplingMultiFields::getFieldAtPos(int id) const -{ - if(id<0 || id>=(int)_fs.size()) - { - std::ostringstream oss; oss << "MEDCouplingMultiFields::getFieldAtPos : Invalid given pos : should be >=0 and < " << _fs.size() << " !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - return _fs[id]; -} - -void MEDCouplingMultiFields::updateTime() const -{ - std::vector< MEDCouplingAutoRefCountObjectPtr >::const_iterator it=_fs.begin(); - for(;it!=_fs.end();it++) - if((const MEDCouplingFieldDouble *)(*it)) - (*it)->updateTime(); - it=_fs.begin(); - for(;it!=_fs.end();it++) - if((const MEDCouplingFieldDouble *)(*it)) - updateTimeWith(*(*it)); -} - -std::size_t MEDCouplingMultiFields::getHeapMemorySizeWithoutChildren() const -{ - return 0; -} - -std::vector MEDCouplingMultiFields::getDirectChildrenWithNull() const -{ - std::vector ret; - for(std::vector< MEDCouplingAutoRefCountObjectPtr >::const_iterator it=_fs.begin();it!=_fs.end();it++) - ret.push_back((const MEDCouplingFieldDouble *)*it); - return ret; -} - -std::vector MEDCouplingMultiFields::getMeshes() const -{ - std::vector ms; - for(std::vector< MEDCouplingAutoRefCountObjectPtr >::const_iterator it=_fs.begin();it!=_fs.end();it++) - { - const MEDCouplingMesh *m=0; - if((const MEDCouplingFieldDouble *)(*it)) - m=(*it)->getMesh(); - ms.push_back(const_cast(m)); - } - return ms; -} - -std::vector MEDCouplingMultiFields::getDifferentMeshes(std::vector& refs) const -{ - refs.resize(_fs.size()); - std::vector ms; - int id=0; - for(std::vector< MEDCouplingAutoRefCountObjectPtr >::const_iterator it=_fs.begin();it!=_fs.end();it++,id++) - { - const MEDCouplingMesh *m=0; - if((const MEDCouplingFieldDouble *)(*it)) - m=(*it)->getMesh(); - if(m) - { - std::vector::iterator it2=std::find(ms.begin(),ms.end(),m); - if(it2==ms.end()) - { - ms.push_back(const_cast(m)); - refs[id]=(int)ms.size()-1; - } - else - refs[id]=(int)std::distance(ms.begin(),it2); - } - else - refs[id]=-1; - } - return ms; -} - -std::vector MEDCouplingMultiFields::getArrays() const -{ - std::vector tmp; - for(std::vector< MEDCouplingAutoRefCountObjectPtr >::const_iterator it=_fs.begin();it!=_fs.end();it++) - { - std::vector tmp2=(*it)->getArrays(); - tmp.insert(tmp.end(),tmp2.begin(),tmp2.end()); - } - return tmp; -} - -std::vector MEDCouplingMultiFields::getDifferentArrays(std::vector< std::vector >& refs) const -{ - refs.resize(_fs.size()); - int id=0; - std::vector ret; - for(std::vector< MEDCouplingAutoRefCountObjectPtr >::const_iterator it=_fs.begin();it!=_fs.end();it++,id++) - { - std::vector tmp2; - if((const MEDCouplingFieldDouble *)(*it)) - { - tmp2=(*it)->getArrays(); - refs[id].resize(tmp2.size()); - } - else - refs[id].clear(); - int id2=0; - for(std::vector::const_iterator it2=tmp2.begin();it2!=tmp2.end();it2++,id2++) - { - if(*it2) - { - std::vector::iterator it3=std::find(ret.begin(),ret.end(),*it2); - if(it3==ret.end()) - { - ret.push_back(*it2); - refs[id][id2]=(int)ret.size()-1; - } - else - refs[id][id2]=(int)std::distance(ret.begin(),it3); - } - else - refs[id][id2]=-1; - } - } - return ret; -} - -void MEDCouplingMultiFields::checkCoherency() const -{ - std::vector< MEDCouplingAutoRefCountObjectPtr >::const_iterator it=_fs.begin(); - for(;it!=_fs.end();it++) - { - if((const MEDCouplingFieldDouble *)(*it)==0) - throw INTERP_KERNEL::Exception("MEDCouplingMultiFields::checkCoherency : There is an empty Field in array..."); - (*it)->checkCoherency(); - } -} - -MEDCouplingMultiFields::MEDCouplingMultiFields(const std::vector& fs):_fs(fs.size()) -{ - int id=0; - for(std::vector< MEDCouplingFieldDouble * >::const_iterator it=fs.begin();it!=fs.end();it++,id++) - { - if(*it) - (*it)->incrRef(); - else - throw INTERP_KERNEL::Exception("MEDCouplingMultiFields constructor : empty field found in vector !"); - (*it)->checkCoherency(); - _fs[id]=*it; - } -} - - -/*! - * Performs deepCpy. - */ -MEDCouplingMultiFields::MEDCouplingMultiFields(const MEDCouplingMultiFields& other):RefCountObject(other) -{ - std::size_t sz=other._fs.size(); - _fs.resize(sz); - std::vector refs; - std::vector< std::vector > refs2; - std::vector ms=other.getDifferentMeshes(refs); - std::size_t msLgh=ms.size(); - std::vector< MEDCouplingAutoRefCountObjectPtr > ms2(msLgh); - for(std::size_t i=0;ideepCpy(); - std::vector das=other.getDifferentArrays(refs2); - std::size_t dasLgth=das.size(); - std::vector< MEDCouplingAutoRefCountObjectPtr > das2(dasLgth); - for(std::size_t i=0;ideepCpy(); - for(std::size_t i=0;igetTimeDiscretization()); - tmp->decrRef(); - if(refs[i]!=-1) - _fs[i]->setMesh(ms2[refs[i]]); - std::size_t nbOfArr=refs2[i].size(); - std::vector tmp2(nbOfArr); - for(std::size_t j=0;jsetArrays(tmp2); - std::vector tinyInfo; - std::vector tinyInfo2; - other._fs[i]->getTimeDiscretizationUnderGround()->getTinySerializationIntInformation2(tinyInfo); - other._fs[i]->getTimeDiscretizationUnderGround()->getTinySerializationDbleInformation2(tinyInfo2); - _fs[i]->getTimeDiscretizationUnderGround()->finishUnserialization2(tinyInfo,tinyInfo2); - } - } -} - -MEDCouplingMultiFields::MEDCouplingMultiFields() -{ -} - -void MEDCouplingMultiFields::getTinySerializationInformation(std::vector& tinyInfo, std::vector& tinyInfo2, int& nbOfDiffMeshes, int& nbOfDiffArr) const -{ - std::vector refs; - std::vector ms=getDifferentMeshes(refs); - nbOfDiffMeshes=(int)ms.size(); - std::vector< std::vector > refs2; - std::vector fs=getDifferentArrays(refs2); - nbOfDiffArr=(int)fs.size(); - // - std::size_t sz=refs.size();//==_fs.size() - int sz2=0; - for(std::size_t i=0;i doubleDaInd(sz); - std::vector timeDiscrInt; - tinyInfo.resize(sz2+5*sz+3); - tinyInfo[0]=(int)sz; - tinyInfo[1]=sz2; - for(std::size_t i=0;i tmp; - std::vector tmp2; - _fs[i]->getTimeDiscretizationUnderGround()->getTinySerializationDbleInformation2(tmp); - _fs[i]->getTimeDiscretizationUnderGround()->getTinySerializationIntInformation2(tmp2); - tinyInfo[3*sz+3+i]=(int)tmp.size(); - tinyInfo[4*sz+3+i]=(int)tmp2.size(); - tinyInfo2.insert(tinyInfo2.end(),tmp.begin(),tmp.end()); - timeDiscrInt.insert(timeDiscrInt.end(),tmp2.begin(),tmp2.end()); - } - int sz3=(int)timeDiscrInt.size(); - tinyInfo[2]=sz3; - // - for(std::size_t i=0;igetTimeDiscretization(); - int k=0; - for(std::size_t i=0;i::const_iterator it=refs2[i].begin();it!=refs2[i].end();it++,k++) - tinyInfo[5*sz+k+3]=*it; - tinyInfo.insert(tinyInfo.end(),timeDiscrInt.begin(),timeDiscrInt.end());//tinyInfo has lgth==sz3+sz2+5*sz+3 -} - -void MEDCouplingMultiFields::finishUnserialization(const std::vector& tinyInfoI, const std::vector& tinyInfoD, - const std::vector& ft, const std::vector& ms, - const std::vector& das) -{ - int sz=tinyInfoI[0]; - _fs.resize(sz); - int sz2=tinyInfoI[1]; - // dealing with ft with no mesh set. - for(int i=0;isetMesh(ms[meshId]); - } - // dealing with fieldtemplate->fielddouble - int k=0; - int offI=0; - int offD=0; - for(int i=0;i tmp(sz3); - for(int j=0;jsetArrays(tmp); - // time discr tiny info - int lgthI=tinyInfoI[4*sz+3+i]; - int lgthD=tinyInfoI[3*sz+3+i]; - // - std::vector tdInfoI(tinyInfoI.begin()+sz2+5*sz+3+offI,tinyInfoI.begin()+sz2+5*sz+3+offI+lgthI); - std::vector tdInfoD(tinyInfoD.begin()+offD,tinyInfoD.begin()+offD+lgthD); - _fs[i]->getTimeDiscretizationUnderGround()->finishUnserialization2(tdInfoI,tdInfoD); - // - offI+=lgthI; - offD+=lgthD; - } -} diff --git a/src/MEDCoupling/MEDCouplingMultiFields.hxx b/src/MEDCoupling/MEDCouplingMultiFields.hxx deleted file mode 100644 index b092bc60d..000000000 --- a/src/MEDCoupling/MEDCouplingMultiFields.hxx +++ /dev/null @@ -1,79 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 -// 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_MEDCOUPLINGMULTIFIELDS_HXX__ -#define __PARAMEDMEM_MEDCOUPLINGMULTIFIELDS_HXX__ - -#include "MEDCouplingRefCountObject.hxx" -#include "MEDCouplingTimeLabel.hxx" -#include "MEDCouplingAutoRefCountObjectPtr.hxx" - -#include "InterpKernelException.hxx" - -#include - -namespace ParaMEDMEM -{ - class MEDCouplingMesh; - class DataArrayDouble; - class MEDCouplingFieldDouble; - class MEDCouplingFieldTemplate; - - class MEDCouplingMultiFields : public RefCountObject, public TimeLabel - { - public: - MEDCOUPLING_EXPORT static MEDCouplingMultiFields *New(const std::vector& fs); - MEDCOUPLING_EXPORT static MEDCouplingMultiFields *New(); - MEDCOUPLING_EXPORT MEDCouplingMultiFields *deepCpy() const; - MEDCOUPLING_EXPORT std::string getName() const; - MEDCOUPLING_EXPORT std::string getDescription() const; - MEDCOUPLING_EXPORT std::string getTimeUnit() const; - MEDCOUPLING_EXPORT double getTimeResolution() const; - MEDCOUPLING_EXPORT virtual std::string simpleRepr() const; - MEDCOUPLING_EXPORT virtual std::string advancedRepr() const; - MEDCOUPLING_EXPORT virtual bool isEqual(const MEDCouplingMultiFields *other, double meshPrec, double valsPrec) const; - MEDCOUPLING_EXPORT virtual bool isEqualWithoutConsideringStr(const MEDCouplingMultiFields *other, double meshPrec, double valsPrec) const; - MEDCOUPLING_EXPORT const MEDCouplingFieldDouble *getFieldWithId(int id) const; - MEDCOUPLING_EXPORT std::vector getFields() const; - MEDCOUPLING_EXPORT int getNumberOfFields() const; - MEDCOUPLING_EXPORT const MEDCouplingFieldDouble *getFieldAtPos(int id) const; - MEDCOUPLING_EXPORT virtual std::vector getMeshes() const; - MEDCOUPLING_EXPORT virtual std::vector getDifferentMeshes(std::vector& refs) const; - MEDCOUPLING_EXPORT virtual std::vector getArrays() const; - MEDCOUPLING_EXPORT virtual std::vector getDifferentArrays(std::vector< std::vector >& refs) const; - MEDCOUPLING_EXPORT void updateTime() const; - MEDCOUPLING_EXPORT std::size_t getHeapMemorySizeWithoutChildren() const; - MEDCOUPLING_EXPORT std::vector getDirectChildrenWithNull() const; - MEDCOUPLING_EXPORT void getTinySerializationInformation(std::vector& tinyInfo, std::vector& tinyInfo2, int& nbOfDiffMeshes, int& nbOfDiffArr) const; - MEDCOUPLING_EXPORT void finishUnserialization(const std::vector& tinyInfoI, const std::vector& tinyInfoD, - const std::vector& ft, const std::vector& ms, - const std::vector& das); - MEDCOUPLING_EXPORT virtual void checkCoherency() const; - protected: - MEDCOUPLING_EXPORT MEDCouplingMultiFields(const std::vector& fs); - MEDCOUPLING_EXPORT MEDCouplingMultiFields(const MEDCouplingMultiFields& other); - MEDCOUPLING_EXPORT MEDCouplingMultiFields(); - protected: - std::vector< MEDCouplingAutoRefCountObjectPtr > _fs; - }; -} - -#endif - diff --git a/src/MEDCoupling/MEDCouplingNatureOfField.cxx b/src/MEDCoupling/MEDCouplingNatureOfField.cxx deleted file mode 100644 index 26f05c670..000000000 --- a/src/MEDCoupling/MEDCouplingNatureOfField.cxx +++ /dev/null @@ -1,70 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 -// 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 "MEDCouplingNatureOfField.hxx" - -#include -#include - -namespace ParaMEDMEM -{ - const char *MEDCouplingNatureOfField::REPR_OF_NATUREOFFIELD[NB_OF_POSSIBILITIES]= - { "NoNature", - "ConservativeVolumic", - "Integral", - "IntegralGlobConstraint", - "RevIntegral"}; - - const int MEDCouplingNatureOfField::POS_OF_NATUREOFFIELD[NB_OF_POSSIBILITIES]={17,26,32,35,37}; - - const char *MEDCouplingNatureOfField::GetRepr(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) - { - 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 -class MEDCouplingNormalizedCartesianMesh -{ -public: - static const int MY_SPACEDIM=SPACEDIM; - static const int MY_MESHDIM=SPACEDIM; - typedef int MyConnType; - static const INTERP_KERNEL::NumberingPolicy My_numPol=INTERP_KERNEL::ALL_C_MODE; -public: - MEDCouplingNormalizedCartesianMesh(const ParaMEDMEM::MEDCouplingCMesh *mesh); - //void getBoundingBox(double *boundingBox) const; - //INTERP_KERNEL::NormalizedCellType getTypeOfElement(int eltId) const; - //int getNumberOfNodesOfElement(int eltId) const; - //int getNumberOfNodes() const; - unsigned long getNumberOfElements() const; - unsigned long nbCellsAlongAxis(int axis) const; - const double * getCoordsAlongAxis(int axis) const; - ~MEDCouplingNormalizedCartesianMesh(); -private: - const ParaMEDMEM::MEDCouplingCMesh *_mesh; -}; - -#endif diff --git a/src/MEDCoupling/MEDCouplingNormalizedCartesianMesh.txx b/src/MEDCoupling/MEDCouplingNormalizedCartesianMesh.txx deleted file mode 100644 index 2fe1f85c1..000000000 --- a/src/MEDCoupling/MEDCouplingNormalizedCartesianMesh.txx +++ /dev/null @@ -1,57 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 -// 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 -// -// File : MEDCouplingNormalizedCartesianMesh.txx -// Created : Mon Aug 17 12:00:38 2009 -// Author : Edward AGAPOV (eap) -// - -#include "MEDCouplingNormalizedCartesianMesh.hxx" -#include "MEDCouplingCMesh.hxx" - -template -MEDCouplingNormalizedCartesianMesh::MEDCouplingNormalizedCartesianMesh(const ParaMEDMEM::MEDCouplingCMesh *mesh):_mesh(mesh) -{ - if(_mesh) - _mesh->incrRef(); -} - -template -MEDCouplingNormalizedCartesianMesh::~MEDCouplingNormalizedCartesianMesh() -{ - if(_mesh) - _mesh->decrRef(); -} - -template -unsigned long MEDCouplingNormalizedCartesianMesh::getNumberOfElements() const -{ - return _mesh->getNumberOfCells(); -} - -template -unsigned long MEDCouplingNormalizedCartesianMesh::nbCellsAlongAxis(int axis) const -{ - return _mesh->getCoordsAt(axis)->getNumberOfTuples() - 1; -} - -template -const double * MEDCouplingNormalizedCartesianMesh::getCoordsAlongAxis(int axis) const -{ - return _mesh->getCoordsAt(axis)->getConstPointer(); -} diff --git a/src/MEDCoupling/MEDCouplingNormalizedUnstructuredMesh.hxx b/src/MEDCoupling/MEDCouplingNormalizedUnstructuredMesh.hxx deleted file mode 100644 index d3e8ce6b3..000000000 --- a/src/MEDCoupling/MEDCouplingNormalizedUnstructuredMesh.hxx +++ /dev/null @@ -1,59 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 -// 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_MEDCOUPLINGNORMALIZEDUNSTRUCTUREDMESH_HXX__ -#define __PARAMEDMEM_MEDCOUPLINGNORMALIZEDUNSTRUCTUREDMESH_HXX__ - -#include "NormalizedUnstructuredMesh.hxx" - -namespace ParaMEDMEM -{ - class MEDCouplingPointSet; -} - -template -class MEDCouplingNormalizedUnstructuredMesh -{ -public: - static const int MY_SPACEDIM=SPACEDIM; - static const int MY_MESHDIM=MESHDIM; - typedef int MyConnType; - static const INTERP_KERNEL::NumberingPolicy My_numPol=INTERP_KERNEL::ALL_C_MODE; -public: - MEDCouplingNormalizedUnstructuredMesh(const ParaMEDMEM::MEDCouplingPointSet *mesh); - void getBoundingBox(double *boundingBox) const; - INTERP_KERNEL::NormalizedCellType getTypeOfElement(int eltId) const; - int getNumberOfNodesOfElement(int eltId) const; - int getNumberOfElements() const; - int getNumberOfNodes() const; - const int *getConnectivityPtr() const; - const double *getCoordinatesPtr() const; - const int *getConnectivityIndexPtr() const; - void releaseTempArrays(); - ~MEDCouplingNormalizedUnstructuredMesh(); -private: - void prepare(); -private: - const ParaMEDMEM::MEDCouplingPointSet *_mesh; - int *_conn_for_interp; - int *_conn_index_for_interp; -}; - -#endif diff --git a/src/MEDCoupling/MEDCouplingNormalizedUnstructuredMesh.txx b/src/MEDCoupling/MEDCouplingNormalizedUnstructuredMesh.txx deleted file mode 100644 index 5e8cfb985..000000000 --- a/src/MEDCoupling/MEDCouplingNormalizedUnstructuredMesh.txx +++ /dev/null @@ -1,176 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 -// 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 __MEDCOUPLINGNORMALIZEDUNSTRUCTUREDMESH_TXX__ -#define __MEDCOUPLINGNORMALIZEDUNSTRUCTUREDMESH_TXX__ - -#include "MEDCouplingNormalizedUnstructuredMesh.hxx" - -#include "MEDCouplingUMesh.hxx" -#include "MEDCoupling1GTUMesh.hxx" -#include "MEDCouplingMemArray.hxx" - -#include - -template -MEDCouplingNormalizedUnstructuredMesh::MEDCouplingNormalizedUnstructuredMesh(const ParaMEDMEM::MEDCouplingPointSet *mesh):_mesh(mesh) -{ - if(_mesh) - _mesh->incrRef(); - prepare(); -} - -template -void MEDCouplingNormalizedUnstructuredMesh::getBoundingBox(double *boundingBox) const -{ - for(int i=0;i::max(); - boundingBox[SPACEDIM+i]=-std::numeric_limits::max(); - } - const ParaMEDMEM::DataArrayDouble *array=_mesh->getCoords(); - const double *ptr=array->getConstPointer(); - int nbOfPts=array->getNbOfElems()/SPACEDIM; - for(int j=0;j*work) - boundingBox[j]=*work; - if(boundingBox[j+SPACEDIM]<*work) - boundingBox[j+SPACEDIM]=*work; - } - } -} - -template -INTERP_KERNEL::NormalizedCellType MEDCouplingNormalizedUnstructuredMesh::getTypeOfElement(int eltId) const -{ - return _mesh->getTypeOfCell(eltId); -} - -template -int MEDCouplingNormalizedUnstructuredMesh::getNumberOfNodesOfElement(int eltId) const -{ - return _mesh->getNumberOfNodesInCell(eltId); -} - -template -int MEDCouplingNormalizedUnstructuredMesh::getNumberOfElements() const -{ - return _mesh->getNumberOfCells(); -} - -template -int MEDCouplingNormalizedUnstructuredMesh::getNumberOfNodes() const -{ - return _mesh->getNumberOfNodes(); -} - -template -const int *MEDCouplingNormalizedUnstructuredMesh::getConnectivityPtr() const -{ - return _conn_for_interp; -} - -template -const double *MEDCouplingNormalizedUnstructuredMesh::getCoordinatesPtr() const -{ - const ParaMEDMEM::DataArrayDouble *array=_mesh->getCoords(); - return array->getConstPointer(); -} - -template -const int *MEDCouplingNormalizedUnstructuredMesh::getConnectivityIndexPtr() const -{ - return _conn_index_for_interp; -} - -template -void MEDCouplingNormalizedUnstructuredMesh::releaseTempArrays() -{ - delete [] _conn_for_interp; - delete [] _conn_index_for_interp; - _conn_for_interp=0; - _conn_index_for_interp=0; -} - -template -MEDCouplingNormalizedUnstructuredMesh::~MEDCouplingNormalizedUnstructuredMesh() -{ - if(_mesh) - _mesh->decrRef(); - releaseTempArrays(); -} - -template -void MEDCouplingNormalizedUnstructuredMesh::prepare() -{ - const ParaMEDMEM::MEDCouplingUMesh *m1(dynamic_cast(_mesh)); - if(m1) - { - int nbOfCell=m1->getNumberOfCells(); - int initialConnSize=m1->getNodalConnectivity()->getNbOfElems(); - _conn_for_interp=new int[initialConnSize-nbOfCell]; - _conn_index_for_interp=new int[nbOfCell+1]; - _conn_index_for_interp[0]=0; - const int *work_conn=m1->getNodalConnectivity()->getConstPointer()+1; - const int *work_conn_index=m1->getNodalConnectivityIndex()->getConstPointer(); - int *work_conn_for_interp=_conn_for_interp; - int *work_conn_index_for_interp=_conn_index_for_interp; - for(int i=0;i(_mesh)); - if(m2) - { - int nbOfCell(m2->getNumberOfCells()); - _conn_index_for_interp=new int[nbOfCell+1]; - const int *conni(m2->getNodalConnectivityIndex()->begin()); - std::copy(conni,conni+nbOfCell+1,_conn_index_for_interp); - _conn_for_interp=new int[m2->getNodalConnectivity()->getNumberOfTuples()]; - std::copy(m2->getNodalConnectivity()->begin(),m2->getNodalConnectivity()->end(),_conn_for_interp); - return ; - } - const ParaMEDMEM::MEDCoupling1SGTUMesh *m3(dynamic_cast(_mesh)); - if(m3) - { - int nbOfCell(m3->getNumberOfCells()),nbNodesPerCell(m3->getNumberOfNodesPerCell()); - _conn_index_for_interp=new int[nbOfCell+1]; _conn_index_for_interp[0]=0; - int *work(_conn_index_for_interp); - for(int i=0;igetNodalConnectivity()->getNumberOfTuples()]; - std::copy(m3->getNodalConnectivity()->begin(),m3->getNodalConnectivity()->end(),_conn_for_interp); - return ; - } - throw INTERP_KERNEL::Exception("MEDCouplingNormalizedUnstructuredMesh::prepare : Unrecognized unstructured mesh ! Type must be in MEDCouplingUMesh, MEDCoupling1DGTUMesh, MEDCoupling1SGTUMesh !"); -} - -#endif diff --git a/src/MEDCoupling/MEDCouplingPartDefinition.cxx b/src/MEDCoupling/MEDCouplingPartDefinition.cxx deleted file mode 100644 index 7523d938b..000000000 --- a/src/MEDCoupling/MEDCouplingPartDefinition.cxx +++ /dev/null @@ -1,419 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 -// 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 (EDF R&D) - -#include "MEDCouplingPartDefinition.hxx" - -using namespace ParaMEDMEM; - -PartDefinition *PartDefinition::New(int start, int stop, int step) -{ - return SlicePartDefinition::New(start,stop,step); -} - -PartDefinition *PartDefinition::New(DataArrayInt *listOfIds) -{ - return DataArrayPartDefinition::New(listOfIds); -} - -PartDefinition *PartDefinition::Unserialize(std::vector& tinyInt, std::vector< MEDCouplingAutoRefCountObjectPtr >& bigArraysI) -{ - if(tinyInt.empty()) - { - MEDCouplingAutoRefCountObjectPtr ret(DataArrayPartDefinition::New(bigArraysI.back())); - bigArraysI.pop_back(); - return ret.retn(); - } - else if(tinyInt.size()==3) - { - MEDCouplingAutoRefCountObjectPtr ret(SlicePartDefinition::New(tinyInt[0],tinyInt[1],tinyInt[2])); - tinyInt.erase(tinyInt.begin(),tinyInt.begin()+3); - return ret.retn(); - } - else - throw INTERP_KERNEL::Exception("PartDefinition::Unserialize"); -} - -PartDefinition::~PartDefinition() -{ -} - -DataArrayPartDefinition *DataArrayPartDefinition::New(DataArrayInt *listOfIds) -{ - return new DataArrayPartDefinition(listOfIds); -} - -bool DataArrayPartDefinition::isEqual(const PartDefinition *other, std::string& what) const -{ - if(!other) - { - what="DataArrayPartDefinition::isEqual : other is null, this is not null !"; - return false; - } - const DataArrayPartDefinition *otherC(dynamic_cast(other)); - if(!otherC) - { - what="DataArrayPartDefinition::isEqual : other is not DataArrayPartDefinition !"; - return false; - } - const DataArrayInt *arr0(_arr),*arr1(otherC->_arr); - if(!arr0 && !arr1) - return true; - if((arr0 && !arr1) || (!arr0 && arr1)) - { - what="DataArrayPartDefinition::isEqual : array is not defined both in other and this !"; - return false; - } - std::string what1; - bool ret(arr0->isEqualIfNotWhy(*arr1,what1)); - if(!ret) - { - what=std::string("DataArrayPartDefinition::isEqual : arrays are not equal :\n")+what1; - return false; - } - return true; -} - -DataArrayPartDefinition *DataArrayPartDefinition::deepCpy() const -{ - const DataArrayInt *arr(_arr); - if(!arr) - throw INTERP_KERNEL::Exception("DataArrayPartDefinition::deepCpy : array is null !"); - return DataArrayPartDefinition::New(const_cast(arr)); -} - -int DataArrayPartDefinition::getNumberOfElems() const -{ - checkInternalArrayOK(); - return _arr->getNumberOfTuples(); -} - -PartDefinition *DataArrayPartDefinition::operator+(const PartDefinition& other) const -{ - const PartDefinition *otherPt(&other); - if(!otherPt) - throw INTERP_KERNEL::Exception("DataArrayPartDefinition::operator+ : NULL input !"); - const DataArrayPartDefinition *other1(dynamic_cast(otherPt)); - if(other1) - return add1(other1); - const SlicePartDefinition *other2(dynamic_cast(otherPt)); - if(other2) - return add2(other2); - throw INTERP_KERNEL::Exception("DataArrayPartDefinition::operator+ : unrecognized type in input !"); -} - -std::string DataArrayPartDefinition::getRepr() const -{ - std::ostringstream oss; oss << "DataArray Part : "; - const DataArrayInt *arr(_arr); - if(arr) - arr->reprQuickOverview(oss); - else - oss << "No Data !"; - return oss.str(); -} - -/*! - * This method operates FoG where F is \a this and G is \a other. - * Example : if \a other is SlicePart(4,14,1) and if \a this is DataArrayPartDefinition([0,1,2,3,6,7,8,9]) -> DataArrayPartDefinition([4,5,6,7,11,12,13]) will be returned - */ -PartDefinition *DataArrayPartDefinition::composeWith(const PartDefinition *other) const -{ - if(!other) - throw INTERP_KERNEL::Exception("DataArrayPartDefinition::composeWith : input PartDef must be not NULL !"); - checkCoherency(); - other->checkCoherency(); - const SlicePartDefinition *spd(dynamic_cast(other)); - if(spd) - {//special case for optim - int a(0),b(0),c(0); - spd->getSlice(a,b,c); - if(c==1) - { - MEDCouplingAutoRefCountObjectPtr arr(DataArrayInt::New()); - arr->alloc(_arr->getNumberOfTuples(),1); - std::transform(_arr->begin(),_arr->end(),arr->getPointer(),std::bind2nd(std::plus(),a)); - return DataArrayPartDefinition::New(arr); - } - } - // - MEDCouplingAutoRefCountObjectPtr arr1(other->toDAI()); - MEDCouplingAutoRefCountObjectPtr arr2(arr1->selectByTupleIdSafe(_arr->begin(),_arr->end())); - return DataArrayPartDefinition::New(arr2); -} - -void DataArrayPartDefinition::checkCoherency() const -{ - CheckInternalArrayOK(_arr); -} - -/*! - * This method tries to simplify \a this if possible. - * - * \return a new reference (equal to this) to be decrRefed. - */ -PartDefinition *DataArrayPartDefinition::tryToSimplify() const -{ - checkCoherency(); - int a(0),b(0),c(0); - if(_arr->isRange(a,b,c)) - { - return SlicePartDefinition::New(a,b,c); - } - else - { - PartDefinition *ret(const_cast(this)); - ret->incrRef(); - return ret; - } -} - -void DataArrayPartDefinition::serialize(std::vector& tinyInt, std::vector< MEDCouplingAutoRefCountObjectPtr >& bigArraysI) const -{ - bigArraysI.push_back(_arr); -} - -DataArrayInt *DataArrayPartDefinition::toDAI() const -{ - checkInternalArrayOK(); - const DataArrayInt *arr(_arr); - DataArrayInt *arr2(const_cast(arr)); - arr2->incrRef(); - return arr2; -} - -DataArrayPartDefinition::DataArrayPartDefinition(DataArrayInt *listOfIds) -{ - CheckInternalArrayOK(listOfIds); - _arr=listOfIds; - _arr->incrRef(); -} - -void DataArrayPartDefinition::checkInternalArrayOK() const -{ - CheckInternalArrayOK(_arr); -} - -void DataArrayPartDefinition::CheckInternalArrayOK(const DataArrayInt *listOfIds) -{ - if(!listOfIds || !listOfIds->isAllocated() || listOfIds->getNumberOfComponents()!=1) - throw INTERP_KERNEL::Exception("DataArrayPartDefinition::CheckInternalArrayOK : Input list must be not null allocated and with one components !"); -} - -void DataArrayPartDefinition::updateTime() const -{ - if((const DataArrayInt *)_arr) - updateTimeWith(*_arr); -} - -std::size_t DataArrayPartDefinition::getHeapMemorySizeWithoutChildren() const -{ - return sizeof(DataArrayPartDefinition); -} - -std::vector DataArrayPartDefinition::getDirectChildrenWithNull() const -{ - std::vector ret(1,(const DataArrayInt *)_arr); - return ret; -} - -DataArrayPartDefinition *DataArrayPartDefinition::add1(const DataArrayPartDefinition *other) const -{ - MEDCouplingAutoRefCountObjectPtr a1(toDAI()),a2(other->toDAI()); - MEDCouplingAutoRefCountObjectPtr a3(DataArrayInt::Aggregate(a1,a2,0)); - a3->sort(); - return DataArrayPartDefinition::New(a3); -} - -DataArrayPartDefinition *DataArrayPartDefinition::add2(const SlicePartDefinition *other) const -{ - MEDCouplingAutoRefCountObjectPtr a1(toDAI()),a2(other->toDAI()); - MEDCouplingAutoRefCountObjectPtr a3(DataArrayInt::Aggregate(a1,a2,0)); - a3->sort(); - return DataArrayPartDefinition::New(a3); -} - -DataArrayPartDefinition::~DataArrayPartDefinition() -{ -} - -SlicePartDefinition *SlicePartDefinition::New(int start, int stop, int step) -{ - return new SlicePartDefinition(start,stop,step); -} - -bool SlicePartDefinition::isEqual(const PartDefinition *other, std::string& what) const -{ - if(!other) - { - what="SlicePartDefinition::isEqual : other is null, this is not null !"; - return false; - } - const SlicePartDefinition *otherC(dynamic_cast(other)); - if(!otherC) - { - what="SlicePartDefinition::isEqual : other is not SlicePartDefinition !"; - return false; - } - bool ret((_start==otherC->_start) && (_stop==otherC->_stop) && (_step==otherC->_step)); - if(!ret) - { - what="SlicePartDefinition::isEqual : values are not the same !"; - return false; - } - return true; -} - -SlicePartDefinition *SlicePartDefinition::deepCpy() const -{ - return SlicePartDefinition::New(_start,_stop,_step); -} - -DataArrayInt *SlicePartDefinition::toDAI() const -{ - return DataArrayInt::Range(_start,_stop,_step); -} - -int SlicePartDefinition::getNumberOfElems() const -{ - return DataArray::GetNumberOfItemGivenBES(_start,_stop,_step,"SlicePartDefinition::getNumberOfElems"); -} - -PartDefinition *SlicePartDefinition::operator+(const PartDefinition& other) const -{ - const PartDefinition *otherPt(&other); - if(!otherPt) - throw INTERP_KERNEL::Exception("DataArrayPartDefinition::operator+ : NULL input !"); - const DataArrayPartDefinition *other1(dynamic_cast(otherPt)); - if(other1) - return add1(other1); - const SlicePartDefinition *other2(dynamic_cast(otherPt)); - if(other2) - return add2(other2); - throw INTERP_KERNEL::Exception("SlicePartDefinition::operator+ : unrecognized type in input !"); -} - -/*! - * This method operates FoG where F is \a this and G is \a other. - * Example : if \a this is SlicePart(4,6,1) and if \a other is DataArrayPartDefinition([12,13,17,18,22,28,34,44]) -> DataArrayPartDefinition([22,28]) will be returned - */ -PartDefinition *SlicePartDefinition::composeWith(const PartDefinition *other) const -{ - if(!other) - throw INTERP_KERNEL::Exception("SlicePartDefinition::composeWith : input PartDef must be not NULL !"); - checkCoherency(); - other->checkCoherency(); - MEDCouplingAutoRefCountObjectPtr arr(other->toDAI()); - MEDCouplingAutoRefCountObjectPtr arr1(arr->selectByTupleId2(_start,_stop,_step)); - return DataArrayPartDefinition::New(arr1); -} - -/*! - * Do nothing it is not a bug. - */ -void SlicePartDefinition::checkCoherency() const -{ -} - -/*! - * Return \a this (because it cannot be simplified) - * - * \return a new reference (equal to this) to be decrRefed. - */ -PartDefinition *SlicePartDefinition::tryToSimplify() const -{ - PartDefinition *ret(const_cast(this)); - ret->incrRef(); - return ret; -} - -void SlicePartDefinition::serialize(std::vector& tinyInt, std::vector< MEDCouplingAutoRefCountObjectPtr >& bigArraysI) const -{ - tinyInt.push_back(_start); - tinyInt.push_back(_stop); - tinyInt.push_back(_step); -} - -std::string SlicePartDefinition::getRepr() const -{ - std::ostringstream oss; - oss << "Slice is defined with : start=" << _start << " stop=" << _stop << " step=" << _step; - return oss.str(); -} - -int SlicePartDefinition::getEffectiveStop() const -{ - int nbElems(DataArray::GetNumberOfItemGivenBES(_start,_stop,_step,"SlicePartDefinition::getEffectiveStop")); - return _start+nbElems*_step; -} - -void SlicePartDefinition::getSlice(int& start, int& stop, int& step) const -{ - start=_start; - stop=_stop; - step=_step; -} - -SlicePartDefinition::SlicePartDefinition(int start, int stop, int step):_start(start),_stop(stop),_step(step) -{ -} - -/*! - * No child ! It is the leaf ! So no implementation. - */ -void SlicePartDefinition::updateTime() const -{ -} - -std::size_t SlicePartDefinition::getHeapMemorySizeWithoutChildren() const -{ - return sizeof(SlicePartDefinition); -} - -std::vector SlicePartDefinition::getDirectChildrenWithNull() const -{ - return std::vector(); -} - -DataArrayPartDefinition *SlicePartDefinition::add1(const DataArrayPartDefinition *other) const -{ - MEDCouplingAutoRefCountObjectPtr a1(toDAI()),a2(other->toDAI()); - MEDCouplingAutoRefCountObjectPtr a3(DataArrayInt::Aggregate(a1,a2,0)); - a3->sort(); - return DataArrayPartDefinition::New(a3); -} - -PartDefinition *SlicePartDefinition::add2(const SlicePartDefinition *other) const -{ - if(_step==other->_step && getEffectiveStop()==other->_start) - { - return SlicePartDefinition::New(_start,other->_stop,_step); - } - else - { - MEDCouplingAutoRefCountObjectPtr a1(toDAI()),a2(other->toDAI()); - MEDCouplingAutoRefCountObjectPtr a3(DataArrayInt::Aggregate(a1,a2,0)); - a3->sort(); - return DataArrayPartDefinition::New(a3); - } -} - -SlicePartDefinition::~SlicePartDefinition() -{ -} diff --git a/src/MEDCoupling/MEDCouplingPartDefinition.hxx b/src/MEDCoupling/MEDCouplingPartDefinition.hxx deleted file mode 100644 index 49bc3d379..000000000 --- a/src/MEDCoupling/MEDCouplingPartDefinition.hxx +++ /dev/null @@ -1,112 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 -// 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 (EDF R&D) - -#ifndef __PARAMEDMEM_MEDCOUPLINGPARTDEFINITION_HXX__ -#define __PARAMEDMEM_MEDCOUPLINGPARTDEFINITION_HXX__ - -#include "MEDCoupling.hxx" -#include "MEDCouplingMemArray.hxx" -#include "MEDCouplingAutoRefCountObjectPtr.hxx" - -namespace ParaMEDMEM -{ - class PartDefinition : public RefCountObject, public TimeLabel - { - public: - MEDCOUPLING_EXPORT static PartDefinition *New(int start, int stop, int step); - MEDCOUPLING_EXPORT static PartDefinition *New(DataArrayInt *listOfIds); - MEDCOUPLING_EXPORT static PartDefinition *Unserialize(std::vector& tinyInt, std::vector< MEDCouplingAutoRefCountObjectPtr >& bigArraysI); - MEDCOUPLING_EXPORT virtual bool isEqual(const PartDefinition *other, std::string& what) const = 0; - MEDCOUPLING_EXPORT virtual PartDefinition *deepCpy() const = 0; - MEDCOUPLING_EXPORT virtual DataArrayInt *toDAI() const = 0; - MEDCOUPLING_EXPORT virtual int getNumberOfElems() const = 0; - MEDCOUPLING_EXPORT virtual PartDefinition *operator+(const PartDefinition& other) const = 0; - MEDCOUPLING_EXPORT virtual std::string getRepr() const = 0; - MEDCOUPLING_EXPORT virtual PartDefinition *composeWith(const PartDefinition *other) const = 0; - MEDCOUPLING_EXPORT virtual void checkCoherency() const = 0; - MEDCOUPLING_EXPORT virtual PartDefinition *tryToSimplify() const = 0; - MEDCOUPLING_EXPORT virtual void serialize(std::vector& tinyInt, std::vector< MEDCouplingAutoRefCountObjectPtr >& bigArraysI) const = 0; - protected: - virtual ~PartDefinition(); - }; - - class SlicePartDefinition; - - class DataArrayPartDefinition : public PartDefinition - { - public: - MEDCOUPLING_EXPORT static DataArrayPartDefinition *New(DataArrayInt *listOfIds); - MEDCOUPLING_EXPORT bool isEqual(const PartDefinition *other, std::string& what) const; - MEDCOUPLING_EXPORT DataArrayPartDefinition *deepCpy() const; - MEDCOUPLING_EXPORT DataArrayInt *toDAI() const; - MEDCOUPLING_EXPORT int getNumberOfElems() const; - MEDCOUPLING_EXPORT PartDefinition *operator+(const PartDefinition& other) const; - MEDCOUPLING_EXPORT std::string getRepr() const; - MEDCOUPLING_EXPORT PartDefinition *composeWith(const PartDefinition *other) const; - MEDCOUPLING_EXPORT void checkCoherency() const; - MEDCOUPLING_EXPORT PartDefinition *tryToSimplify() const; - MEDCOUPLING_EXPORT void serialize(std::vector& tinyInt, std::vector< MEDCouplingAutoRefCountObjectPtr >& bigArraysI) const; - private: - DataArrayPartDefinition(DataArrayInt *listOfIds); - void checkInternalArrayOK() const; - static void CheckInternalArrayOK(const DataArrayInt *listOfIds); - MEDCOUPLING_EXPORT void updateTime() const; - MEDCOUPLING_EXPORT std::size_t getHeapMemorySizeWithoutChildren() const; - MEDCOUPLING_EXPORT std::vector getDirectChildrenWithNull() const; - DataArrayPartDefinition *add1(const DataArrayPartDefinition *other) const; - DataArrayPartDefinition *add2(const SlicePartDefinition *other) const; - virtual ~DataArrayPartDefinition(); - private: - MEDCouplingAutoRefCountObjectPtr _arr; - }; - - class SlicePartDefinition : public PartDefinition - { - public: - MEDCOUPLING_EXPORT static SlicePartDefinition *New(int start, int stop, int step); - MEDCOUPLING_EXPORT bool isEqual(const PartDefinition *other, std::string& what) const; - MEDCOUPLING_EXPORT SlicePartDefinition *deepCpy() const; - MEDCOUPLING_EXPORT DataArrayInt *toDAI() const; - MEDCOUPLING_EXPORT int getNumberOfElems() const; - MEDCOUPLING_EXPORT PartDefinition *operator+(const PartDefinition& other) const; - MEDCOUPLING_EXPORT std::string getRepr() const; - MEDCOUPLING_EXPORT PartDefinition *composeWith(const PartDefinition *other) const; - MEDCOUPLING_EXPORT void checkCoherency() const; - MEDCOUPLING_EXPORT PartDefinition *tryToSimplify() const; - MEDCOUPLING_EXPORT void serialize(std::vector& tinyInt, std::vector< MEDCouplingAutoRefCountObjectPtr >& bigArraysI) const; - //specific method - MEDCOUPLING_EXPORT int getEffectiveStop() const; - MEDCOUPLING_EXPORT void getSlice(int& start, int& stop, int& step) const; - private: - SlicePartDefinition(int start, int stop, int step); - MEDCOUPLING_EXPORT void updateTime() const; - MEDCOUPLING_EXPORT std::size_t getHeapMemorySizeWithoutChildren() const; - MEDCOUPLING_EXPORT std::vector getDirectChildrenWithNull() const; - DataArrayPartDefinition *add1(const DataArrayPartDefinition *other) const; - PartDefinition *add2(const SlicePartDefinition *other) const; - virtual ~SlicePartDefinition(); - private: - int _start; - int _stop; - int _step; - }; -} - -#endif diff --git a/src/MEDCoupling/MEDCouplingPointSet.cxx b/src/MEDCoupling/MEDCouplingPointSet.cxx deleted file mode 100644 index 4793b7993..000000000 --- a/src/MEDCoupling/MEDCouplingPointSet.cxx +++ /dev/null @@ -1,1695 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 -// 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 "MEDCouplingPointSet.hxx" -#include "MEDCouplingAutoRefCountObjectPtr.hxx" -#include "MEDCoupling1GTUMesh.hxx" -#include "MEDCouplingUMesh.hxx" -#include "MEDCouplingMemArray.hxx" -#include "PlanarIntersector.txx" -#include "InterpKernelGeo2DQuadraticPolygon.hxx" -#include "InterpKernelGeo2DNode.hxx" -#include "DirectedBoundingBox.hxx" -#include "InterpKernelAutoPtr.hxx" - -#include -#include -#include - -using namespace ParaMEDMEM; - -MEDCouplingPointSet::MEDCouplingPointSet():_coords(0) -{ -} - -MEDCouplingPointSet::MEDCouplingPointSet(const MEDCouplingPointSet& other, bool deepCopy):MEDCouplingMesh(other),_coords(0) -{ - if(other._coords) - _coords=other._coords->performCpy(deepCopy); -} - -MEDCouplingPointSet::~MEDCouplingPointSet() -{ - if(_coords) - _coords->decrRef(); -} - -int MEDCouplingPointSet::getNumberOfNodes() const -{ - if(_coords) - return _coords->getNumberOfTuples(); - else - throw INTERP_KERNEL::Exception("Unable to get number of nodes because no coordinates specified !"); -} - -int MEDCouplingPointSet::getSpaceDimension() const -{ - if(_coords) - return _coords->getNumberOfComponents(); - else - throw INTERP_KERNEL::Exception("Unable to get space dimension because no coordinates specified !"); -} - -void MEDCouplingPointSet::updateTime() const -{ - if(_coords) - { - updateTimeWith(*_coords); - } -} - -std::size_t MEDCouplingPointSet::getHeapMemorySizeWithoutChildren() const -{ - return MEDCouplingMesh::getHeapMemorySizeWithoutChildren(); -} - -std::vector MEDCouplingPointSet::getDirectChildrenWithNull() const -{ - std::vector ret; - ret.push_back(_coords); - return ret; -} - -void MEDCouplingPointSet::setCoords(const DataArrayDouble *coords) -{ - if( coords != _coords ) - { - if (_coords) - _coords->decrRef(); - _coords=const_cast(coords); - if(_coords) - _coords->incrRef(); - declareAsNew(); - } -} - -/*! - * 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) - _coords->incrRef(); - return _coords; -} - -/*! - * 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) -{ - MEDCouplingMesh::copyTinyStringsFrom(other); - const MEDCouplingPointSet *otherC=dynamic_cast(other); - if(!otherC) - throw INTERP_KERNEL::Exception("MEDCouplingPointSet::copyTinyStringsFrom : meshes have not same type !"); - if(_coords && otherC->_coords) - _coords->copyStringInfoFrom(*otherC->_coords); -} - -bool MEDCouplingPointSet::isEqualIfNotWhy(const MEDCouplingMesh *other, double prec, std::string& reason) const -{ - if(!other) - throw INTERP_KERNEL::Exception("MEDCouplingPointSet::isEqualIfNotWhy : null mesh instance in input !"); - const MEDCouplingPointSet *otherC=dynamic_cast(other); - if(!otherC) - { - reason="mesh given in input is not castable in MEDCouplingPointSet !"; - return false; - } - if(!MEDCouplingMesh::isEqualIfNotWhy(other,prec,reason)) - return false; - if(!areCoordsEqualIfNotWhy(*otherC,prec,reason)) - return false; - 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); - if(!otherC) - return false; - if(!areCoordsEqualWithoutConsideringStr(*otherC,prec)) - return false; - return true; -} - -bool MEDCouplingPointSet::areCoordsEqualIfNotWhy(const MEDCouplingPointSet& other, double prec, std::string& reason) const -{ - if(_coords==0 && other._coords==0) - return true; - if(_coords==0 || other._coords==0) - { - reason="Only one PointSet between the two this and other has coordinate defined !"; - return false; - } - if(_coords==other._coords) - return true; - bool ret=_coords->isEqualIfNotWhy(*other._coords,prec,reason); - if(!ret) - reason.insert(0,"Coordinates DataArray do not match : "); - 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) - return true; - if(_coords==0 || other._coords==0) - return false; - if(_coords==other._coords) - return true; - return _coords->isEqualWithoutConsideringStr(*other._coords,prec); -} - -/*! - * 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. - * - * \if ENABLE_EXAMPLES - * \ref cpp_mcpointset_getcoordinatesofnode "Here is a C++ example".
- * \ref py_mcpointset_getcoordinatesofnode "Here is a Python example". - * \endif - */ -void MEDCouplingPointSet::getCoordinatesOfNode(int nodeId, std::vector& coo) const -{ - if(!_coords) - throw INTERP_KERNEL::Exception("MEDCouplingPointSet::getCoordinatesOfNode : no coordinates array set !"); - int nbNodes=getNumberOfNodes(); - if(nodeId>=0 && nodeIdgetConstPointer(); - int spaceDim=getSpaceDimension(); - coo.insert(coo.end(),cooPtr+spaceDim*nodeId,cooPtr+spaceDim*(nodeId+1)); - } - else - { - std::ostringstream oss; oss << "MEDCouplingPointSet::getCoordinatesOfNode : request of nodeId \"" << nodeId << "\" but it should be in [0,"<< nbNodes << ") !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } -} - -/*! - * 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 numbering. 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(); - MEDCouplingAutoRefCountObjectPtr ret=buildNewNumberingFromCommonNodesFormat(comm,commI,newNbOfNodes); - areNodesMerged=(oldNbOfNodes!=newNbOfNodes); - comm->decrRef(); - commI->decrRef(); - return ret.retn(); -} - -/*! - * Finds nodes coincident within \a prec tolerance. - * Ids of coincident nodes are stored in output arrays in the \ref numbering-indirect format. - * \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 (\ref numbering-indirect). 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. - * - * \if ENABLE_EXAMPLES - * \ref cpp_mcpointset_findcommonnodes "Here is a C++ example".
- * \ref py_mcpointset_findcommonnodes "Here is a Python example". - * \endif - */ -void MEDCouplingPointSet::findCommonNodes(double prec, int limitNodeId, DataArrayInt *&comm, DataArrayInt *&commIndex) const -{ - if(!_coords) - throw INTERP_KERNEL::Exception("MEDCouplingPointSet::findCommonNodes : no coords specified !"); - _coords->findCommonTuples(prec,limitNodeId,comm,commIndex); -} - -/*! - * 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. - * - * \if ENABLE_EXAMPLES - * \ref cpp_mcpointset_getnodeidsnearpoint "Here is a C++ example".
- * \ref py_mcpointset_getnodeidsnearpoint "Here is a Python example". - * \endif - */ -DataArrayInt *MEDCouplingPointSet::getNodeIdsNearPoint(const double *pos, double eps) const -{ - DataArrayInt *c=0,*cI=0; - getNodeIdsNearPoints(pos,1,eps,c,cI); - MEDCouplingAutoRefCountObjectPtr cITmp(cI); - return c; -} - -/*! - * 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 (\ref numbering-indirect) 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 (\ref numbering-indirect).
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. - * - * \if ENABLE_EXAMPLES - * \ref cpp_mcpointset_getnodeidsnearpoints "Here is a C++ example".
- * \ref py_mcpointset_getnodeidsnearpoints "Here is a Python example". - * \endif - */ -void MEDCouplingPointSet::getNodeIdsNearPoints(const double *pos, int nbOfPoints, double eps, DataArrayInt *& c, DataArrayInt *& cI) const -{ - if(!_coords) - throw INTERP_KERNEL::Exception("MEDCouplingPointSet::getNodeIdsNearPoint : no coordiantes set !"); - int spaceDim=getSpaceDimension(); - MEDCouplingAutoRefCountObjectPtr points=DataArrayDouble::New(); - points->useArray(pos,false,CPP_DEALLOC,nbOfPoints,spaceDim); - _coords->computeTupleIdsNearTuples(points,eps,c,cI); -} - -/*! - * @param comm in param in the same format than one returned by findCommonNodes method (\ref numbering-indirect). - * @param commI in param in the same format than one returned by findCommonNodes method (\ref numbering-indirect). - * @return the old to new correspondance array. - */ -DataArrayInt *MEDCouplingPointSet::buildNewNumberingFromCommonNodesFormat(const DataArrayInt *comm, const DataArrayInt *commIndex, - int& newNbOfNodes) const -{ - if(!_coords) - throw INTERP_KERNEL::Exception("MEDCouplingPointSet::buildNewNumberingFromCommonNodesFormat : no coords specified !"); - return DataArrayInt::BuildOld2NewArrayFromSurjectiveFormat2(getNumberOfNodes(),comm->begin(),commIndex->begin(),commIndex->end(),newNbOfNodes); -} - -/*! - * Permutes and possibly removes nodes as specified by \a newNodeNumbers array. - * If \a newNodeNumbers[ i ] < 0 then the i-th node is removed, - * else \a newNodeNumbers[ i ] is a new id of the i-th node. The nodal connectivity - * array is modified accordingly. - * \param [in] newNodeNumbers - a permutation array, of length \a - * this->getNumberOfNodes(), in "Old to New" mode. - * See \ref numbering for more info on renumbering modes. - * \param [in] newNbOfNodes - number of nodes remaining after renumbering. - * \throw If the coordinates array is not set. - * \throw If the nodal connectivity of cells is not defined. - * - * \if ENABLE_EXAMPLES - * \ref cpp_mcumesh_renumberNodes "Here is a C++ example".
- * \ref py_mcumesh_renumberNodes "Here is a Python example". - * \endif - */ -void MEDCouplingPointSet::renumberNodes(const int *newNodeNumbers, int newNbOfNodes) -{ - if(!_coords) - throw INTERP_KERNEL::Exception("MEDCouplingPointSet::renumberNodes : no coords specified !"); - MEDCouplingAutoRefCountObjectPtr newCoords=_coords->renumberAndReduce(newNodeNumbers,newNbOfNodes); - renumberNodesInConn(newNodeNumbers); - setCoords(newCoords);//let it here not before renumberNodesInConn because old number of nodes is sometimes used... -} - -/*! - * Permutes and possibly removes nodes as specified by \a newNodeNumbers array. - * If \a newNodeNumbers[ i ] < 0 then the i-th node is removed, - * else \a newNodeNumbers[ i ] is a new id of the i-th node. The nodal connectivity - * array is modified accordingly. In contrast to renumberNodes(), location - * of merged nodes (whose new ids coincide) is changed to be at their barycenter. - * \param [in] newNodeNumbers - a permutation array, of length \a - * this->getNumberOfNodes(), in "Old to New" mode. - * See \ref numbering for more info on renumbering modes. - * \param [in] newNbOfNodes - number of nodes remaining after renumbering, which is - * actually one more than the maximal id in \a newNodeNumbers. - * \throw If the coordinates array is not set. - * \throw If the nodal connectivity of cells is not defined. - * - * \if ENABLE_EXAMPLES - * \ref cpp_mcumesh_renumberNodes "Here is a C++ example".
- * \ref py_mcumesh_renumberNodes "Here is a Python example". - * \endif - */ -void MEDCouplingPointSet::renumberNodes2(const int *newNodeNumbers, int newNbOfNodes) -{ - DataArrayDouble *newCoords=DataArrayDouble::New(); - std::vector div(newNbOfNodes); - int spaceDim=getSpaceDimension(); - newCoords->alloc(newNbOfNodes,spaceDim); - newCoords->copyStringInfoFrom(*_coords); - newCoords->fillWithZero(); - int oldNbOfNodes=getNumberOfNodes(); - double *ptToFill=newCoords->getPointer(); - const double *oldCoordsPtr=_coords->getConstPointer(); - for(int i=0;i()); - div[newNodeNumbers[i]]++; - } - for(int i=0;i(),1./(double)div[i])); - setCoords(newCoords); - newCoords->decrRef(); - renumberNodesInConn(newNodeNumbers); -} - -/*! - * 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. - * - * \if ENABLE_EXAMPLES - * \ref cpp_mcpointset_getBoundingBox "Here is a C++ example".
- * \ref py_mcpointset_getBoundingBox "Here is a Python example". - * \endif - */ -void MEDCouplingPointSet::getBoundingBox(double *bbox) const -{ - if(!_coords) - throw INTERP_KERNEL::Exception("MEDCouplingPointSet::getBoundingBox : Coordinates not set !"); - _coords->getMinMaxPerComponent(bbox); -} - -/*! - * 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() -{ - checkFullyDefined(); - DataArrayInt *traducer=zipCoordsTraducer(); - traducer->decrRef(); -} - -/*! \cond HIDDEN_ITEMS */ -struct MEDCouplingCompAbs -{ - bool operator()(double x, double y) { return std::abs(x)getConstPointer(); - int nbOfValues=_coords->getNbOfElems(); - return std::abs(*std::max_element(coords,coords+nbOfValues,MEDCouplingCompAbs())); -} - -/*! - * 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. - * - */ -void MEDCouplingPointSet::recenterForMaxPrecision(double eps) -{ - if(!_coords) - throw INTERP_KERNEL::Exception("MEDCouplingPointSet::recenterForMaxPrecision : Coordinates not set !"); - _coords->recenterForMaxPrecision(eps); - updateTime(); -} - -/*! - * 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. - * - * \if ENABLE_EXAMPLES - * \ref cpp_mcpointset_rotate "Here is a C++ example".
- * \ref py_mcpointset_rotate "Here is a Python example". - * \endif - */ -void MEDCouplingPointSet::rotate(const double *center, const double *vector, double angle) -{ - int spaceDim=getSpaceDimension(); - if(spaceDim==3) - rotate3D(center,vector,angle); - else if(spaceDim==2) - rotate2D(center,angle); - else - throw INTERP_KERNEL::Exception("MEDCouplingPointSet::rotate : invalid space dim for rotation must be 2 or 3"); - _coords->declareAsNew(); - updateTime(); -} - -/*! - * 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. - * - * \if ENABLE_EXAMPLES - * \ref cpp_mcpointset_translate "Here is a C++ example".
- * \ref py_mcpointset_translate "Here is a Python example". - * \endif - */ -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(); - for(int i=0; ideclareAsNew(); - updateTime(); -} - - -/*! - * 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. - * - * \if ENABLE_EXAMPLES - * \ref cpp_mcpointset_scale "Here is a C++ example".
- * \ref py_mcpointset_scale "Here is a Python example". - * \endif - */ -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(); - 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(); -} - -/*! - * Converts \a this set of points to an other dimension by changing number of - * components of point coordinates. If the dimension increases, added components - * are filled with \a dftValue. If the dimension decreases, last components are lost. - * If the new dimension is same as \a this->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) -{ - if(getCoords()==0) - throw INTERP_KERNEL::Exception("changeSpaceDimension must be called on an MEDCouplingPointSet instance with coordinates set !"); - if(newSpaceDim<1) - throw INTERP_KERNEL::Exception("changeSpaceDimension must be called a newSpaceDim >=1 !"); - int oldSpaceDim=getSpaceDimension(); - if(newSpaceDim==oldSpaceDim) - return ; - DataArrayDouble *newCoords=getCoords()->changeNbOfComponents(newSpaceDim,dftValue); - setCoords(newCoords); - newCoords->decrRef(); - updateTime(); -} - -/*! - * 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) -{ - if(_coords==other._coords) - return ; - if(!_coords) - throw INTERP_KERNEL::Exception("Current instance has no coords whereas other has !"); - if(!other._coords) - throw INTERP_KERNEL::Exception("Other instance has no coords whereas current has !"); - if(!_coords->isEqualWithoutConsideringStr(*other._coords,epsilon)) - throw INTERP_KERNEL::Exception("Coords are not the same !"); - setCoords(other._coords); -} - -/*! - * This method duplicates the nodes whose ids are in [\b nodeIdsToDuplicateBg, \b nodeIdsToDuplicateEnd) and put the result of their duplication at the end - * of existing node ids. - * - * \param [in] nodeIdsToDuplicateBg begin of node ids (included) to be duplicated in connectivity only - * \param [in] nodeIdsToDuplicateEnd end of node ids (excluded) to be duplicated in connectivity only - */ -void MEDCouplingPointSet::duplicateNodesInCoords(const int *nodeIdsToDuplicateBg, const int *nodeIdsToDuplicateEnd) -{ - if(!_coords) - throw INTERP_KERNEL::Exception("MEDCouplingPointSet::duplicateNodesInCoords : no coords set !"); - MEDCouplingAutoRefCountObjectPtr newCoords=_coords->selectByTupleIdSafe(nodeIdsToDuplicateBg,nodeIdsToDuplicateEnd); - MEDCouplingAutoRefCountObjectPtr newCoords2=DataArrayDouble::Aggregate(_coords,newCoords); - setCoords(newCoords2); -} - -/*! - * 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 -{ - 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() 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 -{ - 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;i vecn=new double[spaceDim]; - for(int i=0;igetConstPointer(); - if(spaceDim==2) - { - for(int i=0;igetSpaceDimension() != \a m2->getSpaceDimension(). - */ -DataArrayDouble *MEDCouplingPointSet::MergeNodesArray(const MEDCouplingPointSet *m1, const MEDCouplingPointSet *m2) -{ - int spaceDim=m1->getSpaceDimension(); - if(spaceDim!=m2->getSpaceDimension()) - throw INTERP_KERNEL::Exception("Mismatch in SpaceDim during call of MergeNodesArray !"); - return DataArrayDouble::Aggregate(m1->getCoords(),m2->getCoords()); -} - -DataArrayDouble *MEDCouplingPointSet::MergeNodesArray(const std::vector& ms) -{ - if(ms.empty()) - throw INTERP_KERNEL::Exception("MEDCouplingPointSet::MergeNodesArray : input array must be NON EMPTY !"); - std::vector::const_iterator it=ms.begin(); - std::vector coo(ms.size()); - int spaceDim=(*it)->getSpaceDimension(); - coo[0]=(*it++)->getCoords(); - if(!coo[0]->isAllocated()) - throw INTERP_KERNEL::Exception("MEDCouplingPointSet::MergeNodesArray : first element in coordinates is not allocated !"); - for(int i=1;it!=ms.end();it++,i++) - { - const DataArrayDouble *tmp=(*it)->getCoords(); - if(tmp) - { - if(tmp->isAllocated()) - { - if((*it)->getSpaceDimension()==spaceDim) - coo[i]=tmp; - else - throw INTERP_KERNEL::Exception("MEDCouplingPointSet::MergeNodesArray : Mismatch in SpaceDim !"); - } - else - throw INTERP_KERNEL::Exception("MEDCouplingPointSet::MergeNodesArray : Presence of a non allocated array !"); - } - else - throw INTERP_KERNEL::Exception("MEDCouplingPointSet::MergeNodesArray : Empty coords detected !"); - } - return DataArrayDouble::Aggregate(coo); -} - -/*! - * Factory to build new instance of instanciable subclasses of MEDCouplingPointSet. - * This method is used during unserialization process. - */ -MEDCouplingPointSet *MEDCouplingPointSet::BuildInstanceFromMeshType(MEDCouplingMeshType type) -{ - switch(type) - { - case UNSTRUCTURED: - return MEDCouplingUMesh::New(); - case SINGLE_STATIC_GEO_TYPE_UNSTRUCTURED: - return MEDCoupling1SGTUMesh::New(); - case SINGLE_DYNAMIC_GEO_TYPE_UNSTRUCTURED: - return MEDCoupling1DGTUMesh::New(); - default: - throw INTERP_KERNEL::Exception("Invalid type of mesh specified"); - } -} - -/*! - * First step of serialization process. Used by ParaMEDMEM and MEDCouplingCorba to transfert data between process. - */ -void MEDCouplingPointSet::getTinySerializationInformation(std::vector& tinyInfoD, std::vector& tinyInfo, std::vector& littleStrings) const -{ - int it,order; - double time=getTime(it,order); - if(_coords) - { - int spaceDim=getSpaceDimension(); - littleStrings.resize(spaceDim+4); - littleStrings[0]=getName(); - littleStrings[1]=getDescription(); - littleStrings[2]=_coords->getName(); - littleStrings[3]=getTimeUnit(); - for(int i=0;igetInfoOnComponent(i); - tinyInfo.clear(); - tinyInfo.push_back(getType()); - tinyInfo.push_back(spaceDim); - tinyInfo.push_back(getNumberOfNodes()); - tinyInfo.push_back(it); - tinyInfo.push_back(order); - tinyInfoD.push_back(time); - } - else - { - littleStrings.resize(3); - littleStrings[0]=getName(); - littleStrings[1]=getDescription(); - littleStrings[2]=getTimeUnit(); - tinyInfo.clear(); - tinyInfo.push_back(getType()); - tinyInfo.push_back(-1); - tinyInfo.push_back(-1); - tinyInfo.push_back(it); - tinyInfo.push_back(order); - tinyInfoD.push_back(time); - } -} - -/*! - * Third and final step of serialization process. - */ -void MEDCouplingPointSet::serialize(DataArrayInt *&a1, DataArrayDouble *&a2) const -{ - if(_coords) - { - a2=const_cast(getCoords()); - a2->incrRef(); - } - else - a2=0; -} - -/*! - * Second step of serialization process. - * @param tinyInfo must be equal to the result given by getTinySerializationInformation method. - */ -void MEDCouplingPointSet::resizeForUnserialization(const std::vector& tinyInfo, DataArrayInt *a1, DataArrayDouble *a2, std::vector& littleStrings) const -{ - if(tinyInfo[2]>=0 && tinyInfo[1]>=1) - { - a2->alloc(tinyInfo[2],tinyInfo[1]); - littleStrings.resize(tinyInfo[1]+4); - } - else - { - littleStrings.resize(3); - } -} - -/*! - * Second and final unserialization process. - * @param tinyInfo must be equal to the result given by getTinySerializationInformation method. - */ -void MEDCouplingPointSet::unserialization(const std::vector& tinyInfoD, const std::vector& tinyInfo, const DataArrayInt *a1, DataArrayDouble *a2, const std::vector& littleStrings) -{ - if(tinyInfo[2]>=0 && tinyInfo[1]>=1) - { - setCoords(a2); - setName(littleStrings[0]); - setDescription(littleStrings[1]); - a2->setName(littleStrings[2]); - setTimeUnit(littleStrings[3]); - for(int i=0;isetInfoOnComponent(i,littleStrings[i+4]); - setTime(tinyInfoD[0],tinyInfo[3],tinyInfo[4]); - } - else - { - setName(littleStrings[0]); - setDescription(littleStrings[1]); - setTimeUnit(littleStrings[2]); - setTime(tinyInfoD[0],tinyInfo[3],tinyInfo[4]); - } -} - -void MEDCouplingPointSet::checkCoherency() const -{ - if(!_coords) - throw INTERP_KERNEL::Exception("MEDCouplingPointSet::checkCoherency : no coordinates set !"); -} - -/*! - * Intersect Bounding Box given 2 Bounding Boxes. - */ -bool MEDCouplingPointSet::intersectsBoundingBox(const double* bb1, const double* bb2, int dim, double eps) -{ - double* bbtemp = new double[2*dim]; - double deltamax=0.0; - - for (int i=0; i< dim; i++) - { - double delta = bb1[2*i+1]-bb1[2*i]; - if ( delta > deltamax ) - { - deltamax = delta ; - } - } - for (int i=0; i deltamax ) - { - deltamax = delta ; - } - } - for (int i=0; igetPointer(); - int nbNodes=getNumberOfNodes(); - Rotate3DAlg(center,vect,angle,nbNodes,coords); -} - -/*! - * Low static method that operates 3D rotation of 'nbNodes' 3D nodes whose coordinates are arranged in 'coords' - * around an axe ('center','vect') and with angle 'angle'. - */ -void MEDCouplingPointSet::Rotate3DAlg(const double *center, const double *vect, double angle, int nbNodes, double *coords) -{ - if(!center || !vect) - throw INTERP_KERNEL::Exception("MEDCouplingPointSet::Rotate3DAlg : null vector in input !"); - double sina=sin(angle); - double cosa=cos(angle); - double vectorNorm[3]; - 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; - matrixTmp[0]=vectorNorm[0]*vectorNorm[0]; matrixTmp[1]=vectorNorm[0]*vectorNorm[1]; matrixTmp[2]=vectorNorm[0]*vectorNorm[2]; - matrixTmp[3]=vectorNorm[1]*vectorNorm[0]; matrixTmp[4]=vectorNorm[1]*vectorNorm[1]; matrixTmp[5]=vectorNorm[1]*vectorNorm[2]; - matrixTmp[6]=vectorNorm[2]*vectorNorm[0]; matrixTmp[7]=vectorNorm[2]*vectorNorm[1]; matrixTmp[8]=vectorNorm[2]*vectorNorm[2]; - std::transform(matrixTmp,matrixTmp+9,matrixTmp,std::bind2nd(std::multiplies(),1-cosa)); - std::transform(matrix,matrix+9,matrixTmp,matrix,std::plus()); - matrixTmp[0]=0.; matrixTmp[1]=-vectorNorm[2]; matrixTmp[2]=vectorNorm[1]; - matrixTmp[3]=vectorNorm[2]; matrixTmp[4]=0.; matrixTmp[5]=-vectorNorm[0]; - matrixTmp[6]=-vectorNorm[1]; matrixTmp[7]=vectorNorm[0]; matrixTmp[8]=0.; - std::transform(matrixTmp,matrixTmp+9,matrixTmp,std::bind2nd(std::multiplies(),sina)); - std::transform(matrix,matrix+9,matrixTmp,matrix,std::plus()); - //rotation matrix computed. - double tmp[3]; - for(int i=0; i()); - coords[i*3]=matrix[0]*tmp[0]+matrix[1]*tmp[1]+matrix[2]*tmp[2]+center[0]; - coords[i*3+1]=matrix[3]*tmp[0]+matrix[4]*tmp[1]+matrix[5]*tmp[2]+center[1]; - coords[i*3+2]=matrix[6]*tmp[0]+matrix[7]*tmp[1]+matrix[8]*tmp[2]+center[2]; - } -} - -/*! - * This method allows to give for each cell in \a trgMesh, how much it interacts with cells of \a srcMesh. - * The returned array can be seen as a weighted array on the target cells of \a trgMesh input parameter. - * - * \param [in] srcMesh - source mesh - * \param [in] trgMesh - target mesh - * \param [in] eps - precision of the detection - * \return DataArrayInt * - An array that gives for each cell of \a trgMesh, how many cells in \a srcMesh (regarding the precision of detection \a eps) can interacts. - * - * \throw If \a srcMesh and \a trgMesh have not the same space dimension. - */ -DataArrayInt *MEDCouplingPointSet::ComputeNbOfInteractionsWithSrcCells(const MEDCouplingPointSet *srcMesh, const MEDCouplingPointSet *trgMesh, double eps) -{ - if(!srcMesh || !trgMesh) - throw INTERP_KERNEL::Exception("MEDCouplingPointSet::ComputeNbOfInteractionsWithSrcCells : the input meshes must be not NULL !"); - MEDCouplingAutoRefCountObjectPtr sbbox(srcMesh->getBoundingBoxForBBTree()),tbbox(trgMesh->getBoundingBoxForBBTree()); - return tbbox->computeNbOfInteractionsWith(sbbox,eps); -} - -/*! - * 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 -{ - return buildPartOfMySelf(start,end,true); -} - -/*! - * 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 -{ - MEDCouplingAutoRefCountObjectPtr ret=buildPartOfMySelf(start,end,true); - arr=ret->zipCoordsTraducer(); - return ret.retn(); -} - -/*! - * This method specialized the MEDCouplingMesh::buildPartRange. - * 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. - * \b WARNING , there is a big difference compared to MEDCouplingMesh::buildPart method. - * If the input range is equal all cells in \a this, \a this is returned ! - * - * \return a new ref to be managed by the caller. Warning this ref can be equal to \a this if input slice is exactly equal to the whole cells in the same order. - * - * \sa MEDCouplingUMesh::buildPartOfMySelf2 - */ -MEDCouplingMesh *MEDCouplingPointSet::buildPartRange(int beginCellIds, int endCellIds, int stepCellIds) const -{ - if(beginCellIds==0 && endCellIds==getNumberOfCells() && stepCellIds==1) - { - MEDCouplingMesh *ret(const_cast(this)); - ret->incrRef(); - return ret; - } - else - { - 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 -{ - 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' - */ -void MEDCouplingPointSet::rotate2D(const double *center, double angle) -{ - double *coords=_coords->getPointer(); - int nbNodes=getNumberOfNodes(); - Rotate2DAlg(center,angle,nbNodes,coords); -} - -/*! - * Low static method that operates 3D rotation of 'nbNodes' 3D nodes whose coordinates are arranged in 'coords' - * around the center point 'center' and with angle 'angle'. - */ -void MEDCouplingPointSet::Rotate2DAlg(const double *center, double angle, int nbNodes, double *coords) -{ - double cosa=cos(angle); - double sina=sin(angle); - double matrix[4]; - matrix[0]=cosa; matrix[1]=-sina; matrix[2]=sina; matrix[3]=cosa; - double tmp[2]; - for(int i=0; i()); - coords[i*2]=matrix[0]*tmp[0]+matrix[1]*tmp[1]+center[0]; - coords[i*2+1]=matrix[2]*tmp[0]+matrix[3]*tmp[1]+center[1]; - } -} - -/// @cond INTERNAL - -class DummyClsMCPS -{ -public: - static const int MY_SPACEDIM=3; - static const int MY_MESHDIM=2; - typedef int MyConnType; - static const INTERP_KERNEL::NumberingPolicy My_numPol=INTERP_KERNEL::ALL_C_MODE; -}; - -/// @endcond - -/*! - * res should be an empty vector before calling this method. - * This method returns all the node coordinates included in _coords which ids are in [startConn;endConn) and put it into 'res' vector. - * If spaceDim==3 a projection will be done for each nodes on the middle plane containing these all nodes in [startConn;endConn). - * And after each projected nodes are moved to Oxy plane in order to consider these nodes as 2D nodes. - */ -void MEDCouplingPointSet::project2DCellOnXY(const int *startConn, const int *endConn, std::vector& res) const -{ - const double *coords=_coords->getConstPointer(); - int spaceDim=getSpaceDimension(); - for(const int *it=startConn;it!=endConn;it++) - res.insert(res.end(),coords+spaceDim*(*it),coords+spaceDim*(*it+1)); - if(spaceDim==2) - return ; - if(spaceDim==3) - { - std::vector cpy(res); - int nbNodes=(int)std::distance(startConn,endConn); - INTERP_KERNEL::PlanarIntersector::Projection(&res[0],&cpy[0],nbNodes,nbNodes,1.e-12,0./*max distance*/,-1./*min dot*/,0.,true); - res.resize(2*nbNodes); - for(int i=0;i& res, bool isQuad, double eps) -{ - std::size_t nbOfNodes=res.size()/2; - std::vector nodes(nbOfNodes); - for(std::size_t i=0;iisButterflyAbs(); - delete pol; - return ret; -} - -/*! - * This method compares 2 cells coming from two unstructured meshes : \a this and \a other. - * This method compares 2 cells having the same id 'cellId' in \a this and \a other. - */ -bool MEDCouplingPointSet::areCellsFrom2MeshEqual(const MEDCouplingPointSet *other, int cellId, double prec) const -{ - if(getTypeOfCell(cellId)!=other->getTypeOfCell(cellId)) - return false; - std::vector c1,c2; - getNodeIdsOfCell(cellId,c1); - other->getNodeIdsOfCell(cellId,c2); - std::size_t sz=c1.size(); - if(sz!=c2.size()) - return false; - for(std::size_t i=0;i n1,n2; - getCoordinatesOfNode(c1[0],n1); - other->getCoordinatesOfNode(c2[0],n2); - std::transform(n1.begin(),n1.end(),n2.begin(),n1.begin(),std::minus()); - std::transform(n1.begin(),n1.end(),n1.begin(),std::ptr_fun(fabs)); - if(*std::max_element(n1.begin(),n1.end())>prec) - return false; - } - return true; -} - -/*! - * Substitutes node coordinates array of \a this mesh with that of \a other mesh - * (i.e. \a this->_coords with \a other._coords) provided that coordinates of the two - * meshes match with a specified precision, else an exception is thrown and \a this - * remains unchanged. In case of success the nodal connectivity of \a this mesh - * is permuted according to new order of nodes. - * Contrary to tryToShareSameCoords() this method makes a deeper analysis of - * coordinates (and so more expensive) than simple equality. - * \param [in] other - the other mesh whose node coordinates array will be used by - * \a this mesh in case of their equality. - * \param [in] epsilon - the precision used to compare coordinates (using infinite norm). - * \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::tryToShareSameCoordsPermute(const MEDCouplingPointSet& other, double epsilon) -{ - const DataArrayDouble *coords=other.getCoords(); - if(!coords) - throw INTERP_KERNEL::Exception("MEDCouplingPointSet::tryToShareSameCoordsPermute : No coords specified in other !"); - if(!_coords) - throw INTERP_KERNEL::Exception("MEDCouplingPointSet::tryToShareSameCoordsPermute : No coords specified in this whereas there is any in other !"); - int otherNbOfNodes=other.getNumberOfNodes(); - MEDCouplingAutoRefCountObjectPtr newCoords=MergeNodesArray(&other,this); - _coords->incrRef(); - MEDCouplingAutoRefCountObjectPtr oldCoords=_coords; - setCoords(newCoords); - bool areNodesMerged; - int newNbOfNodes; - MEDCouplingAutoRefCountObjectPtr da=buildPermArrayForMergeNode(epsilon,otherNbOfNodes,areNodesMerged,newNbOfNodes); - if(!areNodesMerged) - { - setCoords(oldCoords); - throw INTERP_KERNEL::Exception("MEDCouplingPointSet::tryToShareSameCoordsPermute fails : no nodes are mergeable with specified given epsilon !"); - } - int maxId=*std::max_element(da->getConstPointer(),da->getConstPointer()+otherNbOfNodes); - const int *pt=std::find_if(da->getConstPointer()+otherNbOfNodes,da->getConstPointer()+da->getNbOfElems(),std::bind2nd(std::greater(),maxId)); - if(pt!=da->getConstPointer()+da->getNbOfElems()) - { - setCoords(oldCoords); - throw INTERP_KERNEL::Exception("MEDCouplingPointSet::tryToShareSameCoordsPermute fails : some nodes in this are not in other !"); - } - setCoords(oldCoords); - renumberNodesInConn(da->getConstPointer()+otherNbOfNodes); - setCoords(coords); -} - -MEDCouplingPointSet *MEDCouplingPointSet::buildPartOfMySelf(const int *begin, const int *end, bool keepCoords) const -{ - MEDCouplingAutoRefCountObjectPtr ret=buildPartOfMySelfKeepCoords(begin,end); - if(!keepCoords) - ret->zipCoords(); - return ret.retn(); -} - -MEDCouplingPointSet *MEDCouplingPointSet::buildPartOfMySelf2(int start, int end, int step, bool keepCoords) const -{ - MEDCouplingAutoRefCountObjectPtr ret=buildPartOfMySelfKeepCoords2(start,end,step); - if(!keepCoords) - ret->zipCoords(); - return ret.retn(); -} - -/*! - Creates a new MEDCouplingUMesh containing some cells of \a this mesh. The cells to - copy are selected basing on specified node ids and the value of \a fullyIn - parameter. If \a fullyIn ==\c true, a cell is copied if its all nodes are in the - array \a begin of node ids. If \a fullyIn ==\c false, a cell is copied if any its - node is in the array of node ids. The created mesh shares the node coordinates array - with \a this mesh. - * \param [in] begin - the array of node ids. - * \param [in] end - a pointer to the (last+1)-th element of \a begin. - * \param [in] fullyIn - if \c true, then cells whose all nodes are in the - * array \a begin are copied, else cells whose any node is in the - * array \a begin are copied. - * \return MEDCouplingPointSet * - 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 not defined. - * \throw If any node id in \a begin is not valid. - * - * \if ENABLE_EXAMPLES - * \ref cpp_mcumesh_buildPartOfMySelfNode "Here is a C++ example".
- * \ref py_mcumesh_buildPartOfMySelfNode "Here is a Python example". - * \endif - */ -MEDCouplingPointSet *MEDCouplingPointSet::buildPartOfMySelfNode(const int *begin, const int *end, bool fullyIn) const -{ - DataArrayInt *cellIdsKept=0; - fillCellIdsToKeepFromNodeIds(begin,end,fullyIn,cellIdsKept); - MEDCouplingAutoRefCountObjectPtr cellIdsKept2(cellIdsKept); - return buildPartOfMySelf(cellIdsKept->begin(),cellIdsKept->end(),true); -} - -/*! - * Removes duplicates of cells from \a this mesh and returns an array mapping between - * new and old cell ids in "Old to New" mode. Nothing is changed in \a this mesh if no - * equal cells found. - * \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] compType - specifies a cell comparison technique. Meaning of its - * valid values [0,1,2] is as follows. - * - 0 : "exact". Two cells are considered equal \c iff they have exactly same nodal - * connectivity and type. This is the strongest policy. - * - 1 : "permuted same orientation". Two cells are considered equal \c iff they - * are based on same nodes and have the same type and orientation. - * - 2 : "nodal". Two cells are considered equal \c iff they - * are based on same nodes and have the same type. This is the weakest - * policy, it can be used by users not sensitive to cell orientation. - * \param [in] startCellId - specifies the cell id at which search for equal cells - * starts. By default it is 0, which means that all cells in \a this will be - * scanned. - * \return DataArrayInt - a new instance of DataArrayInt, of length \a - * this->getNumberOfCells() before call of this method. The caller is to - * delete this array using decrRef() as it is no more needed. - * \throw If the coordinates array is not set. - * \throw If the nodal connectivity of cells is not defined. - * \throw If the nodal connectivity includes an invalid id. - * - * \if ENABLE_EXAMPLES - * \ref cpp_mcumesh_zipConnectivityTraducer "Here is a C++ example".
- * \ref py_mcumesh_zipConnectivityTraducer "Here is a Python example". - * \endif - */ -DataArrayInt *MEDCouplingPointSet::zipConnectivityTraducer(int compType, int startCellId) -{ - DataArrayInt *commonCells=0,*commonCellsI=0; - findCommonCells(compType,startCellId,commonCells,commonCellsI); - MEDCouplingAutoRefCountObjectPtr commonCellsTmp(commonCells),commonCellsITmp(commonCellsI); - int newNbOfCells=-1; - MEDCouplingAutoRefCountObjectPtr ret=DataArrayInt::BuildOld2NewArrayFromSurjectiveFormat2(getNumberOfCells(),commonCells->begin(),commonCellsI->begin(), - commonCellsI->end(),newNbOfCells); - MEDCouplingAutoRefCountObjectPtr ret2=ret->invertArrayO2N2N2O(newNbOfCells); - MEDCouplingAutoRefCountObjectPtr self=buildPartOfMySelf(ret2->begin(),ret2->end(),true); - shallowCopyConnectivityFrom(self); - return ret.retn(); -} - -/*! - * This const method states if the nodal connectivity of this fetches all nodes in \a this. - * In other words, this method looks is there are no orphan nodes in \a this. - * \sa zipCoordsTraducer, getNodeIdsInUse, computeFetchedNodeIds. - */ -bool MEDCouplingPointSet::areAllNodesFetched() const -{ - checkFullyDefined(); - int nbNodes(getNumberOfNodes()); - std::vector fetchedNodes(nbNodes,false); - computeNodeIdsAlg(fetchedNodes); - return std::find(fetchedNodes.begin(),fetchedNodes.end(),false)==fetchedNodes.end(); -} - -/*! - * 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 MEDCouplingPointSet::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. - * - * \if ENABLE_EXAMPLES - * \ref cpp_mcumesh_checkDeepEquivalWith "Here is a C++ example".
- * \ref py_mcumesh_checkDeepEquivalWith "Here is a Python example". - * \endif - */ -void MEDCouplingPointSet::checkDeepEquivalWith(const MEDCouplingMesh *other, int cellCompPol, double prec, - DataArrayInt *&cellCor, DataArrayInt *&nodeCor) const -{ - if(!other) - throw INTERP_KERNEL::Exception("MEDCouplingPointSet::checkDeepEquivalWith : input is null !"); - const MEDCouplingPointSet *otherC=dynamic_cast(other); - if(!otherC) - throw INTERP_KERNEL::Exception("MEDCouplingPointSet::checkDeepEquivalWith : other is not a PointSet mesh !"); - MEDCouplingAutoRefCountObjectPtr m=dynamic_cast(mergeMyselfWith(otherC)); - bool areNodesMerged; - int newNbOfNodes; - int oldNbOfNodes=getNumberOfNodes(); - MEDCouplingAutoRefCountObjectPtr da=m->buildPermArrayForMergeNode(prec,oldNbOfNodes,areNodesMerged,newNbOfNodes); - //mergeNodes - if(!areNodesMerged && oldNbOfNodes != 0) - throw INTERP_KERNEL::Exception("checkDeepEquivalWith : Nodes are incompatible ! "); - const int *pt=std::find_if(da->getConstPointer()+oldNbOfNodes,da->getConstPointer()+da->getNbOfElems(),std::bind2nd(std::greater(),oldNbOfNodes-1)); - if(pt!=da->getConstPointer()+da->getNbOfElems()) - throw INTERP_KERNEL::Exception("checkDeepEquivalWith : some nodes in other are not in this !"); - m->renumberNodes(da->getConstPointer(),newNbOfNodes); - // - MEDCouplingAutoRefCountObjectPtr nodeCor2=da->substr(oldNbOfNodes); - da=m->mergeNodes(prec,areNodesMerged,newNbOfNodes); - // - da=m->zipConnectivityTraducer(cellCompPol); - int nbCells=getNumberOfCells(); - if (nbCells != other->getNumberOfCells()) - throw INTERP_KERNEL::Exception("checkDeepEquivalWith : some cells in other are not in this !"); - int dan(da->getNumberOfTuples()); - if (dan) - { - MEDCouplingAutoRefCountObjectPtr da1(DataArrayInt::New()),da2(DataArrayInt::New()); - da1->alloc(dan/2,1); da2->alloc(dan/2,1); - std::copy(da->getConstPointer(), da->getConstPointer()+dan/2, da1->getPointer()); - std::copy(da->getConstPointer()+dan/2, da->getConstPointer()+dan, da2->getPointer()); - da1->sort(); da2->sort(); - if (!da1->isEqualWithoutConsideringStr(*da2)) - throw INTERP_KERNEL::Exception("checkDeepEquivalWith : some cells in other are not in 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 MEDCouplingPointSet::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. - * - * \if ENABLE_EXAMPLES - * \ref cpp_mcumesh_checkDeepEquivalWith "Here is a C++ example".
- * \ref py_mcumesh_checkDeepEquivalWith "Here is a Python example". - * \endif - */ -void MEDCouplingPointSet::checkDeepEquivalOnSameNodesWith(const MEDCouplingMesh *other, int cellCompPol, double prec, - DataArrayInt *&cellCor) const -{ - if(!other) - throw INTERP_KERNEL::Exception("MEDCouplingPointSet::checkDeepEquivalOnSameNodesWith : input is null !"); - const MEDCouplingPointSet *otherC=dynamic_cast(other); - if(!otherC) - throw INTERP_KERNEL::Exception("MEDCouplingPointSet::checkDeepEquivalOnSameNodesWith : other is not a PointSet mesh !"); - if(_coords!=otherC->_coords) - throw INTERP_KERNEL::Exception("checkDeepEquivalOnSameNodesWith : meshes do not share the same coordinates ! Use tryToShareSameCoordinates or call checkDeepEquivalWith !"); - MEDCouplingAutoRefCountObjectPtr m=mergeMyselfWithOnSameCoords(otherC); - MEDCouplingAutoRefCountObjectPtr da=m->zipConnectivityTraducer(cellCompPol); - int maxId=*std::max_element(da->getConstPointer(),da->getConstPointer()+getNumberOfCells()); - const int *pt=std::find_if(da->getConstPointer()+getNumberOfCells(),da->getConstPointer()+da->getNbOfElems(),std::bind2nd(std::greater(),maxId)); - if(pt!=da->getConstPointer()+da->getNbOfElems()) - { - throw INTERP_KERNEL::Exception("checkDeepEquivalOnSameNodesWith : some cells in other are not in this !"); - } - MEDCouplingAutoRefCountObjectPtr cellCor2=da->selectByTupleId2(getNumberOfCells(),da->getNbOfElems(),1); - cellCor=cellCor2->isIdentity()?0:cellCor2.retn(); -} - -void MEDCouplingPointSet::checkFastEquivalWith(const MEDCouplingMesh *other, double prec) const -{ - MEDCouplingMesh::checkFastEquivalWith(other,prec); - //other not null checked by the line before - const MEDCouplingPointSet *otherC=dynamic_cast(other); - if(!otherC) - throw INTERP_KERNEL::Exception("MEDCouplingPointSet::checkFastEquivalWith : fails because other is not a pointset mesh !"); - int nbOfCells=getNumberOfCells(); - if(nbOfCells<1) - return ; - bool status=true; - status&=areCellsFrom2MeshEqual(otherC,0,prec); - status&=areCellsFrom2MeshEqual(otherC,nbOfCells/2,prec); - status&=areCellsFrom2MeshEqual(otherC,nbOfCells-1,prec); - if(!status) - throw INTERP_KERNEL::Exception("checkFastEquivalWith : Two meshes are not equal because on 3 test cells some difference have been detected !"); -} - -/*! - * Finds cells whose all or some nodes are in a given array of node ids. - * \param [in] begin - the array of node ids. - * \param [in] end - a pointer to the (last+1)-th element of \a begin. - * \param [in] fullyIn - if \c true, then cells whose all nodes are in the - * array \a begin are returned only, else cells whose any node is in the - * array \a begin are returned. - * \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. - * \throw If the coordinates array is not set. - * \throw If the nodal connectivity of cells is not defined. - * \throw If any cell id in \a begin is not valid. - * - * \sa MEDCouplingPointSet::getCellIdsFullyIncludedInNodeIds - * - * \if ENABLE_EXAMPLES - * \ref cpp_mcumesh_getCellIdsLyingOnNodes "Here is a C++ example".
- * \ref py_mcumesh_getCellIdsLyingOnNodes "Here is a Python example". - * \endif - */ -DataArrayInt *MEDCouplingPointSet::getCellIdsLyingOnNodes(const int *begin, const int *end, bool fullyIn) const -{ - DataArrayInt *cellIdsKept=0; - fillCellIdsToKeepFromNodeIds(begin,end,fullyIn,cellIdsKept); - cellIdsKept->setName(getName()); - return cellIdsKept; -} - -/*! - * Finds cells whose all nodes are in a given array of node ids. - * This method is a specialization of MEDCouplingPointSet::getCellIdsLyingOnNodes (true - * as last input argument). - * \param [in] partBg - the array of node ids. - * \param [in] partEnd - 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. - * \throw If the coordinates array is not set. - * \throw If the nodal connectivity of cells is not defined. - * \throw If any cell id in \a partBg is not valid. - * - * \sa MEDCouplingPointSet::getCellIdsLyingOnNodes - * - * \if ENABLE_EXAMPLES - * \ref cpp_mcumesh_getCellIdsFullyIncludedInNodeIds "Here is a C++ example".
- * \ref py_mcumesh_getCellIdsFullyIncludedInNodeIds "Here is a Python example". - * \endif - */ -DataArrayInt *MEDCouplingPointSet::getCellIdsFullyIncludedInNodeIds(const int *partBg, const int *partEnd) const -{ - return getCellIdsLyingOnNodes(partBg,partEnd,true); -} - -/*! - * Removes unused nodes (the node coordinates array is shorten) and returns an array - * mapping between new and old node ids in "Old to New" mode. -1 values in the returned - * array mean that the corresponding old node is no more used. - * \return DataArrayInt * - a new instance of DataArrayInt of length \a - * this->getNumberOfNodes() before call of this method. The caller is to - * delete this array using decrRef() as it is no more needed. - * \throw If the coordinates array is not set. - * \throw If the nodal connectivity of cells is not defined. - * \throw If the nodal connectivity includes an invalid id. - * - * \if ENABLE_EXAMPLES - * \ref cpp_mcumesh_zipCoordsTraducer "Here is a C++ example".
- * \ref py_mcumesh_zipCoordsTraducer "Here is a Python example". - * \endif - */ -DataArrayInt *MEDCouplingPointSet::zipCoordsTraducer() -{ - int newNbOfNodes=-1; - MEDCouplingAutoRefCountObjectPtr traducer=getNodeIdsInUse(newNbOfNodes); - renumberNodes(traducer->getConstPointer(),newNbOfNodes); - return traducer.retn(); -} - -/*! - * Merges nodes equal within \a precision and returns an array describing the - * permutation used to remove duplicate nodes. - * \param [in] precision - minimal absolute distance between two nodes at which they are - * considered not coincident. - * \param [out] areNodesMerged - is set to \c true if any coincident nodes removed. - * \param [out] newNbOfNodes - number of nodes remaining after the removal. - * \return DataArrayInt * - the permutation array in "Old to New" mode. For more - * info on "Old to New" mode see \ref numbering. The caller - * is to delete this array using decrRef() as it is no more needed. - * \throw If the coordinates array is not set. - * \throw If the nodal connectivity of cells is not defined. - * - * \if ENABLE_EXAMPLES - * \ref cpp_mcumesh_mergeNodes "Here is a C++ example".
- * \ref py_mcumesh_mergeNodes "Here is a Python example". - * \endif - */ -DataArrayInt *MEDCouplingPointSet::mergeNodes(double precision, bool& areNodesMerged, int& newNbOfNodes) -{ - MEDCouplingAutoRefCountObjectPtr ret=buildPermArrayForMergeNode(precision,-1,areNodesMerged,newNbOfNodes); - if(areNodesMerged) - renumberNodes(ret->begin(),newNbOfNodes); - return ret.retn(); -} - -/*! - * Merges nodes equal within \a precision and returns an array describing the - * permutation used to remove duplicate nodes. In contrast to mergeNodes(), location - * of merged nodes is changed to be at their barycenter. - * \param [in] precision - minimal absolute distance between two nodes at which they are - * considered not coincident. - * \param [out] areNodesMerged - is set to \c true if any coincident nodes removed. - * \param [out] newNbOfNodes - number of nodes remaining after the removal. - * \return DataArrayInt * - the permutation array in "Old to New" mode. For more - * info on "Old to New" mode see \ref numbering. The caller - * is to delete this array using decrRef() as it is no more needed. - * \throw If the coordinates array is not set. - * \throw If the nodal connectivity of cells is not defined. - * - * \if ENABLE_EXAMPLES - * \ref cpp_mcumesh_mergeNodes "Here is a C++ example".
- * \ref py_mcumesh_mergeNodes "Here is a Python example". - * \endif - */ -DataArrayInt *MEDCouplingPointSet::mergeNodes2(double precision, bool& areNodesMerged, int& newNbOfNodes) -{ - DataArrayInt *ret=buildPermArrayForMergeNode(precision,-1,areNodesMerged,newNbOfNodes); - if(areNodesMerged) - renumberNodes2(ret->getConstPointer(),newNbOfNodes); - return ret; -} diff --git a/src/MEDCoupling/MEDCouplingPointSet.hxx b/src/MEDCoupling/MEDCouplingPointSet.hxx deleted file mode 100644 index 21c830d2f..000000000 --- a/src/MEDCoupling/MEDCouplingPointSet.hxx +++ /dev/null @@ -1,162 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 -// 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_MEDCOUPLINGPOINTSET_HXX__ -#define __PARAMEDMEM_MEDCOUPLINGPOINTSET_HXX__ - -#include "MEDCoupling.hxx" -#include "MEDCouplingMesh.hxx" - -#include "InterpKernelHashMap.hxx" - -#include - -namespace INTERP_KERNEL -{ - class DirectedBoundingBox; -} - -namespace ParaMEDMEM -{ - class DataArrayInt; - class DataArrayDouble; - - /*! - * This class is abstract and not instanciable. - * ParaMEDMEM::MEDCouplingUMesh class inherits from this class. - * This class aggregates an array '_coords' containing nodes coordinates. - * So all operations on coordinates are managed by this class. - * This is the case for example for following methods : - * rotation, translation, scaling, getNodeIdsNearPoint, boundingbox... - */ - class MEDCouplingPointSet : public MEDCouplingMesh - { - protected: - MEDCOUPLING_EXPORT MEDCouplingPointSet(); - MEDCOUPLING_EXPORT MEDCouplingPointSet(const MEDCouplingPointSet& other, bool deepCopy); - MEDCOUPLING_EXPORT ~MEDCouplingPointSet(); - public: - MEDCOUPLING_EXPORT void updateTime() const; - MEDCOUPLING_EXPORT std::size_t getHeapMemorySizeWithoutChildren() const; - MEDCOUPLING_EXPORT std::vector getDirectChildrenWithNull() const; - MEDCOUPLING_EXPORT int getNumberOfNodes() const; - MEDCOUPLING_EXPORT int getSpaceDimension() const; - MEDCOUPLING_EXPORT void setCoords(const DataArrayDouble *coords); - MEDCOUPLING_EXPORT const DataArrayDouble *getCoords() const { return _coords; } - MEDCOUPLING_EXPORT DataArrayDouble *getCoords() { return _coords; } - MEDCOUPLING_EXPORT DataArrayDouble *getCoordinatesAndOwner() const; - MEDCOUPLING_EXPORT void copyTinyStringsFrom(const MEDCouplingMesh *other); - MEDCOUPLING_EXPORT bool isEqualIfNotWhy(const MEDCouplingMesh *other, double prec, std::string& reason) const; - MEDCOUPLING_EXPORT bool isEqualWithoutConsideringStr(const MEDCouplingMesh *other, double prec) const; - MEDCOUPLING_EXPORT void checkFastEquivalWith(const MEDCouplingMesh *other, double prec) const; - MEDCOUPLING_EXPORT void checkDeepEquivalWith(const MEDCouplingMesh *other, int cellCompPol, double prec, - DataArrayInt *&cellCor, DataArrayInt *&nodeCor) const; - MEDCOUPLING_EXPORT void checkDeepEquivalOnSameNodesWith(const MEDCouplingMesh *other, int cellCompPol, double prec, - DataArrayInt *&cellCor) const; - MEDCOUPLING_EXPORT bool areCoordsEqualIfNotWhy(const MEDCouplingPointSet& other, double prec, std::string& reason) const; - MEDCOUPLING_EXPORT bool areCoordsEqual(const MEDCouplingPointSet& other, double prec) const; - MEDCOUPLING_EXPORT bool areCoordsEqualWithoutConsideringStr(const MEDCouplingPointSet& other, double prec) const; - MEDCOUPLING_EXPORT virtual MEDCouplingPointSet *deepCpyConnectivityOnly() const = 0; - MEDCOUPLING_EXPORT virtual void shallowCopyConnectivityFrom(const MEDCouplingPointSet *other) = 0; - MEDCOUPLING_EXPORT virtual DataArrayInt *mergeNodes(double precision, bool& areNodesMerged, int& newNbOfNodes); - MEDCOUPLING_EXPORT virtual DataArrayInt *mergeNodes2(double precision, bool& areNodesMerged, int& newNbOfNodes); - MEDCOUPLING_EXPORT virtual MEDCouplingPointSet *mergeMyselfWithOnSameCoords(const MEDCouplingPointSet *other) const = 0; - MEDCOUPLING_EXPORT virtual void computeNodeIdsAlg(std::vector& nodeIdsInUse) const = 0; - MEDCOUPLING_EXPORT void getCoordinatesOfNode(int nodeId, std::vector& coo) const; - MEDCOUPLING_EXPORT DataArrayInt *buildPermArrayForMergeNode(double precision, int limitNodeId, bool& areNodesMerged, int& newNbOfNodes) const; - MEDCOUPLING_EXPORT DataArrayInt *getNodeIdsNearPoint(const double *pos, double eps) const; - MEDCOUPLING_EXPORT void getNodeIdsNearPoints(const double *pos, int nbOfPoints, double eps, DataArrayInt *& c, DataArrayInt *& cI) const; - MEDCOUPLING_EXPORT void findCommonNodes(double prec, int limitNodeId, DataArrayInt *&comm, DataArrayInt *&commIndex) const; - MEDCOUPLING_EXPORT virtual void findCommonCells(int compType, int startCellId, DataArrayInt *& commonCellsArr, DataArrayInt *& commonCellsIArr) const = 0; - MEDCOUPLING_EXPORT DataArrayInt *buildNewNumberingFromCommonNodesFormat(const DataArrayInt *comm, const DataArrayInt *commIndex, - int& newNbOfNodes) const; - MEDCOUPLING_EXPORT void getBoundingBox(double *bbox) const; - MEDCOUPLING_EXPORT void zipCoords(); - MEDCOUPLING_EXPORT double getCaracteristicDimension() const; - MEDCOUPLING_EXPORT void recenterForMaxPrecision(double eps); - MEDCOUPLING_EXPORT void rotate(const double *center, const double *vector, double angle); - MEDCOUPLING_EXPORT void translate(const double *vector); - MEDCOUPLING_EXPORT void scale(const double *point, double factor); - MEDCOUPLING_EXPORT void changeSpaceDimension(int newSpaceDim, double dftVal=0.); - MEDCOUPLING_EXPORT void tryToShareSameCoords(const MEDCouplingPointSet& other, double epsilon); - MEDCOUPLING_EXPORT void duplicateNodesInCoords(const int *nodeIdsToDuplicateBg, const int *nodeIdsToDuplicateEnd); - MEDCOUPLING_EXPORT virtual void tryToShareSameCoordsPermute(const MEDCouplingPointSet& other, double epsilon); - MEDCOUPLING_EXPORT void findNodesOnPlane(const double *pt, const double *vec, double eps, std::vector& nodes) const; - MEDCOUPLING_EXPORT void findNodesOnLine(const double *pt, const double *vec, double eps, std::vector& nodes) const; - MEDCOUPLING_EXPORT static DataArrayDouble *MergeNodesArray(const MEDCouplingPointSet *m1, const MEDCouplingPointSet *m2); - MEDCOUPLING_EXPORT static DataArrayDouble *MergeNodesArray(const std::vector& ms); - MEDCOUPLING_EXPORT static MEDCouplingPointSet *BuildInstanceFromMeshType(MEDCouplingMeshType type); - MEDCOUPLING_EXPORT static void Rotate2DAlg(const double *center, double angle, int nbNodes, double *coords); - MEDCOUPLING_EXPORT static void Rotate3DAlg(const double *center, const double *vect, double angle, int nbNodes, double *coords); - MEDCOUPLING_EXPORT static DataArrayInt *ComputeNbOfInteractionsWithSrcCells(const MEDCouplingPointSet *srcMesh, const MEDCouplingPointSet *trgMesh, double eps); - MEDCOUPLING_EXPORT MEDCouplingMesh *buildPart(const int *start, const int *end) const; - MEDCOUPLING_EXPORT MEDCouplingMesh *buildPartAndReduceNodes(const int *start, const int *end, DataArrayInt*& arr) const; - MEDCOUPLING_EXPORT MEDCouplingMesh *buildPartRange(int beginCellIds, int endCellIds, int stepCellIds) const; - MEDCOUPLING_EXPORT MEDCouplingMesh *buildPartRangeAndReduceNodes(int beginCellIds, int endCellIds, int stepCellIds, int& beginOut, int& endOut, int& stepOut, DataArrayInt*& arr) const; - MEDCOUPLING_EXPORT DataArrayInt *getCellIdsFullyIncludedInNodeIds(const int *partBg, const int *partEnd) const; - MEDCOUPLING_EXPORT DataArrayInt *getCellIdsLyingOnNodes(const int *begin, const int *end, bool fullyIn) const; - MEDCOUPLING_EXPORT virtual MEDCouplingPointSet *buildPartOfMySelf(const int *start, const int *end, bool keepCoords=true) const; - MEDCOUPLING_EXPORT virtual MEDCouplingPointSet *buildPartOfMySelf2(int start, int end, int step, bool keepCoords=true) const; - MEDCOUPLING_EXPORT virtual MEDCouplingPointSet *buildPartOfMySelfKeepCoords(const int *begin, const int *end) const = 0; - MEDCOUPLING_EXPORT virtual MEDCouplingPointSet *buildPartOfMySelfKeepCoords2(int start, int end, int step) const = 0; - MEDCOUPLING_EXPORT virtual MEDCouplingPointSet *buildPartOfMySelfNode(const int *start, const int *end, bool fullyIn) const; - MEDCOUPLING_EXPORT virtual MEDCouplingPointSet *buildFacePartOfMySelfNode(const int *start, const int *end, bool fullyIn) const = 0; - MEDCOUPLING_EXPORT virtual DataArrayInt *findBoundaryNodes() const = 0; - MEDCOUPLING_EXPORT virtual MEDCouplingPointSet *buildBoundaryMesh(bool keepCoords) const = 0; - MEDCOUPLING_EXPORT virtual int getNumberOfNodesInCell(int cellId) const = 0; - MEDCOUPLING_EXPORT virtual DataArrayInt *computeFetchedNodeIds() const = 0; - MEDCOUPLING_EXPORT virtual DataArrayInt *getNodeIdsInUse(int& nbrOfNodesInUse) const = 0; - MEDCOUPLING_EXPORT virtual void fillCellIdsToKeepFromNodeIds(const int *begin, const int *end, bool fullyIn, DataArrayInt *&cellIdsKeptArr) const = 0; - MEDCOUPLING_EXPORT virtual void renumberNodesInConn(const int *newNodeNumbersO2N) = 0; - MEDCOUPLING_EXPORT virtual void renumberNodesInConn(const INTERP_KERNEL::HashMap& newNodeNumbersO2N) = 0; - MEDCOUPLING_EXPORT virtual void renumberNodesWithOffsetInConn(int offset) = 0; - MEDCOUPLING_EXPORT virtual void renumberNodes(const int *newNodeNumbers, int newNbOfNodes); - MEDCOUPLING_EXPORT virtual void renumberNodes2(const int *newNodeNumbers, int newNbOfNodes); - MEDCOUPLING_EXPORT virtual bool isEmptyMesh(const std::vector& tinyInfo) const = 0; - MEDCOUPLING_EXPORT virtual void checkFullyDefined() const = 0; - MEDCOUPLING_EXPORT void getTinySerializationInformation(std::vector& tinyInfoD, std::vector& tinyInfo, std::vector& littleStrings) const; - MEDCOUPLING_EXPORT void resizeForUnserialization(const std::vector& tinyInfo, DataArrayInt *a1, DataArrayDouble *a2, std::vector& littleStrings) const; - MEDCOUPLING_EXPORT void serialize(DataArrayInt *&a1, DataArrayDouble *&a2) const; - MEDCOUPLING_EXPORT void unserialization(const std::vector& tinyInfoD, const std::vector& tinyInfo, const DataArrayInt *a1, DataArrayDouble *a2, - const std::vector& littleStrings); - MEDCOUPLING_EXPORT virtual DataArrayDouble *getBoundingBoxForBBTree(double arcDetEps=1e-12) const = 0; - MEDCOUPLING_EXPORT virtual DataArrayInt *getCellsInBoundingBox(const double *bbox, double eps) const = 0; - MEDCOUPLING_EXPORT virtual DataArrayInt *getCellsInBoundingBox(const INTERP_KERNEL::DirectedBoundingBox& bbox, double eps) = 0; - MEDCOUPLING_EXPORT virtual MEDCouplingFieldDouble *computeDiameterField() const = 0; - MEDCOUPLING_EXPORT virtual DataArrayInt *zipCoordsTraducer(); - MEDCOUPLING_EXPORT virtual DataArrayInt *zipConnectivityTraducer(int compType, int startCellId=0); - MEDCOUPLING_EXPORT virtual bool areAllNodesFetched() const; - //tools - public: - MEDCOUPLING_EXPORT bool areCellsFrom2MeshEqual(const MEDCouplingPointSet *other, int cellId, double prec) const; - protected: - MEDCOUPLING_EXPORT void checkCoherency() const; - MEDCOUPLING_EXPORT static bool intersectsBoundingBox(const double* bb1, const double* bb2, int dim, double eps); - MEDCOUPLING_EXPORT static bool intersectsBoundingBox(const INTERP_KERNEL::DirectedBoundingBox& bb1, const double* bb2, int dim, double eps); - MEDCOUPLING_EXPORT void rotate2D(const double *center, double angle); - MEDCOUPLING_EXPORT void rotate3D(const double *center, const double *vect, double angle); - MEDCOUPLING_EXPORT void project2DCellOnXY(const int *startConn, const int *endConn, std::vector& res) const; - MEDCOUPLING_EXPORT static bool isButterfly2DCell(const std::vector& res, bool isQuad, double eps); - protected: - DataArrayDouble *_coords; - }; -} - -#endif diff --git a/src/MEDCoupling/MEDCouplingRefCountObject.cxx b/src/MEDCoupling/MEDCouplingRefCountObject.cxx deleted file mode 100644 index ed44ff223..000000000 --- a/src/MEDCoupling/MEDCouplingRefCountObject.cxx +++ /dev/null @@ -1,275 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 -// 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 "MEDCouplingRefCountObject.hxx" -#include "MED_version.h" - -#include -#include - -using namespace ParaMEDMEM; - -const char *ParaMEDMEM::MEDCouplingVersionStr() -{ - return SALOMEMED_VERSION_STR; -} - -int ParaMEDMEM::MEDCouplingVersion() -{ - return SALOMEMED_VERSION; -} - -void ParaMEDMEM::MEDCouplingVersionMajMinRel(int& maj, int& minor, int& releas) -{ - int ver=SALOMEMED_VERSION; - maj=(ver & 0xFF0000) >> 16; - minor=(ver & 0xFF00) >> 8; - releas=(ver & 0xFF); -} - -int ParaMEDMEM::MEDCouplingSizeOfVoidStar() -{ - return 8*sizeof(std::size_t); -} - -/*! - * If true is returned it is a LittleEndian machine. - * If false it is a BigEndian machine. - * \return the coding mode of integers of the machine. - */ -bool ParaMEDMEM::MEDCouplingByteOrder() -{ - unsigned int x(1); - unsigned char *xc(reinterpret_cast(&x)); - return xc[0]==1; -} - -const char *ParaMEDMEM::MEDCouplingByteOrderStr() -{ - static const char LITTLEENDIAN_STR[]="LittleEndian"; - static const char BIGENDIAN_STR[]="BigEndian"; - if(MEDCouplingByteOrder()) - return LITTLEENDIAN_STR; - else - return BIGENDIAN_STR; -} - -//= - -std::size_t BigMemoryObject::getHeapMemorySize() const -{ - std::size_t ret(getHeapMemorySizeWithoutChildren()); - std::vector v(getDirectChildren()); - std::set s1,s2(v.begin(),v.end()); - return ret+GetHeapMemoryOfSet(s1,s2); -} - -/*! - * This method returns all the progeny of \a this (this is \b not included in returned vector). - * All the progeny means all the subobjects (children), subsubobjects (little children), ... of \a this. - * The elements in returned array are reported only once even if they appear several times in the progeny of \a this. - */ -std::vector BigMemoryObject::getAllTheProgeny() const -{ - std::vector s1(getDirectChildren()); - std::vector ret; - while(!s1.empty()) - { - ret.insert(ret.end(),s1.begin(),s1.end()); - std::vector s3; - for(std::vector::const_iterator it0=s1.begin();it0!=s1.end();it0++) - { - std::vector s2; - if(*it0) - s2=(*it0)->getDirectChildren(); - for(std::vector::const_iterator it1=s2.begin();it1!=s2.end();it1++) - { - if(*it1) - if(std::find(ret.begin(),ret.end(),*it1)==ret.end()) - s3.push_back(*it1); - } - } - s1=s3; - } - return ret; -} - -/*! - * This method scan all the progeny of \a this (\a this excluded) to see if \a obj is part of it. - * If obj is NULL false is returned. - * \sa BigMemoryObject::getAllTheProgeny - */ -bool BigMemoryObject::isObjectInTheProgeny(const BigMemoryObject *obj) const -{ - if(!obj) - return false; - std::vector objs(getAllTheProgeny()); - return std::find(objs.begin(),objs.end(),obj)!=objs.end(); -} - -std::size_t BigMemoryObject::GetHeapMemorySizeOfObjs(const std::vector& objs) -{ - std::size_t ret(0); - std::set s1,s2; - for(std::vector::const_iterator it0=objs.begin();it0!=objs.end();it0++) - { - if(*it0) - if(s1.find(*it0)==s1.end()) - { - std::vector vTmp((*it0)->getDirectChildren()); - s2.insert(vTmp.begin(),vTmp.end()); - ret+=(*it0)->getHeapMemorySizeWithoutChildren(); - s1.insert(*it0); - } - } - return ret+GetHeapMemoryOfSet(s1,s2); -} - -std::size_t BigMemoryObject::GetHeapMemoryOfSet(std::set& s1, std::set& s2) -{ - std::size_t ret(0); - while(!s2.empty()) - { - std::set s3; - for(std::set::const_iterator it=s2.begin();it!=s2.end();it++) - { - if(s1.find(*it)==s1.end()) - { - ret+=(*it)->getHeapMemorySizeWithoutChildren(); - s1.insert(*it); - std::vector v2((*it)->getDirectChildren()); - for(std::vector::const_iterator it2=v2.begin();it2!=v2.end();it2++) - if(s1.find(*it2)==s1.end()) - s3.insert(*it2); - } - } - s2=s3; - } - return ret; -} - -std::string BigMemoryObject::getHeapMemorySizeStr() const -{ - static const char *UNITS[4]={"B","kB","MB","GB"}; - std::size_t m(getHeapMemorySize()); - std::ostringstream oss; oss.precision(3); - std::size_t remain(0); - int i(0); - for(;i<4;i++) - { - if(m<1024) - { - oss << m; - if(remain!=0) - { - std::ostringstream oss2; oss2 << std::fixed << ((double)remain)/1024.; - std::string s(oss2.str()); - s=s.substr(1,4); - std::size_t pos(s.find_last_not_of('0')); - if(pos==4) - oss << s; - else - oss << s.substr(0,pos+1); - } - oss << " " << UNITS[i]; - break; - } - else - { - if(i!=3) - { - remain=(m%1024); - m/=1024; - } - } - } - if(i==4) - oss << m << " " << UNITS[3]; - return oss.str(); -} - -std::vector BigMemoryObject::getDirectChildren() const -{ - std::vector ret; - std::vector retWithNull(getDirectChildrenWithNull()); - for(std::vector::const_iterator it=retWithNull.begin();it!=retWithNull.end();it++) - if(*it) - ret.push_back(*it); - return ret; -} - -BigMemoryObject::~BigMemoryObject() -{ -} - -//= - -RefCountObjectOnly::RefCountObjectOnly():_cnt(1) -{ -} - -RefCountObjectOnly::RefCountObjectOnly(const RefCountObjectOnly& other):_cnt(1) -{ -} - -bool RefCountObjectOnly::decrRef() const -{ - bool ret=((--_cnt)==0); - if(ret) - delete this; - return ret; -} - -void RefCountObjectOnly::incrRef() const -{ - _cnt++; -} - -int RefCountObjectOnly::getRCValue() const -{ - return _cnt; -} - -RefCountObjectOnly::~RefCountObjectOnly() -{ -} - -/*! - * Do nothing here ! It is not a bug ( I hope :) ) because all subclasses that - * copies using operator= should not copy the ref counter of \a other ! - */ -RefCountObjectOnly& RefCountObjectOnly::operator=(const RefCountObjectOnly& other) -{ - return *this; -} - -//= - -RefCountObject::RefCountObject() -{ -} - -RefCountObject::RefCountObject(const RefCountObject& other):RefCountObjectOnly(other) -{ -} - -RefCountObject::~RefCountObject() -{ -} diff --git a/src/MEDCoupling/MEDCouplingRefCountObject.hxx b/src/MEDCoupling/MEDCouplingRefCountObject.hxx deleted file mode 100644 index 4eea72a52..000000000 --- a/src/MEDCoupling/MEDCouplingRefCountObject.hxx +++ /dev/null @@ -1,106 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 -// 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_MEDCOUPLINGREFCOUNTOBJECT_HXX__ -#define __PARAMEDMEM_MEDCOUPLINGREFCOUNTOBJECT_HXX__ - -#include "MEDCoupling.hxx" - -#include -#include -#include -#include - -namespace ParaMEDMEM -{ - typedef enum - { - C_DEALLOC = 2, - CPP_DEALLOC = 3 - } DeallocType; - - typedef enum - { - ON_CELLS = 0, - ON_NODES = 1, - ON_GAUSS_PT = 2, - ON_GAUSS_NE = 3, - ON_NODES_KR = 4 - } TypeOfField; - - typedef enum - { - NO_TIME = 4, - ONE_TIME = 5, - LINEAR_TIME = 6, - CONST_ON_TIME_INTERVAL = 7 - } TypeOfTimeDiscretization; - - typedef bool (*FunctionToEvaluate)(const double *pos, double *res); - - MEDCOUPLING_EXPORT const char *MEDCouplingVersionStr(); - MEDCOUPLING_EXPORT int MEDCouplingVersion(); - MEDCOUPLING_EXPORT void MEDCouplingVersionMajMinRel(int& maj, int& minor, int& releas); - MEDCOUPLING_EXPORT int MEDCouplingSizeOfVoidStar(); - MEDCOUPLING_EXPORT bool MEDCouplingByteOrder(); - MEDCOUPLING_EXPORT const char *MEDCouplingByteOrderStr(); - - class BigMemoryObject - { - public: - MEDCOUPLING_EXPORT std::size_t getHeapMemorySize() const; - MEDCOUPLING_EXPORT std::string getHeapMemorySizeStr() const; - MEDCOUPLING_EXPORT std::vector getDirectChildren() const; - MEDCOUPLING_EXPORT std::vector getAllTheProgeny() const; - MEDCOUPLING_EXPORT bool isObjectInTheProgeny(const BigMemoryObject *obj) const; - MEDCOUPLING_EXPORT static std::size_t GetHeapMemorySizeOfObjs(const std::vector& objs); - MEDCOUPLING_EXPORT virtual std::size_t getHeapMemorySizeWithoutChildren() const = 0; - MEDCOUPLING_EXPORT virtual std::vector getDirectChildrenWithNull() const = 0; - MEDCOUPLING_EXPORT virtual ~BigMemoryObject(); - private: - static std::size_t GetHeapMemoryOfSet(std::set& s1, std::set& s2); - }; - - class RefCountObjectOnly - { - protected: - MEDCOUPLING_EXPORT RefCountObjectOnly(); - MEDCOUPLING_EXPORT RefCountObjectOnly(const RefCountObjectOnly& other); - public: - MEDCOUPLING_EXPORT bool decrRef() const; - MEDCOUPLING_EXPORT void incrRef() const; - MEDCOUPLING_EXPORT int getRCValue() const; - MEDCOUPLING_EXPORT RefCountObjectOnly& operator=(const RefCountObjectOnly& other); - protected: - virtual ~RefCountObjectOnly(); - private: - mutable int _cnt; - }; - - class RefCountObject : public RefCountObjectOnly, public BigMemoryObject - { - protected: - MEDCOUPLING_EXPORT RefCountObject(); - MEDCOUPLING_EXPORT RefCountObject(const RefCountObject& other); - MEDCOUPLING_EXPORT virtual ~RefCountObject(); - }; -} - -#endif diff --git a/src/MEDCoupling/MEDCouplingRemapper.cxx b/src/MEDCoupling/MEDCouplingRemapper.cxx deleted file mode 100644 index 18741778f..000000000 --- a/src/MEDCoupling/MEDCouplingRemapper.cxx +++ /dev/null @@ -1,1312 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 -// 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 "MEDCouplingRemapper.hxx" -#include "MEDCouplingMemArray.hxx" -#include "MEDCouplingFieldDouble.hxx" -#include "MEDCouplingFieldTemplate.hxx" -#include "MEDCouplingFieldDiscretization.hxx" -#include "MEDCouplingExtrudedMesh.hxx" -#include "MEDCouplingCMesh.hxx" -#include "MEDCouplingNormalizedUnstructuredMesh.txx" -#include "MEDCouplingNormalizedCartesianMesh.txx" - -#include "Interpolation1D.txx" -#include "Interpolation2DCurve.hxx" -#include "Interpolation2D.txx" -#include "Interpolation3D.txx" -#include "Interpolation3DSurf.hxx" -#include "Interpolation2D1D.txx" -#include "Interpolation3D2D.txx" -#include "InterpolationCU.txx" -#include "InterpolationCC.txx" - -using namespace ParaMEDMEM; - -MEDCouplingRemapper::MEDCouplingRemapper():_src_ft(0),_target_ft(0),_interp_matrix_pol(IK_ONLY_PREFERED),_nature_of_deno(NoNature),_time_deno_update(0) -{ -} - -MEDCouplingRemapper::~MEDCouplingRemapper() -{ - releaseData(false); -} - -/*! - * This method is the second step of the remapping process. The remapping process works in three phases : - * - * - Set remapping options appropriately - * - The computation of remapping matrix - * - Apply the matrix vector multiply to obtain the result of the remapping - * - * This method performs the second step (computation of remapping matrix) which may be CPU-time consuming. This phase is also the most critical (where the most tricky algorithm) in the remapping process. - * Strictly speaking to perform the computation of the remapping matrix the field templates source-side and target-side is required (which is the case of MEDCouplingRemapper::prepareEx). - * So this method is less precise but a more user friendly way to compute a remapping matrix. - * - * \param [in] srcMesh the source mesh - * \param [in] targetMesh the target mesh - * \param [in] method A string obtained by aggregation of the spatial discretisation string representation of source field and target field. The string representation is those returned by MEDCouplingFieldDiscretization::getStringRepr. - * Example : "P0" is for cell discretization. "P1" is for node discretization. So "P0P1" for \a method parameter means from a source cell field (lying on \a srcMesh) to a target node field (lying on \a targetMesh). - * - * \sa MEDCouplingRemapper::prepareEx - */ -int MEDCouplingRemapper::prepare(const MEDCouplingMesh *srcMesh, const MEDCouplingMesh *targetMesh, const std::string& method) -{ - 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)); - src->setMesh(srcMesh); - MEDCouplingAutoRefCountObjectPtr target=MEDCouplingFieldTemplate::New(MEDCouplingFieldDiscretization::GetTypeOfFieldFromStringRepr(targetMethod)); - target->setMesh(targetMesh); - return prepareEx(src,target); -} - -/*! - * This method is the generalization of MEDCouplingRemapper::prepare. Indeed, MEDCouplingFieldTemplate instances gives all required information to compute the remapping matrix. - * This method must be used instead of MEDCouplingRemapper::prepare if Gauss point to Gauss point must be applied. - * - * \param [in] src is the field template source side. - * \param [in] target is the field template target side. - * - * \sa MEDCouplingRemapper::prepare - */ -int MEDCouplingRemapper::prepareEx(const MEDCouplingFieldTemplate *src, const MEDCouplingFieldTemplate *target) -{ - 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_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() -{ - int meshInterpType=((int)_src_ft->getMesh()->getType()*16)+(int)_target_ft->getMesh()->getType(); - switch(meshInterpType) - { - case 90: - case 91: - case 165: - case 181: - case 170: - case 171: - case 186: - case 187: - case 85://Unstructured-Unstructured - return prepareInterpKernelOnlyUU(); - case 167: - case 183: - case 87://Unstructured-Cartesian - return prepareInterpKernelOnlyUC(); - case 122: - case 123: - case 117://Cartesian-Unstructured - return prepareInterpKernelOnlyCU(); - case 119://Cartesian-Cartesian - return prepareInterpKernelOnlyCC(); - case 136://Extruded-Extruded - return prepareInterpKernelOnlyEE(); - default: - 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::prepareNotInterpKernelOnly() -{ - 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()); - } - } -} - -/*! - * This method performs the operation source to target using matrix computed in ParaMEDMEM::MEDCouplingRemapper::prepare method. - * If meshes of \b srcField and \b targetField do not match exactly those given into \ref ParaMEDMEM::MEDCouplingRemapper::prepare "prepare method" an exception will be thrown. - * - * \param [in] srcField is the source field from which the interpolation will be done. The mesh into \b srcField should be the same than those specified on ParaMEDMEM::MEDCouplingRemapper::prepare. - * \param [in/out] targetField the destination field with the allocated array in which all tuples will be overwritten. - * \param [in] dftValue is the value that will be assigned in the targetField to each entity of target mesh (entity depending on the method selected on prepare invocation) that is not intercepted by any entity of source mesh. - * For example in "P0P0" case (cell-cell) if a cell in target mesh is not overlapped by any source cell the \a dftValue value will be attached on that cell in the returned \a targetField. In some cases a target - * cell not intercepted by any source cell is a bug so in this case it is advised to set a huge value (1e300 for example) to \a dftValue to quickly point to the problem. But for users doing parallelism a target cell can - * be intercepted by a source cell on a different process. In this case 0. assigned to \a dftValue is more appropriate. - * - * \sa transferField - */ -void MEDCouplingRemapper::transfer(const MEDCouplingFieldDouble *srcField, MEDCouplingFieldDouble *targetField, double dftValue) -{ - if(!srcField || !targetField) - throw INTERP_KERNEL::Exception("MEDCouplingRemapper::transfer : input field must be both not NULL !"); - transferUnderground(srcField,targetField,true,dftValue); -} - -/*! - * This method is equivalent to ParaMEDMEM::MEDCouplingRemapper::transfer except that here \b targetField is a in/out parameter. - * If an entity (cell for example) in targetField is not fetched by any entity (cell for example) of \b srcField, the value in targetField is - * let unchanged. - * This method requires that \b targetField was fully defined and allocated. If the array is not allocated an exception will be thrown. - * - * \param [in] srcField is the source field from which the interpolation will be done. The mesh into \b srcField should be the same than those specified on ParaMEDMEM::MEDCouplingRemapper::prepare. - * \param [in,out] targetField the destination field with the allocated array in which only tuples whose entities are fetched by interpolation will be overwritten only. - */ -void MEDCouplingRemapper::partialTransfer(const MEDCouplingFieldDouble *srcField, MEDCouplingFieldDouble *targetField) -{ - if(!srcField || !targetField) - throw INTERP_KERNEL::Exception("MEDCouplingRemapper::partialTransfer : input field must be both not NULL !"); - transferUnderground(srcField,targetField,false,std::numeric_limits::max()); -} - -void MEDCouplingRemapper::reverseTransfer(MEDCouplingFieldDouble *srcField, const MEDCouplingFieldDouble *targetField, double dftValue) -{ - if(!srcField || !targetField) - throw INTERP_KERNEL::Exception("MEDCouplingRemapper::reverseTransfer : input fields must be both not NULL !"); - checkPrepare(); - targetField->checkCoherency(); - if(_src_ft->getDiscretization()->getStringRepr()!=srcField->getDiscretization()->getStringRepr()) - throw INTERP_KERNEL::Exception("Incoherency with prepare call for source field"); - 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 !"); - if(targetField->getNumberOfTuplesExpected()!=_target_ft->getNumberOfTuplesExpected()) - { - std::ostringstream oss; - oss << "MEDCouplingRemapper::reverseTransfer : in given source field the number of tuples required is " << _target_ft->getNumberOfTuplesExpected() << " (on prepare) and number of tuples in given target field is " << targetField->getNumberOfTuplesExpected(); - oss << " ! It appears that the target support is not the same between the prepare and the transfer !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - DataArrayDouble *array(srcField->getArray()); - int trgNbOfCompo=targetField->getNumberOfComponents(); - if(array) - { - srcField->checkCoherency(); - if(trgNbOfCompo!=srcField->getNumberOfTuplesExpected()) - throw INTERP_KERNEL::Exception("Number of components mismatch !"); - } - else - { - MEDCouplingAutoRefCountObjectPtr tmp(DataArrayDouble::New()); - tmp->alloc(srcField->getNumberOfTuplesExpected(),trgNbOfCompo); - srcField->setArray(tmp); - } - computeDeno(srcField->getNature(),srcField,targetField); - double *resPointer(srcField->getArray()->getPointer()); - const double *inputPointer=targetField->getArray()->getConstPointer(); - computeReverseProduct(inputPointer,trgNbOfCompo,dftValue,resPointer); -} - -/*! - * This method performs the operation source to target using matrix computed in ParaMEDMEM::MEDCouplingRemapper::prepare method. - * If mesh of \b srcField does not match exactly those given into \ref ParaMEDMEM::MEDCouplingRemapper::prepare "prepare method" an exception will be thrown. - * - * \param [in] srcField is the source field from which the interpolation will be done. The mesh into \b srcField should be the same than those specified on ParaMEDMEM::MEDCouplingRemapper::prepare. - * \param [in] dftValue is the value that will be assigned in the targetField to each entity of target mesh (entity depending on the method selected on prepare invocation) that is not intercepted by any entity of source mesh. - * For example in "P0P0" case (cell-cell) if a cell in target mesh is not overlapped by any source cell the \a dftValue value will be attached on that cell in the returned \a targetField. In some cases a target - * cell not intercepted by any source cell is a bug so in this case it is advised to set a huge value (1e300 for example) to \a dftValue to quickly point to the problem. But for users doing parallelism a target cell can - * be intercepted by a source cell on a different process. In this case 0. assigned to \a dftValue is more appropriate. - * \return destination field to be deallocated by the caller. - * - * \sa transfer - */ -MEDCouplingFieldDouble *MEDCouplingRemapper::transferField(const MEDCouplingFieldDouble *srcField, double dftValue) -{ - checkPrepare(); - if(!srcField) - throw INTERP_KERNEL::Exception("MEDCouplingRemapper::transferField : input srcField is NULL !"); - srcField->checkCoherency(); - if(_src_ft->getDiscretization()->getStringRepr()!=srcField->getDiscretization()->getStringRepr()) - throw INTERP_KERNEL::Exception("Incoherency with prepare call for source field"); - MEDCouplingFieldDouble *ret=MEDCouplingFieldDouble::New(*_target_ft,srcField->getTimeDiscretization()); - ret->setNature(srcField->getNature()); - 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) -{ - if(!targetField) - throw INTERP_KERNEL::Exception("MEDCouplingRemapper::transferField : input targetField is NULL !"); - targetField->checkCoherency(); - checkPrepare(); - if(_target_ft->getDiscretization()->getStringRepr()!=targetField->getDiscretization()->getStringRepr()) - throw INTERP_KERNEL::Exception("Incoherency with prepare call for target field"); - MEDCouplingFieldDouble *ret=MEDCouplingFieldDouble::New(*_src_ft,targetField->getTimeDiscretization()); - ret->setNature(targetField->getNature()); - 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); -} - -/*! - * 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) -{ - 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() -{ - const MEDCouplingPointSet *src_mesh=static_cast(_src_ft->getMesh()); - const MEDCouplingPointSet *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) - srcSpaceDim=src_mesh->getSpaceDimension(); - const int trgMeshDim=target_mesh->getMeshDimension(); - int trgSpaceDim=-1; - if(trgMeshDim!=-1) - trgSpaceDim=target_mesh->getSpaceDimension(); - if(trgSpaceDim!=srcSpaceDim) - if(trgSpaceDim!=-1 && srcSpaceDim!=-1) - throw INTERP_KERNEL::Exception("Incoherent space dimension detected between target and source."); - int nbCols; - if(srcMeshDim==1 && trgMeshDim==1 && srcSpaceDim==1) - { - 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); - } - 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); - } - 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); - } - 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); - } - 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); - } - else if(srcMeshDim==3 && trgMeshDim==1 && srcSpaceDim==3) - { - if(getIntersectionType()!=INTERP_KERNEL::PointLocator) - throw INTERP_KERNEL::Exception("Invalid interpolation requested between 3D and 1D ! Select PointLocator as intersection type !"); - 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); - } - else if(srcMeshDim==1 && trgMeshDim==3 && srcSpaceDim==3) - { - if(getIntersectionType()!=INTERP_KERNEL::PointLocator) - throw INTERP_KERNEL::Exception("Invalid interpolation requested between 3D and 1D ! Select PointLocator as intersection type !"); - MEDCouplingNormalizedUnstructuredMesh<3,3> source_mesh_wrapper(src_mesh); - MEDCouplingNormalizedUnstructuredMesh<3,3> target_mesh_wrapper(target_mesh); - INTERP_KERNEL::Interpolation3D interpolation(*this); - std::vector > matrixTmp; - std::string revMethod(BuildMethodFrom(trgMeth,srcMeth)); - nbCols=interpolation.interpolateMeshes(target_mesh_wrapper,source_mesh_wrapper,matrixTmp,revMethod); - ReverseMatrix(matrixTmp,nbCols,_matrix); - nbCols=matrixTmp.size(); - } - else if(srcMeshDim==2 && trgMeshDim==1 && srcSpaceDim==2) - { - if(getIntersectionType()==INTERP_KERNEL::PointLocator) - { - 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); - } - else - { - MEDCouplingNormalizedUnstructuredMesh<2,2> source_mesh_wrapper(src_mesh); - MEDCouplingNormalizedUnstructuredMesh<2,2> target_mesh_wrapper(target_mesh); - INTERP_KERNEL::Interpolation2D1D interpolation(*this); - std::vector > matrixTmp; - std::string revMethod(BuildMethodFrom(trgMeth,srcMeth)); - nbCols=interpolation.interpolateMeshes(target_mesh_wrapper,source_mesh_wrapper,matrixTmp,revMethod); - ReverseMatrix(matrixTmp,nbCols,_matrix); - nbCols=matrixTmp.size(); - INTERP_KERNEL::Interpolation2D1D::DuplicateFacesType duplicateFaces=interpolation.retrieveDuplicateFaces(); - if(!duplicateFaces.empty()) - { - std::ostringstream oss; oss << "An unexpected situation happend ! For the following 1D Cells are part of edges shared by 2D cells :\n"; - for(std::map >::const_iterator it=duplicateFaces.begin();it!=duplicateFaces.end();it++) - { - oss << "1D Cell #" << (*it).first << " is part of common edge of following 2D cells ids : "; - std::copy((*it).second.begin(),(*it).second.end(),std::ostream_iterator(oss," ")); - oss << std::endl; - } - } - } - } - else if(srcMeshDim==1 && trgMeshDim==2 && srcSpaceDim==2) - { - if(getIntersectionType()==INTERP_KERNEL::PointLocator) - { - MEDCouplingNormalizedUnstructuredMesh<2,2> source_mesh_wrapper(src_mesh); - MEDCouplingNormalizedUnstructuredMesh<2,2> target_mesh_wrapper(target_mesh); - INTERP_KERNEL::Interpolation2D interpolation(*this); - std::vector > matrixTmp; - std::string revMethod(BuildMethodFrom(trgMeth,srcMeth)); - nbCols=interpolation.interpolateMeshes(target_mesh_wrapper,source_mesh_wrapper,matrixTmp,revMethod); - ReverseMatrix(matrixTmp,nbCols,_matrix); - nbCols=matrixTmp.size(); - } - else - { - 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); - INTERP_KERNEL::Interpolation2D1D::DuplicateFacesType duplicateFaces=interpolation.retrieveDuplicateFaces(); - if(!duplicateFaces.empty()) - { - std::ostringstream oss; oss << "An unexpected situation happend ! For the following 1D Cells are part of edges shared by 2D cells :\n"; - for(std::map >::const_iterator it=duplicateFaces.begin();it!=duplicateFaces.end();it++) - { - oss << "1D Cell #" << (*it).first << " is part of common edge of following 2D cells ids : "; - std::copy((*it).second.begin(),(*it).second.end(),std::ostream_iterator(oss," ")); - oss << std::endl; - } - } - } - } - else if(srcMeshDim==2 && trgMeshDim==3 && srcSpaceDim==3) - { - 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); - INTERP_KERNEL::Interpolation3D2D::DuplicateFacesType duplicateFaces=interpolation.retrieveDuplicateFaces(); - if(!duplicateFaces.empty()) - { - std::ostringstream oss; oss << "An unexpected situation happend ! For the following 2D Cells are part of edges shared by 3D cells :\n"; - for(std::map >::const_iterator it=duplicateFaces.begin();it!=duplicateFaces.end();it++) - { - oss << "2D Cell #" << (*it).first << " is part of common face of following 3D cells ids : "; - std::copy((*it).second.begin(),(*it).second.end(),std::ostream_iterator(oss," ")); - oss << std::endl; - } - } - } - else if(srcMeshDim==3 && trgMeshDim==2 && srcSpaceDim==3) - { - MEDCouplingNormalizedUnstructuredMesh<3,3> source_mesh_wrapper(src_mesh); - MEDCouplingNormalizedUnstructuredMesh<3,3> target_mesh_wrapper(target_mesh); - INTERP_KERNEL::Interpolation3D2D interpolation(*this); - std::vector > matrixTmp; - std::string revMethod(BuildMethodFrom(trgMeth,srcMeth)); - nbCols=interpolation.interpolateMeshes(target_mesh_wrapper,source_mesh_wrapper,matrixTmp,revMethod); - ReverseMatrix(matrixTmp,nbCols,_matrix); - nbCols=matrixTmp.size(); - INTERP_KERNEL::Interpolation3D2D::DuplicateFacesType duplicateFaces=interpolation.retrieveDuplicateFaces(); - if(!duplicateFaces.empty()) - { - std::ostringstream oss; oss << "An unexpected situation happend ! For the following 2D Cells are part of edges shared by 3D cells :\n"; - for(std::map >::const_iterator it=duplicateFaces.begin();it!=duplicateFaces.end();it++) - { - oss << "2D Cell #" << (*it).first << " is part of common face of following 3D cells ids : "; - std::copy((*it).second.begin(),(*it).second.end(),std::ostream_iterator(oss," ")); - oss << std::endl; - } - } - } - else if(trgMeshDim==-1) - { - if(srcMeshDim==2 && srcSpaceDim==2) - { - MEDCouplingNormalizedUnstructuredMesh<2,2> source_mesh_wrapper(src_mesh); - INTERP_KERNEL::Interpolation2D interpolation(*this); - nbCols=interpolation.toIntegralUniform(source_mesh_wrapper,_matrix,srcMeth); - } - 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,srcMeth); - } - 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,srcMeth); - } - else - throw INTERP_KERNEL::Exception("No interpolation available for the given mesh and space dimension of source mesh to -1D targetMesh"); - } - else if(srcMeshDim==-1) - { - if(trgMeshDim==2 && trgSpaceDim==2) - { - MEDCouplingNormalizedUnstructuredMesh<2,2> source_mesh_wrapper(target_mesh); - INTERP_KERNEL::Interpolation2D interpolation(*this); - nbCols=interpolation.fromIntegralUniform(source_mesh_wrapper,_matrix,trgMeth); - } - 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,trgMeth); - } - 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,trgMeth); - } - else - throw INTERP_KERNEL::Exception("No interpolation available for the given mesh and space dimension of source mesh from -1D sourceMesh"); - } - else - throw INTERP_KERNEL::Exception("No interpolation available for the given mesh and space dimension"); - _deno_multiply.clear(); - _deno_multiply.resize(_matrix.size()); - _deno_reverse_multiply.clear(); - _deno_reverse_multiply.resize(nbCols); - declareAsNew(); - return 1; -} - -int MEDCouplingRemapper::prepareInterpKernelOnlyEE() -{ - 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("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,methC); - MEDCouplingUMesh *s1D,*t1D; - double v[3]; - MEDCouplingExtrudedMesh::Project1DMeshes(src_mesh->getMesh1D(),target_mesh->getMesh1D(),getPrecision(),s1D,t1D,v); - MEDCouplingNormalizedUnstructuredMesh<1,1> s1DWrapper(s1D); - MEDCouplingNormalizedUnstructuredMesh<1,1> t1DWrapper(t1D); - std::vector > matrix1D; - INTERP_KERNEL::Interpolation1D interpolation1D(*this); - int nbCols1D=interpolation1D.interpolateMeshes(s1DWrapper,t1DWrapper,matrix1D,methC); - s1D->decrRef(); - t1D->decrRef(); - buildFinalInterpolationMatrixByConvolution(matrix1D,matrix2D,src_mesh->getMesh3DIds()->getConstPointer(),nbCols2D,nbCols1D, - target_mesh->getMesh3DIds()->getConstPointer()); - // - _deno_multiply.clear(); - _deno_multiply.resize(_matrix.size()); - _deno_reverse_multiply.clear(); - _deno_reverse_multiply.resize(nbCols2D*nbCols1D); - declareAsNew(); - return 1; -} - -int MEDCouplingRemapper::prepareInterpKernelOnlyUC() -{ - std::string srcMeth,trgMeth; - std::string methodCpp=checkAndGiveInterpolationMethodStr(srcMeth,trgMeth); - if(methodCpp!="P0P0") - 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::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) - { - case 1: - { - MEDCouplingNormalizedCartesianMesh<1> targetWrapper(target_mesh); - MEDCouplingNormalizedUnstructuredMesh<1,1> sourceWrapper(src_mesh); - INTERP_KERNEL::InterpolationCU myInterpolator(*this); - myInterpolator.interpolateMeshes(targetWrapper,sourceWrapper,res,"P0P0"); - break; - } - case 2: - { - MEDCouplingNormalizedCartesianMesh<2> targetWrapper(target_mesh); - MEDCouplingNormalizedUnstructuredMesh<2,2> sourceWrapper(src_mesh); - INTERP_KERNEL::InterpolationCU myInterpolator(*this); - myInterpolator.interpolateMeshes(targetWrapper,sourceWrapper,res,"P0P0"); - break; - } - case 3: - { - MEDCouplingNormalizedCartesianMesh<3> targetWrapper(target_mesh); - MEDCouplingNormalizedUnstructuredMesh<3,3> sourceWrapper(src_mesh); - INTERP_KERNEL::InterpolationCU myInterpolator(*this); - myInterpolator.interpolateMeshes(targetWrapper,sourceWrapper,res,"P0P0"); - break; - } - default: - throw INTERP_KERNEL::Exception("MEDCouplingRemapper::prepareInterpKernelOnlyUC : only dimension 1 2 or 3 supported !"); - } - ReverseMatrix(res,target_mesh->getNumberOfCells(),_matrix); - nullifiedTinyCoeffInCrudeMatrixAbs(0.); - // - _deno_multiply.clear(); - _deno_multiply.resize(_matrix.size()); - _deno_reverse_multiply.clear(); - _deno_reverse_multiply.resize(src_mesh->getNumberOfCells()); - declareAsNew(); - return 1; -} - -int MEDCouplingRemapper::prepareInterpKernelOnlyCU() -{ - std::string srcMeth,trgMeth; - std::string methodCpp=checkAndGiveInterpolationMethodStr(srcMeth,trgMeth); - if(methodCpp!="P0P0") - 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::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: - { - MEDCouplingNormalizedCartesianMesh<1> sourceWrapper(src_mesh); - MEDCouplingNormalizedUnstructuredMesh<1,1> targetWrapper(target_mesh); - INTERP_KERNEL::InterpolationCU myInterpolator(*this); - myInterpolator.interpolateMeshes(sourceWrapper,targetWrapper,_matrix,"P0P0"); - break; - } - case 2: - { - MEDCouplingNormalizedCartesianMesh<2> sourceWrapper(src_mesh); - MEDCouplingNormalizedUnstructuredMesh<2,2> targetWrapper(target_mesh); - INTERP_KERNEL::InterpolationCU myInterpolator(*this); - myInterpolator.interpolateMeshes(sourceWrapper,targetWrapper,_matrix,"P0P0"); - break; - } - case 3: - { - MEDCouplingNormalizedCartesianMesh<3> sourceWrapper(src_mesh); - MEDCouplingNormalizedUnstructuredMesh<3,3> targetWrapper(target_mesh); - INTERP_KERNEL::InterpolationCU myInterpolator(*this); - myInterpolator.interpolateMeshes(sourceWrapper,targetWrapper,_matrix,"P0P0"); - break; - } - default: - throw INTERP_KERNEL::Exception("MEDCouplingRemapper::prepareInterpKernelOnlyCU : only dimension 1 2 or 3 supported !"); - } - nullifiedTinyCoeffInCrudeMatrixAbs(0.); - // - _deno_multiply.clear(); - _deno_multiply.resize(_matrix.size()); - _deno_reverse_multiply.clear(); - _deno_reverse_multiply.resize(src_mesh->getNumberOfCells()); - declareAsNew(); - return 1; -} - -int MEDCouplingRemapper::prepareInterpKernelOnlyCC() -{ - std::string srcMeth,trgMeth; - std::string methodCpp=checkAndGiveInterpolationMethodStr(srcMeth,trgMeth); - if(methodCpp!="P0P0") - 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::prepareInterpKernelOnlyCC : dim of target cartesian should be equal to dim of source cartesian dimension !"); - switch(srcMeshDim) - { - case 1: - { - MEDCouplingNormalizedCartesianMesh<1> sourceWrapper(src_mesh); - MEDCouplingNormalizedCartesianMesh<1> targetWrapper(target_mesh); - INTERP_KERNEL::InterpolationCC myInterpolator(*this); - myInterpolator.interpolateMeshes(sourceWrapper,targetWrapper,_matrix,"P0P0"); - break; - } - case 2: - { - MEDCouplingNormalizedCartesianMesh<2> sourceWrapper(src_mesh); - MEDCouplingNormalizedCartesianMesh<2> targetWrapper(target_mesh); - INTERP_KERNEL::InterpolationCC myInterpolator(*this); - myInterpolator.interpolateMeshes(sourceWrapper,targetWrapper,_matrix,"P0P0"); - break; - } - case 3: - { - MEDCouplingNormalizedCartesianMesh<3> sourceWrapper(src_mesh); - MEDCouplingNormalizedCartesianMesh<3> targetWrapper(target_mesh); - INTERP_KERNEL::InterpolationCC myInterpolator(*this); - myInterpolator.interpolateMeshes(sourceWrapper,targetWrapper,_matrix,"P0P0"); - break; - } - default: - throw INTERP_KERNEL::Exception("MEDCouplingRemapper::prepareInterpKernelOnlyCC : only dimension 1 2 or 3 supported !"); - } - nullifiedTinyCoeffInCrudeMatrixAbs(0.); - // - _deno_multiply.clear(); - _deno_multiply.resize(_matrix.size()); - _deno_reverse_multiply.clear(); - _deno_reverse_multiply.resize(src_mesh->getNumberOfCells()); - declareAsNew(); - return 1; -} - -int MEDCouplingRemapper::prepareNotInterpKernelOnlyGaussGauss() -{ - 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(); - MEDCouplingAutoRefCountObjectPtr eltsArr,eltsIndexArr; - int trgNbOfGaussPts=trgLoc->getNumberOfTuples(); - _matrix.resize(trgNbOfGaussPts); - _src_ft->getMesh()->getCellsContainingPoints(trgLoc->begin(),trgNbOfGaussPts,getPrecision(),eltsArr,eltsIndexArr); - const int *elts(eltsArr->begin()),*eltsIndex(eltsIndexArr->begin()); - MEDCouplingAutoRefCountObjectPtr nbOfSrcCellsShTrgPts(eltsIndexArr->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) -{ - 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 -{ - 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,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 -{ - 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 -{ - 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(); - return BuildMethodFrom(srcMeth,trgMeth); -} - -std::string MEDCouplingRemapper::BuildMethodFrom(const std::string& meth1, const std::string& meth2) -{ - std::string method(meth1); method+=meth2; - return method; -} - -void MEDCouplingRemapper::releaseData(bool matrixSuppression) -{ - _src_ft=0; - _target_ft=0; - if(matrixSuppression) - { - _matrix.clear(); - _deno_multiply.clear(); - _deno_reverse_multiply.clear(); - } -} - -void MEDCouplingRemapper::transferUnderground(const MEDCouplingFieldDouble *srcField, MEDCouplingFieldDouble *targetField, bool isDftVal, double dftValue) -{ - if(!srcField || !targetField) - throw INTERP_KERNEL::Exception("MEDCouplingRemapper::transferUnderground : srcField or targetField is NULL !"); - srcField->checkCoherency(); - checkPrepare(); - if(_src_ft->getDiscretization()->getStringRepr()!=srcField->getDiscretization()->getStringRepr()) - throw INTERP_KERNEL::Exception("Incoherency with prepare call for source field"); - 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 !"); - if(srcField->getNumberOfTuplesExpected()!=_src_ft->getNumberOfTuplesExpected()) - { - std::ostringstream oss; - oss << "MEDCouplingRemapper::transferUnderground : in given source field the number of tuples required is " << _src_ft->getNumberOfTuplesExpected() << " (on prepare) and number of tuples in given source field is " << srcField->getNumberOfTuplesExpected(); - oss << " ! It appears that the source support is not the same between the prepare and the transfer !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - DataArrayDouble *array(targetField->getArray()); - int srcNbOfCompo(srcField->getNumberOfComponents()); - if(array) - { - targetField->checkCoherency(); - if(srcNbOfCompo!=targetField->getNumberOfComponents()) - throw INTERP_KERNEL::Exception("Number of components mismatch !"); - } - else - { - if(!isDftVal) - throw INTERP_KERNEL::Exception("MEDCouplingRemapper::partialTransfer : This method requires that the array of target field exists ! Allocate it or call MEDCouplingRemapper::transfer instead !"); - MEDCouplingAutoRefCountObjectPtr tmp(DataArrayDouble::New()); - tmp->alloc(targetField->getNumberOfTuples(),srcNbOfCompo); - targetField->setArray(tmp); - } - computeDeno(srcField->getNature(),srcField,targetField); - double *resPointer(targetField->getArray()->getPointer()); - const double *inputPointer(srcField->getArray()->getConstPointer()); - computeProduct(inputPointer,srcNbOfCompo,isDftVal,dftValue,resPointer); -} - -void MEDCouplingRemapper::computeDeno(NatureOfField nat, const MEDCouplingFieldDouble *srcField, const MEDCouplingFieldDouble *trgField) -{ - if(nat==NoNature) - return computeDenoFromScratch(nat,srcField,trgField); - else if(nat!=_nature_of_deno) - return computeDenoFromScratch(nat,srcField,trgField); - else if(nat==_nature_of_deno && _time_deno_update!=getTimeOfThis()) - return computeDenoFromScratch(nat,srcField,trgField); -} - -void MEDCouplingRemapper::computeDenoFromScratch(NatureOfField nat, const MEDCouplingFieldDouble *srcField, const MEDCouplingFieldDouble *trgField) -{ - _nature_of_deno=nat; - _time_deno_update=getTimeOfThis(); - switch(_nature_of_deno) - { - case ConservativeVolumic: - { - ComputeRowSumAndColSum(_matrix,_deno_multiply,_deno_reverse_multiply); - break; - } - case Integral: - { - 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) - { - double *denoRPtr2=denoR->getArray()->getPointer(); - denoRPtr2[0]=std::accumulate(denoPtr,denoPtr+deno->getNumberOfTuples(),0.); - } - if(srcField->getMesh()->getMeshDimension()==-1) - { - double *denoPtr2=deno->getArray()->getPointer(); - denoPtr2[0]=std::accumulate(denoRPtr,denoRPtr+denoR->getNumberOfTuples(),0.); - } - int idx=0; - for(std::vector >::const_iterator iter1=_matrix.begin();iter1!=_matrix.end();iter1++,idx++) - for(std::map::const_iterator iter2=(*iter1).begin();iter2!=(*iter1).end();iter2++) - { - _deno_multiply[idx][(*iter2).first]=denoPtr[(*iter2).first]; - _deno_reverse_multiply[(*iter2).first][idx]=denoRPtr[idx]; - } - deno->decrRef(); - denoR->decrRef(); - break; - } - case IntegralGlobConstraint: - { - ComputeColSumAndRowSum(_matrix,_deno_multiply,_deno_reverse_multiply); - break; - } - case RevIntegral: - { - 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) - { - double *denoRPtr2=denoR->getArray()->getPointer(); - denoRPtr2[0]=std::accumulate(denoPtr,denoPtr+deno->getNumberOfTuples(),0.); - } - if(srcField->getMesh()->getMeshDimension()==-1) - { - double *denoPtr2=deno->getArray()->getPointer(); - denoPtr2[0]=std::accumulate(denoRPtr,denoRPtr+denoR->getNumberOfTuples(),0.); - } - int idx=0; - for(std::vector >::const_iterator iter1=_matrix.begin();iter1!=_matrix.end();iter1++,idx++) - for(std::map::const_iterator iter2=(*iter1).begin();iter2!=(*iter1).end();iter2++) - { - _deno_multiply[idx][(*iter2).first]=denoPtr[idx]; - _deno_reverse_multiply[(*iter2).first][idx]=denoRPtr[(*iter2).first]; - } - deno->decrRef(); - denoR->decrRef(); - break; - } - case NoNature: - throw INTERP_KERNEL::Exception("No nature specified ! Select one !"); - } -} - -void MEDCouplingRemapper::computeProduct(const double *inputPointer, int inputNbOfCompo, bool isDftVal, double dftValue, double *resPointer) -{ - int idx=0; - double *tmp=new double[inputNbOfCompo]; - for(std::vector >::const_iterator iter1=_matrix.begin();iter1!=_matrix.end();iter1++,idx++) - { - if((*iter1).empty()) - { - if(isDftVal) - std::fill(resPointer+idx*inputNbOfCompo,resPointer+(idx+1)*inputNbOfCompo,dftValue); - continue; - } - else - std::fill(resPointer+idx*inputNbOfCompo,resPointer+(idx+1)*inputNbOfCompo,0.); - std::map::const_iterator iter3=_deno_multiply[idx].begin(); - for(std::map::const_iterator iter2=(*iter1).begin();iter2!=(*iter1).end();iter2++,iter3++) - { - std::transform(inputPointer+(*iter2).first*inputNbOfCompo,inputPointer+((*iter2).first+1)*inputNbOfCompo,tmp,std::bind2nd(std::multiplies(),(*iter2).second/(*iter3).second)); - std::transform(tmp,tmp+inputNbOfCompo,resPointer+idx*inputNbOfCompo,resPointer+idx*inputNbOfCompo,std::plus()); - } - } - delete [] tmp; -} - -void MEDCouplingRemapper::computeReverseProduct(const double *inputPointer, int inputNbOfCompo, double dftValue, double *resPointer) -{ - std::vector isReached(_deno_reverse_multiply.size(),false); - int idx=0; - double *tmp=new double[inputNbOfCompo]; - std::fill(resPointer,resPointer+inputNbOfCompo*_deno_reverse_multiply.size(),0.); - for(std::vector >::const_iterator iter1=_matrix.begin();iter1!=_matrix.end();iter1++,idx++) - { - for(std::map::const_iterator iter2=(*iter1).begin();iter2!=(*iter1).end();iter2++) - { - isReached[(*iter2).first]=true; - std::transform(inputPointer+idx*inputNbOfCompo,inputPointer+(idx+1)*inputNbOfCompo,tmp,std::bind2nd(std::multiplies(),(*iter2).second/_deno_reverse_multiply[(*iter2).first][idx])); - std::transform(tmp,tmp+inputNbOfCompo,resPointer+((*iter2).first)*inputNbOfCompo,resPointer+((*iter2).first)*inputNbOfCompo,std::plus()); - } - } - delete [] tmp; - idx=0; - for(std::vector::const_iterator iter3=isReached.begin();iter3!=isReached.end();iter3++,idx++) - if(!*iter3) - std::fill(resPointer+idx*inputNbOfCompo,resPointer+(idx+1)*inputNbOfCompo,dftValue); -} - -void MEDCouplingRemapper::ReverseMatrix(const std::vector >& matIn, int nbColsMatIn, std::vector >& matOut) -{ - matOut.resize(nbColsMatIn); - int id=0; - for(std::vector >::const_iterator iter1=matIn.begin();iter1!=matIn.end();iter1++,id++) - for(std::map::const_iterator iter2=(*iter1).begin();iter2!=(*iter1).end();iter2++) - matOut[(*iter2).first][id]=(*iter2).second; -} - -void MEDCouplingRemapper::ComputeRowSumAndColSum(const std::vector >& matrixDeno, - std::vector >& deno, std::vector >& denoReverse) -{ - std::map values; - int idx=0; - for(std::vector >::const_iterator iter1=matrixDeno.begin();iter1!=matrixDeno.end();iter1++,idx++) - { - double sum=0.; - for(std::map::const_iterator iter2=(*iter1).begin();iter2!=(*iter1).end();iter2++) - { - sum+=(*iter2).second; - values[(*iter2).first]+=(*iter2).second; - } - for(std::map::const_iterator iter2=(*iter1).begin();iter2!=(*iter1).end();iter2++) - deno[idx][(*iter2).first]=sum; - } - idx=0; - for(std::vector >::const_iterator iter1=matrixDeno.begin();iter1!=matrixDeno.end();iter1++,idx++) - { - for(std::map::const_iterator iter2=(*iter1).begin();iter2!=(*iter1).end();iter2++) - denoReverse[(*iter2).first][idx]=values[(*iter2).first]; - } -} - -void MEDCouplingRemapper::ComputeColSumAndRowSum(const std::vector >& matrixDeno, - std::vector >& deno, std::vector >& denoReverse) -{ - std::map values; - int idx=0; - for(std::vector >::const_iterator iter1=matrixDeno.begin();iter1!=matrixDeno.end();iter1++,idx++) - { - double sum=0.; - for(std::map::const_iterator iter2=(*iter1).begin();iter2!=(*iter1).end();iter2++) - { - sum+=(*iter2).second; - values[(*iter2).first]+=(*iter2).second; - } - for(std::map::const_iterator iter2=(*iter1).begin();iter2!=(*iter1).end();iter2++) - denoReverse[(*iter2).first][idx]=sum; - } - idx=0; - for(std::vector >::const_iterator iter1=matrixDeno.begin();iter1!=matrixDeno.end();iter1++,idx++) - { - for(std::map::const_iterator iter2=(*iter1).begin();iter2!=(*iter1).end();iter2++) - deno[idx][(*iter2).first]=values[(*iter2).first]; - } -} - -void MEDCouplingRemapper::buildFinalInterpolationMatrixByConvolution(const std::vector< std::map >& m1D, - const std::vector< std::map >& m2D, - const int *corrCellIdSrc, int nbOf2DCellsSrc, int nbOf1DCellsSrc, - const int *corrCellIdTrg) -{ - int nbOf2DCellsTrg=m2D.size(); - int nbOf1DCellsTrg=m1D.size(); - int nbOf3DCellsTrg=nbOf2DCellsTrg*nbOf1DCellsTrg; - _matrix.resize(nbOf3DCellsTrg); - int id2R=0; - for(std::vector< std::map >::const_iterator iter2R=m2D.begin();iter2R!=m2D.end();iter2R++,id2R++) - { - for(std::map::const_iterator iter2C=(*iter2R).begin();iter2C!=(*iter2R).end();iter2C++) - { - int id1R=0; - for(std::vector< std::map >::const_iterator iter1R=m1D.begin();iter1R!=m1D.end();iter1R++,id1R++) - { - for(std::map::const_iterator iter1C=(*iter1R).begin();iter1C!=(*iter1R).end();iter1C++) - { - _matrix[corrCellIdTrg[id1R*nbOf2DCellsTrg+id2R]][corrCellIdSrc[(*iter1C).first*nbOf2DCellsSrc+(*iter2C).first]]=(*iter1C).second*((*iter2C).second); - } - } - } - } -} - -void MEDCouplingRemapper::PrintMatrix(const std::vector >& m) -{ - int id=0; - for(std::vector >::const_iterator iter1=m.begin();iter1!=m.end();iter1++,id++) - { - std::cout << "Target Cell # " << id << " : "; - for(std::map::const_iterator iter2=(*iter1).begin();iter2!=(*iter1).end();iter2++) - std::cout << "(" << (*iter2).first << "," << (*iter2).second << "), "; - std::cout << std::endl; - } -} - -const std::vector >& MEDCouplingRemapper::getCrudeMatrix() const -{ - return _matrix; -} - -/*! - * Returns the number of columns of matrix returned by MEDCouplingRemapper::getCrudeMatrix method. - */ -int MEDCouplingRemapper::getNumberOfColsOfMatrix() const -{ - return (int)_deno_reverse_multiply.size(); -} - -/*! - * This method is supposed to be called , if needed, right after MEDCouplingRemapper::prepare or MEDCouplingRemapper::prepareEx. - * If not the behaviour is unpredictable. - * This method works on precomputed \a this->_matrix. All coefficients in the matrix is lower than \a maxValAbs this coefficient is - * set to 0. That is to say that its entry disappear from the map storing the corresponding row in the data storage of sparse crude matrix. - * This method is useful to correct at a high level some problems linked to precision. Indeed, with some \ref NatureOfField "natures of field" some threshold effect - * can occur. - * - * \param [in] maxValAbs is a limit behind which a coefficient is set to 0. \a maxValAbs is expected to be positive, if not this method do nothing. - * \return a positive value that tells the number of coefficients put to 0. The 0 returned value means that the matrix has remained unchanged. - * \sa MEDCouplingRemapper::nullifiedTinyCoeffInCrudeMatrix - */ -int MEDCouplingRemapper::nullifiedTinyCoeffInCrudeMatrixAbs(double maxValAbs) -{ - int ret=0; - std::vector > matrixNew(_matrix.size()); - int i=0; - for(std::vector >::const_iterator it1=_matrix.begin();it1!=_matrix.end();it1++,i++) - { - std::map& rowNew=matrixNew[i]; - for(std::map::const_iterator it2=(*it1).begin();it2!=(*it1).end();it2++) - { - if(fabs((*it2).second)>maxValAbs) - rowNew[(*it2).first]=(*it2).second; - else - ret++; - } - } - if(ret>0) - _matrix=matrixNew; - return ret; -} - -/*! - * This method is supposed to be called , if needed, right after MEDCouplingRemapper::prepare or MEDCouplingRemapper::prepareEx. - * If not the behaviour is unpredictable. - * This method works on precomputed \a this->_matrix. All coefficients in the matrix is lower than delta multiplied by \a scaleFactor this coefficient is - * set to 0. That is to say that its entry disappear from the map storing the corresponding row in the data storage of sparse crude matrix. - * delta is the value returned by MEDCouplingRemapper::getMaxValueInCrudeMatrix method. - * This method is useful to correct at a high level some problems linked to precision. Indeed, with some \ref NatureOfField "natures of field" some threshold effect - * can occur. - * - * \param [in] scaleFactor is the scale factor from which coefficients lower than \a scaleFactor times range width of coefficients are set to zero. - * \return a positive value that tells the number of coefficients put to 0. The 0 returned value means that the matrix has remained unchanged. If -1 is returned it means - * that all coefficients are null. - * \sa MEDCouplingRemapper::nullifiedTinyCoeffInCrudeMatrixAbs - */ -int MEDCouplingRemapper::nullifiedTinyCoeffInCrudeMatrix(double scaleFactor) -{ - double maxVal=getMaxValueInCrudeMatrix(); - if(maxVal==0.) - return -1; - return nullifiedTinyCoeffInCrudeMatrixAbs(scaleFactor*maxVal); -} - -/*! - * This method is supposed to be called , if needed, right after MEDCouplingRemapper::prepare or MEDCouplingRemapper::prepareEx. - * If not the behaviour is unpredictable. - * This method returns the maximum of the absolute values of coefficients into the sparse crude matrix. - * The returned value is positive. - */ -double MEDCouplingRemapper::getMaxValueInCrudeMatrix() const -{ - double ret=0.; - for(std::vector >::const_iterator it1=_matrix.begin();it1!=_matrix.end();it1++) - for(std::map::const_iterator it2=(*it1).begin();it2!=(*it1).end();it2++) - if(fabs((*it2).second)>ret) - ret=fabs((*it2).second); - return ret; -} diff --git a/src/MEDCoupling/MEDCouplingRemapper.hxx b/src/MEDCoupling/MEDCouplingRemapper.hxx deleted file mode 100644 index 61bee847d..000000000 --- a/src/MEDCoupling/MEDCouplingRemapper.hxx +++ /dev/null @@ -1,123 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 -// 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_MEDCOUPLINGREMAPPER_HXX__ -#define __PARAMEDMEM_MEDCOUPLINGREMAPPER_HXX__ - -#include "MEDCoupling.hxx" -#include "MEDCouplingTimeLabel.hxx" -#include "InterpolationOptions.hxx" -#include "MEDCouplingNatureOfField.hxx" -#include "MEDCouplingAutoRefCountObjectPtr.hxx" - -#include "InterpKernelException.hxx" - -#include -#include - -namespace ParaMEDMEM -{ - class MEDCouplingMesh; - 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: - MEDCOUPLINGREMAPPER_EXPORT MEDCouplingRemapper(); - MEDCOUPLINGREMAPPER_EXPORT ~MEDCouplingRemapper(); - MEDCOUPLINGREMAPPER_EXPORT int prepare(const MEDCouplingMesh *srcMesh, const MEDCouplingMesh *targetMesh, const std::string& method); - MEDCOUPLINGREMAPPER_EXPORT int prepareEx(const MEDCouplingFieldTemplate *src, const MEDCouplingFieldTemplate *target); - MEDCOUPLINGREMAPPER_EXPORT void transfer(const MEDCouplingFieldDouble *srcField, MEDCouplingFieldDouble *targetField, double dftValue); - MEDCOUPLINGREMAPPER_EXPORT void partialTransfer(const MEDCouplingFieldDouble *srcField, MEDCouplingFieldDouble *targetField); - MEDCOUPLINGREMAPPER_EXPORT void reverseTransfer(MEDCouplingFieldDouble *srcField, const MEDCouplingFieldDouble *targetField, double dftValue); - MEDCOUPLINGREMAPPER_EXPORT MEDCouplingFieldDouble *transferField(const MEDCouplingFieldDouble *srcField, double dftValue); - MEDCOUPLINGREMAPPER_EXPORT MEDCouplingFieldDouble *reverseTransferField(const MEDCouplingFieldDouble *targetField, double dftValue); - 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); - // - MEDCOUPLINGREMAPPER_EXPORT int nullifiedTinyCoeffInCrudeMatrixAbs(double maxValAbs); - MEDCOUPLINGREMAPPER_EXPORT int nullifiedTinyCoeffInCrudeMatrix(double scaleFactor); - MEDCOUPLINGREMAPPER_EXPORT double getMaxValueInCrudeMatrix() const; - public: - MEDCOUPLINGREMAPPER_EXPORT const std::vector >& getCrudeMatrix() const; - MEDCOUPLINGREMAPPER_EXPORT int getNumberOfColsOfMatrix() const; - MEDCOUPLINGREMAPPER_EXPORT static void PrintMatrix(const std::vector >& m); - MEDCOUPLINGREMAPPER_EXPORT static std::string BuildMethodFrom(const std::string& meth1, const std::string& meth2); - private: - int prepareInterpKernelOnly(); - int prepareInterpKernelOnlyUU(); - int prepareInterpKernelOnlyEE(); - int prepareInterpKernelOnlyUC(); - int prepareInterpKernelOnlyCU(); - int prepareInterpKernelOnlyCC(); - // - int prepareNotInterpKernelOnly(); - int prepareNotInterpKernelOnlyGaussGauss(); - // - static int CheckInterpolationMethodManageableByNotOnlyInterpKernel(const std::string& method); - // - bool isInterpKernelOnlyOrNotOnly() const; - void updateTime() const; - void checkPrepare() const; - std::string checkAndGiveInterpolationMethodStr(std::string& srcMeth, std::string& trgMeth) const; - void releaseData(bool matrixSuppression); - void transferUnderground(const MEDCouplingFieldDouble *srcField, MEDCouplingFieldDouble *targetField, bool isDftVal, double dftValue); - void computeDeno(NatureOfField nat, const MEDCouplingFieldDouble *srcField, const MEDCouplingFieldDouble *trgField); - void computeDenoFromScratch(NatureOfField nat, const MEDCouplingFieldDouble *srcField, const MEDCouplingFieldDouble *trgField); - void computeProduct(const double *inputPointer, int inputNbOfCompo, bool isDftVal, double dftValue, double *resPointer); - void computeReverseProduct(const double *inputPointer, int inputNbOfCompo, double dftValue, double *resPointer); - void buildFinalInterpolationMatrixByConvolution(const std::vector< std::map >& m1D, - const std::vector< std::map >& m2D, - const int *corrCellIdSrc, int nbOf2DCellsSrc, int nbOf1DCellsSrc, - const int *corrCellIdTrg); - static void ReverseMatrix(const std::vector >& matIn, int nbColsMatIn, - std::vector >& matOut); - static void ComputeRowSumAndColSum(const std::vector >& matrixDeno, - std::vector >& deno, std::vector >& denoReverse); - static void ComputeColSumAndRowSum(const std::vector >& matrixDeno, - std::vector >& deno, std::vector >& denoReverse); - private: - MEDCouplingAutoRefCountObjectPtr _src_ft; - MEDCouplingAutoRefCountObjectPtr _target_ft; - InterpolationMatrixPolicy _interp_matrix_pol; - NatureOfField _nature_of_deno; - unsigned int _time_deno_update; - std::vector > _matrix; - std::vector > _deno_multiply; - std::vector > _deno_reverse_multiply; - }; -} - -#endif diff --git a/src/MEDCoupling/MEDCouplingSkyLineArray.cxx b/src/MEDCoupling/MEDCouplingSkyLineArray.cxx deleted file mode 100644 index 87f1bae2d..000000000 --- a/src/MEDCoupling/MEDCouplingSkyLineArray.cxx +++ /dev/null @@ -1,102 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// - -#include "MEDCouplingSkyLineArray.hxx" - -using namespace ParaMEDMEM; - -MEDCouplingSkyLineArray::MEDCouplingSkyLineArray(): - _index( DataArrayInt::New() ), _value( DataArrayInt::New() ) -{ -} - -MEDCouplingSkyLineArray::MEDCouplingSkyLineArray(const MEDCouplingSkyLineArray &myArray) -{ - _index=myArray._index; - _value=myArray._value; -} - -MEDCouplingSkyLineArray::~MEDCouplingSkyLineArray() -{ -} - -MEDCouplingSkyLineArray::MEDCouplingSkyLineArray(DataArrayInt* index, DataArrayInt* value) -{ - set( index, value ); -} - -MEDCouplingSkyLineArray::MEDCouplingSkyLineArray( const std::vector& index, - const std::vector& value ): - _index( DataArrayInt::New() ), _value( DataArrayInt::New() ) -{ - _index->reserve( index.size() ); - _index->insertAtTheEnd( index.begin(), index.end() ); - _value->reserve( value.size() ); - _value->insertAtTheEnd( value.begin(), value.end() ); -} - -void MEDCouplingSkyLineArray::set( DataArrayInt* index, DataArrayInt* value ) -{ - _index=index; - _value=value; - if ( (DataArrayInt*)_index ) _index->incrRef(); - else _index = DataArrayInt::New(); - if ( (DataArrayInt*)_value ) _value->incrRef(); - else _value = DataArrayInt::New(); -} - -DataArrayInt* MEDCouplingSkyLineArray::getIndexArray() const -{ - return ((MEDCouplingSkyLineArray*)this)->_index; -} - -DataArrayInt* MEDCouplingSkyLineArray::getValueArray() const -{ - return ((MEDCouplingSkyLineArray*)this)->_value; -} - -std::string MEDCouplingSkyLineArray::simpleRepr() const -{ - std::ostringstream oss; - oss << "MEDCouplingSkyLineArray" << std::endl; - oss << " Nb of items: " << getNumberOf() << std::endl; - oss << " Nb of values: " << getLength() << std::endl; - oss << " Index:" << std::endl; - oss << " "; - const int * i = _index->begin(); - for ( ; i != _index->end(); ++i ) - oss << *i << " "; - oss << std::endl; - oss << " Value:" << std::endl; - oss << " "; - const int * v = _value->begin(); - int cnt = 0; - for ( i = _index->begin(); v != _value->end(); ++v, ++cnt ) - { - if ( cnt == *i ) - { - oss << "| "; - ++i; - } - oss << *v << " "; - } - oss << std::endl; - - return oss.str(); -} diff --git a/src/MEDCoupling/MEDCouplingSkyLineArray.hxx b/src/MEDCoupling/MEDCouplingSkyLineArray.hxx deleted file mode 100644 index c12dc6b68..000000000 --- a/src/MEDCoupling/MEDCouplingSkyLineArray.hxx +++ /dev/null @@ -1,56 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 -// 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 __PARAMEDMEM_MEDCOUPLINGSKYLINEARRAY_HXX__ -#define __PARAMEDMEM_MEDCOUPLINGSKYLINEARRAY_HXX__ - -#include "MEDCoupling.hxx" -#include "MEDCouplingMemArray.hxx" -#include "MEDCouplingAutoRefCountObjectPtr.hxx" - -#include - -namespace ParaMEDMEM -{ - class MEDCOUPLING_EXPORT MEDCouplingSkyLineArray - { - private: - MEDCouplingAutoRefCountObjectPtr _index; - MEDCouplingAutoRefCountObjectPtr _value; - public: - MEDCouplingSkyLineArray(); - MEDCouplingSkyLineArray( const MEDCouplingSkyLineArray &myArray ); - MEDCouplingSkyLineArray( const std::vector& index, const std::vector& value ); - MEDCouplingSkyLineArray( DataArrayInt* index, DataArrayInt* value ); - ~MEDCouplingSkyLineArray(); - - void set( DataArrayInt* index, DataArrayInt* value ); - - int getNumberOf() const { return _index->getNbOfElems()-1; } - int getLength() const { return _value->getNbOfElems(); } - const int* getIndex() const { return _index->begin(); } - const int* getValue() const { return _value->begin(); } - - DataArrayInt* getIndexArray() const; - DataArrayInt* getValueArray() const; - - std::string simpleRepr() const; - }; -} -# endif diff --git a/src/MEDCoupling/MEDCouplingStructuredMesh.cxx b/src/MEDCoupling/MEDCouplingStructuredMesh.cxx deleted file mode 100644 index ceec53712..000000000 --- a/src/MEDCoupling/MEDCouplingStructuredMesh.cxx +++ /dev/null @@ -1,2109 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 -// 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 "MEDCoupling1GTUMesh.hxx" -#include "MEDCouplingUMesh.hxx" -#include "MEDCouplingIMesh.hxx"//tony to throw when optimization will be performed in AssignPartOfFieldOfDoubleUsing - -#include - -using namespace ParaMEDMEM; - -MEDCouplingStructuredMesh::MEDCouplingStructuredMesh() -{ -} - -MEDCouplingStructuredMesh::MEDCouplingStructuredMesh(const MEDCouplingStructuredMesh& other, bool deepCopy):MEDCouplingMesh(other) -{ -} - -MEDCouplingStructuredMesh::~MEDCouplingStructuredMesh() -{ -} - -std::size_t MEDCouplingStructuredMesh::getHeapMemorySizeWithoutChildren() const -{ - return MEDCouplingMesh::getHeapMemorySizeWithoutChildren(); -} - -void MEDCouplingStructuredMesh::copyTinyStringsFrom(const MEDCouplingMesh *other) -{ - MEDCouplingMesh::copyTinyStringsFrom(other); -} - -bool MEDCouplingStructuredMesh::isEqualIfNotWhy(const MEDCouplingMesh *other, double prec, std::string& reason) const -{ - return MEDCouplingMesh::isEqualIfNotWhy(other,prec,reason); -} - -INTERP_KERNEL::NormalizedCellType MEDCouplingStructuredMesh::getTypeOfCell(int cellId) const -{ - return GetGeoTypeGivenMeshDimension(getMeshDimension()); -} - -INTERP_KERNEL::NormalizedCellType MEDCouplingStructuredMesh::GetGeoTypeGivenMeshDimension(int meshDim) -{ - switch(meshDim) - { - case 3: - return INTERP_KERNEL::NORM_HEXA8; - case 2: - return INTERP_KERNEL::NORM_QUAD4; - case 1: - return INTERP_KERNEL::NORM_SEG2; - case 0: - return INTERP_KERNEL::NORM_POINT1; - default: - throw INTERP_KERNEL::Exception("Unexpected dimension for MEDCouplingStructuredMesh::GetGeoTypeGivenMeshDimension !"); - } -} - -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 -{ - 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 -{ - 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 -{ - 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(); -} - -/*! - * This method computes effective number of nodes per cell. That is to say nodes appearing several times in nodal connectivity of a cell, - * will be counted only once here whereas it will be counted several times in MEDCouplingMesh::computeNbOfNodesPerCell method. - * Here for structured mesh it returns exactly as MEDCouplingStructuredMesh::computeNbOfNodesPerCell does. - * - * \return DataArrayInt * - new object to be deallocated by the caller. - */ -DataArrayInt *MEDCouplingStructuredMesh::computeEffectiveNbOfNodesPerCell() const -{ - return computeNbOfNodesPerCell(); -} - -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]*tmpNode[1]+tmp2[0]); conn.push_back(tmp2[1]*tmpNode[1]+tmp2[0]+1); - conn.push_back((tmp2[1]+1)*tmpNode[1]+tmp2[0]+1); conn.push_back((tmp2[1]+1)*tmpNode[1]+tmp2[0]); - break; - case 3: - conn.push_back(tmp2[1]*tmpNode[1]+tmp2[0]+tmp2[2]*tmpNode[2]); conn.push_back(tmp2[1]*tmpNode[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]*tmpNode[1]+tmp2[0]+(tmp2[2]+1)*tmpNode[2]); conn.push_back(tmp2[1]*tmpNode[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 !"); - }; -} - -/*! - * This method returns the mesh dimension of \a this. It can be different from space dimension in case of a not null dimension contains only one node. - */ -int MEDCouplingStructuredMesh::getMeshDimension() const -{ - std::vector ngs(getNodeGridStructure()); - int ret(0),pos(0); - for(std::vector::const_iterator it=ngs.begin();it!=ngs.end();it++,pos++) - { - if(*it<=0) - { - std::ostringstream oss; oss << "MEDCouplingStructuredMesh::getMeshDimension : At pos #" << pos << " number of nodes is " << *it << " ! Must be > 0 !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - if(*it>1) - ret++; - } - return ret; -} - -/*! - * This method returns the space dimension by only considering the node grid structure. - * For cartesian mesh the returned value is equal to those returned by getSpaceDimension. - * But for curvelinear is could be different ! - */ -int MEDCouplingStructuredMesh::getSpaceDimensionOnNodeStruct() const -{ - std::vector nodeStr(getNodeGridStructure()); - int spd1(0),pos(0); - for(std::vector::const_iterator it=nodeStr.begin();it!=nodeStr.end();it++,pos++) - { - int elt(*it); - if(elt<=0) - { - std::ostringstream oss; oss << "MEDCouplingStructuredMesh::getSpaceDimensionOnNodeStruct : At pos #" << pos << " value of node grid structure is " << *it << " ! must be >=1 !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - spd1++; - } - return spd1; -} - -void MEDCouplingStructuredMesh::getSplitCellValues(int *res) const -{ - std::vector strct(getCellGridStructure()); - std::vector ret(MEDCouplingStructuredMesh::GetSplitVectFromStruct(strct)); - std::copy(ret.begin(),ret.end(),res); -} - -void MEDCouplingStructuredMesh::getSplitNodeValues(int *res) const -{ - std::vector strct(getNodeGridStructure()); - std::vector ret(MEDCouplingStructuredMesh::GetSplitVectFromStruct(strct)); - std::copy(ret.begin(),ret.end(),res); -} - -/*! - * This method returns the number of cells of unstructured sub level mesh, without building it. - */ -int MEDCouplingStructuredMesh::getNumberOfCellsOfSubLevelMesh() const -{ - std::vector cgs(getCellGridStructure()); - return GetNumberOfCellsOfSubLevelMesh(cgs,getMeshDimension()); -} - -/*! - * See MEDCouplingUMesh::getDistributionOfTypes for more information - */ -std::vector MEDCouplingStructuredMesh::getDistributionOfTypes() const -{ - //only one type of cell - std::vector ret(3); - ret[0]=getTypeOfCell(0); - ret[1]=getNumberOfCells(); - ret[2]=-1; //ret[3*k+2]==-1 because it has no sense here - return ret; -} - -/*! - * This method tries to minimize at most the number of deep copy. - * So if \a idsPerType is not empty it can be returned directly (without copy, but with ref count incremented) in return. - * - * See MEDCouplingUMesh::checkTypeConsistencyAndContig for more information - */ -DataArrayInt *MEDCouplingStructuredMesh::checkTypeConsistencyAndContig(const std::vector& code, const std::vector& idsPerType) const -{ - int nbOfCells=getNumberOfCells(); - if(code.size()!=3) - throw INTERP_KERNEL::Exception("MEDCouplingStructuredMesh::checkTypeConsistencyAndContig : invalid input code should be exactly of size 3 !"); - if(code[0]!=(int)getTypeOfCell(0)) - { - std::ostringstream oss; oss << "MEDCouplingStructuredMesh::checkTypeConsistencyAndContig : Mismatch of geometric type ! Asking for " << code[0] << " whereas the geometric type is \a this is " << getTypeOfCell(0) << " !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - if(code[2]==-1) - { - if(code[1]==nbOfCells) - return 0; - else - { - std::ostringstream oss; oss << "MEDCouplingStructuredMesh::checkTypeConsistencyAndContig : mismatch between the number of cells in this (" << nbOfCells << ") and the number of non profile (" << code[1] << ") !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - } - if(code[2]!=0) - throw INTERP_KERNEL::Exception("MEDCouplingStructuredMesh::checkTypeConsistencyAndContig : single geo type mesh ! 0 or -1 is expected at pos #2 of input code !"); - if(idsPerType.size()!=1) - throw INTERP_KERNEL::Exception("MEDCouplingStructuredMesh::checkTypeConsistencyAndContig : input code points to DataArrayInt #0 whereas the size of idsPerType is not equal to 1 !"); - const DataArrayInt *pfl=idsPerType[0]; - if(!pfl) - throw INTERP_KERNEL::Exception("MEDCouplingStructuredMesh::checkTypeConsistencyAndContig : the input code points to a NULL DataArrayInt at rank 0 !"); - if(pfl->getNumberOfComponents()!=1) - throw INTERP_KERNEL::Exception("MEDCouplingStructuredMesh::checkTypeConsistencyAndContig : input profile should have exactly one component !"); - pfl->checkAllIdsInRange(0,nbOfCells); - pfl->incrRef(); - return const_cast(pfl); -} - -/*! - * This method is the opposite of MEDCouplingUMesh::checkTypeConsistencyAndContig method. Given a list of cells in \a profile it returns a list of sub-profiles sorted by geo type. - * The result is put in the array \a idsPerType. In the returned parameter \a code, foreach i \a code[3*i+2] refers (if different from -1) to a location into the \a idsPerType. - * This method has 1 input \a profile and 3 outputs \a code \a idsInPflPerType and \a idsPerType. - * - * \param [out] code is a vector of size 3*n where n is the number of different geometric type in \a this \b reduced to the profile \a profile. \a code has exactly the same semantic than in MEDCouplingUMesh::checkTypeConsistencyAndContig method. - * \param [out] idsInPflPerType is a vector of size of different geometric type in the subpart defined by \a profile of \a this ( equal to \a code.size()/3). For each i, - * \a idsInPflPerType[i] stores the tuple ids in \a profile that correspond to the geometric type code[3*i+0] - * \param [out] idsPerType is a vector of size of different sub profiles needed to be defined to represent the profile \a profile for a given geometric type. - * This vector can be empty in case of all geometric type cells are fully covered in ascending in the given input \a profile. - * - * \warning for performance reasons no deep copy will be performed, if \a profile can been used as this in output parameters \a idsInPflPerType and \a idsPerType. - * - * \throw if \a profile has not exactly one component. It throws too, if \a profile contains some values not in [0,getNumberOfCells()) or if \a this is not fully defined - * - * \b Example1:
- * - Before \a this has 3 cells \a profile contains [0,1,2] - * - After \a code contains [NORM_...,nbCells,-1], \a idsInPflPerType [[0,1,2]] and \a idsPerType is empty
- * - * \b Example2:
- * - Before \a this has 3 cells \a profile contains [1,2] - * - After \a code contains [NORM_...,nbCells,0], \a idsInPflPerType [[0,1]] and \a idsPerType is [[1,2]]
- - */ -void MEDCouplingStructuredMesh::splitProfilePerType(const DataArrayInt *profile, std::vector& code, std::vector& idsInPflPerType, std::vector& idsPerType) const -{ - if(!profile || !profile->isAllocated()) - throw INTERP_KERNEL::Exception("MEDCouplingStructuredMesh::splitProfilePerType : input profile is NULL or not allocated !"); - if(profile->getNumberOfComponents()!=1) - throw INTERP_KERNEL::Exception("MEDCouplingStructuredMesh::splitProfilePerType : input profile should have exactly one component !"); - int nbTuples(profile->getNumberOfTuples()); - int nbOfCells=getNumberOfCells(); - code.resize(3); idsInPflPerType.resize(1); - code[0]=(int)getTypeOfCell(0); code[1]=nbOfCells; - idsInPflPerType.resize(1); - if(profile->isIdentity2(nbOfCells)) - { - code[2]=-1; - idsInPflPerType[0]=profile->deepCpy(); - idsPerType.clear(); - return ; - } - code[1]=profile->getNumberOfTuples(); - code[2]=0; - profile->checkAllIdsInRange(0,nbOfCells); - idsPerType.resize(1); - idsPerType[0]=profile->deepCpy(); - idsInPflPerType[0]=DataArrayInt::Range(0,nbTuples,1); -} - -/*! - * Creates a new unstructured mesh (MEDCoupling1SGTUMesh) 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]. - */ -MEDCoupling1SGTUMesh *MEDCouplingStructuredMesh::build1SGTUnstructured() const -{ - int meshDim(getMeshDimension()),spaceDim(getSpaceDimensionOnNodeStruct()); - if((meshDim<0 || meshDim>3) || (spaceDim<0 || spaceDim>3)) - throw INTERP_KERNEL::Exception("MEDCouplingStructuredMesh::build1SGTUnstructured : meshdim and spacedim must be in [1,2,3] !"); - MEDCouplingAutoRefCountObjectPtr coords(getCoordinatesAndOwner()); - int ns[3]; - getNodeGridStructure(ns); - MEDCouplingAutoRefCountObjectPtr conn(Build1GTNodalConnectivity(ns,ns+spaceDim)); - MEDCouplingAutoRefCountObjectPtr ret(MEDCoupling1SGTUMesh::New(getName(),GetGeoTypeGivenMeshDimension(meshDim))); - ret->setNodalConnectivity(conn); ret->setCoords(coords); - try - { ret->copyTinyInfoFrom(this); } - catch(INTERP_KERNEL::Exception&) { } - return ret.retn(); -} - -/*! - * This method returns the unstructured mesh (having single geometric type) of the sub level mesh of \a this. - * This method is equivalent to computing MEDCouplingUMesh::buildDescendingConnectivity on the unstructurized \a this mesh. - * - * The caller is to delete the returned mesh using decrRef() as it is no more needed. - */ -MEDCoupling1SGTUMesh *MEDCouplingStructuredMesh::build1SGTSubLevelMesh() const -{ - int meshDim(getMeshDimension()); - if(meshDim<1 || meshDim>3) - throw INTERP_KERNEL::Exception("MEDCouplingStructuredMesh::build1SGTSubLevelMesh : meshdim must be in [2,3] !"); - MEDCouplingAutoRefCountObjectPtr coords(getCoordinatesAndOwner()); - int ns[3]; - getNodeGridStructure(ns); - MEDCouplingAutoRefCountObjectPtr conn(Build1GTNodalConnectivityOfSubLevelMesh(ns,ns+meshDim)); - MEDCouplingAutoRefCountObjectPtr ret(MEDCoupling1SGTUMesh::New(getName(),GetGeoTypeGivenMeshDimension(meshDim-1))); - ret->setNodalConnectivity(conn); ret->setCoords(coords); - return ret.retn(); -} - -/*! - * 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 -{ - MEDCouplingAutoRefCountObjectPtr ret0(build1SGTUnstructured()); - return ret0->buildUnstructured(); -} - -/*! - * 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 -{ - std::vector cgs(getCellGridStructure()); - std::vector< std::pair > cellPartFormat,nodePartFormat; - if(IsPartStructured(start,end,cgs,cellPartFormat)) - { - MEDCouplingAutoRefCountObjectPtr ret(buildStructuredSubPart(cellPartFormat)); - nodePartFormat=cellPartFormat; - for(std::vector< std::pair >::iterator it=nodePartFormat.begin();it!=nodePartFormat.end();it++) - (*it).second++; - MEDCouplingAutoRefCountObjectPtr tmp1(BuildExplicitIdsFrom(getNodeGridStructure(),nodePartFormat)); - MEDCouplingAutoRefCountObjectPtr tmp2(DataArrayInt::New()); tmp2->alloc(getNumberOfNodes(),1); - tmp2->fillWithValue(-1); - MEDCouplingAutoRefCountObjectPtr tmp3(DataArrayInt::New()); tmp3->alloc(tmp1->getNumberOfTuples(),1); tmp3->iota(0); - tmp2->setPartOfValues3(tmp3,tmp1->begin(),tmp1->end(),0,1,1); - arr=tmp2.retn(); - return ret.retn(); - } - else - { - MEDCouplingUMesh *um=buildUnstructured(); - MEDCouplingMesh *ret=um->buildPartAndReduceNodes(start,end,arr); - um->decrRef(); - return ret; - } -} - -DataArrayInt *MEDCouplingStructuredMesh::simplexize(int policy) -{ - 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::getReverseNodalConnectivity(DataArrayInt *revNodal, DataArrayInt *revNodalIndx) const -{ - std::vector ngs(getNodeGridStructure()); - int dim(getSpaceDimension()); - switch(dim) - { - case 1: - return GetReverseNodalConnectivity1(ngs,revNodal,revNodalIndx); - case 2: - return GetReverseNodalConnectivity2(ngs,revNodal,revNodalIndx); - case 3: - return GetReverseNodalConnectivity3(ngs,revNodal,revNodalIndx); - default: - throw INTERP_KERNEL::Exception("MEDCouplingStructuredMesh::getReverseNodalConnectivity : only dimensions 1, 2 and 3 are supported !"); - } -} - -void MEDCouplingStructuredMesh::GetReverseNodalConnectivity1(const std::vector& ngs, DataArrayInt *revNodal, DataArrayInt *revNodalIndx) -{ - int nbNodes(ngs[0]); - revNodalIndx->alloc(nbNodes+1,1); - if(nbNodes==0) - { revNodal->alloc(0,1); revNodalIndx->setIJ(0,0,0); return ; } - if(nbNodes==1) - { revNodal->alloc(1,1); revNodal->setIJ(0,0,0); revNodalIndx->setIJ(0,0,0); revNodalIndx->setIJ(1,0,1); return ; } - revNodal->alloc(2*(nbNodes-1),1); - int *rn(revNodal->getPointer()),*rni(revNodalIndx->getPointer()); - *rni++=0; *rni=1; *rn++=0; - for(int i=1;i& ngs, DataArrayInt *revNodal, DataArrayInt *revNodalIndx) -{ - int nbNodesX(ngs[0]),nbNodesY(ngs[1]); - int nbNodes(nbNodesX*nbNodesY); - if(nbNodesX==0 || nbNodesY==0) - { revNodal->alloc(0,1); revNodalIndx->setIJ(0,0,0); return ; } - if(nbNodesX==1 || nbNodesY==1) - { std::vector ngs2(1); ngs2[0]=std::max(nbNodesX,nbNodesY); return GetReverseNodalConnectivity1(ngs2,revNodal,revNodalIndx); } - revNodalIndx->alloc(nbNodes+1,1); - int nbCellsX(nbNodesX-1),nbCellsY(nbNodesY-1); - revNodal->alloc(4*(nbNodesX-2)*(nbNodesY-2)+2*2*(nbNodesX-2)+2*2*(nbNodesY-2)+4,1); - int *rn(revNodal->getPointer()),*rni(revNodalIndx->getPointer()); - *rni++=0; *rni=1; *rn++=0; - for(int i=1;i& ngs, DataArrayInt *revNodal, DataArrayInt *revNodalIndx) -{ - int nbNodesX(ngs[0]),nbNodesY(ngs[1]),nbNodesZ(ngs[2]); - int nbNodes(nbNodesX*nbNodesY*nbNodesZ); - if(nbNodesX==0 || nbNodesY==0 || nbNodesZ==0) - { revNodal->alloc(0,1); revNodalIndx->setIJ(0,0,0); return ; } - if(nbNodesX==1 || nbNodesY==1 || nbNodesZ==1) - { - std::vector ngs2(2); - int pos(0); - bool pass(false); - for(int i=0;i<3;i++) - { - if(pass) - { ngs2[pos++]=ngs[i]; } - else - { - pass=ngs[i]==1; - if(!pass) - { ngs2[pos++]=ngs[i]; } - } - } - return GetReverseNodalConnectivity2(ngs2,revNodal,revNodalIndx); - } - revNodalIndx->alloc(nbNodes+1,1); - int nbCellsX(nbNodesX-1),nbCellsY(nbNodesY-1),nbCellsZ(nbNodesZ-1); - revNodal->alloc(8*(nbNodesX-2)*(nbNodesY-2)*(nbNodesZ-2)+4*(2*(nbNodesX-2)*(nbNodesY-2)+2*(nbNodesX-2)*(nbNodesZ-2)+2*(nbNodesY-2)*(nbNodesZ-2))+2*4*(nbNodesX-2)+2*4*(nbNodesY-2)+2*4*(nbNodesZ-2)+8,1); - int *rn(revNodal->getPointer()),*rni(revNodalIndx->getPointer()); - *rni=0; - for(int k=0;k=1 && j>=1 && i>=1) - *rn++=off00+i-1; - if(k>=1 && j>=1 && i=1 && j=1) - *rn++=off01+i-1; - if(k>=1 && j=1 && i>=1) - *rn++=off10+i-1; - if(k=1 && i=1) - *rn++=off11+i-1; - if(k conn(DataArrayInt::New()); - conn->alloc(1,1); conn->setIJ(0,0,0); - return conn.retn(); - } - case 1: - return Build1GTNodalConnectivity1D(zippedNodeSt); - case 2: - return Build1GTNodalConnectivity2D(zippedNodeSt); - case 3: - return Build1GTNodalConnectivity3D(zippedNodeSt); - default: - throw INTERP_KERNEL::Exception("MEDCouplingStructuredMesh::Build1GTNodalConnectivity : only dimension in [0,1,2,3] supported !"); - } -} - -DataArrayInt *MEDCouplingStructuredMesh::Build1GTNodalConnectivityOfSubLevelMesh(const int *nodeStBg, const int *nodeStEnd) -{ - std::size_t dim(std::distance(nodeStBg,nodeStEnd)); - switch(dim) - { - case 3: - return Build1GTNodalConnectivityOfSubLevelMesh3D(nodeStBg); - case 2: - return Build1GTNodalConnectivityOfSubLevelMesh2D(nodeStBg); - default: - throw INTERP_KERNEL::Exception("MEDCouplingStructuredMesh::Build1GTNodalConnectivityOfSubLevelMesh: only dimension in [2,3] supported !"); - } -} - -/*! - * This method returns the list of ids sorted ascendingly of entities that are in the corner in ghost zone. - * The ids are returned in a newly created DataArrayInt having a single component. - * - * \param [in] st - The structure \b without ghost cells. - * \param [in] ghostLev - The size of the ghost zone (>=0) - * \return DataArrayInt * - The DataArray containing all the ids the caller is to deallocate. - */ -DataArrayInt *MEDCouplingStructuredMesh::ComputeCornersGhost(const std::vector& st, int ghostLev) -{ - if(ghostLev<0) - throw INTERP_KERNEL::Exception("MEDCouplingStructuredMesh::ComputeCornersGhost : ghost lev must be >= 0 !"); - std::size_t dim(st.size()); - MEDCouplingAutoRefCountObjectPtr ret(DataArrayInt::New()); - switch(dim) - { - case 1: - { - ret->alloc(2*ghostLev,1); - int *ptr(ret->getPointer()); - for(int i=0;i= 0 !"); - for(int i=0;i= 0 !"); - ret->alloc(4*ghostLev,1); - int *ptr(ret->getPointer()); - for(int i=0;i= 0 !"); - ret->alloc(8*ghostLev,1); - int *ptr(ret->getPointer()); - int zeOffsetZ((offsetX+2*ghostLev)*(offsetY+2*ghostLev)); - for(int i=0;i=0;i--,j++) - { - *ptr++=i*(2*ghostLev+offsetX+1)+j*zeOffsetZ+zeOffsetZ2; - *ptr++=offsetX+2*ghostLev-1+i*(2*ghostLev+offsetX-1)+j*zeOffsetZ+zeOffsetZ2; - *ptr++=(2*ghostLev+offsetX)*(offsetY+ghostLev)+ghostLev-1+(ghostLev-i-1)*(2*ghostLev+offsetX-1)+j*zeOffsetZ+zeOffsetZ2; - *ptr++=(2*ghostLev+offsetX)*(offsetY+ghostLev)+offsetX+ghostLev+(ghostLev-i-1)*(2*ghostLev+offsetX+1)+j*zeOffsetZ+zeOffsetZ2; - } - break; - } - default: - throw INTERP_KERNEL::Exception("MEDCouplingStructuredMesh::ComputeCornersGhost : Only dimensions 1, 2 and 3 are supported actually !"); - } - return ret.retn(); -} - -/*! - * This method retrieves the number of entities (it can be cells or nodes) given a range in compact standard format - * used in methods like BuildExplicitIdsFrom,IsPartStructured. - * - * \sa BuildExplicitIdsFrom,IsPartStructured - */ -int MEDCouplingStructuredMesh::DeduceNumberOfGivenRangeInCompactFrmt(const std::vector< std::pair >& partCompactFormat) -{ - int ret(1); - std::size_t ii(0); - for(std::vector< std::pair >::const_iterator it=partCompactFormat.begin();it!=partCompactFormat.end();it++,ii++) - { - int a((*it).first),b((*it).second); - if(a<0 || b<0 || b-a<0) - { - std::ostringstream oss; oss << "MEDCouplingStructuredMesh::DeduceNumberOfGivenRangeInCompactFrmt : invalid input at dimension " << ii << " !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - ret*=(b-a); - } - return ret; -} - -int MEDCouplingStructuredMesh::DeduceNumberOfGivenStructure(const std::vector& st) -{ - int ret(1); - bool isFetched(false); - for(std::size_t i=0;i >& partCompactFormat, int& axisId, int& sizeOfRange) -{ - int dim((int)partCompactFormat.size()); - int ret(-1); - for(int i=0;iret) - { - axisId=i; sizeOfRange=curDelta; - ret=curDelta; - } - } -} - -/*! - * This method is \b NOT wrapped in python because it has no sense in python (for performance reasons). - * This method starts from a structured mesh with structure \a st on which a boolean field \a crit is set. - * This method find for such minimalist information of mesh and field which is the part of the mesh, given by the range per axis in output parameter - * \a partCompactFormat that contains all the True in \a crit. The returned vector of boolean is the field reduced to that part. - * So the number of True is equal in \a st and in returned vector of boolean. - * - * \param [in] minPatchLgth - minimum length that the patch may have for all directions. - * \param [in] st - The structure per axis of the structured mesh considered. - * \param [in] crit - The field of boolean (for performance reasons) lying on the mesh defined by \a st. - * \param [out] partCompactFormat - The minimal part of \a st containing all the true of \a crit. - * \param [out] reducedCrit - The reduction of \a criterion on \a partCompactFormat. - * \return - The number of True in \a st (that is equal to those in \a reducedCrit) - */ -int MEDCouplingStructuredMesh::FindMinimalPartOf(int minPatchLgth, const std::vector& st, const std::vector& crit, std::vector& reducedCrit, std::vector< std::pair >& partCompactFormat) -{ - if(minPatchLgth<0) - throw INTERP_KERNEL::Exception("MEDCouplingStructuredMesh::FindMinimalPartOf : the input minPatchLgth has to be >=0 !"); - if((int)crit.size()!=DeduceNumberOfGivenStructure(st)) - throw INTERP_KERNEL::Exception("MEDCouplingStructuredMesh::FindMinimalPartOf : size of vector of boolean is invalid regarding the declared structure !"); - int ret(-1); - switch((int)st.size()) - { - case 1: - { - ret=FindMinimalPartOf1D(st,crit,partCompactFormat); - break; - } - case 2: - { - ret=FindMinimalPartOf2D(st,crit,partCompactFormat); - break; - } - case 3: - { - ret=FindMinimalPartOf3D(st,crit,partCompactFormat); - break; - } - default: - throw INTERP_KERNEL::Exception("MEDCouplingStructuredMesh::FindMinimalPartOf : only dimension 1, 2 and 3 are supported actually !"); - } - std::vector dims(MEDCouplingStructuredMesh::GetDimensionsFromCompactFrmt(partCompactFormat)); - int i(0); - for(std::vector< std::pair >::iterator it=partCompactFormat.begin();it!=partCompactFormat.end();it++,i++) - { - if(st[i]st[i]) - { - (*it).first-=(*it).second-st[i]; - (*it).second=st[i]; - } - } - } - ExtractFieldOfBoolFrom(st,crit,partCompactFormat,reducedCrit); - return ret; -} - -/*! - * This method is \b NOT wrapped in python. - * This method considers \a crit input parameter as a matrix having dimensions specified by \a st. This method returns for each axis - * the signature, that is to say the number of elems equal to true in \a crit along this axis. - */ -std::vector< std::vector > MEDCouplingStructuredMesh::ComputeSignaturePerAxisOf(const std::vector& st, const std::vector& crit) -{ - int dim((int)st.size()); - std::vector< std::vector > ret(dim); - switch(dim) - { - case 1: - { - int nx(st[0]); - ret[0].resize(nx); - std::vector& retX(ret[0]); - for(int i=0;i& retX(ret[0]); - for(int i=0;i& retY(ret[1]); - for(int j=0;j& retX(ret[0]); - for(int i=0;i& retY(ret[1]); - for(int j=0;j& retZ(ret[2]); - for(int k=0;k conn(DataArrayInt::New()); - conn->alloc(2*nbOfCells,1); - int *cp=conn->getPointer(); - for(int i=0;i conn(DataArrayInt::New()); - conn->alloc(4*n1*n2,1); - int *cp=conn->getPointer(); - int pos=0; - for(int j=0;j conn(DataArrayInt::New()); - conn->alloc(8*n1*n2*n3,1); - int *cp=conn->getPointer(); - int pos=0; - for(int k=0;k ngs(3); - int n0(nodeStBg[0]-1),n1(nodeStBg[1]-1),n2(nodeStBg[2]-1); ngs[0]=n0; ngs[1]=n1; ngs[2]=n2; - int off0(nodeStBg[0]),off1(nodeStBg[0]*nodeStBg[1]); - MEDCouplingAutoRefCountObjectPtr conn(DataArrayInt::New()); - conn->alloc(4*GetNumberOfCellsOfSubLevelMesh(ngs,3)); - int *cp(conn->getPointer()); - //X - for(int i=0;i& st, const std::vector& crit, std::vector< std::pair >& partCompactFormat) -{ - if(st.size()!=1) - throw INTERP_KERNEL::Exception("MEDCouplingStructuredMesh::FindMinimalPartOf1D : the input size of st must be equal to 1 !"); - int nxMin(std::numeric_limits::max()),nxMax(-std::numeric_limits::max()); - int nx(st[0]),ret(0); - for(int i=0;i& st, const std::vector& crit, std::vector< std::pair >& partCompactFormat) -{ - if(st.size()!=2) - throw INTERP_KERNEL::Exception("MEDCouplingStructuredMesh::FindMinimalPartOf2D : the input size of st must be equal to 2 !"); - int nxMin(std::numeric_limits::max()),nxMax(-std::numeric_limits::max()),nyMin(std::numeric_limits::max()),nyMax(-std::numeric_limits::max()); - int it(0),nx(st[0]),ny(st[1]); - int ret(0); - for(int i=0;i& st, const std::vector& crit, std::vector< std::pair >& partCompactFormat) -{ - if(st.size()!=3) - throw INTERP_KERNEL::Exception("MEDCouplingStructuredMesh::FindMinimalPartOf3D : the input size of st must be equal to 3 !"); - int nxMin(std::numeric_limits::max()),nxMax(-std::numeric_limits::max()),nyMin(std::numeric_limits::max()),nyMax(-std::numeric_limits::max()),nzMin(std::numeric_limits::max()),nzMax(-std::numeric_limits::max()); - int it(0),nx(st[0]),ny(st[1]),nz(st[2]); - int ret(0); - for(int i=0;i3 || spaceDim<1) - throw INTERP_KERNEL::Exception("MEDCouplingStructuredMesh::ZipNodeStructure : spaceDim must in [1,2,3] !"); - zipNodeSt[0]=0; zipNodeSt[1]=0; zipNodeSt[2]=0; - int zippedI(0); - for(int i=0;i=2) - zipNodeSt[zippedI++]=elt; - } - return zippedI; -} - -DataArrayInt *MEDCouplingStructuredMesh::Build1GTNodalConnectivityOfSubLevelMesh2D(const int *nodeStBg) -{ - std::vector ngs(2); - int n0(nodeStBg[0]-1),n1(nodeStBg[1]-1); ngs[0]=n0; ngs[1]=n1; - int off0(nodeStBg[0]); - MEDCouplingAutoRefCountObjectPtr conn(DataArrayInt::New()); - conn->alloc(2*GetNumberOfCellsOfSubLevelMesh(ngs,2)); - int *cp(conn->getPointer()); - //X - for(int i=0;i()); - 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 spaceDim(getSpaceDimension()); - getSplitNodeValues(tmp2); - std::transform(tmp,tmp+spaceDim,tmp2,tmp,std::multiplies()); - return std::accumulate(tmp,tmp+spaceDim,0); -} - - -int MEDCouplingStructuredMesh::getNumberOfCells() const -{ - std::vector ngs(getNodeGridStructure()); - int ret(1); - bool isCatched(false); - std::size_t ii(0); - for(std::vector::const_iterator it=ngs.begin();it!=ngs.end();it++,ii++) - { - int elt(*it); - if(elt<=0) - { - std::ostringstream oss; oss << "MEDCouplingStructuredMesh::getNumberOfCells : at pos #" << ii << " the number of nodes in nodeStructure is " << *it << " ! Must be > 0 !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - if(elt>1) - { - ret*=elt-1; - isCatched=true; - } - } - return isCatched?ret:0; -} - -int MEDCouplingStructuredMesh::getNumberOfNodes() const -{ - std::vector ngs(getNodeGridStructure()); - int ret(1); - for(std::vector::const_iterator it=ngs.begin();it!=ngs.end();it++) - ret*=*it; - return ret; -} - -/*! - * This method returns for a cell which id is \a cellId the location (locX,locY,locZ) of this cell in \a this. - * - * \param [in] cellId - * \return - A vector of size this->getMeshDimension() - * \throw if \a cellId not in [ 0, this->getNumberOfCells() ) - */ -std::vector MEDCouplingStructuredMesh::getLocationFromCellId(int cellId) const -{ - int meshDim(getMeshDimension()); - std::vector ret(meshDim); - std::vector struc(getCellGridStructure()); - int nbCells(std::accumulate(struc.begin(),struc.end(),1,std::multiplies())); - if(cellId<0 || cellId>=nbCells) - { - std::ostringstream oss; oss << "MEDCouplingStructuredMesh::getLocationFromCellId : Input cell id (" << cellId << ") is invalid ! Should be in [0," << nbCells << ") !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - std::vector spt(GetSplitVectFromStruct(struc)); - GetPosFromId(cellId,meshDim,&spt[0],&ret[0]); - return ret; -} - -/*! - * This method returns for a node which id is \a nodeId the location (locX,locY,locZ) of this node in \a this. - * - * \param [in] nodeId - * \return - A vector of size this->getSpaceDimension() - * \throw if \a cellId not in [ 0, this->getNumberOfNodes() ) - */ -std::vector MEDCouplingStructuredMesh::getLocationFromNodeId(int nodeId) const -{ - int spaceDim(getSpaceDimension()); - std::vector ret(spaceDim); - std::vector struc(getNodeGridStructure()); - int nbNodes(std::accumulate(struc.begin(),struc.end(),1,std::multiplies())); - if(nodeId<0 || nodeId>=nbNodes) - { - std::ostringstream oss; oss << "MEDCouplingStructuredMesh::getLocationFromNodeId : Input node id (" << nodeId << ") is invalid ! Should be in [0," << nbNodes << ") !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - std::vector spt(GetSplitVectFromStruct(struc)); - GetPosFromId(nodeId,spaceDim,&spt[0],&ret[0]); - return ret; -} - -void MEDCouplingStructuredMesh::GetPosFromId(int eltId, int meshDim, const int *split, int *res) -{ - int work(eltId); - for(int i=meshDim-1;i>=0;i--) - { - int pos=work/split[i]; - work=work%split[i]; - res[i]=pos; - } -} - -std::vector MEDCouplingStructuredMesh::getCellGridStructure() const -{ - std::vector ret(getNodeGridStructure()); - std::transform(ret.begin(),ret.end(),ret.begin(),std::bind2nd(std::plus(),-1)); - return ret; -} - -/*! - * This method returns the squareness of \a this (quadrature). \a this is expected to be with a mesh dimension equal to 2 or 3. - */ -double MEDCouplingStructuredMesh::computeSquareness() const -{ - std::vector cgs(getCellGridStructure()); - if(cgs.empty()) - throw INTERP_KERNEL::Exception("MEDCouplingStructuredMesh::computeSquareness : empty mesh !"); - std::size_t dim(cgs.size()); - if(dim==1) - throw INTERP_KERNEL::Exception("MEDCouplingStructuredMesh::computeSquareness : A segment cannot be square !"); - if(dim<4) - { - int minAx(cgs[0]),maxAx(cgs[0]); - for(std::size_t i=1;i MEDCouplingStructuredMesh::GetSplitVectFromStruct(const std::vector& strct) -{ - int spaceDim((int)strct.size()); - std::vector res(spaceDim); - for(int l=0;l& st, std::vector< std::pair >& partCompactFormat) -{ - int dim((int)st.size()); - partCompactFormat.resize(dim); - if(dim<1 || dim>3) - throw INTERP_KERNEL::Exception("MEDCouplingStructuredMesh::isPartStructured : input structure must be of dimension in [1,2,3] !"); - std::vector tmp2(dim),tmp(dim),tmp3(dim),tmp4(dim); tmp2[0]=1; - for(int i=1;i=st[dim-1]) - throw INTERP_KERNEL::Exception("MEDCouplingStructuredMesh::IsPartStructured : first id in input is not in valid range !"); - if(sz==1) - { - for(int i=0;i=st[i]) - throw INTERP_KERNEL::Exception("MEDCouplingStructuredMesh::IsPartStructured : last id in input is not in valid range !"); - partCompactFormat[i].second=tmp3[i]+1; - tmp4[i]=partCompactFormat[i].second-partCompactFormat[i].first; - if(tmp4[i]<=0) - return false; - szExp*=tmp4[i]; - } - if(szExp!=(int)sz) - return false; - const int *w(startIds); - switch(dim) - { - case 3: - { - for(int i=0;i MEDCouplingStructuredMesh::GetDimensionsFromCompactFrmt(const std::vector< std::pair >& partCompactFormat) -{ - std::vector ret(partCompactFormat.size()); - for(std::size_t i=0;ipartCompactFormat[i].second) - { - std::ostringstream oss; oss << "MEDCouplingStructuredMesh::GetDimensionsFromCompactFrmt : For axis #" << i << " end is before start !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - ret[i]=partCompactFormat[i].second-partCompactFormat[i].first; - } - return ret; -} - -/*! - * This method takes in input a vector giving the number of entity per axis and returns for each axis a range starting from [0,0...] - * - * \throw if there is an axis in \a dims that is < 0. - * \sa GetDimensionsFromCompactFrmt, ChangeReferenceFromGlobalOfCompactFrmt, ChangeReferenceToGlobalOfCompactFrmt - */ -std::vector< std::pair > MEDCouplingStructuredMesh::GetCompactFrmtFromDimensions(const std::vector& dims) -{ - std::size_t sz(dims.size()); - std::vector< std::pair > ret(sz); - for(std::size_t i=0;i > MEDCouplingStructuredMesh::IntersectRanges(const std::vector< std::pair >& r1, const std::vector< std::pair >& r2) -{ - std::size_t sz(r1.size()); - if(sz!=r2.size()) - throw INTERP_KERNEL::Exception("MEDCouplingStructuredMesh::IntersectRanges : the two ranges must have the same dimension !"); - std::vector< std::pair > ret(sz); - for(std::size_t i=0;ir1[i].second) - { - std::ostringstream oss; oss << "MEDCouplingStructuredMesh::IntersectRanges : On axis " << i << " of range r1, end is before start !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - if(r2[i].first>r2[i].second) - { - std::ostringstream oss; oss << "MEDCouplingStructuredMesh::IntersectRanges : On axis " << i << " of range r2, end is before start !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - ret[i].first=std::max(r1[i].first,r2[i].first); - ret[i].second=std::min(r1[i].second,r2[i].second); - if(ret[i].first>ret[i].second) - { - std::ostringstream oss; oss << "MEDCouplingStructuredMesh::IntersectRanges : On axis " << i << " the intersection of r1 and r2 is empty !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - } - return ret; -} - -/*! - * This method states if \a r1 and \a r2 do overlap of not. If yes you can call IntersectRanges to know the intersection area. - * - * \sa IntersectRanges - */ -bool MEDCouplingStructuredMesh::AreRangesIntersect(const std::vector< std::pair >& r1, const std::vector< std::pair >& r2) -{ - std::size_t sz(r1.size()); - if(sz!=r2.size()) - throw INTERP_KERNEL::Exception("MEDCouplingStructuredMesh::AreRangesIntersect : the two ranges must have the same dimension !"); - for(std::size_t i=0;ir1[i].second) - { - std::ostringstream oss; oss << "MEDCouplingStructuredMesh::AreRangesIntersect : On axis " << i << " of range r1, end is before start !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - if(r2[i].first>r2[i].second) - { - std::ostringstream oss; oss << "MEDCouplingStructuredMesh::AreRangesIntersect : On axis " << i << " of range r2, end is before start !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - if(r1[i].second<=r2[i].first) - return false; - if(r1[i].first>=r2[i].second) - return false; - } - return true; -} - -/*! - * This method is close to BuildExplicitIdsFrom except that instead of returning a DataArrayInt instance containing explicit ids it - * enable elems in the vector of booleans (for performance reasons). As it is method for performance, this method is \b not - * available in python. - * - * \param [in] st The entity structure. - * \param [in] partCompactFormat The compact subpart to be enabled. - * \param [in,out] vectToSwitchOn Vector which fetched items are enabled. - * - * \sa MEDCouplingStructuredMesh::BuildExplicitIdsFrom, ExtractFieldOfBoolFrom - */ -void MEDCouplingStructuredMesh::SwitchOnIdsFrom(const std::vector& st, const std::vector< std::pair >& partCompactFormat, std::vector& vectToSwitchOn) -{ - if(st.size()!=partCompactFormat.size()) - throw INTERP_KERNEL::Exception("MEDCouplingStructuredMesh::SwitchOnIdsFrom : input arrays must have the same size !"); - if((int)vectToSwitchOn.size()!=DeduceNumberOfGivenStructure(st)) - throw INTERP_KERNEL::Exception("MEDCouplingStructuredMesh::SwitchOnIdsFrom : invalid size of input vector of boolean regarding the structure !"); - std::vector dims(GetDimensionsFromCompactFrmt(partCompactFormat)); - switch(st.size()) - { - case 3: - { - for(int i=0;i& st, const std::vector& fieldOfBool, const std::vector< std::pair >& partCompactFormat, std::vector& fieldOut) -{ - if(st.size()!=partCompactFormat.size()) - throw INTERP_KERNEL::Exception("MEDCouplingStructuredMesh::ExtractFieldOfBoolFrom : input arrays must have the same size !"); - if((int)fieldOfBool.size()!=DeduceNumberOfGivenStructure(st)) - throw INTERP_KERNEL::Exception("MEDCouplingStructuredMesh::ExtractFieldOfBoolFrom : invalid size of input field of boolean regarding the structure !"); - std::vector dims(GetDimensionsFromCompactFrmt(partCompactFormat)); - int nbOfTuplesOfOutField(DeduceNumberOfGivenStructure(dims)); - fieldOut.resize(nbOfTuplesOfOutField); - int it(0); - switch(st.size()) - { - case 3: - { - for(int i=0;i& st, const DataArrayDouble *fieldOfDbl, const std::vector< std::pair >& partCompactFormat) -{ - if(!fieldOfDbl || !fieldOfDbl->isAllocated()) - throw INTERP_KERNEL::Exception("MEDCouplingStructuredMesh::ExtractFieldOfDoubleFrom : input array of double is NULL or not allocated!"); - if(st.size()!=partCompactFormat.size()) - throw INTERP_KERNEL::Exception("MEDCouplingStructuredMesh::ExtractFieldOfDoubleFrom : input arrays must have the same size !"); - if(fieldOfDbl->getNumberOfTuples()!=DeduceNumberOfGivenStructure(st)) - throw INTERP_KERNEL::Exception("MEDCouplingStructuredMesh::ExtractFieldOfDoubleFrom : invalid size of input array of double regarding the structure !"); - std::vector dims(GetDimensionsFromCompactFrmt(partCompactFormat)); - int nbOfTuplesOfOutField(DeduceNumberOfGivenStructure(dims)),nbComp(fieldOfDbl->getNumberOfComponents()); - MEDCouplingAutoRefCountObjectPtr ret(DataArrayDouble::New()); ret->alloc(nbOfTuplesOfOutField,nbComp); - ret->copyStringInfoFrom(*fieldOfDbl); - double *ptRet(ret->getPointer()); - const double *fieldOfDblPtr(fieldOfDbl->begin()); - switch(st.size()) - { - case 3: - { - for(int i=0;i& st, DataArrayDouble *fieldOfDbl, const std::vector< std::pair >& partCompactFormat, const DataArrayDouble *other) -{//to be optimized - std::vector facts(st.size(),1.); - MEDCouplingIMesh::CondenseFineToCoarse(st,other,partCompactFormat,facts,fieldOfDbl); -} - -/*! - * This method changes the reference of a part of structured mesh \a partOfBigInAbs define in absolute reference to a new reference \a bigInAbs. - * So this method only performs a translation by doing \a partOfBigRelativeToBig = \a partOfBigInAbs - \a bigInAbs - * This method also checks (if \a check=true) that \a partOfBigInAbs is included in \a bigInAbs. - * This method is useful to extract a part from a field lying on a big mesh. - * - * \sa ChangeReferenceToGlobalOfCompactFrmt, BuildExplicitIdsFrom, SwitchOnIdsFrom, ExtractFieldOfBoolFrom, ExtractFieldOfDoubleFrom - */ -void MEDCouplingStructuredMesh::ChangeReferenceFromGlobalOfCompactFrmt(const std::vector< std::pair >& bigInAbs, const std::vector< std::pair >& partOfBigInAbs, std::vector< std::pair >& partOfBigRelativeToBig, bool check) -{ - std::size_t dim(bigInAbs.size()); - if(dim!=partOfBigInAbs.size()) - throw INTERP_KERNEL::Exception("MEDCouplingStructuredMesh::ChangeReferenceFromGlobalOfCompactFrmt : The size of parts (dimension) must be the same !"); - partOfBigRelativeToBig.resize(dim); - for(std::size_t i=0;ibigInAbs[i].second) - { - std::ostringstream oss; oss << "MEDCouplingStructuredMesh::ChangeReferenceFromGlobalOfCompactFrmt : Error at axis #" << i << " the input big part invalid, end before start !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - if(partOfBigInAbs[i].first=bigInAbs[i].second) - { - std::ostringstream oss; oss << "MEDCouplingStructuredMesh::ChangeReferenceFromGlobalOfCompactFrmt : Error at axis #" << i << " the part is not included in the big one (start) !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - } - partOfBigRelativeToBig[i].first=partOfBigInAbs[i].first-bigInAbs[i].first; - if(check) - { - if(partOfBigInAbs[i].secondbigInAbs[i].second) - { - std::ostringstream oss; oss << "MEDCouplingStructuredMesh::ChangeReferenceFromGlobalOfCompactFrmt : Error at axis #" << i << " the part is not included in the big one (end) !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - } - partOfBigRelativeToBig[i].second=partOfBigInAbs[i].second-bigInAbs[i].first; - } -} - -/* - * This method is performs the opposite reference modification than explained in ChangeReferenceFromGlobalOfCompactFrmt. - * - * \sa ChangeReferenceFromGlobalOfCompactFrmt - */ -void MEDCouplingStructuredMesh::ChangeReferenceToGlobalOfCompactFrmt(const std::vector< std::pair >& bigInAbs, const std::vector< std::pair >& partOfBigRelativeToBig, std::vector< std::pair >& partOfBigInAbs, bool check) -{ - std::size_t dim(bigInAbs.size()); - if(dim!=partOfBigRelativeToBig.size()) - throw INTERP_KERNEL::Exception("MEDCouplingStructuredMesh::ChangeReferenceToGlobalOfCompactFrmt : The size of parts (dimension) must be the same !"); - partOfBigInAbs.resize(dim); - for(std::size_t i=0;ibigInAbs[i].second) - { - std::ostringstream oss; oss << "MEDCouplingStructuredMesh::ChangeReferenceToGlobalOfCompactFrmt : Error at axis #" << i << " the input big part invalid, end before start !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - if(partOfBigRelativeToBig[i].first<0 || partOfBigRelativeToBig[i].first>=bigInAbs[i].second-bigInAbs[i].first) - { - std::ostringstream oss; oss << "MEDCouplingStructuredMesh::ChangeReferenceToGlobalOfCompactFrmt : Error at axis #" << i << " the start of part is not in the big one !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - } - partOfBigInAbs[i].first=partOfBigRelativeToBig[i].first+bigInAbs[i].first; - if(check) - { - if(partOfBigRelativeToBig[i].secondbigInAbs[i].second-bigInAbs[i].first) - { - std::ostringstream oss; oss << "MEDCouplingStructuredMesh::ChangeReferenceToGlobalOfCompactFrmt : Error at axis #" << i << " the end of part is not in the big one !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - } - partOfBigInAbs[i].second=partOfBigRelativeToBig[i].second+bigInAbs[i].first; - } -} - -/*! - * This method performs a translation (defined by \a translation) of \a part and returns the result of translated part. - * - * \sa FindTranslationFrom - */ -std::vector< std::pair > MEDCouplingStructuredMesh::TranslateCompactFrmt(const std::vector< std::pair >& part, const std::vector& translation) -{ - std::size_t sz(part.size()); - if(translation.size()!=sz) - throw INTERP_KERNEL::Exception("MEDCouplingStructuredMesh::TranslateCompactFrmt : the sizes are not equal !"); - std::vector< std::pair > ret(sz); - for(std::size_t i=0;i MEDCouplingStructuredMesh::FindTranslationFrom(const std::vector< std::pair >& startingFrom, const std::vector< std::pair >& goingTo) -{ - std::size_t sz(startingFrom.size()); - if(goingTo.size()!=sz) - throw INTERP_KERNEL::Exception("MEDCouplingStructuredMesh::FindTranslationFrom : the sizes are not equal !"); - std::vector< int > ret(sz); - for(std::size_t i=0;i& st, const std::vector< std::pair >& partCompactFormat) -{ - if(st.size()!=partCompactFormat.size()) - throw INTERP_KERNEL::Exception("MEDCouplingStructuredMesh::BuildExplicitIdsFrom : input arrays must have the same size !"); - int nbOfItems(1); - std::vector dims(st.size()); - for(std::size_t i=0;ist[i]) - throw INTERP_KERNEL::Exception("MEDCouplingStructuredMesh::BuildExplicitIdsFrom : invalid input range 1 !"); - if(partCompactFormat[i].second<0 || partCompactFormat[i].second>st[i]) - throw INTERP_KERNEL::Exception("MEDCouplingStructuredMesh::BuildExplicitIdsFrom : invalid input range 2 !"); - if(partCompactFormat[i].second ret(DataArrayInt::New()); - ret->alloc(nbOfItems,1); - int *pt(ret->getPointer()); - switch(st.size()) - { - case 3: - { - for(int i=0;i& st, const std::vector< std::pair >& part, double factor, DataArrayDouble *da) -{ - if(!da || !da->isAllocated()) - throw INTERP_KERNEL::Exception("MEDCouplingStructuredMesh::MultiplyPartOf : DataArrayDouble instance must be not NULL and allocated !"); - if(st.size()!=part.size()) - throw INTERP_KERNEL::Exception("MEDCouplingStructuredMesh::MultiplyPartOf : input arrays must have the same size !"); - std::vector dims(st.size()); - for(std::size_t i=0;ist[i]) - throw INTERP_KERNEL::Exception("MEDCouplingStructuredMesh::MultiplyPartOf : invalid input range 1 !"); - if(part[i].second<0 || part[i].second>st[i]) - throw INTERP_KERNEL::Exception("MEDCouplingStructuredMesh::MultiplyPartOf : invalid input range 2 !"); - if(part[i].secondgetNumberOfComponents()); - if(da->getNumberOfTuples()!=nbOfTuplesExp) - { - std::ostringstream oss; oss << "MEDCouplingStructuredMesh::MultiplyPartOf : invalid nb of tuples ! Expected " << nbOfTuplesExp << " having " << da->getNumberOfTuples() << " !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - double *pt(da->getPointer()); - switch(st.size()) - { - case 3: - { - for(int i=0;i(),factor)); - } - } - } - break; - } - case 2: - { - for(int j=0;j(),factor)); - } - } - break; - } - case 1: - { - for(int k=0;k(),factor)); - } - break; - } - default: - throw INTERP_KERNEL::Exception("MEDCouplingStructuredMesh::MultiplyPartOf : Dimension supported are 1,2 or 3 !"); - } -} - -/*! - * This method multiplies by \a factor values in tuples located by \a part in \a da. - * - * \param [in] st - the structure of grid ( \b without considering ghost cells). - * \param [in] part - the part in the structure ( \b without considering ghost cells) contained in grid whose structure is defined by \a st. - * \param [in] ghostSize - \a ghostSize must be >= 0. - * \param [in] factor - the factor, the tuples in \a da will be multiply by. - * \param [in,out] da - The DataArray in wich only tuples specified by \a part will be modified. - * - * \sa MultiplyPartOf, PutInGhostFormat - */ -void MEDCouplingStructuredMesh::MultiplyPartOfByGhost(const std::vector& st, const std::vector< std::pair >& part, int ghostSize, double factor, DataArrayDouble *da) -{ - std::vector stWG; - std::vector< std::pair > partWG; - PutInGhostFormat(ghostSize,st,part,stWG,partWG); - MultiplyPartOf(stWG,partWG,factor,da); -} - -/*! - * This method multiplies by \a factor values in tuples located by \a part in \a da. - * - * \param [in] st - the structure of grid ( \b without considering ghost cells). - * \param [in] part - the part in the structure ( \b without considering ghost cells) contained in grid whose structure is defined by \a st. - * \param [in] ghostSize - \a ghostSize must be >= 0. - * \param [out] stWithGhost - the structure considering ghost cells. - * \param [out] partWithGhost - the part considering the ghost cells. - * - * \sa MultiplyPartOf, PutInGhostFormat - */ -void MEDCouplingStructuredMesh::PutInGhostFormat(int ghostSize, const std::vector& st, const std::vector< std::pair >& part, std::vector& stWithGhost, std::vector< std::pair >&partWithGhost) -{ - if(ghostSize<0) - throw INTERP_KERNEL::Exception("MEDCouplingStructuredMesh::PutInGhostFormat : ghost size must be >= 0 !"); - std::size_t dim(part.size()); - if(st.size()!=dim) - throw INTERP_KERNEL::Exception("MEDCouplingStructuredMesh::PutInGhostFormat : the dimension of input vectors must be the same !"); - for(std::size_t i=0;ipart[i].second || part[i].second>st[i]) - throw INTERP_KERNEL::Exception("MEDCouplingStructuredMesh::PutInGhostFormat : the specified part is invalid ! The begin must be >= 0 and <= end ! The end must be <= to the size at considered dimension !"); - stWithGhost.resize(st.size()); - std::transform(st.begin(),st.end(),stWithGhost.begin(),std::bind2nd(std::plus(),2*ghostSize)); - partWithGhost=part; - ApplyGhostOnCompactFrmt(partWithGhost,ghostSize); -} - -/*! - * \param [in,out] partBeforeFact - the part of a image mesh in compact format that will be put in ghost reference. - * \param [in] ghostSize - the ghost size of zone for all axis. - */ -void MEDCouplingStructuredMesh::ApplyGhostOnCompactFrmt(std::vector< std::pair >& partBeforeFact, int ghostSize) -{ - if(ghostSize<0) - throw INTERP_KERNEL::Exception("MEDCouplingStructuredMesh::ApplyGhostOnCompactFrmt : ghost size must be >= 0 !"); - std::size_t sz(partBeforeFact.size()); - for(std::size_t i=0;i& cgs, int mdim) -{ - int ret(0); - for(int i=0;i getAllGeoTypes() const; - MEDCOUPLING_EXPORT int getNumberOfCellsWithType(INTERP_KERNEL::NormalizedCellType type) const; - MEDCOUPLING_EXPORT DataArrayInt *giveCellsWithType(INTERP_KERNEL::NormalizedCellType type) const; - MEDCOUPLING_EXPORT DataArrayInt *computeNbOfNodesPerCell() const; - MEDCOUPLING_EXPORT DataArrayInt *computeNbOfFacesPerCell() const; - MEDCOUPLING_EXPORT DataArrayInt *computeEffectiveNbOfNodesPerCell() const; - MEDCOUPLING_EXPORT std::vector getLocationFromCellId(int cellId) const; - MEDCOUPLING_EXPORT std::vector getLocationFromNodeId(int nodeId) const; - MEDCOUPLING_EXPORT static void GetPosFromId(int eltId, int meshDim, const int *split, int *res); - MEDCOUPLING_EXPORT static INTERP_KERNEL::NormalizedCellType GetGeoTypeGivenMeshDimension(int meshDim); - MEDCOUPLING_EXPORT void getNodeIdsOfCell(int cellId, std::vector& conn) const; - MEDCOUPLING_EXPORT std::size_t getHeapMemorySizeWithoutChildren() const; - MEDCOUPLING_EXPORT void copyTinyStringsFrom(const MEDCouplingMesh *other); - MEDCOUPLING_EXPORT bool isEqualIfNotWhy(const MEDCouplingMesh *other, double prec, std::string& reason) const; - //tools - MEDCOUPLING_EXPORT std::vector getDistributionOfTypes() const; - MEDCOUPLING_EXPORT DataArrayInt *checkTypeConsistencyAndContig(const std::vector& code, const std::vector& idsPerType) const; - MEDCOUPLING_EXPORT void splitProfilePerType(const DataArrayInt *profile, std::vector& code, std::vector& idsInPflPerType, std::vector& idsPerType) const; - MEDCOUPLING_EXPORT MEDCoupling1SGTUMesh *build1SGTUnstructured() const; - MEDCOUPLING_EXPORT MEDCouplingUMesh *buildUnstructured() const; - MEDCOUPLING_EXPORT MEDCouplingMesh *buildPart(const int *start, const int *end) const; - MEDCOUPLING_EXPORT MEDCouplingMesh *buildPartAndReduceNodes(const int *start, const int *end, DataArrayInt*& arr) const; - MEDCOUPLING_EXPORT DataArrayInt *simplexize(int policy); - MEDCOUPLING_EXPORT MEDCouplingFieldDouble *buildOrthogonalField() const; - MEDCOUPLING_EXPORT void getReverseNodalConnectivity(DataArrayInt *revNodal, DataArrayInt *revNodalIndx) const; - //some useful methods - MEDCOUPLING_EXPORT MEDCoupling1SGTUMesh *build1SGTSubLevelMesh() const; - MEDCOUPLING_EXPORT int getCellIdFromPos(int i, int j, int k) const; - MEDCOUPLING_EXPORT int getNodeIdFromPos(int i, int j, int k) const; - MEDCOUPLING_EXPORT int getNumberOfCells() const; - MEDCOUPLING_EXPORT int getNumberOfNodes() const; - MEDCOUPLING_EXPORT int getMeshDimension() const; - MEDCOUPLING_EXPORT int getNumberOfCellsOfSubLevelMesh() const; - MEDCOUPLING_EXPORT int getSpaceDimensionOnNodeStruct() const; - MEDCOUPLING_EXPORT virtual void getNodeGridStructure(int *res) const = 0; - MEDCOUPLING_EXPORT virtual void getSplitCellValues(int *res) const; - MEDCOUPLING_EXPORT virtual void getSplitNodeValues(int *res) const; - MEDCOUPLING_EXPORT virtual std::vector getNodeGridStructure() const = 0; - MEDCOUPLING_EXPORT std::vector getCellGridStructure() const; - MEDCOUPLING_EXPORT double computeSquareness() const; - MEDCOUPLING_EXPORT virtual MEDCouplingStructuredMesh *buildStructuredSubPart(const std::vector< std::pair >& cellPart) const = 0; - MEDCOUPLING_EXPORT static std::vector GetSplitVectFromStruct(const std::vector& strct); - MEDCOUPLING_EXPORT static bool IsPartStructured(const int *startIds, const int *stopIds, const std::vector& st, std::vector< std::pair >& partCompactFormat); - MEDCOUPLING_EXPORT static std::vector GetDimensionsFromCompactFrmt(const std::vector< std::pair >& partCompactFormat); - MEDCOUPLING_EXPORT static std::vector< std::pair > GetCompactFrmtFromDimensions(const std::vector& dims); - MEDCOUPLING_EXPORT static std::vector< std::pair > IntersectRanges(const std::vector< std::pair >& r1, const std::vector< std::pair >& r2); - MEDCOUPLING_EXPORT static bool AreRangesIntersect(const std::vector< std::pair >& r1, const std::vector< std::pair >& r2); - MEDCOUPLING_EXPORT static void SwitchOnIdsFrom(const std::vector& st, const std::vector< std::pair >& partCompactFormat, std::vector& vectToSwitchOn); - MEDCOUPLING_EXPORT static void ExtractFieldOfBoolFrom(const std::vector& st, const std::vector& fieldOfBool, const std::vector< std::pair >& partCompactFormat, std::vector& fieldOut); - MEDCOUPLING_EXPORT static DataArrayDouble *ExtractFieldOfDoubleFrom(const std::vector& st, const DataArrayDouble *fieldOfDbl, const std::vector< std::pair >& partCompactFormat); - MEDCOUPLING_EXPORT static void AssignPartOfFieldOfDoubleUsing(const std::vector& st, DataArrayDouble *fieldOfDbl, const std::vector< std::pair >& partCompactFormat, const DataArrayDouble *other); - MEDCOUPLING_EXPORT static void ChangeReferenceFromGlobalOfCompactFrmt(const std::vector< std::pair >& bigInAbs, const std::vector< std::pair >& partOfBigInAbs, std::vector< std::pair >& partOfBigRelativeToBig, bool check=true); - MEDCOUPLING_EXPORT static void ChangeReferenceToGlobalOfCompactFrmt(const std::vector< std::pair >& bigInAbs, const std::vector< std::pair >& partOfBigRelativeToBig, std::vector< std::pair >& partOfBigInAbs, bool check=true); - MEDCOUPLING_EXPORT static std::vector< std::pair > TranslateCompactFrmt(const std::vector< std::pair >& part, const std::vector& translation); - MEDCOUPLING_EXPORT static std::vector FindTranslationFrom(const std::vector< std::pair >& startingFrom, const std::vector< std::pair >& goingTo); - MEDCOUPLING_EXPORT static DataArrayInt *BuildExplicitIdsFrom(const std::vector& st, const std::vector< std::pair >& partCompactFormat); - MEDCOUPLING_EXPORT static void MultiplyPartOf(const std::vector& st, const std::vector< std::pair >& part, double factor, DataArrayDouble *da); - MEDCOUPLING_EXPORT static void MultiplyPartOfByGhost(const std::vector& st, const std::vector< std::pair >& part, int ghostSize, double factor, DataArrayDouble *da); - MEDCOUPLING_EXPORT static void PutInGhostFormat(int ghostSize, const std::vector& st, const std::vector< std::pair >& part, std::vector& stWithGhost, std::vector< std::pair >&partWithGhost); - MEDCOUPLING_EXPORT static void ApplyGhostOnCompactFrmt(std::vector< std::pair >& partBeforeFact, int ghostSize); - MEDCOUPLING_EXPORT static DataArrayInt *Build1GTNodalConnectivity(const int *nodeStBg, const int *nodeStEnd); - MEDCOUPLING_EXPORT static DataArrayInt *Build1GTNodalConnectivityOfSubLevelMesh(const int *nodeStBg, const int *nodeStEnd); - MEDCOUPLING_EXPORT static DataArrayInt *ComputeCornersGhost(const std::vector& st, int ghostLev); - MEDCOUPLING_EXPORT static int DeduceNumberOfGivenRangeInCompactFrmt(const std::vector< std::pair >& partCompactFormat); - MEDCOUPLING_EXPORT static int DeduceNumberOfGivenStructure(const std::vector& st); - MEDCOUPLING_EXPORT static void FindTheWidestAxisOfGivenRangeInCompactFrmt(const std::vector< std::pair >& partCompactFormat, int& axisId, int& sizeOfRange); - MEDCOUPLING_EXPORT static int FindMinimalPartOf(int minPatchLgth, const std::vector& st, const std::vector& crit, std::vector& reducedCrit, std::vector< std::pair >& partCompactFormat); - MEDCOUPLING_EXPORT static std::vector< std::vector > ComputeSignaturePerAxisOf(const std::vector& st, const std::vector& crit); - private: - static int GetNumberOfCellsOfSubLevelMesh(const std::vector& cgs, int mdim); - static void GetReverseNodalConnectivity1(const std::vector& ngs, DataArrayInt *revNodal, DataArrayInt *revNodalIndx); - static void GetReverseNodalConnectivity2(const std::vector& ngs, DataArrayInt *revNodal, DataArrayInt *revNodalIndx); - static void GetReverseNodalConnectivity3(const std::vector& ngs, DataArrayInt *revNodal, DataArrayInt *revNodalIndx); - static DataArrayInt *Build1GTNodalConnectivity1D(const int *nodeStBg); - static DataArrayInt *Build1GTNodalConnectivity2D(const int *nodeStBg); - static DataArrayInt *Build1GTNodalConnectivity3D(const int *nodeStBg); - static DataArrayInt *Build1GTNodalConnectivityOfSubLevelMesh2D(const int *nodeStBg); - static DataArrayInt *Build1GTNodalConnectivityOfSubLevelMesh3D(const int *nodeStBg); - static int FindMinimalPartOf1D(const std::vector& st, const std::vector& crit, std::vector< std::pair >& partCompactFormat); - static int FindMinimalPartOf2D(const std::vector& st, const std::vector& crit, std::vector< std::pair >& partCompactFormat); - static int FindMinimalPartOf3D(const std::vector& st, const std::vector& crit, std::vector< std::pair >& partCompactFormat); - protected: - static int ZipNodeStructure(const int *nodeStBg, const int *nodeStEnd, int zipNodeSt[3]); - protected: - MEDCOUPLING_EXPORT MEDCouplingStructuredMesh(); - MEDCOUPLING_EXPORT MEDCouplingStructuredMesh(const MEDCouplingStructuredMesh& other, bool deepCpy); - MEDCOUPLING_EXPORT ~MEDCouplingStructuredMesh(); - }; -} - -#endif diff --git a/src/MEDCoupling/MEDCouplingTimeDiscretization.cxx b/src/MEDCoupling/MEDCouplingTimeDiscretization.cxx deleted file mode 100644 index cb456a024..000000000 --- a/src/MEDCoupling/MEDCouplingTimeDiscretization.cxx +++ /dev/null @@ -1,2951 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 -// 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 "MEDCouplingTimeDiscretization.hxx" -#include "MEDCouplingAutoRefCountObjectPtr.hxx" -#include "MEDCouplingMemArray.hxx" -#include "MEDCouplingMesh.hxx" - -#include -#include -#include -#include -#include - -using namespace ParaMEDMEM; - -const double MEDCouplingTimeDiscretization::TIME_TOLERANCE_DFT=1.e-12; - -const char MEDCouplingNoTimeLabel::EXCEPTION_MSG[]="MEDCouplingNoTimeLabel::setTime : no time info attached."; - -const char MEDCouplingNoTimeLabel::REPR[]="No time label defined."; - -const char MEDCouplingWithTimeStep::EXCEPTION_MSG[]="No data on this time."; - -const char MEDCouplingWithTimeStep::REPR[]="One time label."; - -const char MEDCouplingConstOnTimeInterval::EXCEPTION_MSG[]="No data on this time."; - -const char MEDCouplingConstOnTimeInterval::REPR[]="Constant on a time interval."; - -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) -{ - switch(type) - { - case MEDCouplingNoTimeLabel::DISCRETIZATION: - return new MEDCouplingNoTimeLabel; - case MEDCouplingWithTimeStep::DISCRETIZATION: - return new MEDCouplingWithTimeStep; - case MEDCouplingConstOnTimeInterval::DISCRETIZATION: - return new MEDCouplingConstOnTimeInterval; - case MEDCouplingLinearTime::DISCRETIZATION: - return new MEDCouplingLinearTime; - default: - throw INTERP_KERNEL::Exception("Time discretization not implemented yet"); - } -} - -void MEDCouplingTimeDiscretization::copyTinyAttrFrom(const MEDCouplingTimeDiscretization& other) -{ - _time_tolerance=other._time_tolerance; - _time_unit=other._time_unit; -} - -void MEDCouplingTimeDiscretization::copyTinyStringsFrom(const MEDCouplingTimeDiscretization& other) -{ - _time_unit=other._time_unit; - if(_array && other._array) - _array->copyStringInfoFrom(*other._array); -} - -void MEDCouplingTimeDiscretization::checkCoherency() const -{ - if(!_array) - throw INTERP_KERNEL::Exception("Field invalid because no values set !"); - if(_time_tolerance<0.) - throw INTERP_KERNEL::Exception("time tolerance is expected to be greater than 0. !"); -} - -void MEDCouplingTimeDiscretization::updateTime() const -{ - if(_array) - updateTimeWith(*_array); -} - -std::size_t MEDCouplingTimeDiscretization::getHeapMemorySizeWithoutChildren() const -{ - std::size_t ret(_time_unit.capacity()); - return ret; -} - -std::vector MEDCouplingTimeDiscretization::getDirectChildrenWithNull() const -{ - std::vector ret; - ret.push_back(_array); - return ret; -} - -bool MEDCouplingTimeDiscretization::areCompatible(const MEDCouplingTimeDiscretization *other) const -{ - if(std::fabs(_time_tolerance-other->_time_tolerance)>1.e-16) - return false; - if(_array==0 && other->_array==0) - return true; - if(_array==0 || other->_array==0) - return false; - if(_array->getNumberOfComponents()!=other->_array->getNumberOfComponents()) - return false; - return true; -} - -bool MEDCouplingTimeDiscretization::areStrictlyCompatible(const MEDCouplingTimeDiscretization *other, std::string& reason) const -{ - std::ostringstream oss; oss.precision(15); - if(_time_unit!=other->_time_unit) - { - oss << "Field discretizations differ : this time unit = \"" << _time_unit << "\" and other time unit = \"" << other->_time_unit << "\" !"; - reason=oss.str(); - return false; - } - if(std::fabs(_time_tolerance-other->_time_tolerance)>1.e-16) - { - oss << "Field discretizations differ : this time tolerance = \"" << _time_tolerance << "\" and other time tolerance = \"" << other->_time_tolerance << "\" !"; - reason=oss.str(); - return false; - } - if(_array==0 && other->_array==0) - return true; - if(_array==0 || other->_array==0) - { - reason="Field discretizations differ : Only one timediscretization between the two this and other has a DataArrayDouble for values defined"; - return false; - } - if(_array->getNumberOfComponents()!=other->_array->getNumberOfComponents()) - return false; - if(_array->getNumberOfTuples()!=other->_array->getNumberOfTuples()) - return false; - return true; -} - -bool MEDCouplingTimeDiscretization::areCompatibleForMeld(const MEDCouplingTimeDiscretization *other) const -{ - if(std::fabs(_time_tolerance-other->_time_tolerance)>1.e-16) - return false; - if(_array==0 && other->_array==0) - return true; - if(_array==0 || other->_array==0) - return false; - if(_array->getNumberOfTuples()!=other->_array->getNumberOfTuples()) - return false; - return true; -} - -bool MEDCouplingTimeDiscretization::areStrictlyCompatibleForMul(const MEDCouplingTimeDiscretization *other) const -{ - if(std::fabs(_time_tolerance-other->_time_tolerance)>1.e-16) - return false; - if(_array==0 && other->_array==0) - return true; - if(_array==0 || other->_array==0) - return false; - int nbC1=_array->getNumberOfComponents(); - int nbC2=other->_array->getNumberOfComponents(); - int nbMin=std::min(nbC1,nbC2); - if(nbC1!=nbC2 && nbMin!=1) - return false; - return true; -} - -bool MEDCouplingTimeDiscretization::areStrictlyCompatibleForDiv(const MEDCouplingTimeDiscretization *other) const -{ - if(std::fabs(_time_tolerance-other->_time_tolerance)>1.e-16) - return false; - if(_array==0 && other->_array==0) - return true; - if(_array==0 || other->_array==0) - return false; - int nbC1=_array->getNumberOfComponents(); - int nbC2=other->_array->getNumberOfComponents(); - if(nbC1!=nbC2 && nbC2!=1) - return false; - return true; -} - -bool MEDCouplingTimeDiscretization::isEqualIfNotWhy(const MEDCouplingTimeDiscretization *other, double prec, std::string& reason) const -{ - if(!areStrictlyCompatible(other,reason)) - return false; - if(_array==other->_array) - return true; - return _array->isEqualIfNotWhy(*other->_array,prec,reason); -} - -bool MEDCouplingTimeDiscretization::isEqual(const MEDCouplingTimeDiscretization *other, double prec) const -{ - std::string reason; - return isEqualIfNotWhy(other,prec,reason); -} - -bool MEDCouplingTimeDiscretization::isEqualWithoutConsideringStr(const MEDCouplingTimeDiscretization *other, double prec) const -{ - std::string tmp; - if(!areStrictlyCompatible(other,tmp)) - return false; - if(_array==other->_array) - return true; - return _array->isEqualWithoutConsideringStr(*other->_array,prec); -} - -MEDCouplingTimeDiscretization *MEDCouplingTimeDiscretization::buildNewTimeReprFromThis(TypeOfTimeDiscretization type, bool deepCpy) const -{ - MEDCouplingTimeDiscretization *ret=MEDCouplingTimeDiscretization::New(type); - ret->setTimeUnit(getTimeUnit()); - const DataArrayDouble *arrSrc=getArray(); - MEDCouplingAutoRefCountObjectPtr arr; - if(arrSrc) - arr=arrSrc->performCpy(deepCpy); - ret->setArray(arr,0); - return ret; -} - -void MEDCouplingTimeDiscretization::getTinySerializationIntInformation(std::vector& tinyInfo) const -{ - if(_array) - { - tinyInfo.push_back(_array->getNumberOfTuples()); - tinyInfo.push_back(_array->getNumberOfComponents()); - } - else - { - tinyInfo.push_back(-1); - tinyInfo.push_back(-1); - } -} - -void MEDCouplingTimeDiscretization::resizeForUnserialization(const std::vector& tinyInfoI, std::vector& arrays) -{ - arrays.resize(1); - if(_array!=0) - _array->decrRef(); - DataArrayDouble *arr=0; - if(tinyInfoI[0]!=-1 && tinyInfoI[1]!=-1) - { - arr=DataArrayDouble::New(); - arr->alloc(tinyInfoI[0],tinyInfoI[1]); - } - _array=arr; - arrays[0]=arr; -} - -void MEDCouplingTimeDiscretization::checkForUnserialization(const std::vector& tinyInfoI, const std::vector& arrays) -{ - static const char MSG[]="MEDCouplingTimeDiscretization::checkForUnserialization : arrays in input is expected to have size one !"; - if(arrays.size()!=1) - throw INTERP_KERNEL::Exception(MSG); - if(_array!=0) - _array->decrRef(); - _array=0; - if(tinyInfoI[0]!=-1 && tinyInfoI[1]!=-1) - { - if(!arrays[0]) - throw INTERP_KERNEL::Exception(MSG); - arrays[0]->checkNbOfTuplesAndComp(tinyInfoI[0],tinyInfoI[1],MSG); - _array=arrays[0]; - _array->incrRef(); - } -} - -void MEDCouplingTimeDiscretization::finishUnserialization(const std::vector& tinyInfoI, const std::vector& tinyInfoD, const std::vector& tinyInfoS) -{ - _time_tolerance=tinyInfoD[0]; - int nbOfCompo=_array->getNumberOfComponents(); - for(int i=0;isetInfoOnComponent(i,tinyInfoS[i]); -} - -void MEDCouplingTimeDiscretization::getTinySerializationDbleInformation(std::vector& tinyInfo) const -{ - tinyInfo.push_back(_time_tolerance); -} - -void MEDCouplingTimeDiscretization::getTinySerializationStrInformation(std::vector& tinyInfo) const -{ - int nbOfCompo=_array->getNumberOfComponents(); - for(int i=0;igetInfoOnComponent(i)); -} - -MEDCouplingTimeDiscretization::MEDCouplingTimeDiscretization():_time_tolerance(TIME_TOLERANCE_DFT),_array(0) -{ -} - -MEDCouplingTimeDiscretization::MEDCouplingTimeDiscretization(const MEDCouplingTimeDiscretization& other, bool deepCpy):_time_unit(other._time_unit),_time_tolerance(other._time_tolerance) -{ - if(other._array) - _array=other._array->performCpy(deepCpy); - else - _array=0; -} - -MEDCouplingTimeDiscretization::~MEDCouplingTimeDiscretization() -{ - if(_array) - _array->decrRef(); -} - -void MEDCouplingTimeDiscretization::setArray(DataArrayDouble *array, TimeLabel *owner) -{ - if(array!=_array) - { - if(_array) - _array->decrRef(); - _array=array; - if(_array) - _array->incrRef(); - if(owner) - owner->declareAsNew(); - } -} - -const DataArrayDouble *MEDCouplingTimeDiscretization::getEndArray() const -{ - throw INTERP_KERNEL::Exception("getEndArray not available for this type of time discretization !"); -} - -DataArrayDouble *MEDCouplingTimeDiscretization::getEndArray() -{ - throw INTERP_KERNEL::Exception("getEndArray not available for this type of time discretization !"); -} - -void MEDCouplingTimeDiscretization::setEndArray(DataArrayDouble *array, TimeLabel *owner) -{ - throw INTERP_KERNEL::Exception("setEndArray not available for this type of time discretization !"); -} - -void MEDCouplingTimeDiscretization::setArrays(const std::vector& arrays, TimeLabel *owner) -{ - if(arrays.size()!=1) - throw INTERP_KERNEL::Exception("MEDCouplingTimeDiscretization::setArrays : number of arrays must be one."); - setArray(arrays.back(),owner); -} - -void MEDCouplingTimeDiscretization::getArrays(std::vector& arrays) const -{ - arrays.resize(1); - arrays[0]=_array; -} - -bool MEDCouplingTimeDiscretization::isBefore(const MEDCouplingTimeDiscretization *other) const -{ - int iteration,order; - double time1=getEndTime(iteration,order)-_time_tolerance; - double time2=other->getStartTime(iteration,order)+other->getTimeTolerance(); - return time1<=time2; -} - -bool MEDCouplingTimeDiscretization::isStrictlyBefore(const MEDCouplingTimeDiscretization *other) const -{ - int iteration,order; - double time1=getEndTime(iteration,order)+_time_tolerance; - double time2=other->getStartTime(iteration,order)-other->getTimeTolerance(); - return time1setTimeUnit(getTimeUnit()); - std::vector arrays; - getArrays(arrays); - std::vector< MEDCouplingAutoRefCountObjectPtr > arrays2(arrays.size()); - for(std::size_t j=0;jdoublyContractedProduct(); - else - arrays2[j]=0; - } - std::vector arrays3(arrays.size()); - for(std::size_t j=0;jsetArrays(arrays3,0); - return ret; -} - -MEDCouplingTimeDiscretization *MEDCouplingTimeDiscretization::determinant() const -{ - std::vector arrays; - getArrays(arrays); - std::vector< MEDCouplingAutoRefCountObjectPtr > arrays2(arrays.size()); - for(std::size_t j=0;jdeterminant(); - else - arrays2[j]=0; - } - std::vector arrays3(arrays.size()); - for(std::size_t j=0;jsetTimeUnit(getTimeUnit()); - ret->setArrays(arrays3,0); - return ret; -} - -MEDCouplingTimeDiscretization *MEDCouplingTimeDiscretization::eigenValues() const -{ - std::vector arrays; - getArrays(arrays); - std::vector< MEDCouplingAutoRefCountObjectPtr > arrays2(arrays.size()); - for(std::size_t j=0;jeigenValues(); - else - arrays2[j]=0; - } - std::vector arrays3(arrays.size()); - for(std::size_t j=0;jsetTimeUnit(getTimeUnit()); - ret->setArrays(arrays3,0); - return ret; -} - -MEDCouplingTimeDiscretization *MEDCouplingTimeDiscretization::eigenVectors() const -{ - std::vector arrays; - getArrays(arrays); - std::vector< MEDCouplingAutoRefCountObjectPtr > arrays2(arrays.size()); - for(std::size_t j=0;jeigenVectors(); - else - arrays2[j]=0; - } - std::vector arrays3(arrays.size()); - for(std::size_t j=0;jsetTimeUnit(getTimeUnit()); - ret->setArrays(arrays3,0); - return ret; -} - -MEDCouplingTimeDiscretization *MEDCouplingTimeDiscretization::inverse() const -{ - std::vector arrays; - getArrays(arrays); - std::vector< MEDCouplingAutoRefCountObjectPtr > arrays2(arrays.size()); - for(std::size_t j=0;jinverse(); - else - arrays2[j]=0; - } - std::vector arrays3(arrays.size()); - for(std::size_t j=0;jsetTimeUnit(getTimeUnit()); - ret->setArrays(arrays3,0); - return ret; -} - -MEDCouplingTimeDiscretization *MEDCouplingTimeDiscretization::trace() const -{ - std::vector arrays; - getArrays(arrays); - std::vector< MEDCouplingAutoRefCountObjectPtr > arrays2(arrays.size()); - for(std::size_t j=0;jtrace(); - else - arrays2[j]=0; - } - std::vector arrays3(arrays.size()); - for(std::size_t j=0;jsetTimeUnit(getTimeUnit()); - ret->setArrays(arrays3,0); - return ret; -} - -MEDCouplingTimeDiscretization *MEDCouplingTimeDiscretization::deviator() const -{ - std::vector arrays; - getArrays(arrays); - std::vector< MEDCouplingAutoRefCountObjectPtr > arrays2(arrays.size()); - for(std::size_t j=0;jdeviator(); - else - arrays2[j]=0; - } - std::vector arrays3(arrays.size()); - for(std::size_t j=0;jsetTimeUnit(getTimeUnit()); - ret->setArrays(arrays3,0); - return ret; -} - -MEDCouplingTimeDiscretization *MEDCouplingTimeDiscretization::magnitude() const -{ - std::vector arrays; - getArrays(arrays); - std::vector< MEDCouplingAutoRefCountObjectPtr > arrays2(arrays.size()); - for(std::size_t j=0;jmagnitude(); - else - arrays2[j]=0; - } - std::vector arrays3(arrays.size()); - for(std::size_t j=0;jsetTimeUnit(getTimeUnit()); - ret->setArrays(arrays3,0); - return ret; -} - -MEDCouplingTimeDiscretization *MEDCouplingTimeDiscretization::negate() const -{ - 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()); - ret->setArrays(arrays3,0); - return ret; -} - -MEDCouplingTimeDiscretization *MEDCouplingTimeDiscretization::maxPerTuple() const -{ - std::vector arrays; - getArrays(arrays); - std::vector< MEDCouplingAutoRefCountObjectPtr > arrays2(arrays.size()); - for(std::size_t j=0;jmaxPerTuple(); - else - arrays2[j]=0; - } - std::vector arrays3(arrays.size()); - for(std::size_t j=0;jsetTimeUnit(getTimeUnit()); - ret->setArrays(arrays3,0); - return ret; -} - -MEDCouplingTimeDiscretization *MEDCouplingTimeDiscretization::keepSelectedComponents(const std::vector& compoIds) const -{ - std::vector arrays; - getArrays(arrays); - std::vector< MEDCouplingAutoRefCountObjectPtr > arrays2(arrays.size()); - for(std::size_t j=0;j(arrays[j]->keepSelectedComponents(compoIds)); - else - arrays2[j]=0; - } - std::vector arrays3(arrays.size()); - for(std::size_t j=0;jsetTimeUnit(getTimeUnit()); - ret->setArrays(arrays3,0); - return ret; -} - -void MEDCouplingTimeDiscretization::setSelectedComponents(const MEDCouplingTimeDiscretization *other, const std::vector& compoIds) -{ - std::vector arrays1,arrays2; - getArrays(arrays1); - other->getArrays(arrays2); - if(arrays1.size()!=arrays2.size()) - throw INTERP_KERNEL::Exception("TimeDiscretization::setSelectedComponents : number of arrays mismatch !"); - for(std::size_t i=0;isetSelectedComponents(arrays2[i],compoIds); - else if(arrays1[i]!=0 || arrays2[i]!=0) - throw INTERP_KERNEL::Exception("TimeDiscretization::setSelectedComponents : some time array in correspondance are not defined symetrically !"); - } -} - -void MEDCouplingTimeDiscretization::changeNbOfComponents(int newNbOfComp, double dftValue) -{ - std::vector arrays; - getArrays(arrays); - std::vector< MEDCouplingAutoRefCountObjectPtr > arrays2(arrays.size()); - for(std::size_t j=0;jchangeNbOfComponents(newNbOfComp,dftValue); - else - arrays2[j]=0; - } - std::vector arrays3(arrays.size()); - for(std::size_t j=0;j arrays; - getArrays(arrays); - for(std::size_t j=0;jsortPerTuple(asc); - } -} - -void MEDCouplingTimeDiscretization::setUniformValue(int nbOfTuple, int nbOfCompo, double value) -{ - std::vector arrays; - getArrays(arrays); - std::vector< MEDCouplingAutoRefCountObjectPtr > arrays2(arrays.size()); - for(std::size_t j=0;jchangeNbOfComponents(nbOfCompo,value); - arrays2[j]->fillWithValue(value); - } - else - { - arrays2[j]=DataArrayDouble::New(); - arrays2[j]->alloc(nbOfTuple,nbOfCompo); - arrays2[j]->fillWithValue(value); - } - } - std::vector arrays3(arrays.size()); - 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(std::size_t j=0;japplyLin(a,b,compoId); - } -} - -void MEDCouplingTimeDiscretization::applyLin(double a, double b) -{ - std::vector arrays; - getArrays(arrays); - for(std::size_t j=0;japplyLin(a,b); - } -} - -void MEDCouplingTimeDiscretization::applyFunc(int nbOfComp, FunctionToEvaluate func) -{ - std::vector arrays; - getArrays(arrays); - std::vector< MEDCouplingAutoRefCountObjectPtr > arrays2(arrays.size()); - for(std::size_t j=0;japplyFunc(nbOfComp,func); - else - arrays2[j]=0; - } - std::vector arrays3(arrays.size()); - for(std::size_t j=0;j arrays; - getArrays(arrays); - std::vector< MEDCouplingAutoRefCountObjectPtr > arrays2(arrays.size()); - for(std::size_t j=0;japplyFunc(nbOfComp,func); - else - arrays2[j]=0; - } - std::vector arrays3(arrays.size()); - for(std::size_t j=0;j arrays; - getArrays(arrays); - std::vector< MEDCouplingAutoRefCountObjectPtr > arrays2(arrays.size()); - for(std::size_t j=0;japplyFunc2(nbOfComp,func); - else - arrays2[j]=0; - } - std::vector arrays3(arrays.size()); - for(std::size_t j=0;j& varsOrder, const std::string& func) -{ - std::vector arrays; - getArrays(arrays); - std::vector< MEDCouplingAutoRefCountObjectPtr > arrays2(arrays.size()); - for(std::size_t j=0;japplyFunc3(nbOfComp,varsOrder,func); - else - arrays2[j]=0; - } - std::vector arrays3(arrays.size()); - for(std::size_t j=0;j arrays; - getArrays(arrays); - std::vector< MEDCouplingAutoRefCountObjectPtr > arrays2(arrays.size()); - for(std::size_t j=0;japplyFunc(func); - else - arrays2[j]=0; - } - std::vector arrays3(arrays.size()); - for(std::size_t j=0;j arrays; - getArrays(arrays); - for(std::size_t j=0;japplyFuncFast32(func); - } -} - -void MEDCouplingTimeDiscretization::applyFuncFast64(const std::string& func) -{ - std::vector arrays; - getArrays(arrays); - for(std::size_t j=0;japplyFuncFast64(func); - } -} - -void MEDCouplingTimeDiscretization::fillFromAnalytic(const DataArrayDouble *loc, int nbOfComp, FunctionToEvaluate func) -{ - std::vector arrays; - getArrays(arrays); - std::vector< MEDCouplingAutoRefCountObjectPtr > arrays2(arrays.size()); - for(std::size_t j=0;japplyFunc(nbOfComp,func); - std::vector arrays3(arrays.size()); - for(std::size_t j=0;j arrays; - getArrays(arrays); - std::vector< MEDCouplingAutoRefCountObjectPtr > arrays2(arrays.size()); - for(std::size_t j=0;japplyFunc(nbOfComp,func); - std::vector arrays3(arrays.size()); - for(std::size_t j=0;j arrays; - getArrays(arrays); - std::vector< MEDCouplingAutoRefCountObjectPtr > arrays2(arrays.size()); - for(std::size_t j=0;japplyFunc2(nbOfComp,func); - std::vector arrays3(arrays.size()); - for(std::size_t j=0;j& varsOrder, const std::string& func) -{ - std::vector arrays; - getArrays(arrays); - std::vector< MEDCouplingAutoRefCountObjectPtr > arrays2(arrays.size()); - for(std::size_t j=0;japplyFunc3(nbOfComp,varsOrder,func); - std::vector arrays3(arrays.size()); - for(std::size_t j=0;j(other); - return otherC!=0; -} - -bool MEDCouplingNoTimeLabel::areStrictlyCompatible(const MEDCouplingTimeDiscretization *other, std::string& reason) const -{ - if(!MEDCouplingTimeDiscretization::areStrictlyCompatible(other,reason)) - return false; - const MEDCouplingNoTimeLabel *otherC=dynamic_cast(other); - bool ret=otherC!=0; - if(!ret) - reason.insert(0,"time discretization of this is NO_TIME, other has a different time discretization."); - return ret; -} - -bool MEDCouplingNoTimeLabel::areStrictlyCompatibleForMul(const MEDCouplingTimeDiscretization *other) const -{ - if(!MEDCouplingTimeDiscretization::areStrictlyCompatibleForMul(other)) - return false; - const MEDCouplingNoTimeLabel *otherC=dynamic_cast(other); - return otherC!=0; -} - -bool MEDCouplingNoTimeLabel::areStrictlyCompatibleForDiv(const MEDCouplingTimeDiscretization *other) const -{ - if(!MEDCouplingTimeDiscretization::areStrictlyCompatibleForDiv(other)) - return false; - const MEDCouplingNoTimeLabel *otherC=dynamic_cast(other); - return otherC!=0; -} - -bool MEDCouplingNoTimeLabel::areCompatibleForMeld(const MEDCouplingTimeDiscretization *other) const -{ - if(!MEDCouplingTimeDiscretization::areCompatibleForMeld(other)) - return false; - const MEDCouplingNoTimeLabel *otherC=dynamic_cast(other); - return otherC!=0; -} - -bool MEDCouplingNoTimeLabel::isEqualIfNotWhy(const MEDCouplingTimeDiscretization *other, double prec, std::string& reason) const -{ - const MEDCouplingNoTimeLabel *otherC=dynamic_cast(other); - if(!otherC) - { - reason="This has time discretization NO_TIME, other not."; - return false; - } - return MEDCouplingTimeDiscretization::isEqualIfNotWhy(other,prec,reason); -} - -bool MEDCouplingNoTimeLabel::isEqualWithoutConsideringStr(const MEDCouplingTimeDiscretization *other, double prec) const -{ - const MEDCouplingNoTimeLabel *otherC=dynamic_cast(other); - if(!otherC) - return false; - return MEDCouplingTimeDiscretization::isEqualWithoutConsideringStr(other,prec); -} - -MEDCouplingTimeDiscretization *MEDCouplingNoTimeLabel::aggregate(const MEDCouplingTimeDiscretization *other) const -{ - const MEDCouplingNoTimeLabel *otherC=dynamic_cast(other); - if(!otherC) - throw INTERP_KERNEL::Exception("NoTimeLabel::aggregation on mismatched time discretization !"); - MEDCouplingAutoRefCountObjectPtr arr=DataArrayDouble::Aggregate(getArray(),other->getArray()); - MEDCouplingNoTimeLabel *ret=new MEDCouplingNoTimeLabel; - ret->setArray(arr,0); - return ret; -} - -MEDCouplingTimeDiscretization *MEDCouplingNoTimeLabel::aggregate(const std::vector& other) const -{ - std::vector a(other.size()); - int i=0; - for(std::vector::const_iterator it=other.begin();it!=other.end();it++,i++) - { - const MEDCouplingNoTimeLabel *itC=dynamic_cast(*it); - if(!itC) - throw INTERP_KERNEL::Exception("NoTimeLabel::aggregate on mismatched time discretization !"); - a[i]=itC->getArray(); - } - MEDCouplingAutoRefCountObjectPtr arr=DataArrayDouble::Aggregate(a); - MEDCouplingNoTimeLabel *ret=new MEDCouplingNoTimeLabel; - ret->setArray(arr,0); - return ret; -} - -MEDCouplingTimeDiscretization *MEDCouplingNoTimeLabel::meld(const MEDCouplingTimeDiscretization *other) const -{ - const MEDCouplingNoTimeLabel *otherC=dynamic_cast(other); - if(!otherC) - throw INTERP_KERNEL::Exception("NoTimeLabel::meld on mismatched time discretization !"); - MEDCouplingAutoRefCountObjectPtr arr=DataArrayDouble::Meld(getArray(),other->getArray()); - MEDCouplingNoTimeLabel *ret=new MEDCouplingNoTimeLabel; - ret->setTimeTolerance(getTimeTolerance()); - ret->setArray(arr,0); - return ret; -} - -MEDCouplingTimeDiscretization *MEDCouplingNoTimeLabel::dot(const MEDCouplingTimeDiscretization *other) const -{ - const MEDCouplingNoTimeLabel *otherC=dynamic_cast(other); - if(!otherC) - throw INTERP_KERNEL::Exception("NoTimeLabel::dot on mismatched time discretization !"); - MEDCouplingAutoRefCountObjectPtr arr=DataArrayDouble::Dot(getArray(),other->getArray()); - MEDCouplingNoTimeLabel *ret=new MEDCouplingNoTimeLabel; - ret->setArray(arr,0); - return ret; -} - -MEDCouplingTimeDiscretization *MEDCouplingNoTimeLabel::crossProduct(const MEDCouplingTimeDiscretization *other) const -{ - const MEDCouplingNoTimeLabel *otherC=dynamic_cast(other); - if(!otherC) - throw INTERP_KERNEL::Exception("NoTimeLabel::crossProduct on mismatched time discretization !"); - MEDCouplingAutoRefCountObjectPtr arr=DataArrayDouble::CrossProduct(getArray(),other->getArray()); - MEDCouplingNoTimeLabel *ret=new MEDCouplingNoTimeLabel; - ret->setArray(arr,0); - return ret; -} - -MEDCouplingTimeDiscretization *MEDCouplingNoTimeLabel::max(const MEDCouplingTimeDiscretization *other) const -{ - const MEDCouplingNoTimeLabel *otherC=dynamic_cast(other); - if(!otherC) - throw INTERP_KERNEL::Exception("NoTimeLabel::max on mismatched time discretization !"); - MEDCouplingAutoRefCountObjectPtr arr=DataArrayDouble::Max(getArray(),other->getArray()); - MEDCouplingNoTimeLabel *ret=new MEDCouplingNoTimeLabel; - ret->setArray(arr,0); - return ret; -} - -MEDCouplingTimeDiscretization *MEDCouplingNoTimeLabel::min(const MEDCouplingTimeDiscretization *other) const -{ - const MEDCouplingNoTimeLabel *otherC=dynamic_cast(other); - if(!otherC) - throw INTERP_KERNEL::Exception("NoTimeLabel::max on mismatched time discretization !"); - MEDCouplingAutoRefCountObjectPtr arr=DataArrayDouble::Min(getArray(),other->getArray()); - MEDCouplingNoTimeLabel *ret=new MEDCouplingNoTimeLabel; - ret->setArray(arr,0); - return ret; -} - -MEDCouplingTimeDiscretization *MEDCouplingNoTimeLabel::add(const MEDCouplingTimeDiscretization *other) const -{ - const MEDCouplingNoTimeLabel *otherC=dynamic_cast(other); - if(!otherC) - throw INTERP_KERNEL::Exception("NoTimeLabel::add on mismatched time discretization !"); - MEDCouplingAutoRefCountObjectPtr arr=DataArrayDouble::Add(getArray(),other->getArray()); - MEDCouplingNoTimeLabel *ret=new MEDCouplingNoTimeLabel; - ret->setArray(arr,0); - return ret; -} - -void MEDCouplingNoTimeLabel::addEqual(const MEDCouplingTimeDiscretization *other) -{ - const MEDCouplingNoTimeLabel *otherC=dynamic_cast(other); - if(!otherC) - throw INTERP_KERNEL::Exception("NoTimeLabel::addEqual on mismatched time discretization !"); - if(!getArray()) - throw INTERP_KERNEL::Exception("MEDCouplingNoTimeLabel::addEqual : Data Array is NULL !"); - getArray()->addEqual(other->getArray()); -} - -MEDCouplingTimeDiscretization *MEDCouplingNoTimeLabel::substract(const MEDCouplingTimeDiscretization *other) const -{ - const MEDCouplingNoTimeLabel *otherC=dynamic_cast(other); - if(!otherC) - throw INTERP_KERNEL::Exception("NoTimeLabel::substract on mismatched time discretization !"); - if(!getArray()) - throw INTERP_KERNEL::Exception("MEDCouplingNoTimeLabel::substract : Data Array is NULL !"); - MEDCouplingAutoRefCountObjectPtr arr=DataArrayDouble::Substract(getArray(),other->getArray()); - MEDCouplingNoTimeLabel *ret=new MEDCouplingNoTimeLabel; - ret->setArray(arr,0); - return ret; -} - -void MEDCouplingNoTimeLabel::substractEqual(const MEDCouplingTimeDiscretization *other) -{ - const MEDCouplingNoTimeLabel *otherC=dynamic_cast(other); - if(!otherC) - throw INTERP_KERNEL::Exception("NoTimeLabel::substractEqual on mismatched time discretization !"); - if(!getArray()) - throw INTERP_KERNEL::Exception("MEDCouplingNoTimeLabel::substractEqual : Data Array is NULL !"); - getArray()->substractEqual(other->getArray()); -} - -MEDCouplingTimeDiscretization *MEDCouplingNoTimeLabel::multiply(const MEDCouplingTimeDiscretization *other) const -{ - const MEDCouplingNoTimeLabel *otherC=dynamic_cast(other); - if(!otherC) - throw INTERP_KERNEL::Exception("NoTimeLabel::multiply on mismatched time discretization !"); - MEDCouplingAutoRefCountObjectPtr arr=DataArrayDouble::Multiply(getArray(),other->getArray()); - MEDCouplingNoTimeLabel *ret=new MEDCouplingNoTimeLabel; - ret->setArray(arr,0); - return ret; -} - -void MEDCouplingNoTimeLabel::multiplyEqual(const MEDCouplingTimeDiscretization *other) -{ - const MEDCouplingNoTimeLabel *otherC=dynamic_cast(other); - if(!otherC) - throw INTERP_KERNEL::Exception("NoTimeLabel::multiplyEqual on mismatched time discretization !"); - if(!getArray()) - throw INTERP_KERNEL::Exception("MEDCouplingNoTimeLabel::multiplyEqual : Data Array is NULL !"); - getArray()->multiplyEqual(other->getArray()); -} - -MEDCouplingTimeDiscretization *MEDCouplingNoTimeLabel::divide(const MEDCouplingTimeDiscretization *other) const -{ - const MEDCouplingNoTimeLabel *otherC=dynamic_cast(other); - if(!otherC) - throw INTERP_KERNEL::Exception("divide on mismatched time discretization !"); - MEDCouplingAutoRefCountObjectPtr arr=DataArrayDouble::Divide(getArray(),other->getArray()); - MEDCouplingNoTimeLabel *ret=new MEDCouplingNoTimeLabel; - ret->setArray(arr,0); - return ret; -} - -void MEDCouplingNoTimeLabel::divideEqual(const MEDCouplingTimeDiscretization *other) -{ - const MEDCouplingNoTimeLabel *otherC=dynamic_cast(other); - if(!otherC) - throw INTERP_KERNEL::Exception("NoTimeLabel::divideEqual on mismatched time discretization !"); - if(!getArray()) - throw INTERP_KERNEL::Exception("MEDCouplingNoTimeLabel::divideEqual : Data Array is NULL !"); - getArray()->divideEqual(other->getArray()); -} - -MEDCouplingTimeDiscretization *MEDCouplingNoTimeLabel::pow(const MEDCouplingTimeDiscretization *other) const -{ - 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) -{ - 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 -{ - return new MEDCouplingNoTimeLabel(*this,deepCpy); -} - -void MEDCouplingNoTimeLabel::checkTimePresence(double time) const -{ - throw INTERP_KERNEL::Exception(EXCEPTION_MSG); -} - -std::vector< const DataArrayDouble *> MEDCouplingNoTimeLabel::getArraysForTime(double time) const -{ - throw INTERP_KERNEL::Exception(EXCEPTION_MSG); -} - -void MEDCouplingNoTimeLabel::getValueForTime(double time, const std::vector& vals, double *res) const -{ - throw INTERP_KERNEL::Exception(EXCEPTION_MSG); -} - -bool MEDCouplingNoTimeLabel::isBefore(const MEDCouplingTimeDiscretization *other) const -{ - throw INTERP_KERNEL::Exception(EXCEPTION_MSG); -} - -bool MEDCouplingNoTimeLabel::isStrictlyBefore(const MEDCouplingTimeDiscretization *other) const -{ - throw INTERP_KERNEL::Exception(EXCEPTION_MSG); -} - -double MEDCouplingNoTimeLabel::getStartTime(int& iteration, int& order) const -{ - throw INTERP_KERNEL::Exception(EXCEPTION_MSG); -} - -double MEDCouplingNoTimeLabel::getEndTime(int& iteration, int& order) const -{ - throw INTERP_KERNEL::Exception(EXCEPTION_MSG); -} - -void MEDCouplingNoTimeLabel::setStartIteration(int it) -{ - throw INTERP_KERNEL::Exception(EXCEPTION_MSG); -} - -void MEDCouplingNoTimeLabel::setEndIteration(int it) -{ - throw INTERP_KERNEL::Exception(EXCEPTION_MSG); -} - -void MEDCouplingNoTimeLabel::setStartOrder(int order) -{ - throw INTERP_KERNEL::Exception(EXCEPTION_MSG); -} - -void MEDCouplingNoTimeLabel::setEndOrder(int order) -{ - throw INTERP_KERNEL::Exception(EXCEPTION_MSG); -} - -void MEDCouplingNoTimeLabel::setStartTimeValue(double time) -{ - throw INTERP_KERNEL::Exception(EXCEPTION_MSG); -} - -void MEDCouplingNoTimeLabel::setEndTimeValue(double time) -{ - throw INTERP_KERNEL::Exception(EXCEPTION_MSG); -} - -void MEDCouplingNoTimeLabel::setStartTime(double time, int iteration, int order) -{ - throw INTERP_KERNEL::Exception(EXCEPTION_MSG); -} - -void MEDCouplingNoTimeLabel::setEndTime(double time, int iteration, int order) -{ - throw INTERP_KERNEL::Exception(EXCEPTION_MSG); -} - -void MEDCouplingNoTimeLabel::getValueOnTime(int eltId, double time, double *value) const -{ - throw INTERP_KERNEL::Exception(EXCEPTION_MSG); -} - -void MEDCouplingNoTimeLabel::getValueOnDiscTime(int eltId, int iteration, int order, double *value) const -{ - throw INTERP_KERNEL::Exception(EXCEPTION_MSG); -} - -/*! - * idem getTinySerializationIntInformation except that it is for multi field fetch - */ -void MEDCouplingNoTimeLabel::getTinySerializationIntInformation2(std::vector& tinyInfo) const -{ - tinyInfo.clear(); -} - -/*! - * idem getTinySerializationDbleInformation except that it is for multi field fetch - */ -void MEDCouplingNoTimeLabel::getTinySerializationDbleInformation2(std::vector& tinyInfo) const -{ - tinyInfo.resize(1); - tinyInfo[0]=_time_tolerance; -} - -/*! - * idem finishUnserialization except that it is for multi field fetch - */ -void MEDCouplingNoTimeLabel::finishUnserialization2(const std::vector& tinyInfoI, const std::vector& tinyInfoD) -{ - _time_tolerance=tinyInfoD[0]; -} - -MEDCouplingWithTimeStep::MEDCouplingWithTimeStep(const MEDCouplingWithTimeStep& other, bool deepCpy):MEDCouplingTimeDiscretization(other,deepCpy), - _time(other._time),_iteration(other._iteration),_order(other._order) -{ -} - -MEDCouplingWithTimeStep::MEDCouplingWithTimeStep():_time(0.),_iteration(-1),_order(-1) -{ -} - -std::string MEDCouplingWithTimeStep::getStringRepr() const -{ - std::ostringstream stream; - stream << REPR << " Time is defined by iteration=" << _iteration << " order=" << _order << " and time=" << _time << "."; - stream << "\nTime unit is : \"" << _time_unit << "\""; - return stream.str(); -} - -void MEDCouplingWithTimeStep::synchronizeTimeWith(const MEDCouplingMesh *mesh) -{ - if(!mesh) - throw INTERP_KERNEL::Exception("MEDCouplingWithTimeStep::synchronizeTimeWith : mesh instance is NULL ! Impossible to synchronize time !"); - int it=-1,order=-1; - double val=mesh->getTime(it,order); - _time=val; _iteration=it; _order=order; - std::string tUnit=mesh->getTimeUnit(); - _time_unit=tUnit; -} - -void MEDCouplingWithTimeStep::getTinySerializationIntInformation(std::vector& tinyInfo) const -{ - MEDCouplingTimeDiscretization::getTinySerializationIntInformation(tinyInfo); - tinyInfo.push_back(_iteration); - tinyInfo.push_back(_order); -} - -void MEDCouplingWithTimeStep::getTinySerializationDbleInformation(std::vector& tinyInfo) const -{ - MEDCouplingTimeDiscretization::getTinySerializationDbleInformation(tinyInfo); - tinyInfo.push_back(_time); -} - -void MEDCouplingWithTimeStep::finishUnserialization(const std::vector& tinyInfoI, const std::vector& tinyInfoD, const std::vector& tinyInfoS) -{ - MEDCouplingTimeDiscretization::finishUnserialization(tinyInfoI,tinyInfoD,tinyInfoS); - _time=tinyInfoD[1]; - _iteration=tinyInfoI[2]; - _order=tinyInfoI[3]; -} - -/*! - * idem getTinySerializationIntInformation except that it is for multi field fetch - */ -void MEDCouplingWithTimeStep::getTinySerializationIntInformation2(std::vector& tinyInfo) const -{ - tinyInfo.resize(2); - tinyInfo[0]=_iteration; - tinyInfo[1]=_order; -} - -/*! - * idem getTinySerializationDbleInformation except that it is for multi field fetch - */ -void MEDCouplingWithTimeStep::getTinySerializationDbleInformation2(std::vector& tinyInfo) const -{ - tinyInfo.resize(2); - tinyInfo[0]=_time_tolerance; - tinyInfo[1]=_time; -} - -/*! - * idem finishUnserialization except that it is for multi field fetch - */ -void MEDCouplingWithTimeStep::finishUnserialization2(const std::vector& tinyInfoI, const std::vector& tinyInfoD) -{ - _iteration=tinyInfoI[0]; - _order=tinyInfoI[1]; - _time_tolerance=tinyInfoD[0]; - _time=tinyInfoD[1]; -} - -bool MEDCouplingWithTimeStep::areCompatible(const MEDCouplingTimeDiscretization *other) const -{ - if(!MEDCouplingTimeDiscretization::areCompatible(other)) - return false; - const MEDCouplingWithTimeStep *otherC=dynamic_cast(other); - return otherC!=0; -} - -bool MEDCouplingWithTimeStep::areStrictlyCompatible(const MEDCouplingTimeDiscretization *other, std::string& reason) const -{ - if(!MEDCouplingTimeDiscretization::areStrictlyCompatible(other,reason)) - return false; - const MEDCouplingWithTimeStep *otherC=dynamic_cast(other); - bool ret=otherC!=0; - if(!ret) - reason.insert(0,"time discretization of this is ONE_TIME, other has a different time discretization."); - return ret; -} - -bool MEDCouplingWithTimeStep::areStrictlyCompatibleForMul(const MEDCouplingTimeDiscretization *other) const -{ - if(!MEDCouplingTimeDiscretization::areStrictlyCompatibleForMul(other)) - return false; - const MEDCouplingWithTimeStep *otherC=dynamic_cast(other); - return otherC!=0; -} - -bool MEDCouplingWithTimeStep::areStrictlyCompatibleForDiv(const MEDCouplingTimeDiscretization *other) const -{ - if(!MEDCouplingTimeDiscretization::areStrictlyCompatibleForDiv(other)) - return false; - const MEDCouplingWithTimeStep *otherC=dynamic_cast(other); - return otherC!=0; -} - -bool MEDCouplingWithTimeStep::areCompatibleForMeld(const MEDCouplingTimeDiscretization *other) const -{ - if(!MEDCouplingTimeDiscretization::areCompatibleForMeld(other)) - return false; - const MEDCouplingWithTimeStep *otherC=dynamic_cast(other); - return otherC!=0; -} - -bool MEDCouplingWithTimeStep::isEqualIfNotWhy(const MEDCouplingTimeDiscretization *other, double prec, std::string& reason) const -{ - const MEDCouplingWithTimeStep *otherC=dynamic_cast(other); - std::ostringstream oss; oss.precision(15); - if(!otherC) - { - reason="This has time discretization ONE_TIME, other not."; - return false; - } - if(_iteration!=otherC->_iteration) - { - oss << "iterations differ. this iteration=" << _iteration << " other iteration=" << otherC->_iteration; - reason=oss.str(); - return false; - } - if(_order!=otherC->_order) - { - oss << "orders differ. this order=" << _order << " other order=" << otherC->_order; - reason=oss.str(); - return false; - } - if(std::fabs(_time-otherC->_time)>_time_tolerance) - { - oss << "times differ. this time=" << _time << " other time=" << otherC->_time; - reason=oss.str(); - return false; - } - return MEDCouplingTimeDiscretization::isEqualIfNotWhy(other,prec,reason); -} - -bool MEDCouplingWithTimeStep::isEqualWithoutConsideringStr(const MEDCouplingTimeDiscretization *other, double prec) const -{ - const MEDCouplingWithTimeStep *otherC=dynamic_cast(other); - if(!otherC) - return false; - if(_iteration!=otherC->_iteration) - return false; - if(_order!=otherC->_order) - return false; - if(std::fabs(_time-otherC->_time)>_time_tolerance) - return false; - return MEDCouplingTimeDiscretization::isEqualWithoutConsideringStr(other,prec); -} - -void MEDCouplingWithTimeStep::copyTinyAttrFrom(const MEDCouplingTimeDiscretization& other) -{ - MEDCouplingTimeDiscretization::copyTinyAttrFrom(other); - const MEDCouplingWithTimeStep *otherC=dynamic_cast(&other); - if(!otherC) - throw INTERP_KERNEL::Exception("MEDCouplingWithTimeStep::copyTinyAttrFrom : mismatch of time discretization !"); - _time=otherC->_time; - _iteration=otherC->_iteration; - _order=otherC->_order; -} - -MEDCouplingTimeDiscretization *MEDCouplingWithTimeStep::aggregate(const MEDCouplingTimeDiscretization *other) const -{ - const MEDCouplingWithTimeStep *otherC=dynamic_cast(other); - if(!otherC) - throw INTERP_KERNEL::Exception("WithTimeStep::aggregation on mismatched time discretization !"); - MEDCouplingAutoRefCountObjectPtr arr=DataArrayDouble::Aggregate(getArray(),other->getArray()); - MEDCouplingWithTimeStep *ret=new MEDCouplingWithTimeStep; - ret->setArray(arr,0); - return ret; -} - -MEDCouplingTimeDiscretization *MEDCouplingWithTimeStep::aggregate(const std::vector& other) const -{ - std::vector a(other.size()); - int i=0; - for(std::vector::const_iterator it=other.begin();it!=other.end();it++,i++) - { - const MEDCouplingWithTimeStep *itC=dynamic_cast(*it); - if(!itC) - throw INTERP_KERNEL::Exception("WithTimeStep::aggregate on mismatched time discretization !"); - a[i]=itC->getArray(); - } - MEDCouplingAutoRefCountObjectPtr arr=DataArrayDouble::Aggregate(a); - MEDCouplingWithTimeStep *ret=new MEDCouplingWithTimeStep; - ret->setArray(arr,0); - return ret; -} - -MEDCouplingTimeDiscretization *MEDCouplingWithTimeStep::meld(const MEDCouplingTimeDiscretization *other) const -{ - const MEDCouplingWithTimeStep *otherC=dynamic_cast(other); - if(!otherC) - throw INTERP_KERNEL::Exception("WithTimeStep::meld on mismatched time discretization !"); - MEDCouplingAutoRefCountObjectPtr arr=DataArrayDouble::Meld(getArray(),other->getArray()); - MEDCouplingWithTimeStep *ret=new MEDCouplingWithTimeStep; - ret->setArray(arr,0); - return ret; -} - -MEDCouplingTimeDiscretization *MEDCouplingWithTimeStep::dot(const MEDCouplingTimeDiscretization *other) const -{ - const MEDCouplingWithTimeStep *otherC=dynamic_cast(other); - if(!otherC) - throw INTERP_KERNEL::Exception("WithTimeStep::dot on mismatched time discretization !"); - MEDCouplingWithTimeStep *ret=new MEDCouplingWithTimeStep; - MEDCouplingAutoRefCountObjectPtr arr=DataArrayDouble::Dot(getArray(),other->getArray()); - ret->setArray(arr,0); - return ret; -} - -MEDCouplingTimeDiscretization *MEDCouplingWithTimeStep::crossProduct(const MEDCouplingTimeDiscretization *other) const -{ - const MEDCouplingWithTimeStep *otherC=dynamic_cast(other); - if(!otherC) - throw INTERP_KERNEL::Exception("WithTimeStep::crossProduct on mismatched time discretization !"); - MEDCouplingAutoRefCountObjectPtr arr=DataArrayDouble::CrossProduct(getArray(),other->getArray()); - MEDCouplingWithTimeStep *ret=new MEDCouplingWithTimeStep; - ret->setArray(arr,0); - return ret; -} - -MEDCouplingTimeDiscretization *MEDCouplingWithTimeStep::max(const MEDCouplingTimeDiscretization *other) const -{ - const MEDCouplingWithTimeStep *otherC=dynamic_cast(other); - if(!otherC) - throw INTERP_KERNEL::Exception("WithTimeStep::max on mismatched time discretization !"); - MEDCouplingAutoRefCountObjectPtr arr=DataArrayDouble::Max(getArray(),other->getArray()); - MEDCouplingWithTimeStep *ret=new MEDCouplingWithTimeStep; - ret->setArray(arr,0); - return ret; -} - -MEDCouplingTimeDiscretization *MEDCouplingWithTimeStep::min(const MEDCouplingTimeDiscretization *other) const -{ - const MEDCouplingWithTimeStep *otherC=dynamic_cast(other); - if(!otherC) - throw INTERP_KERNEL::Exception("WithTimeStep::min on mismatched time discretization !"); - MEDCouplingAutoRefCountObjectPtr arr=DataArrayDouble::Min(getArray(),other->getArray()); - MEDCouplingWithTimeStep *ret=new MEDCouplingWithTimeStep; - ret->setArray(arr,0); - return ret; -} - -MEDCouplingTimeDiscretization *MEDCouplingWithTimeStep::add(const MEDCouplingTimeDiscretization *other) const -{ - const MEDCouplingWithTimeStep *otherC=dynamic_cast(other); - if(!otherC) - throw INTERP_KERNEL::Exception("WithTimeStep::add on mismatched time discretization !"); - MEDCouplingAutoRefCountObjectPtr arr=DataArrayDouble::Add(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::addEqual(const MEDCouplingTimeDiscretization *other) -{ - const MEDCouplingWithTimeStep *otherC=dynamic_cast(other); - if(!otherC) - throw INTERP_KERNEL::Exception("WithTimeStep::addEqual on mismatched time discretization !"); - if(!getArray()) - throw INTERP_KERNEL::Exception("MEDCouplingWithTimeLabel::addEqual : Data Array is NULL !"); - getArray()->addEqual(other->getArray()); -} - -MEDCouplingTimeDiscretization *MEDCouplingWithTimeStep::substract(const MEDCouplingTimeDiscretization *other) const -{ - const MEDCouplingWithTimeStep *otherC=dynamic_cast(other); - if(!otherC) - throw INTERP_KERNEL::Exception("WithTimeStep::substract on mismatched time discretization !"); - MEDCouplingAutoRefCountObjectPtr arr=DataArrayDouble::Substract(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::substractEqual(const MEDCouplingTimeDiscretization *other) -{ - const MEDCouplingWithTimeStep *otherC=dynamic_cast(other); - if(!otherC) - throw INTERP_KERNEL::Exception("WithTimeStep::substractEqual on mismatched time discretization !"); - if(!getArray()) - throw INTERP_KERNEL::Exception("MEDCouplingWithTimeLabel::substractEqual : Data Array is NULL !"); - getArray()->substractEqual(other->getArray()); -} - -MEDCouplingTimeDiscretization *MEDCouplingWithTimeStep::multiply(const MEDCouplingTimeDiscretization *other) const -{ - const MEDCouplingWithTimeStep *otherC=dynamic_cast(other); - if(!otherC) - throw INTERP_KERNEL::Exception("WithTimeStep::multiply on mismatched time discretization !"); - MEDCouplingAutoRefCountObjectPtr arr=DataArrayDouble::Multiply(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::multiplyEqual(const MEDCouplingTimeDiscretization *other) -{ - const MEDCouplingWithTimeStep *otherC=dynamic_cast(other); - if(!otherC) - throw INTERP_KERNEL::Exception("WithTimeStep::multiplyEqual on mismatched time discretization !"); - if(!getArray()) - throw INTERP_KERNEL::Exception("MEDCouplingWithTimeLabel::multiplyEqual : Data Array is NULL !"); - getArray()->multiplyEqual(other->getArray()); -} - -MEDCouplingTimeDiscretization *MEDCouplingWithTimeStep::divide(const MEDCouplingTimeDiscretization *other) const -{ - const MEDCouplingWithTimeStep *otherC=dynamic_cast(other); - if(!otherC) - throw INTERP_KERNEL::Exception("WithTimeStep::divide on mismatched time discretization !"); - MEDCouplingAutoRefCountObjectPtr arr=DataArrayDouble::Divide(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::divideEqual(const MEDCouplingTimeDiscretization *other) -{ - const MEDCouplingWithTimeStep *otherC=dynamic_cast(other); - if(!otherC) - throw INTERP_KERNEL::Exception("WithTimeStep::divideEqual on mismatched time discretization !"); - if(!getArray()) - throw INTERP_KERNEL::Exception("MEDCouplingWithTimeLabel::divideEqual : Data Array is NULL !"); - getArray()->divideEqual(other->getArray()); -} - -MEDCouplingTimeDiscretization *MEDCouplingWithTimeStep::pow(const MEDCouplingTimeDiscretization *other) const -{ - 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) -{ - 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 -{ - return new MEDCouplingWithTimeStep(*this,deepCpy); -} - -void MEDCouplingWithTimeStep::checkNoTimePresence() const -{ - throw INTERP_KERNEL::Exception("No time specified on a field defined on one time"); -} - -void MEDCouplingWithTimeStep::checkTimePresence(double time) const -{ - if(std::fabs(time-_time)>_time_tolerance) - { - std::ostringstream stream; - stream << "The field is defined on time " << _time << " with eps=" << _time_tolerance << " and asking time = " << time << " !"; - throw INTERP_KERNEL::Exception(stream.str().c_str()); - } -} - -std::vector< const DataArrayDouble *> MEDCouplingWithTimeStep::getArraysForTime(double time) const -{ - if(std::fabs(time-_time)<=_time_tolerance) - { - std::vector< const DataArrayDouble *> ret(1); - ret[0]=_array; - return ret; - } - else - throw INTERP_KERNEL::Exception(EXCEPTION_MSG); -} - -void MEDCouplingWithTimeStep::getValueForTime(double time, const std::vector& vals, double *res) const -{ - std::copy(vals.begin(),vals.end(),res); -} - -void MEDCouplingWithTimeStep::getValueOnTime(int eltId, double time, double *value) const -{ - if(std::fabs(time-_time)<=_time_tolerance) - if(_array) - _array->getTuple(eltId,value); - else - throw INTERP_KERNEL::Exception("No array existing."); - else - throw INTERP_KERNEL::Exception(EXCEPTION_MSG); -} - -void MEDCouplingWithTimeStep::getValueOnDiscTime(int eltId, int iteration, int order, double *value) const -{ - if(_iteration==iteration && _order==order) - if(_array) - _array->getTuple(eltId,value); - else - throw INTERP_KERNEL::Exception("No array existing."); - else - throw INTERP_KERNEL::Exception("No data on this discrete time."); -} - -MEDCouplingConstOnTimeInterval::MEDCouplingConstOnTimeInterval():_start_time(0.),_end_time(0.),_start_iteration(-1),_end_iteration(-1),_start_order(-1),_end_order(-1) -{ -} - -void MEDCouplingConstOnTimeInterval::copyTinyAttrFrom(const MEDCouplingTimeDiscretization& other) -{ - MEDCouplingTimeDiscretization::copyTinyAttrFrom(other); - const MEDCouplingConstOnTimeInterval *otherC=dynamic_cast(&other); - if(!otherC) - throw INTERP_KERNEL::Exception("MEDCouplingConstOnTimeInterval::copyTinyAttrFrom : mismatch of time discretization !"); - _start_time=otherC->_start_time; - _end_time=otherC->_end_time; - _start_iteration=otherC->_start_iteration; - _end_iteration=otherC->_end_iteration; - _start_order=otherC->_start_order; - _end_order=otherC->_end_order; -} - -void MEDCouplingConstOnTimeInterval::getTinySerializationIntInformation(std::vector& tinyInfo) const -{ - MEDCouplingTimeDiscretization::getTinySerializationIntInformation(tinyInfo); - tinyInfo.push_back(_start_iteration); - tinyInfo.push_back(_start_order); - tinyInfo.push_back(_end_iteration); - tinyInfo.push_back(_end_order); -} - -void MEDCouplingConstOnTimeInterval::getTinySerializationDbleInformation(std::vector& tinyInfo) const -{ - 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) -{ - MEDCouplingTimeDiscretization::finishUnserialization(tinyInfoI,tinyInfoD,tinyInfoS); - _start_time=tinyInfoD[1]; - _end_time=tinyInfoD[2]; - _start_iteration=tinyInfoI[2]; - _start_order=tinyInfoI[3]; - _end_iteration=tinyInfoI[4]; - _end_order=tinyInfoI[5]; -} - -/*! - * idem getTinySerializationIntInformation except that it is for multi field fetch - */ -void MEDCouplingConstOnTimeInterval::getTinySerializationIntInformation2(std::vector& tinyInfo) const -{ - tinyInfo.resize(4); - tinyInfo[0]=_start_iteration; - tinyInfo[1]=_start_order; - tinyInfo[2]=_end_iteration; - tinyInfo[3]=_end_order; -} - -/*! - * idem getTinySerializationDbleInformation except that it is for multi field fetch - */ -void MEDCouplingConstOnTimeInterval::getTinySerializationDbleInformation2(std::vector& tinyInfo) const -{ - tinyInfo.resize(3); - tinyInfo[0]=_time_tolerance; - tinyInfo[1]=_start_time; - tinyInfo[2]=_end_time; -} - -/*! - * idem finishUnserialization except that it is for multi field fetch - */ -void MEDCouplingConstOnTimeInterval::finishUnserialization2(const std::vector& tinyInfoI, const std::vector& tinyInfoD) -{ - _start_iteration=tinyInfoI[0]; - _start_order=tinyInfoI[1]; - _end_iteration=tinyInfoI[2]; - _end_order=tinyInfoI[3]; - _time_tolerance=tinyInfoD[0]; - _start_time=tinyInfoD[1]; - _end_time=tinyInfoD[2]; -} - -MEDCouplingConstOnTimeInterval::MEDCouplingConstOnTimeInterval(const MEDCouplingConstOnTimeInterval& 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),_start_order(other._start_order),_end_order(other._end_order) -{ -} - -std::string MEDCouplingConstOnTimeInterval::getStringRepr() const -{ - std::ostringstream stream; - stream << REPR << " Time interval is defined by :\niteration_start=" << _start_iteration << " order_start=" << _start_order << " and time_start=" << _start_time << "\n"; - stream << "iteration_end=" << _end_iteration << " order_end=" << _end_order << " and end_time=" << _end_time << "\n"; - stream << "\nTime unit is : \"" << _time_unit << "\""; - return stream.str(); -} - -void MEDCouplingConstOnTimeInterval::synchronizeTimeWith(const MEDCouplingMesh *mesh) -{ - if(!mesh) - throw INTERP_KERNEL::Exception("MEDCouplingWithTimeStep::synchronizeTimeWith : mesh instance is NULL ! Impossible to synchronize time !"); - int it=-1,order=-1; - double val=mesh->getTime(it,order); - _start_time=val; _start_iteration=it; _start_order=order; - _end_time=val; _end_iteration=it; _end_order=order; - std::string tUnit=mesh->getTimeUnit(); - _time_unit=tUnit; -} - -MEDCouplingTimeDiscretization *MEDCouplingConstOnTimeInterval::performCpy(bool deepCpy) const -{ - return new MEDCouplingConstOnTimeInterval(*this,deepCpy); -} - -std::vector< const DataArrayDouble *> MEDCouplingConstOnTimeInterval::getArraysForTime(double time) const -{ - if(time>_start_time-_time_tolerance && time<_end_time+_time_tolerance) - { - std::vector< const DataArrayDouble *> ret(1); - ret[0]=_array; - return ret; - } - else - throw INTERP_KERNEL::Exception(EXCEPTION_MSG); -} - -void MEDCouplingConstOnTimeInterval::getValueForTime(double time, const std::vector& vals, double *res) const -{ - std::copy(vals.begin(),vals.end(),res); -} - -bool MEDCouplingConstOnTimeInterval::areCompatible(const MEDCouplingTimeDiscretization *other) const -{ - if(!MEDCouplingTimeDiscretization::areCompatible(other)) - return false; - const MEDCouplingConstOnTimeInterval *otherC=dynamic_cast(other); - return otherC!=0; -} - -bool MEDCouplingConstOnTimeInterval::areStrictlyCompatible(const MEDCouplingTimeDiscretization *other, std::string& reason) const -{ - if(!MEDCouplingTimeDiscretization::areStrictlyCompatible(other,reason)) - return false; - const MEDCouplingConstOnTimeInterval *otherC=dynamic_cast(other); - bool ret=otherC!=0; - if(!ret) - reason.insert(0,"time discretization of this is CONST_ON_TIME_INTERVAL, other has a different time discretization."); - return ret; -} - -bool MEDCouplingConstOnTimeInterval::areStrictlyCompatibleForMul(const MEDCouplingTimeDiscretization *other) const -{ - if(!MEDCouplingTimeDiscretization::areStrictlyCompatibleForMul(other)) - return false; - const MEDCouplingConstOnTimeInterval *otherC=dynamic_cast(other); - return otherC!=0; -} - -bool MEDCouplingConstOnTimeInterval::areStrictlyCompatibleForDiv(const MEDCouplingTimeDiscretization *other) const -{ - if(!MEDCouplingTimeDiscretization::areStrictlyCompatibleForDiv(other)) - return false; - const MEDCouplingConstOnTimeInterval *otherC=dynamic_cast(other); - return otherC!=0; -} - -bool MEDCouplingConstOnTimeInterval::areCompatibleForMeld(const MEDCouplingTimeDiscretization *other) const -{ - if(!MEDCouplingTimeDiscretization::areCompatibleForMeld(other)) - return false; - const MEDCouplingConstOnTimeInterval *otherC=dynamic_cast(other); - return otherC!=0; -} - -bool MEDCouplingConstOnTimeInterval::isEqualIfNotWhy(const MEDCouplingTimeDiscretization *other, double prec, std::string& reason) const -{ - const MEDCouplingConstOnTimeInterval *otherC=dynamic_cast(other); - std::ostringstream oss; oss.precision(15); - if(!otherC) - { - reason="This has time discretization CONST_ON_TIME_INTERVAL, other not."; - return false; - } - if(_start_iteration!=otherC->_start_iteration) - { - oss << "start iterations differ. this start iteration=" << _start_iteration << " other start iteration=" << otherC->_start_iteration; - reason=oss.str(); - return false; - } - if(_start_order!=otherC->_start_order) - { - oss << "start orders differ. this start order=" << _start_order << " other start order=" << otherC->_start_order; - reason=oss.str(); - return false; - } - if(std::fabs(_start_time-otherC->_start_time)>_time_tolerance) - { - oss << "start times differ. this start time=" << _start_time << " other start time=" << otherC->_start_time; - reason=oss.str(); - return false; - } - if(_end_iteration!=otherC->_end_iteration) - { - oss << "end iterations differ. this end iteration=" << _end_iteration << " other end iteration=" << otherC->_end_iteration; - reason=oss.str(); - return false; - } - if(_end_order!=otherC->_end_order) - { - oss << "end orders differ. this end order=" << _end_order << " other end order=" << otherC->_end_order; - reason=oss.str(); - return false; - } - if(std::fabs(_end_time-otherC->_end_time)>_time_tolerance) - { - oss << "end times differ. this end time=" << _end_time << " other end time=" << otherC->_end_time; - reason=oss.str(); - return false; - } - return MEDCouplingTimeDiscretization::isEqualIfNotWhy(other,prec,reason); -} - -bool MEDCouplingConstOnTimeInterval::isEqualWithoutConsideringStr(const MEDCouplingTimeDiscretization *other, double prec) const -{ - const MEDCouplingConstOnTimeInterval *otherC=dynamic_cast(other); - if(!otherC) - return false; - if(_start_iteration!=otherC->_start_iteration) - return false; - if(_start_order!=otherC->_start_order) - return false; - if(std::fabs(_start_time-otherC->_start_time)>_time_tolerance) - return false; - if(_end_iteration!=otherC->_end_iteration) - return false; - if(_end_order!=otherC->_end_order) - return false; - if(std::fabs(_end_time-otherC->_end_time)>_time_tolerance) - return false; - return MEDCouplingTimeDiscretization::isEqualWithoutConsideringStr(other,prec); -} - -void MEDCouplingConstOnTimeInterval::getValueOnTime(int eltId, double time, double *value) const -{ - if(time>_start_time-_time_tolerance && time<_end_time+_time_tolerance) - if(_array) - _array->getTuple(eltId,value); - else - throw INTERP_KERNEL::Exception("No array existing."); - else - throw INTERP_KERNEL::Exception(EXCEPTION_MSG); -} - -void MEDCouplingConstOnTimeInterval::getValueOnDiscTime(int eltId, int iteration, int order, double *value) const -{ - if(iteration>=_start_iteration && iteration<=_end_iteration) - if(_array) - _array->getTuple(eltId,value); - else - throw INTERP_KERNEL::Exception("No array existing."); - else - throw INTERP_KERNEL::Exception(EXCEPTION_MSG); -} - -void MEDCouplingConstOnTimeInterval::checkNoTimePresence() const -{ - throw INTERP_KERNEL::Exception("No time specified on a field defined as constant on one time interval"); -} - -void MEDCouplingConstOnTimeInterval::checkTimePresence(double time) const -{ - if(time<_start_time-_time_tolerance || time>_end_time+_time_tolerance) - { - std::ostringstream stream; - stream << "The field is defined between times " << _start_time << " and " << _end_time << " worderh tolerance "; - stream << _time_tolerance << " and trying to access on time = " << time; - throw INTERP_KERNEL::Exception(stream.str().c_str()); - } -} - -MEDCouplingTimeDiscretization *MEDCouplingConstOnTimeInterval::aggregate(const MEDCouplingTimeDiscretization *other) const -{ - const MEDCouplingConstOnTimeInterval *otherC=dynamic_cast(other); - if(!otherC) - throw INTERP_KERNEL::Exception("ConstOnTimeInterval::aggregation on mismatched time discretization !"); - MEDCouplingAutoRefCountObjectPtr arr=DataArrayDouble::Aggregate(getArray(),other->getArray()); - MEDCouplingConstOnTimeInterval *ret=new MEDCouplingConstOnTimeInterval; - ret->setArray(arr,0); - return ret; -} - -MEDCouplingTimeDiscretization *MEDCouplingConstOnTimeInterval::aggregate(const std::vector& other) const -{ - std::vector a(other.size()); - int i=0; - for(std::vector::const_iterator it=other.begin();it!=other.end();it++,i++) - { - const MEDCouplingConstOnTimeInterval *itC=dynamic_cast(*it); - if(!itC) - throw INTERP_KERNEL::Exception("ConstOnTimeInterval::aggregate on mismatched time discretization !"); - a[i]=itC->getArray(); - } - MEDCouplingAutoRefCountObjectPtr arr=DataArrayDouble::Aggregate(a); - MEDCouplingConstOnTimeInterval *ret=new MEDCouplingConstOnTimeInterval; - ret->setArray(arr,0); - return ret; -} - -MEDCouplingTimeDiscretization *MEDCouplingConstOnTimeInterval::meld(const MEDCouplingTimeDiscretization *other) const -{ - const MEDCouplingConstOnTimeInterval *otherC=dynamic_cast(other); - if(!otherC) - throw INTERP_KERNEL::Exception("ConstOnTimeInterval::meld on mismatched time discretization !"); - MEDCouplingAutoRefCountObjectPtr arr=DataArrayDouble::Meld(getArray(),other->getArray()); - MEDCouplingConstOnTimeInterval *ret=new MEDCouplingConstOnTimeInterval; - ret->setTimeTolerance(getTimeTolerance()); - ret->setArray(arr,0); - return ret; -} - -MEDCouplingTimeDiscretization *MEDCouplingConstOnTimeInterval::dot(const MEDCouplingTimeDiscretization *other) const -{ - const MEDCouplingConstOnTimeInterval *otherC=dynamic_cast(other); - if(!otherC) - throw INTERP_KERNEL::Exception("ConstOnTimeInterval::dot on mismatched time discretization !"); - MEDCouplingAutoRefCountObjectPtr arr=DataArrayDouble::Dot(getArray(),other->getArray()); - MEDCouplingConstOnTimeInterval *ret=new MEDCouplingConstOnTimeInterval; - ret->setArray(arr,0); - return ret; -} - -MEDCouplingTimeDiscretization *MEDCouplingConstOnTimeInterval::crossProduct(const MEDCouplingTimeDiscretization *other) const -{ - const MEDCouplingConstOnTimeInterval *otherC=dynamic_cast(other); - if(!otherC) - throw INTERP_KERNEL::Exception("ConstOnTimeInterval::crossProduct on mismatched time discretization !"); - MEDCouplingAutoRefCountObjectPtr arr=DataArrayDouble::CrossProduct(getArray(),other->getArray()); - MEDCouplingConstOnTimeInterval *ret=new MEDCouplingConstOnTimeInterval; - ret->setArray(arr,0); - return ret; -} - -MEDCouplingTimeDiscretization *MEDCouplingConstOnTimeInterval::max(const MEDCouplingTimeDiscretization *other) const -{ - const MEDCouplingConstOnTimeInterval *otherC=dynamic_cast(other); - if(!otherC) - throw INTERP_KERNEL::Exception("ConstOnTimeInterval::max on mismatched time discretization !"); - MEDCouplingAutoRefCountObjectPtr arr=DataArrayDouble::Max(getArray(),other->getArray()); - MEDCouplingConstOnTimeInterval *ret=new MEDCouplingConstOnTimeInterval; - ret->setArray(arr,0); - return ret; -} - -MEDCouplingTimeDiscretization *MEDCouplingConstOnTimeInterval::min(const MEDCouplingTimeDiscretization *other) const -{ - const MEDCouplingConstOnTimeInterval *otherC=dynamic_cast(other); - if(!otherC) - throw INTERP_KERNEL::Exception("ConstOnTimeInterval::min on mismatched time discretization !"); - MEDCouplingAutoRefCountObjectPtr arr=DataArrayDouble::Min(getArray(),other->getArray()); - MEDCouplingConstOnTimeInterval *ret=new MEDCouplingConstOnTimeInterval; - ret->setArray(arr,0); - return ret; -} - -MEDCouplingTimeDiscretization *MEDCouplingConstOnTimeInterval::add(const MEDCouplingTimeDiscretization *other) const -{ - const MEDCouplingConstOnTimeInterval *otherC=dynamic_cast(other); - if(!otherC) - throw INTERP_KERNEL::Exception("ConstOnTimeInterval::add on mismatched time discretization !"); - MEDCouplingAutoRefCountObjectPtr arr=DataArrayDouble::Add(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::addEqual(const MEDCouplingTimeDiscretization *other) -{ - const MEDCouplingConstOnTimeInterval *otherC=dynamic_cast(other); - if(!otherC) - throw INTERP_KERNEL::Exception("ConstOnTimeInterval::addEqual on mismatched time discretization !"); - if(!getArray()) - throw INTERP_KERNEL::Exception("MEDCouplingConstOnTimeInterval::substractaddEqual : Data Array is NULL !"); - getArray()->addEqual(other->getArray()); -} - -MEDCouplingTimeDiscretization *MEDCouplingConstOnTimeInterval::substract(const MEDCouplingTimeDiscretization *other) const -{ - const MEDCouplingConstOnTimeInterval *otherC=dynamic_cast(other); - if(!otherC) - throw INTERP_KERNEL::Exception("ConstOnTimeInterval::substract on mismatched time discretization !"); - MEDCouplingAutoRefCountObjectPtr arr=DataArrayDouble::Substract(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::substractEqual(const MEDCouplingTimeDiscretization *other) -{ - const MEDCouplingConstOnTimeInterval *otherC=dynamic_cast(other); - if(!otherC) - throw INTERP_KERNEL::Exception("ConstOnTimeInterval::substractEqual on mismatched time discretization !"); - if(!getArray()) - throw INTERP_KERNEL::Exception("MEDCouplingConstOnTimeInterval::substractEqual : Data Array is NULL !"); - getArray()->substractEqual(other->getArray()); -} - -MEDCouplingTimeDiscretization *MEDCouplingConstOnTimeInterval::multiply(const MEDCouplingTimeDiscretization *other) const -{ - const MEDCouplingConstOnTimeInterval *otherC=dynamic_cast(other); - if(!otherC) - throw INTERP_KERNEL::Exception("multiply on mismatched time discretization !"); - MEDCouplingAutoRefCountObjectPtr arr=DataArrayDouble::Multiply(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::multiplyEqual(const MEDCouplingTimeDiscretization *other) -{ - const MEDCouplingConstOnTimeInterval *otherC=dynamic_cast(other); - if(!otherC) - throw INTERP_KERNEL::Exception("ConstOnTimeInterval::multiplyEqual on mismatched time discretization !"); - if(!getArray()) - throw INTERP_KERNEL::Exception("MEDCouplingConstOnTimeInterval::multiplyEqual : Data Array is NULL !"); - getArray()->multiplyEqual(other->getArray()); -} - -MEDCouplingTimeDiscretization *MEDCouplingConstOnTimeInterval::divide(const MEDCouplingTimeDiscretization *other) const -{ - const MEDCouplingConstOnTimeInterval *otherC=dynamic_cast(other); - if(!otherC) - throw INTERP_KERNEL::Exception("divide on mismatched time discretization !"); - MEDCouplingAutoRefCountObjectPtr arr=DataArrayDouble::Divide(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::divideEqual(const MEDCouplingTimeDiscretization *other) -{ - const MEDCouplingConstOnTimeInterval *otherC=dynamic_cast(other); - if(!otherC) - throw INTERP_KERNEL::Exception("ConstOnTimeInterval::divideEqual on mismatched time discretization !"); - if(!getArray()) - throw INTERP_KERNEL::Exception("MEDCouplingConstOnTimeInterval::divideEqual : Data Array is NULL !"); - getArray()->divideEqual(other->getArray()); -} - -MEDCouplingTimeDiscretization *MEDCouplingConstOnTimeInterval::pow(const MEDCouplingTimeDiscretization *other) const -{ - 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) -{ - 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), - _start_order(other._start_order),_end_order(other._end_order) -{ - if(other._end_array) - _end_array=other._end_array->performCpy(deepCpy); - else - _end_array=0; -} - -void MEDCouplingTwoTimeSteps::updateTime() const -{ - MEDCouplingTimeDiscretization::updateTime(); - if(_end_array) - updateTimeWith(*_end_array); -} - -void MEDCouplingTwoTimeSteps::synchronizeTimeWith(const MEDCouplingMesh *mesh) -{ - 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::getHeapMemorySizeWithoutChildren() const -{ - return MEDCouplingTimeDiscretization::getHeapMemorySizeWithoutChildren(); -} - -std::vector MEDCouplingTwoTimeSteps::getDirectChildrenWithNull() const -{ - std::vector ret(MEDCouplingTimeDiscretization::getDirectChildrenWithNull()); - ret.push_back(_end_array); - return ret; -} - -void MEDCouplingTwoTimeSteps::copyTinyAttrFrom(const MEDCouplingTimeDiscretization& other) -{ - MEDCouplingTimeDiscretization::copyTinyAttrFrom(other); - const MEDCouplingTwoTimeSteps *otherC=dynamic_cast(&other); - if(!otherC) - throw INTERP_KERNEL::Exception("MEDCouplingTwoTimeSteps::copyTinyAttrFrom : mismatch of time discretization !"); - _start_time=otherC->_start_time; - _end_time=otherC->_end_time; - _start_iteration=otherC->_start_iteration; - _end_iteration=otherC->_end_iteration; - _start_order=otherC->_start_order; - _end_order=otherC->_end_order; -} - -void MEDCouplingTwoTimeSteps::copyTinyStringsFrom(const MEDCouplingTimeDiscretization& other) -{ - MEDCouplingTimeDiscretization::copyTinyStringsFrom(other); - const MEDCouplingTwoTimeSteps *otherC=dynamic_cast(&other); - if(!otherC) - throw INTERP_KERNEL::Exception("Trying to operate copyTinyStringsFrom on different field type (two times//one time) !"); - if(_end_array && otherC->_end_array) - _end_array->copyStringInfoFrom(*otherC->_end_array); -} - -const DataArrayDouble *MEDCouplingTwoTimeSteps::getEndArray() const -{ - return _end_array; -} - -DataArrayDouble *MEDCouplingTwoTimeSteps::getEndArray() -{ - return _end_array; -} - -void MEDCouplingTwoTimeSteps::checkCoherency() const -{ - MEDCouplingTimeDiscretization::checkCoherency(); - if(!_end_array) - throw INTERP_KERNEL::Exception("No end array specified !"); - if(_array->getNumberOfComponents()!=_end_array->getNumberOfComponents()) - throw INTERP_KERNEL::Exception("The number of components mismatch between the start and the end arrays !"); - if(_array->getNumberOfTuples()!=_end_array->getNumberOfTuples()) - 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 -{ - std::ostringstream oss; - const MEDCouplingTwoTimeSteps *otherC=dynamic_cast(other); - if(!otherC) - { - reason="This has time discretization LINEAR_TIME, other not."; - return false; - } - if(_start_iteration!=otherC->_start_iteration) - { - oss << "start iterations differ. this start iteration=" << _start_iteration << " other start iteration=" << otherC->_start_iteration; - reason=oss.str(); - return false; - } - if(_start_order!=otherC->_start_order) - { - oss << "start orders differ. this start order=" << _start_order << " other start order=" << otherC->_start_order; - reason=oss.str(); - return false; - } - if(std::fabs(_start_time-otherC->_start_time)>_time_tolerance) - { - oss << "start times differ. this start time=" << _start_time << " other start time=" << otherC->_start_time; - reason=oss.str(); - return false; - } - if(_end_iteration!=otherC->_end_iteration) - { - oss << "end iterations differ. this end iteration=" << _end_iteration << " other end iteration=" << otherC->_end_iteration; - reason=oss.str(); - return false; - } - if(_end_order!=otherC->_end_order) - { - oss << "end orders differ. this end order=" << _end_order << " other end order=" << otherC->_end_order; - reason=oss.str(); - return false; - } - if(std::fabs(_end_time-otherC->_end_time)>_time_tolerance) - { - oss << "end times differ. this end time=" << _end_time << " other end time=" << otherC->_end_time; - reason=oss.str(); - return false; - } - if(_end_array!=otherC->_end_array) - if(!_end_array->isEqualIfNotWhy(*otherC->_end_array,prec,reason)) - { - reason.insert(0,"end arrays differ for linear time."); - return false; - } - return MEDCouplingTimeDiscretization::isEqualIfNotWhy(other,prec,reason); -} - -bool MEDCouplingTwoTimeSteps::isEqualWithoutConsideringStr(const MEDCouplingTimeDiscretization *other, double prec) const -{ - const MEDCouplingTwoTimeSteps *otherC=dynamic_cast(other); - if(!otherC) - return false; - if(_start_iteration!=otherC->_start_iteration) - return false; - if(_end_iteration!=otherC->_end_iteration) - return false; - if(_start_order!=otherC->_start_order) - return false; - if(_end_order!=otherC->_end_order) - return false; - if(std::fabs(_start_time-otherC->_start_time)>_time_tolerance) - return false; - if(std::fabs(_end_time-otherC->_end_time)>_time_tolerance) - return false; - if(_end_array!=otherC->_end_array) - if(!_end_array->isEqualWithoutConsideringStr(*otherC->_end_array,prec)) - return false; - return MEDCouplingTimeDiscretization::isEqualWithoutConsideringStr(other,prec); -} - -MEDCouplingTwoTimeSteps::MEDCouplingTwoTimeSteps():_start_time(0.),_end_time(0.),_start_iteration(-1),_end_iteration(-1),_start_order(-1),_end_order(-1),_end_array(0) -{ -} - -MEDCouplingTwoTimeSteps::~MEDCouplingTwoTimeSteps() -{ - if(_end_array) - _end_array->decrRef(); -} - -void MEDCouplingTwoTimeSteps::checkNoTimePresence() const -{ - throw INTERP_KERNEL::Exception("The field presents a time to be specified in every access !"); -} - -void MEDCouplingTwoTimeSteps::checkTimePresence(double time) const -{ - if(time<_start_time-_time_tolerance || time>_end_time+_time_tolerance) - { - std::ostringstream stream; - stream << "The field is defined between times " << _start_time << " and " << _end_time << " worderh tolerance "; - stream << _time_tolerance << " and trying to access on time = " << time; - throw INTERP_KERNEL::Exception(stream.str().c_str()); - } -} - -void MEDCouplingTwoTimeSteps::getArrays(std::vector& arrays) const -{ - arrays.resize(2); - arrays[0]=_array; - arrays[1]=_end_array; -} - -void MEDCouplingTwoTimeSteps::setEndArray(DataArrayDouble *array, TimeLabel *owner) -{ - if(array!=_end_array) - { - if(_end_array) - _end_array->decrRef(); - _end_array=array; - if(_end_array) - _end_array->incrRef(); - if(owner) - owner->declareAsNew(); - } -} - -void MEDCouplingTwoTimeSteps::getTinySerializationIntInformation(std::vector& tinyInfo) const -{ - MEDCouplingTimeDiscretization::getTinySerializationIntInformation(tinyInfo); - tinyInfo.push_back(_start_iteration); - tinyInfo.push_back(_start_order); - tinyInfo.push_back(_end_iteration); - tinyInfo.push_back(_end_order); - if(_end_array) - { - tinyInfo.push_back(_end_array->getNumberOfTuples()); - tinyInfo.push_back(_end_array->getNumberOfComponents()); - } - else - { - tinyInfo.push_back(-1); - tinyInfo.push_back(-1); - } -} - -void MEDCouplingTwoTimeSteps::getTinySerializationDbleInformation(std::vector& tinyInfo) const -{ - MEDCouplingTimeDiscretization::getTinySerializationDbleInformation(tinyInfo); - tinyInfo.push_back(_start_time); - tinyInfo.push_back(_end_time); -} - -void MEDCouplingTwoTimeSteps::getTinySerializationStrInformation(std::vector& tinyInfo) const -{ - int nbOfCompo=_array->getNumberOfComponents(); - for(int i=0;igetInfoOnComponent(i)); - for(int i=0;igetInfoOnComponent(i)); -} - -void MEDCouplingTwoTimeSteps::resizeForUnserialization(const std::vector& tinyInfoI, std::vector& arrays) -{ - arrays.resize(2); - if(_array!=0) - _array->decrRef(); - if(_end_array!=0) - _end_array->decrRef(); - DataArrayDouble *arr=0; - if(tinyInfoI[0]!=-1 && tinyInfoI[1]!=-1) - { - arr=DataArrayDouble::New(); - arr->alloc(tinyInfoI[0],tinyInfoI[1]); - } - _array=arr; - arrays[0]=arr; - arr=0; - if(tinyInfoI[6]!=-1 && tinyInfoI[7]!=-1) - { - arr=DataArrayDouble::New(); - arr->alloc(tinyInfoI[6],tinyInfoI[7]); - } - _end_array=arr; - arrays[1]=arr; -} - -void MEDCouplingTwoTimeSteps::checkForUnserialization(const std::vector& tinyInfoI, const std::vector& arrays) -{ - static const char MSG[]="MEDCouplingTimeDiscretization::checkForUnserialization : arrays in input is expected to have size two !"; - if(arrays.size()!=2) - throw INTERP_KERNEL::Exception(MSG); - if(_array!=0) - _array->decrRef(); - if(_end_array!=0) - _end_array->decrRef(); - _array=0; _end_array=0; - if(tinyInfoI[0]!=-1 && tinyInfoI[1]!=-1) - { - if(!arrays[0]) - throw INTERP_KERNEL::Exception(MSG); - arrays[0]->checkNbOfTuplesAndComp(tinyInfoI[0],tinyInfoI[1],MSG); - _array=arrays[0]; _array->incrRef(); - } - if(tinyInfoI[6]!=-1 && tinyInfoI[7]!=-1) - { - if(!arrays[1]) - throw INTERP_KERNEL::Exception(MSG); - arrays[1]->checkNbOfTuplesAndComp(tinyInfoI[0],tinyInfoI[1],MSG); - _end_array=arrays[1]; _end_array->incrRef(); - } -} - -void MEDCouplingTwoTimeSteps::finishUnserialization(const std::vector& tinyInfoI, const std::vector& tinyInfoD, const std::vector& tinyInfoS) -{ - MEDCouplingTimeDiscretization::finishUnserialization(tinyInfoI,tinyInfoD,tinyInfoS); - _start_time=tinyInfoD[1]; - _end_time=tinyInfoD[2]; - _start_iteration=tinyInfoI[2]; - _start_order=tinyInfoI[3]; - _end_iteration=tinyInfoI[4]; - _end_order=tinyInfoI[5]; -} - -/*! - * idem getTinySerializationIntInformation except that it is for multi field fetch - */ -void MEDCouplingTwoTimeSteps::getTinySerializationIntInformation2(std::vector& tinyInfo) const -{ - tinyInfo.resize(4); - tinyInfo[0]=_start_iteration; - tinyInfo[1]=_start_order; - tinyInfo[2]=_end_iteration; - tinyInfo[3]=_end_order; -} - -/*! - * idem getTinySerializationDbleInformation except that it is for multi field fetch - */ -void MEDCouplingTwoTimeSteps::getTinySerializationDbleInformation2(std::vector& tinyInfo) const -{ - tinyInfo.resize(3); - tinyInfo[0]=_time_tolerance; - tinyInfo[1]=_start_time; - tinyInfo[2]=_end_time; -} - -/*! - * idem finishUnserialization except that it is for multi field fetch - */ -void MEDCouplingTwoTimeSteps::finishUnserialization2(const std::vector& tinyInfoI, const std::vector& tinyInfoD) -{ - _start_iteration=tinyInfoI[0]; - _start_order=tinyInfoI[1]; - _end_iteration=tinyInfoI[2]; - _end_order=tinyInfoI[3]; - _time_tolerance=tinyInfoD[0]; - _start_time=tinyInfoD[1]; - _end_time=tinyInfoD[2]; -} - -std::vector< const DataArrayDouble *> MEDCouplingTwoTimeSteps::getArraysForTime(double time) const -{ - if(time>_start_time-_time_tolerance && time<_end_time+_time_tolerance) - { - std::vector< const DataArrayDouble *> ret(2); - ret[0]=_array; - ret[1]=_end_array; - return ret; - } - else - throw INTERP_KERNEL::Exception(EXCEPTION_MSG); -} - -void MEDCouplingTwoTimeSteps::setArrays(const std::vector& arrays, TimeLabel *owner) -{ - if(arrays.size()!=2) - throw INTERP_KERNEL::Exception("MEDCouplingTwoTimeSteps::setArrays : number of arrays must be two."); - setArray(arrays.front(),owner); - setEndArray(arrays.back(),owner); -} - -MEDCouplingLinearTime::MEDCouplingLinearTime(const MEDCouplingLinearTime& other, bool deepCpy):MEDCouplingTwoTimeSteps(other,deepCpy) -{ -} - -MEDCouplingLinearTime::MEDCouplingLinearTime() -{ -} - -std::string MEDCouplingLinearTime::getStringRepr() const -{ - std::ostringstream stream; - stream << REPR << " Time interval is defined by :\niteration_start=" << _start_iteration << " order_start=" << _start_order << " and time_start=" << _start_time << "\n"; - stream << "iteration_end=" << _end_iteration << " order_end=" << _end_order << " and end_time=" << _end_time << "\n"; - stream << "Time unit is : \"" << _time_unit << "\""; - return stream.str(); -} - -void MEDCouplingLinearTime::checkCoherency() const -{ - MEDCouplingTwoTimeSteps::checkCoherency(); - if(std::fabs(_start_time-_end_time)<_time_tolerance) - throw INTERP_KERNEL::Exception("Start time and end time are equals regarding time tolerance."); -} - -MEDCouplingTimeDiscretization *MEDCouplingLinearTime::performCpy(bool deepCpy) const -{ - return new MEDCouplingLinearTime(*this,deepCpy); -} - -bool MEDCouplingLinearTime::areCompatible(const MEDCouplingTimeDiscretization *other) const -{ - if(!MEDCouplingTimeDiscretization::areCompatible(other)) - return false; - const MEDCouplingLinearTime *otherC=dynamic_cast(other); - if(otherC==0) - return false; - if(_end_array==0 && otherC->_end_array==0) - return true; - if(_end_array==0 || otherC->_end_array==0) - return false; - if(_end_array->getNumberOfComponents()!=otherC->_end_array->getNumberOfComponents()) - return false; - return true; -} - -bool MEDCouplingLinearTime::areStrictlyCompatible(const MEDCouplingTimeDiscretization *other, std::string& reason) const -{ - if(!MEDCouplingTimeDiscretization::areStrictlyCompatible(other,reason)) - return false; - const MEDCouplingLinearTime *otherC=dynamic_cast(other); - bool ret=otherC!=0; - if(!ret) - reason.insert(0,"time discretization of this is LINEAR_TIME, other has a different time discretization."); - return ret; -} - -bool MEDCouplingLinearTime::areStrictlyCompatibleForMul(const MEDCouplingTimeDiscretization *other) const -{ - if(!MEDCouplingTimeDiscretization::areStrictlyCompatibleForMul(other)) - return false; - const MEDCouplingLinearTime *otherC=dynamic_cast(other); - return otherC!=0; -} - -bool MEDCouplingLinearTime::areStrictlyCompatibleForDiv(const MEDCouplingTimeDiscretization *other) const -{ - if(!MEDCouplingTimeDiscretization::areStrictlyCompatibleForDiv(other)) - return false; - const MEDCouplingLinearTime *otherC=dynamic_cast(other); - if(otherC==0) - return false; - if(_end_array==0 && otherC->_end_array==0) - return true; - if(_end_array==0 || otherC->_end_array==0) - return false; - int nbC1=_end_array->getNumberOfComponents(); - int nbC2=otherC->_end_array->getNumberOfComponents(); - if(nbC1!=nbC2 && nbC2!=1) - return false; - return true; -} - -bool MEDCouplingLinearTime::areCompatibleForMeld(const MEDCouplingTimeDiscretization *other) const -{ - if(!MEDCouplingTimeDiscretization::areCompatibleForMeld(other)) - return false; - const MEDCouplingLinearTime *otherC=dynamic_cast(other); - return otherC!=0; -} - -/*! - * 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 -{ - double alpha=(_end_time-time)/(_end_time-_start_time); - std::size_t nbComp=vals.size()/2; - std::transform(vals.begin(),vals.begin()+nbComp,res,std::bind2nd(std::multiplies(),alpha)); - std::vector tmp(nbComp); - std::transform(vals.begin()+nbComp,vals.end(),tmp.begin(),std::bind2nd(std::multiplies(),1-alpha)); - std::transform(tmp.begin(),tmp.end(),res,res,std::plus()); -} - -void MEDCouplingLinearTime::getValueOnTime(int eltId, double time, double *value) const -{ - double alpha=(_end_time-time)/(_end_time-_start_time); - int nbComp; - if(_array) - _array->getTuple(eltId,value); - else - throw INTERP_KERNEL::Exception("No start array existing."); - nbComp=_array->getNumberOfComponents(); - std::transform(value,value+nbComp,value,std::bind2nd(std::multiplies(),alpha)); - std::vector tmp(nbComp); - if(_end_array) - _end_array->getTuple(eltId,&tmp[0]); - else - throw INTERP_KERNEL::Exception("No end array existing."); - std::transform(tmp.begin(),tmp.end(),tmp.begin(),std::bind2nd(std::multiplies(),1-alpha)); - std::transform(tmp.begin(),tmp.end(),value,value,std::plus()); -} - -void MEDCouplingLinearTime::getValueOnDiscTime(int eltId, int iteration, int order, double *value) const -{ - if(iteration==_start_iteration && order==_start_order) - { - if(_array) - _array->getTuple(eltId,value); - else - throw INTERP_KERNEL::Exception("iteration order match with start time but no start array existing."); - } - if(iteration==_end_iteration && order==_end_order) - { - if(_end_array) - _end_array->getTuple(eltId,value); - else - throw INTERP_KERNEL::Exception("iteration order match with end time but no end array existing."); - } - else - throw INTERP_KERNEL::Exception(EXCEPTION_MSG); -} - -MEDCouplingTimeDiscretization *MEDCouplingLinearTime::aggregate(const MEDCouplingTimeDiscretization *other) const -{ - const MEDCouplingLinearTime *otherC=dynamic_cast(other); - if(!otherC) - throw INTERP_KERNEL::Exception("LinearTime::aggregation on mismatched time discretization !"); - MEDCouplingAutoRefCountObjectPtr arr1=DataArrayDouble::Aggregate(getArray(),other->getArray()); - MEDCouplingAutoRefCountObjectPtr arr2=DataArrayDouble::Aggregate(getEndArray(),other->getEndArray()); - MEDCouplingLinearTime *ret=new MEDCouplingLinearTime; - ret->setArray(arr1,0); - ret->setEndArray(arr2,0); - return ret; -} - -MEDCouplingTimeDiscretization *MEDCouplingLinearTime::aggregate(const std::vector& other) const -{ - std::vector a(other.size()); - std::vector b(other.size()); - int i=0; - for(std::vector::const_iterator it=other.begin();it!=other.end();it++,i++) - { - const MEDCouplingLinearTime *itC=dynamic_cast(*it); - if(!itC) - throw INTERP_KERNEL::Exception("MEDCouplingLinearTime::aggregate on mismatched time discretization !"); - a[i]=itC->getArray(); - b[i]=itC->getEndArray(); - } - MEDCouplingAutoRefCountObjectPtr arr=DataArrayDouble::Aggregate(a); - MEDCouplingAutoRefCountObjectPtr arr2=DataArrayDouble::Aggregate(b); - MEDCouplingLinearTime *ret=new MEDCouplingLinearTime; - ret->setArray(arr,0); - ret->setEndArray(arr2,0); - return ret; -} - -MEDCouplingTimeDiscretization *MEDCouplingLinearTime::meld(const MEDCouplingTimeDiscretization *other) const -{ - const MEDCouplingLinearTime *otherC=dynamic_cast(other); - if(!otherC) - throw INTERP_KERNEL::Exception("LinearTime::meld on mismatched time discretization !"); - MEDCouplingAutoRefCountObjectPtr arr1=DataArrayDouble::Meld(getArray(),other->getArray()); - MEDCouplingAutoRefCountObjectPtr arr2=DataArrayDouble::Meld(getEndArray(),other->getEndArray()); - MEDCouplingLinearTime *ret=new MEDCouplingLinearTime; - ret->setTimeTolerance(getTimeTolerance()); - ret->setArray(arr1,0); - ret->setEndArray(arr2,0); - return ret; -} - -MEDCouplingTimeDiscretization *MEDCouplingLinearTime::dot(const MEDCouplingTimeDiscretization *other) const -{ - const MEDCouplingLinearTime *otherC=dynamic_cast(other); - if(!otherC) - throw INTERP_KERNEL::Exception("LinearTime::dot on mismatched time discretization !"); - MEDCouplingAutoRefCountObjectPtr arr1=DataArrayDouble::Dot(getArray(),other->getArray()); - MEDCouplingAutoRefCountObjectPtr arr2=DataArrayDouble::Dot(getEndArray(),other->getEndArray()); - MEDCouplingLinearTime *ret=new MEDCouplingLinearTime; - ret->setArray(arr1,0); - ret->setEndArray(arr2,0); - return ret; -} - -MEDCouplingTimeDiscretization *MEDCouplingLinearTime::crossProduct(const MEDCouplingTimeDiscretization *other) const -{ - const MEDCouplingLinearTime *otherC=dynamic_cast(other); - if(!otherC) - throw INTERP_KERNEL::Exception("LinearTime::crossProduct on mismatched time discretization !"); - MEDCouplingAutoRefCountObjectPtr arr1=DataArrayDouble::CrossProduct(getArray(),other->getArray()); - MEDCouplingAutoRefCountObjectPtr arr2=DataArrayDouble::CrossProduct(getEndArray(),other->getEndArray()); - MEDCouplingLinearTime *ret=new MEDCouplingLinearTime; - ret->setArray(arr1,0); - ret->setEndArray(arr2,0); - return ret; -} - -MEDCouplingTimeDiscretization *MEDCouplingLinearTime::max(const MEDCouplingTimeDiscretization *other) const -{ - const MEDCouplingLinearTime *otherC=dynamic_cast(other); - if(!otherC) - throw INTERP_KERNEL::Exception("LinearTime::max on mismatched time discretization !"); - MEDCouplingLinearTime *ret=new MEDCouplingLinearTime; - MEDCouplingAutoRefCountObjectPtr arr1=DataArrayDouble::Max(getArray(),other->getArray()); - MEDCouplingAutoRefCountObjectPtr arr2=DataArrayDouble::Max(getEndArray(),other->getEndArray()); - ret->setArray(arr1,0); - ret->setEndArray(arr2,0); - return ret; -} - -MEDCouplingTimeDiscretization *MEDCouplingLinearTime::min(const MEDCouplingTimeDiscretization *other) const -{ - const MEDCouplingLinearTime *otherC=dynamic_cast(other); - if(!otherC) - throw INTERP_KERNEL::Exception("LinearTime::min on mismatched time discretization !"); - MEDCouplingAutoRefCountObjectPtr arr1=DataArrayDouble::Min(getArray(),other->getArray()); - MEDCouplingAutoRefCountObjectPtr arr2=DataArrayDouble::Min(getEndArray(),other->getEndArray()); - MEDCouplingLinearTime *ret=new MEDCouplingLinearTime; - ret->setArray(arr1,0); - ret->setEndArray(arr2,0); - return ret; -} - -MEDCouplingTimeDiscretization *MEDCouplingLinearTime::add(const MEDCouplingTimeDiscretization *other) const -{ - const MEDCouplingLinearTime *otherC=dynamic_cast(other); - if(!otherC) - throw INTERP_KERNEL::Exception("LinearTime::add on mismatched time discretization !"); - MEDCouplingAutoRefCountObjectPtr arr1=DataArrayDouble::Add(getArray(),other->getArray()); - MEDCouplingAutoRefCountObjectPtr arr2=DataArrayDouble::Add(getEndArray(),other->getEndArray()); - MEDCouplingLinearTime *ret=new MEDCouplingLinearTime; - ret->setArray(arr1,0); - ret->setEndArray(arr2,0); - return ret; -} - -void MEDCouplingLinearTime::addEqual(const MEDCouplingTimeDiscretization *other) -{ - 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::addEqual : Data Array is NULL !"); - if(!getEndArray()) - throw INTERP_KERNEL::Exception("MEDCouplingLinearTime::addEqual : Data Array (end) is NULL !"); - getArray()->addEqual(other->getArray()); - getEndArray()->addEqual(other->getEndArray()); -} - -MEDCouplingTimeDiscretization *MEDCouplingLinearTime::substract(const MEDCouplingTimeDiscretization *other) const -{ - const MEDCouplingLinearTime *otherC=dynamic_cast(other); - if(!otherC) - throw INTERP_KERNEL::Exception("LinearTime::substract on mismatched time discretization !"); - MEDCouplingAutoRefCountObjectPtr arr1=DataArrayDouble::Substract(getArray(),other->getArray()); - MEDCouplingAutoRefCountObjectPtr arr2=DataArrayDouble::Substract(getEndArray(),other->getEndArray()); - MEDCouplingLinearTime *ret=new MEDCouplingLinearTime; - ret->setArray(arr1,0); - ret->setEndArray(arr2,0); - return ret; -} - -void MEDCouplingLinearTime::substractEqual(const MEDCouplingTimeDiscretization *other) -{ - 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::substractEqual : Data Array is NULL !"); - if(!getEndArray()) - throw INTERP_KERNEL::Exception("MEDCouplingLinearTime::substractEqual : Data Array (end) is NULL !"); - getArray()->substractEqual(other->getArray()); - getEndArray()->substractEqual(other->getEndArray()); -} - -MEDCouplingTimeDiscretization *MEDCouplingLinearTime::multiply(const MEDCouplingTimeDiscretization *other) const -{ - const MEDCouplingLinearTime *otherC=dynamic_cast(other); - if(!otherC) - throw INTERP_KERNEL::Exception("LinearTime::multiply on mismatched time discretization !"); - MEDCouplingAutoRefCountObjectPtr arr1=DataArrayDouble::Multiply(getArray(),other->getArray()); - MEDCouplingAutoRefCountObjectPtr arr2=DataArrayDouble::Multiply(getEndArray(),other->getEndArray()); - MEDCouplingLinearTime *ret=new MEDCouplingLinearTime; - ret->setArray(arr1,0); - ret->setEndArray(arr2,0); - return ret; -} - -void MEDCouplingLinearTime::multiplyEqual(const MEDCouplingTimeDiscretization *other) -{ - 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::multiplyEqual : Data Array is NULL !"); - if(!getEndArray()) - throw INTERP_KERNEL::Exception("MEDCouplingLinearTime::multiplyEqual : Data Array (end) is NULL !"); - getArray()->multiplyEqual(other->getArray()); - getEndArray()->multiplyEqual(other->getEndArray()); -} - -MEDCouplingTimeDiscretization *MEDCouplingLinearTime::divide(const MEDCouplingTimeDiscretization *other) const -{ - const MEDCouplingLinearTime *otherC=dynamic_cast(other); - if(!otherC) - throw INTERP_KERNEL::Exception("LinearTime::divide on mismatched time discretization !"); - MEDCouplingAutoRefCountObjectPtr arr1=DataArrayDouble::Divide(getArray(),other->getArray()); - MEDCouplingAutoRefCountObjectPtr arr2=DataArrayDouble::Divide(getEndArray(),other->getEndArray()); - MEDCouplingLinearTime *ret=new MEDCouplingLinearTime; - ret->setArray(arr1,0); - ret->setEndArray(arr2,0); - return ret; -} - -void MEDCouplingLinearTime::divideEqual(const MEDCouplingTimeDiscretization *other) -{ - 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::divideEqual : Data Array is NULL !"); - if(!getEndArray()) - throw INTERP_KERNEL::Exception("MEDCouplingLinearTime::divideEqual : Data Array (end) is NULL !"); - getArray()->divideEqual(other->getArray()); - getEndArray()->divideEqual(other->getEndArray()); -} - -MEDCouplingTimeDiscretization *MEDCouplingLinearTime::pow(const MEDCouplingTimeDiscretization *other) const -{ - 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) -{ - 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 deleted file mode 100644 index 3bf7b82ad..000000000 --- a/src/MEDCoupling/MEDCouplingTimeDiscretization.hxx +++ /dev/null @@ -1,460 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 -// 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_MEDCOUPLINGTIMEDISCRETIZATION_HXX__ -#define __PARAMEDMEM_MEDCOUPLINGTIMEDISCRETIZATION_HXX__ - -#include "MEDCoupling.hxx" -#include "MEDCouplingTimeLabel.hxx" -#include "MEDCouplingRefCountObject.hxx" -#include "InterpKernelException.hxx" - -#include - -namespace ParaMEDMEM -{ - class MEDCouplingMesh; - class DataArrayDouble; - class TimeLabel; - - class MEDCouplingTimeDiscretization : public TimeLabel, public BigMemoryObject - { - protected: - MEDCOUPLING_EXPORT MEDCouplingTimeDiscretization(); - MEDCOUPLING_EXPORT MEDCouplingTimeDiscretization(const MEDCouplingTimeDiscretization& other, bool deepCpy); - public: - MEDCOUPLING_EXPORT void updateTime() const; - MEDCOUPLING_EXPORT virtual std::size_t getHeapMemorySizeWithoutChildren() const; - MEDCOUPLING_EXPORT virtual std::vector getDirectChildrenWithNull() const; - MEDCOUPLING_EXPORT static MEDCouplingTimeDiscretization *New(TypeOfTimeDiscretization type); - MEDCOUPLING_EXPORT void setTimeUnit(const std::string& unit) { _time_unit=unit; } - MEDCOUPLING_EXPORT std::string getTimeUnit() const { return _time_unit; } - MEDCOUPLING_EXPORT virtual void copyTinyAttrFrom(const MEDCouplingTimeDiscretization& other); - MEDCOUPLING_EXPORT virtual void copyTinyStringsFrom(const MEDCouplingTimeDiscretization& other); - MEDCOUPLING_EXPORT virtual void checkCoherency() const; - MEDCOUPLING_EXPORT virtual bool areCompatible(const MEDCouplingTimeDiscretization *other) const; - MEDCOUPLING_EXPORT virtual bool areStrictlyCompatible(const MEDCouplingTimeDiscretization *other, std::string& reason) const; - MEDCOUPLING_EXPORT virtual bool areStrictlyCompatibleForMul(const MEDCouplingTimeDiscretization *other) const; - MEDCOUPLING_EXPORT virtual bool areStrictlyCompatibleForDiv(const MEDCouplingTimeDiscretization *other) const; - MEDCOUPLING_EXPORT virtual bool areCompatibleForMeld(const MEDCouplingTimeDiscretization *other) const; - MEDCOUPLING_EXPORT virtual bool isEqualIfNotWhy(const MEDCouplingTimeDiscretization *other, double prec, std::string& reason) const; - MEDCOUPLING_EXPORT virtual bool isEqual(const MEDCouplingTimeDiscretization *other, double prec) const; - MEDCOUPLING_EXPORT virtual bool isEqualWithoutConsideringStr(const MEDCouplingTimeDiscretization *other, double prec) const; - MEDCOUPLING_EXPORT virtual MEDCouplingTimeDiscretization *buildNewTimeReprFromThis(TypeOfTimeDiscretization type, bool deepCpy) const; - MEDCOUPLING_EXPORT virtual std::string getStringRepr() const = 0; - MEDCOUPLING_EXPORT virtual TypeOfTimeDiscretization getEnum() const = 0; - MEDCOUPLING_EXPORT virtual void synchronizeTimeWith(const MEDCouplingMesh *mesh) = 0; - MEDCOUPLING_EXPORT virtual MEDCouplingTimeDiscretization *aggregate(const MEDCouplingTimeDiscretization *other) const = 0; - MEDCOUPLING_EXPORT virtual MEDCouplingTimeDiscretization *aggregate(const std::vector& other) const = 0; - MEDCOUPLING_EXPORT virtual MEDCouplingTimeDiscretization *meld(const MEDCouplingTimeDiscretization *other) const = 0; - MEDCOUPLING_EXPORT virtual MEDCouplingTimeDiscretization *dot(const MEDCouplingTimeDiscretization *other) const = 0; - MEDCOUPLING_EXPORT virtual MEDCouplingTimeDiscretization *crossProduct(const MEDCouplingTimeDiscretization *other) const = 0; - MEDCOUPLING_EXPORT virtual MEDCouplingTimeDiscretization *max(const MEDCouplingTimeDiscretization *other) const = 0; - MEDCOUPLING_EXPORT virtual MEDCouplingTimeDiscretization *min(const MEDCouplingTimeDiscretization *other) const = 0; - MEDCOUPLING_EXPORT virtual MEDCouplingTimeDiscretization *add(const MEDCouplingTimeDiscretization *other) const = 0; - MEDCOUPLING_EXPORT virtual void addEqual(const MEDCouplingTimeDiscretization *other) = 0; - MEDCOUPLING_EXPORT virtual MEDCouplingTimeDiscretization *substract(const MEDCouplingTimeDiscretization *other) const = 0; - MEDCOUPLING_EXPORT virtual void substractEqual(const MEDCouplingTimeDiscretization *other) = 0; - MEDCOUPLING_EXPORT virtual MEDCouplingTimeDiscretization *multiply(const MEDCouplingTimeDiscretization *other) const = 0; - MEDCOUPLING_EXPORT virtual void multiplyEqual(const MEDCouplingTimeDiscretization *other) = 0; - MEDCOUPLING_EXPORT virtual MEDCouplingTimeDiscretization *divide(const MEDCouplingTimeDiscretization *other) const = 0; - MEDCOUPLING_EXPORT virtual void divideEqual(const MEDCouplingTimeDiscretization *other) = 0; - MEDCOUPLING_EXPORT virtual MEDCouplingTimeDiscretization *pow(const MEDCouplingTimeDiscretization *other) const = 0; - MEDCOUPLING_EXPORT virtual void powEqual(const MEDCouplingTimeDiscretization *other) = 0; - MEDCOUPLING_EXPORT virtual void getTinySerializationIntInformation(std::vector& tinyInfo) const; - MEDCOUPLING_EXPORT virtual void getTinySerializationDbleInformation(std::vector& tinyInfo) const; - MEDCOUPLING_EXPORT virtual void getTinySerializationStrInformation(std::vector& tinyInfo) const; - MEDCOUPLING_EXPORT virtual void resizeForUnserialization(const std::vector& tinyInfoI, std::vector& arrays); - MEDCOUPLING_EXPORT virtual void checkForUnserialization(const std::vector& tinyInfoI, const std::vector& arrays); - MEDCOUPLING_EXPORT virtual void finishUnserialization(const std::vector& tinyInfoI, const std::vector& tinyInfoD, const std::vector& tinyInfoS); - MEDCOUPLING_EXPORT virtual void getTinySerializationIntInformation2(std::vector& tinyInfo) const = 0; - MEDCOUPLING_EXPORT virtual void getTinySerializationDbleInformation2(std::vector& tinyInfo) const = 0; - MEDCOUPLING_EXPORT virtual void finishUnserialization2(const std::vector& tinyInfoI, const std::vector& tinyInfoD) = 0; - MEDCOUPLING_EXPORT virtual MEDCouplingTimeDiscretization *performCpy(bool deepCpy) const = 0; - MEDCOUPLING_EXPORT void setTimeTolerance(double val) { _time_tolerance=val; } - MEDCOUPLING_EXPORT double getTimeTolerance() const { return _time_tolerance; } - MEDCOUPLING_EXPORT virtual void checkNoTimePresence() const = 0; - MEDCOUPLING_EXPORT virtual void checkTimePresence(double time) const = 0; - MEDCOUPLING_EXPORT virtual void setArray(DataArrayDouble *array, TimeLabel *owner); - MEDCOUPLING_EXPORT virtual void setEndArray(DataArrayDouble *array, TimeLabel *owner); - MEDCOUPLING_EXPORT virtual void setArrays(const std::vector& arrays, TimeLabel *owner); - MEDCOUPLING_EXPORT DataArrayDouble *getArray() { return _array; } - MEDCOUPLING_EXPORT const DataArrayDouble *getArray() const { return _array; } - MEDCOUPLING_EXPORT virtual const DataArrayDouble *getEndArray() const; - MEDCOUPLING_EXPORT virtual DataArrayDouble *getEndArray(); - MEDCOUPLING_EXPORT virtual std::vector< const DataArrayDouble *> getArraysForTime(double time) const = 0; - MEDCOUPLING_EXPORT virtual void getValueForTime(double time, const std::vector& vals, double *res) const = 0; - MEDCOUPLING_EXPORT virtual void getArrays(std::vector& arrays) const; - MEDCOUPLING_EXPORT virtual bool isBefore(const MEDCouplingTimeDiscretization *other) const; - MEDCOUPLING_EXPORT virtual bool isStrictlyBefore(const MEDCouplingTimeDiscretization *other) const; - MEDCOUPLING_EXPORT double getTime(int& iteration, int& order) const { return getStartTime(iteration,order); } - MEDCOUPLING_EXPORT virtual double getStartTime(int& iteration, int& order) const = 0; - MEDCOUPLING_EXPORT virtual double getEndTime(int& iteration, int& order) const = 0; - MEDCOUPLING_EXPORT void setTime(double time, int iteration, int order) { setStartTime(time,iteration,order); } - MEDCOUPLING_EXPORT void setIteration(int it) { setStartIteration(it); } - MEDCOUPLING_EXPORT void setOrder(int order) { setStartOrder(order); } - MEDCOUPLING_EXPORT void setTimeValue(double val) { setStartTimeValue(val); } - MEDCOUPLING_EXPORT virtual void setStartIteration(int it) = 0; - MEDCOUPLING_EXPORT virtual void setEndIteration(int it) = 0; - MEDCOUPLING_EXPORT virtual void setStartOrder(int order) = 0; - MEDCOUPLING_EXPORT virtual void setEndOrder(int order) = 0; - MEDCOUPLING_EXPORT virtual void setStartTimeValue(double time) = 0; - MEDCOUPLING_EXPORT virtual void setEndTimeValue(double time) = 0; - MEDCOUPLING_EXPORT virtual void setStartTime(double time, int iteration, int order) = 0; - MEDCOUPLING_EXPORT virtual void setEndTime(double time, int iteration, int order) = 0; - MEDCOUPLING_EXPORT virtual void getValueOnTime(int eltId, double time, double *value) const = 0; - MEDCOUPLING_EXPORT virtual void getValueOnDiscTime(int eltId, int iteration, int order, double *value) const = 0; - // - MEDCOUPLING_EXPORT virtual MEDCouplingTimeDiscretization *doublyContractedProduct() const; - MEDCOUPLING_EXPORT virtual MEDCouplingTimeDiscretization *determinant() const; - MEDCOUPLING_EXPORT virtual MEDCouplingTimeDiscretization *eigenValues() const; - MEDCOUPLING_EXPORT virtual MEDCouplingTimeDiscretization *eigenVectors() const; - MEDCOUPLING_EXPORT virtual MEDCouplingTimeDiscretization *inverse() const; - MEDCOUPLING_EXPORT virtual MEDCouplingTimeDiscretization *trace() const; - MEDCOUPLING_EXPORT virtual MEDCouplingTimeDiscretization *deviator() const; - MEDCOUPLING_EXPORT virtual MEDCouplingTimeDiscretization *magnitude() const; - MEDCOUPLING_EXPORT virtual MEDCouplingTimeDiscretization *negate() const; - MEDCOUPLING_EXPORT virtual MEDCouplingTimeDiscretization *maxPerTuple() const; - MEDCOUPLING_EXPORT virtual MEDCouplingTimeDiscretization *keepSelectedComponents(const std::vector& compoIds) const; - MEDCOUPLING_EXPORT virtual void setSelectedComponents(const MEDCouplingTimeDiscretization *other, const std::vector& compoIds); - MEDCOUPLING_EXPORT virtual void changeNbOfComponents(int newNbOfComp, double dftValue); - MEDCOUPLING_EXPORT virtual void sortPerTuple(bool asc); - MEDCOUPLING_EXPORT virtual void setUniformValue(int nbOfTuple, int nbOfCompo, double value); - MEDCOUPLING_EXPORT virtual void setOrCreateUniformValueOnAllComponents(int nbOfTuple, double value); - MEDCOUPLING_EXPORT virtual void applyLin(double a, double b, int compoId); - MEDCOUPLING_EXPORT virtual void applyLin(double a, double b); - MEDCOUPLING_EXPORT virtual void applyFunc(int nbOfComp, FunctionToEvaluate func); - MEDCOUPLING_EXPORT virtual void applyFunc(int nbOfComp, const std::string& func); - MEDCOUPLING_EXPORT virtual void applyFunc2(int nbOfComp, const std::string& func); - MEDCOUPLING_EXPORT virtual void applyFunc3(int nbOfComp, const std::vector& varsOrder, const std::string& func); - MEDCOUPLING_EXPORT virtual void applyFunc(const std::string& func); - MEDCOUPLING_EXPORT virtual void applyFuncFast32(const std::string& func); - MEDCOUPLING_EXPORT virtual void applyFuncFast64(const std::string& func); - MEDCOUPLING_EXPORT virtual void fillFromAnalytic(const DataArrayDouble *loc, int nbOfComp, FunctionToEvaluate func); - MEDCOUPLING_EXPORT virtual void fillFromAnalytic(const DataArrayDouble *loc, int nbOfComp, const std::string& func); - MEDCOUPLING_EXPORT virtual void fillFromAnalytic2(const DataArrayDouble *loc, int nbOfComp, const std::string& func); - MEDCOUPLING_EXPORT virtual void fillFromAnalytic3(const DataArrayDouble *loc, int nbOfComp, const std::vector& varsOrder, const std::string& func); - // - MEDCOUPLING_EXPORT virtual ~MEDCouplingTimeDiscretization(); - protected: - std::string _time_unit; - double _time_tolerance; - DataArrayDouble *_array; - protected: - static const double TIME_TOLERANCE_DFT; - }; - - class MEDCouplingNoTimeLabel : public MEDCouplingTimeDiscretization - { - public: - MEDCOUPLING_EXPORT MEDCouplingNoTimeLabel(); - MEDCOUPLING_EXPORT MEDCouplingNoTimeLabel(const MEDCouplingTimeDiscretization& other, bool deepCpy); - MEDCOUPLING_EXPORT std::string getStringRepr() const; - MEDCOUPLING_EXPORT TypeOfTimeDiscretization getEnum() const { return DISCRETIZATION; } - MEDCOUPLING_EXPORT void synchronizeTimeWith(const MEDCouplingMesh *mesh); - MEDCOUPLING_EXPORT MEDCouplingTimeDiscretization *aggregate(const MEDCouplingTimeDiscretization *other) const; - MEDCOUPLING_EXPORT MEDCouplingTimeDiscretization *aggregate(const std::vector& other) const; - MEDCOUPLING_EXPORT MEDCouplingTimeDiscretization *meld(const MEDCouplingTimeDiscretization *other) const; - MEDCOUPLING_EXPORT MEDCouplingTimeDiscretization *dot(const MEDCouplingTimeDiscretization *other) const; - MEDCOUPLING_EXPORT MEDCouplingTimeDiscretization *crossProduct(const MEDCouplingTimeDiscretization *other) const; - MEDCOUPLING_EXPORT MEDCouplingTimeDiscretization *max(const MEDCouplingTimeDiscretization *other) const; - MEDCOUPLING_EXPORT MEDCouplingTimeDiscretization *min(const MEDCouplingTimeDiscretization *other) const; - MEDCOUPLING_EXPORT MEDCouplingTimeDiscretization *add(const MEDCouplingTimeDiscretization *other) const; - MEDCOUPLING_EXPORT void addEqual(const MEDCouplingTimeDiscretization *other); - MEDCOUPLING_EXPORT MEDCouplingTimeDiscretization *substract(const MEDCouplingTimeDiscretization *other) const; - MEDCOUPLING_EXPORT void substractEqual(const MEDCouplingTimeDiscretization *other); - MEDCOUPLING_EXPORT MEDCouplingTimeDiscretization *multiply(const MEDCouplingTimeDiscretization *other) const; - MEDCOUPLING_EXPORT void multiplyEqual(const MEDCouplingTimeDiscretization *other); - MEDCOUPLING_EXPORT MEDCouplingTimeDiscretization *divide(const MEDCouplingTimeDiscretization *other) const; - MEDCOUPLING_EXPORT void divideEqual(const MEDCouplingTimeDiscretization *other); - MEDCOUPLING_EXPORT MEDCouplingTimeDiscretization *pow(const MEDCouplingTimeDiscretization *other) const; - MEDCOUPLING_EXPORT void powEqual(const MEDCouplingTimeDiscretization *other); - MEDCOUPLING_EXPORT bool isEqualIfNotWhy(const MEDCouplingTimeDiscretization *other, double prec, std::string& reason) const; - MEDCOUPLING_EXPORT bool isEqualWithoutConsideringStr(const MEDCouplingTimeDiscretization *other, double prec) const; - MEDCOUPLING_EXPORT bool areCompatible(const MEDCouplingTimeDiscretization *other) const; - MEDCOUPLING_EXPORT bool areStrictlyCompatible(const MEDCouplingTimeDiscretization *other, std::string& reason) const; - MEDCOUPLING_EXPORT bool areStrictlyCompatibleForMul(const MEDCouplingTimeDiscretization *other) const; - MEDCOUPLING_EXPORT bool areStrictlyCompatibleForDiv(const MEDCouplingTimeDiscretization *other) const; - MEDCOUPLING_EXPORT bool areCompatibleForMeld(const MEDCouplingTimeDiscretization *other) const; - MEDCOUPLING_EXPORT MEDCouplingTimeDiscretization *performCpy(bool deepCpy) const; - MEDCOUPLING_EXPORT void checkNoTimePresence() const { } - MEDCOUPLING_EXPORT void checkTimePresence(double time) const; - MEDCOUPLING_EXPORT std::vector< const DataArrayDouble *> getArraysForTime(double time) const; - MEDCOUPLING_EXPORT void getValueForTime(double time, const std::vector& vals, double *res) const; - MEDCOUPLING_EXPORT bool isBefore(const MEDCouplingTimeDiscretization *other) const; - MEDCOUPLING_EXPORT bool isStrictlyBefore(const MEDCouplingTimeDiscretization *other) const; - MEDCOUPLING_EXPORT double getStartTime(int& iteration, int& order) const; - MEDCOUPLING_EXPORT double getEndTime(int& iteration, int& order) const; - MEDCOUPLING_EXPORT void setStartIteration(int it); - MEDCOUPLING_EXPORT void setEndIteration(int it); - MEDCOUPLING_EXPORT void setStartOrder(int order); - MEDCOUPLING_EXPORT void setEndOrder(int order); - MEDCOUPLING_EXPORT void setStartTimeValue(double time); - MEDCOUPLING_EXPORT void setEndTimeValue(double time); - MEDCOUPLING_EXPORT void setStartTime(double time, int iteration, int order); - MEDCOUPLING_EXPORT void setEndTime(double time, int iteration, int order); - MEDCOUPLING_EXPORT void getValueOnTime(int eltId, double time, double *value) const; - MEDCOUPLING_EXPORT void getValueOnDiscTime(int eltId, int iteration, int order, double *value) const; - MEDCOUPLING_EXPORT void getTinySerializationIntInformation2(std::vector& tinyInfo) const; - MEDCOUPLING_EXPORT void getTinySerializationDbleInformation2(std::vector& tinyInfo) const; - MEDCOUPLING_EXPORT void finishUnserialization2(const std::vector& tinyInfoI, const std::vector& tinyInfoD); - public: - static const TypeOfTimeDiscretization DISCRETIZATION=NO_TIME; - MEDCOUPLING_EXPORT static const char REPR[]; - private: - static const char EXCEPTION_MSG[]; - }; - - class MEDCouplingWithTimeStep : public MEDCouplingTimeDiscretization - { - protected: - MEDCOUPLING_EXPORT MEDCouplingWithTimeStep(const MEDCouplingWithTimeStep& other, bool deepCpy); - public: - MEDCOUPLING_EXPORT MEDCouplingWithTimeStep(); - MEDCOUPLING_EXPORT std::string getStringRepr() const; - MEDCOUPLING_EXPORT void copyTinyAttrFrom(const MEDCouplingTimeDiscretization& other); - MEDCOUPLING_EXPORT TypeOfTimeDiscretization getEnum() const { return DISCRETIZATION; } - MEDCOUPLING_EXPORT void synchronizeTimeWith(const MEDCouplingMesh *mesh); - MEDCOUPLING_EXPORT MEDCouplingTimeDiscretization *aggregate(const MEDCouplingTimeDiscretization *other) const; - MEDCOUPLING_EXPORT MEDCouplingTimeDiscretization *aggregate(const std::vector& other) const; - MEDCOUPLING_EXPORT MEDCouplingTimeDiscretization *meld(const MEDCouplingTimeDiscretization *other) const; - MEDCOUPLING_EXPORT MEDCouplingTimeDiscretization *dot(const MEDCouplingTimeDiscretization *other) const; - MEDCOUPLING_EXPORT MEDCouplingTimeDiscretization *crossProduct(const MEDCouplingTimeDiscretization *other) const; - MEDCOUPLING_EXPORT MEDCouplingTimeDiscretization *max(const MEDCouplingTimeDiscretization *other) const; - MEDCOUPLING_EXPORT MEDCouplingTimeDiscretization *min(const MEDCouplingTimeDiscretization *other) const; - MEDCOUPLING_EXPORT MEDCouplingTimeDiscretization *add(const MEDCouplingTimeDiscretization *other) const; - MEDCOUPLING_EXPORT void addEqual(const MEDCouplingTimeDiscretization *other); - MEDCOUPLING_EXPORT MEDCouplingTimeDiscretization *substract(const MEDCouplingTimeDiscretization *other) const; - MEDCOUPLING_EXPORT void substractEqual(const MEDCouplingTimeDiscretization *other); - MEDCOUPLING_EXPORT MEDCouplingTimeDiscretization *multiply(const MEDCouplingTimeDiscretization *other) const; - MEDCOUPLING_EXPORT void multiplyEqual(const MEDCouplingTimeDiscretization *other); - MEDCOUPLING_EXPORT MEDCouplingTimeDiscretization *divide(const MEDCouplingTimeDiscretization *other) const; - MEDCOUPLING_EXPORT void divideEqual(const MEDCouplingTimeDiscretization *other); - MEDCOUPLING_EXPORT MEDCouplingTimeDiscretization *pow(const MEDCouplingTimeDiscretization *other) const; - MEDCOUPLING_EXPORT void powEqual(const MEDCouplingTimeDiscretization *other); - MEDCOUPLING_EXPORT bool isEqualIfNotWhy(const MEDCouplingTimeDiscretization *other, double prec, std::string& reason) const; - MEDCOUPLING_EXPORT bool isEqualWithoutConsideringStr(const MEDCouplingTimeDiscretization *other, double prec) const; - MEDCOUPLING_EXPORT bool areCompatible(const MEDCouplingTimeDiscretization *other) const; - MEDCOUPLING_EXPORT bool areStrictlyCompatible(const MEDCouplingTimeDiscretization *other, std::string& reason) const; - MEDCOUPLING_EXPORT bool areStrictlyCompatibleForMul(const MEDCouplingTimeDiscretization *other) const; - MEDCOUPLING_EXPORT bool areStrictlyCompatibleForDiv(const MEDCouplingTimeDiscretization *other) const; - MEDCOUPLING_EXPORT bool areCompatibleForMeld(const MEDCouplingTimeDiscretization *other) const; - MEDCOUPLING_EXPORT void getTinySerializationIntInformation(std::vector& tinyInfo) const; - MEDCOUPLING_EXPORT void getTinySerializationDbleInformation(std::vector& tinyInfo) const; - MEDCOUPLING_EXPORT void finishUnserialization(const std::vector& tinyInfoI, const std::vector& tinyInfoD, const std::vector& tinyInfoS); - MEDCOUPLING_EXPORT void getTinySerializationIntInformation2(std::vector& tinyInfo) const; - MEDCOUPLING_EXPORT void getTinySerializationDbleInformation2(std::vector& tinyInfo) const; - MEDCOUPLING_EXPORT void finishUnserialization2(const std::vector& tinyInfoI, const std::vector& tinyInfoD); - MEDCOUPLING_EXPORT MEDCouplingTimeDiscretization *performCpy(bool deepCpy) const; - MEDCOUPLING_EXPORT void checkNoTimePresence() const; - MEDCOUPLING_EXPORT void checkTimePresence(double time) const; - MEDCOUPLING_EXPORT void setStartTime(double time, int iteration, int order) { _time=time; _iteration=iteration; _order=order; } - MEDCOUPLING_EXPORT void setEndTime(double time, int iteration, int order) { _time=time; _iteration=iteration; _order=order; } - MEDCOUPLING_EXPORT double getStartTime(int& iteration, int& order) const { iteration=_iteration; order=_order; return _time; } - MEDCOUPLING_EXPORT double getEndTime(int& iteration, int& order) const { iteration=_iteration; order=_order; return _time; } - MEDCOUPLING_EXPORT void setStartIteration(int it) { _iteration=it; } - MEDCOUPLING_EXPORT void setEndIteration(int it) { _iteration=it; } - MEDCOUPLING_EXPORT void setStartOrder(int order) { _order=order; } - MEDCOUPLING_EXPORT void setEndOrder(int order) { _order=order; } - MEDCOUPLING_EXPORT void setStartTimeValue(double time) { _time=time; } - MEDCOUPLING_EXPORT void setEndTimeValue(double time) { _time=time; } - MEDCOUPLING_EXPORT std::vector< const DataArrayDouble *> getArraysForTime(double time) const; - MEDCOUPLING_EXPORT void getValueForTime(double time, const std::vector& vals, double *res) const; - MEDCOUPLING_EXPORT void getValueOnTime(int eltId, double time, double *value) const; - MEDCOUPLING_EXPORT void getValueOnDiscTime(int eltId, int iteration, int order, double *value) const; - public: - static const TypeOfTimeDiscretization DISCRETIZATION=ONE_TIME; - MEDCOUPLING_EXPORT static const char REPR[]; - private: - static const char EXCEPTION_MSG[]; - protected: - double _time; - int _iteration; - int _order; - }; - - class MEDCouplingConstOnTimeInterval : public MEDCouplingTimeDiscretization - { - protected: - MEDCOUPLING_EXPORT MEDCouplingConstOnTimeInterval(const MEDCouplingConstOnTimeInterval& other, bool deepCpy); - public: - MEDCOUPLING_EXPORT MEDCouplingConstOnTimeInterval(); - MEDCOUPLING_EXPORT void copyTinyAttrFrom(const MEDCouplingTimeDiscretization& other); - MEDCOUPLING_EXPORT void getTinySerializationIntInformation(std::vector& tinyInfo) const; - MEDCOUPLING_EXPORT void getTinySerializationDbleInformation(std::vector& tinyInfo) const; - MEDCOUPLING_EXPORT void finishUnserialization(const std::vector& tinyInfoI, const std::vector& tinyInfoD, const std::vector& tinyInfoS); - MEDCOUPLING_EXPORT void getTinySerializationIntInformation2(std::vector& tinyInfo) const; - MEDCOUPLING_EXPORT void getTinySerializationDbleInformation2(std::vector& tinyInfo) const; - MEDCOUPLING_EXPORT void finishUnserialization2(const std::vector& tinyInfoI, const std::vector& tinyInfoD); - MEDCOUPLING_EXPORT MEDCouplingTimeDiscretization *performCpy(bool deepCpy) const; - MEDCOUPLING_EXPORT bool areCompatible(const MEDCouplingTimeDiscretization *other) const; - MEDCOUPLING_EXPORT bool areStrictlyCompatible(const MEDCouplingTimeDiscretization *other, std::string& reason) const; - MEDCOUPLING_EXPORT bool areStrictlyCompatibleForMul(const MEDCouplingTimeDiscretization *other) const; - MEDCOUPLING_EXPORT bool areStrictlyCompatibleForDiv(const MEDCouplingTimeDiscretization *other) const; - MEDCOUPLING_EXPORT bool areCompatibleForMeld(const MEDCouplingTimeDiscretization *other) const; - MEDCOUPLING_EXPORT bool isEqualIfNotWhy(const MEDCouplingTimeDiscretization *other, double prec, std::string& reason) const; - MEDCOUPLING_EXPORT bool isEqualWithoutConsideringStr(const MEDCouplingTimeDiscretization *other, double prec) const; - MEDCOUPLING_EXPORT std::vector< const DataArrayDouble *> getArraysForTime(double time) const; - MEDCOUPLING_EXPORT void getValueForTime(double time, const std::vector& vals, double *res) const; - MEDCOUPLING_EXPORT void getValueOnTime(int eltId, double time, double *value) const; - MEDCOUPLING_EXPORT void getValueOnDiscTime(int eltId, int iteration, int order, double *value) const; - MEDCOUPLING_EXPORT TypeOfTimeDiscretization getEnum() const { return DISCRETIZATION; } - MEDCOUPLING_EXPORT void synchronizeTimeWith(const MEDCouplingMesh *mesh); - MEDCOUPLING_EXPORT std::string getStringRepr() const; - MEDCOUPLING_EXPORT MEDCouplingTimeDiscretization *aggregate(const MEDCouplingTimeDiscretization *other) const; - MEDCOUPLING_EXPORT MEDCouplingTimeDiscretization *aggregate(const std::vector& other) const; - MEDCOUPLING_EXPORT MEDCouplingTimeDiscretization *meld(const MEDCouplingTimeDiscretization *other) const; - MEDCOUPLING_EXPORT MEDCouplingTimeDiscretization *dot(const MEDCouplingTimeDiscretization *other) const; - MEDCOUPLING_EXPORT MEDCouplingTimeDiscretization *crossProduct(const MEDCouplingTimeDiscretization *other) const; - MEDCOUPLING_EXPORT MEDCouplingTimeDiscretization *max(const MEDCouplingTimeDiscretization *other) const; - MEDCOUPLING_EXPORT MEDCouplingTimeDiscretization *min(const MEDCouplingTimeDiscretization *other) const; - MEDCOUPLING_EXPORT MEDCouplingTimeDiscretization *add(const MEDCouplingTimeDiscretization *other) const; - MEDCOUPLING_EXPORT void addEqual(const MEDCouplingTimeDiscretization *other); - MEDCOUPLING_EXPORT MEDCouplingTimeDiscretization *substract(const MEDCouplingTimeDiscretization *other) const; - MEDCOUPLING_EXPORT void substractEqual(const MEDCouplingTimeDiscretization *other); - MEDCOUPLING_EXPORT MEDCouplingTimeDiscretization *multiply(const MEDCouplingTimeDiscretization *other) const; - MEDCOUPLING_EXPORT void multiplyEqual(const MEDCouplingTimeDiscretization *other); - MEDCOUPLING_EXPORT MEDCouplingTimeDiscretization *divide(const MEDCouplingTimeDiscretization *other) const; - MEDCOUPLING_EXPORT void divideEqual(const MEDCouplingTimeDiscretization *other); - MEDCouplingTimeDiscretization *pow(const MEDCouplingTimeDiscretization *other) const; - MEDCOUPLING_EXPORT void powEqual(const MEDCouplingTimeDiscretization *other); - MEDCOUPLING_EXPORT void setStartTime(double time, int iteration, int order) { _start_time=time; _start_iteration=iteration; _start_order=order; } - MEDCOUPLING_EXPORT void setEndTime(double time, int iteration, int order) { _end_time=time; _end_iteration=iteration; _end_order=order; } - MEDCOUPLING_EXPORT double getStartTime(int& iteration, int& order) const { iteration=_start_iteration; order=_start_order; return _start_time; } - MEDCOUPLING_EXPORT double getEndTime(int& iteration, int& order) const { iteration=_end_iteration; order=_end_order; return _end_time; } - MEDCOUPLING_EXPORT void setStartIteration(int it) { _start_iteration=it; } - MEDCOUPLING_EXPORT void setEndIteration(int it) { _end_iteration=it; } - MEDCOUPLING_EXPORT void setStartOrder(int order) { _start_order=order; } - MEDCOUPLING_EXPORT void setEndOrder(int order) { _end_order=order; } - MEDCOUPLING_EXPORT void setStartTimeValue(double time) { _start_time=time; } - MEDCOUPLING_EXPORT void setEndTimeValue(double time) { _end_time=time; } - MEDCOUPLING_EXPORT void checkNoTimePresence() const; - MEDCOUPLING_EXPORT void checkTimePresence(double time) const; - public: - static const TypeOfTimeDiscretization DISCRETIZATION=CONST_ON_TIME_INTERVAL; - MEDCOUPLING_EXPORT static const char REPR[]; - private: - static const char EXCEPTION_MSG[]; - protected: - double _start_time; - double _end_time; - int _start_iteration; - int _end_iteration; - int _start_order; - int _end_order; - }; - - class MEDCouplingTwoTimeSteps : public MEDCouplingTimeDiscretization - { - protected: - MEDCOUPLING_EXPORT MEDCouplingTwoTimeSteps(const MEDCouplingTwoTimeSteps& other, bool deepCpy); - MEDCOUPLING_EXPORT MEDCouplingTwoTimeSteps(); - MEDCOUPLING_EXPORT ~MEDCouplingTwoTimeSteps(); - public: - MEDCOUPLING_EXPORT void updateTime() const; - MEDCOUPLING_EXPORT void synchronizeTimeWith(const MEDCouplingMesh *mesh); - MEDCOUPLING_EXPORT std::size_t getHeapMemorySizeWithoutChildren() const; - MEDCOUPLING_EXPORT std::vector getDirectChildrenWithNull() const; - MEDCOUPLING_EXPORT void copyTinyAttrFrom(const MEDCouplingTimeDiscretization& other); - MEDCOUPLING_EXPORT void copyTinyStringsFrom(const MEDCouplingTimeDiscretization& other); - MEDCOUPLING_EXPORT const DataArrayDouble *getEndArray() const; - MEDCOUPLING_EXPORT DataArrayDouble *getEndArray(); - MEDCOUPLING_EXPORT void checkCoherency() const; - MEDCOUPLING_EXPORT bool isEqualIfNotWhy(const MEDCouplingTimeDiscretization *other, double prec, std::string& reason) const; - MEDCOUPLING_EXPORT bool isEqualWithoutConsideringStr(const MEDCouplingTimeDiscretization *other, double prec) const; - MEDCOUPLING_EXPORT void checkNoTimePresence() const; - MEDCOUPLING_EXPORT void checkTimePresence(double time) const; - MEDCOUPLING_EXPORT void getArrays(std::vector& arrays) const; - MEDCOUPLING_EXPORT void setEndArray(DataArrayDouble *array, TimeLabel *owner); - MEDCOUPLING_EXPORT void setStartTime(double time, int iteration, int order) { _start_time=time; _start_iteration=iteration; _start_order=order; } - MEDCOUPLING_EXPORT void setEndTime(double time, int iteration, int order) { _end_time=time; _end_iteration=iteration; _end_order=order; } - MEDCOUPLING_EXPORT double getStartTime(int& iteration, int& order) const { iteration=_start_iteration; order=_start_order; return _start_time; } - MEDCOUPLING_EXPORT double getEndTime(int& iteration, int& order) const { iteration=_end_iteration; order=_end_order; return _end_time; } - MEDCOUPLING_EXPORT void setStartIteration(int it) { _start_iteration=it; } - MEDCOUPLING_EXPORT void setEndIteration(int it) { _end_iteration=it; } - MEDCOUPLING_EXPORT void setStartOrder(int order) { _start_order=order; } - MEDCOUPLING_EXPORT void setEndOrder(int order) { _end_order=order; } - MEDCOUPLING_EXPORT void setStartTimeValue(double time) { _start_time=time; } - MEDCOUPLING_EXPORT void setEndTimeValue(double time) { _end_time=time; } - MEDCOUPLING_EXPORT void getTinySerializationIntInformation(std::vector& tinyInfo) const; - MEDCOUPLING_EXPORT void getTinySerializationDbleInformation(std::vector& tinyInfo) const; - MEDCOUPLING_EXPORT void getTinySerializationStrInformation(std::vector& tinyInfo) const; - MEDCOUPLING_EXPORT void resizeForUnserialization(const std::vector& tinyInfoI, std::vector& arrays); - MEDCOUPLING_EXPORT void checkForUnserialization(const std::vector& tinyInfoI, const std::vector& arrays); - MEDCOUPLING_EXPORT void finishUnserialization(const std::vector& tinyInfoI, const std::vector& tinyInfoD, const std::vector& tinyInfoS); - MEDCOUPLING_EXPORT void getTinySerializationIntInformation2(std::vector& tinyInfo) const; - MEDCOUPLING_EXPORT void getTinySerializationDbleInformation2(std::vector& tinyInfo) const; - MEDCOUPLING_EXPORT void finishUnserialization2(const std::vector& tinyInfoI, const std::vector& tinyInfoD); - MEDCOUPLING_EXPORT std::vector< const DataArrayDouble *> getArraysForTime(double time) const; - MEDCOUPLING_EXPORT void setArrays(const std::vector& arrays, TimeLabel *owner); - protected: - static const char EXCEPTION_MSG[]; - protected: - double _start_time; - double _end_time; - int _start_iteration; - int _end_iteration; - int _start_order; - int _end_order; - DataArrayDouble *_end_array; - }; - - class MEDCouplingLinearTime : public MEDCouplingTwoTimeSteps - { - protected: - MEDCOUPLING_EXPORT MEDCouplingLinearTime(const MEDCouplingLinearTime& other, bool deepCpy); - public: - MEDCOUPLING_EXPORT MEDCouplingLinearTime(); - MEDCOUPLING_EXPORT std::string getStringRepr() const; - MEDCOUPLING_EXPORT TypeOfTimeDiscretization getEnum() const { return DISCRETIZATION; } - MEDCOUPLING_EXPORT void checkCoherency() const; - MEDCOUPLING_EXPORT MEDCouplingTimeDiscretization *performCpy(bool deepCpy) const; - MEDCOUPLING_EXPORT bool areCompatible(const MEDCouplingTimeDiscretization *other) const; - MEDCOUPLING_EXPORT bool areStrictlyCompatible(const MEDCouplingTimeDiscretization *other, std::string& reason) const; - MEDCOUPLING_EXPORT bool areStrictlyCompatibleForMul(const MEDCouplingTimeDiscretization *other) const; - MEDCOUPLING_EXPORT bool areStrictlyCompatibleForDiv(const MEDCouplingTimeDiscretization *other) const; - MEDCOUPLING_EXPORT bool areCompatibleForMeld(const MEDCouplingTimeDiscretization *other) const; - MEDCOUPLING_EXPORT void getValueForTime(double time, const std::vector& vals, double *res) const; - MEDCOUPLING_EXPORT void getValueOnTime(int eltId, double time, double *value) const; - MEDCOUPLING_EXPORT void getValueOnDiscTime(int eltId, int iteration, int order, double *value) const; - MEDCOUPLING_EXPORT MEDCouplingTimeDiscretization *aggregate(const MEDCouplingTimeDiscretization *other) const; - MEDCOUPLING_EXPORT MEDCouplingTimeDiscretization *aggregate(const std::vector& other) const; - MEDCOUPLING_EXPORT MEDCouplingTimeDiscretization *meld(const MEDCouplingTimeDiscretization *other) const; - MEDCOUPLING_EXPORT MEDCouplingTimeDiscretization *dot(const MEDCouplingTimeDiscretization *other) const; - MEDCOUPLING_EXPORT MEDCouplingTimeDiscretization *crossProduct(const MEDCouplingTimeDiscretization *other) const; - MEDCOUPLING_EXPORT MEDCouplingTimeDiscretization *max(const MEDCouplingTimeDiscretization *other) const; - MEDCOUPLING_EXPORT MEDCouplingTimeDiscretization *min(const MEDCouplingTimeDiscretization *other) const; - MEDCOUPLING_EXPORT MEDCouplingTimeDiscretization *add(const MEDCouplingTimeDiscretization *other) const; - MEDCOUPLING_EXPORT void addEqual(const MEDCouplingTimeDiscretization *other); - MEDCOUPLING_EXPORT MEDCouplingTimeDiscretization *substract(const MEDCouplingTimeDiscretization *other) const; - MEDCOUPLING_EXPORT void substractEqual(const MEDCouplingTimeDiscretization *other); - MEDCOUPLING_EXPORT MEDCouplingTimeDiscretization *multiply(const MEDCouplingTimeDiscretization *other) const; - MEDCOUPLING_EXPORT void multiplyEqual(const MEDCouplingTimeDiscretization *other); - MEDCOUPLING_EXPORT MEDCouplingTimeDiscretization *divide(const MEDCouplingTimeDiscretization *other) const; - MEDCOUPLING_EXPORT void divideEqual(const MEDCouplingTimeDiscretization *other); - MEDCOUPLING_EXPORT MEDCouplingTimeDiscretization *pow(const MEDCouplingTimeDiscretization *other) const; - MEDCOUPLING_EXPORT void powEqual(const MEDCouplingTimeDiscretization *other); - public: - static const TypeOfTimeDiscretization DISCRETIZATION=LINEAR_TIME; - MEDCOUPLING_EXPORT static const char REPR[]; - }; -} - -#endif diff --git a/src/MEDCoupling/MEDCouplingTimeLabel.cxx b/src/MEDCoupling/MEDCouplingTimeLabel.cxx deleted file mode 100644 index 4bb3671f7..000000000 --- a/src/MEDCoupling/MEDCouplingTimeLabel.cxx +++ /dev/null @@ -1,112 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 -// 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 "MEDCouplingTimeLabel.hxx" - -#include "InterpKernelException.hxx" - -#include - -using namespace ParaMEDMEM; - -std::size_t TimeLabel::GLOBAL_TIME=0; - -TimeLabel::TimeLabel():_time(GLOBAL_TIME++) -{ -} - -TimeLabel::~TimeLabel() -{ -} - -TimeLabel& TimeLabel::operator=(const TimeLabel& other) -{ - _time=GLOBAL_TIME++; - return *this; -} - -void TimeLabel::declareAsNew() const -{ - _time=GLOBAL_TIME++; -} - -void TimeLabel::updateTimeWith(const TimeLabel& other) const -{ - if(_time::max()) -{ - if(!_tl) - throw INTERP_KERNEL::Exception("TimeLabelConstOverseer constructor : input instance must be not NULL !"); - _tl->updateTime(); - _ref_time=tl->getTimeOfThis(); -} - -/*! - * This method checks that the tracked instance is not NULL and if not NULL that its internal state has not changed. - */ -void TimeLabelConstOverseer::checkConst() const -{ - if(!_tl) - throw INTERP_KERNEL::Exception("TimeLabelConstOverseer::checkConst : NULL tracked instance !"); - _tl->updateTime(); - if(_ref_time!=_tl->getTimeOfThis()) - throw INTERP_KERNEL::Exception("TimeLabelConstOverseer::checkConst : the state of the controlled instance of TimeLable has changed !"); -} - -bool TimeLabelConstOverseer::resetState() -{ - if(_tl) - { - _tl->updateTime(); - _ref_time=_tl->getTimeOfThis(); - return true; - } - else - return false; -} - -bool TimeLabelConstOverseer::keepTrackOfNewTL(const TimeLabel *tl) -{ - if(_tl==tl) - return false; - _tl=tl; - if(_tl) - { - _tl->updateTime(); - _ref_time=_tl->getTimeOfThis(); - } - else - { - _ref_time=std::numeric_limits::max(); - } - return true; -} diff --git a/src/MEDCoupling/MEDCouplingTimeLabel.hxx b/src/MEDCoupling/MEDCouplingTimeLabel.hxx deleted file mode 100644 index 2ab528aad..000000000 --- a/src/MEDCoupling/MEDCouplingTimeLabel.hxx +++ /dev/null @@ -1,66 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 -// 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_TIMELABEL_HXX__ -#define __PARAMEDMEM_TIMELABEL_HXX__ - -#include "MEDCoupling.hxx" - -#include - -namespace ParaMEDMEM -{ - /*! - * Class representing a label of time of the lastely modified part of this. - * More _time is high more the object has been modified recently. - */ - class TimeLabel - { - public: - MEDCOUPLING_EXPORT TimeLabel& operator=(const TimeLabel& other); - //! This method should be called when write access has been done on this. - MEDCOUPLING_EXPORT void declareAsNew() const; - //! This method should be called on high level classes as Field or Mesh to take into acount modifications done in aggregates objects. - MEDCOUPLING_EXPORT virtual void updateTime() const = 0; - MEDCOUPLING_EXPORT std::size_t getTimeOfThis() const { return _time; } - protected: - MEDCOUPLING_EXPORT TimeLabel(); - MEDCOUPLING_EXPORT virtual ~TimeLabel(); - MEDCOUPLING_EXPORT void updateTimeWith(const TimeLabel& other) const; - MEDCOUPLING_EXPORT void forceTimeOfThis(const TimeLabel& other) const; - private: - static std::size_t GLOBAL_TIME; - mutable std::size_t _time; - }; - - class TimeLabelConstOverseer - { - public: - MEDCOUPLING_EXPORT TimeLabelConstOverseer(const TimeLabel *tl); - MEDCOUPLING_EXPORT void checkConst() const; - MEDCOUPLING_EXPORT bool resetState(); - MEDCOUPLING_EXPORT bool keepTrackOfNewTL(const TimeLabel *tl); - private: - const TimeLabel *_tl; - std::size_t _ref_time; - }; -} - -#endif diff --git a/src/MEDCoupling/MEDCouplingUMesh.cxx b/src/MEDCoupling/MEDCouplingUMesh.cxx deleted file mode 100644 index d50bf73c2..000000000 --- a/src/MEDCoupling/MEDCouplingUMesh.cxx +++ /dev/null @@ -1,11916 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 -// 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 "MEDCouplingUMesh.hxx" -#include "MEDCoupling1GTUMesh.hxx" -#include "MEDCouplingMemArray.txx" -#include "MEDCouplingFieldDouble.hxx" -#include "MEDCouplingSkyLineArray.hxx" -#include "CellModel.hxx" -#include "VolSurfUser.txx" -#include "InterpolationUtils.hxx" -#include "PointLocatorAlgos.txx" -#include "BBTree.txx" -#include "BBTreeDst.txx" -#include "SplitterTetra.hxx" -#include "DiameterCalculator.hxx" -#include "DirectedBoundingBox.hxx" -#include "InterpKernelMatrixTools.hxx" -#include "InterpKernelMeshQuality.hxx" -#include "InterpKernelCellSimplify.hxx" -#include "InterpKernelGeo2DEdgeArcCircle.hxx" -#include "InterpKernelAutoPtr.hxx" -#include "InterpKernelGeo2DNode.hxx" -#include "InterpKernelGeo2DEdgeLin.hxx" -#include "InterpKernelGeo2DEdgeArcCircle.hxx" -#include "InterpKernelGeo2DQuadraticPolygon.hxx" - -#include -#include -#include -#include -#include -#include - -using namespace ParaMEDMEM; - -double MEDCouplingUMesh::EPS_FOR_POLYH_ORIENTATION=1.e-14; - -const INTERP_KERNEL::NormalizedCellType MEDCouplingUMesh::MEDMEM_ORDER[N_MEDMEM_ORDER] = { INTERP_KERNEL::NORM_POINT1, INTERP_KERNEL::NORM_SEG2, INTERP_KERNEL::NORM_SEG3, INTERP_KERNEL::NORM_SEG4, INTERP_KERNEL::NORM_POLYL, INTERP_KERNEL::NORM_TRI3, INTERP_KERNEL::NORM_QUAD4, INTERP_KERNEL::NORM_TRI6, INTERP_KERNEL::NORM_TRI7, INTERP_KERNEL::NORM_QUAD8, INTERP_KERNEL::NORM_QUAD9, INTERP_KERNEL::NORM_POLYGON, INTERP_KERNEL::NORM_QPOLYG, INTERP_KERNEL::NORM_TETRA4, INTERP_KERNEL::NORM_PYRA5, INTERP_KERNEL::NORM_PENTA6, INTERP_KERNEL::NORM_HEXA8, INTERP_KERNEL::NORM_HEXGP12, INTERP_KERNEL::NORM_TETRA10, INTERP_KERNEL::NORM_PYRA13, INTERP_KERNEL::NORM_PENTA15, INTERP_KERNEL::NORM_HEXA20, INTERP_KERNEL::NORM_HEXA27, INTERP_KERNEL::NORM_POLYHED }; - -MEDCouplingUMesh *MEDCouplingUMesh::New() -{ - return new MEDCouplingUMesh; -} - -MEDCouplingUMesh *MEDCouplingUMesh::New(const std::string& meshName, int meshDim) -{ - MEDCouplingUMesh *ret=new MEDCouplingUMesh; - ret->setName(meshName); - ret->setMeshDimension(meshDim); - return ret; -} - -/*! - * Returns a new MEDCouplingMesh which is a full copy of \a this one. No data is shared - * between \a this and the new mesh. - * \return MEDCouplingMesh * - a new instance of MEDCouplingMesh. The caller is to - * delete this mesh using decrRef() as it is no more needed. - */ -MEDCouplingMesh *MEDCouplingUMesh::deepCpy() const -{ - return clone(true); -} - -/*! - * Returns a new MEDCouplingMesh which is a copy of \a this one. - * \param [in] recDeepCpy - if \a true, the copy is deep, else all data arrays of \a - * this mesh are shared by the new mesh. - * \return MEDCouplingMesh * - a new instance of MEDCouplingMesh. The caller is to - * delete this mesh using decrRef() as it is no more needed. - */ -MEDCouplingUMesh *MEDCouplingUMesh::clone(bool recDeepCpy) const -{ - return new MEDCouplingUMesh(*this,recDeepCpy); -} - -/*! - * This method behaves mostly like MEDCouplingUMesh::deepCpy method, except that only nodal connectivity arrays are deeply copied. - * The coordinates are shared between \a this and the returned instance. - * - * \return MEDCouplingUMesh * - A new object instance holding the copy of \a this (deep for connectivity, shallow for coordiantes) - * \sa MEDCouplingUMesh::deepCpy - */ -MEDCouplingPointSet *MEDCouplingUMesh::deepCpyConnectivityOnly() const -{ - checkConnectivityFullyDefined(); - MEDCouplingAutoRefCountObjectPtr ret=clone(false); - MEDCouplingAutoRefCountObjectPtr c(getNodalConnectivity()->deepCpy()),ci(getNodalConnectivityIndex()->deepCpy()); - ret->setConnectivity(c,ci); - return ret.retn(); -} - -void MEDCouplingUMesh::shallowCopyConnectivityFrom(const MEDCouplingPointSet *other) -{ - if(!other) - throw INTERP_KERNEL::Exception("MEDCouplingUMesh::shallowCopyConnectivityFrom : input pointer is null !"); - const MEDCouplingUMesh *otherC=dynamic_cast(other); - if(!otherC) - throw INTERP_KERNEL::Exception("MEDCouplingUMesh::shallowCopyConnectivityFrom : input pointer is not an MEDCouplingUMesh instance !"); - MEDCouplingUMesh *otherC2=const_cast(otherC);//sorry :( - setConnectivity(otherC2->getNodalConnectivity(),otherC2->getNodalConnectivityIndex(),true); -} - -std::size_t MEDCouplingUMesh::getHeapMemorySizeWithoutChildren() const -{ - std::size_t ret(MEDCouplingPointSet::getHeapMemorySizeWithoutChildren()); - return ret; -} - -std::vector MEDCouplingUMesh::getDirectChildrenWithNull() const -{ - std::vector ret(MEDCouplingPointSet::getDirectChildrenWithNull()); - ret.push_back(_nodal_connec); - ret.push_back(_nodal_connec_index); - return ret; -} - -void MEDCouplingUMesh::updateTime() const -{ - MEDCouplingPointSet::updateTime(); - if(_nodal_connec) - { - updateTimeWith(*_nodal_connec); - } - if(_nodal_connec_index) - { - updateTimeWith(*_nodal_connec_index); - } -} - -MEDCouplingUMesh::MEDCouplingUMesh():_mesh_dim(-2),_nodal_connec(0),_nodal_connec_index(0) -{ -} - -/*! - * 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 -{ - if(_mesh_dim<-1) - 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) - { - std::ostringstream message; - message << "Mesh invalid because dimension is " << _mesh_dim << " and there is presence of cell(s) with type " << (*iter); - throw INTERP_KERNEL::Exception(message.str().c_str()); - } - } - if(_nodal_connec) - { - if(_nodal_connec->getNumberOfComponents()!=1) - throw INTERP_KERNEL::Exception("Nodal connectivity array is expected to be with number of components set to one !"); - if(_nodal_connec->getInfoOnComponent(0)!="") - throw INTERP_KERNEL::Exception("Nodal connectivity array is expected to have no info on its single component !"); - } - else - if(_mesh_dim!=-1) - throw INTERP_KERNEL::Exception("Nodal connectivity array is not defined !"); - if(_nodal_connec_index) - { - if(_nodal_connec_index->getNumberOfComponents()!=1) - throw INTERP_KERNEL::Exception("Nodal connectivity index array is expected to be with number of components set to one !"); - if(_nodal_connec_index->getInfoOnComponent(0)!="") - throw INTERP_KERNEL::Exception("Nodal connectivity index array is expected to have no info on its single component !"); - } - else - if(_mesh_dim!=-1) - throw INTERP_KERNEL::Exception("Nodal connectivity index array is not defined !"); -} - -/*! - * 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 -{ - checkCoherency(); - if(_mesh_dim==-1) - return ; - int meshDim=getMeshDimension(); - int nbOfNodes=getNumberOfNodes(); - int nbOfCells=getNumberOfCells(); - const int *ptr=_nodal_connec->getConstPointer(); - const int *ptrI=_nodal_connec_index->getConstPointer(); - for(int i=0;i=0) - { - if(nodeId>=nbOfNodes) - { - std::ostringstream oss; oss << "Cell #" << i << " is built with node #" << nodeId << " whereas there are only " << nbOfNodes << " nodes in the mesh !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - } - else if(nodeId<-1) - { - std::ostringstream oss; oss << "Cell #" << i << " is built with node #" << nodeId << " in connectivity ! sounds bad !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - else - { - if((INTERP_KERNEL::NormalizedCellType)(ptr[ptrI[i]])!=INTERP_KERNEL::NORM_POLYHED) - { - std::ostringstream oss; oss << "Cell #" << i << " is built with node #-1 in connectivity ! sounds bad !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - } - } - } -} - - -/*! - * 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 -{ - 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 || 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 an estimation of the given number of cells. The closer is the estimation to the number of cells effectively inserted, - * the less will the library need to reallocate memory. If the number of cells to be inserted is not known simply put 0 to this parameter. - * If a nodal connectivity previouly existed before the call of this method, it will be reset. - * - * \param [in] nbOfCells - estimation of the number of cell \a this mesh will contain. - * - * \if ENABLE_EXAMPLES - * \ref medcouplingcppexamplesUmeshStdBuild1 "Here is a C++ example".
- * \ref medcouplingpyexamplesUmeshStdBuild1 "Here is a Python example". - * \endif - */ -void MEDCouplingUMesh::allocateCells(int nbOfCells) -{ - if(nbOfCells<0) - throw INTERP_KERNEL::Exception("MEDCouplingUMesh::allocateCells : the input number of cells should be >= 0 !"); - if(_nodal_connec_index) - { - _nodal_connec_index->decrRef(); - } - if(_nodal_connec) - { - _nodal_connec->decrRef(); - } - _nodal_connec_index=DataArrayInt::New(); - _nodal_connec_index->reserve(nbOfCells+1); - _nodal_connec_index->pushBackSilent(0); - _nodal_connec=DataArrayInt::New(); - _nodal_connec->reserve(2*nbOfCells); - _types.clear(); - declareAsNew(); -} - -/*! - * 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. - * - * \if ENABLE_EXAMPLES - * \ref medcouplingcppexamplesUmeshStdBuild1 "Here is a C++ example".
- * \ref medcouplingpyexamplesUmeshStdBuild1 "Here is a Python example". - * \endif - */ -void MEDCouplingUMesh::insertNextCell(INTERP_KERNEL::NormalizedCellType type, int size, const int *nodalConnOfCell) -{ - const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(type); - if(_nodal_connec_index==0) - throw INTERP_KERNEL::Exception("MEDCouplingUMesh::insertNextCell : nodal connectivity not set ! invoke allocateCells before calling insertNextCell !"); - if((int)cm.getDimension()==_mesh_dim) - { - 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); - } - else - { - std::ostringstream oss; oss << "MEDCouplingUMesh::insertNextCell : cell type " << cm.getRepr() << " has a dimension " << cm.getDimension(); - oss << " whereas Mesh Dimension of current UMesh instance is set to " << _mesh_dim << " ! Please invoke \"setMeshDimension\" method before or invoke "; - oss << "\"MEDCouplingUMesh::New\" static method with 2 parameters name and meshDimension !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } -} - -/*! - * Compacts data arrays to release unused memory. This method is to be called after - * finishing cell insertion using \a this->insertNextCell(). - * - * \if ENABLE_EXAMPLES - * \ref medcouplingcppexamplesUmeshStdBuild1 "Here is a C++ example".
- * \ref medcouplingpyexamplesUmeshStdBuild1 "Here is a Python example". - * \endif - */ -void MEDCouplingUMesh::finishInsertingCells() -{ - _nodal_connec->pack(); - _nodal_connec_index->pack(); - _nodal_connec->declareAsNew(); - _nodal_connec_index->declareAsNew(); - updateTime(); -} - -/*! - * Entry point for iteration over cells of this. Warning the returned cell iterator should be deallocated. - * Useful for python users. - */ -MEDCouplingUMeshCellIterator *MEDCouplingUMesh::cellIterator() -{ - return new MEDCouplingUMeshCellIterator(this); -} - -/*! - * Entry point for iteration over cells groups geo types per geotypes. Warning the returned cell iterator should be deallocated. - * If \a this is not so that that cells are grouped by geo types this method will throw an exception. - * In this case MEDCouplingUMesh::sortCellsInMEDFileFrmt or MEDCouplingUMesh::rearrange2ConsecutiveCellTypes methods for example can be called before invoking this method. - * Useful for python users. - */ -MEDCouplingUMeshCellByTypeEntry *MEDCouplingUMesh::cellsByType() -{ - if(!checkConsecutiveCellTypes()) - throw INTERP_KERNEL::Exception("MEDCouplingUMesh::cellsByType : this mesh is not sorted by type !"); - return new MEDCouplingUMeshCellByTypeEntry(this); -} - -/*! - * Returns a set of all cell types available in \a this mesh. - * \return std::set - the set of cell types. - * \warning this method does not throw any exception even if \a this is not defined. - * \sa MEDCouplingUMesh::getAllGeoTypesSorted - */ -std::set MEDCouplingUMesh::getAllGeoTypes() const -{ - return _types; -} - -/*! - * This method returns the sorted list of geometric types in \a this. - * Sorted means in the same order than the cells in \a this. A single entry in return vector means the maximal chunk of consecutive cells in \a this - * having the same geometric type. So a same geometric type can appear more than once if the cells are not sorted per geometric type. - * - * \throw if connectivity in \a this is not correctly defined. - * - * \sa MEDCouplingMesh::getAllGeoTypes - */ -std::vector MEDCouplingUMesh::getAllGeoTypesSorted() const -{ - std::vector ret; - checkConnectivityFullyDefined(); - int nbOfCells(getNumberOfCells()); - if(nbOfCells==0) - return ret; - if(getMeshLength()<1) - throw INTERP_KERNEL::Exception("MEDCouplingUMesh::getAllGeoTypesSorted : the connectivity in this seems invalid !"); - const int *c(_nodal_connec->begin()),*ci(_nodal_connec_index->begin()); - ret.push_back((INTERP_KERNEL::NormalizedCellType)c[*ci++]); - for(int i=1;i(other); - if(!otherC) - { - reason="mesh given in input is not castable in MEDCouplingUMesh !"; - return false; - } - if(!MEDCouplingPointSet::isEqualIfNotWhy(other,prec,reason)) - return false; - if(_mesh_dim!=otherC->_mesh_dim) - { - oss << "umesh dimension mismatch : this mesh dimension=" << _mesh_dim << " other mesh dimension=" << otherC->_mesh_dim; - reason=oss.str(); - return false; - } - if(_types!=otherC->_types) - { - oss << "umesh geometric type mismatch :\nThis geometric types are :"; - for(std::set::const_iterator iter=_types.begin();iter!=_types.end();iter++) - { const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(*iter); oss << cm.getRepr() << ", "; } - oss << "\nOther geometric types are :"; - for(std::set::const_iterator iter=otherC->_types.begin();iter!=otherC->_types.end();iter++) - { const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(*iter); oss << cm.getRepr() << ", "; } - reason=oss.str(); - return false; - } - if(_nodal_connec!=0 || otherC->_nodal_connec!=0) - if(_nodal_connec==0 || otherC->_nodal_connec==0) - { - reason="Only one UMesh between the two this and other has its nodal connectivity DataArrayInt defined !"; - return false; - } - if(_nodal_connec!=otherC->_nodal_connec) - if(!_nodal_connec->isEqualIfNotWhy(*otherC->_nodal_connec,reason)) - { - reason.insert(0,"Nodal connectivity DataArrayInt differ : "); - return false; - } - if(_nodal_connec_index!=0 || otherC->_nodal_connec_index!=0) - if(_nodal_connec_index==0 || otherC->_nodal_connec_index==0) - { - reason="Only one UMesh between the two this and other has its nodal connectivity index DataArrayInt defined !"; - return false; - } - if(_nodal_connec_index!=otherC->_nodal_connec_index) - if(!_nodal_connec_index->isEqualIfNotWhy(*otherC->_nodal_connec_index,reason)) - { - reason.insert(0,"Nodal connectivity index DataArrayInt differ : "); - return false; - } - 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); - if(!otherC) - return false; - if(!MEDCouplingPointSet::isEqualWithoutConsideringStr(other,prec)) - return false; - if(_mesh_dim!=otherC->_mesh_dim) - return false; - if(_types!=otherC->_types) - return false; - if(_nodal_connec!=0 || otherC->_nodal_connec!=0) - if(_nodal_connec==0 || otherC->_nodal_connec==0) - return false; - if(_nodal_connec!=otherC->_nodal_connec) - if(!_nodal_connec->isEqualWithoutConsideringStr(*otherC->_nodal_connec)) - return false; - if(_nodal_connec_index!=0 || otherC->_nodal_connec_index!=0) - if(_nodal_connec_index==0 || otherC->_nodal_connec_index==0) - return false; - if(_nodal_connec_index!=otherC->_nodal_connec_index) - if(!_nodal_connec_index->isEqualWithoutConsideringStr(*otherC->_nodal_connec_index)) - return false; - return true; -} - -/*! - * 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 -{ - MEDCouplingPointSet::checkFastEquivalWith(other,prec); - const MEDCouplingUMesh *otherC=dynamic_cast(other); - if(!otherC) - throw INTERP_KERNEL::Exception("MEDCouplingUMesh::checkFastEquivalWith : Two meshes are not not unstructured !"); -} - -/*! - * 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. - * - * \if ENABLE_EXAMPLES - * \ref cpp_mcumesh_getReverseNodalConnectivity "Here is a C++ example".
- * \ref py_mcumesh_getReverseNodalConnectivity "Here is a Python example". - * \endif - */ -void MEDCouplingUMesh::getReverseNodalConnectivity(DataArrayInt *revNodal, DataArrayInt *revNodalIndx) const -{ - checkFullyDefined(); - int nbOfNodes=getNumberOfNodes(); - 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(); - int nbOfCells=getNumberOfCells(); - int nbOfEltsInRevNodal=0; - for(int eltId=0;eltId=0)//for polyhedrons - { - nbOfEltsInRevNodal++; - revNodalIndxPtr[(*iter)+1]++; - } - } - std::transform(revNodalIndxPtr+1,revNodalIndxPtr+nbOfNodes+1,revNodalIndxPtr,revNodalIndxPtr+1,std::plus()); - 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;eltId=0)//for polyhedrons - *std::find_if(revNodalPtr+revNodalIndxPtr[*iter],revNodalPtr+revNodalIndxPtr[*iter+1],std::bind2nd(std::equal_to(),-1))=eltId; - } -} - -/// @cond INTERNAL - -int MEDCouplingFastNbrer(int id, unsigned nb, const INTERP_KERNEL::CellModel& cm, bool compute, const int *conn1, const int *conn2) -{ - return id; -} - -int MEDCouplingOrientationSensitiveNbrer(int id, unsigned nb, const INTERP_KERNEL::CellModel& cm, bool compute, const int *conn1, const int *conn2) -{ - if(!compute) - return id+1; - else - { - if(cm.getOrientationStatus(nb,conn1,conn2)) - return id+1; - else - return -(id+1); - } -} - -class MinusOneSonsGenerator -{ -public: - MinusOneSonsGenerator(const INTERP_KERNEL::CellModel& cm):_cm(cm) { } - unsigned getNumberOfSons2(const int *conn, int lgth) const { return _cm.getNumberOfSons2(conn,lgth); } - unsigned fillSonCellNodalConnectivity2(int sonId, const int *nodalConn, int lgth, int *sonNodalConn, INTERP_KERNEL::NormalizedCellType& typeOfSon) const { return _cm.fillSonCellNodalConnectivity2(sonId,nodalConn,lgth,sonNodalConn,typeOfSon); } - static const int DELTA=1; -private: - const INTERP_KERNEL::CellModel& _cm; -}; - -class MinusOneSonsGeneratorBiQuadratic -{ -public: - MinusOneSonsGeneratorBiQuadratic(const INTERP_KERNEL::CellModel& cm):_cm(cm) { } - unsigned getNumberOfSons2(const int *conn, int lgth) const { return _cm.getNumberOfSons2(conn,lgth); } - unsigned fillSonCellNodalConnectivity2(int sonId, const int *nodalConn, int lgth, int *sonNodalConn, INTERP_KERNEL::NormalizedCellType& typeOfSon) const { return _cm.fillSonCellNodalConnectivity4(sonId,nodalConn,lgth,sonNodalConn,typeOfSon); } - static const int DELTA=1; -private: - const INTERP_KERNEL::CellModel& _cm; -}; - -class MinusTwoSonsGenerator -{ -public: - MinusTwoSonsGenerator(const INTERP_KERNEL::CellModel& cm):_cm(cm) { } - unsigned getNumberOfSons2(const int *conn, int lgth) const { return _cm.getNumberOfEdgesIn3D(conn,lgth); } - unsigned fillSonCellNodalConnectivity2(int sonId, const int *nodalConn, int lgth, int *sonNodalConn, INTERP_KERNEL::NormalizedCellType& typeOfSon) const { return _cm.fillSonEdgesNodalConnectivity3D(sonId,nodalConn,lgth,sonNodalConn,typeOfSon); } - static const int DELTA=2; -private: - const INTERP_KERNEL::CellModel& _cm; -}; - -/// @endcond - -/*! - * 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 (\ref numbering-indirect) 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 (\ref numbering-indirect) 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. - * - * \if ENABLE_EXAMPLES - * \ref cpp_mcumesh_buildDescendingConnectivity "Here is a C++ example".
- * \ref py_mcumesh_buildDescendingConnectivity "Here is a Python example". - * \endif - * \sa buildDescendingConnectivity2() - */ -MEDCouplingUMesh *MEDCouplingUMesh::buildDescendingConnectivity(DataArrayInt *desc, DataArrayInt *descIndx, DataArrayInt *revDesc, DataArrayInt *revDescIndx) const -{ - return buildDescendingConnectivityGen(desc,descIndx,revDesc,revDescIndx,MEDCouplingFastNbrer); -} - -/*! - * \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 -{ - 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 (\ref numbering-indirect) 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 (\ref numbering-indirect) 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. - * - * \if ENABLE_EXAMPLES - * \ref cpp_mcumesh_buildDescendingConnectivity2 "Here is a C++ example".
- * \ref py_mcumesh_buildDescendingConnectivity2 "Here is a Python example". - * \endif - * \sa buildDescendingConnectivity() - */ -MEDCouplingUMesh *MEDCouplingUMesh::buildDescendingConnectivity2(DataArrayInt *desc, DataArrayInt *descIndx, DataArrayInt *revDesc, DataArrayInt *revDescIndx) const -{ - return buildDescendingConnectivityGen(desc,descIndx,revDesc,revDescIndx,MEDCouplingOrientationSensitiveNbrer); -} - -/*! - * \b 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 calls - * MEDCouplingUMesh::buildDescendingConnectivity to compute the result. - * This method lists cell by cell in \b this which are its neighbors. To compute the result - * only connectivities are considered. - * The neighbor cells of cell having id 'cellId' are neighbors[neighborsIndx[cellId]:neighborsIndx[cellId+1]]. - * The format of return is hence \ref numbering-indirect. - * - * \param [out] neighbors is an array storing all the neighbors of all cells in \b this. This array is newly - * allocated and should be dealt by the caller. \b neighborsIndx 2nd output - * parameter allows to select the right part in this array (\ref numbering-indirect). The number of tuples - * is equal to the last values in \b neighborsIndx. - * \param [out] neighborsIndx is an array of size this->getNumberOfCells()+1 newly allocated and should be - * dealt by the caller. This arrays allow to use the first output parameter \b neighbors (\ref numbering-indirect). - */ -void MEDCouplingUMesh::computeNeighborsOfCells(DataArrayInt *&neighbors, DataArrayInt *&neighborsIndx) const -{ - MEDCouplingAutoRefCountObjectPtr desc=DataArrayInt::New(); - MEDCouplingAutoRefCountObjectPtr descIndx=DataArrayInt::New(); - MEDCouplingAutoRefCountObjectPtr revDesc=DataArrayInt::New(); - MEDCouplingAutoRefCountObjectPtr revDescIndx=DataArrayInt::New(); - MEDCouplingAutoRefCountObjectPtr meshDM1=buildDescendingConnectivity(desc,descIndx,revDesc,revDescIndx); - meshDM1=0; - ComputeNeighborsOfCellsAdv(desc,descIndx,revDesc,revDescIndx,neighbors,neighborsIndx); -} - -/*! - * This method is called by MEDCouplingUMesh::computeNeighborsOfCells. This methods performs the algorithm - * of MEDCouplingUMesh::computeNeighborsOfCells. - * This method is useful for users that want to reduce along a criterion the set of neighbours cell. This is - * typically the case to extract a set a neighbours, - * excluding a set of meshdim-1 cells in input descending connectivity. - * Typically \b desc, \b descIndx, \b revDesc and \b revDescIndx (\ref numbering-indirect) input params are - * the result of MEDCouplingUMesh::buildDescendingConnectivity. - * This method lists cell by cell in \b this which are its neighbors. To compute the result only connectivities - * are considered. - * The neighbor cells of cell having id 'cellId' are neighbors[neighborsIndx[cellId]:neighborsIndx[cellId+1]]. - * - * \param [in] desc descending connectivity array. - * \param [in] descIndx descending connectivity index array used to walk through \b desc (\ref numbering-indirect). - * \param [in] revDesc reverse descending connectivity array. - * \param [in] revDescIndx reverse descending connectivity index array used to walk through \b revDesc (\ref numbering-indirect). - * \param [out] neighbors is an array storing all the neighbors of all cells in \b this. This array is newly allocated and should be dealt by the caller. \b neighborsIndx 2nd output - * parameter allows to select the right part in this array. The number of tuples is equal to the last values in \b neighborsIndx. - * \param [out] neighborsIndx is an array of size this->getNumberOfCells()+1 newly allocated and should be dealt by the caller. This arrays allow to use the first output parameter \b neighbors. - */ -void MEDCouplingUMesh::ComputeNeighborsOfCellsAdv(const DataArrayInt *desc, const DataArrayInt *descIndx, const DataArrayInt *revDesc, const DataArrayInt *revDescIndx, - DataArrayInt *&neighbors, DataArrayInt *&neighborsIndx) -{ - if(!desc || !descIndx || !revDesc || !revDescIndx) - throw INTERP_KERNEL::Exception("MEDCouplingUMesh::ComputeNeighborsOfCellsAdv some input array is empty !"); - const int *descPtr=desc->getConstPointer(); - const int *descIPtr=descIndx->getConstPointer(); - const int *revDescPtr=revDesc->getConstPointer(); - const int *revDescIPtr=revDescIndx->getConstPointer(); - // - int nbCells=descIndx->getNumberOfTuples()-1; - MEDCouplingAutoRefCountObjectPtr out0=DataArrayInt::New(); - MEDCouplingAutoRefCountObjectPtr out1=DataArrayInt::New(); out1->alloc(nbCells+1,1); - int *out1Ptr=out1->getPointer(); - *out1Ptr++=0; - out0->reserve(desc->getNumberOfTuples()); - for(int i=0;i s(revDescPtr+revDescIPtr[*w1],revDescPtr+revDescIPtr[(*w1)+1]); - s.erase(i); - out0->insertAtTheEnd(s.begin(),s.end()); - } - *out1Ptr=out0->getNumberOfTuples(); - } - neighbors=out0.retn(); - neighborsIndx=out1.retn(); -} - -/*! - * \b 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 calls - * MEDCouplingUMesh::buildDescendingConnectivity to compute the result. - * This method lists node by node in \b this which are its neighbors. To compute the result - * only connectivities are considered. - * The neighbor nodes of node having id 'nodeId' are neighbors[neighborsIndx[cellId]:neighborsIndx[cellId+1]]. - * - * \param [out] neighbors is an array storing all the neighbors of all nodes in \b this. This array - * is newly allocated and should be dealt by the caller. \b neighborsIndx 2nd output - * parameter allows to select the right part in this array (\ref numbering-indirect). - * The number of tuples is equal to the last values in \b neighborsIndx. - * \param [out] neighborsIdx is an array of size this->getNumberOfCells()+1 newly allocated and should - * be dealt by the caller. This arrays allow to use the first output parameter \b neighbors. - */ -void MEDCouplingUMesh::computeNeighborsOfNodes(DataArrayInt *&neighbors, DataArrayInt *&neighborsIdx) const -{ - checkFullyDefined(); - int mdim(getMeshDimension()),nbNodes(getNumberOfNodes()); - MEDCouplingAutoRefCountObjectPtr desc(DataArrayInt::New()),descIndx(DataArrayInt::New()),revDesc(DataArrayInt::New()),revDescIndx(DataArrayInt::New()); - MEDCouplingAutoRefCountObjectPtr mesh1D; - switch(mdim) - { - case 3: - { - mesh1D=explode3DMeshTo1D(desc,descIndx,revDesc,revDescIndx); - break; - } - case 2: - { - mesh1D=buildDescendingConnectivity(desc,descIndx,revDesc,revDescIndx); - break; - } - case 1: - { - mesh1D=const_cast(this); - mesh1D->incrRef(); - break; - } - default: - { - throw INTERP_KERNEL::Exception("MEDCouplingUMesh::computeNeighborsOfNodes : Mesh dimension supported are [3,2,1] !"); - } - } - desc=DataArrayInt::New(); descIndx=DataArrayInt::New(); revDesc=0; revDescIndx=0; - mesh1D->getReverseNodalConnectivity(desc,descIndx); - MEDCouplingAutoRefCountObjectPtr ret0(DataArrayInt::New()); - ret0->alloc(desc->getNumberOfTuples(),1); - int *r0Pt(ret0->getPointer()); - const int *c1DPtr(mesh1D->getNodalConnectivity()->begin()),*rn(desc->begin()),*rni(descIndx->begin()); - for(int i=0;i -MEDCouplingUMesh *MEDCouplingUMesh::buildDescendingConnectivityGen(DataArrayInt *desc, DataArrayInt *descIndx, DataArrayInt *revDesc, DataArrayInt *revDescIndx, DimM1DescNbrer nbrer) const -{ - 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::string name="Mesh constituent of "; name+=getName(); - MEDCouplingAutoRefCountObjectPtr ret=MEDCouplingUMesh::New(name,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=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;ireserve(newNbOfCellsM1); - revDescIndx->alloc(newNbOfCellsM1+1,1); - int *revDescIndxPtr=revDescIndx->getPointer(); *revDescIndxPtr++=0; - const int *revDesc2Ptr=revDesc2->getConstPointer(); - for(int i=0;ipushBackSilent(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++; - } - } - // - return ret2.retn(); -} - -struct MEDCouplingAccVisit -{ - MEDCouplingAccVisit():_new_nb_of_nodes(0) { } - int operator()(int val) { if(val!=-1) return _new_nb_of_nodes++; else return -1; } - int _new_nb_of_nodes; -}; - -/// @endcond - -/*! - * 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. - * - * \if ENABLE_EXAMPLES - * \ref cpp_mcumesh_convertToPolyTypes "Here is a C++ example".
- * \ref py_mcumesh_convertToPolyTypes "Here is a Python example". - * \endif - */ -void MEDCouplingUMesh::convertToPolyTypes(const int *cellIdsToConvertBg, const int *cellIdsToConvertEnd) -{ - checkFullyDefined(); - int dim=getMeshDimension(); - if(dim<2 || dim>3) - throw INTERP_KERNEL::Exception("Invalid mesh dimension : must be 2 or 3 !"); - int nbOfCells(getNumberOfCells()); - if(dim==2) - { - const int *connIndex=_nodal_connec_index->getConstPointer(); - int *conn=_nodal_connec->getPointer(); - for(const int *iter=cellIdsToConvertBg;iter!=cellIdsToConvertEnd;iter++) - { - if(*iter>=0 && *itergetPointer()); - const int *connOld(_nodal_connec->getConstPointer()); - MEDCouplingAutoRefCountObjectPtr connNew(DataArrayInt::New()),connNewI(DataArrayInt::New()); connNew->alloc(0,1); connNewI->alloc(1,1); connNewI->setIJ(0,0,0); - std::vector toBeDone(nbOfCells,false); - for(const int *iter=cellIdsToConvertBg;iter!=cellIdsToConvertEnd;iter++) - { - if(*iter>=0 && *iterpushBackValsSilent(tmp,tmp+newLgth); - connNewI->pushBackSilent(connNewI->back()+(int)newLgth); - delete [] tmp; - } - else - { - connNew->pushBackValsSilent(connOld+pos,connOld+posP1); - connNewI->pushBackSilent(connNewI->back()+posP1-pos); - } - } - setConnectivity(connNew,connNewI,false);//false because computeTypes called just behind. - } - computeTypes(); -} - -/*! - * Converts all cells to either polygons (if \a this is a 2D mesh) or - * polyhedrons (if \a this is a 3D mesh). - * \warning As this method is purely for user-friendliness and no optimization is - * done to avoid construction of a useless vector, this method can be costly - * in memory. - * \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. - */ -void MEDCouplingUMesh::convertAllToPoly() -{ - int nbOfCells=getNumberOfCells(); - std::vector cellIds(nbOfCells); - for(int i=0;i - * This method is useful to build an extruded unstructured mesh with polyhedrons as - * it releases the user from boring description of polyhedra connectivity in the valid - * format. - * \throw If \a this->getMeshDimension() != 3. - * \throw If \a this->getSpaceDimension() != 3. - * \throw If the nodal connectivity of cells is not defined. - * \throw If the coordinates array is not set. - * \throw If \a this mesh contains polyhedrons with the valid connectivity. - * \throw If \a this mesh contains polyhedrons with odd number of nodes. - * - * \if ENABLE_EXAMPLES - * \ref cpp_mcumesh_arePolyhedronsNotCorrectlyOriented "Here is a C++ example".
- * \ref py_mcumesh_arePolyhedronsNotCorrectlyOriented "Here is a Python example". - * \endif - */ -void MEDCouplingUMesh::convertExtrudedPolyhedra() -{ - checkFullyDefined(); - if(getMeshDimension()!=3 || getSpaceDimension()!=3) - throw INTERP_KERNEL::Exception("MEDCouplingUMesh::convertExtrudedPolyhedra works on umeshes with meshdim equal to 3 and spaceDim equal to 3 too!"); - int nbOfCells=getNumberOfCells(); - MEDCouplingAutoRefCountObjectPtr newCi=DataArrayInt::New(); - newCi->alloc(nbOfCells+1,1); - int *newci=newCi->getPointer(); - const int *ci=_nodal_connec_index->getConstPointer(); - const int *c=_nodal_connec->getConstPointer(); - newci[0]=0; - for(int i=0;i newC=DataArrayInt::New(); - newC->alloc(newci[nbOfCells],1); - int *newc=newC->getPointer(); - for(int i=0;idecrRef(); _nodal_connec_index=newCi.retn(); - _nodal_connec->decrRef(); _nodal_connec=newC.retn(); -} - - -/*! - * Converts all polygons (if \a this is a 2D mesh) or polyhedrons (if \a this is a 3D - * mesh) to cells of classical types. This method is opposite to convertToPolyTypes(). - * \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(). - * \return \c true if at least one cell has been converted, \c false else. In the - * last case the nodal connectivity remains unchanged. - * \throw If the coordinates array is not set. - * \throw If the nodal connectivity of cells is not defined. - * \throw If \a this->getMeshDimension() < 0. - */ -bool MEDCouplingUMesh::unPolyze() -{ - checkFullyDefined(); - int mdim=getMeshDimension(); - if(mdim<0) - throw INTERP_KERNEL::Exception("MEDCouplingUMesh::unPolyze works on umeshes with meshdim equals to 0, 1 2 or 3 !"); - if(mdim<=1) - return false; - int nbOfCells=getNumberOfCells(); - if(nbOfCells<1) - return false; - int initMeshLgth=getMeshLength(); - int *conn=_nodal_connec->getPointer(); - int *index=_nodal_connec_index->getPointer(); - int posOfCurCell=0; - int newPos=0; - int lgthOfCurCell; - bool ret=false; - for(int i=0;i tmp=new int[lgthOfCurCell-1]; - std::copy(conn+posOfCurCell+1,conn+posOfCurCell+lgthOfCurCell,(int *)tmp); - newType=INTERP_KERNEL::CellSimplify::tryToUnPoly2D(cm.isQuadratic(),tmp,lgthOfCurCell-1,conn+newPos+1,newLgth); - break; - } - case 3: - { - int nbOfFaces,lgthOfPolyhConn; - INTERP_KERNEL::AutoPtr zipFullReprOfPolyh=INTERP_KERNEL::CellSimplify::getFullPolyh3DCell(type,conn+posOfCurCell+1,lgthOfCurCell-1,nbOfFaces,lgthOfPolyhConn); - newType=INTERP_KERNEL::CellSimplify::tryToUnPoly3D(zipFullReprOfPolyh,nbOfFaces,lgthOfPolyhConn,conn+newPos+1,newLgth); - break; - } - case 1: - { - newType=(lgthOfCurCell==3)?INTERP_KERNEL::NORM_SEG2:INTERP_KERNEL::NORM_POLYL; - break; - } - } - ret=ret || (newType!=type); - conn[newPos]=newType; - newPos+=newLgth+1; - posOfCurCell=index[i+1]; - index[i+1]=newPos; - } - else - { - std::copy(conn+posOfCurCell,conn+posOfCurCell+lgthOfCurCell,conn+newPos); - newPos+=lgthOfCurCell; - posOfCurCell+=lgthOfCurCell; - index[i+1]=newPos; - } - } - if(newPos!=initMeshLgth) - _nodal_connec->reAlloc(newPos); - if(ret) - computeTypes(); - return ret; -} - -/*! - * This method expects that spaceDimension is equal to 3 and meshDimension equal to 3. - * This method performs operation only on polyhedrons in \b this. If no polyhedrons exists in \b this, \b this remains unchanged. - * This method allows to merge if any coplanar 3DSurf cells that may appear in some polyhedrons cells. - * - * \param [in] eps is a relative precision that allows to establish if some 3D plane are coplanar or not. This epsilon is used to recenter around origin to have maximal - * precision. - */ -void MEDCouplingUMesh::simplifyPolyhedra(double eps) -{ - checkFullyDefined(); - if(getMeshDimension()!=3 || getSpaceDimension()!=3) - throw INTERP_KERNEL::Exception("MEDCouplingUMesh::simplifyPolyhedra : works on meshdimension 3 and spaceDimension 3 !"); - MEDCouplingAutoRefCountObjectPtr coords=getCoords()->deepCpy(); - coords->recenterForMaxPrecision(eps); - // - int nbOfCells=getNumberOfCells(); - const int *conn=_nodal_connec->getConstPointer(); - const int *index=_nodal_connec_index->getConstPointer(); - MEDCouplingAutoRefCountObjectPtr connINew=DataArrayInt::New(); - connINew->alloc(nbOfCells+1,1); - int *connINewPtr=connINew->getPointer(); *connINewPtr++=0; - MEDCouplingAutoRefCountObjectPtr connNew=DataArrayInt::New(); connNew->alloc(0,1); - bool changed=false; - for(int i=0;iinsertAtTheEnd(conn+index[i],conn+index[i+1]); - *connINewPtr=connNew->getNumberOfTuples(); - } - if(changed) - setConnectivity(connNew,connINew,false); -} - -/*! - * This method returns all node ids used in the connectivity of \b this. The data array returned has to be dealt by the caller. - * The returned node ids are sorted ascendingly. This method is close to MEDCouplingUMesh::getNodeIdsInUse except - * the format of the returned DataArrayInt instance. - * - * \return a newly allocated DataArrayInt sorted ascendingly of fetched node ids. - * \sa MEDCouplingUMesh::getNodeIdsInUse, areAllNodesFetched - */ -DataArrayInt *MEDCouplingUMesh::computeFetchedNodeIds() const -{ - checkConnectivityFullyDefined(); - int nbOfCells=getNumberOfCells(); - const int *connIndex=_nodal_connec_index->getConstPointer(); - const int *conn=_nodal_connec->getConstPointer(); - const int *maxEltPt=std::max_element(_nodal_connec->begin(),_nodal_connec->end()); - int maxElt=maxEltPt==_nodal_connec->end()?0:std::abs(*maxEltPt)+1; - std::vector retS(maxElt,false); - for(int i=0;i=0) - retS[conn[j]]=true; - int sz=0; - for(int i=0;ialloc(sz,1); - int *retPtr=ret->getPointer(); - for(int i=0;i& nodeIdsInUse) const -{ - int nbOfNodes((int)nodeIdsInUse.size()),nbOfCells(getNumberOfCells()); - const int *connIndex(_nodal_connec_index->getConstPointer()),*conn(_nodal_connec->getConstPointer()); - for(int i=0;i=0) - { - if(conn[j]getNumberOfNodes(). It holds for each node of \a this mesh either -1 - * if the node is unused or a new id else. The caller is to delete this - * array using decrRef() as it is no more needed. - * \throw If the coordinates array is not set. - * \throw If the nodal connectivity of cells is not defined. - * \throw If the nodal connectivity includes an invalid id. - * - * \if ENABLE_EXAMPLES - * \ref cpp_mcumesh_getNodeIdsInUse "Here is a C++ example".
- * \ref py_mcumesh_getNodeIdsInUse "Here is a Python example". - * \endif - * \sa computeFetchedNodeIds, computeNodeIdsAlg() - */ -DataArrayInt *MEDCouplingUMesh::getNodeIdsInUse(int& nbrOfNodesInUse) const -{ - nbrOfNodesInUse=-1; - int nbOfNodes(getNumberOfNodes()); - MEDCouplingAutoRefCountObjectPtr ret=DataArrayInt::New(); - ret->alloc(nbOfNodes,1); - int *traducer=ret->getPointer(); - std::fill(traducer,traducer+nbOfNodes,-1); - int nbOfCells=getNumberOfCells(); - const int *connIndex=_nodal_connec_index->getConstPointer(); - const int *conn=_nodal_connec->getConstPointer(); - for(int i=0;i=0) - { - if(conn[j]getNumberOfCells() tuples and 1 component. - * For each cell in \b this the number of nodes constituting cell is computed. - * For each polyhedron cell, the sum of the number of nodes of each face constituting polyhedron cell is returned. - * So for pohyhedrons some nodes can be counted several times in the returned result. - * - * \return a newly allocated array - * \sa MEDCouplingUMesh::computeEffectiveNbOfNodesPerCell - */ -DataArrayInt *MEDCouplingUMesh::computeNbOfNodesPerCell() const -{ - checkConnectivityFullyDefined(); - int nbOfCells=getNumberOfCells(); - MEDCouplingAutoRefCountObjectPtr ret=DataArrayInt::New(); - ret->alloc(nbOfCells,1); - int *retPtr=ret->getPointer(); - const int *conn=getNodalConnectivity()->getConstPointer(); - const int *connI=getNodalConnectivityIndex()->getConstPointer(); - for(int i=0;i ret=DataArrayInt::New(); - ret->alloc(nbOfCells,1); - int *retPtr=ret->getPointer(); - const int *conn=getNodalConnectivity()->getConstPointer(); - const int *connI=getNodalConnectivityIndex()->getConstPointer(); - for(int i=0;i s(conn+connI[i]+1,conn+connI[i+1]); - if(conn[connI[i]]!=(int)INTERP_KERNEL::NORM_POLYHED) - *retPtr=(int)s.size(); - else - { - s.erase(-1); - *retPtr=(int)s.size(); - } - } - return ret.retn(); -} - -/*! - * This method returns a newly allocated array containing this->getNumberOfCells() tuples and 1 component. - * For each cell in \b this the number of faces constituting (entity of dimension this->getMeshDimension()-1) cell is computed. - * - * \return a newly allocated array - */ -DataArrayInt *MEDCouplingUMesh::computeNbOfFacesPerCell() const -{ - checkConnectivityFullyDefined(); - int nbOfCells=getNumberOfCells(); - MEDCouplingAutoRefCountObjectPtr ret=DataArrayInt::New(); - ret->alloc(nbOfCells,1); - int *retPtr=ret->getPointer(); - const int *conn=getNodalConnectivity()->getConstPointer(); - const int *connI=getNodalConnectivityIndex()->getConstPointer(); - for(int i=0;igetNumberOfNodes() before call of this method. The caller is to - * delete this array using decrRef() as it is no more needed. - * \throw If the coordinates array is not set. - * \throw If the nodal connectivity of cells is not defined. - * \throw If the nodal connectivity includes an invalid id. - * \sa areAllNodesFetched - * - * \if ENABLE_EXAMPLES - * \ref cpp_mcumesh_zipCoordsTraducer "Here is a C++ example".
- * \ref py_mcumesh_zipCoordsTraducer "Here is a Python example". - * \endif - */ -DataArrayInt *MEDCouplingUMesh::zipCoordsTraducer() -{ - return MEDCouplingPointSet::zipCoordsTraducer(); -} - -/*! - * This method stands if 'cell1' and 'cell2' are equals regarding 'compType' policy. - * The semantic of 'compType' is specified in MEDCouplingPointSet::zipConnectivityTraducer method. - */ -int MEDCouplingUMesh::AreCellsEqual(const int *conn, const int *connI, int cell1, int cell2, int compType) -{ - switch(compType) - { - case 0: - return AreCellsEqual0(conn,connI,cell1,cell2); - case 1: - return AreCellsEqual1(conn,connI,cell1,cell2); - case 2: - return AreCellsEqual2(conn,connI,cell1,cell2); - case 3: - return AreCellsEqual3(conn,connI,cell1,cell2); - case 7: - return AreCellsEqual7(conn,connI,cell1,cell2); - } - throw INTERP_KERNEL::Exception("Unknown comparison asked ! Must be in 0,1,2,3 or 7."); -} - -/*! - * This method is the last step of the MEDCouplingPointSet::zipConnectivityTraducer with policy 0. - */ -int MEDCouplingUMesh::AreCellsEqual0(const int *conn, const int *connI, int cell1, int cell2) -{ - if(connI[cell1+1]-connI[cell1]==connI[cell2+1]-connI[cell2]) - return std::equal(conn+connI[cell1]+1,conn+connI[cell1+1],conn+connI[cell2]+1)?1:0; - return 0; -} - -/*! - * This method is the last step of the MEDCouplingPointSet::zipConnectivityTraducer with policy 1. - */ -int MEDCouplingUMesh::AreCellsEqual1(const int *conn, const int *connI, int cell1, int cell2) -{ - int sz=connI[cell1+1]-connI[cell1]; - if(sz==connI[cell2+1]-connI[cell2]) - { - if(conn[connI[cell1]]==conn[connI[cell2]]) - { - const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel((INTERP_KERNEL::NormalizedCellType)conn[connI[cell1]]); - unsigned dim=cm.getDimension(); - if(dim!=3) - { - if(dim!=1) - { - int sz1=2*(sz-1); - INTERP_KERNEL::AutoPtr tmp=new int[sz1]; - int *work=std::copy(conn+connI[cell1]+1,conn+connI[cell1+1],(int *)tmp); - std::copy(conn+connI[cell1]+1,conn+connI[cell1+1],work); - work=std::search((int *)tmp,(int *)tmp+sz1,conn+connI[cell2]+1,conn+connI[cell2+1]); - return work!=tmp+sz1?1:0; - } - else - return std::equal(conn+connI[cell1]+1,conn+connI[cell1+1],conn+connI[cell2]+1)?1:0;//case of SEG2 and SEG3 - } - else - throw INTERP_KERNEL::Exception("MEDCouplingUMesh::AreCellsEqual1 : not implemented yet for meshdim == 3 !"); - } - } - return 0; -} - -/*! - * This method is the last step of the MEDCouplingPointSet::zipConnectivityTraducer with policy 2. - */ -int MEDCouplingUMesh::AreCellsEqual2(const int *conn, const int *connI, int cell1, int cell2) -{ - if(connI[cell1+1]-connI[cell1]==connI[cell2+1]-connI[cell2]) - { - if(conn[connI[cell1]]==conn[connI[cell2]]) - { - std::set s1(conn+connI[cell1]+1,conn+connI[cell1+1]); - std::set s2(conn+connI[cell2]+1,conn+connI[cell2+1]); - return s1==s2?1:0; - } - } - return 0; -} - -/*! - * This method is less restrictive than AreCellsEqual2. Here the geometric type is absolutely not taken into account ! - */ -int MEDCouplingUMesh::AreCellsEqual3(const int *conn, const int *connI, int cell1, int cell2) -{ - if(connI[cell1+1]-connI[cell1]==connI[cell2+1]-connI[cell2]) - { - std::set s1(conn+connI[cell1]+1,conn+connI[cell1+1]); - std::set s2(conn+connI[cell2]+1,conn+connI[cell2+1]); - return s1==s2?1:0; - } - return 0; -} - -/*! - * This method is the last step of the MEDCouplingPointSet::zipConnectivityTraducer with policy 7. - */ -int MEDCouplingUMesh::AreCellsEqual7(const int *conn, const int *connI, int cell1, int cell2) -{ - int sz=connI[cell1+1]-connI[cell1]; - if(sz==connI[cell2+1]-connI[cell2]) - { - if(conn[connI[cell1]]==conn[connI[cell2]]) - { - const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel((INTERP_KERNEL::NormalizedCellType)conn[connI[cell1]]); - unsigned dim=cm.getDimension(); - if(dim!=3) - { - if(dim!=1) - { - int sz1=2*(sz-1); - INTERP_KERNEL::AutoPtr tmp=new int[sz1]; - int *work=std::copy(conn+connI[cell1]+1,conn+connI[cell1+1],(int *)tmp); - std::copy(conn+connI[cell1]+1,conn+connI[cell1+1],work); - work=std::search((int *)tmp,(int *)tmp+sz1,conn+connI[cell2]+1,conn+connI[cell2+1]); - if(work!=tmp+sz1) - return 1; - else - { - std::reverse_iterator it1((int *)tmp+sz1); - std::reverse_iterator it2((int *)tmp); - if(std::search(it1,it2,conn+connI[cell2]+1,conn+connI[cell2+1])!=it2) - return 2; - else - return 0; - } - - return work!=tmp+sz1?1:0; - } - else - {//case of SEG2 and SEG3 - if(std::equal(conn+connI[cell1]+1,conn+connI[cell1+1],conn+connI[cell2]+1)) - return 1; - if(!cm.isQuadratic()) - { - std::reverse_iterator it1(conn+connI[cell1+1]); - std::reverse_iterator it2(conn+connI[cell1]+1); - if(std::equal(it1,it2,conn+connI[cell2]+1)) - return 2; - return 0; - } - else - { - if(conn[connI[cell1]+1]==conn[connI[cell2]+2] && conn[connI[cell1]+2]==conn[connI[cell2]+1] && conn[connI[cell1]+3]==conn[connI[cell2]+3]) - return 2; - return 0; - } - } - } - else - throw INTERP_KERNEL::Exception("MEDCouplingUMesh::AreCellsEqual7 : not implemented yet for meshdim == 3 !"); - } - } - return 0; -} - -/*! - * This method find in candidate pool defined by 'candidates' the cells equal following the polycy 'compType'. - * If any true is returned and the results will be put at the end of 'result' output parameter. If not false is returned - * and result remains unchanged. - * The semantic of 'compType' is specified in MEDCouplingPointSet::zipConnectivityTraducer method. - * If in 'candidates' pool -1 value is considered as an empty value. - * WARNING this method returns only ONE set of result ! - */ -bool MEDCouplingUMesh::AreCellsEqualInPool(const std::vector& candidates, int compType, const int *conn, const int *connI, DataArrayInt *result) -{ - if(candidates.size()<1) - return false; - bool ret=false; - std::vector::const_iterator iter=candidates.begin(); - int start=(*iter++); - for(;iter!=candidates.end();iter++) - { - int status=AreCellsEqual(conn,connI,start,*iter,compType); - if(status!=0) - { - if(!ret) - { - result->pushBackSilent(start); - ret=true; - } - if(status==1) - result->pushBackSilent(*iter); - else - result->pushBackSilent(status==2?(*iter+1):-(*iter+1)); - } - } - return ret; -} - -/*! - * This method find cells that are equal (regarding \a compType) in \a this. The comparison is specified - * by \a compType. - * This method keeps the coordiantes of \a this. This method is time consuming. - * - * \param [in] compType input specifying the technique used to compare cells each other. - * - 0 : exactly. A cell is detected to be the same if and only if the connectivity is exactly the same without permutation and types same too. This is the strongest policy. - * - 1 : permutation same orientation. cell1 and cell2 are considered equal if the connectivity of cell2 can be deduced by those of cell1 by direct permutation (with exactly the same orientation) - * and their type equal. For 1D mesh the policy 1 is equivalent to 0. - * - 2 : nodal. cell1 and cell2 are equal if and only if cell1 and cell2 have same type and have the same nodes constituting connectivity. This is the laziest policy. This policy - * can be used for users not sensitive to orientation of cell - * \param [in] startCellId specifies the cellId starting from which the equality computation will be carried out. By default it is 0, which it means that all cells in \a this will be scanned. - * \param [out] commonCellsArr common cells ids (\ref numbering-indirect) - * \param [out] commonCellsIArr common cells ids (\ref numbering-indirect) - * \return the correspondance array old to new in a newly allocated array. - * - */ -void MEDCouplingUMesh::findCommonCells(int compType, int startCellId, DataArrayInt *& commonCellsArr, DataArrayInt *& commonCellsIArr) const -{ - MEDCouplingAutoRefCountObjectPtr revNodal=DataArrayInt::New(),revNodalI=DataArrayInt::New(); - getReverseNodalConnectivity(revNodal,revNodalI); - FindCommonCellsAlg(compType,startCellId,_nodal_connec,_nodal_connec_index,revNodal,revNodalI,commonCellsArr,commonCellsIArr); -} - -void MEDCouplingUMesh::FindCommonCellsAlg(int compType, int startCellId, const DataArrayInt *nodal, const DataArrayInt *nodalI, const DataArrayInt *revNodal, const DataArrayInt *revNodalI, - DataArrayInt *& commonCellsArr, DataArrayInt *& commonCellsIArr) -{ - MEDCouplingAutoRefCountObjectPtr commonCells=DataArrayInt::New(),commonCellsI=DataArrayInt::New(); commonCells->alloc(0,1); - int nbOfCells=nodalI->getNumberOfTuples()-1; - commonCellsI->reserve(1); commonCellsI->pushBackSilent(0); - const int *revNodalPtr=revNodal->getConstPointer(),*revNodalIPtr=revNodalI->getConstPointer(); - const int *connPtr=nodal->getConstPointer(),*connIPtr=nodalI->getConstPointer(); - std::vector isFetched(nbOfCells,false); - if(startCellId==0) - { - for(int i=0;i(),-1)); - std::vector v,v2; - if(connOfNode!=connPtr+connIPtr[i+1]) - { - const int *locRevNodal=std::find(revNodalPtr+revNodalIPtr[*connOfNode],revNodalPtr+revNodalIPtr[*connOfNode+1],i); - v2.insert(v2.end(),locRevNodal,revNodalPtr+revNodalIPtr[*connOfNode+1]); - connOfNode++; - } - for(;connOfNode!=connPtr+connIPtr[i+1] && v2.size()>1;connOfNode++) - if(*connOfNode>=0) - { - v=v2; - const int *locRevNodal=std::find(revNodalPtr+revNodalIPtr[*connOfNode],revNodalPtr+revNodalIPtr[*connOfNode+1],i); - std::vector::iterator it=std::set_intersection(v.begin(),v.end(),locRevNodal,revNodalPtr+revNodalIPtr[*connOfNode+1],v2.begin()); - v2.resize(std::distance(v2.begin(),it)); - } - if(v2.size()>1) - { - if(AreCellsEqualInPool(v2,compType,connPtr,connIPtr,commonCells)) - { - int pos=commonCellsI->back(); - commonCellsI->pushBackSilent(commonCells->getNumberOfTuples()); - for(const int *it=commonCells->begin()+pos;it!=commonCells->end();it++) - isFetched[*it]=true; - } - } - } - } - } - else - { - for(int i=startCellId;i(),-1)); - std::vector v,v2; - if(connOfNode!=connPtr+connIPtr[i+1]) - { - v2.insert(v2.end(),revNodalPtr+revNodalIPtr[*connOfNode],revNodalPtr+revNodalIPtr[*connOfNode+1]); - connOfNode++; - } - for(;connOfNode!=connPtr+connIPtr[i+1] && v2.size()>1;connOfNode++) - if(*connOfNode>=0) - { - v=v2; - std::vector::iterator it=std::set_intersection(v.begin(),v.end(),revNodalPtr+revNodalIPtr[*connOfNode],revNodalPtr+revNodalIPtr[*connOfNode+1],v2.begin()); - v2.resize(std::distance(v2.begin(),it)); - } - if(v2.size()>1) - { - if(AreCellsEqualInPool(v2,compType,connPtr,connIPtr,commonCells)) - { - int pos=commonCellsI->back(); - commonCellsI->pushBackSilent(commonCells->getNumberOfTuples()); - for(const int *it=commonCells->begin()+pos;it!=commonCells->end();it++) - isFetched[*it]=true; - } - } - } - } - } - commonCellsArr=commonCells.retn(); - commonCellsIArr=commonCellsI.retn(); -} - -/*! - * Checks if \a this mesh includes all cells of an \a other mesh, and returns an array - * giving for each cell of the \a other an id of a cell in \a this mesh. A value larger - * than \a other->getNumberOfCells() in the returned array means that there is no - * corresponding cell in \a this mesh. - * It is expected that \a this and \a other meshes share the same node coordinates - * array, if it is not so an exception is thrown. - * \param [in] other - the mesh to compare with. - * \param [in] compType - specifies a cell comparison technique. For meaning of its - * valid values [0,1,2], see zipConnectivityTraducer(). - * \param [out] arr - a new instance of DataArrayInt returning correspondence - * between cells of the two meshes. It contains \a other->getNumberOfCells() - * values. The caller is to delete this array using - * decrRef() as it is no more needed. - * \return bool - \c true if all cells of \a other mesh are present in the \a this - * mesh. - * - * \if ENABLE_EXAMPLES - * \ref cpp_mcumesh_areCellsIncludedIn "Here is a C++ example".
- * \ref py_mcumesh_areCellsIncludedIn "Here is a Python example". - * \endif - * \sa checkDeepEquivalOnSameNodesWith() - * \sa checkGeoEquivalWith() - */ -bool MEDCouplingUMesh::areCellsIncludedIn(const MEDCouplingUMesh *other, int compType, DataArrayInt *& arr) const -{ - MEDCouplingAutoRefCountObjectPtr mesh=MergeUMeshesOnSameCoords(this,other); - int nbOfCells=getNumberOfCells(); - static const int possibleCompType[]={0,1,2}; - if(std::find(possibleCompType,possibleCompType+sizeof(possibleCompType)/sizeof(int),compType)==possibleCompType+sizeof(possibleCompType)/sizeof(int)) - { - std::ostringstream oss; oss << "MEDCouplingUMesh::areCellsIncludedIn : only following policies are possible : "; - std::copy(possibleCompType,possibleCompType+sizeof(possibleCompType)/sizeof(int),std::ostream_iterator(oss," ")); - oss << " !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - MEDCouplingAutoRefCountObjectPtr o2n=mesh->zipConnectivityTraducer(compType,nbOfCells); - arr=o2n->substr(nbOfCells); - arr->setName(other->getName()); - int tmp; - if(other->getNumberOfCells()==0) - return true; - return arr->getMaxValue(tmp)getNumberOfCells()'. - * \return If \a other is fully included in 'this 'true is returned. If not false is returned. - */ -bool MEDCouplingUMesh::areCellsIncludedIn2(const MEDCouplingUMesh *other, DataArrayInt *& arr) const -{ - MEDCouplingAutoRefCountObjectPtr mesh=MergeUMeshesOnSameCoords(this,other); - DataArrayInt *commonCells=0,*commonCellsI=0; - int thisNbCells=getNumberOfCells(); - mesh->findCommonCells(7,thisNbCells,commonCells,commonCellsI); - MEDCouplingAutoRefCountObjectPtr commonCellsTmp(commonCells),commonCellsITmp(commonCellsI); - const int *commonCellsPtr=commonCells->getConstPointer(),*commonCellsIPtr=commonCellsI->getConstPointer(); - int otherNbCells=other->getNumberOfCells(); - MEDCouplingAutoRefCountObjectPtr arr2=DataArrayInt::New(); - arr2->alloc(otherNbCells,1); - arr2->fillWithZero(); - int *arr2Ptr=arr2->getPointer(); - int nbOfCommon=commonCellsI->getNumberOfTuples()-1; - for(int i=0;i0?1:-1; - int val=std::abs(commonCellsPtr[j])-1; - if(val>=thisNbCells) - arr2Ptr[val-thisNbCells]=sig*(start+1); - } - } - } - arr2->setName(other->getName()); - if(arr2->presenceOfValue(0)) - return false; - arr=arr2.retn(); - return true; -} - -MEDCouplingPointSet *MEDCouplingUMesh::mergeMyselfWithOnSameCoords(const MEDCouplingPointSet *other) const -{ - if(!other) - throw INTERP_KERNEL::Exception("MEDCouplingUMesh::mergeMyselfWithOnSameCoords : input other is null !"); - const MEDCouplingUMesh *otherC=dynamic_cast(other); - if(!otherC) - throw INTERP_KERNEL::Exception("MEDCouplingUMesh::mergeMyselfWithOnSameCoords : the input other mesh is not of type unstructured !"); - std::vector ms(2); - ms[0]=this; - ms[1]=otherC; - return MergeUMeshesOnSameCoords(ms); -} - -/*! - * Build a sub part of \b this lying or not on the same coordinates than \b this (regarding value of \b keepCoords). - * By default coordinates are kept. This method is close to MEDCouplingUMesh::buildPartOfMySelf except that here input - * cellIds is not given explicitely but by a range python like. - * - * \param start - * \param end - * \param step - * \param keepCoords that specifies if you want or not to keep coords as this or zip it (see ParaMEDMEM::MEDCouplingUMesh::zipCoords). If true zipCoords is \b NOT called, if false, zipCoords is called. - * \return a newly allocated - * - * \warning This method modifies can generate an unstructured mesh whose cells are not sorted by geometric type order. - * In view of the MED file writing, a renumbering of cells of returned unstructured mesh (using MEDCouplingUMesh::sortCellsInMEDFileFrmt) should be necessary. - */ -MEDCouplingPointSet *MEDCouplingUMesh::buildPartOfMySelf2(int start, int end, int step, bool keepCoords) const -{ - if(getMeshDimension()!=-1) - return MEDCouplingPointSet::buildPartOfMySelf2(start,end,step,keepCoords); - else - { - int newNbOfCells=DataArray::GetNumberOfItemGivenBESRelative(start,end,step,"MEDCouplingUMesh::buildPartOfMySelf2 for -1 dimension mesh "); - if(newNbOfCells!=1) - throw INTERP_KERNEL::Exception("-1D mesh has only one cell !"); - if(start!=0) - throw INTERP_KERNEL::Exception("-1D mesh has only one cell : 0 !"); - incrRef(); - return const_cast(this); - } -} - -/*! - * Creates a new MEDCouplingUMesh containing specified cells of \a this mesh. - * The result mesh shares or not the node coordinates array with \a this mesh depending - * on \a keepCoords parameter. - * \warning Cells of the result mesh can be \b not sorted by geometric type, hence, - * to write this mesh to the MED file, its cells must be sorted using - * sortCellsInMEDFileFrmt(). - * \param [in] begin - an array of cell ids to include to the new mesh. - * \param [in] end - a pointer to last-plus-one-th element of \a begin. - * \param [in] keepCoords - if \c true, the result mesh shares the node coordinates - * array of \a this mesh, else "free" nodes are removed from the result mesh - * by calling zipCoords(). - * \return MEDCouplingPointSet * - 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 not defined. - * \throw If any cell id in the array \a begin is not valid. - * - * \if ENABLE_EXAMPLES - * \ref cpp_mcumesh_buildPartOfMySelf "Here is a C++ example".
- * \ref py_mcumesh_buildPartOfMySelf "Here is a Python example". - * \endif - */ -MEDCouplingPointSet *MEDCouplingUMesh::buildPartOfMySelf(const int *begin, const int *end, bool keepCoords) const -{ - if(getMeshDimension()!=-1) - return MEDCouplingPointSet::buildPartOfMySelf(begin,end,keepCoords); - else - { - if(end-begin!=1) - throw INTERP_KERNEL::Exception("-1D mesh has only one cell !"); - if(begin[0]!=0) - throw INTERP_KERNEL::Exception("-1D mesh has only one cell : 0 !"); - incrRef(); - return const_cast(this); - } -} - -/*! - * This method operates only on nodal connectivity on \b this. Coordinates of \b this is completely ignored here. - * - * This method allows to partially modify some cells in \b this (whose list is specified by [ \b cellIdsBg, \b cellIdsEnd ) ) with cells coming in \b otherOnSameCoordsThanThis. - * Size of [ \b cellIdsBg, \b cellIdsEnd ) ) must be equal to the number of cells of otherOnSameCoordsThanThis. - * The number of cells of \b this will remain the same with this method. - * - * \param [in] cellIdsBg begin of cell ids (included) of cells in this to assign - * \param [in] cellIdsEnd end of cell ids (excluded) of cells in this to assign - * \param [in] otherOnSameCoordsThanThis an another mesh with same meshdimension than \b this with exactly the same number of cells than cell ids list in [\b cellIdsBg, \b cellIdsEnd ). - * Coordinate pointer of \b this and those of \b otherOnSameCoordsThanThis must be the same - */ -void MEDCouplingUMesh::setPartOfMySelf(const int *cellIdsBg, const int *cellIdsEnd, const MEDCouplingUMesh& otherOnSameCoordsThanThis) -{ - checkConnectivityFullyDefined(); - otherOnSameCoordsThanThis.checkConnectivityFullyDefined(); - if(getCoords()!=otherOnSameCoordsThanThis.getCoords()) - throw INTERP_KERNEL::Exception("MEDCouplingUMesh::setPartOfMySelf : coordinates pointer are not the same ! Invoke setCoords or call tryToShareSameCoords method !"); - if(getMeshDimension()!=otherOnSameCoordsThanThis.getMeshDimension()) - { - std::ostringstream oss; oss << "MEDCouplingUMesh::setPartOfMySelf : Mismatch of meshdimensions ! this is equal to " << getMeshDimension(); - oss << ", whereas other mesh dimension is set equal to " << otherOnSameCoordsThanThis.getMeshDimension() << " !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - int nbOfCellsToModify=(int)std::distance(cellIdsBg,cellIdsEnd); - if(nbOfCellsToModify!=otherOnSameCoordsThanThis.getNumberOfCells()) - { - std::ostringstream oss; oss << "MEDCouplingUMesh::setPartOfMySelf : cells ids length (" << nbOfCellsToModify << ") do not match the number of cells of other mesh (" << otherOnSameCoordsThanThis.getNumberOfCells() << ") !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - int nbOfCells=getNumberOfCells(); - bool easyAssign=true; - const int *connI=_nodal_connec_index->getConstPointer(); - const int *connIOther=otherOnSameCoordsThanThis._nodal_connec_index->getConstPointer(); - for(const int *it=cellIdsBg;it!=cellIdsEnd && easyAssign;it++,connIOther++) - { - if(*it>=0 && *it arrOutAuto(arrOut),arrIOutAuto(arrIOut); - setConnectivity(arrOut,arrIOut,true); - } -} - -void MEDCouplingUMesh::setPartOfMySelf2(int start, int end, int step, const MEDCouplingUMesh& otherOnSameCoordsThanThis) -{ - checkConnectivityFullyDefined(); - otherOnSameCoordsThanThis.checkConnectivityFullyDefined(); - if(getCoords()!=otherOnSameCoordsThanThis.getCoords()) - throw INTERP_KERNEL::Exception("MEDCouplingUMesh::setPartOfMySelf2 : coordinates pointer are not the same ! Invoke setCoords or call tryToShareSameCoords method !"); - if(getMeshDimension()!=otherOnSameCoordsThanThis.getMeshDimension()) - { - std::ostringstream oss; oss << "MEDCouplingUMesh::setPartOfMySelf2 : Mismatch of meshdimensions ! this is equal to " << getMeshDimension(); - oss << ", whereas other mesh dimension is set equal to " << otherOnSameCoordsThanThis.getMeshDimension() << " !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - int nbOfCellsToModify=DataArray::GetNumberOfItemGivenBESRelative(start,end,step,"MEDCouplingUMesh::setPartOfMySelf2 : "); - if(nbOfCellsToModify!=otherOnSameCoordsThanThis.getNumberOfCells()) - { - std::ostringstream oss; oss << "MEDCouplingUMesh::setPartOfMySelf2 : cells ids length (" << nbOfCellsToModify << ") do not match the number of cells of other mesh (" << otherOnSameCoordsThanThis.getNumberOfCells() << ") !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - int nbOfCells=getNumberOfCells(); - bool easyAssign=true; - const int *connI=_nodal_connec_index->getConstPointer(); - const int *connIOther=otherOnSameCoordsThanThis._nodal_connec_index->getConstPointer(); - int it=start; - for(int i=0;i=0 && it arrOutAuto(arrOut),arrIOutAuto(arrIOut); - setConnectivity(arrOut,arrIOut,true); - } -} - -/*! - * Keeps from \a this only cells which constituing point id are in the ids specified by [ \a begin,\a end ). - * The resulting cell ids are stored at the end of the 'cellIdsKept' parameter. - * Parameter \a fullyIn specifies if a cell that has part of its nodes in ids array is kept or not. - * If \a fullyIn is true only cells whose ids are \b fully contained in [ \a begin,\a end ) tab will be kept. - * - * \param [in] begin input start of array of node ids. - * \param [in] end input end of array of node ids. - * \param [in] fullyIn input that specifies if all node ids must be in [ \a begin,\a end ) array to consider cell to be in. - * \param [in,out] cellIdsKeptArr array where all candidate cell ids are put at the end. - */ -void MEDCouplingUMesh::fillCellIdsToKeepFromNodeIds(const int *begin, const int *end, bool fullyIn, DataArrayInt *&cellIdsKeptArr) const -{ - MEDCouplingAutoRefCountObjectPtr cellIdsKept=DataArrayInt::New(); cellIdsKept->alloc(0,1); - checkConnectivityFullyDefined(); - int tmp=-1; - int sz=getNodalConnectivity()->getMaxValue(tmp); sz=std::max(sz,0)+1; - std::vector fastFinder(sz,false); - for(const int *work=begin;work!=end;work++) - if(*work>=0 && *workgetConstPointer(); - const int *connIndex=getNodalConnectivityIndex()->getConstPointer(); - for(int i=0;i=0) - { - ref++; - if(fastFinder[*work2]) - nbOfHit++; - } - if((ref==nbOfHit && fullyIn) || (nbOfHit!=0 && !fullyIn)) - cellIdsKept->pushBackSilent(i); - } - cellIdsKeptArr=cellIdsKept.retn(); -} - -/*! - * Creates a new MEDCouplingUMesh containing cells, of dimension one less than \a - * this->getMeshDimension(), that bound some cells of \a this mesh. - * The cells of lower dimension to include to the result mesh are selected basing on - * specified node ids and the value of \a fullyIn parameter. If \a fullyIn ==\c true, a - * cell is copied if its all nodes are in the array \a begin of node ids. If \a fullyIn - * ==\c false, a cell is copied if any its node is in the array of node ids. The - * created mesh shares the node coordinates array with \a this mesh. - * \param [in] begin - the array of node ids. - * \param [in] end - a pointer to the (last+1)-th element of \a begin. - * \param [in] fullyIn - if \c true, then cells whose all nodes are in the - * array \a begin are added, else cells whose any node is in the - * array \a begin are added. - * \return MEDCouplingPointSet * - 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 not defined. - * \throw If any node id in \a begin is not valid. - * - * \if ENABLE_EXAMPLES - * \ref cpp_mcumesh_buildFacePartOfMySelfNode "Here is a C++ example".
- * \ref py_mcumesh_buildFacePartOfMySelfNode "Here is a Python example". - * \endif - */ -MEDCouplingPointSet *MEDCouplingUMesh::buildFacePartOfMySelfNode(const int *begin, const int *end, bool fullyIn) const -{ - MEDCouplingAutoRefCountObjectPtr desc,descIndx,revDesc,revDescIndx; - desc=DataArrayInt::New(); descIndx=DataArrayInt::New(); revDesc=DataArrayInt::New(); revDescIndx=DataArrayInt::New(); - MEDCouplingAutoRefCountObjectPtr subMesh=buildDescendingConnectivity(desc,descIndx,revDesc,revDescIndx); - desc=0; descIndx=0; revDesc=0; revDescIndx=0; - return subMesh->buildPartOfMySelfNode(begin,end,fullyIn); -} - -/*! - * Creates a new MEDCouplingUMesh containing cells, of dimension one less than \a - * this->getMeshDimension(), which bound only one cell of \a this mesh. - * \param [in] keepCoords - if \c true, the result mesh shares the node coordinates - * array of \a this mesh, else "free" nodes are removed from the result mesh - * by calling zipCoords(). - * \return MEDCouplingPointSet * - 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 not defined. - * - * \if ENABLE_EXAMPLES - * \ref cpp_mcumesh_buildBoundaryMesh "Here is a C++ example".
- * \ref py_mcumesh_buildBoundaryMesh "Here is a Python example". - * \endif - */ -MEDCouplingPointSet *MEDCouplingUMesh::buildBoundaryMesh(bool keepCoords) const -{ - DataArrayInt *desc=DataArrayInt::New(); - DataArrayInt *descIndx=DataArrayInt::New(); - DataArrayInt *revDesc=DataArrayInt::New(); - DataArrayInt *revDescIndx=DataArrayInt::New(); - // - MEDCouplingAutoRefCountObjectPtr meshDM1=buildDescendingConnectivity(desc,descIndx,revDesc,revDescIndx); - revDesc->decrRef(); - desc->decrRef(); - descIndx->decrRef(); - int nbOfCells=meshDM1->getNumberOfCells(); - const int *revDescIndxC=revDescIndx->getConstPointer(); - std::vector boundaryCells; - for(int i=0;idecrRef(); - MEDCouplingPointSet *ret=meshDM1->buildPartOfMySelf(&boundaryCells[0],&boundaryCells[0]+boundaryCells.size(),keepCoords); - return ret; -} - -/*! - * This method returns a newly created DataArrayInt instance containing ids of cells located in boundary. - * A cell is detected to be on boundary if it contains one or more than one face having only one father. - * This method makes the assumption that \a this is fully defined (coords,connectivity). If not an exception will be thrown. - */ -DataArrayInt *MEDCouplingUMesh::findCellIdsOnBoundary() const -{ - checkFullyDefined(); - MEDCouplingAutoRefCountObjectPtr desc=DataArrayInt::New(); - MEDCouplingAutoRefCountObjectPtr descIndx=DataArrayInt::New(); - MEDCouplingAutoRefCountObjectPtr revDesc=DataArrayInt::New(); - MEDCouplingAutoRefCountObjectPtr revDescIndx=DataArrayInt::New(); - // - buildDescendingConnectivity(desc,descIndx,revDesc,revDescIndx)->decrRef(); - desc=(DataArrayInt*)0; descIndx=(DataArrayInt*)0; - // - MEDCouplingAutoRefCountObjectPtr tmp=revDescIndx->deltaShiftIndex(); - MEDCouplingAutoRefCountObjectPtr faceIds=tmp->getIdsEqual(1); tmp=(DataArrayInt*)0; - const int *revDescPtr=revDesc->getConstPointer(); - const int *revDescIndxPtr=revDescIndx->getConstPointer(); - int nbOfCells=getNumberOfCells(); - std::vector ret1(nbOfCells,false); - int sz=0; - for(const int *pt=faceIds->begin();pt!=faceIds->end();pt++) - if(!ret1[revDescPtr[revDescIndxPtr[*pt]]]) - { ret1[revDescPtr[revDescIndxPtr[*pt]]]=true; sz++; } - // - DataArrayInt *ret2=DataArrayInt::New(); - ret2->alloc(sz,1); - int *ret2Ptr=ret2->getPointer(); - sz=0; - for(std::vector::const_iterator it=ret1.begin();it!=ret1.end();it++,sz++) - if(*it) - *ret2Ptr++=sz; - ret2->setName("BoundaryCells"); - return ret2; -} - -/*! - * This method finds in \b this the cell ids that lie on mesh \b otherDimM1OnSameCoords. - * \b this and \b otherDimM1OnSameCoords have to lie on the same coordinate array pointer. The coherency of that coords array with connectivity - * of \b this and \b otherDimM1OnSameCoords is not important here because this method works only on connectivity. - * this->getMeshDimension() - 1 must be equal to otherDimM1OnSameCoords.getMeshDimension() - * - * s0 is the cell ids set in \b this lying on at least one node in the fetched nodes in \b otherDimM1OnSameCoords. - * This method also returns the cells ids set s1 which contains the cell ids in \b this for which one of the dim-1 constituent - * equals a cell in \b otherDimM1OnSameCoords. - * - * \throw if \b otherDimM1OnSameCoords is not part of constituent of \b this, or if coordinate pointer of \b this and \b otherDimM1OnSameCoords - * are not same, or if this->getMeshDimension()-1!=otherDimM1OnSameCoords.getMeshDimension() - * - * \param [in] otherDimM1OnSameCoords - * \param [out] cellIdsRk0 a newly allocated array containing the cell ids of s0 (which are cell ids of \b this) in the above algorithm. - * \param [out] cellIdsRk1 a newly allocated array containing the cell ids of s1 \b indexed into the \b cellIdsRk0 subset. To get the absolute ids of s1, simply invoke - * cellIdsRk1->transformWithIndArr(cellIdsRk0->begin(),cellIdsRk0->end()); - */ -void MEDCouplingUMesh::findCellIdsLyingOn(const MEDCouplingUMesh& otherDimM1OnSameCoords, DataArrayInt *&cellIdsRk0, DataArrayInt *&cellIdsRk1) const -{ - if(getCoords()!=otherDimM1OnSameCoords.getCoords()) - throw INTERP_KERNEL::Exception("MEDCouplingUMesh::findCellIdsLyingOn : coordinates pointer are not the same ! Use tryToShareSameCoords method !"); - checkConnectivityFullyDefined(); - otherDimM1OnSameCoords.checkConnectivityFullyDefined(); - if(getMeshDimension()-1!=otherDimM1OnSameCoords.getMeshDimension()) - throw INTERP_KERNEL::Exception("MEDCouplingUMesh::findCellIdsLyingOn : invalid mesh dimension of input mesh regarding meshdimesion of this !"); - MEDCouplingAutoRefCountObjectPtr fetchedNodeIds1=otherDimM1OnSameCoords.computeFetchedNodeIds(); - MEDCouplingAutoRefCountObjectPtr s0arr=getCellIdsLyingOnNodes(fetchedNodeIds1->begin(),fetchedNodeIds1->end(),false); - MEDCouplingAutoRefCountObjectPtr thisPart=static_cast(buildPartOfMySelf(s0arr->begin(),s0arr->end(),true)); - MEDCouplingAutoRefCountObjectPtr descThisPart=DataArrayInt::New(),descIThisPart=DataArrayInt::New(),revDescThisPart=DataArrayInt::New(),revDescIThisPart=DataArrayInt::New(); - MEDCouplingAutoRefCountObjectPtr thisPartConsti=thisPart->buildDescendingConnectivity(descThisPart,descIThisPart,revDescThisPart,revDescIThisPart); - const int *revDescThisPartPtr=revDescThisPart->getConstPointer(),*revDescIThisPartPtr=revDescIThisPart->getConstPointer(); - DataArrayInt *idsOtherInConsti=0; - bool b=thisPartConsti->areCellsIncludedIn(&otherDimM1OnSameCoords,2,idsOtherInConsti); - MEDCouplingAutoRefCountObjectPtr idsOtherInConstiAuto(idsOtherInConsti); - if(!b) - throw INTERP_KERNEL::Exception("MEDCouplingUMesh::findCellIdsLyingOn : the given mdim-1 mesh in other is not a constituent of this !"); - std::set s1; - for(const int *idOther=idsOtherInConsti->begin();idOther!=idsOtherInConsti->end();idOther++) - s1.insert(revDescThisPartPtr+revDescIThisPartPtr[*idOther],revDescThisPartPtr+revDescIThisPartPtr[*idOther+1]); - MEDCouplingAutoRefCountObjectPtr s1arr_renum1=DataArrayInt::New(); s1arr_renum1->alloc((int)s1.size(),1); std::copy(s1.begin(),s1.end(),s1arr_renum1->getPointer()); - s1arr_renum1->sort(); - cellIdsRk0=s0arr.retn(); - //cellIdsRk1=s_renum1.retn(); - cellIdsRk1=s1arr_renum1.retn(); -} - -/*! - * This method computes the skin of \b this. That is to say the consituting meshdim-1 mesh is built and only the boundary subpart is - * returned. This subpart of meshdim-1 mesh is built using meshdim-1 cells in it shared only one cell in \b this. - * - * \return a newly allocated mesh lying on the same coordinates than \b this. The caller has to deal with returned mesh. - */ -MEDCouplingUMesh *MEDCouplingUMesh::computeSkin() const -{ - MEDCouplingAutoRefCountObjectPtr desc=DataArrayInt::New(); - MEDCouplingAutoRefCountObjectPtr descIndx=DataArrayInt::New(); - MEDCouplingAutoRefCountObjectPtr revDesc=DataArrayInt::New(); - MEDCouplingAutoRefCountObjectPtr revDescIndx=DataArrayInt::New(); - // - MEDCouplingAutoRefCountObjectPtr meshDM1=buildDescendingConnectivity(desc,descIndx,revDesc,revDescIndx); - revDesc=0; desc=0; descIndx=0; - MEDCouplingAutoRefCountObjectPtr revDescIndx2=revDescIndx->deltaShiftIndex(); - MEDCouplingAutoRefCountObjectPtr part=revDescIndx2->getIdsEqual(1); - return static_cast(meshDM1->buildPartOfMySelf(part->begin(),part->end(),true)); -} - -/*! - * Finds nodes lying on the boundary of \a this mesh. - * \return DataArrayInt * - a new instance of DataArrayInt holding ids of found - * nodes. The caller is to delete this array 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. - * - * \if ENABLE_EXAMPLES - * \ref cpp_mcumesh_findBoundaryNodes "Here is a C++ example".
- * \ref py_mcumesh_findBoundaryNodes "Here is a Python example". - * \endif - */ -DataArrayInt *MEDCouplingUMesh::findBoundaryNodes() const -{ - MEDCouplingAutoRefCountObjectPtr skin=computeSkin(); - return skin->computeFetchedNodeIds(); -} - -MEDCouplingUMesh *MEDCouplingUMesh::buildUnstructured() const -{ - incrRef(); - return const_cast(this); -} - -/*! - * This method expects that \b this and \b otherDimM1OnSameCoords share the same coordinates array. - * otherDimM1OnSameCoords->getMeshDimension() is expected to be equal to this->getMeshDimension()-1. - * This method searches for nodes needed to be duplicated. These nodes are nodes fetched by \b otherDimM1OnSameCoords which are not part of the boundary of \b otherDimM1OnSameCoords. - * If a node is in the boundary of \b this \b and in the boundary of \b otherDimM1OnSameCoords this node is considerd as needed to be duplicated. - * When the set of node ids \b nodeIdsToDuplicate is computed, cell ids in \b this is searched so that their connectivity includes at least 1 node in \b nodeIdsToDuplicate. - * - * \param [in] otherDimM1OnSameCoords a mesh lying on the same coords than \b this and with a mesh dimension equal to those of \b this minus 1. WARNING this input - * parameter is altered during the call. - * \param [out] nodeIdsToDuplicate node ids needed to be duplicated following the algorithm explain above. - * \param [out] cellIdsNeededToBeRenum cell ids in \b this in which the renumber of nodes should be performed. - * \param [out] cellIdsNotModified cell ids int \b this that lies on \b otherDimM1OnSameCoords mesh whose connectivity do \b not need to be modified as it is the case for \b cellIdsNeededToBeRenum. - * - * \warning This method modifies param \b otherDimM1OnSameCoords (for speed reasons). - */ -void MEDCouplingUMesh::findNodesToDuplicate(const MEDCouplingUMesh& otherDimM1OnSameCoords, DataArrayInt *& nodeIdsToDuplicate, - DataArrayInt *& cellIdsNeededToBeRenum, DataArrayInt *& cellIdsNotModified) const -{ - typedef MEDCouplingAutoRefCountObjectPtr DAInt; - - checkFullyDefined(); - otherDimM1OnSameCoords.checkFullyDefined(); - if(getCoords()!=otherDimM1OnSameCoords.getCoords()) - throw INTERP_KERNEL::Exception("MEDCouplingUMesh::findNodesToDuplicate : meshes do not share the same coords array !"); - if(otherDimM1OnSameCoords.getMeshDimension()!=getMeshDimension()-1) - throw INTERP_KERNEL::Exception("MEDCouplingUMesh::findNodesToDuplicate : the mesh given in other parameter must have this->getMeshDimension()-1 !"); - DataArrayInt *cellIdsRk0=0,*cellIdsRk1=0; - findCellIdsLyingOn(otherDimM1OnSameCoords,cellIdsRk0,cellIdsRk1); - DAInt cellIdsRk0Auto(cellIdsRk0),cellIdsRk1Auto(cellIdsRk1); - DAInt s0=cellIdsRk1->buildComplement(cellIdsRk0->getNumberOfTuples()); - s0->transformWithIndArr(cellIdsRk0Auto->begin(),cellIdsRk0Auto->end()); - MEDCouplingAutoRefCountObjectPtr m0Part=static_cast(buildPartOfMySelf(s0->begin(),s0->end(),true)); - DAInt s1=m0Part->computeFetchedNodeIds(); - DAInt s2=otherDimM1OnSameCoords.computeFetchedNodeIds(); - DAInt s3=s2->buildSubstraction(s1); - cellIdsRk1->transformWithIndArr(cellIdsRk0Auto->begin(),cellIdsRk0Auto->end()); - // - MEDCouplingAutoRefCountObjectPtr m0Part2=static_cast(buildPartOfMySelf(cellIdsRk1->begin(),cellIdsRk1->end(),true)); - int nCells2 = m0Part2->getNumberOfCells(); - DAInt desc00=DataArrayInt::New(),descI00=DataArrayInt::New(),revDesc00=DataArrayInt::New(),revDescI00=DataArrayInt::New(); - MEDCouplingAutoRefCountObjectPtr m01=m0Part2->buildDescendingConnectivity(desc00,descI00,revDesc00,revDescI00); - // Neighbor information of the mesh without considering the crack (serves to count how many connex pieces it is made of) - DataArrayInt *tmp00=0,*tmp11=0; - MEDCouplingUMesh::ComputeNeighborsOfCellsAdv(desc00,descI00,revDesc00,revDescI00, tmp00, tmp11); - DAInt neighInit00(tmp00); - DAInt neighIInit00(tmp11); - // Neighbor information of the mesh WITH the crack (some neighbors are removed): - DataArrayInt *idsTmp=0; - bool b=m01->areCellsIncludedIn(&otherDimM1OnSameCoords,2,idsTmp); - DAInt ids(idsTmp); - if(!b) - throw INTERP_KERNEL::Exception("MEDCouplingUMesh::findNodesToDuplicate : the given mdim-1 mesh in other is not a constituent of this !"); - // In the neighbor information remove the connection between high dimension cells and its low level constituents which are part - // of the frontier given in parameter (i.e. the cells of low dimension from the group delimiting the crack): - MEDCouplingUMesh::RemoveIdsFromIndexedArrays(ids->begin(),ids->end(),desc00,descI00); - DataArrayInt *tmp0=0,*tmp1=0; - // Compute the neighbor of each cell in m0Part2, taking into account the broken link above. Two - // cells on either side of the crack (defined by the mesh of low dimension) are not neighbor anymore. - ComputeNeighborsOfCellsAdv(desc00,descI00,revDesc00,revDescI00,tmp0,tmp1); - DAInt neigh00(tmp0); - DAInt neighI00(tmp1); - - // For each initial connex part of the sub-mesh (or said differently for each independent crack): - int seed = 0, nIter = 0; - int nIterMax = nCells2+1; // Safety net for the loop - DAInt hitCells = DataArrayInt::New(); hitCells->alloc(nCells2); - hitCells->fillWithValue(-1); - DAInt cellsToModifyConn0_torenum = DataArrayInt::New(); - cellsToModifyConn0_torenum->alloc(0,1); - while (nIter < nIterMax) - { - DAInt t = hitCells->getIdsEqual(-1); - if (!t->getNumberOfTuples()) - break; - // Connex zone without the crack (to compute the next seed really) - int dnu; - DAInt connexCheck = MEDCouplingUMesh::ComputeSpreadZoneGraduallyFromSeed(&seed, &seed+1, neighInit00,neighIInit00, -1, dnu); - int cnt = 0; - for (int * ptr = connexCheck->getPointer(); cnt < connexCheck->getNumberOfTuples(); ptr++, cnt++) - hitCells->setIJ(*ptr,0,1); - // Connex zone WITH the crack (to identify cells lying on either part of the crack) - DAInt spreadZone = MEDCouplingUMesh::ComputeSpreadZoneGraduallyFromSeed(&seed, &seed+1, neigh00,neighI00, -1, dnu); - cellsToModifyConn0_torenum = DataArrayInt::Aggregate(cellsToModifyConn0_torenum, spreadZone, 0); - // Compute next seed, i.e. a cell in another connex part, which was not covered by the previous iterations - DAInt comple = cellsToModifyConn0_torenum->buildComplement(nCells2); - DAInt nonHitCells = hitCells->getIdsEqual(-1); - DAInt intersec = nonHitCells->buildIntersection(comple); - if (intersec->getNumberOfTuples()) - { seed = intersec->getIJ(0,0); } - else - { break; } - nIter++; - } - if (nIter >= nIterMax) - throw INTERP_KERNEL::Exception("MEDCouplingUMesh::findNodesToDuplicate(): internal error - too many iterations."); - - DAInt cellsToModifyConn1_torenum=cellsToModifyConn0_torenum->buildComplement(neighI00->getNumberOfTuples()-1); - cellsToModifyConn0_torenum->transformWithIndArr(cellIdsRk1->begin(),cellIdsRk1->end()); - cellsToModifyConn1_torenum->transformWithIndArr(cellIdsRk1->begin(),cellIdsRk1->end()); - // - cellIdsNeededToBeRenum=cellsToModifyConn0_torenum.retn(); - cellIdsNotModified=cellsToModifyConn1_torenum.retn(); - nodeIdsToDuplicate=s3.retn(); -} - -/*! - * This method operates a modification of the connectivity and coords in \b this. - * Every time that a node id in [ \b nodeIdsToDuplicateBg, \b nodeIdsToDuplicateEnd ) will append in nodal connectivity of \b this - * its ids will be modified to id this->getNumberOfNodes()+std::distance(nodeIdsToDuplicateBg,std::find(nodeIdsToDuplicateBg,nodeIdsToDuplicateEnd,id)). - * More explicitely the renumber array in nodes is not explicitely given in old2new to avoid to build a big array of renumbering whereas typically few node ids needs to be - * renumbered. The node id nodeIdsToDuplicateBg[0] will have id this->getNumberOfNodes()+0, node id nodeIdsToDuplicateBg[1] will have id this->getNumberOfNodes()+1, - * node id nodeIdsToDuplicateBg[2] will have id this->getNumberOfNodes()+2... - * - * As a consequence nodal connectivity array length will remain unchanged by this method, and nodal connectivity index array will remain unchanged by this method. - * - * \param [in] nodeIdsToDuplicateBg begin of node ids (included) to be duplicated in connectivity only - * \param [in] nodeIdsToDuplicateEnd end of node ids (excluded) to be duplicated in connectivity only - */ -void MEDCouplingUMesh::duplicateNodes(const int *nodeIdsToDuplicateBg, const int *nodeIdsToDuplicateEnd) -{ - int nbOfNodes=getNumberOfNodes(); - duplicateNodesInCoords(nodeIdsToDuplicateBg,nodeIdsToDuplicateEnd); - duplicateNodesInConn(nodeIdsToDuplicateBg,nodeIdsToDuplicateEnd,nbOfNodes); -} - -/*! - * This method renumbers only nodal connectivity in \a this. The renumbering is only an offset applied. So this method is a specialization of - * \a renumberNodesInConn. \b WARNING, this method does not check that the resulting node ids in the nodal connectivity is in a valid range ! - * - * \param [in] offset - specifies the offset to be applied on each element of connectivity. - * - * \sa renumberNodesInConn - */ -void MEDCouplingUMesh::renumberNodesWithOffsetInConn(int offset) -{ - checkConnectivityFullyDefined(); - int *conn(getNodalConnectivity()->getPointer()); - const int *connIndex(getNodalConnectivityIndex()->getConstPointer()); - int nbOfCells(getNumberOfCells()); - for(int i=0;i=0)//avoid polyhedron separator - { - node+=offset; - } - } - _nodal_connec->declareAsNew(); - updateTime(); -} - -/*! - * Same than renumberNodesInConn(const int *) except that here the format of old-to-new traducer is using map instead - * of array. This method is dedicated for renumbering from a big set of nodes the a tiny set of nodes which is the case during extraction - * of a big mesh. - */ -void MEDCouplingUMesh::renumberNodesInConn(const INTERP_KERNEL::HashMap& newNodeNumbersO2N) -{ - checkConnectivityFullyDefined(); - int *conn(getNodalConnectivity()->getPointer()); - const int *connIndex(getNodalConnectivityIndex()->getConstPointer()); - int nbOfCells(getNumberOfCells()); - for(int i=0;i=0)//avoid polyhedron separator - { - INTERP_KERNEL::HashMap::const_iterator it(newNodeNumbersO2N.find(node)); - if(it!=newNodeNumbersO2N.end()) - { - node=(*it).second; - } - else - { - std::ostringstream oss; oss << "MEDCouplingUMesh::renumberNodesInConn(map) : presence in connectivity for cell #" << i << " of node #" << node << " : Not in map !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - } - } - _nodal_connec->declareAsNew(); - updateTime(); -} - -/*! - * Changes ids of nodes within the nodal connectivity arrays according to a permutation - * array in "Old to New" mode. The node coordinates array is \b not changed by this method. - * This method is a generalization of shiftNodeNumbersInConn(). - * \warning This method performs no check of validity of new ids. **Use it with care !** - * \param [in] newNodeNumbersO2N - a permutation array, of length \a - * this->getNumberOfNodes(), in "Old to New" mode. - * See \ref numbering for more info on renumbering modes. - * \throw If the nodal connectivity of cells is not defined. - * - * \if ENABLE_EXAMPLES - * \ref cpp_mcumesh_renumberNodesInConn "Here is a C++ example".
- * \ref py_mcumesh_renumberNodesInConn "Here is a Python example". - * \endif - */ -void MEDCouplingUMesh::renumberNodesInConn(const int *newNodeNumbersO2N) -{ - checkConnectivityFullyDefined(); - int *conn=getNodalConnectivity()->getPointer(); - const int *connIndex=getNodalConnectivityIndex()->getConstPointer(); - int nbOfCells(getNumberOfCells()); - for(int i=0;i=0)//avoid polyhedron separator - { - node=newNodeNumbersO2N[node]; - } - } - _nodal_connec->declareAsNew(); - updateTime(); -} - -/*! - * This method renumbers nodes \b in \b connectivity \b only \b without \b any \b reference \b to \b coords. - * This method performs no check on the fact that new coordinate ids are valid. \b Use \b it \b with \b care ! - * This method is an specialization of \ref ParaMEDMEM::MEDCouplingUMesh::renumberNodesInConn "renumberNodesInConn method". - * - * \param [in] delta specifies the shift size applied to nodeId in nodal connectivity in \b this. - */ -void MEDCouplingUMesh::shiftNodeNumbersInConn(int delta) -{ - checkConnectivityFullyDefined(); - int *conn=getNodalConnectivity()->getPointer(); - const int *connIndex=getNodalConnectivityIndex()->getConstPointer(); - int nbOfCells=getNumberOfCells(); - for(int i=0;i=0)//avoid polyhedron separator - { - node+=delta; - } - } - _nodal_connec->declareAsNew(); - updateTime(); -} - -/*! - * This method operates a modification of the connectivity in \b this. - * Coordinates are \b NOT considered here and will remain unchanged by this method. this->_coords can ever been null for the needs of this method. - * Every time that a node id in [ \b nodeIdsToDuplicateBg, \b nodeIdsToDuplicateEnd ) will append in nodal connectivity of \b this - * its ids will be modified to id offset+std::distance(nodeIdsToDuplicateBg,std::find(nodeIdsToDuplicateBg,nodeIdsToDuplicateEnd,id)). - * More explicitely the renumber array in nodes is not explicitely given in old2new to avoid to build a big array of renumbering whereas typically few node ids needs to be - * renumbered. The node id nodeIdsToDuplicateBg[0] will have id offset+0, node id nodeIdsToDuplicateBg[1] will have id offset+1, - * node id nodeIdsToDuplicateBg[2] will have id offset+2... - * - * As a consequence nodal connectivity array length will remain unchanged by this method, and nodal connectivity index array will remain unchanged by this method. - * As an another consequense after the call of this method \b this can be transiently non cohrent. - * - * \param [in] nodeIdsToDuplicateBg begin of node ids (included) to be duplicated in connectivity only - * \param [in] nodeIdsToDuplicateEnd end of node ids (excluded) to be duplicated in connectivity only - * \param [in] offset the offset applied to all node ids in connectivity that are in [ \a nodeIdsToDuplicateBg, \a nodeIdsToDuplicateEnd ). - */ -void MEDCouplingUMesh::duplicateNodesInConn(const int *nodeIdsToDuplicateBg, const int *nodeIdsToDuplicateEnd, int offset) -{ - checkConnectivityFullyDefined(); - std::map m; - int val=offset; - for(const int *work=nodeIdsToDuplicateBg;work!=nodeIdsToDuplicateEnd;work++,val++) - m[*work]=val; - int *conn=getNodalConnectivity()->getPointer(); - const int *connIndex=getNodalConnectivityIndex()->getConstPointer(); - int nbOfCells=getNumberOfCells(); - for(int i=0;i=0)//avoid polyhedron separator - { - std::map::iterator it=m.find(node); - if(it!=m.end()) - node=(*it).second; - } - } - updateTime(); -} - -/*! - * This method renumbers cells of \a this using the array specified by [old2NewBg;old2NewBg+getNumberOfCells()) - * - * Contrary to MEDCouplingPointSet::renumberNodes, this method makes a permutation without any fuse of cell. - * After the call of this method the number of cells remains the same as before. - * - * If 'check' equals true the method will check that any elements in [ \a old2NewBg; \a old2NewEnd ) is unique ; if not - * an INTERP_KERNEL::Exception will be thrown. When 'check' equals true [ \a old2NewBg ; \a old2NewEnd ) is not expected to - * be strictly in [0;this->getNumberOfCells()). - * - * If 'check' equals false the method will not check the content of [ \a old2NewBg ; \a old2NewEnd ). - * To avoid any throw of SIGSEGV when 'check' equals false, the elements in [ \a old2NewBg ; \a old2NewEnd ) should be unique and - * should be contained in[0;this->getNumberOfCells()). - * - * \param [in] old2NewBg is expected to be a dynamically allocated pointer of size at least equal to this->getNumberOfCells() - * \param check - */ -void MEDCouplingUMesh::renumberCells(const int *old2NewBg, bool check) -{ - checkConnectivityFullyDefined(); - int nbCells=getNumberOfCells(); - const int *array=old2NewBg; - if(check) - array=DataArrayInt::CheckAndPreparePermutation(old2NewBg,old2NewBg+nbCells); - // - const int *conn=_nodal_connec->getConstPointer(); - const int *connI=_nodal_connec_index->getConstPointer(); - MEDCouplingAutoRefCountObjectPtr o2n=DataArrayInt::New(); o2n->useArray(array,false,C_DEALLOC,nbCells,1); - MEDCouplingAutoRefCountObjectPtr n2o=o2n->invertArrayO2N2N2O(nbCells); - const int *n2oPtr=n2o->begin(); - MEDCouplingAutoRefCountObjectPtr newConn=DataArrayInt::New(); - newConn->alloc(_nodal_connec->getNumberOfTuples(),_nodal_connec->getNumberOfComponents()); - newConn->copyStringInfoFrom(*_nodal_connec); - MEDCouplingAutoRefCountObjectPtr newConnI=DataArrayInt::New(); - newConnI->alloc(_nodal_connec_index->getNumberOfTuples(),_nodal_connec_index->getNumberOfComponents()); - newConnI->copyStringInfoFrom(*_nodal_connec_index); - // - int *newC=newConn->getPointer(); - int *newCI=newConnI->getPointer(); - int loc=0; - newCI[0]=loc; - for(int i=0;i(array)); -} - -/*! - * Finds cells whose bounding boxes intersect a given bounding box. - * \param [in] bbox - an array defining the bounding box via coordinates of its - * extremum points in "no interlace" mode, i.e. xMin, xMax, yMin, yMax, zMin, - * zMax (if in 3D). - * \param [in] eps - a factor used to increase size of the bounding box of cell - * before comparing it with \a bbox. This factor is multiplied by the maximal - * extent of the bounding box of cell to produce an addition to this bounding box. - * \return DataArrayInt * - a new instance of DataArrayInt holding ids for found - * cells. The caller is to delete this array using decrRef() as it is no more - * needed. - * \throw If the coordinates array is not set. - * \throw If the nodal connectivity of cells is not defined. - * - * \if ENABLE_EXAMPLES - * \ref cpp_mcumesh_getCellsInBoundingBox "Here is a C++ example".
- * \ref py_mcumesh_getCellsInBoundingBox "Here is a Python example". - * \endif - */ -DataArrayInt *MEDCouplingUMesh::getCellsInBoundingBox(const double *bbox, double eps) const -{ - MEDCouplingAutoRefCountObjectPtr elems=DataArrayInt::New(); elems->alloc(0,1); - if(getMeshDimension()==-1) - { - elems->pushBackSilent(0); - return elems.retn(); - } - int dim=getSpaceDimension(); - INTERP_KERNEL::AutoPtr elem_bb=new double[2*dim]; - const int* conn = getNodalConnectivity()->getConstPointer(); - const int* conn_index= getNodalConnectivityIndex()->getConstPointer(); - const double* coords = getCoords()->getConstPointer(); - int nbOfCells=getNumberOfCells(); - for ( int ielem=0; ielem::max(); - elem_bb[i*2+1]=-std::numeric_limits::max(); - } - - for (int inode=conn_index[ielem]+1; inode=0)//avoid polyhedron separator - { - for (int idim=0; idim elem_bb[idim*2+1] ) - { - elem_bb[idim*2+1] = coords[node*dim+idim] ; - } - } - } - } - if (intersectsBoundingBox(elem_bb, bbox, dim, eps)) - elems->pushBackSilent(ielem); - } - return elems.retn(); -} - -/*! - * Given a boundary box 'bbox' returns elements 'elems' contained in this 'bbox' or touching 'bbox' (within 'eps' distance). - * Warning 'elems' is incremented during the call so if elems is not empty before call returned elements will be - * added in 'elems' parameter. - */ -DataArrayInt *MEDCouplingUMesh::getCellsInBoundingBox(const INTERP_KERNEL::DirectedBoundingBox& bbox, double eps) -{ - MEDCouplingAutoRefCountObjectPtr elems=DataArrayInt::New(); elems->alloc(0,1); - if(getMeshDimension()==-1) - { - elems->pushBackSilent(0); - return elems.retn(); - } - int dim=getSpaceDimension(); - INTERP_KERNEL::AutoPtr elem_bb=new double[2*dim]; - const int* conn = getNodalConnectivity()->getConstPointer(); - const int* conn_index= getNodalConnectivityIndex()->getConstPointer(); - const double* coords = getCoords()->getConstPointer(); - int nbOfCells=getNumberOfCells(); - for ( int ielem=0; ielem::max(); - elem_bb[i*2+1]=-std::numeric_limits::max(); - } - - for (int inode=conn_index[ielem]+1; inode=0)//avoid polyhedron separator - { - for (int idim=0; idim elem_bb[idim*2+1] ) - { - elem_bb[idim*2+1] = coords[node*dim+idim] ; - } - } - } - } - if(intersectsBoundingBox(bbox, elem_bb, dim, eps)) - elems->pushBackSilent(ielem); - } - return elems.retn(); -} - -/*! - * Returns a type of a cell by its id. - * \param [in] cellId - the id of the cell of interest. - * \return INTERP_KERNEL::NormalizedCellType - enumeration item describing the cell type. - * \throw If \a cellId is invalid. Valid range is [0, \a this->getNumberOfCells() ). - */ -INTERP_KERNEL::NormalizedCellType MEDCouplingUMesh::getTypeOfCell(int cellId) const -{ - const int *ptI=_nodal_connec_index->getConstPointer(); - const int *pt=_nodal_connec->getConstPointer(); - if(cellId>=0 && cellId<(int)_nodal_connec_index->getNbOfElems()-1) - return (INTERP_KERNEL::NormalizedCellType) pt[ptI[cellId]]; - else - { - std::ostringstream oss; oss << "MEDCouplingUMesh::getTypeOfCell : Requesting type of cell #" << cellId << " but it should be in [0," << _nodal_connec_index->getNbOfElems()-1 << ") !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } -} - -/*! - * This method returns a newly allocated array containing cell ids (ascendingly sorted) whose geometric type are equal to type. - * This method does not throw exception if geometric type \a type is not in \a this. - * This method throws an INTERP_KERNEL::Exception if meshdimension of \b this is not equal to those of \b type. - * The coordinates array is not considered here. - * - * \param [in] type the geometric type - * \return cell ids in this having geometric type \a type. - */ -DataArrayInt *MEDCouplingUMesh::giveCellsWithType(INTERP_KERNEL::NormalizedCellType type) const -{ - - MEDCouplingAutoRefCountObjectPtr ret=DataArrayInt::New(); - ret->alloc(0,1); - checkConnectivityFullyDefined(); - int nbCells=getNumberOfCells(); - int mdim=getMeshDimension(); - const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(type); - if(mdim!=(int)cm.getDimension()) - throw INTERP_KERNEL::Exception("MEDCouplingUMesh::giveCellsWithType : Mismatch between mesh dimension and dimension of the cell !"); - const int *ptI=_nodal_connec_index->getConstPointer(); - const int *pt=_nodal_connec->getConstPointer(); - for(int i=0;ipushBackSilent(i); - } - return ret.retn(); -} - -/*! - * Returns nb of cells having the geometric type \a type. No throw if no cells in \a this has the geometric type \a type. - */ -int MEDCouplingUMesh::getNumberOfCellsWithType(INTERP_KERNEL::NormalizedCellType type) const -{ - const int *ptI=_nodal_connec_index->getConstPointer(); - const int *pt=_nodal_connec->getConstPointer(); - int nbOfCells=getNumberOfCells(); - int ret=0; - for(int i=0;igetNumberOfCells() ). - */ -void MEDCouplingUMesh::getNodeIdsOfCell(int cellId, std::vector& conn) const -{ - const int *ptI=_nodal_connec_index->getConstPointer(); - const int *pt=_nodal_connec->getConstPointer(); - for(const int *w=pt+ptI[cellId]+1;w!=pt+ptI[cellId+1];w++) - if(*w>=0) - conn.push_back(*w); -} - -std::string MEDCouplingUMesh::simpleRepr() const -{ - static const char msg0[]="No coordinates specified !"; - std::ostringstream ret; - ret << "Unstructured 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"; - if(_mesh_dim>=-1) - { ret << "Mesh dimension : " << _mesh_dim << "\nSpace dimension : "; } - else - { ret << " Mesh dimension has not been set or is invalid !"; } - if(_coords!=0) - { - const int spaceDim=getSpaceDimension(); - ret << spaceDim << "\nInfo attached on space dimension : "; - for(int i=0;igetInfoOnComponent(i) << "\" "; - ret << "\n"; - } - else - ret << msg0 << "\n"; - ret << "Number of nodes : "; - if(_coords!=0) - ret << getNumberOfNodes() << "\n"; - else - ret << msg0 << "\n"; - ret << "Number of cells : "; - if(_nodal_connec!=0 && _nodal_connec_index!=0) - ret << getNumberOfCells() << "\n"; - else - ret << "No connectivity specified !" << "\n"; - ret << "Cell types present : "; - for(std::set::const_iterator iter=_types.begin();iter!=_types.end();iter++) - { - const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(*iter); - ret << cm.getRepr() << " "; - } - ret << "\n"; - return ret.str(); -} - -std::string MEDCouplingUMesh::advancedRepr() const -{ - std::ostringstream ret; - ret << simpleRepr(); - ret << "\nCoordinates array : \n___________________\n\n"; - if(_coords) - _coords->reprWithoutNameStream(ret); - else - ret << "No array set !\n"; - ret << "\n\nConnectivity arrays : \n_____________________\n\n"; - reprConnectivityOfThisLL(ret); - return ret.str(); -} - -/*! - * This method returns a C++ code that is a dump of \a this. - * This method will throw if this is not fully defined. - */ -std::string MEDCouplingUMesh::cppRepr() const -{ - static const char coordsName[]="coords"; - static const char connName[]="conn"; - static const char connIName[]="connI"; - checkFullyDefined(); - std::ostringstream ret; ret << "// coordinates" << std::endl; - _coords->reprCppStream(coordsName,ret); ret << std::endl << "// connectivity" << std::endl; - _nodal_connec->reprCppStream(connName,ret); ret << std::endl; - _nodal_connec_index->reprCppStream(connIName,ret); ret << std::endl; - ret << "MEDCouplingUMesh *mesh=MEDCouplingUMesh::New(\"" << getName() << "\"," << getMeshDimension() << ");" << std::endl; - ret << "mesh->setCoords(" << coordsName << ");" << std::endl; - ret << "mesh->setConnectivity(" << connName << "," << connIName << ",true);" << std::endl; - ret << coordsName << "->decrRef(); " << connName << "->decrRef(); " << connIName << "->decrRef();" << std::endl; - return ret.str(); -} - -std::string MEDCouplingUMesh::reprConnectivityOfThis() const -{ - std::ostringstream ret; - reprConnectivityOfThisLL(ret); - return ret.str(); -} - -/*! - * This method builds a newly allocated instance (with the same name than \a this) that the caller has the responsability to deal with. - * This method returns an instance with all arrays allocated (connectivity, connectivity index, coordinates) - * but with length of these arrays set to 0. It allows to define an "empty" mesh (with nor cells nor nodes but compliant with - * some algos). - * - * This method expects that \a this has a mesh dimension set and higher or equal to 0. If not an exception will be thrown. - * This method analyzes the 3 arrays of \a this. For each the following behaviour is done : if the array is null a newly one is created - * with number of tuples set to 0, if not the array is taken as this in the returned instance. - */ -MEDCouplingUMesh *MEDCouplingUMesh::buildSetInstanceFromThis(int spaceDim) const -{ - int mdim=getMeshDimension(); - if(mdim<0) - throw INTERP_KERNEL::Exception("MEDCouplingUMesh::buildSetInstanceFromThis : invalid mesh dimension ! Should be >= 0 !"); - MEDCouplingAutoRefCountObjectPtr ret=MEDCouplingUMesh::New(getName(),mdim); - MEDCouplingAutoRefCountObjectPtr tmp1,tmp2; - bool needToCpyCT=true; - if(!_nodal_connec) - { - tmp1=DataArrayInt::New(); tmp1->alloc(0,1); - needToCpyCT=false; - } - else - { - tmp1=_nodal_connec; - tmp1->incrRef(); - } - if(!_nodal_connec_index) - { - tmp2=DataArrayInt::New(); tmp2->alloc(1,1); tmp2->setIJ(0,0,0); - needToCpyCT=false; - } - else - { - tmp2=_nodal_connec_index; - tmp2->incrRef(); - } - ret->setConnectivity(tmp1,tmp2,false); - if(needToCpyCT) - ret->_types=_types; - if(!_coords) - { - MEDCouplingAutoRefCountObjectPtr coords=DataArrayDouble::New(); coords->alloc(0,spaceDim); - ret->setCoords(coords); - } - else - ret->setCoords(_coords); - return ret.retn(); -} - -void MEDCouplingUMesh::reprConnectivityOfThisLL(std::ostringstream& stream) const -{ - if(_nodal_connec!=0 && _nodal_connec_index!=0) - { - int nbOfCells=getNumberOfCells(); - const int *c=_nodal_connec->getConstPointer(); - const int *ci=_nodal_connec_index->getConstPointer(); - for(int i=0;i(stream," ")); - stream << "\n"; - } - } - else - stream << "Connectivity not defined !\n"; -} - -int MEDCouplingUMesh::getNumberOfNodesInCell(int cellId) const -{ - const int *ptI=_nodal_connec_index->getConstPointer(); - const int *pt=_nodal_connec->getConstPointer(); - if(pt[ptI[cellId]]!=INTERP_KERNEL::NORM_POLYHED) - return ptI[cellId+1]-ptI[cellId]-1; - else - return (int)std::count_if(pt+ptI[cellId]+1,pt+ptI[cellId+1],std::bind2nd(std::not_equal_to(),-1)); -} - -/*! - * Returns types of cells of the specified part of \a this mesh. - * This method avoids computing sub-mesh explicitely to get its types. - * \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. - * \return std::set - a set of enumeration items - * describing the cell types. - * \throw If the coordinates array is not set. - * \throw If the nodal connectivity of cells is not defined. - * \sa getAllGeoTypes() - */ -std::set MEDCouplingUMesh::getTypesOfPart(const int *begin, const int *end) const -{ - checkFullyDefined(); - std::set ret; - const int *conn=_nodal_connec->getConstPointer(); - const int *connIndex=_nodal_connec_index->getConstPointer(); - for(const int *w=begin;w!=end;w++) - ret.insert((INTERP_KERNEL::NormalizedCellType)conn[connIndex[*w]]); - return ret; -} - -/*! - * Defines the nodal connectivity using given connectivity arrays in \ref numbering-indirect format. - * Optionally updates - * a set of types of cells constituting \a this mesh. - * This method is for advanced users having prepared their connectivity before. For - * more info on using this method see \ref MEDCouplingUMeshAdvBuild. - * \param [in] conn - the nodal connectivity array. - * \param [in] connIndex - the nodal connectivity index array. - * \param [in] isComputingTypes - if \c true, the set of types constituting \a this - * mesh is updated. - */ -void MEDCouplingUMesh::setConnectivity(DataArrayInt *conn, DataArrayInt *connIndex, bool isComputingTypes) -{ - DataArrayInt::SetArrayIn(conn,_nodal_connec); - DataArrayInt::SetArrayIn(connIndex,_nodal_connec_index); - if(isComputingTypes) - computeTypes(); - declareAsNew(); -} - -/*! - * Copy constructor. If 'deepCpy' is false \a this is a shallow copy of other. - * If 'deeCpy' is true all arrays (coordinates and connectivities) are deeply copied. - */ -MEDCouplingUMesh::MEDCouplingUMesh(const MEDCouplingUMesh& other, bool deepCopy):MEDCouplingPointSet(other,deepCopy),_mesh_dim(other._mesh_dim), - _nodal_connec(0),_nodal_connec_index(0), - _types(other._types) -{ - if(other._nodal_connec) - _nodal_connec=other._nodal_connec->performCpy(deepCopy); - if(other._nodal_connec_index) - _nodal_connec_index=other._nodal_connec_index->performCpy(deepCopy); -} - -MEDCouplingUMesh::~MEDCouplingUMesh() -{ - if(_nodal_connec) - _nodal_connec->decrRef(); - if(_nodal_connec_index) - _nodal_connec_index->decrRef(); -} - -/*! - * Recomputes a set of cell types of \a this mesh. For more info see - * \ref MEDCouplingUMeshNodalConnectivity. - */ -void MEDCouplingUMesh::computeTypes() -{ - ComputeAllTypesInternal(_types,_nodal_connec,_nodal_connec_index); -} - -/*! - * This method checks that all arrays are set. If yes nothing done if no an exception is thrown. - */ -void MEDCouplingUMesh::checkFullyDefined() const -{ - if(!_nodal_connec_index || !_nodal_connec || !_coords) - throw INTERP_KERNEL::Exception("Reverse nodal connectivity computation requires full connectivity and coordinates set in unstructured mesh."); -} - -/*! - * This method checks that all connectivity arrays are set. If yes nothing done if no an exception is thrown. - */ -void MEDCouplingUMesh::checkConnectivityFullyDefined() const -{ - if(!_nodal_connec_index || !_nodal_connec) - throw INTERP_KERNEL::Exception("Reverse nodal connectivity computation requires full connectivity set in unstructured mesh."); -} - -/*! - * Returns a number of cells constituting \a this mesh. - * \return int - the number of cells in \a this mesh. - * \throw If the nodal connectivity of cells is not defined. - */ -int MEDCouplingUMesh::getNumberOfCells() const -{ - if(_nodal_connec_index) - return _nodal_connec_index->getNumberOfTuples()-1; - else - if(_mesh_dim==-1) - return 1; - else - throw INTERP_KERNEL::Exception("Unable to get number of cells because no connectivity specified !"); -} - -/*! - * Returns a dimension of \a this mesh, i.e. a dimension of cells constituting \a this - * mesh. For more info see \ref meshes. - * \return int - the dimension of \a this mesh. - * \throw If the mesh dimension is not defined using setMeshDimension(). - */ -int MEDCouplingUMesh::getMeshDimension() const -{ - if(_mesh_dim<-1) - throw INTERP_KERNEL::Exception("No mesh dimension specified !"); - return _mesh_dim; -} - -/*! - * Returns a length of the nodal connectivity array. - * This method is for test reason. Normally the integer returned is not useable by - * user. For more info see \ref MEDCouplingUMeshNodalConnectivity. - * \return int - the length of the nodal connectivity array. - */ -int MEDCouplingUMesh::getMeshLength() const -{ - return _nodal_connec->getNbOfElems(); -} - -/*! - * First step of serialization process. Used by ParaMEDMEM and MEDCouplingCorba to transfert data between process. - */ -void MEDCouplingUMesh::getTinySerializationInformation(std::vector& tinyInfoD, std::vector& tinyInfo, std::vector& littleStrings) const -{ - MEDCouplingPointSet::getTinySerializationInformation(tinyInfoD,tinyInfo,littleStrings); - tinyInfo.push_back(getMeshDimension()); - tinyInfo.push_back(getNumberOfCells()); - if(_nodal_connec) - tinyInfo.push_back(getMeshLength()); - else - tinyInfo.push_back(-1); -} - -/*! - * First step of unserialization process. - */ -bool MEDCouplingUMesh::isEmptyMesh(const std::vector& tinyInfo) const -{ - return tinyInfo[6]<=0; -} - -/*! - * Second step of serialization process. - * \param tinyInfo must be equal to the result given by getTinySerializationInformation method. - * \param a1 - * \param a2 - * \param littleStrings - */ -void MEDCouplingUMesh::resizeForUnserialization(const std::vector& tinyInfo, DataArrayInt *a1, DataArrayDouble *a2, std::vector& littleStrings) const -{ - MEDCouplingPointSet::resizeForUnserialization(tinyInfo,a1,a2,littleStrings); - if(tinyInfo[5]!=-1) - a1->alloc(tinyInfo[7]+tinyInfo[6]+1,1); -} - -/*! - * Third and final step of serialization process. - */ -void MEDCouplingUMesh::serialize(DataArrayInt *&a1, DataArrayDouble *&a2) const -{ - MEDCouplingPointSet::serialize(a1,a2); - if(getMeshDimension()>-1) - { - a1=DataArrayInt::New(); - a1->alloc(getMeshLength()+getNumberOfCells()+1,1); - int *ptA1=a1->getPointer(); - const int *conn=getNodalConnectivity()->getConstPointer(); - const int *index=getNodalConnectivityIndex()->getConstPointer(); - ptA1=std::copy(index,index+getNumberOfCells()+1,ptA1); - std::copy(conn,conn+getMeshLength(),ptA1); - } - else - a1=0; -} - -/*! - * Second and final unserialization process. - * \param tinyInfo must be equal to the result given by getTinySerializationInformation method. - */ -void MEDCouplingUMesh::unserialization(const std::vector& tinyInfoD, const std::vector& tinyInfo, const DataArrayInt *a1, DataArrayDouble *a2, const std::vector& littleStrings) -{ - MEDCouplingPointSet::unserialization(tinyInfoD,tinyInfo,a1,a2,littleStrings); - setMeshDimension(tinyInfo[5]); - if(tinyInfo[7]!=-1) - { - // Connectivity - const int *recvBuffer=a1->getConstPointer(); - MEDCouplingAutoRefCountObjectPtr myConnecIndex=DataArrayInt::New(); - myConnecIndex->alloc(tinyInfo[6]+1,1); - std::copy(recvBuffer,recvBuffer+tinyInfo[6]+1,myConnecIndex->getPointer()); - MEDCouplingAutoRefCountObjectPtr myConnec=DataArrayInt::New(); - myConnec->alloc(tinyInfo[7],1); - std::copy(recvBuffer+tinyInfo[6]+1,recvBuffer+tinyInfo[6]+1+tinyInfo[7],myConnec->getPointer()); - setConnectivity(myConnec, myConnecIndex); - } -} - -/*! - * This is the low algorithm of MEDCouplingUMesh::buildPartOfMySelf2. - * CellIds are given using range specified by a start an end and step. - */ -MEDCouplingPointSet *MEDCouplingUMesh::buildPartOfMySelfKeepCoords2(int start, int end, int step) const -{ - checkFullyDefined(); - int ncell=getNumberOfCells(); - MEDCouplingAutoRefCountObjectPtr ret=MEDCouplingUMesh::New(); - ret->_mesh_dim=_mesh_dim; - ret->setCoords(_coords); - int newNbOfCells=DataArray::GetNumberOfItemGivenBESRelative(start,end,step,"MEDCouplingUMesh::buildPartOfMySelfKeepCoords2 : "); - MEDCouplingAutoRefCountObjectPtr newConnI=DataArrayInt::New(); newConnI->alloc(newNbOfCells+1,1); - int *newConnIPtr=newConnI->getPointer(); *newConnIPtr=0; - int work=start; - const int *conn=_nodal_connec->getConstPointer(); - const int *connIndex=_nodal_connec_index->getConstPointer(); - for(int i=0;i=0 && work newConn=DataArrayInt::New(); newConn->alloc(newConnIPtr[0],1); - int *newConnPtr=newConn->getPointer(); - std::set types; - work=start; - for(int i=0;isetConnectivity(newConn,newConnI,false); - ret->_types=types; - ret->copyTinyInfoFrom(this); - return ret.retn(); -} - -/*! - * This is the low algorithm of MEDCouplingUMesh::buildPartOfMySelf. - * Keeps from \a this only cells which constituing point id are in the ids specified by [ \a begin,\a end ). - * The return newly allocated mesh will share the same coordinates as \a this. - */ -MEDCouplingPointSet *MEDCouplingUMesh::buildPartOfMySelfKeepCoords(const int *begin, const int *end) const -{ - checkConnectivityFullyDefined(); - int ncell=getNumberOfCells(); - MEDCouplingAutoRefCountObjectPtr ret=MEDCouplingUMesh::New(); - ret->_mesh_dim=_mesh_dim; - ret->setCoords(_coords); - std::size_t nbOfElemsRet=std::distance(begin,end); - int *connIndexRet=(int *)malloc((nbOfElemsRet+1)*sizeof(int)); - connIndexRet[0]=0; - const int *conn=_nodal_connec->getConstPointer(); - const int *connIndex=_nodal_connec_index->getConstPointer(); - int newNbring=0; - for(const int *work=begin;work!=end;work++,newNbring++) - { - if(*work>=0 && *work types; - for(const int *work=begin;work!=end;work++) - { - types.insert((INTERP_KERNEL::NormalizedCellType)conn[connIndex[*work]]); - connRetWork=std::copy(conn+connIndex[*work],conn+connIndex[*work+1],connRetWork); - } - MEDCouplingAutoRefCountObjectPtr connRetArr=DataArrayInt::New(); - connRetArr->useArray(connRet,true,C_DEALLOC,connIndexRet[nbOfElemsRet],1); - MEDCouplingAutoRefCountObjectPtr connIndexRetArr=DataArrayInt::New(); - connIndexRetArr->useArray(connIndexRet,true,C_DEALLOC,(int)nbOfElemsRet+1,1); - ret->setConnectivity(connRetArr,connIndexRetArr,false); - ret->_types=types; - ret->copyTinyInfoFrom(this); - return ret.retn(); -} - -/*! - * 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 - 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 on cells - * and one time . The caller is to delete this field using decrRef() as it is no - * more needed. - */ -MEDCouplingFieldDouble *MEDCouplingUMesh::getMeasureField(bool isAbs) const -{ - std::string name="MeasureOfMesh_"; - name+=getName(); - int nbelem=getNumberOfCells(); - MEDCouplingAutoRefCountObjectPtr field=MEDCouplingFieldDouble::New(ON_CELLS,ONE_TIME); - field->setName(name); - MEDCouplingAutoRefCountObjectPtr array=DataArrayDouble::New(); - array->alloc(nbelem,1); - double *area_vol=array->getPointer(); - field->setArray(array) ; array=0; - field->setMesh(const_cast(this)); - field->synchronizeTimeWithMesh(); - if(getMeshDimension()!=-1) - { - int ipt; - INTERP_KERNEL::NormalizedCellType type; - int dim_space=getSpaceDimension(); - const double *coords=getCoords()->getConstPointer(); - const int *connec=getNodalConnectivity()->getConstPointer(); - const int *connec_index=getNodalConnectivityIndex()->getConstPointer(); - for(int iel=0;iel(type,connec+ipt+1,connec_index[iel+1]-ipt-1,coords,dim_space); - } - if(isAbs) - std::transform(area_vol,area_vol+nbelem,area_vol,std::ptr_fun(fabs)); - } - else - { - area_vol[0]=std::numeric_limits::max(); - } - return field.retn(); -} - -/*! - * Returns a new DataArrayDouble containing volumes of specified cells of \a this - * mesh.
- * For 1D cells, the returned array contains lengths.
- * For 2D cells, the returned array contains areas.
- * For 3D cells, the returned array contains volumes. - * This method avoids building explicitly a part of \a this mesh to perform the work. - * \param [in] isAbs - if \c true, the computed cell volume does not reflect cell - * orientation, i.e. the volume is always positive. - * \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. - * \return DataArrayDouble * - a new instance of DataArrayDouble. The caller is to - * delete this array using decrRef() as it is no more needed. - * - * \if ENABLE_EXAMPLES - * \ref cpp_mcumesh_getPartMeasureField "Here is a C++ example".
- * \ref py_mcumesh_getPartMeasureField "Here is a Python example". - * \endif - * \sa getMeasureField() - */ -DataArrayDouble *MEDCouplingUMesh::getPartMeasureField(bool isAbs, const int *begin, const int *end) const -{ - std::string name="PartMeasureOfMesh_"; - name+=getName(); - int nbelem=(int)std::distance(begin,end); - MEDCouplingAutoRefCountObjectPtr array=DataArrayDouble::New(); - array->setName(name); - array->alloc(nbelem,1); - double *area_vol=array->getPointer(); - if(getMeshDimension()!=-1) - { - int ipt; - INTERP_KERNEL::NormalizedCellType type; - int dim_space=getSpaceDimension(); - const double *coords=getCoords()->getConstPointer(); - const int *connec=getNodalConnectivity()->getConstPointer(); - const int *connec_index=getNodalConnectivityIndex()->getConstPointer(); - for(const int *iel=begin;iel!=end;iel++) - { - ipt=connec_index[*iel]; - type=(INTERP_KERNEL::NormalizedCellType)connec[ipt]; - *area_vol++=INTERP_KERNEL::computeVolSurfOfCell2(type,connec+ipt+1,connec_index[*iel+1]-ipt-1,coords,dim_space); - } - if(isAbs) - std::transform(array->getPointer(),area_vol,array->getPointer(),std::ptr_fun(fabs)); - } - else - { - area_vol[0]=std::numeric_limits::max(); - } - return array.retn(); -} - -/*! - * Returns a new MEDCouplingFieldDouble containing volumes of cells of a dual mesh of - * \a this one. The returned field contains the dual cell volume for each corresponding - * node in \a this mesh. In other words, the field returns the getMeasureField() of - * the dual mesh in P1 sens of \a this.
- * For 1D cells, the returned field contains lengths.
- * For 2D cells, the returned field contains areas.
- * For 3D cells, the returned field contains volumes. - * This method is useful to check "P1*" conservative interpolators. - * \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 on - * nodes and one time. The caller is to delete this array using decrRef() as - * it is no more needed. - */ -MEDCouplingFieldDouble *MEDCouplingUMesh::getMeasureFieldOnNode(bool isAbs) const -{ - MEDCouplingAutoRefCountObjectPtr tmp=getMeasureField(isAbs); - std::string name="MeasureOnNodeOfMesh_"; - name+=getName(); - int nbNodes=getNumberOfNodes(); - MEDCouplingAutoRefCountObjectPtr ret=MEDCouplingFieldDouble::New(ON_NODES); - double cst=1./((double)getMeshDimension()+1.); - MEDCouplingAutoRefCountObjectPtr array=DataArrayDouble::New(); - array->alloc(nbNodes,1); - double *valsToFill=array->getPointer(); - std::fill(valsToFill,valsToFill+nbNodes,0.); - const double *values=tmp->getArray()->getConstPointer(); - MEDCouplingAutoRefCountObjectPtr da=DataArrayInt::New(); - MEDCouplingAutoRefCountObjectPtr daInd=DataArrayInt::New(); - getReverseNodalConnectivity(da,daInd); - const int *daPtr=da->getConstPointer(); - const int *daIPtr=daInd->getConstPointer(); - for(int i=0;isetMesh(this); - ret->setArray(array); - return ret.retn(); -} - -/*! - * Returns a new MEDCouplingFieldDouble holding normal vectors to cells of \a this - * mesh. The returned normal vectors to each cell have a norm2 equal to 1. - * The computed vectors have this->getMeshDimension()+1 components - * and are normalized. - *
\a this can be either - * - a 2D mesh in 2D or 3D space or - * - an 1D mesh in 2D space. - * - * \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 the nodal connectivity of cells is not defined. - * \throw If the coordinates array is not set. - * \throw If the mesh dimension is not set. - * \throw If the mesh and space dimension is not as specified above. - */ -MEDCouplingFieldDouble *MEDCouplingUMesh::buildOrthogonalField() const -{ - if((getMeshDimension()!=2) && (getMeshDimension()!=1 || getSpaceDimension()!=2)) - throw INTERP_KERNEL::Exception("Expected a umesh with ( meshDim == 2 spaceDim == 2 or 3 ) or ( meshDim == 1 spaceDim == 2 ) !"); - MEDCouplingAutoRefCountObjectPtr ret=MEDCouplingFieldDouble::New(ON_CELLS,ONE_TIME); - MEDCouplingAutoRefCountObjectPtr array=DataArrayDouble::New(); - int nbOfCells=getNumberOfCells(); - int nbComp=getMeshDimension()+1; - array->alloc(nbOfCells,nbComp); - double *vals=array->getPointer(); - const int *connI=_nodal_connec_index->getConstPointer(); - const int *conn=_nodal_connec->getConstPointer(); - const double *coords=_coords->getConstPointer(); - if(getMeshDimension()==2) - { - if(getSpaceDimension()==3) - { - MEDCouplingAutoRefCountObjectPtr loc=getBarycenterAndOwner(); - const double *locPtr=loc->getConstPointer(); - for(int i=0;i(locPtr+3*i,coords+3*conn[offset+1],coords+3*conn[offset+2],vals); - double n=INTERP_KERNEL::norm<3>(vals); - std::transform(vals,vals+3,vals,std::bind2nd(std::multiplies(),1./n)); - } - } - else - { - MEDCouplingAutoRefCountObjectPtr isAbs=getMeasureField(false); - const double *isAbsPtr=isAbs->getArray()->begin(); - for(int i=0;i0.?1.:-1.; } - } - } - else//meshdimension==1 - { - double tmp[2]; - for(int i=0;i()); - double n=INTERP_KERNEL::norm<2>(tmp); - std::transform(tmp,tmp+2,tmp,std::bind2nd(std::multiplies(),1./n)); - *vals++=-tmp[1]; - *vals++=tmp[0]; - } - } - ret->setArray(array); - ret->setMesh(this); - ret->synchronizeTimeWithSupport(); - return ret.retn(); -} - -/*! - * Returns a new MEDCouplingFieldDouble holding normal vectors to specified cells of - * \a this mesh. The computed vectors have this->getMeshDimension()+1 components - * and are normalized. - *
\a this can be either - * - a 2D mesh in 2D or 3D space or - * - an 1D mesh in 2D space. - * - * This method avoids building explicitly a part of \a this mesh to perform the work. - * \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. - * \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 the nodal connectivity of cells is not defined. - * \throw If the coordinates array is not set. - * \throw If the mesh dimension is not set. - * \throw If the mesh and space dimension is not as specified above. - * \sa buildOrthogonalField() - * - * \if ENABLE_EXAMPLES - * \ref cpp_mcumesh_buildPartOrthogonalField "Here is a C++ example".
- * \ref py_mcumesh_buildPartOrthogonalField "Here is a Python example". - * \endif - */ -MEDCouplingFieldDouble *MEDCouplingUMesh::buildPartOrthogonalField(const int *begin, const int *end) const -{ - if((getMeshDimension()!=2) && (getMeshDimension()!=1 || getSpaceDimension()!=2)) - throw INTERP_KERNEL::Exception("Expected a umesh with ( meshDim == 2 spaceDim == 2 or 3 ) or ( meshDim == 1 spaceDim == 2 ) !"); - MEDCouplingAutoRefCountObjectPtr ret=MEDCouplingFieldDouble::New(ON_CELLS,ONE_TIME); - MEDCouplingAutoRefCountObjectPtr array=DataArrayDouble::New(); - std::size_t nbelems=std::distance(begin,end); - int nbComp=getMeshDimension()+1; - array->alloc((int)nbelems,nbComp); - double *vals=array->getPointer(); - const int *connI=_nodal_connec_index->getConstPointer(); - const int *conn=_nodal_connec->getConstPointer(); - const double *coords=_coords->getConstPointer(); - if(getMeshDimension()==2) - { - if(getSpaceDimension()==3) - { - MEDCouplingAutoRefCountObjectPtr loc=getPartBarycenterAndOwner(begin,end); - const double *locPtr=loc->getConstPointer(); - for(const int *i=begin;i!=end;i++,vals+=3,locPtr+=3) - { - int offset=connI[*i]; - INTERP_KERNEL::crossprod<3>(locPtr,coords+3*conn[offset+1],coords+3*conn[offset+2],vals); - double n=INTERP_KERNEL::norm<3>(vals); - std::transform(vals,vals+3,vals,std::bind2nd(std::multiplies(),1./n)); - } - } - else - { - for(std::size_t i=0;i()); - double n=INTERP_KERNEL::norm<2>(tmp); - std::transform(tmp,tmp+2,tmp,std::bind2nd(std::multiplies(),1./n)); - *vals++=-tmp[1]; - *vals++=tmp[0]; - } - } - ret->setArray(array); - ret->setMesh(this); - ret->synchronizeTimeWithSupport(); - return ret.retn(); -} - -/*! - * Returns a new MEDCouplingFieldDouble holding a direction vector for each SEG2 in \a - * this 1D mesh. The computed vectors have this->getSpaceDimension() components - * and are \b not 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 the nodal connectivity of cells is not defined. - * \throw If the coordinates array is not set. - * \throw If \a this->getMeshDimension() != 1. - * \throw If \a this mesh includes cells of type other than SEG2. - */ -MEDCouplingFieldDouble *MEDCouplingUMesh::buildDirectionVectorField() const -{ - if(getMeshDimension()!=1) - throw INTERP_KERNEL::Exception("Expected a umesh with meshDim == 1 for buildDirectionVectorField !"); - if(_types.size()!=1 || *(_types.begin())!=INTERP_KERNEL::NORM_SEG2) - throw INTERP_KERNEL::Exception("Expected a umesh with only NORM_SEG2 type of elements for buildDirectionVectorField !"); - MEDCouplingAutoRefCountObjectPtr ret=MEDCouplingFieldDouble::New(ON_CELLS,ONE_TIME); - MEDCouplingAutoRefCountObjectPtr array=DataArrayDouble::New(); - int nbOfCells=getNumberOfCells(); - int spaceDim=getSpaceDimension(); - array->alloc(nbOfCells,spaceDim); - double *pt=array->getPointer(); - const double *coo=getCoords()->getConstPointer(); - std::vector conn; - conn.reserve(2); - for(int i=0;i()); - } - ret->setArray(array); - ret->setMesh(this); - ret->synchronizeTimeWithSupport(); - return ret.retn(); -} - -/*! - * Creates a 2D mesh by cutting \a this 3D mesh with a plane. In addition to the mesh, - * returns a new DataArrayInt, of length equal to the number of 2D cells in the result - * mesh, holding, for each cell in the result mesh, an id of a 3D cell it comes - * from. If a result face is shared by two 3D cells, then the face in included twice in - * the result mesh. - * \param [in] origin - 3 components of a point defining location of the plane. - * \param [in] vec - 3 components of a vector normal to the plane. Vector magnitude - * must be greater than 1e-6. - * \param [in] eps - half-thickness of the plane. - * \param [out] cellIds - a new instance of DataArrayInt holding ids of 3D cells - * producing correspondent 2D cells. The caller is to delete this array - * using decrRef() as it is no more needed. - * \return MEDCouplingUMesh * - a new instance of MEDCouplingUMesh. This mesh does - * not share 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 not defined. - * \throw If \a this->getMeshDimension() != 3 or \a this->getSpaceDimension() != 3. - * \throw If magnitude of \a vec is less than 1e-6. - * \throw If the plane does not intersect any 3D cell of \a this mesh. - * \throw If \a this includes quadratic cells. - */ -MEDCouplingUMesh *MEDCouplingUMesh::buildSlice3D(const double *origin, const double *vec, double eps, DataArrayInt *&cellIds) const -{ - checkFullyDefined(); - if(getMeshDimension()!=3 || getSpaceDimension()!=3) - throw INTERP_KERNEL::Exception("MEDCouplingUMesh::buildSlice3D works on umeshes with meshdim equal to 3 and spaceDim equal to 3 too!"); - MEDCouplingAutoRefCountObjectPtr candidates=getCellIdsCrossingPlane(origin,vec,eps); - if(candidates->empty()) - throw INTERP_KERNEL::Exception("MEDCouplingUMesh::buildSlice3D : No 3D cells in this intercepts the specified plane considering bounding boxes !"); - std::vector nodes; - DataArrayInt *cellIds1D=0; - MEDCouplingAutoRefCountObjectPtr subMesh=static_cast(buildPartOfMySelf(candidates->begin(),candidates->end(),false)); - subMesh->findNodesOnPlane(origin,vec,eps,nodes); - MEDCouplingAutoRefCountObjectPtr desc1=DataArrayInt::New(),desc2=DataArrayInt::New(); - MEDCouplingAutoRefCountObjectPtr descIndx1=DataArrayInt::New(),descIndx2=DataArrayInt::New(); - MEDCouplingAutoRefCountObjectPtr revDesc1=DataArrayInt::New(),revDesc2=DataArrayInt::New(); - MEDCouplingAutoRefCountObjectPtr revDescIndx1=DataArrayInt::New(),revDescIndx2=DataArrayInt::New(); - MEDCouplingAutoRefCountObjectPtr mDesc2=subMesh->buildDescendingConnectivity(desc2,descIndx2,revDesc2,revDescIndx2);//meshDim==2 spaceDim==3 - revDesc2=0; revDescIndx2=0; - MEDCouplingAutoRefCountObjectPtr mDesc1=mDesc2->buildDescendingConnectivity(desc1,descIndx1,revDesc1,revDescIndx1);//meshDim==1 spaceDim==3 - revDesc1=0; revDescIndx1=0; - mDesc1->fillCellIdsToKeepFromNodeIds(&nodes[0],&nodes[0]+nodes.size(),true,cellIds1D); - MEDCouplingAutoRefCountObjectPtr cellIds1DTmp(cellIds1D); - // - std::vector cut3DCurve(mDesc1->getNumberOfCells(),-2); - for(const int *it=cellIds1D->begin();it!=cellIds1D->end();it++) - cut3DCurve[*it]=-1; - mDesc1->split3DCurveWithPlane(origin,vec,eps,cut3DCurve); - std::vector< std::pair > cut3DSurf(mDesc2->getNumberOfCells()); - AssemblyForSplitFrom3DCurve(cut3DCurve,nodes,mDesc2->getNodalConnectivity()->getConstPointer(),mDesc2->getNodalConnectivityIndex()->getConstPointer(), - mDesc1->getNodalConnectivity()->getConstPointer(),mDesc1->getNodalConnectivityIndex()->getConstPointer(), - desc1->getConstPointer(),descIndx1->getConstPointer(),cut3DSurf); - MEDCouplingAutoRefCountObjectPtr conn(DataArrayInt::New()),connI(DataArrayInt::New()),cellIds2(DataArrayInt::New()); - connI->pushBackSilent(0); conn->alloc(0,1); cellIds2->alloc(0,1); - subMesh->assemblyForSplitFrom3DSurf(cut3DSurf,desc2->getConstPointer(),descIndx2->getConstPointer(),conn,connI,cellIds2); - if(cellIds2->empty()) - throw INTERP_KERNEL::Exception("MEDCouplingUMesh::buildSlice3D : No 3D cells in this intercepts the specified plane !"); - MEDCouplingAutoRefCountObjectPtr ret=MEDCouplingUMesh::New("Slice3D",2); - ret->setCoords(mDesc1->getCoords()); - ret->setConnectivity(conn,connI,true); - cellIds=candidates->selectByTupleId(cellIds2->begin(),cellIds2->end()); - return ret.retn(); -} - -/*! - * Creates an 1D mesh by cutting \a this 2D mesh in 3D space with a plane. In -addition to the mesh, returns a new DataArrayInt, of length equal to the number of 1D cells in the result mesh, holding, for each cell in the result mesh, an id of a 2D cell it comes -from. If a result segment is shared by two 2D cells, then the segment in included twice in -the result mesh. - * \param [in] origin - 3 components of a point defining location of the plane. - * \param [in] vec - 3 components of a vector normal to the plane. Vector magnitude - * must be greater than 1e-6. - * \param [in] eps - half-thickness of the plane. - * \param [out] cellIds - a new instance of DataArrayInt holding ids of faces - * producing correspondent segments. The caller is to delete this array - * using decrRef() as it is no more needed. - * \return MEDCouplingUMesh * - a new instance of MEDCouplingUMesh. This is an 1D - * mesh in 3D space. This mesh does not share 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 not defined. - * \throw If \a this->getMeshDimension() != 2 or \a this->getSpaceDimension() != 3. - * \throw If magnitude of \a vec is less than 1e-6. - * \throw If the plane does not intersect any 2D cell of \a this mesh. - * \throw If \a this includes quadratic cells. - */ -MEDCouplingUMesh *MEDCouplingUMesh::buildSlice3DSurf(const double *origin, const double *vec, double eps, DataArrayInt *&cellIds) const -{ - checkFullyDefined(); - if(getMeshDimension()!=2 || getSpaceDimension()!=3) - throw INTERP_KERNEL::Exception("MEDCouplingUMesh::buildSlice3DSurf works on umeshes with meshdim equal to 2 and spaceDim equal to 3 !"); - MEDCouplingAutoRefCountObjectPtr candidates=getCellIdsCrossingPlane(origin,vec,eps); - if(candidates->empty()) - throw INTERP_KERNEL::Exception("MEDCouplingUMesh::buildSlice3DSurf : No 3D surf cells in this intercepts the specified plane considering bounding boxes !"); - std::vector nodes; - DataArrayInt *cellIds1D=0; - MEDCouplingAutoRefCountObjectPtr subMesh=static_cast(buildPartOfMySelf(candidates->begin(),candidates->end(),false)); - subMesh->findNodesOnPlane(origin,vec,eps,nodes); - MEDCouplingAutoRefCountObjectPtr desc1=DataArrayInt::New(); - MEDCouplingAutoRefCountObjectPtr descIndx1=DataArrayInt::New(); - MEDCouplingAutoRefCountObjectPtr revDesc1=DataArrayInt::New(); - MEDCouplingAutoRefCountObjectPtr revDescIndx1=DataArrayInt::New(); - MEDCouplingAutoRefCountObjectPtr mDesc1=subMesh->buildDescendingConnectivity(desc1,descIndx1,revDesc1,revDescIndx1);//meshDim==1 spaceDim==3 - mDesc1->fillCellIdsToKeepFromNodeIds(&nodes[0],&nodes[0]+nodes.size(),true,cellIds1D); - MEDCouplingAutoRefCountObjectPtr cellIds1DTmp(cellIds1D); - // - std::vector cut3DCurve(mDesc1->getNumberOfCells(),-2); - for(const int *it=cellIds1D->begin();it!=cellIds1D->end();it++) - cut3DCurve[*it]=-1; - mDesc1->split3DCurveWithPlane(origin,vec,eps,cut3DCurve); - int ncellsSub=subMesh->getNumberOfCells(); - std::vector< std::pair > cut3DSurf(ncellsSub); - AssemblyForSplitFrom3DCurve(cut3DCurve,nodes,subMesh->getNodalConnectivity()->getConstPointer(),subMesh->getNodalConnectivityIndex()->getConstPointer(), - mDesc1->getNodalConnectivity()->getConstPointer(),mDesc1->getNodalConnectivityIndex()->getConstPointer(), - desc1->getConstPointer(),descIndx1->getConstPointer(),cut3DSurf); - MEDCouplingAutoRefCountObjectPtr conn(DataArrayInt::New()),connI(DataArrayInt::New()),cellIds2(DataArrayInt::New()); connI->pushBackSilent(0); - conn->alloc(0,1); - const int *nodal=subMesh->getNodalConnectivity()->getConstPointer(); - const int *nodalI=subMesh->getNodalConnectivityIndex()->getConstPointer(); - for(int i=0;ipushBackSilent((int)INTERP_KERNEL::NORM_SEG2); conn->pushBackSilent(cut3DSurf[i].first); conn->pushBackSilent(cut3DSurf[i].second); - connI->pushBackSilent(conn->getNumberOfTuples()); - cellIds2->pushBackSilent(i); - } - else - { - int cellId3DSurf=cut3DSurf[i].second; - int offset=nodalI[cellId3DSurf]+1; - int nbOfEdges=nodalI[cellId3DSurf+1]-offset; - for(int j=0;jpushBackSilent((int)INTERP_KERNEL::NORM_SEG2); conn->pushBackSilent(nodal[offset+j]); conn->pushBackSilent(nodal[offset+(j+1)%nbOfEdges]); - connI->pushBackSilent(conn->getNumberOfTuples()); - cellIds2->pushBackSilent(cellId3DSurf); - } - } - } - } - if(cellIds2->empty()) - throw INTERP_KERNEL::Exception("MEDCouplingUMesh::buildSlice3DSurf : No 3DSurf cells in this intercepts the specified plane !"); - MEDCouplingAutoRefCountObjectPtr ret=MEDCouplingUMesh::New("Slice3DSurf",1); - ret->setCoords(mDesc1->getCoords()); - ret->setConnectivity(conn,connI,true); - cellIds=candidates->selectByTupleId(cellIds2->begin(),cellIds2->end()); - return ret.retn(); -} - -/*! - * Finds cells whose bounding boxes intersect a given plane. - * \param [in] origin - 3 components of a point defining location of the plane. - * \param [in] vec - 3 components of a vector normal to the plane. Vector magnitude - * must be greater than 1e-6. - * \param [in] eps - half-thickness of the plane. - * \return DataArrayInt * - a new instance of DataArrayInt holding ids of the found - * cells. The caller is to delete this array using decrRef() as it is no more - * needed. - * \throw If the coordinates array is not set. - * \throw If the nodal connectivity of cells is not defined. - * \throw If \a this->getSpaceDimension() != 3. - * \throw If magnitude of \a vec is less than 1e-6. - * \sa buildSlice3D() - */ -DataArrayInt *MEDCouplingUMesh::getCellIdsCrossingPlane(const double *origin, const double *vec, double eps) const -{ - checkFullyDefined(); - if(getSpaceDimension()!=3) - throw INTERP_KERNEL::Exception("MEDCouplingUMesh::buildSlice3D works on umeshes with spaceDim equal to 3 !"); - double normm=sqrt(vec[0]*vec[0]+vec[1]*vec[1]+vec[2]*vec[2]); - if(normm<1e-6) - throw INTERP_KERNEL::Exception("MEDCouplingUMesh::getCellIdsCrossingPlane : parameter 'vec' should have a norm2 greater than 1e-6 !"); - double vec2[3]; - vec2[0]=vec[1]; vec2[1]=-vec[0]; vec2[2]=0.;//vec2 is the result of cross product of vec with (0,0,1) - double angle=acos(vec[2]/normm); - MEDCouplingAutoRefCountObjectPtr cellIds; - double bbox[6]; - if(angle>eps) - { - MEDCouplingAutoRefCountObjectPtr coo=_coords->deepCpy(); - double normm2(sqrt(vec2[0]*vec2[0]+vec2[1]*vec2[1]+vec2[2]*vec2[2])); - if(normm2/normm>1e-6) - MEDCouplingPointSet::Rotate3DAlg(origin,vec2,angle,coo->getNumberOfTuples(),coo->getPointer()); - MEDCouplingAutoRefCountObjectPtr mw=clone(false);//false -> shallow copy - mw->setCoords(coo); - mw->getBoundingBox(bbox); - bbox[4]=origin[2]-eps; bbox[5]=origin[2]+eps; - cellIds=mw->getCellsInBoundingBox(bbox,eps); - } - else - { - getBoundingBox(bbox); - bbox[4]=origin[2]-eps; bbox[5]=origin[2]+eps; - cellIds=getCellsInBoundingBox(bbox,eps); - } - return cellIds.retn(); -} - -/*! - * This method checks that \a this is a contiguous mesh. The user is expected to call this method on a mesh with meshdim==1. - * If not an exception will thrown. If this is an empty mesh with no cell an exception will be thrown too. - * No consideration of coordinate is done by this method. - * A 1D mesh is said contiguous if : a cell i with nodal connectivity (k,p) the cell i+1 the nodal connectivity should be (p,m) - * If not false is returned. In case that false is returned a call to ParaMEDMEM::MEDCouplingUMesh::mergeNodes could be usefull. - */ -bool MEDCouplingUMesh::isContiguous1D() const -{ - if(getMeshDimension()!=1) - throw INTERP_KERNEL::Exception("MEDCouplingUMesh::isContiguous1D : this method has a sense only for 1D mesh !"); - int nbCells=getNumberOfCells(); - if(nbCells<1) - throw INTERP_KERNEL::Exception("MEDCouplingUMesh::isContiguous1D : this method has a sense for non empty mesh !"); - const int *connI=_nodal_connec_index->getConstPointer(); - const int *conn=_nodal_connec->getConstPointer(); - int ref=conn[connI[0]+2]; - for(int i=1;igetNumberOfCells - */ -void MEDCouplingUMesh::project1D(const double *pt, const double *v, double eps, double *res) const -{ - if(getMeshDimension()!=1) - throw INTERP_KERNEL::Exception("Expected a umesh with meshDim == 1 for project1D !"); - if(_types.size()!=1 || *(_types.begin())!=INTERP_KERNEL::NORM_SEG2) - throw INTERP_KERNEL::Exception("Expected a umesh with only NORM_SEG2 type of elements for project1D !"); - if(getSpaceDimension()!=3) - throw INTERP_KERNEL::Exception("Expected a umesh with spaceDim==3 for project1D !"); - MEDCouplingAutoRefCountObjectPtr f=buildDirectionVectorField(); - const double *fPtr=f->getArray()->getConstPointer(); - double tmp[3]; - for(int i=0;i(tmp); - n1/=INTERP_KERNEL::norm<3>(tmp1); - if(n1>eps) - throw INTERP_KERNEL::Exception("UMesh::Projection 1D failed !"); - } - const double *coo=getCoords()->getConstPointer(); - for(int i=0;i()); - std::transform(tmp,tmp+3,v,tmp,std::multiplies()); - res[i]=std::accumulate(tmp,tmp+3,0.); - } -} - -/*! - * This method computes the distance from a point \a pt to \a this and the first \a cellId in \a this corresponding to the returned distance. - * \a this is expected to be a mesh so that its space dimension is equal to its - * mesh dimension + 1. Furthermore only mesh dimension 1 and 2 are supported for the moment. - * Distance from \a ptBg to \a ptEnd is expected to be equal to the space dimension. \a this is also expected to be fully defined (connectivity and coordinates). - * - * WARNING, if there is some orphan nodes in \a this (nodes not fetched by any cells in \a this ( see MEDCouplingUMesh::zipCoords ) ) these nodes will ** not ** been taken - * into account in this method. Only cells and nodes lying on them are considered in the algorithm (even if one of these orphan nodes is closer than returned distance). - * A user that needs to consider orphan nodes should invoke DataArrayDouble::minimalDistanceTo method on the coordinates array of \a this. - * - * So this method is more accurate (so, more costly) than simply searching for the closest point in \a this. - * If only this information is enough for you simply call \c getCoords()->distanceToTuple on \a this. - * - * \param [in] ptBg the start pointer (included) of the coordinates of the point - * \param [in] ptEnd the end pointer (not included) of the coordinates of the point - * \param [out] cellId that corresponds to minimal distance. If the closer node is not linked to any cell in \a this -1 is returned. - * \return the positive value of the distance. - * \throw if distance from \a ptBg to \a ptEnd is not equal to the space dimension. An exception is also thrown if mesh dimension of \a this is not equal to space - * dimension - 1. - * \sa DataArrayDouble::distanceToTuple, MEDCouplingUMesh::distanceToPoints - */ -double MEDCouplingUMesh::distanceToPoint(const double *ptBg, const double *ptEnd, int& cellId) const -{ - int meshDim=getMeshDimension(),spaceDim=getSpaceDimension(); - if(meshDim!=spaceDim-1) - throw INTERP_KERNEL::Exception("MEDCouplingUMesh::distanceToPoint works only for spaceDim=meshDim+1 !"); - if(meshDim!=2 && meshDim!=1) - throw INTERP_KERNEL::Exception("MEDCouplingUMesh::distanceToPoint : only mesh dimension 2 and 1 are implemented !"); - checkFullyDefined(); - if((int)std::distance(ptBg,ptEnd)!=spaceDim) - { std::ostringstream oss; oss << "MEDCouplingUMesh::distanceToPoint : input point has to have dimension equal to the space dimension of this (" << spaceDim << ") !"; throw INTERP_KERNEL::Exception(oss.str().c_str()); } - DataArrayInt *ret1=0; - MEDCouplingAutoRefCountObjectPtr pts=DataArrayDouble::New(); pts->useArray(ptBg,false,C_DEALLOC,1,spaceDim); - MEDCouplingAutoRefCountObjectPtr ret0=distanceToPoints(pts,ret1); - MEDCouplingAutoRefCountObjectPtr ret1Safe(ret1); - cellId=*ret1Safe->begin(); - return *ret0->begin(); -} - -/*! - * This method computes the distance from each point of points serie \a pts (stored in a DataArrayDouble in which each tuple represents a point) - * to \a this and the first \a cellId in \a this corresponding to the returned distance. - * WARNING, if there is some orphan nodes in \a this (nodes not fetched by any cells in \a this ( see MEDCouplingUMesh::zipCoords ) ) these nodes will ** not ** been taken - * into account in this method. Only cells and nodes lying on them are considered in the algorithm (even if one of these orphan nodes is closer than returned distance). - * A user that needs to consider orphan nodes should invoke DataArrayDouble::minimalDistanceTo method on the coordinates array of \a this. - * - * \a this is expected to be a mesh so that its space dimension is equal to its - * mesh dimension + 1. Furthermore only mesh dimension 1 and 2 are supported for the moment. - * Number of components of \a pts is expected to be equal to the space dimension. \a this is also expected to be fully defined (connectivity and coordinates). - * - * So this method is more accurate (so, more costly) than simply searching for each point in \a pts the closest point in \a this. - * If only this information is enough for you simply call \c getCoords()->distanceToTuple on \a this. - * - * \param [in] pts the list of points in which each tuple represents a point - * \param [out] cellIds a newly allocated object that tells for each point in \a pts the first cell id in \a this that minimizes the distance. - * \return a newly allocated object to be dealed by the caller that tells for each point in \a pts the distance to \a this. - * \throw if number of components of \a pts is not equal to the space dimension. - * \throw if mesh dimension of \a this is not equal to space dimension - 1. - * \sa DataArrayDouble::distanceToTuple, MEDCouplingUMesh::distanceToPoint - */ -DataArrayDouble *MEDCouplingUMesh::distanceToPoints(const DataArrayDouble *pts, DataArrayInt *& cellIds) const -{ - if(!pts) - throw INTERP_KERNEL::Exception("MEDCouplingUMesh::distanceToPoints : input points pointer is NULL !"); - pts->checkAllocated(); - int meshDim=getMeshDimension(),spaceDim=getSpaceDimension(); - if(meshDim!=spaceDim-1) - throw INTERP_KERNEL::Exception("MEDCouplingUMesh::distanceToPoints works only for spaceDim=meshDim+1 !"); - if(meshDim!=2 && meshDim!=1) - throw INTERP_KERNEL::Exception("MEDCouplingUMesh::distanceToPoints : only mesh dimension 2 and 1 are implemented !"); - if(pts->getNumberOfComponents()!=spaceDim) - { - std::ostringstream oss; oss << "MEDCouplingUMesh::distanceToPoints : input pts DataArrayDouble has " << pts->getNumberOfComponents() << " components whereas it should be equal to " << spaceDim << " (mesh spaceDimension) !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - checkFullyDefined(); - int nbCells=getNumberOfCells(); - if(nbCells==0) - throw INTERP_KERNEL::Exception("MEDCouplingUMesh::distanceToPoints : no cells in this !"); - int nbOfPts=pts->getNumberOfTuples(); - MEDCouplingAutoRefCountObjectPtr ret0=DataArrayDouble::New(); ret0->alloc(nbOfPts,1); - MEDCouplingAutoRefCountObjectPtr ret1=DataArrayInt::New(); ret1->alloc(nbOfPts,1); - const int *nc=_nodal_connec->begin(),*ncI=_nodal_connec_index->begin(); const double *coords=_coords->begin(); - double *ret0Ptr=ret0->getPointer(); int *ret1Ptr=ret1->getPointer(); const double *ptsPtr=pts->begin(); - MEDCouplingAutoRefCountObjectPtr bboxArr(getBoundingBoxForBBTree()); - const double *bbox(bboxArr->begin()); - switch(spaceDim) - { - case 3: - { - BBTreeDst<3> myTree(bbox,0,0,nbCells); - for(int i=0;i::max(); - std::vector elems; - myTree.getMinDistanceOfMax(ptsPtr,x); - myTree.getElemsWhoseMinDistanceToPtSmallerThan(ptsPtr,x,elems); - DistanceToPoint3DSurfAlg(ptsPtr,&elems[0],&elems[0]+elems.size(),coords,nc,ncI,*ret0Ptr,*ret1Ptr); - } - break; - } - case 2: - { - BBTreeDst<2> myTree(bbox,0,0,nbCells); - for(int i=0;i::max(); - std::vector elems; - myTree.getMinDistanceOfMax(ptsPtr,x); - myTree.getElemsWhoseMinDistanceToPtSmallerThan(ptsPtr,x,elems); - DistanceToPoint2DCurveAlg(ptsPtr,&elems[0],&elems[0]+elems.size(),coords,nc,ncI,*ret0Ptr,*ret1Ptr); - } - break; - } - default: - throw INTERP_KERNEL::Exception("MEDCouplingUMesh::distanceToPoints : only spacedim 2 and 3 supported !"); - } - cellIds=ret1.retn(); - return ret0.retn(); -} - -/*! - * \param [in] pt the start pointer (included) of the coordinates of the point - * \param [in] cellIdsBg the start pointer (included) of cellIds - * \param [in] cellIdsEnd the end pointer (excluded) of cellIds - * \param [in] nc nodal connectivity - * \param [in] ncI nodal connectivity index - * \param [in,out] ret0 the min distance between \a this and the external input point - * \param [out] cellId that corresponds to minimal distance. If the closer node is not linked to any cell in \a this -1 is returned. - * \sa MEDCouplingUMesh::distanceToPoint, MEDCouplingUMesh::distanceToPoints - */ -void MEDCouplingUMesh::DistanceToPoint3DSurfAlg(const double *pt, const int *cellIdsBg, const int *cellIdsEnd, const double *coords, const int *nc, const int *ncI, double& ret0, int& cellId) -{ - cellId=-1; - ret0=std::numeric_limits::max(); - for(const int *zeCell=cellIdsBg;zeCell!=cellIdsEnd;zeCell++) - { - switch((INTERP_KERNEL::NormalizedCellType)nc[ncI[*zeCell]]) - { - case INTERP_KERNEL::NORM_TRI3: - { - double tmp=INTERP_KERNEL::DistanceFromPtToTriInSpaceDim3(pt,coords+3*nc[ncI[*zeCell]+1],coords+3*nc[ncI[*zeCell]+2],coords+3*nc[ncI[*zeCell]+3]); - if(tmp::max(); - for(const int *zeCell=cellIdsBg;zeCell!=cellIdsEnd;zeCell++) - { - switch((INTERP_KERNEL::NormalizedCellType)nc[ncI[*zeCell]]) - { - case INTERP_KERNEL::NORM_SEG2: - { - std::size_t uselessEntry=0; - double tmp=INTERP_KERNEL::SquareDistanceFromPtToSegInSpaceDim2(pt,coords+2*nc[ncI[*zeCell]+1],coords+2*nc[ncI[*zeCell]+2],uselessEntry); - tmp=sqrt(tmp); - if(tmpgetMeshDimension() != \a this->getSpaceDimension(). - */ -int MEDCouplingUMesh::getCellContainingPoint(const double *pos, double eps) const -{ - std::vector elts; - getCellsContainingPoint(pos,eps,elts); - if(elts.empty()) - return -1; - return elts.front(); -} - -/*! - * Finds cells in contact with a ball (i.e. a point with precision). - * For speed reasons, the INTERP_KERNEL::NORM_QUAD4, INTERP_KERNEL::NORM_TRI6 and INTERP_KERNEL::NORM_QUAD8 cells are considered as convex cells to detect if a point is IN or OUT. - * If it is not the case, please change their types to INTERP_KERNEL::NORM_POLYGON or INTERP_KERNEL::NORM_QPOLYG before invoking this method. - * \warning This method is suitable if the caller intends to evaluate only one - * point, for more points getCellsContainingPoints() is recommended as it is - * faster. - * \param [in] pos - array of coordinates of the ball central point. - * \param [in] eps - ball radius. - * \param [out] elts - vector returning ids of the found cells. It is cleared - * before inserting ids. - * \throw If the coordinates array is not set. - * \throw If \a this->getMeshDimension() != \a this->getSpaceDimension(). - * - * \if ENABLE_EXAMPLES - * \ref cpp_mcumesh_getCellsContainingPoint "Here is a C++ example".
- * \ref py_mcumesh_getCellsContainingPoint "Here is a Python example". - * \endif - */ -void MEDCouplingUMesh::getCellsContainingPoint(const double *pos, double eps, std::vector& elts) const -{ - MEDCouplingAutoRefCountObjectPtr eltsUg,eltsIndexUg; - getCellsContainingPoints(pos,1,eps,eltsUg,eltsIndexUg); - elts.clear(); elts.insert(elts.end(),eltsUg->begin(),eltsUg->end()); -} - -/// @cond INTERNAL - -namespace ParaMEDMEM -{ - template - class DummyClsMCUG - { - 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 - }; - - INTERP_KERNEL::Edge *MEDCouplingUMeshBuildQPFromEdge2(INTERP_KERNEL::NormalizedCellType typ, const int *bg, const double *coords2D, std::map< MEDCouplingAutoRefCountObjectPtr,int>& m) - { - INTERP_KERNEL::Edge *ret(0); - MEDCouplingAutoRefCountObjectPtr n0(new INTERP_KERNEL::Node(coords2D[2*bg[0]],coords2D[2*bg[0]+1])),n1(new INTERP_KERNEL::Node(coords2D[2*bg[1]],coords2D[2*bg[1]+1])); - m[n0]=bg[0]; m[n1]=bg[1]; - switch(typ) - { - case INTERP_KERNEL::NORM_SEG2: - { - ret=new INTERP_KERNEL::EdgeLin(n0,n1); - break; - } - case INTERP_KERNEL::NORM_SEG3: - { - INTERP_KERNEL::Node *n2(new INTERP_KERNEL::Node(coords2D[2*bg[2]],coords2D[2*bg[2]+1])); m[n2]=bg[2]; - INTERP_KERNEL::EdgeLin *e1(new INTERP_KERNEL::EdgeLin(n0,n2)),*e2(new INTERP_KERNEL::EdgeLin(n2,n1)); - INTERP_KERNEL::SegSegIntersector inters(*e1,*e2); - // is the SEG3 degenerated, and thus can be reduced to a SEG2? - bool colinearity(inters.areColinears()); - delete e1; delete e2; - if(colinearity) - { ret=new INTERP_KERNEL::EdgeLin(n0,n1); } - else - { ret=new INTERP_KERNEL::EdgeArcCircle(n0,n2,n1); } - break; - } - default: - throw INTERP_KERNEL::Exception("MEDCouplingUMeshBuildQPFromEdge2 : Expecting a mesh with spaceDim==2 and meshDim==1 !"); - } - return ret; - } - - INTERP_KERNEL::Edge *MEDCouplingUMeshBuildQPFromEdge(INTERP_KERNEL::NormalizedCellType typ, std::map >& mapp2, const int *bg) - { - INTERP_KERNEL::Edge *ret=0; - switch(typ) - { - case INTERP_KERNEL::NORM_SEG2: - { - ret=new INTERP_KERNEL::EdgeLin(mapp2[bg[0]].first,mapp2[bg[1]].first); - break; - } - case INTERP_KERNEL::NORM_SEG3: - { - INTERP_KERNEL::EdgeLin *e1=new INTERP_KERNEL::EdgeLin(mapp2[bg[0]].first,mapp2[bg[2]].first); - INTERP_KERNEL::EdgeLin *e2=new INTERP_KERNEL::EdgeLin(mapp2[bg[2]].first,mapp2[bg[1]].first); - INTERP_KERNEL::SegSegIntersector inters(*e1,*e2); - // is the SEG3 degenerated, and thus can be reduced to a SEG2? - bool colinearity=inters.areColinears(); - delete e1; delete e2; - if(colinearity) - ret=new INTERP_KERNEL::EdgeLin(mapp2[bg[0]].first,mapp2[bg[1]].first); - else - ret=new INTERP_KERNEL::EdgeArcCircle(mapp2[bg[0]].first,mapp2[bg[2]].first,mapp2[bg[1]].first); - mapp2[bg[2]].second=false; - break; - } - default: - throw INTERP_KERNEL::Exception("MEDCouplingUMeshBuildQPFromEdge : Expecting a mesh with spaceDim==2 and meshDim==1 !"); - } - return ret; - } - - /*! - * This method creates a sub mesh in Geometric2D DS. The sub mesh is composed by the sub set of cells in 'candidates' taken from - * the global mesh 'mDesc'. - * The input mesh 'mDesc' must be so that mDim==1 and spaceDim==2. - * 'mapp' returns a mapping between local numbering in submesh (represented by a Node*) and the global node numbering in 'mDesc'. - */ - INTERP_KERNEL::QuadraticPolygon *MEDCouplingUMeshBuildQPFromMesh(const MEDCouplingUMesh *mDesc, const std::vector& candidates, - std::map& mapp) - { - mapp.clear(); - std::map > mapp2;//bool is for a flag specifying if node is boundary (true) or only a middle for SEG3. - const double *coo=mDesc->getCoords()->getConstPointer(); - const int *c=mDesc->getNodalConnectivity()->getConstPointer(); - const int *cI=mDesc->getNodalConnectivityIndex()->getConstPointer(); - std::set s; - for(std::vector::const_iterator it=candidates.begin();it!=candidates.end();it++) - s.insert(c+cI[*it]+1,c+cI[(*it)+1]); - for(std::set::const_iterator it2=s.begin();it2!=s.end();it2++) - { - INTERP_KERNEL::Node *n=new INTERP_KERNEL::Node(coo[2*(*it2)],coo[2*(*it2)+1]); - mapp2[*it2]=std::pair(n,true); - } - INTERP_KERNEL::QuadraticPolygon *ret=new INTERP_KERNEL::QuadraticPolygon; - for(std::vector::const_iterator it=candidates.begin();it!=candidates.end();it++) - { - INTERP_KERNEL::NormalizedCellType typ=(INTERP_KERNEL::NormalizedCellType)c[cI[*it]]; - ret->pushBack(MEDCouplingUMeshBuildQPFromEdge(typ,mapp2,c+cI[*it]+1)); - } - for(std::map >::const_iterator it2=mapp2.begin();it2!=mapp2.end();it2++) - { - if((*it2).second.second) - mapp[(*it2).second.first]=(*it2).first; - ((*it2).second.first)->decrRef(); - } - return ret; - } - - INTERP_KERNEL::Node *MEDCouplingUMeshBuildQPNode(int nodeId, const double *coo1, int offset1, const double *coo2, int offset2, const std::vector& addCoo) - { - if(nodeId>=offset2) - { - int locId=nodeId-offset2; - return new INTERP_KERNEL::Node(addCoo[2*locId],addCoo[2*locId+1]); - } - if(nodeId>=offset1) - { - int locId=nodeId-offset1; - return new INTERP_KERNEL::Node(coo2[2*locId],coo2[2*locId+1]); - } - return new INTERP_KERNEL::Node(coo1[2*nodeId],coo1[2*nodeId+1]); - } - - /** - * Construct a mapping between set of Nodes and the standart MEDCoupling connectivity format (c, cI). - */ - void MEDCouplingUMeshBuildQPFromMesh3(const double *coo1, int offset1, const double *coo2, int offset2, const std::vector& addCoo, - const int *desc1Bg, const int *desc1End, const std::vector >& intesctEdges1, - /*output*/std::map& mapp, std::map& mappRev) - { - for(const int *desc1=desc1Bg;desc1!=desc1End;desc1++) - { - int eltId1=abs(*desc1)-1; - for(std::vector::const_iterator it1=intesctEdges1[eltId1].begin();it1!=intesctEdges1[eltId1].end();it1++) - { - std::map::const_iterator it=mappRev.find(*it1); - if(it==mappRev.end()) - { - INTERP_KERNEL::Node *node=MEDCouplingUMeshBuildQPNode(*it1,coo1,offset1,coo2,offset2,addCoo); - mapp[node]=*it1; - mappRev[*it1]=node; - } - } - } - } -} - -/// @endcond - -template -void MEDCouplingUMesh::getCellsContainingPointsAlg(const double *coords, const double *pos, int nbOfPoints, - double eps, MEDCouplingAutoRefCountObjectPtr& elts, MEDCouplingAutoRefCountObjectPtr& eltsIndex) const -{ - elts=DataArrayInt::New(); eltsIndex=DataArrayInt::New(); eltsIndex->alloc(nbOfPoints+1,1); eltsIndex->setIJ(0,0,0); elts->alloc(0,1); - int *eltsIndexPtr(eltsIndex->getPointer()); - MEDCouplingAutoRefCountObjectPtr bboxArr(getBoundingBoxForBBTree(eps)); - const double *bbox(bboxArr->begin()); - int nbOfCells=getNumberOfCells(); - const int *conn=_nodal_connec->getConstPointer(); - const int *connI=_nodal_connec_index->getConstPointer(); - double bb[2*SPACEDIM]; - BBTree myTree(&bbox[0],0,0,nbOfCells,-eps); - for(int i=0;i candidates; - myTree.getIntersectingElems(bb,candidates); - for(std::vector::const_iterator iter=candidates.begin();iter!=candidates.end();iter++) - { - int sz(connI[(*iter)+1]-connI[*iter]-1); - INTERP_KERNEL::NormalizedCellType ct((INTERP_KERNEL::NormalizedCellType)conn[connI[*iter]]); - bool status(false); - if(ct!=INTERP_KERNEL::NORM_POLYGON && ct!=INTERP_KERNEL::NORM_QPOLYG) - status=INTERP_KERNEL::PointLocatorAlgos >::isElementContainsPoint(pos+i*SPACEDIM,ct,coords,conn+connI[*iter]+1,sz,eps); - else - { - if(SPACEDIM!=2) - throw INTERP_KERNEL::Exception("MEDCouplingUMesh::getCellsContainingPointsAlg : not implemented yet for POLYGON and QPOLYGON in spaceDim 3 !"); - INTERP_KERNEL::QUADRATIC_PLANAR::_precision=eps; - INTERP_KERNEL::QUADRATIC_PLANAR::_arc_detection_precision=eps; - std::vector nodes(sz); - INTERP_KERNEL::QuadraticPolygon *pol(0); - for(int j=0;jnormalizeMe(b,c); n->applySimilarity(b,c,a); - status=pol->isInOrOut2(n); - delete pol; n->decrRef(); - } - if(status) - { - eltsIndexPtr[i+1]++; - elts->pushBackSilent(*iter); - } - } - } -} -/*! - * 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. - * For speed reasons, the INTERP_KERNEL::NORM_QUAD4, INTERP_KERNEL::NORM_TRI6 and INTERP_KERNEL::NORM_QUAD8 cells are considered as convex cells to detect if a point is IN or OUT. - * If it is not the case, please change their types to INTERP_KERNEL::NORM_POLYGON or INTERP_KERNEL::NORM_QPOLYG before invoking this method. - * \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 [out] elts - vector returning ids of found cells. - * \param [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* ]. - * \throw If the coordinates array is not set. - * \throw If \a this->getMeshDimension() != \a this->getSpaceDimension(). - * - * \if ENABLE_EXAMPLES - * \ref cpp_mcumesh_getCellsContainingPoints "Here is a C++ example".
- * \ref py_mcumesh_getCellsContainingPoints "Here is a Python example". - * \endif - */ -void MEDCouplingUMesh::getCellsContainingPoints(const double *pos, int nbOfPoints, double eps, - MEDCouplingAutoRefCountObjectPtr& elts, MEDCouplingAutoRefCountObjectPtr& eltsIndex) const -{ - int spaceDim=getSpaceDimension(); - int mDim=getMeshDimension(); - if(spaceDim==3) - { - if(mDim==3) - { - const double *coords=_coords->getConstPointer(); - getCellsContainingPointsAlg<3>(coords,pos,nbOfPoints,eps,elts,eltsIndex); - } - /*else if(mDim==2) - { - - }*/ - else - throw INTERP_KERNEL::Exception("For spaceDim==3 only meshDim==3 implemented for getelementscontainingpoints !"); - } - else if(spaceDim==2) - { - if(mDim==2) - { - const double *coords=_coords->getConstPointer(); - getCellsContainingPointsAlg<2>(coords,pos,nbOfPoints,eps,elts,eltsIndex); - } - else - throw INTERP_KERNEL::Exception("For spaceDim==2 only meshDim==2 implemented for getelementscontainingpoints !"); - } - else if(spaceDim==1) - { - if(mDim==1) - { - const double *coords=_coords->getConstPointer(); - getCellsContainingPointsAlg<1>(coords,pos,nbOfPoints,eps,elts,eltsIndex); - } - else - throw INTERP_KERNEL::Exception("For spaceDim==1 only meshDim==1 implemented for getelementscontainingpoints !"); - } - else - throw INTERP_KERNEL::Exception("MEDCouplingUMesh::getCellsContainingPoints : not managed for mdim not in [1,2,3] !"); -} - -/*! - * Finds butterfly cells in \a this mesh. A 2D cell is considered to be butterfly if at - * least two its edges intersect each other anywhere except their extremities. An - * INTERP_KERNEL::NORM_NORI3 cell can \b not be butterfly. - * \param [in,out] cells - a vector returning ids of the found cells. It is not - * cleared before filling in. - * \param [in] eps - precision. - * \throw If \a this->getMeshDimension() != 2. - * \throw If \a this->getSpaceDimension() != 2 && \a this->getSpaceDimension() != 3. - */ -void MEDCouplingUMesh::checkButterflyCells(std::vector& cells, double eps) const -{ - const char msg[]="Butterfly detection work only for 2D cells with spaceDim==2 or 3!"; - if(getMeshDimension()!=2) - throw INTERP_KERNEL::Exception(msg); - int spaceDim=getSpaceDimension(); - if(spaceDim!=2 && spaceDim!=3) - throw INTERP_KERNEL::Exception(msg); - const int *conn=_nodal_connec->getConstPointer(); - const int *connI=_nodal_connec_index->getConstPointer(); - int nbOfCells=getNumberOfCells(); - std::vector cell2DinS2; - for(int i=0;igetConstPointer(); - int nbOfCells=getNumberOfCells(); - MEDCouplingAutoRefCountObjectPtr nodalConnecIndexOut=DataArrayInt::New(); - nodalConnecIndexOut->alloc(nbOfCells+1,1); - MEDCouplingAutoRefCountObjectPtr nodalConnecOut(DataArrayInt::New()); - int *workIndexOut=nodalConnecIndexOut->getPointer(); - *workIndexOut=0; - const int *nodalConnecIn=_nodal_connec->getConstPointer(); - const int *nodalConnecIndexIn=_nodal_connec_index->getConstPointer(); - std::set types; - MEDCouplingAutoRefCountObjectPtr isChanged(DataArrayInt::New()); - isChanged->alloc(0,1); - for(int i=0;igetNumberOfTuples(); - if(BuildConvexEnvelopOf2DCellJarvis(coords,nodalConnecIn+nodalConnecIndexIn[i],nodalConnecIn+nodalConnecIndexIn[i+1],nodalConnecOut)) - isChanged->pushBackSilent(i); - types.insert((INTERP_KERNEL::NormalizedCellType)nodalConnecOut->getIJ(pos,0)); - workIndexOut[1]=nodalConnecOut->getNumberOfTuples(); - } - if(isChanged->empty()) - return 0; - setConnectivity(nodalConnecOut,nodalConnecIndexOut,false); - _types=types; - return isChanged.retn(); -} - -/*! - * This method is \b NOT const because it can modify \a this. - * \a this is expected to be an unstructured mesh with meshDim==2 and spaceDim==3. If not an exception will be thrown. - * \param mesh1D is an unstructured mesh with MeshDim==1 and spaceDim==3. If not an exception will be thrown. - * \param policy specifies the type of extrusion chosen. \b 0 for translation (most simple), - * \b 1 for translation and rotation around point of 'mesh1D'. - * \return an unstructured mesh with meshDim==3 and spaceDim==3. The returned mesh has the same coords than \a this. - */ -MEDCouplingUMesh *MEDCouplingUMesh::buildExtrudedMesh(const MEDCouplingUMesh *mesh1D, int policy) -{ - checkFullyDefined(); - mesh1D->checkFullyDefined(); - if(!mesh1D->isContiguous1D()) - throw INTERP_KERNEL::Exception("buildExtrudedMesh : 1D mesh passed in parameter is not contiguous !"); - if(getSpaceDimension()!=mesh1D->getSpaceDimension()) - throw INTERP_KERNEL::Exception("Invalid call to buildExtrudedMesh this and mesh1D must have same space dimension !"); - if((getMeshDimension()!=2 || getSpaceDimension()!=3) && (getMeshDimension()!=1 || getSpaceDimension()!=2)) - throw INTERP_KERNEL::Exception("Invalid 'this' for buildExtrudedMesh method : must be (meshDim==2 and spaceDim==3) or (meshDim==1 and spaceDim==2) !"); - if(mesh1D->getMeshDimension()!=1) - throw INTERP_KERNEL::Exception("Invalid 'mesh1D' for buildExtrudedMesh method : must be meshDim==1 !"); - bool isQuad=false; - if(isPresenceOfQuadratic()) - { - if(mesh1D->isFullyQuadratic()) - isQuad=true; - else - throw INTERP_KERNEL::Exception("Invalid 2D mesh and 1D mesh because 2D mesh has quadratic cells and 1D is not fully quadratic !"); - } - int oldNbOfNodes(getNumberOfNodes()); - MEDCouplingAutoRefCountObjectPtr newCoords; - switch(policy) - { - case 0: - { - newCoords=fillExtCoordsUsingTranslation(mesh1D,isQuad); - break; - } - case 1: - { - newCoords=fillExtCoordsUsingTranslAndAutoRotation(mesh1D,isQuad); - break; - } - default: - throw INTERP_KERNEL::Exception("Not implemented extrusion policy : must be in (0) !"); - } - setCoords(newCoords); - MEDCouplingAutoRefCountObjectPtr ret(buildExtrudedMeshFromThisLowLev(oldNbOfNodes,isQuad)); - updateTime(); - return ret.retn(); -} - -/*! - * This method works on a 3D curve linear mesh that is to say (meshDim==1 and spaceDim==3). - * If it is not the case an exception will be thrown. - * This method is non const because the coordinate of \a this can be appended with some new points issued from - * intersection of plane defined by ('origin','vec'). - * This method has one in/out parameter : 'cut3DCurve'. - * Param 'cut3DCurve' is expected to be of size 'this->getNumberOfCells()'. For each i in [0,'this->getNumberOfCells()') - * if cut3DCurve[i]==-2, it means that for cell #i in \a this nothing has been detected previously. - * if cut3DCurve[i]==-1, it means that cell#i has been already detected to be fully part of plane defined by ('origin','vec'). - * This method will throw an exception if \a this contains a non linear segment. - */ -void MEDCouplingUMesh::split3DCurveWithPlane(const double *origin, const double *vec, double eps, std::vector& cut3DCurve) -{ - checkFullyDefined(); - if(getMeshDimension()!=1 || getSpaceDimension()!=3) - throw INTERP_KERNEL::Exception("MEDCouplingUMesh::split3DCurveWithPlane works on umeshes with meshdim equal to 1 and spaceDim equal to 3 !"); - int ncells=getNumberOfCells(); - int nnodes=getNumberOfNodes(); - double vec2[3],vec3[3],vec4[3]; - double normm=sqrt(vec[0]*vec[0]+vec[1]*vec[1]+vec[2]*vec[2]); - if(normm<1e-6) - throw INTERP_KERNEL::Exception("MEDCouplingUMesh::split3DCurveWithPlane : parameter 'vec' should have a norm2 greater than 1e-6 !"); - vec2[0]=vec[0]/normm; vec2[1]=vec[1]/normm; vec2[2]=vec[2]/normm; - const int *conn=_nodal_connec->getConstPointer(); - const int *connI=_nodal_connec_index->getConstPointer(); - const double *coo=_coords->getConstPointer(); - std::vector addCoo; - for(int i=0;ieps)//if colin<=eps -> current SEG2 is colinear to the input plane - { - const double *st2=coo+3*st; - vec4[0]=st2[0]-origin[0]; vec4[1]=st2[1]-origin[1]; vec4[2]=st2[2]-origin[2]; - double pos=-(vec4[0]*vec2[0]+vec4[1]*vec2[1]+vec4[2]*vec2[2])/((vec3[0]*vec2[0]+vec3[1]*vec2[1]+vec3[2]*vec2[2])); - if(pos>eps && pos<1-eps) - { - int nNode=((int)addCoo.size())/3; - vec4[0]=st2[0]+pos*vec3[0]; vec4[1]=st2[1]+pos*vec3[1]; vec4[2]=st2[2]+pos*vec3[2]; - addCoo.insert(addCoo.end(),vec4,vec4+3); - cut3DCurve[i]=nnodes+nNode; - } - } - } - } - else - throw INTERP_KERNEL::Exception("MEDCouplingUMesh::split3DCurveWithPlane : this method is only available for linear cell (NORM_SEG2) !"); - } - if(!addCoo.empty()) - { - int newNbOfNodes=nnodes+((int)addCoo.size())/3; - MEDCouplingAutoRefCountObjectPtr coo2=DataArrayDouble::New(); - coo2->alloc(newNbOfNodes,3); - double *tmp=coo2->getPointer(); - tmp=std::copy(_coords->begin(),_coords->end(),tmp); - std::copy(addCoo.begin(),addCoo.end(),tmp); - DataArrayDouble::SetArrayIn(coo2,_coords); - } -} - -/*! - * This method incarnates the policy 0 for MEDCouplingUMesh::buildExtrudedMesh method. - * \param mesh1D is the input 1D mesh used for translation computation. - * \return newCoords new coords filled by this method. - */ -DataArrayDouble *MEDCouplingUMesh::fillExtCoordsUsingTranslation(const MEDCouplingUMesh *mesh1D, bool isQuad) const -{ - int oldNbOfNodes=getNumberOfNodes(); - int nbOf1DCells=mesh1D->getNumberOfCells(); - int spaceDim=getSpaceDimension(); - DataArrayDouble *ret=DataArrayDouble::New(); - std::vector isQuads; - int nbOfLevsInVec=isQuad?2*nbOf1DCells+1:nbOf1DCells+1; - ret->alloc(oldNbOfNodes*nbOfLevsInVec,spaceDim); - double *retPtr=ret->getPointer(); - const double *coords=getCoords()->getConstPointer(); - double *work=std::copy(coords,coords+spaceDim*oldNbOfNodes,retPtr); - std::vector v; - std::vector c; - double vec[3]; - v.reserve(3); - c.reserve(6); - for(int i=0;igetNodeIdsOfCell(i,v); - c.resize(0); - mesh1D->getCoordinatesOfNode(v[isQuad?2:1],c); - mesh1D->getCoordinatesOfNode(v[0],c); - std::transform(c.begin(),c.begin()+spaceDim,c.begin()+spaceDim,vec,std::minus()); - for(int j=0;j()); - if(isQuad) - { - c.resize(0); - mesh1D->getCoordinatesOfNode(v[1],c); - mesh1D->getCoordinatesOfNode(v[0],c); - std::transform(c.begin(),c.begin()+spaceDim,c.begin()+spaceDim,vec,std::minus()); - for(int j=0;j()); - } - } - ret->copyStringInfoFrom(*getCoords()); - return ret; -} - -/*! - * This method incarnates the policy 1 for MEDCouplingUMesh::buildExtrudedMesh method. - * \param mesh1D is the input 1D mesh used for translation and automatic rotation computation. - * \return newCoords new coords filled by this method. - */ -DataArrayDouble *MEDCouplingUMesh::fillExtCoordsUsingTranslAndAutoRotation(const MEDCouplingUMesh *mesh1D, bool isQuad) const -{ - if(mesh1D->getSpaceDimension()==2) - return fillExtCoordsUsingTranslAndAutoRotation2D(mesh1D,isQuad); - if(mesh1D->getSpaceDimension()==3) - return fillExtCoordsUsingTranslAndAutoRotation3D(mesh1D,isQuad); - throw INTERP_KERNEL::Exception("Not implemented rotation and translation alg. for spacedim other than 2 and 3 !"); -} - -/*! - * This method incarnates the policy 1 for MEDCouplingUMesh::buildExtrudedMesh method. - * \param mesh1D is the input 1D mesh used for translation and automatic rotation computation. - * \return newCoords new coords filled by this method. - */ -DataArrayDouble *MEDCouplingUMesh::fillExtCoordsUsingTranslAndAutoRotation2D(const MEDCouplingUMesh *mesh1D, bool isQuad) const -{ - if(isQuad) - throw INTERP_KERNEL::Exception("MEDCouplingUMesh::fillExtCoordsUsingTranslAndAutoRotation2D : not implemented for quadratic cells !"); - int oldNbOfNodes=getNumberOfNodes(); - int nbOf1DCells=mesh1D->getNumberOfCells(); - if(nbOf1DCells<2) - throw INTERP_KERNEL::Exception("MEDCouplingUMesh::fillExtCoordsUsingTranslAndAutoRotation2D : impossible to detect any angle of rotation ! Change extrusion policy 1->0 !"); - MEDCouplingAutoRefCountObjectPtr ret=DataArrayDouble::New(); - int nbOfLevsInVec=nbOf1DCells+1; - ret->alloc(oldNbOfNodes*nbOfLevsInVec,2); - double *retPtr=ret->getPointer(); - retPtr=std::copy(getCoords()->getConstPointer(),getCoords()->getConstPointer()+getCoords()->getNbOfElems(),retPtr); - MEDCouplingAutoRefCountObjectPtr tmp=MEDCouplingUMesh::New(); - MEDCouplingAutoRefCountObjectPtr tmp2=getCoords()->deepCpy(); - tmp->setCoords(tmp2); - const double *coo1D=mesh1D->getCoords()->getConstPointer(); - const int *conn1D=mesh1D->getNodalConnectivity()->getConstPointer(); - const int *connI1D=mesh1D->getNodalConnectivityIndex()->getConstPointer(); - for(int i=1;itranslate(vec); - double tmp3[2],radius,alpha,alpha0; - const double *p0=i+1rotate(end,0,angle); - retPtr=std::copy(tmp2->getConstPointer(),tmp2->getConstPointer()+tmp2->getNbOfElems(),retPtr); - } - return ret.retn(); -} - -/*! - * This method incarnates the policy 1 for MEDCouplingUMesh::buildExtrudedMesh method. - * \param mesh1D is the input 1D mesh used for translation and automatic rotation computation. - * \return newCoords new coords filled by this method. - */ -DataArrayDouble *MEDCouplingUMesh::fillExtCoordsUsingTranslAndAutoRotation3D(const MEDCouplingUMesh *mesh1D, bool isQuad) const -{ - if(isQuad) - throw INTERP_KERNEL::Exception("MEDCouplingUMesh::fillExtCoordsUsingTranslAndAutoRotation3D : not implemented for quadratic cells !"); - int oldNbOfNodes=getNumberOfNodes(); - int nbOf1DCells=mesh1D->getNumberOfCells(); - if(nbOf1DCells<2) - throw INTERP_KERNEL::Exception("MEDCouplingUMesh::fillExtCoordsUsingTranslAndAutoRotation3D : impossible to detect any angle of rotation ! Change extrusion policy 1->0 !"); - MEDCouplingAutoRefCountObjectPtr ret=DataArrayDouble::New(); - int nbOfLevsInVec=nbOf1DCells+1; - ret->alloc(oldNbOfNodes*nbOfLevsInVec,3); - double *retPtr=ret->getPointer(); - retPtr=std::copy(getCoords()->getConstPointer(),getCoords()->getConstPointer()+getCoords()->getNbOfElems(),retPtr); - MEDCouplingAutoRefCountObjectPtr tmp=MEDCouplingUMesh::New(); - MEDCouplingAutoRefCountObjectPtr tmp2=getCoords()->deepCpy(); - tmp->setCoords(tmp2); - const double *coo1D=mesh1D->getCoords()->getConstPointer(); - const int *conn1D=mesh1D->getNodalConnectivity()->getConstPointer(); - const int *connI1D=mesh1D->getNodalConnectivityIndex()->getConstPointer(); - for(int i=1;itranslate(vec); - double tmp3[2],radius,alpha,alpha0; - const double *p0=i+11.e-7) - { - vecPlane[0]/=norm; vecPlane[1]/=norm; vecPlane[2]/=norm; - double norm2=sqrt(vecPlane[0]*vecPlane[0]+vecPlane[1]*vecPlane[1]); - double vec2[2]={vecPlane[1]/norm2,-vecPlane[0]/norm2}; - double s2=norm2; - double c2=cos(asin(s2)); - double m[3][3]={ - {vec2[0]*vec2[0]*(1-c2)+c2, vec2[0]*vec2[1]*(1-c2), vec2[1]*s2}, - {vec2[0]*vec2[1]*(1-c2), vec2[1]*vec2[1]*(1-c2)+c2, -vec2[0]*s2}, - {-vec2[1]*s2, vec2[0]*s2, c2} - }; - double p0r[3]={m[0][0]*p0[0]+m[0][1]*p0[1]+m[0][2]*p0[2], m[1][0]*p0[0]+m[1][1]*p0[1]+m[1][2]*p0[2], m[2][0]*p0[0]+m[2][1]*p0[1]+m[2][2]*p0[2]}; - double p1r[3]={m[0][0]*p1[0]+m[0][1]*p1[1]+m[0][2]*p1[2], m[1][0]*p1[0]+m[1][1]*p1[1]+m[1][2]*p1[2], m[2][0]*p1[0]+m[2][1]*p1[1]+m[2][2]*p1[2]}; - double p2r[3]={m[0][0]*p2[0]+m[0][1]*p2[1]+m[0][2]*p2[2], m[1][0]*p2[0]+m[1][1]*p2[1]+m[1][2]*p2[2], m[2][0]*p2[0]+m[2][1]*p2[1]+m[2][2]*p2[2]}; - INTERP_KERNEL::EdgeArcCircle::GetArcOfCirclePassingThru(p0r,p1r,p2r,tmp3,radius,alpha,alpha0); - double cosangle=i+1rotate(end,vecPlane,angle); - } - retPtr=std::copy(tmp2->getConstPointer(),tmp2->getConstPointer()+tmp2->getNbOfElems(),retPtr); - } - return ret.retn(); -} - -/*! - * This method is private because not easy to use for end user. This method is const contrary to - * MEDCouplingUMesh::buildExtrudedMesh method because this->_coords are expected to contain - * the coords sorted slice by slice. - * \param isQuad specifies presence of quadratic cells. - */ -MEDCouplingUMesh *MEDCouplingUMesh::buildExtrudedMeshFromThisLowLev(int nbOfNodesOf1Lev, bool isQuad) const -{ - int nbOf1DCells(getNumberOfNodes()/nbOfNodesOf1Lev-1); - int nbOf2DCells(getNumberOfCells()); - int nbOf3DCells(nbOf2DCells*nbOf1DCells); - MEDCouplingUMesh *ret(MEDCouplingUMesh::New("Extruded",getMeshDimension()+1)); - const int *conn(_nodal_connec->begin()),*connI(_nodal_connec_index->begin()); - MEDCouplingAutoRefCountObjectPtr newConn(DataArrayInt::New()),newConnI(DataArrayInt::New()); - newConnI->alloc(nbOf3DCells+1,1); - int *newConnIPtr(newConnI->getPointer()); - *newConnIPtr++=0; - std::vector newc; - for(int j=0;jalloc((int)(newc.size())*nbOf1DCells,1); - int *newConnPtr(newConn->getPointer()); - int deltaPerLev(isQuad?2*nbOfNodesOf1Lev:nbOfNodesOf1Lev); - newConnIPtr=newConnI->getPointer(); - for(int iz=0;iz(),newConnIPtr[iz*nbOf2DCells])); - const int *posOfTypeOfCell(newConnIPtr); - for(std::vector::const_iterator iter=newc.begin();iter!=newc.end();iter++,newConnPtr++) - { - int icell((int)(iter-newc.begin()));//std::distance unfortunately cannot been called here in C++98 - if(icell!=*posOfTypeOfCell) - { - if(*iter!=-1) - *newConnPtr=(*iter)+iz*deltaPerLev; - else - *newConnPtr=-1; - } - else - { - *newConnPtr=*iter; - posOfTypeOfCell++; - } - } - } - ret->setConnectivity(newConn,newConnI,true); - ret->setCoords(getCoords()); - return ret; -} - -/*! - * Checks if \a this mesh is constituted by only quadratic cells. - * \return bool - \c true if there are only quadratic cells in \a this mesh. - * \throw If the coordinates array is not set. - * \throw If the nodal connectivity of cells is not defined. - */ -bool MEDCouplingUMesh::isFullyQuadratic() const -{ - checkFullyDefined(); - bool ret=true; - int nbOfCells=getNumberOfCells(); - for(int i=0;igetConstPointer(); - for(int i=0;i newConn=DataArrayInt::New(); - MEDCouplingAutoRefCountObjectPtr newConnI=DataArrayInt::New(); - const int *icptr=_nodal_connec->getConstPointer(); - newConn->alloc(getMeshLength()-delta,1); - newConnI->alloc(nbOfCells+1,1); - int *ocptr=newConn->getPointer(); - int *ociptr=newConnI->getPointer(); - *ociptr=0; - _types.clear(); - for(int i=0;i types; - checkFullyDefined(); - MEDCouplingAutoRefCountObjectPtr ret,connSafe,connISafe; - MEDCouplingAutoRefCountObjectPtr coordsSafe; - int meshDim=getMeshDimension(); - switch(conversionType) - { - case 0: - switch(meshDim) - { - case 1: - ret=convertLinearCellsToQuadratic1D0(conn,connI,coords,types); - connSafe=conn; connISafe=connI; coordsSafe=coords; - break; - case 2: - ret=convertLinearCellsToQuadratic2D0(conn,connI,coords,types); - connSafe=conn; connISafe=connI; coordsSafe=coords; - break; - case 3: - ret=convertLinearCellsToQuadratic3D0(conn,connI,coords,types); - connSafe=conn; connISafe=connI; coordsSafe=coords; - break; - default: - throw INTERP_KERNEL::Exception("MEDCouplingUMesh::convertLinearCellsToQuadratic : conversion of type 0 mesh dimensions available are [1,2,3] !"); - } - break; - case 1: - { - switch(meshDim) - { - case 1: - ret=convertLinearCellsToQuadratic1D0(conn,connI,coords,types);//it is not a bug. In 1D policy 0 and 1 are equals - connSafe=conn; connISafe=connI; coordsSafe=coords; - break; - case 2: - ret=convertLinearCellsToQuadratic2D1(conn,connI,coords,types); - connSafe=conn; connISafe=connI; coordsSafe=coords; - break; - case 3: - ret=convertLinearCellsToQuadratic3D1(conn,connI,coords,types); - connSafe=conn; connISafe=connI; coordsSafe=coords; - break; - default: - throw INTERP_KERNEL::Exception("MEDCouplingUMesh::convertLinearCellsToQuadratic : conversion of type 1 mesh dimensions available are [1,2,3] !"); - } - break; - } - default: - throw INTERP_KERNEL::Exception("MEDCouplingUMesh::convertLinearCellsToQuadratic : conversion type available are 0 (default, the simplest) and 1 (the most complex) !"); - } - setConnectivity(connSafe,connISafe,false); - _types=types; - setCoords(coordsSafe); - return ret.retn(); -} - -#if 0 -/*! - * This method only works if \a this has spaceDimension equal to 2 and meshDimension also equal to 2. - * This method allows to modify connectivity of cells in \a this that shares some edges in \a edgeIdsToBeSplit. - * The nodes to be added in those 2D cells are defined by the pair of \a nodeIdsToAdd and \a nodeIdsIndexToAdd. - * Length of \a nodeIdsIndexToAdd is expected to equal to length of \a edgeIdsToBeSplit + 1. - * The node ids in \a nodeIdsToAdd should be valid. Those nodes have to be sorted exactly following exactly the direction of the edge. - * This method can be seen as the opposite method of colinearize2D. - * This method can be lead to create some new nodes if quadratic polygon cells have to be split. In this case the added nodes will be put at the end - * to avoid to modify the numbering of existing nodes. - * - * \param [in] nodeIdsToAdd - the list of node ids to be added (\a nodeIdsIndexToAdd array allows to walk on this array) - * \param [in] nodeIdsIndexToAdd - the entry point of \a nodeIdsToAdd to point to the corresponding nodes to be added. - * \param [in] mesh1Desc - 1st output of buildDescendingConnectivity2 on \a this. - * \param [in] desc - 2nd output of buildDescendingConnectivity2 on \a this. - * \param [in] descI - 3rd output of buildDescendingConnectivity2 on \a this. - * \param [in] revDesc - 4th output of buildDescendingConnectivity2 on \a this. - * \param [in] revDescI - 5th output of buildDescendingConnectivity2 on \a this. - * - * \sa buildDescendingConnectivity2 - */ -void MEDCouplingUMesh::splitSomeEdgesOf2DMesh(const DataArrayInt *nodeIdsToAdd, const DataArrayInt *nodeIdsIndexToAdd, const DataArrayInt *edgeIdsToBeSplit, - const MEDCouplingUMesh *mesh1Desc, const DataArrayInt *desc, const DataArrayInt *descI, const DataArrayInt *revDesc, const DataArrayInt *revDescI) -{ - if(!nodeIdsToAdd || !nodeIdsIndexToAdd || !edgeIdsToBeSplit || !mesh1Desc || !desc || !descI || !revDesc || !revDescI) - throw INTERP_KERNEL::Exception("MEDCouplingUMesh::splitSomeEdgesOf2DMesh : input pointers must be not NULL !"); - nodeIdsToAdd->checkAllocated(); nodeIdsIndexToAdd->checkAllocated(); edgeIdsToBeSplit->checkAllocated(); desc->checkAllocated(); descI->checkAllocated(); revDesc->checkAllocated(); revDescI->checkAllocated(); - if(getSpaceDimension()!=2 || getMeshDimension()!=2) - throw INTERP_KERNEL::Exception("MEDCouplingUMesh::splitSomeEdgesOf2DMesh : this must have spacedim=meshdim=2 !"); - if(mesh1Desc->getSpaceDimension()!=2 || mesh1Desc->getMeshDimension()!=1) - throw INTERP_KERNEL::Exception("MEDCouplingUMesh::splitSomeEdgesOf2DMesh : mesh1Desc must be the explosion of this with spaceDim=2 and meshDim = 1 !"); - //DataArrayInt *out0(0),*outi0(0); - //MEDCouplingUMesh::ExtractFromIndexedArrays(idsInDesc2DToBeRefined->begin(),idsInDesc2DToBeRefined->end(),dd3,dd4,out0,outi0); - //MEDCouplingAutoRefCountObjectPtr out0s(out0),outi0s(outi0); - //out0s=out0s->buildUnique(); out0s->sort(true); -} -#endif - -/*! - * Implementes \a conversionType 0 for meshes with meshDim = 1, of MEDCouplingUMesh::convertLinearCellsToQuadratic method. - * \return a newly created DataArrayInt instance that the caller should deal with containing cell ids of converted cells. - * \sa MEDCouplingUMesh::convertLinearCellsToQuadratic. - */ -DataArrayInt *MEDCouplingUMesh::convertLinearCellsToQuadratic1D0(DataArrayInt *&conn, DataArrayInt *&connI, DataArrayDouble *& coords, std::set& types) const -{ - MEDCouplingAutoRefCountObjectPtr bary=getBarycenterAndOwner(); - MEDCouplingAutoRefCountObjectPtr newConn=DataArrayInt::New(); newConn->alloc(0,1); - MEDCouplingAutoRefCountObjectPtr newConnI=DataArrayInt::New(); newConnI->alloc(1,1); newConnI->setIJ(0,0,0); - MEDCouplingAutoRefCountObjectPtr ret=DataArrayInt::New(); ret->alloc(0,1); - int nbOfCells=getNumberOfCells(); - int nbOfNodes=getNumberOfNodes(); - const int *cPtr=_nodal_connec->getConstPointer(); - const int *icPtr=_nodal_connec_index->getConstPointer(); - int lastVal=0,offset=nbOfNodes; - for(int i=0;ipushBackSilent((int)INTERP_KERNEL::NORM_SEG3); - newConn->pushBackValsSilent(cPtr+icPtr[0]+1,cPtr+icPtr[0]+3); - newConn->pushBackSilent(offset++); - lastVal+=4; - newConnI->pushBackSilent(lastVal); - ret->pushBackSilent(i); - } - else - { - types.insert(type); - lastVal+=(icPtr[1]-icPtr[0]); - newConnI->pushBackSilent(lastVal); - newConn->pushBackValsSilent(cPtr+icPtr[0],cPtr+icPtr[1]); - } - } - MEDCouplingAutoRefCountObjectPtr tmp=bary->selectByTupleIdSafe(ret->begin(),ret->end()); - coords=DataArrayDouble::Aggregate(getCoords(),tmp); conn=newConn.retn(); connI=newConnI.retn(); - return ret.retn(); -} - -DataArrayInt *MEDCouplingUMesh::convertLinearCellsToQuadratic2DAnd3D0(const MEDCouplingUMesh *m1D, const DataArrayInt *desc, const DataArrayInt *descI, DataArrayInt *&conn, DataArrayInt *&connI, DataArrayDouble *& coords, std::set& types) const -{ - MEDCouplingAutoRefCountObjectPtr newConn=DataArrayInt::New(); newConn->alloc(0,1); - MEDCouplingAutoRefCountObjectPtr newConnI=DataArrayInt::New(); newConnI->alloc(1,1); newConnI->setIJ(0,0,0); - MEDCouplingAutoRefCountObjectPtr ret=DataArrayInt::New(); ret->alloc(0,1); - // - const int *descPtr(desc->begin()),*descIPtr(descI->begin()); - DataArrayInt *conn1D=0,*conn1DI=0; - std::set types1D; - DataArrayDouble *coordsTmp=0; - MEDCouplingAutoRefCountObjectPtr ret1D=m1D->convertLinearCellsToQuadratic1D0(conn1D,conn1DI,coordsTmp,types1D); ret1D=0; - MEDCouplingAutoRefCountObjectPtr coordsTmpSafe(coordsTmp); - MEDCouplingAutoRefCountObjectPtr conn1DSafe(conn1D),conn1DISafe(conn1DI); - const int *c1DPtr=conn1D->begin(); - const int *c1DIPtr=conn1DI->begin(); - int nbOfCells=getNumberOfCells(); - const int *cPtr=_nodal_connec->getConstPointer(); - const int *icPtr=_nodal_connec_index->getConstPointer(); - int lastVal=0; - for(int i=0;ipushBackSilent(typ2); - newConn->pushBackValsSilent(cPtr+icPtr[0]+1,cPtr+icPtr[1]); - for(const int *d=descPtr+descIPtr[0];d!=descPtr+descIPtr[1];d++) - newConn->pushBackSilent(c1DPtr[c1DIPtr[*d]+3]); - lastVal+=(icPtr[1]-icPtr[0])+(descIPtr[1]-descIPtr[0]); - newConnI->pushBackSilent(lastVal); - ret->pushBackSilent(i); - } - else - { - types.insert(typ); - lastVal+=(icPtr[1]-icPtr[0]); - newConnI->pushBackSilent(lastVal); - newConn->pushBackValsSilent(cPtr+icPtr[0],cPtr+icPtr[1]); - } - } - conn=newConn.retn(); connI=newConnI.retn(); coords=coordsTmpSafe.retn(); - return ret.retn(); -} - -/*! - * Implementes \a conversionType 0 for meshes with meshDim = 2, of MEDCouplingUMesh::convertLinearCellsToQuadratic method. - * \return a newly created DataArrayInt instance that the caller should deal with containing cell ids of converted cells. - * \sa MEDCouplingUMesh::convertLinearCellsToQuadratic. - */ -DataArrayInt *MEDCouplingUMesh::convertLinearCellsToQuadratic2D0(DataArrayInt *&conn, DataArrayInt *&connI, DataArrayDouble *& coords, std::set& types) const -{ - MEDCouplingAutoRefCountObjectPtr desc(DataArrayInt::New()),descI(DataArrayInt::New()),tmp2(DataArrayInt::New()),tmp3(DataArrayInt::New()); - MEDCouplingAutoRefCountObjectPtr m1D=buildDescendingConnectivity(desc,descI,tmp2,tmp3); tmp2=0; tmp3=0; - return convertLinearCellsToQuadratic2DAnd3D0(m1D,desc,descI,conn,connI,coords,types); -} - -DataArrayInt *MEDCouplingUMesh::convertLinearCellsToQuadratic2D1(DataArrayInt *&conn, DataArrayInt *&connI, DataArrayDouble *& coords, std::set& types) const -{ - MEDCouplingAutoRefCountObjectPtr desc(DataArrayInt::New()),descI(DataArrayInt::New()),tmp2(DataArrayInt::New()),tmp3(DataArrayInt::New()); - MEDCouplingAutoRefCountObjectPtr m1D=buildDescendingConnectivity(desc,descI,tmp2,tmp3); tmp2=0; tmp3=0; - // - MEDCouplingAutoRefCountObjectPtr newConn=DataArrayInt::New(); newConn->alloc(0,1); - MEDCouplingAutoRefCountObjectPtr newConnI=DataArrayInt::New(); newConnI->alloc(1,1); newConnI->setIJ(0,0,0); - MEDCouplingAutoRefCountObjectPtr ret=DataArrayInt::New(); ret->alloc(0,1); - // - MEDCouplingAutoRefCountObjectPtr bary=getBarycenterAndOwner(); - const int *descPtr(desc->begin()),*descIPtr(descI->begin()); - DataArrayInt *conn1D=0,*conn1DI=0; - std::set types1D; - DataArrayDouble *coordsTmp=0; - MEDCouplingAutoRefCountObjectPtr ret1D=m1D->convertLinearCellsToQuadratic1D0(conn1D,conn1DI,coordsTmp,types1D); ret1D=0; - MEDCouplingAutoRefCountObjectPtr coordsTmpSafe(coordsTmp); - MEDCouplingAutoRefCountObjectPtr conn1DSafe(conn1D),conn1DISafe(conn1DI); - const int *c1DPtr=conn1D->begin(); - const int *c1DIPtr=conn1DI->begin(); - int nbOfCells=getNumberOfCells(); - const int *cPtr=_nodal_connec->getConstPointer(); - const int *icPtr=_nodal_connec_index->getConstPointer(); - int lastVal=0,offset=coordsTmpSafe->getNumberOfTuples(); - for(int i=0;ipushBackSilent(typ2); - newConn->pushBackValsSilent(cPtr+icPtr[0]+1,cPtr+icPtr[1]); - for(const int *d=descPtr+descIPtr[0];d!=descPtr+descIPtr[1];d++) - newConn->pushBackSilent(c1DPtr[c1DIPtr[*d]+3]); - newConn->pushBackSilent(offset+ret->getNumberOfTuples()); - lastVal+=(icPtr[1]-icPtr[0])+(descIPtr[1]-descIPtr[0])+1; - newConnI->pushBackSilent(lastVal); - ret->pushBackSilent(i); - } - else - { - types.insert(typ); - lastVal+=(icPtr[1]-icPtr[0]); - newConnI->pushBackSilent(lastVal); - newConn->pushBackValsSilent(cPtr+icPtr[0],cPtr+icPtr[1]); - } - } - MEDCouplingAutoRefCountObjectPtr tmp=bary->selectByTupleIdSafe(ret->begin(),ret->end()); - coords=DataArrayDouble::Aggregate(coordsTmpSafe,tmp); conn=newConn.retn(); connI=newConnI.retn(); - return ret.retn(); -} - -/*! - * Implementes \a conversionType 0 for meshes with meshDim = 3, of MEDCouplingUMesh::convertLinearCellsToQuadratic method. - * \return a newly created DataArrayInt instance that the caller should deal with containing cell ids of converted cells. - * \sa MEDCouplingUMesh::convertLinearCellsToQuadratic. - */ -DataArrayInt *MEDCouplingUMesh::convertLinearCellsToQuadratic3D0(DataArrayInt *&conn, DataArrayInt *&connI, DataArrayDouble *& coords, std::set& types) const -{ - MEDCouplingAutoRefCountObjectPtr desc(DataArrayInt::New()),descI(DataArrayInt::New()),tmp2(DataArrayInt::New()),tmp3(DataArrayInt::New()); - MEDCouplingAutoRefCountObjectPtr m1D=explode3DMeshTo1D(desc,descI,tmp2,tmp3); tmp2=0; tmp3=0; - return convertLinearCellsToQuadratic2DAnd3D0(m1D,desc,descI,conn,connI,coords,types); -} - -DataArrayInt *MEDCouplingUMesh::convertLinearCellsToQuadratic3D1(DataArrayInt *&conn, DataArrayInt *&connI, DataArrayDouble *& coords, std::set& types) const -{ - MEDCouplingAutoRefCountObjectPtr desc2(DataArrayInt::New()),desc2I(DataArrayInt::New()),tmp2(DataArrayInt::New()),tmp3(DataArrayInt::New()); - MEDCouplingAutoRefCountObjectPtr m2D=buildDescendingConnectivityGen(desc2,desc2I,tmp2,tmp3,MEDCouplingFastNbrer); tmp2=0; tmp3=0; - MEDCouplingAutoRefCountObjectPtr desc1(DataArrayInt::New()),desc1I(DataArrayInt::New()),tmp4(DataArrayInt::New()),tmp5(DataArrayInt::New()); - MEDCouplingAutoRefCountObjectPtr m1D=explode3DMeshTo1D(desc1,desc1I,tmp4,tmp5); tmp4=0; tmp5=0; - // - MEDCouplingAutoRefCountObjectPtr newConn=DataArrayInt::New(); newConn->alloc(0,1); - MEDCouplingAutoRefCountObjectPtr newConnI=DataArrayInt::New(); newConnI->alloc(1,1); newConnI->setIJ(0,0,0); - MEDCouplingAutoRefCountObjectPtr ret=DataArrayInt::New(),ret2=DataArrayInt::New(); ret->alloc(0,1); ret2->alloc(0,1); - // - MEDCouplingAutoRefCountObjectPtr bary=getBarycenterAndOwner(); - const int *descPtr(desc1->begin()),*descIPtr(desc1I->begin()),*desc2Ptr(desc2->begin()),*desc2IPtr(desc2I->begin()); - DataArrayInt *conn1D=0,*conn1DI=0,*conn2D=0,*conn2DI=0; - std::set types1D,types2D; - DataArrayDouble *coordsTmp=0,*coordsTmp2=0; - MEDCouplingAutoRefCountObjectPtr ret1D=m1D->convertLinearCellsToQuadratic1D0(conn1D,conn1DI,coordsTmp,types1D); ret1D=DataArrayInt::New(); ret1D->alloc(0,1); - MEDCouplingAutoRefCountObjectPtr conn1DSafe(conn1D),conn1DISafe(conn1DI); - MEDCouplingAutoRefCountObjectPtr coordsTmpSafe(coordsTmp); - MEDCouplingAutoRefCountObjectPtr ret2D=m2D->convertLinearCellsToQuadratic2D1(conn2D,conn2DI,coordsTmp2,types2D); ret2D=DataArrayInt::New(); ret2D->alloc(0,1); - MEDCouplingAutoRefCountObjectPtr coordsTmp2Safe(coordsTmp2); - MEDCouplingAutoRefCountObjectPtr conn2DSafe(conn2D),conn2DISafe(conn2DI); - const int *c1DPtr=conn1D->begin(),*c1DIPtr=conn1DI->begin(),*c2DPtr=conn2D->begin(),*c2DIPtr=conn2DI->begin(); - int nbOfCells=getNumberOfCells(); - const int *cPtr=_nodal_connec->getConstPointer(); - const int *icPtr=_nodal_connec_index->getConstPointer(); - int lastVal=0,offset=coordsTmpSafe->getNumberOfTuples(); - for(int i=0;ipushBackSilent(typ2); - newConn->pushBackValsSilent(cPtr+icPtr[0]+1,cPtr+icPtr[1]); - for(const int *d=descPtr+descIPtr[0];d!=descPtr+descIPtr[1];d++) - newConn->pushBackSilent(c1DPtr[c1DIPtr[*d]+3]); - for(const int *d=desc2Ptr+desc2IPtr[0];d!=desc2Ptr+desc2IPtr[1];d++) - { - int nodeId2=c2DPtr[c2DIPtr[(*d)+1]-1]; - int tmpPos=newConn->getNumberOfTuples(); - newConn->pushBackSilent(nodeId2); - ret2D->pushBackSilent(nodeId2); ret1D->pushBackSilent(tmpPos); - } - newConn->pushBackSilent(offset+ret->getNumberOfTuples()); - lastVal+=(icPtr[1]-icPtr[0])+(descIPtr[1]-descIPtr[0])+(desc2IPtr[1]-desc2IPtr[0])+1; - newConnI->pushBackSilent(lastVal); - ret->pushBackSilent(i); - } - else - { - types.insert(typ); - lastVal+=(icPtr[1]-icPtr[0]); - newConnI->pushBackSilent(lastVal); - newConn->pushBackValsSilent(cPtr+icPtr[0],cPtr+icPtr[1]); - } - } - MEDCouplingAutoRefCountObjectPtr diffRet2D=ret2D->getDifferentValues(); - MEDCouplingAutoRefCountObjectPtr o2nRet2D=diffRet2D->invertArrayN2O2O2N(coordsTmp2Safe->getNumberOfTuples()); - coordsTmp2Safe=coordsTmp2Safe->selectByTupleId(diffRet2D->begin(),diffRet2D->end()); - MEDCouplingAutoRefCountObjectPtr tmp=bary->selectByTupleIdSafe(ret->begin(),ret->end()); - std::vector v(3); v[0]=coordsTmpSafe; v[1]=coordsTmp2Safe; v[2]=tmp; - int *c=newConn->getPointer(); - const int *cI(newConnI->begin()); - for(const int *elt=ret1D->begin();elt!=ret1D->end();elt++) - c[*elt]=o2nRet2D->getIJ(c[*elt],0)+offset; - offset=coordsTmp2Safe->getNumberOfTuples(); - for(const int *elt=ret->begin();elt!=ret->end();elt++) - c[cI[(*elt)+1]-1]+=offset; - coords=DataArrayDouble::Aggregate(v); conn=newConn.retn(); connI=newConnI.retn(); - return ret.retn(); -} - -/*! - * Tessellates \a this 2D mesh by dividing not straight edges of quadratic faces, - * so that the number of cells remains the same. Quadratic faces are converted to - * polygons. This method works only for 2D meshes in - * 2D space. If no cells are quadratic (INTERP_KERNEL::NORM_QUAD8, - * INTERP_KERNEL::NORM_TRI6, INTERP_KERNEL::NORM_QPOLYG ), \a this mesh remains unchanged. - * \warning This method can lead to a huge amount of nodes if \a eps is very low. - * \param [in] eps - specifies the maximal angle (in radians) between 2 sub-edges of - * a polylinized edge constituting the input polygon. - * \throw If the coordinates array is not set. - * \throw If the nodal connectivity of cells is not defined. - * \throw If \a this->getMeshDimension() != 2. - * \throw If \a this->getSpaceDimension() != 2. - */ -void MEDCouplingUMesh::tessellate2D(double eps) -{ - checkFullyDefined(); - if(getMeshDimension()!=2 || getSpaceDimension()!=2) - throw INTERP_KERNEL::Exception("MEDCouplingUMesh::tessellate2D works on umeshes with meshdim equal to 2 and spaceDim equal to 2 too!"); - double epsa=fabs(eps); - if(epsa::min()) - throw INTERP_KERNEL::Exception("MEDCouplingUMesh::tessellate2DCurve : epsilon is null ! Please specify a higher epsilon. If too tiny it can lead to a huge amount of nodes and memory !"); - MEDCouplingAutoRefCountObjectPtr desc1=DataArrayInt::New(); - MEDCouplingAutoRefCountObjectPtr descIndx1=DataArrayInt::New(); - MEDCouplingAutoRefCountObjectPtr revDesc1=DataArrayInt::New(); - MEDCouplingAutoRefCountObjectPtr revDescIndx1=DataArrayInt::New(); - MEDCouplingAutoRefCountObjectPtr mDesc=buildDescendingConnectivity2(desc1,descIndx1,revDesc1,revDescIndx1); - revDesc1=0; revDescIndx1=0; - mDesc->tessellate2DCurve(eps); - subDivide2DMesh(mDesc->_nodal_connec->getConstPointer(),mDesc->_nodal_connec_index->getConstPointer(),desc1->getConstPointer(),descIndx1->getConstPointer()); - setCoords(mDesc->getCoords()); -} - -/*! - * Tessellates \a this 1D mesh in 2D space by dividing not straight quadratic edges. - * \warning This method can lead to a huge amount of nodes if \a eps is very low. - * \param [in] eps - specifies the maximal angle (in radian) between 2 sub-edges of - * a sub-divided edge. - * \throw If the coordinates array is not set. - * \throw If the nodal connectivity of cells is not defined. - * \throw If \a this->getMeshDimension() != 1. - * \throw If \a this->getSpaceDimension() != 2. - */ -void MEDCouplingUMesh::tessellate2DCurve(double eps) -{ - checkFullyDefined(); - if(getMeshDimension()!=1 || getSpaceDimension()!=2) - throw INTERP_KERNEL::Exception("MEDCouplingUMesh::tessellate2DCurve works on umeshes with meshdim equal to 1 and spaceDim equal to 2 too!"); - double epsa=fabs(eps); - if(epsa::min()) - throw INTERP_KERNEL::Exception("MEDCouplingUMesh::tessellate2DCurve : epsilon is null ! Please specify a higher epsilon. If too tiny it can lead to a huge amount of nodes and memory !"); - INTERP_KERNEL::QUADRATIC_PLANAR::_arc_detection_precision=1.e-10; - int nbCells=getNumberOfCells(); - int nbNodes=getNumberOfNodes(); - const int *conn=_nodal_connec->getConstPointer(); - const int *connI=_nodal_connec_index->getConstPointer(); - const double *coords=_coords->getConstPointer(); - std::vector addCoo; - std::vector newConn;//no direct DataArrayInt because interface with Geometric2D - MEDCouplingAutoRefCountObjectPtr newConnI(DataArrayInt::New()); - newConnI->alloc(nbCells+1,1); - int *newConnIPtr=newConnI->getPointer(); - *newConnIPtr=0; - int tmp1[3]; - INTERP_KERNEL::Node *tmp2[3]; - std::set types; - for(int i=0;itesselate(tmp1,nbNodes,epsa,newConn,addCoo); - types.insert((INTERP_KERNEL::NormalizedCellType)newConn[newConnIPtr[0]]); - delete eac; - newConnIPtr[1]=(int)newConn.size(); - } - else - { - types.insert(INTERP_KERNEL::NORM_SEG2); - newConn.push_back(INTERP_KERNEL::NORM_SEG2); - newConn.insert(newConn.end(),conn+connI[i]+1,conn+connI[i]+3); - newConnIPtr[1]=newConnIPtr[0]+3; - } - } - else - { - types.insert((INTERP_KERNEL::NormalizedCellType)conn[connI[i]]); - newConn.insert(newConn.end(),conn+connI[i],conn+connI[i+1]); - newConnIPtr[1]=newConnIPtr[0]+3; - } - } - if(addCoo.empty() && ((int)newConn.size())==_nodal_connec->getNumberOfTuples())//nothing happens during tessellation : no update needed - return ; - _types=types; - DataArrayInt::SetArrayIn(newConnI,_nodal_connec_index); - MEDCouplingAutoRefCountObjectPtr newConnArr=DataArrayInt::New(); - newConnArr->alloc((int)newConn.size(),1); - std::copy(newConn.begin(),newConn.end(),newConnArr->getPointer()); - DataArrayInt::SetArrayIn(newConnArr,_nodal_connec); - MEDCouplingAutoRefCountObjectPtr newCoords=DataArrayDouble::New(); - newCoords->alloc(nbNodes+((int)addCoo.size())/2,2); - double *work=std::copy(_coords->begin(),_coords->end(),newCoords->getPointer()); - std::copy(addCoo.begin(),addCoo.end(),work); - DataArrayDouble::SetArrayIn(newCoords,_coords); - updateTime(); -} - -/*! - * Divides every cell of \a this mesh into simplices (triangles in 2D and tetrahedra in 3D). - * In addition, returns an array mapping new cells to old ones.
- * This method typically increases the number of cells in \a this mesh - * but the number of nodes remains \b unchanged. - * That's why the 3D splitting policies - * INTERP_KERNEL::GENERAL_24 and INTERP_KERNEL::GENERAL_48 are not available here. - * \param [in] policy - specifies a pattern used for splitting. - * The semantic of \a policy is: - * - 0 - to split QUAD4 by cutting it along 0-2 diagonal (for 2D mesh only). - * - 1 - to split QUAD4 by cutting it along 1-3 diagonal (for 2D mesh only). - * - INTERP_KERNEL::PLANAR_FACE_5 - to split HEXA8 into 5 TETRA4 (for 3D mesh only - see INTERP_KERNEL::SplittingPolicy for an image). - * - INTERP_KERNEL::PLANAR_FACE_6 - to split HEXA8 into 6 TETRA4 (for 3D mesh only - see INTERP_KERNEL::SplittingPolicy for an image). - * - * - * \return DataArrayInt * - a new instance of DataArrayInt holding, for each new cell, - * an id of old cell producing it. The caller is to delete this array using - * decrRef() as it is no more needed. - * - * \throw If \a policy is 0 or 1 and \a this->getMeshDimension() != 2. - * \throw If \a policy is INTERP_KERNEL::PLANAR_FACE_5 or INTERP_KERNEL::PLANAR_FACE_6 - * and \a this->getMeshDimension() != 3. - * \throw If \a policy is not one of the four discussed above. - * \throw If the nodal connectivity of cells is not defined. - * \sa MEDCouplingUMesh::tetrahedrize, MEDCoupling1SGTUMesh::sortHexa8EachOther - */ -DataArrayInt *MEDCouplingUMesh::simplexize(int policy) -{ - switch(policy) - { - case 0: - return simplexizePol0(); - case 1: - return simplexizePol1(); - case (int) INTERP_KERNEL::PLANAR_FACE_5: - return simplexizePlanarFace5(); - case (int) INTERP_KERNEL::PLANAR_FACE_6: - return simplexizePlanarFace6(); - default: - throw INTERP_KERNEL::Exception("MEDCouplingUMesh::simplexize : unrecognized policy ! Must be :\n - 0 or 1 (only available for meshdim=2) \n - PLANAR_FACE_5, PLANAR_FACE_6 (only for meshdim=3)"); - } -} - -/*! - * Checks if \a this mesh is constituted by simplex cells only. Simplex cells are: - * - 1D: INTERP_KERNEL::NORM_SEG2 - * - 2D: INTERP_KERNEL::NORM_TRI3 - * - 3D: INTERP_KERNEL::NORM_TETRA4. - * - * This method is useful for users that need to use P1 field services as - * MEDCouplingFieldDouble::getValueOn(), MEDCouplingField::buildMeasureField() etc. - * All these methods need mesh support containing only simplex cells. - * \return bool - \c true if there are only simplex cells in \a this mesh. - * \throw If the coordinates array is not set. - * \throw If the nodal connectivity of cells is not defined. - * \throw If \a this->getMeshDimension() < 1. - */ -bool MEDCouplingUMesh::areOnlySimplexCells() const -{ - checkFullyDefined(); - int mdim=getMeshDimension(); - if(mdim<1 || mdim>3) - throw INTERP_KERNEL::Exception("MEDCouplingUMesh::areOnlySimplexCells : only available with meshes having a meshdim 1, 2 or 3 !"); - int nbCells=getNumberOfCells(); - const int *conn=_nodal_connec->getConstPointer(); - const int *connI=_nodal_connec_index->getConstPointer(); - for(int i=0;i ret=DataArrayInt::New(); - int nbOfCutCells=getNumberOfCellsWithType(INTERP_KERNEL::NORM_QUAD4); - ret->alloc(nbOfCells+nbOfCutCells,1); - if(nbOfCutCells==0) { ret->iota(0); return ret.retn(); } - int *retPt=ret->getPointer(); - MEDCouplingAutoRefCountObjectPtr newConn=DataArrayInt::New(); - MEDCouplingAutoRefCountObjectPtr newConnI=DataArrayInt::New(); - newConnI->alloc(nbOfCells+nbOfCutCells+1,1); - newConn->alloc(getMeshLength()+3*nbOfCutCells,1); - int *pt=newConn->getPointer(); - int *ptI=newConnI->getPointer(); - ptI[0]=0; - const int *oldc=_nodal_connec->getConstPointer(); - const int *ci=_nodal_connec_index->getConstPointer(); - for(int i=0;idecrRef(); - _nodal_connec=newConn.retn(); - _nodal_connec_index->decrRef(); - _nodal_connec_index=newConnI.retn(); - computeTypes(); - updateTime(); - return ret.retn(); -} - -/*! - * This method implements policy 1 of virtual method ParaMEDMEM::MEDCouplingUMesh::simplexize. - */ -DataArrayInt *MEDCouplingUMesh::simplexizePol1() -{ - checkConnectivityFullyDefined(); - if(getMeshDimension()!=2) - throw INTERP_KERNEL::Exception("MEDCouplingUMesh::simplexizePol0 : this policy is only available for mesh with meshdim == 2 !"); - int nbOfCells=getNumberOfCells(); - MEDCouplingAutoRefCountObjectPtr ret=DataArrayInt::New(); - int nbOfCutCells=getNumberOfCellsWithType(INTERP_KERNEL::NORM_QUAD4); - ret->alloc(nbOfCells+nbOfCutCells,1); - if(nbOfCutCells==0) { ret->iota(0); return ret.retn(); } - int *retPt=ret->getPointer(); - MEDCouplingAutoRefCountObjectPtr newConn=DataArrayInt::New(); - MEDCouplingAutoRefCountObjectPtr newConnI=DataArrayInt::New(); - newConnI->alloc(nbOfCells+nbOfCutCells+1,1); - newConn->alloc(getMeshLength()+3*nbOfCutCells,1); - int *pt=newConn->getPointer(); - int *ptI=newConnI->getPointer(); - ptI[0]=0; - const int *oldc=_nodal_connec->getConstPointer(); - const int *ci=_nodal_connec_index->getConstPointer(); - for(int i=0;idecrRef(); - _nodal_connec=newConn.retn(); - _nodal_connec_index->decrRef(); - _nodal_connec_index=newConnI.retn(); - computeTypes(); - updateTime(); - return ret.retn(); -} - -/*! - * This method implements policy INTERP_KERNEL::PLANAR_FACE_5 of virtual method ParaMEDMEM::MEDCouplingUMesh::simplexize. - */ -DataArrayInt *MEDCouplingUMesh::simplexizePlanarFace5() -{ - checkConnectivityFullyDefined(); - if(getMeshDimension()!=3) - throw INTERP_KERNEL::Exception("MEDCouplingUMesh::simplexizePlanarFace5 : this policy is only available for mesh with meshdim == 3 !"); - int nbOfCells=getNumberOfCells(); - MEDCouplingAutoRefCountObjectPtr ret=DataArrayInt::New(); - int nbOfCutCells=getNumberOfCellsWithType(INTERP_KERNEL::NORM_HEXA8); - ret->alloc(nbOfCells+4*nbOfCutCells,1); - if(nbOfCutCells==0) { ret->iota(0); return ret.retn(); } - int *retPt=ret->getPointer(); - MEDCouplingAutoRefCountObjectPtr newConn=DataArrayInt::New(); - MEDCouplingAutoRefCountObjectPtr newConnI=DataArrayInt::New(); - newConnI->alloc(nbOfCells+4*nbOfCutCells+1,1); - newConn->alloc(getMeshLength()+16*nbOfCutCells,1);//21 - int *pt=newConn->getPointer(); - int *ptI=newConnI->getPointer(); - ptI[0]=0; - const int *oldc=_nodal_connec->getConstPointer(); - const int *ci=_nodal_connec_index->getConstPointer(); - for(int i=0;idecrRef(); - _nodal_connec=newConn.retn(); - _nodal_connec_index->decrRef(); - _nodal_connec_index=newConnI.retn(); - computeTypes(); - updateTime(); - return ret.retn(); -} - -/*! - * This method implements policy INTERP_KERNEL::PLANAR_FACE_6 of virtual method ParaMEDMEM::MEDCouplingUMesh::simplexize. - */ -DataArrayInt *MEDCouplingUMesh::simplexizePlanarFace6() -{ - checkConnectivityFullyDefined(); - if(getMeshDimension()!=3) - throw INTERP_KERNEL::Exception("MEDCouplingUMesh::simplexizePlanarFace6 : this policy is only available for mesh with meshdim == 3 !"); - int nbOfCells=getNumberOfCells(); - MEDCouplingAutoRefCountObjectPtr ret=DataArrayInt::New(); - int nbOfCutCells=getNumberOfCellsWithType(INTERP_KERNEL::NORM_HEXA8); - ret->alloc(nbOfCells+5*nbOfCutCells,1); - if(nbOfCutCells==0) { ret->iota(0); return ret.retn(); } - int *retPt=ret->getPointer(); - MEDCouplingAutoRefCountObjectPtr newConn=DataArrayInt::New(); - MEDCouplingAutoRefCountObjectPtr newConnI=DataArrayInt::New(); - newConnI->alloc(nbOfCells+5*nbOfCutCells+1,1); - newConn->alloc(getMeshLength()+21*nbOfCutCells,1); - int *pt=newConn->getPointer(); - int *ptI=newConnI->getPointer(); - ptI[0]=0; - const int *oldc=_nodal_connec->getConstPointer(); - const int *ci=_nodal_connec_index->getConstPointer(); - for(int i=0;idecrRef(); - _nodal_connec=newConn.retn(); - _nodal_connec_index->decrRef(); - _nodal_connec_index=newConnI.retn(); - computeTypes(); - updateTime(); - return ret.retn(); -} - -/*! - * This private method is used to subdivide edges of a mesh with meshdim==2. If \a this has no a meshdim equal to 2 an exception will be thrown. - * This method completly ignore coordinates. - * \param nodeSubdived is the nodal connectivity of subdivision of edges - * \param nodeIndxSubdived is the nodal connectivity index of subdivision of edges - * \param desc is descending connectivity in format specified in MEDCouplingUMesh::buildDescendingConnectivity2 - * \param descIndex is descending connectivity index in format specified in MEDCouplingUMesh::buildDescendingConnectivity2 - */ -void MEDCouplingUMesh::subDivide2DMesh(const int *nodeSubdived, const int *nodeIndxSubdived, const int *desc, const int *descIndex) -{ - checkFullyDefined(); - if(getMeshDimension()!=2) - throw INTERP_KERNEL::Exception("MEDCouplingUMesh::subDivide2DMesh : works only on umesh with meshdim==2 !"); - int nbOfCells=getNumberOfCells(); - int *connI=_nodal_connec_index->getPointer(); - int newConnLgth=0; - for(int i=0;i0; - int eedgeId=std::abs(desc[offset+nbOfEdges-1])-1; - int ref=ddirect?nodeSubdived[nodeIndxSubdived[eedgeId+1]-1]:nodeSubdived[nodeIndxSubdived[eedgeId]+1]; - for(int j=0;j0; - int edgeId=std::abs(desc[offset+j])-1; - if(!INTERP_KERNEL::CellModel::GetCellModel((INTERP_KERNEL::NormalizedCellType)nodeSubdived[nodeIndxSubdived[edgeId]]).isQuadratic()) - { - int id1=nodeSubdived[nodeIndxSubdived[edgeId]+1]; - int id2=nodeSubdived[nodeIndxSubdived[edgeId+1]-1]; - int ref2=direct?id1:id2; - if(ref==ref2) - { - int nbOfSubNodes=nodeIndxSubdived[edgeId+1]-nodeIndxSubdived[edgeId]-1; - newConnLgth+=nbOfSubNodes-1; - ref=direct?id2:id1; - } - else - { - std::ostringstream oss; oss << "MEDCouplingUMesh::subDivide2DMesh : On polygon #" << i << " edgeid #" << j << " subedges mismatch : end subedge k!=start subedge k+1 !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - } - else - { - throw INTERP_KERNEL::Exception("MEDCouplingUMesh::subDivide2DMesh : this method only subdivides into linear edges !"); - } - } - newConnLgth++;//+1 is for cell type - connI[1]=newConnLgth; - } - // - MEDCouplingAutoRefCountObjectPtr newConn=DataArrayInt::New(); - newConn->alloc(newConnLgth,1); - int *work=newConn->getPointer(); - for(int i=0;i0; - int edgeId=std::abs(desc[offset+j])-1; - if(direct) - work=std::copy(nodeSubdived+nodeIndxSubdived[edgeId]+1,nodeSubdived+nodeIndxSubdived[edgeId+1]-1,work); - else - { - int nbOfSubNodes=nodeIndxSubdived[edgeId+1]-nodeIndxSubdived[edgeId]-1; - std::reverse_iterator it(nodeSubdived+nodeIndxSubdived[edgeId+1]); - work=std::copy(it,it+nbOfSubNodes-1,work); - } - } - } - DataArrayInt::SetArrayIn(newConn,_nodal_connec); - _types.clear(); - if(nbOfCells>0) - _types.insert(INTERP_KERNEL::NORM_POLYGON); -} - -/*! - * Converts degenerated 2D or 3D linear cells of \a this mesh into cells of simpler - * type. For example an INTERP_KERNEL::NORM_QUAD4 cell having only three unique nodes in - * its connectivity is transformed into an INTERP_KERNEL::NORM_TRI3 cell. This method - * does \b not perform geometrical checks and checks only nodal connectivity of cells, - * so it can be useful to call mergeNodes() before calling this method. - * \throw If \a this->getMeshDimension() <= 1. - * \throw If the coordinates array is not set. - * \throw If the nodal connectivity of cells is not defined. - */ -void MEDCouplingUMesh::convertDegeneratedCells() -{ - checkFullyDefined(); - if(getMeshDimension()<=1) - throw INTERP_KERNEL::Exception("MEDCouplingUMesh::convertDegeneratedCells works on umeshes with meshdim equals to 2 or 3 !"); - int nbOfCells=getNumberOfCells(); - if(nbOfCells<1) - return ; - int initMeshLgth=getMeshLength(); - int *conn=_nodal_connec->getPointer(); - int *index=_nodal_connec_index->getPointer(); - int posOfCurCell=0; - int newPos=0; - int lgthOfCurCell; - for(int i=0;ireAlloc(newPos); - computeTypes(); -} - -/*! - * Finds incorrectly oriented cells of this 2D mesh in 3D space. - * A cell is considered to be oriented correctly if an angle between its - * normal vector and a given vector is less than \c PI / \c 2. - * \param [in] vec - 3 components of the vector specifying the correct orientation of - * cells. - * \param [in] polyOnly - if \c true, only polygons are checked, else, all cells are - * checked. - * \param [in,out] cells - a vector returning ids of incorrectly oriented cells. It - * is not cleared before filling in. - * \throw If \a this->getMeshDimension() != 2. - * \throw If \a this->getSpaceDimension() != 3. - * - * \if ENABLE_EXAMPLES - * \ref cpp_mcumesh_are2DCellsNotCorrectlyOriented "Here is a C++ example".
- * \ref py_mcumesh_are2DCellsNotCorrectlyOriented "Here is a Python example". - * \endif - */ -void MEDCouplingUMesh::are2DCellsNotCorrectlyOriented(const double *vec, bool polyOnly, std::vector& cells) const -{ - if(getMeshDimension()!=2 || getSpaceDimension()!=3) - throw INTERP_KERNEL::Exception("Invalid mesh to apply are2DCellsNotCorrectlyOriented on it : must be meshDim==2 and spaceDim==3 !"); - int nbOfCells=getNumberOfCells(); - const int *conn=_nodal_connec->getConstPointer(); - const int *connI=_nodal_connec_index->getConstPointer(); - const double *coordsPtr=_coords->getConstPointer(); - for(int i=0;igetMeshDimension() != 2. - * \throw If \a this->getSpaceDimension() != 3. - * - * \if ENABLE_EXAMPLES - * \ref cpp_mcumesh_are2DCellsNotCorrectlyOriented "Here is a C++ example".
- * \ref py_mcumesh_are2DCellsNotCorrectlyOriented "Here is a Python example". - * \endif - * - * \sa changeOrientationOfCells - */ -void MEDCouplingUMesh::orientCorrectly2DCells(const double *vec, bool polyOnly) -{ - if(getMeshDimension()!=2 || getSpaceDimension()!=3) - throw INTERP_KERNEL::Exception("Invalid mesh to apply orientCorrectly2DCells on it : must be meshDim==2 and spaceDim==3 !"); - int nbOfCells(getNumberOfCells()),*conn(_nodal_connec->getPointer()); - const int *connI(_nodal_connec_index->getConstPointer()); - const double *coordsPtr(_coords->getConstPointer()); - bool isModified(false); - for(int i=0;ideclareAsNew(); - updateTime(); -} - -/*! - * This method change the orientation of cells in \a this without any consideration of coordinates. Only connectivity is impacted. - * - * \sa orientCorrectly2DCells - */ -void MEDCouplingUMesh::changeOrientationOfCells() -{ - int mdim(getMeshDimension()); - if(mdim!=2 && mdim!=1) - throw INTERP_KERNEL::Exception("Invalid mesh to apply changeOrientationOfCells on it : must be meshDim==2 or meshDim==1 !"); - int nbOfCells(getNumberOfCells()),*conn(_nodal_connec->getPointer()); - const int *connI(_nodal_connec_index->getConstPointer()); - if(mdim==2) - {//2D - for(int i=0;igetMeshDimension() != 3. - * \throw If \a this->getSpaceDimension() != 3. - * \throw If the coordinates array is not set. - * \throw If the nodal connectivity of cells is not defined. - * - * \if ENABLE_EXAMPLES - * \ref cpp_mcumesh_arePolyhedronsNotCorrectlyOriented "Here is a C++ example".
- * \ref py_mcumesh_arePolyhedronsNotCorrectlyOriented "Here is a Python example". - * \endif - */ -void MEDCouplingUMesh::arePolyhedronsNotCorrectlyOriented(std::vector& cells) const -{ - if(getMeshDimension()!=3 || getSpaceDimension()!=3) - throw INTERP_KERNEL::Exception("Invalid mesh to apply arePolyhedronsNotCorrectlyOriented on it : must be meshDim==3 and spaceDim==3 !"); - int nbOfCells=getNumberOfCells(); - const int *conn=_nodal_connec->getConstPointer(); - const int *connI=_nodal_connec_index->getConstPointer(); - const double *coordsPtr=_coords->getConstPointer(); - for(int i=0;igetMeshDimension() != 3. - * \throw If \a this->getSpaceDimension() != 3. - * \throw If the coordinates array is not set. - * \throw If the nodal connectivity of cells is not defined. - * \throw If the reparation fails. - * - * \if ENABLE_EXAMPLES - * \ref cpp_mcumesh_arePolyhedronsNotCorrectlyOriented "Here is a C++ example".
- * \ref py_mcumesh_arePolyhedronsNotCorrectlyOriented "Here is a Python example". - * \endif - * \sa MEDCouplingUMesh::findAndCorrectBadOriented3DCells - */ -void MEDCouplingUMesh::orientCorrectlyPolyhedrons() -{ - if(getMeshDimension()!=3 || getSpaceDimension()!=3) - throw INTERP_KERNEL::Exception("Invalid mesh to apply orientCorrectlyPolyhedrons on it : must be meshDim==3 and spaceDim==3 !"); - int nbOfCells=getNumberOfCells(); - int *conn=_nodal_connec->getPointer(); - const int *connI=_nodal_connec_index->getConstPointer(); - const double *coordsPtr=_coords->getConstPointer(); - for(int i=0;igetMeshDimension() != 3. - * \throw If \a this->getSpaceDimension() != 3. - * \throw If the coordinates array is not set. - * \throw If the nodal connectivity of cells is not defined. - * - * \if ENABLE_EXAMPLES - * \ref cpp_mcumesh_findAndCorrectBadOriented3DExtrudedCells "Here is a C++ example".
- * \ref py_mcumesh_findAndCorrectBadOriented3DExtrudedCells "Here is a Python example". - * \endif - * \sa MEDCouplingUMesh::findAndCorrectBadOriented3DCells - */ -DataArrayInt *MEDCouplingUMesh::findAndCorrectBadOriented3DExtrudedCells() -{ - const char msg[]="check3DCellsWellOriented detection works only for 3D cells !"; - if(getMeshDimension()!=3) - throw INTERP_KERNEL::Exception(msg); - int spaceDim=getSpaceDimension(); - if(spaceDim!=3) - throw INTERP_KERNEL::Exception(msg); - // - int nbOfCells=getNumberOfCells(); - int *conn=_nodal_connec->getPointer(); - const int *connI=_nodal_connec_index->getConstPointer(); - const double *coo=getCoords()->getConstPointer(); - MEDCouplingAutoRefCountObjectPtr cells(DataArrayInt::New()); cells->alloc(0,1); - for(int i=0;ipushBackSilent(i); - } - } - } - return cells.retn(); -} - -/*! - * This method is a faster method to correct orientation of all 3D cells in \a this. - * This method works only if \a this is a 3D mesh, that is to say a mesh with mesh dimension 3 and a space dimension 3. - * This method makes the hypothesis that \a this a coherent that is to say MEDCouplingUMesh::checkCoherency2 should throw no exception. - * - * \return a newly allocated int array with one components containing cell ids renumbered to fit the convention of MED (MED file and MEDCoupling) - * \sa MEDCouplingUMesh::orientCorrectlyPolyhedrons, - */ -DataArrayInt *MEDCouplingUMesh::findAndCorrectBadOriented3DCells() -{ - if(getMeshDimension()!=3 || getSpaceDimension()!=3) - throw INTERP_KERNEL::Exception("Invalid mesh to apply findAndCorrectBadOriented3DCells on it : must be meshDim==3 and spaceDim==3 !"); - int nbOfCells=getNumberOfCells(); - int *conn=_nodal_connec->getPointer(); - const int *connI=_nodal_connec_index->getConstPointer(); - const double *coordsPtr=_coords->getConstPointer(); - MEDCouplingAutoRefCountObjectPtr ret=DataArrayInt::New(); ret->alloc(0,1); - for(int i=0;ipushBackSilent(i); - } - break; - } - case INTERP_KERNEL::NORM_PYRA5: - { - if(!IsPyra5WellOriented(conn+connI[i]+1,conn+connI[i+1],coordsPtr)) - { - std::swap(*(conn+connI[i]+2),*(conn+connI[i]+4)); - ret->pushBackSilent(i); - } - break; - } - case INTERP_KERNEL::NORM_PENTA6: - case INTERP_KERNEL::NORM_HEXA8: - case INTERP_KERNEL::NORM_HEXGP12: - { - if(!Is3DExtrudedStaticCellWellOriented(conn+connI[i]+1,conn+connI[i+1],coordsPtr)) - { - CorrectExtrudedStaticCell(conn+connI[i]+1,conn+connI[i+1]); - ret->pushBackSilent(i); - } - break; - } - case INTERP_KERNEL::NORM_POLYHED: - { - if(!IsPolyhedronWellOriented(conn+connI[i]+1,conn+connI[i+1],coordsPtr)) - { - TryToCorrectPolyhedronOrientation(conn+connI[i]+1,conn+connI[i+1],coordsPtr); - ret->pushBackSilent(i); - } - break; - } - default: - throw INTERP_KERNEL::Exception("MEDCouplingUMesh::orientCorrectly3DCells : Your mesh contains type of cell not supported yet ! send mail to anthony.geay@cea.fr to add it !"); - } - } - updateTime(); - return ret.retn(); -} - -/*! - * This method has a sense for meshes with spaceDim==3 and meshDim==2. - * If it is not the case an exception will be thrown. - * This method is fast because the first cell of \a this is used to compute the plane. - * \param vec output of size at least 3 used to store the normal vector (with norm equal to Area ) of searched plane. - * \param pos output of size at least 3 used to store a point owned of searched plane. - */ -void MEDCouplingUMesh::getFastAveragePlaneOfThis(double *vec, double *pos) const -{ - if(getMeshDimension()!=2 || getSpaceDimension()!=3) - throw INTERP_KERNEL::Exception("Invalid mesh to apply getFastAveragePlaneOfThis on it : must be meshDim==2 and spaceDim==3 !"); - const int *conn=_nodal_connec->getConstPointer(); - const int *connI=_nodal_connec_index->getConstPointer(); - const double *coordsPtr=_coords->getConstPointer(); - INTERP_KERNEL::areaVectorOfPolygon(conn+1,connI[1]-connI[0]-1,coordsPtr,vec); - std::copy(coordsPtr+3*conn[1],coordsPtr+3*conn[1]+3,pos); -} - -/*! - * Creates a new MEDCouplingFieldDouble holding Edge Ratio values of all - * cells. Currently cells of the following types are treated: - * INTERP_KERNEL::NORM_TRI3, INTERP_KERNEL::NORM_QUAD4 and INTERP_KERNEL::NORM_TETRA4. - * For a cell of other type an exception is thrown. - * Space dimension of a 2D mesh can be either 2 or 3. - * The Edge Ratio of a cell \f$t\f$ is: - * \f$\frac{|t|_\infty}{|t|_0}\f$, - * where \f$|t|_\infty\f$ and \f$|t|_0\f$ respectively denote the greatest and - * the smallest edge lengths of \f$t\f$. - * \return MEDCouplingFieldDouble * - a new instance of MEDCouplingFieldDouble on - * cells and one time, lying on \a this mesh. The caller is to delete this - * field using decrRef() as it is no more needed. - * \throw If the coordinates array is not set. - * \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 \a this->getMeshDimension() is neither 2 nor 3. - * \throw If \a this->getSpaceDimension() is neither 2 nor 3. - * \throw If \a this mesh includes cells of type different from the ones enumerated above. - */ -MEDCouplingFieldDouble *MEDCouplingUMesh::getEdgeRatioField() const -{ - checkCoherency(); - int spaceDim=getSpaceDimension(); - int meshDim=getMeshDimension(); - if(spaceDim!=2 && spaceDim!=3) - throw INTERP_KERNEL::Exception("MEDCouplingUMesh::getEdgeRatioField : SpaceDimension must be equal to 2 or 3 !"); - if(meshDim!=2 && meshDim!=3) - throw INTERP_KERNEL::Exception("MEDCouplingUMesh::getEdgeRatioField : MeshDimension must be equal to 2 or 3 !"); - MEDCouplingAutoRefCountObjectPtr ret=MEDCouplingFieldDouble::New(ON_CELLS,ONE_TIME); - ret->setMesh(this); - int nbOfCells=getNumberOfCells(); - MEDCouplingAutoRefCountObjectPtr arr=DataArrayDouble::New(); - arr->alloc(nbOfCells,1); - double *pt=arr->getPointer(); - ret->setArray(arr);//In case of throw to avoid mem leaks arr will be used after decrRef. - const int *conn=_nodal_connec->getConstPointer(); - const int *connI=_nodal_connec_index->getConstPointer(); - const double *coo=_coords->getConstPointer(); - double tmp[12]; - for(int i=0;isetName("EdgeRatio"); - ret->synchronizeTimeWithSupport(); - return ret.retn(); -} - -/*! - * Creates a new MEDCouplingFieldDouble holding Aspect Ratio values of all - * cells. Currently cells of the following types are treated: - * INTERP_KERNEL::NORM_TRI3, INTERP_KERNEL::NORM_QUAD4 and INTERP_KERNEL::NORM_TETRA4. - * For a cell of other type an exception is thrown. - * Space dimension of a 2D mesh can be either 2 or 3. - * \return MEDCouplingFieldDouble * - a new instance of MEDCouplingFieldDouble on - * cells and one time, lying on \a this mesh. The caller is to delete this - * field using decrRef() as it is no more needed. - * \throw If the coordinates array is not set. - * \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 \a this->getMeshDimension() is neither 2 nor 3. - * \throw If \a this->getSpaceDimension() is neither 2 nor 3. - * \throw If \a this mesh includes cells of type different from the ones enumerated above. - */ -MEDCouplingFieldDouble *MEDCouplingUMesh::getAspectRatioField() const -{ - checkCoherency(); - int spaceDim=getSpaceDimension(); - int meshDim=getMeshDimension(); - if(spaceDim!=2 && spaceDim!=3) - throw INTERP_KERNEL::Exception("MEDCouplingUMesh::getAspectRatioField : SpaceDimension must be equal to 2 or 3 !"); - if(meshDim!=2 && meshDim!=3) - throw INTERP_KERNEL::Exception("MEDCouplingUMesh::getAspectRatioField : MeshDimension must be equal to 2 or 3 !"); - MEDCouplingAutoRefCountObjectPtr ret=MEDCouplingFieldDouble::New(ON_CELLS,ONE_TIME); - ret->setMesh(this); - int nbOfCells=getNumberOfCells(); - MEDCouplingAutoRefCountObjectPtr arr=DataArrayDouble::New(); - arr->alloc(nbOfCells,1); - double *pt=arr->getPointer(); - ret->setArray(arr);//In case of throw to avoid mem leaks arr will be used after decrRef. - const int *conn=_nodal_connec->getConstPointer(); - const int *connI=_nodal_connec_index->getConstPointer(); - const double *coo=_coords->getConstPointer(); - double tmp[12]; - for(int i=0;isetName("AspectRatio"); - ret->synchronizeTimeWithSupport(); - return ret.retn(); -} - -/*! - * Creates a new MEDCouplingFieldDouble holding Warping factor values of all - * cells of \a this 2D mesh in 3D space. Currently cells of the following types are - * treated: INTERP_KERNEL::NORM_QUAD4. - * For a cell of other type an exception is thrown. - * \return MEDCouplingFieldDouble * - a new instance of MEDCouplingFieldDouble on - * cells and one time, lying on \a this mesh. The caller is to delete this - * field using decrRef() as it is no more needed. - * \throw If the coordinates array is not set. - * \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 \a this->getMeshDimension() != 2. - * \throw If \a this->getSpaceDimension() != 3. - * \throw If \a this mesh includes cells of type different from the ones enumerated above. - */ -MEDCouplingFieldDouble *MEDCouplingUMesh::getWarpField() const -{ - checkCoherency(); - int spaceDim=getSpaceDimension(); - int meshDim=getMeshDimension(); - if(spaceDim!=3) - throw INTERP_KERNEL::Exception("MEDCouplingUMesh::getWarpField : SpaceDimension must be equal to 3 !"); - if(meshDim!=2) - throw INTERP_KERNEL::Exception("MEDCouplingUMesh::getWarpField : MeshDimension must be equal to 2 !"); - MEDCouplingAutoRefCountObjectPtr ret=MEDCouplingFieldDouble::New(ON_CELLS,ONE_TIME); - ret->setMesh(this); - int nbOfCells=getNumberOfCells(); - MEDCouplingAutoRefCountObjectPtr arr=DataArrayDouble::New(); - arr->alloc(nbOfCells,1); - double *pt=arr->getPointer(); - ret->setArray(arr);//In case of throw to avoid mem leaks arr will be used after decrRef. - const int *conn=_nodal_connec->getConstPointer(); - const int *connI=_nodal_connec_index->getConstPointer(); - const double *coo=_coords->getConstPointer(); - double tmp[12]; - for(int i=0;isetName("Warp"); - ret->synchronizeTimeWithSupport(); - return ret.retn(); -} - - -/*! - * Creates a new MEDCouplingFieldDouble holding Skew factor values of all - * cells of \a this 2D mesh in 3D space. Currently cells of the following types are - * treated: INTERP_KERNEL::NORM_QUAD4. - * For a cell of other type an exception is thrown. - * \return MEDCouplingFieldDouble * - a new instance of MEDCouplingFieldDouble on - * cells and one time, lying on \a this mesh. The caller is to delete this - * field using decrRef() as it is no more needed. - * \throw If the coordinates array is not set. - * \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 \a this->getMeshDimension() != 2. - * \throw If \a this->getSpaceDimension() != 3. - * \throw If \a this mesh includes cells of type different from the ones enumerated above. - */ -MEDCouplingFieldDouble *MEDCouplingUMesh::getSkewField() const -{ - checkCoherency(); - int spaceDim=getSpaceDimension(); - int meshDim=getMeshDimension(); - if(spaceDim!=3) - throw INTERP_KERNEL::Exception("MEDCouplingUMesh::getSkewField : SpaceDimension must be equal to 3 !"); - if(meshDim!=2) - throw INTERP_KERNEL::Exception("MEDCouplingUMesh::getSkewField : MeshDimension must be equal to 2 !"); - MEDCouplingAutoRefCountObjectPtr ret=MEDCouplingFieldDouble::New(ON_CELLS,ONE_TIME); - ret->setMesh(this); - int nbOfCells=getNumberOfCells(); - MEDCouplingAutoRefCountObjectPtr arr=DataArrayDouble::New(); - arr->alloc(nbOfCells,1); - double *pt=arr->getPointer(); - ret->setArray(arr);//In case of throw to avoid mem leaks arr will be used after decrRef. - const int *conn=_nodal_connec->getConstPointer(); - const int *connI=_nodal_connec_index->getConstPointer(); - const double *coo=_coords->getConstPointer(); - double tmp[12]; - for(int i=0;isetName("Skew"); - ret->synchronizeTimeWithSupport(); - return ret.retn(); -} - -/*! - * Returns the cell field giving for each cell in \a this its diameter. Diameter means the max length of all possible SEG2 in the cell. - * - * \return a new instance of field containing the result. The returned instance has to be deallocated by the caller. - * - * \sa getSkewField, getWarpField, getAspectRatioField, getEdgeRatioField - */ -MEDCouplingFieldDouble *MEDCouplingUMesh::computeDiameterField() const -{ - checkCoherency(); - MEDCouplingAutoRefCountObjectPtr ret(MEDCouplingFieldDouble::New(ON_CELLS,ONE_TIME)); - ret->setMesh(this); - std::set types; - ComputeAllTypesInternal(types,_nodal_connec,_nodal_connec_index); - int spaceDim(getSpaceDimension()),nbCells(getNumberOfCells()); - MEDCouplingAutoRefCountObjectPtr arr(DataArrayDouble::New()); - arr->alloc(nbCells,1); - for(std::set::const_iterator it=types.begin();it!=types.end();it++) - { - INTERP_KERNEL::AutoCppPtr dc(INTERP_KERNEL::CellModel::GetCellModel(*it).buildInstanceOfDiameterCalulator(spaceDim)); - MEDCouplingAutoRefCountObjectPtr cellIds(giveCellsWithType(*it)); - dc->computeForListOfCellIdsUMeshFrmt(cellIds->begin(),cellIds->end(),_nodal_connec_index->begin(),_nodal_connec->begin(),getCoords()->begin(),arr->getPointer()); - } - ret->setArray(arr); - ret->setName("Diameter"); - return ret.retn(); -} - -/*! - * This method aggregate the bbox of each cell and put it into bbox parameter. - * - * \param [in] arcDetEps - a parameter specifying in case of 2D quadratic polygon cell the detection limit between linear and arc circle. (By default 1e-12) - * For all other cases this input parameter is ignored. - * \return DataArrayDouble * - newly created object (to be managed by the caller) \a this number of cells tuples and 2*spacedim components. - * - * \throw If \a this is not fully set (coordinates and connectivity). - * \throw If a cell in \a this has no valid nodeId. - * \sa MEDCouplingUMesh::getBoundingBoxForBBTreeFast, MEDCouplingUMesh::getBoundingBoxForBBTree2DQuadratic - */ -DataArrayDouble *MEDCouplingUMesh::getBoundingBoxForBBTree(double arcDetEps) const -{ - int mDim(getMeshDimension()),sDim(getSpaceDimension()); - if((mDim==3 && sDim==3) || (mDim==2 && sDim==3) || (mDim==1 && sDim==1) || ( mDim==1 && sDim==3)) // Compute refined boundary box for quadratic elements only in 2D. - return getBoundingBoxForBBTreeFast(); - if((mDim==2 && sDim==2) || (mDim==1 && sDim==2)) - { - bool presenceOfQuadratic(false); - for(std::set::const_iterator it=_types.begin();it!=_types.end();it++) - { - const INTERP_KERNEL::CellModel& cm(INTERP_KERNEL::CellModel::GetCellModel(*it)); - if(cm.isQuadratic()) - presenceOfQuadratic=true; - } - if(!presenceOfQuadratic) - return getBoundingBoxForBBTreeFast(); - if(mDim==2 && sDim==2) - return getBoundingBoxForBBTree2DQuadratic(arcDetEps); - else - return getBoundingBoxForBBTree1DQuadratic(arcDetEps); - } - throw INTERP_KERNEL::Exception("MEDCouplingUMesh::getBoundingBoxForBBTree : Managed dimensions are (mDim=1,sDim=1), (mDim=1,sDim=2), (mDim=1,sDim=3), (mDim=2,sDim=2), (mDim=2,sDim=3) and (mDim=3,sDim=3) !"); -} - -/*! - * This method aggregate the bbox of each cell only considering the nodes constituting each cell and put it into bbox parameter. - * So meshes having quadratic cells the computed bounding boxes can be invalid ! - * - * \return DataArrayDouble * - newly created object (to be managed by the caller) \a this number of cells tuples and 2*spacedim components. - * - * \throw If \a this is not fully set (coordinates and connectivity). - * \throw If a cell in \a this has no valid nodeId. - */ -DataArrayDouble *MEDCouplingUMesh::getBoundingBoxForBBTreeFast() const -{ - checkFullyDefined(); - int spaceDim(getSpaceDimension()),nbOfCells(getNumberOfCells()),nbOfNodes(getNumberOfNodes()); - MEDCouplingAutoRefCountObjectPtr ret(DataArrayDouble::New()); ret->alloc(nbOfCells,2*spaceDim); - double *bbox(ret->getPointer()); - for(int i=0;i::max(); - bbox[2*i+1]=-std::numeric_limits::max(); - } - const double *coordsPtr(_coords->getConstPointer()); - const int *conn(_nodal_connec->getConstPointer()),*connI(_nodal_connec_index->getConstPointer()); - for(int i=0;i=0 && nodeId ret(DataArrayDouble::New()); ret->alloc(nbOfCells,2*spaceDim); - double *bbox(ret->getPointer()); - const double *coords(_coords->getConstPointer()); - const int *conn(_nodal_connec->getConstPointer()),*connI(_nodal_connec_index->getConstPointer()); - for(int i=0;i nodes(sz); - INTERP_KERNEL::QuadraticPolygon *pol(0); - for(int j=0;jfillBounds(b); delete pol; - bbox[0]=b.getXMin(); bbox[1]=b.getXMax(); bbox[2]=b.getYMin(); bbox[3]=b.getYMax(); - } - return ret.retn(); -} - -/*! - * This method aggregates the bbox of each 1D cell in \a this considering the whole shape. This method is particularly - * useful for 2D meshes having quadratic cells - * because for this type of cells getBoundingBoxForBBTreeFast method may return invalid bounding boxes (since it just considers - * the two extremities of the arc of circle). - * - * \param [in] arcDetEps - a parameter specifying in case of 2D quadratic polygon cell the detection limit between linear and arc circle. (By default 1e-12) - * \return DataArrayDouble * - newly created object (to be managed by the caller) \a this number of cells tuples and 2*spacedim components. - * \throw If \a this is not fully defined. - * \throw If \a this is not a mesh with meshDimension equal to 1. - * \throw If \a this is not a mesh with spaceDimension equal to 2. - * \sa MEDCouplingUMesh::getBoundingBoxForBBTree2DQuadratic - */ -DataArrayDouble *MEDCouplingUMesh::getBoundingBoxForBBTree1DQuadratic(double arcDetEps) const -{ - checkFullyDefined(); - int spaceDim(getSpaceDimension()),mDim(getMeshDimension()),nbOfCells(getNumberOfCells()); - if(spaceDim!=2 || mDim!=1) - throw INTERP_KERNEL::Exception("MEDCouplingUMesh::getBoundingBoxForBBTree1DQuadratic : This method should be applied on mesh with mesh dimension equal to 1 and space dimension also equal to 2!"); - MEDCouplingAutoRefCountObjectPtr ret(DataArrayDouble::New()); ret->alloc(nbOfCells,2*spaceDim); - double *bbox(ret->getPointer()); - const double *coords(_coords->getConstPointer()); - const int *conn(_nodal_connec->getConstPointer()),*connI(_nodal_connec_index->getConstPointer()); - for(int i=0;i nodes(sz); - INTERP_KERNEL::Edge *edge(0); - for(int j=0;jgetBounds()); - bbox[0]=b.getXMin(); bbox[1]=b.getXMax(); bbox[2]=b.getYMin(); bbox[3]=b.getYMax(); edge->decrRef(); - } - return ret.retn(); -} - -/// @cond INTERNAL - -namespace ParaMEDMEMImpl -{ - class ConnReader - { - public: - ConnReader(const int *c, int val):_conn(c),_val(val) { } - bool operator() (const int& pos) { return _conn[pos]!=_val; } - private: - const int *_conn; - int _val; - }; - - class ConnReader2 - { - public: - ConnReader2(const int *c, int val):_conn(c),_val(val) { } - bool operator() (const int& pos) { return _conn[pos]==_val; } - private: - const int *_conn; - int _val; - }; -} - -/// @endcond - -/*! - * This method expects that \a this is sorted by types. If not an exception will be thrown. - * This method returns in the same format as code (see MEDCouplingUMesh::checkTypeConsistencyAndContig or MEDCouplingUMesh::splitProfilePerType) how - * \a this is composed in cell types. - * The returned array is of size 3*n where n is the number of different types present in \a this. - * For every k in [0,n] ret[3*k+2]==-1 because it has no sense here. - * This parameter is kept only for compatibility with other methode listed above. - */ -std::vector MEDCouplingUMesh::getDistributionOfTypes() const -{ - checkConnectivityFullyDefined(); - const int *conn=_nodal_connec->getConstPointer(); - const int *connI=_nodal_connec_index->getConstPointer(); - const int *work=connI; - int nbOfCells=getNumberOfCells(); - std::size_t n=getAllGeoTypes().size(); - std::vector ret(3*n,-1); //ret[3*k+2]==-1 because it has no sense here - std::set types; - for(std::size_t i=0;work!=connI+nbOfCells;i++) - { - INTERP_KERNEL::NormalizedCellType typ=(INTERP_KERNEL::NormalizedCellType)conn[*work]; - if(types.find(typ)!=types.end()) - { - std::ostringstream oss; oss << "MEDCouplingUMesh::getDistributionOfTypes : Type " << INTERP_KERNEL::CellModel::GetCellModel(typ).getRepr(); - oss << " is not contiguous !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - types.insert(typ); - ret[3*i]=typ; - const int *work2=std::find_if(work+1,connI+nbOfCells,ParaMEDMEMImpl::ConnReader(conn,typ)); - ret[3*i+1]=(int)std::distance(work,work2); - work=work2; - } - return ret; -} - -/*! - * This method is used to check that this has contiguous cell type in same order than described in \a code. - * only for types cell, type node is not managed. - * Format of \a code is the following. \a code should be of size 3*n and non empty. If not an exception is thrown. - * foreach k in [0,n) on 3*k pos represent the geometric type and 3*k+1 number of elements of type 3*k. - * 3*k+2 refers if different from -1 the pos in 'idsPerType' to get the corresponding array. - * If 2 or more same geometric type is in \a code and exception is thrown too. - * - * This method firstly checks - * If it exists k so that 3*k geometric type is not in geometric types of this an exception will be thrown. - * If it exists k so that 3*k geometric type exists but the number of consecutive cell types does not match, - * an exception is thrown too. - * - * If all geometric types in \a code are exactly those in \a this null pointer is returned. - * If it exists a geometric type in \a this \b not in \a code \b no exception is thrown - * and a DataArrayInt instance is returned that the user has the responsability to deallocate. - */ -DataArrayInt *MEDCouplingUMesh::checkTypeConsistencyAndContig(const std::vector& code, const std::vector& idsPerType) const -{ - if(code.empty()) - throw INTERP_KERNEL::Exception("MEDCouplingUMesh::checkTypeConsistencyAndContig : code is empty, should not !"); - std::size_t sz=code.size(); - std::size_t n=sz/3; - if(sz%3!=0) - throw INTERP_KERNEL::Exception("MEDCouplingUMesh::checkTypeConsistencyAndContig : code size is NOT %3 !"); - std::vector types; - int nb=0; - bool isNoPflUsed=true; - for(std::size_t i=0;i ret=DataArrayInt::New(); - ret->alloc(nb,1); - int *retPtr=ret->getPointer(); - const int *connI=_nodal_connec_index->getConstPointer(); - const int *conn=_nodal_connec->getConstPointer(); - int nbOfCells=getNumberOfCells(); - const int *i=connI; - int kk=0; - for(std::vector::const_iterator it=types.begin();it!=types.end();it++,kk++) - { - i=std::find_if(i,connI+nbOfCells,ParaMEDMEMImpl::ConnReader2(conn,(int)(*it))); - int offset=(int)std::distance(connI,i); - const int *j=std::find_if(i+1,connI+nbOfCells,ParaMEDMEMImpl::ConnReader(conn,(int)(*it))); - int nbOfCellsOfCurType=(int)std::distance(i,j); - if(code[3*kk+2]==-1) - for(int k=0;k=0 && idInIdsPerType<(int)idsPerType.size()) - { - const DataArrayInt *zePfl=idsPerType[idInIdsPerType]; - if(zePfl) - { - zePfl->checkAllocated(); - if(zePfl->getNumberOfComponents()==1) - { - for(const int *k=zePfl->begin();k!=zePfl->end();k++,retPtr++) - { - if(*k>=0 && *k& code, std::vector& idsInPflPerType, std::vector& idsPerType) const -{ - if(!profile) - throw INTERP_KERNEL::Exception("MEDCouplingUMesh::splitProfilePerType : input profile is NULL !"); - if(profile->getNumberOfComponents()!=1) - throw INTERP_KERNEL::Exception("MEDCouplingUMesh::splitProfilePerType : input profile should have exactly one component !"); - checkConnectivityFullyDefined(); - const int *conn=_nodal_connec->getConstPointer(); - const int *connI=_nodal_connec_index->getConstPointer(); - int nbOfCells=getNumberOfCells(); - std::vector types; - std::vector typeRangeVals(1); - for(const int *i=connI;i!=connI+nbOfCells;) - { - INTERP_KERNEL::NormalizedCellType curType=(INTERP_KERNEL::NormalizedCellType)conn[*i]; - if(std::find(types.begin(),types.end(),curType)!=types.end()) - { - throw INTERP_KERNEL::Exception("MEDCouplingUMesh::splitProfilePerType : current mesh is not sorted by type !"); - } - types.push_back(curType); - i=std::find_if(i+1,connI+nbOfCells,ParaMEDMEMImpl::ConnReader(conn,(int)curType)); - typeRangeVals.push_back((int)std::distance(connI,i)); - } - // - DataArrayInt *castArr=0,*rankInsideCast=0,*castsPresent=0; - profile->splitByValueRange(&typeRangeVals[0],&typeRangeVals[0]+typeRangeVals.size(),castArr,rankInsideCast,castsPresent); - MEDCouplingAutoRefCountObjectPtr tmp0=castArr; - MEDCouplingAutoRefCountObjectPtr tmp1=rankInsideCast; - MEDCouplingAutoRefCountObjectPtr tmp2=castsPresent; - // - int nbOfCastsFinal=castsPresent->getNumberOfTuples(); - code.resize(3*nbOfCastsFinal); - std::vector< MEDCouplingAutoRefCountObjectPtr > idsInPflPerType2; - std::vector< MEDCouplingAutoRefCountObjectPtr > idsPerType2; - for(int i=0;igetIJ(i,0); - MEDCouplingAutoRefCountObjectPtr tmp3=castArr->getIdsEqual(castId); - idsInPflPerType2.push_back(tmp3); - code[3*i]=(int)types[castId]; - code[3*i+1]=tmp3->getNumberOfTuples(); - MEDCouplingAutoRefCountObjectPtr tmp4=rankInsideCast->selectByTupleId(tmp3->getConstPointer(),tmp3->getConstPointer()+tmp3->getNumberOfTuples()); - if(tmp4->getNumberOfTuples()!=typeRangeVals[castId+1]-typeRangeVals[castId] || !tmp4->isIdentity()) - { - tmp4->copyStringInfoFrom(*profile); - idsPerType2.push_back(tmp4); - code[3*i+2]=(int)idsPerType2.size()-1; - } - else - { - code[3*i+2]=-1; - } - } - std::size_t sz2=idsInPflPerType2.size(); - idsInPflPerType.resize(sz2); - for(std::size_t i=0;iincrRef(); - idsInPflPerType[i]=locDa; - } - std::size_t sz=idsPerType2.size(); - idsPerType.resize(sz); - for(std::size_t i=0;iincrRef(); - idsPerType[i]=locDa; - } -} - -/*! - * This method is here too emulate the MEDMEM behaviour on BDC (buildDescendingConnectivity). Hoping this method becomes deprecated very soon. - * This method make the assumption that \a this and 'nM1LevMesh' mesh lyies on same coords (same pointer) as MED and MEDMEM does. - * The following equality should be verified 'nM1LevMesh->getMeshDimension()==this->getMeshDimension()-1' - * This method returns 5+2 elements. 'desc', 'descIndx', 'revDesc', 'revDescIndx' and 'meshnM1' behaves exactly as ParaMEDMEM::MEDCouplingUMesh::buildDescendingConnectivity except the content as described after. The returned array specifies the n-1 mesh reordered by type as MEDMEM does. 'nM1LevMeshIds' contains the ids in returned 'meshnM1'. Finally 'meshnM1Old2New' contains numbering old2new that is to say the cell #k in coarse 'nM1LevMesh' will have the number ret[k] in returned mesh 'nM1LevMesh' MEDMEM reordered. - */ -MEDCouplingUMesh *MEDCouplingUMesh::emulateMEDMEMBDC(const MEDCouplingUMesh *nM1LevMesh, DataArrayInt *desc, DataArrayInt *descIndx, DataArrayInt *&revDesc, DataArrayInt *&revDescIndx, DataArrayInt *& nM1LevMeshIds, DataArrayInt *&meshnM1Old2New) const -{ - checkFullyDefined(); - nM1LevMesh->checkFullyDefined(); - if(getMeshDimension()-1!=nM1LevMesh->getMeshDimension()) - throw INTERP_KERNEL::Exception("MEDCouplingUMesh::emulateMEDMEMBDC : The mesh passed as first argument should have a meshDim equal to this->getMeshDimension()-1 !" ); - if(_coords!=nM1LevMesh->getCoords()) - throw INTERP_KERNEL::Exception("MEDCouplingUMesh::emulateMEDMEMBDC : 'this' and mesh in first argument should share the same coords : Use tryToShareSameCoords method !"); - MEDCouplingAutoRefCountObjectPtr tmp0=DataArrayInt::New(); - MEDCouplingAutoRefCountObjectPtr tmp1=DataArrayInt::New(); - MEDCouplingAutoRefCountObjectPtr ret1=buildDescendingConnectivity(desc,descIndx,tmp0,tmp1); - MEDCouplingAutoRefCountObjectPtr ret0=ret1->sortCellsInMEDFileFrmt(); - desc->transformWithIndArr(ret0->getConstPointer(),ret0->getConstPointer()+ret0->getNbOfElems()); - MEDCouplingAutoRefCountObjectPtr tmp=MEDCouplingUMesh::New(); - tmp->setConnectivity(tmp0,tmp1); - tmp->renumberCells(ret0->getConstPointer(),false); - revDesc=tmp->getNodalConnectivity(); - revDescIndx=tmp->getNodalConnectivityIndex(); - DataArrayInt *ret=0; - if(!ret1->areCellsIncludedIn(nM1LevMesh,2,ret)) - { - int tmp2; - ret->getMaxValue(tmp2); - ret->decrRef(); - std::ostringstream oss; oss << "MEDCouplingUMesh::emulateMEDMEMBDC : input N-1 mesh present a cell not in descending mesh ... Id of cell is " << tmp2 << " !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - nM1LevMeshIds=ret; - // - revDesc->incrRef(); - revDescIndx->incrRef(); - ret1->incrRef(); - ret0->incrRef(); - meshnM1Old2New=ret0; - return ret1; -} - -/*! - * Permutes the nodal connectivity arrays so that the cells are sorted by type, which is - * necessary for writing the mesh to MED file. Additionally returns a permutation array - * in "Old to New" mode. - * \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete - * this array using decrRef() as it is no more needed. - * \throw If the nodal connectivity of cells is not defined. - */ -DataArrayInt *MEDCouplingUMesh::sortCellsInMEDFileFrmt() -{ - checkConnectivityFullyDefined(); - MEDCouplingAutoRefCountObjectPtr ret=getRenumArrForMEDFileFrmt(); - renumberCells(ret->getConstPointer(),false); - return ret.retn(); -} - -/*! - * This methods checks that cells are sorted by their types. - * This method makes asumption (no check) that connectivity is correctly set before calling. - */ -bool MEDCouplingUMesh::checkConsecutiveCellTypes() const -{ - checkFullyDefined(); - const int *conn=_nodal_connec->getConstPointer(); - const int *connI=_nodal_connec_index->getConstPointer(); - int nbOfCells=getNumberOfCells(); - std::set types; - for(const int *i=connI;i!=connI+nbOfCells;) - { - INTERP_KERNEL::NormalizedCellType curType=(INTERP_KERNEL::NormalizedCellType)conn[*i]; - if(types.find(curType)!=types.end()) - return false; - types.insert(curType); - i=std::find_if(i+1,connI+nbOfCells,ParaMEDMEMImpl::ConnReader(conn,(int)curType)); - } - return true; -} - -/*! - * This method is a specialization of MEDCouplingUMesh::checkConsecutiveCellTypesAndOrder method that is called here. - * The geometric type order is specified by MED file. - * - * \sa MEDCouplingUMesh::checkConsecutiveCellTypesAndOrder - */ -bool MEDCouplingUMesh::checkConsecutiveCellTypesForMEDFileFrmt() const -{ - return checkConsecutiveCellTypesAndOrder(MEDMEM_ORDER,MEDMEM_ORDER+N_MEDMEM_ORDER); -} - -/*! - * This method performs the same job as checkConsecutiveCellTypes except that the order of types sequence is analyzed to check - * that the order is specified in array defined by [ \a orderBg , \a orderEnd ). - * If there is some geo types in \a this \b NOT in [ \a orderBg, \a orderEnd ) it is OK (return true) if contiguous. - * If there is some geo types in [ \a orderBg, \a orderEnd ) \b NOT in \a this it is OK too (return true) if contiguous. - */ -bool MEDCouplingUMesh::checkConsecutiveCellTypesAndOrder(const INTERP_KERNEL::NormalizedCellType *orderBg, const INTERP_KERNEL::NormalizedCellType *orderEnd) const -{ - checkFullyDefined(); - const int *conn=_nodal_connec->getConstPointer(); - const int *connI=_nodal_connec_index->getConstPointer(); - int nbOfCells=getNumberOfCells(); - if(nbOfCells==0) - return true; - int lastPos=-1; - std::set sg; - for(const int *i=connI;i!=connI+nbOfCells;) - { - INTERP_KERNEL::NormalizedCellType curType=(INTERP_KERNEL::NormalizedCellType)conn[*i]; - const INTERP_KERNEL::NormalizedCellType *isTypeExists=std::find(orderBg,orderEnd,curType); - if(isTypeExists!=orderEnd) - { - int pos=(int)std::distance(orderBg,isTypeExists); - if(pos<=lastPos) - return false; - lastPos=pos; - i=std::find_if(i+1,connI+nbOfCells,ParaMEDMEMImpl::ConnReader(conn,(int)curType)); - } - else - { - if(sg.find(curType)==sg.end()) - { - i=std::find_if(i+1,connI+nbOfCells,ParaMEDMEMImpl::ConnReader(conn,(int)curType)); - sg.insert(curType); - } - else - return false; - } - } - return true; -} - -/*! - * This method returns 2 newly allocated DataArrayInt instances. The first is an array of size 'this->getNumberOfCells()' with one component, - * that tells for each cell the pos of its type in the array on type given in input parameter. The 2nd output parameter is an array with the same - * number of tuples than input type array and with one component. This 2nd output array gives type by type the number of occurence of type in 'this'. - */ -DataArrayInt *MEDCouplingUMesh::getLevArrPerCellTypes(const INTERP_KERNEL::NormalizedCellType *orderBg, const INTERP_KERNEL::NormalizedCellType *orderEnd, DataArrayInt *&nbPerType) const -{ - checkConnectivityFullyDefined(); - int nbOfCells=getNumberOfCells(); - const int *conn=_nodal_connec->getConstPointer(); - const int *connI=_nodal_connec_index->getConstPointer(); - MEDCouplingAutoRefCountObjectPtr tmpa=DataArrayInt::New(); - MEDCouplingAutoRefCountObjectPtr tmpb=DataArrayInt::New(); - tmpa->alloc(nbOfCells,1); - tmpb->alloc((int)std::distance(orderBg,orderEnd),1); - tmpb->fillWithZero(); - int *tmp=tmpa->getPointer(); - int *tmp2=tmpb->getPointer(); - for(const int *i=connI;i!=connI+nbOfCells;i++) - { - const INTERP_KERNEL::NormalizedCellType *where=std::find(orderBg,orderEnd,(INTERP_KERNEL::NormalizedCellType)conn[*i]); - if(where!=orderEnd) - { - int pos=(int)std::distance(orderBg,where); - tmp2[pos]++; - tmp[std::distance(connI,i)]=pos; - } - else - { - const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel((INTERP_KERNEL::NormalizedCellType)conn[*i]); - std::ostringstream oss; oss << "MEDCouplingUMesh::getLevArrPerCellTypes : Cell #" << std::distance(connI,i); - oss << " has a type " << cm.getRepr() << " not in input array of type !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - } - nbPerType=tmpb.retn(); - return tmpa.retn(); -} - -/*! - * This method behaves exactly as MEDCouplingUMesh::getRenumArrForConsecutiveCellTypesSpec but the order is those defined in MED file spec. - * - * \return a new object containing the old to new correspondance. - * - * \sa MEDCouplingUMesh::getRenumArrForConsecutiveCellTypesSpec, MEDCouplingUMesh::sortCellsInMEDFileFrmt. - */ -DataArrayInt *MEDCouplingUMesh::getRenumArrForMEDFileFrmt() const -{ - return getRenumArrForConsecutiveCellTypesSpec(MEDMEM_ORDER,MEDMEM_ORDER+N_MEDMEM_ORDER); -} - -/*! - * This method is similar to method MEDCouplingUMesh::rearrange2ConsecutiveCellTypes except that the type order is specfied by [ \a orderBg , \a orderEnd ) (as MEDCouplingUMesh::checkConsecutiveCellTypesAndOrder method) and that this method is \b const and performs \b NO permutation in \a this. - * This method returns an array of size getNumberOfCells() that gives a renumber array old2New that can be used as input of MEDCouplingMesh::renumberCells. - * The mesh after this call to MEDCouplingMesh::renumberCells will pass the test of MEDCouplingUMesh::checkConsecutiveCellTypesAndOrder with the same inputs. - * The returned array minimizes the permutations that is to say the order of cells inside same geometric type remains the same. - */ -DataArrayInt *MEDCouplingUMesh::getRenumArrForConsecutiveCellTypesSpec(const INTERP_KERNEL::NormalizedCellType *orderBg, const INTERP_KERNEL::NormalizedCellType *orderEnd) const -{ - DataArrayInt *nbPerType=0; - MEDCouplingAutoRefCountObjectPtr tmpa=getLevArrPerCellTypes(orderBg,orderEnd,nbPerType); - nbPerType->decrRef(); - return tmpa->buildPermArrPerLevel(); -} - -/*! - * This method reorganize the cells of \a this so that the cells with same geometric types are put together. - * The number of cells remains unchanged after the call of this method. - * This method tries to minimizes the number of needed permutations. So, this method behaves not exactly as - * MEDCouplingUMesh::sortCellsInMEDFileFrmt. - * - * \return the array giving the correspondance old to new. - */ -DataArrayInt *MEDCouplingUMesh::rearrange2ConsecutiveCellTypes() -{ - checkFullyDefined(); - computeTypes(); - const int *conn=_nodal_connec->getConstPointer(); - const int *connI=_nodal_connec_index->getConstPointer(); - int nbOfCells=getNumberOfCells(); - std::vector types; - for(const int *i=connI;i!=connI+nbOfCells && (types.size()!=_types.size());) - if(std::find(types.begin(),types.end(),(INTERP_KERNEL::NormalizedCellType)conn[*i])==types.end()) - { - INTERP_KERNEL::NormalizedCellType curType=(INTERP_KERNEL::NormalizedCellType)conn[*i]; - types.push_back(curType); - for(i++;i!=connI+nbOfCells && (INTERP_KERNEL::NormalizedCellType)conn[*i]==curType;i++); - } - DataArrayInt *ret=DataArrayInt::New(); - ret->alloc(nbOfCells,1); - int *retPtr=ret->getPointer(); - std::fill(retPtr,retPtr+nbOfCells,-1); - int newCellId=0; - for(std::vector::const_iterator iter=types.begin();iter!=types.end();iter++) - { - for(const int *i=connI;i!=connI+nbOfCells;i++) - if((INTERP_KERNEL::NormalizedCellType)conn[*i]==(*iter)) - retPtr[std::distance(connI,i)]=newCellId++; - } - renumberCells(retPtr,false); - return ret; -} - -/*! - * This method splits \a this into as mush as untructured meshes that consecutive set of same type cells. - * So this method has typically a sense if MEDCouplingUMesh::checkConsecutiveCellTypes has a sense. - * This method makes asumption that connectivity is correctly set before calling. - */ -std::vector MEDCouplingUMesh::splitByType() const -{ - checkConnectivityFullyDefined(); - const int *conn=_nodal_connec->getConstPointer(); - const int *connI=_nodal_connec_index->getConstPointer(); - int nbOfCells=getNumberOfCells(); - std::vector ret; - for(const int *i=connI;i!=connI+nbOfCells;) - { - INTERP_KERNEL::NormalizedCellType curType=(INTERP_KERNEL::NormalizedCellType)conn[*i]; - int beginCellId=(int)std::distance(connI,i); - i=std::find_if(i+1,connI+nbOfCells,ParaMEDMEMImpl::ConnReader(conn,(int)curType)); - int endCellId=(int)std::distance(connI,i); - int sz=endCellId-beginCellId; - int *cells=new int[sz]; - for(int j=0;j ret=MEDCoupling1GTUMesh::New(getName(),typ); - ret->setCoords(getCoords()); - MEDCoupling1SGTUMesh *retC=dynamic_cast((MEDCoupling1GTUMesh*)ret); - if(retC) - { - MEDCouplingAutoRefCountObjectPtr c=convertNodalConnectivityToStaticGeoTypeMesh(); - retC->setNodalConnectivity(c); - } - else - { - MEDCoupling1DGTUMesh *retD=dynamic_cast((MEDCoupling1GTUMesh*)ret); - if(!retD) - throw INTERP_KERNEL::Exception("MEDCouplingUMesh::convertIntoSingleGeoTypeMesh : Internal error !"); - DataArrayInt *c=0,*ci=0; - convertNodalConnectivityToDynamicGeoTypeMesh(c,ci); - MEDCouplingAutoRefCountObjectPtr cs(c),cis(ci); - retD->setNodalConnectivity(cs,cis); - } - return ret.retn(); -} - -DataArrayInt *MEDCouplingUMesh::convertNodalConnectivityToStaticGeoTypeMesh() const -{ - checkConnectivityFullyDefined(); - if(_types.size()!=1) - throw INTERP_KERNEL::Exception("MEDCouplingUMesh::convertNodalConnectivityToStaticGeoTypeMesh : current mesh does not contain exactly one geometric type !"); - INTERP_KERNEL::NormalizedCellType typ=*_types.begin(); - const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(typ); - if(cm.isDynamic()) - { - std::ostringstream oss; oss << "MEDCouplingUMesh::convertNodalConnectivityToStaticGeoTypeMesh : this contains a single geo type (" << cm.getRepr() << ") but "; - oss << "this type is dynamic ! Only static geometric type is possible for that type ! call convertNodalConnectivityToDynamicGeoTypeMesh instead !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - int nbCells=getNumberOfCells(); - int typi=(int)typ; - int nbNodesPerCell=(int)cm.getNumberOfNodes(); - MEDCouplingAutoRefCountObjectPtr connOut=DataArrayInt::New(); connOut->alloc(nbCells*nbNodesPerCell,1); - int *outPtr=connOut->getPointer(); - const int *conn=_nodal_connec->begin(); - const int *connI=_nodal_connec_index->begin(); - nbNodesPerCell++; - for(int i=0;igetNumberOfTuples(); - if(lgth c(DataArrayInt::New()),ci(DataArrayInt::New()); - c->alloc(lgth-nbCells,1); ci->alloc(nbCells+1,1); - int *cp(c->getPointer()),*cip(ci->getPointer()); - const int *incp(_nodal_connec->begin()),*incip(_nodal_connec_index->begin()); - cip[0]=0; - for(int i=0;i=1) - { - if((strt>=0 && strt=0 && stop<=lgth)) - cp=std::copy(incp+strt,incp+stop,cp); - else - throw INTERP_KERNEL::Exception(msg0); - } - else - throw INTERP_KERNEL::Exception(msg0); - cip[1]=cip[0]+delta; - } - nodalConn=c.retn(); nodalConnIndex=ci.retn(); -} - -/*! - * This method takes in input a vector of MEDCouplingUMesh instances lying on the same coordinates with same mesh dimensions. - * Each mesh in \b ms must be sorted by type with the same order (typically using MEDCouplingUMesh::sortCellsInMEDFileFrmt). - * This method is particulary useful for MED file interaction. It allows to aggregate several meshes and keeping the type sorting - * and the track of the permutation by chunk of same geotype cells to retrieve it. The traditional formats old2new and new2old - * are not used here to avoid the build of big permutation array. - * - * \param [in] ms meshes with same mesh dimension lying on the same coords and sorted by type following de the same geometric type order than - * those specified in MEDCouplingUMesh::sortCellsInMEDFileFrmt method. - * \param [out] szOfCellGrpOfSameType is a newly allocated DataArrayInt instance whose number of tuples is equal to the number of chunks of same geotype - * in all meshes in \b ms. The accumulation of all values of this array is equal to the number of cells of returned mesh. - * \param [out] idInMsOfCellGrpOfSameType is a newly allocated DataArrayInt instance having the same size than \b szOfCellGrpOfSameType. This - * output array gives for each chunck of same type the corresponding mesh id in \b ms. - * \return A newly allocated unstructured mesh that is the result of the aggregation on same coords of all meshes in \b ms. This returned mesh - * is sorted by type following the geo cell types order of MEDCouplingUMesh::sortCellsInMEDFileFrmt method. - */ -MEDCouplingUMesh *MEDCouplingUMesh::AggregateSortedByTypeMeshesOnSameCoords(const std::vector& ms, - DataArrayInt *&szOfCellGrpOfSameType, - DataArrayInt *&idInMsOfCellGrpOfSameType) -{ - std::vector ms2; - for(std::vector::const_iterator it=ms.begin();it!=ms.end();it++) - if(*it) - { - (*it)->checkConnectivityFullyDefined(); - ms2.push_back(*it); - } - if(ms2.empty()) - throw INTERP_KERNEL::Exception("MEDCouplingUMesh::AggregateSortedByTypeMeshesOnSameCoords : input vector is empty !"); - const DataArrayDouble *refCoo=ms2[0]->getCoords(); - int meshDim=ms2[0]->getMeshDimension(); - std::vector m1ssm; - std::vector< MEDCouplingAutoRefCountObjectPtr > m1ssmAuto; - // - std::vector m1ssmSingle; - std::vector< MEDCouplingAutoRefCountObjectPtr > m1ssmSingleAuto; - int fake=0,rk=0; - MEDCouplingAutoRefCountObjectPtr ret1(DataArrayInt::New()),ret2(DataArrayInt::New()); - ret1->alloc(0,1); ret2->alloc(0,1); - for(std::vector::const_iterator it=ms2.begin();it!=ms2.end();it++,rk++) - { - if(meshDim!=(*it)->getMeshDimension()) - throw INTERP_KERNEL::Exception("MEDCouplingUMesh::AggregateSortedByTypeMeshesOnSameCoords : meshdims mismatch !"); - if(refCoo!=(*it)->getCoords()) - throw INTERP_KERNEL::Exception("MEDCouplingUMesh::AggregateSortedByTypeMeshesOnSameCoords : meshes are not shared by a single coordinates coords !"); - std::vector sp=(*it)->splitByType(); - std::copy(sp.begin(),sp.end(),std::back_insert_iterator< std::vector >(m1ssm)); - std::copy(sp.begin(),sp.end(),std::back_insert_iterator< std::vector > >(m1ssmAuto)); - for(std::vector::const_iterator it2=sp.begin();it2!=sp.end();it2++) - { - MEDCouplingUMesh *singleCell=static_cast((*it2)->buildPartOfMySelf(&fake,&fake+1,true)); - m1ssmSingleAuto.push_back(singleCell); - m1ssmSingle.push_back(singleCell); - ret1->pushBackSilent((*it2)->getNumberOfCells()); ret2->pushBackSilent(rk); - } - } - MEDCouplingAutoRefCountObjectPtr m1ssmSingle2=MEDCouplingUMesh::MergeUMeshesOnSameCoords(m1ssmSingle); - MEDCouplingAutoRefCountObjectPtr renum=m1ssmSingle2->sortCellsInMEDFileFrmt(); - std::vector m1ssmfinal(m1ssm.size()); - for(std::size_t i=0;igetIJ(i,0)]=m1ssm[i]; - MEDCouplingAutoRefCountObjectPtr ret0=MEDCouplingUMesh::MergeUMeshesOnSameCoords(m1ssmfinal); - szOfCellGrpOfSameType=ret1->renumber(renum->getConstPointer()); - idInMsOfCellGrpOfSameType=ret2->renumber(renum->getConstPointer()); - return ret0.retn(); -} - -/*! - * This method returns a newly created DataArrayInt instance. - * This method retrieves cell ids in [ \a begin, \a end ) that have the type \a type. - */ -DataArrayInt *MEDCouplingUMesh::keepCellIdsByType(INTERP_KERNEL::NormalizedCellType type, const int *begin, const int *end) const -{ - checkFullyDefined(); - const int *conn=_nodal_connec->getConstPointer(); - const int *connIndex=_nodal_connec_index->getConstPointer(); - MEDCouplingAutoRefCountObjectPtr ret(DataArrayInt::New()); ret->alloc(0,1); - for(const int *w=begin;w!=end;w++) - if((INTERP_KERNEL::NormalizedCellType)conn[connIndex[*w]]==type) - ret->pushBackSilent(*w); - return ret.retn(); -} - -/*! - * This method makes the assumption that da->getNumberOfTuples()getNumberOfCells(). This method makes the assumption that ids contained in 'da' - * are in [0:getNumberOfCells()) - */ -DataArrayInt *MEDCouplingUMesh::convertCellArrayPerGeoType(const DataArrayInt *da) const -{ - checkFullyDefined(); - const int *conn=_nodal_connec->getConstPointer(); - const int *connI=_nodal_connec_index->getConstPointer(); - int nbOfCells=getNumberOfCells(); - std::set types(getAllGeoTypes()); - int *tmp=new int[nbOfCells]; - for(std::set::const_iterator iter=types.begin();iter!=types.end();iter++) - { - int j=0; - for(const int *i=connI;i!=connI+nbOfCells;i++) - if((INTERP_KERNEL::NormalizedCellType)conn[*i]==(*iter)) - tmp[std::distance(connI,i)]=j++; - } - DataArrayInt *ret=DataArrayInt::New(); - ret->alloc(da->getNumberOfTuples(),da->getNumberOfComponents()); - ret->copyStringInfoFrom(*da); - int *retPtr=ret->getPointer(); - const int *daPtr=da->getConstPointer(); - int nbOfElems=da->getNbOfElems(); - for(int k=0;k code=getDistributionOfTypes(); - std::size_t nOfTypesInThis=code.size()/3; - int sz=0,szOfType=0; - for(std::size_t i=0;i=szOfType) - { - std::ostringstream oss; oss << "MEDCouplingUMesh::keepSpecifiedCells : Request on type " << type << " at place #" << std::distance(idsPerGeoTypeBg,work) << " value " << *work; - oss << ". It should be in [0," << szOfType << ") !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - MEDCouplingAutoRefCountObjectPtr idsTokeep=DataArrayInt::New(); idsTokeep->alloc(sz+(int)std::distance(idsPerGeoTypeBg,idsPerGeoTypeEnd),1); - int *idsPtr=idsTokeep->getPointer(); - int offset=0; - for(std::size_t i=0;i(),offset)); - offset+=code[3*i+1]; - } - MEDCouplingAutoRefCountObjectPtr ret=static_cast(buildPartOfMySelf(idsTokeep->begin(),idsTokeep->end(),true)); - ret->copyTinyInfoFrom(this); - return ret.retn(); -} - -/*! - * This method returns a vector of size 'this->getNumberOfCells()'. - * This method retrieves for each cell in \a this if it is linear (false) or quadratic(true). - */ -std::vector MEDCouplingUMesh::getQuadraticStatus() const -{ - int ncell=getNumberOfCells(); - std::vector ret(ncell); - const int *cI=getNodalConnectivityIndex()->getConstPointer(); - const int *c=getNodalConnectivity()->getConstPointer(); - for(int i=0;igetType()!=UNSTRUCTURED) - throw INTERP_KERNEL::Exception("Merge of umesh only available with umesh each other !"); - const MEDCouplingUMesh *otherC=static_cast(other); - return MergeUMeshes(this,otherC); -} - -/*! - * Returns a new DataArrayDouble holding barycenters of all cells. The barycenter is - * computed by averaging coordinates of cell nodes, so this method is not a right - * choice for degnerated meshes (not well oriented, cells with measure close to zero). - * \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. - * \throw If the coordinates array is not set. - * \throw If the nodal connectivity of cells is not defined. - * \sa MEDCouplingUMesh::computeIsoBarycenterOfNodesPerCell - */ -DataArrayDouble *MEDCouplingUMesh::getBarycenterAndOwner() const -{ - MEDCouplingAutoRefCountObjectPtr ret=DataArrayDouble::New(); - int spaceDim=getSpaceDimension(); - int nbOfCells=getNumberOfCells(); - ret->alloc(nbOfCells,spaceDim); - ret->copyStringInfoFrom(*getCoords()); - double *ptToFill=ret->getPointer(); - const int *nodal=_nodal_connec->getConstPointer(); - const int *nodalI=_nodal_connec_index->getConstPointer(); - const double *coor=_coords->getConstPointer(); - for(int i=0;i(type,nodal+nodalI[i]+1,nodalI[i+1]-nodalI[i]-1,coor,spaceDim,ptToFill); - ptToFill+=spaceDim; - } - return ret.retn(); -} - -/*! - * This method computes for each cell in \a this, the location of the iso barycenter of nodes constituting - * the cell. Contrary to badly named MEDCouplingUMesh::getBarycenterAndOwner method that returns the center of inertia of the - * - * \return a newly allocated DataArrayDouble instance that the caller has to deal with. The returned - * DataArrayDouble instance will have \c this->getNumberOfCells() tuples and \c this->getSpaceDimension() components. - * - * \sa MEDCouplingUMesh::getBarycenterAndOwner - * \throw If \a this is not fully defined (coordinates and connectivity) - * \throw If there is presence in nodal connectivity in \a this of node ids not in [0, \c this->getNumberOfNodes() ) - */ -DataArrayDouble *MEDCouplingUMesh::computeIsoBarycenterOfNodesPerCell() const -{ - checkFullyDefined(); - MEDCouplingAutoRefCountObjectPtr ret=DataArrayDouble::New(); - int spaceDim=getSpaceDimension(); - int nbOfCells=getNumberOfCells(); - int nbOfNodes=getNumberOfNodes(); - ret->alloc(nbOfCells,spaceDim); - double *ptToFill=ret->getPointer(); - const int *nodal=_nodal_connec->getConstPointer(); - const int *nodalI=_nodal_connec_index->getConstPointer(); - const double *coor=_coords->getConstPointer(); - for(int i=0;i=0 && *conn()); - else - { - std::ostringstream oss; oss << "MEDCouplingUMesh::computeIsoBarycenterOfNodesPerCell : on cell #" << i << " presence of nodeId #" << *conn << " should be in [0," << nbOfNodes << ") !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - } - int nbOfNodesInCell=nodalI[i+1]-nodalI[i]-1; - if(nbOfNodesInCell>0) - std::transform(ptToFill,ptToFill+spaceDim,ptToFill,std::bind2nd(std::multiplies(),1./(double)nbOfNodesInCell)); - else - { - std::ostringstream oss; oss << "MEDCouplingUMesh::computeIsoBarycenterOfNodesPerCell : on cell #" << i << " presence of cell with no nodes !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - } - else - { - std::set s(nodal+nodalI[i]+1,nodal+nodalI[i+1]); - s.erase(-1); - for(std::set::const_iterator it=s.begin();it!=s.end();it++) - { - if(*it>=0 && *it()); - else - { - std::ostringstream oss; oss << "MEDCouplingUMesh::computeIsoBarycenterOfNodesPerCell : on cell polyhedron cell #" << i << " presence of nodeId #" << *it << " should be in [0," << nbOfNodes << ") !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - } - if(!s.empty()) - std::transform(ptToFill,ptToFill+spaceDim,ptToFill,std::bind2nd(std::multiplies(),1./(double)s.size())); - else - { - std::ostringstream oss; oss << "MEDCouplingUMesh::computeIsoBarycenterOfNodesPerCell : on polyhedron cell #" << i << " there are no nodes !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - } - } - return ret.retn(); -} - -/*! - * Returns a new DataArrayDouble holding barycenters of specified cells. The - * barycenter is computed by averaging coordinates of cell nodes. The cells to treat - * are specified via an array of cell ids. - * \warning Validity of the specified cell ids is not checked! - * Valid range is [ 0, \a this->getNumberOfCells() ). - * \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. - * \return DataArrayDouble * - a new instance of DataArrayDouble, of size ( \a - * end - \a begin ) tuples per \a this->getSpaceDimension() components. The - * caller is to delete this array using decrRef() as it is no more needed. - * \throw If the coordinates array is not set. - * \throw If the nodal connectivity of cells is not defined. - * - * \if ENABLE_EXAMPLES - * \ref cpp_mcumesh_getPartBarycenterAndOwner "Here is a C++ example".
- * \ref py_mcumesh_getPartBarycenterAndOwner "Here is a Python example". - * \endif - */ -DataArrayDouble *MEDCouplingUMesh::getPartBarycenterAndOwner(const int *begin, const int *end) const -{ - DataArrayDouble *ret=DataArrayDouble::New(); - int spaceDim=getSpaceDimension(); - int nbOfTuple=(int)std::distance(begin,end); - ret->alloc(nbOfTuple,spaceDim); - double *ptToFill=ret->getPointer(); - double *tmp=new double[spaceDim]; - const int *nodal=_nodal_connec->getConstPointer(); - const int *nodalI=_nodal_connec_index->getConstPointer(); - const double *coor=_coords->getConstPointer(); - for(const int *w=begin;w!=end;w++) - { - INTERP_KERNEL::NormalizedCellType type=(INTERP_KERNEL::NormalizedCellType)nodal[nodalI[*w]]; - INTERP_KERNEL::computeBarycenter2(type,nodal+nodalI[*w]+1,nodalI[*w+1]-nodalI[*w]-1,coor,spaceDim,ptToFill); - ptToFill+=spaceDim; - } - delete [] tmp; - return ret; -} - -/*! - * Returns a DataArrayDouble instance giving for each cell in \a this the equation of plane given by "a*X+b*Y+c*Z+d=0". - * So the returned instance will have 4 components and \c this->getNumberOfCells() tuples. - * So this method expects that \a this has a spaceDimension equal to 3 and meshDimension equal to 2. - * The computation of the plane equation is done using each time the 3 first nodes of 2D cells. - * This method is useful to detect 2D cells in 3D space that are not coplanar. - * - * \return DataArrayDouble * - a new instance of DataArrayDouble having 4 components and a number of tuples equal to number of cells in \a this. - * \throw If spaceDim!=3 or meshDim!=2. - * \throw If connectivity of \a this is invalid. - * \throw If connectivity of a cell in \a this points to an invalid node. - */ -DataArrayDouble *MEDCouplingUMesh::computePlaneEquationOf3DFaces() const -{ - MEDCouplingAutoRefCountObjectPtr ret(DataArrayDouble::New()); - int nbOfCells(getNumberOfCells()),nbOfNodes(getNumberOfNodes()); - if(getSpaceDimension()!=3 || getMeshDimension()!=2) - throw INTERP_KERNEL::Exception("MEDCouplingUMesh::computePlaneEquationOf3DFaces : This method must be applied on a mesh having meshDimension equal 2 and a spaceDimension equal to 3 !"); - ret->alloc(nbOfCells,4); - double *retPtr(ret->getPointer()); - const int *nodal(_nodal_connec->begin()),*nodalI(_nodal_connec_index->begin()); - const double *coor(_coords->begin()); - for(int i=0;i=3) - { - for(int j=0;j<3;j++) - { - int nodeId(nodal[nodalI[0]+1+j]); - if(nodeId>=0 && nodeIdcheckAllocated(); - MEDCouplingAutoRefCountObjectPtr ret=MEDCouplingUMesh::New(da->getName(),0); - ret->setCoords(da); - int nbOfTuples=da->getNumberOfTuples(); - MEDCouplingAutoRefCountObjectPtr c=DataArrayInt::New(); - MEDCouplingAutoRefCountObjectPtr cI=DataArrayInt::New(); - c->alloc(2*nbOfTuples,1); - cI->alloc(nbOfTuples+1,1); - int *cp=c->getPointer(); - int *cip=cI->getPointer(); - *cip++=0; - for(int i=0;isetConnectivity(c,cI,true); - return ret.retn(); -} -/*! - * Creates a new MEDCouplingUMesh by concatenating two given meshes of the same dimension. - * Cells and nodes of - * the first mesh precede cells and nodes of the second mesh within the result mesh. - * \param [in] mesh1 - the first mesh. - * \param [in] mesh2 - the second mesh. - * \return MEDCouplingUMesh * - 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 mesh1 == NULL or \a mesh2 == NULL. - * \throw If the coordinates array is not set in none of the meshes. - * \throw If \a mesh1->getMeshDimension() < 0 or \a mesh2->getMeshDimension() < 0. - * \throw If \a mesh1->getMeshDimension() != \a mesh2->getMeshDimension(). - */ -MEDCouplingUMesh *MEDCouplingUMesh::MergeUMeshes(const MEDCouplingUMesh *mesh1, const MEDCouplingUMesh *mesh2) -{ - std::vector tmp(2); - tmp[0]=const_cast(mesh1); tmp[1]=const_cast(mesh2); - return MergeUMeshes(tmp); -} - -/*! - * Creates a new MEDCouplingUMesh by concatenating all given meshes of the same dimension. - * Cells and nodes of - * the *i*-th mesh precede cells and nodes of the (*i*+1)-th mesh within the result mesh. - * \param [in] a - a vector of meshes (MEDCouplingUMesh) to concatenate. - * \return MEDCouplingUMesh * - 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 a.size() == 0. - * \throw If \a a[ *i* ] == NULL. - * \throw If the coordinates array is not set in none of the meshes. - * \throw If \a a[ *i* ]->getMeshDimension() < 0. - * \throw If the meshes in \a a are of different dimension (getMeshDimension()). - */ -MEDCouplingUMesh *MEDCouplingUMesh::MergeUMeshes(std::vector& a) -{ - std::size_t sz=a.size(); - if(sz==0) - return MergeUMeshesLL(a); - for(std::size_t ii=0;ii > bb(sz); - std::vector< const MEDCouplingUMesh * > aa(sz); - int spaceDim=-3; - for(std::size_t i=0;igetCoords(); - if(coo) - spaceDim=coo->getNumberOfComponents(); - } - if(spaceDim==-3) - throw INTERP_KERNEL::Exception("MEDCouplingUMesh::MergeUMeshes : no spaceDim specified ! unable to perform merge !"); - for(std::size_t i=0;ibuildSetInstanceFromThis(spaceDim); - aa[i]=bb[i]; - } - return MergeUMeshesLL(aa); -} - -/// @cond INTERNAL - -MEDCouplingUMesh *MEDCouplingUMesh::MergeUMeshesLL(std::vector& a) -{ - if(a.empty()) - throw INTERP_KERNEL::Exception("MEDCouplingUMesh::MergeUMeshes : input array must be NON EMPTY !"); - std::vector::const_iterator it=a.begin(); - int meshDim=(*it)->getMeshDimension(); - int nbOfCells=(*it)->getNumberOfCells(); - int meshLgth=(*it++)->getMeshLength(); - for(;it!=a.end();it++) - { - if(meshDim!=(*it)->getMeshDimension()) - throw INTERP_KERNEL::Exception("Mesh dimensions mismatches, MergeUMeshes impossible !"); - nbOfCells+=(*it)->getNumberOfCells(); - meshLgth+=(*it)->getMeshLength(); - } - std::vector aps(a.size()); - std::copy(a.begin(),a.end(),aps.begin()); - MEDCouplingAutoRefCountObjectPtr pts=MergeNodesArray(aps); - MEDCouplingAutoRefCountObjectPtr ret=MEDCouplingUMesh::New("merge",meshDim); - ret->setCoords(pts); - MEDCouplingAutoRefCountObjectPtr c=DataArrayInt::New(); - c->alloc(meshLgth,1); - int *cPtr=c->getPointer(); - MEDCouplingAutoRefCountObjectPtr cI=DataArrayInt::New(); - cI->alloc(nbOfCells+1,1); - int *cIPtr=cI->getPointer(); - *cIPtr++=0; - int offset=0; - int offset2=0; - for(it=a.begin();it!=a.end();it++) - { - int curNbOfCell=(*it)->getNumberOfCells(); - const int *curCI=(*it)->_nodal_connec_index->getConstPointer(); - const int *curC=(*it)->_nodal_connec->getConstPointer(); - cIPtr=std::transform(curCI+1,curCI+curNbOfCell+1,cIPtr,std::bind2nd(std::plus(),offset)); - for(int j=0;jgetNumberOfNodes(); - } - // - ret->setConnectivity(c,cI,true); - return ret.retn(); -} - -/// @endcond - -/*! - * Creates a new MEDCouplingUMesh by concatenating cells of two given meshes of same - * dimension and sharing the node coordinates array. - * All cells of the first mesh precede all cells of the second mesh - * within the result mesh. - * \param [in] mesh1 - the first mesh. - * \param [in] mesh2 - the second mesh. - * \return MEDCouplingUMesh * - 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 mesh1 == NULL or \a mesh2 == NULL. - * \throw If the meshes do not share the node coordinates array. - * \throw If \a mesh1->getMeshDimension() < 0 or \a mesh2->getMeshDimension() < 0. - * \throw If \a mesh1->getMeshDimension() != \a mesh2->getMeshDimension(). - */ -MEDCouplingUMesh *MEDCouplingUMesh::MergeUMeshesOnSameCoords(const MEDCouplingUMesh *mesh1, const MEDCouplingUMesh *mesh2) -{ - std::vector tmp(2); - tmp[0]=mesh1; tmp[1]=mesh2; - return MergeUMeshesOnSameCoords(tmp); -} - -/*! - * Creates a new MEDCouplingUMesh by concatenating cells of all given meshes of same - * dimension and sharing the node coordinates array. - * All cells of the *i*-th mesh precede all cells of the - * (*i*+1)-th mesh within the result mesh. - * \param [in] meshes - a vector of meshes (MEDCouplingUMesh) to concatenate. - * \return MEDCouplingUMesh * - 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 a.size() == 0. - * \throw If \a a[ *i* ] == NULL. - * \throw If the meshes do not share the node coordinates array. - * \throw If \a a[ *i* ]->getMeshDimension() < 0. - * \throw If the meshes in \a a are of different dimension (getMeshDimension()). - */ -MEDCouplingUMesh *MEDCouplingUMesh::MergeUMeshesOnSameCoords(const std::vector& meshes) -{ - if(meshes.empty()) - throw INTERP_KERNEL::Exception("meshes input parameter is expected to be non empty."); - for(std::size_t ii=0;iigetCoords(); - int meshDim=meshes.front()->getMeshDimension(); - std::vector::const_iterator iter=meshes.begin(); - int meshLgth=0; - int meshIndexLgth=0; - for(;iter!=meshes.end();iter++) - { - if(coords!=(*iter)->getCoords()) - throw INTERP_KERNEL::Exception("meshes does not share the same coords ! Try using tryToShareSameCoords method !"); - if(meshDim!=(*iter)->getMeshDimension()) - throw INTERP_KERNEL::Exception("Mesh dimensions mismatches, FuseUMeshesOnSameCoords impossible !"); - meshLgth+=(*iter)->getMeshLength(); - meshIndexLgth+=(*iter)->getNumberOfCells(); - } - MEDCouplingAutoRefCountObjectPtr nodal=DataArrayInt::New(); - nodal->alloc(meshLgth,1); - int *nodalPtr=nodal->getPointer(); - MEDCouplingAutoRefCountObjectPtr nodalIndex=DataArrayInt::New(); - nodalIndex->alloc(meshIndexLgth+1,1); - int *nodalIndexPtr=nodalIndex->getPointer(); - int offset=0; - for(iter=meshes.begin();iter!=meshes.end();iter++) - { - const int *nod=(*iter)->getNodalConnectivity()->getConstPointer(); - const int *index=(*iter)->getNodalConnectivityIndex()->getConstPointer(); - int nbOfCells=(*iter)->getNumberOfCells(); - int meshLgth2=(*iter)->getMeshLength(); - nodalPtr=std::copy(nod,nod+meshLgth2,nodalPtr); - if(iter!=meshes.begin()) - nodalIndexPtr=std::transform(index+1,index+nbOfCells+1,nodalIndexPtr,std::bind2nd(std::plus(),offset)); - else - nodalIndexPtr=std::copy(index,index+nbOfCells+1,nodalIndexPtr); - offset+=meshLgth2; - } - MEDCouplingUMesh *ret=MEDCouplingUMesh::New(); - ret->setName("merge"); - ret->setMeshDimension(meshDim); - ret->setConnectivity(nodal,nodalIndex,true); - ret->setCoords(coords); - return ret; -} - -/*! - * Creates a new MEDCouplingUMesh by concatenating cells of all given meshes of same - * dimension and sharing the node coordinates array. Cells of the *i*-th mesh precede - * cells of the (*i*+1)-th mesh within the result mesh. Duplicates of cells are - * removed from \a this mesh and arrays mapping between new and old cell ids in "Old to - * New" mode are returned for each input mesh. - * \param [in] meshes - a vector of meshes (MEDCouplingUMesh) to concatenate. - * \param [in] compType - specifies a cell comparison technique. For meaning of its - * valid values [0,1,2], see zipConnectivityTraducer(). - * \param [in,out] corr - an array of DataArrayInt, of the same size as \a - * meshes. The *i*-th array describes cell ids mapping for \a meshes[ *i* ] - * mesh. The caller is to delete each of the arrays using decrRef() as it is - * no more needed. - * \return MEDCouplingUMesh * - 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 meshes[ *i* ] == NULL. - * \throw If the meshes do not share the node coordinates array. - * \throw If \a meshes[ *i* ]->getMeshDimension() < 0. - * \throw If the \a meshes are of different dimension (getMeshDimension()). - * \throw If the nodal connectivity of cells of any of \a meshes is not defined. - * \throw If the nodal connectivity any of \a meshes includes an invalid id. - */ -MEDCouplingUMesh *MEDCouplingUMesh::FuseUMeshesOnSameCoords(const std::vector& meshes, int compType, std::vector& corr) -{ - //All checks are delegated to MergeUMeshesOnSameCoords - MEDCouplingAutoRefCountObjectPtr ret=MergeUMeshesOnSameCoords(meshes); - MEDCouplingAutoRefCountObjectPtr o2n=ret->zipConnectivityTraducer(compType); - corr.resize(meshes.size()); - std::size_t nbOfMeshes=meshes.size(); - int offset=0; - const int *o2nPtr=o2n->getConstPointer(); - for(std::size_t i=0;igetNumberOfCells(); - tmp->alloc(curNbOfCells,1); - std::copy(o2nPtr+offset,o2nPtr+offset+curNbOfCells,tmp->getPointer()); - offset+=curNbOfCells; - tmp->setName(meshes[i]->getName()); - corr[i]=tmp; - } - return ret.retn(); -} - -/*! - * Makes all given meshes share the nodal connectivity array. The common connectivity - * array is created by concatenating the connectivity arrays of all given meshes. All - * the given meshes must be of the same space dimension but dimension of cells **can - * differ**. This method is particulary useful in MEDLoader context to build a \ref - * ParaMEDMEM::MEDFileUMesh "MEDFileUMesh" instance that expects that underlying - * MEDCouplingUMesh'es of different dimension share the same nodal connectivity array. - * \param [in,out] meshes - a vector of meshes to update. - * \throw If any of \a meshes is NULL. - * \throw If the coordinates array is not set in any of \a meshes. - * \throw If the nodal connectivity of cells is not defined in any of \a meshes. - * \throw If \a meshes are of different space dimension. - */ -void MEDCouplingUMesh::PutUMeshesOnSameAggregatedCoords(const std::vector& meshes) -{ - std::size_t sz=meshes.size(); - if(sz==0 || sz==1) - return; - std::vector< const DataArrayDouble * > coords(meshes.size()); - std::vector< const DataArrayDouble * >::iterator it2=coords.begin(); - for(std::vector::const_iterator it=meshes.begin();it!=meshes.end();it++,it2++) - { - if((*it)) - { - (*it)->checkConnectivityFullyDefined(); - const DataArrayDouble *coo=(*it)->getCoords(); - if(coo) - *it2=coo; - else - { - std::ostringstream oss; oss << " MEDCouplingUMesh::PutUMeshesOnSameAggregatedCoords : Item #" << std::distance(meshes.begin(),it) << " inside the vector of length " << meshes.size(); - oss << " has no coordinate array defined !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - } - else - { - std::ostringstream oss; oss << " MEDCouplingUMesh::PutUMeshesOnSameAggregatedCoords : Item #" << std::distance(meshes.begin(),it) << " inside the vector of length " << meshes.size(); - oss << " is null !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - } - MEDCouplingAutoRefCountObjectPtr res=DataArrayDouble::Aggregate(coords); - std::vector::const_iterator it=meshes.begin(); - int offset=(*it)->getNumberOfNodes(); - (*it++)->setCoords(res); - for(;it!=meshes.end();it++) - { - int oldNumberOfNodes=(*it)->getNumberOfNodes(); - (*it)->setCoords(res); - (*it)->shiftNodeNumbersInConn(offset); - offset+=oldNumberOfNodes; - } -} - -/*! - * Merges nodes coincident with a given precision within all given meshes that share - * the nodal connectivity array. The given meshes **can be of different** mesh - * dimension. This method is particulary useful in MEDLoader context to build a \ref - * ParaMEDMEM::MEDFileUMesh "MEDFileUMesh" instance that expects that underlying - * MEDCouplingUMesh'es of different dimension share the same nodal connectivity array. - * \param [in,out] meshes - a vector of meshes to update. - * \param [in] eps - the precision used to detect coincident nodes (infinite norm). - * \throw If any of \a meshes is NULL. - * \throw If the \a meshes do not share the same node coordinates array. - * \throw If the nodal connectivity of cells is not defined in any of \a meshes. - */ -void MEDCouplingUMesh::MergeNodesOnUMeshesSharingSameCoords(const std::vector& meshes, double eps) -{ - if(meshes.empty()) - return ; - std::set s; - for(std::vector::const_iterator it=meshes.begin();it!=meshes.end();it++) - { - if(*it) - s.insert((*it)->getCoords()); - else - { - std::ostringstream oss; oss << "MEDCouplingUMesh::MergeNodesOnUMeshesSharingSameCoords : In input vector of unstructured meshes of size " << meshes.size() << " the element #" << std::distance(meshes.begin(),it) << " is null !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - } - if(s.size()!=1) - { - std::ostringstream oss; oss << "MEDCouplingUMesh::MergeNodesOnUMeshesSharingSameCoords : In input vector of unstructured meshes of size " << meshes.size() << ", it appears that they do not share the same instance of DataArrayDouble for coordiantes ! tryToShareSameCoordsPermute method can help to reach that !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - const DataArrayDouble *coo=*(s.begin()); - if(!coo) - return; - // - DataArrayInt *comm,*commI; - coo->findCommonTuples(eps,-1,comm,commI); - MEDCouplingAutoRefCountObjectPtr tmp1(comm),tmp2(commI); - int oldNbOfNodes=coo->getNumberOfTuples(); - int newNbOfNodes; - MEDCouplingAutoRefCountObjectPtr o2n=DataArrayInt::BuildOld2NewArrayFromSurjectiveFormat2(oldNbOfNodes,comm->begin(),commI->begin(),commI->end(),newNbOfNodes); - if(oldNbOfNodes==newNbOfNodes) - return ; - MEDCouplingAutoRefCountObjectPtr newCoords=coo->renumberAndReduce(o2n->getConstPointer(),newNbOfNodes); - for(std::vector::const_iterator it=meshes.begin();it!=meshes.end();it++) - { - (*it)->renumberNodesInConn(o2n->getConstPointer()); - (*it)->setCoords(newCoords); - } -} - -/*! - * This method takes in input a cell defined by its MEDcouplingUMesh connectivity [ \a connBg , \a connEnd ) and returns its extruded cell by inserting the result at the end of ret. - * \param nbOfNodesPerLev in parameter that specifies the number of nodes of one slice of global dataset - * \param isQuad specifies the policy of connectivity. - * @ret in/out parameter in which the result will be append - */ -void MEDCouplingUMesh::AppendExtrudedCell(const int *connBg, const int *connEnd, int nbOfNodesPerLev, bool isQuad, std::vector& ret) -{ - INTERP_KERNEL::NormalizedCellType flatType=(INTERP_KERNEL::NormalizedCellType)connBg[0]; - const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(flatType); - ret.push_back(cm.getExtrudedType()); - int deltaz=isQuad?2*nbOfNodesPerLev:nbOfNodesPerLev; - switch(flatType) - { - case INTERP_KERNEL::NORM_POINT1: - { - ret.push_back(connBg[1]); - ret.push_back(connBg[1]+nbOfNodesPerLev); - break; - } - case INTERP_KERNEL::NORM_SEG2: - { - int conn[4]={connBg[1],connBg[2],connBg[2]+deltaz,connBg[1]+deltaz}; - ret.insert(ret.end(),conn,conn+4); - break; - } - case INTERP_KERNEL::NORM_SEG3: - { - int conn[8]={connBg[1],connBg[3],connBg[3]+deltaz,connBg[1]+deltaz,connBg[2],connBg[3]+nbOfNodesPerLev,connBg[2]+deltaz,connBg[1]+nbOfNodesPerLev}; - ret.insert(ret.end(),conn,conn+8); - break; - } - case INTERP_KERNEL::NORM_QUAD4: - { - int conn[8]={connBg[1],connBg[2],connBg[3],connBg[4],connBg[1]+deltaz,connBg[2]+deltaz,connBg[3]+deltaz,connBg[4]+deltaz}; - ret.insert(ret.end(),conn,conn+8); - break; - } - case INTERP_KERNEL::NORM_TRI3: - { - int conn[6]={connBg[1],connBg[2],connBg[3],connBg[1]+deltaz,connBg[2]+deltaz,connBg[3]+deltaz}; - ret.insert(ret.end(),conn,conn+6); - break; - } - case INTERP_KERNEL::NORM_TRI6: - { - int conn[15]={connBg[1],connBg[2],connBg[3],connBg[1]+deltaz,connBg[2]+deltaz,connBg[3]+deltaz,connBg[4],connBg[5],connBg[6],connBg[4]+deltaz,connBg[5]+deltaz,connBg[6]+deltaz, - connBg[1]+nbOfNodesPerLev,connBg[2]+nbOfNodesPerLev,connBg[3]+nbOfNodesPerLev}; - ret.insert(ret.end(),conn,conn+15); - break; - } - case INTERP_KERNEL::NORM_QUAD8: - { - int conn[20]={ - connBg[1],connBg[2],connBg[3],connBg[4],connBg[1]+deltaz,connBg[2]+deltaz,connBg[3]+deltaz,connBg[4]+deltaz, - connBg[5],connBg[6],connBg[7],connBg[8],connBg[5]+deltaz,connBg[6]+deltaz,connBg[7]+deltaz,connBg[8]+deltaz, - connBg[1]+nbOfNodesPerLev,connBg[2]+nbOfNodesPerLev,connBg[3]+nbOfNodesPerLev,connBg[4]+nbOfNodesPerLev - }; - ret.insert(ret.end(),conn,conn+20); - break; - } - case INTERP_KERNEL::NORM_POLYGON: - { - std::back_insert_iterator< std::vector > ii(ret); - std::copy(connBg+1,connEnd,ii); - *ii++=-1; - std::reverse_iterator rConnBg(connEnd); - std::reverse_iterator rConnEnd(connBg+1); - std::transform(rConnBg,rConnEnd,ii,std::bind2nd(std::plus(),deltaz)); - std::size_t nbOfRadFaces=std::distance(connBg+1,connEnd); - for(std::size_t i=0;i0.); -} - -/*! - * The polyhedron is specfied by its connectivity nodes in [ \a begin , \a end ). - */ -bool MEDCouplingUMesh::IsPolyhedronWellOriented(const int *begin, const int *end, const double *coords) -{ - std::vector > edges; - std::size_t nbOfFaces=std::count(begin,end,-1)+1; - const int *bgFace=begin; - for(std::size_t i=0;i p1(bgFace[j],bgFace[(j+1)%nbOfEdgesInFace]); - if(std::find(edges.begin(),edges.end(),p1)!=edges.end()) - return false; - edges.push_back(p1); - } - bgFace=endFace+1; - } - return INTERP_KERNEL::calculateVolumeForPolyh2(begin,(int)std::distance(begin,end),coords)>-EPS_FOR_POLYH_ORIENTATION; -} - -/*! - * The 3D extruded static cell (PENTA6,HEXA8,HEXAGP12...) its connectivity nodes in [ \a begin , \a end ). - */ -bool MEDCouplingUMesh::Is3DExtrudedStaticCellWellOriented(const int *begin, const int *end, const double *coords) -{ - double vec0[3],vec1[3]; - std::size_t sz=std::distance(begin,end); - if(sz%2!=0) - throw INTERP_KERNEL::Exception("MEDCouplingUMesh::Is3DExtrudedStaticCellWellOriented : the length of nodal connectivity of extruded cell is not even !"); - int nbOfNodes=(int)sz/2; - INTERP_KERNEL::areaVectorOfPolygon(begin,nbOfNodes,coords,vec0); - const double *pt0=coords+3*begin[0]; - const double *pt1=coords+3*begin[nbOfNodes]; - vec1[0]=pt1[0]-pt0[0]; vec1[1]=pt1[1]-pt0[1]; vec1[2]=pt1[2]-pt0[2]; - return (vec0[0]*vec1[0]+vec0[1]*vec1[1]+vec0[2]*vec1[2])<0.; -} - -void MEDCouplingUMesh::CorrectExtrudedStaticCell(int *begin, int *end) -{ - std::size_t sz=std::distance(begin,end); - INTERP_KERNEL::AutoPtr tmp=new int[sz]; - std::size_t nbOfNodes(sz/2); - std::copy(begin,end,(int *)tmp); - for(std::size_t j=1;j(begin,4,coords,vec0); - const double *pt0=coords+3*begin[0],*pt1=coords+3*begin[4]; - return (vec0[0]*(pt1[0]-pt0[0])+vec0[1]*(pt1[1]-pt0[1])+vec0[2]*(pt1[2]-pt0[2]))<0.; -} - -/*! - * This method performs a simplyfication of a single polyedron cell. To do that each face of cell whose connectivity is defined by [ \b begin , \b end ) - * is compared with the others in order to find faces in the same plane (with approx of eps). If any, the cells are grouped together and projected to - * a 2D space. - * - * \param [in] eps is a relative precision that allows to establish if some 3D plane are coplanar or not. - * \param [in] coords the coordinates with nb of components exactly equal to 3 - * \param [in] begin begin of the nodal connectivity (geometric type included) of a single polyhedron cell - * \param [in] end end of nodal connectivity of a single polyhedron cell (excluded) - * \param [out] res the result is put at the end of the vector without any alteration of the data. - */ -void MEDCouplingUMesh::SimplifyPolyhedronCell(double eps, const DataArrayDouble *coords, const int *begin, const int *end, DataArrayInt *res) -{ - int nbFaces=std::count(begin+1,end,-1)+1; - MEDCouplingAutoRefCountObjectPtr v=DataArrayDouble::New(); v->alloc(nbFaces,3); - double *vPtr=v->getPointer(); - MEDCouplingAutoRefCountObjectPtr p=DataArrayDouble::New(); p->alloc(nbFaces,1); - double *pPtr=p->getPointer(); - const int *stFaceConn=begin+1; - for(int i=0;igetConstPointer(),stFaceConn,endFaceConn,vPtr,pPtr); - stFaceConn=endFaceConn+1; - } - pPtr=p->getPointer(); vPtr=v->getPointer(); - DataArrayInt *comm1=0,*commI1=0; - v->findCommonTuples(eps,-1,comm1,commI1); - MEDCouplingAutoRefCountObjectPtr comm1Auto(comm1),commI1Auto(commI1); - const int *comm1Ptr=comm1->getConstPointer(); - const int *commI1Ptr=commI1->getConstPointer(); - int nbOfGrps1=commI1Auto->getNumberOfTuples()-1; - res->pushBackSilent((int)INTERP_KERNEL::NORM_POLYHED); - // - MEDCouplingAutoRefCountObjectPtr mm=MEDCouplingUMesh::New("",3); - mm->setCoords(const_cast(coords)); mm->allocateCells(1); mm->insertNextCell(INTERP_KERNEL::NORM_POLYHED,(int)std::distance(begin+1,end),begin+1); - mm->finishInsertingCells(); - // - for(int i=0;i tmpgrp2=p->selectByTupleId(comm1Ptr+commI1Ptr[i],comm1Ptr+commI1Ptr[i+1]); - DataArrayInt *comm2=0,*commI2=0; - tmpgrp2->findCommonTuples(eps,-1,comm2,commI2); - MEDCouplingAutoRefCountObjectPtr comm2Auto(comm2),commI2Auto(commI2); - const int *comm2Ptr=comm2->getConstPointer(); - const int *commI2Ptr=commI2->getConstPointer(); - int nbOfGrps2=commI2Auto->getNumberOfTuples()-1; - for(int j=0;jinsertAtTheEnd(begin,end); - res->pushBackSilent(-1); - } - else - { - int pointId=comm1Ptr[commI1Ptr[i]+comm2Ptr[commI2Ptr[j]]]; - MEDCouplingAutoRefCountObjectPtr ids2=comm2->selectByTupleId2(commI2Ptr[j],commI2Ptr[j+1],1); - ids2->transformWithIndArr(comm1Ptr+commI1Ptr[i],comm1Ptr+commI1Ptr[i+1]); - DataArrayInt *tmp0=DataArrayInt::New(),*tmp1=DataArrayInt::New(),*tmp2=DataArrayInt::New(),*tmp3=DataArrayInt::New(); - MEDCouplingAutoRefCountObjectPtr mm2=mm->buildDescendingConnectivity(tmp0,tmp1,tmp2,tmp3); tmp0->decrRef(); tmp1->decrRef(); tmp2->decrRef(); tmp3->decrRef(); - MEDCouplingAutoRefCountObjectPtr mm3=static_cast(mm2->buildPartOfMySelf(ids2->begin(),ids2->end(),true)); - MEDCouplingAutoRefCountObjectPtr idsNodeTmp=mm3->zipCoordsTraducer(); - MEDCouplingAutoRefCountObjectPtr idsNode=idsNodeTmp->invertArrayO2N2N2O(mm3->getNumberOfNodes()); - const int *idsNodePtr=idsNode->getConstPointer(); - double center[3]; center[0]=pPtr[pointId]*vPtr[3*vecId]; center[1]=pPtr[pointId]*vPtr[3*vecId+1]; center[2]=pPtr[pointId]*vPtr[3*vecId+2]; - double vec[3]; vec[0]=vPtr[3*vecId+1]; vec[1]=-vPtr[3*vecId]; vec[2]=0.; - double norm=vec[0]*vec[0]+vec[1]*vec[1]+vec[2]*vec[2]; - if(std::abs(norm)>eps) - { - double angle=INTERP_KERNEL::EdgeArcCircle::SafeAsin(norm); - mm3->rotate(center,vec,angle); - } - mm3->changeSpaceDimension(2); - MEDCouplingAutoRefCountObjectPtr mm4=mm3->buildSpreadZonesWithPoly(); - const int *conn4=mm4->getNodalConnectivity()->getConstPointer(); - const int *connI4=mm4->getNodalConnectivityIndex()->getConstPointer(); - int nbOfCells=mm4->getNumberOfCells(); - for(int k=0;kpushBackSilent(idsNodePtr[*work]); - res->pushBackSilent(-1); - } - } - } - } - res->popBackSilent(); -} - -/*! - * This method computes the normalized vector of the plane and the pos of the point belonging to the plane and the line defined by the vector going - * through origin. The plane is defined by its nodal connectivity [ \b begin, \b end ). - * - * \param [in] eps below that value the dot product of 2 vectors is considered as colinears - * \param [in] coords coordinates expected to have 3 components. - * \param [in] begin start of the nodal connectivity of the face. - * \param [in] end end of the nodal connectivity (excluded) of the face. - * \param [out] v the normalized vector of size 3 - * \param [out] p the pos of plane - */ -void MEDCouplingUMesh::ComputeVecAndPtOfFace(double eps, const double *coords, const int *begin, const int *end, double *v, double *p) -{ - std::size_t nbPoints=std::distance(begin,end); - if(nbPoints<3) - throw INTERP_KERNEL::Exception("MEDCouplingUMesh::ComputeVecAndPtOfFace : < of 3 points in face ! not able to find a plane on that face !"); - double vec[3]={0.,0.,0.}; - std::size_t j=0; - bool refFound=false; - for(;jeps) - { - refFound=true; - vec[0]/=norm; vec[1]/=norm; vec[2]/=norm; - } - } - for(std::size_t i=j;ieps) - { - v[0]/=norm; v[1]/=norm; v[2]/=norm; - *p=v[0]*coords[3*begin[i]]+v[1]*coords[3*begin[i]+1]+v[2]*coords[3*begin[i]+2]; - return ; - } - } - throw INTERP_KERNEL::Exception("Not able to find a normal vector of that 3D face !"); -} - -/*! - * This method tries to obtain a well oriented polyhedron. - * If the algorithm fails, an exception will be thrown. - */ -void MEDCouplingUMesh::TryToCorrectPolyhedronOrientation(int *begin, int *end, const double *coords) -{ - std::list< std::pair > edgesOK,edgesFinished; - std::size_t nbOfFaces=std::count(begin,end,-1)+1; - std::vector isPerm(nbOfFaces,false);//field on faces False: I don't know, True : oriented - isPerm[0]=true; - int *bgFace=begin,*endFace=std::find(begin+1,end,-1); - std::size_t nbOfEdgesInFace=std::distance(bgFace,endFace); - for(std::size_t l=0;l p1(bgFace[l],bgFace[(l+1)%nbOfEdgesInFace]); edgesOK.push_back(p1); } - // - while(std::find(isPerm.begin(),isPerm.end(),false)!=isPerm.end()) - { - bgFace=begin; - std::size_t smthChanged=0; - for(std::size_t i=0;i p1(bgFace[j],bgFace[(j+1)%nbOfEdgesInFace]); - std::pair p2(p1.second,p1.first); - bool b1=std::find(edgesOK.begin(),edgesOK.end(),p1)!=edgesOK.end(); - bool b2=std::find(edgesOK.begin(),edgesOK.end(),p2)!=edgesOK.end(); - if(b1 || b2) { b=b2; isPerm[i]=true; smthChanged++; break; } - } - if(isPerm[i]) - { - if(!b) - std::reverse(bgFace+1,endFace); - for(std::size_t j=0;j p1(bgFace[j],bgFace[(j+1)%nbOfEdgesInFace]); - std::pair p2(p1.second,p1.first); - if(std::find(edgesOK.begin(),edgesOK.end(),p1)!=edgesOK.end()) - { std::ostringstream oss; oss << "Face #" << j << " of polyhedron looks bad !"; throw INTERP_KERNEL::Exception(oss.str().c_str()); } - if(std::find(edgesFinished.begin(),edgesFinished.end(),p1)!=edgesFinished.end() || std::find(edgesFinished.begin(),edgesFinished.end(),p2)!=edgesFinished.end()) - { std::ostringstream oss; oss << "Face #" << j << " of polyhedron looks bad !"; throw INTERP_KERNEL::Exception(oss.str().c_str()); } - std::list< std::pair >::iterator it=std::find(edgesOK.begin(),edgesOK.end(),p2); - if(it!=edgesOK.end()) - { - edgesOK.erase(it); - edgesFinished.push_back(p1); - } - else - edgesOK.push_back(p1); - } - } - } - bgFace=endFace+1; - } - if(smthChanged==0) - { throw INTERP_KERNEL::Exception("The polyhedron looks too bad to be repaired !"); } - } - if(!edgesOK.empty()) - { throw INTERP_KERNEL::Exception("The polyhedron looks too bad to be repaired : Some edges are shared only once !"); } - if(INTERP_KERNEL::calculateVolumeForPolyh2(begin,(int)std::distance(begin,end),coords)<-EPS_FOR_POLYH_ORIENTATION) - {//not lucky ! The first face was not correctly oriented : reorient all faces... - bgFace=begin; - for(std::size_t i=0;igetNumberOfNodes()); - const int *n2oPtr(n2o->getConstPointer()); - MEDCouplingAutoRefCountObjectPtr revNodal(DataArrayInt::New()),revNodalI(DataArrayInt::New()); - skin->getReverseNodalConnectivity(revNodal,revNodalI); - const int *revNodalPtr(revNodal->getConstPointer()),*revNodalIPtr(revNodalI->getConstPointer()); - const int *nodalPtr(skin->getNodalConnectivity()->getConstPointer()); - const int *nodalIPtr(skin->getNodalConnectivityIndex()->getConstPointer()); - MEDCouplingAutoRefCountObjectPtr ret(DataArrayInt::New()); ret->alloc(nbOfNodesExpected+1,1); - int *work(ret->getPointer()); *work++=INTERP_KERNEL::NORM_POLYGON; - if(nbOfNodesExpected<1) - return ret.retn(); - int prevCell(0),prevNode(nodalPtr[nodalIPtr[0]+1]); - *work++=n2oPtr[prevNode]; - for(int i=1;i conn(nodalPtr+nodalIPtr[prevCell]+1,nodalPtr+nodalIPtr[prevCell]+3); - conn.erase(prevNode); - if(conn.size()==1) - { - int curNode(*(conn.begin())); - *work++=n2oPtr[curNode]; - std::set shar(revNodalPtr+revNodalIPtr[curNode],revNodalPtr+revNodalIPtr[curNode+1]); - shar.erase(prevCell); - if(shar.size()==1) - { - prevCell=*(shar.begin()); - prevNode=curNode; - } - else - throw INTERP_KERNEL::Exception("MEDCouplingUMesh::buildUnionOf2DMeshLinear : presence of unexpected 2 !"); - } - else - throw INTERP_KERNEL::Exception("MEDCouplingUMesh::buildUnionOf2DMeshLinear : presence of unexpected 1 !"); - } - else - throw INTERP_KERNEL::Exception("MEDCouplingUMesh::buildUnionOf2DMeshLinear : presence of unexpected cell !"); - } - return ret.retn(); -} - -DataArrayInt *MEDCouplingUMesh::buildUnionOf2DMeshQuadratic(const MEDCouplingUMesh *skin, const DataArrayInt *n2o) const -{ - int nbOfNodesExpected(skin->getNumberOfNodes()); - int nbOfTurn(nbOfNodesExpected/2); - const int *n2oPtr(n2o->getConstPointer()); - MEDCouplingAutoRefCountObjectPtr revNodal(DataArrayInt::New()),revNodalI(DataArrayInt::New()); - skin->getReverseNodalConnectivity(revNodal,revNodalI); - const int *revNodalPtr(revNodal->getConstPointer()),*revNodalIPtr(revNodalI->getConstPointer()); - const int *nodalPtr(skin->getNodalConnectivity()->getConstPointer()); - const int *nodalIPtr(skin->getNodalConnectivityIndex()->getConstPointer()); - MEDCouplingAutoRefCountObjectPtr ret(DataArrayInt::New()); ret->alloc(nbOfNodesExpected+1,1); - int *work(ret->getPointer()); *work++=INTERP_KERNEL::NORM_QPOLYG; - if(nbOfNodesExpected<1) - return ret.retn(); - int prevCell(0),prevNode(nodalPtr[nodalIPtr[0]+1]); - *work=n2oPtr[prevNode]; work[nbOfTurn]=n2oPtr[nodalPtr[nodalIPtr[0]+3]]; work++; - for(int i=1;i conn(nodalPtr+nodalIPtr[prevCell]+1,nodalPtr+nodalIPtr[prevCell]+3); - conn.erase(prevNode); - if(conn.size()==1) - { - int curNode(*(conn.begin())); - *work=n2oPtr[curNode]; - std::set shar(revNodalPtr+revNodalIPtr[curNode],revNodalPtr+revNodalIPtr[curNode+1]); - shar.erase(prevCell); - if(shar.size()==1) - { - int curCell(*(shar.begin())); - work[nbOfTurn]=n2oPtr[nodalPtr[nodalIPtr[curCell]+3]]; - prevCell=curCell; - prevNode=curNode; - work++; - } - else - throw INTERP_KERNEL::Exception("MEDCouplingUMesh::buildUnionOf2DMeshQuadratic : presence of unexpected 2 !"); - } - else - throw INTERP_KERNEL::Exception("MEDCouplingUMesh::buildUnionOf2DMeshQuadratic : presence of unexpected 1 !"); - } - else - throw INTERP_KERNEL::Exception("MEDCouplingUMesh::buildUnionOf2DMeshQuadratic : presence of unexpected cell !"); - } - return ret.retn(); -} - -/*! - * This method makes the assumption spacedimension == meshdimension == 2. - * This method works only for linear cells. - * - * \return a newly allocated array containing the connectivity of a polygon type enum included (NORM_POLYGON in pos#0) - */ -DataArrayInt *MEDCouplingUMesh::buildUnionOf2DMesh() const -{ - if(getMeshDimension()!=2 || getSpaceDimension()!=2) - throw INTERP_KERNEL::Exception("MEDCouplingUMesh::buildUnionOf2DMesh : meshdimension, spacedimension must be equal to 2 !"); - MEDCouplingAutoRefCountObjectPtr skin(computeSkin()); - int oldNbOfNodes(skin->getNumberOfNodes()); - MEDCouplingAutoRefCountObjectPtr o2n(skin->zipCoordsTraducer()); - int nbOfNodesExpected(skin->getNumberOfNodes()); - MEDCouplingAutoRefCountObjectPtr n2o(o2n->invertArrayO2N2N2O(oldNbOfNodes)); - int nbCells(skin->getNumberOfCells()); - if(nbCells==nbOfNodesExpected) - return buildUnionOf2DMeshLinear(skin,n2o); - else if(2*nbCells==nbOfNodesExpected) - return buildUnionOf2DMeshQuadratic(skin,n2o); - else - throw INTERP_KERNEL::Exception("MEDCouplingUMesh::buildUnionOf2DMesh : the mesh 2D in input appears to be not in a single part of a 2D mesh !"); -} - -/*! - * This method makes the assumption spacedimension == meshdimension == 3. - * This method works only for linear cells. - * - * \return a newly allocated array containing the connectivity of a polygon type enum included (NORM_POLYHED in pos#0) - */ -DataArrayInt *MEDCouplingUMesh::buildUnionOf3DMesh() const -{ - if(getMeshDimension()!=3 || getSpaceDimension()!=3) - throw INTERP_KERNEL::Exception("MEDCouplingUMesh::buildUnionOf3DMesh : meshdimension, spacedimension must be equal to 2 !"); - MEDCouplingAutoRefCountObjectPtr m=computeSkin(); - const int *conn=m->getNodalConnectivity()->getConstPointer(); - const int *connI=m->getNodalConnectivityIndex()->getConstPointer(); - int nbOfCells=m->getNumberOfCells(); - MEDCouplingAutoRefCountObjectPtr ret=DataArrayInt::New(); ret->alloc(m->getNodalConnectivity()->getNumberOfTuples(),1); - int *work=ret->getPointer(); *work++=INTERP_KERNEL::NORM_POLYHED; - if(nbOfCells<1) - return ret.retn(); - work=std::copy(conn+connI[0]+1,conn+connI[1],work); - for(int i=1;igetMeshDimension(); - ParaMEDMEM::DataArrayInt* indexr=ParaMEDMEM::DataArrayInt::New(); - ParaMEDMEM::DataArrayInt* revConn=ParaMEDMEM::DataArrayInt::New(); - this->getReverseNodalConnectivity(revConn,indexr); - const int* indexr_ptr=indexr->getConstPointer(); - const int* revConn_ptr=revConn->getConstPointer(); - - const ParaMEDMEM::DataArrayInt* index; - const ParaMEDMEM::DataArrayInt* conn; - conn=this->getNodalConnectivity(); // it includes a type as the 1st element!!! - index=this->getNodalConnectivityIndex(); - int nbCells=this->getNumberOfCells(); - const int* index_ptr=index->getConstPointer(); - const int* conn_ptr=conn->getConstPointer(); - - //creating graph arcs (cell to cell relations) - //arcs are stored in terms of (index,value) notation - // 0 3 5 6 6 - // 1 2 3 2 3 3 - // means 6 arcs (0,1), (0,2), (0,3), (1,2), (1,3), (2,3) - // in present version arcs are not doubled but reflexive (1,1) arcs are present for each cell - - //warning here one node have less than or equal effective number of cell with it - //but cell could have more than effective nodes - //because other equals nodes in other domain (with other global inode) - std::vector cell2cell_index(nbCells+1,0); - std::vector cell2cell; - cell2cell.reserve(3*nbCells); - - for (int icell=0; icell counter; - for (int iconn=index_ptr[icell]+1; iconn::iterator iter=counter.find(icell2); - if (iter!=counter.end()) (iter->second)++; - else counter.insert(std::make_pair(icell2,1)); - } - } - for (std::map::const_iterator iter=counter.begin(); - iter!=counter.end(); iter++) - if (iter->second >= meshDim) - { - cell2cell_index[icell+1]++; - cell2cell.push_back(iter->first); - } - } - indexr->decrRef(); - revConn->decrRef(); - cell2cell_index[0]=0; - for (int icell=0; icell\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",byteData); - else - { - MEDCouplingAutoRefCountObjectPtr coo=_coords->changeNbOfComponents(3,0.); - coo->writeVTK(ofs,8,"Points",byteData); - } - ofs << " \n"; - ofs << " \n"; - const int *cPtr=_nodal_connec->getConstPointer(); - const int *cIPtr=_nodal_connec_index->getConstPointer(); - MEDCouplingAutoRefCountObjectPtr faceoffsets=DataArrayInt::New(); faceoffsets->alloc(nbOfCells,1); - MEDCouplingAutoRefCountObjectPtr types=DataArrayInt::New(); types->alloc(nbOfCells,1); - MEDCouplingAutoRefCountObjectPtr offsets=DataArrayInt::New(); offsets->alloc(nbOfCells,1); - MEDCouplingAutoRefCountObjectPtr connectivity=DataArrayInt::New(); connectivity->alloc(_nodal_connec->getNumberOfTuples()-nbOfCells,1); - int *w1=faceoffsets->getPointer(),*w2=types->getPointer(),*w3=offsets->getPointer(),*w4=connectivity->getPointer(); - int szFaceOffsets=0,szConn=0; - for(int i=0;i c(cPtr+cIPtr[i]+1,cPtr+cIPtr[i+1]); c.erase(-1); - *w3=szConn+(int)c.size(); szConn+=(int)c.size(); - w4=std::copy(c.begin(),c.end(),w4); - } - } - types->transformWithIndArr(PARAMEDMEM2VTKTYPETRADUCER,PARAMEDMEM2VTKTYPETRADUCER+INTERP_KERNEL::NORM_MAXTYPE+1); - types->writeVTK(ofs,8,"UInt8","types",byteData); - offsets->writeVTK(ofs,8,"Int32","offsets",byteData); - if(szFaceOffsets!=0) - {//presence of Polyhedra - connectivity->reAlloc(szConn); - faceoffsets->writeVTK(ofs,8,"Int32","faceoffsets",byteData); - MEDCouplingAutoRefCountObjectPtr faces=DataArrayInt::New(); faces->alloc(szFaceOffsets,1); - w1=faces->getPointer(); - for(int i=0;iwriteVTK(ofs,8,"Int32","faces",byteData); - } - connectivity->writeVTK(ofs,8,"Int32","connectivity",byteData); - ofs << " \n"; - ofs << " \n"; - ofs << " \n"; -} - -void MEDCouplingUMesh::reprQuickOverview(std::ostream& stream) const -{ - stream << "MEDCouplingUMesh C++ instance at " << this << ". Name : \"" << getName() << "\"."; - if(_mesh_dim==-2) - { stream << " Not set !"; return ; } - stream << " Mesh dimension : " << _mesh_dim << "."; - if(_mesh_dim==-1) - return ; - if(!_coords) - { stream << " No coordinates set !"; return ; } - if(!_coords->isAllocated()) - { stream << " Coordinates set but not allocated !"; return ; } - stream << " Space dimension : " << _coords->getNumberOfComponents() << "." << std::endl; - stream << "Number of nodes : " << _coords->getNumberOfTuples() << "."; - if(!_nodal_connec_index) - { stream << std::endl << "Nodal connectivity NOT set !"; return ; } - if(!_nodal_connec_index->isAllocated()) - { stream << std::endl << "Nodal connectivity set but not allocated !"; return ; } - int lgth=_nodal_connec_index->getNumberOfTuples(); - int cpt=_nodal_connec_index->getNumberOfComponents(); - if(cpt!=1 || lgth<1) - return ; - stream << std::endl << "Number of cells : " << lgth-1 << "."; -} - -std::string MEDCouplingUMesh::getVTKDataSetType() const -{ - return std::string("UnstructuredGrid"); -} - -std::string MEDCouplingUMesh::getVTKFileExtension() const -{ - return std::string("vtu"); -} - -/*! - * Partitions the first given 2D mesh using the second given 2D mesh as a tool, and - * returns a result mesh constituted by polygons. - * Thus the final result contains all nodes from m1 plus new nodes. However it doesn't necessarily contains - * all nodes from m2. - * The meshes should be in 2D space. In - * addition, returns two arrays mapping cells of the result mesh to cells of the input - * meshes. - * \param [in] m1 - the first input mesh which is a partitioned object. The mesh must be so that each point in the space covered by \a m1 - * must be covered exactly by one entity, \b no \b more. If it is not the case, some tools are available to heal the mesh (conformize2D, mergeNodes) - * \param [in] m2 - the second input mesh which is a partition tool. The mesh must be so that each point in the space covered by \a m2 - * must be covered exactly by one entity, \b no \b more. If it is not the case, some tools are available to heal the mesh (conformize2D, mergeNodes) - * \param [in] eps - precision used to detect coincident mesh entities. - * \param [out] cellNb1 - a new instance of DataArrayInt holding for each result - * cell an id of the cell of \a m1 it comes from. The caller is to delete - * this array using decrRef() as it is no more needed. - * \param [out] cellNb2 - a new instance of DataArrayInt holding for each result - * cell an id of the cell of \a m2 it comes from. -1 value means that a - * result cell comes from a cell (or part of cell) of \a m1 not overlapped by - * any cell of \a m2. The caller is to delete this array using decrRef() as - * it is no more needed. - * \return MEDCouplingUMesh * - the result 2D mesh which is 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 in any of the meshes. - * \throw If the nodal connectivity of cells is not defined in any of the meshes. - * \throw If any of the meshes is not a 2D mesh in 2D space. - * - * \sa conformize2D, mergeNodes - */ -MEDCouplingUMesh *MEDCouplingUMesh::Intersect2DMeshes(const MEDCouplingUMesh *m1, const MEDCouplingUMesh *m2, - double eps, DataArrayInt *&cellNb1, DataArrayInt *&cellNb2) -{ - if(!m1 || !m2) - throw INTERP_KERNEL::Exception("MEDCouplingUMesh::Intersect2DMeshes : input meshes must be not NULL !"); - m1->checkFullyDefined(); - m2->checkFullyDefined(); - if(m1->getMeshDimension()!=2 || m1->getSpaceDimension()!=2 || m2->getMeshDimension()!=2 || m2->getSpaceDimension()!=2) - throw INTERP_KERNEL::Exception("MEDCouplingUMesh::Intersect2DMeshes works on umeshes m1 AND m2 with meshdim equal to 2 and spaceDim equal to 2 too!"); - - // Step 1: compute all edge intersections (new nodes) - std::vector< std::vector > intersectEdge1, colinear2, subDiv2; - MEDCouplingUMesh *m1Desc=0,*m2Desc=0; // descending connec. meshes - DataArrayInt *desc1=0,*descIndx1=0,*revDesc1=0,*revDescIndx1=0,*desc2=0,*descIndx2=0,*revDesc2=0,*revDescIndx2=0; - std::vector addCoo,addCoordsQuadratic; // coordinates of newly created nodes - IntersectDescending2DMeshes(m1,m2,eps,intersectEdge1,colinear2, subDiv2, - m1Desc,desc1,descIndx1,revDesc1,revDescIndx1, - addCoo, m2Desc,desc2,descIndx2,revDesc2,revDescIndx2); - revDesc1->decrRef(); revDescIndx1->decrRef(); revDesc2->decrRef(); revDescIndx2->decrRef(); - MEDCouplingAutoRefCountObjectPtr dd1(desc1),dd2(descIndx1),dd3(desc2),dd4(descIndx2); - MEDCouplingAutoRefCountObjectPtr dd5(m1Desc),dd6(m2Desc); - - // Step 2: re-order newly created nodes according to the ordering found in m2 - std::vector< std::vector > intersectEdge2; - BuildIntersectEdges(m1Desc,m2Desc,addCoo,subDiv2,intersectEdge2); - subDiv2.clear(); dd5=0; dd6=0; - - // Step 3: - std::vector cr,crI; //no DataArrayInt because interface with Geometric2D - std::vector cNb1,cNb2; //no DataArrayInt because interface with Geometric2D - BuildIntersecting2DCellsFromEdges(eps,m1,desc1->getConstPointer(),descIndx1->getConstPointer(),intersectEdge1,colinear2,m2,desc2->getConstPointer(),descIndx2->getConstPointer(),intersectEdge2,addCoo, - /* outputs -> */addCoordsQuadratic,cr,crI,cNb1,cNb2); - - // Step 4: Prepare final result: - MEDCouplingAutoRefCountObjectPtr addCooDa(DataArrayDouble::New()); - addCooDa->alloc((int)(addCoo.size())/2,2); - std::copy(addCoo.begin(),addCoo.end(),addCooDa->getPointer()); - MEDCouplingAutoRefCountObjectPtr addCoordsQuadraticDa(DataArrayDouble::New()); - addCoordsQuadraticDa->alloc((int)(addCoordsQuadratic.size())/2,2); - std::copy(addCoordsQuadratic.begin(),addCoordsQuadratic.end(),addCoordsQuadraticDa->getPointer()); - std::vector coordss(4); - coordss[0]=m1->getCoords(); coordss[1]=m2->getCoords(); coordss[2]=addCooDa; coordss[3]=addCoordsQuadraticDa; - MEDCouplingAutoRefCountObjectPtr coo(DataArrayDouble::Aggregate(coordss)); - MEDCouplingAutoRefCountObjectPtr ret(MEDCouplingUMesh::New("Intersect2D",2)); - MEDCouplingAutoRefCountObjectPtr conn(DataArrayInt::New()); conn->alloc((int)cr.size(),1); std::copy(cr.begin(),cr.end(),conn->getPointer()); - MEDCouplingAutoRefCountObjectPtr connI(DataArrayInt::New()); connI->alloc((int)crI.size(),1); std::copy(crI.begin(),crI.end(),connI->getPointer()); - MEDCouplingAutoRefCountObjectPtr c1(DataArrayInt::New()); c1->alloc((int)cNb1.size(),1); std::copy(cNb1.begin(),cNb1.end(),c1->getPointer()); - MEDCouplingAutoRefCountObjectPtr c2(DataArrayInt::New()); c2->alloc((int)cNb2.size(),1); std::copy(cNb2.begin(),cNb2.end(),c2->getPointer()); - ret->setConnectivity(conn,connI,true); - ret->setCoords(coo); - cellNb1=c1.retn(); cellNb2=c2.retn(); - return ret.retn(); -} - -/// @cond INTERNAL - -bool IsColinearOfACellOf(const std::vector< std::vector >& intersectEdge1, const std::vector& candidates, int start, int stop, int& retVal) -{ - if(candidates.empty()) - return false; - for(std::vector::const_iterator it=candidates.begin();it!=candidates.end();it++) - { - const std::vector& pool(intersectEdge1[*it]); - int tmp[2]; tmp[0]=start; tmp[1]=stop; - if(std::search(pool.begin(),pool.end(),tmp,tmp+2)!=pool.end()) - { - retVal=*it+1; - return true; - } - tmp[0]=stop; tmp[1]=start; - if(std::search(pool.begin(),pool.end(),tmp,tmp+2)!=pool.end()) - { - retVal=-*it-1; - return true; - } - } - return false; -} - -MEDCouplingUMesh *BuildMesh1DCutFrom(const MEDCouplingUMesh *mesh1D, const std::vector< std::vector >& intersectEdge2, const DataArrayDouble *coords1, const std::vector& addCoo, const std::map& mergedNodes, const std::vector< std::vector >& colinear2, const std::vector< std::vector >& intersectEdge1, - MEDCouplingAutoRefCountObjectPtr& idsInRetColinear, MEDCouplingAutoRefCountObjectPtr& idsInMesh1DForIdsInRetColinear) -{ - idsInRetColinear=DataArrayInt::New(); idsInRetColinear->alloc(0,1); - idsInMesh1DForIdsInRetColinear=DataArrayInt::New(); idsInMesh1DForIdsInRetColinear->alloc(0,1); - int nCells(mesh1D->getNumberOfCells()); - if(nCells!=(int)intersectEdge2.size()) - throw INTERP_KERNEL::Exception("BuildMesh1DCutFrom : internal error # 1 !"); - const DataArrayDouble *coo2(mesh1D->getCoords()); - const int *c(mesh1D->getNodalConnectivity()->begin()),*ci(mesh1D->getNodalConnectivityIndex()->begin()); - const double *coo2Ptr(coo2->begin()); - int offset1(coords1->getNumberOfTuples()); - int offset2(offset1+coo2->getNumberOfTuples()); - int offset3(offset2+addCoo.size()/2); - std::vector addCooQuad; - MEDCouplingAutoRefCountObjectPtr cOut(DataArrayInt::New()),ciOut(DataArrayInt::New()); cOut->alloc(0,1); ciOut->alloc(1,1); ciOut->setIJ(0,0,0); - int tmp[4],cicnt(0),kk(0); - for(int i=0;i,int> m; - INTERP_KERNEL::Edge *e(MEDCouplingUMeshBuildQPFromEdge2((INTERP_KERNEL::NormalizedCellType)c[ci[i]],c+ci[i]+1,coo2Ptr,m)); - const std::vector& subEdges(intersectEdge2[i]); - int nbSubEdge(subEdges.size()/2); - for(int j=0;j n1(MEDCouplingUMeshBuildQPNode(subEdges[2*j],coords1->begin(),offset1,coo2Ptr,offset2,addCoo)),n2(MEDCouplingUMeshBuildQPNode(subEdges[2*j+1],coords1->begin(),offset1,coo2Ptr,offset2,addCoo)); - MEDCouplingAutoRefCountObjectPtr e2(e->buildEdgeLyingOnMe(n1,n2)); - INTERP_KERNEL::Edge *e2Ptr(e2); - std::map::const_iterator itm; - if(dynamic_cast(e2Ptr)) - { - tmp[0]=INTERP_KERNEL::NORM_SEG3; - itm=mergedNodes.find(subEdges[2*j]); - tmp[1]=itm!=mergedNodes.end()?(*itm).second:subEdges[2*j]; - itm=mergedNodes.find(subEdges[2*j+1]); - tmp[2]=itm!=mergedNodes.end()?(*itm).second:subEdges[2*j+1]; - tmp[3]=offset3+(int)addCooQuad.size()/2; - double tmp2[2]; - e2->getBarycenter(tmp2); addCooQuad.insert(addCooQuad.end(),tmp2,tmp2+2); - cicnt+=4; - cOut->insertAtTheEnd(tmp,tmp+4); - ciOut->pushBackSilent(cicnt); - } - else - { - tmp[0]=INTERP_KERNEL::NORM_SEG2; - itm=mergedNodes.find(subEdges[2*j]); - tmp[1]=itm!=mergedNodes.end()?(*itm).second:subEdges[2*j]; - itm=mergedNodes.find(subEdges[2*j+1]); - tmp[2]=itm!=mergedNodes.end()?(*itm).second:subEdges[2*j+1]; - cicnt+=3; - cOut->insertAtTheEnd(tmp,tmp+3); - ciOut->pushBackSilent(cicnt); - } - int tmp00; - if(IsColinearOfACellOf(intersectEdge1,colinear2[i],tmp[1],tmp[2],tmp00)) - { - idsInRetColinear->pushBackSilent(kk); - idsInMesh1DForIdsInRetColinear->pushBackSilent(tmp00); - } - } - e->decrRef(); - } - MEDCouplingAutoRefCountObjectPtr ret(MEDCouplingUMesh::New(mesh1D->getName(),1)); - ret->setConnectivity(cOut,ciOut,true); - MEDCouplingAutoRefCountObjectPtr arr3(DataArrayDouble::New()); - arr3->useArray(&addCoo[0],false,C_DEALLOC,(int)addCoo.size()/2,2); - MEDCouplingAutoRefCountObjectPtr arr4(DataArrayDouble::New()); arr4->useArray(&addCooQuad[0],false,C_DEALLOC,(int)addCooQuad.size()/2,2); - std::vector coordss(4); - coordss[0]=coords1; coordss[1]=mesh1D->getCoords(); coordss[2]=arr3; coordss[3]=arr4; - MEDCouplingAutoRefCountObjectPtr arr(DataArrayDouble::Aggregate(coordss)); - ret->setCoords(arr); - return ret.retn(); -} - -MEDCouplingUMesh *BuildRefined2DCellLinear(const DataArrayDouble *coords, const int *descBg, const int *descEnd, const std::vector< std::vector >& intersectEdge1) -{ - std::vector allEdges; - for(const int *it2(descBg);it2!=descEnd;it2++) - { - const std::vector& edge1(intersectEdge1[std::abs(*it2)-1]); - if(*it2>0) - allEdges.insert(allEdges.end(),edge1.begin(),edge1.end()); - else - allEdges.insert(allEdges.end(),edge1.rbegin(),edge1.rend()); - } - std::size_t nb(allEdges.size()); - if(nb%2!=0) - throw INTERP_KERNEL::Exception("BuildRefined2DCellLinear : internal error 1 !"); - std::size_t nbOfEdgesOf2DCellSplit(nb/2); - MEDCouplingAutoRefCountObjectPtr ret(MEDCouplingUMesh::New("",2)); - ret->setCoords(coords); - ret->allocateCells(1); - std::vector connOut(nbOfEdgesOf2DCellSplit); - for(std::size_t kk=0;kkinsertNextCell(INTERP_KERNEL::NORM_POLYGON,connOut.size(),&connOut[0]); - return ret.retn(); -} - -MEDCouplingUMesh *BuildRefined2DCellQuadratic(const DataArrayDouble *coords, const MEDCouplingUMesh *mesh2D, int cellIdInMesh2D, const int *descBg, const int *descEnd, const std::vector< std::vector >& intersectEdge1) -{ - const int *c(mesh2D->getNodalConnectivity()->begin()),*ci(mesh2D->getNodalConnectivityIndex()->begin()); - const INTERP_KERNEL::CellModel& cm(INTERP_KERNEL::CellModel::GetCellModel((INTERP_KERNEL::NormalizedCellType)c[ci[cellIdInMesh2D]])); - std::size_t ii(0); - unsigned sz(cm.getNumberOfSons2(c+ci[cellIdInMesh2D]+1,ci[cellIdInMesh2D+1]-ci[cellIdInMesh2D]-1)); - if(sz!=std::distance(descBg,descEnd)) - throw INTERP_KERNEL::Exception("BuildRefined2DCellQuadratic : internal error 1 !"); - INTERP_KERNEL::AutoPtr tmpPtr(new int[ci[cellIdInMesh2D+1]-ci[cellIdInMesh2D]]); - std::vector allEdges,centers; - const double *coordsPtr(coords->begin()); - MEDCouplingAutoRefCountObjectPtr addCoo(DataArrayDouble::New()); addCoo->alloc(0,1); - int offset(coords->getNumberOfTuples()); - for(const int *it2(descBg);it2!=descEnd;it2++,ii++) - { - INTERP_KERNEL::NormalizedCellType typeOfSon; - cm.fillSonCellNodalConnectivity2(ii,c+ci[cellIdInMesh2D]+1,ci[cellIdInMesh2D+1]-ci[cellIdInMesh2D]-1,tmpPtr,typeOfSon); - const std::vector& edge1(intersectEdge1[std::abs(*it2)-1]); - if(*it2>0) - allEdges.insert(allEdges.end(),edge1.begin(),edge1.end()); - else - allEdges.insert(allEdges.end(),edge1.rbegin(),edge1.rend()); - if(edge1.size()==2) - centers.push_back(tmpPtr[2]);//special case where no subsplit of edge -> reuse the original center. - else - {//the current edge has been subsplit -> create corresponding centers. - std::size_t nbOfCentersToAppend(edge1.size()/2); - std::map< MEDCouplingAutoRefCountObjectPtr,int> m; - MEDCouplingAutoRefCountObjectPtr ee(MEDCouplingUMeshBuildQPFromEdge2(typeOfSon,tmpPtr,coordsPtr,m)); - std::vector::const_iterator it3(allEdges.end()-edge1.size()); - for(std::size_t k=0;kgetMiddleOfPoints(aa,bb,tmpp); - addCoo->insertAtTheEnd(tmpp,tmpp+2); - centers.push_back(offset+k); - } - } - } - std::size_t nb(allEdges.size()); - if(nb%2!=0) - throw INTERP_KERNEL::Exception("BuildRefined2DCellQuadratic : internal error 2 !"); - std::size_t nbOfEdgesOf2DCellSplit(nb/2); - MEDCouplingAutoRefCountObjectPtr ret(MEDCouplingUMesh::New("",2)); - if(addCoo->empty()) - ret->setCoords(coords); - else - { - addCoo->rearrange(2); - addCoo=DataArrayDouble::Aggregate(coords,addCoo); - ret->setCoords(addCoo); - } - ret->allocateCells(1); - std::vector connOut(nbOfEdgesOf2DCellSplit); - for(std::size_t kk=0;kkinsertNextCell(INTERP_KERNEL::NORM_QPOLYG,connOut.size(),&connOut[0]); - return ret.retn(); -} - -/*! - * This method creates a refinement of a cell in \a mesh2D. Those cell is defined by descending connectivity and the sorted subdivided nodal connectivity - * of those edges. - * - * \param [in] mesh2D - The origin 2D mesh. \b Warning \b coords are not those of \a mesh2D. But mesh2D->getCoords()==coords[:mesh2D->getNumberOfNodes()] - */ -MEDCouplingUMesh *BuildRefined2DCell(const DataArrayDouble *coords, const MEDCouplingUMesh *mesh2D, int cellIdInMesh2D, const int *descBg, const int *descEnd, const std::vector< std::vector >& intersectEdge1) -{ - const INTERP_KERNEL::CellModel& cm(INTERP_KERNEL::CellModel::GetCellModel(mesh2D->getTypeOfCell(cellIdInMesh2D))); - if(!cm.isQuadratic()) - return BuildRefined2DCellLinear(coords,descBg,descEnd,intersectEdge1); - else - return BuildRefined2DCellQuadratic(coords,mesh2D,cellIdInMesh2D,descBg,descEnd,intersectEdge1); -} - -void AddCellInMesh2D(MEDCouplingUMesh *mesh2D, const std::vector& conn, const std::vector< MEDCouplingAutoRefCountObjectPtr >& edges) -{ - bool isQuad(false); - for(std::vector< MEDCouplingAutoRefCountObjectPtr >::const_iterator it=edges.begin();it!=edges.end();it++) - { - const INTERP_KERNEL::Edge *ee(*it); - if(dynamic_cast(ee)) - isQuad=true; - } - if(!isQuad) - mesh2D->insertNextCell(INTERP_KERNEL::NORM_POLYGON,conn.size(),&conn[0]); - else - { - const double *coo(mesh2D->getCoords()->begin()); - std::size_t sz(conn.size()); - std::vector addCoo; - std::vector conn2(conn); - int offset(mesh2D->getNumberOfNodes()); - for(std::size_t i=0;igetMiddleOfPoints(coo+2*conn[i],coo+2*conn[(i+1)%sz],tmp);// tony a chier i+1 -> i - addCoo.insert(addCoo.end(),tmp,tmp+2); - conn2.push_back(offset+(int)i); - } - mesh2D->getCoords()->rearrange(1); - mesh2D->getCoords()->pushBackValsSilent(&addCoo[0],&addCoo[0]+addCoo.size()); - mesh2D->getCoords()->rearrange(2); - mesh2D->insertNextCell(INTERP_KERNEL::NORM_QPOLYG,conn2.size(),&conn2[0]); - } -} - -/*! - * \b WARNING edges in out1 coming from \a splitMesh1D are \b NOT oriented because only used for equation of curve. - * - * This method cuts in 2 parts the input 2D cell given using boundaries description (\a edge1Bis and \a edge1BisPtr) using - * a set of edges defined in \a splitMesh1D. - */ -void BuildMesh2DCutInternal2(const MEDCouplingUMesh *splitMesh1D, const std::vector& edge1Bis, const std::vector< MEDCouplingAutoRefCountObjectPtr >& edge1BisPtr, - std::vector< std::vector >& out0, std::vector< std::vector< MEDCouplingAutoRefCountObjectPtr > >& out1) -{ - std::size_t nb(edge1Bis.size()/2); - std::size_t nbOfEdgesOf2DCellSplit(nb/2); - int iEnd(splitMesh1D->getNumberOfCells()); - if(iEnd==0) - throw INTERP_KERNEL::Exception("BuildMesh2DCutInternal2 : internal error ! input 1D mesh must have at least one cell !"); - std::size_t ii,jj; - const int *cSplitPtr(splitMesh1D->getNodalConnectivity()->begin()),*ciSplitPtr(splitMesh1D->getNodalConnectivityIndex()->begin()); - for(ii=0;ii single output cell - out0.resize(1); out1.resize(1); - std::vector& connOut(out0[0]); - connOut.resize(nbOfEdgesOf2DCellSplit); - std::vector< MEDCouplingAutoRefCountObjectPtr >& edgesPtr(out1[0]); - edgesPtr.resize(nbOfEdgesOf2DCellSplit); - for(std::size_t kk=0;kk& connOutLeft(out0[0]); - std::vector& connOutRight(out0[1]);//connOutLeft should end with edge1Bis[2*ii] and connOutRight should end with edge1Bis[2*jj+1] - std::vector< MEDCouplingAutoRefCountObjectPtr >& eleft(out1[0]); - std::vector< MEDCouplingAutoRefCountObjectPtr >& eright(out1[1]); - for(std::size_t k=ii;k > ees(iEnd); - for(int ik=0;ik,int> m; - MEDCouplingAutoRefCountObjectPtr ee(MEDCouplingUMeshBuildQPFromEdge2((INTERP_KERNEL::NormalizedCellType)cSplitPtr[ciSplitPtr[ik]],cSplitPtr+ciSplitPtr[ik]+1,splitMesh1D->getCoords()->begin(),m)); - ees[ik]=ee; - } - for(int ik=iEnd-1;ik>=0;ik--) - connOutLeft.push_back(cSplitPtr[ciSplitPtr[ik]+1]); - for(std::size_t k=jj+1;k& edges, const std::vector< MEDCouplingAutoRefCountObjectPtr >& edgesPtr); -public: - std::vector _edges; - std::vector< MEDCouplingAutoRefCountObjectPtr > _edges_ptr; -}; - -CellInfo::CellInfo(const std::vector& edges, const std::vector< MEDCouplingAutoRefCountObjectPtr >& edgesPtr) -{ - std::size_t nbe(edges.size()); - std::vector edges2(2*nbe); std::vector< MEDCouplingAutoRefCountObjectPtr > edgesPtr2(2*nbe); - for(std::size_t i=0;i& mesh):_istart(istart),_iend(iend),_mesh(mesh),_left(-7),_right(-7) { } - EdgeInfo(int istart, int iend, int pos, const MEDCouplingAutoRefCountObjectPtr& edge):_istart(istart),_iend(iend),_edge(edge),_left(pos),_right(pos+1) { } - bool isInMyRange(int pos) const { return pos>=_istart && pos<_iend; } - void somethingHappendAt(int pos, const std::vector< MEDCouplingAutoRefCountObjectPtr >& newLeft, const std::vector< MEDCouplingAutoRefCountObjectPtr >& newRight); - void feedEdgeInfoAt(double eps, const MEDCouplingUMesh *mesh2D, int offset, int neighbors[2]) const; -private: - int _istart; - int _iend; - MEDCouplingAutoRefCountObjectPtr _mesh; - MEDCouplingAutoRefCountObjectPtr _edge; - int _left; - int _right; -}; - -void EdgeInfo::somethingHappendAt(int pos, const std::vector< MEDCouplingAutoRefCountObjectPtr >& newLeft, const std::vector< MEDCouplingAutoRefCountObjectPtr >& newRight) -{ - const MEDCouplingUMesh *mesh(_mesh); - if(mesh) - return ; - if(_rightpos) - { _left++; _right++; return ; } - if(_right==pos) - { - bool isLeft(std::find(newLeft.begin(),newLeft.end(),_edge)!=newLeft.end()),isRight(std::find(newRight.begin(),newRight.end(),_edge)!=newRight.end()); - if((isLeft && isRight) || (!isLeft && !isRight)) - throw INTERP_KERNEL::Exception("EdgeInfo::somethingHappendAt : internal error # 1 !"); - if(isLeft) - return ; - if(isRight) - { - _right++; - return ; - } - } - if(_left==pos) - { - bool isLeft(std::find(newLeft.begin(),newLeft.end(),_edge)!=newLeft.end()),isRight(std::find(newRight.begin(),newRight.end(),_edge)!=newRight.end()); - if((isLeft && isRight) || (!isLeft && !isRight)) - throw INTERP_KERNEL::Exception("EdgeInfo::somethingHappendAt : internal error # 2 !"); - if(isLeft) - { - _right++; - return ; - } - if(isRight) - { - _left++; - _right++; - return ; - } - } -} - -void EdgeInfo::feedEdgeInfoAt(double eps, const MEDCouplingUMesh *mesh2D, int offset, int neighbors[2]) const -{ - const MEDCouplingUMesh *mesh(_mesh); - if(!mesh) - { - neighbors[0]=offset+_left; neighbors[1]=offset+_right; - } - else - {// not fully splitting cell case - if(mesh2D->getNumberOfCells()==1) - {//little optimization. 1 cell no need to find in which cell mesh is ! - neighbors[0]=offset; neighbors[1]=offset; - return; - } - else - { - MEDCouplingAutoRefCountObjectPtr barys(mesh->getBarycenterAndOwner()); - int cellId(mesh2D->getCellContainingPoint(barys->begin(),eps)); - if(cellId==-1) - throw INTERP_KERNEL::Exception("EdgeInfo::feedEdgeInfoAt : internal error !"); - neighbors[0]=offset+cellId; neighbors[1]=offset+cellId; - } - } -} - -class VectorOfCellInfo -{ -public: - VectorOfCellInfo(const std::vector& edges, const std::vector< MEDCouplingAutoRefCountObjectPtr >& edgesPtr); - std::size_t size() const { return _pool.size(); } - int getPositionOf(double eps, const MEDCouplingUMesh *mesh) const; - void setMeshAt(int pos, const MEDCouplingAutoRefCountObjectPtr& mesh, int istart, int iend, const MEDCouplingAutoRefCountObjectPtr& mesh1DInCase, const std::vector< std::vector >& edges, const std::vector< std::vector< MEDCouplingAutoRefCountObjectPtr > >& edgePtrs); - const std::vector& getConnOf(int pos) const { return get(pos)._edges; } - const std::vector< MEDCouplingAutoRefCountObjectPtr >& getEdgePtrOf(int pos) const { return get(pos)._edges_ptr; } - MEDCouplingAutoRefCountObjectPtr getZeMesh() const { return _ze_mesh; } - void feedEdgeInfoAt(double eps, int pos, int offset, int neighbors[2]) const; -private: - int getZePosOfEdgeGivenItsGlobalId(int pos) const; - void updateEdgeInfo(int pos, const std::vector< MEDCouplingAutoRefCountObjectPtr >& newLeft, const std::vector< MEDCouplingAutoRefCountObjectPtr >& newRight); - const CellInfo& get(int pos) const; - CellInfo& get(int pos); -private: - std::vector _pool; - MEDCouplingAutoRefCountObjectPtr _ze_mesh; - std::vector _edge_info; -}; - -VectorOfCellInfo::VectorOfCellInfo(const std::vector& edges, const std::vector< MEDCouplingAutoRefCountObjectPtr >& edgesPtr):_pool(1) -{ - _pool[0]._edges=edges; - _pool[0]._edges_ptr=edgesPtr; -} - -int VectorOfCellInfo::getPositionOf(double eps, const MEDCouplingUMesh *mesh) const -{ - if(_pool.empty()) - throw INTERP_KERNEL::Exception("VectorOfCellSplitter::getPositionOf : empty !"); - if(_pool.size()==1) - return 0; - const MEDCouplingUMesh *zeMesh(_ze_mesh); - if(!zeMesh) - throw INTERP_KERNEL::Exception("VectorOfCellSplitter::getPositionOf : null aggregated mesh !"); - MEDCouplingAutoRefCountObjectPtr barys(mesh->getBarycenterAndOwner()); - return zeMesh->getCellContainingPoint(barys->begin(),eps); -} - -void VectorOfCellInfo::setMeshAt(int pos, const MEDCouplingAutoRefCountObjectPtr& mesh, int istart, int iend, const MEDCouplingAutoRefCountObjectPtr& mesh1DInCase, const std::vector< std::vector >& edges, const std::vector< std::vector< MEDCouplingAutoRefCountObjectPtr > >& edgePtrs) -{ - get(pos);//to check pos - bool isFast(pos==0 && _pool.size()==1); - std::size_t sz(edges.size()); - // dealing with edges - if(sz==1) - _edge_info.push_back(EdgeInfo(istart,iend,mesh1DInCase)); - else - _edge_info.push_back(EdgeInfo(istart,iend,pos,edgePtrs[0].back())); - // - std::vector pool(_pool.size()-1+sz); - for(int i=0;i > ms; - if(pos>0) - { - MEDCouplingAutoRefCountObjectPtr elt(static_cast(_ze_mesh->buildPartOfMySelf2(0,pos,true))); - ms.push_back(elt); - } - ms.push_back(mesh); - if(pos<_ze_mesh->getNumberOfCells()-1) - { - MEDCouplingAutoRefCountObjectPtr elt(static_cast(_ze_mesh->buildPartOfMySelf2(pos+1,_ze_mesh->getNumberOfCells(),true))); - ms.push_back(elt); - } - std::vector< const MEDCouplingUMesh *> ms2(ms.size()); - for(std::size_t j=0;j=0 !"); - int ret(0); - for(std::vector::const_iterator it=_edge_info.begin();it!=_edge_info.end();it++,ret++) - { - if((*it).isInMyRange(pos)) - return ret; - } - throw INTERP_KERNEL::Exception("VectorOfCellInfo::getZePosOfEdgeGivenItsGlobalId : invalid id !"); -} - -void VectorOfCellInfo::updateEdgeInfo(int pos, const std::vector< MEDCouplingAutoRefCountObjectPtr >& newLeft, const std::vector< MEDCouplingAutoRefCountObjectPtr >& newRight) -{ - get(pos);//to check; - if(_edge_info.empty()) - return ; - std::size_t sz(_edge_info.size()-1); - for(std::size_t i=0;i=(int)_pool.size()) - throw INTERP_KERNEL::Exception("VectorOfCellSplitter::get const : invalid pos !"); - return _pool[pos]; -} - -CellInfo& VectorOfCellInfo::get(int pos) -{ - if(pos<0 || pos>=(int)_pool.size()) - throw INTERP_KERNEL::Exception("VectorOfCellSplitter::get : invalid pos !"); - return _pool[pos]; -} - -/*! - * Given : - * - a \b closed set of edges ( \a allEdges and \a allEdgesPtr ) that defines the split descending 2D cell. - * - \a splitMesh1D a split 2D curve mesh contained into 2D cell defined above. - * - * This method returns the 2D mesh and feeds \a idsLeftRight using offset. - * - * Algorithm : \a splitMesh1D is cut into contiguous parts. Each contiguous parts will build incrementally the output 2D cells. - * - * \param [in] allEdges a list of pairs (beginNode, endNode). Linked with \a allEdgesPtr to get the equation of edge. - */ -MEDCouplingUMesh *BuildMesh2DCutInternal(double eps, const MEDCouplingUMesh *splitMesh1D, const std::vector& allEdges, const std::vector< MEDCouplingAutoRefCountObjectPtr >& allEdgesPtr, int offset, - MEDCouplingAutoRefCountObjectPtr& idsLeftRight) -{ - int nbCellsInSplitMesh1D(splitMesh1D->getNumberOfCells()); - if(nbCellsInSplitMesh1D==0) - throw INTERP_KERNEL::Exception("BuildMesh2DCutInternal : internal error ! input 1D mesh must have at least one cell !"); - const int *cSplitPtr(splitMesh1D->getNodalConnectivity()->begin()),*ciSplitPtr(splitMesh1D->getNodalConnectivityIndex()->begin()); - std::size_t nb(allEdges.size()),jj; - if(nb%2!=0) - throw INTERP_KERNEL::Exception("BuildMesh2DCutFrom : internal error 2 !"); - std::vector edge1Bis(nb*2); - std::vector< MEDCouplingAutoRefCountObjectPtr > edge1BisPtr(nb*2); - std::copy(allEdges.begin(),allEdges.end(),edge1Bis.begin()); - std::copy(allEdges.begin(),allEdges.end(),edge1Bis.begin()+nb); - std::copy(allEdgesPtr.begin(),allEdgesPtr.end(),edge1BisPtr.begin()); - std::copy(allEdgesPtr.begin(),allEdgesPtr.end(),edge1BisPtr.begin()+nb); - // - idsLeftRight=DataArrayInt::New(); idsLeftRight->alloc(nbCellsInSplitMesh1D*2); idsLeftRight->fillWithValue(-2); idsLeftRight->rearrange(2); - int *idsLeftRightPtr(idsLeftRight->getPointer()); - VectorOfCellInfo pool(edge1Bis,edge1BisPtr); - for(int iStart=0;iStart partOfSplitMesh1D(static_cast(splitMesh1D->buildPartOfMySelf2(iStart,iEnd,1,true))); - int pos(pool.getPositionOf(eps,partOfSplitMesh1D)); - // - MEDCouplingAutoRefCountObjectPtrretTmp(MEDCouplingUMesh::New("",2)); - retTmp->setCoords(splitMesh1D->getCoords()); - retTmp->allocateCells(); - - std::vector< std::vector > out0; - std::vector< std::vector< MEDCouplingAutoRefCountObjectPtr > > out1; - - BuildMesh2DCutInternal2(partOfSplitMesh1D,pool.getConnOf(pos),pool.getEdgePtrOf(pos),out0,out1); - for(std::size_t cnt=0;cnt >& intersectEdge1, int offset, - MEDCouplingAutoRefCountObjectPtr& idsLeftRight) -{ - const int *cdescPtr(mesh2DDesc->getNodalConnectivity()->begin()),*cidescPtr(mesh2DDesc->getNodalConnectivityIndex()->begin()); - // - std::vector allEdges; - std::vector< MEDCouplingAutoRefCountObjectPtr > allEdgesPtr; // for each sub edge in splitMesh2D the uncut Edge object of the original mesh2D - for(const int *it(descBg);it!=descEnd;it++) // for all edges in the descending connectivity of the 2D mesh in relative Fortran mode - { - int edgeId(std::abs(*it)-1); - std::map< MEDCouplingAutoRefCountObjectPtr,int> m; - MEDCouplingAutoRefCountObjectPtr ee(MEDCouplingUMeshBuildQPFromEdge2((INTERP_KERNEL::NormalizedCellType)cdescPtr[cidescPtr[edgeId]],cdescPtr+cidescPtr[edgeId]+1,mesh2DDesc->getCoords()->begin(),m)); - const std::vector& edge1(intersectEdge1[edgeId]); - if(*it>0) - allEdges.insert(allEdges.end(),edge1.begin(),edge1.end()); - else - allEdges.insert(allEdges.end(),edge1.rbegin(),edge1.rend()); - std::size_t sz(edge1.size()); - for(std::size_t cnt=0;cntgetCoords()->begin()); - if(std::distance(candidatesIn2DBg,candidatesIn2DEnd)==1) - return *candidatesIn2DBg; - int edgeId(std::abs(cellIdInMesh1DSplitRelative)-1); - MEDCouplingAutoRefCountObjectPtr cur1D(static_cast(mesh1DSplit->buildPartOfMySelf(&edgeId,&edgeId+1,true))); - if(cellIdInMesh1DSplitRelative<0) - cur1D->changeOrientationOfCells(); - const int *c1D(cur1D->getNodalConnectivity()->begin()); - const INTERP_KERNEL::CellModel& ref1DType(INTERP_KERNEL::CellModel::GetCellModel((INTERP_KERNEL::NormalizedCellType)c1D[0])); - for(const int *it=candidatesIn2DBg;it!=candidatesIn2DEnd;it++) - { - MEDCouplingAutoRefCountObjectPtr cur2D(static_cast(mesh2DSplit->buildPartOfMySelf(it,it+1,true))); - const int *c(cur2D->getNodalConnectivity()->begin()),*ci(cur2D->getNodalConnectivityIndex()->begin()); - const INTERP_KERNEL::CellModel &cm(INTERP_KERNEL::CellModel::GetCellModel((INTERP_KERNEL::NormalizedCellType)c[ci[0]])); - unsigned sz(cm.getNumberOfSons2(c+ci[0]+1,ci[1]-ci[0]-1)); - INTERP_KERNEL::AutoPtr tmpPtr(new int[ci[1]-ci[0]]); - for(unsigned it2=0;it2checkFullyDefined(); - mesh1D->checkFullyDefined(); - const std::vector& compNames(mesh2D->getCoords()->getInfoOnComponents()); - if(mesh2D->getMeshDimension()!=2 || mesh2D->getSpaceDimension()!=2 || mesh1D->getMeshDimension()!=1 || mesh1D->getSpaceDimension()!=2) - throw INTERP_KERNEL::Exception("MEDCouplingUMesh::Intersect2DMeshWith1DLine works with mesh2D with spacedim=meshdim=2 and mesh1D with meshdim=1 spaceDim=2 !"); - // Step 1: compute all edge intersections (new nodes) - std::vector< std::vector > intersectEdge1, colinear2, subDiv2; - std::vector addCoo,addCoordsQuadratic; // coordinates of newly created nodes - INTERP_KERNEL::QUADRATIC_PLANAR::_precision=eps; - INTERP_KERNEL::QUADRATIC_PLANAR::_arc_detection_precision=eps; - // - // Build desc connectivity - DataArrayInt *desc1(DataArrayInt::New()),*descIndx1(DataArrayInt::New()),*revDesc1(DataArrayInt::New()),*revDescIndx1(DataArrayInt::New()); - MEDCouplingAutoRefCountObjectPtr dd1(desc1),dd2(descIndx1),dd3(revDesc1),dd4(revDescIndx1); - MEDCouplingAutoRefCountObjectPtr m1Desc(mesh2D->buildDescendingConnectivity2(desc1,descIndx1,revDesc1,revDescIndx1)); - std::map mergedNodes; - Intersect1DMeshes(m1Desc,mesh1D,eps,intersectEdge1,colinear2,subDiv2,addCoo,mergedNodes); - // use mergeNodes to fix intersectEdge1 - for(std::vector< std::vector >::iterator it0=intersectEdge1.begin();it0!=intersectEdge1.end();it0++) - { - std::size_t n((*it0).size()/2); - int eltStart((*it0)[0]),eltEnd((*it0)[2*n-1]); - std::map::const_iterator it1; - it1=mergedNodes.find(eltStart); - if(it1!=mergedNodes.end()) - (*it0)[0]=(*it1).second; - it1=mergedNodes.find(eltEnd); - if(it1!=mergedNodes.end()) - (*it0)[2*n-1]=(*it1).second; - } - // - MEDCouplingAutoRefCountObjectPtr addCooDa(DataArrayDouble::New()); - addCooDa->useArray(&addCoo[0],false,C_DEALLOC,(int)addCoo.size()/2,2); - // Step 2: re-order newly created nodes according to the ordering found in m2 - std::vector< std::vector > intersectEdge2; - BuildIntersectEdges(m1Desc,mesh1D,addCoo,subDiv2,intersectEdge2); - subDiv2.clear(); - // Step 3: compute splitMesh1D - MEDCouplingAutoRefCountObjectPtr idsInRet1Colinear,idsInDescMesh2DForIdsInRetColinear; - MEDCouplingAutoRefCountObjectPtr ret2(DataArrayInt::New()); ret2->alloc(0,1); - MEDCouplingAutoRefCountObjectPtr ret1(BuildMesh1DCutFrom(mesh1D,intersectEdge2,mesh2D->getCoords(),addCoo,mergedNodes,colinear2,intersectEdge1, - idsInRet1Colinear,idsInDescMesh2DForIdsInRetColinear)); - MEDCouplingAutoRefCountObjectPtr ret3(DataArrayInt::New()); ret3->alloc(ret1->getNumberOfCells()*2,1); ret3->fillWithValue(std::numeric_limits::max()); ret3->rearrange(2); - MEDCouplingAutoRefCountObjectPtr idsInRet1NotColinear(idsInRet1Colinear->buildComplement(ret1->getNumberOfCells())); - // deal with cells in mesh2D that are not cut but only some of their edges are - MEDCouplingAutoRefCountObjectPtr idsInDesc2DToBeRefined(idsInDescMesh2DForIdsInRetColinear->deepCpy()); - idsInDesc2DToBeRefined->abs(); idsInDesc2DToBeRefined->applyLin(1,-1); - idsInDesc2DToBeRefined=idsInDesc2DToBeRefined->buildUnique(); - MEDCouplingAutoRefCountObjectPtr out0s;//ids in mesh2D that are impacted by the fact that some edges of \a mesh1D are part of the edges of those cells - if(!idsInDesc2DToBeRefined->empty()) - { - DataArrayInt *out0(0),*outi0(0); - MEDCouplingUMesh::ExtractFromIndexedArrays(idsInDesc2DToBeRefined->begin(),idsInDesc2DToBeRefined->end(),dd3,dd4,out0,outi0); - MEDCouplingAutoRefCountObjectPtr outi0s(outi0); - out0s=out0; - out0s=out0s->buildUnique(); - out0s->sort(true); - } - // - MEDCouplingAutoRefCountObjectPtr ret1NonCol(static_cast(ret1->buildPartOfMySelf(idsInRet1NotColinear->begin(),idsInRet1NotColinear->end()))); - MEDCouplingAutoRefCountObjectPtr baryRet1(ret1NonCol->getBarycenterAndOwner()); - MEDCouplingAutoRefCountObjectPtr elts,eltsIndex; - mesh2D->getCellsContainingPoints(baryRet1->begin(),baryRet1->getNumberOfTuples(),eps,elts,eltsIndex); - MEDCouplingAutoRefCountObjectPtr eltsIndex2(eltsIndex->deltaShiftIndex()); - MEDCouplingAutoRefCountObjectPtr eltsIndex3(eltsIndex2->getIdsEqual(1)); - if(eltsIndex2->count(0)+eltsIndex3->getNumberOfTuples()!=ret1NonCol->getNumberOfCells()) - throw INTERP_KERNEL::Exception("Intersect2DMeshWith1DLine : internal error 1 !"); - MEDCouplingAutoRefCountObjectPtr cellsToBeModified(elts->buildUnique()); - MEDCouplingAutoRefCountObjectPtr untouchedCells(cellsToBeModified->buildComplement(mesh2D->getNumberOfCells())); - if((DataArrayInt *)out0s) - untouchedCells=untouchedCells->buildSubstraction(out0s);//if some edges in ret1 are colinear to descending mesh of mesh2D remove cells from untouched one - std::vector< MEDCouplingAutoRefCountObjectPtr > outMesh2DSplit; - // OK all is ready to insert in ret2 mesh - if(!untouchedCells->empty()) - {// the most easy part, cells in mesh2D not impacted at all - outMesh2DSplit.push_back(static_cast(mesh2D->buildPartOfMySelf(untouchedCells->begin(),untouchedCells->end()))); - outMesh2DSplit.back()->setCoords(ret1->getCoords()); - ret2->pushBackValsSilent(untouchedCells->begin(),untouchedCells->end()); - } - if((DataArrayInt *)out0s) - {// here dealing with cells in out0s but not in cellsToBeModified - MEDCouplingAutoRefCountObjectPtr fewModifiedCells(out0s->buildSubstraction(cellsToBeModified)); - const int *rdptr(dd3->begin()),*rdiptr(dd4->begin()),*dptr(dd1->begin()),*diptr(dd2->begin()); - for(const int *it=fewModifiedCells->begin();it!=fewModifiedCells->end();it++) - { - outMesh2DSplit.push_back(BuildRefined2DCell(ret1->getCoords(),mesh2D,*it,dptr+diptr[*it],dptr+diptr[*it+1],intersectEdge1)); - ret1->setCoords(outMesh2DSplit.back()->getCoords()); - } - int offset(ret2->getNumberOfTuples()); - ret2->pushBackValsSilent(fewModifiedCells->begin(),fewModifiedCells->end()); - MEDCouplingAutoRefCountObjectPtr partOfRet3(DataArrayInt::New()); partOfRet3->alloc(2*idsInRet1Colinear->getNumberOfTuples(),1); - partOfRet3->fillWithValue(std::numeric_limits::max()); partOfRet3->rearrange(2); - int kk(0),*ret3ptr(partOfRet3->getPointer()); - for(const int *it=idsInDescMesh2DForIdsInRetColinear->begin();it!=idsInDescMesh2DForIdsInRetColinear->end();it++,kk++) - { - int faceId(std::abs(*it)-1); - for(const int *it2=rdptr+rdiptr[faceId];it2!=rdptr+rdiptr[faceId+1];it2++) - { - int tmp(fewModifiedCells->locateValue(*it2)); - if(tmp!=-1) - { - if(std::find(dptr+diptr[*it2],dptr+diptr[*it2+1],-(*it))!=dptr+diptr[*it2+1]) - ret3ptr[2*kk]=tmp+offset; - if(std::find(dptr+diptr[*it2],dptr+diptr[*it2+1],(*it))!=dptr+diptr[*it2+1]) - ret3ptr[2*kk+1]=tmp+offset; - } - else - {//the current edge is shared by a 2D cell that will be split just after - if(std::find(dptr+diptr[*it2],dptr+diptr[*it2+1],-(*it))!=dptr+diptr[*it2+1]) - ret3ptr[2*kk]=-(*it2+1); - if(std::find(dptr+diptr[*it2],dptr+diptr[*it2+1],(*it))!=dptr+diptr[*it2+1]) - ret3ptr[2*kk+1]=-(*it2+1); - } - } - } - m1Desc->setCoords(ret1->getCoords()); - ret1NonCol->setCoords(ret1->getCoords()); - ret3->setPartOfValues3(partOfRet3,idsInRet1Colinear->begin(),idsInRet1Colinear->end(),0,2,1,true); - if(!outMesh2DSplit.empty()) - { - DataArrayDouble *da(outMesh2DSplit.back()->getCoords()); - for(std::vector< MEDCouplingAutoRefCountObjectPtr >::iterator itt=outMesh2DSplit.begin();itt!=outMesh2DSplit.end();itt++) - (*itt)->setCoords(da); - } - } - cellsToBeModified=cellsToBeModified->buildUniqueNotSorted(); - for(const int *it=cellsToBeModified->begin();it!=cellsToBeModified->end();it++) - { - MEDCouplingAutoRefCountObjectPtr idsNonColPerCell(elts->getIdsEqual(*it)); - idsNonColPerCell->transformWithIndArr(eltsIndex3->begin(),eltsIndex3->end()); - MEDCouplingAutoRefCountObjectPtr idsNonColPerCell2(idsInRet1NotColinear->selectByTupleId(idsNonColPerCell->begin(),idsNonColPerCell->end())); - MEDCouplingAutoRefCountObjectPtr partOfMesh1CuttingCur2DCell(static_cast(ret1NonCol->buildPartOfMySelf(idsNonColPerCell->begin(),idsNonColPerCell->end()))); - MEDCouplingAutoRefCountObjectPtr partOfRet3; - MEDCouplingAutoRefCountObjectPtr splitOfOneCell(BuildMesh2DCutFrom(eps,*it,m1Desc,partOfMesh1CuttingCur2DCell,dd1->begin()+dd2->getIJ(*it,0),dd1->begin()+dd2->getIJ((*it)+1,0),intersectEdge1,ret2->getNumberOfTuples(),partOfRet3)); - ret3->setPartOfValues3(partOfRet3,idsNonColPerCell2->begin(),idsNonColPerCell2->end(),0,2,1,true); - outMesh2DSplit.push_back(splitOfOneCell); - for(int i=0;igetNumberOfCells();i++) - ret2->pushBackSilent(*it); - } - // - std::size_t nbOfMeshes(outMesh2DSplit.size()); - std::vector tmp(nbOfMeshes); - for(std::size_t i=0;igetCoords()->setInfoOnComponents(compNames); - MEDCouplingAutoRefCountObjectPtr ret2D(MEDCouplingUMesh::MergeUMeshesOnSameCoords(tmp)); - // To finish - filter ret3 - std::numeric_limits::max() -> -1 - negate values must be resolved. - ret3->rearrange(1); - MEDCouplingAutoRefCountObjectPtr edgesToDealWith(ret3->getIdsStrictlyNegative()); - for(const int *it=edgesToDealWith->begin();it!=edgesToDealWith->end();it++) - { - int old2DCellId(-ret3->getIJ(*it,0)-1); - MEDCouplingAutoRefCountObjectPtr candidates(ret2->getIdsEqual(old2DCellId)); - ret3->setIJ(*it,0,FindRightCandidateAmong(ret2D,candidates->begin(),candidates->end(),ret1,*it%2==0?-((*it)/2+1):(*it)/2+1,eps));// div by 2 because 2 components natively in ret3 - } - ret3->replaceOneValByInThis(std::numeric_limits::max(),-1); - ret3->rearrange(2); - // - splitMesh1D=ret1.retn(); - splitMesh2D=ret2D.retn(); - cellIdInMesh2D=ret2.retn(); - cellIdInMesh1D=ret3.retn(); -} - -/** - * Private. Third step of the partitioning algorithm (Intersect2DMeshes): reconstruct full 2D cells from the - * (newly created) nodes corresponding to the edge intersections. - * Output params: - * @param[out] cr, crI connectivity of the resulting mesh - * @param[out] cNb1, cNb2 correspondance arrays giving for the merged mesh the initial cells IDs in m1 / m2 - * TODO: describe input parameters - */ -void 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) -{ - static const int SPACEDIM=2; - const double *coo1(m1->getCoords()->getConstPointer()); - const int *conn1(m1->getNodalConnectivity()->getConstPointer()),*connI1(m1->getNodalConnectivityIndex()->getConstPointer()); - int offset1(m1->getNumberOfNodes()); - const double *coo2(m2->getCoords()->getConstPointer()); - const int *conn2(m2->getNodalConnectivity()->getConstPointer()),*connI2(m2->getNodalConnectivityIndex()->getConstPointer()); - int offset2(offset1+m2->getNumberOfNodes()); - int offset3(offset2+((int)addCoords.size())/2); - MEDCouplingAutoRefCountObjectPtr bbox1Arr(m1->getBoundingBoxForBBTree()),bbox2Arr(m2->getBoundingBoxForBBTree()); - const double *bbox1(bbox1Arr->begin()),*bbox2(bbox2Arr->begin()); - // Here a BBTree on 2D-cells, not on segments: - BBTree myTree(bbox2,0,0,m2->getNumberOfCells(),eps); - int ncell1(m1->getNumberOfCells()); - crI.push_back(0); - for(int i=0;i candidates2; - myTree.getIntersectingElems(bbox1+i*2*SPACEDIM,candidates2); - std::map mapp; - std::map mappRev; - INTERP_KERNEL::QuadraticPolygon pol1; - INTERP_KERNEL::NormalizedCellType typ=(INTERP_KERNEL::NormalizedCellType)conn1[connI1[i]]; - const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(typ); - // Populate mapp and mappRev with nodes from the current cell (i) from mesh1 - this also builds the Node* objects: - MEDCouplingUMeshBuildQPFromMesh3(coo1,offset1,coo2,offset2,addCoords,desc1+descIndx1[i],desc1+descIndx1[i+1],intesctEdges1,/* output */mapp,mappRev); - // pol1 is the full cell from mesh2, in QP format, with all the additional intersecting nodes. - pol1.buildFromCrudeDataArray(mappRev,cm.isQuadratic(),conn1+connI1[i]+1,coo1, - desc1+descIndx1[i],desc1+descIndx1[i+1],intesctEdges1); - // - std::set edges1;// store all edges of pol1 that are NOT consumed by intersect cells. If any after iteration over candidates2 -> a part of pol1 should appear in result - std::set edgesBoundary2;// store all edges that are on boundary of (pol2 intersect pol1) minus edges on pol1. - INTERP_KERNEL::IteratorOnComposedEdge it1(&pol1); - for(it1.first();!it1.finished();it1.next()) - edges1.insert(it1.current()->getPtr()); - // - std::map > edgesIn2ForShare; // common edges - std::vector pol2s(candidates2.size()); - int ii=0; - for(std::vector::const_iterator it2=candidates2.begin();it2!=candidates2.end();it2++,ii++) - { - INTERP_KERNEL::NormalizedCellType typ2=(INTERP_KERNEL::NormalizedCellType)conn2[connI2[*it2]]; - const INTERP_KERNEL::CellModel& cm2=INTERP_KERNEL::CellModel::GetCellModel(typ2); - // Complete mapping with elements coming from the current cell it2 in mesh2: - MEDCouplingUMeshBuildQPFromMesh3(coo1,offset1,coo2,offset2,addCoords,desc2+descIndx2[*it2],desc2+descIndx2[*it2+1],intesctEdges2,/* output */mapp,mappRev); - // pol2 is the new QP in the final merged result. - pol2s[ii].buildFromCrudeDataArray2(mappRev,cm2.isQuadratic(),conn2+connI2[*it2]+1,coo2,desc2+descIndx2[*it2],desc2+descIndx2[*it2+1],intesctEdges2, - pol1,desc1+descIndx1[i],desc1+descIndx1[i+1],intesctEdges1,colinear2, /* output */ edgesIn2ForShare); - } - ii=0; - for(std::vector::const_iterator it2=candidates2.begin();it2!=candidates2.end();it2++,ii++) - { - INTERP_KERNEL::ComposedEdge::InitLocationsWithOther(pol1,pol2s[ii]); - pol2s[ii].updateLocOfEdgeFromCrudeDataArray2(desc2+descIndx2[*it2],desc2+descIndx2[*it2+1],intesctEdges2,pol1,desc1+descIndx1[i],desc1+descIndx1[i+1],intesctEdges1,colinear2); - //MEDCouplingUMeshAssignOnLoc(pol1,pol2,desc1+descIndx1[i],desc1+descIndx1[i+1],intesctEdges1,desc2+descIndx2[*it2],desc2+descIndx2[*it2+1],intesctEdges2,colinear2); - pol1.buildPartitionsAbs(pol2s[ii],edges1,edgesBoundary2,mapp,i,*it2,offset3,addCoordsQuadratic,cr,crI,cNb1,cNb2); - } - // Deals with remaining (non-consumed) edges from m1: these are the edges that were never touched - // by m2 but that we still want to keep in the final result. - if(!edges1.empty()) - { - try - { - INTERP_KERNEL::QuadraticPolygon::ComputeResidual(pol1,edges1,edgesBoundary2,mapp,offset3,i,addCoordsQuadratic,cr,crI,cNb1,cNb2); - } - catch(INTERP_KERNEL::Exception& e) - { - std::ostringstream oss; oss << "Error when computing residual of cell #" << i << " in source/m1 mesh ! Maybe the neighbours of this cell in mesh are not well connected !\n" << "The deep reason is the following : " << e.what(); - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - } - for(std::map::const_iterator it=mappRev.begin();it!=mappRev.end();it++) - (*it).second->decrRef(); - } -} - -/** - * Provides a renumbering of the cells of this (which has to be a piecewise connected 1D line), so that - * the segments of the line are indexed in consecutive order (i.e. cells \a i and \a i+1 are neighbors). - * This doesn't modify the mesh. This method only works using nodal connectivity consideration. Coordinates of nodes are ignored here. - * The caller is to deal with the resulting DataArrayInt. - * \throw If the coordinate array is not set. - * \throw If the nodal connectivity of the cells is not defined. - * \throw If m1 is not a mesh of dimension 2, or m1 is not a mesh of dimension 1 - * \throw If m2 is not a (piecewise) line (i.e. if a point has more than 2 adjacent segments) - * - * \sa DataArrayInt::sortEachPairToMakeALinkedList - */ -DataArrayInt *MEDCouplingUMesh::orderConsecutiveCells1D() const -{ - checkFullyDefined(); - if(getMeshDimension()!=1) - throw INTERP_KERNEL::Exception("MEDCouplingUMesh::orderConsecutiveCells1D works on unstructured mesh with meshdim = 1 !"); - - // Check that this is a line (and not a more complex 1D mesh) - each point is used at most by 2 segments: - MEDCouplingAutoRefCountObjectPtr _d(DataArrayInt::New()),_dI(DataArrayInt::New()); - MEDCouplingAutoRefCountObjectPtr _rD(DataArrayInt::New()),_rDI(DataArrayInt::New()); - MEDCouplingAutoRefCountObjectPtr m_points(buildDescendingConnectivity(_d, _dI, _rD, _rDI)); - const int *d(_d->getConstPointer()), *dI(_dI->getConstPointer()); - const int *rD(_rD->getConstPointer()), *rDI(_rDI->getConstPointer()); - MEDCouplingAutoRefCountObjectPtr _dsi(_rDI->deltaShiftIndex()); - const int * dsi(_dsi->getConstPointer()); - MEDCouplingAutoRefCountObjectPtr dsii = _dsi->getIdsNotInRange(0,3); - m_points=0; - if (dsii->getNumberOfTuples()) - throw INTERP_KERNEL::Exception("MEDCouplingUMesh::orderConsecutiveCells1D only work with a mesh being a (piecewise) connected line!"); - - int nc(getNumberOfCells()); - MEDCouplingAutoRefCountObjectPtr result(DataArrayInt::New()); - result->alloc(nc,1); - - // set of edges not used so far - std::set edgeSet; - for (int i=0; i linePiece; - // fills a list of consecutive segment linked to startSeg. This can go forward or backward. - for (int direction=0;direction<2;direction++) // direction=0 --> forward, direction=1 --> backward - { - // Fill the list forward (resp. backward) from the start segment: - int activeSeg = startSeg; - int prevPointId = -20; - int ptId; - while (!edgeSet.empty()) - { - if (!(direction == 1 && prevPointId==-20)) // prevent adding twice startSeg - { - if (direction==0) - linePiece.push_back(activeSeg); - else - linePiece.push_front(activeSeg); - edgeSet.erase(activeSeg); - } - - int ptId1 = d[dI[activeSeg]], ptId2 = d[dI[activeSeg]+1]; - ptId = direction ? (ptId1 == prevPointId ? ptId2 : ptId1) : (ptId2 == prevPointId ? ptId1 : ptId2); - if (dsi[ptId] == 1) // hitting the end of the line - break; - prevPointId = ptId; - int seg1 = rD[rDI[ptId]], seg2 = rD[rDI[ptId]+1]; - activeSeg = (seg1 == activeSeg) ? seg2 : seg1; - } - } - // Done, save final piece into DA: - std::copy(linePiece.begin(), linePiece.end(), result->getPointer()+newIdx); - newIdx += linePiece.size(); - - // identify next valid start segment (one which is not consumed) - if(!edgeSet.empty()) - startSeg = *(edgeSet.begin()); - } - while (!edgeSet.empty()); - return result.retn(); -} - -/// @cond INTERNAL - -void IKGeo2DInternalMapper2(INTERP_KERNEL::Node *n, const std::map,int>& m, int forbVal0, int forbVal1, std::vector& isect) -{ - MEDCouplingAutoRefCountObjectPtr nTmp(n); nTmp->incrRef(); - std::map,int>::const_iterator it(m.find(nTmp)); - if(it==m.end()) - throw INTERP_KERNEL::Exception("Internal error in remapping !"); - int v((*it).second); - if(v==forbVal0 || v==forbVal1) - return ; - if(std::find(isect.begin(),isect.end(),v)==isect.end()) - isect.push_back(v); -} - -bool IKGeo2DInternalMapper(const INTERP_KERNEL::ComposedEdge& c, const std::map,int>& m, int forbVal0, int forbVal1, std::vector& isect) -{ - int sz(c.size()); - if(sz<=1) - return false; - bool presenceOfOn(false); - for(int i=0;igetLoc()!=INTERP_KERNEL::FULL_ON_1) - continue ; - IKGeo2DInternalMapper2(e->getStartNode(),m,forbVal0,forbVal1,isect); - IKGeo2DInternalMapper2(e->getEndNode(),m,forbVal0,forbVal1,isect); - } - return presenceOfOn; -} - -/// @endcond - -/** - * This method split some of edges of 2D cells in \a this. The edges to be split are specified in \a subNodesInSeg - * and in \a subNodesInSegI using \ref numbering-indirect storage mode. - * To do the work this method can optionally needs information about middle of subedges for quadratic cases if - * a minimal creation of new nodes is wanted. - * So this method try to reduce at most the number of new nodes. The only case that can lead this method to add - * nodes if a SEG3 is split without information of middle. - * \b WARNING : is returned value is different from 0 a call to MEDCouplingUMesh::mergeNodes is necessary to - * avoid to have a non conform mesh. - * - * \return int - the number of new nodes created (in most of cases 0). - * - * \throw If \a this is not coherent. - * \throw If \a this has not spaceDim equal to 2. - * \throw If \a this has not meshDim equal to 2. - * \throw If some subcells needed to be split are orphan. - * \sa MEDCouplingUMesh::conformize2D - */ -int MEDCouplingUMesh::split2DCells(const DataArrayInt *desc, const DataArrayInt *descI, const DataArrayInt *subNodesInSeg, const DataArrayInt *subNodesInSegI, const DataArrayInt *midOpt, const DataArrayInt *midOptI) -{ - if(!desc || !descI || !subNodesInSeg || !subNodesInSegI) - throw INTERP_KERNEL::Exception("MEDCouplingUMesh::split2DCells : the 4 first arrays must be not null !"); - desc->checkAllocated(); descI->checkAllocated(); subNodesInSeg->checkAllocated(); subNodesInSegI->checkAllocated(); - if(getSpaceDimension()!=2 || getMeshDimension()!=2) - throw INTERP_KERNEL::Exception("MEDCouplingUMesh::split2DCells : This method only works for meshes with spaceDim=2 and meshDim=2 !"); - if(midOpt==0 && midOptI==0) - { - split2DCellsLinear(desc,descI,subNodesInSeg,subNodesInSegI); - return 0; - } - else if(midOpt!=0 && midOptI!=0) - return split2DCellsQuadratic(desc,descI,subNodesInSeg,subNodesInSegI,midOpt,midOptI); - else - throw INTERP_KERNEL::Exception("MEDCouplingUMesh::split2DCells : middle parameters must be set to null for all or not null for all."); -} - -/*! - * \b WARNING this method is \b potentially \b non \b const (if returned array is empty). - * \b WARNING this method lead to have a non geometric type sorted mesh (for MED file users) ! - * This method performs a conformization of \b this. So if a edge in \a this can be split into entire edges in \a this this method - * will suppress such edges to use sub edges in \a this. So this method does not add nodes in \a this if merged edges are both linear (INTERP_KERNEL::NORM_SEG2). - * In the other cases new nodes can be created. If any are created, they will be appended at the end of the coordinates object before the invokation of this method. - * - * Whatever the returned value, this method does not alter the order of cells in \a this neither the orientation of cells. - * The modified cells, if any, are systematically declared as NORM_POLYGON or NORM_QPOLYG depending on the initial quadraticness of geometric type. - * - * This method expects that \b this has a meshDim equal 2 and spaceDim equal to 2 too. - * This method expects that all nodes in \a this are not closer than \a eps. - * If it is not the case you can invoke MEDCouplingUMesh::mergeNodes before calling this method. - * - * \param [in] eps the relative error to detect merged edges. - * \return DataArrayInt * - The list of cellIds in \a this that have been subdivided. If empty, nothing changed in \a this (as if it were a const method). The array is a newly allocated array - * that the user is expected to deal with. - * - * \throw If \a this is not coherent. - * \throw If \a this has not spaceDim equal to 2. - * \throw If \a this has not meshDim equal to 2. - * \sa MEDCouplingUMesh::mergeNodes, MEDCouplingUMesh::split2DCells - */ -DataArrayInt *MEDCouplingUMesh::conformize2D(double eps) -{ - static const int SPACEDIM=2; - checkCoherency(); - if(getSpaceDimension()!=2 || getMeshDimension()!=2) - throw INTERP_KERNEL::Exception("MEDCouplingUMesh::conformize2D : This method only works for meshes with spaceDim=2 and meshDim=2 !"); - MEDCouplingAutoRefCountObjectPtr desc1(DataArrayInt::New()),descIndx1(DataArrayInt::New()),revDesc1(DataArrayInt::New()),revDescIndx1(DataArrayInt::New()); - MEDCouplingAutoRefCountObjectPtr mDesc(buildDescendingConnectivity(desc1,descIndx1,revDesc1,revDescIndx1)); - const int *c(mDesc->getNodalConnectivity()->getConstPointer()),*ci(mDesc->getNodalConnectivityIndex()->getConstPointer()),*rd(revDesc1->getConstPointer()),*rdi(revDescIndx1->getConstPointer()); - MEDCouplingAutoRefCountObjectPtr bboxArr(mDesc->getBoundingBoxForBBTree()); - const double *bbox(bboxArr->begin()),*coords(getCoords()->begin()); - int nCell(getNumberOfCells()),nDescCell(mDesc->getNumberOfCells()); - std::vector< std::vector > intersectEdge(nDescCell),overlapEdge(nDescCell); - std::vector addCoo; - BBTree myTree(bbox,0,0,nDescCell,-eps); - INTERP_KERNEL::QUADRATIC_PLANAR::_precision=eps; - INTERP_KERNEL::QUADRATIC_PLANAR::_arc_detection_precision=eps; - for(int i=0;i candidates; - myTree.getIntersectingElems(bbox+i*2*SPACEDIM,candidates); - for(std::vector::const_iterator it=candidates.begin();it!=candidates.end();it++) - if(*it>i) - { - std::map,int> m; - INTERP_KERNEL::Edge *e1(MEDCouplingUMeshBuildQPFromEdge2((INTERP_KERNEL::NormalizedCellType)c[ci[i]],c+ci[i]+1,coords,m)), - *e2(MEDCouplingUMeshBuildQPFromEdge2((INTERP_KERNEL::NormalizedCellType)c[ci[*it]],c+ci[*it]+1,coords,m)); - INTERP_KERNEL::MergePoints merge; - INTERP_KERNEL::QuadraticPolygon c1,c2; - e1->intersectWith(e2,merge,c1,c2); - e1->decrRef(); e2->decrRef(); - if(IKGeo2DInternalMapper(c1,m,c[ci[i]+1],c[ci[i]+2],intersectEdge[i])) - overlapEdge[i].push_back(*it); - if(IKGeo2DInternalMapper(c2,m,c[ci[*it]+1],c[ci[*it]+2],intersectEdge[*it])) - overlapEdge[*it].push_back(i); - } - } - // splitting done. sort intersect point in intersectEdge. - std::vector< std::vector > middle(nDescCell); - int nbOf2DCellsToBeSplit(0); - bool middleNeedsToBeUsed(false); - std::vector cells2DToTreat(nDescCell,false); - for(int i=0;i& isect(intersectEdge[i]); - int sz((int)isect.size()); - if(sz>1) - { - std::map,int> m; - INTERP_KERNEL::Edge *e(MEDCouplingUMeshBuildQPFromEdge2((INTERP_KERNEL::NormalizedCellType)c[ci[i]],c+ci[i]+1,coords,m)); - e->sortSubNodesAbs(coords,isect); - e->decrRef(); - } - if(sz!=0) - { - int idx0(rdi[i]),idx1(rdi[i+1]); - if(idx1-idx0!=1) - throw INTERP_KERNEL::Exception("MEDCouplingUMesh::conformize2D : internal error #0 !"); - if(!cells2DToTreat[rd[idx0]]) - { - cells2DToTreat[rd[idx0]]=true; - nbOf2DCellsToBeSplit++; - } - // try to reuse at most eventual 'middle' of SEG3 - std::vector& mid(middle[i]); - mid.resize(sz+1,-1); - if((INTERP_KERNEL::NormalizedCellType)c[ci[i]]==INTERP_KERNEL::NORM_SEG3) - { - middleNeedsToBeUsed=true; - const std::vector& candidates(overlapEdge[i]); - std::vector trueCandidates; - for(std::vector::const_iterator itc=candidates.begin();itc!=candidates.end();itc++) - if((INTERP_KERNEL::NormalizedCellType)c[ci[*itc]]==INTERP_KERNEL::NORM_SEG3) - trueCandidates.push_back(*itc); - int stNode(c[ci[i]+1]),endNode(isect[0]); - for(int j=0;j::const_iterator itc=trueCandidates.begin();itc!=trueCandidates.end();itc++) - { - int tmpSt(c[ci[*itc]+1]),tmpEnd(c[ci[*itc]+2]); - if((tmpSt==stNode && tmpEnd==endNode) || (tmpSt==endNode && tmpEnd==stNode)) - { mid[j]=*itc; break; } - } - stNode=endNode; - endNode=j ret(DataArrayInt::New()),notRet(DataArrayInt::New()); ret->alloc(nbOf2DCellsToBeSplit,1); - if(nbOf2DCellsToBeSplit==0) - return ret.retn(); - // - int *retPtr(ret->getPointer()); - for(int i=0;i mSafe,nSafe,oSafe,pSafe,qSafe,rSafe; - DataArrayInt *m(0),*n(0),*o(0),*p(0),*q(0),*r(0); - MEDCouplingUMesh::ExtractFromIndexedArrays(ret->begin(),ret->end(),desc1,descIndx1,m,n); mSafe=m; nSafe=n; - DataArrayInt::PutIntoToSkylineFrmt(intersectEdge,o,p); oSafe=o; pSafe=p; - if(middleNeedsToBeUsed) - { DataArrayInt::PutIntoToSkylineFrmt(middle,q,r); qSafe=q; rSafe=r; } - MEDCouplingAutoRefCountObjectPtr modif(static_cast(buildPartOfMySelf(ret->begin(),ret->end(),true))); - int nbOfNodesCreated(modif->split2DCells(mSafe,nSafe,oSafe,pSafe,qSafe,rSafe)); - setCoords(modif->getCoords());//if nbOfNodesCreated==0 modif and this have the same coordinates pointer so this line has no effect. But for quadratic cases this line is important. - setPartOfMySelf(ret->begin(),ret->end(),*modif); - { - bool areNodesMerged; int newNbOfNodes; - if(nbOfNodesCreated!=0) - MEDCouplingAutoRefCountObjectPtr tmp(mergeNodes(eps,areNodesMerged,newNbOfNodes)); - } - return ret.retn(); -} - -/*! - * This non const method works on 2D mesh. This method scans every cell in \a this and look if each edge constituting this cell is not mergeable with neighbors edges of that cell. - * If yes, the cell is "repaired" to minimize at most its number of edges. So this method do not change the overall shape of cells in \a this (with eps precision). - * This method do not take care of shared edges between cells, so this method can lead to a non conform mesh (\a this). If a conform mesh is required you're expected - * to invoke MEDCouplingUMesh::mergeNodes and MEDCouplingUMesh::conformize2D right after this call. - * This method works on any 2D geometric types of cell (even static one). If a cell is touched its type becomes dynamic automaticaly. For 2D "repaired" quadratic cells - * new nodes for center of merged edges is are systematically created and appended at the end of the previously existing nodes. - * - * If the returned array is empty it means that nothing has changed in \a this (as if it were a const method). If the array is not empty the connectivity of \a this is modified - * using new instance, idem for coordinates. - * - * If \a this is constituted by only linear 2D cells, this method is close to the computation of the convex hull of each cells in \a this. - * - * \return DataArrayInt * - The list of cellIds in \a this that have at least one edge colinearized. - * - * \throw If \a this is not coherent. - * \throw If \a this has not spaceDim equal to 2. - * \throw If \a this has not meshDim equal to 2. - * - * \sa MEDCouplingUMesh::conformize2D, MEDCouplingUMesh::mergeNodes, MEDCouplingUMesh::convexEnvelop2D. - */ -DataArrayInt *MEDCouplingUMesh::colinearize2D(double eps) -{ - MEDCouplingAutoRefCountObjectPtr ret(DataArrayInt::New()); ret->alloc(0,1); - checkCoherency(); - if(getSpaceDimension()!=2 || getMeshDimension()!=2) - throw INTERP_KERNEL::Exception("MEDCouplingUMesh::colinearize2D : This method only works for meshes with spaceDim=2 and meshDim=2 !"); - INTERP_KERNEL::QUADRATIC_PLANAR::_arc_detection_precision=eps; - INTERP_KERNEL::QUADRATIC_PLANAR::_precision=eps; - int nbOfCells(getNumberOfCells()),nbOfNodes(getNumberOfNodes()); - const int *cptr(_nodal_connec->begin()),*ciptr(_nodal_connec_index->begin()); - MEDCouplingAutoRefCountObjectPtr newc(DataArrayInt::New()),newci(DataArrayInt::New()); newci->alloc(nbOfCells+1,1); newc->alloc(0,1); newci->setIJ(0,0,0); - MEDCouplingAutoRefCountObjectPtr appendedCoords(DataArrayDouble::New()); appendedCoords->alloc(0,1);//1 not 2 it is not a bug. - const double *coords(_coords->begin()); - int *newciptr(newci->getPointer()); - for(int i=0;ipushBackSilent(i); - newciptr[1]=newc->getNumberOfTuples(); - } - // - if(ret->empty()) - return ret.retn(); - if(!appendedCoords->empty()) - { - appendedCoords->rearrange(2); - MEDCouplingAutoRefCountObjectPtr newCoords(DataArrayDouble::Aggregate(getCoords(),appendedCoords));//treat info on components - //non const part - setCoords(newCoords); - } - //non const part - setConnectivity(newc,newci,true); - return ret.retn(); -} - -/*! - * \param [out] intersectEdge1 - for each cell in \a m1Desc returns the result of the split. The result is given using pair of int given resp start and stop. - * So for all edge \a i in \a m1Desc \a intersectEdge1[i] is of length 2*n where n is the number of sub edges. - * And for each j in [1,n) intersect[i][2*(j-1)+1]==intersect[i][2*j]. - * \param [out] subDiv2 - for each cell in \a m2Desc returns nodes that split it using convention \a m1Desc first, then \a m2Desc, then addCoo - * \param [out] colinear2 - for each cell in \a m2Desc returns the edges in \a m1Desc that are colinear to it. - * \param [out] addCoo - nodes to be append at the end - * \param [out] mergedNodes - gives all pair of nodes of \a m2Desc that have same location than some nodes in \a m1Desc. key is id in \a m2Desc offseted and value is id in \a m1Desc. - */ -void MEDCouplingUMesh::Intersect1DMeshes(const MEDCouplingUMesh *m1Desc, const MEDCouplingUMesh *m2Desc, double eps, - std::vector< std::vector >& intersectEdge1, std::vector< std::vector >& colinear2, std::vector< std::vector >& subDiv2, std::vector& addCoo, std::map& mergedNodes) -{ - static const int SPACEDIM=2; - INTERP_KERNEL::QUADRATIC_PLANAR::_precision=eps; - INTERP_KERNEL::QUADRATIC_PLANAR::_arc_detection_precision=eps; - const int *c1(m1Desc->getNodalConnectivity()->getConstPointer()),*ci1(m1Desc->getNodalConnectivityIndex()->getConstPointer()); - // Build BB tree of all edges in the tool mesh (second mesh) - MEDCouplingAutoRefCountObjectPtr bbox1Arr(m1Desc->getBoundingBoxForBBTree()),bbox2Arr(m2Desc->getBoundingBoxForBBTree()); - const double *bbox1(bbox1Arr->begin()),*bbox2(bbox2Arr->begin()); - int nDescCell1(m1Desc->getNumberOfCells()),nDescCell2(m2Desc->getNumberOfCells()); - intersectEdge1.resize(nDescCell1); - colinear2.resize(nDescCell2); - subDiv2.resize(nDescCell2); - BBTree myTree(bbox2,0,0,m2Desc->getNumberOfCells(),-eps); - - std::vector candidates1(1); - int offset1(m1Desc->getNumberOfNodes()); - int offset2(offset1+m2Desc->getNumberOfNodes()); - for(int i=0;i candidates2; // edges of mesh2 candidate for intersection - myTree.getIntersectingElems(bbox1+i*2*SPACEDIM,candidates2); - if(!candidates2.empty()) // candidates2 holds edges from the second mesh potentially intersecting current edge i in mesh1 - { - std::map map1,map2; - // pol2 is not necessarily a closed polygon: just a set of (quadratic) edges (same as candidates2) in the Geometric DS format - INTERP_KERNEL::QuadraticPolygon *pol2=MEDCouplingUMeshBuildQPFromMesh(m2Desc,candidates2,map2); - candidates1[0]=i; - INTERP_KERNEL::QuadraticPolygon *pol1=MEDCouplingUMeshBuildQPFromMesh(m1Desc,candidates1,map1); - // This following part is to avoid that some removed nodes (for example due to a merge between pol1 and pol2) are replaced by a newly created one - // This trick guarantees that Node * are discriminant (i.e. form a unique identifier) - std::set nodes; - pol1->getAllNodes(nodes); pol2->getAllNodes(nodes); - std::size_t szz(nodes.size()); - std::vector< MEDCouplingAutoRefCountObjectPtr > nodesSafe(szz); - std::set::const_iterator itt(nodes.begin()); - for(std::size_t iii=0;iiiincrRef(); nodesSafe[iii]=*itt; } - // end of protection - // Performs egde cutting: - pol1->splitAbs(*pol2,map1,map2,offset1,offset2,candidates2,intersectEdge1[i],i,colinear2,subDiv2,addCoo,mergedNodes); - delete pol2; - delete pol1; - } - else - // Copy the edge (take only the two first points, ie discard quadratic point at this stage) - intersectEdge1[i].insert(intersectEdge1[i].end(),c1+ci1[i]+1,c1+ci1[i]+3); - } -} - -/*! - * This method is private and is the first step of Partition of 2D mesh (spaceDim==2 and meshDim==2). - * It builds the descending connectivity of the two meshes, and then using a binary tree - * it computes the edge intersections. This results in new points being created : they're stored in addCoo. - * Documentation about parameters colinear2 and subDiv2 can be found in method QuadraticPolygon::splitAbs(). - */ -void 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, - std::vector& addCoo, - MEDCouplingUMesh *& m2Desc, DataArrayInt *&desc2, DataArrayInt *&descIndx2, DataArrayInt *&revDesc2, DataArrayInt *&revDescIndx2) -{ - // Build desc connectivity - desc1=DataArrayInt::New(); descIndx1=DataArrayInt::New(); revDesc1=DataArrayInt::New(); revDescIndx1=DataArrayInt::New(); - desc2=DataArrayInt::New(); - descIndx2=DataArrayInt::New(); - revDesc2=DataArrayInt::New(); - revDescIndx2=DataArrayInt::New(); - MEDCouplingAutoRefCountObjectPtr dd1(desc1),dd2(descIndx1),dd3(revDesc1),dd4(revDescIndx1); - MEDCouplingAutoRefCountObjectPtr dd5(desc2),dd6(descIndx2),dd7(revDesc2),dd8(revDescIndx2); - m1Desc=m1->buildDescendingConnectivity2(desc1,descIndx1,revDesc1,revDescIndx1); - m2Desc=m2->buildDescendingConnectivity2(desc2,descIndx2,revDesc2,revDescIndx2); - MEDCouplingAutoRefCountObjectPtr dd9(m1Desc),dd10(m2Desc); - std::map notUsedMap; - Intersect1DMeshes(m1Desc,m2Desc,eps,intersectEdge1,colinear2,subDiv2,addCoo,notUsedMap); - m1Desc->incrRef(); desc1->incrRef(); descIndx1->incrRef(); revDesc1->incrRef(); revDescIndx1->incrRef(); - m2Desc->incrRef(); desc2->incrRef(); descIndx2->incrRef(); revDesc2->incrRef(); revDescIndx2->incrRef(); -} - -/*! - * This method performs the 2nd step of Partition of 2D mesh. - * This method has 4 inputs : - * - a mesh 'm1' with meshDim==1 and a SpaceDim==2 - * - a mesh 'm2' with meshDim==1 and a SpaceDim==2 - * - subDiv of size 'm2->getNumberOfCells()' that lists for each seg cell in 'm' the splitting node ids randomly sorted. - * The aim of this method is to sort the splitting nodes, if any, and to put them in 'intersectEdge' output parameter based on edges of mesh 'm2' - * Nodes end up lying consecutively on a cutted edge. - * \param m1 is expected to be a mesh of meshDimension equal to 1 and spaceDim equal to 2. No check of that is performed by this method. - * (Only present for its coords in case of 'subDiv' shares some nodes of 'm1') - * \param m2 is expected to be a mesh of meshDimension equal to 1 and spaceDim equal to 2. No check of that is performed by this method. - * \param addCoo input parameter with additional nodes linked to intersection of the 2 meshes. - * \param[out] intersectEdge the same content as subDiv, but correclty oriented. - */ -void MEDCouplingUMesh::BuildIntersectEdges(const MEDCouplingUMesh *m1, const MEDCouplingUMesh *m2, - const std::vector& addCoo, - const std::vector< std::vector >& subDiv, std::vector< std::vector >& intersectEdge) -{ - int offset1=m1->getNumberOfNodes(); - int ncell=m2->getNumberOfCells(); - const int *c=m2->getNodalConnectivity()->getConstPointer(); - const int *cI=m2->getNodalConnectivityIndex()->getConstPointer(); - const double *coo=m2->getCoords()->getConstPointer(); - const double *cooBis=m1->getCoords()->getConstPointer(); - int offset2=offset1+m2->getNumberOfNodes(); - intersectEdge.resize(ncell); - for(int i=0;i& divs=subDiv[i]; - int nnode=cI[1]-cI[0]-1; - std::map > mapp2; - std::map mapp22; - for(int j=0;j(nn,true); - mapp22[nn]=nnid+offset1; - } - INTERP_KERNEL::Edge *e=MEDCouplingUMeshBuildQPFromEdge((INTERP_KERNEL::NormalizedCellType)c[*cI],mapp2,c+(*cI)+1); - for(std::map >::const_iterator it=mapp2.begin();it!=mapp2.end();it++) - ((*it).second.first)->decrRef(); - std::vector addNodes(divs.size()); - std::map mapp3; - for(std::size_t j=0;jsortIdsAbs(addNodes,mapp22,mapp3,intersectEdge[i]); - for(std::vector::const_iterator it=addNodes.begin();it!=addNodes.end();it++) - (*it)->decrRef(); - e->decrRef(); - } -} - -/*! - * This method is part of the Slice3D algorithm. It is the first step of assembly process, ones coordinates have been computed (by MEDCouplingUMesh::split3DCurveWithPlane method). - * This method allows to compute given the status of 3D curve cells and the descending connectivity 3DSurf->3DCurve to deduce the intersection of each 3D surf cells - * with a plane. The result will be put in 'cut3DSuf' out parameter. - * \param [in] cut3DCurve input paramter that gives for each 3DCurve cell if it owns fully to the plane or partially. - * \param [out] nodesOnPlane, returns all the nodes that are on the plane. - * \param [in] nodal3DSurf is the nodal connectivity of 3D surf mesh. - * \param [in] nodalIndx3DSurf is the nodal connectivity index of 3D surf mesh. - * \param [in] nodal3DCurve is the nodal connectivity of 3D curve mesh. - * \param [in] nodal3DIndxCurve is the nodal connectivity index of 3D curve mesh. - * \param [in] desc is the descending connectivity 3DSurf->3DCurve - * \param [in] descIndx is the descending connectivity index 3DSurf->3DCurve - * \param [out] cut3DSuf input/output param. - */ -void 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) -{ - std::set nodesOnP(nodesOnPlane.begin(),nodesOnPlane.end()); - int nbOf3DSurfCell=(int)cut3DSurf.size(); - for(int i=0;i res; - int offset=descIndx[i]; - int nbOfSeg=descIndx[i+1]-offset; - for(int j=0;j-1) - res.push_back(status); - else - { - res.push_back(nodal3DCurve[nodalIndx3DCurve[edgeId]+1]); - res.push_back(nodal3DCurve[nodalIndx3DCurve[edgeId]+2]); - } - } - } - switch(res.size()) - { - case 2: - { - cut3DSurf[i].first=res[0]; cut3DSurf[i].second=res[1]; - break; - } - case 1: - case 0: - { - std::set s1(nodal3DSurf+nodalIndx3DSurf[i]+1,nodal3DSurf+nodalIndx3DSurf[i+1]); - std::set_intersection(nodesOnP.begin(),nodesOnP.end(),s1.begin(),s1.end(),std::back_insert_iterator< std::vector >(res)); - if(res.size()==2) - { - cut3DSurf[i].first=res[0]; cut3DSurf[i].second=res[1]; - } - else - { - cut3DSurf[i].first=-1; cut3DSurf[i].second=-1; - } - break; - } - default: - {// case when plane is on a multi colinear edge of a polyhedron - if((int)res.size()==2*nbOfSeg) - { - cut3DSurf[i].first=-2; cut3DSurf[i].second=i; - } - else - throw INTERP_KERNEL::Exception("MEDCouplingUMesh::AssemblyPointsFrom3DCurve : unexpected situation !"); - } - } - } -} - -/*! - * \a this is expected to be a mesh with spaceDim==3 and meshDim==3. If not an exception will be thrown. - * This method is part of the Slice3D algorithm. It is the second step of assembly process, ones coordinates have been computed (by MEDCouplingUMesh::split3DCurveWithPlane method). - * This method allows to compute given the result of 3D surf cells with plane and the descending connectivity 3D->3DSurf to deduce the intersection of each 3D cells - * with a plane. The result will be put in 'nodalRes' 'nodalResIndx' and 'cellIds' out parameters. - * \param cut3DSurf input paramter that gives for each 3DSurf its intersection with plane (result of MEDCouplingUMesh::AssemblyForSplitFrom3DCurve). - * \param desc is the descending connectivity 3D->3DSurf - * \param descIndx is the descending connectivity index 3D->3DSurf - */ -void MEDCouplingUMesh::assemblyForSplitFrom3DSurf(const std::vector< std::pair >& cut3DSurf, - const int *desc, const int *descIndx, - DataArrayInt *nodalRes, DataArrayInt *nodalResIndx, DataArrayInt *cellIds) const -{ - checkFullyDefined(); - if(getMeshDimension()!=3 || getSpaceDimension()!=3) - throw INTERP_KERNEL::Exception("MEDCouplingUMesh::assemblyForSplitFrom3DSurf works on umeshes with meshdim equal to 3 and spaceDim equal to 3 too!"); - const int *nodal3D=_nodal_connec->getConstPointer(); - const int *nodalIndx3D=_nodal_connec_index->getConstPointer(); - int nbOfCells=getNumberOfCells(); - for(int i=0;i > m; - int offset=descIndx[i]; - int nbOfFaces=descIndx[i+1]-offset; - int start=-1; - int end=-1; - for(int j=0;j& p=cut3DSurf[desc[offset+j]]; - if(p.first!=-1 && p.second!=-1) - { - if(p.first!=-2) - { - start=p.first; end=p.second; - m[p.first].insert(p.second); - m[p.second].insert(p.first); - } - else - { - const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel((INTERP_KERNEL::NormalizedCellType)nodal3D[nodalIndx3D[i]]); - int sz=nodalIndx3D[i+1]-nodalIndx3D[i]-1; - INTERP_KERNEL::AutoPtr tmp=new int[sz]; - INTERP_KERNEL::NormalizedCellType cmsId; - unsigned nbOfNodesSon=cm.fillSonCellNodalConnectivity2(j,nodal3D+nodalIndx3D[i]+1,sz,tmp,cmsId); - start=tmp[0]; end=tmp[nbOfNodesSon-1]; - for(unsigned k=0;k conn(1,(int)INTERP_KERNEL::NORM_POLYGON); - int prev=end; - while(end!=start) - { - std::map >::const_iterator it=m.find(start); - const std::set& s=(*it).second; - std::set s2; s2.insert(prev); - std::set s3; - std::set_difference(s.begin(),s.end(),s2.begin(),s2.end(),inserter(s3,s3.begin())); - if(s3.size()==1) - { - int val=*s3.begin(); - conn.push_back(start); - prev=start; - start=val; - } - else - start=end; - } - conn.push_back(end); - if(conn.size()>3) - { - nodalRes->insertAtTheEnd(conn.begin(),conn.end()); - nodalResIndx->pushBackSilent(nodalRes->getNumberOfTuples()); - cellIds->pushBackSilent(i); - } - } -} - -/*! - * This method compute the convex hull of a single 2D cell. This method tries to conserve at maximum the given input connectivity. In particular, if the orientation of cell is not clockwise - * as in MED format norm. If definitely the result of Jarvis algorithm is not matchable with the input connectivity, the result will be copied into \b nodalConnecOut parameter and - * the geometric cell type set to INTERP_KERNEL::NORM_POLYGON. - * This method excepts that \b coords parameter is expected to be in dimension 2. [ \b nodalConnBg , \b nodalConnEnd ) is the nodal connectivity of the input - * cell (geometric cell type included at the position 0). If the meshdimension of the input cell is not equal to 2 an INTERP_KERNEL::Exception will be thrown. - * - * \return false if the input connectivity represents already the convex hull, true if the input cell needs to be reordered. - */ -bool MEDCouplingUMesh::BuildConvexEnvelopOf2DCellJarvis(const double *coords, const int *nodalConnBg, const int *nodalConnEnd, DataArrayInt *nodalConnecOut) -{ - std::size_t sz=std::distance(nodalConnBg,nodalConnEnd); - if(sz>=4) - { - const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel((INTERP_KERNEL::NormalizedCellType)*nodalConnBg); - if(cm.getDimension()==2) - { - const int *node=nodalConnBg+1; - int startNode=*node++; - double refX=coords[2*startNode]; - for(;node!=nodalConnEnd;node++) - { - if(coords[2*(*node)] tmpOut; tmpOut.reserve(sz); tmpOut.push_back(startNode); - refX=1e300; - double tmp1; - double tmp2[2]; - double angle0=-M_PI/2; - // - int nextNode=-1; - int prevNode=-1; - double resRef; - double angleNext=0.; - while(nextNode!=startNode) - { - nextNode=-1; - resRef=1e300; - for(node=nodalConnBg+1;node!=nodalConnEnd;node++) - { - if(*node!=tmpOut.back() && *node!=prevNode) - { - tmp2[0]=coords[2*(*node)]-coords[2*tmpOut.back()]; tmp2[1]=coords[2*(*node)+1]-coords[2*tmpOut.back()+1]; - double angleM=INTERP_KERNEL::EdgeArcCircle::GetAbsoluteAngle(tmp2,tmp1); - double res; - if(angleM<=angle0) - res=angle0-angleM; - else - res=angle0-angleM+2.*M_PI; - if(res tmp3(2*(sz-1)); - std::vector::iterator it=std::copy(nodalConnBg+1,nodalConnEnd,tmp3.begin()); - std::copy(nodalConnBg+1,nodalConnEnd,it); - if(std::search(tmp3.begin(),tmp3.end(),tmpOut.begin(),tmpOut.end())!=tmp3.end()) - { - nodalConnecOut->insertAtTheEnd(nodalConnBg,nodalConnEnd); - return false; - } - if(std::search(tmp3.rbegin(),tmp3.rend(),tmpOut.begin(),tmpOut.end())!=tmp3.rend()) - { - nodalConnecOut->insertAtTheEnd(nodalConnBg,nodalConnEnd); - return false; - } - else - { - nodalConnecOut->pushBackSilent((int)INTERP_KERNEL::NORM_POLYGON); - nodalConnecOut->insertAtTheEnd(tmpOut.begin(),tmpOut.end()); - return true; - } - } - else - throw INTERP_KERNEL::Exception("MEDCouplingUMesh::BuildConvexEnvelopOf2DCellJarvis : invalid 2D cell connectivity !"); - } - else - throw INTERP_KERNEL::Exception("MEDCouplingUMesh::BuildConvexEnvelopOf2DCellJarvis : invalid 2D cell connectivity !"); -} - -/*! - * This method works on an input pair (\b arr, \b arrIndx) where \b arr indexes is in \b arrIndx. - * This method will not impact the size of inout parameter \b arrIndx but the size of \b arr will be modified in case of suppression. - * - * \param [in] idsToRemoveBg begin of set of ids to remove in \b arr (included) - * \param [in] idsToRemoveEnd end of set of ids to remove in \b arr (excluded) - * \param [in,out] arr array in which the remove operation will be done. - * \param [in,out] arrIndx array in the remove operation will modify - * \param [in] offsetForRemoval (by default 0) offset so that for each i in [0,arrIndx->getNumberOfTuples()-1) removal process will be performed in the following range [arr+arrIndx[i]+offsetForRemoval,arr+arr[i+1]) - * \return true if \b arr and \b arrIndx have been modified, false if not. - */ -bool MEDCouplingUMesh::RemoveIdsFromIndexedArrays(const int *idsToRemoveBg, const int *idsToRemoveEnd, DataArrayInt *arr, DataArrayInt *arrIndx, int offsetForRemoval) -{ - if(!arrIndx || !arr) - throw INTERP_KERNEL::Exception("MEDCouplingUMesh::RemoveIdsFromIndexedArrays : some input arrays are empty !"); - if(offsetForRemoval<0) - throw INTERP_KERNEL::Exception("MEDCouplingUMesh::RemoveIdsFromIndexedArrays : offsetForRemoval should be >=0 !"); - std::set s(idsToRemoveBg,idsToRemoveEnd); - int nbOfGrps=arrIndx->getNumberOfTuples()-1; - int *arrIPtr=arrIndx->getPointer(); - *arrIPtr++=0; - int previousArrI=0; - const int *arrPtr=arr->getConstPointer(); - std::vector arrOut;//no utility to switch to DataArrayInt because copy always needed - for(int i=0;ioffsetForRemoval) - { - for(const int *work=arrPtr+previousArrI+offsetForRemoval;work!=arrPtr+*arrIPtr;work++) - { - if(s.find(*work)==s.end()) - arrOut.push_back(*work); - } - } - previousArrI=*arrIPtr; - *arrIPtr=(int)arrOut.size(); - } - if(arr->getNumberOfTuples()==(int)arrOut.size()) - return false; - arr->alloc((int)arrOut.size(),1); - std::copy(arrOut.begin(),arrOut.end(),arr->getPointer()); - return true; -} - -/*! - * This method works on a pair input (\b arrIn, \b arrIndxIn) where \b arrIn indexes is in \b arrIndxIn - * (\ref numbering-indirect). - * This method returns the result of the extraction ( specified by a set of ids in [\b idsOfSelectBg , \b idsOfSelectEnd ) ). - * The selection of extraction is done standardly in new2old format. - * This method returns indexed arrays (\ref numbering-indirect) using 2 arrays (arrOut,arrIndexOut). - * - * \param [in] idsOfSelectBg begin of set of ids of the input extraction (included) - * \param [in] idsOfSelectEnd end of set of ids of the input extraction (excluded) - * \param [in] arrIn arr origin array from which the extraction will be done. - * \param [in] arrIndxIn is the input index array allowing to walk into \b arrIn - * \param [out] arrOut the resulting array - * \param [out] arrIndexOut the index array of the resulting array \b arrOut - * \sa MEDCouplingUMesh::ExtractFromIndexedArrays2 - */ -void MEDCouplingUMesh::ExtractFromIndexedArrays(const int *idsOfSelectBg, const int *idsOfSelectEnd, const DataArrayInt *arrIn, const DataArrayInt *arrIndxIn, - DataArrayInt* &arrOut, DataArrayInt* &arrIndexOut) -{ - if(!arrIn || !arrIndxIn) - throw INTERP_KERNEL::Exception("MEDCouplingUMesh::ExtractFromIndexedArrays : input pointer is NULL !"); - arrIn->checkAllocated(); arrIndxIn->checkAllocated(); - if(arrIn->getNumberOfComponents()!=1 || arrIndxIn->getNumberOfComponents()!=1) - throw INTERP_KERNEL::Exception("MEDCouplingUMesh::ExtractFromIndexedArrays : input arrays must have exactly one component !"); - std::size_t sz=std::distance(idsOfSelectBg,idsOfSelectEnd); - const int *arrInPtr=arrIn->getConstPointer(); - const int *arrIndxPtr=arrIndxIn->getConstPointer(); - int nbOfGrps=arrIndxIn->getNumberOfTuples()-1; - if(nbOfGrps<0) - throw INTERP_KERNEL::Exception("MEDCouplingUMesh::ExtractFromIndexedArrays : The format of \"arrIndxIn\" is invalid ! Its nb of tuples should be >=1 !"); - int maxSizeOfArr=arrIn->getNumberOfTuples(); - MEDCouplingAutoRefCountObjectPtr arro=DataArrayInt::New(); - MEDCouplingAutoRefCountObjectPtr arrIo=DataArrayInt::New(); - arrIo->alloc((int)(sz+1),1); - const int *idsIt=idsOfSelectBg; - int *work=arrIo->getPointer(); - *work++=0; - int lgth=0; - for(std::size_t i=0;i=0 && *idsIt=work[-1]) - *work=lgth; - else - { - std::ostringstream oss; oss << "MEDCouplingUMesh::ExtractFromIndexedArrays : id located on pos #" << i << " value is " << *idsIt << " and at this pos arrIndxIn[" << *idsIt; - oss << "+1]-arrIndxIn[" << *idsIt << "] < 0 ! The input index array is bugged !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - } - arro->alloc(lgth,1); - work=arro->getPointer(); - idsIt=idsOfSelectBg; - for(std::size_t i=0;i=0 && arrIndxPtr[*idsIt+1]<=maxSizeOfArr) - work=std::copy(arrInPtr+arrIndxPtr[*idsIt],arrInPtr+arrIndxPtr[*idsIt+1],work); - else - { - std::ostringstream oss; oss << "MEDCouplingUMesh::ExtractFromIndexedArrays : id located on pos #" << i << " value is " << *idsIt << " arrIndx[" << *idsIt << "] must be >= 0 and arrIndx["; - oss << *idsIt << "+1] <= " << maxSizeOfArr << " (the size of arrIn)!"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - } - arrOut=arro.retn(); - arrIndexOut=arrIo.retn(); -} - -/*! - * This method works on a pair input (\b arrIn, \b arrIndxIn) where \b arrIn indexes is in \b arrIndxIn - * (\ref numbering-indirect). - * This method returns the result of the extraction ( specified by a set of ids with a slice given by \a idsOfSelectStart, \a idsOfSelectStop and \a idsOfSelectStep ). - * The selection of extraction is done standardly in new2old format. - * This method returns indexed arrays (\ref numbering-indirect) using 2 arrays (arrOut,arrIndexOut). - * - * \param [in] idsOfSelectStart begin of set of ids of the input extraction (included) - * \param [in] idsOfSelectStop end of set of ids of the input extraction (excluded) - * \param [in] idsOfSelectStep - * \param [in] arrIn arr origin array from which the extraction will be done. - * \param [in] arrIndxIn is the input index array allowing to walk into \b arrIn - * \param [out] arrOut the resulting array - * \param [out] arrIndexOut the index array of the resulting array \b arrOut - * \sa MEDCouplingUMesh::ExtractFromIndexedArrays - */ -void MEDCouplingUMesh::ExtractFromIndexedArrays2(int idsOfSelectStart, int idsOfSelectStop, int idsOfSelectStep, const DataArrayInt *arrIn, const DataArrayInt *arrIndxIn, - DataArrayInt* &arrOut, DataArrayInt* &arrIndexOut) -{ - if(!arrIn || !arrIndxIn) - throw INTERP_KERNEL::Exception("MEDCouplingUMesh::ExtractFromIndexedArrays2 : input pointer is NULL !"); - arrIn->checkAllocated(); arrIndxIn->checkAllocated(); - if(arrIn->getNumberOfComponents()!=1 || arrIndxIn->getNumberOfComponents()!=1) - throw INTERP_KERNEL::Exception("MEDCouplingUMesh::ExtractFromIndexedArrays2 : input arrays must have exactly one component !"); - int sz=DataArrayInt::GetNumberOfItemGivenBESRelative(idsOfSelectStart,idsOfSelectStop,idsOfSelectStep,"MEDCouplingUMesh::ExtractFromIndexedArrays2 : Input slice "); - const int *arrInPtr=arrIn->getConstPointer(); - const int *arrIndxPtr=arrIndxIn->getConstPointer(); - int nbOfGrps=arrIndxIn->getNumberOfTuples()-1; - if(nbOfGrps<0) - throw INTERP_KERNEL::Exception("MEDCouplingUMesh::ExtractFromIndexedArrays2 : The format of \"arrIndxIn\" is invalid ! Its nb of tuples should be >=1 !"); - int maxSizeOfArr=arrIn->getNumberOfTuples(); - MEDCouplingAutoRefCountObjectPtr arro=DataArrayInt::New(); - MEDCouplingAutoRefCountObjectPtr arrIo=DataArrayInt::New(); - arrIo->alloc((int)(sz+1),1); - int idsIt=idsOfSelectStart; - int *work=arrIo->getPointer(); - *work++=0; - int lgth=0; - for(int i=0;i=0 && idsIt=work[-1]) - *work=lgth; - else - { - std::ostringstream oss; oss << "MEDCouplingUMesh::ExtractFromIndexedArrays2 : id located on pos #" << i << " value is " << idsIt << " and at this pos arrIndxIn[" << idsIt; - oss << "+1]-arrIndxIn[" << idsIt << "] < 0 ! The input index array is bugged !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - } - arro->alloc(lgth,1); - work=arro->getPointer(); - idsIt=idsOfSelectStart; - for(int i=0;i=0 && arrIndxPtr[idsIt+1]<=maxSizeOfArr) - work=std::copy(arrInPtr+arrIndxPtr[idsIt],arrInPtr+arrIndxPtr[idsIt+1],work); - else - { - std::ostringstream oss; oss << "MEDCouplingUMesh::ExtractFromIndexedArrays2 : id located on pos #" << i << " value is " << idsIt << " arrIndx[" << idsIt << "] must be >= 0 and arrIndx["; - oss << idsIt << "+1] <= " << maxSizeOfArr << " (the size of arrIn)!"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - } - arrOut=arro.retn(); - arrIndexOut=arrIo.retn(); -} - -/*! - * This method works on an input pair (\b arrIn, \b arrIndxIn) where \b arrIn indexes is in \b arrIndxIn. - * This method builds an output pair (\b arrOut,\b arrIndexOut) that is a copy from \b arrIn for all cell ids \b not \b in [ \b idsOfSelectBg , \b idsOfSelectEnd ) and for - * cellIds \b in [ \b idsOfSelectBg , \b idsOfSelectEnd ) a copy coming from the corresponding values in input pair (\b srcArr, \b srcArrIndex). - * This method is an generalization of MEDCouplingUMesh::SetPartOfIndexedArraysSameIdx that performs the same thing but by without building explicitely a result output arrays. - * - * \param [in] idsOfSelectBg begin of set of ids of the input extraction (included) - * \param [in] idsOfSelectEnd end of set of ids of the input extraction (excluded) - * \param [in] arrIn arr origin array from which the extraction will be done. - * \param [in] arrIndxIn is the input index array allowing to walk into \b arrIn - * \param [in] srcArr input array that will be used as source of copy for ids in [ \b idsOfSelectBg, \b idsOfSelectEnd ) - * \param [in] srcArrIndex index array of \b srcArr - * \param [out] arrOut the resulting array - * \param [out] arrIndexOut the index array of the resulting array \b arrOut - * - * \sa MEDCouplingUMesh::SetPartOfIndexedArraysSameIdx - */ -void MEDCouplingUMesh::SetPartOfIndexedArrays(const int *idsOfSelectBg, const int *idsOfSelectEnd, const DataArrayInt *arrIn, const DataArrayInt *arrIndxIn, - const DataArrayInt *srcArr, const DataArrayInt *srcArrIndex, - DataArrayInt* &arrOut, DataArrayInt* &arrIndexOut) -{ - if(arrIn==0 || arrIndxIn==0 || srcArr==0 || srcArrIndex==0) - throw INTERP_KERNEL::Exception("MEDCouplingUMesh::SetPartOfIndexedArrays : presence of null pointer in input parameter !"); - MEDCouplingAutoRefCountObjectPtr arro=DataArrayInt::New(); - MEDCouplingAutoRefCountObjectPtr arrIo=DataArrayInt::New(); - int nbOfTuples=arrIndxIn->getNumberOfTuples()-1; - std::vector v(nbOfTuples,true); - int offset=0; - const int *arrIndxInPtr=arrIndxIn->getConstPointer(); - const int *srcArrIndexPtr=srcArrIndex->getConstPointer(); - for(const int *it=idsOfSelectBg;it!=idsOfSelectEnd;it++,srcArrIndexPtr++) - { - if(*it>=0 && *itgetConstPointer(); - arrIo->alloc(nbOfTuples+1,1); - arro->alloc(arrIn->getNumberOfTuples()+offset,1); - const int *arrInPtr=arrIn->getConstPointer(); - const int *srcArrPtr=srcArr->getConstPointer(); - int *arrIoPtr=arrIo->getPointer(); *arrIoPtr++=0; - int *arroPtr=arro->getPointer(); - for(int ii=0;iigetNumberOfTuples()-1; - const int *arrIndxInPtr=arrIndxIn->getConstPointer(); - const int *srcArrIndexPtr=srcArrIndex->getConstPointer(); - int *arrInOutPtr=arrInOut->getPointer(); - const int *srcArrPtr=srcArr->getConstPointer(); - for(const int *it=idsOfSelectBg;it!=idsOfSelectEnd;it++,srcArrIndexPtr++) - { - if(*it>=0 && *itgetNumberOfTuples()-1. - * - * \param [in] arrIn arr origin array from which the extraction will be done. - * \param [in] arrIndxIn is the input index array allowing to walk into \b arrIn - * \return a newly allocated DataArray that stores all ids fetched by the gradually spread process. - * \sa MEDCouplingUMesh::ComputeSpreadZoneGraduallyFromSeed, MEDCouplingUMesh::partitionBySpreadZone - */ -DataArrayInt *MEDCouplingUMesh::ComputeSpreadZoneGradually(const DataArrayInt *arrIn, const DataArrayInt *arrIndxIn) -{ - int seed=0,nbOfDepthPeelingPerformed=0; - return ComputeSpreadZoneGraduallyFromSeed(&seed,&seed+1,arrIn,arrIndxIn,-1,nbOfDepthPeelingPerformed); -} - -/*! - * This method works on a pair input (\b arrIn, \b arrIndxIn) where \b arr indexes is in \b arrIndxIn. - * This method expects that these two input arrays come from the output of MEDCouplingUMesh::computeNeighborsOfCells method. - * This method start from id 0 that will be contained in output DataArrayInt. It searches then all neighbors of id0 regarding arrIn[arrIndxIn[0]:arrIndxIn[0+1]]. - * Then it is repeated recursively until either all ids are fetched or no more ids are reachable step by step. - * A negative value in \b arrIn means that it is ignored. - * This method is useful to see if a mesh is contiguous regarding its connectivity. If it is not the case the size of returned array is different from arrIndxIn->getNumberOfTuples()-1. - * \param [in] seedBg the begin pointer (included) of an array containing the seed of the search zone - * \param [in] seedEnd the end pointer (not included) of an array containing the seed of the search zone - * \param [in] arrIn arr origin array from which the extraction will be done. - * \param [in] arrIndxIn is the input index array allowing to walk into \b arrIn - * \param [in] nbOfDepthPeeling the max number of peels requested in search. By default -1, that is to say, no limit. - * \param [out] nbOfDepthPeelingPerformed the number of peels effectively performed. May be different from \a nbOfDepthPeeling - * \return a newly allocated DataArray that stores all ids fetched by the gradually spread process. - * \sa MEDCouplingUMesh::partitionBySpreadZone - */ -DataArrayInt *MEDCouplingUMesh::ComputeSpreadZoneGraduallyFromSeed(const int *seedBg, const int *seedEnd, const DataArrayInt *arrIn, const DataArrayInt *arrIndxIn, int nbOfDepthPeeling, int& nbOfDepthPeelingPerformed) -{ - nbOfDepthPeelingPerformed=0; - if(!arrIndxIn) - throw INTERP_KERNEL::Exception("MEDCouplingUMesh::ComputeSpreadZoneGraduallyFromSeed : arrIndxIn input pointer is NULL !"); - int nbOfTuples=arrIndxIn->getNumberOfTuples()-1; - if(nbOfTuples<=0) - { - DataArrayInt *ret=DataArrayInt::New(); ret->alloc(0,1); - return ret; - } - // - std::vector fetched(nbOfTuples,false); - return ComputeSpreadZoneGraduallyFromSeedAlg(fetched,seedBg,seedEnd,arrIn,arrIndxIn,nbOfDepthPeeling,nbOfDepthPeelingPerformed); -} - -DataArrayInt *MEDCouplingUMesh::ComputeSpreadZoneGraduallyFromSeedAlg(std::vector& fetched, const int *seedBg, const int *seedEnd, const DataArrayInt *arrIn, const DataArrayInt *arrIndxIn, int nbOfDepthPeeling, int& nbOfDepthPeelingPerformed) -{ - nbOfDepthPeelingPerformed=0; - if(!seedBg || !seedEnd || !arrIn || !arrIndxIn) - throw INTERP_KERNEL::Exception("MEDCouplingUMesh::ComputeSpreadZoneGraduallyFromSeedAlg : some input pointer is NULL !"); - int nbOfTuples=arrIndxIn->getNumberOfTuples()-1; - std::vector fetched2(nbOfTuples,false); - int i=0; - for(const int *seedElt=seedBg;seedElt!=seedEnd;seedElt++,i++) - { - if(*seedElt>=0 && *seedEltgetConstPointer(); - const int *arrIndxPtr=arrIndxIn->getConstPointer(); - int targetNbOfDepthPeeling=nbOfDepthPeeling!=-1?nbOfDepthPeeling:std::numeric_limits::max(); - std::vector idsToFetch1(seedBg,seedEnd); - std::vector idsToFetch2; - std::vector *idsToFetch=&idsToFetch1; - std::vector *idsToFetchOther=&idsToFetch2; - while(!idsToFetch->empty() && nbOfDepthPeelingPerformed::const_iterator it=idsToFetch->begin();it!=idsToFetch->end();it++) - for(const int *it2=arrInPtr+arrIndxPtr[*it];it2!=arrInPtr+arrIndxPtr[*it+1];it2++) - if(!fetched[*it2]) - { fetched[*it2]=true; fetched2[*it2]=true; idsToFetchOther->push_back(*it2); } - std::swap(idsToFetch,idsToFetchOther); - idsToFetchOther->clear(); - nbOfDepthPeelingPerformed++; - } - int lgth=(int)std::count(fetched2.begin(),fetched2.end(),true); - i=0; - MEDCouplingAutoRefCountObjectPtr ret=DataArrayInt::New(); ret->alloc(lgth,1); - int *retPtr=ret->getPointer(); - for(std::vector::const_iterator it=fetched2.begin();it!=fetched2.end();it++,i++) - if(*it) - *retPtr++=i; - return ret.retn(); -} - -/*! - * This method works on an input pair (\b arrIn, \b arrIndxIn) where \b arrIn indexes is in \b arrIndxIn. - * This method builds an output pair (\b arrOut,\b arrIndexOut) that is a copy from \b arrIn for all cell ids \b not \b in [ \b idsOfSelectBg , \b idsOfSelectEnd ) and for - * cellIds \b in [\b idsOfSelectBg, \b idsOfSelectEnd) a copy coming from the corresponding values in input pair (\b srcArr, \b srcArrIndex). - * This method is an generalization of MEDCouplingUMesh::SetPartOfIndexedArraysSameIdx that performs the same thing but by without building explicitely a result output arrays. - * - * \param [in] start begin of set of ids of the input extraction (included) - * \param [in] end end of set of ids of the input extraction (excluded) - * \param [in] step step of the set of ids in range mode. - * \param [in] arrIn arr origin array from which the extraction will be done. - * \param [in] arrIndxIn is the input index array allowing to walk into \b arrIn - * \param [in] srcArr input array that will be used as source of copy for ids in [\b idsOfSelectBg, \b idsOfSelectEnd) - * \param [in] srcArrIndex index array of \b srcArr - * \param [out] arrOut the resulting array - * \param [out] arrIndexOut the index array of the resulting array \b arrOut - * - * \sa MEDCouplingUMesh::SetPartOfIndexedArraysSameIdx MEDCouplingUMesh::SetPartOfIndexedArrays - */ -void MEDCouplingUMesh::SetPartOfIndexedArrays2(int start, int end, int step, const DataArrayInt *arrIn, const DataArrayInt *arrIndxIn, - const DataArrayInt *srcArr, const DataArrayInt *srcArrIndex, - DataArrayInt* &arrOut, DataArrayInt* &arrIndexOut) -{ - if(arrIn==0 || arrIndxIn==0 || srcArr==0 || srcArrIndex==0) - throw INTERP_KERNEL::Exception("MEDCouplingUMesh::SetPartOfIndexedArrays2 : presence of null pointer in input parameter !"); - MEDCouplingAutoRefCountObjectPtr arro=DataArrayInt::New(); - MEDCouplingAutoRefCountObjectPtr arrIo=DataArrayInt::New(); - int nbOfTuples=arrIndxIn->getNumberOfTuples()-1; - int offset=0; - const int *arrIndxInPtr=arrIndxIn->getConstPointer(); - const int *srcArrIndexPtr=srcArrIndex->getConstPointer(); - int nbOfElemsToSet=DataArray::GetNumberOfItemGivenBESRelative(start,end,step,"MEDCouplingUMesh::SetPartOfIndexedArrays2 : "); - int it=start; - for(int i=0;i=0 && itgetConstPointer(); - arrIo->alloc(nbOfTuples+1,1); - arro->alloc(arrIn->getNumberOfTuples()+offset,1); - const int *arrInPtr=arrIn->getConstPointer(); - const int *srcArrPtr=srcArr->getConstPointer(); - int *arrIoPtr=arrIo->getPointer(); *arrIoPtr++=0; - int *arroPtr=arro->getPointer(); - for(int ii=0;iigetNumberOfTuples()-1; - const int *arrIndxInPtr=arrIndxIn->getConstPointer(); - const int *srcArrIndexPtr=srcArrIndex->getConstPointer(); - int *arrInOutPtr=arrInOut->getPointer(); - const int *srcArrPtr=srcArr->getConstPointer(); - int nbOfElemsToSet=DataArray::GetNumberOfItemGivenBESRelative(start,end,step,"MEDCouplingUMesh::SetPartOfIndexedArraysSameIdx2 : "); - int it=start; - for(int i=0;i=0 && it partition=partitionBySpreadZone(); - std::vector< MEDCouplingAutoRefCountObjectPtr > partitionAuto; partitionAuto.reserve(partition.size()); - std::copy(partition.begin(),partition.end(),std::back_insert_iterator > >(partitionAuto)); - MEDCouplingAutoRefCountObjectPtr ret=MEDCouplingUMesh::New(getName(),mdim); - ret->setCoords(getCoords()); - ret->allocateCells((int)partition.size()); - // - for(std::vector::const_iterator it=partition.begin();it!=partition.end();it++) - { - MEDCouplingAutoRefCountObjectPtr tmp=static_cast(buildPartOfMySelf((*it)->begin(),(*it)->end(),true)); - MEDCouplingAutoRefCountObjectPtr cell; - switch(mdim) - { - case 2: - cell=tmp->buildUnionOf2DMesh(); - break; - case 3: - cell=tmp->buildUnionOf3DMesh(); - break; - default: - throw INTERP_KERNEL::Exception("MEDCouplingUMesh::buildSpreadZonesWithPoly : meshdimension supported are [2,3] ! Not implemented yet for others !"); - } - - ret->insertNextCell((INTERP_KERNEL::NormalizedCellType)cell->getIJSafe(0,0),cell->getNumberOfTuples()-1,cell->getConstPointer()+1); - } - // - ret->finishInsertingCells(); - return ret.retn(); -} - -/*! - * This method partitions \b this into contiguous zone. - * This method only needs a well defined connectivity. Coordinates are not considered here. - * This method returns a vector of \b newly allocated arrays that the caller has to deal with. - */ -std::vector MEDCouplingUMesh::partitionBySpreadZone() const -{ - int nbOfCellsCur=getNumberOfCells(); - std::vector ret; - if(nbOfCellsCur<=0) - return ret; - DataArrayInt *neigh=0,*neighI=0; - computeNeighborsOfCells(neigh,neighI); - MEDCouplingAutoRefCountObjectPtr neighAuto(neigh),neighIAuto(neighI); - std::vector fetchedCells(nbOfCellsCur,false); - std::vector< MEDCouplingAutoRefCountObjectPtr > ret2; - int seed=0; - while(seed >::iterator it=ret2.begin();it!=ret2.end();it++) - ret.push_back((*it).retn()); - return ret; -} - -/*! - * This method returns given a distribution of cell type (returned for example by MEDCouplingUMesh::getDistributionOfTypes method and customized after) a - * newly allocated DataArrayInt instance with 2 components ready to be interpreted as input of DataArrayInt::findRangeIdForEachTuple method. - * - * \param [in] code a code with the same format than those returned by MEDCouplingUMesh::getDistributionOfTypes except for the code[3*k+2] that should contain start id of chunck. - * \return a newly allocated DataArrayInt to be managed by the caller. - * \throw In case of \a code has not the right format (typically of size 3*n) - */ -DataArrayInt *MEDCouplingUMesh::ComputeRangesFromTypeDistribution(const std::vector& code) -{ - MEDCouplingAutoRefCountObjectPtr ret=DataArrayInt::New(); - std::size_t nb=code.size()/3; - if(code.size()%3!=0) - throw INTERP_KERNEL::Exception("MEDCouplingUMesh::ComputeRangesFromTypeDistribution : invalid input code !"); - ret->alloc((int)nb,2); - int *retPtr=ret->getPointer(); - for(std::size_t i=0;i 0, the coordinates array in returned mesh will have \a nbOfAdditionalPoints - * more tuples (nodes) than in \a this. Anyway, all the nodes in \a this (with the same order) will be in the returned mesh. - * - * \param [in] policy - the policy of splitting that must be in (PLANAR_FACE_5, PLANAR_FACE_6, GENERAL_24, GENERAL_48). The policy will be used only for INTERP_KERNEL::NORM_HEXA8 cells. - * For all other cells, the splitting policy will be ignored. See INTERP_KERNEL::SplittingPolicy for the images. - * \param [out] nbOfAdditionalPoints - number of nodes added to \c this->_coords. If > 0 a new coordinates object will be constructed result of the aggregation of the old one and the new points added. - * \param [out] n2oCells - A new instance of DataArrayInt holding, for each new cell, - * an id of old cell producing it. The caller is to delete this array using - * decrRef() as it is no more needed. - * \return MEDCoupling1SGTUMesh * - the mesh containing only INTERP_KERNEL::NORM_TETRA4 cells. - * - * \warning This method operates on each cells in this independantly ! So it can leads to non conform mesh in returned value ! If you expect to have a conform mesh in output - * the policy PLANAR_FACE_6 should be used on a mesh sorted with MEDCoupling1SGTUMesh::sortHexa8EachOther. - * - * \throw If \a this is not a 3D mesh (spaceDim==3 and meshDim==3). - * \throw If \a this is not fully constituted with linear 3D cells. - * \sa MEDCouplingUMesh::simplexize, MEDCoupling1SGTUMesh::sortHexa8EachOther - */ -MEDCoupling1SGTUMesh *MEDCouplingUMesh::tetrahedrize(int policy, DataArrayInt *& n2oCells, int& nbOfAdditionalPoints) const -{ - INTERP_KERNEL::SplittingPolicy pol((INTERP_KERNEL::SplittingPolicy)policy); - checkConnectivityFullyDefined(); - if(getMeshDimension()!=3 || getSpaceDimension()!=3) - throw INTERP_KERNEL::Exception("MEDCouplingUMesh::tetrahedrize : only available for mesh with meshdim == 3 and spacedim == 3 !"); - int nbOfCells(getNumberOfCells()),nbNodes(getNumberOfNodes()); - MEDCouplingAutoRefCountObjectPtr ret0(MEDCoupling1SGTUMesh::New(getName(),INTERP_KERNEL::NORM_TETRA4)); - MEDCouplingAutoRefCountObjectPtr ret(DataArrayInt::New()); ret->alloc(nbOfCells,1); - int *retPt(ret->getPointer()); - MEDCouplingAutoRefCountObjectPtr newConn(DataArrayInt::New()); newConn->alloc(0,1); - MEDCouplingAutoRefCountObjectPtr addPts(DataArrayDouble::New()); addPts->alloc(0,1); - const int *oldc(_nodal_connec->begin()); - const int *oldci(_nodal_connec_index->begin()); - const double *coords(_coords->begin()); - for(int i=0;i a; std::vector b; - INTERP_KERNEL::SplitIntoTetras(pol,(INTERP_KERNEL::NormalizedCellType)oldc[oldci[0]],oldc+oldci[0]+1,oldc+oldci[1],coords,a,b); - std::size_t nbOfTet(a.size()/4); *retPt=(int)nbOfTet; - const int *aa(&a[0]); - if(!b.empty()) - { - for(std::vector::iterator it=a.begin();it!=a.end();it++) - if(*it<0) - *it=(-(*(it))-1+nbNodes); - addPts->insertAtTheEnd(b.begin(),b.end()); - nbNodes+=(int)b.size()/3; - } - for(std::size_t j=0;jinsertAtTheEnd(aa,aa+4); - } - if(!addPts->empty()) - { - addPts->rearrange(3); - nbOfAdditionalPoints=addPts->getNumberOfTuples(); - addPts=DataArrayDouble::Aggregate(getCoords(),addPts); - ret0->setCoords(addPts); - } - else - { - nbOfAdditionalPoints=0; - ret0->setCoords(getCoords()); - } - ret0->setNodalConnectivity(newConn); - // - ret->computeOffsets2(); - n2oCells=ret->buildExplicitArrOfSliceOnScaledArr(0,nbOfCells,1); - return ret0.retn(); -} - -/*! - * It is the linear part of MEDCouplingUMesh::split2DCells. Here no additionnal nodes will be added in \b this. So coordinates pointer remain unchanged (is not even touch). - * - * \sa MEDCouplingUMesh::split2DCells - */ -void MEDCouplingUMesh::split2DCellsLinear(const DataArrayInt *desc, const DataArrayInt *descI, const DataArrayInt *subNodesInSeg, const DataArrayInt *subNodesInSegI) -{ - checkConnectivityFullyDefined(); - int ncells(getNumberOfCells()),lgthToReach(getMeshLength()+subNodesInSeg->getNumberOfTuples()); - MEDCouplingAutoRefCountObjectPtr c(DataArrayInt::New()); c->alloc((std::size_t)lgthToReach); - const int *subPtr(subNodesInSeg->begin()),*subIPtr(subNodesInSegI->begin()),*descPtr(desc->begin()),*descIPtr(descI->begin()),*oldConn(getNodalConnectivity()->begin()); - int *cPtr(c->getPointer()),*ciPtr(getNodalConnectivityIndex()->getPointer()); - int prevPosOfCi(ciPtr[0]); - for(int i=0;iend()!=cPtr) - throw INTERP_KERNEL::Exception("MEDCouplingUMesh::split2DCellsLinear : Some of edges to be split are orphan !"); - _nodal_connec->decrRef(); - _nodal_connec=c.retn(); _types.clear(); _types.insert(INTERP_KERNEL::NORM_POLYGON); -} - -int InternalAddPoint(const INTERP_KERNEL::Edge *e, int id, const double *coo, int startId, int endId, DataArrayDouble& addCoo, int& nodesCnter) -{ - if(id!=-1) - return id; - else - { - int ret(nodesCnter++); - double newPt[2]; - e->getMiddleOfPoints(coo+2*startId,coo+2*endId,newPt); - addCoo.insertAtTheEnd(newPt,newPt+2); - return ret; - } -} - -int InternalAddPointOriented(const INTERP_KERNEL::Edge *e, int id, const double *coo, int startId, int endId, DataArrayDouble& addCoo, int& nodesCnter) -{ - if(id!=-1) - return id; - else - { - int ret(nodesCnter++); - double newPt[2]; - e->getMiddleOfPointsOriented(coo+2*startId,coo+2*endId,newPt); - addCoo.insertAtTheEnd(newPt,newPt+2); - return ret; - } -} - - -/// @cond INTERNAL - -void EnterTheResultOf2DCellFirst(const INTERP_KERNEL::Edge *e, int start, int stp, int nbOfEdges, bool linOrArc, const double *coords, const int *connBg, int offset, DataArrayInt *newConnOfCell, DataArrayDouble *appendedCoords, std::vector& middles) -{ - int tmp[3]; - int trueStart(start>=0?start:nbOfEdges+start); - tmp[0]=linOrArc?(int)INTERP_KERNEL::NORM_QPOLYG:(int)INTERP_KERNEL::NORM_POLYGON; tmp[1]=connBg[trueStart]; tmp[2]=connBg[stp]; - newConnOfCell->insertAtTheEnd(tmp,tmp+3); - if(linOrArc) - { - if(stp-start>1) - { - int tmp2(0),tmp3(appendedCoords->getNumberOfTuples()/2); - InternalAddPointOriented(e,-1,coords,tmp[1],tmp[2],*appendedCoords,tmp2); - middles.push_back(tmp3+offset); - } - else - middles.push_back(connBg[trueStart+nbOfEdges]); - } -} - -void EnterTheResultOf2DCellMiddle(const INTERP_KERNEL::Edge *e, int start, int stp, int nbOfEdges, bool linOrArc, const double *coords, const int *connBg, int offset, DataArrayInt *newConnOfCell, DataArrayDouble *appendedCoords, std::vector& middles) -{ - int tmpSrt(newConnOfCell->back()),tmpEnd(connBg[stp]); - newConnOfCell->pushBackSilent(tmpEnd); - if(linOrArc) - { - if(stp-start>1) - { - int tmp2(0),tmp3(appendedCoords->getNumberOfTuples()/2); - InternalAddPointOriented(e,-1,coords,tmpSrt,tmpEnd,*appendedCoords,tmp2); - middles.push_back(tmp3+offset); - } - else - middles.push_back(connBg[start+nbOfEdges]); - } -} - -void EnterTheResultOf2DCellEnd(const INTERP_KERNEL::Edge *e, int start, int stp, int nbOfEdges, bool linOrArc, const double *coords, const int *connBg, int offset, DataArrayInt *newConnOfCell, DataArrayDouble *appendedCoords, std::vector& middles) -{ - // only the quadratic point to deal with: - if(linOrArc) - { - if(stp-start>1) - { - int tmpSrt(connBg[start]),tmpEnd(connBg[stp]); - int tmp2(0),tmp3(appendedCoords->getNumberOfTuples()/2); - InternalAddPointOriented(e,-1,coords,tmpSrt,tmpEnd,*appendedCoords,tmp2); - middles.push_back(tmp3+offset); - } - else - middles.push_back(connBg[start+nbOfEdges]); - } -} - -/// @endcond - -/*! - * Returns true if a colinearization has been found in the given cell. If false is returned the content pushed in \a newConnOfCell is equal to [ \a connBg , \a connEnd ) . - * \a appendedCoords is a DataArrayDouble instance with number of components equal to one (even if the items are pushed by pair). - */ -bool MEDCouplingUMesh::Colinearize2DCell(const double *coords, const int *connBg, const int *connEnd, int offset, DataArrayInt *newConnOfCell, DataArrayDouble *appendedCoords) -{ - std::size_t sz(std::distance(connBg,connEnd)); - if(sz<3)//3 because 2+1(for the cell type) and 2 is the minimal number of edges of 2D cell. - throw INTERP_KERNEL::Exception("MEDCouplingUMesh::Colinearize2DCell : the input cell has invalid format !"); - sz--; - INTERP_KERNEL::AutoPtr tmpConn(new int[sz]); - const INTERP_KERNEL::CellModel& cm(INTERP_KERNEL::CellModel::GetCellModel((INTERP_KERNEL::NormalizedCellType)connBg[0])); - unsigned nbs(cm.getNumberOfSons2(connBg+1,sz)); - unsigned nbOfHit(0); // number of fusions operated - int posBaseElt(0),posEndElt(0),nbOfTurn(0); - const unsigned int maxNbOfHit = cm.isQuadratic() ? nbs-2 : nbs-3; // a quad cell is authorized to end up with only two edges, a linear one has to keep 3 at least - INTERP_KERNEL::NormalizedCellType typeOfSon; - std::vector middles; - bool ret(false); - for(;(nbOfTurn+nbOfHit),int> m; - INTERP_KERNEL::Edge *e(MEDCouplingUMeshBuildQPFromEdge2(typeOfSon,tmpConn,coords,m)); - posEndElt = posBaseElt+1; - - // Look backward first: are the final edges of the cells colinear with the first ones? - // This initializes posBaseElt. - if(nbOfTurn==0) - { - for(unsigned i=1;iareColinears(); - if(isColinear) - { - nbOfHit++; - posBaseElt--; - ret=true; - } - delete eint; - eCand->decrRef(); - if(!isColinear) - break; - } - } - // Now move forward: - const unsigned fwdStart = (nbOfTurn == 0 ? 0 : posBaseElt); // the first element to be inspected going forward - for(unsigned j=fwdStart+1;jareColinears()); - if(isColinear) - { - nbOfHit++; - posEndElt++; - ret=true; - } - delete eint; - eCand->decrRef(); - if(!isColinear) - break; - } - //push [posBaseElt,posEndElt) in newConnOfCell using e - // The if clauses below are (volontary) not mutually exclusive: on a quad cell with 2 edges, the end of the connectivity is also its begining! - if(nbOfTurn==0) - // at the begining of the connectivity (insert type) - EnterTheResultOf2DCellFirst(e,posBaseElt,posEndElt,(int)nbs,cm.isQuadratic(),coords,connBg+1,offset,newConnOfCell,appendedCoords,middles); - else if((nbOfHit+nbOfTurn) != (nbs-1)) - // in the middle - EnterTheResultOf2DCellMiddle(e,posBaseElt,posEndElt,(int)nbs,cm.isQuadratic(),coords,connBg+1,offset,newConnOfCell,appendedCoords,middles); - if ((nbOfHit+nbOfTurn) == (nbs-1)) - // at the end (only quad points to deal with) - EnterTheResultOf2DCellEnd(e,posBaseElt,posEndElt,(int)nbs,cm.isQuadratic(),coords,connBg+1,offset,newConnOfCell,appendedCoords,middles); - posBaseElt=posEndElt; - e->decrRef(); - } - if(!middles.empty()) - newConnOfCell->insertAtTheEnd(middles.begin(),middles.end()); - return ret; -} - -/*! - * It is the quadratic part of MEDCouplingUMesh::split2DCells. Here some additionnal nodes can be added at the end of coordinates array object. - * - * \return int - the number of new nodes created. - * \sa MEDCouplingUMesh::split2DCells - */ -int MEDCouplingUMesh::split2DCellsQuadratic(const DataArrayInt *desc, const DataArrayInt *descI, const DataArrayInt *subNodesInSeg, const DataArrayInt *subNodesInSegI, const DataArrayInt *mid, const DataArrayInt *midI) -{ - checkCoherency(); - int ncells(getNumberOfCells()),lgthToReach(getMeshLength()+2*subNodesInSeg->getNumberOfTuples()),nodesCnt(getNumberOfNodes()); - MEDCouplingAutoRefCountObjectPtr c(DataArrayInt::New()); c->alloc((std::size_t)lgthToReach); - MEDCouplingAutoRefCountObjectPtr addCoo(DataArrayDouble::New()); addCoo->alloc(0,1); - const int *subPtr(subNodesInSeg->begin()),*subIPtr(subNodesInSegI->begin()),*descPtr(desc->begin()),*descIPtr(descI->begin()),*oldConn(getNodalConnectivity()->begin()); - const int *midPtr(mid->begin()),*midIPtr(midI->begin()); - const double *oldCoordsPtr(getCoords()->begin()); - int *cPtr(c->getPointer()),*ciPtr(getNodalConnectivityIndex()->getPointer()); - int prevPosOfCi(ciPtr[0]); - for(int i=0;i ns(3); - ns[0]=new INTERP_KERNEL::Node(oldCoordsPtr[2*oldConn[prevPosOfCi+1+j]],oldCoordsPtr[2*oldConn[prevPosOfCi+1+j]+1]); - ns[1]=new INTERP_KERNEL::Node(oldCoordsPtr[2*oldConn[prevPosOfCi+1+(1+j)%sz]],oldCoordsPtr[2*oldConn[prevPosOfCi+1+(1+j)%sz]+1]); - ns[2]=new INTERP_KERNEL::Node(oldCoordsPtr[2*oldConn[prevPosOfCi+1+sz+j]],oldCoordsPtr[2*oldConn[prevPosOfCi+1+sz+j]+1]); - MEDCouplingAutoRefCountObjectPtr e(INTERP_KERNEL::QuadraticPolygon::BuildArcCircleEdge(ns)); - for(int k=0;kend()!=cPtr) - throw INTERP_KERNEL::Exception("MEDCouplingUMesh::split2DCellsQuadratic : Some of edges to be split are orphan !"); - _nodal_connec->decrRef(); - _nodal_connec=c.retn(); _types.clear(); _types.insert(INTERP_KERNEL::NORM_QPOLYG); - addCoo->rearrange(2); - MEDCouplingAutoRefCountObjectPtr coo(DataArrayDouble::Aggregate(getCoords(),addCoo));//info are copied from getCoords() by using Aggregate - setCoords(coo); - return addCoo->getNumberOfTuples(); -} - -void MEDCouplingUMesh::ComputeAllTypesInternal(std::set& types, const DataArrayInt *nodalConnec, const DataArrayInt *nodalConnecIndex) -{ - if(nodalConnec && nodalConnecIndex) - { - types.clear(); - const int *conn(nodalConnec->getConstPointer()),*connIndex(nodalConnecIndex->getConstPointer()); - int nbOfElem(nodalConnecIndex->getNbOfElems()-1); - if(nbOfElem>0) - for(const int *pt=connIndex;pt!=connIndex+nbOfElem;pt++) - types.insert((INTERP_KERNEL::NormalizedCellType)conn[*pt]); - } -} - -MEDCouplingUMeshCellIterator::MEDCouplingUMeshCellIterator(MEDCouplingUMesh *mesh):_mesh(mesh),_cell(new MEDCouplingUMeshCell(mesh)), - _own_cell(true),_cell_id(-1),_nb_cell(0) -{ - if(mesh) - { - mesh->incrRef(); - _nb_cell=mesh->getNumberOfCells(); - } -} - -MEDCouplingUMeshCellIterator::~MEDCouplingUMeshCellIterator() -{ - if(_mesh) - _mesh->decrRef(); - if(_own_cell) - delete _cell; -} - -MEDCouplingUMeshCellIterator::MEDCouplingUMeshCellIterator(MEDCouplingUMesh *mesh, MEDCouplingUMeshCell *itc, int bg, int end):_mesh(mesh),_cell(itc), - _own_cell(false),_cell_id(bg-1), - _nb_cell(end) -{ - if(mesh) - mesh->incrRef(); -} - -MEDCouplingUMeshCell *MEDCouplingUMeshCellIterator::nextt() -{ - _cell_id++; - if(_cell_id<_nb_cell) - { - _cell->next(); - return _cell; - } - else - return 0; -} - -MEDCouplingUMeshCellByTypeEntry::MEDCouplingUMeshCellByTypeEntry(MEDCouplingUMesh *mesh):_mesh(mesh) -{ - if(_mesh) - _mesh->incrRef(); -} - -MEDCouplingUMeshCellByTypeIterator *MEDCouplingUMeshCellByTypeEntry::iterator() -{ - return new MEDCouplingUMeshCellByTypeIterator(_mesh); -} - -MEDCouplingUMeshCellByTypeEntry::~MEDCouplingUMeshCellByTypeEntry() -{ - if(_mesh) - _mesh->decrRef(); -} - -MEDCouplingUMeshCellEntry::MEDCouplingUMeshCellEntry(MEDCouplingUMesh *mesh, INTERP_KERNEL::NormalizedCellType type, MEDCouplingUMeshCell *itc, int bg, int end):_mesh(mesh),_type(type), - _itc(itc), - _bg(bg),_end(end) -{ - if(_mesh) - _mesh->incrRef(); -} - -MEDCouplingUMeshCellEntry::~MEDCouplingUMeshCellEntry() -{ - if(_mesh) - _mesh->decrRef(); -} - -INTERP_KERNEL::NormalizedCellType MEDCouplingUMeshCellEntry::getType() const -{ - return _type; -} - -int MEDCouplingUMeshCellEntry::getNumberOfElems() const -{ - return _end-_bg; -} - -MEDCouplingUMeshCellIterator *MEDCouplingUMeshCellEntry::iterator() -{ - return new MEDCouplingUMeshCellIterator(_mesh,_itc,_bg,_end); -} - -MEDCouplingUMeshCellByTypeIterator::MEDCouplingUMeshCellByTypeIterator(MEDCouplingUMesh *mesh):_mesh(mesh),_cell(new MEDCouplingUMeshCell(mesh)),_cell_id(0),_nb_cell(0) -{ - if(mesh) - { - mesh->incrRef(); - _nb_cell=mesh->getNumberOfCells(); - } -} - -MEDCouplingUMeshCellByTypeIterator::~MEDCouplingUMeshCellByTypeIterator() -{ - if(_mesh) - _mesh->decrRef(); - delete _cell; -} - -MEDCouplingUMeshCellEntry *MEDCouplingUMeshCellByTypeIterator::nextt() -{ - const int *c=_mesh->getNodalConnectivity()->getConstPointer(); - const int *ci=_mesh->getNodalConnectivityIndex()->getConstPointer(); - if(_cell_id<_nb_cell) - { - INTERP_KERNEL::NormalizedCellType type=(INTERP_KERNEL::NormalizedCellType)c[ci[_cell_id]]; - int nbOfElems=(int)std::distance(ci+_cell_id,std::find_if(ci+_cell_id,ci+_nb_cell,ParaMEDMEMImpl::ConnReader(c,type))); - int startId=_cell_id; - _cell_id+=nbOfElems; - return new MEDCouplingUMeshCellEntry(_mesh,type,_cell,startId,_cell_id); - } - else - return 0; -} - -MEDCouplingUMeshCell::MEDCouplingUMeshCell(MEDCouplingUMesh *mesh):_conn(0),_conn_indx(0),_conn_lgth(NOTICABLE_FIRST_VAL) -{ - if(mesh) - { - _conn=mesh->getNodalConnectivity()->getPointer(); - _conn_indx=mesh->getNodalConnectivityIndex()->getPointer(); - } -} - -void MEDCouplingUMeshCell::next() -{ - if(_conn_lgth!=NOTICABLE_FIRST_VAL) - { - _conn+=_conn_lgth; - _conn_indx++; - } - _conn_lgth=_conn_indx[1]-_conn_indx[0]; -} - -std::string MEDCouplingUMeshCell::repr() const -{ - if(_conn_lgth!=NOTICABLE_FIRST_VAL) - { - std::ostringstream oss; oss << "Cell Type " << INTERP_KERNEL::CellModel::GetCellModel((INTERP_KERNEL::NormalizedCellType)_conn[0]).getRepr(); - oss << " : "; - std::copy(_conn+1,_conn+_conn_lgth,std::ostream_iterator(oss," ")); - return oss.str(); - } - else - return std::string("MEDCouplingUMeshCell::repr : Invalid pos"); -} - -INTERP_KERNEL::NormalizedCellType MEDCouplingUMeshCell::getType() const -{ - if(_conn_lgth!=NOTICABLE_FIRST_VAL) - return (INTERP_KERNEL::NormalizedCellType)_conn[0]; - else - return INTERP_KERNEL::NORM_ERROR; -} - -const int *MEDCouplingUMeshCell::getAllConn(int& lgth) const -{ - lgth=_conn_lgth; - if(_conn_lgth!=NOTICABLE_FIRST_VAL) - return _conn; - else - return 0; -} diff --git a/src/MEDCoupling/MEDCouplingUMesh.hxx b/src/MEDCoupling/MEDCouplingUMesh.hxx deleted file mode 100644 index e3bb9c6d7..000000000 --- a/src/MEDCoupling/MEDCouplingUMesh.hxx +++ /dev/null @@ -1,428 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 -// 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_MEDCOUPLINGUMESH_HXX__ -#define __PARAMEDMEM_MEDCOUPLINGUMESH_HXX__ - -#include "MEDCoupling.hxx" -#include "MEDCouplingPointSet.hxx" -#include "MEDCouplingMemArray.hxx" - -#include "CellModel.hxx" - -#include - -namespace ParaMEDMEM -{ - class MEDCouplingUMeshCellByTypeEntry; - class MEDCouplingUMeshCellIterator; - class MEDCoupling1SGTUMesh; - class MEDCoupling1GTUMesh; - class MEDCouplingSkyLineArray; - - class MEDCouplingUMesh : public MEDCouplingPointSet - { - public: - MEDCOUPLING_EXPORT static MEDCouplingUMesh *New(); - MEDCOUPLING_EXPORT static MEDCouplingUMesh *New(const std::string& meshName, int meshDim); - MEDCOUPLING_EXPORT MEDCouplingMesh *deepCpy() const; - MEDCOUPLING_EXPORT MEDCouplingUMesh *clone(bool recDeepCpy) const; - MEDCOUPLING_EXPORT MEDCouplingPointSet *deepCpyConnectivityOnly() const; - MEDCOUPLING_EXPORT void shallowCopyConnectivityFrom(const MEDCouplingPointSet *other); - MEDCOUPLING_EXPORT void updateTime() const; - MEDCOUPLING_EXPORT std::size_t getHeapMemorySizeWithoutChildren() const; - MEDCOUPLING_EXPORT std::vector getDirectChildrenWithNull() const; - MEDCOUPLING_EXPORT MEDCouplingMeshType getType() const { return UNSTRUCTURED; } - MEDCOUPLING_EXPORT bool isEqualIfNotWhy(const MEDCouplingMesh *other, double prec, std::string& reason) const; - MEDCOUPLING_EXPORT bool isEqualWithoutConsideringStr(const MEDCouplingMesh *other, double prec) const; - MEDCOUPLING_EXPORT void checkFastEquivalWith(const MEDCouplingMesh *other, double prec) const; - MEDCOUPLING_EXPORT void checkCoherency() const; - MEDCOUPLING_EXPORT void checkCoherency1(double eps=1e-12) const; - MEDCOUPLING_EXPORT void checkCoherency2(double eps=1e-12) const; - MEDCOUPLING_EXPORT void setMeshDimension(int meshDim); - MEDCOUPLING_EXPORT void allocateCells(int nbOfCells=0); - MEDCOUPLING_EXPORT void insertNextCell(INTERP_KERNEL::NormalizedCellType type, int size, const int *nodalConnOfCell); - MEDCOUPLING_EXPORT void finishInsertingCells(); - MEDCOUPLING_EXPORT MEDCouplingUMeshCellIterator *cellIterator(); - MEDCOUPLING_EXPORT MEDCouplingUMeshCellByTypeEntry *cellsByType(); - MEDCOUPLING_EXPORT std::set getAllGeoTypes() const; - MEDCOUPLING_EXPORT std::vector getAllGeoTypesSorted() const; - MEDCOUPLING_EXPORT std::set getTypesOfPart(const int *begin, const int *end) const; - MEDCOUPLING_EXPORT void setConnectivity(DataArrayInt *conn, DataArrayInt *connIndex, bool isComputingTypes=true); - MEDCOUPLING_EXPORT const DataArrayInt *getNodalConnectivity() const { return _nodal_connec; } - MEDCOUPLING_EXPORT const DataArrayInt *getNodalConnectivityIndex() const { return _nodal_connec_index; } - MEDCOUPLING_EXPORT DataArrayInt *getNodalConnectivity() { return _nodal_connec; } - MEDCOUPLING_EXPORT DataArrayInt *getNodalConnectivityIndex() { return _nodal_connec_index; } - MEDCOUPLING_EXPORT INTERP_KERNEL::NormalizedCellType getTypeOfCell(int cellId) const; - MEDCOUPLING_EXPORT DataArrayInt *giveCellsWithType(INTERP_KERNEL::NormalizedCellType type) const; - MEDCOUPLING_EXPORT int getNumberOfCellsWithType(INTERP_KERNEL::NormalizedCellType type) const; - MEDCOUPLING_EXPORT void getNodeIdsOfCell(int cellId, std::vector& conn) const; - MEDCOUPLING_EXPORT std::string simpleRepr() const; - MEDCOUPLING_EXPORT std::string advancedRepr() const; - MEDCOUPLING_EXPORT std::string cppRepr() const; - MEDCOUPLING_EXPORT std::string reprConnectivityOfThis() const; - MEDCOUPLING_EXPORT MEDCouplingUMesh *buildSetInstanceFromThis(int spaceDim) const; - MEDCOUPLING_EXPORT int getNumberOfNodesInCell(int cellId) const; - MEDCOUPLING_EXPORT int getNumberOfCells() const; - MEDCOUPLING_EXPORT int getMeshDimension() const; - MEDCOUPLING_EXPORT int getMeshLength() const; - MEDCOUPLING_EXPORT void computeTypes(); - //! size of returned tinyInfo must be always the same. - MEDCOUPLING_EXPORT void getTinySerializationInformation(std::vector& tinyInfoD, std::vector& tinyInfo, std::vector& littleStrings) const; - MEDCOUPLING_EXPORT bool isEmptyMesh(const std::vector& tinyInfo) const; - MEDCOUPLING_EXPORT void resizeForUnserialization(const std::vector& tinyInfo, DataArrayInt *a1, DataArrayDouble *a2, std::vector& littleStrings) const; - MEDCOUPLING_EXPORT void serialize(DataArrayInt *&a1, DataArrayDouble *&a2) const; - MEDCOUPLING_EXPORT void unserialization(const std::vector& tinyInfoD, const std::vector& tinyInfo, const DataArrayInt *a1, DataArrayDouble *a2, const std::vector& littleStrings); - MEDCOUPLING_EXPORT std::string getVTKDataSetType() const; - MEDCOUPLING_EXPORT std::string getVTKFileExtension() const; - MEDCOUPLING_EXPORT void writeVTKLL(std::ostream& ofs, const std::string& cellData, const std::string& pointData, DataArrayByte *byteData) const; - MEDCOUPLING_EXPORT void reprQuickOverview(std::ostream& stream) const; - //tools - MEDCOUPLING_EXPORT static int AreCellsEqual(const int *conn, const int *connI, int cell1, int cell2, int compType); - MEDCOUPLING_EXPORT static int AreCellsEqual0(const int *conn, const int *connI, int cell1, int cell2); - MEDCOUPLING_EXPORT static int AreCellsEqual1(const int *conn, const int *connI, int cell1, int cell2); - MEDCOUPLING_EXPORT static int AreCellsEqual2(const int *conn, const int *connI, int cell1, int cell2); - MEDCOUPLING_EXPORT static int AreCellsEqual3(const int *conn, const int *connI, int cell1, int cell2); - MEDCOUPLING_EXPORT static int AreCellsEqual7(const int *conn, const int *connI, int cell1, int cell2); - MEDCOUPLING_EXPORT void convertToPolyTypes(const int *cellIdsToConvertBg, const int *cellIdsToConvertEnd); - MEDCOUPLING_EXPORT void convertAllToPoly(); - MEDCOUPLING_EXPORT void convertExtrudedPolyhedra(); - MEDCOUPLING_EXPORT bool unPolyze(); - MEDCOUPLING_EXPORT void simplifyPolyhedra(double eps); - MEDCOUPLING_EXPORT MEDCouplingUMesh *buildSpreadZonesWithPoly() const; - MEDCOUPLING_EXPORT std::vector partitionBySpreadZone() const; - MEDCOUPLING_EXPORT DataArrayInt *computeFetchedNodeIds() const; - MEDCOUPLING_EXPORT DataArrayInt *getNodeIdsInUse(int& nbrOfNodesInUse) const; - MEDCOUPLING_EXPORT void computeNodeIdsAlg(std::vector& nodeIdsInUse) const; - MEDCOUPLING_EXPORT DataArrayInt *computeNbOfNodesPerCell() const; - MEDCOUPLING_EXPORT DataArrayInt *computeNbOfFacesPerCell() const; - MEDCOUPLING_EXPORT DataArrayInt *computeEffectiveNbOfNodesPerCell() const; - MEDCOUPLING_EXPORT DataArrayInt *zipCoordsTraducer(); - MEDCOUPLING_EXPORT void findCommonCells(int compType, int startCellId, DataArrayInt *& commonCellsArr, DataArrayInt *& commonCellsIArr) const; - MEDCOUPLING_EXPORT bool areCellsIncludedIn(const MEDCouplingUMesh *other, int compType, DataArrayInt *& arr) const; - MEDCOUPLING_EXPORT bool areCellsIncludedIn2(const MEDCouplingUMesh *other, DataArrayInt *& arr) const; - MEDCOUPLING_EXPORT void getReverseNodalConnectivity(DataArrayInt *revNodal, DataArrayInt *revNodalIndx) const; - MEDCOUPLING_EXPORT MEDCouplingUMesh *explode3DMeshTo1D(DataArrayInt *desc, DataArrayInt *descIndx, DataArrayInt *revDesc, DataArrayInt *revDescIndx) const; - MEDCOUPLING_EXPORT MEDCouplingUMesh *buildDescendingConnectivity(DataArrayInt *desc, DataArrayInt *descIndx, DataArrayInt *revDesc, DataArrayInt *revDescIndx) const; - MEDCOUPLING_EXPORT MEDCouplingUMesh *buildDescendingConnectivity2(DataArrayInt *desc, DataArrayInt *descIndx, DataArrayInt *revDesc, DataArrayInt *revDescIndx) const; - MEDCOUPLING_EXPORT void computeNeighborsOfCells(DataArrayInt *&neighbors, DataArrayInt *&neighborsIdx) const; - MEDCOUPLING_EXPORT static void ComputeNeighborsOfCellsAdv(const DataArrayInt *desc, const DataArrayInt *descI, const DataArrayInt *revDesc, const DataArrayInt *revDescI, - DataArrayInt *&neighbors, DataArrayInt *&neighborsIdx); - MEDCOUPLING_EXPORT void computeNeighborsOfNodes(DataArrayInt *&neighbors, DataArrayInt *&neighborsIdx) const; - MEDCOUPLING_EXPORT MEDCouplingPointSet *mergeMyselfWithOnSameCoords(const MEDCouplingPointSet *other) const; - MEDCOUPLING_EXPORT MEDCouplingPointSet *buildPartOfMySelf(const int *begin, const int *end, bool keepCoords=true) const; - MEDCOUPLING_EXPORT MEDCouplingPointSet *buildPartOfMySelf2(int start, int end, int step, bool keepCoords=true) const; - MEDCOUPLING_EXPORT void setPartOfMySelf(const int *cellIdsBg, const int *cellIdsEnd, const MEDCouplingUMesh& otherOnSameCoordsThanThis); - MEDCOUPLING_EXPORT void setPartOfMySelf2(int start, int end, int step, const MEDCouplingUMesh& otherOnSameCoordsThanThis); - MEDCOUPLING_EXPORT MEDCouplingPointSet *buildFacePartOfMySelfNode(const int *begin, const int *end, bool fullyIn) const; - MEDCOUPLING_EXPORT MEDCouplingUMesh *buildUnstructured() const; - MEDCOUPLING_EXPORT DataArrayInt *findBoundaryNodes() const; - MEDCOUPLING_EXPORT MEDCouplingPointSet *buildBoundaryMesh(bool keepCoords) const; - MEDCOUPLING_EXPORT DataArrayInt *findCellIdsOnBoundary() const; - MEDCOUPLING_EXPORT void findCellIdsLyingOn(const MEDCouplingUMesh& otherDimM1OnSameCoords, DataArrayInt *&cellIdsRk0, DataArrayInt *&cellIdsRk1) const; - MEDCOUPLING_EXPORT MEDCouplingUMesh *computeSkin() const; - MEDCOUPLING_EXPORT void findNodesToDuplicate(const MEDCouplingUMesh& otherDimM1OnSameCoords, DataArrayInt *& nodeIdsToDuplicate, - DataArrayInt *& cellIdsNeededToBeRenum, DataArrayInt *& cellIdsNotModified) const; - MEDCOUPLING_EXPORT void duplicateNodes(const int *nodeIdsToDuplicateBg, const int *nodeIdsToDuplicateEnd); - MEDCOUPLING_EXPORT void renumberNodesWithOffsetInConn(int offset); - MEDCOUPLING_EXPORT void renumberNodesInConn(const INTERP_KERNEL::HashMap& newNodeNumbersO2N); - MEDCOUPLING_EXPORT void renumberNodesInConn(const int *newNodeNumbersO2N); - MEDCOUPLING_EXPORT void shiftNodeNumbersInConn(int delta); - MEDCOUPLING_EXPORT void duplicateNodesInConn(const int *nodeIdsToDuplicateBg, const int *nodeIdsToDuplicateEnd, int offset); - MEDCOUPLING_EXPORT void renumberCells(const int *old2NewBg, bool check=true); - MEDCOUPLING_EXPORT DataArrayInt *getCellsInBoundingBox(const double *bbox, double eps) const; - MEDCOUPLING_EXPORT DataArrayInt *getCellsInBoundingBox(const INTERP_KERNEL::DirectedBoundingBox& bbox, double eps); - MEDCOUPLING_EXPORT MEDCouplingFieldDouble *getMeasureField(bool isAbs) const; - MEDCOUPLING_EXPORT DataArrayDouble *getPartMeasureField(bool isAbs, const int *begin, const int *end) const; - MEDCOUPLING_EXPORT MEDCouplingFieldDouble *getMeasureFieldOnNode(bool isAbs) const; - MEDCOUPLING_EXPORT MEDCouplingFieldDouble *buildOrthogonalField() const; - MEDCOUPLING_EXPORT MEDCouplingFieldDouble *buildPartOrthogonalField(const int *begin, const int *end) const; - MEDCOUPLING_EXPORT MEDCouplingFieldDouble *buildDirectionVectorField() const; - MEDCOUPLING_EXPORT MEDCouplingUMesh *buildSlice3D(const double *origin, const double *vec, double eps, DataArrayInt *&cellIds) const; - MEDCOUPLING_EXPORT MEDCouplingUMesh *buildSlice3DSurf(const double *origin, const double *vec, double eps, DataArrayInt *&cellIds) const; - MEDCOUPLING_EXPORT DataArrayInt *getCellIdsCrossingPlane(const double *origin, const double *vec, double eps) const; - MEDCOUPLING_EXPORT bool isContiguous1D() const; - MEDCOUPLING_EXPORT void project1D(const double *pt, const double *v, double eps, double *res) const; - MEDCOUPLING_EXPORT double distanceToPoint(const double *ptBg, const double *ptEnd, int& cellId) const; - MEDCOUPLING_EXPORT DataArrayDouble *distanceToPoints(const DataArrayDouble *pts, DataArrayInt *& cellIds) const; - MEDCOUPLING_EXPORT int getCellContainingPoint(const double *pos, double eps) const; - MEDCOUPLING_EXPORT void getCellsContainingPoint(const double *pos, double eps, std::vector& elts) const; - MEDCOUPLING_EXPORT void getCellsContainingPoints(const double *pos, int nbOfPoints, double eps, MEDCouplingAutoRefCountObjectPtr& elts, MEDCouplingAutoRefCountObjectPtr& eltsIndex) const; - MEDCOUPLING_EXPORT void checkButterflyCells(std::vector& cells, double eps=1e-12) const; - MEDCOUPLING_EXPORT DataArrayInt *convexEnvelop2D(); - MEDCOUPLING_EXPORT DataArrayInt *findAndCorrectBadOriented3DExtrudedCells(); - MEDCOUPLING_EXPORT DataArrayInt *findAndCorrectBadOriented3DCells(); - MEDCOUPLING_EXPORT DataArrayDouble *getBoundingBoxForBBTree(double arcDetEps=1e-12) const; - MEDCOUPLING_EXPORT DataArrayDouble *getBoundingBoxForBBTreeFast() const; - MEDCOUPLING_EXPORT DataArrayDouble *getBoundingBoxForBBTree2DQuadratic(double arcDetEps=1e-12) const; - MEDCOUPLING_EXPORT DataArrayDouble *getBoundingBoxForBBTree1DQuadratic(double arcDetEps=1e-12) const; - MEDCOUPLING_EXPORT MEDCouplingUMesh *buildExtrudedMesh(const MEDCouplingUMesh *mesh1D, int policy); - MEDCOUPLING_EXPORT bool isFullyQuadratic() const; - MEDCOUPLING_EXPORT bool isPresenceOfQuadratic() const; - MEDCOUPLING_EXPORT void convertQuadraticCellsToLinear(); - MEDCOUPLING_EXPORT DataArrayInt *convertLinearCellsToQuadratic(int conversionType=0); - MEDCOUPLING_EXPORT void tessellate2D(double eps); - MEDCOUPLING_EXPORT void tessellate2DCurve(double eps); - MEDCOUPLING_EXPORT MEDCoupling1SGTUMesh *tetrahedrize(int policy, DataArrayInt *& n2oCells, int& nbOfAdditionalPoints) const; - MEDCOUPLING_EXPORT DataArrayInt *simplexize(int policy); - MEDCOUPLING_EXPORT bool areOnlySimplexCells() const; - MEDCOUPLING_EXPORT void convertDegeneratedCells(); - MEDCOUPLING_EXPORT void are2DCellsNotCorrectlyOriented(const double *vec, bool polyOnly, std::vector& cells) const; - MEDCOUPLING_EXPORT void orientCorrectly2DCells(const double *vec, bool polyOnly); - MEDCOUPLING_EXPORT void changeOrientationOfCells(); - MEDCOUPLING_EXPORT void arePolyhedronsNotCorrectlyOriented(std::vector& cells) const; - MEDCOUPLING_EXPORT void orientCorrectlyPolyhedrons(); - MEDCOUPLING_EXPORT void getFastAveragePlaneOfThis(double *vec, double *pos) const; - //Mesh quality - MEDCOUPLING_EXPORT MEDCouplingFieldDouble *getEdgeRatioField() const; - MEDCOUPLING_EXPORT MEDCouplingFieldDouble *getAspectRatioField() const; - MEDCOUPLING_EXPORT MEDCouplingFieldDouble *getWarpField() const; - MEDCOUPLING_EXPORT MEDCouplingFieldDouble *getSkewField() const; - MEDCOUPLING_EXPORT MEDCouplingFieldDouble *computeDiameterField() const; - //utilities for MED File RW - MEDCOUPLING_EXPORT std::vector getDistributionOfTypes() const; - MEDCOUPLING_EXPORT DataArrayInt *checkTypeConsistencyAndContig(const std::vector& code, const std::vector& idsPerType) const; - MEDCOUPLING_EXPORT void splitProfilePerType(const DataArrayInt *profile, std::vector& code, std::vector& idsInPflPerType, std::vector& idsPerType) const; - MEDCOUPLING_EXPORT MEDCouplingUMesh *emulateMEDMEMBDC(const MEDCouplingUMesh *nM1LevMesh, DataArrayInt *desc, DataArrayInt *descIndx, DataArrayInt *&revDesc, DataArrayInt *&revDescIndx, DataArrayInt *& nM1LevMeshIds, DataArrayInt *&meshnM1Old2New) const; - MEDCOUPLING_EXPORT DataArrayInt *sortCellsInMEDFileFrmt(); - MEDCOUPLING_EXPORT bool checkConsecutiveCellTypes() const; - MEDCOUPLING_EXPORT bool checkConsecutiveCellTypesForMEDFileFrmt() const; - MEDCOUPLING_EXPORT bool checkConsecutiveCellTypesAndOrder(const INTERP_KERNEL::NormalizedCellType *orderBg, const INTERP_KERNEL::NormalizedCellType *orderEnd) const; - MEDCOUPLING_EXPORT DataArrayInt *getLevArrPerCellTypes(const INTERP_KERNEL::NormalizedCellType *orderBg, const INTERP_KERNEL::NormalizedCellType *orderEnd, DataArrayInt *&nbPerType) const; - MEDCOUPLING_EXPORT DataArrayInt *getRenumArrForMEDFileFrmt() const; - MEDCOUPLING_EXPORT DataArrayInt *getRenumArrForConsecutiveCellTypesSpec(const INTERP_KERNEL::NormalizedCellType *orderBg, const INTERP_KERNEL::NormalizedCellType *orderEnd) const; - MEDCOUPLING_EXPORT DataArrayInt *rearrange2ConsecutiveCellTypes(); - MEDCOUPLING_EXPORT std::vector splitByType() const; - MEDCOUPLING_EXPORT MEDCoupling1GTUMesh *convertIntoSingleGeoTypeMesh() const; - MEDCOUPLING_EXPORT DataArrayInt *convertNodalConnectivityToStaticGeoTypeMesh() const; - MEDCOUPLING_EXPORT void convertNodalConnectivityToDynamicGeoTypeMesh(DataArrayInt *&nodalConn, DataArrayInt *&nodalConnIndex) const; - MEDCOUPLING_EXPORT static MEDCouplingUMesh *AggregateSortedByTypeMeshesOnSameCoords(const std::vector& ms, - DataArrayInt *&szOfCellGrpOfSameType, - DataArrayInt *&idInMsOfCellGrpOfSameType); - MEDCOUPLING_EXPORT DataArrayInt *keepCellIdsByType(INTERP_KERNEL::NormalizedCellType type, const int *begin, const int *end) const; - MEDCOUPLING_EXPORT DataArrayInt *convertCellArrayPerGeoType(const DataArrayInt *da) const; - MEDCOUPLING_EXPORT MEDCouplingUMesh *keepSpecifiedCells(INTERP_KERNEL::NormalizedCellType type, const int *idsPerGeoTypeBg, const int *idsPerGeoTypeEnd) const; - MEDCOUPLING_EXPORT std::vector getQuadraticStatus() const; - // - MEDCOUPLING_EXPORT MEDCouplingMesh *mergeMyselfWith(const MEDCouplingMesh *other) const; - MEDCOUPLING_EXPORT DataArrayDouble *getBarycenterAndOwner() const; - MEDCOUPLING_EXPORT DataArrayDouble *computeIsoBarycenterOfNodesPerCell() const; - MEDCOUPLING_EXPORT DataArrayDouble *getPartBarycenterAndOwner(const int *begin, const int *end) const; - MEDCOUPLING_EXPORT DataArrayDouble *computePlaneEquationOf3DFaces() const; - MEDCOUPLING_EXPORT DataArrayInt *conformize2D(double eps); - MEDCOUPLING_EXPORT DataArrayInt *colinearize2D(double eps); - MEDCOUPLING_EXPORT int split2DCells(const DataArrayInt *desc, const DataArrayInt *descI, const DataArrayInt *subNodesInSeg, const DataArrayInt *subNodesInSegI, const DataArrayInt *midOpt=0, const DataArrayInt *midOptI=0); - MEDCOUPLING_EXPORT static MEDCouplingUMesh *Build0DMeshFromCoords(DataArrayDouble *da); - MEDCOUPLING_EXPORT static MEDCouplingUMesh *MergeUMeshes(const MEDCouplingUMesh *mesh1, const MEDCouplingUMesh *mesh2); - MEDCOUPLING_EXPORT static MEDCouplingUMesh *MergeUMeshes(std::vector& a); - MEDCOUPLING_EXPORT static MEDCouplingUMesh *MergeUMeshesOnSameCoords(const MEDCouplingUMesh *mesh1, const MEDCouplingUMesh *mesh2); - MEDCOUPLING_EXPORT static MEDCouplingUMesh *MergeUMeshesOnSameCoords(const std::vector& meshes); - MEDCOUPLING_EXPORT static MEDCouplingUMesh *FuseUMeshesOnSameCoords(const std::vector& meshes, int compType, std::vector& corr); - MEDCOUPLING_EXPORT static void PutUMeshesOnSameAggregatedCoords(const std::vector& meshes); - MEDCOUPLING_EXPORT static void MergeNodesOnUMeshesSharingSameCoords(const std::vector& meshes, double eps); - MEDCOUPLING_EXPORT static bool IsPolygonWellOriented(bool isQuadratic, const double *vec, const int *begin, const int *end, const double *coords); - MEDCOUPLING_EXPORT static bool IsPolyhedronWellOriented(const int *begin, const int *end, const double *coords); - MEDCOUPLING_EXPORT static bool Is3DExtrudedStaticCellWellOriented(const int *begin, const int *end, const double *coords); - MEDCOUPLING_EXPORT static void CorrectExtrudedStaticCell(int *begin, int *end); - MEDCOUPLING_EXPORT static bool IsTetra4WellOriented(const int *begin, const int *end, const double *coords); - MEDCOUPLING_EXPORT static bool IsPyra5WellOriented(const int *begin, const int *end, const double *coords); - MEDCOUPLING_EXPORT static void SimplifyPolyhedronCell(double eps, const DataArrayDouble *coords, const int *begin, const int *end, DataArrayInt *res); - MEDCOUPLING_EXPORT static void ComputeVecAndPtOfFace(double eps, const double *coords, const int *begin, const int *end, double *v, double *p); - MEDCOUPLING_EXPORT static void TryToCorrectPolyhedronOrientation(int *begin, int *end, const double *coords); - MEDCOUPLING_EXPORT static MEDCouplingUMesh *Intersect2DMeshes(const MEDCouplingUMesh *m1, const MEDCouplingUMesh *m2, double eps, DataArrayInt *&cellNb1, DataArrayInt *&cellNb2); - MEDCOUPLING_EXPORT static void Intersect2DMeshWith1DLine(const MEDCouplingUMesh *mesh2D, const MEDCouplingUMesh *mesh1D, - double eps, MEDCouplingUMesh *&splitMesh2D, MEDCouplingUMesh *&splitMesh1D, DataArrayInt *&cellIdInMesh2D, DataArrayInt *&cellIdInMesh1D); - MEDCOUPLING_EXPORT static bool BuildConvexEnvelopOf2DCellJarvis(const double *coords, const int *nodalConnBg, const int *nodalConnEnd, DataArrayInt *nodalConnecOut); - MEDCOUPLING_EXPORT static bool RemoveIdsFromIndexedArrays(const int *idsToRemoveBg, const int *idsToRemoveEnd, DataArrayInt *arr, DataArrayInt *arrIndx, int offsetForRemoval=0); - MEDCOUPLING_EXPORT static void ExtractFromIndexedArrays(const int *idsOfSelectBg, const int *idsOfSelectEnd, const DataArrayInt *arrIn, const DataArrayInt *arrIndxIn, - DataArrayInt* &arrOut, DataArrayInt* &arrIndexOut); - MEDCOUPLING_EXPORT static void ExtractFromIndexedArrays2(int idsOfSelectStart, int idsOfSelectStop, int idsOfSelectStep, const DataArrayInt *arrIn, const DataArrayInt *arrIndxIn, - DataArrayInt* &arrOut, DataArrayInt* &arrIndexOut); - MEDCOUPLING_EXPORT static void SetPartOfIndexedArrays(const int *idsOfSelectBg, const int *idsOfSelectEnd, const DataArrayInt *arrIn, const DataArrayInt *arrIndxIn, - const DataArrayInt *srcArr, const DataArrayInt *srcArrIndex, - DataArrayInt* &arrOut, DataArrayInt* &arrIndexOut); - MEDCOUPLING_EXPORT static void SetPartOfIndexedArraysSameIdx(const int *idsOfSelectBg, const int *idsOfSelectEnd, DataArrayInt *arrInOut, const DataArrayInt *arrIndxIn, - const DataArrayInt *srcArr, const DataArrayInt *srcArrIndex); - MEDCOUPLING_EXPORT static void SetPartOfIndexedArrays2(int start, int end, int step, const DataArrayInt *arrIn, const DataArrayInt *arrIndxIn, - const DataArrayInt *srcArr, const DataArrayInt *srcArrIndex, - DataArrayInt* &arrOut, DataArrayInt* &arrIndexOut); - MEDCOUPLING_EXPORT static void SetPartOfIndexedArraysSameIdx2(int start, int end, int step, DataArrayInt *arrInOut, const DataArrayInt *arrIndxIn, - const DataArrayInt *srcArr, const DataArrayInt *srcArrIndex); - MEDCOUPLING_EXPORT static DataArrayInt *ComputeSpreadZoneGradually(const DataArrayInt *arrIn, const DataArrayInt *arrIndxIn); - MEDCOUPLING_EXPORT static DataArrayInt *ComputeSpreadZoneGraduallyFromSeed(const int *seedBg, const int *seedEnd, const DataArrayInt *arrIn, const DataArrayInt *arrIndxIn, int nbOfDepthPeeling, int& nbOfDepthPeelingPerformed); - MEDCOUPLING_EXPORT static void FindCommonCellsAlg(int compType, int startCellId, const DataArrayInt *nodal, const DataArrayInt *nodalI, const DataArrayInt *revNodal, const DataArrayInt *revNodalI, - DataArrayInt *& commonCellsArr, DataArrayInt *& commonCellsIArr); - MEDCOUPLING_EXPORT DataArrayInt *buildUnionOf2DMesh() const; - MEDCOUPLING_EXPORT DataArrayInt *buildUnionOf3DMesh() const; - MEDCOUPLING_EXPORT DataArrayInt *orderConsecutiveCells1D() const; - MEDCOUPLING_EXPORT MEDCouplingSkyLineArray *generateGraph() const; - private: - MEDCouplingUMesh(); - MEDCouplingUMesh(const MEDCouplingUMesh& other, bool deepCopy); - ~MEDCouplingUMesh(); - void checkFullyDefined() const; - void checkConnectivityFullyDefined() const; - void reprConnectivityOfThisLL(std::ostringstream& stream) const; - //tools - DataArrayInt *simplexizePol0(); - DataArrayInt *simplexizePol1(); - DataArrayInt *simplexizePlanarFace5(); - DataArrayInt *simplexizePlanarFace6(); - void subDivide2DMesh(const int *nodeSubdived, const int *nodeIndxSubdived, const int *desc, const int *descIndex); - void fillCellIdsToKeepFromNodeIds(const int *begin, const int *end, bool fullyIn, DataArrayInt *&cellIdsKeptArr) const; - void split3DCurveWithPlane(const double *origin, const double *vec, double eps, std::vector& cut3DCurve); - MEDCouplingUMesh *buildExtrudedMeshFromThisLowLev(int nbOfNodesOf1Lev, bool isQuad) const; - DataArrayDouble *fillExtCoordsUsingTranslation(const MEDCouplingUMesh *mesh1D, bool isQuad) const; - DataArrayDouble *fillExtCoordsUsingTranslAndAutoRotation(const MEDCouplingUMesh *mesh1D, bool isQuad) const; - DataArrayDouble *fillExtCoordsUsingTranslAndAutoRotation2D(const MEDCouplingUMesh *mesh1D, bool isQuad) const; - DataArrayDouble *fillExtCoordsUsingTranslAndAutoRotation3D(const MEDCouplingUMesh *mesh1D, bool isQuad) const; - static bool AreCellsEqualInPool(const std::vector& candidates, int compType, const int *conn, const int *connI, DataArrayInt *result) ; - MEDCouplingPointSet *buildPartOfMySelfKeepCoords(const int *begin, const int *end) const; - MEDCouplingPointSet *buildPartOfMySelfKeepCoords2(int start, int end, int step) const; - DataArrayInt *convertLinearCellsToQuadratic1D0(DataArrayInt *&conn, DataArrayInt *&connI, DataArrayDouble *& coords, std::set& types) const; - DataArrayInt *convertLinearCellsToQuadratic2DAnd3D0(const MEDCouplingUMesh *m1D, const DataArrayInt *desc, const DataArrayInt *descI, DataArrayInt *&conn, DataArrayInt *&connI, DataArrayDouble *& coords, std::set& types) const; - DataArrayInt *convertLinearCellsToQuadratic2D0(DataArrayInt *&conn, DataArrayInt *&connI, DataArrayDouble *& coords, std::set& types) const; - DataArrayInt *convertLinearCellsToQuadratic2D1(DataArrayInt *&conn, DataArrayInt *&connI, DataArrayDouble *& coords, std::set& types) const; - DataArrayInt *convertLinearCellsToQuadratic3D0(DataArrayInt *&conn, DataArrayInt *&connI, DataArrayDouble *& coords, std::set& types) const; - DataArrayInt *convertLinearCellsToQuadratic3D1(DataArrayInt *&conn, DataArrayInt *&connI, DataArrayDouble *& coords, std::set& types) const; - DataArrayInt *buildUnionOf2DMeshLinear(const MEDCouplingUMesh *skin, const DataArrayInt *n2o) const; - DataArrayInt *buildUnionOf2DMeshQuadratic(const MEDCouplingUMesh *skin, const DataArrayInt *n2o) const; - template - void getCellsContainingPointsAlg(const double *coords, const double *pos, int nbOfPoints, - double eps, MEDCouplingAutoRefCountObjectPtr& elts, MEDCouplingAutoRefCountObjectPtr& eltsIndex) const; -/// @cond INTERNAL - static MEDCouplingUMesh *MergeUMeshesLL(std::vector& a); - typedef int (*DimM1DescNbrer)(int id, unsigned nb, const INTERP_KERNEL::CellModel& cm, bool compute, const int *conn1, const int *conn2); - template - MEDCouplingUMesh *buildDescendingConnectivityGen(DataArrayInt *desc, DataArrayInt *descIndx, DataArrayInt *revDesc, DataArrayInt *revDescIndx, DimM1DescNbrer nbrer) const; - static void DistanceToPoint3DSurfAlg(const double *pt, const int *cellIdsBg, const int *cellIdsEnd, const double *coords, const int *nc, const int *ncI, double& ret0, int& cellId); - static void DistanceToPoint2DCurveAlg(const double *pt, const int *cellIdsBg, const int *cellIdsEnd, const double *coords, const int *nc, const int *ncI, double& ret0, int& cellId); - static DataArrayInt *ComputeSpreadZoneGraduallyFromSeedAlg(std::vector& fetched, const int *seedBg, const int *seedEnd, const DataArrayInt *arrIn, const DataArrayInt *arrIndxIn, int nbOfDepthPeeling, int& nbOfDepthPeelingPerformed); - static void FillInCompact3DMode(int spaceDim, int nbOfNodesInCell, const int *conn, const double *coo, double *zipFrmt); - static void AppendExtrudedCell(const int *connBg, const int *connEnd, int nbOfNodesPerLev, bool isQuad, std::vector& ret); - static void Intersect1DMeshes(const MEDCouplingUMesh *m1Desc, const MEDCouplingUMesh *m2Desc, double eps, std::vector< std::vector >& intersectEdge1, std::vector< std::vector >& colinear2, std::vector< std::vector >& subDiv2, std::vector& addCoo, std::map& mergedNodes); - static void 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, - std::vector& addCoo, - MEDCouplingUMesh *& m2Desc, DataArrayInt *&desc2, DataArrayInt *&descIndx2, DataArrayInt *&revDesc2, DataArrayInt *&revDescIndx2); - static void BuildIntersectEdges(const MEDCouplingUMesh *m1, const MEDCouplingUMesh *m2, const std::vector& addCoo, const std::vector< std::vector >& subDiv, std::vector< std::vector >& intersectEdge); - static void 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); - static void 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); - void assemblyForSplitFrom3DSurf(const std::vector< std::pair >& cut3DSurf, - const int *desc, const int *descIndx, DataArrayInt *nodalRes, DataArrayInt *nodalResIndx, DataArrayInt *cellIds) const; - void split2DCellsLinear(const DataArrayInt *desc, const DataArrayInt *descI, const DataArrayInt *subNodesInSeg, const DataArrayInt *subNodesInSegI); - int split2DCellsQuadratic(const DataArrayInt *desc, const DataArrayInt *descI, const DataArrayInt *subNodesInSeg, const DataArrayInt *subNodesInSegI, const DataArrayInt *mid, const DataArrayInt *midI); - static bool Colinearize2DCell(const double *coords, const int *connBg, const int *connEnd, int offset, DataArrayInt *newConnOfCell, DataArrayDouble *appendedCoords); - static void ComputeAllTypesInternal(std::set& types, const DataArrayInt *nodalConnec, const DataArrayInt *nodalConnecIndex); - public: - MEDCOUPLING_EXPORT static DataArrayInt *ComputeRangesFromTypeDistribution(const std::vector& code); - MEDCOUPLING_EXPORT static const int N_MEDMEM_ORDER=24; - MEDCOUPLING_EXPORT static const INTERP_KERNEL::NormalizedCellType MEDMEM_ORDER[N_MEDMEM_ORDER]; - /// @endcond - private: - int _mesh_dim; - DataArrayInt *_nodal_connec; - DataArrayInt *_nodal_connec_index; - std::set _types; - public: - static double EPS_FOR_POLYH_ORIENTATION; - }; - - class MEDCouplingUMeshCell; - - class MEDCouplingUMeshCellIterator - { - public: - MEDCOUPLING_EXPORT MEDCouplingUMeshCellIterator(MEDCouplingUMesh *mesh); - MEDCOUPLING_EXPORT MEDCouplingUMeshCellIterator(MEDCouplingUMesh *mesh, MEDCouplingUMeshCell *itc, int bg, int end); - MEDCOUPLING_EXPORT ~MEDCouplingUMeshCellIterator(); - MEDCOUPLING_EXPORT MEDCouplingUMeshCell *nextt(); - private: - MEDCouplingUMesh *_mesh; - MEDCouplingUMeshCell *_cell; - bool _own_cell; - int _cell_id; - int _nb_cell; - }; - - class MEDCouplingUMeshCellByTypeIterator; - - class MEDCouplingUMeshCellByTypeEntry - { - public: - MEDCOUPLING_EXPORT MEDCouplingUMeshCellByTypeEntry(MEDCouplingUMesh *mesh); - MEDCOUPLING_EXPORT MEDCouplingUMeshCellByTypeIterator *iterator(); - MEDCOUPLING_EXPORT ~MEDCouplingUMeshCellByTypeEntry(); - private: - MEDCouplingUMesh *_mesh; - }; - - class MEDCouplingUMeshCellEntry - { - public: - MEDCOUPLING_EXPORT MEDCouplingUMeshCellEntry(MEDCouplingUMesh *mesh, INTERP_KERNEL::NormalizedCellType type, MEDCouplingUMeshCell *itc, int bg, int end); - MEDCOUPLING_EXPORT ~MEDCouplingUMeshCellEntry(); - MEDCOUPLING_EXPORT INTERP_KERNEL::NormalizedCellType getType() const; - MEDCOUPLING_EXPORT int getNumberOfElems() const; - MEDCOUPLING_EXPORT MEDCouplingUMeshCellIterator *iterator(); - private: - MEDCouplingUMesh *_mesh; - INTERP_KERNEL::NormalizedCellType _type; - MEDCouplingUMeshCell *_itc; - int _bg; - int _end; - }; - - class MEDCouplingUMeshCellByTypeIterator - { - public: - MEDCOUPLING_EXPORT MEDCouplingUMeshCellByTypeIterator(MEDCouplingUMesh *mesh); - MEDCOUPLING_EXPORT ~MEDCouplingUMeshCellByTypeIterator(); - MEDCOUPLING_EXPORT MEDCouplingUMeshCellEntry *nextt(); - private: - MEDCouplingUMesh *_mesh; - MEDCouplingUMeshCell *_cell; - int _cell_id; - int _nb_cell; - }; - - class MEDCouplingUMeshCell - { - public: - MEDCOUPLING_EXPORT MEDCouplingUMeshCell(MEDCouplingUMesh *mesh); - MEDCOUPLING_EXPORT void next(); - MEDCOUPLING_EXPORT std::string repr() const; - MEDCOUPLING_EXPORT INTERP_KERNEL::NormalizedCellType getType() const; - MEDCOUPLING_EXPORT const int *getAllConn(int& lgth) const; - private: - int *_conn; - int *_conn_indx; - int _conn_lgth; - static const int NOTICABLE_FIRST_VAL=-7; - }; -} - -#endif diff --git a/src/MEDCoupling/Test/CMakeLists.txt b/src/MEDCoupling/Test/CMakeLists.txt deleted file mode 100644 index 429c4f85a..000000000 --- a/src/MEDCoupling/Test/CMakeLists.txt +++ /dev/null @@ -1,85 +0,0 @@ -# Copyright (C) 2012-2015 CEA/DEN, EDF 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, 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 -# 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) - -ADD_DEFINITIONS(${CPPUNIT_DEFINITIONS}) - -INCLUDE_DIRECTORIES( - ${CPPUNIT_INCLUDE_DIRS} - ${PTHREADS_INCLUDE_DIRS} - ${CMAKE_CURRENT_SOURCE_DIR}/.. - ${CMAKE_CURRENT_SOURCE_DIR}/../../INTERP_KERNEL - ${CMAKE_CURRENT_SOURCE_DIR}/../../INTERP_KERNEL/Bases - ${CMAKE_CURRENT_SOURCE_DIR}/../../INTERP_KERNEL/Geometric2D - ${CMAKE_CURRENT_SOURCE_DIR}/../../INTERP_KERNEL/ExprEval - ${CMAKE_CURRENT_SOURCE_DIR}/../../INTERP_KERNEL/GaussPoints - ${CMAKE_CURRENT_SOURCE_DIR}/../../INTERP_KERNELTest - ) - -SET(TestMEDCoupling_SOURCES - MEDCouplingBasicsTestInterp.cxx - TestMEDCoupling.cxx - MEDCouplingBasicsTest0.cxx - MEDCouplingBasicsTest1.cxx - MEDCouplingBasicsTest2.cxx - MEDCouplingBasicsTest3.cxx - MEDCouplingBasicsTest4.cxx - MEDCouplingBasicsTest5.cxx - ) - -SET(TestMEDCouplingRemapper_SOURCES - TestMEDCouplingRemapper.cxx - MEDCouplingRemapperTest.cxx - MEDCouplingBasicsTest0.cxx - ) - -SET(TestMEDCouplingExamples_SOURCES - MEDCouplingExamplesTest.cxx - MEDCouplingBasicsTest0.cxx - ) - -SALOME_GENERATE_TESTS_ENVIRONMENT(tests_env) - -ADD_EXECUTABLE(TestMEDCoupling ${TestMEDCoupling_SOURCES}) -TARGET_LINK_LIBRARIES(TestMEDCoupling medcoupling ${CPPUNIT_LIBRARIES} ${PLATFORM_LIBS}) -ADD_TEST(TestMEDCoupling TestMEDCoupling) -SET_TESTS_PROPERTIES(TestMEDCoupling PROPERTIES ENVIRONMENT "${tests_env}") - -ADD_EXECUTABLE(TestMEDCouplingRemapper ${TestMEDCouplingRemapper_SOURCES}) -TARGET_LINK_LIBRARIES(TestMEDCouplingRemapper medcouplingremapper ${CPPUNIT_LIBRARIES} ${PLATFORM_LIBS}) -ADD_TEST(TestMEDCouplingRemapper TestMEDCouplingRemapper) -SET_TESTS_PROPERTIES(TestMEDCouplingRemapper PROPERTIES ENVIRONMENT "${tests_env}") - -ADD_EXECUTABLE(TestMEDCouplingExamples ${TestMEDCouplingExamples_SOURCES}) -TARGET_LINK_LIBRARIES(TestMEDCouplingExamples medcoupling ${CPPUNIT_LIBRARIES} ${PLATFORM_LIBS}) -ADD_TEST(TestMEDCouplingExamples TestMEDCouplingExamples) -SET_TESTS_PROPERTIES(TestMEDCouplingExamples PROPERTIES ENVIRONMENT "${tests_env}") - -INSTALL(TARGETS TestMEDCoupling TestMEDCouplingRemapper TestMEDCouplingExamples DESTINATION ${SALOME_INSTALL_BINS}) - -SET_DIRECTORY_PROPERTIES(PROPERTIES ADDITIONAL_MAKE_CLEAN_FILES UnitTestsResult) - -# Application tests - -SET(TEST_INSTALL_DIRECTORY ${SALOME_INSTALL_SCRIPT_SCRIPTS}/test/MEDCoupling/MEDCoupling) -INSTALL(TARGETS TestMEDCoupling TestMEDCouplingRemapper TestMEDCouplingExamples DESTINATION ${TEST_INSTALL_DIRECTORY}) - -INSTALL(FILES CTestTestfileInstall.cmake - DESTINATION ${TEST_INSTALL_DIRECTORY} - RENAME CTestTestfile.cmake) diff --git a/src/MEDCoupling/Test/CTestTestfileInstall.cmake b/src/MEDCoupling/Test/CTestTestfileInstall.cmake deleted file mode 100644 index fa82537e4..000000000 --- a/src/MEDCoupling/Test/CTestTestfileInstall.cmake +++ /dev/null @@ -1,27 +0,0 @@ -# Copyright (C) 2015 CEA/DEN, EDF 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, 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 -# 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_TEST(TestMEDCoupling TestMEDCoupling) -SET_TESTS_PROPERTIES(TestMEDCoupling PROPERTIES LABELS "${COMPONENT_NAME}") - -ADD_TEST(TestMEDCouplingRemapper TestMEDCouplingRemapper) -SET_TESTS_PROPERTIES(TestMEDCouplingRemapper PROPERTIES LABELS "${COMPONENT_NAME}") - -ADD_TEST(TestMEDCouplingExamples TestMEDCouplingExamples) -SET_TESTS_PROPERTIES(TestMEDCouplingExamples PROPERTIES LABELS "${COMPONENT_NAME}") diff --git a/src/MEDCoupling/Test/MEDCouplingBasicsTest.hxx b/src/MEDCoupling/Test/MEDCouplingBasicsTest.hxx deleted file mode 100644 index be5313b08..000000000 --- a/src/MEDCoupling/Test/MEDCouplingBasicsTest.hxx +++ /dev/null @@ -1,113 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 -// 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 __MEDCOUPLINGBASICSTEST_HXX__ -#define __MEDCOUPLINGBASICSTEST_HXX__ - -#include - -#include -#include - -namespace ParaMEDMEM -{ - class DataArrayDouble; - class MEDCouplingUMesh; - class MEDCouplingFieldDouble; - class MEDCouplingMultiFields; - - class MEDCouplingBasicsTest : public CppUnit::TestFixture - { - public: - static MEDCouplingUMesh *build3DSourceMesh_2(); - static MEDCouplingUMesh *build3DTargetMesh_2(); - static MEDCouplingUMesh *build1DTargetMesh_1(); - static MEDCouplingUMesh *build2DSourceMesh_1(); - static MEDCouplingUMesh *build2DTargetMesh_1(); - static MEDCouplingUMesh *build2DTargetMeshPerm_1(); - static MEDCouplingUMesh *build2DTargetMesh_2(); - static MEDCouplingUMesh *buildCU1DMesh_U(); - static MEDCouplingUMesh *buildCU2DMesh_U(); - static MEDCouplingUMesh *buildCU3DMesh_U(); - static MEDCouplingUMesh *build3DSurfSourceMesh_1(); - static MEDCouplingUMesh *build3DSurfSourceMesh_2(); - static MEDCouplingUMesh *build3DSurfTargetMesh_1(); - static MEDCouplingUMesh *build3DSurfTargetMeshPerm_1(); - static MEDCouplingUMesh *build3DSurfTargetMesh_2(); - static MEDCouplingUMesh *build3DSourceMesh_1(); - static MEDCouplingUMesh *build3DTargetMesh_1(); - static MEDCouplingUMesh *build2DTargetMeshMergeNode_1(); - static MEDCouplingUMesh *build3DTargetMeshMergeNode_1(); - static MEDCouplingUMesh *build3DExtrudedUMesh_1(MEDCouplingUMesh *&mesh2D); - static void build3DExtrudedUMesh_2(MEDCouplingUMesh *&meshN, MEDCouplingUMesh *&meshTT, MEDCouplingUMesh *&meshTF); - static MEDCouplingUMesh *build2DTargetMeshMerged_1(); - static MEDCouplingUMesh *build2DCurveMesh(double dx, double dy); - static MEDCouplingUMesh *build1DMesh(double dx); - static MEDCouplingUMesh *build1DSourceMesh_2(); - static MEDCouplingUMesh *build1DTargetMesh_2(); - static MEDCouplingUMesh *build2DCurveSourceMesh_2(); - static MEDCouplingUMesh *build2DCurveTargetMesh_2(); - static MEDCouplingUMesh *build1DTargetMesh_3(); - static MEDCouplingUMesh *build2DCurveTargetMesh_3(); - static MEDCouplingUMesh *build2DTargetMesh_3(); - static MEDCouplingUMesh *build3DTargetMesh_3(); - static MEDCouplingUMesh *build2DTargetMesh_4(); - static MEDCouplingUMesh *build1DMultiTypes_1(); - static MEDCouplingUMesh *build2DMultiTypes_1(); - static MEDCouplingUMesh *build3DMultiTypes_1(); - static MEDCouplingUMesh *buildHexa8Mesh_1(); - static MEDCouplingUMesh *buildPointe_1(MEDCouplingUMesh *&m1); - - static MEDCouplingUMesh *build2D1DSourceMesh(); - static MEDCouplingUMesh *build2D1DTargetMesh(); - static MEDCouplingUMesh *build2D1DSegSourceMesh(const double shiftX = 0., - const double inclinationX = 0.); - static MEDCouplingUMesh *build2D1DQuadTargetMesh(const double inclinaisonX = 0.); - static MEDCouplingUMesh *build2D1DTriTargetMesh(const double inclinaisonX = 0.); - static MEDCouplingUMesh *build3D2DSourceMesh(); - static MEDCouplingUMesh *build3D2DTargetMesh(); - static MEDCouplingUMesh* build3D2DQuadSourceMesh(const double shiftX = 0., - const double inclinationX = 0.); - static MEDCouplingUMesh* build3D2DTriSourceMesh(const double shiftX = 0., - const double inclinationX = 0.); - static MEDCouplingUMesh* build3D2DTetraTargetMesh(const double inclinaisonX = 0.); - static MEDCouplingUMesh* build3D2DHexaTargetMesh(const double inclinaisonX = 0.); - - static DataArrayDouble *buildCoordsForMultiTypes_1(); - static MEDCouplingMultiFields *buildMultiFields_1(); - static std::vector buildMultiFields_2(); - static double sumAll(const std::vector< std::map >& matrix); - protected: - static int countNonZero(const std::vector< std::map >& matrix); - - static void test2D1DMeshesIntersection(MEDCouplingUMesh *sourceMesh, - MEDCouplingUMesh *targetMesh, - const double correctSurf, - const int correctDuplicateFacesNbr, - const int correctTotalIntersectFacesNbr = -1); - static void test3D2DMeshesIntersection(MEDCouplingUMesh *sourceMesh, - MEDCouplingUMesh *targetMesh, - const double correctSurf, - const int correctDuplicateFacesNbr, - const int correctTotalIntersectFacesNbr = -1); - }; -} - -#endif diff --git a/src/MEDCoupling/Test/MEDCouplingBasicsTest0.cxx b/src/MEDCoupling/Test/MEDCouplingBasicsTest0.cxx deleted file mode 100644 index f42235c44..000000000 --- a/src/MEDCoupling/Test/MEDCouplingBasicsTest0.cxx +++ /dev/null @@ -1,1716 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 -// 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 "MEDCouplingBasicsTest.hxx" -#include "MEDCouplingUMesh.hxx" -#include "MEDCouplingExtrudedMesh.hxx" -#include "MEDCouplingFieldDouble.hxx" -#include "MEDCouplingMemArray.hxx" -#include "MEDCouplingMultiFields.hxx" - -#include "MEDCouplingBasicsTestData1.hxx" - -#include "Interpolation2D.txx" -#include "Interpolation3D2D.txx" -#include "Interpolation2D1D.txx" -#include "MEDCouplingNormalizedUnstructuredMesh.txx" -#include "MEDCouplingNormalizedCartesianMesh.txx" - -using namespace ParaMEDMEM; - -typedef std::vector > IntersectionMatrix; - -MEDCouplingUMesh *MEDCouplingBasicsTest::build3DSourceMesh_2() -{ - double sourceCoords[84]={100.0, 100.0, 0.0, 100.0, 100.0, 100.0, 100.0, 0.0, 100.0, 100.0, 0.0, 0.0, 0.0, 100.0, 0.0, 0.0, 100.0, 100.0, 0.0, - 0.0, 100.0, 0.0, 0.0, 0.0, 100.0, 100.0, 200.0, 100.0, 0.0, 200.0, 0.0, 100.0, 200.0, 0.0, 0.0, 200.0, 100.0, 200.0, - 0.0, 100.0, 200.0, 100.0, 0.0, 200.0, 0.0, 0.0, 200.0, 100.0, 100.0, 200.0, 200.0, 0.0, 200.0, 200.0, 200.0, 100.0, - 0.0, 200.0, 100.00000000833332, 100.00000000833332, 200.0, 0.0, 100.0, 200.0, 0.0, 0.0, 200.0, 100.0, 200.0, 200.0, - 0.0, 200.0, 200.0, 200.0, 0.0, 200.0, 200.0, 100.0, 200.0, 200.0, 200.0, 149.999999970343, 149.9999999874621, 49.999999881628682}; - - - int sourceConn[212]={25, 27, 13, 19, 18, 3, 20, 21, 5, 10, 17, 1, 1, 3, 0, 7, 18, 1, 0, 27, 12, 27, 13, 24, 25, 19, 16, 26, 1, 2, 6, 8, 15, 13, - 12, 5, 24, 13, 25, 27, 10, 11, 9, 6, 19, 8, 23, 1, 22, 8, 23, 19, 16, 13, 17, 1, 6, 9, 10, 8, 13, 17, 5, 15, 5, 4, 1, 12, 18, - 0, 24, 27, 19, 20, 18, 1, 7, 6, 5, 1, 4, 12, 15, 14, 25, 27, 19, 18, 1, 19, 16, 13, 20, 19, 23, 1, 27, 12, 1, 0, 6, 5, 1, 10, - 4, 5, 1, 7, 12, 27, 1, 13, 5, 15, 4, 12, 19, 16, 26, 22, 13, 5, 17, 1, 1, 3, 7, 2, 13, 5, 1, 12, 18, 1, 3, 0, 8, 23, 2, 9, 3, - 1, 18, 20, 1, 27, 19, 13, 24, 25, 18, 27, 25, 16, 19, 13, 7, 1, 2, 6, 3, 1, 20, 2, 8, 16, 17, 1, 7, 4, 0, 1, 18, 19, 1, 27, - 27, 12, 0, 24, 9, 6, 2, 8, 1, 4, 0, 12, 19, 16, 22, 8, 8, 2, 23, 1, 1, 16, 19, 8, 20, 2, 1, 23, 10, 1, 6, 8, 10, 8, 17, 1}; - - MEDCouplingUMesh *sourceMesh=MEDCouplingUMesh::New(); - sourceMesh->setMeshDimension(3); - sourceMesh->allocateCells(53); - for(int i=0;i<53;i++) - sourceMesh->insertNextCell(INTERP_KERNEL::NORM_TETRA4,4,sourceConn+4*i); - sourceMesh->finishInsertingCells(); - DataArrayDouble *myCoords=DataArrayDouble::New(); - myCoords->alloc(28,3); - std::copy(sourceCoords,sourceCoords+84,myCoords->getPointer()); - sourceMesh->setCoords(myCoords); - myCoords->decrRef(); - return sourceMesh; -} - -MEDCouplingUMesh *MEDCouplingBasicsTest::build3DTargetMesh_2() -{ - double targetCoords[24]={200.0, 200.0, 0.0, 200.0, 200.0, 200.0, 200.0, 0.0, 0.0, 200.0, 0.0, 200.0, 0.0, 200.0, 0.0, 0.0, 200.0, 200.0, 0.0, 0.0, 0.0, 0.0, 0.0, 200.0}; - int targetConn[20]={5, 6, 3, 0, 1, 3, 0, 5, 3, 6, 5, 7, 6, 4, 0, 5, 6, 3, 0, 2}; - MEDCouplingUMesh *targetMesh=MEDCouplingUMesh::New(); - targetMesh->setMeshDimension(3); - targetMesh->allocateCells(5); - for(int i=0;i<5;i++) - targetMesh->insertNextCell(INTERP_KERNEL::NORM_TETRA4,4,targetConn+4*i); - targetMesh->finishInsertingCells(); - DataArrayDouble *myCoords=DataArrayDouble::New(); - myCoords->alloc(8,3); - std::copy(targetCoords,targetCoords+24,myCoords->getPointer()); - targetMesh->setCoords(myCoords); - myCoords->decrRef(); - return targetMesh; -} - -MEDCouplingUMesh *MEDCouplingBasicsTest::build1DTargetMesh_1() -{ - double targetCoords[36]={ - 25.,25.,0., 25.,25.,50., 25.,25.,200., 75.,25.,0., 75.,25.,50., 75.,25.,200., - 25.,125.,0., 25.,125.,50., 25.,125.,200., 125.,125.,0., 125.,125.,50., 125.,125.,200. - }; - int targetConn[16]={0,1, 1,2, 3,4, 4,5, 6,7, 7,8, 9,10, 10,11}; - - MEDCouplingUMesh *targetMesh=MEDCouplingUMesh::New("my name of mesh 1D",1); - targetMesh->allocateCells(8); - for(int i=0;i<8;i++) - targetMesh->insertNextCell(INTERP_KERNEL::NORM_SEG2,2,targetConn+2*i); - targetMesh->finishInsertingCells(); - DataArrayDouble *myCoords=DataArrayDouble::New(); - myCoords->alloc(12,3); - std::copy(targetCoords,targetCoords+36,myCoords->getPointer()); - targetMesh->setCoords(myCoords); - myCoords->decrRef(); - return targetMesh; -} - -MEDCouplingUMesh *MEDCouplingBasicsTest::build2DSourceMesh_1() -{ - double sourceCoords[8]={-0.3,-0.3, 0.7,-0.3, -0.3,0.7, 0.7,0.7}; - int sourceConn[6]={0,3,1,0,2,3}; - MEDCouplingUMesh *sourceMesh=MEDCouplingUMesh::New("my name of mesh 2D",2); - sourceMesh->allocateCells(2); - sourceMesh->insertNextCell(INTERP_KERNEL::NORM_TRI3,3,sourceConn); - sourceMesh->insertNextCell(INTERP_KERNEL::NORM_TRI3,3,sourceConn+3); - sourceMesh->finishInsertingCells(); - DataArrayDouble *myCoords=DataArrayDouble::New(); - myCoords->alloc(4,2); - std::copy(sourceCoords,sourceCoords+8,myCoords->getPointer()); - sourceMesh->setCoords(myCoords); - myCoords->decrRef(); - return sourceMesh; -} - -MEDCouplingUMesh *MEDCouplingBasicsTest::build2DTargetMesh_1() -{ - double targetCoords[18]={-0.3,-0.3, 0.2,-0.3, 0.7,-0.3, -0.3,0.2, 0.2,0.2, 0.7,0.2, -0.3,0.7, 0.2,0.7, 0.7,0.7 }; - int targetConn[18]={0,3,4,1, 1,4,2, 4,5,2, 6,7,4,3, 7,8,5,4}; - MEDCouplingUMesh *targetMesh=MEDCouplingUMesh::New(); - targetMesh->setMeshDimension(2); - targetMesh->allocateCells(5); - targetMesh->insertNextCell(INTERP_KERNEL::NORM_QUAD4,4,targetConn); - targetMesh->insertNextCell(INTERP_KERNEL::NORM_TRI3,3,targetConn+4); - targetMesh->insertNextCell(INTERP_KERNEL::NORM_TRI3,3,targetConn+7); - targetMesh->insertNextCell(INTERP_KERNEL::NORM_QUAD4,4,targetConn+10); - targetMesh->insertNextCell(INTERP_KERNEL::NORM_QUAD4,4,targetConn+14); - targetMesh->finishInsertingCells(); - DataArrayDouble *myCoords=DataArrayDouble::New(); - myCoords->alloc(9,2); - std::copy(targetCoords,targetCoords+18,myCoords->getPointer()); - targetMesh->setCoords(myCoords); - myCoords->decrRef(); - return targetMesh; -} - -MEDCouplingUMesh *MEDCouplingBasicsTest::build2DTargetMeshPerm_1() -{ - double targetCoords[18]={-0.3,-0.3, 0.2,-0.3, 0.7,-0.3, -0.3,0.2, 0.2,0.2, 0.7,0.2, -0.3,0.7, 0.2,0.7, 0.7,0.7 }; - int targetConn[18]={0,3,4,1, 1,2,4, 4,5,2, 6,7,4,3, 7,8,5,4}; - MEDCouplingUMesh *targetMesh=MEDCouplingUMesh::New(); - targetMesh->setMeshDimension(2); - targetMesh->allocateCells(5); - targetMesh->insertNextCell(INTERP_KERNEL::NORM_QUAD4,4,targetConn); - targetMesh->insertNextCell(INTERP_KERNEL::NORM_TRI3,3,targetConn+4); - targetMesh->insertNextCell(INTERP_KERNEL::NORM_TRI3,3,targetConn+7); - targetMesh->insertNextCell(INTERP_KERNEL::NORM_QUAD4,4,targetConn+10); - targetMesh->insertNextCell(INTERP_KERNEL::NORM_QUAD4,4,targetConn+14); - targetMesh->finishInsertingCells(); - DataArrayDouble *myCoords=DataArrayDouble::New(); - myCoords->alloc(9,2); - std::copy(targetCoords,targetCoords+18,myCoords->getPointer()); - targetMesh->setCoords(myCoords); - myCoords->decrRef(); - return targetMesh; -} - -MEDCouplingUMesh *MEDCouplingBasicsTest::build2DTargetMesh_2() -{ - double targetCoords[18]={-0.3,-0.3, 0.2,-0.3, 0.7,-0.3, -0.3,0.2, 0.2,0.2, 0.7,0.2, -0.3,0.7, 0.2,0.7, 0.7,0.7 }; - int targetConn[24]={0,3,4, 0,4,1, 1,4,2, 4,5,2, 3,6,4, 6,7,4, 4,7,5, 7,8,5 }; - MEDCouplingUMesh *targetMesh=MEDCouplingUMesh::New(); - targetMesh->setMeshDimension(2); - targetMesh->allocateCells(8); - targetMesh->insertNextCell(INTERP_KERNEL::NORM_TRI3,3,targetConn); - targetMesh->insertNextCell(INTERP_KERNEL::NORM_TRI3,3,targetConn+3); - targetMesh->insertNextCell(INTERP_KERNEL::NORM_TRI3,3,targetConn+6); - targetMesh->insertNextCell(INTERP_KERNEL::NORM_TRI3,3,targetConn+9); - targetMesh->insertNextCell(INTERP_KERNEL::NORM_TRI3,3,targetConn+12); - targetMesh->insertNextCell(INTERP_KERNEL::NORM_TRI3,3,targetConn+15); - targetMesh->insertNextCell(INTERP_KERNEL::NORM_TRI3,3,targetConn+18); - targetMesh->insertNextCell(INTERP_KERNEL::NORM_TRI3,3,targetConn+21); - targetMesh->finishInsertingCells(); - DataArrayDouble *myCoords=DataArrayDouble::New(); - myCoords->alloc(9,2); - std::copy(targetCoords,targetCoords+18,myCoords->getPointer()); - targetMesh->setCoords(myCoords); - myCoords->decrRef(); - return targetMesh; -} - -MEDCouplingUMesh *MEDCouplingBasicsTest::buildCU1DMesh_U() -{ - double coords[4]={ 0.0, 0.3, 0.75, 1.0 }; - int conn[2*3]={ 0,1, 1,2, 2,3 }; - MEDCouplingUMesh *mesh=MEDCouplingUMesh::New(); - mesh->setMeshDimension(1); - mesh->allocateCells(3); - mesh->insertNextCell(INTERP_KERNEL::NORM_SEG2,2,conn); - mesh->insertNextCell(INTERP_KERNEL::NORM_SEG2,2,conn+2); - mesh->insertNextCell(INTERP_KERNEL::NORM_SEG2,2,conn+4); - mesh->finishInsertingCells(); - DataArrayDouble *myCoords=DataArrayDouble::New(); - myCoords->alloc(4,1); - std::copy(coords,coords+4,myCoords->getPointer()); - mesh->setCoords(myCoords); - myCoords->decrRef(); - return mesh; -} -MEDCouplingUMesh *MEDCouplingBasicsTest::buildCU2DMesh_U() -{ - double coords[18]={0.0,0.0, 0.5,0.0, 1.0,0.0, 0.0,0.5, 0.5,0.5, 1.0,0.5, 0.0,1.0, 0.5,1.0, 1.0,1.0 }; - int conn[18]={0,1,4,3, 3,4,7,6, 4,5,8,7, 1,5,4, 1,2,5 }; - MEDCouplingUMesh *mesh=MEDCouplingUMesh::New(); - mesh->setMeshDimension(2); - mesh->allocateCells(5); - mesh->insertNextCell(INTERP_KERNEL::NORM_QUAD4,4,conn); - mesh->insertNextCell(INTERP_KERNEL::NORM_QUAD4,4,conn+4); - mesh->insertNextCell(INTERP_KERNEL::NORM_QUAD4,4,conn+8); - mesh->insertNextCell(INTERP_KERNEL::NORM_TRI3,3,conn+12); - mesh->insertNextCell(INTERP_KERNEL::NORM_TRI3,3,conn+15); - mesh->finishInsertingCells(); - DataArrayDouble *myCoords=DataArrayDouble::New(); - myCoords->alloc(9,2); - std::copy(coords,coords+18,myCoords->getPointer()); - mesh->setCoords(myCoords); - myCoords->decrRef(); - return mesh; -} -MEDCouplingUMesh *MEDCouplingBasicsTest::buildCU3DMesh_U() -{ - double coords[27*3]= - { -// 0.0,1.0,0.0 ,0.0,0.3,0.0 ,0.0,0.3,0.3 ,0.3,0.0,0.0 ,0.3,0.3,1.0 ,1.0,0.0,1.0 ,1.0,0.0,0.3 ,0.3,0.0,0.3 ,0.3,1.0,0.3 ,0.0,0.3,1.0 ,0.3,0.0,1.0 ,0.3,0.3,0.3 ,1.0,0.3,1.0 ,1.0,0.0,0.0 ,0.0,0.0,0.0 ,1.0,0.3,0.3 ,0.3,1.0,0.0 ,1.0,1.0,0.3 ,1.0,1.0,1.0 ,0.0,1.0,1.0 ,0.3,0.3,0.0 ,0.0,1.0,0.3 ,0.0,0.0,1.0 ,0.3,1.0,1.0 ,1.0,0.3,0.0 ,0.0,0.0,0.3 ,1.0,1.0,0.0 - 0.0,0.0,0.0, 0.3,0.0,0.0, 1.0,0.0,0.0, 0.0,0.3,0.0, 0.3,0.3,0.0, 1.0,0.3,0.0, 0.0,1.0,0.0, 0.3,1.0,0.0, 1.0,1.0,0.0, 0.0,0.0,0.3, 0.3,0.0,0.3, 1.0,0.0,0.3, 0.0,0.3,0.3, 0.3,0.3,0.3, 1.0,0.3,0.3, 0.0,1.0,0.3, 0.3,1.0,0.3, 1.0,1.0,0.3, 0.0,0.0,1.0, 0.3,0.0,1.0, 1.0,0.0,1.0, 0.0,0.3,1.0, 0.3,0.3,1.0, 1.0,0.3,1.0, 0.0,1.0,1.0, 0.3,1.0,1.0, 1.0,1.0,1.0, - }; - int conn[8*8]= - { -// 11,15,12,4,8,17,18,23,3,13,6,7,20,24,15,11,14,3,7,25,1,20,11,2,1,20,11,2,0,16,8,21,20,24,15,11,16,26,17,8,25,7,10,22,2,11,4,9,2,11,4,9,21,8,23,19,7,6,5,10,11,15,12,4 - 0,3,4,1,9,12,13,10, 1,4,5,2,10,13,14,11, 3,6,7,4,12,15,16,13, 4,7,8,5,13,16,17,14, 9,12,13,10,18,21,22,19, 10,13,14,11,19,22,23,20, 12,15,16,13,21,24,25,22, 13,16,17,14,22,25,26,23 - }; - MEDCouplingUMesh *mesh=MEDCouplingUMesh::New(); - mesh->setMeshDimension(3); - mesh->allocateCells(8); - for(int i=0;i<8;i++) - mesh->insertNextCell(INTERP_KERNEL::NORM_HEXA8,8,conn+8*i); - mesh->finishInsertingCells(); - DataArrayDouble *myCoords=DataArrayDouble::New(); - myCoords->alloc(27,3); - std::copy(coords,coords+27*3,myCoords->getPointer()); - mesh->setCoords(myCoords); - myCoords->decrRef(); - return mesh; -} - -MEDCouplingUMesh *MEDCouplingBasicsTest::build3DSurfSourceMesh_1() -{ - double sourceCoords[12]={-0.3,-0.3,0.5, 0.7,-0.3,1.5, -0.3,0.7,0.5, 0.7,0.7,1.5}; - int sourceConn[6]={0,3,1,0,2,3}; - MEDCouplingUMesh *sourceMesh=MEDCouplingUMesh::New(); - sourceMesh->setMeshDimension(2); - sourceMesh->allocateCells(2); - sourceMesh->insertNextCell(INTERP_KERNEL::NORM_TRI3,3,sourceConn); - sourceMesh->insertNextCell(INTERP_KERNEL::NORM_TRI3,3,sourceConn+3); - sourceMesh->finishInsertingCells(); - DataArrayDouble *myCoords=DataArrayDouble::New(); - myCoords->alloc(4,3); - std::copy(sourceCoords,sourceCoords+12,myCoords->getPointer()); - sourceMesh->setCoords(myCoords); - myCoords->decrRef(); - return sourceMesh; -} - -MEDCouplingUMesh *MEDCouplingBasicsTest::build3DSurfSourceMesh_2() -{ - double sourceCoords[12]={-0.3,-0.3,0., 0.7,-0.3,0., -0.3,0.7,0., 0.7,0.7,0.}; - int sourceConn[6]={0,3,1,0,2,3}; - MEDCouplingUMesh *sourceMesh=MEDCouplingUMesh::New(); - sourceMesh->setMeshDimension(2); - sourceMesh->allocateCells(2); - sourceMesh->insertNextCell(INTERP_KERNEL::NORM_TRI3,3,sourceConn); - sourceMesh->insertNextCell(INTERP_KERNEL::NORM_TRI3,3,sourceConn+3); - sourceMesh->finishInsertingCells(); - DataArrayDouble *myCoords=DataArrayDouble::New(); - myCoords->alloc(4,3); - std::copy(sourceCoords,sourceCoords+12,myCoords->getPointer()); - sourceMesh->setCoords(myCoords); - myCoords->decrRef(); - return sourceMesh; -} - -MEDCouplingUMesh *MEDCouplingBasicsTest::build3DSurfTargetMesh_1() -{ - double targetCoords[27]={-0.3,-0.3,0.5, 0.2,-0.3,1., 0.7,-0.3,1.5, -0.3,0.2,0.5, 0.2,0.2,1., 0.7,0.2,1.5, -0.3,0.7,0.5, 0.2,0.7,1., 0.7,0.7,1.5}; - int targetConn[18]={0,3,4,1, 1,4,2, 4,5,2, 6,7,4,3, 7,8,5,4}; - MEDCouplingUMesh *targetMesh=MEDCouplingUMesh::New(); - targetMesh->setMeshDimension(2); - targetMesh->allocateCells(5); - targetMesh->insertNextCell(INTERP_KERNEL::NORM_QUAD4,4,targetConn); - targetMesh->insertNextCell(INTERP_KERNEL::NORM_TRI3,3,targetConn+4); - targetMesh->insertNextCell(INTERP_KERNEL::NORM_TRI3,3,targetConn+7); - targetMesh->insertNextCell(INTERP_KERNEL::NORM_QUAD4,4,targetConn+10); - targetMesh->insertNextCell(INTERP_KERNEL::NORM_QUAD4,4,targetConn+14); - targetMesh->finishInsertingCells(); - DataArrayDouble *myCoords=DataArrayDouble::New(); - myCoords->alloc(9,3); - std::copy(targetCoords,targetCoords+27,myCoords->getPointer()); - targetMesh->setCoords(myCoords); - myCoords->decrRef(); - return targetMesh; -} - -/*! - * Idem build3DSurfTargetMesh_1 except that cell id 2 is not correctly numbered. - */ -MEDCouplingUMesh *MEDCouplingBasicsTest::build3DSurfTargetMeshPerm_1() -{ - double targetCoords[27]={-0.3,-0.3,0.5, 0.2,-0.3,1., 0.7,-0.3,1.5, -0.3,0.2,0.5, 0.2,0.2,1., 0.7,0.2,1.5, -0.3,0.7,0.5, 0.2,0.7,1., 0.7,0.7,1.5}; - int targetConn[18]={0,3,4,1, 1,4,2, 4,2,5, 6,7,4,3, 7,8,5,4}; - MEDCouplingUMesh *targetMesh=MEDCouplingUMesh::New(); - targetMesh->setMeshDimension(2); - targetMesh->allocateCells(5); - targetMesh->insertNextCell(INTERP_KERNEL::NORM_QUAD4,4,targetConn); - targetMesh->insertNextCell(INTERP_KERNEL::NORM_TRI3,3,targetConn+4); - targetMesh->insertNextCell(INTERP_KERNEL::NORM_TRI3,3,targetConn+7); - targetMesh->insertNextCell(INTERP_KERNEL::NORM_QUAD4,4,targetConn+10); - targetMesh->insertNextCell(INTERP_KERNEL::NORM_QUAD4,4,targetConn+14); - targetMesh->finishInsertingCells(); - DataArrayDouble *myCoords=DataArrayDouble::New(); - myCoords->alloc(9,3); - std::copy(targetCoords,targetCoords+27,myCoords->getPointer()); - targetMesh->setCoords(myCoords); - myCoords->decrRef(); - return targetMesh; -} - -MEDCouplingUMesh *MEDCouplingBasicsTest::build3DSurfTargetMesh_2() -{ - double targetCoords[27]={-0.3,-0.3,0.5, 0.2,-0.3,1., 0.7,-0.3,1.5, -0.3,0.2,0.5, 0.2,0.2,1., 0.7,0.2,1.5, -0.3,0.7,0.5, 0.2,0.7,1., 0.7,0.7,1.5}; - int targetConn[24]={0,3,4, 0,4,1, 1,4,2, 4,5,2, 3,6,4, 6,7,4, 4,7,5, 7,8,5 }; - MEDCouplingUMesh *targetMesh=MEDCouplingUMesh::New(); - targetMesh->setMeshDimension(2); - targetMesh->allocateCells(8); - targetMesh->insertNextCell(INTERP_KERNEL::NORM_TRI3,3,targetConn); - targetMesh->insertNextCell(INTERP_KERNEL::NORM_TRI3,3,targetConn+3); - targetMesh->insertNextCell(INTERP_KERNEL::NORM_TRI3,3,targetConn+6); - targetMesh->insertNextCell(INTERP_KERNEL::NORM_TRI3,3,targetConn+9); - targetMesh->insertNextCell(INTERP_KERNEL::NORM_TRI3,3,targetConn+12); - targetMesh->insertNextCell(INTERP_KERNEL::NORM_TRI3,3,targetConn+15); - targetMesh->insertNextCell(INTERP_KERNEL::NORM_TRI3,3,targetConn+18); - targetMesh->insertNextCell(INTERP_KERNEL::NORM_TRI3,3,targetConn+21); - targetMesh->finishInsertingCells(); - DataArrayDouble *myCoords=DataArrayDouble::New(); - myCoords->alloc(9,3); - std::copy(targetCoords,targetCoords+27,myCoords->getPointer()); - targetMesh->setCoords(myCoords); - myCoords->decrRef(); - return targetMesh; -} - -MEDCouplingUMesh *MEDCouplingBasicsTest::build3DSourceMesh_1() -{ - double sourceCoords[27]={ 0.0, 0.0, 200.0, 0.0, 0.0, 0.0, 0.0, 200.0, 200.0, 0.0, 200.0, 0.0, 200.0, 0.0, 200.0, - 200.0, 0.0, 0.0, 200.0, 200.0, 200.0, 200.0, 200.0, 0.0, 100.0, 100.0, 100.0 }; - int sourceConn[48]={8,1,7,3, 6,0,8,2, 7,4,5,8, 6,8,4,7, 6,8,0,4, 6,8,7,3, 8,1,3,0, 4,1,5,8, 1,7,5,8, 0,3,8,2, 8,1,0,4, 3,6,8,2}; - MEDCouplingUMesh *sourceMesh=MEDCouplingUMesh::New(); - sourceMesh->setMeshDimension(3); - sourceMesh->allocateCells(12); - sourceMesh->insertNextCell(INTERP_KERNEL::NORM_TETRA4,4,sourceConn); - sourceMesh->insertNextCell(INTERP_KERNEL::NORM_TETRA4,4,sourceConn+4); - sourceMesh->insertNextCell(INTERP_KERNEL::NORM_TETRA4,4,sourceConn+8); - sourceMesh->insertNextCell(INTERP_KERNEL::NORM_TETRA4,4,sourceConn+12); - sourceMesh->insertNextCell(INTERP_KERNEL::NORM_TETRA4,4,sourceConn+16); - sourceMesh->insertNextCell(INTERP_KERNEL::NORM_TETRA4,4,sourceConn+20); - sourceMesh->insertNextCell(INTERP_KERNEL::NORM_TETRA4,4,sourceConn+24); - sourceMesh->insertNextCell(INTERP_KERNEL::NORM_TETRA4,4,sourceConn+28); - sourceMesh->insertNextCell(INTERP_KERNEL::NORM_TETRA4,4,sourceConn+32); - sourceMesh->insertNextCell(INTERP_KERNEL::NORM_TETRA4,4,sourceConn+36); - sourceMesh->insertNextCell(INTERP_KERNEL::NORM_TETRA4,4,sourceConn+40); - sourceMesh->insertNextCell(INTERP_KERNEL::NORM_TETRA4,4,sourceConn+44); - sourceMesh->finishInsertingCells(); - DataArrayDouble *myCoords=DataArrayDouble::New(); - myCoords->alloc(9,3); - std::copy(sourceCoords,sourceCoords+27,myCoords->getPointer()); - sourceMesh->setCoords(myCoords); - myCoords->decrRef(); - return sourceMesh; -} - -MEDCouplingUMesh *MEDCouplingBasicsTest::build3DTargetMesh_1() -{ - double targetCoords[81]={ 0., 0., 0., 50., 0., 0. , 200., 0., 0. , 0., 50., 0., 50., 50., 0. , 200., 50., 0., 0., 200., 0., 50., 200., 0. , 200., 200., 0. , - 0., 0., 50., 50., 0., 50. , 200., 0., 50. , 0., 50., 50., 50., 50., 50. , 200., 50., 50., 0., 200., 50., 50., 200., 50. , 200., 200., 50. , - 0., 0., 200., 50., 0., 200. , 200., 0., 200. , 0., 50., 200., 50., 50., 200. , 200., 50., 200., 0., 200., 200., 50., 200., 200. , 200., 200., 200. }; - int targetConn[64]={0,1,4,3,9,10,13,12, 1,2,5,4,10,11,14,13, 3,4,7,6,12,13,16,15, 4,5,8,7,13,14,17,16, - 9,10,13,12,18,19,22,21, 10,11,14,13,19,20,23,22, 12,13,16,15,21,22,25,24, 13,14,17,16,22,23,26,25}; - MEDCouplingUMesh *targetMesh=MEDCouplingUMesh::New(); - targetMesh->setMeshDimension(3); - targetMesh->allocateCells(12); - for(int i=0;i<8;i++) - targetMesh->insertNextCell(INTERP_KERNEL::NORM_HEXA8,8,targetConn+8*i); - targetMesh->finishInsertingCells(); - DataArrayDouble *myCoords=DataArrayDouble::New(); - myCoords->alloc(27,3); - std::copy(targetCoords,targetCoords+81,myCoords->getPointer()); - targetMesh->setCoords(myCoords); - myCoords->decrRef(); - return targetMesh; -} - -MEDCouplingUMesh *MEDCouplingBasicsTest::build2DTargetMeshMergeNode_1() -{ - double targetCoords[36]={-0.3,-0.3, 0.2,-0.3, 0.7,-0.3, -0.3,-0.3, 0.2,-0.3, 0.2,-0.3, 0.2,0.2, 0.2,0.2, 0.7,-0.3, -0.3,0.2, 0.2,0.2, 0.7,0.2, -0.3,0.7, 0.7,0.2, -0.3,0.7, 0.2,0.7, 0.7,0.7, 0.2,0.7 }; - int targetConn[18]={0,9,7,5, 4,6,2, 10,11,8, 9,14,15,7, 17,16,13,6}; - MEDCouplingUMesh *targetMesh=MEDCouplingUMesh::New(); - targetMesh->setMeshDimension(2); - targetMesh->allocateCells(5); - targetMesh->insertNextCell(INTERP_KERNEL::NORM_QUAD4,4,targetConn); - targetMesh->insertNextCell(INTERP_KERNEL::NORM_TRI3,3,targetConn+4); - targetMesh->insertNextCell(INTERP_KERNEL::NORM_TRI3,3,targetConn+7); - targetMesh->insertNextCell(INTERP_KERNEL::NORM_QUAD4,4,targetConn+10); - targetMesh->insertNextCell(INTERP_KERNEL::NORM_QUAD4,4,targetConn+14); - targetMesh->finishInsertingCells(); - DataArrayDouble *myCoords=DataArrayDouble::New(); - myCoords->alloc(18,2); - std::copy(targetCoords,targetCoords+36,myCoords->getPointer()); - targetMesh->setCoords(myCoords); - myCoords->decrRef(); - return targetMesh; -} - -MEDCouplingUMesh *MEDCouplingBasicsTest::build3DTargetMeshMergeNode_1() -{ - double targetCoords[93]={ 0., 0., 0., 50., 0., 0. , 200., 0., 0. , 0., 50., 0., 50., 50., 0. , 200., 50., 0., 0., 200., 0., 50., 200., 0. , 200., 200., 0. , - 0., 0., 50., 50., 0., 50. , 200., 0., 50. , 0., 50., 50., 50., 50., 50. , 200., 50., 50., 0., 200., 50., 50., 200., 50. , 200., 200., 50. , - 0., 0., 200., 50., 0., 200. , 200., 0., 200. , 0., 50., 200., 50., 50., 200. , 200., 50., 200., 0., 200., 200., 50., 200., 200. , 200., 200., 200., 50.,0.,0., 50.,0.,0., 50.,0.,0., 200., 50., 200.}; - int targetConn[64]={0,29,4,3,9,10,13,12, 28,2,5,4,10,11,14,13, 3,4,7,6,12,13,16,15, 4,5,8,7,13,14,17,16, - 9,10,13,12,18,19,22,21, 10,11,14,13,19,20,23,22, 12,13,16,15,21,22,25,24, 13,14,17,16,22,30,26,25}; - MEDCouplingUMesh *targetMesh=MEDCouplingUMesh::New(); - targetMesh->setMeshDimension(3); - targetMesh->allocateCells(12); - for(int i=0;i<8;i++) - targetMesh->insertNextCell(INTERP_KERNEL::NORM_HEXA8,8,targetConn+8*i); - targetMesh->finishInsertingCells(); - DataArrayDouble *myCoords=DataArrayDouble::New(); - myCoords->alloc(31,3); - std::copy(targetCoords,targetCoords+93,myCoords->getPointer()); - targetMesh->setCoords(myCoords); - myCoords->decrRef(); - return targetMesh; -} - -MEDCouplingUMesh *MEDCouplingBasicsTest::build3DExtrudedUMesh_1(MEDCouplingUMesh *&mesh2D) -{ - double coords[180]={ - 0.,0.,0., 1.,1.,0., 1.,1.25,0., 1.,0.,0., 1.,1.5,0., 2.,0.,0., 2.,1.,0., 1.,2.,0., 0.,2.,0., 3.,1.,0., - 3.,2.,0., 0.,1.,0., 1.,3.,0., 2.,2.,0., 2.,3.,0., - 0.,0.,1., 1.,1.,1., 1.,1.25,1., 1.,0.,1., 1.,1.5,1., 2.,0.,1., 2.,1.,1., 1.,2.,1., 0.,2.,1., 3.,1.,1., - 3.,2.,1., 0.,1.,1., 1.,3.,1., 2.,2.,1., 2.,3.,1., - 0.,0.,2., 1.,1.,2., 1.,1.25,2., 1.,0.,2., 1.,1.5,2., 2.,0.,2., 2.,1.,2., 1.,2.,2., 0.,2.,2., 3.,1.,2., - 3.,2.,2., 0.,1.,2., 1.,3.,2., 2.,2.,2., 2.,3.,2., - 0.,0.,3., 1.,1.,3., 1.,1.25,3., 1.,0.,3., 1.,1.5,3., 2.,0.,3., 2.,1.,3., 1.,2.,3., 0.,2.,3., 3.,1.,3., - 3.,2.,3., 0.,1.,3., 1.,3.,3., 2.,2.,3., 2.,3.,3.}; - - int conn[354]={ - // 0 - 0,11,1,3,15,26,16,18, 1,2,4,7,13,6,-1,1,16,21,6,-1,6,21,28,13,-1,13,7,22,28,-1,7,4,19,22,-1,4,2,17,19,-1,2,1,16,17,-1,16,21,28,22,19,17, - 1,6,5,3,16,21,20,18, 13,10,9,6,28,25,24,21, - 11,8,7,4,2,1,-1,11,26,16,1,-1,1,16,17,2,-1,2,17,19,4,-1,4,19,22,7,-1,7,8,23,22,-1,8,11,26,23,-1,26,16,17,19,22,23, - 7,12,14,13,22,27,29,28, - // 1 - 15,26,16,18,30,41,31,33, 16,17,19,22,28,21,-1,16,31,36,21,-1,21,36,43,28,-1,28,22,37,43,-1,22,19,34,37,-1,19,17,32,34,-1,17,16,31,32,-1,31,36,43,37,34,32, - 16,21,20,18,31,36,35,33, 28,25,24,21,43,40,39,36, - 26,23,22,19,17,16,-1,26,41,31,16,-1,16,31,32,17,-1,17,32,34,19,-1,19,34,37,22,-1,22,23,38,37,-1,23,26,41,38,-1,41,31,32,34,37,38, - 22,27,29,28,37,42,44,43, - // 2 - 30,41,31,33,45,56,46,48, 31,32,34,37,43,36,-1,31,46,51,36,-1,36,51,58,43,-1,43,37,52,58,-1,37,34,49,52,-1,34,32,47,49,-1,32,31,46,47,-1,46,51,58,52,49,47, - 31,36,35,33,46,51,50,48, 43,40,39,36,58,55,54,51, - 41,38,37,34,32,31,-1,41,56,46,31,-1,31,46,47,32,-1,32,47,49,34,-1,34,49,52,37,-1,37,38,53,52,-1,38,41,56,53,-1,56,46,47,49,52,53, - 37,42,44,43,52,57,59,58 - }; - int conn2[28]={7,12,14,13, 11,8,7,4,2,1, 13,10,9,6, 1,6,5,3, 1,2,4,7,13,6, 0,11,1,3}; - // - MEDCouplingUMesh *ret=MEDCouplingUMesh::New(); - ret->setMeshDimension(3); - ret->allocateCells(18); - // - ret->insertNextCell(INTERP_KERNEL::NORM_HEXA8,8,conn); - ret->insertNextCell(INTERP_KERNEL::NORM_POLYHED,43,conn+8); - ret->insertNextCell(INTERP_KERNEL::NORM_HEXA8,8,conn+51); - ret->insertNextCell(INTERP_KERNEL::NORM_HEXA8,8,conn+59); - ret->insertNextCell(INTERP_KERNEL::NORM_POLYHED,43,conn+67); - ret->insertNextCell(INTERP_KERNEL::NORM_HEXA8,8,conn+110); - // - ret->insertNextCell(INTERP_KERNEL::NORM_HEXA8,8,conn+118); - ret->insertNextCell(INTERP_KERNEL::NORM_POLYHED,43,conn+126); - ret->insertNextCell(INTERP_KERNEL::NORM_HEXA8,8,conn+169); - ret->insertNextCell(INTERP_KERNEL::NORM_HEXA8,8,conn+177); - ret->insertNextCell(INTERP_KERNEL::NORM_POLYHED,43,conn+185); - ret->insertNextCell(INTERP_KERNEL::NORM_HEXA8,8,conn+228); - // - ret->insertNextCell(INTERP_KERNEL::NORM_HEXA8,8,conn+236); - ret->insertNextCell(INTERP_KERNEL::NORM_POLYHED,43,conn+244); - ret->insertNextCell(INTERP_KERNEL::NORM_HEXA8,8,conn+287); - ret->insertNextCell(INTERP_KERNEL::NORM_HEXA8,8,conn+295); - ret->insertNextCell(INTERP_KERNEL::NORM_POLYHED,43,conn+303); - ret->insertNextCell(INTERP_KERNEL::NORM_HEXA8,8,conn+346); - // - ret->finishInsertingCells(); - DataArrayDouble *myCoords=DataArrayDouble::New(); - myCoords->alloc(60,3); - std::copy(coords,coords+180,myCoords->getPointer()); - ret->setCoords(myCoords); - // - mesh2D=MEDCouplingUMesh::New(); - mesh2D->setMeshDimension(2); - mesh2D->allocateCells(6); - mesh2D->insertNextCell(INTERP_KERNEL::NORM_QUAD4,4,conn2); - mesh2D->insertNextCell(INTERP_KERNEL::NORM_POLYGON,6,conn2+4); - mesh2D->insertNextCell(INTERP_KERNEL::NORM_QUAD4,4,conn2+10); - mesh2D->insertNextCell(INTERP_KERNEL::NORM_QUAD4,4,conn2+14); - mesh2D->insertNextCell(INTERP_KERNEL::NORM_POLYGON,6,conn2+18); - mesh2D->insertNextCell(INTERP_KERNEL::NORM_QUAD4,4,conn2+24); - mesh2D->setCoords(myCoords); - myCoords->decrRef(); - return ret; -} - -void MEDCouplingBasicsTest::build3DExtrudedUMesh_2(MEDCouplingUMesh *&meshN, MEDCouplingUMesh *&meshTT, MEDCouplingUMesh *&meshTF) -{ - const double coordsN[270]={ - 0, 0, 0, 0.10803000450134277, 0, 0, 0.21606000900268554, 0, 0, 0.28808000564575198, 0, 0, 0.36010002136230468, 0, 0, 0.43212001800537109, 0, 0, 0, - 0.072020001411437995, 0, 0.10803000450134277, 0.072020001411437995, 0, 0.21606000900268554, 0.072020001411437995, 0, 0.28808000564575198, 0.072020001411437995, - 0, 0.36010002136230468, 0.072020001411437995, 0, 0.43212001800537109, 0.072020001411437995, 0, 0, 0.10803000450134277, 0, 0.10803000450134277, - 0.10803000450134277, 0, 0.21606000900268554, 0.10803000450134277, 0, 0.28808000564575198, 0.10803000450134277, 0, 0.36010002136230468, 0.10803000450134277, 0, - 0.43212001800537109, 0.10803000450134277, 0, 0, 0.14404000282287599, 0, 0.10803000450134277, 0.14404000282287599, 0, 0.21606000900268554, 0.14404000282287599, 0, - 0.28808000564575198, 0.14404000282287599, 0, 0.36010002136230468, 0.14404000282287599, 0, 0.43212001800537109, 0.14404000282287599, 0, 0, 0.21606000900268554, 0, - 0.10803000450134277, 0.21606000900268554, 0, 0.21606000900268554, 0.21606000900268554, 0, 0.28808000564575198, 0.21606000900268554, 0, 0.36010002136230468, - 0.21606000900268554, 0, 0.43212001800537109, 0.21606000900268554, 0, 0, 0, 2.1364999389648438, 0.10803000450134277, 0, 2.1364999389648438, 0.21606000900268554, - 0, 2.1364999389648438, 0.28808000564575198, 0, 2.1364999389648438, 0.36010002136230468, 0, 2.1364999389648438, 0.43212001800537109, 0, 2.1364999389648438, 0, - 0.072020001411437995, 2.1364999389648438, 0.10803000450134277, 0.072020001411437995, 2.1364999389648438, 0.21606000900268554, 0.072020001411437995, - 2.1364999389648438, 0.28808000564575198, 0.072020001411437995, 2.1364999389648438, 0.36010002136230468, 0.072020001411437995, 2.1364999389648438, - 0.43212001800537109, 0.072020001411437995, 2.1364999389648438, 0, 0.10803000450134277, 2.1364999389648438, 0.10803000450134277, 0.10803000450134277, - 2.1364999389648438, 0.21606000900268554, 0.10803000450134277, 2.1364999389648438, 0.28808000564575198, 0.10803000450134277, 2.1364999389648438, - 0.36010002136230468, 0.10803000450134277, 2.1364999389648438, 0.43212001800537109, 0.10803000450134277, 2.1364999389648438, 0, 0.14404000282287599, - 2.1364999389648438, 0.10803000450134277, 0.14404000282287599, 2.1364999389648438, 0.21606000900268554, 0.14404000282287599, 2.1364999389648438, - 0.28808000564575198, 0.14404000282287599, 2.1364999389648438, 0.36010002136230468, 0.14404000282287599, 2.1364999389648438, 0.43212001800537109, - 0.14404000282287599, 2.1364999389648438, 0, 0.21606000900268554, 2.1364999389648438, 0.10803000450134277, 0.21606000900268554, 2.1364999389648438, - 0.21606000900268554, 0.21606000900268554, 2.1364999389648438, 0.28808000564575198, 0.21606000900268554, 2.1364999389648438, 0.36010002136230468, - 0.21606000900268554, 2.1364999389648438, 0.43212001800537109, 0.21606000900268554, 2.1364999389648438, 0, 0, 4.2729998779296876, 0.10803000450134277, 0, - 4.2729998779296876, 0.21606000900268554, 0, 4.2729998779296876, 0.28808000564575198, 0, 4.2729998779296876, 0.36010002136230468, 0, 4.2729998779296876, - 0.43212001800537109, 0, 4.2729998779296876, 0, 0.072020001411437995, 4.2729998779296876, 0.10803000450134277, 0.072020001411437995, 4.2729998779296876, - 0.21606000900268554, 0.072020001411437995, 4.2729998779296876, 0.28808000564575198, 0.072020001411437995, 4.2729998779296876, 0.36010002136230468, - 0.072020001411437995, 4.2729998779296876, 0.43212001800537109, 0.072020001411437995, 4.2729998779296876, 0, 0.10803000450134277, 4.2729998779296876, - 0.10803000450134277, 0.10803000450134277, 4.2729998779296876, 0.21606000900268554, 0.10803000450134277, 4.2729998779296876, 0.28808000564575198, - 0.10803000450134277, 4.2729998779296876, 0.36010002136230468, 0.10803000450134277, 4.2729998779296876, 0.43212001800537109, 0.10803000450134277, - 4.2729998779296876, 0, 0.14404000282287599, 4.2729998779296876, 0.10803000450134277, 0.14404000282287599, 4.2729998779296876, 0.21606000900268554, - 0.14404000282287599, 4.2729998779296876, 0.28808000564575198, 0.14404000282287599, 4.2729998779296876, 0.36010002136230468, 0.14404000282287599, - 4.2729998779296876, 0.43212001800537109, 0.14404000282287599, 4.2729998779296876, 0, 0.21606000900268554, 4.2729998779296876, 0.10803000450134277, - 0.21606000900268554, 4.2729998779296876, 0.21606000900268554, 0.21606000900268554, 4.2729998779296876, 0.28808000564575198, 0.21606000900268554, - 4.2729998779296876, 0.36010002136230468, 0.21606000900268554, 4.2729998779296876, 0.43212001800537109, 0.21606000900268554, 4.2729998779296876}; - const int connN[320]={ - 0, 1, 7, 6, 30, 31, 37, 36, 1, 2, 8, 7, 31, 32, 38, 37, 2, 3, 9, 8, 32, 33, 39, 38, 3, 4, 10, 9, 33, 34, 40, 39, 4, 5, 11, 10, 34, 35, 41, 40, 6, - 7, 13, 12, 36, 37, 43, 42, 7, 8, 14, 13, 37, 38, 44, 43, 8, 9, 15, 14, 38, 39, 45, 44, 9, 10, 16, 15, 39, 40, 46, 45, 10, 11, 17, 16, 40, 41, 47, - 46, 12, 13, 19, 18, 42, 43, 49, 48, 13, 14, 20, 19, 43, 44, 50, 49, 14, 15, 21, 20, 44, 45, 51, 50, 15, 16, 22, 21, 45, 46, 52, 51, 16, 17, 23, - 22, 46, 47, 53, 52, 18, 19, 25, 24, 48, 49, 55, 54, 19, 20, 26, 25, 49, 50, 56, 55, 20, 21, 27, 26, 50, 51, 57, 56, 21, 22, 28, 27, 51, 52, 58, - 57, 22, 23, 29, 28, 52, 53, 59, 58, 30, 31, 37, 36, 60, 61, 67, 66, 31, 32, 38, 37, 61, 62, 68, 67, 32, 33, 39, 38, 62, 63, 69, 68, 33, 34, 40, - 39, 63, 64, 70, 69, 34, 35, 41, 40, 64, 65, 71, 70, 36, 37, 43, 42, 66, 67, 73, 72, 37, 38, 44, 43, 67, 68, 74, 73, 38, 39, 45, 44, 68, 69, 75, - 74, 39, 40, 46, 45, 69, 70, 76, 75, 40, 41, 47, 46, 70, 71, 77, 76, 42, 43, 49, 48, 72, 73, 79, 78, 43, 44, 50, 49, 73, 74, 80, 79, 44, 45, 51, - 50, 74, 75, 81, 80, 45, 46, 52, 51, 75, 76, 82, 81, 46, 47, 53, 52, 76, 77, 83, 82, 48, 49, 55, 54, 78, 79, 85, 84, 49, 50, 56, 55, 79, 80, 86, - 85, 50, 51, 57, 56, 80, 81, 87, 86, 51, 52, 58, 57, 81, 82, 88, 87, 52, 53, 59, 58, 82, 83, 89, 88}; - meshN=MEDCouplingUMesh::New(); - meshN->setName("meshExtrudedN"); - meshN->setMeshDimension(3); - meshN->allocateCells(40); - for(int i=0;i<40;i++) - meshN->insertNextCell(INTERP_KERNEL::NORM_HEXA8,8,connN+8*i); - meshN->finishInsertingCells(); - DataArrayDouble *myCoords=DataArrayDouble::New(); - myCoords->alloc(90,3); - std::copy(coordsN,coordsN+270,myCoords->getPointer()); - meshN->setCoords(myCoords); - myCoords->decrRef(); - // - meshTT=MEDCouplingUMesh::New(); - meshTT->setName("meshExtrudedTT"); - meshTT->setMeshDimension(3); - meshTT->allocateCells(200); - for(int i=0;i<200;i++) - meshTT->insertNextCell(INTERP_KERNEL::NORM_POLYHED,connITT[i+1]-connITT[i],connTT+connITT[i]); - meshTT->finishInsertingCells(); - myCoords=DataArrayDouble::New(); - myCoords->alloc(1720,3); - std::copy(coordsTT,coordsTT+5160,myCoords->getPointer()); - meshTT->setCoords(myCoords); - myCoords->decrRef(); - // - meshTF=MEDCouplingUMesh::New(); - meshTF->setName("meshExtrudedTF"); - meshTF->setMeshDimension(3); - meshTF->allocateCells(340); - for(int i=0;i<320;i++) - meshTF->insertNextCell(INTERP_KERNEL::NORM_HEXA8,8,connTFH8+8*i); - for(int i=0;i<20;i++) - meshTF->insertNextCell(INTERP_KERNEL::NORM_POLYHED,connTFPOLH_I[i+1]-connTFPOLH_I[i],connTFPOLH+connTFPOLH_I[i]); - meshTF->finishInsertingCells(); - myCoords=DataArrayDouble::New(); - myCoords->alloc(567,3); - std::copy(coordsTF,coordsTF+1701,myCoords->getPointer()); - meshTF->setCoords(myCoords); - myCoords->decrRef(); -} - -MEDCouplingUMesh *MEDCouplingBasicsTest::build2DTargetMeshMerged_1() -{ - double targetCoords[26]={ - -0.3,-0.3, 0.2,-0.3, 0.7,-0.3, -0.3,0.2, 0.2,0.2, 0.7,0.2, -0.3,0.7, 0.2,0.7, 0.7,0.7, - 0.7,-0.3, 1.7,-0.3, 0.7,0.7, 1.7,0.7 - }; - int targetConn[24]={ - 0,3,4,1, 1,4,2, 4,5,2, 6,7,4,3, 7,8,5,4, - 9,12,10,9,11,12 - }; - MEDCouplingUMesh *targetMesh=MEDCouplingUMesh::New(); - targetMesh->setName("merge"); - targetMesh->setMeshDimension(2); - targetMesh->allocateCells(10); - targetMesh->insertNextCell(INTERP_KERNEL::NORM_QUAD4,4,targetConn); - targetMesh->insertNextCell(INTERP_KERNEL::NORM_TRI3,3,targetConn+4); - targetMesh->insertNextCell(INTERP_KERNEL::NORM_TRI3,3,targetConn+7); - targetMesh->insertNextCell(INTERP_KERNEL::NORM_QUAD4,4,targetConn+10); - targetMesh->insertNextCell(INTERP_KERNEL::NORM_QUAD4,4,targetConn+14); - targetMesh->insertNextCell(INTERP_KERNEL::NORM_TRI3,3,targetConn+18); - targetMesh->insertNextCell(INTERP_KERNEL::NORM_TRI3,3,targetConn+21); - targetMesh->finishInsertingCells(); - DataArrayDouble *myCoords=DataArrayDouble::New(); - myCoords->alloc(13,2); - std::copy(targetCoords,targetCoords+26,myCoords->getPointer()); - targetMesh->setCoords(myCoords); - myCoords->decrRef(); - return targetMesh; -} - -MEDCouplingUMesh *MEDCouplingBasicsTest::build2DCurveMesh(double dx, double dy) -{ - // 1d mesh: - // - // * - // / - // *---* - double targetCoords[3*2]= - { - 0.+dx,0.+dy, 1.+dx,0.+dy, 2.+dx,1.+dy - }; - int targetConn[2*2]={1,2, 0,1}; - - MEDCouplingUMesh *targetMesh=MEDCouplingUMesh::New("2Dcurve 1D mesh",1); - targetMesh->allocateCells(2); - for(int i=0;i<2;i++) - targetMesh->insertNextCell(INTERP_KERNEL::NORM_SEG2,2,targetConn+2*i); - targetMesh->finishInsertingCells(); - DataArrayDouble *myCoords=DataArrayDouble::New(); - myCoords->alloc(3,2); - std::copy(targetCoords,targetCoords+3*2,myCoords->getPointer()); - targetMesh->setCoords(myCoords); - myCoords->decrRef(); - return targetMesh; -} - -MEDCouplingUMesh *MEDCouplingBasicsTest::build1DMesh(double dx) -{ - double targetCoords[4]= - { - 0.+dx, 1.+dx, 3.+dx, 4.+dx - }; - int targetConn[2*3]={1,2, 0,1, 2,3}; - - MEDCouplingUMesh *targetMesh=MEDCouplingUMesh::New("1D mesh",1); - targetMesh->allocateCells(3); - for(int i=0;i<3;i++) - targetMesh->insertNextCell(INTERP_KERNEL::NORM_SEG2,2,targetConn+2*i); - targetMesh->finishInsertingCells(); - DataArrayDouble *myCoords=DataArrayDouble::New(); - myCoords->alloc(4,1); - std::copy(targetCoords,targetCoords+4,myCoords->getPointer()); - targetMesh->setCoords(myCoords); - myCoords->decrRef(); - return targetMesh; -} - -MEDCouplingUMesh *MEDCouplingBasicsTest::build1DSourceMesh_2() -{ - MEDCouplingUMesh *ret=MEDCouplingUMesh::New("1DSourceMesh",1); - ret->allocateCells(4); - int conn[8]={0,1,2,3,1,2,3,4}; - for(int i=0;i<4;i++) - ret->insertNextCell(INTERP_KERNEL::NORM_SEG2,2,conn+2*i); - ret->finishInsertingCells(); - double coords[5]={0.3,0.7,0.9,1.0,1.12}; - DataArrayDouble *myCoords=DataArrayDouble::New(); - myCoords->alloc(5,1); - std::copy(coords,coords+5,myCoords->getPointer()); - ret->setCoords(myCoords); - myCoords->decrRef(); - return ret; -} - -MEDCouplingUMesh *MEDCouplingBasicsTest::build1DTargetMesh_2() -{ - MEDCouplingUMesh *ret=MEDCouplingUMesh::New("1DTargetMesh",1); - ret->allocateCells(2); - int conn[4]={1,2,0,1}; - for(int i=0;i<2;i++) - ret->insertNextCell(INTERP_KERNEL::NORM_SEG2,2,conn+2*i); - ret->finishInsertingCells(); - double coords[3]={0.5,0.75,1.2}; - DataArrayDouble *myCoords=DataArrayDouble::New(); - myCoords->alloc(3,1); - std::copy(coords,coords+3,myCoords->getPointer()); - ret->setCoords(myCoords); - myCoords->decrRef(); - return ret; -} - -MEDCouplingUMesh *MEDCouplingBasicsTest::build2DCurveSourceMesh_2() -{ - MEDCouplingUMesh *ret=MEDCouplingUMesh::New("1DSourceMesh",1); - ret->allocateCells(4); - int conn[8]={0,1,2,3,1,2,3,4}; - for(int i=0;i<4;i++) - ret->insertNextCell(INTERP_KERNEL::NORM_SEG2,2,conn+2*i); - ret->finishInsertingCells(); - double coords[10]={0.3,0.3,0.7,0.7,0.9,0.9,1.0,1.0,1.12,1.12}; - DataArrayDouble *myCoords=DataArrayDouble::New(); - myCoords->alloc(5,2); - std::copy(coords,coords+10,myCoords->getPointer()); - ret->setCoords(myCoords); - myCoords->decrRef(); - return ret; -} - -MEDCouplingUMesh *MEDCouplingBasicsTest::build2DCurveTargetMesh_2() -{ - MEDCouplingUMesh *ret=MEDCouplingUMesh::New("1DTargetMesh",1); - ret->allocateCells(2); - int conn[4]={1,2,0,1}; - for(int i=0;i<2;i++) - ret->insertNextCell(INTERP_KERNEL::NORM_SEG2,2,conn+2*i); - ret->finishInsertingCells(); - double coords[6]={0.5,0.5,0.75,0.75,1.2,1.2}; - DataArrayDouble *myCoords=DataArrayDouble::New(); - myCoords->alloc(3,2); - std::copy(coords,coords+6,myCoords->getPointer()); - ret->setCoords(myCoords); - myCoords->decrRef(); - return ret; -} - -MEDCouplingUMesh *MEDCouplingBasicsTest::build1DTargetMesh_3() -{ - MEDCouplingUMesh *ret=MEDCouplingUMesh::New("1DMesh_3",1); - ret->allocateCells(4); - int conn[10]={0,1,2, 3,4, 6,5,7 ,9,8}; - ret->insertNextCell(INTERP_KERNEL::NORM_SEG3,3,conn); - ret->insertNextCell(INTERP_KERNEL::NORM_SEG2,2,conn+3); - ret->insertNextCell(INTERP_KERNEL::NORM_SEG3,3,conn+5); - ret->insertNextCell(INTERP_KERNEL::NORM_SEG2,2,conn+8); - ret->finishInsertingCells(); - double coords[10]={0.5,1.,0.8,5.,5.21,0.5,1.1,0.7,5.,5.31}; - DataArrayDouble *myCoords=DataArrayDouble::New(); - myCoords->alloc(10,1); - std::copy(coords,coords+10,myCoords->getPointer()); - ret->setCoords(myCoords); - myCoords->decrRef(); - return ret; -} - -MEDCouplingUMesh *MEDCouplingBasicsTest::build2DCurveTargetMesh_3() -{ - MEDCouplingUMesh *ret=MEDCouplingUMesh::New("2DCurveMesh_3",1); - ret->allocateCells(4); - int conn[10]={0,1,2, 3,4, 6,5,7 ,9,8}; - ret->insertNextCell(INTERP_KERNEL::NORM_SEG3,3,conn); - ret->insertNextCell(INTERP_KERNEL::NORM_SEG2,2,conn+3); - ret->insertNextCell(INTERP_KERNEL::NORM_SEG3,3,conn+5); - ret->insertNextCell(INTERP_KERNEL::NORM_SEG2,2,conn+8); - ret->finishInsertingCells(); - double coords[20]={0.5,0.5,1.,1.,0.8,0.8,5.,5.,5.21,5.21,0.5,0.5,1.1,1.1,0.7,0.7,5.,5.,5.31,5.31}; - DataArrayDouble *myCoords=DataArrayDouble::New(); - myCoords->alloc(10,2); - std::copy(coords,coords+20,myCoords->getPointer()); - ret->setCoords(myCoords); - myCoords->decrRef(); - return ret; -} - -MEDCouplingUMesh *MEDCouplingBasicsTest::build2DTargetMesh_3() -{ - MEDCouplingUMesh *ret=MEDCouplingUMesh::New("2DMesh_3",2); - ret->allocateCells(10); - int conn[52]={ - 0,1,2, 0,1,3,4, 0,1,3,5,4, 0,1,2,6,7,8, 0,1,3,4,6,9,2,10, - 0,2,1, 0,4,3,1, 0,4,5,3,1, 0,2,1,8,7,6, 0,4,3,1,10,2,9,6 - }; - ret->insertNextCell(INTERP_KERNEL::NORM_TRI3,3,conn); - ret->insertNextCell(INTERP_KERNEL::NORM_QUAD4,4,conn+3); - ret->insertNextCell(INTERP_KERNEL::NORM_POLYGON,5,conn+7); - ret->insertNextCell(INTERP_KERNEL::NORM_TRI6,6,conn+12); - ret->insertNextCell(INTERP_KERNEL::NORM_QUAD8,8,conn+18); - ret->insertNextCell(INTERP_KERNEL::NORM_TRI3,3,conn+26); - ret->insertNextCell(INTERP_KERNEL::NORM_QUAD4,4,conn+29); - ret->insertNextCell(INTERP_KERNEL::NORM_POLYGON,5,conn+33); - ret->insertNextCell(INTERP_KERNEL::NORM_TRI6,6,conn+38); - ret->insertNextCell(INTERP_KERNEL::NORM_QUAD8,8,conn+44); - ret->finishInsertingCells(); - double coords[22]={0.,0.,1.,0.,0.5,1.,1.,1.,0.,1.,0.5,2.,0.5,0.,0.75,0.5,0.25,0.5,1.,0.5,0.,0.5}; - DataArrayDouble *myCoords=DataArrayDouble::New(); - myCoords->alloc(11,2); - std::copy(coords,coords+22,myCoords->getPointer()); - ret->setCoords(myCoords); - myCoords->decrRef(); - ret->checkCoherency(); - return ret; -} - -/*! - * Same as build2DTargetMesh_1 but with more nodes than needed. To check tryToShareSameCoordsPermute method. - */ -MEDCouplingUMesh *MEDCouplingBasicsTest::build2DTargetMesh_4() -{ - double targetCoords[20]={-0.3,-0.3, 0.2,-0.3, 0.7,-0.3, 0.7,-0.3, -0.3,0.2, 0.2,0.2, 0.7,0.2, -0.3,0.7, 0.2,0.7, 0.7,0.7 }; - int targetConn[18]={0,4,5,1, 1,5,3, 5,6,2, 7,8,5,4, 8,9,6,5}; - MEDCouplingUMesh *targetMesh=MEDCouplingUMesh::New(); - targetMesh->setMeshDimension(2); - targetMesh->allocateCells(5); - targetMesh->insertNextCell(INTERP_KERNEL::NORM_QUAD4,4,targetConn); - targetMesh->insertNextCell(INTERP_KERNEL::NORM_TRI3,3,targetConn+4); - targetMesh->insertNextCell(INTERP_KERNEL::NORM_TRI3,3,targetConn+7); - targetMesh->insertNextCell(INTERP_KERNEL::NORM_QUAD4,4,targetConn+10); - targetMesh->insertNextCell(INTERP_KERNEL::NORM_QUAD4,4,targetConn+14); - targetMesh->finishInsertingCells(); - DataArrayDouble *myCoords=DataArrayDouble::New(); - myCoords->alloc(10,2); - std::copy(targetCoords,targetCoords+20,myCoords->getPointer()); - targetMesh->setCoords(myCoords); - myCoords->decrRef(); - return targetMesh; -} - -MEDCouplingUMesh *MEDCouplingBasicsTest::build3DTargetMesh_3() -{ - return 0; -} - -MEDCouplingMultiFields *MEDCouplingBasicsTest::buildMultiFields_1() -{ - ParaMEDMEM::MEDCouplingUMesh *m1=build2DTargetMesh_1(); - m1->setName("m1"); - ParaMEDMEM::MEDCouplingUMesh *m2=build2DTargetMesh_1(); - m2->setName("m2"); - const double vals0[]={-0.7,-1.,-2.,-3.,-4.}; - const double vals1[]={0.,1.,2.,3.,4.,0.1,0.2,0.3,0.4}; - const double vals1_1[]={170.,171.,172.,173.,174.,170.1,170.2,170.3,170.4}; - const double vals2[]={5.,6.,7.,8.,9.}; - const double vals4[]={15.,16.,17.,18.,19.}; - // - ParaMEDMEM::DataArrayDouble *d0=ParaMEDMEM::DataArrayDouble::New(); d0->alloc(5,1); std::copy(vals0,vals0+5,d0->getPointer()); - ParaMEDMEM::DataArrayDouble *d1=ParaMEDMEM::DataArrayDouble::New(); d1->alloc(9,1); std::copy(vals1,vals1+9,d1->getPointer()); - ParaMEDMEM::DataArrayDouble *d1_1=ParaMEDMEM::DataArrayDouble::New(); d1_1->alloc(9,1); std::copy(vals1_1,vals1_1+9,d1_1->getPointer()); - ParaMEDMEM::DataArrayDouble *d2=ParaMEDMEM::DataArrayDouble::New(); d2->alloc(5,1); std::copy(vals2,vals2+5,d2->getPointer()); - ParaMEDMEM::DataArrayDouble *d4=ParaMEDMEM::DataArrayDouble::New(); d4->alloc(5,1); std::copy(vals4,vals4+5,d4->getPointer()); - // - d0->setName("d0"); d1->setName("d1"); d1_1->setName("d1_1"); d2->setName("d2"); d4->setName("d4"); - d0->setInfoOnComponent(0,"c1"); - d1->setInfoOnComponent(0,"c6"); - d1_1->setInfoOnComponent(0,"c9"); - d2->setInfoOnComponent(0,"c5"); - d4->setInfoOnComponent(0,"c7"); - // - ParaMEDMEM::MEDCouplingFieldDouble *f0=ParaMEDMEM::MEDCouplingFieldDouble::New(ParaMEDMEM::ON_CELLS,ParaMEDMEM::ONE_TIME); - f0->setMesh(m1); - f0->setArray(d0); - f0->setTime(0.2,5,6); - f0->setName("f0"); - ParaMEDMEM::MEDCouplingFieldDouble *f1=ParaMEDMEM::MEDCouplingFieldDouble::New(ParaMEDMEM::ON_NODES,ParaMEDMEM::LINEAR_TIME); - f1->setMesh(m1); - std::vector d1s(2); d1s[0]=d1; d1s[1]=d1_1; - f1->setArrays(d1s); - f1->setStartTime(0.7,7,8); - f1->setEndTime(1.2,9,10); - f1->setName("f1"); - ParaMEDMEM::MEDCouplingFieldDouble *f2=ParaMEDMEM::MEDCouplingFieldDouble::New(ParaMEDMEM::ON_CELLS,ParaMEDMEM::CONST_ON_TIME_INTERVAL); - f2->setMesh(m2); - f2->setArray(d2); - f2->setTime(1.2,11,12); - f2->setEndTime(1.5,13,14); - f2->setName("f2"); - ParaMEDMEM::MEDCouplingFieldDouble *f3=ParaMEDMEM::MEDCouplingFieldDouble::New(ParaMEDMEM::ON_CELLS,ParaMEDMEM::ONE_TIME); - f3->setMesh(m1); - f3->setArray(d2); - f3->setTime(1.7,15,16); - f3->setName("f3"); - ParaMEDMEM::MEDCouplingFieldDouble *f4=ParaMEDMEM::MEDCouplingFieldDouble::New(ParaMEDMEM::ON_CELLS,ParaMEDMEM::NO_TIME); - f4->setMesh(m2); - f4->setArray(d4); - f4->setName("f4"); - // - std::vector fs(5); - fs[0]=f0; fs[1]=f1; fs[2]=f2; fs[3]=f3; fs[4]=f4; - ParaMEDMEM::MEDCouplingMultiFields *ret=ParaMEDMEM::MEDCouplingMultiFields::New(fs); - // - m1->decrRef(); - m2->decrRef(); - d0->decrRef(); - d1->decrRef(); - d1_1->decrRef(); - d2->decrRef(); - d4->decrRef(); - f0->decrRef(); - f1->decrRef(); - f2->decrRef(); - f3->decrRef(); - f4->decrRef(); - // - return ret; -} - -std::vector MEDCouplingBasicsTest::buildMultiFields_2() -{ - ParaMEDMEM::MEDCouplingUMesh *m1=build2DTargetMesh_1(); - m1->setName("m1"); - ParaMEDMEM::MEDCouplingUMesh *m2=build2DTargetMesh_1(); - m2->setName("m2"); - const double vals0[]={-0.7,-1.,-2.,-3.,-4.}; - const double vals1[]={0.,1.,2.,3.,4.}; - const double vals1_1[]={170.,171.,172.,173.,174.}; - const double vals2[]={5.,6.,7.,8.,9.}; - const double vals4[]={15.,16.,17.,18.,19.}; - // - ParaMEDMEM::DataArrayDouble *d0=ParaMEDMEM::DataArrayDouble::New(); d0->alloc(5,1); std::copy(vals0,vals0+5,d0->getPointer()); - ParaMEDMEM::DataArrayDouble *d1=ParaMEDMEM::DataArrayDouble::New(); d1->alloc(5,1); std::copy(vals1,vals1+5,d1->getPointer()); - ParaMEDMEM::DataArrayDouble *d1_1=ParaMEDMEM::DataArrayDouble::New(); d1_1->alloc(5,1); std::copy(vals1_1,vals1_1+5,d1_1->getPointer()); - ParaMEDMEM::DataArrayDouble *d2=ParaMEDMEM::DataArrayDouble::New(); d2->alloc(5,1); std::copy(vals2,vals2+5,d2->getPointer()); - ParaMEDMEM::DataArrayDouble *d4=ParaMEDMEM::DataArrayDouble::New(); d4->alloc(5,1); std::copy(vals4,vals4+5,d4->getPointer()); - // - d0->setName("d0"); d1->setName("d1"); d1_1->setName("d1_1"); d2->setName("d2"); d4->setName("d4"); - d0->setInfoOnComponent(0,"c1"); - d1->setInfoOnComponent(0,"c6"); - d1_1->setInfoOnComponent(0,"c9"); - d2->setInfoOnComponent(0,"c5"); - d4->setInfoOnComponent(0,"c7"); - // - ParaMEDMEM::MEDCouplingFieldDouble *f0=ParaMEDMEM::MEDCouplingFieldDouble::New(ParaMEDMEM::ON_CELLS,ParaMEDMEM::ONE_TIME); - f0->setMesh(m1); - f0->setArray(d0); - f0->setTime(0.2,5,6); - f0->setName("f0"); - ParaMEDMEM::MEDCouplingFieldDouble *f1=ParaMEDMEM::MEDCouplingFieldDouble::New(ParaMEDMEM::ON_CELLS,ParaMEDMEM::LINEAR_TIME); - f1->setMesh(m1); - std::vector d1s(2); d1s[0]=d1; d1s[1]=d1_1; - f1->setArrays(d1s); - f1->setStartTime(0.7,7,8); - f1->setEndTime(1.2,9,10); - f1->setName("f1"); - ParaMEDMEM::MEDCouplingFieldDouble *f2=ParaMEDMEM::MEDCouplingFieldDouble::New(ParaMEDMEM::ON_CELLS,ParaMEDMEM::CONST_ON_TIME_INTERVAL); - f2->setMesh(m2); - f2->setArray(d2); - f2->setTime(1.2,11,12); - f2->setEndTime(1.5,13,14); - f2->setName("f2"); - ParaMEDMEM::MEDCouplingFieldDouble *f3=ParaMEDMEM::MEDCouplingFieldDouble::New(ParaMEDMEM::ON_CELLS,ParaMEDMEM::ONE_TIME); - f3->setMesh(m1); - f3->setArray(d2); - f3->setTime(1.7,15,16); - f3->setName("f3"); - ParaMEDMEM::MEDCouplingFieldDouble *f4=ParaMEDMEM::MEDCouplingFieldDouble::New(ParaMEDMEM::ON_CELLS,ParaMEDMEM::NO_TIME); - f4->setMesh(m2); - f4->setArray(d4); - f4->setName("f4"); - // - std::vector fs(5); - fs[0]=f0; fs[1]=f1; fs[2]=f2; fs[3]=f3; fs[4]=f4; - m1->decrRef(); - m2->decrRef(); - d0->decrRef(); - d1->decrRef(); - d1_1->decrRef(); - d2->decrRef(); - d4->decrRef(); - // - return fs; -} - -MEDCouplingUMesh *MEDCouplingBasicsTest::build1DMultiTypes_1() -{ - MEDCouplingUMesh *mesh=MEDCouplingUMesh::New("Multi1DMesh",1); - DataArrayDouble *coo=buildCoordsForMultiTypes_1(); - const int conn[5]={0,2, 0,2,1}; - mesh->allocateCells(2); - mesh->insertNextCell(INTERP_KERNEL::NORM_SEG2,2,conn); - mesh->insertNextCell(INTERP_KERNEL::NORM_SEG3,3,conn+2); - mesh->finishInsertingCells(); - mesh->setCoords(coo); - coo->decrRef(); - return mesh; -} - -MEDCouplingUMesh *MEDCouplingBasicsTest::build2DMultiTypes_1() -{ - MEDCouplingUMesh *mesh=MEDCouplingUMesh::New("Multi2DMesh",2); - DataArrayDouble *coo=buildCoordsForMultiTypes_1(); - const int conn[21]={3,4,5, 3,4,5,6,7,8, 0,9,10,11, 0,9,10,11,12,13,14,15}; - mesh->allocateCells(4); - mesh->insertNextCell(INTERP_KERNEL::NORM_TRI3,3,conn); - mesh->insertNextCell(INTERP_KERNEL::NORM_TRI6,6,conn+3); - mesh->insertNextCell(INTERP_KERNEL::NORM_QUAD4,4,conn+9); - mesh->insertNextCell(INTERP_KERNEL::NORM_QUAD8,8,conn+13); - mesh->finishInsertingCells(); - mesh->setCoords(coo); - coo->decrRef(); - return mesh; -} - -MEDCouplingUMesh *MEDCouplingBasicsTest::build3DMultiTypes_1() -{ - MEDCouplingUMesh *mesh=MEDCouplingUMesh::New("Multi3DMesh",3); - DataArrayDouble *coo=buildCoordsForMultiTypes_1(); - const int conn[81]={0,16,17,18, - 0,16,17,18,19,20,21,22,23,24, - 0,11,10,9,25, - 0,11,10,9,25,15,14,13,12,26,27,28,29, - 0,30,31,32,33,34, - 0,30,31,32,33,34,35,36,37,38,39,40,41,42,43, - 0,9,10,11,44,45,46,47, - 0,9,10,11,44,45,46,47,12,13,14,15,48,49,50,51,52,53,54,55 }; - mesh->allocateCells(8); - mesh->insertNextCell(INTERP_KERNEL::NORM_TETRA4,4,conn); - mesh->insertNextCell(INTERP_KERNEL::NORM_TETRA10,10,conn+4); - mesh->insertNextCell(INTERP_KERNEL::NORM_PYRA5,5,conn+14); - mesh->insertNextCell(INTERP_KERNEL::NORM_PYRA13,13,conn+19); - mesh->insertNextCell(INTERP_KERNEL::NORM_PENTA6,6,conn+32); - mesh->insertNextCell(INTERP_KERNEL::NORM_PENTA15,15,conn+38); - mesh->insertNextCell(INTERP_KERNEL::NORM_HEXA8,8,conn+53); - mesh->insertNextCell(INTERP_KERNEL::NORM_HEXA20,20,conn+61); - mesh->finishInsertingCells(); - mesh->setCoords(coo); - coo->decrRef(); - return mesh; -} - -DataArrayDouble *MEDCouplingBasicsTest::buildCoordsForMultiTypes_1() -{ - DataArrayDouble *coords=DataArrayDouble::New(); - coords->alloc(56,3); - coords->setInfoOnComponent(0,"X (cm)"); - coords->setInfoOnComponent(1,"Y (cm)"); - coords->setInfoOnComponent(2,"Z (cm)"); - const double data[168]={ - 0.0, 0.0, 0.0, //#0 - 0.5, 0.5, 0.5, //#1 - 1.0, 1.0, 1.0, //#2 - 1.0, 1.0, 0.0, //#3 - 2.0, 2.5, 0.0, //#4 - 6.0, 1.5, 0.0, //#5 - 1.0, 2.0, 0.0, //#6 - 4.5, 2.5, 0.0, //#7 - 4.0, 0.5, 0.0, //#8 - 0.0, 4.0, 0.0, //#9 - 4.0, 4.0, 0.0, //#10 - 4.0, 0.0, 0.0, //#11 - 0.0, 2.0, 0.0, //#12 - 2.0, 4.0, 0.0, //#13 - 4.0, 2.0, 0.0, //#14 - 2.0, 0.0, 0.0, //#15 - 0.0, 6.0, 0.0, //#16 - 3.0, 3.0, 0.0, //#17 - 1.3, 3.0, 3.0, //#18 - 0.0, 3.0, 0.0, //#19 - 1.5, 4.5, 0.0, //#20 - 1.5, 1.5, 0.0, //#21 - 0.65, 1.5, 1.5, //#22 - 0.65, 4.5, 1.5, //#23 - 2.15, 3.0, 1.5, //#24 - 2.0, 2.0, 2.0, //#25 - 3.0, 1.0, 1.0, //#26 - 3.0, 3.0, 1.0, //#27 - 1.0, 3.0, 1.0, //#28 - 1.0, 1.0, 1.0, //#29 - 0.0, 3.0, 0.0, //#30 - 2.0, 0.0, 0.0, //#31 - 0.0, 0.0, 6.0, //#32 - 0.0, 3.0, 6.0, //#33 - 3.0, 0.0, 6.0, //#34 - 0.0, 1.5, 0.0, //#35 - 1.5, 1.5, 0.0, //#36 - 1.5, 0.0, 0.0, //#37 - 0.0, 1.5, 6.0, //#38 - 1.5, 1.5, 6.0, //#39 - 1.5, 0.0, 6.0, //#40 - 0.0, 0.0, 3.0, //#41 - 0.0, 3.0, 3.0, //#42 - 3.0, 0.0, 3.0, //#43 - 0.0, 0.0, 4.0, //#44 - 0.0, 4.0, 4.0, //#45 - 4.0, 4.0, 4.0, //#46 - 4.0, 0.0, 4.0, //#47 - 0.0, 2.0, 4.0, //#48 - 2.0, 4.0, 4.0, //#49 - 4.0, 2.0, 4.0, //#50 - 2.0, 0.0, 4.0, //#51 - 0.0, 0.0, 2.0, //#52 - 0.0, 4.0, 2.0, //#53 - 4.0, 4.0, 2.0, //#54 - 4.0, 0.0, 2.0 //#55 - }; - std::copy(data,data+168,coords->getPointer()); - return coords; -} - -MEDCouplingUMesh *MEDCouplingBasicsTest::buildHexa8Mesh_1() -{ - MEDCouplingUMesh *mesh=MEDCouplingUMesh::New("Hexa8Only",3); - DataArrayDouble *coo=DataArrayDouble::New(); - const double coords[81]={0.0, 0.0, 0.0, 0.5, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.5, 0.0, 0.5, 0.5, 0.0, 1.0, 0.5, 0.0, 0.0, 1.0, 0.0, 0.5, 1.0, 0.0, 1.0, 1.0, 0.0, 0.0, 0.0, 0.5, 0.5, 0.0, 0.5, 1.0, 0.0, 0.5, 0.0, 0.5, 0.5, 0.5, 0.5, 0.5, 1.0, 0.5, 0.5, 0.0, 1.0, 0.5, 0.5, 1.0, 0.5, 1.0, 1.0, 0.5, 0.0, 0.0, 1.0, 0.5, 0.0, 1.0, 1.0, 0.0, 1.0, 0.0, 0.5, 1.0, 0.5, 0.5, 1.0, 1.0, 0.5, 1.0, 0.0, 1.0, 1.0, 0.5, 1.0, 1.0, 1.0, 1.0, 1.0}; - coo->alloc(27,3); - std::copy(coords,coords+81,coo->getPointer()); - const int conn[64]={3,12,13,4,0,9,10,1, - 4,13,14,5,1,10,11,2, - 6,15,16,7,3,12,13,4, - 7,16,17,8,4,13,14,5, - 12,21,22,13,9,18,19,10, - 13,22,23,14,10,19,20,11, - 15,24,25,16,12,21,22,13, - 16,25,26,17,13,22,23,14}; - mesh->allocateCells(8); - for(int i=0;i<8;i++) - mesh->insertNextCell(INTERP_KERNEL::NORM_HEXA8,8,conn+8*i); - mesh->finishInsertingCells(); - mesh->setCoords(coo); - coo->decrRef(); - return mesh; -} - -MEDCouplingUMesh *MEDCouplingBasicsTest::buildPointe_1(MEDCouplingUMesh *& m1) -{ - MEDCouplingUMesh *mesh=MEDCouplingUMesh::New("Pointe.med",3); - MEDCouplingUMesh *mesh2=MEDCouplingUMesh::New("Pointe.med",2); - const double coords[57]={0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 2.0, 0.0, 1.0, 0.0, 2.0, 1.0, -2.0, 0.0, 1.0, 0.0, -2.0, 1.0, 1.0, 1.0, 2.0, -1.0, 1.0, 2.0, -1.0, -1.0, 2.0, 1.0, -1.0, 2.0, 1.0, 1.0, 3.0, -1.0, 1.0, 3.0, -1.0, -1.0, 3.0, 1.0, -1.0, 3.0, 1.0, 1.0, 4.0, -1.0, 1.0, 4.0, -1.0, -1.0, 4.0, 1.0, -1.0, 4.0, 0.0, 0.0, 5.0}; - const int conn[74]={0,1,2,5,0,1,3,2,0,1,4,3,0,1,5,4,1,6,3,2,1,7,4,3,1,8,5,4,1,9,2,5,1,6,2,9,1,7,3,6,1,8,4,7,1,9,5,8, 6,7,8,9,1,14,17,16,15,18, 10,11,12,13,6,7,8,9,14,15,16,17,10,11,12,13}; - DataArrayDouble *coo=DataArrayDouble::New(); - coo->alloc(19,3); - std::copy(coords,coords+57,coo->getPointer()); - mesh->setCoords(coo); - mesh2->setCoords(coo); - coo->decrRef(); - mesh->allocateCells(16); - for(int i=0;i<12;i++) - mesh->insertNextCell(INTERP_KERNEL::NORM_TETRA4,4,conn+4*i); - mesh->insertNextCell(INTERP_KERNEL::NORM_PYRA5,5,conn+48); - mesh->insertNextCell(INTERP_KERNEL::NORM_PYRA5,5,conn+53); - mesh->insertNextCell(INTERP_KERNEL::NORM_HEXA8,8,conn+58); - mesh->insertNextCell(INTERP_KERNEL::NORM_HEXA8,8,conn+66); - mesh->finishInsertingCells(); - //[1,34,29,23,41,32] - const int conn2[20]={0,5,1,14,18,17,8,7,4,9,5,2, 12,8,9,13,6,7,8,9}; - mesh2->allocateCells(6); - for(int i=0;i<4;i++) - mesh2->insertNextCell(INTERP_KERNEL::NORM_TRI3,3,conn2+3*i); - mesh2->insertNextCell(INTERP_KERNEL::NORM_QUAD4,4,conn2+12); - mesh2->insertNextCell(INTERP_KERNEL::NORM_QUAD4,4,conn2+16); - mesh2->finishInsertingCells(); - m1=mesh2; - // - return mesh; -} - -double MEDCouplingBasicsTest::sumAll(const std::vector< std::map >& matrix) -{ - double ret=0.; - for(std::vector< std::map >::const_iterator iter=matrix.begin();iter!=matrix.end();iter++) - for(std::map::const_iterator iter2=(*iter).begin();iter2!=(*iter).end();iter2++) - ret+=(*iter2).second; - return ret; -} - -MEDCouplingUMesh *MEDCouplingBasicsTest::build2D1DSourceMesh() -{ - double sourceCoords[18]={-17., 3., -17., 8., -5., 8., - -5., 3., -9., 0., -13., 3., - -9., 8., -7., 0., -7., 8. - }; - int sourceConn[16]={0,1, 1,2, 2,3, 3,0, 3,4, 4,5, 4,6, 7,8}; - MEDCouplingUMesh *sourceMesh=MEDCouplingUMesh::New(); - sourceMesh->setMeshDimension(1); - sourceMesh->allocateCells(8); - sourceMesh->insertNextCell(INTERP_KERNEL::NORM_SEG2,2,sourceConn); - sourceMesh->insertNextCell(INTERP_KERNEL::NORM_SEG2,2,sourceConn+2); - sourceMesh->insertNextCell(INTERP_KERNEL::NORM_SEG2,2,sourceConn+4); - sourceMesh->insertNextCell(INTERP_KERNEL::NORM_SEG2,2,sourceConn+6); - sourceMesh->insertNextCell(INTERP_KERNEL::NORM_SEG2,2,sourceConn+8); - sourceMesh->insertNextCell(INTERP_KERNEL::NORM_SEG2,2,sourceConn+10); - sourceMesh->insertNextCell(INTERP_KERNEL::NORM_SEG2,2,sourceConn+12); - sourceMesh->insertNextCell(INTERP_KERNEL::NORM_SEG2,2,sourceConn+14); - sourceMesh->finishInsertingCells(); - DataArrayDouble *myCoords=DataArrayDouble::New(); - myCoords->alloc(9,2); - std::copy(sourceCoords,sourceCoords+18,myCoords->getPointer()); - sourceMesh->setCoords(myCoords); - myCoords->decrRef(); - return sourceMesh; -} - -MEDCouplingUMesh *MEDCouplingBasicsTest::build2D1DTargetMesh() -{ - double targetCoords[10]={-17., 0., -17.,6., -9.,6., -9.,0., -5., 3.}; - int targetConn[7]={0,1,2,3, 2,3,4}; - MEDCouplingUMesh *targetMesh=MEDCouplingUMesh::New(); - targetMesh->setMeshDimension(2); - targetMesh->allocateCells(2); - targetMesh->insertNextCell(INTERP_KERNEL::NORM_QUAD4,4,targetConn); - targetMesh->insertNextCell(INTERP_KERNEL::NORM_TRI3 ,3,targetConn + 4); - targetMesh->finishInsertingCells(); - DataArrayDouble *myCoords=DataArrayDouble::New(); - myCoords->alloc(5,2); - std::copy(targetCoords,targetCoords+10,myCoords->getPointer()); - targetMesh->setCoords(myCoords); - myCoords->decrRef(); - return targetMesh; -} - -MEDCouplingUMesh* MEDCouplingBasicsTest::build2D1DSegSourceMesh(const double shiftX, - const double inclinationX) -{ - MEDCouplingUMesh *sourceMesh=MEDCouplingUMesh::New(); - sourceMesh->setMeshDimension(1); - - const int nbY = 4; - const int nbYP1 = nbY + 1; - sourceMesh->allocateCells(nbY); - - int sourceConn[2]; - for (int iY = 0; iY < nbY; ++iY) - { - sourceConn[0] = iY ; - sourceConn[1] = iY + 1; - sourceMesh->insertNextCell(INTERP_KERNEL::NORM_SEG2,2,sourceConn); - } - sourceMesh->finishInsertingCells(); - - std::vector sourceCoords; - for (int iY = 0; iY < nbYP1; ++iY) - { - sourceCoords.push_back(iY * inclinationX + shiftX); - sourceCoords.push_back(iY * 4.); - } - DataArrayDouble *myCoords=DataArrayDouble::New(); - myCoords->alloc(nbYP1,2); - std::copy(sourceCoords.begin(),sourceCoords.end(),myCoords->getPointer()); - sourceMesh->setCoords(myCoords); - myCoords->decrRef(); - - return sourceMesh; -} - -MEDCouplingUMesh* MEDCouplingBasicsTest::build2D1DQuadTargetMesh(const double inclinationX) -{ - MEDCouplingUMesh *targetMesh=MEDCouplingUMesh::New(); - targetMesh->setMeshDimension(2); - - const int nbX = 5; - const int nbY = 4; - const int nbXP1 = nbX + 1; - const int nbYP1 = nbY + 1; - targetMesh->allocateCells(nbX * nbY); - - int targetConn[4]; - for (int iX = 0; iX < nbX; ++iX) - { - for (int iY = 0; iY < nbY; ++iY) - { - targetConn[0] = iY + iX * nbYP1; - targetConn[1] = iY + 1 + iX * nbYP1; - targetConn[2] = iY + 1 + (iX + 1) * nbYP1; - targetConn[3] = iY + (iX + 1) * nbYP1; - targetMesh->insertNextCell(INTERP_KERNEL::NORM_QUAD4,4,targetConn); - } - } - targetMesh->finishInsertingCells(); - - std::vector targetCoords; - for (int iX = 0; iX < nbXP1; ++iX) - { - for (int iY = 0; iY < nbYP1; ++iY) - { - targetCoords.push_back(iX * 3. + iY * inclinationX); - targetCoords.push_back(iY * 4.); - } - } - DataArrayDouble *myCoords=DataArrayDouble::New(); - myCoords->alloc(nbXP1 * nbYP1, 2); - std::copy(targetCoords.begin(),targetCoords.end(),myCoords->getPointer()); - targetMesh->setCoords(myCoords); - myCoords->decrRef(); - - return targetMesh; -} - -MEDCouplingUMesh* MEDCouplingBasicsTest::build2D1DTriTargetMesh(const double inclinationX) -{ - MEDCouplingUMesh *targetMesh=MEDCouplingUMesh::New(); - targetMesh->setMeshDimension(2); - - const int nbX = 5; - const int nbY = 4; - const int nbXP1 = nbX + 1; - const int nbYP1 = nbY + 1; - targetMesh->allocateCells(nbX * nbY * 2); - - int targetConn[3]; - for (int iX = 0; iX < nbX; ++iX) - { - for (int iY = 0; iY < nbY; ++iY) - { - targetConn[0] = iY + iX * nbYP1; - targetConn[1] = iY + 1 + iX * nbYP1; - targetConn[2] = iY + 1 + (iX + 1) * nbYP1; - targetMesh->insertNextCell(INTERP_KERNEL::NORM_TRI3,3,targetConn); - targetConn[0] = iY + iX * nbYP1; - targetConn[1] = iY + 1 + (iX + 1) * nbYP1; - targetConn[2] = iY + (iX + 1) * nbYP1; - targetMesh->insertNextCell(INTERP_KERNEL::NORM_TRI3,3,targetConn); - } - } - targetMesh->finishInsertingCells(); - - std::vector targetCoords; - for (int iX = 0; iX < nbXP1; ++iX) - { - for (int iY = 0; iY < nbYP1; ++iY) - { - targetCoords.push_back(iX * 3. + iY * inclinationX); - targetCoords.push_back(iY * 4.); - } - } - DataArrayDouble *myCoords=DataArrayDouble::New(); - myCoords->alloc(nbXP1 * nbYP1, 2); - std::copy(targetCoords.begin(),targetCoords.end(),myCoords->getPointer()); - targetMesh->setCoords(myCoords); - myCoords->decrRef(); - - return targetMesh; -} - -MEDCouplingUMesh *MEDCouplingBasicsTest::build3D2DSourceMesh() -{ - double sourceCoords[63]={-12., 6., 10., -12.,10., 6., -16.,10. , 10., - -20., 0., 0., -12., 0., 0., -12., 0. , -4., -20.,0.,-4., - -20., 0., 10., -12., 0., 10., -20.,10. , 10., - -25., 5., -5., 5., 5., -5., 5., 5. , 25., -25.,5.,25., - -20., 0., 16., -18., 0., 16., -20., 2.5, 16., - -25., 0., -5., 5., 0., -5., 5., 0. , 25., -25.,0.,25. - }; - int sourceConn[25]={0,1,2, 3,4,5,6, 7,8,9, 10,11,12,13, 14,15,16, 3,4,8,7, 17,18,19,20}; - MEDCouplingUMesh *sourceMesh=MEDCouplingUMesh::New(); - sourceMesh->setMeshDimension(2); - sourceMesh->allocateCells(7); - sourceMesh->insertNextCell(INTERP_KERNEL::NORM_TRI3 ,3,sourceConn); - sourceMesh->insertNextCell(INTERP_KERNEL::NORM_QUAD4,4,sourceConn+3); - sourceMesh->insertNextCell(INTERP_KERNEL::NORM_TRI3 ,3,sourceConn+7); - sourceMesh->insertNextCell(INTERP_KERNEL::NORM_QUAD4,4,sourceConn+10); - sourceMesh->insertNextCell(INTERP_KERNEL::NORM_TRI3 ,3,sourceConn+14); - sourceMesh->insertNextCell(INTERP_KERNEL::NORM_QUAD4,4,sourceConn+17); - sourceMesh->insertNextCell(INTERP_KERNEL::NORM_QUAD4,4,sourceConn+21); - sourceMesh->finishInsertingCells(); - DataArrayDouble *myCoords=DataArrayDouble::New(); - myCoords->alloc(21,3); - std::copy(sourceCoords,sourceCoords+63,myCoords->getPointer()); - sourceMesh->setCoords(myCoords); - myCoords->decrRef(); - return sourceMesh; -} - -MEDCouplingUMesh *MEDCouplingBasicsTest::build3D2DTargetMesh() -{ - double targetCoords[45]={-20., 0., 0., -20.,10., 0., -12.,10., 0., - -12., 0., 0., -20., 0.,10., -20.,10.,10., - -12.,10.,10., -12., 0.,10., -20., 0.,18., - -20.,-5.,10., -20.,-5.,-4., -12.,-5.,-4., - -12.,-5.,10., -20., 0.,-4., -12., 0.,-4. - }; - int targetConn[20]={4,5,7,8, 0,3,2,1,4,7,6,5, 4,13,14,7,9,10,11,12}; - MEDCouplingUMesh *targetMesh=MEDCouplingUMesh::New(); - targetMesh->setMeshDimension(3); - targetMesh->allocateCells(3); - targetMesh->insertNextCell(INTERP_KERNEL::NORM_TETRA4,4,targetConn); - targetMesh->insertNextCell(INTERP_KERNEL::NORM_HEXA8,8,targetConn + 4); - targetMesh->insertNextCell(INTERP_KERNEL::NORM_HEXA8,8,targetConn + 12); - targetMesh->finishInsertingCells(); - DataArrayDouble *myCoords=DataArrayDouble::New(); - myCoords->alloc(15,3); - std::copy(targetCoords,targetCoords+45,myCoords->getPointer()); - targetMesh->setCoords(myCoords); - myCoords->decrRef(); - return targetMesh; -} - -MEDCouplingUMesh* MEDCouplingBasicsTest::build3D2DQuadSourceMesh(const double shiftX, - const double inclinationX) -{ - MEDCouplingUMesh *sourceMesh=MEDCouplingUMesh::New(); - sourceMesh->setMeshDimension(2); - - const int nbY = 4; - const int nbZ = 5; - const int nbYP1 = nbY + 1; - const int nbZP1 = nbZ + 1; - sourceMesh->allocateCells(nbY * nbZ); - - int sourceConn[4]; - for (int iY = 0; iY < nbY; ++iY) - { - for (int iZ = 0; iZ < nbZ; ++iZ) - { - sourceConn[0] = iZ + iY * nbZP1; - sourceConn[1] = iZ + 1 + iY * nbZP1; - sourceConn[2] = iZ + 1 + (iY + 1) * nbZP1; - sourceConn[3] = iZ + (iY + 1) * nbZP1; - sourceMesh->insertNextCell(INTERP_KERNEL::NORM_QUAD4,4,sourceConn); - } - } - sourceMesh->finishInsertingCells(); - - std::vector sourceCoords; - for (int iY = 0; iY < nbYP1; ++iY) - { - for (int iZ = 0; iZ < nbZP1; ++iZ) - { - sourceCoords.push_back(iY * inclinationX + shiftX); - sourceCoords.push_back(iY * 4.); - sourceCoords.push_back(iZ * 3.); - } - - } - DataArrayDouble *myCoords=DataArrayDouble::New(); - myCoords->alloc(nbYP1 * nbZP1,3); - std::copy(sourceCoords.begin(),sourceCoords.end(),myCoords->getPointer()); - sourceMesh->setCoords(myCoords); - myCoords->decrRef(); - - return sourceMesh; -} - -MEDCouplingUMesh* MEDCouplingBasicsTest::build3D2DTriSourceMesh(const double shiftX, - const double inclinationX) -{ - MEDCouplingUMesh *sourceMesh=MEDCouplingUMesh::New(); - sourceMesh->setMeshDimension(2); - - const int nbY = 4; - const int nbZ = 5; - const int nbYP1 = nbY + 1; - const int nbZP1 = nbZ + 1; - sourceMesh->allocateCells(nbY * nbZ * 2); - - int sourceConn[3]; - for (int iY = 0; iY < nbY; ++iY) - { - for (int iZ = 0; iZ < nbZ; ++iZ) - { - sourceConn[0] = iZ + iY * nbZP1; - sourceConn[1] = iZ + 1 + iY * nbZP1; - sourceConn[2] = iZ + 1 + (iY + 1) * nbZP1; - sourceMesh->insertNextCell(INTERP_KERNEL::NORM_TRI3,3,sourceConn); - sourceConn[0] = iZ + iY * nbZP1; - sourceConn[1] = iZ + (iY + 1) * nbZP1; - sourceConn[2] = iZ + 1 + (iY + 1) * nbZP1; - sourceMesh->insertNextCell(INTERP_KERNEL::NORM_TRI3,3,sourceConn); - } - } - sourceMesh->finishInsertingCells(); - - std::vector sourceCoords; - for (int iY = 0; iY < nbYP1; ++iY) - { - for (int iZ = 0; iZ < nbZP1; ++iZ) - { - sourceCoords.push_back(iY * inclinationX + shiftX); - sourceCoords.push_back(iY * 4.); - sourceCoords.push_back(iZ * 3.); - } - - } - DataArrayDouble *myCoords=DataArrayDouble::New(); - myCoords->alloc(nbYP1 * nbZP1,3); - std::copy(sourceCoords.begin(),sourceCoords.end(),myCoords->getPointer()); - sourceMesh->setCoords(myCoords); - myCoords->decrRef(); - - return sourceMesh; -} - -MEDCouplingUMesh* MEDCouplingBasicsTest::build3D2DHexaTargetMesh(const double inclinationX) -{ - MEDCouplingUMesh *targetMesh=MEDCouplingUMesh::New(); - targetMesh->setMeshDimension(3); - - const int nbX = 5; - const int nbY = 4; - const int nbZ = 5; - const int nbXP1 = nbX + 1; - const int nbYP1 = nbY + 1; - const int nbZP1 = nbZ + 1; - targetMesh->allocateCells(nbX * nbY * nbZ); - - int targetConn[8]; - for (int iX = 0; iX < nbX; ++iX) - { - for (int iY = 0; iY < nbY; ++iY) - { - for (int iZ = 0; iZ < nbZ; ++iZ) - { - targetConn[0] = iZ + ( iY + iX * nbYP1) * nbZP1; - targetConn[1] = iZ + 1 + ( iY + iX * nbYP1) * nbZP1; - targetConn[2] = iZ + 1 + ((iY + 1) + iX * nbYP1) * nbZP1; - targetConn[3] = iZ + ((iY + 1) + iX * nbYP1) * nbZP1; - targetConn[4] = iZ + ( iY + (iX + 1) * nbYP1) * nbZP1; - targetConn[5] = iZ + 1 + ( iY + (iX + 1) * nbYP1) * nbZP1; - targetConn[6] = iZ + 1 + ((iY + 1) + (iX + 1) * nbYP1) * nbZP1; - targetConn[7] = iZ + ((iY + 1) + (iX + 1) * nbYP1) * nbZP1; - targetMesh->insertNextCell(INTERP_KERNEL::NORM_HEXA8,8,targetConn); - } - } - } - targetMesh->finishInsertingCells(); - - std::vector targetCoords; - for (int iX = 0; iX < nbXP1; ++iX) - { - for (int iY = 0; iY < nbYP1; ++iY) - { - for (int iZ = 0; iZ < nbZP1; ++iZ) - { - targetCoords.push_back(iX * 3. + iY * inclinationX); - targetCoords.push_back(iY * 4.); - targetCoords.push_back(iZ * 3.); - } - } - } - DataArrayDouble *myCoords=DataArrayDouble::New(); - myCoords->alloc(nbXP1 * nbYP1 * nbZP1, 3); - std::copy(targetCoords.begin(),targetCoords.end(),myCoords->getPointer()); - targetMesh->setCoords(myCoords); - myCoords->decrRef(); - - return targetMesh; -} - -MEDCouplingUMesh* MEDCouplingBasicsTest::build3D2DTetraTargetMesh(const double inclinationX) -{ - MEDCouplingUMesh *targetMesh=MEDCouplingUMesh::New(); - targetMesh->setMeshDimension(3); - - const int nbX = 5; - const int nbY = 4; - const int nbZ = 5; - const int nbXP1 = nbX + 1; - const int nbYP1 = nbY + 1; - const int nbZP1 = nbZ + 1; - targetMesh->allocateCells(nbX * nbY * nbZ * 5); - - int targetConn[4]; - for (int iX = 0; iX < nbX; ++iX) - { - for (int iY = 0; iY < nbY; ++iY) - { - for (int iZ = 0; iZ < nbZ; ++iZ) - { - targetConn[0] = iZ + ( iY + iX * nbYP1) * nbZP1; - targetConn[1] = iZ + 1 + ( iY + iX * nbYP1) * nbZP1; - targetConn[2] = iZ + 1 + ( iY + (iX + 1) * nbYP1) * nbZP1; - targetConn[3] = iZ + 1 + ((iY + 1) + iX * nbYP1) * nbZP1; - targetMesh->insertNextCell(INTERP_KERNEL::NORM_TETRA4,4,targetConn); - targetConn[0] = iZ + ( iY + iX * nbYP1) * nbZP1; - targetConn[1] = iZ + ( iY + (iX + 1) * nbYP1) * nbZP1; - targetConn[2] = iZ + 1 + ( iY + (iX + 1) * nbYP1) * nbZP1; - targetConn[3] = iZ + ((iY + 1) + (iX + 1) * nbYP1) * nbZP1; - targetMesh->insertNextCell(INTERP_KERNEL::NORM_TETRA4,4,targetConn); - targetConn[0] = iZ + ( iY + iX * nbYP1) * nbZP1; - targetConn[1] = iZ + ((iY + 1) + iX * nbYP1) * nbZP1; - targetConn[2] = iZ + ((iY + 1) + (iX + 1) * nbYP1) * nbZP1; - targetConn[3] = iZ + 1 + ((iY + 1) + iX * nbYP1) * nbZP1; - targetMesh->insertNextCell(INTERP_KERNEL::NORM_TETRA4,4,targetConn); - targetConn[0] = iZ + 1 + ( iY + (iX + 1) * nbYP1) * nbZP1; - targetConn[1] = iZ + 1 + ((iY + 1) + (iX + 1) * nbYP1) * nbZP1; - targetConn[2] = iZ + ((iY + 1) + (iX + 1) * nbYP1) * nbZP1; - targetConn[3] = iZ + 1 + ((iY + 1) + iX * nbYP1) * nbZP1; - targetMesh->insertNextCell(INTERP_KERNEL::NORM_TETRA4,4,targetConn); - targetConn[0] = iZ + ( iY + iX * nbYP1) * nbZP1; - targetConn[1] = iZ + 1 + ((iY + 1) + iX * nbYP1) * nbZP1; - targetConn[2] = iZ + 1 + ( iY + (iX + 1) * nbYP1) * nbZP1; - targetConn[3] = iZ + ((iY + 1) + (iX + 1) * nbYP1) * nbZP1; - targetMesh->insertNextCell(INTERP_KERNEL::NORM_TETRA4,4,targetConn); - } - } - } - targetMesh->finishInsertingCells(); - - std::vector targetCoords; - for (int iX = 0; iX < nbXP1; ++iX) - { - for (int iY = 0; iY < nbYP1; ++iY) - { - for (int iZ = 0; iZ < nbZP1; ++iZ) - { - targetCoords.push_back(iX * 3. + iY * inclinationX); - targetCoords.push_back(iY * 4.); - targetCoords.push_back(iZ * 3.); - } - } - } - DataArrayDouble *myCoords=DataArrayDouble::New(); - myCoords->alloc(nbXP1 * nbYP1 * nbZP1, 3); - std::copy(targetCoords.begin(),targetCoords.end(),myCoords->getPointer()); - targetMesh->setCoords(myCoords); - myCoords->decrRef(); - - return targetMesh; -} - -int MEDCouplingBasicsTest::countNonZero(const std::vector< std::map >& matrix) -{ - int ret=0.; - for(std::vector< std::map >::const_iterator iter=matrix.begin();iter!=matrix.end();iter++) - for(std::map::const_iterator iter2=(*iter).begin();iter2!=(*iter).end();iter2++) - if (!INTERP_KERNEL::epsilonEqual((*iter2).second, 0.)) ret +=1; - return ret; -} - -void MEDCouplingBasicsTest::test2D1DMeshesIntersection(MEDCouplingUMesh *sourceMesh, - MEDCouplingUMesh *targetMesh, - const double correctLength, - const int correctDuplicateFacesNbr, - const int correctTotalIntersectFacesNbr) -{ - MEDCouplingNormalizedUnstructuredMesh<2,2> sourceWrapper(sourceMesh); - MEDCouplingNormalizedUnstructuredMesh<2,2> targetWrapper(targetMesh); - INTERP_KERNEL::Interpolation2D1D myInterpolator; - myInterpolator.setPrecision(1e-12); - const double prec = 1.0e-5; - IntersectionMatrix matrix; - myInterpolator.setIntersectionType(INTERP_KERNEL::Geometric2D); - myInterpolator.interpolateMeshes(sourceWrapper,targetWrapper,matrix,"P0P0"); - - std::cout.precision(16); - - const double length = sumAll(matrix); - LOG(1, "length = " << surf <<" correctLength = " << correctLength ); - CPPUNIT_ASSERT_DOUBLES_EQUAL(correctLength, length, prec * std::max(correctLength, length)); - - INTERP_KERNEL::Interpolation3D2D::DuplicateFacesType duplicateFaces = myInterpolator.retrieveDuplicateFaces(); - int duplicateFacesNbr = duplicateFaces.size(); - LOG(1, "duplicateFacesNbr = " << duplicateFacesNbr <<" correctDuplicateFacesNbr = " << correctDuplicateFacesNbr); - CPPUNIT_ASSERT_EQUAL(correctDuplicateFacesNbr, duplicateFacesNbr); - - if (correctTotalIntersectFacesNbr >= 0) - { - int totalIntersectFacesNbr = countNonZero(matrix); - LOG(1, "totalIntersectFacesNbr = " << totalIntersectFacesNbr <<" correctTotalIntersectFacesNbr = " << correctTotalIntersectFacesNbr ); - CPPUNIT_ASSERT_EQUAL(correctTotalIntersectFacesNbr, totalIntersectFacesNbr); - } - //clean up - sourceMesh->decrRef(); - targetMesh->decrRef(); -} - -void MEDCouplingBasicsTest::test3D2DMeshesIntersection(MEDCouplingUMesh *sourceMesh, - MEDCouplingUMesh *targetMesh, - const double correctSurf, - const int correctDuplicateFacesNbr, - const int correctTotalIntersectFacesNbr) -{ - MEDCouplingNormalizedUnstructuredMesh<3,3> sourceWrapper(sourceMesh); - MEDCouplingNormalizedUnstructuredMesh<3,3> targetWrapper(targetMesh); - INTERP_KERNEL::Interpolation3D2D myInterpolator; - myInterpolator.setPrecision(1e-12); - const double prec = 1.0e-5; - IntersectionMatrix matrix; - INTERP_KERNEL::SplittingPolicy sp[] = { INTERP_KERNEL::PLANAR_FACE_5, INTERP_KERNEL::PLANAR_FACE_6, INTERP_KERNEL::GENERAL_24, INTERP_KERNEL::GENERAL_48 }; - for ( size_t i = 0; i < sizeof(sp)/sizeof(sp[0]); ++i ) - { - myInterpolator.setSplittingPolicy( sp[i] ); - matrix.clear(); - myInterpolator.interpolateMeshes(sourceWrapper,targetWrapper,matrix,"P0P0"); - - std::cout.precision(16); - - const double surf = sumAll(matrix); - LOG(1, "surf = " << surf <<" correctSurf = " << correctSurf ); - CPPUNIT_ASSERT_DOUBLES_EQUAL(correctSurf, surf, prec * std::max(correctSurf, surf)); - - INTERP_KERNEL::Interpolation3D2D::DuplicateFacesType duplicateFaces = myInterpolator.retrieveDuplicateFaces(); - int duplicateFacesNbr = duplicateFaces.size(); - LOG(1, "duplicateFacesNbr = " << duplicateFacesNbr <<" correctDuplicateFacesNbr = " << correctDuplicateFacesNbr); - CPPUNIT_ASSERT_EQUAL(correctDuplicateFacesNbr, duplicateFacesNbr); - - if (correctTotalIntersectFacesNbr >= 0) - { - int totalIntersectFacesNbr = countNonZero(matrix); - LOG(1, "totalIntersectFacesNbr = " << totalIntersectFacesNbr <<" correctTotalIntersectFacesNbr = " << correctTotalIntersectFacesNbr ); - CPPUNIT_ASSERT_EQUAL(correctTotalIntersectFacesNbr, totalIntersectFacesNbr); - } - } - //clean up - sourceMesh->decrRef(); - targetMesh->decrRef(); -} diff --git a/src/MEDCoupling/Test/MEDCouplingBasicsTest1.cxx b/src/MEDCoupling/Test/MEDCouplingBasicsTest1.cxx deleted file mode 100644 index 49d3ed779..000000000 --- a/src/MEDCoupling/Test/MEDCouplingBasicsTest1.cxx +++ /dev/null @@ -1,2694 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 -// 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 "MEDCouplingBasicsTest1.hxx" -#include "MEDCouplingUMesh.hxx" -#include "MEDCouplingCMesh.hxx" -#include "MEDCouplingExtrudedMesh.hxx" -#include "MEDCouplingFieldDouble.hxx" -#include "MEDCouplingMemArray.hxx" - -#include -#include -#include -#include - -using namespace ParaMEDMEM; - -void MEDCouplingBasicsTest1::testArray() -{ - int tmp1[6]={7,6,5,4,3,2}; - const int tmp2[3]={8,9,10}; - { - MemArray mem; - mem.useArray(tmp1,false,CPP_DEALLOC,6); - CPPUNIT_ASSERT(tmp1==mem.getConstPointer()); - CPPUNIT_ASSERT_THROW(mem.getPointer(),INTERP_KERNEL::Exception); - CPPUNIT_ASSERT_THROW(mem[2]=7,INTERP_KERNEL::Exception); - CPPUNIT_ASSERT_THROW(mem.writeOnPlace(0,12,tmp2,3),INTERP_KERNEL::Exception); - mem.writeOnPlace(4,12,tmp2,3); - } - { - int *tmp3=new int[6]; - std::copy(tmp1,tmp1+6,tmp3); - MemArray mem2; - mem2.useArray(tmp3,true,CPP_DEALLOC,6); - CPPUNIT_ASSERT(tmp3==mem2.getConstPointer()); - CPPUNIT_ASSERT(tmp3==mem2.getPointer()); - CPPUNIT_ASSERT_EQUAL(5,mem2[2]); - mem2[2]=7; - CPPUNIT_ASSERT_EQUAL(7,mem2[2]); - mem2.writeOnPlace(0,12,tmp2,3); - CPPUNIT_ASSERT_EQUAL(9,mem2[2]); - CPPUNIT_ASSERT_EQUAL(12,mem2[0]); - mem2.writeOnPlace(4,12,tmp2,3); - } -} - -void MEDCouplingBasicsTest1::testArray2() -{ - DataArrayDouble *arr=DataArrayDouble::New(); - arr->alloc(3,4); - double *tmp=arr->getPointer(); - const double arrRef[12]={12.,11.,10.,9.,8.,7.,6.,5.,4.,3.,2.,1.}; - std::copy(arrRef,arrRef+12,tmp); - arr->setInfoOnComponent(0,"ggg"); - arr->setInfoOnComponent(1,"hhhh"); - arr->setInfoOnComponent(2,"jj"); - arr->setInfoOnComponent(3,"kkkkkk"); - DataArrayInt *arr2=arr->convertToIntArr(); - DataArrayDouble *arr3=arr2->convertToDblArr(); - arr2->decrRef(); - CPPUNIT_ASSERT(arr->isEqual(*arr3,1e-14)); - arr3->decrRef(); - arr->decrRef(); -} - -void MEDCouplingBasicsTest1::testArray3() -{ - DataArrayInt *arr1=DataArrayInt::New(); - arr1->alloc(7,2); - int *tmp=arr1->getPointer(); - const int arr1Ref[14]={0,10,1,11,2,12,3,13,4,14,5,15,6,16}; - std::copy(arr1Ref,arr1Ref+14,tmp); - CPPUNIT_ASSERT_EQUAL(7,arr1->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(2,arr1->getNumberOfComponents()); - CPPUNIT_ASSERT(std::equal(arr1Ref,arr1Ref+14,arr1->getConstPointer())); - DataArrayInt *arr2=arr1->substr(3); - CPPUNIT_ASSERT_EQUAL(4,arr2->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(2,arr2->getNumberOfComponents()); - CPPUNIT_ASSERT(std::equal(arr1Ref+6,arr1Ref+14,arr2->getConstPointer())); - arr2->decrRef(); - DataArrayInt *arr3=arr1->substr(2,5); - CPPUNIT_ASSERT_EQUAL(3,arr3->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(2,arr3->getNumberOfComponents()); - CPPUNIT_ASSERT(std::equal(arr1Ref+4,arr1Ref+10,arr3->getConstPointer())); - arr1->decrRef(); - arr3->decrRef(); - // - DataArrayDouble *arr4=DataArrayDouble::New(); - arr4->alloc(7,2); - double *tmp2=arr4->getPointer(); - const double arr4Ref[14]={0.8,10.8,1.9,11.9,2.1,12.1,3.2,13.2,4.3,14.3,5.4,15.4,6.5,16.5}; - std::copy(arr4Ref,arr4Ref+14,tmp2); - CPPUNIT_ASSERT_EQUAL(7,arr4->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(2,arr4->getNumberOfComponents()); - CPPUNIT_ASSERT(std::equal(arr4Ref,arr4Ref+14,arr4->getConstPointer())); - DataArrayDouble *arr5=arr4->substr(3); - CPPUNIT_ASSERT_EQUAL(4,arr5->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(2,arr5->getNumberOfComponents()); - CPPUNIT_ASSERT(std::equal(arr4Ref+6,arr4Ref+14,arr5->getConstPointer())); - arr5->decrRef(); - DataArrayDouble *arr6=arr4->substr(2,5); - CPPUNIT_ASSERT_EQUAL(3,arr6->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(2,arr6->getNumberOfComponents()); - CPPUNIT_ASSERT(std::equal(arr4Ref+4,arr4Ref+10,arr6->getConstPointer())); - arr4->decrRef(); - arr6->decrRef(); -} - -void MEDCouplingBasicsTest1::testMesh() -{ - const int nbOfCells=6; - const int nbOfNodes=12; - - double coords[3*nbOfNodes]={ - 0.024155, 0.04183768725682622, -0.305, 0.04831000000000001, -1.015761910347357e-17, -0.305, 0.09662000000000001, -1.832979297858306e-18, - -0.305, 0.120775, 0.04183768725682623, -0.305, 0.09662000000000001, 0.08367537451365245, -0.305, 0.04831000000000001, - 0.08367537451365246, -0.305, 0.024155, 0.04183768725682622, -0.2863, 0.04831000000000001, -1.015761910347357e-17, -0.2863, - 0.09662000000000001, -1.832979297858306e-18, -0.2863, 0.120775, 0.04183768725682623, -0.2863, 0.09662000000000001, 0.08367537451365245, - -0.2863, 0.04831000000000001, 0.08367537451365246, -0.2863, }; - - int tab4[4*nbOfCells]={ - 1, 2, 8, 7, 2, 3, 9, 8, 3, 4, 10, 9, 4, 5, 11, 10, 5, 0, 6, 11, - 0, 1, 7, 6, }; - CPPUNIT_ASSERT_EQUAL(MEDCouplingMesh::GetNumberOfNodesOfGeometricType(INTERP_KERNEL::NORM_TRI3),3); - CPPUNIT_ASSERT(MEDCouplingMesh::IsStaticGeometricType(INTERP_KERNEL::NORM_TRI3)); - CPPUNIT_ASSERT(MEDCouplingMesh::IsLinearGeometricType(INTERP_KERNEL::NORM_TRI3)); - CPPUNIT_ASSERT_EQUAL(MEDCouplingMesh::GetDimensionOfGeometricType(INTERP_KERNEL::NORM_TRI3),2); - CPPUNIT_ASSERT_EQUAL(std::string(MEDCouplingMesh::GetReprOfGeometricType(INTERP_KERNEL::NORM_TRI3)),std::string("NORM_TRI3")); - CPPUNIT_ASSERT_THROW(MEDCouplingMesh::GetNumberOfNodesOfGeometricType(INTERP_KERNEL::NORM_POLYGON),INTERP_KERNEL::Exception); - CPPUNIT_ASSERT(!MEDCouplingMesh::IsStaticGeometricType(INTERP_KERNEL::NORM_POLYGON)); - CPPUNIT_ASSERT(MEDCouplingMesh::IsLinearGeometricType(INTERP_KERNEL::NORM_POLYGON)); - CPPUNIT_ASSERT_EQUAL(MEDCouplingMesh::GetDimensionOfGeometricType(INTERP_KERNEL::NORM_POLYGON),2); - CPPUNIT_ASSERT_EQUAL(std::string(MEDCouplingMesh::GetReprOfGeometricType(INTERP_KERNEL::NORM_POLYGON)),std::string("NORM_POLYGON")); - CPPUNIT_ASSERT_EQUAL(MEDCouplingMesh::GetNumberOfNodesOfGeometricType(INTERP_KERNEL::NORM_TRI6),6); - CPPUNIT_ASSERT(MEDCouplingMesh::IsStaticGeometricType(INTERP_KERNEL::NORM_TRI6)); - CPPUNIT_ASSERT(!MEDCouplingMesh::IsLinearGeometricType(INTERP_KERNEL::NORM_TRI6)); - CPPUNIT_ASSERT_EQUAL(MEDCouplingMesh::GetDimensionOfGeometricType(INTERP_KERNEL::NORM_TRI6),2); - CPPUNIT_ASSERT_EQUAL(std::string(MEDCouplingMesh::GetReprOfGeometricType(INTERP_KERNEL::NORM_TRI6)),std::string("NORM_TRI6")); - MEDCouplingUMesh *mesh=MEDCouplingUMesh::New(); - mesh->setMeshDimension(2); - mesh->allocateCells(8); - const int *curConn=tab4; - for(int i=0;iinsertNextCell(INTERP_KERNEL::NORM_QUAD4,4,curConn); - mesh->finishInsertingCells(); - CPPUNIT_ASSERT_EQUAL((std::size_t)30,mesh->getNodalConnectivity()->getNbOfElems()); - CPPUNIT_ASSERT_EQUAL(nbOfCells,mesh->getNumberOfCells()); - //test 0 - no copy no ownership - DataArrayDouble *myCoords=DataArrayDouble::New(); - myCoords->useArray(coords,false,CPP_DEALLOC,nbOfNodes,3); - mesh->setCoords(myCoords); - mesh->setCoords(myCoords); - myCoords->decrRef(); - CPPUNIT_ASSERT_EQUAL(nbOfCells,mesh->getNumberOfCells()); - mesh->checkCoherency(); - //test 1 - no copy ownership C++ - myCoords=DataArrayDouble::New(); - double *tmp=new double[3*nbOfNodes]; - std::copy(coords,coords+3*nbOfNodes,tmp); - myCoords->useArray(tmp,true,CPP_DEALLOC,nbOfNodes,3); - mesh->setCoords(myCoords); - myCoords->decrRef(); - CPPUNIT_ASSERT_EQUAL(nbOfCells,mesh->getNumberOfCells()); - mesh->checkCoherency(); - //test 2 - no copy ownership C - myCoords=DataArrayDouble::New(); - tmp=(double *)malloc(3*nbOfNodes*sizeof(double)); - std::copy(coords,coords+3*nbOfNodes,tmp); - myCoords->useArray(tmp,true,C_DEALLOC,nbOfNodes,3); - mesh->setCoords(myCoords); - myCoords->decrRef(); - CPPUNIT_ASSERT_EQUAL(nbOfNodes,mesh->getNumberOfNodes()); - mesh->checkCoherency(); - //test 3 - copy. - myCoords=DataArrayDouble::New(); - myCoords->alloc(nbOfNodes,3); - tmp=myCoords->getPointer(); - std::copy(coords,coords+3*nbOfNodes,tmp); - // test 3 bis deepcopy - DataArrayDouble *myCoords2=DataArrayDouble::New(); - *myCoords2=*myCoords; - myCoords2->decrRef(); - // - mesh->setCoords(myCoords); - myCoords->decrRef(); - CPPUNIT_ASSERT_EQUAL(nbOfNodes,mesh->getNumberOfNodes()); - mesh->checkCoherency(); - CPPUNIT_ASSERT_EQUAL(3,mesh->getSpaceDimension()); - // test clone not recursively - MEDCouplingUMesh *mesh2=mesh->clone(false); - CPPUNIT_ASSERT(mesh2!=mesh); - mesh2->checkCoherency(); - CPPUNIT_ASSERT_EQUAL(nbOfCells,mesh2->getNumberOfCells()); - CPPUNIT_ASSERT_EQUAL(nbOfNodes,mesh2->getNumberOfNodes()); - CPPUNIT_ASSERT_EQUAL(3,mesh2->getSpaceDimension()); - CPPUNIT_ASSERT(mesh!=mesh2); - CPPUNIT_ASSERT(mesh->getCoords()==mesh2->getCoords()); - CPPUNIT_ASSERT_DOUBLES_EQUAL(-0.2863,mesh2->getCoords()->getIJ(11,2),1e-14); - CPPUNIT_ASSERT(mesh->getNodalConnectivity()==mesh2->getNodalConnectivity()); - CPPUNIT_ASSERT_EQUAL(3,mesh2->getNodalConnectivity()->getIJ(7,0)); - CPPUNIT_ASSERT(mesh->getNodalConnectivityIndex()==mesh2->getNodalConnectivityIndex()); - CPPUNIT_ASSERT_EQUAL(15,mesh2->getNodalConnectivityIndex()->getIJ(3,0)); - mesh2->decrRef(); - // test clone not recursively - MEDCouplingUMesh *mesh3=mesh->clone(true); - CPPUNIT_ASSERT(mesh3!=mesh); - mesh3->checkCoherency(); - CPPUNIT_ASSERT_EQUAL(nbOfCells,mesh3->getNumberOfCells()); - CPPUNIT_ASSERT_EQUAL(nbOfNodes,mesh3->getNumberOfNodes()); - CPPUNIT_ASSERT_EQUAL(3,mesh3->getSpaceDimension()); - CPPUNIT_ASSERT(mesh!=mesh3); - CPPUNIT_ASSERT(mesh->getCoords()!=mesh3->getCoords()); - CPPUNIT_ASSERT_DOUBLES_EQUAL(-0.2863,mesh3->getCoords()->getIJ(11,2),1e-14); - CPPUNIT_ASSERT(mesh->getNodalConnectivity()!=mesh3->getNodalConnectivity()); - CPPUNIT_ASSERT_EQUAL(3,mesh3->getNodalConnectivity()->getIJ(7,0)); - CPPUNIT_ASSERT(mesh->getNodalConnectivityIndex()!=mesh3->getNodalConnectivityIndex()); - CPPUNIT_ASSERT_EQUAL(15,mesh3->getNodalConnectivityIndex()->getIJ(3,0)); - mesh3->decrRef(); - //test 4 - Field on cells - MEDCouplingFieldDouble *fieldOnCells=MEDCouplingFieldDouble::New(ON_CELLS); - fieldOnCells->setMesh(mesh); - DataArrayDouble *array=DataArrayDouble::New(); - array->alloc(nbOfCells,9); - fieldOnCells->setArray(array); - tmp=array->getPointer(); - array->decrRef(); - std::fill(tmp,tmp+9*nbOfCells,7.); - //content of field changed -> declare it. - fieldOnCells->declareAsNew(); - fieldOnCells->checkCoherency(); - // testing clone of fields - no recursive - MEDCouplingFieldDouble *fieldOnCells2=fieldOnCells->clone(false); - CPPUNIT_ASSERT(fieldOnCells2!=fieldOnCells); - fieldOnCells2->checkCoherency(); - CPPUNIT_ASSERT_EQUAL(nbOfCells,fieldOnCells2->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(9,fieldOnCells2->getNumberOfComponents()); - CPPUNIT_ASSERT(fieldOnCells2->getArray()==fieldOnCells->getArray()); - CPPUNIT_ASSERT_DOUBLES_EQUAL(7.,fieldOnCells2->getArray()->getIJ(3,7),1e-14); - CPPUNIT_ASSERT(fieldOnCells2->getMesh()==fieldOnCells->getMesh()); - // testing clone of fields - recursive - MEDCouplingFieldDouble *fieldOnCells3=fieldOnCells->clone(true); - CPPUNIT_ASSERT(fieldOnCells3!=fieldOnCells); - fieldOnCells3->checkCoherency(); - CPPUNIT_ASSERT_EQUAL(nbOfCells,fieldOnCells3->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(9,fieldOnCells3->getNumberOfComponents()); - CPPUNIT_ASSERT(fieldOnCells3->getArray()!=fieldOnCells->getArray()); - CPPUNIT_ASSERT_DOUBLES_EQUAL(7.,fieldOnCells3->getArray()->getIJ(3,7),1e-14); - CPPUNIT_ASSERT(fieldOnCells3->getMesh()==fieldOnCells->getMesh()); - fieldOnCells2->decrRef(); - fieldOnCells3->decrRef(); - // - fieldOnCells->decrRef(); - //clean-up - mesh->decrRef(); -} - -void MEDCouplingBasicsTest1::testMeshPointsCloud() -{ - double targetCoords[27]={-0.3,-0.3,0.5, 0.2,-0.3,1., 0.7,-0.3,1.5, -0.3,0.2,0.5, 0.2,0.2,1., 0.7,0.2,1.5, -0.3,0.7,0.5, 0.2,0.7,1., 0.7,0.7,1.5}; - const int targetConn[]={0,1,2,3,4,5,7,6}; - MEDCouplingUMesh *targetMesh=MEDCouplingUMesh::New(); - targetMesh->setMeshDimension(0); - targetMesh->allocateCells(8); - targetMesh->insertNextCell(INTERP_KERNEL::NORM_POINT1,1,targetConn); - targetMesh->insertNextCell(INTERP_KERNEL::NORM_POINT1,1,targetConn+1); - targetMesh->insertNextCell(INTERP_KERNEL::NORM_POINT1,1,targetConn+2); - targetMesh->insertNextCell(INTERP_KERNEL::NORM_POINT1,1,targetConn+3); - targetMesh->insertNextCell(INTERP_KERNEL::NORM_POINT1,1,targetConn+4); - targetMesh->insertNextCell(INTERP_KERNEL::NORM_POINT1,1,targetConn+5); - targetMesh->insertNextCell(INTERP_KERNEL::NORM_POINT1,1,targetConn+6); - targetMesh->insertNextCell(INTERP_KERNEL::NORM_POINT1,1,targetConn+7); - targetMesh->finishInsertingCells(); - CPPUNIT_ASSERT_THROW(targetMesh->checkCoherency(),INTERP_KERNEL::Exception); - DataArrayDouble *myCoords=DataArrayDouble::New(); - myCoords->alloc(9,3); - std::copy(targetCoords,targetCoords+27,myCoords->getPointer()); - targetMesh->setCoords(myCoords); - myCoords->decrRef(); - // - targetMesh->checkCoherency(); - CPPUNIT_ASSERT_EQUAL(3,targetMesh->getSpaceDimension()); - CPPUNIT_ASSERT_EQUAL(8,targetMesh->getNumberOfCells()); - CPPUNIT_ASSERT_EQUAL(9,targetMesh->getNumberOfNodes()); - CPPUNIT_ASSERT_EQUAL(0,targetMesh->getMeshDimension()); - // - targetMesh->decrRef(); -} - -void MEDCouplingBasicsTest1::testMeshM1D() -{ - MEDCouplingUMesh *meshM1D=MEDCouplingUMesh::New(); - CPPUNIT_ASSERT_THROW(meshM1D->getMeshDimension(),INTERP_KERNEL::Exception); - CPPUNIT_ASSERT_THROW(meshM1D->getNumberOfNodes(),INTERP_KERNEL::Exception); - CPPUNIT_ASSERT_THROW(meshM1D->getNumberOfCells(),INTERP_KERNEL::Exception); - CPPUNIT_ASSERT_THROW(meshM1D->setMeshDimension(-2),INTERP_KERNEL::Exception); - CPPUNIT_ASSERT_THROW(meshM1D->setMeshDimension(-10),INTERP_KERNEL::Exception); - CPPUNIT_ASSERT_THROW(meshM1D->checkCoherency(),INTERP_KERNEL::Exception); - meshM1D->setMeshDimension(-1); - meshM1D->checkCoherency(); - CPPUNIT_ASSERT_EQUAL(-1,meshM1D->getMeshDimension()); - CPPUNIT_ASSERT_EQUAL(1,meshM1D->getNumberOfCells()); - CPPUNIT_ASSERT_THROW(meshM1D->getNumberOfNodes(),INTERP_KERNEL::Exception); - CPPUNIT_ASSERT_THROW(meshM1D->getSpaceDimension(),INTERP_KERNEL::Exception); - MEDCouplingUMesh *cpy=meshM1D->clone(true); - CPPUNIT_ASSERT(cpy->isEqual(meshM1D,1e-12)); - cpy->decrRef(); - MEDCouplingFieldDouble *fieldOnCells=MEDCouplingFieldDouble::New(ON_CELLS); - fieldOnCells->setMesh(meshM1D); - DataArrayDouble *array=DataArrayDouble::New(); - array->alloc(1,6); - fieldOnCells->setArray(array); - double *tmp=array->getPointer(); - array->decrRef(); - std::fill(tmp,tmp+6,7.); - fieldOnCells->checkCoherency(); - // - fieldOnCells->decrRef(); - meshM1D->decrRef(); -} - -void MEDCouplingBasicsTest1::testDeepCopy() -{ - DataArrayDouble *array=DataArrayDouble::New(); - array->alloc(5,3); - std::fill(array->getPointer(),array->getPointer()+5*3,7.); - CPPUNIT_ASSERT_DOUBLES_EQUAL(7.,array->getIJ(3,2),1e-14); - double *tmp1=array->getPointer(); - DataArrayDouble *array2=array->deepCpy(); - double *tmp2=array2->getPointer(); - CPPUNIT_ASSERT(tmp1!=tmp2); - array->decrRef(); - CPPUNIT_ASSERT_DOUBLES_EQUAL(7.,array2->getIJ(3,2),1e-14); - array2->decrRef(); - // - DataArrayInt *array3=DataArrayInt::New(); - array3->alloc(5,3); - std::fill(array3->getPointer(),array3->getPointer()+5*3,17); - CPPUNIT_ASSERT_EQUAL(17,array3->getIJ(3,2)); - int *tmp3=array3->getPointer(); - DataArrayInt *array4=array3->deepCpy(); - int *tmp4=array4->getPointer(); - CPPUNIT_ASSERT(tmp3!=tmp4); - array3->decrRef(); - CPPUNIT_ASSERT_EQUAL(17,array4->getIJ(3,2)); - array4->decrRef(); -} - -void MEDCouplingBasicsTest1::testRevNodal() -{ - MEDCouplingUMesh *mesh=build2DTargetMesh_1(); - DataArrayInt *revNodal=DataArrayInt::New(); - DataArrayInt *revNodalIndx=DataArrayInt::New(); - // - mesh->getReverseNodalConnectivity(revNodal,revNodalIndx); - const int revNodalExpected[18]={0,0,1,1,2,0,3,0,1,2,3,4,2,4,3,3,4,4}; - const int revNodalIndexExpected[10]={0,1,3,5,7,12,14,15,17,18}; - CPPUNIT_ASSERT_EQUAL((std::size_t)18,revNodal->getNbOfElems()); - CPPUNIT_ASSERT_EQUAL((std::size_t)10,revNodalIndx->getNbOfElems()); - CPPUNIT_ASSERT(std::equal(revNodalExpected,revNodalExpected+18,revNodal->getPointer())); - CPPUNIT_ASSERT(std::equal(revNodalIndexExpected,revNodalIndexExpected+10,revNodalIndx->getPointer())); - // - revNodal->decrRef(); - revNodalIndx->decrRef(); - mesh->decrRef(); -} - -void MEDCouplingBasicsTest1::testConvertToPolyTypes() -{ - ////// 2D - MEDCouplingUMesh *mesh=build2DTargetMesh_1(); - // - const int elts[2]={1,3}; - std::vector eltsV(elts,elts+2); - mesh->convertToPolyTypes(&eltsV[0],&eltsV[0]+eltsV.size()); - mesh->checkCoherency(); - CPPUNIT_ASSERT_EQUAL(5,mesh->getNumberOfCells()); - CPPUNIT_ASSERT_EQUAL(23,mesh->getNodalConnectivity()->getNumberOfTuples()); - const int *pt=mesh->getNodalConnectivity()->getConstPointer(); - const int expected1[23]={4, 0, 3, 4, 1, 5, 1, 4, 2, 3, 4, 5, 2, 5, 6, 7, 4, 3, 4, 7, 8, 5, 4}; - CPPUNIT_ASSERT(std::equal(expected1,expected1+23,pt)); - // - mesh->decrRef(); - ////// 3D - mesh=build3DTargetMesh_1(); - mesh->convertToPolyTypes(&eltsV[0],&eltsV[0]+eltsV.size()); - mesh->checkCoherency(); - CPPUNIT_ASSERT_EQUAL(8,mesh->getNumberOfCells()); - CPPUNIT_ASSERT_EQUAL(114,mesh->getNodalConnectivity()->getNumberOfTuples()); - mesh->convertToPolyTypes(&eltsV[0],&eltsV[0]+eltsV.size()); - mesh->checkCoherency(); - CPPUNIT_ASSERT_EQUAL(8,mesh->getNumberOfCells()); - CPPUNIT_ASSERT_EQUAL(114,mesh->getNodalConnectivity()->getNumberOfTuples()); - // - mesh->decrRef(); -} - -void MEDCouplingBasicsTest1::testDescConn2D() -{ - MEDCouplingUMesh *mesh=build2DTargetMesh_1(); - DataArrayInt *desc=DataArrayInt::New(); - DataArrayInt *descIndx=DataArrayInt::New(); - DataArrayInt *revDesc=DataArrayInt::New(); - DataArrayInt *revDescIndx=DataArrayInt::New(); - // - MEDCouplingUMesh *mesh2=mesh->buildDescendingConnectivity(desc,descIndx,revDesc,revDescIndx); - mesh2->checkCoherency(); - CPPUNIT_ASSERT_EQUAL(1,mesh2->getMeshDimension()); - CPPUNIT_ASSERT_EQUAL(13,mesh2->getNumberOfCells()); - CPPUNIT_ASSERT_EQUAL((std::size_t)14,revDescIndx->getNbOfElems()); CPPUNIT_ASSERT_EQUAL(14,revDescIndx->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL((std::size_t)6,descIndx->getNbOfElems()); CPPUNIT_ASSERT_EQUAL(6,descIndx->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL((std::size_t)18,desc->getNbOfElems()); CPPUNIT_ASSERT_EQUAL(18,desc->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL((std::size_t)18,revDesc->getNbOfElems()); CPPUNIT_ASSERT_EQUAL(18,revDesc->getNumberOfTuples()); - const int expected1[18]={0,1,2,3, 2,4,5, 6,7,4, 8,9,1,10, 11,12,6,9}; - CPPUNIT_ASSERT(std::equal(expected1,expected1+18,desc->getConstPointer())); - const int expected2[6]={0,4,7,10,14,18}; - CPPUNIT_ASSERT(std::equal(expected2,expected2+6,descIndx->getConstPointer())); - const int expected3[14]={0,1,3,5,6,8,9,11,12,13,15,16,17,18}; - CPPUNIT_ASSERT(std::equal(expected3,expected3+14,revDescIndx->getConstPointer())); - const int expected4[18]={0, 0,3, 0,1, 0, 1,2, 1, 2,4, 2, 3, 3,4, 3, 4, 4}; - CPPUNIT_ASSERT(std::equal(expected4,expected4+18,revDesc->getConstPointer())); - DataArrayInt *conn=mesh2->getNodalConnectivity(); - DataArrayInt *connIndex=mesh2->getNodalConnectivityIndex(); - const int expected5[14]={0,3,6,9,12,15,18,21,24,27,30,33,36,39}; - CPPUNIT_ASSERT(std::equal(expected5,expected5+14,connIndex->getConstPointer())); - const int expected6[39]={1, 0, 3, 1, 3, 4, 1, 4, 1, 1, 1, 0, 1, 4, 2, 1, 2, 1, 1, 4, 5, 1, 5, 2, 1, 6, 7, 1, 7, 4, 1, 3, 6, 1, 7, 8, 1, 8, 5}; - CPPUNIT_ASSERT(std::equal(expected6,expected6+39,conn->getConstPointer())); - // - desc->decrRef(); - descIndx->decrRef(); - revDesc->decrRef(); - revDescIndx->decrRef(); - mesh2->decrRef(); - // - const int elts[2]={1,3}; - std::vector eltsV(elts,elts+2); - mesh->convertToPolyTypes(&eltsV[0],&eltsV[0]+eltsV.size()); - mesh->checkCoherency(); - // - desc=DataArrayInt::New(); - descIndx=DataArrayInt::New(); - revDesc=DataArrayInt::New(); - revDescIndx=DataArrayInt::New(); - // - mesh2=mesh->buildDescendingConnectivity(desc,descIndx,revDesc,revDescIndx); - mesh2->checkCoherency(); - CPPUNIT_ASSERT_EQUAL(1,mesh2->getMeshDimension()); - CPPUNIT_ASSERT_EQUAL(13,mesh2->getNumberOfCells()); - CPPUNIT_ASSERT_EQUAL((std::size_t)14,revDescIndx->getNbOfElems()); CPPUNIT_ASSERT_EQUAL(14,revDescIndx->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL((std::size_t)6,descIndx->getNbOfElems()); CPPUNIT_ASSERT_EQUAL(6,descIndx->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL((std::size_t)18,desc->getNbOfElems()); CPPUNIT_ASSERT_EQUAL(18,desc->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL((std::size_t)18,revDesc->getNbOfElems()); CPPUNIT_ASSERT_EQUAL(18,revDesc->getNumberOfTuples()); - CPPUNIT_ASSERT(std::equal(expected1,expected1+18,desc->getConstPointer())); - CPPUNIT_ASSERT(std::equal(expected2,expected2+6,descIndx->getConstPointer())); - CPPUNIT_ASSERT(std::equal(expected3,expected3+14,revDescIndx->getConstPointer())); - CPPUNIT_ASSERT(std::equal(expected4,expected4+18,revDesc->getConstPointer())); - conn=mesh2->getNodalConnectivity(); - connIndex=mesh2->getNodalConnectivityIndex(); - CPPUNIT_ASSERT(std::equal(expected5,expected5+14,connIndex->getConstPointer())); - CPPUNIT_ASSERT(std::equal(expected6,expected6+39,conn->getConstPointer())); - // - desc->decrRef(); - descIndx->decrRef(); - revDesc->decrRef(); - revDescIndx->decrRef(); - mesh2->decrRef(); - mesh->decrRef(); -} - -void MEDCouplingBasicsTest1::testDescConn3D() -{ - MEDCouplingUMesh *mesh=build3DTargetMesh_1(); - DataArrayInt *desc=DataArrayInt::New(); - DataArrayInt *descIndx=DataArrayInt::New(); - DataArrayInt *revDesc=DataArrayInt::New(); - DataArrayInt *revDescIndx=DataArrayInt::New(); - // - MEDCouplingUMesh *mesh2=mesh->buildDescendingConnectivity(desc,descIndx,revDesc,revDescIndx); - mesh2->checkCoherency(); - CPPUNIT_ASSERT_EQUAL(2,mesh2->getMeshDimension()); - CPPUNIT_ASSERT_EQUAL(36,mesh2->getNumberOfCells()); - CPPUNIT_ASSERT_EQUAL((std::size_t)37,revDescIndx->getNbOfElems()); CPPUNIT_ASSERT_EQUAL(37,revDescIndx->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL((std::size_t)9,descIndx->getNbOfElems()); CPPUNIT_ASSERT_EQUAL(9,descIndx->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL((std::size_t)48,desc->getNbOfElems()); CPPUNIT_ASSERT_EQUAL(48,desc->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL((std::size_t)48,revDesc->getNbOfElems()); CPPUNIT_ASSERT_EQUAL(48,revDesc->getNumberOfTuples()); - const int expected1[9]={0, 6, 12, 18, 24, 30, 36, 42, 48}; - const int expected2[48]={0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 3, 11, 12, 4, 13, 14, 15, 16, 17, 10, 18, 19, 13, 1, 20, 21, 22, 23, 24, 7, 25, 26, 27, 28, 22, 12, 29, 23, 30, 31, 32, 17, 33, 28, 34, 35, 30}; - const int expected3[37]={0, 1, 3, 4, 6, 8, 9, 10, 12, 13, 14, 16, 17, 19, 21, 22, 23, 24, 26, 27, 28, 29, 30, 32, 34, 35, 36, 37, 38, 40, 41, 43, 44, 45, 46, 47, 48}; - const int expected4[48]={0, 0, 4, 0, 0, 1, 0, 2, 0, 1, 1, 5, 1, 1, 1, 3, 2, 2, 6, 2, 3, 2, 2, 3, 3, 7, 3, 3, 4, 4, 4, 5, 4, 6, 4, 5, 5, 5, 5, 7, 6, 6, 7, 6, 6, 7, 7, 7}; - const int expected5[37]={0, 5, 10, 15, 20, 25, 30, 35, 40, 45, 50, 55, 60, 65, 70, 75, 80, 85, 90, 95, 100, 105, 110, 115, 120, 125, 130, 135, 140, 145, 150, 155, 160, 165, 170, 175, 180}; - const int expected6[180]={4, 0, 1, 4, 3, 4, 9, 12, 13, 10, 4, 0, 9, 10, 1, 4, 1, 10, 13, 4, 4, 4, 13, 12, 3, 4, 3, 12, 9, 0, 4, 1, 2, 5, 4, 4, 10, 13, 14, 11, 4, 1, 10, 11, 2, 4, 2, 11, 14, - 5, 4, 5, 14, 13, 4, 4, 3, 4, 7, 6, 4, 12, 15, 16, 13, 4, 4, 13, 16, 7, 4, 7, 16, 15, 6, 4, 6, 15, 12, 3, 4, 4, 5, 8, 7, 4, 13, 16, 17, 14, 4, 5, 14, 17, 8, 4, 8, - 17, 16, 7, 4, 18, 21, 22, 19, 4, 9, 18, 19, 10, 4, 10, 19, 22, 13, 4, 13, 22, 21, 12, 4, 12, 21, 18, 9, 4, 19, 22, 23, 20, 4, 10, 19, 20, 11, 4, 11, 20, 23, 14, 4, - 14, 23, 22, 13, 4, 21, 24, 25, 22, 4, 13, 22, 25, 16, 4, 16, 25, 24, 15, 4, 15, 24, 21, 12, 4, 22, 25, 26, 23, 4, 14, 23, 26, 17, 4, 17, 26, 25, 16}; - const int expected7[180]={4, 0, 1, 4, 3, 4, 9, 12, 13, 10, 4, 0, 9, 10, 1, 4, 1, 10, 13, 4, 4, 4, 13, 12, 3, 4, 3, 12, 9, 0, 5, 1, 2, 5, 4, 5, 10, 13, 14, 11, 5, 1, 10, 11, 2, 5, 2, 11, 14, - 5, 5, 5, 14, 13, 4, 4, 3, 4, 7, 6, 4, 12, 15, 16, 13, 4, 4, 13, 16, 7, 4, 7, 16, 15, 6, 4, 6, 15, 12, 3, 5, 4, 5, 8, 7, 5, 13, 16, 17, 14, 5, 5, 14, 17, 8, 5, 8, - 17, 16, 7, 4, 18, 21, 22, 19, 4, 9, 18, 19, 10, 4, 10, 19, 22, 13, 4, 13, 22, 21, 12, 4, 12, 21, 18, 9, 4, 19, 22, 23, 20, 4, 10, 19, 20, 11, 4, 11, 20, 23, 14, 4, - 14, 23, 22, 13, 4, 21, 24, 25, 22, 4, 13, 22, 25, 16, 4, 16, 25, 24, 15, 4, 15, 24, 21, 12, 4, 22, 25, 26, 23, 4, 14, 23, 26, 17, 4, 17, 26, 25, 16}; - - CPPUNIT_ASSERT(std::equal(expected1,expected1+9,descIndx->getConstPointer())); - CPPUNIT_ASSERT(std::equal(expected2,expected2+48,desc->getConstPointer())); - CPPUNIT_ASSERT(std::equal(expected3,expected3+37,revDescIndx->getConstPointer())); - CPPUNIT_ASSERT(std::equal(expected4,expected4+48,revDesc->getConstPointer())); - CPPUNIT_ASSERT(std::equal(expected5,expected5+37,mesh2->getNodalConnectivityIndex()->getConstPointer())); - CPPUNIT_ASSERT(std::equal(expected6,expected6+180,mesh2->getNodalConnectivity()->getConstPointer())); - // - desc->decrRef(); - descIndx->decrRef(); - revDesc->decrRef(); - revDescIndx->decrRef(); - mesh2->decrRef(); - // - const int elts[2]={1,3}; - std::vector eltsV(elts,elts+2); - mesh->convertToPolyTypes(&eltsV[0],&eltsV[0]+eltsV.size()); - mesh->checkCoherency(); - desc=DataArrayInt::New(); - descIndx=DataArrayInt::New(); - revDesc=DataArrayInt::New(); - revDescIndx=DataArrayInt::New(); - mesh2=mesh->buildDescendingConnectivity(desc,descIndx,revDesc,revDescIndx); - mesh2->checkCoherency(); - CPPUNIT_ASSERT_EQUAL(2,mesh2->getMeshDimension()); - CPPUNIT_ASSERT_EQUAL(36,mesh2->getNumberOfCells()); - CPPUNIT_ASSERT_EQUAL((std::size_t)37,revDescIndx->getNbOfElems()); CPPUNIT_ASSERT_EQUAL(37,revDescIndx->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL((std::size_t)9,descIndx->getNbOfElems()); CPPUNIT_ASSERT_EQUAL(9,descIndx->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL((std::size_t)48,desc->getNbOfElems()); CPPUNIT_ASSERT_EQUAL(48,desc->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL((std::size_t)48,revDesc->getNbOfElems()); CPPUNIT_ASSERT_EQUAL(48,revDesc->getNumberOfTuples()); - CPPUNIT_ASSERT(std::equal(expected1,expected1+9,descIndx->getConstPointer())); - CPPUNIT_ASSERT(std::equal(expected2,expected2+48,desc->getConstPointer())); - CPPUNIT_ASSERT(std::equal(expected3,expected3+37,revDescIndx->getConstPointer())); - CPPUNIT_ASSERT(std::equal(expected4,expected4+48,revDesc->getConstPointer())); - CPPUNIT_ASSERT(std::equal(expected5,expected5+37,mesh2->getNodalConnectivityIndex()->getConstPointer())); - CPPUNIT_ASSERT(std::equal(expected7,expected7+180,mesh2->getNodalConnectivity()->getConstPointer())); - // - desc->decrRef(); - descIndx->decrRef(); - revDesc->decrRef(); - revDescIndx->decrRef(); - mesh2->decrRef(); - mesh->decrRef(); -} - -void MEDCouplingBasicsTest1::testFindBoundaryNodes() -{ - MEDCouplingUMesh *mesh=build3DTargetMesh_1(); - DataArrayInt *boundaryNodes=mesh->findBoundaryNodes(); - CPPUNIT_ASSERT_EQUAL(26,boundaryNodes->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(1,boundaryNodes->getNumberOfComponents()); - const int expected1[26]={0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26}; - CPPUNIT_ASSERT(std::equal(expected1,expected1+26,boundaryNodes->begin())); - boundaryNodes->decrRef(); - mesh->decrRef(); -} - -void MEDCouplingBasicsTest1::testBoundaryMesh() -{ - MEDCouplingUMesh *mesh=build3DTargetMesh_1(); - MEDCouplingPointSet *mesh2=mesh->buildBoundaryMesh(false); - CPPUNIT_ASSERT_EQUAL(24,mesh2->getNumberOfCells()); - CPPUNIT_ASSERT_EQUAL(26,mesh2->getNumberOfNodes()); - mesh2->decrRef(); - mesh->decrRef(); -} - -void MEDCouplingBasicsTest1::testBuildPartOfMySelf() -{ - MEDCouplingUMesh *mesh=build2DTargetMesh_1(); - mesh->setName("Toto"); - const int tab1[2]={0,4}; - const int tab2[3]={0,2,3}; - // - MEDCouplingPointSet *subMeshSimple=mesh->buildPartOfMySelf(tab1,tab1+2,true); - MEDCouplingUMesh *subMesh=dynamic_cast(subMeshSimple); - CPPUNIT_ASSERT(subMesh); - std::string name(subMesh->getName()); - CPPUNIT_ASSERT_EQUAL(2,(int)mesh->getAllGeoTypes().size()); - CPPUNIT_ASSERT_EQUAL(INTERP_KERNEL::NORM_TRI3,*mesh->getAllGeoTypes().begin()); - CPPUNIT_ASSERT_EQUAL(INTERP_KERNEL::NORM_QUAD4,*(++(mesh->getAllGeoTypes().begin()))); - CPPUNIT_ASSERT_EQUAL(1,(int)subMesh->getAllGeoTypes().size()); - CPPUNIT_ASSERT_EQUAL(INTERP_KERNEL::NORM_QUAD4,*subMesh->getAllGeoTypes().begin()); - CPPUNIT_ASSERT(name=="Toto"); - CPPUNIT_ASSERT(mesh->getCoords()==subMesh->getCoords()); - CPPUNIT_ASSERT_EQUAL(2,subMesh->getNumberOfCells()); - const int subConn[10]={4,0,3,4,1,4,7,8,5,4}; - const int subConnIndex[3]={0,5,10}; - CPPUNIT_ASSERT_EQUAL((std::size_t)10,subMesh->getNodalConnectivity()->getNbOfElems()); - CPPUNIT_ASSERT_EQUAL((std::size_t)3,subMesh->getNodalConnectivityIndex()->getNbOfElems()); - CPPUNIT_ASSERT(std::equal(subConn,subConn+10,subMesh->getNodalConnectivity()->getPointer())); - CPPUNIT_ASSERT(std::equal(subConnIndex,subConnIndex+3,subMesh->getNodalConnectivityIndex()->getPointer())); - subMesh->decrRef(); - // - subMeshSimple=mesh->buildPartOfMySelf(tab2,tab2+3,true); - subMesh=dynamic_cast(subMeshSimple); - CPPUNIT_ASSERT(subMesh); - name=subMesh->getName(); - CPPUNIT_ASSERT_EQUAL(2,(int)subMesh->getAllGeoTypes().size()); - CPPUNIT_ASSERT_EQUAL(INTERP_KERNEL::NORM_TRI3,*subMesh->getAllGeoTypes().begin()); - CPPUNIT_ASSERT_EQUAL(INTERP_KERNEL::NORM_QUAD4,*(++(subMesh->getAllGeoTypes().begin()))); - CPPUNIT_ASSERT(name=="Toto"); - CPPUNIT_ASSERT(mesh->getCoords()==subMesh->getCoords()); - CPPUNIT_ASSERT_EQUAL(3,subMesh->getNumberOfCells()); - const int subConn2[14]={4,0,3,4,1,3,4,5,2,4,6,7,4,3}; - const int subConnIndex2[4]={0,5,9,14}; - CPPUNIT_ASSERT_EQUAL((std::size_t)14,subMesh->getNodalConnectivity()->getNbOfElems()); - CPPUNIT_ASSERT_EQUAL((std::size_t)4,subMesh->getNodalConnectivityIndex()->getNbOfElems()); - CPPUNIT_ASSERT(std::equal(subConn2,subConn2+14,subMesh->getNodalConnectivity()->getPointer())); - CPPUNIT_ASSERT(std::equal(subConnIndex2,subConnIndex2+4,subMesh->getNodalConnectivityIndex()->getPointer())); - const int tab3[3]={0,1,2}; - MEDCouplingPointSet *subMeshSimple2=subMeshSimple->buildPartOfMySelf(tab3,tab3+3,true); - subMesh->decrRef(); - name=subMeshSimple2->getName(); - CPPUNIT_ASSERT(name=="Toto"); - subMeshSimple2->decrRef(); - // - mesh->decrRef(); -} - -void MEDCouplingBasicsTest1::testBuildPartOfMySelfNode() -{ - MEDCouplingUMesh *mesh=build2DTargetMesh_1(); - const int tab1[4]={5,7,8,4}; - MEDCouplingPointSet *subMeshSimple=mesh->buildPartOfMySelfNode(tab1,tab1+4,true); - MEDCouplingUMesh *subMesh=dynamic_cast(subMeshSimple); - CPPUNIT_ASSERT(subMesh); - CPPUNIT_ASSERT_EQUAL(1,(int)subMesh->getAllGeoTypes().size()); - CPPUNIT_ASSERT_EQUAL(INTERP_KERNEL::NORM_QUAD4,*subMesh->getAllGeoTypes().begin()); - CPPUNIT_ASSERT_EQUAL(1,subMesh->getNumberOfCells()); - CPPUNIT_ASSERT_EQUAL((std::size_t)5,subMesh->getNodalConnectivity()->getNbOfElems()); - CPPUNIT_ASSERT_EQUAL((std::size_t)2,subMesh->getNodalConnectivityIndex()->getNbOfElems()); - const int subConn[5]={4,7,8,5,4}; - const int subConnIndex[3]={0,5}; - CPPUNIT_ASSERT(std::equal(subConn,subConn+5,subMesh->getNodalConnectivity()->getPointer())); - CPPUNIT_ASSERT(std::equal(subConnIndex,subConnIndex+2,subMesh->getNodalConnectivityIndex()->getPointer())); - CPPUNIT_ASSERT(subMesh->getCoords()==mesh->getCoords()); - subMeshSimple->decrRef(); - // - subMeshSimple=mesh->buildPartOfMySelfNode(tab1,tab1+2,false); - subMesh=dynamic_cast(subMeshSimple); - CPPUNIT_ASSERT(subMesh); - CPPUNIT_ASSERT_EQUAL(2,(int)subMesh->getAllGeoTypes().size()); - CPPUNIT_ASSERT_EQUAL(INTERP_KERNEL::NORM_TRI3,*subMesh->getAllGeoTypes().begin()); - CPPUNIT_ASSERT_EQUAL(INTERP_KERNEL::NORM_QUAD4,*(++subMesh->getAllGeoTypes().begin())); - CPPUNIT_ASSERT_EQUAL(3,subMesh->getNumberOfCells()); - CPPUNIT_ASSERT_EQUAL((std::size_t)14,subMesh->getNodalConnectivity()->getNbOfElems()); - CPPUNIT_ASSERT_EQUAL((std::size_t)4,subMesh->getNodalConnectivityIndex()->getNbOfElems()); - const int subConn2[14]={3,4,5,2,4,6,7,4,3,4,7,8,5,4}; - const int subConnIndex2[4]={0,4,9,14}; - CPPUNIT_ASSERT(std::equal(subConn2,subConn2+14,subMesh->getNodalConnectivity()->getPointer())); - CPPUNIT_ASSERT(std::equal(subConnIndex2,subConnIndex2+4,subMesh->getNodalConnectivityIndex()->getPointer())); - CPPUNIT_ASSERT(subMesh->getCoords()==mesh->getCoords()); - subMeshSimple->decrRef(); - //testing the case where length of tab2 is greater than max number of node per cell. - const int tab2[7]={0,3,2,1,4,5,6}; - subMeshSimple=mesh->buildPartOfMySelfNode(tab2,tab2+7,true); - subMesh=dynamic_cast(subMeshSimple); - CPPUNIT_ASSERT(subMesh); - CPPUNIT_ASSERT_EQUAL(2,(int)subMesh->getAllGeoTypes().size()); - CPPUNIT_ASSERT_EQUAL(INTERP_KERNEL::NORM_TRI3,*subMesh->getAllGeoTypes().begin()); - CPPUNIT_ASSERT_EQUAL(INTERP_KERNEL::NORM_QUAD4,*(++subMesh->getAllGeoTypes().begin())); - CPPUNIT_ASSERT_EQUAL(3,subMesh->getNumberOfCells()); - subMeshSimple->decrRef(); - // - mesh->decrRef(); -} - -void MEDCouplingBasicsTest1::testZipCoords() -{ - MEDCouplingUMesh *mesh=build2DTargetMesh_1(); - CPPUNIT_ASSERT_EQUAL(2,(int)mesh->getAllGeoTypes().size()); - CPPUNIT_ASSERT_EQUAL(2,mesh->getSpaceDimension()); - CPPUNIT_ASSERT_EQUAL(9,mesh->getNumberOfNodes()); - CPPUNIT_ASSERT_EQUAL(5,mesh->getNumberOfCells()); - std::vector oldConn(mesh->getNodalConnectivity()->getNbOfElems()); - std::vector oldConnIndex(mesh->getNumberOfCells()+1); - std::copy(mesh->getNodalConnectivity()->getPointer(),mesh->getNodalConnectivity()->getPointer()+oldConn.size(),oldConn.begin()); - std::copy(mesh->getNodalConnectivityIndex()->getPointer(),mesh->getNodalConnectivityIndex()->getPointer()+mesh->getNumberOfCells()+1,oldConnIndex.begin()); - DataArrayDouble *oldCoords=mesh->getCoords(); - oldCoords->incrRef(); - mesh->zipCoords(); - CPPUNIT_ASSERT_EQUAL(2,(int)mesh->getAllGeoTypes().size()); - CPPUNIT_ASSERT_EQUAL(2,mesh->getSpaceDimension()); - CPPUNIT_ASSERT_EQUAL(9,mesh->getNumberOfNodes()); - CPPUNIT_ASSERT_EQUAL(5,mesh->getNumberOfCells()); - CPPUNIT_ASSERT(mesh->getCoords()!=oldCoords); - CPPUNIT_ASSERT(std::equal(mesh->getCoords()->getPointer(),mesh->getCoords()->getPointer()+2*9,oldCoords->getPointer())); - CPPUNIT_ASSERT(std::equal(oldConn.begin(),oldConn.end(),mesh->getNodalConnectivity()->getPointer())); - CPPUNIT_ASSERT(std::equal(oldConnIndex.begin(),oldConnIndex.end(),mesh->getNodalConnectivityIndex()->getPointer())); - oldCoords->decrRef(); - // - const int tab1[2]={0,4}; - MEDCouplingPointSet *subMeshPtSet=mesh->buildPartOfMySelf(tab1,tab1+2,true); - MEDCouplingUMesh *subMesh=dynamic_cast(subMeshPtSet); - CPPUNIT_ASSERT(subMesh); - DataArrayInt *traducer=subMesh->zipCoordsTraducer(); - const int expectedTraducer[9]={0,1,-1,2,3,4,-1,5,6}; - CPPUNIT_ASSERT(std::equal(expectedTraducer,expectedTraducer+9,traducer->getPointer())); - traducer->decrRef(); - CPPUNIT_ASSERT_EQUAL(INTERP_KERNEL::NORM_QUAD4,*subMesh->getAllGeoTypes().begin()); - CPPUNIT_ASSERT_EQUAL(2,subMesh->getNumberOfCells()); - const int subConn[10]={4,0,2,3,1,4,5,6,4,3}; - const int subConnIndex[3]={0,5,10}; - CPPUNIT_ASSERT_EQUAL(7,subMesh->getNumberOfNodes()); - CPPUNIT_ASSERT_EQUAL((std::size_t)10,subMesh->getNodalConnectivity()->getNbOfElems()); - CPPUNIT_ASSERT_EQUAL((std::size_t)3,subMesh->getNodalConnectivityIndex()->getNbOfElems()); - CPPUNIT_ASSERT(std::equal(subConn,subConn+10,subMesh->getNodalConnectivity()->getPointer())); - CPPUNIT_ASSERT(std::equal(subConnIndex,subConnIndex+3,subMesh->getNodalConnectivityIndex()->getPointer())); - subMesh->decrRef(); - // - subMeshPtSet=mesh->buildPartOfMySelf(tab1,tab1+2,false); - subMesh=dynamic_cast(subMeshPtSet); - CPPUNIT_ASSERT(subMesh); - CPPUNIT_ASSERT_EQUAL(INTERP_KERNEL::NORM_QUAD4,*subMesh->getAllGeoTypes().begin()); - CPPUNIT_ASSERT_EQUAL(2,subMesh->getNumberOfCells()); - CPPUNIT_ASSERT_EQUAL(7,subMesh->getNumberOfNodes()); - CPPUNIT_ASSERT_EQUAL((std::size_t)10,subMesh->getNodalConnectivity()->getNbOfElems()); - CPPUNIT_ASSERT_EQUAL((std::size_t)3,subMesh->getNodalConnectivityIndex()->getNbOfElems()); - CPPUNIT_ASSERT(std::equal(subConn,subConn+10,subMesh->getNodalConnectivity()->getPointer())); - CPPUNIT_ASSERT(std::equal(subConnIndex,subConnIndex+3,subMesh->getNodalConnectivityIndex()->getPointer())); - subMesh->decrRef(); - // - mesh->decrRef(); -} - -void MEDCouplingBasicsTest1::testZipConnectivity() -{ - MEDCouplingUMesh *m1=build2DTargetMesh_1(); - MEDCouplingUMesh *m2=build2DTargetMesh_1(); - int cells1[3]={2,3,4}; - MEDCouplingPointSet *m3_1=m2->buildPartOfMySelf(cells1,cells1+3,true); - MEDCouplingUMesh *m3=dynamic_cast(m3_1); - CPPUNIT_ASSERT(m3); - m2->decrRef(); - MEDCouplingUMesh *m4=build2DSourceMesh_1(); - MEDCouplingUMesh *m5=MEDCouplingUMesh::MergeUMeshes(m1,m3); - m1->decrRef(); - m3->decrRef(); - MEDCouplingUMesh *m6=MEDCouplingUMesh::MergeUMeshes(m5,m4); - m4->decrRef(); - m5->decrRef(); - // - bool areNodesMerged; - int newNbOfNodes; - CPPUNIT_ASSERT_EQUAL(10,m6->getNumberOfCells()); - CPPUNIT_ASSERT_EQUAL(22,m6->getNumberOfNodes()); - DataArrayInt *arr=m6->mergeNodes(1e-13,areNodesMerged,newNbOfNodes); - arr->decrRef(); - CPPUNIT_ASSERT(areNodesMerged); - CPPUNIT_ASSERT_EQUAL(10,m6->getNumberOfCells()); - CPPUNIT_ASSERT_EQUAL(9,m6->getNumberOfNodes()); - CPPUNIT_ASSERT_EQUAL(9,newNbOfNodes); - // - arr=m6->zipConnectivityTraducer(0); - CPPUNIT_ASSERT_EQUAL(7,m6->getNumberOfCells()); - arr->decrRef(); - MEDCouplingUMesh *m7=m6->clone(true); - arr=m6->zipConnectivityTraducer(0); - CPPUNIT_ASSERT(m7->isEqual(m6,1e-12)); - CPPUNIT_ASSERT_EQUAL(7,m6->getNumberOfCells()); - arr->decrRef(); - // - m7->decrRef(); - m6->decrRef(); -} - -void MEDCouplingBasicsTest1::testEqualMesh() -{ - MEDCouplingUMesh *mesh1=build2DTargetMesh_1(); - MEDCouplingUMesh *mesh2=build2DTargetMesh_1(); - // - CPPUNIT_ASSERT(mesh1->isEqual(mesh1,1e-12)); - // - CPPUNIT_ASSERT(mesh1->isEqual(mesh2,1e-12)); - CPPUNIT_ASSERT(mesh2->isEqual(mesh1,1e-12)); - double *pt=mesh2->getCoords()->getPointer(); - double tmp=pt[1]; - pt[1]=5.999; - CPPUNIT_ASSERT(!mesh1->isEqual(mesh2,1e-12)); - CPPUNIT_ASSERT(!mesh2->isEqual(mesh1,1e-12)); - pt[1]=tmp; - CPPUNIT_ASSERT(mesh1->isEqual(mesh2,1e-12)); - CPPUNIT_ASSERT(mesh2->isEqual(mesh1,1e-12)); - // - int *pt2=mesh1->getNodalConnectivity()->getPointer(); - pt2[5]++; - CPPUNIT_ASSERT(!mesh1->isEqual(mesh2,1e-12)); - CPPUNIT_ASSERT(!mesh2->isEqual(mesh1,1e-12)); - pt2[5]--; - CPPUNIT_ASSERT(mesh1->isEqual(mesh2,1e-12)); - CPPUNIT_ASSERT(mesh2->isEqual(mesh1,1e-12)); - // - pt2=mesh1->getNodalConnectivityIndex()->getPointer(); - pt2[1]++; - CPPUNIT_ASSERT(!mesh1->isEqual(mesh2,1e-12)); - CPPUNIT_ASSERT(!mesh2->isEqual(mesh1,1e-12)); - pt2[1]--; - CPPUNIT_ASSERT(mesh1->isEqual(mesh2,1e-12)); - CPPUNIT_ASSERT(mesh2->isEqual(mesh1,1e-12)); - // - std::string tmp3=mesh1->getName(); - mesh1->setName("lllll"); - CPPUNIT_ASSERT(!mesh1->isEqual(mesh2,1e-12)); - CPPUNIT_ASSERT(!mesh2->isEqual(mesh1,1e-12)); - mesh1->setName(tmp3.c_str()); - CPPUNIT_ASSERT(mesh1->isEqual(mesh2,1e-12)); - CPPUNIT_ASSERT(mesh2->isEqual(mesh1,1e-12)); - // - tmp3=mesh2->getCoords()->getInfoOnComponent(1); - mesh2->getCoords()->setInfoOnComponent(1,"kkkkkk"); - CPPUNIT_ASSERT(!mesh1->isEqual(mesh2,1e-12)); - CPPUNIT_ASSERT(!mesh2->isEqual(mesh1,1e-12)); - mesh2->getCoords()->setInfoOnComponent(1,tmp3.c_str()); - CPPUNIT_ASSERT(mesh1->isEqual(mesh2,1e-12)); - CPPUNIT_ASSERT(mesh2->isEqual(mesh1,1e-12)); - // - mesh1->decrRef(); - mesh2->decrRef(); -} - -void MEDCouplingBasicsTest1::testEqualFieldDouble() -{ - MEDCouplingUMesh *mesh1=build2DTargetMesh_1(); - MEDCouplingUMesh *mesh2=build2DTargetMesh_1(); - // - MEDCouplingFieldDouble *fieldOnCells1=MEDCouplingFieldDouble::New(ON_CELLS,NO_TIME); - fieldOnCells1->setMesh(mesh1); - MEDCouplingFieldDouble *fieldOnCells2=MEDCouplingFieldDouble::New(ON_CELLS,NO_TIME); - fieldOnCells2->setMesh(mesh2); - // - CPPUNIT_ASSERT(fieldOnCells1->isEqual(fieldOnCells2,1e-12,1e-15)); - CPPUNIT_ASSERT(fieldOnCells2->isEqual(fieldOnCells1,1e-12,1e-15)); - fieldOnCells2->decrRef(); - // - MEDCouplingFieldDouble *fieldOnNodes1=MEDCouplingFieldDouble::New(ON_CELLS,NO_TIME); - CPPUNIT_ASSERT(!fieldOnCells1->isEqual(fieldOnNodes1,1e-12,1e-15)); - CPPUNIT_ASSERT(!fieldOnNodes1->isEqual(fieldOnCells1,1e-12,1e-15)); - fieldOnNodes1->decrRef(); - // - fieldOnCells2=MEDCouplingFieldDouble::New(ON_CELLS,ONE_TIME); - CPPUNIT_ASSERT(!fieldOnCells1->isEqual(fieldOnCells2,1e-12,1e-15)); - CPPUNIT_ASSERT(!fieldOnCells2->isEqual(fieldOnCells1,1e-12,1e-15)); - fieldOnCells1->decrRef(); - fieldOnCells1=MEDCouplingFieldDouble::New(ON_CELLS,ONE_TIME); - CPPUNIT_ASSERT(fieldOnCells1->isEqual(fieldOnCells2,1e-12,1e-15)); - CPPUNIT_ASSERT(fieldOnCells2->isEqual(fieldOnCells1,1e-12,1e-15)); - fieldOnCells1->setTime(4.,6,7); - CPPUNIT_ASSERT(!fieldOnCells1->isEqual(fieldOnCells2,1e-12,1e-15)); - CPPUNIT_ASSERT(!fieldOnCells2->isEqual(fieldOnCells1,1e-12,1e-15)); - fieldOnCells2->setTime(4.,6,7); - CPPUNIT_ASSERT(fieldOnCells1->isEqual(fieldOnCells2,1e-12,1e-15)); - CPPUNIT_ASSERT(fieldOnCells2->isEqual(fieldOnCells1,1e-12,1e-15)); - fieldOnCells1->setName("Power"); - CPPUNIT_ASSERT(!fieldOnCells1->isEqual(fieldOnCells2,1e-12,1e-15)); - CPPUNIT_ASSERT(!fieldOnCells2->isEqual(fieldOnCells1,1e-12,1e-15)); - fieldOnCells2->setName("Power"); - CPPUNIT_ASSERT(fieldOnCells1->isEqual(fieldOnCells2,1e-12,1e-15)); - CPPUNIT_ASSERT(fieldOnCells2->isEqual(fieldOnCells1,1e-12,1e-15)); - // - fieldOnCells1->setMesh(mesh1); - CPPUNIT_ASSERT(!fieldOnCells1->isEqual(fieldOnCells2,1e-12,1e-15)); - CPPUNIT_ASSERT(!fieldOnCells2->isEqual(fieldOnCells1,1e-12,1e-15)); - fieldOnCells2->setMesh(mesh1); - CPPUNIT_ASSERT(fieldOnCells1->isEqual(fieldOnCells2,1e-12,1e-15)); - CPPUNIT_ASSERT(fieldOnCells2->isEqual(fieldOnCells1,1e-12,1e-15)); - DataArrayDouble *arr=DataArrayDouble::New(); - arr->setName("popo"); - arr->alloc(mesh1->getNumberOfCells(),3); - double *pt=arr->getPointer(); - std::fill(pt,pt+mesh1->getNumberOfCells()*3,6.); - fieldOnCells1->setArray(arr); - CPPUNIT_ASSERT(!fieldOnCells1->isEqual(fieldOnCells2,1e-12,1e-15)); - CPPUNIT_ASSERT(!fieldOnCells2->isEqual(fieldOnCells1,1e-12,1e-15)); - fieldOnCells2->setArray(arr); - arr->decrRef(); - CPPUNIT_ASSERT(fieldOnCells1->isEqual(fieldOnCells2,1e-12,1e-15)); - CPPUNIT_ASSERT(fieldOnCells2->isEqual(fieldOnCells1,1e-12,1e-15)); - // - DataArrayDouble *arr2=arr->deepCpy(); - fieldOnCells2->setArray(arr2); - arr2->decrRef(); - CPPUNIT_ASSERT(fieldOnCells1->isEqual(fieldOnCells2,1e-12,1e-15)); - CPPUNIT_ASSERT(fieldOnCells2->isEqual(fieldOnCells1,1e-12,1e-15)); - pt[4]=6.1; - CPPUNIT_ASSERT(!fieldOnCells1->isEqual(fieldOnCells2,1e-12,1e-15)); - CPPUNIT_ASSERT(!fieldOnCells2->isEqual(fieldOnCells1,1e-12,1e-15)); - pt[4]=6.; - CPPUNIT_ASSERT(fieldOnCells1->isEqual(fieldOnCells2,1e-12,1e-15)); - CPPUNIT_ASSERT(fieldOnCells2->isEqual(fieldOnCells1,1e-12,1e-15)); - arr2->setName("popo2"); - CPPUNIT_ASSERT(!fieldOnCells1->isEqual(fieldOnCells2,1e-12,1e-15)); - CPPUNIT_ASSERT(!fieldOnCells2->isEqual(fieldOnCells1,1e-12,1e-15)); - // - arr2->setName("popo"); - CPPUNIT_ASSERT(fieldOnCells1->isEqual(fieldOnCells2,1e-12,1e-15)); - CPPUNIT_ASSERT(fieldOnCells2->isEqual(fieldOnCells1,1e-12,1e-15)); - // - arr2->setInfoOnComponent(2,"jjj"); - CPPUNIT_ASSERT(!fieldOnCells1->isEqual(fieldOnCells2,1e-12,1e-15)); - CPPUNIT_ASSERT(!fieldOnCells2->isEqual(fieldOnCells1,1e-12,1e-15)); - arr->setInfoOnComponent(2,"jjj"); - CPPUNIT_ASSERT(fieldOnCells1->isEqual(fieldOnCells2,1e-12,1e-15)); - CPPUNIT_ASSERT(fieldOnCells2->isEqual(fieldOnCells1,1e-12,1e-15)); - // - fieldOnCells1->decrRef(); - fieldOnCells2->decrRef(); - // - mesh1->decrRef(); - mesh2->decrRef(); -} - -void MEDCouplingBasicsTest1::testNatureChecking() -{ - MEDCouplingFieldDouble *field=MEDCouplingFieldDouble::New(ON_CELLS,NO_TIME); - field->setNature(Integral); - field->setNature(ConservativeVolumic); - field->setNature(IntegralGlobConstraint); - field->decrRef(); - field=MEDCouplingFieldDouble::New(ON_NODES,NO_TIME); - field->setNature(ConservativeVolumic); - CPPUNIT_ASSERT_THROW(field->setNature(Integral),INTERP_KERNEL::Exception); - CPPUNIT_ASSERT_THROW(field->setNature(IntegralGlobConstraint),INTERP_KERNEL::Exception); - field->decrRef(); -} - -void MEDCouplingBasicsTest1::testBuildSubMeshData() -{ - MEDCouplingUMesh *targetMesh=build2DTargetMesh_1(); - //check buildSubMesh on field on cells - MEDCouplingFieldDouble *fieldCells=MEDCouplingFieldDouble::New(ON_CELLS,NO_TIME); - fieldCells->setMesh(targetMesh); - const int elts[3]={1,2,4}; - DataArrayInt *di; - MEDCouplingMesh *ret1=fieldCells->buildSubMeshData(elts,elts+3,di); - CPPUNIT_ASSERT_EQUAL(3,ret1->getNumberOfCells()); - CPPUNIT_ASSERT_EQUAL(9,ret1->getNumberOfNodes()); - CPPUNIT_ASSERT_EQUAL(3,di->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(1,di->getNumberOfComponents()); - const int *toCheck=di->getConstPointer(); - CPPUNIT_ASSERT(std::equal(elts,elts+3,toCheck)); - MEDCouplingUMesh *ret1DC=dynamic_cast(ret1); - CPPUNIT_ASSERT(ret1DC); - ret1->decrRef(); - di->decrRef(); - fieldCells->decrRef(); - //check buildSubMesh on field on nodes - MEDCouplingFieldDouble *fieldNodes=MEDCouplingFieldDouble::New(ON_NODES,NO_TIME); - fieldNodes->setMesh(targetMesh); - MEDCouplingMesh *ret2=fieldNodes->buildSubMeshData(elts,elts+3,di); - MEDCouplingUMesh *ret2DC=dynamic_cast(ret2); - CPPUNIT_ASSERT(ret2DC); - CPPUNIT_ASSERT_EQUAL(3,ret2->getNumberOfCells()); - CPPUNIT_ASSERT_EQUAL(6,ret2->getNumberOfNodes()); - CPPUNIT_ASSERT_EQUAL(6,di->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(1,di->getNumberOfComponents()); - toCheck=di->getConstPointer(); - const int expected[6]={1,2,4,5,7,8}; - CPPUNIT_ASSERT(std::equal(expected,expected+6,toCheck)); - ret2->decrRef(); - di->decrRef(); - fieldNodes->decrRef(); - targetMesh->decrRef(); -} - -void MEDCouplingBasicsTest1::testExtrudedMesh1() -{ - MEDCouplingUMesh *mesh2D=0; - MEDCouplingUMesh *mesh3D=build3DExtrudedUMesh_1(mesh2D); - MEDCouplingExtrudedMesh *ext=MEDCouplingExtrudedMesh::New(mesh3D,mesh2D,1); - CPPUNIT_ASSERT_EQUAL(18,ext->getNumberOfCells()); - CPPUNIT_ASSERT_EQUAL(60,ext->getNumberOfNodes()); - DataArrayInt *ids3D=ext->getMesh3DIds(); - const int ids3DExpected[18]={5,4,3,2,1,0, 11,10,9,8,7,6, 17,16,15,14,13,12}; - CPPUNIT_ASSERT_EQUAL(18,ids3D->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(1,ids3D->getNumberOfComponents()); - CPPUNIT_ASSERT(std::equal(ids3DExpected,ids3DExpected+18,ids3D->getConstPointer())); - MEDCouplingUMesh *mesh1D=ext->getMesh1D(); - CPPUNIT_ASSERT_EQUAL(4,mesh1D->getNumberOfNodes()); - CPPUNIT_ASSERT_EQUAL(3,mesh1D->getNumberOfCells()); - const double mesh1DExpected[12]={0.66666666666666663, 1.4583333333333333, 0, 0.66666666666666663, 1.4583333333333333, 1, 0.66666666666666663, 1.4583333333333333, 2, 0.66666666666666663, 1.4583333333333333, 3}; - DataArrayDouble *mesh1DCoords=mesh1D->getCoords(); - CPPUNIT_ASSERT_EQUAL(4,mesh1DCoords->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(3,mesh1DCoords->getNumberOfComponents()); - CPPUNIT_ASSERT(std::equal(mesh1DExpected,mesh1DExpected+12,mesh1DCoords->getConstPointer())); - DataArrayInt *conn1D=mesh1D->getNodalConnectivity(); - CPPUNIT_ASSERT_EQUAL(9,conn1D->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(1,conn1D->getNumberOfComponents()); - const int conn1DExpected[9]={1,0,1,1,1,2,1,2,3}; - CPPUNIT_ASSERT(std::equal(conn1DExpected,conn1DExpected+9,conn1D->getConstPointer())); - ext->decrRef(); - mesh3D->decrRef(); - mesh2D->decrRef(); -} - -void MEDCouplingBasicsTest1::testExtrudedMesh2() -{ - MEDCouplingUMesh *mN,*mTT,*mTF; - build3DExtrudedUMesh_2(mN,mTT,mTF); - // - bool b=false; - int newNbOfNodes; - DataArrayInt *da=mTT->mergeNodes(1e-12,b,newNbOfNodes); - CPPUNIT_ASSERT(b); - da->decrRef(); - std::vector n; - double pt[3]={300.,300.,0.}; - double v[3]={0.,0.,2.}; - mTT->findNodesOnPlane(pt,v,1e-12,n); - CPPUNIT_ASSERT_EQUAL(43,(int)n.size()); - MEDCouplingUMesh *mTT3dSurf=(MEDCouplingUMesh *)mTT->buildFacePartOfMySelfNode(&n[0],&n[0]+n.size(),true); - MEDCouplingExtrudedMesh *meTT=MEDCouplingExtrudedMesh::New(mTT,mTT3dSurf,0); - CPPUNIT_ASSERT_EQUAL(200,meTT->getNumberOfCells()); - CPPUNIT_ASSERT_EQUAL(10,meTT->getMesh2D()->getNumberOfCells()); - CPPUNIT_ASSERT_EQUAL(20,meTT->getMesh1D()->getNumberOfCells()); - mTT3dSurf->decrRef(); - // - b=false; - da=mN->mergeNodes(1e-12,b,newNbOfNodes); - da->decrRef(); - CPPUNIT_ASSERT(!b); - n.clear(); - mN->findNodesOnPlane(pt,v,1e-12,n); - CPPUNIT_ASSERT_EQUAL(30,(int)n.size()); - MEDCouplingUMesh *mN3dSurf=(MEDCouplingUMesh *)mN->buildFacePartOfMySelfNode(&n[0],&n[0]+n.size(),true); - MEDCouplingExtrudedMesh *meN=MEDCouplingExtrudedMesh::New(mN,mN3dSurf,0); - CPPUNIT_ASSERT_EQUAL(40,meN->getNumberOfCells()); - CPPUNIT_ASSERT_EQUAL(20,meN->getMesh2D()->getNumberOfCells()); - CPPUNIT_ASSERT_EQUAL(2,meN->getMesh1D()->getNumberOfCells()); - mN3dSurf->decrRef(); - // - b=false; - da=mTF->mergeNodes(1e-12,b,newNbOfNodes); - da->decrRef(); - CPPUNIT_ASSERT(!b); - n.clear(); - mTF->findNodesOnPlane(pt,v,1e-12,n); - CPPUNIT_ASSERT_EQUAL(27,(int)n.size()); - MEDCouplingUMesh *mTF3dSurf=(MEDCouplingUMesh *)mTF->buildFacePartOfMySelfNode(&n[0],&n[0]+n.size(),true); - MEDCouplingExtrudedMesh *meTF=MEDCouplingExtrudedMesh::New(mTF,mTF3dSurf,0); - CPPUNIT_ASSERT_EQUAL(340,meTF->getNumberOfCells()); - CPPUNIT_ASSERT_EQUAL(17,meTF->getMesh2D()->getNumberOfCells()); - CPPUNIT_ASSERT_EQUAL(20,meTF->getMesh1D()->getNumberOfCells()); - mTF3dSurf->decrRef(); - // - meTT->decrRef(); - meN->decrRef(); - meTF->decrRef(); - // - mN->decrRef(); - mTT->decrRef(); - mTF->decrRef(); -} - -/*! - * This test check MEDCouplingUMesh::buildExtrudedMesh method. - */ -void MEDCouplingBasicsTest1::testExtrudedMesh3() -{ - MEDCouplingUMesh *m1=build2DTargetMesh_1(); - m1->changeSpaceDimension(3); - MEDCouplingUMesh *m2=buildCU1DMesh_U(); - m2->changeSpaceDimension(3); - double center[3]={0.,0.,0.}; - double vector[3]={0,1,0}; - m2->rotate(center,vector,-M_PI/2.); - MEDCouplingUMesh *m3=m1->buildExtrudedMesh(m2,0); - // - MEDCouplingExtrudedMesh *m4=MEDCouplingExtrudedMesh::New(m3,m1,0); - CPPUNIT_ASSERT_EQUAL(15,m4->getNumberOfCells()); - CPPUNIT_ASSERT_EQUAL(5,m4->getMesh2D()->getNumberOfCells()); - CPPUNIT_ASSERT_EQUAL(3,m4->getMesh1D()->getNumberOfCells()); - const int *m3DIds=m4->getMesh3DIds()->getConstPointer(); - for(int i=0;i<15;i++) - CPPUNIT_ASSERT_EQUAL(i,m3DIds[i]); - m4->decrRef(); - //some random in cells to check that extrusion alg find it correctly - const int expected1[15]={1,3,2,0,6,5,7,10,11,8,12,9,14,13,4}; - m3->renumberCells(expected1,false); - m4=MEDCouplingExtrudedMesh::New(m3,m1,0); - CPPUNIT_ASSERT_EQUAL(15,m4->getNumberOfCells()); - CPPUNIT_ASSERT_EQUAL(5,m4->getMesh2D()->getNumberOfCells()); - CPPUNIT_ASSERT_EQUAL(3,m4->getMesh1D()->getNumberOfCells()); - m3DIds=m4->getMesh3DIds()->getConstPointer(); - for(int i=0;i<15;i++) - CPPUNIT_ASSERT_EQUAL(expected1[i],m3DIds[i]); - m4->decrRef(); - m3->decrRef(); - //play with polygons and polyedrons - std::vector cells(2); cells[0]=2; cells[1]=3; - m1->convertToPolyTypes(&cells[0],&cells[0]+cells.size()); - m3=m1->buildExtrudedMesh(m2,0); - CPPUNIT_ASSERT_EQUAL((int)INTERP_KERNEL::NORM_HEXA8,(int)m3->getTypeOfCell(0)); - CPPUNIT_ASSERT_EQUAL((int)INTERP_KERNEL::NORM_PENTA6,(int)m3->getTypeOfCell(1)); - CPPUNIT_ASSERT_EQUAL((int)INTERP_KERNEL::NORM_POLYHED,(int)m3->getTypeOfCell(2)); - CPPUNIT_ASSERT_EQUAL((int)INTERP_KERNEL::NORM_POLYHED,(int)m3->getTypeOfCell(3)); - CPPUNIT_ASSERT_EQUAL((int)INTERP_KERNEL::NORM_HEXA8,(int)m3->getTypeOfCell(4)); - m3->renumberCells(expected1,false); - m4=MEDCouplingExtrudedMesh::New(m3,m1,0); - CPPUNIT_ASSERT_EQUAL(15,m4->getNumberOfCells()); - CPPUNIT_ASSERT_EQUAL(5,m4->getMesh2D()->getNumberOfCells()); - CPPUNIT_ASSERT_EQUAL(3,m4->getMesh1D()->getNumberOfCells()); - m3DIds=m4->getMesh3DIds()->getConstPointer(); - for(int i=0;i<15;i++) - CPPUNIT_ASSERT_EQUAL(expected1[i],m3DIds[i]); - m4->decrRef(); - m3->decrRef(); - // - m2->decrRef(); - m1->decrRef(); -} - -/*! - * This test check MEDCouplingUMesh::buildExtrudedMesh method, but also, MEDCouplingExtrudedMesh following methods : - * getCellContainingPoint getMeasureField getNodeIdsOfCell getCoordinateOfNode getTypeOfCell build3DUnstructuredMesh. - */ -void MEDCouplingBasicsTest1::testExtrudedMesh4() -{ - MEDCouplingUMesh *m1=build2DTargetMesh_1(); - std::vector cells(2); cells[0]=2; cells[1]=4; - m1->convertToPolyTypes(&cells[0],&cells[0]+cells.size()); - m1->changeSpaceDimension(3); - MEDCouplingUMesh *m2=buildCU1DMesh_U(); - m2->changeSpaceDimension(3); - double center[3]={0.,0.,0.}; - double vector[3]={0.,1.,0.}; - m2->rotate(center,vector,-M_PI/2.); - m1->zipCoords(); - MEDCouplingUMesh *m3=m1->buildExtrudedMesh(m2,0); - const int expected1[15]= {1,3,2,0,6,5,7,10,11,8,12,9,14,13,4}; - const int rexpected1[15]={3, 0, 2, 1, 14, 5, 4, 6, 9, 11, 7, 8, 10, 13, 12}; - m3->renumberCells(expected1,false); - MEDCouplingExtrudedMesh *m4=MEDCouplingExtrudedMesh::New(m3,m1,0); - CPPUNIT_ASSERT_EQUAL(INTERP_KERNEL::NORM_HEXA8,m4->getTypeOfCell(0)); - CPPUNIT_ASSERT_EQUAL(INTERP_KERNEL::NORM_HEXA8,m4->getTypeOfCell(1)); - CPPUNIT_ASSERT_EQUAL(INTERP_KERNEL::NORM_POLYHED,m4->getTypeOfCell(2)); - CPPUNIT_ASSERT_EQUAL(INTERP_KERNEL::NORM_PENTA6,m4->getTypeOfCell(7)); - MEDCouplingFieldDouble *f=m4->getMeasureField(true); - DataArrayDouble *arr=f->getArray(); - CPPUNIT_ASSERT_EQUAL(15,arr->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(1,arr->getNumberOfComponents()); - const double *arrPtr=arr->getConstPointer(); - const double expected2[15]={0.075,0.0375,0.0375,0.075,0.075, 0.1125,0.05625,0.05625,0.1125,0.1125, 0.0625,0.03125,0.03125,0.0625,0.0625}; - for(int i=0;i<15;i++) - CPPUNIT_ASSERT_DOUBLES_EQUAL(expected2[rexpected1[i]],arrPtr[i],1e-16); - f->decrRef(); - MEDCouplingUMesh *m5=m4->build3DUnstructuredMesh(); - m5->zipCoords(); - CPPUNIT_ASSERT(m5->isEqual(m3,1e-12)); - f=m5->getMeasureField(true); - arr=f->getArray(); - arrPtr=arr->getConstPointer(); - for(int i=0;i<15;i++) - CPPUNIT_ASSERT_DOUBLES_EQUAL(expected2[rexpected1[i]],arrPtr[i],1e-16); - f->decrRef(); - m5->decrRef(); - // - m4->decrRef(); - m3->decrRef(); - m2->decrRef(); - m1->decrRef(); -} - -void MEDCouplingBasicsTest1::testFindCommonNodes() -{ - DataArrayInt *comm,*commI; - MEDCouplingUMesh *targetMesh=build3DTargetMesh_1(); - targetMesh->findCommonNodes(1e-10,-1,comm,commI); - CPPUNIT_ASSERT_EQUAL(1,commI->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(0,comm->getNumberOfTuples()); - int newNbOfNodes; - DataArrayInt *o2n=targetMesh->buildNewNumberingFromCommonNodesFormat(comm,commI,newNbOfNodes); - CPPUNIT_ASSERT_EQUAL(27,newNbOfNodes); - CPPUNIT_ASSERT_EQUAL(27,o2n->getNumberOfTuples()); - const int o2nExp1[27]= - { - 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20, - 21,22,23,24,25,26 - }; - CPPUNIT_ASSERT(std::equal(o2nExp1,o2nExp1+27,o2n->getConstPointer())); - o2n->decrRef(); - comm->decrRef(); - commI->decrRef(); - targetMesh->decrRef(); - // - targetMesh=build3DTargetMeshMergeNode_1(); - CPPUNIT_ASSERT_EQUAL(31,targetMesh->getNumberOfNodes()); - targetMesh->findCommonNodes(1e-10,-1,comm,commI); - CPPUNIT_ASSERT_EQUAL(3,commI->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(6,comm->getNumberOfTuples()); - const int commExpected[6]={1,27,28,29,23,30}; - const int commIExpected[3]={0,4,6}; - CPPUNIT_ASSERT(std::equal(commExpected,commExpected+6,comm->getConstPointer())); - CPPUNIT_ASSERT(std::equal(commIExpected,commIExpected+3,commI->getConstPointer())); - o2n=targetMesh->buildNewNumberingFromCommonNodesFormat(comm,commI,newNbOfNodes); - CPPUNIT_ASSERT_EQUAL(31,o2n->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(27,newNbOfNodes); - const int o2nExp2[31]= - { - 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20, - 21,22,23,24,25,26,1,1,1,23 - }; - CPPUNIT_ASSERT(std::equal(o2nExp2,o2nExp2+31,o2n->getConstPointer())); - o2n->decrRef(); - comm->decrRef(); - commI->decrRef(); - targetMesh->decrRef(); - // - targetMesh=build3DTargetMesh_1(); - bool areNodesMerged; - unsigned int time=targetMesh->getTimeOfThis(); - o2n=targetMesh->mergeNodes(1e-10,areNodesMerged,newNbOfNodes); - targetMesh->updateTime(); - CPPUNIT_ASSERT(time==targetMesh->getTimeOfThis()); - CPPUNIT_ASSERT(!areNodesMerged); - targetMesh->decrRef(); - o2n->decrRef(); - // - targetMesh=build3DTargetMeshMergeNode_1(); - time=targetMesh->getTimeOfThis(); - o2n=targetMesh->mergeNodes(1e-10,areNodesMerged,newNbOfNodes); - targetMesh->updateTime(); - CPPUNIT_ASSERT(time!=targetMesh->getTimeOfThis()); - CPPUNIT_ASSERT(areNodesMerged); - int connExp[72]={18,0,1,4,3,9,10,13,12, 18,1,2,5,4,10,11,14,13, 18,3,4,7,6,12,13,16,15, - 18,4,5,8,7,13,14,17,16, - 18,9,10,13,12,18,19,22,21, 18,10,11,14,13,19,20,23,22, 18,12,13,16,15,21,22,25,24, - 18,13,14,17,16,22,23,26,25}; - CPPUNIT_ASSERT_EQUAL(72,targetMesh->getNodalConnectivity()->getNumberOfTuples()); - CPPUNIT_ASSERT(std::equal(connExp,connExp+72,targetMesh->getNodalConnectivity()->getConstPointer())); - CPPUNIT_ASSERT_EQUAL(27,targetMesh->getCoords()->getNumberOfTuples()); - double coordsExp[81]={ 0., 0., 0., 50., 0., 0. , 200., 0., 0. , 0., 50., 0., 50., 50., 0. , - 200., 50., 0., 0., 200., 0., 50., 200., 0. , 200., 200., 0. , - 0., 0., 50., 50., 0., 50. , 200., 0., 50. , 0., 50., 50., 50., - 50., 50. , 200., 50., 50., 0., 200., 50., 50., 200., 50. , - 200., 200., 50. , 0., 0., 200., 50., 0., 200. , 200., 0., 200. - , 0., 50., 200., 50., 50., 200. , 200., 50., 200., - 0., 200., 200., 50., 200., 200. , 200., 200., 200. }; - CPPUNIT_ASSERT(std::equal(coordsExp,coordsExp+81,targetMesh->getCoords()->getConstPointer())); - targetMesh->decrRef(); - o2n->decrRef(); - //2D - targetMesh=build2DTargetMeshMergeNode_1(); - CPPUNIT_ASSERT_EQUAL(18,targetMesh->getNumberOfNodes()); - time=targetMesh->getTimeOfThis(); - o2n=targetMesh->mergeNodes(1e-10,areNodesMerged,newNbOfNodes); - CPPUNIT_ASSERT(time!=targetMesh->getTimeOfThis()); - CPPUNIT_ASSERT(areNodesMerged); - CPPUNIT_ASSERT_EQUAL(9,targetMesh->getNumberOfNodes()); - int connExp2[23]={4,0,4,3,1, 3,1,3,2, 3,3,5,2, 4,4,6,7,3, 4,7,8,5,3}; - CPPUNIT_ASSERT_EQUAL(23,targetMesh->getNodalConnectivity()->getNumberOfTuples()); - CPPUNIT_ASSERT(std::equal(connExp2,connExp2+23,targetMesh->getNodalConnectivity()->getConstPointer())); - double coordsExp2[18]={-0.3,-0.3, 0.2,-0.3, 0.7,-0.3, 0.2,0.2, -0.3,0.2, 0.7,0.2, -0.3,0.7, 0.2,0.7, 0.7,0.7}; - CPPUNIT_ASSERT_EQUAL(9,targetMesh->getCoords()->getNumberOfTuples()); - CPPUNIT_ASSERT(std::equal(coordsExp2,coordsExp2+18,targetMesh->getCoords()->getConstPointer())); - targetMesh->decrRef(); - o2n->decrRef(); -} - -void MEDCouplingBasicsTest1::testCheckButterflyCells() -{ - std::vector cells; - MEDCouplingUMesh *sourceMesh=build2DTargetMesh_1(); - sourceMesh->checkButterflyCells(cells); - CPPUNIT_ASSERT(cells.empty()); - int *pt=sourceMesh->getNodalConnectivity()->getPointer(); - std::swap(pt[15],pt[16]); - sourceMesh->checkButterflyCells(cells); - CPPUNIT_ASSERT_EQUAL(1,(int)cells.size()); - CPPUNIT_ASSERT_EQUAL(3,cells[0]); - cells.clear(); - std::swap(pt[15],pt[16]); - sourceMesh->checkButterflyCells(cells); - CPPUNIT_ASSERT(cells.empty()); - sourceMesh->decrRef(); - // 3D surf - sourceMesh=build3DSurfTargetMesh_1(); - sourceMesh->checkButterflyCells(cells); - CPPUNIT_ASSERT(cells.empty()); - pt=sourceMesh->getNodalConnectivity()->getPointer(); - std::swap(pt[15],pt[16]); - sourceMesh->checkButterflyCells(cells); - CPPUNIT_ASSERT_EQUAL(1,(int)cells.size()); - CPPUNIT_ASSERT_EQUAL(3,cells[0]); - cells.clear(); - std::swap(pt[15],pt[16]); - sourceMesh->checkButterflyCells(cells); - CPPUNIT_ASSERT(cells.empty()); - sourceMesh->decrRef(); -} - -void MEDCouplingBasicsTest1::testMergeMesh1() -{ - MEDCouplingUMesh *m1=build2DTargetMesh_1(); - MEDCouplingUMesh *m2=build2DSourceMesh_1(); - const double vec[2]={1.,0.}; - m2->translate(vec); - MEDCouplingMesh *m3=m1->mergeMyselfWith(m2); - MEDCouplingUMesh *m3C=dynamic_cast(m3); - CPPUNIT_ASSERT(m3C); - m3->checkCoherency(); - MEDCouplingUMesh *m4=build2DTargetMeshMerged_1(); - CPPUNIT_ASSERT(m3->isEqual(m4,1.e-12)); - m4->decrRef(); - bool isMerged; - int newNbOfNodes; - DataArrayInt *da=m3C->mergeNodes(1.e-12,isMerged,newNbOfNodes); - CPPUNIT_ASSERT_EQUAL(11,m3C->getNumberOfNodes()); - CPPUNIT_ASSERT_EQUAL(11,newNbOfNodes); - CPPUNIT_ASSERT(isMerged); - da->decrRef(); - m3->decrRef(); - m1->decrRef(); - m2->decrRef(); -} - -void MEDCouplingBasicsTest1::testMergeMeshOnSameCoords1() -{ - MEDCouplingUMesh *m1=build2DTargetMesh_1(); - MEDCouplingUMesh *m2=build2DTargetMesh_1(); - std::vector cells(5); - for(int i=0;i<5;i++) - cells[i]=i; - m2->convertToPolyTypes(&cells[0],&cells[0]+cells.size()); - m1->tryToShareSameCoords(*m2,1e-12); - MEDCouplingUMesh *m3=build2DTargetMesh_1(); - m3->tryToShareSameCoords(*m2,1e-12); - std::vector meshes; - meshes.push_back(m1); meshes.push_back(m2); meshes.push_back(m3); - MEDCouplingUMesh *m4=MEDCouplingUMesh::MergeUMeshesOnSameCoords(meshes); - m4->checkCoherency(); - CPPUNIT_ASSERT(m4->getCoords()==m1->getCoords()); - CPPUNIT_ASSERT_EQUAL(15,m4->getNumberOfCells()); - const int cells1[5]={0,1,2,3,4}; - MEDCouplingPointSet *m1_1=m4->buildPartOfMySelf(cells1,cells1+5,true); - m1_1->setName(m1->getName().c_str()); - CPPUNIT_ASSERT(m1->isEqual(m1_1,1e-12)); - const int cells2[5]={5,6,7,8,9}; - MEDCouplingPointSet *m2_1=m4->buildPartOfMySelf(cells2,cells2+5,true); - m2_1->setName(m2->getName().c_str()); - CPPUNIT_ASSERT(m2->isEqual(m2_1,1e-12)); - const int cells3[5]={10,11,12,13,14}; - MEDCouplingPointSet *m3_1=m4->buildPartOfMySelf(cells3,cells3+5,true); - m3_1->setName(m3->getName().c_str()); - CPPUNIT_ASSERT(m3->isEqual(m3_1,1e-12)); - m1_1->decrRef(); m2_1->decrRef(); m3_1->decrRef(); - // - m4->decrRef(); - m1->decrRef(); - m2->decrRef(); - m3->decrRef(); -} - -void MEDCouplingBasicsTest1::testMergeField1() -{ - MEDCouplingUMesh *m1=build2DTargetMesh_1(); - MEDCouplingUMesh *m2=build2DSourceMesh_1(); - const double vec[2]={1.,0.}; - m2->translate(vec); - MEDCouplingFieldDouble *f1=m1->getMeasureField(true); - MEDCouplingFieldDouble *f2=m2->getMeasureField(true); - MEDCouplingFieldDouble *f3=MEDCouplingFieldDouble::MergeFields(f1,f2); - f3->checkCoherency(); - MEDCouplingUMesh *m4=build2DTargetMeshMerged_1(); - CPPUNIT_ASSERT(f3->getMesh()->isEqual(m4,1.e-12)); - std::string name=f3->getName(); - CPPUNIT_ASSERT(name=="MeasureOfMesh_"); - CPPUNIT_ASSERT(f3->getTypeOfField()==ON_CELLS); - CPPUNIT_ASSERT(f3->getTimeDiscretization()==ONE_TIME); - CPPUNIT_ASSERT_EQUAL(1,f3->getNumberOfComponents()); - CPPUNIT_ASSERT_EQUAL(7,f3->getNumberOfTuples()); - double values[7]={0.25,0.125,0.125,0.25,0.25,0.5,0.5}; - const double *tmp=f3->getArray()->getConstPointer(); - std::transform(tmp,tmp+7,values,values,std::minus()); - std::transform(values,values+7,values,std::ptr_fun(fabs)); - double max=*std::max_element(values,values+7); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.,max,1.e-12); - m4->decrRef(); - f3->decrRef(); - f1->decrRef(); - f2->decrRef(); - m1->decrRef(); - m2->decrRef(); -} - -bool func1(const double *pt, double *res); -bool func2(const double *pt, double *res); -bool func3(const double *pt, double *res); -bool func4(const double *pt, double *res); - -bool func1(const double *pt, double *res) -{ - res[0]=pt[0]+pt[1]; - return true; -} - -bool func2(const double *pt, double *res) -{ - res[0]=pt[0]+pt[1]; - res[1]=2.*(pt[0]+pt[1]); - return true; -} - -bool func3(const double *pt, double *res) -{ - if(fabs(pt[0]-0.2)<1e-12) - return false; - res[0]=1./(pt[0]-0.2); - return true; -} - -void MEDCouplingBasicsTest1::testFillFromAnalytic() -{ - MEDCouplingUMesh *m=build2DTargetMesh_1(); - m->setTime(3.4,5,6); m->setTimeUnit("us"); - int a,b; - MEDCouplingFieldDouble *f1=m->fillFromAnalytic(ON_CELLS,1,func1); - CPPUNIT_ASSERT_DOUBLES_EQUAL(3.4,f1->getTime(a,b),1.e-14); - CPPUNIT_ASSERT_EQUAL(5,a); CPPUNIT_ASSERT_EQUAL(6,b); - CPPUNIT_ASSERT_EQUAL(std::string(f1->getTimeUnit()),std::string("us")); - f1->checkCoherency(); - CPPUNIT_ASSERT(f1->getTypeOfField()==ON_CELLS); - CPPUNIT_ASSERT(f1->getTimeDiscretization()==ONE_TIME); - CPPUNIT_ASSERT_EQUAL(1,f1->getNumberOfComponents()); - CPPUNIT_ASSERT_EQUAL(5,f1->getNumberOfTuples()); - double values1[5]={-0.1,0.23333333333333336,0.56666666666666665,0.4,0.9}; - const double *tmp=f1->getArray()->getConstPointer(); - std::transform(tmp,tmp+5,values1,values1,std::minus()); - std::transform(values1,values1+5,values1,std::ptr_fun(fabs)); - double max=*std::max_element(values1,values1+5); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.,max,1.e-12); - f1->decrRef(); - // - f1=m->fillFromAnalytic(ON_NODES,1,func1); - f1->checkCoherency(); - CPPUNIT_ASSERT(f1->getTypeOfField()==ON_NODES); - CPPUNIT_ASSERT(f1->getTimeDiscretization()==ONE_TIME); - CPPUNIT_ASSERT_EQUAL(1,f1->getNumberOfComponents()); - CPPUNIT_ASSERT_EQUAL(9,f1->getNumberOfTuples()); - double values2[9]={-0.6,-0.1,0.4,-0.1,0.4,0.9,0.4,0.9,1.4}; - tmp=f1->getArray()->getConstPointer(); - std::transform(tmp,tmp+9,values2,values2,std::minus()); - std::transform(values2,values2+9,values2,std::ptr_fun(fabs)); - max=*std::max_element(values2,values2+9); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.,max,1.e-12); - f1->decrRef(); - // - f1=m->fillFromAnalytic(ON_NODES,2,func2); - f1->checkCoherency(); - CPPUNIT_ASSERT(f1->getTypeOfField()==ON_NODES); - CPPUNIT_ASSERT(f1->getTimeDiscretization()==ONE_TIME); - CPPUNIT_ASSERT_EQUAL(2,f1->getNumberOfComponents()); - CPPUNIT_ASSERT_EQUAL(9,f1->getNumberOfTuples()); - double values3[18]={-0.6,-1.2,-0.1,-0.2,0.4,0.8,-0.1,-0.2,0.4,0.8,0.9,1.8,0.4,0.8,0.9,1.8,1.4,2.8}; - tmp=f1->getArray()->getConstPointer(); - std::transform(tmp,tmp+18,values3,values3,std::minus()); - std::transform(values3,values3+18,values3,std::ptr_fun(fabs)); - max=*std::max_element(values3,values3+18); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.,max,1.e-12); - double values4[2]; - f1->accumulate(values4); - CPPUNIT_ASSERT_DOUBLES_EQUAL(3.6,values4[0],1.e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(7.2,values4[1],1.e-12); - f1->integral(true,values4); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.5,values4[0],1.e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,values4[1],1.e-12); - f1->decrRef(); - // - CPPUNIT_ASSERT_THROW(f1=m->fillFromAnalytic(ON_NODES,1,func3),INTERP_KERNEL::Exception); - // - m->decrRef(); -} - -void MEDCouplingBasicsTest1::testFillFromAnalytic2() -{ - MEDCouplingUMesh *m=build2DTargetMesh_1(); - MEDCouplingFieldDouble *f1=m->fillFromAnalytic(ON_CELLS,1,"y+x"); - f1->checkCoherency(); - CPPUNIT_ASSERT(f1->getTypeOfField()==ON_CELLS); - CPPUNIT_ASSERT(f1->getTimeDiscretization()==ONE_TIME); - CPPUNIT_ASSERT_EQUAL(1,f1->getNumberOfComponents()); - CPPUNIT_ASSERT_EQUAL(5,f1->getNumberOfTuples()); - double values1[5]={-0.1,0.23333333333333336,0.56666666666666665,0.4,0.9}; - const double *tmp=f1->getArray()->getConstPointer(); - std::transform(tmp,tmp+5,values1,values1,std::minus()); - std::transform(values1,values1+5,values1,std::ptr_fun(fabs)); - double max=*std::max_element(values1,values1+5); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.,max,1.e-12); - f1->decrRef(); - // - f1=m->fillFromAnalytic(ON_NODES,1,"y+2*x"); - f1->checkCoherency(); - CPPUNIT_ASSERT(f1->getTypeOfField()==ON_NODES); - CPPUNIT_ASSERT(f1->getTimeDiscretization()==ONE_TIME); - CPPUNIT_ASSERT_EQUAL(1,f1->getNumberOfComponents()); - CPPUNIT_ASSERT_EQUAL(9,f1->getNumberOfTuples()); - double values2[9]={-0.9,0.1,1.1,-0.4,0.6,1.6,0.1,1.1,2.1}; - tmp=f1->getArray()->getConstPointer(); - std::transform(tmp,tmp+9,values2,values2,std::minus()); - std::transform(values2,values2+9,values2,std::ptr_fun(fabs)); - max=*std::max_element(values2,values2+9); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.,max,1.e-12); - f1->decrRef(); - f1=m->fillFromAnalytic(ON_NODES,1,"2.*x+y"); - f1->checkCoherency(); - CPPUNIT_ASSERT(f1->getTypeOfField()==ON_NODES); - CPPUNIT_ASSERT(f1->getTimeDiscretization()==ONE_TIME); - CPPUNIT_ASSERT_EQUAL(1,f1->getNumberOfComponents()); - CPPUNIT_ASSERT_EQUAL(9,f1->getNumberOfTuples()); - tmp=f1->getArray()->getConstPointer(); - double values2Bis[9]={-0.9,0.1,1.1,-0.4,0.6,1.6,0.1,1.1,2.1}; - std::transform(tmp,tmp+9,values2Bis,values2Bis,std::minus()); - std::transform(values2,values2+9,values2Bis,std::ptr_fun(fabs)); - max=*std::max_element(values2Bis,values2Bis+9); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.,max,1.e-12); - f1->decrRef(); - // - f1=m->fillFromAnalytic(ON_NODES,2,"(x+y)*IVec+2*(x+y)*JVec"); - f1->checkCoherency(); - CPPUNIT_ASSERT(f1->getTypeOfField()==ON_NODES); - CPPUNIT_ASSERT(f1->getTimeDiscretization()==ONE_TIME); - CPPUNIT_ASSERT_EQUAL(2,f1->getNumberOfComponents()); - CPPUNIT_ASSERT_EQUAL(9,f1->getNumberOfTuples()); - double values3[18]={-0.6,-1.2,-0.1,-0.2,0.4,0.8,-0.1,-0.2,0.4,0.8,0.9,1.8,0.4,0.8,0.9,1.8,1.4,2.8}; - tmp=f1->getArray()->getConstPointer(); - std::transform(tmp,tmp+18,values3,values3,std::minus()); - std::transform(values3,values3+18,values3,std::ptr_fun(fabs)); - max=*std::max_element(values3,values3+18); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.,max,1.e-12); - double values4[2]; - f1->accumulate(values4); - CPPUNIT_ASSERT_DOUBLES_EQUAL(3.6,values4[0],1.e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(7.2,values4[1],1.e-12); - f1->integral(true,values4); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.5,values4[0],1.e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,values4[1],1.e-12); - f1->decrRef(); - // - CPPUNIT_ASSERT_THROW(f1=m->fillFromAnalytic(ON_NODES,1,"1./(x-0.2)"),INTERP_KERNEL::Exception); - // - m->decrRef(); -} - -void MEDCouplingBasicsTest1::testApplyFunc() -{ - MEDCouplingUMesh *m=build2DTargetMesh_1(); - MEDCouplingFieldDouble *f1=m->fillFromAnalytic(ON_NODES,2,func2); - f1->checkCoherency(); - CPPUNIT_ASSERT(f1->getTypeOfField()==ON_NODES); - CPPUNIT_ASSERT(f1->getTimeDiscretization()==ONE_TIME); - CPPUNIT_ASSERT_EQUAL(2,f1->getNumberOfComponents()); - CPPUNIT_ASSERT_EQUAL(9,f1->getNumberOfTuples()); - f1->applyFunc(1,func1); - CPPUNIT_ASSERT(f1->getTypeOfField()==ON_NODES); - CPPUNIT_ASSERT(f1->getTimeDiscretization()==ONE_TIME); - CPPUNIT_ASSERT_EQUAL(1,f1->getNumberOfComponents()); - CPPUNIT_ASSERT_EQUAL(9,f1->getNumberOfTuples()); - double values1[9]={-1.8,-0.3,1.2,-0.3,1.2,2.7,1.2,2.7,4.2}; - const double *tmp=f1->getArray()->getConstPointer(); - std::transform(tmp,tmp+9,values1,values1,std::minus()); - std::transform(values1,values1+9,values1,std::ptr_fun(fabs)); - double max=*std::max_element(values1,values1+9); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.,max,1.e-12); - f1->decrRef(); - m->decrRef(); -} - -void MEDCouplingBasicsTest1::testApplyFunc2() -{ - MEDCouplingUMesh *m=build2DTargetMesh_1(); - MEDCouplingFieldDouble *f1=m->fillFromAnalytic(ON_NODES,2,func2); - f1->checkCoherency(); - CPPUNIT_ASSERT(f1->getTypeOfField()==ON_NODES); - CPPUNIT_ASSERT(f1->getTimeDiscretization()==ONE_TIME); - CPPUNIT_ASSERT_EQUAL(2,f1->getNumberOfComponents()); - CPPUNIT_ASSERT_EQUAL(9,f1->getNumberOfTuples()); - // - MEDCouplingFieldDouble *f2=f1->clone(true); - CPPUNIT_ASSERT_THROW(f2->applyFunc(1,"a+b+c+d"),INTERP_KERNEL::Exception); - CPPUNIT_ASSERT_THROW(f2->applyFunc(1,"a/0"),INTERP_KERNEL::Exception); - CPPUNIT_ASSERT_THROW(f2->applyFunc("a/0"),INTERP_KERNEL::Exception); - f2->applyFunc("abs(u)^2.4+2*u"); - CPPUNIT_ASSERT(f1->getTypeOfField()==ON_NODES); - CPPUNIT_ASSERT(f1->getTimeDiscretization()==ONE_TIME); - CPPUNIT_ASSERT_EQUAL(2,f1->getNumberOfComponents()); - CPPUNIT_ASSERT_EQUAL(9,f1->getNumberOfTuples()); - double values2[18]={-0.9065304805418678, -0.85105859001709905, -0.19601892829446504, -0.37898777756476987, - 0.91090317490482353, 2.1853504664669781, -0.19601892829446504, -0.37898777756476987, - 0.91090317490482353, 2.1853504664669781, 2.5765725275664879, 7.6987743736515295, - 0.91090317490482353, 2.1853504664669781, 2.5765725275664879, 7.6987743736515295, - 5.0423700574830965, 17.435300118916864}; - const double *tmp=f2->getArray()->getConstPointer(); - std::transform(tmp,tmp+18,values2,values2,std::minus()); - std::transform(values2,values2+18,values2,std::ptr_fun(fabs)); - double max=*std::max_element(values2,values2+18); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.,max,1.e-12); - f2->decrRef(); - // - f1->applyFunc(1,"x+y"); - CPPUNIT_ASSERT(f1->getTypeOfField()==ON_NODES); - CPPUNIT_ASSERT(f1->getTimeDiscretization()==ONE_TIME); - CPPUNIT_ASSERT_EQUAL(1,f1->getNumberOfComponents()); - CPPUNIT_ASSERT_EQUAL(9,f1->getNumberOfTuples()); - double values1[9]={-1.8,-0.3,1.2,-0.3,1.2,2.7,1.2,2.7,4.2}; - tmp=f1->getArray()->getConstPointer(); - std::transform(tmp,tmp+9,values1,values1,std::minus()); - std::transform(values1,values1+9,values1,std::ptr_fun(fabs)); - max=*std::max_element(values1,values1+9); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.,max,1.e-12); - f1->decrRef(); - m->decrRef(); -} - -void MEDCouplingBasicsTest1::testOperationsOnFields() -{ - MEDCouplingUMesh *m=build2DTargetMesh_1(); - MEDCouplingFieldDouble *f1=m->fillFromAnalytic(ON_NODES,1,func1); - MEDCouplingFieldDouble *f2=m->fillFromAnalytic(ON_NODES,1,func1); - f1->checkCoherency(); - f2->checkCoherency(); - MEDCouplingFieldDouble *f3=(*f1)+(*f2); - f3->checkCoherency(); - CPPUNIT_ASSERT(f3->getTypeOfField()==ON_NODES); - CPPUNIT_ASSERT(f3->getTimeDiscretization()==ONE_TIME); - double values1[9]={-1.2,-0.2,0.8,-0.2,0.8,1.8,0.8,1.8,2.8}; - const double *tmp=f3->getArray()->getConstPointer(); - std::transform(tmp,tmp+9,values1,values1,std::minus()); - std::transform(values1,values1+9,values1,std::ptr_fun(fabs)); - double max=*std::max_element(values1,values1+9); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.,max,1.e-12); - f3->decrRef(); - // - f3=(*f1)*(*f2); - f3->checkCoherency(); - CPPUNIT_ASSERT(f3->getTypeOfField()==ON_NODES); - CPPUNIT_ASSERT(f3->getTimeDiscretization()==ONE_TIME); - double values2[9]={0.36,0.01,0.16,0.01,0.16,0.81,0.16,0.81,1.96}; - tmp=f3->getArray()->getConstPointer(); - std::transform(tmp,tmp+9,values2,values2,std::minus()); - std::transform(values2,values2+9,values2,std::ptr_fun(fabs)); - max=*std::max_element(values2,values2+9); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.,max,1.e-12); - f3->decrRef(); - // - f3=(*f1)+(*f2); - MEDCouplingFieldDouble *f4=(*f1)-(*f3); - f4->checkCoherency(); - CPPUNIT_ASSERT(f4->getTypeOfField()==ON_NODES); - CPPUNIT_ASSERT(f4->getTimeDiscretization()==ONE_TIME); - double values3[9]={0.6,0.1,-0.4,0.1,-0.4,-0.9,-0.4,-0.9,-1.4}; - tmp=f4->getArray()->getConstPointer(); - std::transform(tmp,tmp+9,values3,values3,std::minus()); - std::transform(values3,values3+9,values3,std::ptr_fun(fabs)); - max=*std::max_element(values3,values3+9); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.,max,1.e-12); - f3->decrRef(); - f4->decrRef(); - // - f3=(*f1)+(*f2); - f4=(*f3)/(*f2); - f4->checkCoherency(); - CPPUNIT_ASSERT(f4->getTypeOfField()==ON_NODES); - CPPUNIT_ASSERT(f4->getTimeDiscretization()==ONE_TIME); - tmp=f4->getArray()->getConstPointer(); - for(int i=0;i<9;i++) - CPPUNIT_ASSERT_DOUBLES_EQUAL(2.,tmp[i],1.e-12); - f3->decrRef(); - f4->decrRef(); - // - f4=f2->buildNewTimeReprFromThis(NO_TIME,false); - f4->checkCoherency(); - CPPUNIT_ASSERT(f4->getArray()==f2->getArray()); - CPPUNIT_ASSERT(f4->getTypeOfField()==ON_NODES); - CPPUNIT_ASSERT(f4->getTimeDiscretization()==NO_TIME); - CPPUNIT_ASSERT_THROW(f3=(*f1)+(*f4),INTERP_KERNEL::Exception); - MEDCouplingFieldDouble *f5=f4->buildNewTimeReprFromThis(ONE_TIME,false); - CPPUNIT_ASSERT(f4->getArray()==f5->getArray()); - CPPUNIT_ASSERT(f5->getTypeOfField()==ON_NODES); - CPPUNIT_ASSERT(f5->getTimeDiscretization()==ONE_TIME); - f3=(*f1)+(*f5); - tmp=f3->getArray()->getConstPointer(); - double values4[9]={-1.2,-0.2,0.8,-0.2,0.8,1.8,0.8,1.8,2.8}; - std::transform(tmp,tmp+9,values4,values4,std::minus()); - std::transform(values4,values4+9,values4,std::ptr_fun(fabs)); - max=*std::max_element(values4,values4+9); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.,max,1.e-12); - f5->decrRef(); - f4->decrRef(); - f3->decrRef(); - // - f4=f2->buildNewTimeReprFromThis(NO_TIME,true); - f4->checkCoherency(); - CPPUNIT_ASSERT(f4->getArray()!=f2->getArray()); - CPPUNIT_ASSERT(f4->getTypeOfField()==ON_NODES); - CPPUNIT_ASSERT(f4->getTimeDiscretization()==NO_TIME); - CPPUNIT_ASSERT_THROW(f3=(*f1)+(*f4),INTERP_KERNEL::Exception); - f5=f4->buildNewTimeReprFromThis(ONE_TIME,true); - CPPUNIT_ASSERT(f4->getArray()!=f5->getArray()); - CPPUNIT_ASSERT(f2->getArray()!=f5->getArray()); - CPPUNIT_ASSERT(f5->getTypeOfField()==ON_NODES); - CPPUNIT_ASSERT(f5->getTimeDiscretization()==ONE_TIME); - f3=(*f1)+(*f5); - tmp=f3->getArray()->getConstPointer(); - double values5[9]={-1.2,-0.2,0.8,-0.2,0.8,1.8,0.8,1.8,2.8}; - std::transform(tmp,tmp+9,values5,values5,std::minus()); - std::transform(values5,values5+9,values5,std::ptr_fun(fabs)); - max=*std::max_element(values5,values5+9); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.,max,1.e-12); - f5->decrRef(); - f4->decrRef(); - f3->decrRef(); - // - f1->decrRef(); - f2->decrRef(); - m->decrRef(); -} - -void MEDCouplingBasicsTest1::testOperationsOnFields2() -{ - MEDCouplingUMesh *m=build3DSurfTargetMesh_1(); - m->setTime(3.4,5,6); m->setTimeUnit("us"); - int a,b; - MEDCouplingFieldDouble *f1=m->fillFromAnalytic(ON_NODES,1,"x+y+z"); - MEDCouplingFieldDouble *f2=m->fillFromAnalytic(ON_NODES,1,"a*a+b+c*c"); - MEDCouplingFieldDouble *f3=(*f1)/(*f2); - f3->checkCoherency(); - CPPUNIT_ASSERT(f3->getTypeOfField()==ON_NODES); - CPPUNIT_ASSERT(f3->getTimeDiscretization()==ONE_TIME); - const double expected1[9]={-2.4999999999999991, 1.2162162162162162, 0.77868852459016391, - 0.7407407407407407, 1.129032258064516, 0.81632653061224492, - 0.86538461538461531, 1.0919540229885056, 0.84302325581395343}; - CPPUNIT_ASSERT_EQUAL(1,f3->getNumberOfComponents()); - CPPUNIT_ASSERT_EQUAL(9,f3->getNumberOfTuples()); - const double *val=f3->getArray()->getConstPointer(); - for(int i=0;i<9;i++) - CPPUNIT_ASSERT_DOUBLES_EQUAL(expected1[i],val[i],1.e-12); - f3->decrRef(); - f1->decrRef(); - f2->decrRef(); - // - f1=m->buildOrthogonalField(); - CPPUNIT_ASSERT_DOUBLES_EQUAL(3.4,f1->getTime(a,b),1.e-14); - CPPUNIT_ASSERT_EQUAL(5,a); CPPUNIT_ASSERT_EQUAL(6,b); - CPPUNIT_ASSERT_EQUAL(std::string(f1->getTimeUnit()),std::string("us")); - f2=m->fillFromAnalytic(ON_CELLS,1,"x"); - f3=(*f1)*(*f2); - const double expected2[15]={-0.035355339059327376,0.,0.035355339059327376, 0.2592724864350674,0.,-0.2592724864350674, 0.37712361663282529,0.,-0.37712361663282529, -0.035355339059327376,0.,0.035355339059327376, 0.31819805153394637,0.,-0.31819805153394637}; - val=f3->getArray()->getConstPointer(); - for(int i=0;i<15;i++) - CPPUNIT_ASSERT_DOUBLES_EQUAL(expected2[i],val[i],1.e-12); - f3->decrRef(); - // - f3=(*f2)*(*f1); - val=f3->getArray()->getConstPointer(); - for(int i=0;i<15;i++) - CPPUNIT_ASSERT_DOUBLES_EQUAL(expected2[i],val[i],1.e-12); - f3->decrRef(); - // - f1->decrRef(); - f2->decrRef(); - // - m->decrRef(); -} - -void MEDCouplingBasicsTest1::testOperationsOnFields3() -{ - MEDCouplingUMesh *m=build3DSurfTargetMesh_1(); - MEDCouplingFieldDouble *f1=m->fillFromAnalytic(ON_NODES,1,"x+y+z"); - MEDCouplingFieldDouble *f2=m->fillFromAnalytic(ON_NODES,1,"a*a+b+c*c"); - (*f1)/=(*f2); - f1->checkCoherency(); - CPPUNIT_ASSERT(f1->getTypeOfField()==ON_NODES); - CPPUNIT_ASSERT(f1->getTimeDiscretization()==ONE_TIME); - const double expected1[9]={-2.4999999999999991, 1.2162162162162162, 0.77868852459016391, - 0.7407407407407407, 1.129032258064516, 0.81632653061224492, - 0.86538461538461531, 1.0919540229885056, 0.84302325581395343}; - CPPUNIT_ASSERT_EQUAL(1,f1->getNumberOfComponents()); - CPPUNIT_ASSERT_EQUAL(9,f1->getNumberOfTuples()); - const double *val=f1->getArray()->getConstPointer(); - for(int i=0;i<9;i++) - CPPUNIT_ASSERT_DOUBLES_EQUAL(expected1[i],val[i],1.e-12); - f1->decrRef(); - f2->decrRef(); - // - f1=m->buildOrthogonalField(); - f2=m->fillFromAnalytic(ON_CELLS,1,"x"); - (*f1)*=(*f2); - const double expected2[15]={-0.035355339059327376,0.,0.035355339059327376, 0.2592724864350674,0.,-0.2592724864350674, 0.37712361663282529,0.,-0.37712361663282529, -0.035355339059327376,0.,0.035355339059327376, 0.31819805153394637,0.,-0.31819805153394637}; - val=f1->getArray()->getConstPointer(); - for(int i=0;i<15;i++) - CPPUNIT_ASSERT_DOUBLES_EQUAL(expected2[i],val[i],1.e-12); - f1->decrRef(); - // - f1=m->buildOrthogonalField(); - CPPUNIT_ASSERT_THROW((*f2)*=(*f1),INTERP_KERNEL::Exception); - f1->decrRef(); - f2->decrRef(); - // - m->decrRef(); -} - -/*! - * Check of LINEAR_TIME and CONST_ON_TIME_INTERVAL policies - */ -void MEDCouplingBasicsTest1::testOperationsOnFields4() -{ - MEDCouplingUMesh *m=build2DTargetMesh_1(); - int nbOfCells=m->getNumberOfCells(); - MEDCouplingFieldDouble *f1=MEDCouplingFieldDouble::New(ON_CELLS,CONST_ON_TIME_INTERVAL); - f1->setMesh(m); - DataArrayDouble *array=DataArrayDouble::New(); - array->alloc(nbOfCells,3); - f1->setArray(array); - CPPUNIT_ASSERT_THROW(f1->setEndArray(array),INTERP_KERNEL::Exception); - CPPUNIT_ASSERT_THROW(f1->getEndArray(),INTERP_KERNEL::Exception); - array->decrRef(); - double *tmp=array->getPointer(); - const double arr1[15]={0.,10.,20.,1.,11.,21.,2.,12.,22.,3.,13.,23.,4.,14.,24.}; - const double arr2[15]={5.,15.,25.,6.,16.,26.,7.,17.,27.,8.,18.,28.,9.,19.,29.}; - std::copy(arr1,arr1+15,tmp); - f1->setStartTime(2.,0,0); - f1->setEndTime(3.,0,0); - f1->checkCoherency(); - double res[3]; - const double pos[2]={0.3,-0.2}; - f1->getValueOn(pos,res); - CPPUNIT_ASSERT_DOUBLES_EQUAL(arr1[3],res[0],1.e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(arr1[4],res[1],1.e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(arr1[5],res[2],1.e-12); - std::fill(res,res+3,0.); - f1->getValueOn(pos,2.2,res); - CPPUNIT_ASSERT_DOUBLES_EQUAL(arr1[3],res[0],1.e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(arr1[4],res[1],1.e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(arr1[5],res[2],1.e-12); - std::fill(res,res+3,0.); - CPPUNIT_ASSERT_THROW(f1->getValueOn(pos,3.2,res),INTERP_KERNEL::Exception); - MEDCouplingFieldDouble *f2=MEDCouplingFieldDouble::New(ON_CELLS,LINEAR_TIME); - f2->setMesh(m); - f2->setArray(f1->getArray()); - f2->setStartTime(2.,3,0); - f2->setEndTime(4.,13,0); - CPPUNIT_ASSERT_THROW(f2->checkCoherency(),INTERP_KERNEL::Exception); - DataArrayDouble *array2=DataArrayDouble::New(); - array2->alloc(nbOfCells,3); - tmp=array2->getPointer(); - std::copy(arr2,arr2+15,tmp); - f2->setEndArray(array2); - array2->decrRef(); - f2->checkCoherency(); - // - std::fill(res,res+3,0.); - f2->getValueOn(pos,3.21,res); - CPPUNIT_ASSERT_DOUBLES_EQUAL(4.025,res[0],1.e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(14.025,res[1],1.e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(24.025,res[2],1.e-12); - MEDCouplingFieldDouble *f3=f2->clone(true); - CPPUNIT_ASSERT(f2->isEqual(f3,1e-12,1e-12)); - f3->getEndArray()->getPointer()[0]=5.001; - CPPUNIT_ASSERT(!f2->isEqual(f3,1e-12,1e-12)); - CPPUNIT_ASSERT(f2->isEqual(f3,1e-12,1e-2)); - f3->setStartTime(2.1,3,0); - CPPUNIT_ASSERT(!f2->isEqual(f3,1e-12,1e-2)); - f3->setStartTime(2.,3,0); - CPPUNIT_ASSERT(f2->isEqual(f3,1e-12,1e-2)); - f3->setStartTime(2.,4,0); - CPPUNIT_ASSERT(!f2->isEqual(f3,1e-12,1e-2)); - f3->setStartTime(2.,3,1); - CPPUNIT_ASSERT(!f2->isEqual(f3,1e-12,1e-2)); - f3->setStartTime(2.,3,0); - CPPUNIT_ASSERT(f2->isEqual(f3,1e-12,1e-2)); - f3->setEndTime(4.1,13,0); - CPPUNIT_ASSERT(!f2->isEqual(f3,1e-12,1e-2)); - f3->setEndTime(4.,13,0); - CPPUNIT_ASSERT(f2->isEqual(f3,1e-12,1e-2)); - f3->setEndTime(4.,14,0); - CPPUNIT_ASSERT(!f2->isEqual(f3,1e-12,1e-2)); - f3->setEndTime(4.,13,1); - CPPUNIT_ASSERT(!f2->isEqual(f3,1e-12,1e-2)); - f3->setEndTime(4.,13,0); - CPPUNIT_ASSERT(f2->isEqual(f3,1e-12,1e-2)); - f3->decrRef(); - MEDCouplingFieldDouble *f4=(*f2)+(*f2); - std::fill(res,res+3,0.); - f4->getValueOn(pos,3.21,res); - CPPUNIT_ASSERT_DOUBLES_EQUAL(8.05,res[0],1.e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(28.05,res[1],1.e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(48.05,res[2],1.e-12); - (*f4)+=*f2; - std::fill(res,res+3,0.); - f4->getValueOn(pos,3.21,res); - CPPUNIT_ASSERT_DOUBLES_EQUAL(12.075,res[0],1.e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(42.075,res[1],1.e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(72.075,res[2],1.e-12); - f4->decrRef(); - // - f2->decrRef(); - f1->decrRef(); - m->decrRef(); -} - -bool func4(const double *pt, double *res) -{ - res[0]=pt[0]+pt[1]+pt[2]; - return true; -} - -void MEDCouplingBasicsTest1::testMergeNodesOnField() -{ - double *tmp; - MEDCouplingUMesh *targetMesh=build3DTargetMeshMergeNode_1(); - MEDCouplingFieldDouble *f1=targetMesh->fillFromAnalytic(ON_NODES,1,func4); - f1->mergeNodes(1e-10); - f1->decrRef(); - targetMesh->decrRef(); - // - targetMesh=build3DTargetMeshMergeNode_1(); - f1=targetMesh->fillFromAnalytic(ON_NODES,1,func4); - tmp=f1->getArray()->getPointer(); - tmp[0]=1000.; - f1->mergeNodes(1e-10); - f1->decrRef(); - targetMesh->decrRef(); - // - targetMesh=build3DTargetMeshMergeNode_1(); - f1=targetMesh->fillFromAnalytic(ON_NODES,1,func4); - tmp=f1->getArray()->getPointer(); - tmp[1]=1000.; - CPPUNIT_ASSERT_THROW(f1->mergeNodes(1e-10),INTERP_KERNEL::Exception); - f1->decrRef(); - targetMesh->decrRef(); -} - -void MEDCouplingBasicsTest1::testCheckConsecutiveCellTypes() -{ - MEDCouplingUMesh *sourceMesh=build2DSourceMesh_1(); - MEDCouplingUMesh *targetMesh=build2DTargetMesh_1(); - CPPUNIT_ASSERT(sourceMesh->checkConsecutiveCellTypes()); - const INTERP_KERNEL::NormalizedCellType order1[]={INTERP_KERNEL::NORM_TRI3, INTERP_KERNEL::NORM_QUAD4}; - const INTERP_KERNEL::NormalizedCellType order2[]={INTERP_KERNEL::NORM_QUAD4, INTERP_KERNEL::NORM_TRI3}; - CPPUNIT_ASSERT(!targetMesh->checkConsecutiveCellTypes()); - CPPUNIT_ASSERT(!targetMesh->checkConsecutiveCellTypesAndOrder(order1,order1+2)); - CPPUNIT_ASSERT(!targetMesh->checkConsecutiveCellTypesAndOrder(order2,order2+2)); - DataArrayInt *da=targetMesh->getRenumArrForConsecutiveCellTypesSpec(order1,order1+2); - CPPUNIT_ASSERT_EQUAL(5,da->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(1,da->getNumberOfComponents()); - const int expected1[5]={2,0,1,3,4}; - CPPUNIT_ASSERT(std::equal(expected1,expected1+5,da->getConstPointer())); - da->decrRef(); - da=targetMesh->getRenumArrForConsecutiveCellTypesSpec(order2,order2+2); - CPPUNIT_ASSERT_EQUAL(5,da->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(1,da->getNumberOfComponents()); - const int expected2[5]={0,3,4,1,2}; - CPPUNIT_ASSERT(std::equal(expected2,expected2+5,da->getConstPointer())); - da->decrRef(); - const int renumber1[5]={4,0,1,2,3}; - targetMesh->renumberCells(renumber1,false); - CPPUNIT_ASSERT(targetMesh->checkConsecutiveCellTypes()); - CPPUNIT_ASSERT(targetMesh->checkConsecutiveCellTypesAndOrder(order1,order1+2)); - CPPUNIT_ASSERT(!targetMesh->checkConsecutiveCellTypesAndOrder(order2,order2+2)); - targetMesh->decrRef(); - sourceMesh->decrRef(); -} - -void MEDCouplingBasicsTest1::testRearrange2ConsecutiveCellTypes() -{ - MEDCouplingUMesh *m1_1=build2DSourceMesh_1(); - MEDCouplingUMesh *m2_1=build2DTargetMesh_1(); - DataArrayInt *arr1=m1_1->rearrange2ConsecutiveCellTypes(); - MEDCouplingUMesh *m1_2=build2DSourceMesh_1(); - CPPUNIT_ASSERT(m1_2->isEqual(m1_1,1e-12)); - const int expected1[2]={0,1}; - CPPUNIT_ASSERT_EQUAL(2,arr1->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(1,arr1->getNumberOfComponents()); - CPPUNIT_ASSERT(std::equal(expected1,expected1+2,arr1->getConstPointer())); - arr1->decrRef(); - const int expected2[5]={0,3,4,1,2}; - arr1=m2_1->rearrange2ConsecutiveCellTypes(); - CPPUNIT_ASSERT_EQUAL(5,arr1->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(1,arr1->getNumberOfComponents()); - CPPUNIT_ASSERT(std::equal(expected2,expected2+5,arr1->getConstPointer())); - MEDCouplingUMesh *m2_2=build2DTargetMesh_1(); - CPPUNIT_ASSERT_EQUAL(5,arr1->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(1,arr1->getNumberOfComponents()); - CPPUNIT_ASSERT(std::equal(expected2,expected2+5,arr1->getConstPointer())); - CPPUNIT_ASSERT(!m2_2->isEqual(m2_1,1e-12)); - m2_2->renumberCells(expected2,false); - CPPUNIT_ASSERT(m2_2->isEqual(m2_1,1e-12)); - arr1->decrRef(); - m1_1->decrRef(); - m1_2->decrRef(); - m2_1->decrRef(); - m2_2->decrRef(); -} - -void MEDCouplingBasicsTest1::testSplitByType() -{ - MEDCouplingUMesh *m1=build3DSurfTargetMesh_1(); - std::vector v=m1->splitByType(); - CPPUNIT_ASSERT_EQUAL(3,(int)v.size()); - std::vector v2(v.begin(),v.end()); - MEDCouplingUMesh *m2=MEDCouplingUMesh::MergeUMeshesOnSameCoords(v2); - m2->setName(m1->getName().c_str()); - CPPUNIT_ASSERT(m1->isEqual(m2,1.e-12)); - for(std::vector::const_iterator iter=v.begin();iter!=v.end();iter++) - (*iter)->decrRef(); - m2->decrRef(); - m1->decrRef(); -} - -void MEDCouplingBasicsTest1::testFuseUMeshesOnSameCoords() -{ - std::vector meshes; - MEDCouplingUMesh *m2=build2DTargetMesh_1(); - int cells1[3]={2,3,4}; - MEDCouplingPointSet *m3_1=m2->buildPartOfMySelf(cells1,cells1+3,true); - MEDCouplingUMesh *m3=dynamic_cast(m3_1); - CPPUNIT_ASSERT(m3); - meshes.push_back(m3); - int cells2[3]={1,2,4}; - MEDCouplingPointSet *m4_1=m2->buildPartOfMySelf(cells2,cells2+3,true); - MEDCouplingUMesh *m4=dynamic_cast(m4_1); - CPPUNIT_ASSERT(m4); - meshes.push_back(m4); - int cells3[2]={1,2}; - MEDCouplingPointSet *m5_1=m2->buildPartOfMySelf(cells3,cells3+2,true); - MEDCouplingUMesh *m5=dynamic_cast(m5_1); - CPPUNIT_ASSERT(m5); - meshes.push_back(m5); - m2->decrRef(); - // - std::vector corr; - MEDCouplingUMesh *m7=MEDCouplingUMesh::FuseUMeshesOnSameCoords(meshes,0,corr); - CPPUNIT_ASSERT_EQUAL(4,m7->getNumberOfCells()); - CPPUNIT_ASSERT_EQUAL(3,(int)corr.size()); - const int expectedVals1[3]={3,3,2}; - const int expectedVals2[3][3]={{0,1,2},{3,0,2},{3,0,111111}}; - for(int i=0;i<3;i++) - { - DataArrayInt *arr=corr[i]; - CPPUNIT_ASSERT_EQUAL(1,arr->getNumberOfComponents()); - int nbOfVals=expectedVals1[i]; - CPPUNIT_ASSERT_EQUAL(nbOfVals,arr->getNumberOfTuples()); - const int *vals=arr->getConstPointer(); - for(int j=0;j > fidsOfGroups; - std::vector corr2(corr.begin(),corr.end()); - DataArrayInt *arr2=DataArrayInt::MakePartition(corr2,m7->getNumberOfCells(),fidsOfGroups); - const int fidExp[4]={5,1,3,4}; - const int fidsGrp[3][3]={{1,3,5},{3,4,5},{4,5,23344}}; - CPPUNIT_ASSERT_EQUAL(3,(int)fidsOfGroups.size()); - CPPUNIT_ASSERT_EQUAL(1,arr2->getNumberOfComponents()); - CPPUNIT_ASSERT_EQUAL(4,arr2->getNumberOfTuples()); - CPPUNIT_ASSERT(std::equal(fidExp,fidExp+4,arr2->getConstPointer())); - for(int i=0;i<3;i++) - { - int nbOfVals=expectedVals1[i]; - CPPUNIT_ASSERT_EQUAL(nbOfVals,(int)fidsOfGroups[i].size()); - CPPUNIT_ASSERT(std::equal(fidsOfGroups[i].begin(),fidsOfGroups[i].end(),fidsGrp[i])); - } - for(std::vector::iterator iter=corr.begin();iter!=corr.end();iter++) - (*iter)->decrRef(); - arr2->decrRef(); - m7->decrRef(); - // - m3->decrRef(); - m4->decrRef(); - m5->decrRef(); -} - -void MEDCouplingBasicsTest1::testFuseUMeshesOnSameCoords2() -{ - MEDCouplingUMesh *m2; - MEDCouplingUMesh *m1=build3DExtrudedUMesh_1(m2); - m2->decrRef(); - const int part1[5]={2,3,6,4,10}; - MEDCouplingUMesh *m3=(MEDCouplingUMesh *)m1->buildPartOfMySelf(part1,part1+5,true); - const int part2[4]={5,6,4,7}; - MEDCouplingUMesh *m4=(MEDCouplingUMesh *)m1->buildPartOfMySelf(part2,part2+4,true); - std::vector meshes; - meshes.push_back(m1); - meshes.push_back(m3); - meshes.push_back(m3); - meshes.push_back(m4); - std::vector corr; - MEDCouplingUMesh *m5=MEDCouplingUMesh::FuseUMeshesOnSameCoords(meshes,0,corr); - CPPUNIT_ASSERT_EQUAL(18,m5->getNumberOfCells()); - std::vector::iterator it=corr.begin(); - const int exp1[4]={18,5,5,4}; - const int exp2[4][18]={ - {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17}, - {2,3,6,4,10,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1}, - {2,3,6,4,10,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1}, - {5,6,4,7,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1} - }; - int i=0; - for(;it!=corr.end();it++,i++) - { - int sz=(*it)->getNumberOfTuples(); - CPPUNIT_ASSERT_EQUAL(exp1[i],sz); - CPPUNIT_ASSERT(std::equal(exp2[i],exp2[i]+sz,(*it)->getConstPointer())); - } - for(it=corr.begin();it!=corr.end();it++) - (*it)->decrRef(); - m5->decrRef(); - m4->decrRef(); - m3->decrRef(); - m1->decrRef(); -} - -void MEDCouplingBasicsTest1::testBuildOrthogonalField() -{ - MEDCouplingUMesh *targetMesh=build3DSurfTargetMesh_1(); - MEDCouplingFieldDouble *field=targetMesh->buildOrthogonalField(); - double expected[3]={0.70710678118654746,0.,-0.70710678118654746}; - CPPUNIT_ASSERT_EQUAL(5,field->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(3,field->getNumberOfComponents()); - const double *vals=field->getArray()->getConstPointer(); - for(int i=0;i<15;i++) - CPPUNIT_ASSERT_DOUBLES_EQUAL(expected[i%3],vals[i],1e-12); - field->decrRef(); - targetMesh->decrRef(); - // testing - double targetCoords[12]={0.,0.,0.,0.5,0.,0.5,1.,0.,1.,0.,1.,0.}; - int targetConn[4]={0,1,2,3}; - targetMesh=MEDCouplingUMesh::New(); - targetMesh->setMeshDimension(2); - targetMesh->allocateCells(1); - targetMesh->insertNextCell(INTERP_KERNEL::NORM_QUAD4,4,targetConn); - targetMesh->finishInsertingCells(); - DataArrayDouble *myCoords=DataArrayDouble::New(); - myCoords->alloc(4,3); - std::copy(targetCoords,targetCoords+12,myCoords->getPointer()); - targetMesh->setCoords(myCoords); - myCoords->decrRef(); - field=targetMesh->buildOrthogonalField(); - CPPUNIT_ASSERT_EQUAL(1,field->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(3,field->getNumberOfComponents()); - vals=field->getArray()->getConstPointer(); - CPPUNIT_ASSERT_DOUBLES_EQUAL(-0.70710678118654746,vals[0],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.,vals[1],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.70710678118654746,vals[2],1e-12); - field->decrRef(); - targetMesh->decrRef(); -} - -void MEDCouplingBasicsTest1::testGetCellsContainingPoint() -{ - MEDCouplingUMesh *targetMesh=build2DTargetMesh_1(); - double pos[12]={0.,0.,0.4,0.4,0.,0.4,0.1,0.1,0.25,0.,0.65,0.}; - MEDCouplingAutoRefCountObjectPtr t1,t2; - //2D basic - targetMesh->getCellsContainingPoints(pos,6,1e-12,t1,t2); - CPPUNIT_ASSERT_EQUAL(6,(int)t1->getNbOfElems()); - CPPUNIT_ASSERT_EQUAL(7,(int)t2->getNbOfElems()); - const int expectedValues1[6]={0,4,3,0,1,2}; - const int expectedValues2[7]={0,1,2,3,4,5,6}; - CPPUNIT_ASSERT(std::equal(t1->begin(),t1->end(),expectedValues1)); - CPPUNIT_ASSERT(std::equal(t2->begin(),t2->end(),expectedValues2)); - //2D with no help of bounding box. - double center[2]={0.2,0.2}; - MEDCouplingPointSet::Rotate2DAlg(center,0.78539816339744830962,6,pos); - targetMesh->rotate(center,0,0.78539816339744830962); - targetMesh->getCellsContainingPoints(pos,6,1e-12,t1,t2); - CPPUNIT_ASSERT_EQUAL(6,(int)t1->getNbOfElems()); - CPPUNIT_ASSERT_EQUAL(7,(int)t2->getNbOfElems()); - CPPUNIT_ASSERT(std::equal(t1->begin(),t1->end(),expectedValues1)); - CPPUNIT_ASSERT(std::equal(t2->begin(),t2->end(),expectedValues2)); - //2D outside - const double pos1bis[2]={-0.3303300858899107,-0.11819805153394641}; - CPPUNIT_ASSERT_EQUAL(-1,targetMesh->getCellContainingPoint(pos1bis,1e-12)); - targetMesh->decrRef(); - //test limits 2D - targetMesh=build2DTargetMesh_1(); - const double pos2[2]={0.2,-0.05}; - std::vector t11; - t11.clear(); - targetMesh->getCellsContainingPoint(pos2,1e-12,t11); - CPPUNIT_ASSERT_EQUAL(2,(int)t11.size()); - const int expectedValues3[2]={0,1}; - CPPUNIT_ASSERT(std::equal(t11.begin(),t11.end(),expectedValues3)); - const double pos3[2]={0.2,0.2}; - t11.clear(); - targetMesh->getCellsContainingPoint(pos3,1e-12,t11); - CPPUNIT_ASSERT_EQUAL(5,(int)t11.size()); - const int expectedValues4[5]={0,1,2,3,4}; - CPPUNIT_ASSERT(std::equal(t11.begin(),t11.end(),expectedValues4)); - CPPUNIT_ASSERT_EQUAL(0,targetMesh->getCellContainingPoint(pos3,1e-12)); - targetMesh->decrRef(); - //3D - targetMesh=build3DTargetMesh_1(); - const double pos4[3]={25.,25.,25.}; - CPPUNIT_ASSERT_EQUAL(0,targetMesh->getCellContainingPoint(pos4,1e-12)); - const double pos5[3]={50.,50.,50.}; - t11.clear(); - targetMesh->getCellsContainingPoint(pos5,1e-12,t11); - CPPUNIT_ASSERT_EQUAL(8,(int)t11.size()); - const int expectedValues5[8]={0,1,2,3,4,5,6,7}; - CPPUNIT_ASSERT(std::equal(t11.begin(),t11.end(),expectedValues5)); - const double pos6[3]={0., 50., 0.}; - t11.clear(); - targetMesh->getCellsContainingPoint(pos6,1e-12,t11); - CPPUNIT_ASSERT_EQUAL(2,(int)t11.size()); - const int expectedValues6[2]={0,2}; - CPPUNIT_ASSERT(std::equal(t11.begin(),t11.end(),expectedValues6)); - //3D outside - const double pos7[3]={-1.0,-1.0,0.}; - CPPUNIT_ASSERT_EQUAL(-1,targetMesh->getCellContainingPoint(pos7,1e-12)); - //3D outside 2 - const double center2[3]={0.,0.,0.}; - const double vec2[3]={0.,-1.,0.}; - targetMesh->rotate(center2,vec2,0.78539816339744830962); - const double pos8[3]={-25,25.,12.}; - CPPUNIT_ASSERT_EQUAL(-1,targetMesh->getCellContainingPoint(pos8,1e-12)); - // - targetMesh->decrRef(); -} - -void MEDCouplingBasicsTest1::testGetValueOn1() -{ - MEDCouplingUMesh *targetMesh=build2DTargetMesh_1(); - MEDCouplingFieldDouble *fieldOnCells=MEDCouplingFieldDouble::New(ON_CELLS); - int nbOfCells=targetMesh->getNumberOfCells(); - fieldOnCells->setMesh(targetMesh); - DataArrayDouble *array=DataArrayDouble::New(); - array->alloc(nbOfCells,2); - fieldOnCells->setArray(array); - double *tmp=array->getPointer(); - for(int i=0;idecrRef(); - // - const double pos1[2]={0.25,0.}; - double res[2]; - fieldOnCells->getValueOn(pos1,res); - CPPUNIT_ASSERT_DOUBLES_EQUAL(8.,res[0],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(18.,res[1],1e-12); - // - fieldOnCells->decrRef(); - targetMesh->decrRef(); - // - targetMesh=build2DSourceMesh_1(); - MEDCouplingFieldDouble *fieldOnNodes=MEDCouplingFieldDouble::New(ON_NODES); - int nbOfNodes=targetMesh->getNumberOfNodes(); - fieldOnNodes->setMesh(targetMesh); - array=DataArrayDouble::New(); - array->alloc(nbOfNodes,2); - fieldOnNodes->setArray(array); - tmp=array->getPointer(); - for(int i=0;idecrRef(); - // - const double pos2[2]={-0.13333333333333333,-0.13333333333333333}; - fieldOnNodes->getValueOn(pos2,res); - CPPUNIT_ASSERT_DOUBLES_EQUAL(17.5,res[0],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(27.5,res[1],1e-12); - const double pos3[2]={0.033333333333333326,0.36666666666666664}; - fieldOnNodes->getValueOn(pos3,res); - CPPUNIT_ASSERT_DOUBLES_EQUAL(18.666666666666667,res[0],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(28.666666666666667,res[1],1e-12); - // - fieldOnNodes->decrRef(); - targetMesh->decrRef(); -} - -void MEDCouplingBasicsTest1::testCMesh0() -{ - MEDCouplingCMesh* mesh=MEDCouplingCMesh::New(); - MEDCouplingCMesh* meshEmpty=mesh->clone(true); - CPPUNIT_ASSERT(meshEmpty->isEqual(mesh,1e-12)); - - DataArrayDouble* coordsX=DataArrayDouble::New(); - double arrX[4] = { -1., 1., 2., 4. }; - coordsX->useArray(arrX,false, CPP_DEALLOC,4,1); - DataArrayDouble* coordsY=DataArrayDouble::New(); - double arrY[4] = { -2., 2., 4., 8. }; - coordsY->useArray(arrY,false, CPP_DEALLOC,4,1); - DataArrayDouble* coordsZ=DataArrayDouble::New(); - double arrZ[4] = { -3., 3., 6., 12. }; - coordsZ->useArray(arrZ,false, CPP_DEALLOC,4,1); - mesh->setCoords(coordsX,coordsY,coordsZ); - coordsX->decrRef(); - coordsY->decrRef(); - coordsZ->decrRef(); - // - MEDCouplingFieldDouble *fieldOnNodes=mesh->fillFromAnalytic(ON_NODES,1,"x+y/2.+z/3."); - CPPUNIT_ASSERT_EQUAL(1,fieldOnNodes->getNumberOfComponents()); - CPPUNIT_ASSERT_EQUAL(64,fieldOnNodes->getNumberOfTuples()); - const double expected1[64]={-3., -1., 0., 2., -1., 1., 2., 4., 0., 2., 3., 5., 2., 4., 5., 7., -1., 1., 2., - 4., 1., 3., 4., 6., 2., 4., 5., 7., 4., 6., 7., 9., 0., 2., 3., 5., 2., 4., 5., - 7., 3., 5., 6., 8., 5., 7., 8., 10., 2., 4., 5., - 7., 4., 6., 7., 9., 5., 7., 8., 10., 7., 9., 10., 12.}; - const double *val=fieldOnNodes->getArray()->getConstPointer(); - for(int i=0;i<64;i++) - CPPUNIT_ASSERT_DOUBLES_EQUAL(expected1[i],val[i],1e-12); - double res[1]; //size fieldOnNodes->getNumberOfComponents() - fieldOnNodes->getValueOnPos(1,3,2,&res[0]); - CPPUNIT_ASSERT_DOUBLES_EQUAL(7.,res[0],1e-12); - fieldOnNodes->decrRef(); - // - MEDCouplingFieldDouble *fieldOnCells=mesh->fillFromAnalytic(ON_CELLS,1,"x+y/2.+z/3."); - CPPUNIT_ASSERT_EQUAL(1,fieldOnCells->getNumberOfComponents()); - CPPUNIT_ASSERT_EQUAL(27,fieldOnCells->getNumberOfTuples()); - val=fieldOnCells->getArray()->getConstPointer(); - const double expected2[27]={0, 1.5, 3, 1.5, 3, 4.5, 3, 4.5, 6, 1.5, 3, 4.5, 3, 4.5, - 6, 4.5, 6, 7.5, 3, 4.5, 6, 4.5, 6, 7.5, 6, 7.5, 9}; - for(int i=0;i<27;i++) - CPPUNIT_ASSERT_DOUBLES_EQUAL(expected2[i],val[i],1e-12); - fieldOnCells->getValueOnPos(1,2,1,&res[0]); - CPPUNIT_ASSERT_DOUBLES_EQUAL(6.,res[0],1e-12); - fieldOnCells->decrRef(); - // - MEDCouplingMesh* meshDeepCopy=mesh->deepCpy(); - MEDCouplingCMesh* meshClone=mesh->clone(false); - - CPPUNIT_ASSERT_THROW(meshEmpty->copyTinyStringsFrom(0),INTERP_KERNEL::Exception); - meshEmpty->copyTinyStringsFrom(mesh); - //no data in meshEmpty, expected false - CPPUNIT_ASSERT(!meshEmpty->isEqual(mesh,1e-12)); - - CPPUNIT_ASSERT(meshDeepCopy->isEqual(mesh,1e-12)); - meshDeepCopy->copyTinyStringsFrom(mesh); - CPPUNIT_ASSERT(meshDeepCopy->isEqual(mesh,1e-12)); - CPPUNIT_ASSERT(meshClone->isEqual(mesh,1e-12)); - - CPPUNIT_ASSERT_EQUAL(CARTESIAN,mesh->getType()); - CPPUNIT_ASSERT_EQUAL(CARTESIAN,meshEmpty->getType()); - CPPUNIT_ASSERT_EQUAL(CARTESIAN,meshDeepCopy->getType()); - CPPUNIT_ASSERT_EQUAL(CARTESIAN,meshClone->getType()); - - mesh->decrRef(); - meshEmpty->decrRef(); - meshDeepCopy->decrRef(); - meshClone->decrRef(); -} - -void MEDCouplingBasicsTest1::testCMesh1() -{ - MEDCouplingCMesh *mesh1,*mesh2,*mesh3; - mesh1=MEDCouplingCMesh::New(); - DataArrayDouble* coordsX1=DataArrayDouble::New(); - double arrX1[4] = { -1., 1., 2., 4. }; - coordsX1->useArray(arrX1,false, CPP_DEALLOC,4,1); - DataArrayDouble* coordsY1=DataArrayDouble::New(); - double arrY1[4] = { -2., 2., 4., 8. }; - coordsY1->useArray(arrY1,false, CPP_DEALLOC,4,1); - DataArrayDouble* coordsZ1=DataArrayDouble::New(); - double arrZ1[4] = { -3., 3., 6., 12. }; - coordsZ1->useArray(arrZ1,false, CPP_DEALLOC,4,1); - mesh1->setCoords(coordsX1,coordsY1,coordsZ1); - - mesh2=MEDCouplingCMesh::New(); - DataArrayDouble* coordsX2=DataArrayDouble::New(); - double arrX2[4] = { -1., 1., 2., 4. }; - coordsX2->useArray(arrX2,false, CPP_DEALLOC,4,1); - DataArrayDouble* coordsY2=DataArrayDouble::New(); - double arrY2[4] = { -2., 2., 4., 8. }; - coordsY2->useArray(arrY2,false, CPP_DEALLOC,4,1); - DataArrayDouble* coordsZ2=DataArrayDouble::New(); - double arrZ2[4] = { -3., 3., 6., 12.+1e-6 }; //here is not equal - coordsZ2->useArray(arrZ2,false, CPP_DEALLOC,4,1); - mesh2->setCoords(coordsX2,coordsY2,coordsZ2); - - mesh3=MEDCouplingCMesh::New(); - DataArrayDouble* coordsX3=DataArrayDouble::New(); - double arrX3[1] = { -1.}; - coordsX3->useArray(arrX3,false, CPP_DEALLOC,1,1); - DataArrayDouble* coordsY3=DataArrayDouble::New(); - double arrY3[1] = { -2.}; - coordsY3->useArray(arrY3,false, CPP_DEALLOC,1,1); - DataArrayDouble* coordsZ3=DataArrayDouble::New(); - double arrZ3[1] = { -3.}; - coordsZ3->useArray(arrZ3,false, CPP_DEALLOC,1,1); - mesh3->setCoords(coordsX3,coordsY3,coordsZ3); - - CPPUNIT_ASSERT_EQUAL(3,mesh1->getSpaceDimension()); - CPPUNIT_ASSERT_EQUAL(3,mesh1->getMeshDimension()); - - CPPUNIT_ASSERT(!mesh1->isEqual(mesh2,1e-12)); - CPPUNIT_ASSERT(!mesh2->isEqual(mesh1,1e-12)); - CPPUNIT_ASSERT(!mesh2->isEqualWithoutConsideringStr(mesh1,1e-12)); - CPPUNIT_ASSERT(mesh1->isEqual(mesh2,1e-5)); - CPPUNIT_ASSERT(!mesh1->isEqual(mesh2,1e-7)); - - CPPUNIT_ASSERT_THROW(mesh3->checkCoherency1(1e-12),INTERP_KERNEL::Exception); - mesh1->checkCoherency2(1e-12); - CPPUNIT_ASSERT_EQUAL(INTERP_KERNEL::NORM_HEXA8,mesh1->getTypeOfCell(1)); - - CPPUNIT_ASSERT_EQUAL(INTERP_KERNEL::NORM_HEXA8,*((mesh1->getAllGeoTypes()).begin())); - CPPUNIT_ASSERT_EQUAL(27,mesh1->getNumberOfCellsWithType(INTERP_KERNEL::NORM_HEXA8)); - CPPUNIT_ASSERT_THROW(mesh1->getNumberOfCellsWithType(INTERP_KERNEL::NORM_QUAD4),INTERP_KERNEL::Exception); - - std::vector coo; - mesh1->getCoordinatesOfNode(0, coo); - CPPUNIT_ASSERT_EQUAL(3,(int) coo.size()); - CPPUNIT_ASSERT_DOUBLES_EQUAL(-1.,coo[0],1e-14); - CPPUNIT_ASSERT_DOUBLES_EQUAL(-2.,coo[1],1e-14); - CPPUNIT_ASSERT_DOUBLES_EQUAL(-3.,coo[2],1e-14); - coo.clear(); - mesh1->getCoordinatesOfNode(63, coo); - CPPUNIT_ASSERT_EQUAL(3,(int) coo.size()); - CPPUNIT_ASSERT_DOUBLES_EQUAL(4.,coo[0],1e-14); - CPPUNIT_ASSERT_DOUBLES_EQUAL(8.,coo[1],1e-14); - CPPUNIT_ASSERT_DOUBLES_EQUAL(12.,coo[2],1e-14); - - std::string repr; - repr=mesh1->simpleRepr(); - repr=mesh1->advancedRepr(); - CPPUNIT_ASSERT(!(repr.find("Cartesian")==std::string::npos)); - CPPUNIT_ASSERT(!(repr.find("Number of components : 1")==std::string::npos)); - CPPUNIT_ASSERT(!(repr.find("Number of tuples : 4")==std::string::npos)); - CPPUNIT_ASSERT(!(repr.find("Z Array :")==std::string::npos)); - coordsX1->decrRef(); - coordsY1->decrRef(); - coordsZ1->decrRef(); - coordsX2->decrRef(); - coordsY2->decrRef(); - coordsZ2->decrRef(); - coordsX3->decrRef(); - coordsY3->decrRef(); - coordsZ3->decrRef(); - mesh1->decrRef(); - mesh2->decrRef(); - mesh3->decrRef(); -} - -void MEDCouplingBasicsTest1::testCMesh2() -{ - MEDCouplingCMesh *mesh1; - mesh1=MEDCouplingCMesh::New(); - DataArrayDouble* coordsX1=DataArrayDouble::New(); - double arrX1[4] = { -1., 1., 2., 4. }; - coordsX1->useArray(arrX1,false, CPP_DEALLOC,4,1); - DataArrayDouble* coordsY1=DataArrayDouble::New(); - double arrY1[4] = { -2., 2., 4., 8. }; - coordsY1->useArray(arrY1,false, CPP_DEALLOC,4,1); - DataArrayDouble* coordsZ1=DataArrayDouble::New(); - double arrZ1[4] = { -3., 3., 6., 12. }; - coordsZ1->useArray(arrZ1,false, CPP_DEALLOC,4,1); - mesh1->setCoords(coordsX1,coordsY1,coordsZ1); - - std::vector dis=mesh1->getDistributionOfTypes(); - CPPUNIT_ASSERT_EQUAL(3,(int) dis.size()); - CPPUNIT_ASSERT_EQUAL((int) INTERP_KERNEL::NORM_HEXA8,dis[0]); - CPPUNIT_ASSERT_EQUAL(27,dis[1]); - CPPUNIT_ASSERT_EQUAL(-1,dis[2]); - - std::vector idsPerType; - CPPUNIT_ASSERT(!(mesh1->checkTypeConsistencyAndContig(dis, idsPerType))); - dis[0]=(int) INTERP_KERNEL::NORM_QUAD4; - CPPUNIT_ASSERT_THROW(mesh1->checkTypeConsistencyAndContig(dis, idsPerType),INTERP_KERNEL::Exception); - - dis[0]=(int) INTERP_KERNEL::NORM_HEXA8; - dis[2]=0; - DataArrayInt *ids=DataArrayInt::New(); - ids->alloc(10,1); - ids->fillWithValue(23); - idsPerType.push_back(ids); - DataArrayInt* check=mesh1->checkTypeConsistencyAndContig(dis, idsPerType); - CPPUNIT_ASSERT(check); - CPPUNIT_ASSERT(check->isEqual(*ids)); - - std::vector code; - std::vector idsInPflPerType; - std::vector pfls; - mesh1->splitProfilePerType(ids,code,idsInPflPerType,pfls); - CPPUNIT_ASSERT_EQUAL(3,(int)code.size()); - CPPUNIT_ASSERT_EQUAL((int) INTERP_KERNEL::NORM_HEXA8,code[0]); - CPPUNIT_ASSERT_EQUAL(10,code[1]); - CPPUNIT_ASSERT_EQUAL(0,code[2]); - CPPUNIT_ASSERT_EQUAL(1,(int)idsInPflPerType.size()); - CPPUNIT_ASSERT_EQUAL(1,(int)pfls.size()); - DataArrayInt *exp=DataArrayInt::New(); exp->alloc(10,1); exp->iota(0); - CPPUNIT_ASSERT(idsInPflPerType[0]->isEqual(*exp)); - exp->decrRef(); - CPPUNIT_ASSERT(pfls[0]->isEqual(*ids)); - idsInPflPerType[0]->decrRef(); - pfls[0]->decrRef(); - - ids->decrRef(); - check->decrRef(); - int cells1[4]={0,1,25,26}; - MEDCouplingUMesh *partMesh1= - dynamic_cast(mesh1->buildPart(cells1,cells1+4)); - CPPUNIT_ASSERT(partMesh1); - CPPUNIT_ASSERT_EQUAL(4,partMesh1->getNumberOfCellsWithType(INTERP_KERNEL::NORM_HEXA8)); - CPPUNIT_ASSERT_EQUAL(64,mesh1->getNumberOfNodes()); - CPPUNIT_ASSERT_EQUAL(64,partMesh1->getNumberOfNodes()); - - int cells2[2]={25,26}; - DataArrayInt* arr1; - MEDCouplingCMesh *partMesh2= - dynamic_cast(mesh1->buildPartAndReduceNodes(cells2,cells2+2,arr1)); - CPPUNIT_ASSERT(partMesh2); - CPPUNIT_ASSERT_EQUAL(2,partMesh2->getNumberOfCellsWithType(INTERP_KERNEL::NORM_HEXA8)); - CPPUNIT_ASSERT_EQUAL(12,partMesh2->getNumberOfNodes()); - - int cells3[2]={2,3}; - DataArrayInt* arr2; - MEDCouplingUMesh *partMesh3= - dynamic_cast(partMesh1->buildPartAndReduceNodes(cells3,cells3+2,arr2)); - CPPUNIT_ASSERT(partMesh3); - CPPUNIT_ASSERT_EQUAL(2,partMesh3->getNumberOfCellsWithType(INTERP_KERNEL::NORM_HEXA8)); - CPPUNIT_ASSERT_EQUAL(12,partMesh3->getNumberOfNodes()); - - CPPUNIT_ASSERT_THROW(mesh1->simplexize(0),INTERP_KERNEL::Exception); - CPPUNIT_ASSERT_THROW(mesh1->getMeasureFieldOnNode(true),INTERP_KERNEL::Exception); - - double bbox1[6]; - double bbox2[6]; - mesh1->getBoundingBox(bbox1); - partMesh1->getBoundingBox(bbox2); - for(int i=0;i<6;i++) - CPPUNIT_ASSERT_DOUBLES_EQUAL(bbox1[i],bbox2[i],1e-12); - partMesh3->getBoundingBox(bbox1); - partMesh2->getBoundingBox(bbox2); - for(int i=0;i<6;i++) - CPPUNIT_ASSERT_DOUBLES_EQUAL(bbox1[i],bbox2[i],1e-12); - - CPPUNIT_ASSERT_THROW(mesh1->buildOrthogonalField(),INTERP_KERNEL::Exception); - MEDCouplingCMesh *mesh2d=MEDCouplingCMesh::New(); - mesh2d->setCoords(coordsX1,coordsY1); - MEDCouplingFieldDouble *f1=mesh2d->buildOrthogonalField(); - - std::vector tinyInfoD; - std::vector tinyInfo; - std::vector littleStrings; - mesh2d->getTinySerializationInformation(tinyInfoD, tinyInfo, littleStrings); - CPPUNIT_ASSERT_EQUAL(5,(int)tinyInfo.size()); - CPPUNIT_ASSERT_EQUAL(4,(int)tinyInfo[0]); //x - CPPUNIT_ASSERT_EQUAL(4,(int)tinyInfo[1]); //y - CPPUNIT_ASSERT_EQUAL(-1,(int)tinyInfo[2]); //z - CPPUNIT_ASSERT_EQUAL(-1,(int)tinyInfo[3]); //it - CPPUNIT_ASSERT_EQUAL(-1,(int)tinyInfo[4]); //order - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.,tinyInfoD[0],1e-14); //time - DataArrayInt* d1=DataArrayInt::New(); - DataArrayDouble* d2=DataArrayDouble::New(); - mesh2d->resizeForUnserialization(tinyInfo, d1, d2, littleStrings); - CPPUNIT_ASSERT_EQUAL(0,d1->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(8,d2->getNumberOfTuples()); - - partMesh1->decrRef(); - partMesh2->decrRef(); - partMesh3->decrRef(); - mesh2d->decrRef(); - arr1->decrRef(); - arr2->decrRef(); - f1->decrRef(); - d1->decrRef(); - d2->decrRef(); - coordsX1->decrRef(); - coordsY1->decrRef(); - coordsZ1->decrRef(); - mesh1->decrRef(); -} - -void MEDCouplingBasicsTest1::testScale() -{ - MEDCouplingUMesh *mesh=build2DTargetMesh_1(); - const double pos[2]={0.2,0.2}; - mesh->scale(pos,0.5); - const double expected1[18]={-0.05,-0.05, 0.2,-0.05, 0.45,-0.05, -0.05,0.2, 0.2,0.2, 0.45,0.2, - -0.05,0.45, 0.2,0.45, 0.45,0.45}; - const double *val=mesh->getCoords()->getConstPointer(); - for(int i=0;i<18;i++) - CPPUNIT_ASSERT_DOUBLES_EQUAL(expected1[i],val[i],1e-12); - // - mesh->decrRef(); -} - -void MEDCouplingBasicsTest1::testTryToShareSameCoords() -{ - MEDCouplingUMesh *m1=build2DTargetMesh_1(); - MEDCouplingUMesh *m2=build2DTargetMesh_1(); - CPPUNIT_ASSERT(m1->getCoords()!=m2->getCoords()); - m1->tryToShareSameCoords(*m2,1e-12); - CPPUNIT_ASSERT(m1->getCoords()==m2->getCoords()); - m1->tryToShareSameCoords(*m2,1e-12); - CPPUNIT_ASSERT(m1->getCoords()==m2->getCoords()); - m2->tryToShareSameCoords(*m1,1e-12); - CPPUNIT_ASSERT(m1->getCoords()==m2->getCoords()); - m1->decrRef(); - m2->decrRef(); - // - m1=build2DTargetMesh_1(); - m2=build2DTargetMesh_2(); - CPPUNIT_ASSERT(m1->getCoords()!=m2->getCoords()); - m1->tryToShareSameCoords(*m2,1e-12); - CPPUNIT_ASSERT(m1->getCoords()==m2->getCoords()); - m1->tryToShareSameCoords(*m2,1e-12); - CPPUNIT_ASSERT(m1->getCoords()==m2->getCoords()); - m2->tryToShareSameCoords(*m1,1e-12); - CPPUNIT_ASSERT(m1->getCoords()==m2->getCoords()); - m1->decrRef(); - m2->decrRef(); - // - m1=build2DTargetMesh_1(); - m2=build2DSourceMesh_1(); - CPPUNIT_ASSERT(m1->getCoords()!=m2->getCoords()); - CPPUNIT_ASSERT_THROW(m1->tryToShareSameCoords(*m2,1e-12),INTERP_KERNEL::Exception); - m1->decrRef(); - m2->decrRef(); -} - -void MEDCouplingBasicsTest1::testFindNodeOnPlane() -{ - MEDCouplingUMesh *mesh=build3DTargetMesh_1(); - std::vector n; - double pt[3]={300.,300.,0.}; - double v[3]={0.,0.,2.}; - mesh->findNodesOnPlane(pt,v,1e-12,n); - CPPUNIT_ASSERT_EQUAL(9,(int)n.size()); - MEDCouplingUMesh *m3dSurf=(MEDCouplingUMesh *)mesh->buildFacePartOfMySelfNode(&n[0],&n[0]+n.size(),true); - MEDCouplingExtrudedMesh *me=MEDCouplingExtrudedMesh::New(mesh,m3dSurf,0); - const DataArrayInt *da=me->getMesh3DIds(); - CPPUNIT_ASSERT_EQUAL(8,me->getNumberOfCells()); - const int expected[8]={0,1,2,3,4,5,6,7}; - const int *val=da->getConstPointer(); - for(int i=0;i<8;i++) - CPPUNIT_ASSERT_EQUAL(expected[i],val[i]); - me->decrRef(); - m3dSurf->decrRef(); - mesh->decrRef(); -} - -void MEDCouplingBasicsTest1::testRenumberCells() -{ - MEDCouplingUMesh *m=build3DSurfTargetMesh_1(); - MEDCouplingUMesh *m2=build3DSurfTargetMesh_1(); - CPPUNIT_ASSERT(m->isEqual(m2,0)); - const int arr[5]={12,3,25,2,26}; - m->renumberCells(arr,true); - CPPUNIT_ASSERT(!m->isEqual(m2,0)); - CPPUNIT_ASSERT_EQUAL(INTERP_KERNEL::NORM_QUAD4,m->getTypeOfCell(0)); - CPPUNIT_ASSERT_EQUAL(INTERP_KERNEL::NORM_TRI3,m->getTypeOfCell(1)); - CPPUNIT_ASSERT_EQUAL(INTERP_KERNEL::NORM_QUAD4,m->getTypeOfCell(2)); - CPPUNIT_ASSERT_EQUAL(INTERP_KERNEL::NORM_TRI3,m->getTypeOfCell(3)); - CPPUNIT_ASSERT_EQUAL(INTERP_KERNEL::NORM_QUAD4,m->getTypeOfCell(4)); - const int arr2[5]={5,-1,-5,4,8}; - m->renumberCells(arr2,true); - CPPUNIT_ASSERT(m->isEqual(m2,0)); - m->decrRef(); - m2->decrRef(); -} - -void MEDCouplingBasicsTest1::testChangeSpaceDimension() -{ - MEDCouplingUMesh *m1=build3DSurfTargetMesh_1(); - MEDCouplingUMesh *m2=build2DTargetMesh_1(); - // - CPPUNIT_ASSERT_EQUAL(3,m1->getSpaceDimension()); - m1->changeSpaceDimension(2); - CPPUNIT_ASSERT_EQUAL(2,m1->getSpaceDimension()); - m1->setName(m2->getName().c_str()); - CPPUNIT_ASSERT(m1->isEqual(m2,1e-12)); - m1->changeSpaceDimension(3); - CPPUNIT_ASSERT_EQUAL(3,m1->getSpaceDimension()); - const double expected[27]={-0.3,-0.3,0., 0.2,-0.3,0., 0.7,-0.3,0., -0.3,0.2,0., 0.2,0.2,0., 0.7,0.2,0., -0.3,0.7,0., 0.2,0.7,0., 0.7,0.7,0.}; - const double *val=m1->getCoords()->getConstPointer(); - for(int i=0;i<27;i++) - CPPUNIT_ASSERT_DOUBLES_EQUAL(expected[i],val[i],1e-14); - // - m1->decrRef(); - m2->decrRef(); -} - -void MEDCouplingBasicsTest1::testSetConnectivity() -{ - MEDCouplingUMesh *m1 = build1DTargetMesh_1(); - - DataArrayInt * conn = DataArrayInt::New(); - DataArrayInt * connI = DataArrayInt::New(); - m1->setConnectivity(conn, connI, true); // was SEG-Faulting with empty arrays - conn->decrRef(); - connI->decrRef(); - m1->decrRef(); -} diff --git a/src/MEDCoupling/Test/MEDCouplingBasicsTest1.hxx b/src/MEDCoupling/Test/MEDCouplingBasicsTest1.hxx deleted file mode 100644 index 8372492b7..000000000 --- a/src/MEDCoupling/Test/MEDCouplingBasicsTest1.hxx +++ /dev/null @@ -1,156 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 -// 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 __MEDCOUPLINGBASICSTEST1_HXX__ -#define __MEDCOUPLINGBASICSTEST1_HXX__ - -#include "MEDCouplingBasicsTest.hxx" - -#include -#include - -namespace ParaMEDMEM -{ - class DataArrayDouble; - class MEDCouplingUMesh; - class MEDCouplingFieldDouble; - class MEDCouplingMultiFields; - - class MEDCouplingBasicsTest1 : public MEDCouplingBasicsTest - { - CPPUNIT_TEST_SUITE(MEDCouplingBasicsTest1); - CPPUNIT_TEST( testArray ); - CPPUNIT_TEST( testArray2 ); - CPPUNIT_TEST( testArray3 ); - CPPUNIT_TEST( testMesh ); - CPPUNIT_TEST( testMeshPointsCloud ); - CPPUNIT_TEST( testMeshM1D ); - CPPUNIT_TEST( testDeepCopy ); - CPPUNIT_TEST( testRevNodal ); - CPPUNIT_TEST( testConvertToPolyTypes ); - CPPUNIT_TEST( testDescConn2D ); - CPPUNIT_TEST( testDescConn3D ); - CPPUNIT_TEST( testFindBoundaryNodes ); - CPPUNIT_TEST( testBoundaryMesh ); - CPPUNIT_TEST( testBuildPartOfMySelf ); - CPPUNIT_TEST( testBuildPartOfMySelfNode ); - CPPUNIT_TEST( testZipCoords ); - CPPUNIT_TEST( testZipConnectivity ); - CPPUNIT_TEST( testEqualMesh ); - CPPUNIT_TEST( testEqualFieldDouble ); - CPPUNIT_TEST( testNatureChecking ); - CPPUNIT_TEST( testBuildSubMeshData ); - CPPUNIT_TEST( testExtrudedMesh1 ); - CPPUNIT_TEST( testExtrudedMesh2 ); - CPPUNIT_TEST( testExtrudedMesh3 ); - CPPUNIT_TEST( testExtrudedMesh4 ); - CPPUNIT_TEST( testFindCommonNodes ); - CPPUNIT_TEST( testCheckButterflyCells ); - CPPUNIT_TEST( testMergeMesh1 ); - CPPUNIT_TEST( testMergeMeshOnSameCoords1 ); - CPPUNIT_TEST( testMergeField1 ); - CPPUNIT_TEST( testFillFromAnalytic ); - CPPUNIT_TEST( testFillFromAnalytic2 ); - CPPUNIT_TEST( testApplyFunc ); - CPPUNIT_TEST( testApplyFunc2 ); - CPPUNIT_TEST( testOperationsOnFields ); - CPPUNIT_TEST( testOperationsOnFields2 ); - CPPUNIT_TEST( testOperationsOnFields3 ); - CPPUNIT_TEST( testOperationsOnFields4 ); - CPPUNIT_TEST( testMergeNodesOnField ); - CPPUNIT_TEST( testCheckConsecutiveCellTypes ); - CPPUNIT_TEST( testRearrange2ConsecutiveCellTypes ); - CPPUNIT_TEST( testSplitByType ); - CPPUNIT_TEST( testFuseUMeshesOnSameCoords ); - CPPUNIT_TEST( testFuseUMeshesOnSameCoords2 ); - CPPUNIT_TEST( testBuildOrthogonalField ); - CPPUNIT_TEST( testGetCellsContainingPoint ); - CPPUNIT_TEST( testGetValueOn1 ); - CPPUNIT_TEST( testCMesh0 ); - CPPUNIT_TEST( testCMesh1 ); - CPPUNIT_TEST( testCMesh2 ); - CPPUNIT_TEST( testScale ); - CPPUNIT_TEST( testTryToShareSameCoords ); - CPPUNIT_TEST( testFindNodeOnPlane ); - CPPUNIT_TEST( testRenumberCells ); - CPPUNIT_TEST( testChangeSpaceDimension ); - CPPUNIT_TEST( testSetConnectivity ); - CPPUNIT_TEST_SUITE_END(); - public: - void testArray(); - void testArray2(); - void testArray3(); - void testMesh(); - void testMeshPointsCloud(); - void testMeshM1D(); - void testDeepCopy(); - void testRevNodal(); - void testConvertToPolyTypes(); - void testDescConn2D(); - void testDescConn3D(); - void testFindBoundaryNodes(); - void testBoundaryMesh(); - void testBuildPartOfMySelf(); - void testBuildPartOfMySelfNode(); - void testZipCoords(); - void testZipConnectivity(); - void testEqualMesh(); - void testEqualFieldDouble(); - void testNatureChecking(); - void testBuildSubMeshData(); - void testExtrudedMesh1(); - void testExtrudedMesh2(); - void testExtrudedMesh3(); - void testExtrudedMesh4(); - void testFindCommonNodes(); - void testCheckButterflyCells(); - void testMergeMesh1(); - void testMergeMeshOnSameCoords1(); - void testMergeField1(); - void testFillFromAnalytic(); - void testFillFromAnalytic2(); - void testApplyFunc(); - void testApplyFunc2(); - void testOperationsOnFields(); - void testOperationsOnFields2(); - void testOperationsOnFields3(); - void testOperationsOnFields4(); - void testMergeNodesOnField(); - void testCheckConsecutiveCellTypes(); - void testRearrange2ConsecutiveCellTypes(); - void testSplitByType(); - void testFuseUMeshesOnSameCoords(); - void testFuseUMeshesOnSameCoords2(); - void testBuildOrthogonalField(); - void testGetCellsContainingPoint(); - void testGetValueOn1(); - void testCMesh0(); - void testCMesh1(); - void testCMesh2(); - void testScale(); - void testTryToShareSameCoords(); - void testFindNodeOnPlane(); - void testRenumberCells(); - void testChangeSpaceDimension(); - void testSetConnectivity(); - }; -} - -#endif diff --git a/src/MEDCoupling/Test/MEDCouplingBasicsTest2.cxx b/src/MEDCoupling/Test/MEDCouplingBasicsTest2.cxx deleted file mode 100644 index 4e52b0046..000000000 --- a/src/MEDCoupling/Test/MEDCouplingBasicsTest2.cxx +++ /dev/null @@ -1,2277 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 -// 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 "MEDCouplingBasicsTest2.hxx" -#include "MEDCouplingUMesh.hxx" -#include "MEDCouplingCMesh.hxx" -#include "MEDCouplingExtrudedMesh.hxx" -#include "MEDCouplingFieldDouble.hxx" -#include "MEDCouplingMemArray.hxx" -#include "MEDCouplingGaussLocalization.hxx" - -#include -#include -#include -#include - -using namespace ParaMEDMEM; - -void MEDCouplingBasicsTest2::testGaussPointField1() -{ - const double _a=0.446948490915965; - const double _b=0.091576213509771; - const double _p1=0.11169079483905; - const double _p2=0.0549758718227661; - const double refCoo1[6]={ 0.,0., 1.,0., 0.,1. }; - const double gsCoo1[12]={ 2*_b-1, 1-4*_b, 2*_b-1, 2.07*_b-1, 1-4*_b, - 2*_b-1, 1-4*_a, 2*_a-1, 2*_a-1, 1-4*_a, 2*_a-1, 2*_a-1 }; - const double wg1[6]={ 4*_p2, 4*_p2, 4*_p2, 4*_p1, 4*_p1, 4*_p1 }; - std::vector _refCoo1(refCoo1,refCoo1+6); - std::vector _gsCoo1(gsCoo1,gsCoo1+12); - std::vector _wg1(wg1,wg1+6); - // - MEDCouplingUMesh *m=build2DTargetMesh_1(); - MEDCouplingFieldDouble *f=MEDCouplingFieldDouble::New(ON_GAUSS_PT,NO_TIME); - CPPUNIT_ASSERT_THROW(f->getNumberOfTuples(), INTERP_KERNEL::Exception); // Sanity check! - f->setMesh(m); - CPPUNIT_ASSERT_EQUAL(5,f->getNumberOfMeshPlacesExpected()); - CPPUNIT_ASSERT_EQUAL(0,f->getNbOfGaussLocalization()); - f->setGaussLocalizationOnType(INTERP_KERNEL::NORM_TRI3,_refCoo1,_gsCoo1,_wg1); - f->setGaussLocalizationOnType(INTERP_KERNEL::NORM_TRI3,_refCoo1,_gsCoo1,_wg1); // not a bug only to check that it works well - CPPUNIT_ASSERT_THROW(f->setGaussLocalizationOnType(INTERP_KERNEL::NORM_QUAD4,_refCoo1,_gsCoo1,_wg1),INTERP_KERNEL::Exception); - CPPUNIT_ASSERT_EQUAL(1,f->getNbOfGaussLocalization()); - const double refCoo2[8]={ 0.,0., 1.,0., 1.,1., 0.,1. }; - std::vector _refCoo2(refCoo2,refCoo2+8); - _gsCoo1.resize(4); _wg1.resize(2); - f->setGaussLocalizationOnType(INTERP_KERNEL::NORM_QUAD4,_refCoo2,_gsCoo1,_wg1); - CPPUNIT_ASSERT_EQUAL(2,f->getNbOfGaussLocalization()); - DataArrayDouble *array=DataArrayDouble::New(); - array->alloc(18,2); - double *ptr=array->getPointer(); - for(int i=0;i<18*2;i++) - ptr[i]=(double)(i+1); - f->setArray(array); - f->setName("MyFirstFieldOnGaussPoint"); - array->decrRef(); - f->checkCoherency(); - CPPUNIT_ASSERT_DOUBLES_EQUAL(27.,f->getIJK(2,5,0),1e-14); - CPPUNIT_ASSERT_DOUBLES_EQUAL(16.,f->getIJK(1,5,1),1e-14); - // - f->clearGaussLocalizations(); - CPPUNIT_ASSERT_EQUAL(0,f->getNbOfGaussLocalization()); - CPPUNIT_ASSERT_THROW(f->checkCoherency(),INTERP_KERNEL::Exception); - int ids1[4]={0,1,3,4}; - CPPUNIT_ASSERT_THROW(f->setGaussLocalizationOnCells(ids1,ids1+4,_refCoo2,_gsCoo1,_wg1),INTERP_KERNEL::Exception); - CPPUNIT_ASSERT_EQUAL(0,f->getNbOfGaussLocalization()); - int ids2[2]={0,4}; - f->setGaussLocalizationOnCells(ids2,ids2+2,_refCoo2,_gsCoo1,_wg1); - CPPUNIT_ASSERT_EQUAL(1,f->getNbOfGaussLocalization()); - CPPUNIT_ASSERT_EQUAL(0,f->getGaussLocalizationIdOfOneCell(0)); - CPPUNIT_ASSERT_THROW(f->getGaussLocalizationIdOfOneCell(1),INTERP_KERNEL::Exception); - int ids3[2]={1,2}; - f->setGaussLocalizationOnCells(ids3,ids3+2,_refCoo1,_gsCoo1,_wg1); - CPPUNIT_ASSERT_EQUAL(2,f->getNbOfGaussLocalization()); - CPPUNIT_ASSERT_EQUAL(0,f->getGaussLocalizationIdOfOneCell(0)); - CPPUNIT_ASSERT_EQUAL(1,f->getGaussLocalizationIdOfOneCell(1)); - CPPUNIT_ASSERT_EQUAL(1,f->getGaussLocalizationIdOfOneCell(2)); - CPPUNIT_ASSERT_THROW(f->checkCoherency(),INTERP_KERNEL::Exception);//<- cell 3 has no localization - int ids4[1]={3}; - std::vector _gsCoo2(_gsCoo1); - std::vector _wg2(_wg1); - _gsCoo2[0]=0.8888777776666; _wg2[0]=0.1234567892377; - f->setGaussLocalizationOnCells(ids4,ids4+1,_refCoo2,_gsCoo2,_wg2); - CPPUNIT_ASSERT_EQUAL(3,f->getNbOfGaussLocalization()); - std::vector tmpIds; - f->getCellIdsHavingGaussLocalization(0,tmpIds); - CPPUNIT_ASSERT_EQUAL(2,(int)tmpIds.size()); - CPPUNIT_ASSERT(std::equal(ids2,ids2+2,tmpIds.begin())); - CPPUNIT_ASSERT_THROW(f->checkCoherency(),INTERP_KERNEL::Exception);//<- it's always not ok because undelying array not with the good size. - DataArrayDouble *array2=f->getArray()->substr(0,10); - f->setArray(array2); - array2->decrRef(); - f->checkCoherency();//<- here it is OK - MEDCouplingFieldDouble *f2=f->clone(true); - CPPUNIT_ASSERT(f->isEqual(f2,1e-14,1e-14)); - MEDCouplingGaussLocalization& gl1=f2->getGaussLocalization(0); - double tmp=gl1.getGaussCoord(1,1); - CPPUNIT_ASSERT_DOUBLES_EQUAL(2.07*_b-1,tmp,1e-14); - gl1.setGaussCoord(1,1,0.07); - CPPUNIT_ASSERT(!f->isEqual(f2,1e-14,1e-14)); - gl1.setGaussCoord(1,1,tmp); - CPPUNIT_ASSERT(f->isEqual(f2,1e-14,1e-14)); - f->decrRef(); - f2->checkCoherency(); - // - f2->decrRef(); - m->decrRef(); -} - -void MEDCouplingBasicsTest2::testGaussPointNEField1() -{ - MEDCouplingUMesh *m=build2DTargetMesh_1(); - MEDCouplingFieldDouble *f=MEDCouplingFieldDouble::New(ON_GAUSS_NE,NO_TIME); - f->setMesh(m); - CPPUNIT_ASSERT_EQUAL(5,f->getNumberOfMeshPlacesExpected()); - f->setName("MyFirstFieldOnNE"); - f->setDescription("MyDescriptionNE"); - DataArrayDouble *array=DataArrayDouble::New(); - array->alloc(18,2); - double *ptr=array->getPointer(); - for(int i=0;i<18*2;i++) - ptr[i]=(double)(i+7); - f->setArray(array); - array->decrRef(); - // - f->checkCoherency(); - MEDCouplingFieldDouble *f2=f->clone(true); - CPPUNIT_ASSERT(f->isEqual(f2,1e-14,1e-14)); - CPPUNIT_ASSERT_DOUBLES_EQUAL(21.,f->getIJK(2,0,0),1e-14); - CPPUNIT_ASSERT_DOUBLES_EQUAL(18.,f->getIJK(1,1,1),1e-14); - f2->decrRef(); - // - f->decrRef(); - m->decrRef(); -} - -void MEDCouplingBasicsTest2::testCellOrientation1() -{ - MEDCouplingUMesh *m=build2DTargetMesh_1(); - double vec[3]={0.,0.,-1.}; - std::vector res1; - CPPUNIT_ASSERT_THROW(m->are2DCellsNotCorrectlyOriented(vec,false,res1),INTERP_KERNEL::Exception); - m->changeSpaceDimension(3); - res1.clear(); - m->are2DCellsNotCorrectlyOriented(vec,false,res1); - CPPUNIT_ASSERT(res1.empty()); - vec[2]=1; - m->are2DCellsNotCorrectlyOriented(vec,false,res1); - CPPUNIT_ASSERT_EQUAL(5,(int)res1.size()); - res1.clear(); - // - vec[2]=-1.; - // connectivity inversion - int *conn=m->getNodalConnectivity()->getPointer(); - int tmp=conn[11]; - conn[11]=conn[12]; - conn[12]=tmp; - m->are2DCellsNotCorrectlyOriented(vec,false,res1); - CPPUNIT_ASSERT_EQUAL(1,(int)res1.size()); - CPPUNIT_ASSERT_EQUAL(2,res1[0]); - res1.clear(); - m->orientCorrectly2DCells(vec,false); - m->are2DCellsNotCorrectlyOriented(vec,false,res1); - CPPUNIT_ASSERT(res1.empty()); - MEDCouplingUMesh *m2=build2DTargetMesh_1(); - m2->changeSpaceDimension(3); - CPPUNIT_ASSERT(m->isEqual(m2,1e-12)); - m2->decrRef(); - // - m->decrRef(); -} - -void MEDCouplingBasicsTest2::testCellOrientation2() -{ - MEDCouplingUMesh *m1=0; - MEDCouplingUMesh *m2=build3DExtrudedUMesh_1(m1); - m1->decrRef(); - std::vector res1; - m2->arePolyhedronsNotCorrectlyOriented(res1); - CPPUNIT_ASSERT_EQUAL(6,(int)res1.size()); - m2->orientCorrectlyPolyhedrons(); - res1.clear(); - m2->arePolyhedronsNotCorrectlyOriented(res1); - CPPUNIT_ASSERT(res1.empty()); - m2->checkCoherency(); - CPPUNIT_ASSERT_EQUAL(18,m2->getNumberOfCells()); - int cellIds[3]={0,6,12}; - std::vector cellIds2(cellIds,cellIds+3); - m2->convertToPolyTypes(&cellIds2[0],&cellIds2[0]+cellIds2.size()); - m2->orientCorrectlyPolyhedrons(); - res1.clear(); - m2->arePolyhedronsNotCorrectlyOriented(res1); - CPPUNIT_ASSERT(res1.empty()); - MEDCouplingFieldDouble *f2=m2->getMeasureField(false); - //Test to check global reverse in MEDCouplingUMesh::tryToCorrectPolyhedronOrientation - MEDCouplingUMesh *m3=build2DTargetMesh_1(); - double vec[3]={0.,0.,1.}; - m3->changeSpaceDimension(3); - const int ids1[5]={0,1,2,3,4}; - std::vector ids2(ids1,ids1+5); - m3->convertToPolyTypes(&ids2[0],&ids2[0]+ids2.size()); - m3->orientCorrectly2DCells(vec,false); - MEDCouplingUMesh *m4=buildCU1DMesh_U(); - m4->changeSpaceDimension(3); - double center[3]={0.,0.,0.}; - double vector[3]={0.,1.,0.}; - m4->rotate(center,vector,-M_PI/2.); - MEDCouplingUMesh *m5=m3->buildExtrudedMesh(m4,0); - res1.clear(); - m5->arePolyhedronsNotCorrectlyOriented(res1); - CPPUNIT_ASSERT_EQUAL(15,(int)res1.size()); - m5->orientCorrectlyPolyhedrons(); - res1.clear(); - m5->arePolyhedronsNotCorrectlyOriented(res1); - CPPUNIT_ASSERT(res1.empty()); - MEDCouplingFieldDouble *f3=m5->getMeasureField(false); - CPPUNIT_ASSERT_EQUAL(15,f3->getArray()->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(1,f3->getNumberOfComponents()); - const double *f3Ptr=f3->getArray()->getConstPointer(); - const double expected1[15]={ - 0.075,0.0375,0.0375,0.075,0.075, - 0.1125,0.05625,0.05625,0.1125,0.1125, - 0.0625,0.03125,0.03125,0.0625,0.0625 - }; - for(int i=0;i<15;i++) - CPPUNIT_ASSERT_DOUBLES_EQUAL(std::abs(expected1[i]),f3Ptr[i],1e-12); - f3->decrRef(); - DataArrayDouble *f4=m5->getBarycenterAndOwner(); - CPPUNIT_ASSERT_EQUAL(15,f4->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(3,f4->getNumberOfComponents()); - const double *f4Ptr=f4->getConstPointer(); - const double expected2[45]={ - -0.05,-0.05,0.15, 0.3666666666666667,-0.13333333333333333,0.15, 0.53333333333333333,0.033333333333333333,0.15, -0.05,0.45,0.15, 0.45,0.45,0.15, - -0.05,-0.05,0.525, 0.3666666666666667,-0.13333333333333333,0.525, 0.53333333333333333,0.033333333333333333,0.525, -0.05,0.45,0.525, 0.45,0.45,0.525, - -0.05,-0.05,0.875, 0.3666666666666667,-0.13333333333333333,0.875, 0.53333333333333333,0.033333333333333333,0.875, -0.05,0.45,0.875, 0.45,0.45,0.875 - }; - for(int i=0;i<45;i++) - CPPUNIT_ASSERT_DOUBLES_EQUAL(expected2[i],f4Ptr[i],1e-12); - f4->decrRef(); - m5->decrRef(); - m3->decrRef(); - m4->decrRef(); - // - f2->decrRef(); - m2->decrRef(); -} - -void MEDCouplingBasicsTest2::testCellOrientation3() -{ - MEDCouplingUMesh *m = MEDCouplingUMesh::New("circle", 2); - - double coords[8]={ 0.,0., 0.,0., 0.,0., 0.,0.}; - coords[0] = cos(-M_PI/4.0); coords[1] = sin(-M_PI/4.0); - coords[2] = cos(3*M_PI/4.0); coords[3] = sin(3*M_PI/4.0); - coords[4] = cos(5*M_PI/4.0); coords[5] = sin(5*M_PI/4.0); - coords[6] = cos(M_PI/4.0); coords[7] = sin(M_PI/4.0); - - int conn[4]= { 0,1,2,3 }; - double vec[3]={0.,0.,-1.}; - m->allocateCells(1); - m->insertNextCell(INTERP_KERNEL::NORM_QPOLYG,4,conn); - m->finishInsertingCells(); - DataArrayDouble *myCoords=DataArrayDouble::New(); - myCoords->alloc(4,2); - std::copy(coords,coords+8,myCoords->getPointer()); - m->setCoords(myCoords); - myCoords->decrRef(); - m->changeSpaceDimension(3); - - std::vector res1; - m->are2DCellsNotCorrectlyOriented(vec,false,res1); - CPPUNIT_ASSERT(res1.empty()); - vec[2] = 1.0; - res1.clear(); - m->are2DCellsNotCorrectlyOriented(vec,false,res1); - CPPUNIT_ASSERT_EQUAL(1,(int)res1.size()); - m->decrRef(); -} - -/*! - * This test check polyhedron true barycenter computation. - */ -void MEDCouplingBasicsTest2::testPolyhedronBarycenter() -{ - int connN[]={0,3,2,1, -1, 4,5,6,7, -1, 0,4,7,3, -1, 3,7,6,2, -1, 2,6,5,1, -1, 1,5,4,0}; - double coords[]={0.,0.,0., 1.,0.,0., 1.,1.,0., 0.,1.,0., 0.,0.,1., 1.,0.,1., 1.,1.,1., 0.,1.,1., 0.5, 0.5, 0.5}; - MEDCouplingUMesh *meshN=MEDCouplingUMesh::New(); - meshN->setName("ForBary"); - meshN->setMeshDimension(3); - meshN->allocateCells(4); - meshN->insertNextCell(INTERP_KERNEL::NORM_POLYHED,29,connN); - meshN->finishInsertingCells(); - DataArrayDouble *myCoords=DataArrayDouble::New(); - myCoords->alloc(9,3); - std::copy(coords,coords+27,myCoords->getPointer()); - meshN->setCoords(myCoords); - myCoords->decrRef(); - meshN->checkCoherency(); - // - std::vector res1; - meshN->arePolyhedronsNotCorrectlyOriented(res1); - meshN->orientCorrectlyPolyhedrons(); - CPPUNIT_ASSERT(res1.empty()); - const double *ref,*daPtr; - DataArrayDouble *da=meshN->getBarycenterAndOwner(); - CPPUNIT_ASSERT_EQUAL(1,da->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(3,da->getNumberOfComponents()); - daPtr=da->getConstPointer(); - ref=meshN->getCoords()->getConstPointer()+24; - for(int i=0;i<3;i++) - CPPUNIT_ASSERT_DOUBLES_EQUAL(ref[i],daPtr[i],1e-12); - da->decrRef(); - // - const double center[]={0.,0.,0.}; - const double vec[]={0.,2.78,0.}; - da=meshN->getBarycenterAndOwner(); - daPtr=da->getConstPointer(); - ref=meshN->getCoords()->getConstPointer()+24; - for(int i=0;i<3;i++) - CPPUNIT_ASSERT_DOUBLES_EQUAL(ref[i],daPtr[i],1e-12); - da->decrRef(); - // - meshN->rotate(center,vec,M_PI/7.); - meshN->translate(vec); - da=meshN->getBarycenterAndOwner(); - daPtr=da->getConstPointer(); - ref=meshN->getCoords()->getConstPointer()+24; - for(int i=0;i<3;i++) - CPPUNIT_ASSERT_DOUBLES_EQUAL(ref[i],daPtr[i],1e-12); - da->decrRef(); - // - const double center2[]={1.12,3.45,6.78}; - const double vec2[]={4.5,9.3,2.8}; - meshN->rotate(center2,vec2,M_E); - meshN->translate(vec2); - da=meshN->getBarycenterAndOwner(); - daPtr=da->getConstPointer(); - ref=meshN->getCoords()->getConstPointer()+24; - for(int i=0;i<3;i++) - CPPUNIT_ASSERT_DOUBLES_EQUAL(ref[i],daPtr[i],1e-10); - da->decrRef(); - // - meshN->decrRef(); -} - -void MEDCouplingBasicsTest2::testNormL12Integ1D() -{ - MEDCouplingUMesh *m1=build1DTargetMesh_3(); - MEDCouplingFieldDouble *f1=MEDCouplingFieldDouble::New(ON_CELLS,NO_TIME); - f1->setMesh(m1); - DataArrayDouble *array=DataArrayDouble::New(); - array->alloc(m1->getNumberOfCells(),3); - const double arr[12]={-5.23,15.45,-25.56,6.67,-16.78,26.89,-7.91,17.23,-27.43,8.21,-18.63,28.72}; - std::copy(arr,arr+12,array->getPointer()); - f1->setArray(array); - array->decrRef(); - // - const double *ptr; - DataArrayDouble *f3=m1->getBarycenterAndOwner(); - CPPUNIT_ASSERT_EQUAL(4,f3->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(1,f3->getNumberOfComponents()); - double expected9[4]={0.75,5.105,0.8,5.155}; - ptr=f3->getConstPointer(); - for(int i=0;i<4;i++) - CPPUNIT_ASSERT_DOUBLES_EQUAL(expected9[i],ptr[i],1e-12); - f3->decrRef(); - // - MEDCouplingFieldDouble *f2=m1->getMeasureField(false); - CPPUNIT_ASSERT_EQUAL(4,f2->getArray()->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(1,f2->getNumberOfComponents()); - double expected1[4]={0.5,0.21,-0.6,-0.31}; - ptr=f2->getArray()->getConstPointer(); - for(int i=0;i<4;i++) - CPPUNIT_ASSERT_DOUBLES_EQUAL(expected1[i],ptr[i],1e-12); - f2->decrRef(); - double expected2[4]={0.5,0.21,0.6,0.31}; - f2=m1->getMeasureField(true); - ptr=f2->getArray()->getConstPointer(); - for(int i=0;i<4;i++) - CPPUNIT_ASSERT_DOUBLES_EQUAL(expected2[i],ptr[i],1e-12); - f2->decrRef(); - //integral - double res[3]; - f1->integral(false,res); - double expected3[3]={0.9866,-0.3615,0.4217}; - for(int i=0;i<3;i++) - CPPUNIT_ASSERT_DOUBLES_EQUAL(expected3[i],res[i],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(expected3[0],f1->integral(0,false),1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(expected3[1],f1->integral(1,false),1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(expected3[2],f1->integral(2,false),1e-12); - f1->integral(true,res); - double expected4[3]={-3.4152,8.7639,-14.6879}; - for(int i=0;i<3;i++) - CPPUNIT_ASSERT_DOUBLES_EQUAL(expected4[i],res[i],1e-12); - //normL1 - f1->normL1(res); - double expected5[3]={6.979506172839505, 16.89018518518518, 27.02969135802469}; - for(int i=0;i<3;i++) - CPPUNIT_ASSERT_DOUBLES_EQUAL(expected5[i],res[i],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(expected5[0],f1->normL1(0),1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(expected5[1],f1->normL1(1),1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(expected5[2],f1->normL1(2),1e-12); - //normL2 - f1->normL2(res); - double expected7[3]={7.090910979452395, 16.9275542960123, 27.053271464160858}; - for(int i=0;i<3;i++) - CPPUNIT_ASSERT_DOUBLES_EQUAL(expected7[i],res[i],1e-9); - CPPUNIT_ASSERT_DOUBLES_EQUAL(expected7[0],f1->normL2(0),1e-9); - CPPUNIT_ASSERT_DOUBLES_EQUAL(expected7[1],f1->normL2(1),1e-9); - CPPUNIT_ASSERT_DOUBLES_EQUAL(expected7[2],f1->normL2(2),1e-9); - //buildMeasureField - MEDCouplingFieldDouble *f4=f1->buildMeasureField(false); - CPPUNIT_ASSERT_DOUBLES_EQUAL(-0.2,f4->accumulate(0),1e-12); - f4->decrRef(); - f4=f1->buildMeasureField(true); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1.62,f4->accumulate(0),1e-12); - f4->decrRef(); - // - f1->decrRef(); - m1->decrRef(); - // Testing with 2D Curve - m1=build2DCurveTargetMesh_3(); - f2=m1->getMeasureField(false); - CPPUNIT_ASSERT_EQUAL(4,f2->getArray()->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(1,f2->getNumberOfComponents()); - ptr=f2->getArray()->getConstPointer(); - for(int i=0;i<4;i++) - CPPUNIT_ASSERT_DOUBLES_EQUAL(sqrt(2.)*expected2[i],ptr[i],1e-12); - f2->decrRef(); - f2=m1->getMeasureField(true); - CPPUNIT_ASSERT_EQUAL(4,f2->getArray()->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(1,f2->getNumberOfComponents()); - ptr=f2->getArray()->getConstPointer(); - for(int i=0;i<4;i++) - CPPUNIT_ASSERT_DOUBLES_EQUAL(expected2[i]*sqrt(2.),ptr[i],1e-12); - f2->decrRef(); - //bary - f3=m1->getBarycenterAndOwner(); - CPPUNIT_ASSERT_EQUAL(4,f3->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(2,f3->getNumberOfComponents()); - double expected10[8]={0.75,0.75,5.105,5.105,0.8,0.8,5.155,5.155}; - ptr=f3->getConstPointer(); - for(int i=0;i<8;i++) - CPPUNIT_ASSERT_DOUBLES_EQUAL(expected10[i],ptr[i],1e-12); - f3->decrRef(); - // - f1=MEDCouplingFieldDouble::New(ON_CELLS,NO_TIME); - f1->setMesh(m1); - array=DataArrayDouble::New(); - array->alloc(m1->getNumberOfCells(),3); - std::copy(arr,arr+12,array->getPointer()); - f1->setArray(array); - array->decrRef(); - f1->integral(false,res); - for(int i=0;i<3;i++) - CPPUNIT_ASSERT_DOUBLES_EQUAL(sqrt(2.)*expected4[i],res[i],1e-12); - f1->integral(true,res); - for(int i=0;i<3;i++) - CPPUNIT_ASSERT_DOUBLES_EQUAL(sqrt(2.)*expected4[i],res[i],1e-12); - f1->normL1(res); - for(int i=0;i<3;i++) - CPPUNIT_ASSERT_DOUBLES_EQUAL(expected5[i],res[i],1e-12); - f1->normL2(res); - for(int i=0;i<3;i++) - CPPUNIT_ASSERT_DOUBLES_EQUAL(expected7[i],res[i],1e-12); - // - f1->decrRef(); - m1->decrRef(); -} - -void MEDCouplingBasicsTest2::testAreaBary2D() -{ - MEDCouplingUMesh *m1=build2DTargetMesh_3(); - MEDCouplingFieldDouble *f1=m1->getMeasureField(false); - CPPUNIT_ASSERT_EQUAL(10,f1->getArray()->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(1,f1->getNumberOfComponents()); - double expected1[10]={-0.5,-1,-1.5,-0.5,-1, 0.5,1,1.5,0.5,1}; - const double *ptr=f1->getArray()->getConstPointer(); - for(int i=0;i<10;i++) - CPPUNIT_ASSERT_DOUBLES_EQUAL(expected1[i],ptr[i],1e-12); - f1->decrRef(); - f1=m1->getMeasureField(true); - ptr=f1->getArray()->getConstPointer(); - for(int i=0;i<10;i++) - CPPUNIT_ASSERT_DOUBLES_EQUAL(std::abs(expected1[i]),ptr[i],1e-12); - f1->decrRef(); - DataArrayDouble *f2=m1->getBarycenterAndOwner(); - CPPUNIT_ASSERT_EQUAL(10,f2->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(2,f2->getNumberOfComponents()); - double expected2[20]={ - 0.5,0.3333333333333333,0.5,0.5,0.5,0.77777777777777777,0.5,0.3333333333333333,0.5,0.5, - 0.5,0.3333333333333333,0.5,0.5,0.5,0.77777777777777777,0.5,0.3333333333333333,0.5,0.5, - }; - ptr=f2->getConstPointer(); - for(int i=0;i<20;i++) - CPPUNIT_ASSERT_DOUBLES_EQUAL(expected2[i],ptr[i],1e-12); - f2->decrRef(); - m1->changeSpaceDimension(3); - f1=m1->getMeasureField(false); - CPPUNIT_ASSERT_EQUAL(10,f1->getArray()->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(1,f1->getNumberOfComponents()); - ptr=f1->getArray()->getConstPointer(); - for(int i=0;i<10;i++) - CPPUNIT_ASSERT_DOUBLES_EQUAL(std::abs(expected1[i]),ptr[i],1e-12); - f1->decrRef(); - f2=m1->getBarycenterAndOwner(); - CPPUNIT_ASSERT_EQUAL(10,f2->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(3,f2->getNumberOfComponents()); - ptr=f2->getConstPointer(); - double expected3[30]={ - 0.5,0.3333333333333333,0.,0.5,0.5,0.,0.5,0.77777777777777777,0.,0.5,0.3333333333333333,0.,0.5,0.5,0., - 0.5,0.3333333333333333,0.,0.5,0.5,0.,0.5,0.77777777777777777,0.,0.5,0.3333333333333333,0.,0.5,0.5,0. - }; - for(int i=0;i<30;i++) - CPPUNIT_ASSERT_DOUBLES_EQUAL(expected3[i],ptr[i],1e-12); - f2->decrRef(); - m1->decrRef(); -} - -/*! - * This test check polyhedron true barycenter computation 2. - */ -void MEDCouplingBasicsTest2::testAreaBary3D() -{ - double coords [] = { 0.241310763507 , 0.0504777305619 , 0.0682283524903 , 0.252501053866 , -0.0625176732937 , 0.137272639894 , - 0.152262663601 , 0.241816569527 , 0.133812556197 , 0.18047750211 , -0.0789949051358 , 0.339098173401 , - 0.151741971857 , 0.238885278571 , 0.137715037333 , 0.242532155481 , -0.0928169086456 , 0.0678043417367 , - 0.240941965335 , -0.015461491464 , 0.0617186345825 , 0.24127650112 , 0.0499427876717 , 0.0679634099148 , - -0.145828917428 , 0.206291632565 , 0.0310071927543 , 0.0125651775307 , 0.266262085828 , 0.105228430543 , - -0.0994066533286 , 0.233224271238 , 0.0572213839567 , -0.0951345338317 , 0.234819509426 , 0.0592126284538 , - 0.136580574205 , -0.205486212579 , 0.0572866072014 , 0.0637270784978 , -0.168886355238 , 0.446614057077 , - 0.041337157151 , -0.213402568198 , 0.372407095999 , 0.0411601970268 , -0.202387875756 , 0.411334979491 , - -0.108355701857 , 0.193636239335 , 0.204886756738 , 0.00639779029829 , 0.155296981517 , 0.252585892979 , - 0.0262473111702 , -0.112919732543 , 0.424286639249 ,-0.224103052733 , -0.139430015438 , -0.0122352295701 , - -0.0312760589481 , -0.274272003594 , 0.0323959636568 , -0.166663422532 , -0.217754445175 , 0.00392109070364 , - -0.30586619777 , -0.0475168041091 , -0.0144585228182 , -0.280881480586 , 0.135571293538 , 0.00623923647986 , - -0.25548538234 , 0.156819217766 , 0.0645277879769 , -0.131567009284 , 0.184133752309 , 0.206021802753 , - -0.196204010965 , 0.151602971681 , 0.212974777736 , -0.183713879463 , 0.0802946639531 , 0.260115662599 , - -0.244241178767 , -0.0738873389604 , 0.144590565817 , -0.155804057829 , -0.164892720025 , 0.210613950558 , - -0.170950800428 , -0.215099334026 , 0.00610122860092 , -0.30552634869 , -0.0490020791904 , -0.0132786533145 , - 0.271831011884 , 0.15105657296 , 0.0230534827908 , 0.281919192283 , 0.0898544306288 , -0.0625201489143 , - 0.260240727276 , -0.0120688706637 , -0.0532316588626 , 0.244947737722 , 0.0197984684293 , 0.0309341209233 , - 0.23439631578 , 0.229825279875 , 0.0508520585381 , 0.160921316875 , 0.265078502128 , 0.121716560626 , - -0.315088694175 , 0.0747700471918 , -0.245836615071 , -0.327728781776 , 0.0857114674649 , -0.239431905957 , - -0.308385460634 , 0.145142997084 , -0.149886828433 , 0.0488236045164 , 0.309462801914 , 0.0849169148265 , - -0.0244964803395 , 0.33145611751 , -0.0476415818061 , 0.0060567994229 , 0.32418412014 , 0.0367779543812 , - -0.0950221448063 , 0.236675326003 , 0.0572594453983 , 0.248723023186 , 0.0886648784791 , -0.176629430538 , - 0.116796984 , 0.256596599567 , -0.292863523603 , 0.118024552914 , 0.229154257843 , -0.34233232501 , - 0.217507892549 , -0.0417822335742 , -0.176771782888 , -0.224429321304 , 0.0125595300114 , -0.362064725588 , - 0.0937301100955 , -0.0500824832657 , -0.299713548444 , -0.244162220397 , 0.0383853931293 , -0.389856984411 , - -0.0281989366102 , 0.097392811563 , -0.458244577284 , -0.385010847162 , 0.10122766194 , -0.140052859922 , - -0.377936358012 , 0.110875172128 , -0.176207095463 , 0.244483045556 , -0.0991073977045 , 0.0575134372934 , - 0.262605120167 , -0.100243191645 , -0.0495620806935 , 0.240306880972 , -0.136153701579 , -0.114745281696 , - 0.215763176129 , -0.0836766059189 , -0.183249640616 , 0.237870396603 , -0.132449578286 , -0.121598854639 , - -0.0637683083097 , -0.27921020214 , -0.149112321992 , -0.0856211014977 , -0.2973233473 , -0.0446878139589 , - 0.104675342288 , -0.0625908305324 , -0.290346256534 , 0.0248264249186 , -0.247797708548 , -0.165830884019 , - 0.0719302438309 , -0.178468260473 , -0.211432157345 , 0.142871843159 , -0.208769948542 , 0.0454101128246 , - 0.167803379307 , -0.207851396623 , -0.088802726124 , 0.12868717152 , -0.230920439715 , 0.00760508389036 , - -0.0372812069535 , -0.286740286332 , 0.00963701291166 }; - - int connN [] = { /*polyhedron 0*/ - 0 , 1 , 3 , 4 , 2 , -1 , 1 , 5 , 6 , 7 , 0 , -1 , 0 , 7 , 8 , 10 , 11 , 9 , 2 , -1 , 1 , 5 , 12 , 14 , 15 , 13 , 3 , -1 , 16 , 9 , 2 , 4 , 17 , -1 - , 4 , 3 , 13 , 18 , 17 , -1 , 5 , 6 , 19 , 21 , 20 , 12 , -1 , 6 , 7 , 8 , 23 , 22 , 19 , -1 , 23 , 24 , 10 , 8 , -1 , 25 , 11 , 9 , 16 , -1 - , 24 , 26 , 25 , 11 , 10 , -1 , 12 , 14 , 20 , -1 , 27 , 28 , 29 , 15 , 13 , 18 , -1 , 14 , 15 , 29 , 30 , 21 , 20 , -1 , 26 , 27 , 18 , 17 , 16 , 25 , -1 - , 22 , 19 , 21 , 30 , 31 , -1 , 22 , 31 , 28 , 27 , 26 , 24 , 23 , -1 , 31 , 30 , 29 , 28, - /* polyhedron 1*/ - 0 , 7 , 8 , 10 , 11 , 9 , 2 , -1 , 32 , 0 , 7 , 35 , 34 , 33 , -1 , 32 , 0 , 2 , 37 , 36 , -1 , 35 , 7 , 8 , 40 , 39 , 38 , -1 - , 2 , 37 , 41 , 9 , -1 , 40 , 8 , 10 , 44 , 43 , 42 , -1 , 41 , 9 , 11 , 44 , 43 , -1 , 44 , 11 , 10 , -1 , 32 , 33 , 45 , 47 , 46 , 36 , -1 - , 33 , 34 , 48 , 45 , -1 , 35 , 34 , 48 , 50 , 49 , 38 , -1 , 41 , 43 , 42 , 46 , 36 , 37 , -1 , 38 , 39 , 51 , 49 , -1 - , 39 , 40 , 42 , 46 , 47 , 52 , 51 , -1 , 45 , 47 , 52 , 50 , 48 , -1 , 52 , 51 , 49 , 50, - /* polyhedron 2*/ - 6 , 7 , 8 , 23 , 22 , 19 , -1 , 6 , 35 , 7 , -1 , 6 , 35 , 38 , 19 , -1 , 35 , 7 , 8 , 40 , 39 , 38 , -1 , 53 , 22 , 19 , 38 , 39 , 54 , -1 - , 23 , 53 , 54 , 40 , 8 , -1 , 53 , 22 , 23 , -1 , 39 , 54 , 40, - /*polyhedron 3*/ - 35 , 34 , 48 , 50 , 49 , 38 , -1 , 6 , 35 , 34 , 56 , 55 , 5 , -1 , 6 , 35 , 38 , 19 , -1 , 34 , 56 , 57 , 59 , 58 , 48 , -1 - , 60 , 61 , 21 , 19 , 38 , 49 , -1 , 62 , 50 , 48 , 58 , -1 , 60 , 63 , 64 , 62 , 50 , 49 , -1 , 5 , 6 , 19 , 21 , 20 , 12 , -1 - , 55 , 5 , 12 , 65 , -1 , 66 , 67 , 65 , 55 , 56 , 57 , -1 , 63 , 66 , 57 , 59 , 64 , -1 , 64 , 62 , 58 , 59 , -1 - , 60 , 63 , 66 , 67 , 68 , 61 , -1 , 61 , 68 , 20 , 21 , -1 , 67 , 68 , 20 , 12 , 65}; - - double barys[]={ -0.0165220465527 , -0.0190922868195 , 0.158882733414 , - 0.0287618656076 , 0.135874379934 , -0.14601588119 , - -0.147128055553 , 0.0465995097041 , -0.049391174453 , - -0.00142506732317 , -0.0996953090351 , -0.115159183132 }; - MEDCouplingUMesh *meshN=MEDCouplingUMesh::New(); - meshN->setName("ForBary"); - meshN->setMeshDimension(3); - meshN->allocateCells(4); - meshN->insertNextCell(INTERP_KERNEL::NORM_POLYHED,113,connN); - meshN->insertNextCell(INTERP_KERNEL::NORM_POLYHED,99,connN+113); - meshN->insertNextCell(INTERP_KERNEL::NORM_POLYHED,43,connN+212); - meshN->insertNextCell(INTERP_KERNEL::NORM_POLYHED,92,connN+255); - meshN->finishInsertingCells(); - DataArrayDouble *myCoords=DataArrayDouble::New(); - myCoords->alloc(69,3); - std::copy(coords,coords+207,myCoords->getPointer()); - meshN->setCoords(myCoords); - myCoords->decrRef(); - meshN->checkCoherency(); - std::vector res1; - meshN->arePolyhedronsNotCorrectlyOriented(res1); - meshN->orientCorrectlyPolyhedrons(); - res1.clear(); - meshN->arePolyhedronsNotCorrectlyOriented(res1); - CPPUNIT_ASSERT(res1.empty()); - // - DataArrayDouble *da=meshN->getBarycenterAndOwner(); - CPPUNIT_ASSERT_EQUAL(4,da->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(3,da->getNumberOfComponents()); - const double *daPtr=da->getConstPointer(); - for(int i=0;i<12;i++) - CPPUNIT_ASSERT_DOUBLES_EQUAL(barys[i],daPtr[i],1e-12); - da->decrRef(); - // - meshN->decrRef(); -} - -void MEDCouplingBasicsTest2::testRenumberCellsForFields() -{ - MEDCouplingUMesh *m=build2DTargetMesh_1(); - MEDCouplingFieldDouble *f=MEDCouplingFieldDouble::New(ON_CELLS,NO_TIME); - f->setMesh(m); - DataArrayDouble *arr=DataArrayDouble::New(); - int nbOfCells=m->getNumberOfCells(); - arr->alloc(nbOfCells,3); - f->setArray(arr); - arr->decrRef(); - const double values1[15]={7.,107.,10007.,8.,108.,10008.,9.,109.,10009.,10.,110.,10010.,11.,111.,10011.}; - std::copy(values1,values1+15,arr->getPointer()); - const int renumber1[5]={3,1,0,4,2}; - double res[3]; - const double loc[]={-0.05,-0.05, 0.55,-0.25, 0.55,0.15, -0.05,0.45, 0.45,0.45}; - for(int j=0;j<5;j++) - { - f->getValueOn(loc+2*j,res); - for(int i=0;i<3;i++) - CPPUNIT_ASSERT_DOUBLES_EQUAL(values1[i+3*j],res[i],1e-12); - } - f->renumberCells(renumber1,false); - const double *ptr=f->getArray()->getConstPointer(); - const double expected1[15]={9.,109.,10009.,8.,108.,10008.,11.,111.,10011.,7.,107.,10007.,10.,110.,10010.}; - for(int i=0;i<15;i++) - CPPUNIT_ASSERT_DOUBLES_EQUAL(expected1[i],ptr[i],1e-12); - //check that fields remains the same geometrically - for(int j=0;j<5;j++) - { - f->getValueOn(loc+2*j,res); - for(int i=0;i<3;i++) - CPPUNIT_ASSERT_DOUBLES_EQUAL(values1[i+3*j],res[i],1e-12); - } - f->decrRef(); - //On gauss - f=MEDCouplingFieldDouble::New(ON_GAUSS_PT,NO_TIME); - f->setMesh(m); - const double _a=0.446948490915965; - const double _b=0.091576213509771; - const double _p1=0.11169079483905; - const double _p2=0.0549758718227661; - const double refCoo1[6]={ 0.,0., 1.,0., 0.,1. }; - const double gsCoo1[12]={ 2*_b-1, 1-4*_b, 2*_b-1, 2.07*_b-1, 1-4*_b, - 2*_b-1, 1-4*_a, 2*_a-1, 2*_a-1, 1-4*_a, 2*_a-1, 2*_a-1 }; - const double wg1[6]={ 4*_p2, 4*_p2, 4*_p2, 4*_p1, 4*_p1, 4*_p1 }; - std::vector _refCoo1(refCoo1,refCoo1+6); - std::vector _gsCoo1(gsCoo1,gsCoo1+12); - std::vector _wg1(wg1,wg1+6); - f->setGaussLocalizationOnType(INTERP_KERNEL::NORM_TRI3,_refCoo1,_gsCoo1,_wg1); - const double refCoo2[8]={ 0.,0., 1.,0., 1.,1., 0.,1. }; - std::vector _refCoo2(refCoo2,refCoo2+8); - _gsCoo1.resize(4); _wg1.resize(2); - f->setGaussLocalizationOnType(INTERP_KERNEL::NORM_QUAD4,_refCoo2,_gsCoo1,_wg1); - arr=DataArrayDouble::New(); - arr->alloc(18,2); - const double values2[36]={1.,1001.,2.,1002., 11.,1011.,12.,1012.,13.,1013.,14.,1014.,15.,1015.,16.,1016., 21.,1021.,22.,1022.,23.,1023.,24.,1024.,25.,1025.,26.,1026., 31.,1031.,32.,1032., 41.,1041.,42.,1042.}; - std::copy(values2,values2+36,arr->getPointer()); - f->setArray(arr); - arr->decrRef(); - f->checkCoherency(); - MEDCouplingFieldDouble *fCpy=f->clone(true); - CPPUNIT_ASSERT(f->isEqual(fCpy,1e-12,1e-12)); - f->renumberCells(renumber1,false); - CPPUNIT_ASSERT(!f->isEqual(fCpy,1e-12,1e-12)); - double expected2[36]={21.,1021.,22.,1022.,23.,1023.,24.,1024.,25.,1025.,26.,1026., 11.,1011.,12.,1012.,13.,1013.,14.,1014.,15.,1015.,16.,1016., 41.,1041.,42.,1042., 1.,1001.,2.,1002., 31.,1031.,32.,1032.}; - ptr=f->getArray()->getConstPointer(); - for(int i=0;i<36;i++) - CPPUNIT_ASSERT_DOUBLES_EQUAL(expected2[i],ptr[i],1e-12); - const int renumber2[5]={2,1,4,0,3};//reverse renumber1 - f->renumberCells(renumber2,false); - CPPUNIT_ASSERT(f->isEqual(fCpy,1e-12,1e-12)); - fCpy->decrRef(); - f->decrRef(); - //GaussNE - f=MEDCouplingFieldDouble::New(ON_GAUSS_NE,NO_TIME); - f->setMesh(m); - arr=DataArrayDouble::New(); - arr->alloc(18,2); - const double values3[36]={1.,1001.,2.,1002.,3.,1003.,4.,1004., 11.,1011.,12.,1012.,13.,1013., 21.,1021.,22.,1022.,23.,1023., 31.,1031.,32.,1032.,33.,1033.,34.,1034., 41.,1041.,42.,1042.,43.,1043.,44.,1044.}; - std::copy(values3,values3+36,arr->getPointer()); - f->setArray(arr); - arr->decrRef(); - f->checkCoherency(); - fCpy=f->clone(true); - CPPUNIT_ASSERT(f->isEqual(fCpy,1e-12,1e-12)); - f->renumberCells(renumber1,false); - CPPUNIT_ASSERT(!f->isEqual(fCpy,1e-12,1e-12)); - double expected3[36]={21.,1021.,22.,1022.,23.,1023.,11.,1011.,12.,1012.,13.,1013.,41.,1041.,42.,1042.,43.,1043.,44.,1044.,1.,1001.,2.,1002.,3.,1003.,4.,1004.,31.,1031.,32.,1032.,33.,1033.,34.,1034.}; - ptr=f->getArray()->getConstPointer(); - for(int i=0;i<36;i++) - CPPUNIT_ASSERT_DOUBLES_EQUAL(expected3[i],ptr[i],1e-12); - f->renumberCells(renumber2,false);//perform reverse operation of renumbering to check that the resulting field is equal. - CPPUNIT_ASSERT(f->isEqual(fCpy,1e-12,1e-12)); - fCpy->decrRef(); - f->decrRef(); - // - m->decrRef(); -} - -void MEDCouplingBasicsTest2::testRenumberNodesForFields() -{ - MEDCouplingUMesh *m=build2DTargetMesh_1(); - MEDCouplingFieldDouble *f=MEDCouplingFieldDouble::New(ON_NODES,NO_TIME); - f->setMesh(m); - CPPUNIT_ASSERT_EQUAL(9,f->getNumberOfMeshPlacesExpected()); - DataArrayDouble *arr=DataArrayDouble::New(); - int nbOfNodes=m->getNumberOfNodes(); - arr->alloc(nbOfNodes,3); - f->setArray(arr); - arr->decrRef(); - const double values1[27]={7.,107.,10007.,8.,108.,10008.,9.,109.,10009.,10.,110.,10010.,11.,111.,10011.,12.,112.,10012.,13.,113.,10013.,14.,114.,10014.,15.,115.,10015.}; - std::copy(values1,values1+27,arr->getPointer()); - f->checkCoherency(); - const int renumber1[9]={0,4,1,3,5,2,6,7,8}; - double res[3]; - const double loc[]={0.5432,-0.2432, 0.5478,0.1528}; - const double expected1[6]={9.0272, 109.0272, 10009.0272, 11.4124,111.4124,10011.4124}; - for(int j=0;j<2;j++) - { - f->getValueOn(loc+2*j,res); - for(int i=0;i<3;i++) - CPPUNIT_ASSERT_DOUBLES_EQUAL(expected1[i+3*j],res[i],1e-12); - } - MEDCouplingFieldDouble *fCpy=f->clone(true); - CPPUNIT_ASSERT(f->isEqual(fCpy,1e-12,1e-12)); - f->renumberNodes(renumber1); - CPPUNIT_ASSERT(!f->isEqual(fCpy,1e-12,1e-12)); - for(int j=0;j<2;j++) - { - f->getValueOn(loc+2*j,res); - for(int i=0;i<3;i++) - CPPUNIT_ASSERT_DOUBLES_EQUAL(expected1[i+3*j],res[i],1e-12); - } - const double expected2[27]={7.,107.,10007.,9.,109.,10009.,12.,112.,10012.,10.,110.,10010.,8.,108.,10008.,11.,111.,10011.,13.,113.,10013.,14.,114.,10014.,15.,115.,10015.}; - for(int i=0;i<27;i++) - CPPUNIT_ASSERT_DOUBLES_EQUAL(expected2[i],f->getArray()->getConstPointer()[i],1e-12); - const int renumber2[9]={0,2,5,3,1,4,6,7,8};//reverse of renumber2 - f->renumberNodes(renumber2); - CPPUNIT_ASSERT(f->isEqual(fCpy,1e-12,1e-12)); - fCpy->decrRef(); - // - m->decrRef(); - f->decrRef(); -} - -void MEDCouplingBasicsTest2::testConvertQuadraticCellsToLinear() -{ - MEDCouplingUMesh *mesh=build2DTargetMesh_3(); - mesh->checkCoherency(); - std::set types=mesh->getAllGeoTypes(); - CPPUNIT_ASSERT_EQUAL(5,(int)types.size()); - INTERP_KERNEL::NormalizedCellType expected1[5]={INTERP_KERNEL::NORM_POLYGON, INTERP_KERNEL::NORM_TRI3, INTERP_KERNEL::NORM_QUAD4, INTERP_KERNEL::NORM_TRI6, INTERP_KERNEL::NORM_QUAD8}; - std::set expected1Bis(expected1,expected1+5); - CPPUNIT_ASSERT(expected1Bis==types); - CPPUNIT_ASSERT(mesh->isPresenceOfQuadratic()); - CPPUNIT_ASSERT_EQUAL(62,mesh->getMeshLength()); - MEDCouplingFieldDouble *f1=mesh->getMeasureField(false); - // - mesh->convertQuadraticCellsToLinear(); - CPPUNIT_ASSERT(!mesh->isPresenceOfQuadratic()); - // - mesh->checkCoherency(); - MEDCouplingFieldDouble *f2=mesh->getMeasureField(false); - CPPUNIT_ASSERT(f1->getArray()->isEqual(*f2->getArray(),1e-12)); - CPPUNIT_ASSERT_EQUAL(48,mesh->getMeshLength()); - std::set types2=mesh->getAllGeoTypes(); - CPPUNIT_ASSERT_EQUAL(3,(int)types2.size()); - INTERP_KERNEL::NormalizedCellType expected2[3]={INTERP_KERNEL::NORM_POLYGON, INTERP_KERNEL::NORM_TRI3, INTERP_KERNEL::NORM_QUAD4}; - std::set expected2Bis(expected2,expected2+3); - CPPUNIT_ASSERT(expected2Bis==types2); - // - f1->decrRef(); - f2->decrRef(); - mesh->decrRef(); -} - -void MEDCouplingBasicsTest2::testCheckGeoEquivalWith() -{ - MEDCouplingUMesh *mesh1=build2DTargetMesh_3(); - MEDCouplingUMesh *mesh2=build2DTargetMesh_3(); - DataArrayInt *cellCor,*nodeCor; - //First test mesh1 - mesh1->checkGeoEquivalWith(mesh1,0,1e-12,cellCor,nodeCor);//deepEqual - CPPUNIT_ASSERT(cellCor==0); - CPPUNIT_ASSERT(nodeCor==0); - mesh1->checkGeoEquivalWith(mesh1,1,1e-12,cellCor,nodeCor);//fastEqual - CPPUNIT_ASSERT(cellCor==0); - CPPUNIT_ASSERT(nodeCor==0); - mesh1->checkGeoEquivalWith(mesh1,10,1e-12,cellCor,nodeCor);//deepEqual with geo permutations - CPPUNIT_ASSERT(cellCor==0); - CPPUNIT_ASSERT(nodeCor==0); - //Second test mesh1 and mesh2 are 2 different meshes instance - mesh1->checkGeoEquivalWith(mesh2,0,1e-12,cellCor,nodeCor);//deepEqual - CPPUNIT_ASSERT(cellCor==0); - CPPUNIT_ASSERT(nodeCor==0); - mesh1->checkGeoEquivalWith(mesh2,1,1e-12,cellCor,nodeCor);//fastEqual - CPPUNIT_ASSERT(cellCor==0); - CPPUNIT_ASSERT(nodeCor==0); - mesh1->checkGeoEquivalWith(mesh2,10,1e-12,cellCor,nodeCor);//deepEqual with geo permutations - CPPUNIT_ASSERT(cellCor==0); - CPPUNIT_ASSERT(nodeCor==0); - //Third test : cell permutation by keeping the first the middle and the last as it is. - const int renum[]={0,2,1,3,4,5,6,8,7,9}; - mesh2->renumberCells(renum,false); - CPPUNIT_ASSERT_THROW(mesh1->checkGeoEquivalWith(mesh2,0,1e-12,cellCor,nodeCor),INTERP_KERNEL::Exception);//deepEqual fails - CPPUNIT_ASSERT(cellCor==0); - CPPUNIT_ASSERT(nodeCor==0); - mesh1->checkGeoEquivalWith(mesh2,1,1e-12,cellCor,nodeCor);//fastEqual do not see anything - CPPUNIT_ASSERT(cellCor==0); - CPPUNIT_ASSERT(nodeCor==0); - mesh1->checkGeoEquivalWith(mesh2,10,1e-12,cellCor,nodeCor);//deepEqual with geo permutations - CPPUNIT_ASSERT(cellCor); - CPPUNIT_ASSERT_EQUAL(10,cellCor->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(1,cellCor->getNumberOfComponents()); - CPPUNIT_ASSERT(std::equal(renum,renum+10,cellCor->getConstPointer())); - CPPUNIT_ASSERT(nodeCor==0); - cellCor->decrRef(); - cellCor=0; - CPPUNIT_ASSERT(nodeCor==0); - //4th test : cell and node permutation by keeping the first the middle and the last as it is. - mesh2->decrRef(); - mesh2=build2DTargetMesh_3(); - const int renum2[]={0,2,1,3,4,5,6,8,7,9,10}; - mesh2->renumberCells(renum,false); - mesh2->renumberNodes(renum2,11); - CPPUNIT_ASSERT_THROW(mesh1->checkGeoEquivalWith(mesh2,0,1e-12,cellCor,nodeCor),INTERP_KERNEL::Exception);//deepEqual fails - CPPUNIT_ASSERT(cellCor==0); - CPPUNIT_ASSERT(nodeCor==0); - mesh1->checkGeoEquivalWith(mesh2,1,1e-12,cellCor,nodeCor);//fastEqual do not see anything - CPPUNIT_ASSERT(cellCor==0); - CPPUNIT_ASSERT(nodeCor==0); - mesh1->checkGeoEquivalWith(mesh2,10,1e-12,cellCor,nodeCor);//deepEqual with geo permutations - CPPUNIT_ASSERT(cellCor); - CPPUNIT_ASSERT_EQUAL(10,cellCor->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(1,cellCor->getNumberOfComponents()); - CPPUNIT_ASSERT(std::equal(renum,renum+10,cellCor->getConstPointer())); - CPPUNIT_ASSERT(nodeCor); - CPPUNIT_ASSERT_EQUAL(11,nodeCor->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(1,nodeCor->getNumberOfComponents()); - CPPUNIT_ASSERT(std::equal(renum2,renum2+11,nodeCor->getConstPointer())); - cellCor->decrRef(); - cellCor=0; - nodeCor->decrRef(); - nodeCor=0; - //5th test : modification of the last cell to check fastCheck detection. - mesh2->decrRef(); - mesh2=build2DTargetMesh_3(); - const int renum3[]={0,2,1,3,4,5,6,8,9,7}; - mesh2->renumberCells(renum3,false); - mesh2->renumberNodes(renum2,11); - bool isExcep=false; - try { mesh1->checkGeoEquivalWith(mesh2,0,1e-12,cellCor,nodeCor);//deepEqual fails - } - catch(INTERP_KERNEL::Exception& e) { isExcep=true; } - CPPUNIT_ASSERT(isExcep); isExcep=false; - CPPUNIT_ASSERT(cellCor==0); - CPPUNIT_ASSERT(nodeCor==0); - try { mesh1->checkGeoEquivalWith(mesh2,1,1e-12,cellCor,nodeCor);//fastEqual has detected something - } - catch(INTERP_KERNEL::Exception& e) { isExcep=true; } - CPPUNIT_ASSERT(isExcep); isExcep=false; - CPPUNIT_ASSERT(cellCor==0); - CPPUNIT_ASSERT(nodeCor==0); - mesh2->checkGeoEquivalWith(mesh1,10,1e-12,cellCor,nodeCor);//deepEqual with geo permutations - CPPUNIT_ASSERT(cellCor); - CPPUNIT_ASSERT_EQUAL(10,cellCor->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(1,cellCor->getNumberOfComponents()); - CPPUNIT_ASSERT(std::equal(renum3,renum3+10,cellCor->getConstPointer())); - CPPUNIT_ASSERT(nodeCor); - CPPUNIT_ASSERT_EQUAL(11,nodeCor->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(1,nodeCor->getNumberOfComponents()); - CPPUNIT_ASSERT(std::equal(renum2,renum2+11,nodeCor->getConstPointer())); - cellCor->decrRef(); - cellCor=0; - nodeCor->decrRef(); - nodeCor=0; - // - mesh1->decrRef(); - mesh2->decrRef(); -} - -void MEDCouplingBasicsTest2::testCheckGeoEquivalWith2() -{ - MEDCouplingUMesh *mesh1=build2DTargetMesh_4(); - MEDCouplingUMesh *mesh2=build2DTargetMesh_1(); - DataArrayInt *cellCor,*nodeCor; - mesh1->checkGeoEquivalWith(mesh2,10,1e-12,cellCor,nodeCor); - CPPUNIT_ASSERT(cellCor==0); - CPPUNIT_ASSERT(nodeCor!=0); - const int expected1[9]={0, 1, 3, 4, 5, 6, 7, 8, 9}; - for(int i=0;i<9;i++) - CPPUNIT_ASSERT_EQUAL(expected1[i],nodeCor->getIJ(i,0)); - nodeCor->decrRef(); - // - mesh1->decrRef(); - mesh2->decrRef(); -} - -void MEDCouplingBasicsTest2::testCopyTinyStringsFromOnFields() -{ - MEDCouplingUMesh *m=build3DSurfTargetMesh_1(); - int nbOfCells=m->getNumberOfCells(); - MEDCouplingFieldDouble *f=MEDCouplingFieldDouble::New(ON_CELLS,LINEAR_TIME); - f->setMesh(m); - CPPUNIT_ASSERT_EQUAL(5,f->getNumberOfMeshPlacesExpected()); - f->setName("a"); - f->setDescription("b"); - DataArrayDouble *a1=DataArrayDouble::New(); - a1->alloc(nbOfCells,2); - a1->fillWithZero(); - a1->setInfoOnComponent(0,"c"); - a1->setInfoOnComponent(1,"d"); - DataArrayDouble *a2=a1->deepCpy(); - a2->setInfoOnComponent(0,"e"); - a2->setInfoOnComponent(1,"f"); - f->setArray(a1); - f->setEndArray(a2); - f->setEndTime(3.,3,4); - a2->decrRef(); - a1->decrRef(); - m->setName("g"); - m->getCoords()->setInfoOnComponent(0,"h"); - m->getCoords()->setInfoOnComponent(1,"i"); - m->getCoords()->setInfoOnComponent(2,"j"); - // - f->checkCoherency(); - MEDCouplingFieldDouble *f2=f->clone(true); - CPPUNIT_ASSERT(f2->isEqual(f,1e-12,1e-12)); - f2->setName("smth"); - CPPUNIT_ASSERT(!f2->isEqual(f,1e-12,1e-12)); - f2->copyTinyStringsFrom(f); - CPPUNIT_ASSERT(f2->isEqual(f,1e-12,1e-12)); - f2->setDescription("GGG"); - CPPUNIT_ASSERT(!f2->isEqual(f,1e-12,1e-12)); - f2->copyTinyStringsFrom(f); - CPPUNIT_ASSERT(f2->isEqual(f,1e-12,1e-12)); - f2->getArray()->setInfoOnComponent(0,"mmmm"); - CPPUNIT_ASSERT(!f2->isEqual(f,1e-12,1e-12)); - f2->copyTinyStringsFrom(f); - CPPUNIT_ASSERT(f2->isEqual(f,1e-12,1e-12)); - f2->getEndArray()->setInfoOnComponent(1,"mmmm"); - CPPUNIT_ASSERT(!f2->isEqual(f,1e-12,1e-12)); - f2->copyTinyStringsFrom(f); - CPPUNIT_ASSERT(f2->isEqual(f,1e-12,1e-12)); - f2->decrRef(); - MEDCouplingUMesh *m2=m->clone(true); - CPPUNIT_ASSERT(m2->isEqual(m,1e-12)); - m2->setName("123"); - CPPUNIT_ASSERT(!m2->isEqual(m,1e-12)); - m2->copyTinyStringsFrom(m); - CPPUNIT_ASSERT(m2->isEqual(m,1e-12)); - m2->getCoords()->setInfoOnComponent(1,"eee"); - CPPUNIT_ASSERT(!m2->isEqual(m,1e-12)); - m2->copyTinyStringsFrom(m); - CPPUNIT_ASSERT(m2->isEqual(m,1e-12)); - m2->decrRef(); - // - f->decrRef(); - m->decrRef(); -} - -void MEDCouplingBasicsTest2::testTryToShareSameCoordsPermute() -{ - MEDCouplingUMesh *m=build3DSurfTargetMesh_1(); - MEDCouplingUMesh *m2=build3DSurfTargetMesh_1(); - CPPUNIT_ASSERT(m->getCoords()!=m2->getCoords()); - m->tryToShareSameCoordsPermute(*m2,1e-12); - CPPUNIT_ASSERT(m->getCoords()==m2->getCoords()); - CPPUNIT_ASSERT(m2->isEqual(m,1e-12)); - const int renum1[9]={1,2,0,5,8,7,4,3,6}; - m->renumberNodes(renum1,9); - CPPUNIT_ASSERT(m->getCoords()!=m2->getCoords()); - CPPUNIT_ASSERT(!m2->isEqual(m,1e-12)); - m->tryToShareSameCoordsPermute(*m2,1e-12); - CPPUNIT_ASSERT(m->getCoords()==m2->getCoords()); - CPPUNIT_ASSERT(m2->isEqual(m,1e-12)); - m2->decrRef(); - m->decrRef(); -} - -void MEDCouplingBasicsTest2::testTryToShareSameCoordsPermute2() -{ - MEDCouplingUMesh *m1=build2DTargetMesh_4(); - double targetCoords[8]={-0.3,-0.3, 0.2,-0.3, -0.3,0.2, 0.2,0.2 }; - int targetConn[4]={0,2,3,1}; - MEDCouplingUMesh *m2=MEDCouplingUMesh::New(); - m2->setMeshDimension(2); - m2->allocateCells(1); - m2->insertNextCell(INTERP_KERNEL::NORM_QUAD4,4,targetConn); - m2->finishInsertingCells(); - DataArrayDouble *myCoords=DataArrayDouble::New(); - myCoords->alloc(4,2); - std::copy(targetCoords,targetCoords+8,myCoords->getPointer()); - m2->setCoords(myCoords); - myCoords->decrRef(); - m2->checkCoherency(); - m1->checkCoherency(); - // - const double expected1[5]={0.25,0.125,0.125,0.25,0.25}; - MEDCouplingFieldDouble *f1=m1->getMeasureField(false); - MEDCouplingFieldDouble *f2=m2->getMeasureField(false); - CPPUNIT_ASSERT_EQUAL(5,f1->getArray()->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(1,f2->getArray()->getNumberOfTuples()); - for(int i=0;i<5;i++) - CPPUNIT_ASSERT_DOUBLES_EQUAL(expected1[i],f1->getIJ(i,0),1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(expected1[0],f2->getIJ(0,0),1e-12); - f2->decrRef(); - f1->decrRef(); - CPPUNIT_ASSERT_THROW(m1->tryToShareSameCoordsPermute(*m2,1e-12),INTERP_KERNEL::Exception);// <- here in this order the sharing is impossible. - // Let's go for deeper test of tryToShareSameCoordsPermute - m2->tryToShareSameCoordsPermute(*m1,1e-12); - f1=m1->getMeasureField(false); - f2=m2->getMeasureField(false); - CPPUNIT_ASSERT_EQUAL(5,f1->getArray()->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(1,f2->getArray()->getNumberOfTuples()); - for(int i=0;i<5;i++) - CPPUNIT_ASSERT_DOUBLES_EQUAL(expected1[i],f1->getIJ(i,0),1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(expected1[0],f2->getIJ(0,0),1e-12); - // - f2->decrRef(); - f1->decrRef(); - // - m1->decrRef(); - m2->decrRef(); -} - -void MEDCouplingBasicsTest2::testChangeUnderlyingMesh1() -{ - MEDCouplingUMesh *mesh1=build2DTargetMesh_3(); - MEDCouplingUMesh *mesh2=build2DTargetMesh_3(); - MEDCouplingFieldDouble *f1=MEDCouplingFieldDouble::New(ON_CELLS,NO_TIME); - f1->setMesh(mesh1); - DataArrayDouble *array=DataArrayDouble::New(); - array->alloc(mesh1->getNumberOfCells(),2); - const double arr[20]={7.,107.,8.,108.,9.,109.,10.,110.,11.,111.,12.,112.,13.,113.,14.,114.,15.,115.,16.,116.}; - std::copy(arr,arr+20,array->getPointer()); - f1->setArray(array); - array->decrRef(); - // - const int renum[]={0,2,1,3,4,5,6,8,7,9}; - mesh2->renumberCells(renum,false); - CPPUNIT_ASSERT(f1->getMesh()==mesh1); - f1->changeUnderlyingMesh(mesh1,10,1e-12);// nothing done only to check that nothing done. - CPPUNIT_ASSERT(f1->getMesh()==mesh1); - f1->changeUnderlyingMesh(mesh2,10,1e-12); - CPPUNIT_ASSERT(f1->getMesh()==mesh2); - const double expected1[20]={7.,107.,9.,109.,8.,108.,10.,110.,11.,111.,12.,112.,13.,113.,15.,115.,14.,114.,16.,116.}; - for(int i=0;i<20;i++) - CPPUNIT_ASSERT_DOUBLES_EQUAL(expected1[i],f1->getArray()->getIJ(0,i),1e-12); - f1->decrRef(); - // - f1=MEDCouplingFieldDouble::New(ON_NODES,NO_TIME); - f1->setMesh(mesh1); - array=DataArrayDouble::New(); - array->alloc(mesh1->getNumberOfNodes(),2); - const double arr2[22]={7.,107.,8.,108.,9.,109.,10.,110.,11.,111.,12.,112.,13.,113.,14.,114.,15.,115.,16.,116.,17.,117.}; - std::copy(arr2,arr2+22,array->getPointer()); - f1->setArray(array); - array->decrRef(); - // - const int renum2[]={0,2,10,3,4,5,6,8,7,9,1}; - mesh2->renumberNodes(renum2,11); - CPPUNIT_ASSERT(f1->getMesh()==mesh1); - f1->changeUnderlyingMesh(mesh2,10,1e-12); - CPPUNIT_ASSERT(f1->getMesh()==mesh2); - const double expected2[22]={7.,107.,17.,117.,8.,108.,10.,110.,11.,111.,12.,112.,13.,113.,15.,115.,14.,114.,16.,116.,9.,109.}; - for(int i=0;i<22;i++) - CPPUNIT_ASSERT_DOUBLES_EQUAL(expected2[i],f1->getArray()->getIJ(0,i),1e-12); - f1->decrRef(); - // - mesh1->decrRef(); - mesh2->decrRef(); -} - -void MEDCouplingBasicsTest2::testGetMaxValue1() -{ - MEDCouplingUMesh *m=build3DSurfTargetMesh_1(); - int nbOfCells=m->getNumberOfCells(); - MEDCouplingFieldDouble *f=MEDCouplingFieldDouble::New(ON_CELLS,LINEAR_TIME); - f->setMesh(m); - DataArrayDouble *a1=DataArrayDouble::New(); - a1->alloc(nbOfCells,1); - const double val1[5]={3.,4.,5.,6.,7.}; - std::copy(val1,val1+5,a1->getPointer()); - DataArrayDouble *a2=DataArrayDouble::New(); - a2->alloc(nbOfCells,1); - const double val2[5]={0.,1.,2.,8.,7.}; - std::copy(val2,val2+5,a2->getPointer()); - f->setArray(a1); - f->setEndArray(a2); - f->setEndTime(3.,3,4); - f->checkCoherency(); - // - CPPUNIT_ASSERT_DOUBLES_EQUAL(8.,f->getMaxValue(),1e-14); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.,f->getMinValue(),1e-14); - CPPUNIT_ASSERT_DOUBLES_EQUAL(5.,f->getAverageValue(),1e-14); - CPPUNIT_ASSERT_DOUBLES_EQUAL(5.125,f->getWeightedAverageValue(0),1e-14); - a1->setIJ(0,2,9.5); - CPPUNIT_ASSERT_DOUBLES_EQUAL(9.5,f->getMaxValue(),1e-14); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.,f->getMinValue(),1e-14); - a2->setIJ(0,0,9.); - CPPUNIT_ASSERT_DOUBLES_EQUAL(9.5,f->getMaxValue(),1e-14); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,f->getMinValue(),1e-14); - // - a2->decrRef(); - a1->decrRef(); - m->decrRef(); - f->decrRef(); -} - -void MEDCouplingBasicsTest2::testSubstractInPlaceDM1() -{ - MEDCouplingUMesh *mesh1=build2DTargetMesh_3(); - MEDCouplingUMesh *mesh2=build2DTargetMesh_3(); - MEDCouplingFieldDouble *f1=MEDCouplingFieldDouble::New(ON_CELLS,NO_TIME); - f1->setMesh(mesh1); - DataArrayDouble *array=DataArrayDouble::New(); - array->alloc(mesh1->getNumberOfCells(),2); - const double arr[20]={7.,107.,8.,108.,9.,109.,10.,110.,11.,111.,12.,112.,13.,113.,14.,114.,15.,115.,16.,116.}; - std::copy(arr,arr+20,array->getPointer()); - f1->setArray(array); - array->decrRef(); - // - CPPUNIT_ASSERT_EQUAL(10,f1->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(2,f1->getNumberOfComponents()); - CPPUNIT_ASSERT_EQUAL(20,f1->getNumberOfValues()); - // - const int renum[]={0,2,3,1,4,5,6,8,7,9}; - mesh2->renumberCells(renum,false); - // - MEDCouplingFieldDouble *f2=MEDCouplingFieldDouble::New(ON_CELLS,NO_TIME); - f2->setMesh(mesh2); - array=DataArrayDouble::New(); - array->alloc(mesh2->getNumberOfCells(),2); - const double arr2[20]={7.1,107.1,10.1,110.1,8.1,108.1,9.1,109.1,11.1,111.1,12.1,112.1,13.1,113.1,15.1,115.1,14.1,114.1,16.1,116.1}; - std::copy(arr2,arr2+20,array->getPointer()); - f2->setArray(array); - array->decrRef(); - // - f1->substractInPlaceDM(f2,10,1e-12); - f1->applyFunc(1,"abs(x+y+0.2)"); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.,f1->getMaxValue(),1e-14); - // - f1->decrRef(); - f2->decrRef(); - mesh1->decrRef(); - mesh2->decrRef(); -} - -void MEDCouplingBasicsTest2::testDotCrossProduct1() -{ - MEDCouplingUMesh *mesh1=build2DTargetMesh_3(); - MEDCouplingFieldDouble *f1=MEDCouplingFieldDouble::New(ON_CELLS,ONE_TIME); - f1->setTime(2.3,5,6); - f1->setMesh(mesh1); - DataArrayDouble *array=DataArrayDouble::New(); - array->alloc(mesh1->getNumberOfCells(),3); - const double arr1[30]={7.,107.,207.,8.,108.,208.,9.,109.,209.,10.,110.,210.,11.,111.,211.,12.,112.,212.,13.,113.,213.,14.,114.,214.,15.,115.,215.,16.,116.,216.}; - std::copy(arr1,arr1+30,array->getPointer()); - f1->setArray(array); - array->decrRef(); - MEDCouplingFieldDouble *f2=MEDCouplingFieldDouble::New(ON_CELLS,ONE_TIME); - f2->setTime(7.8,4,5); - f2->setMesh(mesh1); - array=DataArrayDouble::New(); - array->alloc(mesh1->getNumberOfCells(),3); - const double arr2[30]={1.,2.,3.,4.,5.,6.,7.,8.,9.,10.,11.,12.,13.,14.,15.,16.,17.,18.,19.,20.,21.,22.,23.,24.,25.,26.,27.,28.,29.,30.}; - std::copy(arr2,arr2+30,array->getPointer()); - f2->setArray(array); - array->decrRef(); - // - MEDCouplingFieldDouble *f3=f1->dot(*f2); - const double expected1[10]={842.,1820.,2816.,3830.,4862.,5912.,6980.,8066.,9170.,10292.}; - for(int i=0;i<10;i++) - CPPUNIT_ASSERT_DOUBLES_EQUAL(expected1[i],f3->getIJ(i,0),1e-9); - f3->decrRef(); - // - MEDCouplingFieldDouble *f4=f1->crossProduct(*f2); - const double expected2[30]={-93., 186., -93., -392., 784., -392., -691., 1382., -691., -990., 1980., -990., -1289., 2578., -1289., -1588., 3176., -1588., -1887., 3774., -1887., -2186., 4372., -2186., -2485., 4970., -2485., -2784., 5568., -2784.}; - for(int i=0;i<30;i++) - CPPUNIT_ASSERT_DOUBLES_EQUAL(expected2[i],f4->getIJ(0,i),1e-9); - f4->decrRef(); - // - f2->decrRef(); - f1->decrRef(); - mesh1->decrRef(); -} - -void MEDCouplingBasicsTest2::testMinMaxFields1() -{ - MEDCouplingUMesh *mesh1=build2DTargetMesh_3(); - MEDCouplingFieldDouble *f1=MEDCouplingFieldDouble::New(ON_CELLS,ONE_TIME); - f1->setTime(2.3,5,6); - f1->setMesh(mesh1); - DataArrayDouble *array=DataArrayDouble::New(); - array->alloc(mesh1->getNumberOfCells(),3); - const double arr1[30]={7.,107.,207.,8.,108.,208.,9.,109.,209.,10.,110.,210.,11.,111.,211.,12.,112.,212.,13.,113.,213.,14.,114.,214.,15.,115.,215.,16.,116.,216.}; - std::copy(arr1,arr1+30,array->getPointer()); - f1->setArray(array); - array->decrRef(); - MEDCouplingFieldDouble *f2=MEDCouplingFieldDouble::New(ON_CELLS,ONE_TIME); - f2->setTime(7.8,4,5); - f2->setMesh(mesh1); - array=DataArrayDouble::New(); - array->alloc(mesh1->getNumberOfCells(),3); - const double arr2[30]={6.,108.,206.,9.,107.,209.,8.,110.,208.,11.,109.,211.,10.,112.,210.,13.,111.,213.,12.,114.,212.,15.,113.,215.,14.,116.,214.,17.,115.,217.}; - std::copy(arr2,arr2+30,array->getPointer()); - f2->setArray(array); - array->decrRef(); - // - MEDCouplingFieldDouble *f3=f1->max(*f2); - const double expected1[30]={7.,108.,207.,9.,108.,209.,9.,110.,209.,11.,110.,211.,11.,112.,211.,13.,112.,213.,13.,114.,213.,15.,114.,215.,15.,116.,215.,17.,116.,217.}; - for(int i=0;i<30;i++) - CPPUNIT_ASSERT_DOUBLES_EQUAL(expected1[i],f3->getIJ(0,i),1e-9); - f3->decrRef(); - // - MEDCouplingFieldDouble *f4=f1->min(*f2); - const double expected2[30]={6.,107.,206.,8.,107.,208.,8.,109.,208.,10.,109.,210.,10.,111.,210.,12.,111.,212.,12.,113.,212.,14.,113.,214.,14.,115.,214.,16.,115.,216.}; - for(int i=0;i<30;i++) - CPPUNIT_ASSERT_DOUBLES_EQUAL(expected2[i],f4->getIJ(0,i),1e-9); - f4->decrRef(); - // - f2->decrRef(); - f1->decrRef(); - mesh1->decrRef(); -} - -void MEDCouplingBasicsTest2::testApplyLin1() -{ - MEDCouplingUMesh *mesh1=build2DTargetMesh_3(); - MEDCouplingFieldDouble *f1=MEDCouplingFieldDouble::New(ON_CELLS,LINEAR_TIME); - f1->setMesh(mesh1); - DataArrayDouble *array=DataArrayDouble::New(); - array->alloc(mesh1->getNumberOfCells(),2); - const double arr[20]={7.,107.,8.,108.,9.,109.,10.,110.,11.,111.,12.,112.,13.,113.,14.,114.,15.,115.,16.,116.}; - std::copy(arr,arr+20,array->getPointer()); - f1->setArray(array); - array->decrRef(); - // - f1->applyLin(2.,3.,0); - const double expected1[20]={17.,107.,19.,108.,21.,109.,23.,110.,25.,111.,27.,112.,29.,113.,31.,114.,33.,115.,35.,116.}; - for(int i=0;i<20;i++) - CPPUNIT_ASSERT_DOUBLES_EQUAL(expected1[i],f1->getIJ(0,i),1e-9); - // - const double arr2[20]={2.,102.,3.,103.,4.,104.,5.,105.,6.,106.,7.,107.,8.,108.,9.,109.,10.,110.,11.,111.}; - array=DataArrayDouble::New(); - array->alloc(mesh1->getNumberOfCells(),2); - std::copy(arr2,arr2+20,array->getPointer()); - f1->setEndArray(array); - array->decrRef(); - // - f1->applyLin(4.,5.,1); - // - const double expected2[20]={17.,433.,19.,437.,21.,441.,23.,445.,25.,449.,27.,453.,29.,457.,31.,461.,33.,465.,35.,469.}; - for(int i=0;i<20;i++) - CPPUNIT_ASSERT_DOUBLES_EQUAL(expected2[i],f1->getIJ(0,i),1e-9); - const double expected3[20]={2.,413.,3.,417.,4.,421.,5.,425.,6.,429.,7.,433.,8.,437.,9.,441.,10.,445.,11.,449.}; - for(int i=0;i<20;i++) - CPPUNIT_ASSERT_DOUBLES_EQUAL(expected3[i],f1->getEndArray()->getIJ(0,i),1e-9); - // - mesh1->decrRef(); - f1->decrRef(); -} - -void MEDCouplingBasicsTest2::testGetIdsInRange1() -{ - MEDCouplingUMesh *mesh1=build2DTargetMesh_3(); - MEDCouplingFieldDouble *f1=MEDCouplingFieldDouble::New(ON_CELLS,ONE_TIME); - f1->setTime(2.3,5,6); - f1->setMesh(mesh1); - DataArrayDouble *array=DataArrayDouble::New(); - array->alloc(mesh1->getNumberOfCells(),1); - const double arr1[10]={2.,8.,6.,5.,11.,7.,9.,3.,10.,4.}; - std::copy(arr1,arr1+10,array->getPointer()); - f1->setArray(array); - array->decrRef(); - // - f1->checkCoherency(); - DataArrayInt *da=f1->getIdsInRange(2.9,7.1); - CPPUNIT_ASSERT_EQUAL((std::size_t)5,da->getNbOfElems()); - const int expected1[5]={2,3,5,7,9}; - CPPUNIT_ASSERT(std::equal(expected1,expected1+5,da->getConstPointer())); - da->decrRef(); - da=f1->getIdsInRange(8.,12.); - CPPUNIT_ASSERT_EQUAL((std::size_t)4,da->getNbOfElems()); - const int expected2[4]={1,4,6,8}; - CPPUNIT_ASSERT(std::equal(expected2,expected2+4,da->getConstPointer())); - da->decrRef(); - // - f1->decrRef(); - mesh1->decrRef(); -} - -void MEDCouplingBasicsTest2::testBuildSubPart1() -{ - MEDCouplingUMesh *mesh1=build2DTargetMesh_1(); - MEDCouplingFieldDouble *f1=MEDCouplingFieldDouble::New(ON_CELLS,ONE_TIME); - f1->setTime(2.3,5,6); - f1->setMesh(mesh1); - DataArrayDouble *array=DataArrayDouble::New(); - array->alloc(mesh1->getNumberOfCells(),2); - const double arr1[10]={3.,103.,4.,104.,5.,105.,6.,106.,7.,107.}; - std::copy(arr1,arr1+10,array->getPointer()); - f1->setArray(array); - array->decrRef(); - // - const int part1[3]={2,1,4}; - MEDCouplingFieldDouble *f2=f1->buildSubPart(part1,part1+3); - f2->zipCoords(); - CPPUNIT_ASSERT_EQUAL(3,f2->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(2,f2->getNumberOfComponents()); - const double expected1[6]={5.,105.,4.,104.,7.,107.}; - for(int i=0;i<6;i++) - CPPUNIT_ASSERT_DOUBLES_EQUAL(f2->getIJ(0,i),expected1[i],1e-12); - CPPUNIT_ASSERT_EQUAL(3,f2->getMesh()->getNumberOfCells()); - CPPUNIT_ASSERT_EQUAL(6,f2->getMesh()->getNumberOfNodes()); - CPPUNIT_ASSERT_EQUAL(2,f2->getMesh()->getSpaceDimension()); - CPPUNIT_ASSERT_EQUAL(2,f2->getMesh()->getMeshDimension()); - MEDCouplingUMesh *m2C=dynamic_cast(const_cast(f2->getMesh())); - CPPUNIT_ASSERT_EQUAL(13,m2C->getMeshLength()); - const double expected2[12]={0.2, -0.3, 0.7, -0.3, 0.2, 0.2, 0.7, 0.2, 0.2, 0.7, 0.7, 0.7}; - for(int i=0;i<12;i++) - CPPUNIT_ASSERT_DOUBLES_EQUAL(expected2[i],m2C->getCoords()->getIJ(0,i),1.e-12); - const double expected3[13]={3,2,3,1,3,0,2,1,4,4,5,3,2}; - CPPUNIT_ASSERT(std::equal(expected3,expected3+13,m2C->getNodalConnectivity()->getConstPointer())); - const double expected4[4]={0,4,8,13}; - CPPUNIT_ASSERT(std::equal(expected4,expected4+4,m2C->getNodalConnectivityIndex()->getConstPointer())); - f2->decrRef(); - f1->decrRef(); - // Test with field on nodes. - f1=MEDCouplingFieldDouble::New(ON_NODES,ONE_TIME); - f1->setTime(2.3,5,6); - f1->setMesh(mesh1); - array=DataArrayDouble::New(); - array->alloc(mesh1->getNumberOfNodes(),2); - const double arr2[18]={3.,103.,4.,104.,5.,105.,6.,106.,7.,107.,8.,108.,9.,109.,10.,110.,11.,111.}; - std::copy(arr2,arr2+18,array->getPointer()); - f1->setArray(array); - array->decrRef(); - const int part2[2]={1,2}; - f2=f1->buildSubPart(part2,part2+2); - CPPUNIT_ASSERT_EQUAL(4,f2->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(2,f2->getNumberOfComponents()); - const double expected5[8]={4.,104.,5.,105.,7.,107.,8.,108.}; - for(int i=0;i<8;i++) - CPPUNIT_ASSERT_DOUBLES_EQUAL(f2->getIJ(0,i),expected5[i],1e-12); - CPPUNIT_ASSERT_EQUAL(2,f2->getMesh()->getNumberOfCells()); - CPPUNIT_ASSERT_EQUAL(4,f2->getMesh()->getNumberOfNodes()); - CPPUNIT_ASSERT_EQUAL(2,f2->getMesh()->getSpaceDimension()); - CPPUNIT_ASSERT_EQUAL(2,f2->getMesh()->getMeshDimension()); - m2C=dynamic_cast(const_cast(f2->getMesh())); - CPPUNIT_ASSERT_EQUAL(8,m2C->getMeshLength()); - for(int i=0;i<8;i++)//8 is not an error - CPPUNIT_ASSERT_DOUBLES_EQUAL(expected2[i],m2C->getCoords()->getIJ(0,i),1.e-12); - CPPUNIT_ASSERT(std::equal(expected3,expected3+4,m2C->getNodalConnectivity()->getConstPointer()+4)); - CPPUNIT_ASSERT(std::equal(expected3+4,expected3+8,m2C->getNodalConnectivity()->getConstPointer())); - CPPUNIT_ASSERT(std::equal(expected4,expected4+3,m2C->getNodalConnectivityIndex()->getConstPointer())); - f2->decrRef(); - //idem previous because nodes of cell#4 are not fully present in part3 - const int part3[2]={1,2}; - DataArrayInt *arrr=DataArrayInt::New(); - arrr->alloc(2,1); - std::copy(part3,part3+2,arrr->getPointer()); - f2=f1->buildSubPart(arrr); - arrr->decrRef(); - CPPUNIT_ASSERT_EQUAL(4,f2->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(2,f2->getNumberOfComponents()); - for(int i=0;i<8;i++) - CPPUNIT_ASSERT_DOUBLES_EQUAL(f2->getIJ(0,i),expected5[i],1e-12); - CPPUNIT_ASSERT_EQUAL(2,f2->getMesh()->getNumberOfCells()); - CPPUNIT_ASSERT_EQUAL(4,f2->getMesh()->getNumberOfNodes()); - CPPUNIT_ASSERT_EQUAL(2,f2->getMesh()->getSpaceDimension()); - CPPUNIT_ASSERT_EQUAL(2,f2->getMesh()->getMeshDimension()); - m2C=dynamic_cast(const_cast(f2->getMesh())); - CPPUNIT_ASSERT_EQUAL(8,m2C->getMeshLength()); - for(int i=0;i<8;i++)//8 is not an error - CPPUNIT_ASSERT_DOUBLES_EQUAL(expected2[i],m2C->getCoords()->getIJ(0,i),1.e-12); - CPPUNIT_ASSERT(std::equal(expected3,expected3+4,m2C->getNodalConnectivity()->getConstPointer()+4)); - CPPUNIT_ASSERT(std::equal(expected3+4,expected3+8,m2C->getNodalConnectivity()->getConstPointer())); - CPPUNIT_ASSERT(std::equal(expected4,expected4+3,m2C->getNodalConnectivityIndex()->getConstPointer())); - f2->decrRef(); - // - const int part4[3]={1,2,4}; - f2=f1->buildSubPart(part4,part4+3); - CPPUNIT_ASSERT_EQUAL(6,f2->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(2,f2->getNumberOfComponents()); - const double expected6[12]={4.,104.,5.,105.,7.,107.,8.,108.,10.,110.,11.,111.}; - for(int i=0;i<12;i++) - CPPUNIT_ASSERT_DOUBLES_EQUAL(f2->getIJ(0,i),expected6[i],1e-12); - CPPUNIT_ASSERT_EQUAL(3,f2->getMesh()->getNumberOfCells()); - CPPUNIT_ASSERT_EQUAL(6,f2->getMesh()->getNumberOfNodes()); - CPPUNIT_ASSERT_EQUAL(2,f2->getMesh()->getSpaceDimension()); - CPPUNIT_ASSERT_EQUAL(2,f2->getMesh()->getMeshDimension()); - m2C=dynamic_cast(const_cast(f2->getMesh())); - CPPUNIT_ASSERT_EQUAL(13,m2C->getMeshLength()); - for(int i=0;i<12;i++) - CPPUNIT_ASSERT_DOUBLES_EQUAL(expected2[i],m2C->getCoords()->getIJ(0,i),1.e-12); - CPPUNIT_ASSERT(std::equal(expected3,expected3+4,m2C->getNodalConnectivity()->getConstPointer()+4)); - CPPUNIT_ASSERT(std::equal(expected3+4,expected3+8,m2C->getNodalConnectivity()->getConstPointer())); - CPPUNIT_ASSERT(std::equal(expected3+8,expected3+13,m2C->getNodalConnectivity()->getConstPointer()+8)); - CPPUNIT_ASSERT(std::equal(expected4,expected4+4,m2C->getNodalConnectivityIndex()->getConstPointer())); - f2->decrRef(); - // - f1->decrRef(); - mesh1->decrRef(); -} - -void MEDCouplingBasicsTest2::testDoublyContractedProduct1() -{ - MEDCouplingUMesh *mesh1=build2DTargetMesh_1(); - MEDCouplingFieldDouble *f1=MEDCouplingFieldDouble::New(ON_CELLS,NO_TIME); - f1->setMesh(mesh1); - DataArrayDouble *array=DataArrayDouble::New(); - array->alloc(mesh1->getNumberOfCells(),6); - const double arr1[30]={7.8,8.9,9.1,10.2,23.4,34.5, 7.8,8.9,9.1,10.2,23.4,34.5, 7.8,8.9,9.1,10.2,23.4,34.5, 7.8,8.9,9.1,10.2,23.4,34.5, 7.8,8.9,9.1,10.2,23.4,34.5}; - std::copy(arr1,arr1+30,array->getPointer()); - f1->setArray(array); - array->decrRef(); - f1->checkCoherency(); - // - MEDCouplingFieldDouble *f2=f1->doublyContractedProduct(); - f2->checkCoherency(); - CPPUNIT_ASSERT_EQUAL(1,f2->getNumberOfComponents()); - CPPUNIT_ASSERT_EQUAL(5,f2->getNumberOfTuples()); - for(int i=0;i<5;i++) - CPPUNIT_ASSERT_DOUBLES_EQUAL(3906.56,f2->getIJ(i,0),1e-9); - f2->decrRef(); - // - mesh1->decrRef(); - f1->decrRef(); -} - -void MEDCouplingBasicsTest2::testDeterminant1() -{ - MEDCouplingUMesh *mesh1=build2DTargetMesh_1(); - MEDCouplingFieldDouble *f1=MEDCouplingFieldDouble::New(ON_CELLS,CONST_ON_TIME_INTERVAL); - f1->setTime(2.3,5,6); - f1->setEndTime(3.8,7,3); - f1->setMesh(mesh1); - DataArrayDouble *array=DataArrayDouble::New(); - array->alloc(mesh1->getNumberOfCells(),4); - const double arr1[20]={1.2,2.3,3.4,4.5, 1.2,2.3,3.4,4.5, 1.2,2.3,3.4,4.5, 1.2,2.3,3.4,4.5, 1.2,2.3,3.4,4.5}; - std::copy(arr1,arr1+20,array->getPointer()); - f1->setArray(array); - array->decrRef(); - //4 components - f1->checkCoherency(); - MEDCouplingFieldDouble *f2=f1->determinant(); - f2->checkCoherency(); - CPPUNIT_ASSERT_EQUAL(CONST_ON_TIME_INTERVAL,f2->getTimeDiscretization()); - CPPUNIT_ASSERT_EQUAL(1,f2->getNumberOfComponents()); - CPPUNIT_ASSERT_EQUAL(5,f2->getNumberOfValues()); - for(int i=0;i<5;i++) - CPPUNIT_ASSERT_DOUBLES_EQUAL(-2.42,f2->getIJ(i,0),1e-13); - f2->decrRef(); - f1->decrRef(); - //6 components multi arrays with end array not defined - f1=MEDCouplingFieldDouble::New(ON_NODES,LINEAR_TIME); - f1->setTime(2.3,5,6); - f1->setEndTime(3.8,7,3); - f1->setMesh(mesh1); - array=DataArrayDouble::New(); - array->alloc(mesh1->getNumberOfNodes(),6); - const double arr2[54]={1.2,2.3,3.4,4.5,5.6,6.7, 1.2,2.3,3.4,4.5,5.6,6.7, 1.2,2.3,3.4,4.5,5.6,6.7, 1.2,2.3,3.4,4.5,5.6,6.7, 1.2,2.3,3.4,4.5,5.6,6.7, - 1.2,2.3,3.4,4.5,5.6,6.7, 1.2,2.3,3.4,4.5,5.6,6.7, 1.2,2.3,3.4,4.5,5.6,6.7, 1.2,2.3,3.4,4.5,5.6,6.7}; - std::copy(arr2,arr2+54,array->getPointer()); - f1->setArray(array); - array->decrRef(); - CPPUNIT_ASSERT_THROW(f1->checkCoherency(),INTERP_KERNEL::Exception);//no end array specified ! - // - f2=f1->determinant(); - CPPUNIT_ASSERT_EQUAL(LINEAR_TIME,f2->getTimeDiscretization()); - CPPUNIT_ASSERT_EQUAL(1,f2->getArray()->getNumberOfComponents()); - CPPUNIT_ASSERT_EQUAL(9,f2->getNumberOfTuples()); - for(int i=0;i<9;i++) - CPPUNIT_ASSERT_DOUBLES_EQUAL(137.335,f2->getIJ(i,0),1e-10); - f2->decrRef(); - //6 components multi arrays with end array defined - array=DataArrayDouble::New(); - array->alloc(mesh1->getNumberOfNodes(),6); - const double arr3[54]={7.8,8.9,9.1,10.2,23.4,34.5, 7.8,8.9,9.1,10.2,23.4,34.5, 7.8,8.9,9.1,10.2,23.4,34.5, 7.8,8.9,9.1,10.2,23.4,34.5, 7.8,8.9,9.1,10.2,23.4,34.5, - 7.8,8.9,9.1,10.2,23.4,34.5, 7.8,8.9,9.1,10.2,23.4,34.5, 7.8,8.9,9.1,10.2,23.4,34.5, 7.8,8.9,9.1,10.2,23.4,34.5}; - std::copy(arr3,arr3+54,array->getPointer()); - f1->setEndArray(array); - array->decrRef(); - f1->checkCoherency(); - f2=f1->determinant(); - f2->checkCoherency(); - CPPUNIT_ASSERT_EQUAL(LINEAR_TIME,f2->getTimeDiscretization()); - CPPUNIT_ASSERT_EQUAL(1,f2->getNumberOfComponents()); - CPPUNIT_ASSERT_EQUAL(9,f2->getNumberOfTuples()); - int it,order; - CPPUNIT_ASSERT_DOUBLES_EQUAL(2.3,f2->getTime(it,order),1e-12); - CPPUNIT_ASSERT_EQUAL(5,it); CPPUNIT_ASSERT_EQUAL(6,order); - CPPUNIT_ASSERT_DOUBLES_EQUAL(3.8,f2->getEndTime(it,order),1e-12); - CPPUNIT_ASSERT_EQUAL(7,it); CPPUNIT_ASSERT_EQUAL(3,order); - for(int i=0;i<9;i++) - { - CPPUNIT_ASSERT_DOUBLES_EQUAL(137.335,f2->getIJ(i,0),1e-10); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1289.685,f2->getEndArray()->getIJ(i,0),1e-9); - } - f2->decrRef(); - f1->decrRef(); - //9 components - f1=MEDCouplingFieldDouble::New(ON_CELLS,ONE_TIME); - f1->setTime(7.8,10,2); - f1->setMesh(mesh1); - array=DataArrayDouble::New(); - array->alloc(mesh1->getNumberOfCells(),9); - const double arr4[45]={1.2,2.3,3.4,4.5,5.6,6.7,7.8,8.9,9.1, 1.2,2.3,3.4,4.5,5.6,6.7,7.8,8.9,9.1, 1.2,2.3,3.4,4.5,5.6,6.7,7.8,8.9,9.1, 1.2,2.3,3.4,4.5,5.6,6.7,7.8,8.9,9.1, 1.2,2.3,3.4,4.5,5.6,6.7,7.8,8.9,9.1}; - std::copy(arr4,arr4+45,array->getPointer()); - f1->setArray(array); - array->decrRef(); - // - f1->checkCoherency(); - f2=f1->determinant(); - f2->checkCoherency(); - CPPUNIT_ASSERT_EQUAL(ONE_TIME,f2->getTimeDiscretization()); - CPPUNIT_ASSERT_EQUAL(1,f2->getNumberOfComponents()); - CPPUNIT_ASSERT_EQUAL(5,f2->getNumberOfTuples()); - CPPUNIT_ASSERT_DOUBLES_EQUAL(7.8,f2->getTime(it,order),1e-12); - CPPUNIT_ASSERT_EQUAL(10,it); CPPUNIT_ASSERT_EQUAL(2,order); - for(int i=0;i<5;i++) - CPPUNIT_ASSERT_DOUBLES_EQUAL(3.267,f2->getIJ(i,0),1e-13); - f2->decrRef(); - // - mesh1->decrRef(); - f1->decrRef(); -} - -void MEDCouplingBasicsTest2::testEigenValues1() -{ - MEDCouplingUMesh *mesh1=build2DTargetMesh_1(); - MEDCouplingFieldDouble *f1=MEDCouplingFieldDouble::New(ON_CELLS,NO_TIME); - f1->setMesh(mesh1); - DataArrayDouble *array=DataArrayDouble::New(); - array->alloc(mesh1->getNumberOfCells(),6); - const double arr1[30]={1.2,2.3,3.4,4.5,5.6,6.7, 1.2,2.3,3.4,4.5,5.6,6.7, 1.2,2.3,3.4,4.5,5.6,6.7, 1.2,2.3,3.4,4.5,5.6,6.7, 1.2,2.3,3.4,4.5,5.6,6.7}; - std::copy(arr1,arr1+30,array->getPointer()); - f1->setArray(array); - array->decrRef(); - f1->checkCoherency(); - // - MEDCouplingFieldDouble *f2=f1->eigenValues(); - f2->checkCoherency(); - CPPUNIT_ASSERT_EQUAL(3,f2->getNumberOfComponents()); - CPPUNIT_ASSERT_EQUAL(5,f2->getNumberOfTuples()); - const double expected1[3]={13.638813677891717,-4.502313844635971,-2.2364998332557486}; - for(int i=0;i<5;i++) - { - CPPUNIT_ASSERT_DOUBLES_EQUAL(expected1[0],f2->getIJ(i,0),1e-13); - CPPUNIT_ASSERT_DOUBLES_EQUAL(expected1[1],f2->getIJ(i,1),1e-13); - CPPUNIT_ASSERT_DOUBLES_EQUAL(expected1[2],f2->getIJ(i,2),1e-13); - } - f2->decrRef(); - // - mesh1->decrRef(); - f1->decrRef(); -} - -void MEDCouplingBasicsTest2::testEigenVectors1() -{ - MEDCouplingUMesh *mesh1=build2DTargetMesh_1(); - MEDCouplingFieldDouble *f1=MEDCouplingFieldDouble::New(ON_CELLS,NO_TIME); - f1->setMesh(mesh1); - DataArrayDouble *array=DataArrayDouble::New(); - array->alloc(mesh1->getNumberOfCells(),6); - const double arr1[30]={1.2,2.3,3.4,4.5,5.6,6.7, 1.2,2.3,3.4,4.5,5.6,6.7, 1.2,2.3,3.4,4.5,5.6,6.7, 1.2,2.3,3.4,4.5,5.6,6.7, 1.2,2.3,3.4,4.5,5.6,6.7}; - std::copy(arr1,arr1+30,array->getPointer()); - f1->setArray(array); - array->decrRef(); - f1->checkCoherency(); - // - MEDCouplingFieldDouble *f2=f1->eigenVectors(); - f2->checkCoherency(); - CPPUNIT_ASSERT_EQUAL(9,f2->getNumberOfComponents()); - CPPUNIT_ASSERT_EQUAL(5,f2->getNumberOfTuples()); - const double expected1[9]={ - 0.5424262364180696, 0.5351201064614425, 0.6476266283176001,//eigenvect 0 - 0.7381111277307373, 0.06458838384003074, -0.6715804522117897,//eigenvect 1 - -0.4012053603397987, 0.8423032781211455, -0.3599436712889738//eigenvect 2 - }; - for(int i=0;i<5;i++) - { - CPPUNIT_ASSERT_DOUBLES_EQUAL(expected1[0],f2->getIJ(i,0),1e-13); - CPPUNIT_ASSERT_DOUBLES_EQUAL(expected1[1],f2->getIJ(i,1),1e-13); - CPPUNIT_ASSERT_DOUBLES_EQUAL(expected1[2],f2->getIJ(i,2),1e-13); - CPPUNIT_ASSERT_DOUBLES_EQUAL(expected1[3],f2->getIJ(i,3),1e-13); - CPPUNIT_ASSERT_DOUBLES_EQUAL(expected1[4],f2->getIJ(i,4),1e-13); - CPPUNIT_ASSERT_DOUBLES_EQUAL(expected1[5],f2->getIJ(i,5),1e-13); - CPPUNIT_ASSERT_DOUBLES_EQUAL(expected1[6],f2->getIJ(i,6),1e-13); - CPPUNIT_ASSERT_DOUBLES_EQUAL(expected1[7],f2->getIJ(i,7),1e-13); - CPPUNIT_ASSERT_DOUBLES_EQUAL(expected1[8],f2->getIJ(i,8),1e-13); - } - f2->decrRef(); - // - mesh1->decrRef(); - f1->decrRef(); -} - -void MEDCouplingBasicsTest2::testInverse1() -{ - MEDCouplingUMesh *mesh1=build2DTargetMesh_1(); - MEDCouplingFieldDouble *f1=MEDCouplingFieldDouble::New(ON_CELLS,NO_TIME); - f1->setMesh(mesh1); - DataArrayDouble *array=DataArrayDouble::New(); - array->alloc(mesh1->getNumberOfCells(),9); - const double arr1[45]={1.2,2.3,3.4,4.5,5.6,6.7,7.8,8.9,9.1, 1.2,2.3,3.4,4.5,5.6,6.7,7.8,8.9,9.1, 1.2,2.3,3.4,4.5,5.6,6.7,7.8,8.9,9.1, 1.2,2.3,3.4,4.5,5.6,6.7,7.8,8.9,9.1, 1.2,2.3,3.4,4.5,5.6,6.7,7.8,8.9,9.1}; - std::copy(arr1,arr1+45,array->getPointer()); - f1->setArray(array); - array->decrRef(); - f1->checkCoherency(); - // - MEDCouplingFieldDouble *f2=f1->inverse(); - f2->checkCoherency(); - CPPUNIT_ASSERT_EQUAL(9,f2->getNumberOfComponents()); - CPPUNIT_ASSERT_EQUAL(5,f2->getNumberOfTuples()); - const double expected1[9]={-2.6538108356290113, 2.855831037649208, -1.1111111111111067, 3.461891643709813, -4.775022956841121, 2.2222222222222143, -1.1111111111111054, 2.222222222222214, -1.1111111111111072}; - for(int i=0;i<5;i++) - { - CPPUNIT_ASSERT_DOUBLES_EQUAL(expected1[0],f2->getIJ(i,0),1e-13); - CPPUNIT_ASSERT_DOUBLES_EQUAL(expected1[1],f2->getIJ(i,1),1e-13); - CPPUNIT_ASSERT_DOUBLES_EQUAL(expected1[2],f2->getIJ(i,2),1e-13); - CPPUNIT_ASSERT_DOUBLES_EQUAL(expected1[3],f2->getIJ(i,3),1e-13); - CPPUNIT_ASSERT_DOUBLES_EQUAL(expected1[4],f2->getIJ(i,4),1e-13); - CPPUNIT_ASSERT_DOUBLES_EQUAL(expected1[5],f2->getIJ(i,5),1e-13); - CPPUNIT_ASSERT_DOUBLES_EQUAL(expected1[6],f2->getIJ(i,6),1e-13); - CPPUNIT_ASSERT_DOUBLES_EQUAL(expected1[7],f2->getIJ(i,7),1e-13); - CPPUNIT_ASSERT_DOUBLES_EQUAL(expected1[8],f2->getIJ(i,8),1e-13); - } - f2->decrRef(); - // - array=DataArrayDouble::New(); - array->alloc(mesh1->getNumberOfCells(),6); - const double arr3[30]={7.8,8.9,9.1,10.2,23.4,34.5, 7.8,8.9,9.1,10.2,23.4,34.5, 7.8,8.9,9.1,10.2,23.4,34.5, 7.8,8.9,9.1,10.2,23.4,34.5, 7.8,8.9,9.1,10.2,23.4,34.5}; - std::copy(arr3,arr3+30,array->getPointer()); - f1->setArray(array); - array->decrRef(); - f1->checkCoherency(); - // - f2=f1->inverse(); - f2->checkCoherency(); - CPPUNIT_ASSERT_EQUAL(6,f2->getNumberOfComponents()); - CPPUNIT_ASSERT_EQUAL(5,f2->getNumberOfTuples()); - const double expected3[6]={-0.3617705098531818, -0.8678630828458127, -0.026843764174972983, 0.5539957431465833, 0.13133439560823013, -0.05301294502145887}; - for(int i=0;i<5;i++) - { - CPPUNIT_ASSERT_DOUBLES_EQUAL(expected3[0],f2->getIJ(i,0),1e-13); - CPPUNIT_ASSERT_DOUBLES_EQUAL(expected3[1],f2->getIJ(i,1),1e-13); - CPPUNIT_ASSERT_DOUBLES_EQUAL(expected3[2],f2->getIJ(i,2),1e-13); - CPPUNIT_ASSERT_DOUBLES_EQUAL(expected3[3],f2->getIJ(i,3),1e-13); - CPPUNIT_ASSERT_DOUBLES_EQUAL(expected3[4],f2->getIJ(i,4),1e-13); - CPPUNIT_ASSERT_DOUBLES_EQUAL(expected3[5],f2->getIJ(i,5),1e-13); - } - f2->decrRef(); - // - array=DataArrayDouble::New(); - array->alloc(mesh1->getNumberOfCells(),4); - const double arr2[20]={1.2,2.3,3.4,4.5, 1.2,2.3,3.4,4.5, 1.2,2.3,3.4,4.5, 1.2,2.3,3.4,4.5, 1.2,2.3,3.4,4.5}; - std::copy(arr2,arr2+20,array->getPointer()); - f1->setArray(array); - array->decrRef(); - f1->checkCoherency(); - // - f2=f1->inverse(); - f2->checkCoherency(); - CPPUNIT_ASSERT_EQUAL(4,f2->getNumberOfComponents()); - CPPUNIT_ASSERT_EQUAL(5,f2->getNumberOfTuples()); - const double expected2[4]={-1.8595041322314059, 0.9504132231404963, 1.404958677685951, -0.49586776859504156}; - for(int i=0;i<5;i++) - { - CPPUNIT_ASSERT_DOUBLES_EQUAL(expected2[0],f2->getIJ(i,0),1e-13); - CPPUNIT_ASSERT_DOUBLES_EQUAL(expected2[1],f2->getIJ(i,1),1e-13); - CPPUNIT_ASSERT_DOUBLES_EQUAL(expected2[2],f2->getIJ(i,2),1e-13); - CPPUNIT_ASSERT_DOUBLES_EQUAL(expected2[3],f2->getIJ(i,3),1e-13); - } - f2->decrRef(); - // - mesh1->decrRef(); - f1->decrRef(); -} - -void MEDCouplingBasicsTest2::testTrace1() -{ - MEDCouplingUMesh *mesh1=build2DTargetMesh_1(); - MEDCouplingFieldDouble *f1=MEDCouplingFieldDouble::New(ON_CELLS,NO_TIME); - f1->setMesh(mesh1); - DataArrayDouble *array=DataArrayDouble::New(); - array->alloc(mesh1->getNumberOfCells(),9); - const double arr1[45]={1.2,2.3,3.4,4.5,5.6,6.7,7.8,8.9,9.1, 1.2,2.3,3.4,4.5,5.6,6.7,7.8,8.9,9.1, 1.2,2.3,3.4,4.5,5.6,6.7,7.8,8.9,9.1, 1.2,2.3,3.4,4.5,5.6,6.7,7.8,8.9,9.1, 1.2,2.3,3.4,4.5,5.6,6.7,7.8,8.9,9.1}; - std::copy(arr1,arr1+45,array->getPointer()); - f1->setArray(array); - array->decrRef(); - f1->checkCoherency(); - // - MEDCouplingFieldDouble *f2=f1->trace(); - f2->checkCoherency(); - CPPUNIT_ASSERT_EQUAL(1,f2->getNumberOfComponents()); - CPPUNIT_ASSERT_EQUAL(5,f2->getNumberOfTuples()); - for(int i=0;i<5;i++) - CPPUNIT_ASSERT_DOUBLES_EQUAL(15.9,f2->getIJ(i,0),1e-13); - f2->decrRef(); - // - array=DataArrayDouble::New(); - array->alloc(mesh1->getNumberOfCells(),6); - const double arr3[30]={7.8,8.9,9.1,10.2,23.4,34.5, 7.8,8.9,9.1,10.2,23.4,34.5, 7.8,8.9,9.1,10.2,23.4,34.5, 7.8,8.9,9.1,10.2,23.4,34.5, 7.8,8.9,9.1,10.2,23.4,34.5}; - std::copy(arr3,arr3+30,array->getPointer()); - f1->setArray(array); - array->decrRef(); - f1->checkCoherency(); - // - f2=f1->trace(); - f2->checkCoherency(); - CPPUNIT_ASSERT_EQUAL(1,f2->getNumberOfComponents()); - CPPUNIT_ASSERT_EQUAL(5,f2->getNumberOfTuples()); - for(int i=0;i<5;i++) - CPPUNIT_ASSERT_DOUBLES_EQUAL(25.8,f2->getIJ(i,0),1e-13); - f2->decrRef(); - // - array=DataArrayDouble::New(); - array->alloc(mesh1->getNumberOfCells(),4); - const double arr2[20]={1.2,2.3,3.4,4.5, 1.2,2.3,3.4,4.5, 1.2,2.3,3.4,4.5, 1.2,2.3,3.4,4.5, 1.2,2.3,3.4,4.5}; - std::copy(arr2,arr2+20,array->getPointer()); - f1->setArray(array); - array->decrRef(); - f1->checkCoherency(); - // - f2=f1->trace(); - f2->checkCoherency(); - CPPUNIT_ASSERT_EQUAL(1,f2->getNumberOfComponents()); - CPPUNIT_ASSERT_EQUAL(5,f2->getNumberOfTuples()); - for(int i=0;i<5;i++) - CPPUNIT_ASSERT_DOUBLES_EQUAL(5.7,f2->getIJ(i,0),1e-13); - f2->decrRef(); - // - mesh1->decrRef(); - f1->decrRef(); -} - -void MEDCouplingBasicsTest2::testDeviator1() -{ - MEDCouplingUMesh *mesh1=build2DTargetMesh_1(); - MEDCouplingFieldDouble *f1=MEDCouplingFieldDouble::New(ON_CELLS,NO_TIME); - f1->setMesh(mesh1); - DataArrayDouble *array=DataArrayDouble::New(); - array->alloc(mesh1->getNumberOfCells(),6); - const double arr1[30]={1.2,2.3,3.4,4.5,5.6,6.7, 1.2,2.3,3.4,4.5,5.6,6.7, 1.2,2.3,3.4,4.5,5.6,6.7, 1.2,2.3,3.4,4.5,5.6,6.7, 1.2,2.3,3.4,4.5,5.6,6.7}; - std::copy(arr1,arr1+30,array->getPointer()); - f1->setArray(array); - array->decrRef(); - f1->checkCoherency(); - // - MEDCouplingFieldDouble *f2=f1->deviator(); - f2->checkCoherency(); - CPPUNIT_ASSERT_EQUAL(6,f2->getNumberOfComponents()); - CPPUNIT_ASSERT_EQUAL(5,f2->getNumberOfTuples()); - const double expected1[6]={-1.1,0.,1.1,4.5,5.6,6.7}; - for(int i=0;i<5;i++) - { - CPPUNIT_ASSERT_DOUBLES_EQUAL(expected1[0],f2->getIJ(i,0),1e-13); - CPPUNIT_ASSERT_DOUBLES_EQUAL(expected1[1],f2->getIJ(i,1),1e-13); - CPPUNIT_ASSERT_DOUBLES_EQUAL(expected1[2],f2->getIJ(i,2),1e-13); - CPPUNIT_ASSERT_DOUBLES_EQUAL(expected1[3],f2->getIJ(i,3),1e-13); - CPPUNIT_ASSERT_DOUBLES_EQUAL(expected1[4],f2->getIJ(i,4),1e-13); - CPPUNIT_ASSERT_DOUBLES_EQUAL(expected1[5],f2->getIJ(i,5),1e-13); - } - f2->decrRef(); - // - mesh1->decrRef(); - f1->decrRef(); -} - -void MEDCouplingBasicsTest2::testMagnitude1() -{ - MEDCouplingUMesh *mesh1=build2DTargetMesh_1(); - MEDCouplingFieldDouble *f1=MEDCouplingFieldDouble::New(ON_CELLS,NO_TIME); - f1->setMesh(mesh1); - DataArrayDouble *array=DataArrayDouble::New(); - array->alloc(mesh1->getNumberOfCells(),5); - const double arr1[25]={1.2,2.3,3.4,4.5,5.6, 1.2,2.3,3.4,4.5,5.6, 1.2,2.3,3.4,4.5,5.6, 1.2,2.3,3.4,4.5,5.6, 1.2,2.3,3.4,4.5,5.6}; - std::copy(arr1,arr1+25,array->getPointer()); - f1->setArray(array); - array->decrRef(); - f1->checkCoherency(); - // - MEDCouplingFieldDouble *f2=f1->magnitude(); - f2->checkCoherency(); - CPPUNIT_ASSERT_EQUAL(1,f2->getNumberOfComponents()); - CPPUNIT_ASSERT_EQUAL(5,f2->getNumberOfTuples()); - for(int i=0;i<5;i++) - CPPUNIT_ASSERT_DOUBLES_EQUAL(8.3606219864313918,f2->getIJ(i,0),1e-13); - f2->decrRef(); - // - mesh1->decrRef(); - f1->decrRef(); -} - -void MEDCouplingBasicsTest2::testMaxPerTuple1() -{ - MEDCouplingUMesh *mesh1=build2DTargetMesh_1(); - MEDCouplingFieldDouble *f1=MEDCouplingFieldDouble::New(ON_CELLS,NO_TIME); - f1->setMesh(mesh1); - DataArrayDouble *array=DataArrayDouble::New(); - array->alloc(mesh1->getNumberOfCells(),5); - const double arr1[25]={1.2,2.3,3.4,4.5,5.6, 1.2,3.4,4.5,5.6,2.3, 3.4,4.5,5.6,1.2,2.3, 5.6,1.2,2.3,3.4,4.5, 4.5,5.6,1.2,2.3,3.4}; - std::copy(arr1,arr1+25,array->getPointer()); - f1->setArray(array); - array->decrRef(); - f1->checkCoherency(); - // - MEDCouplingFieldDouble *f2=f1->maxPerTuple(); - f2->checkCoherency(); - CPPUNIT_ASSERT_EQUAL(1,f2->getNumberOfComponents()); - CPPUNIT_ASSERT_EQUAL(5,f2->getNumberOfTuples()); - for(int i=0;i<5;i++) - CPPUNIT_ASSERT_DOUBLES_EQUAL(5.6,f2->getIJ(i,0),1e-13); - f2->decrRef(); - // - DataArrayInt *d2I=0; - DataArrayDouble *d2=array->maxPerTupleWithCompoId(d2I); - CPPUNIT_ASSERT_EQUAL(1,d2->getNumberOfComponents()); - CPPUNIT_ASSERT_EQUAL(5,d2->getNumberOfTuples()); - const int expected2[5]={4,3,2,0,1}; - for(int i=0;i<5;i++) - { - CPPUNIT_ASSERT_DOUBLES_EQUAL(5.6,d2->getIJ(i,0),1e-13); - CPPUNIT_ASSERT_EQUAL(expected2[i],d2I->getIJ(i,0)); - } - d2->decrRef(); d2I->decrRef(); - // - mesh1->decrRef(); - f1->decrRef(); -} - -void MEDCouplingBasicsTest2::testChangeNbOfComponents() -{ - MEDCouplingUMesh *mesh1=build2DTargetMesh_1(); - MEDCouplingFieldDouble *f1=MEDCouplingFieldDouble::New(ON_CELLS,NO_TIME); - f1->setMesh(mesh1); - DataArrayDouble *array=DataArrayDouble::New(); - array->alloc(mesh1->getNumberOfCells(),5); - const double arr1[25]={1.2,2.3,3.4,4.5,5.6, 1.2,3.4,4.5,5.6,2.3, 3.4,4.5,5.6,1.2,2.3, 5.6,1.2,2.3,3.4,4.5, 4.5,5.6,1.2,2.3,3.4}; - std::copy(arr1,arr1+25,array->getPointer()); - f1->setArray(array); - array->decrRef(); - f1->checkCoherency(); - // - f1->changeNbOfComponents(3,7.77); - f1->checkCoherency(); - CPPUNIT_ASSERT_EQUAL(3,f1->getNumberOfComponents()); - CPPUNIT_ASSERT_EQUAL(5,f1->getNumberOfTuples()); - const double expected1[15]={1.2,2.3,3.4, 1.2,3.4,4.5, 3.4,4.5,5.6, 5.6,1.2,2.3, 4.5,5.6,1.2}; - for(int i=0;i<15;i++) - CPPUNIT_ASSERT_DOUBLES_EQUAL(expected1[i],f1->getIJ(0,i),1e-13); - f1->changeNbOfComponents(4,7.77); - f1->checkCoherency(); - CPPUNIT_ASSERT_EQUAL(4,f1->getNumberOfComponents()); - CPPUNIT_ASSERT_EQUAL(5,f1->getNumberOfTuples()); - const double expected2[20]={1.2,2.3,3.4,7.77, 1.2,3.4,4.5,7.77, 3.4,4.5,5.6,7.77, 5.6,1.2,2.3,7.77, 4.5,5.6,1.2,7.77}; - for(int i=0;i<20;i++) - CPPUNIT_ASSERT_DOUBLES_EQUAL(expected2[i],f1->getIJ(0,i),1e-13); - // - mesh1->decrRef(); - f1->decrRef(); -} - -void MEDCouplingBasicsTest2::testSortPerTuple1() -{ - MEDCouplingUMesh *mesh1=build2DTargetMesh_1(); - MEDCouplingFieldDouble *f1=MEDCouplingFieldDouble::New(ON_CELLS,NO_TIME); - f1->setMesh(mesh1); - DataArrayDouble *array=DataArrayDouble::New(); - array->alloc(mesh1->getNumberOfCells(),5); - const double arr1[25]={1.2,2.3,3.4,4.5,5.6, 1.2,3.4,4.5,5.6,2.3, 3.4,4.5,5.6,1.2,2.3, 5.6,1.2,2.3,3.4,4.5, 4.5,5.6,1.2,2.3,3.4}; - std::copy(arr1,arr1+25,array->getPointer()); - f1->setArray(array); - array->decrRef(); - f1->checkCoherency(); - // - f1->sortPerTuple(true); - f1->checkCoherency(); - CPPUNIT_ASSERT_EQUAL(5,f1->getNumberOfComponents()); - CPPUNIT_ASSERT_EQUAL(5,f1->getNumberOfTuples()); - for(int i=0;i<5;i++) - { - CPPUNIT_ASSERT_DOUBLES_EQUAL(arr1[0],f1->getIJ(i,0),1e-13); - CPPUNIT_ASSERT_DOUBLES_EQUAL(arr1[1],f1->getIJ(i,1),1e-13); - CPPUNIT_ASSERT_DOUBLES_EQUAL(arr1[2],f1->getIJ(i,2),1e-13); - CPPUNIT_ASSERT_DOUBLES_EQUAL(arr1[3],f1->getIJ(i,3),1e-13); - CPPUNIT_ASSERT_DOUBLES_EQUAL(arr1[4],f1->getIJ(i,4),1e-13); - } - // - f1->sortPerTuple(false); - f1->checkCoherency(); - CPPUNIT_ASSERT_EQUAL(5,f1->getNumberOfComponents()); - CPPUNIT_ASSERT_EQUAL(5,f1->getNumberOfTuples()); - for(int i=0;i<5;i++) - { - CPPUNIT_ASSERT_DOUBLES_EQUAL(arr1[4],f1->getIJ(i,0),1e-13); - CPPUNIT_ASSERT_DOUBLES_EQUAL(arr1[3],f1->getIJ(i,1),1e-13); - CPPUNIT_ASSERT_DOUBLES_EQUAL(arr1[2],f1->getIJ(i,2),1e-13); - CPPUNIT_ASSERT_DOUBLES_EQUAL(arr1[1],f1->getIJ(i,3),1e-13); - CPPUNIT_ASSERT_DOUBLES_EQUAL(arr1[0],f1->getIJ(i,4),1e-13); - } - // - mesh1->decrRef(); - f1->decrRef(); -} - -void MEDCouplingBasicsTest2::testIsEqualWithoutConsideringStr1() -{ - MEDCouplingUMesh *mesh1=build2DTargetMesh_1(); - MEDCouplingUMesh *mesh2=build2DTargetMesh_1(); - DataArrayInt *da1,*da2; - // - CPPUNIT_ASSERT(mesh1->isEqual(mesh2,1e-12)); - CPPUNIT_ASSERT(mesh1->isEqualWithoutConsideringStr(mesh2,1e-12)); - mesh2->setName("rr"); - CPPUNIT_ASSERT(!mesh1->isEqual(mesh2,1e-12)); - CPPUNIT_ASSERT(mesh1->isEqualWithoutConsideringStr(mesh2,1e-12)); - mesh1->checkDeepEquivalWith(mesh2,2,1e-12,da1,da2); - CPPUNIT_ASSERT_THROW(mesh1->checkGeoEquivalWith(mesh2,0,1e-12,da1,da2),INTERP_KERNEL::Exception); - mesh2->setName(""); - CPPUNIT_ASSERT(mesh1->isEqual(mesh2,1e-12)); - CPPUNIT_ASSERT(mesh1->isEqualWithoutConsideringStr(mesh2,1e-12)); - mesh2->getCoords()->setInfoOnComponent(0,"tty"); - CPPUNIT_ASSERT(!mesh1->isEqual(mesh2,1e-12)); - CPPUNIT_ASSERT(mesh1->isEqualWithoutConsideringStr(mesh2,1e-12)); - mesh2->getCoords()->setInfoOnComponent(0,""); - CPPUNIT_ASSERT(mesh1->isEqual(mesh2,1e-12)); - CPPUNIT_ASSERT(mesh1->isEqualWithoutConsideringStr(mesh2,1e-12)); - mesh2->getCoords()->setInfoOnComponent(1,"tty"); - CPPUNIT_ASSERT(!mesh1->isEqual(mesh2,1e-12)); - CPPUNIT_ASSERT(mesh1->isEqualWithoutConsideringStr(mesh2,1e-12)); - mesh2->getCoords()->setInfoOnComponent(1,""); - CPPUNIT_ASSERT(mesh1->isEqual(mesh2,1e-12)); - CPPUNIT_ASSERT(mesh1->isEqualWithoutConsideringStr(mesh2,1e-12)); - double tmp=mesh2->getCoords()->getIJ(0,3); - mesh2->getCoords()->setIJ(0,3,9999.); - CPPUNIT_ASSERT(!mesh1->isEqual(mesh2,1e-12)); - CPPUNIT_ASSERT(!mesh1->isEqualWithoutConsideringStr(mesh2,1e-12)); - mesh2->getCoords()->setIJ(0,3,tmp); - CPPUNIT_ASSERT(mesh1->isEqual(mesh2,1e-12)); - CPPUNIT_ASSERT(mesh1->isEqualWithoutConsideringStr(mesh2,1e-12)); - int tmp2=mesh2->getNodalConnectivity()->getIJ(0,4); - mesh2->getNodalConnectivity()->setIJ(0,4,0); - CPPUNIT_ASSERT(!mesh1->isEqual(mesh2,1e-12)); - CPPUNIT_ASSERT(!mesh1->isEqualWithoutConsideringStr(mesh2,1e-12)); - mesh2->getNodalConnectivity()->setIJ(0,4,tmp2); - CPPUNIT_ASSERT(mesh1->isEqual(mesh2,1e-12)); - CPPUNIT_ASSERT(mesh1->isEqualWithoutConsideringStr(mesh2,1e-12)); - // - MEDCouplingFieldDouble *f1=mesh1->getMeasureField(true); - MEDCouplingFieldDouble *f2=mesh2->getMeasureField(true); - CPPUNIT_ASSERT(f1->isEqual(f2,1e-12,1e-12)); - CPPUNIT_ASSERT(f1->isEqualWithoutConsideringStr(f2,1e-12,1e-12)); - f2->setName("ftest"); - CPPUNIT_ASSERT(!f1->isEqual(f2,1e-12,1e-12)); - CPPUNIT_ASSERT(f1->isEqualWithoutConsideringStr(f2,1e-12,1e-12)); - f1->setName("ftest"); - CPPUNIT_ASSERT(f1->isEqual(f2,1e-12,1e-12)); - CPPUNIT_ASSERT(f1->isEqualWithoutConsideringStr(f2,1e-12,1e-12)); - // - f2->getArray()->setInfoOnComponent(0,"eee"); - CPPUNIT_ASSERT(!f1->isEqual(f2,1e-12,1e-12)); - CPPUNIT_ASSERT(f1->isEqualWithoutConsideringStr(f2,1e-12,1e-12)); - f2->getArray()->setInfoOnComponent(0,""); - CPPUNIT_ASSERT(f1->isEqual(f2,1e-12,1e-12)); - CPPUNIT_ASSERT(f1->isEqualWithoutConsideringStr(f2,1e-12,1e-12)); - // - f2->getArray()->setIJ(1,0,0.123); - CPPUNIT_ASSERT(!f1->isEqual(f2,1e-12,1e-12)); - CPPUNIT_ASSERT(!f1->isEqualWithoutConsideringStr(f2,1e-12,1e-12)); - f2->getArray()->setIJ(1,0,0.125); - CPPUNIT_ASSERT(f1->isEqual(f2,1e-12,1e-12)); - CPPUNIT_ASSERT(f1->isEqualWithoutConsideringStr(f2,1e-12,1e-12)); - // - f1->decrRef(); - f2->decrRef(); - // - mesh1->decrRef(); - mesh2->decrRef(); -} - -void MEDCouplingBasicsTest2::testGetNodeIdsOfCell1() -{ - MEDCouplingUMesh *mesh1=build2DTargetMesh_1(); - std::vector nodeIds; - mesh1->getNodeIdsOfCell(1,nodeIds); - CPPUNIT_ASSERT_EQUAL(3,(int)nodeIds.size()); - CPPUNIT_ASSERT_EQUAL(1,nodeIds[0]); - CPPUNIT_ASSERT_EQUAL(4,nodeIds[1]); - CPPUNIT_ASSERT_EQUAL(2,nodeIds[2]); - std::vector coords; - mesh1->getCoordinatesOfNode(4,coords); - CPPUNIT_ASSERT_EQUAL(2,(int)coords.size()); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.2,coords[0],1e-13); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.2,coords[1],1e-13); - mesh1->decrRef(); -} - -void MEDCouplingBasicsTest2::testGetEdgeRatioField1() -{ - MEDCouplingUMesh *m1=build2DTargetMesh_1(); - m1->setTime(3.4,5,6); m1->setTimeUnit("us"); - int a,b; - MEDCouplingFieldDouble *f1=m1->getEdgeRatioField(); - CPPUNIT_ASSERT_DOUBLES_EQUAL(3.4,f1->getTime(a,b),1.e-14); - CPPUNIT_ASSERT_EQUAL(5,a); CPPUNIT_ASSERT_EQUAL(6,b); - CPPUNIT_ASSERT_EQUAL(std::string(f1->getTimeUnit()),std::string("us")); - CPPUNIT_ASSERT_EQUAL(m1->getNumberOfCells(),f1->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(5,f1->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(1,f1->getNumberOfComponents()); - const double expected1[5]={1.,1.4142135623730951, 1.4142135623730951,1.,1.}; - for(int i=0;i<5;i++) - CPPUNIT_ASSERT_DOUBLES_EQUAL(expected1[i],f1->getIJ(i,0),1e-14); - f1->decrRef(); - m1->decrRef(); - // - m1=build3DSurfTargetMesh_1(); - f1=m1->getEdgeRatioField(); - CPPUNIT_ASSERT_EQUAL(m1->getNumberOfCells(),f1->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(5,f1->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(1,f1->getNumberOfComponents()); - const double expected2[5]={1.4142135623730951, 1.7320508075688772, 1.7320508075688772, 1.4142135623730951, 1.4142135623730951}; - for(int i=0;i<5;i++) - CPPUNIT_ASSERT_DOUBLES_EQUAL(expected2[i],f1->getIJ(i,0),1e-14); - f1->decrRef(); - m1->decrRef(); -} - -void MEDCouplingBasicsTest2::testFillFromAnalytic3() -{ - MEDCouplingUMesh *m=build2DTargetMesh_1(); - MEDCouplingFieldDouble *f1=MEDCouplingFieldDouble::New(ON_CELLS,ONE_TIME); - CPPUNIT_ASSERT_THROW(f1->fillFromAnalytic(1,"y+x"),INTERP_KERNEL::Exception); - f1->setMesh(m); - f1->setName("myField"); - f1->fillFromAnalytic(1,"y+x"); - f1->checkCoherency(); - CPPUNIT_ASSERT(std::string(f1->getName())=="myField"); - CPPUNIT_ASSERT(f1->getTypeOfField()==ON_CELLS); - CPPUNIT_ASSERT(f1->getTimeDiscretization()==ONE_TIME); - CPPUNIT_ASSERT_EQUAL(1,f1->getNumberOfComponents()); - CPPUNIT_ASSERT_EQUAL(5,f1->getNumberOfTuples()); - double values1[5]={-0.1,0.23333333333333336,0.56666666666666665,0.4,0.9}; - const double *tmp=f1->getArray()->getConstPointer(); - std::transform(tmp,tmp+5,values1,values1,std::minus()); - std::transform(values1,values1+5,values1,std::ptr_fun(fabs)); - double max=*std::max_element(values1,values1+5); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.,max,1.e-12); - f1->decrRef(); - // - f1=MEDCouplingFieldDouble::New(ON_NODES,CONST_ON_TIME_INTERVAL); - f1->setMesh(m); - f1->setEndTime(1.2,3,4); - f1->fillFromAnalytic(1,"y+2*x"); - f1->checkCoherency(); - CPPUNIT_ASSERT(f1->getTypeOfField()==ON_NODES); - CPPUNIT_ASSERT(f1->getTimeDiscretization()==CONST_ON_TIME_INTERVAL); - CPPUNIT_ASSERT_EQUAL(1,f1->getNumberOfComponents()); - CPPUNIT_ASSERT_EQUAL(9,f1->getNumberOfTuples()); - double values2[9]={-0.9,0.1,1.1,-0.4,0.6,1.6,0.1,1.1,2.1}; - tmp=f1->getArray()->getConstPointer(); - std::transform(tmp,tmp+9,values2,values2,std::minus()); - std::transform(values2,values2+9,values2,std::ptr_fun(fabs)); - max=*std::max_element(values2,values2+9); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.,max,1.e-12); - f1->decrRef(); - f1=MEDCouplingFieldDouble::New(ON_NODES,LINEAR_TIME); - f1->setMesh(m); - f1->setEndTime(1.2,3,4); - f1->fillFromAnalytic(1,"2.*x+y"); - f1->checkCoherency(); - CPPUNIT_ASSERT(f1->getTypeOfField()==ON_NODES); - CPPUNIT_ASSERT(f1->getTimeDiscretization()==LINEAR_TIME); - CPPUNIT_ASSERT_EQUAL(1,f1->getNumberOfComponents()); - CPPUNIT_ASSERT_EQUAL(9,f1->getNumberOfTuples()); - tmp=f1->getArray()->getConstPointer(); - double values2Bis[9]={-0.9,0.1,1.1,-0.4,0.6,1.6,0.1,1.1,2.1}; - double values2BisBis[9]; - std::transform(tmp,tmp+9,values2Bis,values2BisBis,std::minus()); - std::transform(values2,values2+9,values2BisBis,std::ptr_fun(fabs)); - max=*std::max_element(values2BisBis,values2BisBis+9); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.,max,1.e-12); - tmp=f1->getEndArray()->getConstPointer(); - std::transform(tmp,tmp+9,values2Bis,values2BisBis,std::minus()); - std::transform(values2,values2+9,values2BisBis,std::ptr_fun(fabs)); - max=*std::max_element(values2BisBis,values2BisBis+9); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.,max,1.e-12); - f1->decrRef(); - // - f1=MEDCouplingFieldDouble::New(ON_NODES,NO_TIME); - f1->setMesh(m); - f1->fillFromAnalytic(2,"(x+y)*IVec+2*(x+y)*JVec"); - f1->checkCoherency(); - CPPUNIT_ASSERT(f1->getTypeOfField()==ON_NODES); - CPPUNIT_ASSERT(f1->getTimeDiscretization()==NO_TIME); - CPPUNIT_ASSERT_EQUAL(2,f1->getNumberOfComponents()); - CPPUNIT_ASSERT_EQUAL(9,f1->getNumberOfTuples()); - double values3[18]={-0.6,-1.2,-0.1,-0.2,0.4,0.8,-0.1,-0.2,0.4,0.8,0.9,1.8,0.4,0.8,0.9,1.8,1.4,2.8}; - tmp=f1->getArray()->getConstPointer(); - std::transform(tmp,tmp+18,values3,values3,std::minus()); - std::transform(values3,values3+18,values3,std::ptr_fun(fabs)); - max=*std::max_element(values3,values3+18); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.,max,1.e-12); - double values4[2]; - f1->accumulate(values4); - CPPUNIT_ASSERT_DOUBLES_EQUAL(3.6,values4[0],1.e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(7.2,values4[1],1.e-12); - f1->integral(true,values4); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.5,values4[0],1.e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,values4[1],1.e-12); - f1->decrRef(); - // - f1=MEDCouplingFieldDouble::New(ON_NODES,NO_TIME); - f1->setMesh(m); - CPPUNIT_ASSERT_THROW(f1->fillFromAnalytic(1,"1./(x-0.2)"),INTERP_KERNEL::Exception); - // - m->decrRef(); - f1->decrRef(); -} - -void MEDCouplingBasicsTest2::testFieldDoubleOpEqual1() -{ - MEDCouplingUMesh *m=build2DTargetMesh_1(); - MEDCouplingFieldDouble *f1=MEDCouplingFieldDouble::New(ON_CELLS,ONE_TIME); - CPPUNIT_ASSERT_THROW((*f1)=0.07,INTERP_KERNEL::Exception); - f1->setMesh(m); - (*f1)=0.07; - f1->checkCoherency(); - CPPUNIT_ASSERT_EQUAL(1,f1->getNumberOfComponents()); - CPPUNIT_ASSERT_EQUAL(5,f1->getNumberOfTuples()); - for(int i=0;i<5;i++) - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.07,f1->getIJ(i,0),1e-16); - (*f1)=0.09; - f1->checkCoherency(); - CPPUNIT_ASSERT_EQUAL(1,f1->getNumberOfComponents()); - CPPUNIT_ASSERT_EQUAL(5,f1->getNumberOfTuples()); - for(int i=0;i<5;i++) - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.09,f1->getIJ(i,0),1e-16); - f1->decrRef(); - // - f1=MEDCouplingFieldDouble::New(ON_NODES,LINEAR_TIME); - f1->setEndTime(4.5,2,3); - f1->setMesh(m); - (*f1)=0.08; - f1->checkCoherency(); - CPPUNIT_ASSERT_EQUAL(1,f1->getNumberOfComponents()); - CPPUNIT_ASSERT_EQUAL(9,f1->getNumberOfTuples()); - for(int i=0;i<9;i++) - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.08,f1->getIJ(i,0),1e-16); - CPPUNIT_ASSERT_EQUAL(1,f1->getEndArray()->getNumberOfComponents()); - CPPUNIT_ASSERT_EQUAL(9,f1->getEndArray()->getNumberOfTuples()); - for(int i=0;i<9;i++) - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.08,f1->getEndArray()->getIJ(i,0),1e-16); - f1->decrRef(); - // - m->decrRef(); -} - -void MEDCouplingBasicsTest2::testAreaBary3D2() -{ - const double coordsForHexa8[24]={ - -75.45749305371, 180.95495078401, 39.515472018008, - -9.755591679144, 23.394927935279, 5.108794294848, - 14.337630157832, 61.705351002702, 160.42422501908, - -27.273893776752, 167.567731083961, 192.830034145464, - // - 99.857193154796,264.499264735586,-8.287335493412, - 144.939882761126,156.38626563134,-31.896173894226, - 161.34096835726,182.4654895809,73.832387065572, - 132.680430393685,255.37973247196,96.15235602819 - }; - const double volHexa8=3258520.29637466; - const double baryHexa8[3]={43.925705821778, 155.31893955289, 65.874418109644}; - - const double coordsForPenta6[18]={ - -68.199829618726,178.938498373416,62.608505919588, - 8.461744647847,76.653979804423,165.00018874933, - -27.273893776752,167.567731083961,192.830034145464, - // - 106.586501038965,262.629609408327,13.124533008813, - 155.465082847275,197.414118382622,78.408350795821, - 132.680430393685,255.37973247196,96.15235602819 - }; - const double volPenta6=944849.868507338; - const double baryPenta6[3]={39.631002313543,182.692711783428,106.98540473964}; - - const double coordsForPyra5[15]={ - 132.680430393685,255.37973247196,96.15235602819, - -27.273893776752,167.567731083961,192.830034145464, - 8.461744647847,76.653979804423,165.00018874933, - 155.465082847275,197.414118382622,78.408350795821, - // - -68.199829618726,178.938498373416,62.608505919588 - }; - const double volPyra5=756943.92980254; - const double baryPyra5[3]={29.204294116618,172.540129749156,118.01035951483}; - MEDCouplingUMesh *mesh=MEDCouplingUMesh::New("Bary3D2",3); - DataArrayDouble *coo=DataArrayDouble::New(); - coo->alloc(19,3); - double *tmp=std::copy(coordsForHexa8,coordsForHexa8+24,coo->getPointer()); - tmp=std::copy(coordsForPenta6,coordsForPenta6+18,tmp); - std::copy(coordsForPyra5,coordsForPyra5+15,tmp); - mesh->setCoords(coo); - coo->decrRef(); - // - int tmpConn[8]={0,1,2,3,4,5,6,7}; - mesh->allocateCells(3); - mesh->insertNextCell(INTERP_KERNEL::NORM_HEXA8,8,tmpConn); - std::transform(tmpConn,tmpConn+8,tmpConn,std::bind2nd(std::plus(),8)); - mesh->insertNextCell(INTERP_KERNEL::NORM_PENTA6,6,tmpConn); - std::transform(tmpConn,tmpConn+8,tmpConn,std::bind2nd(std::plus(),6)); - mesh->insertNextCell(INTERP_KERNEL::NORM_PYRA5,5,tmpConn); - mesh->finishInsertingCells(); - mesh->checkCoherency(); - bool isMerged; - int newNebOfNodes; - DataArrayInt *da=mesh->mergeNodes(1e-7,isMerged,newNebOfNodes); - da->decrRef(); - CPPUNIT_ASSERT_EQUAL(12,newNebOfNodes); - MEDCouplingFieldDouble *vols=mesh->getMeasureField(true); - CPPUNIT_ASSERT_EQUAL(3,vols->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(1,vols->getNumberOfComponents()); - CPPUNIT_ASSERT_DOUBLES_EQUAL(volHexa8,vols->getIJ(0,0),1e-6); - CPPUNIT_ASSERT_DOUBLES_EQUAL(volPenta6,vols->getIJ(1,0),1e-7); - CPPUNIT_ASSERT_DOUBLES_EQUAL(volPyra5,vols->getIJ(2,0),1e-7); - vols->decrRef(); - DataArrayDouble *bary=mesh->getBarycenterAndOwner(); - CPPUNIT_ASSERT_EQUAL(3,bary->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(3,bary->getNumberOfComponents()); - CPPUNIT_ASSERT_DOUBLES_EQUAL(baryHexa8[0],bary->getIJ(0,0),1e-11); - CPPUNIT_ASSERT_DOUBLES_EQUAL(baryHexa8[1],bary->getIJ(0,1),1e-11); - CPPUNIT_ASSERT_DOUBLES_EQUAL(baryHexa8[2],bary->getIJ(0,2),1e-11); - CPPUNIT_ASSERT_DOUBLES_EQUAL(baryPenta6[0],bary->getIJ(1,0),1e-11); - CPPUNIT_ASSERT_DOUBLES_EQUAL(baryPenta6[1],bary->getIJ(1,1),1e-11); - CPPUNIT_ASSERT_DOUBLES_EQUAL(baryPenta6[2],bary->getIJ(1,2),1e-11); - CPPUNIT_ASSERT_DOUBLES_EQUAL(baryPyra5[0],bary->getIJ(2,0),1e-11); - CPPUNIT_ASSERT_DOUBLES_EQUAL(baryPyra5[1],bary->getIJ(2,1),1e-11); - CPPUNIT_ASSERT_DOUBLES_EQUAL(baryPyra5[2],bary->getIJ(2,2),1e-11); - bary->decrRef(); - // - mesh->decrRef(); -} diff --git a/src/MEDCoupling/Test/MEDCouplingBasicsTest2.hxx b/src/MEDCoupling/Test/MEDCouplingBasicsTest2.hxx deleted file mode 100644 index f514d7b31..000000000 --- a/src/MEDCoupling/Test/MEDCouplingBasicsTest2.hxx +++ /dev/null @@ -1,128 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 -// 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 __MEDCOUPLINGBASICSTEST2_HXX__ -#define __MEDCOUPLINGBASICSTEST2_HXX__ - -#include "MEDCouplingBasicsTest.hxx" - -#include -#include - -namespace ParaMEDMEM -{ - class DataArrayDouble; - class MEDCouplingUMesh; - class MEDCouplingFieldDouble; - class MEDCouplingMultiFields; - - class MEDCouplingBasicsTest2 : public MEDCouplingBasicsTest - { - CPPUNIT_TEST_SUITE(MEDCouplingBasicsTest2); - CPPUNIT_TEST( testGaussPointField1 ); - CPPUNIT_TEST( testGaussPointNEField1 ); - CPPUNIT_TEST( testCellOrientation1 ); - CPPUNIT_TEST( testCellOrientation2 ); - CPPUNIT_TEST( testCellOrientation3 ); - CPPUNIT_TEST( testPolyhedronBarycenter ); - CPPUNIT_TEST( testNormL12Integ1D ); - CPPUNIT_TEST( testAreaBary2D ); - CPPUNIT_TEST( testAreaBary3D ); - CPPUNIT_TEST( testRenumberCellsForFields ); - CPPUNIT_TEST( testRenumberNodesForFields ); - CPPUNIT_TEST( testConvertQuadraticCellsToLinear ); - CPPUNIT_TEST( testCheckGeoEquivalWith ); - CPPUNIT_TEST( testCheckGeoEquivalWith2 ); - CPPUNIT_TEST( testCopyTinyStringsFromOnFields ); - CPPUNIT_TEST( testTryToShareSameCoordsPermute ); - CPPUNIT_TEST( testTryToShareSameCoordsPermute2 ); - CPPUNIT_TEST( testChangeUnderlyingMesh1 ); - CPPUNIT_TEST( testGetMaxValue1 ); - CPPUNIT_TEST( testSubstractInPlaceDM1 ); - CPPUNIT_TEST( testDotCrossProduct1 ); - CPPUNIT_TEST( testMinMaxFields1 ); - CPPUNIT_TEST( testApplyLin1 ); - CPPUNIT_TEST( testGetIdsInRange1 ); - CPPUNIT_TEST( testBuildSubPart1 ); - CPPUNIT_TEST( testDoublyContractedProduct1 ); - CPPUNIT_TEST( testDeterminant1 ); - CPPUNIT_TEST( testEigenValues1 ); - CPPUNIT_TEST( testEigenVectors1 ); - CPPUNIT_TEST( testInverse1 ); - CPPUNIT_TEST( testTrace1 ); - CPPUNIT_TEST( testDeviator1 ); - CPPUNIT_TEST( testMagnitude1 ); - CPPUNIT_TEST( testMaxPerTuple1 ); - CPPUNIT_TEST( testChangeNbOfComponents ); - CPPUNIT_TEST( testSortPerTuple1 ); - CPPUNIT_TEST( testIsEqualWithoutConsideringStr1 ); - CPPUNIT_TEST( testGetNodeIdsOfCell1 ); - CPPUNIT_TEST( testGetEdgeRatioField1 ); - CPPUNIT_TEST( testFillFromAnalytic3 ); - CPPUNIT_TEST( testFieldDoubleOpEqual1 ); - CPPUNIT_TEST( testAreaBary3D2 ); - CPPUNIT_TEST_SUITE_END(); - public: - void testGaussPointField1(); - void testGaussPointNEField1(); - void testCellOrientation1(); - void testCellOrientation2(); - void testCellOrientation3(); - void testPolyhedronBarycenter(); - void testNormL12Integ1D(); - void testAreaBary2D(); - void testAreaBary3D(); - void testRenumberCellsForFields(); - void testRenumberNodesForFields(); - void testConvertQuadraticCellsToLinear(); - void testCheckGeoEquivalWith(); - void testCheckGeoEquivalWith2(); - void testCopyTinyStringsFromOnFields(); - void testTryToShareSameCoordsPermute(); - void testTryToShareSameCoordsPermute2(); - void testChangeUnderlyingMesh1(); - void testGetMaxValue1(); - void testSubstractInPlaceDM1(); - void testDotCrossProduct1(); - void testMinMaxFields1(); - void testApplyLin1(); - void testGetIdsInRange1(); - void testBuildSubPart1(); - void testDoublyContractedProduct1(); - void testDeterminant1(); - void testEigenValues1(); - void testEigenVectors1(); - void testInverse1(); - void testTrace1(); - void testDeviator1(); - void testMagnitude1(); - void testMaxPerTuple1(); - void testChangeNbOfComponents(); - void testSortPerTuple1(); - void testIsEqualWithoutConsideringStr1(); - void testGetNodeIdsOfCell1(); - void testGetEdgeRatioField1(); - void testFillFromAnalytic3(); - void testFieldDoubleOpEqual1(); - void testAreaBary3D2(); - }; -} - -#endif diff --git a/src/MEDCoupling/Test/MEDCouplingBasicsTest3.cxx b/src/MEDCoupling/Test/MEDCouplingBasicsTest3.cxx deleted file mode 100644 index 358d1c4a1..000000000 --- a/src/MEDCoupling/Test/MEDCouplingBasicsTest3.cxx +++ /dev/null @@ -1,2467 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 -// 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 "MEDCouplingBasicsTest3.hxx" -#include "MEDCouplingUMesh.hxx" -#include "MEDCouplingCMesh.hxx" -#include "MEDCouplingExtrudedMesh.hxx" -#include "MEDCouplingFieldDouble.hxx" -#include "MEDCouplingMemArray.hxx" -#include "MEDCouplingGaussLocalization.hxx" - -#include -#include -#include - -using namespace ParaMEDMEM; - -void MEDCouplingBasicsTest3::testGetMeasureFieldCMesh1() -{ - MEDCouplingCMesh *m=MEDCouplingCMesh::New(); - DataArrayDouble *da=DataArrayDouble::New(); - const double discX[4]={2.3,3.4,5.8,10.2}; - const double discY[3]={12.3,23.4,45.8}; - const double discZ[5]={-0.7,1.2,1.25,2.13,2.67}; - da->alloc(4,1); - std::copy(discX,discX+4,da->getPointer()); - m->setCoordsAt(0,da); - da->decrRef(); - m->checkCoherency(); - CPPUNIT_ASSERT_EQUAL(4,m->getNumberOfNodes()); - CPPUNIT_ASSERT_EQUAL(3,m->getNumberOfCells()); - CPPUNIT_ASSERT_EQUAL(1,m->getSpaceDimension()); - MEDCouplingFieldDouble *f=m->getMeasureField(true); - CPPUNIT_ASSERT_EQUAL(3,f->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(1,f->getNumberOfComponents()); - const double expected1[3]={1.1,2.4,4.4}; - for(int i=0;i<3;i++) - CPPUNIT_ASSERT_DOUBLES_EQUAL(expected1[i],f->getIJ(i,0),1e-12); - f->decrRef(); - DataArrayDouble *coords=m->getCoordinatesAndOwner(); - CPPUNIT_ASSERT_EQUAL(4,coords->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(1,coords->getNumberOfComponents()); - for(int i=0;i<4;i++) - CPPUNIT_ASSERT_DOUBLES_EQUAL(discX[i],coords->getIJ(i,0),1e-12); - coords->decrRef(); - coords=m->getBarycenterAndOwner(); - CPPUNIT_ASSERT_EQUAL(3,coords->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(1,coords->getNumberOfComponents()); - const double expected1_3[3]={2.85,4.6,8.}; - for(int i=0;i<3;i++) - CPPUNIT_ASSERT_DOUBLES_EQUAL(expected1_3[i],coords->getIJ(i,0),1e-12); - coords->decrRef(); - // - da=DataArrayDouble::New(); - da->alloc(3,1); - std::copy(discY,discY+3,da->getPointer()); - m->setCoordsAt(1,da); - da->decrRef(); - m->checkCoherency(); - CPPUNIT_ASSERT_EQUAL(12,m->getNumberOfNodes()); - CPPUNIT_ASSERT_EQUAL(6,m->getNumberOfCells()); - CPPUNIT_ASSERT_EQUAL(2,m->getSpaceDimension()); - f=m->getMeasureField(true); - CPPUNIT_ASSERT_EQUAL(6,f->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(1,f->getNumberOfComponents()); - const double expected2[6]={12.21,26.64,48.84,24.64,53.76,98.56}; - for(int i=0;i<6;i++) - CPPUNIT_ASSERT_DOUBLES_EQUAL(expected2[i],f->getIJ(i,0),1e-12); - f->decrRef(); - coords=m->getCoordinatesAndOwner(); - CPPUNIT_ASSERT_EQUAL(12,coords->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(2,coords->getNumberOfComponents()); - const double expected2_2[24]={2.3,12.3,3.4,12.3,5.8,12.3,10.2,12.3, 2.3,23.4,3.4,23.4,5.8,23.4,10.2,23.4, 2.3,45.8,3.4,45.8,5.8,45.8,10.2,45.8}; - for(int i=0;i<24;i++) - CPPUNIT_ASSERT_DOUBLES_EQUAL(expected2_2[i],coords->getIJ(0,i),1e-12); - coords->decrRef(); - coords=m->getBarycenterAndOwner(); - CPPUNIT_ASSERT_EQUAL(6,coords->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(2,coords->getNumberOfComponents()); - const double expected2_3[12]={2.85,17.85,4.6,17.85,8.,17.85, 2.85,34.6,4.6,34.6,8.,34.6}; - for(int i=0;i<12;i++) - CPPUNIT_ASSERT_DOUBLES_EQUAL(expected2_3[i],coords->getIJ(0,i),1e-12); - coords->decrRef(); - // - da=DataArrayDouble::New(); - da->alloc(5,1); - std::copy(discZ,discZ+5,da->getPointer()); - m->setCoordsAt(2,da); - da->decrRef(); - m->checkCoherency(); - CPPUNIT_ASSERT_EQUAL(60,m->getNumberOfNodes()); - CPPUNIT_ASSERT_EQUAL(24,m->getNumberOfCells()); - CPPUNIT_ASSERT_EQUAL(3,m->getSpaceDimension()); - f=m->getMeasureField(true); - CPPUNIT_ASSERT_EQUAL(24,f->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(1,f->getNumberOfComponents()); - const double expected3[24]={23.199, 50.616, 92.796, 46.816, 102.144, 187.264, 0.6105, 1.332, 2.442, 1.232, 2.688, 4.928, 10.7448, 23.4432, 42.9792, 21.6832, 47.3088, 86.7328, 6.5934, 14.3856, 26.3736, 13.3056, 29.0304, 53.2224}; - for(int i=0;i<24;i++) - CPPUNIT_ASSERT_DOUBLES_EQUAL(expected3[i],f->getIJ(i,0),1e-12); - f->decrRef(); - coords=m->getCoordinatesAndOwner(); - CPPUNIT_ASSERT_EQUAL(60,coords->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(3,coords->getNumberOfComponents()); - const double expected3_2[180]={ - 2.3,12.3,-0.7, 3.4,12.3,-0.7, 5.8,12.3,-0.7, 10.2,12.3,-0.7, 2.3,23.4,-0.7, 3.4,23.4,-0.7, 5.8,23.4,-0.7, 10.2,23.4,-0.7, 2.3,45.8,-0.7, 3.4,45.8,-0.7, 5.8,45.8,-0.7, 10.2,45.8,-0.7, - 2.3,12.3,1.2, 3.4,12.3,1.2, 5.8,12.3,1.2, 10.2,12.3,1.2, 2.3,23.4,1.2, 3.4,23.4,1.2, 5.8,23.4,1.2, 10.2,23.4,1.2, 2.3,45.8,1.2, 3.4,45.8,1.2, 5.8,45.8,1.2, 10.2,45.8,1.2, - 2.3,12.3,1.25, 3.4,12.3,1.25, 5.8,12.3,1.25, 10.2,12.3,1.25, 2.3,23.4,1.25, 3.4,23.4,1.25, 5.8,23.4,1.25, 10.2,23.4,1.25, 2.3,45.8,1.25, 3.4,45.8,1.25, 5.8,45.8,1.25, 10.2,45.8,1.25, - 2.3,12.3,2.13, 3.4,12.3,2.13, 5.8,12.3,2.13, 10.2,12.3,2.13, 2.3,23.4,2.13, 3.4,23.4,2.13, 5.8,23.4,2.13, 10.2,23.4,2.13, 2.3,45.8,2.13, 3.4,45.8,2.13, 5.8,45.8,2.13, 10.2,45.8,2.13, - 2.3,12.3,2.67, 3.4,12.3,2.67, 5.8,12.3,2.67, 10.2,12.3,2.67, 2.3,23.4,2.67, 3.4,23.4,2.67, 5.8,23.4,2.67, 10.2,23.4,2.67, 2.3,45.8,2.67, 3.4,45.8,2.67, 5.8,45.8,2.67, 10.2,45.8,2.67 - }; - for(int i=0;i<180;i++) - CPPUNIT_ASSERT_DOUBLES_EQUAL(expected3_2[i],coords->getIJ(0,i),1e-12); - coords->decrRef(); - coords=m->getBarycenterAndOwner(); - CPPUNIT_ASSERT_EQUAL(24,coords->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(3,coords->getNumberOfComponents()); - const double expected3_3[72]={ - 2.85,17.85,0.25,4.6,17.85,0.25,8.,17.85,0.25, 2.85,34.6,0.25,4.6,34.6,0.25,8.,34.6,0.25, - 2.85,17.85,1.225,4.6,17.85,1.225,8.,17.85,1.225, 2.85,34.6,1.225,4.6,34.6,1.225,8.,34.6,1.225, - 2.85,17.85,1.69,4.6,17.85,1.69,8.,17.85,1.69, 2.85,34.6,1.69,4.6,34.6,1.69,8.,34.6,1.69, - 2.85,17.85,2.4,4.6,17.85,2.4,8.,17.85,2.4, 2.85,34.6,2.4,4.6,34.6,2.4,8.,34.6,2.4 - }; - for(int i=0;i<72;i++) - CPPUNIT_ASSERT_DOUBLES_EQUAL(expected3_3[i],coords->getIJ(0,i),1e-12); - coords->decrRef(); - // - m->decrRef(); -} - -void MEDCouplingBasicsTest3::testFieldDoubleZipCoords1() -{ - MEDCouplingUMesh *m=build2DTargetMeshMergeNode_1(); - MEDCouplingFieldDouble *f=m->fillFromAnalytic(ON_NODES,2,"x*2."); - f->getArray()->setInfoOnComponent(0,"titi"); - f->getArray()->setInfoOnComponent(1,"tutu"); - f->checkCoherency(); - CPPUNIT_ASSERT_EQUAL(18,f->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(2,f->getNumberOfComponents()); - const double expected1[36]={-0.6, -0.6, 0.4, 0.4, 1.4, 1.4, -0.6, -0.6, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 1.4, 1.4, -0.6, -0.6, 0.4, 0.4, 1.4, 1.4, -0.6, -0.6, 1.4, 1.4, -0.6, -0.6, 0.4, 0.4, 1.4, 1.4, 0.4, 0.4}; - for(int i=0;i<36;i++) - CPPUNIT_ASSERT_DOUBLES_EQUAL(expected1[i],f->getIJ(0,i),1e-12); - CPPUNIT_ASSERT(f->zipCoords()); - f->checkCoherency(); - const double expected2[30]={-0.6, -0.6, 1.4, 1.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 1.4, 1.4, -0.6, -0.6, 0.4, 0.4, 1.4, 1.4, 1.4, 1.4, -0.6, -0.6, 0.4, 0.4, 1.4, 1.4, 0.4, 0.4}; - for(int i=0;i<30;i++) - CPPUNIT_ASSERT_DOUBLES_EQUAL(expected2[i],f->getIJ(0,i),1e-12); - CPPUNIT_ASSERT(!f->zipCoords()); - f->checkCoherency(); - for(int i=0;i<30;i++) - CPPUNIT_ASSERT_DOUBLES_EQUAL(expected2[i],f->getIJ(0,i),1e-12); - CPPUNIT_ASSERT(std::string(f->getArray()->getInfoOnComponent(0))=="titi"); - CPPUNIT_ASSERT(std::string(f->getArray()->getInfoOnComponent(1))=="tutu"); - f->decrRef(); - m->decrRef(); -} - -void MEDCouplingBasicsTest3::testFieldDoubleZipConnectivity1() -{ - MEDCouplingUMesh *m1=build2DTargetMesh_1(); - MEDCouplingUMesh *m2=build2DTargetMesh_1(); - const int cells1[3]={2,3,4}; - MEDCouplingPointSet *m3_1=m2->buildPartOfMySelf(cells1,cells1+3,true); - MEDCouplingUMesh *m3=dynamic_cast(m3_1); - CPPUNIT_ASSERT(m3); - m2->decrRef(); - MEDCouplingUMesh *m4=build2DSourceMesh_1(); - MEDCouplingUMesh *m5=MEDCouplingUMesh::MergeUMeshes(m1,m3); - m1->decrRef(); - m3->decrRef(); - MEDCouplingUMesh *m6=MEDCouplingUMesh::MergeUMeshes(m5,m4); - m4->decrRef(); - m5->decrRef(); - // - CPPUNIT_ASSERT_EQUAL(10,m6->getNumberOfCells()); - CPPUNIT_ASSERT_EQUAL(22,m6->getNumberOfNodes()); - bool areNodesMerged; - int newNbOfNodes; - DataArrayInt *arr=m6->mergeNodes(1e-13,areNodesMerged,newNbOfNodes); - CPPUNIT_ASSERT_EQUAL(9,m6->getNumberOfNodes()); - arr->decrRef(); - MEDCouplingFieldDouble *f=m6->fillFromAnalytic(ON_CELLS,2,"x"); - MEDCouplingFieldDouble *f2=m6->fillFromAnalytic(ON_NODES,2,"x"); - CPPUNIT_ASSERT_EQUAL(10,f->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(2,f->getNumberOfComponents()); - const double expected1[20]={-0.05, -0.05, 0.3666666666666667, 0.3666666666666667, 0.53333333333333321, 0.53333333333333321, - -0.05, -0.05, 0.45, 0.45, 0.53333333333333321, 0.53333333333333321, -0.05, -0.05, 0.45, 0.45, - 0.36666666666666659, 0.36666666666666659, 0.033333333333333326, 0.033333333333333326}; - for(int i=0;i<20;i++) - CPPUNIT_ASSERT_DOUBLES_EQUAL(expected1[i],f->getIJ(0,i),1e-12); - f->getArray()->setInfoOnComponent(0,"titi"); - f->getArray()->setInfoOnComponent(1,"tutu"); - f->checkCoherency(); - CPPUNIT_ASSERT(f->zipConnectivity(0)); - const double expected2[14]={-0.05, -0.05, 0.3666666666666667, 0.3666666666666667, 0.53333333333333321, 0.53333333333333321, - -0.05, -0.05, 0.45, 0.45, 0.36666666666666659, 0.36666666666666659, 0.033333333333333326, 0.033333333333333326}; - CPPUNIT_ASSERT_EQUAL(7,f->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(2,f->getNumberOfComponents()); - for(int i=0;i<14;i++) - CPPUNIT_ASSERT_DOUBLES_EQUAL(expected2[i],f->getIJ(0,i),1e-12); - CPPUNIT_ASSERT(std::string(f->getArray()->getInfoOnComponent(0))=="titi"); - CPPUNIT_ASSERT(std::string(f->getArray()->getInfoOnComponent(1))=="tutu"); - CPPUNIT_ASSERT(!f->zipConnectivity(0)); - f->decrRef(); - // - const double expected3[18]={-0.3, -0.3, 0.2, 0.2, 0.7, 0.7, -0.3, -0.3, 0.2, 0.2, 0.7, 0.7, - -0.3, -0.3, 0.2, 0.2, 0.7, 0.7}; - CPPUNIT_ASSERT_EQUAL(9,f2->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(2,f2->getNumberOfComponents()); - for(int i=0;i<18;i++) - CPPUNIT_ASSERT_DOUBLES_EQUAL(expected3[i],f2->getIJ(0,i),1e-12); - CPPUNIT_ASSERT(f2->zipConnectivity(0)); - CPPUNIT_ASSERT_EQUAL(9,f2->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(2,f2->getNumberOfComponents()); - for(int i=0;i<18;i++) - CPPUNIT_ASSERT_DOUBLES_EQUAL(expected3[i],f2->getIJ(0,i),1e-12); - f2->decrRef(); - // - m6->decrRef(); -} - -void MEDCouplingBasicsTest3::testDaDoubleRenumber1() -{ - DataArrayDouble *a=DataArrayDouble::New(); - a->alloc(7,2); - a->setInfoOnComponent(0,"toto"); - a->setInfoOnComponent(1,"tata"); - const double arr1[14]={1.1,11.1,2.1,12.1,3.1,13.1,4.1,14.1,5.1,15.1,6.1,16.1,7.1,17.1}; - std::copy(arr1,arr1+14,a->getPointer()); - // - const int arr2[7]={3,1,0,6,5,4,2}; - DataArrayDouble *b=a->renumber(arr2); - CPPUNIT_ASSERT_EQUAL(7,b->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(2,b->getNumberOfComponents()); - CPPUNIT_ASSERT(std::string(b->getInfoOnComponent(0))=="toto"); - CPPUNIT_ASSERT(std::string(b->getInfoOnComponent(1))=="tata"); - const double expected1[14]={3.1, 13.1, 2.1, 12.1, 7.1, 17.1, 1.1, 11.1, 6.1, 16.1, 5.1, 15.1, 4.1, 14.1}; - for(int i=0;i<14;i++) - CPPUNIT_ASSERT_DOUBLES_EQUAL(expected1[i],b->getIJ(0,i),1e-14); - b->decrRef(); - a->decrRef(); - // - DataArrayInt *c=DataArrayInt::New(); - c->alloc(7,2); - c->setInfoOnComponent(0,"toto"); - c->setInfoOnComponent(1,"tata"); - const int arr3[14]={1,11,2,12,3,13,4,14,5,15,6,16,7,17}; - std::copy(arr3,arr3+14,c->getPointer()); - DataArrayInt *d=c->renumber(arr2); - CPPUNIT_ASSERT_EQUAL(7,d->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(2,d->getNumberOfComponents()); - CPPUNIT_ASSERT(std::string(d->getInfoOnComponent(0))=="toto"); - CPPUNIT_ASSERT(std::string(d->getInfoOnComponent(1))=="tata"); - const int expected2[14]={3, 13, 2, 12, 7, 17, 1, 11, 6, 16, 5, 15, 4, 14}; - for(int i=0;i<14;i++) - CPPUNIT_ASSERT_EQUAL(expected2[i],d->getIJ(0,i)); - c->decrRef(); - d->decrRef(); -} - -void MEDCouplingBasicsTest3::testDaDoubleRenumberAndReduce1() -{ - DataArrayDouble *a=DataArrayDouble::New(); - a->alloc(7,2); - a->setInfoOnComponent(0,"toto"); - a->setInfoOnComponent(1,"tata"); - const double arr1[14]={1.1,11.1,2.1,12.1,3.1,13.1,4.1,14.1,5.1,15.1,6.1,16.1,7.1,17.1}; - std::copy(arr1,arr1+14,a->getPointer()); - // - const int arr2[7]={2,-1,1,-1,0,4,3}; - DataArrayDouble *b=a->renumberAndReduce(arr2,5); - CPPUNIT_ASSERT_EQUAL(5,b->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(2,b->getNumberOfComponents()); - CPPUNIT_ASSERT(std::string(b->getInfoOnComponent(0))=="toto"); - CPPUNIT_ASSERT(std::string(b->getInfoOnComponent(1))=="tata"); - const double expected1[10]={5.1,15.1,3.1,13.1,1.1,11.1,7.1,17.1,6.1,16.1}; - for(int i=0;i<10;i++) - CPPUNIT_ASSERT_DOUBLES_EQUAL(expected1[i],b->getIJ(0,i),1e-14); - b->decrRef(); - a->decrRef(); - // - DataArrayInt *c=DataArrayInt::New(); - c->alloc(7,2); - c->setInfoOnComponent(0,"toto"); - c->setInfoOnComponent(1,"tata"); - const int arr3[14]={1,11,2,12,3,13,4,14,5,15,6,16,7,17}; - std::copy(arr3,arr3+14,c->getPointer()); - DataArrayInt *d=c->renumberAndReduce(arr2,5); - CPPUNIT_ASSERT_EQUAL(5,d->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(2,d->getNumberOfComponents()); - CPPUNIT_ASSERT(std::string(d->getInfoOnComponent(0))=="toto"); - CPPUNIT_ASSERT(std::string(d->getInfoOnComponent(1))=="tata"); - const int expected2[10]={5,15,3,13,1,11,7,17,6,16}; - for(int i=0;i<10;i++) - CPPUNIT_ASSERT_EQUAL(expected2[i],d->getIJ(0,i)); - c->decrRef(); - d->decrRef(); -} - -void MEDCouplingBasicsTest3::testDaDoubleRenumberInPlace1() -{ - DataArrayDouble *a=DataArrayDouble::New(); - a->alloc(7,2); - const double arr1[14]={1.1,11.1,2.1,12.1,3.1,13.1,4.1,14.1,5.1,15.1,6.1,16.1,7.1,17.1}; - std::copy(arr1,arr1+14,a->getPointer()); - // - const int arr2[7]={3,1,0,6,5,4,2}; - a->renumberInPlace(arr2); - CPPUNIT_ASSERT_EQUAL(7,a->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(2,a->getNumberOfComponents()); - const double expected1[14]={3.1, 13.1, 2.1, 12.1, 7.1, 17.1, 1.1, 11.1, 6.1, 16.1, 5.1, 15.1, 4.1, 14.1}; - for(int i=0;i<14;i++) - CPPUNIT_ASSERT_DOUBLES_EQUAL(expected1[i],a->getIJ(0,i),1e-14); - a->decrRef(); - // - DataArrayInt *c=DataArrayInt::New(); - c->alloc(7,2); - const int arr3[14]={1,11,2,12,3,13,4,14,5,15,6,16,7,17}; - std::copy(arr3,arr3+14,c->getPointer()); - c->renumberInPlace(arr2); - CPPUNIT_ASSERT_EQUAL(7,c->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(2,c->getNumberOfComponents()); - const int expected2[14]={3, 13, 2, 12, 7, 17, 1, 11, 6, 16, 5, 15, 4, 14}; - for(int i=0;i<14;i++) - CPPUNIT_ASSERT_EQUAL(expected2[i],c->getIJ(0,i)); - c->decrRef(); -} - -void MEDCouplingBasicsTest3::testDaDoubleRenumberR1() -{ - DataArrayDouble *a=DataArrayDouble::New(); - a->alloc(7,2); - a->setInfoOnComponent(0,"toto"); - a->setInfoOnComponent(1,"tata"); - const double arr1[14]={1.1,11.1,2.1,12.1,3.1,13.1,4.1,14.1,5.1,15.1,6.1,16.1,7.1,17.1}; - std::copy(arr1,arr1+14,a->getPointer()); - // - const int arr2[7]={3,1,0,6,5,4,2}; - DataArrayDouble *b=a->renumberR(arr2); - CPPUNIT_ASSERT_EQUAL(7,b->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(2,b->getNumberOfComponents()); - CPPUNIT_ASSERT(std::string(b->getInfoOnComponent(0))=="toto"); - CPPUNIT_ASSERT(std::string(b->getInfoOnComponent(1))=="tata"); - const double expected1[14]={4.1, 14.1, 2.1, 12.1, 1.1, 11.1, 7.1, 17.1, 6.1, 16.1, 5.1, 15.1, 3.1, 13.1}; - for(int i=0;i<14;i++) - CPPUNIT_ASSERT_DOUBLES_EQUAL(expected1[i],b->getIJ(0,i),1e-14); - b->decrRef(); - a->decrRef(); - // - DataArrayInt *c=DataArrayInt::New(); - c->alloc(7,2); - c->setInfoOnComponent(0,"toto"); - c->setInfoOnComponent(1,"tata"); - const int arr3[14]={1,11,2,12,3,13,4,14,5,15,6,16,7,17}; - std::copy(arr3,arr3+14,c->getPointer()); - DataArrayInt *d=c->renumberR(arr2); - CPPUNIT_ASSERT_EQUAL(7,d->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(2,d->getNumberOfComponents()); - CPPUNIT_ASSERT(std::string(d->getInfoOnComponent(0))=="toto"); - CPPUNIT_ASSERT(std::string(d->getInfoOnComponent(1))=="tata"); - const int expected2[14]={4, 14, 2, 12, 1, 11, 7, 17, 6, 16, 5, 15, 3, 13}; - for(int i=0;i<14;i++) - CPPUNIT_ASSERT_EQUAL(expected2[i],d->getIJ(0,i)); - c->decrRef(); - d->decrRef(); -} - -void MEDCouplingBasicsTest3::testDaDoubleRenumberInPlaceR1() -{ - DataArrayDouble *a=DataArrayDouble::New(); - a->alloc(7,2); - const double arr1[14]={1.1,11.1,2.1,12.1,3.1,13.1,4.1,14.1,5.1,15.1,6.1,16.1,7.1,17.1}; - std::copy(arr1,arr1+14,a->getPointer()); - // - const int arr2[7]={3,1,0,6,5,4,2}; - a->renumberInPlaceR(arr2); - CPPUNIT_ASSERT_EQUAL(7,a->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(2,a->getNumberOfComponents()); - const double expected1[14]={4.1, 14.1, 2.1, 12.1, 1.1, 11.1, 7.1, 17.1, 6.1, 16.1, 5.1, 15.1, 3.1, 13.1}; - for(int i=0;i<14;i++) - CPPUNIT_ASSERT_DOUBLES_EQUAL(expected1[i],a->getIJ(0,i),1e-14); - a->decrRef(); - // - DataArrayInt *c=DataArrayInt::New(); - c->alloc(7,2); - const int arr3[14]={1,11,2,12,3,13,4,14,5,15,6,16,7,17}; - std::copy(arr3,arr3+14,c->getPointer()); - c->renumberInPlaceR(arr2); - CPPUNIT_ASSERT_EQUAL(7,c->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(2,c->getNumberOfComponents()); - const int expected2[14]={4, 14, 2, 12, 1, 11, 7, 17, 6, 16, 5, 15, 3, 13}; - for(int i=0;i<14;i++) - CPPUNIT_ASSERT_EQUAL(expected2[i],c->getIJ(0,i)); - c->decrRef(); -} - -void MEDCouplingBasicsTest3::testDaDoubleSelectByTupleId1() -{ - DataArrayDouble *a=DataArrayDouble::New(); - a->alloc(7,2); - a->setInfoOnComponent(0,"toto"); - a->setInfoOnComponent(1,"tata"); - const double arr1[14]={1.1,11.1,2.1,12.1,3.1,13.1,4.1,14.1,5.1,15.1,6.1,16.1,7.1,17.1}; - std::copy(arr1,arr1+14,a->getPointer()); - // - const int arr2[7]={4,2,0,6,5}; - DataArrayDouble *b=a->selectByTupleId(arr2,arr2+5); - CPPUNIT_ASSERT_EQUAL(5,b->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(2,b->getNumberOfComponents()); - CPPUNIT_ASSERT(std::string(b->getInfoOnComponent(0))=="toto"); - CPPUNIT_ASSERT(std::string(b->getInfoOnComponent(1))=="tata"); - const double expected1[10]={5.1,15.1,3.1,13.1,1.1,11.1,7.1,17.1,6.1,16.1}; - for(int i=0;i<10;i++) - CPPUNIT_ASSERT_DOUBLES_EQUAL(expected1[i],b->getIJ(0,i),1e-14); - b->decrRef(); - a->decrRef(); - // - DataArrayInt *c=DataArrayInt::New(); - c->alloc(7,2); - c->setInfoOnComponent(0,"toto"); - c->setInfoOnComponent(1,"tata"); - const int arr3[14]={1,11,2,12,3,13,4,14,5,15,6,16,7,17}; - std::copy(arr3,arr3+14,c->getPointer()); - DataArrayInt *d=c->selectByTupleId(arr2,arr2+5); - CPPUNIT_ASSERT_EQUAL(5,d->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(2,d->getNumberOfComponents()); - CPPUNIT_ASSERT(std::string(d->getInfoOnComponent(0))=="toto"); - CPPUNIT_ASSERT(std::string(d->getInfoOnComponent(1))=="tata"); - const int expected2[10]={5,15,3,13,1,11,7,17,6,16}; - for(int i=0;i<10;i++) - CPPUNIT_ASSERT_EQUAL(expected2[i],d->getIJ(0,i)); - c->decrRef(); - d->decrRef(); -} - -void MEDCouplingBasicsTest3::testDaDoubleGetMinMaxValues1() -{ - DataArrayDouble *a=DataArrayDouble::New(); - a->alloc(9,1); - const double arr1[9]={2.34,4.56,-6.77,4.55,4.56,2.24,2.34,1.02,4.56}; - std::copy(arr1,arr1+9,a->getPointer()); - int where; - double m=a->getMaxValue(where); - CPPUNIT_ASSERT_EQUAL(1,where); - CPPUNIT_ASSERT_DOUBLES_EQUAL(4.56,m,1e-12); - DataArrayInt *ws; - m=a->getMaxValue2(ws); - CPPUNIT_ASSERT_DOUBLES_EQUAL(4.56,m,1e-12); - CPPUNIT_ASSERT_EQUAL(3,ws->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(1,ws->getNumberOfComponents()); - const int expected1[3]={1,4,8}; - for(int i=0;i<3;i++) - CPPUNIT_ASSERT_EQUAL(expected1[i],ws->getIJ(i,0)); - ws->decrRef(); - a->decrRef(); - a=DataArrayDouble::New(); - const double arr2[9]={-2.34,-4.56,6.77,-4.55,-4.56,-2.24,-2.34,-1.02,-4.56}; - a->alloc(9,1); - std::copy(arr2,arr2+9,a->getPointer()); - where=-2; - m=a->getMinValue(where); - CPPUNIT_ASSERT_EQUAL(1,where); - CPPUNIT_ASSERT_DOUBLES_EQUAL(-4.56,m,1e-12); - m=a->getMinValue2(ws); - CPPUNIT_ASSERT_DOUBLES_EQUAL(-4.56,m,1e-12); - CPPUNIT_ASSERT_EQUAL(3,ws->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(1,ws->getNumberOfComponents()); - for(int i=0;i<3;i++) - CPPUNIT_ASSERT_EQUAL(expected1[i],ws->getIJ(i,0)); - ws->decrRef(); - a->decrRef(); -} - -void MEDCouplingBasicsTest3::testFieldDoubleGetMinMaxValues2() -{ - MEDCouplingUMesh *m1=0; - MEDCouplingUMesh *m2=build3DExtrudedUMesh_1(m1); - m1->decrRef(); - CPPUNIT_ASSERT_EQUAL(18,m2->getNumberOfCells()); - const double arr1[18]={8.71,4.53,-12.41,8.71,-8.71,8.7099,4.55,8.71,5.55,6.77,-1e-200,4.55,8.7099,0.,1.23,0.,2.22,8.71}; - MEDCouplingFieldDouble *f=MEDCouplingFieldDouble::New(ON_CELLS,NO_TIME); - DataArrayDouble *a=DataArrayDouble::New(); - a->alloc(18,1); - std::copy(arr1,arr1+18,a->getPointer()); - f->setArray(a); - a->decrRef(); - f->setMesh(m2); - // - f->checkCoherency(); - double m=f->getMaxValue(); - CPPUNIT_ASSERT_DOUBLES_EQUAL(8.71,m,1e-12); - DataArrayInt *ws; - m=f->getMaxValue2(ws); - CPPUNIT_ASSERT_DOUBLES_EQUAL(8.71,m,1e-12); - CPPUNIT_ASSERT_EQUAL(4,ws->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(1,ws->getNumberOfComponents()); - const int expected1[4]={0,3,7,17}; - for(int i=0;i<4;i++) - CPPUNIT_ASSERT_EQUAL(expected1[i],ws->getIJ(i,0)); - ws->decrRef(); - // - const double arr2[18]={-8.71,-4.53,12.41,-8.71,8.71,-8.7099,-4.55,-8.71,-5.55,-6.77,1e-200,-4.55,-8.7099,0.,-1.23,0.,-2.22,-8.71}; - std::copy(arr2,arr2+18,a->getPointer()); - f->checkCoherency(); - m=f->getMinValue(); - CPPUNIT_ASSERT_DOUBLES_EQUAL(-8.71,m,1e-12); - m=f->getMinValue2(ws); - CPPUNIT_ASSERT_DOUBLES_EQUAL(-8.71,m,1e-12); - CPPUNIT_ASSERT_EQUAL(4,ws->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(1,ws->getNumberOfComponents()); - for(int i=0;i<4;i++) - CPPUNIT_ASSERT_EQUAL(expected1[i],ws->getIJ(i,0)); - ws->decrRef(); - // - f->decrRef(); - m2->decrRef(); -} - -void MEDCouplingBasicsTest3::testBuildUnstructuredCMesh1() -{ - MEDCouplingCMesh *m=MEDCouplingCMesh::New(); - DataArrayDouble *da=DataArrayDouble::New(); - const double discX[4]={2.3,3.4,5.8,10.2}; - const double discY[3]={12.3,23.4,45.8}; - const double discZ[5]={-0.7,1.2,1.25,2.13,2.67}; - da->alloc(4,1); - std::copy(discX,discX+4,da->getPointer()); - m->setCoordsAt(0,da); - da->decrRef(); - m->checkCoherency(); - double pos=2.4; - CPPUNIT_ASSERT_EQUAL(0,m->getCellContainingPoint(&pos,1e-12)); - pos=3.7; - CPPUNIT_ASSERT_EQUAL(1,m->getCellContainingPoint(&pos,1e-12)); - pos=5.9; - CPPUNIT_ASSERT_EQUAL(2,m->getCellContainingPoint(&pos,1e-12)); - pos=10.3; - CPPUNIT_ASSERT_EQUAL(-1,m->getCellContainingPoint(&pos,1e-12)); - pos=1.3; - CPPUNIT_ASSERT_EQUAL(-1,m->getCellContainingPoint(&pos,1e-12)); - // - MEDCouplingUMesh *m2=m->buildUnstructured(); - m2->checkCoherency(); - MEDCouplingFieldDouble *f1=m->getMeasureField(false); - MEDCouplingFieldDouble *f2=m2->getMeasureField(false); - CPPUNIT_ASSERT_EQUAL(f1->getNumberOfTuples(),3); - CPPUNIT_ASSERT_EQUAL(f2->getNumberOfTuples(),3); - CPPUNIT_ASSERT_EQUAL(1,m2->getMeshDimension()); - CPPUNIT_ASSERT_EQUAL(1,m2->getSpaceDimension()); - for(int i=0;i<3;i++) - CPPUNIT_ASSERT_DOUBLES_EQUAL(f1->getIJ(i,0),f2->getIJ(i,0),1e-10); - da=DataArrayDouble::New(); - da->alloc(3,1); - std::copy(discY,discY+3,da->getPointer()); - m->setCoordsAt(1,da); - da->decrRef(); - m2->decrRef(); - f1->decrRef(); - f2->decrRef(); - // - m2=m->buildUnstructured(); - m2->checkCoherency(); - f1=m->getMeasureField(false); - f2=m2->getMeasureField(false); - CPPUNIT_ASSERT_EQUAL(f1->getNumberOfTuples(),6); - CPPUNIT_ASSERT_EQUAL(f2->getNumberOfTuples(),6); - CPPUNIT_ASSERT_EQUAL(2,m2->getMeshDimension()); - CPPUNIT_ASSERT_EQUAL(2,m2->getSpaceDimension()); - for(int i=0;i<6;i++) - CPPUNIT_ASSERT_DOUBLES_EQUAL(f1->getIJ(i,0),f2->getIJ(i,0),1e-10); - f1->decrRef(); - f2->decrRef(); - m2->decrRef(); - // - da=DataArrayDouble::New(); - da->alloc(5,1); - std::copy(discZ,discZ+5,da->getPointer()); - m->setCoordsAt(2,da); - da->decrRef(); - m2=m->buildUnstructured(); - m2->checkCoherency(); - f1=m->getMeasureField(false); - f2=m2->getMeasureField(false); - CPPUNIT_ASSERT_EQUAL(f1->getNumberOfTuples(),24); - CPPUNIT_ASSERT_EQUAL(f2->getNumberOfTuples(),24); - CPPUNIT_ASSERT_EQUAL(3,m2->getMeshDimension()); - CPPUNIT_ASSERT_EQUAL(3,m2->getSpaceDimension()); - for(int i=0;i<24;i++) - CPPUNIT_ASSERT_DOUBLES_EQUAL(f1->getIJ(i,0),f2->getIJ(i,0),1e-10); - f1->decrRef(); - f2->decrRef(); - // - double pos1[3]={5.,30.,2.}; - CPPUNIT_ASSERT_EQUAL(16,m->getCellContainingPoint(pos1,1e-12)); - // - const double pt[3]={2.4,12.7,-3.4}; - m->scale(pt,3.7); - MEDCouplingUMesh *m3=m->buildUnstructured(); - m2->scale(pt,3.7); - CPPUNIT_ASSERT(m3->isEqual(m2,1e-12)); - m2->decrRef(); - m3->decrRef(); - // - m->decrRef(); -} - -void MEDCouplingBasicsTest3::testDataArrayIntInvertO2NNO21() -{ - const int arr1[6]={2,0,4,1,5,3}; - DataArrayInt *da=DataArrayInt::New(); - da->alloc(6,1); - std::copy(arr1,arr1+6,da->getPointer()); - DataArrayInt *da2=da->invertArrayO2N2N2O(6); - CPPUNIT_ASSERT_EQUAL(6,da2->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(1,da2->getNumberOfComponents()); - const int expected1[6]={1,3,0,5,2,4}; - for(int i=0;i<6;i++) - CPPUNIT_ASSERT_EQUAL(expected1[i],da2->getIJ(i,0)); - DataArrayInt *da3=da2->invertArrayN2O2O2N(6); - for(int i=0;i<6;i++) - CPPUNIT_ASSERT_EQUAL(arr1[i],da3->getIJ(i,0)); - da3->decrRef(); - da2->decrRef(); - da->decrRef(); - // - const int arr2[10]={3,-1,5,4,-1,0,-1,1,2,-1}; - da=DataArrayInt::New(); - da->alloc(10,1); - std::copy(arr2,arr2+10,da->getPointer()); - da2=da->invertArrayO2N2N2O(6); - CPPUNIT_ASSERT_EQUAL(6,da2->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(1,da2->getNumberOfComponents()); - const int expected2[10]={5,7,8,0,3,2}; - for(int i=0;i<6;i++) - CPPUNIT_ASSERT_EQUAL(expected2[i],da2->getIJ(i,0)); - da3=da2->invertArrayN2O2O2N(10); - for(int i=0;i<10;i++) - CPPUNIT_ASSERT_EQUAL(arr2[i],da3->getIJ(i,0)); - da3->decrRef(); - da2->decrRef(); - da->decrRef(); -} - -void MEDCouplingBasicsTest3::testKeepSetSelectedComponent1() -{ - const double arr1[20]={1.,2.,3.,4., 11.,12.,13.,14., 21.,22.,23.,24., 31.,32.,33.,34., 41.,42.,43.,44.}; - DataArrayDouble *a1=DataArrayDouble::New(); - a1->alloc(5,4); - std::copy(arr1,arr1+20,a1->getPointer()); - a1->setInfoOnComponent(0,"aaaa"); - a1->setInfoOnComponent(1,"bbbb"); - a1->setInfoOnComponent(2,"cccc"); - a1->setInfoOnComponent(3,"dddd"); - const int arr2[6]={1,2,1,2,0,0}; - std::vector arr2V(arr2,arr2+6); - DataArrayDouble *a2=static_cast(a1->keepSelectedComponents(arr2V)); - CPPUNIT_ASSERT_EQUAL(6,a2->getNumberOfComponents()); - CPPUNIT_ASSERT_EQUAL(5,a2->getNumberOfTuples()); - CPPUNIT_ASSERT(std::string(a2->getInfoOnComponent(0))=="bbbb"); - CPPUNIT_ASSERT(std::string(a2->getInfoOnComponent(1))=="cccc"); - CPPUNIT_ASSERT(std::string(a2->getInfoOnComponent(2))=="bbbb"); - CPPUNIT_ASSERT(std::string(a2->getInfoOnComponent(3))=="cccc"); - CPPUNIT_ASSERT(std::string(a2->getInfoOnComponent(4))=="aaaa"); - CPPUNIT_ASSERT(std::string(a2->getInfoOnComponent(5))=="aaaa"); - const double expected1[30]={2.,3.,2.,3.,1.,1., 12.,13.,12.,13.,11.,11., 22.,23.,22.,23.,21.,21., 32.,33.,32.,33.,31.,31., 42.,43.,42.,43.,41.,41.}; - for(int i=0;i<30;i++) - CPPUNIT_ASSERT_DOUBLES_EQUAL(expected1[i],a2->getIJ(0,i),1e-14); - DataArrayInt *a3=a1->convertToIntArr(); - DataArrayInt *a4=static_cast(a3->keepSelectedComponents(arr2V)); - CPPUNIT_ASSERT_EQUAL(6,a4->getNumberOfComponents()); - CPPUNIT_ASSERT_EQUAL(5,a4->getNumberOfTuples()); - CPPUNIT_ASSERT(std::string(a4->getInfoOnComponent(0))=="bbbb"); - CPPUNIT_ASSERT(std::string(a4->getInfoOnComponent(1))=="cccc"); - CPPUNIT_ASSERT(std::string(a4->getInfoOnComponent(2))=="bbbb"); - CPPUNIT_ASSERT(std::string(a4->getInfoOnComponent(3))=="cccc"); - CPPUNIT_ASSERT(std::string(a4->getInfoOnComponent(4))=="aaaa"); - CPPUNIT_ASSERT(std::string(a4->getInfoOnComponent(5))=="aaaa"); - for(int i=0;i<30;i++) - CPPUNIT_ASSERT_EQUAL(int(expected1[i]),a4->getIJ(0,i)); - // setSelectedComponents - const int arr3[2]={3,2}; - std::vector arr3V(arr3,arr3+2); - DataArrayDouble *a5=static_cast(a1->keepSelectedComponents(arr3V)); - a5->setInfoOnComponent(0,"eeee"); - a5->setInfoOnComponent(1,"ffff"); - const int arr4[2]={1,2}; - std::vector arr4V(arr4,arr4+2); - a2->setSelectedComponents(a5,arr4V); - CPPUNIT_ASSERT_EQUAL(6,a2->getNumberOfComponents()); - CPPUNIT_ASSERT_EQUAL(5,a2->getNumberOfTuples()); - CPPUNIT_ASSERT(std::string(a2->getInfoOnComponent(0))=="bbbb"); - CPPUNIT_ASSERT(std::string(a2->getInfoOnComponent(1))=="eeee"); - CPPUNIT_ASSERT(std::string(a2->getInfoOnComponent(2))=="ffff"); - CPPUNIT_ASSERT(std::string(a2->getInfoOnComponent(3))=="cccc"); - CPPUNIT_ASSERT(std::string(a2->getInfoOnComponent(4))=="aaaa"); - CPPUNIT_ASSERT(std::string(a2->getInfoOnComponent(5))=="aaaa"); - const double expected2[30]={2.,4.,3.,3.,1.,1., 12.,14.,13.,13.,11.,11., 22.,24.,23.,23.,21.,21., 32.,34.,33.,33.,31.,31., 42.,44.,43.,43.,41.,41.}; - for(int i=0;i<30;i++) - CPPUNIT_ASSERT_DOUBLES_EQUAL(expected2[i],a2->getIJ(0,i),1e-14); - DataArrayInt *a6=a5->convertToIntArr(); - a6->setInfoOnComponent(0,"eeee"); - a6->setInfoOnComponent(1,"ffff"); - a4->setSelectedComponents(a6,arr4V); - CPPUNIT_ASSERT_EQUAL(6,a4->getNumberOfComponents()); - CPPUNIT_ASSERT_EQUAL(5,a4->getNumberOfTuples()); - CPPUNIT_ASSERT(std::string(a4->getInfoOnComponent(0))=="bbbb"); - CPPUNIT_ASSERT(std::string(a4->getInfoOnComponent(1))=="eeee"); - CPPUNIT_ASSERT(std::string(a4->getInfoOnComponent(2))=="ffff"); - CPPUNIT_ASSERT(std::string(a4->getInfoOnComponent(3))=="cccc"); - CPPUNIT_ASSERT(std::string(a4->getInfoOnComponent(4))=="aaaa"); - CPPUNIT_ASSERT(std::string(a4->getInfoOnComponent(5))=="aaaa"); - for(int i=0;i<30;i++) - CPPUNIT_ASSERT_EQUAL(int(expected2[i]),a4->getIJ(0,i)); - // test of throw - const int arr5[3]={2,3,6}; - const int arr6[3]={2,7,5}; - const int arr7[4]={2,1,4,6}; - std::vector arr5V(arr5,arr5+3); - std::vector arr6V(arr6,arr6+3); - std::vector arr7V(arr7,arr7+4); - CPPUNIT_ASSERT_THROW(a2->keepSelectedComponents(arr5V),INTERP_KERNEL::Exception); - CPPUNIT_ASSERT_THROW(a2->keepSelectedComponents(arr6V),INTERP_KERNEL::Exception); - CPPUNIT_ASSERT_THROW(a2->setSelectedComponents(a1,arr7V),INTERP_KERNEL::Exception); - arr7V.resize(3); - CPPUNIT_ASSERT_THROW(a2->setSelectedComponents(a1,arr7V),INTERP_KERNEL::Exception); - // - a6->decrRef(); - a5->decrRef(); - a4->decrRef(); - a3->decrRef(); - a2->decrRef(); - a1->decrRef(); -} - -void MEDCouplingBasicsTest3::testKeepSetSelectedComponent2() -{ - MEDCouplingUMesh *m1=build2DTargetMesh_1(); - const double arr1[20]={1.,2.,3.,4., 11.,12.,13.,14., 21.,22.,23.,24., 31.,32.,33.,34., 41.,42.,43.,44.}; - DataArrayDouble *a1=DataArrayDouble::New(); - a1->alloc(5,4); - std::copy(arr1,arr1+20,a1->getPointer()); - a1->setInfoOnComponent(0,"aaaa"); - a1->setInfoOnComponent(1,"bbbb"); - a1->setInfoOnComponent(2,"cccc"); - a1->setInfoOnComponent(3,"dddd"); - MEDCouplingFieldDouble *f1=MEDCouplingFieldDouble::New(ON_CELLS,ONE_TIME); - f1->setTime(2.3,4,5); - f1->setMesh(m1); - f1->setName("f1"); - f1->setArray(a1); - f1->checkCoherency(); - // - const int arr2[6]={1,2,1,2,0,0}; - std::vector arr2V(arr2,arr2+6); - MEDCouplingFieldDouble *f2=f1->keepSelectedComponents(arr2V); - CPPUNIT_ASSERT(f2->getMesh()==f1->getMesh()); - CPPUNIT_ASSERT(f2->getTimeDiscretization()==ONE_TIME); - int dt,it; - CPPUNIT_ASSERT_DOUBLES_EQUAL(2.3,f2->getTime(dt,it),1e-13); - CPPUNIT_ASSERT_EQUAL(4,dt); - CPPUNIT_ASSERT_EQUAL(5,it); - f2->checkCoherency(); - CPPUNIT_ASSERT_EQUAL(6,f2->getNumberOfComponents()); - CPPUNIT_ASSERT_EQUAL(5,f2->getNumberOfTuples()); - CPPUNIT_ASSERT(std::string(f2->getArray()->getInfoOnComponent(0))=="bbbb"); - CPPUNIT_ASSERT(std::string(f2->getArray()->getInfoOnComponent(1))=="cccc"); - CPPUNIT_ASSERT(std::string(f2->getArray()->getInfoOnComponent(2))=="bbbb"); - CPPUNIT_ASSERT(std::string(f2->getArray()->getInfoOnComponent(3))=="cccc"); - CPPUNIT_ASSERT(std::string(f2->getArray()->getInfoOnComponent(4))=="aaaa"); - CPPUNIT_ASSERT(std::string(f2->getArray()->getInfoOnComponent(5))=="aaaa"); - const double expected1[30]={2.,3.,2.,3.,1.,1., 12.,13.,12.,13.,11.,11., 22.,23.,22.,23.,21.,21., 32.,33.,32.,33.,31.,31., 42.,43.,42.,43.,41.,41.}; - for(int i=0;i<30;i++) - CPPUNIT_ASSERT_DOUBLES_EQUAL(expected1[i],f2->getIJ(0,i),1e-14); - //setSelectedComponents - const int arr3[2]={3,2}; - std::vector arr3V(arr3,arr3+2); - MEDCouplingFieldDouble *f5=f1->keepSelectedComponents(arr3V); - f5->setTime(6.7,8,9); - f5->getArray()->setInfoOnComponent(0,"eeee"); - f5->getArray()->setInfoOnComponent(1,"ffff"); - f5->checkCoherency(); - const int arr4[2]={1,2}; - std::vector arr4V(arr4,arr4+2); - f2->setSelectedComponents(f5,arr4V); - CPPUNIT_ASSERT_EQUAL(6,f2->getNumberOfComponents()); - CPPUNIT_ASSERT_EQUAL(5,f2->getNumberOfTuples()); - f2->checkCoherency(); - CPPUNIT_ASSERT_DOUBLES_EQUAL(2.3,f2->getTime(dt,it),1e-13); - CPPUNIT_ASSERT_EQUAL(4,dt); - CPPUNIT_ASSERT_EQUAL(5,it); - CPPUNIT_ASSERT(std::string(f2->getArray()->getInfoOnComponent(0))=="bbbb"); - CPPUNIT_ASSERT(std::string(f2->getArray()->getInfoOnComponent(1))=="eeee"); - CPPUNIT_ASSERT(std::string(f2->getArray()->getInfoOnComponent(2))=="ffff"); - CPPUNIT_ASSERT(std::string(f2->getArray()->getInfoOnComponent(3))=="cccc"); - CPPUNIT_ASSERT(std::string(f2->getArray()->getInfoOnComponent(4))=="aaaa"); - CPPUNIT_ASSERT(std::string(f2->getArray()->getInfoOnComponent(5))=="aaaa"); - const double expected2[30]={2.,4.,3.,3.,1.,1., 12.,14.,13.,13.,11.,11., 22.,24.,23.,23.,21.,21., 32.,34.,33.,33.,31.,31., 42.,44.,43.,43.,41.,41.}; - for(int i=0;i<30;i++) - CPPUNIT_ASSERT_DOUBLES_EQUAL(expected2[i],f2->getIJ(0,i),1e-14); - f5->decrRef(); - f1->decrRef(); - f2->decrRef(); - a1->decrRef(); - m1->decrRef(); -} - -void MEDCouplingBasicsTest3::testElementaryDAThrowAndSpecialCases() -{ - DataArrayInt *da=DataArrayInt::New(); - CPPUNIT_ASSERT_THROW(da->checkAllocated(),INTERP_KERNEL::Exception); - CPPUNIT_ASSERT_THROW(da->fillWithValue(1),INTERP_KERNEL::Exception); - CPPUNIT_ASSERT_THROW(da->iota(1),INTERP_KERNEL::Exception); - da->alloc(7,1); - da->fillWithValue(11); //11,11,11,11... - da->iota(10); //10,11,12,13... - - DataArrayInt *db=DataArrayInt::New(); - db->alloc(7,2); - - DataArrayDouble *dbl2=DataArrayDouble::New(); - dbl2->alloc(7,2); - CPPUNIT_ASSERT_THROW(dbl2->isUniform(10.,1e-15),INTERP_KERNEL::Exception); - CPPUNIT_ASSERT_THROW(dbl2->sort(),INTERP_KERNEL::Exception); - CPPUNIT_ASSERT_THROW(dbl2->iota(10.),INTERP_KERNEL::Exception); - - DataArrayDouble *dbl=DataArrayDouble::New(); - //DataArrayDouble not allocated yet - CPPUNIT_ASSERT_THROW(dbl->iota(10.),INTERP_KERNEL::Exception); - CPPUNIT_ASSERT_THROW(dbl->isUniform(10.,1e-15),INTERP_KERNEL::Exception); - CPPUNIT_ASSERT_THROW(dbl->sort(),INTERP_KERNEL::Exception); - CPPUNIT_ASSERT_THROW(dbl->reverse(),INTERP_KERNEL::Exception); - CPPUNIT_ASSERT_THROW(dbl->fromNoInterlace(),INTERP_KERNEL::Exception); - CPPUNIT_ASSERT_THROW(dbl->toNoInterlace(),INTERP_KERNEL::Exception); - - dbl->alloc(7,1); - dbl->iota(10.); - CPPUNIT_ASSERT(!dbl->isUniform(10.,1e-15)); - dbl->sort(); - CPPUNIT_ASSERT(dbl->isMonotonic(true, .99)); - CPPUNIT_ASSERT(dbl->isMonotonic(true, -.99)); - CPPUNIT_ASSERT(!dbl->isMonotonic(true, 1.1)); - CPPUNIT_ASSERT(!dbl->isMonotonic(true, -1.1)); - dbl->reverse(); - CPPUNIT_ASSERT(dbl->isMonotonic(false, .99)); - CPPUNIT_ASSERT(!dbl->isMonotonic(false, 1.1)); - CPPUNIT_ASSERT(!dbl->isMonotonic(false, -1.1)); - - DataArrayInt *dc=DataArrayInt::New(); - dc->alloc(14,1); - - DataArrayDouble *dd=DataArrayDouble::New(); - CPPUNIT_ASSERT_THROW(dd->checkAllocated(),INTERP_KERNEL::Exception); - CPPUNIT_ASSERT_THROW(dd->fillWithValue(1.),INTERP_KERNEL::Exception); - CPPUNIT_ASSERT_THROW(dd->iota(1.),INTERP_KERNEL::Exception); - CPPUNIT_ASSERT(!((dd->repr().find("No data"))==std::string::npos)); - - dd->alloc(0,1); //Allocated but nbOfElements==0! - CPPUNIT_ASSERT(!((dd->repr().find("Number of tuples : 0"))==std::string::npos)); - CPPUNIT_ASSERT(!((dd->repr().find("Empty Data"))==std::string::npos)); - dd->fillWithValue(11); //?!... - dd->iota(10); //?!... - CPPUNIT_ASSERT(dd->isMonotonic(true, 1.)); - CPPUNIT_ASSERT(dd->isMonotonic(false, 1.)); - - CPPUNIT_ASSERT_THROW(db->copyStringInfoFrom(*da),INTERP_KERNEL::Exception); - CPPUNIT_ASSERT_THROW(db->copyStringInfoFrom(*da),INTERP_KERNEL::Exception); - std::vector cIds(2,2); - CPPUNIT_ASSERT_THROW(da->copyPartOfStringInfoFrom(*db,cIds),INTERP_KERNEL::Exception); - cIds[0]=1; - cIds[0]=-1; - CPPUNIT_ASSERT_THROW(da->copyPartOfStringInfoFrom(*db,cIds),INTERP_KERNEL::Exception); - - std::vector info(2,"infoOfOneComponent"); - CPPUNIT_ASSERT_THROW(da->setInfoOnComponents(info),INTERP_KERNEL::Exception); - CPPUNIT_ASSERT_THROW(da->setInfoOnComponent(1,info[0].c_str()),INTERP_KERNEL::Exception); - db->setInfoOnComponents(info); - - CPPUNIT_ASSERT_THROW(da->getInfoOnComponent(-1),INTERP_KERNEL::Exception); - CPPUNIT_ASSERT_THROW(da->getInfoOnComponent(2),INTERP_KERNEL::Exception); - CPPUNIT_ASSERT(db->getInfoOnComponent(1)==db->getInfoOnComponent(0)); - CPPUNIT_ASSERT_THROW(db->getVarOnComponent(-1),INTERP_KERNEL::Exception); - CPPUNIT_ASSERT_THROW(db->getVarOnComponent(2),INTERP_KERNEL::Exception); - CPPUNIT_ASSERT_THROW(db->getUnitOnComponent(-1),INTERP_KERNEL::Exception); - CPPUNIT_ASSERT_THROW(db->getUnitOnComponent(2),INTERP_KERNEL::Exception); - - CPPUNIT_ASSERT(da->GetVarNameFromInfo(std::string("varname unit "))==std::string("varname unit ")); - CPPUNIT_ASSERT(da->GetVarNameFromInfo(std::string("varname]unit["))==std::string("varname]unit[")); - CPPUNIT_ASSERT(da->GetVarNameFromInfo(std::string("[unit]"))==std::string()); - CPPUNIT_ASSERT(da->GetVarNameFromInfo(std::string("varname [unit]"))==std::string("varname")); - - CPPUNIT_ASSERT(da->GetUnitFromInfo(std::string("varname unit "))==std::string()); - CPPUNIT_ASSERT(da->GetUnitFromInfo(std::string("varname]unit["))==std::string()); - CPPUNIT_ASSERT(da->GetUnitFromInfo(std::string("[unit]"))==std::string("unit")); - CPPUNIT_ASSERT(da->GetUnitFromInfo(std::string("varname [unit]"))==std::string("unit")); - - CPPUNIT_ASSERT_THROW(da->checkNbOfTuplesAndComp(*db,"theMessageInThrow"),INTERP_KERNEL::Exception); - CPPUNIT_ASSERT_THROW(da->checkNbOfTuplesAndComp(*dc,"theMessageInThrow"),INTERP_KERNEL::Exception); - CPPUNIT_ASSERT_THROW(db->checkNbOfTuplesAndComp(*dc,"theMessageInThrow"),INTERP_KERNEL::Exception); - - CPPUNIT_ASSERT_THROW(da->checkNbOfTuplesAndComp(7,2,"theMessageInThrow"),INTERP_KERNEL::Exception); - da->checkNbOfTuplesAndComp(7,1,"theMessageInThrow"); - - CPPUNIT_ASSERT_THROW(db->checkNbOfElems(7*2+1,"theMessageInThrow"),INTERP_KERNEL::Exception); - db->checkNbOfElems(7*2,"theMessageInThrow"); - - CPPUNIT_ASSERT_THROW(db->GetNumberOfItemGivenBES(10,9,1,"theMessageInThrow"),INTERP_KERNEL::Exception); - CPPUNIT_ASSERT_THROW(db->GetNumberOfItemGivenBES(0,1,-1,"theMessageInThrow"),INTERP_KERNEL::Exception); - CPPUNIT_ASSERT_EQUAL(10,db->GetNumberOfItemGivenBES(0,10,1,"theMessageInThrow")); - CPPUNIT_ASSERT_EQUAL(5,db->GetNumberOfItemGivenBES(0,10,2,"theMessageInThrow")); - CPPUNIT_ASSERT_EQUAL(6,db->GetNumberOfItemGivenBES(0,11,2,"theMessageInThrow")); - - //std::cout<<"\n!!!!!!!!!\n"<repr()<<"\n!!!!!!!!!\n"; - CPPUNIT_ASSERT(!((da->repr().find("Number of components : 1"))==std::string::npos)); - CPPUNIT_ASSERT(!((dd->repr().find("Number of components : 1"))==std::string::npos)); - CPPUNIT_ASSERT(!((dbl->repr().find("Number of components : 1"))==std::string::npos)); - - CPPUNIT_ASSERT(!((da->reprZip().find("Number of components : 1"))==std::string::npos)); - CPPUNIT_ASSERT(!((dd->reprZip().find("Number of components : 1"))==std::string::npos)); - CPPUNIT_ASSERT(!((dbl->reprZip().find("Number of components : 1"))==std::string::npos)); - - std::ostringstream ret; - dbl->writeVTK(ret,2,"file.tmp",0); - CPPUNIT_ASSERT(!((ret.str().find("selectByTupleId2(0,1,-1),INTERP_KERNEL::Exception); - CPPUNIT_ASSERT_THROW(dbl->substr(-1,1),INTERP_KERNEL::Exception); - CPPUNIT_ASSERT_THROW(dbl->substr(8,1),INTERP_KERNEL::Exception); - CPPUNIT_ASSERT_THROW(dbl->substr(0,8),INTERP_KERNEL::Exception); - CPPUNIT_ASSERT_THROW(dbl->meldWith(dd),INTERP_KERNEL::Exception); - - CPPUNIT_ASSERT_THROW(dbl->setPartOfValuesAdv(dbl2,da),INTERP_KERNEL::Exception); //dbl dbl2 not have the same number of components - CPPUNIT_ASSERT_THROW(dbl->setPartOfValuesAdv(dd,da),INTERP_KERNEL::Exception); //da tuple selector DataArrayInt instance not have exactly 2 components - - DataArrayDouble *dbl3=DataArrayDouble::New(); - dbl3->alloc(6,2); - dbl3->fillWithValue(11.); - int tupleId; - //bad number of components - CPPUNIT_ASSERT_THROW(dbl3->getMaxValue(tupleId),INTERP_KERNEL::Exception); - CPPUNIT_ASSERT_THROW(dd->getMaxValue(tupleId),INTERP_KERNEL::Exception); - CPPUNIT_ASSERT_THROW(dbl3->getMinValue(tupleId),INTERP_KERNEL::Exception); - CPPUNIT_ASSERT_THROW(dd->getMinValue(tupleId),INTERP_KERNEL::Exception); - CPPUNIT_ASSERT_THROW(dbl3->getAverageValue(),INTERP_KERNEL::Exception); - CPPUNIT_ASSERT_THROW(dd->getAverageValue(),INTERP_KERNEL::Exception); - CPPUNIT_ASSERT_THROW(dd->accumulate(100),INTERP_KERNEL::Exception); - CPPUNIT_ASSERT_THROW(dbl->fromPolarToCart(),INTERP_KERNEL::Exception); - CPPUNIT_ASSERT_THROW(dbl3->fromCylToCart(),INTERP_KERNEL::Exception); - CPPUNIT_ASSERT_THROW(dbl3->fromSpherToCart(),INTERP_KERNEL::Exception); - CPPUNIT_ASSERT_THROW(dbl3->doublyContractedProduct(),INTERP_KERNEL::Exception); - CPPUNIT_ASSERT_THROW(dbl3->determinant(),INTERP_KERNEL::Exception); - CPPUNIT_ASSERT_THROW(dbl3->eigenValues(),INTERP_KERNEL::Exception); - CPPUNIT_ASSERT_THROW(dbl3->eigenVectors(),INTERP_KERNEL::Exception); - CPPUNIT_ASSERT_THROW(dbl3->inverse(),INTERP_KERNEL::Exception); - CPPUNIT_ASSERT_THROW(dbl3->trace(),INTERP_KERNEL::Exception); - CPPUNIT_ASSERT_THROW(dbl3->deviator(),INTERP_KERNEL::Exception); - - dbl3->setIJ(5,1,12.); - CPPUNIT_ASSERT(dbl3->getMaxValueInArray()==12.); - CPPUNIT_ASSERT(dbl3->getMinValueInArray()==11.); - - db->fillWithValue(100); //bad Ids - CPPUNIT_ASSERT_THROW(dbl3->setPartOfValuesAdv(dbl2,db),INTERP_KERNEL::Exception); - db->fillWithValue(-1); //bad Ids - CPPUNIT_ASSERT_THROW(dbl3->setPartOfValuesAdv(dbl2,db),INTERP_KERNEL::Exception); - db->fillWithValue(6); //bad Ids for dbl3 - CPPUNIT_ASSERT_THROW(dbl3->setPartOfValuesAdv(dbl2,db),INTERP_KERNEL::Exception); - - DataArrayDouble::SetArrayIn(dbl,dbl3); //dbl->dbl3 memLeaks? - dbl3->checkNoNullValues(); - dbl3->setIJ(6,0,0.); - CPPUNIT_ASSERT_THROW(dbl3->checkNoNullValues(),INTERP_KERNEL::Exception); - CPPUNIT_ASSERT_THROW(dbl3->applyInv(1.),INTERP_KERNEL::Exception); //div by zero - CPPUNIT_ASSERT_THROW(dbl2->getIdsInRange(1.,2.),INTERP_KERNEL::Exception); - std::vector a(0); //input list must be NON EMPTY - CPPUNIT_ASSERT_THROW(DataArrayDouble::Aggregate(a),INTERP_KERNEL::Exception); - CPPUNIT_ASSERT_THROW(DataArrayDouble::Meld(a),INTERP_KERNEL::Exception); - - a.push_back(dbl2); - a.push_back(dbl); //Nb of components mismatch - CPPUNIT_ASSERT_THROW(DataArrayDouble::Aggregate(a),INTERP_KERNEL::Exception); - - CPPUNIT_ASSERT_THROW(DataArrayDouble::Dot(dbl2,dbl),INTERP_KERNEL::Exception); - - CPPUNIT_ASSERT_THROW(DataArrayDouble::CrossProduct(dbl2,dbl),INTERP_KERNEL::Exception); //Nb of components mismatch - CPPUNIT_ASSERT_THROW(DataArrayDouble::CrossProduct(dbl2,dbl2),INTERP_KERNEL::Exception); //Nb of components must be equal to 3 - DataArrayDouble *dbl4=DataArrayDouble::New(); - dbl4->alloc(6,3); - DataArrayDouble *dbl5=DataArrayDouble::New(); - dbl5->alloc(7,3); - CPPUNIT_ASSERT_THROW(DataArrayDouble::CrossProduct(dbl4,dbl5),INTERP_KERNEL::Exception); //Nb of tuples mismatch - - a[0]=dbl4; //Nb of tuple mismatch - a[1]=dbl5; //Nb of tuple mismatch - CPPUNIT_ASSERT_THROW(DataArrayDouble::Meld(a),INTERP_KERNEL::Exception); - CPPUNIT_ASSERT_THROW(DataArrayDouble::Dot(dbl4,dbl5),INTERP_KERNEL::Exception); - - da->decrRef(); - db->decrRef(); - dbl->decrRef(); - dbl2->decrRef(); - dbl3->decrRef(); - dbl4->decrRef(); - dbl5->decrRef(); - dc->decrRef(); - dd->decrRef(); -} - -void MEDCouplingBasicsTest3::testDAIGetIdsEqual1() -{ - const int tab1[7]={5,-2,-4,-2,3,2,-2}; - DataArrayInt *da=DataArrayInt::New(); - da->alloc(7,1); - std::copy(tab1,tab1+7,da->getPointer()); - DataArrayInt *da2=da->getIdsEqual(-2); - CPPUNIT_ASSERT_EQUAL(3,da2->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(1,da2->getNumberOfComponents()); - const int expected1[3]={1,3,6}; - CPPUNIT_ASSERT(std::equal(expected1,expected1+3,da2->getConstPointer())); - da2->decrRef(); - da->decrRef(); -} - -void MEDCouplingBasicsTest3::testDAIGetIdsEqualList1() -{ - const int tab1[7]={5,-2,-4,-2,3,2,-2}; - DataArrayInt *da=DataArrayInt::New(); - da->alloc(7,1); - std::copy(tab1,tab1+7,da->getPointer()); - const int tab2[3]={3,-2,0}; - std::vector tab2V(tab2,tab2+3); - DataArrayInt *da2=da->getIdsEqualList(&tab2V[0],&tab2V[0]+tab2V.size()); - CPPUNIT_ASSERT_EQUAL(4,da2->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(1,da2->getNumberOfComponents()); - const int expected1[4]={1,3,4,6}; - CPPUNIT_ASSERT(std::equal(expected1,expected1+4,da2->getConstPointer())); - da2->decrRef(); - da->decrRef(); -} - -void MEDCouplingBasicsTest3::testDAFromNoInterlace1() -{ - const int tab1[15]={1,11,21,31,41,2,12,22,32,42,3,13,23,33,43}; - DataArrayInt *da=DataArrayInt::New(); - da->alloc(5,3); - std::copy(tab1,tab1+15,da->getPointer()); - DataArrayInt *da2=da->fromNoInterlace(); - const int expected1[15]={1,2,3,11,12,13,21,22,23,31,32,33,41,42,43}; - CPPUNIT_ASSERT_EQUAL(5,da2->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(3,da2->getNumberOfComponents());// it's not a bug. Avoid to have 1 million components ! - CPPUNIT_ASSERT(std::equal(expected1,expected1+15,da2->getConstPointer())); - DataArrayDouble *da3=da->convertToDblArr(); - DataArrayDouble *da4=da3->fromNoInterlace(); - CPPUNIT_ASSERT_EQUAL(5,da4->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(3,da4->getNumberOfComponents());// it's not a bug. Avoid to have 1 million components ! - for(int i=0;i<15;i++) - CPPUNIT_ASSERT_DOUBLES_EQUAL((double)expected1[i],da4->getIJ(0,i),1e-14); - da4->decrRef(); - da3->decrRef(); - da2->decrRef(); - da->decrRef(); -} - -void MEDCouplingBasicsTest3::testDAToNoInterlace1() -{ - const int tab1[15]={1,2,3,11,12,13,21,22,23,31,32,33,41,42,43}; - DataArrayInt *da=DataArrayInt::New(); - da->alloc(5,3); - std::copy(tab1,tab1+15,da->getPointer()); - DataArrayInt *da2=da->toNoInterlace(); - const int expected1[15]={1,11,21,31,41,2,12,22,32,42,3,13,23,33,43}; - CPPUNIT_ASSERT_EQUAL(5,da2->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(3,da2->getNumberOfComponents());// it's not a bug. Avoid to have 1 million components ! - CPPUNIT_ASSERT(std::equal(expected1,expected1+15,da2->getConstPointer())); - DataArrayDouble *da3=da->convertToDblArr(); - DataArrayDouble *da4=da3->toNoInterlace(); - CPPUNIT_ASSERT_EQUAL(5,da4->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(3,da4->getNumberOfComponents());// it's not a bug. Avoid to have 1 million components ! - for(int i=0;i<15;i++) - CPPUNIT_ASSERT_DOUBLES_EQUAL((double)expected1[i],da4->getIJ(0,i),1e-14); - da4->decrRef(); - da3->decrRef(); - da2->decrRef(); - da->decrRef(); -} - -void MEDCouplingBasicsTest3::testDAIsUniform1() -{ - const int tab1[5]={1,1,1,1,1}; - DataArrayInt *da=DataArrayInt::New(); - da->alloc(5,1); - std::copy(tab1,tab1+5,da->getPointer()); - CPPUNIT_ASSERT(da->isUniform(1)); - da->setIJ(2,0,2); - CPPUNIT_ASSERT(!da->isUniform(1)); - da->setIJ(2,0,1); - CPPUNIT_ASSERT(da->isUniform(1)); - DataArrayDouble *da2=da->convertToDblArr(); - CPPUNIT_ASSERT(da2->isUniform(1.,1e-12)); - da2->setIJ(1,0,1.+1.e-13); - CPPUNIT_ASSERT(da2->isUniform(1.,1e-12)); - da2->setIJ(1,0,1.+1.e-11); - CPPUNIT_ASSERT(!da2->isUniform(1.,1e-12)); - da2->decrRef(); - da->decrRef(); -} - -void MEDCouplingBasicsTest3::testDADFromPolarToCart1() -{ - const double tab1[4]={2.,0.2,2.5,0.7}; - DataArrayDouble *da=DataArrayDouble::New(); - da->alloc(2,2); - std::copy(tab1,tab1+4,da->getPointer()); - DataArrayDouble *da2=da->fromPolarToCart(); - const double expected1[4]={1.9601331556824833,0.39733866159012243, 1.9121054682112213,1.6105442180942275}; - for(int i=0;i<4;i++) - CPPUNIT_ASSERT_DOUBLES_EQUAL(expected1[i],da2->getIJ(0,i),1e-13); - da2->decrRef(); - da->decrRef(); -} - -void MEDCouplingBasicsTest3::testDADFromCylToCart1() -{ - const double tab1[6]={2.,0.2,4.,2.5,0.7,9.}; - DataArrayDouble *da=DataArrayDouble::New(); - da->alloc(2,3); - std::copy(tab1,tab1+6,da->getPointer()); - DataArrayDouble *da2=da->fromCylToCart(); - const double expected1[6]={1.9601331556824833,0.39733866159012243,4., 1.9121054682112213,1.6105442180942275,9.}; - for(int i=0;i<6;i++) - CPPUNIT_ASSERT_DOUBLES_EQUAL(expected1[i],da2->getIJ(0,i),1e-13); - da2->decrRef(); - da->decrRef(); -} - -void MEDCouplingBasicsTest3::testDADFromSpherToCart1() -{ - const double tab1[6]={2.,0.2,0.3,2.5,0.7,0.8}; - DataArrayDouble *da=DataArrayDouble::New(); - da->alloc(2,3); - std::copy(tab1,tab1+6,da->getPointer()); - DataArrayDouble *da2=da->fromSpherToCart(); - const double expected1[6]={0.37959212195737485,0.11742160338765303,1.9601331556824833, 1.1220769624465328,1.1553337045129035,1.9121054682112213}; - for(int i=0;i<6;i++) - CPPUNIT_ASSERT_DOUBLES_EQUAL(expected1[i],da2->getIJ(0,i),1e-13); - da2->decrRef(); - da->decrRef(); -} - -void MEDCouplingBasicsTest3::testUnPolyze1() -{ - const int elts[8]={0,1,2,3,4,5,6,7}; - std::vector eltsV(elts,elts+8); - MEDCouplingUMesh *mesh=build3DTargetMesh_1(); - mesh->convertToPolyTypes(&eltsV[0],&eltsV[0]+eltsV.size()); - mesh->unPolyze(); - MEDCouplingUMesh *mesh2=build3DTargetMesh_1(); - mesh->checkCoherency(); - CPPUNIT_ASSERT(mesh->isEqual(mesh2,1e-12)); - mesh->convertToPolyTypes(&eltsV[0],&eltsV[0]+eltsV.size()); - CPPUNIT_ASSERT(!mesh->isEqual(mesh2,1e-12)); - mesh->getNodalConnectivity()->setIJ(0,6,10); - mesh->getNodalConnectivity()->setIJ(0,7,9); - mesh->getNodalConnectivity()->setIJ(0,8,12); - mesh->getNodalConnectivity()->setIJ(0,9,13); - mesh->unPolyze(); - CPPUNIT_ASSERT(mesh->isEqual(mesh2,1e-12)); - mesh->convertToPolyTypes(&eltsV[0],&eltsV[0]+eltsV.size()); - mesh->getNodalConnectivity()->setIJ(0,6,12); - mesh->getNodalConnectivity()->setIJ(0,7,13); - mesh->getNodalConnectivity()->setIJ(0,8,10); - mesh->getNodalConnectivity()->setIJ(0,9,9); - mesh->unPolyze(); - CPPUNIT_ASSERT(mesh->isEqual(mesh2,1e-12)); - mesh->convertToPolyTypes(&eltsV[0],&eltsV[0]+eltsV.size()); - mesh->getNodalConnectivity()->setIJ(0,6,12); - mesh->getNodalConnectivity()->setIJ(0,7,10); - mesh->getNodalConnectivity()->setIJ(0,8,13); - mesh->getNodalConnectivity()->setIJ(0,9,9); - mesh->unPolyze(); - CPPUNIT_ASSERT(!mesh->isEqual(mesh2,1e-12)); - mesh->decrRef(); - mesh2->decrRef(); - // Test for 2D mesh - mesh=build2DTargetMesh_1(); - mesh2=build2DTargetMesh_1(); - eltsV.resize(5); - mesh->convertToPolyTypes(&eltsV[0],&eltsV[0]+eltsV.size()); - CPPUNIT_ASSERT(!mesh->isEqual(mesh2,1e-12)); - mesh->unPolyze(); - CPPUNIT_ASSERT(mesh->isEqual(mesh2,1e-12)); - mesh->decrRef(); - mesh2->decrRef(); -} - -void MEDCouplingBasicsTest3::testConvertDegeneratedCells1() -{ - MEDCouplingUMesh *mesh=build3DTargetMesh_1(); - int conn[32]={0,1,3,3,9,10,12,12, 0,1,3,4,9,9,9,9, 1,1,1,1,10,12,9,10, 10,11,12,9,1,1,1,1}; - mesh->allocateCells(4); - mesh->insertNextCell(INTERP_KERNEL::NORM_HEXA8,8,conn); - mesh->insertNextCell(INTERP_KERNEL::NORM_HEXA8,8,conn+8); - mesh->insertNextCell(INTERP_KERNEL::NORM_HEXA8,8,conn+16); - mesh->insertNextCell(INTERP_KERNEL::NORM_HEXA8,8,conn+24); - mesh->finishInsertingCells(); - mesh->checkCoherency(); - CPPUNIT_ASSERT_EQUAL(4,mesh->getNumberOfCells()); - CPPUNIT_ASSERT_EQUAL(INTERP_KERNEL::NORM_HEXA8,mesh->getTypeOfCell(0)); - CPPUNIT_ASSERT_EQUAL(INTERP_KERNEL::NORM_HEXA8,mesh->getTypeOfCell(1)); - CPPUNIT_ASSERT_EQUAL(INTERP_KERNEL::NORM_HEXA8,mesh->getTypeOfCell(2)); - CPPUNIT_ASSERT_EQUAL(INTERP_KERNEL::NORM_HEXA8,mesh->getTypeOfCell(3)); - MEDCouplingFieldDouble *f1=mesh->getMeasureField(true); - mesh->convertDegeneratedCells(); - mesh->checkCoherency(); - MEDCouplingFieldDouble *f2=mesh->getMeasureField(true); - CPPUNIT_ASSERT_EQUAL(4,mesh->getNumberOfCells()); - CPPUNIT_ASSERT_EQUAL(INTERP_KERNEL::NORM_PENTA6,mesh->getTypeOfCell(0)); - CPPUNIT_ASSERT_EQUAL(INTERP_KERNEL::NORM_PYRA5,mesh->getTypeOfCell(1)); - CPPUNIT_ASSERT_EQUAL(INTERP_KERNEL::NORM_TETRA4,mesh->getTypeOfCell(2)); - CPPUNIT_ASSERT_EQUAL(INTERP_KERNEL::NORM_PYRA5,mesh->getTypeOfCell(3)); - for(int i=0;i<4;i++) - CPPUNIT_ASSERT_DOUBLES_EQUAL(f1->getArray()->getIJ(0,i),f2->getArray()->getIJ(0,i),1e-5); - f1->decrRef(); - f2->decrRef(); - mesh->decrRef(); -} - -void MEDCouplingBasicsTest3::testGetNodeIdsNearPoints1() -{ - MEDCouplingUMesh *mesh=build2DTargetMesh_1(); - DataArrayDouble *coords=mesh->getCoords(); - DataArrayDouble *tmp=DataArrayDouble::New(); - tmp->alloc(3,2); - const double vals[6]={0.2,0.2,0.1,0.2,0.2,0.2}; - std::copy(vals,vals+6,tmp->getPointer()); - DataArrayDouble *tmp2=DataArrayDouble::Aggregate(coords,tmp); - tmp->decrRef(); - mesh->setCoords(tmp2); - tmp2->decrRef(); - const double pts[6]={0.2,0.2,0.1,0.3,-0.3,0.7}; - DataArrayInt *c=mesh->getNodeIdsNearPoint(pts,1e-7); - CPPUNIT_ASSERT_EQUAL(3,c->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(4,c->getIJ(0,0)); - CPPUNIT_ASSERT_EQUAL(9,c->getIJ(1,0)); - CPPUNIT_ASSERT_EQUAL(11,c->getIJ(2,0)); - c->decrRef(); - DataArrayInt *cI=0; - mesh->getNodeIdsNearPoints(pts,3,1e-7,c,cI); - CPPUNIT_ASSERT_EQUAL(4,cI->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(4,c->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(4,c->getIJ(0,0)); - CPPUNIT_ASSERT_EQUAL(9,c->getIJ(1,0)); - CPPUNIT_ASSERT_EQUAL(11,c->getIJ(2,0)); - CPPUNIT_ASSERT_EQUAL(6,c->getIJ(3,0)); - CPPUNIT_ASSERT_EQUAL(0,cI->getIJ(0,0)); - CPPUNIT_ASSERT_EQUAL(3,cI->getIJ(1,0)); - CPPUNIT_ASSERT_EQUAL(3,cI->getIJ(2,0)); - CPPUNIT_ASSERT_EQUAL(4,cI->getIJ(3,0)); - c->decrRef(); - cI->decrRef(); - mesh->decrRef(); -} - -void MEDCouplingBasicsTest3::testFieldCopyTinyAttrFrom1() -{ - MEDCouplingFieldDouble *f1=MEDCouplingFieldDouble::New(ON_CELLS,ONE_TIME); - f1->setName("f1"); - f1->setTimeTolerance(1.e-5); - f1->setDescription("f1Desc"); - f1->setTime(1.23,4,5); - MEDCouplingFieldDouble *f2=MEDCouplingFieldDouble::New(ON_CELLS,ONE_TIME); - f2->setName("f2"); - f2->setDescription("f2Desc"); - f2->setTime(6.78,9,10); - f2->setTimeTolerance(4.556e-12); - // - int dt,it; - f1->copyTinyAttrFrom(f2); - CPPUNIT_ASSERT_DOUBLES_EQUAL(4.556e-12,f1->getTimeTolerance(),1e-24); - CPPUNIT_ASSERT_DOUBLES_EQUAL(6.78,f1->getTime(dt,it),1e-12); - CPPUNIT_ASSERT_EQUAL(9,dt); - CPPUNIT_ASSERT_EQUAL(10,it); - CPPUNIT_ASSERT(std::string(f1->getName())=="f1");//name unchanged - CPPUNIT_ASSERT(std::string(f1->getDescription())=="f1Desc");//description unchanged - f1->decrRef(); - f2->decrRef(); - // - f1=MEDCouplingFieldDouble::New(ON_CELLS,NO_TIME); - f1->setName("f1"); - f1->setTimeTolerance(1.e-5); - f1->setDescription("f1Desc"); - f2=MEDCouplingFieldDouble::New(ON_CELLS,NO_TIME); - f2->setName("f2"); - f2->setDescription("f2Desc"); - f2->setTimeTolerance(4.556e-12); - // - f1->copyTinyAttrFrom(f2); - CPPUNIT_ASSERT_DOUBLES_EQUAL(4.556e-12,f1->getTimeTolerance(),1e-24); - CPPUNIT_ASSERT(std::string(f1->getName())=="f1");//name unchanged - CPPUNIT_ASSERT(std::string(f1->getDescription())=="f1Desc");//description unchanged - f1->decrRef(); - f2->decrRef(); - // - f1=MEDCouplingFieldDouble::New(ON_CELLS,CONST_ON_TIME_INTERVAL); - f1->setName("f1"); - f1->setTimeTolerance(1.e-5); - f1->setDescription("f1Desc"); - f1->setTime(1.23,4,5); - f1->setEndTime(5.43,2,1); - f2=MEDCouplingFieldDouble::New(ON_CELLS,CONST_ON_TIME_INTERVAL); - f2->setName("f2"); - f2->setDescription("f2Desc"); - f2->setTimeTolerance(4.556e-12); - f2->setTime(6.78,9,10); - f2->setEndTime(10.98,7,6); - // - f1->copyTinyAttrFrom(f2); - CPPUNIT_ASSERT_DOUBLES_EQUAL(4.556e-12,f1->getTimeTolerance(),1e-24); - CPPUNIT_ASSERT(std::string(f1->getName())=="f1");//name unchanged - CPPUNIT_ASSERT(std::string(f1->getDescription())=="f1Desc");//description unchanged - CPPUNIT_ASSERT_DOUBLES_EQUAL(6.78,f1->getTime(dt,it),1e-12); - CPPUNIT_ASSERT_EQUAL(9,dt); - CPPUNIT_ASSERT_EQUAL(10,it); - CPPUNIT_ASSERT_DOUBLES_EQUAL(10.98,f1->getEndTime(dt,it),1e-12); - CPPUNIT_ASSERT_EQUAL(7,dt); - CPPUNIT_ASSERT_EQUAL(6,it); - f1->decrRef(); - f2->decrRef(); - // - f1=MEDCouplingFieldDouble::New(ON_CELLS,LINEAR_TIME); - f1->setName("f1"); - f1->setTimeTolerance(1.e-5); - f1->setDescription("f1Desc"); - f1->setTime(1.23,4,5); - f1->setEndTime(5.43,2,1); - f2=MEDCouplingFieldDouble::New(ON_CELLS,LINEAR_TIME); - f2->setName("f2"); - f2->setDescription("f2Desc"); - f2->setTimeTolerance(4.556e-12); - f2->setTime(6.78,9,10); - f2->setEndTime(10.98,7,6); - // - f1->copyTinyAttrFrom(f2); - CPPUNIT_ASSERT_DOUBLES_EQUAL(4.556e-12,f1->getTimeTolerance(),1e-24); - CPPUNIT_ASSERT(std::string(f1->getName())=="f1");//name unchanged - CPPUNIT_ASSERT(std::string(f1->getDescription())=="f1Desc");//description unchanged - CPPUNIT_ASSERT_DOUBLES_EQUAL(6.78,f1->getTime(dt,it),1e-12); - CPPUNIT_ASSERT_EQUAL(9,dt); - CPPUNIT_ASSERT_EQUAL(10,it); - CPPUNIT_ASSERT_DOUBLES_EQUAL(10.98,f1->getEndTime(dt,it),1e-12); - CPPUNIT_ASSERT_EQUAL(7,dt); - CPPUNIT_ASSERT_EQUAL(6,it); - f1->decrRef(); - f2->decrRef(); -} - -/*! - * 1D -> 2D extrusion with rotation - */ -void MEDCouplingBasicsTest3::testExtrudedMesh5() -{ - const double coo1[4]={0.,1.,2.,3.5}; - DataArrayDouble *a=DataArrayDouble::New(); - a->alloc(4,1); - std::copy(coo1,coo1+4,a->getPointer()); - MEDCouplingCMesh *b=MEDCouplingCMesh::New(); - b->setCoordsAt(0,a); - MEDCouplingUMesh *c=b->buildUnstructured(); - CPPUNIT_ASSERT_EQUAL(1,c->getSpaceDimension()); - c->changeSpaceDimension(2); - // - DataArrayDouble *d=DataArrayDouble::New(); - d->alloc(13,1); - d->iota(); - MEDCouplingCMesh *ee=MEDCouplingCMesh::New(); - ee->setCoordsAt(0,d); - MEDCouplingUMesh *f=ee->buildUnstructured(); - DataArrayDouble *g=f->getCoords()->applyFunc(2,"3.5*IVec+x/6*3.14159265359*JVec"); - CPPUNIT_ASSERT_THROW(f->getCoords()->applyFunc(2,"3.5*IVec+x/6*3.14159265359*KVec"),INTERP_KERNEL::Exception); // KVec refers to component #2 and there is only 2 components ! - DataArrayDouble *h=g->fromPolarToCart(); - f->setCoords(h); - MEDCouplingUMesh *i=c->buildExtrudedMesh(f,1); - CPPUNIT_ASSERT_EQUAL(52,i->getNumberOfNodes()); - bool tmp2; - int tmp3; - DataArrayInt *tmp=i->mergeNodes(1e-9,tmp2,tmp3); - CPPUNIT_ASSERT(tmp2); - CPPUNIT_ASSERT_EQUAL(37,tmp3); - tmp->decrRef(); - i->convertDegeneratedCells(); - i->checkCoherency(); - CPPUNIT_ASSERT_EQUAL(36,i->getNumberOfCells()); - CPPUNIT_ASSERT_EQUAL(37,i->getNumberOfNodes()); - CPPUNIT_ASSERT_EQUAL(12,i->getNumberOfCellsWithType(INTERP_KERNEL::NORM_TRI3)); - CPPUNIT_ASSERT_EQUAL(24,i->getNumberOfCellsWithType(INTERP_KERNEL::NORM_QUAD4)); - const double expected1[3]={0.25,0.75,2.0625}; - MEDCouplingFieldDouble *j=i->getMeasureField(true); - for(int ii=0;ii<12;ii++) - for(int k=0;k<3;k++) - CPPUNIT_ASSERT_DOUBLES_EQUAL(expected1[k],j->getIJ(0,ii*3+k),1e-10); - const double expected2[72]={0.62200846792814113, 0.16666666666681595, 1.4513530918323276, 0.38888888888923495, 2.6293994326053212, 0.7045454545460802, 0.45534180126145435, 0.45534180126150181, 1.0624642029433926, 1.0624642029435025, 1.9248539780597826, 1.9248539780599816, 0.16666666666661334, 0.62200846792815856, 0.38888888888876294, 1.4513530918323678, 0.70454545454522521, 2.629399432605394, -0.16666666666674007, 0.62200846792812436, -0.38888888888906142, 1.4513530918322881, -0.70454545454576778, 2.6293994326052488, -0.45534180126154766, 0.45534180126140844, -1.0624642029436118, 1.0624642029432834, -1.9248539780601803, 1.9248539780595841, -0.62200846792817499, 0.1666666666665495, -1.451353091832408, 0.388888888888613, -2.6293994326054668, 0.70454545454495332, -0.62200846792810593, -0.16666666666680507, -1.451353091832247, -0.38888888888921297, -2.6293994326051746, -0.70454545454604123, -0.45534180126135926, -0.45534180126159562, -1.0624642029431723, -1.0624642029437235, -1.9248539780593836, -1.9248539780603811, -0.1666666666664828, -0.62200846792819242, -0.38888888888846079, -1.4513530918324489, -0.70454545454467987, -2.6293994326055397, 0.16666666666687083, -0.62200846792808862, 0.38888888888936374, -1.4513530918322073, 0.70454545454631357, -2.6293994326051022, 0.45534180126164348, -0.45534180126131207, 1.0624642029438327, -1.0624642029430627, 1.9248539780605791, -1.9248539780591853, 0.62200846792821063, -0.16666666666641802, 1.4513530918324888, -0.38888888888831086, 2.6293994326056125, -0.70454545454440853}; - DataArrayDouble *m=i->getBarycenterAndOwner(); - for(int ii=0;ii<72;ii++) - CPPUNIT_ASSERT_DOUBLES_EQUAL(expected2[ii],m->getIJ(0,ii),1e-10); - // - m->decrRef(); - j->decrRef(); - i->decrRef(); - h->decrRef(); - g->decrRef(); - f->decrRef(); - ee->decrRef(); - d->decrRef(); - c->decrRef(); - b->decrRef(); - a->decrRef(); -} - -/*! - * 1D -> 2D extrusion without rotation - */ -void MEDCouplingBasicsTest3::testExtrudedMesh6() -{ - const double coo1[4]={0.,1.,2.,3.5}; - DataArrayDouble *a=DataArrayDouble::New(); - a->alloc(4,1); - std::copy(coo1,coo1+4,a->getPointer()); - MEDCouplingCMesh *b=MEDCouplingCMesh::New(); - b->setCoordsAt(0,a); - MEDCouplingUMesh *c=b->buildUnstructured(); - CPPUNIT_ASSERT_EQUAL(1,c->getSpaceDimension()); - c->changeSpaceDimension(2); - // - DataArrayDouble *d=DataArrayDouble::New(); - d->alloc(5,1); - d->iota(); - MEDCouplingCMesh *e=MEDCouplingCMesh::New(); - e->setCoordsAt(0,d); - MEDCouplingUMesh *f=e->buildUnstructured(); - DataArrayDouble *d2=f->getCoords()->applyFunc("x*x/2"); - f->setCoords(d2); - f->changeSpaceDimension(2); - // - const double center[2]={0.,0.}; - f->rotate(center,0,M_PI/3); - MEDCouplingUMesh *g=c->buildExtrudedMesh(f,0); - g->checkCoherency(); - const double expected1[]={ 0.4330127018922193, 0.4330127018922193, 0.649519052838329, 1.2990381056766578, 1.299038105676658, 1.948557158514987, 2.1650635094610955, 2.1650635094610964, 3.2475952641916446, 3.031088913245533, 3.0310889132455352, 4.546633369868303 }; - MEDCouplingFieldDouble *f1=g->getMeasureField(true); - for(int i=0;i<12;i++) - CPPUNIT_ASSERT_DOUBLES_EQUAL(expected1[i],f1->getIJ(0,i),1e-12); - - const double expected2[]={0.625, 0.21650635094610962, 1.625, 0.21650635094610959, 2.8750000000000004, 0.21650635094610965, 1.1250000000000002, 1.0825317547305482, 2.125, 1.0825317547305482, 3.3750000000000004, 1.0825317547305484, 2.125, 2.8145825622994254, 3.125, 2.8145825622994254, 4.375, 2.8145825622994254, 3.6250000000000009, 5.4126587736527414, 4.625, 5.4126587736527414, 5.875, 5.4126587736527414}; - DataArrayDouble *f2=g->getBarycenterAndOwner(); - for(int i=0;i<24;i++) - CPPUNIT_ASSERT_DOUBLES_EQUAL(expected2[i],f2->getIJ(0,i),1e-12); - // - f1->decrRef(); - f2->decrRef(); - g->decrRef(); - f->decrRef(); - e->decrRef(); - d->decrRef(); - d2->decrRef(); - c->decrRef(); - b->decrRef(); - a->decrRef(); -} - -/*! - * 2D -> 3D extrusion with rotation - */ -void MEDCouplingBasicsTest3::testExtrudedMesh7() -{ - const double coo1[4]={0.,1.,2.,3.5}; - DataArrayDouble *a=DataArrayDouble::New(); - a->alloc(4,1); - std::copy(coo1,coo1+4,a->getPointer()); - MEDCouplingCMesh *b=MEDCouplingCMesh::New(); - b->setCoordsAt(0,a); - MEDCouplingUMesh *c=b->buildUnstructured(); - CPPUNIT_ASSERT_EQUAL(1,c->getSpaceDimension()); - c->changeSpaceDimension(2); - // - DataArrayDouble *d=DataArrayDouble::New(); - d->alloc(13,1); - d->iota(); - MEDCouplingCMesh *e=MEDCouplingCMesh::New(); - e->setCoordsAt(0,d); - MEDCouplingUMesh *f=e->buildUnstructured(); - DataArrayDouble *g=f->getCoords()->applyFunc(2,"3.5*IVec+x/6*3.14159265359*JVec"); - DataArrayDouble *h=g->fromPolarToCart(); - f->setCoords(h); - MEDCouplingUMesh *i=c->buildExtrudedMesh(f,1); - CPPUNIT_ASSERT_EQUAL(52,i->getNumberOfNodes()); - bool tmp2; - int tmp3; - DataArrayInt *tmp=i->mergeNodes(1e-9,tmp2,tmp3); - CPPUNIT_ASSERT(tmp2); - CPPUNIT_ASSERT_EQUAL(37,tmp3); - tmp->decrRef(); - i->convertDegeneratedCells(); - const double vec1[3]={10.,0.,0.}; - i->translate(vec1); - DataArrayDouble *g2=h->applyFunc(3,"13.5/3.5*x*IVec+0*JVec+13.5/3.5*y*KVec"); - f->setCoords(g2); - i->changeSpaceDimension(3); - MEDCouplingUMesh *i3=i->buildExtrudedMesh(f,1); - MEDCouplingFieldDouble *f2=i3->getMeasureField(true); - tmp=i->mergeNodes(1e-9,tmp2,tmp3); - CPPUNIT_ASSERT(tmp2); - CPPUNIT_ASSERT_EQUAL(444,tmp3); - tmp->decrRef(); - const double expected1[36]={1.327751058489274, 4.2942574094314701, 13.024068164857139, 1.3069177251569044, 4.1484240761012954, 12.297505664866796, 1.270833333332571, 3.8958333333309674, 11.039062499993179, 1.2291666666659207, 3.6041666666644425, 9.585937499993932, 1.1930822748415895, 3.3515759238941376, 8.3274943351204556, 1.1722489415082769, 3.2057425905609289, 7.6009318351210622, 1.1722489415082862, 3.2057425905609884, 7.6009318351213713, 1.1930822748416161, 3.3515759238943001, 8.3274943351212727, 1.2291666666659564, 3.6041666666646734, 9.5859374999950777, 1.2708333333326081, 3.8958333333311868, 11.039062499994293, 1.3069177251569224, 4.1484240761014384, 12.297505664867627, 1.3277510584902354, 4.2942574094346071, 13.024068164866796}; - int kk=0; - for(int ii=0;ii<12;ii++) - for(int jj=0;jj<36;jj++,kk++) - CPPUNIT_ASSERT_DOUBLES_EQUAL(expected1[jj],f2->getIJ(0,kk),1e-9); - // - f2->decrRef(); - i3->decrRef(); - g2->decrRef(); - i->decrRef(); - h->decrRef(); - g->decrRef(); - f->decrRef(); - e->decrRef(); - d->decrRef(); - c->decrRef(); - b->decrRef(); - a->decrRef(); -} - -void MEDCouplingBasicsTest3::testSimplexize1() -{ - MEDCouplingUMesh *m=build3DSurfTargetMesh_1(); - std::vector v(1); - v[0]=3; - m->convertToPolyTypes(&v[0],&v[0]+v.size()); - DataArrayInt *da=m->simplexize(0); - CPPUNIT_ASSERT_EQUAL(7,da->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(1,da->getNumberOfComponents()); - const int expected2[7]={0,0,1,2,3,4,4}; - for(int i=0;i<7;i++) - CPPUNIT_ASSERT_EQUAL(expected2[i],da->getIJ(i,0)); - m->checkCoherency(); - CPPUNIT_ASSERT_EQUAL(7,m->getNumberOfCells()); - CPPUNIT_ASSERT_EQUAL(INTERP_KERNEL::NORM_TRI3,m->getTypeOfCell(0)); - CPPUNIT_ASSERT_EQUAL(INTERP_KERNEL::NORM_TRI3,m->getTypeOfCell(1)); - CPPUNIT_ASSERT_EQUAL(INTERP_KERNEL::NORM_TRI3,m->getTypeOfCell(2)); - CPPUNIT_ASSERT_EQUAL(INTERP_KERNEL::NORM_TRI3,m->getTypeOfCell(3)); - CPPUNIT_ASSERT_EQUAL(INTERP_KERNEL::NORM_POLYGON,m->getTypeOfCell(4)); - CPPUNIT_ASSERT_EQUAL(INTERP_KERNEL::NORM_TRI3,m->getTypeOfCell(5)); - CPPUNIT_ASSERT_EQUAL(INTERP_KERNEL::NORM_TRI3,m->getTypeOfCell(6)); - const double expected1[7]={0.125,0.125,0.125,0.125,0.25,0.125,0.125}; - MEDCouplingFieldDouble *f=m->getMeasureField(false); - for(int i=0;i<7;i++) - CPPUNIT_ASSERT_DOUBLES_EQUAL(expected1[i]*sqrt(2.),f->getIJ(i,0),1e-10); - std::set types=m->getAllGeoTypes(); - CPPUNIT_ASSERT_EQUAL(2,(int)types.size()); - CPPUNIT_ASSERT_EQUAL(INTERP_KERNEL::NORM_TRI3,*(types.begin())); - CPPUNIT_ASSERT_EQUAL(INTERP_KERNEL::NORM_POLYGON,*(++(types.begin()))); - f->decrRef(); - da->decrRef(); - m->decrRef(); - // - m=build3DSurfTargetMesh_1(); - v[0]=3; - m->convertToPolyTypes(&v[0],&v[0]+v.size()); - da=m->simplexize(1); - CPPUNIT_ASSERT_EQUAL(7,da->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(1,da->getNumberOfComponents()); - for(int i=0;i<7;i++) - CPPUNIT_ASSERT_EQUAL(expected2[i],da->getIJ(i,0)); - m->checkCoherency(); - types=m->getAllGeoTypes(); - CPPUNIT_ASSERT_EQUAL(2,(int)types.size()); - CPPUNIT_ASSERT_EQUAL(INTERP_KERNEL::NORM_TRI3,*(types.begin())); - CPPUNIT_ASSERT_EQUAL(INTERP_KERNEL::NORM_POLYGON,*(++(types.begin()))); - CPPUNIT_ASSERT_EQUAL(7,m->getNumberOfCells()); - CPPUNIT_ASSERT_EQUAL(INTERP_KERNEL::NORM_TRI3,m->getTypeOfCell(0)); - CPPUNIT_ASSERT_EQUAL(INTERP_KERNEL::NORM_TRI3,m->getTypeOfCell(1)); - CPPUNIT_ASSERT_EQUAL(INTERP_KERNEL::NORM_TRI3,m->getTypeOfCell(2)); - CPPUNIT_ASSERT_EQUAL(INTERP_KERNEL::NORM_TRI3,m->getTypeOfCell(3)); - CPPUNIT_ASSERT_EQUAL(INTERP_KERNEL::NORM_POLYGON,m->getTypeOfCell(4)); - CPPUNIT_ASSERT_EQUAL(INTERP_KERNEL::NORM_TRI3,m->getTypeOfCell(5)); - CPPUNIT_ASSERT_EQUAL(INTERP_KERNEL::NORM_TRI3,m->getTypeOfCell(6)); - f=m->getMeasureField(false); - for(int i=0;i<7;i++) - CPPUNIT_ASSERT_DOUBLES_EQUAL(expected1[i]*sqrt(2.),f->getIJ(i,0),1e-10); - f->decrRef(); - da->decrRef(); - m->decrRef(); -} - -void MEDCouplingBasicsTest3::testSimplexize2() -{ - MEDCouplingUMesh *m=build3DSurfTargetMesh_1(); - std::vector v(1); - v[0]=3; - m->convertToPolyTypes(&v[0],&v[0]+v.size()); - MEDCouplingFieldDouble *f1=MEDCouplingFieldDouble::New(ON_CELLS,ONE_TIME); - f1->setMesh(m); - DataArrayDouble *arr=DataArrayDouble::New(); - const double arr1[10]={10.,110.,20.,120.,30.,130.,40.,140.,50.,150.}; - arr->alloc(5,2); - std::copy(arr1,arr1+10,arr->getPointer()); - f1->setArray(arr); - arr->decrRef(); - // - f1->checkCoherency(); - CPPUNIT_ASSERT(f1->simplexize(0)); - f1->checkCoherency(); - const double expected1[14]={10.,110.,10.,110.,20.,120.,30.,130.,40.,140.,50.,150.,50.,150.}; - for(int i=0;i<14;i++) - CPPUNIT_ASSERT_DOUBLES_EQUAL(expected1[i],f1->getIJ(0,i),1e-10); - CPPUNIT_ASSERT(!f1->simplexize(0)); - for(int i=0;i<14;i++) - CPPUNIT_ASSERT_DOUBLES_EQUAL(expected1[i],f1->getIJ(0,i),1e-10); - // - f1->decrRef(); - m->decrRef(); -} - -void MEDCouplingBasicsTest3::testDAMeld1() -{ - DataArrayDouble *da1=DataArrayDouble::New(); - da1->alloc(7,2); - DataArrayDouble *da2=DataArrayDouble::New(); - da2->alloc(7,1); - // - da1->fillWithValue(7.); - da2->iota(0.); - DataArrayDouble *da3=da2->applyFunc(3,"10*x*IVec+100*x*JVec+1000*x*KVec"); - // - da1->setInfoOnComponent(0,"c0da1"); - da1->setInfoOnComponent(1,"c1da1"); - da3->setInfoOnComponent(0,"c0da3"); - da3->setInfoOnComponent(1,"c1da3"); - da3->setInfoOnComponent(2,"c2da3"); - // - DataArrayDouble *da1C=da1->deepCpy(); - da1->meldWith(da3); - CPPUNIT_ASSERT_EQUAL(5,da1->getNumberOfComponents()); - CPPUNIT_ASSERT_EQUAL(7,da1->getNumberOfTuples()); - CPPUNIT_ASSERT(da1->getInfoOnComponent(0)=="c0da1"); - CPPUNIT_ASSERT(da1->getInfoOnComponent(1)=="c1da1"); - CPPUNIT_ASSERT(da1->getInfoOnComponent(2)=="c0da3"); - CPPUNIT_ASSERT(da1->getInfoOnComponent(3)=="c1da3"); - CPPUNIT_ASSERT(da1->getInfoOnComponent(4)=="c2da3"); - // - const double expected1[35]={7.,7.,0.,0.,0., 7.,7.,10.,100.,1000., 7.,7.,20.,200.,2000., 7.,7.,30.,300.,3000., 7.,7.,40.,400.,4000.,7.,7.,50.,500.,5000.,7.,7.,60.,600.,6000.}; - for(int i=0;i<35;i++) - CPPUNIT_ASSERT_DOUBLES_EQUAL(expected1[i],da1->getIJ(0,i),1e-10); - // - DataArrayInt *dai1=da1C->convertToIntArr(); - DataArrayInt *dai3=da3->convertToIntArr(); - dai1->meldWith(dai3); - CPPUNIT_ASSERT_EQUAL(5,dai1->getNumberOfComponents()); - CPPUNIT_ASSERT_EQUAL(7,dai1->getNumberOfTuples()); - CPPUNIT_ASSERT(dai1->getInfoOnComponent(0)=="c0da1"); - CPPUNIT_ASSERT(dai1->getInfoOnComponent(1)=="c1da1"); - CPPUNIT_ASSERT(dai1->getInfoOnComponent(2)=="c0da3"); - CPPUNIT_ASSERT(dai1->getInfoOnComponent(3)=="c1da3"); - CPPUNIT_ASSERT(dai1->getInfoOnComponent(4)=="c2da3"); - for(int i=0;i<35;i++) - CPPUNIT_ASSERT_EQUAL((int)expected1[i],dai1->getIJ(0,i)); - // test of static method DataArrayDouble::meld - DataArrayDouble *da4=DataArrayDouble::Meld(da1C,da3); - CPPUNIT_ASSERT_EQUAL(5,da4->getNumberOfComponents()); - CPPUNIT_ASSERT_EQUAL(7,da4->getNumberOfTuples()); - CPPUNIT_ASSERT(da4->getInfoOnComponent(0)=="c0da1"); - CPPUNIT_ASSERT(da4->getInfoOnComponent(1)=="c1da1"); - CPPUNIT_ASSERT(da4->getInfoOnComponent(2)=="c0da3"); - CPPUNIT_ASSERT(da4->getInfoOnComponent(3)=="c1da3"); - CPPUNIT_ASSERT(da4->getInfoOnComponent(4)=="c2da3"); - for(int i=0;i<35;i++) - CPPUNIT_ASSERT_DOUBLES_EQUAL(expected1[i],da4->getIJ(0,i),1e-10); - // test of static method DataArrayInt::meld - dai1->decrRef(); - dai1=da1C->convertToIntArr(); - DataArrayInt *dai4=DataArrayInt::Meld(dai1,dai3); - CPPUNIT_ASSERT_EQUAL(5,dai4->getNumberOfComponents()); - CPPUNIT_ASSERT_EQUAL(7,dai4->getNumberOfTuples()); - CPPUNIT_ASSERT(dai4->getInfoOnComponent(0)=="c0da1"); - CPPUNIT_ASSERT(dai4->getInfoOnComponent(1)=="c1da1"); - CPPUNIT_ASSERT(dai4->getInfoOnComponent(2)=="c0da3"); - CPPUNIT_ASSERT(dai4->getInfoOnComponent(3)=="c1da3"); - CPPUNIT_ASSERT(dai4->getInfoOnComponent(4)=="c2da3"); - for(int i=0;i<35;i++) - CPPUNIT_ASSERT_EQUAL((int)expected1[i],dai4->getIJ(0,i)); - // - dai4->decrRef(); - da4->decrRef(); - dai3->decrRef(); - dai1->decrRef(); - da1C->decrRef(); - da1->decrRef(); - da2->decrRef(); - da3->decrRef(); -} - -void MEDCouplingBasicsTest3::testFieldMeld1() -{ - MEDCouplingUMesh *m=build3DSurfTargetMesh_1(); - MEDCouplingFieldDouble *f1=MEDCouplingFieldDouble::New(ON_CELLS,ONE_TIME); - f1->setMesh(m); - DataArrayDouble *da1=DataArrayDouble::New(); - const double arr1[5]={12.,23.,34.,45.,56.}; - da1->alloc(5,1); - std::copy(arr1,arr1+5,da1->getPointer()); - da1->setInfoOnComponent(0,"aaa"); - f1->setArray(da1); - f1->setTime(3.4,2,1); - f1->checkCoherency(); - // - MEDCouplingFieldDouble *f2=f1->deepCpy(); - f2->setMesh(f1->getMesh()); - f2->checkCoherency(); - f2->changeNbOfComponents(2,5.); - (*f2)=5.; - f2->getArray()->setInfoOnComponent(0,"bbb"); - f2->getArray()->setInfoOnComponent(1,"ccc"); - f2->checkCoherency(); - // - MEDCouplingFieldDouble *f3=MEDCouplingFieldDouble::MeldFields(f2,f1); - f3->checkCoherency(); - CPPUNIT_ASSERT_EQUAL(5,f3->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(3,f3->getNumberOfComponents()); - CPPUNIT_ASSERT(f3->getArray()->getInfoOnComponent(0)=="bbb"); - CPPUNIT_ASSERT(f3->getArray()->getInfoOnComponent(1)=="ccc"); - CPPUNIT_ASSERT(f3->getArray()->getInfoOnComponent(2)=="aaa"); - const double expected1[15]={5.,5.,12.,5.,5.,23.,5.,5.,34.,5.,5.,45.,5.,5.,56.}; - for(int i=0;i<15;i++) - CPPUNIT_ASSERT_DOUBLES_EQUAL(expected1[i],f3->getIJ(0,i),1e-12); - int dt,it; - double time=f3->getTime(dt,it); - CPPUNIT_ASSERT_DOUBLES_EQUAL(3.4,time,1e-14); - CPPUNIT_ASSERT_EQUAL(2,dt); - CPPUNIT_ASSERT_EQUAL(1,it); - // - MEDCouplingFieldDouble *f4=f2->buildNewTimeReprFromThis(NO_TIME,false); - MEDCouplingFieldDouble *f5=f1->buildNewTimeReprFromThis(NO_TIME,false); - MEDCouplingFieldDouble *f6=MEDCouplingFieldDouble::MeldFields(f4,f5); - f6->checkCoherency(); - CPPUNIT_ASSERT_EQUAL(5,f6->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(3,f6->getNumberOfComponents()); - CPPUNIT_ASSERT(f6->getArray()->getInfoOnComponent(0)=="bbb"); - CPPUNIT_ASSERT(f6->getArray()->getInfoOnComponent(1)=="ccc"); - CPPUNIT_ASSERT(f6->getArray()->getInfoOnComponent(2)=="aaa"); - for(int i=0;i<15;i++) - CPPUNIT_ASSERT_DOUBLES_EQUAL(expected1[i],f6->getIJ(0,i),1e-12); - // - f6->decrRef(); - f4->decrRef(); - f5->decrRef(); - f3->decrRef(); - da1->decrRef(); - f2->decrRef(); - f1->decrRef(); - m->decrRef(); -} - -void MEDCouplingBasicsTest3::testMergeNodes2() -{ - MEDCouplingUMesh *m1=build2DTargetMesh_1(); - MEDCouplingUMesh *m2=build2DTargetMesh_1(); - const double vec[2]={0.002,0.}; - m2->translate(vec); - // - std::vector tmp(2); - tmp[0]=m1; - tmp[1]=m2; - MEDCouplingUMesh *m3=MEDCouplingUMesh::MergeUMeshes(tmp); - bool b; - int newNbOfNodes; - DataArrayInt *da=m3->mergeNodes2(0.01,b,newNbOfNodes); - CPPUNIT_ASSERT_EQUAL(9,m3->getNumberOfNodes()); - const double expected1[18]={-0.299,-0.3, 0.201,-0.3, 0.701,-0.3, -0.299,0.2, 0.201,0.2, 0.701,0.2, -0.299,0.7, 0.201,0.7, 0.701,0.7}; - for(int i=0;i<18;i++) - CPPUNIT_ASSERT_DOUBLES_EQUAL(expected1[i],m3->getCoords()->getIJ(0,i),1e-13); - // - da->decrRef(); - m3->decrRef(); - m1->decrRef(); - m2->decrRef(); -} - -void MEDCouplingBasicsTest3::testMergeField2() -{ - MEDCouplingUMesh *m=build2DTargetMesh_1(); - MEDCouplingFieldDouble *f1=MEDCouplingFieldDouble::New(ON_CELLS,ONE_TIME); - f1->setMesh(m); - DataArrayDouble *arr=DataArrayDouble::New(); - arr->alloc(5,2); - arr->fillWithValue(2.); - f1->setArray(arr); - arr->decrRef(); - MEDCouplingFieldDouble *f2=MEDCouplingFieldDouble::New(ON_CELLS,ONE_TIME); - f2->setMesh(m); - arr=DataArrayDouble::New(); - arr->alloc(5,2); - arr->fillWithValue(5.); - f2->setArray(arr); - arr->decrRef(); - MEDCouplingFieldDouble *f3=MEDCouplingFieldDouble::New(ON_CELLS,ONE_TIME); - f3->setMesh(m); - arr=DataArrayDouble::New(); - arr->alloc(5,2); - arr->fillWithValue(7.); - f3->setArray(arr); - arr->decrRef(); - // - std::vector tmp(3); - tmp[0]=f1; tmp[1]=f2; tmp[2]=f3; - MEDCouplingFieldDouble *f4=MEDCouplingFieldDouble::MergeFields(tmp); - CPPUNIT_ASSERT_EQUAL(15,f4->getMesh()->getNumberOfCells()); - const double expected1[30]={2.,2.,2.,2.,2.,2.,2.,2.,2.,2., 5.,5.,5.,5.,5.,5.,5.,5.,5.,5., 7.,7.,7.,7.,7.,7.,7.,7.,7.,7.}; - for(int i=0;i<30;i++) - CPPUNIT_ASSERT_DOUBLES_EQUAL(expected1[i],f4->getIJ(0,i),1.e-13); - // - f4->decrRef(); - f1->decrRef(); - f2->decrRef(); - f3->decrRef(); - m->decrRef(); -} - -void MEDCouplingBasicsTest3::testDAIBuildComplement1() -{ - DataArrayInt *a=DataArrayInt::New(); - const int tab[4]={3,1,7,8}; - a->alloc(4,1); - std::copy(tab,tab+4,a->getPointer()); - DataArrayInt *b=a->buildComplement(12); - CPPUNIT_ASSERT_EQUAL(8,b->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(1,b->getNumberOfComponents()); - const int expected1[8]={0,2,4,5,6,9,10,11}; - for(int i=0;i<8;i++) - CPPUNIT_ASSERT_EQUAL(expected1[i],b->getIJ(0,i)); - b->decrRef(); - a->decrRef(); -} - -void MEDCouplingBasicsTest3::testDAIBuildUnion1() -{ - DataArrayInt *a=DataArrayInt::New(); - const int tab1[4]={3,1,7,8}; - a->alloc(4,1); - std::copy(tab1,tab1+4,a->getPointer()); - DataArrayInt *c=DataArrayInt::New(); - const int tab2[5]={5,3,0,18,8}; - c->alloc(5,1); - std::copy(tab2,tab2+5,c->getPointer()); - DataArrayInt *b=a->buildUnion(c); - CPPUNIT_ASSERT_EQUAL(7,b->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(1,b->getNumberOfComponents()); - const int expected1[7]={0,1,3,5,7,8,18}; - for(int i=0;i<7;i++) - CPPUNIT_ASSERT_EQUAL(expected1[i],b->getIJ(0,i)); - c->decrRef(); - b->decrRef(); - a->decrRef(); -} - -void MEDCouplingBasicsTest3::testDAIBuildIntersection1() -{ - DataArrayInt *a=DataArrayInt::New(); - const int tab1[4]={3,1,7,8}; - a->alloc(4,1); - std::copy(tab1,tab1+4,a->getPointer()); - DataArrayInt *c=DataArrayInt::New(); - const int tab2[5]={5,3,0,18,8}; - c->alloc(5,1); - std::copy(tab2,tab2+5,c->getPointer()); - DataArrayInt *b=a->buildIntersection(c); - CPPUNIT_ASSERT_EQUAL(2,b->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(1,b->getNumberOfComponents()); - const int expected1[2]={3,8}; - for(int i=0;i<2;i++) - CPPUNIT_ASSERT_EQUAL(expected1[i],b->getIJ(0,i)); - c->decrRef(); - b->decrRef(); - a->decrRef(); -} - -void MEDCouplingBasicsTest3::testDAIDeltaShiftIndex1() -{ - DataArrayInt *a=DataArrayInt::New(); - const int tab[7]={1,3,6,7,7,9,15}; - a->alloc(7,1); - std::copy(tab,tab+7,a->getPointer()); - DataArrayInt *b=a->deltaShiftIndex(); - CPPUNIT_ASSERT_EQUAL(6,b->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(1,b->getNumberOfComponents()); - const int expected1[6]={2,3,1,0,2,6}; - for(int i=0;i<6;i++) - CPPUNIT_ASSERT_EQUAL(expected1[i],b->getIJ(0,i)); - b->decrRef(); - a->decrRef(); -} - -void MEDCouplingBasicsTest3::testDaDoubleSelectByTupleIdSafe1() -{ - DataArrayDouble *a=DataArrayDouble::New(); - a->alloc(7,2); - a->setInfoOnComponent(0,"toto"); - a->setInfoOnComponent(1,"tata"); - const double arr1[14]={1.1,11.1,2.1,12.1,3.1,13.1,4.1,14.1,5.1,15.1,6.1,16.1,7.1,17.1}; - std::copy(arr1,arr1+14,a->getPointer()); - // - const int arr2[7]={4,2,0,6,5}; - DataArrayDouble *b=a->selectByTupleIdSafe(arr2,arr2+5); - CPPUNIT_ASSERT_EQUAL(5,b->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(2,b->getNumberOfComponents()); - CPPUNIT_ASSERT(std::string(b->getInfoOnComponent(0))=="toto"); - CPPUNIT_ASSERT(std::string(b->getInfoOnComponent(1))=="tata"); - const double expected1[10]={5.1,15.1,3.1,13.1,1.1,11.1,7.1,17.1,6.1,16.1}; - for(int i=0;i<10;i++) - CPPUNIT_ASSERT_DOUBLES_EQUAL(expected1[i],b->getIJ(0,i),1e-14); - const int arr4[5]={4,-1,0,6,5}; - CPPUNIT_ASSERT_THROW(a->selectByTupleIdSafe(arr4,arr4+5),INTERP_KERNEL::Exception); - const int arr5[5]={4,2,0,6,7}; - CPPUNIT_ASSERT_THROW(a->selectByTupleIdSafe(arr5,arr5+5),INTERP_KERNEL::Exception); - b->decrRef(); - a->decrRef(); - // - DataArrayInt *c=DataArrayInt::New(); - c->alloc(7,2); - c->setInfoOnComponent(0,"toto"); - c->setInfoOnComponent(1,"tata"); - const int arr3[14]={1,11,2,12,3,13,4,14,5,15,6,16,7,17}; - std::copy(arr3,arr3+14,c->getPointer()); - DataArrayInt *d=c->selectByTupleIdSafe(arr2,arr2+5); - CPPUNIT_ASSERT_EQUAL(5,d->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(2,d->getNumberOfComponents()); - CPPUNIT_ASSERT(std::string(d->getInfoOnComponent(0))=="toto"); - CPPUNIT_ASSERT(std::string(d->getInfoOnComponent(1))=="tata"); - const int expected2[10]={5,15,3,13,1,11,7,17,6,16}; - for(int i=0;i<10;i++) - CPPUNIT_ASSERT_EQUAL(expected2[i],d->getIJ(0,i)); - CPPUNIT_ASSERT_THROW(c->selectByTupleIdSafe(arr4,arr4+5),INTERP_KERNEL::Exception); - CPPUNIT_ASSERT_THROW(c->selectByTupleIdSafe(arr5,arr5+5),INTERP_KERNEL::Exception); - c->decrRef(); - d->decrRef(); -} - -void MEDCouplingBasicsTest3::testAreCellsIncludedIn1() -{ - MEDCouplingUMesh *m=build3DSurfTargetMesh_1(); - const int pt[2]={1,3}; - MEDCouplingUMesh *m2=(MEDCouplingUMesh *)m->buildPartOfMySelf(pt,pt+2,true); - DataArrayInt *tmp; - CPPUNIT_ASSERT(m->areCellsIncludedIn(m2,0,tmp)); - CPPUNIT_ASSERT_EQUAL(2,tmp->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(1,tmp->getNumberOfComponents()); - CPPUNIT_ASSERT_EQUAL(pt[0],tmp->getIJ(0,0)); - CPPUNIT_ASSERT_EQUAL(pt[1],tmp->getIJ(0,1)); - tmp->decrRef(); - CPPUNIT_ASSERT(!m2->areCellsIncludedIn(m,0,tmp)); - tmp->decrRef(); - m2->decrRef(); - m->decrRef(); -} - -void MEDCouplingBasicsTest3::testDAIBuildSubstraction1() -{ - DataArrayInt *a=DataArrayInt::New(); - const int aa[]={2,3,6,8,9}; - a->alloc(5,1); - std::copy(aa,aa+5,a->getPointer()); - DataArrayInt *b=DataArrayInt::New(); - const int bb[]={1,3,5,9,11}; - b->alloc(5,1); - std::copy(bb,bb+5,b->getPointer()); - // - DataArrayInt *c=a->buildSubstraction(b); - CPPUNIT_ASSERT_EQUAL(3,c->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(1,c->getNumberOfComponents()); - const int expected1[3]={2,6,8}; - CPPUNIT_ASSERT(std::equal(expected1,expected1+3,c->getConstPointer())); - // - c->decrRef(); - b->decrRef(); - a->decrRef(); -} - -void MEDCouplingBasicsTest3::testBuildOrthogonalField2() -{ - MEDCouplingUMesh *m=build2DTargetMesh_1(); - DataArrayInt *d1=DataArrayInt::New(); - DataArrayInt *d2=DataArrayInt::New(); - DataArrayInt *d3=DataArrayInt::New(); - DataArrayInt *d4=DataArrayInt::New(); - MEDCouplingUMesh *m1=m->buildDescendingConnectivity(d1,d2,d3,d4); - // - MEDCouplingFieldDouble *f1=m1->buildOrthogonalField(); - DataArrayDouble *da1=f1->getArray(); - CPPUNIT_ASSERT_EQUAL(2,da1->getNumberOfComponents()); - CPPUNIT_ASSERT_EQUAL(13,da1->getNumberOfTuples()); - // - const double expected1[26]={-1.,0.,0.,1.,1.,0.,0.,-1.,0.707106781186548,0.707106781186548,0.,-1.,0.,1.,1.,0.,0.,1.,1.,0.,-1.,0.,0.,1.,1.,0.}; - for(int i=0;i<26;i++) - CPPUNIT_ASSERT_DOUBLES_EQUAL(expected1[i],da1->getIJ(0,i),1e-14); - // - f1->decrRef(); - m1->decrRef(); - d1->decrRef(); - d2->decrRef(); - d3->decrRef(); - d4->decrRef(); - m->decrRef(); -} - -void MEDCouplingBasicsTest3::testUMInsertNextCell1() -{ - double targetCoords[18]={-0.3,-0.3, 0.2,-0.3, 0.7,-0.3, -0.3,0.2, 0.2,0.2, 0.7,0.2, -0.3,0.7, 0.2,0.7, 0.7,0.7 }; - int targetConn[18]={0,3,4,1, 1,4,2, 4,5,2, 6,7,4,3, 7,8,5,4}; - MEDCouplingUMesh *targetMesh=MEDCouplingUMesh::New(); - targetMesh->allocateCells(5); - CPPUNIT_ASSERT_THROW(targetMesh->insertNextCell(INTERP_KERNEL::NORM_QUAD4,4,targetConn),INTERP_KERNEL::Exception); - targetMesh->setMeshDimension(2); - targetMesh->insertNextCell(INTERP_KERNEL::NORM_QUAD4,4,targetConn); - CPPUNIT_ASSERT_THROW(targetMesh->insertNextCell(INTERP_KERNEL::NORM_TETRA4,4,targetConn),INTERP_KERNEL::Exception); - CPPUNIT_ASSERT_THROW(targetMesh->insertNextCell(INTERP_KERNEL::NORM_SEG2,2,targetConn),INTERP_KERNEL::Exception); - CPPUNIT_ASSERT_THROW(targetMesh->insertNextCell(INTERP_KERNEL::NORM_POINT1,1,targetConn),INTERP_KERNEL::Exception); - targetMesh->insertNextCell(INTERP_KERNEL::NORM_TRI3,3,targetConn+4); - targetMesh->insertNextCell(INTERP_KERNEL::NORM_TRI3,3,targetConn+7); - targetMesh->insertNextCell(INTERP_KERNEL::NORM_QUAD4,4,targetConn+10); - targetMesh->insertNextCell(INTERP_KERNEL::NORM_QUAD4,4,targetConn+14); - targetMesh->finishInsertingCells(); - DataArrayDouble *myCoords=DataArrayDouble::New(); - myCoords->alloc(9,2); - std::copy(targetCoords,targetCoords+18,myCoords->getPointer()); - targetMesh->setCoords(myCoords); - myCoords->decrRef(); - targetMesh->checkCoherency(); - targetMesh->decrRef(); -} - -void MEDCouplingBasicsTest3::testFieldOperatorDivDiffComp1() -{ - MEDCouplingUMesh *m=build2DTargetMesh_1(); - DataArrayInt *d1=DataArrayInt::New(); - DataArrayInt *d2=DataArrayInt::New(); - DataArrayInt *d3=DataArrayInt::New(); - DataArrayInt *d4=DataArrayInt::New(); - MEDCouplingUMesh *m1=m->buildDescendingConnectivity(d1,d2,d3,d4); - // - MEDCouplingFieldDouble *f1=m1->buildOrthogonalField(); - const double arr1[13]={2.,3.,4.,5.,6.,7.,8.,9.,10.,11.,12.,13.,14.}; - DataArrayDouble *arr=DataArrayDouble::New(); - arr->alloc(13,1); - std::copy(arr1,arr1+13,arr->getPointer()); - MEDCouplingFieldDouble *f2=MEDCouplingFieldDouble::New(ON_CELLS); - f2->setArray(arr); - f2->setMesh(m1); - f2->checkCoherency(); - // - MEDCouplingFieldDouble *f3=(*f1)/(*f2); - CPPUNIT_ASSERT_THROW((*f2)/(*f1),INTERP_KERNEL::Exception); - f3->checkCoherency(); - (*f1)/=(*f2); - CPPUNIT_ASSERT(f1->isEqual(f3,1e-10,1e-10)); - CPPUNIT_ASSERT_THROW((*f2)/=(*f1),INTERP_KERNEL::Exception); - const double expected1[26]={-0.5, 0.0, 0.0, 0.33333333333333331, 0.25, 0.0, 0.0, -0.20000000000000001, 0.117851130197758, 0.117851130197758, 0.0, -0.14285714285714285, 0.0, 0.125, 0.1111111111111111, 0.0, 0.0, 0.10000000000000001, 0.090909090909090912, 0.0, -0.083333333333333329, 0.0, 0.0, 0.076923076923076927, 0.071428571428571425, 0.0}; - for(int i=0;i<26;i++) - CPPUNIT_ASSERT_DOUBLES_EQUAL(expected1[i],f3->getIJ(0,i),1e-10); - // - f3->decrRef(); - f2->decrRef(); - arr->decrRef(); - f1->decrRef(); - m1->decrRef(); - d1->decrRef(); - d2->decrRef(); - d3->decrRef(); - d4->decrRef(); - m->decrRef(); -} - -void MEDCouplingBasicsTest3::testDARearrange1() -{ - DataArrayInt *da1=DataArrayInt::New(); - da1->alloc(12,1); - da1->iota(0); - const int *ptr=da1->getConstPointer(); - // - CPPUNIT_ASSERT_EQUAL((std::size_t)12,da1->getNbOfElems()); - CPPUNIT_ASSERT_EQUAL(1,da1->getNumberOfComponents()); - CPPUNIT_ASSERT_EQUAL(12,da1->getNumberOfTuples()); - da1->rearrange(4); - CPPUNIT_ASSERT(ptr==da1->getConstPointer()); - CPPUNIT_ASSERT_EQUAL((std::size_t)12,da1->getNbOfElems()); - CPPUNIT_ASSERT_EQUAL(4,da1->getNumberOfComponents()); - CPPUNIT_ASSERT_EQUAL(3,da1->getNumberOfTuples()); - for(int i=0;i<12;i++) - CPPUNIT_ASSERT_EQUAL(i,da1->getIJ(0,i)); - // - da1->rearrange(6); - CPPUNIT_ASSERT(ptr==da1->getConstPointer()); - CPPUNIT_ASSERT_EQUAL((std::size_t)12,da1->getNbOfElems()); - CPPUNIT_ASSERT_EQUAL(6,da1->getNumberOfComponents()); - CPPUNIT_ASSERT_EQUAL(2,da1->getNumberOfTuples()); - for(int i=0;i<12;i++) - CPPUNIT_ASSERT_EQUAL(i,da1->getIJ(0,i)); - // - CPPUNIT_ASSERT_THROW(da1->rearrange(7),INTERP_KERNEL::Exception); - // - da1->rearrange(12); - CPPUNIT_ASSERT(ptr==da1->getConstPointer()); - CPPUNIT_ASSERT_EQUAL((std::size_t)12,da1->getNbOfElems()); - CPPUNIT_ASSERT_EQUAL(12,da1->getNumberOfComponents()); - CPPUNIT_ASSERT_EQUAL(1,da1->getNumberOfTuples()); - for(int i=0;i<12;i++) - CPPUNIT_ASSERT_EQUAL(i,da1->getIJ(0,i)); - // - da1->rearrange(3); - CPPUNIT_ASSERT(ptr==da1->getConstPointer()); - CPPUNIT_ASSERT_EQUAL((std::size_t)12,da1->getNbOfElems()); - CPPUNIT_ASSERT_EQUAL(3,da1->getNumberOfComponents()); - CPPUNIT_ASSERT_EQUAL(4,da1->getNumberOfTuples()); - for(int i=0;i<12;i++) - CPPUNIT_ASSERT_EQUAL(i,da1->getIJ(0,i)); - //double - DataArrayDouble *da2=da1->convertToDblArr(); - da1->decrRef(); - const double *ptr2=da2->getConstPointer(); - // - CPPUNIT_ASSERT_EQUAL((std::size_t)12,da2->getNbOfElems()); - CPPUNIT_ASSERT_EQUAL(3,da2->getNumberOfComponents()); - CPPUNIT_ASSERT_EQUAL(4,da2->getNumberOfTuples()); - da2->rearrange(4); - CPPUNIT_ASSERT(ptr2==da2->getConstPointer()); - CPPUNIT_ASSERT_EQUAL((std::size_t)12,da2->getNbOfElems()); - CPPUNIT_ASSERT_EQUAL(4,da2->getNumberOfComponents()); - CPPUNIT_ASSERT_EQUAL(3,da2->getNumberOfTuples()); - for(int i=0;i<12;i++) - CPPUNIT_ASSERT_DOUBLES_EQUAL((double)i,da2->getIJ(0,i),1e-14); - // - da2->rearrange(6); - CPPUNIT_ASSERT(ptr2==da2->getConstPointer()); - CPPUNIT_ASSERT_EQUAL((std::size_t)12,da2->getNbOfElems()); - CPPUNIT_ASSERT_EQUAL(6,da2->getNumberOfComponents()); - CPPUNIT_ASSERT_EQUAL(2,da2->getNumberOfTuples()); - for(int i=0;i<12;i++) - CPPUNIT_ASSERT_DOUBLES_EQUAL((double)i,da2->getIJ(0,i),1e-14); - // - CPPUNIT_ASSERT_THROW(da2->rearrange(7),INTERP_KERNEL::Exception); - // - da2->rearrange(1); - CPPUNIT_ASSERT(ptr2==da2->getConstPointer()); - CPPUNIT_ASSERT_EQUAL((std::size_t)12,da2->getNbOfElems()); - CPPUNIT_ASSERT_EQUAL(1,da2->getNumberOfComponents()); - CPPUNIT_ASSERT_EQUAL(12,da2->getNumberOfTuples()); - for(int i=0;i<12;i++) - CPPUNIT_ASSERT_DOUBLES_EQUAL((double)i,da2->getIJ(0,i),1e-14); - // - da2->rearrange(3); - CPPUNIT_ASSERT(ptr2==da2->getConstPointer()); - CPPUNIT_ASSERT_EQUAL((std::size_t)12,da2->getNbOfElems()); - CPPUNIT_ASSERT_EQUAL(3,da2->getNumberOfComponents()); - CPPUNIT_ASSERT_EQUAL(4,da2->getNumberOfTuples()); - for(int i=0;i<12;i++) - CPPUNIT_ASSERT_DOUBLES_EQUAL((double)i,da2->getIJ(0,i),1e-14); - da2->decrRef(); -} - -void MEDCouplingBasicsTest3::testGetDifferentValues1() -{ - DataArrayInt *da1=DataArrayInt::New(); - const int arr[12]={1,2,3,2,2,3,5,1,5,5,2,2}; - da1->alloc(4,3); - std::copy(arr,arr+12,da1->getPointer()); - DataArrayInt *s=da1->getDifferentValues(); - const int expected1[4]={1,2,3,5}; - CPPUNIT_ASSERT_EQUAL(4,s->getNumberOfTuples()); - CPPUNIT_ASSERT(std::equal(expected1,expected1+4,s->begin())); - da1->decrRef(); - s->decrRef(); -} - -void MEDCouplingBasicsTest3::testDAIBuildPermutationArr1() -{ - DataArrayInt *a=DataArrayInt::New(); - const int vala[5]={4,5,6,7,8}; - a->alloc(5,1); - std::copy(vala,vala+5,a->getPointer()); - DataArrayInt *b=DataArrayInt::New(); - const int valb[5]={5,4,8,6,7}; - b->alloc(5,1); - std::copy(valb,valb+5,b->getPointer()); - DataArrayInt *c=a->buildPermutationArr(*b); - const int expect1[5]={1,0,4,2,3}; - CPPUNIT_ASSERT_EQUAL(5,c->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(1,c->getNumberOfComponents()); - CPPUNIT_ASSERT(std::equal(expect1,expect1+5,c->getConstPointer())); - CPPUNIT_ASSERT(a->isEqualWithoutConsideringStrAndOrder(*b)); - b->setIJ(0,0,9); - CPPUNIT_ASSERT(!a->isEqualWithoutConsideringStrAndOrder(*b)); - CPPUNIT_ASSERT_THROW(a->buildPermutationArr(*b),INTERP_KERNEL::Exception); - a->setIJ(3,0,4); - b->setIJ(0,0,5); - b->setIJ(4,0,4);//;a==[4,5,6,4,8] and b==[5,4,8,6,4] - CPPUNIT_ASSERT(a->isEqualWithoutConsideringStrAndOrder(*b)); - c->decrRef(); - c=a->buildPermutationArr(*b); - const int expect2[5]={1,3,4,2,3}; - CPPUNIT_ASSERT(std::equal(expect2,expect2+5,c->getConstPointer())); - DataArrayDouble *d=b->convertToDblArr(); - b->sort(); - const int expect3[5]={4,4,5,6,8}; - CPPUNIT_ASSERT(std::equal(expect3,expect3+5,b->getConstPointer())); - d->sort(); - CPPUNIT_ASSERT_EQUAL(5,d->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(1,d->getNumberOfComponents()); - for(int i=0;i<5;i++) - CPPUNIT_ASSERT_DOUBLES_EQUAL(double(expect3[i]),d->getIJ(i,0),1e-14); - // - d->decrRef(); - c->decrRef(); - a->decrRef(); - b->decrRef(); -} - -void MEDCouplingBasicsTest3::testAreCellsIncludedIn2() -{ - const char myName[]="Vitoo"; - MEDCouplingUMesh *m=build3DSurfTargetMesh_1(); - MEDCouplingUMesh *m2=(MEDCouplingUMesh *)m->buildPartOfMySelf(0,0,true); - CPPUNIT_ASSERT_EQUAL(0,m2->getNumberOfCells()); - CPPUNIT_ASSERT_EQUAL(3,m2->getSpaceDimension()); - CPPUNIT_ASSERT_EQUAL(2,m2->getMeshDimension()); - m2->setName(myName); - DataArrayInt *tmp; - CPPUNIT_ASSERT(m->areCellsIncludedIn(m2,0,tmp)); - CPPUNIT_ASSERT(std::string(myName)==tmp->getName()); - CPPUNIT_ASSERT_EQUAL(0,tmp->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(1,tmp->getNumberOfComponents()); - m->decrRef(); - m2->decrRef(); - tmp->decrRef(); -} - -void MEDCouplingBasicsTest3::testUMeshGetPartBarycenterAndOwner1() -{ - MEDCouplingUMesh *m1=build2DTargetMesh_1(); - const int part[3]={1,0,4}; - DataArrayDouble *b=m1->getPartBarycenterAndOwner(part,part+3); - CPPUNIT_ASSERT_EQUAL(2,b->getNumberOfComponents()); - CPPUNIT_ASSERT_EQUAL(3,b->getNumberOfTuples()); - const double expected1[6]={0.36666666666666665,-0.13333333333333333,-0.05,-0.05,0.45,0.45}; - for(int i=0;i<6;i++) - CPPUNIT_ASSERT_DOUBLES_EQUAL(expected1[i],b->getIJ(0,i),1e-14); - b->decrRef(); - m1->decrRef(); -} - -void MEDCouplingBasicsTest3::testUMeshGetPartMeasureField1() -{ - MEDCouplingUMesh *m1=build2DTargetMesh_1(); - const int part[3]={1,0,4}; - DataArrayDouble *b=m1->getPartMeasureField(true,part,part+3); - CPPUNIT_ASSERT_EQUAL(1,b->getNumberOfComponents()); - CPPUNIT_ASSERT_EQUAL(3,b->getNumberOfTuples()); - const double expected1[3]={0.125,0.25,0.25}; - for(int i=0;i<3;i++) - CPPUNIT_ASSERT_DOUBLES_EQUAL(expected1[i],b->getIJ(0,i),1e-14); - b->decrRef(); - m1->decrRef(); -} - -void MEDCouplingBasicsTest3::testUMeshBuildPartOrthogonalField1() -{ - MEDCouplingUMesh *m1=build2DTargetMesh_1(); - m1->changeSpaceDimension(3); - const int part[3]={1,0,4}; - MEDCouplingFieldDouble *b=m1->buildPartOrthogonalField(part,part+3); - CPPUNIT_ASSERT_EQUAL(3,b->getArray()->getNumberOfComponents()); - CPPUNIT_ASSERT_EQUAL(3,b->getArray()->getNumberOfTuples()); - const double expected1[9]={0.,0.,-1.,0.,0.,-1.,0.,0.,-1.}; - for(int i=0;i<9;i++) - CPPUNIT_ASSERT_DOUBLES_EQUAL(expected1[i],b->getArray()->getIJ(0,i),1e-14); - b->decrRef(); - m1->decrRef(); -} - -void MEDCouplingBasicsTest3::testUMeshGetTypesOfPart1() -{ - MEDCouplingUMesh *m1=build2DTargetMesh_1(); - const int part1[]={0,3,4}; - std::set s; - s=m1->getTypesOfPart(part1,part1+3); - CPPUNIT_ASSERT(s.size()==1); - CPPUNIT_ASSERT(*s.begin()==INTERP_KERNEL::NORM_QUAD4); - const int part2[]={2,2,2,1}; - s=m1->getTypesOfPart(part2,part2+4); - CPPUNIT_ASSERT(s.size()==1); - CPPUNIT_ASSERT(*s.begin()==INTERP_KERNEL::NORM_TRI3); - const int part3[]={3,2,1}; - s=m1->getTypesOfPart(part3,part3+3); - CPPUNIT_ASSERT(s.size()==2); - CPPUNIT_ASSERT(*s.begin()==INTERP_KERNEL::NORM_TRI3); - CPPUNIT_ASSERT(*(++s.begin())==INTERP_KERNEL::NORM_QUAD4); - m1->decrRef(); -} - -void MEDCouplingBasicsTest3::testUMeshKeepCellIdsByType1() -{ - MEDCouplingUMesh *m1=build2DTargetMesh_1(); - const int part1[3]={0,3,4}; - DataArrayInt *a=m1->keepCellIdsByType(INTERP_KERNEL::NORM_TRI3,part1,part1+3); - CPPUNIT_ASSERT_EQUAL(1,a->getNumberOfComponents()); - CPPUNIT_ASSERT_EQUAL(0,a->getNumberOfTuples()); - a->decrRef(); - // - const int part2[5]={3,2,0,2,4}; - a=m1->keepCellIdsByType(INTERP_KERNEL::NORM_TRI3,part2,part2+5); - CPPUNIT_ASSERT_EQUAL(1,a->getNumberOfComponents()); - CPPUNIT_ASSERT_EQUAL(2,a->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(2,a->getIJ(0,0)); - CPPUNIT_ASSERT_EQUAL(2,a->getIJ(1,0)); - a->decrRef(); - // - a=m1->keepCellIdsByType(INTERP_KERNEL::NORM_QUAD4,part2,part2+5); - CPPUNIT_ASSERT_EQUAL(1,a->getNumberOfComponents()); - CPPUNIT_ASSERT_EQUAL(3,a->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(3,a->getIJ(0,0)); - CPPUNIT_ASSERT_EQUAL(0,a->getIJ(1,0)); - CPPUNIT_ASSERT_EQUAL(4,a->getIJ(2,0)); - // - a->decrRef(); - m1->decrRef(); -} - -void MEDCouplingBasicsTest3::testDAIAggregateMulti1() -{ - DataArrayInt *a=DataArrayInt::New(); - a->setName("aa"); - a->alloc(4,1); - a->iota(0); - a->rearrange(2); - DataArrayInt *b=DataArrayInt::New(); - b->setName("bb"); - b->alloc(6,1); - b->iota(0); - b->rearrange(2); - // - std::vector v(2); - v[0]=a; v[1]=b; - DataArrayInt *c=DataArrayInt::Aggregate(v); - CPPUNIT_ASSERT_EQUAL(5,c->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(2,c->getNumberOfComponents()); - CPPUNIT_ASSERT(c->getName()=="aa"); - const int expect1[10]={0,1,2,3,0,1,2,3,4,5}; - for(int i=0;i<10;i++) - CPPUNIT_ASSERT_EQUAL(expect1[i],c->getIJ(0,i)); - // - c->decrRef(); - a->decrRef(); - b->decrRef(); -} - -void MEDCouplingBasicsTest3::testMergeUMeshes2() -{ - MEDCouplingUMesh *m1=build3DSurfTargetMesh_1(); - MEDCouplingUMesh *m2=build3DSurfTargetMesh_1(); - MEDCouplingUMesh *m3=build3DSurfTargetMesh_1(); - // - const int vec1[3]={0,2,3}; - MEDCouplingUMesh *m2_2=(MEDCouplingUMesh *)m2->buildPartOfMySelf(vec1,vec1+3,false); - const int vec2[2]={1,1}; - MEDCouplingUMesh *m3_2=(MEDCouplingUMesh *)m3->buildPartOfMySelf(vec2,vec2+2,false); - // - std::vector ms(3); - std::vector ms2(3); - ms[0]=m1; ms[1]=m2_2; ms[2]=m3_2; - ms2[0]=m1; ms2[1]=m2_2; ms2[2]=m3_2; - // - MEDCouplingUMesh *m4=MEDCouplingUMesh::MergeUMeshes(ms); - m4->checkCoherency(); - CPPUNIT_ASSERT_EQUAL(10,m4->getNumberOfCells()); - CPPUNIT_ASSERT_EQUAL(20,m4->getNumberOfNodes()); - CPPUNIT_ASSERT_EQUAL(45,m4->getMeshLength()); - // - MEDCouplingMesh *m4bis=MEDCouplingMesh::MergeMeshes(ms2); - CPPUNIT_ASSERT(m4->isEqual(m4bis,1e-12)); - m4bis->decrRef(); - // - const int vec3[5]={0,1,2,3,4}; - MEDCouplingUMesh *m4_1=(MEDCouplingUMesh *)m4->buildPartOfMySelf(vec3,vec3+5,false); - m4_1->setName(m1->getName().c_str()); - CPPUNIT_ASSERT(m4_1->isEqual(m1,1e-12)); - m4_1->decrRef(); - // - const int vec4[3]={5,6,7}; - MEDCouplingUMesh *m4_2=(MEDCouplingUMesh *)m4->buildPartOfMySelf(vec4,vec4+3,false); - DataArrayInt *cellCor=0; - DataArrayInt *nodeCor=0; - m4_2->checkGeoEquivalWith(m2_2,10,1e-12,cellCor,nodeCor); - CPPUNIT_ASSERT(cellCor==0); - CPPUNIT_ASSERT(nodeCor==0); - m4_2->decrRef(); - // - const int vec5[2]={8,9}; - MEDCouplingUMesh *m4_3=(MEDCouplingUMesh *)m4->buildPartOfMySelf(vec5,vec5+2,false); - CPPUNIT_ASSERT_EQUAL(2,m4_3->getNumberOfCells()); - CPPUNIT_ASSERT_EQUAL(3,m4_3->getNumberOfNodes()); - m3_2->zipCoords(); - m4_3->setName(m3_2->getName().c_str()); - CPPUNIT_ASSERT(m4_3->isEqual(m3_2,1e-12)); - m4_3->decrRef(); - // - m4->decrRef(); - m1->decrRef(); - m2->decrRef(); - m2_2->decrRef(); - m3->decrRef(); - m3_2->decrRef(); -} - -void MEDCouplingBasicsTest3::testBuild0DMeshFromCoords1() -{ - const double sourceCoords[12]={-0.3,-0.3,0., 0.7,-0.3,0., -0.3,0.7,0., 0.7,0.7,0.}; - DataArrayDouble *coo=DataArrayDouble::New(); - coo->alloc(4,3); - coo->setName("My0D"); - std::copy(sourceCoords,sourceCoords+12,coo->getPointer()); - MEDCouplingUMesh *m=MEDCouplingUMesh::Build0DMeshFromCoords(coo); - m->checkCoherency(); - CPPUNIT_ASSERT_EQUAL(4,m->getNumberOfNodes()); - CPPUNIT_ASSERT_EQUAL(4,m->getNumberOfCells()); - CPPUNIT_ASSERT_EQUAL(3,m->getSpaceDimension()); - CPPUNIT_ASSERT_EQUAL(0,m->getMeshDimension()); - std::set types=m->getAllGeoTypes(); - CPPUNIT_ASSERT_EQUAL(1,(int)types.size()); - CPPUNIT_ASSERT_EQUAL(INTERP_KERNEL::NORM_POINT1,*types.begin()); - for(int i=0;i<4;i++) - { - std::vector conn; - m->getNodeIdsOfCell(i,conn); - CPPUNIT_ASSERT_EQUAL(1,(int)conn.size()); - CPPUNIT_ASSERT_EQUAL(i,conn[0]); - CPPUNIT_ASSERT(INTERP_KERNEL::NORM_POINT1==m->getTypeOfCell(i)); - } - CPPUNIT_ASSERT(std::string(m->getName())=="My0D"); - m->decrRef(); - coo->decrRef(); -} - diff --git a/src/MEDCoupling/Test/MEDCouplingBasicsTest3.hxx b/src/MEDCoupling/Test/MEDCouplingBasicsTest3.hxx deleted file mode 100644 index df3197d90..000000000 --- a/src/MEDCoupling/Test/MEDCouplingBasicsTest3.hxx +++ /dev/null @@ -1,162 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 -// 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 __MEDCOUPLINGBASICSTEST3_HXX__ -#define __MEDCOUPLINGBASICSTEST3_HXX__ - -#include "MEDCouplingBasicsTest.hxx" - -#include -#include - -namespace ParaMEDMEM -{ - class DataArrayDouble; - class MEDCouplingUMesh; - class MEDCouplingFieldDouble; - class MEDCouplingMultiFields; - - class MEDCouplingBasicsTest3 : public MEDCouplingBasicsTest - { - CPPUNIT_TEST_SUITE(MEDCouplingBasicsTest3); - CPPUNIT_TEST( testGetMeasureFieldCMesh1 ); - CPPUNIT_TEST( testFieldDoubleZipCoords1 ); - CPPUNIT_TEST( testFieldDoubleZipConnectivity1 ); - CPPUNIT_TEST( testDaDoubleRenumber1 ); - CPPUNIT_TEST( testDaDoubleRenumberAndReduce1 ); - CPPUNIT_TEST( testDaDoubleRenumberInPlace1 ); - CPPUNIT_TEST( testDaDoubleSelectByTupleId1 ); - CPPUNIT_TEST( testDaDoubleRenumberR1 ); - CPPUNIT_TEST( testDaDoubleRenumberInPlaceR1 ); - CPPUNIT_TEST( testDaDoubleGetMinMaxValues1 ); - CPPUNIT_TEST( testFieldDoubleGetMinMaxValues2 ); - CPPUNIT_TEST( testBuildUnstructuredCMesh1 ); - CPPUNIT_TEST( testDataArrayIntInvertO2NNO21 ); - CPPUNIT_TEST( testKeepSetSelectedComponent1 ); - CPPUNIT_TEST( testKeepSetSelectedComponent2 ); - CPPUNIT_TEST( testElementaryDAThrowAndSpecialCases ); - CPPUNIT_TEST( testDAIGetIdsEqual1 ); - CPPUNIT_TEST( testDAIGetIdsEqualList1 ); - CPPUNIT_TEST( testDAFromNoInterlace1 ); - CPPUNIT_TEST( testDAToNoInterlace1 ); - CPPUNIT_TEST( testDAIsUniform1 ); - CPPUNIT_TEST( testDADFromPolarToCart1 ); - CPPUNIT_TEST( testDADFromCylToCart1 ); - CPPUNIT_TEST( testDADFromSpherToCart1 ); - CPPUNIT_TEST( testUnPolyze1 ); - CPPUNIT_TEST( testConvertDegeneratedCells1 ); - CPPUNIT_TEST( testGetNodeIdsNearPoints1 ); - CPPUNIT_TEST( testFieldCopyTinyAttrFrom1 ); - CPPUNIT_TEST( testExtrudedMesh5 ); - CPPUNIT_TEST( testExtrudedMesh6 ); - CPPUNIT_TEST( testExtrudedMesh7 ); - CPPUNIT_TEST( testSimplexize1 ); - CPPUNIT_TEST( testSimplexize2 ); - CPPUNIT_TEST( testDAMeld1 ); - CPPUNIT_TEST( testFieldMeld1 ); - CPPUNIT_TEST( testMergeNodes2 ); - CPPUNIT_TEST( testMergeField2 ); - CPPUNIT_TEST( testDAIBuildComplement1 ); - CPPUNIT_TEST( testDAIBuildUnion1 ); - CPPUNIT_TEST( testDAIBuildIntersection1 ); - CPPUNIT_TEST( testDAIDeltaShiftIndex1 ); - CPPUNIT_TEST( testDaDoubleSelectByTupleIdSafe1 ); - CPPUNIT_TEST( testAreCellsIncludedIn1 ); - CPPUNIT_TEST( testDAIBuildSubstraction1 ); - CPPUNIT_TEST( testBuildOrthogonalField2 ); - CPPUNIT_TEST( testUMInsertNextCell1 ); - CPPUNIT_TEST( testFieldOperatorDivDiffComp1 ); - CPPUNIT_TEST( testDARearrange1 ); - CPPUNIT_TEST( testGetDifferentValues1 ); - CPPUNIT_TEST( testDAIBuildPermutationArr1 ); - CPPUNIT_TEST( testAreCellsIncludedIn2 ); - CPPUNIT_TEST( testUMeshGetPartBarycenterAndOwner1 ); - CPPUNIT_TEST( testUMeshGetPartMeasureField1 ); - CPPUNIT_TEST( testUMeshBuildPartOrthogonalField1 ); - CPPUNIT_TEST( testUMeshGetTypesOfPart1 ); - CPPUNIT_TEST( testUMeshKeepCellIdsByType1 ); - CPPUNIT_TEST( testDAIAggregateMulti1 ); - CPPUNIT_TEST( testMergeUMeshes2 ); - CPPUNIT_TEST( testBuild0DMeshFromCoords1 ); - CPPUNIT_TEST_SUITE_END(); - public: - void testGetMeasureFieldCMesh1(); - void testFieldDoubleZipCoords1(); - void testFieldDoubleZipConnectivity1(); - void testDaDoubleRenumber1(); - void testDaDoubleRenumberAndReduce1(); - void testDaDoubleRenumberInPlace1(); - void testDaDoubleSelectByTupleId1(); - void testDaDoubleRenumberR1(); - void testDaDoubleRenumberInPlaceR1(); - void testDaDoubleGetMinMaxValues1(); - void testFieldDoubleGetMinMaxValues2(); - void testBuildUnstructuredCMesh1(); - void testDataArrayIntInvertO2NNO21(); - void testKeepSetSelectedComponent1(); - void testKeepSetSelectedComponent2(); - void testElementaryDAThrowAndSpecialCases(); - void testDAIGetIdsEqual1(); - void testDAIGetIdsEqualList1(); - void testDAFromNoInterlace1(); - void testDAToNoInterlace1(); - void testDAIsUniform1(); - void testDADFromPolarToCart1(); - void testDADFromCylToCart1(); - void testDADFromSpherToCart1(); - void testUnPolyze1(); - void testConvertDegeneratedCells1(); - void testGetNodeIdsNearPoints1(); - void testFieldCopyTinyAttrFrom1(); - void testExtrudedMesh5(); - void testExtrudedMesh6(); - void testExtrudedMesh7(); - void testSimplexize1(); - void testSimplexize2(); - void testDAMeld1(); - void testFieldMeld1(); - void testMergeNodes2(); - void testMergeField2(); - void testDAIBuildComplement1(); - void testDAIBuildUnion1(); - void testDAIBuildIntersection1(); - void testDAIDeltaShiftIndex1(); - void testDaDoubleSelectByTupleIdSafe1(); - void testAreCellsIncludedIn1(); - void testDAIBuildSubstraction1(); - void testBuildOrthogonalField2(); - void testUMInsertNextCell1(); - void testFieldOperatorDivDiffComp1(); - void testDARearrange1(); - void testGetDifferentValues1(); - void testDAIBuildPermutationArr1(); - void testAreCellsIncludedIn2(); - void testUMeshGetPartBarycenterAndOwner1(); - void testUMeshGetPartMeasureField1(); - void testUMeshBuildPartOrthogonalField1(); - void testUMeshGetTypesOfPart1(); - void testUMeshKeepCellIdsByType1(); - void testDAIAggregateMulti1(); - void testMergeUMeshes2(); - void testBuild0DMeshFromCoords1(); - }; -} - -#endif diff --git a/src/MEDCoupling/Test/MEDCouplingBasicsTest4.cxx b/src/MEDCoupling/Test/MEDCouplingBasicsTest4.cxx deleted file mode 100644 index 8b547fe08..000000000 --- a/src/MEDCoupling/Test/MEDCouplingBasicsTest4.cxx +++ /dev/null @@ -1,2223 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 -// 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 "MEDCouplingBasicsTest4.hxx" -#include "MEDCouplingUMesh.hxx" -#include "MEDCouplingCMesh.hxx" -#include "MEDCouplingExtrudedMesh.hxx" -#include "MEDCouplingFieldDouble.hxx" -#include "MEDCouplingMemArray.hxx" -#include "MEDCouplingGaussLocalization.hxx" -#include "MEDCouplingMultiFields.hxx" -#include "MEDCouplingFieldOverTime.hxx" - -#include -#include -#include - -using namespace ParaMEDMEM; - -void MEDCouplingBasicsTest4::testDescriptionInMeshTimeUnit1() -{ - static const char text1[]="totoTTEDD"; - MEDCouplingUMesh *m=build2DTargetMesh_1(); - m->setDescription(text1); - CPPUNIT_ASSERT(std::string(m->getDescription())==text1); - MEDCouplingUMesh *m2=(MEDCouplingUMesh *)m->deepCpy(); - CPPUNIT_ASSERT(m->isEqual(m2,1e-12)); - CPPUNIT_ASSERT(std::string(m2->getDescription())==text1); - m2->setDescription("ggg"); - CPPUNIT_ASSERT(!m->isEqual(m2,1e-12)); - m2->decrRef(); - // - MEDCouplingFieldDouble *f=MEDCouplingFieldDouble::New(ON_CELLS,ONE_TIME); - f->setTimeUnit(text1); - CPPUNIT_ASSERT(std::string(f->getTimeUnit())==text1); - MEDCouplingFieldDouble *f2=f->deepCpy(); - CPPUNIT_ASSERT(std::string(f2->getTimeUnit())==text1); - f2->decrRef(); - // - f->decrRef(); - m->decrRef(); -} - -void MEDCouplingBasicsTest4::testMultiFields1() -{ - MEDCouplingMultiFields *mfs=buildMultiFields_1(); - std::vector ms=mfs->getMeshes(); - std::vector refs; - std::vector dms=mfs->getDifferentMeshes(refs); - std::vector das=mfs->getArrays(); - std::vector< std::vector > refs2; - std::vector das2=mfs->getDifferentArrays(refs2); - // - CPPUNIT_ASSERT_EQUAL(5,(int)ms.size()); - CPPUNIT_ASSERT_EQUAL(2,(int)dms.size()); - CPPUNIT_ASSERT_EQUAL(6,(int)das.size()); - CPPUNIT_ASSERT_EQUAL(5,(int)das2.size()); - // - MEDCouplingMultiFields *mfs2=mfs->deepCpy(); - CPPUNIT_ASSERT(mfs->isEqual(mfs2,1e-12,1e-12)); - mfs2->decrRef(); - // - mfs->decrRef(); -} - -void MEDCouplingBasicsTest4::testFieldOverTime1() -{ - std::vector fs=buildMultiFields_2(); - CPPUNIT_ASSERT_THROW(MEDCouplingFieldOverTime::New(fs),INTERP_KERNEL::Exception); - MEDCouplingFieldDouble *f4bis=fs[4]->buildNewTimeReprFromThis(ONE_TIME,false); - fs[4]->decrRef(); - fs[4]=f4bis; - CPPUNIT_ASSERT_THROW(MEDCouplingFieldOverTime::New(fs),INTERP_KERNEL::Exception); - f4bis->setTime(2.7,20,21); - MEDCouplingFieldOverTime *fot=MEDCouplingFieldOverTime::New(fs); - MEDCouplingDefinitionTime dt=fot->getDefinitionTimeZone(); - std::vector hs=dt.getHotSpotsTime(); - CPPUNIT_ASSERT_EQUAL(6,(int)hs.size()); - const double expected1[]={0.2,0.7,1.2,1.35,1.7,2.7}; - for(int i=0;i<6;i++) - CPPUNIT_ASSERT_DOUBLES_EQUAL(expected1[i],hs[i],1e-12); - int meshId,arrId,arrIdInField,fieldId; - dt.getIdsOnTimeRight(0.2,meshId,arrId,arrIdInField,fieldId); - CPPUNIT_ASSERT_EQUAL(0,meshId); - CPPUNIT_ASSERT_EQUAL(0,arrId); - CPPUNIT_ASSERT_EQUAL(0,arrIdInField); - CPPUNIT_ASSERT_EQUAL(0,fieldId); - // - dt.getIdsOnTimeRight(0.7,meshId,arrId,arrIdInField,fieldId); - CPPUNIT_ASSERT_EQUAL(0,meshId); - CPPUNIT_ASSERT_EQUAL(1,arrId); - CPPUNIT_ASSERT_EQUAL(0,arrIdInField); - CPPUNIT_ASSERT_EQUAL(1,fieldId); - // - dt.getIdsOnTimeLeft(1.2,meshId,arrId,arrIdInField,fieldId);//**** WARNING left here - CPPUNIT_ASSERT_EQUAL(0,meshId); - CPPUNIT_ASSERT_EQUAL(2,arrId); - CPPUNIT_ASSERT_EQUAL(1,arrIdInField); - CPPUNIT_ASSERT_EQUAL(1,fieldId); - // - dt.getIdsOnTimeRight(1.2,meshId,arrId,arrIdInField,fieldId);//**** WARNING right again here - CPPUNIT_ASSERT_EQUAL(1,meshId); - CPPUNIT_ASSERT_EQUAL(3,arrId); - CPPUNIT_ASSERT_EQUAL(0,arrIdInField); - CPPUNIT_ASSERT_EQUAL(2,fieldId); - // - dt.getIdsOnTimeRight(1.35,meshId,arrId,arrIdInField,fieldId); - CPPUNIT_ASSERT_EQUAL(1,meshId); - CPPUNIT_ASSERT_EQUAL(3,arrId); - CPPUNIT_ASSERT_EQUAL(0,arrIdInField); - CPPUNIT_ASSERT_EQUAL(2,fieldId); - // - dt.getIdsOnTimeRight(1.7,meshId,arrId,arrIdInField,fieldId); - CPPUNIT_ASSERT_EQUAL(0,meshId); - CPPUNIT_ASSERT_EQUAL(3,arrId); - CPPUNIT_ASSERT_EQUAL(0,arrIdInField); - CPPUNIT_ASSERT_EQUAL(3,fieldId); - // - dt.getIdsOnTimeRight(2.7,meshId,arrId,arrIdInField,fieldId); - CPPUNIT_ASSERT_EQUAL(1,meshId); - CPPUNIT_ASSERT_EQUAL(4,arrId); - CPPUNIT_ASSERT_EQUAL(0,arrIdInField); - CPPUNIT_ASSERT_EQUAL(4,fieldId); - // - MEDCouplingDefinitionTime dt2; - CPPUNIT_ASSERT(!dt2.isEqual(dt)); - dt2.assign(dt); - dt2.assign(dt);//to check memory management - CPPUNIT_ASSERT(dt2.isEqual(dt)); - // - MEDCouplingDefinitionTime dt3; - std::vector tmp1; - std::vector tmp2; - CPPUNIT_ASSERT(!dt2.isEqual(dt3)); - dt2.getTinySerializationInformation(tmp1,tmp2); - dt3.unserialize(tmp1,tmp2); - CPPUNIT_ASSERT(dt2.isEqual(dt3)); - // - for(std::vector::iterator it=fs.begin();it!=fs.end();it++) - (*it)->decrRef(); - fot->decrRef(); -} - -void MEDCouplingBasicsTest4::testDAICheckAndPreparePermutation1() -{ - const int vals1[]={9,10,0,6,4,11,3,7}; - const int expect1[]={5,6,0,3,2,7,1,4}; - const int vals2[]={9,10,0,6,10,11,3,7}; - DataArrayInt *da=DataArrayInt::New(); - da->alloc(8,1); - std::copy(vals1,vals1+8,da->getPointer()); - DataArrayInt *da2=da->checkAndPreparePermutation(); - CPPUNIT_ASSERT_EQUAL(8,da2->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(1,da2->getNumberOfComponents()); - for(int i=0;i<8;i++) - CPPUNIT_ASSERT_EQUAL(expect1[i],da2->getIJ(i,0)); - da2->decrRef(); - da->decrRef(); - // - da=DataArrayInt::New(); - da->alloc(8,1); - da->iota(0); - da2=da->checkAndPreparePermutation(); - CPPUNIT_ASSERT_EQUAL(8,da2->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(1,da2->getNumberOfComponents()); - CPPUNIT_ASSERT(da2->isIdentity()); - da2->decrRef(); - da->decrRef(); - // - da=DataArrayInt::New(); - da->alloc(8,1); - std::copy(vals2,vals2+8,da->getPointer()); - CPPUNIT_ASSERT_THROW(da->checkAndPreparePermutation(),INTERP_KERNEL::Exception); - da->decrRef(); -} - -void MEDCouplingBasicsTest4::testDAIChangeSurjectiveFormat1() -{ - const int vals1[8]={0,3,2,3,2,2,1,2}; - const int expected1[5]={0,1,2,6,8}; - const int expected2[8]={0, 6, 2,4,5,7, 1,3}; - DataArrayInt *da=DataArrayInt::New(); - da->alloc(8,1); - std::copy(vals1,vals1+8,da->getPointer()); - // - DataArrayInt *da2,*da2I; - da->changeSurjectiveFormat(4,da2,da2I); - CPPUNIT_ASSERT_EQUAL(5,da2I->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(8,da2->getNumberOfTuples()); - CPPUNIT_ASSERT(std::equal(expected1,expected1+5,da2I->getConstPointer())); - CPPUNIT_ASSERT(std::equal(expected2,expected2+8,da2->getConstPointer())); - da2->decrRef(); - da2I->decrRef(); - // - CPPUNIT_ASSERT_THROW(da->changeSurjectiveFormat(3,da2,da2I),INTERP_KERNEL::Exception); - // - da->decrRef(); -} - -void MEDCouplingBasicsTest4::testUMeshGetCellIdsLyingOnNodes1() -{ - MEDCouplingUMesh *m=build3DSurfTargetMesh_1(); - const int nodeIds1[5]={1,2,3,4,6}; - const int nodeIds2[2]={6,7}; - DataArrayInt *da=m->getCellIdsLyingOnNodes(nodeIds1,nodeIds1+5,true); - CPPUNIT_ASSERT_EQUAL(1,da->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(1,da->getNumberOfComponents()); - CPPUNIT_ASSERT_EQUAL(1,da->getIJ(0,0)); - da->decrRef(); - da=m->getCellIdsLyingOnNodes(nodeIds2,nodeIds2+2,false); - CPPUNIT_ASSERT_EQUAL(2,da->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(1,da->getNumberOfComponents()); - CPPUNIT_ASSERT_EQUAL(3,da->getIJ(0,0)); - CPPUNIT_ASSERT_EQUAL(4,da->getIJ(1,0)); - da->decrRef(); - // - m->decrRef(); -} - -void MEDCouplingBasicsTest4::testUMeshFindCellIdsOnBoundary1() -{ - MEDCouplingUMesh *m=build3DSurfTargetMesh_1(); - DataArrayInt *da5=m->findCellIdsOnBoundary(); - CPPUNIT_ASSERT_EQUAL(5,da5->getNumberOfTuples()); - CPPUNIT_ASSERT(da5->isIdentity()); - // - da5->decrRef(); - m->decrRef(); -} - -void MEDCouplingBasicsTest4::testMeshSetTime1() -{ - MEDCouplingUMesh *m1=build3DSurfTargetMesh_1(); - MEDCouplingUMesh *m2=build3DSurfTargetMesh_1(); - // - CPPUNIT_ASSERT(m1->isEqual(m2,1e-12)); - m1->setTime(3.14,6,7); - int tmp1,tmp2; - double tmp3=m1->getTime(tmp1,tmp2); - CPPUNIT_ASSERT_EQUAL(6,tmp1); - CPPUNIT_ASSERT_EQUAL(7,tmp2); - CPPUNIT_ASSERT_DOUBLES_EQUAL(3.14,tmp3,1e-12); - CPPUNIT_ASSERT(!m1->isEqual(m2,1e-12)); - m2->setTime(3.14,6,7); - CPPUNIT_ASSERT(m1->isEqual(m2,1e-12)); - m1->setTimeUnit("ms"); - CPPUNIT_ASSERT(std::string(m1->getTimeUnit())=="ms"); - m1->setTimeUnit("us"); - CPPUNIT_ASSERT(std::string(m1->getTimeUnit())=="us"); - CPPUNIT_ASSERT(!m1->isEqual(m2,1e-12)); - m2->setTimeUnit("us"); - CPPUNIT_ASSERT(m1->isEqual(m2,1e-12)); - m2->setTime(3.14,6,8); - CPPUNIT_ASSERT(!m1->isEqual(m2,1e-12)); - m2->setTime(3.14,7,7); - CPPUNIT_ASSERT(!m1->isEqual(m2,1e-12)); - m2->setTime(3.15,6,7); - CPPUNIT_ASSERT(!m1->isEqual(m2,1e-12)); - // - m1->setTime(10.34,55,12); - MEDCouplingUMesh *m3=(MEDCouplingUMesh *)m1->deepCpy(); - CPPUNIT_ASSERT(m1->isEqual(m3,1e-12)); - tmp3=m3->getTime(tmp1,tmp2); - CPPUNIT_ASSERT_EQUAL(55,tmp1); - CPPUNIT_ASSERT_EQUAL(12,tmp2); - CPPUNIT_ASSERT_DOUBLES_EQUAL(10.34,tmp3,1e-12); - // - m3->decrRef(); - m1->decrRef(); - m2->decrRef(); - // testing CMesh - const double coo1[4]={0.,1.,2.,3.5}; - DataArrayDouble *a=DataArrayDouble::New(); - a->alloc(4,1); - std::copy(coo1,coo1+4,a->getPointer()); - MEDCouplingCMesh *b=MEDCouplingCMesh::New(); - b->setCoordsAt(0,a); - a->decrRef(); - // - b->setTime(5.67,8,100); - tmp3=b->getTime(tmp1,tmp2); - CPPUNIT_ASSERT_EQUAL(8,tmp1); - CPPUNIT_ASSERT_EQUAL(100,tmp2); - CPPUNIT_ASSERT_DOUBLES_EQUAL(5.67,tmp3,1e-12); - MEDCouplingCMesh *c=(MEDCouplingCMesh *)b->deepCpy(); - CPPUNIT_ASSERT(c->isEqual(b,1e-12)); - tmp3=c->getTime(tmp1,tmp2); - CPPUNIT_ASSERT_EQUAL(8,tmp1); - CPPUNIT_ASSERT_EQUAL(100,tmp2); - CPPUNIT_ASSERT_DOUBLES_EQUAL(5.67,tmp3,1e-12); - c->decrRef(); - b->decrRef(); -} - -void MEDCouplingBasicsTest4::testApplyFuncTwo1() -{ - MEDCouplingUMesh *m1=build3DSurfTargetMesh_1(); - MEDCouplingFieldDouble *f1=MEDCouplingFieldDouble::New(ON_CELLS,ONE_TIME); - f1->setMesh(m1); - // - const double vals[15]={1.,11.,21.,2.,12.,22.,3.,13.,23.,4.,14.,24.,5.,15.,25.}; - DataArrayDouble *da=DataArrayDouble::New(); - da->alloc(5,3); - std::copy(vals,vals+15,da->getPointer()); - f1->setArray(da); - // - CPPUNIT_ASSERT_THROW(da->applyFunc2(1,"y+z"),INTERP_KERNEL::Exception); - da->setInfoOnComponent(0,"x [m]"); - da->setInfoOnComponent(1,"y [mm]"); - da->setInfoOnComponent(2,"z [km]"); - - CPPUNIT_ASSERT_THROW(da->applyFunc2(1,"x+y+zz+zzz"),INTERP_KERNEL::Exception); - CPPUNIT_ASSERT_THROW(da->applyFunc2(1,"toto(x+y)"),INTERP_KERNEL::Exception); - CPPUNIT_ASSERT_THROW(da->applyFunc2(1,"x/0"),INTERP_KERNEL::Exception); - - DataArrayDouble *da2=da->applyFunc2(1,"y+z"); - CPPUNIT_ASSERT_EQUAL(1,da2->getNumberOfComponents()); - CPPUNIT_ASSERT_EQUAL(5,da2->getNumberOfTuples()); - const double expected1[5]={32.,34.,36.,38.,40.}; - for(int i=0;i<5;i++) - CPPUNIT_ASSERT_DOUBLES_EQUAL(expected1[i],da2->getIJ(0,i),1e-12); - da2->decrRef(); - da2=da->applyFunc(1,"y+z"); - const double expected2[5]={12.,14.,16.,18.,20.}; - for(int i=0;i<5;i++) - CPPUNIT_ASSERT_DOUBLES_EQUAL(expected2[i],da2->getIJ(0,i),1e-12); - da2->decrRef(); - // - CPPUNIT_ASSERT_EQUAL(3,f1->getNumberOfComponents()); - CPPUNIT_ASSERT_EQUAL(5,f1->getNumberOfTuples()); - f1->applyFunc2(1,"y+z"); - CPPUNIT_ASSERT_EQUAL(1,f1->getNumberOfComponents()); - CPPUNIT_ASSERT_EQUAL(5,f1->getNumberOfTuples()); - for(int i=0;i<5;i++) - CPPUNIT_ASSERT_DOUBLES_EQUAL(expected1[i],f1->getArray()->getIJ(0,i),1e-12); - // - da->decrRef(); - f1->decrRef(); - m1->decrRef(); -} - -void MEDCouplingBasicsTest4::testApplyFuncThree1() -{ - MEDCouplingUMesh *m1=build3DSurfTargetMesh_1(); - MEDCouplingFieldDouble *f1=MEDCouplingFieldDouble::New(ON_CELLS,ONE_TIME); - f1->setMesh(m1); - // - const double vals[15]={1.,11.,21.,2.,12.,22.,3.,13.,23.,4.,14.,24.,5.,15.,25.}; - DataArrayDouble *da=DataArrayDouble::New(); - da->alloc(5,3); - std::copy(vals,vals+15,da->getPointer()); - f1->setArray(da); - // - std::vector vs(3); - vs[0]="x"; vs[1]="Y"; vs[2]="z"; - CPPUNIT_ASSERT_THROW(da->applyFunc3(1,vs,"y+z"),INTERP_KERNEL::Exception); - CPPUNIT_ASSERT_THROW(da->applyFunc3(1,vs,"x+Y+z+zz+zzz"),INTERP_KERNEL::Exception); - CPPUNIT_ASSERT_THROW(da->applyFunc3(1,vs,"x/0."),INTERP_KERNEL::Exception); - vs[1]="y"; - DataArrayDouble *da2=da->applyFunc3(1,vs,"y+z"); - const double expected1[5]={32.,34.,36.,38.,40.}; - for(int i=0;i<5;i++) - CPPUNIT_ASSERT_DOUBLES_EQUAL(expected1[i],da2->getIJ(0,i),1e-12); - da2->decrRef(); - std::vector vs2(4); vs2[0]="x"; vs2[1]="y"; vs2[2]="z"; vs2[3]="a"; - CPPUNIT_ASSERT_THROW(da->applyFunc3(1,vs2,"x+a"),INTERP_KERNEL::Exception); - f1->setArray(da); - CPPUNIT_ASSERT_EQUAL(3,f1->getNumberOfComponents()); - CPPUNIT_ASSERT_EQUAL(5,f1->getNumberOfTuples()); - f1->applyFunc3(1,vs,"y+z"); - CPPUNIT_ASSERT_EQUAL(1,f1->getNumberOfComponents()); - CPPUNIT_ASSERT_EQUAL(5,f1->getNumberOfTuples()); - for(int i=0;i<5;i++) - CPPUNIT_ASSERT_DOUBLES_EQUAL(expected1[i],f1->getArray()->getIJ(0,i),1e-12); - // - da->decrRef(); - f1->decrRef(); - m1->decrRef(); -} - -void MEDCouplingBasicsTest4::testFillFromAnalyticTwo1() -{ - MEDCouplingUMesh *m1=build3DSurfTargetMesh_1(); - m1->setTime(3.4,5,6); m1->setTimeUnit("us"); - int a,b; - CPPUNIT_ASSERT_THROW(m1->fillFromAnalytic2(ON_NODES,1,"y+z"),INTERP_KERNEL::Exception); - m1->getCoords()->setInfoOnComponent(0,"x [m]"); - m1->getCoords()->setInfoOnComponent(1,"y"); - m1->getCoords()->setInfoOnComponent(2,"z"); - MEDCouplingFieldDouble *f1=m1->fillFromAnalytic2(ON_NODES,1,"y+z"); - CPPUNIT_ASSERT_DOUBLES_EQUAL(3.4,f1->getTime(a,b),1.e-14); - CPPUNIT_ASSERT_EQUAL(5,a); CPPUNIT_ASSERT_EQUAL(6,b); - CPPUNIT_ASSERT_EQUAL(std::string(f1->getTimeUnit()),std::string("us")); - CPPUNIT_ASSERT_EQUAL(1,f1->getNumberOfComponents()); - CPPUNIT_ASSERT_EQUAL(9,f1->getNumberOfTuples()); - const double expected1[9]={0.2, 0.7, 1.2, 0.7, 1.2, 1.7, 1.2, 1.7, 2.2}; - for(int i=0;i<9;i++) - CPPUNIT_ASSERT_DOUBLES_EQUAL(expected1[i],f1->getArray()->getIJ(0,i),1e-12); - f1->decrRef(); - m1->decrRef(); -} - -void MEDCouplingBasicsTest4::testFillFromAnalyticThree1() -{ - MEDCouplingUMesh *m1=build3DSurfTargetMesh_1(); - m1->setTime(3.4,5,6); m1->setTimeUnit("us"); - int a,b; - std::vector vs(3); - vs[0]="x"; vs[1]="Y"; vs[2]="z"; - CPPUNIT_ASSERT_THROW(m1->fillFromAnalytic3(ON_NODES,1,vs,"y+z"),INTERP_KERNEL::Exception); - vs[1]="y"; - MEDCouplingFieldDouble *f1=m1->fillFromAnalytic3(ON_NODES,1,vs,"y+z"); - CPPUNIT_ASSERT_DOUBLES_EQUAL(3.4,f1->getTime(a,b),1.e-14); - CPPUNIT_ASSERT_EQUAL(5,a); CPPUNIT_ASSERT_EQUAL(6,b); - CPPUNIT_ASSERT_EQUAL(std::string(f1->getTimeUnit()),std::string("us")); - CPPUNIT_ASSERT_EQUAL(1,f1->getNumberOfComponents()); - CPPUNIT_ASSERT_EQUAL(9,f1->getNumberOfTuples()); - const double expected1[9]={0.2, 0.7, 1.2, 0.7, 1.2, 1.7, 1.2, 1.7, 2.2}; - for(int i=0;i<9;i++) - CPPUNIT_ASSERT_DOUBLES_EQUAL(expected1[i],f1->getArray()->getIJ(0,i),1e-12); - f1->decrRef(); - m1->decrRef(); -} - -void MEDCouplingBasicsTest4::testDAUnitVar1() -{ - DataArrayDouble *da=DataArrayDouble::New(); - da->alloc(1,3); - da->setInfoOnComponent(0,"XPS [m]"); - std::string st1,st2; - st1=da->getVarOnComponent(0); - CPPUNIT_ASSERT(st1=="XPS"); - st2=da->getUnitOnComponent(0); - CPPUNIT_ASSERT(st2=="m"); - // - da->setInfoOnComponent(0,"XPS [m]"); - st1=da->getVarOnComponent(0); - CPPUNIT_ASSERT(st1=="XPS"); - st2=da->getUnitOnComponent(0); - CPPUNIT_ASSERT(st2=="m"); - // - da->setInfoOnComponent(0,"XPP [m]"); - st1=da->getVarOnComponent(0); - CPPUNIT_ASSERT(st1=="XPP"); - st2=da->getUnitOnComponent(0); - CPPUNIT_ASSERT(st2=="m"); - // - da->setInfoOnComponent(0,"XPP kdep kefer [ m ]"); - st1=da->getVarOnComponent(0); - CPPUNIT_ASSERT(st1=="XPP kdep kefer"); - st2=da->getUnitOnComponent(0); - CPPUNIT_ASSERT(st2==" m "); - // - da->setInfoOnComponent(0," XPP k[ dep k]efer [ m^ 2/s^3*kJ ]"); - st1=da->getVarOnComponent(0); - CPPUNIT_ASSERT(st1==" XPP k[ dep k]efer"); - st2=da->getUnitOnComponent(0); - CPPUNIT_ASSERT(st2==" m^ 2/s^3*kJ "); - // - da->setInfoOnComponent(0," XPP kefer "); - st1=da->getVarOnComponent(0); - CPPUNIT_ASSERT(st1==" XPP kefer "); - st2=da->getUnitOnComponent(0); - CPPUNIT_ASSERT(st2==""); - // - da->setInfoOnComponent(0,"temperature( bof)"); - st1=da->getVarOnComponent(0); - CPPUNIT_ASSERT(st1=="temperature( bof)"); - st2=da->getUnitOnComponent(0); - CPPUNIT_ASSERT(st2==""); - // - da->setInfoOnComponent(0,"kkk [m]"); - da->setInfoOnComponent(1,"ppp [m^2/kJ]"); - da->setInfoOnComponent(2,"abcde [MW/s]"); - // - std::vector vs; - vs=da->getVarsOnComponent(); - CPPUNIT_ASSERT_EQUAL(3,(int)vs.size()); - CPPUNIT_ASSERT(vs[0]=="kkk"); - CPPUNIT_ASSERT(vs[1]=="ppp"); - CPPUNIT_ASSERT(vs[2]=="abcde"); - vs=da->getUnitsOnComponent(); - CPPUNIT_ASSERT_EQUAL(3,(int)vs.size()); - CPPUNIT_ASSERT(vs[0]=="m"); - CPPUNIT_ASSERT(vs[1]=="m^2/kJ"); - CPPUNIT_ASSERT(vs[2]=="MW/s"); - // - da->decrRef(); -} - -void MEDCouplingBasicsTest4::testGaussCoordinates1() -{ - //Testing 1D cell types - MEDCouplingUMesh *m1=build1DMultiTypes_1(); - MEDCouplingFieldDouble *f=MEDCouplingFieldDouble::New(ON_GAUSS_PT,ONE_TIME); - f->setMesh(m1); - std::vector wg1(1); wg1[0]=0.3; - std::vector gsCoo1(1); gsCoo1[0]=0.2; - std::vector refCoo1(2); refCoo1[0]=-1.0; refCoo1[1]=1.0; - f->setGaussLocalizationOnType(INTERP_KERNEL::NORM_SEG2,refCoo1,gsCoo1,wg1); - std::vector wg2(wg1); - std::vector gsCoo2(1); gsCoo2[0]=0.2; - std::vector refCoo2(3); refCoo2[0]=-1.0; refCoo2[1]=1.0; refCoo2[2]=0.0; - f->setGaussLocalizationOnType(INTERP_KERNEL::NORM_SEG3,refCoo2,gsCoo2,wg2); - // - DataArrayDouble *resToTest=f->getLocalizationOfDiscr(); - CPPUNIT_ASSERT_EQUAL(3,resToTest->getNumberOfComponents()); - CPPUNIT_ASSERT_EQUAL(2,resToTest->getNumberOfTuples()); - const double expected1[6]={0.6,0.6,0.6, 0.6,0.6,0.6}; - for(int i=0;i<6;i++) - CPPUNIT_ASSERT_DOUBLES_EQUAL(expected1[i],resToTest->getIJ(0,i),1e-14); - resToTest->decrRef(); - // - m1->decrRef(); - f->decrRef(); - //Testing 2D cell types - MEDCouplingUMesh *m2=build2DMultiTypes_1(); - f=MEDCouplingFieldDouble::New(ON_GAUSS_PT,ONE_TIME); - f->setMesh(m2); - std::vector wg3(2); wg3[0]=0.3; wg3[1]=0.3; - const double tria3CooGauss[4]={ 0.1, 0.8, 0.2, 0.7 }; - std::vector gsCoo3(tria3CooGauss,tria3CooGauss+4); - const double tria3CooRef[6]={ 0.0, 0.0, 1.0 , 0.0, 0.0, 1.0 }; - std::vector refCoo3(tria3CooRef,tria3CooRef+6); - f->setGaussLocalizationOnType(INTERP_KERNEL::NORM_TRI3,refCoo3,gsCoo3,wg3); - std::vector wg4(3); wg4[0]=0.3; wg4[1]=0.3; wg4[2]=0.3; - const double tria6CooGauss[6]={ 0.3, 0.2, 0.2, 0.1, 0.2, 0.4 }; - std::vector gsCoo4(tria6CooGauss,tria6CooGauss+6); - const double tria6CooRef[12]={0.0, 0.0, 1.0, 0.0, 0.0, 1.0, 0.5, 0.0, 0.5, 0.5, 0.0, 0.5}; - std::vector refCoo4(tria6CooRef,tria6CooRef+12); - f->setGaussLocalizationOnType(INTERP_KERNEL::NORM_TRI6,refCoo4,gsCoo4,wg4); - std::vector wg5(4); wg5[0]=0.3; wg5[1]=0.3; wg5[2]=0.3; wg5[3]=0.3; - const double quad4CooGauss[8]={ 0.3, 0.2, 0.2, 0.1, 0.2, 0.4, 0.15, 0.27 }; - std::vector gsCoo5(quad4CooGauss,quad4CooGauss+8); - const double quad4CooRef[8]={-1.0, 1.0, -1.0, -1.0, 1.0, -1.0, 1.0, 1.0}; - std::vector refCoo5(quad4CooRef,quad4CooRef+8); - f->setGaussLocalizationOnType(INTERP_KERNEL::NORM_QUAD4,refCoo5,gsCoo5,wg5); - std::vector wg6(4); wg6[0]=0.3; wg6[1]=0.3; wg6[2]=0.3; wg6[3]=0.3; - const double quad8CooGauss[8]={ 0.34, 0.16, 0.21, 0.3, 0.23, 0.4, 0.14, 0.37 }; - std::vector gsCoo6(quad8CooGauss,quad8CooGauss+8); - const double quad8CooRef[16]={ -1.0, -1.0, 1.0, -1.0, 1.0, 1.0, -1.0, 1.0, 0.0, -1.0, 1.0, 0.0, 0.0, 1.0, -1.0, 0.0}; - std::vector refCoo6(quad8CooRef,quad8CooRef+16); - f->setGaussLocalizationOnType(INTERP_KERNEL::NORM_QUAD8,refCoo6,gsCoo6,wg6); - // - resToTest=f->getLocalizationOfDiscr(); - CPPUNIT_ASSERT_EQUAL(3,resToTest->getNumberOfComponents()); - CPPUNIT_ASSERT_EQUAL(13,resToTest->getNumberOfTuples());//2+3+4+4 gauss points for resp TRI3,TRI6,QUAD4,QUAD8 - const double expected2[39]={5.1,1.55,0.0, 4.7,1.65,0.0, //TRI3 - 2.32,1.52,0.0, 1.6,1.32,0.0, 3.52,1.26,0.0,//TRI6 - 2.6,1.6,0.0, 2.4,1.8,0.0, 2.4,1.2,0.0, 2.3,1.46,0.0,//QUAD4 - 2.32,2.68,0.0, 2.6,2.42,0.0, 2.8,2.46,0.0, 2.74,2.28,0.0 };//QUAD8 - for(int i=0;i<39;i++) - CPPUNIT_ASSERT_DOUBLES_EQUAL(expected2[i],resToTest->getIJ(0,i),1e-14); - resToTest->decrRef(); - // - m2->decrRef(); - f->decrRef(); - //Testing 3D cell types - MEDCouplingUMesh *m3=build3DMultiTypes_1(); - f=MEDCouplingFieldDouble::New(ON_GAUSS_PT,ONE_TIME); - f->setMesh(m3); - // - std::vector wg7(1); wg7[0]=0.3; - const double tetra4CooGauss[3]={0.34, 0.16, 0.21}; - std::vector gsCoo7(tetra4CooGauss,tetra4CooGauss+3); - const double tetra4CooRef[12]={0.0,1.0,0.0, 0.0,0.0,1.0, 0.0,0.0,0.0, 1.0,0.0,0.0}; - std::vector refCoo7(tetra4CooRef,tetra4CooRef+12); - f->setGaussLocalizationOnType(INTERP_KERNEL::NORM_TETRA4,refCoo7,gsCoo7,wg7); - std::vector wg8(1); wg8[0]=0.3; - const double tetra10CooGauss[3]={0.2, 0.3, 0.1}; - std::vector gsCoo8(tetra10CooGauss,tetra10CooGauss+3); - const double tetra10CooRef[30]={0.0,1.0,0.0, 0.0,0.0,0.0, 0.0,0.0,1.0, 1.0,0.0,0.0, 0.0,0.5,0.0, 0.0,0.0,0.5, 0.0,0.5,0.5, 0.5,0.5,0.0, 0.5,0.0,0.0, 0.5,0.0,0.5}; - std::vector refCoo8(tetra10CooRef,tetra10CooRef+30); - f->setGaussLocalizationOnType(INTERP_KERNEL::NORM_TETRA10,refCoo8,gsCoo8,wg8); - std::vector wg9(1); wg9[0]=0.3; - const double pyra5CooGauss[3]={0.2, 0.3, 0.1}; - std::vector gsCoo9(pyra5CooGauss,pyra5CooGauss+3); - const double pyra5CooRef[15]={1.0,0.0,0.0, 0.0,1.0,0.0, -1.0,0.0,0.0, 0.0,-1.0,0.0, 0.0,0.0,1.0}; - std::vector refCoo9(pyra5CooRef,pyra5CooRef+15); - f->setGaussLocalizationOnType(INTERP_KERNEL::NORM_PYRA5,refCoo9,gsCoo9,wg9); - std::vector wg10(1); wg10[0]=0.3; - const double pyra13CooGauss[3]={0.1, 0.2, 0.7}; - std::vector gsCoo10(pyra13CooGauss,pyra13CooGauss+3); - const double pyra13CooRef[39]={1.0,0.0,0.0, 0.0,1.0,0.0,-1.0,0.0,0.0,0.0,-1.0,0.0,0.0,0.0,1.0,0.5,0.5,0.0,-0.5,0.5,0.0,-0.5,-0.5,0.0,0.5,-0.5,0.0,0.5,0.0,0.5,0.0,0.5,0.5,-0.5,0.0,0.5,0.0,-0.5,0.5}; - std::vector refCoo10(pyra13CooRef,pyra13CooRef+39); - f->setGaussLocalizationOnType(INTERP_KERNEL::NORM_PYRA13,refCoo10,gsCoo10,wg10); - std::vector wg11(1); wg11[0]=0.3; - const double penta6CooGauss[3]={0.2, 0.3, 0.1}; - std::vector gsCoo11(penta6CooGauss,penta6CooGauss+3); - const double penta6CooRef[18]={-1.0,1.0,0.0,-1.0,-0.0,1.0,-1.0,0.0,0.0,1.0,1.0,0.0,1.0,0.0,1.0,1.0,0.0,0.0}; - std::vector refCoo11(penta6CooRef,penta6CooRef+18); - f->setGaussLocalizationOnType(INTERP_KERNEL::NORM_PENTA6,refCoo11,gsCoo11,wg11); - std::vector wg12(1); wg12[0]=0.3; - const double penta15CooGauss[3]={0.2, 0.3,0.15}; - std::vector gsCoo12(penta15CooGauss,penta15CooGauss+3); - const double penta15CooRef[45]={-1.0,1.0,0.0,-1.0,0.0,1.0,-1.0,0.0,0.0,1.0,1.0,0.0,1.0,0.0,1.0,1.0,0.0,0.0,-1.0,0.5,0.5,-1.0,0.0,0.5,-1.0,0.5,0.0,0.0,1.0,0.0,0.0,0.0,1.0,0.0,0.0,0.0,1.0,0.5,0.5,1.0,0.0, 0.5,1.0,0.5,0.0}; - std::vector refCoo12(penta15CooRef,penta15CooRef+45); - f->setGaussLocalizationOnType(INTERP_KERNEL::NORM_PENTA15,refCoo12,gsCoo12,wg12); - std::vector wg13(1); wg13[0]=0.3; - const double hexa8CooGauss[3]={0.2,0.3,0.15}; - std::vector gsCoo13(hexa8CooGauss,hexa8CooGauss+3); - const double hexa8CooRef[24]={-1.0,-1.0,-1.0,1.0,-1.0,-1.0,1.0,1.0,-1.0,-1.0,1.0,-1.0,-1.0,-1.0,1.0,1.0,-1.0,1.0,1.0,1.0,1.0,-1.0,1.0,1.0}; - std::vector refCoo13(hexa8CooRef,hexa8CooRef+24); - f->setGaussLocalizationOnType(INTERP_KERNEL::NORM_HEXA8,refCoo13,gsCoo13,wg13); - std::vector wg14(1); wg14[0]=0.3; - const double hexa20CooGauss[3]={0.11,0.3,0.55}; - std::vector gsCoo14(hexa20CooGauss,hexa20CooGauss+3); - const double hexa20CooRef[60]={-1.0,-1.0,-1.0,1.0,-1.0,-1.0,1.0,1.0,-1.0,-1.0,1.0,-1.0,-1.0,-1.0,1.0,1.0,-1.0,1.0,1.0,1.0,1.0,-1.0,1.0,1.0,0.0,-1.0,-1.0,1.0,0.0,-1.0,0.0,1.0,-1.0,-1.0,0.0,-1.0,-1.0,-1.0,0.0,1.0,-1.0,0.0,1.0,1.0,0.0,-1.0,1.0,0.0,0.0,-1.0,1.0,1.0,0.0,1.0,0.0,1.0,1.0,-1.0,0.0,1.0}; - std::vector refCoo14(hexa20CooRef,hexa20CooRef+60); - f->setGaussLocalizationOnType(INTERP_KERNEL::NORM_HEXA20,refCoo14,gsCoo14,wg14); - // - resToTest=f->getLocalizationOfDiscr(); - CPPUNIT_ASSERT_EQUAL(3,resToTest->getNumberOfComponents()); - CPPUNIT_ASSERT_EQUAL(8,resToTest->getNumberOfTuples());//2+3+4+4 gauss points for resp TRI3,TRI6,QUAD4,QUAD8 - const double expected3[24]={1.312,3.15,1.02, 0.56,3.3,0.6, 2.18,1.1,0.2, 1.18,1.54,0.98, 1.56,0.3,3.6, 1.613,0.801,4.374, 2.6,2.4,2.3, 2.31232,2.3933985,1.553255}; - for(int i=0;i<24;i++) - CPPUNIT_ASSERT_DOUBLES_EQUAL(expected3[i],resToTest->getIJ(0,i),1e-14); - resToTest->decrRef(); - // - m3->decrRef(); - f->decrRef(); -} - -/*! - * Not activated test ! To be implemented ! - */ -void MEDCouplingBasicsTest4::testQ1Localization1() -{ - MEDCouplingUMesh *m=buildHexa8Mesh_1(); - MEDCouplingFieldDouble *f=MEDCouplingFieldDouble::New(ON_NODES,ONE_TIME); - DataArrayDouble *da=DataArrayDouble::New(); - const double vals1[27]={1.0,3.0,4.0,1.0,3.0,4.0,3.0,2.0,5.0,1.0,3.0,4.0,1.0,3.0,4.0,3.0,2.0,5.0,1.0,3.0,4.0,1.0,3.0,4.0,3.0,2.0,5.0}; - da->alloc(27,1); - std::copy(vals1,vals1+27,da->getPointer()); - f->setMesh(m); - f->setArray(da); - da->decrRef(); - // - const double point1[3]={0.25,0.75,0.25}; - //const double points1[6]={0.25,0.75,0.25,1.0,1.0,1.0}; - double res1[3]; - f->getValueOn(point1,res1); - // - f->decrRef(); - m->decrRef(); -} - -void MEDCouplingBasicsTest4::testP2Localization1() -{ - MEDCouplingUMesh *m=MEDCouplingUMesh::New("testP2",2); - const double coords[12]={0.,2.,3.5,0.,4.5,1.5,1.2,0.32,3.4,1.,2.1,2.4}; - const int conn[6]={0,1,2,3,4,5}; - DataArrayDouble *coo=DataArrayDouble::New(); - coo->alloc(6,2); - std::copy(coords,coords+12,coo->getPointer()); - m->setCoords(coo); - coo->decrRef(); - m->allocateCells(1); - m->insertNextCell(INTERP_KERNEL::NORM_TRI6,6,conn); - m->finishInsertingCells(); - // - MEDCouplingFieldDouble *f=MEDCouplingFieldDouble::New(ON_NODES,ONE_TIME); - f->setMesh(m); - DataArrayDouble *da=DataArrayDouble::New(); - da->alloc(6,3); - const double vals1[18]={1.2,2.3,3.4, 2.2,3.3,4.4, 3.2,4.3,5.4, 4.2,5.3,6.4, 5.2,6.3,7.4, 6.2,7.3,8.4}; - std::copy(vals1,vals1+18,da->getPointer()); - f->setArray(da); - da->decrRef(); - // - const double loc[2]={2.27,1.3}; - DataArrayDouble *locs=f->getValueOnMulti(loc,1); - const double expected1[3]={6.0921164547752236, 7.1921164547752232, 8.2921164547752255}; - for(int i=0;i<3;i++) - CPPUNIT_ASSERT_DOUBLES_EQUAL(expected1[i],locs->getIJ(0,i),1e-12); - locs->decrRef(); - // - m->decrRef(); - f->decrRef(); -} - -void MEDCouplingBasicsTest4::testP2Localization2() -{ - MEDCouplingUMesh *m=MEDCouplingUMesh::New("testP2_2",3); - const double coords[30]={0.33312787792955395, -0.35155740179580952, -0.03567564825034563, 1.307146326477638, -0.57234557776250305, -0.08608044208272235, 0.5551834466499993, 0.62324964668794192, -0.014638951108536295, 0.37761817224442129, -0.38324019806913578, 0.96283164472856886, 0.79494856035658679, -0.40628057809270046, 0.0021004190225864614, 1.023740446371799, 0.07665912970471335, -0.072889657161871096, 0.54564584619517376, 0.11132872093429744, 0.039647326652013051, 0.27164784387819052, -0.42018012100866675, 0.46563376500745146, 0.89501965094896418, -0.56148455362735061, 0.43337469695473035, 0.49118025152924394, 0.093884938060727313, 0.47216346905220891}; - const int conn[10]={0,1,2,3,4,5,6,7,8,9}; - DataArrayDouble *coo=DataArrayDouble::New(); - coo->alloc(10,3); - std::copy(coords,coords+30,coo->getPointer()); - m->setCoords(coo); - coo->decrRef(); - m->allocateCells(1); - m->insertNextCell(INTERP_KERNEL::NORM_TETRA10,10,conn); - m->finishInsertingCells(); - // - MEDCouplingFieldDouble *f=MEDCouplingFieldDouble::New(ON_NODES,ONE_TIME); - f->setMesh(m); - DataArrayDouble *da=DataArrayDouble::New(); - da->alloc(10,1); - const double vals1[10]={1.1,2.1,3.1,4.1,5.2,6.2,7.2,8.2,9.2,10.2}; - std::copy(vals1,vals1+10,da->getPointer()); - f->setArray(da); - da->decrRef(); - // - const double loc[3]={0.64637931739890486, -0.16185896817550552, 0.22678966365273748}; - DataArrayDouble *locs=f->getValueOnMulti(loc,1); - const double expected1[1]={10.0844021968047}; - for(int i=0;i<1;i++) - CPPUNIT_ASSERT_DOUBLES_EQUAL(expected1[i],locs->getIJ(0,i),1e-12); - locs->decrRef(); - // - m->decrRef(); - f->decrRef(); -} - -void MEDCouplingBasicsTest4::testGetValueOn2() -{ - MEDCouplingUMesh *m=build2DTargetMesh_1(); - MEDCouplingFieldDouble *f=MEDCouplingFieldDouble::New(ON_CELLS,NO_TIME); - f->setMesh(m); - DataArrayDouble *arr=DataArrayDouble::New(); - int nbOfCells=m->getNumberOfCells(); - arr->alloc(nbOfCells,3); - f->setArray(arr); - arr->decrRef(); - const double values1[15]={7.,107.,10007.,8.,108.,10008.,9.,109.,10009.,10.,110.,10010.,11.,111.,10011.}; - std::copy(values1,values1+15,arr->getPointer()); - const double loc[10]={-0.05,-0.05, 0.55,-0.25, 0.55,0.15, -0.05,0.45, 0.45,0.45}; - f->checkCoherency(); - DataArrayDouble *locs=f->getValueOnMulti(loc,5); - CPPUNIT_ASSERT_EQUAL(5,locs->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(3,locs->getNumberOfComponents()); - for(int j=0;j<15;j++) - CPPUNIT_ASSERT_DOUBLES_EQUAL(values1[j],locs->getIJ(0,j),1e-12); - locs->decrRef(); - f->decrRef(); - // Testing ON_NODES - f=MEDCouplingFieldDouble::New(ON_NODES,NO_TIME); - f->setMesh(m); - arr=DataArrayDouble::New(); - int nbOfNodes=m->getNumberOfNodes(); - arr->alloc(nbOfNodes,3); - f->setArray(arr); - arr->decrRef(); - const double values2[27]={7.,107.,10007.,8.,108.,10008.,9.,109.,10009.,10.,110.,10010.,11.,111.,10011.,12.,112.,10012.,13.,113.,10013.,14.,114.,10014.,15.,115.,10015.}; - std::copy(values2,values2+27,arr->getPointer()); - const double loc2[8]={0.5432,-0.2432, 0.5478,0.1528, 0.5432,-0.2432, 0.5432,-0.2432}; - const double expected2[12]={9.0272, 109.0272, 10009.0272, 11.4124,111.4124,10011.4124, 9.0272, 109.0272, 10009.0272, 9.0272, 109.0272, 10009.0272}; - f->checkCoherency(); - locs=f->getValueOnMulti(loc2,4); - CPPUNIT_ASSERT_EQUAL(4,locs->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(3,locs->getNumberOfComponents()); - for(int i=0;i<12;i++) - CPPUNIT_ASSERT_DOUBLES_EQUAL(expected2[i],locs->getIJ(0,i),1e-12); - f->decrRef(); - locs->decrRef(); - // - m->decrRef(); -} - -void MEDCouplingBasicsTest4::testDAIGetIdsNotEqual1() -{ - DataArrayInt *d=DataArrayInt::New(); - const int vals1[10]={2,3,5,6,8,5,5,6,1,-5}; - d->alloc(10,1); - std::copy(vals1,vals1+10,d->getPointer()); - DataArrayInt *d2=d->getIdsNotEqual(5); - CPPUNIT_ASSERT_EQUAL(7,d2->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(1,d2->getNumberOfComponents()); - const int expected1[7]={0,1,3,4,7,8,9}; - for(int i=0;i<7;i++) - CPPUNIT_ASSERT_EQUAL(expected1[i],d2->getIJ(0,i)); - d->rearrange(2); - CPPUNIT_ASSERT_THROW(d->getIdsNotEqual(5),INTERP_KERNEL::Exception); - const int vals2[3]={-4,5,6}; - std::vector vals3(vals2,vals2+3); - d->rearrange(1); - DataArrayInt *d3=d->getIdsNotEqualList(&vals3[0],&vals3[0]+vals3.size()); - CPPUNIT_ASSERT_EQUAL(5,d3->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(1,d3->getNumberOfComponents()); - const int expected2[5]={0,1,4,8,9}; - for(int i=0;i<5;i++) - CPPUNIT_ASSERT_EQUAL(expected2[i],d3->getIJ(0,i)); - d3->decrRef(); - d->decrRef(); - d2->decrRef(); -} - -void MEDCouplingBasicsTest4::testDAIComputeOffsets1() -{ - DataArrayInt *d=DataArrayInt::New(); - const int vals1[6]={3,5,1,2,0,8}; - const int expected1[6]={0,3,8,9,11,11}; - d->alloc(6,1); - std::copy(vals1,vals1+6,d->getPointer()); - d->computeOffsets(); - CPPUNIT_ASSERT_EQUAL(6,d->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(1,d->getNumberOfComponents()); - for(int i=0;i<6;i++) - CPPUNIT_ASSERT_EQUAL(expected1[i],d->getIJ(0,i)); - d->decrRef(); -} - -void MEDCouplingBasicsTest4::testUMeshHexagonPrism1() -{ - const double coords[36]={ - 0.8660254037844386, 0.5, 0.0, 0.0, 1.0, 0.0, -0.8660254037844386, 0.5, 0.0, -0.8660254037844386, -0.5, 0.0, 0.0, -1.0, 0.0, 0.8660254037844386, -0.5, 0.0, - 0.8660254037844386, 0.5, 2.0, 0.0, 1.0, 2.0, -0.8660254037844386, 0.5, 2.0, -0.8660254037844386, -0.5, 2.0, 0.0, -1.0, 2.0, 0.8660254037844386, -0.5, 2.0 - }; - const int conn[12]={1,2,3,4,5,0,7,8,9,10,11,6}; - MEDCouplingUMesh *mesh=MEDCouplingUMesh::New("MyFirstHexagonalPrism",3); - DataArrayDouble *coo=DataArrayDouble::New(); - coo->alloc(12,3); - std::copy(coords,coords+36,coo->getPointer()); - mesh->setCoords(coo); - mesh->allocateCells(1); - mesh->insertNextCell(INTERP_KERNEL::NORM_HEXGP12,12,conn); - mesh->finishInsertingCells(); - coo->decrRef(); - // - mesh->checkCoherency(); - MEDCouplingFieldDouble *vols=mesh->getMeasureField(false); - CPPUNIT_ASSERT_EQUAL(1,vols->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(1,vols->getNumberOfComponents()); - CPPUNIT_ASSERT_DOUBLES_EQUAL(-5.196152422706632,vols->getIJ(0,0),1e-12); - DataArrayDouble *bary=mesh->getBarycenterAndOwner(); - CPPUNIT_ASSERT_EQUAL(1,bary->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(3,bary->getNumberOfComponents()); - const double expected1[3]={0.,0.,1.}; - for(int i=0;i<3;i++) - CPPUNIT_ASSERT_DOUBLES_EQUAL(expected1[i],bary->getIJ(0,i),1e-12); - DataArrayInt *d1=DataArrayInt::New(); - DataArrayInt *d2=DataArrayInt::New(); - DataArrayInt *d3=DataArrayInt::New(); - DataArrayInt *d4=DataArrayInt::New(); - MEDCouplingUMesh *m2=mesh->buildDescendingConnectivity(d1,d2,d3,d4); - CPPUNIT_ASSERT_EQUAL(8,m2->getNumberOfCells()); - const int expected4[8][6]={{1,2,3,4,5,0},{7,6,11,10,9,8},{1,7,8,2},{2,8,9,3},{3,9,10,4},{4,10,11,5},{5,11,6,0},{0,6,7,1}}; - const INTERP_KERNEL::NormalizedCellType expected2[8]={INTERP_KERNEL::NORM_POLYGON, INTERP_KERNEL::NORM_POLYGON, INTERP_KERNEL::NORM_QUAD4, INTERP_KERNEL::NORM_QUAD4, INTERP_KERNEL::NORM_QUAD4, INTERP_KERNEL::NORM_QUAD4, INTERP_KERNEL::NORM_QUAD4, INTERP_KERNEL::NORM_QUAD4}; - const int expected3[8]={6,6,4,4,4,4,4,4}; - for(int i=0;i<8;i++) - { - CPPUNIT_ASSERT(m2->getTypeOfCell(i)==expected2[i]); - std::vector v; - m2->getNodeIdsOfCell(i,v); - CPPUNIT_ASSERT((int)v.size()==expected3[i]); - CPPUNIT_ASSERT(std::equal(expected4[i],expected4[i]+expected3[i],v.begin())); - } - d1->decrRef(); - d2->decrRef(); - d3->decrRef(); - d4->decrRef(); - m2->decrRef(); - // - mesh->convertAllToPoly(); - CPPUNIT_ASSERT(INTERP_KERNEL::NORM_POLYHED==mesh->getTypeOfCell(0)); - mesh->unPolyze(); - CPPUNIT_ASSERT(INTERP_KERNEL::NORM_HEXGP12==mesh->getTypeOfCell(0)); - CPPUNIT_ASSERT_EQUAL(13,mesh->getMeshLength()); - // - vols->decrRef(); - bary->decrRef(); - mesh->decrRef(); -} - -void MEDCouplingBasicsTest4::testDADCheckIsMonotonic() -{ - DataArrayDouble *da=DataArrayDouble::New(); - const double vals[4]={-1.,1.01,2.03,6.}; - da->alloc(2,2); - std::copy(vals,vals+4,da->getPointer()); - CPPUNIT_ASSERT_THROW(da->isMonotonic(true, 1e-12),INTERP_KERNEL::Exception); - da->rearrange(1); - CPPUNIT_ASSERT(da->isMonotonic(true, 1e-12)); - da->checkMonotonic(true, 1e-12); - da->setIJ(2,0,6.1); - CPPUNIT_ASSERT(!da->isMonotonic(true, 1e-12)); - CPPUNIT_ASSERT_THROW(da->checkMonotonic(true, 1e-12),INTERP_KERNEL::Exception); - CPPUNIT_ASSERT_THROW(da->checkMonotonic(false, 1e-12),INTERP_KERNEL::Exception); - da->setIJ(2,0,5.99); - CPPUNIT_ASSERT(da->isMonotonic(true, 1e-12)); - CPPUNIT_ASSERT(!da->isMonotonic(true, 1e-1)); - da->decrRef(); -} - -void MEDCouplingBasicsTest4::testCheckCoherencyDeeper1() -{ - MEDCouplingUMesh *m=build3DSourceMesh_1(); - m->checkCoherency(); - m->checkCoherency1(); - m->getNodalConnectivity()->setIJ(8,0,-1); - m->checkCoherency(); - CPPUNIT_ASSERT_THROW(m->checkCoherency1(),INTERP_KERNEL::Exception); - m->getNodalConnectivity()->setIJ(8,0,-6); - m->checkCoherency(); - CPPUNIT_ASSERT_THROW(m->checkCoherency1(),INTERP_KERNEL::Exception); - m->getNodalConnectivity()->setIJ(8,0,9);//9>=NbOfNodes - m->checkCoherency(); - CPPUNIT_ASSERT_THROW(m->checkCoherency1(),INTERP_KERNEL::Exception); - m->getNodalConnectivity()->setIJ(8,0,8);//OK - m->checkCoherency(); - m->checkCoherency1(); - const int elts[2]={1,5}; - std::vector eltsV(elts,elts+2); - m->convertToPolyTypes(&eltsV[0],&eltsV[0]+eltsV.size()); - m->checkCoherency(); - m->checkCoherency1(); - m->getNodalConnectivity()->setIJ(2,0,9);//9>=NbOfNodes - m->checkCoherency(); - CPPUNIT_ASSERT_THROW(m->checkCoherency1(),INTERP_KERNEL::Exception); - m->getNodalConnectivity()->setIJ(2,0,-3); - m->checkCoherency(); - CPPUNIT_ASSERT_THROW(m->checkCoherency1(),INTERP_KERNEL::Exception); - m->getNodalConnectivity()->setIJ(2,0,-1); - m->checkCoherency(); - CPPUNIT_ASSERT_THROW(m->checkCoherency1(),INTERP_KERNEL::Exception);//Throw because cell#0 is not a polyhedron - m->getNodalConnectivity()->setIJ(2,0,4); - m->checkCoherency(); - m->checkCoherency1(); - m->getNodalConnectivity()->setIJ(7,0,-1); - m->checkCoherency(); - m->checkCoherency1();//OK because we are in polyhedron connec - m->getNodalConnectivity()->setIJ(36,0,14); - m->checkCoherency(); - CPPUNIT_ASSERT_THROW(m->checkCoherency1(),INTERP_KERNEL::Exception);//Throw beacause now cell 5 is a TETRA4 (14) so mimatch of number index and static type. - m->decrRef(); -} - -void MEDCouplingBasicsTest4::testUnPolyze2() -{ - MEDCouplingUMesh *m=MEDCouplingUMesh::New("jjj",3); - DataArrayDouble *coo=DataArrayDouble::New(); - coo->alloc(4,3); - coo->rearrange(1); - coo->iota(0); - coo->rearrange(3); - m->setCoords(coo); - coo->decrRef(); - m->allocateCells(2); - const int conn[4]={0,1,2,3}; - m->insertNextCell(INTERP_KERNEL::NORM_TETRA4,4,conn); - m->insertNextCell(INTERP_KERNEL::NORM_TETRA4,4,conn); - m->finishInsertingCells(); - std::vector ms(4,m); - MEDCouplingUMesh *m2=MEDCouplingUMesh::MergeUMeshesOnSameCoords(ms); - std::vector temp(1,2); - m2->convertToPolyTypes(&temp[0],&temp[0]+temp.size()); - m2->unPolyze(); - CPPUNIT_ASSERT(INTERP_KERNEL::NORM_TETRA4==m2->getTypeOfCell(2)); - CPPUNIT_ASSERT_EQUAL(40,m2->getMeshLength()); - std::vector temp2; - m2->getNodeIdsOfCell(2,temp2); - CPPUNIT_ASSERT(4==(int)temp2.size()); - CPPUNIT_ASSERT(std::equal(conn,conn+4,temp2.begin())); - m2->checkCoherency1(); - MEDCouplingMesh *m3=m2->deepCpy(); - m2->unPolyze(); - CPPUNIT_ASSERT(m3->isEqual(m2,1e-12)); - m3->decrRef(); - m->decrRef(); - m2->decrRef(); -} - -void MEDCouplingBasicsTest4::testDACpyFrom1() -{ - DataArrayDouble *d=DataArrayDouble::New(); - d->alloc(12,1); - d->iota(14.); - d->rearrange(3); - d->setName("Toto"); - d->setInfoOnComponent(0,"X [m]"); - d->setInfoOnComponent(1,"Y [m]"); - d->setInfoOnComponent(2,"Z [m]"); - // - DataArrayDouble *d1=DataArrayDouble::New(); - CPPUNIT_ASSERT(!d->isEqual(*d1,1e-12)); - d1->cpyFrom(*d); - CPPUNIT_ASSERT(d->isEqual(*d1,1e-12)); - d1->cpyFrom(*d); - CPPUNIT_ASSERT(d->isEqual(*d1,1e-12)); - d1->rearrange(2); - CPPUNIT_ASSERT(!d->isEqual(*d1,1e-12)); - d1->cpyFrom(*d); - CPPUNIT_ASSERT(d->isEqual(*d1,1e-12)); - // - DataArrayInt *d2=d->convertToIntArr(); - DataArrayInt *d4=DataArrayInt::New(); - CPPUNIT_ASSERT(!d2->isEqual(*d4)); - d4->cpyFrom(*d2); - CPPUNIT_ASSERT(d2->isEqual(*d4)); - d4->cpyFrom(*d2); - CPPUNIT_ASSERT(d2->isEqual(*d4)); - d4->rearrange(2); - CPPUNIT_ASSERT(!d2->isEqual(*d4)); - d4->cpyFrom(*d2); - CPPUNIT_ASSERT(d2->isEqual(*d4)); - // - d->decrRef(); - d1->decrRef(); - d2->decrRef(); - d4->decrRef(); -} - -void MEDCouplingBasicsTest4::testDAITransformWithIndArr1() -{ - const int tab1[4]={17,18,22,19}; - const int tab2[12]={0,1,1,3,3,0,1,3,2,2,3,0}; - const int expected[12]={17,18,18,19,19,17,18,19,22,22,19,17}; - DataArrayInt *d=DataArrayInt::New(); - d->alloc(4,1); - std::copy(tab1,tab1+4,d->getPointer()); - DataArrayInt *d1=DataArrayInt::New(); - d1->alloc(12,1); - std::copy(tab2,tab2+12,d1->getPointer()); - // - d1->transformWithIndArr(d->getConstPointer(),d->getConstPointer()+d->getNbOfElems()); - CPPUNIT_ASSERT_EQUAL(12,d1->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(1,d1->getNumberOfComponents()); - for(int i=0;i<12;i++) - CPPUNIT_ASSERT_EQUAL(expected[i],d1->getIJ(i,0)); - // - d->decrRef(); - d1->decrRef(); -} - -void MEDCouplingBasicsTest4::testDAIBuildPermArrPerLevel1() -{ - const int arr[12]={2,0,1,1,0,1,2,0,1,1,0,0}; - const int expected1[12]={10,0,5,6,1,7,11,2,8,9,3,4}; - DataArrayInt *da=DataArrayInt::New(); - da->alloc(12,1); - std::copy(arr,arr+12,da->getPointer()); - DataArrayInt *da2=da->buildPermArrPerLevel(); - CPPUNIT_ASSERT_EQUAL(12,da2->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(1,da2->getNumberOfComponents()); - for(int i=0;i<12;i++) - CPPUNIT_ASSERT_EQUAL(expected1[i],da2->getIJ(i,0)); - da->decrRef(); - da2->decrRef(); -} - -void MEDCouplingBasicsTest4::testDAIOperations1() -{ - const int arr1[12]={-1,-2,4,7,3,2,6,6,4,3,0,1}; - DataArrayInt *da=DataArrayInt::New(); - da->alloc(4,3); - std::copy(arr1,arr1+12,da->getPointer()); - DataArrayInt *da1=DataArrayInt::New(); - da1->alloc(12,1); - da1->iota(2); - CPPUNIT_ASSERT_THROW(DataArrayInt::Add(da,da1),INTERP_KERNEL::Exception);//not same number of tuples/Components - da1->rearrange(3); - DataArrayInt *da2=DataArrayInt::Add(da,da1); - CPPUNIT_ASSERT_EQUAL(4,da2->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(3,da2->getNumberOfComponents()); - const int expected1[12]={1,1,8,12,9,9,14,15,14,14,12,14}; - for(int i=0;i<12;i++) - CPPUNIT_ASSERT_EQUAL(expected1[i],da2->getIJ(0,i)); - da2->decrRef(); - da1->substractEqual(da); - const int expected2[12]={3,5,0,-2,3,5,2,3,6,8,12,12}; - for(int i=0;i<12;i++) - CPPUNIT_ASSERT_EQUAL(expected2[i],da1->getIJ(0,i)); - da1->rearrange(1); da1->iota(2); da1->rearrange(3); - da1->addEqual(da); - for(int i=0;i<12;i++) - CPPUNIT_ASSERT_EQUAL(expected1[i],da1->getIJ(0,i)); - da1->rearrange(1); da1->iota(2); da1->rearrange(3); - da2=DataArrayInt::Multiply(da,da1); - CPPUNIT_ASSERT_EQUAL(4,da2->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(3,da2->getNumberOfComponents()); - const int expected3[12]={-2,-6,16,35,18,14,48,54,40,33,0,13}; - for(int i=0;i<12;i++) - CPPUNIT_ASSERT_EQUAL(expected3[i],da2->getIJ(0,i)); - da2->decrRef(); - da->divideEqual(da1); - CPPUNIT_ASSERT_EQUAL(4,da->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(3,da->getNumberOfComponents()); - const int expected4[12]={0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0}; - for(int i=0;i<12;i++) - CPPUNIT_ASSERT_EQUAL(expected4[i],da->getIJ(0,i)); - std::copy(arr1,arr1+12,da->getPointer()); - da1->multiplyEqual(da); - CPPUNIT_ASSERT_EQUAL(4,da1->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(3,da1->getNumberOfComponents()); - for(int i=0;i<12;i++) - CPPUNIT_ASSERT_EQUAL(expected3[i],da1->getIJ(0,i)); - da1->rearrange(1); da1->iota(2); da1->rearrange(3); - da2=DataArrayInt::Divide(da,da1); - CPPUNIT_ASSERT_EQUAL(4,da2->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(3,da2->getNumberOfComponents()); - for(int i=0;i<12;i++) - CPPUNIT_ASSERT_EQUAL(expected4[i],da2->getIJ(0,i)); - da2->decrRef(); - da1->applyInv(321); - CPPUNIT_ASSERT_EQUAL(4,da1->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(3,da1->getNumberOfComponents()); - const int expected5[12]={160,107,80,64,53,45,40,35,32,29,26,24}; - for(int i=0;i<12;i++) - CPPUNIT_ASSERT_EQUAL(expected5[i],da1->getIJ(0,i)); - da1->applyDivideBy(2); - CPPUNIT_ASSERT_EQUAL(4,da1->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(3,da1->getNumberOfComponents()); - const int expected6[12]={80,53,40,32,26,22,20,17,16,14,13,12}; - for(int i=0;i<12;i++) - CPPUNIT_ASSERT_EQUAL(expected6[i],da1->getIJ(0,i)); - const int expected7[12]={3,4,5,4,5,1,6,3,2,0,6,5}; - da1->applyModulus(7); - for(int i=0;i<12;i++) - CPPUNIT_ASSERT_EQUAL(expected7[i],da1->getIJ(0,i)); - da1->applyLin(1,1); - const int expected8[12]={3,3,3,3,3,1,3,3,0,0,3,3}; - da1->applyRModulus(3); - for(int i=0;i<12;i++) - CPPUNIT_ASSERT_EQUAL(expected8[i],da1->getIJ(0,i)); - // - da1->decrRef(); - da->decrRef(); -} - -void MEDCouplingBasicsTest4::testEmulateMEDMEMBDC1() -{ - MEDCouplingUMesh *m1=0; - MEDCouplingUMesh *m=buildPointe_1(m1); - DataArrayInt *da1=DataArrayInt::New(); - DataArrayInt *da2=DataArrayInt::New(); - DataArrayInt *da3=0; - DataArrayInt *da4=0; - DataArrayInt *da5=0; - DataArrayInt *da0=0; - MEDCouplingUMesh *m2=m->emulateMEDMEMBDC(m1,da1,da2,da3,da4,da5,da0); - const int expected0[47]={0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,36,37,32,33,34,35,38,39,40,41,42,43,44,45,46}; - const int expected1[6]={1,32,29,23,41,36}; - CPPUNIT_ASSERT_EQUAL(47,da0->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(1,da0->getNumberOfComponents()); - for(int i=0;i<47;i++) - CPPUNIT_ASSERT_EQUAL(expected0[i],da0->getIJ(0,i)); - CPPUNIT_ASSERT_EQUAL(6,da5->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(1,da5->getNumberOfComponents()); - for(int i=0;i<6;i++) - CPPUNIT_ASSERT_EQUAL(expected1[i],da5->getIJ(0,i)); - const int expected2[70]={0,1,2,3,4,0,5,6,7,4,8,9,1,7,10,11,12,13,14,5,15,16,17,8,18,19,20,10,21,22,23,2,13,24,25,21,16,26,27,12,19,28,29,15,22,30,31,18,36,26,28,30,24,37,32,33,34,35,38,36,39,40,41,42,37,38,43,44,45,46}; - CPPUNIT_ASSERT_EQUAL(70,da1->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(1,da1->getNumberOfComponents()); - for(int i=0;i<70;i++) - CPPUNIT_ASSERT_EQUAL(expected2[i],da1->getIJ(0,i)); - const int expected3[17]={0,4,8,12,16,20,24,28,32,36,40,44,48,53,58,64,70}; - CPPUNIT_ASSERT_EQUAL(17,da2->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(1,da2->getNumberOfComponents()); - for(int i=0;i<17;i++) - CPPUNIT_ASSERT_EQUAL(expected3[i],da2->getIJ(0,i)); - const int expected4[48]={0,2,4,6,7,9,11,12,14,16,17,19,20,22,24,25,27,29,30,32,34,35,37,39,40,42,43,45,46,48,49,51,52,53,54,55,56,58,60,62,63,64,65,66,67,68,69,70}; - //const int expected4[48]={0,2,4,6,7,9,11,12,14,16,17,19,20,22,24,25,27,29,30,32,34,35,37,39,40,42,43,45,46,48,49,51,52,54,56,57,58,59,60,62,63,64,65,66,67,68,69,70}; - CPPUNIT_ASSERT_EQUAL(48,da4->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(1,da4->getNumberOfComponents()); - for(int i=0;i<48;i++) - CPPUNIT_ASSERT_EQUAL(expected4[i],da4->getIJ(0,i)); - const int expected5[70]={0,1,0,3,0,7,0,1,2,1,4,1,2,3,2,5,2,3,6,3,4,9,4,8,4,5,10,5,9,5,6,11,6,10,6,7,8,7,11,7,8,12,8,9,12,9,10,12,10,11,12,11,13,13,13,13,12,14,13,15,14,15,14,14,14,14,15,15,15,15}; - CPPUNIT_ASSERT_EQUAL(70,da3->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(1,da3->getNumberOfComponents()); - for(int i=0;i<70;i++) - CPPUNIT_ASSERT_EQUAL(expected5[i],da3->getIJ(0,i)); - // - da0->decrRef(); - da1->decrRef(); - da2->decrRef(); - da3->decrRef(); - da4->decrRef(); - da5->decrRef(); - // - m2->decrRef(); - m1->decrRef(); - m->decrRef(); -} - -void MEDCouplingBasicsTest4::testGetLevArrPerCellTypes1() -{ - MEDCouplingUMesh *m1=0; - MEDCouplingUMesh *m=buildPointe_1(m1); - m1->decrRef(); - DataArrayInt *d0=DataArrayInt::New(); - DataArrayInt *d1=DataArrayInt::New(); - DataArrayInt *d2=DataArrayInt::New(); - DataArrayInt *d3=DataArrayInt::New(); - m1=m->buildDescendingConnectivity(d0,d1,d2,d3); - d0->decrRef(); d1->decrRef(); d2->decrRef(); d3->decrRef(); - INTERP_KERNEL::NormalizedCellType order[2]={INTERP_KERNEL::NORM_TRI3,INTERP_KERNEL::NORM_QUAD4}; - DataArrayInt *da1=0; - DataArrayInt *da0=m1->getLevArrPerCellTypes(order,order+2,da1); - const int expected0[47]={0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,1,1,1,1,1,1,1,1,1}; - const int expected1[47]={0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,36,37,32,33,34,35,38,39,40,41,42,43,44,45,46}; - CPPUNIT_ASSERT_EQUAL(47,da0->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(1,da0->getNumberOfComponents()); - for(int i=0;i<47;i++) - CPPUNIT_ASSERT_EQUAL(expected0[i],da0->getIJ(0,i)); - CPPUNIT_ASSERT_EQUAL(2,da1->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(1,da1->getNumberOfComponents()); - CPPUNIT_ASSERT_EQUAL(36,da1->getIJ(0,0));//36 TRI3 - CPPUNIT_ASSERT_EQUAL(11,da1->getIJ(1,0));//11 QUAD4 - // - DataArrayInt *da2=da0->buildPermArrPerLevel(); - // - CPPUNIT_ASSERT_EQUAL(47,da2->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(1,da2->getNumberOfComponents()); - for(int i=0;i<47;i++) - CPPUNIT_ASSERT_EQUAL(expected1[i],da2->getIJ(0,i)); - da2->decrRef(); - da0->decrRef(); - da1->decrRef(); - // - m->decrRef(); - m1->decrRef(); -} - -void MEDCouplingBasicsTest4::testSortCellsInMEDFileFrmt1() -{ - MEDCouplingUMesh *m1=0; - MEDCouplingUMesh *m=buildPointe_1(m1); - MEDCouplingUMesh *m2=(MEDCouplingUMesh *)m->deepCpy(); - m->setCoords(0); - const int vals[16]={0,1,2,14,3,12,4,5,15,6,7,8,9,10,11,13}; - DataArrayInt *da=DataArrayInt::New(); - da->alloc(16,1); - std::copy(vals,vals+16,da->getPointer()); - DataArrayInt *daa=da->invertArrayN2O2O2N(16); - m->renumberCells(daa->getConstPointer(),false); - daa->decrRef(); - DataArrayInt *da2=m->sortCellsInMEDFileFrmt(); - CPPUNIT_ASSERT(m2->isEqual(m2,1e-12)); - CPPUNIT_ASSERT(da->isEqual(*da2)); - m2->decrRef(); - da2->decrRef(); - da->decrRef(); - m1->decrRef(); - m->decrRef(); -} - -void MEDCouplingBasicsTest4::testBuildPartAndReduceNodes1() -{ - MEDCouplingMesh *m=build2DTargetMesh_1(); - const int arr[2]={1,0}; - DataArrayInt *da; - MEDCouplingMesh *m2=m->buildPartAndReduceNodes(arr,arr+2,da); - CPPUNIT_ASSERT_EQUAL(5,m2->getNumberOfNodes()); - CPPUNIT_ASSERT_EQUAL(2,m2->getNumberOfCells()); - MEDCouplingFieldDouble *f=m2->getMeasureField(true); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.125,f->getArray()->getIJ(0,0),1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.25,f->getArray()->getIJ(1,0),1e-12); - f->decrRef(); - da->decrRef(); - m2->decrRef(); - m->decrRef(); -} - -void MEDCouplingBasicsTest4::testDAITransformWithIndArrR1() -{ - const int tab1[6]={2,4,5,3,6,7}; - const int tab2[12]={-1,-1,0,1,2,3,4,5,-1,-1,-1,-1}; - const int expected[6]={0,3,1,2,4,5}; - DataArrayInt *d=DataArrayInt::New(); - d->alloc(6,1); - std::copy(tab1,tab1+6,d->getPointer()); - DataArrayInt *d1=DataArrayInt::New(); - d1->alloc(12,1); - std::copy(tab2,tab2+12,d1->getPointer()); - // - DataArrayInt *d3=d->transformWithIndArrR(d1->getConstPointer(),d1->getConstPointer()+d1->getNbOfElems()); - CPPUNIT_ASSERT_EQUAL(6,d3->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(1,d3->getNumberOfComponents()); - for(int i=0;i<6;i++) - CPPUNIT_ASSERT_EQUAL(expected[i],d3->getIJ(i,0)); - d3->decrRef(); - // - d->decrRef(); - d1->decrRef(); -} - -void MEDCouplingBasicsTest4::testDAISplitByValueRange1() -{ - const int val1[9]={6,5,0,3,2,7,8,1,4}; - const int val2[3]={0,4,9}; - DataArrayInt *d=DataArrayInt::New(); - d->alloc(9,1); - std::copy(val1,val1+9,d->getPointer()); - DataArrayInt *ee=0,*f=0,*g=0; - d->splitByValueRange(val2,val2+3,ee,f,g); - CPPUNIT_ASSERT_EQUAL(9,ee->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(1,ee->getNumberOfComponents()); - CPPUNIT_ASSERT_EQUAL(9,f->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(1,f->getNumberOfComponents()); - CPPUNIT_ASSERT_EQUAL(2,g->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(1,g->getNumberOfComponents()); - // - const int expected1[9]={1,1,0,0,0,1,1,0,1}; - const int expected2[9]={2,1,0,3,2,3,4,1,0}; - for(int i=0;i<9;i++) - { - CPPUNIT_ASSERT_EQUAL(expected1[i],ee->getIJ(i,0)); - CPPUNIT_ASSERT_EQUAL(expected2[i],f->getIJ(i,0)); - } - CPPUNIT_ASSERT_EQUAL(0,g->getIJ(0,0)); - CPPUNIT_ASSERT_EQUAL(1,g->getIJ(1,0)); - // - ee->decrRef(); - f->decrRef(); - g->decrRef(); - // - d->setIJ(6,0,9); - CPPUNIT_ASSERT_THROW(d->splitByValueRange(val2,val2+3,ee,f,g),INTERP_KERNEL::Exception); - // - d->decrRef(); -} - -void MEDCouplingBasicsTest4::testUMeshSplitProfilePerType1() -{ - const int val0[5]={2,0,1,3,4}; - MEDCouplingUMesh *m=build2DTargetMesh_1(); - m->renumberCells(val0,false); - std::vector code; - std::vector idsInPflPerType; - std::vector pfls; - // - const int val1[3]={0,2,3}; - DataArrayInt *d=DataArrayInt::New(); - d->alloc(3,1); - d->setName("sup"); - std::copy(val1,val1+3,d->getPointer()); - m->splitProfilePerType(d,code,idsInPflPerType,pfls); - CPPUNIT_ASSERT_EQUAL(6,(int)code.size()); - CPPUNIT_ASSERT_EQUAL(2,(int)idsInPflPerType.size()); - const int expected1[6]={3,1,0, 4,2,1}; - for(int i=0;i<6;i++) - CPPUNIT_ASSERT_EQUAL(expected1[i],code[i]); - CPPUNIT_ASSERT_EQUAL(1,idsInPflPerType[0]->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(0,idsInPflPerType[0]->getIJ(0,0)); - CPPUNIT_ASSERT_EQUAL(2,idsInPflPerType[1]->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(1,idsInPflPerType[1]->getIJ(0,0)); - CPPUNIT_ASSERT_EQUAL(2,idsInPflPerType[1]->getIJ(1,0)); - idsInPflPerType[0]->decrRef(); - idsInPflPerType[1]->decrRef(); - CPPUNIT_ASSERT_EQUAL(2,(int)pfls.size()); - CPPUNIT_ASSERT(std::string("sup")==pfls[0]->getName()); - CPPUNIT_ASSERT_EQUAL(1,pfls[0]->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(0,pfls[0]->getIJ(0,0)); - CPPUNIT_ASSERT(std::string("sup")==pfls[1]->getName()); - CPPUNIT_ASSERT_EQUAL(2,pfls[1]->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(0,pfls[1]->getIJ(0,0)); - CPPUNIT_ASSERT_EQUAL(1,pfls[1]->getIJ(1,0)); - pfls[0]->decrRef(); - pfls[1]->decrRef(); - d->decrRef(); - idsInPflPerType.clear(); - pfls.clear(); - code.clear(); - // - const int val2[4]={0,2,3,4};// all quad4 are selected here ! So no profile for Quads - d=DataArrayInt::New(); - d->alloc(4,1); - std::copy(val2,val2+4,d->getPointer()); - m->splitProfilePerType(d,code,idsInPflPerType,pfls); - CPPUNIT_ASSERT_EQUAL(6,(int)code.size()); - CPPUNIT_ASSERT_EQUAL(2,(int)idsInPflPerType.size()); - const int expected2[6]={3,1,0, 4,3,-1}; - for(int i=0;i<6;i++) - CPPUNIT_ASSERT_EQUAL(expected2[i],code[i]); - CPPUNIT_ASSERT_EQUAL(1,idsInPflPerType[0]->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(0,idsInPflPerType[0]->getIJ(0,0)); - CPPUNIT_ASSERT_EQUAL(3,idsInPflPerType[1]->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(1,idsInPflPerType[1]->getIJ(0,0)); - CPPUNIT_ASSERT_EQUAL(2,idsInPflPerType[1]->getIJ(1,0)); - CPPUNIT_ASSERT_EQUAL(3,idsInPflPerType[1]->getIJ(2,0)); - idsInPflPerType[0]->decrRef(); - idsInPflPerType[1]->decrRef(); - CPPUNIT_ASSERT_EQUAL(1,(int)pfls.size()); - CPPUNIT_ASSERT_EQUAL(1,pfls[0]->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(0,pfls[0]->getIJ(0,0)); - pfls[0]->decrRef(); - d->decrRef(); - idsInPflPerType.clear(); - pfls.clear(); - code.clear(); - // - const int val3[3]={1,0,2};// all tri3 are selected here but not in the same order ! Profile requested for Tri3 - d=DataArrayInt::New(); - d->alloc(3,1); - std::copy(val3,val3+3,d->getPointer()); - m->splitProfilePerType(d,code,idsInPflPerType,pfls); - CPPUNIT_ASSERT_EQUAL(6,(int)code.size()); - CPPUNIT_ASSERT_EQUAL(2,(int)idsInPflPerType.size()); - const int expected3[6]={3,2,0, 4,1,1}; - for(int i=0;i<6;i++) - CPPUNIT_ASSERT_EQUAL(expected3[i],code[i]); - CPPUNIT_ASSERT_EQUAL(2,idsInPflPerType[0]->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(0,idsInPflPerType[0]->getIJ(0,0)); - CPPUNIT_ASSERT_EQUAL(1,idsInPflPerType[0]->getIJ(1,0)); - CPPUNIT_ASSERT_EQUAL(1,idsInPflPerType[1]->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(2,idsInPflPerType[1]->getIJ(0,0)); - idsInPflPerType[0]->decrRef(); - idsInPflPerType[1]->decrRef(); - CPPUNIT_ASSERT_EQUAL(2,(int)pfls.size()); - CPPUNIT_ASSERT_EQUAL(2,pfls[0]->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(1,pfls[0]->getIJ(0,0)); - CPPUNIT_ASSERT_EQUAL(0,pfls[0]->getIJ(1,0)); - CPPUNIT_ASSERT_EQUAL(0,pfls[1]->getIJ(0,0)); - pfls[0]->decrRef(); - pfls[1]->decrRef(); - d->decrRef(); - idsInPflPerType.clear(); - pfls.clear(); - code.clear(); - // - const int val4[2]={3,4};// all tri3 are selected here but not in the same order ! Profile requested for Tri3 - d=DataArrayInt::New(); - d->alloc(2,1); - std::copy(val4,val4+2,d->getPointer()); - m->splitProfilePerType(d,code,idsInPflPerType,pfls); - CPPUNIT_ASSERT_EQUAL(3,(int)code.size()); - CPPUNIT_ASSERT_EQUAL(1,(int)idsInPflPerType.size()); - const int expected4[3]={4,2,0}; - for(int i=0;i<3;i++) - CPPUNIT_ASSERT_EQUAL(expected4[i],code[i]); - CPPUNIT_ASSERT_EQUAL(2,idsInPflPerType[0]->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(0,idsInPflPerType[0]->getIJ(0,0)); - CPPUNIT_ASSERT_EQUAL(1,idsInPflPerType[0]->getIJ(1,0)); - idsInPflPerType[0]->decrRef(); - CPPUNIT_ASSERT_EQUAL(1,(int)pfls.size()); - CPPUNIT_ASSERT_EQUAL(2,pfls[0]->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(1,pfls[0]->getIJ(0,0)); - CPPUNIT_ASSERT_EQUAL(2,pfls[0]->getIJ(1,0)); - pfls[0]->decrRef(); - d->decrRef(); - idsInPflPerType.clear(); - pfls.clear(); - code.clear(); - // - m->decrRef(); -} - -void MEDCouplingBasicsTest4::testDAIBuildExplicitArrByRanges1() -{ - DataArrayInt *d=DataArrayInt::New(); - d->alloc(3,1); - const int vals1[3]={0,2,3}; - std::copy(vals1,vals1+3,d->getPointer()); - DataArrayInt *e=DataArrayInt::New(); - e->alloc(6,1); - const int vals2[6]={0,3,6,10,14,20}; - std::copy(vals2,vals2+6,e->getPointer()); - // - DataArrayInt *f=d->buildExplicitArrByRanges(e); - CPPUNIT_ASSERT_EQUAL(11,f->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(1,f->getNumberOfComponents()); - const int expected1[11]={0,1,2,6,7,8,9,10,11,12,13}; - for(int i=0;i<11;i++) - CPPUNIT_ASSERT_EQUAL(expected1[i],f->getIJ(i,0)); - // - f->decrRef(); - e->decrRef(); - d->decrRef(); -} - -void MEDCouplingBasicsTest4::testDAIComputeOffsets2() -{ - DataArrayInt *d=DataArrayInt::New(); - const int vals1[6]={3,5,1,2,0,8}; - const int expected1[7]={0,3,8,9,11,11,19}; - d->alloc(6,1); - std::copy(vals1,vals1+6,d->getPointer()); - d->computeOffsets2(); - CPPUNIT_ASSERT_EQUAL(7,d->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(1,d->getNumberOfComponents()); - for(int i=0;i<7;i++) - CPPUNIT_ASSERT_EQUAL(expected1[i],d->getIJ(0,i)); - d->decrRef(); -} - -void MEDCouplingBasicsTest4::testMergeField3() -{ - MEDCouplingUMesh *m=build2DTargetMesh_1(); - m->getCoords()->setInfoOnComponent(0,"x [m]"); - m->getCoords()->setInfoOnComponent(1,"z [km]"); - m->setName("m"); - m->setDescription("desc"); - MEDCouplingFieldDouble *f1=MEDCouplingFieldDouble::New(ON_CELLS,ONE_TIME); - f1->setName("f1"); - f1->setMesh(m); - DataArrayDouble *arr=DataArrayDouble::New(); - arr->alloc(5,2); - arr->setInfoOnComponent(0,"X [m]"); - arr->setInfoOnComponent(1,"YY [mm]"); - arr->fillWithValue(2.); - f1->setArray(arr); - arr->decrRef(); - m->decrRef(); - // - std::vector tmp(1); - tmp[0]=f1; - MEDCouplingFieldDouble *f2=MEDCouplingFieldDouble::MergeFields(tmp); - CPPUNIT_ASSERT(f1->isEqual(f2,1e-12,1e-12)); - // - f1->decrRef(); - f2->decrRef(); -} - -void MEDCouplingBasicsTest4::testGetDistributionOfTypes1() -{ - MEDCouplingUMesh *m=build2DTargetMesh_1(); - const int tab1[5]={2,0,1,3,4}; - CPPUNIT_ASSERT_THROW(m->getDistributionOfTypes(),INTERP_KERNEL::Exception); - m->renumberCells(tab1,false); - std::vector code=m->getDistributionOfTypes(); - CPPUNIT_ASSERT_EQUAL(6,(int)code.size()); - CPPUNIT_ASSERT_EQUAL(3,code[0]); - CPPUNIT_ASSERT_EQUAL(2,code[1]); - CPPUNIT_ASSERT_EQUAL(-1,code[2]); - CPPUNIT_ASSERT_EQUAL(4,code[3]); - CPPUNIT_ASSERT_EQUAL(3,code[4]); - CPPUNIT_ASSERT_EQUAL(-1,code[5]); - m->decrRef(); -} - -void MEDCouplingBasicsTest4::testNorm2_1() -{ - MEDCouplingUMesh *m=build2DTargetMesh_1(); - MEDCouplingFieldDouble *f=MEDCouplingFieldDouble::New(ON_CELLS,ONE_TIME); - f->setMesh(m); - m->decrRef(); - // - DataArrayDouble *d=DataArrayDouble::New(); - const double tab[10]={1.2,1.3,2.2,2.3,3.2,3.3,4.2,4.3,5.2,5.3}; - d->alloc(5,2); - std::copy(tab,tab+10,d->getPointer()); - f->setArray(d); - d->decrRef(); - f->checkCoherency(); - // - CPPUNIT_ASSERT_DOUBLES_EQUAL(11.209371079592289,f->norm2(),1e-14); - // - f->decrRef(); -} - -void MEDCouplingBasicsTest4::testNormMax1() -{ - MEDCouplingUMesh *m=build2DTargetMesh_1(); - MEDCouplingFieldDouble *f=MEDCouplingFieldDouble::New(ON_CELLS,ONE_TIME); - f->setMesh(m); - m->decrRef(); - // - DataArrayDouble *d=DataArrayDouble::New(); - const double tab[10]={2.3,-1.2,6.3,-7.8,2.9,7.7,2.1,0.,3.6,-7.6}; - d->alloc(5,2); - std::copy(tab,tab+10,d->getPointer()); - f->setArray(d); - d->decrRef(); - f->checkCoherency(); - // - CPPUNIT_ASSERT_DOUBLES_EQUAL(7.8,f->normMax(),1e-14); - // - f->decrRef(); -} - -void MEDCouplingBasicsTest4::testFindAndCorrectBadOriented3DExtrudedCells1() -{ - const double coords[38*3]={0.0011180339887498999, -0.0011755705045849499, 0.0, -0.0012331070204200001, -0.0011755705045849499, 0.0, -0.00067557050458494599, -0.00145964954842536, 0.0, -0.00050000000000000001, -0.00086602540378443902, 0.0, 0.00140211303259031, -0.00061803398874989504, 0.0, 0.00086602540378443902, -0.00050000000000000001, 0.0, 0.001, 0.0, 0.0, 0.00034561537182258202, 0.000269164072574575, 0.0, 0.0, 0.001, 0.0, -0.00050000000000000001, 0.00086602540378443902, 0.0, -0.000269164072574575, 0.00034561537182258202, 0.0, -0.001, 0.0, 0.0, -0.00086602540378443902, -0.00050000000000000001, 0.0, -0.00034561537182258202, -0.000269164072574575, 0.0, 0.0, -0.001, 0.0, 0.00050000000000000001, -0.00086602540378443902, 0.0, 0.000269164072574575, -0.00034561537182258202, 0.0, 0.0015, -6.01853107621011e-36, 0.0, 0.00056049747291484397, -0.00145964954842536, 0.0, 0.0011180339887498999, -0.0011755705045849499, 0.00050000000000000001, -0.0012331070204200001, -0.0011755705045849499, 0.00050000000000000001, -0.00067557050458494599, -0.00145964954842536, 0.00050000000000000001, -0.00050000000000000001, -0.00086602540378443902, 0.00050000000000000001, 0.00140211303259031, -0.00061803398874989504, 0.00050000000000000001, 0.00086602540378443902, -0.00050000000000000001, 0.00050000000000000001, 0.001, 0.0, 0.00050000000000000001, 0.00034561537182258202, 0.000269164072574575, 0.00050000000000000001, 0.0, 0.001, 0.00050000000000000001, -0.00050000000000000001, 0.00086602540378443902, 0.00050000000000000001, -0.000269164072574575, 0.00034561537182258202, 0.00050000000000000001, -0.001, 0.0, 0.00050000000000000001, -0.00086602540378443902, -0.00050000000000000001, 0.00050000000000000001, -0.00034561537182258202, -0.000269164072574575, 0.00050000000000000001, 0.0, -0.001, 0.00050000000000000001, 0.00050000000000000001, -0.00086602540378443902, 0.00050000000000000001, 0.000269164072574575, -0.00034561537182258202, 0.00050000000000000001, 0.0015, -6.01853107621011e-36, 0.00050000000000000001, 0.00056049747291484397, -0.00145964954842536, 0.00050000000000000001}; - const int conn[56]={2, 1, 3, 21, 20, 22, 4, 0, 5, 23, 19, 24, 8, 9, 10, 27, 28, 29, 11, 12, 13, 30, 31, 32, 0, 18, 15, 5, 19, 37, 34, 24, 6, 17, 4, 5, 25, 36, 23, 24, 3, 14, 16, 13, 22, 33, 35, 32, 13, 16, 7, 10, 32, 35, 26, 29}; - const int connExp[64]={16, 2, 1, 3, 21, 20, 22, 16, 4, 0, 5, 23, 19, 24, 16, 8, 10, 9, 27, 29, 28, 16, 11, 13, 12, 30, 32, 31, 18, 0, 18, 15, 5, 19, 37, 34, 24,18, 6, 17, 4, 5, 25, 36, 23, 24, 18, 3, 13, 16, 14, 22, 32, 35, 33, 18, 13, 10, 7, 16, 32, 29, 26, 35}; - const int invalidCells[4]={2,3,6,7}; - MEDCouplingUMesh *m=MEDCouplingUMesh::New("Example",3); - DataArrayDouble *coo=DataArrayDouble::New(); - coo->alloc(38,3); - std::copy(coords,coords+114,coo->getPointer()); - m->setCoords(coo); - coo->decrRef(); - m->allocateCells(8); - m->insertNextCell(INTERP_KERNEL::NORM_PENTA6,6,conn); - m->insertNextCell(INTERP_KERNEL::NORM_PENTA6,6,conn+6); - m->insertNextCell(INTERP_KERNEL::NORM_PENTA6,6,conn+12); - m->insertNextCell(INTERP_KERNEL::NORM_PENTA6,6,conn+18); - m->insertNextCell(INTERP_KERNEL::NORM_HEXA8,8,conn+24); - m->insertNextCell(INTERP_KERNEL::NORM_HEXA8,8,conn+32); - m->insertNextCell(INTERP_KERNEL::NORM_HEXA8,8,conn+40); - m->insertNextCell(INTERP_KERNEL::NORM_HEXA8,8,conn+48); - m->finishInsertingCells(); - // - DataArrayInt *v=m->findAndCorrectBadOriented3DExtrudedCells(); - CPPUNIT_ASSERT_EQUAL(4,v->getNumberOfTuples()); - CPPUNIT_ASSERT(std::equal(v->begin(),v->end(),invalidCells)); - CPPUNIT_ASSERT(std::equal(connExp,connExp+64,m->getNodalConnectivity()->getConstPointer())); - v->decrRef(); - // - m->decrRef(); -} - -void MEDCouplingBasicsTest4::testConvertExtrudedPolyhedra1() -{ - const int conn[72]={1,2,3,4, 5,6,7,8,9,10,11,12, 13,14,15,16, 17,18,19,20,21,22, 23,24,25,26,27,28, 29,30,31,32,33,34,35,36,37,38, 39,40,41,42,43,44,45,46, 47,48,49,50,51,52,53,54,55,56,57,58, 59,60,61,62,63,64,65,66,67,68,69,70,71,72}; - MEDCouplingUMesh *m=MEDCouplingUMesh::New("Example",3); - DataArrayDouble *coo=DataArrayDouble::New(); - coo->alloc(73,3); - coo->rearrange(1); coo->iota(0); coo->rearrange(3); - m->setCoords(coo); - coo->decrRef(); - m->allocateCells(9); - m->insertNextCell(INTERP_KERNEL::NORM_TETRA4,4,conn); - m->insertNextCell(INTERP_KERNEL::NORM_HEXA8,8,conn+4); - m->insertNextCell(INTERP_KERNEL::NORM_TETRA4,4,conn+12); - m->insertNextCell(INTERP_KERNEL::NORM_POLYHED,6,conn+16); - m->insertNextCell(INTERP_KERNEL::NORM_PENTA6,6,conn+22); - m->insertNextCell(INTERP_KERNEL::NORM_POLYHED,10,conn+28); - m->insertNextCell(INTERP_KERNEL::NORM_HEXA8,8,conn+38); - m->insertNextCell(INTERP_KERNEL::NORM_HEXGP12,12,conn+46); - m->insertNextCell(INTERP_KERNEL::NORM_POLYHED,14,conn+58); - m->finishInsertingCells(); - // - m->convertExtrudedPolyhedra(); - DataArrayInt *da=m->getNodalConnectivity(); - DataArrayInt *dai=m->getNodalConnectivityIndex(); - CPPUNIT_ASSERT_EQUAL((std::size_t)10,dai->getNbOfElems()); - CPPUNIT_ASSERT_EQUAL((std::size_t)159,da->getNbOfElems()); - // - const int expected1[159]={14,1,2,3,4, - 18,5,6,7,8,9,10,11,12, - 14,13,14,15,16, - 31,17,18,19,-1,20,22,21,-1,17,20,21,18,-1,18,21,22,19,-1,19,22,20,17, - 16,23,24,25,26,27,28, - 31,29,30,31,32,33,-1,34,38,37,36,35,-1,29,34,35,30,-1,30,35,36,31,-1,31,36,37,32,-1,32,37,38,33,-1,33,38,34,29, - 18,39,40,41,42,43,44,45,46, - 22,47,48,49,50,51,52,53,54,55,56,57,58, - 31,59,60,61,62,63,64,65,-1,66,72,71,70,69,68,67,-1,59,66,67,60,-1,60,67,68,61,-1,61,68,69,62,-1,62,69,70,63,-1,63,70,71,64,-1,64,71,72,65,-1,65,72,66,59}; - const int expected2[10]={0,5,14,19,42,49,86,95,108,159}; - CPPUNIT_ASSERT(std::equal(expected1,expected1+159,da->getConstPointer())); - CPPUNIT_ASSERT(std::equal(expected2,expected2+10,dai->getConstPointer())); - m->checkCoherency2(); - // - m->decrRef(); -} - -void MEDCouplingBasicsTest4::testNonRegressionCopyTinyStrings() -{ - MEDCouplingUMesh *m=build2DTargetMesh_1(); - MEDCouplingFieldDouble *f1=m->getMeasureField(true); - f1->getArray()->setInfoOnComponent(0,"P [N/m^2]"); - DataArrayDouble *bary=m->getBarycenterAndOwner(); - MEDCouplingFieldDouble *f2=f1->buildNewTimeReprFromThis(NO_TIME,false); - f2->setArray(bary); - CPPUNIT_ASSERT_THROW(f1->copyTinyAttrFrom(f2),INTERP_KERNEL::Exception); - m->decrRef(); - f1->decrRef(); - bary->decrRef(); - f2->decrRef(); -} - -void MEDCouplingBasicsTest4::testDaDSetPartOfValuesAdv1() -{ - const double tab1[18]={3.,4.,5., 13.,14.,15., 23.,24.,25., 33.,34.,35., 43.,44.,45., 53.,54.,55.}; - const double tab2[9]={6.,7.,8., 16.,17.,18., 26.,27.,28.}; - const int tab3[6]={4,1, 2,2, 3,0}; - DataArrayDouble *a=DataArrayDouble::New(); - a->alloc(6,3); - std::copy(tab1,tab1+18,a->getPointer()); - DataArrayDouble *b=DataArrayDouble::New(); - b->alloc(3,3); - std::copy(tab2,tab2+9,b->getPointer()); - DataArrayInt *c=DataArrayInt::New(); - c->alloc(3,2); - std::copy(tab3,tab3+6,c->getPointer()); - // - a->setPartOfValuesAdv(b,c); - const double expected1[18]={3.,4.,5., 13.,14.,15., 26.,27.,28., 6.,7.,8., 16.,17.,18., 53.,54.,55.}; - std::equal(expected1,expected1+18,a->getConstPointer()); - // - a->decrRef(); - b->decrRef(); - c->decrRef(); -} - -void MEDCouplingBasicsTest4::testUMeshBuildSetInstanceFromThis1() -{ - MEDCouplingUMesh *m=build3DSurfTargetMesh_1(); - MEDCouplingUMesh *m2=m->buildSetInstanceFromThis(3); - CPPUNIT_ASSERT_EQUAL(m->getNodalConnectivity(),m2->getNodalConnectivity()); - CPPUNIT_ASSERT_EQUAL(m->getNodalConnectivityIndex(),m2->getNodalConnectivityIndex()); - CPPUNIT_ASSERT_EQUAL(m->getCoords(),m2->getCoords()); - m2->decrRef(); - m->decrRef(); - // - m=MEDCouplingUMesh::New("toto",2); - m2=m->buildSetInstanceFromThis(3); - CPPUNIT_ASSERT_EQUAL(0,m2->getNumberOfNodes()); - CPPUNIT_ASSERT_EQUAL(0,m2->getNumberOfCells()); - m->decrRef(); - m2->decrRef(); -} - -void MEDCouplingBasicsTest4::testUMeshMergeMeshesCVW1() -{ - MEDCouplingUMesh *m=build3DSurfTargetMesh_1(); - MEDCouplingUMesh *m2=MEDCouplingUMesh::New("toto",2); - MEDCouplingUMesh *m3=MEDCouplingUMesh::MergeUMeshes(m,m2); - m3->setName(m->getName().c_str()); - CPPUNIT_ASSERT(m->isEqual(m3,1e-12)); - m3->decrRef(); - m->decrRef(); - m2->decrRef(); -} - -void MEDCouplingBasicsTest4::testChangeUnderlyingMeshWithCMesh1() -{ - MEDCouplingCMesh* mesh=MEDCouplingCMesh::New(); - DataArrayDouble* coordsX=DataArrayDouble::New(); - double arrX[4] = { -1., 1., 2., 4. }; - coordsX->useArray(arrX,false, CPP_DEALLOC,4,1); - DataArrayDouble* coordsY=DataArrayDouble::New(); - double arrY[4] = { -2., 2., 4., 8. }; - coordsY->useArray(arrY,false, CPP_DEALLOC,4,1); - DataArrayDouble* coordsZ=DataArrayDouble::New(); - double arrZ[4] = { -3., 3., 6., 12. }; - coordsZ->useArray(arrZ,false, CPP_DEALLOC,4,1); - mesh->setCoords(coordsX,coordsY,coordsZ); - coordsX->decrRef(); - coordsY->decrRef(); - coordsZ->decrRef(); - MEDCouplingMesh *mesh2=mesh->deepCpy(); - // - static const int ids1[9]={0,1,2,10,11,12,20,21,22}; - for(const int *myId=ids1;myId!=ids1+9;myId++) - { - MEDCouplingFieldDouble *f=mesh->getMeasureField(true); - f->changeUnderlyingMesh(mesh2,*myId,1e-12); - f->decrRef(); - } - mesh2->setName("uuuu"); - for(const int *myId=ids1+1;myId!=ids1+9;myId++) - { - MEDCouplingFieldDouble *f=mesh->getMeasureField(true); - f->changeUnderlyingMesh(mesh2,*myId,1e-12); - f->decrRef(); - } - // - mesh2->decrRef(); - mesh->decrRef(); -} - -void MEDCouplingBasicsTest4::testDADFindCommonTuples1() -{ - DataArrayDouble *da=DataArrayDouble::New(); - da->alloc(6,1); - const double array1[6]={2.3,1.2,1.3,2.3,2.301,0.8}; - std::copy(array1,array1+6,da->getPointer()); - DataArrayInt *c=0,*cI=0; - // nbOftuples=1 - da->findCommonTuples(1e-2,-1,c,cI); - const int expected1[3]={0,3,4}; - const int expected2[2]={0,3}; - CPPUNIT_ASSERT_EQUAL((std::size_t)3,c->getNbOfElems()); - CPPUNIT_ASSERT_EQUAL((std::size_t)2,cI->getNbOfElems()); - CPPUNIT_ASSERT(std::equal(expected1,expected1+3,c->getConstPointer())); - CPPUNIT_ASSERT(std::equal(expected2,expected2+2,cI->getConstPointer())); - c->decrRef(); - cI->decrRef(); - // - da->findCommonTuples(2e-1,-1,c,cI); - const int expected3[5]={0,3,4,1,2}; - const int expected4[3]={0,3,5}; - CPPUNIT_ASSERT_EQUAL((std::size_t)5,c->getNbOfElems()); - CPPUNIT_ASSERT_EQUAL((std::size_t)3,cI->getNbOfElems()); - CPPUNIT_ASSERT(std::equal(expected3,expected3+5,c->getConstPointer())); - CPPUNIT_ASSERT(std::equal(expected4,expected4+3,cI->getConstPointer())); - c->decrRef(); - cI->decrRef(); - // nbOftuples=2 - da->alloc(6,2); - const double array2[12]={2.3,2.3,1.2,1.2,1.3,1.3,2.3,2.3,2.301,2.301,0.8,0.8}; - std::copy(array2,array2+12,da->getPointer()); - da->findCommonTuples(1e-2,-1,c,cI); - CPPUNIT_ASSERT_EQUAL((std::size_t)3,c->getNbOfElems()); - CPPUNIT_ASSERT_EQUAL((std::size_t)2,cI->getNbOfElems()); - CPPUNIT_ASSERT(std::equal(expected1,expected1+3,c->getConstPointer())); - CPPUNIT_ASSERT(std::equal(expected2,expected2+2,cI->getConstPointer())); - c->decrRef(); - cI->decrRef(); - // - da->findCommonTuples(2e-1,-1,c,cI); - CPPUNIT_ASSERT_EQUAL((std::size_t)5,c->getNbOfElems()); - CPPUNIT_ASSERT_EQUAL((std::size_t)3,cI->getNbOfElems()); - CPPUNIT_ASSERT(std::equal(expected3,expected3+5,c->getConstPointer())); - CPPUNIT_ASSERT(std::equal(expected4,expected4+3,cI->getConstPointer())); - c->decrRef(); - cI->decrRef(); - // nbOftuples=3 - da->alloc(6,3); - const double array3[18]={2.3,2.3,2.3,1.2,1.2,1.2,1.3,1.3,1.3,2.3,2.3,2.3,2.301,2.301,2.301,0.8,0.8,0.8}; - std::copy(array3,array3+18,da->getPointer()); - da->findCommonTuples(1e-2,-1,c,cI); - CPPUNIT_ASSERT_EQUAL((std::size_t)3,c->getNbOfElems()); - CPPUNIT_ASSERT_EQUAL((std::size_t)2,cI->getNbOfElems()); - CPPUNIT_ASSERT(std::equal(expected1,expected1+3,c->getConstPointer())); - CPPUNIT_ASSERT(std::equal(expected2,expected2+2,cI->getConstPointer())); - c->decrRef(); - cI->decrRef(); - // - da->findCommonTuples(2e-1,-1,c,cI); - CPPUNIT_ASSERT_EQUAL((std::size_t)5,c->getNbOfElems()); - CPPUNIT_ASSERT_EQUAL((std::size_t)3,cI->getNbOfElems()); - CPPUNIT_ASSERT(std::equal(expected3,expected3+5,c->getConstPointer())); - CPPUNIT_ASSERT(std::equal(expected4,expected4+3,cI->getConstPointer())); - c->decrRef(); - cI->decrRef(); - // - const double array11[6]={2.3,1.2,1.3,2.4,2.5,0.8}; - da->alloc(6,1); - std::copy(array11,array11+6,da->getPointer()); - // nbOftuples=1, no common groups - da->findCommonTuples(1e-2,-1,c,cI); - CPPUNIT_ASSERT_EQUAL((std::size_t)0,c->getNbOfElems()); - CPPUNIT_ASSERT_EQUAL((std::size_t)1,cI->getNbOfElems()); - CPPUNIT_ASSERT_EQUAL(0,cI->getIJ(0,0)); - - da->alloc(6,5); //bad NumberOfComponents - CPPUNIT_ASSERT_THROW(da->findCommonTuples(1e-2,-1,c,cI),INTERP_KERNEL::Exception); - - c->decrRef(); - cI->decrRef(); - da->decrRef(); -} - -void MEDCouplingBasicsTest4::testDABack1() -{ - DataArrayDouble *da=DataArrayDouble::New(); - da->alloc(6,1); - const double array1[6]={2.3,1.2,1.3,2.3,2.301,0.8}; - std::copy(array1,array1+6,da->getPointer()); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.8,da->back(),1e-14); - da->rearrange(2); - CPPUNIT_ASSERT_THROW(da->back(),INTERP_KERNEL::Exception); - da->alloc(0,1); - CPPUNIT_ASSERT_THROW(da->back(),INTERP_KERNEL::Exception); - da->decrRef(); - // - DataArrayInt *da2=DataArrayInt::New(); - da2->alloc(4,1); - const int array2[4]={4,7,8,2}; - std::copy(array2,array2+4,da2->getPointer()); - CPPUNIT_ASSERT_EQUAL(2,da2->back()); - da2->rearrange(2); - CPPUNIT_ASSERT_THROW(da2->back(),INTERP_KERNEL::Exception); - da2->alloc(0,1); - CPPUNIT_ASSERT_THROW(da2->back(),INTERP_KERNEL::Exception); - da2->decrRef(); -} - -void MEDCouplingBasicsTest4::testDADGetDifferentValues1() -{ - DataArrayDouble *da=DataArrayDouble::New(); - da->alloc(6,1); - const double array1[6]={2.3,1.2,1.3,2.3,2.301,0.8}; - std::copy(array1,array1+6,da->getPointer()); - // - const double expected1[4]={2.301,1.2,1.3,0.8}; - DataArrayDouble *dv=da->getDifferentValues(1e-2); - CPPUNIT_ASSERT_EQUAL((std::size_t)4,dv->getNbOfElems()); - for(int i=0;i<4;i++) - CPPUNIT_ASSERT_DOUBLES_EQUAL(expected1[i],dv->getIJ(i,0),1e-14); - dv->decrRef(); - // - dv=da->getDifferentValues(2e-1); - const double expected2[3]={2.301,1.3,0.8}; - CPPUNIT_ASSERT_EQUAL((std::size_t)3,dv->getNbOfElems()); - for(int i=0;i<3;i++) - CPPUNIT_ASSERT_DOUBLES_EQUAL(expected2[i],dv->getIJ(i,0),1e-14); - dv->decrRef(); - da->decrRef(); -} - -void MEDCouplingBasicsTest4::testDAIBuildOld2NewArrayFromSurjectiveFormat2() -{ - const int arr[5]={0,3, 5,7,9}; - const int arrI[3]={0,2,5}; - DataArrayInt *a=DataArrayInt::New(); - a->alloc(5,1); - std::copy(arr,arr+5,a->getPointer()); - DataArrayInt *b=DataArrayInt::New(); - b->alloc(3,1); - std::copy(arrI,arrI+3,b->getPointer()); - int newNbTuple=-1; - DataArrayInt *ret=DataArrayInt::BuildOld2NewArrayFromSurjectiveFormat2(10,a->begin(),b->begin(),b->end(),newNbTuple); - const int expected[10]={0,1,2,0,3,4,5,4,6,4}; - CPPUNIT_ASSERT_EQUAL((std::size_t)10,ret->getNbOfElems()); - CPPUNIT_ASSERT_EQUAL(7,newNbTuple); - CPPUNIT_ASSERT_EQUAL(1,ret->getNumberOfComponents()); - CPPUNIT_ASSERT(std::equal(expected,expected+10,ret->getConstPointer())); - CPPUNIT_ASSERT_THROW(DataArrayInt::BuildOld2NewArrayFromSurjectiveFormat2(9,a->begin(),b->begin(),b->end(),newNbTuple),INTERP_KERNEL::Exception); - ret->decrRef(); - b->decrRef(); - a->decrRef(); -} - -void MEDCouplingBasicsTest4::testDADIReverse1() -{ - const int arr[6]={0,3,5,7,9,2}; - DataArrayInt *a=DataArrayInt::New(); - a->alloc(6,1); - std::copy(arr,arr+6,a->getPointer()); - CPPUNIT_ASSERT_EQUAL(2,a->back()); - a->reverse(); - for(int i=0;i<6;i++) - CPPUNIT_ASSERT_EQUAL(arr[5-i],a->getIJ(i,0)); - a->alloc(5,1); - std::copy(arr,arr+5,a->getPointer()); - a->reverse(); - for(int i=0;i<5;i++) - CPPUNIT_ASSERT_EQUAL(arr[4-i],a->getIJ(i,0)); - a->decrRef(); - // - const double arr2[6]={0.,3.,5.,7.,9.,2.}; - DataArrayDouble *b=DataArrayDouble::New(); - b->alloc(6,1); - std::copy(arr2,arr2+6,b->getPointer()); - b->reverse(); - for(int i=0;i<6;i++) - CPPUNIT_ASSERT_DOUBLES_EQUAL(arr2[5-i],b->getIJ(i,0),1e-14); - b->alloc(5,1); - std::copy(arr,arr+5,b->getPointer()); - CPPUNIT_ASSERT_DOUBLES_EQUAL(9.,b->back(),1e-14); - b->reverse(); - for(int i=0;i<5;i++) - CPPUNIT_ASSERT_DOUBLES_EQUAL(arr2[4-i],b->getIJ(i,0),1e-14); - b->decrRef(); -} - -void MEDCouplingBasicsTest4::testGetNodeIdsInUse1() -{ - MEDCouplingUMesh *m0=build2DTargetMesh_1(); - const int CellIds[2]={1,2}; - MEDCouplingUMesh *m1=static_cast(m0->buildPartOfMySelf(CellIds,CellIds+2,true)); - int newNbOfNodes=-1; - DataArrayInt *arr=m1->getNodeIdsInUse(newNbOfNodes); - const int expected[9]={-1,0,1,-1,2,3,-1,-1,-1}; - CPPUNIT_ASSERT_EQUAL(4,newNbOfNodes); - CPPUNIT_ASSERT_EQUAL((std::size_t)9,arr->getNbOfElems()); - CPPUNIT_ASSERT(std::equal(expected,expected+9,arr->getConstPointer())); - DataArrayInt *arr2=arr->invertArrayO2N2N2O(newNbOfNodes); - CPPUNIT_ASSERT_EQUAL((std::size_t)4,arr2->getNbOfElems()); - const int expected2[4]={1,2,4,5}; - CPPUNIT_ASSERT(std::equal(expected2,expected2+4,arr2->getConstPointer())); - arr2->decrRef(); - arr->decrRef(); - m1->decrRef(); - m0->decrRef(); -} - -void MEDCouplingBasicsTest4::testBuildDescendingConnec2() -{ - MEDCouplingUMesh *mesh=build2DTargetMesh_1(); - DataArrayInt *desc=DataArrayInt::New(); - DataArrayInt *descIndx=DataArrayInt::New(); - DataArrayInt *revDesc=DataArrayInt::New(); - DataArrayInt *revDescIndx=DataArrayInt::New(); - // - MEDCouplingUMesh *mesh2=mesh->buildDescendingConnectivity2(desc,descIndx,revDesc,revDescIndx); - mesh2->checkCoherency(); - CPPUNIT_ASSERT_EQUAL(1,mesh2->getMeshDimension()); - CPPUNIT_ASSERT_EQUAL(13,mesh2->getNumberOfCells()); - CPPUNIT_ASSERT_EQUAL((std::size_t)14,revDescIndx->getNbOfElems()); CPPUNIT_ASSERT_EQUAL(14,revDescIndx->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL((std::size_t)6,descIndx->getNbOfElems()); CPPUNIT_ASSERT_EQUAL(6,descIndx->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL((std::size_t)18,desc->getNbOfElems()); CPPUNIT_ASSERT_EQUAL(18,desc->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL((std::size_t)18,revDesc->getNbOfElems()); CPPUNIT_ASSERT_EQUAL(18,revDesc->getNumberOfTuples()); - const int expected1[18]={1,2,3,4,-3,5,6, 7,8,-5,9,10,-2,11, 12,13,-7,-10}; - CPPUNIT_ASSERT(std::equal(expected1,expected1+18,desc->getConstPointer())); - const int expected2[6]={0,4,7,10,14,18}; - CPPUNIT_ASSERT(std::equal(expected2,expected2+6,descIndx->getConstPointer())); - const int expected3[14]={0,1,3,5,6,8,9,11,12,13,15,16,17,18}; - CPPUNIT_ASSERT(std::equal(expected3,expected3+14,revDescIndx->getConstPointer())); - const int expected4[18]={0, 0,3, 0,1, 0, 1,2, 1, 2,4, 2, 3, 3,4, 3, 4, 4}; - CPPUNIT_ASSERT(std::equal(expected4,expected4+18,revDesc->getConstPointer())); - DataArrayInt *conn=mesh2->getNodalConnectivity(); - DataArrayInt *connIndex=mesh2->getNodalConnectivityIndex(); - const int expected5[14]={0,3,6,9,12,15,18,21,24,27,30,33,36,39}; - CPPUNIT_ASSERT(std::equal(expected5,expected5+14,connIndex->getConstPointer())); - const int expected6[39]={1, 0, 3, 1, 3, 4, 1, 4, 1, 1, 1, 0, 1, 4, 2, 1, 2, 1, 1, 4, 5, 1, 5, 2, 1, 6, 7, 1, 7, 4, 1, 3, 6, 1, 7, 8, 1, 8, 5}; - CPPUNIT_ASSERT(std::equal(expected6,expected6+39,conn->getConstPointer())); - // - desc->decrRef(); - descIndx->decrRef(); - revDesc->decrRef(); - revDescIndx->decrRef(); - mesh2->decrRef(); - mesh->decrRef(); -} - -void MEDCouplingBasicsTest4::testIntersect2DMeshesTmp1() -{ - MEDCouplingCMesh *m1c=MEDCouplingCMesh::New(); - DataArrayDouble *coordX=DataArrayDouble::New(); - const double arrX[4]={-1., 1., 2., 4.}; - coordX->alloc(4,1); - std::copy(arrX,arrX+4,coordX->getPointer()); - m1c->setCoordsAt(0,coordX); - DataArrayDouble *coordY=DataArrayDouble::New(); - const double arrY[4]={-2., 2., 4., 8.}; - coordY->alloc(4,1); - std::copy(arrY,arrY+4,coordY->getPointer()); - m1c->setCoordsAt(1,coordY); - MEDCouplingUMesh *m1=m1c->buildUnstructured(); - const int subPart1[3]={3,4,5}; - MEDCouplingUMesh *m1bis=static_cast(m1->buildPartOfMySelf(subPart1,subPart1+3,false)); - MEDCouplingUMesh *m2tmp=static_cast(m1->deepCpy()); - const int subPart2[3]={0,1,2}; - MEDCouplingUMesh *m2=static_cast(m2tmp->buildPartOfMySelf(subPart2,subPart2+3,false)); - const double vec[2]={0.5,0.5}; - m2->translate(vec); - // End of construction of input meshes m1bis and m2 -> start of specific part of the test - DataArrayInt *d1=0,*d2=0; - MEDCouplingUMesh *m3=MEDCouplingUMesh::Intersect2DMeshes(m1bis,m2,1e-10,d1,d2); - const int expected1[8]={0,0,1,1,1,2,2,2}; - const int expected2[8]={0,-1,0,1,-1,1,2,-1}; - CPPUNIT_ASSERT_EQUAL(8,d1->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(8,d2->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(8,m3->getNumberOfCells()); - CPPUNIT_ASSERT_EQUAL(22,m3->getNumberOfNodes()); - CPPUNIT_ASSERT_EQUAL(2,m3->getSpaceDimension()); - CPPUNIT_ASSERT(std::equal(expected1,expected1+8,d1->getConstPointer())); - CPPUNIT_ASSERT(std::equal(expected2,expected2+8,d2->getConstPointer())); - const int expected3[44]={5,17,1,16,12,5,16,0,4,5,17,12,5,18,1,17,13,5,19,2,18,13,5,17,5,6,19,13,5,20,2,19,14,5,21,3,20,14,5,19,6,7,21,14}; - const int expected4[9]={0,5,12,17,22,28,33,38,44}; - const double expected5[44]={-1.0,2.0,1.0,2.0,2.0,2.0,4.0,2.0,-1.0,4.0,1.0,4.0,2.0,4.0,4.0,4.0,-0.5,-1.5,1.5,-1.5,2.5,-1.5,4.5,-1.5,-0.5,2.5,1.5,2.5,2.5,2.5,4.5,2.5,-0.5,2.0,1.0,2.5,1.5,2.0,2.0,2.5,2.5,2.0,4.0,2.5}; - CPPUNIT_ASSERT_EQUAL(44,m3->getNodalConnectivity()->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(9,m3->getNodalConnectivityIndex()->getNumberOfTuples()); - CPPUNIT_ASSERT(std::equal(expected3,expected3+44,m3->getNodalConnectivity()->getConstPointer())); - CPPUNIT_ASSERT(std::equal(expected4,expected4+9,m3->getNodalConnectivityIndex()->getConstPointer())); - for(int i=0;i<44;i++) - CPPUNIT_ASSERT_DOUBLES_EQUAL(expected5[i],m3->getCoords()->getIJ(0,i),1e-12); - d1->decrRef(); - d2->decrRef(); - m3->decrRef(); - // - m2->decrRef(); - m2tmp->decrRef(); - m1bis->decrRef(); - m1->decrRef(); - coordX->decrRef(); - coordY->decrRef(); - m1c->decrRef(); -} - -void MEDCouplingBasicsTest4::testFindNodesOnLine1() -{ - MEDCouplingUMesh *mesh=build2DTargetMesh_1(); - const double pt[2]={-0.3,-0.3}; - const double pt2[3]={0.,0.,0.}; - const double pt3[3]={-0.3,0.,0.}; - const double vec[2]={0.,1.}; - const double vec2[3]={1.,0.,0.}; - const double vec3[3]={0.,1.,1.}; - const int expected1[3]={0,3,6}; - std::vector res; - mesh->findNodesOnLine(pt,vec,1e-12,res); - CPPUNIT_ASSERT_EQUAL(3,(int)res.size()); - CPPUNIT_ASSERT(std::equal(expected1,expected1+3,res.begin())); - res.clear(); - // - mesh->changeSpaceDimension(3); - mesh->rotate(pt2,vec2,M_PI/4.); - mesh->findNodesOnLine(pt3,vec3,1e-12,res); - CPPUNIT_ASSERT_EQUAL(3,(int)res.size()); - CPPUNIT_ASSERT(std::equal(expected1,expected1+3,res.begin())); - // - mesh->decrRef(); -} - -void MEDCouplingBasicsTest4::testIntersect2DMeshesTmp2() -{ - MEDCouplingCMesh *m1c=MEDCouplingCMesh::New(); - DataArrayDouble *coordsX1=DataArrayDouble::New(); - const double arrX1[4]={ 0., 1., 1.5, 2. }; - coordsX1->alloc(4,1); - std::copy(arrX1,arrX1+4,coordsX1->getPointer()); - m1c->setCoordsAt(0,coordsX1); - DataArrayDouble *coordsY1=DataArrayDouble::New(); - const double arrY1[3]={ 0., 1.5, 3.}; - coordsY1->alloc(3,1); - std::copy(arrY1,arrY1+3,coordsY1->getPointer()); - m1c->setCoordsAt(1,coordsY1); - MEDCouplingUMesh *m1=m1c->buildUnstructured(); - // - MEDCouplingCMesh *m2c=MEDCouplingCMesh::New(); - DataArrayDouble *coordsX2=DataArrayDouble::New(); - const double arrX2[3]={ 0., 1., 2. }; - coordsX2->alloc(3,1); - std::copy(arrX2,arrX2+3,coordsX2->getPointer()); - m2c->setCoordsAt(0,coordsX2); - DataArrayDouble *coordsY2=DataArrayDouble::New(); - coordsY2->alloc(3,1); - const double arrY2[3]={ 0., 1., 3.}; - std::copy(arrY2,arrY2+3,coordsY2->getPointer()); - m2c->setCoordsAt(1,coordsY2); - MEDCouplingUMesh *m2=m2c->buildUnstructured(); - // - DataArrayInt *d1=0,*d2=0; - MEDCouplingUMesh *m3=MEDCouplingUMesh::Intersect2DMeshes(m1,m2,1e-10,d1,d2); - const int expected1[9]={0,0,1,1,2,2,3,4,5}; - const int expected2[9]={0,2,1,3,1,3,2,3,3}; - CPPUNIT_ASSERT_EQUAL(9,d1->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(9,d2->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(9,m3->getNumberOfCells()); - CPPUNIT_ASSERT_EQUAL(22,m3->getNumberOfNodes()); - CPPUNIT_ASSERT_EQUAL(2,m3->getSpaceDimension()); - CPPUNIT_ASSERT(std::equal(expected1,expected1+9,d1->getConstPointer())); - CPPUNIT_ASSERT(std::equal(expected2,expected2+9,d2->getConstPointer())); - const int expected3[45]={5,16,13,12,15,5,15,4,5,16,5,21,2,13,16,5,16,5,6,21,5,17,14,2,21,5,21,6,7,17,5,4,18,19,5,5,5,19,10,6,5,6,10,20,7}; - const int expected4[10]={0,5,10,15,20,25,30,35,40,45}; - const double expected5[44]={0.0,0.0,1.0,0.0,1.5,0.0,2.0,0.0,0.0,1.5,1.0,1.5,1.5,1.5,2.0,1.5,0.0,3.0,1.0,3.0,1.5,3.0,2.0,3.0,0.0,0.0,1.0,0.0,2.0,0.0,0.0,1.0,1.0,1.0,2.0,1.0,0.0,3.0,1.0,3.0,2.0,3.0,1.5,1.0}; - CPPUNIT_ASSERT_EQUAL(45,m3->getNodalConnectivity()->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(10,m3->getNodalConnectivityIndex()->getNumberOfTuples()); - CPPUNIT_ASSERT(std::equal(expected3,expected3+45,m3->getNodalConnectivity()->getConstPointer())); - CPPUNIT_ASSERT(std::equal(expected4,expected4+10,m3->getNodalConnectivityIndex()->getConstPointer())); - for(int i=0;i<44;i++) - CPPUNIT_ASSERT_DOUBLES_EQUAL(expected5[i],m3->getCoords()->getIJ(0,i),1e-12); - d1->decrRef(); - d2->decrRef(); - m3->decrRef(); - // - m1c->decrRef(); - coordsX1->decrRef(); - coordsY1->decrRef(); - m1->decrRef(); - m2c->decrRef(); - coordsX2->decrRef(); - coordsY2->decrRef(); - m2->decrRef(); -} - -void MEDCouplingBasicsTest4::testBuildPartOfMySelfSafe1() -{ - MEDCouplingUMesh *mesh=build2DTargetMesh_1(); - const int input1[4]={0,-1,4,2}; - const int input2[4]={0,4,5,4}; - CPPUNIT_ASSERT_THROW(mesh->buildPartOfMySelf(input1,input1+4,true),INTERP_KERNEL::Exception); - CPPUNIT_ASSERT_THROW(mesh->buildPartOfMySelf(input2,input2+4,true),INTERP_KERNEL::Exception); - mesh->decrRef(); -} - -void MEDCouplingBasicsTest4::testIntersect2DMeshesTmp3() -{ - double m1Coords[50]={0.,0.,1.,0.,1.5,0.,0.,1.,0.,1.5,-1.,0.,-1.5,0.,0.,-1,0.,-1.5,0.5,0.,1.25,0.,0.70710678118654757,0.70710678118654757,1.0606601717798214,1.0606601717798214,0.,0.5,0.,1.25,-0.70710678118654757,0.70710678118654757,-1.0606601717798214,1.0606601717798214,-0.5,0.,-1.25,0.,-0.70710678118654757,-0.70710678118654757,-1.0606601717798214,-1.0606601717798214,0.,-0.5,0.,-1.25,0.70710678118654757,-0.70710678118654757,1.0606601717798214,-1.0606601717798214}; - int m1Conn[56]={0,3,1,13,11,9, 3,4,2,1,14,12,10,11, 5,3,0,15,13,17, 6,4,3,5,16,14,15,18, 5,0,7,17,21,19, 6,5,7,8,18,19,22,20, 0,1,7,9,23,21, 1,2,8,7,10,24,22,23}; - MEDCouplingUMesh *m1=MEDCouplingUMesh::New(); - m1->setMeshDimension(2); - m1->allocateCells(8); - m1->insertNextCell(INTERP_KERNEL::NORM_TRI6,6,m1Conn); - m1->insertNextCell(INTERP_KERNEL::NORM_QUAD8,8,m1Conn+6); - m1->insertNextCell(INTERP_KERNEL::NORM_TRI6,6,m1Conn+14); - m1->insertNextCell(INTERP_KERNEL::NORM_QUAD8,8,m1Conn+20); - m1->insertNextCell(INTERP_KERNEL::NORM_TRI6,6,m1Conn+28); - m1->insertNextCell(INTERP_KERNEL::NORM_QUAD8,8,m1Conn+34); - m1->insertNextCell(INTERP_KERNEL::NORM_TRI6,6,m1Conn+42); - m1->insertNextCell(INTERP_KERNEL::NORM_QUAD8,8,m1Conn+48); - m1->finishInsertingCells(); - DataArrayDouble *myCoords1=DataArrayDouble::New(); - myCoords1->alloc(25,2); - std::copy(m1Coords,m1Coords+50,myCoords1->getPointer()); - m1->setCoords(myCoords1); - myCoords1->decrRef(); - // - double m2Coords[30]={0.,0.,1.1,0.,1.1,1.,0.,1.,1.7,0.,1.7,1.,-1.1,1.,-1.1,0.,-1.7,0.,-1.7,1.,-1.7,-1,-1.1,-1.,0.,-1.,1.1,-1,1.7,-1.}; - int m2Conn[32]={0,3,2,1, 1,2,5,4, 7,6,3,0, 8,9,6,7, 7,0,12,11, 8,7,11,10, 0,1,13,12, 1,4,14,13}; - MEDCouplingUMesh *m2=MEDCouplingUMesh::New(); - m2->setMeshDimension(2); - m2->allocateCells(8); - for(int i=0;i<8;i++) - m2->insertNextCell(INTERP_KERNEL::NORM_QUAD4,4,m2Conn+4*i); - m2->finishInsertingCells(); - DataArrayDouble *myCoords2=DataArrayDouble::New(); - myCoords2->alloc(15,2); - std::copy(m2Coords,m2Coords+30,myCoords2->getPointer()); - m2->setCoords(myCoords2); - myCoords2->decrRef(); - // - DataArrayInt *d1=0,*d2=0; - MEDCouplingUMesh *m3=MEDCouplingUMesh::Intersect2DMeshes(m1,m2,1e-10,d1,d2); - m3->unPolyze(); - const int expected1[16]={0,1,1,1,2,3,3,3,4,5,5,5,6,7,7,7}; - const int expected2[16]={0,0,1,-1,2,2,3,-1,4,4,5,-1,6,6,7,-1}; - CPPUNIT_ASSERT_EQUAL(16,d1->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(16,d2->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(16,m3->getNumberOfCells()); - CPPUNIT_ASSERT_EQUAL(104,m3->getNumberOfNodes()); - CPPUNIT_ASSERT_EQUAL(2,m3->getSpaceDimension()); - CPPUNIT_ASSERT(std::equal(expected1,expected1+16,d1->getConstPointer())); - CPPUNIT_ASSERT(std::equal(expected2,expected2+16,d2->getConstPointer())); - const int expected3[136]={6,28,1,25,44,45,46,8,26,1,28,27,47,48,49,50,8,40,2,26,27,51,52,53,54,8,28,4,40,27,55,56,57,58,6,28,25,5,59,60,61,8,28,5,32,31,62,63,64,65,8,32,6,41,31,66,67,68,69,8,41,4,28,31,70,71,72,73,6,25,37,5,74,75,76,8,32,5,37,36,77,78,79,80,8,42,6,32,36,81,82,83,84,8,37,8,42,36,85,86,87,88,6,1,37,25,89,90,91,8,37,1,26,38,92,93,94,95,8,26,2,43,38,96,97,98,99,8,43,8,37,38,100,101,102,103}; - const int expected4[17]={0,7,16,25,34,41,50,59,68,75,84,93,102,109,118,127,136}; - const double expected5[208]={0.,0.,1.,0.,1.5,0.,0.,1.,0.,1.5,-1.,0.,-1.5,0.,0.,-1.,0.,-1.5,0.5,0.,1.25,0.,0.7071067811865476,0.7071067811865476,1.0606601717798214,1.0606601717798214,0.,0.5,0.,1.25,-0.7071067811865476,0.7071067811865476,-1.0606601717798214,1.0606601717798214,-0.5,0.,-1.25,0.,-0.7071067811865476,-0.7071067811865476,-1.0606601717798214,-1.0606601717798214,0.,-0.5,0.,-1.25,0.7071067811865476,-0.7071067811865476,1.0606601717798214,-1.0606601717798214,0.,0.,1.1,0.,1.1,1.,0.,1.,1.7,0.,1.7,1.,-1.1,1.,-1.1,0.,-1.7,0.,-1.7,1.,-1.7,-1.,-1.1,-1.,0.,-1.,1.1,-1.,1.7,-1.,1.118033988749895,1.,-1.118033988749895,1.,-1.118033988749895,-1.,1.118033988749895,-1.,0.7071067811865477,0.7071067811865476,0.5,0.,0.,0.5,1.05,0.,0.7071067811865475,0.7071067811865477,0.55,1.,1.1,0.5,1.4012585384440737,0.535233134659635,1.3,0.,1.1,0.5,1.1090169943749475,1.,0.,1.25,0.6123724356957946,1.369306393762915,1.1090169943749475,1.,0.55,1.,0.,0.5,-0.5,0.,-0.7071067811865477,0.7071067811865476,-0.7071067811865475,0.7071067811865477,-1.05,0.,-1.1,0.5,-0.55,1.,-1.3,0.,-1.4012585384440737,0.5352331346596344,-1.1090169943749475,1.,-1.1,0.5,-0.6123724356957941,1.3693063937629155,0.,1.25,-0.55,1.,-1.1090169943749475,1.,0.,-0.5,-0.7071067811865475,-0.7071067811865477,-0.5,0.,-1.05,0.,-0.7071067811865478,-0.7071067811865475,-0.55,-1.,-1.1,-0.5,-1.4012585384440734,-0.5352331346596354,-1.3,0.,-1.1,-0.5,-1.1090169943749475,-1.,0.,-1.25,-0.6123724356957945,-1.369306393762915,-1.1090169943749475,-1.,-0.55,-1.,0.7071067811865475,-0.7071067811865477,0.,-0.5,0.5,0.,0.7071067811865477,-0.7071067811865475,1.05,0.,1.1,-0.5,0.55,-1.,1.3,0.,1.4012585384440737,-0.535233134659635,1.1090169943749475,-1.,1.1,-0.5,0.6123724356957946,-1.369306393762915,0.,-1.25,0.55,-1.,1.1090169943749475,-1.0}; - CPPUNIT_ASSERT_EQUAL(136,m3->getNodalConnectivity()->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(17,m3->getNodalConnectivityIndex()->getNumberOfTuples()); - CPPUNIT_ASSERT(std::equal(expected3,expected3+136,m3->getNodalConnectivity()->getConstPointer())); - CPPUNIT_ASSERT(std::equal(expected4,expected4+17,m3->getNodalConnectivityIndex()->getConstPointer())); - for(int i=0;i<208;i++) - CPPUNIT_ASSERT_DOUBLES_EQUAL(expected5[i],m3->getCoords()->getIJ(0,i),1e-12); - d1->decrRef(); - d2->decrRef(); - m3->decrRef(); - // - m1->decrRef(); - m2->decrRef(); -} diff --git a/src/MEDCoupling/Test/MEDCouplingBasicsTest4.hxx b/src/MEDCoupling/Test/MEDCouplingBasicsTest4.hxx deleted file mode 100644 index 3e8738255..000000000 --- a/src/MEDCoupling/Test/MEDCouplingBasicsTest4.hxx +++ /dev/null @@ -1,162 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 -// 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 __MEDCOUPLINGBASICSTEST4_HXX__ -#define __MEDCOUPLINGBASICSTEST4_HXX__ - -#include "MEDCouplingBasicsTest.hxx" - -#include -#include - -namespace ParaMEDMEM -{ - class DataArrayDouble; - class MEDCouplingUMesh; - class MEDCouplingFieldDouble; - class MEDCouplingMultiFields; - - class MEDCouplingBasicsTest4 : public MEDCouplingBasicsTest - { - CPPUNIT_TEST_SUITE(MEDCouplingBasicsTest4); - CPPUNIT_TEST( testDescriptionInMeshTimeUnit1 ); - CPPUNIT_TEST( testMultiFields1 ); - CPPUNIT_TEST( testFieldOverTime1 ); - CPPUNIT_TEST( testDAICheckAndPreparePermutation1 ); - CPPUNIT_TEST( testDAIChangeSurjectiveFormat1 ); - CPPUNIT_TEST( testUMeshGetCellIdsLyingOnNodes1 ); - CPPUNIT_TEST( testUMeshFindCellIdsOnBoundary1 ); - CPPUNIT_TEST( testMeshSetTime1 ); - CPPUNIT_TEST( testApplyFuncTwo1 ); - CPPUNIT_TEST( testApplyFuncThree1 ); - CPPUNIT_TEST( testFillFromAnalyticTwo1 ); - CPPUNIT_TEST( testFillFromAnalyticThree1 ); - CPPUNIT_TEST( testDAUnitVar1 ); - CPPUNIT_TEST( testGaussCoordinates1 ); - CPPUNIT_TEST( testP2Localization1 ); - CPPUNIT_TEST( testP2Localization2 ); - CPPUNIT_TEST( testGetValueOn2 ); - CPPUNIT_TEST( testDAIGetIdsNotEqual1 ); - CPPUNIT_TEST( testDAIComputeOffsets1 ); - CPPUNIT_TEST( testUMeshHexagonPrism1 ); - CPPUNIT_TEST( testDADCheckIsMonotonic ); - CPPUNIT_TEST( testCheckCoherencyDeeper1 ); - CPPUNIT_TEST( testUnPolyze2 ); - CPPUNIT_TEST( testDACpyFrom1 ); - CPPUNIT_TEST( testDAITransformWithIndArr1 ); - CPPUNIT_TEST( testDAIBuildPermArrPerLevel1 ); - CPPUNIT_TEST( testDAIOperations1 ); - CPPUNIT_TEST( testEmulateMEDMEMBDC1 ); - CPPUNIT_TEST( testGetLevArrPerCellTypes1 ); - CPPUNIT_TEST( testSortCellsInMEDFileFrmt1 ); - CPPUNIT_TEST( testBuildPartAndReduceNodes1 ); - CPPUNIT_TEST( testDAITransformWithIndArrR1 ); - CPPUNIT_TEST( testDAISplitByValueRange1 ); - CPPUNIT_TEST( testUMeshSplitProfilePerType1 ); - CPPUNIT_TEST( testDAIBuildExplicitArrByRanges1 ); - CPPUNIT_TEST( testDAIComputeOffsets2 ); - CPPUNIT_TEST( testMergeField3 ); - CPPUNIT_TEST( testGetDistributionOfTypes1 ); - CPPUNIT_TEST( testNorm2_1 ); - CPPUNIT_TEST( testNormMax1 ); - CPPUNIT_TEST( testFindAndCorrectBadOriented3DExtrudedCells1 ); - CPPUNIT_TEST( testConvertExtrudedPolyhedra1 ); - CPPUNIT_TEST( testNonRegressionCopyTinyStrings ); - CPPUNIT_TEST( testDaDSetPartOfValuesAdv1 ); - CPPUNIT_TEST( testUMeshBuildSetInstanceFromThis1 ); - CPPUNIT_TEST( testUMeshMergeMeshesCVW1 ); - CPPUNIT_TEST( testDADFindCommonTuples1 ); - CPPUNIT_TEST( testDABack1 ); - CPPUNIT_TEST( testDADGetDifferentValues1 ); - CPPUNIT_TEST( testDAIBuildOld2NewArrayFromSurjectiveFormat2 ); - CPPUNIT_TEST( testDADIReverse1 ); - CPPUNIT_TEST( testGetNodeIdsInUse1 ); - CPPUNIT_TEST( testBuildDescendingConnec2 ); - CPPUNIT_TEST( testIntersect2DMeshesTmp1 ); - CPPUNIT_TEST( testFindNodesOnLine1 ); - CPPUNIT_TEST( testIntersect2DMeshesTmp2 ); - CPPUNIT_TEST( testBuildPartOfMySelfSafe1 ); - CPPUNIT_TEST( testIntersect2DMeshesTmp3 ); - CPPUNIT_TEST_SUITE_END(); - public: - void testDescriptionInMeshTimeUnit1(); - void testMultiFields1(); - void testFieldOverTime1(); - void testDAICheckAndPreparePermutation1(); - void testDAIChangeSurjectiveFormat1(); - void testUMeshGetCellIdsLyingOnNodes1(); - void testUMeshFindCellIdsOnBoundary1(); - void testMeshSetTime1(); - void testApplyFuncTwo1(); - void testApplyFuncThree1(); - void testFillFromAnalyticTwo1(); - void testFillFromAnalyticThree1(); - void testDAUnitVar1(); - void testGaussCoordinates1(); - void testQ1Localization1(); - void testP2Localization1(); - void testP2Localization2(); - void testGetValueOn2(); - void testDAIGetIdsNotEqual1(); - void testDAIComputeOffsets1(); - void testUMeshHexagonPrism1(); - void testDADCheckIsMonotonic(); - void testCheckCoherencyDeeper1(); - void testUnPolyze2(); - void testDACpyFrom1(); - void testDAITransformWithIndArr1(); - void testDAIBuildPermArrPerLevel1(); - void testDAIOperations1(); - void testEmulateMEDMEMBDC1(); - void testGetLevArrPerCellTypes1(); - void testSortCellsInMEDFileFrmt1(); - void testBuildPartAndReduceNodes1(); - void testDAITransformWithIndArrR1(); - void testDAISplitByValueRange1(); - void testUMeshSplitProfilePerType1(); - void testDAIBuildExplicitArrByRanges1(); - void testDAIComputeOffsets2(); - void testMergeField3(); - void testGetDistributionOfTypes1(); - void testNorm2_1(); - void testNormMax1(); - void testFindAndCorrectBadOriented3DExtrudedCells1(); - void testConvertExtrudedPolyhedra1(); - void testNonRegressionCopyTinyStrings(); - void testDaDSetPartOfValuesAdv1(); - void testUMeshBuildSetInstanceFromThis1(); - void testUMeshMergeMeshesCVW1(); - void testChangeUnderlyingMeshWithCMesh1(); - void testDADFindCommonTuples1(); - void testDABack1(); - void testDADGetDifferentValues1(); - void testDAIBuildOld2NewArrayFromSurjectiveFormat2(); - void testDADIReverse1(); - void testGetNodeIdsInUse1(); - void testBuildDescendingConnec2(); - void testIntersect2DMeshesTmp1(); - void testFindNodesOnLine1(); - void testIntersect2DMeshesTmp2(); - void testBuildPartOfMySelfSafe1(); - void testIntersect2DMeshesTmp3(); - }; -} - -#endif diff --git a/src/MEDCoupling/Test/MEDCouplingBasicsTest5.cxx b/src/MEDCoupling/Test/MEDCouplingBasicsTest5.cxx deleted file mode 100644 index 0dc0e8c01..000000000 --- a/src/MEDCoupling/Test/MEDCouplingBasicsTest5.cxx +++ /dev/null @@ -1,2059 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 -// 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 "MEDCouplingBasicsTest5.hxx" -#include "MEDCouplingUMesh.hxx" -#include "MEDCouplingCMesh.hxx" -#include "MEDCouplingExtrudedMesh.hxx" -#include "MEDCouplingFieldDouble.hxx" -#include "MEDCouplingMemArray.hxx" -#include "MEDCouplingGaussLocalization.hxx" -#include "MEDCouplingMultiFields.hxx" -#include "MEDCouplingFieldOverTime.hxx" - -#include -#include -#include - -using namespace ParaMEDMEM; - -void MEDCouplingBasicsTest5::testUMeshTessellate2D1() -{ - double m1Coords[50]={0.,0.,1.,0.,1.5,0.,0.,1.,0.,1.5,-1.,0.,-1.5,0.,0.,-1,0.,-1.5,0.5,0.,1.25,0.,0.70710678118654757,0.70710678118654757,1.0606601717798214,1.0606601717798214,0.,0.5,0.,1.25,-0.70710678118654757,0.70710678118654757,-1.0606601717798214,1.0606601717798214,-0.5,0.,-1.25,0.,-0.70710678118654757,-0.70710678118654757,-1.0606601717798214,-1.0606601717798214,0.,-0.5,0.,-1.25,0.70710678118654757,-0.70710678118654757,1.0606601717798214,-1.0606601717798214}; - int m1Conn[56]={0,3,1,13,11,9, 3,4,2,1,14,12,10,11, 5,3,0,15,13,17, 6,4,3,5,16,14,15,18, 5,0,7,17,21,19, 6,5,7,8,18,19,22,20, 0,1,7,9,23,21, 1,2,8,7,10,24,22,23}; - MEDCouplingUMesh *m1=MEDCouplingUMesh::New(); - m1->setMeshDimension(2); - m1->allocateCells(8); - m1->insertNextCell(INTERP_KERNEL::NORM_TRI6,6,m1Conn); - m1->insertNextCell(INTERP_KERNEL::NORM_QUAD8,8,m1Conn+6); - m1->insertNextCell(INTERP_KERNEL::NORM_TRI6,6,m1Conn+14); - m1->insertNextCell(INTERP_KERNEL::NORM_QUAD8,8,m1Conn+20); - m1->insertNextCell(INTERP_KERNEL::NORM_TRI6,6,m1Conn+28); - m1->insertNextCell(INTERP_KERNEL::NORM_QUAD8,8,m1Conn+34); - m1->insertNextCell(INTERP_KERNEL::NORM_TRI6,6,m1Conn+42); - m1->insertNextCell(INTERP_KERNEL::NORM_QUAD8,8,m1Conn+48); - m1->finishInsertingCells(); - DataArrayDouble *myCoords1=DataArrayDouble::New(); - myCoords1->alloc(25,2); - std::copy(m1Coords,m1Coords+50,myCoords1->getPointer()); - m1->setCoords(myCoords1); - myCoords1->decrRef(); - // - MEDCouplingUMesh *m11=static_cast(m1->deepCpy()); - m11->tessellate2D(1.); - CPPUNIT_ASSERT(m11->getCoords()->isEqual(*m11->getCoords(),1e-12)); - const int expected1[48]={5,0,3,11,1,5,3,4,12,2,1,11,5,5,15,3,0,5,6,16,4,3,15,5,5,5,0,7,19,5,6,5,19,7,8,20,5,0,1,23,7,5,1,2,24,8,7,23}; - const int expected2[9]={0,5,12,17,24,29,36,41,48}; - CPPUNIT_ASSERT_EQUAL(48,m11->getNodalConnectivity()->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(9,m11->getNodalConnectivityIndex()->getNumberOfTuples()); - CPPUNIT_ASSERT(std::equal(expected1,expected1+48,m11->getNodalConnectivity()->getConstPointer())); - CPPUNIT_ASSERT(std::equal(expected2,expected2+9,m11->getNodalConnectivityIndex()->getConstPointer())); - m11->decrRef(); - // - MEDCouplingUMesh *m12=static_cast(m1->deepCpy()); - m12->tessellate2D(0.5); - CPPUNIT_ASSERT_EQUAL(41,m12->getNumberOfNodes()); - const int expected3[60]={5,0,3,25,26,1,5,3,4,27,28,2,1,26,25,5,5,29,30,3,0,5,6,31,32,4,3,30,29,5,5,5,0,7,33,34,5,6,5,34,33,7,8,35,36,5,0,1,37,38,7,5,1,2,39,40,8,7,38,37}; - const int expected4[9]={0,6,15,21,30,36,45,51,60}; - const double expected5[82]={0.,0.,1.,0.,1.5,0.,0.,1.,0.,1.5,-1.,0.,-1.5,0.,0.,-1.,0.,-1.5,0.5,0.,1.25,0.,0.7071067811865476,0.7071067811865476,1.0606601717798214,1.0606601717798214,0.,0.5,0.,1.25,-0.7071067811865476,0.7071067811865476,-1.0606601717798214,1.0606601717798214,-0.5,0.,-1.25,0.,-0.7071067811865476,-0.7071067811865476,-1.0606601717798214,-1.0606601717798214,0.,-0.5,0.,-1.25,0.7071067811865476,-0.7071067811865476,1.0606601717798214,-1.0606601717798214,0.479425538604203,0.8775825618903728,0.8414709848078964,0.54030230586814,0.7191383079063044,1.3163738428355591,1.2622064772118446,0.8104534588022099,-0.877582561890373,0.4794255386042027,-0.5403023058681399,0.8414709848078964,-1.3163738428355596,0.7191383079063038,-0.8104534588022098,1.2622064772118446,-0.4794255386042031,-0.8775825618903728,-0.8414709848078965,-0.5403023058681399,-0.7191383079063045,-1.3163738428355591,-1.2622064772118449,-0.8104534588022098,0.8775825618903729,-0.47942553860420295,0.54030230586814,-0.8414709848078964,1.3163738428355594,-0.7191383079063043,0.8104534588022099,-1.2622064772118446}; - for(int i=0;i<82;i++) - CPPUNIT_ASSERT_DOUBLES_EQUAL(expected5[i],m12->getCoords()->getIJ(0,i),1e-12); - CPPUNIT_ASSERT_EQUAL(60,m12->getNodalConnectivity()->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(9,m12->getNodalConnectivityIndex()->getNumberOfTuples()); - CPPUNIT_ASSERT(std::equal(expected3,expected3+60,m12->getNodalConnectivity()->getConstPointer())); - CPPUNIT_ASSERT(std::equal(expected4,expected4+9,m12->getNodalConnectivityIndex()->getConstPointer())); - m12->decrRef(); - // - m1->decrRef(); -} - -void MEDCouplingBasicsTest5::testUMeshTessellate2DCurve1() -{ - // A quarter of circle: - double mcoords[6] = {0.4,0.0, 0.0,-0.4, 0.283,-0.283}; - int mconnec[3] = {0,1,2}; - - MEDCouplingUMesh *m1 = MEDCouplingUMesh::New(); - m1->setMeshDimension(1); - m1->allocateCells(1); - m1->insertNextCell(INTERP_KERNEL::NORM_SEG3, 3, mconnec); - - DataArrayDouble *myCoords = DataArrayDouble::New(); - myCoords->alloc(3,2); - std::copy(mcoords,mcoords+6,myCoords->getPointer()); - m1->setCoords(myCoords); - myCoords->decrRef(); - - MEDCouplingUMesh *m2 = static_cast(m1->deepCpy()); - m2->tessellate2DCurve(0.1); - CPPUNIT_ASSERT_NO_THROW(m2->checkCoherency1(0.0)); // eps param not used - m1->decrRef(); - m2->decrRef(); -} - -/*! - * idem MEDCouplingBasicsTest4::testIntersect2DMeshesTmp3 except that m1 and m2 are permuted on call to MEDCouplingUMesh::Intersect2DMeshes - */ -void MEDCouplingBasicsTest5::testIntersect2DMeshesTmp4() -{ - double m1Coords[50]={0.,0.,1.,0.,1.5,0.,0.,1.,0.,1.5,-1.,0.,-1.5,0.,0.,-1,0.,-1.5,0.5,0.,1.25,0.,0.70710678118654757,0.70710678118654757,1.0606601717798214,1.0606601717798214,0.,0.5,0.,1.25,-0.70710678118654757,0.70710678118654757,-1.0606601717798214,1.0606601717798214,-0.5,0.,-1.25,0.,-0.70710678118654757,-0.70710678118654757,-1.0606601717798214,-1.0606601717798214,0.,-0.5,0.,-1.25,0.70710678118654757,-0.70710678118654757,1.0606601717798214,-1.0606601717798214}; - int m1Conn[56]={0,3,1,13,11,9, 3,4,2,1,14,12,10,11, 5,3,0,15,13,17, 6,4,3,5,16,14,15,18, 5,0,7,17,21,19, 6,5,7,8,18,19,22,20, 0,1,7,9,23,21, 1,2,8,7,10,24,22,23}; - MEDCouplingUMesh *m1=MEDCouplingUMesh::New(); - m1->setMeshDimension(2); - m1->allocateCells(8); - m1->insertNextCell(INTERP_KERNEL::NORM_TRI6,6,m1Conn); - m1->insertNextCell(INTERP_KERNEL::NORM_QUAD8,8,m1Conn+6); - m1->insertNextCell(INTERP_KERNEL::NORM_TRI6,6,m1Conn+14); - m1->insertNextCell(INTERP_KERNEL::NORM_QUAD8,8,m1Conn+20); - m1->insertNextCell(INTERP_KERNEL::NORM_TRI6,6,m1Conn+28); - m1->insertNextCell(INTERP_KERNEL::NORM_QUAD8,8,m1Conn+34); - m1->insertNextCell(INTERP_KERNEL::NORM_TRI6,6,m1Conn+42); - m1->insertNextCell(INTERP_KERNEL::NORM_QUAD8,8,m1Conn+48); - m1->finishInsertingCells(); - DataArrayDouble *myCoords1=DataArrayDouble::New(); - myCoords1->alloc(25,2); - std::copy(m1Coords,m1Coords+50,myCoords1->getPointer()); - m1->setCoords(myCoords1); - myCoords1->decrRef(); - // - double m2Coords[30]={0.,0.,1.1,0.,1.1,1.,0.,1.,1.7,0.,1.7,1.,-1.1,1.,-1.1,0.,-1.7,0.,-1.7,1.,-1.7,-1,-1.1,-1.,0.,-1.,1.1,-1,1.7,-1.}; - int m2Conn[32]={0,3,2,1, 1,2,5,4, 7,6,3,0, 8,9,6,7, 7,0,12,11, 8,7,11,10, 0,1,13,12, 1,4,14,13}; - MEDCouplingUMesh *m2=MEDCouplingUMesh::New(); - m2->setMeshDimension(2); - m2->allocateCells(8); - for(int i=0;i<8;i++) - m2->insertNextCell(INTERP_KERNEL::NORM_QUAD4,4,m2Conn+4*i); - m2->finishInsertingCells(); - DataArrayDouble *myCoords2=DataArrayDouble::New(); - myCoords2->alloc(15,2); - std::copy(m2Coords,m2Coords+30,myCoords2->getPointer()); - m2->setCoords(myCoords2); - myCoords2->decrRef(); - // - DataArrayInt *d1=0,*d2=0; - MEDCouplingUMesh *m3=MEDCouplingUMesh::Intersect2DMeshes(m2,m1,1e-10,d1,d2); - m3->unPolyze(); - const int expected1[16]={0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7}; - const int expected2[16]={0,1,1,-1,2,3,3,-1,4,5,5,-1,6,7,7,-1}; - CPPUNIT_ASSERT_EQUAL(16,d1->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(16,d2->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(16,m3->getNumberOfCells()); - CPPUNIT_ASSERT_EQUAL(104,m3->getNumberOfNodes()); - CPPUNIT_ASSERT_EQUAL(2,m3->getSpaceDimension()); - CPPUNIT_ASSERT(std::equal(expected1,expected1+16,d1->getConstPointer())); - CPPUNIT_ASSERT(std::equal(expected2,expected2+16,d2->getConstPointer())); - const int expected3[136]={6,16,15,18,44,45,46,8,18,2,1,16,47,48,49,50,8,17,1,2,40,51,52,53,54,8,40,5,4,17,55,56,57,58,6,18,15,20,59,60,61,8,20,7,6,18,62,63,64,65,8,41,6,7,21,66,67,68,69,8,21,8,9,41,70,71,72,73,6,20,15,22,74,75,76,8,22,11,7,20,77,78,79,80,8,21,7,11,42,81,82,83,84,8,42,10,8,21,85,86,87,88,6,22,15,16,89,90,91,8,16,1,13,22,92,93,94,95,8,43,13,1,17,96,97,98,99,8,17,4,14,43,100,101,102,103}; - const int expected4[17]={0,7,16,25,34,41,50,59,68,75,84,93,102,109,118,127,136}; - const double expected5[208]={0.,0.,1.1, 0.,1.1,1.,0.,1.,1.7,0.,1.7,1.,-1.1,1.,-1.1,0.,-1.7,0.,-1.7,1.,-1.7,-1.,-1.1,-1.,0.,-1.,1.1,-1.,1.7,-1.,0.,0.,1.,0.,1.5,0.,0.,1.,0.,1.5,-1.,0.,-1.5,0.,0.,-1.,0.,-1.5,0.5,0.,1.25,0.,0.7071067811865476,0.7071067811865476,1.0606601717798214,1.0606601717798214,0.,0.5,0.,1.25,-0.7071067811865476,0.7071067811865476,-1.0606601717798214,1.0606601717798214,-0.5,0.,-1.25,0.,-0.7071067811865476,-0.7071067811865476,-1.0606601717798214,-1.0606601717798214,0.,-0.5,0.,-1.25,0.7071067811865476,-0.7071067811865476,1.0606601717798214,-1.0606601717798214,1.1180339887498951,1.,-1.1180339887498951,1.,-1.1180339887498951,-1.,1.1180339887498951,-1.,0.5,0.,0.,0.5,0.7071067811865477,0.7071067811865476,0.55,1.,1.1,0.5,1.05,0.,0.7071067811865477,0.7071067811865475,1.3,0.,1.1,0.5,1.1090169943749475,1.,1.4012585384440737,0.535233134659635,1.4090169943749475,1.,1.7,0.5,1.6,0.,1.4012585384440737,0.535233134659635,0.,0.5,-0.5,0.,-0.7071067811865477,0.7071067811865476,-1.05,0.,-1.1,0.5,-0.55,1.,-0.7071067811865478,0.7071067811865475,-1.1090169943749475,1.,-1.1,0.5,-1.3,0.,-1.4012585384440737,0.5352331346596344,-1.6,0.,-1.7,0.5,-1.4090169943749475,1.,-1.4012585384440737,0.5352331346596344,-0.5,0.,0.,-0.5,-0.7071067811865475,-0.7071067811865477,-0.55,-1.,-1.1,-0.5,-1.05,0.,-0.7071067811865475,-0.7071067811865477,-1.3,0.,-1.1,-0.5,-1.1090169943749475,-1.,-1.4012585384440734,-0.5352331346596354,-1.4090169943749475,-1.,-1.7,-0.5,-1.6,0.,-1.4012585384440732,-0.5352331346596354,0.,-0.5,0.5,0.,0.7071067811865475,-0.7071067811865477,1.05,0.,1.1,-0.5,0.55,-1.,0.7071067811865475,-0.7071067811865477,1.1090169943749475,-1.,1.1,-0.5,1.3,0.,1.4012585384440737,-0.535233134659635,1.6,0.,1.7,-0.5,1.4090169943749475,-1.,1.4012585384440737,-0.535233134659635}; - CPPUNIT_ASSERT_EQUAL(136,m3->getNodalConnectivity()->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(17,m3->getNodalConnectivityIndex()->getNumberOfTuples()); - CPPUNIT_ASSERT(std::equal(expected3,expected3+136,m3->getNodalConnectivity()->getConstPointer())); - CPPUNIT_ASSERT(std::equal(expected4,expected4+17,m3->getNodalConnectivityIndex()->getConstPointer())); - for(int i=0;i<208;i++) - CPPUNIT_ASSERT_DOUBLES_EQUAL(expected5[i],m3->getCoords()->getIJ(0,i),1e-12); - d1->decrRef(); - d2->decrRef(); - m3->decrRef(); - // - m1->decrRef(); - m2->decrRef(); -} - -void MEDCouplingBasicsTest5::testGetCellIdsCrossingPlane1() -{ - MEDCouplingUMesh *mesh2D=0; - MEDCouplingUMesh *mesh3D=build3DExtrudedUMesh_1(mesh2D); - const double vec[3]={-0.07,1.,0.07}; - const double origin[3]={1.524,1.4552,1.74768}; - DataArrayInt *ids1=mesh3D->getCellIdsCrossingPlane(origin,vec,1e-10); - CPPUNIT_ASSERT_EQUAL(9,ids1->getNumberOfTuples()); - const int expected1[9]={1,3,4,7,9,10,13,15,16}; - CPPUNIT_ASSERT(std::equal(expected1,expected1+9,ids1->getConstPointer())); - const double vec2[3]={0.,0.,1.}; - DataArrayInt *ids2=mesh3D->getCellIdsCrossingPlane(origin,vec2,1e-10); - const int expected2[6]={6,7,8,9,10,11}; - CPPUNIT_ASSERT_EQUAL(6,ids2->getNumberOfTuples()); - CPPUNIT_ASSERT(std::equal(expected2,expected2+6,ids2->getConstPointer())); - ids1->decrRef(); - ids2->decrRef(); - mesh3D->decrRef(); - mesh2D->decrRef(); -} - -void MEDCouplingBasicsTest5::testBuildSlice3D1() -{ - MEDCouplingUMesh *mesh2D=0; - MEDCouplingUMesh *mesh3D=build3DExtrudedUMesh_1(mesh2D); - mesh2D->decrRef(); - // First slice in the middle of 3D cells - const double vec1[3]={-0.07,1.,0.07}; - const double origin1[3]={1.524,1.4552,1.74768}; - DataArrayInt *ids=0; - MEDCouplingUMesh *slice1=mesh3D->buildSlice3D(origin1,vec1,1e-10,ids); - const int expected1[9]={1,3,4,7,9,10,13,15,16}; - const int expected2[47]={5,42,41,40,43,44,5,42,46,45,41,5,44,43,40,47,48,5,49,42,44,50,5,49,51,46,42,5,50,44,48,52,5,53,49,50,54,5,53,55,51,49,5,54,50,52,56}; - const int expected3[10]={0,6,11,17,22,27,32,37,42,47}; - const double expected4[171]={1.,1.,0.,1.,1.25,0.,1.,1.5,0.,2.,1.,0.,1.,2.,0.,0.,2.,0.,3.,1.,0.,3.,2.,0.,0.,1.,0.,2.,2.,0.,1.,1.,1.,1.,1.25,1.,1.,1.5,1.,2.,1.,1.,1.,2.,1.,0.,2.,1.,3.,1.,1.,3.,2.,1.,0.,1.,1.,2.,2.,1.,1.,1.,2.,1.,1.25,2.,1.,1.5,2.,2.,1.,2.,1.,2.,2.,0.,2.,2.,3.,1.,2.,3.,2.,2.,0.,1.,2.,2.,2.,2.,1.,1.,3.,1.,1.25,3.,1.,1.5,3.,2.,1.,3.,1.,2.,3.,0.,2.,3.,3.,1.,3.,3.,2.,3.,0.,1.,3.,2.,2.,3.,1.,1.5408576,0.,2.,1.6108576000000001,0.,2.,1.5408576,1.,1.,1.5,0.5836800000000008,1.,1.4708576,1.,3.,1.6808576,0.,3.,1.6108576000000001,1.,0.,1.4708576,0.,0.,1.4008576,1.,2.,1.4708576,2.,1.,1.4008576000000001,2.,3.,1.5408575999999998,2.,0.,1.3308575999999999,2.,2.,1.4008576,3.,1.,1.3308576,3.,3.,1.4708576,3.,0.,1.2608576,3.}; - CPPUNIT_ASSERT_EQUAL(2,slice1->getMeshDimension()); - CPPUNIT_ASSERT_EQUAL(3,slice1->getSpaceDimension()); - CPPUNIT_ASSERT_EQUAL(57,slice1->getNumberOfNodes()); - CPPUNIT_ASSERT_EQUAL(9,slice1->getNumberOfCells()); - CPPUNIT_ASSERT_EQUAL(9,ids->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(47,slice1->getNodalConnectivity()->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(10,slice1->getNodalConnectivityIndex()->getNumberOfTuples()); - CPPUNIT_ASSERT(std::equal(expected1,expected1+9,ids->getConstPointer())); - CPPUNIT_ASSERT(std::equal(expected2,expected2+47,slice1->getNodalConnectivity()->getConstPointer())); - CPPUNIT_ASSERT(std::equal(expected3,expected3+10,slice1->getNodalConnectivityIndex()->getConstPointer())); - for(int i=0;i<171;i++) - CPPUNIT_ASSERT_DOUBLES_EQUAL(expected4[i],slice1->getCoords()->getIJ(0,i),1e-12); - ids->decrRef(); - slice1->decrRef(); - // 2nd slice based on already existing nodes of mesh3D. - const double vec2[3]={0.,3.,1.}; - const double origin2[3]={2.5,1.,3.}; - slice1=mesh3D->buildSlice3D(origin2,vec2,1e-10,ids); - const int expected5[49]={5,50,10,4,51,5,50,52,7,10,5,51,4,5,53,5,54,50,51,55,56,5,54,57,52,50,5,56,55,51,53,58,5,38,59,56,54,43,5,54,57,46,43,5,38,59,56,58,48}; - const int expected6[10]={0,5,10,15,21,26,32,38,43,49}; - const double expected7[180]={1.,1.,0.,1.,1.25,0.,1.,1.5,0.,2.,1.,0.,1.,2.,0.,0.,2.,0.,3.,1.,0.,3.,2.,0.,0.,1.,0.,1.,3.,0.,2.,2.,0.,2.,3.,0.,1.,1.,1.,1.,1.25,1.,1.,1.5,1.,2.,1.,1.,1.,2.,1.,0.,2.,1.,3.,1.,1.,3.,2.,1.,0.,1.,1.,1.,3.,1.,2.,2.,1.,2.,3.,1.,0.,0.,2.,1.,1.,2.,1.,1.25,2.,1.,0.,2.,1.,1.5,2.,2.,0.,2.,2.,1.,2.,1.,2.,2.,0.,2.,2.,3.,1.,2.,3.,2.,2.,0.,1.,2.,2.,2.,2.,0.,0.,3.,1.,1.,3.,1.,1.25,3.,1.,0.,3.,1.,1.5,3.,2.,0.,3.,2.,1.,3.,1.,2.,3.,0.,2.,3.,3.,1.,3.,3.,2.,3.,0.,1.,3.,2.,2.,3.,2.,1.6666666666666667,1.,1.,1.6666666666666667,1.,3.,1.6666666666666667,1.,0.,1.6666666666666667,1.,2.,1.3333333333333335,2.,1.,1.5,1.5,1.,1.3333333333333333,2.,3.,1.3333333333333335,2.,0.,1.3333333333333335,2.,1.,1.25,2.25}; - CPPUNIT_ASSERT_EQUAL(2,slice1->getMeshDimension()); - CPPUNIT_ASSERT_EQUAL(3,slice1->getSpaceDimension()); - CPPUNIT_ASSERT_EQUAL(60,slice1->getNumberOfNodes()); - CPPUNIT_ASSERT_EQUAL(9,slice1->getNumberOfCells()); - CPPUNIT_ASSERT_EQUAL(9,ids->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(49,slice1->getNodalConnectivity()->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(10,slice1->getNodalConnectivityIndex()->getNumberOfTuples()); - CPPUNIT_ASSERT(std::equal(expected1,expected1+9,ids->getConstPointer())); - CPPUNIT_ASSERT(std::equal(expected5,expected5+49,slice1->getNodalConnectivity()->getConstPointer())); - CPPUNIT_ASSERT(std::equal(expected6,expected6+10,slice1->getNodalConnectivityIndex()->getConstPointer())); - for(int i=0;i<180;i++) - CPPUNIT_ASSERT_DOUBLES_EQUAL(expected7[i],slice1->getCoords()->getIJ(0,i),1e-12); - ids->decrRef(); - slice1->decrRef(); - // 3rd slice based on shared face of mesh3D. - const double vec3[3]={0.,0.,1.}; - const double origin3[3]={2.5,1.,2.}; - slice1=mesh3D->buildSlice3D(origin3,vec3,1e-10,ids); - const int expected8[12]={6,7,8,9,10,11,12,13,14,15,16,17}; - const int expected9[68]={5,15,26,16,18,5,16,21,28,22,19,17,5,18,20,21,16,5,21,24,25,28,5,26,16,17,19,22,23,5,22,27,29,28,5,15,26,16,18,5,16,21,28,22,19,17,5,18,20,21,16,5,21,24,25,28,5,26,16,17,19,22,23,5,22,27,29,28}; - const int expected10[13]={0,5,12,17,22,29,34,39,46,51,56,63,68}; - const double expected11[135]={0.,0.,1.,1.,1.,1.,1.,1.25, 1.,1.,0.,1.,1.,1.5, 1.,2.,0.,1.,2.,1.,1.,1.,2.,1.,0.,2.,1.,3.,1.,1.,3.,2.,1.,0.,1.,1.,1.,3.,1.,2.,2.,1.,2.,3.,1.,0.,0.,2.,1.,1.,2.,1.,1.25, 2.,1.,0.,2.,1.,1.5, 2.,2.,0.,2.,2.,1.,2.,1.,2.,2.,0.,2.,2.,3.,1.,2.,3.,2.,2.,0.,1.,2.,1.,3.,2.,2.,2.,2.,2.,3.,2.,0.,0.,3.,1.,1.,3.,1.,1.25, 3.,1.,0.,3.,1.,1.5, 3.,2.,0.,3.,2.,1.,3.,1.,2.,3.,0.,2.,3.,3.,1.,3.,3.,2.,3.,0.,1.,3.,1.,3.,3.,2.,2.,3.,2.,3.,3.}; - CPPUNIT_ASSERT_EQUAL(2,slice1->getMeshDimension()); - CPPUNIT_ASSERT_EQUAL(3,slice1->getSpaceDimension()); - CPPUNIT_ASSERT_EQUAL(45,slice1->getNumberOfNodes()); - CPPUNIT_ASSERT_EQUAL(12,slice1->getNumberOfCells()); - CPPUNIT_ASSERT_EQUAL(12,ids->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(68,slice1->getNodalConnectivity()->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(13,slice1->getNodalConnectivityIndex()->getNumberOfTuples()); - CPPUNIT_ASSERT(std::equal(expected8,expected8+12,ids->getConstPointer())); - CPPUNIT_ASSERT(std::equal(expected9,expected9+68,slice1->getNodalConnectivity()->getConstPointer())); - CPPUNIT_ASSERT(std::equal(expected10,expected10+13,slice1->getNodalConnectivityIndex()->getConstPointer())); - for(int i=0;i<135;i++) - CPPUNIT_ASSERT_DOUBLES_EQUAL(expected11[i],slice1->getCoords()->getIJ(0,i),1e-12); - ids->decrRef(); - slice1->decrRef(); - // - mesh3D->decrRef(); -} - -void MEDCouplingBasicsTest5::testBuildSlice3DSurf1() -{ - MEDCouplingUMesh *mesh2D=0; - MEDCouplingUMesh *mesh3D=build3DExtrudedUMesh_1(mesh2D); - mesh2D->decrRef(); - DataArrayInt *a=DataArrayInt::New(),*b=DataArrayInt::New(),*c=DataArrayInt::New(),*d=DataArrayInt::New(); - mesh2D=mesh3D->buildDescendingConnectivity(a,b,c,d); - a->decrRef(); b->decrRef(); c->decrRef(); d->decrRef(); - mesh3D->decrRef(); - // - const double vec1[3]={-0.07,1.,0.07}; - const double origin1[3]={1.524,1.4552,1.74768}; - DataArrayInt *ids=0; - MEDCouplingUMesh *slice1=mesh2D->buildSlice3DSurf(origin1,vec1,1e-10,ids); - const int expected1[25]={6,8,10,11,13,18,19,21,23,25,26,38,41,43,47,49,52,53,64,67,69,73,75,78,79}; - const int expected2[75]={1,40,41,1,42,41,1,40,43,1,44,43,1,42,44,1,45,41,1,42,46,1,46,45,1,47,40,1,47,48,1,44,48,1,49,42,1,44,50,1,49,50,1,49,51,1,51,46,1,48,52,1,50,52,1,53,49,1,50,54,1,53,54,1,53,55,1,55,51,1,52,56,1,54,56}; - const int expected3[26]={0,3,6,9,12,15,18,21,24,27,30,33,36,39,42,45,48,51,54,57,60,63,66,69,72,75}; - const double expected4[171]={1.,1.,0.,1.,1.25,0.,1.,1.5,0.,2.,1.,0.,1.,2.,0.,0.,2.,0.,3.,1.,0.,3.,2.,0.,0.,1.,0.,2.,2.,0.,1.,1.,1.,1.,1.25,1.,1.,1.5,1.,2.,1.,1.,1.,2.,1.,0.,2.,1.,3.,1.,1.,3.,2.,1.,0.,1.,1.,2.,2.,1.,1.,1.,2.,1.,1.25,2.,1.,1.5,2.,2.,1.,2.,1.,2.,2.,0.,2.,2.,3.,1.,2.,3.,2.,2.,0.,1.,2.,2.,2.,2.,1.,1.,3.,1.,1.25,3.,1.,1.5,3.,2.,1.,3.,1.,2.,3.,0.,2.,3.,3.,1.,3.,3.,2.,3.,0.,1.,3.,2.,2.,3.,1.,1.5408576,0.,2.,1.6108576000000001,0.,2.,1.5408576,1.,1.,1.5,0.5836800000000008,1.,1.4708576,1.,3.,1.6808576,0.,3.,1.6108576000000001,1.,0.,1.4708576,0.,0.,1.4008576,1.,2.,1.4708576,2.,1.,1.4008576000000001,2.,3.,1.5408575999999998,2.,0.,1.3308575999999999,2.,2.,1.4008576,3.,1.,1.3308576,3.,3.,1.4708576,3.,0.,1.2608576,3.}; - CPPUNIT_ASSERT_EQUAL(1,slice1->getMeshDimension()); - CPPUNIT_ASSERT_EQUAL(3,slice1->getSpaceDimension()); - CPPUNIT_ASSERT_EQUAL(57,slice1->getNumberOfNodes()); - CPPUNIT_ASSERT_EQUAL(25,slice1->getNumberOfCells()); - CPPUNIT_ASSERT_EQUAL(25,ids->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(75,slice1->getNodalConnectivity()->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(26,slice1->getNodalConnectivityIndex()->getNumberOfTuples()); - CPPUNIT_ASSERT(std::equal(expected1,expected1+25,ids->getConstPointer())); - CPPUNIT_ASSERT(std::equal(expected2,expected2+47,slice1->getNodalConnectivity()->getConstPointer())); - CPPUNIT_ASSERT(std::equal(expected3,expected3+26,slice1->getNodalConnectivityIndex()->getConstPointer())); - for(int i=0;i<171;i++) - CPPUNIT_ASSERT_DOUBLES_EQUAL(expected4[i],slice1->getCoords()->getIJ(0,i),1e-12); - ids->decrRef(); - slice1->decrRef(); - // - const double vec2[3]={0.,0.,1.}; - const double origin2[3]={2.5,1.,2.}; - slice1=mesh2D->buildSlice3DSurf(origin2,vec2,1e-10,ids); - const int expected5[68]={32,32,32,32,33,34,35,36,37,38,39,40,41,42,43,43,43,43,43,43,44,44,44,44,45,46,47,47,47,47,48,49,50,51,52,53,53,53,53,53,53,54,54,54,54,55,56,57,59,60,61,62,63,64,65,66,67,68,71,72,74,75,76,77,78,81,82,83}; - const int expected6[204]={1,15,18,1,18,16,1,16,26,1,26,15,1,26,15,1,16,26,1,18,16,1,15,18,1,16,21,1,21,28,1,22,28,1,19,22,1,17,19,1,16,17,1,16,21,1,21,28,1,28,22,1,22,19,1,19,17,1,17,16,1,16,18,1,18,20,1,20,21,1,21,16,1,20,21,1,18,20,1,28,21,1,21,24,1,24,25,1,25,28,1,25,28,1,24,25,1,21,24,1,23,22,1,26,23,1,26,16,1,16,17,1,17,19,1,19,22,1,22,23,1,23,26,1,22,28,1,28,29,1,29,27,1,27,22,1,27,22,1,29,27,1,28,29,1,26,15,1,16,26,1,18,16,1,15,18,1,16,21,1,21,28,1,22,28,1,19,22,1,17,19,1,16,17,1,20,21,1,18,20,1,25,28,1,24,25,1,21,24,1,23,22,1,26,23,1,27,22,1,29,27,1,28,29}; - const int expected7[69]={0,3,6,9,12,15,18,21,24,27,30,33,36,39,42,45,48,51,54,57,60,63,66,69,72,75,78,81,84,87,90,93,96,99,102,105,108,111,114,117,120,123,126,129,132,135,138,141,144,147,150,153,156,159,162,165,168,171,174,177,180,183,186,189,192,195,198,201,204}; - const double expected8[135]={0.,0.,1.,1.,1.,1.,1.,1.25, 1.,1.,0.,1.,1.,1.5, 1.,2.,0.,1.,2.,1.,1.,1.,2.,1.,0.,2.,1.,3.,1.,1.,3.,2.,1.,0.,1.,1.,1.,3.,1.,2.,2.,1.,2.,3.,1.,0.,0.,2.,1.,1.,2.,1.,1.25, 2.,1.,0.,2.,1.,1.5, 2.,2.,0.,2.,2.,1.,2.,1.,2.,2.,0.,2.,2.,3.,1.,2.,3.,2.,2.,0.,1.,2.,1.,3.,2.,2.,2.,2.,2.,3.,2.,0.,0.,3.,1.,1.,3.,1.,1.25, 3.,1.,0.,3.,1.,1.5, 3.,2.,0.,3.,2.,1.,3.,1.,2.,3.,0.,2.,3.,3.,1.,3.,3.,2.,3.,0.,1.,3.,1.,3.,3.,2.,2.,3.,2.,3.,3.}; - CPPUNIT_ASSERT_EQUAL(1,slice1->getMeshDimension()); - CPPUNIT_ASSERT_EQUAL(3,slice1->getSpaceDimension()); - CPPUNIT_ASSERT_EQUAL(45,slice1->getNumberOfNodes()); - CPPUNIT_ASSERT_EQUAL(68,slice1->getNumberOfCells()); - CPPUNIT_ASSERT_EQUAL(68,ids->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(204,slice1->getNodalConnectivity()->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(69,slice1->getNodalConnectivityIndex()->getNumberOfTuples()); - CPPUNIT_ASSERT(std::equal(expected5,expected5+68,ids->getConstPointer())); - CPPUNIT_ASSERT(std::equal(expected6,expected6+171,slice1->getNodalConnectivity()->getConstPointer())); - CPPUNIT_ASSERT(std::equal(expected7,expected7+69,slice1->getNodalConnectivityIndex()->getConstPointer())); - for(int i=0;i<135;i++) - CPPUNIT_ASSERT_DOUBLES_EQUAL(expected8[i],slice1->getCoords()->getIJ(0,i),1e-12); - ids->decrRef(); - slice1->decrRef(); - // - mesh2D->decrRef(); -} - -void MEDCouplingBasicsTest5::testDataArrayDoubleAdvSetting1() -{ - const double data1[14]={1.,11.,2.,12.,3.,13.,4.,14.,5.,15.,6.,16.,7.,17.}; - const double data2[10]={8.,38.,9.,39.,0.,30.,11.,41.,12.,42.}; - const char *comps[2]={"comp1","comp2"}; - std::vector compsCpp(comps,comps+2); - DataArrayDouble *da=DataArrayDouble::New(); - DataArrayDouble *tmp=0; - da->setInfoAndChangeNbOfCompo(compsCpp); - da->setName("da"); - da->alloc(7,2); - compsCpp.pop_back(); - CPPUNIT_ASSERT_THROW(da->setInfoAndChangeNbOfCompo(compsCpp),INTERP_KERNEL::Exception); - std::copy(data1,data1+14,da->getPointer()); - // - std::vector > p(3); - p[0].first=0; p[0].second=3; p[1].first=3; p[1].second=5; p[2].first=5; p[2].second=7; - tmp=dynamic_cast(da->selectByTupleRanges(p)); - CPPUNIT_ASSERT(tmp->isEqual(*da,1e-14)); - tmp->decrRef(); - p[0].first=0; p[0].second=2; p[1].first=3; p[1].second=4; p[2].first=5; p[2].second=7; - tmp=dynamic_cast(da->selectByTupleRanges(p)); - const double expected1[10]={1.,11.,2.,12.,4.,14.,6.,16.,7.,17.}; - CPPUNIT_ASSERT_EQUAL(5,tmp->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(2,tmp->getNumberOfComponents()); - for(int i=0;i<10;i++) - CPPUNIT_ASSERT_DOUBLES_EQUAL(expected1[i],tmp->getIJ(0,i),1e-14); - tmp->decrRef(); - p[0].first=0; p[0].second=2; p[1].first=0; p[1].second=2; p[2].first=5; p[2].second=6; - tmp=dynamic_cast(da->selectByTupleRanges(p)); - const double expected2[10]={1.,11.,2.,12.,1.,11.,2.,12.,6.,16.}; - CPPUNIT_ASSERT_EQUAL(5,tmp->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(2,tmp->getNumberOfComponents()); - for(int i=0;i<10;i++) - CPPUNIT_ASSERT_DOUBLES_EQUAL(expected2[i],tmp->getIJ(0,i),1e-14); - tmp->decrRef(); - p[0].first=0; p[0].second=2; p[1].first=-1; p[1].second=2; p[2].first=5; p[2].second=6; - CPPUNIT_ASSERT_THROW(da->selectByTupleRanges(p),INTERP_KERNEL::Exception); - p[0].first=0; p[0].second=2; p[1].first=0; p[1].second=2; p[2].first=5; p[2].second=8; - CPPUNIT_ASSERT_THROW(da->selectByTupleRanges(p),INTERP_KERNEL::Exception); - // - DataArrayDouble *da2=DataArrayDouble::New(); - da2->alloc(5,2); - std::copy(data2,data2+10,da2->getPointer()); - // - DataArrayDouble *dac=da->deepCpy(); - dac->setContigPartOfSelectedValues2(1,da2,2,4,1); - const double expected3[14]={1.,11.,0.,30.,11.,41.,4.,14.,5.,15.,6.,16.,7.,17.}; - for(int i=0;i<14;i++) - CPPUNIT_ASSERT_DOUBLES_EQUAL(expected3[i],dac->getIJ(0,i),1e-14); - dac->decrRef(); - // - dac=da->deepCpy(); - CPPUNIT_ASSERT_THROW(dac->setContigPartOfSelectedValues2(3,da2,0,5,1),INTERP_KERNEL::Exception); - CPPUNIT_ASSERT_THROW(dac->setContigPartOfSelectedValues2(0,da2,4,6,1),INTERP_KERNEL::Exception); - CPPUNIT_ASSERT_THROW(dac->setContigPartOfSelectedValues2(3,da2,5,0,1),INTERP_KERNEL::Exception); - dac->setContigPartOfSelectedValues2(3,da2,1,5,1); - const double expected4[14]={1.,11.,2.,12.,3.,13.,9.,39.,0.,30.,11.,41.,12.,42.}; - for(int i=0;i<14;i++) - CPPUNIT_ASSERT_DOUBLES_EQUAL(expected4[i],dac->getIJ(0,i),1e-14); - dac->decrRef(); - // - DataArrayInt *ids=DataArrayInt::New(); - ids->alloc(3,1); - dac=da->deepCpy(); - ids->setIJ(0,0,2); ids->setIJ(1,0,0); ids->setIJ(2,0,4); - dac->setContigPartOfSelectedValues(2,da2,ids); - const double expected5[14]={1.,11.,2.,12.,0.,30.,8.,38.,12.,42.,6.,16.,7.,17.}; - for(int i=0;i<14;i++) - CPPUNIT_ASSERT_DOUBLES_EQUAL(expected5[i],dac->getIJ(0,i),1e-14); - dac->decrRef(); - // - dac=da->deepCpy(); - ids->setIJ(0,0,2); ids->setIJ(1,0,5); ids->setIJ(2,0,4); - CPPUNIT_ASSERT_THROW(dac->setContigPartOfSelectedValues(1,da2,ids),INTERP_KERNEL::Exception); - ids->setIJ(0,0,2); ids->setIJ(1,0,2); ids->setIJ(2,0,-1); - CPPUNIT_ASSERT_THROW(dac->setContigPartOfSelectedValues(1,da2,ids),INTERP_KERNEL::Exception); - ids->setIJ(0,0,2); ids->setIJ(1,0,2); ids->setIJ(2,0,1); - CPPUNIT_ASSERT_THROW(dac->setContigPartOfSelectedValues(5,da2,ids),INTERP_KERNEL::Exception); - dac->decrRef(); - // - ids->setIJ(0,0,2); ids->setIJ(1,0,2); ids->setIJ(2,0,1); - dac=da->deepCpy(); - dac->setContigPartOfSelectedValues(4,da2,ids); - const double expected6[14]={1.,11.,2.,12.,3.,13.,4.,14.,0.,30.,0.,30.,9.,39.}; - for(int i=0;i<14;i++) - CPPUNIT_ASSERT_DOUBLES_EQUAL(expected6[i],dac->getIJ(0,i),1e-14); - dac->decrRef(); - ids->decrRef(); - // - da2->decrRef(); - da->decrRef(); -} - -void MEDCouplingBasicsTest5::testDataArrayIntAdvSetting1() -{ - const int data1[14]={1,11,2,12,3,13,4,14,5,15,6,16,7,17}; - const int data2[10]={8,38,9,39,0,30,11,41,12,42}; - const char *comps[2]={"comp1","comp2"}; - std::vector compsCpp(comps,comps+2); - DataArrayInt *da=DataArrayInt::New(); - DataArrayInt *tmp=0; - da->setInfoAndChangeNbOfCompo(compsCpp); - da->setName("da"); - da->alloc(7,2); - compsCpp.pop_back(); - CPPUNIT_ASSERT_THROW(da->setInfoAndChangeNbOfCompo(compsCpp),INTERP_KERNEL::Exception); - std::copy(data1,data1+14,da->getPointer()); - // - std::vector > p(3); - p[0].first=0; p[0].second=3; p[1].first=3; p[1].second=5; p[2].first=5; p[2].second=7; - tmp=dynamic_cast(da->selectByTupleRanges(p)); - CPPUNIT_ASSERT(tmp->isEqual(*da)); - tmp->decrRef(); - p[0].first=0; p[0].second=2; p[1].first=3; p[1].second=4; p[2].first=5; p[2].second=7; - tmp=dynamic_cast(da->selectByTupleRanges(p)); - const int expected1[10]={1,11,2,12,4,14,6,16,7,17}; - CPPUNIT_ASSERT_EQUAL(5,tmp->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(2,tmp->getNumberOfComponents()); - for(int i=0;i<10;i++) - CPPUNIT_ASSERT_EQUAL(expected1[i],tmp->getIJ(0,i)); - tmp->decrRef(); - p[0].first=0; p[0].second=2; p[1].first=0; p[1].second=2; p[2].first=5; p[2].second=6; - tmp=dynamic_cast(da->selectByTupleRanges(p)); - const int expected2[10]={1,11,2,12,1,11,2,12,6,16}; - CPPUNIT_ASSERT_EQUAL(5,tmp->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(2,tmp->getNumberOfComponents()); - for(int i=0;i<10;i++) - CPPUNIT_ASSERT_EQUAL(expected2[i],tmp->getIJ(0,i)); - tmp->decrRef(); - p[0].first=0; p[0].second=2; p[1].first=-1; p[1].second=2; p[2].first=5; p[2].second=6; - CPPUNIT_ASSERT_THROW(da->selectByTupleRanges(p),INTERP_KERNEL::Exception); - p[0].first=0; p[0].second=2; p[1].first=0; p[1].second=2; p[2].first=5; p[2].second=8; - CPPUNIT_ASSERT_THROW(da->selectByTupleRanges(p),INTERP_KERNEL::Exception); - // - DataArrayInt *da2=DataArrayInt::New(); - da2->alloc(5,2); - std::copy(data2,data2+10,da2->getPointer()); - // - DataArrayInt *dac=da->deepCpy(); - dac->setContigPartOfSelectedValues2(1,da2,2,4,1); - const int expected3[14]={1,11,0,30,11,41,4,14,5,15,6,16,7,17}; - for(int i=0;i<14;i++) - CPPUNIT_ASSERT_EQUAL(expected3[i],dac->getIJ(0,i)); - dac->decrRef(); - // - dac=da->deepCpy(); - CPPUNIT_ASSERT_THROW(dac->setContigPartOfSelectedValues2(3,da2,0,5,1),INTERP_KERNEL::Exception); - CPPUNIT_ASSERT_THROW(dac->setContigPartOfSelectedValues2(0,da2,4,6,1),INTERP_KERNEL::Exception); - CPPUNIT_ASSERT_THROW(dac->setContigPartOfSelectedValues2(3,da2,5,0,1),INTERP_KERNEL::Exception); - dac->setContigPartOfSelectedValues2(3,da2,1,5,1); - const int expected4[14]={1,11,2,12,3,13,9,39,0,30,11,41,12,42}; - for(int i=0;i<14;i++) - CPPUNIT_ASSERT_EQUAL(expected4[i],dac->getIJ(0,i)); - dac->decrRef(); - // - DataArrayInt *ids=DataArrayInt::New(); - ids->alloc(3,1); - dac=da->deepCpy(); - ids->setIJ(0,0,2); ids->setIJ(1,0,0); ids->setIJ(2,0,4); - dac->setContigPartOfSelectedValues(2,da2,ids); - const int expected5[14]={1,11,2,12,0,30,8,38,12,42,6,16,7,17}; - for(int i=0;i<14;i++) - CPPUNIT_ASSERT_EQUAL(expected5[i],dac->getIJ(0,i)); - dac->decrRef(); - // - dac=da->deepCpy(); - ids->setIJ(0,0,2); ids->setIJ(1,0,5); ids->setIJ(2,0,4); - CPPUNIT_ASSERT_THROW(dac->setContigPartOfSelectedValues(1,da2,ids),INTERP_KERNEL::Exception); - ids->setIJ(0,0,2); ids->setIJ(1,0,2); ids->setIJ(2,0,-1); - CPPUNIT_ASSERT_THROW(dac->setContigPartOfSelectedValues(1,da2,ids),INTERP_KERNEL::Exception); - ids->setIJ(0,0,2); ids->setIJ(1,0,2); ids->setIJ(2,0,1); - CPPUNIT_ASSERT_THROW(dac->setContigPartOfSelectedValues(5,da2,ids),INTERP_KERNEL::Exception); - dac->decrRef(); - // - ids->setIJ(0,0,2); ids->setIJ(1,0,2); ids->setIJ(2,0,1); - dac=da->deepCpy(); - dac->setContigPartOfSelectedValues(4,da2,ids); - const int expected6[14]={1,11,2,12,3,13,4,14,0,30,0,30,9,39}; - for(int i=0;i<14;i++) - CPPUNIT_ASSERT_EQUAL(expected6[i],dac->getIJ(0,i)); - dac->decrRef(); - ids->decrRef(); - // - da2->decrRef(); - da->decrRef(); -} - -void MEDCouplingBasicsTest5::testBuildDescendingConnec2Of3DMesh1() -{ - MEDCouplingUMesh *mesh=build3DSourceMesh_1(); - DataArrayInt *desc=DataArrayInt::New(); - DataArrayInt *descIndx=DataArrayInt::New(); - DataArrayInt *revDesc=DataArrayInt::New(); - DataArrayInt *revDescIndx=DataArrayInt::New(); - // - MEDCouplingUMesh *mesh2=mesh->buildDescendingConnectivity2(desc,descIndx,revDesc,revDescIndx); - mesh2->checkCoherency(); - CPPUNIT_ASSERT_EQUAL(2,mesh2->getMeshDimension()); - CPPUNIT_ASSERT_EQUAL(30,mesh2->getNumberOfCells()); - CPPUNIT_ASSERT_EQUAL((std::size_t)31,revDescIndx->getNbOfElems()); CPPUNIT_ASSERT_EQUAL(31,revDescIndx->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL((std::size_t)13,descIndx->getNbOfElems()); CPPUNIT_ASSERT_EQUAL(13,descIndx->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL((std::size_t)48,desc->getNbOfElems()); CPPUNIT_ASSERT_EQUAL(48,desc->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL((std::size_t)48,revDesc->getNbOfElems()); CPPUNIT_ASSERT_EQUAL(48,revDesc->getNumberOfTuples()); - const int expected1[48]={1,2,3,4,5,6,7,8,9,10,11,12,13,14,-10,15,-5,-13,16,17,-14,18,-4,19,-2,20,21,22,23,24,25,-11,26,-1,-12,-25,-22,27,28,-7,-20,-24,29,-16,-18,30,-8,-28}; - CPPUNIT_ASSERT(std::equal(expected1,expected1+48,desc->getConstPointer())); - const int expected2[13]={0,4,8,12,16,20,24,28,32,36,40,44,48}; - CPPUNIT_ASSERT(std::equal(expected2,expected2+13,descIndx->getConstPointer())); - const int expected3[31]={0,2,4,5,7,9,10,12,14,15,17,19,21,23,25,26,28,29,31,32,34,35,37,38,40,42,43,44,46,47,48}; - CPPUNIT_ASSERT(std::equal(expected3,expected3+31,revDescIndx->getConstPointer())); - const int expected4[48]={0,8,0,6,0,0,5,1,4,1,1,9,1,11,2,2,3,2,7,2,8,3,4,3,5,3,4,10,4,5,11,5,6,10,6,6,9,7,7,10,7,8,8,9,9,11,10,11}; - CPPUNIT_ASSERT(std::equal(expected4,expected4+48,revDesc->getConstPointer())); - DataArrayInt *conn=mesh2->getNodalConnectivity(); - DataArrayInt *connIndex=mesh2->getNodalConnectivityIndex(); - const int expected5[31]={0,4,8,12,16,20,24,28,32,36,40,44,48,52,56,60,64,68,72,76,80,84,88,92,96,100,104,108,112,116,120}; - CPPUNIT_ASSERT(std::equal(expected5,expected5+31,connIndex->getConstPointer())); - const int expected6[120]={3,8,1,7,3,8,3,1,3,1,3,7,3,7,3,8,3,6,0,8,3,6,2,0,3,0,2,8,3,8,2,6,3,7,4,5,3,7,8,4,3,4,8,5,3,5,8,7,3,6,8,4,3,6,7,8,3,4,7,6,3,8,4,0,3,0,4,6,3,6,3,8,3,7,3,6,3,8,0,1,3,1,0,3,3,3,0,8,3,4,1,5,3,4,8,1,3,1,8,5,3,1,7,5,3,0,2,3,3,3,2,8,3,1,4,0,3,3,2,6}; - CPPUNIT_ASSERT(std::equal(expected6,expected6+120,conn->getConstPointer())); - // - desc->decrRef(); - descIndx->decrRef(); - revDesc->decrRef(); - revDescIndx->decrRef(); - mesh2->decrRef(); - mesh->decrRef(); -} - -void MEDCouplingBasicsTest5::testAre2DCellsNotCorrectlyOriented1() -{ - double m1Coords[8]={1.,1.,-1.,-1.,-1.,-1.,1.,-1.}; - int m1Conn[4]={0,3,1,2}; - MEDCouplingUMesh *m1=MEDCouplingUMesh::New(); - m1->setMeshDimension(2); - m1->allocateCells(1); - m1->insertNextCell(INTERP_KERNEL::NORM_QUAD4,4,m1Conn); - m1->finishInsertingCells(); - DataArrayDouble *myCoords1=DataArrayDouble::New(); - myCoords1->alloc(4,2); - std::copy(m1Coords,m1Coords+8,myCoords1->getPointer()); - m1->setCoords(myCoords1); - myCoords1->decrRef(); - // - double vec1[3]={0.,0.,1.}; - double *vec2=new double[2]; - for(int i=0;i<18;i++) - { - vec2[0]=3.*cos(M_PI/9.*i); - vec2[1]=3.*sin(M_PI/9.*i); - MEDCouplingUMesh *m1Cpy=static_cast(m1->deepCpy()); - m1Cpy->translate(vec2); - std::vector res; - CPPUNIT_ASSERT_THROW(m1Cpy->are2DCellsNotCorrectlyOriented(vec1,false,res),INTERP_KERNEL::Exception); - res.clear(); - m1Cpy->changeSpaceDimension(3); - m1Cpy->are2DCellsNotCorrectlyOriented(vec1,false,res); - CPPUNIT_ASSERT_EQUAL(1,(int)res.size()); - CPPUNIT_ASSERT_EQUAL(0,res[0]); - m1Cpy->decrRef(); - } - delete [] vec2; - // - m1->decrRef(); -} - -void MEDCouplingBasicsTest5::testDataArrayAbs1() -{ - DataArrayDouble *d1=DataArrayDouble::New(); - const double val1[12]={2.,-3.,-5.,6.,-7.,-8.,9.,10.,-11.,-12.,-13.,-15.}; - const double expected1[12]={2.,3.,5.,6.,7.,8.,9.,10.,11.,12.,13.,15.}; - d1->alloc(6,2); - std::copy(val1,val1+12,d1->getPointer()); - DataArrayInt *d2=d1->convertToIntArr(); - // - d1->abs(); - for(int i=0;i<12;i++) - CPPUNIT_ASSERT_DOUBLES_EQUAL(expected1[i],d1->getIJ(0,i),1e-14); - // - const int expected2[12]={2,3,5,6,7,8,9,10,11,12,13,15}; - d2->abs(); - for(int i=0;i<12;i++) - CPPUNIT_ASSERT_EQUAL(expected2[i],d2->getIJ(0,i)); - // - d2->decrRef(); - d1->decrRef(); -} - -void MEDCouplingBasicsTest5::testGetValueOn3() -{ - const double v[4]={0.,1.,1.5,2.}; - const double v2[5]={0.7,1.25,0.,2.,1.5}; - const double disp[12]={5.,50.,500.,6.,60.,600.,7.,70.,700.,8.,80.,800.}; - MEDCouplingUMesh *m=MEDCouplingUMesh::New("myMesh",1); - const int nbNodes=4; - const int nbCells=nbNodes-1; - m->allocateCells(nbCells); - DataArrayDouble *coords=DataArrayDouble::New(); - coords->alloc(nbNodes,1); - std::copy(v,v+nbNodes,coords->getPointer()); - m->setCoords(coords); - coords->decrRef(); - const int conn[6]={0,1,2,1,2,3}; - m->insertNextCell(INTERP_KERNEL::NORM_SEG2,2,conn); - m->insertNextCell(INTERP_KERNEL::NORM_SEG2,2,conn+2); - m->insertNextCell(INTERP_KERNEL::NORM_SEG2,2,conn+4); - m->finishInsertingCells(); - MEDCouplingFieldDouble *f=MEDCouplingFieldDouble::New(ON_NODES); - f->setMesh(m); - DataArrayDouble *array=DataArrayDouble::New(); - array->alloc(m->getNumberOfNodes(),3); - std::copy(disp,disp+12,array->getPointer()); - f->setArray(array); - array->decrRef(); - DataArrayDouble *arr1=f->getValueOnMulti(v2,5); - CPPUNIT_ASSERT_EQUAL(5,arr1->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(3,arr1->getNumberOfComponents()); - const double expected1[15]={5.7,57.,570.,6.5,65.,650.,5.,50.,500.,8.,80.,800.,7.,70.,700.}; - for(int i=0;i<15;i++) - CPPUNIT_ASSERT_DOUBLES_EQUAL(expected1[i],arr1->getIJ(0,i),1e-14); - arr1->decrRef(); - f->decrRef(); - m->decrRef(); -} - -void MEDCouplingBasicsTest5::testGetNodeIdsOfCell2() -{ - MEDCouplingCMesh *m1c=MEDCouplingCMesh::New(); - DataArrayDouble *coordsX=DataArrayDouble::New(); - double arrX[5] = { -1., 1., 2., 4., 4.5 }; - coordsX->useArray(arrX,false, CPP_DEALLOC,5,1); - DataArrayDouble *coordsY=DataArrayDouble::New(); - double arrY[4] = { -2., 2., 4., 8. }; - coordsY->useArray(arrY,false, CPP_DEALLOC,4,1); - DataArrayDouble *coordsZ=DataArrayDouble::New(); - double arrZ[3] = { -2., 2., 4. }; - coordsZ->useArray(arrZ,false, CPP_DEALLOC,3,1); - // test in 1D - m1c->setCoordsAt(0,coordsX); - CPPUNIT_ASSERT_EQUAL(4,m1c->getNumberOfCells()); - const int expected1[4][2]={{0,1},{1,2},{2,3},{3,4}}; - for(int i=0;i<4;i++) - { - std::vector v; - m1c->getNodeIdsOfCell(i,v); - CPPUNIT_ASSERT((int)v.size()==2); - std::equal(v.begin(),v.end(),expected1[i]); - } - // test in 2D - m1c->setCoordsAt(1,coordsY); - CPPUNIT_ASSERT_EQUAL(12,m1c->getNumberOfCells()); - const int expected2[12][4]={{0,1,6,5},{1,2,7,6},{2,3,8,7},{3,4,9,8},{4,5,11,10},{5,6,12,11},{6,7,13,12},{7,8,14,13},{8,9,16,15},{9,10,17,16},{10,11,18,17},{11,12,19,18}}; - for(int i=0;i<12;i++) - { - std::vector v; - m1c->getNodeIdsOfCell(i,v); - CPPUNIT_ASSERT((int)v.size()==4); - std::equal(v.begin(),v.end(),expected2[i]); - } - // test in 3D - m1c->setCoordsAt(2,coordsZ); - CPPUNIT_ASSERT_EQUAL(24,m1c->getNumberOfCells()); - const int expected3[24][8]={{0,1,6,5,20,21,26,25},{1,2,7,6,21,22,27,26},{2,3,8,7,22,23,28,27},{3,4,9,8,23,24,29,28},{4,5,11,10,24,25,31,30},{5,6,12,11,25,26,32,31},{6,7,13,12,26,27,33,32},{7,8,14,13,27,28,34,33},{8,9,16,15,28,29,36,35},{9,10,17,16,29,30,37,36},{10,11,18,17,30,31,38,37},{11,12,19,18,31,32,39,38},{20,21,26,25,40,41,46,45},{21,22,27,26,41,42,47,46},{22,23,28,27,42,43,48,47},{23,24,29,28,43,44,49,48},{24,25,31,30,44,45,51,50},{25,26,32,31,45,46,52,51},{26,27,33,32,46,47,53,52},{27,28,34,33,47,48,54,53},{28,29,36,35,48,49,56,55},{29,30,37,36,49,50,57,56},{30,31,38,37,50,51,58,57},{31,32,39,38,51,52,59,58}}; - for(int i=0;i<12;i++) - { - std::vector v; - m1c->getNodeIdsOfCell(i,v); - CPPUNIT_ASSERT((int)v.size()==8); - std::equal(v.begin(),v.end(),expected3[i]); - } - // - coordsX->decrRef(); - coordsY->decrRef(); - coordsZ->decrRef(); - m1c->decrRef(); -} - -void MEDCouplingBasicsTest5::testRenumberNodesInConn1() -{ - double mesh2DCoords[27]={-0.3,-0.3,0., 0.2,-0.3,0., 0.7,-0.3,0., -0.3,0.2,0., 0.2,0.2,0., 0.7,0.2,0., -0.3,0.7,0., 0.2,0.7,0., 0.7,0.7,0. }; - int mesh2DConn[18]={1,4,2, 4,5,2, 0,3,4,1, 6,7,4,3, 7,8,5,4}; - MEDCouplingUMesh *mesh2D=MEDCouplingUMesh::New("mesh",2); - mesh2D->allocateCells(5); - mesh2D->insertNextCell(INTERP_KERNEL::NORM_TRI3,3,mesh2DConn); - mesh2D->insertNextCell(INTERP_KERNEL::NORM_TRI3,3,mesh2DConn+3); - mesh2D->insertNextCell(INTERP_KERNEL::NORM_QUAD4,4,mesh2DConn+6); - mesh2D->insertNextCell(INTERP_KERNEL::NORM_QUAD4,4,mesh2DConn+10); - mesh2D->insertNextCell(INTERP_KERNEL::NORM_QUAD4,4,mesh2DConn+14); - mesh2D->finishInsertingCells(); - DataArrayDouble *myCoords=DataArrayDouble::New(); - myCoords->alloc(9,3); - std::copy(mesh2DCoords,mesh2DCoords+27,myCoords->getPointer()); - mesh2D->setCoords(myCoords); - myCoords->decrRef(); - mesh2D->checkCoherency(); - // - double mesh3DCoords[24]={-0.3,-0.3,0., -0.3,0.2,0., 0.2,0.2,0., 0.2,-0.3,0., -0.3,-0.3,1., -0.3,0.2,1., 0.2,0.2,1., 0.2,-0.3,1. }; - int mesh3DConn[8]={0,1,2,3,4,5,6,7}; - MEDCouplingUMesh *mesh3D=MEDCouplingUMesh::New("mesh",3); - mesh3D->allocateCells(1); - mesh3D->insertNextCell(INTERP_KERNEL::NORM_HEXA8,8,mesh3DConn); - mesh3D->finishInsertingCells(); - DataArrayDouble *myCoords3D=DataArrayDouble::New(); - myCoords3D->alloc(8,3); - std::copy(mesh3DCoords,mesh3DCoords+24,myCoords3D->getPointer()); - mesh3D->setCoords(myCoords3D); - myCoords3D->decrRef(); - mesh3D->checkCoherency(); - // - MEDCouplingUMesh *mesh3D_2=dynamic_cast(mesh3D->deepCpy()); - MEDCouplingUMesh *mesh2D_2=dynamic_cast(mesh2D->deepCpy()); - MEDCouplingUMesh *mesh3D_4=dynamic_cast(mesh3D->deepCpy()); - MEDCouplingUMesh *mesh2D_4=dynamic_cast(mesh2D->deepCpy()); - DataArrayInt *renumNodes=DataArrayInt::New(); - int oldNbOf3DNodes=mesh3D->getNumberOfNodes(); - renumNodes->alloc(mesh2D->getNumberOfNodes(),1); - renumNodes->iota(oldNbOf3DNodes); - DataArrayDouble *coo=DataArrayDouble::Aggregate(mesh3D->getCoords(),mesh2D->getCoords()); - mesh3D->setCoords(coo); - mesh2D->setCoords(coo); - coo->decrRef(); - MEDCouplingUMesh *mesh2D_3=dynamic_cast(mesh2D->deepCpy()); - mesh2D_3->shiftNodeNumbersInConn(oldNbOf3DNodes); - mesh2D->renumberNodesInConn(renumNodes->getConstPointer()); - renumNodes->decrRef(); - CPPUNIT_ASSERT(mesh2D_3->isEqual(mesh2D,1e-12)); - mesh2D_3->decrRef(); - // - DataArrayInt *da1,*da2; - mesh3D->checkGeoEquivalWith(mesh3D_2,10,1e-12,da1,da2); - CPPUNIT_ASSERT(da1==0); - CPPUNIT_ASSERT_EQUAL(8,da2->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(1,da2->getNumberOfComponents()); - const int expected1[8]={8,11,12,9,4,5,6,7}; - for(int i=0;i<8;i++) - CPPUNIT_ASSERT_EQUAL(expected1[i],da2->getIJ(i,0)); - da2->decrRef(); - // - mesh2D->checkGeoEquivalWith(mesh2D_2,10,1e-12,da1,da2); - CPPUNIT_ASSERT(da1==0); - CPPUNIT_ASSERT_EQUAL(9,da2->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(1,da2->getNumberOfComponents()); - for(int i=0;i<9;i++) - CPPUNIT_ASSERT_EQUAL(8+i,da2->getIJ(i,0)); - da2->decrRef(); - // - const double vect[3]={1.,0.,0.}; - MEDCouplingUMesh *mesh2D_5=dynamic_cast(mesh2D_4->deepCpy()); - mesh2D_5->translate(vect); - std::vector meshes(3); - meshes[0]=mesh3D_4; meshes[1]=mesh2D_4; meshes[2]=mesh2D_5; - MEDCouplingUMesh::PutUMeshesOnSameAggregatedCoords(meshes); - CPPUNIT_ASSERT(mesh3D_4->getCoords()==mesh2D_4->getCoords()); - CPPUNIT_ASSERT(mesh2D_4->getCoords()==mesh2D_5->getCoords()); - mesh3D_4->checkCoherency(); mesh2D_4->checkCoherency(); mesh2D_5->checkCoherency(); - CPPUNIT_ASSERT_EQUAL(26,mesh3D_4->getNumberOfNodes()); - CPPUNIT_ASSERT_EQUAL(3,mesh3D_4->getSpaceDimension()); - CPPUNIT_ASSERT_EQUAL(9,mesh3D_4->getNodalConnectivity()->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(23,mesh2D_4->getNodalConnectivity()->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(23,mesh2D_5->getNodalConnectivity()->getNumberOfTuples()); - const int expected2[9]={18,0,1,2,3,4,5,6,7}; - const int expected3[23]={3,9,12,10, 3,12,13,10, 4,8,11,12,9, 4,14,15,12,11, 4,15,16,13,12}; - const int expected4[23]={3,18,21,19, 3,21,22,19, 4,17,20,21,18, 4,23,24,21,20, 4,24,25,22,21}; - const double expected5[78]={-0.3,-0.3,0., -0.3,0.2,0., 0.2,0.2,0., 0.2,-0.3,0., -0.3,-0.3,1., -0.3,0.2,1., 0.2,0.2,1., 0.2,-0.3,1., -0.3,-0.3,0., 0.2,-0.3,0., 0.7,-0.3,0., -0.3,0.2,0., 0.2,0.2,0., 0.7,0.2,0., -0.3,0.7,0., 0.2,0.7,0., 0.7,0.7,0., 0.7, -0.3, 0.0, 1.2, -0.3, 0.0, 1.7, -0.3, 0.0, 0.7, 0.2, 0.0, 1.2, 0.2, 0.0, 1.7, 0.2, 0.0, 0.7, 0.7, 0.0, 1.2, 0.7, 0.0, 1.7, 0.7, 0.0}; - CPPUNIT_ASSERT(std::equal(expected2,expected2+9,mesh3D_4->getNodalConnectivity()->getConstPointer())); - CPPUNIT_ASSERT(std::equal(expected3,expected3+23,mesh2D_4->getNodalConnectivity()->getConstPointer())); - CPPUNIT_ASSERT(std::equal(expected4,expected4+23,mesh2D_5->getNodalConnectivity()->getConstPointer())); - for(int i=0;i<78;i++) - CPPUNIT_ASSERT_DOUBLES_EQUAL(expected5[i],mesh3D_4->getCoords()->getIJ(0,i),1e-12); - // - MEDCouplingUMesh::MergeNodesOnUMeshesSharingSameCoords(meshes,1e-12); - mesh3D_4->checkCoherency(); mesh2D_4->checkCoherency(); mesh2D_5->checkCoherency(); - CPPUNIT_ASSERT(mesh3D_4->getCoords()==mesh2D_4->getCoords()); - CPPUNIT_ASSERT(mesh2D_4->getCoords()==mesh2D_5->getCoords()); - CPPUNIT_ASSERT_EQUAL(19,mesh3D_4->getNumberOfNodes()); - CPPUNIT_ASSERT_EQUAL(3,mesh3D_4->getSpaceDimension()); - CPPUNIT_ASSERT_EQUAL(9,mesh3D_4->getNodalConnectivity()->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(23,mesh2D_4->getNodalConnectivity()->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(23,mesh2D_5->getNodalConnectivity()->getNumberOfTuples()); - const int expected6[9]={18,0,1,2,3,4,5,6,7}; - const int expected7[23]={3,3,2,8, 3,2,9,8, 4,0,1,2,3, 4,10,11,2,1, 4,11,12,9,2}; - const int expected8[23]={3,13,15,14, 3,15,16,14, 4,8,9,15,13, 4,12,17,15,9, 4,17,18,16,15}; - const double expected9[57]={-0.3, -0.3, 0., -0.3, 0.2, 0., 0.2, 0.2, 0., 0.2, -0.3, 0., -0.3, -0.3, 1., -0.3, 0.2, 1., - 0.2, 0.2, 1., 0.2, -0.3, 1., 0.7, -0.3, 0., 0.7, 0.2, 0., -0.3, 0.7, 0., 0.2, 0.7, 0., - 0.7, 0.7, 0., 1.2, -0.3, 0., 1.7, -0.3, 0., 1.2, 0.2, 0., 1.7, 0.2, 0., 1.2, 0.7, 0., 1.7, 0.7, 0.}; - CPPUNIT_ASSERT(std::equal(expected6,expected6+9,mesh3D_4->getNodalConnectivity()->getConstPointer())); - CPPUNIT_ASSERT(std::equal(expected7,expected7+23,mesh2D_4->getNodalConnectivity()->getConstPointer())); - CPPUNIT_ASSERT(std::equal(expected8,expected8+23,mesh2D_5->getNodalConnectivity()->getConstPointer())); - for(int i=0;i<57;i++) - CPPUNIT_ASSERT_DOUBLES_EQUAL(expected9[i],mesh3D_4->getCoords()->getIJ(0,i),1e-12); - mesh2D_5->decrRef(); - // - mesh3D_4->decrRef(); - mesh2D_4->decrRef(); - mesh3D_2->decrRef(); - mesh2D_2->decrRef(); - // - mesh3D->decrRef(); - mesh2D->decrRef(); -} - -void MEDCouplingBasicsTest5::testComputeNeighborsOfCells1() -{ - MEDCouplingUMesh *m=build2DTargetMesh_1(); - DataArrayInt *d1=0,*d2=0; - m->computeNeighborsOfCells(d1,d2); - CPPUNIT_ASSERT_EQUAL(6,d2->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(10,d1->getNumberOfTuples()); - const int expected1[6]={0,2,4,6,8,10}; - const int expected2[10]={3,1,0,2,4,1,4,0,2,3}; - CPPUNIT_ASSERT(std::equal(expected1,expected1+6,d2->getConstPointer())); - CPPUNIT_ASSERT(std::equal(expected2,expected2+10,d1->getConstPointer())); - d1->decrRef(); - d2->decrRef(); - m->decrRef(); -} - -void MEDCouplingBasicsTest5::testCheckButterflyCellsBug1() -{ - double mesh2DCoords[10]={323.85,120.983748908684,317.5,131.982271536747,336.55,120.983748908686,330.2,131.982271536751,323.85,142.98079416481}; - int mesh2DConn[5]={4,1,0,2,3}; - MEDCouplingUMesh *mesh2D=MEDCouplingUMesh::New("mesh",2); - mesh2D->allocateCells(1); - mesh2D->insertNextCell(INTERP_KERNEL::NORM_POLYGON,5,mesh2DConn); - mesh2D->finishInsertingCells(); - DataArrayDouble *myCoords=DataArrayDouble::New(); - myCoords->alloc(5,2); - std::copy(mesh2DCoords,mesh2DCoords+10,myCoords->getPointer()); - mesh2D->setCoords(myCoords); - myCoords->decrRef(); - mesh2D->checkCoherency(); - // - std::vector v; - mesh2D->checkButterflyCells(v); - CPPUNIT_ASSERT_EQUAL(0,(int)v.size()); - // - mesh2D->decrRef(); -} - -void MEDCouplingBasicsTest5::testDataArrayIntRange1() -{ - DataArrayInt *d=DataArrayInt::Range(2,17,7); - const int expected1[3]={2,9,16}; - CPPUNIT_ASSERT_EQUAL(3,d->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(1,d->getNumberOfComponents()); - CPPUNIT_ASSERT(std::equal(expected1,expected1+3,d->getConstPointer())); - d->decrRef(); - // - d=DataArrayInt::Range(2,23,7); - CPPUNIT_ASSERT_EQUAL(3,d->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(1,d->getNumberOfComponents()); - CPPUNIT_ASSERT(std::equal(expected1,expected1+3,d->getConstPointer())); - d->decrRef(); - // - d=DataArrayInt::Range(2,24,7); - const int expected2[4]={2,9,16,23}; - CPPUNIT_ASSERT_EQUAL(4,d->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(1,d->getNumberOfComponents()); - CPPUNIT_ASSERT(std::equal(expected2,expected2+4,d->getConstPointer())); - d->decrRef(); - // - d=DataArrayInt::Range(24,2,-7); - const int expected3[4]={24,17,10,3}; - CPPUNIT_ASSERT_EQUAL(4,d->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(1,d->getNumberOfComponents()); - CPPUNIT_ASSERT(std::equal(expected3,expected3+4,d->getConstPointer())); - d->decrRef(); - // - d=DataArrayInt::Range(23,2,-7); - const int expected4[3]={23,16,9}; - CPPUNIT_ASSERT_EQUAL(3,d->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(1,d->getNumberOfComponents()); - CPPUNIT_ASSERT(std::equal(expected4,expected4+3,d->getConstPointer())); - d->decrRef(); - // - d=DataArrayInt::Range(23,22,-7); - CPPUNIT_ASSERT_EQUAL(1,d->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(1,d->getNumberOfComponents()); - CPPUNIT_ASSERT_EQUAL(23,d->getIJ(0,0)); - d->decrRef(); - // - d=DataArrayInt::Range(22,23,7); - CPPUNIT_ASSERT_EQUAL(1,d->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(1,d->getNumberOfComponents()); - CPPUNIT_ASSERT_EQUAL(22,d->getIJ(0,0)); - d->decrRef(); - // - d=DataArrayInt::Range(22,22,7); - CPPUNIT_ASSERT_EQUAL(0,d->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(1,d->getNumberOfComponents()); - d->decrRef(); - // - d=DataArrayInt::Range(22,22,-7); - CPPUNIT_ASSERT_EQUAL(0,d->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(1,d->getNumberOfComponents()); - d->decrRef(); - // - CPPUNIT_ASSERT_THROW(DataArrayInt::Range(22,23,-7),INTERP_KERNEL::Exception); - CPPUNIT_ASSERT_THROW(DataArrayInt::Range(23,22,7),INTERP_KERNEL::Exception); - CPPUNIT_ASSERT_THROW(DataArrayInt::Range(23,22,0),INTERP_KERNEL::Exception); - CPPUNIT_ASSERT_THROW(DataArrayInt::Range(22,23,0),INTERP_KERNEL::Exception); -} - -void MEDCouplingBasicsTest5::testDataArrayDoubleGetMinMaxPerComponent1() -{ - const double values1[12]={1.,2.,3.,-0.9,2.1,3.,1.3,1.7,3.,1.,1.8,3.}; - DataArrayDouble *d1=DataArrayDouble::New(); - double *res=new double[2*3]; - CPPUNIT_ASSERT_THROW(d1->getMinMaxPerComponent(res),INTERP_KERNEL::Exception); - d1->alloc(4,3); - std::copy(values1,values1+12,d1->getPointer()); - d1->getMinMaxPerComponent(res); - const double expected1[6]={-0.9,1.3,1.7,2.1,3.,3.}; - for(int i=0;i<6;i++) - CPPUNIT_ASSERT_DOUBLES_EQUAL(expected1[i],res[i],1e-14); - delete [] res; - // - d1->rearrange(2); - res=new double[2*2]; - d1->getMinMaxPerComponent(res); - const double expected2[4]={1.,3.,-0.9,3.}; - for(int i=0;i<4;i++) - CPPUNIT_ASSERT_DOUBLES_EQUAL(expected2[i],res[i],1e-14); - delete [] res; - // - d1->rearrange(1); - res=new double[2*1]; - d1->getMinMaxPerComponent(res); - const double expected3[2]={-0.9,3.}; - for(int i=0;i<2;i++) - CPPUNIT_ASSERT_DOUBLES_EQUAL(expected3[i],res[i],1e-14); - delete [] res; - d1->decrRef(); -} - -void MEDCouplingBasicsTest5::testDataArrayIntGetHashCode1() -{ - DataArrayInt *d1=DataArrayInt::New(); d1->alloc(3545,1); d1->iota(0); - DataArrayInt *d2=DataArrayInt::New(); d2->alloc(3545,1); d2->iota(0); - // - CPPUNIT_ASSERT_EQUAL(d1->getHashCode(),d2->getHashCode()); - CPPUNIT_ASSERT_EQUAL(232341068,d1->getHashCode()); - d1->setIJ(886,0,6); - CPPUNIT_ASSERT_EQUAL(232340188,d1->getHashCode()); - // - d1->decrRef(); - d2->decrRef(); -} - -void MEDCouplingBasicsTest5::testZipConnectivityPol1() -{ - MEDCouplingUMesh *m1=build2DTargetMesh_1(); - const int cells1[3]={2,3,4}; - MEDCouplingPointSet *m2_1=m1->buildPartOfMySelf(cells1,cells1+3,true); - MEDCouplingUMesh *m2=dynamic_cast(m2_1); - DataArrayInt *arr=0; - CPPUNIT_ASSERT(m2); - // no permutation policy 0 - CPPUNIT_ASSERT(m1->areCellsIncludedIn(m2,0,arr)); - CPPUNIT_ASSERT_EQUAL(3,arr->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(1,arr->getNumberOfComponents()); - CPPUNIT_ASSERT(std::equal(cells1,cells1+3,arr->getConstPointer())); - arr->decrRef(); - // no permutation policy 1 - CPPUNIT_ASSERT(m1->areCellsIncludedIn(m2,1,arr)); - CPPUNIT_ASSERT_EQUAL(3,arr->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(1,arr->getNumberOfComponents()); - CPPUNIT_ASSERT(std::equal(cells1,cells1+3,arr->getConstPointer())); - arr->decrRef(); - // no permutation policy 2 - CPPUNIT_ASSERT(m1->areCellsIncludedIn(m2,2,arr)); - CPPUNIT_ASSERT_EQUAL(3,arr->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(1,arr->getNumberOfComponents()); - CPPUNIT_ASSERT(std::equal(cells1,cells1+3,arr->getConstPointer())); - arr->decrRef(); - // some modification into m2 - const int modif1[3]={2,4,5}; - std::copy(modif1,modif1+3,m2->getNodalConnectivity()->getPointer()+1); - //policy 0 fails because cell0 in m2 has same orientation be not same connectivity - const int expected1[3]={5,3,4}; - CPPUNIT_ASSERT(!m1->areCellsIncludedIn(m2,0,arr)); - CPPUNIT_ASSERT_EQUAL(3,arr->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(1,arr->getNumberOfComponents()); - CPPUNIT_ASSERT(std::equal(expected1,expected1+3,arr->getConstPointer())); - arr->decrRef(); - //policy 1 succeeds because cell0 in m2 has not exactly the same conn - CPPUNIT_ASSERT(m1->areCellsIncludedIn(m2,1,arr)); - CPPUNIT_ASSERT_EQUAL(3,arr->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(1,arr->getNumberOfComponents()); - CPPUNIT_ASSERT(std::equal(cells1,cells1+3,arr->getConstPointer())); - arr->decrRef(); - //policy 2 succeeds because cell0 in m2 has same nodes in connectivity - CPPUNIT_ASSERT(m1->areCellsIncludedIn(m2,2,arr)); - CPPUNIT_ASSERT_EQUAL(3,arr->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(1,arr->getNumberOfComponents()); - CPPUNIT_ASSERT(std::equal(cells1,cells1+3,arr->getConstPointer())); - arr->decrRef(); - //some new modification into m2 - const int modif2[3]={2,5,4}; - std::copy(modif2,modif2+3,m2->getNodalConnectivity()->getPointer()+1); - //policy 0 fails because cell0 in m2 has not exactly the same conn - CPPUNIT_ASSERT(!m1->areCellsIncludedIn(m2,0,arr)); - CPPUNIT_ASSERT_EQUAL(3,arr->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(1,arr->getNumberOfComponents()); - CPPUNIT_ASSERT(std::equal(expected1,expected1+3,arr->getConstPointer())); - arr->decrRef(); - //policy 1 fails too because cell0 in m2 has not same orientation - CPPUNIT_ASSERT(!m1->areCellsIncludedIn(m2,1,arr)); - CPPUNIT_ASSERT_EQUAL(3,arr->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(1,arr->getNumberOfComponents()); - CPPUNIT_ASSERT(std::equal(expected1,expected1+3,arr->getConstPointer())); - arr->decrRef(); - //policy 2 succeeds because cell0 in m2 has same nodes in connectivity - CPPUNIT_ASSERT(m1->areCellsIncludedIn(m2,2,arr)); - CPPUNIT_ASSERT_EQUAL(3,arr->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(1,arr->getNumberOfComponents()); - CPPUNIT_ASSERT(std::equal(cells1,cells1+3,arr->getConstPointer())); - arr->decrRef(); - m1->decrRef(); - m2->decrRef(); - // Now 1D - const int cells2[2]={3,2}; - m1=build1DSourceMesh_2(); - m2_1=m1->buildPartOfMySelf(cells2,cells2+2,true); - m2=dynamic_cast(m2_1); - CPPUNIT_ASSERT(m2); - arr=0; - // no permutation policy 0 - CPPUNIT_ASSERT(m1->areCellsIncludedIn(m2,0,arr)); - CPPUNIT_ASSERT_EQUAL(2,arr->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(1,arr->getNumberOfComponents()); - CPPUNIT_ASSERT(std::equal(cells2,cells2+2,arr->getConstPointer())); - arr->decrRef(); - // no permutation policy 1 - CPPUNIT_ASSERT(m1->areCellsIncludedIn(m2,1,arr)); - CPPUNIT_ASSERT_EQUAL(2,arr->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(1,arr->getNumberOfComponents()); - CPPUNIT_ASSERT(std::equal(cells2,cells2+2,arr->getConstPointer())); - arr->decrRef(); - // no permutation policy 2 - CPPUNIT_ASSERT(m1->areCellsIncludedIn(m2,2,arr)); - CPPUNIT_ASSERT_EQUAL(2,arr->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(1,arr->getNumberOfComponents()); - CPPUNIT_ASSERT(std::equal(cells2,cells2+2,arr->getConstPointer())); - arr->decrRef(); - // some modification into m2 - const int modif3[2]={4,3}; - std::copy(modif3,modif3+2,m2->getNodalConnectivity()->getPointer()+1); - //policy 0 fails because cell0 in m2 has not exactly the same conn - const int expected2[2]={4,2}; - CPPUNIT_ASSERT(!m1->areCellsIncludedIn(m2,0,arr)); - CPPUNIT_ASSERT_EQUAL(2,arr->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(1,arr->getNumberOfComponents()); - CPPUNIT_ASSERT(std::equal(expected2,expected2+2,arr->getConstPointer())); - arr->decrRef(); - //policy 1 fails too because cell0 in m2 has not same orientation - CPPUNIT_ASSERT(!m1->areCellsIncludedIn(m2,1,arr)); - CPPUNIT_ASSERT_EQUAL(2,arr->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(1,arr->getNumberOfComponents()); - CPPUNIT_ASSERT(std::equal(expected2,expected2+2,arr->getConstPointer())); - arr->decrRef(); - //policy 2 succeeds because cell0 in m2 has same nodes in connectivity - CPPUNIT_ASSERT(m1->areCellsIncludedIn(m2,2,arr)); - CPPUNIT_ASSERT_EQUAL(2,arr->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(1,arr->getNumberOfComponents()); - CPPUNIT_ASSERT(std::equal(cells2,cells2+2,arr->getConstPointer())); - arr->decrRef(); - m1->decrRef(); - m2->decrRef(); -} - -void MEDCouplingBasicsTest5::testConvexEnvelop2D1() -{ - const double coords[662]={7.54758495819e-14,-1.12270326253e-12,8.43143594193,-1.02835845055e-12,4.21571797096,7.30183771609,-4.21571797097,7.30183771609,-8.43143594193,-1.09439981894e-12,-4.21571797097,-7.30183771609,4.21571797097,-7.30183771609,16.8628718839,-1.02835845055e-12,12.6471539129,7.30183771609,8.43143594193,14.6036754322,2.26427548746e-13,14.6036754322,-8.43143594193,14.6036754322,-12.6471539129,7.30183771609,-16.8628718839,-1.39630321727e-12,-12.6471539129,-7.30183771609,-8.43143594193,-14.6036754322,3.7737924791e-14,-14.6036754322,8.43143594193,-14.6036754322,12.6471539129,-7.30183771609,25.2943078258,-1.07553085654e-12,21.0785898548,7.30183771609,16.8628718839,14.6036754322,12.6471539129,21.9055131483,4.21571797096,21.9055131483,-4.21571797097,21.9055131483,-12.6471539129,21.9055131483,-16.8628718839,14.6036754322,-21.0785898548,7.30183771609,-25.2943078258,-1.02835845055e-12,-21.0785898548,-7.30183771609,-16.8628718839,-14.6036754322,-12.6471539129,-21.9055131483,-4.21571797097,-21.9055131483,4.21571797097,-21.9055131483,12.6471539129,-21.9055131483,16.8628718839,-14.6036754322,21.0785898548,-7.30183771609,33.7257437677,-7.45324014622e-13,29.5100257968,7.30183771609,25.2943078258,14.6036754322,21.0785898548,21.9055131483,16.8628718839,29.2073508644,8.43143594193,29.2073508644,-1.20761359331e-12,29.2073508644,-8.43143594193,29.2073508644,-16.8628718839,29.2073508644,-21.0785898548,21.9055131483,-25.2943078258,14.6036754322,-29.5100257968,7.30183771609,-33.7257437677,-7.26455052226e-13,-29.5100257968,-7.30183771609,-25.2943078258,-14.6036754322,-21.0785898548,-21.9055131483,-16.8628718839,-29.2073508644,-8.43143594193,-29.2073508644,4.15117172701e-13,-29.2073508644,8.43143594193,-29.2073508644,16.8628718839,-29.2073508644,21.0785898548,-21.9055131483,25.2943078258,-14.6036754322,29.5100257968,-7.30183771609,42.1571797097,-1.86802727715e-12,37.9414617387,7.30183771609,33.7257437677,14.6036754322,29.5100257968,21.9055131483,25.2943078258,29.2073508644,21.0785898548,36.5091885805,12.6471539129,36.5091885805,4.21571797096,36.5091885805,-4.21571797096,36.5091885805,-12.6471539129,36.5091885805,-21.0785898548,36.5091885805,-25.2943078258,29.2073508644,-29.5100257968,21.9055131483,-33.7257437677,14.6036754322,-37.9414617387,7.30183771609,-42.1571797097,-9.81186044565e-13,-37.9414617387,-7.30183771609,-33.7257437677,-14.6036754322,-29.5100257968,-21.9055131483,-25.2943078258,-29.2073508644,-21.0785898548,-36.5091885805,-12.6471539129,-36.5091885805,-4.21571797097,-36.5091885805,4.21571797097,-36.5091885805,12.6471539129,-36.5091885805,21.0785898548,-36.5091885805,25.2943078258,-29.2073508644,29.5100257968,-21.9055131483,33.7257437677,-14.6036754322,37.9414617387,-7.30183771609,50.5886156516,-6.98151608633e-13,46.3728976806,7.30183771609,42.1571797097,14.6036754322,37.9414617387,21.9055131483,33.7257437677,29.2073508644,29.5100257968,36.5091885805,25.2943078258,43.8110262966,16.8628718839,43.8110262966,8.43143594193,43.8110262966,-1.84915831476e-12,43.8110262966,-8.43143594193,43.8110262966,-16.8628718839,43.8110262966,-25.2943078258,43.8110262966,-29.5100257968,36.5091885805,-33.7257437677,29.2073508644,-37.9414617387,21.9055131483,-42.1571797097,14.6036754322,-46.3728976806,7.30183771609,-50.5886156516,-1.47177906685e-12,-46.3728976806,-7.30183771609,-42.1571797097,-14.6036754322,-37.9414617387,-21.9055131483,-33.7257437677,-29.2073508644,-29.5100257968,-36.5091885805,-25.2943078258,-43.8110262966,-16.8628718839,-43.8110262966,-8.43143594193,-43.8110262966,7.54758495819e-14,-43.8110262966,8.43143594193,-43.8110262966,16.8628718839,-43.8110262966,25.2943078258,-43.8110262966,29.5100257968,-36.5091885805,33.7257437677,-29.2073508644,37.9414617387,-21.9055131483,42.1571797097,-14.6036754322,46.3728976806,-7.30183771609,59.0200515935,-7.9249642061e-13,54.8043336225,7.30183771609,50.5886156516,14.6036754322,46.3728976806,21.9055131483,42.1571797097,29.2073508644,37.9414617387,36.5091885805,33.7257437677,43.8110262966,29.5100257968,51.1128640127,21.0785898548,51.1128640127,12.6471539129,51.1128640127,4.21571797096,51.1128640127,-4.21571797096,51.1128640127,-12.6471539129,51.1128640127,-21.0785898548,51.1128640127,-29.5100257968,51.1128640127,-33.7257437677,43.8110262966,-37.9414617387,36.5091885805,-42.1571797097,29.2073508644,-46.3728976806,21.9055131483,-50.5886156516,14.6036754322,-54.8043336226,7.30183771609,-59.0200515935,-1.31139288649e-12,-54.8043336226,-7.30183771609,-50.5886156516,-14.6036754322,-46.3728976806,-21.9055131483,-42.1571797097,-29.2073508644,-37.9414617387,-36.5091885805,-33.7257437677,-43.8110262966,-29.5100257968,-51.1128640127,-21.0785898548,-51.1128640127,-12.6471539129,-51.1128640127,-4.21571797097,-51.1128640127,4.21571797097,-51.1128640127,12.6471539129,-51.1128640127,21.0785898548,-51.1128640127,29.5100257968,-51.1128640127,33.7257437677,-43.8110262966,37.9414617387,-36.5091885805,42.1571797097,-29.2073508644,46.3728976806,-21.9055131483,50.5886156516,-14.6036754322,54.8043336225,-7.30183771609,67.4514875354,-2.14162723189e-12,63.2357695645,7.30183771609,59.0200515935,14.6036754322,54.8043336226,21.9055131483,50.5886156516,29.2073508644,46.3728976806,36.5091885805,42.1571797097,43.8110262966,37.9414617387,51.1128640127,33.7257437677,58.4147017287,25.2943078258,58.4147017287,16.8628718839,58.4147017287,8.43143594193,58.4147017287,6.79282646237e-13,58.4147017287,-8.43143594193,58.4147017287,-16.8628718839,58.4147017287,-25.2943078258,58.4147017287,-33.7257437677,58.4147017287,-37.9414617387,51.1128640127,-42.1571797097,43.8110262966,-46.3728976806,36.5091885805,-50.5886156516,29.2073508644,-54.8043336226,21.9055131483,-59.0200515935,14.6036754322,-63.2357695645,7.30183771609,-67.4514875354,-1.16044118732e-12,-63.2357695645,-7.30183771609,-59.0200515935,-14.6036754322,-54.8043336226,-21.9055131483,-50.5886156516,-29.2073508644,-46.3728976806,-36.5091885805,-42.1571797097,-43.8110262966,-37.9414617387,-51.1128640127,-33.7257437677,-58.4147017287,-25.2943078258,-58.4147017287,-16.8628718839,-58.4147017287,-8.43143594193,-58.4147017287,-5.66068871864e-14,-58.4147017287,8.43143594193,-58.4147017287,16.8628718839,-58.4147017287,25.2943078258,-58.4147017287,33.7257437677,-58.4147017287,37.9414617387,-51.1128640127,42.1571797097,-43.8110262966,46.3728976806,-36.5091885805,50.5886156516,-29.2073508644,54.8043336226,-21.9055131483,59.0200515935,-14.6036754322,63.2357695645,-7.30183771609,75.8829234774,-2.29257893105e-12,71.6672055064,7.30183771609,67.4514875354,14.6036754322,63.2357695645,21.9055131483,59.0200515935,29.2073508644,54.8043336226,36.5091885805,50.5886156516,43.8110262966,46.3728976806,51.1128640127,42.1571797097,58.4147017287,37.9414617387,65.7165394448,29.5100257968,65.7165394448,21.0785898548,65.7165394448,12.6471539129,65.7165394448,4.21571797097,65.7165394448,-4.21571797096,65.7165394448,-12.6471539129,65.7165394448,-21.0785898548,65.7165394448,-29.5100257968,65.7165394448,-37.9414617387,65.7165394448,-42.1571797097,58.4147017287,-46.3728976806,51.1128640127,-50.5886156516,43.8110262966,-54.8043336226,36.5091885805,-59.0200515935,29.2073508644,-63.2357695645,21.9055131483,-67.4514875354,14.6036754322,-71.6672055064,7.30183771609,-75.8829234774,-1.31139288649e-12,-71.6672055064,-7.30183771609,-67.4514875354,-14.6036754322,-63.2357695645,-21.9055131483,-59.0200515935,-29.2073508644,-54.8043336226,-36.5091885805,-50.5886156516,-43.8110262966,-46.3728976806,-51.1128640127,-42.1571797097,-58.4147017287,-37.9414617387,-65.7165394448,-29.5100257968,-65.7165394448,-21.0785898548,-65.7165394448,-12.6471539129,-65.7165394448,-4.21571797097,-65.7165394448,4.21571797097,-65.7165394448,12.6471539129,-65.7165394448,21.0785898548,-65.7165394448,29.5100257968,-65.7165394448,37.9414617387,-65.7165394448,42.1571797097,-58.4147017287,46.3728976806,-51.1128640127,50.5886156516,-43.8110262966,54.8043336226,-36.5091885805,59.0200515935,-29.2073508644,63.2357695645,-21.9055131483,67.4514875354,-14.6036754322,71.6672055064,-7.30183771609,84.3143594193,-1.49064802924e-12,80.0986414483,7.30183771609,75.8829234774,14.6036754322,71.6672055064,21.9055131483,67.4514875354,29.2073508644,63.2357695645,36.5091885805,59.0200515935,43.8110262966,54.8043336226,51.1128640127,50.5886156516,58.4147017287,46.3728976806,65.7165394448,42.1571797097,73.0183771609,33.7257437677,73.0183771609,25.2943078258,73.0183771609,16.8628718839,73.0183771609,8.43143594193,73.0183771609,2.0755858635e-12,73.0183771609,-8.43143594193,73.0183771609,-16.8628718839,73.0183771609,-25.2943078258,73.0183771609,-33.7257437677,73.0183771609,-42.1571797097,73.0183771609,-46.3728976806,65.7165394448,-50.5886156516,58.4147017287,-54.8043336226,51.1128640127,-59.0200515935,43.8110262966,-63.2357695645,36.5091885805,-67.4514875354,29.2073508644,-71.6672055064,21.9055131483,-75.8829234774,14.6036754322,-80.0986414483,7.30183771609,-84.3143594193,-1.11326878133e-12,-80.0986414483,-7.30183771609,-75.8829234774,-14.6036754322,-71.6672055064,-21.9055131483,-67.4514875354,-29.2073508644,-63.2357695645,-36.5091885805,-59.0200515935,-43.8110262966,-54.8043336226,-51.1128640127,-50.5886156516,-58.4147017287,-46.3728976806,-65.7165394448,-42.1571797097,-73.0183771609,-33.7257437677,-73.0183771609,-25.2943078258,-73.0183771609,-16.8628718839,-73.0183771609,-8.43143594193,-73.0183771609,-5.66068871864e-14,-73.0183771609,8.43143594193,-73.0183771609,16.8628718839,-73.0183771609,25.2943078258,-73.0183771609,33.7257437677,-73.0183771609,42.1571797097,-73.0183771609,46.3728976806,-65.7165394448,50.5886156516,-58.4147017287,54.8043336226,-51.1128640127,59.0200515935,-43.8110262966,63.2357695645,-36.5091885805,67.4514875354,-29.2073508644,71.6672055064,-21.9055131483,75.8829234774,-14.6036754322,80.0986414483,-7.3018377161}; - const int conn[2137]={0,2,3,4,5,6,1,1,8,2,0,6,18,7,2,9,10,3,0,1,8,3,10,11,12,4,0,2,4,3,12,13,14,5,0,5,0,4,14,15,16,6,6,1,0,5,16,17,18,7,20,8,1,18,36,19,8,21,9,2,1,7,20,9,22,23,10,2,8,21,10,23,24,11,3,2,9,11,24,25,26,12,3,10,12,11,26,27,13,4,3,13,12,27,28,29,14,4,14,4,13,29,30,15,5,15,5,14,30,31,32,16,16,6,5,15,32,33,17,17,18,6,16,33,34,35,18,7,1,6,17,35,36,19,38,20,7,36,60,37,20,39,21,8,7,19,38,21,40,22,9,8,20,39,22,41,42,23,9,21,40,23,42,43,24,10,9,22,24,43,44,25,11,10,23,25,44,45,46,26,11,24,26,25,46,47,27,12,11,27,26,47,48,28,13,12,28,27,48,49,50,29,13,29,13,28,50,51,30,14,30,14,29,51,52,31,15,31,15,30,52,53,54,32,32,16,15,31,54,55,33,33,17,16,32,55,56,34,34,35,17,33,56,57,58,35,36,18,17,34,58,59,36,19,7,18,35,59,60,37,62,38,19,60,90,61,38,63,39,20,19,37,62,39,64,40,21,20,38,63,40,65,41,22,21,39,64,41,66,67,42,22,40,65,42,67,68,43,23,22,41,43,68,69,44,24,23,42,44,69,70,45,25,24,43,45,70,71,72,46,25,44,46,45,72,73,47,26,25,47,46,73,74,48,27,26,48,47,74,75,49,28,27,49,48,75,76,77,50,28,50,28,49,77,78,51,29,51,29,50,78,79,52,30,52,30,51,79,80,53,31,53,31,52,80,81,82,54,54,32,31,53,82,83,55,55,33,32,54,83,84,56,56,34,33,55,84,85,57,57,58,34,56,85,86,87,58,59,35,34,57,87,88,59,60,36,35,58,88,89,60,37,19,36,59,89,90,61,92,62,37,90,126,91,62,93,63,38,37,61,92,63,94,64,39,38,62,93,64,95,65,40,39,63,94,65,96,66,41,40,64,95,66,97,98,67,41,65,96,67,98,99,68,42,41,66,68,99,100,69,43,42,67,69,100,101,70,44,43,68,70,101,102,71,45,44,69,71,102,103,104,72,45,70,72,71,104,105,73,46,45,73,72,105,106,74,47,46,74,73,106,107,75,48,47,75,74,107,108,76,49,48,76,75,108,109,110,77,49,77,49,76,110,111,78,50,78,50,77,111,112,79,51,79,51,78,112,113,80,52,80,52,79,113,114,81,53,81,53,80,114,115,116,82,82,54,53,81,116,117,83,83,55,54,82,117,118,84,84,56,55,83,118,119,85,85,57,56,84,119,120,86,86,87,57,85,120,121,122,87,88,58,57,86,122,123,88,89,59,58,87,123,124,89,90,60,59,88,124,125,90,61,37,60,89,125,126,91,128,92,61,126,168,127,92,129,93,62,61,91,128,93,130,94,63,62,92,129,94,131,95,64,63,93,130,95,132,96,65,64,94,131,96,133,97,66,65,95,132,97,134,135,98,66,96,133,98,135,136,99,67,66,97,99,136,137,100,68,67,98,100,137,138,101,69,68,99,101,138,139,102,70,69,100,102,139,140,103,71,70,101,103,140,141,142,104,71,102,104,103,142,143,105,72,71,105,104,143,144,106,73,72,106,105,144,145,107,74,73,107,106,145,146,108,75,74,108,107,146,147,109,76,75,109,108,147,148,149,110,76,110,76,109,149,150,111,77,111,77,110,150,151,112,78,112,78,111,151,152,113,79,113,79,112,152,153,114,80,114,80,113,153,154,115,81,115,81,114,154,155,156,116,116,82,81,115,156,157,117,117,83,82,116,157,158,118,118,84,83,117,158,159,119,119,85,84,118,159,160,120,120,86,85,119,160,161,121,121,122,86,120,161,162,163,122,123,87,86,121,163,164,123,124,88,87,122,164,165,124,125,89,88,123,165,166,125,126,90,89,124,166,167,126,91,61,90,125,167,168,127,170,128,91,168,216,169,128,171,129,92,91,127,170,129,172,130,93,92,128,171,130,173,131,94,93,129,172,131,174,132,95,94,130,173,132,175,133,96,95,131,174,133,176,134,97,96,132,175,134,177,178,135,97,133,176,135,178,179,136,98,97,134,136,179,180,137,99,98,135,137,180,181,138,100,99,136,138,181,182,139,101,100,137,139,182,183,140,102,101,138,140,183,184,141,103,102,139,141,184,185,186,142,103,140,142,141,186,187,143,104,103,143,142,187,188,144,105,104,144,143,188,189,145,106,105,145,144,189,190,146,107,106,146,145,190,191,147,108,107,147,146,191,192,148,109,108,148,147,192,193,194,149,109,149,109,148,194,195,150,110,150,110,149,195,196,151,111,151,111,150,196,197,152,112,152,112,151,197,198,153,113,153,113,152,198,199,154,114,154,114,153,199,200,155,115,155,115,154,200,201,202,156,156,116,115,155,202,203,157,157,117,116,156,203,204,158,158,118,117,157,204,205,159,159,119,118,158,205,206,160,160,120,119,159,206,207,161,161,121,120,160,207,208,162,162,163,121,161,208,209,210,163,164,122,121,162,210,211,164,165,123,122,163,211,212,165,166,124,123,164,212,213,166,167,125,124,165,213,214,167,168,126,125,166,214,215,168,127,91,126,167,215,216,169,218,170,127,216,270,217,170,219,171,128,127,169,218,171,220,172,129,128,170,219,172,221,173,130,129,171,220,173,222,174,131,130,172,221,174,223,175,132,131,173,222,175,224,176,133,132,174,223,176,225,177,134,133,175,224,177,226,227,178,134,176,225,178,227,228,179,135,134,177,179,228,229,180,136,135,178,180,229,230,181,137,136,179,181,230,231,182,138,137,180,182,231,232,183,139,138,181,183,232,233,184,140,139,182,184,233,234,185,141,140,183,185,234,235,236,186,141,184,186,185,236,237,187,142,141,187,186,237,238,188,143,142,188,187,238,239,189,144,143,189,188,239,240,190,145,144,190,189,240,241,191,146,145,191,190,241,242,192,147,146,192,191,242,243,193,148,147,193,192,243,244,245,194,148,194,148,193,245,246,195,149,195,149,194,246,247,196,150,196,150,195,247,248,197,151,197,151,196,248,249,198,152,198,152,197,249,250,199,153,199,153,198,250,251,200,154,200,154,199,251,252,201,155,201,155,200,252,253,254,202,202,156,155,201,254,255,203,203,157,156,202,255,256,204,204,158,157,203,256,257,205,205,159,158,204,257,258,206,206,160,159,205,258,259,207,207,161,160,206,259,260,208,208,162,161,207,260,261,209,209,210,162,208,261,262,263,210,211,163,162,209,263,264,211,212,164,163,210,264,265,212,213,165,164,211,265,266,213,214,166,165,212,266,267,214,215,167,166,213,267,268,215,216,168,167,214,268,269,216,169,127,168,215,269,270,217,272,218,169,270,330,271,218,273,219,170,169,217,272,219,274,220,171,170,218,273,220,275,221,172,171,219,274,221,276,222,173,172,220,275,222,277,223,174,173,221,276,223,278,224,175,174,222,277,224,279,225,176,175,223,278,225,280,226,177,176,224,279,226,281,282,227,177,225,280,227,282,283,228,178,177,226,228,283,284,229,179,178,227,229,284,285,230,180,179,228,230,285,286,231,181,180,229,231,286,287,232,182,181,230,232,287,288,233,183,182,231,233,288,289,234,184,183,232,234,289,290,235,185,184,233,235,290,291,292,236,185,234,236,235,292,293,237,186,185,237,236,293,294,238,187,186,238,237,294,295,239,188,187,239,238,295,296,240,189,188,240,239,296,297,241,190,189,241,240,297,298,242,191,190,242,241,298,299,243,192,191,243,242,299,300,244,193,192,244,243,300,301,302,245,193,245,193,244,302,303,246,194,246,194,245,303,304,247,195,247,195,246,304,305,248,196,248,196,247,305,306,249,197,249,197,248,306,307,250,198,250,198,249,307,308,251,199,251,199,250,308,309,252,200,252,200,251,309,310,253,201,253,201,252,310,311,312,254,254,202,201,253,312,313,255,255,203,202,254,313,314,256,256,204,203,255,314,315,257,257,205,204,256,315,316,258,258,206,205,257,316,317,259,259,207,206,258,317,318,260,260,208,207,259,318,319,261,261,209,208,260,319,320,262,262,263,209,261,320,321,322,263,264,210,209,262,322,323,264,265,211,210,263,323,324,265,266,212,211,264,324,325,266,267,213,212,265,325,326,267,268,214,213,266,326,327,268,269,215,214,267,327,328,269,270,216,215,268,328,329,270,217,169,216,269,329,330,271,272,217,330,273,218,217,271,274,219,218,272,275,220,219,273,276,221,220,274,277,222,221,275,278,223,222,276,279,224,223,277,280,225,224,278,281,226,225,279,281,282,226,280,283,227,226,281,284,228,227,282,285,229,228,283,286,230,229,284,287,231,230,285,288,232,231,286,289,233,232,287,290,234,233,288,291,235,234,289,291,292,235,290,291,293,236,235,292,294,237,236,293,295,238,237,294,296,239,238,295,297,240,239,296,298,241,240,297,299,242,241,298,300,243,242,299,301,244,243,301,300,302,244,244,301,303,245,245,302,304,246,246,303,305,247,247,304,306,248,248,305,307,249,249,306,308,250,250,307,309,251,251,308,310,252,252,309,311,253,311,253,310,312,254,253,311,313,255,254,312,314,256,255,313,315,257,256,314,316,258,257,315,317,259,258,316,318,260,259,317,319,261,260,318,320,262,261,319,321,321,322,262,320,323,263,262,321,324,264,263,322,325,265,264,323,326,266,265,324,327,267,266,325,328,268,267,326,329,269,268,327,330,270,269,328,271,217,270,329}; - const int connI[332]={0,7,14,21,28,35,42,49,56,63,70,77,84,91,98,105,112,119,126,133,140,147,154,161,168,175,182,189,196,203,210,217,224,231,238,245,252,259,266,273,280,287,294,301,308,315,322,329,336,343,350,357,364,371,378,385,392,399,406,413,420,427,434,441,448,455,462,469,476,483,490,497,504,511,518,525,532,539,546,553,560,567,574,581,588,595,602,609,616,623,630,637,644,651,658,665,672,679,686,693,700,707,714,721,728,735,742,749,756,763,770,777,784,791,798,805,812,819,826,833,840,847,854,861,868,875,882,889,896,903,910,917,924,931,938,945,952,959,966,973,980,987,994,1001,1008,1015,1022,1029,1036,1043,1050,1057,1064,1071,1078,1085,1092,1099,1106,1113,1120,1127,1134,1141,1148,1155,1162,1169,1176,1183,1190,1197,1204,1211,1218,1225,1232,1239,1246,1253,1260,1267,1274,1281,1288,1295,1302,1309,1316,1323,1330,1337,1344,1351,1358,1365,1372,1379,1386,1393,1400,1407,1414,1421,1428,1435,1442,1449,1456,1463,1470,1477,1484,1491,1498,1505,1512,1519,1526,1533,1540,1547,1554,1561,1568,1575,1582,1589,1596,1603,1610,1617,1624,1631,1638,1645,1652,1659,1666,1673,1680,1687,1694,1701,1708,1715,1722,1729,1736,1743,1750,1757,1764,1771,1778,1785,1792,1799,1806,1813,1820,1827,1834,1841,1848,1855,1862,1869,1876,1883,1890,1897,1901,1905,1909,1913,1917,1921,1925,1929,1933,1937,1941,1945,1949,1953,1957,1961,1965,1969,1973,1977,1981,1985,1989,1993,1997,2001,2005,2009,2013,2017,2021,2025,2029,2033,2037,2041,2045,2049,2053,2057,2061,2065,2069,2073,2077,2081,2085,2089,2093,2097,2101,2105,2109,2113,2117,2121,2125,2129,2133,2137}; - // - MEDCouplingUMesh *m=MEDCouplingUMesh::New("convexhull",2); - m->allocateCells(331); - for(int i=0;i<331;i++) - m->insertNextCell(INTERP_KERNEL::NORM_POLYGON,connI[i+1]-connI[i],conn+connI[i]); - m->finishInsertingCells(); - DataArrayDouble *coordsDa=DataArrayDouble::New(); - coordsDa->alloc(331,2); - std::copy(coords,coords+662,coordsDa->getPointer()); - m->setCoords(coordsDa); - coordsDa->decrRef(); - m->checkCoherency(); - // - DataArrayInt *da=m->convexEnvelop2D(); - m->checkCoherency(); - CPPUNIT_ASSERT(coordsDa==m->getCoords()); - DataArrayInt *daC=da->buildComplement(331); - da->decrRef(); - const int expected[58]={271,272,273,274,275,276,277,278,279,280,281,282,283,284,285,286,287,288,289,290,291,292,293,294,295,296,297,298,299,300,302,303,304,305,306,307,308,309,310,312,313,314,315,316,317,318,319,320,321,322,323,324,325,326,327,328,329,330}; - DataArrayInt *expected2=DataArrayInt::New(); - expected2->alloc(58,1); - std::copy(expected,expected+58,expected2->getPointer()); - CPPUNIT_ASSERT(expected2->isEqual(*daC)); - // - expected2->decrRef(); - daC->decrRef(); - // - MEDCouplingFieldDouble *valsF=m->getMeasureField(ON_CELLS); - DataArrayDouble *vals=valsF->getArray(); - const double ref[331]={184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,-61.564976961404426,-92.34746544254946,-92.34746544259811,-92.34746544253488,-92.3474654425349,-92.34746544180479,-92.34746544253493,-92.3474654419026,-92.34746544190256,-92.34746544253491,-61.564976961404426,-92.34746544254946,-92.34746544259811,-92.34746544253488,-92.3474654425349,-92.34746544180479,-92.34746544253493,-92.3474654419026,-92.34746544190256,-92.34746544253491,-61.564976961404426,-92.34746544254946,-92.34746544259811,-92.34746544253488,-92.3474654425349,-92.34746544180479,-92.34746544253493,-92.3474654419026,-92.34746544190256,-92.34746544253491,61.564976961404426,-92.34746544254946,-92.34746544259811,-92.34746544253488,-92.3474654425349,-92.34746544180479,-92.34746544253493,-92.3474654419026,-92.34746544190256,-92.34746544253491,61.564976961404426,-92.34746544254946,-92.34746544259811,-92.34746544253488,-92.3474654425349,-92.34746544180479,-92.34746544253493,-92.3474654419026,-92.34746544190256,-92.34746544253491,-61.564976961404426,-92.34746544254946,-92.34746544259811,-92.34746544253488,-92.3474654425349,-92.34746544180479,-92.34746544253493,-92.3474654419026,-92.34746544190256,-92.34746544253491}; - DataArrayDouble *ref2=DataArrayDouble::New(); ref2->alloc(331,1); std::copy(ref,ref+331,ref2->getPointer()); - vals->substractEqual(ref2); - ref2->decrRef(); - vals->abs(); - DataArrayInt *theTest=vals->getIdsInRange(-1.,1e-7); - CPPUNIT_ASSERT(theTest->isIdentity()); - CPPUNIT_ASSERT_EQUAL(331,theTest->getNumberOfTuples()); - theTest->decrRef(); - valsF->decrRef(); - // - m->decrRef(); -} - -void MEDCouplingBasicsTest5::testDataArraySort1() -{ - DataArrayInt *arr=DataArrayInt::New(); - CPPUNIT_ASSERT_THROW(arr->sort(true),INTERP_KERNEL::Exception);//no allocation - CPPUNIT_ASSERT_THROW(arr->sort(false),INTERP_KERNEL::Exception);//no allocation - const int values[6]={2,1,6,5,4,7}; - arr->alloc(3,2); - CPPUNIT_ASSERT_THROW(arr->sort(true),INTERP_KERNEL::Exception);//no one component - CPPUNIT_ASSERT_THROW(arr->sort(false),INTERP_KERNEL::Exception);//no one component - arr->rearrange(1); - std::copy(values,values+6,arr->getPointer()); - DataArrayInt *arr1=arr->deepCpy(); - DataArrayInt *arr2=arr->deepCpy(); - arr1->sort(true); - const int expected1[6]={1,2,4,5,6,7}; - CPPUNIT_ASSERT_EQUAL(6,arr1->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(1,arr1->getNumberOfComponents()); - CPPUNIT_ASSERT(std::equal(expected1,expected1+6,arr1->begin())); - arr2->sort(false); - const int expected2[6]={7,6,5,4,2,1}; - CPPUNIT_ASSERT_EQUAL(6,arr2->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(1,arr2->getNumberOfComponents()); - CPPUNIT_ASSERT(std::equal(expected2,expected2+6,arr2->begin())); - arr1->decrRef(); - arr2->decrRef(); - arr->decrRef(); - // - DataArrayDouble *ard=DataArrayDouble::New(); - CPPUNIT_ASSERT_THROW(ard->sort(true),INTERP_KERNEL::Exception);//no allocation - CPPUNIT_ASSERT_THROW(ard->sort(false),INTERP_KERNEL::Exception);//no allocation - const double valuesD[6]={2.,1.,6.,5.,4.,7.}; - ard->alloc(3,2); - CPPUNIT_ASSERT_THROW(ard->sort(true),INTERP_KERNEL::Exception);//no one component - CPPUNIT_ASSERT_THROW(ard->sort(false),INTERP_KERNEL::Exception);//no one component - ard->rearrange(1); - std::copy(valuesD,valuesD+6,ard->getPointer()); - DataArrayDouble *ard1=ard->deepCpy(); - DataArrayDouble *ard2=ard->deepCpy(); - ard1->sort(true); - const double expected3[6]={1.,2.,4.,5.,6.,7.}; - CPPUNIT_ASSERT_EQUAL(6,ard1->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(1,ard1->getNumberOfComponents()); - for(int i=0;i<6;i++) - CPPUNIT_ASSERT_DOUBLES_EQUAL(expected3[i],ard1->getIJ(i,0),1e-12); - ard2->sort(false); - const double expected4[6]={7.,6.,5.,4.,2.,1.}; - CPPUNIT_ASSERT_EQUAL(6,ard2->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(1,ard2->getNumberOfComponents()); - for(int i=0;i<6;i++) - CPPUNIT_ASSERT_DOUBLES_EQUAL(expected4[i],ard2->getIJ(i,0),1e-12); - ard1->decrRef(); - ard2->decrRef(); - ard->decrRef(); -} - -void MEDCouplingBasicsTest5::testPartitionBySpreadZone1() -{ - MEDCouplingUMesh *m=build2DTargetMesh_1(); - const int part0[3]={2,3,4}; - const int part1[2]={0,1}; - MEDCouplingUMesh *m1=static_cast(m->buildPartOfMySelf(part0,part0+3)); - MEDCouplingUMesh *m2=static_cast(m->buildPartOfMySelf(part1,part1+2)); - std::vector v(3); v[0]=m; v[1]=m1; v[2]=m2; - MEDCouplingUMesh *m4=MEDCouplingUMesh::MergeUMeshes(v); - const int renum[10]={5,2,9,6,4,7,0,1,3,8}; - m4->renumberCells(renum); - // - std::vector v2=m4->partitionBySpreadZone(); - CPPUNIT_ASSERT_EQUAL(3,(int)v2.size()); - const int expected0[3]={0,1,7}; - const int expected1[5]={2,4,5,6,9}; - const int expected2[2]={3,8}; - CPPUNIT_ASSERT_EQUAL(3,v2[0]->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(1,v2[0]->getNumberOfComponents()); - CPPUNIT_ASSERT_EQUAL(5,v2[1]->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(1,v2[1]->getNumberOfComponents()); - CPPUNIT_ASSERT_EQUAL(2,v2[2]->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(1,v2[2]->getNumberOfComponents()); - // - CPPUNIT_ASSERT(std::equal(expected0,expected0+3,v2[0]->getConstPointer())); - CPPUNIT_ASSERT(std::equal(expected1,expected1+5,v2[1]->getConstPointer())); - CPPUNIT_ASSERT(std::equal(expected2,expected2+2,v2[2]->getConstPointer())); - v2[0]->decrRef(); - v2[1]->decrRef(); - v2[2]->decrRef(); - // - MEDCouplingUMesh *m5=m4->buildSpreadZonesWithPoly(); - CPPUNIT_ASSERT_EQUAL(3,m5->getNumberOfCells()); - CPPUNIT_ASSERT(m5->getCoords()==m4->getCoords()); - const int expected3[23]={5,15,16,17,14,11,13,12,5,2,1,0,3,6,7,8,5,5,18,21,22,20,19}; - const int expected4[4]={0,8,17,23}; - CPPUNIT_ASSERT_EQUAL(23,m5->getNodalConnectivity()->getNumberOfTuples()); - CPPUNIT_ASSERT(std::equal(expected3,expected3+23,m5->getNodalConnectivity()->getConstPointer())); - CPPUNIT_ASSERT_EQUAL(4,m5->getNodalConnectivityIndex()->getNumberOfTuples()); - CPPUNIT_ASSERT(std::equal(expected4,expected4+4,m5->getNodalConnectivityIndex()->getConstPointer())); - // - m->decrRef(); - m1->decrRef(); - m2->decrRef(); - m4->decrRef(); - m5->decrRef(); -} - -void MEDCouplingBasicsTest5::testGiveCellsWithType1() -{ - const int expected0[2]={1,2}; - const int expected1[3]={0,3,4}; - MEDCouplingUMesh *m=build2DTargetMesh_1(); - DataArrayInt *da=m->giveCellsWithType(INTERP_KERNEL::NORM_TRI3); - CPPUNIT_ASSERT_EQUAL(2,da->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(1,da->getNumberOfComponents()); - CPPUNIT_ASSERT(std::equal(expected0,expected0+2,da->getConstPointer())); - da->decrRef(); - // - da=m->giveCellsWithType(INTERP_KERNEL::NORM_QUAD4); - CPPUNIT_ASSERT_EQUAL(3,da->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(1,da->getNumberOfComponents()); - CPPUNIT_ASSERT(std::equal(expected1,expected1+3,da->getConstPointer())); - da->decrRef(); - // - da=m->giveCellsWithType(INTERP_KERNEL::NORM_TRI6); - CPPUNIT_ASSERT_EQUAL(0,da->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(1,da->getNumberOfComponents()); - da->decrRef(); - // - CPPUNIT_ASSERT_THROW(m->giveCellsWithType(INTERP_KERNEL::NORM_SEG2),INTERP_KERNEL::Exception); - CPPUNIT_ASSERT_THROW(m->giveCellsWithType(INTERP_KERNEL::NORM_HEXA8),INTERP_KERNEL::Exception); - // - m->decrRef(); -} - -void MEDCouplingBasicsTest5::testBuildSlice3D2() -{ - MEDCouplingUMesh *mesh2D=0; - MEDCouplingUMesh *mesh3D=build3DExtrudedUMesh_1(mesh2D); - mesh2D->decrRef(); - // First slice in the middle of 3D cells - const double vec1[3]={-0.07,1.,0.07}; - const double origin1[3]={1.524,1.4552,1.74768}; - DataArrayInt *ids=0; - MEDCouplingUMesh *slice1=mesh3D->buildSlice3D(origin1,vec1,1e-10,ids); - // - MEDCouplingFieldDouble *f=MEDCouplingFieldDouble::New(ON_CELLS,ONE_TIME); - f->setTime(4.5,6,7) ; f->setMesh(mesh3D); - DataArrayDouble *arr=DataArrayDouble::New(); arr->alloc(mesh3D->getNumberOfCells(),2); - arr->rearrange(1); arr->iota(2.); arr->rearrange(2); - f->setArray(arr); - f->checkCoherency(); - const int exp1[9]={1,3,4,7,9,10,13,15,16}; - DataArrayInt *expected1=DataArrayInt::New(); expected1->alloc(9,1); std::copy(exp1,exp1+9,expected1->getPointer()); - CPPUNIT_ASSERT(expected1->isEqual(*ids)); - DataArrayDouble *arr2=arr->selectByTupleIdSafe(expected1->begin(),expected1->end()); - // - MEDCouplingFieldDouble *f2=f->extractSlice3D(origin1,vec1,1e-10); - CPPUNIT_ASSERT(f2->getArray()->isEqual(*arr2,1e-12)); - CPPUNIT_ASSERT(slice1->isEqual(f2->getMesh(),1e-12)); - int a,b; - double c=f2->getTime(a,b); - CPPUNIT_ASSERT_EQUAL(6,a); - CPPUNIT_ASSERT_EQUAL(7,b); - CPPUNIT_ASSERT_DOUBLES_EQUAL(4.5,c,1e-12); - // - ids->decrRef(); - slice1->decrRef(); - arr2->decrRef(); - arr->decrRef(); - f2->decrRef(); - f->decrRef(); - mesh3D->decrRef(); - expected1->decrRef(); -} - -void MEDCouplingBasicsTest5::testComputeTupleIdsToSelectFromCellIds1() -{ - MEDCouplingUMesh *m=build2DTargetMesh_3(); - MEDCouplingFieldDouble *f=MEDCouplingFieldDouble::New(ON_GAUSS_NE,NO_TIME); - f->setMesh(m); - DataArrayDouble *arr=DataArrayDouble::New(); arr->alloc(52,2) ; arr->rearrange(1) ; arr->iota(7.); arr->rearrange(2); - f->setArray(arr); - // - const int subPart1[3]={1,5,9}; - MEDCouplingFieldDouble *f2=f->buildSubPart(subPart1,subPart1+3); - f2->checkCoherency(); - DataArrayInt *cI=m->computeNbOfNodesPerCell(); - cI->computeOffsets2(); - const int sel1[3]={1,5,9}; - DataArrayInt *sel=DataArrayInt::New(); sel->useArray(sel1,false,CPP_DEALLOC,3,1); - DataArrayInt *res=sel->buildExplicitArrByRanges(cI); - DataArrayDouble *arr2=arr->selectByTupleIdSafe(res->begin(),res->end()); - const double expected1[30]={13.,14.,15.,16.,17.,18.,19.,20.,59.,60.,61.,62.,63.,64.,95.,96.,97.,98.,99.,100.,101.,102.,103.,104.,105.,106.,107.,108.,109.,110.}; - DataArrayDouble *arr3=DataArrayDouble::New(); arr3->useArray(expected1,false,CPP_DEALLOC,15,2); - CPPUNIT_ASSERT(arr2->isEqual(*arr3,1e-12)); - CPPUNIT_ASSERT(arr2->isEqual(*f2->getArray(),1e-12)); - // - cI->decrRef(); - arr3->decrRef(); - arr2->decrRef(); - arr->decrRef(); - m->decrRef(); - f->decrRef(); - f2->decrRef(); - sel->decrRef(); - res->decrRef(); -} - -void MEDCouplingBasicsTest5::testComputeSkin1() -{ - const double input1[5]={2.,3.4,5.6,7.7,8.0}; - const double input2[6]={2.,3.4,5.6,7.7,9.0,14.2}; - DataArrayDouble *arrX=DataArrayDouble::New(); arrX->alloc(5,1); std::copy(input1,input1+5,arrX->getPointer()); - DataArrayDouble *arrY=DataArrayDouble::New(); arrY->alloc(6,1); std::copy(input2,input2+6,arrY->getPointer()); - MEDCouplingCMesh *cmesh=MEDCouplingCMesh::New() ; cmesh->setCoordsAt(0,arrX) ; cmesh->setCoordsAt(1,arrY); - MEDCouplingUMesh *umesh=cmesh->buildUnstructured(); - cmesh->decrRef(); arrX->decrRef(); arrY->decrRef(); - // - MEDCouplingUMesh *skin=umesh->computeSkin(); - CPPUNIT_ASSERT_EQUAL(18,skin->getNumberOfCells()); - CPPUNIT_ASSERT_EQUAL(1,skin->getMeshDimension()); - CPPUNIT_ASSERT(skin->getCoords()==umesh->getCoords()); - const int expected1[19]={0,3,6,9,12,15,18,21,24,27,30,33,36,39,42,45,48,51,54}; - const int expected2[54]={1,1,0,1,0,5,1,2,1,1,3,2,1,4,3,1,9,4,1,5,10,1,14,9,1,10,15,1,19,14,1,15,20,1,24,19,1,20,25,1,25,26,1,26,27,1,27,28,1,28,29,1,29,24}; - CPPUNIT_ASSERT_EQUAL((std::size_t)19,skin->getNodalConnectivityIndex()->getNbOfElems()); - CPPUNIT_ASSERT(std::equal(expected1,expected1+19,skin->getNodalConnectivityIndex()->getConstPointer())); - CPPUNIT_ASSERT_EQUAL((std::size_t)54,skin->getNodalConnectivity()->getNbOfElems()); - CPPUNIT_ASSERT(std::equal(expected2,expected2+54,skin->getNodalConnectivity()->getConstPointer())); - DataArrayInt *ids=skin->computeFetchedNodeIds(); - const int expected3[18]={0,1,2,3,4,5,9,10,14,15,19,20,24,25,26,27,28,29}; - CPPUNIT_ASSERT_EQUAL((std::size_t)18,ids->getNbOfElems()); - CPPUNIT_ASSERT(std::equal(expected3,expected3+18,ids->getConstPointer())); - MEDCouplingUMesh *part=dynamic_cast(umesh->buildFacePartOfMySelfNode(ids->begin(),ids->end(),true)); - part->setName(skin->getName().c_str()); - CPPUNIT_ASSERT(part->isEqual(skin,1e-12)); - MEDCouplingUMesh *part2=dynamic_cast(part->buildPartOfMySelf2(1,18,2,true)); - DataArrayInt *ids2=DataArrayInt::Range(0,18,2); - part->setPartOfMySelf(ids2->begin(),ids2->end(),*part2); - ids2->decrRef(); - CPPUNIT_ASSERT(!part->isEqual(skin,1e-12)); - DataArrayInt *trad=part->zipConnectivityTraducer(0); - CPPUNIT_ASSERT_EQUAL(9,part->getNumberOfCells()); - const int expected4[18]={0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8}; - CPPUNIT_ASSERT(std::equal(expected4,expected4+18,trad->getConstPointer())); - CPPUNIT_ASSERT_EQUAL((std::size_t)18,trad->getNbOfElems()); - trad->decrRef(); - part->decrRef(); - part2->decrRef(); - // - ids->decrRef(); - umesh->decrRef(); - skin->decrRef(); -} - -void MEDCouplingBasicsTest5::testUMeshSetPartOfMySelf2() -{ - // resize with explicit ids list - MEDCouplingUMesh *m=build2DTargetMesh_1(); - std::set s; s.insert(INTERP_KERNEL::NORM_TRI3); s.insert(INTERP_KERNEL::NORM_QUAD4); - CPPUNIT_ASSERT(s==m->getAllGeoTypes()); - const int ids1[3]={0,3,4}; - MEDCouplingUMesh *part=static_cast(m->buildPartOfMySelf(ids1,ids1+3,true)); - part->simplexize(0)->decrRef(); - const int ids2[3]={1,2,5}; - MEDCouplingUMesh *part2=static_cast(part->buildPartOfMySelf(ids2,ids2+3,true)); - m->setPartOfMySelf(ids1,ids1+3,*part2); - const int expected1[20]={3,0,4,1,3,1,4,2,3,4,5,2,3,6,7,4,3,7,5,4}; - CPPUNIT_ASSERT(std::equal(expected1,expected1+20,m->getNodalConnectivity()->getConstPointer())); - CPPUNIT_ASSERT_EQUAL((std::size_t)20,m->getNodalConnectivity()->getNbOfElems()); - const int expected2[6]={0,4,8,12,16,20}; - CPPUNIT_ASSERT(std::equal(expected2,expected2+6,m->getNodalConnectivityIndex()->getConstPointer())); - CPPUNIT_ASSERT_EQUAL((std::size_t)6,m->getNodalConnectivityIndex()->getNbOfElems()); - s.clear(); s.insert(INTERP_KERNEL::NORM_TRI3); - CPPUNIT_ASSERT(s==m->getAllGeoTypes()); - m->decrRef(); part->decrRef(); part2->decrRef(); - // no resize with explicit ids list - m=build2DTargetMesh_1(); - part=static_cast(m->buildPartOfMySelf(ids1,ids1+2,true)); - part->convertAllToPoly(); - m->setPartOfMySelf(ids1+1,ids1+3,*part); - const int expected3[23]={4,0,3,4,1,3,1,4,2,3,4,5,2,5,0,3,4,1,5,6,7,4,3}; - CPPUNIT_ASSERT(std::equal(expected3,expected3+23,m->getNodalConnectivity()->getConstPointer())); - CPPUNIT_ASSERT_EQUAL((std::size_t)23,m->getNodalConnectivity()->getNbOfElems()); - const int expected4[6]={0,5,9,13,18,23}; - CPPUNIT_ASSERT(std::equal(expected4,expected4+6,m->getNodalConnectivityIndex()->getConstPointer())); - CPPUNIT_ASSERT_EQUAL((std::size_t)6,m->getNodalConnectivityIndex()->getNbOfElems()); - s.clear(); s.insert(INTERP_KERNEL::NORM_TRI3); s.insert(INTERP_KERNEL::NORM_QUAD4); s.insert(INTERP_KERNEL::NORM_POLYGON); - CPPUNIT_ASSERT(s==m->getAllGeoTypes()); - m->decrRef(); part->decrRef(); - // resize with range ids - m=build2DTargetMesh_1(); - part=static_cast(m->buildPartOfMySelf2(3,5,1,true)); - m->setPartOfMySelf2(1,3,1,*part); - const int expected5[25]={4,0,3,4,1,4,6,7,4,3,4,7,8,5,4,4,6,7,4,3,4,7,8,5,4}; - CPPUNIT_ASSERT(std::equal(expected5,expected5+25,m->getNodalConnectivity()->getConstPointer())); - CPPUNIT_ASSERT_EQUAL((std::size_t)25,m->getNodalConnectivity()->getNbOfElems()); - const int expected6[6]={0,5,10,15,20,25}; - CPPUNIT_ASSERT(std::equal(expected6,expected6+6,m->getNodalConnectivityIndex()->getConstPointer())); - CPPUNIT_ASSERT_EQUAL((std::size_t)6,m->getNodalConnectivityIndex()->getNbOfElems()); - s.clear(); s.insert(INTERP_KERNEL::NORM_QUAD4); - CPPUNIT_ASSERT(s==m->getAllGeoTypes()); - m->decrRef(); part->decrRef(); - // no resize with range ids - m=build2DTargetMesh_1(); - part=static_cast(m->buildPartOfMySelf2(0,5,3,true)); - part->convertAllToPoly(); - m->setPartOfMySelf2(3,5,1,*part); - const int expected7[23]={4,0,3,4,1,3,1,4,2,3,4,5,2,5,0,3,4,1,5,6,7,4,3}; - CPPUNIT_ASSERT(std::equal(expected7,expected7+23,m->getNodalConnectivity()->getConstPointer())); - CPPUNIT_ASSERT_EQUAL((std::size_t)23,m->getNodalConnectivity()->getNbOfElems()); - const int expected8[6]={0,5,9,13,18,23}; - CPPUNIT_ASSERT(std::equal(expected8,expected8+6,m->getNodalConnectivityIndex()->getConstPointer())); - CPPUNIT_ASSERT_EQUAL((std::size_t)6,m->getNodalConnectivityIndex()->getNbOfElems()); -s.clear(); s.insert(INTERP_KERNEL::NORM_TRI3); s.insert(INTERP_KERNEL::NORM_QUAD4); s.insert(INTERP_KERNEL::NORM_POLYGON); - CPPUNIT_ASSERT(s==m->getAllGeoTypes()); - m->decrRef(); part->decrRef(); - // no resize with range ids negative direction - m=build2DTargetMesh_1(); - part=static_cast(m->buildPartOfMySelf2(3,-1,-3,true)); - part->convertAllToPoly(); - m->setPartOfMySelf2(4,2,-1,*part); - const int expected9[23]={4,0,3,4,1,3,1,4,2,3,4,5,2,5,0,3,4,1,5,6,7,4,3}; - CPPUNIT_ASSERT(std::equal(expected9,expected9+23,m->getNodalConnectivity()->getConstPointer())); - CPPUNIT_ASSERT_EQUAL((std::size_t)23,m->getNodalConnectivity()->getNbOfElems()); - const int expected10[6]={0,5,9,13,18,23}; - CPPUNIT_ASSERT(std::equal(expected10,expected10+6,m->getNodalConnectivityIndex()->getConstPointer())); - CPPUNIT_ASSERT_EQUAL((std::size_t)6,m->getNodalConnectivityIndex()->getNbOfElems()); - s.clear(); s.insert(INTERP_KERNEL::NORM_TRI3); s.insert(INTERP_KERNEL::NORM_QUAD4); s.insert(INTERP_KERNEL::NORM_POLYGON); - CPPUNIT_ASSERT(s==m->getAllGeoTypes()); - part->decrRef(); - m->decrRef(); -} - -void MEDCouplingBasicsTest5::testUnPolyze3() -{ - const double coord[18]={0.0,0.5,-0.5,-0.5,-0.5,-0.5,0.5,-0.5,-0.5,0.0,0.5,0.5,-0.5,-0.5,0.5,0.5,-0.5,0.5}; - const int conn[22]={1,2,5,4,-1,4,3,0,1,-1,2,0,3,5,-1,0,2,1,-1,4,5,3}; - MEDCouplingUMesh *m=MEDCouplingUMesh::New("a mesh",3); - m->allocateCells(1); - m->insertNextCell(INTERP_KERNEL::NORM_POLYHED,22,conn); - m->finishInsertingCells(); - DataArrayDouble *coords=DataArrayDouble::New(); - coords->alloc(6,3); - std::copy(coord,coord+18,coords->getPointer()); - m->setCoords(coords); - coords->decrRef(); - m->checkCoherency(); - // - MEDCouplingFieldDouble *vol=m->getMeasureField(ON_CELLS); - CPPUNIT_ASSERT_EQUAL(1,vol->getArray()->getNumberOfTuples()); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.5,vol->getArray()->getIJ(0,0),1e-12); - vol->decrRef(); - // - m->unPolyze(); - CPPUNIT_ASSERT_EQUAL(1,m->getNumberOfCells()); - std::set s; s.insert(INTERP_KERNEL::NORM_PENTA6); - CPPUNIT_ASSERT(s==m->getAllGeoTypes()); - // - const int expected1[2]={0,7}; - const int expected2[7]={16,0,2,1,3,5,4}; - CPPUNIT_ASSERT_EQUAL(2,m->getNodalConnectivityIndex()->getNumberOfTuples()); - CPPUNIT_ASSERT(std::equal(expected1,expected1+2,m->getNodalConnectivityIndex()->getConstPointer())); - CPPUNIT_ASSERT_EQUAL(7,m->getNodalConnectivity()->getNumberOfTuples()); - CPPUNIT_ASSERT(std::equal(expected2,expected2+7,m->getNodalConnectivity()->getConstPointer())); - // - vol=m->getMeasureField(ON_CELLS); - CPPUNIT_ASSERT_EQUAL(1,vol->getArray()->getNumberOfTuples()); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.5,vol->getArray()->getIJ(0,0),1e-12); - vol->decrRef(); - // - m->decrRef(); -} - -void MEDCouplingBasicsTest5::testKrSpatialDiscretization1() -{ - const double srcPointCoordsX[10]={0.8401877171547095, 0.7830992237586059, 0.9116473579367843, 0.335222755714889, 0.2777747108031878, 0.4773970518621602, 0.3647844727918433, 0.9522297251747128, 0.6357117279599009, 0.1416025553558034}; - const double srcFieldValsOnPoints[10]={2.129892434968836, 2.295320474540621, 1.931948594981134, 2.728013590937196, 2.715603240418478, 2.661778472822935, 2.695696990104364, 1.893710234970982, 2.529628016549284, 2.728432341300668}; - const double targetPointCoordsX[40]={-0.5,-0.45,-0.4,-0.35,-0.3,-0.25,-0.2,-0.15,-0.1,-0.05,-6.93889390391e-17,0.05,0.1,0.15,0.2,0.25,0.3,0.35,0.4,0.45,0.5,0.55,0.6,0.65,0.7,0.75,0.8,0.85,0.9,0.95,1.0,1.05,1.1,1.15,1.2,1.25,1.3,1.35,1.4,1.45}; - const double targetFieldValsExpected[40]={2.975379475824351, 2.95613491917003, 2.936890362515361, 2.917645805861018, 2.898401249206574, 2.879156692552137, 2.859912135897732, 2.840667579243201, 2.821423022588731, 2.802178465934342, 2.78293390927989, 2.763689352625457, 2.744444795971001, 2.725209522098197, 2.709077577124666, 2.706677252549218, 2.727467797847971, 2.713338094723676, 2.671342424824244, 2.664877370146978, 2.653840141412181, 2.619607861392791, 2.569777214476479, 2.513263929794591, 2.450732752808528, 2.368313560985155, 2.250909795670307, 2.098194272085416, 1.954257891732065, 1.895040660973802, 1.865256788315972, 1.835475248687992, 1.80569370905998, 1.775912169431971, 1.746130629803976, 1.716349090175918, 1.686567550547855, 1.656786010919941, 1.627004471291988, 1.597222931663817}; - // - int nbOfInputPoints=10; - MEDCouplingFieldDouble *f=MEDCouplingFieldDouble::New(ON_NODES_KR,ONE_TIME); - DataArrayDouble *srcArrX=DataArrayDouble::New(); - srcArrX->alloc(nbOfInputPoints,1); - std::copy(srcPointCoordsX,srcPointCoordsX+nbOfInputPoints,srcArrX->getPointer()); - MEDCouplingCMesh *cmesh=MEDCouplingCMesh::New("aMesh"); - cmesh->setCoordsAt(0,srcArrX); - MEDCouplingUMesh *umesh=cmesh->buildUnstructured(); - f->setMesh(umesh); - DataArrayDouble *srcVals=DataArrayDouble::New(); - srcVals->alloc(nbOfInputPoints,1); - std::copy(srcFieldValsOnPoints,srcFieldValsOnPoints+nbOfInputPoints,srcVals->getPointer()); - f->setArray(srcVals); - f->checkCoherency(); - // - double *res0=new double[1]; - f->getValueOn(targetPointCoordsX,res0); - CPPUNIT_ASSERT_DOUBLES_EQUAL(targetFieldValsExpected[0],res0[0],1e-10); - delete [] res0; - // - DataArrayDouble *valuesToTest=f->getValueOnMulti(targetPointCoordsX,40); - CPPUNIT_ASSERT_EQUAL(40,valuesToTest->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(1,valuesToTest->getNumberOfComponents()); - for(int i=0;i<40;i++) - CPPUNIT_ASSERT_DOUBLES_EQUAL(targetFieldValsExpected[i],valuesToTest->getIJ(i,0),1e-10); - valuesToTest->decrRef(); - // - cmesh->decrRef(); - umesh->decrRef(); - srcArrX->decrRef(); - srcVals->decrRef(); - f->decrRef(); -} - -void MEDCouplingBasicsTest5::testDuplicateEachTupleNTimes1() -{ - const double vals0[4]={9.,8.,7.,6.}; - DataArrayDouble *d=DataArrayDouble::New(); d->useArray(vals0,false,CPP_DEALLOC,4,1); d->setInfoOnComponent(0,"mass [kg]"); d->setName("aname"); - DataArrayDouble *d2=d->duplicateEachTupleNTimes(3); - const double vals1[12]={9.,9.,9.,8.,8.,8.,7.,7.,7.,6.,6.,6.}; - DataArrayDouble *d3=DataArrayDouble::New(); d3->useArray(vals1,false,CPP_DEALLOC,4*3,1); d3->setName("aname"); d3->setInfoOnComponent(0,"mass [kg]"); - CPPUNIT_ASSERT(d2->isEqual(*d2,1e-14)); d3->decrRef(); - d->decrRef(); - d2->decrRef(); - // - const int vals2[4]={9,8,7,6}; - DataArrayInt *d4=DataArrayInt::New(); d4->useArray(vals2,false,CPP_DEALLOC,4,1); d4->setInfoOnComponent(0,"mass [kg]") ; d4->setName("aname"); - DataArrayInt *d5=d4->duplicateEachTupleNTimes(3); - const int vals3[12]={9,9,9,8,8,8,7,7,7,6,6,6}; - DataArrayInt *d6=DataArrayInt::New(); d6->useArray(vals3,false,CPP_DEALLOC,4*3,1); d6->setName("aname"); d6->setInfoOnComponent(0,"mass [kg]"); - CPPUNIT_ASSERT(d5->isEqual(*d6)); d6->decrRef(); - d4->decrRef(); - d5->decrRef(); -} - -void MEDCouplingBasicsTest5::testIntersect2DMeshesTmp5() -{ - // coordinates - DataArrayDouble *coords=DataArrayDouble::New(); - const double coordsData[376]={41,0,42,0,0,42,0,41,41.5,0,29.698484809834998,29.698484809834994,0,41.5,28.991378028648452,28.991378028648445,-42,0,-41,0,-29.698484809834994,29.698484809834998,-41.5,0,-28.991378028648445,28.991378028648452,0,-42,0,-41,-29.698484809835001,-29.698484809834994,0,-41.5,-28.991378028648455,-28.991378028648445,29.698484809834987,-29.698484809835001,28.991378028648441,-28.991378028648455,43,0,0,43,42.5,0,30.405591591021544,30.40559159102154,0,42.5,-43,0,-30.40559159102154,30.405591591021544,-42.5,0,0,-43,-30.405591591021551,-30.40559159102154,0,-42.5,30.405591591021537,-30.405591591021551,44,0,0,44,43.5,0,31.112698372208094,31.112698372208087,0,43.5,-44,0,-31.112698372208087,31.112698372208094,-43.5,0,0,-44,-31.112698372208097,-31.112698372208087,0,-43.5,31.112698372208083,-31.112698372208097,45,0,0,45,44.5,0,31.81980515339464,31.819805153394636,0,44.5,-45,0,-31.819805153394636,31.81980515339464,-44.5,0,0,-45,-31.819805153394647,-31.819805153394636,0,-44.5,31.819805153394629,-31.819805153394647,47,0,0,47,46,0,33.234018715767739,33.234018715767732,0,46,-47,0,-33.234018715767732,33.234018715767739,-46,0,0,-47,-33.234018715767739,-33.234018715767732,0,-46,33.234018715767725,-33.234018715767739,49,0,0,49,48,0,34.648232278140831,34.648232278140824,0,48,-49,0,-34.648232278140824,34.648232278140831,-48,0,0,-49,-34.648232278140839,-34.648232278140824,0,-48,34.648232278140817,-34.648232278140839,51,0,0,51,50,0,36.062445840513924,36.062445840513924,0,50,-51,0,-36.062445840513924,36.062445840513924,-50,0,0,-51,-36.062445840513931,-36.062445840513924,0,-50,36.062445840513917,-36.062445840513931,53,0,0,53,52,0,37.476659402887023,37.476659402887016,0,52,-53,0,-37.476659402887016,37.476659402887023,-52,0,0,-53,-37.47665940288703,-37.476659402887016,0,-52,37.476659402887009,-37.47665940288703,55,0,0,55,54,0,38.890872965260115,38.890872965260108,0,54,-55,0,-38.890872965260108,38.890872965260115,-54,0,0,-55,-38.890872965260122,-38.890872965260108,0,-54,38.890872965260101,-38.890872965260122,59,0,0,59,57,0,41.719300090006307,41.7193000900063,0,57,-59,0,-41.7193000900063,41.719300090006307,-57,0,0,-59,-41.719300090006314,-41.7193000900063,0,-57,41.719300090006293,-41.719300090006314,63,0,0,63,61,0,44.547727214752499,44.547727214752491,0,61,-63,0,-44.547727214752491,44.547727214752499,-61,0,0,-63,-44.547727214752506,-44.547727214752491,0,-61,44.547727214752484,-44.547727214752506,67,0,0,67,65,0,47.37615433949869,47.376154339498683,0,65,-67,0,-47.376154339498683,47.37615433949869,-65,0,0,-67,-47.376154339498697,-47.376154339498683,0,-65,47.376154339498676,-47.376154339498697,71,0,0,71,69,0,50.204581464244875,50.204581464244868,0,69,-71,0,-50.204581464244868,50.204581464244875,-69,0,0,-71,-50.204581464244889,-50.204581464244868,0,-69,50.20458146424486,-50.204581464244889,75,0,0,75,73,0,53.033008588991066,53.033008588991059,0,73,-75,0,-53.033008588991059,53.033008588991066,-73,0,0,-75,-53.033008588991073,-53.033008588991059,0,-73,53.033008588991052,-53.033008588991073,80,0,0,80,77.5,0,56.568542494923804,56.568542494923797,0,77.5,-80,0,-56.568542494923797,56.568542494923804,-77.5,0,0,-80,-56.568542494923818,-56.568542494923797,0,-77.5,56.56854249492379,-56.568542494923818}; - coords->useArray(coordsData,false,CPP_DEALLOC,188,2); - coords->setName(""); - DataArrayInt *conn=DataArrayInt::New(); - const int connData[540]={8,0,1,2,3,4,5,6,7,8,3,2,8,9,6,10,11,12,8,9,8,13,14,11,15,16,17,8,14,13,1,0,16,18,4,19,8,1,20,21,2,22,23,24,5,8,2,21,25,8,24,26,27,10,8,8,25,28,13,27,29,30,15,8,13,28,20,1,30,31,22,18,8,20,32,33,21,34,35,36,23,8,21,33,37,25,36,38,39,26,8,25,37,40,28,39,41,42,29,8,28,40,32,20,42,43,34,31,8,32,44,45,33,46,47,48,35,8,33,45,49,37,48,50,51,38,8,37,49,52,40,51,53,54,41,8,40,52,44,32,54,55,46,43,8,44,56,57,45,58,59,60,47,8,45,57,61,49,60,62,63,50,8,49,61,64,52,63,65,66,53,8,52,64,56,44,66,67,58,55,8,56,68,69,57,70,71,72,59,8,57,69,73,61,72,74,75,62,8,61,73,76,64,75,77,78,65,8,64,76,68,56,78,79,70,67,8,68,80,81,69,82,83,84,71,8,69,81,85,73,84,86,87,74,8,73,85,88,76,87,89,90,77,8,76,88,80,68,90,91,82,79,8,80,92,93,81,94,95,96,83,8,81,93,97,85,96,98,99,86,8,85,97,100,88,99,101,102,89,8,88,100,92,80,102,103,94,91,8,92,104,105,93,106,107,108,95,8,93,105,109,97,108,110,111,98,8,97,109,112,100,111,113,114,101,8,100,112,104,92,114,115,106,103,8,104,116,117,105,118,119,120,107,8,105,117,121,109,120,122,123,110,8,109,121,124,112,123,125,126,113,8,112,124,116,104,126,127,118,115,8,116,128,129,117,130,131,132,119,8,117,129,133,121,132,134,135,122,8,121,133,136,124,135,137,138,125,8,124,136,128,116,138,139,130,127,8,128,140,141,129,142,143,144,131,8,129,141,145,133,144,146,147,134,8,133,145,148,136,147,149,150,137,8,136,148,140,128,150,151,142,139,8,140,152,153,141,154,155,156,143,8,141,153,157,145,156,158,159,146,8,145,157,160,148,159,161,162,149,8,148,160,152,140,162,163,154,151,8,152,164,165,153,166,167,168,155,8,153,165,169,157,168,170,171,158,8,157,169,172,160,171,173,174,161,8,160,172,164,152,174,175,166,163,8,164,176,177,165,178,179,180,167,8,165,177,181,169,180,182,183,170,8,169,181,184,172,183,185,186,173,8,172,184,176,164,186,187,178,175}; - conn->useArray(connData,false,CPP_DEALLOC,540,1); - conn->setName(""); - DataArrayInt *connI=DataArrayInt::New(); - const int connIData[61]={0,9,18,27,36,45,54,63,72,81,90,99,108,117,126,135,144,153,162,171,180,189,198,207,216,225,234,243,252,261,270,279,288,297,306,315,324,333,342,351,360,369,378,387,396,405,414,423,432,441,450,459,468,477,486,495,504,513,522,531,540}; - connI->useArray(connIData,false,CPP_DEALLOC,61,1); - connI->setName(""); - // - MEDCouplingUMesh *m1=MEDCouplingUMesh::New("Fix",2); - m1->setCoords(coords); - m1->setConnectivity(conn,connI,true); - coords->decrRef(); conn->decrRef(); connI->decrRef(); - // - coords=DataArrayDouble::New(); - const double coordsData2[84]={46.5,-2.5,53.5,-2.5,53.5,2.5,46.5,2.5,50,-2.5,53.5,0,50,2.5,46.5,0,60.5,-2.5,60.5,2.5,57,-2.5,60.5,0,57,2.5,53.5,7.5,46.5,7.5,53.5,5,50,7.5,46.5,5,60.5,7.5,60.5,5,57,7.5,-2,47,2,47,2,53,-2,53,0,47,2,50,0,53,-2,50,6,47,6,53,4,47,6,50,4,53,2,59,-2,59,2,56,0,59,-2,56,6,59,6,56,4,59}; - coords->useArray(coordsData2,false,CPP_DEALLOC,42,2); - coords->setName(""); - // connectivity - conn=DataArrayInt::New(); - const int connData2[72]={8,0,1,2,3,4,5,6,7,8,1,8,9,2,10,11,12,5,8,3,2,13,14,6,15,16,17,8,2,9,18,13,12,19,20,15,8,21,22,23,24,25,26,27,28,8,22,29,30,23,31,32,33,26,8,24,23,34,35,27,36,37,38,8,23,30,39,34,33,40,41,36}; - conn->useArray(connData2,false,CPP_DEALLOC,72,1); - conn->setName(""); - connI=DataArrayInt::New(); - const int connIData2[9]={0,9,18,27,36,45,54,63,72}; - connI->useArray(connIData2,false,CPP_DEALLOC,9,1); - connI->setName(""); - MEDCouplingUMesh *m2=MEDCouplingUMesh::New("Mobile",2); - m2->setCoords(coords); - m2->setConnectivity(conn,connI,true); - coords->decrRef(); conn->decrRef(); connI->decrRef(); - // - DataArrayInt *d1=0,*d2=0; - MEDCouplingUMesh *m3=MEDCouplingUMesh::Intersect2DMeshes(m1,m2,1e-10,d1,d2); - CPPUNIT_ASSERT_EQUAL(105,m3->getNumberOfCells()); - CPPUNIT_ASSERT_EQUAL(105,d1->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(105,d2->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(704,m3->getNumberOfNodes()); - // - const double areaExpected[105]={-65.18804756198824,-65.18804756198824,-65.18804756198824,-65.18804756198824,-66.75884388878285,-66.75884388878285,-66.7588438887833,-66.75884388878308,-68.32964021557768,-68.32964021557768,-68.32964021557814,-68.32964021557791,-69.9004365423732,-69.9004365423732,-69.90043654237297,-69.90043654237297,-1.194568659706448,-1.0869994447159463,-142.2316939607081,-144.51326206513068,-144.5132620651309,-1.1945686597064424,-143.3186934054243,-5.002264310862817,-10.0261332846393,-3.9727823117092953,-7.290862524642649,-124.504404940456,-3.9727823117093237,-146.82366506060032,-150.79644737231024,-5.002264310862776,-145.79418306144626,-5.00208651738126,-10.054764051268958,-4.001067863263231,-8.027932154428669,-129.99378209314813,-4.001067863263216,-153.07856481622616,-157.0796326794898,-5.0020865173811915,-152.07754616210832,-5.001928880064381,-10.050590216368969,-4.00098721602491,-8.025810856794209,-136.28350081741684,-4.000987216024939,-159.36183077064402,-163.36281798667005,-5.0019288800643285,-158.36088910660442,-1.2991516319851801,-3.702636830195414,-3.7815130030068254,-6.265364371195623,-0.02516260900254963,-0.6553944641345026,-3.975752765070567,-7.368528340442765,-142.57249927881398,-0.02516260900254963,-3.9757527650706095,-165.64508791977525,-169.64600329384803,-1.299151631985167,-3.7026368301953885,-164.6442148316677,-10.00321285677458,-20.08414323176165,-8.001644468035863,-16.042954878437143,-304.0096070742277,-8.00164446803587,-350.1399180412005,-358.1415625092368,-10.003212856774468,-348.13834965246224,-3.794150313030109,-8.65049239704272,-0.02260276689354157,-0.5885167811200915,-370.2185414798688,-0.022602766893559393,-383.2517009710623,-383.2743037379555,-3.7941503130300576,-379.48015342492505,-408.40704496667513,-408.4070449666742,-408.4070449666742,-408.4070449666742,-433.53978619538975,-433.5397861953902,-433.5397861953911,-433.53978619539066,-458.67252742410983,-458.6725274241094,-458.67252742410983,-458.6725274241089,-608.6835766330232,-608.6835766330232,-608.6835766330232,-608.6835766330241}; - const int expected1[105]={0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,16,16,17,18,19,19,20,20,20,20,20,21,21,22,23,23,24,24,24,24,24,25,25,26,27,27,28,28,28,28,28,29,29,30,31,31,32,32,32,32,32,32,32,32,32,33,33,33,34,35,35,35,36,36,36,36,36,37,37,38,39,39,40,40,40,40,40,41,41,42,43,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59}; - const int expected2[105]={-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,0,2,-1,-1,-1,0,-1,0,2,4,5,-1,4,-1,-1,0,-1,0,2,4,5,-1,4,-1,-1,0,-1,0,2,4,5,-1,4,-1,-1,0,-1,0,1,2,3,4,5,6,7,-1,4,6,-1,-1,0,1,-1,1,3,6,7,-1,6,-1,-1,1,-1,1,3,6,7,-1,6,-1,-1,1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1}; - MEDCouplingFieldDouble *f3f=m3->getMeasureField(ON_CELLS); - const double *f3=f3f->getArray()->getConstPointer(); - for(int i=0;i<105;i++) - { - CPPUNIT_ASSERT_DOUBLES_EQUAL(areaExpected[i],f3[i],1e-10); - CPPUNIT_ASSERT_EQUAL(expected1[i],d1->getIJ(i,0)); - CPPUNIT_ASSERT_EQUAL(expected2[i],d2->getIJ(i,0)); - } - // - f3f->decrRef(); - m3->decrRef(); - d1->decrRef(); - d2->decrRef(); - m2->decrRef(); - m1->decrRef(); -} - -void MEDCouplingBasicsTest5::testDAIBuildUnique1() -{ - DataArrayInt *d=DataArrayInt::New(); - const int dData[14]={1,2,2,3,3,3,3,4,5,5,7,7,7,19}; - d->useArray(dData,false,CPP_DEALLOC,14,1); - const int expectedData[7]={1,2,3,4,5,7,19}; - // - DataArrayInt *e=d->buildUnique(); - CPPUNIT_ASSERT_EQUAL(7,e->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(1,e->getNumberOfComponents()); - for(int i=0;i<7;i++) - CPPUNIT_ASSERT_EQUAL(expectedData[i],e->getIJ(i,0)); - // - e->decrRef(); - d->decrRef(); -} - -void MEDCouplingBasicsTest5::testDAIPartitionByDifferentValues1() -{ - const int data[9]={1,0,1,2,0,2,2,-3,2}; - const int expected1[4]={-3,0,1,2}; - const int expected2_0[1]={7}; - const int expected2_1[2]={1,4}; - const int expected2_2[2]={0,2}; - const int expected2_3[4]={3,5,6,8}; - DataArrayInt *d=DataArrayInt::New(); - d->useArray(data,false,CPP_DEALLOC,9,1); - std::vector f; - static const int nbOfOutputsExpected=4; - std::vector e=d->partitionByDifferentValues(f); - d->decrRef(); - CPPUNIT_ASSERT_EQUAL(nbOfOutputsExpected,(int)e.size()); - CPPUNIT_ASSERT_EQUAL(nbOfOutputsExpected,(int)f.size()); - for(int i=0;igetNbOfElems()); - CPPUNIT_ASSERT_EQUAL((std::size_t)2,e[1]->getNbOfElems()); - CPPUNIT_ASSERT_EQUAL((std::size_t)2,e[2]->getNbOfElems()); - CPPUNIT_ASSERT_EQUAL((std::size_t)4,e[3]->getNbOfElems()); - CPPUNIT_ASSERT_EQUAL(1,e[0]->getNumberOfComponents()); - CPPUNIT_ASSERT_EQUAL(1,e[1]->getNumberOfComponents()); - CPPUNIT_ASSERT_EQUAL(1,e[2]->getNumberOfComponents()); - CPPUNIT_ASSERT_EQUAL(1,e[3]->getNumberOfComponents()); - CPPUNIT_ASSERT(std::equal(expected2_0,expected2_0+1,e[0]->begin())); - CPPUNIT_ASSERT(std::equal(expected2_1,expected2_1+2,e[1]->begin())); - CPPUNIT_ASSERT(std::equal(expected2_2,expected2_2+2,e[2]->begin())); - CPPUNIT_ASSERT(std::equal(expected2_3,expected2_3+4,e[3]->begin())); - e[0]->decrRef(); e[1]->decrRef(); e[2]->decrRef(); e[3]->decrRef(); -} - -void MEDCouplingBasicsTest5::testDAICheckMonotonic1() -{ - const int data1[6]={-1,0,2,2,4,5}; - const int data2[6]={6,2,0,-8,-9,-56}; - const int data3[6]={-1,0,3,2,4,6}; - const int data4[6]={7,5,2,3,0,-6}; - DataArrayInt *d=DataArrayInt::New(); - d->useArray(data1,false,CPP_DEALLOC,6,1); - CPPUNIT_ASSERT(d->isMonotonic(true)); - CPPUNIT_ASSERT(!d->isMonotonic(false)); - d->checkMonotonic(true); - CPPUNIT_ASSERT_THROW(d->checkMonotonic(false),INTERP_KERNEL::Exception); - d->useArray(data2,false,CPP_DEALLOC,6,1); - CPPUNIT_ASSERT(d->isMonotonic(false)); - CPPUNIT_ASSERT(!d->isMonotonic(true)); - d->checkMonotonic(false); - CPPUNIT_ASSERT_THROW(d->checkMonotonic(true),INTERP_KERNEL::Exception); - d->useArray(data3,false,CPP_DEALLOC,6,1); - CPPUNIT_ASSERT(!d->isMonotonic(false)); - CPPUNIT_ASSERT(!d->isMonotonic(true)); - CPPUNIT_ASSERT_THROW(d->checkMonotonic(true),INTERP_KERNEL::Exception); - CPPUNIT_ASSERT_THROW(d->checkMonotonic(false),INTERP_KERNEL::Exception); - d->useArray(data4,false,CPP_DEALLOC,6,1); - CPPUNIT_ASSERT(!d->isMonotonic(false)); - CPPUNIT_ASSERT(!d->isMonotonic(true)); - CPPUNIT_ASSERT_THROW(d->checkMonotonic(true),INTERP_KERNEL::Exception); - CPPUNIT_ASSERT_THROW(d->checkMonotonic(false),INTERP_KERNEL::Exception); - d->useArray(data4,false,CPP_DEALLOC,0,1); - CPPUNIT_ASSERT(d->isMonotonic(true)); - CPPUNIT_ASSERT(d->isMonotonic(false)); - d->checkMonotonic(true); - d->checkMonotonic(false); - d->useArray(data4,false,CPP_DEALLOC,3,2);//throw because nbComp!=1 - CPPUNIT_ASSERT_THROW(d->isMonotonic(true),INTERP_KERNEL::Exception); - CPPUNIT_ASSERT_THROW(d->isMonotonic(false),INTERP_KERNEL::Exception); - CPPUNIT_ASSERT_THROW(d->checkMonotonic(true),INTERP_KERNEL::Exception); - CPPUNIT_ASSERT_THROW(d->checkMonotonic(false),INTERP_KERNEL::Exception); - d->decrRef(); -} - -void MEDCouplingBasicsTest5::testIntersect2DMeshesTmp6() -{ - // coordinates - DataArrayDouble *coords=DataArrayDouble::New(); - const double coordsData[16]={2.7554552980815448e-15,45,-45,5.5109105961630896e-15,-31.819805153394636,31.81980515339464,2.8779199779962799e-15,47,2.8166876380389124e-15,46,-47,5.7558399559925599e-15,-33.234018715767732,33.234018715767739,-46,5.6333752760778247e-15}; - coords->useArray(coordsData,false,CPP_DEALLOC,8,2); - // connectivity - DataArrayInt *conn=DataArrayInt::New(); - const int connData[9]={8,0,3,5,1,4,6,7,2}; - conn->useArray(connData,false,CPP_DEALLOC,9,1); - DataArrayInt *connI=DataArrayInt::New(); - const int connIData[2]={0,9}; - connI->useArray(connIData,false,CPP_DEALLOC,2,1); - MEDCouplingUMesh *m1=MEDCouplingUMesh::New("Fixe",2); - m1->setCoords(coords); - m1->setConnectivity(conn,connI,true); - coords->decrRef(); conn->decrRef(); connI->decrRef(); - // - coords=DataArrayDouble::New(); - const double coordsData2[26]={-7.3800475508445391,41.854329503018846,-3.7041190667754655,42.338274668899189,-3.7041190667754655,45.338274668899189,-7.3800475508445382,44.854329503018839,-5.5473631693521845,42.136406608386956,-3.7041190667754655,43.838274668899189,-5.5420833088100014,45.09630208595901,-7.3800475508445382,43.354329503018839,-3.7041190667754651,52.338274668899189,-7.3800475508445382,51.854329503018839,-3.7041190667754655,48.838274668899189,-5.5420833088100014,52.09630208595901,-7.3800475508445382,48.354329503018839}; - coords->useArray(coordsData2,false,CPP_DEALLOC,13,2); - // connectivity - conn=DataArrayInt::New(); - const int connData2[18]={8,0,1,2,3,4,5,6,7,8,3,2,8,9,6,10,11,12}; - conn->useArray(connData2,false,CPP_DEALLOC,18,1); - connI=DataArrayInt::New(); - const int connIData2[3]={0,9,18}; - connI->useArray(connIData2,false,CPP_DEALLOC,3,1); - // - MEDCouplingUMesh *m2=MEDCouplingUMesh::New("Mobile",2); - m2->setCoords(coords); - m2->setConnectivity(conn,connI,true); - coords->decrRef(); conn->decrRef(); connI->decrRef(); - // - DataArrayInt *d1=0,*d2=0; - MEDCouplingUMesh *m3=MEDCouplingUMesh::Intersect2DMeshes(m1,m2,1e-10,d1,d2); - CPPUNIT_ASSERT_EQUAL(4,m3->getNumberOfCells()); - CPPUNIT_ASSERT_EQUAL(4,d1->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(4,d2->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(43,m3->getNumberOfNodes()); - bool areMerged=false; - int newNbOfNodes=-1; - m3->mergeNodes(1e-12,areMerged,newNbOfNodes)->decrRef(); - CPPUNIT_ASSERT_EQUAL(35,m3->getNumberOfNodes()); - m3->zipCoords(); - CPPUNIT_ASSERT_EQUAL(23,m3->getNumberOfNodes()); - // - MEDCouplingFieldDouble *f=m3->getMeasureField(true); - const double *vals=f->getArray()->getConstPointer(); - const double valuesExpected[4]={1.6603638692585716,5.747555728471923,129.68907101754394,7.4162714498559694}; - for(int i=0;i<4;i++) - CPPUNIT_ASSERT_DOUBLES_EQUAL(valuesExpected[i],vals[i],1e-12); - f->decrRef(); - // - m1->decrRef(); - m2->decrRef(); - m3->decrRef(); - d1->decrRef(); - d2->decrRef(); -} - -void MEDCouplingBasicsTest5::testIntersect2DMeshesTmp7() -{ - double eps = 1.0e-8; - // coordinates circle - SEE getCircle() on the Python side - DataArrayDouble *coords1=DataArrayDouble::New(); - const double coordsData1[16]={0.5328427124746189, -0.08284271247461905, -0.03284271247461901, 0.4828427124746191, -0.03284271247461906, -0.082842712474619, 0.5328427124746191, 0.482842712474619}; - coords1->useArray(coordsData1,false,CPP_DEALLOC,8,2); - // connectivity - DataArrayInt *conn1=DataArrayInt::New(); - const int connData1[5]={INTERP_KERNEL::NORM_QPOLYG,0,1,2,3}; - conn1->useArray(connData1,false,CPP_DEALLOC,5,1); - DataArrayInt *connI1=DataArrayInt::New(); - const int connIData1[2]={0,5}; - connI1->useArray(connIData1,false,CPP_DEALLOC,2,1); - MEDCouplingUMesh *m1=MEDCouplingUMesh::New("circle",2); - m1->setCoords(coords1); - m1->setConnectivity(conn1,connI1,true); - coords1->decrRef(); conn1->decrRef(); connI1->decrRef(); - - // square - DataArrayDouble *coords2=DataArrayDouble::New(); - const double coordsData2[8]={-0.5,-0.5, -0.5, 0.5, 0.5, 0.5, 0.5,-0.5}; - coords2->useArray(coordsData2,false,CPP_DEALLOC,4,2); - // connectivity - DataArrayInt *conn2=DataArrayInt::New(); - const int connData2[5]={INTERP_KERNEL::NORM_POLYGON, 0,1,2,3}; - conn2->useArray(connData2,false,CPP_DEALLOC,5,1); - DataArrayInt *connI2=DataArrayInt::New(); - const int connIData2[2]={0,5}; - connI2->useArray(connIData2,false,CPP_DEALLOC,2,1); - MEDCouplingUMesh *m2=MEDCouplingUMesh::New("square",2); - m2->setCoords(coords2); - m2->setConnectivity(conn2,connI2,true); - coords2->decrRef(); conn2->decrRef(); connI2->decrRef(); - - DataArrayInt * resToM1 = 0, * resToM2 = 0; - MEDCouplingUMesh *m_intersec=MEDCouplingUMesh::Intersect2DMeshes(m2, m1, eps, resToM1, resToM2); - m_intersec->zipCoords(); - - const double coo_tgt[34]={-0.5, -0.5, -0.5, 0.5, 0.5, 0.5, 0.5, -0.5, -0.03284271247461901, 0.4828427124746191, \ - -0.014575131106459124, 0.5000000000000001, 0.5, -0.11224989991991996, 0.24271243444677046, 0.5, 0.5, 0.19387505004004, \ - -0.04799910280454185, -0.06682678787499614, -0.023843325638122054, 0.4915644577163915, 0.5, -0.30612494995996, 0.0, -0.5,\ - -0.5, 0.0, -0.25728756555322957, 0.5, -0.023843325638122026, 0.49156445771639157, -0.04799910280454181, -0.06682678787499613}; - const int conn_tgt[22]={32, 5, 2, 6, 4, 7, 8, 9, 10, 32, 6, 3, 0, 1, 5, 4, 11, 12, 13, 14, 15, 16}; - const int connI_tgt[3]={0, 9, 22}; - const int res1_tgt[2] = {0, 0}; - const int res2_tgt[2] = {0, -1}; - - CPPUNIT_ASSERT(std::equal(conn_tgt,conn_tgt+22,m_intersec->getNodalConnectivity()->getConstPointer())); - CPPUNIT_ASSERT(std::equal(connI_tgt,connI_tgt+3,m_intersec->getNodalConnectivityIndex()->getConstPointer())); - CPPUNIT_ASSERT(std::equal(res1_tgt,res1_tgt+2,resToM1->getConstPointer())); - CPPUNIT_ASSERT(std::equal(res2_tgt,res2_tgt+2,resToM2->getConstPointer())); - for(int i=0;i<34;i++) - CPPUNIT_ASSERT_DOUBLES_EQUAL(coo_tgt[i],m_intersec->getCoords()->getIJ(0,i),1e-12); - m1->decrRef(); m2->decrRef(); m_intersec->decrRef(); - resToM1->decrRef(); resToM2->decrRef(); -} - -void MEDCouplingBasicsTest5::testDAIBuildSubstractionOptimized1() -{ - const int tab1[7]={1,3,5,6,7,9,13}; - const int tab2[3]={3,5,9}; - const int tab3[3]={1,3,5}; - DataArrayInt *da1=DataArrayInt::New(); da1->useArray(tab1,false,CPP_DEALLOC,7,1); - DataArrayInt *da2=DataArrayInt::New(); da2->useArray(tab2,false,CPP_DEALLOC,3,1); - DataArrayInt *da3=DataArrayInt::New(); da3->useArray(tab3,false,CPP_DEALLOC,3,1); - DataArrayInt *da4=DataArrayInt::New(); da4->useArray(tab1,false,CPP_DEALLOC,7,1); - // - DataArrayInt *a=0; - a=da1->buildSubstractionOptimized(da2); - CPPUNIT_ASSERT_EQUAL(4,a->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(1,a->getNumberOfComponents()); - const int expected1_0[4]={1,6,7,13}; - CPPUNIT_ASSERT(std::equal(expected1_0,expected1_0+4,a->begin())); - a->decrRef(); - // - a=da1->buildSubstractionOptimized(da3); - CPPUNIT_ASSERT_EQUAL(4,a->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(1,a->getNumberOfComponents()); - const int expected2_0[4]={6,7,9,13}; - CPPUNIT_ASSERT(std::equal(expected2_0,expected2_0+4,a->begin())); - a->decrRef(); - // - a=da1->buildSubstractionOptimized(da4); - CPPUNIT_ASSERT_EQUAL(0,a->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(1,a->getNumberOfComponents()); - a->decrRef(); - // - da1->decrRef(); - da2->decrRef(); - da3->decrRef(); - da4->decrRef(); -} - -void MEDCouplingBasicsTest5::testDAIIsStrictlyMonotonic1() -{ - const int tab1[7]={1,3,5,6,7,9,13}; - DataArrayInt *da1=DataArrayInt::New(); da1->useArray(tab1,false,CPP_DEALLOC,7,1); - CPPUNIT_ASSERT(da1->isStrictlyMonotonic(true)); - da1->checkStrictlyMonotonic(true); - CPPUNIT_ASSERT(da1->isMonotonic(true)); - da1->checkMonotonic(true); - CPPUNIT_ASSERT(!da1->isStrictlyMonotonic(false)); - CPPUNIT_ASSERT_THROW(da1->checkStrictlyMonotonic(false),INTERP_KERNEL::Exception); - CPPUNIT_ASSERT(!da1->isMonotonic(false)); - CPPUNIT_ASSERT_THROW(da1->checkMonotonic(false),INTERP_KERNEL::Exception); - da1->decrRef(); - // - int tab2[7]={1,3,5,6,6,9,13}; - da1=DataArrayInt::New(); da1->useArray(tab2,false,CPP_DEALLOC,7,1); - CPPUNIT_ASSERT(!da1->isStrictlyMonotonic(true)); - CPPUNIT_ASSERT_THROW(da1->checkStrictlyMonotonic(true),INTERP_KERNEL::Exception); - CPPUNIT_ASSERT(da1->isMonotonic(true)); - da1->checkMonotonic(true); - CPPUNIT_ASSERT(!da1->isStrictlyMonotonic(false)); - CPPUNIT_ASSERT_THROW(da1->checkStrictlyMonotonic(false),INTERP_KERNEL::Exception); - CPPUNIT_ASSERT(!da1->isMonotonic(false)); - CPPUNIT_ASSERT_THROW(da1->checkMonotonic(false),INTERP_KERNEL::Exception); - da1->decrRef(); - // - const int tab3[7]={1,3,5,6,5,9,13}; - da1=DataArrayInt::New(); da1->useArray(tab3,false,CPP_DEALLOC,7,1); - CPPUNIT_ASSERT(!da1->isStrictlyMonotonic(true)); - CPPUNIT_ASSERT_THROW(da1->checkStrictlyMonotonic(true),INTERP_KERNEL::Exception); - CPPUNIT_ASSERT(!da1->isMonotonic(true)); - CPPUNIT_ASSERT_THROW(da1->checkMonotonic(true),INTERP_KERNEL::Exception); - CPPUNIT_ASSERT(!da1->isStrictlyMonotonic(false)); - CPPUNIT_ASSERT_THROW(da1->checkStrictlyMonotonic(false),INTERP_KERNEL::Exception); - CPPUNIT_ASSERT(!da1->isMonotonic(false)); - CPPUNIT_ASSERT_THROW(da1->checkMonotonic(false),INTERP_KERNEL::Exception); - da1->decrRef(); - // - const int tab4[7]={13,9,7,6,5,3,1}; - da1=DataArrayInt::New(); da1->useArray(tab4,false,CPP_DEALLOC,7,1); - CPPUNIT_ASSERT(!da1->isStrictlyMonotonic(true)); - CPPUNIT_ASSERT_THROW(da1->checkStrictlyMonotonic(true),INTERP_KERNEL::Exception); - CPPUNIT_ASSERT(!da1->isMonotonic(true)); - CPPUNIT_ASSERT_THROW(da1->checkMonotonic(true),INTERP_KERNEL::Exception); - CPPUNIT_ASSERT(da1->isStrictlyMonotonic(false)); - da1->checkStrictlyMonotonic(false); - CPPUNIT_ASSERT(da1->isMonotonic(false)); - da1->checkMonotonic(false); - da1->decrRef(); - // - const int tab5[7]={13,9,6,6,5,3,1}; - da1=DataArrayInt::New(); da1->useArray(tab5,false,CPP_DEALLOC,7,1); - CPPUNIT_ASSERT(!da1->isStrictlyMonotonic(true)); - CPPUNIT_ASSERT_THROW(da1->checkStrictlyMonotonic(true),INTERP_KERNEL::Exception); - CPPUNIT_ASSERT(!da1->isMonotonic(true)); - CPPUNIT_ASSERT_THROW(da1->checkMonotonic(true),INTERP_KERNEL::Exception); - CPPUNIT_ASSERT(!da1->isStrictlyMonotonic(false)); - CPPUNIT_ASSERT_THROW(da1->checkStrictlyMonotonic(false),INTERP_KERNEL::Exception); - CPPUNIT_ASSERT(da1->isMonotonic(false)); - da1->checkMonotonic(false); - da1->decrRef(); - // - const int tab6[7]={13,9,5,6,5,3,1}; - da1=DataArrayInt::New(); da1->useArray(tab6,false,CPP_DEALLOC,7,1); - CPPUNIT_ASSERT(!da1->isStrictlyMonotonic(true)); - CPPUNIT_ASSERT_THROW(da1->checkStrictlyMonotonic(true),INTERP_KERNEL::Exception); - CPPUNIT_ASSERT(!da1->isMonotonic(true)); - CPPUNIT_ASSERT_THROW(da1->checkMonotonic(true),INTERP_KERNEL::Exception); - CPPUNIT_ASSERT(!da1->isStrictlyMonotonic(false)); - CPPUNIT_ASSERT_THROW(da1->checkStrictlyMonotonic(false),INTERP_KERNEL::Exception); - CPPUNIT_ASSERT(!da1->isMonotonic(false)); - CPPUNIT_ASSERT_THROW(da1->checkMonotonic(false),INTERP_KERNEL::Exception); - da1->decrRef(); - // - da1=DataArrayInt::New(); da1->useArray(tab1,false,CPP_DEALLOC,0,1); - CPPUNIT_ASSERT(da1->isStrictlyMonotonic(true)); - da1->checkStrictlyMonotonic(true); - CPPUNIT_ASSERT(da1->isMonotonic(true)); - da1->checkMonotonic(true); - CPPUNIT_ASSERT(da1->isStrictlyMonotonic(false)); - da1->checkStrictlyMonotonic(false); - CPPUNIT_ASSERT(da1->isMonotonic(false)); - da1->checkMonotonic(false); - da1->decrRef(); - // - da1=DataArrayInt::New(); da1->useArray(tab1,false,CPP_DEALLOC,1,1); - CPPUNIT_ASSERT(da1->isStrictlyMonotonic(true)); - da1->checkStrictlyMonotonic(true); - CPPUNIT_ASSERT(da1->isMonotonic(true)); - da1->checkMonotonic(true); - CPPUNIT_ASSERT(da1->isStrictlyMonotonic(false)); - da1->checkStrictlyMonotonic(false); - CPPUNIT_ASSERT(da1->isMonotonic(false)); - da1->checkMonotonic(false); - da1->decrRef(); -} - -void MEDCouplingBasicsTest5::testSimplexize3() -{ - const int conn[24]={0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23}; - MEDCouplingUMesh *m=MEDCouplingUMesh::New("toto",3); - m->allocateCells(0); - m->insertNextCell(INTERP_KERNEL::NORM_TETRA4,4,conn+0); - m->insertNextCell(INTERP_KERNEL::NORM_HEXA8,8,conn+4); - m->insertNextCell(INTERP_KERNEL::NORM_HEXA8,8,conn+12); - m->insertNextCell(INTERP_KERNEL::NORM_TETRA4,4,conn+20); - const double coords[72]={0.,0.,0.,0.,1.,0.,1.,0.,0.,0.,0.,1.,2.,0.,0.,2.,1.,0.,3.,1.,0.,3.,0.,0.,2.,0.,1.,2.,1.,1.,3.,1.,1.,3.,0.,1.,4.,0.,0.,4.,1.,0.,5.,1.,0.,5.,0.,0.,4.,0.,1.,4.,1.,1.,5.,1.,1.,5.,0.,1.,6.,0.,0.,6.,1.,0.,7.,0.,0.,6.,0.,1.}; - DataArrayDouble *c=DataArrayDouble::New(); - c->useArray(coords,false,CPP_DEALLOC,24,3); - m->setCoords(c); - c->decrRef(); - m->checkCoherency2(); - // - MEDCouplingUMesh *m1=static_cast(m->deepCpy()); - DataArrayInt *d1=m1->simplexize(INTERP_KERNEL::PLANAR_FACE_5); - m1->checkCoherency2(); - MEDCouplingFieldDouble *f1=m1->getMeasureField(ON_CELLS); - const double vol1Expected[12]={1./6, 1./6, 1./6,1./6, 1./6, 1./3,1./6, 1./6, 1./6, 1./6, 1./3, 1./6}; - CPPUNIT_ASSERT_EQUAL(1,f1->getArray()->getNumberOfComponents()); - CPPUNIT_ASSERT_EQUAL(12,f1->getArray()->getNumberOfTuples()); - for(int i=0;i<12;i++) - CPPUNIT_ASSERT_DOUBLES_EQUAL(vol1Expected[i],f1->getIJ(i,0),1e-12); - const int connExpected1[60]={14,0,1,2,3,14,4,9,5,6,14,4,8,9,11,14,4,7,11,6,14,9,11,10,6,14,4,9,6,11,14,12,17,13,14,14,12,16,17,19,14,12,15,19,14,14,17,19,18,14,14,12,17,14,19,14,20,21,22,23}; - const int connIExpected1[13]={0,5,10,15,20,25,30,35,40,45,50,55,60}; - const int n2o1[12]={0,1,1,1,1,1,2,2,2,2,2,3}; - CPPUNIT_ASSERT_EQUAL(1,m1->getNodalConnectivity()->getNumberOfComponents()); - CPPUNIT_ASSERT_EQUAL(60,m1->getNodalConnectivity()->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(1,m1->getNodalConnectivityIndex()->getNumberOfComponents()); - CPPUNIT_ASSERT_EQUAL(13,m1->getNodalConnectivityIndex()->getNumberOfTuples()); - CPPUNIT_ASSERT(std::equal(connExpected1,connExpected1+60,m1->getNodalConnectivity()->begin())); - CPPUNIT_ASSERT(std::equal(connIExpected1,connIExpected1+13,m1->getNodalConnectivityIndex()->begin())); - CPPUNIT_ASSERT_EQUAL(1,d1->getNumberOfComponents()); - CPPUNIT_ASSERT_EQUAL(12,d1->getNumberOfTuples()); - CPPUNIT_ASSERT(std::equal(n2o1,n2o1+12,d1->begin())); - f1->decrRef(); - m1->decrRef(); - d1->decrRef(); - // - MEDCouplingUMesh *m2=static_cast(m->deepCpy()); - DataArrayInt *d2=m2->simplexize(INTERP_KERNEL::PLANAR_FACE_6); - m2->checkCoherency2(); - MEDCouplingFieldDouble *f2=m2->getMeasureField(ON_CELLS); - const double vol2Expected[14]={1./6, 1./6, 1./6,1./6, 1./6, 1./6,1./6,1./6, 1./6, 1./6, 1./6, 1./6,1./6,1./6}; - CPPUNIT_ASSERT_EQUAL(1,f2->getArray()->getNumberOfComponents()); - CPPUNIT_ASSERT_EQUAL(14,f2->getArray()->getNumberOfTuples()); - for(int i=0;i<14;i++) - CPPUNIT_ASSERT_DOUBLES_EQUAL(vol2Expected[i],f2->getIJ(i,0),1e-12); - const int connExpected2[70]={14,0,1,2,3,14,4,9,5,10,14,4,5,6,10,14,4,8,9,10,14,4,11,8,10,14,4,6,7,10,14,4,7,11,10,14,12,17,13,18,14,12,13,14,18,14,12,16,17,18,14,12,19,16,18,14,12,14,15,18,14,12,15,19,18,14,20,21,22,23}; - const int connIExpected2[15]={0,5,10,15,20,25,30,35,40,45,50,55,60,65,70}; - const int n2o2[14]={0,1,1,1,1,1,1,2,2,2,2,2,2,3}; - CPPUNIT_ASSERT_EQUAL(1,m2->getNodalConnectivity()->getNumberOfComponents()); - CPPUNIT_ASSERT_EQUAL(70,m2->getNodalConnectivity()->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(1,m2->getNodalConnectivityIndex()->getNumberOfComponents()); - CPPUNIT_ASSERT_EQUAL(15,m2->getNodalConnectivityIndex()->getNumberOfTuples()); - CPPUNIT_ASSERT(std::equal(connExpected2,connExpected2+70,m2->getNodalConnectivity()->begin())); - CPPUNIT_ASSERT(std::equal(connIExpected2,connIExpected2+15,m2->getNodalConnectivityIndex()->begin())); - CPPUNIT_ASSERT_EQUAL(1,d2->getNumberOfComponents()); - CPPUNIT_ASSERT_EQUAL(14,d2->getNumberOfTuples()); - CPPUNIT_ASSERT(std::equal(n2o2,n2o2+14,d2->begin())); - f2->decrRef(); - m2->decrRef(); - d2->decrRef(); - // - m->decrRef(); -} diff --git a/src/MEDCoupling/Test/MEDCouplingBasicsTest5.hxx b/src/MEDCoupling/Test/MEDCouplingBasicsTest5.hxx deleted file mode 100644 index a4cedd497..000000000 --- a/src/MEDCoupling/Test/MEDCouplingBasicsTest5.hxx +++ /dev/null @@ -1,124 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 -// 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 __MEDCOUPLINGBASICSTEST5_HXX__ -#define __MEDCOUPLINGBASICSTEST5_HXX__ - -#include "MEDCouplingBasicsTest.hxx" - -#include -#include - -namespace ParaMEDMEM -{ - class DataArrayDouble; - class MEDCouplingUMesh; - class MEDCouplingFieldDouble; - class MEDCouplingMultiFields; - - class MEDCouplingBasicsTest5 : public MEDCouplingBasicsTest - { - CPPUNIT_TEST_SUITE(MEDCouplingBasicsTest5); - CPPUNIT_TEST( testUMeshTessellate2D1 ); - CPPUNIT_TEST( testUMeshTessellate2DCurve1 ); - CPPUNIT_TEST( testIntersect2DMeshesTmp4 ); - CPPUNIT_TEST( testGetCellIdsCrossingPlane1 ); - CPPUNIT_TEST( testBuildSlice3D1 ); - CPPUNIT_TEST( testBuildSlice3DSurf1 ); - CPPUNIT_TEST( testDataArrayDoubleAdvSetting1 ); - CPPUNIT_TEST( testDataArrayIntAdvSetting1 ); - CPPUNIT_TEST( testBuildDescendingConnec2Of3DMesh1 ); - CPPUNIT_TEST( testAre2DCellsNotCorrectlyOriented1 ); - CPPUNIT_TEST( testDataArrayAbs1 ); - CPPUNIT_TEST( testGetValueOn3 ); - CPPUNIT_TEST( testGetNodeIdsOfCell2 ); - CPPUNIT_TEST( testRenumberNodesInConn1 ); - CPPUNIT_TEST( testComputeNeighborsOfCells1 ); - CPPUNIT_TEST( testCheckButterflyCellsBug1 ); - CPPUNIT_TEST( testDataArrayIntRange1 ); - CPPUNIT_TEST( testDataArrayDoubleGetMinMaxPerComponent1 ); - CPPUNIT_TEST( testDataArrayIntGetHashCode1 ); - CPPUNIT_TEST( testZipConnectivityPol1 ); - CPPUNIT_TEST( testConvexEnvelop2D1 ); - CPPUNIT_TEST( testDataArraySort1 ); - CPPUNIT_TEST( testPartitionBySpreadZone1 ); - CPPUNIT_TEST( testGiveCellsWithType1 ); - CPPUNIT_TEST( testBuildSlice3D2 ); - CPPUNIT_TEST( testComputeTupleIdsToSelectFromCellIds1 ); - CPPUNIT_TEST( testComputeSkin1 ); - CPPUNIT_TEST( testUMeshSetPartOfMySelf2 ); - CPPUNIT_TEST( testUnPolyze3 ); - CPPUNIT_TEST( testKrSpatialDiscretization1 ); - CPPUNIT_TEST( testDuplicateEachTupleNTimes1 ); - CPPUNIT_TEST( testIntersect2DMeshesTmp5 ); - CPPUNIT_TEST( testDAIBuildUnique1 ); - CPPUNIT_TEST( testDAIPartitionByDifferentValues1 ); - CPPUNIT_TEST( testDAICheckMonotonic1 ); - CPPUNIT_TEST( testIntersect2DMeshesTmp6 ); - CPPUNIT_TEST( testIntersect2DMeshesTmp7 ); - CPPUNIT_TEST( testDAIBuildSubstractionOptimized1 ); - CPPUNIT_TEST( testDAIIsStrictlyMonotonic1 ); - CPPUNIT_TEST( testSimplexize3 ); - CPPUNIT_TEST_SUITE_END(); - public: - void testUMeshTessellate2D1(); - void testUMeshTessellate2DCurve1(); - void testIntersect2DMeshesTmp4(); - void testGetCellIdsCrossingPlane1(); - void testBuildSlice3D1(); - void testBuildSlice3DSurf1(); - void testDataArrayDoubleAdvSetting1(); - void testDataArrayIntAdvSetting1(); - void testBuildDescendingConnec2Of3DMesh1(); - void testAre2DCellsNotCorrectlyOriented1(); - void testDataArrayAbs1(); - void testGetValueOn3(); - void testGetNodeIdsOfCell2(); - void testRenumberNodesInConn1(); - void testComputeNeighborsOfCells1(); - void testCheckButterflyCellsBug1(); - void testDataArrayIntRange1(); - void testDataArrayDoubleGetMinMaxPerComponent1(); - void testDataArrayIntGetHashCode1(); - void testZipConnectivityPol1(); - void testConvexEnvelop2D1(); - void testDataArraySort1(); - void testPartitionBySpreadZone1(); - void testGiveCellsWithType1(); - void testBuildSlice3D2(); - void testComputeTupleIdsToSelectFromCellIds1(); - void testComputeSkin1(); - void testUMeshSetPartOfMySelf2(); - void testUnPolyze3(); - void testKrSpatialDiscretization1(); - void testDuplicateEachTupleNTimes1(); - void testIntersect2DMeshesTmp5(); - void testDAIBuildUnique1(); - void testDAIPartitionByDifferentValues1(); - void testDAICheckMonotonic1(); - void testIntersect2DMeshesTmp6(); - void testIntersect2DMeshesTmp7(); - void testDAIBuildSubstractionOptimized1(); - void testDAIIsStrictlyMonotonic1(); - void testSimplexize3(); - }; -} - -#endif diff --git a/src/MEDCoupling/Test/MEDCouplingBasicsTestData1.hxx b/src/MEDCoupling/Test/MEDCouplingBasicsTestData1.hxx deleted file mode 100644 index fde75b35c..000000000 --- a/src/MEDCoupling/Test/MEDCouplingBasicsTestData1.hxx +++ /dev/null @@ -1,1167 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 -// 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) - -int connITT[201]={0, 50, 100, 150, 200, 250, 300, 350, 400, 450, 500, 550, 600, 650, 700, 750, 800, 850, 900, 950, 1000, 1029, 1058, 1087, 1116, 1145, 1174, 1203, - 1232, 1261, 1290, 1319, 1348, 1377, 1406, 1435, 1464, 1493, 1522, 1551, 1580, 1609, 1638, 1667, 1696, 1725, 1754, 1783, 1812, 1841, 1870, 1899, - 1928, 1957, 1986, 2015, 2044, 2073, 2102, 2131, 2160, 2189, 2218, 2247, 2276, 2305, 2334, 2363, 2392, 2421, 2450, 2479, 2508, 2537, 2566, 2595, - 2624, 2653, 2682, 2711, 2740, 2769, 2798, 2827, 2856, 2885, 2914, 2943, 2972, 3001, 3030, 3059, 3088, 3117, 3146, 3175, 3204, 3233, 3262, 3291, - 3320, 3349, 3378, 3407, 3436, 3465, 3494, 3523, 3552, 3581, 3610, 3639, 3668, 3697, 3726, 3755, 3784, 3813, 3842, 3871, 3900, 3929, 3958, 3987, - 4016, 4045, 4074, 4103, 4132, 4161, 4190, 4219, 4248, 4277, 4306, 4335, 4364, 4393, 4422, 4451, 4480, 4509, 4538, 4567, 4596, 4625, 4654, 4683, - 4712, 4741, 4770, 4799, 4828, 4857, 4886, 4915, 4944, 4973, 5002, 5031, 5060, 5089, 5118, 5147, 5176, 5205, 5234, 5263, 5292, 5321, 5350, 5379, - 5408, 5437, 5466, 5495, 5524, 5553, 5582, 5611, 5640, 5669, 5698, 5727, 5756, 5785, 5814, 5843, 5872, 5901, 5930, 5959, 5988, 6017, 6046, 6075, - 6104, 6133, 6162, 6191, 6220}; - int connTT[6220]={0, 1, 2, 3, 4, 5, 6, -1, 0, 7, 8, 1, -1, 1, 8, 9, 2, -1, 2, 9, 10, 3, -1, 3, 10, 11, 4, -1, 4, 11, 12, 5, -1, 5, 12, 13, 6, -1, 6, 13, 7, 0, -1, 7, 13, 12, 11, 10, 9, 8, 14, 15, 16, 17, 18, 19, - 20, -1, 14, 21, 22, 15, -1, 15, 22, 23, 16, -1, 16, 23, 24, 17, -1, 17, 24, 25, 18, -1, 18, 25, 26, 19, -1, 19, 26, 27, 20, -1, 20, 27, 21, 14, -1, 21, 27, 26, 25, 24, 23, 22, 28, 29, 30, 31, 32, - 33, 34, -1, 28, 35, 36, 29, -1, 29, 36, 37, 30, -1, 30, 37, 38, 31, -1, 31, 38, 39, 32, -1, 32, 39, 40, 33, -1, 33, 40, 41, 34, -1, 34, 41, 35, 28, -1, 35, 41, 40, 39, 38, 37, 36, 42, 43, 44, 45, - 46, 47, 48, -1, 42, 49, 50, 43, -1, 43, 50, 51, 44, -1, 44, 51, 52, 45, -1, 45, 52, 53, 46, -1, 46, 53, 54, 47, -1, 47, 54, 55, 48, -1, 48, 55, 49, 42, -1, 49, 55, 54, 53, 52, 51, 50, 56, 57, 58, - 59, 60, 61, 62, -1, 56, 63, 64, 57, -1, 57, 64, 65, 58, -1, 58, 65, 66, 59, -1, 59, 66, 67, 60, -1, 60, 67, 68, 61, -1, 61, 68, 69, 62, -1, 62, 69, 63, 56, -1, 63, 69, 68, 67, 66, 65, 64, 70, 71, - 72, 73, 74, 75, 76, -1, 70, 77, 78, 71, -1, 71, 78, 79, 72, -1, 72, 79, 80, 73, -1, 73, 80, 81, 74, -1, 74, 81, 82, 75, -1, 75, 82, 83, 76, -1, 76, 83, 77, 70, -1, 77, 83, 82, 81, 80, 79, 78, 84, - 85, 86, 87, 88, 89, 90, -1, 84, 91, 92, 85, -1, 85, 92, 93, 86, -1, 86, 93, 94, 87, -1, 87, 94, 95, 88, -1, 88, 95, 96, 89, -1, 89, 96, 97, 90, -1, 90, 97, 91, 84, -1, 91, 97, 96, 95, 94, 93, 92, - 98, 99, 100, 101, 102, 103, 104, -1, 98, 105, 106, 99, -1, 99, 106, 107, 100, -1, 100, 107, 108, 101, -1, 101, 108, 109, 102, -1, 102, 109, 110, 103, -1, 103, 110, 111, 104, -1, 104, 111, 105, 98, - -1, 105, 111, 110, 109, 108, 107, 106, 112, 113, 114, 115, 116, 117, 118, -1, 112, 119, 120, 113, -1, 113, 120, 121, 114, -1, 114, 121, 122, 115, -1, 115, 122, 123, 116, -1, 116, 123, 124, 117, -1, - 117, 124, 125, 118, -1, 118, 125, 119, 112, -1, 119, 125, 124, 123, 122, 121, 120, 126, 127, 128, 129, 130, 131, 132, -1, 126, 133, 134, 127, -1, 127, 134, 135, 128, -1, 128, 135, 136, 129, -1, 129, - 136, 137, 130, -1, 130, 137, 138, 131, -1, 131, 138, 139, 132, -1, 132, 139, 133, 126, -1, 133, 139, 138, 137, 136, 135, 134, 140, 141, 142, 143, 144, 145, 146, -1, 140, 147, 148, 141, -1, 141, 148, - 149, 142, -1, 142, 149, 150, 143, -1, 143, 150, 151, 144, -1, 144, 151, 152, 145, -1, 145, 152, 153, 146, -1, 146, 153, 147, 140, -1, 147, 153, 152, 151, 150, 149, 148, 154, 155, 156, 157, 158, 159, - 160, -1, 154, 161, 162, 155, -1, 155, 162, 163, 156, -1, 156, 163, 164, 157, -1, 157, 164, 165, 158, -1, 158, 165, 166, 159, -1, 159, 166, 167, 160, -1, 160, 167, 161, 154, -1, 161, 167, 166, 165, - 164, 163, 162, 168, 169, 170, 171, 172, 173, 174, -1, 168, 175, 176, 169, -1, 169, 176, 177, 170, -1, 170, 177, 178, 171, -1, 171, 178, 179, 172, -1, 172, 179, 180, 173, -1, 173, 180, 181, 174, -1, - 174, 181, 175, 168, -1, 175, 181, 180, 179, 178, 177, 176, 182, 183, 184, 185, 186, 187, 188, -1, 182, 189, 190, 183, -1, 183, 190, 191, 184, -1, 184, 191, 192, 185, -1, 185, 192, 193, 186, -1, 186, - 193, 194, 187, -1, 187, 194, 195, 188, -1, 188, 195, 189, 182, -1, 189, 195, 194, 193, 192, 191, 190, 196, 197, 198, 199, 200, 201, 202, -1, 196, 203, 204, 197, -1, 197, 204, 205, 198, -1, 198, 205, - 206, 199, -1, 199, 206, 207, 200, -1, 200, 207, 208, 201, -1, 201, 208, 209, 202, -1, 202, 209, 203, 196, -1, 203, 209, 208, 207, 206, 205, 204, 210, 211, 212, 213, 214, 215, 216, -1, 210, 217, 218, - 211, -1, 211, 218, 219, 212, -1, 212, 219, 220, 213, -1, 213, 220, 221, 214, -1, 214, 221, 222, 215, -1, 215, 222, 223, 216, -1, 216, 223, 217, 210, -1, 217, 223, 222, 221, 220, 219, 218, 224, 225, - 226, 227, 228, 229, 230, -1, 224, 231, 232, 225, -1, 225, 232, 233, 226, -1, 226, 233, 234, 227, -1, 227, 234, 235, 228, -1, 228, 235, 236, 229, -1, 229, 236, 237, 230, -1, 230, 237, 231, 224, -1, - 231, 237, 236, 235, 234, 233, 232, 238, 239, 240, 241, 242, 243, 244, -1, 238, 245, 246, 239, -1, 239, 246, 247, 240, -1, 240, 247, 248, 241, -1, 241, 248, 249, 242, -1, 242, 249, 250, 243, -1, 243, - 250, 251, 244, -1, 244, 251, 245, 238, -1, 245, 251, 250, 249, 248, 247, 246, 252, 253, 254, 255, 256, 257, 258, -1, 252, 259, 260, 253, -1, 253, 260, 261, 254, -1, 254, 261, 262, 255, -1, 255, 262, - 263, 256, -1, 256, 263, 264, 257, -1, 257, 264, 265, 258, -1, 258, 265, 259, 252, -1, 259, 265, 264, 263, 262, 261, 260, 266, 267, 268, 269, 270, 271, 272, -1, 266, 273, 274, 267, -1, 267, 274, 275, - 268, -1, 268, 275, 276, 269, -1, 269, 276, 277, 270, -1, 270, 277, 278, 271, -1, 271, 278, 279, 272, -1, 272, 279, 273, 266, -1, 273, 279, 278, 277, 276, 275, 274, 280, 281, 282, 283, -1, 280, 284, - 285, 281, -1, 281, 285, 286, 282, -1, 282, 286, 287, 283, -1, 283, 287, 284, 280, -1, 284, 287, 286, 285, 288, 289, 290, 291, -1, 288, 292, 293, 289, -1, 289, 293, 294, 290, -1, 290, 294, 295, 291, - -1, 291, 295, 292, 288, -1, 292, 295, 294, 293, 296, 297, 298, 299, -1, 296, 300, 301, 297, -1, 297, 301, 302, 298, -1, 298, 302, 303, 299, -1, 299, 303, 300, 296, -1, 300, 303, 302, 301, 304, 305, - 306, 307, -1, 304, 308, 309, 305, -1, 305, 309, 310, 306, -1, 306, 310, 311, 307, -1, 307, 311, 308, 304, -1, 308, 311, 310, 309, 312, 313, 314, 315, -1, 312, 316, 317, 313, -1, 313, 317, 318, 314, - -1, 314, 318, 319, 315, -1, 315, 319, 316, 312, -1, 316, 319, 318, 317, 320, 321, 322, 323, -1, 320, 324, 325, 321, -1, 321, 325, 326, 322, -1, 322, 326, 327, 323, -1, 323, 327, 324, 320, -1, 324, - 327, 326, 325, 328, 329, 330, 331, -1, 328, 332, 333, 329, -1, 329, 333, 334, 330, -1, 330, 334, 335, 331, -1, 331, 335, 332, 328, -1, 332, 335, 334, 333, 336, 337, 338, 339, -1, 336, 340, 341, 337, - -1, 337, 341, 342, 338, -1, 338, 342, 343, 339, -1, 339, 343, 340, 336, -1, 340, 343, 342, 341, 344, 345, 346, 347, -1, 344, 348, 349, 345, -1, 345, 349, 350, 346, -1, 346, 350, 351, 347, -1, 347, - 351, 348, 344, -1, 348, 351, 350, 349, 352, 353, 354, 355, -1, 352, 356, 357, 353, -1, 353, 357, 358, 354, -1, 354, 358, 359, 355, -1, 355, 359, 356, 352, -1, 356, 359, 358, 357, 360, 361, 362, 363, - -1, 360, 364, 365, 361, -1, 361, 365, 366, 362, -1, 362, 366, 367, 363, -1, 363, 367, 364, 360, -1, 364, 367, 366, 365, 368, 369, 370, 371, -1, 368, 372, 373, 369, -1, 369, 373, 374, 370, -1, 370, - 374, 375, 371, -1, 371, 375, 372, 368, -1, 372, 375, 374, 373, 376, 377, 378, 379, -1, 376, 380, 381, 377, -1, 377, 381, 382, 378, -1, 378, 382, 383, 379, -1, 379, 383, 380, 376, -1, 380, 383, 382, - 381, 384, 385, 386, 387, -1, 384, 388, 389, 385, -1, 385, 389, 390, 386, -1, 386, 390, 391, 387, -1, 387, 391, 388, 384, -1, 388, 391, 390, 389, 392, 393, 394, 395, -1, 392, 396, 397, 393, -1, 393, - 397, 398, 394, -1, 394, 398, 399, 395, -1, 395, 399, 396, 392, -1, 396, 399, 398, 397, 400, 401, 402, 403, -1, 400, 404, 405, 401, -1, 401, 405, 406, 402, -1, 402, 406, 407, 403, -1, 403, 407, 404, - 400, -1, 404, 407, 406, 405, 408, 409, 410, 411, -1, 408, 412, 413, 409, -1, 409, 413, 414, 410, -1, 410, 414, 415, 411, -1, 411, 415, 412, 408, -1, 412, 415, 414, 413, 416, 417, 418, 419, -1, 416, - 420, 421, 417, -1, 417, 421, 422, 418, -1, 418, 422, 423, 419, -1, 419, 423, 420, 416, -1, 420, 423, 422, 421, 424, 425, 426, 427, -1, 424, 428, 429, 425, -1, 425, 429, 430, 426, -1, 426, 430, 431, - 427, -1, 427, 431, 428, 424, -1, 428, 431, 430, 429, 432, 433, 434, 435, -1, 432, 436, 437, 433, -1, 433, 437, 438, 434, -1, 434, 438, 439, 435, -1, 435, 439, 436, 432, -1, 436, 439, 438, 437, 440, - 441, 442, 443, -1, 440, 444, 445, 441, -1, 441, 445, 446, 442, -1, 442, 446, 447, 443, -1, 443, 447, 444, 440, -1, 444, 447, 446, 445, 448, 449, 450, 451, -1, 448, 452, 453, 449, -1, 449, 453, 454, - 450, -1, 450, 454, 455, 451, -1, 451, 455, 452, 448, -1, 452, 455, 454, 453, 456, 457, 458, 459, -1, 456, 460, 461, 457, -1, 457, 461, 462, 458, -1, 458, 462, 463, 459, -1, 459, 463, 460, 456, -1, - 460, 463, 462, 461, 464, 465, 466, 467, -1, 464, 468, 469, 465, -1, 465, 469, 470, 466, -1, 466, 470, 471, 467, -1, 467, 471, 468, 464, -1, 468, 471, 470, 469, 472, 473, 474, 475, -1, 472, 476, 477, - 473, -1, 473, 477, 478, 474, -1, 474, 478, 479, 475, -1, 475, 479, 476, 472, -1, 476, 479, 478, 477, 480, 481, 482, 483, -1, 480, 484, 485, 481, -1, 481, 485, 486, 482, -1, 482, 486, 487, 483, -1, - 483, 487, 484, 480, -1, 484, 487, 486, 485, 488, 489, 490, 491, -1, 488, 492, 493, 489, -1, 489, 493, 494, 490, -1, 490, 494, 495, 491, -1, 491, 495, 492, 488, -1, 492, 495, 494, 493, 496, 497, 498, - 499, -1, 496, 500, 501, 497, -1, 497, 501, 502, 498, -1, 498, 502, 503, 499, -1, 499, 503, 500, 496, -1, 500, 503, 502, 501, 504, 505, 506, 507, -1, 504, 508, 509, 505, -1, 505, 509, 510, 506, -1, 506, - 510, 511, 507, -1, 507, 511, 508, 504, -1, 508, 511, 510, 509, 512, 513, 514, 515, -1, 512, 516, 517, 513, -1, 513, 517, 518, 514, -1, 514, 518, 519, 515, -1, 515, 519, 516, 512, -1, 516, 519, 518, 517, - 520, 521, 522, 523, -1, 520, 524, 525, 521, -1, 521, 525, 526, 522, -1, 522, 526, 527, 523, -1, 523, 527, 524, 520, -1, 524, 527, 526, 525, 528, 529, 530, 531, -1, 528, 532, 533, 529, -1, 529, 533, - 534, 530, -1, 530, 534, 535, 531, -1, 531, 535, 532, 528, -1, 532, 535, 534, 533, 536, 537, 538, 539, -1, 536, 540, 541, 537, -1, 537, 541, 542, 538, -1, 538, 542, 543, 539, -1, 539, 543, 540, 536, - -1, 540, 543, 542, 541, 544, 545, 546, 547, -1, 544, 548, 549, 545, -1, 545, 549, 550, 546, -1, 546, 550, 551, 547, -1, 547, 551, 548, 544, -1, 548, 551, 550, 549, 552, 553, 554, 555, -1, 552, 556, - 557, 553, -1, 553, 557, 558, 554, -1, 554, 558, 559, 555, -1, 555, 559, 556, 552, -1, 556, 559, 558, 557, 560, 561, 562, 563, -1, 560, 564, 565, 561, -1, 561, 565, 566, 562, -1, 562, 566, 567, 563, - -1, 563, 567, 564, 560, -1, 564, 567, 566, 565, 568, 569, 570, 571, -1, 568, 572, 573, 569, -1, 569, 573, 574, 570, -1, 570, 574, 575, 571, -1, 571, 575, 572, 568, -1, 572, 575, 574, 573, 576, 577, - 578, 579, -1, 576, 580, 581, 577, -1, 577, 581, 582, 578, -1, 578, 582, 583, 579, -1, 579, 583, 580, 576, -1, 580, 583, 582, 581, 584, 585, 586, 587, -1, 584, 588, 589, 585, -1, 585, 589, 590, 586, - -1, 586, 590, 591, 587, -1, 587, 591, 588, 584, -1, 588, 591, 590, 589, 592, 593, 594, 595, -1, 592, 596, 597, 593, -1, 593, 597, 598, 594, -1, 594, 598, 599, 595, -1, 595, 599, 596, 592, -1, 596, - 599, 598, 597, 600, 601, 602, 603, -1, 600, 604, 605, 601, -1, 601, 605, 606, 602, -1, 602, 606, 607, 603, -1, 603, 607, 604, 600, -1, 604, 607, 606, 605, 608, 609, 610, 611, -1, 608, 612, 613, 609, - -1, 609, 613, 614, 610, -1, 610, 614, 615, 611, -1, 611, 615, 612, 608, -1, 612, 615, 614, 613, 616, 617, 618, 619, -1, 616, 620, 621, 617, -1, 617, 621, 622, 618, -1, 618, 622, 623, 619, -1, 619, - 623, 620, 616, -1, 620, 623, 622, 621, 624, 625, 626, 627, -1, 624, 628, 629, 625, -1, 625, 629, 630, 626, -1, 626, 630, 631, 627, -1, 627, 631, 628, 624, -1, 628, 631, 630, 629, 632, 633, 634, 635, - -1, 632, 636, 637, 633, -1, 633, 637, 638, 634, -1, 634, 638, 639, 635, -1, 635, 639, 636, 632, -1, 636, 639, 638, 637, 640, 641, 642, 643, -1, 640, 644, 645, 641, -1, 641, 645, 646, 642, -1, 642, - 646, 647, 643, -1, 643, 647, 644, 640, -1, 644, 647, 646, 645, 648, 649, 650, 651, -1, 648, 652, 653, 649, -1, 649, 653, 654, 650, -1, 650, 654, 655, 651, -1, 651, 655, 652, 648, -1, 652, 655, 654, - 653, 656, 657, 658, 659, -1, 656, 660, 661, 657, -1, 657, 661, 662, 658, -1, 658, 662, 663, 659, -1, 659, 663, 660, 656, -1, 660, 663, 662, 661, 664, 665, 666, 667, -1, 664, 668, 669, 665, -1, 665, - 669, 670, 666, -1, 666, 670, 671, 667, -1, 667, 671, 668, 664, -1, 668, 671, 670, 669, 672, 673, 674, 675, -1, 672, 676, 677, 673, -1, 673, 677, 678, 674, -1, 674, 678, 679, 675, -1, 675, 679, 676, - 672, -1, 676, 679, 678, 677, 680, 681, 682, 683, -1, 680, 684, 685, 681, -1, 681, 685, 686, 682, -1, 682, 686, 687, 683, -1, 683, 687, 684, 680, -1, 684, 687, 686, 685, 688, 689, 690, 691, -1, 688, - 692, 693, 689, -1, 689, 693, 694, 690, -1, 690, 694, 695, 691, -1, 691, 695, 692, 688, -1, 692, 695, 694, 693, 696, 697, 698, 699, -1, 696, 700, 701, 697, -1, 697, 701, 702, 698, -1, 698, 702, 703, - 699, -1, 699, 703, 700, 696, -1, 700, 703, 702, 701, 704, 705, 706, 707, -1, 704, 708, 709, 705, -1, 705, 709, 710, 706, -1, 706, 710, 711, 707, -1, 707, 711, 708, 704, -1, 708, 711, 710, 709, 712, - 713, 714, 715, -1, 712, 716, 717, 713, -1, 713, 717, 718, 714, -1, 714, 718, 719, 715, -1, 715, 719, 716, 712, -1, 716, 719, 718, 717, 720, 721, 722, 723, -1, 720, 724, 725, 721, -1, 721, 725, 726, - 722, -1, 722, 726, 727, 723, -1, 723, 727, 724, 720, -1, 724, 727, 726, 725, 728, 729, 730, 731, -1, 728, 732, 733, 729, -1, 729, 733, 734, 730, -1, 730, 734, 735, 731, -1, 731, 735, 732, 728, -1, - 732, 735, 734, 733, 736, 737, 738, 739, -1, 736, 740, 741, 737, -1, 737, 741, 742, 738, -1, 738, 742, 743, 739, -1, 739, 743, 740, 736, -1, 740, 743, 742, 741, 744, 745, 746, 747, -1, 744, 748, 749, - 745, -1, 745, 749, 750, 746, -1, 746, 750, 751, 747, -1, 747, 751, 748, 744, -1, 748, 751, 750, 749, 752, 753, 754, 755, -1, 752, 756, 757, 753, -1, 753, 757, 758, 754, -1, 754, 758, 759, 755, -1, - 755, 759, 756, 752, -1, 756, 759, 758, 757, 760, 761, 762, 763, -1, 760, 764, 765, 761, -1, 761, 765, 766, 762, -1, 762, 766, 767, 763, -1, 763, 767, 764, 760, -1, 764, 767, 766, 765, 768, 769, 770, - 771, -1, 768, 772, 773, 769, -1, 769, 773, 774, 770, -1, 770, 774, 775, 771, -1, 771, 775, 772, 768, -1, 772, 775, 774, 773, 776, 777, 778, 779, -1, 776, 780, 781, 777, -1, 777, 781, 782, 778, -1, - 778, 782, 783, 779, -1, 779, 783, 780, 776, -1, 780, 783, 782, 781, 784, 785, 786, 787, -1, 784, 788, 789, 785, -1, 785, 789, 790, 786, -1, 786, 790, 791, 787, -1, 787, 791, 788, 784, -1, 788, 791, - 790, 789, 792, 793, 794, 795, -1, 792, 796, 797, 793, -1, 793, 797, 798, 794, -1, 794, 798, 799, 795, -1, 795, 799, 796, 792, -1, 796, 799, 798, 797, 800, 801, 802, 803, -1, 800, 804, 805, 801, -1, - 801, 805, 806, 802, -1, 802, 806, 807, 803, -1, 803, 807, 804, 800, -1, 804, 807, 806, 805, 808, 809, 810, 811, -1, 808, 812, 813, 809, -1, 809, 813, 814, 810, -1, 810, 814, 815, 811, -1, 811, 815, - 812, 808, -1, 812, 815, 814, 813, 816, 817, 818, 819, -1, 816, 820, 821, 817, -1, 817, 821, 822, 818, -1, 818, 822, 823, 819, -1, 819, 823, 820, 816, -1, 820, 823, 822, 821, 824, 825, 826, 827, -1, - 824, 828, 829, 825, -1, 825, 829, 830, 826, -1, 826, 830, 831, 827, -1, 827, 831, 828, 824, -1, 828, 831, 830, 829, 832, 833, 834, 835, -1, 832, 836, 837, 833, -1, 833, 837, 838, 834, -1, 834, 838, - 839, 835, -1, 835, 839, 836, 832, -1, 836, 839, 838, 837, 840, 841, 842, 843, -1, 840, 844, 845, 841, -1, 841, 845, 846, 842, -1, 842, 846, 847, 843, -1, 843, 847, 844, 840, -1, 844, 847, 846, 845, - 848, 849, 850, 851, -1, 848, 852, 853, 849, -1, 849, 853, 854, 850, -1, 850, 854, 855, 851, -1, 851, 855, 852, 848, -1, 852, 855, 854, 853, 856, 857, 858, 859, -1, 856, 860, 861, 857, -1, 857, 861, - 862, 858, -1, 858, 862, 863, 859, -1, 859, 863, 860, 856, -1, 860, 863, 862, 861, 864, 865, 866, 867, -1, 864, 868, 869, 865, -1, 865, 869, 870, 866, -1, 866, 870, 871, 867, -1, 867, 871, 868, 864, - -1, 868, 871, 870, 869, 872, 873, 874, 875, -1, 872, 876, 877, 873, -1, 873, 877, 878, 874, -1, 874, 878, 879, 875, -1, 875, 879, 876, 872, -1, 876, 879, 878, 877, 880, 881, 882, 883, -1, 880, 884, - 885, 881, -1, 881, 885, 886, 882, -1, 882, 886, 887, 883, -1, 883, 887, 884, 880, -1, 884, 887, 886, 885, 888, 889, 890, 891, -1, 888, 892, 893, 889, -1, 889, 893, 894, 890, -1, 890, 894, 895, 891, - -1, 891, 895, 892, 888, -1, 892, 895, 894, 893, 896, 897, 898, 899, -1, 896, 900, 901, 897, -1, 897, 901, 902, 898, -1, 898, 902, 903, 899, -1, 899, 903, 900, 896, -1, 900, 903, 902, 901, 904, 905, - 906, 907, -1, 904, 908, 909, 905, -1, 905, 909, 910, 906, -1, 906, 910, 911, 907, -1, 907, 911, 908, 904, -1, 908, 911, 910, 909, 912, 913, 914, 915, -1, 912, 916, 917, 913, -1, 913, 917, 918, 914, - -1, 914, 918, 919, 915, -1, 915, 919, 916, 912, -1, 916, 919, 918, 917, 920, 921, 922, 923, -1, 920, 924, 925, 921, -1, 921, 925, 926, 922, -1, 922, 926, 927, 923, -1, 923, 927, 924, 920, -1, 924, - 927, 926, 925, 928, 929, 930, 931, -1, 928, 932, 933, 929, -1, 929, 933, 934, 930, -1, 930, 934, 935, 931, -1, 931, 935, 932, 928, -1, 932, 935, 934, 933, 936, 937, 938, 939, -1, 936, 940, 941, 937, - -1, 937, 941, 942, 938, -1, 938, 942, 943, 939, -1, 939, 943, 940, 936, -1, 940, 943, 942, 941, 944, 945, 946, 947, -1, 944, 948, 949, 945, -1, 945, 949, 950, 946, -1, 946, 950, 951, 947, -1, 947, - 951, 948, 944, -1, 948, 951, 950, 949, 952, 953, 954, 955, -1, 952, 956, 957, 953, -1, 953, 957, 958, 954, -1, 954, 958, 959, 955, -1, 955, 959, 956, 952, -1, 956, 959, 958, 957, 960, 961, 962, 963, - -1, 960, 964, 965, 961, -1, 961, 965, 966, 962, -1, 962, 966, 967, 963, -1, 963, 967, 964, 960, -1, 964, 967, 966, 965, 968, 969, 970, 971, -1, 968, 972, 973, 969, -1, 969, 973, 974, 970, -1, 970, - 974, 975, 971, -1, 971, 975, 972, 968, -1, 972, 975, 974, 973, 976, 977, 978, 979, -1, 976, 980, 981, 977, -1, 977, 981, 982, 978, -1, 978, 982, 983, 979, -1, 979, 983, 980, 976, -1, 980, 983, 982, - 981, 984, 985, 986, 987, -1, 984, 988, 989, 985, -1, 985, 989, 990, 986, -1, 986, 990, 991, 987, -1, 987, 991, 988, 984, -1, 988, 991, 990, 989, 992, 993, 994, 995, -1, 992, 996, 997, 993, -1, 993, - 997, 998, 994, -1, 994, 998, 999, 995, -1, 995, 999, 996, 992, -1, 996, 999, 998, 997, 1000, 1001, 1002, 1003, -1, 1000, 1004, 1005, 1001, -1, 1001, 1005, 1006, 1002, -1, 1002, 1006, 1007, 1003, - -1, 1003, 1007, 1004, 1000, -1, 1004, 1007, 1006, 1005, 1008, 1009, 1010, 1011, -1, 1008, 1012, 1013, 1009, -1, 1009, 1013, 1014, 1010, -1, 1010, 1014, 1015, 1011, -1, 1011, 1015, 1012, 1008, -1, - 1012, 1015, 1014, 1013, 1016, 1017, 1018, 1019, -1, 1016, 1020, 1021, 1017, -1, 1017, 1021, 1022, 1018, -1, 1018, 1022, 1023, 1019, -1, 1019, 1023, 1020, 1016, -1, 1020, 1023, 1022, 1021, 1024, - 1025, 1026, 1027, -1, 1024, 1028, 1029, 1025, -1, 1025, 1029, 1030, 1026, -1, 1026, 1030, 1031, 1027, -1, 1027, 1031, 1028, 1024, -1, 1028, 1031, 1030, 1029, 1032, 1033, 1034, 1035, -1, 1032, - 1036, 1037, 1033, -1, 1033, 1037, 1038, 1034, -1, 1034, 1038, 1039, 1035, -1, 1035, 1039, 1036, 1032, -1, 1036, 1039, 1038, 1037, 1040, 1041, 1042, 1043, -1, 1040, 1044, 1045, 1041, -1, 1041, - 1045, 1046, 1042, -1, 1042, 1046, 1047, 1043, -1, 1043, 1047, 1044, 1040, -1, 1044, 1047, 1046, 1045, 1048, 1049, 1050, 1051, -1, 1048, 1052, 1053, 1049, -1, 1049, 1053, 1054, 1050, -1, 1050, - 1054, 1055, 1051, -1, 1051, 1055, 1052, 1048, -1, 1052, 1055, 1054, 1053, 1056, 1057, 1058, 1059, -1, 1056, 1060, 1061, 1057, -1, 1057, 1061, 1062, 1058, -1, 1058, 1062, 1063, 1059, -1, 1059, - 1063, 1060, 1056, -1, 1060, 1063, 1062, 1061, 1064, 1065, 1066, 1067, -1, 1064, 1068, 1069, 1065, -1, 1065, 1069, 1070, 1066, -1, 1066, 1070, 1071, 1067, -1, 1067, 1071, 1068, 1064, -1, 1068, - 1071, 1070, 1069, 1072, 1073, 1074, 1075, -1, 1072, 1076, 1077, 1073, -1, 1073, 1077, 1078, 1074, -1, 1074, 1078, 1079, 1075, -1, 1075, 1079, 1076, 1072, -1, 1076, 1079, 1078, 1077, 1080, 1081, - 1082, 1083, -1, 1080, 1084, 1085, 1081, -1, 1081, 1085, 1086, 1082, -1, 1082, 1086, 1087, 1083, -1, 1083, 1087, 1084, 1080, -1, 1084, 1087, 1086, 1085, 1088, 1089, 1090, 1091, -1, 1088, 1092, - 1093, 1089, -1, 1089, 1093, 1094, 1090, -1, 1090, 1094, 1095, 1091, -1, 1091, 1095, 1092, 1088, -1, 1092, 1095, 1094, 1093, 1096, 1097, 1098, 1099, -1, 1096, 1100, 1101, 1097, -1, 1097, 1101, - 1102, 1098, -1, 1098, 1102, 1103, 1099, -1, 1099, 1103, 1100, 1096, -1, 1100, 1103, 1102, 1101, 1104, 1105, 1106, 1107, -1, 1104, 1108, 1109, 1105, -1, 1105, 1109, 1110, 1106, -1, 1106, 1110, - 1111, 1107, -1, 1107, 1111, 1108, 1104, -1, 1108, 1111, 1110, 1109, 1112, 1113, 1114, 1115, -1, 1112, 1116, 1117, 1113, -1, 1113, 1117, 1118, 1114, -1, 1114, 1118, 1119, 1115, -1, 1115, 1119, - 1116, 1112, -1, 1116, 1119, 1118, 1117, 1120, 1121, 1122, 1123, -1, 1120, 1124, 1125, 1121, -1, 1121, 1125, 1126, 1122, -1, 1122, 1126, 1127, 1123, -1, 1123, 1127, 1124, 1120, -1, 1124, 1127, - 1126, 1125, 1128, 1129, 1130, 1131, -1, 1128, 1132, 1133, 1129, -1, 1129, 1133, 1134, 1130, -1, 1130, 1134, 1135, 1131, -1, 1131, 1135, 1132, 1128, -1, 1132, 1135, 1134, 1133, 1136, 1137, 1138, - 1139, -1, 1136, 1140, 1141, 1137, -1, 1137, 1141, 1142, 1138, -1, 1138, 1142, 1143, 1139, -1, 1139, 1143, 1140, 1136, -1, 1140, 1143, 1142, 1141, 1144, 1145, 1146, 1147, -1, 1144, 1148, 1149, - 1145, -1, 1145, 1149, 1150, 1146, -1, 1146, 1150, 1151, 1147, -1, 1147, 1151, 1148, 1144, -1, 1148, 1151, 1150, 1149, 1152, 1153, 1154, 1155, -1, 1152, 1156, 1157, 1153, -1, 1153, 1157, 1158, - 1154, -1, 1154, 1158, 1159, 1155, -1, 1155, 1159, 1156, 1152, -1, 1156, 1159, 1158, 1157, 1160, 1161, 1162, 1163, -1, 1160, 1164, 1165, 1161, -1, 1161, 1165, 1166, 1162, -1, 1162, 1166, 1167, - 1163, -1, 1163, 1167, 1164, 1160, -1, 1164, 1167, 1166, 1165, 1168, 1169, 1170, 1171, -1, 1168, 1172, 1173, 1169, -1, 1169, 1173, 1174, 1170, -1, 1170, 1174, 1175, 1171, -1, 1171, 1175, 1172, - 1168, -1, 1172, 1175, 1174, 1173, 1176, 1177, 1178, 1179, -1, 1176, 1180, 1181, 1177, -1, 1177, 1181, 1182, 1178, -1, 1178, 1182, 1183, 1179, -1, 1179, 1183, 1180, 1176, -1, 1180, 1183, 1182, - 1181, 1184, 1185, 1186, 1187, -1, 1184, 1188, 1189, 1185, -1, 1185, 1189, 1190, 1186, -1, 1186, 1190, 1191, 1187, -1, 1187, 1191, 1188, 1184, -1, 1188, 1191, 1190, 1189, 1192, 1193, 1194, 1195, - -1, 1192, 1196, 1197, 1193, -1, 1193, 1197, 1198, 1194, -1, 1194, 1198, 1199, 1195, -1, 1195, 1199, 1196, 1192, -1, 1196, 1199, 1198, 1197, 1200, 1201, 1202, 1203, -1, 1200, 1204, 1205, 1201, - -1, 1201, 1205, 1206, 1202, -1, 1202, 1206, 1207, 1203, -1, 1203, 1207, 1204, 1200, -1, 1204, 1207, 1206, 1205, 1208, 1209, 1210, 1211, -1, 1208, 1212, 1213, 1209, -1, 1209, 1213, 1214, 1210, - -1, 1210, 1214, 1215, 1211, -1, 1211, 1215, 1212, 1208, -1, 1212, 1215, 1214, 1213, 1216, 1217, 1218, 1219, -1, 1216, 1220, 1221, 1217, -1, 1217, 1221, 1222, 1218, -1, 1218, 1222, 1223, 1219, - -1, 1219, 1223, 1220, 1216, -1, 1220, 1223, 1222, 1221, 1224, 1225, 1226, 1227, -1, 1224, 1228, 1229, 1225, -1, 1225, 1229, 1230, 1226, -1, 1226, 1230, 1231, 1227, -1, 1227, 1231, 1228, 1224, - -1, 1228, 1231, 1230, 1229, 1232, 1233, 1234, 1235, -1, 1232, 1236, 1237, 1233, -1, 1233, 1237, 1238, 1234, -1, 1234, 1238, 1239, 1235, -1, 1235, 1239, 1236, 1232, -1, 1236, 1239, 1238, 1237, - 1240, 1241, 1242, 1243, -1, 1240, 1244, 1245, 1241, -1, 1241, 1245, 1246, 1242, -1, 1242, 1246, 1247, 1243, -1, 1243, 1247, 1244, 1240, -1, 1244, 1247, 1246, 1245, 1248, 1249, 1250, 1251, -1, - 1248, 1252, 1253, 1249, -1, 1249, 1253, 1254, 1250, -1, 1250, 1254, 1255, 1251, -1, 1251, 1255, 1252, 1248, -1, 1252, 1255, 1254, 1253, 1256, 1257, 1258, 1259, -1, 1256, 1260, 1261, 1257, -1, - 1257, 1261, 1262, 1258, -1, 1258, 1262, 1263, 1259, -1, 1259, 1263, 1260, 1256, -1, 1260, 1263, 1262, 1261, 1264, 1265, 1266, 1267, -1, 1264, 1268, 1269, 1265, -1, 1265, 1269, 1270, 1266, -1, - 1266, 1270, 1271, 1267, -1, 1267, 1271, 1268, 1264, -1, 1268, 1271, 1270, 1269, 1272, 1273, 1274, 1275, -1, 1272, 1276, 1277, 1273, -1, 1273, 1277, 1278, 1274, -1, 1274, 1278, 1279, 1275, -1, - 1275, 1279, 1276, 1272, -1, 1276, 1279, 1278, 1277, 1280, 1281, 1282, 1283, -1, 1280, 1284, 1285, 1281, -1, 1281, 1285, 1286, 1282, -1, 1282, 1286, 1287, 1283, -1, 1283, 1287, 1284, 1280, -1, - 1284, 1287, 1286, 1285, 1288, 1289, 1290, 1291, -1, 1288, 1292, 1293, 1289, -1, 1289, 1293, 1294, 1290, -1, 1290, 1294, 1295, 1291, -1, 1291, 1295, 1292, 1288, -1, 1292, 1295, 1294, 1293, 1296, - 1297, 1298, 1299, -1, 1296, 1300, 1301, 1297, -1, 1297, 1301, 1302, 1298, -1, 1298, 1302, 1303, 1299, -1, 1299, 1303, 1300, 1296, -1, 1300, 1303, 1302, 1301, 1304, 1305, 1306, 1307, -1, 1304, - 1308, 1309, 1305, -1, 1305, 1309, 1310, 1306, -1, 1306, 1310, 1311, 1307, -1, 1307, 1311, 1308, 1304, -1, 1308, 1311, 1310, 1309, 1312, 1313, 1314, 1315, -1, 1312, 1316, 1317, 1313, -1, 1313, - 1317, 1318, 1314, -1, 1314, 1318, 1319, 1315, -1, 1315, 1319, 1316, 1312, -1, 1316, 1319, 1318, 1317, 1320, 1321, 1322, 1323, -1, 1320, 1324, 1325, 1321, -1, 1321, 1325, 1326, 1322, -1, 1322, - 1326, 1327, 1323, -1, 1323, 1327, 1324, 1320, -1, 1324, 1327, 1326, 1325, 1328, 1329, 1330, 1331, -1, 1328, 1332, 1333, 1329, -1, 1329, 1333, 1334, 1330, -1, 1330, 1334, 1335, 1331, -1, 1331, - 1335, 1332, 1328, -1, 1332, 1335, 1334, 1333, 1336, 1337, 1338, 1339, -1, 1336, 1340, 1341, 1337, -1, 1337, 1341, 1342, 1338, -1, 1338, 1342, 1343, 1339, -1, 1339, 1343, 1340, 1336, -1, 1340, - 1343, 1342, 1341, 1344, 1345, 1346, 1347, -1, 1344, 1348, 1349, 1345, -1, 1345, 1349, 1350, 1346, -1, 1346, 1350, 1351, 1347, -1, 1347, 1351, 1348, 1344, -1, 1348, 1351, 1350, 1349, 1352, 1353, - 1354, 1355, -1, 1352, 1356, 1357, 1353, -1, 1353, 1357, 1358, 1354, -1, 1354, 1358, 1359, 1355, -1, 1355, 1359, 1356, 1352, -1, 1356, 1359, 1358, 1357, 1360, 1361, 1362, 1363, -1, 1360, 1364, - 1365, 1361, -1, 1361, 1365, 1366, 1362, -1, 1362, 1366, 1367, 1363, -1, 1363, 1367, 1364, 1360, -1, 1364, 1367, 1366, 1365, 1368, 1369, 1370, 1371, -1, 1368, 1372, 1373, 1369, -1, 1369, 1373, - 1374, 1370, -1, 1370, 1374, 1375, 1371, -1, 1371, 1375, 1372, 1368, -1, 1372, 1375, 1374, 1373, 1376, 1377, 1378, 1379, -1, 1376, 1380, 1381, 1377, -1, 1377, 1381, 1382, 1378, -1, 1378, 1382, - 1383, 1379, -1, 1379, 1383, 1380, 1376, -1, 1380, 1383, 1382, 1381, 1384, 1385, 1386, 1387, -1, 1384, 1388, 1389, 1385, -1, 1385, 1389, 1390, 1386, -1, 1386, 1390, 1391, 1387, -1, 1387, 1391, - 1388, 1384, -1, 1388, 1391, 1390, 1389, 1392, 1393, 1394, 1395, -1, 1392, 1396, 1397, 1393, -1, 1393, 1397, 1398, 1394, -1, 1394, 1398, 1399, 1395, -1, 1395, 1399, 1396, 1392, -1, 1396, 1399, - 1398, 1397, 1400, 1401, 1402, 1403, -1, 1400, 1404, 1405, 1401, -1, 1401, 1405, 1406, 1402, -1, 1402, 1406, 1407, 1403, -1, 1403, 1407, 1404, 1400, -1, 1404, 1407, 1406, 1405, 1408, 1409, - 1410, 1411, -1, 1408, 1412, 1413, 1409, -1, 1409, 1413, 1414, 1410, -1, 1410, 1414, 1415, 1411, -1, 1411, 1415, 1412, 1408, -1, 1412, 1415, 1414, 1413, 1416, 1417, 1418, 1419, -1, 1416, - 1420, 1421, 1417, -1, 1417, 1421, 1422, 1418, -1, 1418, 1422, 1423, 1419, -1, 1419, 1423, 1420, 1416, -1, 1420, 1423, 1422, 1421, 1424, 1425, 1426, 1427, -1, 1424, 1428, 1429, 1425, -1, - 1425, 1429, 1430, 1426, -1, 1426, 1430, 1431, 1427, -1, 1427, 1431, 1428, 1424, -1, 1428, 1431, 1430, 1429, 1432, 1433, 1434, 1435, -1, 1432, 1436, 1437, 1433, -1, 1433, 1437, 1438, 1434, - -1, 1434, 1438, 1439, 1435, -1, 1435, 1439, 1436, 1432, -1, 1436, 1439, 1438, 1437, 1440, 1441, 1442, 1443, -1, 1440, 1444, 1445, 1441, -1, 1441, 1445, 1446, 1442, -1, 1442, 1446, 1447, 1443, - -1, 1443, 1447, 1444, 1440, -1, 1444, 1447, 1446, 1445, 1448, 1449, 1450, 1451, -1, 1448, 1452, 1453, 1449, -1, 1449, 1453, 1454, 1450, -1, 1450, 1454, 1455, 1451, -1, 1451, 1455, 1452, 1448, - -1, 1452, 1455, 1454, 1453, 1456, 1457, 1458, 1459, -1, 1456, 1460, 1461, 1457, -1, 1457, 1461, 1462, 1458, -1, 1458, 1462, 1463, 1459, -1, 1459, 1463, 1460, 1456, -1, 1460, 1463, 1462, 1461, - 1464, 1465, 1466, 1467, -1, 1464, 1468, 1469, 1465, -1, 1465, 1469, 1470, 1466, -1, 1466, 1470, 1471, 1467, -1, 1467, 1471, 1468, 1464, -1, 1468, 1471, 1470, 1469, 1472, 1473, 1474, 1475, -1, - 1472, 1476, 1477, 1473, -1, 1473, 1477, 1478, 1474, -1, 1474, 1478, 1479, 1475, -1, 1475, 1479, 1476, 1472, -1, 1476, 1479, 1478, 1477, 1480, 1481, 1482, 1483, -1, 1480, 1484, 1485, 1481, -1, - 1481, 1485, 1486, 1482, -1, 1482, 1486, 1487, 1483, -1, 1483, 1487, 1484, 1480, -1, 1484, 1487, 1486, 1485, 1488, 1489, 1490, 1491, -1, 1488, 1492, 1493, 1489, -1, 1489, 1493, 1494, 1490, -1, - 1490, 1494, 1495, 1491, -1, 1491, 1495, 1492, 1488, -1, 1492, 1495, 1494, 1493, 1496, 1497, 1498, 1499, -1, 1496, 1500, 1501, 1497, -1, 1497, 1501, 1502, 1498, -1, 1498, 1502, 1503, 1499, -1, - 1499, 1503, 1500, 1496, -1, 1500, 1503, 1502, 1501, 1504, 1505, 1506, 1507, -1, 1504, 1508, 1509, 1505, -1, 1505, 1509, 1510, 1506, -1, 1506, 1510, 1511, 1507, -1, 1507, 1511, 1508, 1504, -1, - 1508, 1511, 1510, 1509, 1512, 1513, 1514, 1515, -1, 1512, 1516, 1517, 1513, -1, 1513, 1517, 1518, 1514, -1, 1514, 1518, 1519, 1515, -1, 1515, 1519, 1516, 1512, -1, 1516, 1519, 1518, 1517, 1520, - 1521, 1522, 1523, -1, 1520, 1524, 1525, 1521, -1, 1521, 1525, 1526, 1522, -1, 1522, 1526, 1527, 1523, -1, 1523, 1527, 1524, 1520, -1, 1524, 1527, 1526, 1525, 1528, 1529, 1530, 1531, -1, 1528, 1532, - 1533, 1529, -1, 1529, 1533, 1534, 1530, -1, 1530, 1534, 1535, 1531, -1, 1531, 1535, 1532, 1528, -1, 1532, 1535, 1534, 1533, 1536, 1537, 1538, 1539, -1, 1536, 1540, 1541, 1537, -1, 1537, 1541, 1542, - 1538, -1, 1538, 1542, 1543, 1539, -1, 1539, 1543, 1540, 1536, -1, 1540, 1543, 1542, 1541, 1544, 1545, 1546, 1547, -1, 1544, 1548, 1549, 1545, -1, 1545, 1549, 1550, 1546, -1, 1546, 1550, 1551, 1547, - -1, 1547, 1551, 1548, 1544, -1, 1548, 1551, 1550, 1549, 1552, 1553, 1554, 1555, -1, 1552, 1556, 1557, 1553, -1, 1553, 1557, 1558, 1554, -1, 1554, 1558, 1559, 1555, -1, 1555, 1559, 1556, 1552, -1, 1556, - 1559, 1558, 1557, 1560, 1561, 1562, 1563, -1, 1560, 1564, 1565, 1561, -1, 1561, 1565, 1566, 1562, -1, 1562, 1566, 1567, 1563, -1, 1563, 1567, 1564, 1560, -1, 1564, 1567, 1566, 1565, 1568, 1569, 1570, 1571, - -1, 1568, 1572, 1573, 1569, -1, 1569, 1573, 1574, 1570, -1, 1570, 1574, 1575, 1571, -1, 1571, 1575, 1572, 1568, -1, 1572, 1575, 1574, 1573, 1576, 1577, 1578, 1579, -1, 1576, 1580, 1581, 1577, -1, - 1577, 1581, 1582, 1578, -1, 1578, 1582, 1583, 1579, -1, 1579, 1583, 1580, 1576, -1, 1580, 1583, 1582, 1581, 1584, 1585, 1586, 1587, -1, 1584, 1588, 1589, 1585, -1, 1585, 1589, 1590, 1586, -1, - 1586, 1590, 1591, 1587, -1, 1587, 1591, 1588, 1584, -1, 1588, 1591, 1590, 1589, 1592, 1593, 1594, 1595, -1, 1592, 1596, 1597, 1593, -1, 1593, 1597, 1598, 1594, -1, 1594, 1598, 1599, 1595, -1, - 1595, 1599, 1596, 1592, -1, 1596, 1599, 1598, 1597, 1600, 1601, 1602, 1603, -1, 1600, 1604, 1605, 1601, -1, 1601, 1605, 1606, 1602, -1, 1602, 1606, 1607, 1603, -1, 1603, 1607, 1604, 1600, -1, - 1604, 1607, 1606, 1605, 1608, 1609, 1610, 1611, -1, 1608, 1612, 1613, 1609, -1, 1609, 1613, 1614, 1610, -1, 1610, 1614, 1615, 1611, -1, 1611, 1615, 1612, 1608, -1, 1612, 1615, 1614, 1613, 1616, - 1617, 1618, 1619, -1, 1616, 1620, 1621, 1617, -1, 1617, 1621, 1622, 1618, -1, 1618, 1622, 1623, 1619, -1, 1619, 1623, 1620, 1616, -1, 1620, 1623, 1622, 1621, 1624, 1625, 1626, 1627, -1, 1624, - 1628, 1629, 1625, -1, 1625, 1629, 1630, 1626, -1, 1626, 1630, 1631, 1627, -1, 1627, 1631, 1628, 1624, -1, 1628, 1631, 1630, 1629, 1632, 1633, 1634, 1635, -1, 1632, 1636, 1637, 1633, -1, 1633, - 1637, 1638, 1634, -1, 1634, 1638, 1639, 1635, -1, 1635, 1639, 1636, 1632, -1, 1636, 1639, 1638, 1637, 1640, 1641, 1642, 1643, -1, 1640, 1644, 1645, 1641, -1, 1641, 1645, 1646, 1642, -1, 1642, - 1646, 1647, 1643, -1, 1643, 1647, 1644, 1640, -1, 1644, 1647, 1646, 1645, 1648, 1649, 1650, 1651, -1, 1648, 1652, 1653, 1649, -1, 1649, 1653, 1654, 1650, -1, 1650, 1654, 1655, 1651, -1, 1651, - 1655, 1652, 1648, -1, 1652, 1655, 1654, 1653, 1656, 1657, 1658, 1659, -1, 1656, 1660, 1661, 1657, -1, 1657, 1661, 1662, 1658, -1, 1658, 1662, 1663, 1659, -1, 1659, 1663, 1660, 1656, -1, 1660, - 1663, 1662, 1661, 1664, 1665, 1666, 1667, -1, 1664, 1668, 1669, 1665, -1, 1665, 1669, 1670, 1666, -1, 1666, 1670, 1671, 1667, -1, 1667, 1671, 1668, 1664, -1, 1668, 1671, 1670, 1669, 1672, 1673, - 1674, 1675, -1, 1672, 1676, 1677, 1673, -1, 1673, 1677, 1678, 1674, -1, 1674, 1678, 1679, 1675, -1, 1675, 1679, 1676, 1672, -1, 1676, 1679, 1678, 1677, 1680, 1681, 1682, 1683, -1, 1680, 1684, - 1685, 1681, -1, 1681, 1685, 1686, 1682, -1, 1682, 1686, 1687, 1683, -1, 1683, 1687, 1684, 1680, -1, 1684, 1687, 1686, 1685, 1688, 1689, 1690, 1691, -1, 1688, 1692, 1693, 1689, -1, 1689, 1693, - 1694, 1690, -1, 1690, 1694, 1695, 1691, -1, 1691, 1695, 1692, 1688, -1, 1692, 1695, 1694, 1693, 1696, 1697, 1698, 1699, -1, 1696, 1700, 1701, 1697, -1, 1697, 1701, 1702, 1698, -1, 1698, 1702, - 1703, 1699, -1, 1699, 1703, 1700, 1696, -1, 1700, 1703, 1702, 1701, 1704, 1705, 1706, 1707, -1, 1704, 1708, 1709, 1705, -1, 1705, 1709, 1710, 1706, -1, 1706, 1710, 1711, 1707, -1, 1707, 1711, - 1708, 1704, -1, 1708, 1711, 1710, 1709, 1712, 1713, 1714, 1715, -1, 1712, 1716, 1717, 1713, -1, 1713, 1717, 1718, 1714, -1, 1714, 1718, 1719, 1715, -1, 1715, 1719, 1716, 1712, -1, 1716, 1719, 1718, 1717}; - -double coordsTT[5160]={ - 0.0054015000000000044, 0.0054015000000000053, 0, 0.2106585, 0.0054015000000000053, 0, 0.2106585, 0.039611, 0, 0.2106585, 0.10803, 0, 0.2106585, - 0.17644899999999999, 0, 0.2106585, 0.2106585, 0, 0.0054015000000000044, 0.2106585, 0, 0.0054015000000000044, 0.0054015000000000053, 0.21364999999999998, - 0.2106585, 0.0054015000000000053, 0.21364999999999998, 0.2106585, 0.039611, 0.21364999999999998, 0.2106585, 0.10803, 0.21364999999999998, 0.2106585, - 0.17644899999999999, 0.21364999999999998, 0.2106585, 0.2106585, 0.21364999999999998, 0.0054015000000000044, 0.2106585, 0.21364999999999998, - 0.0054015000000000044, 0.0054015000000000053, 0.21364999999999998, 0.2106585, 0.0054015000000000053, 0.21364999999999998, 0.2106585, 0.039611, - 0.21364999999999998, 0.2106585, 0.10803, 0.21364999999999998, 0.2106585, 0.17644899999999999, 0.21364999999999998, 0.2106585, 0.2106585, 0.21364999999999998, - 0.0054015000000000044, 0.2106585, 0.21364999999999998, 0.0054015000000000044, 0.0054015000000000053, 0.42729999999999996, 0.2106585, 0.0054015000000000053, - 0.42729999999999996, 0.2106585, 0.039611, 0.42729999999999996, 0.2106585, 0.10803, 0.42729999999999996, 0.2106585, 0.17644899999999999, 0.42729999999999996, - 0.2106585, 0.2106585, 0.42729999999999996, 0.0054015000000000044, 0.2106585, 0.42729999999999996, 0.0054015000000000044, 0.0054015000000000053, - 0.42729999999999996, 0.2106585, 0.0054015000000000053, 0.42729999999999996, 0.2106585, 0.039611, 0.42729999999999996, 0.2106585, 0.10803, 0.42729999999999996, - 0.2106585, 0.17644899999999999, 0.42729999999999996, 0.2106585, 0.2106585, 0.42729999999999996, 0.0054015000000000044, 0.2106585, 0.42729999999999996, - 0.0054015000000000044, 0.0054015000000000053, 0.64094999999999991, 0.2106585, 0.0054015000000000053, 0.64094999999999991, 0.2106585, 0.039611, - 0.64094999999999991, 0.2106585, 0.10803, 0.64094999999999991, 0.2106585, 0.17644899999999999, 0.64094999999999991, 0.2106585, 0.2106585, 0.64094999999999991, - 0.0054015000000000044, 0.2106585, 0.64094999999999991, 0.0054015000000000044, 0.0054015000000000053, 0.64094999999999991, 0.2106585, 0.0054015000000000053, - 0.64094999999999991, 0.2106585, 0.039611, 0.64094999999999991, 0.2106585, 0.10803, 0.64094999999999991, 0.2106585, 0.17644899999999999, 0.64094999999999991, - 0.2106585, 0.2106585, 0.64094999999999991, 0.0054015000000000044, 0.2106585, 0.64094999999999991, 0.0054015000000000044, 0.0054015000000000053, - 0.85459999999999992, 0.2106585, 0.0054015000000000053, 0.85459999999999992, 0.2106585, 0.039611, 0.85459999999999992, 0.2106585, 0.10803, 0.85459999999999992, - 0.2106585, 0.17644899999999999, 0.85459999999999992, 0.2106585, 0.2106585, 0.85459999999999992, 0.0054015000000000044, 0.2106585, 0.85459999999999992, - 0.0054015000000000044, 0.0054015000000000053, 0.85459999999999992, 0.2106585, 0.0054015000000000053, 0.85459999999999992, 0.2106585, 0.039611, - 0.85459999999999992, 0.2106585, 0.10803, 0.85459999999999992, 0.2106585, 0.17644899999999999, 0.85459999999999992, 0.2106585, 0.2106585, 0.85459999999999992, - 0.0054015000000000044, 0.2106585, 0.85459999999999992, 0.0054015000000000044, 0.0054015000000000053, 1.0682499999999999, 0.2106585, 0.0054015000000000053, - 1.0682499999999999, 0.2106585, 0.039611, 1.0682499999999999, 0.2106585, 0.10803, - 1.0682499999999999, 0.2106585, 0.17644899999999999, 1.0682499999999999, 0.2106585, 0.2106585, 1.0682499999999999, 0.0054015000000000044, 0.2106585, - 1.0682499999999999, 0.0054015000000000044, 0.0054015000000000053, 1.0682499999999999, 0.2106585, 0.0054015000000000053, 1.0682499999999999, 0.2106585, 0.039611, - 1.0682499999999999, 0.2106585, 0.10803, 1.0682499999999999, 0.2106585, 0.17644899999999999, 1.0682499999999999, 0.2106585, 0.2106585, 1.0682499999999999, - 0.0054015000000000044, 0.2106585, 1.0682499999999999, 0.0054015000000000044, 0.0054015000000000053, 1.2818999999999998, 0.2106585, 0.0054015000000000053, - 1.2818999999999998, 0.2106585, 0.039611, 1.2818999999999998, 0.2106585, 0.10803, 1.2818999999999998, 0.2106585, 0.17644899999999999, 1.2818999999999998, - 0.2106585, 0.2106585, 1.2818999999999998, 0.0054015000000000044, 0.2106585, 1.2818999999999998, 0.0054015000000000044, 0.0054015000000000053, 1.2818999999999998, - 0.2106585, 0.0054015000000000053, 1.2818999999999998, 0.2106585, 0.039611, 1.2818999999999998, 0.2106585, 0.10803, 1.2818999999999998, 0.2106585, - 0.17644899999999999, 1.2818999999999998, 0.2106585, 0.2106585, 1.2818999999999998, 0.0054015000000000044, 0.2106585, 1.2818999999999998, 0.0054015000000000044, - 0.0054015000000000053, 1.4955499999999999, 0.2106585, 0.0054015000000000053, 1.4955499999999999, 0.2106585, 0.039611, 1.4955499999999999, 0.2106585, 0.10803, - 1.4955499999999999, 0.2106585, 0.17644899999999999, 1.4955499999999999, 0.2106585, 0.2106585, 1.4955499999999999, 0.0054015000000000044, 0.2106585, - 1.4955499999999999, 0.0054015000000000044, 0.0054015000000000053, 1.4955499999999999, 0.2106585, 0.0054015000000000053, 1.4955499999999999, 0.2106585, 0.039611, - 1.4955499999999999, 0.2106585, 0.10803, 1.4955499999999999, 0.2106585, 0.17644899999999999, 1.4955499999999999, 0.2106585, 0.2106585, 1.4955499999999999, - 0.0054015000000000044, 0.2106585, 1.4955499999999999, 0.0054015000000000044, 0.0054015000000000053, 1.7091999999999998, 0.2106585, 0.0054015000000000053, - 1.7091999999999998, 0.2106585, 0.039611, 1.7091999999999998, 0.2106585, 0.10803, 1.7091999999999998, 0.2106585, 0.17644899999999999, 1.7091999999999998, - 0.2106585, 0.2106585, 1.7091999999999998, 0.0054015000000000044, 0.2106585, 1.7091999999999998, 0.0054015000000000044, 0.0054015000000000053, 1.7091999999999998, - 0.2106585, 0.0054015000000000053, 1.7091999999999998, 0.2106585, 0.039611, 1.7091999999999998, 0.2106585, 0.10803, 1.7091999999999998, 0.2106585, - 0.17644899999999999, 1.7091999999999998, 0.2106585, 0.2106585, 1.7091999999999998, 0.0054015000000000044, 0.2106585, 1.7091999999999998, 0.0054015000000000044, - 0.0054015000000000053, 1.9228499999999997, 0.2106585, 0.0054015000000000053, 1.9228499999999997, 0.2106585, 0.039611, 1.9228499999999997, 0.2106585, 0.10803, - 1.9228499999999997, 0.2106585, 0.17644899999999999, 1.9228499999999997, 0.2106585, 0.2106585, 1.9228499999999997, 0.0054015000000000044, 0.2106585, - 1.9228499999999997, 0.0054015000000000044, 0.0054015000000000053, 1.9228499999999997, 0.2106585, 0.0054015000000000053, 1.9228499999999997, 0.2106585, 0.039611, - 1.9228499999999997, 0.2106585, 0.10803, 1.9228499999999997, 0.2106585, 0.17644899999999999, 1.9228499999999997, 0.2106585, 0.2106585, 1.9228499999999997, - 0.0054015000000000044, 0.2106585, 1.9228499999999997, 0.0054015000000000044, - 0.0054015000000000053, 2.1364999999999998, 0.2106585, 0.0054015000000000053, 2.1364999999999998, 0.2106585, 0.039611, 2.1364999999999998, 0.2106585, - 0.10803, 2.1364999999999998, 0.2106585, 0.17644899999999999, 2.1364999999999998, 0.2106585, 0.2106585, 2.1364999999999998, 0.0054015000000000044, 0.2106585, - 2.1364999999999998, 0.0054015000000000044, 0.0054015000000000053, 2.1364999999999998, 0.2106585, 0.0054015000000000053, 2.1364999999999998, 0.2106585, 0.039611, - 2.1364999999999998, 0.2106585, 0.10803, 2.1364999999999998, 0.2106585, 0.17644899999999999, 2.1364999999999998, 0.2106585, 0.2106585, 2.1364999999999998, - 0.0054015000000000044, 0.2106585, 2.1364999999999998, 0.0054015000000000044, 0.0054015000000000053, 2.3501499999999997, 0.2106585, 0.0054015000000000053, - 2.3501499999999997, 0.2106585, 0.039611, 2.3501499999999997, 0.2106585, 0.10803, 2.3501499999999997, 0.2106585, 0.17644899999999999, 2.3501499999999997, - 0.2106585, 0.2106585, 2.3501499999999997, 0.0054015000000000044, 0.2106585, 2.3501499999999997, 0.0054015000000000044, 0.0054015000000000053, 2.3501499999999997, - 0.2106585, 0.0054015000000000053, 2.3501499999999997, 0.2106585, 0.039611, 2.3501499999999997, 0.2106585, 0.10803, 2.3501499999999997, 0.2106585, - 0.17644899999999999, 2.3501499999999997, 0.2106585, 0.2106585, 2.3501499999999997, 0.0054015000000000044, 0.2106585, 2.3501499999999997, 0.0054015000000000044, - 0.0054015000000000053, 2.5637999999999996, 0.2106585, 0.0054015000000000053, 2.5637999999999996, 0.2106585, 0.039611, 2.5637999999999996, 0.2106585, 0.10803, - 2.5637999999999996, 0.2106585, 0.17644899999999999, 2.5637999999999996, 0.2106585, 0.2106585, 2.5637999999999996, 0.0054015000000000044, 0.2106585, - 2.5637999999999996, 0.0054015000000000044, 0.0054015000000000053, 2.5637999999999996, 0.2106585, 0.0054015000000000053, 2.5637999999999996, 0.2106585, 0.039611, - 2.5637999999999996, 0.2106585, 0.10803, 2.5637999999999996, 0.2106585, 0.17644899999999999, 2.5637999999999996, 0.2106585, 0.2106585, 2.5637999999999996, - 0.0054015000000000044, 0.2106585, 2.5637999999999996, 0.0054015000000000044, 0.0054015000000000053, 2.7774499999999995, 0.2106585, 0.0054015000000000053, - 2.7774499999999995, 0.2106585, 0.039611, 2.7774499999999995, 0.2106585, 0.10803, 2.7774499999999995, 0.2106585, 0.17644899999999999, 2.7774499999999995, - 0.2106585, 0.2106585, 2.7774499999999995, 0.0054015000000000044, 0.2106585, 2.7774499999999995, 0.0054015000000000044, 0.0054015000000000053, 2.7774499999999995, - 0.2106585, 0.0054015000000000053, 2.7774499999999995, 0.2106585, 0.039611, 2.7774499999999995, 0.2106585, 0.10803, 2.7774499999999995, 0.2106585, - 0.17644899999999999, 2.7774499999999995, 0.2106585, 0.2106585, 2.7774499999999995, 0.0054015000000000044, 0.2106585, 2.7774499999999995, 0.0054015000000000044, - 0.0054015000000000053, 2.9910999999999999, 0.2106585, 0.0054015000000000053, 2.9910999999999999, 0.2106585, 0.039611, 2.9910999999999999, 0.2106585, 0.10803, - 2.9910999999999999, 0.2106585, 0.17644899999999999, 2.9910999999999999, 0.2106585, 0.2106585, 2.9910999999999999, 0.0054015000000000044, 0.2106585, - 2.9910999999999999, 0.0054015000000000044, 0.0054015000000000053, 2.9910999999999999, 0.2106585, 0.0054015000000000053, 2.9910999999999999, 0.2106585, 0.039611, - 2.9910999999999999, 0.2106585, 0.10803, 2.9910999999999999, - 0.2106585, 0.17644899999999999, 2.9910999999999999, 0.2106585, 0.2106585, 2.9910999999999999, 0.0054015000000000044, 0.2106585, 2.9910999999999999, - 0.0054015000000000044, 0.0054015000000000053, 3.2047499999999998, 0.2106585, 0.0054015000000000053, 3.2047499999999998, 0.2106585, 0.039611, 3.2047499999999998, - 0.2106585, 0.10803, 3.2047499999999998, 0.2106585, 0.17644899999999999, 3.2047499999999998, 0.2106585, 0.2106585, 3.2047499999999998, 0.0054015000000000044, - 0.2106585, 3.2047499999999998, 0.0054015000000000044, 0.0054015000000000053, 3.2047499999999998, 0.2106585, 0.0054015000000000053, 3.2047499999999998, 0.2106585, - 0.039611, 3.2047499999999998, 0.2106585, 0.10803, 3.2047499999999998, 0.2106585, 0.17644899999999999, 3.2047499999999998, 0.2106585, 0.2106585, - 3.2047499999999998, 0.0054015000000000044, 0.2106585, 3.2047499999999998, 0.0054015000000000044, 0.0054015000000000053, 3.4183999999999997, 0.2106585, - 0.0054015000000000053, 3.4183999999999997, 0.2106585, 0.039611, 3.4183999999999997, 0.2106585, 0.10803, 3.4183999999999997, 0.2106585, 0.17644899999999999, - 3.4183999999999997, 0.2106585, 0.2106585, 3.4183999999999997, 0.0054015000000000044, 0.2106585, 3.4183999999999997, 0.0054015000000000044, 0.0054015000000000053, - 3.4183999999999997, 0.2106585, 0.0054015000000000053, 3.4183999999999997, 0.2106585, 0.039611, 3.4183999999999997, 0.2106585, 0.10803, 3.4183999999999997, - 0.2106585, 0.17644899999999999, 3.4183999999999997, 0.2106585, 0.2106585, 3.4183999999999997, 0.0054015000000000044, 0.2106585, 3.4183999999999997, - 0.0054015000000000044, 0.0054015000000000053, 3.6320499999999996, 0.2106585, 0.0054015000000000053, 3.6320499999999996, 0.2106585, 0.039611, 3.6320499999999996, - 0.2106585, 0.10803, 3.6320499999999996, 0.2106585, 0.17644899999999999, 3.6320499999999996, 0.2106585, 0.2106585, 3.6320499999999996, 0.0054015000000000044, - 0.2106585, 3.6320499999999996, 0.0054015000000000044, 0.0054015000000000053, 3.6320499999999996, 0.2106585, 0.0054015000000000053, 3.6320499999999996, 0.2106585, - 0.039611, 3.6320499999999996, 0.2106585, 0.10803, 3.6320499999999996, 0.2106585, 0.17644899999999999, 3.6320499999999996, 0.2106585, 0.2106585, - 3.6320499999999996, 0.0054015000000000044, 0.2106585, 3.6320499999999996, 0.0054015000000000044, 0.0054015000000000053, 3.8456999999999995, 0.2106585, - 0.0054015000000000053, 3.8456999999999995, 0.2106585, 0.039611, 3.8456999999999995, 0.2106585, 0.10803, 3.8456999999999995, 0.2106585, 0.17644899999999999, - 3.8456999999999995, 0.2106585, 0.2106585, 3.8456999999999995, 0.0054015000000000044, 0.2106585, 3.8456999999999995, 0.0054015000000000044, 0.0054015000000000053, - 3.8456999999999995, 0.2106585, 0.0054015000000000053, 3.8456999999999995, 0.2106585, 0.039611, 3.8456999999999995, 0.2106585, 0.10803, 3.8456999999999995, - 0.2106585, 0.17644899999999999, 3.8456999999999995, 0.2106585, 0.2106585, 3.8456999999999995, 0.0054015000000000044, 0.2106585, 3.8456999999999995, - 0.0054015000000000044, 0.0054015000000000053, 4.0593499999999993, 0.2106585, 0.0054015000000000053, 4.0593499999999993, 0.2106585, 0.039611, 4.0593499999999993, - 0.2106585, 0.10803, 4.0593499999999993, 0.2106585, 0.17644899999999999, 4.0593499999999993, 0.2106585, 0.2106585, 4.0593499999999993, 0.0054015000000000044, - 0.2106585, 4.0593499999999993, 0.0054015000000000044, 0.0054015000000000053, - 4.0593499999999993, 0.2106585, 0.0054015000000000053, 4.0593499999999993, 0.2106585, 0.039611, 4.0593499999999993, 0.2106585, 0.10803, 4.0593499999999993, - 0.2106585, 0.17644899999999999, 4.0593499999999993, 0.2106585, 0.2106585, 4.0593499999999993, 0.0054015000000000044, 0.2106585, 4.0593499999999993, - 0.0054015000000000044, 0.0054015000000000053, 4.2729999999999997, 0.2106585, 0.0054015000000000053, 4.2729999999999997, 0.2106585, 0.039611, 4.2729999999999997, - 0.2106585, 0.10803, 4.2729999999999997, 0.2106585, 0.17644899999999999, 4.2729999999999997, 0.2106585, 0.2106585, 4.2729999999999997, 0.0054015000000000044, - 0.2106585, 4.2729999999999997, 0.24197569714517145, 0.025915697145171439, 0, 0.26483839536511933, 0.025915697145171439, 0, 0.26483839536511933, - 0.048778395365119298, 0, 0.24197569714517145, 0.048778395365119298, 0, 0.24197569714517145, 0.025915697145171439, 0.21364999999999998, 0.26483839536511933, - 0.025915697145171439, 0.21364999999999998, 0.26483839536511933, 0.048778395365119298, 0.21364999999999998, 0.24197569714517145, 0.048778395365119298, - 0.21364999999999998, 0.24197569714517145, 0.025915697145171439, 0.21364999999999998, 0.26483839536511933, 0.025915697145171439, 0.21364999999999998, - 0.26483839536511933, 0.048778395365119298, 0.21364999999999998, 0.24197569714517145, 0.048778395365119298, 0.21364999999999998, 0.24197569714517145, - 0.025915697145171439, 0.42729999999999996, 0.26483839536511933, 0.025915697145171439, 0.42729999999999996, 0.26483839536511933, 0.048778395365119298, - 0.42729999999999996, 0.24197569714517145, 0.048778395365119298, 0.42729999999999996, 0.24197569714517145, 0.025915697145171439, 0.42729999999999996, - 0.26483839536511933, 0.025915697145171439, 0.42729999999999996, 0.26483839536511933, 0.048778395365119298, 0.42729999999999996, 0.24197569714517145, - 0.048778395365119298, 0.42729999999999996, 0.24197569714517145, 0.025915697145171439, 0.64094999999999991, 0.26483839536511933, 0.025915697145171439, - 0.64094999999999991, 0.26483839536511933, 0.048778395365119298, 0.64094999999999991, 0.24197569714517145, 0.048778395365119298, 0.64094999999999991, - 0.24197569714517145, 0.025915697145171439, 0.64094999999999991, 0.26483839536511933, 0.025915697145171439, 0.64094999999999991, 0.26483839536511933, - 0.048778395365119298, 0.64094999999999991, 0.24197569714517145, 0.048778395365119298, 0.64094999999999991, 0.24197569714517145, 0.025915697145171439, - 0.85459999999999992, 0.26483839536511933, 0.025915697145171439, 0.85459999999999992, 0.26483839536511933, 0.048778395365119298, 0.85459999999999992, - 0.24197569714517145, 0.048778395365119298, 0.85459999999999992, 0.24197569714517145, 0.025915697145171439, 0.85459999999999992, 0.26483839536511933, - 0.025915697145171439, 0.85459999999999992, 0.26483839536511933, 0.048778395365119298, 0.85459999999999992, 0.24197569714517145, 0.048778395365119298, - 0.85459999999999992, 0.24197569714517145, 0.025915697145171439, 1.0682499999999999, 0.26483839536511933, 0.025915697145171439, 1.0682499999999999, - 0.26483839536511933, 0.048778395365119298, 1.0682499999999999, 0.24197569714517145, 0.048778395365119298, 1.0682499999999999, 0.24197569714517145, - 0.025915697145171439, 1.0682499999999999, 0.26483839536511933, 0.025915697145171439, 1.0682499999999999, 0.26483839536511933, 0.048778395365119298, - 1.0682499999999999, 0.24197569714517145, 0.048778395365119298, 1.0682499999999999, 0.24197569714517145, 0.025915697145171439, 1.2818999999999998, - 0.26483839536511933, 0.025915697145171439, 1.2818999999999998, 0.26483839536511933, 0.048778395365119298, 1.2818999999999998, 0.24197569714517145, - 0.048778395365119298, 1.2818999999999998, 0.24197569714517145, 0.025915697145171439, 1.2818999999999998, 0.26483839536511933, 0.025915697145171439, - 1.2818999999999998, 0.26483839536511933, 0.048778395365119298, 1.2818999999999998, 0.24197569714517145, 0.048778395365119298, 1.2818999999999998, - 0.24197569714517145, 0.025915697145171439, 1.4955499999999999, 0.26483839536511933,0.025915697145171439, 1.4955499999999999, 0.26483839536511933, - 0.048778395365119298, 1.4955499999999999, 0.24197569714517145, 0.048778395365119298, - 1.4955499999999999, 0.24197569714517145, 0.025915697145171439, 1.4955499999999999, 0.26483839536511933, 0.025915697145171439, 1.4955499999999999, - 0.26483839536511933, 0.048778395365119298, 1.4955499999999999, 0.24197569714517145, 0.048778395365119298, 1.4955499999999999, 0.24197569714517145, - 0.025915697145171439, 1.7091999999999998, 0.26483839536511933, 0.025915697145171439, 1.7091999999999998, 0.26483839536511933, 0.048778395365119298, - 1.7091999999999998, 0.24197569714517145, 0.048778395365119298, 1.7091999999999998, 0.24197569714517145, 0.025915697145171439, 1.7091999999999998, - 0.26483839536511933, 0.025915697145171439, 1.7091999999999998, 0.26483839536511933, 0.048778395365119298, 1.7091999999999998, 0.24197569714517145, - 0.048778395365119298, 1.7091999999999998, 0.24197569714517145, 0.025915697145171439, 1.9228499999999997, 0.26483839536511933, 0.025915697145171439, - 1.9228499999999997, 0.26483839536511933, 0.048778395365119298, 1.9228499999999997, 0.24197569714517145, 0.048778395365119298, 1.9228499999999997, - 0.24197569714517145, 0.025915697145171439, 1.9228499999999997, 0.26483839536511933, 0.025915697145171439, 1.9228499999999997, 0.26483839536511933, - 0.048778395365119298, 1.9228499999999997, 0.24197569714517145, 0.048778395365119298, 1.9228499999999997, 0.24197569714517145, 0.025915697145171439, - 2.1364999999999998, 0.26483839536511933, 0.025915697145171439, 2.1364999999999998, 0.26483839536511933, 0.048778395365119298, 2.1364999999999998, - 0.24197569714517145, 0.048778395365119298, 2.1364999999999998, 0.24197569714517145, 0.025915697145171439, 2.1364999999999998, 0.26483839536511933, - 0.025915697145171439, 2.1364999999999998, 0.26483839536511933, 0.048778395365119298, 2.1364999999999998, 0.24197569714517145, 0.048778395365119298, - 2.1364999999999998, 0.24197569714517145, 0.025915697145171439, 2.3501499999999997, 0.26483839536511933, 0.025915697145171439, 2.3501499999999997, - 0.26483839536511933, 0.048778395365119298, 2.3501499999999997, 0.24197569714517145, 0.048778395365119298, 2.3501499999999997, 0.24197569714517145, - 0.025915697145171439, 2.3501499999999997, 0.26483839536511933, 0.025915697145171439, 2.3501499999999997, 0.26483839536511933, 0.048778395365119298, - 2.3501499999999997, 0.24197569714517145, 0.048778395365119298, 2.3501499999999997, 0.24197569714517145, 0.025915697145171439, 2.5637999999999996, - 0.26483839536511933, 0.025915697145171439, 2.5637999999999996, 0.26483839536511933, 0.048778395365119298, 2.5637999999999996, 0.24197569714517145, - 0.048778395365119298, 2.5637999999999996, 0.24197569714517145, 0.025915697145171439, 2.5637999999999996, 0.26483839536511933, 0.025915697145171439, - 2.5637999999999996, 0.26483839536511933, 0.048778395365119298, 2.5637999999999996, 0.24197569714517145, 0.048778395365119298, 2.5637999999999996, - 0.24197569714517145, 0.025915697145171439, 2.7774499999999995, 0.26483839536511933, 0.025915697145171439, 2.7774499999999995, 0.26483839536511933, - 0.048778395365119298, 2.7774499999999995, 0.24197569714517145, 0.048778395365119298, 2.7774499999999995, 0.24197569714517145, 0.025915697145171439, - 2.7774499999999995, 0.26483839536511933, 0.025915697145171439, 2.7774499999999995, 0.26483839536511933, 0.048778395365119298, 2.7774499999999995, - 0.24197569714517145, 0.048778395365119298, 2.7774499999999995, 0.24197569714517145, 0.025915697145171439, 2.9910999999999999, 0.26483839536511933, - 0.025915697145171439, 2.9910999999999999, 0.26483839536511933, 0.048778395365119298, 2.9910999999999999, 0.24197569714517145, 0.048778395365119298, - 2.9910999999999999, 0.24197569714517145, 0.025915697145171439, 2.9910999999999999, 0.26483839536511933, 0.025915697145171439, 2.9910999999999999, - 0.26483839536511933, 0.048778395365119298, 2.9910999999999999, 0.24197569714517145, 0.048778395365119298, 2.9910999999999999, 0.24197569714517145, - 0.025915697145171439, 3.2047499999999998, 0.26483839536511933, 0.025915697145171439, 3.2047499999999998, 0.26483839536511933, 0.048778395365119298, - 3.2047499999999998, 0.24197569714517145, 0.048778395365119298, 3.2047499999999998, - 0.24197569714517145, 0.025915697145171439, 3.2047499999999998, 0.26483839536511933, 0.025915697145171439, 3.2047499999999998, 0.26483839536511933, - 0.048778395365119298, 3.2047499999999998, 0.24197569714517145, 0.048778395365119298, 3.2047499999999998, 0.24197569714517145, 0.025915697145171439, - 3.4183999999999997, 0.26483839536511933, 0.025915697145171439, 3.4183999999999997, 0.26483839536511933, 0.048778395365119298, 3.4183999999999997, - 0.24197569714517145, 0.048778395365119298, 3.4183999999999997, 0.24197569714517145, 0.025915697145171439, 3.4183999999999997, 0.26483839536511933, - 0.025915697145171439, 3.4183999999999997, 0.26483839536511933, 0.048778395365119298, 3.4183999999999997, 0.24197569714517145, 0.048778395365119298, - 3.4183999999999997, 0.24197569714517145, 0.025915697145171439, 3.6320499999999996, 0.26483839536511933, 0.025915697145171439, 3.6320499999999996, - 0.26483839536511933, 0.048778395365119298, 3.6320499999999996, 0.24197569714517145, 0.048778395365119298, 3.6320499999999996, 0.24197569714517145, - 0.025915697145171439, 3.6320499999999996, 0.26483839536511933, 0.025915697145171439, 3.6320499999999996, 0.26483839536511933, 0.048778395365119298, - 3.6320499999999996, 0.24197569714517145, 0.048778395365119298, 3.6320499999999996, 0.24197569714517145, 0.025915697145171439, 3.8456999999999995, - 0.26483839536511933, 0.025915697145171439, 3.8456999999999995, 0.26483839536511933, 0.048778395365119298, 3.8456999999999995, 0.24197569714517145, - 0.048778395365119298, 3.8456999999999995, 0.24197569714517145, 0.025915697145171439, 3.8456999999999995, 0.26483839536511933, 0.025915697145171439, - 3.8456999999999995, 0.26483839536511933, 0.048778395365119298, 3.8456999999999995, 0.24197569714517145, 0.048778395365119298, 3.8456999999999995, - 0.24197569714517145, 0.025915697145171439, 4.0593499999999993, 0.26483839536511933, 0.025915697145171439, 4.0593499999999993, 0.26483839536511933, - 0.048778395365119298, 4.0593499999999993, 0.24197569714517145, 0.048778395365119298, 4.0593499999999993, 0.24197569714517145, 0.025915697145171439, - 4.0593499999999993, 0.26483839536511933, 0.025915697145171439, 4.0593499999999993, 0.26483839536511933, 0.048778395365119298, 4.0593499999999993, - 0.24197569714517145, 0.048778395365119298, 4.0593499999999993, 0.24197569714517145, 0.025915697145171439, 4.2729999999999997, 0.26483839536511933, - 0.025915697145171439, 4.2729999999999997, 0.26483839536511933, 0.048778395365119298, 4.2729999999999997, 0.24197569714517145, 0.048778395365119298, - 4.2729999999999997, 0.31132160463488068, 0.029625802317440348, 0, 0.3368583953651193, 0.029625802317440348, 0, 0.3368583953651193, 0.046104302854828562, 0, - 0.31132160463488068, 0.046104302854828562, 0, 0.31132160463488068, 0.029625802317440348, 0.21364999999999998, 0.3368583953651193, 0.029625802317440348, - 0.21364999999999998, 0.3368583953651193, 0.046104302854828562, 0.21364999999999998, 0.31132160463488068, 0.046104302854828562, 0.21364999999999998, - 0.31132160463488068, 0.029625802317440348, 0.21364999999999998, 0.3368583953651193, 0.029625802317440348, 0.21364999999999998, 0.3368583953651193, - 0.046104302854828562, 0.21364999999999998, 0.31132160463488068, 0.046104302854828562, 0.21364999999999998, 0.31132160463488068, 0.029625802317440348, - 0.42729999999999996, 0.3368583953651193, 0.029625802317440348, 0.42729999999999996, 0.3368583953651193, 0.046104302854828562, 0.42729999999999996, - 0.31132160463488068, 0.046104302854828562, 0.42729999999999996, 0.31132160463488068, 0.029625802317440348, 0.42729999999999996, 0.3368583953651193, - 0.029625802317440348, 0.42729999999999996, 0.3368583953651193, 0.046104302854828562, 0.42729999999999996, 0.31132160463488068, 0.046104302854828562, - 0.42729999999999996, 0.31132160463488068, 0.029625802317440348, 0.64094999999999991, 0.3368583953651193, 0.029625802317440348, 0.64094999999999991, - 0.3368583953651193, 0.046104302854828562, 0.64094999999999991, 0.31132160463488068, 0.046104302854828562, 0.64094999999999991, 0.31132160463488068, - 0.029625802317440348, 0.64094999999999991, 0.3368583953651193, 0.029625802317440348, 0.64094999999999991, 0.3368583953651193, 0.046104302854828562, - 0.64094999999999991, 0.31132160463488068, 0.046104302854828562, 0.64094999999999991, 0.31132160463488068, 0.029625802317440348, 0.85459999999999992, - 0.3368583953651193, 0.029625802317440348, 0.85459999999999992, 0.3368583953651193, 0.046104302854828562, 0.85459999999999992, 0.31132160463488068, - 0.046104302854828562, 0.85459999999999992, 0.31132160463488068, 0.029625802317440348, 0.85459999999999992, 0.3368583953651193, 0.029625802317440348, - 0.85459999999999992, 0.3368583953651193, 0.046104302854828562, 0.85459999999999992, 0.31132160463488068, 0.046104302854828562, 0.85459999999999992, - 0.31132160463488068, 0.029625802317440348, 1.0682499999999999, 0.3368583953651193, 0.029625802317440348, 1.0682499999999999, 0.3368583953651193, - 0.046104302854828562, 1.0682499999999999, 0.31132160463488068, 0.046104302854828562, 1.0682499999999999, 0.31132160463488068, 0.029625802317440348, - 1.0682499999999999, 0.3368583953651193, 0.029625802317440348, 1.0682499999999999, 0.3368583953651193, 0.046104302854828562, 1.0682499999999999, - 0.31132160463488068, 0.046104302854828562, 1.0682499999999999, 0.31132160463488068, 0.029625802317440348, 1.2818999999999998, 0.3368583953651193, - 0.029625802317440348, 1.2818999999999998, 0.3368583953651193, 0.046104302854828562, 1.2818999999999998, 0.31132160463488068, 0.046104302854828562, - 1.2818999999999998, 0.31132160463488068, 0.029625802317440348, 1.2818999999999998, 0.3368583953651193, 0.029625802317440348, 1.2818999999999998, - 0.3368583953651193, 0.046104302854828562, 1.2818999999999998, 0.31132160463488068, 0.046104302854828562, 1.2818999999999998, 0.31132160463488068, - 0.029625802317440348, 1.4955499999999999, 0.3368583953651193, 0.029625802317440348, 1.4955499999999999, 0.3368583953651193, 0.046104302854828562, - 1.4955499999999999, 0.31132160463488068, 0.046104302854828562, 1.4955499999999999, 0.31132160463488068, 0.029625802317440348, 1.4955499999999999, - 0.3368583953651193, 0.029625802317440348, 1.4955499999999999, 0.3368583953651193, 0.046104302854828562, 1.4955499999999999, 0.31132160463488068, - 0.046104302854828562, 1.4955499999999999, 0.31132160463488068, 0.029625802317440348, 1.7091999999999998, 0.3368583953651193, 0.029625802317440348, - 1.7091999999999998, 0.3368583953651193, 0.046104302854828562, 1.7091999999999998, 0.31132160463488068, 0.046104302854828562, 1.7091999999999998, - 0.31132160463488068, 0.029625802317440348, 1.7091999999999998, 0.3368583953651193, 0.029625802317440348, 1.7091999999999998, 0.3368583953651193, - 0.046104302854828562, 1.7091999999999998, 0.31132160463488068, 0.046104302854828562, 1.7091999999999998, 0.31132160463488068, 0.029625802317440348, - 1.9228499999999997, 0.3368583953651193, 0.029625802317440348, 1.9228499999999997, 0.3368583953651193, 0.046104302854828562, 1.9228499999999997, - 0.31132160463488068, 0.046104302854828562, 1.9228499999999997, 0.31132160463488068, 0.029625802317440348, 1.9228499999999997, 0.3368583953651193, - 0.029625802317440348, 1.9228499999999997, 0.3368583953651193, 0.046104302854828562, 1.9228499999999997, 0.31132160463488068, 0.046104302854828562, - 1.9228499999999997, 0.31132160463488068, 0.029625802317440348, 2.1364999999999998, 0.3368583953651193, 0.029625802317440348, 2.1364999999999998, - 0.3368583953651193, 0.046104302854828562, 2.1364999999999998, 0.31132160463488068, 0.046104302854828562, 2.1364999999999998, 0.31132160463488068, - 0.029625802317440348, 2.1364999999999998, 0.3368583953651193, 0.029625802317440348, 2.1364999999999998, 0.3368583953651193, 0.046104302854828562, - 2.1364999999999998, 0.31132160463488068, 0.046104302854828562, 2.1364999999999998, 0.31132160463488068, 0.029625802317440348, 2.3501499999999997, - 0.3368583953651193, 0.029625802317440348, 2.3501499999999997, 0.3368583953651193, 0.046104302854828562, 2.3501499999999997, 0.31132160463488068, - 0.046104302854828562, 2.3501499999999997, 0.31132160463488068, 0.029625802317440348, 2.3501499999999997, 0.3368583953651193, 0.029625802317440348, - 2.3501499999999997, 0.3368583953651193, 0.046104302854828562, 2.3501499999999997, 0.31132160463488068, 0.046104302854828562, 2.3501499999999997, - 0.31132160463488068, 0.029625802317440348, 2.5637999999999996, 0.3368583953651193, - 0.029625802317440348, 2.5637999999999996, 0.3368583953651193, 0.046104302854828562, 2.5637999999999996, 0.31132160463488068, 0.046104302854828562, - 2.5637999999999996, 0.31132160463488068, 0.029625802317440348, 2.5637999999999996, 0.3368583953651193, 0.029625802317440348, 2.5637999999999996, - 0.3368583953651193, 0.046104302854828562, 2.5637999999999996, 0.31132160463488068, 0.046104302854828562, 2.5637999999999996, 0.31132160463488068, - 0.029625802317440348, 2.7774499999999995, 0.3368583953651193, 0.029625802317440348, 2.7774499999999995, 0.3368583953651193, 0.046104302854828562, - 2.7774499999999995, 0.31132160463488068, 0.046104302854828562, 2.7774499999999995, 0.31132160463488068, 0.029625802317440348, 2.7774499999999995, - 0.3368583953651193, 0.029625802317440348, 2.7774499999999995, 0.3368583953651193, 0.046104302854828562, 2.7774499999999995, 0.31132160463488068, - 0.046104302854828562, 2.7774499999999995, 0.31132160463488068, 0.029625802317440348, 2.9910999999999999, 0.3368583953651193, 0.029625802317440348, - 2.9910999999999999, 0.3368583953651193, 0.046104302854828562, 2.9910999999999999, 0.31132160463488068, 0.046104302854828562, 2.9910999999999999, - 0.31132160463488068, 0.029625802317440348, 2.9910999999999999, 0.3368583953651193, 0.029625802317440348, 2.9910999999999999, 0.3368583953651193, - 0.046104302854828562, 2.9910999999999999, 0.31132160463488068, 0.046104302854828562, 2.9910999999999999, 0.31132160463488068, 0.029625802317440348, - 3.2047499999999998, 0.3368583953651193, 0.029625802317440348, 3.2047499999999998, 0.3368583953651193, 0.046104302854828562, 3.2047499999999998, - 0.31132160463488068, 0.046104302854828562, 3.2047499999999998, 0.31132160463488068, 0.029625802317440348, 3.2047499999999998, 0.3368583953651193, - 0.029625802317440348, 3.2047499999999998, 0.3368583953651193, 0.046104302854828562, 3.2047499999999998, 0.31132160463488068, 0.046104302854828562, - 3.2047499999999998, 0.31132160463488068, 0.029625802317440348, 3.4183999999999997, 0.3368583953651193, 0.029625802317440348, 3.4183999999999997, - 0.3368583953651193, 0.046104302854828562, 3.4183999999999997, 0.31132160463488068, 0.046104302854828562, 3.4183999999999997, 0.31132160463488068, - 0.029625802317440348, 3.4183999999999997, 0.3368583953651193, 0.029625802317440348, 3.4183999999999997, 0.3368583953651193, 0.046104302854828562, - 3.4183999999999997, 0.31132160463488068, 0.046104302854828562, 3.4183999999999997, 0.31132160463488068, 0.029625802317440348, 3.6320499999999996, - 0.3368583953651193, 0.029625802317440348, 3.6320499999999996, 0.3368583953651193, 0.046104302854828562, 3.6320499999999996, 0.31132160463488068, - 0.046104302854828562, 3.6320499999999996, 0.31132160463488068, 0.029625802317440348, 3.6320499999999996, 0.3368583953651193, 0.029625802317440348, - 3.6320499999999996, 0.3368583953651193, 0.046104302854828562, 3.6320499999999996, 0.31132160463488068, 0.046104302854828562, 3.6320499999999996, - 0.31132160463488068, 0.029625802317440348, 3.8456999999999995, 0.3368583953651193, 0.029625802317440348, 3.8456999999999995, 0.3368583953651193, - 0.046104302854828562, 3.8456999999999995, 0.31132160463488068, 0.046104302854828562, 3.8456999999999995, 0.31132160463488068, 0.029625802317440348, - 3.8456999999999995, 0.3368583953651193, 0.029625802317440348, 3.8456999999999995, 0.3368583953651193, 0.046104302854828562, 3.8456999999999995, - 0.31132160463488068, 0.046104302854828562, 3.8456999999999995, 0.31132160463488068, 0.029625802317440348, 4.0593499999999993, 0.3368583953651193, - 0.029625802317440348, 4.0593499999999993, 0.3368583953651193, 0.046104302854828562, 4.0593499999999993, 0.31132160463488068, 0.046104302854828562, - 4.0593499999999993, 0.31132160463488068, 0.029625802317440348, 4.0593499999999993, 0.3368583953651193, 0.029625802317440348, 4.0593499999999993, - 0.3368583953651193, 0.046104302854828562, 4.0593499999999993, 0.31132160463488068, 0.046104302854828562, 4.0593499999999993, 0.31132160463488068, - 0.029625802317440348, 4.2729999999999997, 0.3368583953651193, 0.029625802317440348, 4.2729999999999997, 0.3368583953651193, 0.046104302854828562, - 4.2729999999999997, 0.31132160463488068, 0.046104302854828562, 4.2729999999999997, - 0.38334160463488065, 0.025915697145171453, 0, 0.40620430285482856, 0.025915697145171453, 0, 0.40620430285482856, 0.048778395365119291, 0, - 0.38334160463488065, 0.048778395365119291, 0, 0.38334160463488065, 0.025915697145171453, 0.21364999999999998, 0.40620430285482856, 0.025915697145171453, - 0.21364999999999998, 0.40620430285482856, 0.048778395365119291, 0.21364999999999998, 0.38334160463488065, 0.048778395365119291, 0.21364999999999998, - 0.38334160463488065, 0.025915697145171453, 0.21364999999999998, 0.40620430285482856, 0.025915697145171453, 0.21364999999999998, 0.40620430285482856, - 0.048778395365119291, 0.21364999999999998, 0.38334160463488065, 0.048778395365119291, 0.21364999999999998, 0.38334160463488065, 0.025915697145171453, - 0.42729999999999996, 0.40620430285482856, 0.025915697145171453, 0.42729999999999996, 0.40620430285482856, 0.048778395365119291, 0.42729999999999996, - 0.38334160463488065, 0.048778395365119291, 0.42729999999999996, 0.38334160463488065, 0.025915697145171453, 0.42729999999999996, 0.40620430285482856, - 0.025915697145171453, 0.42729999999999996, 0.40620430285482856, 0.048778395365119291, 0.42729999999999996, 0.38334160463488065, 0.048778395365119291, - 0.42729999999999996, 0.38334160463488065, 0.025915697145171453, 0.64094999999999991, 0.40620430285482856, 0.025915697145171453, 0.64094999999999991, - 0.40620430285482856, 0.048778395365119291, 0.64094999999999991, 0.38334160463488065, 0.048778395365119291, 0.64094999999999991, 0.38334160463488065, - 0.025915697145171453, 0.64094999999999991, 0.40620430285482856, 0.025915697145171453, 0.64094999999999991, 0.40620430285482856, 0.048778395365119291, - 0.64094999999999991, 0.38334160463488065, 0.048778395365119291, 0.64094999999999991, 0.38334160463488065, 0.025915697145171453, 0.85459999999999992, - 0.40620430285482856, 0.025915697145171453, 0.85459999999999992, 0.40620430285482856, 0.048778395365119291, 0.85459999999999992, 0.38334160463488065, - 0.048778395365119291, 0.85459999999999992, 0.38334160463488065, 0.025915697145171453, 0.85459999999999992, 0.40620430285482856, 0.025915697145171453, - 0.85459999999999992, 0.40620430285482856, 0.048778395365119291, 0.85459999999999992, 0.38334160463488065, 0.048778395365119291, 0.85459999999999992, - 0.38334160463488065, 0.025915697145171453, 1.0682499999999999, 0.40620430285482856, 0.025915697145171453, 1.0682499999999999, 0.40620430285482856, - 0.048778395365119291, 1.0682499999999999, 0.38334160463488065, 0.048778395365119291, 1.0682499999999999, 0.38334160463488065, 0.025915697145171453, - 1.0682499999999999, 0.40620430285482856, 0.025915697145171453, 1.0682499999999999, 0.40620430285482856, 0.048778395365119291, 1.0682499999999999, - 0.38334160463488065, 0.048778395365119291, 1.0682499999999999, 0.38334160463488065, 0.025915697145171453, 1.2818999999999998, 0.40620430285482856, - 0.025915697145171453, 1.2818999999999998, 0.40620430285482856, 0.048778395365119291, 1.2818999999999998, 0.38334160463488065, 0.048778395365119291, - 1.2818999999999998, 0.38334160463488065, 0.025915697145171453, 1.2818999999999998, 0.40620430285482856, 0.025915697145171453, 1.2818999999999998, - 0.40620430285482856, 0.048778395365119291, 1.2818999999999998, 0.38334160463488065, 0.048778395365119291, 1.2818999999999998, 0.38334160463488065, - 0.025915697145171453, 1.4955499999999999, 0.40620430285482856, 0.025915697145171453, 1.4955499999999999, 0.40620430285482856, 0.048778395365119291, - 1.4955499999999999, 0.38334160463488065, 0.048778395365119291, 1.4955499999999999, 0.38334160463488065, 0.025915697145171453, 1.4955499999999999, - 0.40620430285482856, 0.025915697145171453, 1.4955499999999999, 0.40620430285482856, 0.048778395365119291, 1.4955499999999999, 0.38334160463488065, - 0.048778395365119291, 1.4955499999999999, 0.38334160463488065, 0.025915697145171453, 1.7091999999999998, 0.40620430285482856, 0.025915697145171453, - 1.7091999999999998, 0.40620430285482856, 0.048778395365119291, 1.7091999999999998, 0.38334160463488065, 0.048778395365119291, 1.7091999999999998, - 0.38334160463488065, 0.025915697145171453, 1.7091999999999998, 0.40620430285482856, 0.025915697145171453, 1.7091999999999998, 0.40620430285482856, - 0.048778395365119291, - 1.7091999999999998, 0.38334160463488065, 0.048778395365119291, 1.7091999999999998, 0.38334160463488065, 0.025915697145171453, 1.9228499999999997, - 0.40620430285482856, 0.025915697145171453, 1.9228499999999997, 0.40620430285482856, 0.048778395365119291, 1.9228499999999997, 0.38334160463488065, - 0.048778395365119291, 1.9228499999999997, 0.38334160463488065, 0.025915697145171453, 1.9228499999999997, 0.40620430285482856, 0.025915697145171453, - 1.9228499999999997, 0.40620430285482856, 0.048778395365119291, 1.9228499999999997, 0.38334160463488065, 0.048778395365119291, 1.9228499999999997, - 0.38334160463488065, 0.025915697145171453, 2.1364999999999998, 0.40620430285482856, 0.025915697145171453, 2.1364999999999998, 0.40620430285482856, - 0.048778395365119291, 2.1364999999999998, 0.38334160463488065, 0.048778395365119291, 2.1364999999999998, 0.38334160463488065, 0.025915697145171453, - 2.1364999999999998, 0.40620430285482856, 0.025915697145171453, 2.1364999999999998, 0.40620430285482856, 0.048778395365119291, 2.1364999999999998, - 0.38334160463488065, 0.048778395365119291, 2.1364999999999998, 0.38334160463488065, 0.025915697145171453, 2.3501499999999997, 0.40620430285482856, - 0.025915697145171453, 2.3501499999999997, 0.40620430285482856, 0.048778395365119291, 2.3501499999999997, 0.38334160463488065, 0.048778395365119291, - 2.3501499999999997, 0.38334160463488065, 0.025915697145171453, 2.3501499999999997, 0.40620430285482856, 0.025915697145171453, 2.3501499999999997, - 0.40620430285482856, 0.048778395365119291, 2.3501499999999997, 0.38334160463488065, 0.048778395365119291, 2.3501499999999997, 0.38334160463488065, - 0.025915697145171453, 2.5637999999999996, 0.40620430285482856, 0.025915697145171453, 2.5637999999999996, 0.40620430285482856, 0.048778395365119291, - 2.5637999999999996, 0.38334160463488065, 0.048778395365119291, 2.5637999999999996, 0.38334160463488065, 0.025915697145171453, 2.5637999999999996, - 0.40620430285482856, 0.025915697145171453, 2.5637999999999996, 0.40620430285482856, 0.048778395365119291, 2.5637999999999996, 0.38334160463488065, - 0.048778395365119291, 2.5637999999999996, 0.38334160463488065, 0.025915697145171453, 2.7774499999999995, 0.40620430285482856, 0.025915697145171453, - 2.7774499999999995, 0.40620430285482856, 0.048778395365119291, 2.7774499999999995, 0.38334160463488065, 0.048778395365119291, 2.7774499999999995, - 0.38334160463488065, 0.025915697145171453, 2.7774499999999995, 0.40620430285482856, 0.025915697145171453, 2.7774499999999995, 0.40620430285482856, - 0.048778395365119291, 2.7774499999999995, 0.38334160463488065, 0.048778395365119291, 2.7774499999999995, 0.38334160463488065, 0.025915697145171453, - 2.9910999999999999, 0.40620430285482856, 0.025915697145171453, 2.9910999999999999, 0.40620430285482856, 0.048778395365119291, 2.9910999999999999, - 0.38334160463488065, 0.048778395365119291, 2.9910999999999999, 0.38334160463488065, 0.025915697145171453, 2.9910999999999999, 0.40620430285482856, - 0.025915697145171453, 2.9910999999999999, 0.40620430285482856, 0.048778395365119291, 2.9910999999999999, 0.38334160463488065, 0.048778395365119291, - 2.9910999999999999, 0.38334160463488065, 0.025915697145171453, 3.2047499999999998, 0.40620430285482856, 0.025915697145171453, 3.2047499999999998, - 0.40620430285482856, 0.048778395365119291, 3.2047499999999998, 0.38334160463488065, 0.048778395365119291, 3.2047499999999998, 0.38334160463488065, - 0.025915697145171453, 3.2047499999999998, 0.40620430285482856, 0.025915697145171453, 3.2047499999999998, 0.40620430285482856, 0.048778395365119291, - 3.2047499999999998, 0.38334160463488065, 0.048778395365119291, 3.2047499999999998, 0.38334160463488065, 0.025915697145171453, 3.4183999999999997, - 0.40620430285482856, 0.025915697145171453, 3.4183999999999997, 0.40620430285482856, 0.048778395365119291, 3.4183999999999997, 0.38334160463488065, - 0.048778395365119291, 3.4183999999999997, 0.38334160463488065, 0.025915697145171453, 3.4183999999999997, 0.40620430285482856, 0.025915697145171453, - 3.4183999999999997, 0.40620430285482856, 0.048778395365119291, 3.4183999999999997, 0.38334160463488065, 0.048778395365119291, 3.4183999999999997, - 0.38334160463488065, 0.025915697145171453, 3.6320499999999996, 0.40620430285482856, - 0.025915697145171453, 3.6320499999999996, 0.40620430285482856, 0.048778395365119291, 3.6320499999999996, 0.38334160463488065, 0.048778395365119291, - 3.6320499999999996, 0.38334160463488065, 0.025915697145171453, 3.6320499999999996, 0.40620430285482856, 0.025915697145171453, 3.6320499999999996, - 0.40620430285482856, 0.048778395365119291, 3.6320499999999996, 0.38334160463488065, 0.048778395365119291, 3.6320499999999996, 0.38334160463488065, - 0.025915697145171453, 3.8456999999999995, 0.40620430285482856, 0.025915697145171453, 3.8456999999999995, 0.40620430285482856, 0.048778395365119291, - 3.8456999999999995, 0.38334160463488065, 0.048778395365119291, 3.8456999999999995, 0.38334160463488065, 0.025915697145171453, 3.8456999999999995, - 0.40620430285482856, 0.025915697145171453, 3.8456999999999995, 0.40620430285482856, 0.048778395365119291, 3.8456999999999995, 0.38334160463488065, - 0.048778395365119291, 3.8456999999999995, 0.38334160463488065, 0.025915697145171453, 4.0593499999999993, 0.40620430285482856, 0.025915697145171453, - 4.0593499999999993, 0.40620430285482856, 0.048778395365119291, 4.0593499999999993, 0.38334160463488065, 0.048778395365119291, 4.0593499999999993, - 0.38334160463488065, 0.025915697145171453, 4.0593499999999993, 0.40620430285482856, 0.025915697145171453, 4.0593499999999993, 0.40620430285482856, - 0.048778395365119291, 4.0593499999999993, 0.38334160463488065, 0.048778395365119291, 4.0593499999999993, 0.38334160463488065, 0.025915697145171453, - 4.2729999999999997, 0.40620430285482856, 0.025915697145171453, 4.2729999999999997, 0.40620430285482856, 0.048778395365119291, 4.2729999999999997, - 0.38334160463488065, 0.048778395365119291, 4.2729999999999997, 0.24568580231744036, 0.095261604634880703, 0, 0.26216430285482856, 0.095261604634880703, 0, - 0.26216430285482856, 0.1207983953651193, 0, 0.24568580231744036, 0.1207983953651193, 0, 0.24568580231744036, 0.095261604634880703, 0.21364999999999998, - 0.26216430285482856, 0.095261604634880703, 0.21364999999999998, 0.26216430285482856, 0.1207983953651193, 0.21364999999999998, 0.24568580231744036, - 0.1207983953651193, 0.21364999999999998, 0.24568580231744036, 0.095261604634880703, 0.21364999999999998, 0.26216430285482856, 0.095261604634880703, - 0.21364999999999998, 0.26216430285482856, 0.1207983953651193, 0.21364999999999998, 0.24568580231744036, 0.1207983953651193, 0.21364999999999998, - 0.24568580231744036, 0.095261604634880703, 0.42729999999999996, 0.26216430285482856, 0.095261604634880703, 0.42729999999999996, 0.26216430285482856, - 0.1207983953651193, 0.42729999999999996, 0.24568580231744036, 0.1207983953651193, 0.42729999999999996, 0.24568580231744036, 0.095261604634880703, - 0.42729999999999996, 0.26216430285482856, 0.095261604634880703, 0.42729999999999996, 0.26216430285482856, 0.1207983953651193, 0.42729999999999996, - 0.24568580231744036, 0.1207983953651193, 0.42729999999999996, 0.24568580231744036, 0.095261604634880703, 0.64094999999999991, 0.26216430285482856, - 0.095261604634880703, 0.64094999999999991, 0.26216430285482856, 0.1207983953651193, 0.64094999999999991, 0.24568580231744036, 0.1207983953651193, - 0.64094999999999991, 0.24568580231744036, 0.095261604634880703, 0.64094999999999991, 0.26216430285482856, 0.095261604634880703, 0.64094999999999991, - 0.26216430285482856, 0.1207983953651193, 0.64094999999999991, 0.24568580231744036, 0.1207983953651193, 0.64094999999999991, 0.24568580231744036, - 0.095261604634880703, 0.85459999999999992, 0.26216430285482856, 0.095261604634880703, 0.85459999999999992, 0.26216430285482856, 0.1207983953651193, - 0.85459999999999992, 0.24568580231744036, 0.1207983953651193, 0.85459999999999992, 0.24568580231744036, 0.095261604634880703, 0.85459999999999992, - 0.26216430285482856, 0.095261604634880703, 0.85459999999999992, 0.26216430285482856, 0.1207983953651193, 0.85459999999999992, 0.24568580231744036, - 0.1207983953651193, 0.85459999999999992, 0.24568580231744036, 0.095261604634880703, 1.0682499999999999, 0.26216430285482856, 0.095261604634880703, - 1.0682499999999999, 0.26216430285482856, 0.1207983953651193, 1.0682499999999999, 0.24568580231744036, 0.1207983953651193, 1.0682499999999999, - 0.24568580231744036, 0.095261604634880703, 1.0682499999999999, 0.26216430285482856, 0.095261604634880703, 1.0682499999999999, 0.26216430285482856, - 0.1207983953651193, 1.0682499999999999, 0.24568580231744036, 0.1207983953651193, 1.0682499999999999, 0.24568580231744036, 0.095261604634880703, - 1.2818999999999998, 0.26216430285482856, 0.095261604634880703, 1.2818999999999998, 0.26216430285482856, 0.1207983953651193, 1.2818999999999998, - 0.24568580231744036, 0.1207983953651193, 1.2818999999999998, 0.24568580231744036, 0.095261604634880703, 1.2818999999999998, 0.26216430285482856, - 0.095261604634880703, 1.2818999999999998, 0.26216430285482856, 0.1207983953651193, 1.2818999999999998, 0.24568580231744036, 0.1207983953651193, - 1.2818999999999998, 0.24568580231744036, 0.095261604634880703, 1.4955499999999999, 0.26216430285482856, 0.095261604634880703, 1.4955499999999999, - 0.26216430285482856, 0.1207983953651193, 1.4955499999999999, 0.24568580231744036, 0.1207983953651193, 1.4955499999999999, 0.24568580231744036, - 0.095261604634880703, 1.4955499999999999, 0.26216430285482856, 0.095261604634880703, 1.4955499999999999, 0.26216430285482856, 0.1207983953651193, - 1.4955499999999999, 0.24568580231744036, 0.1207983953651193, 1.4955499999999999, 0.24568580231744036, 0.095261604634880703, 1.7091999999999998, - 0.26216430285482856, 0.095261604634880703, 1.7091999999999998, 0.26216430285482856, 0.1207983953651193, 1.7091999999999998, 0.24568580231744036, - 0.1207983953651193, 1.7091999999999998, 0.24568580231744036, 0.095261604634880703, 1.7091999999999998, 0.26216430285482856, 0.095261604634880703, - 1.7091999999999998, 0.26216430285482856, 0.1207983953651193, 1.7091999999999998, 0.24568580231744036, 0.1207983953651193, 1.7091999999999998, - 0.24568580231744036, 0.095261604634880703, 1.9228499999999997, 0.26216430285482856, 0.095261604634880703, 1.9228499999999997, 0.26216430285482856, - 0.1207983953651193, 1.9228499999999997, 0.24568580231744036, 0.1207983953651193, 1.9228499999999997, 0.24568580231744036, 0.095261604634880703, - 1.9228499999999997, 0.26216430285482856, 0.095261604634880703, 1.9228499999999997, 0.26216430285482856, 0.1207983953651193, 1.9228499999999997, - 0.24568580231744036, 0.1207983953651193, 1.9228499999999997, 0.24568580231744036, 0.095261604634880703, 2.1364999999999998, 0.26216430285482856, - 0.095261604634880703, 2.1364999999999998, 0.26216430285482856, 0.1207983953651193, 2.1364999999999998, 0.24568580231744036, 0.1207983953651193, - 2.1364999999999998, 0.24568580231744036, 0.095261604634880703, 2.1364999999999998, 0.26216430285482856, 0.095261604634880703, 2.1364999999999998, - 0.26216430285482856, 0.1207983953651193, 2.1364999999999998, 0.24568580231744036, 0.1207983953651193, 2.1364999999999998, 0.24568580231744036, - 0.095261604634880703, 2.3501499999999997, 0.26216430285482856, 0.095261604634880703, 2.3501499999999997, 0.26216430285482856, 0.1207983953651193, - 2.3501499999999997, 0.24568580231744036, 0.1207983953651193, 2.3501499999999997, 0.24568580231744036, 0.095261604634880703, 2.3501499999999997, - 0.26216430285482856, 0.095261604634880703, 2.3501499999999997, 0.26216430285482856, 0.1207983953651193, 2.3501499999999997, 0.24568580231744036, - 0.1207983953651193, 2.3501499999999997, 0.24568580231744036, 0.095261604634880703, 2.5637999999999996, 0.26216430285482856, 0.095261604634880703, - 2.5637999999999996, 0.26216430285482856, 0.1207983953651193, 2.5637999999999996, 0.24568580231744036, 0.1207983953651193, 2.5637999999999996, - 0.24568580231744036, 0.095261604634880703, 2.5637999999999996, 0.26216430285482856, 0.095261604634880703, 2.5637999999999996, 0.26216430285482856, - 0.1207983953651193, 2.5637999999999996, 0.24568580231744036, 0.1207983953651193, 2.5637999999999996, 0.24568580231744036, 0.095261604634880703, - 2.7774499999999995, 0.26216430285482856, 0.095261604634880703, 2.7774499999999995, 0.26216430285482856, 0.1207983953651193, 2.7774499999999995, - 0.24568580231744036, 0.1207983953651193, 2.7774499999999995, 0.24568580231744036, 0.095261604634880703, 2.7774499999999995, 0.26216430285482856, - 0.095261604634880703, 2.7774499999999995, 0.26216430285482856, 0.1207983953651193, - 2.7774499999999995, 0.24568580231744036, 0.1207983953651193, 2.7774499999999995, 0.24568580231744036, 0.095261604634880703, 2.9910999999999999, - 0.26216430285482856, 0.095261604634880703, 2.9910999999999999, 0.26216430285482856, 0.1207983953651193, 2.9910999999999999, 0.24568580231744036, - 0.1207983953651193, 2.9910999999999999, 0.24568580231744036, 0.095261604634880703, 2.9910999999999999, 0.26216430285482856, 0.095261604634880703, - 2.9910999999999999, 0.26216430285482856, 0.1207983953651193, 2.9910999999999999, 0.24568580231744036, 0.1207983953651193, 2.9910999999999999, - 0.24568580231744036, 0.095261604634880703, 3.2047499999999998, 0.26216430285482856, 0.095261604634880703, 3.2047499999999998, 0.26216430285482856, - 0.1207983953651193, 3.2047499999999998, 0.24568580231744036, 0.1207983953651193, 3.2047499999999998, 0.24568580231744036, 0.095261604634880703, - 3.2047499999999998, 0.26216430285482856, 0.095261604634880703, 3.2047499999999998, 0.26216430285482856, 0.1207983953651193, 3.2047499999999998, - 0.24568580231744036, 0.1207983953651193, 3.2047499999999998, 0.24568580231744036, 0.095261604634880703, 3.4183999999999997, 0.26216430285482856, - 0.095261604634880703, 3.4183999999999997, 0.26216430285482856, 0.1207983953651193, 3.4183999999999997, 0.24568580231744036, 0.1207983953651193, - 3.4183999999999997, 0.24568580231744036, 0.095261604634880703, 3.4183999999999997, 0.26216430285482856, 0.095261604634880703, 3.4183999999999997, - 0.26216430285482856, 0.1207983953651193, 3.4183999999999997, 0.24568580231744036, 0.1207983953651193, 3.4183999999999997, 0.24568580231744036, - 0.095261604634880703, 3.6320499999999996, 0.26216430285482856, 0.095261604634880703, 3.6320499999999996, 0.26216430285482856, 0.1207983953651193, - 3.6320499999999996, 0.24568580231744036, 0.1207983953651193, 3.6320499999999996, 0.24568580231744036, 0.095261604634880703, 3.6320499999999996, - 0.26216430285482856, 0.095261604634880703, 3.6320499999999996, 0.26216430285482856, 0.1207983953651193, 3.6320499999999996, 0.24568580231744036, - 0.1207983953651193, 3.6320499999999996, 0.24568580231744036, 0.095261604634880703, 3.8456999999999995, 0.26216430285482856, 0.095261604634880703, - 3.8456999999999995, 0.26216430285482856, 0.1207983953651193, 3.8456999999999995, 0.24568580231744036, 0.1207983953651193, 3.8456999999999995, - 0.24568580231744036, 0.095261604634880703, 3.8456999999999995, 0.26216430285482856, 0.095261604634880703, 3.8456999999999995, 0.26216430285482856, - 0.1207983953651193, 3.8456999999999995, 0.24568580231744036, 0.1207983953651193, 3.8456999999999995, 0.24568580231744036, 0.095261604634880703, - 4.0593499999999993, 0.26216430285482856, 0.095261604634880703, 4.0593499999999993, 0.26216430285482856, 0.1207983953651193, 4.0593499999999993, - 0.24568580231744036, 0.1207983953651193, 4.0593499999999993, 0.24568580231744036, 0.095261604634880703, 4.0593499999999993, 0.26216430285482856, - 0.095261604634880703, 4.0593499999999993, 0.26216430285482856, 0.1207983953651193, 4.0593499999999993, 0.24568580231744036, 0.1207983953651193, - 4.0593499999999993, 0.24568580231744036, 0.095261604634880703, 4.2729999999999997, 0.26216430285482856, 0.095261604634880703, 4.2729999999999997, - 0.26216430285482856, 0.1207983953651193, 4.2729999999999997, 0.24568580231744036, 0.1207983953651193, 4.2729999999999997, 0.31399569714517145, - 0.097935697145171446, 0, 0.33418430285482853, 0.097935697145171446, 0, 0.33418430285482853, 0.11812430285482856, 0, 0.31399569714517145, 0.11812430285482856, 0, - 0.31399569714517145, 0.097935697145171446, 0.21364999999999998, 0.33418430285482853, 0.097935697145171446, 0.21364999999999998, 0.33418430285482853, - 0.11812430285482856, 0.21364999999999998, 0.31399569714517145, 0.11812430285482856, 0.21364999999999998, 0.31399569714517145, 0.097935697145171446, - 0.21364999999999998, 0.33418430285482853, 0.097935697145171446, 0.21364999999999998, 0.33418430285482853, 0.11812430285482856, 0.21364999999999998, - 0.31399569714517145, 0.11812430285482856, 0.21364999999999998, 0.31399569714517145, 0.097935697145171446, 0.42729999999999996, 0.33418430285482853, - 0.097935697145171446, 0.42729999999999996, 0.33418430285482853, 0.11812430285482856, 0.42729999999999996, 0.31399569714517145, 0.11812430285482856, - 0.42729999999999996, 0.31399569714517145, 0.097935697145171446, 0.42729999999999996, 0.33418430285482853, 0.097935697145171446, 0.42729999999999996, - 0.33418430285482853, 0.11812430285482856, 0.42729999999999996, 0.31399569714517145, 0.11812430285482856, 0.42729999999999996, 0.31399569714517145, - 0.097935697145171446, 0.64094999999999991, 0.33418430285482853, 0.097935697145171446, 0.64094999999999991, 0.33418430285482853, 0.11812430285482856, - 0.64094999999999991, 0.31399569714517145, 0.11812430285482856, 0.64094999999999991, 0.31399569714517145, 0.097935697145171446, 0.64094999999999991, - 0.33418430285482853, 0.097935697145171446, 0.64094999999999991, 0.33418430285482853, 0.11812430285482856, 0.64094999999999991, 0.31399569714517145, - 0.11812430285482856, 0.64094999999999991, 0.31399569714517145, 0.097935697145171446, 0.85459999999999992, 0.33418430285482853, 0.097935697145171446, - 0.85459999999999992, 0.33418430285482853, 0.11812430285482856, 0.85459999999999992, 0.31399569714517145, 0.11812430285482856, 0.85459999999999992, - 0.31399569714517145, 0.097935697145171446, 0.85459999999999992, 0.33418430285482853, 0.097935697145171446, 0.85459999999999992, 0.33418430285482853, - 0.11812430285482856, 0.85459999999999992, 0.31399569714517145, 0.11812430285482856, 0.85459999999999992, 0.31399569714517145, 0.097935697145171446, - 1.0682499999999999, 0.33418430285482853, 0.097935697145171446, 1.0682499999999999, 0.33418430285482853, 0.11812430285482856, 1.0682499999999999, - 0.31399569714517145, 0.11812430285482856, 1.0682499999999999, 0.31399569714517145, 0.097935697145171446, 1.0682499999999999, 0.33418430285482853, - 0.097935697145171446, 1.0682499999999999, 0.33418430285482853, 0.11812430285482856, 1.0682499999999999, 0.31399569714517145, 0.11812430285482856, - 1.0682499999999999, 0.31399569714517145, 0.097935697145171446, 1.2818999999999998, 0.33418430285482853, 0.097935697145171446, 1.2818999999999998, - 0.33418430285482853, 0.11812430285482856, 1.2818999999999998, 0.31399569714517145, 0.11812430285482856, 1.2818999999999998, 0.31399569714517145, - 0.097935697145171446, 1.2818999999999998, 0.33418430285482853, 0.097935697145171446, 1.2818999999999998, 0.33418430285482853, 0.11812430285482856, - 1.2818999999999998, 0.31399569714517145, 0.11812430285482856, 1.2818999999999998, 0.31399569714517145, 0.097935697145171446, 1.4955499999999999, - 0.33418430285482853, 0.097935697145171446, 1.4955499999999999, 0.33418430285482853, 0.11812430285482856, 1.4955499999999999, 0.31399569714517145, - 0.11812430285482856, 1.4955499999999999, 0.31399569714517145, 0.097935697145171446, 1.4955499999999999, 0.33418430285482853, 0.097935697145171446, - 1.4955499999999999, 0.33418430285482853, 0.11812430285482856, 1.4955499999999999, 0.31399569714517145, 0.11812430285482856, 1.4955499999999999, - 0.31399569714517145, 0.097935697145171446, 1.7091999999999998, 0.33418430285482853, 0.097935697145171446, 1.7091999999999998, 0.33418430285482853, - 0.11812430285482856, 1.7091999999999998, 0.31399569714517145, 0.11812430285482856, 1.7091999999999998, 0.31399569714517145, 0.097935697145171446, - 1.7091999999999998, 0.33418430285482853, 0.097935697145171446, 1.7091999999999998, 0.33418430285482853, 0.11812430285482856, 1.7091999999999998, - 0.31399569714517145, 0.11812430285482856, 1.7091999999999998, 0.31399569714517145, 0.097935697145171446, 1.9228499999999997, 0.33418430285482853, - 0.097935697145171446, 1.9228499999999997, 0.33418430285482853, 0.11812430285482856, 1.9228499999999997, 0.31399569714517145, 0.11812430285482856, - 1.9228499999999997, 0.31399569714517145, 0.097935697145171446, 1.9228499999999997, 0.33418430285482853, 0.097935697145171446, 1.9228499999999997, - 0.33418430285482853, 0.11812430285482856, 1.9228499999999997, 0.31399569714517145, 0.11812430285482856, 1.9228499999999997, 0.31399569714517145, - 0.097935697145171446, 2.1364999999999998, 0.33418430285482853, 0.097935697145171446, 2.1364999999999998, 0.33418430285482853, 0.11812430285482856, - 2.1364999999999998, 0.31399569714517145, 0.11812430285482856, 2.1364999999999998, - 0.31399569714517145, 0.097935697145171446, 2.1364999999999998, 0.33418430285482853, 0.097935697145171446, 2.1364999999999998, 0.33418430285482853, - 0.11812430285482856, 2.1364999999999998, 0.31399569714517145, 0.11812430285482856, 2.1364999999999998, 0.31399569714517145, 0.097935697145171446, - 2.3501499999999997, 0.33418430285482853, 0.097935697145171446, 2.3501499999999997, 0.33418430285482853, 0.11812430285482856, 2.3501499999999997, - 0.31399569714517145, 0.11812430285482856, 2.3501499999999997, 0.31399569714517145, 0.097935697145171446, 2.3501499999999997, 0.33418430285482853, - 0.097935697145171446, 2.3501499999999997, 0.33418430285482853, 0.11812430285482856, 2.3501499999999997, 0.31399569714517145, 0.11812430285482856, - 2.3501499999999997, 0.31399569714517145, 0.097935697145171446, 2.5637999999999996, 0.33418430285482853, 0.097935697145171446, 2.5637999999999996, - 0.33418430285482853, 0.11812430285482856, 2.5637999999999996, 0.31399569714517145, 0.11812430285482856, 2.5637999999999996, 0.31399569714517145, - 0.097935697145171446, 2.5637999999999996, 0.33418430285482853, 0.097935697145171446, 2.5637999999999996, 0.33418430285482853, 0.11812430285482856, - 2.5637999999999996, 0.31399569714517145, 0.11812430285482856, 2.5637999999999996, 0.31399569714517145, 0.097935697145171446, 2.7774499999999995, - 0.33418430285482853, 0.097935697145171446, 2.7774499999999995, 0.33418430285482853, 0.11812430285482856, 2.7774499999999995, 0.31399569714517145, - 0.11812430285482856, 2.7774499999999995, 0.31399569714517145, 0.097935697145171446, 2.7774499999999995, 0.33418430285482853, 0.097935697145171446, - 2.7774499999999995, 0.33418430285482853, 0.11812430285482856, 2.7774499999999995, 0.31399569714517145, 0.11812430285482856, 2.7774499999999995, - 0.31399569714517145, 0.097935697145171446, 2.9910999999999999, 0.33418430285482853, 0.097935697145171446, 2.9910999999999999, 0.33418430285482853, - 0.11812430285482856, 2.9910999999999999, 0.31399569714517145, 0.11812430285482856, 2.9910999999999999, 0.31399569714517145, 0.097935697145171446, - 2.9910999999999999, 0.33418430285482853, 0.097935697145171446, 2.9910999999999999, 0.33418430285482853, 0.11812430285482856, 2.9910999999999999, - 0.31399569714517145, 0.11812430285482856, 2.9910999999999999, 0.31399569714517145, 0.097935697145171446, 3.2047499999999998, 0.33418430285482853, - 0.097935697145171446, 3.2047499999999998, 0.33418430285482853, 0.11812430285482856, 3.2047499999999998, 0.31399569714517145, 0.11812430285482856, - 3.2047499999999998, 0.31399569714517145, 0.097935697145171446, 3.2047499999999998, 0.33418430285482853, 0.097935697145171446, 3.2047499999999998, - 0.33418430285482853, 0.11812430285482856, 3.2047499999999998, 0.31399569714517145, 0.11812430285482856, 3.2047499999999998, 0.31399569714517145, - 0.097935697145171446, 3.4183999999999997, 0.33418430285482853, 0.097935697145171446, 3.4183999999999997, 0.33418430285482853, 0.11812430285482856, - 3.4183999999999997, 0.31399569714517145, 0.11812430285482856, 3.4183999999999997, 0.31399569714517145, 0.097935697145171446, 3.4183999999999997, - 0.33418430285482853, 0.097935697145171446, 3.4183999999999997, 0.33418430285482853, 0.11812430285482856, 3.4183999999999997, 0.31399569714517145, - 0.11812430285482856, 3.4183999999999997, 0.31399569714517145, 0.097935697145171446, 3.6320499999999996, 0.33418430285482853, 0.097935697145171446, - 3.6320499999999996, 0.33418430285482853, 0.11812430285482856, 3.6320499999999996, 0.31399569714517145, 0.11812430285482856, 3.6320499999999996, - 0.31399569714517145, 0.097935697145171446, 3.6320499999999996, 0.33418430285482853, 0.097935697145171446, 3.6320499999999996, 0.33418430285482853, - 0.11812430285482856, 3.6320499999999996, 0.31399569714517145, 0.11812430285482856, 3.6320499999999996, 0.31399569714517145, 0.097935697145171446, - 3.8456999999999995, 0.33418430285482853, 0.097935697145171446, 3.8456999999999995, 0.33418430285482853, 0.11812430285482856, 3.8456999999999995, - 0.31399569714517145, 0.11812430285482856, 3.8456999999999995, 0.31399569714517145, 0.097935697145171446, 3.8456999999999995, 0.33418430285482853, - 0.097935697145171446, 3.8456999999999995, 0.33418430285482853, 0.11812430285482856, - 3.8456999999999995, 0.31399569714517145, 0.11812430285482856, 3.8456999999999995, 0.31399569714517145, 0.097935697145171446, 4.0593499999999993, - 0.33418430285482853, 0.097935697145171446, 4.0593499999999993, 0.33418430285482853, 0.11812430285482856, 4.0593499999999993, 0.31399569714517145, - 0.11812430285482856, 4.0593499999999993, 0.31399569714517145, 0.097935697145171446, 4.0593499999999993, 0.33418430285482853, 0.097935697145171446, - 4.0593499999999993, 0.33418430285482853, 0.11812430285482856, 4.0593499999999993, 0.31399569714517145, 0.11812430285482856, 4.0593499999999993, - 0.31399569714517145, 0.097935697145171446, 4.2729999999999997, 0.33418430285482853, 0.097935697145171446, 4.2729999999999997, 0.33418430285482853, - 0.11812430285482856, 4.2729999999999997, 0.31399569714517145, 0.11812430285482856, 4.2729999999999997, 0.38601569714517142, 0.095261604634880703, 0, - 0.40249419768255962, 0.095261604634880703, 0, 0.40249419768255962, 0.1207983953651193, 0, 0.38601569714517142, 0.1207983953651193, 0, 0.38601569714517142, - 0.095261604634880703, 0.21364999999999998, 0.40249419768255962, 0.095261604634880703, 0.21364999999999998, 0.40249419768255962, 0.1207983953651193, - 0.21364999999999998, 0.38601569714517142, 0.1207983953651193, 0.21364999999999998, 0.38601569714517142, 0.095261604634880703, 0.21364999999999998, - 0.40249419768255962, 0.095261604634880703, 0.21364999999999998, 0.40249419768255962, 0.1207983953651193, 0.21364999999999998, 0.38601569714517142, - 0.1207983953651193, 0.21364999999999998, 0.38601569714517142, 0.095261604634880703, 0.42729999999999996, 0.40249419768255962, 0.095261604634880703, - 0.42729999999999996, 0.40249419768255962, 0.1207983953651193, 0.42729999999999996, 0.38601569714517142, 0.1207983953651193, 0.42729999999999996, - 0.38601569714517142, 0.095261604634880703, 0.42729999999999996, 0.40249419768255962, 0.095261604634880703, 0.42729999999999996, 0.40249419768255962, - 0.1207983953651193, 0.42729999999999996, 0.38601569714517142, 0.1207983953651193, 0.42729999999999996, 0.38601569714517142, 0.095261604634880703, - 0.64094999999999991, 0.40249419768255962, 0.095261604634880703, 0.64094999999999991, 0.40249419768255962, 0.1207983953651193, 0.64094999999999991, - 0.38601569714517142, 0.1207983953651193, 0.64094999999999991, 0.38601569714517142, 0.095261604634880703, 0.64094999999999991, 0.40249419768255962, - 0.095261604634880703, 0.64094999999999991, 0.40249419768255962, 0.1207983953651193, 0.64094999999999991, 0.38601569714517142, 0.1207983953651193, - 0.64094999999999991, 0.38601569714517142, 0.095261604634880703, 0.85459999999999992, 0.40249419768255962, 0.095261604634880703, 0.85459999999999992, - 0.40249419768255962, 0.1207983953651193, 0.85459999999999992, 0.38601569714517142, 0.1207983953651193, 0.85459999999999992, 0.38601569714517142, - 0.095261604634880703, 0.85459999999999992, 0.40249419768255962, 0.095261604634880703, 0.85459999999999992, 0.40249419768255962, 0.1207983953651193, - 0.85459999999999992, 0.38601569714517142, 0.1207983953651193, 0.85459999999999992, 0.38601569714517142, 0.095261604634880703, 1.0682499999999999, - 0.40249419768255962, 0.095261604634880703, 1.0682499999999999, 0.40249419768255962, 0.1207983953651193, 1.0682499999999999, 0.38601569714517142, - 0.1207983953651193, 1.0682499999999999, 0.38601569714517142, 0.095261604634880703, 1.0682499999999999, 0.40249419768255962, 0.095261604634880703, - 1.0682499999999999, 0.40249419768255962, 0.1207983953651193, 1.0682499999999999, 0.38601569714517142, 0.1207983953651193, 1.0682499999999999, - 0.38601569714517142, 0.095261604634880703, 1.2818999999999998, 0.40249419768255962, 0.095261604634880703, 1.2818999999999998, 0.40249419768255962, - 0.1207983953651193, 1.2818999999999998, 0.38601569714517142, 0.1207983953651193, 1.2818999999999998, 0.38601569714517142, 0.095261604634880703, - 1.2818999999999998, 0.40249419768255962, 0.095261604634880703, 1.2818999999999998, 0.40249419768255962, 0.1207983953651193, 1.2818999999999998, - 0.38601569714517142, 0.1207983953651193, 1.2818999999999998, 0.38601569714517142, 0.095261604634880703, 1.4955499999999999, 0.40249419768255962, - 0.095261604634880703, 1.4955499999999999, 0.40249419768255962, 0.1207983953651193, 1.4955499999999999, 0.38601569714517142, 0.1207983953651193, - 1.4955499999999999, 0.38601569714517142, 0.095261604634880703, 1.4955499999999999, 0.40249419768255962, 0.095261604634880703, 1.4955499999999999, - 0.40249419768255962, 0.1207983953651193, 1.4955499999999999, 0.38601569714517142, 0.1207983953651193, 1.4955499999999999, 0.38601569714517142, - 0.095261604634880703, 1.7091999999999998, 0.40249419768255962, 0.095261604634880703, 1.7091999999999998, 0.40249419768255962, 0.1207983953651193, - 1.7091999999999998, 0.38601569714517142, 0.1207983953651193, 1.7091999999999998, 0.38601569714517142, 0.095261604634880703, 1.7091999999999998, - 0.40249419768255962, 0.095261604634880703, 1.7091999999999998, 0.40249419768255962, 0.1207983953651193, 1.7091999999999998, 0.38601569714517142, - 0.1207983953651193, 1.7091999999999998, 0.38601569714517142, 0.095261604634880703, 1.9228499999999997, 0.40249419768255962, 0.095261604634880703, - 1.9228499999999997, 0.40249419768255962, 0.1207983953651193, 1.9228499999999997, 0.38601569714517142, 0.1207983953651193, 1.9228499999999997, - 0.38601569714517142, 0.095261604634880703, 1.9228499999999997, 0.40249419768255962, 0.095261604634880703, 1.9228499999999997, 0.40249419768255962, - 0.1207983953651193, 1.9228499999999997, 0.38601569714517142, 0.1207983953651193, 1.9228499999999997, 0.38601569714517142, 0.095261604634880703, - 2.1364999999999998, 0.40249419768255962, 0.095261604634880703, 2.1364999999999998, 0.40249419768255962, 0.1207983953651193, 2.1364999999999998, - 0.38601569714517142, 0.1207983953651193, 2.1364999999999998, 0.38601569714517142, 0.095261604634880703, 2.1364999999999998, 0.40249419768255962, - 0.095261604634880703, 2.1364999999999998, 0.40249419768255962, 0.1207983953651193, 2.1364999999999998, 0.38601569714517142, 0.1207983953651193, - 2.1364999999999998, 0.38601569714517142, 0.095261604634880703, 2.3501499999999997, 0.40249419768255962, 0.095261604634880703, 2.3501499999999997, - 0.40249419768255962, 0.1207983953651193, 2.3501499999999997, 0.38601569714517142, 0.1207983953651193, 2.3501499999999997, 0.38601569714517142, - 0.095261604634880703, 2.3501499999999997, 0.40249419768255962, 0.095261604634880703, 2.3501499999999997, 0.40249419768255962, 0.1207983953651193, - 2.3501499999999997, 0.38601569714517142, 0.1207983953651193, 2.3501499999999997, 0.38601569714517142, 0.095261604634880703, 2.5637999999999996, - 0.40249419768255962, 0.095261604634880703, 2.5637999999999996, 0.40249419768255962, 0.1207983953651193, 2.5637999999999996, 0.38601569714517142, - 0.1207983953651193, 2.5637999999999996, 0.38601569714517142, 0.095261604634880703, 2.5637999999999996, 0.40249419768255962, 0.095261604634880703, - 2.5637999999999996, 0.40249419768255962, 0.1207983953651193, 2.5637999999999996, 0.38601569714517142, 0.1207983953651193, 2.5637999999999996, - 0.38601569714517142, 0.095261604634880703, 2.7774499999999995, 0.40249419768255962, 0.095261604634880703, 2.7774499999999995, 0.40249419768255962, - 0.1207983953651193, 2.7774499999999995, 0.38601569714517142, 0.1207983953651193, 2.7774499999999995, 0.38601569714517142, 0.095261604634880703, - 2.7774499999999995, 0.40249419768255962, 0.095261604634880703, 2.7774499999999995, 0.40249419768255962, 0.1207983953651193, 2.7774499999999995, - 0.38601569714517142, 0.1207983953651193, 2.7774499999999995, 0.38601569714517142, 0.095261604634880703, 2.9910999999999999, 0.40249419768255962, - 0.095261604634880703, 2.9910999999999999, 0.40249419768255962, 0.1207983953651193, 2.9910999999999999, 0.38601569714517142, 0.1207983953651193, - 2.9910999999999999, 0.38601569714517142, 0.095261604634880703, 2.9910999999999999, 0.40249419768255962, 0.095261604634880703, 2.9910999999999999, - 0.40249419768255962, 0.1207983953651193, 2.9910999999999999, 0.38601569714517142, 0.1207983953651193, 2.9910999999999999, 0.38601569714517142, - 0.095261604634880703, 3.2047499999999998, 0.40249419768255962, 0.095261604634880703, 3.2047499999999998, 0.40249419768255962, 0.1207983953651193, - 3.2047499999999998, 0.38601569714517142, 0.1207983953651193, 3.2047499999999998, - 0.38601569714517142, 0.095261604634880703, 3.2047499999999998, 0.40249419768255962, 0.095261604634880703, 3.2047499999999998, 0.40249419768255962, - 0.1207983953651193, 3.2047499999999998, 0.38601569714517142, 0.1207983953651193, 3.2047499999999998, 0.38601569714517142, 0.095261604634880703, - 3.4183999999999997, 0.40249419768255962, 0.095261604634880703, 3.4183999999999997, 0.40249419768255962, 0.1207983953651193, 3.4183999999999997, - 0.38601569714517142, 0.1207983953651193, 3.4183999999999997, 0.38601569714517142, 0.095261604634880703, 3.4183999999999997, 0.40249419768255962, - 0.095261604634880703, 3.4183999999999997, 0.40249419768255962, 0.1207983953651193, 3.4183999999999997, 0.38601569714517142, 0.1207983953651193, - 3.4183999999999997, 0.38601569714517142, 0.095261604634880703, 3.6320499999999996, 0.40249419768255962, 0.095261604634880703, 3.6320499999999996, - 0.40249419768255962, 0.1207983953651193, 3.6320499999999996, 0.38601569714517142, 0.1207983953651193, 3.6320499999999996, 0.38601569714517142, - 0.095261604634880703, 3.6320499999999996, 0.40249419768255962, 0.095261604634880703, 3.6320499999999996, 0.40249419768255962, 0.1207983953651193, - 3.6320499999999996, 0.38601569714517142, 0.1207983953651193, 3.6320499999999996, 0.38601569714517142, 0.095261604634880703, 3.8456999999999995, - 0.40249419768255962, 0.095261604634880703, 3.8456999999999995, 0.40249419768255962, 0.1207983953651193, 3.8456999999999995, 0.38601569714517142, - 0.1207983953651193, 3.8456999999999995, 0.38601569714517142, 0.095261604634880703, 3.8456999999999995, 0.40249419768255962, 0.095261604634880703, - 3.8456999999999995, 0.40249419768255962, 0.1207983953651193, 3.8456999999999995, 0.38601569714517142, 0.1207983953651193, 3.8456999999999995, - 0.38601569714517142, 0.095261604634880703, 4.0593499999999993, 0.40249419768255962, 0.095261604634880703, 4.0593499999999993, 0.40249419768255962, - 0.1207983953651193, 4.0593499999999993, 0.38601569714517142, 0.1207983953651193, 4.0593499999999993, 0.38601569714517142, 0.095261604634880703, - 4.0593499999999993, 0.40249419768255962, 0.095261604634880703, 4.0593499999999993, 0.40249419768255962, 0.1207983953651193, 4.0593499999999993, - 0.38601569714517142, 0.1207983953651193, 4.0593499999999993, 0.38601569714517142, 0.095261604634880703, 4.2729999999999997, 0.40249419768255962, - 0.095261604634880703, 4.2729999999999997, 0.40249419768255962, 0.1207983953651193, 4.2729999999999997, 0.38601569714517142, 0.1207983953651193, - 4.2729999999999997, 0.24197569714517148, 0.16728160463488068, 0, 0.26483839536511933, 0.16728160463488068, 0, 0.26483839536511933, 0.19014430285482856, 0, - 0.24197569714517148, 0.19014430285482856, 0, 0.24197569714517148, 0.16728160463488068, 0.21364999999999998, 0.26483839536511933, 0.16728160463488068, - 0.21364999999999998, 0.26483839536511933, 0.19014430285482856, 0.21364999999999998, 0.24197569714517148, 0.19014430285482856, 0.21364999999999998, - 0.24197569714517148, 0.16728160463488068, 0.21364999999999998, 0.26483839536511933, 0.16728160463488068, 0.21364999999999998, 0.26483839536511933, - 0.19014430285482856, 0.21364999999999998, 0.24197569714517148, 0.19014430285482856, 0.21364999999999998, 0.24197569714517148, 0.16728160463488068, - 0.42729999999999996, 0.26483839536511933, 0.16728160463488068, 0.42729999999999996, 0.26483839536511933, 0.19014430285482856, 0.42729999999999996, - 0.24197569714517148, 0.19014430285482856, 0.42729999999999996, 0.24197569714517148, 0.16728160463488068, 0.42729999999999996, 0.26483839536511933, - 0.16728160463488068, 0.42729999999999996, 0.26483839536511933, 0.19014430285482856, 0.42729999999999996, 0.24197569714517148, 0.19014430285482856, - 0.42729999999999996, 0.24197569714517148, 0.16728160463488068, 0.64094999999999991, 0.26483839536511933, 0.16728160463488068, 0.64094999999999991, - 0.26483839536511933, 0.19014430285482856, 0.64094999999999991, 0.24197569714517148, 0.19014430285482856, 0.64094999999999991, 0.24197569714517148, - 0.16728160463488068, 0.64094999999999991, 0.26483839536511933, 0.16728160463488068, 0.64094999999999991, 0.26483839536511933, 0.19014430285482856, - 0.64094999999999991, 0.24197569714517148, 0.19014430285482856, 0.64094999999999991, 0.24197569714517148, 0.16728160463488068, 0.85459999999999992, - 0.26483839536511933, 0.16728160463488068, 0.85459999999999992, 0.26483839536511933, 0.19014430285482856, 0.85459999999999992, 0.24197569714517148, - 0.19014430285482856, 0.85459999999999992, 0.24197569714517148, 0.16728160463488068, 0.85459999999999992, 0.26483839536511933, 0.16728160463488068, - 0.85459999999999992, 0.26483839536511933, 0.19014430285482856, 0.85459999999999992, 0.24197569714517148, 0.19014430285482856, 0.85459999999999992, - 0.24197569714517148, 0.16728160463488068, 1.0682499999999999, 0.26483839536511933, 0.16728160463488068, 1.0682499999999999, 0.26483839536511933, - 0.19014430285482856, 1.0682499999999999, 0.24197569714517148, 0.19014430285482856, 1.0682499999999999, 0.24197569714517148, 0.16728160463488068, - 1.0682499999999999, 0.26483839536511933, 0.16728160463488068, 1.0682499999999999, 0.26483839536511933, 0.19014430285482856, 1.0682499999999999, - 0.24197569714517148, 0.19014430285482856, 1.0682499999999999, 0.24197569714517148, 0.16728160463488068, 1.2818999999999998, 0.26483839536511933, - 0.16728160463488068, 1.2818999999999998, 0.26483839536511933, 0.19014430285482856, 1.2818999999999998, 0.24197569714517148, 0.19014430285482856, - 1.2818999999999998, 0.24197569714517148, 0.16728160463488068, 1.2818999999999998, 0.26483839536511933, 0.16728160463488068, 1.2818999999999998, - 0.26483839536511933, 0.19014430285482856, 1.2818999999999998, 0.24197569714517148, 0.19014430285482856, 1.2818999999999998, 0.24197569714517148, - 0.16728160463488068, 1.4955499999999999, 0.26483839536511933, 0.16728160463488068, 1.4955499999999999, 0.26483839536511933, 0.19014430285482856, - 1.4955499999999999, 0.24197569714517148, 0.19014430285482856, 1.4955499999999999, 0.24197569714517148, 0.16728160463488068, 1.4955499999999999, - 0.26483839536511933, 0.16728160463488068, 1.4955499999999999, 0.26483839536511933, 0.19014430285482856, 1.4955499999999999, 0.24197569714517148, - 0.19014430285482856, 1.4955499999999999, 0.24197569714517148, 0.16728160463488068, 1.7091999999999998, 0.26483839536511933, 0.16728160463488068, - 1.7091999999999998, 0.26483839536511933, 0.19014430285482856, 1.7091999999999998, 0.24197569714517148, 0.19014430285482856, 1.7091999999999998, - 0.24197569714517148, 0.16728160463488068, 1.7091999999999998, 0.26483839536511933, 0.16728160463488068, 1.7091999999999998, 0.26483839536511933, - 0.19014430285482856, 1.7091999999999998, 0.24197569714517148, 0.19014430285482856, 1.7091999999999998, 0.24197569714517148, 0.16728160463488068, - 1.9228499999999997, 0.26483839536511933, 0.16728160463488068, 1.9228499999999997, 0.26483839536511933, 0.19014430285482856, 1.9228499999999997, - 0.24197569714517148, 0.19014430285482856, 1.9228499999999997, 0.24197569714517148, 0.16728160463488068, 1.9228499999999997, 0.26483839536511933, - 0.16728160463488068, 1.9228499999999997, 0.26483839536511933, 0.19014430285482856, 1.9228499999999997, 0.24197569714517148, 0.19014430285482856, - 1.9228499999999997, 0.24197569714517148, 0.16728160463488068, 2.1364999999999998, 0.26483839536511933, 0.16728160463488068, 2.1364999999999998, - 0.26483839536511933, 0.19014430285482856, 2.1364999999999998, 0.24197569714517148, 0.19014430285482856, 2.1364999999999998, 0.24197569714517148, - 0.16728160463488068, 2.1364999999999998, 0.26483839536511933, 0.16728160463488068, 2.1364999999999998, 0.26483839536511933, 0.19014430285482856, - 2.1364999999999998, 0.24197569714517148, 0.19014430285482856, 2.1364999999999998, 0.24197569714517148, 0.16728160463488068, 2.3501499999999997, - 0.26483839536511933, 0.16728160463488068, 2.3501499999999997, 0.26483839536511933, 0.19014430285482856, 2.3501499999999997, 0.24197569714517148, - 0.19014430285482856, 2.3501499999999997, 0.24197569714517148, 0.16728160463488068, 2.3501499999999997, 0.26483839536511933, 0.16728160463488068, - 2.3501499999999997, 0.26483839536511933, 0.19014430285482856, 2.3501499999999997, 0.24197569714517148, 0.19014430285482856, 2.3501499999999997, - 0.24197569714517148, 0.16728160463488068, 2.5637999999999996, 0.26483839536511933, - 0.16728160463488068, 2.5637999999999996, 0.26483839536511933, 0.19014430285482856, 2.5637999999999996, 0.24197569714517148, 0.19014430285482856, - 2.5637999999999996, 0.24197569714517148, 0.16728160463488068, 2.5637999999999996, 0.26483839536511933, 0.16728160463488068, 2.5637999999999996, - 0.26483839536511933, 0.19014430285482856, 2.5637999999999996, 0.24197569714517148, 0.19014430285482856, 2.5637999999999996, 0.24197569714517148, - 0.16728160463488068, 2.7774499999999995, 0.26483839536511933, 0.16728160463488068, 2.7774499999999995, 0.26483839536511933, 0.19014430285482856, - 2.7774499999999995, 0.24197569714517148, 0.19014430285482856, 2.7774499999999995, 0.24197569714517148, 0.16728160463488068, 2.7774499999999995, - 0.26483839536511933, 0.16728160463488068, 2.7774499999999995, 0.26483839536511933, 0.19014430285482856, 2.7774499999999995, 0.24197569714517148, - 0.19014430285482856, 2.7774499999999995, 0.24197569714517148, 0.16728160463488068, 2.9910999999999999, 0.26483839536511933, 0.16728160463488068, - 2.9910999999999999, 0.26483839536511933, 0.19014430285482856, 2.9910999999999999, 0.24197569714517148, 0.19014430285482856, 2.9910999999999999, - 0.24197569714517148, 0.16728160463488068, 2.9910999999999999, 0.26483839536511933, 0.16728160463488068, 2.9910999999999999, 0.26483839536511933, - 0.19014430285482856, 2.9910999999999999, 0.24197569714517148, 0.19014430285482856, 2.9910999999999999, 0.24197569714517148, 0.16728160463488068, - 3.2047499999999998, 0.26483839536511933, 0.16728160463488068, 3.2047499999999998, 0.26483839536511933, 0.19014430285482856, 3.2047499999999998, - 0.24197569714517148, 0.19014430285482856, 3.2047499999999998, 0.24197569714517148, 0.16728160463488068, 3.2047499999999998, 0.26483839536511933, - 0.16728160463488068, 3.2047499999999998, 0.26483839536511933, 0.19014430285482856, 3.2047499999999998, 0.24197569714517148, 0.19014430285482856, - 3.2047499999999998, 0.24197569714517148, 0.16728160463488068, 3.4183999999999997, 0.26483839536511933, 0.16728160463488068, 3.4183999999999997, - 0.26483839536511933, 0.19014430285482856, 3.4183999999999997, 0.24197569714517148, 0.19014430285482856, 3.4183999999999997, 0.24197569714517148, - 0.16728160463488068, 3.4183999999999997, 0.26483839536511933, 0.16728160463488068, 3.4183999999999997, 0.26483839536511933, 0.19014430285482856, - 3.4183999999999997, 0.24197569714517148, 0.19014430285482856, 3.4183999999999997, 0.24197569714517148, 0.16728160463488068, 3.6320499999999996, - 0.26483839536511933, 0.16728160463488068, 3.6320499999999996, 0.26483839536511933, 0.19014430285482856, 3.6320499999999996, 0.24197569714517148, - 0.19014430285482856, 3.6320499999999996, 0.24197569714517148, 0.16728160463488068, 3.6320499999999996, 0.26483839536511933, 0.16728160463488068, - 3.6320499999999996, 0.26483839536511933, 0.19014430285482856, 3.6320499999999996, 0.24197569714517148, 0.19014430285482856, 3.6320499999999996, - 0.24197569714517148, 0.16728160463488068, 3.8456999999999995, 0.26483839536511933, 0.16728160463488068, 3.8456999999999995, 0.26483839536511933, - 0.19014430285482856, 3.8456999999999995, 0.24197569714517148, 0.19014430285482856, 3.8456999999999995, 0.24197569714517148, 0.16728160463488068, - 3.8456999999999995, 0.26483839536511933, 0.16728160463488068, 3.8456999999999995, 0.26483839536511933, 0.19014430285482856, 3.8456999999999995, - 0.24197569714517148, 0.19014430285482856, 3.8456999999999995, 0.24197569714517148, 0.16728160463488068, 4.0593499999999993, 0.26483839536511933, - 0.16728160463488068, 4.0593499999999993, 0.26483839536511933, 0.19014430285482856, 4.0593499999999993, 0.24197569714517148, 0.19014430285482856, - 4.0593499999999993, 0.24197569714517148, 0.16728160463488068, 4.0593499999999993, 0.26483839536511933, 0.16728160463488068, 4.0593499999999993, - 0.26483839536511933, 0.19014430285482856, 4.0593499999999993, 0.24197569714517148, 0.19014430285482856, 4.0593499999999993, 0.24197569714517148, - 0.16728160463488068, 4.2729999999999997, 0.26483839536511933, 0.16728160463488068, 4.2729999999999997, 0.26483839536511933, 0.19014430285482856, - 4.2729999999999997, 0.24197569714517148, 0.19014430285482856, 4.2729999999999997, - 0.31132160463488068, 0.16995569714517142, 0, 0.3368583953651193, 0.16995569714517142, 0, 0.3368583953651193, 0.18643419768255964, 0, 0.31132160463488068, - 0.18643419768255964, 0, 0.31132160463488068, 0.16995569714517142, 0.21364999999999998, 0.3368583953651193, 0.16995569714517142, 0.21364999999999998, - 0.3368583953651193, 0.18643419768255964, 0.21364999999999998, 0.31132160463488068, 0.18643419768255964, 0.21364999999999998, 0.31132160463488068, - 0.16995569714517142, 0.21364999999999998, 0.3368583953651193, 0.16995569714517142, 0.21364999999999998, 0.3368583953651193, 0.18643419768255964, - 0.21364999999999998, 0.31132160463488068, 0.18643419768255964, 0.21364999999999998, 0.31132160463488068, 0.16995569714517142, 0.42729999999999996, - 0.3368583953651193, 0.16995569714517142, 0.42729999999999996, 0.3368583953651193, 0.18643419768255964, 0.42729999999999996, 0.31132160463488068, - 0.18643419768255964, 0.42729999999999996, 0.31132160463488068, 0.16995569714517142, 0.42729999999999996, 0.3368583953651193, 0.16995569714517142, - 0.42729999999999996, 0.3368583953651193, 0.18643419768255964, 0.42729999999999996, 0.31132160463488068, 0.18643419768255964, 0.42729999999999996, - 0.31132160463488068, 0.16995569714517142, 0.64094999999999991, 0.3368583953651193, 0.16995569714517142, 0.64094999999999991, 0.3368583953651193, - 0.18643419768255964, 0.64094999999999991, 0.31132160463488068, 0.18643419768255964, 0.64094999999999991, 0.31132160463488068, 0.16995569714517142, - 0.64094999999999991, 0.3368583953651193, 0.16995569714517142, 0.64094999999999991, 0.3368583953651193, 0.18643419768255964, 0.64094999999999991, - 0.31132160463488068, 0.18643419768255964, 0.64094999999999991, 0.31132160463488068, 0.16995569714517142, 0.85459999999999992, 0.3368583953651193, - 0.16995569714517142, 0.85459999999999992, 0.3368583953651193, 0.18643419768255964, 0.85459999999999992, 0.31132160463488068, 0.18643419768255964, - 0.85459999999999992, 0.31132160463488068, 0.16995569714517142, 0.85459999999999992, 0.3368583953651193, 0.16995569714517142, 0.85459999999999992, - 0.3368583953651193, 0.18643419768255964, 0.85459999999999992, 0.31132160463488068, 0.18643419768255964, 0.85459999999999992, 0.31132160463488068, - 0.16995569714517142, 1.0682499999999999, 0.3368583953651193, 0.16995569714517142, 1.0682499999999999, 0.3368583953651193, 0.18643419768255964, - 1.0682499999999999, 0.31132160463488068, 0.18643419768255964, 1.0682499999999999, 0.31132160463488068, 0.16995569714517142, 1.0682499999999999, - 0.3368583953651193, 0.16995569714517142, 1.0682499999999999, 0.3368583953651193, 0.18643419768255964, 1.0682499999999999, 0.31132160463488068, - 0.18643419768255964, 1.0682499999999999, 0.31132160463488068, 0.16995569714517142, 1.2818999999999998, 0.3368583953651193, 0.16995569714517142, - 1.2818999999999998, 0.3368583953651193, 0.18643419768255964, 1.2818999999999998, 0.31132160463488068, 0.18643419768255964, 1.2818999999999998, - 0.31132160463488068, 0.16995569714517142, 1.2818999999999998, 0.3368583953651193, 0.16995569714517142, 1.2818999999999998, 0.3368583953651193, - 0.18643419768255964, 1.2818999999999998, 0.31132160463488068, 0.18643419768255964, 1.2818999999999998, 0.31132160463488068, 0.16995569714517142, - 1.4955499999999999, 0.3368583953651193, 0.16995569714517142, 1.4955499999999999, 0.3368583953651193, 0.18643419768255964, 1.4955499999999999, - 0.31132160463488068, 0.18643419768255964, 1.4955499999999999, 0.31132160463488068, 0.16995569714517142, 1.4955499999999999, 0.3368583953651193, - 0.16995569714517142, 1.4955499999999999, 0.3368583953651193, 0.18643419768255964, 1.4955499999999999, 0.31132160463488068, 0.18643419768255964, - 1.4955499999999999, 0.31132160463488068, 0.16995569714517142, 1.7091999999999998, 0.3368583953651193, 0.16995569714517142, 1.7091999999999998, - 0.3368583953651193, 0.18643419768255964, 1.7091999999999998, 0.31132160463488068, 0.18643419768255964, 1.7091999999999998, 0.31132160463488068, - 0.16995569714517142, 1.7091999999999998, 0.3368583953651193, 0.16995569714517142, 1.7091999999999998, 0.3368583953651193, 0.18643419768255964, - 1.7091999999999998, 0.31132160463488068, 0.18643419768255964, 1.7091999999999998, 0.31132160463488068, 0.16995569714517142, 1.9228499999999997, - 0.3368583953651193, 0.16995569714517142, 1.9228499999999997, 0.3368583953651193, 0.18643419768255964, 1.9228499999999997, 0.31132160463488068, - 0.18643419768255964, 1.9228499999999997, 0.31132160463488068, 0.16995569714517142, 1.9228499999999997, 0.3368583953651193, 0.16995569714517142, - 1.9228499999999997, 0.3368583953651193, 0.18643419768255964, 1.9228499999999997, 0.31132160463488068, 0.18643419768255964, 1.9228499999999997, - 0.31132160463488068, 0.16995569714517142, 2.1364999999999998, 0.3368583953651193, 0.16995569714517142, 2.1364999999999998, 0.3368583953651193, - 0.18643419768255964, 2.1364999999999998, 0.31132160463488068, 0.18643419768255964, 2.1364999999999998, 0.31132160463488068, 0.16995569714517142, - 2.1364999999999998, 0.3368583953651193, 0.16995569714517142, 2.1364999999999998, 0.3368583953651193, 0.18643419768255964, 2.1364999999999998, - 0.31132160463488068, 0.18643419768255964, 2.1364999999999998, 0.31132160463488068, 0.16995569714517142, 2.3501499999999997, 0.3368583953651193, - 0.16995569714517142, 2.3501499999999997, 0.3368583953651193, 0.18643419768255964, 2.3501499999999997, 0.31132160463488068, 0.18643419768255964, - 2.3501499999999997, 0.31132160463488068, 0.16995569714517142, 2.3501499999999997, 0.3368583953651193, 0.16995569714517142, 2.3501499999999997, - 0.3368583953651193, 0.18643419768255964, 2.3501499999999997, 0.31132160463488068, 0.18643419768255964, 2.3501499999999997, 0.31132160463488068, - 0.16995569714517142, 2.5637999999999996, 0.3368583953651193, 0.16995569714517142, 2.5637999999999996, 0.3368583953651193, 0.18643419768255964, - 2.5637999999999996, 0.31132160463488068, 0.18643419768255964, 2.5637999999999996, 0.31132160463488068, 0.16995569714517142, 2.5637999999999996, - 0.3368583953651193, 0.16995569714517142, 2.5637999999999996, 0.3368583953651193, 0.18643419768255964, 2.5637999999999996, 0.31132160463488068, - 0.18643419768255964, 2.5637999999999996, 0.31132160463488068, 0.16995569714517142, 2.7774499999999995, 0.3368583953651193, 0.16995569714517142, - 2.7774499999999995, 0.3368583953651193, 0.18643419768255964, 2.7774499999999995, 0.31132160463488068, 0.18643419768255964, 2.7774499999999995, - 0.31132160463488068, 0.16995569714517142, 2.7774499999999995, 0.3368583953651193, 0.16995569714517142, 2.7774499999999995, 0.3368583953651193, - 0.18643419768255964, 2.7774499999999995, 0.31132160463488068, 0.18643419768255964, 2.7774499999999995, 0.31132160463488068, 0.16995569714517142, - 2.9910999999999999, 0.3368583953651193, 0.16995569714517142, 2.9910999999999999, 0.3368583953651193, 0.18643419768255964, 2.9910999999999999, - 0.31132160463488068, 0.18643419768255964, 2.9910999999999999, 0.31132160463488068, 0.16995569714517142, 2.9910999999999999, 0.3368583953651193, - 0.16995569714517142, 2.9910999999999999, 0.3368583953651193, 0.18643419768255964, 2.9910999999999999, 0.31132160463488068, 0.18643419768255964, - 2.9910999999999999, 0.31132160463488068, 0.16995569714517142, 3.2047499999999998, 0.3368583953651193, 0.16995569714517142, 3.2047499999999998, - 0.3368583953651193, 0.18643419768255964, 3.2047499999999998, 0.31132160463488068, 0.18643419768255964, 3.2047499999999998, 0.31132160463488068, - 0.16995569714517142, 3.2047499999999998, 0.3368583953651193, 0.16995569714517142, 3.2047499999999998, 0.3368583953651193, 0.18643419768255964, - 3.2047499999999998, 0.31132160463488068, 0.18643419768255964, 3.2047499999999998, 0.31132160463488068, 0.16995569714517142, 3.4183999999999997, - 0.3368583953651193, 0.16995569714517142, 3.4183999999999997, 0.3368583953651193, 0.18643419768255964, 3.4183999999999997, 0.31132160463488068, - 0.18643419768255964, 3.4183999999999997, 0.31132160463488068, 0.16995569714517142, 3.4183999999999997, 0.3368583953651193, 0.16995569714517142, - 3.4183999999999997, 0.3368583953651193, 0.18643419768255964, 3.4183999999999997, 0.31132160463488068, 0.18643419768255964, 3.4183999999999997, - 0.31132160463488068, 0.16995569714517142, 3.6320499999999996, 0.3368583953651193, - 0.16995569714517142, 3.6320499999999996, 0.3368583953651193, 0.18643419768255964, 3.6320499999999996, 0.31132160463488068, 0.18643419768255964, - 3.6320499999999996, 0.31132160463488068, 0.16995569714517142, 3.6320499999999996, 0.3368583953651193, 0.16995569714517142, 3.6320499999999996, - 0.3368583953651193, 0.18643419768255964, 3.6320499999999996, 0.31132160463488068, 0.18643419768255964, 3.6320499999999996, 0.31132160463488068, - 0.16995569714517142, 3.8456999999999995, 0.3368583953651193, 0.16995569714517142, 3.8456999999999995, 0.3368583953651193, 0.18643419768255964, - 3.8456999999999995, 0.31132160463488068, 0.18643419768255964, 3.8456999999999995, 0.31132160463488068, 0.16995569714517142, 3.8456999999999995, - 0.3368583953651193, 0.16995569714517142, 3.8456999999999995, 0.3368583953651193, 0.18643419768255964, 3.8456999999999995, 0.31132160463488068, - 0.18643419768255964, 3.8456999999999995, 0.31132160463488068, 0.16995569714517142, 4.0593499999999993, 0.3368583953651193, 0.16995569714517142, - 4.0593499999999993, 0.3368583953651193, 0.18643419768255964, 4.0593499999999993, 0.31132160463488068, 0.18643419768255964, 4.0593499999999993, - 0.31132160463488068, 0.16995569714517142, 4.0593499999999993, 0.3368583953651193, 0.16995569714517142, 4.0593499999999993, 0.3368583953651193, - 0.18643419768255964, 4.0593499999999993, 0.31132160463488068, 0.18643419768255964, 4.0593499999999993, 0.31132160463488068, 0.16995569714517142, - 4.2729999999999997, 0.3368583953651193, 0.16995569714517142, 4.2729999999999997, 0.3368583953651193, 0.18643419768255964, 4.2729999999999997, - 0.31132160463488068, 0.18643419768255964, 4.2729999999999997, 0.38334160463488065, 0.1672816046348807, 0, 0.40620430285482856, 0.1672816046348807, 0, - 0.40620430285482856, 0.19014430285482853, 0, 0.38334160463488065, 0.19014430285482853, 0, 0.38334160463488065, 0.1672816046348807, 0.21364999999999998, - 0.40620430285482856, 0.1672816046348807, 0.21364999999999998, 0.40620430285482856, 0.19014430285482853, 0.21364999999999998, 0.38334160463488065, - 0.19014430285482853, 0.21364999999999998, 0.38334160463488065, 0.1672816046348807, 0.21364999999999998, 0.40620430285482856, 0.1672816046348807, - 0.21364999999999998, 0.40620430285482856, 0.19014430285482853, 0.21364999999999998, 0.38334160463488065, 0.19014430285482853, 0.21364999999999998, - 0.38334160463488065, 0.1672816046348807, 0.42729999999999996, 0.40620430285482856, 0.1672816046348807, 0.42729999999999996, 0.40620430285482856, - 0.19014430285482853, 0.42729999999999996, 0.38334160463488065, 0.19014430285482853, 0.42729999999999996, 0.38334160463488065, 0.1672816046348807, - 0.42729999999999996, 0.40620430285482856, 0.1672816046348807, 0.42729999999999996, 0.40620430285482856, 0.19014430285482853, 0.42729999999999996, - 0.38334160463488065, 0.19014430285482853, 0.42729999999999996, 0.38334160463488065, 0.1672816046348807, 0.64094999999999991, 0.40620430285482856, - 0.1672816046348807, 0.64094999999999991, 0.40620430285482856, 0.19014430285482853, 0.64094999999999991, 0.38334160463488065, 0.19014430285482853, - 0.64094999999999991, 0.38334160463488065, 0.1672816046348807, 0.64094999999999991, 0.40620430285482856, 0.1672816046348807, 0.64094999999999991, - 0.40620430285482856, 0.19014430285482853, 0.64094999999999991, 0.38334160463488065, 0.19014430285482853, 0.64094999999999991, 0.38334160463488065, - 0.1672816046348807, 0.85459999999999992, 0.40620430285482856, 0.1672816046348807, 0.85459999999999992, 0.40620430285482856, 0.19014430285482853, - 0.85459999999999992, 0.38334160463488065, 0.19014430285482853, 0.85459999999999992, 0.38334160463488065, 0.1672816046348807, 0.85459999999999992, - 0.40620430285482856, 0.1672816046348807, 0.85459999999999992, 0.40620430285482856, 0.19014430285482853, 0.85459999999999992, 0.38334160463488065, - 0.19014430285482853, 0.85459999999999992, 0.38334160463488065, 0.1672816046348807, 1.0682499999999999, 0.40620430285482856, 0.1672816046348807, - 1.0682499999999999, 0.40620430285482856, 0.19014430285482853, 1.0682499999999999, 0.38334160463488065, 0.19014430285482853, 1.0682499999999999, - 0.38334160463488065, 0.1672816046348807, 1.0682499999999999, 0.40620430285482856, 0.1672816046348807, 1.0682499999999999, 0.40620430285482856, - 0.19014430285482853, 1.0682499999999999, 0.38334160463488065, 0.19014430285482853, 1.0682499999999999, 0.38334160463488065, 0.1672816046348807, - 1.2818999999999998, 0.40620430285482856, 0.1672816046348807, 1.2818999999999998, 0.40620430285482856, 0.19014430285482853, 1.2818999999999998, - 0.38334160463488065, 0.19014430285482853, 1.2818999999999998, 0.38334160463488065, 0.1672816046348807, 1.2818999999999998, 0.40620430285482856, - 0.1672816046348807, 1.2818999999999998, 0.40620430285482856, 0.19014430285482853, 1.2818999999999998, 0.38334160463488065, 0.19014430285482853, - 1.2818999999999998, 0.38334160463488065, 0.1672816046348807, 1.4955499999999999, 0.40620430285482856, 0.1672816046348807, 1.4955499999999999, - 0.40620430285482856, 0.19014430285482853, 1.4955499999999999, 0.38334160463488065, 0.19014430285482853, 1.4955499999999999, 0.38334160463488065, - 0.1672816046348807, 1.4955499999999999, 0.40620430285482856, 0.1672816046348807, 1.4955499999999999, 0.40620430285482856, 0.19014430285482853, - 1.4955499999999999, 0.38334160463488065, 0.19014430285482853, 1.4955499999999999, 0.38334160463488065, 0.1672816046348807, 1.7091999999999998, - 0.40620430285482856, 0.1672816046348807, 1.7091999999999998, 0.40620430285482856, 0.19014430285482853, 1.7091999999999998, 0.38334160463488065, - 0.19014430285482853, 1.7091999999999998, 0.38334160463488065, 0.1672816046348807, 1.7091999999999998, 0.40620430285482856, 0.1672816046348807, - 1.7091999999999998, 0.40620430285482856, 0.19014430285482853, 1.7091999999999998, 0.38334160463488065, 0.19014430285482853, 1.7091999999999998, - 0.38334160463488065, 0.1672816046348807, 1.9228499999999997, 0.40620430285482856, 0.1672816046348807, 1.9228499999999997, 0.40620430285482856, - 0.19014430285482853, 1.9228499999999997, 0.38334160463488065, 0.19014430285482853, 1.9228499999999997, 0.38334160463488065, 0.1672816046348807, - 1.9228499999999997, 0.40620430285482856, 0.1672816046348807, 1.9228499999999997, 0.40620430285482856, 0.19014430285482853, 1.9228499999999997, - 0.38334160463488065, 0.19014430285482853, 1.9228499999999997, 0.38334160463488065, 0.1672816046348807, 2.1364999999999998, 0.40620430285482856, - 0.1672816046348807, 2.1364999999999998, 0.40620430285482856, 0.19014430285482853, 2.1364999999999998, 0.38334160463488065, 0.19014430285482853, - 2.1364999999999998, 0.38334160463488065, 0.1672816046348807, 2.1364999999999998, 0.40620430285482856, 0.1672816046348807, 2.1364999999999998, - 0.40620430285482856, 0.19014430285482853, 2.1364999999999998, 0.38334160463488065, 0.19014430285482853, 2.1364999999999998, 0.38334160463488065, - 0.1672816046348807, 2.3501499999999997, 0.40620430285482856, 0.1672816046348807, 2.3501499999999997, 0.40620430285482856, 0.19014430285482853, - 2.3501499999999997, 0.38334160463488065, 0.19014430285482853, 2.3501499999999997, 0.38334160463488065, 0.1672816046348807, 2.3501499999999997, - 0.40620430285482856, 0.1672816046348807, 2.3501499999999997, 0.40620430285482856, 0.19014430285482853, 2.3501499999999997, 0.38334160463488065, - 0.19014430285482853, 2.3501499999999997, 0.38334160463488065, 0.1672816046348807, 2.5637999999999996, 0.40620430285482856, 0.1672816046348807, - 2.5637999999999996, 0.40620430285482856, 0.19014430285482853, 2.5637999999999996, 0.38334160463488065, 0.19014430285482853, 2.5637999999999996, - 0.38334160463488065, 0.1672816046348807, 2.5637999999999996, 0.40620430285482856, 0.1672816046348807, 2.5637999999999996, 0.40620430285482856, - 0.19014430285482853, 2.5637999999999996, 0.38334160463488065, 0.19014430285482853, 2.5637999999999996, 0.38334160463488065, 0.1672816046348807, - 2.7774499999999995, 0.40620430285482856, 0.1672816046348807, 2.7774499999999995, 0.40620430285482856, 0.19014430285482853, 2.7774499999999995, - 0.38334160463488065, 0.19014430285482853, 2.7774499999999995, 0.38334160463488065, 0.1672816046348807, 2.7774499999999995, 0.40620430285482856, - 0.1672816046348807, 2.7774499999999995, 0.40620430285482856, 0.19014430285482853, - 2.7774499999999995, 0.38334160463488065, 0.19014430285482853, 2.7774499999999995, 0.38334160463488065, 0.1672816046348807, 2.9910999999999999, - 0.40620430285482856, 0.1672816046348807, 2.9910999999999999, 0.40620430285482856, 0.19014430285482853, 2.9910999999999999, 0.38334160463488065, - 0.19014430285482853, 2.9910999999999999, 0.38334160463488065, 0.1672816046348807, 2.9910999999999999, 0.40620430285482856, 0.1672816046348807, - 2.9910999999999999, 0.40620430285482856, 0.19014430285482853, 2.9910999999999999, 0.38334160463488065, 0.19014430285482853, 2.9910999999999999, - 0.38334160463488065, 0.1672816046348807, 3.2047499999999998, 0.40620430285482856, 0.1672816046348807, 3.2047499999999998, 0.40620430285482856, - 0.19014430285482853, 3.2047499999999998, 0.38334160463488065, 0.19014430285482853, 3.2047499999999998, 0.38334160463488065, 0.1672816046348807, - 3.2047499999999998, 0.40620430285482856, 0.1672816046348807, 3.2047499999999998, 0.40620430285482856, 0.19014430285482853, 3.2047499999999998, - 0.38334160463488065, 0.19014430285482853, 3.2047499999999998, 0.38334160463488065, 0.1672816046348807, 3.4183999999999997, 0.40620430285482856, - 0.1672816046348807, 3.4183999999999997, 0.40620430285482856, 0.19014430285482853, 3.4183999999999997, 0.38334160463488065, 0.19014430285482853, - 3.4183999999999997, 0.38334160463488065, 0.1672816046348807, 3.4183999999999997, 0.40620430285482856, 0.1672816046348807, 3.4183999999999997, - 0.40620430285482856, 0.19014430285482853, 3.4183999999999997, 0.38334160463488065, 0.19014430285482853, 3.4183999999999997, 0.38334160463488065, - 0.1672816046348807, 3.6320499999999996, 0.40620430285482856, 0.1672816046348807, 3.6320499999999996, 0.40620430285482856, 0.19014430285482853, - 3.6320499999999996, 0.38334160463488065, 0.19014430285482853, 3.6320499999999996, 0.38334160463488065, 0.1672816046348807, 3.6320499999999996, - 0.40620430285482856, 0.1672816046348807, 3.6320499999999996, 0.40620430285482856, 0.19014430285482853, 3.6320499999999996, 0.38334160463488065, - 0.19014430285482853, 3.6320499999999996, 0.38334160463488065, 0.1672816046348807, 3.8456999999999995, 0.40620430285482856, 0.1672816046348807, - 3.8456999999999995, 0.40620430285482856, 0.19014430285482853, 3.8456999999999995, 0.38334160463488065, 0.19014430285482853, 3.8456999999999995, - 0.38334160463488065, 0.1672816046348807, 3.8456999999999995, 0.40620430285482856, 0.1672816046348807, 3.8456999999999995, 0.40620430285482856, - 0.19014430285482853, 3.8456999999999995, 0.38334160463488065, 0.19014430285482853, 3.8456999999999995, 0.38334160463488065, 0.1672816046348807, - 4.0593499999999993, 0.40620430285482856, 0.1672816046348807, 4.0593499999999993, 0.40620430285482856, 0.19014430285482853, 4.0593499999999993, - 0.38334160463488065, 0.19014430285482853, 4.0593499999999993, 0.38334160463488065, 0.1672816046348807, 4.0593499999999993, 0.40620430285482856, - 0.1672816046348807, 4.0593499999999993, 0.40620430285482856, 0.19014430285482853, 4.0593499999999993, 0.38334160463488065, 0.19014430285482853, - 4.0593499999999993, 0.38334160463488065, 0.1672816046348807, 4.2729999999999997, 0.40620430285482856, 0.1672816046348807, 4.2729999999999997, - 0.40620430285482856, 0.19014430285482853, 4.2729999999999997, 0.38334160463488065, 0.19014430285482853, 4.2729999999999997 - }; - - -const int connTFH8[2560]={ - 1, 2, 7, 6, 28, 29, 34, 33, 2, 3, 8, 7, 29, 30, 35, 34, 3, 4, 9, 8, 30, 31, 36, 35, 4, 5, 10, 9, 31, 32, 37, 36, 6, 7, 12, 11, 33, 34, 39, 38, 7, 8, 13, 12, 34, 35, 40, 39, - 8, 9, 14, 13, 35, 36, 41, 40, 9, 10, 15, 14, 36, 37, 42, 41, 11, 12, 17, 16, 38, 39, 44, 43, 12, 13, 18, 17, 39, 40, 45, 44, 13, 14, 19, 18, 40, 41, 46, 45, 14, 15, 20, 19, - 41, 42, 47, 46, 16, 17, 21, 26, 43, 44, 48, 53, 17, 18, 22, 21, 44, 45, 49, 48, 18, 19, 23, 22, 45, 46, 50, 49, 19, 20, 24, 23, 46, 47, 51, 50, 28, 29, 34, 33, 55, 56, 61, 60, - 29, 30, 35, 34, 56, 57, 62, 61, 30, 31, 36, 35, 57, 58, 63, 62, 31, 32, 37, 36, 58, 59, 64, 63, 33, 34, 39, 38, 60, 61, 66, 65, 34, 35, 40, 39, 61, 62, 67, 66, 35, 36, 41, 40, - 62, 63, 68, 67, 36, 37, 42, 41, 63, 64, 69, 68, 38, 39, 44, 43, 65, 66, 71, 70, 39, 40, 45, 44, 66, 67, 72, 71, 40, 41, 46, 45, 67, 68, 73, 72, 41, 42, 47, 46, 68, 69, 74, 73, - 43, 44, 48, 53, 70, 71, 75, 80, 44, 45, 49, 48, 71, 72, 76, 75, 45, 46, 50, 49, 72, 73, 77, 76, 46, 47, 51, 50, 73, 74, 78, 77, 55, 56, 61, 60, 82, 83, 88, 87, 56, 57, 62, 61, - 83, 84, 89, 88, 57, 58, 63, 62, 84, 85, 90, 89, 58, 59, 64, 63, 85, 86, 91, 90, 60, 61, 66, 65, 87, 88, 93, 92, 61, 62, 67, 66, 88, 89, 94, 93, 62, 63, 68, 67, 89, 90, 95, 94, - 63, 64, 69, 68, 90, 91, 96, 95, 65, 66, 71, 70, 92, 93, 98, 97, 66, 67, 72, 71, 93, 94, 99, 98, 67, 68, 73, 72, 94, 95, 100, 99, 68, 69, 74, 73, 95, 96, 101, 100, 70, 71, 75, - 80, 97, 98, 102, 107, 71, 72, 76, 75, 98, 99, 103, 102, 72, 73, 77, 76, 99, 100, 104, 103, 73, 74, 78, 77, 100, 101, 105, 104, 82, 83, 88, 87, 109, 110, 115, 114, 83, 84, 89, - 88, 110, 111, 116, 115, 84, 85, 90, 89, 111, 112, 117, 116, 85, 86, 91, 90, 112, 113, 118, 117, 87, 88, 93, 92, 114, 115, 120, 119, 88, 89, 94, 93, 115, 116, 121, 120, 89, 90, - 95, 94, 116, 117, 122, 121, 90, 91, 96, 95, 117, 118, 123, 122, 92, 93, 98, 97, 119, 120, 125, 124, 93, 94, 99, 98, 120, 121, 126, 125, 94, 95, 100, 99, 121, 122, 127, 126, 95, - 96, 101, 100, 122, 123, 128, 127, 97, 98, 102, 107, 124, 125, 129, 134, 98, 99, 103, 102, 125, 126, 130, 129, 99, 100, 104, 103, 126, 127, 131, 130, 100, 101, 105, 104, 127, 128, - 132, 131, 109, 110, 115, 114, 136, 137, 142, 141, 110, 111, 116, 115, 137, 138, 143, 142, 111, 112, 117, 116, 138, 139, 144, 143, 112, 113, 118, 117, 139, 140, 145, 144, 114, 115, - 120, 119, 141, 142, 147, 146, 115, 116, 121, 120, 142, 143, 148, 147, 116, 117, 122, 121, 143, 144, 149, 148, 117, 118, 123, 122, 144, 145, 150, 149, 119, 120, 125, 124, 146, 147, - 152, 151, 120, 121, 126, 125, 147, 148, 153, 152, 121, 122, 127, 126, 148, 149, 154, 153, 122, 123, 128, 127, 149, 150, 155, 154, 124, 125, 129, 134, 151, 152, 156, 161, 125, 126, 130, - 129, 152, 153, 157, 156, 126, 127, 131, 130, 153, 154, 158, 157, 127, 128, 132, 131, 154, 155, 159, 158, 136, 137, 142, 141, 163, 164, 169, 168, 137, 138, 143, 142, 164, 165, 170, 169, 138, 139, 144, 143, 165, 166, 171, 170, 139, - 140, 145, 144, 166, 167, 172, 171, 141, 142, 147, 146, 168, 169, 174, 173, 142, 143, 148, 147, 169, 170, 175, 174, 143, 144, 149, 148, 170, 171, 176, 175, 144, 145, 150, 149, 171, 172, 177, 176, 146, 147, 152, 151, 173, 174, 179, - 178, 147, 148, 153, 152, 174, 175, 180, 179, 148, 149, 154, 153, 175, 176, 181, 180, 149, 150, 155, 154, 176, 177, 182, 181, 151, 152, 156, 161, 178, 179, 183, 188, 152, 153, 157, 156, 179, 180, 184, 183, 153, 154, 158, 157, 180, - 181, 185, 184, 154, 155, 159, 158, 181, 182, 186, 185, 163, 164, 169, 168, 190, 191, 196, 195, 164, 165, 170, 169, 191, 192, 197, 196, 165, 166, 171, 170, 192, 193, 198, 197, 166, 167, 172, 171, 193, 194, 199, 198, 168, 169, 174, - 173, 195, 196, 201, 200, 169, 170, 175, 174, 196, 197, 202, 201, 170, 171, 176, 175, 197, 198, 203, 202, 171, 172, 177, 176, 198, 199, 204, 203, 173, 174, 179, 178, 200, 201, 206, 205, 174, 175, 180, 179, 201, 202, 207, 206, 175, - 176, 181, 180, 202, 203, 208, 207, 176, 177, 182, 181, 203, 204, 209, 208, 178, 179, 183, 188, 205, 206, 210, 215, 179, 180, 184, 183, 206, 207, 211, 210, 180, 181, 185, 184, 207, 208, 212, 211, 181, 182, 186, 185, 208, 209, 213, - 212, 190, 191, 196, 195, 217, 218, 223, 222, 191, 192, 197, 196, 218, 219, 224, 223, 192, 193, 198, 197, 219, 220, 225, 224, 193, 194, 199, 198, 220, 221, 226, 225, 195, 196, 201, 200, 222, 223, 228, 227, 196, 197, 202, 201, 223, - 224, 229, 228, 197, 198, 203, 202, 224, 225, 230, 229, 198, 199, 204, 203, 225, 226, 231, 230, 200, 201, 206, 205, 227, 228, 233, 232, 201, 202, 207, 206, 228, 229, 234, 233, 202, 203, 208, 207, 229, 230, 235, 234, 203, 204, 209, - 208, 230, 231, 236, 235, 205, 206, 210, 215, 232, 233, 237, 242, 206, 207, 211, 210, 233, 234, 238, 237, 207, 208, 212, 211, 234, 235, 239, 238, 208, 209, 213, 212, 235, 236, 240, 239, 217, 218, 223, 222, 244, 245, 250, 249, 218, - 219, 224, 223, 245, 246, 251, 250, 219, 220, 225, 224, 246, 247, 252, 251, 220, 221, 226, 225, 247, 248, 253, 252, 222, 223, 228, 227, 249, 250, 255, 254, 223, 224, 229, 228, 250, 251, 256, 255, 224, 225, 230, 229, 251, 252, 257, - 256, 225, 226, 231, 230, 252, 253, 258, 257, 227, 228, 233, 232, 254, 255, 260, 259, 228, 229, 234, 233, 255, 256, 261, 260, 229, 230, 235, 234, 256, 257, 262, 261, 230, 231, 236, 235, 257, 258, 263, 262, 232, 233, 237, 242, 259, - 260, 264, 269, 233, 234, 238, 237, 260, 261, 265, 264, 234, 235, 239, 238, 261, 262, 266, 265, 235, 236, 240, 239, 262, 263, 267, 266, 244, 245, 250, 249, 271, 272, 277, 276, 245, 246, 251, 250, 272, 273, 278, 277, 246, 247, 252, - 251, 273, 274, 279, 278, 247, 248, 253, 252, 274, 275, 280, 279, 249, 250, 255, 254, 276, 277, 282, 281, 250, 251, 256, 255, 277, 278, 283, 282, 251, 252, 257, 256, 278, 279, 284, 283, 252, 253, 258, 257, 279, 280, 285, 284, 254, - 255, 260, 259, 281, 282, 287, 286, 255, 256, 261, 260, 282, 283, 288, 287, 256, 257, 262, 261, 283, 284, 289, 288, 257, 258, 263, 262, 284, 285, 290, 289, 259, 260, 264, 269, 286, 287, 291, 296, 260, 261, 265, 264, 287, 288, 292, - 291, 261, 262, 266, 265, 288, 289, 293, 292, 262, 263, 267, 266, 289, 290, 294, 293, 271, 272, 277, 276, 298, 299, 304, 303, 272, 273, 278, 277, 299, 300, 305, 304, 273, 274, 279, 278, 300, 301, 306, 305, 274, 275, 280, 279, 301, - 302, 307, 306, 276, 277, 282, 281, 303, 304, 309, 308, 277, 278, 283, 282, 304, 305, 310, 309, 278, 279, 284, 283, 305, 306, 311, 310, 279, 280, 285, 284, 306, 307, 312, 311, 281, 282, 287, 286, 308, 309, 314, 313, 282, 283, 288, - 287, 309, 310, 315, 314, 283, 284, 289, 288, 310, 311, 316, 315, 284, 285, 290, 289, 311, 312, 317, 316, 286, 287, 291, 296, 313, 314, 318, 323, 287, 288, 292, 291, 314, 315, 319, 318, 288, 289, 293, 292, 315, 316, 320, 319, 289, - 290, 294, 293, 316, 317, 321, 320, 298, 299, 304, 303, 325, 326, 331, 330, 299, 300, 305, 304, 326, 327, 332, 331, 300, 301, 306, 305, 327, 328, 333, 332, 301, 302, 307, 306, 328, 329, 334, 333, 303, 304, 309, 308, 330, 331, 336, - 335, 304, 305, 310, 309, 331, 332, 337, 336, 305, 306, 311, 310, 332, 333, 338, 337, 306, 307, 312, 311, 333, 334, 339, 338, 308, 309, 314, 313, 335, 336, 341, 340, 309, 310, 315, 314, 336, 337, 342, 341, 310, 311, 316, 315, 337, - 338, 343, 342, 311, 312, 317, 316, 338, 339, 344, 343, 313, 314, 318, 323, 340, 341, 345, 350, 314, 315, 319, 318, 341, 342, 346, 345, 315, 316, 320, 319, 342, 343, 347, 346, 316, 317, 321, 320, 343, 344, 348, 347, 325, 326, 331, - 330, 352, 353, 358, 357, 326, 327, 332, 331, 353, 354, 359, 358, 327, 328, 333, 332, 354, 355, 360, 359, 328, 329, 334, 333, 355, 356, 361, 360, 330, 331, 336, 335, 357, 358, 363, 362, 331, 332, 337, 336, 358, 359, 364, 363, 332, - 333, 338, 337, 359, 360, 365, 364, 333, 334, 339, 338, 360, 361, 366, 365, 335, 336, 341, 340, 362, 363, 368, 367, 336, 337, 342, 341, 363, 364, 369, 368, 337, 338, 343, 342, 364, 365, 370, 369, 338, 339, 344, 343, 365, 366, 371, - 370, 340, 341, 345, 350, 367, 368, 372, 377, 341, 342, 346, 345, 368, 369, 373, 372, 342, 343, 347, 346, 369, 370, 374, 373, 343, 344, 348, 347, 370, 371, 375, 374, 352, 353, 358, 357, 379, 380, 385, 384, 353, 354, 359, 358, 380, - 381, 386, 385, 354, 355, 360, 359, 381, 382, 387, 386, 355, 356, 361, 360, 382, 383, 388, 387, 357, 358, 363, 362, 384, 385, 390, 389, 358, 359, 364, 363, 385, 386, 391, 390, 359, 360, 365, 364, 386, 387, 392, 391, 360, 361, 366, - 365, 387, 388, 393, 392, 362, 363, 368, 367, 389, 390, 395, 394, 363, 364, 369, 368, 390, 391, 396, 395, 364, 365, 370, 369, 391, 392, 397, 396, 365, 366, 371, 370, 392, 393, 398, 397, 367, 368, 372, 377, 394, 395, 399, 404, 368, - 369, 373, 372, 395, 396, 400, 399, 369, 370, 374, 373, 396, 397, 401, 400, 370, 371, 375, 374, 397, 398, 402, 401, 379, 380, 385, 384, 406, 407, 412, 411, 380, 381, 386, 385, 407, 408, 413, 412, 381, 382, 387, 386, 408, 409, 414, - 413, 382, 383, 388, 387, 409, 410, 415, 414, 384, 385, 390, 389, 411, 412, 417, 416, 385, 386, 391, 390, 412, 413, 418, 417, 386, 387, 392, 391, 413, 414, 419, 418, 387, 388, 393, 392, 414, 415, 420, 419, 389, 390, 395, 394, 416, - 417, 422, 421, 390, 391, 396, 395, 417, 418, 423, 422, 391, 392, 397, 396, 418, 419, 424, 423, 392, 393, 398, 397, 419, 420, 425, 424, 394, 395, 399, 404, 421, 422, 426, 431, 395, 396, 400, 399, 422, 423, 427, 426, 396, 397, 401, - 400, 423, 424, 428, 427, 397, 398, 402, 401, 424, 425, 429, 428, 406, 407, 412, 411, 433, 434, 439, 438, 407, 408, 413, 412, 434, 435, 440, 439, 408, 409, 414, 413, 435, 436, 441, 440, 409, 410, 415, 414, 436, 437, 442, 441, 411, - 412, 417, 416, 438, 439, 444, 443, 412, 413, 418, 417, 439, 440, 445, 444, 413, 414, 419, 418, 440, 441, 446, 445, 414, 415, 420, 419, 441, 442, 447, 446, 416, 417, 422, 421, 443, 444, 449, 448, 417, 418, 423, 422, 444, 445, 450, - 449, 418, 419, 424, 423, 445, 446, 451, 450, 419, 420, 425, 424, 446, 447, 452, 451, 421, 422, 426, 431, 448, 449, 453, 458, 422, 423, 427, 426, 449, 450, 454, 453, 423, 424, 428, 427, 450, 451, 455, 454, 424, 425, 429, 428, 451, - 452, 456, 455, 433, 434, 439, 438, 460, 461, 466, 465, 434, 435, 440, 439, 461, 462, 467, 466, 435, 436, 441, 440, 462, 463, 468, 467, 436, 437, 442, 441, 463, 464, 469, 468, 438, 439, 444, 443, 465, 466, 471, 470, 439, 440, 445, - 444, 466, 467, 472, 471, 440, 441, 446, 445, 467, 468, 473, 472, 441, 442, 447, 446, 468, 469, 474, 473, 443, 444, 449, 448, 470, 471, 476, 475, 444, 445, 450, 449, 471, 472, 477, 476, 445, 446, 451, 450, 472, 473, 478, 477, 446, - 447, 452, 451, 473, 474, 479, 478, 448, 449, 453, 458, 475, 476, 480, 485, 449, 450, 454, 453, 476, 477, 481, 480, 450, 451, 455, 454, 477, 478, 482, 481, 451, 452, 456, 455, 478, 479, 483, 482, 460, 461, 466, 465, 487, 488, 493, - 492, 461, 462, 467, 466, 488, 489, 494, 493, 462, 463, 468, 467, 489, 490, 495, 494, 463, 464, 469, 468, 490, 491, 496, 495, 465, 466, 471, 470, 492, 493, 498, 497, 466, 467, 472, 471, 493, 494, 499, 498, 467, 468, 473, 472, 494, - 495, 500, 499, 468, 469, 474, 473, 495, 496, 501, 500, 470, 471, 476, 475, 497, 498, 503, 502, 471, 472, 477, 476, 498, 499, 504, 503, 472, 473, 478, 477, 499, 500, 505, 504, 473, 474, 479, 478, 500, 501, 506, 505, 475, 476, 480, - 485, 502, 503, 507, 512, 476, 477, 481, 480, 503, 504, 508, 507, 477, 478, 482, 481, 504, 505, 509, 508, 478, 479, 483, 482, 505, 506, 510, 509, 487, 488, 493, 492, 514, 515, 520, 519, 488, 489, 494, 493, 515, 516, 521, 520, 489, - 490, 495, 494, 516, 517, 522, 521, 490, 491, 496, 495, 517, 518, 523, 522, 492, 493, 498, 497, 519, 520, 525, 524, 493, 494, 499, 498, 520, 521, 526, 525, 494, 495, 500, 499, 521, 522, 527, 526, 495, 496, 501, 500, 522, 523, 528, - 527, 497, 498, 503, 502, 524, 525, 530, 529, 498, 499, 504, 503, 525, 526, 531, 530, 499, 500, 505, 504, 526, 527, 532, 531, 500, 501, 506, 505, 527, 528, 533, 532, 502, 503, 507, 512, 529, 530, 534, 539, 503, 504, 508, 507, 530, - 531, 535, 534, 504, 505, 509, 508, 531, 532, 536, 535, 505, 506, 510, 509, 532, 533, 537, 536, 514, 515, 520, 519, 541, 542, 547, 546, 515, 516, 521, 520, 542, 543, 548, 547, 516, 517, 522, 521, 543, 544, 549, 548, 517, 518, 523, - 522, 544, 545, 550, 549, 519, 520, 525, 524, 546, 547, 552, 551, 520, 521, 526, 525, 547, 548, 553, 552, 521, 522, 527, 526, 548, 549, 554, 553, 522, 523, 528, 527, 549, 550, 555, 554, 524, 525, 530, 529, 551, 552, 557, 556, 525, - 526, 531, 530, 552, 553, 558, 557, 526, 527, 532, 531, 553, 554, 559, 558, 527, 528, 533, 532, 554, 555, 560, 559, 529, 530, 534, 539, 556, 557, 561, 566, 530, 531, 535, 534, 557, 558, 562, 561, 531, 532, 536, 535, 558, 559, 563, - 562, 532, 533, 537, 536, 559, 560, 564, 563}; - -const int connTFPOLH[1000]={ - 0, 25, 26, 16, 11, 6, 1, -1, 27, 28, 33, 38, 43, 53, 52, -1, 0, 1, 28, 27, -1, 1, 6, 33, 28, -1, 6, 11, 38, 33, -1, 11, 16, 43, 38, -1, 16, 26, 53, 43, -1, 26, 25, 52, 53, -1, 25, 0, 27, 52, 27, 52, 53, 43, 38, 33, 28, -1, 54, 55, - 60, 65, 70, 80, 79, -1, 27, 28, 55, 54, -1, 28, 33, 60, 55, -1, 33, 38, 65, 60, -1, 38, 43, 70, 65, -1, 43, 53, 80, 70, -1, 53, 52, 79, 80, -1, 52, 27, 54, 79, 54, 79, 80, 70, 65, 60, 55, -1, 81, 82, 87, 92, 97, 107, 106, -1, 54, - 55, 82, 81, -1, 55, 60, 87, 82, -1, 60, 65, 92, 87, -1, 65, 70, 97, 92, -1, 70, 80, 107, 97, -1, 80, 79, 106, 107, -1, 79, 54, 81, 106, 81, 106, 107, 97, 92, 87, 82, -1, 108, 109, 114, 119, 124, 134, 133, -1, 81, 82, 109, 108, -1, - 82, 87, 114, 109, -1, 87, 92, 119, 114, -1, 92, 97, 124, 119, -1, 97, 107, 134, 124, -1, 107, 106, 133, 134, -1, 106, 81, 108, 133, 108, 133, 134, 124, 119, 114, 109, -1, 135, 136, 141, 146, 151, 161, 160, -1, 108, 109, 136, 135, - -1, 109, 114, 141, 136, -1, 114, 119, 146, 141, -1, 119, 124, 151, 146, -1, 124, 134, 161, 151, -1, 134, 133, 160, 161, -1, 133, 108, 135, 160, 135, 160, 161, 151, 146, 141, 136, -1, 162, 163, 168, 173, 178, 188, 187, -1, 135, 136, - 163, 162, -1, 136, 141, 168, 163, -1, 141, 146, 173, 168, -1, 146, 151, 178, 173, -1, 151, 161, 188, 178, -1, 161, 160, 187, 188, -1, 160, 135, 162, 187, 162, 187, 188, 178, 173, 168, 163, -1, 189, 190, 195, 200, 205, 215, 214, -1, - 162, 163, 190, 189, -1, 163, 168, 195, 190, -1, 168, 173, 200, 195, -1, 173, 178, 205, 200, -1, 178, 188, 215, 205, -1, 188, 187, 214, 215, -1, 187, 162, 189, 214, 189, 214, 215, 205, 200, 195, 190, -1, 216, 217, 222, 227, 232, 242, - 241, -1, 189, 190, 217, 216, -1, 190, 195, 222, 217, -1, 195, 200, 227, 222, -1, 200, 205, 232, 227, -1, 205, 215, 242, 232, -1, 215, 214, 241, 242, -1, 214, 189, 216, 241, 216, 241, 242, 232, 227, 222, 217, -1, 243, 244, 249, 254, -259, 269, 268, -1, 216, 217, 244, 243, -1, 217, 222, 249, 244, -1, 222, 227, 254, 249, -1, 227, 232, 259, 254, -1, 232, 242, 269, 259, -1, 242, 241, 268, 269, -1, 241, 216, 243, 268, 243, 268, 269, 259, 254, 249, 244, -1, 270, 271, 276, - 281, 286, 296, 295, -1, 243, 244, 271, 270, -1, 244, 249, 276, 271, -1, 249, 254, 281, 276, -1, 254, 259, 286, 281, -1, 259, 269, 296, 286, -1, 269, 268, 295, 296, -1, 268, 243, 270, 295, 270, 295, 296, 286, 281, 276, 271, -1, 297, 298, - 303, 308, 313, 323, 322, -1, 270, 271, 298, 297, -1, 271, 276, 303, 298, -1, 276, 281, 308, 303, -1, 281, 286, 313, 308, -1, 286, 296, 323, 313, -1, 296, 295, 322, 323, -1, 295, 270, 297, 322, 297, 322, 323, 313, 308, 303, 298, -1, 324, - 325, 330, 335, 340, 350, 349, -1, 297, 298, 325, 324, -1, 298, 303, 330, 325, -1, 303, 308, 335, 330, -1, 308, 313, 340, 335, -1, 313, 323, 350, 340, -1, 323, 322, 349, 350, -1, 322, 297, 324, 349, 324, 349, 350, 340, 335, 330, 325, -1, - 351, 352, 357, 362, 367, 377, 376, -1, 324, 325, 352, 351, -1, 325, 330, 357, 352, -1, 330, 335, 362, 357, -1, 335, 340, 367, 362, -1, 340, 350, 377, 367, -1, 350, 349, 376, 377, -1, 349, 324, 351, 376, 351, 376, 377, 367, 362, 357, 352, - -1, 378, 379, 384, 389, 394, 404, 403, -1, 351, 352, 379, 378, -1, 352, 357, 384, 379, -1, 357, 362, 389, 384, -1, 362, 367, 394, 389, -1, 367, 377, 404, 394, -1, 377, 376, 403, 404, -1, 376, 351, 378, 403, 378, 403, 404, 394, 389, 384, - 379, -1, 405, 406, 411, 416, 421, 431, 430, -1, 378, 379, 406, 405, -1, 379, 384, 411, 406, -1, 384, 389, 416, 411, -1, 389, 394, 421, 416, -1, 394, 404, 431, 421, -1, 404, 403, 430, 431, -1, 403, 378, 405, 430, 405, 430, 431, 421, 416, - 411, 406, -1, 432, 433, 438, 443, 448, 458, 457, -1, 405, 406, 433, 432, -1, 406, 411, 438, 433, -1, 411, 416, 443, 438, -1, 416, 421, 448, 443, -1, 421, 431, 458, 448, -1, 431, 430, 457, 458, -1, 430, 405, 432, 457, 432, 457, 458, 448, - 443, 438, 433, -1, 459, 460, 465, 470, 475, 485, 484, -1, 432, 433, 460, 459, -1, 433, 438, 465, 460, -1, 438, 443, 470, 465, -1, 443, 448, 475, 470, -1, 448, 458, 485, 475, -1, 458, 457, 484, 485, -1, 457, 432, 459, 484, 459, 484, 485, - 475, 470, 465, 460, -1, 486, 487, 492, 497, 502, 512, 511, -1, 459, 460, 487, 486, -1, 460, 465, 492, 487, -1, 465, 470, 497, 492, -1, 470, 475, 502, 497, -1, 475, 485, 512, 502, -1, 485, 484, 511, 512, -1, 484, 459, 486, 511, 486, 511, - 512, 502, 497, 492, 487, -1, 513, 514, 519, 524, 529, 539, 538, -1, 486, 487, 514, 513, -1, 487, 492, 519, 514, -1, 492, 497, 524, 519, -1, 497, 502, 529, 524, -1, 502, 512, 539, 529, -1, 512, 511, 538, 539, -1, 511, 486, 513, 538, 513, - 538, 539, 529, 524, 519, 514, -1, 540, 541, 546, 551, 556, 566, 565, -1, 513, 514, 541, 540, -1, 514, 519, 546, 541, -1, 519, 524, 551, 546, -1, 524, 529, 556, 551, -1, 529, 539, 566, 556, -1, 539, 538, 565, 566, -1, 538, 513, 540, 565 -}; - -const double coordsTF[1701]={ - 0, 0, 0, 0.21606, 0, 0, 0.25207000000000002, 0, 0, 0.32408999999999999, 0, 0, 0.39610999999999996, 0, 0, 0.43212, 0, 0, 0.21606, 0.03601, 0, - 0.25207000000000002, 0.03601, 0, 0.32408999999999999, 0.03601, 0, 0.39610999999999996, 0.03601, 0, 0.43212, 0.03601, 0, 0.21606, 0.10803, 0, 0.25207000000000002, - 0.10803, 0, 0.32408999999999999, 0.10803, 0, 0.39610999999999996, 0.10803, 0, 0.43212, 0.10803, 0, 0.21606, 0.18004999999999999, 0, 0.25207000000000002, - 0.18004999999999999, 0, 0.32408999999999999, 0.18004999999999999, 0, 0.39610999999999996, 0.18004999999999999, 0, 0.43212, 0.18004999999999999, 0, - 0.25207000000000002, 0.21605999999999997, 0, 0.32408999999999999, 0.21605999999999997, 0, 0.39610999999999996, 0.21605999999999997, 0, 0.43212, - 0.21605999999999997, 0, 0, 0.21606, 0, 0.21606, 0.21606, 0, 0, 0, 0.21364999999999998, 0.21606, 0, 0.21364999999999998, 0.25207000000000002, 0, - 0.21364999999999998, 0.32408999999999999, 0, 0.21364999999999998, 0.39610999999999996, 0, 0.21364999999999998, 0.43212, 0, 0.21364999999999998, 0.21606, 0.03601, - 0.21364999999999998, 0.25207000000000002, 0.03601, 0.21364999999999998, 0.32408999999999999, 0.03601, 0.21364999999999998, 0.39610999999999996, 0.03601, - 0.21364999999999998, 0.43212, 0.03601, 0.21364999999999998, 0.21606, 0.10803, 0.21364999999999998, 0.25207000000000002, 0.10803, 0.21364999999999998, - 0.32408999999999999, 0.10803, 0.21364999999999998, 0.39610999999999996, 0.10803, 0.21364999999999998, 0.43212, 0.10803, 0.21364999999999998, 0.21606, - 0.18004999999999999, 0.21364999999999998, 0.25207000000000002, 0.18004999999999999, 0.21364999999999998, 0.32408999999999999, 0.18004999999999999, - 0.21364999999999998, 0.39610999999999996, 0.18004999999999999, 0.21364999999999998, 0.43212, 0.18004999999999999, 0.21364999999999998, 0.25207000000000002, - 0.21605999999999997, 0.21364999999999998, 0.32408999999999999, 0.21605999999999997, 0.21364999999999998, 0.39610999999999996, 0.21605999999999997, - 0.21364999999999998, 0.43212, 0.21605999999999997, 0.21364999999999998, 0, 0.21606, 0.21364999999999998, 0.21606, 0.21606, 0.21364999999999998, 0, 0, - 0.42729999999999996, 0.21606, 0, 0.42729999999999996, 0.25207000000000002, 0, 0.42729999999999996, 0.32408999999999999, 0, 0.42729999999999996, - 0.39610999999999996, 0, 0.42729999999999996, 0.43212, 0, 0.42729999999999996, 0.21606, 0.03601, 0.42729999999999996, 0.25207000000000002, 0.03601, - 0.42729999999999996, 0.32408999999999999, 0.03601, 0.42729999999999996, 0.39610999999999996, 0.03601, 0.42729999999999996, 0.43212, 0.03601, 0.42729999999999996, - 0.21606, 0.10803, 0.42729999999999996, 0.25207000000000002, 0.10803,0.42729999999999996, 0.32408999999999999, 0.10803, 0.42729999999999996, 0.39610999999999996, 0.10803, 0.42729999999999996, 0.43212, 0.10803, - 0.42729999999999996, 0.21606, 0.18004999999999999, 0.42729999999999996, 0.25207000000000002, 0.18004999999999999, 0.42729999999999996, 0.32408999999999999, - 0.18004999999999999, 0.42729999999999996, 0.39610999999999996, 0.18004999999999999, 0.42729999999999996, 0.43212, 0.18004999999999999, 0.42729999999999996, - 0.25207000000000002, 0.21605999999999997, 0.42729999999999996, 0.32408999999999999, 0.21605999999999997, 0.42729999999999996, 0.39610999999999996, - 0.21605999999999997, 0.42729999999999996, 0.43212, 0.21605999999999997, 0.42729999999999996, 0, 0.21606, 0.42729999999999996, 0.21606, 0.21606, - 0.42729999999999996, 0, 0, 0.64094999999999991, 0.21606, 0, 0.64094999999999991, 0.25207000000000002, 0, 0.64094999999999991, 0.32408999999999999, 0, - 0.64094999999999991, 0.39610999999999996, 0, 0.64094999999999991, 0.43212, 0, 0.64094999999999991, 0.21606, 0.03601, 0.64094999999999991, 0.25207000000000002, - 0.03601, 0.64094999999999991, 0.32408999999999999, 0.03601, 0.64094999999999991, 0.39610999999999996, 0.03601, 0.64094999999999991, 0.43212, 0.03601, - 0.64094999999999991, 0.21606, 0.10803, 0.64094999999999991, 0.25207000000000002, 0.10803, 0.64094999999999991, 0.32408999999999999, 0.10803, 0.64094999999999991, - 0.39610999999999996, 0.10803, 0.64094999999999991, 0.43212, 0.10803, 0.64094999999999991, 0.21606, 0.18004999999999999, 0.64094999999999991, 0.25207000000000002, - 0.18004999999999999, 0.64094999999999991, 0.32408999999999999, 0.18004999999999999, 0.64094999999999991, 0.39610999999999996, 0.18004999999999999, - 0.64094999999999991, 0.43212, 0.18004999999999999, 0.64094999999999991, 0.25207000000000002, 0.21605999999999997, 0.64094999999999991, 0.32408999999999999, - 0.21605999999999997, 0.64094999999999991, 0.39610999999999996, 0.21605999999999997, 0.64094999999999991, 0.43212, 0.21605999999999997, 0.64094999999999991, 0, - 0.21606, 0.64094999999999991, 0.21606, 0.21606, 0.64094999999999991, 0, 0, 0.85459999999999992, 0.21606, 0, 0.85459999999999992, 0.25207000000000002, 0, - 0.85459999999999992, 0.32408999999999999, 0, 0.85459999999999992, 0.39610999999999996, 0, 0.85459999999999992, 0.43212, 0, 0.85459999999999992, 0.21606, 0.03601, - 0.85459999999999992, 0.25207000000000002, 0.03601, 0.85459999999999992, 0.32408999999999999, 0.03601, 0.85459999999999992, 0.39610999999999996, 0.03601, - 0.85459999999999992, 0.43212, 0.03601, 0.85459999999999992, 0.21606, 0.10803, 0.85459999999999992, 0.25207000000000002, 0.10803, 0.85459999999999992, - 0.32408999999999999, 0.10803, 0.85459999999999992, 0.39610999999999996, 0.10803, 0.85459999999999992, 0.43212, 0.10803, 0.85459999999999992, 0.21606, - 0.18004999999999999, 0.85459999999999992, 0.25207000000000002, 0.18004999999999999, 0.85459999999999992, 0.32408999999999999, 0.18004999999999999, - 0.85459999999999992, 0.39610999999999996, 0.18004999999999999, 0.85459999999999992, 0.43212, 0.18004999999999999, 0.85459999999999992, 0.25207000000000002, - 0.21605999999999997, 0.85459999999999992, 0.32408999999999999, 0.21605999999999997, 0.85459999999999992, 0.39610999999999996, 0.21605999999999997, - 0.85459999999999992, 0.43212, 0.21605999999999997, 0.85459999999999992, 0,0.21606, 0.85459999999999992, 0.21606, 0.21606, 0.85459999999999992, 0, 0, 1.0682499999999999, 0.21606, 0, 1.0682499999999999, 0.25207000000000002, 0, - 1.0682499999999999, 0.32408999999999999, 0, 1.0682499999999999, 0.39610999999999996, 0, 1.0682499999999999, 0.43212, 0, 1.0682499999999999, 0.21606, 0.03601, - 1.0682499999999999, 0.25207000000000002, 0.03601, 1.0682499999999999, 0.32408999999999999, 0.03601, 1.0682499999999999, 0.39610999999999996, 0.03601, - 1.0682499999999999, 0.43212, 0.03601, 1.0682499999999999, 0.21606, 0.10803, 1.0682499999999999, 0.25207000000000002, 0.10803, 1.0682499999999999, - 0.32408999999999999, 0.10803, 1.0682499999999999, 0.39610999999999996, 0.10803, 1.0682499999999999, 0.43212, 0.10803, 1.0682499999999999, 0.21606, - 0.18004999999999999, 1.0682499999999999, 0.25207000000000002, 0.18004999999999999, 1.0682499999999999, 0.32408999999999999, 0.18004999999999999, - 1.0682499999999999, 0.39610999999999996, 0.18004999999999999, 1.0682499999999999, 0.43212, 0.18004999999999999, 1.0682499999999999, 0.25207000000000002, - 0.21605999999999997, 1.0682499999999999, 0.32408999999999999, 0.21605999999999997, 1.0682499999999999, 0.39610999999999996, 0.21605999999999997, - 1.0682499999999999, 0.43212, 0.21605999999999997, 1.0682499999999999, 0, 0.21606, 1.0682499999999999, 0.21606, 0.21606, 1.0682499999999999, 0, 0, - 1.2818999999999998, 0.21606, 0, 1.2818999999999998, 0.25207000000000002, 0, 1.2818999999999998, 0.32408999999999999, 0, 1.2818999999999998, 0.39610999999999996, - 0, 1.2818999999999998, 0.43212, 0, 1.2818999999999998, 0.21606, 0.03601, 1.2818999999999998, 0.25207000000000002, 0.03601, 1.2818999999999998, - 0.32408999999999999, 0.03601, 1.2818999999999998, 0.39610999999999996, 0.03601, 1.2818999999999998, 0.43212, 0.03601, 1.2818999999999998, 0.21606, 0.10803, - 1.2818999999999998, 0.25207000000000002, 0.10803, 1.2818999999999998, 0.32408999999999999, 0.10803, 1.2818999999999998, 0.39610999999999996, 0.10803, - 1.2818999999999998, 0.43212, 0.10803, 1.2818999999999998, 0.21606, 0.18004999999999999, 1.2818999999999998, 0.25207000000000002, 0.18004999999999999, - 1.2818999999999998, 0.32408999999999999, 0.18004999999999999, 1.2818999999999998, 0.39610999999999996, 0.18004999999999999, 1.2818999999999998, 0.43212, - 0.18004999999999999, 1.2818999999999998, 0.25207000000000002, 0.21605999999999997, 1.2818999999999998, 0.32408999999999999, 0.21605999999999997, - 1.2818999999999998, 0.39610999999999996, 0.21605999999999997, 1.2818999999999998, 0.43212, 0.21605999999999997, 1.2818999999999998, 0, 0.21606, - 1.2818999999999998, 0.21606, 0.21606, 1.2818999999999998, 0, 0, 1.4955499999999999, 0.21606, 0, 1.4955499999999999, 0.25207000000000002, 0, 1.4955499999999999, - 0.32408999999999999, 0, 1.4955499999999999, 0.39610999999999996, 0, 1.4955499999999999, 0.43212, 0, 1.4955499999999999, 0.21606, 0.03601, 1.4955499999999999, - 0.25207000000000002, 0.03601, 1.4955499999999999, 0.32408999999999999, 0.03601, 1.4955499999999999, 0.39610999999999996, 0.03601, 1.4955499999999999, 0.43212, - 0.03601, 1.4955499999999999,0.21606, 0.10803, 1.4955499999999999, 0.25207000000000002, 0.10803, 1.4955499999999999, 0.32408999999999999, 0.10803, 1.4955499999999999, - 0.39610999999999996, 0.10803, 1.4955499999999999, 0.43212, 0.10803, 1.4955499999999999, 0.21606, 0.18004999999999999, 1.4955499999999999, 0.25207000000000002, - 0.18004999999999999, 1.4955499999999999, 0.32408999999999999, 0.18004999999999999, 1.4955499999999999, 0.39610999999999996, 0.18004999999999999, - 1.4955499999999999, 0.43212, 0.18004999999999999, 1.4955499999999999, 0.25207000000000002, 0.21605999999999997, 1.4955499999999999, 0.32408999999999999, - 0.21605999999999997, 1.4955499999999999, 0.39610999999999996, 0.21605999999999997, 1.4955499999999999, 0.43212, 0.21605999999999997, 1.4955499999999999, 0, - 0.21606, 1.4955499999999999, 0.21606, 0.21606, 1.4955499999999999, 0, 0, 1.7091999999999998, 0.21606, 0, 1.7091999999999998, 0.25207000000000002, 0, - 1.7091999999999998, 0.32408999999999999, 0, 1.7091999999999998, 0.39610999999999996, 0, 1.7091999999999998, 0.43212, 0, 1.7091999999999998, 0.21606, 0.03601, - 1.7091999999999998, 0.25207000000000002, 0.03601, 1.7091999999999998, 0.32408999999999999, 0.03601, 1.7091999999999998, 0.39610999999999996, 0.03601, - 1.7091999999999998, 0.43212, 0.03601, 1.7091999999999998, 0.21606, 0.10803, 1.7091999999999998, 0.25207000000000002, 0.10803, 1.7091999999999998, - 0.32408999999999999, 0.10803, 1.7091999999999998, 0.39610999999999996, 0.10803, 1.7091999999999998, 0.43212, 0.10803, 1.7091999999999998, 0.21606, - 0.18004999999999999, 1.7091999999999998, 0.25207000000000002, 0.18004999999999999, 1.7091999999999998, 0.32408999999999999, 0.18004999999999999, - 1.7091999999999998, 0.39610999999999996, 0.18004999999999999, 1.7091999999999998, 0.43212, 0.18004999999999999, 1.7091999999999998, 0.25207000000000002, - 0.21605999999999997, 1.7091999999999998, 0.32408999999999999, 0.21605999999999997, 1.7091999999999998, 0.39610999999999996, 0.21605999999999997, - 1.7091999999999998, 0.43212, 0.21605999999999997, 1.7091999999999998, 0, 0.21606, 1.7091999999999998, 0.21606, 0.21606, 1.7091999999999998, 0, 0, - 1.9228499999999997, 0.21606, 0, 1.9228499999999997, 0.25207000000000002, 0, 1.9228499999999997, 0.32408999999999999, 0, 1.9228499999999997, 0.39610999999999996, - 0, 1.9228499999999997, 0.43212, 0, 1.9228499999999997, 0.21606, 0.03601, 1.9228499999999997, 0.25207000000000002, 0.03601, 1.9228499999999997, - 0.32408999999999999, 0.03601, 1.9228499999999997, 0.39610999999999996, 0.03601, 1.9228499999999997, 0.43212, 0.03601, 1.9228499999999997, 0.21606, 0.10803, - 1.9228499999999997, 0.25207000000000002, 0.10803, 1.9228499999999997, 0.32408999999999999, 0.10803, 1.9228499999999997, 0.39610999999999996, 0.10803, - 1.9228499999999997, 0.43212, 0.10803, 1.9228499999999997, 0.21606, 0.18004999999999999, 1.9228499999999997, 0.25207000000000002, 0.18004999999999999, - 1.9228499999999997, 0.32408999999999999, 0.18004999999999999, 1.9228499999999997, 0.39610999999999996, 0.18004999999999999, 1.9228499999999997, 0.43212, - 0.18004999999999999, 1.9228499999999997, 0.25207000000000002, 0.21605999999999997, 1.9228499999999997, 0.32408999999999999, 0.21605999999999997, - 1.9228499999999997, 0.39610999999999996, 0.21605999999999997,1.9228499999999997, 0.43212, 0.21605999999999997, 1.9228499999999997, 0, 0.21606, 1.9228499999999997, 0.21606, 0.21606, 1.9228499999999997, 0, 0, - 2.1364999999999998, 0.21606, 0, 2.1364999999999998, 0.25207000000000002, 0, 2.1364999999999998, 0.32408999999999999, 0, 2.1364999999999998, 0.39610999999999996, - 0, 2.1364999999999998, 0.43212, 0, 2.1364999999999998, 0.21606, 0.03601, 2.1364999999999998, 0.25207000000000002, 0.03601, 2.1364999999999998, - 0.32408999999999999, 0.03601, 2.1364999999999998, 0.39610999999999996, 0.03601, 2.1364999999999998, 0.43212, 0.03601, 2.1364999999999998, 0.21606, 0.10803, - 2.1364999999999998, 0.25207000000000002, 0.10803, 2.1364999999999998, 0.32408999999999999, 0.10803, 2.1364999999999998, 0.39610999999999996, 0.10803, - 2.1364999999999998, 0.43212, 0.10803, 2.1364999999999998, 0.21606, 0.18004999999999999, 2.1364999999999998, 0.25207000000000002, 0.18004999999999999, - 2.1364999999999998, 0.32408999999999999, 0.18004999999999999, 2.1364999999999998, 0.39610999999999996, 0.18004999999999999, 2.1364999999999998, 0.43212, - 0.18004999999999999, 2.1364999999999998, 0.25207000000000002, 0.21605999999999997, 2.1364999999999998, 0.32408999999999999, 0.21605999999999997, - 2.1364999999999998, 0.39610999999999996, 0.21605999999999997, 2.1364999999999998, 0.43212, 0.21605999999999997, 2.1364999999999998, 0, 0.21606, - 2.1364999999999998, 0.21606, 0.21606, 2.1364999999999998, 0, 0, 2.3501499999999997, 0.21606, 0, 2.3501499999999997, 0.25207000000000002, 0, 2.3501499999999997, - 0.32408999999999999, 0, 2.3501499999999997, 0.39610999999999996, 0, 2.3501499999999997, 0.43212, 0, 2.3501499999999997, 0.21606, 0.03601, 2.3501499999999997, - 0.25207000000000002, 0.03601, 2.3501499999999997, 0.32408999999999999, 0.03601, 2.3501499999999997, 0.39610999999999996, 0.03601, 2.3501499999999997, 0.43212, - 0.03601, 2.3501499999999997, 0.21606, 0.10803, 2.3501499999999997, 0.25207000000000002, 0.10803, 2.3501499999999997, 0.32408999999999999, 0.10803, - 2.3501499999999997, 0.39610999999999996, 0.10803, 2.3501499999999997, 0.43212, 0.10803, 2.3501499999999997, 0.21606, 0.18004999999999999, 2.3501499999999997, - 0.25207000000000002, 0.18004999999999999, 2.3501499999999997, 0.32408999999999999, 0.18004999999999999, 2.3501499999999997, 0.39610999999999996, - 0.18004999999999999, 2.3501499999999997, 0.43212, 0.18004999999999999, 2.3501499999999997, 0.25207000000000002, 0.21605999999999997, 2.3501499999999997, - 0.32408999999999999, 0.21605999999999997, 2.3501499999999997, 0.39610999999999996, 0.21605999999999997, 2.3501499999999997, 0.43212, 0.21605999999999997, - 2.3501499999999997, 0, 0.21606, 2.3501499999999997, 0.21606, 0.21606, 2.3501499999999997, 0, 0, 2.5637999999999996, 0.21606, 0, 2.5637999999999996, - 0.25207000000000002, 0, 2.5637999999999996, 0.32408999999999999, 0, 2.5637999999999996, 0.39610999999999996, 0, 2.5637999999999996, 0.43212, 0, - 2.5637999999999996, 0.21606, 0.03601, 2.5637999999999996, 0.25207000000000002, 0.03601, 2.5637999999999996, 0.32408999999999999, 0.03601, 2.5637999999999996, - 0.39610999999999996,0.03601, 2.5637999999999996, 0.43212, 0.03601, 2.5637999999999996, 0.21606, 0.10803, 2.5637999999999996, 0.25207000000000002, 0.10803, 2.5637999999999996, - 0.32408999999999999, 0.10803, 2.5637999999999996, 0.39610999999999996, 0.10803, 2.5637999999999996, 0.43212, 0.10803, 2.5637999999999996, 0.21606, - 0.18004999999999999, 2.5637999999999996, 0.25207000000000002, 0.18004999999999999, 2.5637999999999996, 0.32408999999999999, 0.18004999999999999, - 2.5637999999999996, 0.39610999999999996, 0.18004999999999999, 2.5637999999999996, 0.43212, 0.18004999999999999, 2.5637999999999996, 0.25207000000000002, - 0.21605999999999997, 2.5637999999999996, 0.32408999999999999, 0.21605999999999997, 2.5637999999999996, 0.39610999999999996, 0.21605999999999997, - 2.5637999999999996, 0.43212, 0.21605999999999997, 2.5637999999999996, 0, 0.21606, 2.5637999999999996, 0.21606, 0.21606, 2.5637999999999996, 0, 0, - 2.7774499999999995, 0.21606, 0, 2.7774499999999995, 0.25207000000000002, 0, 2.7774499999999995, 0.32408999999999999, 0, 2.7774499999999995, 0.39610999999999996, - 0, 2.7774499999999995, 0.43212, 0, 2.7774499999999995, 0.21606, 0.03601, 2.7774499999999995, 0.25207000000000002, 0.03601, 2.7774499999999995, - 0.32408999999999999, 0.03601, 2.7774499999999995, 0.39610999999999996, 0.03601, 2.7774499999999995, 0.43212, 0.03601, 2.7774499999999995, 0.21606, 0.10803, - 2.7774499999999995, 0.25207000000000002, 0.10803, 2.7774499999999995, 0.32408999999999999, 0.10803, 2.7774499999999995, 0.39610999999999996, 0.10803, - 2.7774499999999995, 0.43212, 0.10803, 2.7774499999999995, 0.21606, 0.18004999999999999, 2.7774499999999995, 0.25207000000000002, 0.18004999999999999, - 2.7774499999999995, 0.32408999999999999, 0.18004999999999999, 2.7774499999999995, 0.39610999999999996, 0.18004999999999999, 2.7774499999999995, 0.43212, - 0.18004999999999999, 2.7774499999999995, 0.25207000000000002, 0.21605999999999997, 2.7774499999999995, 0.32408999999999999, 0.21605999999999997, - 2.7774499999999995, 0.39610999999999996, 0.21605999999999997, 2.7774499999999995, 0.43212, 0.21605999999999997, 2.7774499999999995, 0, 0.21606, - 2.7774499999999995, 0.21606, 0.21606, 2.7774499999999995, 0, 0, 2.9910999999999999, 0.21606, 0, 2.9910999999999999, 0.25207000000000002, 0, 2.9910999999999999, - 0.32408999999999999, 0, 2.9910999999999999, 0.39610999999999996, 0, 2.9910999999999999, 0.43212, 0, 2.9910999999999999, 0.21606, 0.03601, 2.9910999999999999, - 0.25207000000000002, 0.03601, 2.9910999999999999, 0.32408999999999999, 0.03601, 2.9910999999999999, 0.39610999999999996, 0.03601, 2.9910999999999999, 0.43212, - 0.03601, 2.9910999999999999, 0.21606, 0.10803, 2.9910999999999999, 0.25207000000000002, 0.10803, 2.9910999999999999, 0.32408999999999999, 0.10803, - 2.9910999999999999, 0.39610999999999996, 0.10803, 2.9910999999999999, 0.43212, 0.10803, 2.9910999999999999, 0.21606, 0.18004999999999999, 2.9910999999999999, - 0.25207000000000002, 0.18004999999999999, 2.9910999999999999, 0.32408999999999999, 0.18004999999999999, 2.9910999999999999, 0.39610999999999996, - 0.18004999999999999, 2.9910999999999999, 0.43212, 0.18004999999999999, 2.9910999999999999, 0.25207000000000002, 0.21605999999999997, 2.9910999999999999, - 0.32408999999999999, 0.21605999999999997, 2.9910999999999999, 0.39610999999999996, 0.21605999999999997, 2.9910999999999999, 0.43212, 0.21605999999999997, - 2.9910999999999999, 0, 0.21606, 2.9910999999999999, 0.21606, 0.21606, 2.9910999999999999, 0, 0, 3.2047499999999998, 0.21606, 0, 3.2047499999999998, - 0.25207000000000002, 0, 3.2047499999999998, 0.32408999999999999, 0, 3.2047499999999998, 0.39610999999999996, 0, 3.2047499999999998, 0.43212, 0, - 3.2047499999999998, 0.21606, 0.03601, 3.2047499999999998, 0.25207000000000002, 0.03601, 3.2047499999999998, 0.32408999999999999, 0.03601, 3.2047499999999998, - 0.39610999999999996, 0.03601, 3.2047499999999998, 0.43212, 0.03601, 3.2047499999999998, 0.21606, 0.10803, 3.2047499999999998, 0.25207000000000002, 0.10803, - 3.2047499999999998, 0.32408999999999999, 0.10803, 3.2047499999999998, 0.39610999999999996, 0.10803, 3.2047499999999998, 0.43212, 0.10803, 3.2047499999999998, - 0.21606, 0.18004999999999999, 3.2047499999999998, 0.25207000000000002, 0.18004999999999999, 3.2047499999999998, 0.32408999999999999, 0.18004999999999999, - 3.2047499999999998, 0.39610999999999996, 0.18004999999999999, 3.2047499999999998, 0.43212, 0.18004999999999999, 3.2047499999999998, 0.25207000000000002, - 0.21605999999999997, 3.2047499999999998, 0.32408999999999999, 0.21605999999999997, 3.2047499999999998, 0.39610999999999996, 0.21605999999999997, - 3.2047499999999998, 0.43212, 0.21605999999999997, 3.2047499999999998, 0, 0.21606, 3.2047499999999998, 0.21606, 0.21606, 3.2047499999999998, 0, 0, - 3.4183999999999997, 0.21606, 0, 3.4183999999999997, 0.25207000000000002, 0, 3.4183999999999997, 0.32408999999999999, 0, 3.4183999999999997, 0.39610999999999996, - 0, 3.4183999999999997, 0.43212, 0, 3.4183999999999997, 0.21606, 0.03601, 3.4183999999999997, 0.25207000000000002, 0.03601, 3.4183999999999997, - 0.32408999999999999, 0.03601, 3.4183999999999997, 0.39610999999999996, 0.03601, 3.4183999999999997, 0.43212, 0.03601, 3.4183999999999997, 0.21606, 0.10803, - 3.4183999999999997, 0.25207000000000002, 0.10803, 3.4183999999999997, 0.32408999999999999, 0.10803, 3.4183999999999997, 0.39610999999999996, 0.10803, - 3.4183999999999997, 0.43212, 0.10803, 3.4183999999999997, 0.21606, 0.18004999999999999, 3.4183999999999997, 0.25207000000000002, 0.18004999999999999, - 3.4183999999999997, 0.32408999999999999, 0.18004999999999999, 3.4183999999999997, 0.39610999999999996, 0.18004999999999999, 3.4183999999999997, 0.43212, - 0.18004999999999999, 3.4183999999999997, 0.25207000000000002, 0.21605999999999997, 3.4183999999999997, 0.32408999999999999, 0.21605999999999997, - 3.4183999999999997, 0.39610999999999996, 0.21605999999999997, 3.4183999999999997, 0.43212, 0.21605999999999997, 3.4183999999999997, 0, 0.21606, - 3.4183999999999997, 0.21606, 0.21606, 3.4183999999999997, 0, 0, 3.6320499999999996, 0.21606, 0, 3.6320499999999996, 0.25207000000000002, 0, 3.6320499999999996, - 0.32408999999999999, 0, 3.6320499999999996, 0.39610999999999996, 0, 3.6320499999999996, 0.43212, 0, 3.6320499999999996, 0.21606, 0.03601, 3.6320499999999996, - 0.25207000000000002, 0.03601, 3.6320499999999996, 0.32408999999999999, 0.03601, 3.6320499999999996, 0.39610999999999996, 0.03601, 3.6320499999999996, 0.43212, 0.03601, - 3.6320499999999996, 0.21606, 0.10803, 3.6320499999999996, 0.25207000000000002, 0.10803, 3.6320499999999996, 0.32408999999999999, 0.10803, 3.6320499999999996, - 0.39610999999999996, 0.10803, 3.6320499999999996, 0.43212, 0.10803, 3.6320499999999996, 0.21606, 0.18004999999999999, 3.6320499999999996, 0.25207000000000002, - 0.18004999999999999, 3.6320499999999996, 0.32408999999999999, 0.18004999999999999, 3.6320499999999996, 0.39610999999999996, 0.18004999999999999, - 3.6320499999999996, 0.43212, 0.18004999999999999, 3.6320499999999996, 0.25207000000000002, 0.21605999999999997, 3.6320499999999996, 0.32408999999999999, - 0.21605999999999997, 3.6320499999999996, 0.39610999999999996, 0.21605999999999997, 3.6320499999999996, 0.43212, 0.21605999999999997, 3.6320499999999996, 0, - 0.21606, 3.6320499999999996, 0.21606, 0.21606, 3.6320499999999996, 0, 0, 3.8456999999999995, 0.21606, 0, 3.8456999999999995, 0.25207000000000002, 0, - 3.8456999999999995, 0.32408999999999999, 0, 3.8456999999999995, 0.39610999999999996, 0, 3.8456999999999995, 0.43212, 0, 3.8456999999999995, 0.21606, 0.03601, - 3.8456999999999995, 0.25207000000000002, 0.03601, 3.8456999999999995, 0.32408999999999999, 0.03601, 3.8456999999999995, 0.39610999999999996, 0.03601, - 3.8456999999999995, 0.43212, 0.03601, 3.8456999999999995, 0.21606, 0.10803, 3.8456999999999995, 0.25207000000000002, 0.10803, 3.8456999999999995, - 0.32408999999999999, 0.10803, 3.8456999999999995, 0.39610999999999996, 0.10803, 3.8456999999999995, 0.43212, 0.10803, 3.8456999999999995, 0.21606, - 0.18004999999999999, 3.8456999999999995, 0.25207000000000002, 0.18004999999999999, 3.8456999999999995, 0.32408999999999999, 0.18004999999999999, - 3.8456999999999995, 0.39610999999999996, 0.18004999999999999, 3.8456999999999995, 0.43212, 0.18004999999999999, 3.8456999999999995, 0.25207000000000002, - 0.21605999999999997, 3.8456999999999995, 0.32408999999999999, 0.21605999999999997, 3.8456999999999995, 0.39610999999999996, 0.21605999999999997, - 3.8456999999999995, 0.43212, 0.21605999999999997, 3.8456999999999995, 0, 0.21606, 3.8456999999999995, 0.21606, 0.21606, 3.8456999999999995, 0, 0, - 4.0593499999999993, 0.21606, 0, 4.0593499999999993, 0.25207000000000002, 0, 4.0593499999999993, 0.32408999999999999, 0, 4.0593499999999993, 0.39610999999999996, - 0, 4.0593499999999993, 0.43212, 0, 4.0593499999999993, 0.21606, 0.03601, 4.0593499999999993, 0.25207000000000002, 0.03601, 4.0593499999999993, - 0.32408999999999999, 0.03601, 4.0593499999999993, 0.39610999999999996, 0.03601, 4.0593499999999993, 0.43212, 0.03601, 4.0593499999999993, 0.21606, 0.10803, - 4.0593499999999993, 0.25207000000000002, 0.10803, 4.0593499999999993, 0.32408999999999999, 0.10803, 4.0593499999999993, 0.39610999999999996, 0.10803, - 4.0593499999999993, 0.43212, 0.10803, 4.0593499999999993, 0.21606, 0.18004999999999999, 4.0593499999999993, 0.25207000000000002, 0.18004999999999999, - 4.0593499999999993, 0.32408999999999999, 0.18004999999999999, 4.0593499999999993, 0.39610999999999996, 0.18004999999999999, 4.0593499999999993, 0.43212, - 0.18004999999999999, 4.0593499999999993, 0.25207000000000002, 0.21605999999999997, 4.0593499999999993, 0.32408999999999999, 0.21605999999999997, - 4.0593499999999993, 0.39610999999999996, 0.21605999999999997, 4.0593499999999993, 0.43212, 0.21605999999999997, 4.0593499999999993, 0, 0.21606, - 4.0593499999999993, 0.21606, 0.21606, 4.0593499999999993, 0, 0, 4.2729999999999997, 0.21606, 0, 4.2729999999999997, 0.25207000000000002, 0, 4.2729999999999997, - 0.32408999999999999, 0, 4.2729999999999997, 0.39610999999999996, 0, 4.2729999999999997, 0.43212, 0, 4.2729999999999997, 0.21606, 0.03601, 4.2729999999999997, - 0.25207000000000002, 0.03601, 4.2729999999999997, 0.32408999999999999, 0.03601, 4.2729999999999997, 0.39610999999999996, 0.03601, 4.2729999999999997, 0.43212, - 0.03601, 4.2729999999999997, 0.21606, 0.10803, 4.2729999999999997, 0.25207000000000002, 0.10803, 4.2729999999999997, 0.32408999999999999, 0.10803, - 4.2729999999999997, 0.39610999999999996, 0.10803, 4.2729999999999997, 0.43212, 0.10803, 4.2729999999999997, 0.21606, 0.18004999999999999, 4.2729999999999997, - 0.25207000000000002, 0.18004999999999999, 4.2729999999999997, 0.32408999999999999, 0.18004999999999999, 4.2729999999999997, 0.39610999999999996, - 0.18004999999999999, 4.2729999999999997, 0.43212, 0.18004999999999999, 4.2729999999999997, 0.25207000000000002, 0.21605999999999997, 4.2729999999999997, - 0.32408999999999999, 0.21605999999999997, 4.2729999999999997, 0.39610999999999996, 0.21605999999999997, 4.2729999999999997, 0.43212, 0.21605999999999997, - 4.2729999999999997, 0, 0.21606, 4.2729999999999997, 0.21606, 0.21606, 4.2729999999999997 -}; - -const int connTFPOLH_I[21]={0, 50, 100, 150, 200, 250, 300, 350, 400, 450, 500, 550, 600, 650, 700, 750, 800, 850, 900, 950, 1000}; diff --git a/src/MEDCoupling/Test/MEDCouplingBasicsTestInterp.cxx b/src/MEDCoupling/Test/MEDCouplingBasicsTestInterp.cxx deleted file mode 100644 index f50b74de9..000000000 --- a/src/MEDCoupling/Test/MEDCouplingBasicsTestInterp.cxx +++ /dev/null @@ -1,2694 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 -// 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 "MEDCouplingBasicsTestInterp.hxx" -#include "MEDCouplingUMesh.hxx" -#include "MEDCouplingExtrudedMesh.hxx" -#include "MEDCouplingFieldDouble.hxx" -#include "MEDCouplingMemArray.hxx" -#include "Interpolation2D.txx" -#include "Interpolation3DSurf.hxx" -#include "Interpolation3D.txx" -#include "Interpolation2D1D.txx" -#include "Interpolation3D2D.txx" -#include "InterpolationCC.txx" -#include "InterpolationCU.txx" -#include "Interpolation2DCurve.hxx" -#include "Interpolation1D.txx" - -#include "MEDCouplingNormalizedUnstructuredMesh.txx" -#include "MEDCouplingNormalizedCartesianMesh.txx" - -#include -#include - -using namespace ParaMEDMEM; - -typedef std::vector > IntersectionMatrix; - -void MEDCouplingBasicsTestInterp::test2DInterpP0P0_1() -{ - MEDCouplingUMesh *sourceMesh=build2DSourceMesh_1(); - MEDCouplingUMesh *targetMesh=build2DTargetMesh_1(); - // - MEDCouplingNormalizedUnstructuredMesh<2,2> sourceWrapper(sourceMesh); - MEDCouplingNormalizedUnstructuredMesh<2,2> targetWrapper(targetMesh); - INTERP_KERNEL::Interpolation2D myInterpolator; - std::vector > res; - INTERP_KERNEL::IntersectionType types[3]={INTERP_KERNEL::Triangulation, INTERP_KERNEL::Convex, INTERP_KERNEL::Geometric2D}; - for(int i=0;i<3;i++) - { - myInterpolator.setPrecision(1e-12); - myInterpolator.setIntersectionType(types[i]); - myInterpolator.interpolateMeshes(sourceWrapper,targetWrapper,res,"P0P0"); - CPPUNIT_ASSERT_EQUAL(5,(int)res.size()); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.125,res[0][0],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.125,res[0][1],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.125,res[1][0],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.125,res[2][0],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.25,res[3][1],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.125,res[4][0],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.125,res[4][1],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,sumAll(res),1e-12); - res.clear(); - } - //clean up - sourceMesh->decrRef(); - targetMesh->decrRef(); -} - -void MEDCouplingBasicsTestInterp::test2DInterpP0P0PL_1() -{ - MEDCouplingUMesh *sourceMesh=build2DSourceMesh_1(); - MEDCouplingUMesh *targetMesh=build2DTargetMesh_1(); - // - MEDCouplingNormalizedUnstructuredMesh<2,2> sourceWrapper(sourceMesh); - MEDCouplingNormalizedUnstructuredMesh<2,2> targetWrapper(targetMesh); - INTERP_KERNEL::Interpolation2D myInterpolator; - std::vector > res; - // - myInterpolator.setIntersectionType(INTERP_KERNEL::PointLocator); - myInterpolator.interpolateMeshes(sourceWrapper,targetWrapper,res,"P0P0"); - CPPUNIT_ASSERT_EQUAL(5,(int)res.size()); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[0][0],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[0][1],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[1][0],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[2][0],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[3][1],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[4][0],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[4][1],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(7.,sumAll(res),1e-12); - // - sourceMesh->decrRef(); - targetMesh->decrRef(); -} - -void MEDCouplingBasicsTestInterp::test2DInterpP0P0PL_2() -{ - MEDCouplingUMesh *sourceMesh=build2DSourceMesh_1(); - MEDCouplingUMesh *targetMesh=build2DTargetMesh_1(); - // - std::vector cellsIds(targetMesh->getNumberOfCells()); - for(int i=0;igetNumberOfCells();i++) - cellsIds[i]=i; - targetMesh->convertToPolyTypes(&cellsIds[0],&cellsIds[0]+cellsIds.size()); - // - MEDCouplingNormalizedUnstructuredMesh<2,2> sourceWrapper(sourceMesh); - MEDCouplingNormalizedUnstructuredMesh<2,2> targetWrapper(targetMesh); - INTERP_KERNEL::Interpolation2D myInterpolator; - std::vector > res; - // - myInterpolator.setIntersectionType(INTERP_KERNEL::PointLocator); - myInterpolator.interpolateMeshes(sourceWrapper,targetWrapper,res,"P0P0"); - CPPUNIT_ASSERT_EQUAL(5,(int)res.size()); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[0][0],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[0][1],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[1][0],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[2][0],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[3][1],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[4][0],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[4][1],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(7.,sumAll(res),1e-12); - // - sourceMesh->decrRef(); - targetMesh->decrRef(); -} - -void MEDCouplingBasicsTestInterp::test2DInterpP0P0PL_3() -{ - MEDCouplingUMesh *sourceMesh=build2DSourceMesh_1(); - MEDCouplingUMesh *targetMesh=build2DTargetMesh_1(); - // - std::vector cellsIds(sourceMesh->getNumberOfCells()); - for(int i=0;igetNumberOfCells();i++) - cellsIds[i]=i; - sourceMesh->convertToPolyTypes(&cellsIds[0],&cellsIds[0]+cellsIds.size()); - // - MEDCouplingNormalizedUnstructuredMesh<2,2> sourceWrapper(sourceMesh); - MEDCouplingNormalizedUnstructuredMesh<2,2> targetWrapper(targetMesh); - INTERP_KERNEL::Interpolation2D myInterpolator; - std::vector > res; - // - myInterpolator.setIntersectionType(INTERP_KERNEL::PointLocator); - myInterpolator.interpolateMeshes(sourceWrapper,targetWrapper,res,"P0P0"); - CPPUNIT_ASSERT_EQUAL(5,(int)res.size()); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[0][0],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[0][1],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[1][0],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[2][0],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[3][1],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[4][0],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[4][1],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(7.,sumAll(res),1e-12); - // - sourceMesh->decrRef(); - targetMesh->decrRef(); -} - -void MEDCouplingBasicsTestInterp::test2DInterpP0P0PL_4() -{ - MEDCouplingUMesh *sourceMesh=build2DSourceMesh_1(); - MEDCouplingUMesh *targetMesh=build2DTargetMesh_1(); - // - std::vector cellsIds(sourceMesh->getNumberOfCells()); - for(int i=0;igetNumberOfCells();i++) - cellsIds[i]=i; - sourceMesh->convertToPolyTypes(&cellsIds[0],&cellsIds[0]+cellsIds.size()); - cellsIds.resize(targetMesh->getNumberOfCells()); - for(int i=0;igetNumberOfCells();i++) - cellsIds[i]=i; - targetMesh->convertToPolyTypes(&cellsIds[0],&cellsIds[0]+cellsIds.size()); - // - MEDCouplingNormalizedUnstructuredMesh<2,2> sourceWrapper(sourceMesh); - MEDCouplingNormalizedUnstructuredMesh<2,2> targetWrapper(targetMesh); - INTERP_KERNEL::Interpolation2D myInterpolator; - std::vector > res; - // - myInterpolator.setIntersectionType(INTERP_KERNEL::PointLocator); - myInterpolator.interpolateMeshes(sourceWrapper,targetWrapper,res,"P0P0"); - CPPUNIT_ASSERT_EQUAL(5,(int)res.size()); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[0][0],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[0][1],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[1][0],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[2][0],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[3][1],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[4][0],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[4][1],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(7.,sumAll(res),1e-12); - // - sourceMesh->decrRef(); - targetMesh->decrRef(); -} - -void MEDCouplingBasicsTestInterp::test2DInterpP0P1_1() -{ - MEDCouplingUMesh *sourceMesh=build2DSourceMesh_1(); - MEDCouplingUMesh *targetMesh=build2DTargetMesh_1(); - // - MEDCouplingNormalizedUnstructuredMesh<2,2> sourceWrapper(sourceMesh); - MEDCouplingNormalizedUnstructuredMesh<2,2> targetWrapper(targetMesh); - INTERP_KERNEL::Interpolation2D myInterpolator; - std::vector > res; - INTERP_KERNEL::IntersectionType types[2]={INTERP_KERNEL::Triangulation, INTERP_KERNEL::Geometric2D}; - for(int i=0;i<2;i++) - { - myInterpolator.setPrecision(1e-12); - myInterpolator.setIntersectionType(types[i]); - myInterpolator.interpolateMeshes(sourceWrapper,targetWrapper,res,"P0P1"); - CPPUNIT_ASSERT_EQUAL(9,(int)res.size()); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.041666666666666664,res[0][0],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.041666666666666664,res[0][1],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.125,res[1][0],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.083333333333333329,res[2][0],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.16666666666666666,res[3][1],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.16666666666666666,res[4][0],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.16666666666666666,res[4][1],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.125,res[5][0],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.083333333333333329,res[6][1],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.16666666666666666,res[7][1],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.041666666666666664,res[8][0],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.041666666666666664,res[8][1],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1.25,sumAll(res),1e-12); - res.clear(); - } - //clean up - sourceMesh->decrRef(); - targetMesh->decrRef(); -} - -void MEDCouplingBasicsTestInterp::test2DInterpP0P1PL_1() -{ - MEDCouplingUMesh *sourceMesh=build2DSourceMesh_1(); - MEDCouplingUMesh *targetMesh=build2DTargetMesh_1(); - // - MEDCouplingNormalizedUnstructuredMesh<2,2> sourceWrapper(sourceMesh); - MEDCouplingNormalizedUnstructuredMesh<2,2> targetWrapper(targetMesh); - INTERP_KERNEL::Interpolation2D myInterpolator; - std::vector > res; - myInterpolator.setPrecision(1e-12); - myInterpolator.setIntersectionType(INTERP_KERNEL::PointLocator); - myInterpolator.interpolateMeshes(sourceWrapper,targetWrapper,res,"P0P1"); - CPPUNIT_ASSERT_EQUAL(9,(int)res.size()); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[0][0],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[0][1],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[1][0],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[2][0],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[3][1],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[4][0],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[4][1],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[5][0],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[6][1],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[7][1],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[8][0],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[8][1],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(12.,sumAll(res),1e-12); - res.clear(); - //clean up - sourceMesh->decrRef(); - targetMesh->decrRef(); -} - -void MEDCouplingBasicsTestInterp::test2DInterpP0P1PL_2() -{ - MEDCouplingUMesh *sourceMesh=build2DSourceMesh_1(); - MEDCouplingUMesh *targetMesh=build2DTargetMesh_1(); - // - std::vector cellsIds(sourceMesh->getNumberOfCells()); - for(int i=0;igetNumberOfCells();i++) - cellsIds[i]=i; - sourceMesh->convertToPolyTypes(&cellsIds[0],&cellsIds[0]+cellsIds.size()); - // - cellsIds.resize(targetMesh->getNumberOfCells()); - for(int i=0;igetNumberOfCells();i++) - cellsIds[i]=i; - targetMesh->convertToPolyTypes(&cellsIds[0],&cellsIds[0]+cellsIds.size()); - // - MEDCouplingNormalizedUnstructuredMesh<2,2> sourceWrapper(sourceMesh); - MEDCouplingNormalizedUnstructuredMesh<2,2> targetWrapper(targetMesh); - INTERP_KERNEL::Interpolation2D myInterpolator; - std::vector > res; - myInterpolator.setPrecision(1e-12); - myInterpolator.setIntersectionType(INTERP_KERNEL::PointLocator); - myInterpolator.interpolateMeshes(sourceWrapper,targetWrapper,res,"P0P1"); - CPPUNIT_ASSERT_EQUAL(9,(int)res.size()); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[0][0],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[0][1],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[1][0],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[2][0],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[3][1],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[4][0],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[4][1],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[5][0],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[6][1],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[7][1],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[8][0],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[8][1],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(12.,sumAll(res),1e-12); - res.clear(); - //clean up - sourceMesh->decrRef(); - targetMesh->decrRef(); -} - -void MEDCouplingBasicsTestInterp::test2DInterpP1P0_1() -{ - MEDCouplingUMesh *sourceMesh=build2DSourceMesh_1(); - MEDCouplingUMesh *targetMesh=build2DTargetMesh_1(); - // - MEDCouplingNormalizedUnstructuredMesh<2,2> sourceWrapper(sourceMesh); - MEDCouplingNormalizedUnstructuredMesh<2,2> targetWrapper(targetMesh); - INTERP_KERNEL::Interpolation2D myInterpolator; - std::vector > res; - INTERP_KERNEL::IntersectionType types[2]={INTERP_KERNEL::Triangulation, INTERP_KERNEL::Geometric2D}; - for(int i=0;i<2;i++) - { - myInterpolator.setPrecision(1e-12); - myInterpolator.setIntersectionType(types[i]); - myInterpolator.interpolateMeshes(sourceWrapper,targetWrapper,res,"P1P0"); - CPPUNIT_ASSERT_EQUAL(5,(int)res.size()); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.25,res[0][0],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.041666666666666664,res[1][0],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.041666666666666664,res[3][0],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.083333333333333333,res[1][1],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.083333333333333333,res[2][1],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.166666666666666667,res[3][2],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.041666666666666664,res[2][3],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.041666666666666664,res[3][3],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.25,res[4][3],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,sumAll(res),1e-12); - res.clear(); - } - //clean up - sourceMesh->decrRef(); - targetMesh->decrRef(); -} - -void MEDCouplingBasicsTestInterp::test2DInterpP1P0PL_1() -{ - MEDCouplingUMesh *sourceMesh=build2DSourceMesh_1(); - MEDCouplingUMesh *targetMesh=build2DTargetMesh_1(); - // - MEDCouplingNormalizedUnstructuredMesh<2,2> sourceWrapper(sourceMesh); - MEDCouplingNormalizedUnstructuredMesh<2,2> targetWrapper(targetMesh); - INTERP_KERNEL::Interpolation2D myInterpolator; - std::vector > res; - myInterpolator.setPrecision(1e-12); - myInterpolator.setIntersectionType(INTERP_KERNEL::PointLocator); - myInterpolator.interpolateMeshes(sourceWrapper,targetWrapper,res,"P1P0"); - CPPUNIT_ASSERT_EQUAL(5,(int)res.size()); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1.5,res[0][0],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.,res[0][1],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.,res[0][2],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.5,res[0][3],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.333333333333333333,res[1][0],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.5,res[1][1],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.166666666666666666,res[1][3],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.166666666666666666,res[2][0],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.5,res[2][1],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.333333333333333333,res[2][3],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.25,res[3][0],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.5,res[3][2],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.25,res[3][3],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.5,res[4][0],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.,res[4][1],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.,res[4][2],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1.5,res[4][3],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(7.,sumAll(res),1e-12); - res.clear(); - //clean up - sourceMesh->decrRef(); - targetMesh->decrRef(); -} - -void MEDCouplingBasicsTestInterp::test2DInterpP1P0PL_2() -{ - MEDCouplingUMesh *sourceMesh=build2DSourceMesh_1(); - MEDCouplingUMesh *targetMesh=build2DTargetMesh_1(); - // - std::vectorcellsIds(targetMesh->getNumberOfCells()); - for(int i=0;igetNumberOfCells();i++) - cellsIds[i]=i; - targetMesh->convertToPolyTypes(&cellsIds[0],&cellsIds[0]+cellsIds.size()); - // - MEDCouplingNormalizedUnstructuredMesh<2,2> sourceWrapper(sourceMesh); - MEDCouplingNormalizedUnstructuredMesh<2,2> targetWrapper(targetMesh); - INTERP_KERNEL::Interpolation2D myInterpolator; - std::vector > res; - myInterpolator.setPrecision(1e-12); - myInterpolator.setIntersectionType(INTERP_KERNEL::PointLocator); - myInterpolator.interpolateMeshes(sourceWrapper,targetWrapper,res,"P1P0"); - CPPUNIT_ASSERT_EQUAL(5,(int)res.size()); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1.5,res[0][0],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.,res[0][1],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.,res[0][2],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.5,res[0][3],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.333333333333333333,res[1][0],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.5,res[1][1],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.166666666666666666,res[1][3],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.166666666666666666,res[2][0],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.5,res[2][1],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.333333333333333333,res[2][3],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.25,res[3][0],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.5,res[3][2],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.25,res[3][3],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.5,res[4][0],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.,res[4][1],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.,res[4][2],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1.5,res[4][3],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(7.,sumAll(res),1e-12); - res.clear(); - //clean up - sourceMesh->decrRef(); - targetMesh->decrRef(); -} - -void MEDCouplingBasicsTestInterp::test2DInterpP1P1_1() -{ - MEDCouplingUMesh *sourceMesh=build2DSourceMesh_1(); - MEDCouplingUMesh *targetMesh=build2DTargetMesh_2(); - // - MEDCouplingNormalizedUnstructuredMesh<2,2> sourceWrapper(sourceMesh); - MEDCouplingNormalizedUnstructuredMesh<2,2> targetWrapper(targetMesh); - INTERP_KERNEL::Interpolation2D myInterpolator; - std::vector > res; - INTERP_KERNEL::IntersectionType types[2]={INTERP_KERNEL::Triangulation, INTERP_KERNEL::Geometric2D}; - for(int i=0;i<2;i++) - { - myInterpolator.setPrecision(1e-12); - myInterpolator.setIntersectionType(types[i]); - myInterpolator.interpolateMeshes(sourceWrapper,targetWrapper,res,"P1P1"); - CPPUNIT_ASSERT_EQUAL(9,(int)res.size()); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.08333333333333334,res[0][0],1.e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.05416666666666665,res[1][0],1.e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.02916666666666666,res[1][1],1.e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.08333333333333334,res[2][1],1.e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.05416666666666665,res[3][0],1.e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.02916666666666668,res[3][2],1.e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.1416666666666666,res[4][0],1.e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.02499999999999999,res[4][1],1.e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.02499999999999999,res[4][2],1.e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.09999999999999999,res[4][3],1.e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.02916666666666666,res[5][1],1.e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.09583333333333333,res[5][3],1.e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.08333333333333333,res[6][2],1.e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.02916666666666667,res[7][2],1.e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.09583333333333331,res[7][3],1.e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.04166666666666668,res[8][3],1.e-12); - res.clear(); - } - //clean up - sourceMesh->decrRef(); - targetMesh->decrRef(); -} - -void MEDCouplingBasicsTestInterp::test2DInterpP1P1PL_1() -{ - MEDCouplingUMesh *sourceMesh=build2DSourceMesh_1(); - MEDCouplingUMesh *targetMesh=build2DTargetMesh_1(); - // - MEDCouplingNormalizedUnstructuredMesh<2,2> sourceWrapper(sourceMesh); - MEDCouplingNormalizedUnstructuredMesh<2,2> targetWrapper(targetMesh); - INTERP_KERNEL::Interpolation2D myInterpolator; - std::vector > res; - myInterpolator.setPrecision(1e-12); - myInterpolator.setIntersectionType(INTERP_KERNEL::PointLocator); - myInterpolator.interpolateMeshes(sourceWrapper,targetWrapper,res,"P1P1"); - CPPUNIT_ASSERT_EQUAL(9,(int)res.size()); - CPPUNIT_ASSERT_DOUBLES_EQUAL(2.,res[0][0],1.e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[1][0],1.e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[1][1],1.e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(2.,res[2][1],1.e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[3][0],1.e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[3][2],1.e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(5.,res[4][0],1.e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(5.,res[4][3],1.e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[5][1],1.e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[5][3],1.e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[6][2],1.e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[7][2],1.e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[7][3],1.e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(2.,res[8][3],1.e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(25.,sumAll(res),1e-12); - res.clear(); - //clean up - sourceMesh->decrRef(); - targetMesh->decrRef(); -} - -void MEDCouplingBasicsTestInterp::test3DSurfInterpP0P0_1() -{ - MEDCouplingUMesh *sourceMesh=build3DSurfSourceMesh_1(); - MEDCouplingUMesh *targetMesh=build3DSurfTargetMesh_1(); - // - MEDCouplingNormalizedUnstructuredMesh<3,2> sourceWrapper(sourceMesh); - MEDCouplingNormalizedUnstructuredMesh<3,2> targetWrapper(targetMesh); - INTERP_KERNEL::Interpolation3DSurf myInterpolator; - std::vector > res; - INTERP_KERNEL::IntersectionType types[3]={INTERP_KERNEL::Triangulation, INTERP_KERNEL::Geometric2D}; - for(int i=0;i<2;i++) - { - myInterpolator.setPrecision(1e-12); - myInterpolator.setIntersectionType(types[i]); - myInterpolator.interpolateMeshes(sourceWrapper,targetWrapper,res,"P0P0"); - CPPUNIT_ASSERT_EQUAL(5,(int)res.size()); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.125*sqrt(2.),res[0][0],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.125*sqrt(2.),res[0][1],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.125*sqrt(2.),res[1][0],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.125*sqrt(2.),res[2][0],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.25*sqrt(2.),res[3][1],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.125*sqrt(2.),res[4][0],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.125*sqrt(2.),res[4][1],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1.*sqrt(2.),sumAll(res),1e-12); - res.clear(); - } - //clean up - sourceMesh->decrRef(); - targetMesh->decrRef(); -} - -void MEDCouplingBasicsTestInterp::test3DSurfInterpP0P0PL_1() -{ - MEDCouplingUMesh *sourceMesh=build3DSurfSourceMesh_1(); - MEDCouplingUMesh *targetMesh=build3DSurfTargetMesh_1(); - // - MEDCouplingNormalizedUnstructuredMesh<3,2> sourceWrapper(sourceMesh); - MEDCouplingNormalizedUnstructuredMesh<3,2> targetWrapper(targetMesh); - INTERP_KERNEL::Interpolation3DSurf myInterpolator; - std::vector > res; - myInterpolator.setPrecision(1e-12); - myInterpolator.setIntersectionType(INTERP_KERNEL::PointLocator); - myInterpolator.interpolateMeshes(sourceWrapper,targetWrapper,res,"P0P0"); - CPPUNIT_ASSERT_EQUAL(5,(int)res.size()); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[0][0],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[0][1],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[1][0],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[2][0],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[3][1],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[4][0],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[4][1],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(7.,sumAll(res),1e-12); - res.clear(); - //clean up - sourceMesh->decrRef(); - targetMesh->decrRef(); -} - -void MEDCouplingBasicsTestInterp::test3DSurfInterpP0P1_1() -{ - MEDCouplingUMesh *sourceMesh=build3DSurfSourceMesh_1(); - MEDCouplingUMesh *targetMesh=build3DSurfTargetMesh_1(); - // - MEDCouplingNormalizedUnstructuredMesh<3,2> sourceWrapper(sourceMesh); - MEDCouplingNormalizedUnstructuredMesh<3,2> targetWrapper(targetMesh); - INTERP_KERNEL::Interpolation3DSurf myInterpolator; - std::vector > res; - INTERP_KERNEL::IntersectionType types[2]={INTERP_KERNEL::Triangulation, INTERP_KERNEL::Geometric2D}; - for(int i=0;i<2;i++) - { - myInterpolator.setPrecision(1e-12); - myInterpolator.setIntersectionType(types[i]); - myInterpolator.interpolateMeshes(sourceWrapper,targetWrapper,res,"P0P1"); - CPPUNIT_ASSERT_EQUAL(9,(int)res.size()); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.041666666666666664*sqrt(2.),res[0][0],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.041666666666666664*sqrt(2.),res[0][1],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.125*sqrt(2.),res[1][0],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.083333333333333329*sqrt(2.),res[2][0],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.16666666666666666*sqrt(2.),res[3][1],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.16666666666666666*sqrt(2.),res[4][0],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.16666666666666666*sqrt(2.),res[4][1],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.125*sqrt(2.),res[5][0],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.083333333333333329*sqrt(2.),res[6][1],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.16666666666666666*sqrt(2.),res[7][1],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.041666666666666664*sqrt(2.),res[8][0],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.041666666666666664*sqrt(2.),res[8][1],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1.25*sqrt(2.),sumAll(res),1e-12); - res.clear(); - } - //clean up - sourceMesh->decrRef(); - targetMesh->decrRef(); -} - -void MEDCouplingBasicsTestInterp::test3DSurfInterpP0P1PL_1() -{ - MEDCouplingUMesh *sourceMesh=build3DSurfSourceMesh_1(); - MEDCouplingUMesh *targetMesh=build3DSurfTargetMesh_1(); - // - MEDCouplingNormalizedUnstructuredMesh<3,2> sourceWrapper(sourceMesh); - MEDCouplingNormalizedUnstructuredMesh<3,2> targetWrapper(targetMesh); - INTERP_KERNEL::Interpolation3DSurf myInterpolator; - std::vector > res; - myInterpolator.setPrecision(1e-12); - myInterpolator.setIntersectionType(INTERP_KERNEL::PointLocator); - myInterpolator.interpolateMeshes(sourceWrapper,targetWrapper,res,"P0P1"); - CPPUNIT_ASSERT_EQUAL(9,(int)res.size()); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[0][0],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[0][1],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[1][0],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[2][0],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[3][1],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[4][0],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[4][1],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[5][0],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[6][1],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[7][1],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[8][0],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[8][1],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(12.,sumAll(res),1e-12); - res.clear(); - //clean up - sourceMesh->decrRef(); - targetMesh->decrRef(); -} - -void MEDCouplingBasicsTestInterp::test3DSurfInterpP1P0_1() -{ - MEDCouplingUMesh *sourceMesh=build3DSurfSourceMesh_1(); - MEDCouplingUMesh *targetMesh=build3DSurfTargetMesh_1(); - // - MEDCouplingNormalizedUnstructuredMesh<3,2> sourceWrapper(sourceMesh); - MEDCouplingNormalizedUnstructuredMesh<3,2> targetWrapper(targetMesh); - INTERP_KERNEL::Interpolation3DSurf myInterpolator; - std::vector > res; - INTERP_KERNEL::IntersectionType types[2]={INTERP_KERNEL::Triangulation, INTERP_KERNEL::Geometric2D}; - for(int i=0;i<2;i++) - { - myInterpolator.setPrecision(1e-12); - myInterpolator.setIntersectionType(types[i]); - myInterpolator.interpolateMeshes(sourceWrapper,targetWrapper,res,"P1P0"); - CPPUNIT_ASSERT_EQUAL(5,(int)res.size()); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.25*sqrt(2.),res[0][0],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.041666666666666664*sqrt(2.),res[1][0],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.041666666666666664*sqrt(2.),res[3][0],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.083333333333333333*sqrt(2.),res[1][1],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.083333333333333333*sqrt(2.),res[2][1],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.166666666666666667*sqrt(2.),res[3][2],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.041666666666666664*sqrt(2.),res[2][3],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.041666666666666664*sqrt(2.),res[3][3],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.25*sqrt(2.),res[4][3],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1.*sqrt(2.),sumAll(res),1e-12); - res.clear(); - } - //clean up - sourceMesh->decrRef(); - targetMesh->decrRef(); -} - -void MEDCouplingBasicsTestInterp::test3DSurfInterpP1P0PL_1() -{ - MEDCouplingUMesh *sourceMesh=build3DSurfSourceMesh_1(); - MEDCouplingUMesh *targetMesh=build3DSurfTargetMesh_1(); - // - MEDCouplingNormalizedUnstructuredMesh<3,2> sourceWrapper(sourceMesh); - MEDCouplingNormalizedUnstructuredMesh<3,2> targetWrapper(targetMesh); - INTERP_KERNEL::Interpolation3DSurf myInterpolator; - std::vector > res; - myInterpolator.setPrecision(1e-12); - myInterpolator.setIntersectionType(INTERP_KERNEL::PointLocator); - myInterpolator.interpolateMeshes(sourceWrapper,targetWrapper,res,"P1P0"); - CPPUNIT_ASSERT_EQUAL(5,(int)res.size()); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1.5,res[0][0],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.,res[0][1],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.,res[0][2],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.5,res[0][3],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.333333333333333333,res[1][0],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.5,res[1][1],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.166666666666666666,res[1][3],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.166666666666666666,res[2][0],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.5,res[2][1],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.333333333333333333,res[2][3],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.25,res[3][0],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.5,res[3][2],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.25,res[3][3],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.5,res[4][0],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.,res[4][1],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.,res[4][2],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1.5,res[4][3],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(7.,sumAll(res),1e-12); - res.clear(); - //clean up - sourceMesh->decrRef(); - targetMesh->decrRef(); -} - -void MEDCouplingBasicsTestInterp::test3DSurfInterpP1P1_1() -{ - MEDCouplingUMesh *sourceMesh=build3DSurfSourceMesh_1(); - MEDCouplingUMesh *targetMesh=build3DSurfTargetMesh_2(); - // - MEDCouplingNormalizedUnstructuredMesh<3,2> sourceWrapper(sourceMesh); - MEDCouplingNormalizedUnstructuredMesh<3,2> targetWrapper(targetMesh); - INTERP_KERNEL::Interpolation3DSurf myInterpolator; - std::vector > res; - INTERP_KERNEL::IntersectionType types[2]={INTERP_KERNEL::Triangulation, INTERP_KERNEL::Geometric2D}; - for(int i=0;i<2;i++) - { - myInterpolator.setPrecision(1e-12); - myInterpolator.setIntersectionType(types[i]); - myInterpolator.interpolateMeshes(sourceWrapper,targetWrapper,res,"P1P1"); - CPPUNIT_ASSERT_EQUAL(9,(int)res.size()); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.08333333333333334*sqrt(2.),res[0][0],1.e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.05416666666666665*sqrt(2.),res[1][0],1.e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.02916666666666666*sqrt(2.),res[1][1],1.e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.08333333333333334*sqrt(2.),res[2][1],1.e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.05416666666666665*sqrt(2.),res[3][0],1.e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.02916666666666668*sqrt(2.),res[3][2],1.e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.1416666666666666*sqrt(2.),res[4][0],1.e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.02499999999999999*sqrt(2.),res[4][1],1.e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.02499999999999999*sqrt(2.),res[4][2],1.e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.09999999999999999*sqrt(2.),res[4][3],1.e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.02916666666666666*sqrt(2.),res[5][1],1.e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.09583333333333333*sqrt(2.),res[5][3],1.e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.08333333333333333*sqrt(2.),res[6][2],1.e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.02916666666666667*sqrt(2.),res[7][2],1.e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.09583333333333331*sqrt(2.),res[7][3],1.e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.04166666666666668*sqrt(2.),res[8][3],1.e-12); - res.clear(); - } - // - sourceMesh->decrRef(); - targetMesh->decrRef(); -} - -void MEDCouplingBasicsTestInterp::test3DSurfInterpP1P1PL_1() -{ - MEDCouplingUMesh *sourceMesh=build3DSurfSourceMesh_1(); - MEDCouplingUMesh *targetMesh=build3DSurfTargetMesh_1(); - // - MEDCouplingNormalizedUnstructuredMesh<3,2> sourceWrapper(sourceMesh); - MEDCouplingNormalizedUnstructuredMesh<3,2> targetWrapper(targetMesh); - INTERP_KERNEL::Interpolation3DSurf myInterpolator; - std::vector > res; - myInterpolator.setPrecision(1e-12); - myInterpolator.setIntersectionType(INTERP_KERNEL::PointLocator); - myInterpolator.interpolateMeshes(sourceWrapper,targetWrapper,res,"P1P1"); - CPPUNIT_ASSERT_EQUAL(9,(int)res.size()); - CPPUNIT_ASSERT_DOUBLES_EQUAL(2.,res[0][0],1.e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[1][0],1.e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[1][1],1.e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(2.,res[2][1],1.e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[3][0],1.e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[3][2],1.e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(5.,res[4][0],1.e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(5.,res[4][3],1.e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[5][1],1.e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[5][3],1.e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[6][2],1.e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[7][2],1.e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[7][3],1.e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(2.,res[8][3],1.e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(25.,sumAll(res),1e-12); - res.clear(); - //clean up - sourceMesh->decrRef(); - targetMesh->decrRef(); -} - -void MEDCouplingBasicsTestInterp::test3DSurfInterpP0P0_2() -{ - MEDCouplingUMesh *sourceMesh=build3DSurfSourceMesh_1(); - MEDCouplingUMesh *targetMesh=build3DSurfTargetMeshPerm_1(); - // - MEDCouplingNormalizedUnstructuredMesh<3,2> sourceWrapper(sourceMesh); - MEDCouplingNormalizedUnstructuredMesh<3,2> targetWrapper(targetMesh); - INTERP_KERNEL::Interpolation3DSurf myInterpolator; - std::vector > res; - myInterpolator.setPrecision(1e-12); - myInterpolator.setIntersectionType(INTERP_KERNEL::Triangulation); - { - myInterpolator.setOrientation(2); - myInterpolator.interpolateMeshes(sourceWrapper,targetWrapper,res,"P0P0"); - CPPUNIT_ASSERT_EQUAL(5,(int)res.size()); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.125*sqrt(2.),res[0][0],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.125*sqrt(2.),res[0][1],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.125*sqrt(2.),res[1][0],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.125*sqrt(2.),res[2][0],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.25*sqrt(2.),res[3][1],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.125*sqrt(2.),res[4][0],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.125*sqrt(2.),res[4][1],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1.*sqrt(2.),sumAll(res),1e-12); - res.clear(); - } - { - myInterpolator.setOrientation(0); - myInterpolator.interpolateMeshes(sourceWrapper,targetWrapper,res,"P0P0"); - CPPUNIT_ASSERT_EQUAL(5,(int)res.size()); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.125*sqrt(2.),res[0][0],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.125*sqrt(2.),res[0][1],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.125*sqrt(2.),res[1][0],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(-0.125*sqrt(2.),res[2][0],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.25*sqrt(2.),res[3][1],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.125*sqrt(2.),res[4][0],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.125*sqrt(2.),res[4][1],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.75*sqrt(2.),sumAll(res),1e-12); - res.clear(); - } - { - myInterpolator.setOrientation(1); - myInterpolator.interpolateMeshes(sourceWrapper,targetWrapper,res,"P0P0"); - CPPUNIT_ASSERT_EQUAL(5,(int)res.size()); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.125*sqrt(2.),res[0][0],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.125*sqrt(2.),res[0][1],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.125*sqrt(2.),res[1][0],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.25*sqrt(2.),res[3][1],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.125*sqrt(2.),res[4][0],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.125*sqrt(2.),res[4][1],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.875*sqrt(2.),sumAll(res),1e-12); - res.clear(); - } - { - myInterpolator.setOrientation(-1); - myInterpolator.interpolateMeshes(sourceWrapper,targetWrapper,res,"P0P0"); - CPPUNIT_ASSERT_EQUAL(5,(int)res.size()); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.125*sqrt(2.),res[2][0],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.125*sqrt(2.),sumAll(res),1e-12); - res.clear(); - } - //clean up - sourceMesh->decrRef(); - targetMesh->decrRef(); -} - -/*! - * Test of precision option implemented by Fabien that represents distance of "barycenter" to the other cell. - */ -void MEDCouplingBasicsTestInterp::test3DSurfInterpP0P0_3() -{ - INTERP_KERNEL::Interpolation3DSurf myInterpolator; - std::vector > res; - double vecTrans[3]={0.,0.,1.e-10}; - double vec[3]={0.,-1.,0.}; - double pt[3]={-0.3,-0.3,5.e-11}; - const int N=32; - const double deltaA=M_PI/N; - myInterpolator.setPrecision(1e-12); - myInterpolator.setIntersectionType(INTERP_KERNEL::Triangulation); - myInterpolator.setMaxDistance3DSurfIntersect(1e-9); - for(int i=0;irotate(pt,vec,i*deltaA); - MEDCouplingUMesh *targetMesh=build3DSurfSourceMesh_2(); - targetMesh->translate(vecTrans); - targetMesh->rotate(pt,vec,i*deltaA); - MEDCouplingNormalizedUnstructuredMesh<3,2> sourceWrapper(sourceMesh); - MEDCouplingNormalizedUnstructuredMesh<3,2> targetWrapper(targetMesh); - myInterpolator.interpolateMeshes(sourceWrapper,targetWrapper,res,"P0P0"); - CPPUNIT_ASSERT_EQUAL(2,(int)res.size()); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,sumAll(res),1e-12); - sourceMesh->decrRef(); - targetMesh->decrRef(); - } - // - myInterpolator.setMaxDistance3DSurfIntersect(1e-11); - for(int i=0;irotate(pt,vec,i*deltaA); - MEDCouplingUMesh *targetMesh=build3DSurfSourceMesh_2(); - targetMesh->translate(vecTrans); - targetMesh->rotate(pt,vec,i*deltaA); - MEDCouplingNormalizedUnstructuredMesh<3,2> sourceWrapper(sourceMesh); - MEDCouplingNormalizedUnstructuredMesh<3,2> targetWrapper(targetMesh); - myInterpolator.interpolateMeshes(sourceWrapper,targetWrapper,res,"P0P0"); - CPPUNIT_ASSERT_EQUAL(2,(int)res.size()); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.,sumAll(res),1e-12); - sourceMesh->decrRef(); - targetMesh->decrRef(); - } - // - res.clear(); - myInterpolator.setMaxDistance3DSurfIntersect(-1.);//unactivate fabien lookup - MEDCouplingUMesh *sourceMesh=build3DSurfSourceMesh_2(); - MEDCouplingUMesh *targetMesh=build3DSurfSourceMesh_2(); - targetMesh->translate(vecTrans); - myInterpolator.setBoundingBoxAdjustment(1e-11); - MEDCouplingNormalizedUnstructuredMesh<3,2> sourceWrapper0(sourceMesh); - MEDCouplingNormalizedUnstructuredMesh<3,2> targetWrapper0(targetMesh); - myInterpolator.interpolateMeshes(sourceWrapper0,targetWrapper0,res,"P0P0"); - CPPUNIT_ASSERT_EQUAL(2,(int)res.size()); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.,sumAll(res),1e-12); - sourceMesh->decrRef(); - targetMesh->decrRef(); - // - res.clear(); - sourceMesh=build3DSurfSourceMesh_2(); - targetMesh=build3DSurfSourceMesh_2(); - targetMesh->translate(vecTrans); - myInterpolator.setBoundingBoxAdjustment(1e-9); - MEDCouplingNormalizedUnstructuredMesh<3,2> sourceWrapper1(sourceMesh); - MEDCouplingNormalizedUnstructuredMesh<3,2> targetWrapper1(targetMesh); - myInterpolator.interpolateMeshes(sourceWrapper1,targetWrapper1,res,"P0P0"); - CPPUNIT_ASSERT_EQUAL(2,(int)res.size()); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,sumAll(res),1e-12); - sourceMesh->decrRef(); - targetMesh->decrRef(); - //keeping the same bbox adj == 1.e-11 but trying rotation - res.clear(); - sourceMesh=build3DSurfSourceMesh_2(); - sourceMesh->rotate(pt,vec,M_PI/4.); - targetMesh=build3DSurfSourceMesh_2(); - targetMesh->translate(vecTrans); - targetMesh->rotate(pt,vec,M_PI/4.); - myInterpolator.setBoundingBoxAdjustment(1e-11); - MEDCouplingNormalizedUnstructuredMesh<3,2> sourceWrapper2(sourceMesh); - MEDCouplingNormalizedUnstructuredMesh<3,2> targetWrapper2(targetMesh); - myInterpolator.interpolateMeshes(sourceWrapper2,targetWrapper2,res,"P0P0"); - CPPUNIT_ASSERT_EQUAL(2,(int)res.size()); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,sumAll(res),1e-12); - sourceMesh->decrRef(); - targetMesh->decrRef(); -} - -void MEDCouplingBasicsTestInterp::test3DInterpP0P0_1() -{ - MEDCouplingUMesh *sourceMesh=build3DSourceMesh_1(); - MEDCouplingUMesh *targetMesh=build3DTargetMesh_1(); - // - MEDCouplingNormalizedUnstructuredMesh<3,3> sourceWrapper(sourceMesh); - MEDCouplingNormalizedUnstructuredMesh<3,3> targetWrapper(targetMesh); - INTERP_KERNEL::Interpolation3D myInterpolator; - std::vector > res; - myInterpolator.setPrecision(1e-12); - INTERP_KERNEL::SplittingPolicy sp[] = { INTERP_KERNEL::PLANAR_FACE_5, INTERP_KERNEL::PLANAR_FACE_6, INTERP_KERNEL::GENERAL_24, INTERP_KERNEL::GENERAL_48 }; - for ( int i = 0; i < 4; ++i ) - { - myInterpolator.setSplittingPolicy( sp[i] ); - res.clear(); - myInterpolator.interpolateMeshes(sourceWrapper,targetWrapper,res,"P0P0"); - CPPUNIT_ASSERT_EQUAL(8,(int)res.size()); - CPPUNIT_ASSERT_DOUBLES_EQUAL(8.e6,sumAll(res),1e-7); - CPPUNIT_ASSERT_DOUBLES_EQUAL(20833.33333333333,res[0][0],1e-7); - CPPUNIT_ASSERT_DOUBLES_EQUAL(41666.66666666667,res[0][6],1e-7); - CPPUNIT_ASSERT_DOUBLES_EQUAL(20833.33333333333,res[0][7],1e-7); - CPPUNIT_ASSERT_DOUBLES_EQUAL(20833.33333333333,res[0][8],1e-7); - CPPUNIT_ASSERT_DOUBLES_EQUAL(20833.33333333333,res[0][10],1e-7); - CPPUNIT_ASSERT_DOUBLES_EQUAL(41666.66666666667,res[1][2],1e-7); - CPPUNIT_ASSERT_DOUBLES_EQUAL(166666.6666666667,res[1][7],1e-7); - CPPUNIT_ASSERT_DOUBLES_EQUAL(166666.6666666667,res[1][8],1e-7); - CPPUNIT_ASSERT_DOUBLES_EQUAL(166666.6666666667,res[2][0],1e-7); - CPPUNIT_ASSERT_DOUBLES_EQUAL(20833.33333333333,res[2][5],1e-7); - CPPUNIT_ASSERT_DOUBLES_EQUAL(145833.3333333333,res[2][6],1e-7); - CPPUNIT_ASSERT_DOUBLES_EQUAL(20833.33333333333,res[2][9],1e-7); - CPPUNIT_ASSERT_DOUBLES_EQUAL(20833.33333333333,res[2][11],1e-7); - CPPUNIT_ASSERT_DOUBLES_EQUAL(395833.3333333333,res[3][0],1e-7); - CPPUNIT_ASSERT_DOUBLES_EQUAL(145833.3333333333,res[3][2],1e-7); - CPPUNIT_ASSERT_DOUBLES_EQUAL(20833.33333333331,res[3][3],1e-7); - CPPUNIT_ASSERT_DOUBLES_EQUAL(166666.6666666667,res[3][5],1e-7); - CPPUNIT_ASSERT_DOUBLES_EQUAL(395833.3333333333,res[3][8],1e-7); - CPPUNIT_ASSERT_DOUBLES_EQUAL(20833.33333333333,res[4][1],1e-7); - CPPUNIT_ASSERT_DOUBLES_EQUAL(20833.33333333333,res[4][4],1e-7); - CPPUNIT_ASSERT_DOUBLES_EQUAL(145833.3333333333,res[4][6],1e-7); - CPPUNIT_ASSERT_DOUBLES_EQUAL(20833.33333333333,res[4][9],1e-7); - CPPUNIT_ASSERT_DOUBLES_EQUAL(166666.6666666667,res[4][10],1e-7); - CPPUNIT_ASSERT_DOUBLES_EQUAL(145833.3333333333,res[5][2],1e-7); - CPPUNIT_ASSERT_DOUBLES_EQUAL(20833.33333333331,res[5][3],1e-7); - CPPUNIT_ASSERT_DOUBLES_EQUAL(166666.6666666667,res[5][4],1e-7); - CPPUNIT_ASSERT_DOUBLES_EQUAL(395833.3333333333,res[5][7],1e-7); - CPPUNIT_ASSERT_DOUBLES_EQUAL(395833.3333333333,res[5][10],1e-7); - CPPUNIT_ASSERT_DOUBLES_EQUAL(166666.6666666667,res[6][1],1e-7); - CPPUNIT_ASSERT_DOUBLES_EQUAL(250000,res[6][6],1e-7); - CPPUNIT_ASSERT_DOUBLES_EQUAL(541666.6666666667,res[6][9],1e-7); - CPPUNIT_ASSERT_DOUBLES_EQUAL(166666.6666666667,res[6][11],1e-7); - CPPUNIT_ASSERT_DOUBLES_EQUAL(83333.33333333331,res[7][0],1e-7); - CPPUNIT_ASSERT_DOUBLES_EQUAL(479166.6666666667,res[7][1],1e-7); - CPPUNIT_ASSERT_DOUBLES_EQUAL(333333.3333333333,res[7][2],1e-7); - CPPUNIT_ASSERT_DOUBLES_EQUAL(624999.9999999997,res[7][3],1e-7); - CPPUNIT_ASSERT_DOUBLES_EQUAL(479166.6666666667,res[7][4],1e-7); - CPPUNIT_ASSERT_DOUBLES_EQUAL(479166.6666666667,res[7][5],1e-7); - CPPUNIT_ASSERT_DOUBLES_EQUAL(83333.33333333333,res[7][6],1e-7); - CPPUNIT_ASSERT_DOUBLES_EQUAL(83333.33333333331,res[7][7],1e-7); - CPPUNIT_ASSERT_DOUBLES_EQUAL(83333.33333333333,res[7][8],1e-7); - CPPUNIT_ASSERT_DOUBLES_EQUAL(83333.33333333333,res[7][9],1e-7); - CPPUNIT_ASSERT_DOUBLES_EQUAL(83333.33333333331,res[7][10],1e-7); - CPPUNIT_ASSERT_DOUBLES_EQUAL(479166.6666666667,res[7][11],1e-7); - } - //clean up - sourceMesh->decrRef(); - targetMesh->decrRef(); -} - -void MEDCouplingBasicsTestInterp::test3DInterpP0P0PL_1() -{ - MEDCouplingUMesh *sourceMesh=build3DSourceMesh_1(); - MEDCouplingUMesh *targetMesh=build3DTargetMesh_1(); - // - MEDCouplingNormalizedUnstructuredMesh<3,3> sourceWrapper(sourceMesh); - MEDCouplingNormalizedUnstructuredMesh<3,3> targetWrapper(targetMesh); - INTERP_KERNEL::Interpolation3D myInterpolator; - std::vector > res; - myInterpolator.setPrecision(1e-12); - myInterpolator.setIntersectionType(INTERP_KERNEL::PointLocator); - INTERP_KERNEL::SplittingPolicy sp[] = { INTERP_KERNEL::PLANAR_FACE_5, INTERP_KERNEL::PLANAR_FACE_6, INTERP_KERNEL::GENERAL_24, INTERP_KERNEL::GENERAL_48 }; - for ( int i = 0; i < 4; ++i ) - { - myInterpolator.setSplittingPolicy( sp[i] ); - res.clear(); - myInterpolator.interpolateMeshes(sourceWrapper,targetWrapper,res,"P0P0"); - CPPUNIT_ASSERT_EQUAL(8,(int)res.size()); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[0][0],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[0][6],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[0][7],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[0][8],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[0][10],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[1][7],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[1][8],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[2][0],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[2][6],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[3][0],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[3][8],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[4][6],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[4][10],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[5][7],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[5][10],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[6][9],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[7][1],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[7][3],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[7][4],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[7][5],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[7][11],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(21.,sumAll(res),1e-12); - } - //clean up - sourceMesh->decrRef(); - targetMesh->decrRef(); -} - -void MEDCouplingBasicsTestInterp::test3DInterpP0P0PL_2() -{ - MEDCouplingUMesh *sourceMesh=build3DSourceMesh_1(); - MEDCouplingUMesh *targetMesh=build3DTargetMesh_1(); - std::vector cellsIds(targetMesh->getNumberOfCells()); - for(int i=0;igetNumberOfCells();i++) - cellsIds[i]=i; - targetMesh->convertToPolyTypes(&cellsIds[0],&cellsIds[0]+cellsIds.size()); - // - MEDCouplingNormalizedUnstructuredMesh<3,3> sourceWrapper(sourceMesh); - MEDCouplingNormalizedUnstructuredMesh<3,3> targetWrapper(targetMesh); - INTERP_KERNEL::Interpolation3D myInterpolator; - std::vector > res; - myInterpolator.setPrecision(1e-12); - myInterpolator.setIntersectionType(INTERP_KERNEL::PointLocator); - INTERP_KERNEL::SplittingPolicy sp[] = { INTERP_KERNEL::PLANAR_FACE_5, INTERP_KERNEL::PLANAR_FACE_6, INTERP_KERNEL::GENERAL_24, INTERP_KERNEL::GENERAL_48 }; - for ( int i = 0; i < 4; ++i ) - { - myInterpolator.setSplittingPolicy( sp[i] ); - res.clear(); - myInterpolator.interpolateMeshes(sourceWrapper,targetWrapper,res,"P0P0"); - CPPUNIT_ASSERT_EQUAL(8,(int)res.size()); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[0][0],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[0][6],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[0][7],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[0][8],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[0][10],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[1][7],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[1][8],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[2][0],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[2][6],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[3][0],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[3][8],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[4][6],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[4][10],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[5][7],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[5][10],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[6][9],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[7][1],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[7][3],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[7][4],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[7][5],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[7][11],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(21.,sumAll(res),1e-12); - } - //clean up - sourceMesh->decrRef(); - targetMesh->decrRef(); -} - -void MEDCouplingBasicsTestInterp::test3DInterpP0P0PL_3() -{ - MEDCouplingUMesh *sourceMesh=build3DSourceMesh_1(); - MEDCouplingUMesh *targetMesh=build3DTargetMesh_1(); - std::vector cellsIds(sourceMesh->getNumberOfCells()); - for(int i=0;igetNumberOfCells();i++) - cellsIds[i]=i; - sourceMesh->convertToPolyTypes(&cellsIds[0],&cellsIds[0]+cellsIds.size()); - // - MEDCouplingNormalizedUnstructuredMesh<3,3> sourceWrapper(sourceMesh); - MEDCouplingNormalizedUnstructuredMesh<3,3> targetWrapper(targetMesh); - INTERP_KERNEL::Interpolation3D myInterpolator; - std::vector > res; - myInterpolator.setPrecision(1e-12); - myInterpolator.setIntersectionType(INTERP_KERNEL::PointLocator); - INTERP_KERNEL::SplittingPolicy sp[] = { INTERP_KERNEL::PLANAR_FACE_5, INTERP_KERNEL::PLANAR_FACE_6, INTERP_KERNEL::GENERAL_24, INTERP_KERNEL::GENERAL_48 }; - for ( int i = 0; i < 4; ++i ) - { - myInterpolator.setSplittingPolicy( sp[i] ); - res.clear(); - myInterpolator.interpolateMeshes(sourceWrapper,targetWrapper,res,"P0P0"); - CPPUNIT_ASSERT_EQUAL(8,(int)res.size()); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[0][0],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[0][6],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[0][7],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[0][8],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[0][10],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[1][7],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[1][8],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[2][0],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[2][6],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[3][0],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[3][8],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[4][6],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[4][10],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[5][7],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[5][10],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[6][9],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[7][1],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[7][3],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[7][4],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[7][5],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[7][11],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(21.,sumAll(res),1e-12); - } - //clean up - sourceMesh->decrRef(); - targetMesh->decrRef(); -} - -void MEDCouplingBasicsTestInterp::test3DInterpP0P0PL_4() -{ - MEDCouplingUMesh *sourceMesh=build3DSourceMesh_1(); - MEDCouplingUMesh *targetMesh=build3DTargetMesh_1(); - std::vector cellsIds(sourceMesh->getNumberOfCells()); - for(int i=0;igetNumberOfCells();i++) - cellsIds[i]=i; - sourceMesh->convertToPolyTypes(&cellsIds[0],&cellsIds[0]+cellsIds.size()); - cellsIds.resize(targetMesh->getNumberOfCells()); - for(int j=0;jgetNumberOfCells();j++) - cellsIds[j]=j; - targetMesh->convertToPolyTypes(&cellsIds[0],&cellsIds[0]+cellsIds.size()); - // - MEDCouplingNormalizedUnstructuredMesh<3,3> sourceWrapper(sourceMesh); - MEDCouplingNormalizedUnstructuredMesh<3,3> targetWrapper(targetMesh); - INTERP_KERNEL::Interpolation3D myInterpolator; - std::vector > res; - myInterpolator.setPrecision(1e-12); - myInterpolator.setIntersectionType(INTERP_KERNEL::PointLocator); - INTERP_KERNEL::SplittingPolicy sp[] = { INTERP_KERNEL::PLANAR_FACE_5, INTERP_KERNEL::PLANAR_FACE_6, INTERP_KERNEL::GENERAL_24, INTERP_KERNEL::GENERAL_48 }; - for ( int i = 0; i < 4; ++i ) - { - myInterpolator.setSplittingPolicy( sp[i] ); - res.clear(); - myInterpolator.interpolateMeshes(sourceWrapper,targetWrapper,res,"P0P0"); - CPPUNIT_ASSERT_EQUAL(8,(int)res.size()); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[0][0],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[0][6],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[0][7],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[0][8],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[0][10],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[1][7],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[1][8],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[2][0],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[2][6],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[3][0],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[3][8],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[4][6],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[4][10],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[5][7],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[5][10],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[6][9],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[7][1],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[7][3],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[7][4],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[7][5],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[7][11],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(21.,sumAll(res),1e-12); - } - //clean up - sourceMesh->decrRef(); - targetMesh->decrRef(); -} - -void MEDCouplingBasicsTestInterp::test3DInterpP0P1_1() -{ - MEDCouplingUMesh *sourceMesh=build3DTargetMesh_1(); - MEDCouplingUMesh *targetMesh=build3DSourceMesh_1(); - // - MEDCouplingNormalizedUnstructuredMesh<3,3> sourceWrapper(sourceMesh); - MEDCouplingNormalizedUnstructuredMesh<3,3> targetWrapper(targetMesh); - INTERP_KERNEL::Interpolation3D myInterpolator; - std::vector > res; - myInterpolator.setPrecision(1e-12); - INTERP_KERNEL::SplittingPolicy sp[] = { INTERP_KERNEL::PLANAR_FACE_5, INTERP_KERNEL::PLANAR_FACE_6, INTERP_KERNEL::GENERAL_24, INTERP_KERNEL::GENERAL_48 }; - for ( int i = 0; i < 4; ++i ) - { - myInterpolator.setSplittingPolicy( sp[i] ); - res.clear(); - myInterpolator.interpolateMeshes(sourceWrapper,targetWrapper,res,"P0P1"); - CPPUNIT_ASSERT_EQUAL(9,(int)res.size()); - CPPUNIT_ASSERT_DOUBLES_EQUAL(244444.4444444445,res[0][4],1e-7); - CPPUNIT_ASSERT_DOUBLES_EQUAL(145833.3333333333,res[0][5],1e-7); - CPPUNIT_ASSERT_DOUBLES_EQUAL(291666.6666666666,res[0][6],1e-7); - CPPUNIT_ASSERT_DOUBLES_EQUAL(151388.8888888889,res[0][7],1e-7); - CPPUNIT_ASSERT_DOUBLES_EQUAL(125000,res[1][0],1e-7); - CPPUNIT_ASSERT_DOUBLES_EQUAL(140277.7777777778,res[1][1],1e-7); - CPPUNIT_ASSERT_DOUBLES_EQUAL(119444.4444444444,res[1][2],1e-7); - CPPUNIT_ASSERT_DOUBLES_EQUAL(151388.8888888889,res[1][3],1e-7); - CPPUNIT_ASSERT_DOUBLES_EQUAL(119444.4444444444,res[1][4],1e-7); - CPPUNIT_ASSERT_DOUBLES_EQUAL(151388.8888888889,res[1][5],1e-7); - CPPUNIT_ASSERT_DOUBLES_EQUAL(26388.88888888889,res[1][6],1e-7); - CPPUNIT_ASSERT_DOUBLES_EQUAL(348611.1111111111,res[2][6],1e-7); - CPPUNIT_ASSERT_DOUBLES_EQUAL(151388.8888888888,res[2][7],1e-7); - CPPUNIT_ASSERT_DOUBLES_EQUAL(244444.4444444444,res[3][2],1e-7); - CPPUNIT_ASSERT_DOUBLES_EQUAL(145833.3333333334,res[3][3],1e-7); - CPPUNIT_ASSERT_DOUBLES_EQUAL(291666.6666666666,res[3][6],1e-7); - CPPUNIT_ASSERT_DOUBLES_EQUAL(151388.8888888889,res[3][7],1e-7); - CPPUNIT_ASSERT_DOUBLES_EQUAL(536111.111111111,res[4][5],1e-7); - CPPUNIT_ASSERT_DOUBLES_EQUAL(297222.2222222221,res[4][7],1e-7); - CPPUNIT_ASSERT_DOUBLES_EQUAL(223611.1111111111,res[5][1],1e-7); - CPPUNIT_ASSERT_DOUBLES_EQUAL(125000,res[5][3],1e-7); - CPPUNIT_ASSERT_DOUBLES_EQUAL(125000,res[5][5],1e-7); - CPPUNIT_ASSERT_DOUBLES_EQUAL(26388.88888888892,res[5][7],1e-7); - CPPUNIT_ASSERT_DOUBLES_EQUAL(833333.333333333,res[6][7],1e-7); - CPPUNIT_ASSERT_DOUBLES_EQUAL(536111.1111111109,res[7][3],1e-7); - CPPUNIT_ASSERT_DOUBLES_EQUAL(297222.2222222221,res[7][7],1e-7); - CPPUNIT_ASSERT_DOUBLES_EQUAL(11111.1111111111,res[8][1],1e-7); - CPPUNIT_ASSERT_DOUBLES_EQUAL(11111.11111111111,res[8][2],1e-7); - CPPUNIT_ASSERT_DOUBLES_EQUAL(166666.6666666666,res[8][3],1e-7); - CPPUNIT_ASSERT_DOUBLES_EQUAL(11111.11111111111,res[8][4],1e-7); - CPPUNIT_ASSERT_DOUBLES_EQUAL(166666.6666666667,res[8][5],1e-7); - CPPUNIT_ASSERT_DOUBLES_EQUAL(166666.6666666667,res[8][6],1e-7); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1466666.666666668,res[8][7],1e-7); - } - //clean up - sourceMesh->decrRef(); - targetMesh->decrRef(); -} - -void MEDCouplingBasicsTestInterp::test3DInterpP0P1PL_1() -{ - MEDCouplingUMesh *sourceMesh=build3DTargetMesh_1(); - MEDCouplingUMesh *targetMesh=build3DSourceMesh_1(); - // - MEDCouplingNormalizedUnstructuredMesh<3,3> sourceWrapper(sourceMesh); - MEDCouplingNormalizedUnstructuredMesh<3,3> targetWrapper(targetMesh); - INTERP_KERNEL::Interpolation3D myInterpolator; - std::vector > res; - myInterpolator.setPrecision(1e-12); - myInterpolator.setIntersectionType(INTERP_KERNEL::PointLocator); - INTERP_KERNEL::SplittingPolicy sp[] = { INTERP_KERNEL::PLANAR_FACE_5, INTERP_KERNEL::PLANAR_FACE_6, INTERP_KERNEL::GENERAL_24, INTERP_KERNEL::GENERAL_48 }; - for ( int i = 0; i < 4; ++i ) - { - myInterpolator.setSplittingPolicy( sp[i] ); - res.clear(); - myInterpolator.interpolateMeshes(sourceWrapper,targetWrapper,res,"P0P1"); - CPPUNIT_ASSERT_EQUAL(9,(int)res.size()); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[0][4],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[1][0],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[2][6],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[3][2],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[4][5],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[5][1],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[6][7],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[7][3],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[8][7],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(9.,sumAll(res),1e-12); - } - //clean up - sourceMesh->decrRef(); - targetMesh->decrRef(); -} - -void MEDCouplingBasicsTestInterp::test3DInterpP1P0_1() -{ - MEDCouplingUMesh *sourceMesh=build3DSourceMesh_1(); - MEDCouplingUMesh *targetMesh=build3DTargetMesh_1(); - // - MEDCouplingNormalizedUnstructuredMesh<3,3> sourceWrapper(sourceMesh); - MEDCouplingNormalizedUnstructuredMesh<3,3> targetWrapper(targetMesh); - INTERP_KERNEL::Interpolation3D myInterpolator; - std::vector > res; - myInterpolator.setPrecision(1e-12); - INTERP_KERNEL::SplittingPolicy sp[] = { INTERP_KERNEL::PLANAR_FACE_5, INTERP_KERNEL::PLANAR_FACE_6, INTERP_KERNEL::GENERAL_24, INTERP_KERNEL::GENERAL_48 }; - for ( int i = 0; i < 4; ++i ) - { - myInterpolator.setSplittingPolicy( sp[i] ); - res.clear(); - myInterpolator.interpolateMeshes(sourceWrapper,targetWrapper,res,"P1P0"); - CPPUNIT_ASSERT_EQUAL(8,(int)res.size()); - CPPUNIT_ASSERT_DOUBLES_EQUAL(125000,res[0][1],1e-7); - CPPUNIT_ASSERT_DOUBLES_EQUAL(140277.7777777778,res[1][1],1e-7); - CPPUNIT_ASSERT_DOUBLES_EQUAL(223611.1111111111,res[1][5],1e-7); - CPPUNIT_ASSERT_DOUBLES_EQUAL(11111.1111111111,res[1][8],1e-7); - CPPUNIT_ASSERT_DOUBLES_EQUAL(119444.4444444444,res[2][1],1e-7); - CPPUNIT_ASSERT_DOUBLES_EQUAL(244444.4444444445,res[2][3],1e-7); - CPPUNIT_ASSERT_DOUBLES_EQUAL(11111.11111111111,res[2][8],1e-7); - CPPUNIT_ASSERT_DOUBLES_EQUAL(151388.8888888889,res[3][1],1e-7); - CPPUNIT_ASSERT_DOUBLES_EQUAL(145833.3333333333,res[3][3],1e-7); - CPPUNIT_ASSERT_DOUBLES_EQUAL(125000,res[3][5],1e-7); - CPPUNIT_ASSERT_DOUBLES_EQUAL(536111.1111111109,res[3][7],1e-7); - CPPUNIT_ASSERT_DOUBLES_EQUAL(166666.6666666667,res[3][8],1e-7); - CPPUNIT_ASSERT_DOUBLES_EQUAL(244444.4444444445,res[4][0],1e-7); - CPPUNIT_ASSERT_DOUBLES_EQUAL(119444.4444444445,res[4][1],1e-7); - CPPUNIT_ASSERT_DOUBLES_EQUAL(11111.11111111111,res[4][8],1e-7); - CPPUNIT_ASSERT_DOUBLES_EQUAL(145833.3333333333,res[5][0],1e-7); - CPPUNIT_ASSERT_DOUBLES_EQUAL(151388.8888888889,res[5][1],1e-7); - CPPUNIT_ASSERT_DOUBLES_EQUAL(536111.1111111109,res[5][4],1e-7); - CPPUNIT_ASSERT_DOUBLES_EQUAL(125000,res[5][5],1e-7); - CPPUNIT_ASSERT_DOUBLES_EQUAL(166666.6666666666,res[5][8],1e-7); - CPPUNIT_ASSERT_DOUBLES_EQUAL(291666.6666666666,res[6][0],1e-7); - CPPUNIT_ASSERT_DOUBLES_EQUAL(26388.88888888889,res[6][1],1e-7); - CPPUNIT_ASSERT_DOUBLES_EQUAL(348611.1111111112,res[6][2],1e-7); - CPPUNIT_ASSERT_DOUBLES_EQUAL(291666.6666666667,res[6][3],1e-7); - CPPUNIT_ASSERT_DOUBLES_EQUAL(166666.6666666666,res[6][8],1e-7); - CPPUNIT_ASSERT_DOUBLES_EQUAL(151388.8888888889,res[7][0],1e-7); - CPPUNIT_ASSERT_DOUBLES_EQUAL(151388.8888888889,res[7][2],1e-7); - CPPUNIT_ASSERT_DOUBLES_EQUAL(151388.8888888889,res[7][3],1e-7); - CPPUNIT_ASSERT_DOUBLES_EQUAL(297222.2222222221,res[7][4],1e-7); - CPPUNIT_ASSERT_DOUBLES_EQUAL(26388.88888888892,res[7][5],1e-7); - CPPUNIT_ASSERT_DOUBLES_EQUAL(833333.333333333,res[7][6],1e-7); - CPPUNIT_ASSERT_DOUBLES_EQUAL(297222.2222222222,res[7][7],1e-7); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1466666.666666668,res[7][8],1e-7); - } - //clean up - sourceMesh->decrRef(); - targetMesh->decrRef(); -} - -void MEDCouplingBasicsTestInterp::test3DInterpP1P0PL_1() -{ - MEDCouplingUMesh *sourceMesh=build3DSourceMesh_1(); - MEDCouplingUMesh *targetMesh=build3DTargetMesh_1(); - // - MEDCouplingNormalizedUnstructuredMesh<3,3> sourceWrapper(sourceMesh); - MEDCouplingNormalizedUnstructuredMesh<3,3> targetWrapper(targetMesh); - INTERP_KERNEL::Interpolation3D myInterpolator; - std::vector > res; - myInterpolator.setPrecision(1e-12); - myInterpolator.setIntersectionType(INTERP_KERNEL::PointLocator); - INTERP_KERNEL::SplittingPolicy sp[] = { INTERP_KERNEL::PLANAR_FACE_5, INTERP_KERNEL::PLANAR_FACE_6, INTERP_KERNEL::GENERAL_24, INTERP_KERNEL::GENERAL_48 }; - for ( int i = 0; i < 4; ++i ) - { - myInterpolator.setSplittingPolicy( sp[i] ); - res.clear(); - myInterpolator.interpolateMeshes(sourceWrapper,targetWrapper,res,"P1P0"); - CPPUNIT_ASSERT_EQUAL(8,(int)res.size()); - CPPUNIT_ASSERT_DOUBLES_EQUAL(3.75,res[0][1],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1.25,res[0][8],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.5,res[1][1],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[1][5],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.5,res[1][8],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.5,res[2][1],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[2][3],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.5,res[2][8],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.5,res[3][1],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[3][7],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.5,res[3][8],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[4][0],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.5,res[4][1],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.5,res[4][8],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.5,res[5][1],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[5][4],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.5,res[5][8],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.25,res[6][0],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.25,res[6][2],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.25,res[6][3],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.25,res[6][8],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1.25,res[7][6],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(3.75,res[7][8],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(21.,sumAll(res),1e-12); - } - //clean up - sourceMesh->decrRef(); - targetMesh->decrRef(); -} - -void MEDCouplingBasicsTestInterp::test3DInterpP1P1_1() -{ - MEDCouplingUMesh *sourceMesh=build3DSourceMesh_2(); - MEDCouplingUMesh *targetMesh=build3DTargetMesh_2(); - // - MEDCouplingNormalizedUnstructuredMesh<3,3> sourceWrapper(sourceMesh); - MEDCouplingNormalizedUnstructuredMesh<3,3> targetWrapper(targetMesh); - INTERP_KERNEL::Interpolation3D myInterpolator; - std::vector > res; - myInterpolator.setPrecision(1e-12); - myInterpolator.interpolateMeshes(sourceWrapper,targetWrapper,res,"P1P1"); - CPPUNIT_ASSERT_EQUAL(8,(int)res.size()); - double res3D[8][28]= {{124999.999883775978, 245370.370390364464, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 203703.703634892299, 187500.000094145857, 0.0, 0.0, 4629.6296266718, 0.0, 215277.777751402784, 209722.222322299582, 0.0, 0.0, 0.0, 0.0, 104166.666590829205, 121296.296368812196, 0.0, 250000.000003472145}, - {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 120370.370368827047, 0.0, 0.0, 38888.888897777797, 0.0, 0.0, 45370.3703701697596, 0.0, 0.0, 45370.3703701697596, 83333.3333263888926, 0.0}, - {0.0, 0.0, 0.0, 97222.2222222221753, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 97222.2222222221608, 0.0, 97222.2222222222044, 41666.6666666666642, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, - {0.0, 277777.777787084982, 199074.074074073927, 0.0, 0.0, 0.0, 4629.62962962962774, 0.0, 321759.259254934732, 83333.3333333333139, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 4629.62962667180363, 0.0, 0.0, 251388.88888319055, 194444.444454861077, 0.0, 79629.6296194135939, 250000.000003472145, 0.0, 0.0, 0.0, 0.0}, - {0.0, 0.0, 0.0, 0.0, 85185.1851851851534, 4629.62962962962774, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 118518.518518518511, 0.0, 41666.6666666666642, 83333.3333333333285, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, - {0.0, 324074.07407629228, 0.0, 0.0, 0.0, 247685.185185184964, 6481.48148148147993, 0.0, 173611.11111196311, 0.0, 164814.814814814832, 0.0, 4629.62962962962865, 208333.33333418527, 0.0, 83333.3333333333285, 203703.703697273799, 249999.999999999767, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, - {125000.000000000015, 423611.111111110775, 134259.259259259241, 194444.444444444351, 164814.814814814745, 164351.851851851825, 203703.703703703592, 249999.999999999825, 0.0, 0.0, 0.0, 0.0, 6481.48148148147902, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, - {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 118518.518518518453, 0.0, 4629.62962962962956, 83333.3333333333139, 85185.1851851851825, 41666.6666666666642, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; - int i=0; - double sum = 0; - //cout.precision(18); - for(std::vector >::const_iterator iter1=res.begin();iter1!=res.end();iter1++,i++) - { - //cout<< "res3D[" <::const_iterator iter2=(*iter1).find(j); - if(iter2!=(*iter1).end()) - { - //cout<< iter2->second<< ", "; - sum += iter2->second; - CPPUNIT_ASSERT_DOUBLES_EQUAL(res3D[i][j],(*iter2).second,1.e-5); - } - else - { - //cout << "0.0, "; - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.,res3D[i][j],1e-14); - } - } - //cout << "}" << endl; - } - //cout << "Sum = " << sum << endl; - CPPUNIT_ASSERT_DOUBLES_EQUAL(8000000,sum,1.e-5); - //clean-up - sourceMesh->decrRef(); - targetMesh->decrRef(); -} - -void MEDCouplingBasicsTestInterp::test3DInterpP1P1PL_1() -{ - MEDCouplingUMesh *sourceMesh=build3DSourceMesh_2(); - MEDCouplingUMesh *targetMesh=build3DTargetMesh_2(); - // - MEDCouplingNormalizedUnstructuredMesh<3,3> sourceWrapper(sourceMesh); - MEDCouplingNormalizedUnstructuredMesh<3,3> targetWrapper(targetMesh); - INTERP_KERNEL::Interpolation3D myInterpolator; - std::vector > res; - myInterpolator.setPrecision(1e-12); - myInterpolator.setIntersectionType(INTERP_KERNEL::PointLocator); - myInterpolator.interpolateMeshes(sourceWrapper,targetWrapper,res,"P1P1"); - CPPUNIT_ASSERT_EQUAL(8,(int)res.size()); - CPPUNIT_ASSERT_DOUBLES_EQUAL(20.,res[0][24],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(2.,res[1][26],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[2][21],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(24.,res[3][23],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[4][14],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(24.,res[5][17],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(24.,res[6][7],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[7][11],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(97.,sumAll(res),1e-12); - //clean-up - sourceMesh->decrRef(); - targetMesh->decrRef(); -} - -void MEDCouplingBasicsTestInterp::test3DInterpP0P0Empty() -{ - MEDCouplingUMesh *sourceMesh=MEDCouplingUMesh::New(); - sourceMesh->setMeshDimension(2); - sourceMesh->allocateCells(0); - sourceMesh->finishInsertingCells(); - DataArrayDouble *myCoords=DataArrayDouble::New(); - myCoords->alloc(0,0); - sourceMesh->setCoords(myCoords); - myCoords->decrRef(); - MEDCouplingUMesh *targetMesh=MEDCouplingUMesh::New(); - targetMesh->setMeshDimension(2); - targetMesh->allocateCells(0); - targetMesh->finishInsertingCells(); - myCoords=DataArrayDouble::New(); - myCoords->alloc(0,2); - targetMesh->setCoords(myCoords); - myCoords->decrRef(); - MEDCouplingNormalizedUnstructuredMesh<2,2> sourceWrapper(sourceMesh); - MEDCouplingNormalizedUnstructuredMesh<2,2> targetWrapper(targetMesh); - INTERP_KERNEL::Interpolation2D myInterpolator; - std::vector > res; - myInterpolator.setPrecision(1e-12); - myInterpolator.interpolateMeshes(sourceWrapper,targetWrapper,res,"P0P0"); - //clean up - sourceMesh->decrRef(); - targetMesh->decrRef(); -} - -void MEDCouplingBasicsTestInterp::testInterpolationCC() -{ - double arr1[3] = { 0/2., 1/2., 2/2. }; - double arr2[4] = { 0/3, 1/3., 2/3., 3/3. }; - MEDCouplingCMesh* mesh[2]; - for ( int i = 0; i < 2; ++i ) - { - const double* arr = i ? arr1 : arr2; - const int nb_coord = i ? 3 : 4; - DataArrayDouble* coords = DataArrayDouble::New(); - coords->useArray( arr, /*ownership=*/false, CPP_DEALLOC, nb_coord, 1 ); - - mesh[i] = MEDCouplingCMesh::New(); - mesh[i]->setCoords( coords, coords, coords ); - coords->decrRef(); - } - MEDCouplingNormalizedCartesianMesh<3> targetWrapper(mesh[1]); - MEDCouplingNormalizedCartesianMesh<3> sourceWrapper(mesh[0]); - CPPUNIT_ASSERT_EQUAL( 27,int( sourceWrapper.getNumberOfElements())); - CPPUNIT_ASSERT_EQUAL( 3, int( sourceWrapper.nbCellsAlongAxis(0))); - CPPUNIT_ASSERT_EQUAL( 3, int( sourceWrapper.nbCellsAlongAxis(1))); - CPPUNIT_ASSERT_EQUAL( 3, int( sourceWrapper.nbCellsAlongAxis(2))); - CPPUNIT_ASSERT_THROW( sourceWrapper.nbCellsAlongAxis(3), INTERP_KERNEL::Exception); - - INTERP_KERNEL::InterpolationCC myInterpolator; - std::vector > res; - myInterpolator.interpolateMeshes(sourceWrapper,targetWrapper,res,"P0P0"); - - CPPUNIT_ASSERT_EQUAL(8,int( res.size())); - CPPUNIT_ASSERT_EQUAL(8,int( res[0].size())); - const double precis = 1e-7; - std::set vals; - double sum = 0; - for ( int i = 0; i < (int)res.size(); ++i ) - for ( std::map::iterator s_v = res[i].begin(); s_v != res[i].end(); ++s_v) - { - sum += s_v->second; - double vvv; -#ifdef WIN32 - double vv = s_v->second / precis; - if(vv>=0.0) - { - vvv = floor(vv+0.5); - } - else - { - vvv = ceil(vv-0.5); - } -#else - vvv = round( s_v->second / precis ); -#endif - vals.insert( precis * vvv ); - } - //cout << "tgt: " << i << " src: " << s_v->first << " - w: " << s_v->second << endl; - CPPUNIT_ASSERT_DOUBLES_EQUAL( 1.0, sum, precis ); - - std::set::iterator v = vals.begin(); - CPPUNIT_ASSERT_EQUAL( 4, int( vals.size()) ); - CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.00462963, *v++, precis ); - CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.00925926, *v++, precis ); - CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.01851850, *v++, precis ); - CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.03703700, *v++, precis ); - - mesh[0]->decrRef(); - mesh[1]->decrRef(); -} - -void MEDCouplingBasicsTestInterp::testInterpolationCU1D() -{ - MEDCouplingCMesh* meshC = MEDCouplingCMesh::New(); - DataArrayDouble* coords = DataArrayDouble::New(); - double arr[4] = { -1/3., 1/3., 2/3., 4/3. }; - coords->useArray( arr, /*ownership=*/false, CPP_DEALLOC, 4, 1 ); - meshC->setCoords( coords ); - coords->decrRef(); - - MEDCouplingUMesh * meshU = buildCU1DMesh_U(); - - MEDCouplingNormalizedCartesianMesh<1> sourceWrapper(meshC); - MEDCouplingNormalizedUnstructuredMesh<1,1> targetWrapper(meshU); - INTERP_KERNEL::InterpolationCU myInterpolator; - std::vector > res; - const double precis = 1e-13; - myInterpolator.setPrecision(precis); - myInterpolator.interpolateMeshes(sourceWrapper,targetWrapper,res,"P0P0"); - -// std::cout.precision(18); -// for ( int i = 0; i < (int)res.size(); ++i ) -// for ( std::map::iterator s_v = res[i].begin(); s_v != res[i].end(); ++s_v) -// { -// std::cout << "CPPUNIT_ASSERT_DOUBLES_EQUAL( "<second<<" ,res["<first<<"],precis);"<decrRef(); - meshU->decrRef(); -} - -void MEDCouplingBasicsTestInterp::testInterpolationCU2D() -{ - MEDCouplingCMesh* meshC = MEDCouplingCMesh::New(); - DataArrayDouble* coords = DataArrayDouble::New(); - double arr[4] = { -1/3., 1/3., 2/3., 4/3. }; - coords->useArray( arr, /*ownership=*/false, CPP_DEALLOC, 4, 1 ); - meshC->setCoords( coords, coords ); - coords->decrRef(); - - MEDCouplingUMesh * meshU = buildCU2DMesh_U(); - - MEDCouplingNormalizedCartesianMesh<2> sourceWrapper(meshC); - MEDCouplingNormalizedUnstructuredMesh<2,2> targetWrapper(meshU); - INTERP_KERNEL::InterpolationCU myInterpolator; - std::vector > res; - myInterpolator.setPrecision(1e-12); - myInterpolator.interpolateMeshes(sourceWrapper,targetWrapper,res,"P0P0"); - - const double precis = 1e-7; - double sum = sumAll(res); - CPPUNIT_ASSERT_EQUAL(5,int( res.size())); - CPPUNIT_ASSERT_DOUBLES_EQUAL( 1, sum, precis ); - CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.1111111 ,res[0][0],precis); - CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.0555556 ,res[0][1],precis); - CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.0555556 ,res[0][3],precis); - CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.0277778 ,res[0][4],precis); - CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.0555556 ,res[1][3],precis); - CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.0277778 ,res[1][4],precis); - CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.1111111 ,res[1][6],precis); - CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.0555556 ,res[1][7],precis); - CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.0277778 ,res[2][4],precis); - CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.0555556 ,res[2][5],precis); - CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.0555556 ,res[2][7],precis); - CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.1111111 ,res[2][8],precis); - CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.0416667 ,res[3][1],precis); - CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.0138889 ,res[3][2],precis); - CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.0277778 ,res[3][4],precis); - CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.0416667 ,res[3][5],precis); - CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.0138889 ,res[4][1],precis); - CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.0972222 ,res[4][2],precis); - CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.0138889 ,res[4][5],precis); - - std::vector > resRev; - myInterpolator.interpolateMeshesRev(targetWrapper,sourceWrapper,resRev,"P0P0"); - - CPPUNIT_ASSERT_DOUBLES_EQUAL( res[0][0] ,resRev[0][0],precis); - CPPUNIT_ASSERT_DOUBLES_EQUAL( res[0][1] ,resRev[1][0],precis); - CPPUNIT_ASSERT_DOUBLES_EQUAL( res[3][1] ,resRev[1][3],precis); - CPPUNIT_ASSERT_DOUBLES_EQUAL( res[4][1] ,resRev[1][4],precis); - CPPUNIT_ASSERT_DOUBLES_EQUAL( res[3][2] ,resRev[2][3],precis); - CPPUNIT_ASSERT_DOUBLES_EQUAL( res[4][2] ,resRev[2][4],precis); - CPPUNIT_ASSERT_DOUBLES_EQUAL( res[0][3] ,resRev[3][0],precis); - CPPUNIT_ASSERT_DOUBLES_EQUAL( res[1][3] ,resRev[3][1],precis); - CPPUNIT_ASSERT_DOUBLES_EQUAL( res[0][4] ,resRev[4][0],precis); - CPPUNIT_ASSERT_DOUBLES_EQUAL( res[1][4] ,resRev[4][1],precis); - CPPUNIT_ASSERT_DOUBLES_EQUAL( res[2][4] ,resRev[4][2],precis); - CPPUNIT_ASSERT_DOUBLES_EQUAL( res[3][4] ,resRev[4][3],precis); - CPPUNIT_ASSERT_DOUBLES_EQUAL( res[2][5] ,resRev[5][2],precis); - CPPUNIT_ASSERT_DOUBLES_EQUAL( res[3][5] ,resRev[5][3],precis); - CPPUNIT_ASSERT_DOUBLES_EQUAL( res[4][5] ,resRev[5][4],precis); - CPPUNIT_ASSERT_DOUBLES_EQUAL( res[1][6] ,resRev[6][1],precis); - CPPUNIT_ASSERT_DOUBLES_EQUAL( res[1][7] ,resRev[7][1],precis); - CPPUNIT_ASSERT_DOUBLES_EQUAL( res[2][7] ,resRev[7][2],precis); - CPPUNIT_ASSERT_DOUBLES_EQUAL( res[2][8] ,resRev[8][2],precis); - - meshC->decrRef(); - meshU->decrRef(); -} - -void MEDCouplingBasicsTestInterp::testInterpolationCU3D() -{ - MEDCouplingCMesh* meshC = MEDCouplingCMesh::New(); - DataArrayDouble* coords = DataArrayDouble::New(); - double arr[4] = { -1/3., 1/3., 2/3., 4/3. }; - coords->useArray( arr, /*ownership=*/false, CPP_DEALLOC, 4, 1 ); - meshC->setCoords( coords, coords, coords ); - coords->decrRef(); - - MEDCouplingUMesh * meshU = buildCU3DMesh_U(); - - MEDCouplingNormalizedCartesianMesh<3> sourceWrapper(meshC); - MEDCouplingNormalizedUnstructuredMesh<3,3> targetWrapper(meshU); - INTERP_KERNEL::InterpolationCU myInterpolator; - std::vector > res; - const double precis = 1e-13; - myInterpolator.setPrecision(precis); - myInterpolator.interpolateMeshes(sourceWrapper,targetWrapper,res,"P0P0"); - - double sum = sumAll(res); - CPPUNIT_ASSERT_EQUAL(8,int( res.size())); - CPPUNIT_ASSERT_DOUBLES_EQUAL( 1, sum, precis ); - CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.02700000000000 ,res[0][0],precis); - CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.00299999999999 ,res[1][0],precis); - CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.02999999999999 ,res[1][1],precis); - CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.03000000000000 ,res[1][2],precis); - CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.00300000000000 ,res[2][0],precis); - CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.02999999999999 ,res[2][3],precis); - CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.02999999999999 ,res[2][6],precis); - CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.00033333333333 ,res[3][0],precis); - CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.00333333333333 ,res[3][1],precis); - CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.00333333333333 ,res[3][2],precis); - CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.00333333333333 ,res[3][3],precis); - CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.03333333333333 ,res[3][4],precis); - CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.03333333333333 ,res[3][5],precis); - CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.00333333333333 ,res[3][6],precis); - CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.03333333333333 ,res[3][7],precis); - CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.03333333333333 ,res[3][8],precis); - CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.00299999999999 ,res[4][0],precis); - CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.02999999999999 ,res[4][9],precis); - CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.03000000000000 ,res[4][18],precis); - CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.00033333333333 ,res[5][0],precis); - CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.00333333333333 ,res[5][1],precis); - CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.00333333333333 ,res[5][2],precis); - CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.00333333333333 ,res[5][9],precis); - CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.03333333333333 ,res[5][10],precis); - CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.03333333333333 ,res[5][11],precis); - CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.00333333333333 ,res[5][18],precis); - CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.03333333333333 ,res[5][19],precis); - CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.03333333333333 ,res[5][20],precis); - CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.00033333333333 ,res[6][0],precis); - CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.00333333333333 ,res[6][3],precis); - CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.00333333333333 ,res[6][6],precis); - CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.00333333333333 ,res[6][9],precis); - CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.03333333333333 ,res[6][12],precis); - CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.03333333333333 ,res[6][15],precis); - CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.00333333333333 ,res[6][18],precis); - CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.03333333333333 ,res[6][21],precis); - CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.03333333333333 ,res[6][24],precis); - CPPUNIT_ASSERT_DOUBLES_EQUAL( 3.7037037037e-05 ,res[7][0],precis); - CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.00037037037037 ,res[7][1],precis); - CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.00037037037037 ,res[7][2],precis); - CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.00037037037037 ,res[7][3],precis); - CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.00370370370370 ,res[7][4],precis); - CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.00370370370370 ,res[7][5],precis); - CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.00037037037037 ,res[7][6],precis); - CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.00370370370370 ,res[7][7],precis); - CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.00370370370370 ,res[7][8],precis); - CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.00037037037037 ,res[7][9],precis); - CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.00370370370370 ,res[7][10],precis); - CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.00370370370370 ,res[7][11],precis); - CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.00370370370370 ,res[7][12],precis); - CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.03703703703703 ,res[7][13],precis); - CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.03703703703703 ,res[7][14],precis); - CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.00370370370370 ,res[7][15],precis); - CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.03703703703703 ,res[7][16],precis); - CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.03703703703703 ,res[7][17],precis); - CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.00037037037037 ,res[7][18],precis); - CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.00370370370370 ,res[7][19],precis); - CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.00370370370370 ,res[7][20],precis); - CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.00370370370370 ,res[7][21],precis); - CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.03703703703703 ,res[7][22],precis); - CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.03703703703703 ,res[7][23],precis); - CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.00370370370370 ,res[7][24],precis); - CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.03703703703703 ,res[7][25],precis); - CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.03703703703703 ,res[7][26],precis); - - - meshC->decrRef(); - meshU->decrRef(); -} - -void MEDCouplingBasicsTestInterp::test2DInterpP0IntegralUniform() -{ - MEDCouplingUMesh *targetMesh=build2DTargetMesh_1(); - // - MEDCouplingNormalizedUnstructuredMesh<2,2> targetWrapper(targetMesh); - INTERP_KERNEL::Interpolation2D myInterpolator; - std::vector > res; - CPPUNIT_ASSERT_EQUAL(5,myInterpolator.toIntegralUniform(targetWrapper,res,"P0")); - CPPUNIT_ASSERT_EQUAL(1,(int)res.size()); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.25,res[0][0],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.125,res[0][1],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.125,res[0][2],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.25,res[0][3],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.25,res[0][4],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,sumAll(res),1e-12); - res.clear(); - CPPUNIT_ASSERT_EQUAL(1,myInterpolator.fromIntegralUniform(targetWrapper,res,"P0")); - CPPUNIT_ASSERT_EQUAL(5,(int)res.size()); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.25,res[0][0],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.125,res[1][0],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.125,res[2][0],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.25,res[3][0],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.25,res[4][0],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,sumAll(res),1e-12); - res.clear(); - targetMesh->decrRef(); - // - targetMesh=build2DTargetMeshPerm_1(); - MEDCouplingNormalizedUnstructuredMesh<2,2> targetWrapper2(targetMesh); - INTERP_KERNEL::Interpolation2D myInterpolator2; - CPPUNIT_ASSERT(myInterpolator2.getMeasureAbsStatus()); - CPPUNIT_ASSERT_EQUAL(5,myInterpolator2.toIntegralUniform(targetWrapper2,res,"P0")); - CPPUNIT_ASSERT_EQUAL(1,(int)res.size()); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.25,res[0][0],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.125,res[0][1],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.125,res[0][2],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.25,res[0][3],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.25,res[0][4],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,sumAll(res),1e-12); - res.clear(); - myInterpolator2.setMeasureAbsStatus(false); - CPPUNIT_ASSERT(!myInterpolator2.getMeasureAbsStatus()); - CPPUNIT_ASSERT_EQUAL(5,myInterpolator2.toIntegralUniform(targetWrapper2,res,"P0")); - CPPUNIT_ASSERT_EQUAL(1,(int)res.size()); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.25,res[0][0],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(-0.125,res[0][1],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.125,res[0][2],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.25,res[0][3],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.25,res[0][4],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.75,sumAll(res),1e-12); - targetMesh->decrRef(); -} - -void MEDCouplingBasicsTestInterp::test3DSurfInterpP0IntegralUniform() -{ - MEDCouplingUMesh *targetMesh=build3DSurfTargetMesh_1(); - INTERP_KERNEL::Interpolation3DSurf myInterpolator; - MEDCouplingNormalizedUnstructuredMesh<3,2> targetWrapper(targetMesh); - std::vector > res; - CPPUNIT_ASSERT_EQUAL(5,myInterpolator.toIntegralUniform(targetWrapper,res,"P0")); - CPPUNIT_ASSERT_EQUAL(1,(int)res.size()); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.25*sqrt(2.),res[0][0],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.125*sqrt(2.),res[0][1],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.125*sqrt(2.),res[0][2],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.25*sqrt(2.),res[0][3],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.25*sqrt(2.),res[0][4],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1.*sqrt(2.),sumAll(res),1e-12); - res.clear(); - CPPUNIT_ASSERT_EQUAL(1,myInterpolator.fromIntegralUniform(targetWrapper,res,"P0")); - CPPUNIT_ASSERT_EQUAL(5,(int)res.size()); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.25*sqrt(2.),res[0][0],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.125*sqrt(2.),res[1][0],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.125*sqrt(2.),res[2][0],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.25*sqrt(2.),res[3][0],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.25*sqrt(2.),res[4][0],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1.*sqrt(2.),sumAll(res),1e-12); - targetMesh->decrRef(); -} - -void MEDCouplingBasicsTestInterp::test3DInterpP0IntegralUniform() -{ - MEDCouplingUMesh *targetMesh=build3DTargetMesh_1(); - INTERP_KERNEL::Interpolation3D myInterpolator; - MEDCouplingNormalizedUnstructuredMesh<3,3> targetWrapper(targetMesh); - std::vector > res; - CPPUNIT_ASSERT_EQUAL(8,myInterpolator.toIntegralUniform(targetWrapper,res,"P0")); - CPPUNIT_ASSERT_EQUAL(1,(int)res.size()); - CPPUNIT_ASSERT_DOUBLES_EQUAL(125000.,res[0][0],1e-6); - CPPUNIT_ASSERT_DOUBLES_EQUAL(375000.,res[0][1],1e-6); - CPPUNIT_ASSERT_DOUBLES_EQUAL(375000.,res[0][2],1e-6); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1125000.,res[0][3],1e-6); - CPPUNIT_ASSERT_DOUBLES_EQUAL(375000.,res[0][4],1e-6); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1125000.,res[0][5],1e-6); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1125000.,res[0][6],1e-6); - CPPUNIT_ASSERT_DOUBLES_EQUAL(3375000.,res[0][7],1e-6); - CPPUNIT_ASSERT_DOUBLES_EQUAL(8000000.,sumAll(res),1e-6); - res.clear(); - CPPUNIT_ASSERT_EQUAL(1,myInterpolator.fromIntegralUniform(targetWrapper,res,"P0")); - CPPUNIT_ASSERT_EQUAL(8,(int)res.size()); - CPPUNIT_ASSERT_DOUBLES_EQUAL(125000.,res[0][0],1e-6); - CPPUNIT_ASSERT_DOUBLES_EQUAL(375000.,res[1][0],1e-6); - CPPUNIT_ASSERT_DOUBLES_EQUAL(375000.,res[2][0],1e-6); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1125000.,res[3][0],1e-6); - CPPUNIT_ASSERT_DOUBLES_EQUAL(375000.,res[4][0],1e-6); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1125000.,res[5][0],1e-6); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1125000.,res[6][0],1e-6); - CPPUNIT_ASSERT_DOUBLES_EQUAL(3375000.,res[7][0],1e-6); - CPPUNIT_ASSERT_DOUBLES_EQUAL(8000000.,sumAll(res),1e-6); - res.clear(); - targetMesh->decrRef(); -} - -void MEDCouplingBasicsTestInterp::test2DInterpP1IntegralUniform() -{ - MEDCouplingUMesh *targetMesh=build2DSourceMesh_1(); - // - MEDCouplingNormalizedUnstructuredMesh<2,2> targetWrapper(targetMesh); - INTERP_KERNEL::Interpolation2D myInterpolator; - std::vector > res; - CPPUNIT_ASSERT_EQUAL(4,myInterpolator.toIntegralUniform(targetWrapper,res,"P1")); - CPPUNIT_ASSERT_EQUAL(1,(int)res.size()); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.33333333333333331,res[0][0],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.16666666666666666,res[0][1],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.16666666666666666,res[0][2],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.33333333333333331,res[0][3],1e-12); - res.clear(); - CPPUNIT_ASSERT_EQUAL(1,myInterpolator.fromIntegralUniform(targetWrapper,res,"P1")); - CPPUNIT_ASSERT_EQUAL(4,(int)res.size()); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.33333333333333331,res[0][0],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.16666666666666666,res[1][0],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.16666666666666666,res[2][0],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.33333333333333331,res[3][0],1e-12); - res.clear(); - targetMesh->decrRef(); -} - -void MEDCouplingBasicsTestInterp::test3DInterpP1IntegralUniform() -{ - MEDCouplingUMesh *sourceMesh=build3DSourceMesh_1(); - // - MEDCouplingNormalizedUnstructuredMesh<3,3> targetWrapper(sourceMesh); - INTERP_KERNEL::Interpolation3D myInterpolator; - std::vector > res; - CPPUNIT_ASSERT_EQUAL(9,myInterpolator.toIntegralUniform(targetWrapper,res,"P1")); - CPPUNIT_ASSERT_EQUAL(1,(int)res.size()); - CPPUNIT_ASSERT_DOUBLES_EQUAL(833333.333333333,res[0][0],1e-6); - CPPUNIT_ASSERT_DOUBLES_EQUAL(833333.333333333,res[0][1],1e-6); - CPPUNIT_ASSERT_DOUBLES_EQUAL(500000.,res[0][2],1e-6); - CPPUNIT_ASSERT_DOUBLES_EQUAL(833333.333333333,res[0][3],1e-6); - CPPUNIT_ASSERT_DOUBLES_EQUAL(833333.333333333,res[0][4],1e-6); - CPPUNIT_ASSERT_DOUBLES_EQUAL(500000.,res[0][5],1e-6); - CPPUNIT_ASSERT_DOUBLES_EQUAL(833333.333333333,res[0][6],1e-6); - CPPUNIT_ASSERT_DOUBLES_EQUAL(833333.333333333,res[0][7],1e-6); - CPPUNIT_ASSERT_DOUBLES_EQUAL(2000000.,res[0][8],1e-6); - CPPUNIT_ASSERT_DOUBLES_EQUAL(8000000.,sumAll(res),1e-6); - res.clear(); - CPPUNIT_ASSERT_EQUAL(1,myInterpolator.fromIntegralUniform(targetWrapper,res,"P1")); - CPPUNIT_ASSERT_EQUAL(9,(int)res.size()); - CPPUNIT_ASSERT_DOUBLES_EQUAL(833333.333333333,res[0][0],1e-6); - CPPUNIT_ASSERT_DOUBLES_EQUAL(833333.333333333,res[1][0],1e-6); - CPPUNIT_ASSERT_DOUBLES_EQUAL(500000.,res[2][0],1e-6); - CPPUNIT_ASSERT_DOUBLES_EQUAL(833333.333333333,res[3][0],1e-6); - CPPUNIT_ASSERT_DOUBLES_EQUAL(833333.333333333,res[4][0],1e-6); - CPPUNIT_ASSERT_DOUBLES_EQUAL(500000.,res[5][0],1e-6); - CPPUNIT_ASSERT_DOUBLES_EQUAL(833333.333333333,res[6][0],1e-6); - CPPUNIT_ASSERT_DOUBLES_EQUAL(833333.333333333,res[7][0],1e-6); - CPPUNIT_ASSERT_DOUBLES_EQUAL(2000000.,res[8][0],1e-6); - CPPUNIT_ASSERT_DOUBLES_EQUAL(8000000.,sumAll(res),1e-6); - sourceMesh->decrRef(); -} - -void MEDCouplingBasicsTestInterp::test2DInterpP1P0Bary_1() -{ - MEDCouplingUMesh *sourceMesh=build2DSourceMesh_1(); - MEDCouplingUMesh *targetMesh=build2DTargetMesh_1(); - // - MEDCouplingNormalizedUnstructuredMesh<2,2> sourceWrapper(sourceMesh); - MEDCouplingNormalizedUnstructuredMesh<2,2> targetWrapper(targetMesh); - INTERP_KERNEL::Interpolation2D myInterpolator; - std::vector > res; - INTERP_KERNEL::IntersectionType types[2]={INTERP_KERNEL::Barycentric,INTERP_KERNEL::BarycentricGeo2D}; - for(int i=0;i<2;i++) - { - myInterpolator.setPrecision(1e-12); - myInterpolator.setIntersectionType(types[i]); - myInterpolator.interpolateMeshes(sourceWrapper,targetWrapper,res,"P1P0"); - CPPUNIT_ASSERT_EQUAL(5,(int)res.size()); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.16666666666666669,res[0][0],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.020833333333333343,res[0][1],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.020833333333333343,res[0][2],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.041666666666666664,res[0][3],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.041666666666666664,res[1][0],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.0625,res[1][1],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.020833333333333343,res[1][3],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.020833333333333343,res[2][0],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.0625,res[2][1],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.041666666666666664,res[2][3],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.0625,res[3][0],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.125,res[3][2],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.0625,res[3][3],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.041666666666666664,res[4][0],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.020833333333333343,res[4][1],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.020833333333333343,res[4][2],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.16666666666666666,res[4][3],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,sumAll(res),1e-12); - res.clear(); - } - //clean up - sourceMesh->decrRef(); - targetMesh->decrRef(); -} - -void MEDCouplingBasicsTestInterp::test3DSurfInterpP1P0Bary_1() -{ - MEDCouplingUMesh *sourceMesh=build3DSurfSourceMesh_1(); - MEDCouplingUMesh *targetMesh=build3DSurfTargetMesh_1(); - // - MEDCouplingNormalizedUnstructuredMesh<3,2> sourceWrapper(sourceMesh); - MEDCouplingNormalizedUnstructuredMesh<3,2> targetWrapper(targetMesh); - INTERP_KERNEL::Interpolation3DSurf myInterpolator; - std::vector > res; - INTERP_KERNEL::IntersectionType types[2]={INTERP_KERNEL::Barycentric,INTERP_KERNEL::BarycentricGeo2D}; - for(int i=0;i<2;i++) - { - myInterpolator.setPrecision(1e-12); - myInterpolator.setIntersectionType(types[i]); - myInterpolator.interpolateMeshes(sourceWrapper,targetWrapper,res,"P1P0"); - CPPUNIT_ASSERT_EQUAL(5,(int)res.size()); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.16666666666666669*sqrt(2.),res[0][0],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.020833333333333343*sqrt(2.),res[0][1],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.020833333333333343*sqrt(2.),res[0][2],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.041666666666666664*sqrt(2.),res[0][3],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.041666666666666664*sqrt(2.),res[1][0],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.0625*sqrt(2.),res[1][1],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.020833333333333343*sqrt(2.),res[1][3],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.020833333333333343*sqrt(2.),res[2][0],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.0625*sqrt(2.),res[2][1],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.041666666666666664*sqrt(2.),res[2][3],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.0625*sqrt(2.),res[3][0],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.125*sqrt(2.),res[3][2],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.0625*sqrt(2.),res[3][3],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.041666666666666664*sqrt(2.),res[4][0],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.020833333333333343*sqrt(2.),res[4][1],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.020833333333333343*sqrt(2.),res[4][2],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.16666666666666666*sqrt(2.),res[4][3],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1.*sqrt(2.),sumAll(res),1e-12); - res.clear(); - } - //clean up - sourceMesh->decrRef(); - targetMesh->decrRef(); -} - -#include -void MEDCouplingBasicsTestInterp::test3DInterpP1P0Bary_1() -{ - MEDCouplingUMesh *sourceMesh=build3DSourceMesh_2(); - MEDCouplingUMesh *targetMesh=build3DTargetMesh_2(); - // - MEDCouplingNormalizedUnstructuredMesh<3,3> sourceWrapper(sourceMesh); - MEDCouplingNormalizedUnstructuredMesh<3,3> targetWrapper(targetMesh); - INTERP_KERNEL::Interpolation3D myInterpolator; - std::vector > res; - myInterpolator.setPrecision(1e-12); - myInterpolator.setIntersectionType(INTERP_KERNEL::Barycentric); - myInterpolator.interpolateMeshes(sourceWrapper,targetWrapper,res,"P1P0"); - CPPUNIT_ASSERT_EQUAL(5,(int)res.size()); - - double res3D[5][28]={{104166.66658918398, 885416.666685817763, 135416.666666666541, 36458.3333333335031, 31249.9999999999018, 145833.333333333256, 41666.6666666667516, 124999.999999999971, 177083.333326388849, 0.0, 31249.9999999999636, 0.0, 41666.666620792399, 159722.22229009436, 0.0, 0.0, 41666.6666631944681, 125000, 43499.2283723790752, 164351.851924000395, 36458.3333372396883, 0.0, 0.0, 125000.000001736029, 34722.2221800900952, 13599.5370788455439, 0.0, 167438.27159690368}, - {0.0, 41666.6664479170649, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 125000.000161457952, 0.0, 0.0, 0.0, 0.0, 111111.11112005508, 0.0, 0.0, 291666.666656249959, 41666.6666666666933, 6944.4444415638809, 270833.333520485845, 0.0, 0.0, 124999.999989583303, 41666.6665798612958, 20833.3333186342825, 145833.333354303701, 83333.3333263888198, 27777.7777501651799}, - {0.0, 93750.0000000000728, 125000.000000000058, 0.0, 0.0, 72916.666666666526, 291666.666666666628, 41666.6666666667152, 197916.66666666657, 166666.666666666802, 218750.000000000116, 41666.6666666665697, 0.0, 0.0, 0.0, 0.0, 0.0, 41666.6666666666861, 0.0, 0.0, 0.0, 0.0, 0.0, 41666.6666666666642, 0.0, 0.0, 0.0, 0.0}, - {72916.6666484848247, 82465.2777799315081, 0.0, 0.0, 217447.916666666686, 197916.666666666802, 0.0, 41666.6666666666715, 0.0, 0.0, 0.0, 0.0, 290364.583310396119, 125000.000018181803, 41666.6666666666351, 166666.666666666599, 0.0, 41666.6666666665551, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 27777.7777734705051, 0.0, 0.0, 27777.7778028684952}, - {72916.6666461071727, 172309.027782170655, 70312.5000000000437, 253906.250000000029, 0.0, 0.0, 0.0, 41666.666666666657, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 258246.527775988478, 71180.5555571812583, 253906.250006944378, 41666.6666666666861, 0.0, 41666.6666649305407, 20833.3333186342534, 6944.44445267237552, 0.0, 27777.7777953707919}}; - - double sum = 0; - int i=0; - for(std::vector >::const_iterator iter1=res.begin();iter1!=res.end();iter1++,i++) - { - for(int j=0;j<28;j++) - { - std::map::const_iterator iter2=(*iter1).find(j); - if(iter2!=(*iter1).end()) - { - sum += iter2->second; - CPPUNIT_ASSERT_DOUBLES_EQUAL(res3D[i][j],(*iter2).second,1.e-5); - } - else - { - CPPUNIT_ASSERT_DOUBLES_EQUAL(0.,res3D[i][j],1e-14); - } - } - } - CPPUNIT_ASSERT_DOUBLES_EQUAL(8000000,sum,1.e-5); - //clean up - sourceMesh->decrRef(); - targetMesh->decrRef(); -} - -void MEDCouplingBasicsTestInterp::test3DTo1DInterpP0P0PL_1() -{ - MEDCouplingUMesh *sourceMesh=build3DTargetMesh_1(); - MEDCouplingUMesh *targetMesh=build1DTargetMesh_1(); - // - MEDCouplingNormalizedUnstructuredMesh<3,3> sourceWrapper(sourceMesh); - MEDCouplingNormalizedUnstructuredMesh<3,3> targetWrapper(targetMesh); - INTERP_KERNEL::Interpolation3D myInterpolator; - std::vector > res; - myInterpolator.setPrecision(1e-12); - myInterpolator.setIntersectionType(INTERP_KERNEL::PointLocator); - myInterpolator.interpolateMeshes(sourceWrapper,targetWrapper,res,"P0P0"); - CPPUNIT_ASSERT_EQUAL(8,(int)res.size()); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[0][0],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[1][4],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[2][1],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[3][5],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[4][2],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[5][6],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[6][3],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[7][7],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(8.,sumAll(res),1e-12); - // - sourceMesh->decrRef(); - targetMesh->decrRef(); -} - -void MEDCouplingBasicsTestInterp::test1DInterp_1() -{ - // c1 c0 c2 - pay attention to cell order! - // S: o---o------o---o - // T: o---o------o---o - // n0 n1 n2 n3 - // - // ---+---+------+---+---> X - // 0. 1. 3. 4. - MEDCouplingUMesh *sourceMesh=build1DMesh(0); - MEDCouplingUMesh *targetMesh=build1DMesh(0.5); - // - MEDCouplingNormalizedUnstructuredMesh<1,1> sourceWrapper(sourceMesh); - MEDCouplingNormalizedUnstructuredMesh<1,1> targetWrapper(targetMesh); - INTERP_KERNEL::Interpolation1D myInterpolator; - const double precis = 1e-13; - myInterpolator.setPrecision(precis); - - // P0P0 - std::vector > res; - myInterpolator.interpolateMeshes(sourceWrapper,targetWrapper,res,"P0P0"); - CPPUNIT_ASSERT_EQUAL( 3, int( res.size()) ); - CPPUNIT_ASSERT_DOUBLES_EQUAL( 1.5, res[0][0], precis); - CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.5, res[0][2], precis); - CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.5, res[1][0], precis); - CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.5, res[1][1], precis); - CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.5, res[2][2], precis); - CPPUNIT_ASSERT_DOUBLES_EQUAL( 3.5, sumAll(res), precis); - - // P1P0 - res.clear(); - myInterpolator.interpolateMeshes(sourceWrapper,targetWrapper,res,"P1P0"); - CPPUNIT_ASSERT_EQUAL( 3, int( res.size()) ); - CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.5, res[0][1], precis); - CPPUNIT_ASSERT_DOUBLES_EQUAL( 1.5, res[0][2], precis); - CPPUNIT_ASSERT_DOUBLES_EQUAL( 1.0, res[1][1], precis); - CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.5, res[2][3], precis); - CPPUNIT_ASSERT_DOUBLES_EQUAL( 3.5, sumAll(res), precis); - - // P0P1 - res.clear(); - myInterpolator.interpolateMeshes(sourceWrapper,targetWrapper,res,"P0P1"); - - CPPUNIT_ASSERT_EQUAL( 4, int( res.size()) ); - CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.5, res[0][1], precis); - CPPUNIT_ASSERT_DOUBLES_EQUAL( 1.5, res[1][0], precis); - CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.5, res[2][0], precis); - CPPUNIT_ASSERT_DOUBLES_EQUAL( 1.0, res[2][2], precis); - CPPUNIT_ASSERT_DOUBLES_EQUAL( 3.5, sumAll(res), precis); - - // P1P1 - res.clear(); - myInterpolator.interpolateMeshes(sourceWrapper,targetWrapper,res,"P1P1"); - CPPUNIT_ASSERT_EQUAL( 4, int( res.size()) ); - CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.5, res[0][1], precis); - CPPUNIT_ASSERT_DOUBLES_EQUAL( 1.0, res[1][1], precis); - CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.5, res[1][2], precis); - CPPUNIT_ASSERT_DOUBLES_EQUAL( 1.0, res[2][2], precis); - CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.5, res[2][3], precis); - CPPUNIT_ASSERT_DOUBLES_EQUAL( 3.5, sumAll(res), precis); - - sourceMesh->decrRef(); - targetMesh->decrRef(); -} - -void MEDCouplingBasicsTestInterp::test2DCurveInterpP0P0_1() -{ - // coincident meshes - MEDCouplingUMesh *sourceMesh=build2DCurveMesh(0,0); - MEDCouplingUMesh *targetMesh=build2DCurveMesh(0,0); - // - MEDCouplingNormalizedUnstructuredMesh<2,1> sourceWrapper(sourceMesh); - MEDCouplingNormalizedUnstructuredMesh<2,1> targetWrapper(targetMesh); - INTERP_KERNEL::Interpolation2DCurve myInterpolator; - const double precis = 1e-13; - myInterpolator.setPrecision(precis); - std::vector > res; - myInterpolator.interpolateMeshes(sourceWrapper,targetWrapper,res,"P0P0"); - - CPPUNIT_ASSERT_EQUAL( 2, int( res.size()) ); - CPPUNIT_ASSERT_DOUBLES_EQUAL( sqrt(2.),res[0][0], precis); - CPPUNIT_ASSERT_DOUBLES_EQUAL( 1., res[1][1], precis); - CPPUNIT_ASSERT_DOUBLES_EQUAL( 1.+sqrt(2.), sumAll(res), precis); - - sourceMesh->decrRef(); - targetMesh->decrRef(); -} - -void MEDCouplingBasicsTestInterp::test2DCurveInterpP0P0_2() -{ - // equal meshes shifted one from another along X by 0.5 - MEDCouplingUMesh *sourceMesh=build2DCurveMesh(0.5,0); - MEDCouplingUMesh *targetMesh=build2DCurveMesh(0,0); - // - MEDCouplingNormalizedUnstructuredMesh<2,1> sourceWrapper(sourceMesh); - MEDCouplingNormalizedUnstructuredMesh<2,1> targetWrapper(targetMesh); - INTERP_KERNEL::Interpolation2DCurve myInterpolator; - const double precis = 1e-13; - myInterpolator.setPrecision(precis); - myInterpolator.setMedianPlane(1.);// median line on target - std::vector > res; - myInterpolator.interpolateMeshes(sourceWrapper,targetWrapper,res,"P0P0"); - - double tolInters = myInterpolator.getBoundingBoxAdjustmentAbs() * sqrt(2.); - CPPUNIT_ASSERT_EQUAL( 2, int( res.size()) ); - CPPUNIT_ASSERT_DOUBLES_EQUAL( 0,res[0][0], precis); - CPPUNIT_ASSERT_DOUBLES_EQUAL( tolInters,res[0][1], precis); - CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.5, res[1][1], precis); - CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.5+tolInters, sumAll(res), precis); - - sourceMesh->decrRef(); - targetMesh->decrRef(); -} - -void MEDCouplingBasicsTestInterp::test2DCurveInterpP0P1_1() -{ - // coincident meshes - MEDCouplingUMesh *sourceMesh=build2DCurveMesh(0,0); - MEDCouplingUMesh *targetMesh=build2DCurveMesh(0,0); - // - MEDCouplingNormalizedUnstructuredMesh<2,1> sourceWrapper(sourceMesh); - MEDCouplingNormalizedUnstructuredMesh<2,1> targetWrapper(targetMesh); - INTERP_KERNEL::Interpolation2DCurve myInterpolator; - const double precis = 1e-13; - myInterpolator.setPrecision(precis); - std::vector > res; - myInterpolator.interpolateMeshes(sourceWrapper,targetWrapper,res,"P0P1"); - - const double len1 = 1., len0 = sqrt(2.); - CPPUNIT_ASSERT_EQUAL( 3, int( res.size()) ); - CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.5*len1, res[0][1], precis); - CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.5*len0, res[1][0], precis); - CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.5*len1, res[1][1], precis); - CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.5*len0, res[2][0], precis); - CPPUNIT_ASSERT_DOUBLES_EQUAL( len0+len1, sumAll(res), precis); - - sourceMesh->decrRef(); - targetMesh->decrRef(); -} - -void MEDCouplingBasicsTestInterp::test2DCurveInterpP1P0_1() -{ - // coincident meshes - MEDCouplingUMesh *sourceMesh=build2DCurveMesh(0,0); - MEDCouplingUMesh *targetMesh=build2DCurveMesh(0,0); - // - MEDCouplingNormalizedUnstructuredMesh<2,1> sourceWrapper(sourceMesh); - MEDCouplingNormalizedUnstructuredMesh<2,1> targetWrapper(targetMesh); - INTERP_KERNEL::Interpolation2DCurve myInterpolator; - const double precis = 1e-13; - myInterpolator.setPrecision(precis); - std::vector > res; - myInterpolator.interpolateMeshes(sourceWrapper,targetWrapper,res,"P1P0"); - - const double len1 = 1., len0 = sqrt(2.); - CPPUNIT_ASSERT_EQUAL( 2, int( res.size()) ); - CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.5*len1, res[1][0], precis); - CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.5*len0, res[0][1], precis); - CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.5*len1, res[1][1], precis); - CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.5*len0, res[0][2], precis); - CPPUNIT_ASSERT_DOUBLES_EQUAL( len0+len1, sumAll(res), precis); - - sourceMesh->decrRef(); - targetMesh->decrRef(); -} - -void MEDCouplingBasicsTestInterp::test2DCurveInterpP1P1_1() -{ - // coincident meshes - MEDCouplingUMesh *sourceMesh=build2DCurveMesh(0,0); - MEDCouplingUMesh *targetMesh=build2DCurveMesh(0,0); - // - MEDCouplingNormalizedUnstructuredMesh<2,1> sourceWrapper(sourceMesh); - MEDCouplingNormalizedUnstructuredMesh<2,1> targetWrapper(targetMesh); - INTERP_KERNEL::Interpolation2DCurve myInterpolator; - const double precis = 1e-13; - myInterpolator.setPrecision(precis); - std::vector > res; - myInterpolator.interpolateMeshes(sourceWrapper,targetWrapper,res,"P1P1"); - - const double len1 = 1., len0 = sqrt(2.); - CPPUNIT_ASSERT_EQUAL( 3, int( res.size()) ); - CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.5*len1, res[0][0], precis); - CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.5*(len0+len1), res[1][1], precis); - CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.5*len0, res[2][2], precis); - CPPUNIT_ASSERT_DOUBLES_EQUAL( len0+len1, sumAll(res), precis); - - sourceMesh->decrRef(); - targetMesh->decrRef(); -} - -void MEDCouplingBasicsTestInterp::test2D1DBasicInterpP0P0() -{ - MEDCouplingUMesh *sourceMesh=build2D1DSourceMesh(); - MEDCouplingUMesh *targetMesh=build2D1DTargetMesh(); - - MEDCouplingNormalizedUnstructuredMesh<2,2> sourceWrapper(sourceMesh); - MEDCouplingNormalizedUnstructuredMesh<2,2> targetWrapper(targetMesh); - INTERP_KERNEL::Interpolation2D1D myInterpolator; - myInterpolator.setPrecision(1e-12); - myInterpolator.setIntersectionType(INTERP_KERNEL::Geometric2D); - std::vector > matrix; - myInterpolator.interpolateMeshes(sourceWrapper,targetWrapper,matrix,"P0P0"); - - CPPUNIT_ASSERT_EQUAL(2,(int)matrix.size()); - - CPPUNIT_ASSERT_DOUBLES_EQUAL(3., matrix[0][0],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0., matrix[0][1],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0., matrix[0][2],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(8., matrix[0][3],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0., matrix[0][4],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(5., matrix[0][5],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(6., matrix[0][6],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0., matrix[0][7],1e-12); - - CPPUNIT_ASSERT_DOUBLES_EQUAL(0., matrix[1][0],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0., matrix[1][1],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0., matrix[1][2],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(4., matrix[1][3],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(5., matrix[1][4],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0., matrix[1][5],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(6., matrix[1][6],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(3., matrix[1][7],1e-12); - - INTERP_KERNEL::Interpolation3D2D::DuplicateFacesType duplicateFaces = myInterpolator.retrieveDuplicateFaces(); - CPPUNIT_ASSERT_EQUAL(1,(int)duplicateFaces.size()); - - INTERP_KERNEL::Interpolation3D2D::DuplicateFacesType correctDuplicateFaces; - std::set face6; - face6.insert(0); - face6.insert(1); - correctDuplicateFaces[6] = face6; - - CPPUNIT_ASSERT(correctDuplicateFaces == duplicateFaces); - - //clean up - sourceMesh->decrRef(); - targetMesh->decrRef(); -} - -void MEDCouplingBasicsTestInterp::test2D1DSegQuadInterpP0P0_1() -{ - MEDCouplingUMesh *sourceMesh=build2D1DSegSourceMesh(); - MEDCouplingUMesh *targetMesh=build2D1DQuadTargetMesh(); - test2D1DMeshesIntersection(sourceMesh, targetMesh, 16., 0, 4); -} - -void MEDCouplingBasicsTestInterp::test2D1DSegQuadInterpP0P0_2() -{ - const double shiftX = 3.; - MEDCouplingUMesh *sourceMesh=build2D1DSegSourceMesh(shiftX); - MEDCouplingUMesh *targetMesh=build2D1DQuadTargetMesh(); - test2D1DMeshesIntersection(sourceMesh, targetMesh, 2. * 16., 4, 2 * 4); -} - -void MEDCouplingBasicsTestInterp::test2D1DSegQuadInterpP0P0_3() -{ - const double shiftX = 1.5; - const double inclinationX = 3.; - MEDCouplingUMesh *sourceMesh=build2D1DSegSourceMesh(shiftX, inclinationX); - MEDCouplingUMesh *targetMesh=build2D1DQuadTargetMesh(inclinationX); - test2D1DMeshesIntersection(sourceMesh, targetMesh, 20., 0, 4); -} - -void MEDCouplingBasicsTestInterp::test2D1DSegQuadInterpP0P0_4() -{ - const double shiftX = 3.; - const double inclinationX = 3.; - MEDCouplingUMesh *sourceMesh=build2D1DSegSourceMesh(shiftX, inclinationX); - MEDCouplingUMesh *targetMesh=build2D1DQuadTargetMesh(inclinationX); - test2D1DMeshesIntersection(sourceMesh, targetMesh, 2. * 20., 4, 2 * 4); -} - -void MEDCouplingBasicsTestInterp::test2D1DSegQuadInterpP0P0_5() -{ - const double shiftX = 9.; - const double inclinationX = 3.; - MEDCouplingUMesh *sourceMesh=build2D1DSegSourceMesh(shiftX); - MEDCouplingUMesh *targetMesh=build2D1DQuadTargetMesh(inclinationX); - test2D1DMeshesIntersection(sourceMesh, targetMesh, 12., 0, 3); -} - -void MEDCouplingBasicsTestInterp::test2D1DSegQuadInterpP0P0_6() -{ - const double shiftX = 9.; - const double inclinationX = 3.; - MEDCouplingUMesh *sourceMesh=build2D1DSegSourceMesh(shiftX, inclinationX); - MEDCouplingUMesh *targetMesh=build2D1DQuadTargetMesh(); - test2D1DMeshesIntersection(sourceMesh, targetMesh, 10., 0, 2); -} - -void MEDCouplingBasicsTestInterp::test2D1DSegTriInterpP0P0_1() -{ - MEDCouplingUMesh *sourceMesh=build2D1DSegSourceMesh(); - MEDCouplingUMesh *targetMesh=build2D1DTriTargetMesh(); - test2D1DMeshesIntersection(sourceMesh, targetMesh, 16., 0, 4); -} - -void MEDCouplingBasicsTestInterp::test2D1DSegTriInterpP0P0_2() -{ - const double shiftX = 3.; - MEDCouplingUMesh *sourceMesh=build2D1DSegSourceMesh(shiftX); - MEDCouplingUMesh *targetMesh=build2D1DTriTargetMesh(); - test2D1DMeshesIntersection(sourceMesh, targetMesh, 2. * 16., 4, 2 * 4); -} - -void MEDCouplingBasicsTestInterp::test2D1DSegTriInterpP0P0_3() -{ - const double shiftX = 1.5; - const double inclinationX = 3.; - MEDCouplingUMesh *sourceMesh=build2D1DSegSourceMesh(shiftX, inclinationX); - MEDCouplingUMesh *targetMesh=build2D1DTriTargetMesh(inclinationX); - test2D1DMeshesIntersection(sourceMesh, targetMesh, 20., 0, 8); -} - -void MEDCouplingBasicsTestInterp::test2D1DSegTriInterpP0P0_4() -{ - const double shiftX = 3.; - const double inclinationX = 3.; - MEDCouplingUMesh *sourceMesh=build2D1DSegSourceMesh(shiftX, inclinationX); - MEDCouplingUMesh *targetMesh=build2D1DTriTargetMesh(inclinationX); - test2D1DMeshesIntersection(sourceMesh, targetMesh, 2. * 20., 4, 8); -} - -void MEDCouplingBasicsTestInterp::test2D1DSegTriInterpP0P0_5() -{ - const double shiftX = 9.; - const double inclinationX = 3.; - MEDCouplingUMesh *sourceMesh=build2D1DSegSourceMesh(shiftX); - MEDCouplingUMesh *targetMesh=build2D1DTriTargetMesh(inclinationX); - test2D1DMeshesIntersection(sourceMesh, targetMesh, 12., 0, 6); -} - -void MEDCouplingBasicsTestInterp::test2D1DSegTriInterpP0P0_6() -{ - const double shiftX = 9.; - const double inclinationX = 3.; - MEDCouplingUMesh *sourceMesh=build2D1DSegSourceMesh(shiftX, inclinationX); - MEDCouplingUMesh *targetMesh=build2D1DTriTargetMesh(); - test2D1DMeshesIntersection(sourceMesh, targetMesh, 20., 2, 4); -} - -void MEDCouplingBasicsTestInterp::test3D2DBasicInterpP0P0() -{ - MEDCouplingUMesh *sourceMesh=build3D2DSourceMesh(); - MEDCouplingUMesh *targetMesh=build3D2DTargetMesh(); - - MEDCouplingNormalizedUnstructuredMesh<3,3> sourceWrapper(sourceMesh); - MEDCouplingNormalizedUnstructuredMesh<3,3> targetWrapper(targetMesh); - INTERP_KERNEL::Interpolation3D2D myInterpolator; - myInterpolator.setPrecision(1e-12); - std::vector > matrix; - INTERP_KERNEL::SplittingPolicy sp[] = { INTERP_KERNEL::PLANAR_FACE_5, INTERP_KERNEL::PLANAR_FACE_6, INTERP_KERNEL::GENERAL_24, INTERP_KERNEL::GENERAL_48 }; - for ( size_t i = 0; i < sizeof(sp)/sizeof(sp[0]); ++i ) - { - myInterpolator.setSplittingPolicy( sp[i] ); - matrix.clear(); - myInterpolator.interpolateMeshes(sourceWrapper,targetWrapper,matrix,"P0P0"); - - CPPUNIT_ASSERT_EQUAL(3,(int)matrix.size()); - - CPPUNIT_ASSERT_DOUBLES_EQUAL(0. ,matrix[0][0],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0. ,matrix[0][1],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(40. ,matrix[0][2],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(8. ,matrix[0][3],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(2.5 ,matrix[0][4],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0. ,matrix[0][5],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(32. ,matrix[0][6],1e-12); - - CPPUNIT_ASSERT_DOUBLES_EQUAL(8.*sqrt(3.),matrix[1][0],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0. ,matrix[1][1],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(40. ,matrix[1][2],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(80. ,matrix[1][3],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0. ,matrix[1][4],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(80. ,matrix[1][5],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(80. ,matrix[1][6],1e-12); - - CPPUNIT_ASSERT_DOUBLES_EQUAL(0. ,matrix[2][0],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(32. ,matrix[2][1],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0. ,matrix[2][2],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0. ,matrix[2][3],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(0. ,matrix[2][4],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(80. ,matrix[2][5],1e-12); - CPPUNIT_ASSERT_DOUBLES_EQUAL(112. ,matrix[2][6],1e-12); - - INTERP_KERNEL::Interpolation3D2D::DuplicateFacesType duplicateFaces = myInterpolator.retrieveDuplicateFaces(); - CPPUNIT_ASSERT_EQUAL(3,(int)duplicateFaces.size()); - - INTERP_KERNEL::Interpolation3D2D::DuplicateFacesType correctDuplicateFaces; - std::set face2; - face2.insert(0); - face2.insert(1); - correctDuplicateFaces[2] = face2; - std::set face5; - face5.insert(1); - face5.insert(2); - correctDuplicateFaces[5] = face5; - std::set face6; - face6.insert(0); - face6.insert(1); - face6.insert(2); - correctDuplicateFaces[6] = face6; - - CPPUNIT_ASSERT(correctDuplicateFaces == duplicateFaces); - } - //clean up - sourceMesh->decrRef(); - targetMesh->decrRef(); -} - -void MEDCouplingBasicsTestInterp::test3D2DQuadHexaInterpP0P0_1() -{ - MEDCouplingUMesh *sourceMesh=build3D2DQuadSourceMesh(); - MEDCouplingUMesh *targetMesh=build3D2DHexaTargetMesh(); - test3D2DMeshesIntersection(sourceMesh, targetMesh, 240., 0, 20); -} - -void MEDCouplingBasicsTestInterp::test3D2DQuadHexaInterpP0P0_2() -{ - const double shiftX = 3.; - MEDCouplingUMesh *sourceMesh=build3D2DQuadSourceMesh(shiftX); - MEDCouplingUMesh *targetMesh=build3D2DHexaTargetMesh(); - test3D2DMeshesIntersection(sourceMesh, targetMesh, 2. * 240., 20, 2 * 20); -} - -void MEDCouplingBasicsTestInterp::test3D2DQuadHexaInterpP0P0_3() -{ - const double shiftX = 1.5; - const double inclinationX = 3.; - MEDCouplingUMesh *sourceMesh=build3D2DQuadSourceMesh(shiftX, inclinationX); - MEDCouplingUMesh *targetMesh=build3D2DHexaTargetMesh(inclinationX); - test3D2DMeshesIntersection(sourceMesh, targetMesh, 300., 0, 20); -} - -void MEDCouplingBasicsTestInterp::test3D2DQuadHexaInterpP0P0_4() -{ - const double shiftX = 3.; - const double inclinationX = 3.; - MEDCouplingUMesh *sourceMesh=build3D2DQuadSourceMesh(shiftX, inclinationX); - MEDCouplingUMesh *targetMesh=build3D2DHexaTargetMesh(inclinationX); - test3D2DMeshesIntersection(sourceMesh, targetMesh, 2. * 300., 20, 2 * 20); -} - -void MEDCouplingBasicsTestInterp::test3D2DQuadHexaInterpP0P0_5() -{ - const double shiftX = 9.; - const double inclinationX = 3.; - MEDCouplingUMesh *sourceMesh=build3D2DQuadSourceMesh(shiftX); - MEDCouplingUMesh *targetMesh=build3D2DHexaTargetMesh(inclinationX); - test3D2DMeshesIntersection(sourceMesh, targetMesh, 180., 0, 15); -} - -void MEDCouplingBasicsTestInterp::test3D2DQuadHexaInterpP0P0_6() -{ - const double shiftX = 9.; - const double inclinationX = 3.; - MEDCouplingUMesh *sourceMesh=build3D2DQuadSourceMesh(shiftX, inclinationX); - MEDCouplingUMesh *targetMesh=build3D2DHexaTargetMesh(); - test3D2DMeshesIntersection(sourceMesh, targetMesh, 150., 0, 10); -} - -void MEDCouplingBasicsTestInterp::test3D2DTriHexaInterpP0P0_1() -{ - MEDCouplingUMesh *sourceMesh=build3D2DTriSourceMesh(); - MEDCouplingUMesh *targetMesh=build3D2DHexaTargetMesh(); - test3D2DMeshesIntersection(sourceMesh, targetMesh, 240., 0, 40); -} - -void MEDCouplingBasicsTestInterp::test3D2DTriHexaInterpP0P0_2() -{ - const double shiftX = 3.; - MEDCouplingUMesh *sourceMesh=build3D2DTriSourceMesh(shiftX); - MEDCouplingUMesh *targetMesh=build3D2DHexaTargetMesh(); - test3D2DMeshesIntersection(sourceMesh, targetMesh, 2. * 240., 40, 2 * 40); -} - -void MEDCouplingBasicsTestInterp::test3D2DTriHexaInterpP0P0_3() -{ - const double shiftX = 1.5; - const double inclinationX = 3.; - MEDCouplingUMesh *sourceMesh=build3D2DTriSourceMesh(shiftX, inclinationX); - MEDCouplingUMesh *targetMesh=build3D2DHexaTargetMesh(inclinationX); - test3D2DMeshesIntersection(sourceMesh, targetMesh, 300., 0, 40); -} - -void MEDCouplingBasicsTestInterp::test3D2DTriHexaInterpP0P0_4() -{ - const double shiftX = 3.; - const double inclinationX = 3.; - MEDCouplingUMesh *sourceMesh=build3D2DTriSourceMesh(shiftX, inclinationX); - MEDCouplingUMesh *targetMesh=build3D2DHexaTargetMesh(inclinationX); - test3D2DMeshesIntersection(sourceMesh, targetMesh, 2. * 300., 40, 2 * 40); -} - -void MEDCouplingBasicsTestInterp::test3D2DTriHexaInterpP0P0_5() -{ - const double shiftX = 9.; - const double inclinationX = 3.; - MEDCouplingUMesh *sourceMesh=build3D2DTriSourceMesh(shiftX); - MEDCouplingUMesh *targetMesh=build3D2DHexaTargetMesh(inclinationX); - test3D2DMeshesIntersection(sourceMesh, targetMesh, 180., 0, 30); -} - -void MEDCouplingBasicsTestInterp::test3D2DTriHexaInterpP0P0_6() -{ - const double shiftX = 9.; - const double inclinationX = 3.; - MEDCouplingUMesh *sourceMesh=build3D2DTriSourceMesh(shiftX, inclinationX); - MEDCouplingUMesh *targetMesh=build3D2DHexaTargetMesh(); - test3D2DMeshesIntersection(sourceMesh, targetMesh, 150., 0, 20); -} - -void MEDCouplingBasicsTestInterp::test3D2DQuadTetraInterpP0P0_1() -{ - MEDCouplingUMesh *sourceMesh=build3D2DQuadSourceMesh(); - MEDCouplingUMesh *targetMesh=build3D2DTetraTargetMesh(); - test3D2DMeshesIntersection(sourceMesh, targetMesh, 240., 20, 40); -} - -void MEDCouplingBasicsTestInterp::test3D2DQuadTetraInterpP0P0_2() -{ - const double shiftX = 3.; - MEDCouplingUMesh *sourceMesh=build3D2DQuadSourceMesh(shiftX); - MEDCouplingUMesh *targetMesh=build3D2DTetraTargetMesh(); - test3D2DMeshesIntersection(sourceMesh, targetMesh, 2. * 240., 20, 2 * 40); -} - -void MEDCouplingBasicsTestInterp::test3D2DQuadTetraInterpP0P0_3() -{ - const double shiftX = 1.5; - const double inclinationX = 3.; - MEDCouplingUMesh *sourceMesh=build3D2DQuadSourceMesh(shiftX, inclinationX); - MEDCouplingUMesh *targetMesh=build3D2DTetraTargetMesh(inclinationX); - test3D2DMeshesIntersection(sourceMesh, targetMesh, 300., 0, 100); -} - -void MEDCouplingBasicsTestInterp::test3D2DQuadTetraInterpP0P0_4() -{ - const double shiftX = 3.; - const double inclinationX = 3.; - MEDCouplingUMesh *sourceMesh=build3D2DQuadSourceMesh(shiftX, inclinationX); - MEDCouplingUMesh *targetMesh=build3D2DTetraTargetMesh(inclinationX); - test3D2DMeshesIntersection(sourceMesh, targetMesh, 2. * 300., 20, 2 * 40); -} - -void MEDCouplingBasicsTestInterp::test3D2DQuadTetraInterpP0P0_5() -{ - const double shiftX = 9.; - const double inclinationX = 3.; - MEDCouplingUMesh *sourceMesh=build3D2DQuadSourceMesh(shiftX); - MEDCouplingUMesh *targetMesh=build3D2DTetraTargetMesh(inclinationX); - test3D2DMeshesIntersection(sourceMesh, targetMesh, 180., 0, 45); -} - -void MEDCouplingBasicsTestInterp::test3D2DQuadTetraInterpP0P0_6() -{ - const double shiftX = 9.; - const double inclinationX = 3.; - MEDCouplingUMesh *sourceMesh=build3D2DQuadSourceMesh(shiftX, inclinationX); - MEDCouplingUMesh *targetMesh=build3D2DTetraTargetMesh(); - test3D2DMeshesIntersection(sourceMesh, targetMesh, 150., 0, 30); -} - -void MEDCouplingBasicsTestInterp::test3D2DTriTetraInterpP0P0_1() -{ - MEDCouplingUMesh *sourceMesh=build3D2DTriSourceMesh(); - MEDCouplingUMesh *targetMesh=build3D2DTetraTargetMesh(); - test3D2DMeshesIntersection(sourceMesh, targetMesh, 240., 0, 40); -} - -void MEDCouplingBasicsTestInterp::test3D2DTriTetraInterpP0P0_2() -{ - const double shiftX = 3.; - MEDCouplingUMesh *sourceMesh=build3D2DTriSourceMesh(shiftX); - MEDCouplingUMesh *targetMesh=build3D2DTetraTargetMesh(); - test3D2DMeshesIntersection(sourceMesh, targetMesh, 2. * 240., 40, 40 + 80); -} - -void MEDCouplingBasicsTestInterp::test3D2DTriTetraInterpP0P0_3() -{ - const double shiftX = 1.5; - const double inclinationX = 3.; - MEDCouplingUMesh *sourceMesh=build3D2DTriSourceMesh(shiftX, inclinationX); - MEDCouplingUMesh *targetMesh=build3D2DTetraTargetMesh(inclinationX); - test3D2DMeshesIntersection(sourceMesh, targetMesh, 300., 0); -} - -void MEDCouplingBasicsTestInterp::test3D2DTriTetraInterpP0P0_4() -{ - const double shiftX = 3.; - const double inclinationX = 3.; - MEDCouplingUMesh *sourceMesh=build3D2DTriSourceMesh(shiftX, inclinationX); - MEDCouplingUMesh *targetMesh=build3D2DTetraTargetMesh(inclinationX); - test3D2DMeshesIntersection(sourceMesh, targetMesh, 2. * 300., 40, 40 + 80); -} - -void MEDCouplingBasicsTestInterp::test3D2DTriTetraInterpP0P0_5() -{ - const double shiftX = 9.; - const double inclinationX = 3.; - MEDCouplingUMesh *sourceMesh=build3D2DTriSourceMesh(shiftX); - MEDCouplingUMesh *targetMesh=build3D2DTetraTargetMesh(inclinationX); - test3D2DMeshesIntersection(sourceMesh, targetMesh, 180., 0); -} - -void MEDCouplingBasicsTestInterp::test3D2DTriTetraInterpP0P0_6() -{ - const double shiftX = 9.; - const double inclinationX = 3.; - MEDCouplingUMesh *sourceMesh=build3D2DTriSourceMesh(shiftX, inclinationX); - MEDCouplingUMesh *targetMesh=build3D2DTetraTargetMesh(); - test3D2DMeshesIntersection(sourceMesh, targetMesh, 150., 0); -} - diff --git a/src/MEDCoupling/Test/MEDCouplingBasicsTestInterp.hxx b/src/MEDCoupling/Test/MEDCouplingBasicsTestInterp.hxx deleted file mode 100644 index a10bd00b3..000000000 --- a/src/MEDCoupling/Test/MEDCouplingBasicsTestInterp.hxx +++ /dev/null @@ -1,236 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 -// 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 __MEDCOUPLINGBASICSTESTINTERP_HXX__ -#define __MEDCOUPLINGBASICSTESTINTERP_HXX__ - -#include "MEDCouplingBasicsTest.hxx" - -#include -#include - -namespace ParaMEDMEM -{ - class DataArrayDouble; - class MEDCouplingUMesh; - class MEDCouplingFieldDouble; - class MEDCouplingMultiFields; - - class MEDCouplingBasicsTestInterp : public MEDCouplingBasicsTest - { - CPPUNIT_TEST_SUITE(MEDCouplingBasicsTestInterp); - CPPUNIT_TEST( test2DInterpP0P0_1 ); - CPPUNIT_TEST( test2DInterpP0P0PL_1 ); - CPPUNIT_TEST( test2DInterpP0P0PL_2 ); - CPPUNIT_TEST( test2DInterpP0P0PL_3 ); - CPPUNIT_TEST( test2DInterpP0P0PL_4 ); - CPPUNIT_TEST( test2DInterpP0P1_1 ); - CPPUNIT_TEST( test2DInterpP0P1PL_1 ); - CPPUNIT_TEST( test2DInterpP0P1PL_2 ); - CPPUNIT_TEST( test2DInterpP1P0_1 ); - CPPUNIT_TEST( test2DInterpP1P0PL_1 ); - CPPUNIT_TEST( test2DInterpP1P0PL_2 ); - CPPUNIT_TEST( test2DInterpP1P1_1 ); - CPPUNIT_TEST( test2DInterpP1P1PL_1 ); - CPPUNIT_TEST( test3DSurfInterpP0P0_1 ); - CPPUNIT_TEST( test3DSurfInterpP0P0PL_1 ); - CPPUNIT_TEST( test3DSurfInterpP0P1_1 ); - CPPUNIT_TEST( test3DSurfInterpP0P1PL_1 ); - CPPUNIT_TEST( test3DSurfInterpP1P0_1 ); - CPPUNIT_TEST( test3DSurfInterpP1P0PL_1 ); - CPPUNIT_TEST( test3DSurfInterpP1P1_1 ); - CPPUNIT_TEST( test3DSurfInterpP1P1PL_1 ); - CPPUNIT_TEST( test3DSurfInterpP0P0_2 ); - CPPUNIT_TEST( test3DSurfInterpP0P0_3 ); - - CPPUNIT_TEST( testInterpolationCC ); - CPPUNIT_TEST( testInterpolationCU1D ); - CPPUNIT_TEST( testInterpolationCU2D ); - CPPUNIT_TEST( testInterpolationCU3D ); - - CPPUNIT_TEST( test3DInterpP0P0_1 ); - CPPUNIT_TEST( test3DInterpP0P0PL_1 ); - CPPUNIT_TEST( test3DInterpP0P0PL_2 ); - CPPUNIT_TEST( test3DInterpP0P0PL_3 ); - CPPUNIT_TEST( test3DInterpP0P0PL_4 ); - CPPUNIT_TEST( test3DInterpP0P1_1 ); - CPPUNIT_TEST( test3DInterpP0P1PL_1 ); - CPPUNIT_TEST( test3DInterpP1P0_1 ); - CPPUNIT_TEST( test3DInterpP1P0PL_1 ); - CPPUNIT_TEST( test3DInterpP1P1_1 ); - CPPUNIT_TEST( test3DInterpP1P1PL_1 ); - CPPUNIT_TEST( test3DInterpP0P0Empty ); - CPPUNIT_TEST( test2DInterpP0IntegralUniform ); - CPPUNIT_TEST( test3DSurfInterpP0IntegralUniform ); - CPPUNIT_TEST( test3DInterpP0IntegralUniform ); - CPPUNIT_TEST( test2DInterpP1IntegralUniform ); - CPPUNIT_TEST( test3DInterpP1IntegralUniform ); - CPPUNIT_TEST( test2DInterpP1P0Bary_1 ); - CPPUNIT_TEST( test3DSurfInterpP1P0Bary_1 ); - CPPUNIT_TEST( test3DInterpP1P0Bary_1 ); - CPPUNIT_TEST( test3DTo1DInterpP0P0PL_1 ); - - CPPUNIT_TEST( test2D1DBasicInterpP0P0 ); - CPPUNIT_TEST( test2D1DSegQuadInterpP0P0_1 ); - CPPUNIT_TEST( test2D1DSegQuadInterpP0P0_2 ); - CPPUNIT_TEST( test2D1DSegQuadInterpP0P0_3 ); - CPPUNIT_TEST( test2D1DSegQuadInterpP0P0_4 ); - CPPUNIT_TEST( test2D1DSegQuadInterpP0P0_5 ); - CPPUNIT_TEST( test2D1DSegQuadInterpP0P0_6 ); - CPPUNIT_TEST( test2D1DSegTriInterpP0P0_1 ); - CPPUNIT_TEST( test2D1DSegTriInterpP0P0_2 ); - CPPUNIT_TEST( test2D1DSegTriInterpP0P0_3 ); - CPPUNIT_TEST( test2D1DSegTriInterpP0P0_4 ); - CPPUNIT_TEST( test2D1DSegTriInterpP0P0_5 ); - CPPUNIT_TEST( test2D1DSegTriInterpP0P0_6 ); - CPPUNIT_TEST( test3D2DBasicInterpP0P0 ); - CPPUNIT_TEST( test3D2DQuadHexaInterpP0P0_1 ); - CPPUNIT_TEST( test3D2DQuadHexaInterpP0P0_2 ); - CPPUNIT_TEST( test3D2DQuadHexaInterpP0P0_3 ); - CPPUNIT_TEST( test3D2DQuadHexaInterpP0P0_4 ); - CPPUNIT_TEST( test3D2DQuadHexaInterpP0P0_5 ); - CPPUNIT_TEST( test3D2DQuadHexaInterpP0P0_6 ); - CPPUNIT_TEST( test3D2DTriHexaInterpP0P0_1 ); - CPPUNIT_TEST( test3D2DTriHexaInterpP0P0_2 ); - CPPUNIT_TEST( test3D2DTriHexaInterpP0P0_3 ); - CPPUNIT_TEST( test3D2DTriHexaInterpP0P0_4 ); - CPPUNIT_TEST( test3D2DTriHexaInterpP0P0_5 ); - CPPUNIT_TEST( test3D2DTriHexaInterpP0P0_6 ); - CPPUNIT_TEST( test3D2DQuadTetraInterpP0P0_1 ); - CPPUNIT_TEST( test3D2DQuadTetraInterpP0P0_2 ); - CPPUNIT_TEST( test3D2DQuadTetraInterpP0P0_3 ); - CPPUNIT_TEST( test3D2DQuadTetraInterpP0P0_4 ); - CPPUNIT_TEST( test3D2DQuadTetraInterpP0P0_5 ); - CPPUNIT_TEST( test3D2DQuadTetraInterpP0P0_6 ); - CPPUNIT_TEST( test3D2DTriTetraInterpP0P0_1 ); - CPPUNIT_TEST( test3D2DTriTetraInterpP0P0_2 ); - CPPUNIT_TEST( test3D2DTriTetraInterpP0P0_3 ); - CPPUNIT_TEST( test3D2DTriTetraInterpP0P0_4 ); - CPPUNIT_TEST( test3D2DTriTetraInterpP0P0_5 ); - CPPUNIT_TEST( test3D2DTriTetraInterpP0P0_6 ); - - CPPUNIT_TEST( test1DInterp_1 ); - CPPUNIT_TEST( test2DCurveInterpP0P0_1 ); - CPPUNIT_TEST( test2DCurveInterpP0P0_2 ); - CPPUNIT_TEST( test2DCurveInterpP0P1_1 ); - CPPUNIT_TEST( test2DCurveInterpP1P0_1 ); - CPPUNIT_TEST( test2DCurveInterpP1P1_1 ); - CPPUNIT_TEST_SUITE_END(); - public: - void test2DInterpP0P0_1(); - void test2DInterpP0P0PL_1(); - void test2DInterpP0P0PL_2(); - void test2DInterpP0P0PL_3(); - void test2DInterpP0P0PL_4(); - void test2DInterpP0P1_1(); - void test2DInterpP0P1PL_1(); - void test2DInterpP0P1PL_2(); - void test2DInterpP1P0_1(); - void test2DInterpP1P0PL_1(); - void test2DInterpP1P0PL_2(); - void test2DInterpP1P1_1(); - void test2DInterpP1P1PL_1(); - void test3DSurfInterpP0P0_1(); - void test3DSurfInterpP0P0PL_1(); - void test3DSurfInterpP0P1_1(); - void test3DSurfInterpP0P1PL_1(); - void test3DSurfInterpP1P0_1(); - void test3DSurfInterpP1P0PL_1(); - void test3DSurfInterpP1P1_1(); - void test3DSurfInterpP1P1PL_1(); - void test3DSurfInterpP0P0_2(); - void test3DSurfInterpP0P0_3(); - void test3DInterpP0P0_1(); - void test3DInterpP0P0PL_1(); - void test3DInterpP0P0PL_2(); - void test3DInterpP0P0PL_3(); - void test3DInterpP0P0PL_4(); - void test3DInterpP0P1_1(); - void test3DInterpP0P1PL_1(); - void test3DInterpP1P0_1(); - void test3DInterpP1P0PL_1(); - void test3DInterpP1P1_1(); - void test3DInterpP1P1PL_1(); - - void testInterpolationCC(); - void testInterpolationCU1D(); - void testInterpolationCU2D(); - void testInterpolationCU3D(); - - void test3DInterpP0P0Empty(); - void test2DInterpP0IntegralUniform(); - void test3DSurfInterpP0IntegralUniform(); - void test3DInterpP0IntegralUniform(); - void test2DInterpP1IntegralUniform(); - void test3DInterpP1IntegralUniform(); - void test2DInterpP1P0Bary_1(); - void test3DSurfInterpP1P0Bary_1(); - void test3DInterpP1P0Bary_1(); - void test3DTo1DInterpP0P0PL_1(); - - void test2D1DBasicInterpP0P0(); - void test2D1DSegQuadInterpP0P0_1(); - void test2D1DSegQuadInterpP0P0_2(); - void test2D1DSegQuadInterpP0P0_3(); - void test2D1DSegQuadInterpP0P0_4(); - void test2D1DSegQuadInterpP0P0_5(); - void test2D1DSegQuadInterpP0P0_6(); - void test2D1DSegTriInterpP0P0_1(); - void test2D1DSegTriInterpP0P0_2(); - void test2D1DSegTriInterpP0P0_3(); - void test2D1DSegTriInterpP0P0_4(); - void test2D1DSegTriInterpP0P0_5(); - void test2D1DSegTriInterpP0P0_6(); - void test3D2DBasicInterpP0P0(); - void test3D2DQuadHexaInterpP0P0_1(); - void test3D2DQuadHexaInterpP0P0_2(); - void test3D2DQuadHexaInterpP0P0_3(); - void test3D2DQuadHexaInterpP0P0_4(); - void test3D2DQuadHexaInterpP0P0_5(); - void test3D2DQuadHexaInterpP0P0_6(); - void test3D2DTriHexaInterpP0P0_1(); - void test3D2DTriHexaInterpP0P0_2(); - void test3D2DTriHexaInterpP0P0_3(); - void test3D2DTriHexaInterpP0P0_4(); - void test3D2DTriHexaInterpP0P0_5(); - void test3D2DTriHexaInterpP0P0_6(); - void test3D2DQuadTetraInterpP0P0_1(); - void test3D2DQuadTetraInterpP0P0_2(); - void test3D2DQuadTetraInterpP0P0_3(); - void test3D2DQuadTetraInterpP0P0_4(); - void test3D2DQuadTetraInterpP0P0_5(); - void test3D2DQuadTetraInterpP0P0_6(); - void test3D2DTriTetraInterpP0P0_1(); - void test3D2DTriTetraInterpP0P0_2(); - void test3D2DTriTetraInterpP0P0_3(); - void test3D2DTriTetraInterpP0P0_4(); - void test3D2DTriTetraInterpP0P0_5(); - void test3D2DTriTetraInterpP0P0_6(); - - void test1DInterp_1(); - void test2DCurveInterpP0P0_1(); - void test2DCurveInterpP0P0_2(); - void test2DCurveInterpP0P1_1(); - void test2DCurveInterpP1P0_1(); - void test2DCurveInterpP1P1_1(); - }; -} - -#endif diff --git a/src/MEDCoupling/Test/MEDCouplingExamplesTest.cxx b/src/MEDCoupling/Test/MEDCouplingExamplesTest.cxx deleted file mode 100644 index f749b2f4b..000000000 --- a/src/MEDCoupling/Test/MEDCouplingExamplesTest.cxx +++ /dev/null @@ -1,2579 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 -// 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 "MEDCouplingBasicsTest.hxx" -#include "MEDCouplingUMesh.hxx" -#include "MEDCouplingCMesh.hxx" -#include "MEDCouplingExtrudedMesh.hxx" -#include "MEDCouplingFieldDouble.hxx" -#include "MEDCouplingMemArray.hxx" -#include "MEDCouplingMultiFields.hxx" - - -void CppExample_MEDCouplingFieldDouble_WriteVTK() -{ - using namespace ParaMEDMEM; - //! [CppSnippet_MEDCouplingFieldDouble_WriteVTK_1] - // mesh1 - const double coords[3] = {0.,2.,4.}; - MEDCouplingAutoRefCountObjectPtr coordsArr = DataArrayDouble::New(); - coordsArr->useExternalArrayWithRWAccess( coords, 3, 1 ); - MEDCouplingAutoRefCountObjectPtr mesh1 = MEDCouplingCMesh::New(); - mesh1->setCoords(coordsArr,coordsArr); // mesh becomes a 2D one - - // 3 fields (lying on the same mesh!) - MEDCouplingAutoRefCountObjectPtr field1 = - mesh1->getMeasureField( true ); - MEDCouplingAutoRefCountObjectPtr field2 = - mesh1->buildOrthogonalField(); - MEDCouplingAutoRefCountObjectPtr field3 = - mesh1->fillFromAnalytic( ON_CELLS, 1, "x"); - field2->setName( "Normal" ); // name is necessary! - field3->setName( "Barycenter" ); // name is necessary! - - // WriteVTK - const char fileName[] = "testExample_MEDCouplingFieldDouble_WriteVTK.vtk"; - std::vector fs( 3 ); // field series - fs[0] = field1; - fs[1] = field2; - fs[2] = field3; - MEDCouplingFieldDouble::WriteVTK( fileName, fs ); - //! [CppSnippet_MEDCouplingFieldDouble_WriteVTK_1] - remove(fileName); -} - -void CppExample_MEDCouplingFieldDouble_MaxFields() -{ - using namespace ParaMEDMEM; - //! [CppSnippet_MEDCouplingFieldDouble_MaxFields_1] - const double vals1[4] = {0.,2., 4.,6.}; // for field 1 - const double vals2[4] = {2.,0., 6.,4.}; // for field 2 - const double valsMax[4] = {2.,2., 6.,6.}; // expected max field - const double valsMin[4] = {0.,0., 4.,4.}; // expected min field - // field 1 - MEDCouplingAutoRefCountObjectPtr valsArr1 = DataArrayDouble::New(); - valsArr1->useExternalArrayWithRWAccess( vals1, 2,2 ); // 2 tuples per 2 components - MEDCouplingAutoRefCountObjectPtr field1 = MEDCouplingFieldDouble::New( ON_NODES ); - field1->setArray( valsArr1 ); - // field 2 - MEDCouplingAutoRefCountObjectPtr valsArr2 = DataArrayDouble::New(); - valsArr2->useExternalArrayWithRWAccess( vals2, 2,2 ); // 2 tuples per 2 components - MEDCouplingAutoRefCountObjectPtr field2 = MEDCouplingFieldDouble::New( ON_NODES ); - field2->setArray( valsArr2 ); - // max field - MEDCouplingAutoRefCountObjectPtr fieldMax = MEDCouplingFieldDouble::MaxFields( field1, field2 ); - CPPUNIT_ASSERT( std::equal( valsMax, valsMax+4, fieldMax->getArray()->getConstPointer() )); // fieldMax == valsMax - // min field - MEDCouplingAutoRefCountObjectPtr fieldMin = MEDCouplingFieldDouble::MinFields( field1, field2 ); - CPPUNIT_ASSERT( std::equal( valsMin, valsMin+4, fieldMin->getArray()->getConstPointer() )); // fieldMin == valsMin - //! [CppSnippet_MEDCouplingFieldDouble_MaxFields_1] -} - -void CppExample_MEDCouplingFieldDouble_MergeFields() -{ - using namespace ParaMEDMEM; - //! [CppSnippet_MEDCouplingFieldDouble_MergeFields_1] - // mesh1 - const double coords[3] = {0.,2.,4.}; - MEDCouplingAutoRefCountObjectPtr coordsArr = DataArrayDouble::New(); - coordsArr->useExternalArrayWithRWAccess( coords, 3, 1 ); - MEDCouplingAutoRefCountObjectPtr mesh1 = MEDCouplingCMesh::New(); - mesh1->setCoords(coordsArr); // mesh becomes a 1D - // field1 - MEDCouplingAutoRefCountObjectPtr field1 = - mesh1->fillFromAnalytic( ON_CELLS, 1, "x"); - - // mesh2 and field2 - MEDCouplingAutoRefCountObjectPtr field2 = - field1->cloneWithMesh( true ); - double vec[1] = { 5. }; - (const_cast(field2->getMesh()))->translate(vec); // translate mesh2 - field2->applyFunc("x + 5"); // "translate" field2 - - // concatenate field1 and field2 - MEDCouplingAutoRefCountObjectPtr field3 = - MEDCouplingFieldDouble::MergeFields( field1, field2 ); - std::vector fields( 2 ); - fields[0] = field1; - fields[1] = field2; - MEDCouplingAutoRefCountObjectPtr field4 = - MEDCouplingFieldDouble::MergeFields( fields ); - //! [CppSnippet_MEDCouplingFieldDouble_MergeFields_1] -} - -void CppExample_MEDCouplingFieldDouble_substractInPlaceDM() -{ - using namespace ParaMEDMEM; - //! [CppSnippet_MEDCouplingFieldDouble_substractInPlaceDM_1] - const double coords1[4] = {0.,1.,2.,3.}; - const double coords2[4] = {2.,1.,0.,3.}; // #0 <==> #2 - // mesh 1 - MEDCouplingAutoRefCountObjectPtr mesh1 = MEDCouplingUMesh::New(); - MEDCouplingAutoRefCountObjectPtr coordsArr = DataArrayDouble::New(); - coordsArr->useExternalArrayWithRWAccess( coords1, 4, 1 ); - mesh1->setCoords(coordsArr); - mesh1->setMeshDimension(0); - mesh1->allocateCells(0); - mesh1->finishInsertingCells(); - // mesh 2 - MEDCouplingAutoRefCountObjectPtr mesh2 = - (MEDCouplingUMesh*) mesh1->deepCpy(); - mesh2->getCoords()->useExternalArrayWithRWAccess( coords2, 4, 1 ); - //! [CppSnippet_MEDCouplingFieldDouble_substractInPlaceDM_1] - //! [CppSnippet_MEDCouplingFieldDouble_substractInPlaceDM_2] - MEDCouplingAutoRefCountObjectPtr field1 = - mesh1->fillFromAnalytic( ParaMEDMEM::ON_NODES,1,"x"); // field1 values == coords1 - MEDCouplingAutoRefCountObjectPtr field2 = - mesh2->fillFromAnalytic( ParaMEDMEM::ON_NODES,1,"x"); // field2 values == coords2 - const double levOfCheck = 10; // nodes can be permuted - field1->substractInPlaceDM( field2, levOfCheck, 1e-13, 0 ); // values #0 and #2 must swap - //! [CppSnippet_MEDCouplingFieldDouble_substractInPlaceDM_2] - //! [CppSnippet_MEDCouplingFieldDouble_substractInPlaceDM_3] - field2->applyFunc( 1, 0.0 ); // all field2 values == 0.0 - CPPUNIT_ASSERT( field1->isEqual( field2, 1e-13, 1e-13 )); // field1 == field2 == 0.0 - //! [CppSnippet_MEDCouplingFieldDouble_substractInPlaceDM_3] -} - -void CppExample_MEDCouplingFieldDouble_changeUnderlyingMesh() -{ - using namespace ParaMEDMEM; - //! [CppSnippet_MEDCouplingFieldDouble_changeUnderlyingMesh_1] - const double coords1[4] = {0.,1.,2.,3.}; - const double coords2[4] = {2.,1.,0.,3.}; // #0 <==> #2 - // mesh 1 - MEDCouplingAutoRefCountObjectPtr mesh1 = MEDCouplingUMesh::New(); - MEDCouplingAutoRefCountObjectPtr coordsArr = DataArrayDouble::New(); - coordsArr->useExternalArrayWithRWAccess( coords1, 4, 1 ); - mesh1->setCoords(coordsArr); - mesh1->setMeshDimension(0); - mesh1->allocateCells(0); - mesh1->finishInsertingCells(); - // mesh 2 - MEDCouplingAutoRefCountObjectPtr mesh2 = - (MEDCouplingUMesh*) mesh1->deepCpy(); - mesh2->getCoords()->useExternalArrayWithRWAccess( coords2, 4, 1 ); - //! [CppSnippet_MEDCouplingFieldDouble_changeUnderlyingMesh_1] - //! [CppSnippet_MEDCouplingFieldDouble_changeUnderlyingMesh_2] - MEDCouplingAutoRefCountObjectPtr field = - mesh1->fillFromAnalytic( ParaMEDMEM::ON_NODES,1,"x"); // field values == coords1 - const double levOfCheck = 10; // nodes can be permuted - field->changeUnderlyingMesh( mesh2, levOfCheck, 1e-13, 0 ); // values #0 and #2 must swap - CPPUNIT_ASSERT( std::equal( coords2, coords2+4, field->getArray()->getConstPointer() )); - //! [CppSnippet_MEDCouplingFieldDouble_changeUnderlyingMesh_2] -} - -void CppExample_MEDCouplingFieldDouble_applyFunc_same_nb_comp() -{ - using namespace ParaMEDMEM; - //! [CppSnippet_MEDCouplingFieldDouble_applyFunc_same_nb_comp_1] - const double v[4] = {1.,2., 3.,4.}; - MEDCouplingAutoRefCountObjectPtr array = DataArrayDouble::New(); - array->useExternalArrayWithRWAccess( v, 2, 2 ); // 2 tuples per 2 components - MEDCouplingAutoRefCountObjectPtr field = - MEDCouplingFieldDouble::New( ParaMEDMEM::ON_CELLS ); - field->setArray( array ); - const char func[] = "IVec * v + JVec * w*w + 10"; - field->applyFunc( 2, func ); - CPPUNIT_ASSERT( field->getNumberOfComponents() == 2 ); // 2 components remains - //! [CppSnippet_MEDCouplingFieldDouble_applyFunc_same_nb_comp_1] - //! [CppSnippet_MEDCouplingFieldDouble_applyFunc_same_nb_comp_2] - const double* v2 = field->getArray()->getConstPointer(); - CPPUNIT_ASSERT_DOUBLES_EQUAL( v2[0], 10 + v[0], 13 ); // "10 + IVec * v" - CPPUNIT_ASSERT_DOUBLES_EQUAL( v2[1], 10 + v[1]*v[1], 13 ); // "10 + JVec * v*v" - CPPUNIT_ASSERT_DOUBLES_EQUAL( v2[2], 10 + v[2], 13 ); // "10 + IVec * v" - CPPUNIT_ASSERT_DOUBLES_EQUAL( v2[3], 10 + v[3]*v[3], 13 ); // "10 + JVec * v*v" - //! [CppSnippet_MEDCouplingFieldDouble_applyFunc_same_nb_comp_2] -} - -void CppExample_MEDCouplingFieldDouble_applyFunc3() -{ - using namespace ParaMEDMEM; - //! [CppSnippet_MEDCouplingFieldDouble_applyFunc3_1] - // create a 2D vector field - const double values[4] = {1.,1., 2.,1.}; - MEDCouplingAutoRefCountObjectPtr array = DataArrayDouble::New(); - array->useExternalArrayWithRWAccess( values, 2, 2 ); // 2 tuples per 2 components - MEDCouplingAutoRefCountObjectPtr field = - MEDCouplingFieldDouble::New( ParaMEDMEM::ON_CELLS ); - field->setArray( array ); - // transform the field to a 3D vector field - const char func[] = "IVec * b + JVec * a + KVec * sqrt( a*a + b*b ) + 10"; - const char* varNames[2] = { "a", "b" }; // names used to refer to X and Y components - std::vector varNamesVec( varNames, varNames+2 ); - field->applyFunc3( 3, varNamesVec, func ); // require 3 components - CPPUNIT_ASSERT( field->getNumberOfComponents() == 3 ); // 3 components as required - //! [CppSnippet_MEDCouplingFieldDouble_applyFunc3_1] - //! [CppSnippet_MEDCouplingFieldDouble_applyFunc3_2] - double vec1[3]; // vector #1 - field->getArray()->getTuple( 1, vec1 ); - const double a = values[2], b = values[3]; // initial components of the vector #1 - CPPUNIT_ASSERT_DOUBLES_EQUAL( vec1[0], 10 + b, 13 ); // "10 + IVec * b" - CPPUNIT_ASSERT_DOUBLES_EQUAL( vec1[1], 10 + a, 13 ); // "10 + JVec * a" - CPPUNIT_ASSERT_DOUBLES_EQUAL( vec1[2], 10 + sqrt(a*a+b*b), 13 ); // "10 + KVec * sqrt( a*a + b*b )" - //! [CppSnippet_MEDCouplingFieldDouble_applyFunc3_2] -} - -void CppExample_MEDCouplingFieldDouble_applyFunc2() -{ - using namespace ParaMEDMEM; - //! [CppSnippet_MEDCouplingFieldDouble_applyFunc2_1] - // create a 2D vector field - const double values[4] = {1.,1., 2.,1.}; - MEDCouplingAutoRefCountObjectPtr array = DataArrayDouble::New(); - array->useExternalArrayWithRWAccess( values, 2, 2 ); // 2 tuples per 2 components - array->setInfoOnComponent(0,"a"); // name used to refer to X component within a function - array->setInfoOnComponent(1,"b"); // name used to refer to Y component within a function - MEDCouplingAutoRefCountObjectPtr field = - MEDCouplingFieldDouble::New( ParaMEDMEM::ON_CELLS ); - field->setArray( array ); - // transform the field to a 3D vector field - const char func[] = "IVec * b + JVec * a + KVec * sqrt( a*a + b*b ) + 10"; - field->applyFunc2( 3, func ); // require 3 components - CPPUNIT_ASSERT( field->getNumberOfComponents() == 3 ); // 3 components as required - //! [CppSnippet_MEDCouplingFieldDouble_applyFunc2_1] - //! [CppSnippet_MEDCouplingFieldDouble_applyFunc2_2] - double vec1[3]; // vector #1 - field->getArray()->getTuple( 1, vec1 ); - const double a = values[2], b = values[3]; // initial components of the vector #1 - CPPUNIT_ASSERT_DOUBLES_EQUAL( vec1[0], 10 + b, 13 ); // "10 + IVec * b" - CPPUNIT_ASSERT_DOUBLES_EQUAL( vec1[1], 10 + a, 13 ); // "10 + JVec * a" - CPPUNIT_ASSERT_DOUBLES_EQUAL( vec1[2], 10 + sqrt(a*a+b*b), 13 ); // "10 + KVec * sqrt( a*a + b*b )" - //! [CppSnippet_MEDCouplingFieldDouble_applyFunc2_2] -} - -void CppExample_MEDCouplingFieldDouble_applyFunc() -{ - using namespace ParaMEDMEM; - //! [CppSnippet_MEDCouplingFieldDouble_applyFunc_1] - // create a 2D vector field - const double values[4] = {1.,1., 2.,1.}; - MEDCouplingAutoRefCountObjectPtr array = DataArrayDouble::New(); - array->useExternalArrayWithRWAccess( values, 2, 2 ); // 2 tuples per 2 components - MEDCouplingAutoRefCountObjectPtr field = - MEDCouplingFieldDouble::New( ParaMEDMEM::ON_CELLS ); - field->setArray( array ); - // transform the field to a 3D vector field - const char func[] = "IVec * b + JVec * a + KVec * sqrt( a*a + b*b ) + 10"; - field->applyFunc( 3, func ); // require 3 components - CPPUNIT_ASSERT( field->getNumberOfComponents() == 3 ); // 3 components as required - //! [CppSnippet_MEDCouplingFieldDouble_applyFunc_1] - //! [CppSnippet_MEDCouplingFieldDouble_applyFunc_2] - double vec1[3]; // vector #1 - field->getArray()->getTuple( 1, vec1 ); - const double a = values[2], b = values[3]; // initial components of the vector #1 - CPPUNIT_ASSERT_DOUBLES_EQUAL( vec1[0], 10 + b, 13 ); // "10 + IVec * b" - CPPUNIT_ASSERT_DOUBLES_EQUAL( vec1[1], 10 + a, 13 ); // "10 + JVec * a" - CPPUNIT_ASSERT_DOUBLES_EQUAL( vec1[2], 10 + sqrt(a*a+b*b), 13 ); // "10 + KVec * sqrt( a*a + b*b )" - //! [CppSnippet_MEDCouplingFieldDouble_applyFunc_2] -} - -void CppExample_MEDCouplingFieldDouble_applyFunc_val() -{ - using namespace ParaMEDMEM; - //! [Snippet_MEDCouplingFieldDouble_applyFunc_val_1] - // mesh - const double coords[4] = {0.,2.,4.}; - MEDCouplingAutoRefCountObjectPtr coordsArr = DataArrayDouble::New(); - coordsArr->useExternalArrayWithRWAccess( coords, 3, 1 ); - MEDCouplingAutoRefCountObjectPtr mesh = MEDCouplingCMesh::New(); - mesh->setCoords(coordsArr,coordsArr); // mesh becomes a 2D structured mesh - // field - MEDCouplingAutoRefCountObjectPtr field = - MEDCouplingFieldDouble::New( ParaMEDMEM::ON_CELLS ); - field->setMesh( mesh ); - field->fillFromAnalytic(2,"IVec * x + JVec * y"); // 2 components - //! [Snippet_MEDCouplingFieldDouble_applyFunc_val_1] - //! [Snippet_MEDCouplingFieldDouble_applyFunc_val_2] - const double newValue = 7.; - field->applyFunc( 3, newValue ); // # 3 components are required - CPPUNIT_ASSERT( field->getIJ(1,0) == newValue ); // a value is as expected - CPPUNIT_ASSERT( field->getNumberOfComponents() == 3 ); - CPPUNIT_ASSERT( field->getNumberOfTuples() == mesh->getNumberOfCells() ); - //! [Snippet_MEDCouplingFieldDouble_applyFunc_val_2] -} - -void CppExample_MEDCouplingFieldDouble_fillFromAnalytic3() -{ - using namespace ParaMEDMEM; - //! [CppSnippet_MEDCouplingFieldDouble_fillFromAnalytic3_1] - const double coords[4] = {0.,2.,4.,6.}; // 6. is not used - MEDCouplingAutoRefCountObjectPtr x = DataArrayDouble::New(); - x->useExternalArrayWithRWAccess( coords, 3, 1 ); - MEDCouplingAutoRefCountObjectPtr y = DataArrayDouble::New(); - y->useExternalArrayWithRWAccess( coords, 2, 1 ); - MEDCouplingAutoRefCountObjectPtr mesh=MEDCouplingCMesh::New(); - mesh->setCoords(x,y); - //! [CppSnippet_MEDCouplingFieldDouble_fillFromAnalytic3_1] - //! [CppSnippet_MEDCouplingFieldDouble_fillFromAnalytic3_2] - MEDCouplingAutoRefCountObjectPtr field = - MEDCouplingFieldDouble::New( ParaMEDMEM::ON_CELLS ); - field->setMesh( mesh ); - const char func[] = "IVec * b + JVec * a + KVec * sqrt( a*a + b*b ) + 10"; - const char* varNames[2] = { "a", "b" }; // names used to refer to X and Y coord components - std::vector varNamesVec( varNames, varNames+2 ); - field->fillFromAnalytic3( 3, varNamesVec, func ); - //! [CppSnippet_MEDCouplingFieldDouble_fillFromAnalytic3_2] - //! [CppSnippet_MEDCouplingFieldDouble_fillFromAnalytic3_3] - double val1[3]; // a value (vector) of the cell #1 - CPPUNIT_ASSERT( field->getNumberOfComponents() == 3 ); // 3 components in the field - field->getArray()->getTuple( 1, val1 ); - // - MEDCouplingAutoRefCountObjectPtr bc = - mesh->getBarycenterAndOwner(); // func is applied to barycenters of cells - double bc1[2]; // coordinates of the second point - bc->getTuple( 1, bc1 ); - // - double dist = sqrt( bc1[0]*bc1[0] + bc1[1]*bc1[1] ); // "sqrt( a*a + b*b )" - CPPUNIT_ASSERT_DOUBLES_EQUAL( val1[0], 10 + bc1[1], 13 ); // "10 + IVec * b" - CPPUNIT_ASSERT_DOUBLES_EQUAL( val1[1], 10 + bc1[0], 13 ); // "10 + JVec * a" - CPPUNIT_ASSERT_DOUBLES_EQUAL( val1[2], 10 + dist , 13 ); // "10 + KVec * sqrt( a*a + b*b )" - //! [CppSnippet_MEDCouplingFieldDouble_fillFromAnalytic3_3] -} - -void CppExample_MEDCouplingFieldDouble_fillFromAnalytic2() -{ - using namespace ParaMEDMEM; - //! [CppSnippet_MEDCouplingFieldDouble_fillFromAnalytic2_1] - const double coords[4] = {0.,2.,4.}; - MEDCouplingAutoRefCountObjectPtr x = DataArrayDouble::New(); - x->useExternalArrayWithRWAccess( coords, 3, 1 ); - MEDCouplingAutoRefCountObjectPtr y = DataArrayDouble::New(); - y->useExternalArrayWithRWAccess( coords, 2, 1 ); - x->setInfoOnComponent(0,"a"); // name used to refer to X coordinate within a function - y->setInfoOnComponent(0,"b"); // name used to refer to Y coordinate within a function - MEDCouplingAutoRefCountObjectPtr mesh=MEDCouplingCMesh::New(); - mesh->setCoords(x,y); - //! [CppSnippet_MEDCouplingFieldDouble_fillFromAnalytic2_1] - //! [CppSnippet_MEDCouplingFieldDouble_fillFromAnalytic2_2] - MEDCouplingAutoRefCountObjectPtr field = - MEDCouplingFieldDouble::New( ParaMEDMEM::ON_CELLS ); - field->setMesh( mesh ); - const char func[] = "IVec * b + JVec * a + KVec * sqrt( a*a + b*b ) + 10"; - field->fillFromAnalytic( 3, func ); - //! [CppSnippet_MEDCouplingFieldDouble_fillFromAnalytic2_2] - //! [CppSnippet_MEDCouplingFieldDouble_fillFromAnalytic2_3] - double val1[3]; // a value (vector) of the cell #1 - CPPUNIT_ASSERT( field->getNumberOfComponents() == 3 ); // 3 components in the field - field->getArray()->getTuple( 1, val1 ); - // - MEDCouplingAutoRefCountObjectPtr bc = - mesh->getBarycenterAndOwner(); // func is applied to barycenters of cells - double bc1[2]; // coordinates of the second point - bc->getTuple( 1, bc1 ); - // - double dist = sqrt( bc1[0]*bc1[0] + bc1[1]*bc1[1] ); // "sqrt( a*a + b*b )" - CPPUNIT_ASSERT_DOUBLES_EQUAL( val1[0], 10 + bc1[1], 13 ); // "10 + IVec * b" - CPPUNIT_ASSERT_DOUBLES_EQUAL( val1[1], 10 + bc1[0], 13 ); // "10 + JVec * a" - CPPUNIT_ASSERT_DOUBLES_EQUAL( val1[2], 10 + dist , 13 ); // "10 + KVec * sqrt( a*a + b*b )" - //! [CppSnippet_MEDCouplingFieldDouble_fillFromAnalytic2_3] -} - -void CppExample_MEDCouplingFieldDouble_fillFromAnalytic() -{ - using namespace ParaMEDMEM; - //! [CppSnippet_MEDCouplingFieldDouble_fillFromAnalytic_1] - const double coords[3] = {0.,2.,4}; - MEDCouplingAutoRefCountObjectPtr x = DataArrayDouble::New(); - x->useExternalArrayWithRWAccess( coords, 3, 1 ); - MEDCouplingAutoRefCountObjectPtr y = DataArrayDouble::New(); - y->useExternalArrayWithRWAccess( coords, 2, 1 ); - MEDCouplingAutoRefCountObjectPtr mesh=MEDCouplingCMesh::New(); - mesh->setCoords(x,y); - //! [CppSnippet_MEDCouplingFieldDouble_fillFromAnalytic_1] - //! [CppSnippet_MEDCouplingFieldDouble_fillFromAnalytic_2] - const char func[] = "IVec * b + JVec * a + KVec * sqrt( a*a + b*b ) + 10"; - MEDCouplingAutoRefCountObjectPtr field = - MEDCouplingFieldDouble::New( ParaMEDMEM::ON_CELLS ); - field->setMesh( mesh ); - field->fillFromAnalytic( 3, func ); - //! [CppSnippet_MEDCouplingFieldDouble_fillFromAnalytic_2] - //! [CppSnippet_MEDCouplingFieldDouble_fillFromAnalytic_3] - double val1[3]; // a value (vector) of the cell #1 - CPPUNIT_ASSERT( field->getNumberOfComponents() == 3 ); // 3 components in the field - field->getArray()->getTuple( 1, val1 ); - // - MEDCouplingAutoRefCountObjectPtr bc = - mesh->getBarycenterAndOwner(); // func is applied to barycenters of cells - double bc1[2]; // coordinates of the second point - bc->getTuple( 1, bc1 ); - // - double dist = sqrt( bc1[0]*bc1[0] + bc1[1]*bc1[1] ); // "sqrt( a*a + b*b )" - CPPUNIT_ASSERT_DOUBLES_EQUAL( val1[0], 10 + bc1[1], 13 ); // "10 + IVec * b" - CPPUNIT_ASSERT_DOUBLES_EQUAL( val1[1], 10 + bc1[0], 13 ); // "10 + JVec * a" - CPPUNIT_ASSERT_DOUBLES_EQUAL( val1[2], 10 + dist , 13 ); // "10 + KVec * sqrt( a*a + b*b )" - //! [CppSnippet_MEDCouplingFieldDouble_fillFromAnalytic_3] -} - -//! [Snippet_MEDCouplingFieldDouble_fillFromAnalytic_c_func_0] -bool getNewValue(const double *pos, double *res) -{ - res[0] = pos[0]; - res[1] = pos[1]; - res[2] = sqrt( pos[0]*pos[0] + pos[1]*pos[1] ); - return true; -} -//! [Snippet_MEDCouplingFieldDouble_fillFromAnalytic_c_func_0] - -void CppExample_MEDCouplingFieldDouble_fillFromAnalytic_c_func() -{ - using namespace ParaMEDMEM; - //! [Snippet_MEDCouplingFieldDouble_fillFromAnalytic_c_func_1] - // mesh - const double coords[4] = {0.,2.,4.}; - MEDCouplingAutoRefCountObjectPtr coordsArr = DataArrayDouble::New(); - coordsArr->useExternalArrayWithRWAccess( coords, 3, 1 ); - MEDCouplingAutoRefCountObjectPtr mesh = MEDCouplingCMesh::New(); - mesh->setCoords(coordsArr,coordsArr); // mesh becomes a 2D structured mesh - // field - MEDCouplingAutoRefCountObjectPtr field = - MEDCouplingFieldDouble::New( ParaMEDMEM::ON_CELLS ); - field->setMesh( mesh ); - field->fillFromAnalytic( 3, &getNewValue ); // 3 components are required - CPPUNIT_ASSERT( field->getNumberOfComponents() == 3 ); - CPPUNIT_ASSERT( field->getNumberOfTuples() == mesh->getNumberOfCells() ); - //! [Snippet_MEDCouplingFieldDouble_fillFromAnalytic_c_func_1] -} - -void CppExample_MEDCouplingFieldDouble_applyFunc_c_func() -{ - using namespace ParaMEDMEM; - //! [Snippet_MEDCouplingFieldDouble_applyFunc_c_func_1] - // mesh - const double coords[4] = {0.,2.,4.}; - MEDCouplingAutoRefCountObjectPtr coordsArr = DataArrayDouble::New(); - coordsArr->useExternalArrayWithRWAccess( coords, 3, 1 ); - MEDCouplingAutoRefCountObjectPtr mesh = MEDCouplingCMesh::New(); - mesh->setCoords(coordsArr,coordsArr); // mesh becomes a 2D structured mesh - // field - MEDCouplingAutoRefCountObjectPtr field = - MEDCouplingFieldDouble::New( ParaMEDMEM::ON_CELLS ); - field->setMesh( mesh ); - MEDCouplingAutoRefCountObjectPtr bc = mesh->getBarycenterAndOwner(); - field->setArray( bc ); // 2 components here as the mesh is 2D - //! [Snippet_MEDCouplingFieldDouble_applyFunc_c_func_1] - //! [Snippet_MEDCouplingFieldDouble_applyFunc_c_func_2] - field->applyFunc( 3, &getNewValue ); // 3 components are required - CPPUNIT_ASSERT( field->getNumberOfComponents() == 3 ); - CPPUNIT_ASSERT( field->getNumberOfTuples() == mesh->getNumberOfCells() ); - //! [Snippet_MEDCouplingFieldDouble_applyFunc_c_func_2] -} - -void CppExample_MEDCouplingFieldDouble_getValueOn_time() -{ - using namespace ParaMEDMEM; - //! [CppSnippet_MEDCouplingFieldDouble_getValueOn_time_1] - const double coords[4] = {0.,2.,4.}; - MEDCouplingAutoRefCountObjectPtr coordsArr = DataArrayDouble::New(); - coordsArr->useExternalArrayWithRWAccess( coords, 3, 1 ); - MEDCouplingAutoRefCountObjectPtr mesh = MEDCouplingCMesh::New(); - mesh->setCoords(coordsArr,coordsArr); - //! [CppSnippet_MEDCouplingFieldDouble_getValueOn_time_1] - //! [CppSnippet_MEDCouplingFieldDouble_getValueOn_time_2] - MEDCouplingAutoRefCountObjectPtr field = - MEDCouplingFieldDouble::New( ParaMEDMEM::ON_CELLS, ParaMEDMEM::LINEAR_TIME ); - field->setMesh( mesh ); - field->fillFromAnalytic( 1,"10"); // all values == 10. - MEDCouplingAutoRefCountObjectPtr array2 = - DataArrayDouble::Add( field->getArray(), field->getArray() ); // == 2 * field->getArray() - field->setEndArray( array2 ); // all values == 20. - const double time1 = 1.1, time2 = 22.; - field->setStartTime( time1, 0, 0 ); - field->setEndTime ( time2, 0, 0 ); - //! [CppSnippet_MEDCouplingFieldDouble_getValueOn_time_2] - //! [CppSnippet_MEDCouplingFieldDouble_getValueOn_time_3] - const double pos[2] = { 1., 1. }; // we are in 2D space - double value[1]; // the field is scalar <-> 1 component - field->getValueOn( pos, 0.5*( time1 + time2 ), value ); - CPPUNIT_ASSERT( fabs( value[0] - 0.5*( 10. + 20. )) < 1e-13 ); - //! [CppSnippet_MEDCouplingFieldDouble_getValueOn_time_3] -} - -void CppExample_MEDCouplingFieldDouble_getValueOnMulti() -{ - using namespace ParaMEDMEM; - //! [CppSnippet_MEDCouplingFieldDouble_getValueOnMulti_1] - const double coords[4] = {0.,2.,4.}; - MEDCouplingAutoRefCountObjectPtr coordsArr = DataArrayDouble::New(); - coordsArr->useExternalArrayWithRWAccess( coords, 3, 1 ); - MEDCouplingAutoRefCountObjectPtr mesh = MEDCouplingCMesh::New(); - mesh->setCoords(coordsArr,coordsArr); - MEDCouplingAutoRefCountObjectPtr field = - mesh->fillFromAnalytic( ParaMEDMEM::ON_CELLS,1,"x+y"); - //! [CppSnippet_MEDCouplingFieldDouble_getValueOnMulti_1] - //! [CppSnippet_MEDCouplingFieldDouble_getValueOnMulti_2] - // field values are located at cell barycenters - MEDCouplingAutoRefCountObjectPtr bc = mesh->getBarycenterAndOwner(); - MEDCouplingAutoRefCountObjectPtr valArray = - field->getValueOnMulti( bc->getConstPointer(), bc->getNumberOfTuples() ); - CPPUNIT_ASSERT( valArray->isEqual( * field->getArray(), 1e-13 )); - //! [CppSnippet_MEDCouplingFieldDouble_getValueOnMulti_2] -} - -void CppExample_MEDCouplingFieldDouble_getValueOn() -{ - using namespace ParaMEDMEM; - //! [CppSnippet_MEDCouplingFieldDouble_getValueOn_1] - const double coords[4] = {0.,2.,4.}; - MEDCouplingAutoRefCountObjectPtr coordsArr = DataArrayDouble::New(); - coordsArr->useExternalArrayWithRWAccess( coords, 3, 1 ); - MEDCouplingAutoRefCountObjectPtr mesh = MEDCouplingCMesh::New(); - mesh->setCoords(coordsArr,coordsArr); - MEDCouplingAutoRefCountObjectPtr field = - mesh->fillFromAnalytic( ParaMEDMEM::ON_CELLS,1,"x+y"); - //! [CppSnippet_MEDCouplingFieldDouble_getValueOn_1] - //! [CppSnippet_MEDCouplingFieldDouble_getValueOn_2] - // field values are located at cell barycenters - MEDCouplingAutoRefCountObjectPtr bc = mesh->getBarycenterAndOwner(); - std::vector vals( field->getNumberOfTuples() ); // array to collect values returned by getValueOn() - double cellBC[2]; // we are in 2D space - for ( int i = 0; i < bc->getNumberOfTuples(); ++i ) - { - bc->getTuple( i, cellBC ); - field->getValueOn( cellBC, & vals[i] ); - } - CPPUNIT_ASSERT( std::equal( vals.begin(), vals.end(), field->getArray()->getConstPointer() )); - //! [CppSnippet_MEDCouplingFieldDouble_getValueOn_2] -} - -void CppExample_MEDCouplingFieldDouble_getValueOnPos() -{ - using namespace ParaMEDMEM; - //! [CppSnippet_MEDCouplingFieldDouble_getValueOnPos_1] - const double coords[4] = {0.,2.,4.}; - MEDCouplingAutoRefCountObjectPtr coordsArr = DataArrayDouble::New(); - coordsArr->useExternalArrayWithRWAccess( coords, 3, 1 ); - MEDCouplingAutoRefCountObjectPtr mesh = MEDCouplingCMesh::New(); - mesh->setCoords(coordsArr,coordsArr); - MEDCouplingAutoRefCountObjectPtr field = - mesh->fillFromAnalytic( ParaMEDMEM::ON_CELLS,1,"x+y"); - //! [CppSnippet_MEDCouplingFieldDouble_getValueOnPos_1] - //! [CppSnippet_MEDCouplingFieldDouble_getValueOnPos_2] - double val11[1]; // 1 == field->getNumberOfComponents() - field->getValueOnPos( 1,1,-1, val11 ); - // field values are located at cell barycenters - MEDCouplingAutoRefCountObjectPtr bc = mesh->getBarycenterAndOwner(); - CPPUNIT_ASSERT( val11[0] == bc->getIJ(3,0) + bc->getIJ(3,1) ); - //! [CppSnippet_MEDCouplingFieldDouble_getValueOnPos_2] -} - -void CppExample_MEDCouplingFieldDouble_renumberNodes() -{ - using namespace ParaMEDMEM; - //! [CppSnippet_MEDCouplingFieldDouble_renumberNodes_1] - const double coords[4] = {0.,2.,4.}; - MEDCouplingAutoRefCountObjectPtr coordsArr = DataArrayDouble::New(); - coordsArr->useExternalArrayWithRWAccess( coords, 3, 1 ); - MEDCouplingAutoRefCountObjectPtr cmesh = MEDCouplingCMesh::New(); - cmesh->setCoords(coordsArr,coordsArr); - MEDCouplingAutoRefCountObjectPtr mesh = cmesh->buildUnstructured(); - //! [CppSnippet_MEDCouplingFieldDouble_renumberNodes_1] - //! [CppSnippet_MEDCouplingFieldDouble_renumberNodes_2] - MEDCouplingAutoRefCountObjectPtr field = - mesh->fillFromAnalytic( ParaMEDMEM::ON_NODES,2,"IVec*x+JVec*y"); - const DataArrayDouble* values = field->getArray(); - const DataArrayDouble* nodeCoords = mesh->getCoords(); - CPPUNIT_ASSERT( values->isEqualWithoutConsideringStr( *nodeCoords, 1e-13 )); - //! [CppSnippet_MEDCouplingFieldDouble_renumberNodes_2] - //! [CppSnippet_MEDCouplingFieldDouble_renumberNodes_3] - const int renumber[9] = { 8, 7, 6, 5, 4, 3, 2, 1, 0 }; - field->renumberNodes(renumber,false); - const MEDCouplingMesh* mesh2 = field->getMesh(); // field now refers to another mesh - values = field->getArray(); - nodeCoords = (static_cast(mesh2))->getCoords(); - CPPUNIT_ASSERT( values->isEqualWithoutConsideringStr( *nodeCoords, 1e-13 )); - //! [CppSnippet_MEDCouplingFieldDouble_renumberNodes_3] -} - -void CppExample_MEDCouplingFieldDouble_renumberCells() -{ - using namespace ParaMEDMEM; - //! [CppSnippet_MEDCouplingFieldDouble_renumberCells_1] - const double coords[4] = {0.,2.,4.}; - MEDCouplingAutoRefCountObjectPtr coordsArr = DataArrayDouble::New(); - coordsArr->useExternalArrayWithRWAccess( coords, 3, 1 ); - MEDCouplingAutoRefCountObjectPtr cmesh = MEDCouplingCMesh::New(); - cmesh->setCoords(coordsArr,coordsArr); - MEDCouplingAutoRefCountObjectPtr mesh = cmesh->buildUnstructured(); - //! [CppSnippet_MEDCouplingFieldDouble_renumberCells_1] - //! [CppSnippet_MEDCouplingFieldDouble_renumberCells_2] - MEDCouplingAutoRefCountObjectPtr field = - mesh->fillFromAnalytic( ParaMEDMEM::ON_CELLS,2,"IVec*x+JVec*y"); - const DataArrayDouble* values = field->getArray(); - MEDCouplingAutoRefCountObjectPtr bc = mesh->getBarycenterAndOwner(); - CPPUNIT_ASSERT( values->isEqualWithoutConsideringStr( *bc, 1e-13 )); - //! [CppSnippet_MEDCouplingFieldDouble_renumberCells_2] - //! [CppSnippet_MEDCouplingFieldDouble_renumberCells_3] - const int renumber[4] = { 3, 2, 1, 0 }; - field->renumberCells(renumber,false); - const MEDCouplingMesh* mesh2 = field->getMesh(); // field now refers to another mesh - values = field->getArray(); - bc = mesh2->getBarycenterAndOwner(); - CPPUNIT_ASSERT( values->isEqualWithoutConsideringStr( *bc, 1e-13 )); - //! [CppSnippet_MEDCouplingFieldDouble_renumberCells_3] -} - -void CppExample_MEDCouplingFieldDouble_buildNewTimeReprFromThis() -{ - using namespace ParaMEDMEM; - //! [CppSnippet_MEDCouplingFieldDouble_buildNewTimeReprFromThis_1] - const double coords[4] = {0.,2.,4.}; - MEDCouplingAutoRefCountObjectPtr coordsArr = DataArrayDouble::New(); - coordsArr->useExternalArrayWithRWAccess( coords, 3, 1 ); - MEDCouplingAutoRefCountObjectPtr mesh = MEDCouplingCMesh::New(); - mesh->setCoords(coordsArr,coordsArr); - MEDCouplingAutoRefCountObjectPtr field1 = - mesh->fillFromAnalytic( ParaMEDMEM::ON_NODES,1,"x+y"); - CPPUNIT_ASSERT( field1->getTimeDiscretization() == ParaMEDMEM::ONE_TIME ); - //! [CppSnippet_MEDCouplingFieldDouble_buildNewTimeReprFromThis_1] - //! [CppSnippet_MEDCouplingFieldDouble_buildNewTimeReprFromThis_2] - MEDCouplingAutoRefCountObjectPtr field2 = - field1->buildNewTimeReprFromThis( ParaMEDMEM::NO_TIME, false ); - CPPUNIT_ASSERT( field2->getTimeDiscretization() == ParaMEDMEM::NO_TIME ); - //! [CppSnippet_MEDCouplingFieldDouble_buildNewTimeReprFromThis_2] -} - -void CppExample_MEDCouplingMesh_fillFromAnalytic3() -{ - using namespace ParaMEDMEM; - //! [CppSnippet_MEDCouplingMesh_fillFromAnalytic3_1] - const double coords[4] = {0.,2.,4.,6.}; // 6. is not used - MEDCouplingAutoRefCountObjectPtr x = DataArrayDouble::New(); - x->useExternalArrayWithRWAccess( coords, 3, 1 ); - MEDCouplingAutoRefCountObjectPtr y = DataArrayDouble::New(); - y->useExternalArrayWithRWAccess( coords, 2, 1 ); - MEDCouplingAutoRefCountObjectPtr mesh=MEDCouplingCMesh::New(); - mesh->setCoords(x,y); - //! [CppSnippet_MEDCouplingMesh_fillFromAnalytic3_1] - //! [CppSnippet_MEDCouplingMesh_fillFromAnalytic3_2] - const char func[] = "IVec * b + JVec * a + KVec * sqrt( a*a + b*b ) + 10"; - const char* varNames[2] = { "a", "b" }; // names used to refer to X and Y coord components - std::vector varNamesVec( varNames, varNames+2 ); - MEDCouplingAutoRefCountObjectPtr field = - mesh->fillFromAnalytic3( ParaMEDMEM::ON_CELLS, 3, varNamesVec, func ); - //! [CppSnippet_MEDCouplingMesh_fillFromAnalytic3_2] - //! [CppSnippet_MEDCouplingMesh_fillFromAnalytic3_3] - double val1[3]; // a value (vector) of the cell #1 - CPPUNIT_ASSERT( field->getNumberOfComponents() == 3 ); // 3 components in the field - field->getArray()->getTuple( 1, val1 ); - // - MEDCouplingAutoRefCountObjectPtr bc = - mesh->getBarycenterAndOwner(); // func is applied to barycenters of cells - double bc1[2]; // coordinates of the second point - bc->getTuple( 1, bc1 ); - // - double dist = sqrt( bc1[0]*bc1[0] + bc1[1]*bc1[1] ); // "sqrt( a*a + b*b )" - CPPUNIT_ASSERT_DOUBLES_EQUAL( val1[0], 10 + bc1[1], 13 ); // "10 + IVec * b" - CPPUNIT_ASSERT_DOUBLES_EQUAL( val1[1], 10 + bc1[0], 13 ); // "10 + JVec * a" - CPPUNIT_ASSERT_DOUBLES_EQUAL( val1[2], 10 + dist , 13 ); // "10 + KVec * sqrt( a*a + b*b )" - //! [CppSnippet_MEDCouplingMesh_fillFromAnalytic3_3] -} - -void CppExample_MEDCouplingMesh_fillFromAnalytic2() -{ - using namespace ParaMEDMEM; - //! [CppSnippet_MEDCouplingMesh_fillFromAnalytic2_1] - const double coords[4] = {0.,2.,4.,6.}; // 6. is not used - MEDCouplingAutoRefCountObjectPtr x = DataArrayDouble::New(); - x->useExternalArrayWithRWAccess( coords, 3, 1 ); - MEDCouplingAutoRefCountObjectPtr y = DataArrayDouble::New(); - y->useExternalArrayWithRWAccess( coords, 2, 1 ); - x->setInfoOnComponent(0,"a"); // name used to refer to X coordinate within a function - y->setInfoOnComponent(0,"b"); // name used to refer to Y coordinate within a function - MEDCouplingAutoRefCountObjectPtr mesh=MEDCouplingCMesh::New(); - mesh->setCoords(x,y); - //! [CppSnippet_MEDCouplingMesh_fillFromAnalytic2_1] - //! [CppSnippet_MEDCouplingMesh_fillFromAnalytic2_2] - const char func[] = "IVec * b + JVec * a + KVec * sqrt( a*a + b*b ) + 10"; - MEDCouplingAutoRefCountObjectPtr field = - mesh->fillFromAnalytic2( ParaMEDMEM::ON_CELLS, 3, func ); - //! [CppSnippet_MEDCouplingMesh_fillFromAnalytic2_2] - //! [CppSnippet_MEDCouplingMesh_fillFromAnalytic2_3] - double val1[3]; // a value (vector) of the cell #1 - CPPUNIT_ASSERT( field->getNumberOfComponents() == 3 ); // 3 components in the field - field->getArray()->getTuple( 1, val1 ); - // - MEDCouplingAutoRefCountObjectPtr bc = - mesh->getBarycenterAndOwner(); // func is applied to barycenters of cells - double bc1[2]; // coordinates of the second point - bc->getTuple( 1, bc1 ); - // - double dist = sqrt( bc1[0]*bc1[0] + bc1[1]*bc1[1] ); // "sqrt( a*a + b*b )" - CPPUNIT_ASSERT_DOUBLES_EQUAL( val1[0], 10 + bc1[1], 13 ); // "10 + IVec * b" - CPPUNIT_ASSERT_DOUBLES_EQUAL( val1[1], 10 + bc1[0], 13 ); // "10 + JVec * a" - CPPUNIT_ASSERT_DOUBLES_EQUAL( val1[2], 10 + dist , 13 ); // "10 + KVec * sqrt( a*a + b*b )" - //! [CppSnippet_MEDCouplingMesh_fillFromAnalytic2_3] -} - -void CppExample_MEDCouplingMesh_fillFromAnalytic() -{ - using namespace ParaMEDMEM; - //! [CppSnippet_MEDCouplingMesh_fillFromAnalytic_1] - const double coords[4] = {0.,2.,4.,6.}; // 6. is not used - MEDCouplingAutoRefCountObjectPtr x = DataArrayDouble::New(); - x->useExternalArrayWithRWAccess( coords, 3, 1 ); - MEDCouplingAutoRefCountObjectPtr y = DataArrayDouble::New(); - y->useExternalArrayWithRWAccess( coords, 2, 1 ); - MEDCouplingAutoRefCountObjectPtr mesh=MEDCouplingCMesh::New(); - mesh->setCoords(x,y); - //! [CppSnippet_MEDCouplingMesh_fillFromAnalytic_1] - //! [CppSnippet_MEDCouplingMesh_fillFromAnalytic_2] - const char func[] = "IVec * b + JVec * a + KVec * sqrt( a*a + b*b ) + 10"; - MEDCouplingAutoRefCountObjectPtr field = - mesh->fillFromAnalytic( ParaMEDMEM::ON_CELLS, 3, func ); - //! [CppSnippet_MEDCouplingMesh_fillFromAnalytic_2] - //! [CppSnippet_MEDCouplingMesh_fillFromAnalytic_3] - double val1[3]; // a value (vector) of the cell #1 - CPPUNIT_ASSERT( field->getNumberOfComponents() == 3 ); // 3 components in the field - field->getArray()->getTuple( 1, val1 ); - // - MEDCouplingAutoRefCountObjectPtr bc = - mesh->getBarycenterAndOwner(); // func is applied to barycenters of cells - double bc1[2]; // coordinates of the second point - bc->getTuple( 1, bc1 ); - // - double dist = sqrt( bc1[0]*bc1[0] + bc1[1]*bc1[1] ); // "sqrt( a*a + b*b )" - CPPUNIT_ASSERT_DOUBLES_EQUAL( val1[0], 10 + bc1[1], 13 ); // "10 + IVec * b" - CPPUNIT_ASSERT_DOUBLES_EQUAL( val1[1], 10 + bc1[0], 13 ); // "10 + JVec * a" - CPPUNIT_ASSERT_DOUBLES_EQUAL( val1[2], 10 + dist , 13 ); // "10 + KVec * sqrt( a*a + b*b )" - //! [CppSnippet_MEDCouplingMesh_fillFromAnalytic_3] -} - -void CppExample_MEDCouplingCMesh_getCoordsAt() -{ - using namespace ParaMEDMEM; - //! [CppSnippet_MEDCouplingCMesh_getCoordsAt_1] - const double coords[3] = {1.,2.,4.}; - MEDCouplingAutoRefCountObjectPtr x = DataArrayDouble::New(); - x->useExternalArrayWithRWAccess( coords, 3, 1 ); - MEDCouplingAutoRefCountObjectPtr mesh=MEDCouplingCMesh::New(); - mesh->setCoordsAt(0,x); - const DataArrayDouble* x2=mesh->getCoordsAt(0); - CPPUNIT_ASSERT( x2->isEqual( *x, 1e-13 )); - //! [CppSnippet_MEDCouplingCMesh_getCoordsAt_1] -} - -void CppExample_MEDCouplingUMesh_areCellsIncludedIn() -{ - using namespace ParaMEDMEM; - //! [CppSnippet_MEDCouplingUMesh_areCellsIncludedIn_1] - MEDCouplingAutoRefCountObjectPtr mesh1=MEDCouplingUMesh::New(); - mesh1->setMeshDimension(2); - mesh1->allocateCells(5); - const int conn[18]={0,3,4,1, 1,4,2, 4,5,2, 6,7,4,3, 7,8,5,4}; - mesh1->insertNextCell(INTERP_KERNEL::NORM_QUAD4,4,conn); // #0 - mesh1->insertNextCell(INTERP_KERNEL::NORM_TRI3,3, conn+4); // #1 - mesh1->insertNextCell(INTERP_KERNEL::NORM_TRI3,3, conn+7); // #2 - mesh1->insertNextCell(INTERP_KERNEL::NORM_QUAD4,4,conn+10); // #3 - mesh1->insertNextCell(INTERP_KERNEL::NORM_QUAD4,4,conn+14); // #4 - mesh1->finishInsertingCells(); - MEDCouplingAutoRefCountObjectPtr coordsArr=DataArrayDouble::New(); - coordsArr->alloc(9,2); - const double coords[18]={-0.3,-0.3, 0.2,-0.3, 0.7,-0.3, -0.3,0.2, 0.2,0.2, 0.7,0.2, -0.3,0.7, 0.2,0.7, 0.7,0.7 }; - std::copy(coords,coords+18,coordsArr->getPointer()); - mesh1->setCoords(coordsArr); - //! [CppSnippet_MEDCouplingUMesh_areCellsIncludedIn_1] - //! [CppSnippet_MEDCouplingUMesh_areCellsIncludedIn_2] - const int cells2[3] = { 4,2,0 }; // even cells selected - MEDCouplingAutoRefCountObjectPtr mesh2 = - (MEDCouplingUMesh*) mesh1->buildPartOfMySelf( cells2, cells2+3, true ); - //! [CppSnippet_MEDCouplingUMesh_areCellsIncludedIn_2] - //! [CppSnippet_MEDCouplingUMesh_areCellsIncludedIn_3] - int compType = 0; // the strongest policy - DataArrayInt *corr2to1, *corr1to2; - // a larger mesh1 includes a smaller mesh2 - CPPUNIT_ASSERT( mesh1->areCellsIncludedIn( mesh2, compType, corr2to1 )); - CPPUNIT_ASSERT( std::equal( cells2, cells2+3, corr2to1->getConstPointer() )); - //! [CppSnippet_MEDCouplingUMesh_areCellsIncludedIn_3] - //! [CppSnippet_MEDCouplingUMesh_areCellsIncludedIn_4] - // the smaller mesh2 does NOT include the larger mesh1 - CPPUNIT_ASSERT( ! mesh2->areCellsIncludedIn( mesh1, compType, corr1to2 )); - const int corr1to2Expected[5] = {2, 3, 1, 4, 0}; - CPPUNIT_ASSERT(std::equal( corr1to2Expected, corr1to2Expected+5, corr1to2->getConstPointer() )); - //! [CppSnippet_MEDCouplingUMesh_areCellsIncludedIn_4] - corr2to1->decrRef(); - corr1to2->decrRef(); -} - -void CppExample_MEDCouplingUMesh_findAndCorrectBadOriented3DExtrudedCells() -{ - using namespace ParaMEDMEM; - //! [CppSnippet_MEDCouplingUMesh_findAndCorrectBadOriented3DExtrudedCells_1] - // 2D coordinates of 5 base nodes - const double coords[5*2]={-0.3,-0.3, 0.2,-0.3, 0.7,-0.3, -0.3,0.2, 0.2,0.2 }; - MEDCouplingAutoRefCountObjectPtr coordsArr=DataArrayDouble::New(); - coordsArr->useExternalArrayWithRWAccess( coords, 5, 2 ); - // coordinates of 5 top nodes - MEDCouplingAutoRefCountObjectPtr coordsArr2 = coordsArr->deepCpy(); - // 3D coordinates of base + top nodes - coordsArr = coordsArr-> changeNbOfComponents( 3, 0 ); - coordsArr2 = coordsArr2->changeNbOfComponents( 3, 1 ); - coordsArr = DataArrayDouble::Aggregate( coordsArr, coordsArr2 ); - // mesh - MEDCouplingAutoRefCountObjectPtr mesh=MEDCouplingUMesh::New(); - mesh->setCoords(coordsArr); - mesh->setMeshDimension(3); - mesh->allocateCells(2); - // connectivity of reversed HEXA8 and PENTA6 - const int conn[8+6]={0,1,4,3, 5,6,9,8, 1,2,4, 6,7,9}; - mesh->insertNextCell(INTERP_KERNEL::NORM_HEXA8, 8,conn+0); - mesh->insertNextCell(INTERP_KERNEL::NORM_PENTA6,6,conn+8); - mesh->finishInsertingCells(); - //! [CppSnippet_MEDCouplingUMesh_findAndCorrectBadOriented3DExtrudedCells_1] - //! [CppSnippet_MEDCouplingUMesh_findAndCorrectBadOriented3DExtrudedCells_2] - MEDCouplingAutoRefCountObjectPtr fixedCells = - mesh->findAndCorrectBadOriented3DExtrudedCells(); - CPPUNIT_ASSERT( fixedCells->getNumberOfTuples() == 2 ); // 2 cells fixed - fixedCells = mesh->findAndCorrectBadOriented3DExtrudedCells(); - CPPUNIT_ASSERT( fixedCells->getNumberOfTuples() == 0 ); // no bad cells - //! [CppSnippet_MEDCouplingUMesh_findAndCorrectBadOriented3DExtrudedCells_2] -} - -void CppExample_MEDCouplingUMesh_arePolyhedronsNotCorrectlyOriented() -{ - using namespace ParaMEDMEM; - //! [CppSnippet_MEDCouplingUMesh_arePolyhedronsNotCorrectlyOriented_1] - // 2D coordinates of 5 base nodes - const double coords[5*2]={-0.3,-0.3, 0.2,-0.3, 0.7,-0.3, -0.3,0.2, 0.2,0.2 }; - MEDCouplingAutoRefCountObjectPtr coordsArr=DataArrayDouble::New(); - coordsArr->useExternalArrayWithRWAccess( coords, 5, 2 ); - // coordinates of 5 top nodes - MEDCouplingAutoRefCountObjectPtr coordsArr2 = coordsArr->deepCpy(); - // 3D coordinates of base + top nodes - coordsArr = coordsArr-> changeNbOfComponents( 3, 0 ); - coordsArr2 = coordsArr2->changeNbOfComponents( 3, 1 ); - coordsArr = DataArrayDouble::Aggregate( coordsArr, coordsArr2 ); - // mesh - MEDCouplingAutoRefCountObjectPtr mesh=MEDCouplingUMesh::New(); - mesh->setCoords(coordsArr); - mesh->setMeshDimension(3); - mesh->allocateCells(2); - // connectivity of a HEXA8 + a reversed PENTA6 - const int conn[8+6]={0,3,4,1, 5,8,9,6, 1,2,4, 6,7,9}; - mesh->insertNextCell(INTERP_KERNEL::NORM_POLYHED,8,conn); // "extruded" polyhedron - mesh->insertNextCell(INTERP_KERNEL::NORM_POLYHED,6,conn+8); - mesh->finishInsertingCells(); - // fix connectivity of NORM_POLYHED's - mesh->convertExtrudedPolyhedra(); - //! [CppSnippet_MEDCouplingUMesh_arePolyhedronsNotCorrectlyOriented_1] - //! [CppSnippet_MEDCouplingUMesh_arePolyhedronsNotCorrectlyOriented_2] - std::vector badCellIds; - mesh->arePolyhedronsNotCorrectlyOriented( badCellIds ); - CPPUNIT_ASSERT( badCellIds.size() == 1 ); // one polyhedron is KO - // fix invalid rolyherdons - mesh->orientCorrectlyPolyhedrons(); - // re-check orientation - badCellIds.clear(); // as badCellIds is not cleared by arePolyhedronsNotCorrectlyOriented() - mesh->arePolyhedronsNotCorrectlyOriented( badCellIds ); - CPPUNIT_ASSERT( badCellIds.size() == 0 ); // connectivity is OK - //! [CppSnippet_MEDCouplingUMesh_arePolyhedronsNotCorrectlyOriented_2] -} - -void CppExample_MEDCouplingUMesh_are2DCellsNotCorrectlyOriented() -{ - using namespace ParaMEDMEM; - //! [CppSnippet_MEDCouplingUMesh_are2DCellsNotCorrectlyOriented_1] - MEDCouplingAutoRefCountObjectPtr mesh=MEDCouplingUMesh::New(); - mesh->setMeshDimension(2); - mesh->allocateCells(5); - const int conn[18]={0,3,4,1, 1,2,4, 4,5,2, 6,7,4,3, 7,8,5,4}; - mesh->insertNextCell(INTERP_KERNEL::NORM_QUAD4,4,conn); // 0 - mesh->insertNextCell(INTERP_KERNEL::NORM_TRI3,3, conn+4); // 1 - mesh->insertNextCell(INTERP_KERNEL::NORM_TRI3,3, conn+7); // 2 - mesh->insertNextCell(INTERP_KERNEL::NORM_QUAD4,4,conn+10); // 3 - mesh->insertNextCell(INTERP_KERNEL::NORM_QUAD4,4,conn+14); // 4 - mesh->finishInsertingCells(); - MEDCouplingAutoRefCountObjectPtr coordsArr=DataArrayDouble::New(); - coordsArr->alloc(9,2); - const double coords[18]={-0.3,-0.3, 0.2,-0.3, 0.7,-0.3, -0.3,0.2, 0.2,0.2, 0.7,0.2, -0.3,0.7, 0.2,0.7, 0.7,0.7 }; - std::copy(coords,coords+18,coordsArr->getPointer()); - mesh->setCoords(coordsArr); - mesh->changeSpaceDimension(3); - //! [CppSnippet_MEDCouplingUMesh_are2DCellsNotCorrectlyOriented_1] - //! [CppSnippet_MEDCouplingUMesh_are2DCellsNotCorrectlyOriented_2] - const double vec[3] = {0.,0.,-1.}; - std::vector badCellIds; - mesh->are2DCellsNotCorrectlyOriented( vec, false, badCellIds ); - CPPUNIT_ASSERT( badCellIds.size() == 1 ); // one cell is reversed - // fix orientation - mesh->orientCorrectly2DCells( vec, false ); - // re-check orientation - badCellIds.clear(); // as badCellIds is not cleared by are2DCellsNotCorrectlyOriented() - mesh->are2DCellsNotCorrectlyOriented( vec, false, badCellIds ); - CPPUNIT_ASSERT( badCellIds.size() == 0 ); // the orientation is OK - //! [CppSnippet_MEDCouplingUMesh_are2DCellsNotCorrectlyOriented_2] -} - -void CppExample_MEDCouplingUMesh_getCellsContainingPoints() -{ - using namespace ParaMEDMEM; - //! [CppSnippet_MEDCouplingUMesh_getCellsContainingPoints_1] - MEDCouplingAutoRefCountObjectPtr mesh=MEDCouplingUMesh::New(); - mesh->setMeshDimension(2); - mesh->allocateCells(5); - const int conn[18]={0,3,4,1, 1,4,2, 4,5,2, 6,7,4,3, 7,8,5,4}; - mesh->insertNextCell(INTERP_KERNEL::NORM_QUAD4,4,conn); - mesh->insertNextCell(INTERP_KERNEL::NORM_TRI3,3, conn+4); - mesh->insertNextCell(INTERP_KERNEL::NORM_TRI3,3, conn+7); - mesh->insertNextCell(INTERP_KERNEL::NORM_QUAD4,4,conn+10); - mesh->insertNextCell(INTERP_KERNEL::NORM_QUAD4,4,conn+14); - mesh->finishInsertingCells(); - MEDCouplingAutoRefCountObjectPtr coordsArr=DataArrayDouble::New(); - coordsArr->alloc(9,2); - const double coords[18]={-0.3,-0.3, 0.2,-0.3, 0.7,-0.3, -0.3,0.2, 0.2,0.2, 0.7,0.2, -0.3,0.7, 0.2,0.7, 0.7,0.7 }; - std::copy(coords,coords+18,coordsArr->getPointer()); - mesh->setCoords(coordsArr); - //! [CppSnippet_MEDCouplingUMesh_getCellsContainingPoints_1] - //! [CppSnippet_MEDCouplingUMesh_getCellsContainingPoints_2] - const double pos[3*2] = { 10., 10, // point out of the mesh - 0.3, 0.3, // point located somewhere inside the mesh - coords[2], coords[3]}; // point at the node #1 - const double eps = 1e-4; // ball radius - MEDCouplingAutoRefCountObjectPtr cells, cellsIndex; - mesh->getCellsContainingPoints( pos, 3, eps, cells, cellsIndex ); - const int cellsExpected[3]={4, 0, 1}; - const int cellsIndexExpected[4]={0, 0, 1, 3}; - CPPUNIT_ASSERT(std::equal( cellsExpected, cellsExpected+3, cells->begin())); - CPPUNIT_ASSERT(std::equal( cellsIndexExpected, cellsIndexExpected+4, cellsIndex->begin())); - //! [CppSnippet_MEDCouplingUMesh_getCellsContainingPoints_2] -} - -void CppExample_MEDCouplingUMesh_getCellsContainingPoint() -{ - using namespace ParaMEDMEM; - //! [CppSnippet_MEDCouplingUMesh_getCellsContainingPoint_1] - MEDCouplingAutoRefCountObjectPtr mesh=MEDCouplingUMesh::New(); - mesh->setMeshDimension(2); - mesh->allocateCells(5); - const int conn[18]={0,3,4,1, 1,4,2, 4,5,2, 6,7,4,3, 7,8,5,4}; - mesh->insertNextCell(INTERP_KERNEL::NORM_QUAD4,4,conn); // 0 - mesh->insertNextCell(INTERP_KERNEL::NORM_TRI3,3, conn+4); // 1 - mesh->insertNextCell(INTERP_KERNEL::NORM_TRI3,3, conn+7); // 2 - mesh->insertNextCell(INTERP_KERNEL::NORM_QUAD4,4,conn+10); // 3 - mesh->insertNextCell(INTERP_KERNEL::NORM_QUAD4,4,conn+14); // 4 - mesh->finishInsertingCells(); - MEDCouplingAutoRefCountObjectPtr coordsArr=DataArrayDouble::New(); - coordsArr->alloc(9,2); - const double coords[18]={-0.3,-0.3, 0.2,-0.3, 0.7,-0.3, -0.3,0.2, 0.2,0.2, 0.7,0.2, -0.3,0.7, 0.2,0.7, 0.7,0.7 }; - std::copy(coords,coords+18,coordsArr->getPointer()); - mesh->setCoords(coordsArr); - //! [CppSnippet_MEDCouplingUMesh_getCellsContainingPoint_1] - //! [CppSnippet_MEDCouplingUMesh_getCellsContainingPoint_2] - const double* coords4 = coords + 4*2; // coordinates of the node #4 - const double eps = 1e-4; // ball radius - const double pos[2] = { coords4[0] + eps, coords4[1] - eps }; // ball center - std::vector cellIds; - mesh->getCellsContainingPoint( pos, eps, cellIds ); - CPPUNIT_ASSERT ( (int)cellIds.size() == mesh->getNumberOfCells() ); - //! [CppSnippet_MEDCouplingUMesh_getCellsContainingPoint_2] -} - -void CppExample_MEDCouplingUMesh_buildPartOrthogonalField() -{ - using namespace ParaMEDMEM; - //! [CppSnippet_MEDCouplingUMesh_buildPartOrthogonalField_1] - MEDCouplingAutoRefCountObjectPtr mesh=MEDCouplingUMesh::New(); - mesh->setMeshDimension(2); - mesh->allocateCells(5); - const int conn[18]={0,3,4,1, 1,4,2, 4,5,2, 6,7,4,3, 7,8,5,4}; - mesh->insertNextCell(INTERP_KERNEL::NORM_QUAD4,4,conn); // 0 - mesh->insertNextCell(INTERP_KERNEL::NORM_TRI3,3, conn+4); // 1 - mesh->insertNextCell(INTERP_KERNEL::NORM_TRI3,3, conn+7); // 2 - mesh->insertNextCell(INTERP_KERNEL::NORM_QUAD4,4,conn+10); // 3 - mesh->insertNextCell(INTERP_KERNEL::NORM_QUAD4,4,conn+14); // 4 - mesh->finishInsertingCells(); - MEDCouplingAutoRefCountObjectPtr coordsArr=DataArrayDouble::New(); - coordsArr->alloc(9,2); - const double coords[18]={-0.3,-0.3, 0.2,-0.3, 0.7,-0.3, -0.3,0.2, 0.2,0.2, 0.7,0.2, -0.3,0.7, 0.2,0.7, 0.7,0.7 }; - std::copy(coords,coords+18,coordsArr->getPointer()); - mesh->setCoords(coordsArr); - //! [CppSnippet_MEDCouplingUMesh_buildPartOrthogonalField_1] - //! [CppSnippet_MEDCouplingUMesh_buildPartOrthogonalField_2] - const int part[4] = {1,2,3,4}; // cell #0 is omitted - MEDCouplingAutoRefCountObjectPtr vecField= - mesh->buildPartOrthogonalField( part, part+4 ); - CPPUNIT_ASSERT ( vecField->getArray()->getNumberOfTuples() == 4 ); - CPPUNIT_ASSERT ( vecField->getArray()->getNumberOfComponents() == 3 ); - //! [CppSnippet_MEDCouplingUMesh_buildPartOrthogonalField_2] -} - -void CppExample_MEDCouplingUMesh_getPartMeasureField() -{ - using namespace ParaMEDMEM; - //! [CppSnippet_MEDCouplingUMesh_getPartMeasureField_1] - MEDCouplingAutoRefCountObjectPtr mesh=MEDCouplingUMesh::New(); - mesh->setMeshDimension(2); - mesh->allocateCells(5); - const int conn[18]={0,3,4,1, 1,2,4, 4,5,2, 6,7,4,3, 7,8,5,4}; - mesh->insertNextCell(INTERP_KERNEL::NORM_QUAD4,4,conn); // 0 - mesh->insertNextCell(INTERP_KERNEL::NORM_TRI3,3, conn+4); // 1 - mesh->insertNextCell(INTERP_KERNEL::NORM_TRI3,3, conn+7); // 2 - mesh->insertNextCell(INTERP_KERNEL::NORM_QUAD4,4,conn+10); // 3 - mesh->insertNextCell(INTERP_KERNEL::NORM_QUAD4,4,conn+14); // 4 - mesh->finishInsertingCells(); - MEDCouplingAutoRefCountObjectPtr coordsArr=DataArrayDouble::New(); - coordsArr->alloc(9,2); - const double coords[18]={-0.3,-0.3, 0.2,-0.3, 0.7,-0.3, -0.3,0.2, 0.2,0.2, 0.7,0.2, -0.3,0.7, 0.2,0.7, 0.7,0.7 }; - std::copy(coords,coords+18,coordsArr->getPointer()); - mesh->setCoords(coordsArr); - //! [CppSnippet_MEDCouplingUMesh_getPartMeasureField_1] - //! [CppSnippet_MEDCouplingUMesh_getPartMeasureField_2] - const bool isAbs = true; - const int part[4] = {1,2,3,4}; // cell #0 is omitted - MEDCouplingAutoRefCountObjectPtr areaArr= - mesh->getPartMeasureField( isAbs, part, part+4 ); - CPPUNIT_ASSERT( areaArr->getIJ(0,0) > 0 ); // orientation ignored - areaArr=mesh->getPartMeasureField( !isAbs, part, part+4 ); - CPPUNIT_ASSERT( areaArr->getIJ(0,0) < 0 ); // orientation considered - CPPUNIT_ASSERT ( areaArr->getNumberOfTuples() == 4 ); - //! [CppSnippet_MEDCouplingUMesh_getPartMeasureField_2] - //! [CppSnippet_MEDCouplingUMesh_getPartMeasureField_3] - const int cellIds[4] = {1,2,3,4}; // cell #0 is omitted - MEDCouplingAutoRefCountObjectPtr baryCenters= - mesh->getPartBarycenterAndOwner( cellIds, cellIds+4 ); - CPPUNIT_ASSERT( baryCenters->getNumberOfTuples() == 4 ); - CPPUNIT_ASSERT( baryCenters->getNumberOfComponents() == mesh->getSpaceDimension() ); - //! [CppSnippet_MEDCouplingUMesh_getPartMeasureField_3] -} - -void CppExample_MEDCouplingUMesh_getCellsInBoundingBox() -{ - using namespace ParaMEDMEM; - //! [CppSnippet_MEDCouplingUMesh_getCellsInBoundingBox_1] - MEDCouplingAutoRefCountObjectPtr mesh=MEDCouplingUMesh::New(); - mesh->setMeshDimension(2); - mesh->allocateCells(1); - const double coords[3*2]={0.,0., 0.,1., 1.,1}; - MEDCouplingAutoRefCountObjectPtr coordsArr=DataArrayDouble::New(); - coordsArr->useExternalArrayWithRWAccess(coords, 3,2); - mesh->setCoords(coordsArr); - mesh->allocateCells(1); - const int conn[3]={0,1,2}; - mesh->insertNextCell(INTERP_KERNEL::NORM_TRI3,3,conn); - mesh->finishInsertingCells(); - //! [CppSnippet_MEDCouplingUMesh_getCellsInBoundingBox_1] - //! [CppSnippet_MEDCouplingUMesh_getCellsInBoundingBox_2] - const double bbox[] = {1., 1., 1.001,1.001}; // xMin, xMax, yMin, yMax - MEDCouplingAutoRefCountObjectPtr cellIdsArr = - mesh->getCellsInBoundingBox( bbox, 0.0 ); - CPPUNIT_ASSERT( cellIdsArr->getNumberOfTuples() == 0 ); - cellIdsArr = mesh->getCellsInBoundingBox( bbox, 0.1 ); - CPPUNIT_ASSERT( cellIdsArr->getNumberOfTuples() == 1 ); - //! [CppSnippet_MEDCouplingUMesh_getCellsInBoundingBox_2] -} - -void CppExample_MEDCouplingUMesh_renumberNodesInConn() -{ - using namespace ParaMEDMEM; - //! [CppSnippet_MEDCouplingUMesh_renumberNodesInConn_1] - MEDCouplingAutoRefCountObjectPtr mesh=MEDCouplingUMesh::New(); - mesh->setMeshDimension(2); - mesh->allocateCells(1); - const int conn[4]={4,3,2,1}; - mesh->insertNextCell(INTERP_KERNEL::NORM_QUAD4,4,conn); - mesh->finishInsertingCells(); - //! [CppSnippet_MEDCouplingUMesh_renumberNodesInConn_1] - //! [CppSnippet_MEDCouplingUMesh_renumberNodesInConn_2] - const int old2newIds[] = {-1,3,2,1,0}; - mesh->renumberNodesInConn( old2newIds ); - const int nodes0Expected[] = {0,1,2,3}; - std::vector nodes0; - mesh->getNodeIdsOfCell( 0, nodes0 ); - CPPUNIT_ASSERT(std::equal( nodes0Expected, nodes0Expected+4, &nodes0[0] )); - //! [CppSnippet_MEDCouplingUMesh_renumberNodesInConn_2] -} - -void CppExample_MEDCouplingUMesh_renumberNodes() -{ - using namespace ParaMEDMEM; - //! [CppSnippet_MEDCouplingUMesh_renumberNodes_1] - MEDCouplingAutoRefCountObjectPtr mesh=MEDCouplingUMesh::New(); - mesh->setMeshDimension(2); - const double coords[4*2]={-0.3,-0.3, 0.2,-0.3, 0.7,-0.3, -0.3,0.3}; - MEDCouplingAutoRefCountObjectPtr coordsArr=DataArrayDouble::New(); - coordsArr->useExternalArrayWithRWAccess(coords, 4,2); - mesh->setCoords(coordsArr); - mesh->allocateCells(0); - mesh->finishInsertingCells(); - //! [CppSnippet_MEDCouplingUMesh_renumberNodes_1] - //! [CppSnippet_MEDCouplingUMesh_renumberNodes_2] - const int newIds[] = { 2,1,0,-1 }; - mesh->renumberNodes(newIds, 3); - coordsArr = mesh->getCoordinatesAndOwner(); // get a shorten array - const double coordsExpected[3*2]={0.7,-0.3, 0.2,-0.3, -0.3,-0.3}; - MEDCouplingAutoRefCountObjectPtr coordsExpectedArr=DataArrayDouble::New(); - coordsExpectedArr->useExternalArrayWithRWAccess(coordsExpected, 3,2); - CPPUNIT_ASSERT( coordsExpectedArr->isEqual( *coordsArr, 1e-13 )); - //! [CppSnippet_MEDCouplingUMesh_renumberNodes_2] - //! [CppSnippet_MEDCouplingUMesh_renumberNodes_3] - coordsArr->useExternalArrayWithRWAccess(coords, 4,2); // restore old nodes - const int newIds2[] = { 2,1,0,2 }; - mesh->renumberNodes2(newIds2, 3); - coordsArr = mesh->getCoordinatesAndOwner(); // get a shorten array - const double coordsExpected2[3*2]={0.7,-0.3, 0.2,-0.3, -0.3, 0.0}; - MEDCouplingAutoRefCountObjectPtr coordsExpectedArr2=DataArrayDouble::New(); - coordsExpectedArr2->useExternalArrayWithRWAccess(coordsExpected2, 3,2); - CPPUNIT_ASSERT( coordsExpectedArr2->isEqual( *coordsArr, 1e-13 )); - //! [CppSnippet_MEDCouplingUMesh_renumberNodes_3] -} - -void CppExample_MEDCouplingUMesh_findBoundaryNodes() -{ - using namespace ParaMEDMEM; - //! [CppSnippet_MEDCouplingUMesh_findBoundaryNodes_1] - MEDCouplingAutoRefCountObjectPtr mesh=MEDCouplingUMesh::New(); - mesh->setMeshDimension(2); - mesh->allocateCells(5); - const int conn[18]={0,3,4,1, 1,4,2, 4,5,2, 6,7,4,3, 7,8,5,4}; - mesh->insertNextCell(INTERP_KERNEL::NORM_QUAD4,4,conn); - mesh->insertNextCell(INTERP_KERNEL::NORM_TRI3,3, conn+4); - mesh->insertNextCell(INTERP_KERNEL::NORM_TRI3,3, conn+7); - mesh->insertNextCell(INTERP_KERNEL::NORM_QUAD4,4,conn+10); - mesh->insertNextCell(INTERP_KERNEL::NORM_QUAD4,4,conn+14); - mesh->finishInsertingCells(); - MEDCouplingAutoRefCountObjectPtr coordsArr=DataArrayDouble::New(); - coordsArr->alloc(9,2); - const double coords[18]={-0.3,-0.3, 0.2,-0.3, 0.7,-0.3, -0.3,0.2, 0.2,0.2, 0.7,0.2, -0.3,0.7, 0.2,0.7, 0.7,0.7 }; - std::copy(coords,coords+18,coordsArr->getPointer()); - mesh->setCoords(coordsArr); - //! [CppSnippet_MEDCouplingUMesh_findBoundaryNodes_1] - //! [CppSnippet_MEDCouplingUMesh_findBoundaryNodes_2] - MEDCouplingAutoRefCountObjectPtr nodeIdsArr=mesh->findBoundaryNodes(); - CPPUNIT_ASSERT( nodeIdsArr->getNumberOfTuples() == mesh->getNumberOfNodes() - 1 ); - //! [CppSnippet_MEDCouplingUMesh_findBoundaryNodes_2] -} - -void CppExample_MEDCouplingUMesh_buildBoundaryMesh() -{ - using namespace ParaMEDMEM; - //! [CppSnippet_MEDCouplingUMesh_buildBoundaryMesh_1] - MEDCouplingAutoRefCountObjectPtr mesh=MEDCouplingUMesh::New(); - mesh->setMeshDimension(2); - mesh->allocateCells(5); - const int conn[18]={0,3,4,1, 1,4,2, 4,5,2, 6,7,4,3, 7,8,5,4}; - mesh->insertNextCell(INTERP_KERNEL::NORM_QUAD4,4,conn); - mesh->insertNextCell(INTERP_KERNEL::NORM_TRI3,3, conn+4); - mesh->insertNextCell(INTERP_KERNEL::NORM_TRI3,3, conn+7); - mesh->insertNextCell(INTERP_KERNEL::NORM_QUAD4,4,conn+10); - mesh->insertNextCell(INTERP_KERNEL::NORM_QUAD4,4,conn+14); - mesh->finishInsertingCells(); - MEDCouplingAutoRefCountObjectPtr coordsArr=DataArrayDouble::New(); - coordsArr->alloc(9,2); - const double coords[18]={-0.3,-0.3, 0.2,-0.3, 0.7,-0.3, -0.3,0.2, 0.2,0.2, 0.7,0.2, -0.3,0.7, 0.2,0.7, 0.7,0.7 }; - std::copy(coords,coords+18,coordsArr->getPointer()); - mesh->setCoords(coordsArr); - //! [CppSnippet_MEDCouplingUMesh_buildBoundaryMesh_1] - //! [CppSnippet_MEDCouplingUMesh_buildBoundaryMesh_2] - MEDCouplingAutoRefCountObjectPtr mesh1=mesh->buildBoundaryMesh(true); - MEDCouplingAutoRefCountObjectPtr mesh2=mesh->buildBoundaryMesh(false); - CPPUNIT_ASSERT( coordsArr->isEqual( *mesh1->getCoords(), 1e-13 )); // same nodes - CPPUNIT_ASSERT( !coordsArr->isEqual( *mesh2->getCoords(), 1e-13 )); // different nodes - //! [CppSnippet_MEDCouplingUMesh_buildBoundaryMesh_2] -} - -void CppExample_MEDCouplingUMesh_buildFacePartOfMySelfNode() -{ - using namespace ParaMEDMEM; - //! [CppSnippet_MEDCouplingUMesh_buildFacePartOfMySelfNode_1] - MEDCouplingAutoRefCountObjectPtr mesh=MEDCouplingUMesh::New(); - mesh->setMeshDimension(2); - mesh->allocateCells(5); - const int conn[18]={0,3,4,1, 1,4,2, 4,5,2, 6,7,4,3, 7,8,5,4}; - mesh->insertNextCell(INTERP_KERNEL::NORM_QUAD4,4,conn); // 0 - mesh->insertNextCell(INTERP_KERNEL::NORM_TRI3,3, conn+4); // 1 - mesh->insertNextCell(INTERP_KERNEL::NORM_TRI3,3, conn+7); // 2 - mesh->insertNextCell(INTERP_KERNEL::NORM_QUAD4,4,conn+10); // 3 - mesh->insertNextCell(INTERP_KERNEL::NORM_QUAD4,4,conn+14); // 4 - mesh->finishInsertingCells(); - MEDCouplingAutoRefCountObjectPtr coordsArr=DataArrayDouble::New(); - coordsArr->alloc(9,2); - const double coords[18]={-0.3,-0.3, 0.2,-0.3, 0.7,-0.3, -0.3,0.2, 0.2,0.2, 0.7,0.2, -0.3,0.7, 0.2,0.7, 0.7,0.7 }; - std::copy(coords,coords+18,coordsArr->getPointer()); - mesh->setCoords(coordsArr); - //! [CppSnippet_MEDCouplingUMesh_buildFacePartOfMySelfNode_1] - //! [CppSnippet_MEDCouplingUMesh_buildFacePartOfMySelfNode_2] - std::vector nodes; - mesh->getNodeIdsOfCell( 0, nodes ); - const bool allNodes = true; - MEDCouplingAutoRefCountObjectPtr mesh1 = - (MEDCouplingUMesh*)mesh->buildFacePartOfMySelfNode( &nodes[0],&nodes[0]+nodes.size(),allNodes); - CPPUNIT_ASSERT( mesh1->getNumberOfCells() == 4 ); // 4 segments bounding QUAD4 #0 only - MEDCouplingAutoRefCountObjectPtr mesh2 = - (MEDCouplingUMesh*)mesh->buildFacePartOfMySelfNode( &nodes[0],&nodes[0]+nodes.size(),!allNodes); - CPPUNIT_ASSERT( mesh2->getNumberOfCells() == 9 ); // more segments added - //! [CppSnippet_MEDCouplingUMesh_buildFacePartOfMySelfNode_2] -} - -void CppExample_MEDCouplingUMesh_buildPartOfMySelfNode() -{ - using namespace ParaMEDMEM; - //! [CppSnippet_MEDCouplingUMesh_buildPartOfMySelfNode_1] - MEDCouplingAutoRefCountObjectPtr mesh=MEDCouplingUMesh::New(); - mesh->setMeshDimension(2); - mesh->allocateCells(5); - const int conn[18]={0,3,4,1, 1,4,2, 4,5,2, 6,7,4,3, 7,8,5,4}; - mesh->insertNextCell(INTERP_KERNEL::NORM_QUAD4,4,conn); // 0 - mesh->insertNextCell(INTERP_KERNEL::NORM_TRI3,3, conn+4); // 1 - mesh->insertNextCell(INTERP_KERNEL::NORM_TRI3,3, conn+7); // 2 - mesh->insertNextCell(INTERP_KERNEL::NORM_QUAD4,4,conn+10); // 3 - mesh->insertNextCell(INTERP_KERNEL::NORM_QUAD4,4,conn+14); // 4 - mesh->finishInsertingCells(); - MEDCouplingAutoRefCountObjectPtr coordsArr=DataArrayDouble::New(); - coordsArr->alloc(9,2); - const double coords[18]={-0.3,-0.3, 0.2,-0.3, 0.7,-0.3, -0.3,0.2, 0.2,0.2, 0.7,0.2, -0.3,0.7, 0.2,0.7, 0.7,0.7 }; - std::copy(coords,coords+18,coordsArr->getPointer()); - mesh->setCoords(coordsArr); - //! [CppSnippet_MEDCouplingUMesh_buildPartOfMySelfNode_1] - //! [CppSnippet_MEDCouplingUMesh_buildPartOfMySelfNode_2] - std::vector nodes; - mesh->getNodeIdsOfCell( 0, nodes ); - const bool allNodes = true; - MEDCouplingAutoRefCountObjectPtr mesh1 = - (MEDCouplingUMesh*)mesh->buildPartOfMySelfNode( &nodes[0], &nodes[0]+nodes.size(), allNodes); - MEDCouplingAutoRefCountObjectPtr mesh2 = - (MEDCouplingUMesh*)mesh->buildPartOfMySelfNode( &nodes[0], &nodes[0]+nodes.size(),!allNodes); - CPPUNIT_ASSERT_EQUAL( mesh1->getNumberOfCells(), 1 ); - CPPUNIT_ASSERT_EQUAL( mesh2->getNumberOfCells(), mesh->getNumberOfCells() ); - //! [CppSnippet_MEDCouplingUMesh_buildPartOfMySelfNode_2] -} - -void CppExample_MEDCouplingUMesh_getCellIdsLyingOnNodes() -{ - using namespace ParaMEDMEM; - //! [CppSnippet_MEDCouplingUMesh_getCellIdsLyingOnNodes_1] - MEDCouplingAutoRefCountObjectPtr mesh=MEDCouplingUMesh::New(); - mesh->setMeshDimension(2); - mesh->allocateCells(5); - const int conn[18]={0,3,4,1, 1,4,2, 4,5,2, 6,7,4,3, 7,8,5,4}; - mesh->insertNextCell(INTERP_KERNEL::NORM_QUAD4,4,conn); // 0 - mesh->insertNextCell(INTERP_KERNEL::NORM_TRI3,3, conn+4); // 1 - mesh->insertNextCell(INTERP_KERNEL::NORM_TRI3,3, conn+7); // 2 - mesh->insertNextCell(INTERP_KERNEL::NORM_QUAD4,4,conn+10); // 3 - mesh->insertNextCell(INTERP_KERNEL::NORM_QUAD4,4,conn+14); // 4 - mesh->finishInsertingCells(); - MEDCouplingAutoRefCountObjectPtr coordsArr=DataArrayDouble::New(); - coordsArr->alloc(9,2); - const double coords[18]={-0.3,-0.3, 0.2,-0.3, 0.7,-0.3, -0.3,0.2, 0.2,0.2, 0.7,0.2, -0.3,0.7, 0.2,0.7, 0.7,0.7 }; - std::copy(coords,coords+18,coordsArr->getPointer()); - mesh->setCoords(coordsArr); - //! [CppSnippet_MEDCouplingUMesh_getCellIdsLyingOnNodes_1] - //! [CppSnippet_MEDCouplingUMesh_getCellIdsLyingOnNodes_2] - std::vector nodes; - mesh->getNodeIdsOfCell( 0, nodes ); - const bool allNodes = true; - DataArrayInt* cellIdsArr1 = mesh->getCellIdsLyingOnNodes( &nodes[0], &nodes[0]+nodes.size(), allNodes); - DataArrayInt* cellIdsArr2 = mesh->getCellIdsLyingOnNodes( &nodes[0], &nodes[0]+nodes.size(),!allNodes); - CPPUNIT_ASSERT_EQUAL( cellIdsArr1->getNumberOfTuples(), 1 ); - CPPUNIT_ASSERT_EQUAL( cellIdsArr2->getNumberOfTuples(), mesh->getNumberOfCells() ); - //! [CppSnippet_MEDCouplingUMesh_getCellIdsLyingOnNodes_2] - cellIdsArr1->decrRef(); - cellIdsArr2->decrRef(); -} - -void CppExample_MEDCouplingUMesh_getCellIdsFullyIncludedInNodeIds() -{ - using namespace ParaMEDMEM; - //! [CppSnippet_MEDCouplingUMesh_getCellIdsFullyIncludedInNodeIds_1] - MEDCouplingAutoRefCountObjectPtr mesh=MEDCouplingUMesh::New(); - mesh->setMeshDimension(2); - mesh->allocateCells(5); - const int conn[18]={0,3,4,1, 1,4,2, 4,5,2, 6,7,4,3, 7,8,5,4}; - mesh->insertNextCell(INTERP_KERNEL::NORM_QUAD4,4,conn); - mesh->insertNextCell(INTERP_KERNEL::NORM_TRI3,3, conn+4); - mesh->insertNextCell(INTERP_KERNEL::NORM_TRI3,3, conn+7); - mesh->insertNextCell(INTERP_KERNEL::NORM_QUAD4,4,conn+10); - mesh->insertNextCell(INTERP_KERNEL::NORM_QUAD4,4,conn+14); - mesh->finishInsertingCells(); - MEDCouplingAutoRefCountObjectPtr coordsArr=DataArrayDouble::New(); - coordsArr->alloc(9,2); - const double coords[18]={-0.3,-0.3, 0.2,-0.3, 0.7,-0.3, -0.3,0.2, 0.2,0.2, 0.7,0.2, -0.3,0.7, 0.2,0.7, 0.7,0.7 }; - std::copy(coords,coords+18,coordsArr->getPointer()); - mesh->setCoords(coordsArr); - //! [CppSnippet_MEDCouplingUMesh_getCellIdsFullyIncludedInNodeIds_1] - //! [CppSnippet_MEDCouplingUMesh_getCellIdsFullyIncludedInNodeIds_2] - const int cellIds[2]={1,2}; - std::vector nodes; - mesh->getNodeIdsOfCell( cellIds[0], nodes ); - mesh->getNodeIdsOfCell( cellIds[1], nodes ); - DataArrayInt* cellIdsArr = mesh->getCellIdsFullyIncludedInNodeIds( &nodes[0], &nodes[0]+nodes.size()); - CPPUNIT_ASSERT(std::equal( cellIds, cellIds+2, cellIdsArr->getPointer() )); - //! [CppSnippet_MEDCouplingUMesh_getCellIdsFullyIncludedInNodeIds_2] - cellIdsArr->decrRef(); -} - -void CppExample_MEDCouplingUMesh_buildPartOfMySelf() -{ - using namespace ParaMEDMEM; - //! [CppSnippet_MEDCouplingUMesh_buildPartOfMySelf_1] - MEDCouplingAutoRefCountObjectPtr mesh=MEDCouplingUMesh::New(); - mesh->setMeshDimension(2); - mesh->allocateCells(5); - const int conn[18]={0,3,4,1, 1,4,2, 4,5,2, 6,7,4,3, 7,8,5,4}; - mesh->insertNextCell(INTERP_KERNEL::NORM_QUAD4,4,conn); // 0 - mesh->insertNextCell(INTERP_KERNEL::NORM_TRI3,3, conn+4); // 1 - mesh->insertNextCell(INTERP_KERNEL::NORM_TRI3,3, conn+7); // 2 - mesh->insertNextCell(INTERP_KERNEL::NORM_QUAD4,4,conn+10); // 3 - mesh->insertNextCell(INTERP_KERNEL::NORM_QUAD4,4,conn+14); // 4 - mesh->finishInsertingCells(); - MEDCouplingAutoRefCountObjectPtr coordsArr=DataArrayDouble::New(); - coordsArr->alloc(9,2); - const double coords[18]={-0.3,-0.3, 0.2,-0.3, 0.7,-0.3, -0.3,0.2, 0.2,0.2, 0.7,0.2, -0.3,0.7, 0.2,0.7, 0.7,0.7 }; - std::copy(coords,coords+18,coordsArr->getPointer()); - mesh->setCoords(coordsArr); - //! [CppSnippet_MEDCouplingUMesh_buildPartOfMySelf_1] - //! [CppSnippet_MEDCouplingUMesh_buildPartOfMySelf_2] - const int cellIds[2]={1,2}; - MEDCouplingUMesh* mesh2=(MEDCouplingUMesh*)mesh->buildPartOfMySelf(cellIds,cellIds+2,true); - MEDCouplingUMesh* mesh3=(MEDCouplingUMesh*)mesh->buildPartOfMySelf(cellIds,cellIds+2,false); - CPPUNIT_ASSERT( coordsArr->isEqual( *mesh2->getCoords(), 1e-13 )); // same nodes - CPPUNIT_ASSERT( !coordsArr->isEqual( *mesh3->getCoords(), 1e-13 )); // different nodes - for ( int i = 0; i < 2; ++i ) - { - std::vector nodes1, nodes2; - mesh ->getNodeIdsOfCell(cellIds[i], nodes1); - mesh2->getNodeIdsOfCell(i, nodes2); - CPPUNIT_ASSERT( nodes1 == nodes2 ); // cell #cellIds[i] was copied - } - //! [CppSnippet_MEDCouplingUMesh_buildPartOfMySelf_2] - mesh2->decrRef(); - mesh3->decrRef(); -} - -void CppExample_MEDCouplingUMesh_mergeNodes() -{ - using namespace ParaMEDMEM; - //! [CppSnippet_MEDCouplingUMesh_mergeNodes_1] - MEDCouplingAutoRefCountObjectPtr mesh=MEDCouplingUMesh::New(); - mesh->setMeshDimension(2); - mesh->allocateCells(5); - const int conn[18]={0,3,4,1, 1,4,2, 4,5,2}; - mesh->insertNextCell(INTERP_KERNEL::NORM_QUAD4,4,conn); - mesh->insertNextCell(INTERP_KERNEL::NORM_TRI3,3, conn+4); - mesh->insertNextCell(INTERP_KERNEL::NORM_TRI3,3, conn+7); - mesh->finishInsertingCells(); - const double coords[6*2]={0.3,-0.301, // #0 - 0.2,-0.3, // #1 - 0.3,-0.302, // #2 ~~ #0 - 1.1,0.0, // #3 - 1.1,0.0, // #4 == #3 - 0.3,-0.303}; // #5 ~~ #0 - MEDCouplingAutoRefCountObjectPtr coordsArr=DataArrayDouble::New(); - coordsArr->alloc(6,2); - std::copy(coords,coords+6*2,coordsArr->getPointer()); - mesh->setCoords(coordsArr); - //! [CppSnippet_MEDCouplingUMesh_mergeNodes_1] - //! [CppSnippet_MEDCouplingUMesh_mergeNodes_2] - bool areNodesMerged; int newNbOfNodes; - MEDCouplingAutoRefCountObjectPtr arr= - mesh->mergeNodes(0.004,areNodesMerged,newNbOfNodes); - const int idsExpected[6] = {0, 1, 0, 2, 2, 0}; - CPPUNIT_ASSERT(std::equal(idsExpected,idsExpected+6,arr->getPointer())); - CPPUNIT_ASSERT( areNodesMerged ); - CPPUNIT_ASSERT_EQUAL( 3, newNbOfNodes ); - //! [CppSnippet_MEDCouplingUMesh_mergeNodes_2] - //! [CppSnippet_MEDCouplingUMesh_mergeNodes_3] - const double* baryCoords2 = coords + 2*2; // initial coordinates of node #2 - coordsArr=mesh->getCoordinatesAndOwner(); // retrieve a new shorten coord array - CPPUNIT_ASSERT( fabs( baryCoords2[1] - coordsArr->getIJ(0,1)) > 1e-4 ); // Y of node #0 differs from that of baryCoords2 - // restore coordinates - coordsArr->alloc(6,2); - std::copy(coords,coords+6*2,coordsArr->getPointer()); - mesh->setCoords(coordsArr); - // call mergeNodes2() - arr = mesh->mergeNodes2(0.004,areNodesMerged,newNbOfNodes); - coordsArr=mesh->getCoordinatesAndOwner(); // retrieve a new shorten coord array - CPPUNIT_ASSERT_DOUBLES_EQUAL( baryCoords2[1], coordsArr->getIJ(0,1), 13 ); // Y of node #0 equals to that of baryCoords2 - //! [CppSnippet_MEDCouplingUMesh_mergeNodes_3] -} - -void CppExample_MEDCouplingUMesh_zipConnectivityTraducer() -{ - using namespace ParaMEDMEM; - //! [CppSnippet_MEDCouplingUMesh_zipConnectivityTraducer_1] - MEDCouplingAutoRefCountObjectPtr mesh=MEDCouplingUMesh::New(); - mesh->setMeshDimension(2); - mesh->allocateCells(5); - const int conn[11]={0,3,4,1, 1,4,2, 4,1,0,3}; - mesh->insertNextCell(INTERP_KERNEL::NORM_QUAD4,4,conn+0); // 0 - mesh->insertNextCell(INTERP_KERNEL::NORM_TRI3,3, conn+4); // 1 - mesh->insertNextCell(INTERP_KERNEL::NORM_TRI3,3, conn+4); // 2 == 1 - mesh->insertNextCell(INTERP_KERNEL::NORM_QUAD4,4,conn+0); // 3 == 0 - mesh->insertNextCell(INTERP_KERNEL::NORM_QUAD4,4,conn+7); // 4 ~~ 0 - mesh->finishInsertingCells(); - MEDCouplingAutoRefCountObjectPtr coordsArr=DataArrayDouble::New(); - coordsArr->alloc(9,2); - const double coords[18]={-0.3,-0.3, 0.2,-0.3, 0.7,-0.3, -0.3,0.2, 0.2,0.2, 0.7,0.2, -0.3,0.7, 0.2,0.7, 0.7,0.7 }; - std::copy(coords,coords+18,coordsArr->getPointer()); - mesh->setCoords(coordsArr); - //! [CppSnippet_MEDCouplingUMesh_zipConnectivityTraducer_1] - //! [CppSnippet_MEDCouplingUMesh_zipConnectivityTraducer_2] - const int oldNbCells = mesh->getNumberOfCells(); - DataArrayInt *arr = mesh->zipConnectivityTraducer(0); - CPPUNIT_ASSERT_EQUAL( oldNbCells-2, mesh->getNumberOfCells() ); - const int idsExpected[5] = {0, 1, 1, 0, 2}; - CPPUNIT_ASSERT(std::equal(idsExpected,idsExpected+5,arr->getPointer())); - //! [CppSnippet_MEDCouplingUMesh_zipConnectivityTraducer_2] - arr->decrRef(); -} - -void CppExample_MEDCouplingUMesh_zipCoordsTraducer() -{ - using namespace ParaMEDMEM; - //! [CppSnippet_MEDCouplingUMesh_zipCoordsTraducer_1] - MEDCouplingAutoRefCountObjectPtr mesh=MEDCouplingUMesh::New(); - mesh->setMeshDimension(2); - mesh->allocateCells(5); - const int conn[18]={0,3,4,1, 1,4,2, 4,5,2, 6,7,4,3, 7,8,5,4}; - mesh->insertNextCell(INTERP_KERNEL::NORM_QUAD4,4,conn); - mesh->insertNextCell(INTERP_KERNEL::NORM_TRI3,3, conn+4); - mesh->insertNextCell(INTERP_KERNEL::NORM_TRI3,3, conn+7); - mesh->insertNextCell(INTERP_KERNEL::NORM_QUAD4,4,conn+10); - mesh->insertNextCell(INTERP_KERNEL::NORM_QUAD4,4,conn+14); - mesh->finishInsertingCells(); - MEDCouplingAutoRefCountObjectPtr coordsArr=DataArrayDouble::New(); - coordsArr->alloc(9,2); - const double coords[18]={-0.3,-0.3, 0.2,-0.3, 0.7,-0.3, -0.3,0.2, 0.2,0.2, 0.7,0.2, -0.3,0.7, 0.2,0.7, 0.7,0.7 }; - std::copy(coords,coords+18,coordsArr->getPointer()); - mesh->setCoords(coordsArr); - //! [CppSnippet_MEDCouplingUMesh_zipCoordsTraducer_1] - //! [CppSnippet_MEDCouplingUMesh_zipCoordsTraducer_2] - const int cellIds[2]={1,2}; - MEDCouplingUMesh* mesh2=(MEDCouplingUMesh*)mesh->buildPartOfMySelf(cellIds,cellIds+2,true); - DataArrayInt *arr=mesh2->zipCoordsTraducer(); - CPPUNIT_ASSERT_EQUAL( 4, mesh2->getNumberOfNodes() ); // nb of nodes decreased - CPPUNIT_ASSERT_EQUAL( mesh->getNumberOfNodes(), arr->getNumberOfTuples() ); - const int idsExpected[9] = {-1,0,1,-1,2,3,-1,-1,-1}; // -1 for unused nodes - CPPUNIT_ASSERT(std::equal(idsExpected,idsExpected+9,arr->getPointer())); - //! [CppSnippet_MEDCouplingUMesh_zipCoordsTraducer_2] - mesh2->decrRef(); - arr->decrRef(); -} - -void CppExample_MEDCouplingUMesh_getNodeIdsInUse() -{ - using namespace ParaMEDMEM; - //! [CppSnippet_MEDCouplingUMesh_getNodeIdsInUse_1] - MEDCouplingAutoRefCountObjectPtr mesh=MEDCouplingUMesh::New(); - mesh->setMeshDimension(2); - mesh->allocateCells(5); - const int conn[18]={0,3,4,1, 1,4,2, 4,5,2, 6,7,4,3, 7,8,5,4}; - mesh->insertNextCell(INTERP_KERNEL::NORM_QUAD4,4,conn); - mesh->insertNextCell(INTERP_KERNEL::NORM_TRI3,3, conn+4); - mesh->insertNextCell(INTERP_KERNEL::NORM_TRI3,3, conn+7); - mesh->insertNextCell(INTERP_KERNEL::NORM_QUAD4,4,conn+10); - mesh->insertNextCell(INTERP_KERNEL::NORM_QUAD4,4,conn+14); - mesh->finishInsertingCells(); - MEDCouplingAutoRefCountObjectPtr coordsArr=DataArrayDouble::New(); - coordsArr->alloc(9,2); - const double coords[18]={-0.3,-0.3, 0.2,-0.3, 0.7,-0.3, -0.3,0.2, 0.2,0.2, 0.7,0.2, -0.3,0.7, 0.2,0.7, 0.7,0.7 }; - std::copy(coords,coords+18,coordsArr->getPointer()); - mesh->setCoords(coordsArr); - //! [CppSnippet_MEDCouplingUMesh_getNodeIdsInUse_1] - //! [CppSnippet_MEDCouplingUMesh_getNodeIdsInUse_2] - const int cellIds[2]={1,2}; - MEDCouplingUMesh* mesh2=(MEDCouplingUMesh*)mesh->buildPartOfMySelf(cellIds,cellIds+2,true); - int newNbOfNodes = 0; - DataArrayInt *arr=mesh2->getNodeIdsInUse( newNbOfNodes ); - const int idsExpected[9] = {-1,0,1,-1,2,3,-1,-1,-1}; - CPPUNIT_ASSERT(std::equal(idsExpected,idsExpected+9,arr->getPointer())); - //! [CppSnippet_MEDCouplingUMesh_getNodeIdsInUse_2] - //! [CppSnippet_MEDCouplingUMesh_getNodeIdsInUse_3] - DataArrayInt *arr2=arr->invertArrayO2N2N2O(newNbOfNodes); - const int idsExpected2[4] = {1,2,4,5}; - CPPUNIT_ASSERT(std::equal(idsExpected2,idsExpected2+4,arr2->getPointer())); - //! [CppSnippet_MEDCouplingUMesh_getNodeIdsInUse_3] - mesh2->decrRef(); - arr->decrRef(); - arr2->decrRef(); -} - -void CppExample_MEDCouplingUMesh_convertToPolyTypes() -{ - using namespace ParaMEDMEM; - //! [CppSnippet_MEDCouplingUMesh_convertToPolyTypes_1] - MEDCouplingAutoRefCountObjectPtr mesh=MEDCouplingUMesh::New(); - mesh->setMeshDimension(2); - mesh->allocateCells(5); - const int conn[18]={0,3,4,1, 1,4,2, 4,5,2, 6,7,4,3, 7,8,5,4}; - mesh->insertNextCell(INTERP_KERNEL::NORM_QUAD4,4,conn); // 0 - mesh->insertNextCell(INTERP_KERNEL::NORM_TRI3,3, conn+4); // 1 - mesh->insertNextCell(INTERP_KERNEL::NORM_TRI3,3, conn+7); // 2 - mesh->insertNextCell(INTERP_KERNEL::NORM_QUAD4,4,conn+10); // 3 - mesh->insertNextCell(INTERP_KERNEL::NORM_QUAD4,4,conn+14); // 4 - mesh->finishInsertingCells(); - MEDCouplingAutoRefCountObjectPtr coordsArr=DataArrayDouble::New(); - coordsArr->alloc(9,2); - const double coords[18]={-0.3,-0.3, 0.2,-0.3, 0.7,-0.3, -0.3,0.2, 0.2,0.2, 0.7,0.2, -0.3,0.7, 0.2,0.7, 0.7,0.7 }; - std::copy(coords,coords+18,coordsArr->getPointer()); - mesh->setCoords(coordsArr); - //! [CppSnippet_MEDCouplingUMesh_convertToPolyTypes_1] - //! [CppSnippet_MEDCouplingUMesh_convertToPolyTypes_2] - const int cells[2]={1,3}; - mesh->convertToPolyTypes(cells, cells+2); - CPPUNIT_ASSERT( mesh->getTypeOfCell(0) == INTERP_KERNEL::NORM_QUAD4 ); - CPPUNIT_ASSERT( mesh->getTypeOfCell(1) == INTERP_KERNEL::NORM_POLYGON ); - CPPUNIT_ASSERT( mesh->getTypeOfCell(2) == INTERP_KERNEL::NORM_TRI3 ); - CPPUNIT_ASSERT( mesh->getTypeOfCell(3) == INTERP_KERNEL::NORM_POLYGON ); - //! [CppSnippet_MEDCouplingUMesh_convertToPolyTypes_2] -} - -void CppExample_MEDCouplingUMesh_buildDescendingConnectivity2() -{ - using namespace ParaMEDMEM; - //! [CppSnippet_MEDCouplingUMesh_buildDescendingConnectivity2_1] - MEDCouplingAutoRefCountObjectPtr mesh=MEDCouplingUMesh::New(); - mesh->setMeshDimension(2); - mesh->allocateCells(5); - const int conn[18]={0,3,4,1, 1,4,2, 4,5,2, 6,7,4,3, 7,8,5,4}; - mesh->insertNextCell(INTERP_KERNEL::NORM_QUAD4,4,conn); // 0 - mesh->insertNextCell(INTERP_KERNEL::NORM_TRI3,3, conn+4); // 1 - mesh->insertNextCell(INTERP_KERNEL::NORM_TRI3,3, conn+7); // 2 - mesh->insertNextCell(INTERP_KERNEL::NORM_QUAD4,4,conn+10); // 3 - mesh->insertNextCell(INTERP_KERNEL::NORM_QUAD4,4,conn+14); // 4 - mesh->finishInsertingCells(); - MEDCouplingAutoRefCountObjectPtr coordsArr=DataArrayDouble::New(); - coordsArr->alloc(9,2); - const double coords[18]={-0.3,-0.3, 0.2,-0.3, 0.7,-0.3, -0.3,0.2, 0.2,0.2, 0.7,0.2, -0.3,0.7, 0.2,0.7, 0.7,0.7 }; - std::copy(coords,coords+18,coordsArr->getPointer()); - mesh->setCoords(coordsArr); - //! [CppSnippet_MEDCouplingUMesh_buildDescendingConnectivity2_1] - //! [CppSnippet_MEDCouplingUMesh_buildDescendingConnectivity2_2] - DataArrayInt *desc =DataArrayInt::New(); - DataArrayInt *descIndx =DataArrayInt::New(); - DataArrayInt *revDesc =DataArrayInt::New(); - DataArrayInt *revDescIndx=DataArrayInt::New(); - MEDCouplingUMesh * mesh2 = mesh->buildDescendingConnectivity2(desc,descIndx,revDesc,revDescIndx); - const int descExpected[] = {1,2,3,4,-3,5,6,7,8,-5,9,10,-2,11,12,13,-7,-10}; - const int descIndxExpected[] = {0,4,7,10,14,18}; - const int revDescExpected[] = {0, 0,3, 0,1, 0, 1,2, 1, 2,4, 2, 3, 3,4, 3, 4, 4}; - const int revDescIndxExpected[] = {0,1,3,5,6,8,9,11,12,13,15,16,17,18}; - CPPUNIT_ASSERT(std::equal(descExpected,descExpected+18,desc->getPointer())); - CPPUNIT_ASSERT(std::equal(descIndxExpected,descIndxExpected+6,descIndx->getPointer())); - CPPUNIT_ASSERT(std::equal(revDescExpected,revDescExpected+18,revDesc->getPointer())); - CPPUNIT_ASSERT(std::equal(revDescIndxExpected,revDescIndxExpected+14,revDescIndx->getPointer())); - //! [CppSnippet_MEDCouplingUMesh_buildDescendingConnectivity2_2] - //! [CppSnippet_MEDCouplingUMesh_buildDescendingConnectivity2_3] - const int cell2ConnExpect[] = {4,1}; - std::vector cell2Conn; - mesh2->getNodeIdsOfCell( 3-1, cell2Conn ); // cell #3 in FORTRAN mode - CPPUNIT_ASSERT(std::equal(cell2ConnExpect,cell2ConnExpect+2,&cell2Conn[0])); - //! [CppSnippet_MEDCouplingUMesh_buildDescendingConnectivity2_3] - desc->decrRef(); - descIndx->decrRef(); - revDesc->decrRef(); - revDescIndx->decrRef(); - mesh2->decrRef(); -} - -void CppExample_MEDCouplingUMesh_buildDescendingConnectivity() -{ - using namespace ParaMEDMEM; - //! [CppSnippet_MEDCouplingUMesh_buildDescendingConnectivity_1] - MEDCouplingAutoRefCountObjectPtr mesh=MEDCouplingUMesh::New(); - mesh->setMeshDimension(2); - mesh->allocateCells(5); - const int conn[18]={0,3,4,1, 1,4,2, 4,5,2, 6,7,4,3, 7,8,5,4}; - mesh->insertNextCell(INTERP_KERNEL::NORM_QUAD4,4,conn); // 0 - mesh->insertNextCell(INTERP_KERNEL::NORM_TRI3,3, conn+4); // 1 - mesh->insertNextCell(INTERP_KERNEL::NORM_TRI3,3, conn+7); // 2 - mesh->insertNextCell(INTERP_KERNEL::NORM_QUAD4,4,conn+10); // 3 - mesh->insertNextCell(INTERP_KERNEL::NORM_QUAD4,4,conn+14); // 4 - mesh->finishInsertingCells(); - MEDCouplingAutoRefCountObjectPtr coordsArr=DataArrayDouble::New(); - coordsArr->alloc(9,2); - const double coords[18]={-0.3,-0.3, 0.2,-0.3, 0.7,-0.3, -0.3,0.2, 0.2,0.2, 0.7,0.2, -0.3,0.7, 0.2,0.7, 0.7,0.7 }; - std::copy(coords,coords+18,coordsArr->getPointer()); - mesh->setCoords(coordsArr); - //! [CppSnippet_MEDCouplingUMesh_buildDescendingConnectivity_1] - //! [CppSnippet_MEDCouplingUMesh_buildDescendingConnectivity_2] - DataArrayInt *desc =DataArrayInt::New(); - DataArrayInt *descIndx =DataArrayInt::New(); - DataArrayInt *revDesc =DataArrayInt::New(); - DataArrayInt *revDescIndx=DataArrayInt::New(); - MEDCouplingUMesh * mesh2 = mesh->buildDescendingConnectivity(desc,descIndx,revDesc,revDescIndx); - const int descExpected[] = {0,1,2,3, 2,4,5, 6,7,4, 8,9,1,10, 11,12,6,9}; - const int descIndxExpected[] = {0,4,7,10,14,18}; - const int revDescExpected[] = {0, 0,3, 0,1, 0, 1,2, 1, 2,4, 2, 3, 3,4, 3, 4, 4}; - const int revDescIndxExpected[] = {0,1,3,5,6,8,9,11,12,13,15,16,17,18}; - CPPUNIT_ASSERT(std::equal(descExpected,descExpected+18,desc->getPointer())); - CPPUNIT_ASSERT(std::equal(descIndxExpected,descIndxExpected+6,descIndx->getPointer())); - CPPUNIT_ASSERT(std::equal(revDescExpected,revDescExpected+18,revDesc->getPointer())); - CPPUNIT_ASSERT(std::equal(revDescIndxExpected,revDescIndxExpected+14,revDescIndx->getPointer())); - //! [CppSnippet_MEDCouplingUMesh_buildDescendingConnectivity_2] - desc->decrRef(); - descIndx->decrRef(); - revDesc->decrRef(); - revDescIndx->decrRef(); - mesh2->decrRef(); -} - -void CppExample_MEDCouplingUMesh_getReverseNodalConnectivity() -{ - using namespace ParaMEDMEM; - //! [CppSnippet_MEDCouplingUMesh_getReverseNodalConnectivity_1] - MEDCouplingAutoRefCountObjectPtr mesh=MEDCouplingUMesh::New(); - mesh->setMeshDimension(2); - mesh->allocateCells(5); - const int conn[18]={0,3,4,1, 1,4,2, 4,5,2, 6,7,4,3, 7,8,5,4}; - mesh->insertNextCell(INTERP_KERNEL::NORM_QUAD4,4,conn); // 0 - mesh->insertNextCell(INTERP_KERNEL::NORM_TRI3,3, conn+4); // 1 - mesh->insertNextCell(INTERP_KERNEL::NORM_TRI3,3, conn+7); // 2 - mesh->insertNextCell(INTERP_KERNEL::NORM_QUAD4,4,conn+10); // 3 - mesh->insertNextCell(INTERP_KERNEL::NORM_QUAD4,4,conn+14); // 4 - mesh->finishInsertingCells(); - MEDCouplingAutoRefCountObjectPtr coordsArr=DataArrayDouble::New(); - coordsArr->alloc(9,2); - const double coords[18]={-0.3,-0.3, 0.2,-0.3, 0.7,-0.3, -0.3,0.2, 0.2,0.2, 0.7,0.2, -0.3,0.7, 0.2,0.7, 0.7,0.7 }; - std::copy(coords,coords+18,coordsArr->getPointer()); - mesh->setCoords(coordsArr); - //! [CppSnippet_MEDCouplingUMesh_getReverseNodalConnectivity_1] - //! [CppSnippet_MEDCouplingUMesh_getReverseNodalConnectivity_2] - DataArrayInt *revNodal=DataArrayInt::New(); - DataArrayInt *revNodalIndx=DataArrayInt::New(); - mesh->getReverseNodalConnectivity(revNodal,revNodalIndx); - const int revNodalExpected[18]={0,0,1,1,2,0,3,0,1,2,3,4,2,4,3,3,4,4}; - const int revNodalIndexExpected[10]={0,1,3,5,7,12,14,15,17,18}; - CPPUNIT_ASSERT(std::equal(revNodalExpected,revNodalExpected+18,revNodal->getPointer())); - CPPUNIT_ASSERT(std::equal(revNodalIndexExpected,revNodalIndexExpected+10,revNodalIndx->getPointer())); - //! [CppSnippet_MEDCouplingUMesh_getReverseNodalConnectivity_2] - revNodal->decrRef(); - revNodalIndx->decrRef(); -} - -void CppExample_MEDCouplingUMesh_checkDeepEquivalWith() -{ - using namespace ParaMEDMEM; - //! [CppSnippet_MEDCouplingUMesh_checkDeepEquivalWith_1] - // mesh 1 - MEDCouplingUMesh *mesh1=MEDCouplingUMesh::New(); - const double coords[4*2]={0.0,0.0, // #0 - 1.0,0.0, // #1 - 1.0,1.0, // #2 - 0.0,1.0}; // #3 - { - mesh1->setMeshDimension(2); - MEDCouplingAutoRefCountObjectPtr coordsArr=DataArrayDouble::New(); - coordsArr->useExternalArrayWithRWAccess( coords, 4, 2 ); - mesh1->setCoords(coordsArr); - mesh1->allocateCells(2); - const int conn[6]={0,1,2, 1,2,3}; - mesh1->insertNextCell(INTERP_KERNEL::NORM_TRI3,3, conn+0); // #0 - mesh1->insertNextCell(INTERP_KERNEL::NORM_TRI3,3, conn+3); // #1 - mesh1->finishInsertingCells(); - } - // mesh 2 - MEDCouplingUMesh *mesh2=MEDCouplingUMesh::New(); - const double coords2[4*2]={0.0,1.0, // #0 = #3 - 0.0,0.0, // #1 = #0 - 1.0,0.0, // #2 = #1 - 1.0,1.001}; // #3 ~ #2 - { - mesh2->setMeshDimension(2); - MEDCouplingAutoRefCountObjectPtr coordsArr=DataArrayDouble::New(); - coordsArr->useExternalArrayWithRWAccess( coords2, 4, 2 ); - mesh2->setCoords(coordsArr); - mesh2->allocateCells(2); - const int conn[6]={2,3,0, 3,1,2}; - mesh2->insertNextCell(INTERP_KERNEL::NORM_TRI3,3, conn+0); // #0 = #1 - mesh2->insertNextCell(INTERP_KERNEL::NORM_TRI3,3, conn+3); // #1 ~ #0 - mesh2->finishInsertingCells(); - } - //! [CppSnippet_MEDCouplingUMesh_checkDeepEquivalWith_1] - //! [CppSnippet_MEDCouplingUMesh_checkDeepEquivalWith_2] - int cellCompPol = 1; // "permuted same orientation" - policy of medium severity - DataArrayInt *nOld2New, *cOld2New; - mesh1->checkDeepEquivalWith( mesh2, cellCompPol, 0.002, cOld2New, nOld2New ); - const int nOld2NewExpected[4] = { 3, 0, 1, 2 }; - const int cOld2NewExpected[2] = { 1, 0 }; - CPPUNIT_ASSERT(std::equal(nOld2NewExpected,nOld2NewExpected+4,nOld2New->getConstPointer())); - CPPUNIT_ASSERT(std::equal(cOld2NewExpected,cOld2NewExpected+2,cOld2New->getConstPointer())); - //! [CppSnippet_MEDCouplingUMesh_checkDeepEquivalWith_2] - //! [CppSnippet_MEDCouplingUMesh_checkDeepEquivalWith_3] - cOld2New->decrRef(); // else memory leaks - CPPUNIT_ASSERT_THROW ( mesh1->checkDeepEquivalOnSameNodesWith( mesh2, cellCompPol, 0.002, cOld2New ), INTERP_KERNEL::Exception ); - mesh2->setCoords( mesh1->getCoords() ); // make meshes share the same coordinates array - mesh2->allocateCells(2); - const int conn[6]={1,2,3, 1,0,2}; - mesh2->insertNextCell(INTERP_KERNEL::NORM_TRI3,3,conn+0); // #0 = #1 - mesh2->insertNextCell(INTERP_KERNEL::NORM_TRI3,3,conn+3); // #1 ~ #0 - mesh2->finishInsertingCells(); - cellCompPol = 2; // the weakest policy - mesh1->checkDeepEquivalOnSameNodesWith( mesh2, cellCompPol, 0, cOld2New ); - //! [CppSnippet_MEDCouplingUMesh_checkDeepEquivalWith_3] - nOld2New->decrRef(); - cOld2New->decrRef(); - mesh1->decrRef(); - mesh2->decrRef(); -} - -void CppExample_MEDCouplingPointSet_scale() -{ - using namespace ParaMEDMEM; - //! [CppSnippet_MEDCouplingPointSet_scale_1] - double coords[4*2]={0.0,0.0, 1.0,0.0, 1.0,1.0, 0.0,1.0}; // 2D coordinates of 4 nodes - MEDCouplingAutoRefCountObjectPtr coordsArr=DataArrayDouble::New(); - coordsArr->useExternalArrayWithRWAccess(coords, 4,2); - MEDCouplingAutoRefCountObjectPtr mesh=MEDCouplingUMesh::New(); - mesh->setCoords(coordsArr); - DataArrayDouble *initCoords = coordsArr->deepCpy(); - //! [CppSnippet_MEDCouplingPointSet_scale_1] - //! [CppSnippet_MEDCouplingPointSet_scale_2] - const double center[2] = {0.,0.}; - const double factor = 2.; - mesh->scale( center, factor ); - //! [CppSnippet_MEDCouplingPointSet_scale_2] - //! [CppSnippet_MEDCouplingPointSet_scale_3] - const DataArrayDouble * coordsArr2 = mesh->getCoords(); - CPPUNIT_ASSERT( coordsArr2->isEqualWithoutConsideringStr( *initCoords, 1.0 )); - CPPUNIT_ASSERT( !coordsArr2->isEqualWithoutConsideringStr( *initCoords, 0.9 )); - // release data - initCoords->decrRef(); - //! [CppSnippet_MEDCouplingPointSet_scale_3] -} - -void CppExample_MEDCouplingPointSet_translate() -{ - using namespace ParaMEDMEM; - //! [CppSnippet_MEDCouplingPointSet_translate_1] - double coords[4*2]={0.0,0.0, 1.0,0.0, 1.0,1.0, 0.0,1.0}; // 2D coordinates of 4 nodes - MEDCouplingAutoRefCountObjectPtr coordsArr=DataArrayDouble::New(); - coordsArr->useExternalArrayWithRWAccess(coords, 4,2); - MEDCouplingAutoRefCountObjectPtr mesh=MEDCouplingUMesh::New(); - mesh->setCoords(coordsArr); - DataArrayDouble *initCoords = coordsArr->deepCpy(); - //! [CppSnippet_MEDCouplingPointSet_translate_1] - //! [CppSnippet_MEDCouplingPointSet_translate_2] - double vector[2] = {1.,1.}; - mesh->translate( vector ); - //! [CppSnippet_MEDCouplingPointSet_translate_2] - //! [CppSnippet_MEDCouplingPointSet_translate_3] - const DataArrayDouble * coordsArr2 = mesh->getCoords(); - CPPUNIT_ASSERT( coordsArr2->isEqualWithoutConsideringStr( *initCoords, 1.0 )); - CPPUNIT_ASSERT( !coordsArr2->isEqualWithoutConsideringStr( *initCoords, 0.9 )); - // release data - initCoords->decrRef(); - //! [CppSnippet_MEDCouplingPointSet_translate_3] -} - -void CppExample_MEDCouplingPointSet_rotate() -{ - using namespace ParaMEDMEM; - //! [CppSnippet_MEDCouplingPointSet_rotate_1] - double coords[4*2]={0.0,0.0, 0.1,0.0, 0.1,0.1, 0.0,0.1}; // 2D coordinates of 4 nodes - double coordsOrig[4*2]; - std::copy(coords,coords+sizeof(coords)/sizeof(double),coordsOrig);//keep tracks of initial values - MEDCouplingAutoRefCountObjectPtr coordsArr=DataArrayDouble::New(); - coordsArr->useExternalArrayWithRWAccess(coords, 4,2); - MEDCouplingAutoRefCountObjectPtr mesh=MEDCouplingUMesh::New(); - mesh->setCoords(coordsArr); - //! [CppSnippet_MEDCouplingPointSet_rotate_1] - //! [CppSnippet_MEDCouplingPointSet_rotate_2] - double center[3] = {0.,0.,0.}; // it suits for 2D as well - double vector[3] = {0.,0.,1.}; // it is not used in 2D - mesh->rotate( center, vector, -M_PI/2); // warning here C++ 'coords' array (defined above) has been modified ! - //! [CppSnippet_MEDCouplingPointSet_rotate_2] - //! [CppSnippet_MEDCouplingPointSet_rotate_3] - mesh->changeSpaceDimension(3); - mesh->rotate( center, vector, +M_PI/2); - //! [CppSnippet_MEDCouplingPointSet_rotate_3] - //! [CppSnippet_MEDCouplingPointSet_rotate_4] - mesh->changeSpaceDimension(2); - const DataArrayDouble * coordsArr2 = mesh->getCoords(); - coordsArr->useExternalArrayWithRWAccess(coordsOrig, 4,2); - CPPUNIT_ASSERT( coordsArr2->isEqualWithoutConsideringStr( *coordsArr, 1e-13 )); - //! [CppSnippet_MEDCouplingPointSet_rotate_4] -} - -void CppExample_MEDCouplingPointSet_getBoundingBox() -{ - using namespace ParaMEDMEM; - //! [CppSnippet_MEDCouplingPointSet_getBoundingBox_1] - double cc[2*3]={0.0, 0.1, 0.2, // 3D coordinates of 2 nodes - 2.0, 2.1, 2.2}; - MEDCouplingAutoRefCountObjectPtr coordsArr=DataArrayDouble::New(); - coordsArr->useExternalArrayWithRWAccess(cc, 2,3); - MEDCouplingAutoRefCountObjectPtr mesh=MEDCouplingUMesh::New(); - mesh->setCoords(coordsArr); - //! [CppSnippet_MEDCouplingPointSet_getBoundingBox_1] - //! [CppSnippet_MEDCouplingPointSet_getBoundingBox_2] - double bbox[3][2]; - mesh->getBoundingBox( (double*) bbox ); - - // check the returned coordinates of extremum points of the bounding box - for ( int i = 0; i < 2; ++i ) // point id - for ( int j = 0; j < 3; ++j ) // component - CPPUNIT_ASSERT_DOUBLES_EQUAL( cc[ i*3 + j ], bbox[j][i], 1e-13); - //! [CppSnippet_MEDCouplingPointSet_getBoundingBox_2] -} - -void CppExample_MEDCouplingPointSet_getNodeIdsNearPoint() -{ - using namespace ParaMEDMEM; - //! [CppSnippet_MEDCouplingPointSet_getNodeIdsNearPoint_1] - // 2D coordinates of 5 nodes - double coords[5*2]={0.3,-0.30001, // #0 - 0.2,-0.3, // #1 - 0.3,-0.30002, // #2 - 1.1,0.0, // #3 - 0.3,-0.30003};// #4 - MEDCouplingAutoRefCountObjectPtr coordsArr=DataArrayDouble::New(); - coordsArr->useExternalArrayWithRWAccess(coords, 5,2); - MEDCouplingAutoRefCountObjectPtr mesh=MEDCouplingUMesh::New(); - mesh->setCoords(coordsArr); - //! [CppSnippet_MEDCouplingPointSet_getNodeIdsNearPoint_1] - //! [CppSnippet_MEDCouplingPointSet_getNodeIdsNearPoint_2] - double point [2]={0.3, -0.3}; // point close to nodes #0, #2 and #4 - DataArrayInt *ids = mesh->getNodeIdsNearPoint(point, 1e-2); - - // check found ids - const int expectedIDs[3] = {0,2,4}; - DataArrayInt * okIDs = ids->getIdsEqualList ( expectedIDs, expectedIDs+3 ); - CPPUNIT_ASSERT_EQUAL(3, okIDs->getNumberOfTuples()); - - // release data - ids->decrRef(); - okIDs->decrRef(); - //! [CppSnippet_MEDCouplingPointSet_getNodeIdsNearPoint_2] -} -void CppExample_MEDCouplingPointSet_getNodeIdsNearPoints() -{ - using namespace ParaMEDMEM; - //! [CppSnippet_MEDCouplingPointSet_getNodeIdsNearPoints_1] - // 2D coordinates of 7 nodes - double coords[7*2]={0.3,-0.301, // #0 - 0.2,-0.3, // #1 - 0.3,-0.302, // #2 - 1.1,0.0, // #3 - 1.1,0.0, // #4 - 1.1,0.002, // #5 - 0.3,-0.303};// #6 - MEDCouplingAutoRefCountObjectPtr coordsArr=DataArrayDouble::New(); - coordsArr->useExternalArrayWithRWAccess(coords, 7,2); - MEDCouplingAutoRefCountObjectPtr mesh=MEDCouplingUMesh::New(); - mesh->setCoords(coordsArr); - //! [CppSnippet_MEDCouplingPointSet_getNodeIdsNearPoints_1] - //! [CppSnippet_MEDCouplingPointSet_getNodeIdsNearPoints_2] - const int nbOfPoints = 3; - double points [nbOfPoints*2]={0.2,-0.30001, // ~ node #1 - 0.0, 0.0, - 1.1, 0.002}; // ~ nodes #3, #4 and #5 - DataArrayInt *ids, *idsIndex; - mesh->getNodeIdsNearPoints(points, nbOfPoints, 1e-1,ids,idsIndex); - - // check found ids (i.e. contents of 'ids' array) - const int expectedIDs[4] = {1, 3, 4, 5}; - DataArrayInt * okIDs = ids->getIdsEqualList ( expectedIDs, expectedIDs+4 ); - CPPUNIT_ASSERT_EQUAL(4, okIDs->getNumberOfTuples()); - - // release data - ids->decrRef(); - idsIndex->decrRef(); - okIDs->decrRef(); - //! [CppSnippet_MEDCouplingPointSet_getNodeIdsNearPoints_2] -} - -void CppExample_MEDCouplingPointSet_findCommonNodes() -{ - using namespace ParaMEDMEM; - //! [CppSnippet_MEDCouplingPointSet_findCommonNodes_1] - double coords[6*2]={0.3,-0.301, // 0 - 0.2,-0.3, // 1 - 0.3,-0.302, // 2 - 1.1,0.0, // 3 - 1.1,0.0, // 4 - 0.3,-0.303};// 5 - MEDCouplingAutoRefCountObjectPtr coordsArr=DataArrayDouble::New(); - coordsArr->useExternalArrayWithRWAccess(coords, 6,2); - MEDCouplingAutoRefCountObjectPtr mesh=MEDCouplingUMesh::New(); - mesh->setCoords(coordsArr); - //! [CppSnippet_MEDCouplingPointSet_findCommonNodes_1] - //! [CppSnippet_MEDCouplingPointSet_findCommonNodes_2] - DataArrayInt *com, *comI; - mesh->findCommonNodes(1e-13,-1,com,comI); - CPPUNIT_ASSERT_EQUAL(2, com->getNumberOfTuples()); - com->decrRef(); comI->decrRef(); - mesh->findCommonNodes(0.004,-1,com,comI); - CPPUNIT_ASSERT_EQUAL(5, com->getNumberOfTuples()); - //! [CppSnippet_MEDCouplingPointSet_findCommonNodes_2] - com->decrRef(); comI->decrRef(); -} - -void CppExample_MEDCouplingPointSet_getCoordinatesOfNode() -{ - using namespace ParaMEDMEM; - //! [CppSnippet_MEDCouplingPointSet_getCoordinatesOfNode_1] - double coords[18]={-0.3,-0.3, 0.2,-0.3, 0.7,-0.3}; - MEDCouplingAutoRefCountObjectPtr coordsArr=DataArrayDouble::New(); - coordsArr->useExternalArrayWithRWAccess(coords, 3,2); - MEDCouplingAutoRefCountObjectPtr mesh=MEDCouplingUMesh::New(); - mesh->setCoords(coordsArr); - //! [CppSnippet_MEDCouplingPointSet_getCoordinatesOfNode_1] - //! [CppSnippet_MEDCouplingPointSet_getCoordinatesOfNode_2] - std::vector coords2; - mesh->getCoordinatesOfNode(1,coords2); - CPPUNIT_ASSERT_DOUBLES_EQUAL(coords[2],coords2[0],1e-13); - CPPUNIT_ASSERT_DOUBLES_EQUAL(coords[3],coords2[1],1e-13); - //! [CppSnippet_MEDCouplingPointSet_getCoordinatesOfNode_2] -} - -void CppExample_DataArrayInt_buildPermutationArr() -{ - using namespace ParaMEDMEM; - //! [CppSnippet_DataArrayInt_buildPermutationArr_1] - DataArrayInt *a=DataArrayInt::New(); - const int vala[5]={4,5,6,7,8}; - a->alloc(5,1); - std::copy(vala,vala+5,a->getPointer()); - DataArrayInt *b=DataArrayInt::New(); - const int valb[5]={5,4,8,6,7}; - b->alloc(5,1); - std::copy(valb,valb+5,b->getPointer()); - DataArrayInt *c=a->buildPermutationArr(*b); - //! [CppSnippet_DataArrayInt_buildPermutationArr_1] - const int expect1[5]={1,0,4,2,3}; - CPPUNIT_ASSERT_EQUAL(5,c->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(1,c->getNumberOfComponents()); - CPPUNIT_ASSERT(std::equal(expect1,expect1+5,c->getConstPointer())); - CPPUNIT_ASSERT(a->isEqualWithoutConsideringStrAndOrder(*b)); - a->decrRef(); - b->decrRef(); - c->decrRef(); -} - -void CppExample_DataArrayInt_invertArrayO2N2N2O() -{ - using namespace ParaMEDMEM; - //! [CppSnippet_DataArrayInt_invertArrayO2N2N2O_1] - const int arr1[6]={2,0,4,1,5,3}; - DataArrayInt *da=DataArrayInt::New(); - da->alloc(6,1); - std::copy(arr1,arr1+6,da->getPointer()); - DataArrayInt *da2=da->invertArrayO2N2N2O(6); - const int expected1[6]={1,3,0,5,2,4}; - for(int i=0;i<6;i++) - CPPUNIT_ASSERT_EQUAL(expected1[i],da2->getIJ(i,0)); - //! [CppSnippet_DataArrayInt_invertArrayO2N2N2O_1] - da->decrRef(); - da2->decrRef(); -} - -void CppExample_DataArrayInt_invertArrayN2O2O2N() -{ - using namespace ParaMEDMEM; - //! [CppSnippet_DataArrayInt_invertArrayN2O2O2N_1] - const int arr1[6]={2,0,4,1,5,3}; - DataArrayInt *da=DataArrayInt::New(); - da->alloc(6,1); - std::copy(arr1,arr1+6,da->getPointer()); - DataArrayInt *da2=da->invertArrayN2O2O2N(6); - const int expected1[6]={1,3,0,5,2,4}; - for(int i=0;i<6;i++) - CPPUNIT_ASSERT_EQUAL(expected1[i],da2->getIJ(i,0)); - //! [CppSnippet_DataArrayInt_invertArrayN2O2O2N_1] - da->decrRef(); - da2->decrRef(); -} - -void CppExample_DataArrayDouble_getIdsInRange() -{ - using namespace ParaMEDMEM; - //! [CppSnippet_DataArrayDouble_getIdsInRange_1] - DataArrayDouble *da=DataArrayDouble::New(); - da->alloc(10,1); - da->iota(); - - DataArrayInt* da2 = da->getIdsInRange( 2.5, 6 ); - //! [CppSnippet_DataArrayDouble_getIdsInRange_1] - da->decrRef(); - da2->decrRef(); -} - -void CppExample_DataArrayDouble_findCommonTuples() -{ - using namespace ParaMEDMEM; - //! [CppSnippet_DataArrayDouble_findCommonTuples1] - DataArrayDouble *da=DataArrayDouble::New(); - da->alloc(6,2); - const double array2[12]={2.3,2.3, // 0 - 1.2,1.2, // 1 - 1.3,1.3, // 2 - 2.3,2.3, // 3 - 2.301, // 4 - 2.301, // 5 - 0.8,0.8};// 6 - std::copy(array2,array2+12,da->getPointer()); - //! [CppSnippet_DataArrayDouble_findCommonTuples1] - //! [CppSnippet_DataArrayDouble_findCommonTuples2] - DataArrayInt *c=0,*cI=0; - da->findCommonTuples(1.01e-1,-1,c,cI); - - const int expected3[5]={0,3,4,1,2}; - const int expected4[3]={0,3,5}; - CPPUNIT_ASSERT(std::equal(expected3,expected3+5,c->getConstPointer())); - CPPUNIT_ASSERT(std::equal(expected4,expected4+3,cI->getConstPointer())); - c->decrRef(); - cI->decrRef(); - da->decrRef(); - //! [CppSnippet_DataArrayDouble_findCommonTuples2] -} - -void CppExample_DataArrayDouble_Meld1() -{ - using namespace ParaMEDMEM; - //! [CppSnippet_DataArrayDouble_Meld1_1] - const int sameNbTuples = 7; - - DataArrayDouble *da1=DataArrayDouble::New(); - da1->alloc(sameNbTuples,2); - da1->fillWithValue(7.); - da1->setInfoOnComponent(0,"c0da1"); - da1->setInfoOnComponent(1,"c1da1"); - - DataArrayDouble *da2=DataArrayDouble::New(); - da2->alloc(sameNbTuples,1); - da2->iota(0.); - da2->setInfoOnComponent(0,"c0da2"); - - da1->meldWith(da2); - //! [CppSnippet_DataArrayDouble_Meld1_1] - //! [CppSnippet_DataArrayDouble_Meld1_2] - da1->decrRef(); - da2->decrRef(); - //! [CppSnippet_DataArrayDouble_Meld1_2] -} - -void CppExample_DataArrayInt_Meld1() -{ - using namespace ParaMEDMEM; - //! [CppSnippet_DataArrayInt_Meld1_1] - const int sameNbTuples = 7; - - DataArrayInt *da1=DataArrayInt::New(); - da1->alloc(sameNbTuples,2); - da1->fillWithValue(7); - da1->setInfoOnComponent(0,"c0da1"); - da1->setInfoOnComponent(1,"c1da1"); - - DataArrayInt *da2=DataArrayInt::New(); - da2->alloc(sameNbTuples,1); - da2->iota(0); - da2->setInfoOnComponent(0,"c0da2"); - - da1->meldWith(da2); - //! [CppSnippet_DataArrayInt_Meld1_1] - //! [CppSnippet_DataArrayInt_Meld1_2] - da1->decrRef(); - da2->decrRef(); - //! [CppSnippet_DataArrayInt_Meld1_2] -} - -void CppExampleFieldDoubleBuildSubPart1() -{ - //! [CppSnippetFieldDoubleBuildSubPart1_1] - ParaMEDMEM::MEDCouplingUMesh *mesh1=ParaMEDMEM::MEDCouplingBasicsTest::build2DTargetMesh_1(); - ParaMEDMEM::MEDCouplingFieldDouble *f1=ParaMEDMEM::MEDCouplingFieldDouble::New(ParaMEDMEM::ON_CELLS,ParaMEDMEM::ONE_TIME); - f1->setTime(2.3,5,6); - f1->setMesh(mesh1); - ParaMEDMEM::DataArrayDouble *array=ParaMEDMEM::DataArrayDouble::New(); - array->alloc(mesh1->getNumberOfCells(),2); - const double arr1[10]={3.,103.,4.,104.,5.,105.,6.,106.,7.,107.}; - std::copy(arr1,arr1+10,array->getPointer()); - f1->setArray(array); - array->decrRef(); - //! [CppSnippetFieldDoubleBuildSubPart1_1] - //! [CppSnippetFieldDoubleBuildSubPart1_2] - const int part1[3]={2,1,4}; - ParaMEDMEM::MEDCouplingFieldDouble *f2=f1->buildSubPart(part1,part1+3); - //! [CppSnippetFieldDoubleBuildSubPart1_2] - f2->zipCoords(); - CPPUNIT_ASSERT_EQUAL(3,f2->getMesh()->getNumberOfCells()); - CPPUNIT_ASSERT_EQUAL(6,f2->getMesh()->getNumberOfNodes()); - CPPUNIT_ASSERT_EQUAL(2,f2->getMesh()->getSpaceDimension()); - CPPUNIT_ASSERT_EQUAL(2,f2->getMesh()->getMeshDimension()); - ParaMEDMEM::MEDCouplingUMesh *m2C=dynamic_cast(const_cast(f2->getMesh())); - CPPUNIT_ASSERT_EQUAL(13,m2C->getMeshLength()); - const double expected2[12]={0.2, -0.3, 0.7, -0.3, 0.2, 0.2, 0.7, 0.2, 0.2, 0.7, 0.7, 0.7}; - for(int i=0;i<12;i++) - CPPUNIT_ASSERT_DOUBLES_EQUAL(expected2[i],m2C->getCoords()->getIJ(0,i),1.e-12); - const double expected3[13]={3,2,3,1,3,0,2,1,4,4,5,3,2}; - CPPUNIT_ASSERT(std::equal(expected3,expected3+13,m2C->getNodalConnectivity()->getConstPointer())); - const double expected4[4]={0,4,8,13}; - CPPUNIT_ASSERT(std::equal(expected4,expected4+4,m2C->getNodalConnectivityIndex()->getConstPointer())); - f2->decrRef(); - f1->decrRef(); - //! [CppSnippetFieldDoubleBuildSubPart1_3] - f1=ParaMEDMEM::MEDCouplingFieldDouble::New(ParaMEDMEM::ON_NODES,ParaMEDMEM::ONE_TIME); - f1->setTime(2.3,5,6); - f1->setMesh(mesh1); - array=ParaMEDMEM::DataArrayDouble::New(); - array->alloc(mesh1->getNumberOfNodes(),2); - const double arr2[18]={3.,103.,4.,104.,5.,105.,6.,106.,7.,107.,8.,108.,9.,109.,10.,110.,11.,111.}; - std::copy(arr2,arr2+18,array->getPointer()); - f1->setArray(array); - array->decrRef(); - //! [CppSnippetFieldDoubleBuildSubPart1_3] - //! [CppSnippetFieldDoubleBuildSubPart1_4] - const int part2[2]={1,2}; - f2=f1->buildSubPart(part2,part2+2); - //! [CppSnippetFieldDoubleBuildSubPart1_4] - f2->decrRef(); - //idem previous because nodes of cell#4 are not fully present in part3 - const int part3[2]={1,2}; - ParaMEDMEM::DataArrayInt *arrr=ParaMEDMEM::DataArrayInt::New(); - arrr->alloc(2,1); - std::copy(part3,part3+2,arrr->getPointer()); - f2=f1->buildSubPart(arrr); - arrr->decrRef(); - f2->decrRef(); - // - const int part4[3]={1,2,4}; - f2=f1->buildSubPart(part4,part4+3); - f2->decrRef(); - // - f1->decrRef(); - mesh1->decrRef(); - return; -} - -void CppSnippetUMeshStdBuild1() -{ - //! [CppSnippetUMeshStdBuild1_1] - double coords[27]={-0.3,-0.3,0., 0.2,-0.3,0., 0.7,-0.3,0., -0.3,0.2,0., 0.2,0.2,0., - 0.7,0.2,0., -0.3,0.7,0., 0.2,0.7,0., 0.7,0.7,0. }; - int nodalConnPerCell[18]={0,3,4,1, 1,4,2, 4,5,2, 6,7,4,3, 7,8,5,4}; - //! [CppSnippetUMeshStdBuild1_1] - //! [CppSnippetUMeshStdBuild1_2] - ParaMEDMEM::MEDCouplingUMesh *mesh=ParaMEDMEM::MEDCouplingUMesh::New("My2DMesh",2); - //! [CppSnippetUMeshStdBuild1_2] - //! [CppSnippetUMeshStdBuild1_3] - mesh->allocateCells(5);//You can put more than 5 if you want but not less. - mesh->insertNextCell(INTERP_KERNEL::NORM_QUAD4,4,nodalConnPerCell); - mesh->insertNextCell(INTERP_KERNEL::NORM_TRI3,3,nodalConnPerCell+4); - mesh->insertNextCell(INTERP_KERNEL::NORM_TRI3,3,nodalConnPerCell+7); - mesh->insertNextCell(INTERP_KERNEL::NORM_QUAD4,4,nodalConnPerCell+10); - mesh->insertNextCell(INTERP_KERNEL::NORM_QUAD4,4,nodalConnPerCell+14); - mesh->finishInsertingCells(); - //! [CppSnippetUMeshStdBuild1_3] - //! [CppSnippetUMeshStdBuild1_4] - ParaMEDMEM::DataArrayDouble *coordsArr=ParaMEDMEM::DataArrayDouble::New(); - coordsArr->alloc(9,3);//here coordsArr are declared to have 3 components, mesh will deduce that its spaceDim==3. - std::copy(coords,coords+27,coordsArr->getPointer()); - mesh->setCoords(coordsArr);//coordsArr contains 9 tuples, that is to say mesh contains 9 nodes. - coordsArr->decrRef(); - //! [CppSnippetUMeshStdBuild1_4] - mesh->checkCoherency(); - //! [CppSnippetUMeshStdBuild1_5] - mesh->decrRef(); - //! [CppSnippetUMeshStdBuild1_5] -} - -void CppSnippetCMeshStdBuild1() -{ - //! [CppSnippetCMeshStdBuild1_1] - double XCoords[9]={-0.3,0.,0.1,0.3,0.45,0.47,0.49,1.,1.22}; - double YCoords[7]={0.,0.1,0.37,0.45,0.47,0.49,1.007}; - ParaMEDMEM::DataArrayDouble *arrX=ParaMEDMEM::DataArrayDouble::New(); - arrX->alloc(9,1); - std::copy(XCoords,XCoords+9,arrX->getPointer()); - arrX->setInfoOnComponent(0,"X [m]"); - ParaMEDMEM::DataArrayDouble *arrY=ParaMEDMEM::DataArrayDouble::New(); - arrY->alloc(7,1); - std::copy(YCoords,YCoords+7,arrY->getPointer()); - arrY->setInfoOnComponent(0,"Y [m]"); - //! [CppSnippetCMeshStdBuild1_1] - //! [CppSnippetCMeshStdBuild1_2] - ParaMEDMEM::MEDCouplingCMesh *mesh=ParaMEDMEM::MEDCouplingCMesh::New("My2D_CMesh"); - mesh->setCoords(arrX,arrY); - arrX->decrRef(); - arrY->decrRef(); - //! [CppSnippetCMeshStdBuild1_2] - //! [CppSnippetCMeshStdBuild1_3] - CPPUNIT_ASSERT_EQUAL(8*6,mesh->getNumberOfCells()); - CPPUNIT_ASSERT_EQUAL(9*7,mesh->getNumberOfNodes()); - CPPUNIT_ASSERT_EQUAL(2,mesh->getSpaceDimension()); - CPPUNIT_ASSERT_EQUAL(2,mesh->getMeshDimension()); - //! [CppSnippetCMeshStdBuild1_3] - mesh->decrRef(); - mesh=ParaMEDMEM::MEDCouplingCMesh::New("My2D_CMesh"); - arrX=ParaMEDMEM::DataArrayDouble::New(); arrX->alloc(9,1); std::copy(XCoords,XCoords+9,arrX->getPointer()); arrX->setInfoOnComponent(0,"X [m]"); - arrY=ParaMEDMEM::DataArrayDouble::New(); arrY->alloc(7,1); std::copy(YCoords,YCoords+7,arrY->getPointer()); arrY->setInfoOnComponent(0,"Y [m]"); - //! [CppSnippetCMeshStdBuild1_2bis] - mesh->setCoordsAt(0,arrX); - arrX->decrRef(); - mesh->setCoordsAt(1,arrY); - arrY->decrRef(); - //! [CppSnippetCMeshStdBuild1_2bis] - CPPUNIT_ASSERT_EQUAL(8*6,mesh->getNumberOfCells()); - CPPUNIT_ASSERT_EQUAL(9*7,mesh->getNumberOfNodes()); - CPPUNIT_ASSERT_EQUAL(2,mesh->getSpaceDimension()); - CPPUNIT_ASSERT_EQUAL(2,mesh->getMeshDimension()); - //! [CppSnippetCMeshStdBuild1_4] - mesh->decrRef(); - //! [CppSnippetCMeshStdBuild1_4] -} - -void CppSnippetUMeshAdvBuild1() -{ - //! [CppSnippetUMeshAdvBuild1_1] - double coords[27]={-0.3,-0.3,0., 0.2,-0.3,0., 0.7,-0.3,0., -0.3,0.2,0., 0.2,0.2,0., - 0.7,0.2,0., -0.3,0.7,0., 0.2,0.7,0., 0.7,0.7,0. }; - int nodalConnPerCell[23]={4,0,3,4,1, 3,1,4,2, 3,4,5,2, 4,6,7,4,3, 4,7,8,5,4}; - int nodalConnPerCellIndex[6]={0,5,9,13,18,23}; - //! [CppSnippetUMeshAdvBuild1_1] - //! [CppSnippetUMeshAdvBuild1_2] - ParaMEDMEM::MEDCouplingUMesh *mesh=ParaMEDMEM::MEDCouplingUMesh::New("My2DMesh",2); - //! [CppSnippetUMeshAdvBuild1_2] - //! [CppSnippetUMeshAdvBuild1_3] - ParaMEDMEM::DataArrayInt *nodalConn=ParaMEDMEM::DataArrayInt::New(); - nodalConn->alloc(23,1); - std::copy(nodalConnPerCell,nodalConnPerCell+23,nodalConn->getPointer()); - ParaMEDMEM::DataArrayInt *nodalConnI=ParaMEDMEM::DataArrayInt::New(); - nodalConnI->alloc(6,1); - std::copy(nodalConnPerCellIndex,nodalConnPerCellIndex+6,nodalConnI->getPointer()); - mesh->setConnectivity(nodalConn,nodalConnI,true); - nodalConn->decrRef();// nodalConn DataArrayInt instance is owned by mesh after call to setConnectivity method. No more need here -> decrRef() - nodalConnI->decrRef();// nodalConnI DataArrayInt instance is owned by mesh after call to setConnectivity method. No more need here -> decrRef() - //! [CppSnippetUMeshAdvBuild1_3] - //! [CppSnippetUMeshAdvBuild1_4] - ParaMEDMEM::DataArrayDouble *coordsArr=ParaMEDMEM::DataArrayDouble::New(); - coordsArr->alloc(9,3);//here coordsArr are declared to have 3 components, mesh will deduce that its spaceDim==3. - std::copy(coords,coords+27,coordsArr->getPointer()); - mesh->setCoords(coordsArr);//coordsArr contains 9 tuples, that is to say mesh contains 9 nodes. - coordsArr->decrRef(); - //! [CppSnippetUMeshAdvBuild1_4] - mesh->checkCoherency(); - //! [CppSnippetUMeshAdvBuild1_5] - mesh->decrRef(); - //! [CppSnippetUMeshAdvBuild1_5] -} - -void CppSnippetDataArrayBuild1() -{ - //! [CppSnippetDataArrayBuild1_0] - const int nbOfNodes=12; - double coords[3*nbOfNodes]={2.,3.,4.,3.,4.,5.,4.,5.,6.,5.,6.,7.,6.,7.,8.,7.,8.,9.,8.,9.,10.,9.,10.,11.,10.,11.,12.,11.,12.,13.,12.,13.,14.,13.,14.,15.}; - // - ParaMEDMEM::DataArrayDouble *coordsArr=0; - double *tmp=0; - //! [CppSnippetDataArrayBuild1_0] - // - //! [CppSnippetDataArrayBuild1_1] - coordsArr=ParaMEDMEM::DataArrayDouble::New(); - coordsArr->useArray(coords,false,ParaMEDMEM::CPP_DEALLOC,nbOfNodes,3); - //now use coordsArr as you need - //... - //coordsArr is no more useful here : release it - coordsArr->decrRef(); - //! [CppSnippetDataArrayBuild1_1] - //! [CppSnippetDataArrayBuild1_2] - coordsArr=ParaMEDMEM::DataArrayDouble::New(); - tmp=new double[3*nbOfNodes]; - std::copy(coords,coords+3*nbOfNodes,tmp); - coordsArr->useArray(tmp,true,ParaMEDMEM::CPP_DEALLOC,nbOfNodes,3); - //now use coordsArr as you need - //... - //coordsArr is no more useful, release it - coordsArr->decrRef(); - //! [CppSnippetDataArrayBuild1_2] - //! [CppSnippetDataArrayBuild1_3] - coordsArr=ParaMEDMEM::DataArrayDouble::New(); - tmp=(double *)malloc(3*nbOfNodes*sizeof(double)); - std::copy(coords,coords+3*nbOfNodes,tmp); - coordsArr->useArray(tmp,true,ParaMEDMEM::C_DEALLOC,nbOfNodes,3); - //now use coordsArr as you need - //... - //coordsArr is no more useful here : release it - coordsArr->decrRef(); - //! [CppSnippetDataArrayBuild1_3] - //! [CppSnippetDataArrayBuild1_4] - coordsArr=ParaMEDMEM::DataArrayDouble::New(); - coordsArr->alloc(nbOfNodes,3); - tmp=coordsArr->getPointer(); - std::copy(coords,coords+3*nbOfNodes,tmp); - coordsArr->declareAsNew();//you have modified data pointed by internal pointer notify object - //now use coordsArr as you need - //... - //coordsArr is no more useful here : release it - coordsArr->decrRef(); - //! [CppSnippetDataArrayBuild1_4] - coordsArr=ParaMEDMEM::DataArrayDouble::New(); - coordsArr->alloc(nbOfNodes,3); - tmp=coordsArr->getPointer(); - std::copy(coords,coords+3*nbOfNodes,tmp); - ParaMEDMEM::DataArrayDouble *coordsArrCpy=0; - //! [CppSnippetDataArrayBuild1_5] - coordsArrCpy=coordsArr->deepCpy(); - //! [CppSnippetDataArrayBuild1_5] - //! [CppSnippetDataArrayBuild1_6] - CPPUNIT_ASSERT(coordsArrCpy->isEqual(*coordsArr,1e-12)); - coordsArrCpy->setIJ(0,0,1000.); - CPPUNIT_ASSERT(!coordsArrCpy->isEqual(*coordsArr,1e-12));//coordsArrCpy only has been modified - //! [CppSnippetDataArrayBuild1_6] - //! [CppSnippetDataArrayBuild1_7] - coordsArrCpy->decrRef(); - //! [CppSnippetDataArrayBuild1_7] - //! [CppSnippetDataArrayBuild1_5bis] - coordsArrCpy=coordsArr->performCpy(true); - //! [CppSnippetDataArrayBuild1_5bis] - CPPUNIT_ASSERT(coordsArrCpy->isEqual(*coordsArr,1e-12)); - coordsArrCpy->setIJ(0,0,1000.); - CPPUNIT_ASSERT(!coordsArrCpy->isEqual(*coordsArr,1e-12));//coordsArrCpy only has been modified - coordsArrCpy->decrRef(); - //! [CppSnippetDataArrayBuild1_8] - coordsArrCpy=coordsArr->performCpy(false); - //! [CppSnippetDataArrayBuild1_8] - //! [CppSnippetDataArrayBuild1_9] - CPPUNIT_ASSERT(coordsArrCpy->isEqual(*coordsArr,1e-12)); - coordsArrCpy->setIJ(0,0,1000.); - CPPUNIT_ASSERT(coordsArrCpy->isEqual(*coordsArr,1e-12));//coordsArr and coordsArrCpy have been modified simultaneously - //! [CppSnippetDataArrayBuild1_9] - //! [CppSnippetDataArrayBuild1_10] - coordsArrCpy->decrRef(); - //! [CppSnippetDataArrayBuild1_10] - //! [CppSnippetDataArrayBuild1_11] - coordsArrCpy=ParaMEDMEM::DataArrayDouble::New(); - //! [CppSnippetDataArrayBuild1_11] - //! [CppSnippetDataArrayBuild1_12] - coordsArrCpy->cpyFrom(*coordsArr); - //! [CppSnippetDataArrayBuild1_12] - //! [CppSnippetDataArrayBuild1_13] - CPPUNIT_ASSERT(coordsArrCpy->isEqual(*coordsArr,1e-12)); - coordsArrCpy->setIJ(0,0,2000.); - CPPUNIT_ASSERT(!coordsArrCpy->isEqual(*coordsArr,1e-12));//coordsArrCpy only has been modified - //! [CppSnippetDataArrayBuild1_13] - //! [CppSnippetDataArrayBuild1_14] - coordsArrCpy->decrRef(); - //! [CppSnippetDataArrayBuild1_14] - coordsArr->decrRef(); - //! [CppSnippetDataArrayBuild1_14] -} - -void CppSnippetFieldDoubleBuild1() -{ - double XCoords[9]={-0.3,0.07,0.1,0.3,0.45,0.47,0.49,1.,1.22}; - double YCoords[7]={0.07,0.1,0.37,0.45,0.47,0.49,1.007}; - ParaMEDMEM::DataArrayDouble *arrX=ParaMEDMEM::DataArrayDouble::New(); arrX->alloc(9,1); std::copy(XCoords,XCoords+9,arrX->getPointer()); arrX->setInfoOnComponent(0,"X [m]"); - ParaMEDMEM::DataArrayDouble *arrY=ParaMEDMEM::DataArrayDouble::New(); arrY->alloc(7,1); std::copy(YCoords,YCoords+7,arrY->getPointer()); arrY->setInfoOnComponent(0,"Y [m]"); - ParaMEDMEM::MEDCouplingCMesh *mesh=ParaMEDMEM::MEDCouplingCMesh::New("My2D_CMesh"); - mesh->setCoords(arrX,arrY); arrX->decrRef(); arrY->decrRef(); - //! [CppSnippetFieldDoubleBuild1_1] - ParaMEDMEM::MEDCouplingFieldDouble* fieldOnCells=ParaMEDMEM::MEDCouplingFieldDouble::New(ParaMEDMEM::ON_CELLS,ParaMEDMEM::NO_TIME); - fieldOnCells->setName("MyTensorFieldOnCellNoTime"); - fieldOnCells->setMesh(mesh); - mesh->decrRef(); // no more need of mesh because mesh has been attached to fieldOnCells - ParaMEDMEM::DataArrayDouble *array=ParaMEDMEM::DataArrayDouble::New(); - array->alloc(fieldOnCells->getMesh()->getNumberOfCells(),9);//Implicitely fieldOnCells will be a 9 components field. - array->fillWithValue(7.); - fieldOnCells->setArray(array); - array->decrRef(); - // fieldOnCells is now usable - // ... - // fieldOnCells is no more useful here : release it - fieldOnCells->decrRef(); - //! [CppSnippetFieldDoubleBuild1_1] - arrX=ParaMEDMEM::DataArrayDouble::New(); arrX->alloc(9,1); std::copy(XCoords,XCoords+9,arrX->getPointer()); arrX->setInfoOnComponent(0,"X [m]"); - arrY=ParaMEDMEM::DataArrayDouble::New(); arrY->alloc(7,1); std::copy(YCoords,YCoords+7,arrY->getPointer()); arrY->setInfoOnComponent(0,"Y [m]"); - mesh=ParaMEDMEM::MEDCouplingCMesh::New("My2D_CMesh"); - mesh->setCoords(arrX,arrY); arrX->decrRef(); arrY->decrRef(); - //! [CppSnippetFieldDoubleBuild1_2] - ParaMEDMEM::MEDCouplingFieldDouble *f1=mesh->fillFromAnalytic(ParaMEDMEM::ON_CELLS,1,"x*x+y*y*3+2.*x");//f1 is scalar - ParaMEDMEM::MEDCouplingFieldDouble *f2=mesh->fillFromAnalytic(ParaMEDMEM::ON_CELLS,1,"cos(x+y/x)");//f2 is scalar too - ParaMEDMEM::MEDCouplingFieldDouble *f2bis=mesh->fillFromAnalytic(ParaMEDMEM::ON_CELLS,2,"x*x*IVec+3*y*JVec");//f2bis is a vectors field - ParaMEDMEM::MEDCouplingFieldDouble *f3=(*f1)+(*f2);//f3 scalar - ParaMEDMEM::MEDCouplingFieldDouble *f4=(*f3)/(*f2);//f4 scalar - f2bis->applyFunc(1,"sqrt(x*x+y*y)");//f2bis becomes scalar - ParaMEDMEM::MEDCouplingFieldDouble *f5=(*f2bis)*(*f4);//f5 scalar - const double pos1[2]={0.48,0.38}; - double res; - f4->getValueOn(pos1,&res);//f4 is scalar so the returned value is of size 1. - // ... - //! [CppSnippetFieldDoubleBuild1_2] - mesh->decrRef(); - //! [CppSnippetFieldDoubleBuild1_3] - // f1, f2, f2bis, f3, f4, f5 are no more useful here : release them - f1->decrRef(); - f2->decrRef(); - f2bis->decrRef(); - f3->decrRef(); - f4->decrRef(); - f5->decrRef(); - //! [CppSnippetFieldDoubleBuild1_3] -} - -void CppSnippetFieldDoubleBuild2() -{ - double XCoords[9]={-0.3,0.,0.1,0.3,0.45,0.47,0.49,1.,1.22}; - double YCoords[7]={0.,0.1,0.37,0.45,0.47,0.49,1.007}; - ParaMEDMEM::DataArrayDouble *arrX=ParaMEDMEM::DataArrayDouble::New(); arrX->alloc(9,1); std::copy(XCoords,XCoords+9,arrX->getPointer()); arrX->setInfoOnComponent(0,"X [m]"); - ParaMEDMEM::DataArrayDouble *arrY=ParaMEDMEM::DataArrayDouble::New(); arrY->alloc(7,1); std::copy(YCoords,YCoords+7,arrY->getPointer()); arrY->setInfoOnComponent(0,"Y [m]"); - ParaMEDMEM::MEDCouplingCMesh *mesh=ParaMEDMEM::MEDCouplingCMesh::New("My2D_CMesh"); - mesh->setCoords(arrX,arrY); arrX->decrRef(); arrY->decrRef(); - //! [CppSnippetFieldDoubleBuild2_1] - ParaMEDMEM::MEDCouplingFieldDouble* fieldOnNodes=ParaMEDMEM::MEDCouplingFieldDouble::New(ParaMEDMEM::ON_NODES,ParaMEDMEM::NO_TIME); - fieldOnNodes->setName("MyScalarFieldOnNodeNoTime"); - fieldOnNodes->setMesh(mesh); - mesh->decrRef(); // no more need of mesh because mesh has been attached to fieldOnNodes - ParaMEDMEM::DataArrayDouble *array=ParaMEDMEM::DataArrayDouble::New(); - array->alloc(fieldOnNodes->getMesh()->getNumberOfNodes(),1);//Implicitely fieldOnNodes will be a 1 component field. - array->fillWithValue(8.); - fieldOnNodes->setArray(array); - array->decrRef(); - // fieldOnNodes is now usable - // ... - // fieldOnNodes is no more useful here : release it - fieldOnNodes->decrRef(); - //! [CppSnippetFieldDoubleBuild2_1] -} - -void CppSnippetFieldDoubleBuild3() -{ - double XCoords[9]={-0.3,0.,0.1,0.3,0.45,0.47,0.49,1.,1.22}; - double YCoords[7]={0.,0.1,0.37,0.45,0.47,0.49,1.007}; - ParaMEDMEM::DataArrayDouble *arrX=ParaMEDMEM::DataArrayDouble::New(); arrX->alloc(9,1); std::copy(XCoords,XCoords+9,arrX->getPointer()); arrX->setInfoOnComponent(0,"X [m]"); - ParaMEDMEM::DataArrayDouble *arrY=ParaMEDMEM::DataArrayDouble::New(); arrY->alloc(7,1); std::copy(YCoords,YCoords+7,arrY->getPointer()); arrY->setInfoOnComponent(0,"Y [m]"); - ParaMEDMEM::MEDCouplingCMesh *mesh=ParaMEDMEM::MEDCouplingCMesh::New("My2D_CMesh"); - mesh->setCoords(arrX,arrY); arrX->decrRef(); arrY->decrRef(); - //! [CppSnippetFieldDoubleBuild3_1] - ParaMEDMEM::MEDCouplingFieldDouble* fieldOnCells=ParaMEDMEM::MEDCouplingFieldDouble::New(ParaMEDMEM::ON_CELLS,ParaMEDMEM::ONE_TIME); - fieldOnCells->setName("MyTensorFieldOnCellNoTime"); - fieldOnCells->setTimeUnit("ms"); // Time unit is ms. - fieldOnCells->setTime(4.22,2,-1); // Time attached is 4.22 ms, iteration id is 2 and order id (or sub iteration id) is -1 - fieldOnCells->setMesh(mesh); - mesh->decrRef(); // no more need of mesh because mesh has been attached to fieldOnCells - ParaMEDMEM::DataArrayDouble *array=ParaMEDMEM::DataArrayDouble::New(); - array->alloc(fieldOnCells->getMesh()->getNumberOfCells(),2);//Implicitely fieldOnCells will be a 2 components field. - array->fillWithValue(7.); - fieldOnCells->setArray(array); - array->decrRef(); - // fieldOnCells is now usable - // ... - // fieldOnCells is no more useful here : release it - fieldOnCells->decrRef(); - //! [CppSnippetFieldDoubleBuild3_1] -} - -void CppSnippetFieldDoubleBuild4() -{ - double XCoords[9]={-0.3,0.,0.1,0.3,0.45,0.47,0.49,1.,1.22}; - double YCoords[7]={0.,0.1,0.37,0.45,0.47,0.49,1.007}; - ParaMEDMEM::DataArrayDouble *arrX=ParaMEDMEM::DataArrayDouble::New(); arrX->alloc(9,1); std::copy(XCoords,XCoords+9,arrX->getPointer()); arrX->setInfoOnComponent(0,"X [m]"); - ParaMEDMEM::DataArrayDouble *arrY=ParaMEDMEM::DataArrayDouble::New(); arrY->alloc(7,1); std::copy(YCoords,YCoords+7,arrY->getPointer()); arrY->setInfoOnComponent(0,"Y [m]"); - ParaMEDMEM::MEDCouplingCMesh *mesh=ParaMEDMEM::MEDCouplingCMesh::New("My2D_CMesh"); - mesh->setCoords(arrX,arrY); arrX->decrRef(); arrY->decrRef(); - //! [CppSnippetFieldDoubleBuild4_1] - ParaMEDMEM::MEDCouplingFieldDouble* fieldOnNodes=ParaMEDMEM::MEDCouplingFieldDouble::New(ParaMEDMEM::ON_NODES,ParaMEDMEM::CONST_ON_TIME_INTERVAL); - fieldOnNodes->setName("MyVecFieldOnNodeWithConstTime"); - fieldOnNodes->setTimeUnit("ms"); // Time unit is ms. - fieldOnNodes->setStartTime(4.22,2,-1); - fieldOnNodes->setEndTime(6.44,4,-1); // fieldOnNodes is defined in interval [4.22 ms,6.44 ms] - fieldOnNodes->setMesh(mesh); - mesh->decrRef(); // no more need of mesh because mesh has been attached to fieldOnNodes - ParaMEDMEM::DataArrayDouble *array=ParaMEDMEM::DataArrayDouble::New(); - array->alloc(fieldOnNodes->getMesh()->getNumberOfNodes(),3);//Implicitely fieldOnNodes will be a 3 components field. - array->fillWithValue(8.); - fieldOnNodes->setArray(array); - array->decrRef(); - // fieldOnNodes is now usable - // ... - // fieldOnNodes is no more useful here : release it - fieldOnNodes->decrRef(); - //! [CppSnippetFieldDoubleBuild4_1] -} - -int main(int argc, char *argv[]) -{ - CppExample_MEDCouplingFieldDouble_WriteVTK(); - CppExample_MEDCouplingFieldDouble_MaxFields(); - CppExample_MEDCouplingFieldDouble_MergeFields(); - CppExample_MEDCouplingFieldDouble_substractInPlaceDM(); - CppExample_MEDCouplingFieldDouble_changeUnderlyingMesh(); - CppExample_MEDCouplingFieldDouble_applyFunc_same_nb_comp(); - CppExample_MEDCouplingFieldDouble_applyFunc3(); - CppExample_MEDCouplingFieldDouble_applyFunc2(); - CppExample_MEDCouplingFieldDouble_applyFunc(); - CppExample_MEDCouplingFieldDouble_applyFunc_val(); - CppExample_MEDCouplingFieldDouble_fillFromAnalytic3(); - CppExample_MEDCouplingFieldDouble_fillFromAnalytic2(); - CppExample_MEDCouplingFieldDouble_fillFromAnalytic(); - CppExample_MEDCouplingFieldDouble_fillFromAnalytic_c_func(); - CppExample_MEDCouplingFieldDouble_applyFunc_c_func(); - CppExample_MEDCouplingFieldDouble_getValueOn_time(); - CppExample_MEDCouplingFieldDouble_getValueOnMulti(); - CppExample_MEDCouplingFieldDouble_getValueOn(); - CppExample_MEDCouplingFieldDouble_getValueOnPos(); - CppExample_MEDCouplingFieldDouble_renumberNodes(); - CppExample_MEDCouplingFieldDouble_renumberCells(); - CppExample_MEDCouplingFieldDouble_buildNewTimeReprFromThis(); - CppExample_MEDCouplingMesh_fillFromAnalytic3(); - CppExample_MEDCouplingMesh_fillFromAnalytic2(); - CppExample_MEDCouplingMesh_fillFromAnalytic(); - CppExample_MEDCouplingCMesh_getCoordsAt(); - CppExample_MEDCouplingUMesh_areCellsIncludedIn(); - CppExample_MEDCouplingUMesh_findAndCorrectBadOriented3DExtrudedCells(); - CppExample_MEDCouplingUMesh_arePolyhedronsNotCorrectlyOriented(); - CppExample_MEDCouplingUMesh_are2DCellsNotCorrectlyOriented(); - CppExample_MEDCouplingUMesh_getCellsContainingPoints(); - CppExample_MEDCouplingUMesh_getCellsContainingPoint(); - CppExample_MEDCouplingUMesh_buildPartOrthogonalField(); - CppExample_MEDCouplingUMesh_getPartMeasureField(); - CppExample_MEDCouplingUMesh_getCellsInBoundingBox(); - CppExample_MEDCouplingUMesh_renumberNodesInConn(); - CppExample_MEDCouplingUMesh_renumberNodes(); - CppExample_MEDCouplingUMesh_findBoundaryNodes(); - CppExample_MEDCouplingUMesh_buildBoundaryMesh(); - CppExample_MEDCouplingUMesh_buildFacePartOfMySelfNode(); - CppExample_MEDCouplingUMesh_buildPartOfMySelfNode(); - CppExample_MEDCouplingUMesh_getCellIdsLyingOnNodes(); - CppExample_MEDCouplingUMesh_getCellIdsFullyIncludedInNodeIds(); - CppExample_MEDCouplingUMesh_buildPartOfMySelf(); - CppExample_MEDCouplingUMesh_mergeNodes(); - CppExample_MEDCouplingUMesh_zipConnectivityTraducer(); - CppExample_MEDCouplingUMesh_zipCoordsTraducer(); - CppExample_MEDCouplingUMesh_getNodeIdsInUse(); - CppExample_MEDCouplingUMesh_convertToPolyTypes(); - CppExample_MEDCouplingUMesh_buildDescendingConnectivity2(); - CppExample_MEDCouplingUMesh_buildDescendingConnectivity(); - CppExample_MEDCouplingUMesh_getReverseNodalConnectivity(); - CppExample_MEDCouplingUMesh_checkDeepEquivalWith(); - CppExample_MEDCouplingPointSet_scale(); - CppExample_MEDCouplingPointSet_translate(); - CppExample_MEDCouplingPointSet_rotate(); - CppExample_MEDCouplingPointSet_getBoundingBox(); - CppExample_MEDCouplingPointSet_getNodeIdsNearPoint(); - CppExample_MEDCouplingPointSet_getNodeIdsNearPoints(); - CppExample_MEDCouplingPointSet_findCommonNodes(); - CppExample_MEDCouplingPointSet_getCoordinatesOfNode(); - CppExample_DataArrayInt_buildPermutationArr(); - CppExample_DataArrayInt_invertArrayO2N2N2O(); - CppExample_DataArrayInt_invertArrayN2O2O2N(); - CppExample_DataArrayDouble_getIdsInRange(); - CppExample_DataArrayDouble_findCommonTuples(); - CppExample_DataArrayDouble_Meld1(); - CppExampleFieldDoubleBuildSubPart1(); - CppSnippetUMeshStdBuild1(); - CppSnippetUMeshAdvBuild1(); - CppSnippetDataArrayBuild1(); - CppSnippetCMeshStdBuild1(); - CppSnippetFieldDoubleBuild1(); - CppSnippetFieldDoubleBuild2(); - CppSnippetFieldDoubleBuild3(); - CppSnippetFieldDoubleBuild4(); - - return 0; -} diff --git a/src/MEDCoupling/Test/MEDCouplingRemapperTest.cxx b/src/MEDCoupling/Test/MEDCouplingRemapperTest.cxx deleted file mode 100644 index f8a2e37ba..000000000 --- a/src/MEDCoupling/Test/MEDCouplingRemapperTest.cxx +++ /dev/null @@ -1,1318 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 -// 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 "MEDCouplingRemapperTest.hxx" -#include "MEDCouplingUMesh.hxx" -#include "MEDCouplingExtrudedMesh.hxx" -#include "MEDCouplingFieldDouble.hxx" -#include "MEDCouplingFieldTemplate.hxx" -#include "MEDCouplingMemArray.hxx" -#include "MEDCouplingRemapper.hxx" - -#include "MEDCouplingBasicsTest.hxx" - -#include -#include - -using namespace ParaMEDMEM; - -void MEDCouplingRemapperTest::test2DInterpP0P0_1() -{ - MEDCouplingUMesh *sourceMesh=MEDCouplingBasicsTest::build2DSourceMesh_1(); - MEDCouplingUMesh *targetMesh=MEDCouplingBasicsTest::build2DTargetMesh_1(); - // - MEDCouplingRemapper remapper; - remapper.setPrecision(1e-12); - remapper.setIntersectionType(INTERP_KERNEL::Triangulation); - CPPUNIT_ASSERT_EQUAL(1,remapper.prepare(sourceMesh,targetMesh,"P0P0")); - - MEDCouplingFieldDouble *srcField=MEDCouplingFieldDouble::New(ON_CELLS); - srcField->setNature(ConservativeVolumic); - srcField->setMesh(sourceMesh); - DataArrayDouble *array=DataArrayDouble::New(); - array->alloc(sourceMesh->getNumberOfCells(),1); - srcField->setArray(array); - double *ptr=array->getPointer(); - for(int i=0;igetNumberOfCells();i++) - ptr[i]=(double)(i+7); - array->decrRef(); - MEDCouplingFieldDouble *trgfield=remapper.transferField(srcField,4.57); - const double *values=trgfield->getArray()->getConstPointer(); - const double valuesExpected[5]={7.5 ,7. ,7.,8.,7.5}; - CPPUNIT_ASSERT_EQUAL(5,trgfield->getArray()->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(1,trgfield->getArray()->getNumberOfComponents()); - for(int i0=0;i0<5;i0++) - CPPUNIT_ASSERT_DOUBLES_EQUAL(valuesExpected[i0],values[i0],1e-12); - trgfield->decrRef(); - // - srcField->setNature(IntegralGlobConstraint); - trgfield=remapper.transferField(srcField,4.57); - values=trgfield->getArray()->getConstPointer(); - const double valuesExpected2[5]={3.75 ,1.75 ,1.75,4.,3.75}; - CPPUNIT_ASSERT_EQUAL(5,trgfield->getArray()->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(1,trgfield->getArray()->getNumberOfComponents()); - for(int i0=0;i0<5;i0++) - CPPUNIT_ASSERT_DOUBLES_EQUAL(valuesExpected2[i0],values[i0],1e-12); - trgfield->decrRef(); - // - srcField->setNature(ConservativeVolumic); - trgfield=remapper.transferField(srcField,4.57); - values=trgfield->getArray()->getConstPointer(); - CPPUNIT_ASSERT_EQUAL(5,trgfield->getArray()->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(1,trgfield->getArray()->getNumberOfComponents()); - for(int i0=0;i0<5;i0++) - CPPUNIT_ASSERT_DOUBLES_EQUAL(valuesExpected[i0],values[i0],1e-12); - trgfield->decrRef(); - // - srcField->setNature(IntegralGlobConstraint); - trgfield=remapper.transferField(srcField,4.57); - values=trgfield->getArray()->getConstPointer(); - CPPUNIT_ASSERT_EQUAL(5,trgfield->getArray()->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(1,trgfield->getArray()->getNumberOfComponents()); - for(int i0=0;i0<5;i0++) - CPPUNIT_ASSERT_DOUBLES_EQUAL(valuesExpected2[i0],values[i0],1e-12); - trgfield->decrRef(); - // - srcField->setNature(Integral); - trgfield=remapper.transferField(srcField,4.57); - values=trgfield->getArray()->getConstPointer(); - CPPUNIT_ASSERT_EQUAL(5,trgfield->getArray()->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(1,trgfield->getArray()->getNumberOfComponents()); - for(int i0=0;i0<5;i0++) - CPPUNIT_ASSERT_DOUBLES_EQUAL(valuesExpected2[i0],values[i0],1e-12); - trgfield->decrRef(); - // - srcField->setNature(RevIntegral); - trgfield=remapper.transferField(srcField,4.57); - values=trgfield->getArray()->getConstPointer(); - CPPUNIT_ASSERT_EQUAL(5,trgfield->getArray()->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(1,trgfield->getArray()->getNumberOfComponents()); - for(int i0=0;i0<5;i0++) - CPPUNIT_ASSERT_DOUBLES_EQUAL(valuesExpected[i0],values[i0],1e-12); - trgfield->decrRef(); - // - srcField->decrRef(); - //clean up - sourceMesh->decrRef(); - targetMesh->decrRef(); -} - -void MEDCouplingRemapperTest::test2DInterpP0P0R_1() -{ - MEDCouplingUMesh *sourceMesh=MEDCouplingBasicsTest::build2DSourceMesh_1(); - MEDCouplingUMesh *targetMesh=MEDCouplingBasicsTest::build2DTargetMesh_1(); - // - MEDCouplingRemapper remapper; - remapper.setPrecision(1e-12); - remapper.setIntersectionType(INTERP_KERNEL::Triangulation); - CPPUNIT_ASSERT_EQUAL(1,remapper.prepare(sourceMesh,targetMesh,"P0P0")); - - MEDCouplingFieldDouble *targetField=MEDCouplingFieldDouble::New(ON_CELLS); - targetField->setNature(ConservativeVolumic); - targetField->setMesh(targetMesh); - DataArrayDouble *array=DataArrayDouble::New(); - array->alloc(targetMesh->getNumberOfCells(),1); - targetField->setArray(array); - double *ptr=array->getPointer(); - for(int i=0;igetNumberOfCells();i++) - ptr[i]=(double)(i+7); - array->decrRef(); - // - MEDCouplingFieldDouble *srcfield=remapper.reverseTransferField(targetField,4.57); - const double *values=srcfield->getArray()->getConstPointer(); - const double valuesExpected[2]={8.75 ,9.5}; - CPPUNIT_ASSERT_EQUAL(2,srcfield->getArray()->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(1,srcfield->getArray()->getNumberOfComponents()); - for(int i0=0;i0<2;i0++) - CPPUNIT_ASSERT_DOUBLES_EQUAL(valuesExpected[i0],values[i0],1e-12); - srcfield->decrRef(); - // - targetField->setNature(IntegralGlobConstraint); - srcfield=remapper.reverseTransferField(targetField,4.57); - values=srcfield->getArray()->getConstPointer(); - const double valuesExpected2[2]={26., 19.}; - CPPUNIT_ASSERT_EQUAL(2,srcfield->getArray()->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(1,srcfield->getArray()->getNumberOfComponents()); - for(int i0=0;i0<2;i0++) - CPPUNIT_ASSERT_DOUBLES_EQUAL(valuesExpected2[i0],values[i0],1e-12); - srcfield->decrRef(); - // - targetField->decrRef(); - //clean up - sourceMesh->decrRef(); - targetMesh->decrRef(); -} - -void MEDCouplingRemapperTest::test1DInterp_1() -{ - MEDCouplingUMesh *sourceMesh=MEDCouplingBasicsTest::build1DSourceMesh_2(); - MEDCouplingUMesh *targetMesh=MEDCouplingBasicsTest::build1DTargetMesh_2(); - // - MEDCouplingRemapper remapper; - CPPUNIT_ASSERT_EQUAL(1,remapper.prepare(sourceMesh,targetMesh,"P0P0")); - MEDCouplingFieldDouble *srcField=MEDCouplingFieldDouble::New(ON_CELLS); - srcField->setNature(ConservativeVolumic); - srcField->setMesh(sourceMesh); - DataArrayDouble *array=DataArrayDouble::New(); - array->alloc(sourceMesh->getNumberOfCells(),1); - srcField->setArray(array); - double *ptr=array->getPointer(); - for(int i=0;igetNumberOfCells();i++) - ptr[i]=(double)(i+7); - array->decrRef(); - // - MEDCouplingFieldDouble *trgfield=remapper.transferField(srcField,4.57); - const double *values=trgfield->getArray()->getConstPointer(); - const double valuesExpected1[2]={9.0540540540540526,7.4}; - CPPUNIT_ASSERT_EQUAL(2,trgfield->getArray()->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(1,trgfield->getArray()->getNumberOfComponents()); - for(int i0=0;i0<2;i0++) - CPPUNIT_ASSERT_DOUBLES_EQUAL(valuesExpected1[i0],values[i0],1e-12); - trgfield->decrRef(); - const double valuesExpected2[2]={24.75,5.75}; - srcField->setNature(Integral); - trgfield=remapper.transferField(srcField,4.57); - values=trgfield->getArray()->getConstPointer(); - CPPUNIT_ASSERT_EQUAL(2,trgfield->getArray()->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(1,trgfield->getArray()->getNumberOfComponents()); - for(int i0=0;i0<2;i0++) - CPPUNIT_ASSERT_DOUBLES_EQUAL(valuesExpected2[i0],values[i0],1e-12); - trgfield->decrRef(); - // - const double valuesExpected3[2]={24.75,9.25}; - srcField->setNature(IntegralGlobConstraint); - trgfield=remapper.transferField(srcField,4.57); - values=trgfield->getArray()->getConstPointer(); - CPPUNIT_ASSERT_EQUAL(2,trgfield->getArray()->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(1,trgfield->getArray()->getNumberOfComponents()); - for(int i0=0;i0<2;i0++) - CPPUNIT_ASSERT_DOUBLES_EQUAL(valuesExpected3[i0],values[i0],1e-12); - trgfield->decrRef(); - // - const double valuesExpected4[2]={7.4444444444444446,7.4}; - srcField->setNature(RevIntegral); - trgfield=remapper.transferField(srcField,4.57); - values=trgfield->getArray()->getConstPointer(); - CPPUNIT_ASSERT_EQUAL(2,trgfield->getArray()->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(1,trgfield->getArray()->getNumberOfComponents()); - for(int i0=0;i0<2;i0++) - CPPUNIT_ASSERT_DOUBLES_EQUAL(valuesExpected4[i0],values[i0],1e-12); - trgfield->decrRef(); - // - srcField->decrRef(); - sourceMesh->decrRef(); - targetMesh->decrRef(); - //2D Curve - sourceMesh=MEDCouplingBasicsTest::build2DCurveSourceMesh_2(); - targetMesh=MEDCouplingBasicsTest::build2DCurveTargetMesh_2(); - CPPUNIT_ASSERT_EQUAL(1,remapper.prepare(sourceMesh,targetMesh,"P0P0")); - srcField=MEDCouplingFieldDouble::New(ON_CELLS); - srcField->setNature(ConservativeVolumic); - srcField->setMesh(sourceMesh); - array=DataArrayDouble::New(); - array->alloc(sourceMesh->getNumberOfCells(),1); - srcField->setArray(array); - ptr=array->getPointer(); - for(int i=0;igetNumberOfCells();i++) - ptr[i]=(double)(i+7); - array->decrRef(); - // - trgfield=remapper.transferField(srcField,4.57); - values=trgfield->getArray()->getConstPointer(); - CPPUNIT_ASSERT_EQUAL(2,trgfield->getArray()->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(1,trgfield->getArray()->getNumberOfComponents()); - for(int i0=0;i0<2;i0++) - CPPUNIT_ASSERT_DOUBLES_EQUAL(valuesExpected1[i0],values[i0],1e-12); - trgfield->decrRef(); - srcField->setNature(Integral); - trgfield=remapper.transferField(srcField,4.57); - values=trgfield->getArray()->getConstPointer(); - CPPUNIT_ASSERT_EQUAL(2,trgfield->getArray()->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(1,trgfield->getArray()->getNumberOfComponents()); - for(int i0=0;i0<2;i0++) - CPPUNIT_ASSERT_DOUBLES_EQUAL(valuesExpected2[i0],values[i0],1e-12); - trgfield->decrRef(); - // - srcField->setNature(IntegralGlobConstraint); - trgfield=remapper.transferField(srcField,4.57); - values=trgfield->getArray()->getConstPointer(); - CPPUNIT_ASSERT_EQUAL(2,trgfield->getArray()->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(1,trgfield->getArray()->getNumberOfComponents()); - for(int i0=0;i0<2;i0++) - CPPUNIT_ASSERT_DOUBLES_EQUAL(valuesExpected3[i0],values[i0],1e-12); - trgfield->decrRef(); - // - srcField->setNature(RevIntegral); - trgfield=remapper.transferField(srcField,4.57); - values=trgfield->getArray()->getConstPointer(); - CPPUNIT_ASSERT_EQUAL(2,trgfield->getArray()->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(1,trgfield->getArray()->getNumberOfComponents()); - for(int i0=0;i0<2;i0++) - CPPUNIT_ASSERT_DOUBLES_EQUAL(valuesExpected4[i0],values[i0],1e-12); - trgfield->decrRef(); - // - srcField->decrRef(); - sourceMesh->decrRef(); - targetMesh->decrRef(); -} - -void MEDCouplingRemapperTest::test2DInterpMultiMethods() -{ - MEDCouplingUMesh *sourceMesh=MEDCouplingBasicsTest::build2DSourceMesh_1(); - MEDCouplingUMesh *targetMesh=MEDCouplingBasicsTest::build2DTargetMesh_1(); - // - MEDCouplingRemapper remapper; - remapper.setPrecision(1e-12); - remapper.setIntersectionType(INTERP_KERNEL::Triangulation); - CPPUNIT_ASSERT_EQUAL(1,remapper.prepare(sourceMesh,targetMesh,"P0P0")); - - MEDCouplingFieldDouble *srcField=MEDCouplingFieldDouble::New(ON_CELLS); - srcField->setNature(ConservativeVolumic); - srcField->setMesh(sourceMesh); - DataArrayDouble *array=DataArrayDouble::New(); - array->alloc(sourceMesh->getNumberOfCells(),1); - srcField->setArray(array); - double *ptr=array->getPointer(); - for(int i=0;igetNumberOfCells();i++) - ptr[i]=(double)(i+7); - array->decrRef(); - MEDCouplingFieldDouble *trgfield=remapper.transferField(srcField,4.57); - const double *values=trgfield->getArray()->getConstPointer(); - const double valuesExpected[5]={7.5 ,7. ,7.,8.,7.5}; - CPPUNIT_ASSERT_EQUAL(5,trgfield->getArray()->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(1,trgfield->getArray()->getNumberOfComponents()); - for(int i0=0;i0<5;i0++) - CPPUNIT_ASSERT_DOUBLES_EQUAL(valuesExpected[i0],values[i0],1e-12); - trgfield->decrRef(); - srcField->decrRef(); - // - CPPUNIT_ASSERT_EQUAL(1,remapper.prepare(sourceMesh,targetMesh,"P1P0")); - srcField=MEDCouplingFieldDouble::New(ON_NODES); - srcField->setNature(ConservativeVolumic); - srcField->setMesh(sourceMesh); - array=DataArrayDouble::New(); - array->alloc(sourceMesh->getNumberOfNodes(),1); - srcField->setArray(array); - ptr=array->getPointer(); - for(int i=0;igetNumberOfNodes();i++) - ptr[i]=(double)(i+7); - array->decrRef(); - trgfield=remapper.transferField(srcField,4.57); - values=trgfield->getArray()->getConstPointer(); - const double valuesExpected2[5]={7.,7.666666666666667,8.6666666666666661,8.8333333333333339,10.}; - CPPUNIT_ASSERT_EQUAL(5,trgfield->getArray()->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(1,trgfield->getArray()->getNumberOfComponents()); - for(int i0=0;i0<5;i0++) - CPPUNIT_ASSERT_DOUBLES_EQUAL(valuesExpected2[i0],values[i0],1e-12); - trgfield->decrRef(); - srcField->decrRef(); - // - CPPUNIT_ASSERT_EQUAL(1,remapper.prepare(targetMesh,sourceMesh,"P0P1")); - srcField=MEDCouplingFieldDouble::New(ON_CELLS); - srcField->setNature(ConservativeVolumic); - srcField->setMesh(targetMesh); - array=DataArrayDouble::New(); - array->alloc(targetMesh->getNumberOfCells(),1); - srcField->setArray(array); - ptr=array->getPointer(); - for(int i=0;igetNumberOfCells();i++) - ptr[i]=(double)(i+7); - array->decrRef(); - trgfield=remapper.transferField(srcField,4.57); - values=trgfield->getArray()->getConstPointer(); - const double valuesExpected3[4]={7.5,8.5,10.,10.625}; - CPPUNIT_ASSERT_EQUAL(4,trgfield->getArray()->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(1,trgfield->getArray()->getNumberOfComponents()); - for(int i0=0;i0<4;i0++) - CPPUNIT_ASSERT_DOUBLES_EQUAL(valuesExpected3[i0],values[i0],1e-12); - trgfield->decrRef(); - srcField->decrRef(); - //clean up - sourceMesh->decrRef(); - targetMesh->decrRef(); - // - sourceMesh=MEDCouplingBasicsTest::build2DSourceMesh_1(); - targetMesh=MEDCouplingBasicsTest::build2DTargetMesh_2(); - CPPUNIT_ASSERT_EQUAL(1,remapper.prepare(sourceMesh,targetMesh,"P1P1")); - srcField=MEDCouplingFieldDouble::New(ON_NODES); - srcField->setNature(ConservativeVolumic); - srcField->setMesh(sourceMesh); - array=DataArrayDouble::New(); - array->alloc(sourceMesh->getNumberOfNodes(),1); - srcField->setArray(array); - ptr=array->getPointer(); - for(int i=0;igetNumberOfNodes();i++) - ptr[i]=(double)(i+7); - array->decrRef(); - trgfield=remapper.transferField(srcField,4.57); - values=trgfield->getArray()->getConstPointer(); - const double valuesExpected4[9]={ 7.,7.35,8.,7.7,8.2857142857142865, - 9.5333333333333332,9.,9.7666666666666657,10.}; - CPPUNIT_ASSERT_EQUAL(9,trgfield->getArray()->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(1,trgfield->getArray()->getNumberOfComponents()); - for(int i0=0;i0<9;i0++) - CPPUNIT_ASSERT_DOUBLES_EQUAL(valuesExpected4[i0],values[i0],1e-12); - trgfield->decrRef(); - srcField->decrRef(); - //clean up - sourceMesh->decrRef(); - targetMesh->decrRef(); -} - -void MEDCouplingRemapperTest::testMultiDimCombi() -{ - // ------------- 2D - MEDCouplingUMesh *sourceMesh=MEDCouplingBasicsTest::build2DSourceMesh_1(); - MEDCouplingUMesh *targetMesh=MEDCouplingBasicsTest::build2DTargetMesh_1(); - // - MEDCouplingRemapper remapper; - remapper.setPrecision(1e-12); - remapper.setIntersectionType(INTERP_KERNEL::Triangulation); - CPPUNIT_ASSERT_EQUAL(1,remapper.prepare(sourceMesh,targetMesh,"P0P0")); - MEDCouplingFieldDouble *srcField=MEDCouplingFieldDouble::New(ON_CELLS); - srcField->setNature(ConservativeVolumic); - srcField->setMesh(sourceMesh); - DataArrayDouble *array=DataArrayDouble::New(); - array->alloc(sourceMesh->getNumberOfCells(),1); - srcField->setArray(array); - double *ptr=array->getPointer(); - for(int i=0;igetNumberOfCells();i++) - ptr[i]=(double)(i+7); - array->decrRef(); - MEDCouplingFieldDouble *trgField=remapper.transferField(srcField,4.57); - const double *values=trgField->getArray()->getConstPointer(); - const double valuesExpected[5]={7.5 ,7. ,7.,8.,7.5}; - CPPUNIT_ASSERT_EQUAL(5,trgField->getArray()->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(1,trgField->getArray()->getNumberOfComponents()); - for(int i0=0;i0<5;i0++) - CPPUNIT_ASSERT_DOUBLES_EQUAL(valuesExpected[i0],values[i0],1e-12); - trgField->decrRef(); - srcField->decrRef(); - sourceMesh->decrRef(); - targetMesh->decrRef(); - // ------------- 3D Surf - sourceMesh=MEDCouplingBasicsTest::build3DSurfSourceMesh_1(); - targetMesh=MEDCouplingBasicsTest::build3DSurfTargetMesh_1(); - CPPUNIT_ASSERT_EQUAL(1,remapper.prepare(sourceMesh,targetMesh,"P0P0")); - srcField=MEDCouplingFieldDouble::New(ON_CELLS); - srcField->setNature(ConservativeVolumic); - srcField->setMesh(sourceMesh); - array=DataArrayDouble::New(); - array->alloc(sourceMesh->getNumberOfCells(),1); - srcField->setArray(array); - ptr=array->getPointer(); - for(int i=0;igetNumberOfCells();i++) - ptr[i]=(double)(i+8); - array->decrRef(); - trgField=remapper.transferField(srcField,4.57); - CPPUNIT_ASSERT_EQUAL(5,trgField->getArray()->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(1,trgField->getArray()->getNumberOfComponents()); - const double valuesExpected2[5]={8.5,8.,8.,9.,8.5}; - values=trgField->getArray()->getConstPointer(); - for(int i0=0;i0<5;i0++) - CPPUNIT_ASSERT_DOUBLES_EQUAL(valuesExpected2[i0],values[i0],1e-12); - trgField->decrRef(); - srcField->decrRef(); - sourceMesh->decrRef(); - targetMesh->decrRef(); - // ------------- 3D - sourceMesh=MEDCouplingBasicsTest::build3DSourceMesh_1(); - targetMesh=MEDCouplingBasicsTest::build3DTargetMesh_1(); - CPPUNIT_ASSERT_EQUAL(1,remapper.prepare(sourceMesh,targetMesh,"P0P0")); - srcField=MEDCouplingFieldDouble::New(ON_CELLS); - srcField->setNature(ConservativeVolumic); - srcField->setMesh(sourceMesh); - array=DataArrayDouble::New(); - array->alloc(sourceMesh->getNumberOfCells(),1); - srcField->setArray(array); - ptr=array->getPointer(); - for(int i=0;igetNumberOfCells();i++) - ptr[i]=(double)(i+7); - array->decrRef(); - trgField=remapper.transferField(srcField,4.57); - CPPUNIT_ASSERT_EQUAL(8,trgField->getArray()->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(1,trgField->getArray()->getNumberOfComponents()); - const double valuesExpected3[8]={13.166666666666668, 13.888888888888888, 10.722222222222223, 10.870370370370372, - 14.555555555555555, 13.888888888888889, 14.444444444444443, 11.72222222222222}; - values=trgField->getArray()->getConstPointer(); - for(int i0=0;i0<8;i0++) - CPPUNIT_ASSERT_DOUBLES_EQUAL(valuesExpected3[i0],values[i0],1e-12); - trgField->decrRef(); - srcField->decrRef(); - sourceMesh->decrRef(); - targetMesh->decrRef(); - // ------------- 3D -> 1D - sourceMesh=MEDCouplingBasicsTest::build3DTargetMesh_1(); - targetMesh=MEDCouplingBasicsTest::build1DTargetMesh_1(); - remapper.setIntersectionType(INTERP_KERNEL::PointLocator); - CPPUNIT_ASSERT_EQUAL(1,remapper.prepare(sourceMesh,targetMesh,"P0P0")); - srcField=MEDCouplingFieldDouble::New(ON_CELLS); - srcField->setNature(ConservativeVolumic); - srcField->setMesh(sourceMesh); - array=DataArrayDouble::New(); - array->alloc(sourceMesh->getNumberOfCells(),1); - srcField->setArray(array); - ptr=array->getPointer(); - for(int i=0;igetNumberOfCells();i++) - ptr[i]=(double)(i+7); - array->decrRef(); - trgField=remapper.transferField(srcField,4.57); - CPPUNIT_ASSERT_EQUAL(8,trgField->getArray()->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(1,trgField->getArray()->getNumberOfComponents()); - const double valuesExpected4[8]={7.,11.,8.,12.,9.,13.,10.,14.}; - values=trgField->getArray()->getConstPointer(); - for(int i0=0;i0<8;i0++) - CPPUNIT_ASSERT_DOUBLES_EQUAL(valuesExpected4[i0],values[i0],1e-12); - trgField->decrRef(); - srcField->decrRef(); - sourceMesh->decrRef(); - targetMesh->decrRef(); - // ------------- 1D -> 3D - sourceMesh=MEDCouplingBasicsTest::build1DTargetMesh_1(); - targetMesh=MEDCouplingBasicsTest::build3DTargetMesh_1(); - remapper.setIntersectionType(INTERP_KERNEL::PointLocator); - CPPUNIT_ASSERT_EQUAL(1,remapper.prepare(sourceMesh,targetMesh,"P0P0")); - srcField=MEDCouplingFieldDouble::New(ON_CELLS); - srcField->setNature(ConservativeVolumic); - srcField->setMesh(sourceMesh); - array=DataArrayDouble::New(); - array->alloc(sourceMesh->getNumberOfCells(),1); - srcField->setArray(array); - ptr=array->getPointer(); - for(int i=0;igetNumberOfCells();i++) - ptr[i]=(double)(i+7); - array->decrRef(); - trgField=remapper.transferField(srcField,4.57); - CPPUNIT_ASSERT_EQUAL(8,trgField->getArray()->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(1,trgField->getArray()->getNumberOfComponents()); - const double valuesExpected5[8]={7.,9.,11.,13.,8.,10.,12.,14.}; - values=trgField->getArray()->getConstPointer(); - for(int i0=0;i0<8;i0++) - CPPUNIT_ASSERT_DOUBLES_EQUAL(valuesExpected5[i0],values[i0],1e-12); - trgField->decrRef(); - srcField->decrRef(); - sourceMesh->decrRef(); - targetMesh->decrRef(); - // ------------- 2D -> 1D - sourceMesh=MEDCouplingBasicsTest::build2DTargetMesh_1(); - targetMesh=build1DTargetMesh_2(); - remapper.setIntersectionType(INTERP_KERNEL::PointLocator); - CPPUNIT_ASSERT_EQUAL(1,remapper.prepare(sourceMesh,targetMesh,"P0P0")); - srcField=MEDCouplingFieldDouble::New(ON_CELLS); - srcField->setNature(ConservativeVolumic); - srcField->setMesh(sourceMesh); - array=DataArrayDouble::New(); - array->alloc(sourceMesh->getNumberOfCells(),1); - srcField->setArray(array); - ptr=array->getPointer(); - for(int i=0;igetNumberOfCells();i++) - ptr[i]=(double)(i+7); - array->decrRef(); - trgField=remapper.transferField(srcField,4.57); - const double valuesExpected8[5]={9.,8.,11.,7.,11.}; - values=trgField->getArray()->getConstPointer(); - for(int i0=0;i0<5;i0++) - CPPUNIT_ASSERT_DOUBLES_EQUAL(valuesExpected8[i0],values[i0],1e-12); - trgField->decrRef(); - srcField->decrRef(); - sourceMesh->decrRef(); - targetMesh->decrRef(); - // ------------- 1D -> 2D - sourceMesh=build1DTargetMesh_2(); - targetMesh=MEDCouplingBasicsTest::build2DTargetMesh_1(); - remapper.setIntersectionType(INTERP_KERNEL::PointLocator); - CPPUNIT_ASSERT_EQUAL(1,remapper.prepare(sourceMesh,targetMesh,"P0P0")); - srcField=MEDCouplingFieldDouble::New(ON_CELLS); - srcField->setNature(ConservativeVolumic); - srcField->setMesh(sourceMesh); - array=DataArrayDouble::New(); - array->alloc(sourceMesh->getNumberOfCells(),1); - srcField->setArray(array); - ptr=array->getPointer(); - for(int i=0;igetNumberOfCells();i++) - ptr[i]=(double)(i+7); - array->decrRef(); - trgField=remapper.transferField(srcField,4.57); - const double valuesExpected9[5]={10.,8.,7.,4.57,10.}; - values=trgField->getArray()->getConstPointer(); - for(int i0=0;i0<5;i0++) - CPPUNIT_ASSERT_DOUBLES_EQUAL(valuesExpected9[i0],values[i0],1e-12); - trgField->decrRef(); - srcField->decrRef(); - sourceMesh->decrRef(); - targetMesh->decrRef(); - // ------------- 2D -> -1D - sourceMesh=MEDCouplingBasicsTest::build2DTargetMesh_1(); - targetMesh=MEDCouplingUMesh::New("an example of -1 D mesh",-1); - srcField=MEDCouplingFieldDouble::New(ON_CELLS); - srcField->setNature(ConservativeVolumic); - srcField->setMesh(sourceMesh); - array=DataArrayDouble::New(); - array->alloc(sourceMesh->getNumberOfCells(),1); - srcField->setArray(array); - ptr=array->getPointer(); - for(int i=0;igetNumberOfCells();i++) - ptr[i]=(double)(i+7); - array->decrRef(); - CPPUNIT_ASSERT_EQUAL(1,remapper.prepare(sourceMesh,targetMesh,"P0P0")); - trgField=remapper.transferField(srcField,4.57); - values=trgField->getArray()->getConstPointer(); - CPPUNIT_ASSERT_EQUAL(1,trgField->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(1,trgField->getNumberOfComponents()); - CPPUNIT_ASSERT_DOUBLES_EQUAL(9.125,values[0],1e-14); - srcField->decrRef(); - srcField=remapper.reverseTransferField(trgField,4.220173); - CPPUNIT_ASSERT_EQUAL(5,srcField->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(1,srcField->getNumberOfComponents()); - values=srcField->getArray()->getConstPointer(); - for(int i0=0;i0<5;i0++) - CPPUNIT_ASSERT_DOUBLES_EQUAL(9.125,values[i0],1e-14); - srcField->decrRef(); - trgField->setNature(Integral); - srcField=remapper.reverseTransferField(trgField,4.220173); - CPPUNIT_ASSERT_EQUAL(5,srcField->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(1,srcField->getNumberOfComponents()); - values=srcField->getArray()->getConstPointer(); - const double valuesExpected6[5]={2.28125,1.140625,1.140625,2.28125,2.28125}; - for(int i0=0;i0<5;i0++) - CPPUNIT_ASSERT_DOUBLES_EQUAL(valuesExpected6[i0],values[i0],1e-14); - srcField->decrRef(); - trgField->decrRef(); - // ------------- -1D -> 2D - CPPUNIT_ASSERT_EQUAL(1,remapper.prepare(targetMesh,sourceMesh,"P0P0")); - trgField=MEDCouplingFieldDouble::New(ON_CELLS); - trgField->setNature(ConservativeVolumic); - trgField->setMesh(targetMesh); - array=DataArrayDouble::New(); - array->alloc(targetMesh->getNumberOfCells(),1); - trgField->setArray(array); - ptr=array->getPointer(); - ptr[0]=7.; - array->decrRef(); - srcField=remapper.transferField(trgField,4.221073); - values=srcField->getArray()->getConstPointer(); - for(int i0=0;i0<5;i0++) - CPPUNIT_ASSERT_DOUBLES_EQUAL(7.,values[i0],1e-14); - srcField->decrRef(); - trgField->setNature(IntegralGlobConstraint); - srcField=remapper.transferField(trgField,4.221073); - values=srcField->getArray()->getConstPointer(); - const double valuesExpected7[5]={1.75,0.875,0.875,1.75,1.75}; - for(int i0=0;i0<5;i0++) - CPPUNIT_ASSERT_DOUBLES_EQUAL(valuesExpected7[i0],values[i0],1e-14); - srcField->decrRef(); - trgField->setNature(Integral); - srcField=remapper.transferField(trgField,4.221073); - values=srcField->getArray()->getConstPointer(); - for(int i0=0;i0<5;i0++) - CPPUNIT_ASSERT_DOUBLES_EQUAL(valuesExpected7[i0],values[i0],1e-14); - srcField->decrRef(); - trgField->decrRef(); - sourceMesh->decrRef(); - targetMesh->decrRef(); - //------------- 1D -> 2D - const int conn[8]={0,1,1,2,2,3,3,0}; - const int conn2[12]={6,7,5,4,2,7,6,3,0,4,5,1}; - const double coords1[]={0.17,0.93,0.56,0.93,0.56,0.25,0.17,0.52}; - const double coords2[]={0.,0.,1.,0.,1.,1.,0.,1.,0.,0.5,1.,0.5,0.,0.8,1.,0.8}; - sourceMesh=MEDCouplingUMesh::New("src1D",1); - sourceMesh->allocateCells(4); - sourceMesh->insertNextCell(INTERP_KERNEL::NORM_SEG2,2,conn); - sourceMesh->insertNextCell(INTERP_KERNEL::NORM_SEG2,2,conn+2); - sourceMesh->insertNextCell(INTERP_KERNEL::NORM_SEG2,2,conn+4); - sourceMesh->insertNextCell(INTERP_KERNEL::NORM_SEG2,2,conn+6); - sourceMesh->finishInsertingCells(); - array=DataArrayDouble::New(); array->alloc(4,2); - std::copy(coords1,coords1+8,array->getPointer()); - sourceMesh->setCoords(array); array->decrRef(); - targetMesh=MEDCouplingUMesh::New("trg2D",2); - targetMesh->allocateCells(3); - targetMesh->insertNextCell(INTERP_KERNEL::NORM_QUAD4,4,conn2); - targetMesh->insertNextCell(INTERP_KERNEL::NORM_QUAD4,4,conn2+4); - targetMesh->insertNextCell(INTERP_KERNEL::NORM_QUAD4,4,conn2+8); - targetMesh->finishInsertingCells(); - array=DataArrayDouble::New(); array->alloc(8,2); - std::copy(coords2,coords2+16,array->getPointer()); - targetMesh->setCoords(array); array->decrRef(); - remapper.setPrecision(1e-12); - remapper.setIntersectionType(INTERP_KERNEL::Geometric2D); - CPPUNIT_ASSERT_EQUAL(1,remapper.prepare(sourceMesh,targetMesh,"P0P0")); - srcField=MEDCouplingFieldDouble::New(ON_CELLS); - srcField->setNature(ConservativeVolumic); - srcField->setMesh(sourceMesh); - array=DataArrayDouble::New(); - array->alloc(4,1); array->iota(2.); - srcField->setArray(array); array->decrRef(); - trgField=remapper.transferField(srcField,4.57); - const double valuesExpected10[3]={3.9674868868103834, 2.8, 3.6372633449255796}; - CPPUNIT_ASSERT_EQUAL(3,trgField->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(1,trgField->getNumberOfComponents()); - for(int i=0;i<3;i++) - CPPUNIT_ASSERT_DOUBLES_EQUAL(valuesExpected10[i],trgField->getIJ(i,0),1e-13); - srcField->decrRef(); - trgField->decrRef(); - //------------- 2D -> 1D - remapper.setPrecision(1e-12); - remapper.setIntersectionType(INTERP_KERNEL::Geometric2D); - CPPUNIT_ASSERT_EQUAL(1,remapper.prepare(targetMesh,sourceMesh,"P0P0")); - srcField=MEDCouplingFieldDouble::New(ON_CELLS); - srcField->setNature(ConservativeVolumic); - srcField->setMesh(targetMesh); - array=DataArrayDouble::New(); - array->alloc(3,1); array->iota(2.); - srcField->setArray(array); array->decrRef(); - trgField=remapper.transferField(srcField,4.57); - const double valuesExpected11[4]={3., 2.9264705882352944, 3.8518518518518516, 2.3170731707317076}; - CPPUNIT_ASSERT_EQUAL(4,trgField->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(1,trgField->getNumberOfComponents()); - for(int i=0;i<4;i++) - CPPUNIT_ASSERT_DOUBLES_EQUAL(valuesExpected11[i],trgField->getIJ(i,0),1e-13); - srcField->decrRef(); - trgField->decrRef(); - sourceMesh->decrRef(); - targetMesh->decrRef(); - //------------- 2D -> 3D - sourceMesh=MEDCouplingBasicsTest::build3D2DSourceMesh(); - targetMesh=MEDCouplingBasicsTest::build3D2DTargetMesh(); - remapper.setIntersectionType(INTERP_KERNEL::Triangulation); - CPPUNIT_ASSERT_EQUAL(1,remapper.prepare(sourceMesh,targetMesh,"P0P0")); - srcField=MEDCouplingFieldDouble::New(ON_CELLS); - srcField->setNature(ConservativeVolumic); - srcField->setMesh(sourceMesh); - array=DataArrayDouble::New(); - array->alloc(7,1); array->iota(2.); - srcField->setArray(array); array->decrRef(); - trgField=remapper.transferField(srcField,4.57); - const double valuesExpected12[3]={5.70909090909091, 6.08362715128042, 6.92857142857143}; - CPPUNIT_ASSERT_EQUAL(3,trgField->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(1,trgField->getNumberOfComponents()); - for(int i=0;i<3;i++) - CPPUNIT_ASSERT_DOUBLES_EQUAL(valuesExpected12[i],trgField->getIJ(i,0),1e-13); - srcField->decrRef(); - trgField->decrRef(); - //------------- 3D -> 2D - CPPUNIT_ASSERT_EQUAL(1,remapper.prepare(targetMesh,sourceMesh,"P0P0")); - srcField=MEDCouplingFieldDouble::New(ON_CELLS); - srcField->setNature(ConservativeVolumic); - srcField->setMesh(targetMesh); - array=DataArrayDouble::New(); - array->alloc(3,1); array->iota(2.); - srcField->setArray(array); array->decrRef(); - trgField=remapper.transferField(srcField,4.57); - const double valuesExpected13[7]={3., 4., 2.5, 2.909090909090909, 2., 3.5, 3.3571428571428572}; - CPPUNIT_ASSERT_EQUAL(7,trgField->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(1,trgField->getNumberOfComponents()); - for(int i=0;i<7;i++) - CPPUNIT_ASSERT_DOUBLES_EQUAL(valuesExpected13[i],trgField->getIJ(i,0),1e-13); - srcField->decrRef(); - trgField->decrRef(); - sourceMesh->decrRef(); - targetMesh->decrRef(); -} - -void MEDCouplingRemapperTest::testNatureOfField() -{ - MEDCouplingUMesh *sourceMesh=MEDCouplingBasicsTest::build2DSourceMesh_1(); - MEDCouplingUMesh *targetMesh=build2DTargetMesh_3(); - // - MEDCouplingRemapper remapper; - remapper.setPrecision(1e-12); - remapper.setIntersectionType(INTERP_KERNEL::Triangulation); - CPPUNIT_ASSERT_EQUAL(1,remapper.prepare(sourceMesh,targetMesh,"P0P0")); - MEDCouplingFieldDouble *srcField=MEDCouplingFieldDouble::New(ON_CELLS); - srcField->setNature(ConservativeVolumic); - srcField->setMesh(sourceMesh); - DataArrayDouble *array=DataArrayDouble::New(); - array->alloc(sourceMesh->getNumberOfCells(),1); - srcField->setArray(array); - double *ptr=array->getPointer(); - for(int i=0;igetNumberOfCells();i++) - ptr[i]=(double)(i+7); - array->decrRef(); - MEDCouplingFieldDouble *trgfield=remapper.transferField(srcField,4.220173); - const double *values=trgfield->getArray()->getConstPointer(); - const double valuesExpected[4]={7.75, 7.0625, 4.220173,8.0}; - CPPUNIT_ASSERT_EQUAL(4,trgfield->getArray()->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(1,trgfield->getArray()->getNumberOfComponents()); - for(int i0=0;i0<4;i0++) - CPPUNIT_ASSERT_DOUBLES_EQUAL(valuesExpected[i0],values[i0],1e-12); - trgfield->decrRef(); - // - srcField->setNature(IntegralGlobConstraint); - trgfield=remapper.transferField(srcField,4.220173); - values=trgfield->getArray()->getConstPointer(); - const double valuesExpected2[4]={2.8374999999999999, 7.3624999999999998, 4.220173, 4.7999999999999998}; - CPPUNIT_ASSERT_EQUAL(4,trgfield->getArray()->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(1,trgfield->getArray()->getNumberOfComponents()); - for(int i0=0;i0<4;i0++) - CPPUNIT_ASSERT_DOUBLES_EQUAL(valuesExpected2[i0],values[i0],1e-12); - trgfield->decrRef(); - // - srcField->setNature(Integral); - trgfield=remapper.transferField(srcField,4.220173); - values=trgfield->getArray()->getConstPointer(); - const double valuesExpected3[4]={1.24, 4.5199999999999996, 4.220173, 1.9199999999999999}; - CPPUNIT_ASSERT_EQUAL(4,trgfield->getArray()->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(1,trgfield->getArray()->getNumberOfComponents()); - for(int i0=0;i0<4;i0++) - CPPUNIT_ASSERT_DOUBLES_EQUAL(valuesExpected3[i0],values[i0],1e-12); - trgfield->decrRef(); - // - srcField->setNature(RevIntegral); - trgfield=remapper.transferField(srcField,4.220173); - values=trgfield->getArray()->getConstPointer(); - const double valuesExpected9[4]={2.48, 3.766666666666666, 4.220173, 1.9199999999999999}; - CPPUNIT_ASSERT_EQUAL(4,trgfield->getArray()->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(1,trgfield->getArray()->getNumberOfComponents()); - for(int i0=0;i0<4;i0++) - CPPUNIT_ASSERT_DOUBLES_EQUAL(valuesExpected9[i0],values[i0],1e-12); - trgfield->decrRef(); - // - srcField->decrRef(); - // REVERSE *********** - trgfield=MEDCouplingFieldDouble::New(ON_CELLS); - trgfield->setNature(ConservativeVolumic); - trgfield->setMesh(targetMesh); - array=DataArrayDouble::New(); - array->alloc(targetMesh->getNumberOfCells(),1); - trgfield->setArray(array); - ptr=array->getPointer(); - for(int i=0;igetNumberOfCells();i++) - ptr[i]=(double)(i+7); - array->decrRef(); - srcField=remapper.reverseTransferField(trgfield,4.220173); - values=srcField->getArray()->getConstPointer(); - const double valuesExpected4[2]={7.9375, 8.9}; - CPPUNIT_ASSERT_EQUAL(2,srcField->getArray()->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(1,srcField->getArray()->getNumberOfComponents()); - for(int i0=0;i0<2;i0++) - CPPUNIT_ASSERT_DOUBLES_EQUAL(valuesExpected4[i0],values[i0],1e-12); - srcField->decrRef(); - // - trgfield->decrRef(); - // - sourceMesh->decrRef(); - targetMesh->decrRef(); - // REVERSE ALL - sourceMesh=build2DTargetMesh_3(); - targetMesh=MEDCouplingBasicsTest::build2DSourceMesh_1(); - // - CPPUNIT_ASSERT_EQUAL(1,remapper.prepare(sourceMesh,targetMesh,"P0P0")); - srcField=MEDCouplingFieldDouble::New(ON_CELLS); - srcField->setNature(ConservativeVolumic); - srcField->setMesh(sourceMesh); - array=DataArrayDouble::New(); - array->alloc(sourceMesh->getNumberOfCells(),1); - srcField->setArray(array); - ptr=array->getPointer(); - for(int i=0;igetNumberOfCells();i++) - ptr[i]=(double)(i+7); - array->decrRef(); - trgfield=remapper.transferField(srcField,4.220173); - values=trgfield->getArray()->getConstPointer(); - const double valuesExpected5[2]={7.9375, 8.9}; - CPPUNIT_ASSERT_EQUAL(2,trgfield->getArray()->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(1,trgfield->getArray()->getNumberOfComponents()); - for(int i0=0;i0<2;i0++) - CPPUNIT_ASSERT_DOUBLES_EQUAL(valuesExpected5[i0],values[i0],1e-12); - trgfield->decrRef(); - // - srcField->setNature(IntegralGlobConstraint); - trgfield=remapper.transferField(srcField,4.220173); - values=trgfield->getArray()->getConstPointer(); - const double valuesExpected6[4]={9.25, 15.75}; - CPPUNIT_ASSERT_EQUAL(2,trgfield->getArray()->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(1,trgfield->getArray()->getNumberOfComponents()); - for(int i0=0;i0<2;i0++) - CPPUNIT_ASSERT_DOUBLES_EQUAL(valuesExpected6[i0],values[i0],1e-12); - trgfield->decrRef(); - // - srcField->setNature(Integral); - trgfield=remapper.transferField(srcField,4.220173); - values=trgfield->getArray()->getConstPointer(); - const double valuesExpected7[2]={4.56, 4.3466666666666667}; - CPPUNIT_ASSERT_EQUAL(2,trgfield->getArray()->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(1,trgfield->getArray()->getNumberOfComponents()); - for(int i0=0;i0<2;i0++) - CPPUNIT_ASSERT_DOUBLES_EQUAL(valuesExpected7[i0],values[i0],1e-12); - trgfield->decrRef(); - // - srcField->setNature(RevIntegral); - trgfield=remapper.transferField(srcField,4.220173); - values=trgfield->getArray()->getConstPointer(); - const double valuesExpected10[2]={5.08, 3.56}; - CPPUNIT_ASSERT_EQUAL(2,trgfield->getArray()->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(1,trgfield->getArray()->getNumberOfComponents()); - for(int i0=0;i0<2;i0++) - CPPUNIT_ASSERT_DOUBLES_EQUAL(valuesExpected10[i0],values[i0],1e-12); - trgfield->decrRef(); - // - srcField->decrRef(); - // REVERSE *********** - trgfield=MEDCouplingFieldDouble::New(ON_CELLS); - trgfield->setNature(ConservativeVolumic); - trgfield->setMesh(targetMesh); - array=DataArrayDouble::New(); - array->alloc(targetMesh->getNumberOfCells(),1); - trgfield->setArray(array); - ptr=array->getPointer(); - for(int i=0;igetNumberOfCells();i++) - ptr[i]=(double)(i+7); - array->decrRef(); - srcField=remapper.reverseTransferField(trgfield,4.220173); - values=srcField->getArray()->getConstPointer(); - const double valuesExpected8[4]={7.75, 7.0625,4.220173, 8.0}; - CPPUNIT_ASSERT_EQUAL(4,srcField->getArray()->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(1,srcField->getArray()->getNumberOfComponents()); - for(int i0=0;i0<4;i0++) - CPPUNIT_ASSERT_DOUBLES_EQUAL(valuesExpected8[i0],values[i0],1e-12); - srcField->decrRef(); - // - trgfield->decrRef(); - // - sourceMesh->decrRef(); - targetMesh->decrRef(); -} - -void MEDCouplingRemapperTest::testExtruded() -{ - MEDCouplingUMesh *mesh2DS=0; - MEDCouplingUMesh *mesh3DS=build3DExtrudedUMesh_1(mesh2DS); - MEDCouplingExtrudedMesh *extS=MEDCouplingExtrudedMesh::New(mesh3DS,mesh2DS,1); - mesh3DS->decrRef(); - mesh2DS->decrRef(); - MEDCouplingUMesh *mesh2DT=0; - MEDCouplingUMesh *mesh3DT=build3DExtrudedUMesh_1(mesh2DT); - MEDCouplingExtrudedMesh *extT=MEDCouplingExtrudedMesh::New(mesh3DT,mesh2DT,1); - // - // - mesh3DT->decrRef(); - mesh2DT->decrRef(); - // - extS->decrRef(); - extT->decrRef(); -} - -void MEDCouplingRemapperTest::testExtruded2() -{ - MEDCouplingUMesh *meshN,*meshTT,*meshTF; - MEDCouplingBasicsTest::build3DExtrudedUMesh_2(meshN,meshTT,meshTF); - std::vector n; - double pt[3]={300.,300.,0.}; - double v[3]={0.,0.,2.}; - meshN->findNodesOnPlane(pt,v,1e-12,n); - MEDCouplingUMesh *meshN2D=(MEDCouplingUMesh *)meshN->buildFacePartOfMySelfNode(&n[0],&n[0]+n.size(),true); - n.clear(); - bool b=false; - int newNbOfNodes; - DataArrayInt *da=meshTT->mergeNodes(1e-12,b,newNbOfNodes); - CPPUNIT_ASSERT(b); - da->decrRef(); - meshTT->findNodesOnPlane(pt,v,1e-12,n); - MEDCouplingUMesh *meshTT2D=(MEDCouplingUMesh *)meshTT->buildFacePartOfMySelfNode(&n[0],&n[0]+n.size(),true); - n.clear(); - meshTF->findNodesOnPlane(pt,v,1e-12,n); - MEDCouplingUMesh *meshTF2D=(MEDCouplingUMesh *)meshTF->buildFacePartOfMySelfNode(&n[0],&n[0]+n.size(),true); - n.clear(); - // - MEDCouplingExtrudedMesh *meshNE=MEDCouplingExtrudedMesh::New(meshN,meshN2D,0); - MEDCouplingExtrudedMesh *meshTTE=MEDCouplingExtrudedMesh::New(meshTT,meshTT2D,0); - MEDCouplingExtrudedMesh *meshTFE=MEDCouplingExtrudedMesh::New(meshTF,meshTF2D,0); - // - MEDCouplingRemapper remapper; - remapper.setPrecision(1e-12); - remapper.setIntersectionType(INTERP_KERNEL::Triangulation); - CPPUNIT_ASSERT_EQUAL(1,remapper.prepare(meshNE,meshTTE,"P0P0")); - MEDCouplingFieldDouble *srcField=MEDCouplingFieldDouble::New(ON_CELLS); - srcField->setNature(IntegralGlobConstraint); - srcField->setMesh(meshNE); - DataArrayDouble *array=DataArrayDouble::New(); - array->alloc(meshNE->getNumberOfCells(),1); - srcField->setArray(array); - double vals1[40]={ - 1000.,1000.,1020.,1030.,1040.,1000.,1000.,1070.,1080.,1090.,1000.,1000.,1120.,1130.,1140.,1000.,1000.,1170.,1180.,1190., - 2000.,2000.,2020.,2030.,2040.,2000.,2000.,2070.,2080.,2090.,2000.,2000.,2120.,2130.,2140.,2000.,2000.,2170.,2180.,2190., - }; - CPPUNIT_ASSERT_EQUAL((int)(sizeof(vals1)/sizeof(double)),meshNE->getNumberOfCells()); - std::copy(vals1,vals1+meshNE->getNumberOfCells(),array->getPointer()); - array->decrRef(); - MEDCouplingFieldDouble *trgField=remapper.transferField(srcField,4.220173); - double expected1[200]={ - 800.,800.,800.,800.,800.,800.,800.,800.,800.,800.,1600.,1600.,1600.,1600.,1600.,1600.,1600.,1600.,1600.,1600., - 102.,102.,102.,102.,102.,102.,102.,102.,102.,102.,202.,202.,202.,202.,202.,202.,202.,202.,202.,202., - 103.,103.,103.,103.,103.,103.,103.,103.,103.,103.,203.,203.,203.,203.,203.,203.,203.,203.,203.,203., - 104.,104.,104.,104.,104.,104.,104.,104.,104.,104.,204.,204.,204.,204.,204.,204.,204.,204.,204.,204., - 219.,219.,219.,219.,219.,219.,219.,219.,219.,219.,419.,419.,419.,419.,419.,419.,419.,419.,419.,419., - 221.,221.,221.,221.,221.,221.,221.,221.,221.,221.,421.,421.,421.,421.,421.,421.,421.,421.,421.,421., - 223.,223.,223.,223.,223.,223.,223.,223.,223.,223.,423.,423.,423.,423.,423.,423.,423.,423.,423.,423., - 117.,117.,117.,117.,117.,117.,117.,117.,117.,117.,217.,217.,217.,217.,217.,217.,217.,217.,217.,217., - 118.,118.,118.,118.,118.,118.,118.,118.,118.,118.,218.,218.,218.,218.,218.,218.,218.,218.,218.,218., - 119.,119.,119.,119.,119.,119.,119.,119.,119.,119.,219.,219.,219.,219.,219.,219.,219.,219.,219.,219. - }; - for(int i=0;i<200;i++) - CPPUNIT_ASSERT_DOUBLES_EQUAL(expected1[i],trgField->getArray()->getConstPointer()[i],1e-3);//1e-3 precision due to non coincidence in 1D mesh - CPPUNIT_ASSERT_DOUBLES_EQUAL(std::accumulate(expected1,expected1+200,0.),std::accumulate(vals1,vals1+40,0.),1e-10); - CPPUNIT_ASSERT_DOUBLES_EQUAL(std::accumulate(expected1,expected1+200,0.),std::accumulate(trgField->getArray()->getConstPointer(),trgField->getArray()->getConstPointer()+200,0.),1e-10); - trgField->decrRef(); - // - CPPUNIT_ASSERT_EQUAL(1,remapper.prepare(meshNE,meshTFE,"P0P0")); - trgField=remapper.transferField(srcField,4.220173); - double expected2[340]={25.5, 51.25, 51.75, 26., 79., 158.75, 160.25, 80.5, 85.25, 171.25, 172.75, 86.75, 29.25, 58.75, 59.25, 29.75, 25.5, 51.25, 51.75, 26., 79., 158.75, - 160.25, 80.5, 85.25, 171.25, 172.75, 86.75, 29.25, 58.75, 59.25, 29.75, 25.5, 51.25, 51.75, 26., 79., 158.75, 160.25, 80.5, 85.25, 171.25, 172.75, 86.75, - 29.25, 58.75, 59.25, 29.75, 25.5, 51.25, 51.75, 26., 79., 158.75, 160.25, 80.5, 85.25, 171.25, 172.75, 86.75, 29.25, 58.75, 59.25, 29.75, 25.5, 51.25, 51.75, - 26., 79., 158.75, 160.25, 80.5, 85.25, 171.25, 172.75, 86.75, 29.25, 58.75, 59.25, 29.75, 25.5, 51.25, 51.75, 26., 79., 158.75, 160.25, 80.5, 85.25, 171.25, - 172.75, 86.75, 29.25, 58.75, 59.25, 29.75, 25.5, 51.25, 51.75, 26., 79., 158.75, 160.25, 80.5, 85.25, 171.25, 172.75, 86.75, 29.25, 58.75, 59.25, 29.75, 25.5, - 51.25, 51.75, 26., 79., 158.75, 160.25, 80.5, 85.25, 171.25, 172.75, 86.75, 29.25, 58.75, 59.25, 29.75, 25.5, 51.25, 51.75, 26., 79., 158.75, 160.25, 80.5, - 85.25, 171.25, 172.75, 86.75, 29.25, 58.75, 59.25, 29.75, 25.5, 51.25, 51.75, 26., 79., 158.75, 160.25, 80.5, 85.25, 171.25, 172.75, 86.75, 29.25, 58.75, 59.25, - 29.75, 50.5, 101.25, 101.75, 51., 154., 308.75, 310.25, 155.5, 160.25, 321.25, 322.75, 161.75, 54.25, 108.75, 109.25, 54.75, 50.5, 101.25, 101.75, 51., 154., - 308.75, 310.25, 155.5, 160.25, 321.25, 322.75, 161.75, 54.25, 108.75, 109.25, 54.75, 50.5, 101.25, 101.75, 51., 154., 308.75, 310.25, 155.5, 160.25, 321.25, 322.75, - 161.75, 54.25, 108.75, 109.25, 54.75, 50.5, 101.25, 101.75, 51., 154., 308.75, 310.25, 155.5, 160.25, 321.25, 322.75, 161.75, 54.25, 108.75, 109.25, 54.75, 50.5, - 101.25, 101.75, 51., 154., 308.75, 310.25, 155.5, 160.25, 321.25, 322.75, 161.75, 54.25, 108.75, 109.25, 54.75, 50.5, 101.25, 101.75, 51., 154., 308.75, 310.25, - 155.5, 160.25, 321.25, 322.75, 161.75, 54.25, 108.75, 109.25, 54.75, 50.5, 101.25, 101.75, 51., 154., 308.75, 310.25, 155.5, 160.25, 321.25, 322.75, 161.75, 54.25, - 108.75, 109.25, 54.75, 50.5, 101.25, 101.75, 51., 154., 308.75, 310.25, 155.5, 160.25, 321.25, 322.75, 161.75, 54.25, 108.75, 109.25, 54.75, 50.5, 101.25, 101.75, - 51., 154., 308.75, 310.25, 155.5, 160.25, 321.25, 322.75, 161.75, 54.25, 108.75, 109.25, 54.75, 50.5, 101.25, 101.75, 51., 154., 308.75, 310.25, 155.5, 160.25, 321.25, - 322.75, 161.75, 54.25, 108.75, 109.25, 54.75, 800., 800., 800., 800., 800., 800., 800., 800., 800., 800., 1600., 1600., 1600., 1600., 1600., 1600., 1600., - 1600., 1600., 1600.}; - for(int i=0;i<340;i++) - CPPUNIT_ASSERT_DOUBLES_EQUAL(expected2[i],trgField->getArray()->getConstPointer()[i],1e-3);//1e-3 precision due to non coincidence in 1D mesh - CPPUNIT_ASSERT_DOUBLES_EQUAL(std::accumulate(expected2,expected2+340,0.),std::accumulate(vals1,vals1+40,0.),1e-10); - CPPUNIT_ASSERT_DOUBLES_EQUAL(std::accumulate(expected2,expected2+340,0.),std::accumulate(trgField->getArray()->getConstPointer(),trgField->getArray()->getConstPointer()+340,0.),1e-10); - trgField->decrRef(); - srcField->decrRef(); - // - double vals2[200]={ - 100., 200., 300., 400., 500., 600., 700., 800., 900., 1000., 1100., 1200., 1300., 1400., 1500., 1600., 1700., 1800., 1900., 2000, - 101., 201., 301., 401., 501., 601., 701., 801., 901., 1001., 1101., 1201., 1301., 1401., 1501., 1601., 1701., 1801., 1901., 2001, - 102., 202., 302., 402., 502., 602., 702., 802., 902., 1002., 1102., 1202., 1302., 1402., 1502., 1602., 1702., 1802., 1902., 2002, - 103., 203., 303., 403., 503., 603., 703., 803., 903., 1003., 1103., 1203., 1303., 1403., 1503., 1603., 1703., 1803., 1903., 2003, - 104., 204., 304., 404., 504., 604., 704., 804., 904., 1004., 1104., 1204., 1304., 1404., 1504., 1604., 1704., 1804., 1904., 2004, - 105., 205., 305., 405., 505., 605., 705., 805., 905., 1005., 1105., 1205., 1305., 1405., 1505., 1605., 1705., 1805., 1905., 2005, - 106., 206., 306., 406., 506., 606., 706., 806., 906., 1006., 1106., 1206., 1306., 1406., 1506., 1606., 1706., 1806., 1906., 2006, - 107., 207., 307., 407., 507., 607., 707., 807., 907., 1007., 1107., 1207., 1307., 1407., 1507., 1607., 1707., 1807., 1907., 2007, - 108., 208., 308., 408., 508., 608., 708., 808., 908., 1008., 1108., 1208., 1308., 1408., 1508., 1608., 1708., 1808., 1908., 2008, - 109., 209., 309., 409., 509., 609., 709., 809., 909., 1009., 1109., 1209., 1309., 1409., 1509., 1609., 1709., 1809., 1909., 2009. - }; - CPPUNIT_ASSERT_EQUAL(1,remapper.prepare(meshNE,meshTTE,"P0P0")); - trgField=MEDCouplingFieldDouble::New(ON_CELLS); - trgField->setNature(ConservativeVolumic); - trgField->setMesh(meshTTE); - array=DataArrayDouble::New(); - array->alloc(meshTTE->getNumberOfCells(),1); - trgField->setArray(array); - std::copy(vals2,vals2+meshTTE->getNumberOfCells(),array->getPointer()); - array->decrRef(); - srcField=remapper.reverseTransferField(trgField,4.220173); - double expected3[40]={ - 550.,550.,551.,552.,553.,550.,550.,554.,555.,556.,550.,550.,554.,555.,556.,550.,550.,557.,558.,559., - 1550.,1550.,1551.,1552.,1553.,1550.,1550.,1554.,1555.,1556.,1550.,1550.,1554.,1555.,1556.,1550.,1550.,1557.,1558.,1559. - }; - for(int i=0;i<40;i++) - CPPUNIT_ASSERT_DOUBLES_EQUAL(expected3[i],srcField->getArray()->getConstPointer()[i],1e-3);//1e-3 precision due to non coincidence in 1D mesh - srcField->decrRef(); - trgField->decrRef(); - // - double vals3[340]={ - 100., 101., 102., 103., 104., 105., 106., 107., 108., 109., 110., 111., 112., 113., 114., 115., - 200., 201., 202., 203., 204., 205., 206., 207., 208., 209., 210., 211., 212., 213., 214., 215., - 300., 301., 302., 303., 304., 305., 306., 307., 308., 309., 310., 311., 312., 313., 314., 315., - 400., 401., 402., 403., 404., 405., 406., 407., 408., 409., 410., 411., 412., 413., 414., 415., - 500., 501., 502., 503., 504., 505., 506., 507., 508., 509., 510., 511., 512., 513., 514., 515., - 600., 601., 602., 603., 604., 605., 606., 607., 608., 609., 610., 611., 612., 613., 614., 615., - 700., 701., 702., 703., 704., 705., 706., 707., 708., 709., 710., 711., 712., 713., 714., 715., - 800., 801., 802., 803., 804., 805., 806., 807., 808., 809., 810., 811., 812., 813., 814., 815., - 900., 901., 902., 903., 904., 905., 906., 907., 908., 909., 910., 911., 912., 913., 914., 915., - 1000., 1001., 1002., 1003., 1004., 1005., 1006., 1007., 1008., 1009., 1010., 1011., 1012., 1013., 1014., 1015., - 1100., 1101., 1102., 1103., 1104., 1105., 1106., 1107., 1108., 1109., 1110., 1111., 1112., 1113., 1114., 1115., - 1200., 1201., 1202., 1203., 1204., 1205., 1206., 1207., 1208., 1209., 1210., 1211., 1212., 1213., 1214., 1215., - 1300., 1301., 1302., 1303., 1304., 1305., 1306., 1307., 1308., 1309., 1310., 1311., 1312., 1313., 1314., 1315., - 1400., 1401., 1402., 1403., 1404., 1405., 1406., 1407., 1408., 1409., 1410., 1411., 1412., 1413., 1414., 1415., - 1500., 1501., 1502., 1503., 1504., 1505., 1506., 1507., 1508., 1509., 1510., 1511., 1512., 1513., 1514., 1515., - 1600., 1601., 1602., 1603., 1604., 1605., 1606., 1607., 1608., 1609., 1610., 1611., 1612., 1613., 1614., 1615., - 1700., 1701., 1702., 1703., 1704., 1705., 1706., 1707., 1708., 1709., 1710., 1711., 1712., 1713., 1714., 1715., - 1800., 1801., 1802., 1803., 1804., 1805., 1806., 1807., 1808., 1809., 1810., 1811., 1812., 1813., 1814., 1815., - 1900., 1901., 1902., 1903., 1904., 1905., 1906., 1907., 1908., 1909., 1910., 1911., 1912., 1913., 1914., 1915., - 2000., 2001., 2002., 2003., 2004., 2005., 2006., 2007., 2008., 2009., 2010., 2011., 2012., 2013., 2014., 2015., - 116.,216.,316.,416.,516.,616.,716.,816.,916.,1016.,1116.,1216.,1316.,1416.,1516.,1616.,1716.,1816.,1916.,2016. - }; - CPPUNIT_ASSERT_EQUAL(1,remapper.prepare(meshNE,meshTFE,"P0P0")); - trgField=MEDCouplingFieldDouble::New(ON_CELLS); - trgField->setNature(ConservativeVolumic); - trgField->setMesh(meshTFE); - array=DataArrayDouble::New(); - array->alloc(meshTFE->getNumberOfCells(),1); - trgField->setArray(array); - std::copy(vals3,vals3+meshTFE->getNumberOfCells(),array->getPointer()); - array->decrRef(); - srcField=remapper.reverseTransferField(trgField,4.220173); - double expected4[40]={ - 566.,566.,552.5,553.5,554.5,566.,566.,554.5,555.5,556.5,566.,566.,558.5,559.5,560.5,566.,566.,560.5,561.5,562.5, - 1566.,1566.,1552.5,1553.5,1554.5,1566.,1566.,1554.5,1555.5,1556.5,1566.,1566.,1558.5,1559.5,1560.5,1566.,1566.,1560.5,1561.5,1562.5 - }; - for(int i=0;i<40;i++) - CPPUNIT_ASSERT_DOUBLES_EQUAL(expected4[i],srcField->getArray()->getConstPointer()[i],1e-3);//1e-3 precision due to non coincidence in 1D mesh - srcField->decrRef(); - trgField->decrRef(); - // - meshN2D->decrRef(); - meshTT2D->decrRef(); - meshTF2D->decrRef(); - meshNE->decrRef(); - meshTTE->decrRef(); - meshTFE->decrRef(); - meshN->decrRef(); - meshTT->decrRef(); - meshTF->decrRef(); -} - -void MEDCouplingRemapperTest::testPrepareEx1() -{ - MEDCouplingUMesh *sourceMesh=MEDCouplingBasicsTest::build2DSourceMesh_1(); - MEDCouplingUMesh *targetMesh=build2DTargetMesh_3(); - // - MEDCouplingRemapper remapper; - remapper.setPrecision(1e-12); - remapper.setIntersectionType(INTERP_KERNEL::Triangulation); - MEDCouplingFieldTemplate *srcFt=MEDCouplingFieldTemplate::New(ON_CELLS); - MEDCouplingFieldTemplate *trgFt=MEDCouplingFieldTemplate::New(ON_CELLS); - srcFt->setMesh(sourceMesh); - trgFt->setMesh(targetMesh); - CPPUNIT_ASSERT_EQUAL(1,remapper.prepareEx(srcFt,trgFt)); - srcFt->decrRef(); - trgFt->decrRef(); - MEDCouplingFieldDouble *srcField=MEDCouplingFieldDouble::New(ON_CELLS); - srcField->setNature(ConservativeVolumic); - srcField->setMesh(sourceMesh); - DataArrayDouble *array=DataArrayDouble::New(); - array->alloc(sourceMesh->getNumberOfCells(),1); - srcField->setArray(array); - double *ptr=array->getPointer(); - for(int i=0;igetNumberOfCells();i++) - ptr[i]=(double)(i+7); - array->decrRef(); - MEDCouplingFieldDouble *trgfield=remapper.transferField(srcField,4.220173); - const double *values=trgfield->getArray()->getConstPointer(); - const double valuesExpected[4]={7.75, 7.0625, 4.220173,8.0}; - CPPUNIT_ASSERT_EQUAL(4,trgfield->getArray()->getNumberOfTuples()); - CPPUNIT_ASSERT_EQUAL(1,trgfield->getArray()->getNumberOfComponents()); - for(int i0=0;i0<4;i0++) - CPPUNIT_ASSERT_DOUBLES_EQUAL(valuesExpected[i0],values[i0],1e-12); - trgfield->decrRef(); - srcField->decrRef(); - sourceMesh->decrRef(); - targetMesh->decrRef(); -} - -MEDCouplingUMesh *MEDCouplingRemapperTest::build1DTargetMesh_2() -{ - double targetCoords[20]={ - 0.59,0.09, 0.69,0.19, 0.21,-0.29,0.31,-0.19, 0.45,0.25,0.65,0.45, - -0.2,-0.2,0.11,0.11, 0.25,0.25, 0.45,0.45 - }; - int targetConn[10]={0,1, 2,3, 4,5, 6,7, 8,9}; - - MEDCouplingUMesh *targetMesh=MEDCouplingUMesh::New("my name of mesh 1D 2",1); - targetMesh->allocateCells(5); - for(int i=0;i<5;i++) - targetMesh->insertNextCell(INTERP_KERNEL::NORM_SEG2,2,targetConn+2*i); - targetMesh->finishInsertingCells(); - DataArrayDouble *myCoords=DataArrayDouble::New(); - myCoords->alloc(10,2); - std::copy(targetCoords,targetCoords+20,myCoords->getPointer()); - targetMesh->setCoords(myCoords); - myCoords->decrRef(); - return targetMesh; -} - -MEDCouplingUMesh *MEDCouplingRemapperTest::build2DTargetMesh_3() -{ - double targetCoords[20]={-0.6,-0.4, -0.1,-0.4, 1.1,-0.4, 2.1,-0.4, - -0.6,0.1, -0.1,0.1, 1.1,0.1, 2.1,0.1, - -0.6,1.1, -0.1,1.1}; - int targetConn[16]={0,4,5,1, 1,5,6,2, 2,6,7,3, 4,8,9,5}; - MEDCouplingUMesh *targetMesh=MEDCouplingUMesh::New(); - targetMesh->setMeshDimension(2); - targetMesh->allocateCells(4); - for(int i=0;i<4;i++) - targetMesh->insertNextCell(INTERP_KERNEL::NORM_QUAD4,4,targetConn+4*i); - targetMesh->finishInsertingCells(); - DataArrayDouble *myCoords=DataArrayDouble::New(); - myCoords->alloc(10,2); - std::copy(targetCoords,targetCoords+20,myCoords->getPointer()); - targetMesh->setCoords(myCoords); - myCoords->decrRef(); - return targetMesh; -} - -MEDCouplingUMesh *MEDCouplingRemapperTest::build3DExtrudedUMesh_1(MEDCouplingUMesh *&mesh2D) -{ - double coords[180]={ - 0.,0.,0., 1.,1.,0., 1.,1.25,0., 0.,1.,0., 1.,1.5,0., 2.,0.,0., 2.,1.,0., 1.,2.,0., 0.,2.,0., 3.,1.,0., - 3.,2.,0., 0.,1.,0., 1.,3.,0., 2.,2.,0., 2.,3.,0., - 0.,0.,1., 1.,1.,1., 1.,1.25,1., 0.,1.,1., 1.,1.5,1., 2.,0.,1., 2.,1.,1., 1.,2.,1., 0.,2.,1., 3.,1.,1., - 3.,2.,1., 0.,1.,1., 1.,3.,1., 2.,2.,1., 2.,3.,1., - 0.,0.,2., 1.,1.,2., 1.,1.25,2., 0.,1.,2., 1.,1.5,2., 2.,0.,2., 2.,1.,2., 1.,2.,2., 0.,2.,2., 3.,1.,2., - 3.,2.,2., 0.,1.,2., 1.,3.,2., 2.,2.,2., 2.,3.,2., - 0.,0.,3., 1.,1.,3., 1.,1.25,3., 0.,1.,3., 1.,1.5,3., 2.,0.,3., 2.,1.,3., 1.,2.,3., 0.,2.,3., 3.,1.,3., - 3.,2.,3., 0.,1.,3., 1.,3.,3., 2.,2.,3., 2.,3.,3.}; - - int conn[354]={ - // 0 - 0,11,1,3,15,26,16,18, 1,2,4,7,13,6,-1,1,16,21,6,-1,6,21,28,13,-1,13,7,22,28,-1,7,4,19,22,-1,4,2,17,19,-1,2,1,16,17,-1,16,21,28,22,19,17, - 1,6,5,3,16,21,20,18, 13,10,9,6,28,25,24,21, - 11,8,7,4,2,1,-1,11,26,16,1,-1,1,16,17,2,-1,2,17,19,4,-1,4,19,22,7,-1,7,8,23,22,-1,8,11,26,23,-1,26,16,17,19,22,23, - 7,12,14,13,22,27,29,28, - // 1 - 15,26,16,18,30,41,31,33, 16,17,19,22,28,21,-1,16,31,36,21,-1,21,36,43,28,-1,28,22,37,43,-1,22,19,34,37,-1,19,17,32,34,-1,17,16,31,32,-1,31,36,43,37,34,32, - 16,21,20,18,31,36,35,33, 28,25,24,21,43,40,39,36, - 26,23,22,19,17,16,-1,26,41,31,16,-1,16,31,32,17,-1,17,32,34,19,-1,19,34,37,22,-1,22,23,38,37,-1,23,26,41,38,-1,41,31,32,34,37,38, - 22,27,29,28,37,42,44,43, - // 2 - 30,41,31,33,45,56,46,48, 31,32,34,37,43,36,-1,31,46,51,36,-1,36,51,58,43,-1,43,37,52,58,-1,37,34,49,52,-1,34,32,47,49,-1,32,31,46,47,-1,46,51,58,52,49,47, - 31,36,35,33,46,51,50,48, 43,40,39,36,58,55,54,51, - 41,38,37,34,32,31,-1,41,56,46,31,-1,31,46,47,32,-1,32,47,49,34,-1,34,49,52,37,-1,37,38,53,52,-1,38,41,56,53,-1,56,46,47,49,52,53, - 37,42,44,43,52,57,59,58 - }; - int conn2[28]={7,12,14,13, 11,8,7,4,2,1, 13,10,9,6, 1,6,5,3, 1,2,4,7,13,6, 0,11,1,3}; - // - MEDCouplingUMesh *ret=MEDCouplingUMesh::New(); - ret->setMeshDimension(3); - ret->allocateCells(18); - // - ret->insertNextCell(INTERP_KERNEL::NORM_HEXA8,8,conn); - ret->insertNextCell(INTERP_KERNEL::NORM_POLYHED,43,conn+8); - ret->insertNextCell(INTERP_KERNEL::NORM_HEXA8,8,conn+51); - ret->insertNextCell(INTERP_KERNEL::NORM_HEXA8,8,conn+59); - ret->insertNextCell(INTERP_KERNEL::NORM_POLYHED,43,conn+67); - ret->insertNextCell(INTERP_KERNEL::NORM_HEXA8,8,conn+110); - // - ret->insertNextCell(INTERP_KERNEL::NORM_HEXA8,8,conn+118); - ret->insertNextCell(INTERP_KERNEL::NORM_POLYHED,43,conn+126); - ret->insertNextCell(INTERP_KERNEL::NORM_HEXA8,8,conn+169); - ret->insertNextCell(INTERP_KERNEL::NORM_HEXA8,8,conn+177); - ret->insertNextCell(INTERP_KERNEL::NORM_POLYHED,43,conn+185); - ret->insertNextCell(INTERP_KERNEL::NORM_HEXA8,8,conn+228); - // - ret->insertNextCell(INTERP_KERNEL::NORM_HEXA8,8,conn+236); - ret->insertNextCell(INTERP_KERNEL::NORM_POLYHED,43,conn+244); - ret->insertNextCell(INTERP_KERNEL::NORM_HEXA8,8,conn+287); - ret->insertNextCell(INTERP_KERNEL::NORM_HEXA8,8,conn+295); - ret->insertNextCell(INTERP_KERNEL::NORM_POLYHED,43,conn+303); - ret->insertNextCell(INTERP_KERNEL::NORM_HEXA8,8,conn+346); - // - ret->finishInsertingCells(); - DataArrayDouble *myCoords=DataArrayDouble::New(); - myCoords->alloc(60,3); - std::copy(coords,coords+180,myCoords->getPointer()); - ret->setCoords(myCoords); - // - mesh2D=MEDCouplingUMesh::New(); - mesh2D->setMeshDimension(2); - mesh2D->allocateCells(6); - mesh2D->insertNextCell(INTERP_KERNEL::NORM_QUAD4,4,conn2); - mesh2D->insertNextCell(INTERP_KERNEL::NORM_POLYGON,6,conn2+4); - mesh2D->insertNextCell(INTERP_KERNEL::NORM_QUAD4,4,conn2+10); - mesh2D->insertNextCell(INTERP_KERNEL::NORM_QUAD4,4,conn2+14); - mesh2D->insertNextCell(INTERP_KERNEL::NORM_POLYGON,6,conn2+18); - mesh2D->insertNextCell(INTERP_KERNEL::NORM_QUAD4,4,conn2+24); - mesh2D->setCoords(myCoords); - myCoords->decrRef(); - return ret; -} - -void MEDCouplingRemapperTest::testPartialTransfer1() -{ - MEDCouplingRemapper remapper; - MEDCouplingUMesh *sourceMesh=build1DTargetMesh_2(); - MEDCouplingUMesh *targetMesh=MEDCouplingBasicsTest::build2DTargetMesh_1(); - remapper.setIntersectionType(INTERP_KERNEL::PointLocator); - CPPUNIT_ASSERT_EQUAL(1,remapper.prepare(sourceMesh,targetMesh,"P0P0")); - MEDCouplingFieldDouble *srcField=MEDCouplingFieldDouble::New(ON_CELLS); - srcField->setNature(ConservativeVolumic); - srcField->setMesh(sourceMesh); - DataArrayDouble *array=DataArrayDouble::New(); - array->alloc(sourceMesh->getNumberOfCells(),1); - srcField->setArray(array); - double *ptr=array->getPointer(); - for(int i=0;igetNumberOfCells();i++) - ptr[i]=(double)(i+7); - array->decrRef(); - MEDCouplingFieldDouble *trgField=MEDCouplingFieldDouble::New(ON_CELLS); - trgField->setNature(ConservativeVolumic); - trgField->setMesh(targetMesh); - array=DataArrayDouble::New(); - array->alloc(targetMesh->getNumberOfCells(),1); - ptr=array->getPointer(); - std::fill(ptr,ptr+targetMesh->getNumberOfCells(),96.3); - trgField->setArray(array); - array->decrRef(); - remapper.partialTransfer(srcField,trgField); - const double valuesExpected9[5]={10.,8.,7.,96.3,10.}; - const double *values=trgField->getArray()->getConstPointer(); - for(int i0=0;i0<5;i0++) - CPPUNIT_ASSERT_DOUBLES_EQUAL(valuesExpected9[i0],values[i0],1e-12); - trgField->decrRef(); - srcField->decrRef(); - sourceMesh->decrRef(); - targetMesh->decrRef(); -} - -void MEDCouplingRemapperTest::testBugNonRegression1() -{ - // source - DataArrayDouble *coordsSrc(DataArrayDouble::New()); - const double coordsSrcData[18]={-6.25,3.6084391824351605,264.85199999999998,-6.25,3.6084391824351605,289.05200000000002,-6.2499999999999991,-3.6084391824351618,264.85199999999998,-6.2499999999999991,-3.6084391824351618,289.05200000000002,-1.7763568394002505e-15,4.4408920985006262e-15,264.85199999999998,-1.7763568394002505e-15,4.4408920985006262e-15,289.05200000000002}; - coordsSrc->useArray(coordsSrcData,false,CPP_DEALLOC,6,3); - DataArrayInt *connSrc(DataArrayInt::New()),*connISrc(DataArrayInt::New()); - const int connSrcData[7]={16,2,0,4,3,1,5}; - connSrc->useArray(connSrcData,false,CPP_DEALLOC,7,1); - const int connISrcData[2]={0,7}; - connISrc->useArray(connISrcData,false,CPP_DEALLOC,2,1); - MEDCouplingUMesh *srcMesh(MEDCouplingUMesh::New("source",3)); - srcMesh->setCoords(coordsSrc); - srcMesh->setConnectivity(connSrc,connISrc,true); - coordsSrc->decrRef(); connSrc->decrRef(); connISrc->decrRef(); - // target - DataArrayDouble *coordsTrg(DataArrayDouble::New()); -const double coordsTrgData[36]={-2,1.1547005383792521,264.85199999999998,-2,0.57735026918962618,264.85199999999998,-2.5,0.2886751345948132,264.85199999999998,-2.5,1.443375672974065,264.85199999999998,-3.0000000000000004,1.1547005383792526,264.85199999999998,-3.0000000000000004,0.57735026918962662,264.85199999999998,-2,1.1547005383792521,289.05200000000002,-2,0.57735026918962618,289.05200000000002,-2.5,0.2886751345948132,289.05200000000002,-2.5,1.443375672974065,289.05200000000002,-3.0000000000000004,1.1547005383792526,289.05200000000002,-3.0000000000000004,0.57735026918962662,289.05200000000002}; - coordsTrg->useArray(coordsTrgData,false,CPP_DEALLOC,12,3); - DataArrayInt *connTrg=DataArrayInt::New(); - const int connTrgData[44]={31,0,1,2,5,4,3,-1,7,6,9,10,11,8,-1,3,9,6,0,-1,4,10,9,3,-1,5,11,10,4,-1,2,8,11,5,-1,1,7,8,2,-1,0,6,7,1}; - connTrg->useArray(connTrgData,false,CPP_DEALLOC,44,1); - DataArrayInt *connITrg=DataArrayInt::New(); - const int connITrgData[2]={0,44}; - connITrg->useArray(connITrgData,false,CPP_DEALLOC,2,1); - MEDCouplingUMesh *trgMesh=MEDCouplingUMesh::New("target",3); - trgMesh->setCoords(coordsTrg); - trgMesh->setConnectivity(connTrg,connITrg,true); - coordsTrg->decrRef(); connTrg->decrRef(); connITrg->decrRef(); - // Go ! - const double valExpected(20.957814771583468); - MEDCouplingRemapper remapper; - remapper.setPrecision(1e-12); - remapper.setIntersectionType(INTERP_KERNEL::Triangulation); - CPPUNIT_ASSERT_EQUAL(1,remapper.prepare(srcMesh,trgMesh,"P0P0")); - std::vector > matrx(remapper.getCrudeMatrix()); - CPPUNIT_ASSERT_EQUAL(1,(int)matrx.size()); - CPPUNIT_ASSERT_EQUAL(1,(int)matrx[0].size()); - CPPUNIT_ASSERT_DOUBLES_EQUAL(valExpected,matrx[0][0],1e-13); - // - srcMesh->decrRef(); trgMesh->decrRef(); -} - diff --git a/src/MEDCoupling/Test/MEDCouplingRemapperTest.hxx b/src/MEDCoupling/Test/MEDCouplingRemapperTest.hxx deleted file mode 100644 index 72a4f45fc..000000000 --- a/src/MEDCoupling/Test/MEDCouplingRemapperTest.hxx +++ /dev/null @@ -1,68 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 -// 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 __MEDCOUPLINGREMAPPERTEST_HXX__ -#define __MEDCOUPLINGREMAPPERTEST_HXX__ - -#include - -#include -#include - -namespace ParaMEDMEM -{ - class MEDCouplingUMesh; - - class MEDCouplingRemapperTest : public CppUnit::TestFixture - { - CPPUNIT_TEST_SUITE(MEDCouplingRemapperTest); - CPPUNIT_TEST( test2DInterpP0P0_1 ); - CPPUNIT_TEST( test2DInterpP0P0R_1 ); - CPPUNIT_TEST( test1DInterp_1 ); - CPPUNIT_TEST( test2DInterpMultiMethods ); - CPPUNIT_TEST( testMultiDimCombi ); - CPPUNIT_TEST( testNatureOfField ); - CPPUNIT_TEST( testExtruded ); - CPPUNIT_TEST( testExtruded2 ); - CPPUNIT_TEST( testPrepareEx1 ); - CPPUNIT_TEST( testPartialTransfer1 ); - CPPUNIT_TEST( testBugNonRegression1 ); - CPPUNIT_TEST_SUITE_END(); - public: - void test2DInterpP0P0_1(); - void test2DInterpP0P0R_1(); - void test1DInterp_1(); - void test2DInterpMultiMethods(); - void testMultiDimCombi(); - void testNatureOfField(); - void testExtruded(); - void testExtruded2(); - void testPrepareEx1(); - void testPartialTransfer1(); - // - void testBugNonRegression1(); - private: - static MEDCouplingUMesh *build1DTargetMesh_2(); - static MEDCouplingUMesh *build2DTargetMesh_3(); - static MEDCouplingUMesh *build3DExtrudedUMesh_1(MEDCouplingUMesh *&mesh2D); - }; -} - -#endif diff --git a/src/MEDCoupling/Test/TestMEDCoupling.cxx b/src/MEDCoupling/Test/TestMEDCoupling.cxx deleted file mode 100644 index 0d017ae0d..000000000 --- a/src/MEDCoupling/Test/TestMEDCoupling.cxx +++ /dev/null @@ -1,35 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 -// 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 "MEDCouplingBasicsTest1.hxx" -#include "MEDCouplingBasicsTest2.hxx" -#include "MEDCouplingBasicsTest3.hxx" -#include "MEDCouplingBasicsTest4.hxx" -#include "MEDCouplingBasicsTest5.hxx" -#include "MEDCouplingBasicsTestInterp.hxx" - -CPPUNIT_TEST_SUITE_REGISTRATION( ParaMEDMEM::MEDCouplingBasicsTest1 ); -CPPUNIT_TEST_SUITE_REGISTRATION( ParaMEDMEM::MEDCouplingBasicsTest2 ); -CPPUNIT_TEST_SUITE_REGISTRATION( ParaMEDMEM::MEDCouplingBasicsTest3 ); -CPPUNIT_TEST_SUITE_REGISTRATION( ParaMEDMEM::MEDCouplingBasicsTest4 ); -CPPUNIT_TEST_SUITE_REGISTRATION( ParaMEDMEM::MEDCouplingBasicsTest5 ); -CPPUNIT_TEST_SUITE_REGISTRATION( ParaMEDMEM::MEDCouplingBasicsTestInterp ); - -#include "BasicMainTest.hxx" diff --git a/src/MEDCoupling/Test/TestMEDCouplingRemapper.cxx b/src/MEDCoupling/Test/TestMEDCouplingRemapper.cxx deleted file mode 100644 index cbcb2d22b..000000000 --- a/src/MEDCoupling/Test/TestMEDCouplingRemapper.cxx +++ /dev/null @@ -1,25 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 -// 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 "MEDCouplingRemapperTest.hxx" - -CPPUNIT_TEST_SUITE_REGISTRATION( ParaMEDMEM::MEDCouplingRemapperTest ); - -#include "BasicMainTest.hxx" diff --git a/src/MEDCoupling_Swig/CMakeLists.txt b/src/MEDCoupling_Swig/CMakeLists.txt deleted file mode 100644 index 07929a88d..000000000 --- a/src/MEDCoupling_Swig/CMakeLists.txt +++ /dev/null @@ -1,114 +0,0 @@ -# Copyright (C) 2012-2015 CEA/DEN, EDF 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, 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 -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -# -# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -# - -INCLUDE(${SWIG_USE_FILE}) - -ADD_DEFINITIONS(${PYTHON_DEFINITIONS}) - -SET_SOURCE_FILES_PROPERTIES(MEDCoupling.i PROPERTIES CPLUSPLUS ON) -SET_SOURCE_FILES_PROPERTIES(MEDCoupling.i PROPERTIES SWIG_DEFINITIONS "-shadow") -SET(SWIG_MODULE_MEDCoupling_EXTRA_FLAGS ${SWIG_EXTRA_FLAGS_FOR_NUMPYANDSCIPY}) - -SET (MEDCoupling_SWIG_DPYS_FILES - MEDCouplingCommon.i - MEDCouplingMemArray.i - MEDCouplingFieldDiscretization.i - MEDCouplingFinalize.i - MEDCouplingTypemaps.i) - -INCLUDE_DIRECTORIES( - ${PYTHON_INCLUDE_DIRS} - ${PTHREAD_INCLUDE_DIR} # pthread dependancy due to python2.7 library - ${CMAKE_CURRENT_SOURCE_DIR} - ${CMAKE_CURRENT_BINARY_DIR} - ${CMAKE_CURRENT_SOURCE_DIR}/../MEDCoupling - ${CMAKE_CURRENT_SOURCE_DIR}/../INTERP_KERNEL - ${CMAKE_CURRENT_SOURCE_DIR}/../INTERP_KERNEL/Bases - ${CMAKE_CURRENT_SOURCE_DIR}/../INTERP_KERNEL/Geometric2D - ${CMAKE_CURRENT_SOURCE_DIR}/../INTERP_KERNEL/ExprEval - ${CMAKE_CURRENT_SOURCE_DIR}/../INTERP_KERNEL/GaussPoints - ${PROJECT_BINARY_DIR}/doc - ) - -# _ABR_ Ensure dependency mechanism on all SWIG files and headers -SET (SWIG_MODULE_MEDCoupling_EXTRA_DEPS ${MEDCoupling_SWIG_DPYS_FILES} - ${medcoupling_HEADERS_HXX} ${medcoupling_HEADERS_TXX} - ${interpkernel_HEADERS_HXX} ${interpkernel_HEADERS_TXX}) - -# SWIG must run after the doc if we want to have the docstrings extracted from Doxygen -# into the Python module: -IF(SALOME_BUILD_DOC) - LIST(APPEND SWIG_MODULE_MEDCoupling_EXTRA_FLAGS -DWITH_DOCSTRINGS) - LIST(APPEND SWIG_MODULE_MEDCoupling_EXTRA_DEPS - ${PROJECT_BINARY_DIR}/doc/MEDCoupling_doc.i - swig_ready) -ENDIF() - -SWIG_ADD_MODULE(MEDCoupling python MEDCoupling.i) -SWIG_LINK_LIBRARIES(MEDCoupling ${PYTHON_LIBRARIES} ${PLATFORM_LIBS} medcoupling) - -SET_SOURCE_FILES_PROPERTIES(MEDCouplingRemapper.i PROPERTIES CPLUSPLUS ON) -SET_SOURCE_FILES_PROPERTIES(MEDCouplingRemapper.i PROPERTIES SWIG_DEFINITIONS "-shadow") -SET(SWIG_MODULE_MEDCouplingRemapper_EXTRA_FLAGS ${SWIG_EXTRA_FLAGS_FOR_NUMPYANDSCIPY}) - -# _ABR_ Ensure dependency mechanism on all SWIG files and headers -SET (SWIG_MODULE_MEDCouplingRemapper_EXTRA_DEPS ${MEDCoupling_SWIG_DPYS_FILES} - ${medcoupling_HEADERS_HXX} ${medcoupling_HEADERS_TXX} - ${interpkernel_HEADERS_HXX} ${interpkernel_HEADERS_TXX}) - -SWIG_ADD_MODULE(MEDCouplingRemapper python MEDCouplingRemapper.i) -SWIG_LINK_LIBRARIES(MEDCouplingRemapper ${PYTHON_LIBRARIES} medcouplingremapper) - -IF(WIN32) - SET_TARGET_PROPERTIES(_MEDCouplingRemapper PROPERTIES DEBUG_OUTPUT_NAME _MEDCouplingRemapper_d) - SET_TARGET_PROPERTIES(_MEDCoupling PROPERTIES DEBUG_OUTPUT_NAME _MEDCoupling_d) -ENDIF(WIN32) -INSTALL(TARGETS ${SWIG_MODULE_MEDCoupling_REAL_NAME} ${SWIG_MODULE_MEDCouplingRemapper_REAL_NAME} DESTINATION ${SALOME_INSTALL_PYTHON}) - -SET(PYFILES_TO_INSTALL ${CMAKE_CURRENT_BINARY_DIR}/MEDCoupling.py ${CMAKE_CURRENT_BINARY_DIR}/MEDCouplingRemapper.py) -SALOME_INSTALL_SCRIPTS("${PYFILES_TO_INSTALL}" ${SALOME_INSTALL_PYTHON}) - -INSTALL(FILES MEDCoupling.i MEDCouplingCommon.i MEDCouplingRefCountObject.i MEDCouplingMemArray.i MEDCouplingFieldDiscretization.i MEDCouplingTimeDiscretization.i MEDCouplingFinalize.i MEDCouplingRemapper.i MEDCouplingTypemaps.i MEDCouplingDataArrayTypemaps.i DESTINATION ${SALOME_INSTALL_HEADERS}) -INSTALL(FILES MEDCouplingBasicsTest.py MEDCouplingRemapperTest.py MEDCouplingDataForTest.py MEDCouplingNumPyTest.py MEDCouplingPickleTest.py DESTINATION ${SALOME_INSTALL_SCRIPT_PYTHON}) -INSTALL(FILES MEDCouplingExamplesTest.py DESTINATION ${SALOME_INSTALL_SCRIPT_PYTHON}) - -SALOME_GENERATE_TESTS_ENVIRONMENT(tests_env) - -ADD_TEST(MEDCouplingBasicsTest ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/MEDCouplingBasicsTest.py) -SET_TESTS_PROPERTIES(MEDCouplingBasicsTest PROPERTIES ENVIRONMENT "${tests_env}") -ADD_TEST(MEDCouplingExamplesTest ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/MEDCouplingExamplesTest.py) -SET_TESTS_PROPERTIES(MEDCouplingExamplesTest PROPERTIES ENVIRONMENT "${tests_env}") -ADD_TEST(MEDCouplingRemapperTest ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/MEDCouplingRemapperTest.py) -SET_TESTS_PROPERTIES(MEDCouplingRemapperTest PROPERTIES ENVIRONMENT "${tests_env}") - -IF(NUMPY_FOUND) - ADD_TEST(MEDCouplingNumPyTest ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/MEDCouplingNumPyTest.py) - SET_TESTS_PROPERTIES(MEDCouplingNumPyTest PROPERTIES ENVIRONMENT "${tests_env}") - ADD_TEST(MEDCouplingPickleTest ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/MEDCouplingPickleTest.py) - SET_TESTS_PROPERTIES(MEDCouplingPickleTest PROPERTIES ENVIRONMENT "${tests_env}") -ENDIF(NUMPY_FOUND) - -# Application tests - -SET(TEST_INSTALL_DIRECTORY ${SALOME_INSTALL_SCRIPT_SCRIPTS}/test/MEDCoupling/MEDCoupling_Swig) -INSTALL(FILES MEDCouplingBasicsTest.py MEDCouplingRemapperTest.py MEDCouplingDataForTest.py MEDCouplingNumPyTest.py MEDCouplingPickleTest.py MEDCouplingExamplesTest.py DESTINATION ${TEST_INSTALL_DIRECTORY}) - -INSTALL(FILES CTestTestfileInstall.cmake - DESTINATION ${TEST_INSTALL_DIRECTORY} - RENAME CTestTestfile.cmake) diff --git a/src/MEDCoupling_Swig/CTestTestfileInstall.cmake b/src/MEDCoupling_Swig/CTestTestfileInstall.cmake deleted file mode 100644 index c1f34cca8..000000000 --- a/src/MEDCoupling_Swig/CTestTestfileInstall.cmake +++ /dev/null @@ -1,34 +0,0 @@ -# Copyright (C) 2015 CEA/DEN, EDF 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, 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 -# 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_TEST(MEDCouplingBasicsTest python MEDCouplingBasicsTest.py) -SET_TESTS_PROPERTIES(MEDCouplingBasicsTest PROPERTIES LABELS "${COMPONENT_NAME}") - -ADD_TEST(MEDCouplingExamplesTest python MEDCouplingExamplesTest.py) -SET_TESTS_PROPERTIES(MEDCouplingExamplesTest PROPERTIES LABELS "${COMPONENT_NAME}") - -ADD_TEST(MEDCouplingRemapperTest python MEDCouplingRemapperTest.py) -SET_TESTS_PROPERTIES(MEDCouplingRemapperTest PROPERTIES LABELS "${COMPONENT_NAME}") - -# if numpy is used -ADD_TEST(MEDCouplingNumPyTest python MEDCouplingNumPyTest.py) -SET_TESTS_PROPERTIES(MEDCouplingNumPyTest PROPERTIES LABELS "${COMPONENT_NAME}") - -ADD_TEST(MEDCouplingPickleTest python MEDCouplingPickleTest.py) -SET_TESTS_PROPERTIES(MEDCouplingPickleTest PROPERTIES LABELS "${COMPONENT_NAME}") diff --git a/src/MEDCoupling_Swig/MEDCoupling.i b/src/MEDCoupling_Swig/MEDCoupling.i deleted file mode 100644 index d6450452e..000000000 --- a/src/MEDCoupling_Swig/MEDCoupling.i +++ /dev/null @@ -1,136 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// - -%include "MEDCouplingCommon.i" - -%pythoncode %{ -def ParaMEDMEMDataArrayDoublenew(cls,*args): - import _MEDCoupling - return _MEDCoupling.DataArrayDouble____new___(cls,args) -def ParaMEDMEMDataArrayDoubleIadd(self,*args): - import _MEDCoupling - return _MEDCoupling.DataArrayDouble____iadd___(self, self, *args) -def ParaMEDMEMDataArrayDoubleIsub(self,*args): - import _MEDCoupling - return _MEDCoupling.DataArrayDouble____isub___(self, self, *args) -def ParaMEDMEMDataArrayDoubleImul(self,*args): - import _MEDCoupling - return _MEDCoupling.DataArrayDouble____imul___(self, self, *args) -def ParaMEDMEMDataArrayDoubleIdiv(self,*args): - import _MEDCoupling - return _MEDCoupling.DataArrayDouble____idiv___(self, self, *args) -def ParaMEDMEMDataArrayDoubleIpow(self,*args): - import _MEDCoupling - return _MEDCoupling.DataArrayDouble____ipow___(self, self, *args) -def ParaMEDMEMMEDCouplingFieldDoublenew(cls,*args): - import _MEDCoupling - return _MEDCoupling.MEDCouplingFieldDouble____new___(cls,args) -def ParaMEDMEMMEDCouplingFieldDoubleIadd(self,*args): - import _MEDCoupling - return _MEDCoupling.MEDCouplingFieldDouble____iadd___(self, self, *args) -def ParaMEDMEMMEDCouplingFieldDoubleIsub(self,*args): - import _MEDCoupling - return _MEDCoupling.MEDCouplingFieldDouble____isub___(self, self, *args) -def ParaMEDMEMMEDCouplingFieldDoubleImul(self,*args): - import _MEDCoupling - return _MEDCoupling.MEDCouplingFieldDouble____imul___(self, self, *args) -def ParaMEDMEMMEDCouplingFieldDoubleIdiv(self,*args): - import _MEDCoupling - return _MEDCoupling.MEDCouplingFieldDouble____idiv___(self, self, *args) -def ParaMEDMEMMEDCouplingFieldDoubleIpow(self,*args): - import _MEDCoupling - return _MEDCoupling.MEDCouplingFieldDouble____ipow___(self, self, *args) -def ParaMEDMEMDataArrayIntnew(cls,*args): - import _MEDCoupling - return _MEDCoupling.DataArrayInt____new___(cls,args) -def ParaMEDMEMDataArrayIntIadd(self,*args): - import _MEDCoupling - return _MEDCoupling.DataArrayInt____iadd___(self, self, *args) -def ParaMEDMEMDataArrayIntIsub(self,*args): - import _MEDCoupling - return _MEDCoupling.DataArrayInt____isub___(self, self, *args) -def ParaMEDMEMDataArrayIntImul(self,*args): - import _MEDCoupling - return _MEDCoupling.DataArrayInt____imul___(self, self, *args) -def ParaMEDMEMDataArrayIntIdiv(self,*args): - import _MEDCoupling - return _MEDCoupling.DataArrayInt____idiv___(self, self, *args) -def ParaMEDMEMDataArrayIntImod(self,*args): - import _MEDCoupling - return _MEDCoupling.DataArrayInt____imod___(self, self, *args) -def ParaMEDMEMDataArrayIntIpow(self,*args): - import _MEDCoupling - return _MEDCoupling.DataArrayInt____ipow___(self, self, *args) -def ParaMEDMEMDataArrayDoubleTupleIadd(self,*args): - import _MEDCoupling - return _MEDCoupling.DataArrayDoubleTuple____iadd___(self, self, *args) -def ParaMEDMEMDataArrayDoubleTupleIsub(self,*args): - import _MEDCoupling - return _MEDCoupling.DataArrayDoubleTuple____isub___(self, self, *args) -def ParaMEDMEMDataArrayDoubleTupleImul(self,*args): - import _MEDCoupling - return _MEDCoupling.DataArrayDoubleTuple____imul___(self, self, *args) -def ParaMEDMEMDataArrayDoubleTupleIdiv(self,*args): - import _MEDCoupling - return _MEDCoupling.DataArrayDoubleTuple____idiv___(self, self, *args) -def ParaMEDMEMDataArrayIntTupleIadd(self,*args): - import _MEDCoupling - return _MEDCoupling.DataArrayIntTuple____iadd___(self, self, *args) -def ParaMEDMEMDataArrayIntTupleIsub(self,*args): - import _MEDCoupling - return _MEDCoupling.DataArrayIntTuple____isub___(self, self, *args) -def ParaMEDMEMDataArrayIntTupleImul(self,*args): - import _MEDCoupling - return _MEDCoupling.DataArrayIntTuple____imul___(self, self, *args) -def ParaMEDMEMDataArrayIntTupleIdiv(self,*args): - import _MEDCoupling - return _MEDCoupling.DataArrayIntTuple____idiv___(self, self, *args) -def ParaMEDMEMDataArrayIntTupleImod(self,*args): - import _MEDCoupling - return _MEDCoupling.DataArrayIntTuple____imod___(self, self, *args) -def ParaMEDMEMDenseMatrixIadd(self,*args): - import _MEDCoupling - return _MEDCoupling.DenseMatrix____iadd___(self, self, *args) -def ParaMEDMEMDenseMatrixIsub(self,*args): - import _MEDCoupling - return _MEDCoupling.DenseMatrix____isub___(self, self, *args) -def ParaMEDMEMMEDCouplingUMeshnew(cls,*args): - import _MEDCoupling - return _MEDCoupling.MEDCouplingUMesh____new___(cls,args) -def ParaMEDMEMMEDCoupling1DGTUMeshnew(cls,*args): - import _MEDCoupling - return _MEDCoupling.MEDCoupling1DGTUMesh____new___(cls,args) -def ParaMEDMEMMEDCoupling1SGTUMeshnew(cls,*args): - import _MEDCoupling - return _MEDCoupling.MEDCoupling1SGTUMesh____new___(cls,args) -def ParaMEDMEMMEDCouplingCurveLinearMeshnew(cls,*args): - import _MEDCoupling - return _MEDCoupling.MEDCouplingCurveLinearMesh____new___(cls,args) -def ParaMEDMEMMEDCouplingCMeshnew(cls,*args): - import _MEDCoupling - return _MEDCoupling.MEDCouplingCMesh____new___(cls,args) -def ParaMEDMEMMEDCouplingIMeshnew(cls,*args): - import _MEDCoupling - return _MEDCoupling.MEDCouplingIMesh____new___(cls,args) -def ParaMEDMEMMEDCouplingExtrudedMeshnew(cls,*args): - import _MEDCoupling - return _MEDCoupling.MEDCouplingExtrudedMesh____new___(cls,args) -%} - -%include "MEDCouplingFinalize.i" diff --git a/src/MEDCoupling_Swig/MEDCouplingBasicsTest.py b/src/MEDCoupling_Swig/MEDCouplingBasicsTest.py deleted file mode 100644 index 18118dc75..000000000 --- a/src/MEDCoupling_Swig/MEDCouplingBasicsTest.py +++ /dev/null @@ -1,16776 +0,0 @@ -# -*- coding: iso-8859-1 -*- -# Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 -# 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 -# - -from MEDCoupling import * -import unittest -from math import pi,e,sqrt,cos,sin -from datetime import datetime -from MEDCouplingDataForTest import MEDCouplingDataForTest -import rlcompleter,readline # this line has to be here, to ensure a usability of MEDCoupling/MEDLoader. B4 removing it please notify to anthony.geay@cea.fr - -class MEDCouplingBasicsTest(unittest.TestCase): - def testArray2(self): - arr=DataArrayDouble.New() - arr.setValues([12.,11.,10.,9.,8.,7.,6.,5.,4.,3.,2.,1.],3,4) - arr.setInfoOnComponent(0,"ggg"); - arr.setInfoOnComponent(1,"hhhh"); - arr.setInfoOnComponent(2,"jj"); - arr.setInfoOnComponent(3,"kkkkkk"); - arr2=arr.convertToIntArr(); - arr3=arr2.convertToDblArr(); - self.assertTrue(arr.isEqual(arr3,1e-14)) - pass - - def testArray3(self): - arr1=DataArrayInt.New(); - arr1Ref=[0,10,1,11,2,12,3,13,4,14,5,15,6,16] - arr1.setValues(arr1Ref,7,2); - self.assertEqual(7,arr1.getNumberOfTuples()); - self.assertEqual(2,arr1.getNumberOfComponents()); - self.assertEqual(arr1Ref,list(arr1.getValues())); - arr2=arr1.substr(3); - self.assertEqual(4,arr2.getNumberOfTuples()); - self.assertEqual(2,arr2.getNumberOfComponents()); - self.assertEqual(arr1Ref[6:],list(arr2.getValues())); - arr3=arr1.substr(2,5); - self.assertEqual(3,arr3.getNumberOfTuples()); - self.assertEqual(2,arr3.getNumberOfComponents()); - self.assertEqual(arr1Ref[4:10],list(arr3.getValues())); - # - arr4=DataArrayDouble.New(); - arr4Ref=[0.8,10.8,1.9,11.9,2.1,12.1,3.2,13.2,4.3,14.3,5.4,15.4,6.5,16.5] - arr4.setValues(arr4Ref,7,2); - self.assertEqual(7,arr4.getNumberOfTuples()); - self.assertEqual(2,arr4.getNumberOfComponents()); - tmp=arr4.getValues() - for i in xrange(14): - self.assertTrue(abs(arr4Ref[i]-tmp[i])<1e-14); - pass - arr5=arr4.substr(3); - self.assertEqual(4,arr5.getNumberOfTuples()); - self.assertEqual(2,arr5.getNumberOfComponents()); - tmp=arr5.getValues() - for i in xrange(8): - self.assertTrue(abs(arr4Ref[6+i]-tmp[i])<1e-14); - pass - arr6=arr4.substr(2,5); - self.assertEqual(3,arr6.getNumberOfTuples()); - self.assertEqual(2,arr6.getNumberOfComponents()); - tmp=arr6.getValues() - for i in xrange(6): - self.assertTrue(abs(arr4Ref[4+i]-tmp[i])<1e-14); - pass - pass - - def testMesh(self): - tab4=[1, 2, 8, 7, 2, 3, 9, 8, 3, - 4, 10, 9, 4, 5, 11, 10, 5, - 0, 6, 11, 0, 1, 7, 6 ] - nbOfNodes=12 - nbOfCells=6 - coords=[ 0.024155, 0.04183768725682622, -0.305, 0.04831000000000001, -1.015761910347357e-17, - -0.305, 0.09662000000000001, -1.832979297858306e-18, -0.305, 0.120775, 0.04183768725682623, - -0.305, 0.09662000000000001, 0.08367537451365245, -0.305, 0.04831000000000001, 0.08367537451365246, - -0.305, 0.024155, 0.04183768725682622, -0.2863, 0.04831000000000001, -1.015761910347357e-17, -0.2863, - 0.09662000000000001, -1.832979297858306e-18, -0.2863, 0.120775, 0.04183768725682623, -0.2863, 0.09662000000000001, - 0.08367537451365245, -0.2863, 0.04831000000000001, 0.08367537451365246, -0.2863 ] - self.assertEqual(MEDCouplingMesh.GetNumberOfNodesOfGeometricType(NORM_TRI3),3) - self.assertTrue(MEDCouplingMesh.IsStaticGeometricType(NORM_TRI3)) - self.assertTrue(MEDCouplingMesh.IsLinearGeometricType(NORM_TRI3)) - self.assertEqual(MEDCouplingMesh.GetDimensionOfGeometricType(NORM_TRI3),2) - self.assertEqual(MEDCouplingMesh.GetReprOfGeometricType(NORM_TRI3),"NORM_TRI3") - self.assertRaises(InterpKernelException,MEDCouplingMesh.GetNumberOfNodesOfGeometricType,NORM_POLYGON) - self.assertTrue(not MEDCouplingMesh.IsStaticGeometricType(NORM_POLYGON)) - self.assertTrue(MEDCouplingMesh.IsLinearGeometricType(NORM_POLYGON)) - self.assertEqual(MEDCouplingMesh.GetDimensionOfGeometricType(NORM_POLYGON),2) - self.assertEqual(MEDCouplingMesh.GetReprOfGeometricType(NORM_POLYGON),"NORM_POLYGON") - self.assertEqual(MEDCouplingMesh.GetNumberOfNodesOfGeometricType(NORM_TRI6),6) - self.assertTrue(MEDCouplingMesh.IsStaticGeometricType(NORM_TRI6)) - self.assertTrue(not MEDCouplingMesh.IsLinearGeometricType(NORM_TRI6)) - self.assertEqual(MEDCouplingMesh.GetDimensionOfGeometricType(NORM_TRI6),2) - self.assertEqual(MEDCouplingMesh.GetReprOfGeometricType(NORM_TRI6),"NORM_TRI6") - mesh=MEDCouplingUMesh.New() - mesh.setMeshDimension(2) - mesh.allocateCells(8); - mesh.setName("mesh1") - self.assertTrue(mesh.getName()=="mesh1") - for i in range(nbOfCells): - mesh.insertNextCell(NORM_QUAD4,4,tab4[4*i:4*(i+1)]); - pass - mesh.finishInsertingCells() - self.assertTrue(mesh.getNumberOfCells()==nbOfCells) - self.assertTrue(mesh.getNodalConnectivity().getNbOfElems()==30) - self.assertTrue(mesh.getNodalConnectivityIndex().getNbOfElems()==nbOfCells+1) - myCoords=DataArrayDouble.New() - myCoords.setValues(coords,nbOfNodes,3); - self.assertTrue(myCoords.getIJ(3,2)==-0.305) - mesh.setCoords(myCoords); - mesh.checkCoherency(); - self.assertTrue(mesh.getAllGeoTypes()==[4]) - myFalseConn=DataArrayInt.New() - myFalseConn.setValues(tab4,6,4) - self.assertTrue(myFalseConn.getIJ(1,1)==3) - # - field=MEDCouplingFieldDouble.New(ON_CELLS) - field.setMesh(mesh) - field.setNature(Integral) - myCoords=DataArrayDouble.New() - sampleTab=[] - for i in range(nbOfCells*9): - sampleTab.append(float(i)) - myCoords.setValues(sampleTab,nbOfCells,9); - field.setArray(myCoords) - self.assertTrue(3==mesh.getSpaceDimension()) - field.checkCoherency() - mesh2=mesh.clone(False) - mesh3=mesh.clone(True) - mesh3=0 - mesh2=0 - ## deep full recursively copy of field -> both field and mesh underneath copied - field2=field.clone(True) - field2.setMesh(field.getMesh().clone(True)) - mesh3=mesh.clone(True) - field3=mesh3.fillFromAnalytic(ON_CELLS,2,"x*IVec+(y+z)*JVec") - field3.applyFunc("u*u*u+cos(u)") - pass - - def testMeshPointsCloud(self): - targetCoords=[-0.3,-0.3,0.5, 0.2,-0.3,1., 0.7,-0.3,1.5, - -0.3,0.2,0.5, 0.2,0.2,1., 0.7,0.2,1.5, -0.3,0.7,0.5, 0.2,0.7,1., 0.7,0.7,1.5] - targetMesh=MEDCouplingUMesh.New(); - targetMesh.setMeshDimension(0); - targetMesh.allocateCells(8); - targetMesh.insertNextCell(NORM_POINT1,1,[0]); - targetMesh.insertNextCell(NORM_POINT1,1,[1]); - targetMesh.insertNextCell(NORM_POINT1,1,[2]); - targetMesh.insertNextCell(NORM_POINT1,1,[3]); - targetMesh.insertNextCell(NORM_POINT1,1,[4]); - targetMesh.insertNextCell(NORM_POINT1,1,[5]); - targetMesh.insertNextCell(NORM_POINT1,1,[7]); - targetMesh.insertNextCell(NORM_POINT1,1,[6]); - targetMesh.finishInsertingCells(); - self.assertRaises(InterpKernelException,targetMesh.checkCoherency); - myCoords=DataArrayDouble.New(); - myCoords.setValues(targetCoords,9,3); - targetMesh.setCoords(myCoords); - self.assertEqual(targetMesh.getSpaceDimension(),3) - self.assertEqual(targetMesh.getNumberOfCells(),8) - self.assertEqual(targetMesh.getNumberOfNodes(),9) - self.assertEqual(targetMesh.getMeshDimension(),0) - pass - - def testMeshM1D(self): - meshM1D=MEDCouplingUMesh.New(); - self.assertRaises(InterpKernelException,meshM1D.getMeshDimension); - self.assertRaises(InterpKernelException,meshM1D.getNumberOfNodes); - self.assertRaises(InterpKernelException,meshM1D.getNumberOfCells); - self.assertRaises(InterpKernelException,meshM1D.setMeshDimension,-2) - self.assertRaises(InterpKernelException,meshM1D.setMeshDimension,-10) - meshM1D.setMeshDimension(-1); - meshM1D.checkCoherency(); - self.assertEqual(meshM1D.getMeshDimension(),-1); - self.assertEqual(meshM1D.getNumberOfCells(),1); - self.assertRaises(InterpKernelException,meshM1D.getNumberOfNodes); - self.assertRaises(InterpKernelException,meshM1D.getSpaceDimension); - cpy=meshM1D.clone(True); - self.assertTrue(cpy.isEqual(meshM1D,1e-12)); - fieldOnCells=MEDCouplingFieldDouble.New(ON_CELLS); - fieldOnCells.setMesh(meshM1D); - array=DataArrayDouble.New(); - array.setValues(6*[7.],1,6); - fieldOnCells.setArray(array); - fieldOnCells.checkCoherency(); - pass - - def testDeepCopy(self): - array=DataArrayDouble.New(); - array.setValues(5*3*[7.],5,3); - self.assertEqual(array.getIJ(3,2),7.); - array2=array.deepCpy(); - self.assertEqual(array2.getIJ(3,2),7.) - # - array3=DataArrayInt.New(); - array3.setValues(5*3*[17],5,3); - self.assertEqual(array3.getIJ(3,2),17); - array4=array3.deepCpy(); - self.assertEqual(array4.getIJ(3,2),17); - pass - - def testRevNodal(self): - mesh=MEDCouplingDataForTest.build2DTargetMesh_1() - revNodal,revNodalIndx=mesh.getReverseNodalConnectivity(); - revNodalExpected=[0,0,1,1,2,0,3,0,1,2,3,4,2,4,3,3,4,4]; - revNodalIndexExpected=[0,1,3,5,7,12,14,15,17,18]; - self.assertEqual(revNodal.getNbOfElems(),18) - self.assertEqual(revNodalIndx.getNbOfElems(),10) - self.assertEqual(list(revNodal.getValues()),revNodalExpected) - self.assertEqual(list(revNodalIndx.getValues()),revNodalIndexExpected) - pass - - def testConvertToPolyTypes(self): - mesh=MEDCouplingDataForTest.build2DTargetMesh_1(); - elts=[1,3]; - mesh.convertToPolyTypes(elts); - mesh.checkCoherency(); - self.assertEqual(5,mesh.getNumberOfCells()); - self.assertEqual(23,mesh.getNodalConnectivity().getNumberOfTuples()); - expected1=[4, 0, 3, 4, 1, 5, 1, 4, 2, 3, 4, 5, 2, 5, 6, 7, 4, 3, 4, 7, 8, 5, 4] - self.assertEqual(expected1,list(mesh.getNodalConnectivity().getValues())); - # - mesh=MEDCouplingDataForTest.build3DTargetMesh_1(); - mesh.convertToPolyTypes(elts); - mesh.checkCoherency(); - self.assertEqual(8,mesh.getNumberOfCells()); - self.assertEqual(114,mesh.getNodalConnectivity().getNumberOfTuples()); - mesh.convertToPolyTypes(elts); - mesh.checkCoherency(); - self.assertEqual(8,mesh.getNumberOfCells()); - self.assertEqual(114,mesh.getNodalConnectivity().getNumberOfTuples()); - pass - - def testDescConn2D(self): - mesh=MEDCouplingDataForTest.build2DTargetMesh_1(); - desc=DataArrayInt.New(); - descIndx=DataArrayInt.New(); - revDesc=DataArrayInt.New(); - revDescIndx=DataArrayInt.New(); - mesh2=mesh.buildDescendingConnectivity(desc,descIndx,revDesc,revDescIndx); - mesh2.checkCoherency(); - self.assertEqual(1,mesh2.getMeshDimension()); - self.assertEqual(13,mesh2.getNumberOfCells()); - self.assertEqual(14,revDescIndx.getNbOfElems()); self.assertEqual(14,revDescIndx.getNumberOfTuples()); - self.assertEqual(6,descIndx.getNbOfElems()); self.assertEqual(6,descIndx.getNumberOfTuples()); - self.assertEqual(18,desc.getNbOfElems()); self.assertEqual(18,desc.getNumberOfTuples()); - self.assertEqual(18,revDesc.getNbOfElems()); self.assertEqual(18,revDesc.getNumberOfTuples()); - expected1=[0,1,2,3, 2,4,5, 6,7,4, 8,9,1,10, 11,12,6,9]; - self.assertEqual(expected1,list(desc.getValues())); - expected2=[0,4,7,10,14,18]; - self.assertEqual(expected2,list(descIndx.getValues())); - expected3=[0,1,3,5,6,8,9,11,12,13,15,16,17,18]; - self.assertEqual(expected3,list(revDescIndx.getValues())); - expected4=[0, 0,3, 0,1, 0, 1,2, 1, 2,4, 2, 3, 3,4, 3, 4, 4]; - self.assertEqual(expected4,list(revDesc.getValues())); - conn=mesh2.getNodalConnectivity(); - connIndex=mesh2.getNodalConnectivityIndex(); - expected5=[0,3,6,9,12,15,18,21,24,27,30,33,36,39]; - self.assertEqual(expected5,list(connIndex.getValues())); - expected6=[1, 0, 3, 1, 3, 4, 1, 4, 1, 1, 1, 0, 1, 4, 2, 1, 2, 1, 1, 4, 5, 1, 5, 2, 1, 6, 7, 1, 7, 4, 1, 3, 6, 1, 7, 8, 1, 8, 5]; - self.assertEqual(expected6,list(conn.getValues())); - # - eltsV=[1,3]; - mesh.convertToPolyTypes(eltsV); - mesh.checkCoherency(); - # - desc=DataArrayInt.New(); - descIndx=DataArrayInt.New(); - revDesc=DataArrayInt.New(); - revDescIndx=DataArrayInt.New(); - # - mesh2=mesh.buildDescendingConnectivity(desc,descIndx,revDesc,revDescIndx); - mesh2.checkCoherency(); - self.assertEqual(1,mesh2.getMeshDimension()); - self.assertEqual(13,mesh2.getNumberOfCells()); - self.assertEqual(14,revDescIndx.getNbOfElems()); self.assertEqual(14,revDescIndx.getNumberOfTuples()); - self.assertEqual(6,descIndx.getNbOfElems()); self.assertEqual(6,descIndx.getNumberOfTuples()); - self.assertEqual(18,desc.getNbOfElems()); self.assertEqual(18,desc.getNumberOfTuples()); - self.assertEqual(18,revDesc.getNbOfElems()); self.assertEqual(18,revDesc.getNumberOfTuples()); - self.assertEqual(expected1,list(desc.getValues())); - self.assertEqual(expected2,list(descIndx.getValues())); - self.assertEqual(expected3,list(revDescIndx.getValues())); - self.assertEqual(expected4,list(revDesc.getValues())); - conn=mesh2.getNodalConnectivity(); - connIndex=mesh2.getNodalConnectivityIndex(); - self.assertEqual(expected5,list(connIndex.getValues())); - self.assertEqual(expected6,list(conn.getValues())); - pass - - def testDescConn3D(self): - mesh=MEDCouplingDataForTest.build3DTargetMesh_1(); - desc=DataArrayInt.New(); - descIndx=DataArrayInt.New(); - revDesc=DataArrayInt.New(); - revDescIndx=DataArrayInt.New(); - # - mesh2=mesh.buildDescendingConnectivity(desc,descIndx,revDesc,revDescIndx); - mesh2.checkCoherency(); - self.assertEqual(2,mesh2.getMeshDimension()); - self.assertEqual(36,mesh2.getNumberOfCells()); - self.assertEqual(37,revDescIndx.getNbOfElems()); self.assertEqual(37,revDescIndx.getNumberOfTuples()); - self.assertEqual(9,descIndx.getNbOfElems()); self.assertEqual(9,descIndx.getNumberOfTuples()); - self.assertEqual(48,desc.getNbOfElems()); self.assertEqual(48,desc.getNumberOfTuples()); - self.assertEqual(48,revDesc.getNbOfElems()); self.assertEqual(48,revDesc.getNumberOfTuples()); - expected1=[0, 6, 12, 18, 24, 30, 36, 42, 48] - expected2=[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 3, 11, 12, 4, 13, 14, 15, 16, 17, 10, 18, 19, 13, 1, 20, 21, 22, 23, 24, 7, 25, 26, 27, 28, 22, 12, 29, 23, 30, 31, 32, 17, 33, 28, 34, 35, 30] - expected3=[0, 1, 3, 4, 6, 8, 9, 10, 12, 13, 14, 16, 17, 19, 21, 22, 23, 24, 26, 27, 28, 29, 30, 32, 34, 35, 36, 37, 38, 40, 41, 43, 44, 45, 46, 47, 48] - expected4=[0, 0, 4, 0, 0, 1, 0, 2, 0, 1, 1, 5, 1, 1, 1, 3, 2, 2, 6, 2, 3, 2, 2, 3, 3, 7, 3, 3, 4, 4, 4, 5, 4, 6, 4, 5, 5, 5, 5, 7, 6, 6, 7, 6, 6, 7, 7, 7] - expected5=[0, 5, 10, 15, 20, 25, 30, 35, 40, 45, 50, 55, 60, 65, 70, 75, 80, 85, 90, 95, 100, 105, 110, 115, 120, 125, 130, 135, 140, 145, 150, 155, 160, 165, 170, 175, 180] - expected6=[4, 0, 1, 4, 3, 4, 9, 12, 13, 10, 4, 0, 9, 10, 1, 4, 1, 10, 13, 4, 4, 4, 13, 12, 3, 4, 3, 12, 9, 0, 4, 1, 2, 5, 4, 4, 10, 13, 14, 11, 4, 1, 10, 11, 2, 4, 2, 11, 14, - 5, 4, 5, 14, 13, 4, 4, 3, 4, 7, 6, 4, 12, 15, 16, 13, 4, 4, 13, 16, 7, 4, 7, 16, 15, 6, 4, 6, 15, 12, 3, 4, 4, 5, 8, 7, 4, 13, 16, 17, 14, 4, 5, 14, 17, 8, 4, 8, - 17, 16, 7, 4, 18, 21, 22, 19, 4, 9, 18, 19, 10, 4, 10, 19, 22, 13, 4, 13, 22, 21, 12, 4, 12, 21, 18, 9, 4, 19, 22, 23, 20, 4, 10, 19, 20, 11, 4, 11, 20, 23, 14, 4, - 14, 23, 22, 13, 4, 21, 24, 25, 22, 4, 13, 22, 25, 16, 4, 16, 25, 24, 15, 4, 15, 24, 21, 12, 4, 22, 25, 26, 23, 4, 14, 23, 26, 17, 4, 17, 26, 25, 16] - expected7=[4, 0, 1, 4, 3, 4, 9, 12, 13, 10, 4, 0, 9, 10, 1, 4, 1, 10, 13, 4, 4, 4, 13, 12, 3, 4, 3, 12, 9, 0, 5, 1, 2, 5, 4, 5, 10, 13, 14, 11, 5, 1, 10, 11, 2, 5, 2, 11, 14, - 5, 5, 5, 14, 13, 4, 4, 3, 4, 7, 6, 4, 12, 15, 16, 13, 4, 4, 13, 16, 7, 4, 7, 16, 15, 6, 4, 6, 15, 12, 3, 5, 4, 5, 8, 7, 5, 13, 16, 17, 14, 5, 5, 14, 17, 8, 5, 8, - 17, 16, 7, 4, 18, 21, 22, 19, 4, 9, 18, 19, 10, 4, 10, 19, 22, 13, 4, 13, 22, 21, 12, 4, 12, 21, 18, 9, 4, 19, 22, 23, 20, 4, 10, 19, 20, 11, 4, 11, 20, 23, 14, 4, - 14, 23, 22, 13, 4, 21, 24, 25, 22, 4, 13, 22, 25, 16, 4, 16, 25, 24, 15, 4, 15, 24, 21, 12, 4, 22, 25, 26, 23, 4, 14, 23, 26, 17, 4, 17, 26, 25, 16] - - self.assertEqual(expected1,list(descIndx.getValues())); - self.assertEqual(expected2,list(desc.getValues())); - self.assertEqual(expected3,list(revDescIndx.getValues())); - self.assertEqual(expected4,list(revDesc.getValues())); - self.assertEqual(expected5,list(mesh2.getNodalConnectivityIndex().getValues())); - self.assertEqual(expected6,list(mesh2.getNodalConnectivity().getValues())); - # - eltsV=[1,3] - mesh.convertToPolyTypes(eltsV); - mesh.checkCoherency(); - desc=DataArrayInt.New(); - descIndx=DataArrayInt.New(); - revDesc=DataArrayInt.New(); - revDescIndx=DataArrayInt.New(); - mesh2=mesh.buildDescendingConnectivity(desc,descIndx,revDesc,revDescIndx); - mesh2.checkCoherency(); - self.assertEqual(2,mesh2.getMeshDimension()); - self.assertEqual(36,mesh2.getNumberOfCells()); - self.assertEqual(37,revDescIndx.getNbOfElems()); self.assertEqual(37,revDescIndx.getNumberOfTuples()); - self.assertEqual(9,descIndx.getNbOfElems()); self.assertEqual(9,descIndx.getNumberOfTuples()); - self.assertEqual(48,desc.getNbOfElems()); self.assertEqual(48,desc.getNumberOfTuples()); - self.assertEqual(48,revDesc.getNbOfElems()); self.assertEqual(48,revDesc.getNumberOfTuples()); - self.assertEqual(expected1,list(descIndx.getValues())); - self.assertEqual(expected2,list(desc.getValues())); - self.assertEqual(expected3,list(revDescIndx.getValues())); - self.assertEqual(expected4,list(revDesc.getValues())); - self.assertEqual(expected5,list(mesh2.getNodalConnectivityIndex().getValues())); - self.assertEqual(expected7,list(mesh2.getNodalConnectivity().getValues())); - pass - - def testFindBoundaryNodes(self): - mesh=MEDCouplingDataForTest.build3DTargetMesh_1(); - boundaryNodes=mesh.findBoundaryNodes(); - expected1=[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26]; - self.assertEqual(expected1,boundaryNodes.getValues()); - pass - - def testBoundaryMesh(self): - mesh=MEDCouplingDataForTest.build3DTargetMesh_1(); - mesh2=mesh.buildBoundaryMesh(False); - self.assertEqual(24,mesh2.getNumberOfCells()); - self.assertEqual(26,mesh2.getNumberOfNodes()); - pass - - def testBuildPartOfMySelf(self): - mesh=MEDCouplingDataForTest.build2DTargetMesh_1(); - mesh.setName("Toto"); - tab1=[0,4] - tab2=[0,2,3] - # - subMesh=mesh.buildPart(tab1) - self.assertTrue(isinstance(subMesh,MEDCouplingUMesh)) - subMesh=mesh.buildPartOfMySelf(tab1,True); - self.assertTrue(isinstance(subMesh,MEDCouplingUMesh)) - name=subMesh.getName(); - self.assertEqual(2,len(mesh.getAllGeoTypes())); - self.assertEqual(NORM_TRI3,mesh.getAllGeoTypes()[0]); - self.assertEqual(NORM_QUAD4,mesh.getAllGeoTypes()[1]); - self.assertEqual(1,len(subMesh.getAllGeoTypes())); - self.assertEqual(NORM_QUAD4,subMesh.getAllGeoTypes()[0]); - self.assertEqual(name,"Toto"); - self.assertEqual(2,subMesh.getNumberOfCells()); - subConn=[4,0,3,4,1,4,7,8,5,4]; - subConnIndex=[0,5,10]; - self.assertEqual(10,subMesh.getNodalConnectivity().getNbOfElems()); - self.assertEqual(3,subMesh.getNodalConnectivityIndex().getNbOfElems()); - self.assertEqual(subConn[0:10],list(subMesh.getNodalConnectivity().getValues())); - self.assertEqual(subConnIndex[0:3],list(subMesh.getNodalConnectivityIndex().getValues())); - # - subMesh=mesh.buildPartOfMySelf(tab2[0:3],True); - self.assertTrue(isinstance(subMesh,MEDCouplingUMesh)); - name=subMesh.getName(); - self.assertEqual(2,len(subMesh.getAllGeoTypes())); - self.assertEqual(NORM_TRI3,subMesh.getAllGeoTypes()[0]); - self.assertEqual(NORM_QUAD4,subMesh.getAllGeoTypes()[1]); - self.assertEqual(name,"Toto"); - self.assertEqual(3,subMesh.getNumberOfCells()); - subConn2=[4,0,3,4,1,3,4,5,2,4,6,7,4,3] - subConnIndex2=[0,5,9,14] - self.assertEqual(14,subMesh.getNodalConnectivity().getNbOfElems()); - self.assertEqual(4,subMesh.getNodalConnectivityIndex().getNbOfElems()); - self.assertEqual(subConn2[0:14],list(subMesh.getNodalConnectivity().getValues())); - self.assertEqual(subConnIndex2[0:4],list(subMesh.getNodalConnectivityIndex().getValues())); - dd=DataArrayInt.New() - dd.alloc(3,1) - dd.iota(0) - dd.setName("coucou") - subMesh=subMesh.buildPartOfMySelf(dd,True); - self.assertEqual("coucou",subMesh.getName()); - pass - - def testBuildPartOfMySelfNode(self): - mesh=MEDCouplingDataForTest.build2DTargetMesh_1(); - tab1=[5,7,8,4] - subMesh=mesh.buildPartOfMySelfNode(tab1[0:4],True); - self.assertTrue(isinstance(subMesh,MEDCouplingUMesh)) - self.assertEqual(1,len(subMesh.getAllGeoTypes())); - self.assertEqual(NORM_QUAD4,subMesh.getAllGeoTypes()[0]); - self.assertEqual(1,subMesh.getNumberOfCells()); - self.assertEqual(5,subMesh.getNodalConnectivity().getNbOfElems()); - self.assertEqual(2,subMesh.getNodalConnectivityIndex().getNbOfElems()); - subConn=[4,7,8,5,4] - subConnIndex=[0,5] - self.assertEqual(subConn[0:5],list(subMesh.getNodalConnectivity().getValues())); - self.assertEqual(subConnIndex[0:2],list(subMesh.getNodalConnectivityIndex().getValues())); - # - ddd=DataArrayInt.New() - ddd.setValues(tab1[0:2],2,1) - ddd.setName("ddd") - subMesh=mesh.buildPartOfMySelfNode(ddd,False); - self.assertEqual("ddd",subMesh.getName()) - self.assertTrue(isinstance(subMesh,MEDCouplingUMesh)) - self.assertEqual(2,len(subMesh.getAllGeoTypes())); - self.assertEqual(NORM_TRI3,subMesh.getAllGeoTypes()[0]); - self.assertEqual(NORM_QUAD4,subMesh.getAllGeoTypes()[1]); - self.assertEqual(3,subMesh.getNumberOfCells()); - self.assertEqual(14,subMesh.getNodalConnectivity().getNbOfElems()); - self.assertEqual(4,subMesh.getNodalConnectivityIndex().getNbOfElems()); - subConn2=[3,4,5,2,4,6,7,4,3,4,7,8,5,4] - subConnIndex2=[0,4,9,14] - self.assertEqual(subConn2[0:14],list(subMesh.getNodalConnectivity().getValues())); - self.assertEqual(subConnIndex2[0:4],list(subMesh.getNodalConnectivityIndex().getValues())); - #testing the case where length of tab2 is greater than max number of node per cell. - tab2=[0,3,2,1,4,5,6] - subMesh=mesh.buildPartOfMySelfNode(tab2[0:7],True); - self.assertTrue(isinstance(subMesh,MEDCouplingUMesh)) - self.assertEqual(2,len(subMesh.getAllGeoTypes())); - self.assertEqual(NORM_TRI3,subMesh.getAllGeoTypes()[0]); - self.assertEqual(NORM_QUAD4,subMesh.getAllGeoTypes()[1]); - self.assertEqual(3,subMesh.getNumberOfCells()); - pass - - def testZipCoords(self): - mesh=MEDCouplingDataForTest.build2DTargetMesh_1(); - self.assertEqual(2,len(mesh.getAllGeoTypes())); - self.assertEqual(2,mesh.getSpaceDimension()); - self.assertEqual(9,mesh.getNumberOfNodes()); - self.assertEqual(5,mesh.getNumberOfCells()); - oldConn=mesh.getNodalConnectivity().getValues()[0:mesh.getNodalConnectivity().getNbOfElems()]; - oldConnIndex=mesh.getNodalConnectivityIndex().getValues()[0:mesh.getNumberOfCells()+1] - oldCoords=mesh.getCoords(); - mesh.zipCoords(); - self.assertEqual(2,len(mesh.getAllGeoTypes())); - self.assertEqual(2,mesh.getSpaceDimension()); - self.assertEqual(9,mesh.getNumberOfNodes()); - self.assertEqual(5,mesh.getNumberOfCells()); - self.assertEqual(mesh.getCoords().getValues()[0:2*9],oldCoords.getValues()); - self.assertEqual(list(oldConn),list(mesh.getNodalConnectivity().getValues())); - self.assertEqual(list(oldConnIndex),list(mesh.getNodalConnectivityIndex().getValues())); - # - tab1=[0,4] - subMesh=mesh.buildPartOfMySelf(tab1,True); - self.assertTrue(isinstance(subMesh,MEDCouplingUMesh)) - traducer=subMesh.zipCoordsTraducer(); - expectedTraducer=[0, 1, -1, 2, 3, 4, -1, 5, 6] - self.assertEqual(expectedTraducer,list(traducer.getValues())); - self.assertEqual(NORM_QUAD4,subMesh.getAllGeoTypes()[0]); - self.assertEqual(2,subMesh.getNumberOfCells()); - subConn=[4,0,2,3,1,4,5,6,4,3] - subConnIndex=[0,5,10] - self.assertEqual(7,subMesh.getNumberOfNodes()); - self.assertEqual(10,subMesh.getNodalConnectivity().getNbOfElems()); - self.assertEqual(3,subMesh.getNodalConnectivityIndex().getNbOfElems()); - self.assertEqual(subConn,list(subMesh.getNodalConnectivity().getValues())); - self.assertEqual(subConnIndex,list(subMesh.getNodalConnectivityIndex().getValues())); - # - subMesh=mesh.buildPartOfMySelf(tab1,False); - self.assertTrue(isinstance(subMesh,MEDCouplingUMesh)) - self.assertEqual(NORM_QUAD4,subMesh.getAllGeoTypes()[0]); - self.assertEqual(2,subMesh.getNumberOfCells()); - self.assertEqual(7,subMesh.getNumberOfNodes()); - self.assertEqual(10,subMesh.getNodalConnectivity().getNbOfElems()); - self.assertEqual(3,subMesh.getNodalConnectivityIndex().getNbOfElems()); - self.assertEqual(subConn,list(subMesh.getNodalConnectivity().getValues())); - self.assertEqual(subConnIndex,list(subMesh.getNodalConnectivityIndex().getValues())); - pass - - def testZipConnectivity(self): - m1=MEDCouplingDataForTest.build2DTargetMesh_1(); - m2=MEDCouplingDataForTest.build2DTargetMesh_1(); - cells1=[2,3,4] - m3=m2.buildPartOfMySelf(cells1,True); - self.assertTrue(isinstance(m3,MEDCouplingUMesh)) - m4=MEDCouplingDataForTest.build2DSourceMesh_1(); - m5=MEDCouplingUMesh.MergeUMeshes(m1,m3); - m6=MEDCouplingUMesh.MergeUMeshes(m5,m4); - # - self.assertEqual(10,m6.getNumberOfCells()); - self.assertEqual(22,m6.getNumberOfNodes()); - (arr,areNodesMerged,newNbOfNodes)=m6.mergeNodes(1e-13); - self.assertTrue(areNodesMerged); - self.assertEqual(10,m6.getNumberOfCells()); - self.assertEqual(9,m6.getNumberOfNodes()); - # - arr=m6.zipConnectivityTraducer(0); - self.assertEqual(7,m6.getNumberOfCells()); - m7=m6.clone(True); - arr=m6.zipConnectivityTraducer(0); - self.assertTrue(m7.isEqual(m6,1e-12)); - self.assertEqual(7,m6.getNumberOfCells()); - pass - - def testEqualMesh(self): - mesh1=MEDCouplingDataForTest.build2DTargetMesh_1(); - mesh2=MEDCouplingDataForTest.build2DTargetMesh_1(); - # - self.assertTrue(mesh1.isEqual(mesh1,1e-12)); - # - self.assertTrue(mesh1.isEqual(mesh2,1e-12)); - self.assertTrue(mesh2.isEqual(mesh1,1e-12)); - pt=mesh2.getCoords().getValues(); - tmp=pt[1] - mesh2.getCoords().setIJ(0,1,5.999); - self.assertTrue(not mesh1.isEqual(mesh2,1e-12)); - self.assertTrue(not mesh2.isEqual(mesh1,1e-12)); - mesh2.getCoords().setIJ(0,1,tmp); - self.assertTrue(mesh1.isEqual(mesh2,1e-12)); - self.assertTrue(mesh2.isEqual(mesh1,1e-12)); - # - pt2=mesh1.getNodalConnectivity().getValues(); - mesh1.getNodalConnectivity().setIJ(5,0,int(pt2[5])+1); - self.assertTrue(not mesh1.isEqual(mesh2,1e-12)); - self.assertTrue(not mesh2.isEqual(mesh1,1e-12)); - mesh1.getNodalConnectivity().setIJ(5,0,int(pt2[5])); - self.assertTrue(mesh1.isEqual(mesh2,1e-12)); - self.assertTrue(mesh2.isEqual(mesh1,1e-12)); - # - pt2=mesh1.getNodalConnectivityIndex().getValues(); - mesh1.getNodalConnectivityIndex().setIJ(1,0,int(pt2[1]+1)); - self.assertTrue(not mesh1.isEqual(mesh2,1e-12)); - self.assertTrue(not mesh2.isEqual(mesh1,1e-12)); - mesh1.getNodalConnectivityIndex().setIJ(1,0,int(pt2[1])); - self.assertTrue(mesh1.isEqual(mesh2,1e-12)); - self.assertTrue(mesh2.isEqual(mesh1,1e-12)); - # - tmp3=mesh1.getName(); - mesh1.setName("lllll"); - self.assertTrue(not mesh1.isEqual(mesh2,1e-12)); - self.assertTrue(not mesh2.isEqual(mesh1,1e-12)); - mesh1.setName(tmp3); - self.assertTrue(mesh1.isEqual(mesh2,1e-12)); - self.assertTrue(mesh2.isEqual(mesh1,1e-12)); - # - tmp3=mesh2.getCoords().getInfoOnComponent(1); - mesh2.getCoords().setInfoOnComponent(1,"kkkkkk"); - self.assertTrue(not mesh1.isEqual(mesh2,1e-12)); - self.assertTrue(not mesh2.isEqual(mesh1,1e-12)); - mesh2.getCoords().setInfoOnComponent(1,tmp3); - self.assertTrue(mesh1.isEqual(mesh2,1e-12)); - self.assertTrue(mesh2.isEqual(mesh1,1e-12)); - pass - - def testEqualFieldDouble(self): - mesh1=MEDCouplingDataForTest.build2DTargetMesh_1(); - mesh2=MEDCouplingDataForTest.build2DTargetMesh_1(); - # - fieldOnCells1=MEDCouplingFieldDouble.New(ON_CELLS,NO_TIME); - fieldOnCells1.setMesh(mesh1); - fieldOnCells2=MEDCouplingFieldDouble.New(ON_CELLS,NO_TIME); - fieldOnCells2.setMesh(mesh2); - # - self.assertTrue(fieldOnCells1.isEqual(fieldOnCells2,1e-12,1e-15)); - self.assertTrue(fieldOnCells2.isEqual(fieldOnCells1,1e-12,1e-15)); - # - fieldOnNodes1=MEDCouplingFieldDouble.New(ON_CELLS,NO_TIME); - self.assertTrue(not fieldOnCells1.isEqual(fieldOnNodes1,1e-12,1e-15)); - self.assertTrue(not fieldOnNodes1.isEqual(fieldOnCells1,1e-12,1e-15)); - # - fieldOnCells2=MEDCouplingFieldDouble.New(ON_CELLS,ONE_TIME); - self.assertEqual(fieldOnCells2.getMesh(),None) # to check that convertMesh wrapping do not raise but return Py_None - self.assertTrue(not fieldOnCells1.isEqual(fieldOnCells2,1e-12,1e-15)); - self.assertTrue(not fieldOnCells2.isEqual(fieldOnCells1,1e-12,1e-15)); - fieldOnCells1=MEDCouplingFieldDouble.New(ON_CELLS,ONE_TIME); - self.assertTrue(fieldOnCells1.isEqual(fieldOnCells2,1e-12,1e-15)); - self.assertTrue(fieldOnCells2.isEqual(fieldOnCells1,1e-12,1e-15)); - fieldOnCells1.setTime(4.,6,7); - self.assertTrue(not fieldOnCells1.isEqual(fieldOnCells2,1e-12,1e-15)); - self.assertTrue(not fieldOnCells2.isEqual(fieldOnCells1,1e-12,1e-15)); - fieldOnCells2.setTime(4.,6,7); - self.assertTrue(fieldOnCells1.isEqual(fieldOnCells2,1e-12,1e-15)); - self.assertTrue(fieldOnCells2.isEqual(fieldOnCells1,1e-12,1e-15)); - fieldOnCells1.setName("Power"); - self.assertTrue(not fieldOnCells1.isEqual(fieldOnCells2,1e-12,1e-15)); - self.assertTrue(not fieldOnCells2.isEqual(fieldOnCells1,1e-12,1e-15)); - fieldOnCells2.setName("Power"); - self.assertTrue(fieldOnCells1.isEqual(fieldOnCells2,1e-12,1e-15)); - self.assertTrue(fieldOnCells2.isEqual(fieldOnCells1,1e-12,1e-15)); - # - fieldOnCells1.setMesh(mesh1); - self.assertTrue(not fieldOnCells1.isEqual(fieldOnCells2,1e-12,1e-15)); - self.assertTrue(not fieldOnCells2.isEqual(fieldOnCells1,1e-12,1e-15)); - fieldOnCells2.setMesh(mesh1); - self.assertTrue(fieldOnCells1.isEqual(fieldOnCells2,1e-12,1e-15)); - self.assertTrue(fieldOnCells2.isEqual(fieldOnCells1,1e-12,1e-15)); - arr=DataArrayDouble.New(); - arr.setName("popo"); - arr.setValues(mesh1.getNumberOfCells()*3*[6.],mesh1.getNumberOfCells(),3); - fieldOnCells1.setArray(arr); - self.assertTrue(not fieldOnCells1.isEqual(fieldOnCells2,1e-12,1e-15)); - self.assertTrue(not fieldOnCells2.isEqual(fieldOnCells1,1e-12,1e-15)); - fieldOnCells2.setArray(arr); - self.assertTrue(fieldOnCells1.isEqual(fieldOnCells2,1e-12,1e-15)); - self.assertTrue(fieldOnCells2.isEqual(fieldOnCells1,1e-12,1e-15)); - # - arr2=arr.deepCpy(); - fieldOnCells2.setArray(arr2); - self.assertTrue(fieldOnCells1.isEqual(fieldOnCells2,1e-12,1e-15)); - self.assertTrue(fieldOnCells2.isEqual(fieldOnCells1,1e-12,1e-15)); - arr.setIJ(1,2,6.1); - self.assertTrue(not fieldOnCells1.isEqual(fieldOnCells2,1e-12,1e-15)); - self.assertTrue(not fieldOnCells2.isEqual(fieldOnCells1,1e-12,1e-15)); - arr.setIJ(1,2,6.); - self.assertTrue(fieldOnCells1.isEqual(fieldOnCells2,1e-12,1e-15)); - self.assertTrue(fieldOnCells2.isEqual(fieldOnCells1,1e-12,1e-15)); - arr2.setName("popo2"); - self.assertTrue(not fieldOnCells1.isEqual(fieldOnCells2,1e-12,1e-15)); - self.assertTrue(not fieldOnCells2.isEqual(fieldOnCells1,1e-12,1e-15)); - # - arr2.setName("popo"); - self.assertTrue(fieldOnCells1.isEqual(fieldOnCells2,1e-12,1e-15)); - self.assertTrue(fieldOnCells2.isEqual(fieldOnCells1,1e-12,1e-15)); - # - arr2.setInfoOnComponent(2,"jjj"); - self.assertTrue(not fieldOnCells1.isEqual(fieldOnCells2,1e-12,1e-15)); - self.assertTrue(not fieldOnCells2.isEqual(fieldOnCells1,1e-12,1e-15)); - arr.setInfoOnComponent(2,"jjj"); - self.assertTrue(fieldOnCells1.isEqual(fieldOnCells2,1e-12,1e-15)); - self.assertTrue(fieldOnCells2.isEqual(fieldOnCells1,1e-12,1e-15)); - pass - - def testNatureChecking(self): - field=MEDCouplingFieldDouble.New(ON_CELLS,NO_TIME); - field.setNature(Integral); - field.setNature(ConservativeVolumic); - field.setNature(IntegralGlobConstraint); - field=MEDCouplingFieldDouble.New(ON_NODES,NO_TIME); - field.setNature(ConservativeVolumic); - self.assertRaises(InterpKernelException,field.setNature,Integral); - self.assertRaises(InterpKernelException,field.setNature,IntegralGlobConstraint); - pass - - def testNatureOperations(self): - """ Check nature constraints on field operations """ - m = MEDCouplingCMesh() - m.setCoordsAt(0, DataArrayDouble([1.0,2.0,3.0])) - m.setCoordsAt(1, DataArrayDouble([1.0,2.0,3.0])) - m = m.buildUnstructured() - f1, f2 = MEDCouplingFieldDouble.New(ON_CELLS, NO_TIME), MEDCouplingFieldDouble.New(ON_CELLS, NO_TIME) - f1.setNature(Integral) - f2.setNature(ConservativeVolumic) - self.assertEqual(Integral, f1.getNature()) - self.assertEqual(ConservativeVolumic, f2.getNature()) - - da = DataArrayDouble([1.0,2.0,3.0,4.0]) - f1.setMesh(m); f2.setMesh(m) - f1.setArray(da); f2.setArray(da.deepCpy()) - # All this should complain about nature: - self.assertRaises(InterpKernelException, f1.__add__, f2) - self.assertRaises(InterpKernelException, f1.__iadd__, f2) - self.assertRaises(InterpKernelException, f1.__sub__, f2) - self.assertRaises(InterpKernelException, f1.__isub__, f2) - self.assertRaises(InterpKernelException, f1.__radd__, f2) - self.assertRaises(InterpKernelException, f1.__rsub__, f2) - self.assertRaises(InterpKernelException, MEDCouplingFieldDouble.AddFields, f1, f2) - self.assertRaises(InterpKernelException, MEDCouplingFieldDouble.SubstractFields, f1, f2) - self.assertRaises(InterpKernelException, MEDCouplingFieldDouble.MaxFields, f1, f2) - self.assertRaises(InterpKernelException, MEDCouplingFieldDouble.MinFields, f1, f2) - # Not those ones: - f3 = MEDCouplingFieldDouble.MultiplyFields(f1,f2) - self.assertEqual(NoNature, f3.getNature()) - f3 = f1*f2 - self.assertEqual(NoNature, f3.getNature()) - f1Tmp = f1.deepCpy(); f1Tmp.setMesh(m); f1Tmp *= f2 - self.assertEqual(NoNature, f1Tmp.getNature()) - f3 = MEDCouplingFieldDouble.DivideFields(f1,f2) - self.assertEqual(NoNature, f3.getNature()) - f3 = f1/f2 - self.assertEqual(NoNature, f3.getNature()) - f1Tmp = f1.deepCpy(); f1Tmp.setMesh(m); f1Tmp /= f2 - self.assertEqual(NoNature, f1Tmp.getNature()) -# f3 = MEDCouplingFieldDouble.PowFields(f1,f2) -# self.assertEqual(NoNature, f3.getNature()) - f3 = f1**f2 - self.assertEqual(NoNature, f3.getNature()) - f1Tmp = f1.deepCpy(); f1Tmp.setMesh(m); f1Tmp **= f2 - self.assertEqual(NoNature, f1Tmp.getNature()) - f3 = MEDCouplingFieldDouble.DotFields(f1,f2) - self.assertEqual(NoNature, f3.getNature()) - f3 = f1.dot(f2) - self.assertEqual(NoNature, f3.getNature()) - - da = DataArrayDouble.Meld([da, da, da]) - f1.setArray(da); f2.setArray(da.deepCpy()) - f3 = MEDCouplingFieldDouble.CrossProductFields(f1,f2) - self.assertEqual(NoNature, f3.getNature()) - f3 = f1.crossProduct(f2) - - def testBuildSubMeshData(self): - targetMesh=MEDCouplingDataForTest.build2DTargetMesh_1() - #check buildSubMesh on field on cells - fieldCells=MEDCouplingFieldDouble.New(ON_CELLS,NO_TIME); - fieldCells.setMesh(targetMesh); - elts=[1,2,4] - ret1,di=fieldCells.buildSubMeshData(elts); - self.assertTrue(isinstance(ret1,MEDCouplingUMesh)) - self.assertEqual(3,ret1.getNumberOfCells()); - self.assertEqual(9,ret1.getNumberOfNodes()); - self.assertEqual(3,di.getNumberOfTuples()); - self.assertEqual(1,di.getNumberOfComponents()); - toCheck=di.getValues(); - self.assertTrue(elts,toCheck); - #check buildSubMesh on field on nodes - fieldNodes=MEDCouplingFieldDouble.New(ON_NODES,NO_TIME); - fieldNodes.setMesh(targetMesh); - ret2,di=fieldNodes.buildSubMeshData(elts); - self.assertTrue(isinstance(ret2,MEDCouplingUMesh)) - self.assertEqual(3,ret2.getNumberOfCells()); - self.assertEqual(6,ret2.getNumberOfNodes()); - self.assertEqual(6,di.getNumberOfTuples()); - self.assertEqual(1,di.getNumberOfComponents()); - toCheck=di.getValues(); - expected=[1,2,4,5,7,8] - self.assertEqual(expected,list(toCheck)); - pass - - def testExtrudedMesh1(self): - mesh3D,mesh2D=MEDCouplingDataForTest.build3DExtrudedUMesh_1(); - ext=MEDCouplingExtrudedMesh.New(mesh3D,mesh2D,1); - self.assertEqual(18,ext.getNumberOfCells()); - self.assertEqual(60,ext.getNumberOfNodes()); - ids3D=ext.getMesh3DIds(); - ids3DExpected=[5,4,3,2,1,0, 11,10,9,8,7,6, 17,16,15,14,13,12] - self.assertEqual(18,ids3D.getNumberOfTuples()); - self.assertEqual(1,ids3D.getNumberOfComponents()); - self.assertEqual(ids3DExpected,list(ids3D.getValues())); - mesh1D=ext.getMesh1D(); - self.assertEqual(4,mesh1D.getNumberOfNodes()); - self.assertEqual(3,mesh1D.getNumberOfCells()); - mesh1DExpected=[0.66666666666666663, 1.4583333333333333, 0, 0.66666666666666663, - 1.4583333333333333, 1, 0.66666666666666663, 1.4583333333333333, - 2, 0.66666666666666663, 1.4583333333333333, 3] - mesh1DCoords=mesh1D.getCoords(); - self.assertEqual(4,mesh1DCoords.getNumberOfTuples()); - self.assertEqual(3,mesh1DCoords.getNumberOfComponents()); - self.assertEqual(mesh1DExpected,mesh1DCoords.getValues()); - conn1D=mesh1D.getNodalConnectivity(); - self.assertEqual(9,conn1D.getNumberOfTuples()); - self.assertEqual(1,conn1D.getNumberOfComponents()); - conn1DExpected=[1,0,1,1,1,2,1,2,3] - self.assertEqual(conn1DExpected,list(conn1D.getValues())); - pass - - def testExtrudedMesh3(self): - m1=MEDCouplingDataForTest.build2DTargetMesh_1(); - m1.changeSpaceDimension(3); - m2=MEDCouplingDataForTest.buildCU1DMesh_U(); - m2.changeSpaceDimension(3); - center=[0.,0.,0.] - vector=[0.,1.,0.] - m2.rotate(center,vector,-pi/2.); - m3=m1.buildExtrudedMesh(m2,0); - # - m4=MEDCouplingExtrudedMesh.New(m3,m1,0); - self.assertEqual(15,m4.getNumberOfCells()); - self.assertEqual(5,m4.getMesh2D().getNumberOfCells()); - self.assertEqual(3,m4.getMesh1D().getNumberOfCells()); - m3DIds=m4.getMesh3DIds().getValues(); - self.assertEqual(range(15),list(m3DIds)); - #some random in cells to check that extrusion alg find it correctly - expected1=[1,3,2,0,6,5,7,10,11,8,12,9,14,13,4] - m3.renumberCells(expected1,False); - m4=MEDCouplingExtrudedMesh.New(m3,m1,0); - self.assertEqual(15,m4.getNumberOfCells()); - self.assertEqual(5,m4.getMesh2D().getNumberOfCells()); - self.assertEqual(3,m4.getMesh1D().getNumberOfCells()); - m3DIds=m4.getMesh3DIds().getValues(); - self.assertEqual(expected1,list(m3DIds)); - #play with polygons and polyedrons - cells=[2,3] - m1.convertToPolyTypes(cells); - m3=m1.buildExtrudedMesh(m2,0); - self.assertEqual(NORM_HEXA8,m3.getTypeOfCell(0)); - self.assertEqual(NORM_PENTA6,m3.getTypeOfCell(1)); - self.assertEqual(NORM_POLYHED,m3.getTypeOfCell(2)); - self.assertEqual(NORM_POLYHED,m3.getTypeOfCell(3)); - self.assertEqual(NORM_HEXA8,m3.getTypeOfCell(4)); - m3.renumberCells(expected1,False); - m4=MEDCouplingExtrudedMesh.New(m3,m1,0); - self.assertEqual(15,m4.getNumberOfCells()); - self.assertEqual(5,m4.getMesh2D().getNumberOfCells()); - self.assertEqual(3,m4.getMesh1D().getNumberOfCells()); - m3DIds=m4.getMesh3DIds().getValues(); - self.assertEqual(expected1,list(m3DIds)); - pass - - def testExtrudedMesh4(self): - m1=MEDCouplingDataForTest.build2DTargetMesh_1(); - cells=[2,4]; - m1.convertToPolyTypes(cells); - m1.changeSpaceDimension(3); - m2=MEDCouplingDataForTest.buildCU1DMesh_U(); - m2.changeSpaceDimension(3); - center=[0.,0.,0.] - vector=[0.,1.,0.] - m2.rotate(center,vector,-pi/2.); - m1.zipCoords() - m3=m1.buildExtrudedMesh(m2,0); - expected1=[1,3,2,0,6,5,7,10,11,8,12,9,14,13,4] - rexpected1=[3, 0, 2, 1, 14, 5, 4, 6, 9, 11, 7, 8, 10, 13, 12] - m3.renumberCells(expected1,False); - m4=MEDCouplingExtrudedMesh.New(m3,m1,0); - self.assertEqual(NORM_HEXA8,m4.getTypeOfCell(0)); - self.assertEqual(NORM_HEXA8,m4.getTypeOfCell(1)); - self.assertEqual(NORM_POLYHED,m4.getTypeOfCell(2)); - self.assertEqual(NORM_PENTA6,m4.getTypeOfCell(7)); - f=m4.getMeasureField(True); - arr=f.getArray(); - self.assertEqual(15,arr.getNumberOfTuples()); - self.assertEqual(1,arr.getNumberOfComponents()); - arrPtr=arr.getValues(); - expected2=[0.075,0.0375,0.0375,0.075,0.075, - 0.1125,0.05625,0.05625,0.1125,0.1125, - 0.0625,0.03125,0.03125,0.0625,0.0625] - for i in xrange(15): - self.assertAlmostEqual(expected2[rexpected1[i]],arrPtr[i],16); - pass - m5=m4.build3DUnstructuredMesh(); - m5.zipCoords() - self.assertTrue(m5.isEqual(m3,1e-12)); - f=m5.getMeasureField(True); - f.setMesh(m4) - self.assertTrue(isinstance(f.getMesh(),MEDCouplingExtrudedMesh)) - arr=f.getArray(); - arrPtr=arr.getValues(); - for i in xrange(15): - self.assertAlmostEqual(expected2[rexpected1[i]],arrPtr[i],15); - pass - pass - - def testFindCommonNodes(self): - targetMesh=MEDCouplingDataForTest.build3DTargetMesh_1(); - comm,commI=targetMesh.findCommonNodes(1e-10,-1); - self.assertEqual(1,commI.getNumberOfTuples()); - self.assertEqual(0,comm.getNumberOfTuples()); - o2n,newNbOfNodes=targetMesh.buildNewNumberingFromCommonNodesFormat(comm,commI); - self.assertEqual(27,newNbOfNodes); - self.assertEqual(27,o2n.getNumberOfTuples()); - o2nExp1=range(27) - self.assertEqual(o2nExp1,list(o2n.getValues())); - # - targetMesh=MEDCouplingDataForTest.build3DTargetMeshMergeNode_1(); - self.assertEqual(31,targetMesh.getNumberOfNodes()); - comm,commI=targetMesh.findCommonNodes(1e-10);# testing default parameter - self.assertEqual(3,commI.getNumberOfTuples()); - self.assertEqual(6,comm.getNumberOfTuples()); - commExpected=[1,27,28,29,23,30] - commIExpected=[0,4,6] - self.assertEqual(commExpected,list(comm.getValues())); - self.assertEqual(commIExpected,list(commI.getValues())); - o2n,newNbOfNodes=targetMesh.buildNewNumberingFromCommonNodesFormat(comm,commI); - self.assertEqual(31,o2n.getNumberOfTuples()); - self.assertEqual(27,newNbOfNodes); - o2nExp2=[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20, - 21,22,23,24,25,26,1,1,1,23] - self.assertEqual(o2nExp2,list(o2n.getValues())); - # - targetMesh=MEDCouplingDataForTest.build3DTargetMesh_1(); - time=targetMesh.getTimeOfThis(); - o2n,areNodesMerged,newNbOfNodes=targetMesh.mergeNodes(1e-10); - targetMesh.updateTime(); - self.assertEqual(time,targetMesh.getTimeOfThis()); - self.assertTrue(not areNodesMerged); - # - targetMesh=MEDCouplingDataForTest.build3DTargetMeshMergeNode_1(); - time=targetMesh.getTimeOfThis(); - o2n,areNodesMerged,newNbOfNodes=targetMesh.mergeNodes(1e-10); - targetMesh.updateTime(); - self.assertTrue(time!=targetMesh.getTimeOfThis()); - self.assertTrue(areNodesMerged); - connExp=[18,0,1,4,3,9,10,13,12, 18,1,2,5,4,10,11,14,13, 18,3,4,7,6,12,13,16,15, - 18,4,5,8,7,13,14,17,16, - 18,9,10,13,12,18,19,22,21, 18,10,11,14,13,19,20,23,22, 18,12,13,16,15,21,22,25,24, - 18,13,14,17,16,22,23,26,25] - self.assertEqual(72,targetMesh.getNodalConnectivity().getNumberOfTuples()); - self.assertEqual(connExp,list(targetMesh.getNodalConnectivity().getValues())); - self.assertEqual(27,targetMesh.getCoords().getNumberOfTuples()); - coordsExp=[ 0., 0., 0., 50., 0., 0. , 200., 0., 0. , 0., 50., 0., 50., 50., 0. , - 200., 50., 0., 0., 200., 0., 50., 200., 0. , 200., 200., 0. , - 0., 0., 50., 50., 0., 50. , 200., 0., 50. , 0., 50., 50., 50., - 50., 50. , 200., 50., 50., 0., 200., 50., 50., 200., 50. , - 200., 200., 50. , 0., 0., 200., 50., 0., 200. , 200., 0., 200. - , 0., 50., 200., 50., 50., 200. , 200., 50., 200., - 0., 200., 200., 50., 200., 200. , 200., 200., 200. ] - self.assertEqual(coordsExp,targetMesh.getCoords().getValues()); - # 2D - targetMesh=MEDCouplingDataForTest.build2DTargetMeshMergeNode_1(); - self.assertEqual(18,targetMesh.getNumberOfNodes()); - time=targetMesh.getTimeOfThis(); - o2n,areNodesMerged,newNbOfNodes=targetMesh.mergeNodes(1e-10); - self.assertTrue(time!=targetMesh.getTimeOfThis()); - self.assertTrue(areNodesMerged); - self.assertEqual(9,targetMesh.getNumberOfNodes()); - connExp2=[4,0,4,3,1, 3,1,3,2, 3,3,5,2, 4,4,6,7,3, 4,7,8,5,3] - self.assertEqual(23,targetMesh.getNodalConnectivity().getNumberOfTuples()); - self.assertEqual(connExp2,list(targetMesh.getNodalConnectivity().getValues())); - coordsExp2=[-0.3,-0.3, 0.2,-0.3, 0.7,-0.3, 0.2,0.2, -0.3,0.2, 0.7,0.2, -0.3,0.7, 0.2,0.7, 0.7,0.7] - self.assertEqual(9,targetMesh.getCoords().getNumberOfTuples()); - self.assertEqual(coordsExp2,targetMesh.getCoords().getValues()); - pass - - def testCheckButterflyCells(self): - sourceMesh=MEDCouplingDataForTest.build2DTargetMesh_1(); - cells=sourceMesh.checkButterflyCells(); - self.assertEqual(0,len(cells)); - conn=sourceMesh.getNodalConnectivity() - tmp=conn.getIJ(15,0) - conn.setIJ(15,0,conn.getIJ(16,0)) - conn.setIJ(16,0,tmp) - cells=sourceMesh.checkButterflyCells(); - self.assertEqual(1,len(cells)); - self.assertEqual([3],cells.getValues()); - tmp=conn.getIJ(15,0) - conn.setIJ(15,0,conn.getIJ(16,0)) - conn.setIJ(16,0,tmp) - cells=sourceMesh.checkButterflyCells(); - self.assertEqual(0,len(cells)); - # 3D surf - sourceMesh=MEDCouplingDataForTest.build3DSurfTargetMesh_1(); - cells=sourceMesh.checkButterflyCells(); - self.assertEqual(0,len(cells)); - conn=sourceMesh.getNodalConnectivity() - tmp=conn.getIJ(15,0) - conn.setIJ(15,0,conn.getIJ(16,0)) - conn.setIJ(16,0,tmp) - cells=sourceMesh.checkButterflyCells(); - self.assertEqual(1,len(cells)); - self.assertEqual([3],cells.getValues()); - tmp=conn.getIJ(15,0) - conn.setIJ(15,0,conn.getIJ(16,0)) - conn.setIJ(16,0,tmp) - cells=sourceMesh.checkButterflyCells(); - self.assertEqual(0,len(cells)); - pass - - def testMergeMesh1(self): - m1=MEDCouplingDataForTest.build2DTargetMesh_1(); - m2=MEDCouplingDataForTest.build2DSourceMesh_1(); - vec=[1.,0.] - m2.translate(vec); - m3=m1.mergeMyselfWith(m2); - self.assertTrue(isinstance(m3,MEDCouplingUMesh)); - m3.checkCoherency(); - m4=MEDCouplingDataForTest.build2DTargetMeshMerged_1(); - self.assertTrue(m3.isEqual(m4,1.e-12)); - da,isMerged,newNbOfNodes=m3.mergeNodes(1.e-12); - self.assertEqual(11,m3.getNumberOfNodes()); - self.assertTrue(isMerged); - pass - - def testMergeMeshOnSameCoords1(self): - m1=MEDCouplingDataForTest.build2DTargetMesh_1(); - m2=MEDCouplingDataForTest.build2DTargetMesh_1(); - cells=range(5); - m2.convertToPolyTypes(cells); - m1.tryToShareSameCoords(m2,1e-12); - m3=MEDCouplingDataForTest.build2DTargetMesh_1(); - m3.tryToShareSameCoords(m2,1e-12); - meshes=[m1,m2,m3] - m4=MEDCouplingUMesh.MergeUMeshesOnSameCoords(meshes); - m4.checkCoherency(); - self.assertEqual(15,m4.getNumberOfCells()); - cells1=[0,1,2,3,4] - m1_1=m4.buildPartOfMySelf(cells1,True); - m1_1.setName(m1.getName()); - self.assertTrue(m1.isEqual(m1_1,1e-12)); - cells2=[5,6,7,8,9] - m2_1=m4.buildPartOfMySelf(cells2,True); - m2_1.setName(m2.getName()); - self.assertTrue(m2.isEqual(m2_1,1e-12)); - cells3=[10,11,12,13,14] - m3_1=m4.buildPartOfMySelf(cells3,True); - m3_1.setName(m3.getName()); - self.assertTrue(m3.isEqual(m3_1,1e-12)); - pass - - def testMergeField1(self): - m1=MEDCouplingDataForTest.build2DTargetMesh_1(); - m2=MEDCouplingDataForTest.build2DSourceMesh_1(); - vec=[1.,0.] - m2.translate(vec); - f1=m1.getMeasureField(True); - f2=m2.getMeasureField(True); - f3=MEDCouplingFieldDouble.MergeFields(f1,f2); - f3.checkCoherency(); - m4=MEDCouplingDataForTest.build2DTargetMeshMerged_1(); - self.assertTrue(f3.getMesh().isEqual(m4,1.e-12)); - name=f3.getName(); - self.assertEqual(name,"MeasureOfMesh_"); - self.assertEqual(f3.getTypeOfField(),ON_CELLS); - self.assertEqual(f3.getTimeDiscretization(),ONE_TIME); - self.assertEqual(1,f3.getNumberOfComponents()); - self.assertEqual(7,f3.getNumberOfTuples()); - values=[0.25,0.125,0.125,0.25,0.25,0.5,0.5] - tmp=f3.getArray().getValues(); - self.assertEqual(len(values),len(tmp)) - for i in xrange(7): - self.assertTrue(abs(values[i]-tmp[i])<1e-12) - pass - pass - - def testFillFromAnalytic(self): - m=MEDCouplingDataForTest.build2DTargetMesh_1(); - m.setTime(3.4,5,6); m.setTimeUnit("us"); - f1=m.fillFromAnalytic(ON_CELLS,1,"x+y"); - self.assertAlmostEqual(3.4,f1.getTime()[0],12) ; self.assertEqual(5,f1.getTime()[1]) ; self.assertEqual(6,f1.getTime()[2]) - self.assertEqual("us",f1.getTimeUnit()) - f1.checkCoherency(); - self.assertEqual(f1.getTypeOfField(),ON_CELLS); - self.assertEqual(f1.getTimeDiscretization(),ONE_TIME); - self.assertEqual(1,f1.getNumberOfComponents()); - self.assertEqual(5,f1.getNumberOfTuples()); - values1=[-0.1,0.23333333333333336,0.56666666666666665,0.4,0.9] - tmp=f1.getArray().getValues(); - self.assertEqual(len(values1),len(tmp)) - for i in xrange(len(tmp)): - self.assertTrue(abs(tmp[i]-values1[i])<1.e-12) - pass - # - f1=m.fillFromAnalytic(ON_NODES,1,"x+y"); - f1.checkCoherency(); - self.assertEqual(f1.getTypeOfField(),ON_NODES); - self.assertEqual(f1.getTimeDiscretization(),ONE_TIME); - self.assertEqual(1,f1.getNumberOfComponents()); - self.assertEqual(9,f1.getNumberOfTuples()); - values2=[-0.6,-0.1,0.4,-0.1,0.4,0.9,0.4,0.9,1.4] - tmp=f1.getArray().getValues(); - self.assertEqual(len(values2),len(tmp)) - for i in xrange(len(tmp)): - self.assertTrue(abs(tmp[i]-values2[i])<1.e-12) - pass - # - f1=m.fillFromAnalytic(ON_NODES,2,"(x+y)*IVec+(2*(x+y))*JVec"); - f1.checkCoherency(); - self.assertEqual(f1.getTypeOfField(),ON_NODES); - self.assertEqual(f1.getTimeDiscretization(),ONE_TIME); - self.assertEqual(2,f1.getNumberOfComponents()); - self.assertEqual(9,f1.getNumberOfTuples()); - values3=[-0.6,-1.2,-0.1,-0.2,0.4,0.8,-0.1,-0.2,0.4,0.8,0.9,1.8,0.4,0.8,0.9,1.8,1.4,2.8] - tmp=f1.getArray().getValues(); - self.assertEqual(len(values3),len(tmp)) - for i in xrange(len(tmp)): - self.assertTrue(abs(tmp[i]-values3[i])<1.e-12) - pass - values4=f1.accumulate(); - self.assertEqual(2,len(values4)) - self.assertTrue(abs(3.6-values4[0])<1.e-12); - self.assertTrue(abs(7.2-values4[1])<1.e-12); - values4=f1.integral(True); - self.assertEqual(2,len(values4)) - self.assertTrue(abs(0.5-values4[0])<1.e-12); - self.assertTrue(abs(1.-values4[1])<1.e-12); - # - self.assertRaises(InterpKernelException,m.fillFromAnalytic,ON_NODES,1,"1./(x-0.2)"); - pass - - def testFillFromAnalytic2(self): - m=MEDCouplingDataForTest.build2DTargetMesh_1(); - f1=m.fillFromAnalytic(ON_CELLS,1,"y+x"); - f1.checkCoherency(); - self.assertEqual(f1.getTypeOfField(),ON_CELLS); - self.assertEqual(f1.getTimeDiscretization(),ONE_TIME); - self.assertEqual(1,f1.getNumberOfComponents()); - self.assertEqual(5,f1.getNumberOfTuples()); - values1=[-0.1,0.23333333333333336,0.56666666666666665,0.4,0.9] - tmp=f1.getArray().getValues(); - self.assertEqual(len(values1),len(tmp)) - for i in xrange(len(values1)): - self.assertTrue(abs(values1[i]-tmp[i])<1.e-12); - pass - # - f1=m.fillFromAnalytic(ON_NODES,1,"y+2*x"); - f1.checkCoherency(); - self.assertEqual(f1.getTypeOfField(),ON_NODES); - self.assertEqual(f1.getTimeDiscretization(),ONE_TIME); - self.assertEqual(1,f1.getNumberOfComponents()); - self.assertEqual(9,f1.getNumberOfTuples()); - values2=[-0.9,0.1,1.1,-0.4,0.6,1.6,0.1,1.1,2.1] - tmp=f1.getArray().getValues(); - self.assertEqual(len(values2),len(tmp)) - for i in xrange(len(values2)): - self.assertTrue(abs(values2[i]-tmp[i])<1.e-12); - pass - f1=m.fillFromAnalytic(ON_NODES,1,"2.*x+y"); - f1.checkCoherency(); - self.assertEqual(f1.getTypeOfField(),ON_NODES); - self.assertEqual(f1.getTimeDiscretization(),ONE_TIME); - self.assertEqual(1,f1.getNumberOfComponents()); - self.assertEqual(9,f1.getNumberOfTuples()); - tmp=f1.getArray().getValues(); - values2Bis=[-0.9,0.1,1.1,-0.4,0.6,1.6,0.1,1.1,2.1] - self.assertEqual(len(values2Bis),len(tmp)) - for i in xrange(len(values2Bis)): - self.assertTrue(abs(values2Bis[i]-tmp[i])<1.e-12); - pass - # - f1=m.fillFromAnalytic(ON_NODES,2,"(x+y)*IVec+2*(x+y)*JVec"); - f1.checkCoherency(); - self.assertEqual(f1.getTypeOfField(),ON_NODES); - self.assertEqual(f1.getTimeDiscretization(),ONE_TIME); - self.assertEqual(2,f1.getNumberOfComponents()); - self.assertEqual(9,f1.getNumberOfTuples()); - values3=[-0.6,-1.2,-0.1,-0.2,0.4,0.8,-0.1,-0.2,0.4,0.8,0.9,1.8,0.4,0.8,0.9,1.8,1.4,2.8] - tmp=f1.getArray().getValues(); - self.assertEqual(len(values3),len(tmp)) - for i in xrange(len(values3)): - self.assertTrue(abs(values3[i]-tmp[i])<1.e-12); - pass - values4=f1.accumulate(); - self.assertTrue(abs(3.6-values4[0])<1.e-12); - self.assertTrue(abs(7.2-values4[1])<1.e-12); - values4=f1.integral(True); - self.assertTrue(abs(0.5-values4[0])<1.e-12); - self.assertTrue(abs(1.-values4[1])<1.e-12); - pass - - def testApplyFunc(self): - m=MEDCouplingDataForTest.build2DTargetMesh_1(); - f1=m.fillFromAnalytic(ON_NODES,2,"(x+y)*IVec+(2*(x+y))*JVec"); - f1.checkCoherency(); - self.assertEqual(f1.getTypeOfField(),ON_NODES); - self.assertEqual(f1.getTimeDiscretization(),ONE_TIME); - self.assertEqual(2,f1.getNumberOfComponents()); - self.assertEqual(9,f1.getNumberOfTuples()); - f1.applyFunc(1,"x+y"); - self.assertEqual(f1.getTypeOfField(),ON_NODES); - self.assertEqual(f1.getTimeDiscretization(),ONE_TIME); - self.assertEqual(1,f1.getNumberOfComponents()); - self.assertEqual(9,f1.getNumberOfTuples()); - values1=[-1.8,-0.3,1.2,-0.3,1.2,2.7,1.2,2.7,4.2] - tmp=f1.getArray().getValues(); - self.assertEqual(len(values1),len(tmp)) - for i in xrange(len(tmp)): - self.assertTrue(abs(tmp[i]-values1[i])<1.e-12) - pass - pass - - def testApplyFunc2(self): - m=MEDCouplingDataForTest.build2DTargetMesh_1(); - f1=m.fillFromAnalytic(ON_NODES,2,"(x+y)*IVec+2*(x+y)*JVec"); - f1.checkCoherency(); - self.assertEqual(f1.getTypeOfField(),ON_NODES); - self.assertEqual(f1.getTimeDiscretization(),ONE_TIME); - self.assertEqual(2,f1.getNumberOfComponents()); - self.assertEqual(9,f1.getNumberOfTuples()); - # - f2=f1.clone(True); - self.assertRaises(InterpKernelException, f2.applyFunc, 1, "a+b+c+d"); - self.assertRaises(InterpKernelException, f2.applyFunc, 1, "a/0"); - self.assertRaises(InterpKernelException, f2.applyFunc, "a/0"); - f2.applyFunc("abs(u)^2.4+2*u"); - self.assertEqual(f1.getTypeOfField(),ON_NODES); - self.assertEqual(f1.getTimeDiscretization(),ONE_TIME); - self.assertEqual(2,f1.getNumberOfComponents()); - self.assertEqual(9,f1.getNumberOfTuples()); - values2=[-0.9065304805418678, -0.85105859001709905, -0.19601892829446504, -0.37898777756476987, - 0.91090317490482353, 2.1853504664669781, -0.19601892829446504, -0.37898777756476987, - 0.91090317490482353, 2.1853504664669781, 2.5765725275664879, 7.6987743736515295, - 0.91090317490482353, 2.1853504664669781, 2.5765725275664879, 7.6987743736515295, - 5.0423700574830965, 17.435300118916864] - tmp=f2.getArray().getValues(); - self.assertEqual(len(tmp),len(values2)) - for i in xrange(len(tmp)): - self.assertTrue(abs(tmp[i]-values2[i])<1.e-12) - pass - # - f1.applyFunc(1,"x+y"); - self.assertEqual(f1.getTypeOfField(),ON_NODES); - self.assertEqual(f1.getTimeDiscretization(),ONE_TIME); - self.assertEqual(1,f1.getNumberOfComponents()); - self.assertEqual(9,f1.getNumberOfTuples()); - values1=[-1.8,-0.3,1.2,-0.3,1.2,2.7,1.2,2.7,4.2] - tmp=f1.getArray().getValues(); - self.assertEqual(len(tmp),len(values1)) - for i in xrange(len(tmp)): - self.assertTrue(abs(tmp[i]-values1[i])<1.e-12) - pass - pass - - def testOperationsOnFields(self): - m=MEDCouplingDataForTest.build2DTargetMesh_1(); - f1=m.fillFromAnalytic(ON_NODES,1,"x+y"); - f2=m.fillFromAnalytic(ON_NODES,1,"x+y"); - f1.checkCoherency(); - f2.checkCoherency(); - f3=f1+f2; - f3.checkCoherency(); - self.assertEqual(f3.getTypeOfField(),ON_NODES); - self.assertEqual(f3.getTimeDiscretization(),ONE_TIME); - values1=[-1.2,-0.2,0.8,-0.2,0.8,1.8,0.8,1.8,2.8] - tmp=f3.getArray().getValues(); - self.assertEqual(len(values1),len(tmp)) - for i in xrange(len(tmp)): - self.assertTrue(abs(tmp[i]-values1[i])<1.e-12) - pass - # - f3=f1*f2; - f3.checkCoherency(); - self.assertEqual(f3.getTypeOfField(),ON_NODES); - self.assertEqual(f3.getTimeDiscretization(),ONE_TIME); - values2=[0.36,0.01,0.16,0.01,0.16,0.81,0.16,0.81,1.96] - tmp=f3.getArray().getValues(); - self.assertEqual(len(values2),len(tmp)) - for i in xrange(len(tmp)): - self.assertTrue(abs(tmp[i]-values2[i])<1.e-12) - pass - # - f3=f1+f2; - f4=f1-f3; - f4.checkCoherency(); - self.assertEqual(f4.getTypeOfField(),ON_NODES); - self.assertEqual(f4.getTimeDiscretization(),ONE_TIME); - values3=[0.6,0.1,-0.4,0.1,-0.4,-0.9,-0.4,-0.9,-1.4] - tmp=f4.getArray().getValues(); - self.assertEqual(len(values3),len(tmp)) - for i in xrange(len(tmp)): - self.assertTrue(abs(tmp[i]-values3[i])<1.e-12) - pass - # - f3=f1+f2; - f4=f3/f2; - f4.checkCoherency(); - self.assertEqual(f4.getTypeOfField(),ON_NODES); - self.assertEqual(f4.getTimeDiscretization(),ONE_TIME); - tmp=f4.getArray().getValues(); - for i in xrange(len(tmp)): - self.assertTrue(abs(tmp[i]-2.)<1.e-12) - pass - # - f4=f2.buildNewTimeReprFromThis(NO_TIME,False); - f4.checkCoherency(); - self.assertEqual(f4.getTypeOfField(),ON_NODES); - self.assertEqual(f4.getTimeDiscretization(),NO_TIME); - self.assertRaises(InterpKernelException,f1.__add__,f4); - f5=f4.buildNewTimeReprFromThis(ONE_TIME,False); - self.assertEqual(f5.getTypeOfField(),ON_NODES); - self.assertEqual(f5.getTimeDiscretization(),ONE_TIME); - f3=f1+f5; - tmp=f3.getArray().getValues(); - values4=[-1.2,-0.2,0.8,-0.2,0.8,1.8,0.8,1.8,2.8] - self.assertEqual(len(values3),len(tmp)) - for i in xrange(len(tmp)): - self.assertTrue(abs(tmp[i]-values4[i])<1.e-12) - pass - # - f4=f2.buildNewTimeReprFromThis(NO_TIME,True); - f4.checkCoherency(); - self.assertEqual(f4.getTypeOfField(),ON_NODES); - self.assertEqual(f4.getTimeDiscretization(),NO_TIME); - self.assertRaises(InterpKernelException,f1.__add__,f4); - f5=f4.buildNewTimeReprFromThis(ONE_TIME,True); - self.assertEqual(f5.getTypeOfField(),ON_NODES); - self.assertEqual(f5.getTimeDiscretization(),ONE_TIME); - f3=f1+f5; - tmp=f3.getArray().getValues(); - values5=[-1.2,-0.2,0.8,-0.2,0.8,1.8,0.8,1.8,2.8] - self.assertEqual(len(values5),len(tmp)) - for i in xrange(len(tmp)): - self.assertTrue(abs(tmp[i]-values5[i])<1.e-12) - pass - pass - - def testOperationsOnFields2(self): - m=MEDCouplingDataForTest.build3DSurfTargetMesh_1(); - m.setTime(3.4,5,6); m.setTimeUnit("us"); - f1=m.fillFromAnalytic(ON_NODES,1,"x+y+z"); - f2=m.fillFromAnalytic(ON_NODES,1,"a*a+b+c*c"); - f3=f1/f2; - f3.checkCoherency(); - self.assertEqual(f3.getTypeOfField(),ON_NODES); - self.assertEqual(f3.getTimeDiscretization(),ONE_TIME); - expected1=[-2.4999999999999991, 1.2162162162162162, 0.77868852459016391, - 0.7407407407407407, 1.129032258064516, 0.81632653061224492, - 0.86538461538461531, 1.0919540229885056, 0.84302325581395343] - self.assertEqual(1,f3.getNumberOfComponents()); - self.assertEqual(9,f3.getNumberOfTuples()); - val=f3.getArray().getValues(); - for i in xrange(9): - self.assertTrue(abs(expected1[i]-val[i])<1.e-12); - # - f1=m.buildOrthogonalField(); - self.assertAlmostEqual(3.4,f1.getTime()[0],12) ; self.assertEqual(5,f1.getTime()[1]) ; self.assertEqual(6,f1.getTime()[2]) - self.assertEqual("us",f1.getTimeUnit()) - f2=m.fillFromAnalytic(ON_CELLS,1,"x"); - f3=f1*f2; - expected2=[-0.035355339059327376,0.,0.035355339059327376, 0.2592724864350674,0.,-0.2592724864350674, 0.37712361663282529,0.,-0.37712361663282529, -0.035355339059327376,0.,0.035355339059327376, 0.31819805153394637,0.,-0.31819805153394637] - val=f3.getArray().getValues(); - for i in xrange(15): - self.assertTrue(abs(expected2[i]-val[i])<1.e-12); - pass - # - f3=f2*f1; - val=f3.getArray().getValues(); - for i in xrange(15): - self.assertTrue(abs(expected2[i]-val[i])<1.e-12); - pass - pass - - def testOperationsOnFields3(self): - m=MEDCouplingDataForTest.build3DSurfTargetMesh_1(); - f1=m.fillFromAnalytic(ON_NODES,1,"x+y+z"); - f2=m.fillFromAnalytic(ON_NODES,1,"a*a+b+c*c"); - f1/=f2 - f1.checkCoherency(); - self.assertEqual(f1.getTypeOfField(),ON_NODES); - self.assertEqual(f1.getTimeDiscretization(),ONE_TIME); - expected1=[-2.4999999999999991, 1.2162162162162162, 0.77868852459016391, - 0.7407407407407407, 1.129032258064516, 0.81632653061224492, - 0.86538461538461531, 1.0919540229885056, 0.84302325581395343] - self.assertEqual(1,f1.getNumberOfComponents()); - self.assertEqual(9,f1.getNumberOfTuples()); - val=f1.getArray().getValues(); - for i in xrange(9): - self.assertTrue(abs(expected1[i]-val[i])<1.e-12); - pass - # - f1=m.buildOrthogonalField(); - f2=m.fillFromAnalytic(ON_CELLS,1,"x"); - f1*=f2 - expected2=[-0.035355339059327376,0.,0.035355339059327376, 0.2592724864350674,0.,-0.2592724864350674, 0.37712361663282529,0.,-0.37712361663282529, -0.035355339059327376,0.,0.035355339059327376, 0.31819805153394637,0.,-0.31819805153394637] - val=f1.getArray().getValues(); - for i in xrange(15): - self.assertTrue(abs(expected2[i]-val[i])<1.e-12); - pass - # - f1=m.buildOrthogonalField(); - # to avoid valgrind leaks - # self.assertRaises(InterpKernelException,f2.__imul__,f1); - pass - - def testOperationsOnFields4(self): - m=MEDCouplingDataForTest.build2DTargetMesh_1(); - nbOfCells=m.getNumberOfCells(); - f1=MEDCouplingFieldDouble.New(ON_CELLS,CONST_ON_TIME_INTERVAL); - f1.setMesh(m); - array=DataArrayDouble.New(); - f1.setArray(array); - self.assertRaises(InterpKernelException,f1.setEndArray,array); - self.assertRaises(InterpKernelException,f1.getEndArray); - arr1=[0.,10.,20.,1.,11.,21.,2.,12.,22.,3.,13.,23.,4.,14.,24.] - arr2=[5.,15.,25.,6.,16.,26.,7.,17.,27.,8.,18.,28.,9.,19.,29.] - array.setValues(arr1,nbOfCells,3); - f1.setStartTime(2.,0,0); - f1.setEndTime(3.,0,0); - f1.checkCoherency(); - pos=[0.3,-0.2] - res=f1.getValueOn(pos); - self.assertTrue(abs(arr1[3]-res[0])<1.e-12); - self.assertTrue(abs(arr1[4]-res[1])<1.e-12); - self.assertTrue(abs(arr1[5]-res[2])<1.e-12); - res=None - res=f1.getValueOn(pos,2.2); - self.assertTrue(abs(arr1[3]-res[0])<1.e-12); - self.assertTrue(abs(arr1[4]-res[1])<1.e-12); - self.assertTrue(abs(arr1[5]-res[2])<1.e-12); - res=None - self.assertRaises(InterpKernelException,f1.getValueOn,pos,3.2) - f2=MEDCouplingFieldDouble.New(ON_CELLS,LINEAR_TIME); - f2.setMesh(m); - f2.setArray(f1.getArray()); - f2.setStartTime(2.,3,0); - f2.setEndTime(4.,13,0); - self.assertRaises(InterpKernelException,f2.checkCoherency) - array2=DataArrayDouble.New(); - array2.setValues(arr2,nbOfCells,3); - f2.setEndArray(array2); - f2.checkCoherency(); - # - res=None - res=f2.getValueOn(pos,3.21); - self.assertTrue(abs(4.025-res[0])<1.e-12); - self.assertTrue(abs(14.025-res[1])<1.e-12); - self.assertTrue(abs(24.025-res[2])<1.e-12); - f3=f2.clone(True); - self.assertTrue(f2.isEqual(f3,1e-12,1e-12)); - f3.getEndArray().setIJ(0,0,5.001); - self.assertTrue(not f2.isEqual(f3,1e-12,1e-12)); - self.assertTrue(f2.isEqual(f3,1e-12,1e-2)); - f3.setStartTime(2.1,3,0); - self.assertTrue(not f2.isEqual(f3,1e-12,1e-2)); - f3.setStartTime(2.,3,0); - self.assertTrue(f2.isEqual(f3,1e-12,1e-2)); - f3.setStartTime(2.,4,0); - self.assertTrue(not f2.isEqual(f3,1e-12,1e-2)); - f3.setStartTime(2.,3,1); - self.assertTrue(not f2.isEqual(f3,1e-12,1e-2)); - f3.setStartTime(2.,3,0); - self.assertTrue(f2.isEqual(f3,1e-12,1e-2)); - f3.setEndTime(4.1,13,0); - self.assertTrue(not f2.isEqual(f3,1e-12,1e-2)); - f3.setEndTime(4.,13,0); - self.assertTrue(f2.isEqual(f3,1e-12,1e-2)); - f3.setEndTime(4.,14,0); - self.assertTrue(not f2.isEqual(f3,1e-12,1e-2)); - f3.setEndTime(4.,13,1); - self.assertTrue(not f2.isEqual(f3,1e-12,1e-2)); - f3.setEndTime(4.,13,0); - self.assertTrue(f2.isEqual(f3,1e-12,1e-2)); - f4=f2+f2 - res=None - res=f4.getValueOn(pos,3.21); - self.assertTrue(abs(8.05-res[0])<1.e-12); - self.assertTrue(abs(28.05-res[1])<1.e-12); - self.assertTrue(abs(48.05-res[2])<1.e-12); - f4+=f2; - res=None - res=f4.getValueOn(pos,3.21); - self.assertTrue(abs(12.075-res[0])<1.e-12); - self.assertTrue(abs(42.075-res[1])<1.e-12); - self.assertTrue(abs(72.075-res[2])<1.e-12); - pass - - def testMergeNodesOnField(self): - targetMesh=MEDCouplingDataForTest.build3DTargetMeshMergeNode_1(); - f1=targetMesh.fillFromAnalytic(ON_NODES,1,"x+y+z"); - f1.mergeNodes(1e-10); - # - targetMesh=MEDCouplingDataForTest.build3DTargetMeshMergeNode_1(); - f1=targetMesh.fillFromAnalytic(ON_NODES,1,"x+y+z"); - tmp=f1.getArray() - tmp.setIJ(0,0,1000.); - f1.mergeNodes(1e-10); - # - targetMesh=MEDCouplingDataForTest.build3DTargetMeshMergeNode_1(); - f1=targetMesh.fillFromAnalytic(ON_NODES,1,"x+y+z"); - tmp=f1.getArray() - tmp.setIJ(1,0,1000.); - self.assertRaises(InterpKernelException,f1.mergeNodes,1.e-10) - pass - - def testCheckConsecutiveCellTypes(self): - sourceMesh=MEDCouplingDataForTest.build2DSourceMesh_1(); - targetMesh=MEDCouplingDataForTest.build2DTargetMesh_1(); - self.assertTrue(sourceMesh.checkConsecutiveCellTypes()); - order1=[NORM_TRI3,NORM_QUAD4] - order2=[NORM_QUAD4,NORM_TRI3] - self.assertTrue(not targetMesh.checkConsecutiveCellTypes()); - self.assertTrue(not targetMesh.checkConsecutiveCellTypesAndOrder(order1)); - self.assertTrue(not targetMesh.checkConsecutiveCellTypesAndOrder(order2)); - da=targetMesh.getRenumArrForConsecutiveCellTypesSpec(order1); - self.assertEqual(5,da.getNumberOfTuples()); - self.assertEqual(1,da.getNumberOfComponents()); - expected1=[2,0,1,3,4] - self.assertTrue(expected1==list(da.getValues())); - da=targetMesh.getRenumArrForConsecutiveCellTypesSpec(order2); - self.assertEqual(5,da.getNumberOfTuples()); - self.assertEqual(1,da.getNumberOfComponents()); - expected2=[0,3,4,1,2] - self.assertTrue(expected2==list(da.getValues())); - renumber1=[4,0,1,2,3] - targetMesh.renumberCells(renumber1,False); - self.assertTrue(targetMesh.checkConsecutiveCellTypes()); - self.assertTrue(targetMesh.checkConsecutiveCellTypesAndOrder(order1)); - self.assertTrue(not targetMesh.checkConsecutiveCellTypesAndOrder(order2)); - pass - - def testRearrange2ConsecutiveCellTypes(self): - m1_1=MEDCouplingDataForTest.build2DSourceMesh_1(); - m2_1=MEDCouplingDataForTest.build2DTargetMesh_1(); - arr1=m1_1.rearrange2ConsecutiveCellTypes(); - m1_2=MEDCouplingDataForTest.build2DSourceMesh_1(); - self.assertTrue(m1_2.isEqual(m1_1,1e-12)); - expected1=[0,1] - self.assertEqual(2,arr1.getNumberOfTuples()); - self.assertEqual(1,arr1.getNumberOfComponents()); - self.assertEqual(expected1,arr1.getValues()); - expected2=[0,3,4,1,2] - arr1=m2_1.rearrange2ConsecutiveCellTypes(); - self.assertEqual(5,arr1.getNumberOfTuples()); - self.assertEqual(1,arr1.getNumberOfComponents()); - self.assertEqual(expected2,list(arr1.getValues())); - m2_2=MEDCouplingDataForTest.build2DTargetMesh_1(); - self.assertEqual(5,arr1.getNumberOfTuples()); - self.assertEqual(1,arr1.getNumberOfComponents()); - self.assertEqual(expected2,list(arr1.getValues())); - self.assertTrue(not m2_2.isEqual(m2_1,1e-12)); - m2_2.renumberCells(expected2,False); - self.assertTrue(m2_2.isEqual(m2_1,1e-12)); - pass - - def testSplitByType(self): - m1=MEDCouplingDataForTest.build3DSurfTargetMesh_1(); - v=m1.splitByType(); - self.assertEqual(3,len(v)); - m2=MEDCouplingUMesh.MergeUMeshesOnSameCoords(v); - m2.setName(m1.getName()); - self.assertTrue(m1.isEqual(m2,1.e-12)); - pass - - def testFuseUMeshesOnSameCoords(self): - m2=MEDCouplingDataForTest.build2DTargetMesh_1(); - cells1=[2,3,4] - m3=m2.buildPartOfMySelf(cells1,True); - self.assertTrue(isinstance(m3,MEDCouplingUMesh)) - cells2=[1,2,4] - m4=m2.buildPartOfMySelf(cells2,True); - self.assertTrue(isinstance(m4,MEDCouplingUMesh)) - cells3=[1,2] - m5=m2.buildPartOfMySelf(cells3,True); - self.assertTrue(isinstance(m5,MEDCouplingUMesh)) - meshes=[m3,m4,m5] - # - m7,corr=MEDCouplingUMesh.FuseUMeshesOnSameCoords(meshes,0); - self.assertEqual(4,m7.getNumberOfCells()); - self.assertEqual(3,len(corr)); - expectedVals1=[3,3,2] - expectedVals2=[[0,1,2],[3,0,2],[3,0]] - for i in xrange(3): - arr=corr[i]; - self.assertEqual(1,arr.getNumberOfComponents()); - nbOfVals=expectedVals1[i]; - self.assertEqual(nbOfVals,arr.getNumberOfTuples()); - vals=arr.getValues(); - self.assertEqual(expectedVals2[i],list(vals)); - pass - arr2,fidsOfGroups=DataArrayInt.MakePartition(corr,m7.getNumberOfCells()); - fidExp=[5,1,3,4] - fidsGrp=[[1,3,5],[3,4,5],[4,5]] - self.assertEqual(3,len(fidsOfGroups)); - self.assertEqual(1,arr2.getNumberOfComponents()); - self.assertEqual(4,arr2.getNumberOfTuples()); - self.assertEqual(fidExp,list(arr2.getValues())); - for i in xrange(3): - nbOfVals=expectedVals1[i]; - self.assertEqual(list(fidsOfGroups[i]),fidsGrp[i]); - pass - pass - - def testFuseUMeshesOnSameCoords2(self): - m1,m2=MEDCouplingDataForTest.build3DExtrudedUMesh_1(); - part1=[2,3,6,4,10] - m3=m1.buildPartOfMySelf(part1,True); - part2=[5,6,4,7] - m4=m1.buildPartOfMySelf(part2,True); - meshes=[m1,m3,m3,m4] - m5,corr=MEDCouplingUMesh.FuseUMeshesOnSameCoords(meshes,0); - self.assertEqual(18,m5.getNumberOfCells()); - exp2=[ - [0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17], - [2,3,6,4,10], - [2,3,6,4,10], - [5,6,4,7]] - i=0; - for it in corr: - self.assertEqual(exp2[i],list(it.getValues())); - i+=1 - pass - pass - - def testBuildOrthogonalField(self): - targetMesh=MEDCouplingDataForTest.build3DSurfTargetMesh_1(); - field=targetMesh.buildOrthogonalField(); - expected=[0.70710678118654746,0.,-0.70710678118654746] - self.assertEqual(5,field.getNumberOfTuples()); - self.assertEqual(3,field.getNumberOfComponents()); - vals=field.getArray().getValues(); - for i in xrange(15): - self.assertTrue(abs(expected[i%3]-vals[i])<1e-12); - # testing - targetCoords=[0.,0.,0.,0.5,0.,0.5,1.,0.,1.,0.,1.,0.] - targetConn=[0,1,2,3] - targetMesh=MEDCouplingUMesh.New(); - targetMesh.setMeshDimension(2); - targetMesh.allocateCells(1); - targetMesh.insertNextCell(NORM_QUAD4,targetConn[0:4]) - targetMesh.finishInsertingCells(); - myCoords=DataArrayDouble.New(); - myCoords.setValues(targetCoords,4,3); - targetMesh.setCoords(myCoords); - field=targetMesh.buildOrthogonalField(); - self.assertEqual(1,field.getNumberOfTuples()); - self.assertEqual(3,field.getNumberOfComponents()); - vals=field.getArray().getValues(); - self.assertTrue(abs(-0.70710678118654746-vals[0])<1e-12); - self.assertTrue(abs(0.-vals[1])<1e-12); - self.assertTrue(abs(0.70710678118654746-vals[2])<1e-12); - pass - - def testGetCellsContainingPoint(self): - targetMesh=MEDCouplingDataForTest.build2DTargetMesh_1(); - pos=[0.,0.,0.4,0.4,0.,0.4,0.1,0.1,0.25,0.,0.65,0.] - #2D basic - t1,t2=targetMesh.getCellsContainingPoints(pos,6,1e-12); - self.assertEqual(6,t1.getNumberOfTuples()); - self.assertEqual(1,t1.getNumberOfComponents()); - self.assertEqual(7,t2.getNumberOfTuples()); - self.assertEqual(1,t2.getNumberOfComponents()); - expectedValues1=[0,4,3,0,1,2] - expectedValues2=[0,1,2,3,4,5,6] - self.assertEqual(list(t1.getValues()),expectedValues1); - self.assertEqual(list(t2.getValues()),expectedValues2); - #2D with no help of bounding box. - center=[0.2,0.2] - MEDCouplingPointSet.Rotate2DAlg(center,0.78539816339744830962,6,pos); - targetMesh.rotate(center,0.78539816339744830962); - t1=None - t2=None - t1,t2=targetMesh.getCellsContainingPoints(pos,1e-12); - self.assertEqual(6,t1.getNumberOfTuples()); - self.assertEqual(7,t2.getNumberOfTuples()); - self.assertEqual(list(t1.getValues()),expectedValues1); - self.assertEqual(list(t2.getValues()),expectedValues2); - t1,t2=targetMesh.getCellsContainingPoints(DataArrayDouble.New(pos,6,2),1e-12); - self.assertEqual(6,t1.getNumberOfTuples()); - self.assertEqual(7,t2.getNumberOfTuples()); - self.assertEqual(list(t1.getValues()),expectedValues1); - self.assertEqual(list(t2.getValues()),expectedValues2); - self.assertRaises(InterpKernelException,targetMesh.getCellsContainingPoints,DataArrayDouble.New(pos,4,3),1e-12); - #2D outside - pos1bis=[-0.3303300858899107,-0.11819805153394641] - self.assertEqual(-1,targetMesh.getCellContainingPoint(pos1bis,1e-12)); - #test limits 2D - targetMesh=MEDCouplingDataForTest.build2DTargetMesh_1(); - pos2=[0.2,-0.05] - t1=None - t1=targetMesh.getCellsContainingPoint(pos2,1e-12) - self.assertEqual(2,len(t1)); - expectedValues3=[0,1] - self.assertEqual(list(t1.getValues()),expectedValues3); - pos3=[0.2,0.2] - t1=None - t1=targetMesh.getCellsContainingPoint(pos3,1e-12); - self.assertEqual(5,len(t1)); - expectedValues4=[0,1,2,3,4] - self.assertEqual(list(t1.getValues()),expectedValues4); - self.assertEqual(0,targetMesh.getCellContainingPoint(pos3,1e-12)); - #3D - targetMesh=MEDCouplingDataForTest.build3DTargetMesh_1(); - pos4=[25.,25.,25.] - self.assertEqual(0,targetMesh.getCellContainingPoint(pos4,1e-12)); - pos5=[50.,50.,50.] - t1=None - t1=targetMesh.getCellsContainingPoint(pos5,1e-12); - self.assertEqual(8,len(t1)); - expectedValues5=[0,1,2,3,4,5,6,7] - self.assertEqual(list(t1.getValues()),expectedValues5); - pos6=[0., 50., 0.] - t1=None - t1=targetMesh.getCellsContainingPoint(pos6,1e-12); - self.assertEqual(2,len(t1)); - expectedValues6=[0,2] - self.assertEqual(list(t1.getValues()),expectedValues6); - #3D outside - pos7=[-1.0,-1.0,0.] - self.assertEqual(-1,targetMesh.getCellContainingPoint(pos7,1e-12)); - #3D outside 2 - center2=[0.,0.,0.] - vec2=[0.,-1.,0.] - targetMesh.rotate(center2,vec2,0.78539816339744830962); - pos8=[-25.,25.,12.] - self.assertEqual(-1,targetMesh.getCellContainingPoint(pos8,1e-12)); - pass - - def testGetValueOn1(self): - targetMesh=MEDCouplingDataForTest.build2DTargetMesh_1(); - fieldOnCells=MEDCouplingFieldDouble.New(ON_CELLS); - nbOfCells=targetMesh.getNumberOfCells(); - fieldOnCells.setMesh(targetMesh); - array=DataArrayDouble.New(); - tmp=2*nbOfCells*[None] - for i in xrange(nbOfCells): - tmp[2*i]=7.+float(i); - tmp[2*i+1]=17.+float(i) - pass - array.setValues(tmp,nbOfCells,2); - fieldOnCells.setArray(array); - # - pos1=[0.25,0.] - res=fieldOnCells.getValueOn(pos1); - self.assertEqual(2,len(res)) - self.assertTrue(abs(8.-res[0])<1e-12); - self.assertTrue(abs(18.-res[1])<1e-12); - # - # - targetMesh=MEDCouplingDataForTest.build2DSourceMesh_1(); - fieldOnNodes=MEDCouplingFieldDouble.New(ON_NODES); - nbOfNodes=targetMesh.getNumberOfNodes(); - fieldOnNodes.setMesh(targetMesh); - array=DataArrayDouble.New(); - tmp=2*nbOfNodes*[None] - for i in xrange(nbOfNodes): - tmp[2*i]=17.+float(i); - tmp[2*i+1]=27.+float(i) - pass - array.setValues(tmp,nbOfNodes,2); - fieldOnNodes.setArray(array); - # - pos2=[-0.13333333333333333,-0.13333333333333333] - res=None - res=fieldOnNodes.getValueOn(pos2); - self.assertEqual(2,len(res)) - self.assertTrue(abs(17.5-res[0])<1e-12); - self.assertTrue(abs(27.5-res[1])<1e-12); - pos3=[0.033333333333333326,0.36666666666666664] - res=None - res=fieldOnNodes.getValueOn(pos3); - self.assertEqual(2,len(res)) - self.assertTrue(abs(18.666666666666667-res[0])<1e-12); - self.assertTrue(abs(28.666666666666667-res[1])<1e-12); - pass - - def testCMesh0(self): - mesh=MEDCouplingCMesh.New(); - meshEmpty=mesh.clone(True); - self.assertTrue(meshEmpty.isEqual(mesh, 1e-12)); - - coordsX=DataArrayDouble.New(); - arrX=[ -1., 1., 2., 4. ] - coordsX.setValues(arrX, 4, 1); - coordsY=DataArrayDouble.New(); - arrY=[ -2., 2., 4., 8. ] - coordsY.setValues(arrY, 4, 1); - coordsZ=DataArrayDouble.New(); - arrZ=[ -3., 3., 6., 12. ] - coordsZ.setValues(arrZ, 4, 1); - mesh.setCoords(coordsX, coordsY, coordsZ); - # - fieldOnNodes=mesh.fillFromAnalytic(ON_NODES, 1, "x+y/2.+z/3."); - self.assertEqual(1, fieldOnNodes.getNumberOfComponents()); - self.assertEqual(64, fieldOnNodes.getNumberOfTuples()); - expected1=[-3., -1., 0., 2., -1., 1., 2., 4., 0., 2., 3., 5., 2., 4., 5., 7., -1., 1., 2., - 4., 1., 3., 4., 6., 2., 4., 5., 7., 4., 6., 7., 9., 0., 2., 3., 5., 2., 4., 5., - 7., 3., 5., 6., 8., 5., 7., 8., 10., 2., 4., 5., - 7., 4., 6., 7., 9., 5., 7., 8., 10., 7., 9., 10., 12.]; - - val=fieldOnNodes.getArray().getValues(); - for i in xrange(64): - self.assertAlmostEqual(expected1[i], val[i], 12) - res=fieldOnNodes.getValueOnPos(1, 3, 2); - self.assertAlmostEqual(7., res[0], 12); - # - fieldOnCells=mesh.fillFromAnalytic(ON_CELLS, 1, "x+y/2.+z/3."); - self.assertEqual(1, fieldOnCells.getNumberOfComponents()); - self.assertEqual(27, fieldOnCells.getNumberOfTuples()); - val=fieldOnCells.getArray().getValues(); - expected2=[0, 1.5, 3, 1.5, 3, 4.5, 3, 4.5, 6, 1.5, 3, 4.5, 3, 4.5, - 6, 4.5, 6, 7.5, 3, 4.5, 6, 4.5, 6, 7.5, 6, 7.5, 9]; - for i in xrange(27): - self.assertAlmostEqual(expected2[i], val[i], 12); - #res=fieldOnCells.getValueOnPos(1,2,1); - #self.assertAlmostEqual(6.,res,12); - # - meshDeepCopy=mesh.deepCpy(); - meshClone=mesh.clone(False); - - meshEmpty.copyTinyStringsFrom(mesh); - #no data in meshEmpty, expected False - self.assertTrue(not meshEmpty.isEqual(mesh, 1e-12)); - - self.assertTrue(meshDeepCopy.isEqual(mesh, 1e-12)); - meshDeepCopy.copyTinyStringsFrom(mesh); - self.assertTrue(meshDeepCopy.isEqual(mesh, 1e-12)); - self.assertTrue(meshClone.isEqual(mesh, 1e-12)); - - self.assertEqual(CARTESIAN, mesh.getType()); - self.assertEqual(CARTESIAN, meshEmpty.getType()); - self.assertEqual(CARTESIAN, meshDeepCopy.getType()); - self.assertEqual(CARTESIAN, meshClone.getType()); - pass - - def testCMesh1(self): - mesh1=MEDCouplingCMesh.New(); - coordsX1=DataArrayDouble.New(); - arrX1=[ -1., 1., 2., 4. ] - coordsX1.setValues(arrX1, 4, 1); - coordsY1=DataArrayDouble.New(); - arrY1=[ -2., 2., 4., 8. ] - coordsY1.setValues(arrY1, 4, 1); - coordsZ1=DataArrayDouble.New(); - arrZ1=[ -3., 3., 6., 12. ] - coordsZ1.setValues(arrZ1, 4, 1); - mesh1.setCoords(coordsX1, coordsY1, coordsZ1); - - mesh2=MEDCouplingCMesh.New(); - coordsX2=DataArrayDouble.New(); - arrX2=[ -1., 1., 2., 4. ] - coordsX2.setValues(arrX2, 4, 1); - coordsY2=DataArrayDouble.New(); - arrY2=[ -2., 2., 4., 8. ] - coordsY2.setValues(arrY2, 4, 1); - coordsZ2=DataArrayDouble.New(); - arrZ2=[ -3., 3., 6., 12.+1e-6 ] - coordsZ2.setValues(arrZ2, 4, 1); - mesh2.setCoords(coordsX2, coordsY2, coordsZ2); - - mesh3=MEDCouplingCMesh.New(); - coordsX3=DataArrayDouble.New(); - arrX3=[-1.] - coordsX3.setValues(arrX3, 1, 1); - coordsY3=DataArrayDouble.New(); - arrY3=[-2.] - coordsY3.setValues(arrY3, 1, 1); - coordsZ3=DataArrayDouble.New(); - arrZ3=[-3.] - coordsZ3.setValues(arrZ3, 1, 1); - mesh3.setCoords(coordsX3, coordsY3, coordsZ3); - - self.assertEqual(3, mesh1.getSpaceDimension()); - self.assertEqual(3, mesh1.getMeshDimension()); - - self.assertTrue(not mesh1.isEqual(mesh2, 1e-12)); - self.assertTrue(not mesh2.isEqual(mesh1, 1e-12)); - self.assertTrue(not mesh2.isEqualWithoutConsideringStr(mesh1, 1e-12)); - self.assertTrue(mesh1.isEqual(mesh2, 1e-5)); - self.assertTrue(not mesh1.isEqual(mesh2, 1e-7)); - - self.assertRaises(InterpKernelException, mesh3.checkCoherency1, 1e-12); - mesh1.checkCoherency2(1e-12); - self.assertEqual(NORM_HEXA8, mesh1.getTypeOfCell(1)); - - self.assertEqual(NORM_HEXA8, mesh1.getAllGeoTypes()[0]); - self.assertEqual(27, mesh1.getNumberOfCellsWithType(NORM_HEXA8)); - self.assertRaises(InterpKernelException, mesh1.getNumberOfCellsWithType, NORM_QUAD4); - - coo=mesh1.getCoordinatesOfNode(0); - self.assertEqual(3, len(coo)); - self.assertAlmostEqual(-1., coo[0], 14); - self.assertAlmostEqual(-2., coo[1], 14); - self.assertAlmostEqual(-3., coo[2], 14); - coo=mesh1.getCoordinatesOfNode(63); - self.assertEqual(3, len(coo)); - self.assertAlmostEqual(4., coo[0], 14); - self.assertAlmostEqual(8., coo[1], 14); - self.assertAlmostEqual(12., coo[2], 14); - - a=str(mesh1) - repr=mesh1.simpleRepr(); - repr=mesh1.advancedRepr(); - self.assertTrue("Cartesian" in repr); - self.assertTrue("Number of components : 1" in repr); - self.assertTrue("Number of tuples : 4" in repr); - self.assertTrue("Z Array :" in repr); - pass - - def testCMesh2(self): - mesh1=MEDCouplingCMesh.New(); - coordsX1=DataArrayDouble.New(); - arrX1=[ -1., 1., 2., 4. ] - coordsX1.setValues(arrX1, 4, 1); - coordsY1=DataArrayDouble.New(); - arrY1=[ -2., 2., 4., 8. ] - coordsY1.setValues(arrY1, 4, 1); - coordsZ1=DataArrayDouble.New(); - arrZ1=[ -3., 3., 6., 12. ] - coordsZ1.setValues(arrZ1, 4, 1); - mesh1.setCoords(coordsX1, coordsY1, coordsZ1); - - dis=mesh1.getDistributionOfTypes(); - self.assertEqual(1, len(dis)); - self.assertEqual(NORM_HEXA8, dis[0][0]); - self.assertEqual(27, dis[0][1]); - self.assertEqual(-1, dis[0][2]); - - idsPerType=[] - self.assertTrue(not mesh1.checkTypeConsistencyAndContig(dis, idsPerType)); - dis[0][0]=NORM_QUAD4; - self.assertRaises(InterpKernelException, mesh1.checkTypeConsistencyAndContig, dis, idsPerType); - dis[0][0]=NORM_HEXA8; - dis[0][2]=0; - ids=DataArrayInt.New(); - ids.alloc(10, 1); - ids.fillWithValue(23); - idsPerType=[ids]; - check=mesh1.checkTypeConsistencyAndContig(dis, idsPerType); - self.assertTrue(check); - self.assertTrue(check.isEqual(ids)); - - code, idsInPflPerType, pfls=mesh1.splitProfilePerType(ids); - self.assertEqual(1, len(code)); - self.assertEqual(NORM_HEXA8, code[0][0]); - self.assertEqual(10, code[0][1]); - self.assertEqual(0, code[0][2]); - self.assertEqual(1, len(idsInPflPerType)); - self.assertEqual(1, len(pfls)); - self.assertTrue(idsInPflPerType[0].isEqual(DataArrayInt([0,1,2,3,4,5,6,7,8,9]))); - self.assertTrue(pfls[0].isEqual(ids)); - - cells1=[0, 1, 25, 26] - partMesh1=mesh1.buildPart(cells1) - self.assertTrue(isinstance(partMesh1,MEDCouplingMesh)) - self.assertEqual(4, partMesh1.getNumberOfCellsWithType(NORM_HEXA8)); - self.assertEqual(64, mesh1.getNumberOfNodes()); - self.assertEqual(64, partMesh1.getNumberOfNodes()); - - cells2=[25, 26] - partMesh2, arr1=mesh1.buildPartAndReduceNodes(cells2) - self.assertTrue(isinstance(partMesh2,MEDCouplingCMesh)) - self.assertEqual(2,partMesh2.getNumberOfCellsWithType(NORM_HEXA8)); - self.assertEqual(12,partMesh2.getNumberOfNodes()); - - cells3=[2, 3] - partMesh3, arr2=partMesh1.buildPartAndReduceNodes(cells3) - self.assertTrue(isinstance(partMesh3,MEDCouplingUMesh)) - self.assertEqual(2, partMesh3.getNumberOfCellsWithType(NORM_HEXA8)); - self.assertEqual(12, partMesh3.getNumberOfNodes()); - - self.assertRaises(InterpKernelException, mesh1.simplexize, 0); - self.assertRaises(InterpKernelException, mesh1.getMeasureFieldOnNode, True); - - #double bbox1[6]; - #double bbox2[6]; - bbox1=mesh1.getBoundingBox(); #[(-1.0, 4.0), (-2.0, 8.0), (-3.0, 12.0)] - bbox2=partMesh1.getBoundingBox(); - self.assertTrue(bbox1==bbox2); - bbox1=partMesh3.getBoundingBox(); - bbox2=partMesh2.getBoundingBox(); - self.assertTrue(bbox1==bbox2); - - self.assertRaises(InterpKernelException, mesh1.buildOrthogonalField); - mesh2d=MEDCouplingCMesh.New(); - mesh2d.setCoords(coordsX1, coordsY1); - f1=mesh2d.buildOrthogonalField(); - - pass - - def testScale(self): - mesh=MEDCouplingDataForTest.build2DTargetMesh_1(); - pos=[0.2,0.2] - mesh.scale(pos,0.5); - expected1=[-0.05,-0.05, 0.2,-0.05, 0.45,-0.05, -0.05,0.2, 0.2,0.2, 0.45,0.2, - -0.05,0.45, 0.2,0.45, 0.45,0.45] - val=mesh.getCoords().getValues(); - self.assertEqual(18,len(val)) - for i in xrange(18): - self.assertTrue(abs(expected1[i]-val[i])<1e-12); - pass - pass - - def testTryToShareSameCoords(self): - m1=MEDCouplingDataForTest.build2DTargetMesh_1(); - m2=MEDCouplingDataForTest.build2DTargetMesh_1(); - self.assertTrue(m1.getCoords().getHiddenCppPointer()!=m2.getCoords().getHiddenCppPointer()); - m1.tryToShareSameCoords(m2,1e-12); - self.assertTrue(m1.getCoords().getHiddenCppPointer()==m2.getCoords().getHiddenCppPointer()); - m1.tryToShareSameCoords(m2,1e-12); - self.assertTrue(m1.getCoords().getHiddenCppPointer()==m2.getCoords().getHiddenCppPointer()); - m2.tryToShareSameCoords(m1,1e-12); - self.assertTrue(m1.getCoords().getHiddenCppPointer()==m2.getCoords().getHiddenCppPointer()); - # - m1=MEDCouplingDataForTest.build2DTargetMesh_1(); - m2=MEDCouplingDataForTest.build2DTargetMesh_2(); - self.assertTrue(m1.getCoords().getHiddenCppPointer()!=m2.getCoords().getHiddenCppPointer()); - m1.tryToShareSameCoords(m2,1e-12); - self.assertTrue(m1.getCoords().getHiddenCppPointer()==m2.getCoords().getHiddenCppPointer()); - m1.tryToShareSameCoords(m2,1e-12); - self.assertTrue(m1.getCoords().getHiddenCppPointer()==m2.getCoords().getHiddenCppPointer()); - m2.tryToShareSameCoords(m1,1e-12); - self.assertTrue(m1.getCoords().getHiddenCppPointer()==m2.getCoords().getHiddenCppPointer()); - # - m1=MEDCouplingDataForTest.build2DTargetMesh_1(); - m2=MEDCouplingDataForTest.build2DSourceMesh_1(); - self.assertTrue(m1.getCoords().getHiddenCppPointer()!=m2.getCoords().getHiddenCppPointer()); - self.assertRaises(InterpKernelException,m1.tryToShareSameCoords,m2,1e-12) - pass - - def testFindNodeOnPlane(self): - mesh=MEDCouplingDataForTest.build3DTargetMesh_1(); - pt=[300.,300.,0.] - v=[0.,0.,2.] - n=mesh.findNodesOnPlane(pt,v,1e-12); - self.assertEqual(9,len(n)); - m3dSurf=mesh.buildFacePartOfMySelfNode(n,True); - self.assertTrue(isinstance(m3dSurf,MEDCouplingUMesh)) - me=MEDCouplingExtrudedMesh.New(mesh,m3dSurf,0); - da=me.getMesh3DIds(); - self.assertEqual(8,me.getNumberOfCells()); - expected=[0,1,2,3,4,5,6,7] - val=da.getValues(); - self.assertEqual(expected,list(val)); - # - m3dSurf=mesh.buildFacePartOfMySelfNode(n,True); - self.assertTrue(isinstance(m3dSurf,MEDCouplingUMesh)) - me=MEDCouplingExtrudedMesh.New(mesh,m3dSurf,0); - da=me.getMesh3DIds(); - self.assertEqual(8,me.getNumberOfCells()); - expected=[0,1,2,3,4,5,6,7] - val=da.getValues(); - self.assertEqual(expected,list(val)); - pass - - def testRenumberCells(self): - m=MEDCouplingDataForTest.build3DSurfTargetMesh_1(); - m2=MEDCouplingDataForTest.build3DSurfTargetMesh_1(); - self.assertTrue(m.isEqual(m2,0)); - arr=[12,3,25,2,26] - m.renumberCells(arr,True); - self.assertTrue(not m.isEqual(m2,0)); - self.assertEqual(NORM_QUAD4,m.getTypeOfCell(0)); - self.assertEqual(NORM_TRI3,m.getTypeOfCell(1)); - self.assertEqual(NORM_QUAD4,m.getTypeOfCell(2)); - self.assertEqual(NORM_TRI3,m.getTypeOfCell(3)); - self.assertEqual(NORM_QUAD4,m.getTypeOfCell(4)); - arr2=[5,-1,-5,4,8] - m.renumberCells(arr2,True); - self.assertTrue(m.isEqual(m2,0)); - pass - - def testChangeSpaceDimension(self): - m1=MEDCouplingDataForTest.build3DSurfTargetMesh_1(); - m2=MEDCouplingDataForTest.build2DTargetMesh_1(); - # - self.assertEqual(3,m1.getSpaceDimension()); - m1.changeSpaceDimension(2); - self.assertEqual(2,m1.getSpaceDimension()); - m1.setName(m2.getName()); - self.assertTrue(m1.isEqual(m2,1e-12)); - m1.changeSpaceDimension(3); - self.assertEqual(3,m1.getSpaceDimension()); - expected=[-0.3,-0.3,0., 0.2,-0.3,0., 0.7,-0.3,0., -0.3,0.2,0., 0.2,0.2,0., 0.7,0.2,0., -0.3,0.7,0., 0.2,0.7,0., 0.7,0.7,0.] - val=m1.getCoords().getValues(); - for i in xrange(27): - self.assertTrue(abs(expected[i]-val[i])<1e-14); - pass - pass - - def testGaussPointField1(self): - _a=0.446948490915965; - _b=0.091576213509771; - _p1=0.11169079483905; - _p2=0.0549758718227661; - refCoo1=[ 0.,0., 1.,0., 0.,1. ] - gsCoo1=[ 2*_b-1, 1-4*_b, 2*_b-1, 2.07*_b-1, 1-4*_b, - 2*_b-1, 1-4*_a, 2*_a-1, 2*_a-1, 1-4*_a, 2*_a-1, 2*_a-1 ] - wg1=[ 4*_p2, 4*_p2, 4*_p2, 4*_p1, 4*_p1, 4*_p1 ] - _refCoo1=refCoo1 - _gsCoo1=gsCoo1 - _wg1=wg1 - # - m=MEDCouplingDataForTest.build2DTargetMesh_1(); - f=MEDCouplingFieldDouble.New(ON_GAUSS_PT,NO_TIME); - f.setMesh(m); - self.assertEqual(5,f.getNumberOfMeshPlacesExpected()); - self.assertEqual(0,f.getNbOfGaussLocalization()); - f.setGaussLocalizationOnType(NORM_TRI3,_refCoo1,_gsCoo1,_wg1); - f.setGaussLocalizationOnType(NORM_TRI3,_refCoo1,_gsCoo1,_wg1); # not a bug only to check that it works well - self.assertRaises(InterpKernelException,f.setGaussLocalizationOnType,NORM_QUAD4,_refCoo1,_gsCoo1,_wg1) - self.assertEqual(1,f.getNbOfGaussLocalization()); - refCoo2=[ 0.,0., 1.,0., 1.,1., 0.,1. ] - _refCoo2=refCoo2 - _gsCoo1=_gsCoo1[0:4] - _wg1=_wg1[0:2] - f.setGaussLocalizationOnType(NORM_QUAD4,_refCoo2,_gsCoo1,_wg1); - self.assertEqual(2,f.getNbOfGaussLocalization()); - array=DataArrayDouble.New(); - ptr=18*2*[None] - for i in xrange(18*2): - ptr[i]=float(i+1) - array.setValues(ptr,18,2); - ptr=array.getPointer(); - f.setArray(array); - f.setName("MyFirstFieldOnGaussPoint"); - f.checkCoherency(); - self.assertAlmostEqual(27.,f.getIJK(2,5,0),14); - self.assertAlmostEqual(16.,f.getIJK(1,5,1),14); - # - f.clearGaussLocalizations(); - self.assertEqual(0,f.getNbOfGaussLocalization()); - self.assertRaises(InterpKernelException,f.checkCoherency); - ids1=[0,1,3,4] - self.assertRaises(InterpKernelException,f.setGaussLocalizationOnCells,ids1,_refCoo2,_gsCoo1,_wg1); - self.assertEqual(0,f.getNbOfGaussLocalization()); - ids2=[0,4] - f.setGaussLocalizationOnCells(ids2,_refCoo2,_gsCoo1,_wg1); - self.assertEqual(1,f.getNbOfGaussLocalization()); - self.assertEqual(0,f.getGaussLocalizationIdOfOneCell(0)); - self.assertRaises(InterpKernelException,f.getGaussLocalizationIdOfOneCell,1); - ids3=[1,2] - f.setGaussLocalizationOnCells(ids3,_refCoo1,_gsCoo1,_wg1); - self.assertEqual(2,f.getNbOfGaussLocalization()); - self.assertEqual(0,f.getGaussLocalizationIdOfOneCell(0)); - self.assertEqual(1,f.getGaussLocalizationIdOfOneCell(1)); - self.assertEqual(1,f.getGaussLocalizationIdOfOneCell(2)); - self.assertRaises(InterpKernelException,f.checkCoherency);#<- cell 3 has no localization - ids4=[3] - _gsCoo2=_gsCoo1; - _wg2=_wg1; - _gsCoo2[0]=0.8888777776666; - _wg2[0]=0.1234567892377; - f.setGaussLocalizationOnCells(ids4,_refCoo2,_gsCoo2,_wg2); - self.assertEqual(3,f.getNbOfGaussLocalization()); - tmpIds=f.getCellIdsHavingGaussLocalization(0); - self.assertEqual(ids2,list(tmpIds.getValues())); - self.assertRaises(InterpKernelException,f.checkCoherency);#<- it's always not ok because undelying array not with the good size. - array2=f.getArray().substr(0,10); - f.setArray(array2); - f.checkCoherency();#<- here it is OK - f2=f.clone(True); - self.assertTrue(f.isEqual(f2,1e-14,1e-14)); - gl1=f2.getGaussLocalization(0); - tmp=gl1.getGaussCoord(1,1); - self.assertAlmostEqual(2.07*_b-1,tmp,14); - gl1.setGaussCoord(1,1,0.07); - self.assertTrue(not f.isEqual(f2,1e-14,1e-14)); - gl1.setGaussCoord(1,1,tmp); - self.assertTrue(f.isEqual(f2,1e-14,1e-14)); - f2.checkCoherency(); - pass - - def testGaussPointNEField1(self): - m=MEDCouplingDataForTest.build2DTargetMesh_1(); - f=MEDCouplingFieldDouble.New(ON_GAUSS_NE,NO_TIME); - f.setMesh(m); - self.assertEqual(5,f.getNumberOfMeshPlacesExpected()); - f.setName("MyFirstFieldOnNE"); - f.setDescription("MyDescriptionNE"); - array=DataArrayDouble.New(); - tmp=18*2*[None] - for i in xrange(18*2): - tmp[i]=float(i+7) - pass - array.setValues(tmp,18,2); - ptr=array.getPointer(); - f.setArray(array); - # - f.checkCoherency(); - f2=f.clone(True); - self.assertTrue(f.isEqual(f2,1e-14,1e-14)); - self.assertAlmostEqual(21.,f.getIJK(2,0,0),14); - self.assertAlmostEqual(18.,f.getIJK(1,1,1),14); - pass - - def testCellOrientation1(self): - m=MEDCouplingDataForTest.build2DTargetMesh_1(); - vec=[0.,0.,-1.] - self.assertRaises(InterpKernelException,m.are2DCellsNotCorrectlyOriented,vec,False); - m.changeSpaceDimension(3); - res1=m.are2DCellsNotCorrectlyOriented(vec,False); - self.assertTrue(len(res1)==0); - vec[2]=1.; - res1=m.are2DCellsNotCorrectlyOriented(vec,False); - self.assertEqual(5,len(res1)); - # - vec[2]=-1.; - # connectivity inversion - conn=m.getNodalConnectivity().getValues(); - tmp=conn[11]; - conn[11]=conn[12]; - conn[12]=tmp; - m.getNodalConnectivity().setValues(conn,len(conn),1) - res1=m.are2DCellsNotCorrectlyOriented(vec,False); - self.assertEqual(1,len(res1)); - self.assertEqual(2,res1.getValues()[0]); - m.orientCorrectly2DCells(vec,False); - res1=m.are2DCellsNotCorrectlyOriented(vec,False); - self.assertTrue(len(res1)==0); - m2=MEDCouplingDataForTest.build2DTargetMesh_1(); - m2.changeSpaceDimension(3); - self.assertTrue(m.isEqual(m2,1e-12)); - pass - - def testCellOrientation2(self): - m2,m1=MEDCouplingDataForTest.build3DExtrudedUMesh_1(); - res1=m2.arePolyhedronsNotCorrectlyOriented(); - self.assertEqual(6,len(res1)); - m2.orientCorrectlyPolyhedrons(); - res1=m2.arePolyhedronsNotCorrectlyOriented(); - self.assertTrue(len(res1)==0); - m2.checkCoherency(); - self.assertEqual(18,m2.getNumberOfCells()); - cellIds2=[0,6,12] - m2.convertToPolyTypes(cellIds2); - m2.orientCorrectlyPolyhedrons(); - res1=m2.arePolyhedronsNotCorrectlyOriented(); - self.assertTrue(len(res1)==0); - f2=m2.getMeasureField(False); - f2Ptr=f2.getArray().getValues(); - #Test to check global reverse in MEDCouplingUMesh::tryToCorrectPolyhedronOrientation - m3=MEDCouplingDataForTest.build2DTargetMesh_1(); - vec=[0.,0.,1.] - m3.changeSpaceDimension(3); - ids2=[0,1,2,3,4] - m3.convertToPolyTypes(ids2); - m3.orientCorrectly2DCells(vec,False); - m4=MEDCouplingDataForTest.buildCU1DMesh_U(); - m4.changeSpaceDimension(3); - center=[0.,0.,0.] - vector=[0.,1.,0.] - m4.rotate(center,vector,-pi/2.); - m5=m3.buildExtrudedMesh(m4,0); - res1=m5.arePolyhedronsNotCorrectlyOriented(); - self.assertEqual(15,len(res1)); - m5.orientCorrectlyPolyhedrons(); - res1=m5.arePolyhedronsNotCorrectlyOriented(); - self.assertTrue(len(res1)==0); - f3=m5.getMeasureField(False); - self.assertEqual(15,f3.getArray().getNumberOfTuples()); - self.assertEqual(1,f3.getNumberOfComponents()); - f3Ptr=f3.getArray().getValues(); - expected1=[0.075,0.0375,0.0375,0.075,0.075, 0.1125,0.05625,0.05625,0.1125,0.1125, 0.0625,0.03125,0.03125,0.0625,0.0625]; - for i in xrange(15): - self.assertTrue(abs(expected1[i]-f3Ptr[i])<1e-12); - pass - f4=m5.getBarycenterAndOwner(); - self.assertEqual(15,f4.getNumberOfTuples()); - self.assertEqual(3,f4.getNumberOfComponents()); - f4Ptr=f4.getValues(); - expected2=[-0.05,-0.05,0.15, 0.3666666666666667,-0.13333333333333333,0.15, 0.53333333333333333,0.033333333333333333,0.15, -0.05,0.45,0.15, 0.45,0.45,0.15,-0.05,-0.05,0.525, 0.3666666666666667,-0.13333333333333333,0.525, 0.53333333333333333,0.033333333333333333,0.525, -0.05,0.45,0.525, 0.45,0.45,0.525,-0.05,-0.05,0.875, 0.3666666666666667,-0.13333333333333333,0.875, 0.53333333333333333,0.033333333333333333,0.875, -0.05,0.45,0.875, 0.45,0.45,0.875]; - for i in xrange(45): - self.assertTrue(abs(expected2[i]-f4Ptr[i])<1e-12); - pass - pass - - def testCellOrientation3(self): - from cmath import rect - - c = [rect(1.0, i*pi/4.0) for i in range(8)] - coords = [c[-1].real,c[-1].imag, c[3].real,c[3].imag, - c[5].real,c[5].imag, c[1].real,c[1].imag] - connec = [0,1,2,3] - baseMesh = MEDCouplingUMesh.New("circle", 2) - baseMesh.allocateCells(1) - meshCoords = DataArrayDouble.New(coords, 4, 2) - baseMesh.setCoords(meshCoords) - baseMesh.insertNextCell(NORM_QPOLYG, connec) # a circle - baseMesh.finishInsertingCells() - baseMesh.changeSpaceDimension(3) - Oz = [0.0, 0.0, -1.0] - cell_lst = baseMesh.are2DCellsNotCorrectlyOriented(Oz, False) - self.assertEqual(cell_lst.getNumberOfTuples(), 0) - Oz[2] = 1.0 - cell_lst = baseMesh.are2DCellsNotCorrectlyOriented(Oz, False) - self.assertEqual(cell_lst.getNumberOfTuples(), 1) - - def testPolyhedronBarycenter(self): - connN=[0,3,2,1, -1, 4,5,6,7, -1, 0,4,7,3, -1, 3,7,6,2, -1, 2,6,5,1, -1, 1,5,4,0]; - coords=[0.,0.,0., 1.,0.,0., 1.,1.,0., 0.,1.,0., 0.,0.,1., 1.,0.,1., 1.,1.,1., 0.,1.,1., 0.5, 0.5, 0.5]; - meshN=MEDCouplingUMesh.New(); - meshN.setName("ForBary"); - meshN.setMeshDimension(3); - meshN.allocateCells(4); - meshN.insertNextCell(NORM_POLYHED,29,connN[0:29]) - meshN.finishInsertingCells(); - myCoords=DataArrayDouble.New(); - myCoords.setValues(coords,9,3); - meshN.setCoords(myCoords); - meshN.checkCoherency(); - # - res1=meshN.arePolyhedronsNotCorrectlyOriented(); - meshN.orientCorrectlyPolyhedrons(); - self.assertTrue(len(res1)==0); - da=meshN.getBarycenterAndOwner(); - self.assertEqual(1,da.getNumberOfTuples()); - self.assertEqual(3,da.getNumberOfComponents()); - daPtr=da.getValues(); - ref=meshN.getCoords().getValues()[24:]; - for i in xrange(3): - self.assertTrue(abs(ref[i]-daPtr[i])<1e-12); - pass - # - center=[0.,0.,0.] - vec=[0.,2.78,0.] - da=meshN.getBarycenterAndOwner(); - daPtr=da.getValues(); - ref=meshN.getCoords().getValues()[24:]; - for i in xrange(3): - self.assertTrue(abs(ref[i]-daPtr[i])<1e-12); - pass - # - meshN.rotate(center,vec,pi/7.); - meshN.translate(vec); - da=meshN.getBarycenterAndOwner(); - daPtr=da.getValues(); - ref=meshN.getCoords().getValues()[24:]; - for i in xrange(3): - self.assertTrue(abs(ref[i]-daPtr[i])<1e-12); - pass - # - center2=[1.12,3.45,6.78] - vec2=[4.5,9.3,2.8] - meshN.rotate(center2,vec2,e); - meshN.translate(vec2); - da=meshN.getBarycenterAndOwner(); - daPtr=da.getValues(); - ref=meshN.getCoords().getValues()[24:]; - for i in xrange(3): - self.assertTrue(abs(ref[i]-daPtr[i])<1e-10); - pass - pass - - def testNormL12Integ1D(self): - m1=MEDCouplingDataForTest.build1DTargetMesh_3(); - f1=MEDCouplingFieldDouble.New(ON_CELLS,NO_TIME); - f1.setMesh(m1); - array=DataArrayDouble.New(); - arr=[-5.23,15.45,-25.56,6.67,-16.78,26.89,-7.91,17.23,-27.43,8.21,-18.63,28.72] - array.setValues(arr,m1.getNumberOfCells(),3); - f1.setArray(array); - # - f3=m1.getBarycenterAndOwner(); - self.assertEqual(4,f3.getNumberOfTuples()); - self.assertEqual(1,f3.getNumberOfComponents()); - expected9=[0.75,5.105,0.8,5.155] - ptr=f3.getValues(); - for i in xrange(4): - self.assertTrue(abs(expected9[i]-ptr[i])<1e-12); - pass - # - f2=m1.getMeasureField(False); - self.assertEqual(4,f2.getArray().getNumberOfTuples()); - self.assertEqual(1,f2.getNumberOfComponents()); - expected1=[0.5,0.21,-0.6,-0.31] - ptr=f2.getArray().getValues(); - for i in xrange(4): - self.assertTrue(abs(expected1[i]-ptr[i])<1e-12); - pass - expected2=[0.5,0.21,0.6,0.31] - f2=m1.getMeasureField(True); - ptr=f2.getArray().getValues(); - for i in xrange(4): - self.assertTrue(abs(expected2[i]-ptr[i])<1e-12); - pass - #integral - self.assertTrue(4,f1.getNumberOfTuples()) - res=f1.integral(False); - self.assertTrue(3,len(res)) - expected3=[0.9866,-0.3615,0.4217] - for i in xrange(3): - self.assertTrue(abs(expected3[i]-res[i])<1e-12); - pass - self.assertTrue(abs(expected3[0]-f1.integral(0,False))<1e-12); - self.assertTrue(abs(expected3[1]-f1.integral(1,False))<1e-12); - self.assertTrue(abs(expected3[2]-f1.integral(2,False))<1e-12); - res=f1.integral(True); - expected4=[-3.4152,8.7639,-14.6879] - for i in xrange(3): - self.assertTrue(abs(expected4[i]-res[i])<1e-12); - pass - #normL1 - res=f1.normL1(); - self.assertTrue(3,len(res)) - expected5=[6.979506172839505, 16.89018518518518, 27.02969135802469] - for i in xrange(3): - self.assertTrue(abs(expected5[i]-res[i])<1e-12); - pass - self.assertTrue(abs(expected5[0]-f1.normL1(0))<1e-12); - self.assertTrue(abs(expected5[1]-f1.normL1(1))<1e-12); - self.assertTrue(abs(expected5[2]-f1.normL1(2))<1e-12); - #normL2 - res=f1.normL2(); - self.assertTrue(3,len(res)) - expected7=[7.090910979452395, 16.9275542960123, 27.053271464160858] - for i in xrange(3): - self.assertTrue(abs(expected7[i]-res[i])<1e-9); - pass - self.assertTrue(abs(expected7[0]-f1.normL2(0))<1e-9); - self.assertTrue(abs(expected7[1]-f1.normL2(1))<1e-9); - self.assertTrue(abs(expected7[2]-f1.normL2(2))<1e-9); - #buildMeasureField - f4=f1.buildMeasureField(False); - self.assertTrue(abs(-0.2-f4.accumulate(0))<1e-12); - f4=f1.buildMeasureField(True); - self.assertTrue(abs(1.62-f4.accumulate(0))<1e-12); - # Testing with 2D Curve - m1=MEDCouplingDataForTest.build2DCurveTargetMesh_3(); - f2=m1.getMeasureField(False); - self.assertEqual(4,f2.getArray().getNumberOfTuples()); - self.assertEqual(1,f2.getNumberOfComponents()); - ptr=f2.getArray().getValues(); - for i in xrange(4): - self.assertTrue(abs(sqrt(2.)*expected2[i]-ptr[i])<1e-12); - pass - f2=m1.getMeasureField(True); - self.assertEqual(4,f2.getArray().getNumberOfTuples()); - self.assertEqual(1,f2.getNumberOfComponents()); - ptr=f2.getArray().getValues(); - for i in xrange(4): - self.assertTrue(abs(expected2[i]*sqrt(2.)-ptr[i])<1e-12); - pass - #bary - f3=m1.getBarycenterAndOwner(); - self.assertEqual(4,f3.getNumberOfTuples()); - self.assertEqual(2,f3.getNumberOfComponents()); - expected10=[0.75,0.75,5.105,5.105,0.8,0.8,5.155,5.155] - ptr=f3.getValues(); - for i in xrange(8): - self.assertTrue(abs(expected10[i]-ptr[i])<1e-12); - pass - # - f1=MEDCouplingFieldDouble.New(ON_CELLS,NO_TIME); - f1.setMesh(m1); - array=DataArrayDouble.New(); - array.setValues(arr,m1.getNumberOfCells(),3); - f1.setArray(array); - res=f1.integral(False); - for i in xrange(3): - self.assertTrue(abs(sqrt(2.)*expected4[i]-res[i])<1e-12); - pass - res=f1.integral(True); - for i in xrange(3): - self.assertTrue(abs(sqrt(2.)*expected4[i]-res[i])<1e-12); - pass - res=f1.normL1(); - for i in xrange(3): - self.assertTrue(abs(expected5[i]-res[i])<1e-12); - pass - res=f1.normL2(); - for i in xrange(3): - self.assertTrue(abs(expected7[i]-res[i])<1e-12); - pass - pass - - def testAreaBary2D(self): - m1=MEDCouplingDataForTest.build2DTargetMesh_3(); - f1=m1.getMeasureField(False); - self.assertEqual(10,f1.getArray().getNumberOfTuples()); - self.assertEqual(1,f1.getNumberOfComponents()); - expected1=[-0.5,-1,-1.5,-0.5,-1, 0.5,1,1.5,0.5,1] - ptr=f1.getArray().getValues(); - for i in xrange(10): - self.assertTrue(abs(expected1[i]-ptr[i])<1e-12); - pass - f1=m1.getMeasureField(True); - ptr=f1.getArray().getValues(); - for i in xrange(10): - self.assertTrue(abs(abs(expected1[i])-ptr[i])<1e-12); - pass - f2=m1.getBarycenterAndOwner(); - self.assertEqual(10,f2.getNumberOfTuples()); - self.assertEqual(2,f2.getNumberOfComponents()); - expected2=[0.5,0.3333333333333333,0.5,0.5,0.5,0.77777777777777777,0.5,0.3333333333333333,0.5,0.5,0.5,0.3333333333333333,0.5,0.5,0.5,0.77777777777777777,0.5,0.3333333333333333,0.5,0.5] - ptr=f2.getValues(); - for i in xrange(20): - self.assertTrue(abs(expected2[i]-ptr[i])<1e-12); - pass - m1.changeSpaceDimension(3); - f1=m1.getMeasureField(False); - self.assertEqual(10,f1.getArray().getNumberOfTuples()); - self.assertEqual(1,f1.getNumberOfComponents()); - ptr=f1.getArray().getValues(); - for i in xrange(10): - self.assertTrue(abs(abs(expected1[i])-ptr[i])<1e-12); - pass - f2=m1.getBarycenterAndOwner(); - self.assertEqual(10,f2.getNumberOfTuples()); - self.assertEqual(3,f2.getNumberOfComponents()); - ptr=f2.getValues(); - expected3=[0.5,0.3333333333333333,0.,0.5,0.5,0.,0.5,0.77777777777777777,0.,0.5,0.3333333333333333,0.,0.5,0.5,0., 0.5,0.3333333333333333,0.,0.5,0.5,0.,0.5,0.77777777777777777,0.,0.5,0.3333333333333333,0.,0.5,0.5,0.] - for i in xrange(30): - self.assertTrue(abs(expected3[i]-ptr[i])<1e-12); - pass - pass - - def testAreaBary3D(self): - coords=[ 0.241310763507 , 0.0504777305619 , 0.0682283524903 , 0.252501053866 , -0.0625176732937 , 0.137272639894 , - 0.152262663601 , 0.241816569527 , 0.133812556197 , 0.18047750211 , -0.0789949051358 , 0.339098173401 , - 0.151741971857 , 0.238885278571 , 0.137715037333 , 0.242532155481 , -0.0928169086456 , 0.0678043417367 , - 0.240941965335 , -0.015461491464 , 0.0617186345825 , 0.24127650112 , 0.0499427876717 , 0.0679634099148 , - -0.145828917428 , 0.206291632565 , 0.0310071927543 , 0.0125651775307 , 0.266262085828 , 0.105228430543 , - -0.0994066533286 , 0.233224271238 , 0.0572213839567 , -0.0951345338317 , 0.234819509426 , 0.0592126284538 , - 0.136580574205 , -0.205486212579 , 0.0572866072014 , 0.0637270784978 , -0.168886355238 , 0.446614057077 , - 0.041337157151 , -0.213402568198 , 0.372407095999 , 0.0411601970268 , -0.202387875756 , 0.411334979491 , - -0.108355701857 , 0.193636239335 , 0.204886756738 , 0.00639779029829 , 0.155296981517 , 0.252585892979 , - 0.0262473111702 , -0.112919732543 , 0.424286639249 ,-0.224103052733 , -0.139430015438 , -0.0122352295701 , - -0.0312760589481 , -0.274272003594 , 0.0323959636568 , -0.166663422532 , -0.217754445175 , 0.00392109070364 , - -0.30586619777 , -0.0475168041091 , -0.0144585228182 , -0.280881480586 , 0.135571293538 , 0.00623923647986 , - -0.25548538234 , 0.156819217766 , 0.0645277879769 , -0.131567009284 , 0.184133752309 , 0.206021802753 , - -0.196204010965 , 0.151602971681 , 0.212974777736 , -0.183713879463 , 0.0802946639531 , 0.260115662599 , - -0.244241178767 , -0.0738873389604 , 0.144590565817 , -0.155804057829 , -0.164892720025 , 0.210613950558 , - -0.170950800428 , -0.215099334026 , 0.00610122860092 , -0.30552634869 , -0.0490020791904 , -0.0132786533145 , - 0.271831011884 , 0.15105657296 , 0.0230534827908 , 0.281919192283 , 0.0898544306288 , -0.0625201489143 , - 0.260240727276 , -0.0120688706637 , -0.0532316588626 , 0.244947737722 , 0.0197984684293 , 0.0309341209233 , - 0.23439631578 , 0.229825279875 , 0.0508520585381 , 0.160921316875 , 0.265078502128 , 0.121716560626 , - -0.315088694175 , 0.0747700471918 , -0.245836615071 , -0.327728781776 , 0.0857114674649 , -0.239431905957 , - -0.308385460634 , 0.145142997084 , -0.149886828433 , 0.0488236045164 , 0.309462801914 , 0.0849169148265 , - -0.0244964803395 , 0.33145611751 , -0.0476415818061 , 0.0060567994229 , 0.32418412014 , 0.0367779543812 , - -0.0950221448063 , 0.236675326003 , 0.0572594453983 , 0.248723023186 , 0.0886648784791 , -0.176629430538 , - 0.116796984 , 0.256596599567 , -0.292863523603 , 0.118024552914 , 0.229154257843 , -0.34233232501 , - 0.217507892549 , -0.0417822335742 , -0.176771782888 , -0.224429321304 , 0.0125595300114 , -0.362064725588 , - 0.0937301100955 , -0.0500824832657 , -0.299713548444 , -0.244162220397 , 0.0383853931293 , -0.389856984411 , - -0.0281989366102 , 0.097392811563 , -0.458244577284 , -0.385010847162 , 0.10122766194 , -0.140052859922 , - -0.377936358012 , 0.110875172128 , -0.176207095463 , 0.244483045556 , -0.0991073977045 , 0.0575134372934 , - 0.262605120167 , -0.100243191645 , -0.0495620806935 , 0.240306880972 , -0.136153701579 , -0.114745281696 , - 0.215763176129 , -0.0836766059189 , -0.183249640616 , 0.237870396603 , -0.132449578286 , -0.121598854639 , - -0.0637683083097 , -0.27921020214 , -0.149112321992 , -0.0856211014977 , -0.2973233473 , -0.0446878139589 , - 0.104675342288 , -0.0625908305324 , -0.290346256534 , 0.0248264249186 , -0.247797708548 , -0.165830884019 , - 0.0719302438309 , -0.178468260473 , -0.211432157345 , 0.142871843159 , -0.208769948542 , 0.0454101128246 , - 0.167803379307 , -0.207851396623 , -0.088802726124 , 0.12868717152 , -0.230920439715 , 0.00760508389036 , - -0.0372812069535 , -0.286740286332 , 0.00963701291166 ] - - connN = [ #polyhedron 0 - 0 , 1 , 3 , 4 , 2 , -1 , 1 , 5 , 6 , 7 , 0 , -1 , 0 , 7 , 8 , 10 , 11 , 9 , 2 , -1 , 1 , 5 , 12 , 14 , 15 , 13 , 3 , -1 , 16 , 9 , 2 , 4 , 17 , -1 - , 4 , 3 , 13 , 18 , 17 , -1 , 5 , 6 , 19 , 21 , 20 , 12 , -1 , 6 , 7 , 8 , 23 , 22 , 19 , -1 , 23 , 24 , 10 , 8 , -1 , 25 , 11 , 9 , 16 , -1 - , 24 , 26 , 25 , 11 , 10 , -1 , 12 , 14 , 20 , -1 , 27 , 28 , 29 , 15 , 13 , 18 , -1 , 14 , 15 , 29 , 30 , 21 , 20 , -1 , 26 , 27 , 18 , 17 , 16 , 25 , -1 - , 22 , 19 , 21 , 30 , 31 , -1 , 22 , 31 , 28 , 27 , 26 , 24 , 23 , -1 , 31 , 30 , 29 , 28, - # polyhedron 1 - 0 , 7 , 8 , 10 , 11 , 9 , 2 , -1 , 32 , 0 , 7 , 35 , 34 , 33 , -1 , 32 , 0 , 2 , 37 , 36 , -1 , 35 , 7 , 8 , 40 , 39 , 38 , -1 - , 2 , 37 , 41 , 9 , -1 , 40 , 8 , 10 , 44 , 43 , 42 , -1 , 41 , 9 , 11 , 44 , 43 , -1 , 44 , 11 , 10 , -1 , 32 , 33 , 45 , 47 , 46 , 36 , -1 - , 33 , 34 , 48 , 45 , -1 , 35 , 34 , 48 , 50 , 49 , 38 , -1 , 41 , 43 , 42 , 46 , 36 , 37 , -1 , 38 , 39 , 51 , 49 , -1 - , 39 , 40 , 42 , 46 , 47 , 52 , 51 , -1 , 45 , 47 , 52 , 50 , 48 , -1 , 52 , 51 , 49 , 50, - # polyhedron 2 - 6 , 7 , 8 , 23 , 22 , 19 , -1 , 6 , 35 , 7 , -1 , 6 , 35 , 38 , 19 , -1 , 35 , 7 , 8 , 40 , 39 , 38 , -1 , 53 , 22 , 19 , 38 , 39 , 54 , -1 - , 23 , 53 , 54 , 40 , 8 , -1 , 53 , 22 , 23 , -1 , 39 , 54 , 40, - # polyhedron 3 - 35 , 34 , 48 , 50 , 49 , 38 , -1 , 6 , 35 , 34 , 56 , 55 , 5 , -1 , 6 , 35 , 38 , 19 , -1 , 34 , 56 , 57 , 59 , 58 , 48 , -1 - , 60 , 61 , 21 , 19 , 38 , 49 , -1 , 62 , 50 , 48 , 58 , -1 , 60 , 63 , 64 , 62 , 50 , 49 , -1 , 5 , 6 , 19 , 21 , 20 , 12 , -1 - , 55 , 5 , 12 , 65 , -1 , 66 , 67 , 65 , 55 , 56 , 57 , -1 , 63 , 66 , 57 , 59 , 64 , -1 , 64 , 62 , 58 , 59 , -1 - , 60 , 63 , 66 , 67 , 68 , 61 , -1 , 61 , 68 , 20 , 21 , -1 , 67 , 68 , 20 , 12 , 65] - - barys = [ -0.0165220465527 , -0.0190922868195 , 0.158882733414 , - 0.0287618656076 , 0.135874379934 , -0.14601588119 , - -0.147128055553 , 0.0465995097041 , -0.049391174453 , - -0.00142506732317 , -0.0996953090351 , -0.115159183132 ] - meshN=MEDCouplingUMesh.New(); - meshN.setName("ForBary"); - meshN.setMeshDimension(3); - meshN.allocateCells(4); - meshN.insertNextCell(NORM_POLYHED,113,connN); - meshN.insertNextCell(NORM_POLYHED,99,connN[113:]); - meshN.insertNextCell(NORM_POLYHED,43,connN[212:]); - meshN.insertNextCell(NORM_POLYHED,92,connN[255:]); - meshN.finishInsertingCells(); - myCoords=DataArrayDouble.New(); - myCoords.setValues(coords,69,3); - meshN.setCoords(myCoords); - meshN.checkCoherency(); - res1=meshN.arePolyhedronsNotCorrectlyOriented(); - meshN.orientCorrectlyPolyhedrons(); - res1=meshN.arePolyhedronsNotCorrectlyOriented(); - self.assertTrue(len(res1)==0); - # - da=meshN.getBarycenterAndOwner(); - self.assertEqual(4,da.getNumberOfTuples()); - self.assertEqual(3,da.getNumberOfComponents()); - daPtr=da.getValues(); - for i in xrange(12): - self.assertTrue(abs(barys[i]-daPtr[i])<1e-12); - pass - pass - - def testRenumberCellsForFields(self): - m=MEDCouplingDataForTest.build2DTargetMesh_1(); - f=MEDCouplingFieldDouble.New(ON_CELLS,NO_TIME); - f.setMesh(m); - arr=DataArrayDouble.New(); - nbOfCells=m.getNumberOfCells(); - values1=[7.,107.,10007.,8.,108.,10008.,9.,109.,10009.,10.,110.,10010.,11.,111.,10011.] - arr.setValues(values1,nbOfCells,3); - f.setArray(arr); - renumber1=[3,1,0,4,2] - loc=[-0.05,-0.05, 0.55,-0.25, 0.55,0.15, -0.05,0.45, 0.45,0.45] - for j in xrange(5): - res=f.getValueOn(loc[2*j:2*j+2]); - for i in xrange(3): - self.assertTrue(abs(values1[i+3*j]-res[i])<1e-12); - pass - pass - f.renumberCells(renumber1,False); - ptr=f.getArray().getValues(); - expected1=[9.,109.,10009.,8.,108.,10008.,11.,111.,10011.,7.,107.,10007.,10.,110.,10010.] - for i in xrange(15): - self.assertTrue(abs(expected1[i]-ptr[i])<1e-12); - pass - #check that fields remains the same geometrically - for j in xrange(5): - res=f.getValueOn(loc[2*j:2*(j+1)]); - for i in xrange(3): - self.assertTrue(abs(values1[i+3*j]-res[i])<1e-12); - pass - pass - #On gauss - f=MEDCouplingFieldDouble.New(ON_GAUSS_PT,NO_TIME); - f.setMesh(m); - _a=0.446948490915965; - _b=0.091576213509771; - _p1=0.11169079483905; - _p2=0.0549758718227661; - refCoo1=[ 0.,0., 1.,0., 0.,1. ] - gsCoo1=[ 2*_b-1, 1-4*_b, 2*_b-1, 2.07*_b-1, 1-4*_b, 2*_b-1, 1-4*_a, 2*_a-1, 2*_a-1, 1-4*_a, 2*_a-1, 2*_a-1 ]; - wg1=[ 4*_p2, 4*_p2, 4*_p2, 4*_p1, 4*_p1, 4*_p1 ] - _refCoo1=refCoo1[0:6]; - _gsCoo1=gsCoo1[0:12]; - _wg1=wg1[0:6]; - f.setGaussLocalizationOnType(NORM_TRI3,_refCoo1,_gsCoo1,_wg1); - refCoo2=[ 0.,0., 1.,0., 1.,1., 0.,1. ] - _refCoo2=refCoo2[0:8]; - _gsCoo1=_gsCoo1[0:4] - _wg1=_wg1[0:2] - f.setGaussLocalizationOnType(NORM_QUAD4,_refCoo2,_gsCoo1,_wg1); - arr=DataArrayDouble.New(); - values2=[1.,1001.,2.,1002., 11.,1011.,12.,1012.,13.,1013.,14.,1014.,15.,1015.,16.,1016., 21.,1021.,22.,1022.,23.,1023.,24.,1024.,25.,1025.,26.,1026., 31.,1031.,32.,1032., 41.,1041.,42.,1042.] - arr.setValues(values2,18,2); - f.setArray(arr); - f.checkCoherency(); - fCpy=f.clone(True); - self.assertTrue(f.isEqual(fCpy,1e-12,1e-12)); - f.renumberCells(renumber1,False); - self.assertTrue(not f.isEqual(fCpy,1e-12,1e-12)); - expected2=[21.,1021.,22.,1022.,23.,1023.,24.,1024.,25.,1025.,26.,1026., 11.,1011.,12.,1012.,13.,1013.,14.,1014.,15.,1015.,16.,1016., 41.,1041.,42.,1042., 1.,1001.,2.,1002., 31.,1031.,32.,1032.] - ptr=f.getArray().getValues(); - for i in xrange(36): - self.assertTrue(abs(expected2[i]-ptr[i])<1e-12); - pass - renumber2=[2,1,4,0,3] - f.renumberCells(renumber2,False); - self.assertTrue(f.isEqual(fCpy,1e-12,1e-12)); - #GaussNE - f=MEDCouplingFieldDouble.New(ON_GAUSS_NE,NO_TIME); - f.setMesh(m); - arr=DataArrayDouble.New(); - values3=[1.,1001.,2.,1002.,3.,1003.,4.,1004., 11.,1011.,12.,1012.,13.,1013., 21.,1021.,22.,1022.,23.,1023., 31.,1031.,32.,1032.,33.,1033.,34.,1034., 41.,1041.,42.,1042.,43.,1043.,44.,1044.] - arr.setValues(values3,18,2); - f.setArray(arr); - f.checkCoherency(); - fCpy=f.clone(True); - self.assertTrue(f.isEqual(fCpy,1e-12,1e-12)); - f.renumberCells(renumber1,False); - self.assertTrue(not f.isEqual(fCpy,1e-12,1e-12)); - expected3=[21.,1021.,22.,1022.,23.,1023.,11.,1011.,12.,1012.,13.,1013.,41.,1041.,42.,1042.,43.,1043.,44.,1044.,1.,1001.,2.,1002.,3.,1003.,4.,1004.,31.,1031.,32.,1032.,33.,1033.,34.,1034.] - ptr=f.getArray().getValues(); - for i in xrange(36): - self.assertTrue(abs(expected3[i]-ptr[i])<1e-12); - pass - f.renumberCells(renumber2,False);#perform reverse operation of renumbering to check that the resulting field is equal. - self.assertTrue(f.isEqual(fCpy,1e-12,1e-12)); - # - pass - - def testRenumberNodesForFields(self): - m=MEDCouplingDataForTest.build2DTargetMesh_1(); - f=MEDCouplingFieldDouble.New(ON_NODES,NO_TIME); - f.setMesh(m); - self.assertEqual(9,f.getNumberOfMeshPlacesExpected()); - arr=DataArrayDouble.New(); - nbOfNodes=m.getNumberOfNodes(); - values1=[7.,107.,10007.,8.,108.,10008.,9.,109.,10009.,10.,110.,10010.,11.,111.,10011.,12.,112.,10012.,13.,113.,10013.,14.,114.,10014.,15.,115.,10015.] - arr.setValues(values1,nbOfNodes,3); - f.setArray(arr); - f.checkCoherency(); - renumber1=[0,4,1,3,5,2,6,7,8] - loc=[0.5432,-0.2432, 0.5478,0.1528] - expected1=[9.0272, 109.0272, 10009.0272, 11.4124,111.4124,10011.4124] - for j in xrange(2): - res=f.getValueOn(loc[2*j:2*j+2]); - for i in xrange(3): - self.assertTrue(abs(expected1[i+3*j]-res[i])<1e-12); - pass - pass - fCpy=f.clone(True); - self.assertTrue(f.isEqual(fCpy,1e-12,1e-12)); - f.renumberNodes(renumber1); - self.assertTrue(not f.isEqual(fCpy,1e-12,1e-12)); - for j in xrange(2): - res=f.getValueOn(loc[2*j:2*j+2]); - for i in xrange(3): - self.assertTrue(abs(expected1[i+3*j]-res[i])<1e-12); - pass - pass - expected2=[7.,107.,10007.,9.,109.,10009.,12.,112.,10012.,10.,110.,10010.,8.,108.,10008.,11.,111.,10011.,13.,113.,10013.,14.,114.,10014.,15.,115.,10015.] - for i in xrange(27): - self.assertTrue(abs(expected2[i]-f.getArray().getValues()[i])<1e-12); - pass - renumber2=[0,2,5,3,1,4,6,7,8] - f.renumberNodes(renumber2); - self.assertTrue(f.isEqual(fCpy,1e-12,1e-12)); - pass - - def testConvertQuadraticCellsToLinear(self): - mesh=MEDCouplingDataForTest.build2DTargetMesh_3(); - mesh.checkCoherency(); - types=mesh.getAllGeoTypes(); - types.sort() - self.assertEqual(5,len(types)); - expected1=[NORM_POLYGON, NORM_TRI3, NORM_QUAD4, NORM_TRI6, NORM_QUAD8] - expected1.sort() - self.assertEqual(expected1,types); - self.assertTrue(mesh.isPresenceOfQuadratic()); - self.assertEqual(62,mesh.getMeshLength()); - f1=mesh.getMeasureField(False); - # - mesh.convertQuadraticCellsToLinear(); - self.assertTrue(not mesh.isPresenceOfQuadratic()); - # - mesh.checkCoherency(); - f2=mesh.getMeasureField(False); - self.assertTrue(f1.getArray().isEqual(f2.getArray(),1e-12)); - self.assertEqual(48,mesh.getMeshLength()); - types2=mesh.getAllGeoTypes(); - types2.sort() - self.assertEqual(3,len(types2)); - expected2=[NORM_POLYGON, NORM_TRI3, NORM_QUAD4] - expected2.sort() - self.assertEqual(expected2,types2); - pass - - def testCheckGeoEquivalWith(self): - mesh1=MEDCouplingDataForTest.build2DTargetMesh_3(); - mesh2=MEDCouplingDataForTest.build2DTargetMesh_3(); - #First test mesh1 - cellCor,nodeCor=mesh1.checkGeoEquivalWith(mesh1,0,1e-12);#deepEqual - self.assertTrue(cellCor==None); - self.assertTrue(nodeCor==None); - cellCor,nodeCor=mesh1.checkGeoEquivalWith(mesh1,1,1e-12);#fastEqual - self.assertTrue(cellCor==None); - self.assertTrue(nodeCor==None); - cellCor,nodeCor=mesh1.checkGeoEquivalWith(mesh1,10,1e-12);#deepEqual with geo permutations - self.assertTrue(cellCor==None); - self.assertTrue(nodeCor==None); - #Second test mesh1 and mesh2 are 2 different meshes instance - cellCor,nodeCor=mesh1.checkGeoEquivalWith(mesh2,0,1e-12);#deepEqual - self.assertTrue(cellCor==None); - self.assertTrue(nodeCor==None); - cellCor,nodeCor=mesh1.checkGeoEquivalWith(mesh2,1,1e-12);#fastEqual - self.assertTrue(cellCor==None); - self.assertTrue(nodeCor==None); - cellCor,nodeCor=mesh1.checkGeoEquivalWith(mesh2,10,1e-12);#deepEqual with geo permutations - self.assertTrue(cellCor==None); - self.assertTrue(nodeCor==None); - #Third test : cell permutation by keeping the first the middle and the last as it is. - renum=[0,2,1,3,4,5,6,8,7,9] - mesh2.renumberCells(renum,False); - self.assertRaises(InterpKernelException,mesh1.checkGeoEquivalWith,mesh2,0,1e-12);#deepEqual fails - self.assertTrue(cellCor==None); - self.assertTrue(nodeCor==None); - cellCor,nodeCor=mesh1.checkGeoEquivalWith(mesh2,1,1e-12);#fastEqual do not see anything - self.assertTrue(cellCor==None); - self.assertTrue(nodeCor==None); - cellCor,nodeCor=mesh1.checkGeoEquivalWith(mesh2,10,1e-12);#deepEqual with geo permutations - self.assertTrue(cellCor); - self.assertEqual(10,cellCor.getNumberOfTuples()); - self.assertEqual(1,cellCor.getNumberOfComponents()); - self.assertEqual(renum,list(cellCor.getValues())) - self.assertTrue(nodeCor==None); - cellCor=0; - self.assertTrue(nodeCor==None); - a,b=mesh1.checkDeepEquivalWith(mesh2,0,1e-12); - self.assertEqual(renum,list(a.getValues())) - self.assertTrue(b==None); - mesh2.setCoords(mesh1.getCoords()) - a=mesh1.checkDeepEquivalOnSameNodesWith(mesh2,0,1e-12); - self.assertEqual(renum,list(a.getValues())) - #4th test : cell and node permutation by keeping the first the middle and the last as it is. - mesh2=MEDCouplingDataForTest.build2DTargetMesh_3(); - renum2=[0,2,1,3,4,5,6,8,7,9,10] - mesh2.renumberCells(renum,False); - mesh2.renumberNodes(renum2,11); - cellCor=None - nodeCor=None - self.assertRaises(InterpKernelException,mesh1.checkGeoEquivalWith,mesh2,0,1e-12);#deepEqual fails - self.assertTrue(cellCor==None); - self.assertTrue(nodeCor==None); - cellCor,nodeCor=mesh1.checkGeoEquivalWith(mesh2,1,1e-12);#fastEqual do not see anything - self.assertTrue(cellCor==None); - self.assertTrue(nodeCor==None); - cellCor,nodeCor=mesh1.checkGeoEquivalWith(mesh2,10,1e-12);#deepEqual with geo permutations - self.assertTrue(cellCor); - self.assertEqual(10,cellCor.getNumberOfTuples()); - self.assertEqual(1,cellCor.getNumberOfComponents()); - self.assertEqual(renum,list(cellCor.getValues())) - self.assertTrue(nodeCor); - self.assertEqual(11,nodeCor.getNumberOfTuples()); - self.assertEqual(1,nodeCor.getNumberOfComponents()); - self.assertEqual(renum2,list(nodeCor.getValues())) - cellCor=0; - nodeCor=0; - #5th test : modification of the last cell to check fastCheck detection. - mesh2=MEDCouplingDataForTest.build2DTargetMesh_3(); - renum3=[0,2,1,3,4,5,6,8,9,7] - mesh2.renumberCells(renum3,False); - mesh2.renumberNodes(renum2,11); - cellCor=None - nodeCor=None - self.assertRaises(InterpKernelException,mesh1.checkGeoEquivalWith,mesh2,0,1e-12) - self.assertTrue(cellCor==None); - self.assertTrue(nodeCor==None); - self.assertRaises(InterpKernelException,mesh1.checkGeoEquivalWith,mesh2,1,1e-12) - self.assertTrue(cellCor==None); - self.assertTrue(nodeCor==None); - cellCor,nodeCor=mesh2.checkGeoEquivalWith(mesh1,10,1e-12);#deepEqual with geo permutations - self.assertTrue(cellCor!=None); - self.assertEqual(10,cellCor.getNumberOfTuples()); - self.assertEqual(1,cellCor.getNumberOfComponents()); - self.assertEqual(renum3,list(cellCor.getValues())) - self.assertTrue(nodeCor!=None); - self.assertEqual(11,nodeCor.getNumberOfTuples()); - self.assertEqual(1,nodeCor.getNumberOfComponents()); - self.assertEqual(renum2,list(nodeCor.getValues())); - pass - - def testCheckGeoEquivalWith2(self): - mesh1=MEDCouplingDataForTest.build2DTargetMesh_4(); - mesh2=MEDCouplingDataForTest.build2DTargetMesh_1(); - cellCor,nodeCor=mesh1.checkGeoEquivalWith(mesh2,10,1e-12); - self.assertEqual(None,cellCor); - self.assertNotEqual(None,nodeCor); - expected1=[0, 1, 3, 4, 5, 6, 7, 8, 9] - for i in xrange(9): - self.assertEqual(expected1[i],nodeCor.getIJ(i,0)); - pass - pass - - def testSwig2CheckDeepEquivalWith1(self): - eps = 1.0e-8 - mcart = MEDCouplingCMesh() - mcart.setCoordsAt(0, DataArrayDouble([0.0,1.5,2.0])) - mcart.setCoordsAt(1, DataArrayDouble([1.0,2.5,3.0,4.0])) - m = mcart.buildUnstructured() - m2 = m[1:m.getNumberOfCells()] - self.assertRaises(InterpKernelException, m.checkDeepEquivalWith, m2, 0, eps) - self.assertRaises(InterpKernelException, m.checkDeepEquivalWith, m2, 1, eps) - self.assertRaises(InterpKernelException, m.checkDeepEquivalWith, m2, 2, eps) - pass - - def testSwig2CheckDeepEquivalWith2(self): - eps = 1.0e-8 - m = MEDCouplingUMesh("tst", 2) - m.setCoords(DataArrayDouble([], 0,2)) - m.setConnectivity(DataArrayInt([]), DataArrayInt([0])) - m2 = m.deepCpy() - m.checkDeepEquivalWith(m2, 0, eps) # Should not raise! - pass - - def testCopyTinyStringsFromOnFields(self): - m=MEDCouplingDataForTest.build3DSurfTargetMesh_1(); - nbOfCells=m.getNumberOfCells(); - f=MEDCouplingFieldDouble.New(ON_CELLS,LINEAR_TIME); - f.setMesh(m); - self.assertEqual(5,f.getNumberOfMeshPlacesExpected()); - f.setName("a"); - f.setDescription("b"); - a1=DataArrayDouble.New(); - a1.alloc(nbOfCells,2); - a1.fillWithZero(); - a1.setInfoOnComponent(0,"c"); - a1.setInfoOnComponent(1,"d"); - a2=a1.deepCpy(); - a2.setInfoOnComponent(0,"e"); - a2.setInfoOnComponent(1,"f"); - f.setArray(a1); - f.setEndArray(a2); - f.setEndTime(3.,3,4); - m.setName("g"); - m.getCoords().setInfoOnComponent(0,"h"); - m.getCoords().setInfoOnComponent(1,"i"); - m.getCoords().setInfoOnComponent(2,"j"); - # - f.checkCoherency(); - f2=f.clone(True); - self.assertTrue(f2.isEqual(f,1e-12,1e-12)); - f2.setName("smth"); - self.assertTrue(not f2.isEqual(f,1e-12,1e-12)); - f2.copyTinyStringsFrom(f); - self.assertTrue(f2.isEqual(f,1e-12,1e-12)); - f2.setDescription("GGG"); - self.assertTrue(not f2.isEqual(f,1e-12,1e-12)); - f2.copyTinyStringsFrom(f); - self.assertTrue(f2.isEqual(f,1e-12,1e-12)); - f2.getArray().setInfoOnComponent(0,"mmmm"); - self.assertTrue(not f2.isEqual(f,1e-12,1e-12)); - f2.copyTinyStringsFrom(f); - self.assertTrue(f2.isEqual(f,1e-12,1e-12)); - f2.getEndArray().setInfoOnComponent(1,"mmmm"); - self.assertTrue(not f2.isEqual(f,1e-12,1e-12)); - f2.copyTinyStringsFrom(f); - self.assertTrue(f2.isEqual(f,1e-12,1e-12)); - m2=m.clone(True); - self.assertTrue(m2.isEqual(m,1e-12)); - m2.setName("123"); - self.assertTrue(not m2.isEqual(m,1e-12)); - m2.copyTinyStringsFrom(m); - self.assertTrue(m2.isEqual(m,1e-12)); - m2.getCoords().setInfoOnComponent(1,"eee"); - self.assertTrue(not m2.isEqual(m,1e-12)); - m2.copyTinyStringsFrom(m); - self.assertTrue(m2.isEqual(m,1e-12)); - pass - - def testTryToShareSameCoordsPermute(self): - m=MEDCouplingDataForTest.build3DSurfTargetMesh_1(); - m2=MEDCouplingDataForTest.build3DSurfTargetMesh_1(); - #self.assertTrue(m.getCoords()!=m2.getCoords()); - m.tryToShareSameCoordsPermute(m2,1e-12); - #self.assertTrue(m.getCoords()==m2.getCoords()); - self.assertTrue(m2.isEqual(m,1e-12)); - renum1=[1,2,0,5,8,7,4,3,6] - r1=DataArrayInt.New() - r1.setValues(renum1,len(renum1),1) - m.renumberNodes(r1,9); - #self.assertTrue(m.getCoords()!=m2.getCoords()); - self.assertTrue(not m2.isEqual(m,1e-12)); - m.tryToShareSameCoordsPermute(m2,1e-12); - #self.assertTrue(m.getCoords()==m2.getCoords()); - self.assertTrue(m2.isEqual(m,1e-12)); - pass - - def testTryToShareSameCoordsPermute2(self): - m1=MEDCouplingDataForTest.build2DTargetMesh_4(); - targetCoords=[-0.3,-0.3, 0.2,-0.3, -0.3,0.2, 0.2,0.2 ] - targetConn=[0,2,3,1] - m2=MEDCouplingUMesh.New(); - m2.setMeshDimension(2); - m2.allocateCells(1); - m2.insertNextCell(NORM_QUAD4,targetConn[0:4]) - m2.finishInsertingCells(); - myCoords=DataArrayDouble.New(); - myCoords.setValues(targetCoords,4,2); - m2.setCoords(myCoords); - m2.checkCoherency(); - m1.checkCoherency(); - # - expected1=[0.25,0.125,0.125,0.25,0.25] - f1=m1.getMeasureField(False); - f2=m2.getMeasureField(False); - self.assertEqual(5,f1.getArray().getNumberOfTuples()); - self.assertEqual(1,f2.getArray().getNumberOfTuples()); - for i in xrange(5): - self.assertAlmostEqual(expected1[i],f1.getIJ(i,0),12); - pass - self.assertAlmostEqual(expected1[0],f2.getIJ(0,0),12); - self.assertRaises(InterpKernelException,m1.tryToShareSameCoordsPermute,m2,1e-12);# <- here in this order the sharing is impossible. - # Let's go for deeper test of tryToShareSameCoordsPermute - m2.tryToShareSameCoordsPermute(m1,1e-12); - f1=m1.getMeasureField(False); - f2=m2.getMeasureField(False); - self.assertEqual(5,f1.getArray().getNumberOfTuples()); - self.assertEqual(1,f2.getArray().getNumberOfTuples()); - for i in xrange(5): - self.assertAlmostEqual(expected1[i],f1.getIJ(i,0),12); - pass - self.assertAlmostEqual(expected1[0],f2.getIJ(0,0),12); - pass - - def testChangeUnderlyingMesh1(self): - mesh1=MEDCouplingDataForTest.build2DTargetMesh_3(); - mesh2=MEDCouplingDataForTest.build2DTargetMesh_3(); - f1=MEDCouplingFieldDouble.New(ON_CELLS,NO_TIME); - f1.setMesh(mesh1); - array=DataArrayDouble.New(); - arr=[7., 107., 8., 108., 9., 109., 10., 110., 11., 111., 12., 112., 13., 113., 14., 114., 15., 115., 16., 116.] - array.setValues(arr,mesh1.getNumberOfCells(),2); - f1.setArray(array); - # - renum=[0,2,1,3,4,5,6,8,7,9] - mesh2.renumberCells(renum,False); - #self.assertTrue(f1.getMesh()==mesh1); - f1.changeUnderlyingMesh(mesh1,10,1e-12);# nothing done only to check that nothing done. - #self.assertTrue(f1.getMesh()==mesh1); - f1.changeUnderlyingMesh(mesh2,10,1e-12); - #self.assertTrue(f1.getMesh()==mesh2); - expected1=[7.,107.,9.,109.,8.,108.,10.,110.,11.,111.,12.,112.,13.,113.,15.,115.,14.,114.,16.,116.] - for i in xrange(20): - self.assertAlmostEqual(expected1[i],f1.getArray().getIJ(0,i),12); - pass - # - f1=MEDCouplingFieldDouble.New(ON_NODES,NO_TIME); - f1.setMesh(mesh1); - array=DataArrayDouble.New(); - arr2=[7.,107.,8.,108.,9.,109.,10.,110.,11.,111.,12.,112.,13.,113.,14.,114.,15.,115.,16.,116.,17.,117.] - array.setValues(arr2,mesh1.getNumberOfNodes(),2); - f1.setArray(array); - # - renum2=[0,2,10,3,4,5,6,8,7,9,1] - mesh2.renumberNodes(renum2,11); - #self.assertTrue(f1.getMesh()==mesh1); - f1.changeUnderlyingMesh(mesh2,10,1e-12); - #self.assertTrue(f1.getMesh()==mesh2); - expected2=[7.,107.,17.,117.,8.,108.,10.,110.,11.,111.,12.,112.,13.,113.,15.,115.,14.,114.,16.,116.,9.,109.] - for i in xrange(22): - self.assertAlmostEqual(expected2[i],f1.getArray().getIJ(0,i),12); - pass - pass - - def testGetMaxValue1(self): - m=MEDCouplingDataForTest.build3DSurfTargetMesh_1(); - nbOfCells=m.getNumberOfCells(); - f=MEDCouplingFieldDouble.New(ON_CELLS,LINEAR_TIME); - f.setMesh(m); - a1=DataArrayDouble.New(); - val1=[3.,4.,5.,6.,7.] - a1.setValues(val1,nbOfCells,1); - a2=DataArrayDouble.New(); - val2=[0.,1.,2.,8.,7.] - a2.setValues(val2,nbOfCells,1); - f.setArray(a1); - f.setEndArray(a2); - f.setEndTime(3.,3,4); - f.checkCoherency(); - # - self.assertAlmostEqual(8.,f.getMaxValue(),14); - self.assertAlmostEqual(0.,f.getMinValue(),14); - self.assertAlmostEqual(5.,f.getAverageValue(),14); - self.assertAlmostEqual(5.125,f.getWeightedAverageValue(0,True),14); - a1.setIJ(0,2,9.5); - self.assertAlmostEqual(9.5,f.getMaxValue(),14); - self.assertAlmostEqual(0.,f.getMinValue(),14); - a2.setIJ(0,0,9.); - self.assertAlmostEqual(9.5,f.getMaxValue(),14); - self.assertAlmostEqual(1.,f.getMinValue(),14); - pass - - def testSubstractInPlaceDM1(self): - mesh1=MEDCouplingDataForTest.build2DTargetMesh_3(); - mesh2=MEDCouplingDataForTest.build2DTargetMesh_3(); - f1=MEDCouplingFieldDouble.New(ON_CELLS,NO_TIME); - f1.setMesh(mesh1); - array=DataArrayDouble.New(); - arr=[7.,107.,8.,108.,9.,109.,10.,110.,11.,111.,12.,112.,13.,113.,14.,114.,15.,115.,16.,116.] - array.setValues(arr,mesh1.getNumberOfCells(),2); - f1.setArray(array); - # - self.assertEqual(10,f1.getNumberOfTuples()); - self.assertEqual(2,f1.getNumberOfComponents()); - self.assertEqual(20,f1.getNumberOfValues()); - # - renum=[0,2,3,1,4,5,6,8,7,9] - mesh2.renumberCells(renum,False); - # - f2=MEDCouplingFieldDouble.New(ON_CELLS,NO_TIME); - f2.setMesh(mesh2); - array=DataArrayDouble.New(); - arr2=[7.1,107.1,10.1,110.1,8.1,108.1,9.1,109.1,11.1,111.1,12.1,112.1,13.1,113.1,15.1,115.1,14.1,114.1,16.1,116.1] - array.setValues(arr2,mesh2.getNumberOfCells(),2); - f2.setArray(array); - # - f1.substractInPlaceDM(f2,10,1e-12); - f1.applyFunc(1,"abs(x+y+0.2)"); - self.assertAlmostEqual(0.,f1.getMaxValue(),13); - pass - - def testDotCrossProduct1(self): - mesh1=MEDCouplingDataForTest.build2DTargetMesh_3(); - f1=MEDCouplingFieldDouble.New(ON_CELLS,ONE_TIME); - f1.setTime(2.3,5,6); - f1.setMesh(mesh1); - array=DataArrayDouble.New(); - arr1=[7.,107.,207.,8.,108.,208.,9.,109.,209.,10.,110.,210.,11.,111.,211.,12.,112.,212.,13.,113.,213.,14.,114.,214.,15.,115.,215.,16.,116.,216.] - array.setValues(arr1,mesh1.getNumberOfCells(),3); - f1.setArray(array); - f2=MEDCouplingFieldDouble.New(ON_CELLS,ONE_TIME); - f2.setTime(7.8,4,5); - f2.setMesh(mesh1); - array=DataArrayDouble.New(); - arr2=[1.,2.,3.,4.,5.,6.,7.,8.,9.,10.,11.,12.,13.,14.,15.,16.,17.,18.,19.,20.,21.,22.,23.,24.,25.,26.,27.,28.,29.,30.] - array.setValues(arr2,mesh1.getNumberOfCells(),3); - f2.setArray(array); - # - f3=f1.dot(f2); - expected1=[842.,1820.,2816.,3830.,4862.,5912.,6980.,8066.,9170.,10292.] - for i in xrange(10): - self.assertAlmostEqual(expected1[i],f3.getIJ(i,0),9); - pass - # - f4=f1.crossProduct(f2); - expected2=[-93., 186., -93., -392., 784., -392., -691., 1382., -691., -990., 1980., -990., -1289., 2578., -1289., -1588., 3176., -1588., -1887., 3774., -1887., -2186., 4372., -2186., -2485., 4970., -2485., -2784., 5568., -2784.] - for i in xrange(30): - self.assertAlmostEqual(expected2[i],f4.getIJ(0,i),9); - pass - pass - - def testMinMaxFields1(self): - mesh1=MEDCouplingDataForTest.build2DTargetMesh_3(); - f1=MEDCouplingFieldDouble.New(ON_CELLS,ONE_TIME); - f1.setTime(2.3,5,6); - f1.setMesh(mesh1); - array=DataArrayDouble.New(); - arr1=[7.,107.,207.,8.,108.,208.,9.,109.,209.,10.,110.,210.,11.,111.,211.,12.,112.,212.,13.,113.,213.,14.,114.,214.,15.,115.,215.,16.,116.,216.] - array.setValues(arr1,mesh1.getNumberOfCells(),3); - f1.setArray(array); - f2=MEDCouplingFieldDouble.New(ON_CELLS,ONE_TIME); - f2.setTime(7.8,4,5); - f2.setMesh(mesh1); - array=DataArrayDouble.New(); - arr2=[6.,108.,206.,9.,107.,209.,8.,110.,208.,11.,109.,211.,10.,112.,210.,13.,111.,213.,12.,114.,212.,15.,113.,215.,14.,116.,214.,17.,115.,217.] - array.setValues(arr2,mesh1.getNumberOfCells(),3); - f2.setArray(array); - # - f3=f1.max(f2); - expected1=[7.,108.,207.,9.,108.,209.,9.,110.,209.,11.,110.,211.,11.,112.,211.,13.,112.,213.,13.,114.,213.,15.,114.,215.,15.,116.,215.,17.,116.,217.] - for i in xrange(30): - self.assertAlmostEqual(expected1[i],f3.getIJ(0,i),9); - pass - # - f4=f1.min(f2); - expected2=[6.,107.,206.,8.,107.,208.,8.,109.,208.,10.,109.,210.,10.,111.,210.,12.,111.,212.,12.,113.,212.,14.,113.,214.,14.,115.,214.,16.,115.,216.] - for i in xrange(30): - self.assertAlmostEqual(expected2[i],f4.getIJ(0,i),9); - pass - # - pass - - def testApplyLin1(self): - mesh1=MEDCouplingDataForTest.build2DTargetMesh_3(); - f1=MEDCouplingFieldDouble.New(ON_CELLS,LINEAR_TIME); - f1.setMesh(mesh1); - array=DataArrayDouble.New(); - arr=[7.,107.,8.,108.,9.,109.,10.,110.,11.,111.,12.,112.,13.,113.,14.,114.,15.,115.,16.,116.] - array.setValues(arr,mesh1.getNumberOfCells(),2); - f1.setArray(array); - # - f1.applyLin(2.,3.,0); - expected1=[17.,107.,19.,108.,21.,109.,23.,110.,25.,111.,27.,112.,29.,113.,31.,114.,33.,115.,35.,116.] - for i in xrange(20): - self.assertAlmostEqual(expected1[i],f1.getIJ(0,i),9); - pass - # - arr2=[2.,102.,3.,103.,4.,104.,5.,105.,6.,106.,7.,107.,8.,108.,9.,109.,10.,110.,11.,111.] - array=DataArrayDouble.New(); - array.setValues(arr2,mesh1.getNumberOfCells(),2); - f1.setEndArray(array); - # - f1.applyLin(4.,5.,1); - # - expected2=[17.,433.,19.,437.,21.,441.,23.,445.,25.,449.,27.,453.,29.,457.,31.,461.,33.,465.,35.,469.] - for i in xrange(20): - self.assertAlmostEqual(expected2[i],f1.getIJ(0,i),9); - pass - expected3=[2.,413.,3.,417.,4.,421.,5.,425.,6.,429.,7.,433.,8.,437.,9.,441.,10.,445.,11.,449.] - for i in xrange(20): - self.assertAlmostEqual(expected3[i],f1.getEndArray().getIJ(0,i),9); - pass - # - pass - - def testGetIdsInRange1(self): - mesh1=MEDCouplingDataForTest.build2DTargetMesh_3(); - f1=MEDCouplingFieldDouble.New(ON_CELLS,ONE_TIME); - f1.setTime(2.3,5,6); - f1.setMesh(mesh1); - array=DataArrayDouble.New(); - arr1=[2.,8.,6.,5.,11.,7.,9.,3.,10.,4.] - array.setValues(arr1,mesh1.getNumberOfCells(),1); - f1.setArray(array); - # - f1.checkCoherency(); - da=f1.getIdsInRange(2.9,7.1); - self.failUnlessEqual(5,da.getNbOfElems()); - expected1=[2,3,5,7,9] - self.failUnlessEqual(expected1,list(da.getValues())); - da=f1.getIdsInRange(8.,12.); - self.failUnlessEqual(4,da.getNbOfElems()); - expected2=[1,4,6,8] - self.failUnlessEqual(expected2,list(da.getValues())); - # - pass - - def testBuildSubPart1(self): - mesh1=MEDCouplingDataForTest.build2DTargetMesh_1(); - f1=MEDCouplingFieldDouble.New(ON_CELLS,ONE_TIME); - f1.setTime(2.3,5,6); - f1.setMesh(mesh1); - array=DataArrayDouble.New(); - arr1=[3.,103.,4.,104.,5.,105.,6.,106.,7.,107.] - array.setValues(arr1,mesh1.getNumberOfCells(),2); - f1.setArray(array); - # - part1=[2,1,4] - f2=f1[part1]; - f2.zipCoords() - self.failUnlessEqual(3,f2.getNumberOfTuples()); - self.failUnlessEqual(2,f2.getNumberOfComponents()); - expected1=[5.,105.,4.,104.,7.,107.] - for i in xrange(6): - self.assertAlmostEqual(f2.getIJ(0,i),expected1[i],12); - pass - self.failUnlessEqual(3,f2.getMesh().getNumberOfCells()); - self.failUnlessEqual(6,f2.getMesh().getNumberOfNodes()); - self.failUnlessEqual(2,f2.getMesh().getSpaceDimension()); - self.failUnlessEqual(2,f2.getMesh().getMeshDimension()); - m2C=f2.getMesh(); - self.failUnlessEqual(13,m2C.getMeshLength()); - expected2=[0.2, -0.3, 0.7, -0.3, 0.2, 0.2, 0.7, 0.2, 0.2, 0.7, 0.7, 0.7] - for i in xrange(12): - self.assertAlmostEqual(expected2[i],m2C.getCoords().getIJ(0,i),12); - pass - expected3=[3,2,3,1,3,0,2,1,4,4,5,3,2] - self.failUnlessEqual(expected3,list(m2C.getNodalConnectivity().getValues())); - expected4=[0,4,8,13] - self.failUnlessEqual(expected4,list(m2C.getNodalConnectivityIndex().getValues())); - # Test with field on nodes. - f1=MEDCouplingFieldDouble.New(ON_NODES,ONE_TIME); - f1.setTime(2.3,5,6); - f1.setMesh(mesh1); - array=DataArrayDouble.New(); - arr2=[3.,103.,4.,104.,5.,105.,6.,106.,7.,107.,8.,108.,9.,109.,10.,110.,11.,111.] - array.setValues(arr2,mesh1.getNumberOfNodes(),2); - f1.setArray(array); - part2=[1,2] - f2=f1.buildSubPart(part2); - self.failUnlessEqual(4,f2.getNumberOfTuples()); - self.failUnlessEqual(2,f2.getNumberOfComponents()); - expected5=[4.,104.,5.,105.,7.,107.,8.,108.] - for i in xrange(8): - self.assertAlmostEqual(f2.getIJ(0,i),expected5[i],12); - pass - self.failUnlessEqual(2,f2.getMesh().getNumberOfCells()); - self.failUnlessEqual(4,f2.getMesh().getNumberOfNodes()); - self.failUnlessEqual(2,f2.getMesh().getSpaceDimension()); - self.failUnlessEqual(2,f2.getMesh().getMeshDimension()); - m2C=f2.getMesh(); - self.failUnlessEqual(8,m2C.getMeshLength()); - for i in xrange(8):#8 is not an error - self.assertAlmostEqual(expected2[i],m2C.getCoords().getIJ(0,i),12); - pass - self.failUnlessEqual(expected3[:4],list(m2C.getNodalConnectivity().getValues())[4:]); - self.failUnlessEqual(expected3[4:8],list(m2C.getNodalConnectivity().getValues())[:4]); - self.failUnlessEqual(expected4[:3],list(m2C.getNodalConnectivityIndex().getValues())); - #idem previous because nodes of cell#4 are not fully present in part3 - part3=[1,2] - arrr=DataArrayInt.New(); - arrr.setValues(part3,2,1); - f2=f1.buildSubPart(arrr); - self.failUnlessEqual(4,f2.getNumberOfTuples()); - self.failUnlessEqual(2,f2.getNumberOfComponents()); - for i in xrange(8): - self.assertAlmostEqual(f2.getIJ(0,i),expected5[i],12); - pass - self.failUnlessEqual(2,f2.getMesh().getNumberOfCells()); - self.failUnlessEqual(4,f2.getMesh().getNumberOfNodes()); - self.failUnlessEqual(2,f2.getMesh().getSpaceDimension()); - self.failUnlessEqual(2,f2.getMesh().getMeshDimension()); - m2C=f2.getMesh(); - self.failUnlessEqual(8,m2C.getMeshLength()); - for i in xrange(8):#8 is not an error - self.assertAlmostEqual(expected2[i],m2C.getCoords().getIJ(0,i),12); - pass - self.failUnlessEqual(expected3[:4],list(m2C.getNodalConnectivity().getValues())[4:8]); - self.failUnlessEqual(expected3[4:8],list(m2C.getNodalConnectivity().getValues())[:4]); - self.failUnlessEqual(expected4[:3],list(m2C.getNodalConnectivityIndex().getValues())); - # - part4=[1,2,4] - f2=f1.buildSubPart(part4); - self.failUnlessEqual(6,f2.getNumberOfTuples()); - self.failUnlessEqual(2,f2.getNumberOfComponents()); - expected6=[4.,104.,5.,105.,7.,107.,8.,108.,10.,110.,11.,111.] - for i in xrange(12): - self.assertAlmostEqual(f2.getIJ(0,i),expected6[i],12); - pass - self.failUnlessEqual(3,f2.getMesh().getNumberOfCells()); - self.failUnlessEqual(6,f2.getMesh().getNumberOfNodes()); - self.failUnlessEqual(2,f2.getMesh().getSpaceDimension()); - self.failUnlessEqual(2,f2.getMesh().getMeshDimension()); - m2C=f2.getMesh(); - self.failUnlessEqual(13,m2C.getMeshLength()); - for i in xrange(12): - self.assertAlmostEqual(expected2[i],m2C.getCoords().getIJ(0,i),12); - pass - self.failUnlessEqual(expected3[0:4],list(m2C.getNodalConnectivity().getValues())[4:8]); - self.failUnlessEqual(expected3[4:8],list(m2C.getNodalConnectivity().getValues())[0:4]); - self.failUnlessEqual(expected3[8:13],list(m2C.getNodalConnectivity().getValues())[8:13]); - self.failUnlessEqual(expected4,list(m2C.getNodalConnectivityIndex().getValues())); - pass - - def testDoublyContractedProduct1(self): - mesh1=MEDCouplingDataForTest.build2DTargetMesh_1(); - f1=MEDCouplingFieldDouble.New(ON_CELLS,NO_TIME); - f1.setMesh(mesh1); - array=DataArrayDouble.New(); - arr1=[7.8,8.9,9.1,10.2,23.4,34.5, 7.8,8.9,9.1,10.2,23.4,34.5, 7.8,8.9,9.1,10.2,23.4,34.5, 7.8,8.9,9.1,10.2,23.4,34.5, 7.8,8.9,9.1,10.2,23.4,34.5] - array.setValues(arr1,mesh1.getNumberOfCells(),6); - f1.setArray(array); - f1.checkCoherency(); - # - f2=f1.doublyContractedProduct(); - f2.checkCoherency(); - self.assertEqual(1,f2.getNumberOfComponents()); - self.assertEqual(5,f2.getNumberOfTuples()); - for i in xrange(5): - self.assertAlmostEqual(3906.56,f2.getIJ(i,0),9); - pass - # - pass - - def testDeterminant1(self): - mesh1=MEDCouplingDataForTest.build2DTargetMesh_1(); - f1=MEDCouplingFieldDouble.New(ON_CELLS,CONST_ON_TIME_INTERVAL); - f1.setTime(2.3,5,6); - f1.setEndTime(3.8,7,3); - f1.setMesh(mesh1); - array=DataArrayDouble.New(); - arr1=[1.2,2.3,3.4,4.5, 1.2,2.3,3.4,4.5, 1.2,2.3,3.4,4.5, 1.2,2.3,3.4,4.5, 1.2,2.3,3.4,4.5] - array.setValues(arr1,mesh1.getNumberOfCells(),4); - f1.setArray(array); - #4 components - f1.checkCoherency(); - f2=f1.determinant(); - f2.checkCoherency(); - self.assertEqual(CONST_ON_TIME_INTERVAL,f2.getTimeDiscretization()); - self.assertEqual(1,f2.getNumberOfComponents()); - self.assertEqual(5,f2.getNumberOfValues()); - for i in xrange(5): - self.assertAlmostEqual(-2.42,f2.getIJ(i,0),13); - pass - #6 components multi arrays with end array not defined - f1=MEDCouplingFieldDouble.New(ON_NODES,LINEAR_TIME); - f1.setTime(2.3,5,6); - f1.setEndTime(3.8,7,3); - f1.setMesh(mesh1); - array=DataArrayDouble.New(); - arr2=[1.2,2.3,3.4,4.5,5.6,6.7, 1.2,2.3,3.4,4.5,5.6,6.7, 1.2,2.3,3.4,4.5,5.6,6.7, 1.2,2.3,3.4,4.5,5.6,6.7, 1.2,2.3,3.4,4.5,5.6,6.7, - 1.2,2.3,3.4,4.5,5.6,6.7, 1.2,2.3,3.4,4.5,5.6,6.7, 1.2,2.3,3.4,4.5,5.6,6.7, 1.2,2.3,3.4,4.5,5.6,6.7] - array.setValues(arr2,mesh1.getNumberOfNodes(),6); - f1.setArray(array); - self.assertRaises(InterpKernelException,f1.checkCoherency);#no end array specified ! - # - f2=f1.determinant(); - self.assertEqual(LINEAR_TIME,f2.getTimeDiscretization()); - self.assertEqual(1,f2.getArray().getNumberOfComponents()); - self.assertEqual(9,f2.getNumberOfTuples()); - for i in xrange(9): - self.assertAlmostEqual(137.335,f2.getIJ(i,0),10); - pass - #6 components multi arrays with end array defined - array=DataArrayDouble.New(); - arr3=[7.8,8.9,9.1,10.2,23.4,34.5, 7.8,8.9,9.1,10.2,23.4,34.5, 7.8,8.9,9.1,10.2,23.4,34.5, 7.8,8.9,9.1,10.2,23.4,34.5, 7.8,8.9,9.1,10.2,23.4,34.5, - 7.8,8.9,9.1,10.2,23.4,34.5, 7.8,8.9,9.1,10.2,23.4,34.5, 7.8,8.9,9.1,10.2,23.4,34.5, 7.8,8.9,9.1,10.2,23.4,34.5] - array.setValues(arr3,mesh1.getNumberOfNodes(),6); - f1.setEndArray(array); - f1.checkCoherency(); - f2=f1.determinant(); - f2.checkCoherency(); - self.assertEqual(LINEAR_TIME,f2.getTimeDiscretization()); - self.assertEqual(1,f2.getNumberOfComponents()); - self.assertEqual(9,f2.getNumberOfTuples()); - time2,it,order=f2.getTime() - self.assertAlmostEqual(2.3,time2,12); - self.assertEqual(5,it); - self.assertEqual(6,order); - time2,it,order=f2.getEndTime() - self.assertAlmostEqual(3.8,time2,12); - self.assertEqual(7,it); - self.assertEqual(3,order); - for i in xrange(9): - self.assertAlmostEqual(137.335,f2.getIJ(i,0),10); - self.assertAlmostEqual(1289.685,f2.getEndArray().getIJ(i,0),9); - pass - #9 components - f1=MEDCouplingFieldDouble.New(ON_CELLS,ONE_TIME); - f1.setTime(7.8,10,2); - f1.setMesh(mesh1); - array=DataArrayDouble.New(); - arr4=[1.2,2.3,3.4,4.5,5.6,6.7,7.8,8.9,9.1, 1.2,2.3,3.4,4.5,5.6,6.7,7.8,8.9,9.1, 1.2,2.3,3.4,4.5,5.6,6.7,7.8,8.9,9.1, 1.2,2.3,3.4,4.5,5.6,6.7,7.8,8.9,9.1, 1.2,2.3,3.4,4.5,5.6,6.7,7.8,8.9,9.1] - array.setValues(arr4,mesh1.getNumberOfCells(),9); - f1.setArray(array); - # - f1.checkCoherency(); - f2=f1.determinant(); - f2.checkCoherency(); - self.assertEqual(ONE_TIME,f2.getTimeDiscretization()); - self.assertEqual(1,f2.getNumberOfComponents()); - self.assertEqual(5,f2.getNumberOfTuples()); - time2,it,order=f2.getTime() - self.assertAlmostEqual(7.8,time2,12); - self.assertEqual(10,it); - self.assertEqual(2,order); - for i in xrange(5): - self.assertAlmostEqual(3.267,f2.getIJ(i,0),13); - pass - pass - - def testEigenValues1(self): - mesh1=MEDCouplingDataForTest.build2DTargetMesh_1(); - f1=MEDCouplingFieldDouble.New(ON_CELLS,NO_TIME); - f1.setMesh(mesh1); - array=DataArrayDouble.New(); - arr1=[1.2,2.3,3.4,4.5,5.6,6.7, 1.2,2.3,3.4,4.5,5.6,6.7, 1.2,2.3,3.4,4.5,5.6,6.7, 1.2,2.3,3.4,4.5,5.6,6.7, 1.2,2.3,3.4,4.5,5.6,6.7] - array.setValues(arr1,mesh1.getNumberOfCells(),6); - f1.setArray(array); - f1.checkCoherency(); - # - f2=f1.eigenValues(); - f2.checkCoherency(); - self.assertEqual(3,f2.getNumberOfComponents()); - self.assertEqual(5,f2.getNumberOfTuples()); - expected1=[13.638813677891717,-4.502313844635971,-2.2364998332557486] - for i in xrange(5): - self.assertAlmostEqual(expected1[0],f2.getIJ(i,0),13); - self.assertAlmostEqual(expected1[1],f2.getIJ(i,1),13); - self.assertAlmostEqual(expected1[2],f2.getIJ(i,2),13); - pass - pass - - def testEigenVectors1(self): - mesh1=MEDCouplingDataForTest.build2DTargetMesh_1(); - f1=MEDCouplingFieldDouble.New(ON_CELLS,NO_TIME); - f1.setMesh(mesh1); - array=DataArrayDouble.New(); - arr1=[1.2,2.3,3.4,4.5,5.6,6.7, 1.2,2.3,3.4,4.5,5.6,6.7, 1.2,2.3,3.4,4.5,5.6,6.7, 1.2,2.3,3.4,4.5,5.6,6.7, 1.2,2.3,3.4,4.5,5.6,6.7] - array.setValues(arr1,mesh1.getNumberOfCells(),6); - f1.setArray(array); - f1.checkCoherency(); - # - f2=f1.eigenVectors(); - f2.checkCoherency(); - self.assertEqual(9,f2.getNumberOfComponents()); - self.assertEqual(5,f2.getNumberOfTuples()); - expected1=[0.5424262364180696, 0.5351201064614425, 0.6476266283176001,#eigenvect 0 - 0.7381111277307373, 0.06458838384003074, -0.6715804522117897,#eigenvect 1 - -0.4012053603397987, 0.8423032781211455, -0.3599436712889738#eigenvect 2 - ] - for i in xrange(5): - self.assertAlmostEqual(expected1[0],f2.getIJ(i,0),13); - self.assertAlmostEqual(expected1[1],f2.getIJ(i,1),13); - self.assertAlmostEqual(expected1[2],f2.getIJ(i,2),13); - self.assertAlmostEqual(expected1[3],f2.getIJ(i,3),13); - self.assertAlmostEqual(expected1[4],f2.getIJ(i,4),13); - self.assertAlmostEqual(expected1[5],f2.getIJ(i,5),13); - self.assertAlmostEqual(expected1[6],f2.getIJ(i,6),13); - self.assertAlmostEqual(expected1[7],f2.getIJ(i,7),13); - self.assertAlmostEqual(expected1[8],f2.getIJ(i,8),13); - pass - # - pass - - def testInverse1(self): - mesh1=MEDCouplingDataForTest.build2DTargetMesh_1(); - f1=MEDCouplingFieldDouble.New(ON_CELLS,NO_TIME); - f1.setMesh(mesh1); - array=DataArrayDouble.New(); - arr1=[1.2,2.3,3.4,4.5,5.6,6.7,7.8,8.9,9.1, 1.2,2.3,3.4,4.5,5.6,6.7,7.8,8.9,9.1, 1.2,2.3,3.4,4.5,5.6,6.7,7.8,8.9,9.1, 1.2,2.3,3.4,4.5,5.6,6.7,7.8,8.9,9.1, 1.2,2.3,3.4,4.5,5.6,6.7,7.8,8.9,9.1] - array.setValues(arr1,mesh1.getNumberOfCells(),9); - f1.setArray(array); - f1.checkCoherency(); - # - f2=f1.inverse(); - f2.checkCoherency(); - self.assertEqual(9,f2.getNumberOfComponents()); - self.assertEqual(5,f2.getNumberOfTuples()); - expected1=[-2.6538108356290113, 2.855831037649208, -1.1111111111111067, 3.461891643709813, -4.775022956841121, 2.2222222222222143, -1.1111111111111054, 2.222222222222214, -1.1111111111111072] - for i in xrange(5): - self.assertAlmostEqual(expected1[0],f2.getIJ(i,0),13); - self.assertAlmostEqual(expected1[1],f2.getIJ(i,1),13); - self.assertAlmostEqual(expected1[2],f2.getIJ(i,2),13); - self.assertAlmostEqual(expected1[3],f2.getIJ(i,3),13); - self.assertAlmostEqual(expected1[4],f2.getIJ(i,4),13); - self.assertAlmostEqual(expected1[5],f2.getIJ(i,5),13); - self.assertAlmostEqual(expected1[6],f2.getIJ(i,6),13); - self.assertAlmostEqual(expected1[7],f2.getIJ(i,7),13); - self.assertAlmostEqual(expected1[8],f2.getIJ(i,8),13); - pass - # - array=DataArrayDouble.New(); - arr3=[7.8,8.9,9.1,10.2,23.4,34.5, 7.8,8.9,9.1,10.2,23.4,34.5, 7.8,8.9,9.1,10.2,23.4,34.5, 7.8,8.9,9.1,10.2,23.4,34.5, 7.8,8.9,9.1,10.2,23.4,34.5] - array.setValues(arr3,mesh1.getNumberOfCells(),6); - f1.setArray(array); - f1.checkCoherency(); - # - f2=f1.inverse(); - f2.checkCoherency(); - self.assertEqual(6,f2.getNumberOfComponents()); - self.assertEqual(5,f2.getNumberOfTuples()); - expected3=[-0.3617705098531818, -0.8678630828458127, -0.026843764174972983, 0.5539957431465833, 0.13133439560823013, -0.05301294502145887] - for i in xrange(5): - self.assertAlmostEqual(expected3[0],f2.getIJ(i,0),13); - self.assertAlmostEqual(expected3[1],f2.getIJ(i,1),13); - self.assertAlmostEqual(expected3[2],f2.getIJ(i,2),13); - self.assertAlmostEqual(expected3[3],f2.getIJ(i,3),13); - self.assertAlmostEqual(expected3[4],f2.getIJ(i,4),13); - self.assertAlmostEqual(expected3[5],f2.getIJ(i,5),13); - pass - # - array=DataArrayDouble.New(); - arr2=[1.2,2.3,3.4,4.5, 1.2,2.3,3.4,4.5, 1.2,2.3,3.4,4.5, 1.2,2.3,3.4,4.5, 1.2,2.3,3.4,4.5] - array.setValues(arr2,mesh1.getNumberOfCells(),4); - f1.setArray(array); - f1.checkCoherency(); - # - f2=f1.inverse(); - f2.checkCoherency(); - self.assertEqual(4,f2.getNumberOfComponents()); - self.assertEqual(5,f2.getNumberOfTuples()); - expected2=[-1.8595041322314059, 0.9504132231404963, 1.404958677685951, -0.49586776859504156] - for i in xrange(5): - self.assertAlmostEqual(expected2[0],f2.getIJ(i,0),13); - self.assertAlmostEqual(expected2[1],f2.getIJ(i,1),13); - self.assertAlmostEqual(expected2[2],f2.getIJ(i,2),13); - self.assertAlmostEqual(expected2[3],f2.getIJ(i,3),13); - pass - # - pass - - def testTrace1(self): - mesh1=MEDCouplingDataForTest.build2DTargetMesh_1(); - f1=MEDCouplingFieldDouble.New(ON_CELLS,NO_TIME); - f1.setMesh(mesh1); - array=DataArrayDouble.New(); - arr1=[1.2,2.3,3.4,4.5,5.6,6.7,7.8,8.9,9.1, 1.2,2.3,3.4,4.5,5.6,6.7,7.8,8.9,9.1, 1.2,2.3,3.4,4.5,5.6,6.7,7.8,8.9,9.1, 1.2,2.3,3.4,4.5,5.6,6.7,7.8,8.9,9.1, 1.2,2.3,3.4,4.5,5.6,6.7,7.8,8.9,9.1] - array.setValues(arr1,mesh1.getNumberOfCells(),9); - f1.setArray(array); - f1.checkCoherency(); - # - f2=f1.trace(); - f2.checkCoherency(); - self.assertEqual(1,f2.getNumberOfComponents()); - self.assertEqual(5,f2.getNumberOfTuples()); - for i in xrange(5): - self.assertAlmostEqual(15.9,f2.getIJ(i,0),13); - pass - # - array=DataArrayDouble.New(); - arr3=[7.8,8.9,9.1,10.2,23.4,34.5, 7.8,8.9,9.1,10.2,23.4,34.5, 7.8,8.9,9.1,10.2,23.4,34.5, 7.8,8.9,9.1,10.2,23.4,34.5, 7.8,8.9,9.1,10.2,23.4,34.5] - array.setValues(arr3,mesh1.getNumberOfCells(),6); - f1.setArray(array); - f1.checkCoherency(); - # - f2=f1.trace(); - f2.checkCoherency(); - self.assertEqual(1,f2.getNumberOfComponents()); - self.assertEqual(5,f2.getNumberOfTuples()); - for i in xrange(5): - self.assertAlmostEqual(25.8,f2.getIJ(i,0),13); - pass - # - array=DataArrayDouble.New(); - arr2=[1.2,2.3,3.4,4.5, 1.2,2.3,3.4,4.5, 1.2,2.3,3.4,4.5, 1.2,2.3,3.4,4.5, 1.2,2.3,3.4,4.5] - array.setValues(arr2,mesh1.getNumberOfCells(),4); - f1.setArray(array); - f1.checkCoherency(); - # - f2=f1.trace(); - f2.checkCoherency(); - self.assertEqual(1,f2.getNumberOfComponents()); - self.assertEqual(5,f2.getNumberOfTuples()); - for i in xrange(5): - self.assertAlmostEqual(5.7,f2.getIJ(i,0),13); - pass - # - pass - - def testDeviator1(self): - mesh1=MEDCouplingDataForTest.build2DTargetMesh_1(); - f1=MEDCouplingFieldDouble.New(ON_CELLS,NO_TIME); - f1.setMesh(mesh1); - array=DataArrayDouble.New(); - arr1=[1.2,2.3,3.4,4.5,5.6,6.7, 1.2,2.3,3.4,4.5,5.6,6.7, 1.2,2.3,3.4,4.5,5.6,6.7, 1.2,2.3,3.4,4.5,5.6,6.7, 1.2,2.3,3.4,4.5,5.6,6.7] - array.setValues(arr1,mesh1.getNumberOfCells(),6); - f1.setArray(array); - f1.checkCoherency(); - # - f2=f1.deviator(); - f2.checkCoherency(); - self.assertEqual(6,f2.getNumberOfComponents()); - self.assertEqual(5,f2.getNumberOfTuples()); - expected1=[-1.1,0.,1.1,4.5,5.6,6.7] - for i in xrange(5): - self.assertAlmostEqual(expected1[0],f2.getIJ(i,0),13); - self.assertAlmostEqual(expected1[1],f2.getIJ(i,1),13); - self.assertAlmostEqual(expected1[2],f2.getIJ(i,2),13); - self.assertAlmostEqual(expected1[3],f2.getIJ(i,3),13); - self.assertAlmostEqual(expected1[4],f2.getIJ(i,4),13); - self.assertAlmostEqual(expected1[5],f2.getIJ(i,5),13); - pass - # - pass - - def testMagnitude1(self): - mesh1=MEDCouplingDataForTest.build2DTargetMesh_1(); - f1=MEDCouplingFieldDouble.New(ON_CELLS,NO_TIME); - f1.setMesh(mesh1); - array=DataArrayDouble.New(); - arr1=[1.2,2.3,3.4,4.5,5.6, 1.2,2.3,3.4,4.5,5.6, 1.2,2.3,3.4,4.5,5.6, 1.2,2.3,3.4,4.5,5.6, 1.2,2.3,3.4,4.5,5.6] - array.setValues(arr1,mesh1.getNumberOfCells(),5); - f1.setArray(array); - f1.checkCoherency(); - # - f2=f1.magnitude(); - f2.checkCoherency(); - self.assertEqual(1,f2.getNumberOfComponents()); - self.assertEqual(5,f2.getNumberOfTuples()); - for i in xrange(5): - self.assertAlmostEqual(8.3606219864313918,f2.getIJ(i,0),13); - pass - # - pass - - def testMaxPerTuple1(self): - mesh1=MEDCouplingDataForTest.build2DTargetMesh_1(); - f1=MEDCouplingFieldDouble.New(ON_CELLS,NO_TIME); - f1.setMesh(mesh1); - array=DataArrayDouble.New(); - arr1=[1.2,2.3,3.4,4.5,5.6, 1.2,3.4,4.5,5.6,2.3, 3.4,4.5,5.6,1.2,2.3, 5.6,1.2,2.3,3.4,4.5, 4.5,5.6,1.2,2.3,3.4] - array.setValues(arr1,mesh1.getNumberOfCells(),5); - f1.setArray(array); - f1.checkCoherency(); - # - f2=f1.maxPerTuple(); - f2.checkCoherency(); - self.assertEqual(1,f2.getNumberOfComponents()); - self.assertEqual(5,f2.getNumberOfTuples()); - for i in xrange(5): - self.assertAlmostEqual(5.6,f2.getIJ(i,0),13); - pass - # - d2,d2I=array.maxPerTupleWithCompoId() - self.assertEqual(1,d2.getNumberOfComponents()); - self.assertEqual(5,d2.getNumberOfTuples()); - for i in xrange(5): - self.assertAlmostEqual(5.6,d2.getIJ(i,0),13); - pass - self.assertTrue(d2I.isEqual(DataArrayInt([4,3,2,0,1]))) - pass - - def testChangeNbOfComponents(self): - mesh1=MEDCouplingDataForTest.build2DTargetMesh_1(); - f1=MEDCouplingFieldDouble.New(ON_CELLS,NO_TIME); - f1.setMesh(mesh1); - array=DataArrayDouble.New(); - arr1=[1.2,2.3,3.4,4.5,5.6, 1.2,3.4,4.5,5.6,2.3, 3.4,4.5,5.6,1.2,2.3, 5.6,1.2,2.3,3.4,4.5, 4.5,5.6,1.2,2.3,3.4] - array.setValues(arr1,mesh1.getNumberOfCells(),5); - f1.setArray(array); - f1.checkCoherency(); - # - f1.changeNbOfComponents(3,7.77); - f1.checkCoherency(); - self.assertEqual(3,f1.getNumberOfComponents()); - self.assertEqual(5,f1.getNumberOfTuples()); - expected1=[1.2,2.3,3.4, 1.2,3.4,4.5, 3.4,4.5,5.6, 5.6,1.2,2.3, 4.5,5.6,1.2] - for i in xrange(15): - self.assertAlmostEqual(expected1[i],f1.getIJ(0,i),13); - pass - f1.changeNbOfComponents(4,7.77); - f1.checkCoherency(); - self.assertEqual(4,f1.getNumberOfComponents()); - self.assertEqual(5,f1.getNumberOfTuples()); - expected2=[1.2,2.3,3.4,7.77, 1.2,3.4,4.5,7.77, 3.4,4.5,5.6,7.77, 5.6,1.2,2.3,7.77, 4.5,5.6,1.2,7.77] - for i in xrange(20): - self.assertAlmostEqual(expected2[i],f1.getIJ(0,i),13); - pass - # - pass - - def testSortPerTuple1(self): - mesh1=MEDCouplingDataForTest.build2DTargetMesh_1(); - f1=MEDCouplingFieldDouble.New(ON_CELLS,NO_TIME); - f1.setMesh(mesh1); - array=DataArrayDouble.New(); - arr1=[1.2,2.3,3.4,4.5,5.6, 1.2,3.4,4.5,5.6,2.3, 3.4,4.5,5.6,1.2,2.3, 5.6,1.2,2.3,3.4,4.5, 4.5,5.6,1.2,2.3,3.4] - array.setValues(arr1,mesh1.getNumberOfCells(),5); - f1.setArray(array); - f1.checkCoherency(); - # - f1.sortPerTuple(True); - f1.checkCoherency(); - self.assertEqual(5,f1.getNumberOfComponents()); - self.assertEqual(5,f1.getNumberOfTuples()); - for i in xrange(5): - self.assertAlmostEqual(arr1[0],f1.getIJ(i,0),13); - self.assertAlmostEqual(arr1[1],f1.getIJ(i,1),13); - self.assertAlmostEqual(arr1[2],f1.getIJ(i,2),13); - self.assertAlmostEqual(arr1[3],f1.getIJ(i,3),13); - self.assertAlmostEqual(arr1[4],f1.getIJ(i,4),13); - pass - # - f1.sortPerTuple(False); - f1.checkCoherency(); - self.assertEqual(5,f1.getNumberOfComponents()); - self.assertEqual(5,f1.getNumberOfTuples()); - for i in xrange(5): - self.assertAlmostEqual(arr1[4],f1.getIJ(i,0),13); - self.assertAlmostEqual(arr1[3],f1.getIJ(i,1),13); - self.assertAlmostEqual(arr1[2],f1.getIJ(i,2),13); - self.assertAlmostEqual(arr1[1],f1.getIJ(i,3),13); - self.assertAlmostEqual(arr1[0],f1.getIJ(i,4),13); - pass - # - pass - - def testIsEqualWithoutConsideringStr1(self): - mesh1=MEDCouplingDataForTest.build2DTargetMesh_1(); - mesh2=MEDCouplingDataForTest.build2DTargetMesh_1(); - # - self.assertTrue(mesh1.isEqual(mesh2,1e-12)); - self.assertTrue(mesh1.isEqualWithoutConsideringStr(mesh2,1e-12)); - mesh2.setName("rr"); - self.assertTrue(not mesh1.isEqual(mesh2,1e-12)); - self.assertTrue(mesh1.isEqualWithoutConsideringStr(mesh2,1e-12)); - da1,da2=mesh1.checkGeoEquivalWith(mesh2,2,1e-12); - self.assertRaises(InterpKernelException,mesh1.checkGeoEquivalWith,mesh2,0,1e-12); - mesh2.setName(""); - self.assertTrue(mesh1.isEqual(mesh2,1e-12)); - self.assertTrue(mesh1.isEqualWithoutConsideringStr(mesh2,1e-12)); - mesh2.getCoords().setInfoOnComponent(0,"tty"); - self.assertTrue(not mesh1.isEqual(mesh2,1e-12)); - self.assertTrue(mesh1.isEqualWithoutConsideringStr(mesh2,1e-12)); - mesh2.getCoords().setInfoOnComponent(0,""); - self.assertTrue(mesh1.isEqual(mesh2,1e-12)); - self.assertTrue(mesh1.isEqualWithoutConsideringStr(mesh2,1e-12)); - mesh2.getCoords().setInfoOnComponent(1,"tty"); - self.assertTrue(not mesh1.isEqual(mesh2,1e-12)); - self.assertTrue(mesh1.isEqualWithoutConsideringStr(mesh2,1e-12)); - mesh2.getCoords().setInfoOnComponent(1,""); - self.assertTrue(mesh1.isEqual(mesh2,1e-12)); - self.assertTrue(mesh1.isEqualWithoutConsideringStr(mesh2,1e-12)); - tmp=mesh2.getCoords().getIJ(0,3); - mesh2.getCoords().setIJ(0,3,9999.); - self.assertTrue(not mesh1.isEqual(mesh2,1e-12)); - self.assertTrue(not mesh1.isEqualWithoutConsideringStr(mesh2,1e-12)); - mesh2.getCoords().setIJ(0,3,tmp); - self.assertTrue(mesh1.isEqual(mesh2,1e-12)); - self.assertTrue(mesh1.isEqualWithoutConsideringStr(mesh2,1e-12)); - tmp2=mesh2.getNodalConnectivity().getIJ(0,4); - mesh2.getNodalConnectivity().setIJ(0,4,0); - self.assertTrue(not mesh1.isEqual(mesh2,1e-12)); - self.assertTrue(not mesh1.isEqualWithoutConsideringStr(mesh2,1e-12)); - mesh2.getNodalConnectivity().setIJ(0,4,tmp2); - self.assertTrue(mesh1.isEqual(mesh2,1e-12)); - self.assertTrue(mesh1.isEqualWithoutConsideringStr(mesh2,1e-12)); - # - f1=mesh1.getMeasureField(True); - f2=mesh2.getMeasureField(True); - self.assertTrue(f1.isEqual(f2,1e-12,1e-12)); - self.assertTrue(f1.isEqualWithoutConsideringStr(f2,1e-12,1e-12)); - f2.setName("ftest"); - self.assertTrue(not f1.isEqual(f2,1e-12,1e-12)); - self.assertTrue(f1.isEqualWithoutConsideringStr(f2,1e-12,1e-12)); - f1.setName("ftest"); - self.assertTrue(f1.isEqual(f2,1e-12,1e-12)); - self.assertTrue(f1.isEqualWithoutConsideringStr(f2,1e-12,1e-12)); - # - f2.getArray().setInfoOnComponent(0,"eee"); - self.assertTrue(not f1.isEqual(f2,1e-12,1e-12)); - self.assertTrue(f1.isEqualWithoutConsideringStr(f2,1e-12,1e-12)); - f2.getArray().setInfoOnComponent(0,""); - self.assertTrue(f1.isEqual(f2,1e-12,1e-12)); - self.assertTrue(f1.isEqualWithoutConsideringStr(f2,1e-12,1e-12)); - # - f2.getArray().setIJ(1,0,0.123); - self.assertTrue(not f1.isEqual(f2,1e-12,1e-12)); - self.assertTrue(not f1.isEqualWithoutConsideringStr(f2,1e-12,1e-12)); - f2.getArray().setIJ(1,0,0.125); - self.assertTrue(f1.isEqual(f2,1e-12,1e-12)); - self.assertTrue(f1.isEqualWithoutConsideringStr(f2,1e-12,1e-12)); - # - pass - - def testGetNodeIdsOfCell1(self): - mesh1=MEDCouplingDataForTest.build2DTargetMesh_1(); - li=mesh1.getNodeIdsOfCell(1) - expected1=[1, 4, 2] - self.assertEqual(expected1,list(li)) - li=mesh1.getCoordinatesOfNode(4) - self.assertEqual(2,len(li)) - self.assertAlmostEqual(0.2,li[0],13); - self.assertAlmostEqual(0.2,li[1],13); - li=mesh1.getCoords().getValuesAsTuple() - self.assertEqual(9,len(li)) - li2=mesh1.getNodalConnectivityIndex().getValuesAsTuple() - self.assertEqual(6,len(li2)) - pass - - def testGetEdgeRatioField1(self): - m1=MEDCouplingDataForTest.build2DTargetMesh_1(); - m1.setTime(3.4,5,6); m1.setTimeUnit("us"); - f1=m1.getEdgeRatioField(); - self.assertAlmostEqual(3.4,f1.getTime()[0],12) ; self.assertEqual(5,f1.getTime()[1]) ; self.assertEqual(6,f1.getTime()[2]) - self.assertEqual("us",f1.getTimeUnit()) - self.assertEqual(m1.getNumberOfCells(),f1.getNumberOfTuples()); - self.assertEqual(5,f1.getNumberOfTuples()); - self.assertEqual(1,f1.getNumberOfComponents()); - expected1=[1.,1.4142135623730951, 1.4142135623730951,1.,1.] - for i in xrange(5): - self.assertAlmostEqual(expected1[i],f1.getIJ(i,0),14); - pass - # - m1=MEDCouplingDataForTest.build3DSurfTargetMesh_1(); - f1=m1.getEdgeRatioField(); - self.assertEqual(m1.getNumberOfCells(),f1.getNumberOfTuples()); - self.assertEqual(5,f1.getNumberOfTuples()); - self.assertEqual(1,f1.getNumberOfComponents()); - expected2=[1.4142135623730951, 1.7320508075688772, 1.7320508075688772, 1.4142135623730951, 1.4142135623730951] - for i in xrange(5): - self.assertAlmostEqual(expected2[i],f1.getIJ(i,0),14); - pass - pass - - def testFillFromAnalytic3(self): - m=MEDCouplingDataForTest.build2DTargetMesh_1() - f1=MEDCouplingFieldDouble.New(ON_CELLS,ONE_TIME) - self.assertRaises(InterpKernelException,f1.fillFromAnalytic,1,"y+x"); - f1.setMesh(m) - f1.setName("myField"); - f1.fillFromAnalytic(1,"y+x"); - f1.checkCoherency(); - self.assertEqual(f1.getName(),"myField"); - self.assertEqual(f1.getTypeOfField(),ON_CELLS); - self.assertEqual(f1.getTimeDiscretization(),ONE_TIME); - self.assertEqual(1,f1.getNumberOfComponents()); - self.assertEqual(5,f1.getNumberOfTuples()); - values1=[-0.1,0.23333333333333336,0.56666666666666665,0.4,0.9] - tmp=f1.getArray().getValues(); - self.assertEqual(len(values1),len(tmp)) - for i in xrange(len(values1)): - self.assertTrue(abs(values1[i]-tmp[i])<1.e-12); - pass - # - f1=MEDCouplingFieldDouble.New(ON_NODES,CONST_ON_TIME_INTERVAL) - f1.setMesh(m) - f1.fillFromAnalytic(1,"y+2*x"); - f1.setEndTime(1.2,3,4); - f1.checkCoherency(); - self.assertEqual(f1.getTypeOfField(),ON_NODES); - self.assertEqual(f1.getTimeDiscretization(),CONST_ON_TIME_INTERVAL); - self.assertEqual(1,f1.getNumberOfComponents()); - self.assertEqual(9,f1.getNumberOfTuples()); - values2=[-0.9,0.1,1.1,-0.4,0.6,1.6,0.1,1.1,2.1] - tmp=f1.getArray().getValues(); - self.assertEqual(len(values2),len(tmp)) - for i in xrange(len(values2)): - self.assertTrue(abs(values2[i]-tmp[i])<1.e-12); - pass - f1=MEDCouplingFieldDouble.New(ON_NODES,LINEAR_TIME); - f1.setMesh(m) - f1.fillFromAnalytic(1,"2.*x+y"); - f1.setEndTime(1.2,3,4); - f1.checkCoherency(); - self.assertEqual(f1.getTypeOfField(),ON_NODES); - self.assertEqual(f1.getTimeDiscretization(),LINEAR_TIME); - self.assertEqual(1,f1.getNumberOfComponents()); - self.assertEqual(9,f1.getNumberOfTuples()); - tmp=f1.getArray().getValues(); - values2Bis=[-0.9,0.1,1.1,-0.4,0.6,1.6,0.1,1.1,2.1] - self.assertEqual(len(values2Bis),len(tmp)) - for i in xrange(len(values2Bis)): - self.assertTrue(abs(values2Bis[i]-tmp[i])<1.e-12); - pass - tmp=f1.getEndArray().getValues(); - self.assertEqual(len(values2Bis),len(tmp)) - for i in xrange(len(values2Bis)): - self.assertTrue(abs(values2Bis[i]-tmp[i])<1.e-12); - pass - # - f1=MEDCouplingFieldDouble.New(ON_NODES,ONE_TIME); - f1.setMesh(m) - f1.fillFromAnalytic(2,"(x+y)*IVec+2*(x+y)*JVec"); - f1.checkCoherency(); - self.assertEqual(f1.getTypeOfField(),ON_NODES); - self.assertEqual(f1.getTimeDiscretization(),ONE_TIME); - self.assertEqual(2,f1.getNumberOfComponents()); - self.assertEqual(9,f1.getNumberOfTuples()); - values3=[-0.6,-1.2,-0.1,-0.2,0.4,0.8,-0.1,-0.2,0.4,0.8,0.9,1.8,0.4,0.8,0.9,1.8,1.4,2.8] - tmp=f1.getArray().getValues(); - self.assertEqual(len(values3),len(tmp)) - for i in xrange(len(values3)): - self.assertTrue(abs(values3[i]-tmp[i])<1.e-12); - pass - values4=f1.accumulate(); - self.assertTrue(abs(3.6-values4[0])<1.e-12); - self.assertTrue(abs(7.2-values4[1])<1.e-12); - values4=f1.integral(True); - self.assertTrue(abs(0.5-values4[0])<1.e-12); - self.assertTrue(abs(1.-values4[1])<1.e-12); - # - f1=MEDCouplingFieldDouble.New(ON_NODES,NO_TIME); - f1.setMesh(m); - self.assertRaises(InterpKernelException,f1.fillFromAnalytic,1,"1./(x-0.2)"); - pass - - def testFieldDoubleOpEqual1(self): - m=MEDCouplingDataForTest.build2DTargetMesh_1(); - f1=MEDCouplingFieldDouble.New(ON_CELLS,ONE_TIME); - self.assertRaises(InterpKernelException,f1.assign,0.07); - f1.setMesh(m); - f1.assign(0.07); - f1.checkCoherency(); - self.assertEqual(1,f1.getNumberOfComponents()); - self.assertEqual(5,f1.getNumberOfTuples()); - for i in xrange(5): - self.assertAlmostEqual(0.07,f1.getIJ(i,0),16); - pass - f1.assign(0.09); - f1.checkCoherency(); - self.assertEqual(1,f1.getNumberOfComponents()); - self.assertEqual(5,f1.getNumberOfTuples()); - for i in xrange(5): - self.assertAlmostEqual(0.09,f1.getIJ(i,0),16); - pass - # - f1=MEDCouplingFieldDouble.New(ON_NODES,LINEAR_TIME); - f1.setEndTime(4.5,2,3); - f1.setMesh(m); - f1.assign(0.08); - f1.checkCoherency(); - self.assertEqual(1,f1.getNumberOfComponents()); - self.assertEqual(9,f1.getNumberOfTuples()); - for i in xrange(9): - self.assertAlmostEqual(0.08,f1.getIJ(i,0),16); - pass - self.assertEqual(1,f1.getEndArray().getNumberOfComponents()); - self.assertEqual(9,f1.getEndArray().getNumberOfTuples()); - for i in xrange(9): - self.assertAlmostEqual(0.08,f1.getEndArray().getIJ(i,0),16); - pass - pass - - def testAreaBary3D2(self): - coordsForHexa8=[-75.45749305371, 180.95495078401, 39.515472018008, - -9.755591679144, 23.394927935279, 5.108794294848, - 14.337630157832, 61.705351002702, 160.42422501908, - -27.273893776752, 167.567731083961, 192.830034145464, - 99.857193154796,264.499264735586,-8.287335493412, - 144.939882761126,156.38626563134,-31.896173894226, - 161.34096835726,182.4654895809,73.832387065572, - 132.680430393685,255.37973247196,96.15235602819]; - volHexa8=3258520.29637466; - baryHexa8=[43.925705821778, 155.31893955289, 65.874418109644] - - coordsForPenta6=[-68.199829618726,178.938498373416,62.608505919588, - 8.461744647847,76.653979804423,165.00018874933, - -27.273893776752,167.567731083961,192.830034145464, - 106.586501038965,262.629609408327,13.124533008813, - 155.465082847275,197.414118382622,78.408350795821, - 132.680430393685,255.37973247196,96.15235602819]; - volPenta6=944849.868507338; - baryPenta6=[39.631002313543,182.692711783428,106.98540473964] - - coordsForPyra5=[132.680430393685,255.37973247196,96.15235602819, - -27.273893776752,167.567731083961,192.830034145464, - 8.461744647847,76.653979804423,165.00018874933, - 155.465082847275,197.414118382622,78.408350795821, - -68.199829618726,178.938498373416,62.608505919588]; - volPyra5=756943.92980254; - baryPyra5=[29.204294116618,172.540129749156,118.01035951483] - mesh=MEDCouplingUMesh.New("Bary3D2",3); - coo=DataArrayDouble.New(); - tmp=coordsForHexa8+coordsForPenta6+coordsForPyra5 - coo.setValues(tmp,19,3); - mesh.setCoords(coo); - # - tmpConn=[0,1,2,3,4,5,6,7] - mesh.allocateCells(3); - self.assertRaises(InterpKernelException,mesh.insertNextCell,NORM_HEXA8,9,tmpConn[0:8]) - mesh.insertNextCell(NORM_HEXA8,tmpConn[0:8]) - mesh.insertNextCell(NORM_PENTA6,6,[i+8 for i in tmpConn]) - mesh.insertNextCell(NORM_PYRA5,5,[i+14 for i in tmpConn]) - mesh.finishInsertingCells(); - mesh.checkCoherency(); - mesh.mergeNodes(1e-7) - self.assertEqual(12,mesh.getNumberOfNodes()); - vols=mesh.getMeasureField(True); - self.assertEqual(3,vols.getNumberOfTuples()); - self.assertEqual(1,vols.getNumberOfComponents()); - self.assertAlmostEqual(volHexa8,vols.getIJ(0,0),6); - self.assertAlmostEqual(volPenta6,vols.getIJ(1,0),7); - self.assertAlmostEqual(volPyra5,vols.getIJ(2,0),7); - bary=mesh.getBarycenterAndOwner(); - self.assertEqual(3,bary.getNumberOfTuples()); - self.assertEqual(3,bary.getNumberOfComponents()); - self.assertAlmostEqual(baryHexa8[0],bary.getIJ(0,0),11); - self.assertAlmostEqual(baryHexa8[1],bary.getIJ(0,1),11); - self.assertAlmostEqual(baryHexa8[2],bary.getIJ(0,2),11); - self.assertAlmostEqual(baryPenta6[0],bary.getIJ(1,0),11); - self.assertAlmostEqual(baryPenta6[1],bary.getIJ(1,1),11); - self.assertAlmostEqual(baryPenta6[2],bary.getIJ(1,2),11); - self.assertAlmostEqual(baryPyra5[0],bary.getIJ(2,0),11); - self.assertAlmostEqual(baryPyra5[1],bary.getIJ(2,1),11); - self.assertAlmostEqual(baryPyra5[2],bary.getIJ(2,2),11); - pass - - def testGetMeasureFieldCMesh1(self): - m=MEDCouplingCMesh.New(); - da=DataArrayDouble.New(); - discX=[2.3,3.4,5.8,10.2] - discY=[12.3,23.4,45.8] - discZ=[-0.7,1.2,1.25,2.13,2.67] - da.setValues(discX,4,1); - m.setCoordsAt(0,da); - m.checkCoherency(); - self.assertEqual(4,m.getNumberOfNodes()); - self.assertEqual(3,m.getNumberOfCells()); - self.assertEqual(1,m.getSpaceDimension()); - f=m.getMeasureField(True); - self.assertEqual(3,f.getNumberOfTuples()); - self.assertEqual(1,f.getNumberOfComponents()); - expected1=[1.1,2.4,4.4] - for i in xrange(3): - self.assertAlmostEqual(expected1[i],f.getIJ(i,0),12); - pass - coords=m.getCoordinatesAndOwner(); - self.assertEqual(4,coords.getNumberOfTuples()); - self.assertEqual(1,coords.getNumberOfComponents()); - for i in xrange(4): - self.assertAlmostEqual(discX[i],coords.getIJ(i,0),12); - pass - coords=m.getBarycenterAndOwner(); - self.assertEqual(3,coords.getNumberOfTuples()); - self.assertEqual(1,coords.getNumberOfComponents()); - expected1_3=[2.85,4.6,8.] - for i in xrange(3): - self.assertAlmostEqual(expected1_3[i],coords.getIJ(i,0),12); - pass - # - da=DataArrayDouble.New(); - da.setValues(discY,3,1); - m.setCoordsAt(1,da); - m.checkCoherency(); - self.assertEqual(12,m.getNumberOfNodes()); - self.assertEqual(6,m.getNumberOfCells()); - self.assertEqual(2,m.getSpaceDimension()); - f=m.getMeasureField(True); - self.assertEqual(6,f.getNumberOfTuples()); - self.assertEqual(1,f.getNumberOfComponents()); - expected2=[12.21,26.64,48.84,24.64,53.76,98.56] - for i in xrange(6): - self.assertAlmostEqual(expected2[i],f.getIJ(i,0),12); - pass - coords=m.getCoordinatesAndOwner(); - self.assertEqual(12,coords.getNumberOfTuples()); - self.assertEqual(2,coords.getNumberOfComponents()); - expected2_2=[2.3,12.3,3.4,12.3,5.8,12.3,10.2,12.3, 2.3,23.4,3.4,23.4,5.8,23.4,10.2,23.4, 2.3,45.8,3.4,45.8,5.8,45.8,10.2,45.8] - for i in xrange(24): - self.assertAlmostEqual(expected2_2[i],coords.getIJ(0,i),12); - pass - coords=m.getBarycenterAndOwner(); - self.assertEqual(6,coords.getNumberOfTuples()); - self.assertEqual(2,coords.getNumberOfComponents()); - expected2_3=[2.85,17.85,4.6,17.85,8.,17.85, 2.85,34.6,4.6,34.6,8.,34.6] - for i in xrange(12): - self.assertAlmostEqual(expected2_3[i],coords.getIJ(0,i),12); - pass - # - da=DataArrayDouble.New(); - da.setValues(discZ,5,1); - m.setCoordsAt(2,da); - m.checkCoherency(); - self.assertEqual(60,m.getNumberOfNodes()); - self.assertEqual(24,m.getNumberOfCells()); - self.assertEqual(3,m.getSpaceDimension()); - f=m.getMeasureField(True); - self.assertEqual(24,f.getNumberOfTuples()); - self.assertEqual(1,f.getNumberOfComponents()); - expected3=[23.199, 50.616, 92.796, 46.816, 102.144, 187.264, 0.6105, 1.332, 2.442, 1.232, 2.688, 4.928, 10.7448, 23.4432, 42.9792, 21.6832, 47.3088, 86.7328, 6.5934, 14.3856, 26.3736, 13.3056, 29.0304, 53.2224] - for i in xrange(24): - self.assertAlmostEqual(expected3[i],f.getIJ(i,0),12); - pass - coords=m.getCoordinatesAndOwner(); - self.assertEqual(60,coords.getNumberOfTuples()); - self.assertEqual(3,coords.getNumberOfComponents()); - expected3_2=[ - 2.3,12.3,-0.7, 3.4,12.3,-0.7, 5.8,12.3,-0.7, 10.2,12.3,-0.7, 2.3,23.4,-0.7, 3.4,23.4,-0.7, 5.8,23.4,-0.7, 10.2,23.4,-0.7, 2.3,45.8,-0.7, 3.4,45.8,-0.7, 5.8,45.8,-0.7, 10.2,45.8,-0.7, - 2.3,12.3,1.2, 3.4,12.3,1.2, 5.8,12.3,1.2, 10.2,12.3,1.2, 2.3,23.4,1.2, 3.4,23.4,1.2, 5.8,23.4,1.2, 10.2,23.4,1.2, 2.3,45.8,1.2, 3.4,45.8,1.2, 5.8,45.8,1.2, 10.2,45.8,1.2, - 2.3,12.3,1.25, 3.4,12.3,1.25, 5.8,12.3,1.25, 10.2,12.3,1.25, 2.3,23.4,1.25, 3.4,23.4,1.25, 5.8,23.4,1.25, 10.2,23.4,1.25, 2.3,45.8,1.25, 3.4,45.8,1.25, 5.8,45.8,1.25, 10.2,45.8,1.25, - 2.3,12.3,2.13, 3.4,12.3,2.13, 5.8,12.3,2.13, 10.2,12.3,2.13, 2.3,23.4,2.13, 3.4,23.4,2.13, 5.8,23.4,2.13, 10.2,23.4,2.13, 2.3,45.8,2.13, 3.4,45.8,2.13, 5.8,45.8,2.13, 10.2,45.8,2.13, - 2.3,12.3,2.67, 3.4,12.3,2.67, 5.8,12.3,2.67, 10.2,12.3,2.67, 2.3,23.4,2.67, 3.4,23.4,2.67, 5.8,23.4,2.67, 10.2,23.4,2.67, 2.3,45.8,2.67, 3.4,45.8,2.67, 5.8,45.8,2.67, 10.2,45.8,2.67]; - for i in xrange(180): - self.assertAlmostEqual(expected3_2[i],coords.getIJ(0,i),12); - pass - coords=m.getBarycenterAndOwner(); - self.assertEqual(24,coords.getNumberOfTuples()); - self.assertEqual(3,coords.getNumberOfComponents()); - expected3_3=[ - 2.85,17.85,0.25,4.6,17.85,0.25,8.,17.85,0.25, 2.85,34.6,0.25,4.6,34.6,0.25,8.,34.6,0.25, - 2.85,17.85,1.225,4.6,17.85,1.225,8.,17.85,1.225, 2.85,34.6,1.225,4.6,34.6,1.225,8.,34.6,1.225, - 2.85,17.85,1.69,4.6,17.85,1.69,8.,17.85,1.69, 2.85,34.6,1.69,4.6,34.6,1.69,8.,34.6,1.69, - 2.85,17.85,2.4,4.6,17.85,2.4,8.,17.85,2.4, 2.85,34.6,2.4,4.6,34.6,2.4,8.,34.6,2.4]; - for i in xrange(72): - self.assertAlmostEqual(expected3_3[i],coords.getIJ(0,i),12); - pass - pass - - def testFieldDoubleZipCoords1(self): - m=MEDCouplingDataForTest.build2DTargetMeshMergeNode_1(); - f=m.fillFromAnalytic(ON_NODES,2,"x*2."); - f.getArray().setInfoOnComponent(0,"titi"); - f.getArray().setInfoOnComponent(1,"tutu"); - f.checkCoherency(); - self.assertEqual(18,f.getNumberOfTuples()); - self.assertEqual(2,f.getNumberOfComponents()); - expected1=[-0.6, -0.6, 0.4, 0.4, 1.4, 1.4, -0.6, -0.6, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 1.4, 1.4, -0.6, -0.6, 0.4, 0.4, 1.4, 1.4, -0.6, -0.6, 1.4, 1.4, -0.6, -0.6, 0.4, 0.4, 1.4, 1.4, 0.4, 0.4] - for i in xrange(36): - self.assertAlmostEqual(expected1[i],f.getIJ(0,i),12); - pass - self.assertTrue(f.zipCoords()); - f.checkCoherency(); - expected2=[-0.6, -0.6, 1.4, 1.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 1.4, 1.4, -0.6, -0.6, 0.4, 0.4, 1.4, 1.4, 1.4, 1.4, -0.6, -0.6, 0.4, 0.4, 1.4, 1.4, 0.4, 0.4] - for i in xrange(30): - self.assertAlmostEqual(expected2[i],f.getIJ(0,i),12); - pass - self.assertTrue(not f.zipCoords()); - f.checkCoherency(); - for i in xrange(30): - self.assertAlmostEqual(expected2[i],f.getIJ(0,i),12); - pass - self.assertTrue(f.getArray().getInfoOnComponent(0)=="titi"); - self.assertTrue(f.getArray().getInfoOnComponent(1)=="tutu"); - pass - - def testFieldDoubleZipConnectivity1(self): - m1=MEDCouplingDataForTest.build2DTargetMesh_1(); - m2=MEDCouplingDataForTest.build2DTargetMesh_1(); - cells1=[2,3,4] - m3_1=m2.buildPartOfMySelf(cells1,True); - m3=m3_1; - m4=MEDCouplingDataForTest.build2DSourceMesh_1(); - m5=MEDCouplingUMesh.MergeUMeshes(m1,m3); - m6=MEDCouplingUMesh.MergeUMeshes(m5,m4); - # - self.assertEqual(10,m6.getNumberOfCells()); - self.assertEqual(22,m6.getNumberOfNodes()); - arr,areNodesMerged,newNbOfNodes=m6.mergeNodes(1e-13); - self.assertEqual(9,m6.getNumberOfNodes()); - f=m6.fillFromAnalytic(ON_CELLS,2,"x"); - f2=m6.fillFromAnalytic(ON_NODES,2,"x"); - self.assertEqual(10,f.getNumberOfTuples()); - self.assertEqual(2,f.getNumberOfComponents()); - expected1=[-0.05, -0.05, 0.3666666666666667, 0.3666666666666667, 0.53333333333333321, 0.53333333333333321, - -0.05, -0.05, 0.45, 0.45, 0.53333333333333321, 0.53333333333333321, -0.05, -0.05, 0.45, 0.45, - 0.36666666666666659, 0.36666666666666659, 0.033333333333333326, 0.033333333333333326]; - for i in xrange(20): - self.assertAlmostEqual(expected1[i],f.getIJ(0,i),12); - pass - f.getArray().setInfoOnComponent(0,"titi"); - f.getArray().setInfoOnComponent(1,"tutu"); - f.checkCoherency(); - self.assertTrue(f.zipConnectivity(0)); - expected2=[-0.05, -0.05, 0.3666666666666667, 0.3666666666666667, 0.53333333333333321, 0.53333333333333321, - -0.05, -0.05, 0.45, 0.45, 0.36666666666666659, 0.36666666666666659, 0.033333333333333326, 0.033333333333333326]; - self.assertEqual(7,f.getNumberOfTuples()); - self.assertEqual(2,f.getNumberOfComponents()); - for i in xrange(14): - self.assertAlmostEqual(expected2[i],f.getIJ(0,i),12); - pass - self.assertTrue(f.getArray().getInfoOnComponent(0)=="titi"); - self.assertTrue(f.getArray().getInfoOnComponent(1)=="tutu"); - self.assertTrue(not f.zipConnectivity(0)); - # - expected3=[-0.3, -0.3, 0.2, 0.2, 0.7, 0.7, -0.3, -0.3, 0.2, 0.2, 0.7, 0.7, - -0.3, -0.3, 0.2, 0.2, 0.7, 0.7]; - self.assertEqual(9,f2.getNumberOfTuples()); - self.assertEqual(2,f2.getNumberOfComponents()); - for i in xrange(18): - self.assertAlmostEqual(expected3[i],f2.getIJ(0,i),12); - pass - self.assertTrue(f2.zipConnectivity(0)); - self.assertEqual(9,f2.getNumberOfTuples()); - self.assertEqual(2,f2.getNumberOfComponents()); - for i in xrange(18): - self.assertAlmostEqual(expected3[i],f2.getIJ(0,i),12); - pass - pass - - def testDaDoubleRenumber1(self): - a=DataArrayDouble.New(); - arr1=[1.1,11.1,2.1,12.1,3.1,13.1,4.1,14.1,5.1,15.1,6.1,16.1,7.1,17.1] - a.setValues(arr1,7,2); - a.setInfoOnComponent(0,"toto"); - a.setInfoOnComponent(1,"tata"); - # - arr2=[3,1,0,6,5,4,2] - b=a.renumber(arr2); - self.assertEqual(7,b.getNumberOfTuples()); - self.assertEqual(2,b.getNumberOfComponents()); - self.assertTrue(b.getInfoOnComponent(0)=="toto"); - self.assertTrue(b.getInfoOnComponent(1)=="tata"); - expected1=[3.1, 13.1, 2.1, 12.1, 7.1, 17.1, 1.1, 11.1, 6.1, 16.1, 5.1, 15.1, 4.1, 14.1] - for i in xrange(14): - self.assertAlmostEqual(expected1[i],b.getIJ(0,i),14); - pass - # - c=DataArrayInt.New(); - arr3=[1,11,2,12,3,13,4,14,5,15,6,16,7,17] - c.setValues(arr3,7,2); - c.setInfoOnComponent(0,"toto"); - c.setInfoOnComponent(1,"tata"); - d=c.renumber(arr2); - self.assertEqual(7,d.getNumberOfTuples()); - self.assertEqual(2,d.getNumberOfComponents()); - self.assertTrue(d.getInfoOnComponent(0)=="toto"); - self.assertTrue(d.getInfoOnComponent(1)=="tata"); - expected2=[3, 13, 2, 12, 7, 17, 1, 11, 6, 16, 5, 15, 4, 14] - for i in xrange(14): - self.assertEqual(expected2[i],d.getIJ(0,i)); - pass - pass - - def testDaDoubleRenumberAndReduce1(self): - a=DataArrayDouble.New(); - arr1=[1.1,11.1,2.1,12.1,3.1,13.1,4.1,14.1,5.1,15.1,6.1,16.1,7.1,17.1] - a.setValues(arr1,7,2); - a.setInfoOnComponent(0,"toto"); - a.setInfoOnComponent(1,"tata"); - # - arr2=[2,-1,1,-1,0,4,3] - b=a.renumberAndReduce(arr2,5); - self.assertEqual(5,b.getNumberOfTuples()); - self.assertEqual(2,b.getNumberOfComponents()); - self.assertTrue(b.getInfoOnComponent(0)=="toto"); - self.assertTrue(b.getInfoOnComponent(1)=="tata"); - expected1=[5.1,15.1,3.1,13.1,1.1,11.1,7.1,17.1,6.1,16.1] - for i in xrange(10): - self.assertAlmostEqual(expected1[i],b.getIJ(0,i),14); - pass - # - c=DataArrayInt.New(); - arr3=[1,11,2,12,3,13,4,14,5,15,6,16,7,17] - c.setValues(arr3,7,2); - c.setInfoOnComponent(0,"toto"); - c.setInfoOnComponent(1,"tata"); - d=c.renumberAndReduce(arr2,5); - self.assertEqual(5,d.getNumberOfTuples()); - self.assertEqual(2,d.getNumberOfComponents()); - self.assertTrue(d.getInfoOnComponent(0)=="toto"); - self.assertTrue(d.getInfoOnComponent(1)=="tata"); - expected2=[5,15,3,13,1,11,7,17,6,16] - for i in xrange(10): - self.assertEqual(expected2[i],d.getIJ(0,i)); - pass - pass - - def testDaDoubleRenumberInPlace1(self): - a=DataArrayDouble.New(); - arr1=[1.1,11.1,2.1,12.1,3.1,13.1,4.1,14.1,5.1,15.1,6.1,16.1,7.1,17.1] - a.setValues(arr1,7,2); - # - arr2=[3,1,0,6,5,4,2] - a.renumberInPlace(arr2); - self.assertEqual(7,a.getNumberOfTuples()); - self.assertEqual(2,a.getNumberOfComponents()); - expected1=[3.1, 13.1, 2.1, 12.1, 7.1, 17.1, 1.1, 11.1, 6.1, 16.1, 5.1, 15.1, 4.1, 14.1] - for i in xrange(14): - self.assertAlmostEqual(expected1[i],a.getIJ(0,i),14); - pass - # - c=DataArrayInt.New(); - arr3=[1,11,2,12,3,13,4,14,5,15,6,16,7,17] - c.setValues(arr3,7,2); - c.renumberInPlace(arr2); - self.assertEqual(7,c.getNumberOfTuples()); - self.assertEqual(2,c.getNumberOfComponents()); - expected2=[3, 13, 2, 12, 7, 17, 1, 11, 6, 16, 5, 15, 4, 14] - for i in xrange(14): - self.assertEqual(expected2[i],c.getIJ(0,i)); - pass - pass - - def testDaDoubleRenumberR1(self): - a=DataArrayDouble.New(); - arr1=[1.1,11.1,2.1,12.1,3.1,13.1,4.1,14.1,5.1,15.1,6.1,16.1,7.1,17.1] - a.setValues(arr1,7,2); - a.setInfoOnComponent(0,"toto"); - a.setInfoOnComponent(1,"tata"); - # - arr2=[3,1,0,6,5,4,2] - b=a.renumberR(arr2); - self.assertEqual(7,b.getNumberOfTuples()); - self.assertEqual(2,b.getNumberOfComponents()); - self.assertTrue(b.getInfoOnComponent(0)=="toto"); - self.assertTrue(b.getInfoOnComponent(1)=="tata"); - expected1=[4.1, 14.1, 2.1, 12.1, 1.1, 11.1, 7.1, 17.1, 6.1, 16.1, 5.1, 15.1, 3.1, 13.1] - for i in xrange(14): - self.assertAlmostEqual(expected1[i],b.getIJ(0,i),14); - pass - # - c=DataArrayInt.New(); - arr3=[1,11,2,12,3,13,4,14,5,15,6,16,7,17] - c.setValues(arr3,7,2); - c.setInfoOnComponent(0,"toto"); - c.setInfoOnComponent(1,"tata"); - d=c.renumberR(arr2); - self.assertEqual(7,d.getNumberOfTuples()); - self.assertEqual(2,d.getNumberOfComponents()); - self.assertTrue(d.getInfoOnComponent(0)=="toto"); - self.assertTrue(d.getInfoOnComponent(1)=="tata"); - expected2=[4, 14, 2, 12, 1, 11, 7, 17, 6, 16, 5, 15, 3, 13] - for i in xrange(14): - self.assertEqual(expected2[i],d.getIJ(0,i)); - pass - pass - - def testDaDoubleRenumberInPlaceR1(self): - a=DataArrayDouble.New(); - arr1=[1.1,11.1,2.1,12.1,3.1,13.1,4.1,14.1,5.1,15.1,6.1,16.1,7.1,17.1] - a.setValues(arr1,7,2); - # - arr2=[3,1,0,6,5,4,2] - a.renumberInPlaceR(arr2); - self.assertEqual(7,a.getNumberOfTuples()); - self.assertEqual(2,a.getNumberOfComponents()); - expected1=[4.1, 14.1, 2.1, 12.1, 1.1, 11.1, 7.1, 17.1, 6.1, 16.1, 5.1, 15.1, 3.1, 13.1] - for i in xrange(14): - self.assertAlmostEqual(expected1[i],a.getIJ(0,i),14); - pass - # - c=DataArrayInt.New(); - arr3=[1,11,2,12,3,13,4,14,5,15,6,16,7,17] - c.setValues(arr3,7,2); - c.renumberInPlaceR(arr2); - self.assertEqual(7,c.getNumberOfTuples()); - self.assertEqual(2,c.getNumberOfComponents()); - expected2=[4, 14, 2, 12, 1, 11, 7, 17, 6, 16, 5, 15, 3, 13] - for i in xrange(14): - self.assertEqual(expected2[i],c.getIJ(0,i)); - pass - pass - - def testDaDoubleSelectByTupleId1(self): - a=DataArrayDouble.New(); - arr1=[1.1,11.1,2.1,12.1,3.1,13.1,4.1,14.1,5.1,15.1,6.1,16.1,7.1,17.1] - a.setValues(arr1,7,2); - a.setInfoOnComponent(0,"toto"); - a.setInfoOnComponent(1,"tata"); - # - arr2=[4,2,0,6,5] - b=a.selectByTupleId(arr2); - self.assertEqual(5,b.getNumberOfTuples()); - self.assertEqual(2,b.getNumberOfComponents()); - self.assertTrue(b.getInfoOnComponent(0)=="toto"); - self.assertTrue(b.getInfoOnComponent(1)=="tata"); - expected1=[5.1,15.1,3.1,13.1,1.1,11.1,7.1,17.1,6.1,16.1] - for i in xrange(10): - self.assertAlmostEqual(expected1[i],b.getIJ(0,i),14); - pass - # - c=DataArrayInt.New(); - arr3=[1,11,2,12,3,13,4,14,5,15,6,16,7,17] - c.setValues(arr3,7,2); - c.setInfoOnComponent(0,"toto"); - c.setInfoOnComponent(1,"tata"); - d=c.selectByTupleId(arr2); - self.assertEqual(5,d.getNumberOfTuples()); - self.assertEqual(2,d.getNumberOfComponents()); - self.assertTrue(d.getInfoOnComponent(0)=="toto"); - self.assertTrue(d.getInfoOnComponent(1)=="tata"); - expected2=[5,15,3,13,1,11,7,17,6,16] - for i in xrange(10): - self.assertEqual(expected2[i],d.getIJ(0,i)); - pass - pass - - def testDaDoubleGetMinMaxValues1(self): - a=DataArrayDouble.New(); - arr1=[2.34,4.56,-6.77,4.55,4.56,2.24,2.34,1.02,4.56] - a.setValues(arr1,9,1); - m,where=a.getMaxValue(); - self.assertEqual(1,where); - self.assertAlmostEqual(4.56,m,12); - m,ws=a.getMaxValue2(); - self.assertAlmostEqual(4.56,m,12); - self.assertEqual(3,ws.getNumberOfTuples()); - self.assertEqual(1,ws.getNumberOfComponents()); - expected1=[1,4,8] - for i in xrange(3): - self.assertEqual(expected1[i],ws.getIJ(i,0)); - pass - a=DataArrayDouble.New(); - arr2=[-2.34,-4.56,6.77,-4.55,-4.56,-2.24,-2.34,-1.02,-4.56] - a.setValues(arr2,9,1); - m,where=a.getMinValue(); - self.assertEqual(1,where); - self.assertAlmostEqual(-4.56,m,12); - m,ws=a.getMinValue2(); - self.assertAlmostEqual(-4.56,m,12); - self.assertEqual(3,ws.getNumberOfTuples()); - self.assertEqual(1,ws.getNumberOfComponents()); - for i in xrange(3): - self.assertEqual(expected1[i],ws.getIJ(i,0)); - pass - pass - - def testFieldDoubleGetMinMaxValues2(self): - m2,m1=MEDCouplingDataForTest.build3DExtrudedUMesh_1(); - self.assertEqual(18,m2.getNumberOfCells()); - arr1=[8.71,4.53,-12.41,8.71,-8.71,8.7099,4.55,8.71,5.55,6.77,-1e-200,4.55,8.7099,0.,1.23,0.,2.22,8.71] - f=MEDCouplingFieldDouble.New(ON_CELLS,NO_TIME); - a=DataArrayDouble.New(); - a.setValues(arr1,18,1); - f.setArray(a); - f.setMesh(m2); - # - f.checkCoherency(); - m=f.getMaxValue(); - self.assertAlmostEqual(8.71,m,12); - m,ws=f.getMaxValue2(); - self.assertAlmostEqual(8.71,m,12); - self.assertEqual(4,ws.getNumberOfTuples()); - self.assertEqual(1,ws.getNumberOfComponents()); - expected1=[0,3,7,17] - for i in xrange(4): - self.assertEqual(expected1[i],ws.getIJ(i,0)); - pass - # - arr2=[-8.71,-4.53,12.41,-8.71,8.71,-8.7099,-4.55,-8.71,-5.55,-6.77,1e-200,-4.55,-8.7099,0.,-1.23,0.,-2.22,-8.71] - a.setValues(arr2,18,1); - f.checkCoherency(); - m=f.getMinValue(); - self.assertAlmostEqual(-8.71,m,12); - m,ws=f.getMinValue2(); - self.assertAlmostEqual(-8.71,m,12); - self.assertEqual(4,ws.getNumberOfTuples()); - self.assertEqual(1,ws.getNumberOfComponents()); - for i in xrange(4): - self.assertEqual(expected1[i],ws.getIJ(i,0)); - pass - pass - - def testBuildUnstructuredCMesh1(self): - m=MEDCouplingCMesh.New(); - da=DataArrayDouble.New(); - discX=[2.3,3.4,5.8,10.2] - discY=[12.3,23.4,45.8] - discZ=[-0.7,1.2,1.25,2.13,2.67] - da.setValues(discX,4,1); - m.setCoordsAt(0,da); - m.checkCoherency(); - self.assertEqual(0,m.getCellContainingPoint([2.4],1e-12)); - self.assertEqual(1,m.getCellContainingPoint([3.7],1e-12)); - self.assertEqual(2,m.getCellContainingPoint([5.9],1e-12)); - self.assertEqual(-1,m.getCellContainingPoint([10.3],1e-12)); - self.assertEqual(-1,m.getCellContainingPoint([1.3],1e-12)); - # - m2=m.buildUnstructured(); - m2.checkCoherency(); - f1=m.getMeasureField(False); - f2=m2.getMeasureField(False); - self.assertTrue(isinstance(f1.getMesh(),MEDCouplingCMesh)) - self.assertEqual(f1.getNumberOfTuples(),3); - self.assertEqual(f2.getNumberOfTuples(),3); - self.assertEqual(1,m2.getMeshDimension()); - self.assertEqual(1,m2.getSpaceDimension()); - for i in xrange(3): - self.assertAlmostEqual(f1.getIJ(i,0),f2.getIJ(i,0),10); - pass - da=DataArrayDouble.New(); - da.setValues(discY,3,1); - m.setCoordsAt(1,da); - # - m2=m.buildUnstructured(); - m2.checkCoherency(); - f1=m.getMeasureField(False); - f2=m2.getMeasureField(False); - self.assertEqual(f1.getNumberOfTuples(),6); - self.assertEqual(f2.getNumberOfTuples(),6); - self.assertEqual(2,m2.getMeshDimension()); - self.assertEqual(2,m2.getSpaceDimension()); - for i in xrange(6): - self.assertAlmostEqual(f1.getIJ(i,0),f2.getIJ(i,0),10); - pass - # - da=DataArrayDouble.New(); - da.setValues(discZ,5,1); - m.setCoordsAt(2,da); - m2=m.buildUnstructured(); - m2.checkCoherency(); - f1=m.getMeasureField(False); - f2=m2.getMeasureField(False); - self.assertEqual(f1.getNumberOfTuples(),24); - self.assertEqual(f2.getNumberOfTuples(),24); - self.assertEqual(3,m2.getMeshDimension()); - self.assertEqual(3,m2.getSpaceDimension()); - for i in xrange(24): - self.assertAlmostEqual(f1.getIJ(i,0),f2.getIJ(i,0),10); - pass - # - pos1=[5.,30.,2.] - self.assertEqual(16,m.getCellContainingPoint(pos1,1e-12)); - # - elems=m2.getCellsInBoundingBox([3.5,6.,12.2,25.,0.,1.5],1e-7) - self.assertEqual([1, 2, 4, 5, 7, 8, 10, 11, 13, 14, 16, 17],elems.getValues()) - # - pt=[2.4,12.7,-3.4] - m.scale(pt,3.7); - m3=m.buildUnstructured(); - m2.scale(pt,3.7); - self.assertTrue(m3.isEqual(m2,1e-12)); - pass - - def testDataArrayIntInvertO2NNO21(self): - arr1=[2,0,4,1,5,3] - da=DataArrayInt.New(); - da.setValues(arr1,6,1); - da2=da.invertArrayO2N2N2O(6); - self.assertEqual(6,da2.getNumberOfTuples()); - self.assertEqual(1,da2.getNumberOfComponents()); - expected1=[1,3,0,5,2,4] - for i in xrange(6): - self.assertEqual(expected1[i],da2.getIJ(i,0)); - pass - da3=da2.invertArrayN2O2O2N(6); - for i in xrange(6): - self.assertEqual(arr1[i],da3.getIJ(i,0)); - pass - # - arr2=[3,-1,5,4,-1,0,-1,1,2,-1] - da=DataArrayInt.New(); - da.setValues(arr2,10,1); - da2=da.invertArrayO2N2N2O(6); - self.assertEqual(6,da2.getNumberOfTuples()); - self.assertEqual(1,da2.getNumberOfComponents()); - expected2=[5,7,8,0,3,2] - for i in xrange(6): - self.assertEqual(expected2[i],da2.getIJ(i,0)); - pass - da3=da2.invertArrayN2O2O2N(10); - for i in xrange(10): - self.assertEqual(arr2[i],da3.getIJ(i,0)); - pass - pass - - def testKeepSetSelectedComponent1(self): - arr1=[1.,2.,3.,4., 11.,12.,13.,14., 21.,22.,23.,24., 31.,32.,33.,34., 41.,42.,43.,44.] - a1=DataArrayDouble.New(); - a1.setValues(arr1,5,4); - expp=[21.,22.,23.,24.] - self.assertEqual(4,len(a1.getTuple(2))); - for i in xrange(4): - self.assertAlmostEqual(expp[i],a1.getTuple(2)[i],12) - pass - a1.setInfoOnComponent(0,"aaaa"); - a1.setInfoOnComponent(1,"bbbb"); - a1.setInfoOnComponent(2,"cccc"); - a1.setInfoOnComponent(3,"dddd"); - arr2V=[1,2,1,2,0,0] - a2=a1.keepSelectedComponents(arr2V); - self.assertEqual(6,a2.getNumberOfComponents()); - self.assertEqual(5,a2.getNumberOfTuples()); - self.assertTrue(a2.getInfoOnComponent(0)=="bbbb"); - self.assertTrue(a2.getInfoOnComponent(1)=="cccc"); - self.assertTrue(a2.getInfoOnComponent(2)=="bbbb"); - self.assertTrue(a2.getInfoOnComponent(3)=="cccc"); - self.assertTrue(a2.getInfoOnComponent(4)=="aaaa"); - self.assertTrue(a2.getInfoOnComponent(5)=="aaaa"); - expected1=[2.,3.,2.,3.,1.,1., 12.,13.,12.,13.,11.,11., 22.,23.,22.,23.,21.,21., 32.,33.,32.,33.,31.,31., 42.,43.,42.,43.,41.,41.] - for i in xrange(30): - self.assertAlmostEqual(expected1[i],a2.getIJ(0,i),14); - pass - a3=a1.convertToIntArr(); - self.assertEqual([21,22,23,24],a3.getTuple(2)) - a4=a3.keepSelectedComponents(arr2V); - self.assertEqual(6,a4.getNumberOfComponents()); - self.assertEqual(5,a4.getNumberOfTuples()); - self.assertTrue(a4.getInfoOnComponent(0)=="bbbb"); - self.assertTrue(a4.getInfoOnComponent(1)=="cccc"); - self.assertTrue(a4.getInfoOnComponent(2)=="bbbb"); - self.assertTrue(a4.getInfoOnComponent(3)=="cccc"); - self.assertTrue(a4.getInfoOnComponent(4)=="aaaa"); - self.assertTrue(a4.getInfoOnComponent(5)=="aaaa"); - for i in xrange(30): - self.assertEqual(int(expected1[i]),a4.getIJ(0,i)); - pass - # setSelectedComponents - arr3V=[3,2] - a5=a1.keepSelectedComponents(arr3V); - a5.setInfoOnComponent(0,"eeee"); - a5.setInfoOnComponent(1,"ffff"); - arr4V=[1,2] - a2.setSelectedComponents(a5,arr4V); - self.assertEqual(6,a2.getNumberOfComponents()); - self.assertEqual(5,a2.getNumberOfTuples()); - self.assertTrue(a2.getInfoOnComponent(0)=="bbbb"); - self.assertTrue(a2.getInfoOnComponent(1)=="eeee"); - self.assertTrue(a2.getInfoOnComponent(2)=="ffff"); - self.assertTrue(a2.getInfoOnComponent(3)=="cccc"); - self.assertTrue(a2.getInfoOnComponent(4)=="aaaa"); - self.assertTrue(a2.getInfoOnComponent(5)=="aaaa"); - expected2=[2.,4.,3.,3.,1.,1., 12.,14.,13.,13.,11.,11., 22.,24.,23.,23.,21.,21., 32.,34.,33.,33.,31.,31., 42.,44.,43.,43.,41.,41.] - for i in xrange(30): - self.assertAlmostEqual(expected2[i],a2.getIJ(0,i),14); - pass - a6=a5.convertToIntArr(); - a6.setInfoOnComponent(0,"eeee"); - a6.setInfoOnComponent(1,"ffff"); - a4.setSelectedComponents(a6,arr4V); - self.assertEqual(6,a4.getNumberOfComponents()); - self.assertEqual(5,a4.getNumberOfTuples()); - self.assertTrue(a4.getInfoOnComponent(0)=="bbbb"); - self.assertTrue(a4.getInfoOnComponent(1)=="eeee"); - self.assertTrue(a4.getInfoOnComponent(2)=="ffff"); - self.assertTrue(a4.getInfoOnComponent(3)=="cccc"); - self.assertTrue(a4.getInfoOnComponent(4)=="aaaa"); - self.assertTrue(a4.getInfoOnComponent(5)=="aaaa"); - for i in xrange(30): - self.assertEqual(int(expected2[i]),a4.getIJ(0,i)); - pass - # test of throw - arr5V=[2,3,6] - arr6V=[2,7,5] - arr7V=[2,1,4,6] - self.assertRaises(InterpKernelException,a2.keepSelectedComponents,arr5V); - self.assertRaises(InterpKernelException,a2.keepSelectedComponents,arr6V); - self.assertRaises(InterpKernelException,a2.setSelectedComponents,a1,arr7V); - arr7V=arr7V[0:3] - self.assertRaises(InterpKernelException,a2.setSelectedComponents,a1,arr7V); - # - pass - - def testKeepSetSelectedComponent2(self): - m1=MEDCouplingDataForTest.build2DTargetMesh_1(); - arr1=[1.,2.,3.,4., 11.,12.,13.,14., 21.,22.,23.,24., 31.,32.,33.,34., 41.,42.,43.,44.] - a1=DataArrayDouble.New(); - a1.setValues(arr1,5,4); - a1.setInfoOnComponent(0,"aaaa"); - a1.setInfoOnComponent(1,"bbbb"); - a1.setInfoOnComponent(2,"cccc"); - a1.setInfoOnComponent(3,"dddd"); - f1=MEDCouplingFieldDouble.New(ON_CELLS,ONE_TIME); - f1.setTime(2.3,4,5); - f1.setMesh(m1); - f1.setName("f1"); - f1.setArray(a1); - f1.checkCoherency(); - # - arr2V=[1,2,1,2,0,0] - f2=f1.keepSelectedComponents(arr2V); - self.assertTrue(f2.getTimeDiscretization()==ONE_TIME); - t,dt,it=f2.getTime() - self.assertAlmostEqual(2.3,t,13); - self.assertEqual(4,dt); - self.assertEqual(5,it); - f2.checkCoherency(); - self.assertEqual(6,f2.getNumberOfComponents()); - self.assertEqual(5,f2.getNumberOfTuples()); - self.assertTrue(f2.getArray().getInfoOnComponent(0)=="bbbb"); - self.assertTrue(f2.getArray().getInfoOnComponent(1)=="cccc"); - self.assertTrue(f2.getArray().getInfoOnComponent(2)=="bbbb"); - self.assertTrue(f2.getArray().getInfoOnComponent(3)=="cccc"); - self.assertTrue(f2.getArray().getInfoOnComponent(4)=="aaaa"); - self.assertTrue(f2.getArray().getInfoOnComponent(5)=="aaaa"); - expected1=[2.,3.,2.,3.,1.,1., 12.,13.,12.,13.,11.,11., 22.,23.,22.,23.,21.,21., 32.,33.,32.,33.,31.,31., 42.,43.,42.,43.,41.,41.] - for i in xrange(30): - self.assertAlmostEqual(expected1[i],f2.getIJ(0,i),14); - pass - #setSelectedComponents - arr3V=[3,2] - f5=f1.keepSelectedComponents(arr3V); - f5.setTime(6.7,8,9); - f5.getArray().setInfoOnComponent(0,"eeee"); - f5.getArray().setInfoOnComponent(1,"ffff"); - f5.checkCoherency(); - arr4V=[1,2] - f2.setSelectedComponents(f5,arr4V); - self.assertEqual(6,f2.getNumberOfComponents()); - self.assertEqual(5,f2.getNumberOfTuples()); - f2.checkCoherency(); - t,dt,it=f2.getTime() - self.assertAlmostEqual(2.3,t,13); - self.assertEqual(4,dt); - self.assertEqual(5,it); - self.assertTrue(f2.getArray().getInfoOnComponent(0)=="bbbb"); - self.assertTrue(f2.getArray().getInfoOnComponent(1)=="eeee"); - self.assertTrue(f2.getArray().getInfoOnComponent(2)=="ffff"); - self.assertTrue(f2.getArray().getInfoOnComponent(3)=="cccc"); - self.assertTrue(f2.getArray().getInfoOnComponent(4)=="aaaa"); - self.assertTrue(f2.getArray().getInfoOnComponent(5)=="aaaa"); - expected2=[2.,4.,3.,3.,1.,1., 12.,14.,13.,13.,11.,11., 22.,24.,23.,23.,21.,21., 32.,34.,33.,33.,31.,31., 42.,44.,43.,43.,41.,41.] - for i in xrange(30): - self.assertAlmostEqual(expected2[i],f2.getIJ(0,i),14); - pass - # - pass - - def testElementaryDAThrowAndSpecialCases(self): - da=DataArrayInt.New(); - self.assertRaises(InterpKernelException, da.checkAllocated); - self.assertRaises(InterpKernelException, da.fillWithValue, 1); - self.assertRaises(InterpKernelException, da.iota, 1); - da.alloc(7,1); - da.fillWithValue(11); #11,11,11,11... - da.iota(10); #10,11,12,13... - - db=DataArrayInt.New(); - db.alloc(7,2); - - dbl2=DataArrayDouble.New(); - dbl2.alloc(7,2); - self.assertRaises(InterpKernelException, dbl2.isUniform, 10., 1e-15); - self.assertRaises(InterpKernelException, dbl2.sort); - self.assertRaises(InterpKernelException, dbl2.iota, 10.); - - dbl=DataArrayDouble.New(); - #DataArrayDouble not allocated yet - self.assertRaises(InterpKernelException, dbl.iota, 10.); - self.assertRaises(InterpKernelException, dbl.isUniform, 10., 1e-15); - self.assertRaises(InterpKernelException, dbl.sort); - self.assertRaises(InterpKernelException, dbl.fromNoInterlace); - self.assertRaises(InterpKernelException, dbl.toNoInterlace); - - dbl.alloc(7,1); - dbl.iota(10.); - self.assertTrue(not dbl.isUniform(10.,1e-15)); - dbl.sort(); - self.assertTrue(dbl.isMonotonic(True, .99)); - self.assertTrue(dbl.isMonotonic(True, -.99)); - self.assertTrue(not dbl.isMonotonic(True, 1.1)); - self.assertTrue(not dbl.isMonotonic(True, -1.1)); - dbl.reverse(); - self.assertTrue(dbl.isMonotonic(False, .99)); - self.assertTrue(not dbl.isMonotonic(False, 1.1)); - self.assertTrue(not dbl.isMonotonic(False, -1.1)); - - dc=DataArrayInt.New(); - dc.alloc(14,1); - - dd=DataArrayDouble.New(); - self.assertRaises(InterpKernelException, dd.checkAllocated); - self.assertRaises(InterpKernelException, dd.fillWithValue, 1.); - self.assertRaises(InterpKernelException, dd.iota, 1.); - self.assertTrue(not ((dd.repr().find("No data"))==-1)); - - dd.alloc(0,1); #Allocated but nbOfElements==0! - self.assertTrue(not ((dd.repr().find("Number of tuples : 0"))==-1)); - self.assertTrue(not ((dd.repr().find("Empty Data"))==-1)); - dd.fillWithValue(11); #?!...ok - dd.iota(10); #?!...ok - self.assertTrue(dd.isMonotonic(True, 1.)); #nothing is monotonic - self.assertTrue(dd.isMonotonic(False, 1.)); - - self.assertRaises(InterpKernelException, db.copyStringInfoFrom, da); - self.assertRaises(InterpKernelException, db.copyStringInfoFrom, da); - cIds=[2,2] - self.assertRaises(InterpKernelException, da.copyPartOfStringInfoFrom, db, cIds); - cIds[0]=1; - cIds[0]=-1; - self.assertRaises(InterpKernelException, da.copyPartOfStringInfoFrom, db, cIds); - - info=["infoOfOneComponent"]*2; - self.assertRaises(InterpKernelException, da.setInfoOnComponents, info); - self.assertRaises(InterpKernelException, da.setInfoOnComponent, 1, info[0]); - db.setInfoOnComponents(info); - - self.assertRaises(InterpKernelException, da.getInfoOnComponent, -1); - self.assertRaises(InterpKernelException, da.getInfoOnComponent, 2); - self.assertTrue(db.getInfoOnComponent(1)==db.getInfoOnComponent(0)); - self.assertRaises(InterpKernelException, db.getVarOnComponent, -1); - self.assertRaises(InterpKernelException, db.getVarOnComponent, 2); - self.assertRaises(InterpKernelException, db.getUnitOnComponent, -1); - self.assertRaises(InterpKernelException, db.getUnitOnComponent, 2); - - self.assertTrue(da.GetVarNameFromInfo("varname unit ")=="varname unit "); - self.assertTrue(da.GetVarNameFromInfo("varname]unit[")=="varname]unit["); - self.assertTrue(da.GetVarNameFromInfo("[unit]")==""); - self.assertTrue(da.GetVarNameFromInfo("varname [unit]")=="varname"); - - self.assertTrue(da.GetUnitFromInfo("varname unit ")==""); - self.assertTrue(da.GetUnitFromInfo("varname]unit[")==""); - self.assertTrue(da.GetUnitFromInfo("[unit]")=="unit"); - self.assertTrue(da.GetUnitFromInfo("varname [unit]")=="unit"); - - self.assertRaises(InterpKernelException, da.checkNbOfTuplesAndComp, db, "theMessageInThrow"); - self.assertRaises(InterpKernelException, da.checkNbOfTuplesAndComp, dc, "theMessageInThrow"); - self.assertRaises(InterpKernelException, db.checkNbOfTuplesAndComp, dc, "theMessageInThrow"); - - self.assertRaises(InterpKernelException, da.checkNbOfTuplesAndComp, 7, 2, "theMessageInThrow"); - da.checkNbOfTuplesAndComp(7,1,"theMessageInThrow"); - - self.assertRaises(InterpKernelException, db.checkNbOfElems, 7*2+1, "theMessageInThrow"); - db.checkNbOfElems(7*2,"theMessageInThrow"); - - self.assertRaises(InterpKernelException, db.GetNumberOfItemGivenBES, 10, 9, 1, "theMessageInThrow"); - self.assertRaises(InterpKernelException, db.GetNumberOfItemGivenBES, 0, 1, -1, "theMessageInThrow"); - self.assertEqual(10,db.GetNumberOfItemGivenBES(0,10,1,"theMessageInThrow")); - self.assertEqual(5,db.GetNumberOfItemGivenBES(0,10,2,"theMessageInThrow")); - self.assertEqual(6,db.GetNumberOfItemGivenBES(0,11,2,"theMessageInThrow")); - - self.assertTrue(not ((da.repr().find("Number of components : 1"))==-1)); - self.assertTrue(not ((dd.repr().find("Number of components : 1"))==-1)); - self.assertTrue(not ((dbl.repr().find("Number of components : 1"))==-1)); - - self.assertTrue(not ((da.reprZip().find("Number of components : 1"))==-1)); - self.assertTrue(not ((dd.reprZip().find("Number of components : 1"))==-1)); - self.assertTrue(not ((dbl.reprZip().find("Number of components : 1"))==-1)); - - self.assertRaises(InterpKernelException, dbl.selectByTupleId2, 0, 1, -1); - self.assertRaises(InterpKernelException, dbl.substr, -1, 1); - self.assertRaises(InterpKernelException, dbl.substr, 8, 1); - self.assertRaises(InterpKernelException, dbl.substr, 0, 8); - self.assertRaises(InterpKernelException, dbl.meldWith, dd); - - self.assertRaises(InterpKernelException, dbl.setPartOfValuesAdv, dbl2, da); #dbl dbl2 not have the same number of components - self.assertRaises(InterpKernelException, dbl.setPartOfValuesAdv, dd, da); #da tuple selector DataArrayInt instance not have exactly 2 components - - dbl3=DataArrayDouble.New(); - dbl3.alloc(6,2); - dbl3.fillWithValue(11.); - #bad number of components - self.assertRaises(InterpKernelException, dbl3.getMaxValue); - self.assertRaises(InterpKernelException, dd.getMaxValue); - self.assertRaises(InterpKernelException, dbl3.getMinValue); - self.assertRaises(InterpKernelException, dd.getMinValue); - self.assertRaises(InterpKernelException, dbl3.getAverageValue); - self.assertRaises(InterpKernelException, dd.getAverageValue); - self.assertRaises(InterpKernelException, dd.accumulate, 100); - self.assertRaises(InterpKernelException, dbl.fromPolarToCart); - self.assertRaises(InterpKernelException, dbl3.fromCylToCart); - self.assertRaises(InterpKernelException, dbl3.fromSpherToCart); - self.assertRaises(InterpKernelException, dbl3.doublyContractedProduct); - self.assertRaises(InterpKernelException, dbl3.determinant); - self.assertRaises(InterpKernelException, dbl3.eigenValues); - self.assertRaises(InterpKernelException, dbl3.eigenVectors); - self.assertRaises(InterpKernelException, dbl3.inverse); - self.assertRaises(InterpKernelException, dbl3.trace); - self.assertRaises(InterpKernelException, dbl3.deviator); - - dbl3.setIJ(5,1,12.); - self.assertTrue(dbl3.getMaxValueInArray()==12.); - self.assertTrue(dbl3.getMinValueInArray()==11.); - - db.fillWithValue(100); #bad Ids - self.assertRaises(InterpKernelException, dbl3.setPartOfValuesAdv, dbl2, db); - db.fillWithValue(-1); #bad Ids - self.assertRaises(InterpKernelException, dbl3.setPartOfValuesAdv, dbl2, db); - db.fillWithValue(6); #bad Ids for dbl3 - self.assertRaises(InterpKernelException, dbl3.setPartOfValuesAdv, dbl2, db); - - dbl3.checkNoNullValues(); - dbl3.setIJ(5,0,0.); - self.assertRaises(InterpKernelException, dbl3.checkNoNullValues); - self.assertRaises(InterpKernelException, dbl3.applyInv, 1.); #div by zero - self.assertRaises(InterpKernelException, dbl2.getIdsInRange, 1., 2.); - a=[] - self.assertRaises(InterpKernelException, DataArrayDouble_Aggregate, a); - self.assertRaises(InterpKernelException, DataArrayDouble_Meld, a); - - a=[dbl2,dbl]; #Nb of components mismatch - self.assertRaises(InterpKernelException, DataArrayDouble_Aggregate, a); - - self.assertRaises(InterpKernelException, DataArrayDouble_Dot, dbl2, dbl); - - self.assertRaises(InterpKernelException, DataArrayDouble_CrossProduct, dbl2, dbl); #Nb of components mismatch - self.assertRaises(InterpKernelException, DataArrayDouble_CrossProduct, dbl2, dbl2); #Nb of components must be equal to 3 - dbl4=DataArrayDouble.New(); - dbl4.alloc(6,3); - dbl5=DataArrayDouble.New(); - dbl5.alloc(7,3); - self.assertRaises(InterpKernelException, DataArrayDouble_CrossProduct, dbl4, dbl5); #Nb of tuples mismatch - - a[0]=dbl4; #Nb of tuple mismatch - a[1]=dbl5; #Nb of tuple mismatch - self.assertRaises(InterpKernelException, DataArrayDouble_Meld, a); - self.assertRaises(InterpKernelException, DataArrayDouble_Dot, dbl4, dbl5); - pass - - def testDAIGetIdsEqual1(self): - tab1=[5,-2,-4,-2,3,2,-2]; - da=DataArrayInt.New(); - da.setValues(tab1,7,1); - da2=da.getIdsEqual(-2); - self.assertEqual(3,da2.getNumberOfTuples()); - self.assertEqual(1,da2.getNumberOfComponents()); - expected1=[1,3,6]; - self.assertEqual(expected1,da2.getValues()); - pass - - def testDAIGetIdsEqualList1(self): - tab1=[5,-2,-4,-2,3,2,-2]; - da=DataArrayInt.New(); - da.setValues(tab1,7,1); - da2=da.getIdsEqualList([3,-2,0]); - self.assertEqual(4,da2.getNumberOfTuples()); - self.assertEqual(1,da2.getNumberOfComponents()); - expected1=[1,3,4,6]; - self.assertEqual(expected1,da2.getValues()); - pass - - def testDAFromNoInterlace1(self): - tab1=[1,11,21,31,41,2,12,22,32,42,3,13,23,33,43] - da=DataArrayInt.New(); - da.setValues(tab1,5,3); - da2=da.fromNoInterlace(); - expected1=[1,2,3,11,12,13,21,22,23,31,32,33,41,42,43] - self.assertEqual(5,da2.getNumberOfTuples()); - self.assertEqual(3,da2.getNumberOfComponents());# it's not a bug. Avoid to have 1 million components ! - self.assertEqual(expected1,da2.getValues()); - da3=da.convertToDblArr(); - da4=da3.fromNoInterlace(); - self.assertEqual(5,da4.getNumberOfTuples()); - self.assertEqual(3,da4.getNumberOfComponents());# it's not a bug. Avoid to have 1 million components ! - for i in xrange(15): - self.assertAlmostEqual(expected1[i],da4.getIJ(0,i),14); - pass - pass - - def testDAToNoInterlace1(self): - tab1=[1,2,3,11,12,13,21,22,23,31,32,33,41,42,43] - da=DataArrayInt.New(); - da.setValues(tab1,5,3); - da2=da.toNoInterlace(); - expected1=[1,11,21,31,41,2,12,22,32,42,3,13,23,33,43] - self.assertEqual(5,da2.getNumberOfTuples()); - self.assertEqual(3,da2.getNumberOfComponents());# it's not a bug. Avoid to have 1 million components ! - self.assertEqual(expected1,da2.getValues()); - da3=da.convertToDblArr(); - da4=da3.toNoInterlace(); - self.assertEqual(5,da4.getNumberOfTuples()); - self.assertEqual(3,da4.getNumberOfComponents());# it's not a bug. Avoid to have 1 million components ! - for i in xrange(15): - self.assertAlmostEqual(expected1[i],da4.getIJ(0,i),14); - pass - pass - - def testDAIsUniform1(self): - tab1=[1,1,1,1,1] - da=DataArrayInt.New(); - da.setValues(tab1,5,1); - self.assertTrue(da.isUniform(1)); - da.setIJ(2,0,2); - self.assertTrue(not da.isUniform(1)); - da.setIJ(2,0,1); - self.assertTrue(da.isUniform(1)); - da2=da.convertToDblArr(); - self.assertTrue(da2.isUniform(1.,1.e-12)); - da2.setIJ(1,0,1.+1.e-13); - self.assertTrue(da2.isUniform(1.,1.e-12)); - da2.setIJ(1,0,1.+1.e-11); - self.assertTrue(not da2.isUniform(1.,1.e-12)); - pass - - def testDADFromPolarToCart1(self): - tab1=[2.,0.2,2.5,0.7] - da=DataArrayDouble.New(); - da.setValues(tab1,2,2); - da2=da.fromPolarToCart(); - expected1=[1.9601331556824833,0.39733866159012243, 1.9121054682112213,1.6105442180942275] - for i in xrange(4): - self.assertAlmostEqual(expected1[i],da2.getIJ(0,i),13); - pass - pass - - def testDADFromCylToCart1(self): - tab1=[2.,0.2,4.,2.5,0.7,9.] - da=DataArrayDouble.New(); - da.setValues(tab1,2,3); - da2=da.fromCylToCart(); - expected1=[1.9601331556824833,0.39733866159012243,4., 1.9121054682112213,1.6105442180942275,9.] - for i in xrange(6): - self.assertAlmostEqual(expected1[i],da2.getIJ(0,i),13); - pass - pass - - def testDADFromSpherToCart1(self): - tab1=[2.,0.2,0.3,2.5,0.7,0.8] - da=DataArrayDouble.New(); - da.setValues(tab1,2,3); - da2=da.fromSpherToCart(); - expected1=[0.37959212195737485,0.11742160338765303,1.9601331556824833, 1.1220769624465328,1.1553337045129035,1.9121054682112213] - for i in xrange(6): - self.assertAlmostEqual(expected1[i],da2.getIJ(0,i),13); - pass - pass - - def testUnPolyze1(self): - elts=[0,1,2,3,4,5,6,7] - eltsV=elts; - mesh=MEDCouplingDataForTest.build3DTargetMesh_1(); - mesh.convertToPolyTypes(eltsV); - mesh.unPolyze(); - mesh2=MEDCouplingDataForTest.build3DTargetMesh_1(); - mesh.checkCoherency(); - self.assertTrue(mesh.isEqual(mesh2,1e-12)); - mesh.convertToPolyTypes(eltsV); - self.assertTrue(not mesh.isEqual(mesh2,1e-12)); - mesh.getNodalConnectivity().setIJ(0,6,10); - mesh.getNodalConnectivity().setIJ(0,7,9); - mesh.getNodalConnectivity().setIJ(0,8,12); - mesh.getNodalConnectivity().setIJ(0,9,13); - mesh.unPolyze(); - self.assertTrue(mesh.isEqual(mesh2,1e-12)); - mesh.convertToPolyTypes(eltsV); - mesh.getNodalConnectivity().setIJ(0,6,12); - mesh.getNodalConnectivity().setIJ(0,7,13); - mesh.getNodalConnectivity().setIJ(0,8,10); - mesh.getNodalConnectivity().setIJ(0,9,9); - mesh.unPolyze(); - self.assertTrue(mesh.isEqual(mesh2,1e-12)); - mesh.convertToPolyTypes(eltsV); - mesh.getNodalConnectivity().setIJ(0,6,12); - mesh.getNodalConnectivity().setIJ(0,7,10); - mesh.getNodalConnectivity().setIJ(0,8,13); - mesh.getNodalConnectivity().setIJ(0,9,9); - mesh.unPolyze(); - self.assertTrue(not mesh.isEqual(mesh2,1e-12)); - # Test for 2D mesh - mesh=MEDCouplingDataForTest.build2DTargetMesh_1(); - mesh2=MEDCouplingDataForTest.build2DTargetMesh_1(); - eltsV=eltsV[:5]; - mesh.convertToPolyTypes(eltsV); - self.assertTrue(not mesh.isEqual(mesh2,1e-12)); - mesh.unPolyze(); - self.assertTrue(mesh.isEqual(mesh2,1e-12)); - pass - - def testConvertDegeneratedCells1(self): - mesh=MEDCouplingDataForTest.build3DTargetMesh_1(); - conn=[0,1,3,3,9,10,12,12, 0,1,3,4,9,9,9,9, 1,1,1,1,10,12,9,10, 10,11,12,9,1,1,1,1] - mesh.allocateCells(4); - mesh.insertNextCell(NORM_HEXA8,8,conn[0:8]) - mesh.insertNextCell(NORM_HEXA8,8,conn[8:16]) - mesh.insertNextCell(NORM_HEXA8,8,conn[16:24]) - mesh.insertNextCell(NORM_HEXA8,8,conn[24:32]) - mesh.finishInsertingCells(); - mesh.checkCoherency(); - self.assertEqual(4,mesh.getNumberOfCells()); - self.assertEqual(NORM_HEXA8,mesh.getTypeOfCell(0)); - self.assertEqual(NORM_HEXA8,mesh.getTypeOfCell(1)); - self.assertEqual(NORM_HEXA8,mesh.getTypeOfCell(2)); - self.assertEqual(NORM_HEXA8,mesh.getTypeOfCell(3)); - f1=mesh.getMeasureField(True); - mesh.convertDegeneratedCells(); - mesh.checkCoherency(); - f2=mesh.getMeasureField(True); - self.assertEqual(4,mesh.getNumberOfCells()); - self.assertEqual(NORM_PENTA6,mesh.getTypeOfCell(0)); - self.assertEqual(NORM_PYRA5,mesh.getTypeOfCell(1)); - self.assertEqual(NORM_TETRA4,mesh.getTypeOfCell(2)); - self.assertEqual(NORM_PYRA5,mesh.getTypeOfCell(3)); - for i in xrange(4): - self.assertAlmostEqual(f1.getArray().getIJ(0,i),f2.getArray().getIJ(0,i),5); - pass - pass - - def testGetNodeIdsNearPoints1(self): - mesh=MEDCouplingDataForTest.build2DTargetMesh_1(); - coords=mesh.getCoords(); - tmp=DataArrayDouble.New(); - vals=[0.2,0.2,0.1,0.2,0.2,0.2] - tmp.setValues(vals,3,2); - tmp2=DataArrayDouble.Aggregate(coords,tmp); - mesh.setCoords(tmp2); - pts=[0.2,0.2,0.1,0.3,-0.3,0.7] - c=mesh.getNodeIdsNearPoint(pts[:2],1e-7); - self.assertEqual([4,9,11],c.getValues()); - c,cI=mesh.getNodeIdsNearPoints(pts,3,1e-7); - self.assertEqual([0,3,3,4],cI.getValues()); - self.assertEqual([4,9,11,6],c.getValues()); - c,cI=mesh.getNodeIdsNearPoints(pts,1e-7); - self.assertEqual([0,3,3,4],cI.getValues()); - self.assertEqual([4,9,11,6],c.getValues()); - c,cI=mesh.getNodeIdsNearPoints(DataArrayDouble.New(pts,3,2),1e-7); - self.assertEqual([0,3,3,4],cI.getValues()); - self.assertEqual([4,9,11,6],c.getValues()); - self.assertRaises(InterpKernelException,mesh.getNodeIdsNearPoints,DataArrayDouble.New(pts,2,3),1e-7); - pass - - def testFieldCopyTinyAttrFrom1(self): - f1=MEDCouplingFieldDouble.New(ON_CELLS,ONE_TIME); - f1.setName("f1"); - f1.setTimeTolerance(1.e-5); - f1.setDescription("f1Desc"); - f1.setTime(1.23,4,5); - f2=MEDCouplingFieldDouble.New(ON_CELLS,ONE_TIME); - f2.setName("f2"); - f2.setDescription("f2Desc"); - f2.setTime(6.78,9,10); - f2.setTimeTolerance(4.556e-12); - # - f1.copyTinyAttrFrom(f2); - self.assertAlmostEqual(4.556e-12,f1.getTimeTolerance(),24); - t,dt,it=f1.getTime() - self.assertAlmostEqual(6.78,t,12); - self.assertEqual(9,dt); - self.assertEqual(10,it); - self.assertTrue(f1.getName()=="f1");#name unchanged - self.assertTrue(f1.getDescription()=="f1Desc");#description unchanged - # - f1=MEDCouplingFieldDouble.New(ON_CELLS,NO_TIME); - f1.setName("f1"); - f1.setTimeTolerance(1.e-5); - f1.setDescription("f1Desc"); - f2=MEDCouplingFieldDouble.New(ON_CELLS,NO_TIME); - f2.setName("f2"); - f2.setDescription("f2Desc"); - f2.setTimeTolerance(4.556e-12); - # - f1.copyTinyAttrFrom(f2); - self.assertAlmostEqual(4.556e-12,f1.getTimeTolerance(),24); - self.assertTrue(f1.getName()=="f1");#name unchanged - self.assertTrue(f1.getDescription()=="f1Desc");#description unchanged - # - f1=MEDCouplingFieldDouble.New(ON_CELLS,CONST_ON_TIME_INTERVAL); - f1.setName("f1"); - f1.setTimeTolerance(1.e-5); - f1.setDescription("f1Desc"); - f1.setTime(1.23,4,5); - f1.setEndTime(5.43,2,1); - f2=MEDCouplingFieldDouble.New(ON_CELLS,CONST_ON_TIME_INTERVAL); - f2.setName("f2"); - f2.setDescription("f2Desc"); - f2.setTimeTolerance(4.556e-12); - f2.setTime(6.78,9,10); - f2.setEndTime(10.98,7,6); - # - f1.copyTinyAttrFrom(f2); - self.assertAlmostEqual(4.556e-12,f1.getTimeTolerance(),24); - self.assertTrue(f1.getName()=="f1");#name unchanged - self.assertTrue(f1.getDescription()=="f1Desc");#description unchanged - t,dt,it=f1.getTime() - self.assertAlmostEqual(6.78,t,12); - self.assertEqual(9,dt); - self.assertEqual(10,it); - t,dt,it=f1.getEndTime() - self.assertAlmostEqual(10.98,t,12); - self.assertEqual(7,dt); - self.assertEqual(6,it); - # - f1=MEDCouplingFieldDouble.New(ON_CELLS,LINEAR_TIME); - f1.setName("f1"); - f1.setTimeTolerance(1.e-5); - f1.setDescription("f1Desc"); - f1.setTime(1.23,4,5); - f1.setEndTime(5.43,2,1); - f2=MEDCouplingFieldDouble.New(ON_CELLS,LINEAR_TIME); - f2.setName("f2"); - f2.setDescription("f2Desc"); - f2.setTimeTolerance(4.556e-12); - f2.setTime(6.78,9,10); - f2.setEndTime(10.98,7,6); - # - f1.copyTinyAttrFrom(f2); - self.assertAlmostEqual(4.556e-12,f1.getTimeTolerance(),24); - self.assertTrue(f1.getName()=="f1");#name unchanged - self.assertTrue(f1.getDescription()=="f1Desc");#description unchanged - t,dt,it=f1.getTime() - self.assertAlmostEqual(6.78,t,12); - self.assertEqual(9,dt); - self.assertEqual(10,it); - t,dt,it=f1.getEndTime() - self.assertAlmostEqual(10.98,t,12); - self.assertEqual(7,dt); - self.assertEqual(6,it); - pass - - def testExtrudedMesh5(self): - coo1=[0.,1.,2.,3.5] - a=DataArrayDouble.New(); - a.setValues(coo1,4,1); - b=MEDCouplingCMesh.New(); - b.setCoordsAt(0,a); - c=b.buildUnstructured(); - self.assertEqual(1,c.getSpaceDimension()); - c.changeSpaceDimension(2); - # - d=DataArrayDouble.New(); - d.alloc(13,1); - d.iota(); - e=MEDCouplingCMesh.New(); - e.setCoordsAt(0,d); - f=e.buildUnstructured(); - g=f.getCoords().applyFunc(2,"3.5*IVec+x/6*3.14159265359*JVec"); - self.assertRaises(InterpKernelException,f.getCoords().applyFunc,2,"3.5*IVec+x/6*3.14159265359*KVec"); # KVec refers to component #2 and there is only 2 components ! - h=g.fromPolarToCart(); - f.setCoords(h); - i=c.buildExtrudedMesh(f,1); - self.assertEqual(52,i.getNumberOfNodes()); - tmp,tmp2,tmp3=i.mergeNodes(1e-9); - self.assertTrue(tmp2); - self.assertEqual(37,tmp3); - i.convertDegeneratedCells(); - i.checkCoherency(); - self.assertEqual(36,i.getNumberOfCells()); - self.assertEqual(37,i.getNumberOfNodes()); - self.assertEqual(12,i.getNumberOfCellsWithType(NORM_TRI3)); - self.assertEqual(24,i.getNumberOfCellsWithType(NORM_QUAD4)); - expected1=[0.25,0.75,2.0625] - j=i.getMeasureField(True); - for ii in xrange(12): - for k in xrange(3): - self.assertAlmostEqual(expected1[k],j.getIJ(0,ii*3+k),10); - pass - pass - expected2=[0.62200846792814113, 0.16666666666681595, 1.4513530918323276, 0.38888888888923495, 2.6293994326053212, 0.7045454545460802, 0.45534180126145435, 0.45534180126150181, 1.0624642029433926, 1.0624642029435025, 1.9248539780597826, 1.9248539780599816, 0.16666666666661334, 0.62200846792815856, 0.38888888888876294, 1.4513530918323678, 0.70454545454522521, 2.629399432605394, -0.16666666666674007, 0.62200846792812436, -0.38888888888906142, 1.4513530918322881, -0.70454545454576778, 2.6293994326052488, -0.45534180126154766, 0.45534180126140844, -1.0624642029436118, 1.0624642029432834, -1.9248539780601803, 1.9248539780595841, -0.62200846792817499, 0.1666666666665495, -1.451353091832408, 0.388888888888613, -2.6293994326054668, 0.70454545454495332, -0.62200846792810593, -0.16666666666680507, -1.451353091832247, -0.38888888888921297, -2.6293994326051746, -0.70454545454604123, -0.45534180126135926, -0.45534180126159562, -1.0624642029431723, -1.0624642029437235, -1.9248539780593836, -1.9248539780603811, -0.1666666666664828, -0.62200846792819242, -0.38888888888846079, -1.4513530918324489, -0.70454545454467987, -2.6293994326055397, 0.16666666666687083, -0.62200846792808862, 0.38888888888936374, -1.4513530918322073, 0.70454545454631357, -2.6293994326051022, 0.45534180126164348, -0.45534180126131207, 1.0624642029438327, -1.0624642029430627, 1.9248539780605791, -1.9248539780591853, 0.62200846792821063, -0.16666666666641802, 1.4513530918324888, -0.38888888888831086, 2.6293994326056125, -0.70454545454440853] - m=i.getBarycenterAndOwner(); - for i in xrange(72): - self.assertAlmostEqual(expected2[i],m.getIJ(0,i),10); - pass - # - pass - - def testExtrudedMesh6(self): - coo1=[0.,1.,2.,3.5] - a=DataArrayDouble.New(); - a.setValues(coo1,4,1); - b=MEDCouplingCMesh.New(); - b.setCoordsAt(0,a); - c=b.buildUnstructured(); - self.assertEqual(1,c.getSpaceDimension()); - c.changeSpaceDimension(2); - # - d=DataArrayDouble.New(); - d.alloc(5); - d.iota(); - e=MEDCouplingCMesh.New(); - e.setCoordsAt(0,d); - f=e.buildUnstructured(); - d2=f.getCoords().applyFunc("x*x/2"); - f.setCoords(d2); - f.changeSpaceDimension(2); - # - center=[0.,0.] - f.rotate(center,None,pi/3); - g=c.buildExtrudedMesh(f,0); - g.checkCoherency(); - expected1=[ 0.4330127018922193, 0.4330127018922193, 0.649519052838329, 1.2990381056766578, 1.299038105676658, 1.948557158514987, 2.1650635094610955, 2.1650635094610964, 3.2475952641916446, 3.031088913245533, 3.0310889132455352, 4.546633369868303 ] - f1=g.getMeasureField(True); - for i in xrange(12): - self.assertAlmostEqual(expected1[i],f1.getIJ(0,i),12); - pass - expected2=[0.625, 0.21650635094610962, 1.625, 0.21650635094610959, 2.8750000000000004, 0.21650635094610965, 1.1250000000000002, 1.0825317547305482, 2.125, 1.0825317547305482, 3.3750000000000004, 1.0825317547305484, 2.125, 2.8145825622994254, 3.125, 2.8145825622994254, 4.375, 2.8145825622994254, 3.6250000000000009, 5.4126587736527414, 4.625, 5.4126587736527414, 5.875, 5.4126587736527414] - f2=g.getBarycenterAndOwner(); - for i in xrange(24): - self.assertAlmostEqual(expected2[i],f2.getIJ(0,i),12); - pass - pass - - def testExtrudedMesh7(self): - coo1=[0.,1.,2.,3.5] - a=DataArrayDouble.New(); - a.setValues(coo1,4,1); - b=MEDCouplingCMesh.New(); - b.setCoordsAt(0,a); - c=b.buildUnstructured(); - self.assertEqual(1,c.getSpaceDimension()); - c.changeSpaceDimension(2); - # - d=DataArrayDouble.New(); - d.alloc(13,1); - d.iota(); - e=MEDCouplingCMesh.New(); - e.setCoordsAt(0,d); - f=e.buildUnstructured(); - g=f.getCoords().applyFunc(2,"3.5*IVec+x/6*3.14159265359*JVec"); - h=g.fromPolarToCart(); - f.setCoords(h); - i=c.buildExtrudedMesh(f,1); - self.assertEqual(52,i.getNumberOfNodes()); - tmp,tmp2,tmp3=i.mergeNodes(1e-9); - self.assertTrue(tmp2); - self.assertEqual(37,tmp3); - i.convertDegeneratedCells(); - vec1=[10.,0] - i.translate(vec1); - g2=h.applyFunc(3,"13.5/3.5*x*IVec+0*JVec+13.5/3.5*y*KVec"); - f.setCoords(g2); - i.changeSpaceDimension(3); - i3=i.buildExtrudedMesh(f,1); - f2=i3.getMeasureField(True); - tmp,tmp2,tmp3=i.mergeNodes(1e-9); - self.assertTrue(tmp2); - self.assertEqual(444,tmp3); - expected1=[1.327751058489274, 4.2942574094314701, 13.024068164857139, 1.3069177251569044, 4.1484240761012954, 12.297505664866796, 1.270833333332571, 3.8958333333309674, 11.039062499993179, 1.2291666666659207, 3.6041666666644425, 9.585937499993932, 1.1930822748415895, 3.3515759238941376, 8.3274943351204556, 1.1722489415082769, 3.2057425905609289, 7.6009318351210622, 1.1722489415082862, 3.2057425905609884, 7.6009318351213713, 1.1930822748416161, 3.3515759238943001, 8.3274943351212727, 1.2291666666659564, 3.6041666666646734, 9.5859374999950777, 1.2708333333326081, 3.8958333333311868, 11.039062499994293, 1.3069177251569224, 4.1484240761014384, 12.297505664867627, 1.3277510584902354, 4.2942574094346071, 13.024068164866796] - for ii in xrange(12): - for jj in xrange(36): - self.assertAlmostEqual(expected1[jj],f2.getIJ(0,ii*36+jj),9); - pass - # - pass - - def testSimplexize1(self): - m=MEDCouplingDataForTest.build3DSurfTargetMesh_1(); - m.convertToPolyTypes([3]); - da=m.simplexize(0); - self.assertEqual(7,da.getNumberOfTuples()); - self.assertEqual(1,da.getNumberOfComponents()); - expected2=[0,0,1,2,3,4,4] - for i in xrange(7): - self.assertEqual(expected2[i],da.getIJ(i,0)); - pass - m.checkCoherency(); - self.assertEqual(7,m.getNumberOfCells()); - self.assertEqual(NORM_TRI3,m.getTypeOfCell(0)); - self.assertEqual(NORM_TRI3,m.getTypeOfCell(1)); - self.assertEqual(NORM_TRI3,m.getTypeOfCell(2)); - self.assertEqual(NORM_TRI3,m.getTypeOfCell(3)); - self.assertEqual(NORM_POLYGON,m.getTypeOfCell(4)); - self.assertEqual(NORM_TRI3,m.getTypeOfCell(5)); - self.assertEqual(NORM_TRI3,m.getTypeOfCell(6)); - expected1=[0.125,0.125,0.125,0.125,0.25,0.125,0.125] - f=m.getMeasureField(False); - for i in xrange(7): - self.assertAlmostEqual(expected1[i]*sqrt(2.),f.getIJ(i,0),10); - pass - types=m.getAllGeoTypes(); - self.assertEqual([NORM_TRI3,NORM_POLYGON],types); - # - m=MEDCouplingDataForTest.build3DSurfTargetMesh_1(); - m.convertToPolyTypes([3]); - da=m.simplexize(1); - self.assertEqual(7,da.getNumberOfTuples()); - self.assertEqual(1,da.getNumberOfComponents()); - for i in xrange(7): - self.assertEqual(expected2[i],da.getIJ(i,0)); - pass - m.checkCoherency(); - types=m.getAllGeoTypes(); - self.assertEqual([NORM_TRI3,NORM_POLYGON],types); - self.assertEqual(7,m.getNumberOfCells()); - self.assertEqual(NORM_TRI3,m.getTypeOfCell(0)); - self.assertEqual(NORM_TRI3,m.getTypeOfCell(1)); - self.assertEqual(NORM_TRI3,m.getTypeOfCell(2)); - self.assertEqual(NORM_TRI3,m.getTypeOfCell(3)); - self.assertEqual(NORM_POLYGON,m.getTypeOfCell(4)); - self.assertEqual(NORM_TRI3,m.getTypeOfCell(5)); - self.assertEqual(NORM_TRI3,m.getTypeOfCell(6)); - f=m.getMeasureField(False); - for i in xrange(7): - self.assertAlmostEqual(expected1[i]*sqrt(2.),f.getIJ(i,0),10); - pass - pass - - def testSimplexize2(self): - m=MEDCouplingDataForTest.build3DSurfTargetMesh_1(); - m.convertToPolyTypes([3]); - f1=MEDCouplingFieldDouble.New(ON_CELLS,ONE_TIME); - f1.setMesh(m); - arr=DataArrayDouble.New(); - arr1=[10.,110.,20.,120.,30.,130.,40.,140.,50.,150.] - arr.setValues(arr1,5,2); - f1.setArray(arr); - # - f1.checkCoherency(); - self.assertTrue(f1.simplexize(0)); - f1.checkCoherency(); - expected1=[10.,110.,10.,110.,20.,120.,30.,130.,40.,140.,50.,150.,50.,150.] - for i in xrange(14): - self.assertAlmostEqual(expected1[i],f1.getIJ(0,i),10); - pass - self.assertTrue(not f1.simplexize(0)); - for i in xrange(14): - self.assertAlmostEqual(expected1[i],f1.getIJ(0,i),10); - pass - # - pass - - def testDAMeld1(self): - da1=DataArrayDouble.New(); - da1.alloc(7,2); - da2=DataArrayDouble.New(); - da2.alloc(7,1); - # - da1.fillWithValue(7.); - da2.iota(0.); - da3=da2.applyFunc(3,"10*x*IVec+100*x*JVec+1000*x*KVec"); - # - da1.setInfoOnComponent(0,"c0da1"); - da1.setInfoOnComponent(1,"c1da1"); - da3.setInfoOnComponent(0,"c0da3"); - da3.setInfoOnComponent(1,"c1da3"); - da3.setInfoOnComponent(2,"c2da3"); - # - da1C=da1.deepCpy(); - da1.meldWith(da3); - self.assertEqual(5,da1.getNumberOfComponents()); - self.assertEqual(7,da1.getNumberOfTuples()); - self.assertTrue(da1.getInfoOnComponent(0)=="c0da1"); - self.assertTrue(da1.getInfoOnComponent(1)=="c1da1"); - self.assertTrue(da1.getInfoOnComponent(2)=="c0da3"); - self.assertTrue(da1.getInfoOnComponent(3)=="c1da3"); - self.assertTrue(da1.getInfoOnComponent(4)=="c2da3"); - # - expected1=[7.,7.,0.,0.,0., 7.,7.,10.,100.,1000., 7.,7.,20.,200.,2000., 7.,7.,30.,300.,3000., 7.,7.,40.,400.,4000.,7.,7.,50.,500.,5000.,7.,7.,60.,600.,6000.] - for i in xrange(35): - self.assertAlmostEqual(expected1[i],da1.getIJ(0,i),10); - pass - # - dai1=da1C.convertToIntArr(); - dai3=da3.convertToIntArr(); - dai1.meldWith(dai3); - self.assertEqual(5,dai1.getNumberOfComponents()); - self.assertEqual(7,dai1.getNumberOfTuples()); - self.assertTrue(dai1.getInfoOnComponent(0)=="c0da1"); - self.assertTrue(dai1.getInfoOnComponent(1)=="c1da1"); - self.assertTrue(dai1.getInfoOnComponent(2)=="c0da3"); - self.assertTrue(dai1.getInfoOnComponent(3)=="c1da3"); - self.assertTrue(dai1.getInfoOnComponent(4)=="c2da3"); - for i in xrange(35): - self.assertEqual(int(expected1[i]),dai1.getIJ(0,i)); - pass - # test of static method DataArrayDouble::meld - da4=DataArrayDouble.Meld(da1C,da3); - tmp=DataArrayDouble.Meld([da1C,da3]); - self.assertTrue(da4.isEqual(tmp,1e-10)) - self.assertEqual(5,da4.getNumberOfComponents()); - self.assertEqual(7,da4.getNumberOfTuples()); - self.assertTrue(da4.getInfoOnComponent(0)=="c0da1"); - self.assertTrue(da4.getInfoOnComponent(1)=="c1da1"); - self.assertTrue(da4.getInfoOnComponent(2)=="c0da3"); - self.assertTrue(da4.getInfoOnComponent(3)=="c1da3"); - self.assertTrue(da4.getInfoOnComponent(4)=="c2da3"); - for i in xrange(35): - self.assertAlmostEqual(expected1[i],da4.getIJ(0,i),10); - pass - # test of static method DataArrayInt::meld - dai1=da1C.convertToIntArr(); - dai4=DataArrayInt.Meld(dai1,dai3); - tmp=DataArrayInt.Meld([dai1,dai3]); - self.assertTrue(dai4.isEqual(tmp)) - self.assertEqual(5,dai4.getNumberOfComponents()); - self.assertEqual(7,dai4.getNumberOfTuples()); - self.assertTrue(dai4.getInfoOnComponent(0)=="c0da1"); - self.assertTrue(dai4.getInfoOnComponent(1)=="c1da1"); - self.assertTrue(dai4.getInfoOnComponent(2)=="c0da3"); - self.assertTrue(dai4.getInfoOnComponent(3)=="c1da3"); - self.assertTrue(dai4.getInfoOnComponent(4)=="c2da3"); - for i in xrange(35): - self.assertEqual(int(expected1[i]),dai4.getIJ(0,i)); - pass - pass - - def testFieldMeld1(self): - m=MEDCouplingDataForTest.build3DSurfTargetMesh_1(); - f1=MEDCouplingFieldDouble.New(ON_CELLS,ONE_TIME); - f1.setMesh(m); - da1=DataArrayDouble.New(); - arr1=[12.,23.,34.,45.,56.] - da1.setValues(arr1,5,1); - da1.setInfoOnComponent(0,"aaa"); - f1.setArray(da1); - f1.setTime(3.4,2,1); - f1.checkCoherency(); - # - f2=f1.deepCpy(); - f2.setMesh(f1.getMesh()); - f2.checkCoherency(); - f2.changeNbOfComponents(2,5.); - f2.assign(5.); - f2.getArray().setInfoOnComponent(0,"bbb"); - f2.getArray().setInfoOnComponent(1,"ccc"); - f2.checkCoherency(); - # - f3=MEDCouplingFieldDouble.MeldFields(f2,f1); - f3.checkCoherency(); - self.assertEqual(5,f3.getNumberOfTuples()); - self.assertEqual(3,f3.getNumberOfComponents()); - self.assertTrue(f3.getArray().getInfoOnComponent(0)=="bbb"); - self.assertTrue(f3.getArray().getInfoOnComponent(1)=="ccc"); - self.assertTrue(f3.getArray().getInfoOnComponent(2)=="aaa"); - expected1=[5.,5.,12.,5.,5.,23.,5.,5.,34.,5.,5.,45.,5.,5.,56.] - for i in xrange(15): - self.assertAlmostEqual(expected1[i],f3.getIJ(0,i),12); - pass - time,dt,it=f3.getTime(); - self.assertAlmostEqual(3.4,time,14); - self.assertEqual(2,dt); - self.assertEqual(1,it); - # - f4=f2.buildNewTimeReprFromThis(NO_TIME,False); - f5=f1.buildNewTimeReprFromThis(NO_TIME,False); - f6=MEDCouplingFieldDouble.MeldFields(f4,f5); - f6.checkCoherency(); - self.assertEqual(5,f6.getNumberOfTuples()); - self.assertEqual(3,f6.getNumberOfComponents()); - self.assertTrue(f6.getArray().getInfoOnComponent(0)=="bbb"); - self.assertTrue(f6.getArray().getInfoOnComponent(1)=="ccc"); - self.assertTrue(f6.getArray().getInfoOnComponent(2)=="aaa"); - for i in xrange(15): - self.assertAlmostEqual(expected1[i],f6.getIJ(0,i),12); - pass - # - pass - - def testMergeNodes2(self): - m1=MEDCouplingDataForTest.build2DTargetMesh_1(); - m2=MEDCouplingDataForTest.build2DTargetMesh_1(); - vec=[0.002,0.] - m2.translate(vec); - # - m3=MEDCouplingUMesh.MergeUMeshes([m1,m2]); - da,b,newNbOfNodes=m3.mergeNodes2(0.01); - self.assertEqual(9,m3.getNumberOfNodes()); - expected1=[-0.299,-0.3, 0.201,-0.3, 0.701,-0.3, -0.299,0.2, 0.201,0.2, 0.701,0.2, -0.299,0.7, 0.201,0.7, 0.701,0.7] - for i in xrange(18): - self.assertAlmostEqual(expected1[i],m3.getCoords().getIJ(0,i),13); - pass - # - pass - - def testMergeField2(self): - m=MEDCouplingDataForTest.build2DTargetMesh_1(); - f1=MEDCouplingFieldDouble.New(ON_CELLS,ONE_TIME); - f1.setMesh(m); - arr=DataArrayDouble.New(); - arr.alloc(5,2); - arr.fillWithValue(2.); - f1.setArray(arr); - f2=MEDCouplingFieldDouble.New(ON_CELLS,ONE_TIME); - f2.setMesh(m); - arr=DataArrayDouble.New(); - arr.alloc(5,2); - arr.fillWithValue(5.); - f2.setArray(arr); - f3=MEDCouplingFieldDouble.New(ON_CELLS,ONE_TIME); - f3.setMesh(m); - arr=DataArrayDouble.New(); - arr.alloc(5,2); - arr.fillWithValue(7.); - f3.setArray(arr); - # - f4=MEDCouplingFieldDouble.MergeFields([f1,f2,f3]); - self.assertEqual(15,f4.getMesh().getNumberOfCells()); - expected1=[2.,2.,2.,2.,2.,2.,2.,2.,2.,2., 5.,5.,5.,5.,5.,5.,5.,5.,5.,5., 7.,7.,7.,7.,7.,7.,7.,7.,7.,7.] - for i in xrange(30): - self.assertAlmostEqual(expected1[i],f4.getIJ(0,i),13); - pass - # - pass - - def testDAIBuildComplement1(self): - a=DataArrayInt.New(); - tab=[3,1,7,8] - a.setValues(tab,4,1); - b=a.buildComplement(12); - self.assertEqual(8,b.getNumberOfTuples()); - self.assertEqual(1,b.getNumberOfComponents()); - expected1=[0,2,4,5,6,9,10,11] - for i in xrange(8): - self.assertEqual(expected1[i],b.getIJ(0,i)); - pass - pass - - def testDAIBuildUnion1(self): - a=DataArrayInt.New(); - tab1=[3,1,7,8] - a.setValues(tab1,4,1); - c=DataArrayInt.New(); - tab2=[5,3,0,18,8] - c.setValues(tab2,5,1); - b=a.buildUnion(c); - self.assertEqual(7,b.getNumberOfTuples()); - self.assertEqual(1,b.getNumberOfComponents()); - expected1=[0,1,3,5,7,8,18] - for i in xrange(7): - self.assertEqual(expected1[i],b.getIJ(0,i)); - pass - b=DataArrayInt.BuildUnion([a,c]); - self.assertEqual(7,b.getNumberOfTuples()); - self.assertEqual(1,b.getNumberOfComponents()); - expected1=[0,1,3,5,7,8,18] - for i in xrange(7): - self.assertEqual(expected1[i],b.getIJ(0,i)); - pass - pass - - def testDAIBuildIntersection1(self): - a=DataArrayInt.New(); - tab1=[3,1,7,8] - a.setValues(tab1,4,1); - c=DataArrayInt.New(); - tab2=[5,3,0,18,8] - c.setValues(tab2,5,1); - b=a.buildIntersection(c); - self.assertEqual(2,b.getNumberOfTuples()); - self.assertEqual(1,b.getNumberOfComponents()); - expected1=[3,8] - for i in xrange(2): - self.assertEqual(expected1[i],b.getIJ(0,i)); - pass - b=DataArrayInt.BuildIntersection([a,c]); - self.assertEqual(2,b.getNumberOfTuples()); - self.assertEqual(1,b.getNumberOfComponents()); - expected1=[3,8] - for i in xrange(2): - self.assertEqual(expected1[i],b.getIJ(0,i)); - pass - pass - - def testDAIDeltaShiftIndex1(self): - a=DataArrayInt.New(); - tab=[1,3,6,7,7,9,15] - a.setValues(tab,7,1); - b=a.deltaShiftIndex(); - self.assertEqual(6,b.getNumberOfTuples()); - self.assertEqual(1,b.getNumberOfComponents()); - expected1=[2,3,1,0,2,6] - for i in xrange(6): - self.assertEqual(expected1[i],b.getIJ(0,i)); - pass - pass - - def testDaDoubleSelectByTupleIdSafe1(self): - a=DataArrayDouble.New(); - arr1=[1.1,11.1,2.1,12.1,3.1,13.1,4.1,14.1,5.1,15.1,6.1,16.1,7.1,17.1] - a.setValues(arr1,7,2); - a.setInfoOnComponent(0,"toto"); - a.setInfoOnComponent(1,"tata"); - # - arr2=[4,2,0,6,5] - b=a.selectByTupleIdSafe(arr2); - self.assertEqual(5,b.getNumberOfTuples()); - self.assertEqual(2,b.getNumberOfComponents()); - self.assertTrue(b.getInfoOnComponent(0)=="toto"); - self.assertTrue(b.getInfoOnComponent(1)=="tata"); - expected1=[5.1,15.1,3.1,13.1,1.1,11.1,7.1,17.1,6.1,16.1] - for i in xrange(10): - self.assertAlmostEqual(expected1[i],b.getIJ(0,i),14); - pass - arr4=[4,-1,0,6,5] - self.assertRaises(InterpKernelException,a.selectByTupleIdSafe,arr4); - arr5=[4,2,0,6,7] - self.assertRaises(InterpKernelException,a.selectByTupleIdSafe,arr5); - # - c=DataArrayInt.New(); - arr3=[1,11,2,12,3,13,4,14,5,15,6,16,7,17] - c.setValues(arr3,7,2); - c.setInfoOnComponent(0,"toto"); - c.setInfoOnComponent(1,"tata"); - d=c.selectByTupleIdSafe(arr2); - self.assertEqual(5,d.getNumberOfTuples()); - self.assertEqual(2,d.getNumberOfComponents()); - self.assertTrue(d.getInfoOnComponent(0)=="toto"); - self.assertTrue(d.getInfoOnComponent(1)=="tata"); - expected2=[5,15,3,13,1,11,7,17,6,16] - for i in xrange(10): - self.assertEqual(expected2[i],d.getIJ(0,i)); - pass - self.assertRaises(InterpKernelException,c.selectByTupleIdSafe,arr4); - self.assertRaises(InterpKernelException,c.selectByTupleIdSafe,arr5); - pass - - def testAreCellsIncludedIn1(self): - m=MEDCouplingDataForTest.build3DSurfTargetMesh_1(); - pt=[1,3] - m2=m.buildPartOfMySelf(pt,True); - ret,tmp=m.areCellsIncludedIn(m2,0) - self.assertTrue(ret); - self.assertEqual(2,tmp.getNumberOfTuples()); - self.assertEqual(1,tmp.getNumberOfComponents()); - self.assertEqual(pt[0],tmp.getIJ(0,0)); - self.assertEqual(pt[1],tmp.getIJ(0,1)); - ret,tmp=m2.areCellsIncludedIn(m,0) - self.assertTrue(not ret); - m3=MEDCouplingUMesh.MergeUMeshesOnSameCoords(m,m2) - c,cI=m3.findCommonCells(2,m.getNumberOfCells()) - self.assertTrue(c.isEqual(DataArrayInt([1,5,3,6]))) - self.assertTrue(cI.isEqual(DataArrayInt([0,2,4]))) - pass - - def testSwigErrorProtection1(self): - m=MEDCouplingDataForTest.build3DTargetMesh_1(); - m.rotate([0.,0.,0.],[0.3,0.6,1.2],0.37) - m.rotate([0.,0.,0.],[0.3,6,1.2],0.37) - self.assertRaises(InterpKernelException,m.rotate,[0.,0.,0.],(0.3,6,"1.2"),0.37) - self.assertRaises(InterpKernelException,m.rotate,[0.,"0.",0.],[0.3,0.6,1.2],0.37) - self.assertRaises(InterpKernelException,m.rotate,[0.,0.,0.],[0.3,'0.6',1.2],0.37) - m2=m.buildPartOfMySelf([2,5],True) - m3=m.buildPartOfMySelf((2,5),True) - self.assertTrue(m2.isEqual(m3,1e-12)) - self.assertRaises(InterpKernelException,m.buildPartOfMySelf,[2,5.],True) - da1=m.getCoords().keepSelectedComponents([1]) - da2=m.getCoords().keepSelectedComponents((1,)) - self.assertTrue(da1.isEqual(da2,1e-12)) - self.assertRaises(InterpKernelException,m.getCoords().keepSelectedComponents,["1"]) - pass - - def testDAIBuildSubstraction1(self): - a=DataArrayInt.New() - aa=[2,3,6,8,9] - a.setValues(aa,5,1) - b=DataArrayInt.New() - bb=[1,3,5,9,11] - b.setValues(bb,5,1) - self.assertEqual([2,6,8],a.buildSubstraction(b).getValues()) - pass - - def testBuildOrthogonalField2(self): - m=MEDCouplingDataForTest.build2DTargetMesh_1(); - d1=DataArrayInt.New(); - d2=DataArrayInt.New(); - d3=DataArrayInt.New(); - d4=DataArrayInt.New(); - m1=m.buildDescendingConnectivity(d1,d2,d3,d4); - # - f1=m1.buildOrthogonalField(); - da1=f1.getArray(); - self.assertEqual(2,da1.getNumberOfComponents()); - self.assertEqual(13,da1.getNumberOfTuples()); - # - expected1=[-1.,0.,0.,1.,1.,0.,0.,-1.,0.707106781186548,0.707106781186548,0.,-1.,0.,1.,1.,0.,0.,1.,1.,0.,-1.,0.,0.,1.,1.,0.]; - for i in xrange(26): - self.assertAlmostEqual(expected1[i],da1.getIJ(0,i),14); - pass - pass - - def testSwigErrorProtection2(self): - m=MEDCouplingDataForTest.build2DTargetMesh_1(); - coo=m.getCoords() - c=m.getNodalConnectivity() - ci=m.getNodalConnectivityIndex() - del m - self.assertEqual(2,coo.getNumberOfComponents()); - self.assertEqual(6,ci.getNumberOfTuples()); - self.assertEqual(23,c.getNumberOfTuples()); - m=MEDCouplingDataForTest.build2DTargetMesh_1(); - f=m.getMeasureField(True) - c=f.getArray() - del f - self.assertEqual(1,c.getNumberOfComponents()); - m=MEDCouplingCMesh.New() - x=DataArrayDouble.New() - x.setValues([1.,2.,4.],3,1) - m.setCoordsAt(0,x) - del x - xx=m.getCoordsAt(0) - del m - self.assertEqual(3,xx.getNumberOfTuples()); - # - m=MEDCouplingDataForTest.build2DTargetMesh_1(); - f=m.getMeasureField(True) - m2=f.getMesh() - del m - del f - self.assertEqual(5,m2.getNumberOfCells()); - pass - - def testUMInsertNextCell1(self): - targetCoords=[-0.3,-0.3, 0.2,-0.3, 0.7,-0.3, -0.3,0.2, 0.2,0.2, 0.7,0.2, -0.3,0.7, 0.2,0.7, 0.7,0.7 ] - targetConn=[0,3,4,1, 1,4,2, 4,5,2, 6,7,4,3, 7,8,5,4] - targetMesh=MEDCouplingUMesh.New(); - targetMesh.allocateCells(5); - self.assertRaises(InterpKernelException,targetMesh.insertNextCell,NORM_QUAD4,4,targetConn[0:4]) - targetMesh.setMeshDimension(2); - targetMesh.insertNextCell(NORM_QUAD4,4,targetConn[0:4]) - self.assertRaises(InterpKernelException,targetMesh.insertNextCell,NORM_TETRA4,4,targetConn[0:4]) - self.assertRaises(InterpKernelException,targetMesh.insertNextCell,NORM_SEG2,2,targetConn[0:2]) - self.assertRaises(InterpKernelException,targetMesh.insertNextCell,NORM_POINT1,1,targetConn[0:1]) - targetMesh.insertNextCell(NORM_TRI3,3,targetConn[4:7]) - targetMesh.insertNextCell(NORM_TRI3,3,targetConn[7:10]) - targetMesh.insertNextCell(NORM_QUAD4,4,targetConn[10:14]) - targetMesh.insertNextCell(NORM_QUAD4,4,targetConn[14:18]) - targetMesh.finishInsertingCells(); - myCoords=DataArrayDouble.New(); - myCoords.setValues(targetCoords,9,2); - targetMesh.setCoords(myCoords); - targetMesh.checkCoherency(); - pass - - def testFieldOperatorDivDiffComp1(self): - m=MEDCouplingDataForTest.build2DTargetMesh_1(); - m1,d0,d1,d2,d3=m.buildDescendingConnectivity(); - # - f1=m1.buildOrthogonalField(); - arr1=[2.,3.,4.,5.,6.,7.,8.,9.,10.,11.,12.,13.,14.] - arr=DataArrayDouble.New(); - arr.setValues(arr1,13,1); - f2=MEDCouplingFieldDouble.New(ON_CELLS); - f2.setArray(arr); - f2.setMesh(m1); - f2.checkCoherency(); - # - f3=f1/f2; - self.assertRaises(InterpKernelException,f2.__div__,f1) - f3.checkCoherency(); - f1/=f2; - #self.assertRaises(InterpKernelException,f2.__idiv__,f1) # mem leaks - self.assertTrue(f1.isEqual(f3,1e-10,1e-10)); - expected1=[-0.5, 0.0, 0.0, 0.33333333333333331, 0.25, 0.0, 0.0, -0.20000000000000001, 0.117851130197758, 0.117851130197758, 0.0, -0.14285714285714285, 0.0, 0.125, 0.1111111111111111, 0.0, 0.0, 0.10000000000000001, 0.090909090909090912, 0.0, -0.083333333333333329, 0.0, 0.0, 0.076923076923076927, 0.071428571428571425, 0.0] - for i in xrange(26): - self.assertAlmostEqual(expected1[i],f3.getIJ(0,i),10); - pass - pass - - def testDARearrange1(self): - da1=DataArrayInt.New(); - da1.alloc(12,1); - da1.iota(0); - # - self.assertEqual(12,da1.getNbOfElems()); - self.assertEqual(1,da1.getNumberOfComponents()); - self.assertEqual(12,da1.getNumberOfTuples()); - da1.rearrange(4); - self.assertEqual(12,da1.getNbOfElems()); - self.assertEqual(4,da1.getNumberOfComponents()); - self.assertEqual(3,da1.getNumberOfTuples()); - for i in xrange(12): - self.assertEqual(i,da1.getIJ(0,i)); - # - da1.rearrange(6); - self.assertEqual(12,da1.getNbOfElems()); - self.assertEqual(6,da1.getNumberOfComponents()); - self.assertEqual(2,da1.getNumberOfTuples()); - for i in xrange(12): - self.assertEqual(i,da1.getIJ(0,i)); - # - self.assertRaises(InterpKernelException,da1.rearrange,7); - # - da1.rearrange(12); - self.assertEqual(12,da1.getNbOfElems()); - self.assertEqual(12,da1.getNumberOfComponents()); - self.assertEqual(1,da1.getNumberOfTuples()); - for i in xrange(12): - self.assertEqual(i,da1.getIJ(0,i)); - # - da1.rearrange(3); - self.assertEqual(12,da1.getNbOfElems()); - self.assertEqual(3,da1.getNumberOfComponents()); - self.assertEqual(4,da1.getNumberOfTuples()); - for i in xrange(12): - self.assertEqual(i,da1.getIJ(0,i)); - #double - da2=da1.convertToDblArr(); - st=da2.getHiddenCppPointer() - # - self.assertEqual(12,da2.getNbOfElems()); - self.assertEqual(3,da2.getNumberOfComponents()); - self.assertEqual(4,da2.getNumberOfTuples()); - da2.rearrange(4); - self.assertEqual(12,da2.getNbOfElems()); - self.assertEqual(4,da2.getNumberOfComponents()); - self.assertEqual(3,da2.getNumberOfTuples()); - for i in xrange(12): - self.assertAlmostEqual(float(i),da2.getIJ(0,i),14); - # - da2.rearrange(6); - self.assertEqual(12,da2.getNbOfElems()); - self.assertEqual(6,da2.getNumberOfComponents()); - self.assertEqual(2,da2.getNumberOfTuples()); - for i in xrange(12): - self.assertAlmostEqual(float(i),da2.getIJ(0,i),14); - # - self.assertRaises(InterpKernelException,da2.rearrange,7); - # - da2.rearrange(1); - self.assertEqual(st,da2.getHiddenCppPointer()) - self.assertEqual(12,da2.getNbOfElems()); - self.assertEqual(1,da2.getNumberOfComponents()); - self.assertEqual(12,da2.getNumberOfTuples()); - for i in xrange(12): - self.assertAlmostEqual(float(i),da2.getIJ(0,i),14); - # - da2.rearrange(3); - self.assertEqual(12,da2.getNbOfElems()); - self.assertEqual(3,da2.getNumberOfComponents()); - self.assertEqual(4,da2.getNumberOfTuples()); - for i in xrange(12): - self.assertAlmostEqual(float(i),da2.getIJ(0,i),14); - pass - - def testDARearrange2(self): - da1=DataArrayInt.New(); - arr=[1,2,3,2,2,3,5,1,5,5,2,2] - da1.setValues(arr,4,3); - s=da1.getDifferentValues(); - expected1=DataArrayInt([1,2,3,5]) - self.assertTrue(expected1.isEqual(s)); - pass - - def testSwigErrorProtection3(self): - da=DataArrayInt.New() - da.setValues([1,2,3,4,0,0,0,0,0,0,0,0],4,3) - self.assertEqual([1, 2, 3, 4, 0, 0, 0, 0, 0, 0, 0, 0],da.getValues()) - self.assertEqual(3,da.getNumberOfComponents()); - self.assertEqual(4,da.getNumberOfTuples()); - da=DataArrayInt.New() - da.setValues(((1,2,3),(4,4,3),(0,0,0),(0,0,0)),4,3) - self.assertEqual([1, 2, 3, 4, 4, 3, 0, 0, 0, 0, 0, 0],da.getValues()) - self.assertEqual(3,da.getNumberOfComponents()); - self.assertEqual(4,da.getNumberOfTuples()); - da.setValues((10*[1]+290*[2])[:12],4,3) - self.assertEqual(10*[1]+[2,2],da.getValues()) - self.assertEqual(3,da.getNumberOfComponents()); - self.assertEqual(4,da.getNumberOfTuples()); - # - da=DataArrayDouble.New() - da.setValues([1,2,3.,4,0,0,0,0,0,0,0,0],4,3) - self.assertEqual([1., 2., 3., 4., 0., 0., 0., 0., 0., 0., 0., 0.],da.getValues()) - self.assertEqual(3,da.getNumberOfComponents()); - self.assertEqual(4,da.getNumberOfTuples()); - da=DataArrayDouble.New() - da.setValues(((1,2,3),(4.,4,3),(0,0,0),(0,0,0)),4,3) - self.assertEqual([1., 2., 3., 4., 4., 3., 0., 0., 0., 0., 0., 0.],da.getValues()) - self.assertEqual(3,da.getNumberOfComponents()); - self.assertEqual(4,da.getNumberOfTuples()); - da.setValues((10*[1]+290*[2])[:12],4,3) - self.assertEqual(10*[1.]+[2.,2.],da.getValues()) - self.assertEqual(3,da.getNumberOfComponents()); - self.assertEqual(4,da.getNumberOfTuples()); - pass - - def testDAIBuildPermutationArr1(self): - a=DataArrayInt.New() - a.setValues([4,5,6,7,8],5,1) - b=DataArrayInt.New() - b.setValues([5,4,8,6,7],5,1) - c=a.buildPermutationArr(b) - self.assertEqual([1,0,4,2,3],c.getValues()) - self.assertTrue(a.isEqualWithoutConsideringStrAndOrder(b)) - b.setIJ(0,0,9) - self.assertTrue(not a.isEqualWithoutConsideringStrAndOrder(b)) - self.assertRaises(InterpKernelException,a.buildPermutationArr,b) - a.setIJ(3,0,4) - b.setIJ(0,0,5) - b.setIJ(4,0,4)#a==[4,5,6,4,8] and b==[5,4,8,6,4] - self.assertTrue(a.isEqualWithoutConsideringStrAndOrder(b)) - c=a.buildPermutationArr(b) - self.assertEqual([1,3,4,2,3],c.getValues()) - d=b.convertToDblArr() - expect3=[4,4,5,6,8] - b.sort() - self.assertEqual(expect3,b.getValues()) - d.sort() - self.assertEqual(5,d.getNumberOfTuples()); - self.assertEqual(1,d.getNumberOfComponents()); - for i in xrange(5): - self.assertAlmostEqual(float(expect3[i]),d.getIJ(i,0),14); - pass - pass - - def testAreCellsIncludedIn2(self): - myName="Vitoo"; - m=MEDCouplingDataForTest.build3DSurfTargetMesh_1(); - m2=m.buildPartOfMySelf([],True); - self.assertEqual(0,m2.getNumberOfCells()); - self.assertEqual(3,m2.getSpaceDimension()); - self.assertEqual(2,m2.getMeshDimension()); - m2.setName(myName); - test,tmp=m.areCellsIncludedIn(m2,0) - self.assertTrue(test); - self.assertEqual(myName,tmp.getName()); - self.assertEqual(0,tmp.getNumberOfTuples()) - self.assertEqual(1,tmp.getNumberOfComponents()) - pass - - def testUMeshGetPartBarycenterAndOwner1(self): - m1=MEDCouplingDataForTest.build2DTargetMesh_1(); - part1=[1,0,4]; - part=DataArrayInt.New(); - part.setValues(part1,3,1); - b=m1.getPartBarycenterAndOwner(part); - self.assertEqual(2,b.getNumberOfComponents()); - self.assertEqual(3,b.getNumberOfTuples()); - expected1=[0.36666666666666665,-0.13333333333333333,-0.05,-0.05,0.45,0.45]; - for i in xrange(6): - self.assertAlmostEqual(expected1[i],b.getIJ(0,i),14); - pass - pass - - def testUMeshGetPartMeasureField1(self): - m1=MEDCouplingDataForTest.build2DTargetMesh_1(); - part1=[1,0,4]; - part=DataArrayInt.New(); - part.setValues(part1,3,1); - b=m1.getPartMeasureField(True,part); - self.assertEqual(1,b.getNumberOfComponents()); - self.assertEqual(3,b.getNumberOfTuples()); - expected1=[0.125,0.25,0.25]; - for i in xrange(3): - self.assertAlmostEqual(expected1[i],b.getIJ(0,i),14); - pass - pass - - def testUMeshBuildPartOrthogonalField1(self): - m1=MEDCouplingDataForTest.build2DTargetMesh_1(); - m1.changeSpaceDimension(3); - part1=[1,0,4]; - part=DataArrayInt.New(); - part.setValues(part1,3,1); - b=m1.buildPartOrthogonalField(part); - self.assertEqual(3,b.getArray().getNumberOfComponents()); - self.assertEqual(3,b.getArray().getNumberOfTuples()); - expected1=[0.,0.,-1.,0.,0.,-1.,0.,0.,-1.]; - for i in xrange(9): - self.assertAlmostEqual(expected1[i],b.getArray().getIJ(0,i),14); - pass - pass - - def testUMeshGetTypesOfPart1(self): - m1=MEDCouplingDataForTest.build2DTargetMesh_1(); - part1=[0,3,4]; - p1=DataArrayInt.New() - p1.setValues(part1,3,1) - s=m1.getTypesOfPart(p1); - self.assertEqual([NORM_QUAD4],s); - part2=[2,2,2,1]; - p2=DataArrayInt.New() - p2.setValues(part2,4,1) - s=m1.getTypesOfPart(p2); - self.assertEqual([NORM_TRI3],s); - part3=[3,2,1]; - p3=DataArrayInt.New() - p3.setValues(part3,3,1) - s=m1.getTypesOfPart(p3); - self.assertEqual(s,[NORM_TRI3,NORM_QUAD4]); - pass - - def testUMeshKeepCellIdsByType1(self): - m1=MEDCouplingDataForTest.build2DTargetMesh_1(); - part1=[0,3,4] - p1=DataArrayInt.New() - p1.setValues(part1,3,1) - p1.setName("p1") - a=m1.keepCellIdsByType(NORM_TRI3,p1); - self.assertEqual("p1",a.getName()) - self.assertEqual(1,a.getNumberOfComponents()); - self.assertEqual(0,a.getNumberOfTuples()); - # - part2=[3,2,0,2,4] - p2=DataArrayInt.New() - p2.setValues(part2,5,1) - p2.setName("p2") - a=m1.keepCellIdsByType(NORM_TRI3,p2); - self.assertEqual("p2",a.getName()) - self.assertEqual(1,a.getNumberOfComponents()); - self.assertEqual(2,a.getNumberOfTuples()); - self.assertEqual(2,a.getIJ(0,0)); - self.assertEqual(2,a.getIJ(1,0)); - # - a=m1.keepCellIdsByType(NORM_QUAD4,p2); - self.assertEqual("p2",a.getName()) - self.assertEqual(1,a.getNumberOfComponents()); - self.assertEqual(3,a.getNumberOfTuples()); - self.assertEqual(3,a.getIJ(0,0)); - self.assertEqual(0,a.getIJ(1,0)); - self.assertEqual(4,a.getIJ(2,0)); - pass - - def testSwigErrorDaIntSelectByTupleId1(self): - a=DataArrayInt.New(); - arr1=[1,11,2,12,3,13,4,14,5,15,6,16,7,17] - a.setValues(arr1,7,2); - a.setInfoOnComponent(0,"toto"); - a.setInfoOnComponent(1,"tata"); - # - arr2=[4,2,0,6,5] - b=a.selectByTupleId(arr2); - self.assertEqual(5,b.getNumberOfTuples()); - self.assertEqual(2,b.getNumberOfComponents()); - self.assertTrue(b.getInfoOnComponent(0)=="toto"); - self.assertTrue(b.getInfoOnComponent(1)=="tata"); - expected1=[5,15,3,13,1,11,7,17,6,16] - self.assertEqual(expected1,b.getValues()) - # - a2=DataArrayInt.New() - a2.setValues(arr2,5,1) - b=a.selectByTupleId(a2); - self.assertEqual(5,b.getNumberOfTuples()); - self.assertEqual(2,b.getNumberOfComponents()); - self.assertTrue(b.getInfoOnComponent(0)=="toto"); - self.assertTrue(b.getInfoOnComponent(1)=="tata"); - expected1=[5,15,3,13,1,11,7,17,6,16] - self.assertEqual(expected1,b.getValues()) - pass - - def testSwigErrorRenum(self): - da=DataArrayDouble.New() - da.setValues([7.,107.,8.,108.,9.,109.,10.,110.,11.,111.,12.,112.,13.,113.,14.,114.,15.,115.,16.,116.],10,2) - d=DataArrayInt.New() - d.setValues([0,2,3,1,4,5,6,8,7,9],10,1) - da.renumberInPlace(d) - da.renumber(d) - pass - - def testSwigGetItem1(self): - da=DataArrayInt.New() - da.alloc(16,3) - da.rearrange(1) - da.iota(7) - da.rearrange(3) - da.setInfoOnComponent(0,"X [m]") - da.setInfoOnComponent(1,"Y [m]") - da.setInfoOnComponent(2,"Z [km]") - da2=da[5:-1] - self.assertEqual([22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51],da2.getValues()) - da2=da[4] - self.assertEqual([19, 20, 21],da2.getValues()) - try: - da2=da[4:17] - except InterpKernelException as e: - self.assertTrue(True) - else: - self.assertTrue(False) - pass - da2=da[5:-2,2] - self.assertEqual([24, 27, 30, 33, 36, 39, 42, 45, 48],da2.getValues()) - da2=da[5:8,:] - self.assertEqual([22, 23, 24, 25, 26, 27, 28, 29, 30],da2.getValues()) - da2=da[:] - self.assertTrue(da2.isEqual(da)) - da2=da[:,:] - self.assertTrue(da2.isEqual(da)) - try: - da2=da[:,:,:] - except InterpKernelException as e: - self.assertTrue(True) - else: - self.assertTrue(False) - pass - self.assertTrue(da[5:8,-2].isEqualWithoutConsideringStr(DataArrayInt([23,26,29]))) - da2=da[5:8,:-2] - self.assertEqual([22, 25, 28],da2.getValues()) - try: - da2=da[5:-18,2] - except InterpKernelException as e: - self.assertTrue(True) - else: - self.assertTrue(False) - pass - da2=da[5:5,2] - self.assertEqual([],da2.getValues()) - pass - - def testSwigGetItem2(self): - da=DataArrayDouble.New() - da.alloc(16,3) - da.rearrange(1) - da.iota(7) - da.rearrange(3) - da.setInfoOnComponent(0,"X [m]") - da.setInfoOnComponent(1,"Y [m]") - da.setInfoOnComponent(2,"Z [km]") - da2=da[5:-1] - self.assertEqual([22., 23., 24., 25., 26., 27., 28., 29., 30., 31., 32., 33., 34., 35., 36., 37., 38., 39., 40., 41., 42., 43., 44., 45., 46., 47., 48., 49., 50., 51.],da2.getValues()) - da2=da[4] - self.assertEqual([19., 20., 21],da2.getValues()) - try: - da2=da[4:17] - except InterpKernelException as e: - self.assertTrue(True) - else: - self.assertTrue(False) - pass - da2=da[5:-2,2] - self.assertEqual([24., 27., 30., 33., 36., 39., 42., 45., 48.],da2.getValues()) - da2=da[5:8,:] - self.assertEqual([22., 23., 24., 25., 26., 27., 28., 29., 30.],da2.getValues()) - da2=da[:] - self.assertTrue(da2.isEqual(da,1e-12)) - da2=da[:,:] - self.assertTrue(da2.isEqual(da,1e-12)) - try: - da2=da[:,:,:] - except InterpKernelException as e: - self.assertTrue(True) - else: - self.assertTrue(False) - pass - self.assertTrue(da[5:8,-2].isEqualWithoutConsideringStr(DataArrayDouble([23.,26.,29.]),1e-12)) - da2=da[5:8,:-2] - self.assertEqual([22., 25., 28.],da2.getValues()) - try: - da2=da[5:-18,2] - except InterpKernelException as e: - self.assertTrue(True) - else: - self.assertTrue(False) - pass - da2=da[5:5,2] - self.assertEqual([],da2.getValues()) - pass - - def testSwigSetItem1(self): - da=DataArrayInt.New() - da.alloc(20,1) - da.iota(7) - da.rearrange(5) - da.setInfoOnComponent(0,"X [m]") ; da.setInfoOnComponent(1,"Y [km]") ; da.setInfoOnComponent(2,"Y [m]") - da.setInfoOnComponent(3,"Z [W]") ; da.setInfoOnComponent(4,"ZZ [km]") ; - da[:,2]=3 - self.assertEqual([7, 8, 3, 10, 11, 12, 13, 3, 15, 16, 17, 18, 3, 20, 21, 22, 23, 3, 25, 26],da.getValues()) - da.rearrange(1) ; da.iota(7) ; da.rearrange(5) - da[2]=3 - self.assertEqual([7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 3, 3, 3, 3, 3, 22, 23, 24, 25, 26],da.getValues()) - da.rearrange(1) ; da.iota(7) ; da.rearrange(5) - da[[0,3]]=-1 - self.assertEqual([-1, -1, -1, -1, -1, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, -1, -1, -1, -1, -1],da.getValues()) - da.rearrange(1) ; da.iota(7) ; da.rearrange(5) - da[:,[1,3,4]]=-3 - self.assertEqual([7, -3, 9, -3, -3, 12, -3, 14, -3, -3, 17, -3, 19, -3, -3, 22, -3, 24, -3, -3],da.getValues()) - da.rearrange(1) ; da.iota(7) ; da.rearrange(5) - da2=DataArrayInt.New() ; da2.setValues([0,2,3],3,1) - da[da2]=-7 - self.assertEqual([-7, -7, -7, -7, -7, 12, 13, 14, 15, 16, -7, -7, -7, -7, -7, -7, -7, -7, -7, -7],da.getValues()) - da.rearrange(1) ; da.iota(7) ; da.rearrange(5) - da[da2,-2:]=-7 - self.assertEqual([7, 8, 9, -7, -7, 12, 13, 14, 15, 16, 17, 18, 19, -7, -7, 22, 23, 24, -7, -7],da.getValues()) - # Let's test with DAI right hand side - da1=DataArrayInt.New() - da1.setValues([25,26,27,125,126,127],2,3) - # - da.rearrange(1) ; da.iota(7) ; da.rearrange(5) - da[-2:,1:4]=da1 - self.assertEqual([7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 25, 26, 27, 21, 22, 125, 126, 127, 26],da.getValues()) - da.rearrange(1) ; da.iota(7) ; da.rearrange(5) - da[1:,3]=[225,226,227] - self.assertEqual([7, 8, 9, 10, 11, 12, 13, 14, 225, 16, 17, 18, 19, 226, 21, 22, 23, 24, 227, 26],da.getValues()) - da.rearrange(1) ; da.iota(7) ; da.rearrange(5) - da[1,2:]=[225,226,227] - self.assertEqual([7, 8, 9, 10, 11, 12, 13, 225, 226, 227, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26],da.getValues()) - da.rearrange(1) ; da.iota(7) ; da.rearrange(5) - da[da2,-2:]=[88,99,1010,1111,1212,1313] - self.assertEqual([7, 8, 9, 88, 99, 12, 13, 14, 15, 16, 17, 18, 19, 1010, 1111, 22, 23, 24, 1212, 1313],da.getValues()) - da.rearrange(1) ; da.iota(7) ; da.rearrange(5) - da3=DataArrayInt.New(); da3.setValues([88,99,1010,1111,1212,1313],3,2) - da[da2,-2:]=da3 - self.assertEqual([7, 8, 9, 88, 99, 12, 13, 14, 15, 16, 17, 18, 19, 1010, 1111, 22, 23, 24, 1212, 1313],da.getValues()) - da.rearrange(1) ; da.iota(7) ; da.rearrange(5) - da[da2,[0,2]]=da3 - self.assertEqual([88, 8, 99, 10, 11, 12, 13, 14, 15, 16, 1010, 18, 1111, 20, 21, 1212, 23, 1313, 25, 26],da.getValues()) - da.rearrange(1) ; da.iota(7) ; da.rearrange(5) - da[da2,0:3:2]=da3 - self.assertEqual([88, 8, 99, 10, 11, 12, 13, 14, 15, 16, 1010, 18, 1111, 20, 21, 1212, 23, 1313, 25, 26],da.getValues()) - da.rearrange(1) ; da.iota(7) ; da.rearrange(5) - da[da2,0:3:2]=-8 - self.assertEqual([-8, 8, -8, 10, 11, 12, 13, 14, 15, 16, -8, 18, -8, 20, 21, -8, 23, -8, 25, 26],da.getValues()) - pass - - def testSwigSetItem2(self): - da=DataArrayDouble.New() - da.alloc(20,1) - da.iota(7) - da.rearrange(5) - da.setInfoOnComponent(0,"X [m]") ; da.setInfoOnComponent(1,"Y [km]") ; da.setInfoOnComponent(2,"Y [m]") - da.setInfoOnComponent(3,"Z [W]") ; da.setInfoOnComponent(4,"ZZ [km]") ; - da[:,2]=3. - self.assertEqual([7., 8., 3., 10., 11., 12., 13., 3., 15., 16., 17., 18., 3., 20., 21., 22., 23., 3., 25., 26.],da.getValues()) - da.rearrange(1) ; da.iota(7) ; da.rearrange(5) - da[2]=3. - self.assertEqual([7., 8., 9., 10., 11., 12., 13., 14., 15., 16., 3., 3., 3., 3., 3., 22., 23., 24., 25., 26.],da.getValues()) - da.rearrange(1) ; da.iota(7) ; da.rearrange(5) - da[[0,3]]=-1. - self.assertEqual([-1., -1., -1., -1., -1., 12., 13., 14., 15., 16., 17., 18., 19., 20., 21., -1., -1., -1., -1., -1.],da.getValues()) - da.rearrange(1) ; da.iota(7) ; da.rearrange(5) - da[:,[1,3,4]]=-3. - self.assertEqual([7., -3., 9., -3., -3., 12., -3., 14., -3., -3., 17., -3., 19., -3., -3., 22., -3., 24., -3., -3.],da.getValues()) - da.rearrange(1) ; da.iota(7) ; da.rearrange(5) - da2=DataArrayInt.New() ; da2.setValues([0,2,3],3,1) - da[da2]=-7. - self.assertEqual([-7., -7., -7., -7., -7., 12., 13., 14., 15., 16., -7., -7., -7., -7., -7., -7., -7., -7., -7., -7.],da.getValues()) - da.rearrange(1) ; da.iota(7) ; da.rearrange(5) - da[da2,-2:]=-7 - self.assertEqual([7., 8., 9., -7., -7., 12., 13., 14., 15., 16., 17., 18., 19., -7., -7., 22., 23., 24., -7., -7.],da.getValues()) - # Let's test with DAI right hand side - da1=DataArrayDouble.New() - da1.setValues([25,26,27,125,126,127],2,3) - # - da.rearrange(1) ; da.iota(7) ; da.rearrange(5) - da[-2:,1:4]=da1 - self.assertEqual([7., 8., 9., 10., 11., 12., 13., 14., 15., 16., 17., 25., 26., 27., 21., 22., 125., 126., 127., 26.],da.getValues()) - da.rearrange(1) ; da.iota(7) ; da.rearrange(5) - da[1:,3]=[225.,226.,227.] - self.assertEqual([7., 8., 9., 10., 11., 12., 13., 14., 225., 16., 17., 18., 19., 226., 21., 22., 23., 24., 227., 26.],da.getValues()) - da.rearrange(1) ; da.iota(7) ; da.rearrange(5) - da[1,2:]=[225,226,227] - self.assertEqual([7., 8., 9., 10., 11., 12., 13., 225., 226., 227., 17., 18., 19., 20., 21., 22., 23., 24., 25., 26.],da.getValues()) - da.rearrange(1) ; da.iota(7) ; da.rearrange(5) - da[da2,-2:]=[88,99,1010,1111,1212,1313] - self.assertEqual([7., 8., 9., 88., 99., 12., 13., 14., 15., 16., 17., 18., 19., 1010., 1111., 22., 23., 24., 1212., 1313.],da.getValues()) - da.rearrange(1) ; da.iota(7) ; da.rearrange(5) - da3=DataArrayDouble.New(); da3.setValues([88,99,1010,1111,1212,1313],3,2) - da[da2,-2:]=da3 - self.assertEqual([7., 8., 9., 88., 99., 12., 13., 14., 15., 16., 17., 18., 19., 1010., 1111., 22., 23., 24., 1212., 1313.],da.getValues()) - da.rearrange(1) ; da.iota(7) ; da.rearrange(5) - da[da2,[0,2]]=da3 - self.assertEqual([88., 8., 99., 10., 11., 12., 13., 14., 15., 16., 1010., 18., 1111., 20., 21., 1212., 23., 1313., 25., 26.],da.getValues()) - da.rearrange(1) ; da.iota(7) ; da.rearrange(5) - da[da2,0:3:2]=da3 - self.assertEqual([88., 8., 99., 10., 11., 12., 13., 14., 15., 16., 1010., 18., 1111., 20., 21., 1212., 23., 1313., 25., 26.],da.getValues()) - da.rearrange(1) ; da.iota(7) ; da.rearrange(5) - da[da2,0:3:2]=-8. - self.assertEqual([-8., 8., -8., 10., 11., 12., 13., 14., 15., 16., -8., 18., -8., 20., 21., -8., 23., -8., 25., 26.],da.getValues()) - pass - - def testSwigDADOp(self): - da=DataArrayDouble.New() - da.alloc(12,1) - da.iota(7.) - da1=DataArrayDouble.New() - da1.alloc(12,1) - da1.iota(8.) - da2=da+da1 - self.assertEqual([15., 17., 19., 21., 23., 25., 27., 29., 31., 33., 35., 37.],da2.getValues()) - da2=da+3 - da3=3+da - self.assertTrue(da2.isEqual(da3,1e-12)) - da2=da-1. - self.assertEqual([6.0, 7.0, 8.0, 9.0, 10.0, 11.0, 12.0, 13.0, 14.0, 15.0, 16.0, 17.0],da2.getValues()) - da2=1-da - self.assertEqual([-6.0, -7.0, -8.0, -9.0, -10.0, -11.0, -12.0, -13.0, -14.0, -15.0, -16.0, -17.0],da2.getValues()) - da2=da*3 - self.assertEqual([21.0, 24.0, 27.0, 30.0, 33.0, 36.0, 39.0, 42.0, 45.0, 48.0, 51.0, 54.0],da2.getValues()) - da2=3.*da - self.assertEqual([21.0, 24.0, 27.0, 30.0, 33.0, 36.0, 39.0, 42.0, 45.0, 48.0, 51.0, 54.0],da2.getValues()) - da2=da*da1 - self.assertEqual([56.0, 72.0, 90.0, 110.0, 132.0, 156.0, 182.0, 210.0, 240.0, 272.0, 306.0, 342.0],da2.getValues()) - da2=da/4. - self.assertEqual([1.75, 2.0, 2.25, 2.5, 2.75, 3.0, 3.25, 3.5, 3.75, 4.0, 4.25, 4.5],da2.getValues()) - da3=4./da - da4=da3*da2 - self.assertTrue(da4.isUniform(1.,1e-12)) - st1=da.getHiddenCppPointer() - da+=1 - st2=da.getHiddenCppPointer() - self.assertEqual(st1,st2) - self.assertTrue(da.isEqual(da1,1e-12)) - da-=8 - st2=da.getHiddenCppPointer() - self.assertEqual(st1,st2) - self.assertEqual(range(12),da.getValues()) - da+=da1 - st2=da.getHiddenCppPointer() - self.assertEqual(st1,st2) - self.assertEqual([8.0, 10.0, 12.0, 14.0, 16.0, 18.0, 20.0, 22.0, 24.0, 26.0, 28.0, 30.0],da.getValues()) - da*=0.5 - st2=da.getHiddenCppPointer() - self.assertEqual(st1,st2) - self.assertEqual([4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0, 11.0, 12.0, 13.0, 14.0, 15.0],da.getValues()) - da*=da1 - st2=da.getHiddenCppPointer() - self.assertEqual(st1,st2) - self.assertEqual([32.0, 45.0, 60.0, 77.0, 96.0, 117.0, 140.0, 165.0, 192.0, 221.0, 252.0, 285.0],da.getValues()) - da/=da1 - self.assertEqual(st1,st2) - self.assertEqual([4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0, 11.0, 12.0, 13.0, 14.0, 15.0],da.getValues()) - da/=2 - st2=da.getHiddenCppPointer() - self.assertEqual(st1,st2) - self.assertEqual([2.0, 2.5, 3.0, 3.5, 4.0, 4.5, 5.0, 5.5, 6.0, 6.5, 7.0, 7.5],da.getValues()) - da.rearrange(3) - da5=DataArrayDouble.New() - da5.setValues([5.,4.,3.,2.],4,1) - da*=da5 # it works with unmathing number of compo - st2=da.getHiddenCppPointer() - self.assertEqual(st1,st2) - self.assertEqual([10.0, 12.5, 15.0, 14.0, 16.0, 18.0, 15.0, 16.5, 18.0, 13.0, 14.0, 15.0],da.getValues()) - # - da.alloc(30,1) - da.iota(7.) - da.rearrange(3) - ids=DataArrayInt.New() - ids.setValues([3,4,7],3,1) - da[ids,:]=[5.,8.,9.] - self.assertEqual([7.,8.,9.,10.,11.,12.,13.,14.,15.,5.,8.,9.,5.,8.,9.,22.,23.,24.,25.,26.,27.,5.,8.,9.,31.,32.,33.,34.,35.,36.0],da.getValues()) - # - da.rearrange(1) ; da.iota(7) ; da.rearrange(3) - da[ids,[1,2]]=[5,8] - self.assertEqual([7.,8.,9.,10.,11.,12.,13.,14.,15.,16.,5.,8.,19.,5.,8.,22.,23.,24.,25.,26.,27.,28.,5.,8.,31.,32.,33.,34.,35.,36.],da.getValues()) - pass - - def testSwigDAIOp(self): - da=DataArrayInt.New() - da.alloc(12,1) - da.iota(7) - da1=DataArrayInt.New() - da1.alloc(12,1) - da1.iota(8) - da2=da+da1 - self.assertEqual([15,17,19,21,23,25,27,29,31,33,35,37],da2.getValues()) - da2=da+3 - da3=3+da - self.assertTrue(da2.isEqual(da3)) - da2=da-1 - self.assertEqual([6,7,8,9,10,11,12,13,14,15,16,17],da2.getValues()) - da2=1-da - self.assertEqual([-6,-7,-8,-9,-10,-11,-12,-13,-14,-15,-16,-17],da2.getValues()) - da2=da*3 - self.assertEqual([21,24,27,30,33,36,39,42,45,48,51,54.0],da2.getValues()) - da2=3*da - self.assertEqual([21,24,27,30,33,36,39,42,45,48,51,54.0],da2.getValues()) - da2=da*da1 - self.assertEqual([56,72,90,110,132,156,182,210,240,272,306,342.0],da2.getValues()) - da2=da/4 - self.assertEqual([1,2,2,2,2,3,3,3,3,4,4,4],da2.getValues()) - da3=4/da - da4=da3*da2 - self.assertTrue(da4.isUniform(0)) - st1=da.getHiddenCppPointer() - da+=1 - st2=da.getHiddenCppPointer() - self.assertEqual(st1,st2) - self.assertTrue(da.isEqual(da1)) - da-=8 - st2=da.getHiddenCppPointer() - self.assertEqual(st1,st2) - self.assertEqual(range(12),da.getValues()) - da+=da1 - st2=da.getHiddenCppPointer() - self.assertEqual(st1,st2) - self.assertEqual([8,10,12,14,16,18,20,22,24,26,28,30],da.getValues()) - da/=2 - st2=da.getHiddenCppPointer() - self.assertEqual(st1,st2) - self.assertEqual([4,5,6,7,8,9,10,11,12,13,14,15],da.getValues()) - da*=da1 - st2=da.getHiddenCppPointer() - self.assertEqual(st1,st2) - self.assertEqual([32,45,60,77,96,117,140,165,192,221,252,285],da.getValues()) - da/=da1 - self.assertEqual(st1,st2) - self.assertEqual([4,5,6,7,8,9,10,11,12,13,14,15],da.getValues()) - da/=2 - st2=da.getHiddenCppPointer() - self.assertEqual(st1,st2) - self.assertEqual([2,2, 3,3, 4,4, 5,5, 6,6, 7,7],da.getValues()) - da.rearrange(3) - da5=DataArrayInt.New() - da5.setValues([5,4,3,2],4,1) - da*=da5 # it works with unmathing number of compo - st2=da.getHiddenCppPointer() - self.assertEqual(st1,st2) - self.assertEqual([10,10, 15,12,16,16,15,15, 18,12,14,14],da.getValues()) - da%=6 - st2=da.getHiddenCppPointer() - self.assertEqual(st1,st2) - self.assertEqual([4,4,3,0,4,4,3,3,0,0,2,2],da.getValues()) - # - da.alloc(30,1) - da.iota(7) - da.rearrange(3) - ids=DataArrayInt.New() - ids.setValues([3,4,7],3,1) - da[ids,:]=[5,8,9] - self.assertEqual([7,8,9,10,11,12,13,14,15,5,8,9,5,8,9,22,23,24,25,26,27,5,8,9,31,32,33,34,35,36],da.getValues()) - # - da.rearrange(1) ; da.iota(7) ; da.rearrange(3) - da[ids,[1,2]]=[5,8] - self.assertEqual([7,8,9,10,11,12,13,14,15,16,5,8,19,5,8,22,23,24,25,26,27,28,5,8,31,32,33,34,35,36],da.getValues()) - pass - - def testSwigDAIOp2(self): - da=DataArrayInt.New() - st=da.getHiddenCppPointer() - da.alloc(10,3) - da.rearrange(1) - da.iota(0) - da.rearrange(3) - da[:,1]+=4 - da[-2:,2]+=10 - da[-2:,2]+=10 - da[:,2]+=da[:,0] - da[da[0],:]=7 - self.assertEqual(st,da.getHiddenCppPointer()) - self.assertEqual(da.getValues(),[7,7,7,3,8,8,7,7,7,9,14,20,12,17,26,7,7,7,18,23,38,21,26,44,24,29,70,27,32,76]) - pass - - def testSwigDAIOp3(self): - da=DataArrayInt.New() - self.assertRaises(InterpKernelException,da.__len__) - self.assertRaises(InterpKernelException,da.__int__) - for elt in da: - self.assertTrue(False) - pass - da.alloc(12,3) - da.rearrange(1) ; da.fillWithZero() - l1=list(da) - self.assertEqual(36,len(da)); - da.rearrange(3) - tmp=da[0] - self.assertRaises(InterpKernelException,tmp.__int__) - self.assertEqual(12,len(da)); - l=list(da) - for elt in enumerate(l): - elt[1][2]=elt[0] - pass - ref=[0,0,0,0,0,1,0,0,2,0,0,3,0,0,4,0,0,5,0,0,6,0,0,7,0,0,8,0,0,9,0,0,10,0,0,11] - self.assertEqual(ref,da.getValues()); - da.rearrange(1) - l=[int(elt) for elt in l1] - self.assertEqual(ref,da.getValues()); - self.assertEqual(11,int(da[-1:])) - pass - - def testSwigDADOp3(self): - da=DataArrayDouble.New() - self.assertRaises(InterpKernelException,da.__len__) - self.assertRaises(InterpKernelException,da.__float__) - for elt in da: - self.assertTrue(False) - pass - da.alloc(12,3) - da.rearrange(1) ; da.fillWithZero() - l1=list(da) - self.assertEqual(36,len(da)); - da.rearrange(3) - tmp=da[0] - self.assertRaises(InterpKernelException,tmp.__float__) - self.assertEqual(12,len(da)); - l=list(da) - for elt in enumerate(l): - elt[1][2]=elt[0] - pass - ref=[0.,0.,0.,0.,0.,1.,0.,0.,2.,0.,0.,3.,0.,0.,4.,0.,0.,5.,0.,0.,6.,0.,0.,7.,0.,0.,8.,0.,0.,9.,0.,0.,10.,0.,0.,11.] - self.assertEqual(ref,da.getValues()); - da.rearrange(1) - l=[float(elt) for elt in l1] - self.assertEqual(ref,da.getValues()); - self.assertEqual(11.,float(da[-1:])) - pass - - def testSwigDataArrayIntIterator1(self): - da=DataArrayInt.New() - da.alloc(12,1) - da.iota(2) - da.rearrange(3) - # __getitem__ testing - li=[] - for it in da: - li+=it[1:] - pass - self.assertEqual([3, 4, 6, 7, 9, 10, 12, 13],li) - li=[] - for it in da: - li+=[it[-1]] - pass - self.assertEqual([4, 7, 10, 13],li) - li=[] - for it in da: - li+=it[[2,1,0]] - pass - self.assertEqual([4, 3, 2, 7, 6, 5, 10, 9, 8, 13, 12, 11],li) - # __setitem__ testing - da3=da.deepCpy() - da2=DataArrayInt.New() - da2.alloc(12,1) - da2.iota(2002) - da2.rearrange(3) - it2=da2.__iter__() - i=0 - for it in da: - pt=it2.next() - it[:]=pt - pass - self.assertTrue(da.isEqual(da2)) - da=da3 - da3=da.deepCpy() - # - for it in da: - it[:]=5 - pass - da.rearrange(1) - self.assertTrue(da.isUniform(5)) - da=da3 - da3=da.deepCpy() - # - for it in da: - it[:]=[8,9,12] - pass - self.assertEqual([8, 9, 12, 8, 9, 12, 8, 9, 12, 8, 9, 12],da.getValues()) - da=da3 - da3=da.deepCpy() - # - for it in da: - it[2]=[7] - pass - self.assertEqual([2, 3, 7, 5, 6, 7, 8, 9, 7, 11, 12, 7],da.getValues()) - pass - - def testSwigDataArrayDoubleIterator1(self): - da=DataArrayDouble.New() - da.alloc(12,1) - da.iota(2) - da.rearrange(3) - # __getitem__ testing - li=[] - for it in da: - li+=it[1:] - pass - self.assertEqual([3, 4, 6, 7, 9, 10, 12, 13],li) - li=[] - for it in da: - li+=[it[-1]] - pass - self.assertEqual([4, 7, 10, 13],li) - li=[] - for it in da: - li+=it[[2,1,0]] - pass - self.assertEqual([4, 3, 2, 7, 6, 5, 10, 9, 8, 13, 12, 11],li) - # __setitem__ testing - da3=da.deepCpy() - da2=DataArrayDouble.New() - da2.alloc(12,1) - da2.iota(2002) - da2.rearrange(3) - it2=da2.__iter__() - i=0 - for it in da: - pt=it2.next() - it[:]=pt - pass - self.assertTrue(da.isEqual(da2,1e-12)) - da=da3 - da3=da.deepCpy() - # - for it in da: - it[:]=5 - pass - da.rearrange(1) - self.assertTrue(da.isUniform(5,1e-12)) - da=da3 - da3=da.deepCpy() - # - for it in da: - it[:]=[8,9,12] - pass - self.assertEqual([8, 9, 12, 8, 9, 12, 8, 9, 12, 8, 9, 12],da.getValues()) - da=da3 - da3=da.deepCpy() - # - for it in da: - it[2]=[7] - pass - self.assertEqual([2, 3, 7, 5, 6, 7, 8, 9, 7, 11, 12, 7],da.getValues()) - pass - - def testSwigUMeshIterator1(self): - m=MEDCouplingDataForTest.build2DTargetMesh_1() - li1=[] - li2=[] - for cell in m: - li1+=cell.getAllConn()[1:] - li2+=[cell.getType()] - pass - self.assertEqual(li1,[0, 3, 4, 1, 1, 4, 2, 4, 5, 2, 6, 7, 4, 3, 7, 8, 5, 4]) - self.assertEqual(li2,[4, 3, 3, 4, 4]) - pass - - def testSwigUMeshIterator2(self): - m=MEDCouplingDataForTest.build2DTargetMesh_1() - self.assertRaises(InterpKernelException,m.cellsByType); - m.rearrange2ConsecutiveCellTypes() - li1=[] - li2=[] - li3=[] - for cellsByType in m.cellsByType(): - li1.append(cellsByType.getType()) - li2.append(cellsByType.getNumberOfElems()) - temp=[] - for cell in cellsByType: - t=[None,None] - t[0]=cell.getType() - t[1]=cell.getAllConn()[1:] - temp.append(t) - pass - li3.append(temp) - pass - self.assertEqual(li1,[4, 3]) - self.assertEqual(li2,[3, 2]) - self.assertEqual(li3,[[[4, (0, 3, 4, 1)], [4, (6, 7, 4, 3)], [4, (7, 8, 5, 4)]], [[3, (1, 4, 2)], [3, (4, 5, 2)]]]) - pass - - def testDAIAggregateMulti1(self): - a=DataArrayInt.New() - a.setValues(range(4),2,2) - a.setName("aa") - b=DataArrayInt.New() - b.setValues(range(6),3,2) - c=DataArrayInt.Aggregate([a,b]) - self.assertEqual(range(4)+range(6),c.getValues()) - self.assertEqual("aa",c.getName()) - self.assertEqual(5,c.getNumberOfTuples()) - self.assertEqual(2,c.getNumberOfComponents()) - pass - - def testMergeUMeshes2(self): - m1=MEDCouplingDataForTest.build3DSurfTargetMesh_1(); - m2=MEDCouplingDataForTest.build3DSurfTargetMesh_1(); - m3=MEDCouplingDataForTest.build3DSurfTargetMesh_1(); - # - vec1=[0,2,3] - m2_2=m2.buildPartOfMySelf(vec1,False); - vec2=[1,1] - m3_2=m3.buildPartOfMySelf(vec2,False); - # - ms=[m1,m2_2,m3_2]; - # - self.assertRaises(InterpKernelException,MEDCouplingUMesh.MergeUMeshes,ms+[None]); - self.assertRaises(InterpKernelException,MEDCouplingUMesh.MergeUMeshes,ms+[3.4]) - m4=MEDCouplingUMesh.MergeUMeshes(ms); - m4.checkCoherency(); - self.assertEqual(10,m4.getNumberOfCells()); - self.assertEqual(20,m4.getNumberOfNodes()); - self.assertEqual(45,m4.getMeshLength()); - m4bis=MEDCouplingMesh.MergeMeshes(ms); - self.assertTrue(m4.isEqual(m4bis,1e-12)) - del m4bis - # - vec3=[0,1,2,3,4] - m4_1=m4.buildPartOfMySelf(vec3,False); - m4_1.setName(m1.getName()); - self.assertTrue(m4_1.isEqual(m1,1e-12)); - # - vec4=[5,6,7] - m4_2=m4.buildPartOfMySelf(vec4,False); - cellCor,nodeCor=m4_2.checkGeoEquivalWith(m2_2,10,1e-12); - # - vec5=[8,9] - m4_3=m4.buildPartOfMySelf(vec5,False); - self.assertEqual(2,m4_3.getNumberOfCells()); - self.assertEqual(3,m4_3.getNumberOfNodes()); - m3_2.zipCoords(); - m4_3.setName(m3_2.getName()); - self.assertTrue(m4_3.isEqual(m3_2,1e-12)); - # - pass - - def testBuild0DMeshFromCoords1(self): - sourceCoords=[-0.3,-0.3,0., 0.7,-0.3,0., -0.3,0.7,0., 0.7,0.7,0.] - coo=DataArrayDouble.New(); - coo.setValues(sourceCoords,4,3); - coo.setName("My0D"); - m=MEDCouplingUMesh.Build0DMeshFromCoords(coo); - m.checkCoherency(); - self.assertEqual(4,m.getNumberOfNodes()); - self.assertEqual(4,m.getNumberOfCells()); - self.assertEqual(3,m.getSpaceDimension()); - self.assertEqual(0,m.getMeshDimension()); - types1=m.getAllGeoTypes(); - self.assertEqual([NORM_POINT1],types1); - for i in xrange(4): - conn=m.getNodeIdsOfCell(i); - self.assertEqual([i],conn); - self.assertTrue(NORM_POINT1==m.getTypeOfCell(i)); - pass - self.assertEqual(m.getName(),"My0D"); - pass - - def testDescriptionInMeshTimeUnit1(self): - text1="totoTTEDD"; - m=MEDCouplingDataForTest.build2DTargetMesh_1(); - m.setDescription(text1); - self.assertEqual(m.getDescription(),text1); - m2=m.deepCpy(); - self.assertTrue(m.isEqual(m2,1e-12)); - self.assertEqual(m2.getDescription(),text1); - m2.setDescription("ggg"); - self.assertTrue(not m.isEqual(m2,1e-12)); - # - f=MEDCouplingFieldDouble.New(ON_CELLS,ONE_TIME); - f.setTimeUnit(text1); - self.assertEqual(f.getTimeUnit(),text1); - f2=f.deepCpy(); - self.assertEqual(f2.getTimeUnit(),text1); - # - pass - - def testMultiFields1(self): - mfs=MEDCouplingDataForTest.buildMultiFields_1(); - ms=mfs.getMeshes(); - dms,refs=mfs.getDifferentMeshes() - das=mfs.getArrays(); - das2,refs2=mfs.getDifferentArrays() - self.assertEqual(5,len(mfs.getFields())) - self.assertEqual(1,len(mfs.getFields()[0].getArrays())); - self.assertEqual(2,len(mfs.getFields()[1].getArrays())); - self.assertEqual(1,len(mfs.getFields()[2].getArrays())); - self.assertEqual(1,len(mfs.getFields()[3].getArrays())); - self.assertEqual(1,len(mfs.getFields()[4].getArrays())); - self.assertEqual(5,len(ms)); - self.assertEqual(2,len(dms)); - self.assertEqual(6,len(das)); - self.assertEqual(5,len(das2)); - mfs2=mfs.deepCpy(); - self.assertTrue(mfs.isEqual(mfs2,1e-12,1e-12)) - pass - - def testFieldOverTime1(self): - fs=MEDCouplingDataForTest.buildMultiFields_2(); - self.assertRaises(InterpKernelException,MEDCouplingFieldOverTime.New,fs); - f4bis=fs[4].buildNewTimeReprFromThis(ONE_TIME,False); - fs[4]=f4bis; - self.assertRaises(InterpKernelException,MEDCouplingFieldOverTime.New,fs); - f4bis.setTime(2.7,20,21); - fot=MEDCouplingFieldOverTime.New(fs); - dt=fot.getDefinitionTimeZone(); - hs=dt.getHotSpotsTime(); - self.assertEqual(6,len(hs)); - expected1=[0.2,0.7,1.2,1.35,1.7,2.7] - for i in xrange(6): - self.assertAlmostEqual(expected1[i],hs[i],12); - pass - meshId,arrId,arrIdInField,fieldId=dt.getIdsOnTimeRight(0.2); - self.assertEqual(0,meshId); - self.assertEqual(0,arrId); - self.assertEqual(0,arrIdInField); - self.assertEqual(0,fieldId); - # - meshId,arrId,arrIdInField,fieldId=dt.getIdsOnTimeRight(0.7); - self.assertEqual(0,meshId); - self.assertEqual(1,arrId); - self.assertEqual(0,arrIdInField); - self.assertEqual(1,fieldId); - # - meshId,arrId,arrIdInField,fieldId=dt.getIdsOnTimeLeft(1.2);#**** WARNING left here - self.assertEqual(0,meshId); - self.assertEqual(2,arrId); - self.assertEqual(1,arrIdInField); - self.assertEqual(1,fieldId); - # - meshId,arrId,arrIdInField,fieldId=dt.getIdsOnTimeRight(1.2);#**** WARNING right again here - self.assertEqual(1,meshId); - self.assertEqual(3,arrId); - self.assertEqual(0,arrIdInField); - self.assertEqual(2,fieldId); - # - meshId,arrId,arrIdInField,fieldId=dt.getIdsOnTimeRight(1.35); - self.assertEqual(1,meshId); - self.assertEqual(3,arrId); - self.assertEqual(0,arrIdInField); - self.assertEqual(2,fieldId); - # - meshId,arrId,arrIdInField,fieldId=dt.getIdsOnTimeRight(1.7); - self.assertEqual(0,meshId); - self.assertEqual(3,arrId); - self.assertEqual(0,arrIdInField); - self.assertEqual(3,fieldId); - # - meshId,arrId,arrIdInField,fieldId=dt.getIdsOnTimeRight(2.7); - self.assertEqual(1,meshId); - self.assertEqual(4,arrId); - self.assertEqual(0,arrIdInField); - self.assertEqual(4,fieldId); - # - dt2=MEDCouplingDefinitionTime(); - self.assertTrue(not dt2.isEqual(dt)); - dt2.assign(dt); - dt2.assign(dt);#to check memory management - self.assertTrue(dt2.isEqual(dt)); - # - dt3=MEDCouplingDefinitionTime(); - # - pass - - def testDAICheckAndPreparePermutation1(self): - vals1=[9,10,0,6,4,11,3,7]; - expect1=[5,6,0,3,2,7,1,4]; - vals2=[9,10,0,6,10,11,3,7]; - da=DataArrayInt.New(); - da.setValues(vals1,8,1); - da2=da.checkAndPreparePermutation(); - self.assertEqual(8,da2.getNumberOfTuples()); - self.assertEqual(1,da2.getNumberOfComponents()); - for i in xrange(8): - self.assertEqual(expect1[i],da2.getIJ(i,0)); - pass - # - da=DataArrayInt.New(); - da.alloc(8,1); - da.iota(0); - da2=da.checkAndPreparePermutation(); - self.assertEqual(8,da2.getNumberOfTuples()); - self.assertEqual(1,da2.getNumberOfComponents()); - self.assertTrue(da2.isIdentity()); - # - da=DataArrayInt.New(); - da.alloc(8,1); - da.setValues(vals2,8,1); - self.assertRaises(InterpKernelException,da.checkAndPreparePermutation); - pass - - def testDAIChangeSurjectiveFormat1(self): - vals1=[0,3,2,3,2,2,1,2] - expected1=[0,1,2,6,8] - expected2=[0, 6, 2,4,5,7, 1,3] - da=DataArrayInt.New(); - da.setValues(vals1,8,1); - # - da2,da2I=da.changeSurjectiveFormat(4); - self.assertEqual(5,da2I.getNumberOfTuples()); - self.assertEqual(8,da2.getNumberOfTuples()); - self.assertEqual(expected1,da2I.getValues()); - self.assertEqual(expected2,da2.getValues()); - # - self.assertRaises(InterpKernelException,da.changeSurjectiveFormat,3); - # - pass - - def testUMeshGetCellIdsLyingOnNodes1(self): - m=MEDCouplingDataForTest.build3DSurfTargetMesh_1(); - nodeIds1=[1,2,3,4,6] - nodeIds2=[6,7] - da=m.getCellIdsLyingOnNodes(nodeIds1,True); - self.assertEqual(1,da.getNumberOfTuples()); - self.assertEqual(1,da.getNumberOfComponents()); - self.assertEqual(1,da.getIJ(0,0)); - da2=DataArrayInt.New() - da2.setValues(nodeIds2,2,1) - da=m.getCellIdsLyingOnNodes(da2,False); - self.assertEqual(2,da.getNumberOfTuples()); - self.assertEqual(1,da.getNumberOfComponents()); - self.assertEqual(3,da.getIJ(0,0)); - self.assertEqual(4,da.getIJ(1,0)); - pass - - def testUMeshFindCellIdsOnBoundary1(self): - m=MEDCouplingDataForTest.build3DSurfTargetMesh_1(); - da5=m.findCellIdsOnBoundary(); - self.assertEqual(5,da5.getNumberOfTuples()); - self.assertTrue(da5.isIdentity()); - pass - - def testMeshSetTime1(self): - m1=MEDCouplingDataForTest.build3DSurfTargetMesh_1(); - m2=MEDCouplingDataForTest.build3DSurfTargetMesh_1(); - # - self.assertTrue(m1.isEqual(m2,1e-12)); - m1.setTime(3.14,6,7); - tmp3,tmp1,tmp2=m1.getTime(); - self.assertEqual(6,tmp1); - self.assertEqual(7,tmp2); - self.assertAlmostEqual(3.14,tmp3,12); - self.assertTrue(not m1.isEqual(m2,1e-12)); - m2.setTime(3.14,6,7); - self.assertTrue(m1.isEqual(m2,1e-12)); - m1.setTimeUnit("ms"); - self.assertTrue(m1.getTimeUnit()=="ms"); - m1.setTimeUnit("us"); - self.assertTrue(m1.getTimeUnit()=="us"); - self.assertTrue(not m1.isEqual(m2,1e-12)); - m2.setTimeUnit("us"); - self.assertTrue(m1.isEqual(m2,1e-12)); - m2.setTime(3.14,6,8); - self.assertTrue(not m1.isEqual(m2,1e-12)); - m2.setTime(3.14,7,7); - self.assertTrue(not m1.isEqual(m2,1e-12)); - m2.setTime(3.15,6,7); - self.assertTrue(not m1.isEqual(m2,1e-12)); - # - m1.setTime(10.34,55,12); - m3=m1.deepCpy(); - self.assertTrue(m1.isEqual(m3,1e-12)); - tmp3,tmp1,tmp2=m3.getTime(); - self.assertEqual(55,tmp1); - self.assertEqual(12,tmp2); - self.assertAlmostEqual(10.34,tmp3,12); - # - # testing CMesh - coo1=[0.,1.,2.,3.5] - a=DataArrayDouble.New(); - a.setValues(coo1,4,1); - b=MEDCouplingCMesh.New(); - b.setCoordsAt(0,a); - # - b.setTime(5.67,8,100); - tmp3,tmp1,tmp2=b.getTime(); - self.assertEqual(8,tmp1); - self.assertEqual(100,tmp2); - self.assertAlmostEqual(5.67,tmp3,12); - c=b.deepCpy(); - self.assertTrue(c.isEqual(b,1e-12)); - tmp3,tmp1,tmp2=c.getTime(); - self.assertEqual(8,tmp1); - self.assertEqual(100,tmp2); - self.assertAlmostEqual(5.67,tmp3,12); - pass - - def testApplyFuncTwo1(self): - m1=MEDCouplingDataForTest.build3DSurfTargetMesh_1(); - f1=MEDCouplingFieldDouble.New(ON_CELLS,ONE_TIME); - f1.setMesh(m1); - # - vals=[1.,11.,21.,2.,12.,22.,3.,13.,23.,4.,14.,24.,5.,15.,25.] - da=DataArrayDouble.New(); - da.setValues(vals,5,3); - f1.setArray(da); - # - self.assertRaises(InterpKernelException,da.applyFunc2,1,"y+z"); - da.setInfoOnComponent(0,"x [m]"); - da.setInfoOnComponent(1,"y [mm]"); - da.setInfoOnComponent(2,"z [km]"); - - self.assertRaises(InterpKernelException, da.applyFunc2, 1, "x+y+zz+zzz"); - self.assertRaises(InterpKernelException, da.applyFunc2, 1, "toto(x+y)"); - self.assertRaises(InterpKernelException, da.applyFunc2, 1, "x/0"); - - da2=da.applyFunc2(1,"y+z"); - self.assertEqual(1,da2.getNumberOfComponents()); - self.assertEqual(5,da2.getNumberOfTuples()); - expected1=[32.,34.,36.,38.,40.] - for i in xrange(5): - self.assertAlmostEqual(expected1[i],da2.getIJ(0,i),12); - pass - da2=da.applyFunc(1,"y+z"); - expected2=[12.,14.,16.,18.,20.] - for i in xrange(5): - self.assertAlmostEqual(expected2[i],da2.getIJ(0,i),12); - pass - # - self.assertEqual(3,f1.getNumberOfComponents()); - self.assertEqual(5,f1.getNumberOfTuples()); - f1.applyFunc2(1,"y+z"); - self.assertEqual(1,f1.getNumberOfComponents()); - self.assertEqual(5,f1.getNumberOfTuples()); - for i in xrange(5): - self.assertAlmostEqual(expected1[i],f1.getArray().getIJ(0,i),12); - pass - # - pass - - def testApplyFuncThree1(self): - m1=MEDCouplingDataForTest.build3DSurfTargetMesh_1(); - f1=MEDCouplingFieldDouble.New(ON_CELLS,ONE_TIME); - f1.setMesh(m1); - # - vals=[1.,11.,21.,2.,12.,22.,3.,13.,23.,4.,14.,24.,5.,15.,25.] - da=DataArrayDouble.New(); - da.setValues(vals,5,3); - f1.setArray(da); - # - vs=3*[None]; - vs[0]="x"; vs[1]="Y"; vs[2]="z"; - self.assertRaises(InterpKernelException, da.applyFunc3, 1, vs, "y+z"); - self.assertRaises(InterpKernelException, da.applyFunc3, 1, vs, "x+Y+z+zz+zzz"); - self.assertRaises(InterpKernelException, da.applyFunc3, 1, vs, "x/0"); - vs[1]="y"; - da2=da.applyFunc3(1,vs,"y+z"); - expected1=[32.,34.,36.,38.,40.] - for i in xrange(5): - self.assertAlmostEqual(expected1[i],da2.getIJ(0,i),12); - pass - self.assertRaises(InterpKernelException, da.applyFunc3, 1, ["x","y","z","a"],"x+a") - f1.setArray(da); - self.assertEqual(3,f1.getNumberOfComponents()); - self.assertEqual(5,f1.getNumberOfTuples()); - f1.applyFunc3(1,vs,"y+z"); - self.assertEqual(1,f1.getNumberOfComponents()); - self.assertEqual(5,f1.getNumberOfTuples()); - for i in xrange(5): - self.assertAlmostEqual(expected1[i],f1.getArray().getIJ(0,i),12); - pass - pass - - def testFillFromAnalyticTwo1(self): - m1=MEDCouplingDataForTest.build3DSurfTargetMesh_1(); - m1.setTime(3.4,5,6); m1.setTimeUnit("us"); - self.assertRaises(InterpKernelException,m1.fillFromAnalytic2,ON_NODES,1,"y+z"); - m1.getCoords().setInfoOnComponent(0,"x [m]"); - m1.getCoords().setInfoOnComponent(1,"y"); - m1.getCoords().setInfoOnComponent(2,"z"); - f1=m1.fillFromAnalytic2(ON_NODES,1,"y+z"); - self.assertAlmostEqual(3.4,f1.getTime()[0],12) ; self.assertEqual(5,f1.getTime()[1]) ; self.assertEqual(6,f1.getTime()[2]) - self.assertEqual("us",f1.getTimeUnit()) - self.assertEqual(1,f1.getNumberOfComponents()); - self.assertEqual(9,f1.getNumberOfTuples()); - expected1=[0.2, 0.7, 1.2, 0.7, 1.2, 1.7, 1.2, 1.7, 2.2] - for i in xrange(9): - self.assertAlmostEqual(expected1[i],f1.getArray().getIJ(0,i),12); - pass - pass - - def testFillFromAnalyticThree1(self): - m1=MEDCouplingDataForTest.build3DSurfTargetMesh_1(); - m1.setTime(3.4,5,6); m1.setTimeUnit("us"); - vs=3*[None]; - vs[0]="x"; vs[1]="Y"; vs[2]="z"; - self.assertRaises(InterpKernelException,m1.fillFromAnalytic3,ON_NODES,1,vs,"y+z"); - vs[1]="y"; - f1=m1.fillFromAnalytic3(ON_NODES,1,vs,"y+z"); - self.assertAlmostEqual(3.4,f1.getTime()[0],12) ; self.assertEqual(5,f1.getTime()[1]) ; self.assertEqual(6,f1.getTime()[2]) - self.assertEqual("us",f1.getTimeUnit()) - self.assertEqual(1,f1.getNumberOfComponents()); - self.assertEqual(9,f1.getNumberOfTuples()); - expected1=[0.2, 0.7, 1.2, 0.7, 1.2, 1.7, 1.2, 1.7, 2.2] - for i in xrange(9): - self.assertAlmostEqual(expected1[i],f1.getArray().getIJ(0,i),12); - pass - pass - - def testDAUnitVar1(self): - da=DataArrayDouble.New(); - da.alloc(1,3); - da.setInfoOnComponent(0,"XPS [m]"); - st1=da.getVarOnComponent(0); - self.assertTrue(st1=="XPS"); - st2=da.getUnitOnComponent(0); - self.assertTrue(st2=="m"); - # - da.setInfoOnComponent(0,"XPS [m]"); - st1=da.getVarOnComponent(0); - self.assertTrue(st1=="XPS"); - st2=da.getUnitOnComponent(0); - self.assertTrue(st2=="m"); - # - da.setInfoOnComponent(0,"XPP [m]"); - st1=da.getVarOnComponent(0); - self.assertTrue(st1=="XPP"); - st2=da.getUnitOnComponent(0); - self.assertTrue(st2=="m"); - # - da.setInfoOnComponent(0,"XPP kdep kefer [ m ]"); - st1=da.getVarOnComponent(0); - self.assertTrue(st1=="XPP kdep kefer"); - st2=da.getUnitOnComponent(0); - self.assertTrue(st2==" m "); - # - da.setInfoOnComponent(0," XPP k[ dep k]efer [ m^ 2/s^3*kJ ]"); - st1=da.getVarOnComponent(0); - self.assertTrue(st1==" XPP k[ dep k]efer"); - st2=da.getUnitOnComponent(0); - self.assertTrue(st2==" m^ 2/s^3*kJ "); - # - da.setInfoOnComponent(0," XPP kefer "); - st1=da.getVarOnComponent(0); - self.assertTrue(st1==" XPP kefer "); - st2=da.getUnitOnComponent(0); - self.assertTrue(st2==""); - # - da.setInfoOnComponent(0,"temperature( bof)"); - st1=da.getVarOnComponent(0); - self.assertTrue(st1=="temperature( bof)"); - st2=da.getUnitOnComponent(0); - self.assertTrue(st2==""); - # - da.setInfoOnComponent(0,"kkk [m]"); - da.setInfoOnComponent(1,"ppp [m^2/kJ]"); - da.setInfoOnComponent(2,"abcde [MW/s]"); - # - vs=da.getVarsOnComponent(); - self.assertEqual(3,len(vs)); - self.assertTrue(vs[0]=="kkk"); - self.assertTrue(vs[1]=="ppp"); - self.assertTrue(vs[2]=="abcde"); - vs=da.getUnitsOnComponent(); - self.assertEqual(3,len(vs)); - self.assertTrue(vs[0]=="m"); - self.assertTrue(vs[1]=="m^2/kJ"); - self.assertTrue(vs[2]=="MW/s"); - pass - - def testGaussCoordinates1(self): - #Testing 1D cell types - m1=MEDCouplingDataForTest.build1DMultiTypes_1(); - f=MEDCouplingFieldDouble.New(ON_GAUSS_PT,ONE_TIME); - f.setMesh(m1); - wg1=[0.3]; - gsCoo1=[0.2]; - refCoo1=[-1.0,1.0]; - f.setGaussLocalizationOnType(NORM_SEG2,refCoo1,gsCoo1,wg1); - wg2=wg1; - gsCoo2=[0.2]; - refCoo2=[-1.0,1.0,0.0]; - f.setGaussLocalizationOnType(NORM_SEG3,refCoo2,gsCoo2,wg2); - # - resToTest=f.getLocalizationOfDiscr(); - self.assertEqual(3,resToTest.getNumberOfComponents()); - self.assertEqual(2,resToTest.getNumberOfTuples()); - expected1=[0.6,0.6,0.6, 0.6,0.6,0.6] - for i in xrange(6): - self.assertAlmostEqual(expected1[i],resToTest.getIJ(0,i),14); - pass - # - #Testing 2D cell types - m2=MEDCouplingDataForTest.build2DMultiTypes_1(); - f=MEDCouplingFieldDouble.New(ON_GAUSS_PT,ONE_TIME); - f.setMesh(m2); - wg3=[0.3,0.3]; - tria3CooGauss=[ 0.1, 0.8, 0.2, 0.7 ] - gsCoo3=tria3CooGauss - tria3CooRef=[ 0.0, 0.0, 1.0 , 0.0, 0.0, 1.0 ] - refCoo3=tria3CooRef; - f.setGaussLocalizationOnType(NORM_TRI3,refCoo3,gsCoo3,wg3); - wg4=[0.3,0.3,0.3]; - tria6CooGauss=[ 0.3, 0.2, 0.2, 0.1, 0.2, 0.4 ] - gsCoo4=tria6CooGauss; - tria6CooRef=[0.0, 0.0, 1.0, 0.0, 0.0, 1.0, 0.5, 0.0, 0.5, 0.5, 0.0, 0.5] - refCoo4=tria6CooRef; - f.setGaussLocalizationOnType(NORM_TRI6,refCoo4,gsCoo4,wg4); - wg5=[0.3,0.3,0.3,0.3]; - quad4CooGauss=[ 0.3, 0.2, 0.2, 0.1, 0.2, 0.4, 0.15, 0.27 ] - gsCoo5=quad4CooGauss; - quad4CooRef=[-1.0, 1.0, -1.0, -1.0, 1.0, -1.0, 1.0, 1.0] - refCoo5=quad4CooRef; - f.setGaussLocalizationOnType(NORM_QUAD4,refCoo5,gsCoo5,wg5); - wg6=[0.3,0.3,0.3,0.3]; - quad8CooGauss=[ 0.34, 0.16, 0.21, 0.3, 0.23, 0.4, 0.14, 0.37 ] - gsCoo6=quad8CooGauss; - quad8CooRef=[ -1.0, -1.0, 1.0, -1.0, 1.0, 1.0, -1.0, 1.0, 0.0, -1.0, 1.0, 0.0, 0.0, 1.0, -1.0, 0.0] - refCoo6=quad8CooRef; - f.setGaussLocalizationOnType(NORM_QUAD8,refCoo6,gsCoo6,wg6); - # - resToTest=f.getLocalizationOfDiscr(); - self.assertEqual(3,resToTest.getNumberOfComponents()); - self.assertEqual(13,resToTest.getNumberOfTuples());#2+3+4+4 gauss points for resp TRI3,TRI6,QUAD4,QUAD8 - expected2=[5.1,1.55,0.0, 4.7,1.65,0.0, - 2.32,1.52,0.0, 1.6,1.32,0.0, 3.52,1.26,0.0,#TRI6 - 2.6,1.6,0.0, 2.4,1.8,0.0, 2.4,1.2,0.0, 2.3,1.46,0.0,#QUAD4 - 2.32,2.68,0.0, 2.6,2.42,0.0, 2.8,2.46,0.0, 2.74,2.28,0.0 ];#QUAD8 - for i in xrange(39): - self.assertAlmostEqual(expected2[i],resToTest.getIJ(0,i),14); - pass - # - #Testing 3D cell types - m3=MEDCouplingDataForTest.build3DMultiTypes_1(); - f=MEDCouplingFieldDouble.New(ON_GAUSS_PT,ONE_TIME); - f.setMesh(m3); - # - wg7=[0.3]; - tetra4CooGauss=[0.34, 0.16, 0.21] - gsCoo7=tetra4CooGauss; - tetra4CooRef=[0.0,1.0,0.0, 0.0,0.0,1.0, 0.0,0.0,0.0, 1.0,0.0,0.0] - refCoo7=tetra4CooRef; - f.setGaussLocalizationOnType(NORM_TETRA4,refCoo7,gsCoo7,wg7); - wg8=[0.3]; - tetra10CooGauss=[0.2, 0.3, 0.1] - gsCoo8=tetra10CooGauss; - tetra10CooRef=[0.0,1.0,0.0, 0.0,0.0,0.0, 0.0,0.0,1.0, 1.0,0.0,0.0, 0.0,0.5,0.0, 0.0,0.0,0.5, 0.0,0.5,0.5, 0.5,0.5,0.0, 0.5,0.0,0.0, 0.5,0.0,0.5] - refCoo8=tetra10CooRef; - f.setGaussLocalizationOnType(NORM_TETRA10,refCoo8,gsCoo8,wg8); - wg9=[0.3]; - pyra5CooGauss=[0.2, 0.3, 0.1] - gsCoo9=pyra5CooGauss; - pyra5CooRef=[1.0,0.0,0.0, 0.0,1.0,0.0, -1.0,0.0,0.0, 0.0,-1.0,0.0, 0.0,0.0,1.0] - refCoo9=pyra5CooRef; - f.setGaussLocalizationOnType(NORM_PYRA5,refCoo9,gsCoo9,wg9); - wg10=[0.3]; - pyra13CooGauss=[0.1, 0.2, 0.7] - gsCoo10=pyra13CooGauss; - pyra13CooRef=[1.0,0.0,0.0, 0.0,1.0,0.0,-1.0,0.0,0.0,0.0,-1.0,0.0,0.0,0.0,1.0,0.5,0.5,0.0,-0.5,0.5,0.0,-0.5,-0.5,0.0,0.5,-0.5,0.0,0.5,0.0,0.5,0.0,0.5,0.5,-0.5,0.0,0.5,0.0,-0.5,0.5] - refCoo10=pyra13CooRef; - f.setGaussLocalizationOnType(NORM_PYRA13,refCoo10,gsCoo10,wg10); - wg11=[0.3]; - penta6CooGauss=[0.2, 0.3, 0.1] - gsCoo11=penta6CooGauss; - penta6CooRef=[-1.0,1.0,0.0,-1.0,-0.0,1.0,-1.0,0.0,0.0,1.0,1.0,0.0,1.0,0.0,1.0,1.0,0.0,0.0] - refCoo11=penta6CooRef; - f.setGaussLocalizationOnType(NORM_PENTA6,refCoo11,gsCoo11,wg11); - wg12=[0.3]; - penta15CooGauss=[0.2, 0.3,0.15] - gsCoo12=penta15CooGauss; - penta15CooRef=[-1.0,1.0,0.0,-1.0,0.0,1.0,-1.0,0.0,0.0,1.0,1.0,0.0,1.0,0.0,1.0,1.0,0.0,0.0,-1.0,0.5,0.5,-1.0,0.0,0.5,-1.0,0.5,0.0,0.0,1.0,0.0,0.0,0.0,1.0,0.0,0.0,0.0,1.0,0.5,0.5,1.0,0.0, 0.5,1.0,0.5,0.0] - refCoo12=penta15CooRef; - f.setGaussLocalizationOnType(NORM_PENTA15,refCoo12,gsCoo12,wg12); - wg13=[0.3]; - hexa8CooGauss=[0.2,0.3,0.15] - gsCoo13=hexa8CooGauss; - hexa8CooRef=[-1.0,-1.0,-1.0,1.0,-1.0,-1.0,1.0,1.0,-1.0,-1.0,1.0,-1.0,-1.0,-1.0,1.0,1.0,-1.0,1.0,1.0,1.0,1.0,-1.0,1.0,1.0] - refCoo13=hexa8CooRef; - f.setGaussLocalizationOnType(NORM_HEXA8,refCoo13,gsCoo13,wg13); - wg14=[0.3]; - hexa20CooGauss=[0.11,0.3,0.55] - gsCoo14=hexa20CooGauss; - hexa20CooRef=[-1.0,-1.0,-1.0,1.0,-1.0,-1.0,1.0,1.0,-1.0,-1.0,1.0,-1.0,-1.0,-1.0,1.0,1.0,-1.0,1.0,1.0,1.0,1.0,-1.0,1.0,1.0,0.0,-1.0,-1.0,1.0,0.0,-1.0,0.0,1.0,-1.0,-1.0,0.0,-1.0,-1.0,-1.0,0.0,1.0,-1.0,0.0,1.0,1.0,0.0,-1.0,1.0,0.0,0.0,-1.0,1.0,1.0,0.0,1.0,0.0,1.0,1.0,-1.0,0.0,1.0] - refCoo14=hexa20CooRef; - f.setGaussLocalizationOnType(NORM_HEXA20,refCoo14,gsCoo14,wg14); - # - resToTest=f.getLocalizationOfDiscr(); - self.assertEqual(3,resToTest.getNumberOfComponents()); - self.assertEqual(8,resToTest.getNumberOfTuples());#2+3+4+4 gauss points for resp TRI3,TRI6,QUAD4,QUAD8 - expected3=[1.312,3.15,1.02, 0.56,3.3,0.6, 2.18,1.1,0.2, 1.18,1.54,0.98, 1.56,0.3,3.6, 1.613,0.801,4.374, 2.6,2.4,2.3, 2.31232,2.3933985,1.553255] - for i in xrange(24): - self.assertAlmostEqual(expected3[i],resToTest.getIJ(0,i),14); - pass - # - pass - - def testP2Localization1(self): - m=MEDCouplingUMesh.New("testP2",2); - coords=[0.,2.,3.5,0.,4.5,1.5,1.2,0.32,3.4,1.,2.1,2.4] - conn=[0,1,2,3,4,5] - coo=DataArrayDouble.New(); - coo.setValues(coords,6,2); - m.setCoords(coo); - m.allocateCells(1); - m.insertNextCell(NORM_TRI6,6,conn[0:6]) - m.finishInsertingCells(); - # - f=MEDCouplingFieldDouble.New(ON_NODES,ONE_TIME); - f.setMesh(m); - da=DataArrayDouble.New(); - vals1=[1.2,2.3,3.4, 2.2,3.3,4.4, 3.2,4.3,5.4, 4.2,5.3,6.4, 5.2,6.3,7.4, 6.2,7.3,8.4] - da.setValues(vals1,6,3); - f.setArray(da); - # - loc=[2.27,1.3] - locs=f.getValueOnMulti(loc); - expected1=[6.0921164547752236, 7.1921164547752232, 8.2921164547752255] - for i in xrange(3): - self.assertAlmostEqual(expected1[i],locs.getIJ(0,i),12); - pass - pass - - def testP2Localization2(self): - m=MEDCouplingUMesh.New("testP2_2",3); - coords=[0.33312787792955395, -0.35155740179580952, -0.03567564825034563, 1.307146326477638, -0.57234557776250305, -0.08608044208272235, 0.5551834466499993, 0.62324964668794192, -0.014638951108536295, 0.37761817224442129, -0.38324019806913578, 0.96283164472856886, 0.79494856035658679, -0.40628057809270046, 0.0021004190225864614, 1.023740446371799, 0.07665912970471335, -0.072889657161871096, 0.54564584619517376, 0.11132872093429744, 0.039647326652013051, 0.27164784387819052, -0.42018012100866675, 0.46563376500745146, 0.89501965094896418, -0.56148455362735061, 0.43337469695473035, 0.49118025152924394, 0.093884938060727313, 0.47216346905220891] - conn=[0,1,2,3,4,5,6,7,8,9] - coo=DataArrayDouble.New(); - coo.setValues(coords,10,3); - m.setCoords(coo); - m.allocateCells(1); - m.insertNextCell(NORM_TETRA10,10,conn[0:10]) - m.finishInsertingCells(); - # - f=MEDCouplingFieldDouble.New(ON_NODES,ONE_TIME); - f.setMesh(m); - da=DataArrayDouble.New(); - vals1=[1.1,2.1,3.1,4.1,5.2,6.2,7.2,8.2,9.2,10.2] - da.setValues(vals1,10,1); - f.setArray(da); - # - loc=[0.64637931739890486, -0.16185896817550552, 0.22678966365273748] - locs=f.getValueOnMulti(loc); - expected1=[10.0844021968047] - for i in xrange(1): - self.assertAlmostEqual(expected1[i],locs.getIJ(0,i),12); - pass - pass - - def testGetValueOn2(self): - m=MEDCouplingDataForTest.build2DTargetMesh_1(); - f=MEDCouplingFieldDouble.New(ON_CELLS,NO_TIME); - f.setMesh(m); - arr=DataArrayDouble.New(); - nbOfCells=m.getNumberOfCells(); - f.setArray(arr); - values1=[7.,107.,10007.,8.,108.,10008.,9.,109.,10009.,10.,110.,10010.,11.,111.,10011.] - arr.setValues(values1,nbOfCells,3); - loc=[-0.05,-0.05, 0.55,-0.25, 0.55,0.15, -0.05,0.45, 0.45,0.45] - f.checkCoherency(); - locs=f.getValueOnMulti(loc); - self.assertEqual(5,locs.getNumberOfTuples()); - self.assertEqual(3,locs.getNumberOfComponents()); - for j in xrange(15): - self.assertAlmostEqual(values1[j],locs.getIJ(0,j),12); - pass - # Testing ON_NODES - f=MEDCouplingFieldDouble.New(ON_NODES,NO_TIME); - f.setMesh(m); - arr=DataArrayDouble.New(); - nbOfNodes=m.getNumberOfNodes(); - f.setArray(arr); - values2=[7.,107.,10007.,8.,108.,10008.,9.,109.,10009.,10.,110.,10010.,11.,111.,10011.,12.,112.,10012.,13.,113.,10013.,14.,114.,10014.,15.,115.,10015.] - arr.setValues(values2,nbOfNodes,3); - loc2=[0.5432,-0.2432, 0.5478,0.1528, 0.5432,-0.2432, 0.5432,-0.2432] - expected2=[9.0272, 109.0272, 10009.0272, 11.4124,111.4124,10011.4124, 9.0272, 109.0272, 10009.0272, 9.0272, 109.0272, 10009.0272] - f.checkCoherency(); - loc3=DataArrayDouble.New() - loc3.setValues(loc2,4,2); - locs=f.getValueOnMulti(loc3); - self.assertEqual(4,locs.getNumberOfTuples()); - self.assertEqual(3,locs.getNumberOfComponents()); - for i in xrange(12): - self.assertAlmostEqual(expected2[i],locs.getIJ(0,i),12); - pass - # - pass - - def testDAIGetIdsNotEqual1(self): - d=DataArrayInt.New(); - vals1=[2,3,5,6,8,5,5,6,1,-5] - d.setValues(vals1,10,1); - d2=d.getIdsNotEqual(5); - self.assertEqual(7,d2.getNumberOfTuples()); - self.assertEqual(1,d2.getNumberOfComponents()); - expected1=[0,1,3,4,7,8,9] - for i in xrange(7): - self.assertEqual(expected1[i],d2.getIJ(0,i)); - pass - d.rearrange(2); - self.assertRaises(InterpKernelException,d.getIdsNotEqual,5); - vals2=[-4,5,6] - vals3=vals2; - d.rearrange(1); - d3=d.getIdsNotEqualList(vals3); - self.assertEqual(5,d3.getNumberOfTuples()); - self.assertEqual(1,d3.getNumberOfComponents()); - expected2=[0,1,4,8,9] - for i in xrange(5): - self.assertEqual(expected2[i],d3.getIJ(0,i)); - pass - pass - - def testDAIComputeOffsets1(self): - d=DataArrayInt.New(); - vals1=[3,5,1,2,0,8] - expected1=[0,3,8,9,11,11] - d.setValues(vals1,6,1); - d.computeOffsets(); - self.assertEqual(6,d.getNumberOfTuples()); - self.assertEqual(1,d.getNumberOfComponents()); - for i in xrange(6): - self.assertEqual(expected1[i],d.getIJ(0,i)); - pass - pass - - def testUMeshHexagonPrism1(self): - coords=[0.8660254037844386, 0.5, 0.0, 0.0, 1.0, 0.0, -0.8660254037844386, 0.5, 0.0, -0.8660254037844386, -0.5, 0.0, 0.0, -1.0, 0.0, 0.8660254037844386, -0.5, 0.0, - 0.8660254037844386, 0.5, 2.0, 0.0, 1.0, 2.0, -0.8660254037844386, 0.5, 2.0, -0.8660254037844386, -0.5, 2.0, 0.0, -1.0, 2.0, 0.8660254037844386, -0.5, 2.0]; - conn=[1,2,3,4,5,0,7,8,9,10,11,6] - mesh=MEDCouplingUMesh.New("MyFirstHexagonalPrism",3); - coo=DataArrayDouble.New(); - coo.setValues(coords,12,3); - mesh.setCoords(coo); - mesh.allocateCells(1); - mesh.insertNextCell(NORM_HEXGP12,12,conn[0:12]) - mesh.finishInsertingCells(); - # - mesh.checkCoherency(); - vols=mesh.getMeasureField(False); - self.assertEqual(1,vols.getNumberOfTuples()); - self.assertEqual(1,vols.getNumberOfComponents()); - self.assertAlmostEqual(-5.196152422706632,vols.getIJ(0,0),12); - bary=mesh.getBarycenterAndOwner(); - self.assertEqual(1,bary.getNumberOfTuples()); - self.assertEqual(3,bary.getNumberOfComponents()); - expected1=[0.,0.,1.] - for i in xrange(3): - self.assertAlmostEqual(expected1[i],bary.getIJ(0,i),12); - pass - d1=DataArrayInt.New(); - d2=DataArrayInt.New(); - d3=DataArrayInt.New(); - d4=DataArrayInt.New(); - m2=mesh.buildDescendingConnectivity(d1,d2,d3,d4); - self.assertEqual(8,m2.getNumberOfCells()); - expected4=[[1,2,3,4,5,0],[7,6,11,10,9,8],[1,7,8,2],[2,8,9,3],[3,9,10,4],[4,10,11,5],[5,11,6,0],[0,6,7,1]]; - expected2=[NORM_POLYGON, NORM_POLYGON, NORM_QUAD4, NORM_QUAD4, NORM_QUAD4, NORM_QUAD4, NORM_QUAD4, NORM_QUAD4]; - expected3=[6,6,4,4,4,4,4,4] - for i in xrange(8): - self.assertTrue(m2.getTypeOfCell(i)==expected2[i]); - v=m2.getNodeIdsOfCell(i); - self.assertTrue(len(v)==expected3[i]); - self.assertEqual(expected4[i],v); - # - mesh.convertAllToPoly(); - self.assertTrue(NORM_POLYHED==mesh.getTypeOfCell(0)); - mesh.unPolyze(); - self.assertTrue(NORM_HEXGP12==mesh.getTypeOfCell(0)); - self.assertEqual(13,mesh.getMeshLength()); - # - pass - - def testDADCheckIsMonotonic(self): - da=DataArrayDouble.New(); - da.setValues([-1.,1.01,2.03,6.],2,2); - self.assertRaises(InterpKernelException,da.isMonotonic,True,1e-12); - da.rearrange(1); - self.assertTrue(da.isMonotonic(True,1e-12)); - da.checkMonotonic(True,1e-12); - da.setIJ(2,0,6.1); - self.assertTrue(not da.isMonotonic(True,1e-12)); - self.assertRaises(InterpKernelException,da.checkMonotonic,True,1e-12); - da.setIJ(2,0,5.99); - self.assertTrue(da.isMonotonic(True,1e-12)); - self.assertTrue(not da.isMonotonic(True,1e-1)); - pass - - def testCheckCoherencyDeeper1(self): - m=MEDCouplingDataForTest.build3DSourceMesh_1(); - m.checkCoherency(); - m.checkCoherency1(); - m.getNodalConnectivity().setIJ(8,0,-1); - m.checkCoherency(); - self.assertRaises(InterpKernelException,m.checkCoherency1); - m.getNodalConnectivity().setIJ(8,0,-6); - m.checkCoherency(); - self.assertRaises(InterpKernelException,m.checkCoherency1); - m.getNodalConnectivity().setIJ(8,0,9);#9>=NbOfNodes - m.checkCoherency(); - self.assertRaises(InterpKernelException,m.checkCoherency1); - m.getNodalConnectivity().setIJ(8,0,8);#OK - m.checkCoherency(); - m.checkCoherency1(); - elts=[1,5] - m.convertToPolyTypes(elts); - m.checkCoherency(); - m.checkCoherency1(); - m.getNodalConnectivity().setIJ(2,0,9);#9>=NbOfNodes - m.checkCoherency(); - self.assertRaises(InterpKernelException,m.checkCoherency1); - m.getNodalConnectivity().setIJ(2,0,-3); - m.checkCoherency(); - self.assertRaises(InterpKernelException,m.checkCoherency1); - m.getNodalConnectivity().setIJ(2,0,-1); - m.checkCoherency(); - self.assertRaises(InterpKernelException,m.checkCoherency1);#Throw because cell#0 is not a polyhedron - m.getNodalConnectivity().setIJ(2,0,4); - m.checkCoherency(); - m.checkCoherency1(); - m.getNodalConnectivity().setIJ(7,0,-1); - m.checkCoherency(); - m.checkCoherency1();#OK because we are in polyhedron connec - m.getNodalConnectivity().setIJ(36,0,14); - m.checkCoherency(); - self.assertRaises(InterpKernelException,m.checkCoherency1);#Throw beacause now cell 5 is a TETRA4 (14) so mimatch of number index and static type. - pass - - def testUnPolyze2(self): - m=MEDCouplingUMesh.New("jjj",3); - coo=DataArrayDouble.New(); - coo.alloc(4,3); - coo.rearrange(1); - coo.iota(0); - coo.rearrange(3); - m.setCoords(coo); - m.allocateCells(2); - m.insertNextCell(NORM_TETRA4,4,[0,1,2,3]); - m.insertNextCell(NORM_TETRA4,4,[0,1,2,3]); - m.finishInsertingCells(); - m2=MEDCouplingUMesh.MergeUMeshesOnSameCoords(4*[m]); - m2.convertToPolyTypes([2]); - m2.unPolyze(); - self.assertEqual(NORM_TETRA4,m2.getTypeOfCell(2)); - self.assertEqual(40,m2.getMeshLength()); - temp2=m2.getNodeIdsOfCell(2); - self.assertEqual(temp2,[0,1,2,3]); - m2.checkCoherency1(); - m3=m2.deepCpy(); - m2.unPolyze(); - self.assertTrue(m3.isEqual(m2,1e-12)); - pass - - def testDACpyFrom1(self): - d=DataArrayDouble.New(); - d.alloc(12,1); - d.iota(14.); - d.rearrange(3); - d.setName("Toto"); - d.setInfoOnComponent(0,"X [m]"); - d.setInfoOnComponent(1,"Y [m]"); - d.setInfoOnComponent(2,"Z [m]"); - # - d1=DataArrayDouble.New(); - self.assertTrue(not d.isEqual(d1,1e-12)); - d1.cpyFrom(d); - self.assertTrue(d.isEqual(d1,1e-12)); - d1.cpyFrom(d); - self.assertTrue(d.isEqual(d1,1e-12)); - d1.rearrange(2); - self.assertTrue(not d.isEqual(d1,1e-12)); - d1.cpyFrom(d); - self.assertTrue(d.isEqual(d1,1e-12)); - # - d2=d.convertToIntArr(); - d4=DataArrayInt.New(); - self.assertTrue(not d2.isEqual(d4)); - d4.cpyFrom(d2); - self.assertTrue(d2.isEqual(d4)); - d4.cpyFrom(d2); - self.assertTrue(d2.isEqual(d4)); - d4.rearrange(2); - self.assertTrue(not d2.isEqual(d4)); - d4.cpyFrom(d2); - self.assertTrue(d2.isEqual(d4)); - pass - - def testDAITransformWithIndArr1(self): - tab1=[17,18,22,19] - tab2=[0,1,1,3,3,0,1,3,2,2,3,0] - expected=[17,18,18,19,19,17,18,19,22,22,19,17] - d=DataArrayInt.New(); - d.setValues(tab1,4,1); - d1=DataArrayInt.New(); - d1.setValues(tab2,12,1); - d2=d1[:] - # - d1.transformWithIndArr(d); - self.assertEqual(12,d1.getNumberOfTuples()); - self.assertEqual(1,d1.getNumberOfComponents()); - for i in xrange(12): - self.assertEqual(expected[i],d1.getIJ(i,0)); - pass - # - d1=d2 - d1.transformWithIndArr(tab1) - self.assertEqual(12,d1.getNumberOfTuples()); - self.assertEqual(1,d1.getNumberOfComponents()); - for i in xrange(12): - self.assertEqual(expected[i],d1.getIJ(i,0)); - pass - pass - - def testDAIBuildPermArrPerLevel1(self): - arr=[2,0,1,1,0,1,2,0,1,1,0,0] - expected1=[10,0,5,6,1,7,11,2,8,9,3,4] - da=DataArrayInt.New(); - da.setValues(arr,12,1); - da2=da.buildPermArrPerLevel(); - self.assertEqual(12,da2.getNumberOfTuples()); - self.assertEqual(1,da2.getNumberOfComponents()); - for i in xrange(12): - self.assertEqual(expected1[i],da2.getIJ(i,0)); - pass - pass - - def testDAIOperations1(self): - arr1=[-1,-2,4,7,3,2,6,6,4,3,0,1] - da=DataArrayInt.New(); - da.setValues(arr1,4,3); - da1=DataArrayInt.New(); - da1.alloc(12,1); - da1.iota(2); - self.assertRaises(InterpKernelException,DataArrayInt.Add,da,da1);#not same number of tuples/Components - da1.rearrange(3); - da2=DataArrayInt.Add(da,da1); - self.assertEqual(4,da2.getNumberOfTuples()); - self.assertEqual(3,da2.getNumberOfComponents()); - expected1=[1,1,8,12,9,9,14,15,14,14,12,14] - for i in xrange(12): - self.assertEqual(expected1[i],da2.getIJ(0,i)); - pass - da1.substractEqual(da); - expected2=[3,5,0,-2,3,5,2,3,6,8,12,12] - for i in xrange(12): - self.assertEqual(expected2[i],da1.getIJ(0,i)); - pass - da1.rearrange(1); da1.iota(2); da1.rearrange(3); - da1.addEqual(da); - for i in xrange(12): - self.assertEqual(expected1[i],da1.getIJ(0,i)); - pass - da1.rearrange(1); da1.iota(2); da1.rearrange(3); - da2=DataArrayInt.Multiply(da,da1); - self.assertEqual(4,da2.getNumberOfTuples()); - self.assertEqual(3,da2.getNumberOfComponents()); - expected3=[-2,-6,16,35,18,14,48,54,40,33,0,13] - for i in xrange(12): - self.assertEqual(expected3[i],da2.getIJ(0,i)); - pass - da.divideEqual(da1); - self.assertEqual(4,da.getNumberOfTuples()); - self.assertEqual(3,da.getNumberOfComponents()); - expected4=[0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0] - for i in xrange(12): - self.assertEqual(expected4[i],da.getIJ(0,i)); - pass - da.setValues(arr1,4,3); - da1.multiplyEqual(da); - self.assertEqual(4,da1.getNumberOfTuples()); - self.assertEqual(3,da1.getNumberOfComponents()); - for i in xrange(12): - self.assertEqual(expected3[i],da1.getIJ(0,i)); - pass - da1.rearrange(1); da1.iota(2); da1.rearrange(3); - da2=DataArrayInt.Divide(da,da1); - self.assertEqual(4,da2.getNumberOfTuples()); - self.assertEqual(3,da2.getNumberOfComponents()); - for i in xrange(12): - self.assertEqual(expected4[i],da2.getIJ(0,i)); - pass - da1.applyInv(321); - self.assertEqual(4,da1.getNumberOfTuples()); - self.assertEqual(3,da1.getNumberOfComponents()); - expected5=[160,107,80,64,53,45,40,35,32,29,26,24] - for i in xrange(12): - self.assertEqual(expected5[i],da1.getIJ(0,i)); - pass - da1.applyDivideBy(2); - self.assertEqual(4,da1.getNumberOfTuples()); - self.assertEqual(3,da1.getNumberOfComponents()); - expected6=[80,53,40,32,26,22,20,17,16,14,13,12] - for i in xrange(12): - self.assertEqual(expected6[i],da1.getIJ(0,i)); - pass - expected7=[3,4,5,4,5,1,6,3,2,0,6,5] - da1.applyModulus(7); - for i in xrange(12): - self.assertEqual(expected7[i],da1.getIJ(0,i)); - pass - da1.applyLin(1,1); - expected8=[3,3,3,3,3,1,3,3,0,0,3,3] - da1.applyRModulus(3); - for i in xrange(12): - self.assertEqual(expected8[i],da1.getIJ(0,i)); - pass - pass - - def testEmulateMEDMEMBDC1(self): - m,m1=MEDCouplingDataForTest.buildPointe_1(); - m2,da1,da2,da3,da4,da5,da0=m.emulateMEDMEMBDC(m1) - expected0=[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,36,37,32,33,34,35,38,39,40,41,42,43,44,45,46] - expected1=[1,32,29,23,41,36] - self.assertEqual(47,da0.getNumberOfTuples()); - self.assertEqual(1,da0.getNumberOfComponents()); - for i in xrange(47): - self.assertEqual(expected0[i],da0.getIJ(0,i)); - pass - self.assertEqual(6,da5.getNumberOfTuples()); - self.assertEqual(1,da5.getNumberOfComponents()); - for i in xrange(6): - self.assertEqual(expected1[i],da5.getIJ(0,i)); - pass - expected2=[0,1,2,3,4,0,5,6,7,4,8,9,1,7,10,11,12,13,14,5,15,16,17,8,18,19,20,10,21,22,23,2,13,24,25,21,16,26,27,12,19,28,29,15,22,30,31,18,36,26,28,30,24,37,32,33,34,35,38,36,39,40,41,42,37,38,43,44,45,46] - self.assertEqual(70,da1.getNumberOfTuples()); - self.assertEqual(1,da1.getNumberOfComponents()); - for i in xrange(70): - self.assertEqual(expected2[i],da1.getIJ(0,i)); - pass - expected3=[0,4,8,12,16,20,24,28,32,36,40,44,48,53,58,64,70] - self.assertEqual(17,da2.getNumberOfTuples()); - self.assertEqual(1,da2.getNumberOfComponents()); - for i in xrange(17): - self.assertEqual(expected3[i],da2.getIJ(0,i)); - pass - expected4=[0,2,4,6,7,9,11,12,14,16,17,19,20,22,24,25,27,29,30,32,34,35,37,39,40,42,43,45,46,48,49,51,52,53,54,55,56,58,60,62,63,64,65,66,67,68,69,70] - #expected4=[0,2,4,6,7,9,11,12,14,16,17,19,20,22,24,25,27,29,30,32,34,35,37,39,40,42,43,45,46,48,49,51,52,54,56,57,58,59,60,62,63,64,65,66,67,68,69,70]; - self.assertEqual(48,da4.getNumberOfTuples()); - self.assertEqual(1,da4.getNumberOfComponents()); - for i in xrange(48): - self.assertEqual(expected4[i],da4.getIJ(0,i)); - pass - expected5=[0,1,0,3,0,7,0,1,2,1,4,1,2,3,2,5,2,3,6,3,4,9,4,8,4,5,10,5,9,5,6,11,6,10,6,7,8,7,11,7,8,12,8,9,12,9,10,12,10,11,12,11,13,13,13,13,12,14,13,15,14,15,14,14,14,14,15,15,15,15] - self.assertEqual(70,da3.getNumberOfTuples()); - self.assertEqual(1,da3.getNumberOfComponents()); - for i in xrange(70): - self.assertEqual(expected5[i],da3.getIJ(0,i)); - pass - pass - - def testGetLevArrPerCellTypes1(self): - m,m1=MEDCouplingDataForTest.buildPointe_1(); - m1,d0,d1,d2,d3=m.buildDescendingConnectivity(); - order=[NORM_TRI3,NORM_QUAD4]; - da0,da1=m1.getLevArrPerCellTypes(order); - expected0=[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,1,1,1,1,1,1,1,1,1] - expected1=[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,36,37,32,33,34,35,38,39,40,41,42,43,44,45,46] - self.assertEqual(47,da0.getNumberOfTuples()); - self.assertEqual(1,da0.getNumberOfComponents()); - for i in xrange(47): - self.assertEqual(expected0[i],da0.getIJ(0,i)); - pass - self.assertEqual(2,da1.getNumberOfTuples()); - self.assertEqual(1,da1.getNumberOfComponents()); - self.assertEqual(36,da1.getIJ(0,0));#36 TRI3 - self.assertEqual(11,da1.getIJ(1,0));#11 QUAD4 - # - da2=da0.buildPermArrPerLevel(); - # - self.assertEqual(47,da2.getNumberOfTuples()); - self.assertEqual(1,da2.getNumberOfComponents()); - for i in xrange(47): - self.assertEqual(expected1[i],da2.getIJ(0,i)); - pass - pass - - def testSortCellsInMEDFileFrmt1(self): - m,m1=MEDCouplingDataForTest.buildPointe_1(); - m2=m.deepCpy() - da=DataArrayInt.New() - da.setValues([0,1,2,14,3,12,4,5,15,6,7,8,9,10,11,13],16,1) - daa=da.invertArrayN2O2O2N(16) - m.renumberCells(daa,False) - da2=m.sortCellsInMEDFileFrmt() - self.assertEqual(da2.getValues(),[0,1,2,14,3,12,4,5,15,6,7,8,9,10,11,13]) - self.assertTrue(m.isEqual(m2,1e-12)) - self.assertTrue(da.isEqual(da2)) - pass - - def testBuildPartAndReduceNodes1(self): - m=MEDCouplingDataForTest.build2DTargetMesh_1(); - arr=[1,0] - m2,da=m.buildPartAndReduceNodes(arr); - self.assertEqual(5,m2.getNumberOfNodes()); - self.assertEqual(2,m2.getNumberOfCells()); - f=m2.getMeasureField(True); - self.assertAlmostEqual(0.125,f.getArray().getIJ(0,0),12); - self.assertAlmostEqual(0.25,f.getArray().getIJ(1,0),12); - # - arr2=DataArrayInt.New() - arr2.setValues(arr,2,1) - m2,da=m.buildPartAndReduceNodes(arr2); - self.assertEqual(5,m2.getNumberOfNodes()); - self.assertEqual(2,m2.getNumberOfCells()); - f=m2.getMeasureField(True); - self.assertAlmostEqual(0.125,f.getArray().getIJ(0,0),12); - self.assertAlmostEqual(0.25,f.getArray().getIJ(1,0),12); - pass - - def testDAITransformWithIndArrR1(self): - tab1=[2,4,5,3,6,7] - tab2=[-1,-1,0,1,2,3,4,5,-1,-1,-1,-1] - expected=[0,3,1,2,4,5] - d=DataArrayInt.New(); - d.setValues(tab1,6,1); - d1=DataArrayInt.New(); - d1.setValues(tab2,12,1); - d2=d1[:] - # - d3=d.transformWithIndArrR(d1); - self.assertEqual(6,d3.getNumberOfTuples()); - self.assertEqual(1,d3.getNumberOfComponents()); - for i in xrange(6): - self.assertEqual(expected[i],d3.getIJ(i,0)); - pass - # - d1=d2 - d3=d.transformWithIndArrR(tab2) - self.assertEqual(6,d3.getNumberOfTuples()); - self.assertEqual(1,d3.getNumberOfComponents()); - for i in xrange(6): - self.assertEqual(expected[i],d3.getIJ(i,0)); - pass - pass - - def testDAISplitByValueRange1(self): - val1=[6,5,0,3,2,7,8,1,4] - val2=[0,4,9] - d=DataArrayInt.New(); - d.setValues(val1,9,1); - e,f,g=d.splitByValueRange(val2); - self.assertEqual(9,e.getNumberOfTuples()); - self.assertEqual(1,e.getNumberOfComponents()); - self.assertEqual(9,f.getNumberOfTuples()); - self.assertEqual(1,f.getNumberOfComponents()); - self.assertEqual(2,g.getNumberOfTuples()); - self.assertEqual(1,g.getNumberOfComponents()); - # - expected1=[1,1,0,0,0,1,1,0,1] - expected2=[2,1,0,3,2,3,4,1,0] - for i in xrange(9): - self.assertEqual(expected1[i],e.getIJ(i,0)); - self.assertEqual(expected2[i],f.getIJ(i,0)); - pass - self.assertEqual(0,g.getIJ(0,0)); - self.assertEqual(1,g.getIJ(1,0)); - # - d.setIJ(6,0,9); - self.assertRaises(InterpKernelException,d.splitByValueRange,val2); - pass - - def testUMeshSplitProfilePerType1(self): - val0=[2,0,1,3,4] - m=MEDCouplingDataForTest.build2DTargetMesh_1(); - m.renumberCells(val0,False); - # - val1=[0,2,3] - d=DataArrayInt.New(); - d.setValues(val1,3,1); - d.setName("sup") - code,idsInPflPerType,pfls=m.splitProfilePerType(d); - self.assertEqual(2,len(code)); - self.assertEqual(2,len(idsInPflPerType)); - expected1=[[3,1,0], [4,2,1]] - self.assertEqual(expected1,code) - self.assertEqual(2,len(idsInPflPerType)); - self.assertEqual(1,idsInPflPerType[0].getNumberOfTuples()); - self.assertEqual(0,idsInPflPerType[0].getIJ(0,0)); - self.assertEqual(2,idsInPflPerType[1].getNumberOfTuples()); - self.assertEqual(1,idsInPflPerType[1].getIJ(0,0)); - self.assertEqual(2,idsInPflPerType[1].getIJ(1,0)); - # - self.assertEqual(2,len(pfls)); - self.assertEqual("sup",pfls[0].getName()) - self.assertEqual(1,pfls[0].getNumberOfTuples()); - self.assertEqual(0,pfls[0].getIJ(0,0)); - self.assertEqual("sup",pfls[1].getName()) - self.assertEqual(2,pfls[1].getNumberOfTuples()); - self.assertEqual(0,pfls[1].getIJ(0,0)); - self.assertEqual(1,pfls[1].getIJ(1,0)); - # - val2=[0,2,3,4] - d=DataArrayInt.New(); - d.setValues(val2,4,1); - code,idsInPflPerType,pfls=m.splitProfilePerType(d); - self.assertEqual(2,len(code)); - self.assertEqual(2,len(idsInPflPerType)); - expected2=[[3,1,0], [4,3,-1]] - self.assertEqual(expected2,code); - self.assertEqual(2,len(idsInPflPerType)); - self.assertEqual(1,idsInPflPerType[0].getNumberOfTuples()); - self.assertEqual(0,idsInPflPerType[0].getIJ(0,0)); - self.assertEqual(3,idsInPflPerType[1].getNumberOfTuples()); - self.assertEqual(1,idsInPflPerType[1].getIJ(0,0)); - self.assertEqual(2,idsInPflPerType[1].getIJ(1,0)); - self.assertEqual(3,idsInPflPerType[1].getIJ(2,0)); - # - self.assertEqual(1,len(pfls)); - self.assertEqual(1,pfls[0].getNumberOfTuples()); - self.assertEqual(0,pfls[0].getIJ(0,0)); - # - val3=[1,0,2] - d=DataArrayInt.New(); - d.setValues(val3,3,1); - code,idsInPflPerType,pfls=m.splitProfilePerType(d); - self.assertEqual(2,len(code)); - self.assertEqual(2,len(idsInPflPerType)); - expected3=[[3,2,0], [4,1,1]] - self.assertEqual(expected3,code); - self.assertEqual(2,len(idsInPflPerType)); - self.assertEqual(2,idsInPflPerType[0].getNumberOfTuples()); - self.assertEqual(0,idsInPflPerType[0].getIJ(0,0)); - self.assertEqual(1,idsInPflPerType[0].getIJ(1,0)); - self.assertEqual(1,idsInPflPerType[1].getNumberOfTuples()); - self.assertEqual(2,idsInPflPerType[1].getIJ(0,0)); - # - self.assertEqual(2,len(pfls)); - self.assertEqual(2,pfls[0].getNumberOfTuples()); - self.assertEqual(1,pfls[0].getIJ(0,0)); - self.assertEqual(0,pfls[0].getIJ(1,0)); - self.assertEqual(0,pfls[1].getIJ(0,0)); - # - val4=[3,4] - d=DataArrayInt.New(); - d.setValues(val4,2,1); - code,idsInPflPerType,pfls=m.splitProfilePerType(d); - self.assertEqual(1,len(code)); - self.assertEqual(1,len(idsInPflPerType)); - expected4=[[4,2,0]] - self.assertEqual(expected4,code); - self.assertEqual(1,len(idsInPflPerType)); - self.assertEqual(2,idsInPflPerType[0].getNumberOfTuples()); - self.assertEqual(0,idsInPflPerType[0].getIJ(0,0)); - self.assertEqual(1,idsInPflPerType[0].getIJ(1,0)); - # - self.assertEqual(1,len(pfls)); - self.assertEqual(2,pfls[0].getNumberOfTuples()); - self.assertEqual(1,pfls[0].getIJ(0,0)); - self.assertEqual(2,pfls[0].getIJ(1,0)); - pass - - def testDAIBuildExplicitArrByRanges1(self): - d=DataArrayInt.New(); - vals1=[0,2,3] - d.setValues(vals1,3,1); - e=DataArrayInt.New(); - vals2=[0,3,6,10,14,20] - e.setValues(vals2,6,1); - # - f=d.buildExplicitArrByRanges(e); - self.assertEqual(11,f.getNumberOfTuples()); - self.assertEqual(1,f.getNumberOfComponents()); - expected1=[0,1,2,6,7,8,9,10,11,12,13] - for i in xrange(11): - self.assertEqual(expected1[i],f.getIJ(i,0)); - pass - pass - - def testDAIComputeOffsets2(self): - d=DataArrayInt.New(); - vals1=[3,5,1,2,0,8] - expected1=[0,3,8,9,11,11,19] - d.setValues(vals1,6,1); - d.computeOffsets2(); - self.assertEqual(7,d.getNumberOfTuples()); - self.assertEqual(1,d.getNumberOfComponents()); - for i in xrange(7): - self.assertEqual(expected1[i],d.getIJ(0,i)); - pass - pass - - def testMergeField3(self): - m=MEDCouplingDataForTest.build2DTargetMesh_1(); - m.getCoords().setInfoOnComponent(0,"x [m]"); - m.getCoords().setInfoOnComponent(1,"z [km]"); - m.setName("m"); - m.setDescription("desc"); - f1=MEDCouplingFieldDouble.New(ON_CELLS,ONE_TIME); - f1.setName("f1"); - f1.setMesh(m); - arr=DataArrayDouble.New(); - arr.alloc(5,2); - arr.setInfoOnComponent(0,"X [m]"); - arr.setInfoOnComponent(1,"YY [mm]"); - arr.fillWithValue(2.); - f1.setArray(arr); - # - f2=MEDCouplingFieldDouble.MergeFields([f1]); - self.assertTrue(f1.isEqual(f2,1e-12,1e-12)); - # - pass - - def testGetDistributionOfTypes1(self): - m=MEDCouplingDataForTest.build2DTargetMesh_1(); - tab1=[2,0,1,3,4] - self.assertRaises(InterpKernelException,m.getDistributionOfTypes); - m.renumberCells(tab1,False); - code=m.getDistributionOfTypes(); - self.assertEqual(2,len(code)); - self.assertEqual(3,code[0][0]); - self.assertEqual(2,code[0][1]); - self.assertEqual(-1,code[0][2]); - self.assertEqual(4,code[1][0]); - self.assertEqual(3,code[1][1]); - self.assertEqual(-1,code[1][2]); - pass - - def testNorm2_1(self): - m=MEDCouplingDataForTest.build2DTargetMesh_1(); - f=MEDCouplingFieldDouble.New(ON_CELLS,ONE_TIME); - f.setMesh(m); - # - d=DataArrayDouble.New(); - tab=[1.2,1.3,2.2,2.3,3.2,3.3,4.2,4.3,5.2,5.3] - d.setValues(tab,5,2); - f.setArray(d); - f.checkCoherency(); - # - self.assertAlmostEqual(11.209371079592289,f.norm2(),14); - # - pass - - def testNormMax1(self): - m=MEDCouplingDataForTest.build2DTargetMesh_1(); - f=MEDCouplingFieldDouble.New(ON_CELLS,ONE_TIME); - f.setMesh(m); - # - d=DataArrayDouble.New(); - tab=[2.3,-1.2,6.3,-7.8,2.9,7.7,2.1,0.,3.6,-7.6] - d.setValues(tab,5,2); - f.setArray(d); - f.checkCoherency(); - # - self.assertAlmostEqual(7.8,f.normMax(),14); - # - pass - - def testFindAndCorrectBadOriented3DExtrudedCells1(self): - coords=[0.0011180339887498999, -0.0011755705045849499, 0.0, -0.0012331070204200001, -0.0011755705045849499, 0.0, -0.00067557050458494599, -0.00145964954842536, 0.0, -0.00050000000000000001, -0.00086602540378443902, 0.0, 0.00140211303259031, -0.00061803398874989504, 0.0, 0.00086602540378443902, -0.00050000000000000001, 0.0, 0.001, 0.0, 0.0, 0.00034561537182258202, 0.000269164072574575, 0.0, 0.0, 0.001, 0.0, -0.00050000000000000001, 0.00086602540378443902, 0.0, -0.000269164072574575, 0.00034561537182258202, 0.0, -0.001, 0.0, 0.0, -0.00086602540378443902, -0.00050000000000000001, 0.0, -0.00034561537182258202, -0.000269164072574575, 0.0, 0.0, -0.001, 0.0, 0.00050000000000000001, -0.00086602540378443902, 0.0, 0.000269164072574575, -0.00034561537182258202, 0.0, 0.0015, -6.01853107621011e-36, 0.0, 0.00056049747291484397, -0.00145964954842536, 0.0, 0.0011180339887498999, -0.0011755705045849499, 0.00050000000000000001, -0.0012331070204200001, -0.0011755705045849499, 0.00050000000000000001, -0.00067557050458494599, -0.00145964954842536, 0.00050000000000000001, -0.00050000000000000001, -0.00086602540378443902, 0.00050000000000000001, 0.00140211303259031, -0.00061803398874989504, 0.00050000000000000001, 0.00086602540378443902, -0.00050000000000000001, 0.00050000000000000001, 0.001, 0.0, 0.00050000000000000001, 0.00034561537182258202, 0.000269164072574575, 0.00050000000000000001, 0.0, 0.001, 0.00050000000000000001, -0.00050000000000000001, 0.00086602540378443902, 0.00050000000000000001, -0.000269164072574575, 0.00034561537182258202, 0.00050000000000000001, -0.001, 0.0, 0.00050000000000000001, -0.00086602540378443902, -0.00050000000000000001, 0.00050000000000000001, -0.00034561537182258202, -0.000269164072574575, 0.00050000000000000001, 0.0, -0.001, 0.00050000000000000001, 0.00050000000000000001, -0.00086602540378443902, 0.00050000000000000001, 0.000269164072574575, -0.00034561537182258202, 0.00050000000000000001, 0.0015, -6.01853107621011e-36, 0.00050000000000000001, 0.00056049747291484397, -0.00145964954842536, 0.00050000000000000001]; - conn=[2, 1, 3, 21, 20, 22, 4, 0, 5, 23, 19, 24, 8, 9, 10, 27, 28, 29, 11, 12, 13, 30, 31, 32, 0, 18, 15, 5, 19, 37, 34, 24, 6, 17, 4, 5, 25, 36, 23, 24, 3, 14, 16, 13, 22, 33, 35, 32, 13, 16, 7, 10, 32, 35, 26, 29] - connExp=[16, 2, 1, 3, 21, 20, 22, 16, 4, 0, 5, 23, 19, 24, 16, 8, 10, 9, 27, 29, 28, 16, 11, 13, 12, 30, 32, 31, 18, 0, 18, 15, 5, 19, 37, 34, 24,18, 6, 17, 4, 5, 25, 36, 23, 24, 18, 3, 13, 16, 14, 22, 32, 35, 33, 18, 13, 10, 7, 16, 32, 29, 26, 35] - invalidCells=[2,3,6,7] - m=MEDCouplingUMesh.New("Example",3); - coo=DataArrayDouble.New(); - coo.setValues(coords,38,3); - m.setCoords(coo); - m.allocateCells(8); - m.insertNextCell(NORM_PENTA6,6,conn[0:6]) - m.insertNextCell(NORM_PENTA6,6,conn[6:12]) - m.insertNextCell(NORM_PENTA6,6,conn[12:18]) - m.insertNextCell(NORM_PENTA6,6,conn[18:24]) - m.insertNextCell(NORM_HEXA8,8,conn[24:32]) - m.insertNextCell(NORM_HEXA8,8,conn[32:40]) - m.insertNextCell(NORM_HEXA8,8,conn[40:48]) - m.insertNextCell(NORM_HEXA8,8,conn[48:56]) - m.finishInsertingCells(); - # - v=m.findAndCorrectBadOriented3DExtrudedCells(); - self.assertEqual(4,len(v)); - self.assertEqual(v.getValues(),invalidCells); - self.assertEqual(connExp,m.getNodalConnectivity().getValues()); - self.assertTrue(m.findAndCorrectBadOriented3DExtrudedCells().empty()) - # - pass - - def testConvertExtrudedPolyhedra1(self): - conn=[1,2,3,4, 5,6,7,8,9,10,11,12, 13,14,15,16, 17,18,19,20,21,22, 23,24,25,26,27,28, 29,30,31,32,33,34,35,36,37,38, 39,40,41,42,43,44,45,46, 47,48,49,50,51,52,53,54,55,56,57,58, 59,60,61,62,63,64,65,66,67,68,69,70,71,72] - m=MEDCouplingUMesh.New("Example",3); - coo=DataArrayDouble.New(); - coo.alloc(73,3); - coo.rearrange(1); coo.iota(0); coo.rearrange(3); - m.setCoords(coo); - m.allocateCells(9); - m.insertNextCell(NORM_TETRA4,4,conn[0:4]) - m.insertNextCell(NORM_HEXA8,8,conn[4:12]) - m.insertNextCell(NORM_TETRA4,4,conn[12:16]) - m.insertNextCell(NORM_POLYHED,6,conn[16:22]) - m.insertNextCell(NORM_PENTA6,6,conn[22:28]) - m.insertNextCell(NORM_POLYHED,10,conn[28:38]) - m.insertNextCell(NORM_HEXA8,8,conn[38:46]) - m.insertNextCell(NORM_HEXGP12,12,conn[46:58]) - m.insertNextCell(NORM_POLYHED,14,conn[58:72]) - m.finishInsertingCells(); - # - m.convertExtrudedPolyhedra(); - da=m.getNodalConnectivity(); - dai=m.getNodalConnectivityIndex(); - self.assertEqual(10,dai.getNbOfElems()); - self.assertEqual(159,da.getNbOfElems()); - # - expected1=[14,1,2,3,4,18,5,6,7,8,9,10,11,12,14,13,14,15,16,31,17,18,19,-1,20,22,21,-1,17,20,21,18,-1,18,21,22,19,-1,19,22,20,17,16,23,24,25,26,27,28,31,29,30,31,32,33,-1,34,38,37,36,35,-1,29,34,35,30,-1,30,35,36,31,-1,31,36,37,32,-1,32,37,38,33,-1,33,38,34,29,18,39,40,41,42,43,44,45,46,22,47,48,49,50,51,52,53,54,55,56,57,58,31,59,60,61,62,63,64,65,-1,66,72,71,70,69,68,67,-1,59,66,67,60,-1,60,67,68,61,-1,61,68,69,62,-1,62,69,70,63,-1,63,70,71,64,-1,64,71,72,65,-1,65,72,66,59]; - expected2=[0,5,14,19,42,49,86,95,108,159] - self.assertEqual(expected1,da.getValues()); - self.assertEqual(expected2,dai.getValues()); - m.checkCoherency2() - pass - - def testNonRegressionCopyTinyStrings(self): - m=MEDCouplingDataForTest.build2DTargetMesh_1() - f1=m.getMeasureField(True) - f1.getArray().setInfoOnComponent(0,"P [N/m^2]") - bary=m.getBarycenterAndOwner() - f2=f1.buildNewTimeReprFromThis(NO_TIME,False) - f2.setArray(bary) - self.assertRaises(InterpKernelException,f1.copyTinyAttrFrom,f2) - pass - - def testDaDSetPartOfValuesAdv1(self): - tab1=[3.,4.,5., 13.,14.,15., 23.,24.,25., 33.,34.,35., 43.,44.,45., 53.,54.,55.] - tab2=[6.,7.,8., 16.,17.,18., 26.,27.,28.] - tab3=[4,1, 2,2, 3,0] - a=DataArrayDouble.New(); - a.setValues(tab1,6,3); - b=DataArrayDouble.New(); - b.setValues(tab2,3,3); - c=DataArrayInt.New(); - c.setValues(tab3,3,2); - # - a.setPartOfValuesAdv(b,c); - expected1=[3.,4.,5., 13.,14.,15., 26.,27.,28., 6.,7.,8., 16.,17.,18., 53.,54.,55.] - self.assertEqual(expected1,a.getValues()); - pass - - def testUMeshBuildSetInstanceFromThis1(self): - m=MEDCouplingDataForTest.build3DSurfTargetMesh_1(); - m2=m.buildSetInstanceFromThis(3); - self.assertTrue(m.isEqual(m2,1e-12)); - # - m=MEDCouplingUMesh.New("toto",2); - m2=m.buildSetInstanceFromThis(3); - self.assertEqual(0,m2.getNumberOfNodes()); - self.assertEqual(0,m2.getNumberOfCells()); - pass - - def testUMeshMergeMeshesCVW1(self): - m=MEDCouplingDataForTest.build3DSurfTargetMesh_1(); - m2=MEDCouplingUMesh.New("toto",2); - m3=MEDCouplingUMesh.MergeUMeshes([m,m2]); - m3.setName(m.getName()); - self.assertTrue(m.isEqual(m3,1e-12)); - pass - - def testChangeUnderlyingMeshWithCMesh1(self): - mesh=MEDCouplingCMesh.New(); - coordsX=DataArrayDouble.New(); - arrX=[ -1., 1., 2., 4. ] - coordsX.setValues(arrX,4,1); - coordsY=DataArrayDouble.New(); - arrY=[ -2., 2., 4., 8. ] - coordsY.setValues(arrY,4,1); - coordsZ=DataArrayDouble.New(); - arrZ=[ -3., 3., 6., 12. ] - coordsZ.setValues(arrZ,4,1); - mesh.setCoords(coordsX,coordsY,coordsZ); - f=mesh.getMeasureField(True) - mesh2=mesh.deepCpy() - for myId in [0,1,2,10,11,12,20,21,22]: - f=mesh.getMeasureField(True) - f.changeUnderlyingMesh(mesh2,myId,1e-12); - pass - mesh2.setName("uuuu") - for myId in [1,2,10,11,12,20,21,22]: - f=mesh.getMeasureField(True) - f.changeUnderlyingMesh(mesh2,myId,1e-12); - pass - pass - - def testDADFindCommonTuples1(self): - da=DataArrayDouble.New(); - # nbOftuples=1 - array1=[2.3,1.2,1.3,2.3,2.301,0.8] - da.setValues(array1,6,1) - c,cI=da.findCommonTuples(1e-2); - expected1=[0,3,4] - expected2=[0,3] - self.assertEqual(3,c.getNbOfElems()); - self.assertEqual(2,cI.getNbOfElems()); - self.assertEqual(expected1,c.getValues()) - self.assertEqual(expected2,cI.getValues()) - c,cI=da.findCommonTuples(2e-1) - expected3=[0,3,4,1,2] - expected4=[0,3,5] - self.assertEqual(5,c.getNbOfElems()); - self.assertEqual(3,cI.getNbOfElems()); - self.assertEqual(expected3,c.getValues()) - self.assertEqual(expected4,cI.getValues()) - # nbOftuples=2 - array2=[2.3,2.3,1.2,1.2,1.3,1.3,2.3,2.3,2.301,2.301,0.8,0.8] - da.setValues(array2,6,2) - c,cI=da.findCommonTuples(1e-2); - self.assertEqual(3,c.getNbOfElems()); - self.assertEqual(2,cI.getNbOfElems()); - self.assertEqual(expected1,c.getValues()) - self.assertEqual(expected2,cI.getValues()) - c,cI=da.findCommonTuples(2e-1) - self.assertEqual(5,c.getNbOfElems()); - self.assertEqual(3,cI.getNbOfElems()); - self.assertEqual(expected3,c.getValues()) - self.assertEqual(expected4,cI.getValues()) - # nbOftuples=3 - array3=[2.3,2.3,2.3,1.2,1.2,1.2,1.3,1.3,1.3,2.3,2.3,2.3,2.301,2.301,2.301,0.8,0.8,0.8] - da.setValues(array3,6,3) - c,cI=da.findCommonTuples(1e-2); - self.assertEqual(3,c.getNbOfElems()); - self.assertEqual(2,cI.getNbOfElems()); - self.assertEqual(expected1,c.getValues()) - self.assertEqual(expected2,cI.getValues()) - c,cI=da.findCommonTuples(2e-1) - self.assertEqual(5,c.getNbOfElems()); - self.assertEqual(3,cI.getNbOfElems()); - self.assertEqual(expected3,c.getValues()) - self.assertEqual(expected4,cI.getValues()) - # nbOftuples=1, no common groups - array11=[2.3,1.2,1.3,2.4,2.5,0.8] - da.setValues(array11,6,1) - c,cI=da.findCommonTuples(1e-2); - self.assertEqual(0,c.getNbOfElems()); - self.assertEqual(1,cI.getNbOfElems()); - self.assertEqual([0],cI.getValues()) - - array12=[0.]*(6*5) - da.setValues(array12,6,5) #bad NumberOfComponents - self.assertRaises(InterpKernelException, da.findCommonTuples, 1e-2); - pass - - def testDABack1(self): - da=DataArrayDouble.New(); - array1=[2.3,1.2,1.3,2.3,2.301,0.8] - da.setValues(array1,6,1); - self.assertAlmostEqual(0.8,da.back(),14); - da.rearrange(2); - self.assertRaises(InterpKernelException,da.back); - da.alloc(0,1); - self.assertRaises(InterpKernelException,da.back); - # - da=DataArrayInt.New(); - array2=[4,7,8,2] - da.setValues(array2,4,1); - self.assertEqual(2,da.back()); - da.rearrange(2); - self.assertRaises(InterpKernelException,da.back); - da.alloc(0,1); - self.assertRaises(InterpKernelException,da.back); - pass - - def testDADGetDifferentValues1(self): - da=DataArrayDouble.New(); - array1=[2.3,1.2,1.3,2.3,2.301,0.8] - da.setValues(array1,6,1) - # - expected1=[2.301,1.2,1.3,0.8] - dv=da.getDifferentValues(1e-2); - self.assertEqual(4,dv.getNbOfElems()); - for i in xrange(4): - self.assertAlmostEqual(expected1[i],dv.getIJ(i,0),14); - pass - # - dv=da.getDifferentValues(2e-1); - expected2=[2.301,1.3,0.8] - self.assertEqual(3,dv.getNbOfElems()); - for i in xrange(3): - self.assertAlmostEqual(expected2[i],dv.getIJ(i,0),14); - pass - pass - - def testDAIBuildOld2NewArrayFromSurjectiveFormat2(self): - arr=[0,3, 5,7,9] - arrI=[0,2,5] - a=DataArrayInt.New(); - a.setValues(arr,5,1); - b=DataArrayInt.New(); - b.setValues(arrI,3,1); - ret,newNbTuple=DataArrayInt.BuildOld2NewArrayFromSurjectiveFormat2(10,a,b); - expected=[0,1,2,0,3,4,5,4,6,4] - self.assertEqual(10,ret.getNbOfElems()); - self.assertEqual(7,newNbTuple); - self.assertEqual(1,ret.getNumberOfComponents()); - self.assertEqual(expected,ret.getValues()); - self.assertRaises(InterpKernelException,DataArrayInt.BuildOld2NewArrayFromSurjectiveFormat2,9,a,b); - pass - - def testDADIReverse1(self): - arr=[0,3,5,7,9,2] - a=DataArrayInt.New(); - a.setValues(arr,6,1); - self.assertEqual(2,a.back()); - a.reverse(); - for i in xrange(6): - self.assertEqual(arr[5-i],a.getIJ(i,0)); - pass - a.setValues(arr[:-1],5,1); - a.reverse(); - for i in xrange(5): - self.assertEqual(arr[4-i],a.getIJ(i,0)); - pass - # - arr2=[0.,3.,5.,7.,9.,2.] - b=DataArrayDouble.New(); - b.setValues(arr2,6,1); - b.reverse(); - for i in xrange(6): - self.assertAlmostEqual(arr2[5-i],b.getIJ(i,0),14); - pass - b.setValues(arr2[:5],5,1); - self.assertAlmostEqual(9.,b.back(),14) - b.reverse(); - for i in xrange(5): - self.assertAlmostEqual(arr2[4-i],b.getIJ(i,0),14); - pass - pass - - def testGetNodeIdsInUse1(self): - m0=MEDCouplingDataForTest.build2DTargetMesh_1(); - CellIds=[1,2] - m1=m0.buildPartOfMySelf(CellIds,True); - arr,newNbOfNodes=m1.getNodeIdsInUse(); - expected=[-1,0,1,-1,2,3,-1,-1,-1] - self.assertEqual(4,newNbOfNodes); - self.assertEqual(9,arr.getNbOfElems()); - self.assertEqual(expected,arr.getValues()); - arr2=arr.invertArrayO2N2N2O(newNbOfNodes); - self.assertEqual(4,arr2.getNbOfElems()); - expected2=[1,2,4,5] - self.assertEqual(expected2,arr2.getValues()); - pass - - def testBuildDescendingConnec2(self): - mesh=MEDCouplingDataForTest.build2DTargetMesh_1(); - # - mesh2,desc,descIndx,revDesc,revDescIndx=mesh.buildDescendingConnectivity2(); - mesh2.checkCoherency(); - self.assertEqual(1,mesh2.getMeshDimension()); - self.assertEqual(13,mesh2.getNumberOfCells()); - self.assertEqual(14,revDescIndx.getNbOfElems()); self.assertEqual(14,revDescIndx.getNumberOfTuples()); - self.assertEqual(6,descIndx.getNbOfElems()); self.assertEqual(6,descIndx.getNumberOfTuples()); - self.assertEqual(18,desc.getNbOfElems()); self.assertEqual(18,desc.getNumberOfTuples()); - self.assertEqual(18,revDesc.getNbOfElems()); self.assertEqual(18,revDesc.getNumberOfTuples()); - expected1=[1,2,3,4,-3,5,6, 7,8,-5,9,10,-2,11, 12,13,-7,-10] - self.assertEqual(expected1,desc.getValues()); - expected2=[0,4,7,10,14,18] - self.assertEqual(expected2,descIndx.getValues()); - expected3=[0,1,3,5,6,8,9,11,12,13,15,16,17,18] - self.assertEqual(expected3,revDescIndx.getValues()); - expected4=[0, 0,3, 0,1, 0, 1,2, 1, 2,4, 2, 3, 3,4, 3, 4, 4] - self.assertEqual(expected4,revDesc.getValues()); - conn=mesh2.getNodalConnectivity(); - connIndex=mesh2.getNodalConnectivityIndex(); - expected5=[0,3,6,9,12,15,18,21,24,27,30,33,36,39] - self.assertEqual(expected5,connIndex.getValues()); - expected6=[1, 0, 3, 1, 3, 4, 1, 4, 1, 1, 1, 0, 1, 4, 2, 1, 2, 1, 1, 4, 5, 1, 5, 2, 1, 6, 7, 1, 7, 4, 1, 3, 6, 1, 7, 8, 1, 8, 5] - self.assertEqual(expected6,conn.getValues()); - pass - - def testIntersect2DMeshesTmp1(self): - m1c=MEDCouplingCMesh.New(); - coordsX=DataArrayDouble.New(); - arrX=[ -1., 1., 2., 4. ] - coordsX.setValues(arrX,4,1); - m1c.setCoordsAt(0,coordsX); - coordsY=DataArrayDouble.New(); - arrY=[ -2., 2., 4., 8. ] - coordsY.setValues(arrY,4,1); - m1c.setCoordsAt(1,coordsY); - m1=m1c.buildUnstructured() - m1bis=m1.buildPartOfMySelf([3,4,5],False) - m2=m1.deepCpy() - m2=m2.buildPartOfMySelf([0,1,2],False) - m2.translate([0.5,0.5]) - # - m3,d1,d2=MEDCouplingUMesh.Intersect2DMeshes(m1bis,m2,1e-10) - expected1=[0,0,1,1,1,2,2,2] - expected2=[0,-1,0,1,-1,1,2,-1] - self.assertEqual(8,d1.getNumberOfTuples()); - self.assertEqual(8,d2.getNumberOfTuples()); - self.assertEqual(8,m3.getNumberOfCells()); - self.assertEqual(22,m3.getNumberOfNodes()); - self.assertEqual(2,m3.getSpaceDimension()); - self.assertEqual(expected1,d1.getValues()); - self.assertEqual(expected2,d2.getValues()); - expected3=[5,17,1,16,12,5,16,0,4,5,17,12,5,18,1,17,13,5,19,2,18,13,5,17,5,6,19,13,5,20,2,19,14,5,21,3,20,14,5,19,6,7,21,14] - expected4=[0,5,12,17,22,28,33,38,44] - expected5=[-1.0,2.0,1.0,2.0,2.0,2.0,4.0,2.0,-1.0,4.0,1.0,4.0,2.0,4.0,4.0,4.0,-0.5,-1.5,1.5,-1.5,2.5,-1.5,4.5,-1.5,-0.5,2.5,1.5,2.5,2.5,2.5,4.5,2.5,-0.5,2.0,1.0,2.5,1.5,2.0,2.0,2.5,2.5,2.0,4.0,2.5] - self.assertEqual(44,m3.getNodalConnectivity().getNumberOfTuples()); - self.assertEqual(9,m3.getNodalConnectivityIndex().getNumberOfTuples()); - self.assertEqual(expected3,m3.getNodalConnectivity().getValues()); - self.assertEqual(expected4,m3.getNodalConnectivityIndex().getValues()); - for i in xrange(44): - self.assertAlmostEqual(expected5[i],m3.getCoords().getIJ(0,i),12); - pass - pass - - def testFindNodesOnLine1(self): - mesh=MEDCouplingDataForTest.build2DTargetMesh_1(); - pt=[-0.3,-0.3] - pt2=[0.,0.,0.] - pt3=[-0.3,0.,0.] - vec=[0.,1.] - vec2=[1.,0.,0.] - vec3=[0.,1.,1.] - expected1=[0,3,6] - res=mesh.findNodesOnLine(pt,vec,1e-12); - self.assertEqual(3,len(res)); - self.assertEqual(expected1,res.getValues()); - # - mesh.changeSpaceDimension(3); - mesh.rotate(pt2,vec2,pi/4.); - res=mesh.findNodesOnLine(pt3,vec3,1e-12); - self.assertEqual(3,len(res)); - self.assertEqual(expected1,res.getValues()); - pass - - def testIntersect2DMeshesTmp2(self): - m1c=MEDCouplingCMesh.New(); - coordsX1=DataArrayDouble.New(); - arrX1=[ 0., 1., 1.5, 2. ] - coordsX1.setValues(arrX1,4,1); - m1c.setCoordsAt(0,coordsX1); - coordsY1=DataArrayDouble.New(); - arrY1=[ 0., 1.5, 3.] - coordsY1.setValues(arrY1,3,1); - m1c.setCoordsAt(1,coordsY1); - m1=m1c.buildUnstructured(); - m2c=MEDCouplingCMesh.New(); - coordsX2=DataArrayDouble.New(); - arrX2=[ 0., 1., 2. ] - coordsX2.setValues(arrX2,3,1); - m2c.setCoordsAt(0,coordsX2); - coordsY2=DataArrayDouble.New(); - arrY2=[ 0., 1., 3.] - coordsY2.setValues(arrY2,3,1); - m2c.setCoordsAt(1,coordsY2); - m2=m2c.buildUnstructured(); - # - m3,d1,d2=MEDCouplingUMesh.Intersect2DMeshes(m1,m2,1e-10) - # - expected1=[0,0,1,1,2,2,3,4,5] - expected2=[0,2,1,3,1,3,2,3,3] - self.assertEqual(9,d1.getNumberOfTuples()); - self.assertEqual(9,d2.getNumberOfTuples()); - self.assertEqual(9,m3.getNumberOfCells()); - self.assertEqual(22,m3.getNumberOfNodes()); - self.assertEqual(2,m3.getSpaceDimension()); - self.assertEqual(expected1,d1.getValues()); - self.assertEqual(expected2,d2.getValues()); - expected3=[5,16,13,12,15,5,15,4,5,16,5,21,2,13,16,5,16,5,6,21,5,17,14,2,21,5,21,6,7,17,5,4,18,19,5,5,5,19,10,6,5,6,10,20,7] - expected4=[0,5,10,15,20,25,30,35,40,45] - expected5=[0.0,0.0,1.0,0.0,1.5,0.0,2.0,0.0,0.0,1.5,1.0,1.5,1.5,1.5,2.0,1.5,0.0,3.0,1.0,3.0,1.5,3.0,2.0,3.0,0.0,0.0,1.0,0.0,2.0,0.0,0.0,1.0,1.0,1.0,2.0,1.0,0.0,3.0,1.0,3.0,2.0,3.0,1.5,1.0] - self.assertEqual(45,m3.getNodalConnectivity().getNumberOfTuples()); - self.assertEqual(10,m3.getNodalConnectivityIndex().getNumberOfTuples()); - self.assertEqual(expected3,m3.getNodalConnectivity().getValues()); - self.assertEqual(expected4,m3.getNodalConnectivityIndex().getValues()); - for i in xrange(44): - self.assertAlmostEqual(expected5[i],m3.getCoords().getIJ(0,i),12); - pass - pass - - def testBuildPartOfMySelfSafe1(self): - mesh=MEDCouplingDataForTest.build2DTargetMesh_1() - self.assertRaises(InterpKernelException,mesh.buildPartOfMySelf,[0,-1,4,2],True) - self.assertRaises(InterpKernelException,mesh.buildPartOfMySelf,[0,4,5,4],True) - pass - - def testIntersect2DMeshesTmp3(self): - m1Coords=[0.,0.,1.,0.,1.5,0.,0.,1.,0.,1.5,-1.,0.,-1.5,0.,0.,-1,0.,-1.5,0.5,0.,1.25,0.,0.70710678118654757,0.70710678118654757,1.0606601717798214,1.0606601717798214,0.,0.5,0.,1.25,-0.70710678118654757,0.70710678118654757,-1.0606601717798214,1.0606601717798214,-0.5,0.,-1.25,0.,-0.70710678118654757,-0.70710678118654757,-1.0606601717798214,-1.0606601717798214,0.,-0.5,0.,-1.25,0.70710678118654757,-0.70710678118654757,1.0606601717798214,-1.0606601717798214]; - m1Conn=[0,3,1,13,11,9, 3,4,2,1,14,12,10,11, 5,3,0,15,13,17, 6,4,3,5,16,14,15,18, 5,0,7,17,21,19, 6,5,7,8,18,19,22,20, 0,1,7,9,23,21, 1,2,8,7,10,24,22,23]; - m1=MEDCouplingUMesh.New(); - m1.setMeshDimension(2); - m1.allocateCells(8); - m1.insertNextCell(NORM_TRI6,6,m1Conn[0:6]); - m1.insertNextCell(NORM_QUAD8,8,m1Conn[6:14]); - m1.insertNextCell(NORM_TRI6,6,m1Conn[14:20]); - m1.insertNextCell(NORM_QUAD8,8,m1Conn[20:28]); - m1.insertNextCell(NORM_TRI6,6,m1Conn[28:34]); - m1.insertNextCell(NORM_QUAD8,8,m1Conn[34:42]); - m1.insertNextCell(NORM_TRI6,6,m1Conn[42:48]); - m1.insertNextCell(NORM_QUAD8,8,m1Conn[48:56]); - m1.finishInsertingCells(); - myCoords1=DataArrayDouble.New(); - myCoords1.setValues(m1Coords,25,2); - m1.setCoords(myCoords1); - # - m2Coords=[0.,0.,1.1,0.,1.1,1.,0.,1.,1.7,0.,1.7,1.,-1.1,1.,-1.1,0.,-1.7,0.,-1.7,1.,-1.7,-1,-1.1,-1.,0.,-1.,1.1,-1,1.7,-1.] - m2Conn=[0,3,2,1, 1,2,5,4, 7,6,3,0, 8,9,6,7, 7,0,12,11, 8,7,11,10, 0,1,13,12, 1,4,14,13] - m2=MEDCouplingUMesh.New(); - m2.setMeshDimension(2); - m2.allocateCells(8); - for i in xrange(8): - m2.insertNextCell(NORM_QUAD4,4,m2Conn[4*i:4*(i+1)]) - pass - m2.finishInsertingCells(); - myCoords2=DataArrayDouble.New(); - myCoords2.setValues(m2Coords,15,2); - m2.setCoords(myCoords2); - # - m3,d1,d2=MEDCouplingUMesh.Intersect2DMeshes(m1,m2,1e-10) - m3.unPolyze() - # - expected1=[0,1,1,1,2,3,3,3,4,5,5,5,6,7,7,7] - expected2=[0,0,1,-1,2,2,3,-1,4,4,5,-1,6,6,7,-1] - self.assertEqual(16,d1.getNumberOfTuples()); - self.assertEqual(16,d2.getNumberOfTuples()); - self.assertEqual(16,m3.getNumberOfCells()); - self.assertEqual(104,m3.getNumberOfNodes()); - self.assertEqual(2,m3.getSpaceDimension()); - self.assertEqual(expected1,d1.getValues()); - self.assertEqual(expected2,d2.getValues()); - expected3=[6,28,1,25,44,45,46,8,26,1,28,27,47,48,49,50,8,40,2,26,27,51,52,53,54,8,28,4,40,27,55,56,57,58,6,28,25,5,59,60,61,8,28,5,32,31,62,63,64,65,8,32,6,41,31,66,67,68,69,8,41,4,28,31,70,71,72,73,6,25,37,5,74,75,76,8,32,5,37,36,77,78,79,80,8,42,6,32,36,81,82,83,84,8,37,8,42,36,85,86,87,88,6,1,37,25,89,90,91,8,37,1,26,38,92,93,94,95,8,26,2,43,38,96,97,98,99,8,43,8,37,38,100,101,102,103] - expected4=[0,7,16,25,34,41,50,59,68,75,84,93,102,109,118,127,136] - expected5=[0.,0.,1.,0.,1.5,0.,0.,1.,0.,1.5,-1.,0.,-1.5,0.,0.,-1.,0.,-1.5,0.5,0.,1.25,0.,0.7071067811865476,0.7071067811865476,1.0606601717798214,1.0606601717798214,0.,0.5,0.,1.25,-0.7071067811865476,0.7071067811865476,-1.0606601717798214,1.0606601717798214,-0.5,0.,-1.25,0.,-0.7071067811865476,-0.7071067811865476,-1.0606601717798214,-1.0606601717798214,0.,-0.5,0.,-1.25,0.7071067811865476,-0.7071067811865476,1.0606601717798214,-1.0606601717798214,0.,0.,1.1,0.,1.1,1.,0.,1.,1.7,0.,1.7,1.,-1.1,1.,-1.1,0.,-1.7,0.,-1.7,1.,-1.7,-1.,-1.1,-1.,0.,-1.,1.1,-1.,1.7,-1.,1.118033988749895,1.,-1.118033988749895,1.,-1.118033988749895,-1.,1.118033988749895,-1.,0.7071067811865477,0.7071067811865476,0.5,0.,0.,0.5,1.05,0.,0.7071067811865475,0.7071067811865477,0.55,1.,1.1,0.5,1.4012585384440737,0.535233134659635,1.3,0.,1.1,0.5,1.1090169943749475,1.,0.,1.25,0.6123724356957946,1.369306393762915,1.1090169943749475,1.,0.55,1.,0.,0.5,-0.5,0.,-0.7071067811865477,0.7071067811865476,-0.7071067811865475,0.7071067811865477,-1.05,0.,-1.1,0.5,-0.55,1.,-1.3,0.,-1.4012585384440737,0.5352331346596344,-1.1090169943749475,1.,-1.1,0.5,-0.6123724356957941,1.3693063937629155,0.,1.25,-0.55,1.,-1.1090169943749475,1.,0.,-0.5,-0.7071067811865475,-0.7071067811865477,-0.5,0.,-1.05,0.,-0.7071067811865478,-0.7071067811865475,-0.55,-1.,-1.1,-0.5,-1.4012585384440734,-0.5352331346596354,-1.3,0.,-1.1,-0.5,-1.1090169943749475,-1.,0.,-1.25,-0.6123724356957945,-1.369306393762915,-1.1090169943749475,-1.,-0.55,-1.,0.7071067811865475,-0.7071067811865477,0.,-0.5,0.5,0.,0.7071067811865477,-0.7071067811865475,1.05,0.,1.1,-0.5,0.55,-1.,1.3,0.,1.4012585384440737,-0.535233134659635,1.1090169943749475,-1.,1.1,-0.5,0.6123724356957946,-1.369306393762915,0.,-1.25,0.55,-1.,1.1090169943749475,-1.0] - self.assertEqual(136,m3.getNodalConnectivity().getNumberOfTuples()); - self.assertEqual(17,m3.getNodalConnectivityIndex().getNumberOfTuples()); - self.assertEqual(expected3,m3.getNodalConnectivity().getValues()); - self.assertEqual(expected4,m3.getNodalConnectivityIndex().getValues()); - for i in xrange(208): - self.assertAlmostEqual(expected5[i],m3.getCoords().getIJ(0,i),12); - pass - pass - - def testUMeshTessellate2D1(self): - m1Coords=[0.,0.,1.,0.,1.5,0.,0.,1.,0.,1.5,-1.,0.,-1.5,0.,0.,-1,0.,-1.5,0.5,0.,1.25,0.,0.70710678118654757,0.70710678118654757,1.0606601717798214,1.0606601717798214,0.,0.5,0.,1.25,-0.70710678118654757,0.70710678118654757,-1.0606601717798214,1.0606601717798214,-0.5,0.,-1.25,0.,-0.70710678118654757,-0.70710678118654757,-1.0606601717798214,-1.0606601717798214,0.,-0.5,0.,-1.25,0.70710678118654757,-0.70710678118654757,1.0606601717798214,-1.0606601717798214]; - m1Conn=[0,3,1,13,11,9, 3,4,2,1,14,12,10,11, 5,3,0,15,13,17, 6,4,3,5,16,14,15,18, 5,0,7,17,21,19, 6,5,7,8,18,19,22,20, 0,1,7,9,23,21, 1,2,8,7,10,24,22,23]; - m1=MEDCouplingUMesh.New(); - m1.setMeshDimension(2); - m1.allocateCells(8); - m1.insertNextCell(NORM_TRI6,6,m1Conn[0:6]); - m1.insertNextCell(NORM_QUAD8,8,m1Conn[6:14]); - m1.insertNextCell(NORM_TRI6,6,m1Conn[14:20]); - m1.insertNextCell(NORM_QUAD8,8,m1Conn[20:28]); - m1.insertNextCell(NORM_TRI6,6,m1Conn[28:34]); - m1.insertNextCell(NORM_QUAD8,8,m1Conn[34:42]); - m1.insertNextCell(NORM_TRI6,6,m1Conn[42:48]); - m1.insertNextCell(NORM_QUAD8,8,m1Conn[48:56]); - m1.finishInsertingCells(); - myCoords1=DataArrayDouble.New(); - myCoords1.setValues(m1Coords,25,2); - m1.setCoords(myCoords1); - # - m11=m1.deepCpy(); - m11.tessellate2D(1.); - self.assertTrue(m11.getCoords().isEqual(m11.getCoords(),1e-12)); - expected1=[5,0,3,11,1,5,3,4,12,2,1,11,5,5,15,3,0,5,6,16,4,3,15,5,5,5,0,7,19,5,6,5,19,7,8,20,5,0,1,23,7,5,1,2,24,8,7,23] - expected2=[0,5,12,17,24,29,36,41,48] - self.assertEqual(48,m11.getNodalConnectivity().getNumberOfTuples()); - self.assertEqual(9,m11.getNodalConnectivityIndex().getNumberOfTuples()); - self.assertEqual(expected1,m11.getNodalConnectivity().getValues()); - self.assertEqual(expected2,m11.getNodalConnectivityIndex().getValues()); - # - m12=m1.deepCpy(); - m12.tessellate2D(0.5); - self.assertEqual(41,m12.getNumberOfNodes()); - expected3=[5,0,3,25,26,1,5,3,4,27,28,2,1,26,25,5,5,29,30,3,0,5,6,31,32,4,3,30,29,5,5,5,0,7,33,34,5,6,5,34,33,7,8,35,36,5,0,1,37,38,7,5,1,2,39,40,8,7,38,37] - expected4=[0,6,15,21,30,36,45,51,60] - expected5=[0.,0.,1.,0.,1.5,0.,0.,1.,0.,1.5,-1.,0.,-1.5,0.,0.,-1.,0.,-1.5,0.5,0.,1.25,0.,0.7071067811865476,0.7071067811865476,1.0606601717798214,1.0606601717798214,0.,0.5,0.,1.25,-0.7071067811865476,0.7071067811865476,-1.0606601717798214,1.0606601717798214,-0.5,0.,-1.25,0.,-0.7071067811865476,-0.7071067811865476,-1.0606601717798214,-1.0606601717798214,0.,-0.5,0.,-1.25,0.7071067811865476,-0.7071067811865476,1.0606601717798214,-1.0606601717798214,0.479425538604203,0.8775825618903728,0.8414709848078964,0.54030230586814,0.7191383079063044,1.3163738428355591,1.2622064772118446,0.8104534588022099,-0.877582561890373,0.4794255386042027,-0.5403023058681399,0.8414709848078964,-1.3163738428355596,0.7191383079063038,-0.8104534588022098,1.2622064772118446,-0.4794255386042031,-0.8775825618903728,-0.8414709848078965,-0.5403023058681399,-0.7191383079063045,-1.3163738428355591,-1.2622064772118449,-0.8104534588022098,0.8775825618903729,-0.47942553860420295,0.54030230586814,-0.8414709848078964,1.3163738428355594,-0.7191383079063043,0.8104534588022099,-1.2622064772118446] - for i in xrange(82): - self.assertAlmostEqual(expected5[i],m12.getCoords().getIJ(0,i),12); - pass - self.assertEqual(60,m12.getNodalConnectivity().getNumberOfTuples()); - self.assertEqual(9,m12.getNodalConnectivityIndex().getNumberOfTuples()); - self.assertEqual(expected3,m12.getNodalConnectivity().getValues()); - self.assertEqual(expected4,m12.getNodalConnectivityIndex().getValues()); - pass - - def testUMeshTessellate2DCurve1(self): - # A quarter of circle: - mcoords = [0.4,0.0, 0.0,-0.4, 0.283,-0.283] - mconnec = [0,1,2] - - m1 = MEDCouplingUMesh.New() - m1.setMeshDimension(1) - m1.allocateCells(1) - m1.insertNextCell(NORM_SEG3, mconnec) - - myCoords = DataArrayDouble.New(mcoords, 3, 2) - m1.setCoords(myCoords) - - m2 = m1.deepCpy() - m2.tessellate2DCurve(0.1) - # If the following raises, the test will fail automatically: - m2.checkCoherency1(0.0) # eps param not used - - def testIntersect2DMeshesTmp4(self): - m1Coords=[0.,0.,1.,0.,1.5,0.,0.,1.,0.,1.5,-1.,0.,-1.5,0.,0.,-1,0.,-1.5,0.5,0.,1.25,0.,0.70710678118654757,0.70710678118654757,1.0606601717798214,1.0606601717798214,0.,0.5,0.,1.25,-0.70710678118654757,0.70710678118654757,-1.0606601717798214,1.0606601717798214,-0.5,0.,-1.25,0.,-0.70710678118654757,-0.70710678118654757,-1.0606601717798214,-1.0606601717798214,0.,-0.5,0.,-1.25,0.70710678118654757,-0.70710678118654757,1.0606601717798214,-1.0606601717798214]; - m1Conn=[0,3,1,13,11,9, 3,4,2,1,14,12,10,11, 5,3,0,15,13,17, 6,4,3,5,16,14,15,18, 5,0,7,17,21,19, 6,5,7,8,18,19,22,20, 0,1,7,9,23,21, 1,2,8,7,10,24,22,23]; - m1=MEDCouplingUMesh.New(); - m1.setMeshDimension(2); - m1.allocateCells(8); - m1.insertNextCell(NORM_TRI6,6,m1Conn[0:6]); - m1.insertNextCell(NORM_QUAD8,8,m1Conn[6:14]); - m1.insertNextCell(NORM_TRI6,6,m1Conn[14:20]); - m1.insertNextCell(NORM_QUAD8,8,m1Conn[20:28]); - m1.insertNextCell(NORM_TRI6,6,m1Conn[28:34]); - m1.insertNextCell(NORM_QUAD8,8,m1Conn[34:42]); - m1.insertNextCell(NORM_TRI6,6,m1Conn[42:48]); - m1.insertNextCell(NORM_QUAD8,8,m1Conn[48:56]); - m1.finishInsertingCells(); - myCoords1=DataArrayDouble.New(); - myCoords1.setValues(m1Coords,25,2); - m1.setCoords(myCoords1); - # - m2Coords=[0.,0.,1.1,0.,1.1,1.,0.,1.,1.7,0.,1.7,1.,-1.1,1.,-1.1,0.,-1.7,0.,-1.7,1.,-1.7,-1,-1.1,-1.,0.,-1.,1.1,-1,1.7,-1.] - m2Conn=[0,3,2,1, 1,2,5,4, 7,6,3,0, 8,9,6,7, 7,0,12,11, 8,7,11,10, 0,1,13,12, 1,4,14,13] - m2=MEDCouplingUMesh.New(); - m2.setMeshDimension(2); - m2.allocateCells(8); - for i in xrange(8): - m2.insertNextCell(NORM_QUAD4,4,m2Conn[4*i:4*(i+1)]) - pass - m2.finishInsertingCells(); - myCoords2=DataArrayDouble.New(); - myCoords2.setValues(m2Coords,15,2); - m2.setCoords(myCoords2); - # - m3,d1,d2=MEDCouplingUMesh.Intersect2DMeshes(m2,m1,1e-10) - m3.unPolyze() - # - expected1=[0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7] - expected2=[0,1,1,-1,2,3,3,-1,4,5,5,-1,6,7,7,-1] - self.assertEqual(16,d1.getNumberOfTuples()); - self.assertEqual(16,d2.getNumberOfTuples()); - self.assertEqual(16,m3.getNumberOfCells()); - self.assertEqual(104,m3.getNumberOfNodes()); - self.assertEqual(2,m3.getSpaceDimension()); - self.assertEqual(expected1,d1.getValues()); - self.assertEqual(expected2,d2.getValues()); - expected3=[6,16,15,18,44,45,46,8,18,2,1,16,47,48,49,50,8,17,1,2,40,51,52,53,54,8,40,5,4,17,55,56,57,58,6,18,15,20,59,60,61,8,20,7,6,18,62,63,64,65,8,41,6,7,21,66,67,68,69,8,21,8,9,41,70,71,72,73,6,20,15,22,74,75,76,8,22,11,7,20,77,78,79,80,8,21,7,11,42,81,82,83,84,8,42,10,8,21,85,86,87,88,6,22,15,16,89,90,91,8,16,1,13,22,92,93,94,95,8,43,13,1,17,96,97,98,99,8,17,4,14,43,100,101,102,103] - expected4=[0,7,16,25,34,41,50,59,68,75,84,93,102,109,118,127,136] - expected5=[0.,0.,1.1, 0.,1.1,1.,0.,1.,1.7,0.,1.7,1.,-1.1,1.,-1.1,0.,-1.7,0.,-1.7,1.,-1.7,-1.,-1.1,-1.,0.,-1.,1.1,-1.,1.7,-1.,0.,0.,1.,0.,1.5,0.,0.,1.,0.,1.5,-1.,0.,-1.5,0.,0.,-1.,0.,-1.5,0.5,0.,1.25,0.,0.7071067811865476,0.7071067811865476,1.0606601717798214,1.0606601717798214,0.,0.5,0.,1.25,-0.7071067811865476,0.7071067811865476,-1.0606601717798214,1.0606601717798214,-0.5,0.,-1.25,0.,-0.7071067811865476,-0.7071067811865476,-1.0606601717798214,-1.0606601717798214,0.,-0.5,0.,-1.25,0.7071067811865476,-0.7071067811865476,1.0606601717798214,-1.0606601717798214,1.1180339887498951,1.,-1.1180339887498951,1.,-1.1180339887498951,-1.,1.1180339887498951,-1.,0.5,0.,0.,0.5,0.7071067811865477,0.7071067811865476,0.55,1.,1.1,0.5,1.05,0.,0.7071067811865477,0.7071067811865475,1.3,0.,1.1,0.5,1.1090169943749475,1.,1.4012585384440737,0.535233134659635,1.4090169943749475,1.,1.7,0.5,1.6,0.,1.4012585384440737,0.535233134659635,0.,0.5,-0.5,0.,-0.7071067811865477,0.7071067811865476,-1.05,0.,-1.1,0.5,-0.55,1.,-0.7071067811865478,0.7071067811865475,-1.1090169943749475,1.,-1.1,0.5,-1.3,0.,-1.4012585384440737,0.5352331346596344,-1.6,0.,-1.7,0.5,-1.4090169943749475,1.,-1.4012585384440737,0.5352331346596344,-0.5,0.,0.,-0.5,-0.7071067811865475,-0.7071067811865477,-0.55,-1.,-1.1,-0.5,-1.05,0.,-0.7071067811865475,-0.7071067811865477,-1.3,0.,-1.1,-0.5,-1.1090169943749475,-1.,-1.4012585384440734,-0.5352331346596354,-1.4090169943749475,-1.,-1.7,-0.5,-1.6,0.,-1.4012585384440732,-0.5352331346596354,0.,-0.5,0.5,0.,0.7071067811865475,-0.7071067811865477,1.05,0.,1.1,-0.5,0.55,-1.,0.7071067811865475,-0.7071067811865477,1.1090169943749475,-1.,1.1,-0.5,1.3,0.,1.4012585384440737,-0.535233134659635,1.6,0.,1.7,-0.5,1.4090169943749475,-1.,1.4012585384440737,-0.535233134659635] - self.assertEqual(136,m3.getNodalConnectivity().getNumberOfTuples()); - self.assertEqual(17,m3.getNodalConnectivityIndex().getNumberOfTuples()); - self.assertEqual(expected3,m3.getNodalConnectivity().getValues()); - self.assertEqual(expected4,m3.getNodalConnectivityIndex().getValues()); - for i in xrange(208): - self.assertAlmostEqual(expected5[i],m3.getCoords().getIJ(0,i),12); - pass - pass - - def testGetCellIdsCrossingPlane1(self): - mesh3D,mesh2D=MEDCouplingDataForTest.build3DExtrudedUMesh_1(); - vec=[-0.07,1.,0.07] - origin=[1.524,1.4552,1.74768] - ids1=mesh3D.getCellIdsCrossingPlane(origin,vec,1e-10) - self.assertEqual([1,3,4,7,9,10,13,15,16],ids1.getValues()) - vec2=[0.,0.,1.] - ids2=mesh3D.getCellIdsCrossingPlane(origin,vec2,1e-10) - self.assertEqual([6,7,8,9,10,11],ids2.getValues()) - pass - - def testBuildSlice3D1(self): - mesh3D,mesh2D=MEDCouplingDataForTest.build3DExtrudedUMesh_1(); - vec1=[-0.07,1.,0.07] - origin1=[1.524,1.4552,1.74768] - slice1,ids=mesh3D.buildSlice3D(origin1,vec1,1e-10); - expected1=[1,3,4,7,9,10,13,15,16] - expected2=[5,42,41,40,43,44,5,42,46,45,41,5,44,43,40,47,48,5,49,42,44,50,5,49,51,46,42,5,50,44,48,52,5,53,49,50,54,5,53,55,51,49,5,54,50,52,56] - expected3=[0,6,11,17,22,27,32,37,42,47] - expected4=[1.,1.,0.,1.,1.25,0.,1.,1.5,0.,2.,1.,0.,1.,2.,0.,0.,2.,0.,3.,1.,0.,3.,2.,0.,0.,1.,0.,2.,2.,0.,1.,1.,1.,1.,1.25,1.,1.,1.5,1.,2.,1.,1.,1.,2.,1.,0.,2.,1.,3.,1.,1.,3.,2.,1.,0.,1.,1.,2.,2.,1.,1.,1.,2.,1.,1.25,2.,1.,1.5,2.,2.,1.,2.,1.,2.,2.,0.,2.,2.,3.,1.,2.,3.,2.,2.,0.,1.,2.,2.,2.,2.,1.,1.,3.,1.,1.25,3.,1.,1.5,3.,2.,1.,3.,1.,2.,3.,0.,2.,3.,3.,1.,3.,3.,2.,3.,0.,1.,3.,2.,2.,3.,1.,1.5408576,0.,2.,1.6108576000000001,0.,2.,1.5408576,1.,1.,1.5,0.5836800000000008,1.,1.4708576,1.,3.,1.6808576,0.,3.,1.6108576000000001,1.,0.,1.4708576,0.,0.,1.4008576,1.,2.,1.4708576,2.,1.,1.4008576000000001,2.,3.,1.5408575999999998,2.,0.,1.3308575999999999,2.,2.,1.4008576,3.,1.,1.3308576,3.,3.,1.4708576,3.,0.,1.2608576,3.] - self.assertEqual(2,slice1.getMeshDimension()); - self.assertEqual(3,slice1.getSpaceDimension()); - self.assertEqual(57,slice1.getNumberOfNodes()); - self.assertEqual(9,slice1.getNumberOfCells()); - self.assertEqual(9,ids.getNumberOfTuples()); - self.assertEqual(47,slice1.getNodalConnectivity().getNumberOfTuples()); - self.assertEqual(10,slice1.getNodalConnectivityIndex().getNumberOfTuples()); - self.assertEqual(expected1,ids.getValues()); - self.assertEqual(expected2,slice1.getNodalConnectivity().getValues()); - self.assertEqual(expected3,slice1.getNodalConnectivityIndex().getValues()); - for i in xrange(171): - self.assertAlmostEqual(expected4[i],slice1.getCoords().getIJ(0,i),12); - pass - # 2nd slice based on already existing nodes of mesh3D. - vec2=[0.,3.,1.] - origin2=[2.5,1.,3.] - slice1,ids=mesh3D.buildSlice3D(origin2,vec2,1e-10); - expected5=[5,50,10,4,51,5,50,52,7,10,5,51,4,5,53,5,54,50,51,55,56,5,54,57,52,50,5,56,55,51,53,58,5,38,59,56,54,43,5,54,57,46,43,5,38,59,56,58,48] - expected6=[0,5,10,15,21,26,32,38,43,49] - expected7=[1.,1.,0.,1.,1.25,0.,1.,1.5,0.,2.,1.,0.,1.,2.,0.,0.,2.,0.,3.,1.,0.,3.,2.,0.,0.,1.,0.,1.,3.,0.,2.,2.,0.,2.,3.,0.,1.,1.,1.,1.,1.25,1.,1.,1.5,1.,2.,1.,1.,1.,2.,1.,0.,2.,1.,3.,1.,1.,3.,2.,1.,0.,1.,1.,1.,3.,1.,2.,2.,1.,2.,3.,1.,0.,0.,2.,1.,1.,2.,1.,1.25,2.,1.,0.,2.,1.,1.5,2.,2.,0.,2.,2.,1.,2.,1.,2.,2.,0.,2.,2.,3.,1.,2.,3.,2.,2.,0.,1.,2.,2.,2.,2.,0.,0.,3.,1.,1.,3.,1.,1.25,3.,1.,0.,3.,1.,1.5,3.,2.,0.,3.,2.,1.,3.,1.,2.,3.,0.,2.,3.,3.,1.,3.,3.,2.,3.,0.,1.,3.,2.,2.,3.,2.,1.6666666666666667,1.,1.,1.6666666666666667,1.,3.,1.6666666666666667,1.,0.,1.6666666666666667,1.,2.,1.3333333333333335,2.,1.,1.5,1.5,1.,1.3333333333333333,2.,3.,1.3333333333333335,2.,0.,1.3333333333333335,2.,1.,1.25,2.25] - self.assertEqual(2,slice1.getMeshDimension()); - self.assertEqual(3,slice1.getSpaceDimension()); - self.assertEqual(60,slice1.getNumberOfNodes()); - self.assertEqual(9,slice1.getNumberOfCells()); - self.assertEqual(9,ids.getNumberOfTuples()); - self.assertEqual(49,slice1.getNodalConnectivity().getNumberOfTuples()); - self.assertEqual(10,slice1.getNodalConnectivityIndex().getNumberOfTuples()); - self.assertEqual(expected1,ids.getValues()); - self.assertEqual(expected5,slice1.getNodalConnectivity().getValues()); - self.assertEqual(expected6,slice1.getNodalConnectivityIndex().getValues()); - for i in xrange(180): - self.assertAlmostEqual(expected7[i],slice1.getCoords().getIJ(0,i),12); - pass - # 3rd slice based on shared face of mesh3D. - vec3=[0.,0.,1.] - origin3=[2.5,1.,2.] - slice1,ids=mesh3D.buildSlice3D(origin3,vec3,1e-10); - expected8=[6,7,8,9,10,11,12,13,14,15,16,17] - expected9=[5,15,26,16,18,5,16,21,28,22,19,17,5,18,20,21,16,5,21,24,25,28,5,26,16,17,19,22,23,5,22,27,29,28,5,15,26,16,18,5,16,21,28,22,19,17,5,18,20,21,16,5,21,24,25,28,5,26,16,17,19,22,23,5,22,27,29,28] - expected10=[0,5,12,17,22,29,34,39,46,51,56,63,68] - expected11=[0.,0.,1.,1.,1.,1.,1.,1.25,1.,1.,0.,1.,1.,1.5,1.,2.,0.,1.,2.,1.,1.,1.,2.,1.,0.,2.,1.,3.,1.,1.,3.,2.,1.,0.,1.,1.,1.,3.,1.,2.,2.,1.,2.,3.,1.,0.,0.,2.,1.,1.,2.,1.,1.25,2.,1.,0.,2.,1.,1.5,2.,2.,0.,2.,2.,1.,2.,1.,2.,2.,0.,2.,2.,3.,1.,2.,3.,2.,2.,0.,1.,2.,1.,3.,2.,2.,2.,2.,2.,3.,2.,0.,0.,3.,1.,1.,3.,1.,1.25,3.,1.,0.,3.,1.,1.5,3.,2.,0.,3.,2.,1.,3.,1.,2.,3.,0.,2.,3.,3.,1.,3.,3.,2.,3.,0.,1.,3.,1.,3.,3.,2.,2.,3.,2.,3.,3.] - self.assertEqual(2,slice1.getMeshDimension()); - self.assertEqual(3,slice1.getSpaceDimension()); - self.assertEqual(45,slice1.getNumberOfNodes()); - self.assertEqual(12,slice1.getNumberOfCells()); - self.assertEqual(12,ids.getNumberOfTuples()); - self.assertEqual(68,slice1.getNodalConnectivity().getNumberOfTuples()); - self.assertEqual(13,slice1.getNodalConnectivityIndex().getNumberOfTuples()); - self.assertEqual(expected8,ids.getValues()); - self.assertEqual(expected9,slice1.getNodalConnectivity().getValues()); - self.assertEqual(expected10,slice1.getNodalConnectivityIndex().getValues()); - for i in xrange(135): - self.assertAlmostEqual(expected11[i],slice1.getCoords().getIJ(0,i),12); - pass - pass - - def testBuildSlice3DSurf1(self): - mesh3D,mesh2D=MEDCouplingDataForTest.build3DExtrudedUMesh_1(); - mesh2D=mesh3D.buildDescendingConnectivity()[0]; - vec1=[-0.07,1.,0.07] - origin1=[1.524,1.4552,1.74768] - slice1,ids=mesh2D.buildSlice3DSurf(origin1,vec1,1e-10); - expected1=[6,8,10,11,13,18,19,21,23,25,26,38,41,43,47,49,52,53,64,67,69,73,75,78,79] - expected2=[1,40,41,1,42,41,1,40,43,1,44,43,1,42,44,1,45,41,1,42,46,1,46,45,1,47,40,1,47,48,1,44,48,1,49,42,1,44,50,1,49,50,1,49,51,1,51,46,1,48,52,1,50,52,1,53,49,1,50,54,1,53,54,1,53,55,1,55,51,1,52,56,1,54,56] - expected3=[0,3,6,9,12,15,18,21,24,27,30,33,36,39,42,45,48,51,54,57,60,63,66,69,72,75]; - expected4=[1.,1.,0.,1.,1.25,0.,1.,1.5,0.,2.,1.,0.,1.,2.,0.,0.,2.,0.,3.,1.,0.,3.,2.,0.,0.,1.,0.,2.,2.,0.,1.,1.,1.,1.,1.25,1.,1.,1.5,1.,2.,1.,1.,1.,2.,1.,0.,2.,1.,3.,1.,1.,3.,2.,1.,0.,1.,1.,2.,2.,1.,1.,1.,2.,1.,1.25,2.,1.,1.5,2.,2.,1.,2.,1.,2.,2.,0.,2.,2.,3.,1.,2.,3.,2.,2.,0.,1.,2.,2.,2.,2.,1.,1.,3.,1.,1.25,3.,1.,1.5,3.,2.,1.,3.,1.,2.,3.,0.,2.,3.,3.,1.,3.,3.,2.,3.,0.,1.,3.,2.,2.,3.,1.,1.5408576,0.,2.,1.6108576000000001,0.,2.,1.5408576,1.,1.,1.5,0.5836800000000008,1.,1.4708576,1.,3.,1.6808576,0.,3.,1.6108576000000001,1.,0.,1.4708576,0.,0.,1.4008576,1.,2.,1.4708576,2.,1.,1.4008576000000001,2.,3.,1.5408575999999998,2.,0.,1.3308575999999999,2.,2.,1.4008576,3.,1.,1.3308576,3.,3.,1.4708576,3.,0.,1.2608576,3.] - self.assertEqual(1,slice1.getMeshDimension()); - self.assertEqual(3,slice1.getSpaceDimension()); - self.assertEqual(57,slice1.getNumberOfNodes()); - self.assertEqual(25,slice1.getNumberOfCells()); - self.assertEqual(25,ids.getNumberOfTuples()); - self.assertEqual(75,slice1.getNodalConnectivity().getNumberOfTuples()); - self.assertEqual(26,slice1.getNodalConnectivityIndex().getNumberOfTuples()); - self.assertEqual(expected1,ids.getValues()); - self.assertEqual(expected2,slice1.getNodalConnectivity().getValues()); - self.assertEqual(expected3,slice1.getNodalConnectivityIndex().getValues()); - for i in xrange(171): - self.assertAlmostEqual(expected4[i],slice1.getCoords().getIJ(0,i),12); - pass - # - vec2=[0.,0.,1.] - origin2=[2.5,1.,2.] - slice1,ids=mesh2D.buildSlice3DSurf(origin2,vec2,1e-10); - expected5=[32,32,32,32,33,34,35,36,37,38,39,40,41,42,43,43,43,43,43,43,44,44,44,44,45,46,47,47,47,47,48,49,50,51,52,53,53,53,53,53,53,54,54,54,54,55,56,57,59,60,61,62,63,64,65,66,67,68,71,72,74,75,76,77,78,81,82,83] - expected6=[1,15,18,1,18,16,1,16,26,1,26,15,1,26,15,1,16,26,1,18,16,1,15,18,1,16,21,1,21,28,1,22,28,1,19,22,1,17,19,1,16,17,1,16,21,1,21,28,1,28,22,1,22,19,1,19,17,1,17,16,1,16,18,1,18,20,1,20,21,1,21,16,1,20,21,1,18,20,1,28,21,1,21,24,1,24,25,1,25,28,1,25,28,1,24,25,1,21,24,1,23,22,1,26,23,1,26,16,1,16,17,1,17,19,1,19,22,1,22,23,1,23,26,1,22,28,1,28,29,1,29,27,1,27,22,1,27,22,1,29,27,1,28,29,1,26,15,1,16,26,1,18,16,1,15,18,1,16,21,1,21,28,1,22,28,1,19,22,1,17,19,1,16,17,1,20,21,1,18,20,1,25,28,1,24,25,1,21,24,1,23,22,1,26,23,1,27,22,1,29,27,1,28,29] - expected7=[0,3,6,9,12,15,18,21,24,27,30,33,36,39,42,45,48,51,54,57,60,63,66,69,72,75,78,81,84,87,90,93,96,99,102,105,108,111,114,117,120,123,126,129,132,135,138,141,144,147,150,153,156,159,162,165,168,171,174,177,180,183,186,189,192,195,198,201,204]; - expected8=[0.,0.,1.,1.,1.,1.,1.,1.25, 1.,1.,0.,1.,1.,1.5, 1.,2.,0.,1.,2.,1.,1.,1.,2.,1.,0.,2.,1.,3.,1.,1.,3.,2.,1.,0.,1.,1.,1.,3.,1.,2.,2.,1.,2.,3.,1.,0.,0.,2.,1.,1.,2.,1.,1.25, 2.,1.,0.,2.,1.,1.5, 2.,2.,0.,2.,2.,1.,2.,1.,2.,2.,0.,2.,2.,3.,1.,2.,3.,2.,2.,0.,1.,2.,1.,3.,2.,2.,2.,2.,2.,3.,2.,0.,0.,3.,1.,1.,3.,1.,1.25, 3.,1.,0.,3.,1.,1.5, 3.,2.,0.,3.,2.,1.,3.,1.,2.,3.,0.,2.,3.,3.,1.,3.,3.,2.,3.,0.,1.,3.,1.,3.,3.,2.,2.,3.,2.,3.,3.] - self.assertEqual(1,slice1.getMeshDimension()); - self.assertEqual(3,slice1.getSpaceDimension()); - self.assertEqual(45,slice1.getNumberOfNodes()); - self.assertEqual(68,slice1.getNumberOfCells()); - self.assertEqual(68,ids.getNumberOfTuples()); - self.assertEqual(204,slice1.getNodalConnectivity().getNumberOfTuples()); - self.assertEqual(69,slice1.getNodalConnectivityIndex().getNumberOfTuples()); - self.assertEqual(expected5,ids.getValues()); - self.assertEqual(expected6,slice1.getNodalConnectivity().getValues()); - self.assertEqual(expected7,slice1.getNodalConnectivityIndex().getValues()); - for i in xrange(135): - self.assertAlmostEqual(expected8[i],slice1.getCoords().getIJ(0,i),12); - pass - pass - - def testDataArrayDoubleAdvSetting1(self): - data1=[1.,11.,2.,12.,3.,13.,4.,14.,5.,15.,6.,16.,7.,17.] - data2=[8.,38.,9.,39.,0.,30.,11.,41.,12.,42.] - compsCpp=["comp1","comp2"] - da=DataArrayDouble.New(); - da.setInfoAndChangeNbOfCompo(compsCpp); - da.setName("da"); - da.alloc(7,2); - compsCpp=compsCpp[:-1] - self.assertRaises(InterpKernelException,da.setInfoAndChangeNbOfCompo,compsCpp); - da.setValues(data1,7,2) - # - p=[(0,3),(3,5),(5,7)] - tmp=da.selectByTupleRanges(p); - self.assertTrue(tmp.isEqual(da,1e-14)); - p=[(0,2),(3,4),(5,7)] - tmp=da.selectByTupleRanges(p); - expected1=[1.,11.,2.,12.,4.,14.,6.,16.,7.,17.] - self.assertEqual(5,tmp.getNumberOfTuples()); - self.assertEqual(2,tmp.getNumberOfComponents()); - for i in xrange(10): - self.assertAlmostEqual(expected1[i],tmp.getIJ(0,i),14); - pass - p=[(0,2),(0,2),(5,6)] - tmp=da.selectByTupleRanges(p); - expected2=[1.,11.,2.,12.,1.,11.,2.,12.,6.,16.] - self.assertEqual(5,tmp.getNumberOfTuples()); - self.assertEqual(2,tmp.getNumberOfComponents()); - for i in xrange(10): - self.assertAlmostEqual(expected2[i],tmp.getIJ(0,i),14); - pass - p=[(0,2),(-1,2),(5,6)] - self.assertRaises(InterpKernelException,da.selectByTupleRanges,p); - p=[(0,2),(0,2),(5,8)] - self.assertRaises(InterpKernelException,da.selectByTupleRanges,p); - # - da2=DataArrayDouble.New(); - da2.setValues(data2,5,2); - # - dac=da.deepCpy(); - dac.setContigPartOfSelectedValues2(1,da2,2,4,1); - expected3=[1.,11.,0.,30.,11.,41.,4.,14.,5.,15.,6.,16.,7.,17.] - for i in xrange(14): - self.assertAlmostEqual(expected3[i],dac.getIJ(0,i),14); - pass - # - dac=da.deepCpy(); - self.assertRaises(InterpKernelException,dac.setContigPartOfSelectedValues2,3,da2,0,5,1); - self.assertRaises(InterpKernelException,dac.setContigPartOfSelectedValues2,0,da2,4,6,1); - self.assertRaises(InterpKernelException,dac.setContigPartOfSelectedValues2,3,da2,5,0,1); - dac.setContigPartOfSelectedValues2(3,da2,1,5,1); - expected4=[1.,11.,2.,12.,3.,13.,9.,39.,0.,30.,11.,41.,12.,42.] - for i in xrange(14): - self.assertAlmostEqual(expected4[i],dac.getIJ(0,i),14); - pass - # - ids=DataArrayInt.New(); - ids.alloc(3,1); - dac=da.deepCpy(); - ids.setIJ(0,0,2); ids.setIJ(1,0,0); ids.setIJ(2,0,4); - dac.setContigPartOfSelectedValues(2,da2,ids); - expected5=[1.,11.,2.,12.,0.,30.,8.,38.,12.,42.,6.,16.,7.,17.] - for i in xrange(14): - self.assertAlmostEqual(expected5[i],dac.getIJ(0,i),14); - pass - # - dac=da.deepCpy(); - ids.setIJ(0,0,2); ids.setIJ(1,0,5); ids.setIJ(2,0,4); - self.assertRaises(InterpKernelException,dac.setContigPartOfSelectedValues,1,da2,ids); - ids.setIJ(0,0,2); ids.setIJ(1,0,2); ids.setIJ(2,0,-1); - self.assertRaises(InterpKernelException,dac.setContigPartOfSelectedValues,1,da2,ids); - ids.setIJ(0,0,2); ids.setIJ(1,0,2); ids.setIJ(2,0,1); - self.assertRaises(InterpKernelException,dac.setContigPartOfSelectedValues,5,da2,ids); - # - ids.setIJ(0,0,2); ids.setIJ(1,0,2); ids.setIJ(2,0,1); - dac=da.deepCpy(); - dac.setContigPartOfSelectedValues(4,da2,ids); - expected6=[1.,11.,2.,12.,3.,13.,4.,14.,0.,30.,0.,30.,9.,39.] - for i in xrange(14): - self.assertAlmostEqual(expected6[i],dac.getIJ(0,i),14); - pass - pass - - def testDataArrayIntAdvSetting1(self): - data1=[1,11,2,12,3,13,4,14,5,15,6,16,7,17] - data2=[8,38,9,39,0,30,11,41,12,42] - compsCpp=["comp1","comp2"] - da=DataArrayInt.New(); - da.setInfoAndChangeNbOfCompo(compsCpp); - da.setName("da"); - da.alloc(7,2); - compsCpp=compsCpp[:-1] - self.assertRaises(InterpKernelException,da.setInfoAndChangeNbOfCompo,compsCpp); - da.setValues(data1,7,2) - # - p=[(0,3),(3,5),(5,7)] - tmp=da.selectByTupleRanges(p); - self.assertTrue(tmp.isEqual(da)); - p=[(0,2),(3,4),(5,7)] - tmp=da.selectByTupleRanges(p); - expected1=[1,11,2,12,4,14,6,16,7,17] - self.assertEqual(5,tmp.getNumberOfTuples()); - self.assertEqual(2,tmp.getNumberOfComponents()); - for i in xrange(10): - self.assertEqual(expected1[i],tmp.getIJ(0,i)); - pass - p=[(0,2),(0,2),(5,6)] - tmp=da.selectByTupleRanges(p); - expected2=[1,11,2,12,1,11,2,12,6,16] - self.assertEqual(5,tmp.getNumberOfTuples()); - self.assertEqual(2,tmp.getNumberOfComponents()); - for i in xrange(10): - self.assertEqual(expected2[i],tmp.getIJ(0,i)); - pass - p=[(0,2),(-1,2),(5,6)] - self.assertRaises(InterpKernelException,da.selectByTupleRanges,p); - p=[(0,2),(0,2),(5,8)] - self.assertRaises(InterpKernelException,da.selectByTupleRanges,p); - # - da2=DataArrayInt.New(); - da2.setValues(data2,5,2); - # - dac=da.deepCpy(); - dac.setContigPartOfSelectedValues2(1,da2,2,4,1); - expected3=[1,11,0,30,11,41,4,14,5,15,6,16,7,17] - for i in xrange(14): - self.assertEqual(expected3[i],dac.getIJ(0,i)); - pass - # - dac=da.deepCpy(); - self.assertRaises(InterpKernelException,dac.setContigPartOfSelectedValues2,3,da2,0,5,1); - self.assertRaises(InterpKernelException,dac.setContigPartOfSelectedValues2,0,da2,4,6,1); - self.assertRaises(InterpKernelException,dac.setContigPartOfSelectedValues2,3,da2,5,0,1); - dac.setContigPartOfSelectedValues2(3,da2,1,5,1); - expected4=[1,11,2,12,3,13,9,39,0,30,11,41,12,42] - for i in xrange(14): - self.assertEqual(expected4[i],dac.getIJ(0,i)); - pass - # - ids=DataArrayInt.New(); - ids.alloc(3,1); - dac=da.deepCpy(); - ids.setIJ(0,0,2); ids.setIJ(1,0,0); ids.setIJ(2,0,4); - dac.setContigPartOfSelectedValues(2,da2,ids); - expected5=[1,11,2,12,0,30,8,38,12,42,6,16,7,17] - for i in xrange(14): - self.assertEqual(expected5[i],dac.getIJ(0,i)); - pass - # - dac=da.deepCpy(); - ids.setIJ(0,0,2); ids.setIJ(1,0,5); ids.setIJ(2,0,4); - self.assertRaises(InterpKernelException,dac.setContigPartOfSelectedValues,1,da2,ids); - ids.setIJ(0,0,2); ids.setIJ(1,0,2); ids.setIJ(2,0,-1); - self.assertRaises(InterpKernelException,dac.setContigPartOfSelectedValues,1,da2,ids); - ids.setIJ(0,0,2); ids.setIJ(1,0,2); ids.setIJ(2,0,1); - self.assertRaises(InterpKernelException,dac.setContigPartOfSelectedValues,5,da2,ids); - # - ids.setIJ(0,0,2); ids.setIJ(1,0,2); ids.setIJ(2,0,1); - dac=da.deepCpy(); - dac.setContigPartOfSelectedValues(4,da2,ids); - expected6=[1,11,2,12,3,13,4,14,0,30,0,30,9,39] - for i in xrange(14): - self.assertEqual(expected6[i],dac.getIJ(0,i)); - pass - pass - - def testBuildDescendingConnec2Of3DMesh1(self): - mesh=MEDCouplingDataForTest.build3DSourceMesh_1(); - # - mesh2,desc,descIndx,revDesc,revDescIndx=mesh.buildDescendingConnectivity2(); - mesh2.checkCoherency(); - self.assertEqual(2,mesh2.getMeshDimension()); - self.assertEqual(30,mesh2.getNumberOfCells()); - self.assertEqual(31,revDescIndx.getNbOfElems()); self.assertEqual(31,revDescIndx.getNumberOfTuples()); - self.assertEqual(13,descIndx.getNbOfElems()); self.assertEqual(13,descIndx.getNumberOfTuples()); - self.assertEqual(48,desc.getNbOfElems()); self.assertEqual(48,desc.getNumberOfTuples()); - self.assertEqual(48,revDesc.getNbOfElems()); self.assertEqual(48,revDesc.getNumberOfTuples()); - expected1=[1,2,3,4,5,6,7,8,9,10,11,12,13,14,-10,15,-5,-13,16,17,-14,18,-4,19,-2,20,21,22,23,24,25,-11,26,-1,-12,-25,-22,27,28,-7,-20,-24,29,-16,-18,30,-8,-28] - self.assertEqual(expected1,desc.getValues()); - expected2=[0,4,8,12,16,20,24,28,32,36,40,44,48] - self.assertEqual(expected2,descIndx.getValues()); - expected3=[0,2,4,5,7,9,10,12,14,15,17,19,21,23,25,26,28,29,31,32,34,35,37,38,40,42,43,44,46,47,48] - self.assertEqual(expected3,revDescIndx.getValues()); - expected4=[0,8,0,6,0,0,5,1,4,1,1,9,1,11,2,2,3,2,7,2,8,3,4,3,5,3,4,10,4,5,11,5,6,10,6,6,9,7,7,10,7,8,8,9,9,11,10,11] - self.assertEqual(expected4,revDesc.getValues()); - conn=mesh2.getNodalConnectivity(); - connIndex=mesh2.getNodalConnectivityIndex(); - expected5=[0,4,8,12,16,20,24,28,32,36,40,44,48,52,56,60,64,68,72,76,80,84,88,92,96,100,104,108,112,116,120] - self.assertEqual(expected5,connIndex.getValues()); - expected6=[3,8,1,7,3,8,3,1,3,1,3,7,3,7,3,8,3,6,0,8,3,6,2,0,3,0,2,8,3,8,2,6,3,7,4,5,3,7,8,4,3,4,8,5,3,5,8,7,3,6,8,4,3,6,7,8,3,4,7,6,3,8,4,0,3,0,4,6,3,6,3,8,3,7,3,6,3,8,0,1,3,1,0,3,3,3,0,8,3,4,1,5,3,4,8,1,3,1,8,5,3,1,7,5,3,0,2,3,3,3,2,8,3,1,4,0,3,3,2,6] - self.assertEqual(expected6,conn.getValues()); - pass - - def testAre2DCellsNotCorrectlyOriented1(self): - m1Coords=[1.,1.,-1.,-1.,-1.,-1.,1.,-1.] - m1Conn=[0,3,1,2] - m1=MEDCouplingUMesh.New(); - m1.setMeshDimension(2); - m1.allocateCells(1); - m1.insertNextCell(NORM_QUAD4,4,m1Conn[0:4]) - m1.finishInsertingCells(); - myCoords1=DataArrayDouble.New(); - myCoords1.setValues(m1Coords,4,2); - m1.setCoords(myCoords1); - # - vec1=[0.,0.,1.] - for i in xrange(18): - vec2=[3.*cos(pi/9.*i),3.*sin(pi/9.*i)]; - m1Cpy=m1.deepCpy(); - m1Cpy.translate(vec2); - self.assertRaises(InterpKernelException,m1Cpy.are2DCellsNotCorrectlyOriented,vec1,False); - m1Cpy.changeSpaceDimension(3); - res=m1Cpy.are2DCellsNotCorrectlyOriented(vec1,False) - self.assertEqual([0],res.getValues()); - pass - pass - - def testDataArrayAbs1(self): - d1=DataArrayDouble.New(); - val1=[2.,-3.,-5.,6.,-7.,-8.,9.,10.,-11.,-12.,-13.,-15.] - expected1=[2.,3.,5.,6.,7.,8.,9.,10.,11.,12.,13.,15.] - d1.setValues(val1,6,2); - d2=d1.convertToIntArr(); - # - d1.abs(); - for i in xrange(12): - self.assertAlmostEqual(expected1[i],d1.getIJ(0,i),14); - pass - # - expected2=[2,3,5,6,7,8,9,10,11,12,13,15] - d2.abs(); - for i in xrange(12): - self.assertEqual(expected2[i],d2.getIJ(0,i)); - pass - # - pass - - # test on 1D - def testGetValueOn3(self): - v=[0.,1.,1.5,2.] - v2=[0.7,1.25,0.,2.,1.5] - disp=[5.,50.,500.,6.,60.,600.,7.,70.,700.,8.,80.,800.] - m=MEDCouplingUMesh.New("myMesh",1) - nbNodes=len(v) - nbCells=nbNodes-1 - m.allocateCells(nbCells) - coords=DataArrayDouble.New() ; coords.setValues(v,nbNodes,1) - m.setCoords(coords) - m.insertNextCell(NORM_SEG2,2,[0,1]) - m.insertNextCell(NORM_SEG2,2,[2,1]) - m.insertNextCell(NORM_SEG2,2,[2,3]) - m.finishInsertingCells() - f=MEDCouplingFieldDouble.New(ON_NODES) - f.setMesh(m) - array=DataArrayDouble.New(); array.setValues(disp,m.getNumberOfNodes(),3) - f.setArray(array) - arr1=f.getValueOnMulti(v2) - self.assertEqual(5,arr1.getNumberOfTuples()); - self.assertEqual(3,arr1.getNumberOfComponents()); - expected1=[5.7,57.,570.,6.5,65.,650.,5.,50.,500.,8.,80.,800.,7.,70.,700.] - for i in xrange(15): - self.assertAlmostEqual(expected1[i],arr1.getIJ(0,i),14); - pass - pass - - def testGetNodeIdsOfCell2(self): - m1c=MEDCouplingCMesh.New(); - coordsX=DataArrayDouble.New(); - arrX=[ -1., 1., 2., 4., 4.5 ] - coordsX.setValues(arrX,5,1); - coordsY=DataArrayDouble.New(); - arrY=[ -2., 2., 4., 8.] - coordsY.setValues(arrY,4,1); - coordsZ=DataArrayDouble.New(); - arrZ=[ -2., 2., 4.] - coordsZ.setValues(arrZ,3,1); - # test in 1D - m1c.setCoordsAt(0,coordsX); - expected1=[[0,1],[1,2],[2,3],[3,4]] - self.assertEqual(4,m1c.getNumberOfCells()) - for i in xrange(m1c.getNumberOfCells()): - self.assertEqual(expected1[i],m1c.getNodeIdsOfCell(i)) - pass - # test in 2D - m1c.setCoordsAt(1,coordsY); - self.assertEqual(12,m1c.getNumberOfCells()) - self.assertEqual(20,m1c.getNumberOfNodes()) - expected2=[[0,1,6,5],[1,2,7,6],[2,3,8,7],[3,4,9,8],[5,6,11,10],[6,7,12,11],[7,8,13,12],[8,9,14,13],[10,11,16,15],[11,12,17,16],[12,13,18,17],[13,14,19,18]] - for i in xrange(m1c.getNumberOfCells()): - self.assertEqual(expected2[i],m1c.getNodeIdsOfCell(i)) - pass - # test in 3D - m1c.setCoordsAt(2,coordsZ); - self.assertEqual(24,m1c.getNumberOfCells()) - self.assertEqual(60,m1c.getNumberOfNodes()) - expected3=[[0,1,6,5,20,21,26,25],[1,2,7,6,21,22,27,26],[2,3,8,7,22,23,28,27],[3,4,9,8,23,24,29,28],[5,6,11,10,25,26,31,30],[6,7,12,11,26,27,32,31],[7,8,13,12,27,28,33,32],[8,9,14,13,28,29,34,33],[10,11,16,15,30,31,36,35],[11,12,17,16,31,32,37,36],[12,13,18,17,32,33,38,37],[13,14,19,18,33,34,39,38],[20,21,26,25,40,41,46,45],[21,22,27,26,41,42,47,46],[22,23,28,27,42,43,48,47],[23,24,29,28,43,44,49,48],[25,26,31,30,45,46,51,50],[26,27,32,31,46,47,52,51],[27,28,33,32,47,48,53,52],[28,29,34,33,48,49,54,53],[30,31,36,35,50,51,56,55],[31,32,37,36,51,52,57,56],[32,33,38,37,52,53,58,57],[33,34,39,38,53,54,59,58]] - self.assertEqual(24,m1c.getNumberOfCells()) - for i in xrange(m1c.getNumberOfCells()): - self.assertEqual(expected3[i],m1c.getNodeIdsOfCell(i)) - pass - pass - - def testSwigDADOp4(self): - da=DataArrayDouble.New(range(6,30),12,2) - self.assertEqual(12,da.getNumberOfTuples()); - self.assertEqual(2,da.getNumberOfComponents()); - for i in xrange(24): - self.assertAlmostEqual(da.getIJ(0,i),float(i+6),13) - pass - # operator transpose - da.transpose() - self.assertEqual(2,da.getNumberOfTuples()); - self.assertEqual(12,da.getNumberOfComponents()); - for i in xrange(24): - self.assertAlmostEqual(da.getIJ(0,i),float(i+6),13) - pass - da.transpose() - # operator __neg__ - da2=DataArrayDouble.New(12,1) - da2.iota(0.) - dabis=-da - for i in xrange(24): - self.assertAlmostEqual(dabis.getIJ(0,i),-float(i+6),13) - pass - # operator+= - da+=da2 - expected1=[6.,7.,9.,10.,12.,13.,15.,16.,18.,19.,21.,22.,24.,25.,27.,28.,30.,31.,33.,34.,36.,37.,39.,40.] - for i in xrange(24): - self.assertAlmostEqual(da.getIJ(0,i),expected1[i],13) - pass - da=-dabis - da+=[100.,101.] - expected2=[106.,108.,108.,110.,110.,112.,112.,114.,114.,116.,116.,118.,118.,120.,120.,122.,122.,124.,124.,126.,126.,128.,128.,130.] - self.assertEqual(12,da.getNumberOfTuples()); - self.assertEqual(2,da.getNumberOfComponents()); - for i in xrange(24): - self.assertAlmostEqual(da.getIJ(0,i),expected2[i],13) - pass - for pos,elt in enumerate(dabis): - da[pos]+=elt - pass - self.assertEqual(12,da.getNumberOfTuples()); - self.assertEqual(2,da.getNumberOfComponents()); - for elt in da: - li=elt[:] - self.assertAlmostEqual(li[0],100.,13) ; self.assertAlmostEqual(li[1],101.,13) - pass - # operator-= - da=DataArrayDouble.New(range(6,30),12,2) - da2=DataArrayDouble.New(range(12),12,1) - dabis=-da - da-=da2 - expected1=[6.,7.,7.,8.,8.,9.,9.,10.,10.,11.,11.,12.,12.,13.,13.,14.,14.,15.,15.,16.,16.,17.,17.,18.] - for i in xrange(24): - self.assertAlmostEqual(da.getIJ(0,i),expected1[i],13) - pass - da=-dabis - da-=[100.,101.] - expected2=[-94.,-94.,-92.,-92.,-90.,-90.,-88.,-88.,-86.,-86.,-84.,-84.,-82.,-82.,-80.,-80.,-78.,-78.,-76.,-76.,-74.,-74.,-72.,-72.] - self.assertEqual(12,da.getNumberOfTuples()); - self.assertEqual(2,da.getNumberOfComponents()); - for i in xrange(24): - self.assertAlmostEqual(da.getIJ(0,i),expected2[i],13) - pass - for pos,elt in enumerate(dabis): - da[pos]-=elt - pass - self.assertEqual(12,da.getNumberOfTuples()); - self.assertEqual(2,da.getNumberOfComponents()); - expected3=[-88.,-87.,-84.,-83.,-80.,-79.,-76.,-75.,-72.,-71.,-68.,-67.,-64.,-63.,-60.,-59.,-56.,-55.,-52.,-51.,-48.,-47.,-44.,-43.] - for i in xrange(24): - self.assertAlmostEqual(da.getIJ(0,i),expected3[i],13) - pass - # operator*= - da=DataArrayDouble.New(range(6,30),12,2) - da2=DataArrayDouble.New(range(12),12,1) - dabis=-da - da*=da2 - expected1=[0.,0.,8.,9.,20.,22.,36.,39.,56.,60.,80.,85.,108.,114.,140.,147.,176.,184.,216.,225.,260.,270.,308.,319.] - for i in xrange(24): - self.assertAlmostEqual(da.getIJ(0,i),expected1[i],13) - pass - da=-dabis - da*=[100.,101.] - expected2=[600.,707.,800.,909.,1000.,1111.,1200.,1313.,1400.,1515.,1600.,1717.,1800.,1919.,2000.,2121.,2200.,2323.,2400.,2525.,2600.,2727.,2800.,2929.] - self.assertEqual(12,da.getNumberOfTuples()); - self.assertEqual(2,da.getNumberOfComponents()); - for i in xrange(24): - self.assertAlmostEqual(da.getIJ(0,i),expected2[i],13) - pass - for pos,elt in enumerate(dabis): - da[pos]*=elt - pass - self.assertEqual(12,da.getNumberOfTuples()); - self.assertEqual(2,da.getNumberOfComponents()); - expected3=[-3600.,-4949.,-6400.,-8181.,-10000.,-12221.,-14400.,-17069.,-19600.,-22725.,-25600.,-29189.,-32400.,-36461.,-40000.,-44541.,-48400.,-53429.,-57600.,-63125.,-67600.,-73629.,-78400.,-84941.0] - for i in xrange(24): - self.assertAlmostEqual(da.getIJ(0,i),expected3[i],13) - pass - # operator/= - da=DataArrayDouble.New(range(6,30),12,2) - da2=DataArrayDouble.New(range(1,13),12,1) - dabis=-da - da/=da2 - expected1=[6.0,7.0,4.0,4.5,3.3333333333333335,3.6666666666666665,3.0,3.25,2.8,3.0,2.6666666666666665,2.8333333333333335,2.5714285714285716,2.7142857142857144,2.5,2.625,2.4444444444444446,2.5555555555555554,2.4,2.5,2.3636363636363638,2.4545454545454546,2.3333333333333335,2.4166666666666665] - for i in xrange(24): - self.assertAlmostEqual(da.getIJ(0,i),expected1[i],13) - pass - da=-dabis - da/=[100.,101.] - expected2=[0.06,0.06930693069306931,0.08,0.0891089108910891,0.1,0.10891089108910891,0.12,0.12871287128712872,0.14,0.1485148514851485,0.16,0.16831683168316833,0.18,0.18811881188118812,0.2,0.2079207920792079,0.22,0.22772277227722773,0.24,0.24752475247524752,0.26,0.26732673267326734,0.28,0.2871287128712871] - self.assertEqual(12,da.getNumberOfTuples()); - self.assertEqual(2,da.getNumberOfComponents()); - for i in xrange(24): - self.assertAlmostEqual(da.getIJ(0,i),expected2[i],13) - pass - for pos,elt in enumerate(dabis): - da[pos]/=elt - pass - self.assertEqual(12,da.getNumberOfTuples()); - self.assertEqual(2,da.getNumberOfComponents()); - expected3=[-0.01, -0.009900990099009901, -0.01, -0.009900990099009901, -0.01, -0.009900990099009901, -0.01, -0.009900990099009901, -0.01, -0.009900990099009901, -0.01, -0.009900990099009901, -0.01, -0.009900990099009901, -0.01, -0.009900990099009901, -0.01, -0.009900990099009901, -0.01, -0.009900990099009901, -0.01, -0.009900990099009901, -0.01, -0.0099009900990099] - for i in xrange(24): - self.assertAlmostEqual(da.getIJ(0,i),expected3[i],13) - pass - pass - - def testSwigDAIOp4(self): - da=DataArrayInt.New(range(6,30),12,2) - self.assertEqual(12,da.getNumberOfTuples()); - self.assertEqual(2,da.getNumberOfComponents()); - for i in xrange(24): - self.assertEqual(da.getIJ(0,i),i+6) - pass - # operator transpose - da.transpose() - self.assertEqual(2,da.getNumberOfTuples()); - self.assertEqual(12,da.getNumberOfComponents()); - for i in xrange(24): - self.assertEqual(da.getIJ(0,i),i+6) - pass - da.transpose() - # operator __neg__ - da2=DataArrayInt.New(12,1) - da2.iota(0) - dabis=-da - for i in xrange(24): - self.assertEqual(dabis.getIJ(0,i),-(i+6)) - pass - # operator+= - da+=da2 - expected1=[6,7,9,10,12,13,15,16,18,19,21,22,24,25,27,28,30,31,33,34,36,37,39,40] - for i in xrange(24): - self.assertEqual(da.getIJ(0,i),expected1[i]) - pass - da=-dabis - da+=[100,101] - expected2=[106,108,108,110,110,112,112,114,114,116,116,118,118,120,120,122,122,124,124,126,126,128,128,130] - self.assertEqual(12,da.getNumberOfTuples()); - self.assertEqual(2,da.getNumberOfComponents()); - for i in xrange(24): - self.assertEqual(da.getIJ(0,i),expected2[i]) - pass - for pos,elt in enumerate(dabis): - da[pos]+=elt - pass - self.assertEqual(12,da.getNumberOfTuples()); - self.assertEqual(2,da.getNumberOfComponents()); - for elt in da: - li=elt[:] - self.assertEqual(li[0],100) ; self.assertEqual(li[1],101) - pass - # operator-= - da=DataArrayInt.New(range(6,30),12,2) - da2=DataArrayInt.New(range(12),12,1) - dabis=-da - da-=da2 - expected1=[6,7,7,8,8,9,9,10,10,11,11,12,12,13,13,14,14,15,15,16,16,17,17,18] - for i in xrange(24): - self.assertEqual(da.getIJ(0,i),expected1[i]) - pass - da=-dabis - da-=[100,101] - expected2=[-94,-94,-92,-92,-90,-90,-88,-88,-86,-86,-84,-84,-82,-82,-80,-80,-78,-78,-76,-76,-74,-74,-72,-72] - self.assertEqual(12,da.getNumberOfTuples()); - self.assertEqual(2,da.getNumberOfComponents()); - for i in xrange(24): - self.assertEqual(da.getIJ(0,i),expected2[i]) - pass - for pos,elt in enumerate(dabis): - da[pos]-=elt - pass - self.assertEqual(12,da.getNumberOfTuples()); - self.assertEqual(2,da.getNumberOfComponents()); - expected3=[-88,-87,-84,-83,-80,-79,-76,-75,-72,-71,-68,-67,-64,-63,-60,-59,-56,-55,-52,-51,-48,-47,-44,-43] - for i in xrange(24): - self.assertEqual(da.getIJ(0,i),expected3[i]) - pass - # operator*= - da=DataArrayInt.New(range(6,30),12,2) - da2=DataArrayInt.New(range(12),12,1) - dabis=-da - da*=da2 - expected1=[0,0,8,9,20,22,36,39,56,60,80,85,108,114,140,147,176,184,216,225,260,270,308,319] - for i in xrange(24): - self.assertEqual(da.getIJ(0,i),expected1[i]) - pass - da=-dabis - da*=[100,101] - expected2=[600,707,800,909,1000,1111,1200,1313,1400,1515,1600,1717,1800,1919,2000,2121,2200,2323,2400,2525,2600,2727,2800,2929] - self.assertEqual(12,da.getNumberOfTuples()); - self.assertEqual(2,da.getNumberOfComponents()); - for i in xrange(24): - self.assertEqual(da.getIJ(0,i),expected2[i]) - pass - for pos,elt in enumerate(dabis): - da[pos]*=elt - pass - self.assertEqual(12,da.getNumberOfTuples()); - self.assertEqual(2,da.getNumberOfComponents()); - expected3=[-3600,-4949,-6400,-8181,-10000,-12221,-14400,-17069,-19600,-22725,-25600,-29189,-32400,-36461,-40000,-44541,-48400,-53429,-57600,-63125,-67600,-73629,-78400,-84941.0] - for i in xrange(24): - self.assertEqual(da.getIJ(0,i),expected3[i]) - pass - # operator/= - da=DataArrayInt.New(range(6,30),12,2) - da2=DataArrayInt.New(range(1,13),12,1) - dabis=-da - da/=da2 - expected1=[6,7,4,4,3,3,3,3,2,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2] - for i in xrange(24): - self.assertEqual(da.getIJ(0,i),expected1[i]) - pass - da=-dabis - da/=DataArrayInt.New([2,3],1,2) - self.assertEqual(12,da.getNumberOfTuples()); - self.assertEqual(2,da.getNumberOfComponents()); - expected2=[3,2,4,3,5,3,6,4,7,5,8,5,9,6,10,7,11,7,12,8,13,9,14,9] - for i in xrange(24): - self.assertEqual(da.getIJ(0,i),expected2[i]) - pass - pass - - def testSwigDADOp5(self): - da=DataArrayDouble.New([5,6,7,8,9,6,7,-2,3,9,8,10]) - da.rearrange(3) - da2=DataArrayDouble.New([5.,8.,10.,12]) - self.assertEqual(4,da2.getNumberOfTuples()); - self.assertEqual(1,da2.getNumberOfComponents()); - da3=da+da2 - self.assertEqual(4,da3.getNumberOfTuples()); - self.assertEqual(3,da3.getNumberOfComponents()); - expected1=[10.,11.,12.,16.,17.,14.,17.,8.,13.,21.,20.,22.] - for i in xrange(12): - self.assertAlmostEqual(da3.getIJ(0,i),expected1[i],13) - pass - da3=da2+da - self.assertEqual(4,da3.getNumberOfTuples()); - self.assertEqual(3,da3.getNumberOfComponents()); - for i in xrange(12): - self.assertAlmostEqual(da3.getIJ(0,i),expected1[i],13) - pass - # Test new API of classmethod DataArrayDouble.New - vals=[5,6,7,8,9,6,7,-2,3,9,8,10] - da=DataArrayDouble.New(vals) - self.assertEqual(12,da.getNumberOfTuples()); - self.assertEqual(1,da.getNumberOfComponents()); - for i in xrange(12): - self.assertAlmostEqual(da.getIJ(0,i),vals[i],13) - pass - da=DataArrayDouble.New(vals,12) - self.assertEqual(12,da.getNumberOfTuples()); - self.assertEqual(1,da.getNumberOfComponents()); - for i in xrange(12): - self.assertAlmostEqual(da.getIJ(0,i),vals[i],13) - pass - da=DataArrayDouble.New(vals,1,12) - self.assertEqual(1,da.getNumberOfTuples()); - self.assertEqual(12,da.getNumberOfComponents()); - for i in xrange(12): - self.assertAlmostEqual(da.getIJ(0,i),vals[i],13) - pass - da=DataArrayDouble.New(vals,6,2) - self.assertEqual(6,da.getNumberOfTuples()); - self.assertEqual(2,da.getNumberOfComponents()); - for i in xrange(12): - self.assertAlmostEqual(da.getIJ(0,i),vals[i],13) - pass - da=DataArrayDouble.New(vals,4,3) - self.assertEqual(4,da.getNumberOfTuples()); - self.assertEqual(3,da.getNumberOfComponents()); - for i in xrange(12): - self.assertAlmostEqual(da.getIJ(0,i),vals[i],13) - pass - self.assertRaises(InterpKernelException,DataArrayDouble.New,vals,11); - self.assertRaises(InterpKernelException,DataArrayDouble.New,vals,13); - self.assertRaises(InterpKernelException,DataArrayDouble.New,vals,5,2); - self.assertRaises(InterpKernelException,DataArrayDouble.New,vals,7,2); - pass - - def testSwigDADOp6(self): - da=DataArrayInt.New([5,6,7,8,9,6,7,-2,3,9,8,10]) - da.rearrange(3) - da2=DataArrayInt.New([5,8,10,12]) - self.assertEqual(4,da2.getNumberOfTuples()); - self.assertEqual(1,da2.getNumberOfComponents()); - da3=da+da2 - self.assertEqual(4,da3.getNumberOfTuples()); - self.assertEqual(3,da3.getNumberOfComponents()); - expected1=[10,11,12,16,17,14,17,8,13,21,20,22] - for i in xrange(12): - self.assertEqual(da3.getIJ(0,i),expected1[i]) - pass - da3=da2+da - self.assertEqual(4,da3.getNumberOfTuples()); - self.assertEqual(3,da3.getNumberOfComponents()); - for i in xrange(12): - self.assertEqual(da3.getIJ(0,i),expected1[i]) - pass - da3=da+DataArrayInt.New(da2.getValues()) - # Test new API of classmethod DataArrayInt.New - vals=[5,6,7,8,9,6,7,-2,3,9,8,10] - da=DataArrayDouble.New(vals) - self.assertEqual(12,da.getNumberOfTuples()); - self.assertEqual(1,da.getNumberOfComponents()); - for i in xrange(12): - self.assertEqual(da.getIJ(0,i),vals[i]) - pass - da=DataArrayDouble.New(vals,12) - self.assertEqual(12,da.getNumberOfTuples()); - self.assertEqual(1,da.getNumberOfComponents()); - for i in xrange(12): - self.assertEqual(da.getIJ(0,i),vals[i]) - pass - da=DataArrayDouble.New(vals,1,12) - self.assertEqual(1,da.getNumberOfTuples()); - self.assertEqual(12,da.getNumberOfComponents()); - for i in xrange(12): - self.assertEqual(da.getIJ(0,i),vals[i]) - pass - da=DataArrayDouble.New(vals,6,2) - self.assertEqual(6,da.getNumberOfTuples()); - self.assertEqual(2,da.getNumberOfComponents()); - for i in xrange(12): - self.assertEqual(da.getIJ(0,i),vals[i]) - pass - da=DataArrayDouble.New(vals,4,3) - self.assertEqual(4,da.getNumberOfTuples()); - self.assertEqual(3,da.getNumberOfComponents()); - for i in xrange(12): - self.assertEqual(da.getIJ(0,i),vals[i]) - pass - self.assertRaises(InterpKernelException,DataArrayDouble.New,vals,11); - self.assertRaises(InterpKernelException,DataArrayDouble.New,vals,13); - self.assertRaises(InterpKernelException,DataArrayDouble.New,vals,5,2); - self.assertRaises(InterpKernelException,DataArrayDouble.New,vals,7,2); - pass - - def testSwigDADOp9(self): - l1=[(1.,2.,3),(4.,5.,6.),(7.,8.,9.),[10.,11.,12.]] - da1=DataArrayDouble(l1,4,3) - self.assertEqual(4,da1.getNumberOfTuples()); - self.assertEqual(3,da1.getNumberOfComponents()); - da2=DataArrayDouble(12) ; da2.iota(1.) ; da2.rearrange(3) - self.assertTrue(da2.isEqual(da1,1e-12)) - self.assertRaises(InterpKernelException,DataArrayDouble.New,l1,3,4); - da3=DataArrayDouble(l1,4) - self.assertTrue(da3.isEqual(da1,1e-12)) - self.assertRaises(InterpKernelException,DataArrayDouble.New,l1,3); - self.assertRaises(InterpKernelException,DataArrayDouble.New,l1,5); - l1=[(1.,2.,3),(4.,(5.),((6.))),(7.,8.,9.),[10.,11.,12.]] - da1=DataArrayDouble(l1,4,3) - self.assertEqual(4,da1.getNumberOfTuples()); - self.assertEqual(3,da1.getNumberOfComponents()); - da2=DataArrayDouble(12) ; da2.iota(1.) ; da2.rearrange(3) - self.assertTrue(da2.isEqual(da1,1e-12)) - self.assertRaises(InterpKernelException,DataArrayDouble.New,l1,3,4); - da3=DataArrayDouble(l1,4) - self.assertTrue(da3.isEqual(da1,1e-12)) - self.assertRaises(InterpKernelException,DataArrayDouble.New,l1,3); - self.assertRaises(InterpKernelException,DataArrayDouble.New,l1,5); - # - l1=[(1,2,3),(4,5,6),(7,8,9),[10,11,12]] - da1=DataArrayInt(l1,4,3) - self.assertEqual(4,da1.getNumberOfTuples()); - self.assertEqual(3,da1.getNumberOfComponents()); - da2=DataArrayInt(12) ; da2.iota(1) ; da2.rearrange(3) - self.assertTrue(da2.isEqual(da1)) - self.assertRaises(InterpKernelException,DataArrayInt.New,l1,3,4); - da3=DataArrayInt(l1,4) - self.assertTrue(da3.isEqual(da1)) - self.assertRaises(InterpKernelException,DataArrayInt.New,l1,3); - self.assertRaises(InterpKernelException,DataArrayInt.New,l1,5); - l1=[(1,[2],3),(4,[(5)],6),((([7])),8,9),[10,11,12]] - da1=DataArrayInt(l1,4,3) - self.assertEqual(4,da1.getNumberOfTuples()); - self.assertEqual(3,da1.getNumberOfComponents()); - da2=DataArrayInt(12) ; da2.iota(1) ; da2.rearrange(3) - self.assertTrue(da2.isEqual(da1)) - self.assertRaises(InterpKernelException,DataArrayInt.New,l1,3,4); - da3=DataArrayInt(l1,4) - self.assertTrue(da3.isEqual(da1)) - self.assertRaises(InterpKernelException,DataArrayInt.New,l1,3); - self.assertRaises(InterpKernelException,DataArrayInt.New,l1,5); - pass - - def testRenumberNodesInConn1(self): - mesh2DCoords=[-0.3,-0.3,0., 0.2,-0.3,0., 0.7,-0.3,0., -0.3,0.2,0., 0.2,0.2,0., 0.7,0.2,0., -0.3,0.7,0., 0.2,0.7,0., 0.7,0.7,0. ] - mesh2DConn=[1,4,2, 4,5,2, 0,3,4,1, 6,7,4,3, 7,8,5,4] - mesh2D=MEDCouplingUMesh.New("mesh",2); - mesh2D.allocateCells(5); - mesh2D.insertNextCell(NORM_TRI3,3,mesh2DConn[0:3]) - mesh2D.insertNextCell(NORM_TRI3,3,mesh2DConn[3:6]) - mesh2D.insertNextCell(NORM_QUAD4,4,mesh2DConn[6:10]) - mesh2D.insertNextCell(NORM_QUAD4,4,mesh2DConn[10:14]) - mesh2D.insertNextCell(NORM_QUAD4,4,mesh2DConn[14:18]) - mesh2D.finishInsertingCells(); - myCoords=DataArrayDouble.New(mesh2DCoords,9,3); - mesh2D.setCoords(myCoords); - mesh2D.checkCoherency(); - # - mesh3DCoords=[-0.3,-0.3,0., -0.3,0.2,0., 0.2,0.2,0., 0.2,-0.3,0., -0.3,-0.3,1., -0.3,0.2,1., 0.2,0.2,1., 0.2,-0.3,1. ] - mesh3DConn=[0,1,2,3,4,5,6,7] - mesh3D=MEDCouplingUMesh.New("mesh",3); - mesh3D.allocateCells(1); - mesh3D.insertNextCell(NORM_HEXA8,8,mesh3DConn[:]) - mesh3D.finishInsertingCells(); - myCoords3D=DataArrayDouble.New(mesh3DCoords,8,3); - mesh3D.setCoords(myCoords3D); - mesh3D.checkCoherency(); - # - mesh3D_2=mesh3D.deepCpy(); - mesh2D_2=mesh2D.deepCpy(); - mesh3D_4=mesh3D.deepCpy(); - mesh2D_4=mesh2D.deepCpy(); - oldNbOf3DNodes=mesh3D.getNumberOfNodes(); - renumNodes=DataArrayInt.New(); - renumNodes.alloc(mesh2D.getNumberOfNodes(),1); - renumNodes.iota(oldNbOf3DNodes); - coo=DataArrayDouble.Aggregate(mesh3D.getCoords(),mesh2D.getCoords()); - mesh3D.setCoords(coo); - mesh2D.setCoords(coo); - mesh2DCpy=mesh2D.deepCpy() - mesh2D_3=mesh2D.deepCpy(); - mesh2D_3.shiftNodeNumbersInConn(oldNbOf3DNodes); - mesh2D.renumberNodesInConn(renumNodes); - mesh2DCpy.renumberNodesInConn(renumNodes.getValues()); - self.assertTrue(mesh2D.isEqual(mesh2DCpy,1e-12)) - self.assertTrue(mesh2D.isEqual(mesh2D_3,1e-12)) - # - da1,da2=mesh3D.checkGeoEquivalWith(mesh3D_2,10,1e-12); - self.assertTrue(da1==None); - self.assertEqual(8,da2.getNumberOfTuples()); - self.assertEqual(1,da2.getNumberOfComponents()); - expected1=[8,11,12,9,4,5,6,7] - for i in xrange(8): - self.assertEqual(expected1[i],da2.getIJ(i,0)); - pass - # - da1,da2=mesh2D.checkGeoEquivalWith(mesh2D_2,10,1e-12); - self.assertTrue(da1==None); - self.assertEqual(9,da2.getNumberOfTuples()); - self.assertEqual(1,da2.getNumberOfComponents()); - for i in xrange(9): - self.assertEqual(8+i,da2.getIJ(i,0)); - pass - # - mesh2D_5=mesh2D_4.deepCpy(); - mesh2D_5.translate([1.,0.,0.]); - meshes=[mesh3D_4,mesh2D_4,mesh2D_5]; - MEDCouplingUMesh.PutUMeshesOnSameAggregatedCoords(meshes); - self.assertTrue(mesh3D_4.getCoords().getHiddenCppPointer()==mesh2D_4.getCoords().getHiddenCppPointer()); - self.assertTrue(mesh2D_4.getCoords().getHiddenCppPointer()==mesh2D_5.getCoords().getHiddenCppPointer()); - mesh3D_4.checkCoherency(); mesh2D_4.checkCoherency(); mesh2D_5.checkCoherency(); - self.assertEqual(26,mesh3D_4.getNumberOfNodes()); - self.assertEqual(3,mesh3D_4.getSpaceDimension()); - self.assertEqual(9,mesh3D_4.getNodalConnectivity().getNumberOfTuples()); - self.assertEqual(23,mesh2D_4.getNodalConnectivity().getNumberOfTuples()); - self.assertEqual(23,mesh2D_5.getNodalConnectivity().getNumberOfTuples()); - expected2=[18,0,1,2,3,4,5,6,7] - expected3=[3,9,12,10, 3,12,13,10, 4,8,11,12,9, 4,14,15,12,11, 4,15,16,13,12] - expected4=[3,18,21,19, 3,21,22,19, 4,17,20,21,18, 4,23,24,21,20, 4,24,25,22,21] - expected5=[-0.3,-0.3,0., -0.3,0.2,0., 0.2,0.2,0., 0.2,-0.3,0., -0.3,-0.3,1., -0.3,0.2,1., 0.2,0.2,1., 0.2,-0.3,1., -0.3,-0.3,0., 0.2,-0.3,0., 0.7,-0.3,0., -0.3,0.2,0., 0.2,0.2,0., 0.7,0.2,0., -0.3,0.7,0., 0.2,0.7,0., 0.7,0.7,0., 0.7, -0.3, 0.0, 1.2, -0.3, 0.0, 1.7, -0.3, 0.0, 0.7, 0.2, 0.0, 1.2, 0.2, 0.0, 1.7, 0.2, 0.0, 0.7, 0.7, 0.0, 1.2, 0.7, 0.0, 1.7, 0.7, 0.0] - self.assertEqual(expected2,mesh3D_4.getNodalConnectivity().getValues()); - self.assertEqual(expected3,mesh2D_4.getNodalConnectivity().getValues()); - self.assertEqual(expected4,mesh2D_5.getNodalConnectivity().getValues()); - for i in xrange(78): - self.assertAlmostEqual(expected5[i],mesh3D_4.getCoords().getIJ(0,i),12); - pass - # - MEDCouplingUMesh.MergeNodesOnUMeshesSharingSameCoords(meshes,1e-12); - mesh3D_4.checkCoherency(); mesh2D_4.checkCoherency(); mesh2D_5.checkCoherency(); - self.assertTrue(mesh3D_4.getCoords().getHiddenCppPointer()==mesh2D_4.getCoords().getHiddenCppPointer()); - self.assertTrue(mesh2D_4.getCoords().getHiddenCppPointer()==mesh2D_5.getCoords().getHiddenCppPointer()); - self.assertEqual(19,mesh3D_4.getNumberOfNodes()); - self.assertEqual(3,mesh3D_4.getSpaceDimension()); - self.assertEqual(9,mesh3D_4.getNodalConnectivity().getNumberOfTuples()); - self.assertEqual(23,mesh2D_4.getNodalConnectivity().getNumberOfTuples()); - self.assertEqual(23,mesh2D_5.getNodalConnectivity().getNumberOfTuples()); - expected6=[18,0,1,2,3,4,5,6,7] - expected7=[3,3,2,8, 3,2,9,8, 4,0,1,2,3, 4,10,11,2,1, 4,11,12,9,2] - expected8=[3,13,15,14, 3,15,16,14, 4,8,9,15,13, 4,12,17,15,9, 4,17,18,16,15] - expected9=[-0.3, -0.3, 0., -0.3, 0.2, 0., 0.2, 0.2, 0., 0.2, -0.3, 0., -0.3, -0.3, 1., -0.3, 0.2, 1., - 0.2, 0.2, 1., 0.2, -0.3, 1., 0.7, -0.3, 0., 0.7, 0.2, 0., -0.3, 0.7, 0., 0.2, 0.7, 0., - 0.7, 0.7, 0., 1.2, -0.3, 0., 1.7, -0.3, 0., 1.2, 0.2, 0., 1.7, 0.2, 0., 1.2, 0.7, 0., 1.7, 0.7, 0.] - self.assertEqual(expected6,mesh3D_4.getNodalConnectivity().getValues()); - self.assertEqual(expected7,mesh2D_4.getNodalConnectivity().getValues()); - self.assertEqual(expected8,mesh2D_5.getNodalConnectivity().getValues()); - for i in xrange(57): - self.assertAlmostEqual(expected9[i],mesh3D_4.getCoords().getIJ(0,i),12); - pass - # - pass - - def testComputeNeighborsOfCells1(self): - m=MEDCouplingDataForTest.build2DTargetMesh_1(); - d1,d2=m.computeNeighborsOfCells(); - self.assertEqual(6,d2.getNumberOfTuples()); - self.assertEqual(10,d1.getNumberOfTuples()); - expected1=[0,2,4,6,8,10] - expected2=[3,1,0,2,4,1,4,0,2,3] - self.assertEqual(expected1,d2.getValues()); - self.assertEqual(expected2,d1.getValues()); - pass - - def testCheckButterflyCellsBug1(self): - mesh2DCoords=[323.85,120.983748908684,317.5,131.982271536747,336.55,120.983748908686,330.2,131.982271536751,323.85,142.98079416481] - mesh2DConn=[4,1,0,2,3] - mesh2D=MEDCouplingUMesh.New("mesh",2); - mesh2D.allocateCells(1); - mesh2D.insertNextCell(NORM_POLYGON,5,mesh2DConn[0:5]) - mesh2D.finishInsertingCells(); - myCoords=DataArrayDouble.New(mesh2DCoords,5,2); - mesh2D.setCoords(myCoords); - mesh2D.checkCoherency(); - # - v=mesh2D.checkButterflyCells(); - self.assertTrue(v.empty()); - pass - - def testDataArrayIntRange1(self): - d=DataArrayInt.Range(2,17,7); - expected1=[2,9,16] - self.assertEqual(3,d.getNumberOfTuples()); - self.assertEqual(1,d.getNumberOfComponents()); - self.assertEqual(expected1,d.getValues()); - # - d=DataArrayInt.Range(2,23,7); - self.assertEqual(3,d.getNumberOfTuples()); - self.assertEqual(1,d.getNumberOfComponents()); - self.assertEqual(expected1,d.getValues()); - # - d=DataArrayInt.Range(2,24,7); - expected2=[2,9,16,23] - self.assertEqual(4,d.getNumberOfTuples()); - self.assertEqual(1,d.getNumberOfComponents()); - self.assertEqual(expected2,d.getValues()); - # - d=DataArrayInt.Range(24,2,-7); - expected3=[24,17,10,3] - self.assertEqual(4,d.getNumberOfTuples()); - self.assertEqual(1,d.getNumberOfComponents()); - self.assertEqual(expected3,d.getValues()); - # - d=DataArrayInt.Range(23,2,-7); - expected4=[23,16,9] - self.assertEqual(3,d.getNumberOfTuples()); - self.assertEqual(1,d.getNumberOfComponents()); - self.assertEqual(expected4,d.getValues()); - # - d=DataArrayInt.Range(23,22,-7); - self.assertEqual(1,d.getNumberOfTuples()); - self.assertEqual(1,d.getNumberOfComponents()); - self.assertEqual(23,d.getIJ(0,0)); - # - d=DataArrayInt.Range(22,23,7); - self.assertEqual(1,d.getNumberOfTuples()); - self.assertEqual(1,d.getNumberOfComponents()); - self.assertEqual(22,d.getIJ(0,0)); - # - d=DataArrayInt.Range(22,22,7); - self.assertEqual(0,d.getNumberOfTuples()); - self.assertEqual(1,d.getNumberOfComponents()); - # - d=DataArrayInt.Range(22,22,-7); - self.assertEqual(0,d.getNumberOfTuples()); - self.assertEqual(1,d.getNumberOfComponents()); - # - self.assertRaises(InterpKernelException,DataArrayInt.Range,22,23,-7); - self.assertRaises(InterpKernelException,DataArrayInt.Range,23,22,7); - self.assertRaises(InterpKernelException,DataArrayInt.Range,23,22,0); - self.assertRaises(InterpKernelException,DataArrayInt.Range,22,23,0); - pass - - def testSwigUMeshGetItem1(self): - m=MEDCouplingDataForTest.build2DTargetMesh_1(); - subMesh=m.buildPartOfMySelf([1,3],True); - self.assertTrue(isinstance(subMesh,MEDCouplingUMesh)) - m1=m[[1,3]] - self.assertTrue(isinstance(m1,MEDCouplingUMesh)) - m2=m[(1,3)] - self.assertTrue(isinstance(m2,MEDCouplingUMesh)) - m3=m[1::2] - self.assertTrue(isinstance(m3,MEDCouplingUMesh)) - m4=m[DataArrayInt.New([1,3])] - m5_1=m[1] - self.assertTrue(isinstance(m5_1,MEDCouplingUMesh)) - m5_2=m[3] - self.assertTrue(isinstance(m5_2,MEDCouplingUMesh)) - m5=MEDCouplingUMesh.MergeUMeshesOnSameCoords([m5_1,m5_2]); - m5.setName(subMesh.getName()) - self.assertTrue(isinstance(m4,MEDCouplingUMesh)) - self.assertTrue(subMesh.isEqual(m1,1e-12)) - self.assertTrue(subMesh.isEqual(m2,1e-12)) - self.assertTrue(subMesh.isEqual(m3,1e-12)) - self.assertTrue(subMesh.isEqual(m4,1e-12)) - self.assertTrue(subMesh.isEqual(m5,1e-12)) - self.assertRaises(InterpKernelException,m.buildPartOfMySelf,[1,5],True); - pass - - def testSwigGetItem3(self): - da=DataArrayInt.New([4,5,6]) - self.assertEqual(5,da[1]) - self.assertEqual(6,da[-1]) - self.assertRaises(InterpKernelException,da.__getitem__,3) - da=DataArrayInt.New([4,5,6,7,8,9],2,3) - self.assertEqual(9,da[1,2]) - da=DataArrayDouble.New([4.1,5.2,6.3]) - self.assertAlmostEqual(5.2,da[1],12) - self.assertAlmostEqual(6.3,da[-1],12) - self.assertRaises(InterpKernelException,da.__getitem__,3) - da=DataArrayDouble.New([4.12,5.12,6.12,7.12,8.12,9.12],2,3) - self.assertAlmostEqual(9.12,da[1,2],12) - pass - - def testSwigDADISub1(self): - mesh3D,mesh2D=MEDCouplingDataForTest.build3DExtrudedUMesh_1(); - bary=mesh3D.getBarycenterAndOwner() - bary=bary[:,:2] - pts=bary.getDifferentValues(1e-12) - expected=[[0,6,12],[1,7,13],[2,8,14],[3,9,15],[4,10,16],[5,11,17]] - for pos,pt in enumerate(pts): - bary2=bary[:,:2] - bary2[:]-=pt - norm=bary2.magnitude() - self.assertEqual(expected[pos],norm.getIdsInRange(-1.,1e-5).getValues()) - pass - expected2=[[3.,54.],[-141.,180.],[21.,54.],[39.,72.],[-15.,90.],[21.,90.]] - for pos,pt in enumerate(pts): - bary2=bary[:,:2] - bary2[:]+=pt - self.assertAlmostEqual(expected2[pos][0],bary2.accumulate()[0],12); - self.assertAlmostEqual(expected2[pos][1],bary2.accumulate()[1],12); - pass - expected3=[[-3.,22.5],[45.,337.5],[-9., 22.5],[-15.,67.5],[3.,112.5],[-9.,112.5]] - for pos,pt in enumerate(pts): - bary2=bary[:,:2] - bary2[:]*=pt - self.assertAlmostEqual(expected3[pos][0],bary2.accumulate()[0],12); - self.assertAlmostEqual(expected3[pos][1],bary2.accumulate()[1],12); - pass - expected4=[[-12.,90.],[0.8,6.],[-4,90.],[-2.4,30.],[12.,18],[-4,18.]] - for pos,pt in enumerate(pts): - bary2=bary[:,:2] - bary2[:]/=pt - self.assertAlmostEqual(expected4[pos][0],bary2.accumulate()[0],12); - self.assertAlmostEqual(expected4[pos][1],bary2.accumulate()[1],12); - pass - # - d=DataArrayInt.New([1,2,0,1,0,2],3,2) - e=DataArrayInt.New([1,11,101,2,12,102,3,13,103,4,14,104],4,3) - expected5=[[1,11,101,77,77,77,77,77,77,4,14,104],[77,77,77,77,77,77,3,13,103,4,14,104],[77,77,77,2,12,102,77,77,77,4,14,104]] - expected6=[[1,77,77,2,77,77,3,77,77,4,77,77],[77,77,101,77,77,102,77,77,103,77,77,104],[77,11,77,77,12,77,77,13,77,77,14,77]] - for pos,tup in enumerate(d): - f=e[:] - self.assertTrue(isinstance(f,DataArrayInt)) - f[tup]=77 - self.assertEqual(expected5[pos],f.getValues()) - self.assertEqual(6*[77],f[tup].getValues()) - f=e[:] - f[:,tup]=77 - self.assertEqual(expected6[pos],f.getValues()) - self.assertEqual(8*[77],f[:,tup].getValues()) - pass - # - e=e.convertToDblArr() - for pos,tup in enumerate(d): - f=e[:] - self.assertTrue(isinstance(f,DataArrayDouble)) - f[tup]=77. - self.assertEqual(expected5[pos],f.convertToIntArr().getValues()) - self.assertEqual(6*[77],f[tup].convertToIntArr().getValues()) - f=e[:] - f[:,tup]=77. - self.assertEqual(expected6[pos],f.convertToIntArr().getValues()) - self.assertEqual(8*[77],f[:,tup].convertToIntArr().getValues()) - pass - pass - - def testDataArrayDoubleGetMinMaxPerComponent1(self): - values1=[1.,2.,3.,-0.9,2.1,3.,1.3,1.7,3.,1.,1.8,3.] - d1=DataArrayDouble.New(); - self.assertRaises(InterpKernelException,d1.getMinMaxPerComponent) - d1=DataArrayDouble.New(values1,4,3); - res=d1.getMinMaxPerComponent(); - self.assertTrue(isinstance(res,list)) - self.assertEqual(3,len(res)) - for i in xrange(3): - self.assertTrue(isinstance(res[i],tuple)) - self.assertEqual(2,len(res[i])) - pass - expected1=[-0.9,1.3,1.7,2.1,3.,3.] - for i in xrange(6): - self.assertAlmostEqual(expected1[i],res[i/2][i%2],14) - pass - # - d1.rearrange(2); - res=d1.getMinMaxPerComponent(); - self.assertTrue(isinstance(res,list)) - self.assertEqual(2,len(res)) - for i in xrange(2): - self.assertTrue(isinstance(res[i],tuple)) - self.assertEqual(2,len(res[i])) - pass - expected2=[1.,3.,-0.9,3.] - for i in xrange(4): - self.assertAlmostEqual(expected2[i],res[i/2][i%2],14) - pass - # - d1.rearrange(1); - res=d1.getMinMaxPerComponent(); - self.assertTrue(isinstance(res,list)) - self.assertEqual(1,len(res)) - for i in xrange(1): - self.assertTrue(isinstance(res[i],tuple)) - self.assertEqual(2,len(res[i])) - pass - expected3=[-0.9,3.] - for i in xrange(2): - self.assertAlmostEqual(expected3[i],res[i/2][i%2],14) - pass - pass - - def testDataArrayIntGetHashCode1(self): - d1=DataArrayInt.New(range(3545)) - d2=DataArrayInt.New(range(3545)) - self.assertEqual(d2.getHashCode(),d1.getHashCode()) - self.assertEqual(232341068,d1.getHashCode()) - d1[886]=6 - self.assertEqual(232340188,d1.getHashCode()) - pass - - def testZipConnectivityPol1(self): - m1=MEDCouplingDataForTest.build2DTargetMesh_1(); - cells1=[2,3,4] - m2_1=m1.buildPartOfMySelf(cells1,True); - m2=m2_1 - self.assertTrue(isinstance(m2,MEDCouplingUMesh)) - # no permutation policy 0 - isOk,arr=m1.areCellsIncludedIn(m2,0) - self.assertTrue(isOk); - self.assertEqual(3,arr.getNumberOfTuples()); - self.assertEqual(1,arr.getNumberOfComponents()); - self.assertEqual(cells1,arr.getValues()) - # no permutation policy 1 - isOk,arr=m1.areCellsIncludedIn(m2,1) - self.assertTrue(isOk); - self.assertEqual(3,arr.getNumberOfTuples()); - self.assertEqual(1,arr.getNumberOfComponents()); - self.assertEqual(cells1,arr.getValues()) - # no permutation policy 2 - isOk,arr=m1.areCellsIncludedIn(m2,2) - self.assertTrue(isOk); - self.assertEqual(3,arr.getNumberOfTuples()); - self.assertEqual(1,arr.getNumberOfComponents()); - self.assertEqual(cells1,arr.getValues()) - # some modification into m2 - modif1=[2,4,5] - m2.getNodalConnectivity()[1:4]=modif1 - #policy 0 fails because cell0 in m2 has same orientation be not same connectivity - expected1=[5,3,4] - isOk,arr=m1.areCellsIncludedIn(m2,0) - self.assertTrue(not isOk); - self.assertEqual(3,arr.getNumberOfTuples()); - self.assertEqual(1,arr.getNumberOfComponents()); - self.assertEqual(expected1,arr.getValues()) - #policy 1 succeeds because cell0 in m2 has not exactly the same conn - isOk,arr=m1.areCellsIncludedIn(m2,1) - self.assertTrue(isOk); - self.assertEqual(3,arr.getNumberOfTuples()); - self.assertEqual(1,arr.getNumberOfComponents()); - self.assertEqual(cells1,arr.getValues()) - #policy 2 succeeds because cell0 in m2 has same nodes in connectivity - isOk,arr=m1.areCellsIncludedIn(m2,2) - self.assertTrue(isOk); - self.assertEqual(3,arr.getNumberOfTuples()); - self.assertEqual(1,arr.getNumberOfComponents()); - self.assertEqual(cells1,arr.getValues()) - #some new modification into m2 - modif2=[2,5,4] - m2.getNodalConnectivity()[1:4]=modif2 - #policy 0 fails because cell0 in m2 has not exactly the same conn - isOk,arr=m1.areCellsIncludedIn(m2,0) - self.assertTrue(not isOk); - self.assertEqual(3,arr.getNumberOfTuples()); - self.assertEqual(1,arr.getNumberOfComponents()); - self.assertEqual(expected1,arr.getValues()) - #policy 1 fails too because cell0 in m2 has not same orientation - isOk,arr=m1.areCellsIncludedIn(m2,1) - self.assertTrue(not isOk); - self.assertEqual(3,arr.getNumberOfTuples()); - self.assertEqual(1,arr.getNumberOfComponents()); - self.assertEqual(expected1,arr.getValues()) - #policy 2 succeeds because cell0 in m2 has same nodes in connectivity - isOk,arr=m1.areCellsIncludedIn(m2,2) - self.assertTrue(isOk); - self.assertEqual(3,arr.getNumberOfTuples()); - self.assertEqual(1,arr.getNumberOfComponents()); - self.assertEqual(cells1,arr.getValues()) - # Now 1D - cells2=[3,2] - m1=MEDCouplingDataForTest.build1DSourceMesh_2(); - m2_1=m1.buildPartOfMySelf(cells2,True); - m2=m2_1 - self.assertTrue(isinstance(m2,MEDCouplingUMesh)) - # no permutation policy 0 - isOk,arr=m1.areCellsIncludedIn(m2,0) - self.assertTrue(isOk); - self.assertEqual(2,arr.getNumberOfTuples()); - self.assertEqual(1,arr.getNumberOfComponents()); - self.assertEqual(cells2,arr.getValues()) - # no permutation policy 1 - isOk,arr=m1.areCellsIncludedIn(m2,1) - self.assertTrue(isOk); - self.assertEqual(2,arr.getNumberOfTuples()); - self.assertEqual(1,arr.getNumberOfComponents()); - self.assertEqual(cells2,arr.getValues()) - # no permutation policy 2 - isOk,arr=m1.areCellsIncludedIn(m2,2) - self.assertTrue(isOk); - self.assertEqual(2,arr.getNumberOfTuples()); - self.assertEqual(1,arr.getNumberOfComponents()); - self.assertEqual(cells2,arr.getValues()) - # some modification into m2 - modif3=[4,3] - m2.getNodalConnectivity()[1:3]=modif3 - #policy 0 fails because cell0 in m2 has not exactly the same conn - expected2=[4,2] - isOk,arr=m1.areCellsIncludedIn(m2,0) - self.assertTrue(not isOk); - self.assertEqual(2,arr.getNumberOfTuples()); - self.assertEqual(1,arr.getNumberOfComponents()); - self.assertEqual(expected2,arr.getValues()) - #policy 1 fails too because cell0 in m2 has not same orientation - isOk,arr=m1.areCellsIncludedIn(m2,1) - self.assertTrue(not isOk); - self.assertEqual(2,arr.getNumberOfTuples()); - self.assertEqual(1,arr.getNumberOfComponents()); - self.assertEqual(expected2,arr.getValues()) - #policy 2 succeeds because cell0 in m2 has same nodes in connectivity - isOk,arr=m1.areCellsIncludedIn(m2,2) - self.assertTrue(isOk); - self.assertEqual(2,arr.getNumberOfTuples()); - self.assertEqual(1,arr.getNumberOfComponents()); - self.assertEqual(cells2,arr.getValues()) - pass - - def toSeeIfDaIIopsAreOK(self,d): - d+=5 - d*=6 - d/=3 - d-=2 - d%=7 - pass - - def testSwigDAIOp5(self): - d=DataArrayInt.New([4,5,6,10,3,-1],2,3) - self.toSeeIfDaIIopsAreOK(d) - dExp=DataArrayInt.New([2,4,6,0,0,6],2,3) - self.assertTrue(d.isEqual(dExp)); - pass - - def toSeeIfDaDIopsAreOK(self,d): - d+=5 - d*=6 - d/=3 - d-=2 - pass - - def testSwigDADOp7(self): - d=DataArrayDouble.New([4.,5.,6.,10.,3.,-1.],2,3) - self.toSeeIfDaDIopsAreOK(d) - dExp=DataArrayDouble.New([16.,18.,20.,28.,14.,6.],2,3) - self.assertTrue(d.isEqual(dExp,1e-14)); - pass - - def testConvexEnvelop2D1(self): - coords=[7.54758495819e-14,-1.12270326253e-12,8.43143594193,-1.02835845055e-12,4.21571797096,7.30183771609,-4.21571797097,7.30183771609,-8.43143594193,-1.09439981894e-12,-4.21571797097,-7.30183771609,4.21571797097,-7.30183771609,16.8628718839,-1.02835845055e-12,12.6471539129,7.30183771609,8.43143594193,14.6036754322,2.26427548746e-13,14.6036754322,-8.43143594193,14.6036754322,-12.6471539129,7.30183771609,-16.8628718839,-1.39630321727e-12,-12.6471539129,-7.30183771609,-8.43143594193,-14.6036754322,3.7737924791e-14,-14.6036754322,8.43143594193,-14.6036754322,12.6471539129,-7.30183771609,25.2943078258,-1.07553085654e-12,21.0785898548,7.30183771609,16.8628718839,14.6036754322,12.6471539129,21.9055131483,4.21571797096,21.9055131483,-4.21571797097,21.9055131483,-12.6471539129,21.9055131483,-16.8628718839,14.6036754322,-21.0785898548,7.30183771609,-25.2943078258,-1.02835845055e-12,-21.0785898548,-7.30183771609,-16.8628718839,-14.6036754322,-12.6471539129,-21.9055131483,-4.21571797097,-21.9055131483,4.21571797097,-21.9055131483,12.6471539129,-21.9055131483,16.8628718839,-14.6036754322,21.0785898548,-7.30183771609,33.7257437677,-7.45324014622e-13,29.5100257968,7.30183771609,25.2943078258,14.6036754322,21.0785898548,21.9055131483,16.8628718839,29.2073508644,8.43143594193,29.2073508644,-1.20761359331e-12,29.2073508644,-8.43143594193,29.2073508644,-16.8628718839,29.2073508644,-21.0785898548,21.9055131483,-25.2943078258,14.6036754322,-29.5100257968,7.30183771609,-33.7257437677,-7.26455052226e-13,-29.5100257968,-7.30183771609,-25.2943078258,-14.6036754322,-21.0785898548,-21.9055131483,-16.8628718839,-29.2073508644,-8.43143594193,-29.2073508644,4.15117172701e-13,-29.2073508644,8.43143594193,-29.2073508644,16.8628718839,-29.2073508644,21.0785898548,-21.9055131483,25.2943078258,-14.6036754322,29.5100257968,-7.30183771609,42.1571797097,-1.86802727715e-12,37.9414617387,7.30183771609,33.7257437677,14.6036754322,29.5100257968,21.9055131483,25.2943078258,29.2073508644,21.0785898548,36.5091885805,12.6471539129,36.5091885805,4.21571797096,36.5091885805,-4.21571797096,36.5091885805,-12.6471539129,36.5091885805,-21.0785898548,36.5091885805,-25.2943078258,29.2073508644,-29.5100257968,21.9055131483,-33.7257437677,14.6036754322,-37.9414617387,7.30183771609,-42.1571797097,-9.81186044565e-13,-37.9414617387,-7.30183771609,-33.7257437677,-14.6036754322,-29.5100257968,-21.9055131483,-25.2943078258,-29.2073508644,-21.0785898548,-36.5091885805,-12.6471539129,-36.5091885805,-4.21571797097,-36.5091885805,4.21571797097,-36.5091885805,12.6471539129,-36.5091885805,21.0785898548,-36.5091885805,25.2943078258,-29.2073508644,29.5100257968,-21.9055131483,33.7257437677,-14.6036754322,37.9414617387,-7.30183771609,50.5886156516,-6.98151608633e-13,46.3728976806,7.30183771609,42.1571797097,14.6036754322,37.9414617387,21.9055131483,33.7257437677,29.2073508644,29.5100257968,36.5091885805,25.2943078258,43.8110262966,16.8628718839,43.8110262966,8.43143594193,43.8110262966,-1.84915831476e-12,43.8110262966,-8.43143594193,43.8110262966,-16.8628718839,43.8110262966,-25.2943078258,43.8110262966,-29.5100257968,36.5091885805,-33.7257437677,29.2073508644,-37.9414617387,21.9055131483,-42.1571797097,14.6036754322,-46.3728976806,7.30183771609,-50.5886156516,-1.47177906685e-12,-46.3728976806,-7.30183771609,-42.1571797097,-14.6036754322,-37.9414617387,-21.9055131483,-33.7257437677,-29.2073508644,-29.5100257968,-36.5091885805,-25.2943078258,-43.8110262966,-16.8628718839,-43.8110262966,-8.43143594193,-43.8110262966,7.54758495819e-14,-43.8110262966,8.43143594193,-43.8110262966,16.8628718839,-43.8110262966,25.2943078258,-43.8110262966,29.5100257968,-36.5091885805,33.7257437677,-29.2073508644,37.9414617387,-21.9055131483,42.1571797097,-14.6036754322,46.3728976806,-7.30183771609,59.0200515935,-7.9249642061e-13,54.8043336225,7.30183771609,50.5886156516,14.6036754322,46.3728976806,21.9055131483,42.1571797097,29.2073508644,37.9414617387,36.5091885805,33.7257437677,43.8110262966,29.5100257968,51.1128640127,21.0785898548,51.1128640127,12.6471539129,51.1128640127,4.21571797096,51.1128640127,-4.21571797096,51.1128640127,-12.6471539129,51.1128640127,-21.0785898548,51.1128640127,-29.5100257968,51.1128640127,-33.7257437677,43.8110262966,-37.9414617387,36.5091885805,-42.1571797097,29.2073508644,-46.3728976806,21.9055131483,-50.5886156516,14.6036754322,-54.8043336226,7.30183771609,-59.0200515935,-1.31139288649e-12,-54.8043336226,-7.30183771609,-50.5886156516,-14.6036754322,-46.3728976806,-21.9055131483,-42.1571797097,-29.2073508644,-37.9414617387,-36.5091885805,-33.7257437677,-43.8110262966,-29.5100257968,-51.1128640127,-21.0785898548,-51.1128640127,-12.6471539129,-51.1128640127,-4.21571797097,-51.1128640127,4.21571797097,-51.1128640127,12.6471539129,-51.1128640127,21.0785898548,-51.1128640127,29.5100257968,-51.1128640127,33.7257437677,-43.8110262966,37.9414617387,-36.5091885805,42.1571797097,-29.2073508644,46.3728976806,-21.9055131483,50.5886156516,-14.6036754322,54.8043336225,-7.30183771609,67.4514875354,-2.14162723189e-12,63.2357695645,7.30183771609,59.0200515935,14.6036754322,54.8043336226,21.9055131483,50.5886156516,29.2073508644,46.3728976806,36.5091885805,42.1571797097,43.8110262966,37.9414617387,51.1128640127,33.7257437677,58.4147017287,25.2943078258,58.4147017287,16.8628718839,58.4147017287,8.43143594193,58.4147017287,6.79282646237e-13,58.4147017287,-8.43143594193,58.4147017287,-16.8628718839,58.4147017287,-25.2943078258,58.4147017287,-33.7257437677,58.4147017287,-37.9414617387,51.1128640127,-42.1571797097,43.8110262966,-46.3728976806,36.5091885805,-50.5886156516,29.2073508644,-54.8043336226,21.9055131483,-59.0200515935,14.6036754322,-63.2357695645,7.30183771609,-67.4514875354,-1.16044118732e-12,-63.2357695645,-7.30183771609,-59.0200515935,-14.6036754322,-54.8043336226,-21.9055131483,-50.5886156516,-29.2073508644,-46.3728976806,-36.5091885805,-42.1571797097,-43.8110262966,-37.9414617387,-51.1128640127,-33.7257437677,-58.4147017287,-25.2943078258,-58.4147017287,-16.8628718839,-58.4147017287,-8.43143594193,-58.4147017287,-5.66068871864e-14,-58.4147017287,8.43143594193,-58.4147017287,16.8628718839,-58.4147017287,25.2943078258,-58.4147017287,33.7257437677,-58.4147017287,37.9414617387,-51.1128640127,42.1571797097,-43.8110262966,46.3728976806,-36.5091885805,50.5886156516,-29.2073508644,54.8043336226,-21.9055131483,59.0200515935,-14.6036754322,63.2357695645,-7.30183771609,75.8829234774,-2.29257893105e-12,71.6672055064,7.30183771609,67.4514875354,14.6036754322,63.2357695645,21.9055131483,59.0200515935,29.2073508644,54.8043336226,36.5091885805,50.5886156516,43.8110262966,46.3728976806,51.1128640127,42.1571797097,58.4147017287,37.9414617387,65.7165394448,29.5100257968,65.7165394448,21.0785898548,65.7165394448,12.6471539129,65.7165394448,4.21571797097,65.7165394448,-4.21571797096,65.7165394448,-12.6471539129,65.7165394448,-21.0785898548,65.7165394448,-29.5100257968,65.7165394448,-37.9414617387,65.7165394448,-42.1571797097,58.4147017287,-46.3728976806,51.1128640127,-50.5886156516,43.8110262966,-54.8043336226,36.5091885805,-59.0200515935,29.2073508644,-63.2357695645,21.9055131483,-67.4514875354,14.6036754322,-71.6672055064,7.30183771609,-75.8829234774,-1.31139288649e-12,-71.6672055064,-7.30183771609,-67.4514875354,-14.6036754322,-63.2357695645,-21.9055131483,-59.0200515935,-29.2073508644,-54.8043336226,-36.5091885805,-50.5886156516,-43.8110262966,-46.3728976806,-51.1128640127,-42.1571797097,-58.4147017287,-37.9414617387,-65.7165394448,-29.5100257968,-65.7165394448,-21.0785898548,-65.7165394448,-12.6471539129,-65.7165394448,-4.21571797097,-65.7165394448,4.21571797097,-65.7165394448,12.6471539129,-65.7165394448,21.0785898548,-65.7165394448,29.5100257968,-65.7165394448,37.9414617387,-65.7165394448,42.1571797097,-58.4147017287,46.3728976806,-51.1128640127,50.5886156516,-43.8110262966,54.8043336226,-36.5091885805,59.0200515935,-29.2073508644,63.2357695645,-21.9055131483,67.4514875354,-14.6036754322,71.6672055064,-7.30183771609,84.3143594193,-1.49064802924e-12,80.0986414483,7.30183771609,75.8829234774,14.6036754322,71.6672055064,21.9055131483,67.4514875354,29.2073508644,63.2357695645,36.5091885805,59.0200515935,43.8110262966,54.8043336226,51.1128640127,50.5886156516,58.4147017287,46.3728976806,65.7165394448,42.1571797097,73.0183771609,33.7257437677,73.0183771609,25.2943078258,73.0183771609,16.8628718839,73.0183771609,8.43143594193,73.0183771609,2.0755858635e-12,73.0183771609,-8.43143594193,73.0183771609,-16.8628718839,73.0183771609,-25.2943078258,73.0183771609,-33.7257437677,73.0183771609,-42.1571797097,73.0183771609,-46.3728976806,65.7165394448,-50.5886156516,58.4147017287,-54.8043336226,51.1128640127,-59.0200515935,43.8110262966,-63.2357695645,36.5091885805,-67.4514875354,29.2073508644,-71.6672055064,21.9055131483,-75.8829234774,14.6036754322,-80.0986414483,7.30183771609,-84.3143594193,-1.11326878133e-12,-80.0986414483,-7.30183771609,-75.8829234774,-14.6036754322,-71.6672055064,-21.9055131483,-67.4514875354,-29.2073508644,-63.2357695645,-36.5091885805,-59.0200515935,-43.8110262966,-54.8043336226,-51.1128640127,-50.5886156516,-58.4147017287,-46.3728976806,-65.7165394448,-42.1571797097,-73.0183771609,-33.7257437677,-73.0183771609,-25.2943078258,-73.0183771609,-16.8628718839,-73.0183771609,-8.43143594193,-73.0183771609,-5.66068871864e-14,-73.0183771609,8.43143594193,-73.0183771609,16.8628718839,-73.0183771609,25.2943078258,-73.0183771609,33.7257437677,-73.0183771609,42.1571797097,-73.0183771609,46.3728976806,-65.7165394448,50.5886156516,-58.4147017287,54.8043336226,-51.1128640127,59.0200515935,-43.8110262966,63.2357695645,-36.5091885805,67.4514875354,-29.2073508644,71.6672055064,-21.9055131483,75.8829234774,-14.6036754322,80.0986414483,-7.3018377161] - conn=[0,2,3,4,5,6,1,1,8,2,0,6,18,7,2,9,10,3,0,1,8,3,10,11,12,4,0,2,4,3,12,13,14,5,0,5,0,4,14,15,16,6,6,1,0,5,16,17,18,7,20,8,1,18,36,19,8,21,9,2,1,7,20,9,22,23,10,2,8,21,10,23,24,11,3,2,9,11,24,25,26,12,3,10,12,11,26,27,13,4,3,13,12,27,28,29,14,4,14,4,13,29,30,15,5,15,5,14,30,31,32,16,16,6,5,15,32,33,17,17,18,6,16,33,34,35,18,7,1,6,17,35,36,19,38,20,7,36,60,37,20,39,21,8,7,19,38,21,40,22,9,8,20,39,22,41,42,23,9,21,40,23,42,43,24,10,9,22,24,43,44,25,11,10,23,25,44,45,46,26,11,24,26,25,46,47,27,12,11,27,26,47,48,28,13,12,28,27,48,49,50,29,13,29,13,28,50,51,30,14,30,14,29,51,52,31,15,31,15,30,52,53,54,32,32,16,15,31,54,55,33,33,17,16,32,55,56,34,34,35,17,33,56,57,58,35,36,18,17,34,58,59,36,19,7,18,35,59,60,37,62,38,19,60,90,61,38,63,39,20,19,37,62,39,64,40,21,20,38,63,40,65,41,22,21,39,64,41,66,67,42,22,40,65,42,67,68,43,23,22,41,43,68,69,44,24,23,42,44,69,70,45,25,24,43,45,70,71,72,46,25,44,46,45,72,73,47,26,25,47,46,73,74,48,27,26,48,47,74,75,49,28,27,49,48,75,76,77,50,28,50,28,49,77,78,51,29,51,29,50,78,79,52,30,52,30,51,79,80,53,31,53,31,52,80,81,82,54,54,32,31,53,82,83,55,55,33,32,54,83,84,56,56,34,33,55,84,85,57,57,58,34,56,85,86,87,58,59,35,34,57,87,88,59,60,36,35,58,88,89,60,37,19,36,59,89,90,61,92,62,37,90,126,91,62,93,63,38,37,61,92,63,94,64,39,38,62,93,64,95,65,40,39,63,94,65,96,66,41,40,64,95,66,97,98,67,41,65,96,67,98,99,68,42,41,66,68,99,100,69,43,42,67,69,100,101,70,44,43,68,70,101,102,71,45,44,69,71,102,103,104,72,45,70,72,71,104,105,73,46,45,73,72,105,106,74,47,46,74,73,106,107,75,48,47,75,74,107,108,76,49,48,76,75,108,109,110,77,49,77,49,76,110,111,78,50,78,50,77,111,112,79,51,79,51,78,112,113,80,52,80,52,79,113,114,81,53,81,53,80,114,115,116,82,82,54,53,81,116,117,83,83,55,54,82,117,118,84,84,56,55,83,118,119,85,85,57,56,84,119,120,86,86,87,57,85,120,121,122,87,88,58,57,86,122,123,88,89,59,58,87,123,124,89,90,60,59,88,124,125,90,61,37,60,89,125,126,91,128,92,61,126,168,127,92,129,93,62,61,91,128,93,130,94,63,62,92,129,94,131,95,64,63,93,130,95,132,96,65,64,94,131,96,133,97,66,65,95,132,97,134,135,98,66,96,133,98,135,136,99,67,66,97,99,136,137,100,68,67,98,100,137,138,101,69,68,99,101,138,139,102,70,69,100,102,139,140,103,71,70,101,103,140,141,142,104,71,102,104,103,142,143,105,72,71,105,104,143,144,106,73,72,106,105,144,145,107,74,73,107,106,145,146,108,75,74,108,107,146,147,109,76,75,109,108,147,148,149,110,76,110,76,109,149,150,111,77,111,77,110,150,151,112,78,112,78,111,151,152,113,79,113,79,112,152,153,114,80,114,80,113,153,154,115,81,115,81,114,154,155,156,116,116,82,81,115,156,157,117,117,83,82,116,157,158,118,118,84,83,117,158,159,119,119,85,84,118,159,160,120,120,86,85,119,160,161,121,121,122,86,120,161,162,163,122,123,87,86,121,163,164,123,124,88,87,122,164,165,124,125,89,88,123,165,166,125,126,90,89,124,166,167,126,91,61,90,125,167,168,127,170,128,91,168,216,169,128,171,129,92,91,127,170,129,172,130,93,92,128,171,130,173,131,94,93,129,172,131,174,132,95,94,130,173,132,175,133,96,95,131,174,133,176,134,97,96,132,175,134,177,178,135,97,133,176,135,178,179,136,98,97,134,136,179,180,137,99,98,135,137,180,181,138,100,99,136,138,181,182,139,101,100,137,139,182,183,140,102,101,138,140,183,184,141,103,102,139,141,184,185,186,142,103,140,142,141,186,187,143,104,103,143,142,187,188,144,105,104,144,143,188,189,145,106,105,145,144,189,190,146,107,106,146,145,190,191,147,108,107,147,146,191,192,148,109,108,148,147,192,193,194,149,109,149,109,148,194,195,150,110,150,110,149,195,196,151,111,151,111,150,196,197,152,112,152,112,151,197,198,153,113,153,113,152,198,199,154,114,154,114,153,199,200,155,115,155,115,154,200,201,202,156,156,116,115,155,202,203,157,157,117,116,156,203,204,158,158,118,117,157,204,205,159,159,119,118,158,205,206,160,160,120,119,159,206,207,161,161,121,120,160,207,208,162,162,163,121,161,208,209,210,163,164,122,121,162,210,211,164,165,123,122,163,211,212,165,166,124,123,164,212,213,166,167,125,124,165,213,214,167,168,126,125,166,214,215,168,127,91,126,167,215,216,169,218,170,127,216,270,217,170,219,171,128,127,169,218,171,220,172,129,128,170,219,172,221,173,130,129,171,220,173,222,174,131,130,172,221,174,223,175,132,131,173,222,175,224,176,133,132,174,223,176,225,177,134,133,175,224,177,226,227,178,134,176,225,178,227,228,179,135,134,177,179,228,229,180,136,135,178,180,229,230,181,137,136,179,181,230,231,182,138,137,180,182,231,232,183,139,138,181,183,232,233,184,140,139,182,184,233,234,185,141,140,183,185,234,235,236,186,141,184,186,185,236,237,187,142,141,187,186,237,238,188,143,142,188,187,238,239,189,144,143,189,188,239,240,190,145,144,190,189,240,241,191,146,145,191,190,241,242,192,147,146,192,191,242,243,193,148,147,193,192,243,244,245,194,148,194,148,193,245,246,195,149,195,149,194,246,247,196,150,196,150,195,247,248,197,151,197,151,196,248,249,198,152,198,152,197,249,250,199,153,199,153,198,250,251,200,154,200,154,199,251,252,201,155,201,155,200,252,253,254,202,202,156,155,201,254,255,203,203,157,156,202,255,256,204,204,158,157,203,256,257,205,205,159,158,204,257,258,206,206,160,159,205,258,259,207,207,161,160,206,259,260,208,208,162,161,207,260,261,209,209,210,162,208,261,262,263,210,211,163,162,209,263,264,211,212,164,163,210,264,265,212,213,165,164,211,265,266,213,214,166,165,212,266,267,214,215,167,166,213,267,268,215,216,168,167,214,268,269,216,169,127,168,215,269,270,217,272,218,169,270,330,271,218,273,219,170,169,217,272,219,274,220,171,170,218,273,220,275,221,172,171,219,274,221,276,222,173,172,220,275,222,277,223,174,173,221,276,223,278,224,175,174,222,277,224,279,225,176,175,223,278,225,280,226,177,176,224,279,226,281,282,227,177,225,280,227,282,283,228,178,177,226,228,283,284,229,179,178,227,229,284,285,230,180,179,228,230,285,286,231,181,180,229,231,286,287,232,182,181,230,232,287,288,233,183,182,231,233,288,289,234,184,183,232,234,289,290,235,185,184,233,235,290,291,292,236,185,234,236,235,292,293,237,186,185,237,236,293,294,238,187,186,238,237,294,295,239,188,187,239,238,295,296,240,189,188,240,239,296,297,241,190,189,241,240,297,298,242,191,190,242,241,298,299,243,192,191,243,242,299,300,244,193,192,244,243,300,301,302,245,193,245,193,244,302,303,246,194,246,194,245,303,304,247,195,247,195,246,304,305,248,196,248,196,247,305,306,249,197,249,197,248,306,307,250,198,250,198,249,307,308,251,199,251,199,250,308,309,252,200,252,200,251,309,310,253,201,253,201,252,310,311,312,254,254,202,201,253,312,313,255,255,203,202,254,313,314,256,256,204,203,255,314,315,257,257,205,204,256,315,316,258,258,206,205,257,316,317,259,259,207,206,258,317,318,260,260,208,207,259,318,319,261,261,209,208,260,319,320,262,262,263,209,261,320,321,322,263,264,210,209,262,322,323,264,265,211,210,263,323,324,265,266,212,211,264,324,325,266,267,213,212,265,325,326,267,268,214,213,266,326,327,268,269,215,214,267,327,328,269,270,216,215,268,328,329,270,217,169,216,269,329,330,271,272,217,330,273,218,217,271,274,219,218,272,275,220,219,273,276,221,220,274,277,222,221,275,278,223,222,276,279,224,223,277,280,225,224,278,281,226,225,279,281,282,226,280,283,227,226,281,284,228,227,282,285,229,228,283,286,230,229,284,287,231,230,285,288,232,231,286,289,233,232,287,290,234,233,288,291,235,234,289,291,292,235,290,291,293,236,235,292,294,237,236,293,295,238,237,294,296,239,238,295,297,240,239,296,298,241,240,297,299,242,241,298,300,243,242,299,301,244,243,301,300,302,244,244,301,303,245,245,302,304,246,246,303,305,247,247,304,306,248,248,305,307,249,249,306,308,250,250,307,309,251,251,308,310,252,252,309,311,253,311,253,310,312,254,253,311,313,255,254,312,314,256,255,313,315,257,256,314,316,258,257,315,317,259,258,316,318,260,259,317,319,261,260,318,320,262,261,319,321,321,322,262,320,323,263,262,321,324,264,263,322,325,265,264,323,326,266,265,324,327,267,266,325,328,268,267,326,329,269,268,327,330,270,269,328,271,217,270,329] - connI=[0,7,14,21,28,35,42,49,56,63,70,77,84,91,98,105,112,119,126,133,140,147,154,161,168,175,182,189,196,203,210,217,224,231,238,245,252,259,266,273,280,287,294,301,308,315,322,329,336,343,350,357,364,371,378,385,392,399,406,413,420,427,434,441,448,455,462,469,476,483,490,497,504,511,518,525,532,539,546,553,560,567,574,581,588,595,602,609,616,623,630,637,644,651,658,665,672,679,686,693,700,707,714,721,728,735,742,749,756,763,770,777,784,791,798,805,812,819,826,833,840,847,854,861,868,875,882,889,896,903,910,917,924,931,938,945,952,959,966,973,980,987,994,1001,1008,1015,1022,1029,1036,1043,1050,1057,1064,1071,1078,1085,1092,1099,1106,1113,1120,1127,1134,1141,1148,1155,1162,1169,1176,1183,1190,1197,1204,1211,1218,1225,1232,1239,1246,1253,1260,1267,1274,1281,1288,1295,1302,1309,1316,1323,1330,1337,1344,1351,1358,1365,1372,1379,1386,1393,1400,1407,1414,1421,1428,1435,1442,1449,1456,1463,1470,1477,1484,1491,1498,1505,1512,1519,1526,1533,1540,1547,1554,1561,1568,1575,1582,1589,1596,1603,1610,1617,1624,1631,1638,1645,1652,1659,1666,1673,1680,1687,1694,1701,1708,1715,1722,1729,1736,1743,1750,1757,1764,1771,1778,1785,1792,1799,1806,1813,1820,1827,1834,1841,1848,1855,1862,1869,1876,1883,1890,1897,1901,1905,1909,1913,1917,1921,1925,1929,1933,1937,1941,1945,1949,1953,1957,1961,1965,1969,1973,1977,1981,1985,1989,1993,1997,2001,2005,2009,2013,2017,2021,2025,2029,2033,2037,2041,2045,2049,2053,2057,2061,2065,2069,2073,2077,2081,2085,2089,2093,2097,2101,2105,2109,2113,2117,2121,2125,2129,2133,2137] - # - m=MEDCouplingUMesh.New("convexhull",2); - m.allocateCells(331); - for i in xrange(331): - m.insertNextCell(NORM_POLYGON,conn[connI[i]:connI[i+1]]); - pass - m.finishInsertingCells(); - coordsDa=DataArrayDouble.New(coords,331,2); - m.setCoords(coordsDa); - m.checkCoherency(); - # - da=m.convexEnvelop2D(); - m.checkCoherency() - self.assertEqual(coordsDa.getHiddenCppPointer(),m.getCoords().getHiddenCppPointer()) - daC=da.buildComplement(m.getNumberOfCells()); - expected2=DataArrayInt.New([271,272,273,274,275,276,277,278,279,280,281,282,283,284,285,286,287,288,289,290,291,292,293,294,295,296,297,298,299,300,302,303,304,305,306,307,308,309,310,312,313,314,315,316,317,318,319,320,321,322,323,324,325,326,327,328,329,330]); - self.assertTrue(expected2.isEqual(daC)); - # - vals=m.getMeasureField(ON_CELLS).getArray() - ref=271*[184.69493088478035]+3*[-61.564976961404426,-92.34746544254946,-92.34746544259811,-92.34746544253488,-92.3474654425349,-92.34746544180479,-92.34746544253493,-92.3474654419026,-92.34746544190256,-92.34746544253491]+2*[61.564976961404426,-92.34746544254946,-92.34746544259811,-92.34746544253488,-92.3474654425349,-92.34746544180479,-92.34746544253493,-92.3474654419026,-92.34746544190256,-92.34746544253491]+[-61.564976961404426,-92.34746544254946,-92.34746544259811,-92.34746544253488,-92.3474654425349,-92.34746544180479,-92.34746544253493,-92.3474654419026,-92.34746544190256,-92.34746544253491] - vals-=DataArrayDouble.New(ref) - vals.abs() - theTest=vals.getIdsInRange(-1.,1e-7) - self.assertTrue(theTest.isIdentity()) - self.assertEqual(331,len(theTest)) - pass - - def testSwigDAIOp8(self): - da=DataArrayInt.New([7,5,6,7,8,9,9,10,12,13,47,15]) - self.assertTrue(7 in da) - self.assertTrue(47 in da) - self.assertTrue(15 in da) - self.assertEqual(0,da.index(7)) - self.assertEqual(10,da.index(47)) - self.assertTrue(14 not in da) - self.assertEqual(5,da.search([9,9])) - self.assertEqual(-1,da.search([5,8])) - da.rearrange(2) - self.assertTrue([47,16] not in da) - self.assertTrue([5,6] not in da) - self.assertTrue([6,7] in da) - self.assertEqual(4,da.index([12,13])) - pass - - def testDataArraySort1(self): - arr=DataArrayInt.New(); - self.assertRaises(InterpKernelException,arr.sort,True) - self.assertRaises(InterpKernelException,arr.sort,False) - values=[2,1,6,5,4,7] - arr.alloc(3,2); - self.assertRaises(InterpKernelException,arr.sort,True) - self.assertRaises(InterpKernelException,arr.sort,False) - arr.rearrange(1); - arr.setValues(values,6,1) - arr1=arr.deepCpy(); - arr2=arr.deepCpy(); - arr1.sort(True); - expected1=[1,2,4,5,6,7] - self.assertEqual(6,arr1.getNumberOfTuples()); - self.assertEqual(1,arr1.getNumberOfComponents()); - self.assertEqual(expected1,arr1.getValues()); - arr2.sort(False); - expected2=[7,6,5,4,2,1] - self.assertEqual(6,arr2.getNumberOfTuples()); - self.assertEqual(1,arr2.getNumberOfComponents()); - self.assertTrue(expected2,arr2.getValues()); - # - ard=DataArrayDouble.New(); - self.assertRaises(InterpKernelException,ard.sort,True) - self.assertRaises(InterpKernelException,ard.sort,False) - valuesD=[2.,1.,6.,5.,4.,7.] - ard.alloc(3,2); - self.assertRaises(InterpKernelException,ard.sort,True) - self.assertRaises(InterpKernelException,ard.sort,False) - ard.rearrange(1); - ard.setValues(valuesD,6,1) - ard1=ard.deepCpy(); - ard2=ard.deepCpy(); - ard1.sort(True); - expected3=[1.,2.,4.,5.,6.,7.] - self.assertEqual(6,ard1.getNumberOfTuples()); - self.assertEqual(1,ard1.getNumberOfComponents()); - for i in xrange(6): - self.assertAlmostEqual(expected3[i],ard1.getIJ(i,0),12) - pass - ard2.sort(False); - expected4=[7.,6.,5.,4.,2.,1.] - self.assertEqual(6,ard2.getNumberOfTuples()); - self.assertEqual(1,ard2.getNumberOfComponents()); - for i in xrange(6): - self.assertAlmostEqual(expected4[i],ard2.getIJ(i,0),12) - pass - pass - - def testPartitionBySpreadZone1(self): - m=MEDCouplingDataForTest.build2DTargetMesh_1(); - m4=MEDCouplingUMesh.MergeUMeshes([m,m[-3:],m[0:2]]); - m4.renumberCells([5,2,9,6,4,7,0,1,3,8]); - # - v2=m4.partitionBySpreadZone(); - self.assertTrue(3,len(v2)); - self.assertTrue(v2[0].isEqual(DataArrayInt.New([0,1,7]))) - self.assertTrue(v2[1].isEqual(DataArrayInt.New([2,4,5,6,9]))) - self.assertTrue(v2[2].isEqual(DataArrayInt.New([3,8]))) - # - m5=m4.buildSpreadZonesWithPoly(); - self.assertEqual(3,m5.getNumberOfCells()); - self.assertTrue(m5.getCoords().getHiddenCppPointer()==m4.getCoords().getHiddenCppPointer()); - self.assertEqual([5,15,16,17,14,11,13,12,5,2,1,0,3,6,7,8,5,5,18,21,22,20,19],m5.getNodalConnectivity().getValues()) - self.assertEqual([0,8,17,23],m5.getNodalConnectivityIndex().getValues()) - # - pass - - def testGiveCellsWithType1(self): - expected0=[1,2] - expected1=[0,3,4] - m=MEDCouplingDataForTest.build2DTargetMesh_1(); - da=m.giveCellsWithType(NORM_TRI3); - self.assertEqual(2,da.getNumberOfTuples()); - self.assertEqual(1,da.getNumberOfComponents()); - self.assertEqual(expected0,da.getValues()) - # - da=m.giveCellsWithType(NORM_QUAD4); - self.assertEqual(3,da.getNumberOfTuples()); - self.assertEqual(1,da.getNumberOfComponents()); - self.assertEqual(expected1,da.getValues()) - # - da=m.giveCellsWithType(NORM_TRI6); - self.assertEqual(0,da.getNumberOfTuples()); - self.assertEqual(1,da.getNumberOfComponents()); - # - self.assertRaises(InterpKernelException,m.giveCellsWithType,NORM_SEG2) - self.assertRaises(InterpKernelException,m.giveCellsWithType,NORM_HEXA8) - pass - - def testSwigDAOp1(self): - d=DataArrayDouble.New(5,2) - d.rearrange(1) ; d.iota(2.) ; d.rearrange(2) - d.setInfoOnComponents(["X [m]","Y [m]"]) - d.setName("AName") - # - d1=d+[8,9] - self.assertTrue(d1.isEqualWithoutConsideringStr(DataArrayDouble.New([10.0,12.0,12.0,14.0,14.0,16.0,16.0,18.0,18.0,20.0]),1e-12)) - d1bis=DataArrayDouble.New([8,9],1,2)+d - self.assertTrue(d1bis.isEqual(d1,1e-12)) - d1ter=[8,9]+d - self.assertTrue(d1ter.isEqual(d1,1e-12)) - # - d2=d1-[8,9] - self.assertTrue(d2.isEqual(d,1e-12)) - self.assertRaises(InterpKernelException,d1.__rsub__,[8,9])#[8,9]-d1 - # - d3=d*[8,9] - self.assertTrue(d3.isEqualWithoutConsideringStr(DataArrayDouble.New([16.0,27.0,32.0,45.0,48.0,63.0,64.0,81.0,80.0,99.0]),1e-12)) - d3bis=DataArrayDouble.New([8,9],1,2)*d - self.assertTrue(d3bis.isEqual(d3,1e-12)) - d3ter=[8,9]*d - self.assertTrue(d3ter.isEqual(d3,1e-12)) - # - d4=d3/[8,9] - self.assertTrue(d4.isEqual(d,1e-12)) - # - d=DataArrayInt.New(5,2) - d.rearrange(1) ; d.iota(2) ; d.rearrange(2) - d.setInfoOnComponents(["X [m]","Y [m]"]) - d.setName("AName") - # - d1=d+[8,9] - self.assertEqual(d1.getValues(),[10,12,12,14,14,16,16,18,18,20]) - d1bis=DataArrayInt.New([8,9],1,2)+d - self.assertTrue(d1bis.isEqual(d1)) - d1ter=[8,9]+d - self.assertTrue(d1ter.isEqual(d1)) - # - d2=d1-[8,9] - self.assertTrue(d2.isEqual(d)) - self.assertRaises(InterpKernelException,d1.__rsub__,[8,9]) - # - d3=d*[8,9] - self.assertEqual(d3.getValues(),[16,27,32,45,48,63,64,81,80,99]) - d3bis=DataArrayInt.New([8,9],1,2)*d - self.assertTrue(d3bis.isEqual(d3)) - d3ter=[8,9]*d - self.assertTrue(d3ter.isEqual(d3)) - # - d4=d3/[8,9] - self.assertTrue(d4.isEqual(d)) - # - d5=d%[4,5] - self.assertEqual(d5.getValues(),[2,3,0,0,2,2,0,4,2,1]) - pass - - def testSwigSelectTupleId2DAIBug1(self): - da=DataArrayInt.New([0,1,2,3,12,13,4,5,6,7,14,15,8,9,10,11,16,17]) - self.assertEqual([2,6,10],da[2::6].getValues()) - self.assertEqual([0,4,8],da[::6].getValues()) - self.assertEqual([5,9],da[7::6].getValues()) - self.assertEqual([5],da[7:-5:6].getValues()) - pass - - def testSwigCpp5Safe1(self): - m=MEDCouplingUMesh.New("toto",2) - coords=DataArrayDouble.New([0.,0.,1.,0.,1.,1.,0.,1.],4,2) - m.setCoords(coords) - vecs=DataArrayDouble.New([2.,3.,4.,5.,6.,7.],3,2) - expected1=[[2.,3.,3.,3.,3.,4.,2.,4.0],[4.,5.,5.,5.,5.,6.,4.,6.0],[6.,7.,7.,7.,7.,8.,6.,8.0]] - for pos,vec in enumerate(vecs): - m2=m.deepCpy() - m2.translate(vec) - self.assertTrue(m2.getCoords().isEqual(DataArrayDouble.New(expected1[pos],4,2),1e-12)) - pass - for pos,vec in enumerate(vecs): - m2=m.deepCpy() - m2.translate(vec.buildDADouble()) - self.assertTrue(m2.getCoords().isEqual(DataArrayDouble.New(expected1[pos],4,2),1e-12)) - pass - pass - - def testSwigBugNonRegressionZipDA(self): - angles=map(lambda x:pi/3*x,xrange(6)) - radius=3 - # - dad=DataArrayDouble.New(6, 2) - dad[:,0]=radius - dad[:,1]=angles - # - dad2=dad.fromPolarToCart() - dads=[dad2.deepCpy() for elt in 7*[None]] - # - translationToPerform=[[0.01,0.02],[3./2.*radius,-radius*sqrt(3.)/2],[3./2.*radius,radius*sqrt(3.)/2],[0.,radius*sqrt(3.)],[-3./2.*radius,radius*sqrt(3.)/2],[-3./2.*radius,-radius*sqrt(3.)/2],[0.,-radius*sqrt(3.)]] - for d,t in zip(dads,translationToPerform): - d+=t - pass - for elt in dads: - self.assertTrue(not dad2.isEqual(elt,1e-12)) - pass - for d,t in zip(dads,translationToPerform): - d-=t - pass - for elt in dads: - self.assertTrue(dad2.isEqual(elt,1e-12)) - pass - pass - - def testBuildSlice3D2(self): - mesh3D,mesh2D=MEDCouplingDataForTest.build3DExtrudedUMesh_1(); - vec1=[-0.07,1.,0.07] - origin1=[1.524,1.4552,1.74768] - slice1,ids=mesh3D.buildSlice3D(origin1,vec1,1e-10); - f=MEDCouplingFieldDouble(ON_CELLS,ONE_TIME) - f.setTime(4.5,6,7) ; f.setMesh(mesh3D) - arr=DataArrayDouble(mesh3D.getNumberOfCells(),2) - arr.rearrange(1) ; arr.iota(2.) ; arr.rearrange(2) - f.setArray(arr) - f.checkCoherency() - expected1=DataArrayInt([1,3,4,7,9,10,13,15,16]) - self.assertTrue(expected1.isEqual(ids)) - arr2=arr[expected1] - # - f2=f.extractSlice3D(origin1,vec1,1e-10) - self.assertTrue(f2.getArray().isEqual(arr2,1e-12)); - self.assertTrue(slice1.isEqual(f2.getMesh(),1e-12)) - self.assertEqual(6,f2.getTime()[1]) ; self.assertEqual(7,f2.getTime()[2]) - self.assertAlmostEqual(4.5,f2.getTime()[0],12); - pass - - def testComputeTupleIdsToSelectFromCellIds1(self): - m=MEDCouplingDataForTest.build2DTargetMesh_3() - f=MEDCouplingFieldDouble.New(ON_GAUSS_NE,NO_TIME); - f.setMesh(m); - arr=DataArrayDouble(52,2) ; arr.rearrange(1) ; arr.iota(7.) ; arr.rearrange(2) - f.setArray(arr) - # - f2=f.buildSubPart([1,5,9]) - f2.checkCoherency() - cI=m.computeNbOfNodesPerCell() - cI.computeOffsets2() - sel=DataArrayInt([1,5,9]) - res=sel.buildExplicitArrByRanges(cI) - arr2=arr[res] - self.assertTrue(arr2.isEqual(DataArrayDouble([13,14,15,16,17,18,19,20,59,60,61,62,63,64,95,96,97,98,99,100,101,102,103,104,105,106,107,108,109,110],15,2),1e-12)) - self.assertTrue(arr2.isEqual(f2.getArray(),1e-12)) - pass - - def testComputeSkin1(self): - arrX=DataArrayDouble([2.,3.4,5.6,7.7,8.0]) ; arrY=DataArrayDouble([2.,3.4,5.6,7.7,9.0,14.2]) - cmesh=MEDCouplingCMesh() ; cmesh.setCoordsAt(0,arrX) ; cmesh.setCoordsAt(1,arrY) - umesh=cmesh.buildUnstructured() - # - skin=umesh.computeSkin() - self.assertEqual(18,skin.getNumberOfCells()) - self.assertEqual(1,skin.getMeshDimension()) - self.assertTrue(skin.getCoords().getHiddenCppPointer()==umesh.getCoords().getHiddenCppPointer()) - self.assertEqual([0,3,6,9,12,15,18,21,24,27,30,33,36,39,42,45,48,51,54],skin.getNodalConnectivityIndex().getValues()) - self.assertEqual([1,1,0,1,0,5,1,2,1,1,3,2,1,4,3,1,9,4,1,5,10,1,14,9,1,10,15,1,19,14,1,15,20,1,24,19,1,20,25,1,25,26,1,26,27,1,27,28,1,28,29,1,29,24],skin.getNodalConnectivity().getValues()) - ids=skin.computeFetchedNodeIds() - self.assertEqual([0,1,2,3,4,5,9,10,14,15,19,20,24,25,26,27,28,29],ids.getValues()) - part=umesh.buildFacePartOfMySelfNode(ids,True) - part.setName(skin.getName()); - self.assertTrue(part.isEqual(skin,1e-12)) - part2=part[1::2] - part[::2]=part2 - self.assertTrue(not part.isEqual(skin,1e-12)) - trad=part.zipConnectivityTraducer(0) - self.assertEqual(9,part.getNumberOfCells()) - self.assertEqual([0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8],trad.getValues()) - pass - - def testUMeshSetPartOfMySelf2(self): - # resize with explicit ids list - m=MEDCouplingDataForTest.build2DTargetMesh_1() - self.assertEqual([3,4],m.getAllGeoTypes()) - part=m[[0,3,4]] - part.simplexize(0) - part2=part[[1,2,5]] - m[[0,3,4]]=part2 - self.assertEqual([3,0,4,1,3,1,4,2,3,4,5,2,3,6,7,4,3,7,5,4],m.getNodalConnectivity().getValues()) - self.assertEqual([0,4,8,12,16,20],m.getNodalConnectivityIndex().getValues()) - self.assertEqual([3],m.getAllGeoTypes()) - # no resize with explicit ids list - m=MEDCouplingDataForTest.build2DTargetMesh_1() - part=m[[0,3]] - part.convertAllToPoly() - m[[3,4]]=part - self.assertEqual([4,0,3,4,1,3,1,4,2,3,4,5,2,5,0,3,4,1,5,6,7,4,3],m.getNodalConnectivity().getValues()) - self.assertEqual([0,5,9,13,18,23],m.getNodalConnectivityIndex().getValues()) - self.assertEqual([3,4,5],m.getAllGeoTypes()) - # resize with range ids - m=MEDCouplingDataForTest.build2DTargetMesh_1() - part=m[3:] - m[1:3]=part - self.assertEqual([4,0,3,4,1,4,6,7,4,3,4,7,8,5,4,4,6,7,4,3,4,7,8,5,4],m.getNodalConnectivity().getValues()) - self.assertEqual([0,5,10,15,20,25],m.getNodalConnectivityIndex().getValues()) - self.assertEqual([4],m.getAllGeoTypes()) - # no resize with range ids - m=MEDCouplingDataForTest.build2DTargetMesh_1() - part=m[0::3] - part.convertAllToPoly() - m[3:]=part - self.assertEqual([4,0,3,4,1,3,1,4,2,3,4,5,2,5,0,3,4,1,5,6,7,4,3],m.getNodalConnectivity().getValues()) - self.assertEqual([0,5,9,13,18,23],m.getNodalConnectivityIndex().getValues()) - self.assertEqual([3,4,5],m.getAllGeoTypes()) - # no resize with range ids negative direction - m=MEDCouplingDataForTest.build2DTargetMesh_1() - part=m[3::-3] - part.convertAllToPoly() - m[:-3:-1]=part - self.assertEqual([4,0,3,4,1,3,1,4,2,3,4,5,2,5,0,3,4,1,5,6,7,4,3],m.getNodalConnectivity().getValues()) - self.assertEqual([0,5,9,13,18,23],m.getNodalConnectivityIndex().getValues()) - self.assertEqual([3,4,5],m.getAllGeoTypes()) - pass - - def testUnPolyze3(self): - coord=[0.0,0.5,-0.5,-0.5,-0.5,-0.5,0.5,-0.5,-0.5,0.0,0.5,0.5,-0.5,-0.5,0.5,0.5,-0.5,0.5] - conn=[1,2,5,4,-1,4,3,0,1,-1,2,0,3,5,-1,0,2,1,-1,4,5,3] - m=MEDCouplingUMesh.New("a mesh",3); - m.allocateCells(1); - m.insertNextCell(NORM_POLYHED,22,conn[0:22]) - m.finishInsertingCells(); - coords=DataArrayDouble(coord,6,3); - m.setCoords(coords); - m.checkCoherency(); - # - vol=m.getMeasureField(ON_CELLS); - self.assertEqual(1,vol.getArray().getNumberOfTuples()); - self.assertAlmostEqual(0.5,vol.getArray().getIJ(0,0),12) - # - m.unPolyze(); - # - self.assertEqual([NORM_PENTA6],m.getAllGeoTypes()) - self.assertTrue(DataArrayInt([0,7]).isEqual(m.getNodalConnectivityIndex())) - self.assertTrue(DataArrayInt([16,0,2,1,3,5,4]).isEqual(m.getNodalConnectivity())) - # - vol=m.getMeasureField(ON_CELLS); - self.assertEqual(1,vol.getArray().getNumberOfTuples()); - self.assertAlmostEqual(0.5,vol.getArray().getIJ(0,0),12) - pass - - def testKrSpatialDiscretization1(self): - srcPointCoordsX=[0.8401877171547095, 0.7830992237586059, 0.9116473579367843, 0.335222755714889, 0.2777747108031878, 0.4773970518621602, 0.3647844727918433, 0.9522297251747128, 0.6357117279599009, 0.1416025553558034] - srcFieldValsOnPoints=[2.129892434968836, 2.295320474540621, 1.931948594981134, 2.728013590937196, 2.715603240418478, 2.661778472822935, 2.695696990104364, 1.893710234970982, 2.529628016549284, 2.728432341300668] - targetPointCoordsX=[-0.5,-0.45,-0.4,-0.35,-0.3,-0.25,-0.2,-0.15,-0.1,-0.05,-6.93889390391e-17,0.05,0.1,0.15,0.2,0.25,0.3,0.35,0.4,0.45,0.5,0.55,0.6,0.65,0.7,0.75,0.8,0.85,0.9,0.95,1.0,1.05,1.1,1.15,1.2,1.25,1.3,1.35,1.4,1.45] - targetFieldValsExpected=[2.975379475824351, 2.95613491917003, 2.936890362515361, 2.917645805861018, 2.898401249206574, 2.879156692552137, 2.859912135897732, 2.840667579243201, 2.821423022588731, 2.802178465934342, 2.78293390927989, 2.763689352625457, 2.744444795971001, 2.725209522098197, 2.709077577124666, 2.706677252549218, 2.727467797847971, 2.713338094723676, 2.671342424824244, 2.664877370146978, 2.653840141412181, 2.619607861392791, 2.569777214476479, 2.513263929794591, 2.450732752808528, 2.368313560985155, 2.250909795670307, 2.098194272085416, 1.954257891732065, 1.895040660973802, 1.865256788315972, 1.835475248687992, 1.80569370905998, 1.775912169431971, 1.746130629803976, 1.716349090175918, 1.686567550547855, 1.656786010919941, 1.627004471291988, 1.597222931663817] - coeffsExpected=DataArrayDouble.New([52.238272642008695, 26.186513281350948, -173.42106377948534, 324.56733663875184, -104.64968873410248, 34.375030568158316, -256.12372208190425, 105.2292032463934, -16.239907618144965, 7.838025836978943, 2.621910745077291, -0.4902609628247241]) - # - nbOfInputPoints=10; - f=MEDCouplingFieldDouble.New(ON_NODES_KR,ONE_TIME); - srcArrX=DataArrayDouble.New(srcPointCoordsX,nbOfInputPoints,1); - cmesh=MEDCouplingCMesh.New("aMesh"); - cmesh.setCoordsAt(0,srcArrX); - umesh=cmesh.buildUnstructured(); - f.setMesh(umesh); - srcVals=DataArrayDouble.New(srcFieldValsOnPoints,nbOfInputPoints,1); - f.setArray(srcVals); - f.checkCoherency(); - # - res0=f.getValueOn(targetPointCoordsX[:1]); - self.assertAlmostEqual(targetFieldValsExpected[0],res0[0],10) - # - valuesToTest=f.getValueOnMulti(targetPointCoordsX); - self.assertEqual(40,valuesToTest.getNumberOfTuples()); - self.assertEqual(1,valuesToTest.getNumberOfComponents()); - for i in xrange(40): - self.assertAlmostEqual(targetFieldValsExpected[i],valuesToTest.getIJ(i,0),10) - pass - fd=f.getDiscretization() - del f - self.assertTrue(isinstance(fd,MEDCouplingFieldDiscretizationKriging)) - coeffs,isDrift=fd.computeVectorOfCoefficients(umesh,srcVals) - self.assertEqual(2,isDrift) - self.assertTrue(coeffsExpected.isEqual(coeffs,1e-8)) - # - pass - - def testDuplicateEachTupleNTimes1(self): - d=DataArrayDouble.New([9.,8.,7.,6.],4,1) ; d.setInfoOnComponents(["mass [kg]"]) ; d.setName("aname") - d2=d.duplicateEachTupleNTimes(3) - self.assertTrue(d2.isEqualWithoutConsideringStr(DataArrayDouble.New([9.,9.,9.,8.,8.,8.,7.,7.,7.,6.,6.,6.],4*3,1),1e-14)) - self.assertEqual("aname",d2.getName()) - self.assertEqual(["mass [kg]"],d2.getInfoOnComponents()) - # - d=DataArrayInt.New([9,8,7,6],4,1) ; d.setInfoOnComponents(["mass [kg]"]) ; d.setName("aname") - d2=d.duplicateEachTupleNTimes(3) - self.assertTrue(d2.isEqualWithoutConsideringStr(DataArrayInt.New([9,9,9,8,8,8,7,7,7,6,6,6],4*3,1))) - self.assertEqual("aname",d2.getName()) - self.assertEqual(["mass [kg]"],d2.getInfoOnComponents()) - pass - - def testSwigComputeTupleIdsNearTuples1(self): - da=DataArrayDouble([5.,6.,-5.,-6.,5.,-6.,-5.,6.,5.,6.],5,2) - arr,arrI=da.computeTupleIdsNearTuples(DataArrayDouble([5.,-6.,5.,6.,-5.,-6.],3,2),1e-10) - self.assertEqual([2,0,4,1],arr.getValues()) - self.assertEqual([0,1,3,4],arrI.getValues()) - arr,arrI=da.computeTupleIdsNearTuples([5.,-6.,5.,6.,-5.,-6.],1e-10) - self.assertEqual([2,0,4,1],arr.getValues()) - self.assertEqual([0,1,3,4],arrI.getValues()) - expected0=[[2],[0,4],[1]] - expected1=[[0,1],[0,2],[0,1]] - for pos,it in enumerate(DataArrayDouble([5.,-6.,5.,6.,-5.,-6.],3,2)): - arr,arrI=da.computeTupleIdsNearTuples(it,1e-10) - self.assertEqual(expected0[pos],arr.getValues()) - self.assertEqual(expected1[pos],arrI.getValues()) - pass - pass - - def testSwigDataTupleIOp1(self): - d=DataArrayDouble(10,1) - d.iota(7.) - for elt in d: - elt+=2. - pass - toTest=DataArrayDouble([9.0,10.0,11.0,12.0,13.0,14.0,15.0,16.0,17.0,18.0]) - self.assertTrue(toTest.isEqual(d,1e-12)) - for elt in d: - elt-=2. - pass - toTest=DataArrayDouble([7.0,8.0,9.0,10.0,11.0,12.0,13.0,14.0,15.0,16.0]) - self.assertTrue(toTest.isEqual(d,1e-12)) - for elt in d: - elt*=2. - pass - toTest=DataArrayDouble([14.0,16.0,18.0,20.0,22.0,24.0,26.0,28.0,30.0,32.0]) - self.assertTrue(toTest.isEqual(d,1e-12)) - for elt in d: - elt/=2. - pass - toTest=DataArrayDouble([7.0,8.0,9.0,10.0,11.0,12.0,13.0,14.0,15.0,16.0]) - self.assertTrue(toTest.isEqual(d,1e-12)) - # - d=DataArrayInt(10,1) - d.iota(7) - for elt in d: - elt+=2 - pass - self.assertEqual(d.getValues(),[9,10,11,12,13,14,15,16,17,18]) - for elt in d: - elt-=2 - pass - self.assertEqual(d.getValues(),[7,8,9,10,11,12,13,14,15,16]) - for elt in d: - elt*=2 - pass - self.assertEqual(d.getValues(),[14,16,18,20,22,24,26,28,30,32]) - for elt in d: - elt/=2 - pass - self.assertEqual(d.getValues(),[7,8,9,10,11,12,13,14,15,16]) - for elt in d: - elt%=3 - pass - self.assertEqual(d.getValues(),[1,2,0,1,2,0,1,2,0,1]) - pass - - def testIntersect2DMeshesTmp5(self): - coords=DataArrayDouble.New([41,0,42,0,0,42,0,41,41.5,0,29.698484809834998,29.698484809834994,0,41.5,28.991378028648452,28.991378028648445,-42,0,-41,0,-29.698484809834994,29.698484809834998,-41.5,0,-28.991378028648445,28.991378028648452,0,-42,0,-41,-29.698484809835001,-29.698484809834994,0,-41.5,-28.991378028648455,-28.991378028648445,29.698484809834987,-29.698484809835001,28.991378028648441,-28.991378028648455,43,0,0,43,42.5,0,30.405591591021544,30.40559159102154,0,42.5,-43,0,-30.40559159102154,30.405591591021544,-42.5,0,0,-43,-30.405591591021551,-30.40559159102154,0,-42.5,30.405591591021537,-30.405591591021551,44,0,0,44,43.5,0,31.112698372208094,31.112698372208087,0,43.5,-44,0,-31.112698372208087,31.112698372208094,-43.5,0,0,-44,-31.112698372208097,-31.112698372208087,0,-43.5,31.112698372208083,-31.112698372208097,45,0,0,45,44.5,0,31.81980515339464,31.819805153394636,0,44.5,-45,0,-31.819805153394636,31.81980515339464,-44.5,0,0,-45,-31.819805153394647,-31.819805153394636,0,-44.5,31.819805153394629,-31.819805153394647,47,0,0,47,46,0,33.234018715767739,33.234018715767732,0,46,-47,0,-33.234018715767732,33.234018715767739,-46,0,0,-47,-33.234018715767739,-33.234018715767732,0,-46,33.234018715767725,-33.234018715767739,49,0,0,49,48,0,34.648232278140831,34.648232278140824,0,48,-49,0,-34.648232278140824,34.648232278140831,-48,0,0,-49,-34.648232278140839,-34.648232278140824,0,-48,34.648232278140817,-34.648232278140839,51,0,0,51,50,0,36.062445840513924,36.062445840513924,0,50,-51,0,-36.062445840513924,36.062445840513924,-50,0,0,-51,-36.062445840513931,-36.062445840513924,0,-50,36.062445840513917,-36.062445840513931,53,0,0,53,52,0,37.476659402887023,37.476659402887016,0,52,-53,0,-37.476659402887016,37.476659402887023,-52,0,0,-53,-37.47665940288703,-37.476659402887016,0,-52,37.476659402887009,-37.47665940288703,55,0,0,55,54,0,38.890872965260115,38.890872965260108,0,54,-55,0,-38.890872965260108,38.890872965260115,-54,0,0,-55,-38.890872965260122,-38.890872965260108,0,-54,38.890872965260101,-38.890872965260122,59,0,0,59,57,0,41.719300090006307,41.7193000900063,0,57,-59,0,-41.7193000900063,41.719300090006307,-57,0,0,-59,-41.719300090006314,-41.7193000900063,0,-57,41.719300090006293,-41.719300090006314,63,0,0,63,61,0,44.547727214752499,44.547727214752491,0,61,-63,0,-44.547727214752491,44.547727214752499,-61,0,0,-63,-44.547727214752506,-44.547727214752491,0,-61,44.547727214752484,-44.547727214752506,67,0,0,67,65,0,47.37615433949869,47.376154339498683,0,65,-67,0,-47.376154339498683,47.37615433949869,-65,0,0,-67,-47.376154339498697,-47.376154339498683,0,-65,47.376154339498676,-47.376154339498697,71,0,0,71,69,0,50.204581464244875,50.204581464244868,0,69,-71,0,-50.204581464244868,50.204581464244875,-69,0,0,-71,-50.204581464244889,-50.204581464244868,0,-69,50.20458146424486,-50.204581464244889,75,0,0,75,73,0,53.033008588991066,53.033008588991059,0,73,-75,0,-53.033008588991059,53.033008588991066,-73,0,0,-75,-53.033008588991073,-53.033008588991059,0,-73,53.033008588991052,-53.033008588991073,80,0,0,80,77.5,0,56.568542494923804,56.568542494923797,0,77.5,-80,0,-56.568542494923797,56.568542494923804,-77.5,0,0,-80,-56.568542494923818,-56.568542494923797,0,-77.5,56.56854249492379,-56.568542494923818],188,2) - conn=DataArrayInt.New([8,0,1,2,3,4,5,6,7,8,3,2,8,9,6,10,11,12,8,9,8,13,14,11,15,16,17,8,14,13,1,0,16,18,4,19,8,1,20,21,2,22,23,24,5,8,2,21,25,8,24,26,27,10,8,8,25,28,13,27,29,30,15,8,13,28,20,1,30,31,22,18,8,20,32,33,21,34,35,36,23,8,21,33,37,25,36,38,39,26,8,25,37,40,28,39,41,42,29,8,28,40,32,20,42,43,34,31,8,32,44,45,33,46,47,48,35,8,33,45,49,37,48,50,51,38,8,37,49,52,40,51,53,54,41,8,40,52,44,32,54,55,46,43,8,44,56,57,45,58,59,60,47,8,45,57,61,49,60,62,63,50,8,49,61,64,52,63,65,66,53,8,52,64,56,44,66,67,58,55,8,56,68,69,57,70,71,72,59,8,57,69,73,61,72,74,75,62,8,61,73,76,64,75,77,78,65,8,64,76,68,56,78,79,70,67,8,68,80,81,69,82,83,84,71,8,69,81,85,73,84,86,87,74,8,73,85,88,76,87,89,90,77,8,76,88,80,68,90,91,82,79,8,80,92,93,81,94,95,96,83,8,81,93,97,85,96,98,99,86,8,85,97,100,88,99,101,102,89,8,88,100,92,80,102,103,94,91,8,92,104,105,93,106,107,108,95,8,93,105,109,97,108,110,111,98,8,97,109,112,100,111,113,114,101,8,100,112,104,92,114,115,106,103,8,104,116,117,105,118,119,120,107,8,105,117,121,109,120,122,123,110,8,109,121,124,112,123,125,126,113,8,112,124,116,104,126,127,118,115,8,116,128,129,117,130,131,132,119,8,117,129,133,121,132,134,135,122,8,121,133,136,124,135,137,138,125,8,124,136,128,116,138,139,130,127,8,128,140,141,129,142,143,144,131,8,129,141,145,133,144,146,147,134,8,133,145,148,136,147,149,150,137,8,136,148,140,128,150,151,142,139,8,140,152,153,141,154,155,156,143,8,141,153,157,145,156,158,159,146,8,145,157,160,148,159,161,162,149,8,148,160,152,140,162,163,154,151,8,152,164,165,153,166,167,168,155,8,153,165,169,157,168,170,171,158,8,157,169,172,160,171,173,174,161,8,160,172,164,152,174,175,166,163,8,164,176,177,165,178,179,180,167,8,165,177,181,169,180,182,183,170,8,169,181,184,172,183,185,186,173,8,172,184,176,164,186,187,178,175],540) - connI=DataArrayInt.New([0,9,18,27,36,45,54,63,72,81,90,99,108,117,126,135,144,153,162,171,180,189,198,207,216,225,234,243,252,261,270,279,288,297,306,315,324,333,342,351,360,369,378,387,396,405,414,423,432,441,450,459,468,477,486,495,504,513,522,531,540],61) - # - m1=MEDCouplingUMesh.New("Fix",2); - m1.setCoords(coords); - m1.setConnectivity(conn,connI,True); - # - coords=DataArrayDouble([46.5,-2.5,53.5,-2.5,53.5,2.5,46.5,2.5,50,-2.5,53.5,0,50,2.5,46.5,0,60.5,-2.5,60.5,2.5,57,-2.5,60.5,0,57,2.5,53.5,7.5,46.5,7.5,53.5,5,50,7.5,46.5,5,60.5,7.5,60.5,5,57,7.5,-2,47,2,47,2,53,-2,53,0,47,2,50,0,53,-2,50,6,47,6,53,4,47,6,50,4,53,2,59,-2,59,2,56,0,59,-2,56,6,59,6,56,4,59],42,2) - # connectivity - conn=DataArrayInt([8,0,1,2,3,4,5,6,7,8,1,8,9,2,10,11,12,5,8,3,2,13,14,6,15,16,17,8,2,9,18,13,12,19,20,15,8,21,22,23,24,25,26,27,28,8,22,29,30,23,31,32,33,26,8,24,23,34,35,27,36,37,38,8,23,30,39,34,33,40,41,36],72); - conn.setName(""); - connI=DataArrayInt([0,9,18,27,36,45,54,63,72],9) - m2=MEDCouplingUMesh.New("Mobile",2); - m2.setCoords(coords); - m2.setConnectivity(conn,connI,True); - # - m3,d1,d2=MEDCouplingUMesh.Intersect2DMeshes(m1,m2,1e-10); - self.assertEqual(105,m3.getNumberOfCells()); - self.assertEqual(105,d1.getNumberOfTuples()); - self.assertEqual(105,d2.getNumberOfTuples()); - self.assertEqual(704,m3.getNumberOfNodes()); - # - areaExpected=[-65.18804756198824,-65.18804756198824,-65.18804756198824,-65.18804756198824,-66.75884388878285,-66.75884388878285,-66.7588438887833,-66.75884388878308,-68.32964021557768,-68.32964021557768,-68.32964021557814,-68.32964021557791,-69.9004365423732,-69.9004365423732,-69.90043654237297,-69.90043654237297,-1.194568659706448,-1.0869994447159463,-142.2316939607081,-144.51326206513068,-144.5132620651309,-1.1945686597064424,-143.3186934054243,-5.002264310862817,-10.0261332846393,-3.9727823117092953,-7.290862524642649,-124.504404940456,-3.9727823117093237,-146.82366506060032,-150.79644737231024,-5.002264310862776,-145.79418306144626,-5.00208651738126,-10.054764051268958,-4.001067863263231,-8.027932154428669,-129.99378209314813,-4.001067863263216,-153.07856481622616,-157.0796326794898,-5.0020865173811915,-152.07754616210832,-5.001928880064381,-10.050590216368969,-4.00098721602491,-8.025810856794209,-136.28350081741684,-4.000987216024939,-159.36183077064402,-163.36281798667005,-5.0019288800643285,-158.36088910660442,-1.2991516319851801,-3.702636830195414,-3.7815130030068254,-6.265364371195623,-0.02516260900254963,-0.6553944641345026,-3.975752765070567,-7.368528340442765,-142.57249927881398,-0.02516260900254963,-3.9757527650706095,-165.64508791977525,-169.64600329384803,-1.299151631985167,-3.7026368301953885,-164.6442148316677,-10.00321285677458,-20.08414323176165,-8.001644468035863,-16.042954878437143,-304.0096070742277,-8.00164446803587,-350.1399180412005,-358.1415625092368,-10.003212856774468,-348.13834965246224,-3.794150313030109,-8.65049239704272,-0.02260276689354157,-0.5885167811200915,-370.2185414798688,-0.022602766893559393,-383.2517009710623,-383.2743037379555,-3.7941503130300576,-379.48015342492505,-408.40704496667513,-408.4070449666742,-408.4070449666742,-408.4070449666742,-433.53978619538975,-433.5397861953902,-433.5397861953911,-433.53978619539066,-458.67252742410983,-458.6725274241094,-458.67252742410983,-458.6725274241089,-608.6835766330232,-608.6835766330232,-608.6835766330232,-608.6835766330241] - expected1=[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,16,16,17,18,19,19,20,20,20,20,20,21,21,22,23,23,24,24,24,24,24,25,25,26,27,27,28,28,28,28,28,29,29,30,31,31,32,32,32,32,32,32,32,32,32,33,33,33,34,35,35,35,36,36,36,36,36,37,37,38,39,39,40,40,40,40,40,41,41,42,43,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59] - expected2=[-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,0,2,-1,-1,-1,0,-1,0,2,4,5,-1,4,-1,-1,0,-1,0,2,4,5,-1,4,-1,-1,0,-1,0,2,4,5,-1,4,-1,-1,0,-1,0,1,2,3,4,5,6,7,-1,4,6,-1,-1,0,1,-1,1,3,6,7,-1,6,-1,-1,1,-1,1,3,6,7,-1,6,-1,-1,1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1] - f3=m3.getMeasureField(ON_CELLS).getArray().getValues(); - for i in xrange(105): - self.assertAlmostEqual(areaExpected[i],f3[i],10) - pass - self.assertEqual(expected1,d1.getValues()) - self.assertEqual(expected2,d2.getValues()) - pass - - def testSwig2Intersect2DMeshesQuadra1(self): - import cmath - def createDiagCircle(lX, lY, R, cells=[0,1]): - """ A circle in a square box, cut along the diagonal. - """ - c = [] - for i in range(8): - c.append(cmath.rect(R, i*pi/4)) - - coords = [0.0,0.0, c[3].real,c[3].imag, -lX/2.0, lY/2.0, - 0.0, lY/2.0, lX/2.0,lY/2.0, lX/2.0,0.0, - # 6 7 8 - lX/2.0,-lY/2.0, c[7].real,c[7].imag, c[1].real,c[1].imag, - # 9 10 11 - c[5].real,c[5].imag, -lX/2.0,-lY/2.0, 0.0, -lY/2.0, - # 12 13 14 - -lX/2.0,0.0, 0.0,0.0, 0.0, 0.0] - # Points 13 (reps. 14) are average of points (6,7) (resp (1,2)) - coords[13*2] = 0.5*(coords[6*2]+coords[7*2]) - coords[13*2+1] = 0.5*(coords[6*2+1]+coords[7*2+1]) - coords[14*2] = 0.5*(coords[1*2]+coords[2*2]) - coords[14*2+1] = 0.5*(coords[1*2+1]+coords[2*2+1]) - connec = [1,7,8,0] # half circle up right - connec3 = [6,7,1,2,4,13,8,14,3,5] - - baseMesh = MEDCouplingUMesh.New("box_circle", 2) - baseMesh.allocateCells(2) - meshCoords = DataArrayDouble.New(coords, len(coords)/2, 2) - meshCoords.setInfoOnComponents(["X [au]", "Y [au]"]) - baseMesh.setCoords(meshCoords) - - if 0 in cells: - baseMesh.insertNextCell(NORM_QPOLYG, connec) - if 1 in cells: - baseMesh.insertNextCell(NORM_QPOLYG, connec3) - baseMesh.finishInsertingCells() - baseMesh.checkCoherency() - return baseMesh - - eps = 1.0e-7 - m1 = createDiagCircle(1.0, 1.0, 0.5*0.90, cells=[0,1]) - m2 = createDiagCircle(1.0, 1.0, 0.5*0.95, cells=[0]) - m3, _, _= MEDCouplingUMesh.Intersect2DMeshes(m1, m2, eps) - m3.mergeNodes(eps) - m3.convertDegeneratedCells() - m3.zipCoords() - m4 = m3.deepCpy() - m5, _, _ = MEDCouplingUMesh.Intersect2DMeshes(m3, m4, eps) - m5.mergeNodes(eps) - # Check coordinates: - self.assertTrue(m3.getCoords().isEqual(m5.getCoords(), eps)) - - def testIntersect2DMeshesTmp7(self): - eps = 1.0e-8 - coords = [-0.5,-0.5, -0.5, 0.5, 0.5, 0.5, 0.5,-0.5] - connec = range(4) - m1 = MEDCouplingUMesh.New("box", 2) - m1.allocateCells(1) - meshCoords = DataArrayDouble.New(coords, len(coords)/2, 2) - m1.setCoords(meshCoords) - m1.insertNextCell(NORM_POLYGON, connec) - m1.finishInsertingCells() - - m2 = MEDCouplingDataForTest.buildCircle(0.25, 0.2, 0.4) - # Was looping indefinitly: - m_intersec, resToM1, resToM2 = MEDCouplingUMesh.Intersect2DMeshes(m1, m2, eps) - m_intersec.zipCoords() - coo_tgt = DataArrayDouble([-0.5, -0.5, -0.5, 0.5, 0.5, 0.5, 0.5, -0.5, -0.03284271247461901, 0.4828427124746191, - -0.014575131106459124, 0.5000000000000001, 0.5, -0.11224989991991996, 0.24271243444677046, 0.5, 0.5, 0.19387505004004, - -0.04799910280454185, -0.06682678787499614, -0.023843325638122054, 0.4915644577163915, 0.5, -0.30612494995996, 0.0, -0.5, - -0.5, 0.0, -0.25728756555322957, 0.5, -0.023843325638122026, 0.49156445771639157, -0.04799910280454181, -0.06682678787499613], 17 ,2) - conn_tgt = [32, 5, 2, 6, 4, 7, 8, 9, 10, 32, 6, 3, 0, 1, 5, 4, 11, 12, 13, 14, 15, 16] - connI_tgt = [0, 9, 22] - res1_tgt = [0, 0] - res2_tgt = [0, -1] - self.assert_(coo_tgt.isEqualWithoutConsideringStr(m_intersec.getCoords(), 1e-12)) - self.assertEqual(conn_tgt, m_intersec.getNodalConnectivity().getValues()) - self.assertEqual(connI_tgt, m_intersec.getNodalConnectivityIndex().getValues()) - self.assertEqual(res1_tgt, resToM1.getValues()) - self.assertEqual(res2_tgt, resToM2.getValues()) - - def testDAIBuildUnique1(self): - d=DataArrayInt([1,2,2,3,3,3,3,4,5,5,7,7,7,19]) - e=d.buildUnique() - self.assertTrue(e.isEqual(DataArrayInt([1,2,3,4,5,7,19]))) - pass - - def testDAIPartitionByDifferentValues1(self): - d=DataArrayInt([1,0,1,2,0,2,2,-3,2]) - expected=[[-3,[7]],[0,[1,4]],[1,[0,2]],[2,[3,5,6,8]]] - for i,elt in enumerate(zip(*d.partitionByDifferentValues())): - self.assertEqual(expected[i][0],elt[1]) - self.assertEqual(expected[i][1],elt[0].getValues()) - pass - pass - - def testFieldGaussMultiDiscPerType1(self): - coords=DataArrayDouble([0.,0.,0.,1.,1.,1.,1.,0.,0.,0.5,0.5,1.,1.,0.5,0.5,0.],8,2) - mQ8=MEDCouplingUMesh("",2) ; mQ8.setCoords(coords) - mQ8.allocateCells(1) - mQ8.insertNextCell(NORM_QUAD8,range(8)) - mQ8.finishInsertingCells() - mQ4=MEDCouplingUMesh("",2) ; mQ4.setCoords(coords) - mQ4.allocateCells(1) - mQ4.insertNextCell(NORM_QUAD4,range(4)) - mQ4.finishInsertingCells() - mT3=MEDCouplingUMesh("",2) ; mT3.setCoords(coords) - mT3.allocateCells(1) - mT3.insertNextCell(NORM_TRI3,range(3)) - mT3.finishInsertingCells() - - tr=[[0.,0.],[2.,0.], [0.,2.],[2.,2.],[4.,2.],[6.,2.],[8.,2.],[10.,2.],[12.,2.],[0.,4.],[2.,4.],[4.,4.],[6.,4.],[8.,4.],[10.,4.],[12.,4.],[14.,4.],[16.,4.],[18.,4.],[20.,4.],[22.,4.]] - ms=2*[mQ4]+7*[mQ8]+11*[mT3] - ms[:]=(elt.deepCpy() for elt in ms) - for m,t in zip(ms,tr): - d=m.getCoords() ; d+= t - pass - m=MEDCouplingUMesh.MergeUMeshes(ms) - f=MEDCouplingFieldDouble.New(ON_GAUSS_PT,NO_TIME) - f.setMesh(m) - # throw because cell 0,1 are QUAD4 and cell 3 is QUAD8 - self.assertRaises(InterpKernelException,f.setGaussLocalizationOnCells,[0,1,3],[0.,0.,1.,0.,1.,1.,0.,1.],[0.3,0.3,0.7,0.7],[0.8,0.2]) - f.setGaussLocalizationOnCells([0,1],[0.,0.,1.,0.,1.,1.,0.,1.],[0.3,0.3,0.7,0.7],[0.8,0.2]) - f.setGaussLocalizationOnCells([3,2,5],[0.,0.,1.,0.,1.,1.,0.,1.,0.5,0.,1.,0.5,0.5,1.,0.,0.5],[0.3,0.3,0.7,0.7,0.9,0.9],[0.8,0.05,0.15]) - f.setGaussLocalizationOnCells([4,6,8,7],[0.,0.,1.,0.,1.,1.,0.,1.,0.5,0.,1.,0.5,0.5,1.,0.,0.5],[0.3,0.3,0.7,0.7,0.9,0.9,-0.1,0.3],[0.7,0.05,0.15,0.1]) - f.setGaussLocalizationOnCells([9,10,11,12,13],[0.,0.,1.,0.,1.,1.],[0.4,0.4],[1.]) - f.setGaussLocalizationOnCells([14,15,16,17,18,19],[0.,0.,1.,0.,1.,1.],[0.4,0.4,0.14,0.16],[0.22,0.78]) - self.assertEqual(46,f.getNumberOfTuplesExpected()) - vals=DataArrayDouble.New(46*3,1) ; vals.iota(7.7) ; vals.rearrange(3) - f.setArray(vals) - f.checkCoherency() - #f.getLocalizationOfDiscr() - self.assertRaises(InterpKernelException,f.getGaussLocalizationIdOfOneType,NORM_QUAD8) #throw because several loc - self.assertEqual([1,2],f.getGaussLocalizationIdsOfOneType(NORM_QUAD8)) - self.assertEqual([0,0,1,1,2,1,2,2,2,3,3,3,3,3,4,4,4,4,4,4],f.getDiscretization().getArrayOfDiscIds().getValues()) - fc=f[[1,2,3,8]] - fc.checkCoherency() - self.assertTrue(DataArrayDouble([13.7,14.7,15.7,16.7,17.7,18.7,19.7,20.7,21.7,22.7,23.7,24.7,25.7,26.7,27.7,28.7,29.7,30.7,31.7,32.7,33.7,34.7,35.7,36.7,82.7,83.7,84.7,85.7,86.7,87.7,88.7,89.7,90.7,91.7,92.7,93.7],12,3).isEqual(fc.getArray(),1e-10)) - fc.renumberCells([3,2,0,1]) - self.assertTrue(DataArrayDouble([28.7, 29.7, 30.7, 31.7, 32.7, 33.7, 34.7, 35.7, 36.7, 82.7, 83.7, 84.7, 85.7, 86.7, 87.7, 88.7, 89.7, 90.7, 91.7, 92.7, 93.7, 19.7, 20.7, 21.7, 22.7, 23.7, 24.7, 25.7, 26.7, 27.7, 13.7, 14.7, 15.7, 16.7, 17.7, 18.7],12,3).isEqual(fc.getArray(),1e-10)) - fc.getArray() - pass - - def testSwigRotate(self): - d=DataArrayDouble([1.,2.,3.,4.,6.,5.],2,3) - MEDCouplingPointSet.Rotate3DAlg([0.,0.,0.],[0.,1.,0.],1.5707963267948966,d) - self.assertTrue(d.isEqual(DataArrayDouble([3.,2.,-1.,5.,6.,-4.],2,3),1e-12)) - d=DataArrayDouble([1.,2.,3.,4.,6.,5.],3,2) - MEDCouplingPointSet.Rotate2DAlg([0.,0.],1.5707963267948966,d) - self.assertTrue(d.isEqual(DataArrayDouble([-2.,1.,-4.,3.,-5.,6.],3,2),1e-12)) - pass - - def testSwigCMeshProtection(self): - cm=MEDCouplingCMesh() - self.assertRaises(InterpKernelException,cm.setCoordsAt,0,DataArrayDouble([4.,4.5,6.,7.],2,2)) - self.assertRaises(InterpKernelException,cm.setCoords,DataArrayDouble([4.,4.5,6.,7.],2,2)) - pass - - def testSwigCellsInBoundingBox1(self): - m3D=MEDCouplingDataForTest.build3DExtrudedUMesh_1()[0] - self.assertTrue(m3D.getCellsInBoundingBox([(0,3),(0,3),(0,1)],-1e-12).isEqual(DataArrayInt([0,1,2,3,4,5]))) - self.assertRaises(InterpKernelException,m3D.getCellsInBoundingBox,[(0,3,0),(3,0,1)],-1e-12) - pass - - def testDAICheckMonotonic1(self): - data1=[-1,0,2,2,4,5] - data2=[6,2,0,-8,-9,-56] - data3=[-1,0,3,2,4,6] - data4=[7,5,2,3,0,-6] - d=DataArrayInt.New(data1); - self.assertTrue(d.isMonotonic(True)); - self.assertTrue(not d.isMonotonic(False)); - d.checkMonotonic(True); - self.assertRaises(InterpKernelException,d.checkMonotonic,False) - d=DataArrayInt.New(data2); - self.assertTrue(d.isMonotonic(False)); - self.assertTrue(not d.isMonotonic(True)); - d.checkMonotonic(False); - self.assertRaises(InterpKernelException,d.checkMonotonic,True) - d=DataArrayInt.New(data3); - self.assertTrue(not d.isMonotonic(False)); - self.assertTrue(not d.isMonotonic(True)); - self.assertRaises(InterpKernelException,d.checkMonotonic,True) - self.assertRaises(InterpKernelException,d.checkMonotonic,False) - d=DataArrayInt.New(data4); - self.assertTrue(not d.isMonotonic(False)); - self.assertTrue(not d.isMonotonic(True)); - self.assertRaises(InterpKernelException,d.checkMonotonic,True) - self.assertRaises(InterpKernelException,d.checkMonotonic,False) - d=DataArrayInt.New(0,1) - self.assertTrue(d.isMonotonic(True)); - self.assertTrue(d.isMonotonic(False)); - d.checkMonotonic(True); - d.checkMonotonic(False); - d=DataArrayInt.New(data4,3,2);#throw because nbComp!=1 - self.assertRaises(InterpKernelException,d.isMonotonic,True) - self.assertRaises(InterpKernelException,d.isMonotonic,False) - self.assertRaises(InterpKernelException,d.checkMonotonic,True) - self.assertRaises(InterpKernelException,d.checkMonotonic,False) - pass - - def testSwigDASetItemOnEmpty1(self): - d=DataArrayInt(0,1) - isThrow=False - try: - d[0:1000:2]=4 - except InterpKernelException as e: - isThrow=True - pass - self.assertTrue(isThrow) - d[:]=4 - d[::2]=5 - # - d=DataArrayDouble(0,1) - isThrow=False - try: - d[0:1000:2]=4 - except InterpKernelException as e: - isThrow=True - pass - self.assertTrue(isThrow) - d[:]=4 - d[::2]=5 - d=DataArrayInt([],0,1) - d2=DataArrayInt(0) - self.assertTrue(d2.isEqual(d)) - d=DataArrayDouble([],0,1) - d2=DataArrayDouble(0) - self.assertTrue(d2.isEqual(d,1e-12)) - pass - - def testSwigDAITransformWithIndArr1(self): - arr=DataArrayInt([0,4,5,1]) - d=DataArrayInt([7,8,9,10]) - self.assertRaises(InterpKernelException,arr.transformWithIndArr,d) - pass - - def testIntersect2DMeshesTmp6(self): - # coordinates - coords=DataArrayDouble.New([2.7554552980815448e-15,45,-45,5.5109105961630896e-15,-31.819805153394636,31.81980515339464,2.8779199779962799e-15,47,2.8166876380389124e-15,46,-47,5.7558399559925599e-15,-33.234018715767732,33.234018715767739,-46,5.6333752760778247e-15],8,2); - # connectivity - conn=DataArrayInt.New([8,0,3,5,1,4,6,7,2]) - connI=DataArrayInt.New([0,9]); - m1=MEDCouplingUMesh.New("Fixe",2); - m1.setCoords(coords); - m1.setConnectivity(conn,connI,True); - # - coords=DataArrayDouble.New([-7.3800475508445391,41.854329503018846,-3.7041190667754655,42.338274668899189,-3.7041190667754655,45.338274668899189,-7.3800475508445382,44.854329503018839,-5.5473631693521845,42.136406608386956,-3.7041190667754655,43.838274668899189,-5.5420833088100014,45.09630208595901,-7.3800475508445382,43.354329503018839,-3.7041190667754651,52.338274668899189,-7.3800475508445382,51.854329503018839,-3.7041190667754655,48.838274668899189,-5.5420833088100014,52.09630208595901,-7.3800475508445382,48.354329503018839],13,2); - # connectivity - conn=DataArrayInt.New([8,0,1,2,3,4,5,6,7,8,3,2,8,9,6,10,11,12]); - connI=DataArrayInt.New([0,9,18]); - # - m2=MEDCouplingUMesh.New("Mobile",2); - m2.setCoords(coords); - m2.setConnectivity(conn,connI,True); - # - m3,d1,d2=MEDCouplingUMesh.Intersect2DMeshes(m1,m2,1e-10); - self.assertTrue(d1.isEqual(DataArrayInt([0,0,0,0]))); - self.assertTrue(d2.isEqual(DataArrayInt([0,1,-1,-1]))); - self.assertEqual(4,m3.getNumberOfCells()); - self.assertEqual(4,d1.getNumberOfTuples()); - self.assertEqual(4,d2.getNumberOfTuples()); - self.assertEqual(43,m3.getNumberOfNodes()); - dI,areMerged,newNbOfNodes=m3.mergeNodes(1e-12) - self.assertEqual(35,m3.getNumberOfNodes()); - m3.zipCoords(); - self.assertEqual(23,m3.getNumberOfNodes()); - # - f=m3.getMeasureField(True); - valuesExpected=DataArrayDouble([1.6603638692585716,5.747555728471923,129.68907101754394,7.4162714498559694]) - self.assertTrue(f.getArray().isEqual(valuesExpected,1e-12)) - pass - - def testDAPushBack(self): - d=DataArrayDouble(0,1) - for i in xrange(8): - d.pushBackSilent(i) - pass - self.assertEqual(d.getNumberOfTuples(),8) - self.assertEqual(d.getNbOfElemAllocated(),8) - d.pushBackSilent(4.44) - self.assertEqual(d.getNumberOfTuples(),9) - self.assertEqual(d.getNbOfElemAllocated(),16) - self.assertTrue(d.isEqual(DataArrayDouble([0.,1.,2.,3.,4.,5.,6.,7.,4.44]),1e-12)) - e=d.deepCpy() - self.assertEqual(e.getNumberOfTuples(),9) - self.assertEqual(e.getNbOfElemAllocated(),9) - self.assertTrue(e.isEqual(DataArrayDouble([0.,1.,2.,3.,4.,5.,6.,7.,4.44]),1e-12)) - self.assertAlmostEqual(d.popBackSilent(),4.44,12) - self.assertEqual(d.getNumberOfTuples(),8) - self.assertEqual(d.getNbOfElemAllocated(),16) - self.assertTrue(d.isEqual(DataArrayDouble([0.,1.,2.,3.,4.,5.,6.,7.]),1e-12)) - f=DataArrayDouble() - f.reserve(1000) - f.pushBackSilent(4.) - self.assertTrue(f.isEqual(DataArrayDouble([4.]),1e-12)) - self.assertEqual(f.getNumberOfTuples(),1) - self.assertEqual(f.getNbOfElemAllocated(),1000) - ff=f[:] - self.assertTrue(ff.isEqual(DataArrayDouble([4.]),1e-12)) - self.assertEqual(ff.getNumberOfTuples(),1) - self.assertEqual(ff.getNbOfElemAllocated(),1) - d=DataArrayDouble() - d.pushBackSilent(4.44) - d.pushBackSilent(5.55) - d.pushBackSilent(6.66) - self.assertTrue(d.isEqual(DataArrayDouble([4.44,5.55,6.66]),1e-12)) - # - d=DataArrayInt(0,1) - for i in xrange(8): - d.pushBackSilent(i) - pass - self.assertEqual(d.getNumberOfTuples(),8) - self.assertEqual(d.getNbOfElemAllocated(),8) - d.pushBackSilent(444) - self.assertEqual(d.getNumberOfTuples(),9) - self.assertEqual(d.getNbOfElemAllocated(),16) - self.assertTrue(d.isEqual(DataArrayInt([0,1,2,3,4,5,6,7,444]))) - e=d.deepCpy() - self.assertEqual(e.getNumberOfTuples(),9) - self.assertEqual(e.getNbOfElemAllocated(),9) - self.assertTrue(e.isEqual(DataArrayInt([0,1,2,3,4,5,6,7,444]))) - self.assertEqual(d.popBackSilent(),444) - self.assertEqual(d.getNumberOfTuples(),8) - self.assertEqual(d.getNbOfElemAllocated(),16) - self.assertTrue(d.isEqual(DataArrayInt([0,1,2,3,4,5,6,7]))) - f=DataArrayInt() - f.reserve(1000) - f.pushBackSilent(4) - self.assertTrue(f.isEqual(DataArrayInt([4]))) - self.assertEqual(f.getNumberOfTuples(),1) - self.assertEqual(f.getNbOfElemAllocated(),1000) - ff=f[:] - self.assertTrue(ff.isEqual(DataArrayInt([4]))) - self.assertEqual(ff.getNumberOfTuples(),1) - self.assertEqual(ff.getNbOfElemAllocated(),1) - d=DataArrayInt() - d.pushBackSilent(444) - d.pushBackSilent(555) - d.pushBackSilent(666) - self.assertTrue(d.isEqual(DataArrayInt([444,555,666]))) - # - d=DataArrayInt() - d.alloc(10,1) - d.setInfoOnComponent(0,"ABC") - d.setName("dEf") - d.iota(7) - e=DataArrayInt([7,8,9,10,11,12,13,14,15,16]) ; e.copyStringInfoFrom(d) ; self.assertTrue(d.isEqual(e)) - self.assertEqual(10,d.getNbOfElemAllocated()) - d.pushBackSilent(55) - e=DataArrayInt([7,8,9,10,11,12,13,14,15,16,55]) ; e.copyStringInfoFrom(d) ; self.assertTrue(d.isEqual(e)) - self.assertEqual(20,d.getNbOfElemAllocated()) - d.reserve(4) - e=DataArrayInt([7,8,9,10]) ; e.copyStringInfoFrom(d) ; self.assertTrue(d.isEqual(e)) - self.assertEqual(4,d.getNbOfElemAllocated()) - d.pushBackSilent(5) - e=DataArrayInt([7,8,9,10,5]) ; e.copyStringInfoFrom(d) ; self.assertTrue(d.isEqual(e)) - self.assertEqual(8,d.getNbOfElemAllocated()) - self.assertEqual(5,d.popBackSilent()) - e=DataArrayInt([7,8,9,10]) ; e.copyStringInfoFrom(d) ; self.assertTrue(d.isEqual(e)) - self.assertEqual(8,d.getNbOfElemAllocated()) - self.assertRaises(OverflowError,d.reserve,-1) - e=DataArrayInt([7,8,9,10]) ; e.copyStringInfoFrom(d) ; self.assertTrue(d.isEqual(e)) - self.assertEqual(8,d.getNbOfElemAllocated()) - d.reserve(0) - e=DataArrayInt([]) ; e.setInfoOnComponent(0,"ABC") ; e.setName("dEf") ; self.assertTrue(d.isEqual(e)) - self.assertEqual(0,d.getNbOfElemAllocated()) - # - d=DataArrayDouble() - d.alloc(10,1) - d.setInfoOnComponent(0,"ABC") - d.setName("dEf") - d.iota(7) - e=DataArrayDouble([7,8,9,10,11,12,13,14,15,16]) ; e.copyStringInfoFrom(d) ; self.assertTrue(d.isEqual(e,1e-14)) - self.assertEqual(10,d.getNbOfElemAllocated()) - d.pushBackSilent(55) - e=DataArrayDouble([7,8,9,10,11,12,13,14,15,16,55]) ; e.copyStringInfoFrom(d) ; self.assertTrue(d.isEqual(e,1e-14)) - self.assertEqual(20,d.getNbOfElemAllocated()) - d.reserve(4) - e=DataArrayDouble([7,8,9,10]) ; e.copyStringInfoFrom(d) ; self.assertTrue(d.isEqual(e,1e-14)) - self.assertEqual(4,d.getNbOfElemAllocated()) - d.pushBackSilent(5) - e=DataArrayDouble([7,8,9,10,5]) ; e.copyStringInfoFrom(d) ; self.assertTrue(d.isEqual(e,1e-14)) - self.assertEqual(8,d.getNbOfElemAllocated()) - self.assertEqual(5.,d.popBackSilent()) - e=DataArrayDouble([7,8,9,10]) ; e.copyStringInfoFrom(d) ; self.assertTrue(d.isEqual(e,1e-14)) - self.assertEqual(8,d.getNbOfElemAllocated()) - self.assertRaises(OverflowError,d.reserve,-1) - e=DataArrayDouble([7,8,9,10]) ; e.copyStringInfoFrom(d) ; self.assertTrue(d.isEqual(e,1e-14)) - self.assertEqual(8,d.getNbOfElemAllocated()) - d.reserve(0) - e=DataArrayDouble([]) ; e.setInfoOnComponent(0,"ABC") ; e.setName("dEf") ; self.assertTrue(d.isEqual(e,1e-14)) - self.assertEqual(0,d.getNbOfElemAllocated()) - pass - - def testDAIBuildSubstractionOptimized1(self): - da1=DataArrayInt.New([1,3,5,6,7,9,13]) - da2=DataArrayInt.New([3,5,9]) - da3=DataArrayInt.New([1,3,5]) - da4=DataArrayInt.New([1,3,5,6,7,9,13]) - # - a=da1.buildSubstractionOptimized(da2); - self.assertTrue(a.isEqual(DataArrayInt([1,6,7,13]))); - # - a=da1.buildSubstractionOptimized(da3); - self.assertTrue(a.isEqual(DataArrayInt([6,7,9,13]))); - # - a=da1.buildSubstractionOptimized(da4); - self.assertTrue(a.isEqual(DataArrayInt([]))); - pass - - def testDAIIsStrictlyMonotonic1(self): - da1=DataArrayInt.New([1,3,5,6,7,9,13]) - self.assertTrue(da1.isStrictlyMonotonic(True)); - da1.checkStrictlyMonotonic(True); - self.assertTrue(da1.isMonotonic(True)); - da1.checkMonotonic(True); - self.assertTrue(not da1.isStrictlyMonotonic(False)); - self.assertRaises(InterpKernelException,da1.checkStrictlyMonotonic,False) - self.assertTrue(not da1.isMonotonic(False)); - self.assertRaises(InterpKernelException,da1.checkMonotonic,False) - # - da1=DataArrayInt.New([1,3,5,6,6,9,13]) - self.assertTrue(not da1.isStrictlyMonotonic(True)); - self.assertRaises(InterpKernelException,da1.checkStrictlyMonotonic,True) - self.assertTrue(da1.isMonotonic(True)); - da1.checkMonotonic(True); - self.assertTrue(not da1.isStrictlyMonotonic(False)); - self.assertRaises(InterpKernelException,da1.checkStrictlyMonotonic,False) - self.assertTrue(not da1.isMonotonic(False)); - self.assertRaises(InterpKernelException,da1.checkMonotonic,False) - # - da1=DataArrayInt.New([1,3,5,6,5,9,13]) - self.assertTrue(not da1.isStrictlyMonotonic(True)); - self.assertRaises(InterpKernelException,da1.checkStrictlyMonotonic,True) - self.assertTrue(not da1.isMonotonic(True)); - self.assertRaises(InterpKernelException,da1.checkMonotonic,True) - self.assertTrue(not da1.isStrictlyMonotonic(False)); - self.assertRaises(InterpKernelException,da1.checkStrictlyMonotonic,False) - self.assertTrue(not da1.isMonotonic(False)); - self.assertRaises(InterpKernelException,da1.checkMonotonic,False) - # - da1=DataArrayInt.New([13,9,7,6,5,3,1]) - self.assertTrue(not da1.isStrictlyMonotonic(True)); - self.assertRaises(InterpKernelException,da1.checkStrictlyMonotonic,True) - self.assertTrue(not da1.isMonotonic(True)); - self.assertRaises(InterpKernelException,da1.checkMonotonic,True) - self.assertTrue(da1.isStrictlyMonotonic(False)); - da1.checkStrictlyMonotonic(False); - self.assertTrue(da1.isMonotonic(False)); - da1.checkMonotonic(False); - # - da1=DataArrayInt.New([13,9,6,6,5,3,1]) - self.assertTrue(not da1.isStrictlyMonotonic(True)); - self.assertRaises(InterpKernelException,da1.checkStrictlyMonotonic,True) - self.assertTrue(not da1.isMonotonic(True)); - self.assertRaises(InterpKernelException,da1.checkMonotonic,True) - self.assertTrue(not da1.isStrictlyMonotonic(False)); - self.assertRaises(InterpKernelException,da1.checkStrictlyMonotonic,False) - self.assertTrue(da1.isMonotonic(False)); - da1.checkMonotonic(False); - # - da1=DataArrayInt.New([13,9,5,6,5,3,1]) - self.assertTrue(not da1.isStrictlyMonotonic(True)); - self.assertRaises(InterpKernelException,da1.checkStrictlyMonotonic,True) - self.assertTrue(not da1.isMonotonic(True)); - self.assertRaises(InterpKernelException,da1.checkMonotonic,True) - self.assertTrue(not da1.isStrictlyMonotonic(False)); - self.assertRaises(InterpKernelException,da1.checkStrictlyMonotonic,False) - self.assertTrue(not da1.isMonotonic(False)); - self.assertRaises(InterpKernelException,da1.checkMonotonic,False) - # - da1=DataArrayInt.New([]) - self.assertTrue(da1.isStrictlyMonotonic(True)); - da1.checkStrictlyMonotonic(True); - self.assertTrue(da1.isMonotonic(True)); - da1.checkMonotonic(True); - self.assertTrue(da1.isStrictlyMonotonic(False)); - da1.checkStrictlyMonotonic(False); - self.assertTrue(da1.isMonotonic(False)); - da1.checkMonotonic(False); - # - da1=DataArrayInt.New([13]) - self.assertTrue(da1.isStrictlyMonotonic(True)); - da1.checkStrictlyMonotonic(True); - self.assertTrue(da1.isMonotonic(True)); - da1.checkMonotonic(True); - self.assertTrue(da1.isStrictlyMonotonic(False)); - da1.checkStrictlyMonotonic(False); - self.assertTrue(da1.isMonotonic(False)); - da1.checkMonotonic(False); - pass - - def testFindAndCorrectBadOriented3DCells1(self): - nbOfDisc=20 - vects=([0,0,-1],[0.3,0.7,0.2],[-0.3,0.7,0.2],[-0.3,-0.7,0.2]) - # - m0=MEDCouplingUMesh("m",3) ; m0.allocateCells(0); m0.insertNextCell(NORM_TETRA4,[0,1,2,3]); #Well oriented - m1=MEDCouplingUMesh("m",3) ; m1.allocateCells(0); m1.insertNextCell(NORM_PYRA5,[0,1,2,3,4]); #Well oriented - m2=MEDCouplingUMesh("m",3) ; m2.allocateCells(0); m2.insertNextCell(NORM_PENTA6,[0,1,2,3,4,5]); #Well oriented - m3=MEDCouplingUMesh("m",3) ; m3.allocateCells(0); m3.insertNextCell(NORM_HEXA8,[0,1,2,3,4,5,6,7]); #Well oriented - m4=MEDCouplingUMesh("m",3) ; m4.allocateCells(0) - self.assertRaises(InterpKernelException,m4.insertNextCell,NORM_HEXGP12,[0,1,2,3,4,5,6,7,8,9,10,11,12]); - m4.insertNextCell(NORM_HEXGP12,[0,1,2,3,4,5,6,7,8,9,10,11]); #Well oriented - c0=DataArrayDouble([0.,0.,0.,0.,1.,0.,1.,0.,0.,0.,0.,1.],4,3) ; m0.setCoords(c0) - c1=DataArrayDouble([0.,0.,0.,0.,1.,0.,1.,1.,0.,1.,0.,0.,0.,0.,1.],5,3) ; m1.setCoords(c1) - c2=DataArrayDouble([0.,0.,0.,0.,1.,0.,1.,0.,0., 0.,0.,1.,0.,1.,1.,1.,0.,1.],6,3) ; m2.setCoords(c2) - c3=DataArrayDouble([0.,0.,0.,0.,1.,0.,1.,1.,0.,1.,0.,0.,0.,0.,1.,0.,1.,1.,1.,1.,1.,1.,0.,1.],8,3) ; m3.setCoords(c3) - c4=DataArrayDouble([0.,0.,0.,0.,1.,0.,1.,1.,0.,1.,0.,0.,0.8,0.,0.,0.45,0.,0., 0.,0.,1.,0.,1.,1.,1.,1.,1.,1.,0.,1.,0.8,0.,1.,0.45,0.,1.],12,3) ; m4.setCoords(c4) - m=MEDCouplingMesh.MergeMeshes([m0,m1,m2,m3,m4]) - expected1=DataArrayDouble([0.16666666666666666,0.3333333333333333,0.5,1.,1.]) - for v in vects: - for i in xrange(nbOfDisc): - mm=m.deepCpy() - mm.rotate([0.,0.,0.],[0.3,0.7,0.2],float(i)/float(nbOfDisc)*2*pi) - mm2=mm.deepCpy() - self.assertTrue(mm.getMeasureField(False).getArray().isEqual(expected1,1e-14)) - self.assertTrue(mm.findAndCorrectBadOriented3DCells().empty()) - self.assertTrue(mm.isEqual(mm2,1e-14)) - self.assertTrue(mm.getMeasureField(False).getArray().isEqual(expected1,1e-14)) - mm.convertAllToPoly() - self.assertTrue(mm.getMeasureField(False).getArray().isEqual(expected1,1e-14)) - pass - pass - # - mOK=m.deepCpy() - m0=MEDCouplingUMesh("m",3) ; m0.allocateCells(0); m0.insertNextCell(NORM_TETRA4,[0,2,1,3]); #Not well oriented - m1=MEDCouplingUMesh("m",3) ; m1.allocateCells(0); m1.insertNextCell(NORM_PYRA5,[0,1,2,3,4]); #Well oriented - m2=MEDCouplingUMesh("m",3) ; m2.allocateCells(0); m2.insertNextCell(NORM_PENTA6,[0,1,2,3,4,5]); #Well oriented - m3=MEDCouplingUMesh("m",3) ; m3.allocateCells(0); m3.insertNextCell(NORM_HEXA8,[0,3,2,1,4,7,6,5]); #Not well oriented - m4=MEDCouplingUMesh("m",3) ; m4.allocateCells(0); m4.insertNextCell(NORM_HEXGP12,[0,5,4,3,2,1,6,11,10,9,8,7]); #Not well oriented - m0.setCoords(c0) ; m1.setCoords(c1) ; m2.setCoords(c2) ; m3.setCoords(c3) ; m4.setCoords(c4) - m=MEDCouplingMesh.MergeMeshes([m0,m1,m2,m3,m4]) - expected2=DataArrayDouble([-0.16666666666666666,0.3333333333333333,0.5,-1.,-1.]) - for v in vects: - for i in xrange(nbOfDisc): - mm=m.deepCpy() - mm.rotate([0.,0.,0.],[0.3,0.7,0.2],float(i)/float(nbOfDisc)*2*pi) - mm2=mm.deepCpy() ; mm3=mm.deepCpy() ; mm3.convertAllToPoly() - self.assertTrue(mm3.getMeasureField(False).getArray().isEqual(expected2,1e-14)) - self.assertTrue(mm.getMeasureField(False).getArray().isEqual(expected2,1e-14)) - self.assertTrue(mm.findAndCorrectBadOriented3DCells().isEqual(DataArrayInt([0,3,4]))) - mOK.setCoords(mm.getCoords()) - self.assertTrue(mm.isEqual(mOK,1e-14)) - self.assertTrue(mm.getMeasureField(False).getArray().isEqual(expected1,1e-14)) - mmm=mm.deepCpy() - self.assertTrue(mmm.findAndCorrectBadOriented3DCells().empty()) - mm.convertAllToPoly() - self.assertTrue(mm.getMeasureField(False).getArray().isEqual(expected1,1e-14)) - pass - pass - # - m0=MEDCouplingUMesh("m",3) ; m0.allocateCells(0); m0.insertNextCell(NORM_TETRA4,[0,1,2,3]); #Well oriented - m1=MEDCouplingUMesh("m",3) ; m1.allocateCells(0); m1.insertNextCell(NORM_PYRA5,[0,3,2,1,4]); #Not well oriented - m2=MEDCouplingUMesh("m",3) ; m2.allocateCells(0); m2.insertNextCell(NORM_PENTA6,[0,2,1,3,5,4]); #Not well oriented - m3=MEDCouplingUMesh("m",3) ; m3.allocateCells(0); m3.insertNextCell(NORM_HEXA8,[0,1,2,3,4,5,6,7]); #Well oriented - m4=MEDCouplingUMesh("m",3) ; m4.allocateCells(0); m4.insertNextCell(NORM_HEXGP12,range(12)); #Well oriented - m0.setCoords(c0) ; m1.setCoords(c1) ; m2.setCoords(c2) ; m3.setCoords(c3) ; m4.setCoords(c4) - m=MEDCouplingMesh.MergeMeshes([m0,m1,m2,m3,m4]) - expected3=DataArrayDouble([0.16666666666666666,-0.3333333333333333,-0.5,1.,1.]) - for v in vects: - for i in xrange(nbOfDisc): - mm=m.deepCpy() - mm.rotate([0.,0.,0.],[0.3,0.7,0.2],float(i)/float(nbOfDisc)*2*pi) - mm2=mm.deepCpy() ; mm3=mm.deepCpy() ; mm3.convertAllToPoly() - self.assertTrue(mm3.getMeasureField(False).getArray().isEqual(expected3,1e-14)) - self.assertTrue(mm.getMeasureField(False).getArray().isEqual(expected3,1e-14)) - self.assertTrue(mm.findAndCorrectBadOriented3DCells().isEqual(DataArrayInt([1,2]))) - mOK.setCoords(mm.getCoords()) - self.assertTrue(mm.isEqual(mOK,1e-14)) - self.assertTrue(mm.getMeasureField(False).getArray().isEqual(expected1,1e-14)) - mmm=mm.deepCpy() - self.assertTrue(mmm.findAndCorrectBadOriented3DCells().empty()) - mm.convertAllToPoly() - self.assertTrue(mm.getMeasureField(False).getArray().isEqual(expected1,1e-14)) - pass - pass - pass - - def testSwig2CellOrientation1(self): - coords=DataArrayDouble([-0.21606,-0.10803,0.29999999999999999,-0.21606,-0.10803,0.37700000000000006,0,-0.10803,0.29999999999999999,0,-0.10803,0.37700000000000006,0,0.10803,0.29999999999999999,0,0.10803,0.37700000000000006,-0.21606,0.10803,0.29999999999999999,-0.21606,0.10803,0.37700000000000006,0,0.03601,0.29999999999999999,0,0.03601,0.37700000000000006,0,-0.03601,0.29999999999999999,0,-0.03601,0.37700000000000006],12,3) - conn=[[0,2,10,8,4,6],[1,3,11,9,5,7],[0,1,3,2],[2,3,11,10],[10,11,9,8],[8,9,5,4],[4,5,7,6],[6,7,1,0]] - for i in xrange(256): - mesh=MEDCouplingUMesh("FluidMesh_1",3); - mesh.allocateCells(0) - conn2=[elt[:] for elt in conn] - code=bin(i)[2:] ; code='0'*(8-len(code))+code - for face,rev in zip(conn2,code): - if bool(int(rev)): - face.reverse() - pass - pass - conn3=[elt+[-1] for elt in conn2] - conn3=sum(conn3,[])[:-1] - mesh.insertNextCell(NORM_POLYHED,conn3) - mesh.setCoords(coords) - mesh.orientCorrectlyPolyhedrons() - self.assertTrue(mesh.getBarycenterAndOwner().isEqual(DataArrayDouble([-0.10803,0.,0.3385],1,3),1e-12)) - pass - pass - - def testSwig2CheckConsecutiveCellTypesForMEDFileFrmt1(self): - m1=MEDCouplingUMesh("",2) ; m1.allocateCells(0) - m1.insertNextCell(NORM_QUAD4,[0,1,2,3]) - m1.insertNextCell(NORM_TRI3,[0,1,2]) - d=DataArrayDouble(4,3) ; d[:]=0. - m1.setCoords(d) - self.assertTrue(m1.checkConsecutiveCellTypes()) - self.assertTrue(not m1.checkConsecutiveCellTypesForMEDFileFrmt()) - m1.renumberCells([1,0]) - self.assertTrue(m1.checkConsecutiveCellTypes()) - self.assertTrue(m1.checkConsecutiveCellTypesForMEDFileFrmt()) - pass - - def testSwig2DAAccumulate1(self): - d=DataArrayInt(10) ; d.iota(0) - self.assertEqual([45],d.accumulate()) - self.assertEqual(45,d.accumulate(0)) - d=DataArrayInt(30) ; d.iota(0) ; d.rearrange(3) - self.assertEqual([135,145,155],d.accumulate()) - self.assertEqual(135,d.accumulate(0)) - self.assertEqual(145,d.accumulate(1)) - self.assertEqual(155,d.accumulate(2)) - d=DataArrayDouble(10) ; d.iota(0.) - self.assertEqual([45.],d.accumulate()) - self.assertEqual(45.,d.accumulate(0)) - d=DataArrayDouble(30) ; d.iota(0) ; d.rearrange(3) - self.assertEqual([135.,145.,155.],d.accumulate()) - self.assertEqual(135.,d.accumulate(0)) - self.assertEqual(145.,d.accumulate(1)) - self.assertEqual(155.,d.accumulate(2)) - pass - - def testSwig2UMeshDistanceToMesh1(self): - m=MEDCouplingUMesh("toto",2) - coords=DataArrayDouble([2.3,3.4,5.6,6.5,-4.3,3.2,-9.8,7.6,-5.4],3,3) - m.setCoords(coords) - m.allocateCells(0) - m.insertNextCell(NORM_TRI3,[0,1,2]) - a,b=m.distanceToPoint([-0.335,2.27,1.21]) - self.assertEqual(0,b) - self.assertAlmostEqual(0.022360988100374124,a,14); - a,b=m.distanceToPoint(DataArrayDouble([-0.335,2.27,1.21],1,3)) - self.assertEqual(0,b) - self.assertAlmostEqual(0.022360988100374124,a,14); - a,b=coords.distanceToTuple([-0.335,2.27,1.21]) - self.assertAlmostEqual(5.243302871282566,a,14) - self.assertEqual(0,b) - # - m=MEDCouplingUMesh("toto",2) - coords=DataArrayDouble([0.,0.,0., 8.,0.,0., 8.,8.,0., 0.,8.,0.],4,3) - m.setCoords(coords) - m.allocateCells(0) - m.insertNextCell(NORM_QUAD4,[0,1,2,3]) - m.checkCoherency2() - self.assertEqual([4,0,1,2,3],m.getNodalConnectivity().getValues()) - a,b=m.distanceToPoint([5.,2.,0.1]) - self.assertAlmostEqual(0.1,a,14) ; self.assertEqual(0,b) - a,b=m.distanceToPoint([5.,-2.,4.]) - self.assertAlmostEqual(sqrt(2*2+4*4),a,14) ; self.assertEqual(0,b) - m.allocateCells(0) - m.insertNextCell(NORM_POLYGON,[0,1,2,3]) - m.checkCoherency2() - self.assertEqual([5,0,1,2,3],m.getNodalConnectivity().getValues()) - a,b=m.distanceToPoint([11.,3.,4.]) - self.assertAlmostEqual(sqrt(3*3+4*4),a,14) ; self.assertEqual(0,b) - a,b=m.distanceToPoint([4.,12.,5.]) - self.assertAlmostEqual(sqrt(4*4+5*5),a,14) ; self.assertEqual(0,b) - d=DataArrayDouble([-1.2,3.,2.],1,3) - for elt in d: - a,b=m.distanceToPoint(d) - self.assertAlmostEqual(sqrt(1.2*1.2+2*2),a,14) ; self.assertEqual(0,b) - pass - # - m=MEDCouplingUMesh("toto",1) - coords=DataArrayDouble([0.,0.,4.,0.,0.,4.],3,2) ; m.setCoords(coords) - m.allocateCells(0) ; m.insertNextCell(NORM_SEG2,[0,1]) ; m.insertNextCell(NORM_SEG2,[1,2]) - a,b=m.distanceToPoint([-0.1,4.1]) - self.assertAlmostEqual(0.14142135623730925,a,14) # b==1 self.assertEqual(2,c) - a,b=m.distanceToPoint([0.,3.9]) - self.assertAlmostEqual(0.07071067811865482,a,14) ; self.assertEqual(1,b) # self.assertEqual(2,c) - pass - - def testSwig2NonRegressionPartitionBySpreadZone1(self): - m=MEDCouplingCMesh() - arr=DataArrayDouble(6) ; arr.iota(0.) - m.setCoords(arr,arr,arr) - m=m.buildUnstructured() - mPart=m[50,80,85,87,92,122] - zones=mPart.partitionBySpreadZone() - self.assertEqual(4,len(zones)) - self.assertTrue(zones[0].isEqual(DataArrayInt([0]))) - self.assertTrue(zones[1].isEqual(DataArrayInt([1,2]))) - self.assertTrue(zones[2].isEqual(DataArrayInt([3,4]))) - self.assertTrue(zones[3].isEqual(DataArrayInt([5]))) - # - n,ni=m.computeNeighborsOfCells() - a,b=MEDCouplingUMesh.ComputeSpreadZoneGraduallyFromSeed(0,n,ni) - self.assertEqual(13,b) ; self.assertEqual(125,len(a)) ; self.assertTrue(a.isIdentity()) - a,b=MEDCouplingUMesh.ComputeSpreadZoneGraduallyFromSeed([1],n,ni) - self.assertEqual(12,b) ; self.assertEqual(125,len(a)) ; self.assertTrue(a.isIdentity()) - a,b=MEDCouplingUMesh.ComputeSpreadZoneGraduallyFromSeed((2,),n,ni) - self.assertEqual(11,b) ; self.assertEqual(125,len(a)) ; self.assertTrue(a.isIdentity()) - a,b=MEDCouplingUMesh.ComputeSpreadZoneGraduallyFromSeed(DataArrayInt([3]),n,ni) - self.assertEqual(12,b) ; self.assertEqual(125,len(a)) ; self.assertTrue(a.isIdentity()) - pass - - def testSwigUMeshInsertNextCell1(self): - m=MEDCouplingUMesh("toto",2) - # - coords=DataArrayDouble([0.,0.,1.,1.,1.,0.]) ; m.setCoords(coords) - da=DataArrayInt([0,1,2]) - m.allocateCells(0) - for i in xrange(5): - m.insertNextCell(NORM_TRI3,da) - pass - self.assertTrue(m.getNodalConnectivity().isEqual(DataArrayInt([3,0,1,2,3,0,1,2,3,0,1,2,3,0,1,2,3,0,1,2]))) - self.assertTrue(m.getNodalConnectivityIndex().isEqual(DataArrayInt([0,4,8,12,16,20]))) - # - da=DataArrayInt([0,1,2,3]) - m.allocateCells(0) - for i in xrange(5): - m.insertNextCell(NORM_TRI3,3,da) - pass - self.assertTrue(m.getNodalConnectivity().isEqual(DataArrayInt([3,0,1,2,3,0,1,2,3,0,1,2,3,0,1,2,3,0,1,2]))) - self.assertTrue(m.getNodalConnectivityIndex().isEqual(DataArrayInt([0,4,8,12,16,20]))) - # - da=DataArrayInt([0,1]) - m.allocateCells(0) - self.assertRaises(InterpKernelException,m.insertNextCell,NORM_TRI3,3,da) - # - da=DataArrayInt([0,1,2,0,1,3,0,1,4,0,1,5,0,1,6],5,3) - m.allocateCells(0) - for t in da: - m.insertNextCell(NORM_TRI3,t) - pass - self.assertTrue(m.getNodalConnectivity().isEqual(DataArrayInt([3,0,1,2,3,0,1,3,3,0,1,4,3,0,1,5,3,0,1,6]))) - self.assertTrue(m.getNodalConnectivityIndex().isEqual(DataArrayInt([0,4,8,12,16,20]))) - self.assertRaises(InterpKernelException,m.insertNextCell,NORM_TRI3,None) - pass - - def testSwigCurveLinearMesh1(self): - m=MEDCouplingCurveLinearMesh("toto") - m.setNodeGridStructure([2,3]) - coords=DataArrayDouble([0.,0., 2.,0., 0.,1., 1.9,1.1, 0.3,1.9, 2.2,2.1],6,2) - m.setCoords(coords) - m.checkCoherency() - m0=m.deepCpy() - self.assertTrue(m0.isEqual(m,1e-12)) - m.getCoords().setInfoOnComponents(["X [m]","Y [m]"]) - self.assertTrue(not m0.isEqual(m,1e-12)) - m0=m.deepCpy() - self.assertTrue(m0.isEqual(m,1e-12)) - self.assertEqual(m.getNodeGridStructure(),(2,3)) - pass - - def testSimplexize3(self): - m=MEDCouplingUMesh("toto",3) - m.allocateCells(0) - m.insertNextCell(NORM_TETRA4,[0,1,2,3]) - self.assertEqual([NORM_TETRA4],m.getAllGeoTypesSorted()) - m.insertNextCell(NORM_HEXA8,[4,5,6,7,8,9,10,11]) - self.assertEqual([NORM_TETRA4,NORM_HEXA8],m.getAllGeoTypesSorted()) - m.insertNextCell(NORM_HEXA8,[12,13,14,15,16,17,18,19]) - self.assertEqual([NORM_TETRA4,NORM_HEXA8],m.getAllGeoTypesSorted()) - m.insertNextCell(NORM_TETRA4,[20,21,22,23]) - self.assertEqual([NORM_TETRA4,NORM_HEXA8,NORM_TETRA4],m.getAllGeoTypesSorted()) - c1=DataArrayDouble([0.,0.,0.,0.,1.,0.,1.,0.,0.,0.,0.,1.],4,3) - c2=DataArrayDouble([0.,0.,0.,0.,1.,0.,1.,1.,0.,1.,0.,0., 0.,0.,1.,0.,1.,1.,1.,1.,1.,1.,0.,1.],8,3) ; c2+=[2.,0.,0.] - c3=c2+[2.,0.,0.] - c4=c1+[6.,0.,0.] - c=DataArrayDouble.Aggregate([c1,c2,c3,c4]) - m.setCoords(c) - m.checkCoherency2() - # - m1=m.deepCpy() - d1=m1.simplexize(PLANAR_FACE_5) - m1.checkCoherency2() - vol1=m1.getMeasureField(ON_CELLS).getArray() - self.assertTrue(vol1.isEqual(DataArrayDouble([1./6, 1./6, 1./6,1./6, 1./6, 1./3,1./6, 1./6, 1./6, 1./6, 1./3, 1./6]),1e-12)) - self.assertEqual(m1.getNodalConnectivity().getValues(),[14,0,1,2,3,14,4,9,5,6,14,4,8,9,11,14,4,7,11,6,14,9,11,10,6,14,4,9,6,11,14,12,17,13,14,14,12,16,17,19,14,12,15,19,14,14,17,19,18,14,14,12,17,14,19,14,20,21,22,23]) - self.assertEqual(m1.getNodalConnectivityIndex().getValues(),[0,5,10,15,20,25,30,35,40,45,50,55,60]) - self.assertTrue(d1.isEqual(DataArrayInt([0,1,1,1,1,1,2,2,2,2,2,3]))) - # - m2=m.deepCpy() - d2=m2.simplexize(PLANAR_FACE_6) - m2.checkCoherency2() - vol2=m2.getMeasureField(ON_CELLS).getArray() - self.assertTrue(vol2.isEqual(DataArrayDouble([1./6, 1./6, 1./6,1./6, 1./6, 1./6,1./6,1./6, 1./6, 1./6, 1./6, 1./6,1./6,1./6]),1e-12)) - self.assertEqual(m2.getNodalConnectivity().getValues(),[14,0,1,2,3,14,4,9,5,10,14,4,5,6,10,14,4,8,9,10,14,4,11,8,10,14,4,6,7,10,14,4,7,11,10,14,12,17,13,18,14,12,13,14,18,14,12,16,17,18,14,12,19,16,18,14,12,14,15,18,14,12,15,19,18,14,20,21,22,23]) - self.assertEqual(m2.getNodalConnectivityIndex().getValues(),[0,5,10,15,20,25,30,35,40,45,50,55,60,65,70]) - self.assertTrue(d2.isEqual(DataArrayInt([0,1,1,1,1,1,1,2,2,2,2,2,2,3]))) - pass - - def testSwig2CurveLinearMesh2(self): - c=MEDCouplingCMesh() - #2D - arr1=DataArrayDouble([0,1,3,7]) - arr2=DataArrayDouble([0,1,1.5]) - c.setCoords(arr1,arr2) - u=c.buildUnstructured() - coo=u.getCoords() - cl=MEDCouplingCurveLinearMesh() - cl.setCoords(coo) - cl.setNodeGridStructure([4,3]) - cl.checkCoherency2() - li1=[1.,2.,4.,0.5,1.,2.] - self.assertTrue(cl.getMeasureField(False).getArray().isEqual(DataArrayDouble(li1),1e-14)) - self.assertTrue(u.getMeasureField(False).getArray().isEqual(DataArrayDouble(li1),1e-14)) - li1_1=[0.5,0.5,2.,0.5,5.,0.5,0.5,1.25,2.,1.25,5.,1.25] - self.assertTrue(cl.getBarycenterAndOwner().isEqual(DataArrayDouble(li1_1,6,2),1e-14)) - self.assertTrue(u.getBarycenterAndOwner().isEqual(DataArrayDouble(li1_1,6,2),1e-14)) - #3D - c.setCoords(arr1,arr2,arr2) - u=c.buildUnstructured() - coo=u.getCoords() - cl=MEDCouplingCurveLinearMesh() - cl.setCoords(coo) - cl.setNodeGridStructure([4,3,3]) - cl.checkCoherency2() - li2=[1.,2.,4.,0.5, 1.,2.,0.5,1.,2.,0.25,0.5,1.] - li2_1=[0.5,0.5,0.5,2.,0.5,0.5,5.,0.5,0.5,0.5,1.25,0.5,2.,1.25,0.5,5.,1.25,0.5,0.5,0.5,1.25,2.,0.5,1.25,5.,0.5,1.25,0.5,1.25,1.25,2.,1.25,1.25,5.,1.25,1.25] - self.assertTrue(cl.getMeasureField(False).getArray().isEqual(DataArrayDouble(li2),1e-14)) - self.assertTrue(u.getMeasureField(False).getArray().isEqual(DataArrayDouble(li2),1e-14)) - self.assertTrue(cl.getBarycenterAndOwner().isEqual(DataArrayDouble(li2_1,12,3),1e-14)) - self.assertTrue(u.getBarycenterAndOwner().isEqual(DataArrayDouble(li2_1,12,3),1e-14)) - #1D spaceDim 1 - coo=DataArrayDouble(5) ; coo.iota(0.) - coo=coo*coo - cl.setCoords(coo) - cl.setNodeGridStructure([5]) - cl.checkCoherency2() - li3=[1.,3.,5.,7.] - li3_1=[0.5,2.5,6.5,12.5] - self.assertTrue(cl.getMeasureField(False).getArray().isEqual(DataArrayDouble(li3),1e-14)) - self.assertTrue(cl.buildUnstructured().getMeasureField(False).getArray().isEqual(DataArrayDouble(li3),1e-14)) - self.assertTrue(cl.getBarycenterAndOwner().isEqual(DataArrayDouble(li3_1),1e-14)) - self.assertTrue(cl.buildUnstructured().getBarycenterAndOwner().isEqual(DataArrayDouble(li3_1),1e-14)) - #1D spaceDim 2 - coo=DataArrayDouble.Meld(coo,coo) - cl.setCoords(coo) - cl.checkCoherency2() - li4=[sqrt(2.)*elt for elt in [1.,3.,5.,7.]] - li4_1=[0.5,0.5,2.5,2.5,6.5,6.5,12.5,12.5] - self.assertEqual(2,cl.getSpaceDimension()) - self.assertEqual(1,cl.getMeshDimension()) - self.assertEqual(4,cl.getNumberOfCells()) - self.assertEqual(5,cl.getNumberOfNodes()) - self.assertTrue(cl.getMeasureField(False).getArray().isEqual(DataArrayDouble(li4),1e-14)) - self.assertTrue(cl.buildUnstructured().getMeasureField(False).getArray().isEqual(DataArrayDouble(li4),1e-14)) - self.assertTrue(cl.getBarycenterAndOwner().isEqual(DataArrayDouble(li4_1,4,2),1e-14)) - self.assertTrue(cl.buildUnstructured().getBarycenterAndOwner().isEqual(DataArrayDouble(li4_1,4,2),1e-14)) - pass - - def testSwig2CurveLinearMeshNonRegression1(self): - coords=DataArrayDouble([0.0, 0.0, 0.10000000149011612, 0.6000000238418579, 0.10000000149011612, 0.30000001192092896, 1.100000023841858, 0.10000000149011612, 0.20000000298023224, 0.10000000149011612, 0.6000000238418579, 0.20000000298023224, 0.699999988079071, 0.6000000238418579, 0.10000000149011612, 1.2000000476837158, 0.6000000238418579, 0.30000001192092896, 0.10000000149011612, 1.100000023841858, 0.30000001192092896, 0.5, 1.100000023841858, 0.20000000298023224, 1.0, 1.2000000476837158, 0.10000000149011612, 0.0, 0.10000000149011612, 0.5, 0.5, 0.10000000149011612, 0.6000000238418579, 1.2000000476837158, 0.10000000149011612, 0.699999988079071, 0.10000000149011612, 0.6000000238418579, 0.699999988079071, 0.6000000238418579, 0.6000000238418579, 0.5, 1.100000023841858, 0.6000000238418579, 0.6000000238418579, 0.10000000149011612, 1.0, 0.6000000238418579, 0.699999988079071, 1.2000000476837158, 0.699999988079071, 0.8999999761581421, 1.0, 0.5, 0.10000000149011612, 0.10000000149011612, 1.2000000476837158, 0.699999988079071, 0.10000000149011612, 1.0, 1.0, 0.10000000149011612, 1.100000023841858, 0.10000000149011612, 0.6000000238418579, 1.100000023841858, 0.6000000238418579, 0.6000000238418579, 1.100000023841858, 1.100000023841858, 0.6000000238418579, 1.2000000476837158, 0.10000000149011612, 1.2000000476837158, 1.0, 0.5, 1.100000023841858, 1.2000000476837158, 1.2000000476837158, 1.100000023841858, 1.0],27,3) - m=MEDCouplingCurveLinearMesh("toto") - m.setCoords(coords) - m.setNodeGridStructure([3,3,3]) - # - vol=m.getMeasureField(False).getArray() - self.assertTrue(vol.isEqual(DataArrayDouble([0.11450000709295281, 0.10583334351579375,0.11149999939029423,0.08866666863113633, 0.1404166805123294,0.1250000135352219,0.1270833433481557,0.13258334288001067]),1e-12)) - self.assertTrue(vol.isEqual(m.buildUnstructured().getMeasureField(False).getArray(),1e-12)) - # - self.assertTrue(m.getBarycenterAndOwner().isEqual(m.buildUnstructured().getBarycenterAndOwner(),1e-12)) - pass - - def testSwig2NonRegressionDASetSelectedComponents1(self): - da=DataArrayDouble.New([1.,2.,3.,4.,5.,6.],3,2) - dv=DataArrayDouble.New(); - dv.alloc(4,4) - dv.fillWithZero() - # da has less tuples than dv - dv.setSelectedComponents(da,[1,0]) - # - self.assertTrue(dv.isEqual(DataArrayDouble([2.,1.,0.,0.,4.,3.,0.,0.,6.,5.,0.,0.,0.,0.,0.,0.],4,4),1e-14)) - # - da=DataArrayInt.New([1,2,3,4,5,6],3,2) - dv=DataArrayInt.New(); - dv.alloc(4,4) - dv.fillWithZero() - # da has less tuples than dv - dv.setSelectedComponents(da,[1,0]) - # - self.assertTrue(dv.isEqual(DataArrayInt([2,1,0,0,4,3,0,0,6,5,0,0,0,0,0,0],4,4))) - pass - - def testSwigSetItem3(self): - # 1-2 - d=DataArrayDouble([0,0,0,0,0,0,0,0,0,0,0,0],6,2) - d[3]=[1,2] - self.assertTrue(d.isEqual(DataArrayDouble([0,0,0,0,0,0,1,2,0,0,0,0],6,2),1e-14)) - # 2-2 false - d=DataArrayDouble([0,0,0,0,0,0,0,0,0,0,0,0],6,2) - d[[5,3,2]]=[1,2] - self.assertTrue(d.isEqual(DataArrayDouble([0,0,0,0,1,2,1,2,0,0,1,2],6,2),1e-14)) - # 3-2 false - d=DataArrayDouble([0,0,0,0,0,0,0,0,0,0,0,0],6,2) - d[:]=[1,2] - self.assertTrue(d.isEqual(DataArrayDouble([1,2,1,2,1,2,1,2,1,2,1,2],6,2),1e-14)) - # 4-2 false - d=DataArrayDouble([0,0,0,0,0,0,0,0,0,0,0,0],6,2) - d[DataArrayInt([0,3,4])]=[1,2] - self.assertTrue(d.isEqual(DataArrayDouble([1,2,0,0,0,0,1,2,1,2,0,0],6,2),1e-14)) - # 5-2 - d=DataArrayDouble([0,0,0,0,0,0,0,0,0,0,0,0],6,2) - d[5,1]=[7] - self.assertTrue(d.isEqual(DataArrayDouble([0,0,0,0,0,0,0,0,0,0,0,7],6,2),1e-14)) - # 6-2 false - d=DataArrayDouble([0,0,0,0,0,0,0,0,0,0,0,0],6,2) - d[[3,5],1]=[7] - self.assertTrue(d.isEqual(DataArrayDouble([0,0,0,0,0,0,0,7,0,0,0,7],6,2),1e-14)) - # 7-2 false - d=DataArrayDouble([0,0,0,0,0,0,0,0,0,0,0,0],6,2) - d[:-1:2,1]=[7] - self.assertTrue(d.isEqual(DataArrayDouble([0,7,0,0,0,7,0,0,0,7,0,0],6,2),1e-14)) - # 8-2 false - d=DataArrayDouble([0,0,0,0,0,0,0,0,0,0,0,0],6,2) - d[DataArrayInt([0,3,4]),1]=[7] - self.assertTrue(d.isEqual(DataArrayDouble([0,7,0,0,0,0,0,7,0,7,0,0],6,2),1e-14)) - # 9-2 - d=DataArrayDouble([0,0,0,0,0,0,0,0,0,0,0,0],6,2) - d[3,[1,0]]=[7,8] - self.assertTrue(d.isEqual(DataArrayDouble([0,0,0,0,0,0,8,7,0,0,0,0],6,2),1e-14)) - # 10-2 false - d=DataArrayDouble([0,0,0,0,0,0,0,0,0,0,0,0],6,2) - d[[1,3,4],[1,0]]=[7,8] - self.assertTrue(d.isEqual(DataArrayDouble([0,0,8,7,0,0,8,7,8,7,0,0],6,2),1e-14)) - # 11-2 false - d=DataArrayDouble([0,0,0,0,0,0,0,0,0,0,0,0],6,2) - d[1::2,[1,0]]=[7,8] - self.assertTrue(d.isEqual(DataArrayDouble([0,0,8,7,0,0,8,7,0,0,8,7],6,2),1e-14)) - # 12-2 false - d=DataArrayDouble([0,0,0,0,0,0,0,0,0,0,0,0],6,2) - d[DataArrayInt([1,4]),[1,0]]=[7,8] - self.assertTrue(d.isEqual(DataArrayDouble([0,0,8,7,0,0,0,0,8,7,0,0],6,2),1e-14)) - # 13-2 - d=DataArrayDouble([0,0,0,0,0,0,0,0,0,0,0,0],6,2) - d[1,:-1]=[9] - self.assertTrue(d.isEqual(DataArrayDouble([0,0,9,0,0,0,0,0,0,0,0,0],6,2),1e-14)) - # 14-2 false - d=DataArrayDouble([0,0,0,0,0,0,0,0,0,0,0,0],6,2) - d[[1,4,5],:]=[7,8] - self.assertTrue(d.isEqual(DataArrayDouble([0,0,7,8,0,0,0,0,7,8,7,8],6,2),1e-14)) - # 15-2 false - d=DataArrayDouble([0,0,0,0,0,0,0,0,0,0,0,0],6,2) - d[1::2,:]=[3,9] - self.assertTrue(d.isEqual(DataArrayDouble([0,0,3,9,0,0,3,9,0,0,3,9],6,2),1e-14)) - # 1-2 - d=DataArrayInt([0,0,0,0,0,0,0,0,0,0,0,0],6,2) - d[3]=[1,2] - self.assertTrue(d.isEqual(DataArrayInt([0,0,0,0,0,0,1,2,0,0,0,0],6,2))) - # 2-2 false - d=DataArrayInt([0,0,0,0,0,0,0,0,0,0,0,0],6,2) - d[[5,3,2]]=[1,2] - self.assertTrue(d.isEqual(DataArrayInt([0,0,0,0,1,2,1,2,0,0,1,2],6,2))) - # 3-2 false - d=DataArrayInt([0,0,0,0,0,0,0,0,0,0,0,0],6,2) - d[:]=[1,2] - self.assertTrue(d.isEqual(DataArrayInt([1,2,1,2,1,2,1,2,1,2,1,2],6,2))) - # 4-2 false - d=DataArrayInt([0,0,0,0,0,0,0,0,0,0,0,0],6,2) - d[DataArrayInt([0,3,4])]=[1,2] - self.assertTrue(d.isEqual(DataArrayInt([1,2,0,0,0,0,1,2,1,2,0,0],6,2))) - # 5-2 - d=DataArrayInt([0,0,0,0,0,0,0,0,0,0,0,0],6,2) - d[5,1]=[7] - self.assertTrue(d.isEqual(DataArrayInt([0,0,0,0,0,0,0,0,0,0,0,7],6,2))) - # 6-2 false - d=DataArrayInt([0,0,0,0,0,0,0,0,0,0,0,0],6,2) - d[[3,5],1]=[7] - self.assertTrue(d.isEqual(DataArrayInt([0,0,0,0,0,0,0,7,0,0,0,7],6,2))) - # 7-2 false - d=DataArrayInt([0,0,0,0,0,0,0,0,0,0,0,0],6,2) - d[:-1:2,1]=[7] - self.assertTrue(d.isEqual(DataArrayInt([0,7,0,0,0,7,0,0,0,7,0,0],6,2))) - # 8-2 false - d=DataArrayInt([0,0,0,0,0,0,0,0,0,0,0,0],6,2) - d[DataArrayInt([0,3,4]),1]=[7] - self.assertTrue(d.isEqual(DataArrayInt([0,7,0,0,0,0,0,7,0,7,0,0],6,2))) - # 9-2 - d=DataArrayInt([0,0,0,0,0,0,0,0,0,0,0,0],6,2) - d[3,[1,0]]=[7,8] - self.assertTrue(d.isEqual(DataArrayInt([0,0,0,0,0,0,8,7,0,0,0,0],6,2))) - # 10-2 false - d=DataArrayInt([0,0,0,0,0,0,0,0,0,0,0,0],6,2) - d[[1,3,4],[1,0]]=[7,8] - self.assertTrue(d.isEqual(DataArrayInt([0,0,8,7,0,0,8,7,8,7,0,0],6,2))) - # 11-2 false - d=DataArrayInt([0,0,0,0,0,0,0,0,0,0,0,0],6,2) - d[1::2,[1,0]]=[7,8] - self.assertTrue(d.isEqual(DataArrayInt([0,0,8,7,0,0,8,7,0,0,8,7],6,2))) - # 12-2 false - d=DataArrayInt([0,0,0,0,0,0,0,0,0,0,0,0],6,2) - d[DataArrayInt([1,4]),[1,0]]=[7,8] - self.assertTrue(d.isEqual(DataArrayInt([0,0,8,7,0,0,0,0,8,7,0,0],6,2))) - # 13-2 - d=DataArrayInt([0,0,0,0,0,0,0,0,0,0,0,0],6,2) - d[1,:-1]=[9] - self.assertTrue(d.isEqual(DataArrayInt([0,0,9,0,0,0,0,0,0,0,0,0],6,2))) - # 14-2 false - d=DataArrayInt([0,0,0,0,0,0,0,0,0,0,0,0],6,2) - d[[1,4,5],:]=[7,8] - self.assertTrue(d.isEqual(DataArrayInt([0,0,7,8,0,0,0,0,7,8,7,8],6,2))) - # 15-2 false - d=DataArrayInt([0,0,0,0,0,0,0,0,0,0,0,0],6,2) - d[1::2,:]=[3,9] - self.assertTrue(d.isEqual(DataArrayInt([0,0,3,9,0,0,3,9,0,0,3,9],6,2))) - pass - - def testSwig2ConvertLinearCellsToQuadratic1(self): - coordsExp=DataArrayDouble([-0.3,-0.3,0.2,-0.3,0.7,-0.3,-0.3,0.2,0.2,0.2,0.7,0.2,-0.3,0.7,0.2,0.7,0.7,0.7,-0.3,-0.05,-0.05,0.2,0.2,-0.05,-0.05,-0.3,0.45,-0.05,0.45,-0.3,0.45,0.2,0.7,-0.05,-0.05,0.7,0.2,0.45,-0.3,0.45,0.45,0.7,0.7,0.45],22,2) - # 2D - m2D=MEDCouplingDataForTest.build2DTargetMesh_1() - m2D.convertLinearCellsToQuadratic(0) - m2D.checkCoherency1() - self.assertEqual(m2D.getNodalConnectivity().getValues(),[8,0,3,4,1,9,10,11,12,6,1,4,2,11,13,14,6,4,5,2,15,16,13,8,6,7,4,3,17,18,10,19,8,7,8,5,4,20,21,15,18]) - self.assertEqual(m2D.getNodalConnectivityIndex().getValues(),[0,9,16,23,32,41]) - self.assertTrue(m2D.getCoords().isEqual(coordsExp,1e-14)) - # 1D - m1D=MEDCouplingDataForTest.build2DTargetMesh_1().buildDescendingConnectivity()[0] - m1D.convertLinearCellsToQuadratic(0) - m1D.checkCoherency1() - self.assertEqual(m1D.getNodalConnectivity().getValues(),[2,0,3,9,2,3,4,10,2,4,1,11,2,1,0,12,2,4,2,13,2,2,1,14,2,4,5,15,2,5,2,16,2,6,7,17,2,7,4,18,2,3,6,19,2,7,8,20,2,8,5,21]) - self.assertEqual(m1D.getNodalConnectivityIndex().getValues(),[0,4,8,12,16,20,24,28,32,36,40,44,48,52]) - self.assertTrue(m1D.getCoords().isEqual(coordsExp,1e-14)) - # 3D - m2D=MEDCouplingDataForTest.build2DTargetMesh_1() - m2D.changeSpaceDimension(3) - arr=DataArrayDouble(4); arr.iota(0) ; z=MEDCouplingCMesh() ; z.setCoords(arr) - m1D=z.buildUnstructured() ; m1D.setCoords(arr.changeNbOfComponents(3,0.)) - m1D.getCoords()[:]=m1D.getCoords()[:,[1,2,0]] - cooTmp=m2D.getCoords()[:] - m3D=m2D.buildExtrudedMesh(m1D,0) - m3D.convertLinearCellsToQuadratic(0) - m3D.checkCoherency1() - # check of new m3D content - coordsExp2=[coordsExp.changeNbOfComponents(3,i) for i in xrange(4)] - coordsExp3=[DataArrayDouble.Meld(cooTmp[:,[0,1]],cooTmp[:,2]+(0.5+float(i))) for i in xrange(3)] - coordsExp4=DataArrayDouble.Aggregate([coordsExp2[0],coordsExp3[0],coordsExp2[1],coordsExp3[1],coordsExp2[2],coordsExp3[2],coordsExp2[3]]) - c=DataArrayDouble.Aggregate(m3D.getCoords(),coordsExp4) - self.assertEqual(len(coordsExp4),115) - self.assertEqual(len(m3D.getCoords()),115) - a,b=c.findCommonTuples(1e-14) - self.assertEqual(len(b),len(coordsExp4)+1) - e,f=DataArrayInt.BuildOld2NewArrayFromSurjectiveFormat2(2*115,a,b) - self.assertEqual(f,115) - self.assertTrue(e.isEqual(DataArrayInt([0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97,98,99,100,101,102,103,104,105,106,107,108,109,110,111,112,113,114,0,1,2,3,4,5,6,7,8,36,37,38,39,48,49,53,54,58,59,60,66,67,44,47,52,45,46,57,64,65,70,9,10,11,12,13,14,15,16,17,40,41,42,43,50,51,55,56,61,62,63,68,69,75,78,81,76,77,84,88,89,92,18,19,20,21,22,23,24,25,26,71,72,73,74,79,80,82,83,85,86,87,90,91,97,100,103,98,99,106,110,111,114,27,28,29,30,31,32,33,34,35,93,94,95,96,101,102,104,105,107,108,109,112,113]))) - self.assertTrue(DataArrayInt([30,0,3,4,1,9,12,13,10,36,37,38,39,40,41,42,43,44,45,46,47,25,1,4,2,10,13,11,38,48,49,42,50,51,47,46,52,25,4,5,2,13,14,11,53,54,48,55,56,50,46,57,52,30,6,7,4,3,15,16,13,12,58,59,37,60,61,62,41,63,64,65,46,45,30,7,8,5,4,16,17,14,13,66,67,53,59,68,69,55,62,65,70,57,46,30,9,12,13,10,18,21,22,19,40,41,42,43,71,72,73,74,75,76,77,78,25,10,13,11,19,22,20,42,50,51,73,79,80,78,77,81,25,13,14,11,22,23,20,55,56,50,82,83,79,77,84,81,30,15,16,13,12,24,25,22,21,61,62,41,63,85,86,72,87,88,89,77,76,30,16,17,14,13,25,26,23,22,68,69,55,62,90,91,82,86,89,92,84,77,30,18,21,22,19,27,30,31,28,71,72,73,74,93,94,95,96,97,98,99,100,25,19,22,20,28,31,29,73,79,80,95,101,102,100,99,103,25,22,23,20,31,32,29,82,83,79,104,105,101,99,106,103,30,24,25,22,21,33,34,31,30,85,86,72,87,107,108,94,109,110,111,99,98,30,25,26,23,22,34,35,32,31,90,91,82,86,112,113,104,108,111,114,106,99]).isEqual(m3D.getNodalConnectivity())) - self.assertTrue(DataArrayInt([0,21,37,53,74,95,116,132,148,169,190,211,227,243,264,285]).isEqual(m3D.getNodalConnectivityIndex())) - # testing explode3DMeshTo1D - m3DSlice0=m3D[:5] - m3DSlice0.zipCoords() - a,b,c,d,e=m3DSlice0.explode3DMeshTo1D() - self.assertTrue(b.isEqual(DataArrayInt([0,1,2,3,4,5,6,7,8,9,10,11,2,12,13,6,14,15,11,10,16,17,18,12,19,20,14,10,21,16,22,23,1,24,25,26,5,27,28,29,10,9,30,31,17,23,32,33,19,26,29,34,21,10]))) - self.assertTrue(c.isEqual(DataArrayInt([0,12,21,30,42,54]))) - self.assertTrue(d.isEqual(DataArrayInt([0,0,3,0,1,0,0,0,3,0,1,0,0,0,3,0,1,2,3,4,0,1,1,2,1,1,2,1,1,2,2,4,2,2,4,2,2,4,3,3,4,3,3,3,4,3,3,3,4,4,4,4,4,4]))) - self.assertTrue(e.isEqual(DataArrayInt([0,1,3,5,6,7,9,11,12,13,15,20,22,24,25,27,28,30,32,33,35,36,38,39,41,42,43,45,46,47,49,50,51,52,53,54]))) - self.assertTrue(a.getNodalConnectivity().isEqual(DataArrayInt([2,0,3,18,2,3,4,19,2,4,1,20,2,1,0,21,2,9,12,22,2,12,13,23,2,13,10,24,2,10,9,25,2,0,9,26,2,3,12,27,2,4,13,28,2,1,10,29,2,4,2,30,2,2,1,31,2,13,11,32,2,11,10,33,2,2,11,34,2,4,5,35,2,5,2,36,2,13,14,37,2,14,11,38,2,5,14,39,2,6,7,40,2,7,4,41,2,3,6,42,2,15,16,43,2,16,13,44,2,12,15,45,2,6,15,46,2,7,16,47,2,7,8,48,2,8,5,49,2,16,17,50,2,17,14,51,2,8,17,52]))) - self.assertTrue(a.getNodalConnectivityIndex().isEqual(DataArrayInt([0,4,8,12,16,20,24,28,32,36,40,44,48,52,56,60,64,68,72,76,80,84,88,92,96,100,104,108,112,116,120,124,128,132,136,140]))) - self.assertTrue(a.getCoords().isEqual(DataArrayDouble([-0.3,-0.3,0.0,0.2,-0.3,0.0,0.7,-0.3,0.0,-0.3,0.2,0.0,0.2,0.2,0.0,0.7,0.2,0.0,-0.3,0.7,0.0,0.2,0.7,0.0,0.7,0.7,0.0,-0.3,-0.3,1.0,0.2,-0.3,1.0,0.7,-0.3,1.0,-0.3,0.2,1.0,0.2,0.2,1.0,0.7,0.2,1.0,-0.3,0.7,1.0,0.2,0.7,1.0,0.7,0.7,1.0,-0.3,-0.05,0.0,-0.05,0.2,0.0,0.2,-0.05,0.0,-0.05,-0.3,0.0,-0.3,-0.05,1.0,-0.05,0.2,1.0,0.2,-0.05,1.0,-0.05,-0.3,1.0,-0.3,-0.3,0.5,-0.3,0.2,0.5,0.2,0.2,0.5,0.2,-0.3,0.5,0.45,-0.05,0.0,0.45,-0.3,0.0,0.45,-0.05,1.0,0.45,-0.3,1.0,0.7,-0.3,0.5,0.45,0.2,0.0,0.7,-0.05,0.0,0.45,0.2,1.0,0.7,-0.05,1.0,0.7,0.2,0.5,-0.05,0.7,0.0,0.2,0.45,0.0,-0.3,0.45,0.0,-0.05,0.7,1.0,0.2,0.45,1.0,-0.3,0.45,1.0,-0.3,0.7,0.5,0.2,0.7,0.5,0.45,0.7,0.0,0.7,0.45,0.0,0.45,0.7,1.0,0.7,0.45,1.0,0.7,0.7,0.5],53,3),1e-14)) - pass - - def testSwig2DataArrayPushBackValsSilent1(self): - d=DataArrayDouble() - d.pushBackValsSilent([4,5,6]) - self.assertTrue(d.isEqual(DataArrayDouble([4.,5.,6.]),1e-14)) - e=DataArrayDouble([1,2,3],1,3) - for t in e: d.pushBackValsSilent(t) - self.assertTrue(d.isEqual(DataArrayDouble([4.,5.,6.,1.,2.,3.]),1e-14)) - d.pushBackValsSilent(DataArrayDouble([9,10.])) - self.assertTrue(d.isEqual(DataArrayDouble([4.,5.,6.,1.,2.,3.,9.,10.]),1e-14)) - d.pushBackValsSilent(DataArrayDouble(0,1)) - self.assertTrue(d.isEqual(DataArrayDouble([4.,5.,6.,1.,2.,3.,9.,10.]),1e-14)) - e=DataArrayDouble([1,2,3],3,1) - for t in e: d.pushBackValsSilent(t) - self.assertTrue(d.isEqual(DataArrayDouble([4.,5.,6.,1.,2.,3.,9.,10.,1.,2.,3.]),1e-14)) - d.pushBackValsSilent(77) - self.assertTrue(d.isEqual(DataArrayDouble([4.,5.,6.,1.,2.,3.,9.,10.,1.,2.,3.,77.]),1e-14)) - # - d=DataArrayInt() - d.pushBackValsSilent([4,5,6]) - self.assertTrue(d.isEqual(DataArrayInt([4,5,6]))) - e=DataArrayInt([1,2,3],1,3) - for t in e: d.pushBackValsSilent(t) - self.assertTrue(d.isEqual(DataArrayInt([4,5,6,1,2,3]))) - d.pushBackValsSilent(DataArrayInt([9,10])) - self.assertTrue(d.isEqual(DataArrayInt([4,5,6,1,2,3,9,10]))) - d.pushBackValsSilent(DataArrayInt(0,1)) - self.assertTrue(d.isEqual(DataArrayInt([4,5,6,1,2,3,9,10]))) - e=DataArrayInt([1,2,3],3,1) - for t in e: d.pushBackValsSilent(t) - self.assertTrue(d.isEqual(DataArrayInt([4,5,6,1,2,3,9,10,1,2,3]))) - d.pushBackValsSilent(77) - self.assertTrue(d.isEqual(DataArrayInt([4,5,6,1,2,3,9,10,1,2,3,77]))) - pass - - def testSwig2ConvertLinearCellsToQuadratic2(self): - m2D=MEDCouplingDataForTest.build2DTargetMesh_1() - ret=m2D.convertLinearCellsToQuadratic(1) - self.assertTrue(ret.isIdentity()) - self.assertEqual(5,len(ret)) - m2D.checkCoherency1() - coordsExp=DataArrayDouble([-0.3,-0.3,0.2,-0.3,0.7,-0.3,-0.3,0.2,0.2,0.2,0.7,0.2,-0.3,0.7,0.2,0.7,0.7,0.7,-0.3,-0.05,-0.05,0.2,0.2,-0.05,-0.05,-0.3,0.45,-0.05,0.45,-0.3,0.45,0.2,0.7,-0.05,-0.05,0.7,0.2,0.45,-0.3,0.45,0.45,0.7,0.7,0.45,-0.05,-0.05,0.3666666666666667,-0.1333333333333333,0.5333333333333332,0.03333333333333334,-0.05,0.45,0.45,0.45],27,2) - self.assertTrue(m2D.getCoords().isEqual(coordsExp,1e-14)) - self.assertTrue(m2D.getNodalConnectivity().isEqual(DataArrayInt([9,0,3,4,1,9,10,11,12,22,7,1,4,2,11,13,14,23,7,4,5,2,15,16,13,24,9,6,7,4,3,17,18,10,19,25,9,7,8,5,4,20,21,15,18,26]))) - self.assertTrue(m2D.getNodalConnectivityIndex().isEqual(DataArrayInt([0,10,18,26,36,46]))) - # - m2D=MEDCouplingDataForTest.build2DTargetMesh_1()[(0,3)] ; m2D.zipCoords() - m2D.changeSpaceDimension(3) - arr=DataArrayDouble(3); arr.iota(0) ; z=MEDCouplingCMesh() ; z.setCoords(arr) - m1D=z.buildUnstructured() ; m1D.setCoords(arr.changeNbOfComponents(3,0.)) - m1D.getCoords()[:]=m1D.getCoords()[:,[1,2,0]] - cooTmp=m2D.getCoords()[:] - m3D=m2D.buildExtrudedMesh(m1D,0) - ret=m3D.convertLinearCellsToQuadratic(1) - self.assertTrue(ret.isIdentity()) - self.assertEqual(4,len(ret)) - m3D.checkCoherency1() - coordsExp2=DataArrayDouble([-0.3,-0.3,0.0,0.2,-0.3,0.0,-0.3,0.2,0.0,0.2,0.2,0.0,-0.3,0.7,0.0,0.2,0.7,0.0,-0.3,-0.3,1.0,0.2,-0.3,1.0,-0.3,0.2,1.0,0.2,0.2,1.0,-0.3,0.7,1.0,0.2,0.7,1.0,-0.3,-0.3,2.0,0.2,-0.3,2.0,-0.3,0.2,2.0,0.2,0.2,2.0,-0.3,0.7,2.0,0.2,0.7,2.0,-0.3,-0.05,0.0,-0.05,0.2,0.0,0.2,-0.05,0.0,-0.05,-0.3,0.0,-0.3,-0.05,1.0,-0.05,0.2,1.0,0.2,-0.05,1.0,-0.05,-0.3,1.0,-0.3,-0.3,0.5,-0.3,0.2,0.5,0.2,0.2,0.5,0.2,-0.3,0.5,-0.05,0.7,0.0,0.2,0.45,0.0,-0.3,0.45,0.0,-0.05,0.7,1.0,0.2,0.45,1.0,-0.3,0.45,1.0,-0.3,0.7,0.5,0.2,0.7,0.5,-0.3,-0.05,2.0,-0.05,0.2,2.0,0.2,-0.05,2.0,-0.05,-0.3,2.0,-0.3,-0.3,1.5,-0.3,0.2,1.5,0.2,0.2,1.5,0.2,-0.3,1.5,-0.05,0.7,2.0,0.2,0.45,2.0,-0.3,0.45,2.0,-0.3,0.7,1.5,0.2,0.7,1.5,-0.05,-0.05,0.0,-0.3,-0.05,0.5,-0.05,0.2,0.5,0.2,-0.05,0.5,-0.05,-0.3,0.5,-0.05,-0.05,1.0,-0.05,0.45,0.0,-0.05,0.7,0.5,0.2,0.45,0.5,-0.3,0.45,0.5,-0.05,0.45,1.0,-0.3,-0.05,1.5,-0.05,0.2,1.5,0.2,-0.05,1.5,-0.05,-0.3,1.5,-0.05,-0.05,2.0,-0.05,0.7,1.5,0.2,0.45,1.5,-0.3,0.45,1.5,-0.05,0.45,2.0,-0.05,-0.05,0.5,-0.05,0.45,0.5,-0.05,-0.05,1.5,-0.05,0.45,1.5],75,3) - self.assertTrue(m3D.getCoords().isEqual(coordsExp2,1e-14)) - self.assertTrue(m3D.getNodalConnectivity().isEqual(DataArrayInt([27,0,2,3,1,6,8,9,7,18,19,20,21,22,23,24,25,26,27,28,29,51,52,53,54,55,56,71,27,4,5,3,2,10,11,9,8,30,31,19,32,33,34,23,35,36,37,28,27,57,58,59,53,60,61,72,27,6,8,9,7,12,14,15,13,22,23,24,25,38,39,40,41,42,43,44,45,56,62,63,64,65,66,73,27,10,11,9,8,16,17,15,14,33,34,23,35,46,47,39,48,49,50,44,43,61,67,68,63,69,70,74]))) - self.assertTrue(m3D.getNodalConnectivityIndex().isEqual(DataArrayInt([0,28,56,84,112]))) - pass - - def testSwig2GaussNEIntegral1(self): - m2D=MEDCouplingDataForTest.build2DTargetMesh_1() - m0=m2D[0] ; m0.zipCoords() - m1=m2D[[1,2]] ; m1.zipCoords() - m2=m2D[[3,4]] ; m2.zipCoords() - m0.convertLinearCellsToQuadratic(1) - m1.convertLinearCellsToQuadratic(0) - m2.convertLinearCellsToQuadratic(1) - m=MEDCouplingUMesh.MergeUMeshes([m0,m1,m2]) - m.mergeNodes(1e-12) - f=MEDCouplingFieldDouble(ON_GAUSS_NE) - f.setMesh(m) - arr=DataArrayDouble([1.1,2.2,3.3,4.4,5.5,6.6,7.7,8.8,9.9, - 11.1,12.2,13.3,14.4,15.5,16.6, - 21.1,22.2,23.3,24.4,25.5,26.6, - 31.1,32.2,33.3,34.4,35.5,36.6,37.7,38.8,39.9, - 41.1,42.2,43.3,44.4,45.5,46.6,47.7,48.8,49.9]) - arr2=DataArrayDouble(len(arr),2) - arr2[:,0]=arr ; arr2[:,1]=arr+100 - f.setArray(arr2) - f.checkCoherency() - res=f.integral(False) - # a=25./81 ; b=40./81 ; c=64./81 - # p1=0.11169079483905 ; p2=0.0549758718227661 - # 1st compo - # c0=(a*(1.1+2.2+3.3+4.4)+b*(5.5+6.6+7.7+8.8)+c*9.9)*0.25/3.9999999999999978 ; c0=1.5837962962962973 - # c1=(p2*(11.1+12.2+13.3)+p1*(14.4+15.5+16.6))*0.125/0.4999999999854482 ; c1=1.8014347172346943 - # c2=(p2*(21.1+22.2+23.3)+p1*(24.4+25.5+26.6))*0.125/0.4999999999854482 ; c2=3.0514347172346943 - # c3=(a*(31.1+32.2+33.3+34.4)+b*(35.5+36.6+37.7+38.8)+c*39.9)*0.25/3.9999999999999978 ; c3=9.0837962962963 - # c4=(a*(41.1+42.2+43.3+44.4)+b*(45.5+46.6+47.7+48.8)+c*49.9)*0.25/3.9999999999999978 ; c4=11.583796296296303 - # c0+c1+c2+c3+c4=27.104258323358287 - integExp0=27.104258323358287 - self.assertAlmostEqual(res[0],integExp0,13) - # 2nd compo - # c0=(a*(101.1+102.2+103.3+104.4)+b*(105.5+106.6+107.7+108.8)+c*109.9)*0.25/3.9999999999999978 ; c0=26.58379629629631 - # c1=(p2*(111.1+112.2+113.3)+p1*(114.4+115.5+116.6))*0.125/0.4999999999854482 ; c1=14.301434717234699 - # c2=(p2*(121.1+122.2+123.3)+p1*(124.4+125.5+126.6))*0.125/0.4999999999854482 ; c2=15.5514347172347 - # c3=(a*(131.1+132.2+133.3+134.4)+b*(135.5+136.6+137.7+138.8)+c*139.9)*0.25/3.9999999999999978 ; c3=34.08379629629631 - # c4=(a*(141.1+142.2+143.3+144.4)+b*(145.5+146.6+147.7+148.8)+c*149.9)*0.25/3.9999999999999978 ; c4=36.58379629629632 - # c0+c1+c2+c3+c4=127.10425832335835 - integExp1=127.10425832335835 - self.assertAlmostEqual(res[1],integExp1,12) - meas=f.getDiscretization().getMeasureField(f.getMesh(),False) - intPerTuple=meas*f - res2=intPerTuple.accumulate() - self.assertAlmostEqual(res2[0],integExp0,13) - self.assertAlmostEqual(res2[1],integExp1,12) - # - meas2=f.buildMeasureField(False) - intPerTuple=meas2*f - res3=intPerTuple.accumulate() - self.assertAlmostEqual(res3[0],integExp0,13) - self.assertAlmostEqual(res3[1],integExp1,12) - # - res4=f.getWeightedAverageValue(False) # res4==res2 because sum of area of mesh is equal to 1 - self.assertAlmostEqual(res4[0],integExp0,13) - self.assertAlmostEqual(res4[1],integExp1,12) - # - m.scale([0,0],2.) - # - res5=f.getWeightedAverageValue() # res4==res4 because weighted average is not sensitive to the scaling - self.assertAlmostEqual(res5[0],integExp0,13) - self.assertAlmostEqual(res5[1],integExp1,12) - meas3=f.buildMeasureField(False) - delta=4*meas2.getArray()-meas3.getArray() - delta.abs() - self.assertTrue(delta.isUniform(0.,1e-16)) - res6=f.integral(False) - self.assertAlmostEqual(res6[0],4.*integExp0,12) - self.assertAlmostEqual(res6[1],4.*integExp1,11) - pass - - def testSwig2SlowDADFindClosestTupleId(self): - nbPts=[10,] - for nbPt in nbPts: - d=DataArrayDouble(nbPt) ; d.iota() ; d*=1./(nbPt-1) - c=MEDCouplingCMesh() ; c.setCoords(d,d) ; m=c.buildUnstructured() ; pts=m.getCoords() ; del m - # - d0=DataArrayDouble((nbPt-1)*(nbPt-1)) ; d0.iota() ; d0*=(3./((nbPt-1)*(nbPt-1))) ; d0=d0.applyFunc("exp(x)-1") - d1=DataArrayDouble((nbPt-1)*(nbPt-1)) ; d1.iota() - d2=DataArrayDouble.Meld(d0,d1) ; d2=d2.fromPolarToCart() ; d2+=[0.32,0.73] - ids=pts.findClosestTupleId(d2) - #print "Start of costly computation" - idsExpected=DataArrayInt(len(d2)) - tmp=1e300 - for i,elt in enumerate(d2): - l,m=(pts-elt).magnitude().getMinValue() - idsExpected.setIJSilent(i,0,m) - if l 2147483647 - pass - pass - - def testSwig2DAReverseMultiCompo1(self): - d=DataArrayDouble(6,2) - d[:,0]=range(6) - d[:,1]=range(10,16) - d.reverse() - self.assertTrue(d.isEqual(DataArrayDouble([5.,15.,4.,14.,3.,13.,2.,12.,1.,11.,0.,10.],6,2),1e-14)) - d=DataArrayDouble(7,2) - d[:,0]=range(7) - d[:,1]=range(10,17) - d.reverse() - self.assertTrue(d.isEqual(DataArrayDouble([6.,16.,5.,15.,4.,14.,3.,13.,2.,12.,1.,11.,0.,10.],7,2),1e-14)) - # - d=DataArrayInt(6,2) - d[:,0]=range(6) - d[:,1]=range(10,16) - d.reverse() - self.assertTrue(d.isEqual(DataArrayInt([5,15,4,14,3,13,2,12,1,11,0,10],6,2))) - d=DataArrayInt(7,2) - d[:,0]=range(7) - d[:,1]=range(10,17) - d.reverse() - self.assertTrue(d.isEqual(DataArrayInt([6,16,5,15,4,14,3,13,2,12,1,11,0,10],7,2))) - pass - - def testSwigDAPow1(self): - d=DataArrayInt(10) - d.iota(0) - d1=d.deepCpy() - d.setIJ(2,0,-2) - self.assertTrue((d**2).isEqual(DataArrayInt([0,1,4,9,16,25,36,49,64,81]))) - self.assertTrue((d**3).isEqual(DataArrayInt([0,1,-8,27,64,125,216,343,512,729]))) - for elt in [d]: - elt**=2 - pass - self.assertTrue(d.isEqual(DataArrayInt([0,1,4,9,16,25,36,49,64,81]))) - self.assertTrue((d1[:4]**d1[:4]).isEqual(DataArrayInt([1,1,4,27]))) - self.assertTrue((3**d1[:4]).isEqual(DataArrayInt([1,3,9,27]))) - d2=d1[:4] - d2**=d2 - self.assertTrue(d2.isEqual(DataArrayInt([1,1,4,27]))) - self.assertRaises(InterpKernelException,d2.__pow__,-1)#non supporting negative pow in DataArrayInt.__pow__ - self.assertRaises(InterpKernelException,d2.__ipow__,-1)#non supporting negative pow in DataArrayInt.__pow__ - # - d=DataArrayDouble(10) - d.iota(0) - d1=d.deepCpy() - d.setIJ(2,0,-2.) - self.assertTrue((d**2).isEqual(DataArrayDouble([0,1,4,9,16,25,36,49,64,81]),1e-12)) - self.assertTrue((d**3).isEqual(DataArrayDouble([0,1,-8,27,64,125,216,343,512,729]),1e-12)) - self.assertRaises(InterpKernelException,d.__pow__,3.1)#3.1 is double not integer -> not supporting negative values in d - for elt in [d]: - elt**=2 - pass - self.assertTrue(d.isEqual(DataArrayDouble([0,1,4,9,16,25,36,49,64,81]),1e-12)) - self.assertTrue((d1[:4]**d1[:4]).isEqual(DataArrayDouble([1,1,4,27]),1e-12)) - self.assertTrue((3**d1[:4]).isEqual(DataArrayDouble([1,3,9,27]),1e-12)) - d2=d1[:4] - d2**=d2 - self.assertTrue(d2.isEqual(DataArrayDouble([1,1,4,27]),1e-12)) - d2**=-0.5 - self.assertTrue(d2.isEqual(DataArrayDouble([1,1,1./2,1./sqrt(27.)]),1e-14)) - d3=-1./d1[1:5] - self.assertTrue((3**d3).isEqual(DataArrayDouble([0.3333333333333333,0.5773502691896257,0.6933612743506348,0.7598356856515925]),1e-14)) - d4=d3.deepCpy() ; d4.abs() - self.assertTrue((d4**d3).isEqual(DataArrayDouble([1.,sqrt(2.),1.4422495703074083,sqrt(2.)]),1e-14)) - d4**=d3 - self.assertTrue(d4.isEqual(DataArrayDouble([1.,sqrt(2.),1.4422495703074083,sqrt(2.)]),1e-14)) - pass - - def testSwig2Baryenter3DForCellsWithVolumeZero1(self): - coo=DataArrayDouble([0.,0.,0.,1.,0.,0.,0.,1.,0.],3,3) - m2=MEDCouplingUMesh("mesh",2) - m2.allocateCells(0) - m2.insertNextCell(NORM_POLYGON,[0,1,2]) - m2.setCoords(coo) - m2.checkCoherency1() - # - coo2=DataArrayDouble([0.,0.,0.,0.,0.,0.,0.,0.,2.],3,3) - m1=MEDCouplingUMesh("mesh",1) - m1.allocateCells(0) - m1.insertNextCell(NORM_SEG2,[0,1]) - m1.insertNextCell(NORM_SEG2,[1,2]) - m1.setCoords(coo2) - m1.checkCoherency1() - # - m3=m2.buildExtrudedMesh(m1,0) - m3.insertNextCell(NORM_POLYHED,[3,4,5,-1,8,7,6,-1,4,3,6,7,-1,5,4,7,8,-1,5,4,-1,3,5,8,6])# addition of face #4 with null surface - self.assertTrue(m3.getBarycenterAndOwner().isEqual(DataArrayDouble([0.3333333333333333,0.3333333333333333,0.,0.3333333333333333,0.3333333333333333,1.,0.3333333333333333,0.3333333333333333,1.],3,3),1e-13)) - m4,a,b,c,d=m3.buildDescendingConnectivity() - self.assertTrue(m4.getBarycenterAndOwner().isEqual(DataArrayDouble([0.3333333333333333,0.3333333333333333,0.,0.3333333333333333,0.3333333333333333,0.,0.5,0.,0.,0.5,0.5,0.,0.,0.5,0.,0.3333333333333333,0.3333333333333333,2.,0.5,0.,1.,0.5,0.5,1.,0.,0.5,1.,0.5,0.5,0.],10,3),1e-13)) - pass - - def testSwigRepr1(self): - d=DataArrayDouble() - self.assertTrue(len(d.__repr__())<120) - d.alloc(1000,0) ; self.assertTrue(len(d.__repr__())<100) - for i in xrange(100): - d.alloc(i,1) ; d.iota(1.1234567890123456) ; d*=1e123 - self.assertTrue(len(d.__repr__())<500) - pass - for i in xrange(50): - d.alloc(i,2) ; d.rearrange(1) ; d.iota(1.1234567890123456) ; d.rearrange(2) ; d*=1e123 - self.assertTrue(len(d.__repr__())<500) - pass - d.alloc(4000,1) ; d.iota() ; self.assertTrue(len(d.__repr__())<500) - for i in xrange(2,4): - d.alloc(362880,1) ; d.iota() ; d.rearrange(i) ; self.assertTrue(len(d.__repr__())<500) - pass - d.alloc(0,9) - self.assertTrue(len(d.__repr__())<120) - # - d=DataArrayInt() - self.assertTrue(len(d.__repr__())<100) - d.alloc(1000,0) ; self.assertTrue(len(d.__repr__())<100) - for i in xrange(100): - d.alloc(i,1) ; d.iota(123456789) - self.assertTrue(len(d.__repr__())<500) - pass - for i in xrange(50): - d.alloc(i,2) ; d.rearrange(1) ; d.iota(123456789) ; d.rearrange(2) - self.assertTrue(len(d.__repr__())<500) - pass - d.alloc(4000,1) ; d.iota() ; self.assertTrue(len(d.__repr__())<500) - for i in xrange(2,10): - d.alloc(362880,1) ; d.iota() ; d.rearrange(i) ; self.assertTrue(len(d.__repr__())<500) - pass - d.alloc(0,9) - self.assertTrue(len(d.__repr__())<100) - # - d=DataArrayAsciiChar() - d.alloc(1000,0) ; self.assertTrue(len(d.__repr__())<100) - d.alloc(2,16) ; d[:]='1234567890ABCDEF' - self.assertTrue(len(d.__repr__())<500) - d.alloc(2000,16) ; d[:]='1234567890ABCDEF' - self.assertTrue(len(d.__repr__())<500) - d.alloc(0,16) ; d[:]='1234567890ABCDEF' - self.assertTrue(len(d.__repr__())<120) - # - d=DataArrayByte() - self.assertTrue(len(d.__repr__())<100) - d.alloc(1000,0) ; self.assertTrue(len(d.__repr__())<100) - d.alloc(0,16) ; self.assertTrue(len(d.__repr__())<100) - d.alloc(5,1) ; d.fillWithValue(127) - self.assertTrue(len(d.__repr__())<200) - d.alloc(1000,1) ; d.fillWithValue(127) - self.assertTrue(len(d.__repr__())<500) - d.alloc(1000,3) ; d.fillWithValue(127) - self.assertTrue(len(d.__repr__())<500) - pass - - def testSwig2MeshComputeIsoBarycenterOfNodesPerCell1(self): - coo=DataArrayDouble([26.17509821414239,5.0374,200.,26.175098214142388,-5.0374,200.,17.450065476094927,20.1496,200.,8.725032738047464,25.187,200.,43.62516369023732,5.0374,200.,34.90013095218986,10.0748,200.,34.900130952189855,-10.0748,200.,43.625163690237315,-5.0374,200.,26.175098214142402,25.187,200.,26.175098214142395,35.2618,200.,17.45006547609493,40.2992,200.,8.725032738047469,35.2618,200.,26.17509821414239,5.0374,200.,26.175098214142388,-5.0374,200.,17.450065476094927,20.1496,200.,8.725032738047464,25.187,200.,43.62516369023732,5.0374,200.,34.90013095218986,10.0748,200.,34.900130952189855,-10.0748,200.,43.625163690237315,-5.0374,200.,26.175098214142402,25.187,200.,26.175098214142395,35.2618,200.,17.45006547609493,40.2992,200.,8.725032738047469,35.2618,200.],24,3) - m=MEDCouplingUMesh.New("toto",3) - m.allocateCells(0) - m.insertNextCell(NORM_POLYHED,[4,5,0,1,6,7,-1,19,18,13,12,17,16,-1,5,4,16,17,-1,0,5,17,12,-1,1,0,12,13,-1,6,1,13,18,-1,7,6,18,19,-1,4,7,19,16]) - m.insertNextCell(NORM_POLYHED,[9,10,11,3,2,8,-1,20,14,15,23,22,21,-1,10,9,21,22,-1,11,10,22,23,-1,3,11,23,15,-1,2,3,15,14,-1,8,2,14,20,-1,9,8,20,21]) - m.setCoords(coo) - m.checkCoherency1() - # - dReference=DataArrayDouble([(34.900130952189848,0.,200),(17.450065476094931,30.2244,200.)]) - self.assertTrue(m.computeIsoBarycenterOfNodesPerCell().isEqual(dReference,1e-12)) - m.getNodalConnectivity().setIJ(87,0,24) - self.assertRaises(InterpKernelException,m.computeIsoBarycenterOfNodesPerCell) - m.getNodalConnectivity().setIJ(87,0,-2) - self.assertRaises(InterpKernelException,m.computeIsoBarycenterOfNodesPerCell) - m.getNodalConnectivity().setIJ(87,0,21)# put again 21 as at the beginning - # - self.assertTrue(m.unPolyze()) - self.assertEqual([NORM_HEXGP12],m.getAllGeoTypes()) - self.assertTrue(m.computeIsoBarycenterOfNodesPerCell().isEqual(dReference,1e-12)) - m.getNodalConnectivity().setIJ(25,0,24) - self.assertRaises(InterpKernelException,m.computeIsoBarycenterOfNodesPerCell) - m.getNodalConnectivity().setIJ(25,0,-1) - self.assertRaises(InterpKernelException,m.computeIsoBarycenterOfNodesPerCell) - pass - - def testSwig2NonRegressionBugDescHexa20(self): - coo=DataArrayDouble([0.,0.,0.,1.23,0.,0.,0.615,0.,0.,0.,2.1,0.,0.615,2.1,0.,1.23,2.1,0.,1.23,1.05,0.,0.,1.05,0.,0.,0.,2.16,1.23,0.,2.16,1.23,2.1,2.16,0.,2.1,2.16,0.,0.,4.32,0.615,0.,4.32,1.23,0.,4.32,1.23,1.05,4.32,1.23,2.1,4.32,0.615,2.1,4.32,0.,2.1,4.32,0.,1.05,4.32],20,3) - m=MEDCouplingUMesh('mesh',3) - m.allocateCells(0) - m.insertNextCell(NORM_HEXA20,[0,3,5,1,12,18,16,14,7,4,6,2,19,17,15,13,8,11,10,9]) - m.setCoords(coo) - m.checkCoherency1() - # - a,b,c,d,e=m.buildDescendingConnectivity() - m2=MEDCouplingUMesh('mesh',2) - m2.allocateCells(0) - m2.setCoords(coo) - conn2=[[0,3,5,1,7,4,6,2],[12,14,16,18,13,15,17,19],[0,12,18,3,8,19,11,7],[3,18,16,5,11,17,10,4],[5,16,14,1,10,15,9,6],[1,14,12,0,9,13,8,2]] - for i in xrange(6): - m2.insertNextCell(NORM_QUAD8,conn2[i]) - pass - self.assertTrue(m2.isEqual(a,1e-12)) - self.assertTrue(b.isEqual(DataArrayInt([0,1,2,3,4,5]))) - self.assertTrue(c.isEqual(DataArrayInt([0,6]))) - self.assertTrue(d.isEqual(DataArrayInt([0,0,0,0,0,0]))) - self.assertTrue(e.isEqual(DataArrayInt([0,1,2,3,4,5,6]))) - # - m.convertQuadraticCellsToLinear() ; m.zipCoords() - m.convertLinearCellsToQuadratic(1) - # - coo2=DataArrayDouble([0.,0.,0.,1.23,0.,0.,0.,2.1,0.,1.23,2.1,0.,0.,0.,4.32,1.23,0.,4.32,1.23,2.1,4.32,0.,2.1,4.32,0.,1.05,0.,0.615,2.1,0.,1.23,1.05,0.,0.615,0.,0.,0.,1.05,4.32,0.615,2.1,4.32,1.23,1.05,4.32,0.615,0.,4.32,0.,0.,2.16,0.,2.1,2.16,1.23,2.1,2.16,1.23,0.,2.16,0.615,1.05,0.,0.,1.05,2.16,0.615,2.1,2.16,1.23,1.05,2.16,0.615,0.,2.16,0.615,1.05,4.32,0.615,1.05,2.16],27,3) - m3=MEDCouplingUMesh("mesh",3) - m3.allocateCells(1) - m3.insertNextCell(NORM_HEXA27,[0,2,3,1,4,7,6,5,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26]) - m3.setCoords(coo2) - self.assertTrue(m3.isEqual(m,1e-12)) - # - a,b,c,d,e=m.buildDescendingConnectivity() - conn4=[[0,2,3,1,8,9,10,11,20],[4,5,6,7,15,14,13,12,25],[0,4,7,2,16,12,17,8,21],[2,7,6,3,17,13,18,9,22],[3,6,5,1,18,14,19,10,23],[1,5,4,0,19,15,16,11,24]] - m4=MEDCouplingUMesh("mesh",2) - m4.allocateCells(0) - for i in xrange(6): - m4.insertNextCell(NORM_QUAD9,conn4[i]) - pass - m4.setCoords(coo2) - self.assertTrue(m4.isEqual(a,1e-12)) - self.assertTrue(b.isEqual(DataArrayInt([0,1,2,3,4,5]))) - self.assertTrue(c.isEqual(DataArrayInt([0,6]))) - self.assertTrue(d.isEqual(DataArrayInt([0,0,0,0,0,0]))) - self.assertTrue(e.isEqual(DataArrayInt([0,1,2,3,4,5,6]))) - pass - - def testSwigAdvGauss(self): - f=MEDCouplingFieldTemplate(ON_GAUSS_PT) - f.setDiscretization(None) - f.__repr__() ; f.__str__() - # - f=MEDCouplingFieldTemplate(ON_GAUSS_PT) - d=f.getDiscretization() - i=DataArrayInt() ; i.alloc(10,1) ; i.iota(1) - d.setArrayOfDiscIds(i) - f.__repr__() ; f.__str__() - i2=d.getArrayOfDiscIds() - self.assertEqual(i.__repr__(),i2.__repr__()) - # - f=MEDCouplingFieldDouble(ON_GAUSS_PT) - f.setDiscretization(None) - f.__repr__() ; f.__str__() - # - f=MEDCouplingFieldDouble(ON_GAUSS_PT) - d=f.getDiscretization() - i=DataArrayInt() ; i.alloc(10,1) ; i.iota(1) - d.setArrayOfDiscIds(i) - f.__repr__() ; f.__str__() - # - gl=MEDCouplingGaussLocalization(NORM_SEG2,[0,1],[0.5],[1.]) - gl.setWeights([3.]) - gl.__repr__() ; gl.__str__() - gl=MEDCouplingGaussLocalization(NORM_ERROR) - gl.setWeights([3.]) - gl.__repr__() ; gl.__str__() - pass - - def testSwig2NonRegressionBugSubstractInPlaceDM(self): - m0=MEDCouplingCMesh() - arr=DataArrayDouble(5,1) ; arr.iota(0.) - m0.setCoords(arr,arr) - m0=m0.buildUnstructured() - m00=m0[::2] ; m00.simplexize(0) ; m01=m0[1::2] - m0=MEDCouplingUMesh.MergeUMeshes([m00,m01]) - m0.getCoords()[:]*=1/4. - m0.setName("mesh") - # - NodeField=MEDCouplingFieldDouble(ON_NODES,ONE_TIME) ; NodeField.setTime(5.6,5,6) ; NodeField.setMesh(m0) - NodeField.setName("NodeField") - NodeField.fillFromAnalytic(1,"exp(-((x-1)*(x-1)+(y-1)*(y-1)))") ; NodeField.getArray().setInfoOnComponent(0,"powernode [W]") - proc0=m0.getCellsInBoundingBox([(0.,0.4),(0.,0.4)],1e-10) - proc1=proc0.buildComplement(m0.getNumberOfCells()) - # - NodeField0=NodeField[proc0] ; NodeField0.getMesh().setName(m0.getName()) - NodeField1=NodeField[proc1] ; NodeField1.getMesh().setName(m0.getName()) - # - NodeField_read=MEDCouplingFieldDouble.MergeFields([NodeField0,NodeField1]) - NodeField_read.mergeNodes(1e-10) - NodeFieldCpy=NodeField.deepCpy() - NodeFieldCpy.mergeNodes(1e-10) - NodeField.checkCoherency() - self.assertTrue(not NodeField.getArray().isUniform(0.,1e-12)) - NodeField.substractInPlaceDM(NodeField_read,10,1e-12) - self.assertTrue(NodeField.getArray().isUniform(0.,1e-12)) - pass - - def testSwigFieldOperationOpen1(self): - ## MEDCouplingFieldDouble.__add__ - m=MEDCouplingDataForTest.build2DTargetMesh_1() - f=MEDCouplingFieldDouble(ON_CELLS) - f.setMesh(m) - arr=DataArrayDouble(5,2) - arr[:,0]=range(5) ; arr[:,1]=2*arr[:,0] - f2=f.clone(True) - self.assertRaises(InterpKernelException,f.__add__,2) - self.assertRaises(InterpKernelException,f.__add__,range(5)) - self.assertRaises(InterpKernelException,f.__add__,arr) - self.assertRaises(InterpKernelException,f.__add__,f2) - f.setArray(DataArrayDouble()) - self.assertRaises(InterpKernelException,f.__add__,2) - self.assertRaises(InterpKernelException,f.__add__,range(5)) - self.assertRaises(InterpKernelException,f.__add__,arr) - self.assertRaises(InterpKernelException,f.__add__,f2) - self.assertRaises(InterpKernelException,f.__getitem__,(slice(None),0)) - f.getArray().alloc(5,2) - f.getArray()[:,0]=range(5) ; f.getArray()[:,1]=f.getArray()[:,0]+7 - ff=f+2 - ff.checkCoherency() - self.assertTrue(ff.getArray().isEqual(DataArrayDouble([(2,9),(3,10),(4,11),(5,12),(6,13)]),1e-12)) - ff=f+arr - ff.checkCoherency() - self.assertTrue(ff.getArray().isEqual(DataArrayDouble([(0,7),(2,10),(4,13),(6,16),(8,19)]),1e-12)) - self.assertRaises(InterpKernelException,f.__add__,f2) - f2.setArray(arr) - ff=f+f2 - ff.checkCoherency() - self.assertTrue(ff.getArray().isEqual(DataArrayDouble([(0,7),(2,10),(4,13),(6,16),(8,19)]),1e-12)) - ff=f+[5,8] - self.assertTrue(ff.getArray().isEqual(DataArrayDouble([(5,15),(6,16),(7,17),(8,18),(9,19)]),1e-12)) - ### MEDCouplingFieldDouble.__sub__ - m=MEDCouplingDataForTest.build2DTargetMesh_1() - f=MEDCouplingFieldDouble(ON_CELLS) - f.setMesh(m) - arr=DataArrayDouble(5,2) - arr[:,0]=range(5) ; arr[:,1]=2*arr[:,0] - f2=f.clone(True) - self.assertRaises(InterpKernelException,f.__sub__,2) - self.assertRaises(InterpKernelException,f.__sub__,range(5)) - self.assertRaises(InterpKernelException,f.__sub__,arr) - self.assertRaises(InterpKernelException,f.__sub__,f2) - f.setArray(DataArrayDouble()) - self.assertRaises(InterpKernelException,f.__sub__,2) - self.assertRaises(InterpKernelException,f.__sub__,range(5)) - self.assertRaises(InterpKernelException,f.__sub__,arr) - self.assertRaises(InterpKernelException,f.__sub__,f2) - self.assertRaises(InterpKernelException,f.__getitem__,(slice(None),0)) - f.getArray().alloc(5,2) - f.getArray()[:,0]=range(5) ; f.getArray()[:,1]=f.getArray()[:,0]+7 - ff=f-2 - ff.checkCoherency() - self.assertTrue(ff.getArray().isEqual(DataArrayDouble([(-2,5),(-1,6),(0,7),(1,8),(2,9)]),1e-12)) - ff=f-arr - ff.checkCoherency() - self.assertTrue(ff.getArray().isEqual(DataArrayDouble([(0,7),(0,6),(0,5),(0,4),(0,3)]),1e-12)) - self.assertRaises(InterpKernelException,f.__sub__,f2) - f2.setArray(arr) - ff=f-f2 - ff.checkCoherency() - self.assertTrue(ff.getArray().isEqual(DataArrayDouble([(0,7),(0,6),(0,5),(0,4),(0,3)]),1e-12)) - ff=f-[5,8] - self.assertTrue(ff.getArray().isEqual(DataArrayDouble([(-5,-1),(-4,0),(-3,1),(-2,2),(-1,3)]),1e-12)) - ### MEDCouplingFieldDouble.__mul__ - m=MEDCouplingDataForTest.build2DTargetMesh_1() - f=MEDCouplingFieldDouble(ON_CELLS) - f.setMesh(m) - arr=DataArrayDouble(5,2) - arr[:,0]=range(5) ; arr[:,1]=2*arr[:,0] - f2=f.clone(True) - self.assertRaises(InterpKernelException,f.__mul__,2) - self.assertRaises(InterpKernelException,f.__mul__,range(5)) - self.assertRaises(InterpKernelException,f.__mul__,arr) - self.assertRaises(InterpKernelException,f.__mul__,f2) - f.setArray(DataArrayDouble()) - self.assertRaises(InterpKernelException,f.__mul__,2) - self.assertRaises(InterpKernelException,f.__mul__,range(5)) - self.assertRaises(InterpKernelException,f.__mul__,arr) - self.assertRaises(InterpKernelException,f.__mul__,f2) - self.assertRaises(InterpKernelException,f.__getitem__,(slice(None),0)) - f.getArray().alloc(5,2) - f.getArray()[:,0]=range(5) ; f.getArray()[:,1]=f.getArray()[:,0]+7 - ff=f*2 - ff.checkCoherency() - self.assertTrue(ff.getArray().isEqual(DataArrayDouble([(0,14),(2,16),(4,18),(6,20),(8,22)]),1e-12)) - ff=f*arr - ff.checkCoherency() - self.assertTrue(ff.getArray().isEqual(DataArrayDouble([(0,0),(1,16),(4,36),(9,60),(16,88)]),1e-12)) - self.assertRaises(InterpKernelException,f.__mul__,f2) - f2.setArray(arr) - ff=f*f2 - ff.checkCoherency() - self.assertTrue(ff.getArray().isEqual(DataArrayDouble([(0,0),(1,16),(4,36),(9,60),(16,88)]),1e-12)) - ff=f*[5,8] - self.assertTrue(ff.getArray().isEqual(DataArrayDouble([(0,56),(5,64),(10,72),(15,80),(20,88)]),1e-12)) - ### MEDCouplingFieldDouble.__div__ - m=MEDCouplingDataForTest.build2DTargetMesh_1() - f=MEDCouplingFieldDouble(ON_CELLS) - f.setMesh(m) - arr=DataArrayDouble(5,2) - arr[:,0]=range(1,6) ; arr[:,1]=2*arr[:,0] - f2=f.clone(True) - self.assertRaises(InterpKernelException,f.__div__,2) - self.assertRaises(InterpKernelException,f.__div__,range(5)) - self.assertRaises(InterpKernelException,f.__div__,arr) - self.assertRaises(InterpKernelException,f.__div__,f2) - f.setArray(DataArrayDouble()) - self.assertRaises(InterpKernelException,f.__div__,2) - self.assertRaises(InterpKernelException,f.__div__,range(5)) - self.assertRaises(InterpKernelException,f.__div__,arr) - self.assertRaises(InterpKernelException,f.__div__,f2) - self.assertRaises(InterpKernelException,f.__getitem__,(slice(None),0)) - f.getArray().alloc(5,2) - f.getArray()[:,0]=range(5) ; f.getArray()[:,1]=f.getArray()[:,0]+7 - self.assertRaises(InterpKernelException,f.__div__,0) - ff=f/2 - ff.checkCoherency() - self.assertTrue(ff.getArray().isEqual(DataArrayDouble([(0,3.5),(0.5,4),(1,4.5),(1.5,5),(2,5.5)]),1e-12)) - ff=f/arr - ff.checkCoherency() - self.assertTrue(ff.getArray().isEqual(DataArrayDouble([(0,3.5),(0.5,2),(0.6666666666666666,1.5),(0.75,1.25),(0.8,1.1)]),1e-12)) - self.assertRaises(InterpKernelException,f.__div__,f2) - f2.setArray(arr) - ff=f/f2 - ff.checkCoherency() - self.assertTrue(ff.getArray().isEqual(DataArrayDouble([(0,3.5),(0.5,2),(0.6666666666666666,1.5),(0.75,1.25),(0.8,1.1)]),1e-12)) - ff=f/[5,8] - self.assertTrue(ff.getArray().isEqual(DataArrayDouble([(0,0.875),(0.2,1),(0.4,1.125),(0.6,1.25),(0.8,1.375)]),1e-12)) - ### MEDCouplingFieldDouble.__pow__ - m=MEDCouplingDataForTest.build2DTargetMesh_1() - f=MEDCouplingFieldDouble(ON_CELLS) - f.setMesh(m) - arr=DataArrayDouble(5) - arr[:]=[1,1,3,2,0] - f2=f.clone(True) - self.assertRaises(InterpKernelException,f.__div__,2) - self.assertRaises(InterpKernelException,f.__div__,range(5)) - self.assertRaises(InterpKernelException,f.__div__,arr) - self.assertRaises(InterpKernelException,f.__div__,f2) - f.setArray(DataArrayDouble()) - self.assertRaises(InterpKernelException,f.__div__,2) - self.assertRaises(InterpKernelException,f.__div__,range(5)) - self.assertRaises(InterpKernelException,f.__div__,arr) - self.assertRaises(InterpKernelException,f.__div__,f2) - self.assertRaises(InterpKernelException,f.__getitem__,(slice(None),0)) - f.getArray().alloc(5,1) - f.getArray()[:]=range(2,7) - ff=f**2 - ff.checkCoherency() - self.assertTrue(ff.getArray().isEqual(DataArrayDouble([4,9,16,25,36]),1e-12)) - ff=f**arr - ff.checkCoherency() - self.assertTrue(ff.getArray().isEqual(DataArrayDouble([2,3,64,25,1]),1e-12)) - f2.setArray(arr) - ff=f**f2 - ff.checkCoherency() - self.assertTrue(ff.getArray().isEqual(DataArrayDouble([2,3,64,25,1]),1e-12)) - ## MEDCouplingFieldDouble.__iadd__ - m=MEDCouplingDataForTest.build2DTargetMesh_1() - f=MEDCouplingFieldDouble(ON_CELLS) - f.setMesh(m) - arr=DataArrayDouble(5,2) - arr[:,0]=range(5) ; arr[:,1]=2*arr[:,0] - f2=f.clone(True) - self.assertRaises(InterpKernelException,f.__iadd__,2) - self.assertRaises(InterpKernelException,f.__iadd__,range(5)) - self.assertRaises(InterpKernelException,f.__iadd__,arr) - self.assertRaises(InterpKernelException,f.__iadd__,f2) - f.setArray(DataArrayDouble()) - self.assertRaises(InterpKernelException,f.__iadd__,2) - self.assertRaises(InterpKernelException,f.__iadd__,range(5)) - self.assertRaises(InterpKernelException,f.__iadd__,arr) - self.assertRaises(InterpKernelException,f.__iadd__,f2) - f.getArray().alloc(5,2) - f.getArray()[:,0]=range(5) ; f.getArray()[:,1]=f.getArray()[:,0]+7 - f.checkCoherency() - f+=2 - f.checkCoherency() - self.assertTrue(f.getArray().isEqual(DataArrayDouble([(2,9),(3,10),(4,11),(5,12),(6,13)]),1e-12)) - f+=arr - f.checkCoherency() - self.assertTrue(f.getArray().isEqual(DataArrayDouble([(2,9),(4,12),(6,15),(8,18),(10,21)]),1e-12)) - f2.setArray(arr) - f+=f2 - f.checkCoherency() - self.assertTrue(f.getArray().isEqual(DataArrayDouble([(2,9),(5,14),(8,19),(11,24),(14,29)]),1e-12)) - f+=[0.1,0.2] - f.checkCoherency() - self.assertTrue(f.getArray().isEqual(DataArrayDouble([(2.1,9.2),(5.1,14.2),(8.1,19.2),(11.1,24.2),(14.1,29.2)]),1e-12)) - ## MEDCouplingFieldDouble.__isub__ - m=MEDCouplingDataForTest.build2DTargetMesh_1() - f=MEDCouplingFieldDouble(ON_CELLS) - f.setMesh(m) - arr=DataArrayDouble(5,2) - arr[:,0]=range(5) ; arr[:,1]=2*arr[:,0] - f2=f.clone(True) - self.assertRaises(InterpKernelException,f.__isub__,2) - self.assertRaises(InterpKernelException,f.__isub__,range(5)) - self.assertRaises(InterpKernelException,f.__isub__,arr) - self.assertRaises(InterpKernelException,f.__isub__,f2) - f.setArray(DataArrayDouble()) - self.assertRaises(InterpKernelException,f.__isub__,2) - self.assertRaises(InterpKernelException,f.__isub__,range(5)) - self.assertRaises(InterpKernelException,f.__isub__,arr) - self.assertRaises(InterpKernelException,f.__isub__,f2) - f.getArray().alloc(5,2) - f.getArray()[:,0]=range(5) ; f.getArray()[:,1]=f.getArray()[:,0]+7 - f.checkCoherency() - f-=2 - f.checkCoherency() - self.assertTrue(f.getArray().isEqual(DataArrayDouble([(-2,5),(-1,6),(0,7),(1,8),(2,9)]),1e-12)) - f-=arr - f.checkCoherency() - self.assertTrue(f.getArray().isEqual(DataArrayDouble([(-2,5),(-2,4),(-2,3),(-2,2),(-2,1)]),1e-12)) - f2.setArray(arr) - f-=f2 - f.checkCoherency() - self.assertTrue(f.getArray().isEqual(DataArrayDouble([(-2,5),(-3,2),(-4,-1),(-5,-4),(-6,-7)]),1e-12)) - f-=[0.1,0.2] - f.checkCoherency() - self.assertTrue(f.getArray().isEqual(DataArrayDouble([(-2.1,4.8),(-3.1,1.8),(-4.1,-1.2),(-5.1,-4.2),(-6.1,-7.2)]),1e-12)) - ## MEDCouplingFieldDouble.__imul__ - m=MEDCouplingDataForTest.build2DTargetMesh_1() - f=MEDCouplingFieldDouble(ON_CELLS) - f.setMesh(m) - arr=DataArrayDouble(5,2) - arr[:,0]=range(5) ; arr[:,1]=2*arr[:,0] - f2=f.clone(True) - self.assertRaises(InterpKernelException,f.__imul__,2) - self.assertRaises(InterpKernelException,f.__imul__,range(5)) - self.assertRaises(InterpKernelException,f.__imul__,arr) - self.assertRaises(InterpKernelException,f.__imul__,f2) - f.setArray(DataArrayDouble()) - self.assertRaises(InterpKernelException,f.__imul__,2) - self.assertRaises(InterpKernelException,f.__imul__,range(5)) - self.assertRaises(InterpKernelException,f.__imul__,arr) - self.assertRaises(InterpKernelException,f.__imul__,f2) - f.getArray().alloc(5,2) - f.getArray()[:,0]=range(5) ; f.getArray()[:,1]=f.getArray()[:,0]+7 - f.checkCoherency() - f*=2 - f.checkCoherency() - self.assertTrue(f.getArray().isEqual(DataArrayDouble([(0,14),(2,16),(4,18),(6,20),(8,22)]),1e-12)) - f*=arr - f.checkCoherency() - self.assertTrue(f.getArray().isEqual(DataArrayDouble([(0,0),(2,32),(8,72),(18,120),(32,176)]),1e-12)) - f2.setArray(arr) - f*=f2 - f.checkCoherency() - self.assertTrue(f.getArray().isEqual(DataArrayDouble([(0,0),(2,64),(16,288),(54,720),(128,1408)]),1e-12)) - f*=[0.1,0.2] - f.checkCoherency() - self.assertTrue(f.getArray().isEqual(DataArrayDouble([(0,0),(0.2,12.8),(1.6,57.6),(5.4,144),(12.8,281.6)]),1e-12)) - ## MEDCouplingFieldDouble.__idiv__ - m=MEDCouplingDataForTest.build2DTargetMesh_1() - f=MEDCouplingFieldDouble(ON_CELLS) - f.setMesh(m) - arr=DataArrayDouble(5,2) - arr[:,0]=range(1,6) ; arr[:,1]=2*arr[:,0] - f2=f.clone(True) - self.assertRaises(InterpKernelException,f.__idiv__,2) - self.assertRaises(InterpKernelException,f.__idiv__,range(5)) - self.assertRaises(InterpKernelException,f.__idiv__,arr) - self.assertRaises(InterpKernelException,f.__idiv__,f2) - f.setArray(DataArrayDouble()) - self.assertRaises(InterpKernelException,f.__idiv__,2) - self.assertRaises(InterpKernelException,f.__idiv__,range(5)) - self.assertRaises(InterpKernelException,f.__idiv__,arr) - self.assertRaises(InterpKernelException,f.__idiv__,f2) - f.getArray().alloc(5,2) - f.getArray()[:,0]=range(5) ; f.getArray()[:,1]=f.getArray()[:,0]+7 - f.checkCoherency() - f/=2 - f.checkCoherency() - self.assertTrue(f.getArray().isEqual(DataArrayDouble([(0,3.5),(0.5,4),(1,4.5),(1.5,5),(2,5.5)]),1e-12)) - f/=arr - f.checkCoherency() - self.assertTrue(f.getArray().isEqual(DataArrayDouble([(0,1.75),(0.25,1),(0.3333333333333333,0.75),(0.375,0.625),(0.4,0.55)]),1e-12)) - f2.setArray(arr) - f/=f2 - f.checkCoherency() - self.assertTrue(f.getArray().isEqual(DataArrayDouble([(0,0.875),(0.125,0.25),(0.1111111111111111,0.125),(0.09375,0.078125),(0.08,0.055)]),1e-12)) - f/=[0.1,0.2] - f.checkCoherency() - self.assertTrue(f.getArray().isEqual(DataArrayDouble([(0,4.375),(1.25,1.25),(1.1111111111111111,0.625),(0.9375,0.390625),(0.8,0.275)]),1e-12)) - ## MEDCouplingFieldDouble.__ipow__ - m=MEDCouplingDataForTest.build2DTargetMesh_1() - f=MEDCouplingFieldDouble(ON_CELLS) - f.setMesh(m) - arr=DataArrayDouble(5,2) - arr[:,0]=range(1,6) ; arr[:,1]=2*arr[:,0] - f2=f.clone(True) - self.assertRaises(InterpKernelException,f.__ipow__,2) - self.assertRaises(InterpKernelException,f.__ipow__,range(5)) - self.assertRaises(InterpKernelException,f.__ipow__,arr) - self.assertRaises(InterpKernelException,f.__ipow__,f2) - f.setArray(DataArrayDouble()) - self.assertRaises(InterpKernelException,f.__ipow__,2) - self.assertRaises(InterpKernelException,f.__ipow__,range(5)) - self.assertRaises(InterpKernelException,f.__ipow__,arr) - self.assertRaises(InterpKernelException,f.__ipow__,f2) - f.getArray().alloc(5,2) - f.getArray()[:,0]=range(5) ; f.getArray()[:,1]=f.getArray()[:,0]+7 - f.checkCoherency() - f**=2 - f.checkCoherency() - self.assertTrue(f.getArray().isEqual(DataArrayDouble([(0,49),(1,64),(4,81),(9,100),(16,121)]),1e-12)) - ## MEDCouplingFieldDouble.__radd__ - m=MEDCouplingDataForTest.build2DTargetMesh_1() - f=MEDCouplingFieldDouble(ON_CELLS) - f.setMesh(m) - arr=DataArrayDouble(5,2) - arr[:,0]=range(5) ; arr[:,1]=2*arr[:,0] - f2=f.clone(True) - self.assertRaises(InterpKernelException,f.__radd__,2) - self.assertRaises(InterpKernelException,f.__radd__,range(5)) - self.assertRaises(InterpKernelException,f.__radd__,arr) - self.assertRaises(InterpKernelException,f.__radd__,f2) - f.setArray(DataArrayDouble()) - self.assertRaises(InterpKernelException,f.__radd__,2) - self.assertRaises(InterpKernelException,f.__radd__,range(5)) - self.assertRaises(InterpKernelException,f.__radd__,arr) - self.assertRaises(InterpKernelException,f.__radd__,f2) - self.assertRaises(InterpKernelException,f.__getitem__,(slice(None),0)) - f.getArray().alloc(5,2) - f.getArray()[:,0]=range(5) ; f.getArray()[:,1]=f.getArray()[:,0]+7 - ff=2+f - ff.checkCoherency() - self.assertTrue(ff.getArray().isEqual(DataArrayDouble([(2,9),(3,10),(4,11),(5,12),(6,13)]),1e-12)) - ff=arr+f - ff.checkCoherency() - self.assertTrue(ff.getArray().isEqual(DataArrayDouble([(0,7),(2,10),(4,13),(6,16),(8,19)]),1e-12)) - self.assertRaises(InterpKernelException,f.__radd__,f2) - ff=[5,8]+f - self.assertTrue(ff.getArray().isEqual(DataArrayDouble([(5,15),(6,16),(7,17),(8,18),(9,19)]),1e-12)) - ### MEDCouplingFieldDouble.__rsub__ - m=MEDCouplingDataForTest.build2DTargetMesh_1() - f=MEDCouplingFieldDouble(ON_CELLS) - f.setMesh(m) - arr=DataArrayDouble(5,2) - arr[:,0]=range(5) ; arr[:,1]=2*arr[:,0] - f2=f.clone(True) - self.assertRaises(InterpKernelException,f.__rsub__,2) - self.assertRaises(InterpKernelException,f.__rsub__,range(5)) - self.assertRaises(InterpKernelException,f.__rsub__,arr) - self.assertRaises(InterpKernelException,f.__rsub__,f2) - f.setArray(DataArrayDouble()) - self.assertRaises(InterpKernelException,f.__rsub__,2) - self.assertRaises(InterpKernelException,f.__rsub__,range(5)) - self.assertRaises(InterpKernelException,f.__rsub__,arr) - self.assertRaises(InterpKernelException,f.__rsub__,f2) - self.assertRaises(InterpKernelException,f.__getitem__,(slice(None),0)) - f.getArray().alloc(5,2) - f.getArray()[:,0]=range(5) ; f.getArray()[:,1]=f.getArray()[:,0]+7 - ff=2-f - ff.checkCoherency() - self.assertTrue(ff.getArray().isEqual(DataArrayDouble([(2,-5),(1,-6),(0,-7),(-1,-8),(-2,-9)]),1e-12)) - ff=arr-f - ff.checkCoherency() - self.assertTrue(ff.getArray().isEqual(DataArrayDouble([(0,-7),(0,-6),(0,-5),(0,-4),(0,-3)]),1e-12)) - self.assertRaises(InterpKernelException,f.__rsub__,f2) - ### MEDCouplingFieldDouble.__rmul__ - m=MEDCouplingDataForTest.build2DTargetMesh_1() - f=MEDCouplingFieldDouble(ON_CELLS) - f.setMesh(m) - arr=DataArrayDouble(5,2) - arr[:,0]=range(5) ; arr[:,1]=2*arr[:,0] - f2=f.clone(True) - self.assertRaises(InterpKernelException,f.__rmul__,2) - self.assertRaises(InterpKernelException,f.__rmul__,range(5)) - self.assertRaises(InterpKernelException,f.__rmul__,arr) - self.assertRaises(InterpKernelException,f.__rmul__,f2) - f.setArray(DataArrayDouble()) - self.assertRaises(InterpKernelException,f.__rmul__,2) - self.assertRaises(InterpKernelException,f.__rmul__,range(5)) - self.assertRaises(InterpKernelException,f.__rmul__,arr) - self.assertRaises(InterpKernelException,f.__rmul__,f2) - self.assertRaises(InterpKernelException,f.__getitem__,(slice(None),0)) - f.getArray().alloc(5,2) - f.getArray()[:,0]=range(5) ; f.getArray()[:,1]=f.getArray()[:,0]+7 - ff=2*f - ff.checkCoherency() - self.assertTrue(ff.getArray().isEqual(DataArrayDouble([(0,14),(2,16),(4,18),(6,20),(8,22)]),1e-12)) - ff=arr*f - ff.checkCoherency() - self.assertTrue(ff.getArray().isEqual(DataArrayDouble([(0,0),(1,16),(4,36),(9,60),(16,88)]),1e-12)) - self.assertRaises(InterpKernelException,f.__rmul__,f2) - ff=f*[5,8] - self.assertTrue(ff.getArray().isEqual(DataArrayDouble([(0,56),(5,64),(10,72),(15,80),(20,88)]),1e-12)) - ### MEDCouplingFieldDouble.__rdiv__ - m=MEDCouplingDataForTest.build2DTargetMesh_1() - f=MEDCouplingFieldDouble(ON_CELLS) - f.setMesh(m) - arr=DataArrayDouble(5,2) - arr[:,0]=range(1,6) ; arr[:,1]=2*arr[:,0] - f2=f.clone(True) - self.assertRaises(InterpKernelException,f.__rdiv__,2) - self.assertRaises(InterpKernelException,f.__rdiv__,range(5)) - self.assertRaises(InterpKernelException,f.__rdiv__,arr) - self.assertRaises(InterpKernelException,f.__rdiv__,f2) - f.setArray(DataArrayDouble()) - self.assertRaises(InterpKernelException,f.__rdiv__,2) - self.assertRaises(InterpKernelException,f.__rdiv__,range(5)) - self.assertRaises(InterpKernelException,f.__rdiv__,arr) - self.assertRaises(InterpKernelException,f.__rdiv__,f2) - self.assertRaises(InterpKernelException,f.__getitem__,(slice(None),0)) - f.getArray().alloc(5,2) - f.getArray()[:,0]=range(1,6) ; f.getArray()[:,1]=f.getArray()[:,0]+7 - ff=2/f - ff.checkCoherency() - self.assertTrue(ff.getArray().isEqual(DataArrayDouble([(2,0.25),(1,0.22222222222222221),(0.66666666666666663,0.20000000000000001),(0.5,0.18181818181818182),(0.40000000000000002,0.16666666666666666)]),1e-12)) - ff=arr/f - ff.checkCoherency() - self.assertTrue(ff.getArray().isEqual(DataArrayDouble([(1,0.25),(1,0.44444444444444442),(1,0.59999999999999998),(1,0.72727272727272729),(1,0.83333333333333337)]),1e-12)) - self.assertRaises(InterpKernelException,f.__rdiv__,f2) - pass - - def testSwig2FieldDoubleBuildSubPartRange1(self): - #ON_CELLS - m=MEDCouplingDataForTest.build2DTargetMesh_1() - f=MEDCouplingFieldDouble(ON_CELLS) - f.setMesh(m) - arr=DataArrayDouble(5,2) ; arr[:,0]=range(7,12) ; arr[:,1]=100+arr[:,0] - f.setArray(arr) - f.checkCoherency() - ff=f[1:-1:2] - ff.checkCoherency() - self.assertTrue((m.buildPartOfMySelf([1,3],True)).isEqual(ff.getMesh(),1e-12)) - self.assertTrue(9,ff.getMesh().getNumberOfNodes()) - self.assertTrue(2,ff.getMesh().getNumberOfCells()) - self.assertTrue(ff.getArray().isEqual(arr[[1,3]],1e-12)) - # - a,b=f.buildSubMeshDataRange(2,5,1) - self.assertTrue(m.buildPartOfMySelf([2,3,4],True).isEqual(a,1e-12)) - self.assertEqual(b,slice(2,5,1)) - ff=f[2:] - ff.checkCoherency() - self.assertTrue((m.buildPartOfMySelf([2,3,4],True)).isEqual(ff.getMesh(),1e-12)) - self.assertTrue(9,ff.getMesh().getNumberOfNodes()) - self.assertTrue(3,ff.getMesh().getNumberOfCells()) - self.assertTrue(ff.getArray().isEqual(arr[[2,3,4]],1e-12)) - # - ff=f[-2:0:-1] - ff.checkCoherency() - self.assertTrue((m.buildPartOfMySelf([3,2,1],True)).isEqual(ff.getMesh(),1e-12)) - self.assertTrue(9,ff.getMesh().getNumberOfNodes()) - self.assertTrue(3,ff.getMesh().getNumberOfCells()) - self.assertTrue(ff.getArray().isEqual(arr[[3,2,1]],1e-12)) - self.assertTrue(f[-2:0:-1,1].getArray().isEqual(arr[[3,2,1],1],1e-12)) - #ON_NODES - f=MEDCouplingFieldDouble(ON_NODES) - f.setMesh(m) - arr=DataArrayDouble(9,2) ; arr[:,0]=range(7,16) ; arr[:,1]=100+arr[:,0] - f.setArray(arr) - f.checkCoherency() - ff=f[1:-1:2] - ff.checkCoherency() - self.assertTrue((m.buildPartOfMySelf([1,3],False)).isEqual(ff.getMesh(),1e-12)) - self.assertTrue(6,ff.getMesh().getNumberOfNodes()) - self.assertTrue(2,ff.getMesh().getNumberOfCells()) - self.assertTrue(ff.getArray().isEqual(arr[[1,2,3,4,6,7]],1e-12)) - # - m2=m.buildPartRange(2,5,1) - self.assertTrue(m.buildPartOfMySelf([2,3,4],True).isEqual(m2,1e-12)) - m2,b=m.buildPartRangeAndReduceNodes(2,5,1) - self.assertTrue(m.buildPartOfMySelf([2,3,4],False).isEqual(m2,1e-12)) - self.assertTrue(b.isEqual(DataArrayInt([-1,-1,0,1,2,3,4,5,6]))) - a,b=f.buildSubMeshDataRange(2,5,1) - self.assertTrue(m.buildPartOfMySelf([2,3,4],False).isEqual(a,1e-12)) - self.assertTrue(b.isEqual(DataArrayInt([2,3,4,5,6,7,8]))) - ff=f[2:] - ff.checkCoherency() - self.assertTrue((m.buildPartOfMySelf([2,3,4],False)).isEqual(ff.getMesh(),1e-12)) - self.assertTrue(7,ff.getMesh().getNumberOfNodes()) - self.assertTrue(3,ff.getMesh().getNumberOfCells()) - self.assertTrue(ff.getArray().isEqual(arr[[2,3,4,5,6,7,8]],1e-12)) - # - ff=f[-2:0:-1] - ff.checkCoherency() - self.assertTrue((m.buildPartOfMySelf([3,2,1],False)).isEqual(ff.getMesh(),1e-12)) - self.assertTrue(7,ff.getMesh().getNumberOfNodes()) - self.assertTrue(3,ff.getMesh().getNumberOfCells()) - self.assertTrue(ff.getArray().isEqual(arr[[1,2,3,4,5,6,7]],1e-12)) - self.assertTrue(f[-2:0:-1,1].getArray().isEqual(arr[[1,2,3,4,5,6,7],1],1e-12)) - #ON_GAUSS_NE - f=MEDCouplingFieldDouble(ON_GAUSS_NE) - f.setMesh(m) - arr=DataArrayDouble(18,2) ; arr[:,0]=range(7,25) ; arr[:,1]=100+arr[:,0] - f.setArray(arr) - f.checkCoherency() - ff=f[1:-1:2] - ff.checkCoherency() - self.assertTrue((m.buildPartOfMySelf([1,3],True)).isEqual(ff.getMesh(),1e-12)) - self.assertTrue(9,ff.getMesh().getNumberOfNodes()) - self.assertTrue(2,ff.getMesh().getNumberOfCells()) - self.assertTrue(ff.getArray().isEqual(arr[[4,5,6,10,11,12,13]],1e-12)) - # - a,b=f.buildSubMeshDataRange(2,5,1) - self.assertTrue(m.buildPartOfMySelf([2,3,4],True).isEqual(a,1e-12)) - self.assertEqual(b,slice(7,18,1)) - ff=f[2:] - ff.checkCoherency() - self.assertTrue((m.buildPartOfMySelf([2,3,4],True)).isEqual(ff.getMesh(),1e-12)) - self.assertTrue(9,ff.getMesh().getNumberOfNodes()) - self.assertTrue(3,ff.getMesh().getNumberOfCells()) - self.assertTrue(ff.getArray().isEqual(arr[[7,8,9,10,11,12,13,14,15,16,17]],1e-12)) - # - ff=f[-2:0:-1] - ff.checkCoherency() - self.assertTrue((m.buildPartOfMySelf([3,2,1],True)).isEqual(ff.getMesh(),1e-12)) - self.assertTrue(9,ff.getMesh().getNumberOfNodes()) - self.assertTrue(3,ff.getMesh().getNumberOfCells()) - self.assertTrue(ff.getArray().isEqual(arr[[10,11,12,13,7,8,9,4,5,6]],1e-12)) - self.assertTrue(f[-2:0:-1,1].getArray().isEqual(arr[[10,11,12,13,7,8,9,4,5,6],1],1e-12)) - #ON_GAUSS_PT - f=MEDCouplingFieldDouble(ON_GAUSS_PT) - f.setMesh(m) - f.setGaussLocalizationOnCells([0,4],[0,0,1,0,1,1,1,0],[1.1,1.1,2.2,2.2],[0.2,0.8]); - f.setGaussLocalizationOnCells([3],[0,0,1,0,1,1,1,0],[1.1,1.1,2.2,2.2,3.,3.],[0.2,0.4,0.4]); - f.setGaussLocalizationOnCells([1],[0,0,1,0,1,0],[1.1,1.1,2.2,2.2,3.,3.,4.,4.],[0.1,0.1,0.4,0.4]); - f.setGaussLocalizationOnCells([2],[0,0,1,0,1,0],[1.1,1.1,2.2,2.2,3.,3.,4.,4.,5.,5.],[0.1,0.1,0.4,0.3,0.1]); - arr=DataArrayDouble(16,2) ; arr[:,0]=range(7,23) ; arr[:,1]=100+arr[:,0] - f.setArray(arr) - f.checkCoherency() - ff=f[1:-1:2] - ff.checkCoherency() - self.assertTrue((m.buildPartOfMySelf([1,3],True)).isEqual(ff.getMesh(),1e-12)) - self.assertTrue(9,ff.getMesh().getNumberOfNodes()) - self.assertTrue(2,ff.getMesh().getNumberOfCells()) - self.assertTrue(ff.getArray().isEqual(arr[[2,3,4,5,11,12,13]],1e-12)) - # - a,b=f.buildSubMeshDataRange(2,5,1) - self.assertTrue(m.buildPartOfMySelf([2,3,4],True).isEqual(a,1e-12)) - self.assertEqual(b,slice(6,16,1)) - ff=f[2:] - ff.checkCoherency() - self.assertTrue((m.buildPartOfMySelf([2,3,4],True)).isEqual(ff.getMesh(),1e-12)) - self.assertTrue(9,ff.getMesh().getNumberOfNodes()) - self.assertTrue(3,ff.getMesh().getNumberOfCells()) - self.assertTrue(ff.getArray().isEqual(arr[[6,7,8,9,10,11,12,13,14,15]],1e-12)) - # - ff=f[-2:0:-1] - ff.checkCoherency() - self.assertTrue((m.buildPartOfMySelf([3,2,1],True)).isEqual(ff.getMesh(),1e-12)) - self.assertTrue(9,ff.getMesh().getNumberOfNodes()) - self.assertTrue(3,ff.getMesh().getNumberOfCells()) - self.assertTrue(ff.getArray().isEqual(arr[[11,12,13,6,7,8,9,10,2,3,4,5]],1e-12)) - self.assertTrue(f[-2:0:-1,0].getArray().isEqual(arr[[11,12,13,6,7,8,9,10,2,3,4,5],0],1e-12)) - pass - - def testSwig2FieldDoubleApplyFuncBug1(self): - f=MEDCouplingFieldDouble(ON_CELLS) - f.setMesh(MEDCouplingDataForTest.build2DTargetMesh_1()) - f.applyFunc(3,700.) - f.checkCoherency() - self.assertEqual(3,f.getArray().getNumberOfComponents()) - f.getArray().rearrange(1) - self.assertTrue(f.getArray().isUniform(700.,1e-10)) - f.getArray().rearrange(3) - f.checkCoherency() - f.applyFunc(4,800.) - f.checkCoherency() - self.assertEqual(4,f.getArray().getNumberOfComponents()) - f.getArray().rearrange(1) - self.assertTrue(f.getArray().isUniform(800.,1e-10)) - f.getArray().rearrange(4) - f.checkCoherency() - pass - - def testSwig2ComputeTupleIdsNearTupleBug1(self): - coords=[1.1,0.0, 1.1,0.0 ]; - coordsArr=DataArrayDouble(coords,2,2); - mesh=MEDCouplingUMesh(); - mesh.setCoords(coordsArr); - points=[1.1, 0.002] - c,cI=mesh.getNodeIdsNearPoints(points,0.00185); - self.assertTrue(c.isEqual(DataArrayInt([]))) - self.assertTrue(cI.isEqual(DataArrayInt([0,0]))) - c,cI=mesh.getNodeIdsNearPoints(points,0.00200000000000001); - self.assertTrue(c.isEqual(DataArrayInt([0,1]))) - self.assertTrue(cI.isEqual(DataArrayInt([0,2]))) - pass - - def testSwig2NonRegressionBugChangeUnderlyingWithZeroCells(self): - coords1=[0.,1.,2.,3.] - coords2=[2.,1.,0.,3.] #0 <==> #2 - # mesh 1 - mesh1=MEDCouplingUMesh.New(); - coordsArr=DataArrayDouble.New(coords1,4,1); - mesh1.setCoords(coordsArr); - mesh1.setMeshDimension(0); - mesh1.allocateCells(0); - mesh1.finishInsertingCells(); - # mesh 2 - mesh2=mesh1.deepCpy(); - coordsArr=DataArrayDouble.New(coords2,4,1); - mesh2.setCoords(coordsArr); - field = mesh1.fillFromAnalytic(ON_NODES,1,"x") - field.checkCoherency() - levOfCheck = 10 - field.changeUnderlyingMesh( mesh2, levOfCheck, 1e-13, 0 ) - self.assertTrue( field.getArray().getValues() == coords2 ) - pass - - def testSwig2UMeshDistanceToMesh2(self): - sz=5 - m=MEDCouplingCMesh() - arr=DataArrayDouble(sz+1) ; arr.iota() ; arr/=sz - m.setCoords(arr,arr,arr) - m=m.buildUnstructured() - m1=m.computeSkin() - m1.zipCoords() - c=m1.getCoords()[:] - d=2*(c-[0.5,0.5,0.5])+[0.5,0.5,0.5] - time_deb = datetime.now() - #print "go.." - a,b=m1.distanceToPoints(d) - #print 'time spent in distanceToPoints %s ' %str(datetime.now() - time_deb) - time_deb = datetime.now() - a1=DataArrayDouble(len(d)) - b1=DataArrayInt(len(d)) - m1s=[m1[i] for i in xrange(m1.getNumberOfCells())] - for j,pt in enumerate(d): - eter=1e308 - fter=-1 - for i,miter in enumerate(m1s): - e,f=miter.distanceToPoint(pt) - self.assertEqual(0,f) - if e start of specific part of the test - a,b,c,d = MEDCouplingUMesh.Intersect2DMeshWith1DLine(m1, m2, 1e-10) - self.assertTrue(a.getNodalConnectivity().isEqual(DataArrayInt([4,2,1,4,5,32,0,3,11,7,10,14,15,16,17,18,32,4,1,10,7,11,19,20,21,22,23]))) - self.assertTrue(a.getNodalConnectivityIndex().isEqual(DataArrayInt([0,5,16,27]))) - self.assertTrue(b.getNodalConnectivity().isEqual(DataArrayInt([1,6,10,1,10,7,2,7,11,12,2,11,8,13]))) - self.assertTrue(b.getNodalConnectivityIndex().isEqual(DataArrayInt([0,3,6,10,14]))) - self.assertTrue(a.getCoords().getHiddenCppPointer()==b.getCoords().getHiddenCppPointer()) - self.assertTrue(a.getCoords()[:6].isEqual(m1.getCoords(),1e-12)) - self.assertTrue(a.getCoords()[6:10].isEqual(m2.getCoords(),1e-12)) - self.assertTrue(a.getCoords()[10:].isEqual(DataArrayDouble([(0.,0.),(0.5164175471673584,2.),(0.3796918047064557,1.43726403104512),(0.3796918047064557,2.56273596895488),(-1.,1.),(-0.24179122641632078,2.),(0.3796918047064558,1.4372640310451201),(0.,0.5),(-0.5,0.),(1.,1.),(0.5,0.),(0.,0.5),(0.3796918047064558,1.4372640310451201),(0.7582087735836792,2.)]),1e-12)) - self.assertTrue(c.isEqual(DataArrayInt([1,0,0]))) - self.assertTrue(d.isEqual(DataArrayInt([(-1,-1),(1,2),(1,2),(-1,-1)]))) - pass - - def testSwig2Intersect2DMeshWith1DLine7(self): - """ Star pattern (a triangle intersecting another one upside down) """ - coords1 = DataArrayDouble([-2.,1., 2.,1., 0.,-2.], 3,2) - coords2 = DataArrayDouble([0.,2., 2.,-1., -2.,-1., 0.,3.], 4,2) - m1 = MEDCouplingUMesh("triangle", 2) - m2 = MEDCouplingUMesh("tri_line", 1) - m1.setCoords(coords1) - m2.setCoords(coords2) - m1.setConnectivity(DataArrayInt([NORM_TRI3, 0,1,2]), DataArrayInt([0,4])) - m2.setConnectivity(DataArrayInt([NORM_SEG2,0,1,NORM_SEG2,1,2,NORM_SEG2,2,3]), DataArrayInt([0,3,6,9])) - # End of construction of input meshes m1bis and m2 -> start of specific part of the test - a,b,c,d = MEDCouplingUMesh.Intersect2DMeshWith1DLine(m1, m2, 1e-10) - self.assertTrue(a.getNodalConnectivity().isEqual(DataArrayInt([5,1,9,7,5,2,11,10,5,0,8,12,5,7,9,10,11,12,8]))) - self.assertTrue(a.getNodalConnectivityIndex().isEqual(DataArrayInt([0,4,8,12,19]))) - self.assertTrue(b.getNodalConnectivity().isEqual(DataArrayInt([1,3,7,1,7,9,1,9,4,1,4,10,1,10,11,1,11,5,1,5,12,1,12,8,1,8,6]))) - self.assertTrue(b.getNodalConnectivityIndex().isEqual(DataArrayInt([0,3,6,9,12,15,18,21,24,27]))) - self.assertTrue(a.getCoords()[:3].isEqual(m1.getCoords(),1e-12)) - self.assertTrue(a.getCoords()[3:7].isEqual(m2.getCoords(),1e-12)) - self.assertTrue(a.getCoords()[7:].isEqual(DataArrayDouble([(0.6666666666666666,1.),(-1.,1.),(1.3333333333333333,1.1102230246251565e-16),(0.6666666666666665,-0.9999999999999996),(-0.6666666666666667,-1.),(-1.4285714285714284,0.14285714285714302)]),1e-12)) - self.assertTrue(a.getCoords().getHiddenCppPointer()==b.getCoords().getHiddenCppPointer()) - self.assertTrue(c.isEqual(DataArrayInt([0,0,0,0]))) - self.assertTrue(d.isEqual(DataArrayInt([(-1,-1),(0,3),(-1,-1),(-1,-1),(1,3),(-1,-1),(-1,-1),(2,3),(-1,-1)]))) - pass - - def testSwig2Intersect2DMeshWith1DLine8(self): - """ Line pieces ending (or fully located) in the middle of a cell """ - m1c = MEDCouplingCMesh() - m1c.setCoordsAt(0,DataArrayDouble([-1., 1.])) - m1c.setCoordsAt(1,DataArrayDouble([-1., 1.])); - m1 = m1c.buildUnstructured() - coords2 = DataArrayDouble([0.,0., 0.,1.5, -1.5,0., 0.5,0.0, 0.0,-0.5, 1.1,-0.6], 6,2) - m2 = MEDCouplingUMesh("piecewise_line", 1) - m2.setCoords(coords2) - c = DataArrayInt([NORM_SEG2,2,1, NORM_SEG2,1,4, NORM_SEG2,4,3, NORM_SEG2,3,5]) - cI = DataArrayInt([0,3,6,9,12]) - m2.setConnectivity(c, cI) - a,b,c,d = MEDCouplingUMesh.Intersect2DMeshWith1DLine(m1, m2, 1e-10) - self.assertTrue(a.getNodalConnectivity().isEqual(DataArrayInt([5,2,11,10,5,3,13,7,8,12,5,1,0,10,11,12,8,7,13]))) - self.assertTrue(a.getNodalConnectivityIndex().isEqual(DataArrayInt([0,4,10,19]))) - self.assertTrue(b.getNodalConnectivity().isEqual(DataArrayInt([1,6,10,1,10,11,1,11,5,1,5,12,1,12,8,1,8,7,1,7,13,1,13,9]))) - self.assertTrue(b.getNodalConnectivityIndex().isEqual(DataArrayInt([0,3,6,9,12,15,18,21,24]))) - self.assertTrue(a.getCoords()[:4].isEqual(m1.getCoords(),1e-12)) - self.assertTrue(a.getCoords()[4:10].isEqual(m2.getCoords(),1e-12)) - self.assertTrue(a.getCoords()[10:].isEqual(DataArrayDouble([(-1.,0.5),(-0.5,1.),(0.,1.),(1.,-0.5)]),1e-12)) - self.assertTrue(a.getCoords().getHiddenCppPointer()==b.getCoords().getHiddenCppPointer()) - self.assertTrue(c.isEqual(DataArrayInt([0,0,0]))) - self.assertTrue(d.isEqual(DataArrayInt([(-1,-1),(0,2),(-1,-1),(-1,-1),(1,2),(1,2),(1,2),(-1,-1)]))) - pass - - def testSwig2Intersect2DMeshWith1DLine9(self): - """ Intersection with a line whose connectivity is not consecutive """ - m1c = MEDCouplingCMesh() - coordX = DataArrayDouble([-1., 1., 2]) - m1c.setCoordsAt(0,coordX) - coordY = DataArrayDouble([0., 2.]) - m1c.setCoordsAt(1,coordY); - m1 = m1c.buildUnstructured() - # A simple line: - m2 = MEDCouplingUMesh("bla", 1) - coord2 = DataArrayDouble([0.,1.5, 0.5,1., 0.0,0.5, 0.0,3.0, 0.0,-1.0], 5, 2) - conn2 = DataArrayInt([NORM_SEG2,3,0,NORM_SEG3,0,2,1,NORM_SEG2,2,4]) - connI2 = DataArrayInt([0,3,7,10]) - m2.setCoords(coord2) - m2.setConnectivity(conn2, connI2) - # End of construction of input meshes m1bis and m2 -> start of specific part of the test - a,b,c,d = MEDCouplingUMesh.Intersect2DMeshWith1DLine(m1, m2, 1e-10) - self.assertTrue(a.getNodalConnectivity().isEqual(DataArrayInt([4,2,1,4,5,32,4,1,11,8,6,12,14,15,16,17,18,19,32,0,3,12,6,8,11,20,21,22,23,24,25]))) - self.assertTrue(a.getNodalConnectivityIndex().isEqual(DataArrayInt([0,5,18,31]))) - self.assertTrue(b.getNodalConnectivity().isEqual(DataArrayInt([1,9,12,1,12,6,2,6,8,13,1,8,11,1,11,10]))) - self.assertTrue(b.getNodalConnectivityIndex().isEqual(DataArrayInt([0,3,6,10,13,16]))) - self.assertTrue(a.getCoords()[:6].isEqual(m1.getCoords(),1e-12)) - self.assertTrue(a.getCoords()[6:11].isEqual(m2.getCoords(),1e-12)) - self.assertTrue(a.getCoords()[11:].isEqual(DataArrayDouble([(0.,0.),(0.,2.),(0.5,1.),(1.,1.),(0.5,0.),(0.,0.25),(0.5,1.),(0.,1.75),(0.5,2.),(-1.,1.),(-0.5,2.),(0.,1.75),(0.5,1.),(0.,0.25),(-0.5,0.)]),1e-12)) - self.assertTrue(a.getCoords().getHiddenCppPointer()==b.getCoords().getHiddenCppPointer()) - self.assertTrue(c.isEqual(DataArrayInt([1,0,0]))) - self.assertTrue(d.isEqual(DataArrayInt([(-1,-1),(1,2),(1,2),(1,2),(-1,-1)]))) - pass - - def testSwig2Intersect2DMeshWith1DLine10(self): - """ Intersection between a circle and various lines """ - eps = 1.0e-8 - m_circ = MEDCouplingDataForTest.buildCircle2(0.0, 0.0, 2.0) - coords = [0.0,3.0,0.0,-3.0] - connec = [0,1] - m_line = MEDCouplingUMesh("seg", 1) - m_line.allocateCells(1) - meshCoords = DataArrayDouble.New(coords, len(coords)/2, 2) - m_line.setCoords(meshCoords) - m_line.insertNextCell(NORM_SEG2, connec) - a, b, c, d = MEDCouplingUMesh.Intersect2DMeshWith1DLine(m_circ, m_line, eps) - self.assertTrue(a.getCoords().getHiddenCppPointer()==b.getCoords().getHiddenCppPointer()) - self.assertTrue(a.getCoords()[:m_circ.getNumberOfNodes()].isEqual(m_circ.getCoords(),1e-12)) - self.assertTrue(a.getCoords()[m_circ.getNumberOfNodes():m_circ.getNumberOfNodes()+m_line.getNumberOfNodes()].isEqual(m_line.getCoords(),1e-12)) - self.assertTrue(a.getCoords().isEqual(DataArrayDouble([(2.,0.),(1.4142135623730951,1.414213562373095),(0.,2.),(-1.414213562373095,1.4142135623730951),(-2.,0.),(-1.4142135623730954,-1.414213562373095),(0.,-2.),(1.4142135623730947,-1.4142135623730954),(0.,3.),(0.,-3.),(0.,-2.),(0.,2.),(2.,0.),(0.7653668647301797,-1.8477590650225735),(0.,0.),(0.7653668647301797,1.8477590650225735),(-2,0.),(-0.7653668647301795,1.8477590650225735),(0.,0.),(-0.7653668647301795,-1.8477590650225735)]),1e-12)) - self.assertEqual([32,1,7,10,11,12,13,14,15,32,5,3,11,10,16,17,18,19],a.getNodalConnectivity().getValues()) - self.assertEqual([0,9,18], a.getNodalConnectivityIndex().getValues()) - self.assertEqual([1,8,11,1,11,10,1,10,9],b.getNodalConnectivity().getValues()) - self.assertEqual([0,3,6,9],b.getNodalConnectivityIndex().getValues()) - self.assertTrue(a.getCoords()[:8].isEqual(m_circ.getCoords(),1e-12)) - self.assertTrue(a.getCoords()[8:10].isEqual(m_line.getCoords(),1e-12)) - coo_tgt = DataArrayDouble([2.,0.,1.4142135623730951,1.414213562373095,1.2246467991473532e-16,2.,-1.414213562373095,1.4142135623730951,-2.,0.,-1.4142135623730954,-1.414213562373095,-3.6739403974420594e-16,-2.,1.4142135623730947,-1.4142135623730954,0.,3.,0.,-3.,0.,-2.,0.,2.,2.,0.,0.7653668647301797,-1.8477590650225735,0.,0.,0.7653668647301797,1.8477590650225735,-2.,0.,-0.7653668647301795,1.8477590650225735,0.,0.,-0.7653668647301795,-1.8477590650225735]) - self.assertTrue(a.getCoords().isEqualWithoutConsideringStr(coo_tgt,1.0e-12)) - self.assertTrue(a.getCoords().getHiddenCppPointer()==b.getCoords().getHiddenCppPointer()) - self.assertEqual([0,0],c.getValues()) - self.assertEqual([-1,-1,0,1,-1,-1],d.getValues()) - - def testSwig2Intersect2DMeshWith1DLine11(self): - """ Quad line re-entering a square cell """ - eps = 1.0e-8 - m = MEDCouplingUMesh("box", 2) - m.setCoords(DataArrayDouble([-1., -1., -1., 1., 1., 1., 1., -1.0],4,2)) - c, cI = [NORM_POLYGON, 0, 1, 2, 3], [0, 5] - m.setConnectivity(DataArrayInt(c), DataArrayInt(cI)) - m.checkCoherency() - coords2 = [0., 1.3, -1.3, 0., -0.6, 0.6, 0., -1.3, -0.5, -0.5] - connec2, cI2 = [NORM_SEG3, 0, 1, 2, NORM_SEG3, 1, 3, 4], [0,4,8] - m_line = MEDCouplingUMesh("seg", 1) - m_line.setCoords(DataArrayDouble(coords2, len(coords2)/2, 2)) - m_line.setConnectivity(DataArrayInt(connec2), DataArrayInt(cI2)) - a, b, c, d = MEDCouplingUMesh.Intersect2DMeshWith1DLine(m, m_line, eps) - self.assertTrue(a.getCoords().getHiddenCppPointer()==b.getCoords().getHiddenCppPointer()) - self.assertTrue(a.getCoords()[:m.getNumberOfNodes()].isEqual(m.getCoords(),1e-12)) - self.assertTrue(a.getCoords()[m.getNumberOfNodes():m.getNumberOfNodes()+m_line.getNumberOfNodes()].isEqual(m_line.getCoords(),1e-12)) - self.assertTrue(a.getCoords().isEqual(DataArrayDouble([(-1.,-1.),(-1.,1.),(1.,1.),(1.,-1.),(0.,1.3),(-1.3,0.),(-0.6,0.6),(0.,-1.3),(-0.5,-0.5),(-1.,0.23453685964236054),(-1.,-0.13033276368660177),(-0.2345368596423598,1.),(-0.1303327636866019,-1.),(-0.11489196370692323,1.1481421036683868),(-0.6,0.6),(-1.1481421036683859,0.11489196370692323),(-1.147455889106615,-0.0593103465193594),(-0.5,-0.5),(-0.0593103465193594,-1.147455889106615),(1.,0.),(0.4348336181566991,-1.),(-0.5651663818433009,-1.),(-1.,-0.5651663818433009),(-1.,0.05210204797787939),(-0.6,0.6),(0.3827315701788201,1.),(-0.6172684298211799,1.),(-0.6,0.6),(-1.,0.6172684298211802),(-0.6,0.6),(0.3827315701788201,1.),(1.,0.),(0.4348336181566991,-1.),(-0.5,-0.5),(-1.,0.05210204797787939),(-1.,-0.5651663818433009),(-0.5,-0.5),(-0.5651663818433009,-1.)]),1e-12)) - self.assertEqual([32,9,11,2,3,12,10,29,30,31,32,33,34,32,0,10,12,35,36,37,32,1,11,9,26,27,28],a.getNodalConnectivity().getValues()) - self.assertEqual([0,13,20,27],a.getNodalConnectivityIndex().getValues()) - self.assertEqual([2,4,11,13,2,11,9,14,2,9,5,15,2,5,10,16,2,10,12,17,2,12,7,18],b.getNodalConnectivity().getValues()) - self.assertEqual([0,4,8,12,16,20,24],b.getNodalConnectivityIndex().getValues()) - self.assertTrue(a.getCoords()[:4].isEqual(m.getCoords(),1e-12)) - self.assertTrue(a.getCoords()[4:9].isEqual(m_line.getCoords(),1e-12)) - self.assertTrue(DataArrayInt([0,0,0]).isEqual(c)) - self.assertTrue(DataArrayInt([(-1,-1),(0,2),(-1,-1),(-1,-1),(0,1),(-1,-1)]).isEqual(d)) - pass - - def testSwig2Intersect2DMeshWith1DLine12(self): - """ Two squares one in the other intersected by an horizontal line """ - eps = 1.0e-8 - m = MEDCouplingUMesh("boxbox", 2) - m.setCoords(DataArrayDouble([-0.5,-0.5,-0.5,0.5,0.5,0.5,0.5,-0.5,-0.25,-0.25,-0.25,0.25,0.25,0.25,0.25,-0.25],8,2)) - c = [NORM_POLYGON, 4, 5, 6, 7, NORM_POLYGON, 0, 1, 5, 4, NORM_POLYGON, 1, 2, 3, 0, 4, 7, 6, 5] - cI = [0, 5, 10, 19] - m.setConnectivity(DataArrayInt(c), DataArrayInt(cI)) - m.checkCoherency() - coords2 = [-1., 0.25, 1., 0.25] - connec2, cI2 = [NORM_SEG2, 0, 1], [0,3] - m_line = MEDCouplingUMesh.New("seg", 1) - m_line.setCoords(DataArrayDouble(coords2, len(coords2)/2, 2)) - m_line.setConnectivity(DataArrayInt(connec2), DataArrayInt(cI2)) - m_line2 = m_line.deepCpy() - m2 = m.deepCpy() - a, b, c, d = MEDCouplingUMesh.Intersect2DMeshWith1DLine(m, m_line, eps) - self.assertTrue(a.getCoords().getHiddenCppPointer()==b.getCoords().getHiddenCppPointer()) - self.assertTrue(a.getCoords()[:m.getNumberOfNodes()].isEqual(m.getCoords(),1e-12)) - self.assertTrue(a.getCoords()[m.getNumberOfNodes():m.getNumberOfNodes()+m_line.getNumberOfNodes()].isEqual(m_line.getCoords(),1e-12)) - self.assertTrue(a.getCoords().isEqual(DataArrayDouble([(-0.5,-0.5),(-0.5,0.5),(0.5,0.5),(0.5,-0.5),(-0.25,-0.25),(-0.25,0.25),(0.25,0.25),(0.25,-0.25),(-1.,0.25),(1.,0.25),(-0.5,0.25),(0.5,0.25)]),1e-12)) - self.assertEqual([5,4,5,6,7,5,1,5,10,5,4,0,10,5,5,5,1,2,11,6,5,3,0,4,7,6,11],a.getNodalConnectivity().getValues()) - self.assertEqual([0,5,9,14,20,27],a.getNodalConnectivityIndex().getValues()) - self.assertEqual([1,8,10,1,10,5,1,5,6,1,6,11,1,11,9],b.getNodalConnectivity().getValues()) - self.assertEqual([0,3,6,9,12,15],b.getNodalConnectivityIndex().getValues()) - self.assertTrue(c.isEqual(DataArrayInt([0,1,1,2,2]))) - self.assertTrue(d.isEqual(DataArrayInt([(-1,-1),(1,2),(3,0),(3,4),(-1,-1)]))) - pass - - def testSwig2Intersect2DMeshWith1DLine13(self): - """ A square (side length) in a circle intersected by a simple horizontal line """ - import math - eps = 1.0e-8 - m = MEDCouplingUMesh("boxcircle", 2) - sq2 = math.sqrt(2.0) - soth = (sq2+1.0)/2.0 - coo = [2., 0., sq2, sq2, 0., 2., -sq2, sq2, -2., 0., -sq2, -sq2, 0., -2., sq2, -sq2, -1., -1., -1., 1., 1., - 1., 1., -1., -1., 0., 0., 1., 1., 0., 0., -1., -soth, soth, soth,soth] - coo = DataArrayDouble(coo); coo.rearrange(2) - m.setCoords(coo) - c = [NORM_QPOLYG, 8, 9, 10, 11, 12, 13, 14, 15, NORM_QPOLYG, 3, 1, 10, 9, 2, 17, 13, 16, NORM_QPOLYG, 1, 7, 5, 3, 9, 8, 11, 10, 0, 6, 4, 16, 12, 15, 14, 17] - cI = [0, 9, 18, 35] - m.setConnectivity(DataArrayInt(c), DataArrayInt(cI)) - m.checkCoherency() - coords2 = [-2., 1., 2., 1.0] - connec2, cI2 = [NORM_SEG2, 0, 1], [0,3] - m_line = MEDCouplingUMesh("seg", 1) - m_line.setCoords(DataArrayDouble(coords2, len(coords2)/2, 2)) - m_line.setConnectivity(DataArrayInt(connec2), DataArrayInt(cI2)) - a, b, c, d = MEDCouplingUMesh.Intersect2DMeshWith1DLine(m, m_line, eps) - self.assertTrue(a.getCoords().getHiddenCppPointer()==b.getCoords().getHiddenCppPointer()) - self.assertTrue(a.getCoords()[:m.getNumberOfNodes()].isEqual(m.getCoords(),1e-12)) - self.assertTrue(a.getCoords()[m.getNumberOfNodes():m.getNumberOfNodes()+m_line.getNumberOfNodes()].isEqual(m_line.getCoords(),1e-12)) - self.assertTrue(a.getCoords().isEqual(DataArrayDouble([(2.,0.),(1.4142135623730951,1.4142135623730951),(0.,2.),(-1.4142135623730951,1.4142135623730951),(-2.,0.),(-1.4142135623730951,-1.4142135623730951),(0.,-2.),(1.4142135623730951,-1.4142135623730951),(-1.,-1.),(-1.,1.),(1.,1.),(1.,-1.),(-1.,0.),(0.,1.),(1.,0.),(0.,-1.),(-1.2071067811865475,1.2071067811865475),(1.2071067811865475,1.2071067811865475),(-2.,1.),(2.,1.),(1.7320508075688772,1.),(-1.7320508075688772,1.),(-1.2071067811865475,1.2071067811865475),(-1.3660254037844386,1.),(-1.58670668058247,1.2175228580174415),(0.,-1.),(1.,0.),(1.2071067811865475,1.2071067811865475),(1.5867066805824703,1.2175228580174413),(1.9828897227476205,-0.26105238444010315),(0.,-2.),(-1.9828897227476205,-0.2610523844401032),(-1.3660254037844386,1.),(-1.,0.),(1.5867066805824703,1.2175228580174413),(1.3660254037844386,1.),(1.2071067811865475,1.2071067811865475),(0.,-2.),(-1.9828897227476205,-0.2610523844401032),(-1.3660254037844386,1.),(-1.,0.),(0.,-1.),(1.,0.),(1.3660254037844386,1.),(1.9828897227476205,-0.26105238444010315)]),1e-12)) - self.assertEqual([32,8,9,10,11,12,13,14,15,32,3,1,10,9,2,17,13,16,32,3,9,21,22,23,24,32,1,20,10,34,35,36,32,7,5,21,9,8,11,10,20,37,38,39,40,41,42,43,44],a.getNodalConnectivity().getValues()) - self.assertEqual([0,9,18,25,32,49],a.getNodalConnectivityIndex().getValues()) - self.assertEqual([1,18,21,1,21,9,1,9,10,1,10,20,1,20,19],b.getNodalConnectivity().getValues()) - self.assertEqual([0,3,6,9,12,15],b.getNodalConnectivityIndex().getValues()) - self.assertTrue(c.isEqual(DataArrayInt([0,1,2,2,2]))) - self.assertTrue(d.isEqual(DataArrayInt([(-1,-1),(2,4),(1,0),(3,4),(-1,-1)]))) - pass - - def testSwig2Intersect2DMeshWith1DLine14(self): - """ A circle in a circle intersected by a simple horizontal line, not tangent to the circles """ - eps = 1.0e-8 - m = MEDCouplingUMesh("boxcircle", 2) - coo = [2.,0.,1.4142135623730951,1.414213562373095,0.,2.,-1.414213562373095,1.4142135623730951,-2.,0.,-1.4142135623730954,-1.414213562373095,0.,-2., - 1.4142135623730947,-1.4142135623730954,1.,0.,0.7071067811865476,0.7071067811865475,0.,1.,-0.7071067811865475,0.7071067811865476,-1.,0.,-0.7071067811865477,-0.7071067811865475, - 0.,-1.,0.7071067811865474,-0.7071067811865477,1.060660171779821,-1.0606601717798214,-1.0606601717798214,-1.0606601717798212] - coo = DataArrayDouble(coo); coo.rearrange(2) - m.setCoords(coo) - c = [NORM_QPOLYG, 15, 13, 11, 9, 14, 12, 10, 8, NORM_QPOLYG, 7, 5, 13, 15, 6, 17, 14, 16, NORM_QPOLYG, 5, 3, 1, 7, 15, 9, 11, 13, 4, 2, 0, 16, 8, 10, 12, 17] - cI = [0, 9, 18, 35] - m.setConnectivity(DataArrayInt(c), DataArrayInt(cI)) - m.checkCoherency() - coords2 = [-2., 0., 2., 0.] - connec2, cI2 = [NORM_SEG2, 0, 1], [0,3] - m_line = MEDCouplingUMesh.New("seg", 1) - m_line.setCoords(DataArrayDouble(coords2, len(coords2)/2, 2)) - m_line.setConnectivity(DataArrayInt(connec2), DataArrayInt(cI2)) - a, b, c, d = MEDCouplingUMesh.Intersect2DMeshWith1DLine(m, m_line, eps) - self.assertTrue(a.getCoords().getHiddenCppPointer()==b.getCoords().getHiddenCppPointer()) - self.assertTrue(a.getCoords()[:m.getNumberOfNodes()].isEqual(m.getCoords(),1e-12)) - self.assertTrue(a.getCoords()[m.getNumberOfNodes():m.getNumberOfNodes()+m_line.getNumberOfNodes()].isEqual(m_line.getCoords(),1e-12)) - self.assertTrue(a.getCoords().isEqual(DataArrayDouble([(2.,0.),(1.4142135623730951,1.414213562373095),(0.,2.),(-1.414213562373095,1.4142135623730951),(-2.,0.),(-1.4142135623730954,-1.414213562373095),(0.,-2.),(1.4142135623730947,-1.4142135623730954),(1.,0.),(0.7071067811865476,0.7071067811865475),(0.,1.),(-0.7071067811865475,0.7071067811865476),(-1.,0.),(-0.7071067811865477,-0.7071067811865475),(0.,-1.),(0.7071067811865474,-0.7071067811865477),(1.060660171779821,-1.0606601717798214),(-1.0606601717798214,-1.0606601717798212),(-2.,0.),(2.,0.),(-1.,0.),(1.,0.),(0.,2.),(1.8477590650225735,0.7653668647301795),(1.8477590650225735,-0.7653668647301797),(1.060660171779821,-1.0606601717798214),(0.9238795325112867,-0.38268343236508984),(0.9238795325112867,0.3826834323650897),(0.,1.),(-0.9238795325112867,0.3826834323650896),(-1.5,0.),(-1.8477590650225735,0.7653668647301792),(-1.0606601717798214,-1.0606601717798212),(-1.8477590650225733,-0.7653668647301799),(-1.5,0.),(-0.9238795325112866,-0.38268343236508995),(0.,1.),(-0.9238795325112867,0.3826834323650896),(-1.5,0.),(-1.8477590650225735,0.7653668647301792),(0.,2.),(1.8477590650225735,0.7653668647301795),(1.5,0.),(0.9238795325112867,0.3826834323650897),(1.060660171779821,-1.0606601717798214),(0.9238795325112867,-0.38268343236508984),(1.5,0.),(1.8477590650225735,-0.7653668647301797),(0.,1.),(0.9238795325112867,0.3826834323650897),(0.,0.),(-0.9238795325112867,0.3826834323650896),(0.,-1.),(-0.9238795325112866,-0.38268343236508995),(0.,0.),(0.9238795325112867,-0.38268343236508984)]),1e-12)) - self.assertEqual([32,7,5,13,15,6,17,14,16,32,9,11,20,18,3,1,19,21,36,37,38,39,40,41,42,43,32,7,15,21,19,44,45,46,47,32,13,5,18,20,32,33,34,35,32,11,9,21,20,48,49,50,51,32,15,13,20,21,52,53,54,55],a.getNodalConnectivity().getValues()) - self.assertEqual([0,9,26,35,44,53,62],a.getNodalConnectivityIndex().getValues()) - self.assertEqual([1,18,20,1,20,21,1,21,19],b.getNodalConnectivity().getValues()) - self.assertEqual([0,3,6,9],b.getNodalConnectivityIndex().getValues()) - self.assertTrue(c.isEqual(DataArrayInt([1,2,2,2,0,0]))) - self.assertTrue(d.isEqual(DataArrayInt([(1,3),(4,5),(1,2)]))) - pass - - def testSwig2Intersect2DMeshWith1DLine15(self): - """ Same as testSwig2Intersect2DMeshWith1DLine13 except that the line is colinear AND splits on of the common edge of 2D mesh.""" - import math - eps = 1.0e-8 - m = MEDCouplingUMesh("boxcircle", 2) - sq2 = math.sqrt(2.0) - soth = (sq2+1.0)/2.0 - coo = [2., 0., sq2, sq2, 0., 2., -sq2, sq2, -2., 0., -sq2, -sq2, 0., -2., sq2, -sq2, -1., -1., -1., 1., 1., - 1., 1., -1., -1., 0., 0., 1., 1., 0., 0., -1., -soth, soth, soth,soth] - coo = DataArrayDouble(coo); coo.rearrange(2) - m.setCoords(coo) - c = [NORM_QPOLYG, 8, 9, 10, 11, 12, 13, 14, 15, NORM_QPOLYG, 3, 1, 10, 9, 2, 17, 13, 16, NORM_QPOLYG, 1, 7, 5, 3, 9, 8, 11, 10, 0, 6, 4, 16, 12, 15, 14, 17] - cI = [0, 9, 18, 35] - m.setConnectivity(DataArrayInt(c), DataArrayInt(cI)) - m.checkCoherency() - coords2 = [(-2., 1.),(2.,1.),(0.,1)] - connec2, cI2 = [NORM_SEG2, 0, 2, NORM_SEG2, 2, 1], [0,3,6] - m_line = MEDCouplingUMesh("seg", 1) - m_line.setCoords(DataArrayDouble(coords2)) - m_line.setConnectivity(DataArrayInt(connec2), DataArrayInt(cI2)) - a, b, c, d = MEDCouplingUMesh.Intersect2DMeshWith1DLine(m, m_line, eps) - self.assertTrue(a.getCoords().getHiddenCppPointer()==b.getCoords().getHiddenCppPointer()) - self.assertTrue(a.getCoords()[:m.getNumberOfNodes()].isEqual(m.getCoords(),1e-12)) - self.assertTrue(a.getCoords()[m.getNumberOfNodes():m.getNumberOfNodes()+m_line.getNumberOfNodes()].isEqual(m_line.getCoords(),1e-12)) - self.assertTrue(a.getCoords().isEqual(DataArrayDouble([(2.,0.),(1.4142135623730951,1.4142135623730951),(0.,2.),(-1.4142135623730951,1.4142135623730951),(-2.,0.),(-1.4142135623730951,-1.4142135623730951),(0.,-2.),(1.4142135623730951,-1.4142135623730951),(-1.,-1.),(-1.,1.),(1.,1.),(1.,-1.),(-1.,0.),(0.,1.),(1.,0.),(0.,-1.),(-1.2071067811865475,1.2071067811865475),(1.2071067811865475,1.2071067811865475),(-2.,1.),(2.,1.),(0.,1.),(1.7320508075688776,1.),(-1.7320508075688776,1.),(-0.5,1.),(0.5,1.),(0.5,1.),(-0.5,1.),(-1.2071067811865475,1.2071067811865475),(-1.3660254037844388,1.),(-1.58670668058247,1.2175228580174415),(0.,-1.),(1.,0.),(1.2071067811865475,1.2071067811865475),(1.5867066805824703,1.2175228580174413),(1.9828897227476205,-0.26105238444010315),(0.,-2.),(-1.9828897227476205,-0.2610523844401032),(-1.3660254037844388,1.),(-1.,0.),(1.5867066805824703,1.2175228580174413),(1.3660254037844388,1.),(1.2071067811865475,1.2071067811865475),(0.,-2.),(-1.9828897227476205,-0.2610523844401032),(-1.3660254037844388,1.),(-1.,0.),(0.,-1.),(1.,0.),(1.3660254037844388,1.),(1.9828897227476205,-0.26105238444010315)]),1e-12)) - self.assertEqual([32,8,9,20,10,11,12,23,24,14,15,32,3,1,10,20,9,2,17,25,26,16,32,3,9,22,27,28,29,32,1,21,10,39,40,41,32,7,5,22,9,8,11,10,21,42,43,44,45,46,47,48,49],a.getNodalConnectivity().getValues()) - self.assertEqual([0,11,22,29,36,53],a.getNodalConnectivityIndex().getValues()) - self.assertEqual([1,18,22,1,22,9,1,9,20,1,20,10,1,10,21,1,21,19],b.getNodalConnectivity().getValues()) - self.assertEqual([0,3,6,9,12,15,18],b.getNodalConnectivityIndex().getValues()) - self.assertTrue(c.isEqual(DataArrayInt([0,1,2,2,2]))) - self.assertTrue(d.isEqual(DataArrayInt([(-1,-1),(2,4),(1,0),(1,0),(3,4),(-1,-1)]))) - pass - - def testSwig2Intersect2DMeshWith1DLine16(self): - """ Same than testSwig2Intersect2DMeshWith1DLine13 except it is a vertical line. Non regression test.""" - import math - eps = 1.0e-8 - m = MEDCouplingUMesh("boxcircle", 2) - sq2 = math.sqrt(2.0) - soth = (sq2+1.0)/2.0 - coo = [2., 0., sq2, sq2, 0., 2., -sq2, sq2, -2., 0., -sq2, -sq2, 0., -2., sq2, -sq2, -1., -1., -1., 1., 1., - 1., 1., -1., -1., 0., 0., 1., 1., 0., 0., -1., -soth, soth, soth,soth] - coo = DataArrayDouble(coo); coo.rearrange(2) - m.setCoords(coo) - c = [NORM_QPOLYG, 8, 9, 10, 11, 12, 13, 14, 15, NORM_QPOLYG, 3, 1, 10, 9, 2, 17, 13, 16, NORM_QPOLYG, 1, 7, 5, 3, 9, 8, 11, 10, 0, 6, 4, 16, 12, 15, 14, 17] - cI = [0, 9, 18, 35] - m.setConnectivity(DataArrayInt(c), DataArrayInt(cI)) - m.checkCoherency() - coords2 = [1., 2., 1., -2.] - connec2, cI2 = [NORM_SEG2, 0, 1], [0,3] - m_line = MEDCouplingUMesh("seg", 1) - m_line.setCoords(DataArrayDouble(coords2, len(coords2)/2, 2)) - m_line.setConnectivity(DataArrayInt(connec2), DataArrayInt(cI2)) - a, b, c, d = MEDCouplingUMesh.Intersect2DMeshWith1DLine(m, m_line, eps) - self.assertTrue(a.getCoords().getHiddenCppPointer()==b.getCoords().getHiddenCppPointer()) - self.assertTrue(a.getCoords()[:m.getNumberOfNodes()].isEqual(m.getCoords(),1e-12)) - self.assertTrue(a.getCoords()[m.getNumberOfNodes():m.getNumberOfNodes()+m_line.getNumberOfNodes()].isEqual(m_line.getCoords(),1e-12)) - self.assertTrue(a.getCoords().isEqual(DataArrayDouble([(2., 0.),(1.4142135623730951,1.4142135623730951),(0.,2.),(-1.4142135623730951,1.4142135623730951),(-2.,0.),(-1.4142135623730951,-1.4142135623730951),(0.,-2.),(1.4142135623730951,-1.4142135623730951),(-1.,-1.),(-1.,1.),(1.,1.),(1.,-1.),(-1.,0.),(0.,1.),(1.,0.),(0.,-1.),(-1.2071067811865475,1.2071067811865475),(1.2071067811865475,1.2071067811865475),(1.,2.),(1.,-2.),(1.,1.7320508075688772),(1.,-1.7320508075688772),(1.2071067811865475,1.2071067811865475),(1.,1.3660254037844386),(1.217522858017441,1.5867066805824703),(-1.2071067811865475,1.2071067811865475),(-0.2610523844401028,1.9828897227476208),(1.,1.3660254037844386),(0.,1.),(1.2071067811865475,1.2071067811865475),(2.,0.),(1.217522858017441,-1.5867066805824703),(1.,-1.3660254037844386),(1.,0.),(-2.,0.),(-1.2071067811865475,1.2071067811865475),(-1.,0.),(0.,-1.),(1.,-1.3660254037844386),(-0.2610523844401028,-1.9828897227476208)]),1e-12)) - self.assertEqual([32,8,9,10,11,12,13,14,15,32,1,10,20,22,23,24,32,9,3,20,10,25,26,27,28,32,10,1,7,21,11,29,30,31,32,33,32,5,3,9,8,11,21,34,35,36,37,38,39],a.getNodalConnectivity().getValues()) - self.assertEqual([0,9,16,25,36,49],a.getNodalConnectivityIndex().getValues()) - self.assertEqual([1,18,20,1,20,10,1,10,11,1,11,21,1,21,19],b.getNodalConnectivity().getValues()) - self.assertEqual([0,3,6,9,12,15],b.getNodalConnectivityIndex().getValues()) - self.assertTrue(c.isEqual(DataArrayInt([0,1,1,2,2]))) - self.assertTrue(d.isEqual(DataArrayInt([(-1,-1),(1,2),(3,0),(3,4),(-1,-1)]))) - pass - - def testOrderConsecutiveCells1D1(self): - """A line in several unconnected pieces:""" - m2 = MEDCouplingUMesh.New("bla", 1) - c = DataArrayInt([NORM_SEG2,0,1,NORM_SEG3,1,3,2, NORM_SEG2,3,4, - NORM_SEG3,5,7,6, NORM_SEG3,7,9,8, NORM_SEG2,9,10, - NORM_SEG2,11,12,NORM_SEG2,12,13, - NORM_SEG2,14,15]) - cI = DataArrayInt([0,3,7,10,14,18,21,24,27,30]) - coords2 = DataArrayDouble([float(i) for i in range(32)], 16,2) - m2.setCoords(coords2); - m2.setConnectivity(c, cI); - m2.checkCoherency2(1.0e-8); - - # Shuffle a bit :-) - m2.renumberCells(DataArrayInt([0,3,6,8,1,4,7,5,2]), True); - res = m2.orderConsecutiveCells1D() - expRes = [0,3,6,8,1,4,2,7,5] - self.assertEqual(m2.getNumberOfCells(),res.getNumberOfTuples()) - self.assertEqual(expRes, res.getValues()) - - # A closed line (should also work) - m3 = MEDCouplingUMesh.New("bla3", 1) - conn3A = DataArrayInt([NORM_SEG2,0,1,NORM_SEG3,1,3,2, NORM_SEG2,3,0]) - coord3 = coords2[0:5] - c.reAlloc(10) - cI.reAlloc(4) - - m3.setCoords(coord3) - m3.setConnectivity(conn3A, cI) - m3.checkCoherency2(1.0e-8) - res2 = m3.orderConsecutiveCells1D() - expRes2 = [0,1,2] - self.assertEqual(m3.getNumberOfCells(),res2.getNumberOfTuples()) - self.assertEqual(expRes2, res2.getValues()) - pass - - def testDADApplyFuncOnThis1(self): - d=DataArrayDouble(5) ; d.iota(0.) - d.applyFuncOnThis("2*x+1") - self.assertTrue(d.isEqual(DataArrayDouble([1.,3.,5.,7.,9.]),1e-12)) - d=DataArrayDouble(6) ; d.iota(0.) ; d.rearrange(2) - d.applyFuncOnThis("2*x+1") - self.assertTrue(d.isEqual(DataArrayDouble([1.,3.,5.,7.,9.,11.],3,2),1e-12)) - d.applyFuncOnThis("1+2*3") - self.assertTrue(d.isEqual(DataArrayDouble([(7.,7.),(7.,7.),(7.,7.)]),1e-12)) - pass - - def testSwig2PointSetComputeFetchedNodeIds1(self): - arr=DataArrayDouble(6) ; arr.iota() - m=MEDCouplingCMesh() ; m.setCoords(arr,arr,arr) - m=m.buildUnstructured() - m0=m[[0,1,5,6,25,26,30,31,124]] - ref=DataArrayInt([0,1,2,6,7,8,12,13,14,36,37,38,42,43,44,48,49,50,72,73,74,78,79,80,84,85,86,172,173,178,179,208,209,214,215]) - self.assertTrue(m0.computeFetchedNodeIds().isEqual(ref)) - self.assertTrue(MEDCoupling1SGTUMesh(m0).computeFetchedNodeIds().isEqual(ref)) - self.assertEqual(m0.getAllGeoTypes(),[NORM_HEXA8]) - m0.convertAllToPoly() - self.assertEqual(m0.getAllGeoTypes(),[NORM_POLYHED]) - self.assertTrue(MEDCoupling1DGTUMesh(m0).computeFetchedNodeIds().isEqual(ref)) - pass - - def testSwig2PartDefinition1(self): - pd=PartDefinition.New(5,22,3) - self.assertTrue(isinstance(pd,SlicePartDefinition)) - self.assertTrue(pd.toDAI().isEqual(DataArrayInt([5,8,11,14,17,20]))) - self.assertEqual(pd.getNumberOfElems(),6) - self.assertEqual(pd.getEffectiveStop(),23) - pd=PartDefinition.New(5,23,3) - self.assertTrue(isinstance(pd,SlicePartDefinition)) - self.assertTrue(pd.toDAI().isEqual(DataArrayInt([5,8,11,14,17,20]))) - self.assertEqual(pd.getNumberOfElems(),6) - self.assertEqual(pd.getEffectiveStop(),23) - self.assertEqual(pd.getSlice(),slice(5,23,3)) - pd=PartDefinition.New(5,22,1) - self.assertTrue(isinstance(pd,SlicePartDefinition)) - self.assertTrue(pd.toDAI().isEqual(DataArrayInt([5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21]))) - self.assertEqual(pd.getNumberOfElems(),17) - self.assertEqual(pd.getEffectiveStop(),22) - pd=PartDefinition.New(5,23,3)+PartDefinition.New(23,27,3) - self.assertTrue(isinstance(pd,SlicePartDefinition)) - self.assertEqual(pd.getNumberOfElems(),8) - self.assertTrue(pd.toDAI().isEqual(DataArrayInt([5,8,11,14,17,20,23,26]))) - self.assertEqual(pd.getEffectiveStop(),29) - pd=SlicePartDefinition(5,22,1) - self.assertTrue(isinstance(pd,SlicePartDefinition)) - self.assertTrue(pd.toDAI().isEqual(DataArrayInt([5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21]))) - self.assertEqual(pd.getNumberOfElems(),17) - self.assertEqual(pd.getEffectiveStop(),22) - d=DataArrayInt([2,4,5,6,10]) - pd=PartDefinition.New(d) - self.assertTrue(isinstance(pd,DataArrayPartDefinition)) - self.assertEqual(pd.toDAI().getHiddenCppPointer(),d.getHiddenCppPointer()) - pd=DataArrayPartDefinition(d) - self.assertEqual(pd.toDAI().getHiddenCppPointer(),d.getHiddenCppPointer()) - pd=DataArrayPartDefinition(d)+DataArrayPartDefinition(DataArrayInt([12,14,20])) - self.assertTrue(isinstance(pd,DataArrayPartDefinition)) - self.assertEqual(pd.getNumberOfElems(),8) - self.assertTrue(pd.toDAI().isEqual(DataArrayInt([2,4,5,6,10,12,14,20]))) - pass - - def testSwig2SortEachPairToMakeALinkedList1(self): - d=DataArrayInt([(50,49),(50,51),(51,52),(53,52),(53,54),(55,54),(55,56),(56,57),(58,57),(58,59),(60,59),(60,61),(61,62),(63,62),(63,64),(65,64),(65,66),(66,67)]) - d.sortEachPairToMakeALinkedList() - self.assertTrue(d.isEqual(DataArrayInt([(49,50),(50,51),(51,52),(52,53),(53,54),(54,55),(55,56),(56,57),(57,58),(58,59),(59,60),(60,61),(61,62),(62,63),(63,64),(64,65),(65,66),(66,67)]))) - pass - - def testSwig2DAIIsRange(self): - d=DataArrayInt([2,6,10]) - a,b=d.isRange() - self.assertTrue(a) - self.assertEqual(b,slice(2,11,4)) - self.assertTrue(DataArrayInt.Range(b.start,b.stop,b.step).isEqual(d)) - # - d=DataArrayInt([2,7,10]) - a,b=d.isRange() - self.assertTrue(not a) - self.assertTrue(b is None) - # - d=DataArrayInt([22,17,12]) - a,b=d.isRange() - self.assertTrue(a) - self.assertEqual(b,slice(22,11,-5)) - self.assertTrue(DataArrayInt.Range(b.start,b.stop,b.step).isEqual(d)) - # - d=DataArrayInt([22,16,12]) - a,b=d.isRange() - self.assertTrue(not a) - self.assertTrue(b is None) - # - d=DataArrayInt([33]) - a,b=d.isRange() - self.assertTrue(a) - self.assertEqual(b,slice(33,34,1)) - self.assertTrue(DataArrayInt.Range(b.start,b.stop,b.step).isEqual(d)) - # - d=DataArrayInt([]) - a,b=d.isRange() - self.assertTrue(a) - self.assertEqual(b,slice(0,0,1)) - self.assertTrue(DataArrayInt.Range(b.start,b.stop,b.step).isEqual(d)) - # - d=DataArrayInt([2,6,10,2]) - a,b=d.isRange() - self.assertTrue(not a) - self.assertTrue(b is None) - pass - - def testSwig2PartDefinitionComposeWith1(self): - f=PartDefinition.New(DataArrayInt([0,1,2,3,6,7,8,9])) - g=PartDefinition.New(4,14,1) - g2=g.deepCpy() - self.assertTrue(g2.isEqual(g)[0]) - h=f.composeWith(g) - self.assertTrue(isinstance(h,DataArrayPartDefinition)) - self.assertTrue(h.toDAI().isEqual(DataArrayInt([4,5,6,7,10,11,12,13]))) - f2=f.tryToSimplify() - g2=g.tryToSimplify() - self.assertEqual(f2.getHiddenCppPointer(),f.getHiddenCppPointer())# same because no simplification due to content of array - self.assertEqual(g2.getHiddenCppPointer(),g.getHiddenCppPointer())# same because no simplification linked to type of PartDef - p=PartDefinition.New(DataArrayInt([2,6,10])) - p2=p.tryToSimplify() - self.assertNotEqual(p2.getHiddenCppPointer(),p.getHiddenCppPointer()) - self.assertTrue(isinstance(p2,SlicePartDefinition)) - self.assertEqual(p2.getSlice(),slice(2,11,4)) - self.assertTrue(p2.isEqual(SlicePartDefinition(2,11,4))[0]) - self.assertTrue(p2.isEqual(p2.deepCpy())[0]) - self.assertTrue(not p2.isEqual(SlicePartDefinition(1,11,4))[0]) - self.assertTrue(not p2.isEqual(SlicePartDefinition(2,10,4))[0]) - self.assertTrue(not p2.isEqual(SlicePartDefinition(2,11,3))[0]) - pass - - def testSwig2DAIGetIdsStrictlyNegative1(self): - d=DataArrayInt([4,-5,-1,0,3,99,-7]) - self.assertTrue(d.getIdsStrictlyNegative().isEqual(DataArrayInt([1,2,6]))) - pass - - def testSwig2DAIReplaceOneValByInThis1(self): - d=DataArrayInt([4,-5,-1,0,-5,99,-7,5]) - d.replaceOneValByInThis(-5,900) - self.assertTrue(d.isEqual(DataArrayInt([4,900,-1,0,900,99,-7,5]))) - pass - - def testSwig2DAIGetMinMaxValues1(self): - d=DataArrayInt([4,-5,-1,0,3,99,-7]) - a,b=d.getMinMaxValues() - self.assertEqual(a,-7) - self.assertEqual(b,99) - pass - - def testSwig2DAIBuildUniqueNotSorted1(self): - d=DataArrayInt([-5,3,2,-1,2,3,-6,4,2,-5,3,7]) - self.assertTrue(d.buildUniqueNotSorted().isEqual(DataArrayInt([-5,3,2,-1,-6,4,7]))) - pass - - def testSwig2UMeshChangeOrientationOfCells1(self): - """ Here testing changeOrientationOfCell method on unstructured meshes lying on no coords.""" - m=MEDCouplingUMesh("mesh",1) - c=DataArrayInt([NORM_SEG2,4,5,NORM_SEG2,10,8,NORM_SEG3,20,7,33,NORM_SEG3,13,15,12,NORM_SEG2,3,2,NORM_SEG4,5,6,8,10,NORM_SEG4,34,33,3,2]) - cI=DataArrayInt([0,3,6,10,14,17,22,27]) - m.setConnectivity(c,cI) - m.changeOrientationOfCells() - self.assertTrue(m.getNodalConnectivity().isEqual(DataArrayInt([NORM_SEG2,5,4,NORM_SEG2,8,10,NORM_SEG3,7,20,33,NORM_SEG3,15,13,12,NORM_SEG2,2,3,NORM_SEG4,6,5,10,8,NORM_SEG4,33,34,2,3]))) - self.assertTrue(m.getNodalConnectivityIndex().isEqual(cI)) - # testing 2D cells - m=MEDCouplingUMesh("mesh",2) - c=DataArrayInt([NORM_TRI3,0,1,2,NORM_QUAD4,3,4,5,6,NORM_POLYGON,7,8,9,10,11,NORM_TRI6,12,13,14,15,16,17,NORM_QUAD8,18,19,20,21,22,23,24,25,NORM_QPOLYG,26,27,28,29,30,31,32,33,34,35]) - cI=DataArrayInt([0,4,9,15,22,31,42]) - m.setConnectivity(c,cI) - m.changeOrientationOfCells() - self.assertTrue(m.getNodalConnectivity().isEqual(DataArrayInt([NORM_TRI3,0,2,1,NORM_QUAD4,3,6,5,4,NORM_POLYGON,7,11,10,9,8,NORM_TRI6,12,14,13,17,16,15,NORM_QUAD8,18,21,20,19,25,24,23,22,NORM_QPOLYG,26,30,29,28,27,35,34,33,32,31]))) - self.assertTrue(m.getNodalConnectivityIndex().isEqual(cI)) - pass - - def testSwig2StructuredMeshCellLocation1(self): - # 3D - arrX=DataArrayDouble(5) ; arrX.iota() - arrY=DataArrayDouble(4) ; arrY.iota() - arrZ=DataArrayDouble(3) ; arrZ.iota() - m=MEDCouplingCMesh() ; m.setCoords(arrX,arrY,arrZ) - li=[] - liExp3D=[(0,0,0),(1,0,0),(2,0,0),(3,0,0),(0,1,0),(1,1,0),(2,1,0),(3,1,0),(0,2,0),(1,2,0),(2,2,0),(3,2,0),(0,0,1),(1,0,1),(2,0,1),(3,0,1),(0,1,1),(1,1,1),(2,1,1),(3,1,1),(0,2,1),(1,2,1),(2,2,1),(3,2,1)] - self.assertEqual(24,m.getNumberOfCells()) - for i in xrange(m.getNumberOfCells()): - li.append(m.getLocationFromCellId(i)) - pass - self.assertEqual(liExp3D,li) - self.assertRaises(InterpKernelException,m.getLocationFromCellId,24) - self.assertRaises(InterpKernelException,m.getLocationFromCellId,-1) - # 2D - arrX=DataArrayDouble(5) ; arrX.iota() - arrY=DataArrayDouble(4) ; arrY.iota() - m=MEDCouplingCMesh() ; m.setCoords(arrX,arrY) - li=[] - liExp2D=[(0,0),(1,0),(2,0),(3,0),(0,1),(1,1),(2,1),(3,1),(0,2),(1,2),(2,2),(3,2)] - self.assertEqual(12,m.getNumberOfCells()) - for i in xrange(m.getNumberOfCells()): - li.append(m.getLocationFromCellId(i)) - pass - self.assertEqual(liExp2D,li) - self.assertRaises(InterpKernelException,m.getLocationFromCellId,12) - self.assertRaises(InterpKernelException,m.getLocationFromCellId,-1) - # 1D - arrX=DataArrayDouble(5) ; arrX.iota() - m=MEDCouplingCMesh() ; m.setCoords(arrX) - self.assertEqual(4,m.getNumberOfCells()) - for i in xrange(m.getNumberOfCells()): - self.assertEqual((i,),m.getLocationFromCellId(i)) - pass - self.assertRaises(InterpKernelException,m.getLocationFromCellId,4) - self.assertRaises(InterpKernelException,m.getLocationFromCellId,-1) - pass - - def testSwig2StructuredMeshNodeLocation1(self): - # 3D - arrX=DataArrayDouble(5) ; arrX.iota() - arrY=DataArrayDouble(4) ; arrY.iota() - arrZ=DataArrayDouble(3) ; arrZ.iota() - m=MEDCouplingCMesh() ; m.setCoords(arrX,arrY,arrZ) - li=[] - liExp3D=[(0,0,0),(1,0,0),(2,0,0),(3,0,0),(4,0,0),(0,1,0),(1,1,0),(2,1,0),(3,1,0),(4,1,0),(0,2,0),(1,2,0),(2,2,0),(3,2,0),(4,2,0),(0,3,0),(1,3,0),(2,3,0),(3,3,0),(4,3,0),(0,0,1),(1,0,1),(2,0,1),(3,0,1),(4,0,1),(0,1,1),(1,1,1),(2,1,1),(3,1,1),(4,1,1),(0,2,1),(1,2,1),(2,2,1),(3,2,1),(4,2,1),(0,3,1),(1,3,1),(2,3,1),(3,3,1),(4,3,1),(0,0,2),(1,0,2),(2,0,2),(3,0,2),(4,0,2),(0,1,2),(1,1,2),(2,1,2),(3,1,2),(4,1,2),(0,2,2),(1,2,2),(2,2,2),(3,2,2),(4,2,2),(0,3,2),(1,3,2),(2,3,2),(3,3,2),(4,3,2)] - self.assertEqual(60,m.getNumberOfNodes()) - for i in xrange(m.getNumberOfNodes()): - li.append(m.getLocationFromNodeId(i)) - pass - self.assertEqual(liExp3D,li) - self.assertRaises(InterpKernelException,m.getLocationFromNodeId,60) - self.assertRaises(InterpKernelException,m.getLocationFromNodeId,-1) - # 2D - arrX=DataArrayDouble(5) ; arrX.iota() - arrY=DataArrayDouble(4) ; arrY.iota() - m=MEDCouplingCMesh() ; m.setCoords(arrX,arrY) - li=[] - liExp2D=[(0,0),(1,0),(2,0),(3,0),(4,0),(0,1),(1,1),(2,1),(3,1),(4,1),(0,2),(1,2),(2,2),(3,2),(4,2),(0,3),(1,3),(2,3),(3,3),(4,3)] - self.assertEqual(20,m.getNumberOfNodes()) - for i in xrange(m.getNumberOfNodes()): - li.append(m.getLocationFromNodeId(i)) - pass - self.assertEqual(liExp2D,li) - self.assertRaises(InterpKernelException,m.getLocationFromNodeId,20) - self.assertRaises(InterpKernelException,m.getLocationFromNodeId,-1) - # 1D - arrX=DataArrayDouble(5) ; arrX.iota() - m=MEDCouplingCMesh() ; m.setCoords(arrX) - self.assertEqual(5,m.getNumberOfNodes()) - for i in xrange(m.getNumberOfNodes()): - self.assertEqual((i,),m.getLocationFromNodeId(i)) - pass - self.assertRaises(InterpKernelException,m.getLocationFromCellId,5) - self.assertRaises(InterpKernelException,m.getLocationFromCellId,-1) - pass - - def testSwig2DataArrayPrintNotTooLong1(self): - """ Now that DataArrayDouble and DataArrayInt and pickelized they can appear in YACS ports. Avoid to have too heavy string representation of them.""" - d=DataArrayDouble(2000) ; d.iota() ; d.rearrange(2) - st0=d.repr() ; st1=str(d) ; st2=d.reprNotTooLong() - self.assertEqual(st0,st1) # 1000 tuples ( >=0 and <= 1000) -> str(d)==d.repr() - self.assertEqual(st1,st2) - # - d=DataArrayDouble(2002) ; d.iota() ; d.rearrange(2) - st0=d.repr() ; st1=str(d) ; st2=d.reprNotTooLong() - self.assertNotEqual(st0,st1) # 1001 tuples ( > 1000) -> str(d)==d.reprNotTooLong() - self.assertEqual(st1,st2) - self.assertIn(len(st2),xrange(0,1000)) # no more than 1000 characters - ## Now for DataArrayInt - d=DataArrayInt(2000) ; d.iota() ; d.rearrange(2) - st0=d.repr() ; st1=str(d) ; st2=d.reprNotTooLong() - self.assertEqual(st0,st1) # 1000 tuples ( >=0 and <= 1000) -> str(d)==d.repr() - self.assertEqual(st1,st2) - # - d=DataArrayInt(2002) ; d.iota() ; d.rearrange(2) - st0=d.repr() ; st1=str(d) ; st2=d.reprNotTooLong() - self.assertNotEqual(st0,st1) # 1001 tuples ( > 1000) -> str(d)==d.reprNotTooLong() - self.assertEqual(st1,st2) - self.assertIn(len(st2),xrange(0,1000)) # no more than 1000 characters - pass - - def testExtrudedMeshWithoutZipCoords1(self): - """This test checks that MEDCouplingUMesh.buildExtrudedMesh do not perform a zipCoords.""" - arr=DataArrayDouble([(0.,0.),(1.,0.),(2.,0.),(3.,0.)]) - m=MEDCouplingUMesh("mesh",1) ; m.setCoords(arr) - m.allocateCells() - m.insertNextCell(NORM_SEG2,[1,2]) - arr1D=DataArrayDouble([(0.,0.),(0.,1.5),(0.,2.)]) - m1D=MEDCouplingUMesh("mesh1D",1) ; m1D.setCoords(arr1D) - m1D.allocateCells() - m1D.insertNextCell(NORM_SEG2,[0,1]) - m1D.insertNextCell(NORM_SEG2,[1,2]) - m2D=m.buildExtrudedMesh(m1D,0) - self.assertEqual(m.getCoords().getHiddenCppPointer(),m2D.getCoords().getHiddenCppPointer()) - coo=DataArrayDouble([(0,0),(1,0),(2,0),(3,0),(0,1.5),(1,1.5),(2,1.5),(3,1.5),(0,2),(1,2),(2,2),(3,2)]) - self.assertTrue(m.getCoords().isEqual(coo,1e-12)) - self.assertTrue(m2D.getNodalConnectivity().isEqual(DataArrayInt([4,1,2,6,5,4,5,6,10,9]))) - self.assertTrue(m2D.getNodalConnectivityIndex().isEqual(DataArrayInt([0,5,10]))) - pass - - def testPointSetAreAllNodesFetched1(self): - m=MEDCouplingCMesh() ; arr=DataArrayDouble(10) ; arr.iota() - m.setCoords(arr,arr) - m=m.buildUnstructured() - self.assertTrue(m.areAllNodesFetched()) - m2=m[[0,2,3,4,5]] - self.assertTrue(not m2.areAllNodesFetched()) - m2.zipCoords() - self.assertTrue(m2.areAllNodesFetched()) - pass - - def testMEDCouplingPointSetComputeDiameterField1(self): - arrX=DataArrayDouble([0.,1.1,1.7,2.1]) - arrY=DataArrayDouble([0.,0.7,0.8,1.9]) - arrZ=DataArrayDouble([0.,1.3,2.1,2.4]) - m=MEDCouplingCMesh() ; m.setCoords(arrX,arrY,arrZ) ; m=m.buildUnstructured() - f=m.computeDiameterField() - f.checkCoherency() - exp=DataArrayDouble([1.8411952639521971,1.5937377450509227,1.5297058540778357,1.705872210923198,1.4352700094407325,1.3638181696985856,2.0273134932713295,1.8055470085267789,1.7492855684535902,1.5297058540778357,1.2206555615733703,1.1357816691600546,1.3638181696985856,1.004987562112089,0.9,1.7492855684535902,1.4866068747318506,1.4177446878757824,1.3379088160259651,0.9695359714832656,0.8602325267042626,1.1445523142259597,0.6782329983125266,0.5099019513592785,1.5842979517754858,1.2884098726725124,1.208304597359457]) - self.assertTrue(exp.isEqual(f.getArray(),1e-12)) - m1=m[::2] - m2=m[1::2] - m2.simplexize(PLANAR_FACE_5) - m3=MEDCouplingUMesh.MergeUMeshesOnSameCoords(m1,m2) - f=m3.computeDiameterField() - f.checkCoherency() - exp2=DataArrayDouble([1.8411952639521971,1.5297058540778357,1.4352700094407325,2.0273134932713295,1.7492855684535902,1.2206555615733703,1.3638181696985856,0.9,1.4866068747318506,1.3379088160259651,0.8602325267042626,0.6782329983125266,1.5842979517754858,1.208304597359457,1.47648230602334,1.47648230602334,1.47648230602334,1.47648230602334,1.47648230602334,1.7029386365926402,1.7029386365926402,1.7029386365926402,1.7029386365926402,1.7029386365926402,1.3601470508735445,1.3601470508735445,1.3601470508735445,1.3601470508735445,1.3601470508735445,1.70293863659264,1.70293863659264,1.70293863659264,1.70293863659264,1.70293863659264,1.3601470508735445,1.3601470508735445,1.3601470508735445,1.3601470508735445,1.3601470508735445,1.063014581273465,1.063014581273465,1.063014581273465,1.063014581273465,1.063014581273465,1.0,1.0,1.0,1.0,1.0,1.5556349186104046,1.5556349186104046,1.5556349186104046,1.5556349186104046,1.5556349186104046,1.3601470508735443,1.3601470508735443,1.3601470508735443,1.3601470508735443,1.3601470508735443,0.9219544457292886,0.9219544457292886,0.9219544457292886,0.9219544457292886,0.9219544457292886,1.140175425099138,1.140175425099138,1.140175425099138,1.140175425099138,1.140175425099138,0.5,0.5,0.5,0.5,0.5,1.2529964086141667,1.2529964086141667,1.2529964086141667,1.2529964086141667,1.2529964086141667]) - self.assertTrue(exp2.isEqual(f.getArray(),1e-12)) - # TRI3 - spacedim = 2 - coo=DataArrayDouble([(1,1),(5,1.9),(2.1,3)]) - m=MEDCoupling1SGTUMesh("mesh",NORM_TRI3) ; m.setCoords(coo) - for c in [[0,1,2],[0,2,1],[2,1,0]]: - m.setNodalConnectivity(DataArrayInt(c)) - self.assertAlmostEqual(m.computeDiameterField().getArray()[0],4.1,12) - m2=m.buildUnstructured() ; m2.convertLinearCellsToQuadratic(0) - self.assertAlmostEqual(m2.computeDiameterField().getArray()[0],4.1,12) - m3=m.buildUnstructured() ; m3.convertLinearCellsToQuadratic(1) - self.assertAlmostEqual(m3.computeDiameterField().getArray()[0],4.1,12) - # TRI3 - spacedim = 3 - coo=DataArrayDouble([(1.3198537928820775,1.0991902391274959,-0.028645697595823361),(5.2486835106806335,2.2234012799688281,0.30368935050077939),(2.2973688139447361,3.1572023778066649,0.10937756365410012)]) - m=MEDCoupling1SGTUMesh("mesh",NORM_TRI3) ; m.setCoords(coo) - for c in [[0,1,2],[0,2,1],[2,1,0]]: - m.setNodalConnectivity(DataArrayInt(c)) - self.assertAlmostEqual(m.computeDiameterField().getArray()[0],4.1,12) - m2=m.buildUnstructured() ; m2.convertLinearCellsToQuadratic(0) - self.assertAlmostEqual(m2.computeDiameterField().getArray()[0],4.1,12) - m3=m.buildUnstructured() ; m3.convertLinearCellsToQuadratic(1) - self.assertAlmostEqual(m3.computeDiameterField().getArray()[0],4.1,12) - # QUAD4 - spacedim = 2 - coo=DataArrayDouble([(0,2),(2,0),(6,4),(4,9)]) - m=MEDCoupling1SGTUMesh("mesh",NORM_QUAD4) ; m.setCoords(coo) - exp3=sqrt(85.) - for delta in xrange(4): - c=[(elt+delta)%4 for elt in xrange(4)] - m.setNodalConnectivity(DataArrayInt(c)) - self.assertAlmostEqual(m.computeDiameterField().getArray()[0],exp3,12) - m2=m.buildUnstructured() ; m2.convertLinearCellsToQuadratic(0) - self.assertAlmostEqual(m2.computeDiameterField().getArray()[0],exp3,12) - m3=m.buildUnstructured() ; m3.convertLinearCellsToQuadratic(1) - self.assertAlmostEqual(m3.computeDiameterField().getArray()[0],exp3,12) - c.reverse() - m.setNodalConnectivity(DataArrayInt(c)) - self.assertAlmostEqual(m.computeDiameterField().getArray()[0],exp3,12) - m2=m.buildUnstructured() ; m2.convertLinearCellsToQuadratic(0) - self.assertAlmostEqual(m2.computeDiameterField().getArray()[0],exp3,12) - m3=m.buildUnstructured() ; m3.convertLinearCellsToQuadratic(1) - self.assertAlmostEqual(m3.computeDiameterField().getArray()[0],exp3,12) - # QUAD4 - spacedim = 3 - coo=DataArrayDouble([(0.26570992384234871,2.0405889913271817,-0.079134238105786903),(2.3739976619218064,0.15779148692781009,0.021842842914139737),(6.1207841448393197,4.3755532938679655,0.43666375769970678),(3.8363255342943359,9.2521096041694229,0.41551170895942313)]) - m=MEDCoupling1SGTUMesh("mesh",NORM_QUAD4) ; m.setCoords(coo) - for delta in xrange(4): - c=[(elt+delta)%4 for elt in xrange(4)] - m.setNodalConnectivity(DataArrayInt(c)) - self.assertAlmostEqual(m.computeDiameterField().getArray()[0],exp3,12) - m2=m.buildUnstructured() ; m2.convertLinearCellsToQuadratic(0) - self.assertAlmostEqual(m2.computeDiameterField().getArray()[0],exp3,12) - m3=m.buildUnstructured() ; m3.convertLinearCellsToQuadratic(1) - self.assertAlmostEqual(m3.computeDiameterField().getArray()[0],exp3,12) - c.reverse() - m.setNodalConnectivity(DataArrayInt(c)) - self.assertAlmostEqual(m.computeDiameterField().getArray()[0],exp3,12) - m2=m.buildUnstructured() ; m2.convertLinearCellsToQuadratic(0) - self.assertAlmostEqual(m2.computeDiameterField().getArray()[0],exp3,12) - m3=m.buildUnstructured() ; m3.convertLinearCellsToQuadratic(1) - self.assertAlmostEqual(m3.computeDiameterField().getArray()[0],exp3,12) - # PENTA6 - # noise of coo=DataArrayDouble([(0,0,0),(1,0,0),(0,1,0),(0,0,2),(1,0,2),(0,1,2)]) + rotation([0.7,-1.2,0.6],[-4,-1,10],0.3) - coo=DataArrayDouble([(-0.28594726851554486,-0.23715005500928255,-0.10268080010083136),(0.6167364988633947,-0.008923258436324799,-0.08574087516687756),(-0.6132873463333834,0.6943403970881654,-0.2806118260037991),(-0.40705974936532896,-0.05868487929989308,1.7724055544436323),(0.5505955507861958,0.19145393798144705,1.8788156352163994),(-0.6092686217773406,0.812502961290914,1.685712743757831)]) - m=MEDCoupling1SGTUMesh("mesh",NORM_PENTA6) ; m.setCoords(coo) - exp4=2.5041256256889888 - self.assertAlmostEqual(exp4,coo.buildEuclidianDistanceDenseMatrix().getMaxValue()[0],12)# <- the definition of diameter - for delta in xrange(3): - c=[(elt+delta)%3 for elt in xrange(3)] - c+=[elt+3 for elt in c] - m.setNodalConnectivity(DataArrayInt(c)) - self.assertAlmostEqual(m.computeDiameterField().getArray()[0],exp4,12) - m2=m.buildUnstructured() ; m2.convertLinearCellsToQuadratic(0) - self.assertAlmostEqual(m2.computeDiameterField().getArray()[0],exp4,12) - c.reverse() - m.setNodalConnectivity(DataArrayInt(c)) - self.assertAlmostEqual(m.computeDiameterField().getArray()[0],exp4,12) - m2=m.buildUnstructured() ; m2.convertLinearCellsToQuadratic(0) - self.assertAlmostEqual(m2.computeDiameterField().getArray()[0],exp4,12) - # HEXA8 - # noise of coo=DataArrayDouble([(0,0,0),(1,0,0),(1,1,0),(0,1,0),(0,0,2),(1,0,2),(1,1,2),(0,1,2)]) + rotation([0.7,-1.2,0.6],[-4,-1,10],0.3) - coo=DataArrayDouble([(-0.21266406388867243,-0.3049569460042527,-0.11012394815006032),(0.7641037943272584,-0.06990814759929553,-0.0909613877456491),(0.47406560768559974,0.8681310650341907,-0.2577311403703061),(-0.5136830410871793,0.644390554940524,-0.21319015989794698),(-0.4080167737381202,-0.12853761670628505,1.7869166291979348),(0.5650318811550441,0.20476257733110748,1.8140158890821603),(0.3230844436386215,1.1660778242678538,1.7175073141333406),(-0.6656588358432984,0.918357550969698,1.7566470691880265)]) - m=MEDCoupling1SGTUMesh("mesh",NORM_HEXA8) ; m.setCoords(coo) - exp5=2.5366409441884215 - self.assertAlmostEqual(exp5,coo.buildEuclidianDistanceDenseMatrix().getMaxValue()[0],12)# <- the definition of diameter - for delta in xrange(4): - c=[(elt+delta)%4 for elt in xrange(4)] - c+=[elt+4 for elt in c] - m.setNodalConnectivity(DataArrayInt(c)) - self.assertAlmostEqual(m.computeDiameterField().getArray()[0],exp5,12) - m2=m.buildUnstructured() ; m2.convertLinearCellsToQuadratic(0) - self.assertAlmostEqual(m2.computeDiameterField().getArray()[0],exp5,12) - c.reverse() - m.setNodalConnectivity(DataArrayInt(c)) - self.assertAlmostEqual(m.computeDiameterField().getArray()[0],exp5,12) - m2=m.buildUnstructured() ; m2.convertLinearCellsToQuadratic(0) - self.assertAlmostEqual(m2.computeDiameterField().getArray()[0],exp5,12) - # PYRA5 (1) 5th node is further - # noise of coo=DataArrayDouble([(0,0,0),(1,0,0),(1,1,0),(0,1,0),(0.5,0.5,2)]) + rotation([0.7,-1.2,0.6],[-4,-1,10],0.3) - coo=DataArrayDouble([(-0.31638393672228626,-0.3157865246451914,-0.12555467233075002),(0.7281379795666488,0.03836511217237115,-0.08431662762197323),(0.4757967840735147,0.8798897996143908,-0.2680890320119049),(-0.5386339871809047,0.5933159894201252,-0.2975311238319419),(0.012042592988768974,0.534282135495012,1.7859521682027926)]) - m=MEDCoupling1SGTUMesh("mesh",NORM_PYRA5) ; m.setCoords(coo) - exp6=2.1558368027391386 - self.assertAlmostEqual(exp6,coo.buildEuclidianDistanceDenseMatrix().getMaxValue()[0],12)# <- the definition of diameter - for delta in xrange(4): - c=[(elt+delta)%4 for elt in xrange(4)] - c+=[4] - m.setNodalConnectivity(DataArrayInt(c)) - self.assertAlmostEqual(m.computeDiameterField().getArray()[0],exp6,12) - m2=m.buildUnstructured() ; m2.convertLinearCellsToQuadratic(0) - self.assertAlmostEqual(m2.computeDiameterField().getArray()[0],exp6,12) - pass - # PYRA5 (2) 5th node is closer - # noise of coo=DataArrayDouble([(0,0,0),(1,0,0),(1,1,0),(0,1,0),(0.5,0.5,0.1)]) + rotation([0.7,-1.2,0.6],[-4,-1,10],0.3) - coo=DataArrayDouble([(-0.31638393672228626,-0.3157865246451914,-0.12555467233075002),(0.7281379795666488,0.03836511217237115,-0.08431662762197323),(0.4757967840735147,0.8798897996143908,-0.2680890320119049),(-0.5386339871809047,0.5933159894201252,-0.2975311238319419),(0.092964408350795,0.33389670321297005,-0.10171764888060142)]) - m=MEDCoupling1SGTUMesh("mesh",NORM_PYRA5) ; m.setCoords(coo) - exp7=1.4413563787228953 - self.assertAlmostEqual(exp7,coo.buildEuclidianDistanceDenseMatrix().getMaxValue()[0],12)# <- the definition of diameter - for delta in xrange(4): - c=[(elt+delta)%4 for elt in xrange(4)] - c+=[4] - m.setNodalConnectivity(DataArrayInt(c)) - self.assertAlmostEqual(m.computeDiameterField().getArray()[0],exp7,12) - m2=m.buildUnstructured() ; m2.convertLinearCellsToQuadratic(0) - self.assertAlmostEqual(m2.computeDiameterField().getArray()[0],exp7,12) - pass - # TETRA4 - # noise of coo=DataArrayDouble([(0,0,0),(1,0,0),(0,1,0),(1,1,1)]) + rotation([0.7,-1.2,0.6],[-4,-1,10],0.3) - coo=DataArrayDouble([(-0.2256894071281369,-0.27631691290428106,-0.20266086543995965),(0.655458695100186,-0.08173323565551605,-0.19254662462061933),(-0.49893490718947264,0.5848097154568599,-0.3039928255382145),(0.2988102920828487,1.0582266398878504,0.7347375047372364)]) - m=MEDCoupling1SGTUMesh("mesh",NORM_TETRA4) ; m.setCoords(coo) - exp8=1.7131322579364157 - self.assertAlmostEqual(exp8,coo.buildEuclidianDistanceDenseMatrix().getMaxValue()[0],12)# <- the definition of diameter - for c in [[0,1,2,3],[0,3,2,1],[0,1,3,2],[0,2,3,1],[0,3,1,2],[0,2,1,3]]: - for i in xrange(4): - m.setNodalConnectivity(DataArrayInt([(elt+i)%4 for elt in c])) - self.assertAlmostEqual(m.computeDiameterField().getArray()[0],exp8,12) - m2=m.buildUnstructured() ; m2.convertLinearCellsToQuadratic(0) - self.assertAlmostEqual(m2.computeDiameterField().getArray()[0],exp8,12) - pass - pass - pass - - def testMEDCouplingSkyLineArray(self): - index = DataArrayInt([ 0, 3, 5, 6, 6 ]) - value = DataArrayInt([ 1, 2, 3, 2, 3, 3 ]) - - sla0 = MEDCouplingSkyLineArray() - self.assertEqual( -1, sla0.getNumberOf() ) - self.assertEqual( 0, sla0.getLength() ) - sla0.set( index, value ) - self.assertTrue( index.isEqual( sla0.getIndexArray() )) - self.assertTrue( value.isEqual( sla0.getValueArray() )) - self.assertEqual( 4, sla0.getNumberOf() ) - self.assertEqual( 6, sla0.getLength() ) - - sla1 = MEDCouplingSkyLineArray( index, value ) - self.assertTrue( index.isEqual( sla1.getIndexArray() )) - self.assertTrue( value.isEqual( sla1.getValueArray() )) - self.assertEqual( 4, sla1.getNumberOf() ) - self.assertEqual( 6, sla1.getLength() ) - - sla2 = MEDCouplingSkyLineArray( sla1 ) - self.assertTrue( index.isEqual( sla2.getIndexArray() )) - self.assertTrue( value.isEqual( sla2.getValueArray() )) - self.assertEqual( 4, sla2.getNumberOf() ) - self.assertEqual( 6, sla2.getLength() ) - - indexVec = ivec(); indexVec.reserve( len( index )) - for i in index: indexVec.push_back( i[0] ) - valueVec = ivec(); valueVec.reserve( len( value )) - for i in value: valueVec.push_back( i[0] ) - sla3 = MEDCouplingSkyLineArray( indexVec, valueVec ) - self.assertTrue( index.isEqual( sla3.getIndexArray() )) - self.assertTrue( value.isEqual( sla3.getValueArray() )) - self.assertEqual( 4, sla3.getNumberOf() ) - self.assertEqual( 6, sla3.getLength() ) - - pass - - def testMEDCouplingUMeshgenerateGraph(self): - # cartesian mesh 3x3 - arr=DataArrayDouble(4) ; arr.iota() - c=MEDCouplingCMesh() ; c.setCoords(arr,arr) - m=c.buildUnstructured() - graph = m.generateGraph() - # 0 1 2 - # 3 4 5 - # 6 7 8 - valRef=[ 0,1,3, - 0,1,2,4, - 1,2,5, - 0,3,4,6, - 1,3,4,5,7, - 2,4,5,8, - 3,6,7, - 4,6,7,8, - 5,7,8] - self.assertEqual(valRef,list(graph.getValueArray().getValues())); - - indRef=[0, 3, 7, 10, 14, 19, 23, 26, 30, 33] - self.assertEqual(indRef,list(graph.getIndexArray().getValues())); - pass - - def testSwig2MEDCouplingCurveLinearReprQuick1(self): - """Non regression test. Error in m.__str__ when m is a MEDCouplingCurveLinear with spaceDim != meshDim.""" - arr=DataArrayDouble(12) ; arr.iota() ; arr.rearrange(2) - m=MEDCouplingCurveLinearMesh() - m.setCoords(arr) - m.setNodeGridStructure([3,2]) - m.checkCoherency() - self.assertEqual(m.getMeshDimension(),2) - self.assertEqual(m.getSpaceDimension(),2) - self.assertTrue(not "mismatch" in m.__str__()) - self.assertTrue(not "mismatch" in m.__repr__()) - # - arr=DataArrayDouble(18) ; arr.iota() ; arr.rearrange(3) - m.setCoords(arr) - self.assertEqual(m.getMeshDimension(),2) - self.assertEqual(m.getSpaceDimension(),3) - self.assertTrue(not "mismatch" in m.__str__()) - self.assertTrue(not "mismatch" in m.__repr__())# bug was here ! - pass - - pass - -if __name__ == '__main__': - unittest.main() diff --git a/src/MEDCoupling_Swig/MEDCouplingCommon.i b/src/MEDCoupling_Swig/MEDCouplingCommon.i deleted file mode 100644 index 8f1717456..000000000 --- a/src/MEDCoupling_Swig/MEDCouplingCommon.i +++ /dev/null @@ -1,5857 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 -// 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) - -%module MEDCoupling - -#ifdef WITH_DOCSTRINGS -%include MEDCoupling_doc.i -#endif - -%include std_vector.i -%include std_string.i - -%{ -#include "MEDCouplingMemArray.hxx" -#include "MEDCouplingUMesh.hxx" -#include "MEDCouplingExtrudedMesh.hxx" -#include "MEDCouplingCMesh.hxx" -#include "MEDCouplingIMesh.hxx" -#include "MEDCouplingCurveLinearMesh.hxx" -#include "MEDCoupling1GTUMesh.hxx" -#include "MEDCouplingField.hxx" -#include "MEDCouplingFieldDouble.hxx" -#include "MEDCouplingFieldTemplate.hxx" -#include "MEDCouplingGaussLocalization.hxx" -#include "MEDCouplingAutoRefCountObjectPtr.hxx" -#include "MEDCouplingMultiFields.hxx" -#include "MEDCouplingFieldOverTime.hxx" -#include "MEDCouplingDefinitionTime.hxx" -#include "MEDCouplingFieldDiscretization.hxx" -#include "MEDCouplingCartesianAMRMesh.hxx" -#include "MEDCouplingAMRAttribute.hxx" -#include "MEDCouplingMatrix.hxx" -#include "MEDCouplingPartDefinition.hxx" -#include "MEDCouplingSkyLineArray.hxx" -#include "MEDCouplingTypemaps.i" - -#include "InterpKernelAutoPtr.hxx" -#include "BoxSplittingOptions.hxx" - -using namespace ParaMEDMEM; -using namespace INTERP_KERNEL; - -%} - -%template(ivec) std::vector; -%template(dvec) std::vector; -%template(svec) std::vector; - -//////////////////// -%typemap(out) ParaMEDMEM::MEDCouplingMesh* -{ - $result=convertMesh($1,$owner); -} - -%typemap(out) MEDCouplingMesh* -{ - $result=convertMesh($1,$owner); -} -//$$$$$$$$$$$$$$$$$$ - -//////////////////// -%typemap(out) ParaMEDMEM::MEDCouplingPointSet* -{ - $result=convertMesh($1,$owner); -} - -%typemap(out) MEDCouplingPointSet* -{ - $result=convertMesh($1,$owner); -} -//$$$$$$$$$$$$$$$$$$ - -//////////////////// -%typemap(out) MEDCouplingCartesianAMRPatchGen* -{ - $result=convertCartesianAMRPatch($1,$owner); -} -//$$$$$$$$$$$$$$$$$$ - -//////////////////// -%typemap(out) MEDCouplingCartesianAMRMeshGen* -{ - $result=convertCartesianAMRMesh($1,$owner); -} -//$$$$$$$$$$$$$$$$$$ - -//////////////////// -%typemap(out) MEDCouplingDataForGodFather* -{ - $result=convertDataForGodFather($1,$owner); -} -//$$$$$$$$$$$$$$$$$$ - -//////////////////// -%typemap(out) ParaMEDMEM::MEDCoupling1GTUMesh* -{ - $result=convertMesh($1,$owner); -} - -%typemap(out) MEDCoupling1GTUMesh* -{ - $result=convertMesh($1,$owner); -} -//$$$$$$$$$$$$$$$$$$ - -//////////////////// -%typemap(out) ParaMEDMEM::MEDCouplingStructuredMesh* -{ - $result=convertMesh($1,$owner); -} - -%typemap(out) MEDCouplingStructuredMesh* -{ - $result=convertMesh($1,$owner); -} -//$$$$$$$$$$$$$$$$$$ - -//////////////////// -%typemap(out) ParaMEDMEM::MEDCouplingFieldDiscretization* -{ - $result=convertFieldDiscretization($1,$owner); -} - -%typemap(out) MEDCouplingFieldDiscretization* -{ - $result=convertFieldDiscretization($1,$owner); -} -//$$$$$$$$$$$$$$$$$$ - -//////////////////// -%typemap(out) ParaMEDMEM::MEDCouplingMultiFields* -{ - $result=convertMultiFields($1,$owner); -} - -%typemap(out) MEDCouplingMultiFields* -{ - $result=convertMultiFields($1,$owner); -} -//$$$$$$$$$$$$$$$$$$ - -//////////////////// -%typemap(out) ParaMEDMEM::PartDefinition* -{ - $result=convertPartDefinition($1,$owner); -} - -%typemap(out) PartDefinition* -{ - $result=convertPartDefinition($1,$owner); -} -//$$$$$$$$$$$$$$$$$$ - -#ifdef WITH_NUMPY -%init %{ import_array(); %} -#endif - -%feature("autodoc", "1"); -%feature("docstring"); - -%newobject ParaMEDMEM::MEDCouplingField::buildMeasureField; -%newobject ParaMEDMEM::MEDCouplingField::getLocalizationOfDiscr; -%newobject ParaMEDMEM::MEDCouplingField::computeTupleIdsToSelectFromCellIds; -%newobject ParaMEDMEM::MEDCouplingFieldDouble::New; -%newobject ParaMEDMEM::MEDCouplingFieldDouble::getArray; -%newobject ParaMEDMEM::MEDCouplingFieldDouble::getEndArray; -%newobject ParaMEDMEM::MEDCouplingFieldDouble::MergeFields; -%newobject ParaMEDMEM::MEDCouplingFieldDouble::MeldFields; -%newobject ParaMEDMEM::MEDCouplingFieldDouble::doublyContractedProduct; -%newobject ParaMEDMEM::MEDCouplingFieldDouble::determinant; -%newobject ParaMEDMEM::MEDCouplingFieldDouble::eigenValues; -%newobject ParaMEDMEM::MEDCouplingFieldDouble::eigenVectors; -%newobject ParaMEDMEM::MEDCouplingFieldDouble::inverse; -%newobject ParaMEDMEM::MEDCouplingFieldDouble::trace; -%newobject ParaMEDMEM::MEDCouplingFieldDouble::deviator; -%newobject ParaMEDMEM::MEDCouplingFieldDouble::magnitude; -%newobject ParaMEDMEM::MEDCouplingFieldDouble::maxPerTuple; -%newobject ParaMEDMEM::MEDCouplingFieldDouble::keepSelectedComponents; -%newobject ParaMEDMEM::MEDCouplingFieldDouble::extractSlice3D; -%newobject ParaMEDMEM::MEDCouplingFieldDouble::DotFields; -%newobject ParaMEDMEM::MEDCouplingFieldDouble::dot; -%newobject ParaMEDMEM::MEDCouplingFieldDouble::CrossProductFields; -%newobject ParaMEDMEM::MEDCouplingFieldDouble::crossProduct; -%newobject ParaMEDMEM::MEDCouplingFieldDouble::MaxFields; -%newobject ParaMEDMEM::MEDCouplingFieldDouble::max; -%newobject ParaMEDMEM::MEDCouplingFieldDouble::MinFields; -%newobject ParaMEDMEM::MEDCouplingFieldDouble::AddFields; -%newobject ParaMEDMEM::MEDCouplingFieldDouble::SubstractFields; -%newobject ParaMEDMEM::MEDCouplingFieldDouble::MultiplyFields; -%newobject ParaMEDMEM::MEDCouplingFieldDouble::DivideFields; -%newobject ParaMEDMEM::MEDCouplingFieldDouble::min; -%newobject ParaMEDMEM::MEDCouplingFieldDouble::negate; -%newobject ParaMEDMEM::MEDCouplingFieldDouble::getIdsInRange; -%newobject ParaMEDMEM::MEDCouplingFieldDouble::buildSubPart; -%newobject ParaMEDMEM::MEDCouplingFieldDouble::buildSubPartRange; -%newobject ParaMEDMEM::MEDCouplingFieldDouble::__getitem__; -%newobject ParaMEDMEM::MEDCouplingFieldDouble::__neg__; -%newobject ParaMEDMEM::MEDCouplingFieldDouble::__add__; -%newobject ParaMEDMEM::MEDCouplingFieldDouble::__sub__; -%newobject ParaMEDMEM::MEDCouplingFieldDouble::__mul__; -%newobject ParaMEDMEM::MEDCouplingFieldDouble::__div__; -%newobject ParaMEDMEM::MEDCouplingFieldDouble::__pow__; -%newobject ParaMEDMEM::MEDCouplingFieldDouble::__radd__; -%newobject ParaMEDMEM::MEDCouplingFieldDouble::__rsub__; -%newobject ParaMEDMEM::MEDCouplingFieldDouble::__rmul__; -%newobject ParaMEDMEM::MEDCouplingFieldDouble::__rdiv__; -%newobject ParaMEDMEM::MEDCouplingFieldDouble::clone; -%newobject ParaMEDMEM::MEDCouplingFieldDouble::cloneWithMesh; -%newobject ParaMEDMEM::MEDCouplingFieldDouble::deepCpy; -%newobject ParaMEDMEM::MEDCouplingFieldDouble::buildNewTimeReprFromThis; -%newobject ParaMEDMEM::MEDCouplingFieldDouble::nodeToCellDiscretization; -%newobject ParaMEDMEM::MEDCouplingFieldDouble::cellToNodeDiscretization; -%newobject ParaMEDMEM::MEDCouplingFieldDouble::getValueOnMulti; -%newobject ParaMEDMEM::MEDCouplingFieldTemplate::New; -%newobject ParaMEDMEM::MEDCouplingMesh::deepCpy; -%newobject ParaMEDMEM::MEDCouplingMesh::checkDeepEquivalOnSameNodesWith; -%newobject ParaMEDMEM::MEDCouplingMesh::checkTypeConsistencyAndContig; -%newobject ParaMEDMEM::MEDCouplingMesh::computeNbOfNodesPerCell; -%newobject ParaMEDMEM::MEDCouplingMesh::computeNbOfFacesPerCell; -%newobject ParaMEDMEM::MEDCouplingMesh::computeEffectiveNbOfNodesPerCell; -%newobject ParaMEDMEM::MEDCouplingMesh::buildPartRange; -%newobject ParaMEDMEM::MEDCouplingMesh::giveCellsWithType; -%newobject ParaMEDMEM::MEDCouplingMesh::getCoordinatesAndOwner; -%newobject ParaMEDMEM::MEDCouplingMesh::getBarycenterAndOwner; -%newobject ParaMEDMEM::MEDCouplingMesh::computeIsoBarycenterOfNodesPerCell; -%newobject ParaMEDMEM::MEDCouplingMesh::buildOrthogonalField; -%newobject ParaMEDMEM::MEDCouplingMesh::getCellIdsFullyIncludedInNodeIds; -%newobject ParaMEDMEM::MEDCouplingMesh::mergeMyselfWith; -%newobject ParaMEDMEM::MEDCouplingMesh::fillFromAnalytic; -%newobject ParaMEDMEM::MEDCouplingMesh::fillFromAnalytic2; -%newobject ParaMEDMEM::MEDCouplingMesh::fillFromAnalytic3; -%newobject ParaMEDMEM::MEDCouplingMesh::getMeasureField; -%newobject ParaMEDMEM::MEDCouplingMesh::simplexize; -%newobject ParaMEDMEM::MEDCouplingMesh::buildUnstructured; -%newobject ParaMEDMEM::MEDCouplingMesh::MergeMeshes; -%newobject ParaMEDMEM::MEDCouplingPointSet::zipCoordsTraducer; -%newobject ParaMEDMEM::MEDCouplingPointSet::getCellsInBoundingBox; -%newobject ParaMEDMEM::MEDCouplingPointSet::findBoundaryNodes; -%newobject ParaMEDMEM::MEDCouplingPointSet::buildBoundaryMesh; -%newobject ParaMEDMEM::MEDCouplingPointSet::MergeNodesArray; -%newobject ParaMEDMEM::MEDCouplingPointSet::buildPartOfMySelf2; -%newobject ParaMEDMEM::MEDCouplingPointSet::BuildInstanceFromMeshType; -%newobject ParaMEDMEM::MEDCouplingPointSet::zipConnectivityTraducer; -%newobject ParaMEDMEM::MEDCouplingPointSet::mergeMyselfWithOnSameCoords; -%newobject ParaMEDMEM::MEDCouplingPointSet::fillCellIdsToKeepFromNodeIds; -%newobject ParaMEDMEM::MEDCouplingPointSet::getCellIdsLyingOnNodes; -%newobject ParaMEDMEM::MEDCouplingPointSet::deepCpyConnectivityOnly; -%newobject ParaMEDMEM::MEDCouplingPointSet::getBoundingBoxForBBTree; -%newobject ParaMEDMEM::MEDCouplingPointSet::computeFetchedNodeIds; -%newobject ParaMEDMEM::MEDCouplingPointSet::ComputeNbOfInteractionsWithSrcCells; -%newobject ParaMEDMEM::MEDCouplingPointSet::computeDiameterField; -%newobject ParaMEDMEM::MEDCouplingPointSet::__getitem__; -%newobject ParaMEDMEM::MEDCouplingUMesh::New; -%newobject ParaMEDMEM::MEDCouplingUMesh::getNodalConnectivity; -%newobject ParaMEDMEM::MEDCouplingUMesh::getNodalConnectivityIndex; -%newobject ParaMEDMEM::MEDCouplingUMesh::clone; -%newobject ParaMEDMEM::MEDCouplingUMesh::__iter__; -%newobject ParaMEDMEM::MEDCouplingUMesh::cellsByType; -%newobject ParaMEDMEM::MEDCouplingUMesh::buildDescendingConnectivity; -%newobject ParaMEDMEM::MEDCouplingUMesh::buildDescendingConnectivity2; -%newobject ParaMEDMEM::MEDCouplingUMesh::explode3DMeshTo1D; -%newobject ParaMEDMEM::MEDCouplingUMesh::buildExtrudedMesh; -%newobject ParaMEDMEM::MEDCouplingUMesh::buildSpreadZonesWithPoly; -%newobject ParaMEDMEM::MEDCouplingUMesh::MergeUMeshes; -%newobject ParaMEDMEM::MEDCouplingUMesh::MergeUMeshesOnSameCoords; -%newobject ParaMEDMEM::MEDCouplingUMesh::ComputeSpreadZoneGradually; -%newobject ParaMEDMEM::MEDCouplingUMesh::ComputeSpreadZoneGraduallyFromSeed; -%newobject ParaMEDMEM::MEDCouplingUMesh::buildNewNumberingFromCommNodesFrmt; -%newobject ParaMEDMEM::MEDCouplingUMesh::conformize2D; -%newobject ParaMEDMEM::MEDCouplingUMesh::colinearize2D; -%newobject ParaMEDMEM::MEDCouplingUMesh::rearrange2ConsecutiveCellTypes; -%newobject ParaMEDMEM::MEDCouplingUMesh::sortCellsInMEDFileFrmt; -%newobject ParaMEDMEM::MEDCouplingUMesh::getRenumArrForMEDFileFrmt; -%newobject ParaMEDMEM::MEDCouplingUMesh::convertCellArrayPerGeoType; -%newobject ParaMEDMEM::MEDCouplingUMesh::getRenumArrForConsecutiveCellTypesSpec; -%newobject ParaMEDMEM::MEDCouplingUMesh::buildDirectionVectorField; -%newobject ParaMEDMEM::MEDCouplingUMesh::convertLinearCellsToQuadratic; -%newobject ParaMEDMEM::MEDCouplingUMesh::getEdgeRatioField; -%newobject ParaMEDMEM::MEDCouplingUMesh::getAspectRatioField; -%newobject ParaMEDMEM::MEDCouplingUMesh::getWarpField; -%newobject ParaMEDMEM::MEDCouplingUMesh::getSkewField; -%newobject ParaMEDMEM::MEDCouplingUMesh::getPartBarycenterAndOwner; -%newobject ParaMEDMEM::MEDCouplingUMesh::computePlaneEquationOf3DFaces; -%newobject ParaMEDMEM::MEDCouplingUMesh::getPartMeasureField; -%newobject ParaMEDMEM::MEDCouplingUMesh::buildPartOrthogonalField; -%newobject ParaMEDMEM::MEDCouplingUMesh::keepCellIdsByType; -%newobject ParaMEDMEM::MEDCouplingUMesh::Build0DMeshFromCoords; -%newobject ParaMEDMEM::MEDCouplingUMesh::findAndCorrectBadOriented3DExtrudedCells; -%newobject ParaMEDMEM::MEDCouplingUMesh::findAndCorrectBadOriented3DCells; -%newobject ParaMEDMEM::MEDCouplingUMesh::convertIntoSingleGeoTypeMesh; -%newobject ParaMEDMEM::MEDCouplingUMesh::convertNodalConnectivityToStaticGeoTypeMesh; -%newobject ParaMEDMEM::MEDCouplingUMesh::findCellIdsOnBoundary; -%newobject ParaMEDMEM::MEDCouplingUMesh::computeSkin; -%newobject ParaMEDMEM::MEDCouplingUMesh::buildSetInstanceFromThis; -%newobject ParaMEDMEM::MEDCouplingUMesh::getCellIdsCrossingPlane; -%newobject ParaMEDMEM::MEDCouplingUMesh::convexEnvelop2D; -%newobject ParaMEDMEM::MEDCouplingUMesh::ComputeRangesFromTypeDistribution; -%newobject ParaMEDMEM::MEDCouplingUMesh::buildUnionOf2DMesh; -%newobject ParaMEDMEM::MEDCouplingUMesh::buildUnionOf3DMesh; -%newobject ParaMEDMEM::MEDCouplingUMesh::generateGraph; -%newobject ParaMEDMEM::MEDCouplingUMesh::orderConsecutiveCells1D; -%newobject ParaMEDMEM::MEDCouplingUMesh::getBoundingBoxForBBTreeFast; -%newobject ParaMEDMEM::MEDCouplingUMesh::getBoundingBoxForBBTree2DQuadratic; -%newobject ParaMEDMEM::MEDCouplingUMesh::getBoundingBoxForBBTree1DQuadratic; -%newobject ParaMEDMEM::MEDCouplingUMeshCellByTypeEntry::__iter__; -%newobject ParaMEDMEM::MEDCouplingUMeshCellEntry::__iter__; -%newobject ParaMEDMEM::MEDCoupling1GTUMesh::New; -%newobject ParaMEDMEM::MEDCoupling1GTUMesh::getNodalConnectivity; -%newobject ParaMEDMEM::MEDCoupling1GTUMesh::AggregateOnSameCoordsToUMesh; -%newobject ParaMEDMEM::MEDCoupling1SGTUMesh::New; -%newobject ParaMEDMEM::MEDCoupling1SGTUMesh::buildSetInstanceFromThis; -%newobject ParaMEDMEM::MEDCoupling1SGTUMesh::computeDualMesh; -%newobject ParaMEDMEM::MEDCoupling1SGTUMesh::explodeEachHexa8To6Quad4; -%newobject ParaMEDMEM::MEDCoupling1SGTUMesh::sortHexa8EachOther; -%newobject ParaMEDMEM::MEDCoupling1SGTUMesh::Merge1SGTUMeshes; -%newobject ParaMEDMEM::MEDCoupling1SGTUMesh::Merge1SGTUMeshesOnSameCoords; -%newobject ParaMEDMEM::MEDCoupling1DGTUMesh::New; -%newobject ParaMEDMEM::MEDCoupling1DGTUMesh::getNodalConnectivityIndex; -%newobject ParaMEDMEM::MEDCoupling1DGTUMesh::buildSetInstanceFromThis; -%newobject ParaMEDMEM::MEDCoupling1DGTUMesh::Merge1DGTUMeshes; -%newobject ParaMEDMEM::MEDCoupling1DGTUMesh::Merge1DGTUMeshesOnSameCoords; -%newobject ParaMEDMEM::MEDCouplingExtrudedMesh::New; -%newobject ParaMEDMEM::MEDCouplingExtrudedMesh::build3DUnstructuredMesh; -%newobject ParaMEDMEM::MEDCouplingStructuredMesh::buildStructuredSubPart; -%newobject ParaMEDMEM::MEDCouplingStructuredMesh::build1SGTUnstructured; -%newobject ParaMEDMEM::MEDCouplingStructuredMesh::build1SGTSubLevelMesh; -%newobject ParaMEDMEM::MEDCouplingStructuredMesh::BuildExplicitIdsFrom; -%newobject ParaMEDMEM::MEDCouplingStructuredMesh::ExtractFieldOfDoubleFrom; -%newobject ParaMEDMEM::MEDCouplingStructuredMesh::Build1GTNodalConnectivity; -%newobject ParaMEDMEM::MEDCouplingStructuredMesh::Build1GTNodalConnectivityOfSubLevelMesh; -%newobject ParaMEDMEM::MEDCouplingStructuredMesh::ComputeCornersGhost; -%newobject ParaMEDMEM::MEDCouplingCMesh::New; -%newobject ParaMEDMEM::MEDCouplingCMesh::clone; -%newobject ParaMEDMEM::MEDCouplingCMesh::getCoordsAt; -%newobject ParaMEDMEM::MEDCouplingIMesh::New; -%newobject ParaMEDMEM::MEDCouplingIMesh::asSingleCell; -%newobject ParaMEDMEM::MEDCouplingIMesh::buildWithGhost; -%newobject ParaMEDMEM::MEDCouplingIMesh::convertToCartesian; -%newobject ParaMEDMEM::MEDCouplingCurveLinearMesh::New; -%newobject ParaMEDMEM::MEDCouplingCurveLinearMesh::clone; -%newobject ParaMEDMEM::MEDCouplingCurveLinearMesh::getCoords; -%newobject ParaMEDMEM::MEDCouplingMultiFields::New; -%newobject ParaMEDMEM::MEDCouplingMultiFields::deepCpy; -%newobject ParaMEDMEM::MEDCouplingFieldOverTime::New; -%newobject ParaMEDMEM::MEDCouplingCartesianAMRPatchGen::getMesh; -%newobject ParaMEDMEM::MEDCouplingCartesianAMRPatchGen::__getitem__; -%newobject ParaMEDMEM::MEDCouplingCartesianAMRMeshGen::deepCpy; -%newobject ParaMEDMEM::MEDCouplingCartesianAMRMeshGen::buildUnstructured; -%newobject ParaMEDMEM::MEDCouplingCartesianAMRMeshGen::extractGhostFrom; -%newobject ParaMEDMEM::MEDCouplingCartesianAMRMeshGen::buildMeshFromPatchEnvelop; -%newobject ParaMEDMEM::MEDCouplingCartesianAMRMeshGen::buildMeshOfDirectChildrenOnly; -%newobject ParaMEDMEM::MEDCouplingCartesianAMRMeshGen::getImageMesh; -%newobject ParaMEDMEM::MEDCouplingCartesianAMRMeshGen::getGodFather; -%newobject ParaMEDMEM::MEDCouplingCartesianAMRMeshGen::getFather; -%newobject ParaMEDMEM::MEDCouplingCartesianAMRMeshGen::getPatch; -%newobject ParaMEDMEM::MEDCouplingCartesianAMRMeshGen::createCellFieldOnPatch; -%newobject ParaMEDMEM::MEDCouplingCartesianAMRMeshGen::findPatchesInTheNeighborhoodOf; -%newobject ParaMEDMEM::MEDCouplingCartesianAMRMeshGen::getPatchAtPosition; -%newobject ParaMEDMEM::MEDCouplingCartesianAMRMeshGen::getMeshAtPosition; -%newobject ParaMEDMEM::MEDCouplingCartesianAMRMeshGen::__getitem__; -%newobject ParaMEDMEM::MEDCouplingCartesianAMRMesh::New; -%newobject ParaMEDMEM::MEDCouplingDataForGodFather::getMyGodFather; -%newobject ParaMEDMEM::MEDCouplingAMRAttribute::New; -%newobject ParaMEDMEM::MEDCouplingAMRAttribute::deepCpy; -%newobject ParaMEDMEM::MEDCouplingAMRAttribute::deepCpyWithoutGodFather; -%newobject ParaMEDMEM::MEDCouplingAMRAttribute::getFieldOn; -%newobject ParaMEDMEM::MEDCouplingAMRAttribute::projectTo; -%newobject ParaMEDMEM::MEDCouplingAMRAttribute::buildCellFieldOnRecurseWithoutOverlapWithoutGhost; -%newobject ParaMEDMEM::MEDCouplingAMRAttribute::buildCellFieldOnWithGhost; -%newobject ParaMEDMEM::MEDCouplingAMRAttribute::buildCellFieldOnWithoutGhost; -%newobject ParaMEDMEM::DenseMatrix::New; -%newobject ParaMEDMEM::DenseMatrix::deepCpy; -%newobject ParaMEDMEM::DenseMatrix::shallowCpy; -%newobject ParaMEDMEM::DenseMatrix::getData; -%newobject ParaMEDMEM::DenseMatrix::matVecMult; -%newobject ParaMEDMEM::DenseMatrix::MatVecMult; -%newobject ParaMEDMEM::DenseMatrix::__add__; -%newobject ParaMEDMEM::DenseMatrix::__sub__; -%newobject ParaMEDMEM::DenseMatrix::__mul__; -%newobject ParaMEDMEM::PartDefinition::New; -%newobject ParaMEDMEM::PartDefinition::toDAI; -%newobject ParaMEDMEM::PartDefinition::__add__; -%newobject ParaMEDMEM::PartDefinition::composeWith; -%newobject ParaMEDMEM::PartDefinition::tryToSimplify; -%newobject ParaMEDMEM::DataArrayPartDefinition::New; -%newobject ParaMEDMEM::SlicePartDefinition::New; - -%feature("unref") MEDCouplingPointSet "$this->decrRef();" -%feature("unref") MEDCouplingMesh "$this->decrRef();" -%feature("unref") MEDCouplingUMesh "$this->decrRef();" -%feature("unref") MEDCoupling1GTUMesh "$this->decrRef();" -%feature("unref") MEDCoupling1SGTUMesh "$this->decrRef();" -%feature("unref") MEDCoupling1DGTUMesh "$this->decrRef();" -%feature("unref") MEDCouplingExtrudedMesh "$this->decrRef();" -%feature("unref") MEDCouplingCMesh "$this->decrRef();" -%feature("unref") MEDCouplingIMesh "$this->decrRef();" -%feature("unref") MEDCouplingCurveLinearMesh "$this->decrRef();" -%feature("unref") MEDCouplingField "$this->decrRef();" -%feature("unref") MEDCouplingFieldDiscretizationP0 "$this->decrRef();" -%feature("unref") MEDCouplingFieldDiscretizationP1 "$this->decrRef();" -%feature("unref") MEDCouplingFieldDiscretizationGauss "$this->decrRef();" -%feature("unref") MEDCouplingFieldDiscretizationGaussNE "$this->decrRef();" -%feature("unref") MEDCouplingFieldDiscretizationKriging "$this->decrRef();" -%feature("unref") MEDCouplingFieldDouble "$this->decrRef();" -%feature("unref") MEDCouplingMultiFields "$this->decrRef();" -%feature("unref") MEDCouplingFieldTemplate "$this->decrRef();" -%feature("unref") MEDCouplingMultiFields "$this->decrRef();" -%feature("unref") MEDCouplingCartesianAMRMeshGen "$this->decrRef();" -%feature("unref") MEDCouplingCartesianAMRMesh "$this->decrRef();" -%feature("unref") MEDCouplingCartesianAMRMeshSub "$this->decrRef();" -%feature("unref") MEDCouplingCartesianAMRPatchGen "$this->decrRef();" -%feature("unref") MEDCouplingCartesianAMRPatchGF "$this->decrRef();" -%feature("unref") MEDCouplingCartesianAMRPatch "$this->decrRef();" -%feature("unref") MEDCouplingDataForGodFather "$this->decrRef();" -%feature("unref") MEDCouplingAMRAttribute "$this->decrRef();" -%feature("unref") DenseMatrix "$this->decrRef();" -%feature("unref") PartDefinition "$this->decrRef();" -%feature("unref") DataArrayPartDefinition "$this->decrRef();" -%feature("unref") SlicePartDefinition "$this->decrRef();" - -%rename(assign) *::operator=; -%ignore ParaMEDMEM::MEDCouplingGaussLocalization::pushTinySerializationIntInfo; -%ignore ParaMEDMEM::MEDCouplingGaussLocalization::pushTinySerializationDblInfo; -%ignore ParaMEDMEM::MEDCouplingGaussLocalization::fillWithValues; -%ignore ParaMEDMEM::MEDCouplingGaussLocalization::buildNewInstanceFromTinyInfo; - -%nodefaultctor; - -%rename (InterpKernelException) INTERP_KERNEL::Exception; - -%include "MEDCouplingRefCountObject.i" -%include "MEDCouplingMemArray.i" - -namespace INTERP_KERNEL -{ - /*! - * \class BoxSplittingOptions - * Class defining the options for box splitting used for AMR algorithm like creation of patches following a criterion. - */ - class BoxSplittingOptions - { - public: - BoxSplittingOptions(); - void init() throw(INTERP_KERNEL::Exception); - double getEfficiencyGoal() const throw(INTERP_KERNEL::Exception); - void setEfficiencyGoal(double efficiency) throw(INTERP_KERNEL::Exception); - double getEfficiencyThreshold() const throw(INTERP_KERNEL::Exception); - void setEfficiencyThreshold(double efficiencyThreshold) throw(INTERP_KERNEL::Exception); - int getMinimumPatchLength() const throw(INTERP_KERNEL::Exception); - void setMinimumPatchLength(int minPatchLength) throw(INTERP_KERNEL::Exception); - int getMaximumPatchLength() const throw(INTERP_KERNEL::Exception); - void setMaximumPatchLength(int maxPatchLength) throw(INTERP_KERNEL::Exception); - int getMaximumNbOfCellsInPatch() const throw(INTERP_KERNEL::Exception); - void setMaximumNbOfCellsInPatch(int maxNbCellsInPatch) throw(INTERP_KERNEL::Exception); - void copyOptions(const BoxSplittingOptions & other) throw(INTERP_KERNEL::Exception); - std::string printOptions() const throw(INTERP_KERNEL::Exception); - %extend - { - std::string __str__() const throw(INTERP_KERNEL::Exception) - { - return self->printOptions(); - } - } - }; -} - -namespace ParaMEDMEM -{ - typedef enum - { - ON_CELLS = 0, - ON_NODES = 1, - ON_GAUSS_PT = 2, - ON_GAUSS_NE = 3, - ON_NODES_KR = 4 - } TypeOfField; - - typedef enum - { - NO_TIME = 4, - ONE_TIME = 5, - LINEAR_TIME = 6, - CONST_ON_TIME_INTERVAL = 7 - } TypeOfTimeDiscretization; - - typedef enum - { - UNSTRUCTURED = 5, - CARTESIAN = 7, - EXTRUDED = 8, - CURVE_LINEAR = 9, - SINGLE_STATIC_GEO_TYPE_UNSTRUCTURED = 10, - SINGLE_DYNAMIC_GEO_TYPE_UNSTRUCTURED = 11, - IMAGE_GRID = 12 - } MEDCouplingMeshType; - - class DataArrayInt; - class DataArrayDouble; - class MEDCouplingUMesh; - class MEDCouplingFieldDouble; - - %extend RefCountObject - { - std::string getHiddenCppPointer() const - { - std::ostringstream oss; oss << "C++ Pointer address is : " << self; - return oss.str(); - } - } - - %extend MEDCouplingGaussLocalization - { - std::string __str__() const throw(INTERP_KERNEL::Exception) - { - return self->getStringRepr(); - } - - std::string __repr__() const throw(INTERP_KERNEL::Exception) - { - std::ostringstream oss; oss << "MEDCouplingGaussLocalization C++ instance at " << self << "." << std::endl; - oss << self->getStringRepr(); - return oss.str(); - } - } - - //== MEDCouplingMesh - - class MEDCouplingMesh : public RefCountObject, public TimeLabel - { - public: - void setName(const std::string& name); - std::string getName() const; - void setDescription(const std::string& descr); - std::string getDescription() const; - void setTime(double val, int iteration, int order); - void setTimeUnit(const std::string& unit); - std::string getTimeUnit() const; - virtual MEDCouplingMeshType getType() const throw(INTERP_KERNEL::Exception); - bool isStructured() const throw(INTERP_KERNEL::Exception); - virtual MEDCouplingMesh *deepCpy() const; - virtual bool isEqual(const MEDCouplingMesh *other, double prec) const throw(INTERP_KERNEL::Exception); - virtual bool isEqualWithoutConsideringStr(const MEDCouplingMesh *other, double prec) const throw(INTERP_KERNEL::Exception); - virtual void checkFastEquivalWith(const MEDCouplingMesh *other, double prec) const throw(INTERP_KERNEL::Exception); - virtual void copyTinyStringsFrom(const MEDCouplingMesh *other) throw(INTERP_KERNEL::Exception); - virtual void copyTinyInfoFrom(const MEDCouplingMesh *other) throw(INTERP_KERNEL::Exception); - virtual void checkCoherency() const throw(INTERP_KERNEL::Exception); - virtual void checkCoherency1(double eps=1e-12) const throw(INTERP_KERNEL::Exception); - virtual void checkCoherency2(double eps=1e-12) const throw(INTERP_KERNEL::Exception); - virtual int getNumberOfCells() const throw(INTERP_KERNEL::Exception); - virtual int getNumberOfNodes() const throw(INTERP_KERNEL::Exception); - virtual int getSpaceDimension() const throw(INTERP_KERNEL::Exception); - virtual int getMeshDimension() const throw(INTERP_KERNEL::Exception); - virtual DataArrayDouble *getCoordinatesAndOwner() const throw(INTERP_KERNEL::Exception); - virtual DataArrayDouble *getBarycenterAndOwner() const throw(INTERP_KERNEL::Exception); - virtual DataArrayDouble *computeIsoBarycenterOfNodesPerCell() const throw(INTERP_KERNEL::Exception); - virtual DataArrayInt *giveCellsWithType(INTERP_KERNEL::NormalizedCellType type) const throw(INTERP_KERNEL::Exception); - virtual DataArrayInt *computeNbOfNodesPerCell() const throw(INTERP_KERNEL::Exception); - virtual DataArrayInt *computeNbOfFacesPerCell() const throw(INTERP_KERNEL::Exception); - virtual DataArrayInt *computeEffectiveNbOfNodesPerCell() const throw(INTERP_KERNEL::Exception); - virtual MEDCouplingMesh *buildPartRange(int beginCellIds, int endCellIds, int stepCellIds) const throw(INTERP_KERNEL::Exception); - virtual int getNumberOfCellsWithType(INTERP_KERNEL::NormalizedCellType type) const throw(INTERP_KERNEL::Exception); - virtual INTERP_KERNEL::NormalizedCellType getTypeOfCell(int cellId) const throw(INTERP_KERNEL::Exception); - virtual std::string simpleRepr() const throw(INTERP_KERNEL::Exception); - virtual std::string advancedRepr() const throw(INTERP_KERNEL::Exception); - std::string writeVTK(const std::string& fileName, bool isBinary=true) const throw(INTERP_KERNEL::Exception); - virtual std::string getVTKFileExtension() const; - std::string getVTKFileNameOf(const std::string& fileName) const; - // tools - virtual MEDCouplingFieldDouble *getMeasureField(bool isAbs) const throw(INTERP_KERNEL::Exception); - virtual MEDCouplingFieldDouble *getMeasureFieldOnNode(bool isAbs) const throw(INTERP_KERNEL::Exception); - virtual MEDCouplingFieldDouble *fillFromAnalytic(TypeOfField t, int nbOfComp, const std::string& func) const throw(INTERP_KERNEL::Exception); - virtual MEDCouplingFieldDouble *fillFromAnalytic2(TypeOfField t, int nbOfComp, const std::string& func) const throw(INTERP_KERNEL::Exception); - virtual MEDCouplingFieldDouble *fillFromAnalytic3(TypeOfField t, int nbOfComp, const std::vector& varsOrder, const std::string& func) const throw(INTERP_KERNEL::Exception); - virtual MEDCouplingFieldDouble *buildOrthogonalField() const throw(INTERP_KERNEL::Exception); - virtual MEDCouplingUMesh *buildUnstructured() const throw(INTERP_KERNEL::Exception); - virtual MEDCouplingMesh *mergeMyselfWith(const MEDCouplingMesh *other) const throw(INTERP_KERNEL::Exception); - virtual bool areCompatibleForMerge(const MEDCouplingMesh *other) const throw(INTERP_KERNEL::Exception); - virtual DataArrayInt *simplexize(int policy) throw(INTERP_KERNEL::Exception); - virtual void unserialization(const std::vector& tinyInfoD, const std::vector& tinyInfo, const DataArrayInt *a1, DataArrayDouble *a2, const std::vector& littleStrings) throw(INTERP_KERNEL::Exception); - static MEDCouplingMesh *MergeMeshes(const MEDCouplingMesh *mesh1, const MEDCouplingMesh *mesh2) 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); - %extend - { - std::string __str__() const throw(INTERP_KERNEL::Exception) - { - return self->simpleRepr(); - } - - PyObject *getTime() throw(INTERP_KERNEL::Exception) - { - int tmp1,tmp2; - double tmp0=self->getTime(tmp1,tmp2); - PyObject *res = PyList_New(3); - PyList_SetItem(res,0,SWIG_From_double(tmp0)); - PyList_SetItem(res,1,SWIG_From_int(tmp1)); - PyList_SetItem(res,2,SWIG_From_int(tmp2)); - return res; - } - - int getCellContainingPoint(PyObject *p, double eps) const throw(INTERP_KERNEL::Exception) - { - double val; - DataArrayDouble *a; - DataArrayDoubleTuple *aa; - std::vector bb; - int sw; - int spaceDim=self->getSpaceDimension(); - const char msg[]="Python wrap of MEDCouplingMesh::getCellContainingPoint : "; - const double *pos=convertObjToPossibleCpp5_Safe(p,sw,val,a,aa,bb,msg,1,spaceDim,true); - return self->getCellContainingPoint(pos,eps); - } - - PyObject *getCellsContainingPoints(PyObject *p, int nbOfPoints, double eps) const throw(INTERP_KERNEL::Exception) - { - double val; - DataArrayDouble *a; - DataArrayDoubleTuple *aa; - std::vector bb; - int sw; - int spaceDim=self->getSpaceDimension(); - const char msg[]="Python wrap of MEDCouplingMesh::getCellsContainingPoint : "; - const double *pos=convertObjToPossibleCpp5_Safe(p,sw,val,a,aa,bb,msg,nbOfPoints,spaceDim,true); - MEDCouplingAutoRefCountObjectPtr elts,eltsIndex; - self->getCellsContainingPoints(pos,nbOfPoints,eps,elts,eltsIndex); - PyObject *ret=PyTuple_New(2); - PyTuple_SetItem(ret,0,SWIG_NewPointerObj(SWIG_as_voidptr(elts.retn()),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 )); - PyTuple_SetItem(ret,1,SWIG_NewPointerObj(SWIG_as_voidptr(eltsIndex.retn()),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 )); - return ret; - } - - PyObject *getCellsContainingPoints(PyObject *p, double eps) const throw(INTERP_KERNEL::Exception) - { - MEDCouplingAutoRefCountObjectPtr elts,eltsIndex; - int spaceDim=self->getSpaceDimension(); - void *da=0; - int res1=SWIG_ConvertPtr(p,&da,SWIGTYPE_p_ParaMEDMEM__DataArrayDouble, 0 | 0 ); - if (!SWIG_IsOK(res1)) - { - int size; - INTERP_KERNEL::AutoCPtr tmp=convertPyToNewDblArr2(p,&size); - int nbOfPoints=size/spaceDim; - if(size%spaceDim!=0) - { - throw INTERP_KERNEL::Exception("MEDCouplingMesh::getCellsContainingPoints : Invalid list length ! Must be a multiple of self.getSpaceDimension() !"); - } - self->getCellsContainingPoints(tmp,nbOfPoints,eps,elts,eltsIndex); - } - else - { - DataArrayDouble *da2=reinterpret_cast< DataArrayDouble * >(da); - if(!da2) - throw INTERP_KERNEL::Exception("MEDCouplingMesh::getCellsContainingPoints : Not null DataArrayDouble instance expected !"); - da2->checkAllocated(); - int size=da2->getNumberOfTuples(); - int nbOfCompo=da2->getNumberOfComponents(); - if(nbOfCompo!=spaceDim) - { - throw INTERP_KERNEL::Exception("MEDCouplingMesh::getCellsContainingPoints : Invalid DataArrayDouble nb of components ! Expected same as self.getSpaceDimension() !"); - } - self->getCellsContainingPoints(da2->getConstPointer(),size,eps,elts,eltsIndex); - } - PyObject *ret=PyTuple_New(2); - PyTuple_SetItem(ret,0,SWIG_NewPointerObj(SWIG_as_voidptr(elts.retn()),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 )); - PyTuple_SetItem(ret,1,SWIG_NewPointerObj(SWIG_as_voidptr(eltsIndex.retn()),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 )); - return ret; - } - - PyObject *getCellsContainingPoint(PyObject *p, double eps) const throw(INTERP_KERNEL::Exception) - { - double val; - DataArrayDouble *a; - DataArrayDoubleTuple *aa; - std::vector bb; - int sw; - int spaceDim=self->getSpaceDimension(); - const char msg[]="Python wrap of MEDCouplingUMesh::getCellsContainingPoint : "; - const double *pos=convertObjToPossibleCpp5_Safe(p,sw,val,a,aa,bb,msg,1,spaceDim,true); - std::vector elts; - self->getCellsContainingPoint(pos,eps,elts); - DataArrayInt *ret=DataArrayInt::New(); - ret->alloc((int)elts.size(),1); - std::copy(elts.begin(),elts.end(),ret->getPointer()); - return SWIG_NewPointerObj(SWIG_as_voidptr(ret),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 ); - } - - virtual PyObject *getReverseNodalConnectivity() const throw(INTERP_KERNEL::Exception) - { - MEDCouplingAutoRefCountObjectPtr d0=DataArrayInt::New(); - MEDCouplingAutoRefCountObjectPtr d1=DataArrayInt::New(); - self->getReverseNodalConnectivity(d0,d1); - PyObject *ret=PyTuple_New(2); - PyTuple_SetItem(ret,0,SWIG_NewPointerObj(SWIG_as_voidptr(d0.retn()),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 )); - PyTuple_SetItem(ret,1,SWIG_NewPointerObj(SWIG_as_voidptr(d1.retn()),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 )); - return ret; - } - - void renumberCells(PyObject *li, bool check=true) throw(INTERP_KERNEL::Exception) - { - int sw,sz(-1); - int v0; std::vector v1; - const int *ids(convertObjToPossibleCpp1_Safe(li,sw,sz,v0,v1)); - self->renumberCells(ids,check); - } - - PyObject *checkGeoEquivalWith(const MEDCouplingMesh *other, int levOfCheck, double prec) const throw(INTERP_KERNEL::Exception) - { - DataArrayInt *cellCor, *nodeCor; - self->checkGeoEquivalWith(other,levOfCheck,prec,cellCor,nodeCor); - PyObject *res = PyList_New(2); - PyList_SetItem(res,0,SWIG_NewPointerObj(SWIG_as_voidptr(cellCor),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, cellCor?SWIG_POINTER_OWN | 0:0 )); - PyList_SetItem(res,1,SWIG_NewPointerObj(SWIG_as_voidptr(nodeCor),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, nodeCor?SWIG_POINTER_OWN | 0:0 )); - return res; - } - - PyObject *checkDeepEquivalWith(const MEDCouplingMesh *other, int cellCompPol, double prec) const throw(INTERP_KERNEL::Exception) - { - DataArrayInt *cellCor=0,*nodeCor=0; - self->checkDeepEquivalWith(other,cellCompPol,prec,cellCor,nodeCor); - PyObject *res = PyList_New(2); - PyList_SetItem(res,0,SWIG_NewPointerObj(SWIG_as_voidptr(cellCor),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, cellCor?SWIG_POINTER_OWN | 0:0 )); - PyList_SetItem(res,1,SWIG_NewPointerObj(SWIG_as_voidptr(nodeCor),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, nodeCor?SWIG_POINTER_OWN | 0:0 )); - return res; - } - - DataArrayInt *checkDeepEquivalOnSameNodesWith(const MEDCouplingMesh *other, int cellCompPol, double prec) const throw(INTERP_KERNEL::Exception) - { - DataArrayInt *cellCor=0; - self->checkDeepEquivalOnSameNodesWith(other,cellCompPol,prec,cellCor); - return cellCor; - } - - DataArrayInt *getCellIdsFullyIncludedInNodeIds(PyObject *li) const throw(INTERP_KERNEL::Exception) - { - void *da=0; - int res1=SWIG_ConvertPtr(li,&da,SWIGTYPE_p_ParaMEDMEM__DataArrayInt, 0 | 0 ); - if (!SWIG_IsOK(res1)) - { - int size; - INTERP_KERNEL::AutoPtr tmp=convertPyToNewIntArr2(li,&size); - return self->getCellIdsFullyIncludedInNodeIds(tmp,((const int *)tmp)+size); - } - else - { - DataArrayInt *da2=reinterpret_cast< DataArrayInt * >(da); - if(!da2) - throw INTERP_KERNEL::Exception("Not null DataArrayInt instance expected !"); - da2->checkAllocated(); - return self->getCellIdsFullyIncludedInNodeIds(da2->getConstPointer(),da2->getConstPointer()+da2->getNbOfElems()); - } - } - PyObject *getNodeIdsOfCell(int cellId) const throw(INTERP_KERNEL::Exception) - { - std::vector conn; - self->getNodeIdsOfCell(cellId,conn); - return convertIntArrToPyList2(conn); - } - - PyObject *getCoordinatesOfNode(int nodeId) const throw(INTERP_KERNEL::Exception) - { - std::vector coo; - self->getCoordinatesOfNode(nodeId,coo); - return convertDblArrToPyList2(coo); - } - - void scale(PyObject *point, double factor) throw(INTERP_KERNEL::Exception) - { - double val; - DataArrayDouble *a; - DataArrayDoubleTuple *aa; - std::vector bb; - int sw; - int spaceDim=self->getSpaceDimension(); - const char msg[]="Python wrap of MEDCouplingPointSet::scale : "; - const double *pointPtr=convertObjToPossibleCpp5_Safe(point,sw,val,a,aa,bb,msg,1,spaceDim,true); - self->scale(pointPtr,factor); - } - - PyObject *getBoundingBox() const throw(INTERP_KERNEL::Exception) - { - int spaceDim=self->getSpaceDimension(); - INTERP_KERNEL::AutoPtr tmp=new double[2*spaceDim]; - self->getBoundingBox(tmp); - PyObject *ret=convertDblArrToPyListOfTuple(tmp,2,spaceDim); - return ret; - } - - PyObject *isEqualIfNotWhy(const MEDCouplingMesh *other, double prec) const throw(INTERP_KERNEL::Exception) - { - std::string ret1; - bool ret0=self->isEqualIfNotWhy(other,prec,ret1); - PyObject *ret=PyTuple_New(2); - PyObject *ret0Py=ret0?Py_True:Py_False; - Py_XINCREF(ret0Py); - PyTuple_SetItem(ret,0,ret0Py); - PyTuple_SetItem(ret,1,PyString_FromString(ret1.c_str())); - return ret; - } - - PyObject *buildPart(PyObject *li) const throw(INTERP_KERNEL::Exception) - { - int szArr,sw,iTypppArr; - std::vector stdvecTyyppArr; - const int *tmp=convertObjToPossibleCpp1_Safe(li,sw,szArr,iTypppArr,stdvecTyyppArr); - MEDCouplingMesh *ret=self->buildPart(tmp,tmp+szArr); - if(sw==3)//DataArrayInt - { - void *argp; SWIG_ConvertPtr(li,&argp,SWIGTYPE_p_ParaMEDMEM__DataArrayInt,0|0); - DataArrayInt *argpt=reinterpret_cast< ParaMEDMEM::DataArrayInt * >(argp); - std::string name=argpt->getName(); - if(!name.empty()) - ret->setName(name.c_str()); - } - return convertMesh(ret, SWIG_POINTER_OWN | 0 ); - } - - PyObject *buildPartAndReduceNodes(PyObject *li) const throw(INTERP_KERNEL::Exception) - { - int szArr,sw,iTypppArr; - std::vector stdvecTyyppArr; - DataArrayInt *arr=0; - const int *tmp=convertObjToPossibleCpp1_Safe(li,sw,szArr,iTypppArr,stdvecTyyppArr); - MEDCouplingMesh *ret=self->buildPartAndReduceNodes(tmp,tmp+szArr,arr); - if(sw==3)//DataArrayInt - { - void *argp; SWIG_ConvertPtr(li,&argp,SWIGTYPE_p_ParaMEDMEM__DataArrayInt,0|0); - DataArrayInt *argpt=reinterpret_cast< ParaMEDMEM::DataArrayInt * >(argp); - std::string name=argpt->getName(); - if(!name.empty()) - ret->setName(name.c_str()); - } - // - PyObject *res = PyList_New(2); - PyObject *obj0=convertMesh(ret, SWIG_POINTER_OWN | 0 ); - PyObject *obj1=SWIG_NewPointerObj(SWIG_as_voidptr(arr),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 ); - PyList_SetItem(res,0,obj0); - PyList_SetItem(res,1,obj1); - return res; - } - - PyObject *buildPartRangeAndReduceNodes(int beginCellIds, int endCellIds, int stepCellIds) const throw(INTERP_KERNEL::Exception) - { - int a,b,c; - DataArrayInt *arr=0; - MEDCouplingMesh *ret=self->buildPartRangeAndReduceNodes(beginCellIds,endCellIds,stepCellIds,a,b,c,arr); - PyObject *res = PyTuple_New(2); - PyObject *obj0=convertMesh(ret, SWIG_POINTER_OWN | 0 ); - PyObject *obj1=0; - if(arr) - obj1=SWIG_NewPointerObj(SWIG_as_voidptr(arr),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 ); - else - obj1=PySlice_New(PyInt_FromLong(a),PyInt_FromLong(b),PyInt_FromLong(b)); - PyTuple_SetItem(res,0,obj0); - PyTuple_SetItem(res,1,obj1); - return res; - } - - PyObject *getDistributionOfTypes() const throw(INTERP_KERNEL::Exception) - { - std::vector vals=self->getDistributionOfTypes(); - if(vals.size()%3!=0) - throw INTERP_KERNEL::Exception("Internal Error detected in wrap python ! code returned by MEDCouplingMesh::getDistributionOfTypes is not so that %3==0 !"); - PyObject *ret=PyList_New((int)vals.size()/3); - for(int j=0;j<(int)vals.size()/3;j++) - { - PyObject *ret1=PyList_New(3); - PyList_SetItem(ret1,0,SWIG_From_int(vals[3*j])); - PyList_SetItem(ret1,1,SWIG_From_int(vals[3*j+1])); - PyList_SetItem(ret1,2,SWIG_From_int(vals[3*j+2])); - PyList_SetItem(ret,j,ret1); - } - return ret; - } - - DataArrayInt *checkTypeConsistencyAndContig(PyObject *li, PyObject *li2) const throw(INTERP_KERNEL::Exception) - { - std::vector code; - std::vector idsPerType; - convertFromPyObjVectorOfObj(li2,SWIGTYPE_p_ParaMEDMEM__DataArrayInt,"DataArrayInt",idsPerType); - convertPyToNewIntArr4(li,1,3,code); - return self->checkTypeConsistencyAndContig(code,idsPerType); - } - - PyObject *splitProfilePerType(const DataArrayInt *profile) const throw(INTERP_KERNEL::Exception) - { - std::vector code; - std::vector idsInPflPerType; - std::vector idsPerType; - self->splitProfilePerType(profile,code,idsInPflPerType,idsPerType); - PyObject *ret=PyTuple_New(3); - // - if(code.size()%3!=0) - throw INTERP_KERNEL::Exception("Internal Error detected in wrap python ! code returned by MEDCouplingMesh::splitProfilePerType is not so that %3==0 !"); - PyObject *ret0=PyList_New((int)code.size()/3); - for(int j=0;j<(int)code.size()/3;j++) - { - PyObject *ret00=PyList_New(3); - PyList_SetItem(ret00,0,SWIG_From_int(code[3*j])); - PyList_SetItem(ret00,1,SWIG_From_int(code[3*j+1])); - PyList_SetItem(ret00,2,SWIG_From_int(code[3*j+2])); - PyList_SetItem(ret0,j,ret00); - } - PyTuple_SetItem(ret,0,ret0); - // - PyObject *ret1=PyList_New(idsInPflPerType.size()); - for(std::size_t j=0;j bb; - int sw; - int spaceDim=self->getSpaceDimension(); - const char msg[]="Python wrap of MEDCouplingPointSet::translate : "; - const double *vectorPtr=convertObjToPossibleCpp5_Safe(vector,sw,val,a,aa,bb,msg,1,spaceDim,true); - self->translate(vectorPtr); - } - - void rotate(PyObject *center, double alpha) throw(INTERP_KERNEL::Exception) - { - const char msg[]="Python wrap of MEDCouplingPointSet::rotate : "; - double val; - DataArrayDouble *a; - DataArrayDoubleTuple *aa; - std::vector bb; - int sw; - int spaceDim=self->getSpaceDimension(); - const double *centerPtr=convertObjToPossibleCpp5_Safe(center,sw,val,a,aa,bb,msg,1,spaceDim,true); - self->rotate(centerPtr,0,alpha); - } - - void rotate(PyObject *center, PyObject *vector, double alpha) throw(INTERP_KERNEL::Exception) - { - const char msg[]="Python wrap of MEDCouplingPointSet::rotate : "; - double val,val2; - DataArrayDouble *a,*a2; - DataArrayDoubleTuple *aa,*aa2; - std::vector bb,bb2; - int sw; - int spaceDim=self->getSpaceDimension(); - const double *centerPtr=convertObjToPossibleCpp5_Safe(center,sw,val,a,aa,bb,msg,1,spaceDim,true); - const double *vectorPtr=convertObjToPossibleCpp5_Safe(vector,sw,val2,a2,aa2,bb2,msg,1,spaceDim,false);//vectorPtr can be null in case of space dim 2 - self->rotate(centerPtr,vectorPtr,alpha); - } - - PyObject *getAllGeoTypes() const throw(INTERP_KERNEL::Exception) - { - std::set result=self->getAllGeoTypes(); - std::set::const_iterator iL=result.begin(); - PyObject *res=PyList_New(result.size()); - for(int i=0;iL!=result.end(); i++, iL++) - PyList_SetItem(res,i,PyInt_FromLong(*iL)); - return res; - } - - virtual PyObject *getTinySerializationInformation() const throw(INTERP_KERNEL::Exception) - { - std::vector a0; - std::vector a1; - std::vector a2; - self->getTinySerializationInformation(a0,a1,a2); - PyObject *ret(PyTuple_New(3)); - PyTuple_SetItem(ret,0,convertDblArrToPyList2(a0)); - PyTuple_SetItem(ret,1,convertIntArrToPyList2(a1)); - int sz(a2.size()); - PyObject *ret2(PyList_New(sz)); - { - for(int i=0;iserialize(a0Tmp,a1Tmp); - PyObject *ret(PyTuple_New(2)); - PyTuple_SetItem(ret,0,SWIG_NewPointerObj(SWIG_as_voidptr(a0Tmp),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 )); - PyTuple_SetItem(ret,1,SWIG_NewPointerObj(SWIG_as_voidptr(a1Tmp),SWIGTYPE_p_ParaMEDMEM__DataArrayDouble, SWIG_POINTER_OWN | 0 )); - return ret; - } - - void resizeForUnserialization(const std::vector& tinyInfo, DataArrayInt *a1, DataArrayDouble *a2) const throw(INTERP_KERNEL::Exception) - { - std::vector littleStrings; - self->resizeForUnserialization(tinyInfo,a1,a2,littleStrings); - } - - PyObject *__getnewargs__() throw(INTERP_KERNEL::Exception) - {// put an empty dict in input to say to __new__ to call __init__... - PyObject *ret(PyTuple_New(1)); - PyObject *ret0(PyDict_New()); - PyTuple_SetItem(ret,0,ret0); - return ret; - } - - PyObject *__getstate__() const throw(INTERP_KERNEL::Exception) - { - PyObject *ret0(ParaMEDMEM_MEDCouplingMesh_getTinySerializationInformation(self)); - PyObject *ret1(ParaMEDMEM_MEDCouplingMesh_serialize(self)); - PyObject *ret(PyTuple_New(2)); - PyTuple_SetItem(ret,0,ret0); - PyTuple_SetItem(ret,1,ret1); - return ret; - } - - void __setstate__(PyObject *inp) throw(INTERP_KERNEL::Exception) - { - static const char MSG[]="MEDCouplingMesh.__setstate__ : expected input is a tuple of size 2 !"; - if(!PyTuple_Check(inp)) - throw INTERP_KERNEL::Exception(MSG); - int sz(PyTuple_Size(inp)); - if(sz!=2) - throw INTERP_KERNEL::Exception(MSG); - PyObject *elt0(PyTuple_GetItem(inp,0)); - PyObject *elt1(PyTuple_GetItem(inp,1)); - std::vector a0; - std::vector a1; - std::vector a2; - DataArrayInt *b0(0); - DataArrayDouble *b1(0); - { - if(!PyTuple_Check(elt0) && PyTuple_Size(elt0)!=3) - throw INTERP_KERNEL::Exception(MSG); - PyObject *a0py(PyTuple_GetItem(elt0,0)),*a1py(PyTuple_GetItem(elt0,1)),*a2py(PyTuple_GetItem(elt0,2)); - int tmp(-1); - fillArrayWithPyListDbl3(a0py,tmp,a0); - convertPyToNewIntArr3(a1py,a1); - fillStringVector(a2py,a2); - } - { - if(!PyTuple_Check(elt1) && PyTuple_Size(elt1)!=2) - throw INTERP_KERNEL::Exception(MSG); - PyObject *b0py(PyTuple_GetItem(elt1,0)),*b1py(PyTuple_GetItem(elt1,1)); - void *argp(0); - int status(SWIG_ConvertPtr(b0py,&argp,SWIGTYPE_p_ParaMEDMEM__DataArrayInt,0|0)); - if(!SWIG_IsOK(status)) - throw INTERP_KERNEL::Exception(MSG); - b0=reinterpret_cast(argp); - status=SWIG_ConvertPtr(b1py,&argp,SWIGTYPE_p_ParaMEDMEM__DataArrayDouble,0|0); - if(!SWIG_IsOK(status)) - throw INTERP_KERNEL::Exception(MSG); - b1=reinterpret_cast(argp); - } - // useless here to call resizeForUnserialization because arrays are well resized. - self->unserialization(a0,a1,b0,b1,a2); - } - - static MEDCouplingMesh *MergeMeshes(PyObject *li) throw(INTERP_KERNEL::Exception) - { - std::vector tmp; - convertFromPyObjVectorOfObj(li,SWIGTYPE_p_ParaMEDMEM__MEDCouplingMesh,"MEDCouplingMesh",tmp); - return MEDCouplingMesh::MergeMeshes(tmp); - } - } - }; -} - -//== MEDCouplingMesh End - -%include "NormalizedGeometricTypes" -%include "MEDCouplingNatureOfFieldEnum" -// -namespace ParaMEDMEM -{ - class MEDCouplingNatureOfField - { - public: - static const char *GetRepr(NatureOfField nat) throw(INTERP_KERNEL::Exception); - static std::string GetReprNoThrow(NatureOfField nat); - static std::string GetAllPossibilitiesStr(); - }; -} - -// the MEDCouplingTimeDiscretization classes are not swigged : in case the file can help -// include "MEDCouplingTimeDiscretization.i" - -namespace ParaMEDMEM -{ - class MEDCouplingGaussLocalization - { - 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 throw(INTERP_KERNEL::Exception); - void setType(INTERP_KERNEL::NormalizedCellType typ) throw(INTERP_KERNEL::Exception); - int getNumberOfGaussPt() const throw(INTERP_KERNEL::Exception); - int getDimension() const throw(INTERP_KERNEL::Exception); - int getNumberOfPtsInRefCell() const throw(INTERP_KERNEL::Exception); - std::string getStringRepr() const throw(INTERP_KERNEL::Exception); - void checkCoherency() const throw(INTERP_KERNEL::Exception); - bool isEqual(const MEDCouplingGaussLocalization& other, double eps) const throw(INTERP_KERNEL::Exception); - // - const std::vector& getRefCoords() const throw(INTERP_KERNEL::Exception); - double getRefCoord(int ptIdInCell, int comp) const throw(INTERP_KERNEL::Exception); - const std::vector& getGaussCoords() const throw(INTERP_KERNEL::Exception); - double getGaussCoord(int gaussPtIdInCell, int comp) const throw(INTERP_KERNEL::Exception); - const std::vector& getWeights() const throw(INTERP_KERNEL::Exception); - double getWeight(int gaussPtIdInCell, double newVal) const throw(INTERP_KERNEL::Exception); - 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 bool AreAlmostEqual(const std::vector& v1, const std::vector& v2, double eps); - }; - - class MEDCouplingSkyLineArray - { - public: - MEDCouplingSkyLineArray(); - MEDCouplingSkyLineArray( const MEDCouplingSkyLineArray &myArray ); - MEDCouplingSkyLineArray( DataArrayInt* index, DataArrayInt* value ); - MEDCouplingSkyLineArray( const std::vector& index, const std::vector& value ); - - void set( DataArrayInt* index, DataArrayInt* value ); - int getNumberOf() const; - int getLength() const; - DataArrayInt* getIndexArray() const; - DataArrayInt* getValueArray() const; - %extend - { - std::string __str__() const throw(INTERP_KERNEL::Exception) - { - return self->simpleRepr(); - } - } - }; -} - -%include "MEDCouplingFieldDiscretization.i" - -//== MEDCouplingPointSet - -namespace ParaMEDMEM -{ - class MEDCouplingPointSet : public ParaMEDMEM::MEDCouplingMesh - { - public: - void setCoords(const DataArrayDouble *coords) throw(INTERP_KERNEL::Exception); - DataArrayDouble *getCoordinatesAndOwner() const throw(INTERP_KERNEL::Exception); - bool areCoordsEqual(const MEDCouplingPointSet& other, double prec) const throw(INTERP_KERNEL::Exception); - void zipCoords() throw(INTERP_KERNEL::Exception); - double getCaracteristicDimension() const throw(INTERP_KERNEL::Exception); - void recenterForMaxPrecision(double eps) throw(INTERP_KERNEL::Exception); - void changeSpaceDimension(int newSpaceDim, double dftVal=0.) throw(INTERP_KERNEL::Exception); - void tryToShareSameCoords(const MEDCouplingPointSet& other, double epsilon) throw(INTERP_KERNEL::Exception); - virtual void shallowCopyConnectivityFrom(const MEDCouplingPointSet *other) throw(INTERP_KERNEL::Exception); - virtual MEDCouplingPointSet *buildPartOfMySelf2(int start, int end, int step) const throw(INTERP_KERNEL::Exception); - virtual void tryToShareSameCoordsPermute(const MEDCouplingPointSet& other, double epsilon) throw(INTERP_KERNEL::Exception); - static DataArrayDouble *MergeNodesArray(const MEDCouplingPointSet *m1, const MEDCouplingPointSet *m2) throw(INTERP_KERNEL::Exception); - static MEDCouplingPointSet *BuildInstanceFromMeshType(MEDCouplingMeshType type) throw(INTERP_KERNEL::Exception); - static DataArrayInt *ComputeNbOfInteractionsWithSrcCells(const MEDCouplingPointSet *srcMesh, const MEDCouplingPointSet *trgMesh, double eps) throw(INTERP_KERNEL::Exception); - virtual DataArrayInt *computeFetchedNodeIds() const throw(INTERP_KERNEL::Exception); - virtual int getNumberOfNodesInCell(int cellId) const throw(INTERP_KERNEL::Exception); - virtual MEDCouplingPointSet *buildBoundaryMesh(bool keepCoords) const throw(INTERP_KERNEL::Exception); - virtual DataArrayInt *getCellsInBoundingBox(const INTERP_KERNEL::DirectedBoundingBox& bbox, double eps) throw(INTERP_KERNEL::Exception); - virtual DataArrayInt *zipCoordsTraducer() throw(INTERP_KERNEL::Exception); - virtual DataArrayInt *findBoundaryNodes() const; - virtual DataArrayInt *zipConnectivityTraducer(int compType, int startCellId=0) throw(INTERP_KERNEL::Exception); - virtual MEDCouplingPointSet *mergeMyselfWithOnSameCoords(const MEDCouplingPointSet *other) const throw(INTERP_KERNEL::Exception); - virtual void checkFullyDefined() const throw(INTERP_KERNEL::Exception); - virtual bool isEmptyMesh(const std::vector& tinyInfo) const throw(INTERP_KERNEL::Exception); - virtual MEDCouplingPointSet *deepCpyConnectivityOnly() const throw(INTERP_KERNEL::Exception); - virtual DataArrayDouble *getBoundingBoxForBBTree(double arcDetEps=1e-12) const throw(INTERP_KERNEL::Exception); - virtual void renumberNodesWithOffsetInConn(int offset) throw(INTERP_KERNEL::Exception); - virtual bool areAllNodesFetched() const throw(INTERP_KERNEL::Exception); - virtual MEDCouplingFieldDouble *computeDiameterField() const throw(INTERP_KERNEL::Exception); - %extend - { - std::string __str__() const throw(INTERP_KERNEL::Exception) - { - return self->simpleRepr(); - } - - PyObject *buildNewNumberingFromCommonNodesFormat(const DataArrayInt *comm, const DataArrayInt *commIndex) const throw(INTERP_KERNEL::Exception) - { - int newNbOfNodes; - DataArrayInt *ret0=self->buildNewNumberingFromCommonNodesFormat(comm,commIndex,newNbOfNodes); - PyObject *res = PyList_New(2); - PyList_SetItem(res,0,SWIG_NewPointerObj(SWIG_as_voidptr(ret0),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 )); - PyList_SetItem(res,1,SWIG_From_int(newNbOfNodes)); - return res; - } - - PyObject *findCommonNodes(double prec, int limitTupleId=-1) const throw(INTERP_KERNEL::Exception) - { - DataArrayInt *comm, *commIndex; - self->findCommonNodes(prec,limitTupleId,comm,commIndex); - PyObject *res = PyList_New(2); - PyList_SetItem(res,0,SWIG_NewPointerObj(SWIG_as_voidptr(comm),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 )); - PyList_SetItem(res,1,SWIG_NewPointerObj(SWIG_as_voidptr(commIndex),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 )); - return res; - } - - PyObject *getCoords() throw(INTERP_KERNEL::Exception) - { - DataArrayDouble *ret1=self->getCoords(); - if (ret1) - ret1->incrRef(); - return SWIG_NewPointerObj((void*)ret1,SWIGTYPE_p_ParaMEDMEM__DataArrayDouble,SWIG_POINTER_OWN | 0); - } - - PyObject *buildPartOfMySelf(PyObject *li, bool keepCoords=true) const throw(INTERP_KERNEL::Exception) - { - int szArr,sw,iTypppArr; - std::vector stdvecTyyppArr; - const int *tmp=convertObjToPossibleCpp1_Safe(li,sw,szArr,iTypppArr,stdvecTyyppArr); - MEDCouplingPointSet *ret=self->buildPartOfMySelf(tmp,tmp+szArr,keepCoords); - if(sw==3)//DataArrayInt - { - void *argp; SWIG_ConvertPtr(li,&argp,SWIGTYPE_p_ParaMEDMEM__DataArrayInt,0|0); - DataArrayInt *argpt=reinterpret_cast< ParaMEDMEM::DataArrayInt * >(argp); - std::string name=argpt->getName(); - if(!name.empty()) - ret->setName(name.c_str()); - } - return convertMesh(ret, SWIG_POINTER_OWN | 0 ); - } - - PyObject *buildPartOfMySelfNode(PyObject *li, bool fullyIn) const throw(INTERP_KERNEL::Exception) - { - int szArr,sw,iTypppArr; - std::vector stdvecTyyppArr; - const int *tmp=convertObjToPossibleCpp1_Safe(li,sw,szArr,iTypppArr,stdvecTyyppArr); - MEDCouplingPointSet *ret=self->buildPartOfMySelfNode(tmp,tmp+szArr,fullyIn); - if(sw==3)//DataArrayInt - { - void *argp; SWIG_ConvertPtr(li,&argp,SWIGTYPE_p_ParaMEDMEM__DataArrayInt,0|0); - DataArrayInt *argpt=reinterpret_cast< ParaMEDMEM::DataArrayInt * >(argp); - std::string name=argpt->getName(); - if(!name.empty()) - ret->setName(name.c_str()); - } - return convertMesh(ret, SWIG_POINTER_OWN | 0 ); - } - - virtual PyObject *buildPartOfMySelfKeepCoords(PyObject *li) const throw(INTERP_KERNEL::Exception) - { - int szArr,sw,iTypppArr; - std::vector stdvecTyyppArr; - const int *tmp=convertObjToPossibleCpp1_Safe(li,sw,szArr,iTypppArr,stdvecTyyppArr); - MEDCouplingPointSet *ret=self->buildPartOfMySelfKeepCoords(tmp,tmp+szArr); - if(sw==3)//DataArrayInt - { - void *argp; SWIG_ConvertPtr(li,&argp,SWIGTYPE_p_ParaMEDMEM__DataArrayInt,0|0); - DataArrayInt *argpt=reinterpret_cast< ParaMEDMEM::DataArrayInt * >(argp); - std::string name=argpt->getName(); - if(!name.empty()) - ret->setName(name.c_str()); - } - return convertMesh(ret, SWIG_POINTER_OWN | 0 ); - } - - virtual PyObject *buildPartOfMySelfKeepCoords2(int start, int end, int step) const throw(INTERP_KERNEL::Exception) - { - MEDCouplingPointSet *ret=self->buildPartOfMySelfKeepCoords2(start,end,step); - return convertMesh(ret, SWIG_POINTER_OWN | 0 ); - } - - PyObject *buildFacePartOfMySelfNode(PyObject *li, bool fullyIn) const throw(INTERP_KERNEL::Exception) - { - int szArr,sw,iTypppArr; - std::vector stdvecTyyppArr; - const int *tmp=convertObjToPossibleCpp1_Safe(li,sw,szArr,iTypppArr,stdvecTyyppArr); - MEDCouplingPointSet *ret=self->buildFacePartOfMySelfNode(tmp,tmp+szArr,fullyIn); - if(sw==3)//DataArrayInt - { - void *argp; SWIG_ConvertPtr(li,&argp,SWIGTYPE_p_ParaMEDMEM__DataArrayInt,0|0); - DataArrayInt *argpt=reinterpret_cast< ParaMEDMEM::DataArrayInt * >(argp); - std::string name=argpt->getName(); - if(!name.empty()) - ret->setName(name.c_str()); - } - return convertMesh(ret, SWIG_POINTER_OWN | 0 ); - } - - void renumberNodes(PyObject *li, int newNbOfNodes) throw(INTERP_KERNEL::Exception) - { - int szArr,sw,iTypppArr; - std::vector stdvecTyyppArr; - const int *tmp=convertObjToPossibleCpp1_Safe(li,sw,szArr,iTypppArr,stdvecTyyppArr); - self->renumberNodes(tmp,newNbOfNodes); - } - - void renumberNodes2(PyObject *li, int newNbOfNodes) throw(INTERP_KERNEL::Exception) - { - int szArr,sw,iTypppArr; - std::vector stdvecTyyppArr; - const int *tmp=convertObjToPossibleCpp1_Safe(li,sw,szArr,iTypppArr,stdvecTyyppArr); - self->renumberNodes2(tmp,newNbOfNodes); - } - - PyObject *findNodesOnLine(PyObject *pt, PyObject *vec, double eps) const throw(INTERP_KERNEL::Exception) - { - int spaceDim=self->getSpaceDimension(); - double val,val2; - DataArrayDouble *a,*a2; - DataArrayDoubleTuple *aa,*aa2; - std::vector bb,bb2; - int sw; - const char msg[]="Python wrap of MEDCouplingPointSet::findNodesOnLine : 1st paramater for point."; - const char msg2[]="Python wrap of MEDCouplingPointSet::findNodesOnLine : 2nd paramater for vector."; - const double *p=convertObjToPossibleCpp5_Safe(pt,sw,val,a,aa,bb,msg,1,spaceDim,true); - const double *v=convertObjToPossibleCpp5_Safe(vec,sw,val2,a2,aa2,bb2,msg2,1,spaceDim,true); - std::vector nodes; - self->findNodesOnLine(p,v,eps,nodes); - DataArrayInt *ret=DataArrayInt::New(); - ret->alloc((int)nodes.size(),1); - std::copy(nodes.begin(),nodes.end(),ret->getPointer()); - return SWIG_NewPointerObj(SWIG_as_voidptr(ret),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 ); - } - PyObject *findNodesOnPlane(PyObject *pt, PyObject *vec, double eps) const throw(INTERP_KERNEL::Exception) - { - int spaceDim=self->getSpaceDimension(); - double val,val2; - DataArrayDouble *a,*a2; - DataArrayDoubleTuple *aa,*aa2; - std::vector bb,bb2; - int sw; - const char msg[]="Python wrap of MEDCouplingPointSet::findNodesOnPlane : 1st paramater for point."; - const char msg2[]="Python wrap of MEDCouplingPointSet::findNodesOnPlane : 2nd paramater for vector."; - const double *p=convertObjToPossibleCpp5_Safe(pt,sw,val,a,aa,bb,msg,1,spaceDim,true); - const double *v=convertObjToPossibleCpp5_Safe(vec,sw,val2,a2,aa2,bb2,msg2,1,spaceDim,true); - std::vector nodes; - self->findNodesOnPlane(p,v,eps,nodes); - DataArrayInt *ret=DataArrayInt::New(); - ret->alloc((int)nodes.size(),1); - std::copy(nodes.begin(),nodes.end(),ret->getPointer()); - return SWIG_NewPointerObj(SWIG_as_voidptr(ret),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 ); - } - - PyObject *getNodeIdsNearPoint(PyObject *pt, double eps) const throw(INTERP_KERNEL::Exception) - { - double val; - DataArrayDouble *a; - DataArrayDoubleTuple *aa; - std::vector bb; - int sw; - int spaceDim=self->getSpaceDimension(); - const char msg[]="Python wrap of MEDCouplingPointSet::getNodeIdsNearPoint : "; - const double *pos=convertObjToPossibleCpp5_Safe(pt,sw,val,a,aa,bb,msg,1,spaceDim,true); - DataArrayInt *ret=self->getNodeIdsNearPoint(pos,eps); - return SWIG_NewPointerObj(SWIG_as_voidptr(ret),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 ); - } - - PyObject *getNodeIdsNearPoints(PyObject *pt, int nbOfPoints, double eps) const throw(INTERP_KERNEL::Exception) - { - DataArrayInt *c=0,*cI=0; - // - double val; - DataArrayDouble *a; - DataArrayDoubleTuple *aa; - std::vector bb; - int sw; - int spaceDim=self->getSpaceDimension(); - const char msg[]="Python wrap of MEDCouplingPointSet::getNodeIdsNearPoints : "; - const double *pos=convertObjToPossibleCpp5_Safe(pt,sw,val,a,aa,bb,msg,nbOfPoints,spaceDim,true); - self->getNodeIdsNearPoints(pos,nbOfPoints,eps,c,cI); - PyObject *ret=PyTuple_New(2); - PyTuple_SetItem(ret,0,SWIG_NewPointerObj(SWIG_as_voidptr(c),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 )); - PyTuple_SetItem(ret,1,SWIG_NewPointerObj(SWIG_as_voidptr(cI),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 )); - return ret; - } - - PyObject *getNodeIdsNearPoints(PyObject *pt, double eps) const throw(INTERP_KERNEL::Exception) - { - DataArrayInt *c=0,*cI=0; - int spaceDim=self->getSpaceDimension(); - double val; - DataArrayDouble *a; - DataArrayDoubleTuple *aa; - std::vector bb; - int sw; - int nbOfTuples=-1; - const double *ptPtr=convertObjToPossibleCpp5_Safe2(pt,sw,val,a,aa,bb,"Python wrap of MEDCouplingUMesh::getNodeIdsNearPoints",spaceDim,true,nbOfTuples); - self->getNodeIdsNearPoints(ptPtr,nbOfTuples,eps,c,cI); - // - PyObject *ret=PyTuple_New(2); - PyTuple_SetItem(ret,0,SWIG_NewPointerObj(SWIG_as_voidptr(c),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 )); - PyTuple_SetItem(ret,1,SWIG_NewPointerObj(SWIG_as_voidptr(cI),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 )); - return ret; - } - - PyObject *getCellsInBoundingBox(PyObject *bbox, double eps) const throw(INTERP_KERNEL::Exception) - { - double val; - DataArrayDouble *a; - DataArrayDoubleTuple *aa; - std::vector bb; - int sw; - int spaceDim=self->getSpaceDimension(); - const char msg[]="Python wrap of MEDCouplingPointSet::getCellsInBoundingBox : "; - const double *tmp=convertObjToPossibleCpp5_Safe(bbox,sw,val,a,aa,bb,msg,spaceDim,2,true); - // - DataArrayInt *elems=self->getCellsInBoundingBox(tmp,eps); - return SWIG_NewPointerObj(SWIG_as_voidptr(elems),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 ); - } - - void duplicateNodesInCoords(PyObject *li) throw(INTERP_KERNEL::Exception) - { - int sw; - int singleVal; - std::vector multiVal; - std::pair > slic; - ParaMEDMEM::DataArrayInt *daIntTyypp=0; - convertObjToPossibleCpp2(li,self->getNumberOfNodes(),sw,singleVal,multiVal,slic,daIntTyypp); - switch(sw) - { - case 1: - return self->duplicateNodesInCoords(&singleVal,&singleVal+1); - case 2: - return self->duplicateNodesInCoords(&multiVal[0],&multiVal[0]+multiVal.size()); - case 4: - return self->duplicateNodesInCoords(daIntTyypp->begin(),daIntTyypp->end()); - default: - throw INTERP_KERNEL::Exception("MEDCouplingPointSet::duplicateNodesInCoords : unrecognized type entered, expected list of int, tuple of int or DataArrayInt !"); - } - } - - virtual PyObject *findCommonCells(int compType, int startCellId=0) const throw(INTERP_KERNEL::Exception) - { - DataArrayInt *v0=0,*v1=0; - self->findCommonCells(compType,startCellId,v0,v1); - PyObject *res = PyList_New(2); - PyList_SetItem(res,0,SWIG_NewPointerObj(SWIG_as_voidptr(v0),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 )); - PyList_SetItem(res,1,SWIG_NewPointerObj(SWIG_as_voidptr(v1),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 )); - return res; - } - - - virtual void renumberNodesInConn(PyObject *li) throw(INTERP_KERNEL::Exception) - { - void *da=0; - int res1=SWIG_ConvertPtr(li,&da,SWIGTYPE_p_ParaMEDMEM__DataArrayInt, 0 | 0 ); - if (!SWIG_IsOK(res1)) - { - int size; - INTERP_KERNEL::AutoPtr tmp=convertPyToNewIntArr2(li,&size); - self->renumberNodesInConn(tmp); - } - else - { - DataArrayInt *da2=reinterpret_cast< DataArrayInt * >(da); - if(!da2) - throw INTERP_KERNEL::Exception("Not null DataArrayInt instance expected !"); - da2->checkAllocated(); - self->renumberNodesInConn(da2->getConstPointer()); - } - } - - virtual PyObject *getNodeIdsInUse() const throw(INTERP_KERNEL::Exception) - { - int ret1=-1; - DataArrayInt *ret0=self->getNodeIdsInUse(ret1); - PyObject *ret=PyTuple_New(2); - PyTuple_SetItem(ret,0,SWIG_NewPointerObj(SWIG_as_voidptr(ret0),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 )); - PyTuple_SetItem(ret,1,PyInt_FromLong(ret1)); - return ret; - } - - virtual DataArrayInt *fillCellIdsToKeepFromNodeIds(PyObject *li, bool fullyIn) const - { - DataArrayInt *ret=0; - // - int szArr,sw,iTypppArr; - std::vector stdvecTyyppArr; - const int *tmp=convertObjToPossibleCpp1_Safe(li,sw,szArr,iTypppArr,stdvecTyyppArr); - self->fillCellIdsToKeepFromNodeIds(tmp,tmp+szArr,fullyIn,ret); - return ret; - } - - virtual PyObject *mergeNodes(double precision) throw(INTERP_KERNEL::Exception) - { - bool ret1; - int ret2; - DataArrayInt *ret0=self->mergeNodes(precision,ret1,ret2); - PyObject *res = PyList_New(3); - PyList_SetItem(res,0,SWIG_NewPointerObj(SWIG_as_voidptr(ret0),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 )); - PyList_SetItem(res,1,SWIG_From_bool(ret1)); - PyList_SetItem(res,2,SWIG_From_int(ret2)); - return res; - } - - virtual PyObject *mergeNodes2(double precision) throw(INTERP_KERNEL::Exception) - { - bool ret1; - int ret2; - DataArrayInt *ret0=self->mergeNodes2(precision,ret1,ret2); - PyObject *res = PyList_New(3); - PyList_SetItem(res,0,SWIG_NewPointerObj(SWIG_as_voidptr(ret0),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 )); - PyList_SetItem(res,1,SWIG_From_bool(ret1)); - PyList_SetItem(res,2,SWIG_From_int(ret2)); - return res; - } - - DataArrayInt *getCellIdsLyingOnNodes(PyObject *li, bool fullyIn) const throw(INTERP_KERNEL::Exception) - { - void *da=0; - int res1=SWIG_ConvertPtr(li,&da,SWIGTYPE_p_ParaMEDMEM__DataArrayInt, 0 | 0 ); - if (!SWIG_IsOK(res1)) - { - int size; - INTERP_KERNEL::AutoPtr tmp=convertPyToNewIntArr2(li,&size); - return self->getCellIdsLyingOnNodes(tmp,((const int *)tmp)+size,fullyIn); - } - else - { - DataArrayInt *da2=reinterpret_cast< DataArrayInt * >(da); - if(!da2) - throw INTERP_KERNEL::Exception("Not null DataArrayInt instance expected !"); - da2->checkAllocated(); - return self->getCellIdsLyingOnNodes(da2->getConstPointer(),da2->getConstPointer()+da2->getNbOfElems(),fullyIn); - } - } - - MEDCouplingPointSet *__getitem__(PyObject *listOrDataArrI) throw(INTERP_KERNEL::Exception) - { - int sw; - int singleVal; - std::vector multiVal; - std::pair > slic; - ParaMEDMEM::DataArrayInt *daIntTyypp=0; - int nbc=self->getNumberOfCells(); - convertObjToPossibleCpp2(listOrDataArrI,nbc,sw,singleVal,multiVal,slic,daIntTyypp); - switch(sw) - { - case 1: - { - if(singleVal>=nbc) - { - std::ostringstream oss; - oss << "Requesting for cell id " << singleVal << " having only " << nbc << " cells !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - if(singleVal>=0) - return self->buildPartOfMySelf(&singleVal,&singleVal+1,true); - else - { - if(nbc+singleVal>0) - { - int tmp=nbc+singleVal; - return self->buildPartOfMySelf(&tmp,&tmp+1,true); - } - else - { - std::ostringstream oss; - oss << "Requesting for cell id " << singleVal << " having only " << nbc << " cells !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - } - } - case 2: - { - return static_cast(self->buildPartOfMySelf(&multiVal[0],&multiVal[0]+multiVal.size(),true)); - } - case 3: - { - return self->buildPartOfMySelf2(slic.first,slic.second.first,slic.second.second,true); - } - case 4: - { - if(!daIntTyypp) - throw INTERP_KERNEL::Exception("MEDCouplingUMesh::__getitem__ : null instance has been given in input !"); - daIntTyypp->checkAllocated(); - return self->buildPartOfMySelf(daIntTyypp->begin(),daIntTyypp->end(),true); - } - default: - throw INTERP_KERNEL::Exception("MEDCouplingUMesh::__getitem__ : unrecognized type in input ! Possibilities are : int, list or tuple of int DataArrayInt instance !"); - } - } - - static void Rotate2DAlg(PyObject *center, double angle, int nbNodes, PyObject *coords) throw(INTERP_KERNEL::Exception) - { - int sz; - INTERP_KERNEL::AutoCPtr c=convertPyToNewDblArr2(center,&sz); - INTERP_KERNEL::AutoCPtr coo=convertPyToNewDblArr2(coords,&sz); - ParaMEDMEM::MEDCouplingPointSet::Rotate2DAlg(c,angle,nbNodes,coo); - for(int i=0;i c=convertPyToNewDblArr2(center,&sz); - int sw,nbNodes=0; - double val0; ParaMEDMEM::DataArrayDouble *val1=0; ParaMEDMEM::DataArrayDoubleTuple *val2=0; - std::vector val3; - const double *coo=convertObjToPossibleCpp5_Safe2(coords,sw,val0,val1,val2,val3, - "Rotate2DAlg",2,true,nbNodes); - if(sw!=2 && sw!=3) - throw INTERP_KERNEL::Exception("Invalid call to MEDCouplingPointSet::Rotate2DAlg : try another overload method !"); - ParaMEDMEM::MEDCouplingPointSet::Rotate2DAlg(c,angle,nbNodes,const_cast(coo)); - } - - static void Rotate3DAlg(PyObject *center, PyObject *vect, double angle, int nbNodes, PyObject *coords) throw(INTERP_KERNEL::Exception) - { - int sz,sz2; - INTERP_KERNEL::AutoCPtr c=convertPyToNewDblArr2(center,&sz); - INTERP_KERNEL::AutoCPtr coo=convertPyToNewDblArr2(coords,&sz); - INTERP_KERNEL::AutoCPtr v=convertPyToNewDblArr2(vect,&sz2); - ParaMEDMEM::MEDCouplingPointSet::Rotate3DAlg(c,v,angle,nbNodes,coo); - for(int i=0;i c=convertPyToNewDblArr2(center,&sz); - int sw,nbNodes=0; - double val0; ParaMEDMEM::DataArrayDouble *val1=0; ParaMEDMEM::DataArrayDoubleTuple *val2=0; - std::vector val3; - const double *coo=convertObjToPossibleCpp5_Safe2(coords,sw,val0,val1,val2,val3, - "Rotate3DAlg",3,true,nbNodes); - if(sw!=2 && sw!=3) - throw INTERP_KERNEL::Exception("Invalid call to MEDCouplingPointSet::Rotate3DAlg : try another overload method !"); - INTERP_KERNEL::AutoCPtr v=convertPyToNewDblArr2(vect,&sz2); - ParaMEDMEM::MEDCouplingPointSet::Rotate3DAlg(c,v,angle,nbNodes,const_cast(coo)); - } - } - }; - - //== MEDCouplingPointSet End - - class MEDCouplingUMeshCell - { - public: - INTERP_KERNEL::NormalizedCellType getType() const; - %extend - { - std::string __str__() const throw(INTERP_KERNEL::Exception) - { - return self->repr(); - } - - PyObject *getAllConn() const throw(INTERP_KERNEL::Exception) - { - int ret2; - const int *r=self->getAllConn(ret2); - PyObject *ret=PyTuple_New(ret2); - for(int i=0;inextt(); - if(ret) - return SWIG_NewPointerObj(SWIG_as_voidptr(ret),SWIGTYPE_p_ParaMEDMEM__MEDCouplingUMeshCell,0|0); - else - { - PyErr_SetString(PyExc_StopIteration,"No more data."); - return 0; - } - } - } - }; - - class MEDCouplingUMeshCellByTypeIterator - { - public: - ~MEDCouplingUMeshCellByTypeIterator(); - %extend - { - PyObject *next() - { - MEDCouplingUMeshCellEntry *ret=self->nextt(); - if(ret) - return SWIG_NewPointerObj(SWIG_as_voidptr(ret),SWIGTYPE_p_ParaMEDMEM__MEDCouplingUMeshCellEntry,SWIG_POINTER_OWN | 0); - else - { - PyErr_SetString(PyExc_StopIteration,"No more data."); - return 0; - } - } - } - }; - - class MEDCouplingUMeshCellByTypeEntry - { - public: - ~MEDCouplingUMeshCellByTypeEntry(); - %extend - { - MEDCouplingUMeshCellByTypeIterator *__iter__() - { - return self->iterator(); - } - } - }; - - class MEDCouplingUMeshCellEntry - { - public: - INTERP_KERNEL::NormalizedCellType getType() const; - int getNumberOfElems() const; - %extend - { - MEDCouplingUMeshCellIterator *__iter__() - { - return self->iterator(); - } - } - }; - - //== MEDCouplingUMesh - - class MEDCouplingUMesh : public ParaMEDMEM::MEDCouplingPointSet - { - public: - static MEDCouplingUMesh *New() throw(INTERP_KERNEL::Exception); - static MEDCouplingUMesh *New(const char *meshName, int meshDim) throw(INTERP_KERNEL::Exception); - MEDCouplingUMesh *clone(bool recDeepCpy) const; - void checkCoherency() const throw(INTERP_KERNEL::Exception); - void setMeshDimension(int meshDim) throw(INTERP_KERNEL::Exception); - void allocateCells(int nbOfCells=0) throw(INTERP_KERNEL::Exception); - void finishInsertingCells() throw(INTERP_KERNEL::Exception); - MEDCouplingUMeshCellByTypeEntry *cellsByType() throw(INTERP_KERNEL::Exception); - void setConnectivity(DataArrayInt *conn, DataArrayInt *connIndex, bool isComputingTypes=true) throw(INTERP_KERNEL::Exception); - INTERP_KERNEL::NormalizedCellType getTypeOfCell(int cellId) const throw(INTERP_KERNEL::Exception); - void setPartOfMySelf2(int start, int end, int step, const MEDCouplingUMesh& otherOnSameCoordsThanThis) throw(INTERP_KERNEL::Exception); - int getMeshLength() const throw(INTERP_KERNEL::Exception); - void computeTypes() throw(INTERP_KERNEL::Exception); - std::string reprConnectivityOfThis() const throw(INTERP_KERNEL::Exception); - MEDCouplingUMesh *buildSetInstanceFromThis(int spaceDim) const throw(INTERP_KERNEL::Exception); - //tools - DataArrayInt *conformize2D(double eps) throw(INTERP_KERNEL::Exception); - DataArrayInt *colinearize2D(double eps) throw(INTERP_KERNEL::Exception); - void shiftNodeNumbersInConn(int delta) throw(INTERP_KERNEL::Exception); - std::vector getQuadraticStatus() const throw(INTERP_KERNEL::Exception); - DataArrayInt *findCellIdsOnBoundary() const throw(INTERP_KERNEL::Exception); - MEDCouplingUMesh *computeSkin() const throw(INTERP_KERNEL::Exception); - bool checkConsecutiveCellTypes() const throw(INTERP_KERNEL::Exception); - bool checkConsecutiveCellTypesForMEDFileFrmt() const throw(INTERP_KERNEL::Exception); - DataArrayInt *rearrange2ConsecutiveCellTypes() throw(INTERP_KERNEL::Exception); - DataArrayInt *sortCellsInMEDFileFrmt() throw(INTERP_KERNEL::Exception); - DataArrayInt *getRenumArrForMEDFileFrmt() const throw(INTERP_KERNEL::Exception); - DataArrayInt *convertCellArrayPerGeoType(const DataArrayInt *da) const throw(INTERP_KERNEL::Exception); - MEDCouplingUMesh *buildDescendingConnectivity(DataArrayInt *desc, DataArrayInt *descIndx, DataArrayInt *revDesc, DataArrayInt *revDescIndx) const throw(INTERP_KERNEL::Exception); - MEDCouplingUMesh *buildDescendingConnectivity2(DataArrayInt *desc, DataArrayInt *descIndx, DataArrayInt *revDesc, DataArrayInt *revDescIndx) const throw(INTERP_KERNEL::Exception); - MEDCouplingUMesh *explode3DMeshTo1D(DataArrayInt *desc, DataArrayInt *descIndx, DataArrayInt *revDesc, DataArrayInt *revDescIndx) const throw(INTERP_KERNEL::Exception); - void orientCorrectlyPolyhedrons() throw(INTERP_KERNEL::Exception); - bool isPresenceOfQuadratic() const throw(INTERP_KERNEL::Exception); - bool isFullyQuadratic() const throw(INTERP_KERNEL::Exception); - MEDCouplingFieldDouble *buildDirectionVectorField() const throw(INTERP_KERNEL::Exception); - bool isContiguous1D() const throw(INTERP_KERNEL::Exception); - void tessellate2D(double eps) throw(INTERP_KERNEL::Exception); - void tessellate2DCurve(double eps) throw(INTERP_KERNEL::Exception); - void convertQuadraticCellsToLinear() throw(INTERP_KERNEL::Exception); - DataArrayInt *convertLinearCellsToQuadratic(int conversionType=0) throw(INTERP_KERNEL::Exception); - void convertDegeneratedCells() throw(INTERP_KERNEL::Exception); - bool areOnlySimplexCells() const throw(INTERP_KERNEL::Exception); - MEDCouplingFieldDouble *getEdgeRatioField() const throw(INTERP_KERNEL::Exception); - MEDCouplingFieldDouble *getAspectRatioField() const throw(INTERP_KERNEL::Exception); - MEDCouplingFieldDouble *getWarpField() const throw(INTERP_KERNEL::Exception); - MEDCouplingFieldDouble *getSkewField() const throw(INTERP_KERNEL::Exception); - DataArrayDouble *computePlaneEquationOf3DFaces() const throw(INTERP_KERNEL::Exception); - DataArrayInt *convexEnvelop2D() throw(INTERP_KERNEL::Exception); - std::string cppRepr() const throw(INTERP_KERNEL::Exception); - DataArrayInt *findAndCorrectBadOriented3DExtrudedCells() throw(INTERP_KERNEL::Exception); - DataArrayInt *findAndCorrectBadOriented3DCells() throw(INTERP_KERNEL::Exception); - ParaMEDMEM::MEDCoupling1GTUMesh *convertIntoSingleGeoTypeMesh() const throw(INTERP_KERNEL::Exception); - DataArrayInt *convertNodalConnectivityToStaticGeoTypeMesh() const throw(INTERP_KERNEL::Exception); - DataArrayInt *buildUnionOf2DMesh() const throw(INTERP_KERNEL::Exception); - DataArrayInt *buildUnionOf3DMesh() const throw(INTERP_KERNEL::Exception); - MEDCouplingSkyLineArray *generateGraph() const throw(INTERP_KERNEL::Exception); - DataArrayInt *orderConsecutiveCells1D() const throw(INTERP_KERNEL::Exception); - DataArrayDouble *getBoundingBoxForBBTreeFast() const throw(INTERP_KERNEL::Exception); - DataArrayDouble *getBoundingBoxForBBTree2DQuadratic(double arcDetEps=1e-12) const throw(INTERP_KERNEL::Exception); - DataArrayDouble *getBoundingBoxForBBTree1DQuadratic(double arcDetEps=1e-12) const throw(INTERP_KERNEL::Exception); - void changeOrientationOfCells() throw(INTERP_KERNEL::Exception); - int split2DCells(const DataArrayInt *desc, const DataArrayInt *descI, const DataArrayInt *subNodesInSeg, const DataArrayInt *subNodesInSegI, const DataArrayInt *midOpt=0, const DataArrayInt *midOptI=0) throw(INTERP_KERNEL::Exception); - static MEDCouplingUMesh *Build0DMeshFromCoords(DataArrayDouble *da) throw(INTERP_KERNEL::Exception); - static MEDCouplingUMesh *MergeUMeshes(const MEDCouplingUMesh *mesh1, const MEDCouplingUMesh *mesh2) throw(INTERP_KERNEL::Exception); - static MEDCouplingUMesh *MergeUMeshesOnSameCoords(const MEDCouplingUMesh *mesh1, const MEDCouplingUMesh *mesh2) throw(INTERP_KERNEL::Exception); - static DataArrayInt *ComputeSpreadZoneGradually(const DataArrayInt *arrIn, const DataArrayInt *arrIndxIn) throw(INTERP_KERNEL::Exception); - static DataArrayInt *ComputeRangesFromTypeDistribution(const std::vector& code) throw(INTERP_KERNEL::Exception); - %extend { - MEDCouplingUMesh() throw(INTERP_KERNEL::Exception) - { - return MEDCouplingUMesh::New(); - } - - MEDCouplingUMesh(const char *meshName, int meshDim) throw(INTERP_KERNEL::Exception) - { - return MEDCouplingUMesh::New(meshName,meshDim); - } - - // serialization - static PyObject *___new___(PyObject *cls, PyObject *args) throw(INTERP_KERNEL::Exception) - { - return NewMethWrapCallInitOnlyIfEmptyDictInInput(cls,args,"MEDCouplingUMesh"); - } - - std::string __str__() const throw(INTERP_KERNEL::Exception) - { - return self->simpleRepr(); - } - - std::string __repr__() const throw(INTERP_KERNEL::Exception) - { - std::ostringstream oss; - self->reprQuickOverview(oss); - return oss.str(); - } - - MEDCouplingUMeshCellIterator *__iter__() throw(INTERP_KERNEL::Exception) - { - return self->cellIterator(); - } - - PyObject *getAllGeoTypesSorted() const throw(INTERP_KERNEL::Exception) - { - std::vector result=self->getAllGeoTypesSorted(); - std::vector::const_iterator iL=result.begin(); - PyObject *res=PyList_New(result.size()); - for(int i=0;iL!=result.end(); i++, iL++) - PyList_SetItem(res,i,PyInt_FromLong(*iL)); - return res; - } - - void setPartOfMySelf(PyObject *li, const MEDCouplingUMesh& otherOnSameCoordsThanThis) throw(INTERP_KERNEL::Exception) - { - int sw; - int singleVal; - std::vector multiVal; - std::pair > slic; - ParaMEDMEM::DataArrayInt *daIntTyypp=0; - int nbc=self->getNumberOfCells(); - convertObjToPossibleCpp2(li,nbc,sw,singleVal,multiVal,slic,daIntTyypp); - switch(sw) - { - case 1: - { - if(singleVal>=nbc) - { - std::ostringstream oss; - oss << "Requesting for cell id " << singleVal << " having only " << nbc << " cells !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - if(singleVal>=0) - { - self->setPartOfMySelf(&singleVal,&singleVal+1,otherOnSameCoordsThanThis); - break; - } - else - { - if(nbc+singleVal>0) - { - int tmp=nbc+singleVal; - self->setPartOfMySelf(&tmp,&tmp+1,otherOnSameCoordsThanThis); - break; - } - else - { - std::ostringstream oss; - oss << "Requesting for cell id " << singleVal << " having only " << nbc << " cells !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - } - } - case 2: - { - self->setPartOfMySelf(&multiVal[0],&multiVal[0]+multiVal.size(),otherOnSameCoordsThanThis); - break; - } - case 4: - { - if(!daIntTyypp) - throw INTERP_KERNEL::Exception("MEDCouplingUMesh::setPartOfMySelf : null instance has been given in input !"); - daIntTyypp->checkAllocated(); - self->setPartOfMySelf(daIntTyypp->begin(),daIntTyypp->end(),otherOnSameCoordsThanThis); - break; - } - default: - throw INTERP_KERNEL::Exception("MEDCouplingUMesh::setPartOfMySelf : unrecognized type in input ! Possibilities are : int, list or tuple of int DataArrayInt instance !"); - } - } - - void __setitem__(PyObject *li, const MEDCouplingUMesh& otherOnSameCoordsThanThis) throw(INTERP_KERNEL::Exception) - { - int sw; - int singleVal; - std::vector multiVal; - std::pair > slic; - ParaMEDMEM::DataArrayInt *daIntTyypp=0; - int nbc=self->getNumberOfCells(); - convertObjToPossibleCpp2(li,nbc,sw,singleVal,multiVal,slic,daIntTyypp); - switch(sw) - { - case 1: - { - if(singleVal>=nbc) - { - std::ostringstream oss; - oss << "Requesting for cell id " << singleVal << " having only " << nbc << " cells !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - if(singleVal>=0) - { - self->setPartOfMySelf(&singleVal,&singleVal+1,otherOnSameCoordsThanThis); - break; - } - else - { - if(nbc+singleVal>0) - { - int tmp=nbc+singleVal; - self->setPartOfMySelf(&tmp,&tmp+1,otherOnSameCoordsThanThis); - break; - } - else - { - std::ostringstream oss; - oss << "Requesting for cell id " << singleVal << " having only " << nbc << " cells !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - } - } - case 2: - { - self->setPartOfMySelf(&multiVal[0],&multiVal[0]+multiVal.size(),otherOnSameCoordsThanThis); - break; - } - case 3: - { - self->setPartOfMySelf2(slic.first,slic.second.first,slic.second.second,otherOnSameCoordsThanThis); - break; - } - case 4: - { - if(!daIntTyypp) - throw INTERP_KERNEL::Exception("MEDCouplingUMesh::__setitem__ : null instance has been given in input !"); - daIntTyypp->checkAllocated(); - self->setPartOfMySelf(daIntTyypp->begin(),daIntTyypp->end(),otherOnSameCoordsThanThis); - break; - } - default: - throw INTERP_KERNEL::Exception("MEDCouplingUMesh::__setitem__ : unrecognized type in input ! Possibilities are : int, list or tuple of int, slice, DataArrayInt instance !"); - } - } - - void insertNextCell(INTERP_KERNEL::NormalizedCellType type, int size, PyObject *li) throw(INTERP_KERNEL::Exception) - { - int szArr,sw,iTypppArr; - std::vector stdvecTyyppArr; - const int *tmp=convertObjToPossibleCpp1_Safe(li,sw,szArr,iTypppArr,stdvecTyyppArr); - if(size>szArr) - { - std::ostringstream oss; oss << "Wrap of MEDCouplingUMesh::insertNextCell : request of connectivity with length " << size << " whereas the length of input is " << szArr << " !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - self->insertNextCell(type,size,tmp); - } - - void insertNextCell(INTERP_KERNEL::NormalizedCellType type, PyObject *li) throw(INTERP_KERNEL::Exception) - { - int szArr,sw,iTypppArr; - std::vector stdvecTyyppArr; - const int *tmp=convertObjToPossibleCpp1_Safe(li,sw,szArr,iTypppArr,stdvecTyyppArr); - self->insertNextCell(type,szArr,tmp); - } - - DataArrayInt *getNodalConnectivity() throw(INTERP_KERNEL::Exception) - { - DataArrayInt *ret=self->getNodalConnectivity(); - if(ret) - ret->incrRef(); - return ret; - } - DataArrayInt *getNodalConnectivityIndex() throw(INTERP_KERNEL::Exception) - { - DataArrayInt *ret=self->getNodalConnectivityIndex(); - if(ret) - ret->incrRef(); - return ret; - } - - static PyObject *ComputeSpreadZoneGraduallyFromSeed(PyObject *seed, const DataArrayInt *arrIn, const DataArrayInt *arrIndxIn, int nbOfDepthPeeling=-1) throw(INTERP_KERNEL::Exception) - { - int szArr,sw,iTypppArr; - std::vector stdvecTyyppArr; - const int *seedPtr=convertObjToPossibleCpp1_Safe(seed,sw,szArr,iTypppArr,stdvecTyyppArr); - int nbOfDepthPeelingPerformed=0; - DataArrayInt *ret0=MEDCouplingUMesh::ComputeSpreadZoneGraduallyFromSeed(seedPtr,seedPtr+szArr,arrIn,arrIndxIn,nbOfDepthPeeling,nbOfDepthPeelingPerformed); - PyObject *res=PyTuple_New(2); - PyTuple_SetItem(res,0,SWIG_NewPointerObj(SWIG_as_voidptr(ret0),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 )); - PyTuple_SetItem(res,1,PyInt_FromLong(nbOfDepthPeelingPerformed)); - return res; - } - - static PyObject *FindCommonCellsAlg(int compType, int startCellId, const DataArrayInt *nodal, const DataArrayInt *nodalI, const DataArrayInt *revNodal, const DataArrayInt *revNodalI) throw(INTERP_KERNEL::Exception) - { - DataArrayInt *v0=0,*v1=0; - MEDCouplingUMesh::FindCommonCellsAlg(compType,startCellId,nodal,nodalI,revNodal,revNodalI,v0,v1); - PyObject *res = PyList_New(2); - PyList_SetItem(res,0,SWIG_NewPointerObj(SWIG_as_voidptr(v0),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 )); - PyList_SetItem(res,1,SWIG_NewPointerObj(SWIG_as_voidptr(v1),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 )); - return res; - } - - PyObject *distanceToPoint(PyObject *point) const throw(INTERP_KERNEL::Exception) - { - double val; - DataArrayDouble *a; - DataArrayDoubleTuple *aa; - std::vector bb; - int sw; - int nbOfCompo=self->getSpaceDimension(); - const double *pt=convertObjToPossibleCpp5_Safe(point,sw,val,a,aa,bb,"Python wrap of MEDCouplingUMesh::distanceToPoint",1,nbOfCompo,true); - // - int cellId=-1; - double ret0=self->distanceToPoint(pt,pt+nbOfCompo,cellId); - PyObject *ret=PyTuple_New(2); - PyTuple_SetItem(ret,0,PyFloat_FromDouble(ret0)); - PyTuple_SetItem(ret,1,PyInt_FromLong(cellId)); - return ret; - } - - PyObject *distanceToPoints(const DataArrayDouble *pts) const throw(INTERP_KERNEL::Exception) - { - DataArrayInt *ret1=0; - DataArrayDouble *ret0=self->distanceToPoints(pts,ret1); - PyObject *ret=PyTuple_New(2); - PyTuple_SetItem(ret,0,SWIG_NewPointerObj(SWIG_as_voidptr(ret0),SWIGTYPE_p_ParaMEDMEM__DataArrayDouble, SWIG_POINTER_OWN | 0 )); - PyTuple_SetItem(ret,1,SWIG_NewPointerObj(SWIG_as_voidptr(ret1),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 )); - return ret; - } - - PyObject *tetrahedrize(int policy) throw(INTERP_KERNEL::Exception) - { - int ret2(-1); - DataArrayInt *ret1(0); - MEDCoupling1SGTUMesh *ret0(self->tetrahedrize(policy,ret1,ret2)); - PyObject *ret=PyTuple_New(3); - PyTuple_SetItem(ret,0,SWIG_NewPointerObj(SWIG_as_voidptr(ret0),SWIGTYPE_p_ParaMEDMEM__MEDCoupling1SGTUMesh, SWIG_POINTER_OWN | 0 )); - PyTuple_SetItem(ret,1,SWIG_NewPointerObj(SWIG_as_voidptr(ret1),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 )); - PyTuple_SetItem(ret,2,PyInt_FromLong(ret2)); - return ret; - } - - PyObject *checkButterflyCells(double eps=1e-12) throw(INTERP_KERNEL::Exception) - { - std::vector cells; - self->checkButterflyCells(cells,eps); - DataArrayInt *ret=DataArrayInt::New(); - ret->alloc((int)cells.size(),1); - std::copy(cells.begin(),cells.end(),ret->getPointer()); - return SWIG_NewPointerObj(SWIG_as_voidptr(ret),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 ); - } - - PyObject *splitByType() const throw(INTERP_KERNEL::Exception) - { - std::vector ms=self->splitByType(); - int sz=ms.size(); - PyObject *ret = PyList_New(sz); - for(int i=0;i retCpp=self->partitionBySpreadZone(); - int sz=retCpp.size(); - PyObject *ret=PyList_New(sz); - for(int i=0;i tmp=convertPyToNewIntArr2(ids,&size); - MEDCouplingUMesh *ret=self->keepSpecifiedCells(type,tmp,tmp+size); - return SWIG_NewPointerObj(SWIG_as_voidptr(ret),SWIGTYPE_p_ParaMEDMEM__MEDCouplingUMesh, SWIG_POINTER_OWN | 0 ); - } - - bool checkConsecutiveCellTypesAndOrder(PyObject *li) const throw(INTERP_KERNEL::Exception) - { - int sz; - INTERP_KERNEL::AutoPtr order=(INTERP_KERNEL::NormalizedCellType *)convertPyToNewIntArr2(li,&sz); - bool ret=self->checkConsecutiveCellTypesAndOrder(order,order+sz); - return ret; - } - - DataArrayInt *getRenumArrForConsecutiveCellTypesSpec(PyObject *li) const throw(INTERP_KERNEL::Exception) - { - int sz; - INTERP_KERNEL::AutoPtr order=(INTERP_KERNEL::NormalizedCellType *)convertPyToNewIntArr2(li,&sz); - DataArrayInt *ret=self->getRenumArrForConsecutiveCellTypesSpec(order,(INTERP_KERNEL::NormalizedCellType *)order+sz); - return ret; - } - - PyObject *findNodesToDuplicate(const MEDCouplingUMesh& otherDimM1OnSameCoords) const throw(INTERP_KERNEL::Exception) - { - DataArrayInt *tmp0=0,*tmp1=0,*tmp2=0; - self->findNodesToDuplicate(otherDimM1OnSameCoords,tmp0,tmp1,tmp2); - PyObject *ret=PyTuple_New(3); - PyTuple_SetItem(ret,0,SWIG_NewPointerObj(SWIG_as_voidptr(tmp0),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 )); - PyTuple_SetItem(ret,1,SWIG_NewPointerObj(SWIG_as_voidptr(tmp1),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 )); - PyTuple_SetItem(ret,2,SWIG_NewPointerObj(SWIG_as_voidptr(tmp2),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 )); - return ret; - } - - PyObject *findCellIdsLyingOn(const MEDCouplingUMesh& otherDimM1OnSameCoords) const throw(INTERP_KERNEL::Exception) - { - DataArrayInt *tmp0=0,*tmp1=0; - self->findCellIdsLyingOn(otherDimM1OnSameCoords,tmp0,tmp1); - PyObject *ret=PyTuple_New(2); - PyTuple_SetItem(ret,0,SWIG_NewPointerObj(SWIG_as_voidptr(tmp0),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 )); - PyTuple_SetItem(ret,1,SWIG_NewPointerObj(SWIG_as_voidptr(tmp1),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 )); - return ret; - } - - void duplicateNodes(PyObject *li) throw(INTERP_KERNEL::Exception) - { - int sw; - int singleVal; - std::vector multiVal; - std::pair > slic; - ParaMEDMEM::DataArrayInt *daIntTyypp=0; - convertObjToPossibleCpp2(li,self->getNumberOfNodes(),sw,singleVal,multiVal,slic,daIntTyypp); - switch(sw) - { - case 1: - return self->duplicateNodes(&singleVal,&singleVal+1); - case 2: - return self->duplicateNodes(&multiVal[0],&multiVal[0]+multiVal.size()); - case 4: - return self->duplicateNodes(daIntTyypp->begin(),daIntTyypp->end()); - default: - throw INTERP_KERNEL::Exception("MEDCouplingUMesh::duplicateNodes : unrecognized type entered, expected list of int, tuple of int or DataArrayInt !"); - } - } - - void duplicateNodesInConn(PyObject *li, int offset) throw(INTERP_KERNEL::Exception) - { - int sw; - int singleVal; - std::vector multiVal; - std::pair > slic; - ParaMEDMEM::DataArrayInt *daIntTyypp=0; - convertObjToPossibleCpp2(li,self->getNumberOfNodes(),sw,singleVal,multiVal,slic,daIntTyypp); - switch(sw) - { - case 1: - return self->duplicateNodesInConn(&singleVal,&singleVal+1,offset); - case 2: - return self->duplicateNodesInConn(&multiVal[0],&multiVal[0]+multiVal.size(),offset); - case 4: - return self->duplicateNodesInConn(daIntTyypp->begin(),daIntTyypp->end(),offset); - default: - throw INTERP_KERNEL::Exception("MEDCouplingUMesh::duplicateNodesInConn : unrecognized type entered, expected list of int, tuple of int or DataArrayInt !"); - } - } - - PyObject *getLevArrPerCellTypes(PyObject *li) const throw(INTERP_KERNEL::Exception) - { - int sz; - INTERP_KERNEL::AutoPtr order=(INTERP_KERNEL::NormalizedCellType *)convertPyToNewIntArr2(li,&sz); - DataArrayInt *tmp0,*tmp1=0; - tmp0=self->getLevArrPerCellTypes(order,(INTERP_KERNEL::NormalizedCellType *)order+sz,tmp1); - PyObject *ret=PyTuple_New(2); - PyTuple_SetItem(ret,0,SWIG_NewPointerObj(SWIG_as_voidptr(tmp0),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 )); - PyTuple_SetItem(ret,1,SWIG_NewPointerObj(SWIG_as_voidptr(tmp1),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 )); - return ret; - } - - PyObject *convertNodalConnectivityToDynamicGeoTypeMesh() const throw(INTERP_KERNEL::Exception) - { - DataArrayInt *ret0=0,*ret1=0; - self->convertNodalConnectivityToDynamicGeoTypeMesh(ret0,ret1); - PyObject *ret=PyTuple_New(2); - PyTuple_SetItem(ret,0,SWIG_NewPointerObj(SWIG_as_voidptr(ret0),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 )); - PyTuple_SetItem(ret,1,SWIG_NewPointerObj(SWIG_as_voidptr(ret1),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 )); - return ret; - } - - static PyObject *AggregateSortedByTypeMeshesOnSameCoords(PyObject *ms) throw(INTERP_KERNEL::Exception) - { - std::vector meshes; - convertFromPyObjVectorOfObj(ms,SWIGTYPE_p_ParaMEDMEM__MEDCouplingUMesh,"MEDCouplingUMesh",meshes); - DataArrayInt *ret1=0,*ret2=0; - MEDCouplingUMesh *ret0=MEDCouplingUMesh::AggregateSortedByTypeMeshesOnSameCoords(meshes,ret1,ret2); - PyObject *ret=PyTuple_New(3); - PyTuple_SetItem(ret,0,SWIG_NewPointerObj(SWIG_as_voidptr(ret0),SWIGTYPE_p_ParaMEDMEM__MEDCouplingUMesh, SWIG_POINTER_OWN | 0 )); - PyTuple_SetItem(ret,1,SWIG_NewPointerObj(SWIG_as_voidptr(ret1),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 )); - PyTuple_SetItem(ret,2,SWIG_NewPointerObj(SWIG_as_voidptr(ret2),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 )); - return ret; - } - - static PyObject *MergeUMeshesOnSameCoords(PyObject *ms) throw(INTERP_KERNEL::Exception) - { - std::vector meshes; - convertFromPyObjVectorOfObj(ms,SWIGTYPE_p_ParaMEDMEM__MEDCouplingUMesh,"MEDCouplingUMesh",meshes); - MEDCouplingUMesh *ret=MEDCouplingUMesh::MergeUMeshesOnSameCoords(meshes); - return convertMesh(ret, SWIG_POINTER_OWN | 0 ); - } - - static PyObject *FuseUMeshesOnSameCoords(PyObject *ms, int compType) throw(INTERP_KERNEL::Exception) - { - int sz; - std::vector meshes; - convertFromPyObjVectorOfObj(ms,SWIGTYPE_p_ParaMEDMEM__MEDCouplingUMesh,"MEDCouplingUMesh",meshes); - std::vector corr; - MEDCouplingUMesh *um=MEDCouplingUMesh::FuseUMeshesOnSameCoords(meshes,compType,corr); - sz=corr.size(); - PyObject *ret1=PyList_New(sz); - for(int i=0;i meshes; - convertFromPyObjVectorOfObj(ms,SWIGTYPE_p_ParaMEDMEM__MEDCouplingUMesh,"MEDCouplingUMesh",meshes); - MEDCouplingUMesh::PutUMeshesOnSameAggregatedCoords(meshes); - } - - static void MergeNodesOnUMeshesSharingSameCoords(PyObject *ms, double eps) throw(INTERP_KERNEL::Exception) - { - std::vector meshes; - convertFromPyObjVectorOfObj(ms,SWIGTYPE_p_ParaMEDMEM__MEDCouplingUMesh,"MEDCouplingUMesh",meshes); - MEDCouplingUMesh::MergeNodesOnUMeshesSharingSameCoords(meshes,eps); - } - - static bool RemoveIdsFromIndexedArrays(PyObject *li, DataArrayInt *arr, DataArrayInt *arrIndx, int offsetForRemoval=0) throw(INTERP_KERNEL::Exception) - { - int sw; - int singleVal; - std::vector multiVal; - std::pair > slic; - ParaMEDMEM::DataArrayInt *daIntTyypp=0; - if(!arrIndx) - throw INTERP_KERNEL::Exception("MEDCouplingUMesh::RemoveIdsFromIndexedArrays : null pointer as arrIndex !"); - convertObjToPossibleCpp2(li,arrIndx->getNumberOfTuples()-1,sw,singleVal,multiVal,slic,daIntTyypp); - switch(sw) - { - case 1: - return MEDCouplingUMesh::RemoveIdsFromIndexedArrays(&singleVal,&singleVal+1,arr,arrIndx,offsetForRemoval); - case 2: - return MEDCouplingUMesh::RemoveIdsFromIndexedArrays(&multiVal[0],&multiVal[0]+multiVal.size(),arr,arrIndx,offsetForRemoval); - case 4: - return MEDCouplingUMesh::RemoveIdsFromIndexedArrays(daIntTyypp->begin(),daIntTyypp->end(),arr,arrIndx,offsetForRemoval); - default: - throw INTERP_KERNEL::Exception("MEDCouplingUMesh::RemoveIdsFromIndexedArrays : unrecognized type entered, expected list of int, tuple of int or DataArrayInt !"); - } - } - - static PyObject *ExtractFromIndexedArrays(PyObject *li, const DataArrayInt *arrIn, const DataArrayInt *arrIndxIn) throw(INTERP_KERNEL::Exception) - { - DataArrayInt *arrOut=0,*arrIndexOut=0; - int sw; - int singleVal; - std::vector multiVal; - std::pair > slic; - ParaMEDMEM::DataArrayInt *daIntTyypp=0; - if(!arrIndxIn) - throw INTERP_KERNEL::Exception("MEDCouplingUMesh::ExtractFromIndexedArrays : null pointer as arrIndxIn !"); - convertObjToPossibleCpp2(li,arrIndxIn->getNumberOfTuples()-1,sw,singleVal,multiVal,slic,daIntTyypp); - switch(sw) - { - case 1: - { - MEDCouplingUMesh::ExtractFromIndexedArrays(&singleVal,&singleVal+1,arrIn,arrIndxIn,arrOut,arrIndexOut); - break; - } - case 2: - { - MEDCouplingUMesh::ExtractFromIndexedArrays(&multiVal[0],&multiVal[0]+multiVal.size(),arrIn,arrIndxIn,arrOut,arrIndexOut); - break; - } - case 4: - { - MEDCouplingUMesh::ExtractFromIndexedArrays(daIntTyypp->begin(),daIntTyypp->end(),arrIn,arrIndxIn,arrOut,arrIndexOut); - break; - } - default: - throw INTERP_KERNEL::Exception("MEDCouplingUMesh::ExtractFromIndexedArrays : unrecognized type entered, expected list of int, tuple of int or DataArrayInt !"); - } - PyObject *ret=PyTuple_New(2); - PyTuple_SetItem(ret,0,SWIG_NewPointerObj(SWIG_as_voidptr(arrOut),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 )); - PyTuple_SetItem(ret,1,SWIG_NewPointerObj(SWIG_as_voidptr(arrIndexOut),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 )); - return ret; - } - - static PyObject *ExtractFromIndexedArrays2(int strt, int stp, int step, const DataArrayInt *arrIn, const DataArrayInt *arrIndxIn) throw(INTERP_KERNEL::Exception) - { - DataArrayInt *arrOut=0,*arrIndexOut=0; - MEDCouplingUMesh::ExtractFromIndexedArrays2(strt,stp,step,arrIn,arrIndxIn,arrOut,arrIndexOut); - PyObject *ret=PyTuple_New(2); - PyTuple_SetItem(ret,0,SWIG_NewPointerObj(SWIG_as_voidptr(arrOut),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 )); - PyTuple_SetItem(ret,1,SWIG_NewPointerObj(SWIG_as_voidptr(arrIndexOut),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 )); - return ret; - } - - static PyObject *ExtractFromIndexedArrays2(PyObject *slic, const DataArrayInt *arrIn, const DataArrayInt *arrIndxIn) throw(INTERP_KERNEL::Exception) - { - if(!PySlice_Check(slic)) - throw INTERP_KERNEL::Exception("ExtractFromIndexedArrays2 (wrap) : the first param is not a pyslice !"); - Py_ssize_t strt=2,stp=2,step=2; - PySliceObject *sliC=reinterpret_cast(slic); - if(!arrIndxIn) - throw INTERP_KERNEL::Exception("ExtractFromIndexedArrays2 (wrap) : last array is null !"); - arrIndxIn->checkAllocated(); - if(arrIndxIn->getNumberOfComponents()!=1) - throw INTERP_KERNEL::Exception("ExtractFromIndexedArrays2 (wrap) : number of components of last argument must be equal to one !"); - GetIndicesOfSlice(sliC,arrIndxIn->getNumberOfTuples(),&strt,&stp,&step,"ExtractFromIndexedArrays2 (wrap) : Invalid slice regarding nb of elements !"); - DataArrayInt *arrOut=0,*arrIndexOut=0; - MEDCouplingUMesh::ExtractFromIndexedArrays2(strt,stp,step,arrIn,arrIndxIn,arrOut,arrIndexOut); - PyObject *ret=PyTuple_New(2); - PyTuple_SetItem(ret,0,SWIG_NewPointerObj(SWIG_as_voidptr(arrOut),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 )); - PyTuple_SetItem(ret,1,SWIG_NewPointerObj(SWIG_as_voidptr(arrIndexOut),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 )); - return ret; - } - - static PyObject *SetPartOfIndexedArrays(PyObject *li, - const DataArrayInt *arrIn, const DataArrayInt *arrIndxIn, - const DataArrayInt *srcArr, const DataArrayInt *srcArrIndex) throw(INTERP_KERNEL::Exception) - { - DataArrayInt *arrOut=0,*arrIndexOut=0; - int sw; - int singleVal; - std::vector multiVal; - std::pair > slic; - ParaMEDMEM::DataArrayInt *daIntTyypp=0; - if(!arrIndxIn) - throw INTERP_KERNEL::Exception("MEDCouplingUMesh::SetPartOfIndexedArrays : null pointer as arrIndex !"); - convertObjToPossibleCpp2(li,arrIndxIn->getNumberOfTuples()-1,sw,singleVal,multiVal,slic,daIntTyypp); - switch(sw) - { - case 1: - { - MEDCouplingUMesh::SetPartOfIndexedArrays(&singleVal,&singleVal+1,arrIn,arrIndxIn,srcArr,srcArrIndex,arrOut,arrIndexOut); - break; - } - case 2: - { - MEDCouplingUMesh::SetPartOfIndexedArrays(&multiVal[0],&multiVal[0]+multiVal.size(),arrIn,arrIndxIn,srcArr,srcArrIndex,arrOut,arrIndexOut); - break; - } - case 4: - { - MEDCouplingUMesh::SetPartOfIndexedArrays(daIntTyypp->begin(),daIntTyypp->end(),arrIn,arrIndxIn,srcArr,srcArrIndex,arrOut,arrIndexOut); - break; - } - default: - throw INTERP_KERNEL::Exception("MEDCouplingUMesh::SetPartOfIndexedArrays : unrecognized type entered, expected list of int, tuple of int or DataArrayInt !"); - } - PyObject *ret=PyTuple_New(2); - PyTuple_SetItem(ret,0,SWIG_NewPointerObj(SWIG_as_voidptr(arrOut),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 )); - PyTuple_SetItem(ret,1,SWIG_NewPointerObj(SWIG_as_voidptr(arrIndexOut),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 )); - return ret; - } - - static void SetPartOfIndexedArraysSameIdx(PyObject *li, DataArrayInt *arrIn, const DataArrayInt *arrIndxIn, - const DataArrayInt *srcArr, const DataArrayInt *srcArrIndex) throw(INTERP_KERNEL::Exception) - { - int sw; - int singleVal; - std::vector multiVal; - std::pair > slic; - ParaMEDMEM::DataArrayInt *daIntTyypp=0; - if(!arrIndxIn) - throw INTERP_KERNEL::Exception("MEDCouplingUMesh::SetPartOfIndexedArraysSameIdx : null pointer as arrIndex !"); - convertObjToPossibleCpp2(li,arrIndxIn->getNumberOfTuples()-1,sw,singleVal,multiVal,slic,daIntTyypp); - switch(sw) - { - case 1: - { - MEDCouplingUMesh::SetPartOfIndexedArraysSameIdx(&singleVal,&singleVal+1,arrIn,arrIndxIn,srcArr,srcArrIndex); - break; - } - case 2: - { - MEDCouplingUMesh::SetPartOfIndexedArraysSameIdx(&multiVal[0],&multiVal[0]+multiVal.size(),arrIn,arrIndxIn,srcArr,srcArrIndex); - break; - } - case 4: - { - MEDCouplingUMesh::SetPartOfIndexedArraysSameIdx(daIntTyypp->begin(),daIntTyypp->end(),arrIn,arrIndxIn,srcArr,srcArrIndex); - break; - } - default: - throw INTERP_KERNEL::Exception("MEDCouplingUMesh::SetPartOfIndexedArraysSameIdx : unrecognized type entered, expected list of int, tuple of int or DataArrayInt !"); - } - } - - PyObject *are2DCellsNotCorrectlyOriented(PyObject *vec, bool polyOnly) const throw(INTERP_KERNEL::Exception) - { - double val; - DataArrayDouble *a; - DataArrayDoubleTuple *aa; - std::vector bb; - int sw; - int spaceDim=self->getSpaceDimension(); - const char msg[]="Python wrap of MEDCouplingUMesh::are2DCellsNotCorrectlyOriented : "; - const double *v=convertObjToPossibleCpp5_Safe(vec,sw,val,a,aa,bb,msg,1,spaceDim,true); - // - std::vector cells; - self->are2DCellsNotCorrectlyOriented(v,polyOnly,cells); - DataArrayInt *ret=DataArrayInt::New(); - ret->alloc((int)cells.size(),1); - std::copy(cells.begin(),cells.end(),ret->getPointer()); - return SWIG_NewPointerObj(SWIG_as_voidptr(ret),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 ); - } - - void orientCorrectly2DCells(PyObject *vec, bool polyOnly) throw(INTERP_KERNEL::Exception) - { - double val; - DataArrayDouble *a; - DataArrayDoubleTuple *aa; - std::vector bb; - int sw; - int spaceDim=self->getSpaceDimension(); - const char msg[]="Python wrap of MEDCouplingUMesh::orientCorrectly2DCells : "; - const double *v=convertObjToPossibleCpp5_Safe(vec,sw,val,a,aa,bb,msg,1,spaceDim,true); - self->orientCorrectly2DCells(v,polyOnly); - } - - PyObject *arePolyhedronsNotCorrectlyOriented() const throw(INTERP_KERNEL::Exception) - { - std::vector cells; - self->arePolyhedronsNotCorrectlyOriented(cells); - DataArrayInt *ret=DataArrayInt::New(); - ret->alloc((int)cells.size(),1); - std::copy(cells.begin(),cells.end(),ret->getPointer()); - return SWIG_NewPointerObj(SWIG_as_voidptr(ret),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 ); - } - - PyObject *getFastAveragePlaneOfThis() const throw(INTERP_KERNEL::Exception) - { - double vec[3]; - double pos[3]; - self->getFastAveragePlaneOfThis(vec,pos); - double vals[6]; - std::copy(vec,vec+3,vals); - std::copy(pos,pos+3,vals+3); - return convertDblArrToPyListOfTuple(vals,3,2); - } - - static MEDCouplingUMesh *MergeUMeshes(PyObject *li) throw(INTERP_KERNEL::Exception) - { - std::vector tmp; - convertFromPyObjVectorOfObj(li,SWIGTYPE_p_ParaMEDMEM__MEDCouplingUMesh,"MEDCouplingUMesh",tmp); - return MEDCouplingUMesh::MergeUMeshes(tmp); - } - - PyObject *areCellsIncludedIn(const MEDCouplingUMesh *other, int compType) const throw(INTERP_KERNEL::Exception) - { - DataArrayInt *ret1; - bool ret0=self->areCellsIncludedIn(other,compType,ret1); - PyObject *ret=PyTuple_New(2); - PyObject *ret0Py=ret0?Py_True:Py_False; - Py_XINCREF(ret0Py); - PyTuple_SetItem(ret,0,ret0Py); - PyTuple_SetItem(ret,1,SWIG_NewPointerObj(SWIG_as_voidptr(ret1),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 )); - return ret; - } - - PyObject *areCellsIncludedIn2(const MEDCouplingUMesh *other) const throw(INTERP_KERNEL::Exception) - { - DataArrayInt *ret1; - bool ret0=self->areCellsIncludedIn2(other,ret1); - PyObject *ret=PyTuple_New(2); - PyObject *ret0Py=ret0?Py_True:Py_False; - Py_XINCREF(ret0Py); - PyTuple_SetItem(ret,0,ret0Py); - PyTuple_SetItem(ret,1,SWIG_NewPointerObj(SWIG_as_voidptr(ret1),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 )); - return ret; - } - - PyObject *explode3DMeshTo1D() const throw(INTERP_KERNEL::Exception) - { - MEDCouplingAutoRefCountObjectPtr d0=DataArrayInt::New(); - MEDCouplingAutoRefCountObjectPtr d1=DataArrayInt::New(); - MEDCouplingAutoRefCountObjectPtr d2=DataArrayInt::New(); - MEDCouplingAutoRefCountObjectPtr d3=DataArrayInt::New(); - MEDCouplingUMesh *m=self->explode3DMeshTo1D(d0,d1,d2,d3); - PyObject *ret=PyTuple_New(5); - PyTuple_SetItem(ret,0,SWIG_NewPointerObj(SWIG_as_voidptr(m),SWIGTYPE_p_ParaMEDMEM__MEDCouplingUMesh, SWIG_POINTER_OWN | 0 )); - PyTuple_SetItem(ret,1,SWIG_NewPointerObj(SWIG_as_voidptr(d0.retn()),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 )); - PyTuple_SetItem(ret,2,SWIG_NewPointerObj(SWIG_as_voidptr(d1.retn()),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 )); - PyTuple_SetItem(ret,3,SWIG_NewPointerObj(SWIG_as_voidptr(d2.retn()),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 )); - PyTuple_SetItem(ret,4,SWIG_NewPointerObj(SWIG_as_voidptr(d3.retn()),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 )); - return ret; - } - - PyObject *buildDescendingConnectivity() const throw(INTERP_KERNEL::Exception) - { - MEDCouplingAutoRefCountObjectPtr d0=DataArrayInt::New(); - MEDCouplingAutoRefCountObjectPtr d1=DataArrayInt::New(); - MEDCouplingAutoRefCountObjectPtr d2=DataArrayInt::New(); - MEDCouplingAutoRefCountObjectPtr d3=DataArrayInt::New(); - MEDCouplingUMesh *m=self->buildDescendingConnectivity(d0,d1,d2,d3); - PyObject *ret=PyTuple_New(5); - PyTuple_SetItem(ret,0,SWIG_NewPointerObj(SWIG_as_voidptr(m),SWIGTYPE_p_ParaMEDMEM__MEDCouplingUMesh, SWIG_POINTER_OWN | 0 )); - PyTuple_SetItem(ret,1,SWIG_NewPointerObj(SWIG_as_voidptr(d0.retn()),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 )); - PyTuple_SetItem(ret,2,SWIG_NewPointerObj(SWIG_as_voidptr(d1.retn()),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 )); - PyTuple_SetItem(ret,3,SWIG_NewPointerObj(SWIG_as_voidptr(d2.retn()),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 )); - PyTuple_SetItem(ret,4,SWIG_NewPointerObj(SWIG_as_voidptr(d3.retn()),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 )); - return ret; - } - - PyObject *buildDescendingConnectivity2() const throw(INTERP_KERNEL::Exception) - { - MEDCouplingAutoRefCountObjectPtr d0=DataArrayInt::New(); - MEDCouplingAutoRefCountObjectPtr d1=DataArrayInt::New(); - MEDCouplingAutoRefCountObjectPtr d2=DataArrayInt::New(); - MEDCouplingAutoRefCountObjectPtr d3=DataArrayInt::New(); - MEDCouplingUMesh *m=self->buildDescendingConnectivity2(d0,d1,d2,d3); - PyObject *ret=PyTuple_New(5); - PyTuple_SetItem(ret,0,SWIG_NewPointerObj(SWIG_as_voidptr(m),SWIGTYPE_p_ParaMEDMEM__MEDCouplingUMesh, SWIG_POINTER_OWN | 0 )); - PyTuple_SetItem(ret,1,SWIG_NewPointerObj(SWIG_as_voidptr(d0.retn()),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 )); - PyTuple_SetItem(ret,2,SWIG_NewPointerObj(SWIG_as_voidptr(d1.retn()),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 )); - PyTuple_SetItem(ret,3,SWIG_NewPointerObj(SWIG_as_voidptr(d2.retn()),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 )); - PyTuple_SetItem(ret,4,SWIG_NewPointerObj(SWIG_as_voidptr(d3.retn()),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 )); - return ret; - } - - PyObject *computeNeighborsOfCells() const throw(INTERP_KERNEL::Exception) - { - DataArrayInt *neighbors=0,*neighborsIdx=0; - self->computeNeighborsOfCells(neighbors,neighborsIdx); - PyObject *ret=PyTuple_New(2); - PyTuple_SetItem(ret,0,SWIG_NewPointerObj(SWIG_as_voidptr(neighbors),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 )); - PyTuple_SetItem(ret,1,SWIG_NewPointerObj(SWIG_as_voidptr(neighborsIdx),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 )); - return ret; - } - - PyObject *computeNeighborsOfNodes() const throw(INTERP_KERNEL::Exception) - { - DataArrayInt *neighbors=0,*neighborsIdx=0; - self->computeNeighborsOfNodes(neighbors,neighborsIdx); - PyObject *ret=PyTuple_New(2); - PyTuple_SetItem(ret,0,SWIG_NewPointerObj(SWIG_as_voidptr(neighbors),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 )); - PyTuple_SetItem(ret,1,SWIG_NewPointerObj(SWIG_as_voidptr(neighborsIdx),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 )); - return ret; - } - - static PyObject *ComputeNeighborsOfCellsAdv(const DataArrayInt *desc, const DataArrayInt *descI, const DataArrayInt *revDesc, const DataArrayInt *revDescI) throw(INTERP_KERNEL::Exception) - { - DataArrayInt *neighbors=0,*neighborsIdx=0; - MEDCouplingUMesh::ComputeNeighborsOfCellsAdv(desc,descI,revDesc,revDescI,neighbors,neighborsIdx); - PyObject *ret=PyTuple_New(2); - PyTuple_SetItem(ret,0,SWIG_NewPointerObj(SWIG_as_voidptr(neighbors),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 )); - PyTuple_SetItem(ret,1,SWIG_NewPointerObj(SWIG_as_voidptr(neighborsIdx),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 )); - return ret; - } - - PyObject *emulateMEDMEMBDC(const MEDCouplingUMesh *nM1LevMesh) - { - MEDCouplingAutoRefCountObjectPtr d0=DataArrayInt::New(); - MEDCouplingAutoRefCountObjectPtr d1=DataArrayInt::New(); - DataArrayInt *d2,*d3,*d4,*dd5; - MEDCouplingUMesh *mOut=self->emulateMEDMEMBDC(nM1LevMesh,d0,d1,d2,d3,d4,dd5); - PyObject *ret=PyTuple_New(7); - PyTuple_SetItem(ret,0,SWIG_NewPointerObj(SWIG_as_voidptr(mOut),SWIGTYPE_p_ParaMEDMEM__MEDCouplingUMesh, SWIG_POINTER_OWN | 0 )); - PyTuple_SetItem(ret,1,SWIG_NewPointerObj(SWIG_as_voidptr(d0.retn()),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 )); - PyTuple_SetItem(ret,2,SWIG_NewPointerObj(SWIG_as_voidptr(d1.retn()),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 )); - PyTuple_SetItem(ret,3,SWIG_NewPointerObj(SWIG_as_voidptr(d2),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 )); - PyTuple_SetItem(ret,4,SWIG_NewPointerObj(SWIG_as_voidptr(d3),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 )); - PyTuple_SetItem(ret,5,SWIG_NewPointerObj(SWIG_as_voidptr(d4),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 )); - PyTuple_SetItem(ret,6,SWIG_NewPointerObj(SWIG_as_voidptr(dd5),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 )); - return ret; - } - - DataArrayDouble *getPartBarycenterAndOwner(DataArrayInt *da) const throw(INTERP_KERNEL::Exception) - { - if(!da) - throw INTERP_KERNEL::Exception("Not null DataArrayInt instance expected !"); - da->checkAllocated(); - return self->getPartBarycenterAndOwner(da->getConstPointer(),da->getConstPointer()+da->getNbOfElems()); - } - - DataArrayDouble *getPartMeasureField(bool isAbs, DataArrayInt *da) const throw(INTERP_KERNEL::Exception) - { - if(!da) - throw INTERP_KERNEL::Exception("Not null DataArrayInt instance expected !"); - da->checkAllocated(); - return self->getPartMeasureField(isAbs,da->getConstPointer(),da->getConstPointer()+da->getNbOfElems()); - } - - MEDCouplingFieldDouble *buildPartOrthogonalField(DataArrayInt *da) const throw(INTERP_KERNEL::Exception) - { - if(!da) - throw INTERP_KERNEL::Exception("Not null DataArrayInt instance expected !"); - da->checkAllocated(); - return self->buildPartOrthogonalField(da->getConstPointer(),da->getConstPointer()+da->getNbOfElems()); - } - - PyObject *getTypesOfPart(DataArrayInt *da) const throw(INTERP_KERNEL::Exception) - { - if(!da) - throw INTERP_KERNEL::Exception("Not null DataArrayInt instance expected !"); - da->checkAllocated(); - std::set result=self->getTypesOfPart(da->getConstPointer(),da->getConstPointer()+da->getNbOfElems()); - std::set::const_iterator iL=result.begin(); - PyObject *res = PyList_New(result.size()); - for (int i=0;iL!=result.end(); i++, iL++) - PyList_SetItem(res,i,PyInt_FromLong(*iL)); - return res; - } - - DataArrayInt *keepCellIdsByType(INTERP_KERNEL::NormalizedCellType type, DataArrayInt *da) const throw(INTERP_KERNEL::Exception) - { - if(!da) - throw INTERP_KERNEL::Exception("Not null DataArrayInt instance expected !"); - da->checkAllocated(); - DataArrayInt *ret=self->keepCellIdsByType(type,da->getConstPointer(),da->getConstPointer()+da->getNbOfElems()); - ret->setName(da->getName().c_str()); - return ret; - } - - static PyObject *Intersect2DMeshes(const MEDCouplingUMesh *m1, const MEDCouplingUMesh *m2, double eps) throw(INTERP_KERNEL::Exception) - { - DataArrayInt *cellNb1=0,*cellNb2=0; - MEDCouplingUMesh *mret=MEDCouplingUMesh::Intersect2DMeshes(m1,m2,eps,cellNb1,cellNb2); - PyObject *ret=PyTuple_New(3); - PyTuple_SetItem(ret,0,SWIG_NewPointerObj(SWIG_as_voidptr(mret),SWIGTYPE_p_ParaMEDMEM__MEDCouplingUMesh, SWIG_POINTER_OWN | 0 )); - PyTuple_SetItem(ret,1,SWIG_NewPointerObj(SWIG_as_voidptr(cellNb1),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 )); - PyTuple_SetItem(ret,2,SWIG_NewPointerObj(SWIG_as_voidptr(cellNb2),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 )); - return ret; - } - - static PyObject *Intersect2DMeshWith1DLine(const MEDCouplingUMesh *mesh2D, const MEDCouplingUMesh *mesh1D, double eps) throw(INTERP_KERNEL::Exception) - { - MEDCouplingUMesh *splitMesh2D(0),*splitMesh1D(0); - DataArrayInt *cellIdInMesh2D(0),*cellIdInMesh1D(0); - MEDCouplingUMesh::Intersect2DMeshWith1DLine(mesh2D,mesh1D,eps,splitMesh2D,splitMesh1D,cellIdInMesh2D,cellIdInMesh1D); - PyObject *ret(PyTuple_New(4)); - PyTuple_SetItem(ret,0,SWIG_NewPointerObj(SWIG_as_voidptr(splitMesh2D),SWIGTYPE_p_ParaMEDMEM__MEDCouplingUMesh, SWIG_POINTER_OWN | 0 )); - PyTuple_SetItem(ret,1,SWIG_NewPointerObj(SWIG_as_voidptr(splitMesh1D),SWIGTYPE_p_ParaMEDMEM__MEDCouplingUMesh, SWIG_POINTER_OWN | 0 )); - PyTuple_SetItem(ret,2,SWIG_NewPointerObj(SWIG_as_voidptr(cellIdInMesh2D),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 )); - PyTuple_SetItem(ret,3,SWIG_NewPointerObj(SWIG_as_voidptr(cellIdInMesh1D),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 )); - return ret; - } - - PyObject *buildSlice3D(PyObject *origin, PyObject *vec, double eps) const throw(INTERP_KERNEL::Exception) - { - int spaceDim=self->getSpaceDimension(); - if(spaceDim!=3) - throw INTERP_KERNEL::Exception("Python wrap of MEDCouplingUMesh::buildSlice3D : works only for spaceDim 3 !"); - double val,val2; - DataArrayDouble *a,*a2; - DataArrayDoubleTuple *aa,*aa2; - std::vector bb,bb2; - int sw; - const char msg[]="Python wrap of MEDCouplingUMesh::buildSlice3D : 1st paramater for origin."; - const char msg2[]="Python wrap of MEDCouplingUMesh::buildSlice3D : 2nd paramater for vector."; - const double *orig=convertObjToPossibleCpp5_Safe(origin,sw,val,a,aa,bb,msg,1,spaceDim,true); - const double *vect=convertObjToPossibleCpp5_Safe(vec,sw,val2,a2,aa2,bb2,msg2,1,spaceDim,true); - // - DataArrayInt *cellIds=0; - MEDCouplingUMesh *ret0=self->buildSlice3D(orig,vect,eps,cellIds); - PyObject *ret=PyTuple_New(2); - PyTuple_SetItem(ret,0,SWIG_NewPointerObj(SWIG_as_voidptr(ret0),SWIGTYPE_p_ParaMEDMEM__MEDCouplingUMesh, SWIG_POINTER_OWN | 0 )); - PyTuple_SetItem(ret,1,SWIG_NewPointerObj(SWIG_as_voidptr(cellIds),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 )); - return ret; - } - - PyObject *buildSlice3DSurf(PyObject *origin, PyObject *vec, double eps) const throw(INTERP_KERNEL::Exception) - { - int spaceDim=self->getSpaceDimension(); - if(spaceDim!=3) - throw INTERP_KERNEL::Exception("Python wrap of MEDCouplingUMesh::buildSlice3DSurf : works only for spaceDim 3 !"); - double val,val2; - DataArrayDouble *a,*a2; - DataArrayDoubleTuple *aa,*aa2; - std::vector bb,bb2; - int sw; - const char msg[]="Python wrap of MEDCouplingUMesh::buildSlice3DSurf : 1st paramater for origin."; - const char msg2[]="Python wrap of MEDCouplingUMesh::buildSlice3DSurf : 2nd paramater for vector."; - const double *orig=convertObjToPossibleCpp5_Safe(origin,sw,val,a,aa,bb,msg,1,spaceDim,true); - const double *vect=convertObjToPossibleCpp5_Safe(vec,sw,val2,a2,aa2,bb2,msg2,1,spaceDim,true); - // - DataArrayInt *cellIds=0; - MEDCouplingUMesh *ret0=self->buildSlice3DSurf(orig,vect,eps,cellIds); - PyObject *ret=PyTuple_New(2); - PyTuple_SetItem(ret,0,SWIG_NewPointerObj(SWIG_as_voidptr(ret0),SWIGTYPE_p_ParaMEDMEM__MEDCouplingUMesh, SWIG_POINTER_OWN | 0 )); - PyTuple_SetItem(ret,1,SWIG_NewPointerObj(SWIG_as_voidptr(cellIds),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 )); - return ret; - } - - DataArrayInt *getCellIdsCrossingPlane(PyObject *origin, PyObject *vec, double eps) const throw(INTERP_KERNEL::Exception) - { - int spaceDim=self->getSpaceDimension(); - if(spaceDim!=3) - throw INTERP_KERNEL::Exception("Python wrap of MEDCouplingUMesh::getCellIdsCrossingPlane : works only for spaceDim 3 !"); - double val,val2; - DataArrayDouble *a,*a2; - DataArrayDoubleTuple *aa,*aa2; - std::vector bb,bb2; - int sw; - const char msg[]="Python wrap of MEDCouplingUMesh::getCellIdsCrossingPlane : 1st paramater for origin."; - const char msg2[]="Python wrap of MEDCouplingUMesh::getCellIdsCrossingPlane : 2nd paramater for vector."; - const double *orig=convertObjToPossibleCpp5_Safe(origin,sw,val,a,aa,bb,msg,1,spaceDim,true); - const double *vect=convertObjToPossibleCpp5_Safe(vec,sw,val2,a2,aa2,bb2,msg2,1,spaceDim,true); - return self->getCellIdsCrossingPlane(orig,vect,eps); - } - - void convertToPolyTypes(PyObject *li) throw(INTERP_KERNEL::Exception) - { - int sw; - int pos1; - std::vector pos2; - DataArrayInt *pos3=0; - DataArrayIntTuple *pos4=0; - convertObjToPossibleCpp1(li,sw,pos1,pos2,pos3,pos4); - switch(sw) - { - case 1: - { - self->convertToPolyTypes(&pos1,&pos1+1); - return; - } - case 2: - { - if(pos2.empty()) - return; - self->convertToPolyTypes(&pos2[0],&pos2[0]+pos2.size()); - return ; - } - case 3: - { - self->convertToPolyTypes(pos3->begin(),pos3->end()); - return ; - } - default: - throw INTERP_KERNEL::Exception("MEDCouplingUMesh::convertToPolyTypes : unexpected input array type recognized !"); - } - } - } - void convertAllToPoly(); - void convertExtrudedPolyhedra() throw(INTERP_KERNEL::Exception); - bool unPolyze() throw(INTERP_KERNEL::Exception); - void simplifyPolyhedra(double eps) throw(INTERP_KERNEL::Exception); - MEDCouplingUMesh *buildSpreadZonesWithPoly() const throw(INTERP_KERNEL::Exception); - MEDCouplingUMesh *buildExtrudedMesh(const MEDCouplingUMesh *mesh1D, int policy) throw(INTERP_KERNEL::Exception); - }; - - //== MEDCouplingUMesh End - - //== MEDCouplingExtrudedMesh - - class MEDCouplingExtrudedMesh : public ParaMEDMEM::MEDCouplingMesh - { - public: - static MEDCouplingExtrudedMesh *New(const MEDCouplingUMesh *mesh3D, const MEDCouplingUMesh *mesh2D, int cell2DId) throw(INTERP_KERNEL::Exception); - MEDCouplingUMesh *build3DUnstructuredMesh() const throw(INTERP_KERNEL::Exception); - %extend { - MEDCouplingExtrudedMesh(const MEDCouplingUMesh *mesh3D, const MEDCouplingUMesh *mesh2D, int cell2DId) throw(INTERP_KERNEL::Exception) - { - return MEDCouplingExtrudedMesh::New(mesh3D,mesh2D,cell2DId); - } - - MEDCouplingExtrudedMesh() - { - return MEDCouplingExtrudedMesh::New(); - } - - static PyObject *___new___(PyObject *cls, PyObject *args) throw(INTERP_KERNEL::Exception) - { - return NewMethWrapCallInitOnlyIfEmptyDictInInput(cls,args,"MEDCouplingExtrudedMesh"); - } - - std::string __str__() const throw(INTERP_KERNEL::Exception) - { - return self->simpleRepr(); - } - - std::string __repr__() const throw(INTERP_KERNEL::Exception) - { - std::ostringstream oss; - self->reprQuickOverview(oss); - return oss.str(); - } - - PyObject *getMesh2D() const throw(INTERP_KERNEL::Exception) - { - MEDCouplingUMesh *ret=self->getMesh2D(); - if(ret) - ret->incrRef(); - return convertMesh(ret, SWIG_POINTER_OWN | 0 ); - } - PyObject *getMesh1D() const throw(INTERP_KERNEL::Exception) - { - MEDCouplingUMesh *ret=self->getMesh1D(); - if(ret) - ret->incrRef(); - return convertMesh(ret, SWIG_POINTER_OWN | 0 ); - } - PyObject *getMesh3DIds() const throw(INTERP_KERNEL::Exception) - { - DataArrayInt *ret=self->getMesh3DIds(); - if(ret) - ret->incrRef(); - return SWIG_NewPointerObj(SWIG_as_voidptr(ret),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 ); - } - } - }; - - //== MEDCouplingExtrudedMesh End - - class MEDCoupling1GTUMesh : public ParaMEDMEM::MEDCouplingPointSet - { - public: - static MEDCoupling1GTUMesh *New(const std::string& name, INTERP_KERNEL::NormalizedCellType type) throw(INTERP_KERNEL::Exception); - static MEDCoupling1GTUMesh *New(const MEDCouplingUMesh *m) throw(INTERP_KERNEL::Exception); - INTERP_KERNEL::NormalizedCellType getCellModelEnum() const throw(INTERP_KERNEL::Exception); - int getNodalConnectivityLength() const throw(INTERP_KERNEL::Exception); - virtual void allocateCells(int nbOfCells=0) throw(INTERP_KERNEL::Exception); - virtual void checkCoherencyOfConnectivity() const throw(INTERP_KERNEL::Exception); - %extend - { - virtual void insertNextCell(PyObject *li) throw(INTERP_KERNEL::Exception) - { - int szArr,sw,iTypppArr; - std::vector stdvecTyyppArr; - const int *tmp=convertObjToPossibleCpp1_Safe(li,sw,szArr,iTypppArr,stdvecTyyppArr); - self->insertNextCell(tmp,tmp+szArr); - } - - virtual DataArrayInt *getNodalConnectivity() const throw(INTERP_KERNEL::Exception) - { - DataArrayInt *ret=self->getNodalConnectivity(); - if(ret) ret->incrRef(); - return ret; - } - - static MEDCouplingUMesh *AggregateOnSameCoordsToUMesh(PyObject *li) throw(INTERP_KERNEL::Exception) - { - std::vector< const MEDCoupling1GTUMesh *> parts; - convertFromPyObjVectorOfObj(li,SWIGTYPE_p_ParaMEDMEM__MEDCoupling1GTUMesh,"MEDCoupling1GTUMesh",parts); - return MEDCoupling1GTUMesh::AggregateOnSameCoordsToUMesh(parts); - } - } - }; - - //== MEDCoupling1SGTUMesh - - class MEDCoupling1SGTUMesh : public ParaMEDMEM::MEDCoupling1GTUMesh - { - public: - static MEDCoupling1SGTUMesh *New(const std::string& name, INTERP_KERNEL::NormalizedCellType type) throw(INTERP_KERNEL::Exception); - static MEDCoupling1SGTUMesh *New(const MEDCouplingUMesh *m) throw(INTERP_KERNEL::Exception); - void setNodalConnectivity(DataArrayInt *nodalConn) throw(INTERP_KERNEL::Exception); - int getNumberOfNodesPerCell() const throw(INTERP_KERNEL::Exception); - static MEDCoupling1SGTUMesh *Merge1SGTUMeshes(const MEDCoupling1SGTUMesh *mesh1, const MEDCoupling1SGTUMesh *mesh2) throw(INTERP_KERNEL::Exception); - MEDCoupling1SGTUMesh *buildSetInstanceFromThis(int spaceDim) const throw(INTERP_KERNEL::Exception); - MEDCoupling1GTUMesh *computeDualMesh() const throw(INTERP_KERNEL::Exception); - MEDCoupling1SGTUMesh *explodeEachHexa8To6Quad4() const throw(INTERP_KERNEL::Exception); - DataArrayInt *sortHexa8EachOther() throw(INTERP_KERNEL::Exception); - %extend - { - MEDCoupling1SGTUMesh() - { - return MEDCoupling1SGTUMesh::New(); - } - - MEDCoupling1SGTUMesh(const std::string& name, INTERP_KERNEL::NormalizedCellType type) throw(INTERP_KERNEL::Exception) - { - return MEDCoupling1SGTUMesh::New(name,type); - } - - MEDCoupling1SGTUMesh(const MEDCouplingUMesh *m) throw(INTERP_KERNEL::Exception) - { - return MEDCoupling1SGTUMesh::New(m); - } - - static PyObject *___new___(PyObject *cls, PyObject *args) throw(INTERP_KERNEL::Exception) - { - return NewMethWrapCallInitOnlyIfEmptyDictInInput(cls,args,"MEDCoupling1SGTUMesh"); - } - - std::string __str__() const throw(INTERP_KERNEL::Exception) - { - return self->simpleRepr(); - } - - std::string __repr__() const throw(INTERP_KERNEL::Exception) - { - std::ostringstream oss; - self->reprQuickOverview(oss); - return oss.str(); - } - - PyObject *structurizeMe(double eps=1e-12) const throw(INTERP_KERNEL::Exception) - { - DataArrayInt *cellPerm(0),*nodePerm(0); - MEDCouplingCMesh *retCpp(self->structurizeMe(cellPerm,nodePerm,eps)); - PyObject *ret(PyTuple_New(3)); - PyTuple_SetItem(ret,0,SWIG_NewPointerObj(SWIG_as_voidptr(retCpp),SWIGTYPE_p_ParaMEDMEM__MEDCouplingCMesh, SWIG_POINTER_OWN | 0 )); - PyTuple_SetItem(ret,1,SWIG_NewPointerObj(SWIG_as_voidptr(cellPerm),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 )); - PyTuple_SetItem(ret,2,SWIG_NewPointerObj(SWIG_as_voidptr(nodePerm),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 )); - return ret; - } - - static MEDCoupling1SGTUMesh *Merge1SGTUMeshes(PyObject *li) throw(INTERP_KERNEL::Exception) - { - std::vector tmp; - convertFromPyObjVectorOfObj(li,SWIGTYPE_p_ParaMEDMEM__MEDCoupling1SGTUMesh,"MEDCoupling1SGTUMesh",tmp); - return MEDCoupling1SGTUMesh::Merge1SGTUMeshes(tmp); - } - - static MEDCoupling1SGTUMesh *Merge1SGTUMeshesOnSameCoords(PyObject *li) throw(INTERP_KERNEL::Exception) - { - std::vector tmp; - convertFromPyObjVectorOfObj(li,SWIGTYPE_p_ParaMEDMEM__MEDCoupling1SGTUMesh,"MEDCoupling1SGTUMesh",tmp); - return MEDCoupling1SGTUMesh::Merge1SGTUMeshesOnSameCoords(tmp); - } - } - }; - - //== MEDCoupling1SGTUMesh End - - //== MEDCoupling1DGTUMesh - - class MEDCoupling1DGTUMesh : public ParaMEDMEM::MEDCoupling1GTUMesh - { - public: - static MEDCoupling1DGTUMesh *New(const std::string& name, INTERP_KERNEL::NormalizedCellType type) throw(INTERP_KERNEL::Exception); - static MEDCoupling1DGTUMesh *New(const MEDCouplingUMesh *m) throw(INTERP_KERNEL::Exception); - void setNodalConnectivity(DataArrayInt *nodalConn, DataArrayInt *nodalConnIndex) throw(INTERP_KERNEL::Exception); - MEDCoupling1DGTUMesh *buildSetInstanceFromThis(int spaceDim) const throw(INTERP_KERNEL::Exception); - bool isPacked() const throw(INTERP_KERNEL::Exception); - %extend - { - MEDCoupling1DGTUMesh() - { - return MEDCoupling1DGTUMesh::New(); - } - MEDCoupling1DGTUMesh(const std::string& name, INTERP_KERNEL::NormalizedCellType type) throw(INTERP_KERNEL::Exception) - { - return MEDCoupling1DGTUMesh::New(name,type); - } - - MEDCoupling1DGTUMesh(const MEDCouplingUMesh *m) throw(INTERP_KERNEL::Exception) - { - return MEDCoupling1DGTUMesh::New(m); - } - - static PyObject *___new___(PyObject *cls, PyObject *args) throw(INTERP_KERNEL::Exception) - { - return NewMethWrapCallInitOnlyIfEmptyDictInInput(cls,args,"MEDCoupling1DGTUMesh"); - } - - std::string __str__() const throw(INTERP_KERNEL::Exception) - { - return self->simpleRepr(); - } - - std::string __repr__() const throw(INTERP_KERNEL::Exception) - { - std::ostringstream oss; - self->reprQuickOverview(oss); - return oss.str(); - } - - DataArrayInt *getNodalConnectivityIndex() const throw(INTERP_KERNEL::Exception) - { - DataArrayInt *ret=self->getNodalConnectivityIndex(); - if(ret) ret->incrRef(); - return ret; - } - - PyObject *retrievePackedNodalConnectivity() const throw(INTERP_KERNEL::Exception) - { - DataArrayInt *ret1=0,*ret2=0; - bool ret0=self->retrievePackedNodalConnectivity(ret1,ret2); - PyObject *ret0Py=ret0?Py_True:Py_False; - Py_XINCREF(ret0Py); - PyObject *ret=PyTuple_New(3); - PyTuple_SetItem(ret,0,ret0Py); - PyTuple_SetItem(ret,1,SWIG_NewPointerObj(SWIG_as_voidptr(ret1),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 )); - PyTuple_SetItem(ret,2,SWIG_NewPointerObj(SWIG_as_voidptr(ret2),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 )); - return ret; - } - - PyObject *copyWithNodalConnectivityPacked() const throw(INTERP_KERNEL::Exception) - { - bool ret1; - MEDCoupling1DGTUMesh *ret0=self->copyWithNodalConnectivityPacked(ret1); - PyObject *ret=PyTuple_New(2); - PyObject *ret1Py=ret1?Py_True:Py_False; Py_XINCREF(ret1Py); - PyTuple_SetItem(ret,0,SWIG_NewPointerObj(SWIG_as_voidptr(ret0),SWIGTYPE_p_ParaMEDMEM__MEDCoupling1DGTUMesh, SWIG_POINTER_OWN | 0 )); - PyTuple_SetItem(ret,1,ret1Py); - return ret; - } - - static MEDCoupling1DGTUMesh *Merge1DGTUMeshes(PyObject *li) throw(INTERP_KERNEL::Exception) - { - std::vector tmp; - convertFromPyObjVectorOfObj(li,SWIGTYPE_p_ParaMEDMEM__MEDCoupling1DGTUMesh,"MEDCoupling1DGTUMesh",tmp); - return MEDCoupling1DGTUMesh::Merge1DGTUMeshes(tmp); - } - - static MEDCoupling1DGTUMesh *Merge1DGTUMeshesOnSameCoords(PyObject *li) throw(INTERP_KERNEL::Exception) - { - std::vector tmp; - convertFromPyObjVectorOfObj(li,SWIGTYPE_p_ParaMEDMEM__MEDCoupling1DGTUMesh,"MEDCoupling1DGTUMesh",tmp); - return MEDCoupling1DGTUMesh::Merge1DGTUMeshesOnSameCoords(tmp); - } - - static DataArrayInt *AggregateNodalConnAndShiftNodeIds(PyObject *li, const std::vector& offsetInNodeIdsPerElt) throw(INTERP_KERNEL::Exception) - { - std::vector tmp; - convertFromPyObjVectorOfObj(li,SWIGTYPE_p_ParaMEDMEM__DataArrayInt,"DataArrayInt",tmp); - return MEDCoupling1DGTUMesh::AggregateNodalConnAndShiftNodeIds(tmp,offsetInNodeIdsPerElt); - } - } - }; - - //== MEDCoupling1DGTUMeshEnd - - class MEDCouplingStructuredMesh : public ParaMEDMEM::MEDCouplingMesh - { - public: - int getCellIdFromPos(int i, int j, int k) const throw(INTERP_KERNEL::Exception); - int getNodeIdFromPos(int i, int j, int k) const throw(INTERP_KERNEL::Exception); - int getNumberOfCellsOfSubLevelMesh() const throw(INTERP_KERNEL::Exception); - int getSpaceDimensionOnNodeStruct() const throw(INTERP_KERNEL::Exception); - double computeSquareness() const throw(INTERP_KERNEL::Exception); - virtual std::vector getNodeGridStructure() const throw(INTERP_KERNEL::Exception); - std::vector getCellGridStructure() const throw(INTERP_KERNEL::Exception); - MEDCoupling1SGTUMesh *build1SGTUnstructured() const throw(INTERP_KERNEL::Exception); - std::vector getLocationFromCellId(int cellId) const throw(INTERP_KERNEL::Exception); - std::vector getLocationFromNodeId(int cellId) const throw(INTERP_KERNEL::Exception); - static INTERP_KERNEL::NormalizedCellType GetGeoTypeGivenMeshDimension(int meshDim) throw(INTERP_KERNEL::Exception); - MEDCoupling1SGTUMesh *build1SGTSubLevelMesh() const throw(INTERP_KERNEL::Exception); - static int DeduceNumberOfGivenStructure(const std::vector& st) throw(INTERP_KERNEL::Exception); - static DataArrayInt *ComputeCornersGhost(const std::vector& st, int ghostLev) throw(INTERP_KERNEL::Exception); - static std::vector GetSplitVectFromStruct(const std::vector& strct) throw(INTERP_KERNEL::Exception); - %extend - { - virtual MEDCouplingStructuredMesh *buildStructuredSubPart(PyObject *cellPart) const throw(INTERP_KERNEL::Exception) - { - int tmpp1=-1,tmpp2=-1; - std::vector tmp=fillArrayWithPyListInt2(cellPart,tmpp1,tmpp2); - std::vector< std::pair > inp; - if(tmpp2==2) - { - inp.resize(tmpp1); - for(int i=0;ibuildStructuredSubPart(inp); - } - - static DataArrayInt *BuildExplicitIdsFrom(PyObject *st, PyObject *part) throw(INTERP_KERNEL::Exception) - { - std::vector< std::pair > inp; - convertPyToVectorPairInt(part,inp); - // - int szArr,sw,iTypppArr; - std::vector stdvecTyyppArr; - const int *tmp4=convertObjToPossibleCpp1_Safe(st,sw,szArr,iTypppArr,stdvecTyyppArr); - std::vector tmp5(tmp4,tmp4+szArr); - // - return MEDCouplingStructuredMesh::BuildExplicitIdsFrom(tmp5,inp); - } - - static void MultiplyPartOf(const std::vector& st, PyObject *part, double factor, DataArrayDouble *da) throw(INTERP_KERNEL::Exception) - { - std::vector< std::pair > inp; - convertPyToVectorPairInt(part,inp); - MEDCouplingStructuredMesh::MultiplyPartOf(st,inp,factor,da); - } - - static void MultiplyPartOfByGhost(const std::vector& st, PyObject *part, int ghostSize, double factor, DataArrayDouble *da) throw(INTERP_KERNEL::Exception) - { - std::vector< std::pair > inp; - convertPyToVectorPairInt(part,inp); - MEDCouplingStructuredMesh::MultiplyPartOfByGhost(st,inp,ghostSize,factor,da); - } - - static PyObject *PutInGhostFormat(int ghostSize, const std::vector& st, PyObject *part) throw(INTERP_KERNEL::Exception) - { - std::vector< std::pair > inp; - convertPyToVectorPairInt(part,inp); - std::vector stWithGhost; - std::vector< std::pair > partWithGhost; - MEDCouplingStructuredMesh::PutInGhostFormat(ghostSize,st,inp,stWithGhost,partWithGhost); - PyObject *ret(PyTuple_New(2)); - PyTuple_SetItem(ret,0,convertIntArrToPyList2(stWithGhost)); - PyTuple_SetItem(ret,1,convertFromVectorPairInt(partWithGhost)); - return ret; - } - - static DataArrayDouble *ExtractFieldOfDoubleFrom(const std::vector& st, const DataArrayDouble *fieldOfDbl, PyObject *partCompactFormat) throw(INTERP_KERNEL::Exception) - { - std::vector< std::pair > inp; - convertPyToVectorPairInt(partCompactFormat,inp); - return MEDCouplingStructuredMesh::ExtractFieldOfDoubleFrom(st,fieldOfDbl,inp); - } - - static void AssignPartOfFieldOfDoubleUsing(const std::vector& st, DataArrayDouble *fieldOfDbl, PyObject *partCompactFormat, const DataArrayDouble *other) throw(INTERP_KERNEL::Exception) - { - std::vector< std::pair > inp; - convertPyToVectorPairInt(partCompactFormat,inp); - MEDCouplingStructuredMesh::AssignPartOfFieldOfDoubleUsing(st,fieldOfDbl,inp,other); - } - - static int DeduceNumberOfGivenRangeInCompactFrmt(PyObject *part) throw(INTERP_KERNEL::Exception) - { - std::vector< std::pair > inp; - convertPyToVectorPairInt(part,inp); - return MEDCouplingStructuredMesh::DeduceNumberOfGivenRangeInCompactFrmt(inp); - } - - static DataArrayInt *Build1GTNodalConnectivity(PyObject *li) throw(INTERP_KERNEL::Exception) - { - int szArr,sw,iTypppArr; - std::vector stdvecTyyppArr; - const int *tmp=convertObjToPossibleCpp1_Safe(li,sw,szArr,iTypppArr,stdvecTyyppArr); - return MEDCouplingStructuredMesh::Build1GTNodalConnectivity(tmp,tmp+szArr); - } - - static DataArrayInt *Build1GTNodalConnectivityOfSubLevelMesh(PyObject *li) throw(INTERP_KERNEL::Exception) - { - int szArr,sw,iTypppArr; - std::vector stdvecTyyppArr; - const int *tmp(convertObjToPossibleCpp1_Safe(li,sw,szArr,iTypppArr,stdvecTyyppArr)); - return MEDCouplingStructuredMesh::Build1GTNodalConnectivityOfSubLevelMesh(tmp,tmp+szArr); - } - - static std::vector GetDimensionsFromCompactFrmt(PyObject *partCompactFormat) throw(INTERP_KERNEL::Exception) - { - std::vector< std::pair > inp; - convertPyToVectorPairInt(partCompactFormat,inp); - return MEDCouplingStructuredMesh::GetDimensionsFromCompactFrmt(inp); - } - - static PyObject *GetCompactFrmtFromDimensions(const std::vector& dims) throw(INTERP_KERNEL::Exception) - { - std::vector< std::pair > ret(MEDCouplingStructuredMesh::GetCompactFrmtFromDimensions(dims)); - PyObject *retPy=PyList_New(ret.size()); - for(std::size_t i=0;i > r1Cpp,r2Cpp; - convertPyToVectorPairInt(r1,r1Cpp); - convertPyToVectorPairInt(r2,r2Cpp); - std::vector< std::pair > ret(MEDCouplingStructuredMesh::IntersectRanges(r1Cpp,r2Cpp)); - PyObject *retPy=PyList_New(ret.size()); - for(std::size_t i=0;i > r1Cpp,r2Cpp; - convertPyToVectorPairInt(r1,r1Cpp); - convertPyToVectorPairInt(r2,r2Cpp); - return MEDCouplingStructuredMesh::AreRangesIntersect(r1Cpp,r2Cpp); - } - - static PyObject *IsPartStructured(PyObject *li, PyObject *st) throw(INTERP_KERNEL::Exception) - { - int szArr,sw,iTypppArr; - std::vector stdvecTyyppArr; - const int *tmp=convertObjToPossibleCpp1_Safe(li,sw,szArr,iTypppArr,stdvecTyyppArr); - int szArr2,sw2,iTypppArr2; - std::vector stdvecTyyppArr2; - const int *tmp2=convertObjToPossibleCpp1_Safe(st,sw2,szArr2,iTypppArr2,stdvecTyyppArr2); - std::vector tmp3(tmp2,tmp2+szArr2); - std::vector< std::pair > partCompactFormat; - bool ret0=MEDCouplingStructuredMesh::IsPartStructured(tmp,tmp+szArr,tmp3,partCompactFormat); - PyObject *ret=PyTuple_New(2); - PyObject *ret0Py=ret0?Py_True:Py_False; Py_XINCREF(ret0Py); - PyTuple_SetItem(ret,0,ret0Py); - PyObject *ret1Py=PyList_New(partCompactFormat.size()); - for(std::size_t i=0;i > param0,param1,ret; - convertPyToVectorPairInt(bigInAbs,param0); - convertPyToVectorPairInt(partOfBigInAbs,param1); - MEDCouplingStructuredMesh::ChangeReferenceFromGlobalOfCompactFrmt(param0,param1,ret,check); - PyObject *retPy(PyList_New(ret.size())); - for(std::size_t i=0;i& translation) throw(INTERP_KERNEL::Exception) - { - std::vector< std::pair > param0; - convertPyToVectorPairInt(part,param0); - std::vector< std::pair > ret(MEDCouplingStructuredMesh::TranslateCompactFrmt(param0,translation)); - PyObject *retPy(PyList_New(ret.size())); - for(std::size_t i=0;i FindTranslationFrom(PyObject *startingFrom, PyObject *goingTo) throw(INTERP_KERNEL::Exception) - { - std::vector< std::pair > param0,param1; - convertPyToVectorPairInt(startingFrom,param0); - convertPyToVectorPairInt(goingTo,param1); - return MEDCouplingStructuredMesh::FindTranslationFrom(param0,param1); - } - - static PyObject *ChangeReferenceToGlobalOfCompactFrmt(PyObject *bigInAbs, PyObject *partOfBigRelativeToBig, bool check=true) throw(INTERP_KERNEL::Exception) - { - std::vector< std::pair > param0,param1,ret; - convertPyToVectorPairInt(bigInAbs,param0); - convertPyToVectorPairInt(partOfBigRelativeToBig,param1); - MEDCouplingStructuredMesh::ChangeReferenceToGlobalOfCompactFrmt(param0,param1,ret,check); - PyObject *retPy(PyList_New(ret.size())); - for(std::size_t i=0;isimpleRepr(); - } - std::string __repr__() const throw(INTERP_KERNEL::Exception) - { - std::ostringstream oss; - self->reprQuickOverview(oss); - return oss.str(); - } - DataArrayDouble *getCoordsAt(int i) throw(INTERP_KERNEL::Exception) - { - DataArrayDouble *ret=self->getCoordsAt(i); - if(ret) - ret->incrRef(); - return ret; - } - } - }; - - //== MEDCouplingCMesh End - - //== MEDCouplingCurveLinearMesh - - class MEDCouplingCurveLinearMesh : public ParaMEDMEM::MEDCouplingStructuredMesh - { - public: - static MEDCouplingCurveLinearMesh *New() throw(INTERP_KERNEL::Exception); - static MEDCouplingCurveLinearMesh *New(const std::string& meshName) throw(INTERP_KERNEL::Exception); - MEDCouplingCurveLinearMesh *clone(bool recDeepCpy) const; - void setCoords(const DataArrayDouble *coords) throw(INTERP_KERNEL::Exception); - %extend { - MEDCouplingCurveLinearMesh() throw(INTERP_KERNEL::Exception) - { - return MEDCouplingCurveLinearMesh::New(); - } - MEDCouplingCurveLinearMesh(const std::string& meshName) throw(INTERP_KERNEL::Exception) - { - return MEDCouplingCurveLinearMesh::New(meshName); - } - static PyObject *___new___(PyObject *cls, PyObject *args) throw(INTERP_KERNEL::Exception) - { - return NewMethWrapCallInitOnlyIfEmptyDictInInput(cls,args,"MEDCouplingCurveLinearMesh"); - } - std::string __str__() const throw(INTERP_KERNEL::Exception) - { - return self->simpleRepr(); - } - std::string __repr__() const throw(INTERP_KERNEL::Exception) - { - std::ostringstream oss; - self->reprQuickOverview(oss); - return oss.str(); - } - DataArrayDouble *getCoords() throw(INTERP_KERNEL::Exception) - { - DataArrayDouble *ret=self->getCoords(); - if(ret) - ret->incrRef(); - return ret; - } - void setNodeGridStructure(PyObject *gridStruct) throw(INTERP_KERNEL::Exception) - { - int szArr,sw,iTypppArr; - std::vector stdvecTyyppArr; - const int *tmp=convertObjToPossibleCpp1_Safe(gridStruct,sw,szArr,iTypppArr,stdvecTyyppArr); - self->setNodeGridStructure(tmp,tmp+szArr); - } - } - }; - - //== MEDCouplingCurveLinearMesh End - - //== MEDCouplingIMesh - - class MEDCouplingIMesh : public ParaMEDMEM::MEDCouplingStructuredMesh - { - public: - static MEDCouplingIMesh *New() throw(INTERP_KERNEL::Exception); - // - void setSpaceDimension(int spaceDim) throw(INTERP_KERNEL::Exception); - std::vector getNodeStruct() const throw(INTERP_KERNEL::Exception); - std::vector getOrigin() const throw(INTERP_KERNEL::Exception); - std::vector getDXYZ() const throw(INTERP_KERNEL::Exception); - void setAxisUnit(const std::string& unitName) throw(INTERP_KERNEL::Exception); - std::string getAxisUnit() const throw(INTERP_KERNEL::Exception); - double getMeasureOfAnyCell() const throw(INTERP_KERNEL::Exception); - MEDCouplingCMesh *convertToCartesian() const throw(INTERP_KERNEL::Exception); - void refineWithFactor(const std::vector& factors) throw(INTERP_KERNEL::Exception); - MEDCouplingIMesh *asSingleCell() const throw(INTERP_KERNEL::Exception); - MEDCouplingIMesh *buildWithGhost(int ghostLev) const throw(INTERP_KERNEL::Exception); - %extend - { - MEDCouplingIMesh() - { - return MEDCouplingIMesh::New(); - } - static MEDCouplingIMesh *New(const std::string& meshName, int spaceDim, PyObject *nodeStrct, PyObject *origin, PyObject *dxyz) throw(INTERP_KERNEL::Exception) - { - static const char msg0[]="MEDCouplingIMesh::New : error on 'origin' parameter !"; - static const char msg1[]="MEDCouplingIMesh::New : error on 'dxyz' parameter !"; - const int *nodeStrctPtr(0); - const double *originPtr(0),*dxyzPtr(0); - int sw,sz,val0; - std::vector bb0; - nodeStrctPtr=convertObjToPossibleCpp1_Safe(nodeStrct,sw,sz,val0,bb0); - // - double val,val2; - std::vector bb,bb2; - int sz1,sz2; - originPtr=convertObjToPossibleCpp5_SingleCompo(origin,sw,val,bb,msg0,false,sz1); - dxyzPtr=convertObjToPossibleCpp5_SingleCompo(dxyz,sw,val2,bb2,msg1,false,sz2); - // - return MEDCouplingIMesh::New(meshName,spaceDim,nodeStrctPtr,nodeStrctPtr+sz,originPtr,originPtr+sz1,dxyzPtr,dxyzPtr+sz2); - } - - MEDCouplingIMesh(const std::string& meshName, int spaceDim, PyObject *nodeStrct, PyObject *origin, PyObject *dxyz) throw(INTERP_KERNEL::Exception) - { - return ParaMEDMEM_MEDCouplingIMesh_New__SWIG_1(meshName,spaceDim,nodeStrct,origin,dxyz); - } - - static PyObject *___new___(PyObject *cls, PyObject *args) throw(INTERP_KERNEL::Exception) - { - return NewMethWrapCallInitOnlyIfEmptyDictInInput(cls,args,"MEDCouplingIMesh"); - } - - void setNodeStruct(PyObject *nodeStrct) throw(INTERP_KERNEL::Exception) - { - int sw,sz,val0; - std::vector bb0; - const int *nodeStrctPtr(convertObjToPossibleCpp1_Safe(nodeStrct,sw,sz,val0,bb0)); - self->setNodeStruct(nodeStrctPtr,nodeStrctPtr+sz); - } - - void setOrigin(PyObject *origin) throw(INTERP_KERNEL::Exception) - { - static const char msg[]="MEDCouplingIMesh::setOrigin : invalid input 'origin' parameter ! integer, float, list/tuple of float, DataArrayDouble or DataArrayDoubleTuple supported !"; - double val; - DataArrayDouble *a; - DataArrayDoubleTuple *aa; - std::vector bb; - int sw,nbTuples; - const double *originPtr(convertObjToPossibleCpp5_SingleCompo(origin,sw,val,bb,msg,false,nbTuples)); - self->setOrigin(originPtr,originPtr+nbTuples); - } - - void setDXYZ(PyObject *dxyz) throw(INTERP_KERNEL::Exception) - { - static const char msg[]="MEDCouplingIMesh::setDXYZ : invalid input 'dxyz' parameter ! integer, float, list/tuple of float, DataArrayDouble or DataArrayDoubleTuple supported !"; - double val; - DataArrayDouble *a; - DataArrayDoubleTuple *aa; - std::vector bb; - int sw,nbTuples; - const double *originPtr(convertObjToPossibleCpp5_SingleCompo(dxyz,sw,val,bb,msg,false,nbTuples)); - self->setDXYZ(originPtr,originPtr+nbTuples); - } - - static void CondenseFineToCoarse(const std::vector& coarseSt, const DataArrayDouble *fineDA, PyObject *fineLocInCoarse, const std::vector& facts, DataArrayDouble *coarseDA) throw(INTERP_KERNEL::Exception) - { - std::vector< std::pair > inp; - convertPyToVectorPairInt(fineLocInCoarse,inp); - MEDCouplingIMesh::CondenseFineToCoarse(coarseSt,fineDA,inp,facts,coarseDA); - } - - static void CondenseFineToCoarseGhost(const std::vector& coarseSt, const DataArrayDouble *fineDA, PyObject *fineLocInCoarse, const std::vector& facts, DataArrayDouble *coarseDA, int ghostSize) throw(INTERP_KERNEL::Exception) - { - std::vector< std::pair > inp; - convertPyToVectorPairInt(fineLocInCoarse,inp); - MEDCouplingIMesh::CondenseFineToCoarseGhost(coarseSt,fineDA,inp,facts,coarseDA,ghostSize); - } - - static void SpreadCoarseToFine(const DataArrayDouble *coarseDA, const std::vector& coarseSt, DataArrayDouble *fineDA, PyObject *fineLocInCoarse, const std::vector& facts) throw(INTERP_KERNEL::Exception) - { - std::vector< std::pair > inp; - convertPyToVectorPairInt(fineLocInCoarse,inp); - MEDCouplingIMesh::SpreadCoarseToFine(coarseDA,coarseSt,fineDA,inp,facts); - } - - static void SpreadCoarseToFineGhost(const DataArrayDouble *coarseDA, const std::vector& coarseSt, DataArrayDouble *fineDA, PyObject *fineLocInCoarse, const std::vector& facts, int ghostSize) throw(INTERP_KERNEL::Exception) - { - std::vector< std::pair > inp; - convertPyToVectorPairInt(fineLocInCoarse,inp); - MEDCouplingIMesh::SpreadCoarseToFineGhost(coarseDA,coarseSt,fineDA,inp,facts,ghostSize); - } - - static void SpreadCoarseToFineGhostZone(const DataArrayDouble *coarseDA, const std::vector& coarseSt, DataArrayDouble *fineDA, PyObject *fineLocInCoarse, const std::vector& facts, int ghostSize) throw(INTERP_KERNEL::Exception) - { - std::vector< std::pair > inp; - convertPyToVectorPairInt(fineLocInCoarse,inp); - MEDCouplingIMesh::SpreadCoarseToFineGhostZone(coarseDA,coarseSt,fineDA,inp,facts,ghostSize); - } - - std::string __str__() const throw(INTERP_KERNEL::Exception) - { - return self->simpleRepr(); - } - std::string __repr__() const throw(INTERP_KERNEL::Exception) - { - std::ostringstream oss; - self->reprQuickOverview(oss); - return oss.str(); - } - } - }; - - //== MEDCouplingIMesh End - -} - -namespace ParaMEDMEM -{ - class MEDCouplingField : public ParaMEDMEM::RefCountObject, public ParaMEDMEM::TimeLabel - { - public: - virtual void checkCoherency() const throw(INTERP_KERNEL::Exception); - virtual bool areCompatibleForMerge(const MEDCouplingField *other) const throw(INTERP_KERNEL::Exception); - virtual bool isEqual(const MEDCouplingField *other, double meshPrec, double valsPrec) const throw(INTERP_KERNEL::Exception); - virtual bool isEqualWithoutConsideringStr(const MEDCouplingField *other, double meshPrec, double valsPrec) const throw(INTERP_KERNEL::Exception); - virtual void copyTinyStringsFrom(const MEDCouplingField *other) throw(INTERP_KERNEL::Exception); - void setMesh(const ParaMEDMEM::MEDCouplingMesh *mesh) throw(INTERP_KERNEL::Exception); - void setName(const char *name) throw(INTERP_KERNEL::Exception); - std::string getDescription() const throw(INTERP_KERNEL::Exception); - void setDescription(const char *desc) throw(INTERP_KERNEL::Exception); - std::string getName() const throw(INTERP_KERNEL::Exception); - TypeOfField getTypeOfField() const throw(INTERP_KERNEL::Exception); - NatureOfField getNature() const throw(INTERP_KERNEL::Exception); - virtual void setNature(NatureOfField nat) throw(INTERP_KERNEL::Exception); - DataArrayDouble *getLocalizationOfDiscr() const throw(INTERP_KERNEL::Exception); - MEDCouplingFieldDouble *buildMeasureField(bool isAbs) const throw(INTERP_KERNEL::Exception); - int getNumberOfTuplesExpected() const throw(INTERP_KERNEL::Exception); - int getNumberOfMeshPlacesExpected() const throw(INTERP_KERNEL::Exception); - void setGaussLocalizationOnType(INTERP_KERNEL::NormalizedCellType type, const std::vector& refCoo, - const std::vector& gsCoo, const std::vector& wg) throw(INTERP_KERNEL::Exception); - void clearGaussLocalizations() 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); - const MEDCouplingGaussLocalization& getGaussLocalization(int locId) const throw(INTERP_KERNEL::Exception); - int getGaussLocalizationIdOfOneType(INTERP_KERNEL::NormalizedCellType type) const throw(INTERP_KERNEL::Exception); - void setDiscretization(MEDCouplingFieldDiscretization *newDisc); - %extend { - PyObject *getMesh() const throw(INTERP_KERNEL::Exception) - { - MEDCouplingMesh *ret1=const_cast(self->getMesh()); - if(ret1) - ret1->incrRef(); - return convertMesh(ret1,SWIG_POINTER_OWN | 0 ); - } - - PyObject *getDiscretization() throw(INTERP_KERNEL::Exception) - { - MEDCouplingFieldDiscretization *ret=self->getDiscretization(); - if(ret) - ret->incrRef(); - return convertFieldDiscretization(ret,SWIG_POINTER_OWN | 0 ); - } - - PyObject *getGaussLocalizationIdsOfOneType(INTERP_KERNEL::NormalizedCellType type) const throw(INTERP_KERNEL::Exception) - { - std::set ret=self->getGaussLocalizationIdsOfOneType(type); - return convertIntArrToPyList3(ret); - } - - PyObject *isEqualIfNotWhy(const MEDCouplingField *other, double meshPrec, double valsPrec) const throw(INTERP_KERNEL::Exception) - { - std::string ret1; - bool ret0=self->isEqualIfNotWhy(other,meshPrec,valsPrec,ret1); - PyObject *ret=PyTuple_New(2); - PyObject *ret0Py=ret0?Py_True:Py_False; - Py_XINCREF(ret0Py); - PyTuple_SetItem(ret,0,ret0Py); - PyTuple_SetItem(ret,1,PyString_FromString(ret1.c_str())); - return ret; - } - - PyObject *buildSubMeshData(PyObject *li) const throw(INTERP_KERNEL::Exception) - { - DataArrayInt *ret1=0; - MEDCouplingMesh *ret0=0; - void *da=0; - int res1=SWIG_ConvertPtr(li,&da,SWIGTYPE_p_ParaMEDMEM__DataArrayInt, 0 | 0 ); - if (!SWIG_IsOK(res1)) - { - int size; - INTERP_KERNEL::AutoPtr tmp=convertPyToNewIntArr2(li,&size); - ret0=self->buildSubMeshData(tmp,tmp+size,ret1); - } - else - { - DataArrayInt *da2=reinterpret_cast< DataArrayInt * >(da); - if(!da2) - throw INTERP_KERNEL::Exception("Not null DataArrayInt instance expected !"); - da2->checkAllocated(); - ret0=self->buildSubMeshData(da2->getConstPointer(),da2->getConstPointer()+da2->getNbOfElems(),ret1); - } - PyObject *res = PyList_New(2); - PyList_SetItem(res,0,convertMesh(ret0, SWIG_POINTER_OWN | 0 )); - PyList_SetItem(res,1,SWIG_NewPointerObj((void*)ret1,SWIGTYPE_p_ParaMEDMEM__DataArrayInt,SWIG_POINTER_OWN | 0)); - return res; - } - - PyObject *buildSubMeshDataRange(int begin, int end, int step) const throw(INTERP_KERNEL::Exception) - { - DataArrayInt *ret1=0; - int bb,ee,ss; - MEDCouplingMesh *ret0=self->buildSubMeshDataRange(begin,end,step,bb,ee,ss,ret1); - PyObject *res=PyTuple_New(2); - PyTuple_SetItem(res,0,convertMesh(ret0, SWIG_POINTER_OWN | 0 )); - if(ret1) - PyTuple_SetItem(res,1,SWIG_NewPointerObj((void*)ret1,SWIGTYPE_p_ParaMEDMEM__DataArrayInt,SWIG_POINTER_OWN | 0)); - else - { - PyObject *res1=PySlice_New(PyInt_FromLong(bb),PyInt_FromLong(ee),PyInt_FromLong(ss)); - PyTuple_SetItem(res,1,res1); - } - return res; - } - - DataArrayInt *computeTupleIdsToSelectFromCellIds(PyObject *cellIds) const - { - int sw,sz(-1); - int v0; std::vector v1; - const int *cellIdsBg(convertObjToPossibleCpp1_Safe(cellIds,sw,sz,v0,v1)); - return self->computeTupleIdsToSelectFromCellIds(cellIdsBg,cellIdsBg+sz); - } - - void setGaussLocalizationOnCells(PyObject *li, const std::vector& refCoo, - const std::vector& gsCoo, const std::vector& wg) throw(INTERP_KERNEL::Exception) - { - void *da=0; - int res1=SWIG_ConvertPtr(li,&da,SWIGTYPE_p_ParaMEDMEM__DataArrayInt, 0 | 0 ); - if (!SWIG_IsOK(res1)) - { - int size; - INTERP_KERNEL::AutoPtr tmp=convertPyToNewIntArr2(li,&size); - self->setGaussLocalizationOnCells(tmp,((int *)tmp)+size,refCoo,gsCoo,wg); - } - else - { - DataArrayInt *da2=reinterpret_cast< DataArrayInt * >(da); - if(!da2) - throw INTERP_KERNEL::Exception("Not null DataArrayInt instance expected !"); - da2->checkAllocated(); - self->setGaussLocalizationOnCells(da2->getConstPointer(),da2->getConstPointer()+da2->getNbOfElems(),refCoo,gsCoo,wg); - } - } - - PyObject *getCellIdsHavingGaussLocalization(int locId) const throw(INTERP_KERNEL::Exception) - { - std::vector tmp; - self->getCellIdsHavingGaussLocalization(locId,tmp); - DataArrayInt *ret=DataArrayInt::New(); - ret->alloc((int)tmp.size(),1); - std::copy(tmp.begin(),tmp.end(),ret->getPointer()); - return SWIG_NewPointerObj(SWIG_as_voidptr(ret),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 ); - } - - int getNumberOfTuplesExpectedRegardingCode(PyObject *code, PyObject *idsPerType) const throw(INTERP_KERNEL::Exception) - { - std::vector inp0; - convertPyToNewIntArr4(code,1,3,inp0); - std::vector inp1; - convertFromPyObjVectorOfObj(idsPerType,SWIGTYPE_p_ParaMEDMEM__DataArrayInt,"DataArrayInt",inp1); - return self->getNumberOfTuplesExpectedRegardingCode(inp0,inp1); - } - } - }; - - class MEDCouplingFieldTemplate : public ParaMEDMEM::MEDCouplingField - { - public: - static MEDCouplingFieldTemplate *New(const MEDCouplingFieldDouble& f) throw(INTERP_KERNEL::Exception); - static MEDCouplingFieldTemplate *New(TypeOfField type); - std::string simpleRepr() const throw(INTERP_KERNEL::Exception); - std::string advancedRepr() const throw(INTERP_KERNEL::Exception); - %extend - { - MEDCouplingFieldTemplate(const MEDCouplingFieldDouble& f) throw(INTERP_KERNEL::Exception) - { - return MEDCouplingFieldTemplate::New(f); - } - - MEDCouplingFieldTemplate(TypeOfField type) throw(INTERP_KERNEL::Exception) - { - return MEDCouplingFieldTemplate::New(type); - } - - std::string __str__() const throw(INTERP_KERNEL::Exception) - { - return self->simpleRepr(); - } - - std::string __repr__() const throw(INTERP_KERNEL::Exception) - { - std::ostringstream oss; - self->reprQuickOverview(oss); - return oss.str(); - } - } - }; - - class MEDCouplingFieldDouble : public ParaMEDMEM::MEDCouplingField - { - public: - static MEDCouplingFieldDouble *New(TypeOfField type, TypeOfTimeDiscretization td=ONE_TIME); - static MEDCouplingFieldDouble *New(const MEDCouplingFieldTemplate& ft, TypeOfTimeDiscretization td=ONE_TIME); - void setTimeUnit(const std::string& unit); - std::string getTimeUnit() const; - void synchronizeTimeWithSupport() 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 throw(INTERP_KERNEL::Exception); - std::string advancedRepr() const throw(INTERP_KERNEL::Exception); - std::string writeVTK(const std::string& fileName, bool isBinary=true) const throw(INTERP_KERNEL::Exception); - MEDCouplingFieldDouble *clone(bool recDeepCpy) const; - MEDCouplingFieldDouble *cloneWithMesh(bool recDeepCpy) const; - MEDCouplingFieldDouble *deepCpy() const; - MEDCouplingFieldDouble *buildNewTimeReprFromThis(TypeOfTimeDiscretization td, bool deepCpy) const throw(INTERP_KERNEL::Exception); - MEDCouplingFieldDouble *nodeToCellDiscretization() const throw(INTERP_KERNEL::Exception); - MEDCouplingFieldDouble *cellToNodeDiscretization() const throw(INTERP_KERNEL::Exception); - TypeOfTimeDiscretization getTimeDiscretization() const throw(INTERP_KERNEL::Exception); - double getIJ(int tupleId, int compoId) const throw(INTERP_KERNEL::Exception); - double getIJK(int cellId, int nodeIdInCell, int compoId) const throw(INTERP_KERNEL::Exception); - void synchronizeTimeWithMesh() throw(INTERP_KERNEL::Exception); - void setArray(DataArrayDouble *array) throw(INTERP_KERNEL::Exception); - void setEndArray(DataArrayDouble *array) throw(INTERP_KERNEL::Exception); - void setTime(double val, int iteration, int order) throw(INTERP_KERNEL::Exception); - void setStartTime(double val, int iteration, int order) throw(INTERP_KERNEL::Exception); - void setEndTime(double val, int iteration, int order) throw(INTERP_KERNEL::Exception); - void applyLin(double a, double b, int compoId) throw(INTERP_KERNEL::Exception); - void applyLin(double a, double b) throw(INTERP_KERNEL::Exception); - int getNumberOfComponents() const throw(INTERP_KERNEL::Exception); - int getNumberOfTuples() const throw(INTERP_KERNEL::Exception); - int getNumberOfValues() const throw(INTERP_KERNEL::Exception); - void setTimeTolerance(double val) throw(INTERP_KERNEL::Exception); - double getTimeTolerance() const throw(INTERP_KERNEL::Exception); - void setIteration(int it) throw(INTERP_KERNEL::Exception); - void setEndIteration(int it) throw(INTERP_KERNEL::Exception); - void setOrder(int order) throw(INTERP_KERNEL::Exception); - void setEndOrder(int order) throw(INTERP_KERNEL::Exception); - void setTimeValue(double val) throw(INTERP_KERNEL::Exception); - void setEndTimeValue(double val) 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); - bool zipConnectivity(int compType,double epsOnVals=1e-15) throw(INTERP_KERNEL::Exception); - bool simplexize(int policy) throw(INTERP_KERNEL::Exception); - MEDCouplingFieldDouble *doublyContractedProduct() const throw(INTERP_KERNEL::Exception); - MEDCouplingFieldDouble *determinant() const throw(INTERP_KERNEL::Exception); - MEDCouplingFieldDouble *eigenValues() const throw(INTERP_KERNEL::Exception); - MEDCouplingFieldDouble *eigenVectors() const throw(INTERP_KERNEL::Exception); - MEDCouplingFieldDouble *inverse() const throw(INTERP_KERNEL::Exception); - MEDCouplingFieldDouble *trace() const throw(INTERP_KERNEL::Exception); - MEDCouplingFieldDouble *deviator() const throw(INTERP_KERNEL::Exception); - MEDCouplingFieldDouble *magnitude() const throw(INTERP_KERNEL::Exception); - MEDCouplingFieldDouble *maxPerTuple() const throw(INTERP_KERNEL::Exception); - void changeNbOfComponents(int newNbOfComp, double dftValue=0.) throw(INTERP_KERNEL::Exception); - void sortPerTuple(bool asc) throw(INTERP_KERNEL::Exception); - MEDCouplingFieldDouble &operator=(double value) throw(INTERP_KERNEL::Exception); - void fillFromAnalytic(int nbOfComp, const std::string& func) throw(INTERP_KERNEL::Exception); - void fillFromAnalytic2(int nbOfComp, const std::string& func) throw(INTERP_KERNEL::Exception); - void fillFromAnalytic3(int nbOfComp, const std::vector& varsOrder, const std::string& func) throw(INTERP_KERNEL::Exception); - void applyFunc(int nbOfComp, const std::string& func) throw(INTERP_KERNEL::Exception); - void applyFunc2(int nbOfComp, const std::string& func) throw(INTERP_KERNEL::Exception); - void applyFunc3(int nbOfComp, const std::vector& varsOrder, const std::string& func) throw(INTERP_KERNEL::Exception); - void applyFunc(int nbOfComp, double val) throw(INTERP_KERNEL::Exception); - void applyFunc(const std::string& func) throw(INTERP_KERNEL::Exception); - void applyFuncFast32(const std::string& func) throw(INTERP_KERNEL::Exception); - void applyFuncFast64(const std::string& func) throw(INTERP_KERNEL::Exception); - double accumulate(int compId) const throw(INTERP_KERNEL::Exception); - double getMaxValue() const throw(INTERP_KERNEL::Exception); - double getMinValue() const throw(INTERP_KERNEL::Exception); - double getAverageValue() const throw(INTERP_KERNEL::Exception); - double norm2() const throw(INTERP_KERNEL::Exception); - double normMax() const throw(INTERP_KERNEL::Exception); - //do not put a default value to isWAbs because confusion in python with overloaded getWeightedAverageValue method - double getWeightedAverageValue(int compId, bool isWAbs) const throw(INTERP_KERNEL::Exception); - double integral(int compId, bool isWAbs) const throw(INTERP_KERNEL::Exception); - double normL1(int compId) const throw(INTERP_KERNEL::Exception); - double normL2(int compId) const throw(INTERP_KERNEL::Exception); - DataArrayInt *getIdsInRange(double vmin, double vmax) const throw(INTERP_KERNEL::Exception); - MEDCouplingFieldDouble *buildSubPartRange(int begin, int end, int step) const throw(INTERP_KERNEL::Exception); - static MEDCouplingFieldDouble *MergeFields(const MEDCouplingFieldDouble *f1, const MEDCouplingFieldDouble *f2) throw(INTERP_KERNEL::Exception); - static MEDCouplingFieldDouble *MeldFields(const MEDCouplingFieldDouble *f1, const MEDCouplingFieldDouble *f2) throw(INTERP_KERNEL::Exception); - static MEDCouplingFieldDouble *DotFields(const MEDCouplingFieldDouble *f1, const MEDCouplingFieldDouble *f2) throw(INTERP_KERNEL::Exception); - MEDCouplingFieldDouble *dot(const MEDCouplingFieldDouble& other) const throw(INTERP_KERNEL::Exception); - static MEDCouplingFieldDouble *CrossProductFields(const MEDCouplingFieldDouble *f1, const MEDCouplingFieldDouble *f2) throw(INTERP_KERNEL::Exception); - MEDCouplingFieldDouble *crossProduct(const MEDCouplingFieldDouble& other) const throw(INTERP_KERNEL::Exception); - static MEDCouplingFieldDouble *MaxFields(const MEDCouplingFieldDouble *f1, const MEDCouplingFieldDouble *f2) throw(INTERP_KERNEL::Exception); - MEDCouplingFieldDouble *max(const MEDCouplingFieldDouble& other) const throw(INTERP_KERNEL::Exception); - static MEDCouplingFieldDouble *MinFields(const MEDCouplingFieldDouble *f1, const MEDCouplingFieldDouble *f2) throw(INTERP_KERNEL::Exception); - static MEDCouplingFieldDouble *AddFields(const MEDCouplingFieldDouble *f1, const MEDCouplingFieldDouble *f2) throw(INTERP_KERNEL::Exception); - static MEDCouplingFieldDouble *SubstractFields(const MEDCouplingFieldDouble *f1, const MEDCouplingFieldDouble *f2) throw(INTERP_KERNEL::Exception); - static MEDCouplingFieldDouble *MultiplyFields(const MEDCouplingFieldDouble *f1, const MEDCouplingFieldDouble *f2) throw(INTERP_KERNEL::Exception); - static MEDCouplingFieldDouble *DivideFields(const MEDCouplingFieldDouble *f1, const MEDCouplingFieldDouble *f2) throw(INTERP_KERNEL::Exception); - MEDCouplingFieldDouble *min(const MEDCouplingFieldDouble& other) const throw(INTERP_KERNEL::Exception); - MEDCouplingFieldDouble *negate() const throw(INTERP_KERNEL::Exception); - %extend { - MEDCouplingFieldDouble(TypeOfField type, TypeOfTimeDiscretization td=ONE_TIME) - { - return MEDCouplingFieldDouble::New(type,td); - } - - MEDCouplingFieldDouble(const MEDCouplingFieldTemplate& ft, TypeOfTimeDiscretization td=ONE_TIME) - { - return MEDCouplingFieldDouble::New(ft,td); - } - - std::string __str__() const throw(INTERP_KERNEL::Exception) - { - return self->simpleRepr(); - } - - std::string __repr__() const throw(INTERP_KERNEL::Exception) - { - std::ostringstream oss; - self->reprQuickOverview(oss); - return oss.str(); - } - - DataArrayDouble *getArray() throw(INTERP_KERNEL::Exception) - { - DataArrayDouble *ret=self->getArray(); - if(ret) - ret->incrRef(); - return ret; - } - - PyObject *getArrays() const throw(INTERP_KERNEL::Exception) - { - std::vector arrs=self->getArrays(); - for(std::vector::iterator it=arrs.begin();it!=arrs.end();it++) - if(*it) - (*it)->incrRef(); - int sz=arrs.size(); - PyObject *ret=PyTuple_New(sz); - for(int i=0;i tmp; - convertFromPyObjVectorOfObj(ls,SWIGTYPE_p_ParaMEDMEM__DataArrayDouble,"DataArrayDouble",tmp); - int sz=tmp.size(); - std::vector arrs(sz); - for(int i=0;i(tmp[i]); - self->setArrays(arrs); - } - - DataArrayDouble *getEndArray() throw(INTERP_KERNEL::Exception) - { - DataArrayDouble *ret=self->getEndArray(); - if(ret) - ret->incrRef(); - return ret; - } - - PyObject *getValueOn(PyObject *sl) const throw(INTERP_KERNEL::Exception) - { - double val; - DataArrayDouble *a; - DataArrayDoubleTuple *aa; - std::vector bb; - int sw; - const MEDCouplingMesh *mesh=self->getMesh(); - if(!mesh) - throw INTERP_KERNEL::Exception("Python wrap of MEDCouplingFieldDouble::getValueOn : no underlying mesh !"); - int spaceDim=mesh->getSpaceDimension(); - const char msg[]="Python wrap of MEDCouplingFieldDouble::getValueOn : "; - const double *spaceLoc=convertObjToPossibleCpp5_Safe(sl,sw,val,a,aa,bb,msg,1,spaceDim,true); - // - int sz=self->getNumberOfComponents(); - INTERP_KERNEL::AutoPtr res=new double[sz]; - self->getValueOn(spaceLoc,res); - return convertDblArrToPyList(res,sz); - } - - PyObject *getValueOnPos(int i, int j, int k) const throw(INTERP_KERNEL::Exception) - { - int sz=self->getNumberOfComponents(); - INTERP_KERNEL::AutoPtr res=new double[sz]; - self->getValueOnPos(i,j,k,res); - return convertDblArrToPyList(res,sz); - } - - DataArrayDouble *getValueOnMulti(PyObject *locs) const throw(INTERP_KERNEL::Exception) - { - const MEDCouplingMesh *mesh(self->getMesh()); - if(!mesh) - throw INTERP_KERNEL::Exception("Python wrap MEDCouplingFieldDouble::getValueOnMulti : lying on a null mesh !"); - // - int sw,nbPts; - double v0; ParaMEDMEM::DataArrayDouble *v1(0); ParaMEDMEM::DataArrayDoubleTuple *v2(0); std::vector v3; - const double *inp=convertObjToPossibleCpp5_Safe2(locs,sw,v0,v1,v2,v3,"wrap of MEDCouplingFieldDouble::getValueOnMulti", - mesh->getSpaceDimension(),true,nbPts); - return self->getValueOnMulti(inp,nbPts); - } - - PyObject *getValueOn(PyObject *sl, double time) const throw(INTERP_KERNEL::Exception) - { - double val; - DataArrayDouble *a; - DataArrayDoubleTuple *aa; - std::vector bb; - int sw; - const MEDCouplingMesh *mesh=self->getMesh(); - if(!mesh) - throw INTERP_KERNEL::Exception("Python wrap of MEDCouplingFieldDouble::getValueOn : no underlying mesh !"); - int spaceDim=mesh->getSpaceDimension(); - const char msg[]="Python wrap of MEDCouplingFieldDouble::getValueOn : "; - const double *spaceLoc=convertObjToPossibleCpp5_Safe(sl,sw,val,a,aa,bb,msg,1,spaceDim,true); - // - // - int sz=self->getNumberOfComponents(); - INTERP_KERNEL::AutoPtr res=new double[sz]; - self->getValueOn(spaceLoc,time,res); - return convertDblArrToPyList(res,sz); - } - - void setValues(PyObject *li, PyObject *nbOfTuples=0, PyObject *nbOfComp=0) throw(INTERP_KERNEL::Exception) - { - if(self->getArray()!=0) - ParaMEDMEM_DataArrayDouble_setValues__SWIG_0(self->getArray(),li,nbOfTuples,nbOfComp); - else - { - MEDCouplingAutoRefCountObjectPtr arr=DataArrayDouble::New(); - ParaMEDMEM_DataArrayDouble_setValues__SWIG_0(arr,li,nbOfTuples,nbOfComp); - self->setArray(arr); - } - } - - PyObject *getTime() throw(INTERP_KERNEL::Exception) - { - int tmp1,tmp2; - double tmp0=self->getTime(tmp1,tmp2); - PyObject *res = PyList_New(3); - PyList_SetItem(res,0,SWIG_From_double(tmp0)); - PyList_SetItem(res,1,SWIG_From_int(tmp1)); - PyList_SetItem(res,2,SWIG_From_int(tmp2)); - return res; - } - - PyObject *getStartTime() throw(INTERP_KERNEL::Exception) - { - int tmp1,tmp2; - double tmp0=self->getStartTime(tmp1,tmp2); - PyObject *res = PyList_New(3); - PyList_SetItem(res,0,SWIG_From_double(tmp0)); - PyList_SetItem(res,1,SWIG_From_int(tmp1)); - PyList_SetItem(res,2,SWIG_From_int(tmp2)); - return res; - } - - PyObject *getEndTime() throw(INTERP_KERNEL::Exception) - { - int tmp1,tmp2; - double tmp0=self->getEndTime(tmp1,tmp2); - PyObject *res = PyList_New(3); - PyList_SetItem(res,0,SWIG_From_double(tmp0)); - PyList_SetItem(res,1,SWIG_From_int(tmp1)); - PyList_SetItem(res,2,SWIG_From_int(tmp2)); - return res; - } - PyObject *accumulate() const throw(INTERP_KERNEL::Exception) - { - int sz=self->getNumberOfComponents(); - INTERP_KERNEL::AutoPtr tmp=new double[sz]; - self->accumulate(tmp); - return convertDblArrToPyList(tmp,sz); - } - PyObject *integral(bool isWAbs) const throw(INTERP_KERNEL::Exception) - { - int sz=self->getNumberOfComponents(); - INTERP_KERNEL::AutoPtr tmp=new double[sz]; - self->integral(isWAbs,tmp); - return convertDblArrToPyList(tmp,sz); - } - PyObject *getWeightedAverageValue(bool isWAbs=true) const throw(INTERP_KERNEL::Exception) - { - int sz=self->getNumberOfComponents(); - INTERP_KERNEL::AutoPtr tmp=new double[sz]; - self->getWeightedAverageValue(tmp,isWAbs); - return convertDblArrToPyList(tmp,sz); - } - PyObject *normL1() const throw(INTERP_KERNEL::Exception) - { - int sz=self->getNumberOfComponents(); - INTERP_KERNEL::AutoPtr tmp=new double[sz]; - self->normL1(tmp); - return convertDblArrToPyList(tmp,sz); - } - PyObject *normL2() const throw(INTERP_KERNEL::Exception) - { - int sz=self->getNumberOfComponents(); - INTERP_KERNEL::AutoPtr tmp=new double[sz]; - self->normL2(tmp); - return convertDblArrToPyList(tmp,sz); - } - void renumberCells(PyObject *li, bool check=true) throw(INTERP_KERNEL::Exception) - { - int szArr,sw,iTypppArr; - std::vector stdvecTyyppArr; - const int *tmp=convertObjToPossibleCpp1_Safe(li,sw,szArr,iTypppArr,stdvecTyyppArr); - self->renumberCells(tmp,check); - } - - void renumberCellsWithoutMesh(PyObject *li, bool check=true) throw(INTERP_KERNEL::Exception) - { - int szArr,sw,iTypppArr; - std::vector stdvecTyyppArr; - const int *tmp=convertObjToPossibleCpp1_Safe(li,sw,szArr,iTypppArr,stdvecTyyppArr); - self->renumberCellsWithoutMesh(tmp,check); - } - - void renumberNodes(PyObject *li, double eps=1e-15) throw(INTERP_KERNEL::Exception) - { - int szArr,sw,iTypppArr; - std::vector stdvecTyyppArr; - const int *tmp=convertObjToPossibleCpp1_Safe(li,sw,szArr,iTypppArr,stdvecTyyppArr); - self->renumberNodes(tmp,eps); - } - - void renumberNodesWithoutMesh(PyObject *li, int newNbOfNodes, double eps=1e-15) throw(INTERP_KERNEL::Exception) - { - int szArr,sw,iTypppArr; - std::vector stdvecTyyppArr; - const int *tmp=convertObjToPossibleCpp1_Safe(li,sw,szArr,iTypppArr,stdvecTyyppArr); - self->renumberNodesWithoutMesh(tmp,newNbOfNodes,eps); - } - - MEDCouplingFieldDouble *buildSubPart(PyObject *li) const throw(INTERP_KERNEL::Exception) - { - int sw; - int singleVal; - std::vector multiVal; - std::pair > slic; - ParaMEDMEM::DataArrayInt *daIntTyypp=0; - const MEDCouplingMesh *mesh=self->getMesh(); - if(!mesh) - throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::buildSubPart : field lies on a null mesh !"); - int nbc=mesh->getNumberOfCells(); - convertObjToPossibleCpp2(li,nbc,sw,singleVal,multiVal,slic,daIntTyypp); - switch(sw) - { - case 1: - { - if(singleVal>=nbc) - { - std::ostringstream oss; - oss << "Requesting for cell id " << singleVal << " having only " << nbc << " cells !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - if(singleVal>=0) - return self->buildSubPart(&singleVal,&singleVal+1); - else - { - if(nbc+singleVal>0) - { - int tmp=nbc+singleVal; - return self->buildSubPart(&tmp,&tmp+1); - } - else - { - std::ostringstream oss; - oss << "Requesting for cell id " << singleVal << " having only " << nbc << " cells !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - } - } - case 2: - { - return self->buildSubPart(&multiVal[0],&multiVal[0]+multiVal.size()); - } - case 3: - { - return self->buildSubPartRange(slic.first,slic.second.first,slic.second.second); - } - case 4: - { - if(!daIntTyypp) - throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::buildSubPart : null instance has been given in input !"); - daIntTyypp->checkAllocated(); - return self->buildSubPart(daIntTyypp->begin(),daIntTyypp->end()); - } - default: - throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::buildSubPart : unrecognized type in input ! Possibilities are : int, list or tuple of int DataArrayInt instance !"); - } - } - - MEDCouplingFieldDouble *__getitem__(PyObject *li) const throw(INTERP_KERNEL::Exception) - { - const char msg[]="MEDCouplingFieldDouble::__getitem__ : invalid call Available API are : \n-myField[dataArrayInt]\n-myField[slice]\n-myField[pythonListOfCellIds]\n-myField[integer]\n-myField[dataArrayInt,1]\n-myField[slice,1]\n-myField[pythonListOfCellIds,1]\n-myField[integer,1]\n"; - if(PyTuple_Check(li)) - { - Py_ssize_t sz=PyTuple_Size(li); - if(sz!=2) - throw INTERP_KERNEL::Exception(msg); - PyObject *elt0=PyTuple_GetItem(li,0),*elt1=PyTuple_GetItem(li,1); - int sw; - int singleVal; - std::vector multiVal; - std::pair > slic; - ParaMEDMEM::DataArrayInt *daIntTyypp=0; - if(!self->getArray()) - throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::__getitem__ : no array set on field to deduce number of components !"); - try - { convertObjToPossibleCpp2(elt1,self->getArray()->getNumberOfComponents(),sw,singleVal,multiVal,slic,daIntTyypp); } - catch(INTERP_KERNEL::Exception& e) - { std::ostringstream oss; oss << "MEDCouplingFieldDouble::__getitem__ : invalid type in 2nd parameter (compo) !" << e.what(); throw INTERP_KERNEL::Exception(oss.str().c_str()); } - MEDCouplingAutoRefCountObjectPtr ret0=ParaMEDMEM_MEDCouplingFieldDouble_buildSubPart(self,elt0); - DataArrayDouble *ret0Arr=ret0->getArray(); - if(!ret0Arr) - throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::__getitem__ : no array exists to apply restriction on component on it !"); - switch(sw) - { - case 1: - { - std::vector v2(1,singleVal); - MEDCouplingAutoRefCountObjectPtr aarr(ret0Arr->keepSelectedComponents(v2)); - ret0->setArray(aarr); - return ret0.retn(); - } - case 2: - { - MEDCouplingAutoRefCountObjectPtr aarr(ret0Arr->keepSelectedComponents(multiVal)); - ret0->setArray(aarr); - return ret0.retn(); - } - case 3: - { - int nbOfComp=DataArray::GetNumberOfItemGivenBESRelative(slic.first,slic.second.first,slic.second.second,"MEDCouplingFieldDouble::__getitem__ : invalid range in 2nd parameter (components) !"); - std::vector v2(nbOfComp); - for(int i=0;i aarr(ret0Arr->keepSelectedComponents(v2)); - ret0->setArray(aarr); - return ret0.retn(); - } - default: - throw INTERP_KERNEL::Exception(msg); - } - - } - else - return ParaMEDMEM_MEDCouplingFieldDouble_buildSubPart(self,li); - } - - PyObject *getMaxValue2() const throw(INTERP_KERNEL::Exception) - { - DataArrayInt *tmp; - double r1=self->getMaxValue2(tmp); - PyObject *ret=PyTuple_New(2); - PyTuple_SetItem(ret,0,PyFloat_FromDouble(r1)); - PyTuple_SetItem(ret,1,SWIG_NewPointerObj(SWIG_as_voidptr(tmp),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 )); - return ret; - } - - PyObject *getMinValue2() const throw(INTERP_KERNEL::Exception) - { - DataArrayInt *tmp; - double r1=self->getMinValue2(tmp); - PyObject *ret=PyTuple_New(2); - PyTuple_SetItem(ret,0,PyFloat_FromDouble(r1)); - PyTuple_SetItem(ret,1,SWIG_NewPointerObj(SWIG_as_voidptr(tmp),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 )); - return ret; - } - - MEDCouplingFieldDouble *keepSelectedComponents(PyObject *li) const throw(INTERP_KERNEL::Exception) - { - std::vector tmp; - convertPyToNewIntArr3(li,tmp); - return self->keepSelectedComponents(tmp); - } - - void setSelectedComponents(const MEDCouplingFieldDouble *f, PyObject *li) throw(INTERP_KERNEL::Exception) - { - std::vector tmp; - convertPyToNewIntArr3(li,tmp); - self->setSelectedComponents(f,tmp); - } - - MEDCouplingFieldDouble *extractSlice3D(PyObject *origin, PyObject *vec, double eps) const throw(INTERP_KERNEL::Exception) - { - double val,val2; - DataArrayDouble *a,*a2; - DataArrayDoubleTuple *aa,*aa2; - std::vector bb,bb2; - int sw; - int spaceDim=3; - const char msg[]="Python wrap of MEDCouplingFieldDouble::extractSlice3D : 1st paramater for origin."; - const char msg2[]="Python wrap of MEDCouplingFieldDouble::extractSlice3D : 2nd paramater for vector."; - const double *orig=convertObjToPossibleCpp5_Safe(origin,sw,val,a,aa,bb,msg,1,spaceDim,true); - const double *vect=convertObjToPossibleCpp5_Safe(vec,sw,val2,a2,aa2,bb2,msg2,1,spaceDim,true); - // - return self->extractSlice3D(orig,vect,eps); - } - - MEDCouplingFieldDouble *__add__(PyObject *obj) throw(INTERP_KERNEL::Exception) - { - return ParaMEDMEM_MEDCouplingFieldDouble___add__Impl(self,obj); - } - - MEDCouplingFieldDouble *__radd__(PyObject *obj) throw(INTERP_KERNEL::Exception) - { - return ParaMEDMEM_MEDCouplingFieldDouble___radd__Impl(self,obj); - } - - MEDCouplingFieldDouble *__sub__(PyObject *obj) throw(INTERP_KERNEL::Exception) - { - const char msg[]="Unexpected situation in MEDCouplingFieldDouble.__sub__ ! Expecting a not null MEDCouplingFieldDouble or DataArrayDouble or DataArrayDoubleTuple instance, or a list of double, or a double."; - const char msg2[]="in MEDCouplingFieldDouble.__sub__ : self field has no Array of values set !"; - void *argp; - // - if(SWIG_IsOK(SWIG_ConvertPtr(obj,&argp,SWIGTYPE_p_ParaMEDMEM__MEDCouplingFieldDouble,0|0))) - { - MEDCouplingFieldDouble *other=reinterpret_cast< ParaMEDMEM::MEDCouplingFieldDouble * >(argp); - if(other) - return (*self)-(*other); - else - throw INTERP_KERNEL::Exception(msg); - } - // - double val; - DataArrayDouble *a; - DataArrayDoubleTuple *aa; - std::vector bb; - int sw; - convertObjToPossibleCpp5(obj,sw,val,a,aa,bb); - switch(sw) - { - case 1: - { - if(!self->getArray()) - throw INTERP_KERNEL::Exception(msg2); - MEDCouplingAutoRefCountObjectPtr ret=self->getArray()->deepCpy(); - ret->applyLin(1.,-val); - MEDCouplingAutoRefCountObjectPtr ret2=self->clone(false); - ret2->setArray(ret); - return ret2.retn(); - } - case 2: - { - if(!self->getArray()) - throw INTERP_KERNEL::Exception(msg2); - MEDCouplingAutoRefCountObjectPtr ret=DataArrayDouble::Substract(self->getArray(),a); - MEDCouplingAutoRefCountObjectPtr ret2=self->clone(false); - ret2->setArray(ret); - return ret2.retn(); - } - case 3: - { - if(!self->getArray()) - throw INTERP_KERNEL::Exception(msg2); - MEDCouplingAutoRefCountObjectPtr aaa=aa->buildDADouble(1,self->getNumberOfComponents()); - MEDCouplingAutoRefCountObjectPtr ret=DataArrayDouble::Substract(self->getArray(),aaa); - MEDCouplingAutoRefCountObjectPtr ret2=self->clone(false); - ret2->setArray(ret); - return ret2.retn(); - } - case 4: - { - if(!self->getArray()) - throw INTERP_KERNEL::Exception(msg2); - MEDCouplingAutoRefCountObjectPtr aaa=DataArrayDouble::New(); aaa->useArray(&bb[0],false,CPP_DEALLOC,1,(int)bb.size()); - MEDCouplingAutoRefCountObjectPtr ret=DataArrayDouble::Substract(self->getArray(),aaa); - MEDCouplingAutoRefCountObjectPtr ret2=self->clone(false); - ret2->setArray(ret); - return ret2.retn(); - } - default: - { throw INTERP_KERNEL::Exception(msg); } - } - } - - MEDCouplingFieldDouble *__rsub__(PyObject *obj) throw(INTERP_KERNEL::Exception) - { - return ParaMEDMEM_MEDCouplingFieldDouble___rsub__Impl(self,obj); - } - - MEDCouplingFieldDouble *__mul__(PyObject *obj) throw(INTERP_KERNEL::Exception) - { - return ParaMEDMEM_MEDCouplingFieldDouble___mul__Impl(self,obj); - } - - MEDCouplingFieldDouble *__rmul__(PyObject *obj) throw(INTERP_KERNEL::Exception) - { - return ParaMEDMEM_MEDCouplingFieldDouble___rmul__Impl(self,obj); - } - - MEDCouplingFieldDouble *__div__(PyObject *obj) throw(INTERP_KERNEL::Exception) - { - const char msg[]="Unexpected situation in MEDCouplingFieldDouble.__div__ ! Expecting a not null MEDCouplingFieldDouble or DataArrayDouble or DataArrayDoubleTuple instance, or a list of double, or a double."; - const char msg2[]="in MEDCouplingFieldDouble.__div__ : self field has no Array of values set !"; - void *argp; - // - if(SWIG_IsOK(SWIG_ConvertPtr(obj,&argp,SWIGTYPE_p_ParaMEDMEM__MEDCouplingFieldDouble,0|0))) - { - MEDCouplingFieldDouble *other=reinterpret_cast< ParaMEDMEM::MEDCouplingFieldDouble * >(argp); - if(other) - return (*self)/(*other); - else - throw INTERP_KERNEL::Exception(msg); - } - // - double val; - DataArrayDouble *a; - DataArrayDoubleTuple *aa; - std::vector bb; - int sw; - convertObjToPossibleCpp5(obj,sw,val,a,aa,bb); - switch(sw) - { - case 1: - { - if(val==0.) - throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble.__div__ : trying to divide by zero !"); - if(!self->getArray()) - throw INTERP_KERNEL::Exception(msg2); - MEDCouplingAutoRefCountObjectPtr ret=self->getArray()->deepCpy(); - ret->applyLin(1./val,0); - MEDCouplingAutoRefCountObjectPtr ret2=self->clone(false); - ret2->setArray(ret); - return ret2.retn(); - } - case 2: - { - if(!self->getArray()) - throw INTERP_KERNEL::Exception(msg2); - MEDCouplingAutoRefCountObjectPtr ret=DataArrayDouble::Divide(self->getArray(),a); - MEDCouplingAutoRefCountObjectPtr ret2=self->clone(false); - ret2->setArray(ret); - return ret2.retn(); - } - case 3: - { - if(!self->getArray()) - throw INTERP_KERNEL::Exception(msg2); - MEDCouplingAutoRefCountObjectPtr aaa=aa->buildDADouble(1,self->getNumberOfComponents()); - MEDCouplingAutoRefCountObjectPtr ret=DataArrayDouble::Divide(self->getArray(),aaa); - MEDCouplingAutoRefCountObjectPtr ret2=self->clone(false); - ret2->setArray(ret); - return ret2.retn(); - } - case 4: - { - if(!self->getArray()) - throw INTERP_KERNEL::Exception(msg2); - MEDCouplingAutoRefCountObjectPtr aaa=DataArrayDouble::New(); aaa->useArray(&bb[0],false,CPP_DEALLOC,1,(int)bb.size()); - MEDCouplingAutoRefCountObjectPtr ret=DataArrayDouble::Divide(self->getArray(),aaa); - MEDCouplingAutoRefCountObjectPtr ret2=self->clone(false); - ret2->setArray(ret); - return ret2.retn(); - } - default: - { throw INTERP_KERNEL::Exception(msg); } - } - } - - MEDCouplingFieldDouble *__rdiv__(PyObject *obj) throw(INTERP_KERNEL::Exception) - { - return ParaMEDMEM_MEDCouplingFieldDouble___rdiv__Impl(self,obj); - } - - MEDCouplingFieldDouble *__pow__(PyObject *obj) throw(INTERP_KERNEL::Exception) - { - const char msg[]="Unexpected situation in MEDCouplingFieldDouble.__pow__ ! Expecting a not null MEDCouplingFieldDouble or DataArrayDouble or DataArrayDoubleTuple instance, or a list of double, or a double."; - const char msg2[]="in MEDCouplingFieldDouble.__pow__ : self field has no Array of values set !"; - void *argp; - // - if(SWIG_IsOK(SWIG_ConvertPtr(obj,&argp,SWIGTYPE_p_ParaMEDMEM__MEDCouplingFieldDouble,0|0))) - { - MEDCouplingFieldDouble *other=reinterpret_cast< ParaMEDMEM::MEDCouplingFieldDouble * >(argp); - if(other) - return (*self)^(*other); - else - throw INTERP_KERNEL::Exception(msg); - } - // - double val; - DataArrayDouble *a; - DataArrayDoubleTuple *aa; - std::vector bb; - int sw; - convertObjToPossibleCpp5(obj,sw,val,a,aa,bb); - switch(sw) - { - case 1: - { - if(!self->getArray()) - throw INTERP_KERNEL::Exception(msg2); - MEDCouplingAutoRefCountObjectPtr ret=self->getArray()->deepCpy(); - ret->applyPow(val); - MEDCouplingAutoRefCountObjectPtr ret2=self->clone(false); - ret2->setArray(ret); - return ret2.retn(); - } - case 2: - { - if(!self->getArray()) - throw INTERP_KERNEL::Exception(msg2); - MEDCouplingAutoRefCountObjectPtr ret=DataArrayDouble::Pow(self->getArray(),a); - MEDCouplingAutoRefCountObjectPtr ret2=self->clone(false); - ret2->setArray(ret); - return ret2.retn(); - } - case 3: - { - if(!self->getArray()) - throw INTERP_KERNEL::Exception(msg2); - MEDCouplingAutoRefCountObjectPtr aaa=aa->buildDADouble(1,self->getNumberOfComponents()); - MEDCouplingAutoRefCountObjectPtr ret=DataArrayDouble::Pow(self->getArray(),aaa); - MEDCouplingAutoRefCountObjectPtr ret2=self->clone(false); - ret2->setArray(ret); - return ret2.retn(); - } - case 4: - { - if(!self->getArray()) - throw INTERP_KERNEL::Exception(msg2); - MEDCouplingAutoRefCountObjectPtr aaa=DataArrayDouble::New(); aaa->useArray(&bb[0],false,CPP_DEALLOC,1,(int)bb.size()); - MEDCouplingAutoRefCountObjectPtr ret=DataArrayDouble::Pow(self->getArray(),aaa); - MEDCouplingAutoRefCountObjectPtr ret2=self->clone(false); - ret2->setArray(ret); - return ret2.retn(); - } - default: - { throw INTERP_KERNEL::Exception(msg); } - } - } - - MEDCouplingFieldDouble *__neg__() const throw(INTERP_KERNEL::Exception) - { - return self->negate(); - } - - PyObject *___iadd___(PyObject *trueSelf, PyObject *obj) throw(INTERP_KERNEL::Exception) - { - const char msg[]="Unexpected situation in MEDCouplingFieldDouble.__iadd__ ! Expecting a not null MEDCouplingFieldDouble or DataArrayDouble or DataArrayDoubleTuple instance, or a list of double, or a double."; - const char msg2[]="in MEDCouplingFieldDouble.__iadd__ : self field has no Array of values set !"; - void *argp; - // - if(SWIG_IsOK(SWIG_ConvertPtr(obj,&argp,SWIGTYPE_p_ParaMEDMEM__MEDCouplingFieldDouble,0|0))) - { - MEDCouplingFieldDouble *other=reinterpret_cast< ParaMEDMEM::MEDCouplingFieldDouble * >(argp); - if(other) - { - *self+=*other; - Py_XINCREF(trueSelf); - return trueSelf; - } - else - throw INTERP_KERNEL::Exception(msg); - } - // - double val; - DataArrayDouble *a; - DataArrayDoubleTuple *aa; - std::vector bb; - int sw; - convertObjToPossibleCpp5(obj,sw,val,a,aa,bb); - switch(sw) - { - case 1: - { - if(!self->getArray()) - throw INTERP_KERNEL::Exception(msg2); - self->getArray()->applyLin(1.,val); - Py_XINCREF(trueSelf); - return trueSelf; - } - case 2: - { - MEDCouplingAutoRefCountObjectPtr ret2=self->clone(false); - ret2->setArray(a); - *self+=*ret2; - Py_XINCREF(trueSelf); - return trueSelf; - } - case 3: - { - MEDCouplingAutoRefCountObjectPtr aaa=aa->buildDADouble(1,self->getNumberOfComponents()); - MEDCouplingAutoRefCountObjectPtr ret2=self->clone(false); - ret2->setArray(aaa); - *self+=*ret2; - Py_XINCREF(trueSelf); - return trueSelf; - } - case 4: - { - if(!self->getArray()) - throw INTERP_KERNEL::Exception(msg2); - MEDCouplingAutoRefCountObjectPtr aaa=DataArrayDouble::New(); aaa->useArray(&bb[0],false,CPP_DEALLOC,1,(int)bb.size()); - self->getArray()->addEqual(aaa); - Py_XINCREF(trueSelf); - return trueSelf; - } - default: - { throw INTERP_KERNEL::Exception(msg); } - } - } - - PyObject *___isub___(PyObject *trueSelf, PyObject *obj) throw(INTERP_KERNEL::Exception) - { - const char msg[]="Unexpected situation in MEDCouplingFieldDouble.__isub__ ! Expecting a not null MEDCouplingFieldDouble or DataArrayDouble or DataArrayDoubleTuple instance, or a list of double, or a double."; - const char msg2[]="in MEDCouplingFieldDouble.__isub__ : self field has no Array of values set !"; - void *argp; - // - if(SWIG_IsOK(SWIG_ConvertPtr(obj,&argp,SWIGTYPE_p_ParaMEDMEM__MEDCouplingFieldDouble,0|0))) - { - MEDCouplingFieldDouble *other=reinterpret_cast< ParaMEDMEM::MEDCouplingFieldDouble * >(argp); - if(other) - { - *self-=*other; - Py_XINCREF(trueSelf); - return trueSelf; - } - else - throw INTERP_KERNEL::Exception(msg); - } - // - double val; - DataArrayDouble *a; - DataArrayDoubleTuple *aa; - std::vector bb; - int sw; - convertObjToPossibleCpp5(obj,sw,val,a,aa,bb); - switch(sw) - { - case 1: - { - if(!self->getArray()) - throw INTERP_KERNEL::Exception(msg2); - self->getArray()->applyLin(1.,-val); - Py_XINCREF(trueSelf); - return trueSelf; - } - case 2: - { - MEDCouplingAutoRefCountObjectPtr ret2=self->clone(false); - ret2->setArray(a); - *self-=*ret2; - Py_XINCREF(trueSelf); - return trueSelf; - } - case 3: - { - MEDCouplingAutoRefCountObjectPtr aaa=aa->buildDADouble(1,self->getNumberOfComponents()); - MEDCouplingAutoRefCountObjectPtr ret2=self->clone(false); - ret2->setArray(aaa); - *self-=*ret2; - Py_XINCREF(trueSelf); - return trueSelf; - } - case 4: - { - if(!self->getArray()) - throw INTERP_KERNEL::Exception(msg2); - MEDCouplingAutoRefCountObjectPtr aaa=DataArrayDouble::New(); aaa->useArray(&bb[0],false,CPP_DEALLOC,1,(int)bb.size()); - self->getArray()->substractEqual(aaa); - Py_XINCREF(trueSelf); - return trueSelf; - } - default: - { throw INTERP_KERNEL::Exception(msg); } - } - } - - PyObject *___imul___(PyObject *trueSelf, PyObject *obj) throw(INTERP_KERNEL::Exception) - { - const char msg[]="Unexpected situation in MEDCouplingFieldDouble.__imul__ ! Expecting a not null MEDCouplingFieldDouble or DataArrayDouble or DataArrayDoubleTuple instance, or a list of double, or a double."; - const char msg2[]="in MEDCouplingFieldDouble.__imul__ : self field has no Array of values set !"; - void *argp; - // - if(SWIG_IsOK(SWIG_ConvertPtr(obj,&argp,SWIGTYPE_p_ParaMEDMEM__MEDCouplingFieldDouble,0|0))) - { - MEDCouplingFieldDouble *other=reinterpret_cast< ParaMEDMEM::MEDCouplingFieldDouble * >(argp); - if(other) - { - *self*=*other; - Py_XINCREF(trueSelf); - return trueSelf; - } - else - throw INTERP_KERNEL::Exception(msg); - } - // - double val; - DataArrayDouble *a; - DataArrayDoubleTuple *aa; - std::vector bb; - int sw; - convertObjToPossibleCpp5(obj,sw,val,a,aa,bb); - switch(sw) - { - case 1: - { - if(!self->getArray()) - throw INTERP_KERNEL::Exception(msg2); - self->getArray()->applyLin(val,0); - Py_XINCREF(trueSelf); - return trueSelf; - } - case 2: - { - MEDCouplingAutoRefCountObjectPtr ret2=self->clone(false); - ret2->setArray(a); - *self*=*ret2; - Py_XINCREF(trueSelf); - return trueSelf; - } - case 3: - { - MEDCouplingAutoRefCountObjectPtr aaa=aa->buildDADouble(1,self->getNumberOfComponents()); - MEDCouplingAutoRefCountObjectPtr ret2=self->clone(false); - ret2->setArray(aaa); - *self*=*ret2; - Py_XINCREF(trueSelf); - return trueSelf; - } - case 4: - { - if(!self->getArray()) - throw INTERP_KERNEL::Exception(msg2); - MEDCouplingAutoRefCountObjectPtr aaa=DataArrayDouble::New(); aaa->useArray(&bb[0],false,CPP_DEALLOC,1,(int)bb.size()); - self->getArray()->multiplyEqual(aaa); - Py_XINCREF(trueSelf); - return trueSelf; - } - default: - { throw INTERP_KERNEL::Exception(msg); } - } - } - - PyObject *___idiv___(PyObject *trueSelf, PyObject *obj) throw(INTERP_KERNEL::Exception) - { - const char msg[]="Unexpected situation in MEDCouplingFieldDouble.__idiv__ ! Expecting a not null MEDCouplingFieldDouble or DataArrayDouble or DataArrayDoubleTuple instance, or a list of double, or a double."; - const char msg2[]="in MEDCouplingFieldDouble.__idiv__ : self field has no Array of values set !"; - void *argp; - // - if(SWIG_IsOK(SWIG_ConvertPtr(obj,&argp,SWIGTYPE_p_ParaMEDMEM__MEDCouplingFieldDouble,0|0))) - { - MEDCouplingFieldDouble *other=reinterpret_cast< ParaMEDMEM::MEDCouplingFieldDouble * >(argp); - if(other) - { - *self/=*other; - Py_XINCREF(trueSelf); - return trueSelf; - } - else - throw INTERP_KERNEL::Exception(msg); - } - // - double val; - DataArrayDouble *a; - DataArrayDoubleTuple *aa; - std::vector bb; - int sw; - convertObjToPossibleCpp5(obj,sw,val,a,aa,bb); - switch(sw) - { - case 1: - { - if(val==0.) - throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble.__idiv__ : trying to divide by zero !"); - if(!self->getArray()) - throw INTERP_KERNEL::Exception(msg2); - self->getArray()->applyLin(1./val,0); - Py_XINCREF(trueSelf); - return trueSelf; - } - case 2: - { - MEDCouplingAutoRefCountObjectPtr ret2=self->clone(false); - ret2->setArray(a); - *self/=*ret2; - Py_XINCREF(trueSelf); - return trueSelf; - } - case 3: - { - MEDCouplingAutoRefCountObjectPtr aaa=aa->buildDADouble(1,self->getNumberOfComponents()); - MEDCouplingAutoRefCountObjectPtr ret2=self->clone(false); - ret2->setArray(aaa); - *self/=*ret2; - Py_XINCREF(trueSelf); - return trueSelf; - } - case 4: - { - if(!self->getArray()) - throw INTERP_KERNEL::Exception(msg2); - MEDCouplingAutoRefCountObjectPtr aaa=DataArrayDouble::New(); aaa->useArray(&bb[0],false,CPP_DEALLOC,1,(int)bb.size()); - self->getArray()->divideEqual(aaa); - Py_XINCREF(trueSelf); - return trueSelf; - } - default: - { throw INTERP_KERNEL::Exception(msg); } - } - } - - PyObject *___ipow___(PyObject *trueSelf, PyObject *obj) throw(INTERP_KERNEL::Exception) - { - const char msg[]="Unexpected situation in MEDCouplingFieldDouble.__ipow__ ! Expecting a not null MEDCouplingFieldDouble or DataArrayDouble or DataArrayDoubleTuple instance, or a list of double, or a double."; - const char msg2[]="in MEDCouplingFieldDouble.__ipow__ : self field has no Array of values set !"; - void *argp; - // - if(SWIG_IsOK(SWIG_ConvertPtr(obj,&argp,SWIGTYPE_p_ParaMEDMEM__MEDCouplingFieldDouble,0|0))) - { - MEDCouplingFieldDouble *other=reinterpret_cast< ParaMEDMEM::MEDCouplingFieldDouble * >(argp); - if(other) - { - *self^=*other; - Py_XINCREF(trueSelf); - return trueSelf; - } - else - throw INTERP_KERNEL::Exception(msg); - } - // - double val; - DataArrayDouble *a; - DataArrayDoubleTuple *aa; - std::vector bb; - int sw; - convertObjToPossibleCpp5(obj,sw,val,a,aa,bb); - switch(sw) - { - case 1: - { - if(!self->getArray()) - throw INTERP_KERNEL::Exception(msg2); - self->getArray()->applyPow(val); - Py_XINCREF(trueSelf); - return trueSelf; - } - case 2: - { - MEDCouplingAutoRefCountObjectPtr ret2=self->clone(false); - ret2->setArray(a); - *self^=*ret2; - Py_XINCREF(trueSelf); - return trueSelf; - } - case 3: - { - MEDCouplingAutoRefCountObjectPtr aaa=aa->buildDADouble(1,self->getNumberOfComponents()); - MEDCouplingAutoRefCountObjectPtr ret2=self->clone(false); - ret2->setArray(aaa); - *self^=*ret2; - Py_XINCREF(trueSelf); - return trueSelf; - } - case 4: - { - if(!self->getArray()) - throw INTERP_KERNEL::Exception(msg2); - MEDCouplingAutoRefCountObjectPtr aaa=DataArrayDouble::New(); aaa->useArray(&bb[0],false,CPP_DEALLOC,1,(int)bb.size()); - self->getArray()->powEqual(aaa); - Py_XINCREF(trueSelf); - return trueSelf; - } - default: - { throw INTERP_KERNEL::Exception(msg); } - } - } - - static MEDCouplingFieldDouble *MergeFields(PyObject *li) throw(INTERP_KERNEL::Exception) - { - std::vector tmp; - convertFromPyObjVectorOfObj(li,SWIGTYPE_p_ParaMEDMEM__MEDCouplingFieldDouble,"MEDCouplingFieldDouble",tmp); - return MEDCouplingFieldDouble::MergeFields(tmp); - } - - static std::string WriteVTK(const char *fileName, PyObject *li, bool isBinary=true) throw(INTERP_KERNEL::Exception) - { - std::vector tmp; - convertFromPyObjVectorOfObj(li,SWIGTYPE_p_ParaMEDMEM__MEDCouplingFieldDouble,"MEDCouplingFieldDouble",tmp); - return MEDCouplingFieldDouble::WriteVTK(fileName,tmp,isBinary); - } - - PyObject *getTinySerializationInformation() const throw(INTERP_KERNEL::Exception) - { - std::vector a0; - std::vector a1; - std::vector a2; - self->getTinySerializationDbleInformation(a0); - self->getTinySerializationIntInformation(a1); - self->getTinySerializationStrInformation(a2); - // - PyObject *ret(PyTuple_New(3)); - PyTuple_SetItem(ret,0,convertDblArrToPyList2(a0)); - PyTuple_SetItem(ret,1,convertIntArrToPyList2(a1)); - int sz(a2.size()); - PyObject *ret2(PyList_New(sz)); - { - for(int i=0;i ret1; - self->serialize(ret0,ret1); - if(ret0) - ret0->incrRef(); - std::size_t sz(ret1.size()); - PyObject *ret(PyTuple_New(2)); - PyTuple_SetItem(ret,0,SWIG_NewPointerObj(SWIG_as_voidptr(ret0),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 )); - PyObject *ret1Py(PyList_New(sz)); - for(std::size_t i=0;iincrRef(); - PyList_SetItem(ret1Py,i,SWIG_NewPointerObj(SWIG_as_voidptr(ret1[i]),SWIGTYPE_p_ParaMEDMEM__DataArrayDouble, SWIG_POINTER_OWN | 0 )); - } - PyTuple_SetItem(ret,1,ret1Py); - return ret; - } - - static PyObject *___new___(PyObject *cls, PyObject *args) throw(INTERP_KERNEL::Exception) - { - static const char MSG[]="MEDCouplingFieldDouble.__new__ : the args in input is expected to be a tuple !"; - if(!PyTuple_Check(args)) - throw INTERP_KERNEL::Exception(MSG); - PyObject *builtinsd(PyEval_GetBuiltins());//borrowed - PyObject *obj(PyDict_GetItemString(builtinsd,"object"));//borrowed - PyObject *selfMeth(PyObject_GetAttrString(obj,"__new__")); - // - PyObject *tmp0(PyTuple_New(1)); - PyTuple_SetItem(tmp0,0,cls); Py_XINCREF(cls); - PyObject *instance(PyObject_CallObject(selfMeth,tmp0)); - Py_DECREF(tmp0); - Py_DECREF(selfMeth); - if(PyTuple_Size(args)==2 && PyDict_Check(PyTuple_GetItem(args,1)) && PyDict_Size(PyTuple_GetItem(args,1))==1 ) - {// NOT general case. only true if in unpickeling context ! call __init__. Because for all other cases, __init__ is called right after __new__ ! - PyObject *initMeth(PyObject_GetAttrString(instance,"__init__")); - //// - PyObject *a(PyInt_FromLong(0)); - PyObject *uniqueElt(PyDict_GetItem(PyTuple_GetItem(args,1),a)); - Py_DECREF(a); - if(!uniqueElt) - throw INTERP_KERNEL::Exception(MSG); - if(!PyTuple_Check(uniqueElt) || PyTuple_Size(uniqueElt)!=2) - throw INTERP_KERNEL::Exception(MSG); - PyObject *tmp2(PyObject_CallObject(initMeth,uniqueElt)); - Py_XDECREF(tmp2); - //// - Py_DECREF(initMeth); - } - return instance; - } - - PyObject *__getnewargs__() throw(INTERP_KERNEL::Exception) - {// put an empty dict in input to say to __new__ to call __init__... - self->checkCoherency(); - PyObject *ret(PyTuple_New(1)); - PyObject *ret0(PyDict_New()); - { - PyObject *a(PyInt_FromLong(0)),*b(PyInt_FromLong(self->getTypeOfField())),*c(PyInt_FromLong(self->getTimeDiscretization())); - PyObject *d(PyTuple_New(2)); PyTuple_SetItem(d,0,b); PyTuple_SetItem(d,1,c); - PyDict_SetItem(ret0,a,d); - Py_DECREF(a); Py_DECREF(d); - } - PyTuple_SetItem(ret,0,ret0); - return ret; - } - - PyObject *__getstate__() const throw(INTERP_KERNEL::Exception) - { - self->checkCoherency(); - PyObject *ret0(ParaMEDMEM_MEDCouplingFieldDouble_getTinySerializationInformation(self)); - PyObject *ret1(ParaMEDMEM_MEDCouplingFieldDouble_serialize(self)); - const MEDCouplingMesh *mesh(self->getMesh()); - if(mesh) - mesh->incrRef(); - PyObject *ret(PyTuple_New(3)); - PyTuple_SetItem(ret,0,ret0); - PyTuple_SetItem(ret,1,ret1); - PyTuple_SetItem(ret,2,convertMesh(const_cast(mesh),SWIG_POINTER_OWN | 0 )); - return ret; - } - - void __setstate__(PyObject *inp) throw(INTERP_KERNEL::Exception) - { - static const char MSG[]="MEDCouplingFieldDouble.__setstate__ : expected input is a tuple of size 3 !"; - if(!PyTuple_Check(inp)) - throw INTERP_KERNEL::Exception(MSG); - int sz(PyTuple_Size(inp)); - if(sz!=3) - throw INTERP_KERNEL::Exception(MSG); - // mesh - PyObject *elt2(PyTuple_GetItem(inp,2)); - void *argp=0; - int status(SWIG_ConvertPtr(elt2,&argp,SWIGTYPE_p_ParaMEDMEM__MEDCouplingMesh,0|0)); - if(!SWIG_IsOK(status)) - throw INTERP_KERNEL::Exception(MSG); - self->setMesh(reinterpret_cast< const MEDCouplingUMesh * >(argp)); - // - PyObject *elt0(PyTuple_GetItem(inp,0)); - PyObject *elt1(PyTuple_GetItem(inp,1)); - std::vector a0; - std::vector a1; - std::vector a2; - DataArrayInt *b0(0); - std::vectorb1; - { - if(!PyTuple_Check(elt0) && PyTuple_Size(elt0)!=3) - throw INTERP_KERNEL::Exception(MSG); - PyObject *a0py(PyTuple_GetItem(elt0,0)),*a1py(PyTuple_GetItem(elt0,1)),*a2py(PyTuple_GetItem(elt0,2)); - int tmp(-1); - fillArrayWithPyListDbl3(a0py,tmp,a0); - convertPyToNewIntArr3(a1py,a1); - fillStringVector(a2py,a2); - } - { - if(!PyTuple_Check(elt1) && PyTuple_Size(elt1)!=2) - throw INTERP_KERNEL::Exception(MSG); - PyObject *b0py(PyTuple_GetItem(elt1,0)),*b1py(PyTuple_GetItem(elt1,1)); - void *argp(0); - int status(SWIG_ConvertPtr(b0py,&argp,SWIGTYPE_p_ParaMEDMEM__DataArrayInt,0|0)); - if(!SWIG_IsOK(status)) - throw INTERP_KERNEL::Exception(MSG); - b0=reinterpret_cast(argp); - convertFromPyObjVectorOfObj(b1py,SWIGTYPE_p_ParaMEDMEM__DataArrayDouble,"DataArrayDouble",b1); - } - self->checkForUnserialization(a1,b0,b1); - // useless here to call resizeForUnserialization because arrays are well resized. - self->finishUnserialization(a1,a0,a2); - } - } - }; - - class MEDCouplingMultiFields : public RefCountObject, public TimeLabel - { - public: - int getNumberOfFields() const; - MEDCouplingMultiFields *deepCpy() const; - virtual std::string simpleRepr() const throw(INTERP_KERNEL::Exception); - virtual std::string advancedRepr() const throw(INTERP_KERNEL::Exception); - virtual bool isEqual(const MEDCouplingMultiFields *other, double meshPrec, double valsPrec) const; - virtual bool isEqualWithoutConsideringStr(const MEDCouplingMultiFields *other, double meshPrec, double valsPrec) const; - virtual void checkCoherency() const throw(INTERP_KERNEL::Exception); - %extend - { - std::string __str__() const throw(INTERP_KERNEL::Exception) - { - return self->simpleRepr(); - } - static MEDCouplingMultiFields *New(PyObject *li) throw(INTERP_KERNEL::Exception) - { - std::vector tmp; - convertFromPyObjVectorOfObj(li,SWIGTYPE_p_ParaMEDMEM__MEDCouplingFieldDouble,"MEDCouplingFieldDouble",tmp); - int sz=tmp.size(); - std::vector fs(sz); - for(int i=0;i(tmp[i]); - return MEDCouplingMultiFields::New(fs); - } - MEDCouplingMultiFields(PyObject *li) throw(INTERP_KERNEL::Exception) - { - std::vector tmp; - convertFromPyObjVectorOfObj(li,SWIGTYPE_p_ParaMEDMEM__MEDCouplingFieldDouble,"MEDCouplingFieldDouble",tmp); - int sz=tmp.size(); - std::vector fs(sz); - for(int i=0;i(tmp[i]); - return MEDCouplingMultiFields::New(fs); - } - PyObject *getFields() const - { - std::vector fields=self->getFields(); - int sz=fields.size(); - PyObject *res = PyList_New(sz); - for(int i=0;iincrRef(); - PyList_SetItem(res,i,SWIG_NewPointerObj(SWIG_as_voidptr(fields[i]),SWIGTYPE_p_ParaMEDMEM__MEDCouplingFieldDouble, SWIG_POINTER_OWN | 0 )); - } - else - { - PyList_SetItem(res,i,SWIG_NewPointerObj(SWIG_as_voidptr(0),SWIGTYPE_p_ParaMEDMEM__MEDCouplingFieldDouble, 0 )); - } - } - return res; - } - PyObject *getFieldAtPos(int id) const throw(INTERP_KERNEL::Exception) - { - const MEDCouplingFieldDouble *ret=self->getFieldAtPos(id); - if(ret) - { - ret->incrRef(); - return SWIG_NewPointerObj(SWIG_as_voidptr(ret),SWIGTYPE_p_ParaMEDMEM__MEDCouplingFieldDouble, SWIG_POINTER_OWN | 0 ); - } - else - return SWIG_NewPointerObj(SWIG_as_voidptr(0),SWIGTYPE_p_ParaMEDMEM__MEDCouplingFieldDouble, 0 ); - } - PyObject *getMeshes() const throw(INTERP_KERNEL::Exception) - { - std::vector ms=self->getMeshes(); - int sz=ms.size(); - PyObject *res = PyList_New(sz); - for(int i=0;iincrRef(); - PyList_SetItem(res,i,convertMesh(ms[i], SWIG_POINTER_OWN | 0 )); - } - else - { - PyList_SetItem(res,i,SWIG_NewPointerObj(SWIG_as_voidptr(0),SWIGTYPE_p_ParaMEDMEM__MEDCouplingUMesh, 0 )); - } - } - return res; - } - PyObject *getDifferentMeshes() const throw(INTERP_KERNEL::Exception) - { - std::vector refs; - std::vector ms=self->getDifferentMeshes(refs); - int sz=ms.size(); - PyObject *res = PyList_New(sz); - for(int i=0;iincrRef(); - PyList_SetItem(res,i,convertMesh(ms[i], SWIG_POINTER_OWN | 0 )); - } - else - { - PyList_SetItem(res,i,SWIG_NewPointerObj(SWIG_as_voidptr(0),SWIGTYPE_p_ParaMEDMEM__MEDCouplingUMesh, 0 )); - } - } - // - PyObject *ret=PyTuple_New(2); - PyTuple_SetItem(ret,0,res); - PyTuple_SetItem(ret,1,convertIntArrToPyList2(refs)); - return ret; - } - PyObject *getArrays() const throw(INTERP_KERNEL::Exception) - { - std::vector ms=self->getArrays(); - int sz=ms.size(); - PyObject *res = PyList_New(sz); - for(int i=0;iincrRef(); - PyList_SetItem(res,i,SWIG_NewPointerObj(SWIG_as_voidptr(ms[i]),SWIGTYPE_p_ParaMEDMEM__DataArrayDouble, SWIG_POINTER_OWN | 0 )); - } - else - { - PyList_SetItem(res,i,SWIG_NewPointerObj(SWIG_as_voidptr(0),SWIGTYPE_p_ParaMEDMEM__DataArrayDouble, 0 )); - } - } - return res; - } - PyObject *getDifferentArrays() const throw(INTERP_KERNEL::Exception) - { - std::vector< std::vector > refs; - std::vector ms=self->getDifferentArrays(refs); - int sz=ms.size(); - PyObject *res = PyList_New(sz); - PyObject *res2 = PyList_New(sz); - for(int i=0;iincrRef(); - PyList_SetItem(res,i,SWIG_NewPointerObj(SWIG_as_voidptr(ms[i]),SWIGTYPE_p_ParaMEDMEM__DataArrayDouble, SWIG_POINTER_OWN | 0 )); - } - else - { - PyList_SetItem(res,i,SWIG_NewPointerObj(SWIG_as_voidptr(0),SWIGTYPE_p_ParaMEDMEM__DataArrayDouble, 0 )); - } - PyList_SetItem(res2,i,convertIntArrToPyList2(refs[i])); - } - // - PyObject *ret=PyTuple_New(2); - PyTuple_SetItem(ret,0,res); - PyTuple_SetItem(ret,1,res2); - return ret; - } - } - }; - - class MEDCouplingDefinitionTime - { - public: - MEDCouplingDefinitionTime(); - void assign(const MEDCouplingDefinitionTime& other); - bool isEqual(const MEDCouplingDefinitionTime& other) const; - double getTimeResolution() const; - std::vector getHotSpotsTime() const; - %extend - { - std::string __str__() const throw(INTERP_KERNEL::Exception) - { - std::ostringstream oss; - self->appendRepr(oss); - return oss.str(); - } - - PyObject *getIdsOnTimeRight(double tm) const throw(INTERP_KERNEL::Exception) - { - int meshId,arrId,arrIdInField,fieldId; - self->getIdsOnTimeRight(tm,meshId,arrId,arrIdInField,fieldId); - PyObject *res=PyList_New(4); - PyList_SetItem(res,0,PyInt_FromLong(meshId)); - PyList_SetItem(res,1,PyInt_FromLong(arrId)); - PyList_SetItem(res,2,PyInt_FromLong(arrIdInField)); - PyList_SetItem(res,3,PyInt_FromLong(fieldId)); - return res; - } - - PyObject *getIdsOnTimeLeft(double tm) const throw(INTERP_KERNEL::Exception) - { - int meshId,arrId,arrIdInField,fieldId; - self->getIdsOnTimeLeft(tm,meshId,arrId,arrIdInField,fieldId); - PyObject *res=PyList_New(4); - PyList_SetItem(res,0,PyInt_FromLong(meshId)); - PyList_SetItem(res,1,PyInt_FromLong(arrId)); - PyList_SetItem(res,2,PyInt_FromLong(arrIdInField)); - PyList_SetItem(res,3,PyInt_FromLong(fieldId)); - return res; - } - } - }; - - class MEDCouplingFieldOverTime : public MEDCouplingMultiFields - { - public: - double getTimeTolerance() const throw(INTERP_KERNEL::Exception); - MEDCouplingDefinitionTime getDefinitionTimeZone() const; - - %extend - { - MEDCouplingFieldOverTime(PyObject *li) throw(INTERP_KERNEL::Exception) - { - std::vector tmp; - convertFromPyObjVectorOfObj(li,SWIGTYPE_p_ParaMEDMEM__MEDCouplingFieldDouble,"MEDCouplingFieldDouble",tmp); - int sz=tmp.size(); - std::vector fs(sz); - for(int i=0;i(tmp[i]); - return MEDCouplingFieldOverTime::New(fs); - } - std::string __str__() const throw(INTERP_KERNEL::Exception) - { - return self->simpleRepr(); - } - static MEDCouplingFieldOverTime *New(PyObject *li) throw(INTERP_KERNEL::Exception) - { - std::vector tmp; - convertFromPyObjVectorOfObj(li,SWIGTYPE_p_ParaMEDMEM__MEDCouplingFieldDouble,"MEDCouplingFieldDouble",tmp); - int sz=tmp.size(); - std::vector fs(sz); - for(int i=0;i(tmp[i]); - return MEDCouplingFieldOverTime::New(fs); - } - } - }; - - class MEDCouplingCartesianAMRMesh; - - class MEDCouplingCartesianAMRPatchGen : public RefCountObject - { - public: - int getNumberOfCellsRecursiveWithOverlap() const throw(INTERP_KERNEL::Exception); - int getNumberOfCellsRecursiveWithoutOverlap() const throw(INTERP_KERNEL::Exception); - int getMaxNumberOfLevelsRelativeToThis() const throw(INTERP_KERNEL::Exception); - %extend - { - MEDCouplingCartesianAMRMeshGen *getMesh() const throw(INTERP_KERNEL::Exception) - { - MEDCouplingCartesianAMRMeshGen *ret(const_cast(self->getMesh())); - if(ret) - ret->incrRef(); - return ret; - } - } - }; - - class MEDCouplingCartesianAMRPatch : public MEDCouplingCartesianAMRPatchGen - { - public: - int getNumberOfOverlapedCellsForFather() const throw(INTERP_KERNEL::Exception); - bool isInMyNeighborhood(const MEDCouplingCartesianAMRPatch *other, int ghostLev) const throw(INTERP_KERNEL::Exception); - std::vector computeCellGridSt() const throw(INTERP_KERNEL::Exception); - %extend - { - PyObject *getBLTRRange() const throw(INTERP_KERNEL::Exception) - { - const std::vector< std::pair >& ret(self->getBLTRRange()); - return convertFromVectorPairInt(ret); - } - - PyObject *getBLTRRangeRelativeToGF() const throw(INTERP_KERNEL::Exception) - { - std::vector< std::pair > ret(self->getBLTRRangeRelativeToGF()); - return convertFromVectorPairInt(ret); - } - - void addPatch(PyObject *bottomLeftTopRight, const std::vector& factors) throw(INTERP_KERNEL::Exception) - { - std::vector< std::pair > inp; - convertPyToVectorPairInt(bottomLeftTopRight,inp); - self->addPatch(inp,factors); - } - - MEDCouplingCartesianAMRPatch *__getitem__(int patchId) const throw(INTERP_KERNEL::Exception) - { - const MEDCouplingCartesianAMRMeshGen *mesh(self->getMesh()); - if(!mesh) - throw INTERP_KERNEL::Exception("wrap MEDCouplingCartesianAMRPatchGen.__getitem__ : no underlying mesh !"); - if(patchId==mesh->getNumberOfPatches()) - { - std::ostringstream oss; - oss << "Requesting for patchId " << patchId << " having only " << mesh->getNumberOfPatches() << " patches !"; - PyErr_SetString(PyExc_StopIteration,oss.str().c_str()); - return 0; - } - MEDCouplingCartesianAMRPatch *ret(const_cast(mesh->getPatch(patchId))); - if(ret) - ret->incrRef(); - return ret; - } - - void __delitem__(int patchId) throw(INTERP_KERNEL::Exception) - { - MEDCouplingCartesianAMRMeshGen *mesh(const_cast(self->getMesh())); - if(!mesh) - throw INTERP_KERNEL::Exception("wrap MEDCouplingCartesianAMRPatch.__delitem__ : no underlying mesh !"); - mesh->removePatch(patchId); - } - - int __len__() const throw(INTERP_KERNEL::Exception) - { - const MEDCouplingCartesianAMRMeshGen *mesh(self->getMesh()); - if(!mesh) - throw INTERP_KERNEL::Exception("wrap MEDCouplingCartesianAMRPatch.__len__ : no underlying mesh !"); - return mesh->getNumberOfPatches(); - } - } - }; - - class MEDCouplingCartesianAMRPatchGF : public MEDCouplingCartesianAMRPatchGen - { - }; - - class MEDCouplingCartesianAMRMeshGen : public RefCountObject, public TimeLabel - { - public: - int getAbsoluteLevel() const throw(INTERP_KERNEL::Exception); - int getAbsoluteLevelRelativeTo(const MEDCouplingCartesianAMRMeshGen *ref) const throw(INTERP_KERNEL::Exception); - std::vector getPositionRelativeTo(const MEDCouplingCartesianAMRMeshGen *ref) const throw(INTERP_KERNEL::Exception); - int getSpaceDimension() const throw(INTERP_KERNEL::Exception); - const std::vector& getFactors() const throw(INTERP_KERNEL::Exception); - void setFactors(const std::vector& newFactors) throw(INTERP_KERNEL::Exception); - int getMaxNumberOfLevelsRelativeToThis() const throw(INTERP_KERNEL::Exception); - int getNumberOfCellsAtCurrentLevel() const throw(INTERP_KERNEL::Exception); - int getNumberOfCellsAtCurrentLevelGhost(int ghostLev) const throw(INTERP_KERNEL::Exception); - int getNumberOfCellsRecursiveWithOverlap() const throw(INTERP_KERNEL::Exception); - int getNumberOfCellsRecursiveWithoutOverlap() const throw(INTERP_KERNEL::Exception); - bool isPatchInNeighborhoodOf(int patchId1, int patchId2, int ghostLev) const throw(INTERP_KERNEL::Exception); - virtual void detachFromFather() throw(INTERP_KERNEL::Exception); - // - int getNumberOfPatches() const throw(INTERP_KERNEL::Exception); - int getPatchIdFromChildMesh(const MEDCouplingCartesianAMRMeshGen *mesh) const throw(INTERP_KERNEL::Exception); - MEDCouplingUMesh *buildUnstructured() const throw(INTERP_KERNEL::Exception); - DataArrayDouble *extractGhostFrom(int ghostSz, const DataArrayDouble *arr) const throw(INTERP_KERNEL::Exception); - std::vector getPatchIdsInTheNeighborhoodOf(int patchId, int ghostLev) const throw(INTERP_KERNEL::Exception); - MEDCoupling1SGTUMesh *buildMeshFromPatchEnvelop() const throw(INTERP_KERNEL::Exception); - MEDCoupling1SGTUMesh *buildMeshOfDirectChildrenOnly() const throw(INTERP_KERNEL::Exception); - void removeAllPatches() throw(INTERP_KERNEL::Exception); - void removePatch(int patchId) throw(INTERP_KERNEL::Exception); - void createPatchesFromCriterion(const INTERP_KERNEL::BoxSplittingOptions& bso, const DataArrayByte *criterion, const std::vector& factors) throw(INTERP_KERNEL::Exception); - void createPatchesFromCriterion(const INTERP_KERNEL::BoxSplittingOptions& bso, const DataArrayDouble *criterion, const std::vector& factors, double eps) throw(INTERP_KERNEL::Exception); - DataArrayDouble *createCellFieldOnPatch(int patchId, const DataArrayDouble *cellFieldOnThis) const throw(INTERP_KERNEL::Exception); - void fillCellFieldOnPatch(int patchId, const DataArrayDouble *cellFieldOnThis, DataArrayDouble *cellFieldOnPatch, bool isConservative=true) const throw(INTERP_KERNEL::Exception); - void fillCellFieldOnPatchGhost(int patchId, const DataArrayDouble *cellFieldOnThis, DataArrayDouble *cellFieldOnPatch, int ghostLev, bool isConservative=true) const throw(INTERP_KERNEL::Exception); - void fillCellFieldOnPatchOnlyOnGhostZone(int patchId, const DataArrayDouble *cellFieldOnThis, DataArrayDouble *cellFieldOnPatch, int ghostLev) const throw(INTERP_KERNEL::Exception); - void fillCellFieldOnPatchOnlyOnGhostZoneWith(int ghostLev, const MEDCouplingCartesianAMRPatch *patchToBeModified, const MEDCouplingCartesianAMRPatch *neighborPatch, DataArrayDouble *cellFieldOnPatch, const DataArrayDouble *cellFieldNeighbor) const; - void fillCellFieldComingFromPatch(int patchId, const DataArrayDouble *cellFieldOnPatch, DataArrayDouble *cellFieldOnThis, bool isConservative=true) const throw(INTERP_KERNEL::Exception); - void fillCellFieldComingFromPatchGhost(int patchId, const DataArrayDouble *cellFieldOnPatch, DataArrayDouble *cellFieldOnThis, int ghostLev, bool isConservative=true) const throw(INTERP_KERNEL::Exception); - DataArrayInt *findPatchesInTheNeighborhoodOf(int patchId, int ghostLev) const throw(INTERP_KERNEL::Exception); - std::string buildPythonDumpOfThis() const throw(INTERP_KERNEL::Exception); - %extend - { - void addPatch(PyObject *bottomLeftTopRight, const std::vector& factors) throw(INTERP_KERNEL::Exception) - { - std::vector< std::pair > inp; - convertPyToVectorPairInt(bottomLeftTopRight,inp); - self->addPatch(inp,factors); - } - - PyObject *getPatches() const throw(INTERP_KERNEL::Exception) - { - std::vector< const MEDCouplingCartesianAMRPatch *> ps(self->getPatches()); - int sz(ps.size()); - PyObject *ret = PyList_New(sz); - for(int i=0;i(ps[i])); - if(elt) - elt->incrRef(); - PyList_SetItem(ret,i,convertCartesianAMRPatch(elt, SWIG_POINTER_OWN | 0 )); - } - return ret; - } - - // agy : don't know why typemap fails here ??? let it in the extend section - PyObject *deepCpy(MEDCouplingCartesianAMRMeshGen *father) const throw(INTERP_KERNEL::Exception) - { - return convertCartesianAMRMesh(self->deepCpy(father), SWIG_POINTER_OWN | 0 ); - } - - MEDCouplingCartesianAMRPatch *getPatchAtPosition(const std::vector& pos) const throw(INTERP_KERNEL::Exception) - { - const MEDCouplingCartesianAMRPatch *ret(self->getPatchAtPosition(pos)); - MEDCouplingCartesianAMRPatch *ret2(const_cast(ret)); - if(ret2) - ret2->incrRef(); - return ret2; - } - - MEDCouplingCartesianAMRMeshGen *getMeshAtPosition(const std::vector& pos) const throw(INTERP_KERNEL::Exception) - { - const MEDCouplingCartesianAMRMeshGen *ret(self->getMeshAtPosition(pos)); - MEDCouplingCartesianAMRMeshGen *ret2(const_cast(ret)); - if(ret2) - ret2->incrRef(); - return ret2; - } - - virtual PyObject *positionRelativeToGodFather() const throw(INTERP_KERNEL::Exception) - { - std::vector out1; - std::vector< std::pair > out0(self->positionRelativeToGodFather(out1)); - PyObject *ret(PyTuple_New(2)); - PyTuple_SetItem(ret,0,convertFromVectorPairInt(out0)); - PyTuple_SetItem(ret,1,convertIntArrToPyList2(out1)); - return ret; - } - - virtual PyObject *retrieveGridsAt(int absoluteLev) const throw(INTERP_KERNEL::Exception) - { - std::vector ps(self->retrieveGridsAt(absoluteLev)); - int sz(ps.size()); - PyObject *ret = PyList_New(sz); - for(int i=0;i inp; - convertFromPyObjVectorOfObj(recurseArrs,SWIGTYPE_p_ParaMEDMEM__DataArrayDouble,"DataArrayDouble",inp); - return self->buildCellFieldOnRecurseWithoutOverlapWithoutGhost(ghostSz,inp); - } - - virtual MEDCouplingCartesianAMRMeshGen *getFather() const throw(INTERP_KERNEL::Exception) - { - MEDCouplingCartesianAMRMeshGen *ret(const_cast(self->getFather())); - if(ret) - ret->incrRef(); - return ret; - } - - virtual MEDCouplingCartesianAMRMeshGen *getGodFather() const throw(INTERP_KERNEL::Exception) - { - MEDCouplingCartesianAMRMeshGen *ret(const_cast(self->getGodFather())); - if(ret) - ret->incrRef(); - return ret; - } - - MEDCouplingCartesianAMRPatch *getPatch(int patchId) const throw(INTERP_KERNEL::Exception) - { - MEDCouplingCartesianAMRPatch *ret(const_cast(self->getPatch(patchId))); - if(ret) - ret->incrRef(); - return ret; - } - - MEDCouplingIMesh *getImageMesh() const throw(INTERP_KERNEL::Exception) - { - const MEDCouplingIMesh *ret(self->getImageMesh()); - if(ret) - ret->incrRef(); - return const_cast(ret); - } - - MEDCouplingCartesianAMRPatch *__getitem__(int patchId) const throw(INTERP_KERNEL::Exception) - { - if(patchId==self->getNumberOfPatches()) - { - std::ostringstream oss; - oss << "Requesting for patchId " << patchId << " having only " << self->getNumberOfPatches() << " patches !"; - PyErr_SetString(PyExc_StopIteration,oss.str().c_str()); - return 0; - } - MEDCouplingCartesianAMRPatch *ret(const_cast(self->getPatch(patchId))); - if(ret) - ret->incrRef(); - return ret; - } - - void fillCellFieldOnPatchGhostAdv(int patchId, const DataArrayDouble *cellFieldOnThis, int ghostLev, PyObject *arrsOnPatches, bool isConservative=true) const throw(INTERP_KERNEL::Exception) - { - std::vector arrsOnPatches2; - convertFromPyObjVectorOfObj(arrsOnPatches,SWIGTYPE_p_ParaMEDMEM__DataArrayDouble,"DataArrayDouble",arrsOnPatches2); - self->fillCellFieldOnPatchGhostAdv(patchId,cellFieldOnThis,ghostLev,arrsOnPatches2,isConservative); - } - - void fillCellFieldOnPatchOnlyGhostAdv(int patchId, int ghostLev, PyObject *arrsOnPatches) const - { - std::vector arrsOnPatches2; - convertFromPyObjVectorOfObj(arrsOnPatches,SWIGTYPE_p_ParaMEDMEM__DataArrayDouble,"DataArrayDouble",arrsOnPatches2); - self->fillCellFieldOnPatchOnlyGhostAdv(patchId,ghostLev,arrsOnPatches2); - } - - void __delitem__(int patchId) throw(INTERP_KERNEL::Exception) - { - self->removePatch(patchId); - } - - int __len__() const throw(INTERP_KERNEL::Exception) - { - return self->getNumberOfPatches(); - } - } - }; - - class MEDCouplingCartesianAMRMeshSub : public MEDCouplingCartesianAMRMeshGen - { - }; - - class MEDCouplingCartesianAMRMesh : public MEDCouplingCartesianAMRMeshGen - { - public: - static MEDCouplingCartesianAMRMesh *New(MEDCouplingIMesh *mesh) throw(INTERP_KERNEL::Exception); - %extend - { - static MEDCouplingCartesianAMRMesh *New(const std::string& meshName, int spaceDim, PyObject *nodeStrct, PyObject *origin, PyObject *dxyz) throw(INTERP_KERNEL::Exception) - { - static const char msg0[]="MEDCouplingCartesianAMRMesh::New : error on 'origin' parameter !"; - static const char msg1[]="MEDCouplingCartesianAMRMesh::New : error on 'dxyz' parameter !"; - const int *nodeStrctPtr(0); - const double *originPtr(0),*dxyzPtr(0); - int sw,sz,val0; - std::vector bb0; - nodeStrctPtr=convertObjToPossibleCpp1_Safe(nodeStrct,sw,sz,val0,bb0); - // - double val,val2; - std::vector bb,bb2; - int sz1,sz2; - originPtr=convertObjToPossibleCpp5_SingleCompo(origin,sw,val,bb,msg0,false,sz1); - dxyzPtr=convertObjToPossibleCpp5_SingleCompo(dxyz,sw,val2,bb2,msg1,false,sz2); - // - return MEDCouplingCartesianAMRMesh::New(meshName,spaceDim,nodeStrctPtr,nodeStrctPtr+sz,originPtr,originPtr+sz1,dxyzPtr,dxyzPtr+sz2); - } - - void createPatchesFromCriterionML(PyObject *bso, const DataArrayDouble *criterion, PyObject *factors, double eps) throw(INTERP_KERNEL::Exception) - { - std::vector inp0; - convertFromPyObjVectorOfObj(bso,SWIGTYPE_p_INTERP_KERNEL__BoxSplittingOptions,"BoxSplittingOptions",inp0); - std::vector< std::vector > inp2; - convertPyToVectorOfVectorOfInt(factors,inp2); - self->createPatchesFromCriterionML(inp0,criterion,inp2,eps); - } - - MEDCouplingCartesianAMRMesh(const std::string& meshName, int spaceDim, PyObject *nodeStrct, PyObject *origin, PyObject *dxyz) throw(INTERP_KERNEL::Exception) - { - return ParaMEDMEM_MEDCouplingCartesianAMRMesh_New__SWIG_1(meshName,spaceDim,nodeStrct,origin,dxyz); - } - - MEDCouplingCartesianAMRMesh(MEDCouplingIMesh *mesh) throw(INTERP_KERNEL::Exception) - { - return MEDCouplingCartesianAMRMesh::New(mesh); - } - } - }; - - class MEDCouplingDataForGodFather : public RefCountObject - { - public: - virtual void synchronizeFineToCoarse() throw(INTERP_KERNEL::Exception); - virtual void synchronizeFineToCoarseBetween(int fromLev, int toLev) throw(INTERP_KERNEL::Exception); - virtual void synchronizeCoarseToFine() throw(INTERP_KERNEL::Exception); - virtual void synchronizeCoarseToFineBetween(int fromLev, int toLev) throw(INTERP_KERNEL::Exception); - virtual void synchronizeAllGhostZones() throw(INTERP_KERNEL::Exception); - virtual void synchronizeAllGhostZonesOfDirectChidrenOf(const MEDCouplingCartesianAMRMeshGen *mesh) throw(INTERP_KERNEL::Exception); - virtual void synchronizeAllGhostZonesAtASpecifiedLevel(int level) throw(INTERP_KERNEL::Exception); - virtual void synchronizeAllGhostZonesAtASpecifiedLevelUsingOnlyFather(int level) throw(INTERP_KERNEL::Exception); - virtual void alloc() throw(INTERP_KERNEL::Exception); - virtual void dealloc() throw(INTERP_KERNEL::Exception); - %extend - { - MEDCouplingCartesianAMRMesh *getMyGodFather() throw(INTERP_KERNEL::Exception) - { - MEDCouplingCartesianAMRMesh *ret(self->getMyGodFather()); - if(ret) - ret->incrRef(); - return ret; - } - } - }; - - class MEDCouplingAMRAttribute : public MEDCouplingDataForGodFather, public TimeLabel - { - public: - int getNumberOfLevels() const throw(INTERP_KERNEL::Exception); - MEDCouplingAMRAttribute *deepCpy() const throw(INTERP_KERNEL::Exception); - MEDCouplingAMRAttribute *deepCpyWithoutGodFather() const throw(INTERP_KERNEL::Exception); - MEDCouplingFieldDouble *buildCellFieldOnRecurseWithoutOverlapWithoutGhost(MEDCouplingCartesianAMRMeshGen *mesh, const std::string& fieldName) const throw(INTERP_KERNEL::Exception); - MEDCouplingFieldDouble *buildCellFieldOnWithGhost(MEDCouplingCartesianAMRMeshGen *mesh, const std::string& fieldName) const throw(INTERP_KERNEL::Exception); - MEDCouplingFieldDouble *buildCellFieldOnWithoutGhost(MEDCouplingCartesianAMRMeshGen *mesh, const std::string& fieldName) const throw(INTERP_KERNEL::Exception); - bool changeGodFather(MEDCouplingCartesianAMRMesh *gf) throw(INTERP_KERNEL::Exception); - MEDCouplingAMRAttribute *projectTo(MEDCouplingCartesianAMRMesh *targetGF) const throw(INTERP_KERNEL::Exception); - std::string writeVTHB(const std::string& fileName) const throw(INTERP_KERNEL::Exception); - %extend - { - static MEDCouplingAMRAttribute *New(MEDCouplingCartesianAMRMesh *gf, PyObject *fieldNames, int ghostLev) throw(INTERP_KERNEL::Exception) - { - std::vector< std::pair > fieldNamesCpp0; - std::vector< std::pair > > fieldNamesCpp1; - MEDCouplingAMRAttribute *ret(0); - try - { - convertPyToVectorPairStringInt(fieldNames,fieldNamesCpp0); - ret=MEDCouplingAMRAttribute::New(gf,fieldNamesCpp0,ghostLev); - } - catch(INTERP_KERNEL::Exception&) - { - convertPyToVectorPairStringVecString(fieldNames,fieldNamesCpp1); - ret=MEDCouplingAMRAttribute::New(gf,fieldNamesCpp1,ghostLev); - } - return ret; - } - - MEDCouplingAMRAttribute(MEDCouplingCartesianAMRMesh *gf, PyObject *fieldNames, int ghostLev) throw(INTERP_KERNEL::Exception) - { - return ParaMEDMEM_MEDCouplingAMRAttribute_New(gf,fieldNames,ghostLev); - } - - DataArrayDouble *getFieldOn(MEDCouplingCartesianAMRMeshGen *mesh, const std::string& fieldName) const throw(INTERP_KERNEL::Exception) - { - const DataArrayDouble *ret(self->getFieldOn(mesh,fieldName)); - DataArrayDouble *ret2(const_cast(ret)); - if(ret2) - ret2->incrRef(); - return ret2; - } - - void spillInfoOnComponents(PyObject *compNames) throw(INTERP_KERNEL::Exception) - { - std::vector< std::vector > compNamesCpp; - convertPyToVectorOfVectorOfString(compNames,compNamesCpp); - self->spillInfoOnComponents(compNamesCpp); - } - - void spillNatures(PyObject *nfs) throw(INTERP_KERNEL::Exception) - { - std::vector inp0; - if(!fillIntVector(nfs,inp0)) - throw INTERP_KERNEL::Exception("wrap of MEDCouplingAMRAttribute::spillNatures : vector of NatureOfField enum expected !"); - std::size_t sz(inp0.size()); - std::vector inp00(sz); - for(std::size_t i=0;ispillNatures(inp00); - } - - PyObject *retrieveFieldsOn(MEDCouplingCartesianAMRMeshGen *mesh) const throw(INTERP_KERNEL::Exception) - { - std::vector ret(self->retrieveFieldsOn(mesh)); - int sz((int)ret.size()); - PyObject *retPy(PyList_New(sz)); - for(int i=0;iisEqualIfNotWhy(other,eps,ret1); - PyObject *ret=PyTuple_New(2); - PyObject *ret0Py=ret0?Py_True:Py_False; - Py_XINCREF(ret0Py); - PyTuple_SetItem(ret,0,ret0Py); - PyTuple_SetItem(ret,1,PyString_FromString(ret1.c_str())); - return ret; - } - - DataArrayDouble *getData() throw(INTERP_KERNEL::Exception) - { - DataArrayDouble *ret(self->getData()); - if(ret) - ret->incrRef(); - return ret; - } - - DenseMatrix *__add__(const DenseMatrix *other) throw(INTERP_KERNEL::Exception) - { - return ParaMEDMEM::DenseMatrix::Add(self,other); - } - - DenseMatrix *__sub__(const DenseMatrix *other) throw(INTERP_KERNEL::Exception) - { - return ParaMEDMEM::DenseMatrix::Substract(self,other); - } - - DenseMatrix *__mul__(const DenseMatrix *other) throw(INTERP_KERNEL::Exception) - { - return ParaMEDMEM::DenseMatrix::Multiply(self,other); - } - - DenseMatrix *__mul__(const DataArrayDouble *other) throw(INTERP_KERNEL::Exception) - { - return ParaMEDMEM::DenseMatrix::Multiply(self,other); - } - - PyObject *___iadd___(PyObject *trueSelf, const DenseMatrix *other) throw(INTERP_KERNEL::Exception) - { - self->addEqual(other); - Py_XINCREF(trueSelf); - return trueSelf; - } - - PyObject *___isub___(PyObject *trueSelf, const DenseMatrix *other) throw(INTERP_KERNEL::Exception) - { - self->substractEqual(other); - Py_XINCREF(trueSelf); - return trueSelf; - } -#ifdef WITH_NUMPY - PyObject *toNumPyMatrix() throw(INTERP_KERNEL::Exception) // not const. It is not a bug ! - { - PyObject *obj(ToNumPyArrayUnderground(self->getData(),NPY_DOUBLE,"DataArrayDouble",self->getNumberOfRows(),self->getNumberOfCols())); - return obj; - } -#endif - } - }; - - class PartDefinition : public RefCountObject, public TimeLabel - { - public: - static PartDefinition *New(int start, int stop, int step) throw(INTERP_KERNEL::Exception); - static PartDefinition *New(DataArrayInt *listOfIds) throw(INTERP_KERNEL::Exception); - virtual DataArrayInt *toDAI() const throw(INTERP_KERNEL::Exception); - virtual int getNumberOfElems() const throw(INTERP_KERNEL::Exception); - virtual std::string getRepr() const throw(INTERP_KERNEL::Exception); - virtual PartDefinition *composeWith(const PartDefinition *other) const throw(INTERP_KERNEL::Exception); - virtual void checkCoherency() const throw(INTERP_KERNEL::Exception); - virtual PartDefinition *tryToSimplify() const throw(INTERP_KERNEL::Exception); - %extend - { - virtual PartDefinition *__add__(const PartDefinition& other) const throw(INTERP_KERNEL::Exception) - { - return (*self)+other; - } - - virtual PyObject *isEqual(const PartDefinition *other) const throw(INTERP_KERNEL::Exception) - { - std::string ret1; - bool ret0(self->isEqual(other,ret1)); - PyObject *ret=PyTuple_New(2); - PyObject *ret0Py=ret0?Py_True:Py_False; - Py_XINCREF(ret0Py); - PyTuple_SetItem(ret,0,ret0Py); - PyTuple_SetItem(ret,1,PyString_FromString(ret1.c_str())); - return ret; - } - - virtual PyObject *deepCpy() const throw(INTERP_KERNEL::Exception) - { - return convertPartDefinition(self->deepCpy(),SWIG_POINTER_OWN | 0); - } - } - protected: - virtual ~PartDefinition(); - }; - - class DataArrayPartDefinition : public PartDefinition - { - public: - static DataArrayPartDefinition *New(DataArrayInt *listOfIds) throw(INTERP_KERNEL::Exception); - %extend - { - DataArrayPartDefinition(DataArrayInt *listOfIds) throw(INTERP_KERNEL::Exception) - { - return DataArrayPartDefinition::New(listOfIds); - } - - std::string __str__() const throw(INTERP_KERNEL::Exception) - { - return self->getRepr(); - } - - std::string __repr__() const throw(INTERP_KERNEL::Exception) - { - std::ostringstream oss; oss << "DataArrayPartDefinition C++ instance at " << self << "." << std::endl; - oss << self->getRepr(); - return oss.str(); - } - } - protected: - virtual ~DataArrayPartDefinition(); - }; - - class SlicePartDefinition : public PartDefinition - { - public: - static SlicePartDefinition *New(int start, int stop, int step) throw(INTERP_KERNEL::Exception); - int getEffectiveStop() const throw(INTERP_KERNEL::Exception); - %extend - { - SlicePartDefinition(int start, int stop, int step) throw(INTERP_KERNEL::Exception) - { - return SlicePartDefinition::New(start,stop,step); - } - - PyObject *getSlice() const throw(INTERP_KERNEL::Exception) - { - int a,b,c; - self->getSlice(a,b,c); - return PySlice_New(PyInt_FromLong(a),PyInt_FromLong(b),PyInt_FromLong(c)); - } - - std::string __str__() const throw(INTERP_KERNEL::Exception) - { - return self->getRepr(); - } - - std::string __repr__() const throw(INTERP_KERNEL::Exception) - { - std::ostringstream oss; oss << "SlicePartDefinition C++ instance at " << self << "." << std::endl; - oss << self->getRepr(); - return oss.str(); - } - } - protected: - virtual ~SlicePartDefinition(); - }; -} - -%pythoncode %{ -import os -__filename=os.environ.get('PYTHONSTARTUP') -if __filename and os.path.isfile(__filename): - execfile(__filename) - pass -%} diff --git a/src/MEDCoupling_Swig/MEDCouplingDataArrayTypemaps.i b/src/MEDCoupling_Swig/MEDCouplingDataArrayTypemaps.i deleted file mode 100644 index eba6b204e..000000000 --- a/src/MEDCoupling_Swig/MEDCouplingDataArrayTypemaps.i +++ /dev/null @@ -1,2529 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 -// 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 "InterpKernelAutoPtr.hxx" - -/*! - * This method is an extention of PySlice_GetIndices but less - * open than PySlice_GetIndicesEx that accepts too many situations. - */ -void GetIndicesOfSlice(PySliceObject *slice, Py_ssize_t length, Py_ssize_t *start, Py_ssize_t *stop, Py_ssize_t *step, const char *msgInCaseOfFailure) -{ - int ret(PySlice_GetIndices(slice,length,start,stop,step)); - if(ret==0) - return ; - if(*step>0 && *start==*stop && length==*start) - return ; - throw INTERP_KERNEL::Exception(msgInCaseOfFailure); -} - -/*! - * This method allows to retrieve slice info from \a slice. - */ -void GetIndicesOfSliceExplicitely(PySliceObject *slice, Py_ssize_t *start, Py_ssize_t *stop, Py_ssize_t *step, const char *msgInCaseOfFailure) -{ - int ret(PySlice_GetIndices(slice,std::numeric_limits::max(),start,stop,step)); - if(ret==0) - { - if(*start!=std::numeric_limits::max() && *stop!=std::numeric_limits::max()) - return ; - std::ostringstream oss; - oss << msgInCaseOfFailure << " The input slice contains some unknowns that can't be determined in static method ! The input slice must be explicit here !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - throw INTERP_KERNEL::Exception(msgInCaseOfFailure); -} - -int InterpreteNegativeInt(int val, int nbelem) -{ - if(val<0) - { - int newVal(nbelem+val); - if(newVal<0) - { - std::ostringstream oss; oss << "interpreteNegativeInt : request for negative int=" << val << " but number of elems is equal to " << nbelem << " !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - return newVal; - } - else - return val; -} - -#ifdef WITH_NUMPY -#include -#if NPY_API_VERSION <= 0x00000006 -# define MED_NUMPY_OWNDATA NPY_OWNDATA -#else -# define MED_NUMPY_OWNDATA NPY_ARRAY_OWNDATA -#endif - -// specific DataArray deallocator callback. This deallocator is used both in the constructor of DataArray and in the toNumPyArr -// method. This dellocator uses weakref to determine if the linked numArr is still alive or not. If alive the ownership is given to it. -// if no more alive the "standart" DataArray deallocator is called. -void numarrdeal(void *pt, void *wron) -{ - void **wronc=(void **)wron; - PyObject *weakRefOnOwner=reinterpret_cast(wronc[0]); - PyObject *obj=PyWeakref_GetObject(weakRefOnOwner); - if(obj!=Py_None) - { - Py_XINCREF(obj); - PyArrayObject *objC=reinterpret_cast(obj); - objC->flags|=MED_NUMPY_OWNDATA; - Py_XDECREF(weakRefOnOwner); - Py_XDECREF(obj); - } - else - { - typedef void (*MyDeallocator)(void *,void *); - MyDeallocator deall=(MyDeallocator)wronc[1]; - deall(pt,NULL); - Py_XDECREF(weakRefOnOwner); - } - delete [] wronc; -} - -template -struct PyCallBackDataArraySt { - PyObject_HEAD - MCData *_pt_mc; -}; - -typedef struct PyCallBackDataArraySt PyCallBackDataArrayInt; -typedef struct PyCallBackDataArraySt PyCallBackDataArrayDouble; - -extern "C" -{ - static int callbackmcdataarray___init__(PyObject *self, PyObject *args, PyObject *kwargs) { return 0; } - - static PyObject *callbackmcdataarrayint___new__(PyTypeObject *type, PyObject *args, PyObject *kwargs) - { - PyCallBackDataArrayInt *self = (PyCallBackDataArrayInt *) ( type->tp_alloc(type, 0) ); - return (PyObject *)self; - } - - static PyObject *callbackmcdataarraydouble___new__(PyTypeObject *type, PyObject *args, PyObject *kwargs) - { - PyCallBackDataArrayDouble *self = (PyCallBackDataArrayDouble *) ( type->tp_alloc(type, 0) ); - return (PyObject *)self; - } - - static void callbackmcdataarray_dealloc(PyObject *self) - { - Py_TYPE(self)->tp_free(self); - } - - // real callback called when a numpy arr having more than one DataArray instance client on it is destroyed. - // In this case, all the "weak" clients, except the first one, invoke this call back that desable the content of these "weak" clients. - static PyObject *callbackmcdataarrayint_call(PyCallBackDataArrayInt *self, PyObject *args, PyObject *kw) - { - if(self->_pt_mc) - { - ParaMEDMEM::MemArray& mma=self->_pt_mc->accessToMemArray(); - mma.destroy(); - } - Py_XINCREF(Py_None); - return Py_None; - } - - // real callback called when a numpy arr having more than one DataArray instance client on it is destroyed. - // In this case, all the "weak" clients, except the first one, invoke this call back that desable the content of these "weak" clients. - static PyObject *callbackmcdataarraydouble_call(PyCallBackDataArrayDouble *self, PyObject *args, PyObject *kw) - { - if(self->_pt_mc) - { - ParaMEDMEM::MemArray& mma=self->_pt_mc->accessToMemArray(); - mma.destroy(); - } - Py_XINCREF(Py_None); - return Py_None; - } -} - -PyTypeObject PyCallBackDataArrayInt_RefType = { - PyVarObject_HEAD_INIT(&PyType_Type, 0) - "callbackmcdataarrayint", - sizeof(PyCallBackDataArrayInt), - 0, - callbackmcdataarray_dealloc, /*tp_dealloc*/ - 0, /*tp_print*/ - 0, /*tp_getattr*/ - 0, /*tp_setattr*/ - 0, /*tp_compare*/ - 0, /*tp_repr*/ - 0, /*tp_as_number*/ - 0, /*tp_as_sequence*/ - 0, /*tp_as_mapping*/ - 0, /*tp_hash*/ - (ternaryfunc)callbackmcdataarrayint_call, /*tp_call*/ - 0, /*tp_str*/ - 0, /*tp_getattro*/ - 0, /*tp_setattro*/ - 0, /*tp_as_buffer*/ - Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_BASETYPE, /*tp_flags*/ - 0, /*tp_doc*/ - 0, /*tp_traverse*/ - 0, /*tp_clear*/ - 0, /*tp_richcompare*/ - 0, /*tp_weaklistoffset*/ - 0, /*tp_iter*/ - 0, /*tp_iternext*/ - 0, /*tp_methods*/ - 0, /*tp_members*/ - 0, /*tp_getset*/ - 0, /*tp_base*/ - 0, /*tp_dict*/ - 0, /*tp_descr_get*/ - 0, /*tp_descr_set*/ - 0, /*tp_dictoffset*/ - callbackmcdataarray___init__, /*tp_init*/ - PyType_GenericAlloc, /*tp_alloc*/ - callbackmcdataarrayint___new__, /*tp_new*/ - PyObject_GC_Del, /*tp_free*/ -}; - -PyTypeObject PyCallBackDataArrayDouble_RefType = { - PyVarObject_HEAD_INIT(&PyType_Type, 0) - "callbackmcdataarraydouble", - sizeof(PyCallBackDataArrayDouble), - 0, - callbackmcdataarray_dealloc, /*tp_dealloc*/ - 0, /*tp_print*/ - 0, /*tp_getattr*/ - 0, /*tp_setattr*/ - 0, /*tp_compare*/ - 0, /*tp_repr*/ - 0, /*tp_as_number*/ - 0, /*tp_as_sequence*/ - 0, /*tp_as_mapping*/ - 0, /*tp_hash*/ - (ternaryfunc)callbackmcdataarraydouble_call, /*tp_call*/ - 0, /*tp_str*/ - 0, /*tp_getattro*/ - 0, /*tp_setattro*/ - 0, /*tp_as_buffer*/ - Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_BASETYPE, /*tp_flags*/ - 0, /*tp_doc*/ - 0, /*tp_traverse*/ - 0, /*tp_clear*/ - 0, /*tp_richcompare*/ - 0, /*tp_weaklistoffset*/ - 0, /*tp_iter*/ - 0, /*tp_iternext*/ - 0, /*tp_methods*/ - 0, /*tp_members*/ - 0, /*tp_getset*/ - 0, /*tp_base*/ - 0, /*tp_dict*/ - 0, /*tp_descr_get*/ - 0, /*tp_descr_set*/ - 0, /*tp_dictoffset*/ - callbackmcdataarray___init__, /*tp_init*/ - PyType_GenericAlloc, /*tp_alloc*/ - callbackmcdataarraydouble___new__, /*tp_new*/ - PyObject_GC_Del, /*tp_free*/ -}; - -// this is the second type of specific deallocator, only valid for the constructor of DataArrays taking numpy array -// in input when an another DataArray is already client of this. -template -void numarrdeal2(void *pt, void *obj) -{ - typedef struct PyCallBackDataArraySt PyCallBackDataArray; - void **obj1=(void **)obj; - PyCallBackDataArray *cbdaic=reinterpret_cast(obj1[0]); - PyObject *weakRefOnOwner=reinterpret_cast(obj1[1]); - cbdaic->_pt_mc=0; - Py_XDECREF(weakRefOnOwner); - Py_XDECREF(cbdaic); - delete [] obj1; -} - -template -MCData *BuildNewInstance(PyObject *elt0, int npyObjectType, PyTypeObject *pytype, const char *msg) -{ - int ndim=PyArray_NDIM(elt0); - if(ndim!=1 && ndim!=2) - throw INTERP_KERNEL::Exception("Input numpy array should have dimension equal to 1 or 2 !"); - if(PyArray_DESCR(elt0)->type_num != npyObjectType) - { - std::ostringstream oss; oss << "Input numpy array has not the type " << msg << "!"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - npy_intp sz0=PyArray_DIM(elt0,0); - npy_intp sz1=ndim==2?PyArray_DIM(elt0,1):1; - // - int itemSize=PyArray_ITEMSIZE(elt0); - if(itemSize!=sizeof(T)) - { - std::ostringstream oss; oss << "Input numpy array has not itemSize set to " << sizeof(T) << " !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - if(itemSize*sz1!=PyArray_STRIDE(elt0,0)) - throw INTERP_KERNEL::Exception("Input numpy array has stride that mismatches the item size ! Data are not packed in the right way for DataArrays !"); - if(ndim==2) - if(itemSize!=PyArray_STRIDE(elt0,1)) - throw INTERP_KERNEL::Exception("Input numpy array has stride that mismatches the item size ! Data are not packed in the right way for DataArrays for component #1 !"); - const char *data=PyArray_BYTES(elt0); - typename ParaMEDMEM::MEDCouplingAutoRefCountObjectPtr ret=MCData::New(); - if(PyArray_ISBEHAVED(elt0))//aligned and writeable and in machine byte-order - { - PyArrayObject *elt0C=reinterpret_cast(elt0); - PyArrayObject *eltOwning=(PyArray_FLAGS(elt0C) & MED_NUMPY_OWNDATA)?elt0C:NULL; - int mask=MED_NUMPY_OWNDATA; mask=~mask; - elt0C->flags&=mask; - PyObject *deepestObj=elt0; - PyObject *base=elt0C->base; - if(base) deepestObj=base; - bool isSpetialCase(false); - while(base) - { - if(PyArray_Check(base)) - { - PyArrayObject *baseC=reinterpret_cast(base); - eltOwning=(PyArray_FLAGS(baseC) & MED_NUMPY_OWNDATA)?baseC:eltOwning; - baseC->flags&=mask; - base=baseC->base; - if(base) deepestObj=base; - } - else - { - isSpetialCase=true; - break; - } - } - if(isSpetialCase) - {// this case is present for numpy arrayint coming from load of pickelized string. The owner of elt0 is not an array -> A copy is requested. - std::size_t nbOfElems(sz0*sz1); - T *dataCpy=(T*)malloc(sizeof(T)*nbOfElems); - std::copy(reinterpret_cast(data),reinterpret_cast(data)+nbOfElems,dataCpy); - ret->useArray(dataCpy,true,ParaMEDMEM::C_DEALLOC,sz0,sz1); - return ret.retn(); - } - typename ParaMEDMEM::MemArray& mma=ret->accessToMemArray(); - if(eltOwning==NULL) - { - PyCallBackDataArraySt *cb=PyObject_GC_New(PyCallBackDataArraySt,pytype); - cb->_pt_mc=ret; - ret->useArray(reinterpret_cast(data),true,ParaMEDMEM::C_DEALLOC,sz0,sz1); - PyObject *ref=PyWeakref_NewRef(deepestObj,(PyObject *)cb); - void **objs=new void *[2]; objs[0]=cb; objs[1]=ref; - mma.setParameterForDeallocator(objs); - mma.setSpecificDeallocator(numarrdeal2); - //"Impossible to share this numpy array chunk of data, because already shared by an another non numpy array object (maybe an another DataArrayInt instance) ! Release it, or perform a copy on the input array !"); - } - else - { - ret->useArray(reinterpret_cast(data),true,ParaMEDMEM::C_DEALLOC,sz0,sz1); - PyObject *ref=PyWeakref_NewRef(reinterpret_cast(eltOwning),NULL); - typename ParaMEDMEM::MemArray::Deallocator tmp(ParaMEDMEM::MemArray::CDeallocator); - void **tmp2 = reinterpret_cast(&tmp); // MSVC2010 does not support constructor() - void **objs=new void *[2]; objs[0]=ref; objs[1]=*tmp2; - mma.setParameterForDeallocator(objs); - mma.setSpecificDeallocator(numarrdeal); - } - } - else if(PyArray_ISBEHAVED_RO(elt0)) - ret->useArray(reinterpret_cast(data),false,ParaMEDMEM::CPP_DEALLOC,sz0,sz1); - return ret.retn(); -} - - -int NumpyArrSetBaseObjectExt(PyArrayObject *arr, PyObject *obj) -{ - if (obj == NULL) { - PyErr_SetString(PyExc_ValueError, - "Cannot set the NumPy array 'base' " - "dependency to NULL after initialization"); - return -1; - } - /* - * Allow the base to be set only once. Once the object which - * owns the data is set, it doesn't make sense to change it. - */ - if (PyArray_BASE(arr) != NULL) { - Py_DECREF(obj); - PyErr_SetString(PyExc_ValueError, - "Cannot set the NumPy array 'base' " - "dependency more than once"); - return -1; - } - - /* - * Don't allow infinite chains of views, always set the base - * to the first owner of the data. - * That is, either the first object which isn't an array, - * or the first object which owns its own data. - */ - - while (PyArray_Check(obj) && (PyObject *)arr != obj) { - PyArrayObject *obj_arr = (PyArrayObject *)obj; - PyObject *tmp; - - - /* If this array owns its own data, stop collapsing */ - if (PyArray_CHKFLAGS(obj_arr, MED_NUMPY_OWNDATA )) { - break; - } - - tmp = PyArray_BASE(obj_arr); - /* If there's no base, stop collapsing */ - if (tmp == NULL) { - break; - } - /* Stop the collapse new base when the would not be of the same - * type (i.e. different subclass). - */ - if (Py_TYPE(tmp) != Py_TYPE(arr)) { - break; - } - - - Py_INCREF(tmp); - Py_DECREF(obj); - obj = tmp; - } - - /* Disallow circular references */ - if ((PyObject *)arr == obj) { - Py_DECREF(obj); - PyErr_SetString(PyExc_ValueError, - "Cannot create a circular NumPy array 'base' dependency"); - return -1; - } - - arr->base = obj; - - return 0; -} - -template -PyObject *ToNumPyArrayUnderground(MCData *self, int npyObjectType, const char *MCDataStr, int nbTuples, int nbComp) -{ - if(!self->isAllocated()) - { - std::ostringstream oss; oss << MCDataStr << "::toNumPyArray : this is not allocated !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - ParaMEDMEM::MemArray& mem=self->accessToMemArray(); - if(nbComp==0) - { - std::ostringstream oss; oss << MCDataStr << "::toNumPyArray : number of components of this is 0 ! Should be > 0 !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - int nbDims=nbComp==1?1:2; - npy_intp dim[2]; - dim[0]=(npy_intp)nbTuples; dim[1]=nbComp; - const T *bg=self->getConstPointer(); - PyObject *ret(PyArray_SimpleNewFromData(nbDims,dim,npyObjectType,const_cast(bg))); - if(mem.isDeallocatorCalled()) - { - if(mem.getDeallocator()!=numarrdeal) - {// case for the first call of toNumPyArray - PyObject *ref(PyWeakref_NewRef(ret,NULL)); - typename ParaMEDMEM::MemArray::Deallocator tmp(mem.getDeallocator()); - void **tmp2 = reinterpret_cast(&tmp); // MSVC2010 does not support constructor() - void **objs=new void *[2]; objs[0]=reinterpret_cast(ref); objs[1]=*tmp2; - mem.setParameterForDeallocator(objs); - mem.setSpecificDeallocator(numarrdeal); - return ret; - } - else - {// case for the second and other call of toNumPyArray - void **objs=(void **)mem.getParameterForDeallocator(); - PyObject *weakRefOnOwner=(PyObject *)objs[0]; - PyObject *obj=PyWeakref_GetObject(weakRefOnOwner); - if(obj!=Py_None) - {//the previous numArray exists let numpy deals the numpy array each other by declaring the still alive instance as base - Py_XINCREF(obj); - NumpyArrSetBaseObjectExt((PyArrayObject*)ret,obj); - } - else - {//the previous numArray no more exists -> declare the newly created numpy array as the first one. - Py_XDECREF(weakRefOnOwner); - PyObject *ref=PyWeakref_NewRef(ret,NULL); - objs[0]=ref; - } - } - } - return ret; -} - -template -PyObject *ToNumPyArray(MCData *self, int npyObjectType, const char *MCDataStr) -{ - return ToNumPyArrayUnderground(self,npyObjectType,MCDataStr,self->getNumberOfTuples(),self->getNumberOfComponents()); -} - -SWIGINTERN PyObject *ParaMEDMEM_DataArrayInt_toNumPyArray(ParaMEDMEM::DataArrayInt *self); -SWIGINTERN PyObject *ParaMEDMEM_DataArrayDouble_toNumPyArray(ParaMEDMEM::DataArrayDouble *self); - -PyObject *ToCSRMatrix(const std::vector >& m, int nbCols) throw(INTERP_KERNEL::Exception) -{ - int nbRows((int)m.size()); - ParaMEDMEM::MEDCouplingAutoRefCountObjectPtr indPtr(ParaMEDMEM::DataArrayInt::New()),indices(ParaMEDMEM::DataArrayInt::New()); - ParaMEDMEM::MEDCouplingAutoRefCountObjectPtr data(ParaMEDMEM::DataArrayDouble::New()); - indPtr->alloc(nbRows+1,1); - int *intPtr_ptr(indPtr->getPointer()); intPtr_ptr[0]=0; intPtr_ptr++; - int sz2(0); - for(std::vector >::const_iterator it0=m.begin();it0!=m.end();it0++,intPtr_ptr++) - { - sz2+=(int)(*it0).size(); - *intPtr_ptr=sz2; - } - indices->alloc(sz2,1); data->alloc(sz2,1); - int *indices_ptr(indices->getPointer()); - double *data_ptr(data->getPointer()); - for(std::vector >::const_iterator it0=m.begin();it0!=m.end();it0++) - for(std::map::const_iterator it1=(*it0).begin();it1!=(*it0).end();it1++,indices_ptr++,data_ptr++) - { - *indices_ptr=(*it1).first; - *data_ptr=(*it1).second; - } - PyObject *a(ParaMEDMEM_DataArrayDouble_toNumPyArray(data)),*b(ParaMEDMEM_DataArrayInt_toNumPyArray(indices)),*c(ParaMEDMEM_DataArrayInt_toNumPyArray(indPtr)); - // - PyObject *args(PyTuple_New(1)),*args0(PyTuple_New(3)),*kw(PyDict_New()),*kw1(PyTuple_New(2)); - PyTuple_SetItem(args0,0,a); PyTuple_SetItem(args0,1,b); PyTuple_SetItem(args0,2,c); PyTuple_SetItem(args,0,args0); - PyTuple_SetItem(kw1,0,PyInt_FromLong(nbRows)); PyTuple_SetItem(kw1,1,PyInt_FromLong(nbCols)); - PyObject *tmp1(PyString_FromString("shape")); - PyDict_SetItem(kw,tmp1,kw1); Py_DECREF(tmp1); Py_DECREF(kw1); - PyObject* pdict=PyDict_New(); - PyDict_SetItemString(pdict, "__builtins__", PyEval_GetBuiltins()); - PyObject *tmp(PyRun_String("from scipy.sparse import csr_matrix", Py_single_input, pdict, pdict)); - if(!tmp) - throw INTERP_KERNEL::Exception("Problem during loading csr_matrix in scipy.sparse ! Is Scipy module available in present ?"); - PyObject *csrMatrixCls=PyDict_GetItemString(pdict,"csr_matrix"); - if(!csrMatrixCls) - throw INTERP_KERNEL::Exception("csr_matrix not found in scipy.sparse ! Is Scipy module available in present ?"); - PyObject *ret(PyObject_Call(csrMatrixCls,args,kw)); - Py_DECREF(pdict); Py_XDECREF(tmp); Py_DECREF(args); Py_DECREF(kw); - return ret; -} - -#endif - -static PyObject *convertDataArrayChar(ParaMEDMEM::DataArrayChar *dac, int owner) throw(INTERP_KERNEL::Exception) -{ - PyObject *ret=0; - if(!dac) - { - Py_XINCREF(Py_None); - return Py_None; - } - if(dynamic_cast(dac)) - ret=SWIG_NewPointerObj((void*)dac,SWIGTYPE_p_ParaMEDMEM__DataArrayByte,owner); - if(dynamic_cast(dac)) - ret=SWIG_NewPointerObj((void*)dac,SWIGTYPE_p_ParaMEDMEM__DataArrayAsciiChar,owner); - if(!ret) - throw INTERP_KERNEL::Exception("Not recognized type of DataArrayChar on downcast !"); - return ret; -} - -static PyObject *convertDataArray(ParaMEDMEM::DataArray *dac, int owner) throw(INTERP_KERNEL::Exception) -{ - PyObject *ret=0; - if(!dac) - { - Py_XINCREF(Py_None); - return Py_None; - } - if(dynamic_cast(dac)) - ret=SWIG_NewPointerObj((void*)dac,SWIGTYPE_p_ParaMEDMEM__DataArrayDouble,owner); - if(dynamic_cast(dac)) - ret=SWIG_NewPointerObj((void*)dac,SWIGTYPE_p_ParaMEDMEM__DataArrayInt,owner); - if(dynamic_cast(dac)) - ret=SWIG_NewPointerObj((void*)dac,SWIGTYPE_p_ParaMEDMEM__DataArrayByte,owner); - if(dynamic_cast(dac)) - ret=SWIG_NewPointerObj((void*)dac,SWIGTYPE_p_ParaMEDMEM__DataArrayAsciiChar,owner); - if(!ret) - throw INTERP_KERNEL::Exception("Not recognized type of DataArray on downcast !"); - return ret; -} - -static PyObject *convertIntArrToPyList(const int *ptr, int size) throw(INTERP_KERNEL::Exception) -{ - PyObject *ret=PyList_New(size); - for(int i=0;i& v) throw(INTERP_KERNEL::Exception) -{ - int size=v.size(); - PyObject *ret=PyList_New(size); - for(int i=0;i& v) throw(INTERP_KERNEL::Exception) -{ - int size=v.size(); - PyObject *ret=PyList_New(size); - std::set::const_iterator it=v.begin(); - for(int i=0;i >& arr) throw(INTERP_KERNEL::Exception) -{ - PyObject *ret=PyList_New(arr.size()); - for(std::size_t i=0;i >& arr) throw(INTERP_KERNEL::Exception) -{ - const char msg[]="list must contain tuples of 2 integers only or tuple must contain tuples of 2 integers only !"; - if(PyList_Check(pyLi)) - { - int size=PyList_Size(pyLi); - arr.resize(size); - for(int i=0;i >& arr) throw(INTERP_KERNEL::Exception) -{ - const char msg[]="convertPyToVectorPairStringInt : list must contain tuples of 2 integers only or tuple must contain tuples of 1 string and 1 integer only !"; - if(PyList_Check(pyLi)) - { - int size=PyList_Size(pyLi); - arr.resize(size); - for(int i=0;i& arr) throw(INTERP_KERNEL::Exception) -{ - if(PyList_Check(pyLi)) - { - int size=PyList_Size(pyLi); - arr.resize(size); - for(int i=0;i& arr) throw(INTERP_KERNEL::Exception) -{ - if(recurseLev<0) - throw INTERP_KERNEL::Exception("convertPyToNewIntArr4 : invalid list of integers level of recursion !"); - arr.clear(); - if(PyList_Check(pyLi)) - { - int size=PyList_Size(pyLi); - for(int i=0;i arr2; - convertPyToNewIntArr4(o,recurseLev-1,nbOfSubPart,arr2); - if(nbOfSubPart>=1 && nbOfSubPart!=(int)arr2.size()) - { - std::ostringstream oss; oss << "convertPyToNewIntArr4 : input list at lev " << recurseLev << " invalid nb of subpart elts expected " << nbOfSubPart << " having " << arr2.size() << " !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - arr.insert(arr.end(),arr2.begin(),arr2.end()); - } - } - } - else if(PyTuple_Check(pyLi)) - { - int size=PyTuple_Size(pyLi); - for(int i=0;i arr2; - convertPyToNewIntArr4(o,recurseLev-1,nbOfSubPart,arr2); - if(nbOfSubPart>=1 && nbOfSubPart!=(int)arr2.size()) - { - std::ostringstream oss; oss << "convertPyToNewIntArr4 : input list at lev " << recurseLev << " invalid nb of subpart elts expected " << nbOfSubPart << " having " << arr2.size() << " !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - arr.insert(arr.end(),arr2.begin(),arr2.end()); - } - } - } - else - throw INTERP_KERNEL::Exception("convertPyToNewIntArr4 : not a list nor a tuple recursively !"); -} - -static void checkFillArrayWithPyList(int size1, int size2, int& nbOfTuples, int& nbOfComp) throw(INTERP_KERNEL::Exception) -{ - if(nbOfTuples==-1) - { - if(nbOfComp==-1) { nbOfTuples=size1; nbOfComp=size2; } - else { if(nbOfComp==size2) { nbOfTuples=size1; } else - { - std::ostringstream oss; oss << "fillArrayWithPyListDbl2 : mismatch between nb of elemts : Input has " << size1 << " tuples and " << size2 << " components"; - oss << " whereas nb of components expected is " << nbOfComp << " !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } } - } - else - { - if(nbOfComp!=-1) - { - if((nbOfTuples!=size1 || nbOfComp!=size2)) - { - if(size2!=1 || size1!=nbOfComp*nbOfTuples) - { - std::ostringstream oss; oss << "fillArrayWithPyListDbl2 : mismatch between nb of elemts : Input has " << size1 << " tuples and " << size2 << " components"; - oss << " whereas nb of tuples expected is " << nbOfTuples << " and number of components expected is " << nbOfComp << " !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - } - } - else - { - if(nbOfTuples==size1) - nbOfComp=size2; - else - { - std::ostringstream oss; oss << "fillArrayWithPyListDbl2 : mismatch between nb of elemts : Input has " << size1 << " tuples and " << size2 << " components"; - oss << " whereas nb of tuples expected is " << nbOfTuples << " !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - } - } -} - -static void fillArrayWithPyListInt3(PyObject *pyLi, int& nbOfElt, std::vector& ret) -{ - static const char MSG[]="fillArrayWithPyListInt3 : It appears that the input list or tuple is composed by elts having different sizes !"; - if(PyInt_Check(pyLi)) - { - long val=PyInt_AS_LONG(pyLi); - if(nbOfElt==-1) - nbOfElt=1; - else - if(nbOfElt!=1) - throw INTERP_KERNEL::Exception(MSG); - ret.push_back(val); - } - else if(PyList_Check(pyLi)) - { - int size=PyList_Size(pyLi); - int tmp=0; - for(int i=0;i fillArrayWithPyListInt2(PyObject *pyLi, int& nbOfTuples, int& nbOfComp) throw(INTERP_KERNEL::Exception) -{ - std::vector ret; - int size1=-1,size2=-1; - if(PyList_Check(pyLi)) - { - size1=PyList_Size(pyLi); - for(int i=0;i& vec) throw(INTERP_KERNEL::Exception) -{ - if(PyList_Check(pyLi)) - { - Py_ssize_t sz=PyList_Size(pyLi); - vec.resize(sz); - for(int i=0;i >& arr) throw(INTERP_KERNEL::Exception) -{ - const char msg[]="convertPyToVectorOfVectorOfString : expecting list of list of strings !"; - if(PyList_Check(pyLi)) - { - Py_ssize_t sz=PyList_Size(pyLi); - arr.resize(sz); - for(int i=0;i& vec) throw(INTERP_KERNEL::Exception) -{ - if(PyList_Check(pyLi)) - { - Py_ssize_t sz=PyList_Size(pyLi); - vec.resize(sz); - for(int i=0;i >& arr) throw(INTERP_KERNEL::Exception) -{ - const char msg[]="convertPyToVectorOfVectorOfInt : expecting list of list of strings !"; - if(PyList_Check(pyLi)) - { - Py_ssize_t sz=PyList_Size(pyLi); - arr.resize(sz); - for(int i=0;i > >& arr) throw(INTERP_KERNEL::Exception) -{ - const char msg[]="convertPyToVectorPairStringVecString : expecting list of tuples containing each exactly 2 items : one string and one vector of string !"; - if(PyList_Check(pyLi)) - { - Py_ssize_t sz=PyList_Size(pyLi); - arr.resize(sz); - for(int i=0;i > item; - PyObject *o_0=PyTuple_GetItem(o,0); - if(!PyString_Check(o_0)) - throw INTERP_KERNEL::Exception(msg); - item.first=PyString_AsString(o_0); - PyObject *o_1=PyTuple_GetItem(o,1); - if(!fillStringVector(o_1,item.second)) - throw INTERP_KERNEL::Exception(msg); - arr[i]=item; - } - else - throw INTERP_KERNEL::Exception(msg); - } - } - else if(PyTuple_Check(pyLi)) - { - Py_ssize_t sz=PyTuple_Size(pyLi); - arr.resize(sz); - for(int i=0;i > item; - PyObject *o_0=PyTuple_GetItem(o,0); - if(!PyString_Check(o_0)) - throw INTERP_KERNEL::Exception(msg); - item.first=PyString_AsString(o_0); - PyObject *o_1=PyTuple_GetItem(o,1); - if(!fillStringVector(o_1,item.second)) - throw INTERP_KERNEL::Exception(msg); - arr[i]=item; - } - else - throw INTERP_KERNEL::Exception(msg); - } - } - else - throw INTERP_KERNEL::Exception(msg); -} - -static PyObject *convertDblArrToPyList(const double *ptr, int size) throw(INTERP_KERNEL::Exception) -{ - PyObject *ret=PyList_New(size); - for(int i=0;i& v) throw(INTERP_KERNEL::Exception) -{ - int size=v.size(); - PyObject *ret=PyList_New(size); - for(int i=0;i tmp=new char[nbOfComp+1]; tmp[nbOfComp]='\0'; - for(int i=0;i& ret) -{ - static const char MSG[]="fillArrayWithPyListDbl3 : It appears that the input list or tuple is composed by elts having different sizes !"; - if(PyFloat_Check(pyLi)) - { - if(nbOfElt==-1) - nbOfElt=1; - else - if(nbOfElt!=1) - throw INTERP_KERNEL::Exception(MSG); - double val=PyFloat_AS_DOUBLE(pyLi); - ret.push_back(val); - } - else if(PyInt_Check(pyLi)) - { - long val0=PyInt_AS_LONG(pyLi); - double val=val0; - if(nbOfElt==-1) - nbOfElt=1; - else - if(nbOfElt!=1) - throw INTERP_KERNEL::Exception(MSG); - ret.push_back(val); - } - else if(PyList_Check(pyLi)) - { - int size=PyList_Size(pyLi); - int tmp=0; - for(int i=0;i fillArrayWithPyListDbl2(PyObject *pyLi, int& nbOfTuples, int& nbOfComp) throw(INTERP_KERNEL::Exception) -{ - std::vector ret; - int size1=-1,size2=-1; - if(PyList_Check(pyLi)) - { - size1=PyList_Size(pyLi); - for(int i=0;i(pyLi,SWIGTYPE_p_ParaMEDMEM__MEDCouplingUMesh,"MEDCouplingUMesh") -template -static void convertFromPyObjVectorOfObj(PyObject *pyLi, swig_type_info *ty, const char *typeStr, typename std::vector& ret) -{ - void *argp=0; - if(PyList_Check(pyLi)) - { - int size=PyList_Size(pyLi); - ret.resize(size); - for(int i=0;i(argp); - ret[i]=arg; - } - } - else if(PyTuple_Check(pyLi)) - { - int size=PyTuple_Size(pyLi); - ret.resize(size); - for(int i=0;i(argp); - ret[i]=arg; - } - } - else if(SWIG_IsOK(SWIG_ConvertPtr(pyLi,&argp,ty,0|0))) - { - ret.resize(1); - T arg=reinterpret_cast< T >(argp); - ret[0]=arg; - } - else - throw INTERP_KERNEL::Exception("convertFromPyObjVectorOfObj : not a list nor a tuple"); -} - -/*! - * if python int -> cpp int sw=1 - * if python list[int] -> cpp vector sw=2 - * if python tuple[int] -> cpp vector sw=2 - * if python DataArrayInt -> cpp DataArrayInt sw=3 - * if python DataArrayIntTuple -> cpp DataArrayIntTuple sw=4 - * - * switch between (int,vector,DataArrayInt) - */ -static void convertObjToPossibleCpp1(PyObject *value, int& sw, int& iTyypp, std::vector& stdvecTyypp, ParaMEDMEM::DataArrayInt *& daIntTyypp, ParaMEDMEM::DataArrayIntTuple *&daIntTuple) throw(INTERP_KERNEL::Exception) -{ - sw=-1; - if(PyInt_Check(value)) - { - iTyypp=(int)PyInt_AS_LONG(value); - sw=1; - return; - } - if(PyTuple_Check(value)) - { - int size=PyTuple_Size(value); - stdvecTyypp.resize(size); - for(int i=0;i(argp); - sw=3; - return; - } - status=SWIG_ConvertPtr(value,&argp,SWIGTYPE_p_ParaMEDMEM__DataArrayIntTuple,0|0); - if(SWIG_IsOK(status)) - { - daIntTuple=reinterpret_cast< ParaMEDMEM::DataArrayIntTuple * >(argp); - sw=4; - return ; - } - throw INTERP_KERNEL::Exception("5 types accepted : integer, tuple of integer, list of integer, DataArrayInt, DataArrayIntTuple"); -} - -/*! - * if python double -> cpp double sw=1 - * if python int -> cpp double sw=1 - * if python list[double] -> cpp vector sw=2 - * if python list[int] -> cpp vector sw=2 - * if python tuple[double] -> cpp vector sw=2 - * if python tuple[int] -> cpp vector sw=2 - * if python DataArrayDouble -> cpp DataArrayDouble sw=3 - * - * switch between (int,vector,DataArrayInt) - */ -static void convertObjToPossibleCpp4(PyObject *value, int& sw, double& iTyypp, std::vector& stdvecTyypp, ParaMEDMEM::DataArrayDouble *& daIntTyypp) throw(INTERP_KERNEL::Exception) -{ - sw=-1; - if(PyFloat_Check(value)) - { - iTyypp=PyFloat_AS_DOUBLE(value); - sw=1; - return; - } - if(PyInt_Check(value)) - { - iTyypp=(double)PyInt_AS_LONG(value); - sw=1; - return; - } - if(PyTuple_Check(value)) - { - int size=PyTuple_Size(value); - stdvecTyypp.resize(size); - for(int i=0;i(argp); - sw=3; -} - -/*! - * if python double -> cpp double sw=1 - * if python int -> cpp double sw=1 - * if python list[double] -> cpp vector sw=2 - * if python list[int] -> cpp vector sw=2 - * if python tuple[double] -> cpp vector sw=2 - * if python tuple[int] -> cpp vector sw=2 - * if python DataArrayDoubleTuple -> cpp DataArrayDoubleTuple sw=3 - * - * switch between (int,vector,DataArrayInt) - */ -static void convertObjToPossibleCpp44(PyObject *value, int& sw, double& iTyypp, std::vector& stdvecTyypp, ParaMEDMEM::DataArrayDoubleTuple *& daIntTyypp) throw(INTERP_KERNEL::Exception) -{ - sw=-1; - if(PyFloat_Check(value)) - { - iTyypp=PyFloat_AS_DOUBLE(value); - sw=1; - return; - } - if(PyInt_Check(value)) - { - iTyypp=(double)PyInt_AS_LONG(value); - sw=1; - return; - } - if(PyTuple_Check(value)) - { - int size=PyTuple_Size(value); - stdvecTyypp.resize(size); - for(int i=0;i(argp); - sw=3; -} - -/*! - * if python int -> cpp int sw=1 - * if python list[int] -> cpp vector sw=2 - * if python tuple[int] -> cpp vector sw=2 - * if python slicp -> cpp pair sw=3 (begin,end,step) - * if python DataArrayInt -> cpp DataArrayInt sw=4 . The returned pointer cannot be the null pointer ! If null an exception is thrown. - * - * switch between (int,vector,DataArrayInt) - */ -static void convertObjToPossibleCpp2(PyObject *value, int nbelem, int& sw, int& iTyypp, std::vector& stdvecTyypp, std::pair >& p, ParaMEDMEM::DataArrayInt *& daIntTyypp) throw(INTERP_KERNEL::Exception) -{ - const char *msg="5 types accepted : integer, tuple of integer, list of integer, slice, DataArrayInt, DataArrayIntTuple"; - sw=-1; - if(PyInt_Check(value)) - { - iTyypp=(int)PyInt_AS_LONG(value); - sw=1; - return; - } - if(PyTuple_Check(value)) - { - int size=PyTuple_Size(value); - stdvecTyypp.resize(size); - for(int i=0;i(value); - GetIndicesOfSlice(oC,nbelem,&strt,&stp,&step,"Slice in subscriptable object DataArray invalid !"); - p.first=strt; - p.second.first=stp; - p.second.second=step; - sw=3; - return ; - } - void *argp; - int status=SWIG_ConvertPtr(value,&argp,SWIGTYPE_p_ParaMEDMEM__DataArrayInt,0|0); - if(SWIG_IsOK(status)) - { - daIntTyypp=reinterpret_cast< ParaMEDMEM::DataArrayInt * >(argp); - if(!daIntTyypp) - { - std::ostringstream oss; oss << msg << " Instance in null !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - sw=4; - return ; - } - status=SWIG_ConvertPtr(value,&argp,SWIGTYPE_p_ParaMEDMEM__DataArrayIntTuple,0|0); - if(SWIG_IsOK(status)) - { - ParaMEDMEM::DataArrayIntTuple *tmp=reinterpret_cast< ParaMEDMEM::DataArrayIntTuple * >(argp); - if(!tmp) - { - std::ostringstream oss; oss << msg << " Instance in null !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - stdvecTyypp.resize(tmp->getNumberOfCompo()); - std::copy(tmp->getConstPointer(),tmp->getConstPointer()+tmp->getNumberOfCompo(),stdvecTyypp.begin()); - sw=2; - return ; - } - throw INTERP_KERNEL::Exception(msg); -} - -/*! - * Idem than convertObjToPossibleCpp2 - */ -static void convertObjToPossibleCpp2WithNegIntInterp(PyObject *value, int nbelem, int& sw, int& iTyypp, std::vector& stdvecTyypp, std::pair >& p, ParaMEDMEM::DataArrayInt *& daIntTyypp) throw(INTERP_KERNEL::Exception) -{ - convertObjToPossibleCpp2(value,nbelem,sw,iTyypp,stdvecTyypp,p,daIntTyypp); - if(sw==1) - { - iTyypp=InterpreteNegativeInt(iTyypp,nbelem); - } -} - -/*! - * if python int -> cpp int sw=1 - * if python tuple[int] -> cpp vector sw=2 - * if python list[int] -> cpp vector sw=2 - * if python slice -> cpp pair sw=3 - * if python DataArrayIntTuple -> cpp DataArrayIntTuple sw=4 . WARNING The returned pointer can be the null pointer ! - */ -static void convertObjToPossibleCpp22(PyObject *value, int nbelem, int& sw, int& iTyypp, std::vector& stdvecTyypp, std::pair >& p, ParaMEDMEM::DataArrayIntTuple *& daIntTyypp) throw(INTERP_KERNEL::Exception) -{ - sw=-1; - if(PyInt_Check(value)) - { - iTyypp=(int)PyInt_AS_LONG(value); - sw=1; - return; - } - if(PyTuple_Check(value)) - { - int size=PyTuple_Size(value); - stdvecTyypp.resize(size); - for(int i=0;i(value); - GetIndicesOfSlice(oC,nbelem,&strt,&stp,&step,"Slice in subscriptable object DataArray invalid !"); - p.first=strt; - p.second.first=stp; - p.second.second=step; - sw=3; - return ; - } - void *argp; - int status=SWIG_ConvertPtr(value,&argp,SWIGTYPE_p_ParaMEDMEM__DataArrayIntTuple,0|0); - if(!SWIG_IsOK(status)) - throw INTERP_KERNEL::Exception("4 types accepted : integer, tuple of integer, list of integer, slice, DataArrayIntTuple"); - daIntTyypp=reinterpret_cast< ParaMEDMEM::DataArrayIntTuple * >(argp); - sw=4; -} - -/*! - * if python string with size one -> cpp char sw=1 - * if python string with size different from one -> cpp string sw=2 - * if python tuple[string] or list[string] -> vector sw=3 - * if python not null pointer of DataArrayChar -> cpp DataArrayChar sw=4 - * switch between (int,string,vector,DataArrayChar) - */ -static void convertObjToPossibleCpp6(PyObject *value, int& sw, char& cTyp, std::string& sType, std::vector& vsType, ParaMEDMEM::DataArrayChar *& dacType) throw(INTERP_KERNEL::Exception) -{ - const char *msg="4 types accepted : string, list or tuple of strings having same size, not null DataArrayChar instance."; - sw=-1; - if(PyString_Check(value)) - { - const char *pt=PyString_AsString(value); - Py_ssize_t sz=PyString_Size(value); - if(sz==1) - { - cTyp=pt[0]; - sw=1; - return; - } - else - { - sType=pt; - sw=2; - return; - } - } - if(PyTuple_Check(value)) - { - int size=PyTuple_Size(value); - vsType.resize(size); - for(int i=0;i(argp); - if(!dacType) - { - std::ostringstream oss; oss << msg << " Instance in null !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - sw=4; - return ; - } - throw INTERP_KERNEL::Exception(msg); -} - -/*! - * if value int -> cpp it sw=1 - * if value list[int] -> vt sw=2 - * if value tuple[int] -> vt sw=2 - * if value slice -> pt sw=3 - * if value DataArrayInt -> dt sw=4 - * if value tuple [int,int] -> cpp it,ip sw=5 - * if value tuple [list[int],int] -> cpp vt,ip sw=6 - * if value tuple [tuple[int],int] -> cpp vt,ip sw=6 - * if value tuple [slice,int] -> cpp pt,ip sw=7 - * if value tuple [DaI,int] -> cpp dt,ip sw=8 - * if value tuple [int,list[int]] -> cpp it,vc sw=9 - * if value tuple [list[int],list[int]] -> cpp vt,vc sw=10 - * if value tuple [tuple[int],list[int]] -> cpp vt,vc sw=10 - * if value tuple [slice,list[int]] -> cpp pt,vc sw=11 - * if value tuple [DaI,list[int]] -> cpp dt,vc sw=12 - * if value tuple [int,tuple[int]] -> cpp it,vc sw=9 - * if value tuple [list[int],tuple[int]] -> cpp vt,vc sw=10 - * if value tuple [tuple[int],tuple[int]] -> cpp vt,vc sw=10 - * if value tuple [slice,tuple[int]] -> cpp pt,vc sw=11 - * if value tuple [DaI,tuple[int]] -> cpp dt,vc sw=12 - * if value tuple [int,slice] -> cpp it,pc sw=13 - * if value tuple [list[int],slice] -> cpp vt,pc sw=14 - * if value tuple [tuple[int],slice] -> cpp vt,pc sw=14 - * if value tuple [slice,slice] -> cpp pt,pc sw=15 - * if value tuple [DaI,slice] -> cpp dt,pc sw=16 - * - * switch between (int,vector,DataArrayInt) - */ -static void convertObjToPossibleCpp3(PyObject *value, int nbTuple, int nbCompo, int& sw, int& it, int& ic, std::vector& vt, std::vector& vc, - std::pair >& pt, std::pair >& pc, - ParaMEDMEM::DataArrayInt *&dt, ParaMEDMEM::DataArrayInt *&dc) throw(INTERP_KERNEL::Exception) -{ - if(!PyTuple_Check(value)) - { - convertObjToPossibleCpp2WithNegIntInterp(value,nbTuple,sw,it,vt,pt,dt); - return ; - } - else - { - int sz=PyTuple_Size(value); - if(sz!=2) - throw INTERP_KERNEL::Exception("Unexpected nb of slice element : 1 or 2 expected !\n1st is for tuple selection, 2nd for component selection !"); - PyObject *ob0=PyTuple_GetItem(value,0); - int sw1,sw2; - convertObjToPossibleCpp2WithNegIntInterp(ob0,nbTuple,sw1,it,vt,pt,dt); - PyObject *ob1=PyTuple_GetItem(value,1); - convertObjToPossibleCpp2WithNegIntInterp(ob1,nbCompo,sw2,ic,vc,pc,dc); - sw=4*sw2+sw1; - } -} - -/*! - * if value int -> cpp val sw=1 - * if value double -> cpp val sw=1 - * if value DataArrayDouble -> cpp DataArrayDouble sw=2 - * if value DataArrayDoubleTuple -> cpp DataArrayDoubleTuple sw=3 - * if value list[int,double] -> cpp std::vector sw=4 - * if value tuple[int,double] -> cpp std::vector sw=4 - */ -static void convertObjToPossibleCpp5(PyObject *value, int& sw, double& val, ParaMEDMEM::DataArrayDouble *&d, ParaMEDMEM::DataArrayDoubleTuple *&e, std::vector& f) -{ - sw=-1; - if(PyFloat_Check(value)) - { - val=PyFloat_AS_DOUBLE(value); - sw=1; - return; - } - if(PyInt_Check(value)) - { - val=(double)PyInt_AS_LONG(value); - sw=1; - return; - } - if(PyTuple_Check(value)) - { - int size=PyTuple_Size(value); - f.resize(size); - for(int i=0;i(argp); - sw=2; - return ; - } - status=SWIG_ConvertPtr(value,&argp,SWIGTYPE_p_ParaMEDMEM__DataArrayDoubleTuple,0|0); - if(SWIG_IsOK(status)) - { - e=reinterpret_cast< ParaMEDMEM::DataArrayDoubleTuple * >(argp); - sw=3; - return ; - } - throw INTERP_KERNEL::Exception("4 types accepted : integer, double, DataArrayDouble, DataArrayDoubleTuple"); -} - -/*! - * if value int -> cpp val sw=1 - * if value double -> cpp val sw=1 - * if value DataArrayDouble -> cpp DataArrayDouble sw=2 - * if value DataArrayDoubleTuple -> cpp DataArrayDoubleTuple sw=3 - * if value list[int,double] -> cpp std::vector sw=4 - * if value tuple[int,double] -> cpp std::vector sw=4 - */ -static const double *convertObjToPossibleCpp5_Safe(PyObject *value, int& sw, double& val, ParaMEDMEM::DataArrayDouble *&d, ParaMEDMEM::DataArrayDoubleTuple *&e, std::vector& f, - const char *msg, int nbTuplesExpected, int nbCompExpected, bool throwIfNullPt) throw(INTERP_KERNEL::Exception) -{ - sw=-1; - if(PyFloat_Check(value)) - { - val=PyFloat_AS_DOUBLE(value); - sw=1; - if(nbTuplesExpected*nbCompExpected!=1) - { - std::ostringstream oss; oss << msg << "dimension expected to be " << nbTuplesExpected*nbCompExpected << " , and your data in input has dimension one (single PyFloat) !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - return &val; - } - if(PyInt_Check(value)) - { - val=(double)PyInt_AS_LONG(value); - sw=1; - if(nbTuplesExpected*nbCompExpected!=1) - { - std::ostringstream oss; oss << msg << "dimension expected to be " << nbTuplesExpected*nbCompExpected << " , and your data in input has dimension one (single PyInt) !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - return &val; - } - if(PyTuple_Check(value) || PyList_Check(value)) - { - try - { - int tmp1=nbTuplesExpected,tmp2=nbCompExpected; - std::vector ret=fillArrayWithPyListDbl2(value,tmp1,tmp2); - sw=4; - f=ret; - return &f[0]; - } - catch(INTERP_KERNEL::Exception& exc) { throw exc; } - } - void *argp; - int status=SWIG_ConvertPtr(value,&argp,SWIGTYPE_p_ParaMEDMEM__DataArrayDouble,0|0); - if(SWIG_IsOK(status)) - { - d=reinterpret_cast< ParaMEDMEM::DataArrayDouble * >(argp); - sw=2; - if(d) - { - if(d->getNumberOfTuples()==nbTuplesExpected) - { - if(d->getNumberOfComponents()==nbCompExpected) - { - return d->getConstPointer(); - } - else - { - std::ostringstream oss; oss << msg << "nb of components expected to be " << nbCompExpected << " , and input has " << d->getNumberOfComponents() << " components !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - } - else - { - std::ostringstream oss; oss << msg << " input DataArrayDouble should have a number of tuples equal to " << nbTuplesExpected << " and there are " << d->getNumberOfTuples() << " tuples !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - } - else - { - if(throwIfNullPt) - { - std::ostringstream oss; oss << msg << " null pointer not accepted!"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - else - return 0; - } - } - status=SWIG_ConvertPtr(value,&argp,SWIGTYPE_p_ParaMEDMEM__DataArrayDoubleTuple,0|0); - if(SWIG_IsOK(status)) - { - e=reinterpret_cast< ParaMEDMEM::DataArrayDoubleTuple * >(argp); - sw=3; - if(e->getNumberOfCompo()==nbCompExpected) - { - if(nbTuplesExpected==1) - return e->getConstPointer(); - else - { - std::ostringstream oss; oss << msg << "nb of tuples expected to be " << nbTuplesExpected << " , and input DataArrayDoubleTuple has always one tuple by contruction !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - } - else - { - std::ostringstream oss; oss << msg << "nb of components expected to be " << nbCompExpected << " , and input DataArrayDoubleTuple has " << e->getNumberOfCompo() << " components !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - } - throw INTERP_KERNEL::Exception("4 types accepted : integer, double, DataArrayDouble, DataArrayDoubleTuple"); -} - -/*! - * if value int -> cpp val sw=1 - * if value double -> cpp val sw=1 - * if value DataArrayDouble -> cpp DataArrayDouble sw=2 - * if value DataArrayDoubleTuple -> cpp DataArrayDoubleTuple sw=3 - * if value list[int,double] -> cpp std::vector sw=4 - * if value tuple[int,double] -> cpp std::vector sw=4 - */ -static const double *convertObjToPossibleCpp5_Safe2(PyObject *value, int& sw, double& val, ParaMEDMEM::DataArrayDouble *&d, ParaMEDMEM::DataArrayDoubleTuple *&e, std::vector& f, - const char *msg, int nbCompExpected, bool throwIfNullPt, int& nbTuples) throw(INTERP_KERNEL::Exception) -{ - sw=-1; - if(PyFloat_Check(value)) - { - val=PyFloat_AS_DOUBLE(value); - sw=1; - if(nbCompExpected!=1) - { - std::ostringstream oss; oss << msg << "dimension expected to be " << nbCompExpected << " , and your data in input has dimension one (single PyFloat) !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - nbTuples=1; - return &val; - } - if(PyInt_Check(value)) - { - val=(double)PyInt_AS_LONG(value); - sw=1; - if(nbCompExpected!=1) - { - std::ostringstream oss; oss << msg << "dimension expected to be " << nbCompExpected << " , and your data in input has dimension one (single PyInt) !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - nbTuples=1; - return &val; - } - if(PyTuple_Check(value)) - { - int size=PyTuple_Size(value); - f.resize(size); - for(int i=0;i(argp); - sw=2; - if(d) - { - if(d->getNumberOfComponents()==nbCompExpected) - { - nbTuples=d->getNumberOfTuples(); - return d->getConstPointer(); - } - else - { - std::ostringstream oss; oss << msg << "nb of components expected to be a multiple of " << nbCompExpected << " , and input has " << d->getNumberOfComponents() << " components !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - } - else - { - if(throwIfNullPt) - { - std::ostringstream oss; oss << msg << " null pointer not accepted!"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - else - { nbTuples=0; return 0; } - } - } - status=SWIG_ConvertPtr(value,&argp,SWIGTYPE_p_ParaMEDMEM__DataArrayDoubleTuple,0|0); - if(SWIG_IsOK(status)) - { - e=reinterpret_cast< ParaMEDMEM::DataArrayDoubleTuple * >(argp); - sw=3; - if(e) - { - if(e->getNumberOfCompo()==nbCompExpected) - { - nbTuples=1; - return e->getConstPointer(); - } - else - { - std::ostringstream oss; oss << msg << "nb of components expected to be " << nbCompExpected << " , and input DataArrayDoubleTuple has " << e->getNumberOfCompo() << " components !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - } - else - { - if(throwIfNullPt) - { - std::ostringstream oss; oss << msg << " null pointer not accepted!"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - else - { nbTuples=0; return 0; } - } - } - throw INTERP_KERNEL::Exception("4 types accepted : integer, double, DataArrayDouble, DataArrayDoubleTuple"); -} - -/*! - * if value int -> cpp val sw=1 - * if value double -> cpp val sw=1 - * if value DataArrayDouble -> cpp DataArrayDouble sw=2 - * if value DataArrayDoubleTuple -> cpp DataArrayDoubleTuple sw=3 - * if value list[int,double] -> cpp std::vector sw=4 - * if value tuple[int,double] -> cpp std::vector sw=4 - */ -static const double *convertObjToPossibleCpp5_SingleCompo(PyObject *value, int& sw, double& val, std::vector& f, - const char *msg, bool throwIfNullPt, int& nbTuples) throw(INTERP_KERNEL::Exception) -{ - ParaMEDMEM::DataArrayDouble *d=0; - ParaMEDMEM::DataArrayDoubleTuple *e=0; - sw=-1; - if(PyFloat_Check(value)) - { - val=PyFloat_AS_DOUBLE(value); - sw=1; - nbTuples=1; - return &val; - } - if(PyInt_Check(value)) - { - val=(double)PyInt_AS_LONG(value); - sw=1; - nbTuples=1; - return &val; - } - if(PyTuple_Check(value)) - { - int size=PyTuple_Size(value); - f.resize(size); - for(int i=0;i(argp); - sw=2; - if(d) - { - if(d->getNumberOfComponents()==1) - { - nbTuples=d->getNumberOfTuples(); - return d->getConstPointer(); - } - else - { - std::ostringstream oss; oss << msg << "nb of components expected to be one, and input has " << d->getNumberOfComponents() << " components !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - } - else - { - if(throwIfNullPt) - { - std::ostringstream oss; oss << msg << " null pointer not accepted!"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - else - { nbTuples=0; return 0; } - } - } - status=SWIG_ConvertPtr(value,&argp,SWIGTYPE_p_ParaMEDMEM__DataArrayDoubleTuple,0|0); - if(SWIG_IsOK(status)) - { - e=reinterpret_cast< ParaMEDMEM::DataArrayDoubleTuple * >(argp); - sw=3; - if(e) - { - nbTuples=e->getNumberOfCompo(); - return e->getConstPointer(); - } - else - { - if(throwIfNullPt) - { - std::ostringstream oss; oss << msg << " null pointer not accepted!"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - else - { nbTuples=0; return 0; } - } - } - throw INTERP_KERNEL::Exception("4 types accepted : integer, double, DataArrayDouble, DataArrayDoubleTuple"); -} - -/*! - * if python int -> cpp int sw=1 - * if python list[int] -> cpp vector sw=2 - * if python tuple[int] -> cpp vector sw=2 - * if python DataArrayInt -> cpp DataArrayInt sw=3 - * if python DataArrayIntTuple -> cpp DataArrayIntTuple sw=4 - * - * switch between (int,vector,DataArrayInt) - */ -static const int *convertObjToPossibleCpp1_Safe(PyObject *value, int& sw, int& sz, int& iTyypp, std::vector& stdvecTyypp) throw(INTERP_KERNEL::Exception) -{ - sw=-1; - if(PyInt_Check(value)) - { - iTyypp=(int)PyInt_AS_LONG(value); - sw=1; sz=1; - return &iTyypp; - } - if(PyTuple_Check(value)) - { - int size=PyTuple_Size(value); - stdvecTyypp.resize(size); - for(int i=0;i(argp); - if(daIntTyypp) - { - sw=3; sz=daIntTyypp->getNbOfElems(); - return daIntTyypp->begin(); - } - else - { - sz=0; - return 0; - } - } - status=SWIG_ConvertPtr(value,&argp,SWIGTYPE_p_ParaMEDMEM__DataArrayIntTuple,0|0); - if(SWIG_IsOK(status)) - { - ParaMEDMEM::DataArrayIntTuple *daIntTuple=reinterpret_cast< ParaMEDMEM::DataArrayIntTuple * >(argp); - sw=4; sz=daIntTuple->getNumberOfCompo(); - return daIntTuple->getConstPointer(); - } - throw INTERP_KERNEL::Exception("5 types accepted : integer, tuple of integer, list of integer, DataArrayInt, DataArrayIntTuple"); -} - -static ParaMEDMEM::DataArray *CheckAndRetrieveDataArrayInstance(PyObject *obj, const char *msg) -{ - void *aBasePtrVS=0; - int status=SWIG_ConvertPtr(obj,&aBasePtrVS,SWIGTYPE_p_ParaMEDMEM__DataArray,0|0); - if(!SWIG_IsOK(status)) - { - status=SWIG_ConvertPtr(obj,&aBasePtrVS,SWIGTYPE_p_ParaMEDMEM__DataArrayDouble,0|0); - if(!SWIG_IsOK(status)) - { - status=SWIG_ConvertPtr(obj,&aBasePtrVS,SWIGTYPE_p_ParaMEDMEM__DataArrayInt,0|0); - if(!SWIG_IsOK(status)) - { - status=SWIG_ConvertPtr(obj,&aBasePtrVS,SWIGTYPE_p_ParaMEDMEM__DataArrayAsciiChar,0|0); - if(!SWIG_IsOK(status)) - { - status=SWIG_ConvertPtr(obj,&aBasePtrVS,SWIGTYPE_p_ParaMEDMEM__DataArrayByte,0|0); - std::ostringstream oss; oss << msg << " ! Accepted instances are DataArrayDouble, DataArrayInt, DataArrayAsciiChar, DataArrayByte !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - } - } - } - return reinterpret_cast< ParaMEDMEM::DataArray * >(aBasePtrVS); -} diff --git a/src/MEDCoupling_Swig/MEDCouplingDataForTest.py b/src/MEDCoupling_Swig/MEDCouplingDataForTest.py deleted file mode 100644 index f88aad244..000000000 --- a/src/MEDCoupling_Swig/MEDCouplingDataForTest.py +++ /dev/null @@ -1,756 +0,0 @@ -# -*- coding: iso-8859-1 -*- -# Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 -# 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 -# - -from MEDCoupling import * - -class MEDCouplingDataForTest: - def build2DTargetMesh_1(cls): - targetCoords=[-0.3,-0.3, 0.2,-0.3, 0.7,-0.3, -0.3,0.2, 0.2,0.2, 0.7,0.2, -0.3,0.7, 0.2,0.7, 0.7,0.7 ]; - targetConn=[0,3,4,1, 1,4,2, 4,5,2, 6,7,4,3, 7,8,5,4]; - targetMesh=MEDCouplingUMesh.New(); - targetMesh.setMeshDimension(2); - targetMesh.allocateCells(5); - targetMesh.insertNextCell(NORM_QUAD4,4,targetConn[0:4]); - targetMesh.insertNextCell(NORM_TRI3,3,targetConn[4:7]); - targetMesh.insertNextCell(NORM_TRI3,3,targetConn[7:10]); - targetMesh.insertNextCell(NORM_QUAD4,4,targetConn[10:14]); - targetMesh.insertNextCell(NORM_QUAD4,4,targetConn[14:18]); - targetMesh.finishInsertingCells(); - myCoords=DataArrayDouble.New(); - myCoords.setValues(targetCoords,9,2); - targetMesh.setCoords(myCoords); - return targetMesh; - - def build2DSourceMesh_1(cls): - sourceCoords=[-0.3,-0.3, 0.7,-0.3, -0.3,0.7, 0.7,0.7] - sourceConn=[0,3,1,0,2,3] - sourceMesh=MEDCouplingUMesh.New("my name of mesh 2D",2); - sourceMesh.allocateCells(2); - sourceMesh.insertNextCell(NORM_TRI3,3,sourceConn[0:3]); - sourceMesh.insertNextCell(NORM_TRI3,3,sourceConn[3:6]); - sourceMesh.finishInsertingCells(); - myCoords=DataArrayDouble.New(); - myCoords.setValues(sourceCoords,4,2); - sourceMesh.setCoords(myCoords); - return sourceMesh; - - def build3DTargetMesh_1(cls): - targetCoords=[ 0., 0., 0., 50., 0., 0. , 200., 0., 0. , 0., 50., 0., 50., 50., 0. , 200., 50., 0., 0., 200., 0., 50., 200., 0. , 200., 200., 0. , - 0., 0., 50., 50., 0., 50. , 200., 0., 50. , 0., 50., 50., 50., 50., 50. , 200., 50., 50., 0., 200., 50., 50., 200., 50. , 200., 200., 50. , - 0., 0., 200., 50., 0., 200. , 200., 0., 200. , 0., 50., 200., 50., 50., 200. , 200., 50., 200., 0., 200., 200., 50., 200., 200. , 200., 200., 200. ]; - targetConn=[0,1,4,3,9,10,13,12, 1,2,5,4,10,11,14,13, 3,4,7,6,12,13,16,15, 4,5,8,7,13,14,17,16, - 9,10,13,12,18,19,22,21, 10,11,14,13,19,20,23,22, 12,13,16,15,21,22,25,24, 13,14,17,16,22,23,26,25]; - targetMesh=MEDCouplingUMesh.New(); - targetMesh.setMeshDimension(3); - targetMesh.allocateCells(12); - for i in xrange(8): - targetMesh.insertNextCell(NORM_HEXA8,8,targetConn[8*i:8*i+8]); - pass - targetMesh.finishInsertingCells(); - myCoords=DataArrayDouble.New(); - myCoords.setValues(targetCoords,27,3); - targetMesh.setCoords(myCoords); - return targetMesh - - def build3DSourceMesh_1(self): - sourceCoords=[ 0.0, 0.0, 200.0, 0.0, 0.0, 0.0, 0.0, 200.0, 200.0, 0.0, 200.0, 0.0, 200.0, 0.0, 200.0, - 200.0, 0.0, 0.0, 200.0, 200.0, 200.0, 200.0, 200.0, 0.0, 100.0, 100.0, 100.0] - sourceConn=[8,1,7,3, 6,0,8,2, 7,4,5,8, 6,8,4,7, 6,8,0,4, 6,8,7,3, 8,1,3,0, 4,1,5,8, 1,7,5,8, 0,3,8,2, 8,1,0,4, 3,6,8,2] - sourceMesh=MEDCouplingUMesh.New(); - sourceMesh.setMeshDimension(3); - sourceMesh.allocateCells(12); - sourceMesh.insertNextCell(NORM_TETRA4,4,sourceConn[0:4]) - sourceMesh.insertNextCell(NORM_TETRA4,4,sourceConn[4:8]) - sourceMesh.insertNextCell(NORM_TETRA4,4,sourceConn[8:12]) - sourceMesh.insertNextCell(NORM_TETRA4,4,sourceConn[12:16]) - sourceMesh.insertNextCell(NORM_TETRA4,4,sourceConn[16:20]) - sourceMesh.insertNextCell(NORM_TETRA4,4,sourceConn[20:24]) - sourceMesh.insertNextCell(NORM_TETRA4,4,sourceConn[24:28]) - sourceMesh.insertNextCell(NORM_TETRA4,4,sourceConn[28:32]) - sourceMesh.insertNextCell(NORM_TETRA4,4,sourceConn[32:36]) - sourceMesh.insertNextCell(NORM_TETRA4,4,sourceConn[36:40]) - sourceMesh.insertNextCell(NORM_TETRA4,4,sourceConn[40:44]) - sourceMesh.insertNextCell(NORM_TETRA4,4,sourceConn[44:48]) - sourceMesh.finishInsertingCells(); - myCoords=DataArrayDouble.New(); - myCoords.setValues(sourceCoords,9,3); - sourceMesh.setCoords(myCoords); - return sourceMesh; - - - def build3DSurfTargetMesh_1(self): - targetCoords=[-0.3,-0.3,0.5, 0.2,-0.3,1., 0.7,-0.3,1.5, -0.3,0.2,0.5, 0.2,0.2,1., 0.7,0.2,1.5, -0.3,0.7,0.5, 0.2,0.7,1., 0.7,0.7,1.5] - targetConn=[0,3,4,1, 1,4,2, 4,5,2, 6,7,4,3, 7,8,5,4] - targetMesh=MEDCouplingUMesh.New(); - targetMesh.setMeshDimension(2); - targetMesh.allocateCells(5); - targetMesh.insertNextCell(NORM_QUAD4,4,targetConn[0:4]) - targetMesh.insertNextCell(NORM_TRI3,3,targetConn[4:7]) - targetMesh.insertNextCell(NORM_TRI3,3,targetConn[7:10]) - targetMesh.insertNextCell(NORM_QUAD4,4,targetConn[10:14]) - targetMesh.insertNextCell(NORM_QUAD4,4,targetConn[14:18]) - targetMesh.finishInsertingCells(); - myCoords=DataArrayDouble.New(); - myCoords.setValues(targetCoords,9,3); - targetMesh.setCoords(myCoords); - return targetMesh; - - def build3DExtrudedUMesh_1(self): - coords=[ - 0.,0.,0., 1.,1.,0., 1.,1.25,0., 1.,0.,0., 1.,1.5,0., 2.,0.,0., 2.,1.,0., 1.,2.,0., 0.,2.,0., 3.,1.,0., - 3.,2.,0., 0.,1.,0., 1.,3.,0., 2.,2.,0., 2.,3.,0., - 0.,0.,1., 1.,1.,1., 1.,1.25,1., 1.,0.,1., 1.,1.5,1., 2.,0.,1., 2.,1.,1., 1.,2.,1., 0.,2.,1., 3.,1.,1., - 3.,2.,1., 0.,1.,1., 1.,3.,1., 2.,2.,1., 2.,3.,1., - 0.,0.,2., 1.,1.,2., 1.,1.25,2., 1.,0.,2., 1.,1.5,2., 2.,0.,2., 2.,1.,2., 1.,2.,2., 0.,2.,2., 3.,1.,2., - 3.,2.,2., 0.,1.,2., 1.,3.,2., 2.,2.,2., 2.,3.,2., - 0.,0.,3., 1.,1.,3., 1.,1.25,3., 1.,0.,3., 1.,1.5,3., 2.,0.,3., 2.,1.,3., 1.,2.,3., 0.,2.,3., 3.,1.,3., - 3.,2.,3., 0.,1.,3., 1.,3.,3., 2.,2.,3., 2.,3.,3.] - - conn=[ - # 0 - 0,11,1,3,15,26,16,18, 1,2,4,7,13,6,-1,1,16,21,6,-1,6,21,28,13,-1,13,7,22,28,-1,7,4,19,22,-1,4,2,17,19,-1,2,1,16,17,-1,16,21,28,22,19,17, - 1,6,5,3,16,21,20,18, 13,10,9,6,28,25,24,21, - 11,8,7,4,2,1,-1,11,26,16,1,-1,1,16,17,2,-1,2,17,19,4,-1,4,19,22,7,-1,7,8,23,22,-1,8,11,26,23,-1,26,16,17,19,22,23, - 7,12,14,13,22,27,29,28, - # 1 - 15,26,16,18,30,41,31,33, 16,17,19,22,28,21,-1,16,31,36,21,-1,21,36,43,28,-1,28,22,37,43,-1,22,19,34,37,-1,19,17,32,34,-1,17,16,31,32,-1,31,36,43,37,34,32, - 16,21,20,18,31,36,35,33, 28,25,24,21,43,40,39,36, - 26,23,22,19,17,16,-1,26,41,31,16,-1,16,31,32,17,-1,17,32,34,19,-1,19,34,37,22,-1,22,23,38,37,-1,23,26,41,38,-1,41,31,32,34,37,38, - 22,27,29,28,37,42,44,43, - # 2 - 30,41,31,33,45,56,46,48, 31,32,34,37,43,36,-1,31,46,51,36,-1,36,51,58,43,-1,43,37,52,58,-1,37,34,49,52,-1,34,32,47,49,-1,32,31,46,47,-1,46,51,58,52,49,47, - 31,36,35,33,46,51,50,48, 43,40,39,36,58,55,54,51, - 41,38,37,34,32,31,-1,41,56,46,31,-1,31,46,47,32,-1,32,47,49,34,-1,34,49,52,37,-1,37,38,53,52,-1,38,41,56,53,-1,56,46,47,49,52,53, - 37,42,44,43,52,57,59,58] - conn2=[7,12,14,13, 11,8,7,4,2,1, 13,10,9,6, 1,6,5,3, 1,2,4,7,13,6, 0,11,1,3] - # - ret=MEDCouplingUMesh.New(); - ret.setMeshDimension(3); - ret.allocateCells(18); - # - ret.insertNextCell(NORM_HEXA8,8,conn[0:8]); - ret.insertNextCell(NORM_POLYHED,43,conn[8:51]); - ret.insertNextCell(NORM_HEXA8,8,conn[51:59]); - ret.insertNextCell(NORM_HEXA8,8,conn[59:67]); - ret.insertNextCell(NORM_POLYHED,43,conn[67:110]); - ret.insertNextCell(NORM_HEXA8,8,conn[110:118]); - # - ret.insertNextCell(NORM_HEXA8,8,conn[118:126]); - ret.insertNextCell(NORM_POLYHED,43,conn[126:169]); - ret.insertNextCell(NORM_HEXA8,8,conn[169:177]); - ret.insertNextCell(NORM_HEXA8,8,conn[177:185]); - ret.insertNextCell(NORM_POLYHED,43,conn[185:228]); - ret.insertNextCell(NORM_HEXA8,8,conn[228:236]); - # - ret.insertNextCell(NORM_HEXA8,8,conn[236:244]); - ret.insertNextCell(NORM_POLYHED,43,conn[244:287]); - ret.insertNextCell(NORM_HEXA8,8,conn[287:295]); - ret.insertNextCell(NORM_HEXA8,8,conn[295:303]); - ret.insertNextCell(NORM_POLYHED,43,conn[303:346]); - ret.insertNextCell(NORM_HEXA8,8,conn[346:354]); - # - ret.finishInsertingCells(); - myCoords=DataArrayDouble.New(); - myCoords.setValues(coords,60,3); - ret.setCoords(myCoords); - # - mesh2D=MEDCouplingUMesh.New(); - mesh2D.setMeshDimension(2); - mesh2D.allocateCells(6); - mesh2D.insertNextCell(NORM_QUAD4,4,conn2[0:4]); - mesh2D.insertNextCell(NORM_POLYGON,6,conn2[4:10]); - mesh2D.insertNextCell(NORM_QUAD4,4,conn2[10:14]); - mesh2D.insertNextCell(NORM_QUAD4,4,conn2[14:18]); - mesh2D.insertNextCell(NORM_POLYGON,6,conn2[18:24]); - mesh2D.insertNextCell(NORM_QUAD4,4,conn2[24:28]); - mesh2D.finishInsertingCells(); - mesh2D.setCoords(myCoords); - return ret,mesh2D - - def buildCU1DMesh_U(self): - coords=[ 0.0, 0.3, 0.75, 1.0 ] - conn=[ 0,1, 1,2, 2,3 ] - mesh=MEDCouplingUMesh.New(); - mesh.setMeshDimension(1); - mesh.allocateCells(3); - mesh.insertNextCell(NORM_SEG2,2,conn[0:2]); - mesh.insertNextCell(NORM_SEG2,2,conn[2:4]); - mesh.insertNextCell(NORM_SEG2,2,conn[4:6]); - mesh.finishInsertingCells(); - myCoords=DataArrayDouble.New(); - myCoords.setValues(coords,4,1); - mesh.setCoords(myCoords); - return mesh; - - def build2DTargetMeshMergeNode_1(self): - targetCoords=[-0.3,-0.3, 0.2,-0.3, 0.7,-0.3, -0.3,-0.3, 0.2,-0.3, 0.2,-0.3, 0.2,0.2, 0.2,0.2, 0.7,-0.3, -0.3,0.2, 0.2,0.2, 0.7,0.2, -0.3,0.7, 0.7,0.2, -0.3,0.7, 0.2,0.7, 0.7,0.7, 0.2,0.7 ] - targetConn=[0,9,7,5, 4,6,2, 10,11,8, 9,14,15,7, 17,16,13,6] - targetMesh=MEDCouplingUMesh.New(); - targetMesh.setMeshDimension(2); - targetMesh.allocateCells(5); - targetMesh.insertNextCell(NORM_QUAD4,4,targetConn[0:4]); - targetMesh.insertNextCell(NORM_TRI3,3,targetConn[4:7]); - targetMesh.insertNextCell(NORM_TRI3,3,targetConn[7:10]); - targetMesh.insertNextCell(NORM_QUAD4,4,targetConn[10:14]); - targetMesh.insertNextCell(NORM_QUAD4,4,targetConn[14:18]); - targetMesh.finishInsertingCells(); - myCoords=DataArrayDouble.New(); - myCoords.setValues(targetCoords,18,2); - targetMesh.setCoords(myCoords); - return targetMesh; - - def build3DTargetMeshMergeNode_1(self): - targetCoords=[ 0., 0., 0., 50., 0., 0. , 200., 0., 0. , 0., 50., 0., 50., 50., 0. , 200., 50., 0., 0., 200., 0., 50., 200., 0. , 200., 200., 0. , - 0., 0., 50., 50., 0., 50. , 200., 0., 50. , 0., 50., 50., 50., 50., 50. , 200., 50., 50., 0., 200., 50., 50., 200., 50. , 200., 200., 50. , - 0., 0., 200., 50., 0., 200. , 200., 0., 200. , 0., 50., 200., 50., 50., 200. , 200., 50., 200., 0., 200., 200., 50., 200., 200. , 200., 200., 200., 50.,0.,0., 50.,0.,0., 50.,0.,0., 200., 50., 200.] - targetConn=[0,29,4,3,9,10,13,12, 28,2,5,4,10,11,14,13, 3,4,7,6,12,13,16,15, 4,5,8,7,13,14,17,16, - 9,10,13,12,18,19,22,21, 10,11,14,13,19,20,23,22, 12,13,16,15,21,22,25,24, 13,14,17,16,22,30,26,25] - targetMesh=MEDCouplingUMesh.New(); - targetMesh.setMeshDimension(3); - targetMesh.allocateCells(12); - for i in xrange(8): - targetMesh.insertNextCell(NORM_HEXA8,8,targetConn[8*i:8*(i+1)]); - pass - targetMesh.finishInsertingCells(); - myCoords=DataArrayDouble.New(); - myCoords.setValues(targetCoords,31,3); - targetMesh.setCoords(myCoords); - return targetMesh; - - def build2DTargetMeshMerged_1(self): - targetCoords=[ - -0.3,-0.3, 0.2,-0.3, 0.7,-0.3, -0.3,0.2, 0.2,0.2, 0.7,0.2, -0.3,0.7, 0.2,0.7, 0.7,0.7, - 0.7,-0.3, 1.7,-0.3, 0.7,0.7, 1.7,0.7 - ] - targetConn=[ - 0,3,4,1, 1,4,2, 4,5,2, 6,7,4,3, 7,8,5,4, - 9,12,10,9,11,12 - ] - targetMesh=MEDCouplingUMesh.New(); - targetMesh.setName("merge"); - targetMesh.setMeshDimension(2); - targetMesh.allocateCells(10); - targetMesh.insertNextCell(NORM_QUAD4,4,targetConn[0:4]) - targetMesh.insertNextCell(NORM_TRI3,3,targetConn[4:7]) - targetMesh.insertNextCell(NORM_TRI3,3,targetConn[7:10]) - targetMesh.insertNextCell(NORM_QUAD4,4,targetConn[10:14]) - targetMesh.insertNextCell(NORM_QUAD4,4,targetConn[14:18]) - targetMesh.insertNextCell(NORM_TRI3,3,targetConn[18:21]) - targetMesh.insertNextCell(NORM_TRI3,3,targetConn[21:24]) - targetMesh.finishInsertingCells(); - myCoords=DataArrayDouble.New(); - myCoords.setValues(targetCoords,13,2); - targetMesh.setCoords(myCoords); - return targetMesh; - - def build2DTargetMesh_2(cls): - targetCoords=[-0.3,-0.3, 0.2,-0.3, 0.7,-0.3, -0.3,0.2, 0.2,0.2, 0.7,0.2, -0.3,0.7, 0.2,0.7, 0.7,0.7 ] - targetConn=[0,3,4, 0,4,1, 1,4,2, 4,5,2, 3,6,4, 6,7,4, 4,7,5, 7,8,5 ] - targetMesh=MEDCouplingUMesh.New(); - targetMesh.setMeshDimension(2); - targetMesh.allocateCells(8); - targetMesh.insertNextCell(NORM_TRI3,3,targetConn[0:3]) - targetMesh.insertNextCell(NORM_TRI3,3,targetConn[3:6]) - targetMesh.insertNextCell(NORM_TRI3,3,targetConn[6:9]) - targetMesh.insertNextCell(NORM_TRI3,3,targetConn[9:12]) - targetMesh.insertNextCell(NORM_TRI3,3,targetConn[12:15]) - targetMesh.insertNextCell(NORM_TRI3,3,targetConn[15:18]) - targetMesh.insertNextCell(NORM_TRI3,3,targetConn[18:21]) - targetMesh.insertNextCell(NORM_TRI3,3,targetConn[21:24]) - targetMesh.finishInsertingCells(); - myCoords=DataArrayDouble.New(); - myCoords.setValues(targetCoords,9,2); - targetMesh.setCoords(myCoords); - return targetMesh; - - def build1DSourceMesh_2(cls): - ret=MEDCouplingUMesh.New("1DSourceMesh",1); - ret.allocateCells(4); - conn=[0,1,2,3,1,2,3,4] - for i in xrange(4): - ret.insertNextCell(NORM_SEG2,2,conn[2*i:2*i+2]); - pass - ret.finishInsertingCells(); - myCoords=DataArrayDouble.New([0.3,0.7,0.9,1.0,1.12],5,1); - ret.setCoords(myCoords); - return ret - - def build1DTargetMesh_3(cls): - ret=MEDCouplingUMesh.New("1DMesh_3",1); - ret.allocateCells(4); - conn=[0,1,2, 3,4, 6,5,7 ,9,8] - ret.insertNextCell(NORM_SEG3,3,conn[0:3]) - ret.insertNextCell(NORM_SEG2,2,conn[3:5]) - ret.insertNextCell(NORM_SEG3,3,conn[5:8]) - ret.insertNextCell(NORM_SEG2,2,conn[8:10]) - ret.finishInsertingCells(); - coords=[0.5,1.,0.8,5.,5.21,0.5,1.1,0.7,5.,5.31] - myCoords=DataArrayDouble.New(); - myCoords.setValues(coords,10,1); - ret.setCoords(myCoords); - return ret; - - def build2DCurveTargetMesh_3(cls): - ret=MEDCouplingUMesh.New("2DCurveMesh_3",1); - ret.allocateCells(4); - conn=[0,1,2, 3,4, 6,5,7 ,9,8] - ret.insertNextCell(NORM_SEG3,3,conn[0:3]) - ret.insertNextCell(NORM_SEG2,2,conn[3:5]) - ret.insertNextCell(NORM_SEG3,3,conn[5:8]) - ret.insertNextCell(NORM_SEG2,2,conn[8:10]) - ret.finishInsertingCells(); - coords=[0.5,0.5,1.,1.,0.8,0.8,5.,5.,5.21,5.21,0.5,0.5,1.1,1.1,0.7,0.7,5.,5.,5.31,5.31] - myCoords=DataArrayDouble.New(); - myCoords.setValues(coords,10,2); - ret.setCoords(myCoords); - return ret; - - def build2DTargetMesh_3(cls): - ret=MEDCouplingUMesh.New("2DMesh_3",2); - ret.allocateCells(10); - conn=[0,1,2, 0,1,3,4, 0,1,3,5,4, 0,1,2,6,7,8, 0,1,3,4,6,9,2,10, 0,2,1, 0,4,3,1, 0,4,5,3,1, 0,2,1,8,7,6, 0,4,3,1,10,2,9,6] - ret.insertNextCell(NORM_TRI3,3,conn[0:3]) - ret.insertNextCell(NORM_QUAD4,4,conn[3:7]) - ret.insertNextCell(NORM_POLYGON,5,conn[7:12]) - ret.insertNextCell(NORM_TRI6,6,conn[12:18]) - ret.insertNextCell(NORM_QUAD8,8,conn[18:26]) - ret.insertNextCell(NORM_TRI3,3,conn[26:29]) - ret.insertNextCell(NORM_QUAD4,4,conn[29:33]) - ret.insertNextCell(NORM_POLYGON,5,conn[33:38]) - ret.insertNextCell(NORM_TRI6,6,conn[38:44]) - ret.insertNextCell(NORM_QUAD8,8,conn[44:52]) - ret.finishInsertingCells(); - coords=[0.,0.,1.,0.,0.5,1.,1.,1.,0.,1.,0.5,2.,0.5,0.,0.75,0.5,0.25,0.5,1.,0.5,0.,0.5] - myCoords=DataArrayDouble.New(); - myCoords.setValues(coords,11,2); - ret.setCoords(myCoords); - ret.checkCoherency(); - return ret; - - def build2DTargetMesh_4(cls): - targetCoords=[-0.3,-0.3, 0.2,-0.3, 0.7,-0.3, 0.7,-0.3, -0.3,0.2, 0.2,0.2, 0.7,0.2, -0.3,0.7, 0.2,0.7, 0.7,0.7 ] - targetConn=[0,4,5,1, 1,5,3, 5,6,2, 7,8,5,4, 8,9,6,5] - targetMesh=MEDCouplingUMesh.New(); - targetMesh.setMeshDimension(2); - targetMesh.allocateCells(5); - targetMesh.insertNextCell(NORM_QUAD4,4,targetConn[0:4]) - targetMesh.insertNextCell(NORM_TRI3,3,targetConn[4:7]) - targetMesh.insertNextCell(NORM_TRI3,3,targetConn[7:10]) - targetMesh.insertNextCell(NORM_QUAD4,4,targetConn[10:14]) - targetMesh.insertNextCell(NORM_QUAD4,4,targetConn[14:18]) - targetMesh.finishInsertingCells(); - myCoords=DataArrayDouble.New(); - myCoords.setValues(targetCoords,10,2); - targetMesh.setCoords(myCoords); - return targetMesh; - - def buildMultiFields_1(cls): - m1=MEDCouplingDataForTest.build2DTargetMesh_1(); - m1.setName("m1"); - m2=MEDCouplingDataForTest.build2DTargetMesh_1(); - m2.setName("m2"); - vals0=[-0.7,-1.,-2.,-3.,-4.]; - vals1=[0.,1.,2.,3.,4.,0.1,0.2,0.3,0.4]; - vals1_1=[170.,171.,172.,173.,174.,170.1,170.2,170.3,170.4]; - vals2=[5.,6.,7.,8.,9.]; - vals4=[15.,16.,17.,18.,19.]; - d0=DataArrayDouble.New(); - d0.setValues(vals0,5,1); - d1=DataArrayDouble.New(); - d1.setValues(vals1,9,1); - d1_1=DataArrayDouble.New(); - d1_1.setValues(vals1_1,9,1); - d2=DataArrayDouble.New(); - d2.setValues(vals2,5,1); - d4=DataArrayDouble.New(); - d4.setValues(vals4,5,1); - d0.setName("d0"); d1.setName("d1"); d1_1.setName("d1_1"); d2.setName("d2"); d4.setName("d4"); - d0.setInfoOnComponent(0,"c1"); - d1.setInfoOnComponent(0,"c6"); - d1_1.setInfoOnComponent(0,"c9"); - d2.setInfoOnComponent(0,"c5"); - d4.setInfoOnComponent(0,"c7"); - f0=MEDCouplingFieldDouble.New(ON_CELLS,ONE_TIME); - f0.setMesh(m1); - f0.setArray(d0); - f0.setTime(0.2,5,6); - f0.setName("f0"); - f1=MEDCouplingFieldDouble.New(ON_NODES,LINEAR_TIME); - f1.setMesh(m1); - f1.setArrays([d1,d1_1]); - f1.setStartTime(0.7,7,8); - f1.setEndTime(1.2,9,10); - f1.setName("f1"); - f2=MEDCouplingFieldDouble.New(ON_CELLS,CONST_ON_TIME_INTERVAL); - f2.setMesh(m2); - f2.setArray(d2); - f2.setTime(1.2,11,12); - f2.setEndTime(1.5,13,14); - f2.setName("f2"); - f3=MEDCouplingFieldDouble.New(ON_CELLS,ONE_TIME); - f3.setMesh(m1); - f3.setArray(d2); - f3.setTime(1.7,15,16); - f3.setName("f3"); - f4=MEDCouplingFieldDouble.New(ON_CELLS,NO_TIME); - f4.setMesh(m2); - f4.setArray(d4); - f4.setName("f4"); - ret=MEDCouplingMultiFields.New([f0,f1,f2,f3,f4]); - return ret; - - def buildMultiFields_2(cls): - m1=MEDCouplingDataForTest.build2DTargetMesh_1(); - m1.setName("m1"); - m2=MEDCouplingDataForTest.build2DTargetMesh_1(); - m2.setName("m2"); - vals0=[-0.7,-1.,-2.,-3.,-4.]; - vals1=[0.,1.,2.,3.,4.]; - vals1_1=[170.,171.,172.,173.,174.]; - vals2=[5.,6.,7.,8.,9.]; - vals4=[15.,16.,17.,18.,19.]; - d0=DataArrayDouble.New(); - d0.setValues(vals0,5,1); - d1=DataArrayDouble.New(); - d1.setValues(vals1,5,1); - d1_1=DataArrayDouble.New(); - d1_1.setValues(vals1_1,5,1); - d2=DataArrayDouble.New(); - d2.setValues(vals2,5,1); - d4=DataArrayDouble.New(); - d4.setValues(vals4,5,1); - d0.setName("d0"); d1.setName("d1"); d1_1.setName("d1_1"); d2.setName("d2"); d4.setName("d4"); - d0.setInfoOnComponent(0,"c1"); - d1.setInfoOnComponent(0,"c6"); - d1_1.setInfoOnComponent(0,"c9"); - d2.setInfoOnComponent(0,"c5"); - d4.setInfoOnComponent(0,"c7"); - f0=MEDCouplingFieldDouble.New(ON_CELLS,ONE_TIME); - f0.setMesh(m1); - f0.setArray(d0); - f0.setTime(0.2,5,6); - f0.setName("f0"); - f1=MEDCouplingFieldDouble.New(ON_CELLS,LINEAR_TIME); - f1.setMesh(m1); - f1.setArrays([d1,d1_1]); - f1.setStartTime(0.7,7,8); - f1.setEndTime(1.2,9,10); - f1.setName("f1"); - f2=MEDCouplingFieldDouble.New(ON_CELLS,CONST_ON_TIME_INTERVAL); - f2.setMesh(m2); - f2.setArray(d2); - f2.setTime(1.2,11,12); - f2.setEndTime(1.5,13,14); - f2.setName("f2"); - f3=MEDCouplingFieldDouble.New(ON_CELLS,ONE_TIME); - f3.setMesh(m1); - f3.setArray(d2); - f3.setTime(1.7,15,16); - f3.setName("f3"); - f4=MEDCouplingFieldDouble.New(ON_CELLS,NO_TIME); - f4.setMesh(m2); - f4.setArray(d4); - f4.setName("f4"); - return [f0,f1,f2,f3,f4] - - def build1DMultiTypes_1(self): - mesh=MEDCouplingUMesh.New("Multi1DMesh",1); - coo=MEDCouplingDataForTest.buildCoordsForMultiTypes_1(); - conn=[0,2, 0,2,1] - mesh.allocateCells(2); - mesh.insertNextCell(NORM_SEG2,2,conn[0:2]) - mesh.insertNextCell(NORM_SEG3,3,conn[2:5]) - mesh.finishInsertingCells(); - mesh.setCoords(coo); - return mesh; - - def build2DMultiTypes_1(self): - mesh=MEDCouplingUMesh.New("Multi2DMesh",2); - coo=MEDCouplingDataForTest.buildCoordsForMultiTypes_1(); - conn=[3,4,5, 3,4,5,6,7,8, 0,9,10,11, 0,9,10,11,12,13,14,15] - mesh.allocateCells(4); - mesh.insertNextCell(NORM_TRI3,3,conn[0:3]) - mesh.insertNextCell(NORM_TRI6,6,conn[3:9]) - mesh.insertNextCell(NORM_QUAD4,4,conn[9:13]) - mesh.insertNextCell(NORM_QUAD8,8,conn[13:21]) - mesh.finishInsertingCells(); - mesh.setCoords(coo); - return mesh; - - def build3DMultiTypes_1(self): - mesh=MEDCouplingUMesh.New("Multi3DMesh",3); - coo=MEDCouplingDataForTest.buildCoordsForMultiTypes_1(); - conn=[0,16,17,18, - 0,16,17,18,19,20,21,22,23,24, - 0,11,10,9,25, - 0,11,10,9,25,15,14,13,12,26,27,28,29, - 0,30,31,32,33,34, - 0,30,31,32,33,34,35,36,37,38,39,40,41,42,43, - 0,9,10,11,44,45,46,47, - 0,9,10,11,44,45,46,47,12,13,14,15,48,49,50,51,52,53,54,55 ]; - mesh.allocateCells(8); - mesh.insertNextCell(NORM_TETRA4,4,conn[0:4]) - mesh.insertNextCell(NORM_TETRA10,10,conn[4:14]) - mesh.insertNextCell(NORM_PYRA5,5,conn[14:19]) - mesh.insertNextCell(NORM_PYRA13,13,conn[19:32]) - mesh.insertNextCell(NORM_PENTA6,6,conn[32:38]) - mesh.insertNextCell(NORM_PENTA15,15,conn[38:53]) - mesh.insertNextCell(NORM_HEXA8,8,conn[53:61]) - mesh.insertNextCell(NORM_HEXA20,20,conn[61:81]) - mesh.finishInsertingCells(); - mesh.setCoords(coo); - return mesh; - - def buildCoordsForMultiTypes_1(self): - coords=DataArrayDouble.New(); - data=[0.0,0.0,0.0, 0.5,0.5,0.5, 1.0,1.0,1.0, 1.0,1.0,0.0, 2.0,2.5,0.0, 6.0,1.5,0.0, 1.0,2.0,0.0, 4.5,2.5,0.0, 4.0,0.5,0.0, 0.0,4.0,0.0, 4.0,4.0,0.0, 4.0,0.0,0.0, 0.0,2.0,0.0, 2.0,4.0,0.0, 4.0,2.0,0.0, 2.0,0.0,0.0, 0.0,6.0,0.0, 3.0,3.0,0.0, 1.3,3.0,3.0, 0.0,3.0,0.0, 1.5,4.5,0.0, 1.5,1.5,0.0, 0.65,1.5,1.5, 0.65,4.5,1.5, 2.15,3.0,1.5, 2.0,2.0,2.0, 3.0,1.0,1.0, 3.0,3.0,1.0, 1.0,3.0,1.0, 1.0,1.0,1.0, 0.0,3.0,0.0, 2.0,0.0,0.0, 0.0,0.0,6.0, 0.0,3.0,6.0, 3.0,0.0,6.0, 0.0,1.5,0.0, 1.5,1.5,0.0, 1.5,0.0,0.0, 0.0,1.5,6.0, 1.5,1.5,6.0, 1.5,0.0,6.0, 0.0,0.0,3.0, 0.0,3.0,3.0, 3.0,0.0,3.0, 0.0,0.0,4.0, 0.0,4.0,4.0, 4.0,4.0,4.0, 4.0,0.0,4.0, 0.0,2.0,4.0, 2.0,4.0,4.0, 4.0,2.0,4.0, 2.0,0.0,4.0, 0.0,0.0,2.0, 0.0,4.0,2.0, 4.0,4.0,2.0, 4.0,0.0,2.0] - coords.setValues(data,56,3); - coords.setInfoOnComponent(0,"X (cm)"); - coords.setInfoOnComponent(1,"Y (cm)"); - coords.setInfoOnComponent(2,"Z (cm)"); - return coords - - def buildHexa8Mesh_1(self): - mesh=MEDCouplingUMesh.New("Hexa8Only",3); - coo=DataArrayDouble.New(); - coords=[0.0, 0.0, 0.0, 0.5, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.5, 0.0, 0.5, 0.5, 0.0, 1.0, 0.5, 0.0, 0.0, 1.0, 0.0, 0.5, 1.0, 0.0, 1.0, 1.0, 0.0, 0.0, 0.0, 0.5, 0.5, 0.0, 0.5, 1.0, 0.0, 0.5, 0.0, 0.5, 0.5, 0.5, 0.5, 0.5, 1.0, 0.5, 0.5, 0.0, 1.0, 0.5, 0.5, 1.0, 0.5, 1.0, 1.0, 0.5, 0.0, 0.0, 1.0, 0.5, 0.0, 1.0, 1.0, 0.0, 1.0, 0.0, 0.5, 1.0, 0.5, 0.5, 1.0, 1.0, 0.5, 1.0, 0.0, 1.0, 1.0, 0.5, 1.0, 1.0, 1.0, 1.0, 1.0] - coo.setValues(coords,27,3); - conn=[3,12,13,4,0,9,10,1, - 4,13,14,5,1,10,11,2, - 6,15,16,7,3,12,13,4, - 7,16,17,8,4,13,14,5, - 12,21,22,13,9,18,19,10, - 13,22,23,14,10,19,20,11, - 15,24,25,16,12,21,22,13, - 16,25,26,17,13,22,23,14]; - mesh.allocateCells(8); - for i in xrange(8): - mesh.insertNextCell(NORM_HEXA8,8,conn[8*i:8*(i+1)]) - pass - mesh.finishInsertingCells(); - mesh.setCoords(coo); - return mesh; - - def buildPointe_1(self): - mesh=MEDCouplingUMesh.New("Pointe.med",3); - mesh2=MEDCouplingUMesh.New("Pointe.med",2); - coords=[0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 2.0, 0.0, 1.0, 0.0, 2.0, 1.0, -2.0, 0.0, 1.0, 0.0, -2.0, 1.0, 1.0, 1.0, 2.0, -1.0, 1.0, 2.0, -1.0, -1.0, 2.0, 1.0, -1.0, 2.0, 1.0, 1.0, 3.0, -1.0, 1.0, 3.0, -1.0, -1.0, 3.0, 1.0, -1.0, 3.0, 1.0, 1.0, 4.0, -1.0, 1.0, 4.0, -1.0, -1.0, 4.0, 1.0, -1.0, 4.0, 0.0, 0.0, 5.0] - conn=[0,1,2,5,0,1,3,2,0,1,4,3,0,1,5,4,1,6,3,2,1,7,4,3,1,8,5,4,1,9,2,5,1,6,2,9,1,7,3,6,1,8,4,7,1,9,5,8, 6,7,8,9,1,14,17,16,15,18, 10,11,12,13,6,7,8,9,14,15,16,17,10,11,12,13] - coo=DataArrayDouble.New(); - coo.setValues(coords,19,3); - mesh.setCoords(coo); - mesh2.setCoords(coo); - mesh.allocateCells(16); - for i in xrange(12): - mesh.insertNextCell(NORM_TETRA4,4,conn[4*i:4*i+4]) - pass - mesh.insertNextCell(NORM_PYRA5,5,conn[48:53]) - mesh.insertNextCell(NORM_PYRA5,5,conn[53:58]) - mesh.insertNextCell(NORM_HEXA8,8,conn[58:66]) - mesh.insertNextCell(NORM_HEXA8,8,conn[66:74]) - mesh.finishInsertingCells(); - #[1,34,29,23,41,32] - conn2=[0,5,1,14,18,17,8,7,4,9,5,2, 12,8,9,13,6,7,8,9] - mesh2.allocateCells(6); - for i in xrange(4): - mesh2.insertNextCell(NORM_TRI3,3,conn2[3*i:3*i+3]) - pass - mesh2.insertNextCell(NORM_QUAD4,4,conn2[12:16]) - mesh2.insertNextCell(NORM_QUAD4,4,conn2[16:20]) - mesh2.finishInsertingCells(); - return [mesh,mesh2] - - # 2D usecase1 for interpolation Gauss Pt-> Gauss Pt. Coming from ASTER : Please, do not touch - def buildFieldOnGauss_1(self): - coo=DataArrayDouble([1.0,0.0,1.33333333333333,0.0,1.66666666666667,0.0,0.923879532511287,0.38268343236509006,1.23183937668172,0.510244576486786,1.53979922085214,0.6378057206084831,2.0,0.0,1.8477590650225701,0.7653668647301801,0.9428090415820631,0.9428090415820631,1.1785113019775801,1.1785113019775801,1.4142135623731,1.41421356237309,0.707106781186548,0.707106781186547,0.38268343236509006,0.923879532511287,0.510244576486786,1.23183937668172,0.6378057206084831,1.53979922085214,0.7653668647301801,1.8477590650225701,3.1550283219328204e-17,1.33333333333333,1.16009632455949e-17,1.66666666666667,-2.7620050344068196e-16,2.0,-1.3810025172034098e-16,1.0,-2.0,0.0,-1.53979922085214,0.6378057206084831,-1.66666666666667,0.0,-1.33333333333333,0.0,-0.923879532511287,0.38268343236509006,-1.8477590650225701,0.7653668647301801,-0.9428090415820631,0.9428090415820631,-1.23183937668172,0.510244576486786,-1.83333333333333,0.0,-1.6937791429373599,0.701586292669331,-1.5,0.0,-1.30771370720431,0.26012042935483803,-1.16666666666667,0.0,-1.0778594545965,0.44646400442593803,-1.38578268717091,0.9259503883660041,-1.38581929876693,0.574025148547635,-1.06066017177982,1.06066017177982,-0.8314696123025451,0.5555702330196021,-1.0,0.0,-1.1785113019775801,1.1785113019775801,-0.707106781186548,0.707106781186547,-1.63464213400538,0.325150536693547,-1.9615705608064598,0.390180644032256,-1.47117792060485,0.292635483024192,-0.9807852804032301,0.19509032201612803,-1.524360955888,1.0185454272026,-1.2963624321753402,1.2963624321753402,-1.10862614973673,0.740760310692803,-0.970047881019636,0.6481652718562021,-0.824957911384305,0.824957911384305,-1.4142135623731,1.41421356237309,-1.7981063474059198,0.357665590362902,-1.1442494938037702,0.227605375685483,-1.66293922460509,1.1111404660392,-1.24720441845382,0.833355349529403,-0.7653668647301801,1.8477590650225701,-0.6378057206084831,1.53979922085214,-0.510244576486786,1.23183937668172,-0.701586292669331,1.6937791429373599,-0.574025148547635,1.38581929876693,-0.44646400442593803,1.0778594545965,-0.38268343236509006,0.923879532511287,-0.9259503883660041,1.38578268717091,-0.740760310692803,1.10862614973673,-0.5555702330196021,0.8314696123025451,-0.325150536693547,1.63464213400538,-0.26012042935483803,1.30771370720431,-0.19509032201612803,0.9807852804032301,1.6805133673525298e-18,1.83333333333333,-2.4643915380595496e-16,1.5,-1.4799359654427099e-16,1.16666666666667,-1.1111404660392,1.66293922460509,-0.39018064403225705,1.9615705608064598],73,2) - coo.setInfoOnComponents(["X [INCONNUE]","Y [INCONNUE]"]) - m=MEDCouplingUMesh("MA1",2) - m.setDescription("CREE PAR CODE_ASTER") ; m.setTimeUnit("SANS UNITES") ; m.setTime(-1.,-1,-1) - m.setCoords(coo) - m.allocateCells() - conn=[[11,8,13],[11,13,12],[8,9,13],[9,14,13],[9,10,15],[9,15,14],[12,13,19],[13,16,19],[13,14,17],[13,17,16],[14,15,17],[15,18,17],[0,1,4,3],[1,2,5,4],[2,6,7,5],[3,4,8,11],[4,5,9,8],[5,7,10,9],[20,22,21,28,41,51],[21,25,20,29,42,51],[22,23,21,30,43,41],[23,27,21,31,35,43],[23,38,24,32,44,52],[24,27,23,33,31,52],[25,21,50,29,45,53],[21,39,50,34,46,45],[21,27,26,35,47,54],[26,39,21,36,34,54],[27,24,26,33,48,47],[24,40,26,37,49,48],[50,39,56,55,46,62,58,71],[39,26,57,56,36,63,59,62],[26,40,61,57,49,64,60,63],[55,56,17,18,58,65,68,72],[56,57,16,17,59,66,69,65],[57,61,19,16,60,67,70,66]] - for i in xrange(0,12): - m.insertNextCell(NORM_TRI3,conn[i]) - pass - for i in xrange(12,18): - m.insertNextCell(NORM_QUAD4,conn[i]) - pass - for i in xrange(18,30): - m.insertNextCell(NORM_TRI6,conn[i]) - pass - for i in xrange(30,36): - m.insertNextCell(NORM_QUAD8,conn[i]) - pass - fff=MEDCouplingFieldDouble.New(ON_GAUSS_PT) ; fff.setName("CH1RB") ; fff.setNature(ConservativeVolumic) - fff.setMesh(m) - fff.setGaussLocalizationOnCells(range(0,12),[0.,0.,1.,0.,0.,1.],[0.3333333333333333,0.3333333333333333],[0.5]) - fff.setGaussLocalizationOnCells(range(12,18),[-1.,-1.,1.,-1.,1.,1.,-1.,1.],[-0.577350269189626,-0.577350269189626,0.577350269189626,-0.577350269189626,0.577350269189626,0.577350269189626,-0.577350269189626,0.577350269189626],[1.,1.,1.,1.]) - fff.setGaussLocalizationOnCells(range(18,30),[0.,0.,1.,0.,0.,1.,0.5, 0.,0.5, 0.5, 0.,0.5],[0.16666666666666666,0.16666666666666666,0.6666666666666666,0.16666666666666666,0.16666666666666666,0.6666666666666666],[0.16666666666666666,0.16666666666666666,0.16666666666666666]) - fff.setGaussLocalizationOnCells(range(30,36),[-1.,-1.,1.,-1.,1.,1.,-1.,1.,0.,-1.,1.,0.,0.,1.,-1.,0.],[-0.774596669241483,-0.774596669241483,0.774596669241483,-0.774596669241483,0.774596669241483,0.774596669241483,-0.774596669241483,0.774596669241483,0.0,-0.774596669241483,0.774596669241483,0.0,0.0,0.774596669241483,-0.774596669241483,0.0,0.0,0.0],[0.30864197530864196,0.30864197530864196,0.30864197530864196,0.30864197530864196,0.49382716049382713,0.49382716049382713,0.49382716049382713,0.49382716049382713,0.7901234567901234]) - return MEDCouplingFieldTemplate(fff) - - # 2D usecase2 for interpolation Gauss Pt-> Gauss Pt. Coming from ASTER : Please, do not touch - def buildFieldOnGauss_2(self): - coo=DataArrayDouble([1.0,0.0,1.24068268955165,0.15233667925643402,1.25,0.0,1.5,0.0,1.73695576537231,0.21327135095900804,1.75,0.0,2.0,0.0,0.9925461516413221,0.12186934340514702,1.212869657845,0.302402369499585,1.48881922746198,0.182804015107721,1.6980175209829897,0.423363317299419,1.9850923032826397,0.243738686810295,0.9702957262759959,0.241921895599668,1.1669755331215,0.447959936931625,1.4554435894139899,0.362882843399502,1.6337657463701,0.627143911704275,1.94059145255199,0.483843791199335,0.9335804264972021,0.35836794954530005,1.10368449107366,0.586839453482364,1.4003706397458,0.5375519243179501,1.5451582875031202,0.8215752348753091,1.8671608529944002,0.716735899090601,0.882947592858927,0.46947156278589103,1.02394005536124,0.716970545438808,1.32442138928839,0.704207344178836,1.43351607750574,1.00375876361433,1.76589518571785,0.9389431255717821,1.125,0.0,1.11661442059649,0.137103011330791,1.375,0.0,1.4972021976328,0.09157280930228531,1.625,0.0,1.61288749641715,0.198037683033365,1.875,0.0,1.9962695968437298,0.12209707906971401,1.0915826920605,0.272162132549626,1.36475095850682,0.167570347182078,1.47488236134593,0.27335328823822097,1.5767305551984903,0.39312308034946003,1.8610240343274802,0.228505018884652,1.96650981512791,0.364471050984295,1.05027797980935,0.403163943238463,1.3341566236295,0.332642606449543,1.43057542612234,0.45105869925641007,1.5170681930579497,0.5823479180111131,1.8193044867674901,0.45360355424937704,1.9074339014964499,0.601411599008546,0.993316041966293,0.528155508134127,1.28367308643365,0.492755930624788,1.36494190631481,0.6220398639843591,1.43478983839576,0.7628912895270731,1.7504632996822498,0.671939905397438,1.81992254175309,0.8293864853124782,0.921546049825116,0.645273490894927,1.21405294018102,0.6455233988306001,1.27896024653114,0.783747847073923,1.33112207196961,0.93206170907045,1.65552673661049,0.8802591802235451,1.70528032870818,1.0449971294319,0.8191520442889921,0.5735764363510459,1.22872806643349,0.8603646545265691,1.6383040885779798,1.14715287270209,1.24766849802733,0.0763106744185711,0.9981347984218671,0.0610485395348569,1.37243534783007,0.0839417418604282,1.74673589723827,0.106834944186,1.871502747041,0.114466011627857,1.22906863445494,0.227794406865184,0.9832549075639551,0.18223552549214703,1.3519754979004401,0.25057384755170303,1.7206960882369198,0.318912169611258,1.84360295168241,0.341691610297777,1.19214618843528,0.37588224938034104,0.953716950748227,0.300705799504273,1.31136080727881,0.413470474318376,1.6690046638094,0.526235149132478,1.7882192826529297,0.563823374070512,1.13745158859568,0.518366553320299,0.9099612708765431,0.4146932426562391,1.25119674745525,0.570203208652329,1.5924322240339497,0.725713174648418,1.7061773828935198,0.777549829980448,1.06580020544262,0.6531232058949361,0.8526401643540921,0.522498564715949,1.17238022598688,0.7184355264844301,1.12633406089736,0.7886675999826881,1.49212028761966,0.91437248825291,1.59870030816392,0.979684808842404,1.53591008304186,1.07545581815821,1.1229016482246,0.068679606976714,1.6219690474355302,0.0992038767441424,1.10616177100945,0.205014966178666,1.59778922479143,0.29613272892474,1.07293156959176,0.338294024442307,1.5497900449658701,0.488646924194444,1.02370642973611,0.466529897988269,1.47868706517438,0.673876519316388,0.9592201848983541,0.587810885305442,1.3855402670754,0.8490601676634171,0.743144825477394,0.669130606358858,0.9289310318467431,0.836413257948573,1.11471723821609,1.00369590953829,1.30050344458544,1.170978561128,0.656059028990507,0.7547095802227721,0.820073786238134,0.943386975278465,0.984088543485761,1.13206437033416,1.14810330073339,1.32074176538985,0.559192903470747,0.8290375725550421,0.6989911293384331,1.0362969656938,0.8387893552061201,1.24355635883256,0.978587581073807,1.45081575197132,0.453990499739547,0.8910065241883681,0.567488124674433,1.11375815523546,0.6809857496093201,1.3365097862825501,0.794483374544207,1.55926141732964,0.8360379286620679,0.7527719321537151,1.0218241350314199,0.92005458374343,1.20761034140077,1.08733723533314,1.39339654777011,1.25461988692286,0.7380664076143211,0.8490482777506181,0.902081164861948,1.03772567280631,1.06609592210957,1.226403067862,1.2301106793572,1.4150804629177,0.6290920164045901,0.932667269124422,0.7688902422722771,1.13992666226318,0.9086884681399641,1.34718605540194,1.04848669400765,1.5544454485407,0.51073931220699,1.00238233971191,0.624236937141877,1.22513397075901,0.737734562076764,1.4478856018061,0.85123218701165,1.6706372328531902,1.48628965095479,1.33826121271772,1.31211805798101,1.5094191604455398,1.11838580694149,1.6580751451100801,0.907980999479094,1.7820130483767398,0.978260196065517,0.778143295797024,1.17391223527862,0.9337719549564292,1.36956427449172,1.08940061411583,1.56521631370483,1.24502927327524,0.876136580374814,0.891563061442727,1.05136389644978,1.06987567373127,1.22659121252474,1.2481882860198201,1.4018185285997,1.42650089830836,0.7609517862609011,0.991691675364044,0.913142143513081,1.19003001043685,1.06533250076526,1.38836834550966,1.21752285801744,1.5867066805824699,0.6344229537008801,1.07703645055191,0.7613075444410561,1.29244374066229,0.8881921351812321,1.50785103077267,1.01507672592141,1.7232583208830499,0.498436336156558,1.1463250929814,0.5981236033878691,1.37559011157769,0.697810870619181,1.60485513017397,0.7974981378504931,1.8341201487702499,0.42752517915708604,1.17461577598239,0.513030214988503,1.4095389311788602,0.59853525081992,1.6444620863753399,0.6840402866513371,1.87938524157182,0.38477266124137705,1.05715419838415,0.470277697072795,1.29207735358062,0.5557827329042121,1.5270005087771,0.6412877687356291,1.76192366397358,0.34202014332566905,0.9396926207859091,0.782608156852414,0.6225146366376201,0.7009092642998511,0.713250449154182,0.608761429008721,0.7933533402912349,0.507538362960704,0.861629160441526,0.398749068925246,0.917060074385124,-2.0,0.0,-1.75,0.0,-1.5,0.0,-1.25,0.0,-1.9632543668953297,0.38161799075309005,-1.71784757103341,0.333915741908953,-1.4724407751715,0.286213493064817,-1.22703397930958,0.23851124422068104,-1.85436770913357,0.749213186831824,-1.62257174549188,0.655561538477846,-1.39077578185018,0.561909890123868,-1.15897981820848,0.46825824176988995,-1.6773411358908499,1.08927807003005,-1.4676734939044902,0.953118311276297,-1.25800585191814,0.816958552522541,-1.04833820993178,0.680798793768784,-1.4386796006773,1.38931674091799,-1.25884465059264,1.21565214830325,-1.07900970050798,1.0419875556885,-0.8991747504233141,0.868322963073747,-1.0,0.0,-0.981627183447664,0.19080899537654503,-0.9271838545667871,0.374606593415912,-0.838670567945424,0.544639035015027,-0.7193398003386511,0.694658370458997,-1.00375876361433,1.43351607750574,-0.8603646545265691,1.22872806643349,-0.716970545438808,1.02394005536124,-0.5735764363510459,0.8191520442889921,-1.14715287270209,1.6383040885779798,-0.8134732861516011,1.8270909152852002,-0.71178912538265,1.59870455087455,-0.6101049646137,1.3703181864639,-0.50842080384475,1.14193182205325,-0.4067366430758,0.9135454576426011,-0.44990210868773,1.9487401295704703,-0.39366434510176407,1.70514761337416,-0.337426581515798,1.4615550971778501,-0.281188817929831,1.21796258098154,-0.224951054343865,0.974370064785235,-0.06979899340500181,1.9987816540381902,-0.0610741192293767,1.74893394728342,-0.0523492450537515,1.49908624052864,-0.0436243708781263,1.24923853377387,-0.03489949670250091,0.9993908270190961,0.312868930080462,1.97537668119028,0.27376031382040406,1.72845459604149,0.23465169756034704,1.48153251089271,0.19554308130028902,1.23461042574392,0.156434465040231,0.9876883405951381],219,2) - coo.setInfoOnComponents(["X [INCONNUE]","Y [INCONNUE]"]) - m=MEDCouplingUMesh("MA2",2) - m.setDescription("CREE PAR CODE_ASTER") ; m.setTimeUnit("SANS UNITES") ; m.setTime(-1.,-1,-1) - m.setCoords(coo) - m.allocateCells(0) - conn=[[198,194,200],[198,200,199],[194,195,200],[195,201,200],[195,196,202],[195,202,201],[196,197,202],[197,203,202],[199,200,205],[199,205,204],[200,201,205],[201,206,205],[201,202,207],[201,207,206],[202,203,207],[203,208,207],[204,205,210],[204,210,209],[205,206,210],[206,211,210],[206,207,212],[206,212,211],[207,208,212],[208,213,212],[209,210,215],[209,215,214],[210,211,215],[211,216,215],[211,212,217],[211,217,216],[212,213,217],[213,218,217],[214,215,157],[214,157,158],[215,216,157],[216,156,157],[216,217,155],[216,155,156],[217,218,155],[218,163,155],[169,170,174,173],[170,171,175,174],[171,172,176,175],[172,189,190,176],[173,174,178,177],[174,175,179,178],[175,176,180,179],[176,190,191,180],[177,178,182,181],[178,179,183,182],[179,180,184,183],[180,191,192,184],[181,182,186,185],[182,183,187,186],[183,184,188,187],[184,192,193,188],[185,186,194,198],[186,187,195,194],[187,188,196,195],[188,193,197,196],[0,2,1,27,62,89],[1,7,0,28,63,89],[2,3,1,29,64,62],[3,9,1,30,36,64],[3,5,4,31,65,90],[4,9,3,32,30,90],[5,6,4,33,66,65],[6,11,4,34,39,66],[7,1,8,28,67,91],[8,12,7,35,68,91],[1,9,8,36,69,67],[9,14,8,37,42,69],[9,4,10,32,70,92],[10,14,9,38,37,92],[4,11,10,39,71,70],[11,16,10,40,45,71],[12,8,13,35,72,93],[13,17,12,41,73,93],[8,14,13,42,74,72],[14,19,13,43,48,74],[14,10,15,38,75,94],[15,19,14,44,43,94],[10,16,15,45,76,75],[16,21,15,46,51,76],[17,13,18,41,77,95],[18,22,17,47,78,95],[13,19,18,48,79,77],[19,24,18,49,54,79],[19,15,20,44,80,96],[20,24,19,50,49,96],[15,21,20,51,81,80],[21,26,20,52,57,81],[22,18,23,47,82,97],[23,59,22,53,83,97],[18,24,23,54,84,82],[24,60,23,55,85,84],[24,20,25,50,86,98],[25,60,24,56,55,98],[20,26,25,57,87,86],[26,61,25,58,88,87],[59,23,100,99,53,135,115,164],[23,60,101,100,85,136,116,135],[60,25,102,101,56,137,117,136],[25,61,131,102,88,138,118,137],[99,100,104,103,115,139,119,165],[100,101,105,104,116,140,120,139],[101,102,106,105,117,141,121,140],[102,131,132,106,118,142,122,141],[103,104,108,107,119,143,123,166],[104,105,109,108,120,144,124,143],[105,106,110,109,121,145,125,144],[106,132,133,110,122,146,126,145],[107,108,112,111,123,147,127,167],[108,109,113,112,124,148,128,147],[109,110,114,113,125,149,129,148],[110,133,134,114,126,150,130,149],[111,112,155,163,127,151,159,168],[112,113,156,155,128,152,160,151],[113,114,157,156,129,153,161,152],[114,134,158,157,130,154,162,153]] - for i in xrange(0,40): - m.insertNextCell(NORM_TRI3,conn[i]) - pass - for i in xrange(40,60): - m.insertNextCell(NORM_QUAD4,conn[i]) - pass - for i in xrange(60,100): - m.insertNextCell(NORM_TRI6,conn[i]) - pass - for i in xrange(100,120): - m.insertNextCell(NORM_QUAD8,conn[i]) - pass - fff=MEDCouplingFieldDouble.New(ON_GAUSS_PT) ; fff.setName("CH2RB") ; fff.setNature(ConservativeVolumic) - fff.setMesh(m) - fff.setGaussLocalizationOnCells(range(0,40),[0.,0.,1.,0.,0.,1.],[0.3333333333333333,0.3333333333333333],[0.5]) - fff.setGaussLocalizationOnCells(range(40,60),[-1.,-1.,1.,-1.,1.,1.,-1.,1.],[-0.577350269189626,-0.577350269189626,0.577350269189626,-0.577350269189626,0.577350269189626,0.577350269189626,-0.577350269189626,0.577350269189626],[1.,1.,1.,1.]) - fff.setGaussLocalizationOnCells(range(60,100),[0.,0.,1.,0.,0.,1.,0.5, 0.,0.5, 0.5, 0.,0.5],[0.16666666666666666,0.16666666666666666,0.6666666666666666,0.16666666666666666,0.16666666666666666,0.6666666666666666],[0.16666666666666666,0.16666666666666666,0.16666666666666666]) - fff.setGaussLocalizationOnCells(range(100,120),[-1.,-1.,1.,-1.,1.,1.,-1.,1.,0.,-1.,1.,0.,0.,1.,-1.,0.],[-0.774596669241483,-0.774596669241483,0.774596669241483,-0.774596669241483,0.774596669241483,0.774596669241483,-0.774596669241483,0.774596669241483,0.0,-0.774596669241483,0.774596669241483,0.0,0.0,0.774596669241483,-0.774596669241483,0.0,0.0,0.0],[0.30864197530864196,0.30864197530864196,0.30864197530864196,0.30864197530864196,0.49382716049382713,0.49382716049382713,0.49382716049382713,0.49382716049382713,0.7901234567901234]) - return MEDCouplingFieldTemplate(fff) - - # 3D usecase1 for interpolation Gauss Pt-> Gauss Pt. Coming from ASTER : Please, do not touch - def buildFieldOnGauss_3(self): - coo=DataArrayDouble([0.,1.,0.,0.,2.,0.,0.,3.,0.,1.,1.,0.,1.,2.,0.,1.,3.,0.,0.,1.,1.,0.,3.,1.,0.5,1.,1.,0.5,3.,1.,1.,1.,1.,1.,3.,1.,0.,0.,0.,0.,1.,0.,1.,0.,0.,1.,1.,0.,0.,0.,1.,0.,0.5,1.,0.,1.,1.,0.5,0.,1.,0.5,0.5,1.,0.5,1.,1.,1.,0.,1.,1.,0.5,1.,1.,1.,1.0],25,3) - coo.setInfoOnComponents(["X [INCONNUE]","Y [INCONNUE]","Z [INCONNUE]"]) - m=MEDCouplingUMesh("MA1",3) - m.setDescription("CREE PAR CODE_ASTER") ; m.setTimeUnit("SANS UNITES") ; m.setTime(-1.,-1,-1) - m.setCoords(coo) - m.allocateCells(0) - conn=[[3,10,8,4],[19,22,23,20,14],[0,6,1,3,8,4],[4,8,10,5,9,11],[12,16,17,14,19,20],[14,20,23,15,21,24],[1,2,5,4,6,7,9,8],[12,13,15,14,17,18,21,20]] - m.insertNextCell(NORM_TETRA4,conn[0]) - m.insertNextCell(NORM_PYRA5,conn[1]) - for i in xrange(2,6): - m.insertNextCell(NORM_PENTA6,conn[i]) - pass - m.insertNextCell(NORM_HEXA8,conn[6]) - m.insertNextCell(NORM_HEXA8,conn[7]) - fff=MEDCouplingFieldDouble.New(ON_GAUSS_PT) ; fff.setName("CH13") ; fff.setNature(ConservativeVolumic) - fff.setMesh(m) - fff.setGaussLocalizationOnCells([0],[0.,1.,0.,0.,0.,0.,0.,0.,1.,1.,0.,0.],[0.25,0.25,0.25],[0.16666666666666666]) - fff.setGaussLocalizationOnCells([1],[1.,0.,0.,0.,-1.,0.,-1.,0.,0.,0.,1.,0.,0.,0.,1.],[0.5,0.,0.1531754163448146,0.,0.5,0.1531754163448146,-0.5,0.,0.1531754163448146,0.,-0.5,0.1531754163448146,0.,0.,0.6372983346207416],[0.1333333333333333,0.1333333333333333,0.1333333333333333,0.1333333333333333,0.1333333333333333]) - fff.setGaussLocalizationOnCells([2,3,4,5],[-1.,1.,0.,-1.,0.,0.,-1.,0.,1.,1.,1.,0.,1.,0.,0.,1.,0.,1.],[-0.577350269189626,0.5,0.5,-0.577350269189626,0.,0.5,-0.577350269189626,0.5,0.,0.577350269189626,0.5,0.5,0.577350269189626,0.,0.5,0.577350269189626,0.5,0.],[0.16666666666666666,0.16666666666666666,0.16666666666666666,0.16666666666666666,0.16666666666666666,0.16666666666666666]) - fff.setGaussLocalizationOnCells([6,7],[-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.577350269189626,-0.577350269189626,-0.577350269189626,-0.577350269189626,-0.577350269189626,0.577350269189626,-0.577350269189626,0.577350269189626,-0.577350269189626,-0.577350269189626,0.577350269189626,0.577350269189626,0.577350269189626,-0.577350269189626,-0.577350269189626,0.577350269189626,-0.577350269189626,0.577350269189626,0.577350269189626,0.577350269189626,-0.577350269189626,0.577350269189626,0.577350269189626,0.577350269189626],[1.,1.,1.,1.,1.,1.,1.,1.]) - return MEDCouplingFieldTemplate(fff) - - # 3D usecase2 for interpolation Gauss Pt-> Gauss Pt. Coming from ASTER : Please, do not touch - def buildFieldOnGauss_4(self): - coo=DataArrayDouble([0.,2.,0.,0.,1.,0.,0.,0.,0.,1.,2.,0.,1.,1.,0.,1.,0.,0.,0.,2.,1.,0.,0.,1.,0.5, 2.,1.,0.5, 0.,1.,1.,2.,1.,1.,0.,1.,0.,3.,0.,0.,2.,0.,1.,3.,0.,1.,2.,0.,0.,3.,1.,0.,2.5, 1.,0.,2.,1.,0.5, 3.,1.,0.5, 2.5, 1.,0.5, 2.,1.,1.,3.,1.,1.,2.5, 1.,1.,2.,1.0],25,3) - coo.setInfoOnComponents(["X [INCONNUE]","Y [INCONNUE]","Z [INCONNUE]"]) - m=MEDCouplingUMesh("MA2",3) - m.setDescription("CREE PAR CODE_ASTER") ; m.setTimeUnit("SANS UNITES") ; m.setTime(-1.,-1,-1) - m.setCoords(coo) - m.allocateCells(0) - conn=[[3,10,8,4],[19,22,23,20,14],[0,6,1,3,8,4],[4,8,10,5,9,11],[12,16,17,14,19,20],[14,20,23,15,21,24],[1,2,5,4,6,7,9,8],[12,13,15,14,17,18,21,20]] - m.insertNextCell(NORM_TETRA4,conn[0]) - m.insertNextCell(NORM_PYRA5,conn[1]) - for i in xrange(2,6): - m.insertNextCell(NORM_PENTA6,conn[i]) - pass - m.insertNextCell(NORM_HEXA8,conn[6]) - m.insertNextCell(NORM_HEXA8,conn[7]) - fff=MEDCouplingFieldDouble.New(ON_GAUSS_PT) ; fff.setName("CH23") ; fff.setNature(ConservativeVolumic) - fff.setMesh(m) - fff.setGaussLocalizationOnCells([0],[0.,1.,0.,0.,0.,0.,0.,0.,1.,1.,0.,0.],[0.25,0.25,0.25],[0.16666666666666666]) - fff.setGaussLocalizationOnCells([1],[1.,0.,0.,0.,-1.,0.,-1.,0.,0.,0.,1.,0.,0.,0.,1.],[0.5,0.,0.1531754163448146,0.,0.5,0.1531754163448146,-0.5,0.,0.1531754163448146,0.,-0.5,0.1531754163448146,0.,0.,0.6372983346207416],[0.1333333333333333,0.1333333333333333,0.1333333333333333,0.1333333333333333,0.1333333333333333]) - fff.setGaussLocalizationOnCells([2,3,4,5],[-1.,1.,0.,-1.,0.,0.,-1.,0.,1.,1.,1.,0.,1.,0.,0.,1.,0.,1.],[-0.577350269189626,0.5,0.5,-0.577350269189626,0.,0.5,-0.577350269189626,0.5,0.,0.577350269189626,0.5,0.5,0.577350269189626,0.,0.5,0.577350269189626,0.5,0.],[0.16666666666666666,0.16666666666666666,0.16666666666666666,0.16666666666666666,0.16666666666666666,0.16666666666666666]) - fff.setGaussLocalizationOnCells([6,7],[-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.577350269189626,-0.577350269189626,-0.577350269189626,-0.577350269189626,-0.577350269189626,0.577350269189626,-0.577350269189626,0.577350269189626,-0.577350269189626,-0.577350269189626,0.577350269189626,0.577350269189626,0.577350269189626,-0.577350269189626,-0.577350269189626,0.577350269189626,-0.577350269189626,0.577350269189626,0.577350269189626,0.577350269189626,-0.577350269189626,0.577350269189626,0.577350269189626,0.577350269189626],[1.,1.,1.,1.,1.,1.,1.,1.]) - return MEDCouplingFieldTemplate(fff) - - def buildCircle(self, center_X, center_Y, radius): - from cmath import rect - from math import pi - - c = [rect(radius, i*pi/4.0) for i in range(8)] - coords = [c[-1].real,c[-1].imag, c[3].real,c[3].imag, - c[5].real,c[5].imag, c[1].real,c[1].imag] - connec = range(4) - baseMesh = MEDCouplingUMesh.New("circle", 2) - baseMesh.allocateCells(1) - meshCoords = DataArrayDouble.New(coords, len(coords)/2, 2) - meshCoords += (center_X, center_Y) - baseMesh.setCoords(meshCoords) - - baseMesh.insertNextCell(NORM_QPOLYG, connec) - baseMesh.finishInsertingCells() - return baseMesh - - def buildCircle2(self, center_X, center_Y, radius): - from cmath import rect - from math import pi - - c = [rect(radius, i*pi/4.0) for i in range(8)] - coords = [] - for i in range(8): - coords.extend([c[i].real,c[i].imag]) - connec = [7,5,3,1, 6,4,2,0] - baseMesh = MEDCouplingUMesh.New("circle", 2) - baseMesh.allocateCells(1) - meshCoords = DataArrayDouble.New(coords, len(coords)/2, 2) - meshCoords += (center_X, center_Y) - baseMesh.setCoords(meshCoords) - - baseMesh.insertNextCell(NORM_QPOLYG, connec) - baseMesh.finishInsertingCells() - return baseMesh - - build2DTargetMesh_1=classmethod(build2DTargetMesh_1) - build2DSourceMesh_1=classmethod(build2DSourceMesh_1) - build3DTargetMesh_1=classmethod(build3DTargetMesh_1) - build3DSourceMesh_1=classmethod(build3DSourceMesh_1) - build3DSurfTargetMesh_1=classmethod(build3DSurfTargetMesh_1) - build3DExtrudedUMesh_1=classmethod(build3DExtrudedUMesh_1) - buildCU1DMesh_U=classmethod(buildCU1DMesh_U) - build2DTargetMeshMergeNode_1=classmethod(build2DTargetMeshMergeNode_1) - build3DTargetMeshMergeNode_1=classmethod(build3DTargetMeshMergeNode_1) - build2DTargetMeshMerged_1=classmethod(build2DTargetMeshMerged_1) - build2DTargetMesh_2=classmethod(build2DTargetMesh_2) - build1DSourceMesh_2=classmethod(build1DSourceMesh_2) - build1DTargetMesh_3=classmethod(build1DTargetMesh_3) - build2DCurveTargetMesh_3=classmethod(build2DCurveTargetMesh_3) - build2DTargetMesh_3=classmethod(build2DTargetMesh_3) - build2DTargetMesh_4=classmethod(build2DTargetMesh_4) - buildMultiFields_1=classmethod(buildMultiFields_1) - buildMultiFields_2=classmethod(buildMultiFields_2) - build1DMultiTypes_1=classmethod(build1DMultiTypes_1) - build2DMultiTypes_1=classmethod(build2DMultiTypes_1) - build3DMultiTypes_1=classmethod(build3DMultiTypes_1) - buildCoordsForMultiTypes_1=classmethod(buildCoordsForMultiTypes_1) - buildHexa8Mesh_1=classmethod(buildHexa8Mesh_1) - buildPointe_1=classmethod(buildPointe_1) - buildFieldOnGauss_1=classmethod(buildFieldOnGauss_1) - buildFieldOnGauss_2=classmethod(buildFieldOnGauss_2) - buildFieldOnGauss_3=classmethod(buildFieldOnGauss_3) - buildFieldOnGauss_4=classmethod(buildFieldOnGauss_4) - buildCircle=classmethod(buildCircle) - buildCircle2=classmethod(buildCircle2) - pass - - - diff --git a/src/MEDCoupling_Swig/MEDCouplingExamplesTest.py b/src/MEDCoupling_Swig/MEDCouplingExamplesTest.py deleted file mode 100644 index 3ebd2170d..000000000 --- a/src/MEDCoupling_Swig/MEDCouplingExamplesTest.py +++ /dev/null @@ -1,2343 +0,0 @@ -# -*- coding: iso-8859-1 -*- -# Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 -# 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 -# - -from MEDCoupling import * -import unittest -from math import pi, sqrt - -class MEDCouplingBasicsTest(unittest.TestCase): - - def testExample_MEDCouplingFieldDouble_WriteVTK(self): - #! [PySnippet_MEDCouplingFieldDouble_WriteVTK_1] - # mesh - coords = [0.,2.,4.] - coordsArr=DataArrayDouble(coords,3,1) - mesh=MEDCouplingCMesh() - mesh.setCoords(coordsArr,coordsArr) # mesh becomes a 2D one - - # 3 fields (lying on the same mesh!) - field1 = mesh.getMeasureField( True ) - field2 = mesh.buildOrthogonalField() - field3 = mesh.fillFromAnalytic( ON_CELLS, 2, "IVec * x + JVec * y" ) - field2.setName( "Normal" ) # name is necessary! - field3.setName( "Barycenter" ) # name is necessary! - - # WriteVTK - fileName = "testExample_MEDCouplingFieldDouble_WriteVTK" - fs = [ field1, field2, field3 ] # field series - writtenFileName=MEDCouplingFieldDouble.WriteVTK( fileName, fs ) - print "The file name with correct extension is : %s"%(writtenFileName) - #! [PySnippet_MEDCouplingFieldDouble_WriteVTK_1] - import os - os.remove( writtenFileName ) - - return - - def testExample_MEDCouplingFieldDouble_MaxFields(self): - #! [PySnippet_MEDCouplingFieldDouble_MaxFields_1] - vals1 = [0.,2., 4.,6.] # for field 1 - vals2 = [2.,0., 6.,4.] # for field 2 - valsMax = [2.,2., 6.,6.] # expected max field - valsMin = [0.,0., 4.,4.] # expected min field - - # field 1 - valsArr1=DataArrayDouble(vals1,2,2) # 2 tuples per 2 components - field1 = MEDCouplingFieldDouble( ON_NODES ) - field1.setArray( valsArr1 ) - - # field 2 - valsArr2=DataArrayDouble(vals2,2,2) # 2 tuples per 2 components - field2 = MEDCouplingFieldDouble( ON_NODES ) - field2.setArray( valsArr2 ) - - # max field - fieldMax = MEDCouplingFieldDouble.MaxFields( field1, field2 ) - self.assertTrue( fieldMax.getArray().getValues() == valsMax ) - - # min field - fieldMin = MEDCouplingFieldDouble.MinFields( field1, field2 ) - self.assertTrue( fieldMin.getArray().getValues() == valsMin ) - #! [PySnippet_MEDCouplingFieldDouble_MaxFields_1] - - def testExample_MEDCouplingFieldDouble_MergeFields(self): - #! [PySnippet_MEDCouplingFieldDouble_MergeFields_1] - # mesh 1 - coords = [0.,2.,4.] - coordsArr=DataArrayDouble(coords,3,1) - mesh1=MEDCouplingCMesh() - mesh1.setCoords(coordsArr) - # field 1 - field1 = mesh1.fillFromAnalytic( ON_CELLS, 1, "x") - - # mesh 2 and field 2 - field2 = field1.cloneWithMesh( True ) - vec = [5.] - field2.getMesh().translate(vec) # translate mesh2 - field2.applyFunc("x + 5") # "translate" field2 - - # concatenate field1 and field2 - field3 = MEDCouplingFieldDouble.MergeFields( field1, field2 ) - field4 = MEDCouplingFieldDouble.MergeFields( [ field1, field2] ) - #! [PySnippet_MEDCouplingFieldDouble_MergeFields_1] - return - - def testExample_MEDCouplingFieldDouble_substractInPlaceDM(self): - #! [PySnippet_MEDCouplingFieldDouble_substractInPlaceDM_1] - coords1=[0.,1.,2.,3.] - coords2=[2.,1.,0.,3.] #0 <==> #2 - # mesh 1 - mesh1=MEDCouplingUMesh() - coordsArr=DataArrayDouble(coords1, 4, 1) - mesh1.setCoords(coordsArr) - mesh1.setMeshDimension(0) - mesh1.allocateCells(0) - mesh1.finishInsertingCells() - # mesh 2 - mesh2=mesh1.deepCpy() - mesh2.getCoords().setValues(coords2, 4, 1) - #! [PySnippet_MEDCouplingFieldDouble_substractInPlaceDM_1] - #! [PySnippet_MEDCouplingFieldDouble_substractInPlaceDM_2] - field1 = mesh1.fillFromAnalytic(ON_NODES,1,"x") # field1 values == coords1 - field2 = mesh2.fillFromAnalytic(ON_NODES,1,"x") # field2 values == coords2 - levOfCheck = 10 # nodes can be permuted - field1.substractInPlaceDM( field2, levOfCheck, 1e-13, 0 ) # values #0 and #2 must swap - #! [PySnippet_MEDCouplingFieldDouble_substractInPlaceDM_2] - #! [PySnippet_MEDCouplingFieldDouble_substractInPlaceDM_3] - field2.applyFunc( 1, 0.0 ) # all field2 values == 0.0 - self.assertTrue( field1.isEqual( field2, 1e-13, 1e-13 )) # field1 == field2 == 0.0 - #! [PySnippet_MEDCouplingFieldDouble_substractInPlaceDM_3] - return - - def testExample_MEDCouplingFieldDouble_changeUnderlyingMesh(self): - #! [PySnippet_MEDCouplingFieldDouble_changeUnderlyingMesh_1] - coords1=[0.,1.,2.,3.] - coords2=[2.,1.,0.,3.] #0 <==> #2 - # mesh 1 - mesh1=MEDCouplingUMesh() - coordsArr=DataArrayDouble(coords1, 4, 1) - mesh1.setCoords(coordsArr) - mesh1.setMeshDimension(0) - mesh1.allocateCells(0) - mesh1.finishInsertingCells() - # mesh 2 - mesh2=mesh1.deepCpy() - mesh2.getCoords().setValues(coords2, 4, 1) - #! [PySnippet_MEDCouplingFieldDouble_changeUnderlyingMesh_1] - #! [PySnippet_MEDCouplingFieldDouble_changeUnderlyingMesh_2] - field = mesh1.fillFromAnalytic(ON_NODES,1,"x") # field values == coords1 - levOfCheck = 10 # nodes can be permuted - field.changeUnderlyingMesh( mesh2, levOfCheck, 1e-13, 0 ) # values #0 and #2 must swap - self.assertTrue( field.getArray().getValues() == coords2 ) - #! [PySnippet_MEDCouplingFieldDouble_changeUnderlyingMesh_2] - return - - def testExample_MEDCouplingFieldDouble_applyFunc_same_nb_comp(self): - #! [PySnippet_MEDCouplingFieldDouble_applyFunc_same_nb_comp_1] - v = [1.,2., 3.,4.] - array = DataArrayDouble( v, 2, 2 ) # 2 tuples per 2 components - field = MEDCouplingFieldDouble( ON_CELLS ) - field.setArray( array ) - func = "IVec * v + JVec * w*w + 10" - field.applyFunc( 2, func ) - self.assertTrue( field.getNumberOfComponents() == 2 ) # 2 components remains - #! [PySnippet_MEDCouplingFieldDouble_applyFunc_same_nb_comp_1] - #! [PySnippet_MEDCouplingFieldDouble_applyFunc_same_nb_comp_2] - v2 = field.getArray().getValues() - self.assertAlmostEqual( v2[0], 10 + v[0], 13 ) # "10 + IVec * v" - self.assertAlmostEqual( v2[1], 10 + v[1]*v[1], 13 ) # "10 + JVec * v*v" - self.assertAlmostEqual( v2[2], 10 + v[2], 13 ) # "10 + IVec * v" - self.assertAlmostEqual( v2[3], 10 + v[3]*v[3], 13 ) # "10 + JVec * v*v" - #! [PySnippet_MEDCouplingFieldDouble_applyFunc_same_nb_comp_2] - return - - def testExample_MEDCouplingFieldDouble_applyFunc3(self): - #! [PySnippet_MEDCouplingFieldDouble_applyFunc3_1] - # create a 2D vector field - values = [1.,1., 2.,1.] - array = DataArrayDouble( values, 2, 2 ) # 2 tuples per 2 components - field = MEDCouplingFieldDouble( ON_CELLS ) - field.setArray( array ) - # transform the field to a 3D vector field - func = "IVec * b + JVec * a + KVec * sqrt( a*a + b*b ) + 10" - varNames=["a","b"] # names used to refer to X and Y components - field.applyFunc3( 3, varNames, func ) # require 3 components - self.assertTrue( field.getNumberOfComponents() == 3 ) # 3 components as required - #! [PySnippet_MEDCouplingFieldDouble_applyFunc3_1] - #! [PySnippet_MEDCouplingFieldDouble_applyFunc3_2] - vec1 = field.getArray().getTuple(1) # vector #1 - a,b = values[2], values[3] # initial components of the vector #1 - self.assertAlmostEqual( vec1[0], 10 + b, 13 ) # "10 + IVec * b" - self.assertAlmostEqual( vec1[1], 10 + a, 13 ) # "10 + JVec * a" - self.assertAlmostEqual( vec1[2], 10 + sqrt(a*a+b*b), 13 ) # "10 + KVec * sqrt( a*a + b*b )" - #! [PySnippet_MEDCouplingFieldDouble_applyFunc3_2] - return - - def testExample_MEDCouplingFieldDouble_applyFunc2(self): - #! [PySnippet_MEDCouplingFieldDouble_applyFunc2_1] - # create a 2D vector field - values = [1.,1., 2.,1.] - array = DataArrayDouble( values, 2, 2 ) # 2 tuples per 2 components - array.setInfoOnComponent(0,"a") # name used to refer to X component within a function - array.setInfoOnComponent(1,"b") # name used to refer to Y component within a function - field = MEDCouplingFieldDouble( ON_CELLS ) - field.setArray( array ) - # transform the field to a 3D vector field - func = "IVec * b + JVec * a + KVec * sqrt( a*a + b*b ) + 10" - field.applyFunc2( 3, func ) # require 3 components - self.assertTrue( field.getNumberOfComponents() == 3 ) # 3 components as required - #! [PySnippet_MEDCouplingFieldDouble_applyFunc2_1] - #! [PySnippet_MEDCouplingFieldDouble_applyFunc2_2] - vec1 = field.getArray().getTuple(1) # vector #1 - a,b = values[2], values[3] # initial components of the vector #1 - self.assertAlmostEqual( vec1[0], 10 + b, 13 ) # "10 + IVec * b" - self.assertAlmostEqual( vec1[1], 10 + a, 13 ) # "10 + JVec * a" - self.assertAlmostEqual( vec1[2], 10 + sqrt(a*a+b*b), 13 ) # "10 + KVec * sqrt( a*a + b*b )" - #! [PySnippet_MEDCouplingFieldDouble_applyFunc2_2] - return - - def testExample_MEDCouplingFieldDouble_applyFunc(self): - #! [PySnippet_MEDCouplingFieldDouble_applyFunc_1] - # create a 2D vector field - values = [1.,1., 2.,1.] - array = DataArrayDouble( values, 2, 2 ) # 2 tuples per 2 components - field = MEDCouplingFieldDouble( ON_CELLS ) - field.setArray( array ) - # transform the field to a 3D vector field - func = "IVec * b + JVec * a + KVec * sqrt( a*a + b*b ) + 10" - field.applyFunc( 3, func ) # require 3 components - self.assertTrue( field.getNumberOfComponents() == 3 ) # 3 components as required - #! [PySnippet_MEDCouplingFieldDouble_applyFunc_1] - #! [PySnippet_MEDCouplingFieldDouble_applyFunc_2] - vec1 = field.getArray().getTuple(1) # vector #1 - a,b = values[2], values[3] # initial components of the vector #1 - self.assertAlmostEqual( vec1[0], 10 + b, 13 ) # "10 + IVec * b" - self.assertAlmostEqual( vec1[1], 10 + a, 13 ) # "10 + JVec * a" - self.assertAlmostEqual( vec1[2], 10 + sqrt(a*a+b*b), 13 ) # "10 + KVec * sqrt( a*a + b*b )" - #! [PySnippet_MEDCouplingFieldDouble_applyFunc_2] - return - - def testExample_MEDCouplingFieldDouble_applyFunc_val(self): - #! [PySnippet_MEDCouplingFieldDouble_applyFunc_val_1] - coords = [0.,2.,4.] - coordsArr=DataArrayDouble(coords,3,1) - mesh=MEDCouplingCMesh() - mesh.setCoords(coordsArr,coordsArr) - field = MEDCouplingFieldDouble( ON_CELLS ) - field.setMesh( mesh ) - field.fillFromAnalytic(2,"IVec * x + JVec * y") # 2 components - #! [PySnippet_MEDCouplingFieldDouble_applyFunc_val_1] - #! [PySnippet_MEDCouplingFieldDouble_applyFunc_val_2] - newValue = 7. - field.applyFunc( 3, newValue ) # 3 components are required - self.assertTrue( field.getIJ(1,0) == newValue ) # a value is as expected - self.assertTrue( field.getNumberOfComponents() == 3 ) - self.assertTrue( field.getNumberOfTuples() == mesh.getNumberOfCells() ) - #! [PySnippet_MEDCouplingFieldDouble_applyFunc_val_2] - return - - def testExample_MEDCouplingFieldDouble_fillFromAnalytic3(self): - #! [PySnippet_MEDCouplingFieldDouble_fillFromAnalytic3_1] - coords = [0.,2.,4.,6.] # 6. is not used - x=DataArrayDouble(coords[:3],3,1) - y=DataArrayDouble(coords[:2],2,1) - mesh=MEDCouplingCMesh() - mesh.setCoords(x,y) - #! [PySnippet_MEDCouplingFieldDouble_fillFromAnalytic3_1] - #! [PySnippet_MEDCouplingFieldDouble_fillFromAnalytic3_2] - field = MEDCouplingFieldDouble( ON_CELLS ) - field.setMesh( mesh ) - func = "IVec * b + JVec * a + KVec * sqrt( a*a + b*b ) + 10" - varNames=["a","b"] # names used to refer to X and Y coord components - field.fillFromAnalytic3(3,varNames,func) - #! [PySnippet_MEDCouplingFieldDouble_fillFromAnalytic3_2] - #! [PySnippet_MEDCouplingFieldDouble_fillFromAnalytic3_3] - vals1 = field.getArray().getTuple(1) # values of the cell #1 - assert len( vals1 ) == 3 # 3 components in the field - # - bc = mesh.getBarycenterAndOwner() # func is applied to barycenters of cells - bc1 = bc.getTuple(1) # coordinates of the second point - # - dist = sqrt( bc1[0]*bc1[0] + bc1[1]*bc1[1] ) # "sqrt( a*a + b*b )" - self.assertAlmostEqual( vals1[0], 10 + bc1[1], 13 ) # "10 + IVec * b" - self.assertAlmostEqual( vals1[1], 10 + bc1[0], 13 ) # "10 + JVec * a" - self.assertAlmostEqual( vals1[2], 10 + dist , 13 ) # "10 + KVec * sqrt( a*a + b*b )" - #! [PySnippet_MEDCouplingFieldDouble_fillFromAnalytic3_3] - return - - def testExample_MEDCouplingFieldDouble_fillFromAnalytic2(self): - #! [PySnippet_MEDCouplingFieldDouble_fillFromAnalytic2_1] - coords = [0.,2.,4.] - x=DataArrayDouble(coords[:3],3,1) - y=DataArrayDouble(coords[:2],2,1) - x.setInfoOnComponent(0,"a") # name used to refer to X coordinate within a function - y.setInfoOnComponent(0,"b") # name used to refer to Y coordinate within a function - mesh=MEDCouplingCMesh() - mesh.setCoords(x,y) - #! [PySnippet_MEDCouplingFieldDouble_fillFromAnalytic2_1] - #! [PySnippet_MEDCouplingFieldDouble_fillFromAnalytic2_2] - field = MEDCouplingFieldDouble( ON_CELLS ) - field.setMesh( mesh ) - func = "IVec * b + JVec * a + KVec * sqrt( a*a + b*b ) + 10" - field.fillFromAnalytic2(3,func) - #! [PySnippet_MEDCouplingFieldDouble_fillFromAnalytic2_2] - #! [PySnippet_MEDCouplingFieldDouble_fillFromAnalytic2_3] - vals1 = field.getArray().getTuple(1) # values of the cell #1 - assert len( vals1 ) == 3 # 3 components in the field - # - bc = mesh.getBarycenterAndOwner() # func is applied to barycenters of cells - bc1 = bc.getTuple(1) # coordinates of the second point - # - dist = sqrt( bc1[0]*bc1[0] + bc1[1]*bc1[1] ) # "sqrt( a*a + b*b )" - self.assertAlmostEqual( vals1[0], 10 + bc1[1], 13 ) # "10 + IVec * b" - self.assertAlmostEqual( vals1[1], 10 + bc1[0], 13 ) # "10 + JVec * a" - self.assertAlmostEqual( vals1[2], 10 + dist , 13 ) # "10 + KVec * sqrt( a*a + b*b )" - #! [PySnippet_MEDCouplingFieldDouble_fillFromAnalytic2_3] - return - - def testExample_MEDCouplingFieldDouble_fillFromAnalytic(self): - #! [PySnippet_MEDCouplingFieldDouble_fillFromAnalytic_1] - coords = [0.,2.,4.] - x=DataArrayDouble(coords[:3],3,1) - y=DataArrayDouble(coords[:2],2,1) - mesh=MEDCouplingCMesh() - mesh.setCoords(x,y) - #! [PySnippet_MEDCouplingFieldDouble_fillFromAnalytic_1] - #! [PySnippet_MEDCouplingFieldDouble_fillFromAnalytic_2] - field = MEDCouplingFieldDouble( ON_CELLS ) - field.setMesh( mesh ) - func = "IVec * b + JVec * a + KVec * sqrt( a*a + b*b ) + 10" - field.fillFromAnalytic(3,func) - #! [PySnippet_MEDCouplingFieldDouble_fillFromAnalytic_2] - #! [PySnippet_MEDCouplingFieldDouble_fillFromAnalytic_3] - vals1 = field.getArray().getTuple(1) # values of the cell #1 - assert len( vals1 ) == 3 # 3 components in the field - # - bc = mesh.getBarycenterAndOwner() # func is applied to barycenters of cells - bc1 = bc.getTuple(1) # coordinates of the second point - # - dist = sqrt( bc1[0]*bc1[0] + bc1[1]*bc1[1] ) # "sqrt( a*a + b*b )" - self.assertAlmostEqual( vals1[0], 10 + bc1[1], 13 ) # "10 + IVec * b" - self.assertAlmostEqual( vals1[1], 10 + bc1[0], 13 ) # "10 + JVec * a" - self.assertAlmostEqual( vals1[2], 10 + dist , 13 ) # "10 + KVec * sqrt( a*a + b*b )" - #! [PySnippet_MEDCouplingFieldDouble_fillFromAnalytic_3] - return - - def testExample_MEDCouplingFieldDouble_getValueOn_time(self): - #! [PySnippet_MEDCouplingFieldDouble_getValueOn_time_1] - coords = [0.,2.,4.] - coordsArr=DataArrayDouble(coords,3,1) - mesh=MEDCouplingCMesh() - mesh.setCoords(coordsArr,coordsArr) - #! [PySnippet_MEDCouplingFieldDouble_getValueOn_time_1] - #! [PySnippet_MEDCouplingFieldDouble_getValueOn_time_2] - field = MEDCouplingFieldDouble( ON_CELLS, LINEAR_TIME ) - field.setMesh( mesh ) - field.fillFromAnalytic(1,"10") # all values == 10. - field.setEndArray( field.getArray() + field.getArray() ) # all values == 20. - time1, time2 = 1.1, 22. - field.setStartTime( time1, 0, 0 ) - field.setEndTime ( time2, 0, 0 ) - #! [PySnippet_MEDCouplingFieldDouble_getValueOn_time_2] - #! [PySnippet_MEDCouplingFieldDouble_getValueOn_time_3] - pos = [ 1., 1. ] # we are in 2D space - value = field.getValueOn( pos, 0.5*( time1 + time2 )) - self.assertTrue( value[0] == 0.5*( 10. + 20.)) - #! [PySnippet_MEDCouplingFieldDouble_getValueOn_time_3] - return - - def testExample_MEDCouplingFieldDouble_getValueOnMulti(self): - #! [PySnippet_MEDCouplingFieldDouble_getValueOnMulti_1] - coords = [0.,2.,4.] - coordsArr=DataArrayDouble(coords,3,1) - mesh=MEDCouplingCMesh() - mesh.setCoords(coordsArr,coordsArr) - field = mesh.fillFromAnalytic(ON_CELLS,1,"x+y") - #! [PySnippet_MEDCouplingFieldDouble_getValueOnMulti_1] - #! [PySnippet_MEDCouplingFieldDouble_getValueOnMulti_2] - bc = mesh.getBarycenterAndOwner() # field values are located at cell barycenters - valArray = field.getValueOnMulti( bc ) - self.assertTrue( valArray.isEqual( field.getArray(), 1e-13 )) - #! [PySnippet_MEDCouplingFieldDouble_getValueOnMulti_2] - return - - def testExample_MEDCouplingFieldDouble_getValueOn(self): - #! [PySnippet_MEDCouplingFieldDouble_getValueOn_1] - coords = [0.,2.,4.] - coordsArr=DataArrayDouble(coords,3,1) - mesh=MEDCouplingCMesh() - mesh.setCoords(coordsArr,coordsArr) - field = mesh.fillFromAnalytic(ON_CELLS,1,"x+y") - #! [PySnippet_MEDCouplingFieldDouble_getValueOn_1] - #! [PySnippet_MEDCouplingFieldDouble_getValueOn_2] - bc = mesh.getBarycenterAndOwner() # field values are located at cell barycenters - vals = [] # array to collect values returned by getValueOn() - for i,tupl in enumerate( bc ): - vals.extend( field.getValueOn( tupl ) ) - self.assertTrue( vals == field.getArray().getValues() ) - #! [PySnippet_MEDCouplingFieldDouble_getValueOn_2] - return - - def testExample_MEDCouplingFieldDouble_getValueOnPos(self): - #! [PySnippet_MEDCouplingFieldDouble_getValueOnPos_1] - coords = [0.,2.,4.] - coordsArr=DataArrayDouble(coords,3,1) - mesh=MEDCouplingCMesh() - mesh.setCoords(coordsArr,coordsArr) - field = mesh.fillFromAnalytic(ON_CELLS,1,"x+y") - #! [PySnippet_MEDCouplingFieldDouble_getValueOnPos_1] - #! [PySnippet_MEDCouplingFieldDouble_getValueOnPos_2] - val11 = field.getValueOnPos( 1,1,-1) - bc = mesh.getBarycenterAndOwner() # field values are located at cell barycenters - self.assertTrue( val11[0] == bc[3,0] + bc[3,1] ) - #! [PySnippet_MEDCouplingFieldDouble_getValueOnPos_2] - return - - def testExample_MEDCouplingFieldDouble_renumberNodes(self): - #! [PySnippet_MEDCouplingFieldDouble_renumberNodes_1] - coords = [0.,2.,4.] - coordsArr=DataArrayDouble(coords,3,1) - mesh=MEDCouplingCMesh() - mesh.setCoords(coordsArr,coordsArr) - mesh=mesh.buildUnstructured() - #! [PySnippet_MEDCouplingFieldDouble_renumberNodes_1] - #! [PySnippet_MEDCouplingFieldDouble_renumberNodes_2] - field = mesh.fillFromAnalytic(ON_NODES,2,"IVec*x+JVec*y") - values = field.getArray() - nodeCoords = mesh.getCoords() - self.assertTrue( values.isEqualWithoutConsideringStr( nodeCoords, 1e-13 )) - #! [PySnippet_MEDCouplingFieldDouble_renumberNodes_2] - #! [PySnippet_MEDCouplingFieldDouble_renumberNodes_3] - renumber = [8, 7, 6, 5, 4, 3, 2, 1, 0] - field.renumberNodes(renumber,False) - mesh2 = field.getMesh() # field now refers to another mesh - values = field.getArray() - nodeCoords = mesh2.getCoords() - self.assertTrue( values.isEqualWithoutConsideringStr( nodeCoords, 1e-13 )) - #! [PySnippet_MEDCouplingFieldDouble_renumberNodes_3] - return - - - def testExample_MEDCouplingFieldDouble_renumberCells(self): - #! [PySnippet_MEDCouplingFieldDouble_renumberCells_1] - coords = [0.,2.,4.] - coordsArr=DataArrayDouble(coords,3,1) - mesh=MEDCouplingCMesh() - mesh.setCoords(coordsArr,coordsArr) - mesh=mesh.buildUnstructured() - #! [PySnippet_MEDCouplingFieldDouble_renumberCells_1] - #! [PySnippet_MEDCouplingFieldDouble_renumberCells_2] - field = mesh.fillFromAnalytic(ON_CELLS,2,"IVec*x+JVec*y") - values = field.getArray() - bc = mesh.getBarycenterAndOwner() - self.assertTrue( values.isEqualWithoutConsideringStr( bc, 1e-13 )) - #! [PySnippet_MEDCouplingFieldDouble_renumberCells_2] - #! [PySnippet_MEDCouplingFieldDouble_renumberCells_3] - renumber = [ 3, 2, 1, 0 ] - field.renumberCells(renumber,False) - mesh2 = field.getMesh() # field now refers to another mesh - values = field.getArray() - bc = mesh2.getBarycenterAndOwner() - self.assertTrue( values.isEqualWithoutConsideringStr( bc, 1e-13 )) - #! [PySnippet_MEDCouplingFieldDouble_renumberCells_3] - return - - def testExample_MEDCouplingFieldDouble_buildNewTimeReprFromThis(self): - #! [PySnippet_MEDCouplingFieldDouble_buildNewTimeReprFromThis_1] - coords = [0.,2.,4.] - coordsArr=DataArrayDouble(coords,3,1) - mesh=MEDCouplingCMesh() - mesh.setCoords(coordsArr,coordsArr) - field1 = mesh.fillFromAnalytic(ON_NODES,1,"x+y") - self.assertTrue( field1.getTimeDiscretization() == ONE_TIME ) - #! [PySnippet_MEDCouplingFieldDouble_buildNewTimeReprFromThis_1] - #! [PySnippet_MEDCouplingFieldDouble_buildNewTimeReprFromThis_2] - field2 = field1.buildNewTimeReprFromThis(NO_TIME,False) - self.assertTrue( field2.getTimeDiscretization() == NO_TIME ) - #! [PySnippet_MEDCouplingFieldDouble_buildNewTimeReprFromThis_2] - return - - def testExample_MEDCouplingMesh_fillFromAnalytic3(self): - #! [PySnippet_MEDCouplingMesh_fillFromAnalytic3_1] - coords = [0.,2.,4.,6.] # 6. is not used - x=DataArrayDouble(coords[:3],3,1) - y=DataArrayDouble(coords[:2],2,1) - mesh=MEDCouplingCMesh() - mesh.setCoords(x,y) - #! [PySnippet_MEDCouplingMesh_fillFromAnalytic3_1] - #! [PySnippet_MEDCouplingMesh_fillFromAnalytic3_2] - func = "IVec * b + JVec * a + KVec * sqrt( a*a + b*b ) + 10" - varNames=["a","b"] # names used to refer to X and Y coord components - field=mesh.fillFromAnalytic3(ON_CELLS,3,varNames,func) - #! [PySnippet_MEDCouplingMesh_fillFromAnalytic3_2] - #! [PySnippet_MEDCouplingMesh_fillFromAnalytic3_3] - vals1 = field.getArray().getTuple(1) # values of the cell #1 - assert len( vals1 ) == 3 # 3 components in the field - # - bc = mesh.getBarycenterAndOwner() # func is applied to barycenters of cells - bc1 = bc.getTuple(1) # coordinates of the second point - # - dist = sqrt( bc1[0]*bc1[0] + bc1[1]*bc1[1] ) # "sqrt( a*a + b*b )" - self.assertAlmostEqual( vals1[0], 10 + bc1[1], 13 ) # "10 + IVec * b" - self.assertAlmostEqual( vals1[1], 10 + bc1[0], 13 ) # "10 + JVec * a" - self.assertAlmostEqual( vals1[2], 10 + dist , 13 ) # "10 + KVec * sqrt( a*a + b*b )" - #! [PySnippet_MEDCouplingMesh_fillFromAnalytic3_3] - return - - def testExample_MEDCouplingMesh_fillFromAnalytic2(self): - #! [PySnippet_MEDCouplingMesh_fillFromAnalytic2_1] - coords = [0.,2.,4.,6.] # 6. is not used - x=DataArrayDouble(coords[:3],3,1) - y=DataArrayDouble(coords[:2],2,1) - x.setInfoOnComponent(0,"a") # name used to refer to X coordinate within a function - y.setInfoOnComponent(0,"b") # name used to refer to Y coordinate within a function - mesh=MEDCouplingCMesh() - mesh.setCoords(x,y) - #! [PySnippet_MEDCouplingMesh_fillFromAnalytic2_1] - #! [PySnippet_MEDCouplingMesh_fillFromAnalytic2_2] - func = "IVec * b + JVec * a + KVec * sqrt( a*a + b*b ) + 10" - field=mesh.fillFromAnalytic2(ON_CELLS,3,func) - #! [PySnippet_MEDCouplingMesh_fillFromAnalytic2_2] - #! [PySnippet_MEDCouplingMesh_fillFromAnalytic2_3] - vals1 = field.getArray().getTuple(1) # values of the cell #1 - assert len( vals1 ) == 3 # 3 components in the field - # - bc = mesh.getBarycenterAndOwner() # func is applied to barycenters of cells - bc1 = bc.getTuple(1) # coordinates of the second point - # - dist = sqrt( bc1[0]*bc1[0] + bc1[1]*bc1[1] ) # "sqrt( a*a + b*b )" - self.assertAlmostEqual( vals1[0], 10 + bc1[1], 13 ) # "10 + IVec * b" - self.assertAlmostEqual( vals1[1], 10 + bc1[0], 13 ) # "10 + JVec * a" - self.assertAlmostEqual( vals1[2], 10 + dist , 13 ) # "10 + KVec * sqrt( a*a + b*b )" - #! [PySnippet_MEDCouplingMesh_fillFromAnalytic2_3] - return - - def testExample_MEDCouplingMesh_fillFromAnalytic(self): - #! [PySnippet_MEDCouplingMesh_fillFromAnalytic_1] - coords = [0.,2.,4.,6.] # 6. is not used - x=DataArrayDouble(coords[:3],3,1) - y=DataArrayDouble(coords[:2],2,1) - mesh=MEDCouplingCMesh() - mesh.setCoords(x,y) - #! [PySnippet_MEDCouplingMesh_fillFromAnalytic_1] - #! [PySnippet_MEDCouplingMesh_fillFromAnalytic_2] - func = "IVec * b + JVec * a + KVec * sqrt( a*a + b*b ) + 10" - field=mesh.fillFromAnalytic(ON_CELLS,3,func) - #! [PySnippet_MEDCouplingMesh_fillFromAnalytic_2] - #! [PySnippet_MEDCouplingMesh_fillFromAnalytic_3] - vals1 = field.getArray().getTuple(1) # values of the cell #1 - assert len( vals1 ) == 3 # 3 components in the field - # - bc = mesh.getBarycenterAndOwner() # func is applied to barycenters of cells - bc1 = bc.getTuple(1) # coordinates of the second point - # - dist = sqrt( bc1[0]*bc1[0] + bc1[1]*bc1[1] ) # "sqrt( a*a + b*b )" - self.assertAlmostEqual( vals1[0], 10 + bc1[1], 13 ) # "10 + IVec * b" - self.assertAlmostEqual( vals1[1], 10 + bc1[0], 13 ) # "10 + JVec * a" - self.assertAlmostEqual( vals1[2], 10 + dist , 13 ) # "10 + KVec * sqrt( a*a + b*b )" - #! [PySnippet_MEDCouplingMesh_fillFromAnalytic_3] - return - - def testExample_MEDCouplingCMesh_getCoordsAt(self): - #! [PySnippet_MEDCouplingCMesh_getCoordsAt_1] - coords = [1.,2.,4.] - x=DataArrayDouble(coords,3,1) - mesh=MEDCouplingCMesh() - mesh.setCoordsAt(0,x) - x2=mesh.getCoordsAt(0) - assert coords == x2.getValues() - #! [PySnippet_MEDCouplingCMesh_getCoordsAt_1] - return - - def testExample_MEDCouplingUMesh_areCellsIncludedIn(self): - #! [PySnippet_MEDCouplingUMesh_areCellsIncludedIn_1] - mesh1=MEDCouplingUMesh() - mesh1.setMeshDimension(2) - mesh1.allocateCells(5) - conn=[0,3,4,1, 1,2,4, 4,5,2, 6,7,4,3, 7,8,5,4] - mesh1.insertNextCell(NORM_QUAD4,4,conn[0:4]) # 0 - mesh1.insertNextCell(NORM_TRI3,3, conn[4:7]) # 1 - mesh1.insertNextCell(NORM_TRI3,3, conn[7:10]) # 2 - mesh1.insertNextCell(NORM_QUAD4,4,conn[10:14]) # 3 - mesh1.insertNextCell(NORM_QUAD4,4,conn[14:18]) # 4 - mesh1.finishInsertingCells() - coords=[-0.3,-0.3, 0.2,-0.3, 0.7,-0.3, -0.3,0.2, 0.2,0.2, 0.7,0.2, -0.3,0.7, 0.2,0.7, 0.7,0.7 ] - coordsArr=DataArrayDouble(coords,9,2) - mesh1.setCoords(coordsArr) - #! [PySnippet_MEDCouplingUMesh_areCellsIncludedIn_1] - #! [PySnippet_MEDCouplingUMesh_areCellsIncludedIn_2] - cells2 = [ 4,2,0 ] - mesh2 = mesh1.buildPartOfMySelf(cells2, True ) # even cells selected - #! [PySnippet_MEDCouplingUMesh_areCellsIncludedIn_2] - #! [PySnippet_MEDCouplingUMesh_areCellsIncludedIn_3] - compType = 0 # the strongest policy - isOk, corr2to1 = mesh1.areCellsIncludedIn( mesh2, compType ) - assert isOk # a larger mesh1 includes a smaller mesh2 - assert corr2to1.getValues() == cells2 - #! [PySnippet_MEDCouplingUMesh_areCellsIncludedIn_3] - #! [PySnippet_MEDCouplingUMesh_areCellsIncludedIn_4] - isOk, corr1to2 = mesh2.areCellsIncludedIn( mesh1, compType ) - assert not isOk # the smaller mesh2 does NOT include the larger mesh1 - assert corr1to2.getValues() == [2, 3, 1, 4, 0] - #! [PySnippet_MEDCouplingUMesh_areCellsIncludedIn_4] - - def testExample_MEDCouplingUMesh_findAndCorrectBadOriented3DExtrudedCells(self): - #! [PySnippet_MEDCouplingUMesh_findAndCorrectBadOriented3DExtrudedCells_1] - # 2D coordinates of 5 base nodes - coords=[-0.3,-0.3, 0.2,-0.3, 0.7,-0.3, -0.3,0.2, 0.2,0.2] - coordsArr=DataArrayDouble(coords,5,2) - # coordinates of 5 top nodes - coordsArr2 = coordsArr.deepCpy() - # 3D coordinates of base + top nodes - coordsArr = coordsArr.changeNbOfComponents( 3, 0 ) - coordsArr2 = coordsArr2.changeNbOfComponents( 3, 1 ) - coordsArr = DataArrayDouble.Aggregate([coordsArr,coordsArr2]) - # mesh - mesh=MEDCouplingUMesh() - mesh.setCoords(coordsArr) - mesh.setMeshDimension(3) - mesh.allocateCells(2) - # connectivity of reversed HEXA8 and PENTA6 - conn=[0,1,4,3, 5,6,9,8, 1,2,4, 6,7,9] - mesh.insertNextCell(NORM_HEXA8, 8,conn[0:0+8]) - mesh.insertNextCell(NORM_PENTA6,6,conn[8:8+6]) - mesh.finishInsertingCells() - #! [PySnippet_MEDCouplingUMesh_findAndCorrectBadOriented3DExtrudedCells_1] - #! [PySnippet_MEDCouplingUMesh_findAndCorrectBadOriented3DExtrudedCells_2] - fixedCells = mesh.findAndCorrectBadOriented3DExtrudedCells() - assert len( fixedCells ) == 2 # 2 cells fixed - fixedCells = mesh.findAndCorrectBadOriented3DExtrudedCells() - assert len( fixedCells ) == 0 # no bad cells - #! [PySnippet_MEDCouplingUMesh_findAndCorrectBadOriented3DExtrudedCells_2] - return - - def testExample_MEDCouplingUMesh_arePolyhedronsNotCorrectlyOriented(self): - #! [PySnippet_MEDCouplingUMesh_arePolyhedronsNotCorrectlyOriented_1] - # 2D coordinates of 5 base nodes - coords=[-0.3,-0.3, 0.2,-0.3, 0.7,-0.3, -0.3,0.2, 0.2,0.2] - coordsArr=DataArrayDouble(coords,5,2) - # coordinates of 5 top nodes - coordsArr2 = coordsArr.deepCpy() - # 3D coordinates of base + top nodes - coordsArr = coordsArr.changeNbOfComponents( 3, 0 ) - coordsArr2 = coordsArr2.changeNbOfComponents( 3, 1 ) - coordsArr = DataArrayDouble.Aggregate([coordsArr,coordsArr2]) - # mesh - mesh=MEDCouplingUMesh() - mesh.setCoords(coordsArr) - mesh.setMeshDimension(3) - mesh.allocateCells(2) - # connectivity of a HEXA8 + a reversed PENTA6 - conn=[0,3,4,1, 5,8,9,6, 1,2,4, 6,7,9] - mesh.insertNextCell(NORM_POLYHED, 8,conn[0:0+8]) # "extruded" polyhedron - mesh.insertNextCell(NORM_POLYHED,6,conn[8:8+6]) - mesh.finishInsertingCells() - # fix connectivity of NORM_POLYHED's - mesh.convertExtrudedPolyhedra() - #! [PySnippet_MEDCouplingUMesh_arePolyhedronsNotCorrectlyOriented_1] - #! [PySnippet_MEDCouplingUMesh_arePolyhedronsNotCorrectlyOriented_2] - badCells = mesh.arePolyhedronsNotCorrectlyOriented() - assert len( badCells ) == 1 # one polyhedron is KO - # fix invalid rolyherdons - mesh.orientCorrectlyPolyhedrons() - # re-check the orientation - badCells = mesh.arePolyhedronsNotCorrectlyOriented() - assert len( badCells ) == 0 # connectivity is OK - #! [PySnippet_MEDCouplingUMesh_arePolyhedronsNotCorrectlyOriented_2] - return - - def testExample_MEDCouplingUMesh_are2DCellsNotCorrectlyOriented(self): - #! [PySnippet_MEDCouplingUMesh_are2DCellsNotCorrectlyOriented_1] - mesh=MEDCouplingUMesh() - mesh.setMeshDimension(2) - mesh.allocateCells(5) - conn=[0,3,4,1, 1,2,4, 4,5,2, 6,7,4,3, 7,8,5,4] - mesh.insertNextCell(NORM_QUAD4,4,conn[0:4]) # 0 - mesh.insertNextCell(NORM_TRI3,3, conn[4:7]) # 1 - mesh.insertNextCell(NORM_TRI3,3, conn[7:10]) # 2 - mesh.insertNextCell(NORM_QUAD4,4,conn[10:14]) # 3 - mesh.insertNextCell(NORM_QUAD4,4,conn[14:18]) # 4 - mesh.finishInsertingCells() - coords=[-0.3,-0.3, 0.2,-0.3, 0.7,-0.3, -0.3,0.2, 0.2,0.2, 0.7,0.2, -0.3,0.7, 0.2,0.7, 0.7,0.7 ] - coordsArr=DataArrayDouble(coords,9,2) - mesh.setCoords(coordsArr) - mesh.changeSpaceDimension(3) - #! [PySnippet_MEDCouplingUMesh_are2DCellsNotCorrectlyOriented_1] - #! [PySnippet_MEDCouplingUMesh_are2DCellsNotCorrectlyOriented_2] - vec = [0.,0.,-1.] - badCellIds=mesh.are2DCellsNotCorrectlyOriented( vec, False ) - assert len( badCellIds ) == 1 # one cell is reversed - # fix orientation - mesh.orientCorrectly2DCells( vec, False ) - # re-check orientation - badCellIds=mesh.are2DCellsNotCorrectlyOriented( vec, False ) - assert len( badCellIds ) == 0 # the orientation is OK - #! [PySnippet_MEDCouplingUMesh_are2DCellsNotCorrectlyOriented_2] - return - - def testExample_MEDCouplingUMesh_getCellsContainingPoints(self): - #! [PySnippet_MEDCouplingUMesh_getCellsContainingPoints_1] - mesh=MEDCouplingUMesh() - mesh.setMeshDimension(2) - mesh.allocateCells(5) - conn=[0,3,4,1, 1,2,4, 4,5,2, 6,7,4,3, 7,8,5,4] - mesh.insertNextCell(NORM_QUAD4,4,conn[0:4]) # 0 - mesh.insertNextCell(NORM_TRI3,3, conn[4:7]) # 1 - mesh.insertNextCell(NORM_TRI3,3, conn[7:10]) # 2 - mesh.insertNextCell(NORM_QUAD4,4,conn[10:14]) # 3 - mesh.insertNextCell(NORM_QUAD4,4,conn[14:18]) # 4 - mesh.finishInsertingCells() - coords=[-0.3,-0.3, 0.2,-0.3, 0.7,-0.3, -0.3,0.2, 0.2,0.2, 0.7,0.2, -0.3,0.7, 0.2,0.7, 0.7,0.7 ] - coordsArr=DataArrayDouble(coords,9,2) - mesh.setCoords(coordsArr) - #! [PySnippet_MEDCouplingUMesh_getCellsContainingPoints_1] - #! [PySnippet_MEDCouplingUMesh_getCellsContainingPoints_2] - pos = [ 10., 10, # point out of the mesh - 0.3, 0.3, # point located somewhere inside the mesh - coords[2], coords[3]] # point at the node #1 - eps = 1e-4 # ball radius - cells,cellsIndex=mesh.getCellsContainingPoints( pos, 3, eps ) - assert cells.getValues() == [4, 0, 1] - assert cellsIndex.getValues() == [0, 0, 1, 3] - #! [PySnippet_MEDCouplingUMesh_getCellsContainingPoints_2] - return - - - def testExample_MEDCouplingUMesh_getCellsContainingPoint(self): - #! [PySnippet_MEDCouplingUMesh_getCellsContainingPoint_1] - mesh=MEDCouplingUMesh() - mesh.setMeshDimension(2) - mesh.allocateCells(5) - conn=[0,3,4,1, 1,2,4, 4,5,2, 6,7,4,3, 7,8,5,4] - mesh.insertNextCell(NORM_QUAD4,4,conn[0:4]) - mesh.insertNextCell(NORM_TRI3,3, conn[4:7]) - mesh.insertNextCell(NORM_TRI3,3, conn[7:10]) - mesh.insertNextCell(NORM_QUAD4,4,conn[10:14]) - mesh.insertNextCell(NORM_QUAD4,4,conn[14:18]) - mesh.finishInsertingCells() - coords=[-0.3,-0.3, 0.2,-0.3, 0.7,-0.3, -0.3,0.2, 0.2,0.2, 0.7,0.2, -0.3,0.7, 0.2,0.7, 0.7,0.7 ] - coordsArr=DataArrayDouble(coords,9,2) - mesh.setCoords(coordsArr) - #! [PySnippet_MEDCouplingUMesh_getCellsContainingPoint_1] - #! [PySnippet_MEDCouplingUMesh_getCellsContainingPoint_2] - pos4 = coords[ 4*2 : ] # coordinates of the node #4 - eps = 1e-4 # ball radius - pos = [ pos4[0]+eps, pos4[1]-eps ] # ball center - cellIds=mesh.getCellsContainingPoint( pos, eps ) - assert len( cellIds ) == mesh.getNumberOfCells() - #! [PySnippet_MEDCouplingUMesh_getCellsContainingPoint_2] - return - - - def testExample_MEDCouplingUMesh_buildPartOrthogonalField(self): - #! [PySnippet_MEDCouplingUMesh_buildPartOrthogonalField_1] - mesh=MEDCouplingUMesh() - mesh.setMeshDimension(2) - mesh.allocateCells(5) - conn=[0,3,4,1, 1,2,4, 4,5,2, 6,7,4,3, 7,8,5,4] - mesh.insertNextCell(NORM_QUAD4,4,conn[0:4]) # 0 - mesh.insertNextCell(NORM_TRI3,3, conn[4:7]) # 1 - mesh.insertNextCell(NORM_TRI3,3, conn[7:10]) # 2 - mesh.insertNextCell(NORM_QUAD4,4,conn[10:14]) # 3 - mesh.insertNextCell(NORM_QUAD4,4,conn[14:18]) # 4 - mesh.finishInsertingCells() - coords=[-0.3,-0.3, 0.2,-0.3, 0.7,-0.3, -0.3,0.2, 0.2,0.2, 0.7,0.2, -0.3,0.7, 0.2,0.7, 0.7,0.7 ] - coordsArr=DataArrayDouble(coords,9,2) - mesh.setCoords(coordsArr) - #! [PySnippet_MEDCouplingUMesh_buildPartOrthogonalField_1] - #! [PySnippet_MEDCouplingUMesh_buildPartOrthogonalField_2] - part = DataArrayInt([1,2,3,4],4,1) # cell #0 is omitted - vecField=mesh.buildPartOrthogonalField( part ) - vecArr = vecField.getArray() - assert len( vecArr ) == len( part ) - assert vecArr.getNumberOfComponents() == 3 - #! [PySnippet_MEDCouplingUMesh_buildPartOrthogonalField_2] - return - - def testExample_MEDCouplingUMesh_getPartMeasureField(self): - #! [PySnippet_MEDCouplingUMesh_getPartMeasureField_1] - mesh=MEDCouplingUMesh() - mesh.setMeshDimension(2) - mesh.allocateCells(5) - conn=[0,3,4,1, 1,2,4, 4,5,2, 6,7,4,3, 7,8,5,4] - mesh.insertNextCell(NORM_QUAD4,4,conn[0:4]) # 0 - mesh.insertNextCell(NORM_TRI3,3, conn[4:7]) # 1 - mesh.insertNextCell(NORM_TRI3,3, conn[7:10]) # 2 - mesh.insertNextCell(NORM_QUAD4,4,conn[10:14]) # 3 - mesh.insertNextCell(NORM_QUAD4,4,conn[14:18]) # 4 - mesh.finishInsertingCells() - coords=[-0.3,-0.3, 0.2,-0.3, 0.7,-0.3, -0.3,0.2, 0.2,0.2, 0.7,0.2, -0.3,0.7, 0.2,0.7, 0.7,0.7 ] - coordsArr=DataArrayDouble(coords,9,2) - mesh.setCoords(coordsArr) - #! [PySnippet_MEDCouplingUMesh_getPartMeasureField_1] - #! [PySnippet_MEDCouplingUMesh_getPartMeasureField_2] - isAbs = True - part = DataArrayInt([1,2,3,4],4,1) # cell #0 is omitted - areaArr=mesh.getPartMeasureField( isAbs, part ) - assert areaArr[0] > 0 # orientation ignored - areaArr=mesh.getPartMeasureField( not isAbs, part ) - assert areaArr[0] < 0 # orientation considered - assert len( areaArr ) == len( part ) - #! [PySnippet_MEDCouplingUMesh_getPartMeasureField_2] - #! [PySnippet_MEDCouplingUMesh_getPartMeasureField_3] - part = DataArrayInt([1,2,3,4],4,1) # cell #0 is omitted - baryCenters = mesh.getPartBarycenterAndOwner( part ) - assert len( baryCenters ) == len( part ) - assert baryCenters.getNumberOfComponents() == mesh.getSpaceDimension() - #! [PySnippet_MEDCouplingUMesh_getPartMeasureField_3] - return - - def testExample_MEDCouplingUMesh_getCellsInBoundingBox(self): - #! [PySnippet_MEDCouplingUMesh_getCellsInBoundingBox_1] - mesh=MEDCouplingUMesh() - mesh.setMeshDimension(2) - coords=[0.,0., 0.,1., 1.,1] - coordsArr=DataArrayDouble(coords,3,2) - mesh.setCoords(coordsArr) - mesh.allocateCells(1) - conn=[0,1,2] - mesh.insertNextCell(NORM_TRI3,3,conn) - mesh.finishInsertingCells() - #! [PySnippet_MEDCouplingUMesh_getCellsInBoundingBox_1] - #! [PySnippet_MEDCouplingUMesh_getCellsInBoundingBox_2] - bbox = [1., 1., 1.001,1.001] # xMin, xMax, yMin, yMax - cellsInBox = mesh.getCellsInBoundingBox( bbox, 0.0 ) - assert cellsInBox.getValues() == [] - cellsInBox = mesh.getCellsInBoundingBox( bbox, 0.1 ) - assert cellsInBox.getValues() == [0] - #! [PySnippet_MEDCouplingUMesh_getCellsInBoundingBox_2] - - - def testExample_MEDCouplingUMesh_renumberNodesInConn(self): - #! [PySnippet_MEDCouplingUMesh_renumberNodesInConn_1] - mesh=MEDCouplingUMesh() - mesh.setMeshDimension(2) - mesh.allocateCells(1) - conn=[4,3,2,1] - mesh.insertNextCell(NORM_QUAD4,4,conn[0:4]) - mesh.finishInsertingCells() - #! [PySnippet_MEDCouplingUMesh_renumberNodesInConn_1] - #! [PySnippet_MEDCouplingUMesh_renumberNodesInConn_2] - old2newIds = [-1,3,2,1,0] - mesh.renumberNodesInConn( old2newIds ) - nodes0 = mesh.getNodeIdsOfCell( 0 ) - assert nodes0 == [0,1,2,3] - #! [PySnippet_MEDCouplingUMesh_renumberNodesInConn_2] - return - - - def testExample_MEDCouplingUMesh_renumberNodes(self): - #! [PySnippet_MEDCouplingUMesh_renumberNodes_1] - mesh=MEDCouplingUMesh() - mesh.setMeshDimension(2) - coords=[-0.3,-0.3, 0.2,-0.3, 0.7,-0.3, -0.3,0.3] - coordsArr=DataArrayDouble(coords,4,2) - mesh.setCoords(coordsArr) - mesh.allocateCells(0) - mesh.finishInsertingCells() - #! [PySnippet_MEDCouplingUMesh_renumberNodes_1] - #! [PySnippet_MEDCouplingUMesh_renumberNodes_2] - mesh.renumberNodes([ 2,1,0,-1 ], 3) - coordsArr = mesh.getCoords() # get a shorten array - assert coordsArr.getValues() == [0.7,-0.3, 0.2,-0.3, -0.3,-0.3] - #! [PySnippet_MEDCouplingUMesh_renumberNodes_2] - #! [PySnippet_MEDCouplingUMesh_renumberNodes_3] - coordsArr.setValues(coords,4,2) # restore old nodes - mesh.renumberNodes2([ 2,1,0,2 ], 3) - coordsArr = mesh.getCoords() # get a shorten array - assert coordsArr.getValues() == [0.7,-0.3, 0.2,-0.3, -0.3,0.0] - #! [PySnippet_MEDCouplingUMesh_renumberNodes_3] - return - - def testExample_MEDCouplingUMesh_findBoundaryNodes(self): - #! [PySnippet_MEDCouplingUMesh_findBoundaryNodes_1] - mesh=MEDCouplingUMesh() - mesh.setMeshDimension(2) - mesh.allocateCells(5) - conn=[0,3,4,1, 1,4,2, 4,5,2, 6,7,4,3, 7,8,5,4] - mesh.insertNextCell(NORM_QUAD4,4,conn[0:4]) - mesh.insertNextCell(NORM_TRI3,3, conn[4:7]) - mesh.insertNextCell(NORM_TRI3,3, conn[7:10]) - mesh.insertNextCell(NORM_QUAD4,4,conn[10:14]) - mesh.insertNextCell(NORM_QUAD4,4,conn[14:18]) - mesh.finishInsertingCells() - coords=[-0.3,-0.3, 0.2,-0.3, 0.7,-0.3, -0.3,0.2, 0.2,0.2, 0.7,0.2, -0.3,0.7, 0.2,0.7, 0.7,0.7 ] - coordsArr=DataArrayDouble(coords,9,2) - mesh.setCoords(coordsArr) - #! [PySnippet_MEDCouplingUMesh_findBoundaryNodes_1] - #! [PySnippet_MEDCouplingUMesh_findBoundaryNodes_2] - nodeIdsArr=mesh.findBoundaryNodes() - assert nodeIdsArr.getNumberOfTuples() == mesh.getNumberOfNodes() - 1 - #! [PySnippet_MEDCouplingUMesh_findBoundaryNodes_2] - return - - def testExample_MEDCouplingUMesh_buildBoundaryMesh(self): - #! [PySnippet_MEDCouplingUMesh_buildBoundaryMesh_1] - mesh=MEDCouplingUMesh() - mesh.setMeshDimension(2) - mesh.allocateCells(5) - conn=[0,3,4,1, 1,4,2, 4,5,2, 6,7,4,3, 7,8,5,4] - mesh.insertNextCell(NORM_QUAD4,4,conn[0:4]) - mesh.insertNextCell(NORM_TRI3,3, conn[4:7]) - mesh.insertNextCell(NORM_TRI3,3, conn[7:10]) - mesh.insertNextCell(NORM_QUAD4,4,conn[10:14]) - mesh.insertNextCell(NORM_QUAD4,4,conn[14:18]) - mesh.finishInsertingCells() - coords=[-0.3,-0.3, 0.2,-0.3, 0.7,-0.3, -0.3,0.2, 0.2,0.2, 0.7,0.2, -0.3,0.7, 0.2,0.7, 0.7,0.7 ] - coordsArr=DataArrayDouble(coords,9,2) - mesh.setCoords(coordsArr) - #! [PySnippet_MEDCouplingUMesh_buildBoundaryMesh_1] - #! [PySnippet_MEDCouplingUMesh_buildBoundaryMesh_2] - mesh1=mesh.buildBoundaryMesh(True) - mesh2=mesh.buildBoundaryMesh(False) - assert coordsArr.isEqual( mesh1.getCoords(), 1e-13 ) # same nodes - assert not coordsArr.isEqual( mesh2.getCoords(), 1e-13 ) # different nodes - #! [PySnippet_MEDCouplingUMesh_buildBoundaryMesh_2] - return - - def testExample_MEDCouplingUMesh_buildFacePartOfMySelfNode(self): - #! [PySnippet_MEDCouplingUMesh_buildFacePartOfMySelfNode_1] - mesh=MEDCouplingUMesh() - mesh.setMeshDimension(2) - mesh.allocateCells(5) - conn=[0,3,4,1, 1,4,2, 4,5,2, 6,7,4,3, 7,8,5,4] - mesh.insertNextCell(NORM_QUAD4,4,conn[0:4]) # 0 - mesh.insertNextCell(NORM_TRI3,3, conn[4:7]) # 1 - mesh.insertNextCell(NORM_TRI3,3, conn[7:10]) # 2 - mesh.insertNextCell(NORM_QUAD4,4,conn[10:14]) # 3 - mesh.insertNextCell(NORM_QUAD4,4,conn[14:18]) # 4 - mesh.finishInsertingCells() - coords=[-0.3,-0.3, 0.2,-0.3, 0.7,-0.3, -0.3,0.2, 0.2,0.2, 0.7,0.2, -0.3,0.7, 0.2,0.7, 0.7,0.7 ] - coordsArr=DataArrayDouble(coords,9,2) - mesh.setCoords(coordsArr) - #! [PySnippet_MEDCouplingUMesh_buildFacePartOfMySelfNode_1] - #! [PySnippet_MEDCouplingUMesh_buildFacePartOfMySelfNode_2] - nodeIds = mesh.getNodeIdsOfCell( 0 ) - allNodes = True - mesh1 = mesh.buildFacePartOfMySelfNode( nodeIds, allNodes ) - assert mesh1.getNumberOfCells() == 4 # 4 segments bounding QUAD4 #0 only - mesh2 = mesh.buildFacePartOfMySelfNode( nodeIds, not allNodes ) - assert mesh2.getNumberOfCells() > 4 # more segments added - #! [PySnippet_MEDCouplingUMesh_buildFacePartOfMySelfNode_2] - return - - - def testExample_MEDCouplingUMesh_buildPartOfMySelfNode(self): - #! [PySnippet_MEDCouplingUMesh_buildPartOfMySelfNode_1] - mesh=MEDCouplingUMesh() - mesh.setMeshDimension(2) - mesh.allocateCells(5) - conn=[0,3,4,1, 1,4,2, 4,5,2, 6,7,4,3, 7,8,5,4] - mesh.insertNextCell(NORM_QUAD4,4,conn[0:4]) # 0 - mesh.insertNextCell(NORM_TRI3,3, conn[4:7]) # 1 - mesh.insertNextCell(NORM_TRI3,3, conn[7:10]) # 2 - mesh.insertNextCell(NORM_QUAD4,4,conn[10:14]) # 3 - mesh.insertNextCell(NORM_QUAD4,4,conn[14:18]) # 4 - mesh.finishInsertingCells() - coords=[-0.3,-0.3, 0.2,-0.3, 0.7,-0.3, -0.3,0.2, 0.2,0.2, 0.7,0.2, -0.3,0.7, 0.2,0.7, 0.7,0.7 ] - coordsArr=DataArrayDouble(coords,9,2) - mesh.setCoords(coordsArr) - #! [PySnippet_MEDCouplingUMesh_buildPartOfMySelfNode_1] - #! [PySnippet_MEDCouplingUMesh_buildPartOfMySelfNode_2] - nodeIds = mesh.getNodeIdsOfCell( 0 ) - allNodes = True - mesh1 = mesh.buildPartOfMySelfNode( nodeIds, allNodes ) - mesh2 = mesh.buildPartOfMySelfNode( nodeIds, not allNodes ) - assert mesh1.getNumberOfCells() == 1 # cell #0 is found only - assert mesh2.getNumberOfCells() == mesh.getNumberOfCells() # all cells are found - #! [PySnippet_MEDCouplingUMesh_buildPartOfMySelfNode_2] - return - - - def testExample_MEDCouplingUMesh_getCellIdsLyingOnNodes(self): - #! [PySnippet_MEDCouplingUMesh_getCellIdsLyingOnNodes_1] - mesh=MEDCouplingUMesh() - mesh.setMeshDimension(2) - mesh.allocateCells(5) - conn=[0,3,4,1, 1,4,2, 4,5,2, 6,7,4,3, 7,8,5,4] - mesh.insertNextCell(NORM_QUAD4,4,conn[0:4]) # 0 - mesh.insertNextCell(NORM_TRI3,3, conn[4:7]) # 1 - mesh.insertNextCell(NORM_TRI3,3, conn[7:10]) # 2 - mesh.insertNextCell(NORM_QUAD4,4,conn[10:14]) # 3 - mesh.insertNextCell(NORM_QUAD4,4,conn[14:18]) # 4 - mesh.finishInsertingCells() - coords=[-0.3,-0.3, 0.2,-0.3, 0.7,-0.3, -0.3,0.2, 0.2,0.2, 0.7,0.2, -0.3,0.7, 0.2,0.7, 0.7,0.7 ] - coordsArr=DataArrayDouble(coords,9,2) - mesh.setCoords(coordsArr) - #! [PySnippet_MEDCouplingUMesh_getCellIdsLyingOnNodes_1] - #! [PySnippet_MEDCouplingUMesh_getCellIdsLyingOnNodes_2] - nodeIds = mesh.getNodeIdsOfCell( 0 ) - allNodes = True - cellIdsArr1 = mesh.getCellIdsLyingOnNodes( nodeIds, allNodes ) - cellIdsArr2 = mesh.getCellIdsLyingOnNodes( nodeIds, not allNodes ) - assert cellIdsArr1.getNumberOfTuples() == 1 # cell #0 is found only - assert cellIdsArr2.getNumberOfTuples() == mesh.getNumberOfCells() # all cells are found - #! [PySnippet_MEDCouplingUMesh_getCellIdsLyingOnNodes_2] - return - - - def testExample_MEDCouplingUMesh_getCellIdsFullyIncludedInNodeIds(self): - #! [PySnippet_MEDCouplingUMesh_getCellIdsFullyIncludedInNodeIds_1] - mesh=MEDCouplingUMesh() - mesh.setMeshDimension(2) - mesh.allocateCells(5) - conn=[0,3,4,1, 1,4,2, 4,5,2, 6,7,4,3, 7,8,5,4] - mesh.insertNextCell(NORM_QUAD4,4,conn[0:4]) - mesh.insertNextCell(NORM_TRI3,3, conn[4:7]) - mesh.insertNextCell(NORM_TRI3,3, conn[7:10]) - mesh.insertNextCell(NORM_QUAD4,4,conn[10:14]) - mesh.insertNextCell(NORM_QUAD4,4,conn[14:18]) - mesh.finishInsertingCells() - coords=[-0.3,-0.3, 0.2,-0.3, 0.7,-0.3, -0.3,0.2, 0.2,0.2, 0.7,0.2, -0.3,0.7, 0.2,0.7, 0.7,0.7 ] - coordsArr=DataArrayDouble(coords,9,2) - mesh.setCoords(coordsArr) - #! [PySnippet_MEDCouplingUMesh_getCellIdsFullyIncludedInNodeIds_1] - #! [PySnippet_MEDCouplingUMesh_getCellIdsFullyIncludedInNodeIds_2] - cellIds = [1,2] - nodeIds = mesh.getNodeIdsOfCell( cellIds[0] ) - nodeIds += mesh.getNodeIdsOfCell( cellIds[1] ) - cellIdsArr = mesh.getCellIdsFullyIncludedInNodeIds( nodeIds ) - assert cellIdsArr.getValues() == cellIds - #! [PySnippet_MEDCouplingUMesh_getCellIdsFullyIncludedInNodeIds_2] - return - - - def testExample_MEDCouplingUMesh_buildPartOfMySelf(self): - #! [PySnippet_MEDCouplingUMesh_buildPartOfMySelf_1] - mesh=MEDCouplingUMesh() - mesh.setMeshDimension(2) - mesh.allocateCells(5) - conn=[0,3,4,1, 1,4,2, 4,5,2, 6,7,4,3, 7,8,5,4] - mesh.insertNextCell(NORM_QUAD4,4,conn[0:4]) # 0 - mesh.insertNextCell(NORM_TRI3,3, conn[4:7]) # 1 - mesh.insertNextCell(NORM_TRI3,3, conn[7:10]) # 2 - mesh.insertNextCell(NORM_QUAD4,4,conn[10:14]) # 3 - mesh.insertNextCell(NORM_QUAD4,4,conn[14:18]) # 4 - mesh.finishInsertingCells() - coords=[-0.3,-0.3, 0.2,-0.3, 0.7,-0.3, -0.3,0.2, 0.2,0.2, 0.7,0.2, -0.3,0.7, 0.2,0.7, 0.7,0.7 ] - coordsArr=DataArrayDouble(coords,9,2) - mesh.setCoords(coordsArr) - #! [PySnippet_MEDCouplingUMesh_buildPartOfMySelf_1] - #! [PySnippet_MEDCouplingUMesh_buildPartOfMySelf_2] - cellIds=[1,2] - mesh2=mesh.buildPartOfMySelf(cellIds, True) - mesh3=mesh.buildPartOfMySelf(cellIds, False) - coordsArr2 = mesh2.getCoords() - assert coordsArr.isEqual( coordsArr2, 1e-13 ) # same nodes - coordsArr3 = mesh3.getCoords() - assert not coordsArr.isEqual( coordsArr3, 1e-13 ) # different nodes - assert mesh2.getNodeIdsOfCell(0) == mesh.getNodeIdsOfCell( cellIds[0]) # cell #1 was copied - assert mesh2.getNodeIdsOfCell(1) == mesh.getNodeIdsOfCell( cellIds[1]) # cell #2 was copied - #! [PySnippet_MEDCouplingUMesh_buildPartOfMySelf_2] - return - - def testExample_MEDCouplingUMesh_mergeNodes(self): - #! [PySnippet_MEDCouplingUMesh_mergeNodes_1] - mesh=MEDCouplingUMesh() - mesh.setMeshDimension(2) - mesh.allocateCells(5) - conn=[0,3,4,1, 1,4,2, 4,5,2] - mesh.insertNextCell(NORM_QUAD4,4,conn[0:4]) - mesh.insertNextCell(NORM_TRI3,3, conn[4:7]) - mesh.insertNextCell(NORM_TRI3,3, conn[7:10]) - mesh.finishInsertingCells() - coords=[0.3,-0.301, # 0 - 0.2,-0.3, # 1 - 0.3,-0.302, # 2 ~~ 0 - 1.1,0.0, # 3 - 1.1,0.0, # 4 == 3 - 0.3,-0.303]# 5 ~~ 0 - coordsArr=DataArrayDouble(coords,6,2) - mesh.setCoords(coordsArr) - #! [PySnippet_MEDCouplingUMesh_mergeNodes_1] - #! [PySnippet_MEDCouplingUMesh_mergeNodes_2] - arr,areNodesMerged,newNbOfNodes=mesh.mergeNodes(0.004) - assert arr.getValues() == [0, 1, 0, 2, 2, 0] - assert areNodesMerged - assert newNbOfNodes == 3 - #! [PySnippet_MEDCouplingUMesh_mergeNodes_2] - #! [PySnippet_MEDCouplingUMesh_mergeNodes_3] - baryCoords2 = coords[2*2:] # initial coordinates of node #2 - coordsArr = mesh.getCoords() # retrieve a new shorten coord array - self.assertNotAlmostEqual( baryCoords2[1], coordsArr.getIJ(0,1), 13 ) # Y of node #0 differs from that of baryCoords2 - # restore coordinates - coordsArr = DataArrayDouble(coords,6,2) - mesh.setCoords(coordsArr) - # call mergeNodes2() - mesh.mergeNodes2(0.004) - coordsArr = mesh.getCoords() # retrieve a new shorten coord array - self.assertAlmostEqual( baryCoords2[1], coordsArr.getIJ(0,1), 13 ) # Y of node #0 equals to that of baryCoords2 - #! [PySnippet_MEDCouplingUMesh_mergeNodes_3] - return - - def testExample_MEDCouplingUMesh_zipConnectivityTraducer(self): - #! [PySnippet_MEDCouplingUMesh_zipConnectivityTraducer_1] - mesh=MEDCouplingUMesh() - mesh.setMeshDimension(2) - mesh.allocateCells(5) - conn=[0,3,4,1, 1,4,2] - mesh.insertNextCell(NORM_QUAD4,4,conn[0:4]) # 0 - mesh.insertNextCell(NORM_TRI3,3, conn[4:7]) # 1 - mesh.insertNextCell(NORM_TRI3,3, conn[4:7]) # 2 == 1 - mesh.insertNextCell(NORM_QUAD4,4,conn[0:4]) # 3 == 0 - mesh.insertNextCell(NORM_QUAD4,4,conn[2:4]+conn[0:2]) # 4 ~~ 0 - mesh.finishInsertingCells() - coords=[-0.3,-0.3, 0.2,-0.3, 0.7,-0.3, -0.3,0.2, 0.2,0.2, 0.7,0.2, -0.3,0.7, 0.2,0.7, 0.7,0.7 ] - coordsArr=DataArrayDouble(coords,9,2) - mesh.setCoords(coordsArr) - #! [PySnippet_MEDCouplingUMesh_zipConnectivityTraducer_1] - #! [PySnippet_MEDCouplingUMesh_zipConnectivityTraducer_2] - oldNbCells = mesh.getNumberOfCells() - arr = mesh.zipConnectivityTraducer(0) - assert mesh.getNumberOfCells() == oldNbCells-2 - assert arr.getValues() == [0, 1, 1, 0, 2] - #! [PySnippet_MEDCouplingUMesh_zipConnectivityTraducer_2] - return - - def testExample_MEDCouplingUMesh_zipCoordsTraducer(self): - #! [PySnippet_MEDCouplingUMesh_zipCoordsTraducer_1] - mesh=MEDCouplingUMesh() - mesh.setMeshDimension(2) - mesh.allocateCells(5) - conn=[0,3,4,1, 1,4,2, 4,5,2, 6,7,4,3, 7,8,5,4] - mesh.insertNextCell(NORM_QUAD4,4,conn[0:4]) - mesh.insertNextCell(NORM_TRI3,3, conn[4:7]) - mesh.insertNextCell(NORM_TRI3,3, conn[7:10]) - mesh.insertNextCell(NORM_QUAD4,4,conn[10:14]) - mesh.insertNextCell(NORM_QUAD4,4,conn[14:18]) - mesh.finishInsertingCells() - coords=[-0.3,-0.3, 0.2,-0.3, 0.7,-0.3, -0.3,0.2, 0.2,0.2, 0.7,0.2, -0.3,0.7, 0.2,0.7, 0.7,0.7 ] - coordsArr=DataArrayDouble(coords,9,2) - mesh.setCoords(coordsArr) - #! [PySnippet_MEDCouplingUMesh_zipCoordsTraducer_1] - #! [PySnippet_MEDCouplingUMesh_zipCoordsTraducer_2] - cellIds=[1,2] - mesh2=mesh.buildPartOfMySelf(cellIds,True) - arr=mesh2.zipCoordsTraducer() - assert mesh2.getNumberOfNodes() == 4 # nb of nodes decreased - assert arr.getValues() == [-1,0,1,-1,2,3,-1,-1,-1] # -1 for unused nodes - #! [PySnippet_MEDCouplingUMesh_zipCoordsTraducer_2] - return - - def testExample_MEDCouplingUMesh_getNodeIdsInUse(self): - #! [PySnippet_MEDCouplingUMesh_getNodeIdsInUse_1] - mesh=MEDCouplingUMesh() - mesh.setMeshDimension(2) - mesh.allocateCells(5) - conn=[0,3,4,1, 1,4,2, 4,5,2, 6,7,4,3, 7,8,5,4] - mesh.insertNextCell(NORM_QUAD4,4,conn[0:4]) - mesh.insertNextCell(NORM_TRI3,3, conn[4:7]) - mesh.insertNextCell(NORM_TRI3,3, conn[7:10]) - mesh.insertNextCell(NORM_QUAD4,4,conn[10:14]) - mesh.insertNextCell(NORM_QUAD4,4,conn[14:18]) - mesh.finishInsertingCells() - coords=[-0.3,-0.3, 0.2,-0.3, 0.7,-0.3, -0.3,0.2, 0.2,0.2, 0.7,0.2, -0.3,0.7, 0.2,0.7, 0.7,0.7 ] - coordsArr=DataArrayDouble(coords,9,2) - mesh.setCoords(coordsArr) - #! [PySnippet_MEDCouplingUMesh_getNodeIdsInUse_1] - #! [PySnippet_MEDCouplingUMesh_getNodeIdsInUse_2] - cellIds=[1,2] - mesh2=mesh.buildPartOfMySelf(cellIds,True) - arr,newNbOfNodes=mesh2.getNodeIdsInUse() - assert arr.getValues() == [-1,0,1,-1,2,3,-1,-1,-1] - #! [PySnippet_MEDCouplingUMesh_getNodeIdsInUse_2] - #! [PySnippet_MEDCouplingUMesh_getNodeIdsInUse_3] - arr2=arr.invertArrayO2N2N2O(newNbOfNodes) - assert arr2.getValues() == [1,2,4,5] - #! [PySnippet_MEDCouplingUMesh_getNodeIdsInUse_3] - return - - def testExample_MEDCouplingUMesh_convertToPolyTypes(self): - #! [PySnippet_MEDCouplingUMesh_convertToPolyTypes_1] - mesh=MEDCouplingUMesh() - mesh.setMeshDimension(2) - mesh.allocateCells(5) - conn=[0,3,4,1, 1,4,2, 4,5,2, 6,7,4,3, 7,8,5,4] - mesh.insertNextCell(NORM_QUAD4,4,conn[0:4]) # 0 - mesh.insertNextCell(NORM_TRI3,3, conn[4:7]) # 1 - mesh.insertNextCell(NORM_TRI3,3, conn[7:10]) # 2 - mesh.insertNextCell(NORM_QUAD4,4,conn[10:14]) # 3 - mesh.insertNextCell(NORM_QUAD4,4,conn[14:18]) # 4 - mesh.finishInsertingCells() - coords=[-0.3,-0.3, 0.2,-0.3, 0.7,-0.3, -0.3,0.2, 0.2,0.2, 0.7,0.2, -0.3,0.7, 0.2,0.7, 0.7,0.7 ] - coordsArr=DataArrayDouble(coords,9,2) - mesh.setCoords(coordsArr) - #! [PySnippet_MEDCouplingUMesh_convertToPolyTypes_1] - #! [PySnippet_MEDCouplingUMesh_convertToPolyTypes_2] - cells=[1,3] - mesh.convertToPolyTypes(cells) - assert mesh.getTypeOfCell(0) == NORM_QUAD4 - assert mesh.getTypeOfCell(1) == NORM_POLYGON, mesh.getTypeOfCell(1) - assert mesh.getTypeOfCell(2) == NORM_TRI3 - assert mesh.getTypeOfCell(3) == NORM_POLYGON - #! [PySnippet_MEDCouplingUMesh_convertToPolyTypes_2] - return - - def testExample_MEDCouplingUMesh_buildDescendingConnectivity2(self): - #! [PySnippet_MEDCouplingUMesh_buildDescendingConnectivity2_1] - mesh=MEDCouplingUMesh() - mesh.setMeshDimension(2) - mesh.allocateCells(5) - conn=[0,3,4,1, 1,4,2, 4,5,2, 6,7,4,3, 7,8,5,4] - mesh.insertNextCell(NORM_QUAD4,4,conn[0:4]) # 0 - mesh.insertNextCell(NORM_TRI3,3, conn[4:7]) # 1 - mesh.insertNextCell(NORM_TRI3,3, conn[7:10]) # 2 - mesh.insertNextCell(NORM_QUAD4,4,conn[10:14]) # 3 - mesh.insertNextCell(NORM_QUAD4,4,conn[14:18]) # 4 - mesh.finishInsertingCells() - coords=[-0.3,-0.3, 0.2,-0.3, 0.7,-0.3, -0.3,0.2, 0.2,0.2, 0.7,0.2, -0.3,0.7, 0.2,0.7, 0.7,0.7 ] - coordsArr=DataArrayDouble(coords,9,2) - mesh.setCoords(coordsArr) - #! [PySnippet_MEDCouplingUMesh_buildDescendingConnectivity2_1] - #! [PySnippet_MEDCouplingUMesh_buildDescendingConnectivity2_2] - mesh2,desc,descIndx,revDesc,revDescIndx=mesh.buildDescendingConnectivity2() - assert desc.getValues() == [1,2,3,4,-3,5,6, 7,8,-5,9,10,-2,11, 12,13,-7,-10] - assert descIndx.getValues() == [0,4,7,10,14,18] - assert revDesc.getValues() == [0, 0,3, 0,1, 0, 1,2, 1, 2,4, 2, 3, 3,4, 3, 4, 4] - assert revDescIndx.getValues() == [0,1,3,5,6,8,9,11,12,13,15,16,17,18] - #! [PySnippet_MEDCouplingUMesh_buildDescendingConnectivity2_2] - #! [PySnippet_MEDCouplingUMesh_buildDescendingConnectivity2_3] - assert mesh2.getNodeIdsOfCell( 3-1 ) == [4, 1] # cell #3 in FORTRAN mode - #! [PySnippet_MEDCouplingUMesh_buildDescendingConnectivity2_3] - return - - def testExample_MEDCouplingUMesh_buildDescendingConnectivity(self): - #! [PySnippet_MEDCouplingUMesh_buildDescendingConnectivity_1] - mesh=MEDCouplingUMesh() - mesh.setMeshDimension(2) - mesh.allocateCells(5) - conn=[0,3,4,1, 1,4,2, 4,5,2, 6,7,4,3, 7,8,5,4] - mesh.insertNextCell(NORM_QUAD4,4,conn[0:4]) # 0 - mesh.insertNextCell(NORM_TRI3,3, conn[4:7]) # 1 - mesh.insertNextCell(NORM_TRI3,3, conn[7:10]) # 2 - mesh.insertNextCell(NORM_QUAD4,4,conn[10:14]) # 3 - mesh.insertNextCell(NORM_QUAD4,4,conn[14:18]) # 4 - mesh.finishInsertingCells() - coords=[-0.3,-0.3, 0.2,-0.3, 0.7,-0.3, -0.3,0.2, 0.2,0.2, 0.7,0.2, -0.3,0.7, 0.2,0.7, 0.7,0.7 ] - coordsArr=DataArrayDouble(coords,9,2) - mesh.setCoords(coordsArr) - #! [PySnippet_MEDCouplingUMesh_buildDescendingConnectivity_1] - #! [PySnippet_MEDCouplingUMesh_buildDescendingConnectivity_2] - mesh2,desc,descIndx,revDesc,revDescIndx=mesh.buildDescendingConnectivity() - assert desc.getValues() == [0,1,2,3, 2,4,5, 6,7,4, 8,9,1,10, 11,12,6,9] - assert descIndx.getValues() == [0,4,7,10,14,18] - assert revDesc.getValues() == [0, 0,3, 0,1, 0, 1,2, 1, 2,4, 2, 3, 3,4, 3, 4, 4] - assert revDescIndx.getValues() == [0,1,3,5,6,8,9,11,12,13,15,16,17,18] - #! [PySnippet_MEDCouplingUMesh_buildDescendingConnectivity_2] - return - - def testExample_MEDCouplingUMesh_getReverseNodalConnectivity(self): - #! [PySnippet_MEDCouplingUMesh_getReverseNodalConnectivity_1] - mesh=MEDCouplingUMesh() - mesh.setMeshDimension(2) - mesh.allocateCells(5) - conn=[0,3,4,1, 1,4,2, 4,5,2, 6,7,4,3, 7,8,5,4] - mesh.insertNextCell(NORM_QUAD4,4,conn[0:4]) # 0 - mesh.insertNextCell(NORM_TRI3,3, conn[4:7]) # 1 - mesh.insertNextCell(NORM_TRI3,3, conn[7:10]) # 2 - mesh.insertNextCell(NORM_QUAD4,4,conn[10:14]) # 3 - mesh.insertNextCell(NORM_QUAD4,4,conn[14:18]) # 4 - mesh.finishInsertingCells() - coords=[-0.3,-0.3, 0.2,-0.3, 0.7,-0.3, -0.3,0.2, 0.2,0.2, 0.7,0.2, -0.3,0.7, 0.2,0.7, 0.7,0.7 ] - coordsArr=DataArrayDouble(coords,9,2) - mesh.setCoords(coordsArr) - #! [PySnippet_MEDCouplingUMesh_getReverseNodalConnectivity_1] - #! [PySnippet_MEDCouplingUMesh_getReverseNodalConnectivity_2] - revNodal,revNodalIndx=mesh.getReverseNodalConnectivity() - assert revNodal.getValues() == [0,0,1,1,2,0,3,0,1,2,3,4,2,4,3,3,4,4] - assert revNodalIndx.getValues() == [0,1,3,5,7,12,14,15,17,18] - #! [PySnippet_MEDCouplingUMesh_getReverseNodalConnectivity_2] - return - - def testExample_MEDCouplingUMesh_checkDeepEquivalWith(self): - #! [PySnippet_MEDCouplingUMesh_checkDeepEquivalWith_1] - # mesh 1 - mesh1=MEDCouplingUMesh() - mesh1.setMeshDimension(2) - coords=[0.0,0.0, #0 - 1.0,0.0, #1 - 1.0,1.0, #2 - 0.0,1.0] #3 - coordsArr=DataArrayDouble(coords,4,2) - mesh1.setCoords(coordsArr) - mesh1.allocateCells(2) - mesh1.insertNextCell(NORM_TRI3,3,[0,1,2]) #0 - mesh1.insertNextCell(NORM_TRI3,3,[1,2,3]) #1 - mesh1.finishInsertingCells() - # mesh 2 - mesh2=MEDCouplingUMesh() - mesh2.setMeshDimension(2) - coords=[0.0,1.0, #0 = #3 - 0.0,0.0, #1 = #0 - 1.0,0.0, #2 = #1 - 1.0,1.001] #3 ~ #2 - coordsArr2=DataArrayDouble(coords,4,2) - mesh2.setCoords(coordsArr2) - mesh2.allocateCells(2) - mesh2.insertNextCell(NORM_TRI3,3,[2,3,0]) #0 = #1 - mesh2.insertNextCell(NORM_TRI3,3,[3,1,2]) #1 ~ #0 - mesh2.finishInsertingCells() - #! [PySnippet_MEDCouplingUMesh_checkDeepEquivalWith_1] - #! [PySnippet_MEDCouplingUMesh_checkDeepEquivalWith_2] - cellCompPol = 1 # "permuted same orientation" - policy of medium severity - cOld2New, nOld2New = mesh1.checkDeepEquivalWith( mesh2, cellCompPol, 0.002 ) - assert nOld2New.getValues() == [3, 0, 1, 2] - assert cOld2New.getValues() == [1, 0] - #! [PySnippet_MEDCouplingUMesh_checkDeepEquivalWith_2] - #! [PySnippet_MEDCouplingUMesh_checkDeepEquivalWith_3] - self.assertRaises( InterpKernelException, mesh1.checkDeepEquivalOnSameNodesWith, mesh2, cellCompPol, 0.002) - mesh2.setCoords(coordsArr) # make meshes share the same coordinates array - mesh2.allocateCells(2) - mesh2.insertNextCell(NORM_TRI3,3,[1,2,3]) #0 = #1 - mesh2.insertNextCell(NORM_TRI3,3,[1,0,2]) #1 ~ #0 - mesh2.finishInsertingCells() - cellCompPol = 2 # the weakest policy - mesh1.checkDeepEquivalOnSameNodesWith( mesh2, cellCompPol, 0 ) - #! [PySnippet_MEDCouplingUMesh_checkDeepEquivalWith_3] - return - - def testExample_MEDCouplingPointSet_scale(self): - #! [PySnippet_MEDCouplingPointSet_scale_1] - coords=[0.0,0.0, 1.0,0.0, 1.0,1.0, 0.0,1.0] # 2D coordinates of 4 nodes - coordsArr=DataArrayDouble(coords,4,2) - mesh=MEDCouplingUMesh() - mesh.setCoords(coordsArr) - initCoords = coordsArr.deepCpy() - #! [PySnippet_MEDCouplingPointSet_scale_1] - #! [PySnippet_MEDCouplingPointSet_scale_2] - center = [0.,0.] - factor = 2. - mesh.scale(center,factor) - #! [PySnippet_MEDCouplingPointSet_scale_2] - #! [PySnippet_MEDCouplingPointSet_scale_3] - coords2 = mesh.getCoords() - assert coords2.isEqualWithoutConsideringStr( initCoords, 1.0 ) - assert not coords2.isEqualWithoutConsideringStr( initCoords, 0.9 ) - #! [PySnippet_MEDCouplingPointSet_scale_3] - return - - def testExample_MEDCouplingPointSet_translate(self): - #! [PySnippet_MEDCouplingPointSet_translate_1] - coords=[0.0,0.0, 1.0,0.0, 1.0,1.0, 0.0,1.0] # 2D coordinates of 4 nodes - coordsArr=DataArrayDouble(coords,4,2) - mesh=MEDCouplingUMesh() - mesh.setCoords(coordsArr) - initCoords = coordsArr.deepCpy() - #! [PySnippet_MEDCouplingPointSet_translate_1] - #! [PySnippet_MEDCouplingPointSet_translate_2] - vector = [1.,1.] - mesh.translate(vector) - #! [PySnippet_MEDCouplingPointSet_translate_2] - #! [PySnippet_MEDCouplingPointSet_translate_3] - coords2 = mesh.getCoords() - assert coords2.isEqualWithoutConsideringStr( initCoords, 1 ) - assert not coords2.isEqualWithoutConsideringStr( initCoords, 0.9 ) - #! [PySnippet_MEDCouplingPointSet_translate_3] - return - - def testExample_MEDCouplingPointSet_rotate(self): - #! [PySnippet_MEDCouplingPointSet_rotate_1] - coords=[0.0,0.0, 0.1,0.0, 0.1,0.1, 0.0,0.1] # 2D coordinates of 4 nodes - coordsArr=DataArrayDouble(coords,4,2) - mesh=MEDCouplingUMesh() - mesh.setCoords(coordsArr) - #! [PySnippet_MEDCouplingPointSet_rotate_1] - #! [PySnippet_MEDCouplingPointSet_rotate_2] - center = [0.,0.] - mesh.rotate(center,-pi/2) - #! [PySnippet_MEDCouplingPointSet_rotate_2] - #! [PySnippet_MEDCouplingPointSet_rotate_3] - mesh.changeSpaceDimension(3) - center = [0.,0.,0.] - vector = [0.,0.,1.] - mesh.rotate(center,vector,pi/2) - #! [PySnippet_MEDCouplingPointSet_rotate_3] - #! [PySnippet_MEDCouplingPointSet_rotate_4] - mesh.changeSpaceDimension(2) - coords2 = mesh.getCoords() - for i,c in enumerate( coords ): - self.assertAlmostEqual( c, coords2.getIJ(0,i), 13 ) - #! [PySnippet_MEDCouplingPointSet_rotate_4] - return - - def testExample_MEDCouplingPointSet_getBoundingBox(self): - #! [PySnippet_MEDCouplingPointSet_getBoundingBox_1] - cc=[0.0, 0.1, 0.2, # 3D coordinates of 2 nodes - 2.0, 2.1, 2.2] - coordsArr=DataArrayDouble(cc,2,3) - mesh=MEDCouplingUMesh() - mesh.setCoords(coordsArr) - #! [PySnippet_MEDCouplingPointSet_getBoundingBox_1] - #! [PySnippet_MEDCouplingPointSet_getBoundingBox_2] - bbox=mesh.getBoundingBox() - assert bbox == [( cc[0], cc[3] ), # NOTE: list of 3 tuples is retirned! - ( cc[1], cc[4] ), - ( cc[2], cc[5] )] - #! [PySnippet_MEDCouplingPointSet_getBoundingBox_2] - - def testExample_MEDCouplingPointSet_getNodeIdsNearPoint(self): - #! [PySnippet_MEDCouplingPointSet_getNodeIdsNearPoint_1] - # 2D coordinates of 5 nodes - coords=[0.3,-0.301, # 0 - 0.2,-0.3, # 1 - 0.3,-0.302, # 2 - 1.1,0.0, # 3 - 0.3,-0.30299999999999]# 4 - coordsArr=DataArrayDouble(coords,5,2) - mesh=MEDCouplingUMesh() - mesh.setCoords(coordsArr) - #! [PySnippet_MEDCouplingPointSet_getNodeIdsNearPoint_1] - #! [PySnippet_MEDCouplingPointSet_getNodeIdsNearPoint_2] - point=[0.3, -0.3] # point close to nodes #0, #2 and #4 - ids=mesh.getNodeIdsNearPoint(point,0.003) - assert ids.getValues() == [0,2,4] - #! [PySnippet_MEDCouplingPointSet_getNodeIdsNearPoint_2] - return - - def testExample_MEDCouplingPointSet_getNodeIdsNearPoints(self): - #! [PySnippet_MEDCouplingPointSet_getNodeIdsNearPoints_1] - # 2D coordinates of 7 nodes - coords=[0.3,-0.301, # 0 - 0.2,-0.3, # 1 - 0.3,-0.302, # 2 - 1.1,0.0, # 3 - 1.1,0.0, # 4 - 1.1,0.002, # 5 - 0.3,-0.303]# 6 - coordsArr=DataArrayDouble(coords,7,2) - mesh=MEDCouplingUMesh() - mesh.setCoords(coordsArr) - #! [PySnippet_MEDCouplingPointSet_getNodeIdsNearPoints_1] - #! [PySnippet_MEDCouplingPointSet_getNodeIdsNearPoints_2] - points=[0.2,-0.301, # ~ node #1 - 0.0, 0.0, - 1.1, 0.002] # ~ nodes #3, #4 and #5 - ids,idsIndex=mesh.getNodeIdsNearPoints(points,3,0.003) - assert ids.getValues() == [1, 3, 4, 5] - assert idsIndex.getValues() == [0, 1, 1, 4] - #! [PySnippet_MEDCouplingPointSet_getNodeIdsNearPoints_2] - return - - def testExample_MEDCouplingPointSet_findCommonNodes(self): - #! [PySnippet_MEDCouplingPointSet_findCommonNodes_1] - coords=[0.3,-0.301, # 0 - 0.2,-0.3, # 1 - 0.3,-0.302, # 2 - 1.1,0.0, # 3 - 1.1,0.0, # 4 - 0.3,-0.303]# 5 - coordsArr=DataArrayDouble(coords,6,2) - mesh=MEDCouplingUMesh() - mesh.setCoords(coordsArr) - #! [PySnippet_MEDCouplingPointSet_findCommonNodes_1] - #! [PySnippet_MEDCouplingPointSet_findCommonNodes_2] - comm,commI=mesh.findCommonNodes(1e-13) - assert comm.getValues() == [3,4] - comm,commI=mesh.findCommonNodes(0.004) - assert comm.getValues() == [0,2,5,3,4] - #! [PySnippet_MEDCouplingPointSet_findCommonNodes_2] - return - - def testExample_MEDCouplingPointSet_getCoordinatesOfNode(self): - #! [PySnippet_MEDCouplingPointSet_getCoordinatesOfNode_1] - coords=[-0.3,-0.3, 0.2,-0.3, 0.7,-0.3] - coordsArr=DataArrayDouble(coords,3,2) - mesh=MEDCouplingUMesh() - mesh.setCoords(coordsArr) -#! [PySnippet_MEDCouplingPointSet_getCoordinatesOfNode_1] -#! [PySnippet_MEDCouplingPointSet_getCoordinatesOfNode_2] - nodeCoords=mesh.getCoordinatesOfNode(1) - self.assertAlmostEqual(0.2, nodeCoords[0],13) - self.assertAlmostEqual(-0.3,nodeCoords[1],13) -#! [PySnippet_MEDCouplingPointSet_getCoordinatesOfNode_2] - return - - def testExample_DataArrayInt_getTuple(self): -#! [Snippet_DataArrayInt_getTuple_1] - dv=DataArrayInt() - dv.alloc( 6, 1 ) - dv.iota(7) - dv.rearrange( 2 ) - assert dv.getTuple( 1 ) == [9,10] -#! [Snippet_DataArrayInt_getTuple_1] -#! [Snippet_DataArrayInt_getTuple_2] - for tpl in dv: - print tpl -#! [Snippet_DataArrayInt_getTuple_2] - return - - def testExample_DataArrayInt_buildPermutationArr(self): -#! [PySnippet_DataArrayInt_buildPermutationArr_1] - a=DataArrayInt() - a.setValues([4,5,6,7,8],5,1) - b=DataArrayInt() - b.setValues([5,4,8,6,7],5,1) - c=a.buildPermutationArr(b) -#! [PySnippet_DataArrayInt_buildPermutationArr_1] - self.assertEqual([1,0,4,2,3],c.getValues()) - return - - def testExample_DataArrayInt_invertArrayO2N2N2O(self): -#! [PySnippet_DataArrayInt_invertArrayO2N2N2O_1] - arr1=[2,0,4,1,5,3] - da=DataArrayInt() - da.setValues(arr1,6,1) - da2=da.invertArrayO2N2N2O(6) - expected1=[1,3,0,5,2,4] - for i in xrange(6): - self.assertEqual(expected1[i],da2.getIJ(i,0)) - pass -#! [PySnippet_DataArrayInt_invertArrayO2N2N2O_1] - return - - def testExample_DataArrayInt_invertArrayN2O2O2N(self): -#! [PySnippet_DataArrayInt_invertArrayN2O2O2N_1] - arr1=[2,0,4,1,5,3] - da=DataArrayInt() - da.setValues(arr1,6,1) - da2=da.invertArrayN2O2O2N(7) - expected1=[1,3,0,5,2,4,-1] - for i in xrange(6): - self.assertEqual(expected1[i],da2.getIJ(i,0)) - pass -#! [PySnippet_DataArrayInt_invertArrayN2O2O2N_1] - return - - - def testExample_DataArrayDouble_getIdsInRange(self): -#! [PySnippet_DataArrayDouble_getIdsInRange_1] - da=DataArrayDouble() - da.alloc( 10, 1 ) - da[ :, :] = range(10) - da2 = da.getIdsInRange( 2.5, 6 ) -#! [PySnippet_DataArrayDouble_getIdsInRange_1] - return - - def testExample_DataArrayDouble_setPartOfValues2(self): -#! [Snippet_DataArrayDouble_setPartOfValues2_1] - da=DataArrayDouble() - da.alloc( 4, 7 ) - # - dv=DataArrayDouble() - dv.alloc( 6, 1 ) - dv.iota(7) - dv.rearrange( 2 ) -#! [Snippet_DataArrayDouble_setPartOfValues2_1] -#! [Snippet_DataArrayDouble_setPartOfValues2_2] - da.fillWithZero() - da[ [0,1,2], [1,3] ] = dv -#! [Snippet_DataArrayDouble_setPartOfValues2_2] -#! [Snippet_DataArrayDouble_setPartOfValues2_3] - da.fillWithZero() - dv.rearrange( 6 ) - da[ [0,2,3], [0,2,3,4,5,6]] = dv -#! [Snippet_DataArrayDouble_setPartOfValues2_3] - return - - def testExample_DataArrayInt_setPartOfValues2(self): -#! [Snippet_DataArrayInt_setPartOfValues2_1] - da=DataArrayInt() - da.alloc( 4, 7 ) - # - dv=DataArrayInt() - dv.alloc( 6, 1 ) - dv.iota(7) - dv.rearrange( 2 ) -#! [Snippet_DataArrayInt_setPartOfValues2_1] -#! [Snippet_DataArrayInt_setPartOfValues2_2] - da.fillWithZero() - da[ [0,1,2], [1,3] ] = dv -#! [Snippet_DataArrayInt_setPartOfValues2_2] -#! [Snippet_DataArrayInt_setPartOfValues2_3] - da.fillWithZero() - dv.rearrange( 6 ) - da[ [0,2,3], [0,2,3,4,5,6]] = dv -#! [Snippet_DataArrayInt_setPartOfValues2_3] - return - - def testExample_DataArrayDouble_setPartOfValues3(self): -#! [Snippet_DataArrayDouble_setPartOfValues3_1] - da=DataArrayDouble() - da.alloc( 4, 7 ) - # - dv=DataArrayDouble() - dv.alloc( 6, 1 ) - dv.iota(7) - dv.rearrange( 2 ) -#! [Snippet_DataArrayDouble_setPartOfValues3_1] -#! [Snippet_DataArrayDouble_setPartOfValues3_2] - da.fillWithZero() - da[ 0:3, [1,3] ] = dv -#! [Snippet_DataArrayDouble_setPartOfValues3_2] -#! [Snippet_DataArrayDouble_setPartOfValues3_3] - da.fillWithZero() - dv.rearrange( 6 ) - da[ 0:4:2, [0,2,3,4,5,6]] = dv -#! [Snippet_DataArrayDouble_setPartOfValues3_3] - return - - def testExample_DataArrayInt_setPartOfValues3(self): -#! [Snippet_DataArrayInt_setPartOfValues3_1] - da=DataArrayInt() - da.alloc( 4, 7 ) - # - dv=DataArrayInt() - dv.alloc( 6, 1 ) - dv.iota(7) - dv.rearrange( 2 ) -#! [Snippet_DataArrayInt_setPartOfValues3_1] -#! [Snippet_DataArrayInt_setPartOfValues3_2] - da.fillWithZero() - da[ 0:3, [1,3] ] = dv -#! [Snippet_DataArrayInt_setPartOfValues3_2] -#! [Snippet_DataArrayInt_setPartOfValues3_3] - da.fillWithZero() - dv.rearrange( 6 ) - da[ 0:4:2, [0,2,3,4,5,6]] = dv -#! [Snippet_DataArrayInt_setPartOfValues3_3] - return - - def testExample_DataArrayDouble_setPartOfValues1(self): -#! [Snippet_DataArrayDouble_setPartOfValues1_1] - da=DataArrayDouble() - da.alloc( 4, 4 ) - da.setInfoOnComponents( ["v1","v2","v3","v4"]) - # - dv=DataArrayDouble() - dv.alloc( 4, 1 ) - dv.iota(7) - dv.rearrange( 2 ) - dv.setInfoOnComponents( ["a1","a2"]) -#! [Snippet_DataArrayDouble_setPartOfValues1_1] -#! [Snippet_DataArrayDouble_setPartOfValues1_2] - da.fillWithZero() - da.setPartOfValues1( dv, 1,3,1, 1,3,1, True ) -#! [Snippet_DataArrayDouble_setPartOfValues1_2] -#! [Snippet_DataArrayDouble_setPartOfValues1_3] - da.fillWithZero() - da.setPartOfValues1( dv, 0,4,1, 1,2,1, False ) -#! [Snippet_DataArrayDouble_setPartOfValues1_3] -#! [Snippet_DataArrayDouble_setPartOfValues1_4] - da.fillWithZero() - da.setPartOfValues1( dv, 1,2,1, 0,4,1, False ) -#! [Snippet_DataArrayDouble_setPartOfValues1_4] -#! [Snippet_DataArrayDouble_setPartOfValues1_5] - da.fillWithZero() - da.setPartOfValues1( dv, 0,3,2, 1,4,2, True ) -#! [Snippet_DataArrayDouble_setPartOfValues1_5] -#! [Snippet_DataArrayDouble_setPartOfValues1_6] - da2 = da.deepCpy() - da2.fillWithZero() - da2[ 0:3:2, 1:4:2 ] = dv - self.assertTrue( da.isEqual( da2, 1e-20 )) -#! [Snippet_DataArrayDouble_setPartOfValues1_6] - return - - def testExample_DataArrayInt_setPartOfValues1(self): -#! [Snippet_DataArrayInt_setPartOfValues1_1] - da=DataArrayInt() - da.alloc( 4, 4 ) - da.setInfoOnComponents( ["v1","v2","v3","v4"]) - # - dv=DataArrayInt() - dv.alloc( 4, 1 ) - dv.iota(7) - dv.rearrange( 2 ) - dv.setInfoOnComponents( ["a1","a2"]) -#! [Snippet_DataArrayInt_setPartOfValues1_1] -#! [Snippet_DataArrayInt_setPartOfValues1_2] - da.fillWithZero() - da.setPartOfValues1( dv, 1,3,1, 1,3,1, True ) -#! [Snippet_DataArrayInt_setPartOfValues1_2] -#! [Snippet_DataArrayInt_setPartOfValues1_3] - da.fillWithZero() - da.setPartOfValues1( dv, 0,4,1, 1,2,1, False ) -#! [Snippet_DataArrayInt_setPartOfValues1_3] -#! [Snippet_DataArrayInt_setPartOfValues1_4] - da.fillWithZero() - da.setPartOfValues1( dv, 1,2,1, 0,4,1, False ) -#! [Snippet_DataArrayInt_setPartOfValues1_4] -#! [Snippet_DataArrayInt_setPartOfValues1_5] - da.fillWithZero() - da.setPartOfValues1( dv, 0,3,2, 1,4,2, True ) -#! [Snippet_DataArrayInt_setPartOfValues1_5] -#! [Snippet_DataArrayInt_setPartOfValues1_6] - da2 = da.deepCpy() - da2.fillWithZero() - da2[ 0:3:2, 1:4:2 ] = dv - self.assertTrue( da.isEqual( da2 )) -#! [Snippet_DataArrayInt_setPartOfValues1_6] - return - - def testExample_DataArrayDouble_setPartOfValuesSimple1(self): -#! [Snippet_DataArrayDouble_setPartOfValuesSimple1_1] - da=DataArrayDouble() - da.alloc( 4, 4 ) - dv = 7 -#! [Snippet_DataArrayDouble_setPartOfValuesSimple1_1] -#! [Snippet_DataArrayDouble_setPartOfValuesSimple1_2] - da.fillWithZero() - da.setPartOfValuesSimple1( dv, 1,3,1, 1,3,1 ) -#! [Snippet_DataArrayDouble_setPartOfValuesSimple1_2] -#! [Snippet_DataArrayDouble_setPartOfValuesSimple1_3] - da.fillWithZero() - da.setPartOfValuesSimple1( dv, 0,4,1, 1,2,1 ) -#! [Snippet_DataArrayDouble_setPartOfValuesSimple1_3] -#! [Snippet_DataArrayDouble_setPartOfValuesSimple1_4] - da.fillWithZero() - da.setPartOfValuesSimple1( dv, 1,2,1, 0,4,1 ) -#! [Snippet_DataArrayDouble_setPartOfValuesSimple1_4] -#! [Snippet_DataArrayDouble_setPartOfValuesSimple1_5] - da.fillWithZero() - da.setPartOfValuesSimple1( dv, 0,3,2, 1,4,2 ) -#! [Snippet_DataArrayDouble_setPartOfValuesSimple1_5] -#! [Snippet_DataArrayDouble_setPartOfValuesSimple1_6] - da2 = da.deepCpy() - da2.fillWithZero() - da2[ 0:3:2, 1:4:2 ] = dv - self.assertTrue( da.isEqual( da2, 1e-20 )) -#! [Snippet_DataArrayDouble_setPartOfValuesSimple1_6] - return - - def testExample_DataArrayInt_setPartOfValuesSimple1(self): -#! [Snippet_DataArrayInt_setPartOfValuesSimple1_1] - da=DataArrayInt() - da.alloc( 4, 4 ) - dv = 7 -#! [Snippet_DataArrayInt_setPartOfValuesSimple1_1] -#! [Snippet_DataArrayInt_setPartOfValuesSimple1_2] - da.fillWithZero() - da.setPartOfValuesSimple1( dv, 1,3,1, 1,3,1 ) -#! [Snippet_DataArrayInt_setPartOfValuesSimple1_2] -#! [Snippet_DataArrayInt_setPartOfValuesSimple1_3] - da.fillWithZero() - da.setPartOfValuesSimple1( dv, 0,4,1, 1,2,1 ) -#! [Snippet_DataArrayInt_setPartOfValuesSimple1_3] -#! [Snippet_DataArrayInt_setPartOfValuesSimple1_4] - da.fillWithZero() - da.setPartOfValuesSimple1( dv, 1,2,1, 0,4,1 ) -#! [Snippet_DataArrayInt_setPartOfValuesSimple1_4] -#! [Snippet_DataArrayInt_setPartOfValuesSimple1_5] - da.fillWithZero() - da.setPartOfValuesSimple1( dv, 0,3,2, 1,4,2 ) -#! [Snippet_DataArrayInt_setPartOfValuesSimple1_5] -#! [Snippet_DataArrayInt_setPartOfValuesSimple1_6] - da2 = da.deepCpy() - da2.fillWithZero() - da2[ 0:3:2, 1:4:2 ] = dv - self.assertTrue( da.isEqual( da2 )) -#! [Snippet_DataArrayInt_setPartOfValuesSimple1_6] - return - - def testExample_DataArrayDouble_setPartOfValuesSimple2(self): -#! [Snippet_DataArrayDouble_setPartOfValuesSimple2_1] - da=DataArrayDouble() - da.alloc( 4, 4 ) - dv = 7 -#! [Snippet_DataArrayDouble_setPartOfValuesSimple2_1] -#! [Snippet_DataArrayDouble_setPartOfValuesSimple2_2] - da.fillWithZero() - da[[1,2], [1,2]] = dv -#! [Snippet_DataArrayDouble_setPartOfValuesSimple2_2] -#! [Snippet_DataArrayDouble_setPartOfValuesSimple2_3] - da.fillWithZero() - da[[0,1,2,3], [1]] = dv -#! [Snippet_DataArrayDouble_setPartOfValuesSimple2_3] -#! [Snippet_DataArrayDouble_setPartOfValuesSimple2_4] - da.fillWithZero() - da[[1], [0,1,2,3]] = dv -#! [Snippet_DataArrayDouble_setPartOfValuesSimple2_4] -#! [Snippet_DataArrayDouble_setPartOfValuesSimple2_5] - da.fillWithZero() - da[[0,2], [1,3]] = dv -#! [Snippet_DataArrayDouble_setPartOfValuesSimple2_5] - return - - def testExample_DataArrayInt_setPartOfValuesSimple2(self): -#! [Snippet_DataArrayInt_setPartOfValuesSimple2_1] - da=DataArrayInt() - da.alloc( 4, 4 ) - dv = 7 -#! [Snippet_DataArrayInt_setPartOfValuesSimple2_1] -#! [Snippet_DataArrayInt_setPartOfValuesSimple2_2] - da.fillWithZero() - da[[1,2], [1,2]] = dv -#! [Snippet_DataArrayInt_setPartOfValuesSimple2_2] -#! [Snippet_DataArrayInt_setPartOfValuesSimple2_3] - da.fillWithZero() - da[[0,1,2,3], [1]] = dv -#! [Snippet_DataArrayInt_setPartOfValuesSimple2_3] -#! [Snippet_DataArrayInt_setPartOfValuesSimple2_4] - da.fillWithZero() - da[[1], [0,1,2,3]] = dv -#! [Snippet_DataArrayInt_setPartOfValuesSimple2_4] -#! [Snippet_DataArrayInt_setPartOfValuesSimple2_5] - da.fillWithZero() - da[[0,2], [1,3]] = dv -#! [Snippet_DataArrayInt_setPartOfValuesSimple2_5] - return - - def testExample_DataArrayDouble_setPartOfValuesSimple3(self): -#! [Snippet_DataArrayDouble_setPartOfValuesSimple3_1] - da=DataArrayDouble() - da.alloc( 4, 4 ) - dv = 7 -#! [Snippet_DataArrayDouble_setPartOfValuesSimple3_1] -#! [Snippet_DataArrayDouble_setPartOfValuesSimple3_2] - da.fillWithZero() - da[[1,2], 1:3] = dv -#! [Snippet_DataArrayDouble_setPartOfValuesSimple3_2] -#! [Snippet_DataArrayDouble_setPartOfValuesSimple3_3] - da.fillWithZero() - da[[0,1,2,3], 1:2] = dv -#! [Snippet_DataArrayDouble_setPartOfValuesSimple3_3] -#! [Snippet_DataArrayDouble_setPartOfValuesSimple3_4] - da.fillWithZero() - da[[1], 0:4] = dv -#! [Snippet_DataArrayDouble_setPartOfValuesSimple3_4] -#! [Snippet_DataArrayDouble_setPartOfValuesSimple3_5] - da.fillWithZero() - da[[0,2], 1:4:2] = dv -#! [Snippet_DataArrayDouble_setPartOfValuesSimple3_5] - return - - def testExample_DataArrayInt_setPartOfValuesSimple3(self): -#! [Snippet_DataArrayInt_setPartOfValuesSimple3_1] - da=DataArrayInt() - da.alloc( 4, 4 ) - dv = 7 -#! [Snippet_DataArrayInt_setPartOfValuesSimple3_1] -#! [Snippet_DataArrayInt_setPartOfValuesSimple3_2] - da.fillWithZero() - da[[1,2], 1:3] = dv -#! [Snippet_DataArrayInt_setPartOfValuesSimple3_2] -#! [Snippet_DataArrayInt_setPartOfValuesSimple3_3] - da.fillWithZero() - da[[0,1,2,3], 1:2] = dv -#! [Snippet_DataArrayInt_setPartOfValuesSimple3_3] -#! [Snippet_DataArrayInt_setPartOfValuesSimple3_4] - da.fillWithZero() - da[[1], 0:4] = dv -#! [Snippet_DataArrayInt_setPartOfValuesSimple3_4] -#! [Snippet_DataArrayInt_setPartOfValuesSimple3_5] - da.fillWithZero() - da[[0,2], 1:4:2] = dv -#! [Snippet_DataArrayInt_setPartOfValuesSimple3_5] - return - - def testExample_DataArrayDouble_setSelectedComponents(self): -#! [Snippet_DataArrayDouble_setSelectedComponents1] - array1=[1.,2., 3.,4., 5.,6.] - da=DataArrayDouble(array1,3,2) - da.setInfoOnComponents( ["a1","a2"]) -#! [Snippet_DataArrayDouble_setSelectedComponents1] -#! [Snippet_DataArrayDouble_setSelectedComponents2] - dv=DataArrayDouble() - dv.alloc( 4, 4 ) - dv.fillWithZero() - dv.setInfoOnComponents( ["v1","v2","v3","v4"]) - dv2 = dv.deepCpy() - dv.setSelectedComponents( da, [1,0] ) -#! [Snippet_DataArrayDouble_setSelectedComponents2] -#! [Snippet_DataArrayDouble_setSelectedComponents3] - dv2[:3,[1,0]] = da - self.assertTrue( dv.isEqualWithoutConsideringStr( dv2, 1e-20 )) -#! [Snippet_DataArrayDouble_setSelectedComponents3] - return - - def testExample_DataArrayInt_setSelectedComponents(self): -#! [Snippet_DataArrayInt_setSelectedComponents1] - da=DataArrayInt() - array1=[1,2, 3,4, 5,6] - da.setValues(array1,3,2) - da.setInfoOnComponents( ["a1","a2"]) -#! [Snippet_DataArrayInt_setSelectedComponents1] -#! [Snippet_DataArrayInt_setSelectedComponents2] - dv=DataArrayInt() - dv.alloc( 4, 4 ) - dv.fillWithZero() - dv.setInfoOnComponents( ["v1","v2","v3","v4"]) - dv2 = dv.deepCpy() - dv.setSelectedComponents( da, [1,0] ) -#! [Snippet_DataArrayInt_setSelectedComponents2] -#! [Snippet_DataArrayInt_setSelectedComponents3] - dv2[:3,[1,0]] = da - self.assertTrue( dv.isEqualWithoutConsideringStr( dv2 )) -#! [Snippet_DataArrayInt_setSelectedComponents3] - return - - def testExample_DataArrayDouble_getDifferentValues(self): -#! [Snippet_DataArrayDouble_getDifferentValues1] - array1=[2.3,1.2,1.3,2.3,2.301,0.8] - da=DataArrayDouble(array1,6,1) - # - dv=da.getDifferentValues(2e-1) - expected2=[2.301,1.3,0.8] - self.assertEqual(3,dv.getNbOfElems()) - for i in xrange(3): - self.assertAlmostEqual(expected2[i],dv.getIJ(i,0),14) - pass -#! [Snippet_DataArrayDouble_getDifferentValues1] - return - - def testExample_DataArrayDouble_findCommonTuples1(self): -#! [PySnippet_DataArrayDouble_findCommonTuples1] - array2=[2.3,2.3, 1.2,1.2, 1.3,1.3, 2.3,2.3, 2.301,2.301, 0.8,0.8] - da=DataArrayDouble(array2,6,2) -#! [PySnippet_DataArrayDouble_findCommonTuples1] -#! [PySnippet_DataArrayDouble_findCommonTuples2] - c,cI=da.findCommonTuples(1.01e-1) - expected3=[0,3,4,1,2] - expected4=[0,3,5] - self.assertEqual(expected3,c.getValues()) - self.assertEqual(expected4,cI.getValues()) -#! [PySnippet_DataArrayDouble_findCommonTuples2] - return - - def testExampleDataArrayDoubleMeldWith(self): -#! [PySnippet_DataArrayDouble_Meld1_1] - da1=DataArrayDouble() - da1.alloc(7,2) - da2=DataArrayDouble() - da2.alloc(7,1) - # - da1.fillWithValue(7.) - da2.iota(0.) - da3=da2.applyFunc(3,"10*x*IVec+100*x*JVec+1000*x*KVec") - # - da1.setInfoOnComponent(0,"c0da1") - da1.setInfoOnComponent(1,"c1da1") - da3.setInfoOnComponent(0,"c0da3") - da3.setInfoOnComponent(1,"c1da3") - da3.setInfoOnComponent(2,"c2da3") - # - da1C=da1.deepCpy() - da1.meldWith(da3) -#! [PySnippet_DataArrayDouble_Meld1_1] - - def testExampleDataArrayIntMeldWith(self): -#! [PySnippet_DataArrayInt_Meld1_1] - da1=DataArrayInt() - da1.alloc(7,2) - da2=DataArrayInt() - da2.alloc(7,1) - # - da1.fillWithValue(7) - da2.iota(0) - # - da1.setInfoOnComponent(0,"c0da1") - da1.setInfoOnComponent(1,"c1da1") - da2.setInfoOnComponent(0,"c0da2") - # - da1.meldWith(da2) -#! [PySnippet_DataArrayInt_Meld1_1] - - def testExampleDataArrayDoubleKeepSelectedComponents1(self): -#! [SnippeDataArrayDoubleKeepSelectedComponents1_1] - arr1=[1.,2.,3.,4., # tuple 0 - 11.,12.,13.,14., # tuple 1 - 21.,22.,23.,24., # ... - 31.,32.,33.,34., - 41.,42.,43.,44.] - a1=DataArrayDouble(arr1,5,4) - a1.setInfoOnComponent(0,"a") - a1.setInfoOnComponent(1,"b") - a1.setInfoOnComponent(2,"c") - a1.setInfoOnComponent(3,"d") -#! [SnippeDataArrayDoubleKeepSelectedComponents1_1] -#! [SnippeDataArrayDoubleKeepSelectedComponents1_2] - arr2V=[1,2,1,2,0,0] - a2=a1.keepSelectedComponents(arr2V) -#! [SnippeDataArrayDoubleKeepSelectedComponents1_2] - return - - def testExampleDataArrayIntKeepSelectedComponents1(self): -#! [SnippeDataArrayIntKeepSelectedComponents1_1] - arr1=[1,2,3,4, # tuple 0 - 11,12,13,14, # tuple 1 - 21,22,23,24, # - 31,32,33,34, - 41,42,43,44] - a1=DataArrayInt() - a1.setValues(arr1,5,4) - a1.setInfoOnComponent(0,"a") - a1.setInfoOnComponent(1,"b") - a1.setInfoOnComponent(2,"c") - a1.setInfoOnComponent(3,"d") -#! [SnippeDataArrayIntKeepSelectedComponents1_1] -#! [SnippeDataArrayIntKeepSelectedComponents1_2] - arr2V=[1,2,1,2,0,0] - a2=a1.keepSelectedComponents(arr2V) -#! [SnippeDataArrayIntKeepSelectedComponents1_2] -#! [SnippeDataArrayIntKeepSelectedComponents1_3] - a3=a1[:,arr2V ] -#! [SnippeDataArrayIntKeepSelectedComponents1_3] - return - - def testExampleFieldDoubleBuildSubPart1(self): - from MEDCouplingDataForTest import MEDCouplingDataForTest -#! [PySnippetFieldDoubleBuildSubPart1_1] - mesh1=MEDCouplingDataForTest.build2DTargetMesh_1() - f1=MEDCouplingFieldDouble(ON_CELLS,ONE_TIME) - f1.setTime(2.3,5,6) - f1.setMesh(mesh1) - arr1=[3.,103.,4.,104.,5.,105.,6.,106.,7.,107.] - array=DataArrayDouble(arr1,mesh1.getNumberOfCells(),2) - f1.setArray(array) -# ! [PySnippetFieldDoubleBuildSubPart1_1] -# ! [PySnippetFieldDoubleBuildSubPart1_2] - part1=[2,1,4] - f2=f1.buildSubPart(part1) -# ! [PySnippetFieldDoubleBuildSubPart1_2] - f2.zipCoords() - self.assertEqual(3,f2.getNumberOfTuples()) - self.assertEqual(2,f2.getNumberOfComponents()) - expected1=[5.,105.,4.,104.,7.,107.] - for i in xrange(6): - self.assertAlmostEqual(f2.getIJ(0,i),expected1[i],12) - pass - self.assertEqual(3,f2.getMesh().getNumberOfCells()) - self.assertEqual(6,f2.getMesh().getNumberOfNodes()) - self.assertEqual(2,f2.getMesh().getSpaceDimension()) - self.assertEqual(2,f2.getMesh().getMeshDimension()) - m2C=f2.getMesh() - self.assertEqual(13,m2C.getMeshLength()) - expected2=[0.2, -0.3, 0.7, -0.3, 0.2, 0.2, 0.7, 0.2, 0.2, 0.7, 0.7, 0.7] - for i in xrange(12): - self.assertAlmostEqual(expected2[i],m2C.getCoords().getIJ(0,i),12) - pass - expected3=[3,2,3,1,3,0,2,1,4,4,5,3,2] - self.assertEqual(expected3,list(m2C.getNodalConnectivity().getValues())) - expected4=[0,4,8,13] - self.assertEqual(expected4,list(m2C.getNodalConnectivityIndex().getValues())) - # Test with field on nodes. -# ! [PySnippetFieldDoubleBuildSubPart1_3] - f1=MEDCouplingFieldDouble(ON_NODES,ONE_TIME) - f1.setTime(2.3,5,6) - f1.setMesh(mesh1) - arr2=[3.,103.,4.,104.,5.,105.,6.,106.,7.,107.,8.,108.,9.,109.,10.,110.,11.,111.] - array=DataArrayDouble(arr2,mesh1.getNumberOfNodes(),2) - f1.setArray(array) -# ! [PySnippetFieldDoubleBuildSubPart1_3] -# ! [PySnippetFieldDoubleBuildSubPart1_4] - part2=[1,2] - f2=f1.buildSubPart(part2) -# ! [PySnippetFieldDoubleBuildSubPart1_4] - self.assertEqual(4,f2.getNumberOfTuples()) - self.assertEqual(2,f2.getNumberOfComponents()) - expected5=[4.,104.,5.,105.,7.,107.,8.,108.] - for i in xrange(8): - self.assertAlmostEqual(f2.getIJ(0,i),expected5[i],12) - pass - self.assertEqual(2,f2.getMesh().getNumberOfCells()) - self.assertEqual(4,f2.getMesh().getNumberOfNodes()) - self.assertEqual(2,f2.getMesh().getSpaceDimension()) - self.assertEqual(2,f2.getMesh().getMeshDimension()) - m2C=f2.getMesh() - self.assertEqual(8,m2C.getMeshLength()) - for i in xrange(8):#8 is not an error - self.assertAlmostEqual(expected2[i],m2C.getCoords().getIJ(0,i),12) - pass - self.assertEqual(expected3[:4],[int(i) for i in m2C.getNodalConnectivity()][4:]) - self.assertEqual(expected3[4:8],[int(i) for i in m2C.getNodalConnectivity()][:4]) - self.assertEqual(expected4[:3],[int(i) for i in m2C.getNodalConnectivityIndex()]) - #idem previous because nodes of cell#4 are not fully present in part3 - part3=[1,2] - arrr=DataArrayInt() - arrr.setValues(part3,2,1) - f2=f1.buildSubPart(arrr) - self.assertEqual(4,f2.getNumberOfTuples()) - self.assertEqual(2,f2.getNumberOfComponents()) - for i in xrange(8): - self.assertAlmostEqual(f2.getIJ(0,i),expected5[i],12) - pass - self.assertEqual(2,f2.getMesh().getNumberOfCells()) - self.assertEqual(4,f2.getMesh().getNumberOfNodes()) - self.assertEqual(2,f2.getMesh().getSpaceDimension()) - self.assertEqual(2,f2.getMesh().getMeshDimension()) - m2C=f2.getMesh() - self.assertEqual(8,m2C.getMeshLength()) - for i in xrange(8):#8 is not an error - self.assertAlmostEqual(expected2[i],m2C.getCoords().getIJ(0,i),12) - pass - self.assertEqual(expected3[:4],[int(i) for i in m2C.getNodalConnectivity()][4:8]) - self.assertEqual(expected3[4:8],[int(i) for i in m2C.getNodalConnectivity()][:4]) - self.assertEqual(expected4[:3],m2C.getNodalConnectivityIndex().getValues()) - part4=[1,2,4] - f2=f1.buildSubPart(part4) - self.assertEqual(6,f2.getNumberOfTuples()) - self.assertEqual(2,f2.getNumberOfComponents()) - expected6=[4.,104.,5.,105.,7.,107.,8.,108.,10.,110.,11.,111.] - for i in xrange(12): - self.assertAlmostEqual(f2.getIJ(0,i),expected6[i],12) - pass - self.assertEqual(3,f2.getMesh().getNumberOfCells()) - self.assertEqual(6,f2.getMesh().getNumberOfNodes()) - self.assertEqual(2,f2.getMesh().getSpaceDimension()) - self.assertEqual(2,f2.getMesh().getMeshDimension()) - m2C=f2.getMesh() - self.assertEqual(13,m2C.getMeshLength()) - for i in xrange(12): - self.assertAlmostEqual(expected2[i],m2C.getCoords().getIJ(0,i),12) - pass - self.assertEqual(expected3[0:4],m2C.getNodalConnectivity().getValues()[4:8]) - self.assertEqual(expected3[4:8],m2C.getNodalConnectivity().getValues()[0:4]) - self.assertEqual(expected3[8:13],m2C.getNodalConnectivity().getValues()[8:13]) - self.assertEqual(expected4,m2C.getNodalConnectivityIndex().getValues()) - # previous line equivalent to - self.assertEqual(expected4,[int(i) for i in m2C.getNodalConnectivityIndex()]) - return - - def testExampleUMeshStdBuild1(self): -# ! [PySnippetUMeshStdBuild1_1] - coords=[-0.3,-0.3,0., 0.2,-0.3,0., 0.7,-0.3,0., -0.3,0.2,0., 0.2,0.2,0., - 0.7,0.2,0., -0.3,0.7,0., 0.2,0.7,0., 0.7,0.7,0. ] - nodalConnPerCell=[0,3,4,1, 1,4,2, 4,5,2, 6,7,4,3, 7,8,5,4] -# ! [PySnippetUMeshStdBuild1_1] -# ! [PySnippetUMeshStdBuild1_2] - mesh=MEDCouplingUMesh("My2DMesh",2) -# ! [PySnippetUMeshStdBuild1_2] -# ! [PySnippetUMeshStdBuild1_3] - mesh.allocateCells(5)#You can put more than 5 if you want but not less. - mesh.insertNextCell(NORM_QUAD4,nodalConnPerCell[:4]) - mesh.insertNextCell(NORM_TRI3,nodalConnPerCell[4:7]) - mesh.insertNextCell(NORM_TRI3,nodalConnPerCell[7:10]) - mesh.insertNextCell(NORM_QUAD4,nodalConnPerCell[10:14]) - mesh.insertNextCell(NORM_QUAD4,nodalConnPerCell[14:]) - mesh.finishInsertingCells() -# ! [PySnippetUMeshStdBuild1_3] -# ! [PySnippetUMeshStdBuild1_4] - coordsArr=DataArrayDouble(coords,9,3)#here coordsArr are declared to have 3 components, mesh will deduce that its spaceDim==3. - mesh.setCoords(coordsArr)#coordsArr contains 9 tuples, that is to say mesh contains 9 nodes. -# ! [PySnippetUMeshStdBuild1_4] -# ! [PySnippetUMeshStdBuild1_5] -# ! [PySnippetUMeshStdBuild1_5] - mesh.checkCoherency() - return - - def testExampleCMeshStdBuild1(self): -# ! [PySnippetCMeshStdBuild1_1] - XCoords=[-0.3,0.,0.1,0.3,0.45,0.47,0.49,1.,1.22] # 9 values along X - YCoords=[0.,0.1,0.37,0.45,0.47,0.49,1.007] # 7 values along Y - arrX=DataArrayDouble(XCoords) - arrX.setInfoOnComponent(0,"X [m]") - arrY=DataArrayDouble(YCoords) - arrY.setInfoOnComponent(0,"Y [m]") -# ! [PySnippetCMeshStdBuild1_1] -# ! [PySnippetCMeshStdBuild1_2] - mesh=MEDCouplingCMesh("My2D_CMesh") - mesh.setCoords(arrX,arrY) -# ! [PySnippetCMeshStdBuild1_2] -# ! [PySnippetCMeshStdBuild1_3] - self.assertEqual(8*6,mesh.getNumberOfCells()) - self.assertEqual(9*7,mesh.getNumberOfNodes()) - self.assertEqual(2,mesh.getSpaceDimension()) - self.assertEqual(2,mesh.getMeshDimension()) -# ! [PySnippetCMeshStdBuild1_3] - mesh=MEDCouplingCMesh("My2D_CMesh") -# ! [PySnippetCMeshStdBuild1_2bis] - mesh.setCoordsAt(0,arrX) - mesh.setCoordsAt(1,arrY) -# ! [PySnippetCMeshStdBuild1_2bis] - self.assertEqual(8*6,mesh.getNumberOfCells()) - self.assertEqual(9*7,mesh.getNumberOfNodes()) - self.assertEqual(2,mesh.getSpaceDimension()) - self.assertEqual(2,mesh.getMeshDimension()) - return - - def testExampleUMeshAdvBuild1(self): -# ! [PySnippetUMeshAdvBuild1_1] - coords=[-0.3,-0.3,0., 0.2,-0.3,0., 0.7,-0.3,0., -0.3,0.2,0., 0.2,0.2,0., - 0.7,0.2,0., -0.3,0.7,0., 0.2,0.7,0., 0.7,0.7,0. ] - nodalConnPerCell=[4,0,3,4,1, 3,1,4,2, 3,4,5,2, 4,6,7,4,3, 4,7,8,5,4] - nodalConnPerCellIndex=[0,5,9,13,18,23] -# ! [PySnippetUMeshAdvBuild1_1] -# ! [PySnippetUMeshAdvBuild1_2] - mesh=MEDCouplingUMesh("My2DMesh",2) -# ! [PySnippetUMeshAdvBuild1_2] -# ! [PySnippetUMeshAdvBuild1_3] - nodalConn=DataArrayInt(nodalConnPerCell,23,1) - nodalConnI=DataArrayInt(nodalConnPerCellIndex,6,1) - mesh.setConnectivity(nodalConn,nodalConnI,True) -# ! [PySnippetUMeshAdvBuild1_3] -# ! [PySnippetUMeshAdvBuild1_4] - coordsArr=DataArrayDouble(coords,9,3)#here coordsArr are declared to have 3 components, mesh will deduce that its spaceDim==3. - mesh.setCoords(coordsArr)#coordsArr contains 9 tuples, that is to say mesh contains 9 nodes. -# ! [PySnippetUMeshAdvBuild1_4] -# ! [PySnippetUMeshAdvBuild1_5] -# ! [PySnippetUMeshAdvBuild1_5] - mesh.checkCoherency() - return - - def testExampleDataArrayBuild1(self): -# ! [PySnippetDataArrayBuild1_0] - dataDouble=[0.,10.,20.,1.,11.,21.,2.,12.,22.,3.,13.,23.,4.,14.,24.] -# ! [PySnippetDataArrayBuild1_0] -# ! [PySnippetDataArrayBuild1_1] - arrayDouble=DataArrayDouble() - arrayDouble.setValues(dataDouble,5,3)# 5 tuples containing each 3 components -# ! [PySnippetDataArrayBuild1_1] -# ! [PySnippetDataArrayBuild1_1bis] - arrayDouble=DataArrayDouble(dataDouble,5,3) -# ! [PySnippetDataArrayBuild1_1bis] -# ! [PySnippetDataArrayBuild1_2] - dataInt=[0, 10, 20, 1, 11, 21, 2, 12, 22, 3, 13, 23, 4, 14, 24] -# ! [PySnippetDataArrayBuild1_2] -# ! [PySnippetDataArrayBuild1_3] - arrayInt=DataArrayInt() - arrayInt.setValues(dataInt,5,3)# 5 tuples containing each 3 components -# ! [PySnippetDataArrayBuild1_3] -# ! [PySnippetDataArrayBuild1_3bis] - arrayInt=DataArrayInt(dataInt,5,3) -# ! [PySnippetDataArrayBuild1_3bis] - return - - def testExampleFieldDoubleBuild1(self): - XCoords=[-0.3,0.07,0.1,0.3,0.45,0.47,0.49,1.,1.22]; arrX=DataArrayDouble(XCoords) - YCoords=[0.07,0.1,0.37,0.45,0.47,0.49,1.007]; arrY=DataArrayDouble(YCoords) - mesh=MEDCouplingCMesh("My2D_CMesh") - mesh.setCoords(arrX,arrY) -# ! [PySnippetFieldDoubleBuild1_1] - fieldOnCells=MEDCouplingFieldDouble(ON_CELLS,NO_TIME) - fieldOnCells.setName("MyTensorFieldOnCellNoTime") - fieldOnCells.setMesh(mesh) - array=DataArrayDouble() - array.alloc(fieldOnCells.getMesh().getNumberOfCells(),9) # Implicitely fieldOnCells will be a 9 components field. - array.fillWithValue(7.) - fieldOnCells.setArray(array) - # fieldOnCells is now usable - # ... -# ! [PySnippetFieldDoubleBuild1_1] -# ! [PySnippetFieldDoubleBuild1_2] - f1=mesh.fillFromAnalytic(ON_CELLS,1,"x*x+y*y*3+2.*x") # f1 is scalar - f2=mesh.fillFromAnalytic(ON_CELLS,1,"cos(x+y/x)") # f2 is scalar too - f2bis=mesh.fillFromAnalytic(ON_CELLS,2,"x*x*IVec+3*y*JVec") # f2bis is a vectors field - f3=f1+f2 # f3 scalar - f4=f3/f2 # f4 scalar - f2bis.applyFunc(1,"sqrt(x*x+y*y)") # f2bis becomes scalar - f5=f2bis*f4 # f5 scalar - pos1=[0.48,0.38] - res=f4.getValueOn(pos1) # f4 is scalar so the returned value is of size 1. - # ... -# ! [PySnippetFieldDoubleBuild1_2] -# ! [PySnippetFieldDoubleBuild1_3] -# ! [PySnippetFieldDoubleBuild1_3] - return - - def testExampleFieldDoubleBuild2(self): - XCoords=[-0.3,0.,0.1,0.3,0.45,0.47,0.49,1.,1.22]; arrX=DataArrayDouble(XCoords) - YCoords=[0.,0.1,0.37,0.45,0.47,0.49,1.007]; arrY=DataArrayDouble(YCoords) - mesh=MEDCouplingCMesh("My2D_CMesh") - mesh.setCoords(arrX,arrY) -# ! [PySnippetFieldDoubleBuild2_1] - fieldOnNodes=MEDCouplingFieldDouble(ON_NODES,NO_TIME) - fieldOnNodes.setName("MyScalarFieldOnNodeNoTime") - fieldOnNodes.setMesh(mesh) - array=DataArrayDouble() - array.alloc(fieldOnNodes.getMesh().getNumberOfNodes(),1) # Implicitely fieldOnNodes will be a 1 component field. - array.fillWithValue(7.) - fieldOnNodes.setArray(array) - # fieldOnNodes is now usable - # ... -# ! [PySnippetFieldDoubleBuild2_1] - return - - def testExampleFieldDoubleBuild3(self): - XCoords=[-0.3,0.,0.1,0.3,0.45,0.47,0.49,1.,1.22]; arrX=DataArrayDouble(XCoords) - YCoords=[0.,0.1,0.37,0.45,0.47,0.49,1.007]; arrY=DataArrayDouble(YCoords) - mesh=MEDCouplingCMesh("My2D_CMesh") - mesh.setCoords(arrX,arrY) -# ! [PySnippetFieldDoubleBuild3_1] - fieldOnCells=MEDCouplingFieldDouble(ON_CELLS,ONE_TIME) - fieldOnCells.setName("MyTensorFieldOnCellNoTime") - fieldOnCells.setTimeUnit("ms") # Time unit is ms. - fieldOnCells.setTime(4.22,2,-1) # Time attached is 4.22 ms, iteration id is 2 and order id (or sub iteration id) is -1 - fieldOnCells.setMesh(mesh) - array=DataArrayDouble() - array.alloc(fieldOnCells.getMesh().getNumberOfCells(),2) # Implicitely fieldOnCells will be a 2 components field. - array.fillWithValue(7.) - fieldOnCells.setArray(array) - # fieldOnCells is now usable - # ... -# ! [PySnippetFieldDoubleBuild3_1] - return - - def testExampleFieldDoubleBuild4(self): - XCoords=[-0.3,0.,0.1,0.3,0.45,0.47,0.49,1.,1.22]; arrX=DataArrayDouble(XCoords) - YCoords=[0.,0.1,0.37,0.45,0.47,0.49,1.007]; arrY=DataArrayDouble(YCoords) - mesh=MEDCouplingCMesh("My2D_CMesh") - mesh.setCoords(arrX,arrY) -# ! [PySnippetFieldDoubleBuild4_1] - fieldOnNodes=MEDCouplingFieldDouble(ON_NODES,CONST_ON_TIME_INTERVAL) - fieldOnNodes.setName("MyVecFieldOnNodeWithConstTime") - fieldOnNodes.setTimeUnit("ms") # Time unit is ms. - fieldOnNodes.setStartTime(4.22,2,-1) - fieldOnNodes.setEndTime(6.44,4,-1)# fieldOnNodes is defined in interval [4.22 ms,6.44 ms] - fieldOnNodes.setMesh(mesh) - array=DataArrayDouble() - array.alloc(fieldOnNodes.getMesh().getNumberOfNodes(),3) # Implicitely fieldOnNodes will be a 3 components field. - array.fillWithValue(7.) - fieldOnNodes.setArray(array) - # fieldOnNodes is now usable - # ... -# ! [PySnippetFieldDoubleBuild4_1] - return - - def testExampleDataArrayApplyFunc1(self): -# ! [PySnippetDataArrayApplyFunc1_1] - d=DataArrayDouble([1.,2.,11.,12.,21.,22.,31.,41.],4,2) - self.assertRaises(InterpKernelException,d.applyFunc,"x*y") -# ! [PySnippetDataArrayApplyFunc1_1] -# ! [PySnippetDataArrayApplyFunc1_2] - d=DataArrayDouble([1.,2.,11.,12.,21.,22.,31.,41.],4,2) - d1=d.applyFunc("smth*smth") - self.assertTrue(d1.isEqual(DataArrayDouble([1.,4.,121.,144.,441.,484.,961.,1681.],4,2),1e-12)) -# ! [PySnippetDataArrayApplyFunc1_2] -# ! [PySnippetDataArrayApplyFunc1_3] - d2=d.applyFunc(2,"smth1*IVec+2*smth2*JVec") - self.assertTrue(d2.isEqual(DataArrayDouble([1.,4.,11.,24.,21.,44.,31.,82.],4,2),1e-12)) -# ! [PySnippetDataArrayApplyFunc1_3] -# ! [PySnippetDataArrayApplyFunc1_4] - dd=DataArrayDouble([1.,4.,3.,11.,144.,13.,21.,484.,23.,31.,1024.,33.],4,3) -# ! [PySnippetDataArrayApplyFunc1_4] -# ! [PySnippetDataArrayApplyFunc1_5] - dd1=dd.applyFunc(1,"f+sqrt(g)+h") - self.assertTrue(dd1.isEqual(DataArrayDouble([6.,36.,66.,96.],4,1),1e-12)) -# ! [PySnippetDataArrayApplyFunc1_5] -# ! [PySnippetDataArrayApplyFunc1_6] - dd2=dd.applyFunc(1,"a+0.*b+c") - self.assertTrue(dd2.isEqual(DataArrayDouble([4.,24.,44.,64.],4,1),1e-12)) -# ! [PySnippetDataArrayApplyFunc1_6] -# ! [PySnippetDataArrayApplyFunc1_7] - ddd=DataArrayDouble([1.,4.,3.,11.,144.,13.,21.,484.,23.,31.,1024.,33.],4,3) - ddd.setInfoOnComponents(["Y [m]","AA [m/s]","GG [MW]"]) -# ! [PySnippetDataArrayApplyFunc1_7] -# ! [PySnippetDataArrayApplyFunc1_8] - ddd1=ddd.applyFunc2(1,"Y+GG") - self.assertTrue(ddd1.isEqual(DataArrayDouble([4.,24.,44.,64.],4,1),1e-12)) -# ! [PySnippetDataArrayApplyFunc1_8] -# ! [PySnippetDataArrayApplyFunc1_9] - ddd1=ddd.applyFunc3(1,["X","Y","Z"],"X+Z") - self.assertTrue(ddd1.isEqual(DataArrayDouble([4.,24.,44.,64.],4,1),1e-12)) -# ! [PySnippetDataArrayApplyFunc1_9] - return - - pass - -unittest.main() diff --git a/src/MEDCoupling_Swig/MEDCouplingFieldDiscretization.i b/src/MEDCoupling_Swig/MEDCouplingFieldDiscretization.i deleted file mode 100644 index bf4732b14..000000000 --- a/src/MEDCoupling_Swig/MEDCouplingFieldDiscretization.i +++ /dev/null @@ -1,472 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 -// 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) - -%newobject ParaMEDMEM::MEDCouplingFieldDiscretization::New; -%newobject ParaMEDMEM::MEDCouplingFieldDiscretization::deepCpy; -%newobject ParaMEDMEM::MEDCouplingFieldDiscretization::clone; -%newobject ParaMEDMEM::MEDCouplingFieldDiscretization::clonePartRange; -%newobject ParaMEDMEM::MEDCouplingFieldDiscretization::getOffsetArr; -%newobject ParaMEDMEM::MEDCouplingFieldDiscretization::getLocalizationOfDiscValues; -%newobject ParaMEDMEM::MEDCouplingFieldDiscretization::getMeasureField; -%newobject ParaMEDMEM::MEDCouplingFieldDiscretization::clonePart; -%newobject ParaMEDMEM::MEDCouplingFieldDiscretization::getValueOnMulti; -%newobject ParaMEDMEM::MEDCouplingFieldDiscretization::computeTupleIdsToSelectFromCellIds; -%newobject ParaMEDMEM::MEDCouplingFieldDiscretizationKriging::PerformDriftOfVec; - -namespace ParaMEDMEM -{ - class MEDCouplingFieldDiscretization : public RefCountObject, public TimeLabel - { - public: - static MEDCouplingFieldDiscretization *New(TypeOfField type) throw(INTERP_KERNEL::Exception); - double getPrecision() const throw(INTERP_KERNEL::Exception); - void setPrecision(double val) throw(INTERP_KERNEL::Exception); - static TypeOfField GetTypeOfFieldFromStringRepr(const std::string& repr) throw(INTERP_KERNEL::Exception); - virtual TypeOfField getEnum() const throw(INTERP_KERNEL::Exception); - virtual bool isEqual(const MEDCouplingFieldDiscretization *other, double eps) const throw(INTERP_KERNEL::Exception); - virtual bool isEqualIfNotWhy(const MEDCouplingFieldDiscretization *other, double eps, std::string& reason) const throw(INTERP_KERNEL::Exception); - virtual bool isEqualWithoutConsideringStr(const MEDCouplingFieldDiscretization *other, double eps) const throw(INTERP_KERNEL::Exception); - virtual MEDCouplingFieldDiscretization *deepCpy() const throw(INTERP_KERNEL::Exception); - virtual MEDCouplingFieldDiscretization *clone() const throw(INTERP_KERNEL::Exception); - virtual MEDCouplingFieldDiscretization *clonePartRange(int beginCellIds, int endCellIds, int stepCellIds) const throw(INTERP_KERNEL::Exception); - virtual std::string getStringRepr() const throw(INTERP_KERNEL::Exception); - virtual const char *getRepr() const throw(INTERP_KERNEL::Exception); - virtual int getNumberOfTuples(const MEDCouplingMesh *mesh) const throw(INTERP_KERNEL::Exception); - virtual int getNumberOfMeshPlaces(const MEDCouplingMesh *mesh) const throw(INTERP_KERNEL::Exception); - virtual DataArrayInt *getOffsetArr(const MEDCouplingMesh *mesh) const throw(INTERP_KERNEL::Exception); - virtual DataArrayDouble *getLocalizationOfDiscValues(const MEDCouplingMesh *mesh) const throw(INTERP_KERNEL::Exception); - virtual void checkCompatibilityWithNature(NatureOfField nat) const throw(INTERP_KERNEL::Exception); - 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 DataArray *da) const throw(INTERP_KERNEL::Exception); - virtual MEDCouplingFieldDouble *getMeasureField(const MEDCouplingMesh *mesh, bool isAbs) const throw(INTERP_KERNEL::Exception); - virtual void setGaussLocalizationOnType(const MEDCouplingMesh *m, INTERP_KERNEL::NormalizedCellType type, const std::vector& refCoo, - const std::vector& gsCoo, const std::vector& wg) throw(INTERP_KERNEL::Exception); - virtual void clearGaussLocalizations() throw(INTERP_KERNEL::Exception); - virtual MEDCouplingGaussLocalization& getGaussLocalization(int locId) throw(INTERP_KERNEL::Exception); - virtual int getNbOfGaussLocalization() const throw(INTERP_KERNEL::Exception); - virtual int getGaussLocalizationIdOfOneCell(int cellId) const throw(INTERP_KERNEL::Exception); - virtual int getGaussLocalizationIdOfOneType(INTERP_KERNEL::NormalizedCellType type) const throw(INTERP_KERNEL::Exception); - %extend - { - virtual MEDCouplingFieldDiscretization *clonePart(PyObject *li) - { - int sz=0,sw=-1,val1=-1; - std::vector val2; - const int *inp=convertObjToPossibleCpp1_Safe(li,sw,sz,val1,val2); - return self->clonePart(inp,inp+sz); - } - - virtual PyObject *buildSubMeshDataRange(const MEDCouplingMesh *mesh, int beginCellIds, int endCellIds, int stepCellIds, int& beginOut, int& endOut, int& stepOut, DataArrayInt *&di) const throw(INTERP_KERNEL::Exception) - { - DataArrayInt *ret1=0; - int bb,ee,ss; - MEDCouplingMesh *ret0=self->buildSubMeshDataRange(mesh,beginCellIds,endCellIds,stepCellIds,bb,ee,ss,ret1); - PyObject *res=PyTuple_New(2); - PyTuple_SetItem(res,0,convertMesh(ret0, SWIG_POINTER_OWN | 0 )); - if(ret1) - PyTuple_SetItem(res,1,SWIG_NewPointerObj((void*)ret1,SWIGTYPE_p_ParaMEDMEM__DataArrayInt,SWIG_POINTER_OWN | 0)); - else - { - PyObject *res1=PySlice_New(PyInt_FromLong(bb),PyInt_FromLong(ee),PyInt_FromLong(ss)); - PyTuple_SetItem(res,1,res1); - } - return res; - } - - virtual int getNumberOfTuplesExpectedRegardingCode(PyObject *code, PyObject *idsPerType) const throw(INTERP_KERNEL::Exception) - { - std::vector inp0; - convertPyToNewIntArr4(code,1,3,inp0); - std::vector inp1; - convertFromPyObjVectorOfObj(idsPerType,SWIGTYPE_p_ParaMEDMEM__DataArrayInt,"DataArrayInt",inp1); - return self->getNumberOfTuplesExpectedRegardingCode(inp0,inp1); - } - - virtual PyObject *computeMeshRestrictionFromTupleIds(const MEDCouplingMesh *mesh, PyObject *tupleIds) const throw(INTERP_KERNEL::Exception) - { - std::vector vVal; int iVal=-1; - int sz=-1,sw=0; - const int *tupleIdsBg=convertObjToPossibleCpp1_Safe(tupleIds,sw,sz,iVal,vVal); - if(sw==0) - throw INTERP_KERNEL::Exception("MEDCouplingFieldDiscretization::computeMeshRestrictionFromTupleIds : none parameter in input !"); - DataArrayInt *ret0=0,*ret1=0; - self->computeMeshRestrictionFromTupleIds(mesh,tupleIdsBg,tupleIdsBg+sz,ret0,ret1); - PyObject *pyRet=PyTuple_New(2); - PyTuple_SetItem(pyRet,0,SWIG_NewPointerObj(SWIG_as_voidptr(ret0),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 )); - PyTuple_SetItem(pyRet,1,SWIG_NewPointerObj(SWIG_as_voidptr(ret1),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 )); - return pyRet; - } - - virtual PyObject *normL1(const MEDCouplingMesh *mesh, const DataArrayDouble *arr) const throw(INTERP_KERNEL::Exception) - { - if(!arr) - throw INTERP_KERNEL::Exception("wrap of MEDCouplingFieldDiscretization::normL1 : input array is null !"); - int sz(arr->getNumberOfComponents()); - INTERP_KERNEL::AutoPtr tmp=new double[sz]; - self->normL1(mesh,arr,tmp); - return convertDblArrToPyList(tmp,sz); - } - - virtual PyObject *normL2(const MEDCouplingMesh *mesh, const DataArrayDouble *arr) const throw(INTERP_KERNEL::Exception) - { - if(!arr) - throw INTERP_KERNEL::Exception("wrap of MEDCouplingFieldDiscretization::normL2 : input array is null !"); - int sz(arr->getNumberOfComponents()); - INTERP_KERNEL::AutoPtr tmp=new double[sz]; - self->normL2(mesh,arr,tmp); - return convertDblArrToPyList(tmp,sz); - } - - virtual PyObject *integral(const MEDCouplingMesh *mesh, const DataArrayDouble *arr, bool isWAbs) const throw(INTERP_KERNEL::Exception) - { - if(!arr) - throw INTERP_KERNEL::Exception("wrap of MEDCouplingFieldDiscretization::integral : input array is null !"); - int sz(arr->getNumberOfComponents()); - INTERP_KERNEL::AutoPtr tmp=new double[sz]; - self->integral(mesh,arr,isWAbs,tmp); - return convertDblArrToPyList(tmp,sz); - } - - virtual PyObject *getCellIdsHavingGaussLocalization(int locId) const throw(INTERP_KERNEL::Exception) - { - std::vector tmp; - self->getCellIdsHavingGaussLocalization(locId,tmp); - DataArrayInt *ret=DataArrayInt::New(); - ret->alloc((int)tmp.size(),1); - std::copy(tmp.begin(),tmp.end(),ret->getPointer()); - return SWIG_NewPointerObj(SWIG_as_voidptr(ret),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 ); - } - - virtual void setGaussLocalizationOnCells(const MEDCouplingMesh *m, PyObject *li, const std::vector& refCoo, - const std::vector& gsCoo, const std::vector& wg) throw(INTERP_KERNEL::Exception) - { - void *da=0; - int res1=SWIG_ConvertPtr(li,&da,SWIGTYPE_p_ParaMEDMEM__DataArrayInt, 0 | 0 ); - if (!SWIG_IsOK(res1)) - { - int size; - INTERP_KERNEL::AutoPtr tmp=convertPyToNewIntArr2(li,&size); - self->setGaussLocalizationOnCells(m,tmp,((int *)tmp)+size,refCoo,gsCoo,wg); - } - else - { - DataArrayInt *da2=reinterpret_cast< DataArrayInt * >(da); - if(!da2) - throw INTERP_KERNEL::Exception("Not null DataArrayInt instance expected !"); - da2->checkAllocated(); - self->setGaussLocalizationOnCells(m,da2->getConstPointer(),da2->getConstPointer()+da2->getNbOfElems(),refCoo,gsCoo,wg); - } - } - - virtual PyObject *getGaussLocalizationIdsOfOneType(INTERP_KERNEL::NormalizedCellType type) const throw(INTERP_KERNEL::Exception) - { - std::set ret=self->getGaussLocalizationIdsOfOneType(type); - return convertIntArrToPyList3(ret); - } - - virtual PyObject *getValueOn(const DataArrayDouble *arr, const MEDCouplingMesh *mesh, PyObject *sl) const throw(INTERP_KERNEL::Exception) - { - double val; - DataArrayDouble *a; - DataArrayDoubleTuple *aa; - std::vector bb; - int sw; - if(!mesh) - throw INTERP_KERNEL::Exception("Python wrap of MEDCouplingFieldDiscretization::getValueOn : no underlying mesh !"); - int spaceDim=mesh->getSpaceDimension(); - const char msg[]="Python wrap of MEDCouplingFieldDiscretization::getValueOn : "; - const double *spaceLoc=convertObjToPossibleCpp5_Safe(sl,sw,val,a,aa,bb,msg,1,spaceDim,true); - // - INTERP_KERNEL::AutoPtr res(new double[spaceDim]); - self->getValueOn(arr,mesh,spaceLoc,res); - return convertDblArrToPyList(res,spaceDim); - } - - virtual PyObject *getValueOnPos(const DataArrayDouble *arr, const MEDCouplingMesh *mesh, int i, int j, int k) const throw(INTERP_KERNEL::Exception) - { - if(!arr) - throw INTERP_KERNEL::Exception("wrap of MEDCouplingFieldDiscretization::getValueOnPos : input array is null !"); - int sz(arr->getNumberOfComponents()); - INTERP_KERNEL::AutoPtr res=new double[sz]; - self->getValueOnPos(arr,mesh,i,j,k,res); - return convertDblArrToPyList(res,sz); - } - - virtual DataArrayDouble *getValueOnMulti(const DataArrayDouble *arr, const MEDCouplingMesh *mesh, PyObject *loc) const throw(INTERP_KERNEL::Exception) - { - if(!mesh) - throw INTERP_KERNEL::Exception("Python wrap MEDCouplingFieldDiscretization::getValueOnMulti : null input mesh !"); - // - int sw,nbPts; - double v0; ParaMEDMEM::DataArrayDouble *v1(0); ParaMEDMEM::DataArrayDoubleTuple *v2(0); std::vector v3; - const double *inp=convertObjToPossibleCpp5_Safe2(loc,sw,v0,v1,v2,v3,"wrap of MEDCouplingFieldDouble::getValueOnMulti", - mesh->getSpaceDimension(),true,nbPts); - return self->getValueOnMulti(arr,mesh,inp,nbPts); - } - - virtual void renumberCells(PyObject *li, bool check=true) throw(INTERP_KERNEL::Exception) - { - int sw,sz(-1); - int v0; std::vector v1; - const int *ids(convertObjToPossibleCpp1_Safe(li,sw,sz,v0,v1)); - self->renumberCells(ids,check); - } - - virtual void renumberArraysForCell(const MEDCouplingMesh *mesh, PyObject *arrays, - PyObject *old2New, bool check) throw(INTERP_KERNEL::Exception) - { - std::vector input1; - convertFromPyObjVectorOfObj(arrays,SWIGTYPE_p_ParaMEDMEM__DataArray,"DataArray",input1); - // - int sw,sz(-1); - int v0; std::vector v1; - const int *old2NewBg(convertObjToPossibleCpp1_Safe(old2New,sw,sz,v0,v1)); - // - self->renumberArraysForCell(mesh,input1,old2NewBg,check); - } - - virtual DataArrayInt *computeTupleIdsToSelectFromCellIds(const MEDCouplingMesh *mesh, PyObject *cellIds) const throw(INTERP_KERNEL::Exception) - { - int sw,sz(-1); - int v0; std::vector v1; - const int *cellIdsBg(convertObjToPossibleCpp1_Safe(cellIds,sw,sz,v0,v1)); - return self->computeTupleIdsToSelectFromCellIds(mesh,cellIdsBg,cellIdsBg+sz); - } - - virtual PyObject *buildSubMeshData(const MEDCouplingMesh *mesh, PyObject *ids) const throw(INTERP_KERNEL::Exception) - { - int sw,sz(-1); - int v0; std::vector v1; - const int *idsBg(convertObjToPossibleCpp1_Safe(ids,sw,sz,v0,v1)); - DataArrayInt *di(0); - MEDCouplingMesh *ret0=self->buildSubMeshData(mesh,idsBg,idsBg+sz,di); - PyObject *ret=PyTuple_New(2); - PyTuple_SetItem(ret,0,convertMesh(ret0, SWIG_POINTER_OWN | 0 )); - PyTuple_SetItem(ret,1,SWIG_NewPointerObj(SWIG_as_voidptr(di),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 )); - return ret; - } - - virtual void renumberValuesOnNodes(double epsOnVals, PyObject *old2New, int newNbOfNodes, DataArrayDouble *arr) const throw(INTERP_KERNEL::Exception) - { - int sw,sz(-1); - int v0; std::vector v1; - const int *old2NewBg(convertObjToPossibleCpp1_Safe(old2New,sw,sz,v0,v1)); - self->renumberValuesOnNodes(epsOnVals,old2NewBg,newNbOfNodes,arr); - } - - virtual void renumberValuesOnCells(double epsOnVals, const MEDCouplingMesh *mesh, PyObject *old2New, int newSz, DataArrayDouble *arr) const throw(INTERP_KERNEL::Exception) - { - int sw,sz(-1); - int v0; std::vector v1; - const int *old2NewBg(convertObjToPossibleCpp1_Safe(old2New,sw,sz,v0,v1)); - self->renumberValuesOnCells(epsOnVals,mesh,old2NewBg,newSz,arr); - } - - virtual void renumberValuesOnCellsR(const MEDCouplingMesh *mesh, PyObject *new2old, int newSz, DataArrayDouble *arr) const throw(INTERP_KERNEL::Exception) - { - int sw,sz(-1); - int v0; std::vector v1; - const int *new2oldBg(convertObjToPossibleCpp1_Safe(new2old,sw,sz,v0,v1)); - self->renumberValuesOnCellsR(mesh,new2oldBg,newSz,arr); - } - } - }; - - class MEDCouplingFieldDiscretizationP0 : public MEDCouplingFieldDiscretization - { - }; - - class MEDCouplingFieldDiscretizationOnNodes : public MEDCouplingFieldDiscretization - { - }; - - class MEDCouplingFieldDiscretizationP1 : public MEDCouplingFieldDiscretizationOnNodes - { - }; - - class MEDCouplingFieldDiscretizationPerCell : public MEDCouplingFieldDiscretization - { - public: - void setArrayOfDiscIds(const DataArrayInt *adids) throw(INTERP_KERNEL::Exception); - void checkNoOrphanCells() const throw(INTERP_KERNEL::Exception); - %extend - { - PyObject *getArrayOfDiscIds() const - { - DataArrayInt *ret=const_cast(self->getArrayOfDiscIds()); - if(ret) - ret->incrRef(); - return SWIG_NewPointerObj(SWIG_as_voidptr(ret),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 ); - } - - PyObject *splitIntoSingleGaussDicrPerCellType() const throw(INTERP_KERNEL::Exception) - { - std::vector ret1; - std::vector ret0=self->splitIntoSingleGaussDicrPerCellType(ret1); - std::size_t sz=ret0.size(); - PyObject *pyRet=PyTuple_New(2); - PyObject *pyRet0=PyList_New((int)sz); - PyObject *pyRet1=PyList_New((int)sz); - for(std::size_t i=0;icomputeVectorOfCoefficients(mesh,arr,ret1); - PyObject *ret=PyTuple_New(2); - PyTuple_SetItem(ret,0,SWIG_NewPointerObj(SWIG_as_voidptr(ret0),SWIGTYPE_p_ParaMEDMEM__DataArrayDouble, SWIG_POINTER_OWN | 0 )); - PyTuple_SetItem(ret,1,PyInt_FromLong(ret1)); - return ret; - } - - PyObject *computeInverseMatrix(const MEDCouplingMesh *mesh) const throw(INTERP_KERNEL::Exception) - { - int ret1(-1),ret2(-1); - DataArrayDouble *ret0=self->computeInverseMatrix(mesh,ret1,ret2); - PyObject *ret=PyTuple_New(3); - PyTuple_SetItem(ret,0,SWIG_NewPointerObj(SWIG_as_voidptr(ret0),SWIGTYPE_p_ParaMEDMEM__DataArrayDouble, SWIG_POINTER_OWN | 0 )); - PyTuple_SetItem(ret,1,PyInt_FromLong(ret1)); - PyTuple_SetItem(ret,2,PyInt_FromLong(ret2)); - return ret; - } - - PyObject *computeMatrix(const MEDCouplingMesh *mesh) const throw(INTERP_KERNEL::Exception) - { - int ret1(-1),ret2(-1); - DataArrayDouble *ret0=self->computeMatrix(mesh,ret1,ret2); - PyObject *ret=PyTuple_New(3); - PyTuple_SetItem(ret,0,SWIG_NewPointerObj(SWIG_as_voidptr(ret0),SWIGTYPE_p_ParaMEDMEM__DataArrayDouble, SWIG_POINTER_OWN | 0 )); - PyTuple_SetItem(ret,1,PyInt_FromLong(ret1)); - PyTuple_SetItem(ret,2,PyInt_FromLong(ret2)); - return ret; - } - - PyObject *computeEvaluationMatrixOnGivenPts(const MEDCouplingMesh *mesh, PyObject *locs) const throw(INTERP_KERNEL::Exception) - { - if(!mesh) - throw INTERP_KERNEL::Exception("wrap of MEDCouplingFieldDiscretizationKriging::computeEvaluationMatrixOnGivenPts : input mesh is empty !"); - int sw,nbPts; - double v0; ParaMEDMEM::DataArrayDouble *v1(0); ParaMEDMEM::DataArrayDoubleTuple *v2(0); std::vector v3; - const double *inp=convertObjToPossibleCpp5_Safe2(locs,sw,v0,v1,v2,v3,"wrap of MEDCouplingFieldDiscretizationKriging::computeEvaluationMatrixOnGivenPts", - mesh->getSpaceDimension(),true,nbPts); - // - int ret1(-1); - DataArrayDouble *ret0=self->computeEvaluationMatrixOnGivenPts(mesh,inp,nbPts,ret1); - PyObject *ret=PyTuple_New(2); - PyTuple_SetItem(ret,0,SWIG_NewPointerObj(SWIG_as_voidptr(ret0),SWIGTYPE_p_ParaMEDMEM__DataArrayDouble, SWIG_POINTER_OWN | 0 )); - PyTuple_SetItem(ret,1,PyInt_FromLong(ret1)); - return ret; - } - - void operateOnDenseMatrix(int spaceDimension, DataArrayDouble *myMatrix) const throw(INTERP_KERNEL::Exception) - { - if(!myMatrix || !myMatrix->isAllocated() || myMatrix->getNumberOfComponents()!=1) - throw INTERP_KERNEL::Exception("Wrap of MEDCouplingFieldDiscretizationKriging::operateOnDenseMatrix : invalid input matrix as DataArrayDouble ! Must be allocated with one component !"); - self->operateOnDenseMatrix(spaceDimension,myMatrix->getNumberOfTuples(),myMatrix->getPointer()); - } - - PyObject *performDrift(const DataArrayDouble *matr, const DataArrayDouble *arr) const throw(INTERP_KERNEL::Exception) - { - int ret1(-1); - DataArrayDouble *ret0(self->performDrift(matr,arr,ret1)); - PyObject *res(PyTuple_New(2)); - PyTuple_SetItem(res,0,SWIG_NewPointerObj((void*)ret0,SWIGTYPE_p_ParaMEDMEM__DataArrayDouble,SWIG_POINTER_OWN | 0)); - PyTuple_SetItem(res,1,PyInt_FromLong(ret1)); - return res; - } - - static PyObject *PerformDriftRect(const DataArrayDouble *matr, const DataArrayDouble *arr) throw(INTERP_KERNEL::Exception) - { - int ret1(-1); - DataArrayDouble *ret0(MEDCouplingFieldDiscretizationKriging::PerformDriftRect(matr,arr,ret1)); - PyObject *res(PyTuple_New(2)); - PyTuple_SetItem(res,0,SWIG_NewPointerObj((void*)ret0,SWIGTYPE_p_ParaMEDMEM__DataArrayDouble,SWIG_POINTER_OWN | 0)); - PyTuple_SetItem(res,1,PyInt_FromLong(ret1)); - return res; - } - - static void OperateOnDenseMatrixH3(DataArrayDouble *myMatrix) throw(INTERP_KERNEL::Exception) - { - if(!myMatrix || !myMatrix->isAllocated() || myMatrix->getNumberOfComponents()!=1) - throw INTERP_KERNEL::Exception("Wrap of MEDCouplingFieldDiscretizationKriging::OperateOnDenseMatrixH3 : invalid input matrix as DataArrayDouble ! Must be allocated with one component !"); - MEDCouplingFieldDiscretizationKriging::OperateOnDenseMatrixH3(myMatrix->getNumberOfTuples(),myMatrix->getPointer()); - } - - static void OperateOnDenseMatrixH2Ln(DataArrayDouble *myMatrix) throw(INTERP_KERNEL::Exception) - { - if(!myMatrix || !myMatrix->isAllocated() || myMatrix->getNumberOfComponents()!=1) - throw INTERP_KERNEL::Exception("Wrap of MEDCouplingFieldDiscretizationKriging::OperateOnDenseMatrixH2Ln : invalid input matrix as DataArrayDouble ! Must be allocated with one component !"); - MEDCouplingFieldDiscretizationKriging::OperateOnDenseMatrixH2Ln(myMatrix->getNumberOfTuples(),myMatrix->getPointer()); - } - } - }; -} diff --git a/src/MEDCoupling_Swig/MEDCouplingFinalize.i b/src/MEDCoupling_Swig/MEDCouplingFinalize.i deleted file mode 100644 index 393dec9c8..000000000 --- a/src/MEDCoupling_Swig/MEDCouplingFinalize.i +++ /dev/null @@ -1,102 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 -// 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 -// - -%pythoncode %{ -InterpKernelException.__reduce__=INTERPKERNELExceptionReduce -DataArrayDouble.__new__=classmethod(ParaMEDMEMDataArrayDoublenew) -DataArrayDouble.__iadd__=ParaMEDMEMDataArrayDoubleIadd -DataArrayDouble.__isub__=ParaMEDMEMDataArrayDoubleIsub -DataArrayDouble.__imul__=ParaMEDMEMDataArrayDoubleImul -DataArrayDouble.__idiv__=ParaMEDMEMDataArrayDoubleIdiv -DataArrayDouble.__ipow__=ParaMEDMEMDataArrayDoubleIpow - -DataArrayInt.__new__=classmethod(ParaMEDMEMDataArrayIntnew) -DataArrayInt.__iadd__=ParaMEDMEMDataArrayIntIadd -DataArrayInt.__isub__=ParaMEDMEMDataArrayIntIsub -DataArrayInt.__imul__=ParaMEDMEMDataArrayIntImul -DataArrayInt.__idiv__=ParaMEDMEMDataArrayIntIdiv -DataArrayInt.__imod__=ParaMEDMEMDataArrayIntImod -DataArrayInt.__ipow__=ParaMEDMEMDataArrayIntIpow - -MEDCouplingFieldDouble.__iadd__=ParaMEDMEMMEDCouplingFieldDoubleIadd -MEDCouplingFieldDouble.__isub__=ParaMEDMEMMEDCouplingFieldDoubleIsub -MEDCouplingFieldDouble.__imul__=ParaMEDMEMMEDCouplingFieldDoubleImul -MEDCouplingFieldDouble.__idiv__=ParaMEDMEMMEDCouplingFieldDoubleIdiv -MEDCouplingFieldDouble.__ipow__=ParaMEDMEMMEDCouplingFieldDoubleIpow - -DataArrayDoubleTuple.__iadd__=ParaMEDMEMDataArrayDoubleTupleIadd -DataArrayDoubleTuple.__isub__=ParaMEDMEMDataArrayDoubleTupleIsub -DataArrayDoubleTuple.__imul__=ParaMEDMEMDataArrayDoubleTupleImul -DataArrayDoubleTuple.__idiv__=ParaMEDMEMDataArrayDoubleTupleIdiv - -DataArrayIntTuple.__iadd__=ParaMEDMEMDataArrayIntTupleIadd -DataArrayIntTuple.__isub__=ParaMEDMEMDataArrayIntTupleIsub -DataArrayIntTuple.__imul__=ParaMEDMEMDataArrayIntTupleImul -DataArrayIntTuple.__idiv__=ParaMEDMEMDataArrayIntTupleIdiv -DataArrayIntTuple.__imod__=ParaMEDMEMDataArrayIntTupleImod - -DenseMatrix.__iadd__=ParaMEDMEMDenseMatrixIadd -DenseMatrix.__isub__=ParaMEDMEMDenseMatrixIsub - -MEDCouplingUMesh.__new__=classmethod(ParaMEDMEMMEDCouplingUMeshnew) -MEDCoupling1DGTUMesh.__new__=classmethod(ParaMEDMEMMEDCoupling1DGTUMeshnew) -MEDCoupling1SGTUMesh.__new__=classmethod(ParaMEDMEMMEDCoupling1SGTUMeshnew) -MEDCouplingCurveLinearMesh.__new__=classmethod(ParaMEDMEMMEDCouplingCurveLinearMeshnew) -MEDCouplingCMesh.__new__=classmethod(ParaMEDMEMMEDCouplingCMeshnew) -MEDCouplingIMesh.__new__=classmethod(ParaMEDMEMMEDCouplingIMeshnew) -MEDCouplingExtrudedMesh.__new__=classmethod(ParaMEDMEMMEDCouplingExtrudedMeshnew) -MEDCouplingFieldDouble.__new__=classmethod(ParaMEDMEMMEDCouplingFieldDoublenew) - -del INTERPKERNELExceptionReduce -del ParaMEDMEMDataArrayDoublenew -del ParaMEDMEMDataArrayDoubleIadd -del ParaMEDMEMDataArrayDoubleIsub -del ParaMEDMEMDataArrayDoubleImul -del ParaMEDMEMDataArrayDoubleIdiv -del ParaMEDMEMMEDCouplingFieldDoubleIadd -del ParaMEDMEMMEDCouplingFieldDoubleIsub -del ParaMEDMEMMEDCouplingFieldDoubleImul -del ParaMEDMEMMEDCouplingFieldDoubleIdiv -del ParaMEDMEMMEDCouplingFieldDoubleIpow -del ParaMEDMEMDataArrayIntnew -del ParaMEDMEMDataArrayIntIadd -del ParaMEDMEMDataArrayIntIsub -del ParaMEDMEMDataArrayIntImul -del ParaMEDMEMDataArrayIntIdiv -del ParaMEDMEMDataArrayIntImod -del ParaMEDMEMDataArrayDoubleTupleIadd -del ParaMEDMEMDataArrayDoubleTupleIsub -del ParaMEDMEMDataArrayDoubleTupleImul -del ParaMEDMEMDataArrayDoubleTupleIdiv -del ParaMEDMEMDataArrayIntTupleIadd -del ParaMEDMEMDataArrayIntTupleIsub -del ParaMEDMEMDataArrayIntTupleImul -del ParaMEDMEMDataArrayIntTupleIdiv -del ParaMEDMEMDataArrayIntTupleImod -del ParaMEDMEMDenseMatrixIadd -del ParaMEDMEMDenseMatrixIsub -del ParaMEDMEMMEDCouplingUMeshnew -del ParaMEDMEMMEDCoupling1DGTUMeshnew -del ParaMEDMEMMEDCoupling1SGTUMeshnew -del ParaMEDMEMMEDCouplingCurveLinearMeshnew -del ParaMEDMEMMEDCouplingCMeshnew -del ParaMEDMEMMEDCouplingIMeshnew -del ParaMEDMEMMEDCouplingExtrudedMeshnew -del ParaMEDMEMMEDCouplingFieldDoublenew -%} diff --git a/src/MEDCoupling_Swig/MEDCouplingMemArray.i b/src/MEDCoupling_Swig/MEDCouplingMemArray.i deleted file mode 100644 index 3e4010867..000000000 --- a/src/MEDCoupling_Swig/MEDCouplingMemArray.i +++ /dev/null @@ -1,6160 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 -// 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) - -//////////////////// -%typemap(out) ParaMEDMEM::DataArray* -{ - $result=convertDataArray($1,$owner); -} - -%typemap(out) DataArray* -{ - $result=convertDataArray($1,$owner); -} -//$$$$$$$$$$$$$$$$$$ - -//////////////////// -%typemap(out) ParaMEDMEM::DataArrayChar* -{ - $result=convertDataArrayChar($1,$owner); -} - -%typemap(out) DataArrayChar* -{ - $result=convertDataArrayChar($1,$owner); -} -//$$$$$$$$$$$$$$$$$$ - -%newobject ParaMEDMEM::DataArray::deepCpy; -%newobject ParaMEDMEM::DataArray::selectByTupleRanges; -%newobject ParaMEDMEM::DataArray::selectByTupleId; -%newobject ParaMEDMEM::DataArray::selectByTupleIdSafe; -%newobject ParaMEDMEM::DataArray::selectByTupleId2; -%newobject ParaMEDMEM::DataArray::Aggregate; -%newobject ParaMEDMEM::DataArrayInt::New; -%newobject ParaMEDMEM::DataArrayInt::__iter__; -%newobject ParaMEDMEM::DataArrayInt::convertToDblArr; -%newobject ParaMEDMEM::DataArrayInt::performCpy; -%newobject ParaMEDMEM::DataArrayInt::substr; -%newobject ParaMEDMEM::DataArrayInt::changeNbOfComponents; -%newobject ParaMEDMEM::DataArrayInt::accumulatePerChunck; -%newobject ParaMEDMEM::DataArrayInt::checkAndPreparePermutation; -%newobject ParaMEDMEM::DataArrayInt::transformWithIndArrR; -%newobject ParaMEDMEM::DataArrayInt::renumber; -%newobject ParaMEDMEM::DataArrayInt::renumberR; -%newobject ParaMEDMEM::DataArrayInt::renumberAndReduce; -%newobject ParaMEDMEM::DataArrayInt::invertArrayO2N2N2O; -%newobject ParaMEDMEM::DataArrayInt::invertArrayN2O2O2N; -%newobject ParaMEDMEM::DataArrayInt::invertArrayO2N2N2OBis; -%newobject ParaMEDMEM::DataArrayInt::getIdsEqual; -%newobject ParaMEDMEM::DataArrayInt::getIdsNotEqual; -%newobject ParaMEDMEM::DataArrayInt::getIdsEqualList; -%newobject ParaMEDMEM::DataArrayInt::getIdsNotEqualList; -%newobject ParaMEDMEM::DataArrayInt::getIdsEqualTuple; -%newobject ParaMEDMEM::DataArrayInt::sumPerTuple; -%newobject ParaMEDMEM::DataArrayInt::negate; -%newobject ParaMEDMEM::DataArrayInt::computeAbs; -%newobject ParaMEDMEM::DataArrayInt::getIdsInRange; -%newobject ParaMEDMEM::DataArrayInt::getIdsNotInRange; -%newobject ParaMEDMEM::DataArrayInt::getIdsStrictlyNegative; -%newobject ParaMEDMEM::DataArrayInt::Aggregate; -%newobject ParaMEDMEM::DataArrayInt::AggregateIndexes; -%newobject ParaMEDMEM::DataArrayInt::Meld; -%newobject ParaMEDMEM::DataArrayInt::Add; -%newobject ParaMEDMEM::DataArrayInt::Substract; -%newobject ParaMEDMEM::DataArrayInt::Multiply; -%newobject ParaMEDMEM::DataArrayInt::Divide; -%newobject ParaMEDMEM::DataArrayInt::Pow; -%newobject ParaMEDMEM::DataArrayInt::BuildUnion; -%newobject ParaMEDMEM::DataArrayInt::BuildIntersection; -%newobject ParaMEDMEM::DataArrayInt::Range; -%newobject ParaMEDMEM::DataArrayInt::fromNoInterlace; -%newobject ParaMEDMEM::DataArrayInt::toNoInterlace; -%newobject ParaMEDMEM::DataArrayInt::buildComplement; -%newobject ParaMEDMEM::DataArrayInt::buildUnion; -%newobject ParaMEDMEM::DataArrayInt::buildSubstraction; -%newobject ParaMEDMEM::DataArrayInt::buildSubstractionOptimized; -%newobject ParaMEDMEM::DataArrayInt::buildIntersection; -%newobject ParaMEDMEM::DataArrayInt::buildUnique; -%newobject ParaMEDMEM::DataArrayInt::buildUniqueNotSorted; -%newobject ParaMEDMEM::DataArrayInt::deltaShiftIndex; -%newobject ParaMEDMEM::DataArrayInt::buildExplicitArrByRanges; -%newobject ParaMEDMEM::DataArrayInt::buildExplicitArrOfSliceOnScaledArr; -%newobject ParaMEDMEM::DataArrayInt::findRangeIdForEachTuple; -%newobject ParaMEDMEM::DataArrayInt::findIdInRangeForEachTuple; -%newobject ParaMEDMEM::DataArrayInt::duplicateEachTupleNTimes; -%newobject ParaMEDMEM::DataArrayInt::buildPermutationArr; -%newobject ParaMEDMEM::DataArrayInt::buildPermArrPerLevel; -%newobject ParaMEDMEM::DataArrayInt::getDifferentValues; -%newobject ParaMEDMEM::DataArrayInt::FindPermutationFromFirstToSecond; -%newobject ParaMEDMEM::DataArrayInt::CheckAndPreparePermutation; -%newobject ParaMEDMEM::DataArrayInt::__neg__; -%newobject ParaMEDMEM::DataArrayInt::__add__; -%newobject ParaMEDMEM::DataArrayInt::__radd__; -%newobject ParaMEDMEM::DataArrayInt::__sub__; -%newobject ParaMEDMEM::DataArrayInt::__rsub__; -%newobject ParaMEDMEM::DataArrayInt::__mul__; -%newobject ParaMEDMEM::DataArrayInt::__rmul__; -%newobject ParaMEDMEM::DataArrayInt::__div__; -%newobject ParaMEDMEM::DataArrayInt::__rdiv__; -%newobject ParaMEDMEM::DataArrayInt::__mod__; -%newobject ParaMEDMEM::DataArrayInt::__rmod__; -%newobject ParaMEDMEM::DataArrayInt::__pow__; -%newobject ParaMEDMEM::DataArrayInt::__rpow__; -%newobject ParaMEDMEM::DataArrayIntTuple::buildDAInt; -%newobject ParaMEDMEM::DataArrayChar::convertToIntArr; -%newobject ParaMEDMEM::DataArrayChar::renumber; -%newobject ParaMEDMEM::DataArrayChar::renumberR; -%newobject ParaMEDMEM::DataArrayChar::renumberAndReduce; -%newobject ParaMEDMEM::DataArrayChar::changeNbOfComponents; -%newobject ParaMEDMEM::DataArrayChar::getIdsEqual; -%newobject ParaMEDMEM::DataArrayChar::getIdsNotEqual; -%newobject ParaMEDMEM::DataArrayChar::Aggregate; -%newobject ParaMEDMEM::DataArrayChar::Meld; -%newobject ParaMEDMEM::DataArrayByte::New; -%newobject ParaMEDMEM::DataArrayByte::__iter__; -%newobject ParaMEDMEM::DataArrayByte::performCpy; -%newobject ParaMEDMEM::DataArrayByteTuple::buildDAByte; -%newobject ParaMEDMEM::DataArrayChar::substr; -%newobject ParaMEDMEM::DataArrayAsciiChar::New; -%newobject ParaMEDMEM::DataArrayAsciiChar::__iter__; -%newobject ParaMEDMEM::DataArrayAsciiChar::performCpy; -%newobject ParaMEDMEM::DataArrayAsciiCharTuple::buildDAAsciiChar; -%newobject ParaMEDMEM::DataArrayDouble::New; -%newobject ParaMEDMEM::DataArrayDouble::__iter__; -%newobject ParaMEDMEM::DataArrayDouble::convertToIntArr; -%newobject ParaMEDMEM::DataArrayDouble::performCpy; -%newobject ParaMEDMEM::DataArrayDouble::Aggregate; -%newobject ParaMEDMEM::DataArrayDouble::Meld; -%newobject ParaMEDMEM::DataArrayDouble::Dot; -%newobject ParaMEDMEM::DataArrayDouble::CrossProduct; -%newobject ParaMEDMEM::DataArrayDouble::Add; -%newobject ParaMEDMEM::DataArrayDouble::Substract; -%newobject ParaMEDMEM::DataArrayDouble::Multiply; -%newobject ParaMEDMEM::DataArrayDouble::Divide; -%newobject ParaMEDMEM::DataArrayDouble::Pow; -%newobject ParaMEDMEM::DataArrayDouble::substr; -%newobject ParaMEDMEM::DataArrayDouble::changeNbOfComponents; -%newobject ParaMEDMEM::DataArrayDouble::accumulatePerChunck; -%newobject ParaMEDMEM::DataArrayDouble::getIdsInRange; -%newobject ParaMEDMEM::DataArrayDouble::getIdsNotInRange; -%newobject ParaMEDMEM::DataArrayDouble::negate; -%newobject ParaMEDMEM::DataArrayDouble::computeAbs; -%newobject ParaMEDMEM::DataArrayDouble::applyFunc; -%newobject ParaMEDMEM::DataArrayDouble::applyFunc2; -%newobject ParaMEDMEM::DataArrayDouble::applyFunc3; -%newobject ParaMEDMEM::DataArrayDouble::doublyContractedProduct; -%newobject ParaMEDMEM::DataArrayDouble::determinant; -%newobject ParaMEDMEM::DataArrayDouble::eigenValues; -%newobject ParaMEDMEM::DataArrayDouble::eigenVectors; -%newobject ParaMEDMEM::DataArrayDouble::inverse; -%newobject ParaMEDMEM::DataArrayDouble::trace; -%newobject ParaMEDMEM::DataArrayDouble::deviator; -%newobject ParaMEDMEM::DataArrayDouble::magnitude; -%newobject ParaMEDMEM::DataArrayDouble::maxPerTuple; -%newobject ParaMEDMEM::DataArrayDouble::sumPerTuple; -%newobject ParaMEDMEM::DataArrayDouble::computeBBoxPerTuple; -%newobject ParaMEDMEM::DataArrayDouble::buildEuclidianDistanceDenseMatrix; -%newobject ParaMEDMEM::DataArrayDouble::buildEuclidianDistanceDenseMatrixWith; -%newobject ParaMEDMEM::DataArrayDouble::renumber; -%newobject ParaMEDMEM::DataArrayDouble::renumberR; -%newobject ParaMEDMEM::DataArrayDouble::renumberAndReduce; -%newobject ParaMEDMEM::DataArrayDouble::fromNoInterlace; -%newobject ParaMEDMEM::DataArrayDouble::toNoInterlace; -%newobject ParaMEDMEM::DataArrayDouble::fromPolarToCart; -%newobject ParaMEDMEM::DataArrayDouble::fromCylToCart; -%newobject ParaMEDMEM::DataArrayDouble::fromSpherToCart; -%newobject ParaMEDMEM::DataArrayDouble::getDifferentValues; -%newobject ParaMEDMEM::DataArrayDouble::findClosestTupleId; -%newobject ParaMEDMEM::DataArrayDouble::computeNbOfInteractionsWith; -%newobject ParaMEDMEM::DataArrayDouble::duplicateEachTupleNTimes; -%newobject ParaMEDMEM::DataArrayDouble::__neg__; -%newobject ParaMEDMEM::DataArrayDouble::__radd__; -%newobject ParaMEDMEM::DataArrayDouble::__rsub__; -%newobject ParaMEDMEM::DataArrayDouble::__rmul__; -%newobject ParaMEDMEM::DataArrayDouble::__rdiv__; -%newobject ParaMEDMEM::DataArrayDouble::__pow__; -%newobject ParaMEDMEM::DataArrayDouble::__rpow__; -%newobject ParaMEDMEM::DataArrayDoubleTuple::buildDADouble; - -%feature("unref") DataArray "$this->decrRef();" -%feature("unref") DataArrayDouble "$this->decrRef();" -%feature("unref") DataArrayInt "$this->decrRef();" -%feature("unref") DataArrayChar "$this->decrRef();" -%feature("unref") DataArrayAsciiChar "$this->decrRef();" -%feature("unref") DataArrayByte "$this->decrRef();" - -namespace ParaMEDMEM -{ - class DataArray : public RefCountObject, public TimeLabel - { - public: - void setName(const std::string& name); - void copyStringInfoFrom(const DataArray& other) throw(INTERP_KERNEL::Exception); - void copyPartOfStringInfoFrom(const DataArray& other, const std::vector& compoIds) throw(INTERP_KERNEL::Exception); - void copyPartOfStringInfoFrom2(const std::vector& compoIds, const DataArray& other) throw(INTERP_KERNEL::Exception); - bool areInfoEqualsIfNotWhy(const DataArray& other, std::string& reason) const throw(INTERP_KERNEL::Exception); - bool areInfoEquals(const DataArray& other) const throw(INTERP_KERNEL::Exception); - std::string cppRepr(const std::string& varName) const throw(INTERP_KERNEL::Exception); - std::string getName() const; - void setInfoOnComponents(const std::vector& info) throw(INTERP_KERNEL::Exception); - void setInfoAndChangeNbOfCompo(const std::vector& info) throw(INTERP_KERNEL::Exception); - std::vector getVarsOnComponent() const throw(INTERP_KERNEL::Exception); - std::vector getUnitsOnComponent() const throw(INTERP_KERNEL::Exception); - std::string getInfoOnComponent(int i) const throw(INTERP_KERNEL::Exception); - std::string getVarOnComponent(int i) const throw(INTERP_KERNEL::Exception); - std::string getUnitOnComponent(int i) const throw(INTERP_KERNEL::Exception); - void setInfoOnComponent(int i, const std::string& info) throw(INTERP_KERNEL::Exception); - int getNumberOfComponents() const; - virtual void alloc(int nbOfTuple, int nbOfCompo=1) throw(INTERP_KERNEL::Exception); - virtual void reAlloc(int nbOfTuples) throw(INTERP_KERNEL::Exception); - virtual bool isAllocated() const throw(INTERP_KERNEL::Exception); - virtual void checkAllocated() const throw(INTERP_KERNEL::Exception); - virtual void desallocate() throw(INTERP_KERNEL::Exception); - virtual int getNumberOfTuples() const throw(INTERP_KERNEL::Exception); - virtual std::size_t getNbOfElems() const throw(INTERP_KERNEL::Exception); - virtual std::size_t getNbOfElemAllocated() const throw(INTERP_KERNEL::Exception); - virtual DataArray *deepCpy() const throw(INTERP_KERNEL::Exception); - virtual DataArray *selectByTupleId2(int bg, int end2, int step) const throw(INTERP_KERNEL::Exception); - virtual void rearrange(int newNbOfCompo) throw(INTERP_KERNEL::Exception); - void checkNbOfTuples(int nbOfTuples, const std::string& msg) const throw(INTERP_KERNEL::Exception); - void checkNbOfComps(int nbOfCompo, const std::string& msg) const throw(INTERP_KERNEL::Exception); - void checkNbOfTuplesAndComp(const DataArray& other, const std::string& msg) const throw(INTERP_KERNEL::Exception); - void checkNbOfTuplesAndComp(int nbOfTuples, int nbOfCompo, const std::string& msg) const throw(INTERP_KERNEL::Exception); - void checkNbOfElems(std::size_t nbOfElems, const std::string& msg) const throw(INTERP_KERNEL::Exception); - static int GetNumberOfItemGivenBES(int begin, int end, int step, const std::string& msg) throw(INTERP_KERNEL::Exception); - static int GetNumberOfItemGivenBESRelative(int begin, int end, int step, const std::string& msg) throw(INTERP_KERNEL::Exception); - static int GetPosOfItemGivenBESRelativeNoThrow(int value, int begin, int end, int step) throw(INTERP_KERNEL::Exception); - static std::string GetVarNameFromInfo(const std::string& info) throw(INTERP_KERNEL::Exception); - static std::string GetUnitFromInfo(const std::string& info) throw(INTERP_KERNEL::Exception); - static std::string BuildInfoFromVarAndUnit(const std::string& var, const std::string& unit) throw(INTERP_KERNEL::Exception); - void updateTime() const; - %extend - { - PyObject *getInfoOnComponents() const throw(INTERP_KERNEL::Exception) - { - const std::vector& comps=self->getInfoOnComponents(); - PyObject *ret=PyList_New((int)comps.size()); - for(int i=0;i<(int)comps.size();i++) - PyList_SetItem(ret,i,PyString_FromString(comps[i].c_str())); - return ret; - } - - void copyPartOfStringInfoFrom(const DataArray& other, PyObject *li) throw(INTERP_KERNEL::Exception) - { - std::vector tmp; - convertPyToNewIntArr3(li,tmp); - self->copyPartOfStringInfoFrom(other,tmp); - } - - void copyPartOfStringInfoFrom2(PyObject *li, const DataArray& other) throw(INTERP_KERNEL::Exception) - { - std::vector tmp; - convertPyToNewIntArr3(li,tmp); - self->copyPartOfStringInfoFrom2(tmp,other); - } - - virtual void renumberInPlace(PyObject *li) throw(INTERP_KERNEL::Exception) - { - void *da=0; - int res1=SWIG_ConvertPtr(li,&da,SWIGTYPE_p_ParaMEDMEM__DataArrayInt, 0 | 0 ); - if (!SWIG_IsOK(res1)) - { - int size; - INTERP_KERNEL::AutoPtr tmp=convertPyToNewIntArr2(li,&size); - if(size!=self->getNumberOfTuples()) - { - throw INTERP_KERNEL::Exception("Invalid list length ! Must be equal to number of tuples !"); - } - self->renumberInPlace(tmp); - } - else - { - DataArrayInt *da2=reinterpret_cast< DataArrayInt * >(da); - if(!da2) - throw INTERP_KERNEL::Exception("Not null DataArrayInt instance expected !"); - da2->checkAllocated(); - int size=self->getNumberOfTuples(); - if(size!=self->getNumberOfTuples()) - { - throw INTERP_KERNEL::Exception("Invalid list length ! Must be equal to number of tuples !"); - } - self->renumberInPlace(da2->getConstPointer()); - } - } - - virtual void renumberInPlaceR(PyObject *li) throw(INTERP_KERNEL::Exception) - { - void *da=0; - int res1=SWIG_ConvertPtr(li,&da,SWIGTYPE_p_ParaMEDMEM__DataArrayInt, 0 | 0 ); - if (!SWIG_IsOK(res1)) - { - int size; - INTERP_KERNEL::AutoPtr tmp=convertPyToNewIntArr2(li,&size); - if(size!=self->getNumberOfTuples()) - { - throw INTERP_KERNEL::Exception("Invalid list length ! Must be equal to number of tuples !"); - } - self->renumberInPlaceR(tmp); - } - else - { - DataArrayInt *da2=reinterpret_cast< DataArrayInt * >(da); - if(!da2) - throw INTERP_KERNEL::Exception("Not null DataArrayInt instance expected !"); - da2->checkAllocated(); - int size=self->getNumberOfTuples(); - if(size!=self->getNumberOfTuples()) - { - throw INTERP_KERNEL::Exception("Invalid list length ! Must be equal to number of tuples !"); - } - self->renumberInPlaceR(da2->getConstPointer()); - } - } - - //tuplesSelec in PyObject * because DataArrayInt is not already existing ! - virtual void setContigPartOfSelectedValues(int tupleIdStart, PyObject *aBase, PyObject *tuplesSelec) throw(INTERP_KERNEL::Exception) - { - static const char msg[]="DataArray::setContigPartOfSelectedValues2 : 4th parameter \"tuplesSelec\" should be of type DataArrayInt"; - DataArray *a=CheckAndRetrieveDataArrayInstance(aBase,"DataArray::setContigPartOfSelectedValues2 : 3rd parameter \"aBase\" should be of type DataArray"); - DataArray *tuplesSelecPtr=CheckAndRetrieveDataArrayInstance(tuplesSelec,msg); - DataArrayInt *tuplesSelecPtr2=0; - if(tuplesSelecPtr) - { - tuplesSelecPtr2=dynamic_cast(tuplesSelecPtr); - if(!tuplesSelecPtr2) - throw INTERP_KERNEL::Exception(msg); - } - self->setContigPartOfSelectedValues(tupleIdStart,a,tuplesSelecPtr2); - } - - virtual void setContigPartOfSelectedValues2(int tupleIdStart, PyObject *aBase, int bg, int end2, int step) throw(INTERP_KERNEL::Exception) - { - DataArray *a=CheckAndRetrieveDataArrayInstance(aBase,"DataArray::setContigPartOfSelectedValues2 : 2nd parameter \"aBase\" should be of type DataArray"); - self->setContigPartOfSelectedValues2(tupleIdStart,a,bg,end2,step); - } - - virtual DataArray *selectByTupleRanges(PyObject *li) const throw(INTERP_KERNEL::Exception) - { - std::vector > ranges; - convertPyToVectorPairInt(li,ranges); - return self->selectByTupleRanges(ranges); - } - - virtual DataArray *selectByTupleId(PyObject *li) const throw(INTERP_KERNEL::Exception) - { - void *da=0; - int res1=SWIG_ConvertPtr(li,&da,SWIGTYPE_p_ParaMEDMEM__DataArrayInt, 0 | 0 ); - if (!SWIG_IsOK(res1)) - { - int size; - INTERP_KERNEL::AutoPtr tmp=convertPyToNewIntArr2(li,&size); - return self->selectByTupleId(tmp,tmp+size); - } - else - { - DataArrayInt *da2=reinterpret_cast< DataArrayInt * >(da); - if(!da2) - throw INTERP_KERNEL::Exception("Not null DataArrayInt instance expected !"); - da2->checkAllocated(); - return self->selectByTupleId(da2->getConstPointer(),da2->getConstPointer()+da2->getNbOfElems()); - } - } - - virtual DataArray *selectByTupleIdSafe(PyObject *li) const throw(INTERP_KERNEL::Exception) - { - void *da=0; - int res1=SWIG_ConvertPtr(li,&da,SWIGTYPE_p_ParaMEDMEM__DataArrayInt, 0 | 0 ); - if (!SWIG_IsOK(res1)) - { - int size; - INTERP_KERNEL::AutoPtr tmp=convertPyToNewIntArr2(li,&size); - return self->selectByTupleIdSafe(tmp,tmp+size); - } - else - { - DataArrayInt *da2=reinterpret_cast< DataArrayInt * >(da); - if(!da2) - throw INTERP_KERNEL::Exception("Not null DataArrayInt instance expected !"); - da2->checkAllocated(); - return self->selectByTupleIdSafe(da2->getConstPointer(),da2->getConstPointer()+da2->getNbOfElems()); - } - } - - virtual PyObject *keepSelectedComponents(PyObject *li) const throw(INTERP_KERNEL::Exception) - { - std::vector tmp; - convertPyToNewIntArr3(li,tmp); - DataArray *ret=self->keepSelectedComponents(tmp); - return convertDataArray(ret,SWIG_POINTER_OWN | 0 ); - } - - static PyObject *GetSlice(PyObject *slic, int sliceId, int nbOfSlices) throw(INTERP_KERNEL::Exception) - { - if(!PySlice_Check(slic)) - throw INTERP_KERNEL::Exception("DataArray::GetSlice (wrap) : expecting a pyslice as second (first) parameter !"); - Py_ssize_t strt=2,stp=2,step=2; - PySliceObject *sly=reinterpret_cast(slic); - GetIndicesOfSliceExplicitely(sly,&strt,&stp,&step,"DataArray::GetSlice (wrap) : the input slice is invalid !"); - int a,b; - DataArray::GetSlice(strt,stp,step,sliceId,nbOfSlices,a,b); - return PySlice_New(PyInt_FromLong(a),PyInt_FromLong(b),PyInt_FromLong(step)); - } - - PyObject *getSlice(PyObject *slic, int sliceId, int nbOfSlices) const throw(INTERP_KERNEL::Exception) - { - if(!PySlice_Check(slic)) - throw INTERP_KERNEL::Exception("DataArray::getSlice (wrap) : expecting a pyslice as second (first) parameter !"); - Py_ssize_t strt=2,stp=2,step=2; - PySliceObject *sly=reinterpret_cast(slic); - GetIndicesOfSlice(sly,self->getNumberOfTuples(),&strt,&stp,&step,"DataArray::getSlice (wrap) : the input slice is invalid !"); - int a,b; - DataArray::GetSlice(strt,stp,step,sliceId,nbOfSlices,a,b); - return PySlice_New(PyInt_FromLong(a),PyInt_FromLong(b),PyInt_FromLong(step)); - } - - static int GetNumberOfItemGivenBES(PyObject *slic) throw(INTERP_KERNEL::Exception) - { - if(!PySlice_Check(slic)) - throw INTERP_KERNEL::Exception("DataArray::GetNumberOfItemGivenBES (wrap) : expecting a pyslice as second (first) parameter !"); - Py_ssize_t strt=2,stp=2,step=2; - PySliceObject *sly=reinterpret_cast(slic); - GetIndicesOfSliceExplicitely(sly,&strt,&stp,&step,"DataArray::GetNumberOfItemGivenBES (wrap) : the input slice is invalid !"); - return DataArray::GetNumberOfItemGivenBES(strt,stp,step,""); - } - - static int GetNumberOfItemGivenBESRelative(PyObject *slic) throw(INTERP_KERNEL::Exception) - { - if(!PySlice_Check(slic)) - throw INTERP_KERNEL::Exception("DataArray::GetNumberOfItemGivenBESRelative (wrap) : expecting a pyslice as second (first) parameter !"); - Py_ssize_t strt=2,stp=2,step=2; - PySliceObject *sly=reinterpret_cast(slic); - GetIndicesOfSliceExplicitely(sly,&strt,&stp,&step,"DataArray::GetNumberOfItemGivenBESRelative (wrap) : the input slice is invalid !"); - return DataArray::GetNumberOfItemGivenBESRelative(strt,stp,step,""); - } - - static DataArray *Aggregate(PyObject *arrs) throw(INTERP_KERNEL::Exception) - { - std::vector tmp; - convertFromPyObjVectorOfObj(arrs,SWIGTYPE_p_ParaMEDMEM__DataArray,"DataArray",tmp); - return DataArray::Aggregate(tmp); - } - - int getNumberOfItemGivenBES(PyObject *slic) const throw(INTERP_KERNEL::Exception) - { - if(!PySlice_Check(slic)) - throw INTERP_KERNEL::Exception("DataArray::getNumberOfItemGivenBES (wrap) : expecting a pyslice as second (first) parameter !"); - Py_ssize_t strt=2,stp=2,step=2; - PySliceObject *sly=reinterpret_cast(slic); - GetIndicesOfSlice(sly,self->getNumberOfTuples(),&strt,&stp,&step,"DataArray::getNumberOfItemGivenBES (wrap) : the input slice is invalid !"); - return DataArray::GetNumberOfItemGivenBES(strt,stp,step,""); - } - - int getNumberOfItemGivenBESRelative(PyObject *slic) throw(INTERP_KERNEL::Exception) - { - if(!PySlice_Check(slic)) - throw INTERP_KERNEL::Exception("DataArray::getNumberOfItemGivenBESRelative (wrap) : expecting a pyslice as second (first) parameter !"); - Py_ssize_t strt=2,stp=2,step=2; - PySliceObject *sly=reinterpret_cast(slic); - GetIndicesOfSlice(sly,self->getNumberOfTuples(),&strt,&stp,&step,"DataArray::getNumberOfItemGivenBESRelative (wrap) : the input slice is invalid !"); - return DataArray::GetNumberOfItemGivenBESRelative(strt,stp,step,""); - } - - PyObject *__getstate__() const throw(INTERP_KERNEL::Exception) - { - PyObject *ret(PyTuple_New(2)); - std::string a0(self->getName()); - const std::vector &a1(self->getInfoOnComponents()); - PyTuple_SetItem(ret,0,PyString_FromString(a0.c_str())); - // - int sz(a1.size()); - PyObject *ret1(PyList_New(sz)); - for(int i=0;i a1cpp; - if(!fillStringVector(a1,a1cpp)) - throw INTERP_KERNEL::Exception(MSG); - self->setName(PyString_AsString(a0)); - self->setInfoOnComponents(a1cpp); - } - } - }; - - class DataArrayInt; - class DataArrayDoubleIterator; - - class DataArrayDouble : public DataArray - { - public: - static DataArrayDouble *New(); - double doubleValue() const throw(INTERP_KERNEL::Exception); - bool empty() const throw(INTERP_KERNEL::Exception); - DataArrayDouble *performCpy(bool deepCpy) const throw(INTERP_KERNEL::Exception); - void cpyFrom(const DataArrayDouble& other) throw(INTERP_KERNEL::Exception); - void reserve(std::size_t nbOfElems) throw(INTERP_KERNEL::Exception); - void pushBackSilent(double val) throw(INTERP_KERNEL::Exception); - double popBackSilent() throw(INTERP_KERNEL::Exception); - void pack() const throw(INTERP_KERNEL::Exception); - void allocIfNecessary(int nbOfTuple, int nbOfCompo) throw(INTERP_KERNEL::Exception); - void fillWithZero() throw(INTERP_KERNEL::Exception); - void fillWithValue(double val) throw(INTERP_KERNEL::Exception); - void iota(double init=0.) throw(INTERP_KERNEL::Exception); - bool isUniform(double val, double eps) const throw(INTERP_KERNEL::Exception); - void sort(bool asc=true) throw(INTERP_KERNEL::Exception); - void reverse() throw(INTERP_KERNEL::Exception); - void checkMonotonic(bool increasing, double eps) const throw(INTERP_KERNEL::Exception); - bool isMonotonic(bool increasing, double eps) const throw(INTERP_KERNEL::Exception); - std::string repr() const throw(INTERP_KERNEL::Exception); - std::string reprZip() const throw(INTERP_KERNEL::Exception); - std::string reprNotTooLong() const throw(INTERP_KERNEL::Exception); - bool isEqual(const DataArrayDouble& other, double prec) const throw(INTERP_KERNEL::Exception); - bool isEqualWithoutConsideringStr(const DataArrayDouble& other, double prec) const throw(INTERP_KERNEL::Exception); - DataArrayInt *convertToIntArr() const throw(INTERP_KERNEL::Exception); - DataArrayDouble *fromNoInterlace() const throw(INTERP_KERNEL::Exception); - DataArrayDouble *toNoInterlace() const throw(INTERP_KERNEL::Exception); - DataArrayDouble *substr(int tupleIdBg, int tupleIdEnd=-1) const throw(INTERP_KERNEL::Exception); - void transpose() throw(INTERP_KERNEL::Exception); - DataArrayDouble *changeNbOfComponents(int newNbOfComp, double dftValue) const throw(INTERP_KERNEL::Exception); - void meldWith(const DataArrayDouble *other) throw(INTERP_KERNEL::Exception); - DataArrayDouble *duplicateEachTupleNTimes(int nbTimes) const throw(INTERP_KERNEL::Exception); - DataArrayDouble *getDifferentValues(double prec, int limitTupleId=-1) const throw(INTERP_KERNEL::Exception); - DataArrayInt *findClosestTupleId(const DataArrayDouble *other) const throw(INTERP_KERNEL::Exception); - DataArrayInt *computeNbOfInteractionsWith(const DataArrayDouble *otherBBoxFrmt, double eps) const throw(INTERP_KERNEL::Exception); - void setPartOfValues1(const DataArrayDouble *a, int bgTuples, int endTuples, int stepTuples, int bgComp, int endComp, int stepComp, bool strictCompoCompare=true) throw(INTERP_KERNEL::Exception); - void setPartOfValuesSimple1(double a, int bgTuples, int endTuples, int stepTuples, int bgComp, int endComp, int stepComp) throw(INTERP_KERNEL::Exception); - void setPartOfValuesAdv(const DataArrayDouble *a, const DataArrayInt *tuplesSelec) throw(INTERP_KERNEL::Exception); - double getIJ(int tupleId, int compoId) const throw(INTERP_KERNEL::Exception); - double front() const throw(INTERP_KERNEL::Exception); - double back() const throw(INTERP_KERNEL::Exception); - double getIJSafe(int tupleId, int compoId) const throw(INTERP_KERNEL::Exception); - void setIJ(int tupleId, int compoId, double newVal) throw(INTERP_KERNEL::Exception); - void setIJSilent(int tupleId, int compoId, double newVal) throw(INTERP_KERNEL::Exception); - double *getPointer() throw(INTERP_KERNEL::Exception); - void checkNoNullValues() const throw(INTERP_KERNEL::Exception); - DataArrayDouble *computeBBoxPerTuple(double epsilon=0.0) const throw(INTERP_KERNEL::Exception); - void recenterForMaxPrecision(double eps) throw(INTERP_KERNEL::Exception); - double getMaxValue(int& tupleId) const throw(INTERP_KERNEL::Exception); - double getMaxValueInArray() const throw(INTERP_KERNEL::Exception); - double getMinValue(int& tupleId) const throw(INTERP_KERNEL::Exception); - double getMinValueInArray() const throw(INTERP_KERNEL::Exception); - int count(double value, double eps) const throw(INTERP_KERNEL::Exception); - double getAverageValue() const throw(INTERP_KERNEL::Exception); - double norm2() const throw(INTERP_KERNEL::Exception); - double normMax() const throw(INTERP_KERNEL::Exception); - double normMin() const throw(INTERP_KERNEL::Exception); - double accumulate(int compId) const throw(INTERP_KERNEL::Exception); - DataArrayDouble *fromPolarToCart() const throw(INTERP_KERNEL::Exception); - DataArrayDouble *fromCylToCart() const throw(INTERP_KERNEL::Exception); - DataArrayDouble *fromSpherToCart() const throw(INTERP_KERNEL::Exception); - DataArrayDouble *doublyContractedProduct() const throw(INTERP_KERNEL::Exception); - DataArrayDouble *determinant() const throw(INTERP_KERNEL::Exception); - DataArrayDouble *eigenValues() const throw(INTERP_KERNEL::Exception); - DataArrayDouble *eigenVectors() const throw(INTERP_KERNEL::Exception); - DataArrayDouble *inverse() const throw(INTERP_KERNEL::Exception); - DataArrayDouble *trace() const throw(INTERP_KERNEL::Exception); - DataArrayDouble *deviator() const throw(INTERP_KERNEL::Exception); - DataArrayDouble *magnitude() const throw(INTERP_KERNEL::Exception); - DataArrayDouble *maxPerTuple() const throw(INTERP_KERNEL::Exception); - DataArrayDouble *sumPerTuple() const throw(INTERP_KERNEL::Exception); - DataArrayDouble *buildEuclidianDistanceDenseMatrix() const throw(INTERP_KERNEL::Exception); - DataArrayDouble *buildEuclidianDistanceDenseMatrixWith(const DataArrayDouble *other) const throw(INTERP_KERNEL::Exception); - void sortPerTuple(bool asc) throw(INTERP_KERNEL::Exception); - void abs() throw(INTERP_KERNEL::Exception); - DataArrayDouble *computeAbs() const throw(INTERP_KERNEL::Exception); - void applyLin(double a, double b, int compoId) throw(INTERP_KERNEL::Exception); - void applyLin(double a, double b) throw(INTERP_KERNEL::Exception); - void applyInv(double numerator) throw(INTERP_KERNEL::Exception); - void applyPow(double val) throw(INTERP_KERNEL::Exception); - void applyRPow(double val) throw(INTERP_KERNEL::Exception); - DataArrayDouble *negate() const throw(INTERP_KERNEL::Exception); - DataArrayDouble *applyFunc(int nbOfComp, FunctionToEvaluate func) const throw(INTERP_KERNEL::Exception); - DataArrayDouble *applyFunc(int nbOfComp, const std::string& func, bool isSafe=true) const throw(INTERP_KERNEL::Exception); - DataArrayDouble *applyFunc(const std::string& func, bool isSafe=true) const throw(INTERP_KERNEL::Exception); - void applyFuncOnThis(const std::string& func, bool isSafe=true) throw(INTERP_KERNEL::Exception); - DataArrayDouble *applyFunc2(int nbOfComp, const std::string& func, bool isSafe=true) const throw(INTERP_KERNEL::Exception); - DataArrayDouble *applyFunc3(int nbOfComp, const std::vector& varsOrder, const std::string& func, bool isSafe=true) const throw(INTERP_KERNEL::Exception); - void applyFuncFast32(const std::string& func) throw(INTERP_KERNEL::Exception); - void applyFuncFast64(const std::string& func) throw(INTERP_KERNEL::Exception); - DataArrayInt *getIdsInRange(double vmin, double vmax) const throw(INTERP_KERNEL::Exception); - DataArrayInt *getIdsNotInRange(double vmin, double vmax) const throw(INTERP_KERNEL::Exception); - static DataArrayDouble *Aggregate(const DataArrayDouble *a1, const DataArrayDouble *a2) throw(INTERP_KERNEL::Exception); - static DataArrayDouble *Meld(const DataArrayDouble *a1, const DataArrayDouble *a2) throw(INTERP_KERNEL::Exception); - static DataArrayDouble *Dot(const DataArrayDouble *a1, const DataArrayDouble *a2) throw(INTERP_KERNEL::Exception); - static DataArrayDouble *CrossProduct(const DataArrayDouble *a1, const DataArrayDouble *a2) throw(INTERP_KERNEL::Exception); - static DataArrayDouble *Max(const DataArrayDouble *a1, const DataArrayDouble *a2) throw(INTERP_KERNEL::Exception); - static DataArrayDouble *Min(const DataArrayDouble *a1, const DataArrayDouble *a2) throw(INTERP_KERNEL::Exception); - static DataArrayDouble *Add(const DataArrayDouble *a1, const DataArrayDouble *a2) throw(INTERP_KERNEL::Exception); - void addEqual(const DataArrayDouble *other) throw(INTERP_KERNEL::Exception); - static DataArrayDouble *Substract(const DataArrayDouble *a1, const DataArrayDouble *a2) throw(INTERP_KERNEL::Exception); - void substractEqual(const DataArrayDouble *other) throw(INTERP_KERNEL::Exception); - static DataArrayDouble *Multiply(const DataArrayDouble *a1, const DataArrayDouble *a2) throw(INTERP_KERNEL::Exception); - void multiplyEqual(const DataArrayDouble *other) throw(INTERP_KERNEL::Exception); - static DataArrayDouble *Divide(const DataArrayDouble *a1, const DataArrayDouble *a2) throw(INTERP_KERNEL::Exception); - void divideEqual(const DataArrayDouble *other) throw(INTERP_KERNEL::Exception); - static DataArrayDouble *Pow(const DataArrayDouble *a1, const DataArrayDouble *a2) throw(INTERP_KERNEL::Exception); - void powEqual(const DataArrayDouble *other) throw(INTERP_KERNEL::Exception); - %extend - { - DataArrayDouble() throw(INTERP_KERNEL::Exception) - { - return DataArrayDouble::New(); - } - - static DataArrayDouble *New(PyObject *elt0, PyObject *nbOfTuples=0, PyObject *elt2=0) throw(INTERP_KERNEL::Exception) - { - const char *msgBase="ParaMEDMEM::DataArrayDouble::New : Available API are : \n-DataArrayDouble.New()\n-DataArrayDouble.New([1.,3.,4.])\n-DataArrayDouble.New([1.,3.,4.],3)\n-DataArrayDouble.New([1.,3.,4.,5.],2,2)\n-DataArrayDouble.New([1.,3.,4.,5.,7,8.],3,2)\n-DataArrayDouble.New([(1.,3.),(4.,5.),(7,8.)])\n-DataArrayDouble.New(5)\n-DataArrayDouble.New(5,2)"; - std::string msg(msgBase); -#ifdef WITH_NUMPY - msg+="\n-DataArrayDouble.New(numpy array with dtype=float64)"; -#endif - msg+=" !"; - if(PyList_Check(elt0) || PyTuple_Check(elt0)) - { - if(nbOfTuples) - { - if(PyInt_Check(nbOfTuples)) - { - int nbOfTuples1=PyInt_AS_LONG(nbOfTuples); - if(nbOfTuples1<0) - throw INTERP_KERNEL::Exception("DataArrayDouble::New : should be a positive set of allocated memory !"); - if(elt2) - { - if(PyInt_Check(elt2)) - {//DataArrayDouble.New([1.,3.,4.,5.],2,2) - int nbOfCompo=PyInt_AS_LONG(elt2); - if(nbOfCompo<0) - throw INTERP_KERNEL::Exception("DataArrayDouble::New : should be a positive number of components !"); - MEDCouplingAutoRefCountObjectPtr ret=DataArrayDouble::New(); - std::vector tmp=fillArrayWithPyListDbl2(elt0,nbOfTuples1,nbOfCompo); - ret->alloc(nbOfTuples1,nbOfCompo); std::copy(tmp.begin(),tmp.end(),ret->getPointer()); - return ret.retn(); - } - else - throw INTERP_KERNEL::Exception(msg.c_str()); - } - else - {//DataArrayDouble.New([1.,3.,4.],3) - MEDCouplingAutoRefCountObjectPtr ret=DataArrayDouble::New(); - int tmpp1=-1; - std::vector tmp=fillArrayWithPyListDbl2(elt0,nbOfTuples1,tmpp1); - ret->alloc(nbOfTuples1,tmpp1); std::copy(tmp.begin(),tmp.end(),ret->getPointer()); - return ret.retn(); - } - } - else - throw INTERP_KERNEL::Exception(msg.c_str()); - } - else - {// DataArrayDouble.New([1.,3.,4.]) - MEDCouplingAutoRefCountObjectPtr ret=DataArrayDouble::New(); - int tmpp1=-1,tmpp2=-1; - std::vector tmp=fillArrayWithPyListDbl2(elt0,tmpp1,tmpp2); - ret->alloc(tmpp1,tmpp2); std::copy(tmp.begin(),tmp.end(),ret->getPointer()); - return ret.retn(); - } - } - else if(PyInt_Check(elt0)) - { - int nbOfTuples1=PyInt_AS_LONG(elt0); - if(nbOfTuples1<0) - throw INTERP_KERNEL::Exception("DataArrayDouble::New : should be a positive set of allocated memory !"); - if(nbOfTuples) - { - if(!elt2) - { - if(PyInt_Check(nbOfTuples)) - {//DataArrayDouble.New(5,2) - int nbOfCompo=PyInt_AS_LONG(nbOfTuples); - if(nbOfCompo<0) - throw INTERP_KERNEL::Exception("DataArrayDouble::New : should be a positive number of components !"); - MEDCouplingAutoRefCountObjectPtr ret=DataArrayDouble::New(); - ret->alloc(nbOfTuples1,nbOfCompo); - return ret.retn(); - } - else - throw INTERP_KERNEL::Exception(msg.c_str()); - } - else - throw INTERP_KERNEL::Exception(msg.c_str()); - } - else - {//DataArrayDouble.New(5) - MEDCouplingAutoRefCountObjectPtr ret=DataArrayDouble::New(); - ret->alloc(nbOfTuples1,1); - return ret.retn(); - } - } -#ifdef WITH_NUMPY - else if(PyArray_Check(elt0) && nbOfTuples==NULL && elt2==NULL) - {//DataArrayDouble.New(numpyArray) - return BuildNewInstance(elt0,NPY_DOUBLE,&PyCallBackDataArrayDouble_RefType,"FLOAT64"); - } -#endif - else - throw INTERP_KERNEL::Exception(msg.c_str()); - throw INTERP_KERNEL::Exception(msg.c_str());//to make g++ happy - } - - DataArrayDouble(PyObject *elt0, PyObject *nbOfTuples=0, PyObject *elt2=0) throw(INTERP_KERNEL::Exception) - { - return ParaMEDMEM_DataArrayDouble_New__SWIG_1(elt0,nbOfTuples,elt2); - } - - void pushBackValsSilent(PyObject *li) throw(INTERP_KERNEL::Exception) - { - double val; - std::vector bb; - int sw,nbTuples=-1; - const char msg[]="Python wrap of DataArrayDouble::pushBackValsSilent : "; - const double *tmp=convertObjToPossibleCpp5_SingleCompo(li,sw,val,bb,msg,true,nbTuples); - self->pushBackValsSilent(tmp,tmp+nbTuples); - } - - std::string __repr__() const throw(INTERP_KERNEL::Exception) - { - std::ostringstream oss; - self->reprQuickOverview(oss); - return oss.str(); - } - - std::string __str__() const throw(INTERP_KERNEL::Exception) - { - return self->reprNotTooLong(); - } - - double __float__() const throw(INTERP_KERNEL::Exception) - { - return self->doubleValue(); - } - - int __len__() const throw(INTERP_KERNEL::Exception) - { - if(self->isAllocated()) - { - return self->getNumberOfTuples(); - } - else - { - throw INTERP_KERNEL::Exception("DataArrayDouble::__len__ : Instance is NOT allocated !"); - } - } - - DataArrayDoubleIterator *__iter__() throw(INTERP_KERNEL::Exception) - { - return self->iterator(); - } - - void setValues(PyObject *li, PyObject *nbOfTuples=0, PyObject *nbOfComp=0) throw(INTERP_KERNEL::Exception) - { - const char *msg="ParaMEDMEM::DataArrayDouble::setValues : Available API are : \n-DataArrayDouble.setValues([1.,3.,4.])\n-DataArrayDouble.setValues([1.,3.,4.],3)\n-DataArrayDouble.setValues([1.,3.,4.,5.],2,2)\n-DataArrayDouble.setValues([(1.,1.7),(3.,3.7),(4.,4.7)])\n !"; - if(PyList_Check(li) || PyTuple_Check(li)) - { - if(nbOfTuples) - { - if(PyInt_Check(nbOfTuples)) - { - int nbOfTuples1=PyInt_AS_LONG(nbOfTuples); - if(nbOfTuples1<0) - throw INTERP_KERNEL::Exception("DataArrayDouble::setValues : should be a positive set of allocated memory !"); - if(nbOfComp) - { - if(PyInt_Check(nbOfComp)) - {//DataArrayDouble.setValues([1.,3.,4.,5.],2,2) - int nbOfCompo=PyInt_AS_LONG(nbOfComp); - if(nbOfCompo<0) - throw INTERP_KERNEL::Exception("DataArrayDouble::setValues : should be a positive number of components !"); - std::vector tmp=fillArrayWithPyListDbl2(li,nbOfTuples1,nbOfCompo); - self->alloc(nbOfTuples1,nbOfCompo); std::copy(tmp.begin(),tmp.end(),self->getPointer()); - } - else - throw INTERP_KERNEL::Exception(msg); - } - else - {//DataArrayDouble.setValues([1.,3.,4.],3) - int tmpp1=-1; - std::vector tmp=fillArrayWithPyListDbl2(li,nbOfTuples1,tmpp1); - self->alloc(nbOfTuples1,tmpp1); std::copy(tmp.begin(),tmp.end(),self->getPointer()); - } - } - else - throw INTERP_KERNEL::Exception(msg); - } - else - {// DataArrayDouble.setValues([1.,3.,4.]) - int tmpp1=-1,tmpp2=-1; - std::vector tmp=fillArrayWithPyListDbl2(li,tmpp1,tmpp2); - self->alloc(tmpp1,tmpp2); std::copy(tmp.begin(),tmp.end(),self->getPointer()); - } - } - else - throw INTERP_KERNEL::Exception(msg); - } - - PyObject *getValues() const throw(INTERP_KERNEL::Exception) - { - const double *vals=self->getConstPointer(); - return convertDblArrToPyList(vals,self->getNbOfElems()); - } - -#ifdef WITH_NUMPY - PyObject *toNumPyArray() throw(INTERP_KERNEL::Exception) // not const. It is not a bug ! - { - return ToNumPyArray(self,NPY_DOUBLE,"DataArrayDouble"); - } -#endif - - PyObject *isEqualIfNotWhy(const DataArrayDouble& other, double prec) const throw(INTERP_KERNEL::Exception) - { - std::string ret1; - bool ret0=self->isEqualIfNotWhy(other,prec,ret1); - PyObject *ret=PyTuple_New(2); - PyObject *ret0Py=ret0?Py_True:Py_False; - Py_XINCREF(ret0Py); - PyTuple_SetItem(ret,0,ret0Py); - PyTuple_SetItem(ret,1,PyString_FromString(ret1.c_str())); - return ret; - } - - PyObject *getValuesAsTuple() const throw(INTERP_KERNEL::Exception) - { - const double *vals=self->getConstPointer(); - int nbOfComp=self->getNumberOfComponents(); - int nbOfTuples=self->getNumberOfTuples(); - return convertDblArrToPyListOfTuple(vals,nbOfComp,nbOfTuples); - } - - DataArrayDouble *renumber(PyObject *li) throw(INTERP_KERNEL::Exception) - { - void *da=0; - int res1=SWIG_ConvertPtr(li,&da,SWIGTYPE_p_ParaMEDMEM__DataArrayInt, 0 | 0 ); - if (!SWIG_IsOK(res1)) - { - int size; - INTERP_KERNEL::AutoPtr tmp=convertPyToNewIntArr2(li,&size); - if(size!=self->getNumberOfTuples()) - { - throw INTERP_KERNEL::Exception("Invalid list length ! Must be equal to number of tuples !"); - } - return self->renumber(tmp); - } - else - { - DataArrayInt *da2=reinterpret_cast< DataArrayInt * >(da); - if(!da2) - throw INTERP_KERNEL::Exception("Not null DataArrayInt instance expected !"); - da2->checkAllocated(); - int size=self->getNumberOfTuples(); - if(size!=self->getNumberOfTuples()) - { - throw INTERP_KERNEL::Exception("Invalid list length ! Must be equal to number of tuples !"); - } - return self->renumber(da2->getConstPointer()); - } - } - - DataArrayDouble *renumberR(PyObject *li) throw(INTERP_KERNEL::Exception) - { - void *da=0; - int res1=SWIG_ConvertPtr(li,&da,SWIGTYPE_p_ParaMEDMEM__DataArrayInt, 0 | 0 ); - if (!SWIG_IsOK(res1)) - { - int size; - INTERP_KERNEL::AutoPtr tmp=convertPyToNewIntArr2(li,&size); - if(size!=self->getNumberOfTuples()) - { - throw INTERP_KERNEL::Exception("Invalid list length ! Must be equal to number of tuples !"); - } - return self->renumberR(tmp); - } - else - { - DataArrayInt *da2=reinterpret_cast< DataArrayInt * >(da); - if(!da2) - throw INTERP_KERNEL::Exception("Not null DataArrayInt instance expected !"); - da2->checkAllocated(); - int size=self->getNumberOfTuples(); - if(size!=self->getNumberOfTuples()) - { - throw INTERP_KERNEL::Exception("Invalid list length ! Must be equal to number of tuples !"); - } - return self->renumberR(da2->getConstPointer()); - } - } - - DataArrayDouble *renumberAndReduce(PyObject *li, int newNbOfTuple) throw(INTERP_KERNEL::Exception) - { - void *da=0; - int res1=SWIG_ConvertPtr(li,&da,SWIGTYPE_p_ParaMEDMEM__DataArrayInt, 0 | 0 ); - if (!SWIG_IsOK(res1)) - { - int size; - INTERP_KERNEL::AutoPtr tmp=convertPyToNewIntArr2(li,&size); - if(size!=self->getNumberOfTuples()) - { - throw INTERP_KERNEL::Exception("Invalid list length ! Must be equal to number of tuples !"); - } - return self->renumberAndReduce(tmp,newNbOfTuple); - } - else - { - DataArrayInt *da2=reinterpret_cast< DataArrayInt * >(da); - if(!da2) - throw INTERP_KERNEL::Exception("Not null DataArrayInt instance expected !"); - da2->checkAllocated(); - int size=self->getNumberOfTuples(); - if(size!=self->getNumberOfTuples()) - { - throw INTERP_KERNEL::Exception("Invalid list length ! Must be equal to number of tuples !"); - } - return self->renumberAndReduce(da2->getConstPointer(),newNbOfTuple); - } - } - - PyObject *minimalDistanceTo(const DataArrayDouble *other) const throw(INTERP_KERNEL::Exception) - { - int thisTupleId,otherTupleId; - double r0=self->minimalDistanceTo(other,thisTupleId,otherTupleId); - PyObject *ret=PyTuple_New(3); - PyTuple_SetItem(ret,0,PyFloat_FromDouble(r0)); - PyTuple_SetItem(ret,1,PyInt_FromLong(thisTupleId)); - PyTuple_SetItem(ret,2,PyInt_FromLong(otherTupleId)); - return ret; - } - - PyObject *getMaxValue() const throw(INTERP_KERNEL::Exception) - { - int tmp; - double r1=self->getMaxValue(tmp); - PyObject *ret=PyTuple_New(2); - PyTuple_SetItem(ret,0,PyFloat_FromDouble(r1)); - PyTuple_SetItem(ret,1,PyInt_FromLong(tmp)); - return ret; - } - - PyObject *getMaxValue2() const throw(INTERP_KERNEL::Exception) - { - DataArrayInt *tmp; - double r1=self->getMaxValue2(tmp); - PyObject *ret=PyTuple_New(2); - PyTuple_SetItem(ret,0,PyFloat_FromDouble(r1)); - PyTuple_SetItem(ret,1,SWIG_NewPointerObj(SWIG_as_voidptr(tmp),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 )); - return ret; - } - - PyObject *getMinValue() const throw(INTERP_KERNEL::Exception) - { - int tmp; - double r1=self->getMinValue(tmp); - PyObject *ret=PyTuple_New(2); - PyTuple_SetItem(ret,0,PyFloat_FromDouble(r1)); - PyTuple_SetItem(ret,1,PyInt_FromLong(tmp)); - return ret; - } - - PyObject *getMinValue2() const throw(INTERP_KERNEL::Exception) - { - DataArrayInt *tmp; - double r1=self->getMinValue2(tmp); - PyObject *ret=PyTuple_New(2); - PyTuple_SetItem(ret,0,PyFloat_FromDouble(r1)); - PyTuple_SetItem(ret,1,SWIG_NewPointerObj(SWIG_as_voidptr(tmp),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 )); - return ret; - } - - PyObject *getMinMaxPerComponent() const throw(INTERP_KERNEL::Exception) - { - int nbOfCompo=self->getNumberOfComponents(); - INTERP_KERNEL::AutoPtr tmp=new double[2*nbOfCompo]; - self->getMinMaxPerComponent(tmp); - PyObject *ret=convertDblArrToPyListOfTuple(tmp,2,nbOfCompo); - return ret; - } - - PyObject *accumulate() const throw(INTERP_KERNEL::Exception) - { - int sz=self->getNumberOfComponents(); - INTERP_KERNEL::AutoPtr tmp=new double[sz]; - self->accumulate(tmp); - return convertDblArrToPyList(tmp,sz); - } - - DataArrayDouble *accumulatePerChunck(PyObject *indexArr) const throw(INTERP_KERNEL::Exception) - { - int sw,sz,val; - std::vector val2; - const int *bg=convertObjToPossibleCpp1_Safe(indexArr,sw,sz,val,val2); - return self->accumulatePerChunck(bg,bg+sz); - } - - PyObject *findCommonTuples(double prec, int limitNodeId=-1) const throw(INTERP_KERNEL::Exception) - { - DataArrayInt *comm, *commIndex; - self->findCommonTuples(prec,limitNodeId,comm,commIndex); - PyObject *res = PyList_New(2); - PyList_SetItem(res,0,SWIG_NewPointerObj(SWIG_as_voidptr(comm),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 )); - PyList_SetItem(res,1,SWIG_NewPointerObj(SWIG_as_voidptr(commIndex),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 )); - return res; - } - - PyObject *distanceToTuple(PyObject *tuple) const throw(INTERP_KERNEL::Exception) - { - double val; - DataArrayDouble *a; - DataArrayDoubleTuple *aa; - std::vector bb; - int sw; - int tupleId=-1,nbOfCompo=self->getNumberOfComponents(); - const double *pt=convertObjToPossibleCpp5_Safe(tuple,sw,val,a,aa,bb,"Python wrap of DataArrayDouble::distanceToTuple",1,nbOfCompo,true); - // - double ret0=self->distanceToTuple(pt,pt+nbOfCompo,tupleId); - PyObject *ret=PyTuple_New(2); - PyTuple_SetItem(ret,0,PyFloat_FromDouble(ret0)); - PyTuple_SetItem(ret,1,PyInt_FromLong(tupleId)); - return ret; - } - - void setSelectedComponents(const DataArrayDouble *a, PyObject *li) throw(INTERP_KERNEL::Exception) - { - std::vector tmp; - convertPyToNewIntArr3(li,tmp); - self->setSelectedComponents(a,tmp); - } - - PyObject *getTuple(int tupleId) throw(INTERP_KERNEL::Exception) - { - int sz=self->getNumberOfComponents(); - INTERP_KERNEL::AutoPtr tmp=new double[sz]; - self->getTuple(tupleId,tmp); - return convertDblArrToPyList(tmp,sz); - } - - static DataArrayDouble *Aggregate(PyObject *li) throw(INTERP_KERNEL::Exception) - { - std::vector tmp; - convertFromPyObjVectorOfObj(li,SWIGTYPE_p_ParaMEDMEM__DataArrayDouble,"DataArrayDouble",tmp); - return DataArrayDouble::Aggregate(tmp); - } - - static DataArrayDouble *Meld(PyObject *li) throw(INTERP_KERNEL::Exception) - { - std::vector tmp; - convertFromPyObjVectorOfObj(li,SWIGTYPE_p_ParaMEDMEM__DataArrayDouble,"DataArrayDouble",tmp); - return DataArrayDouble::Meld(tmp); - } - - PyObject *computeTupleIdsNearTuples(PyObject *pt, double eps) const throw(INTERP_KERNEL::Exception) - { - double val; - DataArrayDouble *a; - DataArrayDoubleTuple *aa; - std::vector bb; - int sw; - int nbComp=self->getNumberOfComponents(),nbTuples=-1; - const char msg[]="Python wrap of DataArrayDouble::computeTupleIdsNearTuples : "; - const double *pos=convertObjToPossibleCpp5_Safe2(pt,sw,val,a,aa,bb,msg,nbComp,true,nbTuples); - MEDCouplingAutoRefCountObjectPtr inpu=DataArrayDouble::New(); inpu->useArray(pos,false,CPP_DEALLOC,nbTuples,nbComp); - DataArrayInt *c=0,*cI=0; - self->computeTupleIdsNearTuples(inpu,eps,c,cI); - PyObject *ret=PyTuple_New(2); - PyTuple_SetItem(ret,0,SWIG_NewPointerObj(SWIG_as_voidptr(c),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 )); - PyTuple_SetItem(ret,1,SWIG_NewPointerObj(SWIG_as_voidptr(cI),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 )); - return ret; - } - - PyObject *areIncludedInMe(const DataArrayDouble *other, double prec) const throw(INTERP_KERNEL::Exception) - { - DataArrayInt *ret1=0; - bool ret0=self->areIncludedInMe(other,prec,ret1); - PyObject *ret=PyTuple_New(2); - PyObject *ret0Py=ret0?Py_True:Py_False; - Py_XINCREF(ret0Py); - PyTuple_SetItem(ret,0,ret0Py); - PyTuple_SetItem(ret,1,SWIG_NewPointerObj(SWIG_as_voidptr(ret1),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 )); - return ret; - } - - PyObject *__getitem__(PyObject *obj) throw(INTERP_KERNEL::Exception) - { - const char msg[]="Unexpected situation in DataArrayDouble::__getitem__ !"; - const char msg2[]="DataArrayDouble::__getitem__ : Mismatch of slice values in 2nd parameter (components) !"; - self->checkAllocated(); - int nbOfTuples=self->getNumberOfTuples(); - int nbOfComponents=self->getNumberOfComponents(); - int it1,ic1; - std::vector vt1,vc1; - std::pair > pt1,pc1; - DataArrayInt *dt1=0,*dc1=0; - int sw; - convertObjToPossibleCpp3(obj,nbOfTuples,nbOfComponents,sw,it1,ic1,vt1,vc1,pt1,pc1,dt1,dc1); - MEDCouplingAutoRefCountObjectPtr ret; - switch(sw) - { - case 1: - if(nbOfComponents==1) - return PyFloat_FromDouble(self->getIJSafe(it1,0)); - return SWIG_NewPointerObj(SWIG_as_voidptr(self->selectByTupleIdSafe(&it1,&it1+1)),SWIGTYPE_p_ParaMEDMEM__DataArrayDouble, SWIG_POINTER_OWN | 0 ); - case 2: - return SWIG_NewPointerObj(SWIG_as_voidptr(self->selectByTupleIdSafe(&vt1[0],&vt1[0]+vt1.size())),SWIGTYPE_p_ParaMEDMEM__DataArrayDouble, SWIG_POINTER_OWN | 0 ); - case 3: - return SWIG_NewPointerObj(SWIG_as_voidptr(self->selectByTupleId2(pt1.first,pt1.second.first,pt1.second.second)),SWIGTYPE_p_ParaMEDMEM__DataArrayDouble, SWIG_POINTER_OWN | 0 ); - case 4: - return SWIG_NewPointerObj(SWIG_as_voidptr(self->selectByTupleIdSafe(dt1->getConstPointer(),dt1->getConstPointer()+dt1->getNbOfElems())),SWIGTYPE_p_ParaMEDMEM__DataArrayDouble, SWIG_POINTER_OWN | 0 ); - case 5: - return PyFloat_FromDouble(self->getIJSafe(it1,ic1)); - case 6: - { - ret=self->selectByTupleIdSafe(&vt1[0],&vt1[0]+vt1.size()); - std::vector v2(1,ic1); - return SWIG_NewPointerObj(SWIG_as_voidptr(ret->keepSelectedComponents(v2)),SWIGTYPE_p_ParaMEDMEM__DataArrayDouble, SWIG_POINTER_OWN | 0 ); - } - case 7: - { - ret=self->selectByTupleId2(pt1.first,pt1.second.first,pt1.second.second); - std::vector v2(1,ic1); - return SWIG_NewPointerObj(SWIG_as_voidptr(ret->keepSelectedComponents(v2)),SWIGTYPE_p_ParaMEDMEM__DataArrayDouble, SWIG_POINTER_OWN | 0 ); - } - case 8: - { - ret=self->selectByTupleIdSafe(dt1->getConstPointer(),dt1->getConstPointer()+dt1->getNbOfElems()); - std::vector v2(1,ic1); - return SWIG_NewPointerObj(SWIG_as_voidptr(ret->keepSelectedComponents(v2)),SWIGTYPE_p_ParaMEDMEM__DataArrayDouble, SWIG_POINTER_OWN | 0 ); - } - case 9: - { - ret=self->selectByTupleIdSafe(&it1,&it1+1); - return SWIG_NewPointerObj(SWIG_as_voidptr(ret->keepSelectedComponents(vc1)),SWIGTYPE_p_ParaMEDMEM__DataArrayDouble, SWIG_POINTER_OWN | 0 ); - } - case 10: - { - ret=self->selectByTupleIdSafe(&vt1[0],&vt1[0]+vt1.size()); - return SWIG_NewPointerObj(SWIG_as_voidptr(ret->keepSelectedComponents(vc1)),SWIGTYPE_p_ParaMEDMEM__DataArrayDouble, SWIG_POINTER_OWN | 0 ); - } - case 11: - { - ret=self->selectByTupleId2(pt1.first,pt1.second.first,pt1.second.second); - return SWIG_NewPointerObj(SWIG_as_voidptr(ret->keepSelectedComponents(vc1)),SWIGTYPE_p_ParaMEDMEM__DataArrayDouble, SWIG_POINTER_OWN | 0 ); - } - case 12: - { - ret=self->selectByTupleIdSafe(dt1->getConstPointer(),dt1->getConstPointer()+dt1->getNbOfElems()); - return SWIG_NewPointerObj(SWIG_as_voidptr(ret->keepSelectedComponents(vc1)),SWIGTYPE_p_ParaMEDMEM__DataArrayDouble, SWIG_POINTER_OWN | 0 ); - } - case 13: - { - ret=self->selectByTupleIdSafe(&it1,&it1+1); - int nbOfComp=DataArray::GetNumberOfItemGivenBESRelative(pc1.first,pc1.second.first,pc1.second.second,msg2); - std::vector v2(nbOfComp); - for(int i=0;ikeepSelectedComponents(v2)),SWIGTYPE_p_ParaMEDMEM__DataArrayDouble, SWIG_POINTER_OWN | 0 ); - } - case 14: - { - ret=self->selectByTupleIdSafe(&vt1[0],&vt1[0]+vt1.size()); - int nbOfComp=DataArray::GetNumberOfItemGivenBESRelative(pc1.first,pc1.second.first,pc1.second.second,msg2); - std::vector v2(nbOfComp); - for(int i=0;ikeepSelectedComponents(v2)),SWIGTYPE_p_ParaMEDMEM__DataArrayDouble, SWIG_POINTER_OWN | 0 ); - } - case 15: - { - ret=self->selectByTupleId2(pt1.first,pt1.second.first,pt1.second.second); - int nbOfComp=DataArray::GetNumberOfItemGivenBESRelative(pc1.first,pc1.second.first,pc1.second.second,msg2); - std::vector v2(nbOfComp); - for(int i=0;ikeepSelectedComponents(v2)),SWIGTYPE_p_ParaMEDMEM__DataArrayDouble, SWIG_POINTER_OWN | 0 ); - } - case 16: - { - ret=self->selectByTupleIdSafe(dt1->getConstPointer(),dt1->getConstPointer()+dt1->getNbOfElems()); - int nbOfComp=DataArray::GetNumberOfItemGivenBESRelative(pc1.first,pc1.second.first,pc1.second.second,msg2); - std::vector v2(nbOfComp); - for(int i=0;ikeepSelectedComponents(v2)),SWIGTYPE_p_ParaMEDMEM__DataArrayDouble, SWIG_POINTER_OWN | 0 ); - } - default: - throw INTERP_KERNEL::Exception(msg); - } - } - - DataArrayDouble *__setitem__(PyObject *obj, PyObject *value) throw(INTERP_KERNEL::Exception) - { - self->checkAllocated(); - const char msg[]="Unexpected situation in DataArrayDouble::__setitem__ !"; - int nbOfTuples=self->getNumberOfTuples(); - int nbOfComponents=self->getNumberOfComponents(); - int sw1,sw2; - double i1; - std::vector v1; - DataArrayDouble *d1=0; - convertObjToPossibleCpp4(value,sw1,i1,v1,d1); - int it1,ic1; - std::vector vt1,vc1; - std::pair > pt1,pc1; - DataArrayInt *dt1=0,*dc1=0; - convertObjToPossibleCpp3(obj,nbOfTuples,nbOfComponents,sw2,it1,ic1,vt1,vc1,pt1,pc1,dt1,dc1); - MEDCouplingAutoRefCountObjectPtr tmp; - switch(sw2) - { - case 1: - { - switch(sw1) - { - case 1: - self->setPartOfValuesSimple1(i1,it1,it1+1,1,0,nbOfComponents,1); - return self; - case 2: - tmp=DataArrayDouble::New(); - tmp->useArray(&v1[0],false,CPP_DEALLOC,1,v1.size()); - self->setPartOfValues1(tmp,it1,it1+1,1,0,nbOfComponents,1,false); - return self; - case 3: - self->setPartOfValues1(d1,it1,it1+1,1,0,nbOfComponents,1); - return self; - default: - throw INTERP_KERNEL::Exception(msg); - } - break; - } - case 2: - { - switch(sw1) - { - case 1: - self->setPartOfValuesSimple3(i1,&vt1[0],&vt1[0]+vt1.size(),0,nbOfComponents,1); - return self; - case 2: - tmp=DataArrayDouble::New(); - tmp->useArray(&v1[0],false,CPP_DEALLOC,1,v1.size()); - self->setPartOfValues3(tmp,&vt1[0],&vt1[0]+vt1.size(),0,nbOfComponents,1,false); - return self; - case 3: - self->setPartOfValues3(d1,&vt1[0],&vt1[0]+vt1.size(),0,nbOfComponents,1); - return self; - default: - throw INTERP_KERNEL::Exception(msg); - } - break; - } - case 3: - { - switch(sw1) - { - case 1: - self->setPartOfValuesSimple1(i1,pt1.first,pt1.second.first,pt1.second.second,0,nbOfComponents,1); - return self; - case 2: - tmp=DataArrayDouble::New(); - tmp->useArray(&v1[0],false,CPP_DEALLOC,1,v1.size()); - self->setPartOfValues1(tmp,pt1.first,pt1.second.first,pt1.second.second,0,nbOfComponents,1,false); - return self; - case 3: - self->setPartOfValues1(d1,pt1.first,pt1.second.first,pt1.second.second,0,nbOfComponents,1); - return self; - default: - throw INTERP_KERNEL::Exception(msg); - } - break; - } - case 4: - { - switch(sw1) - { - case 1: - self->setPartOfValuesSimple3(i1,dt1->getConstPointer(),dt1->getConstPointer()+dt1->getNbOfElems(),0,nbOfComponents,1); - return self; - case 2: - tmp=DataArrayDouble::New(); - tmp->useArray(&v1[0],false,CPP_DEALLOC,1,v1.size()); - self->setPartOfValues3(tmp,dt1->getConstPointer(),dt1->getConstPointer()+dt1->getNbOfElems(),0,nbOfComponents,1,false); - return self; - case 3: - self->setPartOfValues3(d1,dt1->getConstPointer(),dt1->getConstPointer()+dt1->getNbOfElems(),0,nbOfComponents,1); - return self; - default: - throw INTERP_KERNEL::Exception(msg); - } - break; - } - case 5: - { - switch(sw1) - { - case 1: - self->setPartOfValuesSimple1(i1,it1,it1+1,1,ic1,ic1+1,1); - return self; - case 2: - tmp=DataArrayDouble::New(); - tmp->useArray(&v1[0],false,CPP_DEALLOC,1,v1.size()); - self->setPartOfValues1(tmp,it1,it1+1,1,ic1,ic1+1,1,false); - return self; - case 3: - self->setPartOfValues1(d1,it1,it1+1,1,ic1,ic1+1,1); - return self; - default: - throw INTERP_KERNEL::Exception(msg); - } - break; - } - case 6: - { - switch(sw1) - { - case 1: - self->setPartOfValuesSimple3(i1,&vt1[0],&vt1[0]+vt1.size(),ic1,ic1+1,1); - return self; - case 2: - tmp=DataArrayDouble::New(); - tmp->useArray(&v1[0],false,CPP_DEALLOC,1,v1.size()); - self->setPartOfValues3(tmp,&vt1[0],&vt1[0]+vt1.size(),ic1,ic1+1,1,false); - return self; - case 3: - self->setPartOfValues3(d1,&vt1[0],&vt1[0]+vt1.size(),ic1,ic1+1,1); - return self; - default: - throw INTERP_KERNEL::Exception(msg); - } - break; - } - case 7: - { - switch(sw1) - { - case 1: - self->setPartOfValuesSimple1(i1,pt1.first,pt1.second.first,pt1.second.second,ic1,ic1+1,1); - return self; - case 2: - tmp=DataArrayDouble::New(); - tmp->useArray(&v1[0],false,CPP_DEALLOC,1,v1.size()); - self->setPartOfValues1(tmp,pt1.first,pt1.second.first,pt1.second.second,ic1,ic1+1,1,false); - return self; - case 3: - self->setPartOfValues1(d1,pt1.first,pt1.second.first,pt1.second.second,ic1,ic1+1,1); - return self; - default: - throw INTERP_KERNEL::Exception(msg); - } - break; - } - case 8: - { - switch(sw1) - { - case 1: - self->setPartOfValuesSimple3(i1,dt1->getConstPointer(),dt1->getConstPointer()+dt1->getNbOfElems(),ic1,ic1+1,1); - return self; - case 2: - tmp=DataArrayDouble::New(); - tmp->useArray(&v1[0],false,CPP_DEALLOC,1,v1.size()); - self->setPartOfValues3(tmp,dt1->getConstPointer(),dt1->getConstPointer()+dt1->getNbOfElems(),ic1,ic1+1,1,false); - return self; - case 3: - self->setPartOfValues3(d1,dt1->getConstPointer(),dt1->getConstPointer()+dt1->getNbOfElems(),ic1,ic1+1,1); - return self; - default: - throw INTERP_KERNEL::Exception(msg); - } - break; - } - case 9: - { - switch(sw1) - { - case 1: - self->setPartOfValuesSimple2(i1,&it1,&it1+1,&vc1[0],&vc1[0]+vc1.size()); - return self; - case 2: - tmp=DataArrayDouble::New(); - tmp->useArray(&v1[0],false,CPP_DEALLOC,1,v1.size()); - self->setPartOfValues2(tmp,&it1,&it1+1,&vc1[0],&vc1[0]+vc1.size(),false); - return self; - case 3: - self->setPartOfValues2(d1,&it1,&it1+1,&vc1[0],&vc1[0]+vc1.size()); - return self; - default: - throw INTERP_KERNEL::Exception(msg); - } - break; - } - case 10: - { - switch(sw1) - { - case 1: - self->setPartOfValuesSimple2(i1,&vt1[0],&vt1[0]+vt1.size(),&vc1[0],&vc1[0]+vc1.size()); - return self; - case 2: - tmp=DataArrayDouble::New(); - tmp->useArray(&v1[0],false,CPP_DEALLOC,1,v1.size()); - self->setPartOfValues2(tmp,&vt1[0],&vt1[0]+vt1.size(),&vc1[0],&vc1[0]+vc1.size(),false); - return self; - case 3: - self->setPartOfValues2(d1,&vt1[0],&vt1[0]+vt1.size(),&vc1[0],&vc1[0]+vc1.size()); - return self; - default: - throw INTERP_KERNEL::Exception(msg); - } - break; - } - case 11: - { - switch(sw1) - { - case 1: - self->setPartOfValuesSimple4(i1,pt1.first,pt1.second.first,pt1.second.second,&vc1[0],&vc1[0]+vc1.size()); - return self; - case 2: - tmp=DataArrayDouble::New(); - tmp->useArray(&v1[0],false,CPP_DEALLOC,1,v1.size()); - self->setPartOfValues4(tmp,pt1.first,pt1.second.first,pt1.second.second,&vc1[0],&vc1[0]+vc1.size(),false); - return self; - case 3: - self->setPartOfValues4(d1,pt1.first,pt1.second.first,pt1.second.second,&vc1[0],&vc1[0]+vc1.size()); - return self; - default: - throw INTERP_KERNEL::Exception(msg); - } - break; - } - case 12: - { - switch(sw1) - { - case 1: - self->setPartOfValuesSimple2(i1,dt1->getConstPointer(),dt1->getConstPointer()+dt1->getNbOfElems(),&vc1[0],&vc1[0]+vc1.size()); - return self; - case 2: - tmp=DataArrayDouble::New(); - tmp->useArray(&v1[0],false,CPP_DEALLOC,1,v1.size()); - self->setPartOfValues2(tmp,dt1->getConstPointer(),dt1->getConstPointer()+dt1->getNbOfElems(),&vc1[0],&vc1[0]+vc1.size(),false); - return self; - case 3: - self->setPartOfValues2(d1,dt1->getConstPointer(),dt1->getConstPointer()+dt1->getNbOfElems(),&vc1[0],&vc1[0]+vc1.size()); - return self; - default: - throw INTERP_KERNEL::Exception(msg); - } - break; - } - case 13: - { - switch(sw1) - { - case 1: - self->setPartOfValuesSimple1(i1,it1,it1+1,1,pc1.first,pc1.second.first,pc1.second.second); - return self; - case 2: - tmp=DataArrayDouble::New(); - tmp->useArray(&v1[0],false,CPP_DEALLOC,1,v1.size()); - self->setPartOfValues1(tmp,it1,it1+1,1,pc1.first,pc1.second.first,pc1.second.second,false); - return self; - case 3: - self->setPartOfValues1(d1,it1,it1+1,1,pc1.first,pc1.second.first,pc1.second.second); - return self; - default: - throw INTERP_KERNEL::Exception(msg); - } - break; - } - case 14: - { - switch(sw1) - { - case 1: - self->setPartOfValuesSimple3(i1,&vt1[0],&vt1[0]+vt1.size(),pc1.first,pc1.second.first,pc1.second.second); - return self; - case 2: - tmp=DataArrayDouble::New(); - tmp->useArray(&v1[0],false,CPP_DEALLOC,1,v1.size()); - self->setPartOfValues3(tmp,&vt1[0],&vt1[0]+vt1.size(),pc1.first,pc1.second.first,pc1.second.second,false); - return self; - case 3: - self->setPartOfValues3(d1,&vt1[0],&vt1[0]+vt1.size(),pc1.first,pc1.second.first,pc1.second.second); - return self; - default: - throw INTERP_KERNEL::Exception(msg); - } - break; - } - case 15: - { - switch(sw1) - { - case 1: - self->setPartOfValuesSimple1(i1,pt1.first,pt1.second.first,pt1.second.second,pc1.first,pc1.second.first,pc1.second.second); - return self; - case 2: - tmp=DataArrayDouble::New(); - tmp->useArray(&v1[0],false,CPP_DEALLOC,1,v1.size()); - self->setPartOfValues1(tmp,pt1.first,pt1.second.first,pt1.second.second,pc1.first,pc1.second.first,pc1.second.second,false); - return self; - case 3: - self->setPartOfValues1(d1,pt1.first,pt1.second.first,pt1.second.second,pc1.first,pc1.second.first,pc1.second.second); - return self; - default: - throw INTERP_KERNEL::Exception(msg); - } - break; - } - case 16: - { - switch(sw1) - { - case 1: - self->setPartOfValuesSimple3(i1,dt1->getConstPointer(),dt1->getConstPointer()+dt1->getNbOfElems(),pc1.first,pc1.second.first,pc1.second.second); - return self; - case 2: - tmp=DataArrayDouble::New(); - tmp->useArray(&v1[0],false,CPP_DEALLOC,1,v1.size()); - self->setPartOfValues3(tmp,dt1->getConstPointer(),dt1->getConstPointer()+dt1->getNbOfElems(),pc1.first,pc1.second.first,pc1.second.second,false); - return self; - case 3: - self->setPartOfValues3(d1,dt1->getConstPointer(),dt1->getConstPointer()+dt1->getNbOfElems(),pc1.first,pc1.second.first,pc1.second.second); - return self; - default: - throw INTERP_KERNEL::Exception(msg); - } - break; - } - default: - throw INTERP_KERNEL::Exception(msg); - } - return self; - } - - DataArrayDouble *__neg__() const throw(INTERP_KERNEL::Exception) - { - return self->negate(); - } - - PyObject *__add__(PyObject *obj) throw(INTERP_KERNEL::Exception) - { - const char msg[]="Unexpected situation in DataArrayDouble.__add__ !"; - double val; - DataArrayDouble *a; - DataArrayDoubleTuple *aa; - std::vector bb; - int sw; - // -#ifndef WITHOUT_AUTOFIELD - void *argp; - if(SWIG_IsOK(SWIG_ConvertPtr(obj,&argp,SWIGTYPE_p_ParaMEDMEM__MEDCouplingFieldDouble,0|0))) - { - MEDCouplingFieldDouble *other=reinterpret_cast< ParaMEDMEM::MEDCouplingFieldDouble * >(argp); - if(other) - { - PyObject *tmp=SWIG_NewPointerObj(SWIG_as_voidptr(self),SWIGTYPE_p_ParaMEDMEM__DataArrayDouble, 0 | 0 ); - MEDCouplingAutoRefCountObjectPtr ret=ParaMEDMEM_MEDCouplingFieldDouble___radd__Impl(other,tmp); - Py_XDECREF(tmp); - return SWIG_NewPointerObj(SWIG_as_voidptr(ret.retn()),SWIGTYPE_p_ParaMEDMEM__MEDCouplingFieldDouble, SWIG_POINTER_OWN | 0 ); - } - else - throw INTERP_KERNEL::Exception(msg); - } -#endif - // - convertObjToPossibleCpp5(obj,sw,val,a,aa,bb); - switch(sw) - { - case 1: - { - MEDCouplingAutoRefCountObjectPtr ret=self->deepCpy(); - ret->applyLin(1.,val); - return SWIG_NewPointerObj(SWIG_as_voidptr(ret.retn()),SWIGTYPE_p_ParaMEDMEM__DataArrayDouble, SWIG_POINTER_OWN | 0 ); - } - case 2: - { - return SWIG_NewPointerObj(SWIG_as_voidptr(DataArrayDouble::Add(self,a)),SWIGTYPE_p_ParaMEDMEM__DataArrayDouble, SWIG_POINTER_OWN | 0 ); - } - case 3: - { - MEDCouplingAutoRefCountObjectPtr aaa=aa->buildDADouble(1,self->getNumberOfComponents()); - return SWIG_NewPointerObj(SWIG_as_voidptr(DataArrayDouble::Add(self,aaa)),SWIGTYPE_p_ParaMEDMEM__DataArrayDouble, SWIG_POINTER_OWN | 0 ); - } - case 4: - { - MEDCouplingAutoRefCountObjectPtr aaa=DataArrayDouble::New(); aaa->useArray(&bb[0],false,CPP_DEALLOC,1,(int)bb.size()); - return SWIG_NewPointerObj(SWIG_as_voidptr(DataArrayDouble::Add(self,aaa)),SWIGTYPE_p_ParaMEDMEM__DataArrayDouble, SWIG_POINTER_OWN | 0 ); - } - default: - throw INTERP_KERNEL::Exception(msg); - } - } - - DataArrayDouble *__radd__(PyObject *obj) throw(INTERP_KERNEL::Exception) - { - const char msg[]="Unexpected situation in __radd__ !"; - double val; - DataArrayDouble *a; - DataArrayDoubleTuple *aa; - std::vector bb; - int sw; - convertObjToPossibleCpp5(obj,sw,val,a,aa,bb); - switch(sw) - { - case 1: - { - MEDCouplingAutoRefCountObjectPtr ret=self->deepCpy(); - ret->applyLin(1.,val); - return ret.retn(); - } - case 3: - { - MEDCouplingAutoRefCountObjectPtr aaa=aa->buildDADouble(1,self->getNumberOfComponents()); - return DataArrayDouble::Add(self,aaa); - } - case 4: - { - MEDCouplingAutoRefCountObjectPtr aaa=DataArrayDouble::New(); aaa->useArray(&bb[0],false,CPP_DEALLOC,1,(int)bb.size()); - return DataArrayDouble::Add(self,aaa); - } - default: - throw INTERP_KERNEL::Exception(msg); - } - } - - PyObject *___iadd___(PyObject *trueSelf, PyObject *obj) throw(INTERP_KERNEL::Exception) - { - const char msg[]="Unexpected situation in __iadd__ !"; - double val; - DataArrayDouble *a; - DataArrayDoubleTuple *aa; - std::vector bb; - int sw; - convertObjToPossibleCpp5(obj,sw,val,a,aa,bb); - switch(sw) - { - case 1: - { - self->applyLin(1.,val); - Py_XINCREF(trueSelf); - return trueSelf; - } - case 2: - { - self->addEqual(a); - Py_XINCREF(trueSelf); - return trueSelf; - } - case 3: - { - MEDCouplingAutoRefCountObjectPtr aaa=aa->buildDADouble(1,self->getNumberOfComponents()); - self->addEqual(aaa); - Py_XINCREF(trueSelf); - return trueSelf; - } - case 4: - { - MEDCouplingAutoRefCountObjectPtr aaa=DataArrayDouble::New(); aaa->useArray(&bb[0],false,CPP_DEALLOC,1,(int)bb.size()); - self->addEqual(aaa); - Py_XINCREF(trueSelf); - return trueSelf; - } - default: - throw INTERP_KERNEL::Exception(msg); - } - } - - PyObject *__sub__(PyObject *obj) throw(INTERP_KERNEL::Exception) - { - const char msg[]="Unexpected situation in __sub__ !"; - double val; - DataArrayDouble *a; - DataArrayDoubleTuple *aa; - std::vector bb; - int sw; - // -#ifndef WITHOUT_AUTOFIELD - void *argp; - if(SWIG_IsOK(SWIG_ConvertPtr(obj,&argp,SWIGTYPE_p_ParaMEDMEM__MEDCouplingFieldDouble,0|0))) - { - MEDCouplingFieldDouble *other=reinterpret_cast< ParaMEDMEM::MEDCouplingFieldDouble * >(argp); - if(other) - { - PyObject *tmp=SWIG_NewPointerObj(SWIG_as_voidptr(self),SWIGTYPE_p_ParaMEDMEM__DataArrayDouble, 0 | 0 ); - MEDCouplingAutoRefCountObjectPtr ret=ParaMEDMEM_MEDCouplingFieldDouble___rsub__Impl(other,tmp); - Py_XDECREF(tmp); - return SWIG_NewPointerObj(SWIG_as_voidptr(ret.retn()),SWIGTYPE_p_ParaMEDMEM__MEDCouplingFieldDouble, SWIG_POINTER_OWN | 0 ); - } - else - throw INTERP_KERNEL::Exception(msg); - } -#endif - // - convertObjToPossibleCpp5(obj,sw,val,a,aa,bb); - switch(sw) - { - case 1: - { - MEDCouplingAutoRefCountObjectPtr ret=self->deepCpy(); - ret->applyLin(1.,-val); - return SWIG_NewPointerObj(SWIG_as_voidptr(ret.retn()),SWIGTYPE_p_ParaMEDMEM__DataArrayDouble, SWIG_POINTER_OWN | 0 ); - } - case 2: - { - return SWIG_NewPointerObj(SWIG_as_voidptr(DataArrayDouble::Substract(self,a)),SWIGTYPE_p_ParaMEDMEM__DataArrayDouble, SWIG_POINTER_OWN | 0 ); - } - case 3: - { - MEDCouplingAutoRefCountObjectPtr aaa=aa->buildDADouble(1,self->getNumberOfComponents()); - return SWIG_NewPointerObj(SWIG_as_voidptr(DataArrayDouble::Substract(self,aaa)),SWIGTYPE_p_ParaMEDMEM__DataArrayDouble, SWIG_POINTER_OWN | 0 ); - } - case 4: - { - MEDCouplingAutoRefCountObjectPtr aaa=DataArrayDouble::New(); aaa->useArray(&bb[0],false,CPP_DEALLOC,1,(int)bb.size()); - return SWIG_NewPointerObj(SWIG_as_voidptr(DataArrayDouble::Substract(self,aaa)),SWIGTYPE_p_ParaMEDMEM__DataArrayDouble, SWIG_POINTER_OWN | 0 ); - } - default: - throw INTERP_KERNEL::Exception(msg); - } - } - - DataArrayDouble *__rsub__(PyObject *obj) throw(INTERP_KERNEL::Exception) - { - const char msg[]="Unexpected situation in __rsub__ !"; - double val; - DataArrayDouble *a; - DataArrayDoubleTuple *aa; - std::vector bb; - int sw; - convertObjToPossibleCpp5(obj,sw,val,a,aa,bb); - switch(sw) - { - case 1: - { - MEDCouplingAutoRefCountObjectPtr ret=self->deepCpy(); - ret->applyLin(-1.,val); - return ret.retn(); - } - case 3: - { - MEDCouplingAutoRefCountObjectPtr aaa=aa->buildDADouble(1,self->getNumberOfComponents()); - return DataArrayDouble::Substract(aaa,self); - } - case 4: - { - MEDCouplingAutoRefCountObjectPtr aaa=DataArrayDouble::New(); aaa->useArray(&bb[0],false,CPP_DEALLOC,1,(int)bb.size()); - return DataArrayDouble::Substract(aaa,self); - } - default: - throw INTERP_KERNEL::Exception(msg); - } - } - - PyObject *___isub___(PyObject *trueSelf, PyObject *obj) throw(INTERP_KERNEL::Exception) - { - const char msg[]="Unexpected situation in __isub__ !"; - double val; - DataArrayDouble *a; - DataArrayDoubleTuple *aa; - std::vector bb; - int sw; - convertObjToPossibleCpp5(obj,sw,val,a,aa,bb); - switch(sw) - { - case 1: - { - self->applyLin(1,-val); - Py_XINCREF(trueSelf); - return trueSelf; - } - case 2: - { - self->substractEqual(a); - Py_XINCREF(trueSelf); - return trueSelf; - } - case 3: - { - MEDCouplingAutoRefCountObjectPtr aaa=aa->buildDADouble(1,self->getNumberOfComponents()); - self->substractEqual(aaa); - Py_XINCREF(trueSelf); - return trueSelf; - } - case 4: - { - MEDCouplingAutoRefCountObjectPtr aaa=DataArrayDouble::New(); aaa->useArray(&bb[0],false,CPP_DEALLOC,1,(int)bb.size()); - self->substractEqual(aaa); - Py_XINCREF(trueSelf); - return trueSelf; - } - default: - throw INTERP_KERNEL::Exception(msg); - } - } - - PyObject *__mul__(PyObject *obj) throw(INTERP_KERNEL::Exception) - { - const char msg[]="Unexpected situation in __mul__ !"; - double val; - DataArrayDouble *a; - DataArrayDoubleTuple *aa; - std::vector bb; - int sw; - // -#ifndef WITHOUT_AUTOFIELD - void *argp; - if(SWIG_IsOK(SWIG_ConvertPtr(obj,&argp,SWIGTYPE_p_ParaMEDMEM__MEDCouplingFieldDouble,0|0))) - { - MEDCouplingFieldDouble *other=reinterpret_cast< ParaMEDMEM::MEDCouplingFieldDouble * >(argp); - if(other) - { - PyObject *tmp=SWIG_NewPointerObj(SWIG_as_voidptr(self),SWIGTYPE_p_ParaMEDMEM__DataArrayDouble, 0 | 0 ); - MEDCouplingAutoRefCountObjectPtr ret=ParaMEDMEM_MEDCouplingFieldDouble___rmul__Impl(other,tmp); - Py_XDECREF(tmp); - return SWIG_NewPointerObj(SWIG_as_voidptr(ret.retn()),SWIGTYPE_p_ParaMEDMEM__MEDCouplingFieldDouble, SWIG_POINTER_OWN | 0 ); - } - else - throw INTERP_KERNEL::Exception(msg); - } -#endif - // - convertObjToPossibleCpp5(obj,sw,val,a,aa,bb); - switch(sw) - { - case 1: - { - MEDCouplingAutoRefCountObjectPtr ret=self->deepCpy(); - ret->applyLin(val,0.); - return SWIG_NewPointerObj(SWIG_as_voidptr(ret.retn()),SWIGTYPE_p_ParaMEDMEM__DataArrayDouble, SWIG_POINTER_OWN | 0 ); - } - case 2: - { - return SWIG_NewPointerObj(SWIG_as_voidptr(DataArrayDouble::Multiply(self,a)),SWIGTYPE_p_ParaMEDMEM__DataArrayDouble, SWIG_POINTER_OWN | 0 ); - } - case 3: - { - MEDCouplingAutoRefCountObjectPtr aaa=aa->buildDADouble(1,self->getNumberOfComponents()); - return SWIG_NewPointerObj(SWIG_as_voidptr(DataArrayDouble::Multiply(self,aaa)),SWIGTYPE_p_ParaMEDMEM__DataArrayDouble, SWIG_POINTER_OWN | 0 ); - } - case 4: - { - MEDCouplingAutoRefCountObjectPtr aaa=DataArrayDouble::New(); aaa->useArray(&bb[0],false,CPP_DEALLOC,1,(int)bb.size()); - return SWIG_NewPointerObj(SWIG_as_voidptr(DataArrayDouble::Multiply(self,aaa)),SWIGTYPE_p_ParaMEDMEM__DataArrayDouble, SWIG_POINTER_OWN | 0 ); - } - default: - throw INTERP_KERNEL::Exception(msg); - } - } - - DataArrayDouble *__rmul__(PyObject *obj) throw(INTERP_KERNEL::Exception) - { - const char msg[]="Unexpected situation in __rmul__ !"; - double val; - DataArrayDouble *a; - DataArrayDoubleTuple *aa; - std::vector bb; - int sw; - convertObjToPossibleCpp5(obj,sw,val,a,aa,bb); - switch(sw) - { - case 1: - { - MEDCouplingAutoRefCountObjectPtr ret=self->deepCpy(); - ret->applyLin(val,0.); - return ret.retn(); - } - case 3: - { - MEDCouplingAutoRefCountObjectPtr aaa=aa->buildDADouble(1,self->getNumberOfComponents()); - return DataArrayDouble::Multiply(self,aaa); - } - case 4: - { - MEDCouplingAutoRefCountObjectPtr aaa=DataArrayDouble::New(); aaa->useArray(&bb[0],false,CPP_DEALLOC,1,(int)bb.size()); - return DataArrayDouble::Multiply(self,aaa); - } - default: - throw INTERP_KERNEL::Exception(msg); - } - } - - PyObject *___imul___(PyObject *trueSelf, PyObject *obj) throw(INTERP_KERNEL::Exception) - { - const char msg[]="Unexpected situation in __imul__ !"; - double val; - DataArrayDouble *a; - DataArrayDoubleTuple *aa; - std::vector bb; - int sw; - convertObjToPossibleCpp5(obj,sw,val,a,aa,bb); - switch(sw) - { - case 1: - { - self->applyLin(val,0.); - Py_XINCREF(trueSelf); - return trueSelf; - } - case 2: - { - self->multiplyEqual(a); - Py_XINCREF(trueSelf); - return trueSelf; - } - case 3: - { - MEDCouplingAutoRefCountObjectPtr aaa=aa->buildDADouble(1,self->getNumberOfComponents()); - self->multiplyEqual(aaa); - Py_XINCREF(trueSelf); - return trueSelf; - } - case 4: - { - MEDCouplingAutoRefCountObjectPtr aaa=DataArrayDouble::New(); aaa->useArray(&bb[0],false,CPP_DEALLOC,1,(int)bb.size()); - self->multiplyEqual(aaa); - Py_XINCREF(trueSelf); - return trueSelf; - } - default: - throw INTERP_KERNEL::Exception(msg); - } - } - - PyObject *__div__(PyObject *obj) throw(INTERP_KERNEL::Exception) - { - const char msg[]="Unexpected situation in __div__ !"; - double val; - DataArrayDouble *a; - DataArrayDoubleTuple *aa; - std::vector bb; - int sw; - // -#ifndef WITHOUT_AUTOFIELD - void *argp; - if(SWIG_IsOK(SWIG_ConvertPtr(obj,&argp,SWIGTYPE_p_ParaMEDMEM__MEDCouplingFieldDouble,0|0))) - { - MEDCouplingFieldDouble *other=reinterpret_cast< ParaMEDMEM::MEDCouplingFieldDouble * >(argp); - if(other) - { - PyObject *tmp=SWIG_NewPointerObj(SWIG_as_voidptr(self),SWIGTYPE_p_ParaMEDMEM__DataArrayDouble, 0 | 0 ); - MEDCouplingAutoRefCountObjectPtr ret=ParaMEDMEM_MEDCouplingFieldDouble___rdiv__Impl(other,tmp); - Py_XDECREF(tmp); - return SWIG_NewPointerObj(SWIG_as_voidptr(ret.retn()),SWIGTYPE_p_ParaMEDMEM__MEDCouplingFieldDouble, SWIG_POINTER_OWN | 0 ); - } - else - throw INTERP_KERNEL::Exception(msg); - } -#endif - // - convertObjToPossibleCpp5(obj,sw,val,a,aa,bb); - switch(sw) - { - case 1: - { - if(val==0.) - throw INTERP_KERNEL::Exception("DataArrayDouble::__div__ : trying to divide by zero !"); - MEDCouplingAutoRefCountObjectPtr ret=self->deepCpy(); - ret->applyLin(1/val,0.); - return SWIG_NewPointerObj(SWIG_as_voidptr(ret.retn()),SWIGTYPE_p_ParaMEDMEM__DataArrayDouble, SWIG_POINTER_OWN | 0 ); - } - case 2: - { - return SWIG_NewPointerObj(SWIG_as_voidptr(DataArrayDouble::Divide(self,a)),SWIGTYPE_p_ParaMEDMEM__DataArrayDouble, SWIG_POINTER_OWN | 0 ); - } - case 3: - { - MEDCouplingAutoRefCountObjectPtr aaa=aa->buildDADouble(1,self->getNumberOfComponents()); - return SWIG_NewPointerObj(SWIG_as_voidptr(DataArrayDouble::Divide(self,aaa)),SWIGTYPE_p_ParaMEDMEM__DataArrayDouble, SWIG_POINTER_OWN | 0 ); - } - case 4: - { - MEDCouplingAutoRefCountObjectPtr aaa=DataArrayDouble::New(); aaa->useArray(&bb[0],false,CPP_DEALLOC,1,(int)bb.size()); - return SWIG_NewPointerObj(SWIG_as_voidptr(DataArrayDouble::Divide(self,aaa)),SWIGTYPE_p_ParaMEDMEM__DataArrayDouble, SWIG_POINTER_OWN | 0 ); - } - default: - throw INTERP_KERNEL::Exception(msg); - } - } - - DataArrayDouble *__rdiv__(PyObject *obj) throw(INTERP_KERNEL::Exception) - { - const char msg[]="Unexpected situation in __rdiv__ !"; - double val; - DataArrayDouble *a; - DataArrayDoubleTuple *aa; - std::vector bb; - int sw; - convertObjToPossibleCpp5(obj,sw,val,a,aa,bb); - switch(sw) - { - case 1: - { - MEDCouplingAutoRefCountObjectPtr ret=self->deepCpy(); - ret->applyInv(val); - return ret.retn(); - } - case 3: - { - MEDCouplingAutoRefCountObjectPtr aaa=aa->buildDADouble(1,self->getNumberOfComponents()); - return DataArrayDouble::Divide(aaa,self); - } - case 4: - { - MEDCouplingAutoRefCountObjectPtr aaa=DataArrayDouble::New(); aaa->useArray(&bb[0],false,CPP_DEALLOC,1,(int)bb.size()); - return DataArrayDouble::Divide(aaa,self); - } - default: - throw INTERP_KERNEL::Exception(msg); - } - } - - PyObject *___idiv___(PyObject *trueSelf, PyObject *obj) throw(INTERP_KERNEL::Exception) - { - const char msg[]="Unexpected situation in __idiv__ !"; - double val; - DataArrayDouble *a; - DataArrayDoubleTuple *aa; - std::vector bb; - int sw; - convertObjToPossibleCpp5(obj,sw,val,a,aa,bb); - switch(sw) - { - case 1: - { - if(val==0.) - throw INTERP_KERNEL::Exception("DataArrayDouble::__div__ : trying to divide by zero !"); - self->applyLin(1./val,0.); - Py_XINCREF(trueSelf); - return trueSelf; - } - case 2: - { - self->divideEqual(a); - Py_XINCREF(trueSelf); - return trueSelf; - } - case 3: - { - MEDCouplingAutoRefCountObjectPtr aaa=aa->buildDADouble(1,self->getNumberOfComponents()); - self->divideEqual(aaa); - Py_XINCREF(trueSelf); - return trueSelf; - } - case 4: - { - MEDCouplingAutoRefCountObjectPtr aaa=DataArrayDouble::New(); aaa->useArray(&bb[0],false,CPP_DEALLOC,1,(int)bb.size()); - self->divideEqual(aaa); - Py_XINCREF(trueSelf); - return trueSelf; - } - default: - throw INTERP_KERNEL::Exception(msg); - } - } - - DataArrayDouble *__pow__(PyObject *obj) throw(INTERP_KERNEL::Exception) - { - const char msg[]="Unexpected situation in __pow__ !"; - double val; - DataArrayDouble *a; - DataArrayDoubleTuple *aa; - std::vector bb; - int sw; - convertObjToPossibleCpp5(obj,sw,val,a,aa,bb); - switch(sw) - { - case 1: - { - MEDCouplingAutoRefCountObjectPtr ret=self->deepCpy(); - ret->applyPow(val); - return ret.retn(); - } - case 2: - { - return DataArrayDouble::Pow(self,a); - } - case 3: - { - MEDCouplingAutoRefCountObjectPtr aaa=aa->buildDADouble(1,self->getNumberOfComponents()); - return DataArrayDouble::Pow(self,aaa); - } - case 4: - { - MEDCouplingAutoRefCountObjectPtr aaa=DataArrayDouble::New(); aaa->useArray(&bb[0],false,CPP_DEALLOC,1,(int)bb.size()); - return DataArrayDouble::Pow(self,aaa); - } - default: - throw INTERP_KERNEL::Exception(msg); - } - } - - DataArrayDouble *__rpow__(PyObject *obj) throw(INTERP_KERNEL::Exception) - { - const char msg[]="Unexpected situation in __rpow__ !"; - double val; - DataArrayDouble *a; - DataArrayDoubleTuple *aa; - std::vector bb; - int sw; - convertObjToPossibleCpp5(obj,sw,val,a,aa,bb); - switch(sw) - { - case 1: - { - MEDCouplingAutoRefCountObjectPtr ret=self->deepCpy(); - ret->applyRPow(val); - return ret.retn(); - } - case 3: - { - MEDCouplingAutoRefCountObjectPtr aaa=aa->buildDADouble(1,self->getNumberOfComponents()); - return DataArrayDouble::Pow(aaa,self); - } - case 4: - { - MEDCouplingAutoRefCountObjectPtr aaa=DataArrayDouble::New(); aaa->useArray(&bb[0],false,CPP_DEALLOC,1,(int)bb.size()); - return DataArrayDouble::Pow(aaa,self); - } - default: - throw INTERP_KERNEL::Exception(msg); - } - } - - PyObject *___ipow___(PyObject *trueSelf, PyObject *obj) throw(INTERP_KERNEL::Exception) - { - const char msg[]="Unexpected situation in __ipow__ !"; - double val; - DataArrayDouble *a; - DataArrayDoubleTuple *aa; - std::vector bb; - int sw; - convertObjToPossibleCpp5(obj,sw,val,a,aa,bb); - switch(sw) - { - case 1: - { - self->applyPow(val); - Py_XINCREF(trueSelf); - return trueSelf; - } - case 2: - { - self->powEqual(a); - Py_XINCREF(trueSelf); - return trueSelf; - } - case 3: - { - MEDCouplingAutoRefCountObjectPtr aaa=aa->buildDADouble(1,self->getNumberOfComponents()); - self->powEqual(aaa); - Py_XINCREF(trueSelf); - return trueSelf; - } - case 4: - { - MEDCouplingAutoRefCountObjectPtr aaa=DataArrayDouble::New(); aaa->useArray(&bb[0],false,CPP_DEALLOC,1,(int)bb.size()); - self->powEqual(aaa); - Py_XINCREF(trueSelf); - return trueSelf; - } - default: - throw INTERP_KERNEL::Exception(msg); - } - } - - PyObject *computeTupleIdsNearTuples(const DataArrayDouble *other, double eps) - { - DataArrayInt *c=0,*cI=0; - // - self->computeTupleIdsNearTuples(other,eps,c,cI); - PyObject *ret=PyTuple_New(2); - PyTuple_SetItem(ret,0,SWIG_NewPointerObj(SWIG_as_voidptr(c),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 )); - PyTuple_SetItem(ret,1,SWIG_NewPointerObj(SWIG_as_voidptr(cI),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 )); - return ret; - } - - PyObject *maxPerTupleWithCompoId() const throw(INTERP_KERNEL::Exception) - { - DataArrayInt *ret1=0; - DataArrayDouble *ret0=self->maxPerTupleWithCompoId(ret1); - PyObject *ret=PyTuple_New(2); - PyTuple_SetItem(ret,0,SWIG_NewPointerObj(SWIG_as_voidptr(ret0),SWIGTYPE_p_ParaMEDMEM__DataArrayDouble, SWIG_POINTER_OWN | 0 )); - PyTuple_SetItem(ret,1,SWIG_NewPointerObj(SWIG_as_voidptr(ret1),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 )); - return ret; - } - - // serialization - static PyObject *___new___(PyObject *cls, PyObject *args) throw(INTERP_KERNEL::Exception) - { - static const char MSG[]="DataArrayDouble.__new__ : the args in input is expected to be a tuple !"; - if(!PyTuple_Check(args)) - throw INTERP_KERNEL::Exception(MSG); - PyObject *builtinsd(PyEval_GetBuiltins());//borrowed - PyObject *obj(PyDict_GetItemString(builtinsd,"object"));//borrowed - PyObject *selfMeth(PyObject_GetAttrString(obj,"__new__")); - // - PyObject *tmp0(PyTuple_New(1)); - PyTuple_SetItem(tmp0,0,cls); Py_XINCREF(cls); - PyObject *instance(PyObject_CallObject(selfMeth,tmp0)); - Py_DECREF(tmp0); - Py_DECREF(selfMeth); - PyObject *initMeth(PyObject_GetAttrString(instance,"__init__")); - int sz(PyTuple_Size(args)); - - if(PyTuple_Size(args)==2 && PyDict_Check(PyTuple_GetItem(args,1)) && PyDict_Size(PyTuple_GetItem(args,1))==1 ) - {// NOT general case. only true if in unpickeling context ! call __init__. Because for all other cases, __init__ is called right after __new__ ! - PyObject *zeNumpyRepr(0); - PyObject *tmp1(PyInt_FromLong(0)); - zeNumpyRepr=PyDict_GetItem(PyTuple_GetItem(args,1),tmp1);//borrowed - Py_DECREF(tmp1); - PyObject *tmp3(PyTuple_New(1)); - PyTuple_SetItem(tmp3,0,zeNumpyRepr); Py_XINCREF(zeNumpyRepr); - PyObject *tmp2(PyObject_CallObject(initMeth,tmp3)); - Py_XDECREF(tmp2); - Py_DECREF(tmp3); - } - Py_DECREF(initMeth); - return instance; - } - - PyObject *__getnewargs__() throw(INTERP_KERNEL::Exception) - { -#ifdef WITH_NUMPY - if(!self->isAllocated()) - throw INTERP_KERNEL::Exception("PyWrap of DataArrayDouble.__getnewargs__ : self is not allocated !"); - PyObject *ret(PyTuple_New(1)); - PyObject *ret0(PyDict_New()); - PyObject *numpyArryObj(ParaMEDMEM_DataArrayDouble_toNumPyArray(self)); - {// create a dict to discriminite in __new__ if __init__ should be called. Not beautiful but not idea ... - PyObject *tmp1(PyInt_FromLong(0)); - PyDict_SetItem(ret0,tmp1,numpyArryObj); Py_DECREF(tmp1); Py_DECREF(numpyArryObj); - PyTuple_SetItem(ret,0,ret0); - } - return ret; -#else - throw INTERP_KERNEL::Exception("PyWrap of DataArrayDouble.__getnewargs__ : not implemented because numpy is not active in your configuration ! No serialization/unserialization available without numpy !"); -#endif - } - } - }; - - class DataArrayDoubleTuple; - - class DataArrayDoubleIterator - { - public: - DataArrayDoubleIterator(DataArrayDouble *da); - ~DataArrayDoubleIterator(); - %extend - { - PyObject *next() - { - DataArrayDoubleTuple *ret=self->nextt(); - if(ret) - return SWIG_NewPointerObj(SWIG_as_voidptr(ret),SWIGTYPE_p_ParaMEDMEM__DataArrayDoubleTuple,SWIG_POINTER_OWN|0); - else - { - PyErr_SetString(PyExc_StopIteration,"No more data."); - return 0; - } - } - } - }; - - class DataArrayDoubleTuple - { - public: - int getNumberOfCompo() const throw(INTERP_KERNEL::Exception); - DataArrayDouble *buildDADouble(int nbOfTuples, int nbOfCompo) const throw(INTERP_KERNEL::Exception); - %extend - { - std::string __str__() const throw(INTERP_KERNEL::Exception) - { - return self->repr(); - } - - double __float__() const throw(INTERP_KERNEL::Exception) - { - return self->doubleValue(); - } - - DataArrayDouble *buildDADouble() throw(INTERP_KERNEL::Exception) - { - return self->buildDADouble(1,self->getNumberOfCompo()); - } - - PyObject *___iadd___(PyObject *trueSelf, PyObject *obj) throw(INTERP_KERNEL::Exception) - { - MEDCouplingAutoRefCountObjectPtr ret=self->buildDADouble(1,self->getNumberOfCompo()); - ParaMEDMEM_DataArrayDouble____iadd___(ret,0,obj); - Py_XINCREF(trueSelf); - return trueSelf; - } - - PyObject *___isub___(PyObject *trueSelf, PyObject *obj) throw(INTERP_KERNEL::Exception) - { - MEDCouplingAutoRefCountObjectPtr ret=self->buildDADouble(1,self->getNumberOfCompo()); - ParaMEDMEM_DataArrayDouble____isub___(ret,0,obj); - Py_XINCREF(trueSelf); - return trueSelf; - } - - PyObject *___imul___(PyObject *trueSelf, PyObject *obj) throw(INTERP_KERNEL::Exception) - { - MEDCouplingAutoRefCountObjectPtr ret=self->buildDADouble(1,self->getNumberOfCompo()); - ParaMEDMEM_DataArrayDouble____imul___(ret,0,obj); - Py_XINCREF(trueSelf); - return trueSelf; - } - - PyObject *___idiv___(PyObject *trueSelf, PyObject *obj) throw(INTERP_KERNEL::Exception) - { - MEDCouplingAutoRefCountObjectPtr ret=self->buildDADouble(1,self->getNumberOfCompo()); - ParaMEDMEM_DataArrayDouble____idiv___(ret,0,obj); - Py_XINCREF(trueSelf); - return trueSelf; - } - - PyObject *__len__() throw(INTERP_KERNEL::Exception) - { - return PyInt_FromLong(self->getNumberOfCompo()); - } - - PyObject *__getitem__(PyObject *obj) throw(INTERP_KERNEL::Exception) - { - const char msg2[]="DataArrayDoubleTuple::__getitem__ : Mismatch of slice values in 2nd parameter (components) !"; - int sw; - int singleVal; - std::vector multiVal; - std::pair > slic; - ParaMEDMEM::DataArrayInt *daIntTyypp=0; - const double *pt=self->getConstPointer(); - int nbc=self->getNumberOfCompo(); - convertObjToPossibleCpp2WithNegIntInterp(obj,nbc,sw,singleVal,multiVal,slic,daIntTyypp); - switch(sw) - { - case 1: - { - if(singleVal>=nbc) - { - std::ostringstream oss; - oss << "Requesting for id " << singleVal << " having only " << nbc << " components !"; - PyErr_SetString(PyExc_StopIteration,oss.str().c_str()); - return 0; - } - if(singleVal>=0) - return PyFloat_FromDouble(pt[singleVal]); - else - { - if(nbc+singleVal>0) - return PyFloat_FromDouble(pt[nbc+singleVal]); - else - { - std::ostringstream oss; - oss << "Requesting for id " << singleVal << " having only " << nbc << " components !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - } - } - case 2: - { - PyObject *t=PyTuple_New(multiVal.size()); - for(int j=0;j<(int)multiVal.size();j++) - { - int cid=multiVal[j]; - if(cid>=nbc) - { - std::ostringstream oss; - oss << "Requesting for id #" << cid << " having only " << nbc << " components !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - PyTuple_SetItem(t,j,PyFloat_FromDouble(pt[cid])); - } - return t; - } - case 3: - { - int sz=DataArray::GetNumberOfItemGivenBES(slic.first,slic.second.first,slic.second.second,msg2); - PyObject *t=PyTuple_New(sz); - for(int j=0;j multiValV; - ParaMEDMEM::DataArrayDoubleTuple *daIntTyyppV=0; - int nbc=self->getNumberOfCompo(); - convertObjToPossibleCpp44(value,sw1,singleValV,multiValV,daIntTyyppV); - int singleVal; - std::vector multiVal; - std::pair > slic; - ParaMEDMEM::DataArrayInt *daIntTyypp=0; - double *pt=self->getPointer(); - convertObjToPossibleCpp2WithNegIntInterp(obj,nbc,sw2,singleVal,multiVal,slic,daIntTyypp); - switch(sw2) - { - case 1: - { - if(singleVal>=nbc) - { - std::ostringstream oss; - oss << "Requesting for setting id # " << singleVal << " having only " << nbc << " components !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - switch(sw1) - { - case 1: - { - pt[singleVal]=singleValV; - return self; - } - case 2: - { - if(multiValV.size()!=1) - { - std::ostringstream oss; - oss << "Requesting for setting id # " << singleVal << " with a list or tuple with size != 1 ! "; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - pt[singleVal]=multiValV[0]; - return self; - } - case 3: - { - pt[singleVal]=daIntTyyppV->getConstPointer()[0]; - return self; - } - default: - throw INTERP_KERNEL::Exception(msg); - } - } - case 2: - { - switch(sw1) - { - case 1: - { - for(std::vector::const_iterator it=multiVal.begin();it!=multiVal.end();it++) - { - if(*it>=nbc) - { - std::ostringstream oss; - oss << "Requesting for setting id # " << *it << " having only " << nbc << " components !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - pt[*it]=singleValV; - } - return self; - } - case 2: - { - if(multiVal.size()!=multiValV.size()) - { - std::ostringstream oss; - oss << "Mismatch length of during assignment : " << multiValV.size() << " != " << multiVal.size() << " !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - for(int i=0;i<(int)multiVal.size();i++) - { - int pos=multiVal[i]; - if(pos>=nbc) - { - std::ostringstream oss; - oss << "Requesting for setting id # " << pos << " having only " << nbc << " components !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - pt[multiVal[i]]=multiValV[i]; - } - return self; - } - case 3: - { - const double *ptV=daIntTyyppV->getConstPointer(); - if(nbc>daIntTyyppV->getNumberOfCompo()) - { - std::ostringstream oss; - oss << "Mismatch length of during assignment : " << nbc << " != " << daIntTyyppV->getNumberOfCompo() << " !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - std::copy(ptV,ptV+nbc,pt); - return self; - } - default: - throw INTERP_KERNEL::Exception(msg); - } - } - case 3: - { - int sz=DataArray::GetNumberOfItemGivenBES(slic.first,slic.second.first,slic.second.second,msg2); - switch(sw1) - { - case 1: - { - for(int j=0;jgetConstPointer(); - if(sz>daIntTyyppV->getNumberOfCompo()) - { - std::ostringstream oss; - oss << "Mismatch length of during assignment : " << nbc << " != " << daIntTyyppV->getNumberOfCompo() << " !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - for(int j=0;j& tupl) const throw(INTERP_KERNEL::Exception); - int locateValue(int value) const throw(INTERP_KERNEL::Exception); - int locateValue(const std::vector& vals) const throw(INTERP_KERNEL::Exception); - int search(const std::vector& vals) const throw(INTERP_KERNEL::Exception); - bool presenceOfTuple(const std::vector& tupl) const throw(INTERP_KERNEL::Exception); - bool presenceOfValue(int value) const throw(INTERP_KERNEL::Exception); - bool presenceOfValue(const std::vector& vals) const throw(INTERP_KERNEL::Exception); - int count(int value) const throw(INTERP_KERNEL::Exception); - int accumulate(int compId) const throw(INTERP_KERNEL::Exception); - int getMaxValue(int& tupleId) const throw(INTERP_KERNEL::Exception); - int getMaxValueInArray() const throw(INTERP_KERNEL::Exception); - int getMinValue(int& tupleId) const throw(INTERP_KERNEL::Exception); - int getMinValueInArray() const throw(INTERP_KERNEL::Exception); - void abs() throw(INTERP_KERNEL::Exception); - DataArrayInt *computeAbs() const throw(INTERP_KERNEL::Exception); - void applyLin(int a, int b, int compoId) throw(INTERP_KERNEL::Exception); - void applyLin(int a, int b) throw(INTERP_KERNEL::Exception); - void applyInv(int numerator) throw(INTERP_KERNEL::Exception); - DataArrayInt *negate() const throw(INTERP_KERNEL::Exception); - void applyDivideBy(int val) throw(INTERP_KERNEL::Exception); - void applyModulus(int val) throw(INTERP_KERNEL::Exception); - void applyRModulus(int val) throw(INTERP_KERNEL::Exception); - void applyPow(int val) throw(INTERP_KERNEL::Exception); - void applyRPow(int val) throw(INTERP_KERNEL::Exception); - DataArrayInt *getIdsInRange(int vmin, int vmax) const throw(INTERP_KERNEL::Exception); - DataArrayInt *getIdsNotInRange(int vmin, int vmax) const throw(INTERP_KERNEL::Exception); - DataArrayInt *getIdsStrictlyNegative() const throw(INTERP_KERNEL::Exception); - bool checkAllIdsInRange(int vmin, int vmax) const throw(INTERP_KERNEL::Exception); - static DataArrayInt *Aggregate(const DataArrayInt *a1, const DataArrayInt *a2, int offsetA2) throw(INTERP_KERNEL::Exception); - static DataArrayInt *Meld(const DataArrayInt *a1, const DataArrayInt *a2) throw(INTERP_KERNEL::Exception); - static DataArrayInt *MakePartition(const std::vector& groups, int newNb, std::vector< std::vector >& fidsOfGroups) throw(INTERP_KERNEL::Exception); - static DataArrayInt *BuildUnion(const std::vector& arr) throw(INTERP_KERNEL::Exception); - static DataArrayInt *BuildIntersection(const std::vector& arr) throw(INTERP_KERNEL::Exception); - static DataArrayInt *FindPermutationFromFirstToSecond(const DataArrayInt *ids1, const DataArrayInt *ids2) throw(INTERP_KERNEL::Exception); - DataArrayInt *buildComplement(int nbOfElement) const throw(INTERP_KERNEL::Exception); - DataArrayInt *buildSubstraction(const DataArrayInt *other) const throw(INTERP_KERNEL::Exception); - DataArrayInt *buildSubstractionOptimized(const DataArrayInt *other) const throw(INTERP_KERNEL::Exception); - DataArrayInt *buildUnion(const DataArrayInt *other) const throw(INTERP_KERNEL::Exception); - DataArrayInt *buildIntersection(const DataArrayInt *other) const throw(INTERP_KERNEL::Exception); - DataArrayInt *buildUnique() const throw(INTERP_KERNEL::Exception); - DataArrayInt *buildUniqueNotSorted() const throw(INTERP_KERNEL::Exception); - DataArrayInt *deltaShiftIndex() const throw(INTERP_KERNEL::Exception); - void computeOffsets() throw(INTERP_KERNEL::Exception); - void computeOffsets2() throw(INTERP_KERNEL::Exception); - DataArrayInt *buildExplicitArrByRanges(const DataArrayInt *offsets) const throw(INTERP_KERNEL::Exception); - DataArrayInt *findRangeIdForEachTuple(const DataArrayInt *ranges) const throw(INTERP_KERNEL::Exception); - DataArrayInt *findIdInRangeForEachTuple(const DataArrayInt *ranges) const throw(INTERP_KERNEL::Exception); - void sortEachPairToMakeALinkedList() throw(INTERP_KERNEL::Exception); - DataArrayInt *duplicateEachTupleNTimes(int nbTimes) const throw(INTERP_KERNEL::Exception); - DataArrayInt *getDifferentValues() const throw(INTERP_KERNEL::Exception); - static DataArrayInt *Add(const DataArrayInt *a1, const DataArrayInt *a2) throw(INTERP_KERNEL::Exception); - void addEqual(const DataArrayInt *other) throw(INTERP_KERNEL::Exception); - static DataArrayInt *Substract(const DataArrayInt *a1, const DataArrayInt *a2) throw(INTERP_KERNEL::Exception); - void substractEqual(const DataArrayInt *other) throw(INTERP_KERNEL::Exception); - static DataArrayInt *Multiply(const DataArrayInt *a1, const DataArrayInt *a2) throw(INTERP_KERNEL::Exception); - void multiplyEqual(const DataArrayInt *other) throw(INTERP_KERNEL::Exception); - static DataArrayInt *Divide(const DataArrayInt *a1, const DataArrayInt *a2) throw(INTERP_KERNEL::Exception); - void divideEqual(const DataArrayInt *other) throw(INTERP_KERNEL::Exception); - static DataArrayInt *Modulus(const DataArrayInt *a1, const DataArrayInt *a2) throw(INTERP_KERNEL::Exception); - void modulusEqual(const DataArrayInt *other) throw(INTERP_KERNEL::Exception); - static DataArrayInt *Pow(const DataArrayInt *a1, const DataArrayInt *a2) throw(INTERP_KERNEL::Exception); - void powEqual(const DataArrayInt *other) throw(INTERP_KERNEL::Exception); - public: - static DataArrayInt *Range(int begin, int end, int step) throw(INTERP_KERNEL::Exception); - %extend - { - DataArrayInt() throw(INTERP_KERNEL::Exception) - { - return DataArrayInt::New(); - } - - static DataArrayInt *New(PyObject *elt0, PyObject *nbOfTuples=0, PyObject *nbOfComp=0) throw(INTERP_KERNEL::Exception) - { - const char *msgBase="ParaMEDMEM::DataArrayInt::New : Available API are : \n-DataArrayInt.New()\n-DataArrayInt.New([1,3,4])\n-DataArrayInt.New([1,3,4],3)\n-DataArrayInt.New([1,3,4,5],2,2)\n-DataArrayInt.New([1,3,4,5,7,8],3,2)\n-DataArrayInt.New([(1,3),(4,5),(7,8)])\n-DataArrayInt.New(5)\n-DataArrayInt.New(5,2)"; - std::string msg(msgBase); -#ifdef WITH_NUMPY - msg+="\n-DataArrayInt.New(numpy array with dtype=int32)"; -#endif - msg+=" !"; - if(PyList_Check(elt0) || PyTuple_Check(elt0)) - { - if(nbOfTuples) - { - if(PyInt_Check(nbOfTuples)) - { - int nbOfTuples1=PyInt_AS_LONG(nbOfTuples); - if(nbOfTuples1<0) - throw INTERP_KERNEL::Exception("DataArrayInt::New : should be a positive set of allocated memory !"); - if(nbOfComp) - { - if(PyInt_Check(nbOfComp)) - {//DataArrayInt.New([1,3,4,5],2,2) - int nbOfCompo=PyInt_AS_LONG(nbOfComp); - if(nbOfCompo<0) - throw INTERP_KERNEL::Exception("DataArrayInt::New : should be a positive number of components !"); - MEDCouplingAutoRefCountObjectPtr ret=DataArrayInt::New(); - std::vector tmp=fillArrayWithPyListInt2(elt0,nbOfTuples1,nbOfCompo); - ret->alloc(nbOfTuples1,nbOfCompo); std::copy(tmp.begin(),tmp.end(),ret->getPointer()); - return ret.retn(); - } - else - throw INTERP_KERNEL::Exception(msg.c_str()); - } - else - {//DataArrayInt.New([1,3,4],3) - MEDCouplingAutoRefCountObjectPtr ret=DataArrayInt::New(); - int tmpp1=-1; - std::vector tmp=fillArrayWithPyListInt2(elt0,nbOfTuples1,tmpp1); - ret->alloc(nbOfTuples1,tmpp1); std::copy(tmp.begin(),tmp.end(),ret->getPointer()); - return ret.retn(); - } - } - else - throw INTERP_KERNEL::Exception(msg.c_str()); - } - else - {// DataArrayInt.New([1,3,4]) - MEDCouplingAutoRefCountObjectPtr ret=DataArrayInt::New(); - int tmpp1=-1,tmpp2=-1; - std::vector tmp=fillArrayWithPyListInt2(elt0,tmpp1,tmpp2); - ret->alloc(tmpp1,tmpp2); std::copy(tmp.begin(),tmp.end(),ret->getPointer()); - return ret.retn(); - } - } - else if(PyInt_Check(elt0)) - { - int nbOfTuples1=PyInt_AS_LONG(elt0); - if(nbOfTuples1<0) - throw INTERP_KERNEL::Exception("DataArrayInt::New : should be a positive set of allocated memory !"); - if(nbOfTuples) - { - if(!nbOfComp) - { - if(PyInt_Check(nbOfTuples)) - {//DataArrayInt.New(5,2) - int nbOfCompo=PyInt_AS_LONG(nbOfTuples); - if(nbOfCompo<0) - throw INTERP_KERNEL::Exception("DataArrayInt::New : should be a positive number of components !"); - MEDCouplingAutoRefCountObjectPtr ret=DataArrayInt::New(); - ret->alloc(nbOfTuples1,nbOfCompo); - return ret.retn(); - } - else - throw INTERP_KERNEL::Exception(msg.c_str()); - } - else - throw INTERP_KERNEL::Exception(msg.c_str()); - } - else - {//DataArrayInt.New(5) - MEDCouplingAutoRefCountObjectPtr ret=DataArrayInt::New(); - ret->alloc(nbOfTuples1,1); - return ret.retn(); - } - } -#ifdef WITH_NUMPY - else if(PyArray_Check(elt0) && nbOfTuples==NULL && nbOfComp==NULL) - {//DataArrayInt.New(numpyArray) - return BuildNewInstance(elt0,NPY_INT32,&PyCallBackDataArrayInt_RefType,"INT32"); - } -#endif - else - throw INTERP_KERNEL::Exception(msg.c_str()); - throw INTERP_KERNEL::Exception(msg.c_str());//to make g++ happy - } - - DataArrayInt(PyObject *elt0, PyObject *nbOfTuples=0, PyObject *nbOfComp=0) throw(INTERP_KERNEL::Exception) - { - return ParaMEDMEM_DataArrayInt_New__SWIG_1(elt0,nbOfTuples,nbOfComp); - } - - std::string __str__() const throw(INTERP_KERNEL::Exception) - { - return self->reprNotTooLong(); - } - - int __len__() const throw(INTERP_KERNEL::Exception) - { - if(self->isAllocated()) - { - return self->getNumberOfTuples(); - } - else - { - throw INTERP_KERNEL::Exception("DataArrayInt::__len__ : Instance is NOT allocated !"); - } - } - - int __int__() const throw(INTERP_KERNEL::Exception) - { - return self->intValue(); - } - - DataArrayIntIterator *__iter__() throw(INTERP_KERNEL::Exception) - { - return self->iterator(); - } - - PyObject *accumulate() const throw(INTERP_KERNEL::Exception) - { - int sz=self->getNumberOfComponents(); - INTERP_KERNEL::AutoPtr tmp=new int[sz]; - self->accumulate(tmp); - return convertIntArrToPyList(tmp,sz); - } - - DataArrayInt *accumulatePerChunck(PyObject *indexArr) const throw(INTERP_KERNEL::Exception) - { - int sw,sz,val; - std::vector val2; - const int *bg=convertObjToPossibleCpp1_Safe(indexArr,sw,sz,val,val2); - return self->accumulatePerChunck(bg,bg+sz); - } - - DataArrayInt *getIdsEqualTuple(PyObject *inputTuple) const throw(INTERP_KERNEL::Exception) - { - int sw,sz,val; - std::vector val2; - const int *bg(convertObjToPossibleCpp1_Safe(inputTuple,sw,sz,val,val2)); - return self->getIdsEqualTuple(bg,bg+sz); - } - - PyObject *splitInBalancedSlices(int nbOfSlices) const throw(INTERP_KERNEL::Exception) - { - std::vector< std::pair > slcs(self->splitInBalancedSlices(nbOfSlices)); - PyObject *ret=PyList_New(slcs.size()); - for(std::size_t i=0;i(slic); - GetIndicesOfSliceExplicitely(sly,&strt,&stp,&step,"DataArrayInt::buildExplicitArrOfSliceOnScaledArr (wrap) : the input slice is invalid !"); - if(strt==std::numeric_limits::max() || stp==std::numeric_limits::max()) - throw INTERP_KERNEL::Exception("DataArrayInt::buildExplicitArrOfSliceOnScaledArr (wrap) : the input slice contains some unknowns that can't be determined in static method ! Call DataArray::getSlice (non static) instead !"); - return self->buildExplicitArrOfSliceOnScaledArr(strt,stp,step); - } - - PyObject *getMinMaxValues() const throw(INTERP_KERNEL::Exception) - { - int a,b; - self->getMinMaxValues(a,b); - PyObject *ret=PyTuple_New(2); - PyTuple_SetItem(ret,0,PyInt_FromLong(a)); - PyTuple_SetItem(ret,1,PyInt_FromLong(b)); - return ret; - } - - static PyObject *BuildOld2NewArrayFromSurjectiveFormat2(int nbOfOldTuples, PyObject *arr, PyObject *arrI) throw(INTERP_KERNEL::Exception) - { - int newNbOfTuples=-1; - int szArr,szArrI,sw,iTypppArr,iTypppArrI; - std::vector stdvecTyyppArr,stdvecTyyppArrI; - const int *arrPtr=convertObjToPossibleCpp1_Safe(arr,sw,szArr,iTypppArr,stdvecTyyppArr); - const int *arrIPtr=convertObjToPossibleCpp1_Safe(arrI,sw,szArrI,iTypppArrI,stdvecTyyppArrI); - DataArrayInt *ret0=ParaMEDMEM::DataArrayInt::BuildOld2NewArrayFromSurjectiveFormat2(nbOfOldTuples,arrPtr,arrIPtr,arrIPtr+szArrI,newNbOfTuples); - PyObject *ret=PyTuple_New(2); - PyTuple_SetItem(ret,0,SWIG_NewPointerObj((void*)ret0,SWIGTYPE_p_ParaMEDMEM__DataArrayInt,SWIG_POINTER_OWN | 0)); - PyTuple_SetItem(ret,1,PyInt_FromLong(newNbOfTuples)); - return ret; - } - - static DataArrayInt *CheckAndPreparePermutation(PyObject *arr) throw(INTERP_KERNEL::Exception) - { - MEDCouplingAutoRefCountObjectPtr ret(DataArrayInt::New()); - int szArr,sw,iTypppArr; - std::vector stdvecTyyppArr; - const int *arrPtr(convertObjToPossibleCpp1_Safe(arr,sw,szArr,iTypppArr,stdvecTyyppArr)); - int *pt(ParaMEDMEM::DataArrayInt::CheckAndPreparePermutation(arrPtr,arrPtr+szArr)); - ret->useArray(pt,true,ParaMEDMEM::C_DEALLOC,szArr,1); - return ret.retn(); - } - - void setValues(PyObject *li, PyObject *nbOfTuples=0, PyObject *nbOfComp=0) throw(INTERP_KERNEL::Exception) - { - const char *msg="ParaMEDMEM::DataArrayInt::setValues : Available API are : \n-DataArrayInt.setValues([1,3,4])\n-DataArrayInt.setValues([1,3,4],3)\n-DataArrayInt.setValues([1,3,4,5],2,2)\n-DataArrayInt.New(5)\n !"; - if(PyList_Check(li) || PyTuple_Check(li)) - { - if(nbOfTuples) - { - if(PyInt_Check(nbOfTuples)) - { - int nbOfTuples1=PyInt_AS_LONG(nbOfTuples); - if(nbOfTuples<0) - throw INTERP_KERNEL::Exception("DataArrayInt::setValue : should be a positive set of allocated memory !"); - if(nbOfComp) - { - if(PyInt_Check(nbOfComp)) - {//DataArrayInt.setValues([1,3,4,5],2,2) - int nbOfCompo=PyInt_AS_LONG(nbOfComp); - if(nbOfCompo<0) - throw INTERP_KERNEL::Exception("DataArrayInt::setValue : should be a positive number of components !"); - std::vector tmp=fillArrayWithPyListInt2(li,nbOfTuples1,nbOfCompo); - self->alloc(nbOfTuples1,nbOfCompo); std::copy(tmp.begin(),tmp.end(),self->getPointer()); - } - else - throw INTERP_KERNEL::Exception(msg); - } - else - {//DataArrayInt.setValues([1,3,4],3) - int tmpp1=-1; - std::vector tmp=fillArrayWithPyListInt2(li,nbOfTuples1,tmpp1); - self->alloc(nbOfTuples1,tmpp1); std::copy(tmp.begin(),tmp.end(),self->getPointer()); - } - } - else - throw INTERP_KERNEL::Exception(msg); - } - else - {// DataArrayInt.setValues([1,3,4]) - int tmpp1=-1,tmpp2=-1; - std::vector tmp=fillArrayWithPyListInt2(li,tmpp1,tmpp2); - self->alloc(tmpp1,tmpp2); std::copy(tmp.begin(),tmp.end(),self->getPointer()); - } - } - else - throw INTERP_KERNEL::Exception(msg); - } - - PyObject *getValues() const throw(INTERP_KERNEL::Exception) - { - const int *vals=self->getConstPointer(); - return convertIntArrToPyList(vals,self->getNbOfElems()); - } - -#ifdef WITH_NUMPY - PyObject *toNumPyArray() throw(INTERP_KERNEL::Exception) // not const. It is not a bug ! - { - return ToNumPyArray(self,NPY_INT32,"DataArrayInt"); - } -#endif - - PyObject *isEqualIfNotWhy(const DataArrayInt& other) const throw(INTERP_KERNEL::Exception) - { - std::string ret1; - bool ret0=self->isEqualIfNotWhy(other,ret1); - PyObject *ret=PyTuple_New(2); - PyObject *ret0Py=ret0?Py_True:Py_False; - Py_XINCREF(ret0Py); - PyTuple_SetItem(ret,0,ret0Py); - PyTuple_SetItem(ret,1,PyString_FromString(ret1.c_str())); - return ret; - } - - PyObject *getValuesAsTuple() const throw(INTERP_KERNEL::Exception) - { - const int *vals=self->getConstPointer(); - int nbOfComp=self->getNumberOfComponents(); - int nbOfTuples=self->getNumberOfTuples(); - return convertIntArrToPyListOfTuple(vals,nbOfComp,nbOfTuples); - } - - static PyObject *MakePartition(PyObject *gps, int newNb) throw(INTERP_KERNEL::Exception) - { - std::vector groups; - std::vector< std::vector > fidsOfGroups; - convertFromPyObjVectorOfObj(gps,SWIGTYPE_p_ParaMEDMEM__DataArrayInt,"DataArrayInt",groups); - ParaMEDMEM::DataArrayInt *ret0=ParaMEDMEM::DataArrayInt::MakePartition(groups,newNb,fidsOfGroups); - PyObject *ret = PyList_New(2); - PyList_SetItem(ret,0,SWIG_NewPointerObj(SWIG_as_voidptr(ret0),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 )); - int sz=fidsOfGroups.size(); - PyObject *ret1 = PyList_New(sz); - for(int i=0;i tmp=convertPyToNewIntArr2(li,&size); - self->transformWithIndArr(tmp,tmp+size); - } - else - { - DataArrayInt *da2=reinterpret_cast< DataArrayInt * >(da); - self->transformWithIndArr(da2->getConstPointer(),da2->getConstPointer()+da2->getNbOfElems()); - } - } - - DataArrayInt *getIdsEqualList(PyObject *obj) throw(INTERP_KERNEL::Exception) - { - int sw; - int singleVal; - std::vector multiVal; - std::pair > slic; - ParaMEDMEM::DataArrayInt *daIntTyypp=0; - convertObjToPossibleCpp2(obj,self->getNumberOfTuples(),sw,singleVal,multiVal,slic,daIntTyypp); - switch(sw) - { - case 1: - return self->getIdsEqualList(&singleVal,&singleVal+1); - case 2: - return self->getIdsEqualList(&multiVal[0],&multiVal[0]+multiVal.size()); - case 4: - return self->getIdsEqualList(daIntTyypp->begin(),daIntTyypp->end()); - default: - throw INTERP_KERNEL::Exception("DataArrayInt::getIdsEqualList : unrecognized type entered, expected list of int, tuple of int or DataArrayInt !"); - } - } - - DataArrayInt *getIdsNotEqualList(PyObject *obj) throw(INTERP_KERNEL::Exception) - { - int sw; - int singleVal; - std::vector multiVal; - std::pair > slic; - ParaMEDMEM::DataArrayInt *daIntTyypp=0; - convertObjToPossibleCpp2(obj,self->getNumberOfTuples(),sw,singleVal,multiVal,slic,daIntTyypp); - switch(sw) - { - case 1: - return self->getIdsNotEqualList(&singleVal,&singleVal+1); - case 2: - return self->getIdsNotEqualList(&multiVal[0],&multiVal[0]+multiVal.size()); - case 4: - return self->getIdsNotEqualList(daIntTyypp->begin(),daIntTyypp->end()); - default: - throw INTERP_KERNEL::Exception("DataArrayInt::getIdsNotEqualList : unrecognized type entered, expected list of int, tuple of int or DataArrayInt !"); - } - } - - PyObject *splitByValueRange(PyObject *li) const throw(INTERP_KERNEL::Exception) - { - DataArrayInt *ret0=0,*ret1=0,*ret2=0; - void *da=0; - int res1=SWIG_ConvertPtr(li,&da,SWIGTYPE_p_ParaMEDMEM__DataArrayInt, 0 | 0 ); - if (!SWIG_IsOK(res1)) - { - int size; - INTERP_KERNEL::AutoPtr tmp=convertPyToNewIntArr2(li,&size); - self->splitByValueRange(tmp,(int *)tmp+size,ret0,ret1,ret2); - } - else - { - DataArrayInt *da2=reinterpret_cast< DataArrayInt * >(da); - if(!da2) - throw INTERP_KERNEL::Exception("Not null DataArrayInt instance expected !"); - da2->checkAllocated(); - int size=self->getNumberOfTuples(); - self->splitByValueRange(da2->getConstPointer(),da2->getConstPointer()+size,ret0,ret1,ret2); - } - PyObject *ret = PyList_New(3); - PyList_SetItem(ret,0,SWIG_NewPointerObj(SWIG_as_voidptr(ret0),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 )); - PyList_SetItem(ret,1,SWIG_NewPointerObj(SWIG_as_voidptr(ret1),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 )); - PyList_SetItem(ret,2,SWIG_NewPointerObj(SWIG_as_voidptr(ret2),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 )); - return ret; - } - - DataArrayInt *transformWithIndArrR(PyObject *li) const throw(INTERP_KERNEL::Exception) - { - void *da=0; - int res1=SWIG_ConvertPtr(li,&da,SWIGTYPE_p_ParaMEDMEM__DataArrayInt, 0 | 0 ); - if (!SWIG_IsOK(res1)) - { - int size; - INTERP_KERNEL::AutoPtr tmp=convertPyToNewIntArr2(li,&size); - return self->transformWithIndArrR(tmp,tmp+size); - } - else - { - DataArrayInt *da2=reinterpret_cast< DataArrayInt * >(da); - return self->transformWithIndArrR(da2->getConstPointer(),da2->getConstPointer()+da2->getNbOfElems()); - } - } - - DataArrayInt *renumberAndReduce(PyObject *li, int newNbOfTuple) throw(INTERP_KERNEL::Exception) - { - void *da=0; - int res1=SWIG_ConvertPtr(li,&da,SWIGTYPE_p_ParaMEDMEM__DataArrayInt, 0 | 0 ); - if (!SWIG_IsOK(res1)) - { - int size; - INTERP_KERNEL::AutoPtr tmp=convertPyToNewIntArr2(li,&size); - if(size!=self->getNumberOfTuples()) - { - throw INTERP_KERNEL::Exception("Invalid list length ! Must be equal to number of tuples !"); - } - return self->renumberAndReduce(tmp,newNbOfTuple); - } - else - { - DataArrayInt *da2=reinterpret_cast< DataArrayInt * >(da); - if(!da2) - throw INTERP_KERNEL::Exception("Not null DataArrayInt instance expected !"); - da2->checkAllocated(); - int size=self->getNumberOfTuples(); - if(size!=self->getNumberOfTuples()) - { - throw INTERP_KERNEL::Exception("Invalid list length ! Must be equal to number of tuples !"); - } - return self->renumberAndReduce(da2->getConstPointer(),newNbOfTuple); - } - } - - DataArrayInt *renumber(PyObject *li) throw(INTERP_KERNEL::Exception) - { - void *da=0; - int res1=SWIG_ConvertPtr(li,&da,SWIGTYPE_p_ParaMEDMEM__DataArrayInt, 0 | 0 ); - if (!SWIG_IsOK(res1)) - { - int size; - INTERP_KERNEL::AutoPtr tmp=convertPyToNewIntArr2(li,&size); - if(size!=self->getNumberOfTuples()) - { - throw INTERP_KERNEL::Exception("Invalid list length ! Must be equal to number of tuples !"); - } - return self->renumber(tmp); - } - else - { - DataArrayInt *da2=reinterpret_cast< DataArrayInt * >(da); - if(!da2) - throw INTERP_KERNEL::Exception("Not null DataArrayInt instance expected !"); - da2->checkAllocated(); - int size=self->getNumberOfTuples(); - if(size!=self->getNumberOfTuples()) - { - throw INTERP_KERNEL::Exception("Invalid list length ! Must be equal to number of tuples !"); - } - return self->renumber(da2->getConstPointer()); - } - } - - DataArrayInt *renumberR(PyObject *li) throw(INTERP_KERNEL::Exception) - { - void *da=0; - int res1=SWIG_ConvertPtr(li,&da,SWIGTYPE_p_ParaMEDMEM__DataArrayInt, 0 | 0 ); - if (!SWIG_IsOK(res1)) - { - int size; - INTERP_KERNEL::AutoPtr tmp=convertPyToNewIntArr2(li,&size); - if(size!=self->getNumberOfTuples()) - { - throw INTERP_KERNEL::Exception("Invalid list length ! Must be equal to number of tuples !"); - } - return self->renumberR(tmp); - } - else - { - DataArrayInt *da2=reinterpret_cast< DataArrayInt * >(da); - if(!da2) - throw INTERP_KERNEL::Exception("Not null DataArrayInt instance expected !"); - da2->checkAllocated(); - int size=self->getNumberOfTuples(); - if(size!=self->getNumberOfTuples()) - { - throw INTERP_KERNEL::Exception("Invalid list length ! Must be equal to number of tuples !"); - } - return self->renumberR(da2->getConstPointer()); - } - } - - void setSelectedComponents(const DataArrayInt *a, PyObject *li) throw(INTERP_KERNEL::Exception) - { - std::vector tmp; - convertPyToNewIntArr3(li,tmp); - self->setSelectedComponents(a,tmp); - } - - PyObject *getTuple(int tupleId) throw(INTERP_KERNEL::Exception) - { - int sz=self->getNumberOfComponents(); - INTERP_KERNEL::AutoPtr tmp=new int[sz]; - self->getTuple(tupleId,tmp); - return convertIntArrToPyList(tmp,sz); - } - - PyObject *changeSurjectiveFormat(int targetNb) const throw(INTERP_KERNEL::Exception) - { - DataArrayInt *arr=0; - DataArrayInt *arrI=0; - self->changeSurjectiveFormat(targetNb,arr,arrI); - PyObject *res = PyList_New(2); - PyList_SetItem(res,0,SWIG_NewPointerObj((void*)arr,SWIGTYPE_p_ParaMEDMEM__DataArrayInt,SWIG_POINTER_OWN | 0)); - PyList_SetItem(res,1,SWIG_NewPointerObj((void*)arrI,SWIGTYPE_p_ParaMEDMEM__DataArrayInt,SWIG_POINTER_OWN | 0)); - return res; - } - - static DataArrayInt *Meld(PyObject *li) throw(INTERP_KERNEL::Exception) - { - std::vector tmp; - convertFromPyObjVectorOfObj(li,SWIGTYPE_p_ParaMEDMEM__DataArrayInt,"DataArrayInt",tmp); - return DataArrayInt::Meld(tmp); - } - - static DataArrayInt *Aggregate(PyObject *li) throw(INTERP_KERNEL::Exception) - { - std::vector tmp; - convertFromPyObjVectorOfObj(li,SWIGTYPE_p_ParaMEDMEM__DataArrayInt,"DataArrayInt",tmp); - return DataArrayInt::Aggregate(tmp); - } - - static DataArrayInt *AggregateIndexes(PyObject *li) throw(INTERP_KERNEL::Exception) - { - std::vector tmp; - convertFromPyObjVectorOfObj(li,SWIGTYPE_p_ParaMEDMEM__DataArrayInt,"DataArrayInt",tmp); - return DataArrayInt::AggregateIndexes(tmp); - } - - static DataArrayInt *BuildUnion(PyObject *li) throw(INTERP_KERNEL::Exception) - { - std::vector tmp; - convertFromPyObjVectorOfObj(li,SWIGTYPE_p_ParaMEDMEM__DataArrayInt,"DataArrayInt",tmp); - return DataArrayInt::BuildUnion(tmp); - } - - static DataArrayInt *BuildIntersection(PyObject *li) throw(INTERP_KERNEL::Exception) - { - std::vector tmp; - convertFromPyObjVectorOfObj(li,SWIGTYPE_p_ParaMEDMEM__DataArrayInt,"DataArrayInt",tmp); - return DataArrayInt::BuildIntersection(tmp); - } - - PyObject *getMaxValue() const throw(INTERP_KERNEL::Exception) - { - int tmp; - int r1=self->getMaxValue(tmp); - PyObject *ret=PyTuple_New(2); - PyTuple_SetItem(ret,0,PyInt_FromLong(r1)); - PyTuple_SetItem(ret,1,PyInt_FromLong(tmp)); - return ret; - } - - PyObject *getMinValue() const throw(INTERP_KERNEL::Exception) - { - int tmp; - int r1=self->getMinValue(tmp); - PyObject *ret=PyTuple_New(2); - PyTuple_SetItem(ret,0,PyInt_FromLong(r1)); - PyTuple_SetItem(ret,1,PyInt_FromLong(tmp)); - return ret; - } - - int index(PyObject *obj) const throw(INTERP_KERNEL::Exception) - { - int nbOfCompo=self->getNumberOfComponents(); - switch(nbOfCompo) - { - case 1: - { - if(PyInt_Check(obj)) - { - int val=(int)PyInt_AS_LONG(obj); - return self->locateValue(val); - } - else - throw INTERP_KERNEL::Exception("DataArrayInt::index : 'this' contains one component and trying to find an element which is not an integer !"); - } - default: - { - std::vector arr; - convertPyToNewIntArr3(obj,arr); - return self->locateTuple(arr); - } - } - } - - bool __contains__(PyObject *obj) const throw(INTERP_KERNEL::Exception) - { - int nbOfCompo=self->getNumberOfComponents(); - switch(nbOfCompo) - { - case 0: - return false; - case 1: - { - if(PyInt_Check(obj)) - { - int val=(int)PyInt_AS_LONG(obj); - return self->presenceOfValue(val); - } - else - throw INTERP_KERNEL::Exception("DataArrayInt::__contains__ : 'this' contains one component and trying to find an element which is not an integer !"); - } - default: - { - std::vector arr; - convertPyToNewIntArr3(obj,arr); - return self->presenceOfTuple(arr); - } - } - } - - PyObject *__getitem__(PyObject *obj) throw(INTERP_KERNEL::Exception) - { - const char msg[]="Unexpected situation in DataArrayInt::__getitem__ !"; - const char msg2[]="DataArrayInt::__getitem__ : Mismatch of slice values in 2nd parameter (components) !"; - self->checkAllocated(); - int nbOfTuples=self->getNumberOfTuples(); - int nbOfComponents=self->getNumberOfComponents(); - int it1,ic1; - std::vector vt1,vc1; - std::pair > pt1,pc1; - DataArrayInt *dt1=0,*dc1=0; - int sw; - convertObjToPossibleCpp3(obj,nbOfTuples,nbOfComponents,sw,it1,ic1,vt1,vc1,pt1,pc1,dt1,dc1); - MEDCouplingAutoRefCountObjectPtr ret; - switch(sw) - { - case 1: - { - if(nbOfComponents==1) - return PyInt_FromLong(self->getIJSafe(it1,0)); - return SWIG_NewPointerObj(SWIG_as_voidptr(self->selectByTupleIdSafe(&it1,&it1+1)),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 ); - } - case 2: - return SWIG_NewPointerObj(SWIG_as_voidptr(self->selectByTupleIdSafe(&vt1[0],&vt1[0]+vt1.size())),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 ); - case 3: - return SWIG_NewPointerObj(SWIG_as_voidptr(self->selectByTupleId2(pt1.first,pt1.second.first,pt1.second.second)),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 ); - case 4: - return SWIG_NewPointerObj(SWIG_as_voidptr(self->selectByTupleIdSafe(dt1->getConstPointer(),dt1->getConstPointer()+dt1->getNbOfElems())),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 ); - case 5: - return PyInt_FromLong(self->getIJSafe(it1,ic1)); - case 6: - { - ret=self->selectByTupleIdSafe(&vt1[0],&vt1[0]+vt1.size()); - std::vector v2(1,ic1); - return SWIG_NewPointerObj(SWIG_as_voidptr(ret->keepSelectedComponents(v2)),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 ); - } - case 7: - { - ret=self->selectByTupleId2(pt1.first,pt1.second.first,pt1.second.second); - std::vector v2(1,ic1); - return SWIG_NewPointerObj(SWIG_as_voidptr(ret->keepSelectedComponents(v2)),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 ); - } - case 8: - { - ret=self->selectByTupleIdSafe(dt1->getConstPointer(),dt1->getConstPointer()+dt1->getNbOfElems()); - std::vector v2(1,ic1); - return SWIG_NewPointerObj(SWIG_as_voidptr(ret->keepSelectedComponents(v2)),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 ); - } - case 9: - { - ret=self->selectByTupleIdSafe(&it1,&it1+1); - return SWIG_NewPointerObj(SWIG_as_voidptr(ret->keepSelectedComponents(vc1)),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 ); - } - case 10: - { - ret=self->selectByTupleIdSafe(&vt1[0],&vt1[0]+vt1.size()); - return SWIG_NewPointerObj(SWIG_as_voidptr(ret->keepSelectedComponents(vc1)),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 ); - } - case 11: - { - ret=self->selectByTupleId2(pt1.first,pt1.second.first,pt1.second.second); - return SWIG_NewPointerObj(SWIG_as_voidptr(ret->keepSelectedComponents(vc1)),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 ); - } - case 12: - { - ret=self->selectByTupleIdSafe(dt1->getConstPointer(),dt1->getConstPointer()+dt1->getNbOfElems()); - return SWIG_NewPointerObj(SWIG_as_voidptr(ret->keepSelectedComponents(vc1)),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 ); - } - case 13: - { - ret=self->selectByTupleIdSafe(&it1,&it1+1); - int nbOfComp=DataArray::GetNumberOfItemGivenBESRelative(pc1.first,pc1.second.first,pc1.second.second,msg2); - std::vector v2(nbOfComp); - for(int i=0;ikeepSelectedComponents(v2)),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 ); - } - case 14: - { - ret=self->selectByTupleIdSafe(&vt1[0],&vt1[0]+vt1.size()); - int nbOfComp=DataArray::GetNumberOfItemGivenBESRelative(pc1.first,pc1.second.first,pc1.second.second,msg2); - std::vector v2(nbOfComp); - for(int i=0;ikeepSelectedComponents(v2)),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 ); - } - case 15: - { - ret=self->selectByTupleId2(pt1.first,pt1.second.first,pt1.second.second); - int nbOfComp=DataArray::GetNumberOfItemGivenBESRelative(pc1.first,pc1.second.first,pc1.second.second,msg2); - std::vector v2(nbOfComp); - for(int i=0;ikeepSelectedComponents(v2)),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 ); - } - case 16: - { - ret=self->selectByTupleIdSafe(dt1->getConstPointer(),dt1->getConstPointer()+dt1->getNbOfElems()); - int nbOfComp=DataArray::GetNumberOfItemGivenBESRelative(pc1.first,pc1.second.first,pc1.second.second,msg2); - std::vector v2(nbOfComp); - for(int i=0;ikeepSelectedComponents(v2)),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 ); - } - default: - throw INTERP_KERNEL::Exception(msg); - } - } - - DataArrayInt *__setitem__(PyObject *obj, PyObject *value) throw(INTERP_KERNEL::Exception) - { - self->checkAllocated(); - const char msg[]="Unexpected situation in __setitem__ !"; - int nbOfTuples=self->getNumberOfTuples(); - int nbOfComponents=self->getNumberOfComponents(); - int sw1,sw2; - int i1; - std::vector v1; - DataArrayInt *d1=0; - DataArrayIntTuple *dd1=0; - convertObjToPossibleCpp1(value,sw1,i1,v1,d1,dd1); - int it1,ic1; - std::vector vt1,vc1; - std::pair > pt1,pc1; - DataArrayInt *dt1=0,*dc1=0; - convertObjToPossibleCpp3(obj,nbOfTuples,nbOfComponents,sw2,it1,ic1,vt1,vc1,pt1,pc1,dt1,dc1); - MEDCouplingAutoRefCountObjectPtr tmp; - switch(sw2) - { - case 1: - { - switch(sw1) - { - case 1: - self->setPartOfValuesSimple1(i1,it1,it1+1,1,0,nbOfComponents,1); - return self; - case 2: - tmp=DataArrayInt::New(); - tmp->useArray(&v1[0],false,CPP_DEALLOC,1,v1.size()); - self->setPartOfValues1(tmp,it1,it1+1,1,0,nbOfComponents,1,false); - return self; - case 3: - self->setPartOfValues1(d1,it1,it1+1,1,0,nbOfComponents,1); - return self; - case 4: - tmp=dd1->buildDAInt(1,self->getNumberOfComponents()); - self->setPartOfValues1(tmp,it1,it1+1,1,0,nbOfComponents,1); - return self; - default: - throw INTERP_KERNEL::Exception(msg); - } - break; - } - case 2: - { - switch(sw1) - { - case 1: - self->setPartOfValuesSimple3(i1,&vt1[0],&vt1[0]+vt1.size(),0,nbOfComponents,1); - return self; - case 2: - tmp=DataArrayInt::New(); - tmp->useArray(&v1[0],false,CPP_DEALLOC,1,v1.size()); - self->setPartOfValues3(tmp,&vt1[0],&vt1[0]+vt1.size(),0,nbOfComponents,1,false); - return self; - case 3: - self->setPartOfValues3(d1,&vt1[0],&vt1[0]+vt1.size(),0,nbOfComponents,1); - return self; - case 4: - tmp=dd1->buildDAInt(1,self->getNumberOfComponents()); - self->setPartOfValues3(tmp,&vt1[0],&vt1[0]+vt1.size(),0,nbOfComponents,1); - return self; - default: - throw INTERP_KERNEL::Exception(msg); - } - break; - } - case 3: - { - switch(sw1) - { - case 1: - self->setPartOfValuesSimple1(i1,pt1.first,pt1.second.first,pt1.second.second,0,nbOfComponents,1); - return self; - case 2: - tmp=DataArrayInt::New(); - tmp->useArray(&v1[0],false,CPP_DEALLOC,1,v1.size()); - self->setPartOfValues1(tmp,pt1.first,pt1.second.first,pt1.second.second,0,nbOfComponents,1,false); - return self; - case 3: - self->setPartOfValues1(d1,pt1.first,pt1.second.first,pt1.second.second,0,nbOfComponents,1); - return self; - case 4: - tmp=dd1->buildDAInt(1,self->getNumberOfComponents()); - self->setPartOfValues1(tmp,pt1.first,pt1.second.first,pt1.second.second,0,nbOfComponents,1); - return self; - default: - throw INTERP_KERNEL::Exception(msg); - } - break; - } - case 4: - { - switch(sw1) - { - case 1: - self->setPartOfValuesSimple3(i1,dt1->getConstPointer(),dt1->getConstPointer()+dt1->getNbOfElems(),0,nbOfComponents,1); - return self; - case 2: - tmp=DataArrayInt::New(); - tmp->useArray(&v1[0],false,CPP_DEALLOC,1,v1.size()); - self->setPartOfValues3(tmp,dt1->getConstPointer(),dt1->getConstPointer()+dt1->getNbOfElems(),0,nbOfComponents,1,false); - return self; - case 3: - self->setPartOfValues3(d1,dt1->getConstPointer(),dt1->getConstPointer()+dt1->getNbOfElems(),0,nbOfComponents,1); - return self; - case 4: - tmp=dd1->buildDAInt(1,self->getNumberOfComponents()); - self->setPartOfValues3(tmp,dt1->getConstPointer(),dt1->getConstPointer()+dt1->getNbOfElems(),0,nbOfComponents,1); - return self; - default: - throw INTERP_KERNEL::Exception(msg); - } - break; - } - case 5: - { - switch(sw1) - { - case 1: - self->setPartOfValuesSimple1(i1,it1,it1+1,1,ic1,ic1+1,1); - return self; - case 2: - tmp=DataArrayInt::New(); - tmp->useArray(&v1[0],false,CPP_DEALLOC,1,v1.size()); - self->setPartOfValues1(tmp,it1,it1+1,1,ic1,ic1+1,1,false); - return self; - case 3: - self->setPartOfValues1(d1,it1,it1+1,1,ic1,ic1+1,1); - return self; - case 4: - tmp=dd1->buildDAInt(1,self->getNumberOfComponents()); - self->setPartOfValues1(tmp,it1,it1+1,1,ic1,ic1+1,1); - return self; - default: - throw INTERP_KERNEL::Exception(msg); - } - break; - } - case 6: - { - switch(sw1) - { - case 1: - self->setPartOfValuesSimple3(i1,&vt1[0],&vt1[0]+vt1.size(),ic1,ic1+1,1); - return self; - case 2: - tmp=DataArrayInt::New(); - tmp->useArray(&v1[0],false,CPP_DEALLOC,1,v1.size()); - self->setPartOfValues3(tmp,&vt1[0],&vt1[0]+vt1.size(),ic1,ic1+1,1,false); - return self; - case 3: - self->setPartOfValues3(d1,&vt1[0],&vt1[0]+vt1.size(),ic1,ic1+1,1); - return self; - case 4: - tmp=dd1->buildDAInt(1,self->getNumberOfComponents()); - self->setPartOfValues3(tmp,&vt1[0],&vt1[0]+vt1.size(),ic1,ic1+1,1); - return self; - default: - throw INTERP_KERNEL::Exception(msg); - } - break; - } - case 7: - { - switch(sw1) - { - case 1: - self->setPartOfValuesSimple1(i1,pt1.first,pt1.second.first,pt1.second.second,ic1,ic1+1,1); - return self; - case 2: - tmp=DataArrayInt::New(); - tmp->useArray(&v1[0],false,CPP_DEALLOC,1,v1.size()); - self->setPartOfValues1(tmp,pt1.first,pt1.second.first,pt1.second.second,ic1,ic1+1,1,false); - return self; - case 3: - self->setPartOfValues1(d1,pt1.first,pt1.second.first,pt1.second.second,ic1,ic1+1,1); - return self; - case 4: - tmp=dd1->buildDAInt(1,self->getNumberOfComponents()); - self->setPartOfValues1(tmp,pt1.first,pt1.second.first,pt1.second.second,ic1,ic1+1,1); - return self; - default: - throw INTERP_KERNEL::Exception(msg); - } - break; - } - case 8: - { - switch(sw1) - { - case 1: - self->setPartOfValuesSimple3(i1,dt1->getConstPointer(),dt1->getConstPointer()+dt1->getNbOfElems(),ic1,ic1+1,1); - return self; - case 2: - tmp=DataArrayInt::New(); - tmp->useArray(&v1[0],false,CPP_DEALLOC,1,v1.size()); - self->setPartOfValues3(tmp,dt1->getConstPointer(),dt1->getConstPointer()+dt1->getNbOfElems(),ic1,ic1+1,1,false); - return self; - case 3: - self->setPartOfValues3(d1,dt1->getConstPointer(),dt1->getConstPointer()+dt1->getNbOfElems(),ic1,ic1+1,1); - return self; - case 4: - tmp=dd1->buildDAInt(1,self->getNumberOfComponents()); - self->setPartOfValues3(tmp,dt1->getConstPointer(),dt1->getConstPointer()+dt1->getNbOfElems(),ic1,ic1+1,1); - return self; - default: - throw INTERP_KERNEL::Exception(msg); - } - break; - } - case 9: - { - switch(sw1) - { - case 1: - self->setPartOfValuesSimple2(i1,&it1,&it1+1,&vc1[0],&vc1[0]+vc1.size()); - return self; - case 2: - tmp=DataArrayInt::New(); - tmp->useArray(&v1[0],false,CPP_DEALLOC,1,v1.size()); - self->setPartOfValues2(tmp,&it1,&it1+1,&vc1[0],&vc1[0]+vc1.size(),false); - return self; - case 3: - self->setPartOfValues2(d1,&it1,&it1+1,&vc1[0],&vc1[0]+vc1.size()); - return self; - case 4: - tmp=dd1->buildDAInt(1,self->getNumberOfComponents()); - self->setPartOfValues2(tmp,&it1,&it1+1,&vc1[0],&vc1[0]+vc1.size()); - return self; - default: - throw INTERP_KERNEL::Exception(msg); - } - break; - } - case 10: - { - switch(sw1) - { - case 1: - self->setPartOfValuesSimple2(i1,&vt1[0],&vt1[0]+vt1.size(),&vc1[0],&vc1[0]+vc1.size()); - return self; - case 2: - tmp=DataArrayInt::New(); - tmp->useArray(&v1[0],false,CPP_DEALLOC,1,v1.size()); - self->setPartOfValues2(tmp,&vt1[0],&vt1[0]+vt1.size(),&vc1[0],&vc1[0]+vc1.size(),false); - return self; - case 3: - self->setPartOfValues2(d1,&vt1[0],&vt1[0]+vt1.size(),&vc1[0],&vc1[0]+vc1.size()); - return self; - case 4: - tmp=dd1->buildDAInt(1,self->getNumberOfComponents()); - self->setPartOfValues2(tmp,&vt1[0],&vt1[0]+vt1.size(),&vc1[0],&vc1[0]+vc1.size()); - return self; - default: - throw INTERP_KERNEL::Exception(msg); - } - break; - } - case 11: - { - switch(sw1) - { - case 1: - self->setPartOfValuesSimple4(i1,pt1.first,pt1.second.first,pt1.second.second,&vc1[0],&vc1[0]+vc1.size()); - return self; - case 2: - tmp=DataArrayInt::New(); - tmp->useArray(&v1[0],false,CPP_DEALLOC,1,v1.size()); - self->setPartOfValues4(tmp,pt1.first,pt1.second.first,pt1.second.second,&vc1[0],&vc1[0]+vc1.size(),false); - return self; - case 3: - self->setPartOfValues4(d1,pt1.first,pt1.second.first,pt1.second.second,&vc1[0],&vc1[0]+vc1.size()); - return self; - case 4: - tmp=dd1->buildDAInt(1,self->getNumberOfComponents()); - self->setPartOfValues4(tmp,pt1.first,pt1.second.first,pt1.second.second,&vc1[0],&vc1[0]+vc1.size()); - return self; - default: - throw INTERP_KERNEL::Exception(msg); - } - break; - } - case 12: - { - switch(sw1) - { - case 1: - self->setPartOfValuesSimple2(i1,dt1->getConstPointer(),dt1->getConstPointer()+dt1->getNbOfElems(),&vc1[0],&vc1[0]+vc1.size()); - return self; - case 2: - tmp=DataArrayInt::New(); - tmp->useArray(&v1[0],false,CPP_DEALLOC,1,v1.size()); - self->setPartOfValues2(tmp,dt1->getConstPointer(),dt1->getConstPointer()+dt1->getNbOfElems(),&vc1[0],&vc1[0]+vc1.size(),false); - return self; - case 3: - self->setPartOfValues2(d1,dt1->getConstPointer(),dt1->getConstPointer()+dt1->getNbOfElems(),&vc1[0],&vc1[0]+vc1.size()); - return self; - case 4: - tmp=dd1->buildDAInt(1,self->getNumberOfComponents()); - self->setPartOfValues2(tmp,dt1->getConstPointer(),dt1->getConstPointer()+dt1->getNbOfElems(),&vc1[0],&vc1[0]+vc1.size()); - return self; - default: - throw INTERP_KERNEL::Exception(msg); - } - break; - } - case 13: - { - switch(sw1) - { - case 1: - self->setPartOfValuesSimple1(i1,it1,it1+1,1,pc1.first,pc1.second.first,pc1.second.second); - return self; - case 2: - tmp=DataArrayInt::New(); - tmp->useArray(&v1[0],false,CPP_DEALLOC,1,v1.size()); - self->setPartOfValues1(tmp,it1,it1+1,1,pc1.first,pc1.second.first,pc1.second.second,false); - return self; - case 3: - self->setPartOfValues1(d1,it1,it1+1,1,pc1.first,pc1.second.first,pc1.second.second); - return self; - case 4: - tmp=dd1->buildDAInt(1,self->getNumberOfComponents()); - self->setPartOfValues1(tmp,it1,it1+1,1,pc1.first,pc1.second.first,pc1.second.second); - return self; - default: - throw INTERP_KERNEL::Exception(msg); - } - break; - } - case 14: - { - switch(sw1) - { - case 1: - self->setPartOfValuesSimple3(i1,&vt1[0],&vt1[0]+vt1.size(),pc1.first,pc1.second.first,pc1.second.second); - return self; - case 2: - tmp=DataArrayInt::New(); - tmp->useArray(&v1[0],false,CPP_DEALLOC,1,v1.size()); - self->setPartOfValues3(tmp,&vt1[0],&vt1[0]+vt1.size(),pc1.first,pc1.second.first,pc1.second.second,false); - return self; - case 3: - self->setPartOfValues3(d1,&vt1[0],&vt1[0]+vt1.size(),pc1.first,pc1.second.first,pc1.second.second); - return self; - case 4: - tmp=dd1->buildDAInt(1,self->getNumberOfComponents()); - self->setPartOfValues3(tmp,&vt1[0],&vt1[0]+vt1.size(),pc1.first,pc1.second.first,pc1.second.second); - return self; - default: - throw INTERP_KERNEL::Exception(msg); - } - break; - } - case 15: - { - switch(sw1) - { - case 1: - self->setPartOfValuesSimple1(i1,pt1.first,pt1.second.first,pt1.second.second,pc1.first,pc1.second.first,pc1.second.second); - return self; - case 2: - tmp=DataArrayInt::New(); - tmp->useArray(&v1[0],false,CPP_DEALLOC,1,v1.size()); - self->setPartOfValues1(tmp,pt1.first,pt1.second.first,pt1.second.second,pc1.first,pc1.second.first,pc1.second.second,false); - return self; - case 3: - self->setPartOfValues1(d1,pt1.first,pt1.second.first,pt1.second.second,pc1.first,pc1.second.first,pc1.second.second); - return self; - case 4: - tmp=dd1->buildDAInt(1,self->getNumberOfComponents()); - self->setPartOfValues1(tmp,pt1.first,pt1.second.first,pt1.second.second,pc1.first,pc1.second.first,pc1.second.second); - return self; - default: - throw INTERP_KERNEL::Exception(msg); - } - break; - } - case 16: - { - switch(sw1) - { - case 1: - self->setPartOfValuesSimple3(i1,dt1->getConstPointer(),dt1->getConstPointer()+dt1->getNbOfElems(),pc1.first,pc1.second.first,pc1.second.second); - return self; - case 2: - tmp=DataArrayInt::New(); - tmp->useArray(&v1[0],false,CPP_DEALLOC,1,v1.size()); - self->setPartOfValues3(tmp,dt1->getConstPointer(),dt1->getConstPointer()+dt1->getNbOfElems(),pc1.first,pc1.second.first,pc1.second.second,false); - return self; - case 3: - self->setPartOfValues3(d1,dt1->getConstPointer(),dt1->getConstPointer()+dt1->getNbOfElems(),pc1.first,pc1.second.first,pc1.second.second); - return self; - case 4: - tmp=dd1->buildDAInt(1,self->getNumberOfComponents()); - self->setPartOfValues3(tmp,dt1->getConstPointer(),dt1->getConstPointer()+dt1->getNbOfElems(),pc1.first,pc1.second.first,pc1.second.second); - return self; - default: - throw INTERP_KERNEL::Exception(msg); - } - break; - } - default: - throw INTERP_KERNEL::Exception(msg); - } - return self; - } - - DataArrayInt *__neg__() const throw(INTERP_KERNEL::Exception) - { - return self->negate(); - } - - DataArrayInt *__add__(PyObject *obj) throw(INTERP_KERNEL::Exception) - { - const char msg[]="Unexpected situation in __add__ !"; - int val; - DataArrayInt *a; - std::vector aa; - DataArrayIntTuple *aaa; - int sw; - convertObjToPossibleCpp1(obj,sw,val,aa,a,aaa); - switch(sw) - { - case 1: - { - MEDCouplingAutoRefCountObjectPtr ret=self->deepCpy(); - ret->applyLin(1,val); - return ret.retn(); - } - case 2: - { - MEDCouplingAutoRefCountObjectPtr aaaa=DataArrayInt::New(); aaaa->useArray(&aa[0],false,CPP_DEALLOC,1,(int)aa.size()); - return DataArrayInt::Add(self,aaaa); - } - case 3: - { - return DataArrayInt::Add(self,a); - } - case 4: - { - MEDCouplingAutoRefCountObjectPtr aaaa=aaa->buildDAInt(1,self->getNumberOfComponents()); - return DataArrayInt::Add(self,aaaa); - } - default: - throw INTERP_KERNEL::Exception(msg); - } - } - - DataArrayInt *__radd__(PyObject *obj) throw(INTERP_KERNEL::Exception) - { - const char msg[]="Unexpected situation in __radd__ !"; - int val; - DataArrayInt *a; - std::vector aa; - DataArrayIntTuple *aaa; - int sw; - convertObjToPossibleCpp1(obj,sw,val,aa,a,aaa); - switch(sw) - { - case 1: - { - MEDCouplingAutoRefCountObjectPtr ret=self->deepCpy(); - ret->applyLin(1,val); - return ret.retn(); - } - case 2: - { - MEDCouplingAutoRefCountObjectPtr aaaa=DataArrayInt::New(); aaaa->useArray(&aa[0],false,CPP_DEALLOC,1,(int)aa.size()); - return DataArrayInt::Add(self,aaaa); - } - case 4: - { - MEDCouplingAutoRefCountObjectPtr aaaa=aaa->buildDAInt(1,self->getNumberOfComponents()); - return DataArrayInt::Add(self,aaaa); - } - default: - throw INTERP_KERNEL::Exception(msg); - } - } - - PyObject *___iadd___(PyObject *trueSelf, PyObject *obj) throw(INTERP_KERNEL::Exception) - { - const char msg[]="Unexpected situation in __iadd__ !"; - int val; - DataArrayInt *a; - std::vector aa; - DataArrayIntTuple *aaa; - int sw; - convertObjToPossibleCpp1(obj,sw,val,aa,a,aaa); - switch(sw) - { - case 1: - { - self->applyLin(1,val); - Py_XINCREF(trueSelf); - return trueSelf; - } - case 2: - { - MEDCouplingAutoRefCountObjectPtr bb=DataArrayInt::New(); bb->useArray(&aa[0],false,CPP_DEALLOC,1,(int)aa.size()); - self->addEqual(bb); - Py_XINCREF(trueSelf); - return trueSelf; - } - case 3: - { - self->addEqual(a); - Py_XINCREF(trueSelf); - return trueSelf; - } - case 4: - { - MEDCouplingAutoRefCountObjectPtr aaaa=aaa->buildDAInt(1,self->getNumberOfComponents()); - self->addEqual(aaaa); - Py_XINCREF(trueSelf); - return trueSelf; - } - default: - throw INTERP_KERNEL::Exception(msg); - } - } - - DataArrayInt *__sub__(PyObject *obj) throw(INTERP_KERNEL::Exception) - { - const char msg[]="Unexpected situation in __sub__ !"; - int val; - DataArrayInt *a; - std::vector aa; - DataArrayIntTuple *aaa; - int sw; - convertObjToPossibleCpp1(obj,sw,val,aa,a,aaa); - switch(sw) - { - case 1: - { - MEDCouplingAutoRefCountObjectPtr ret=self->deepCpy(); - ret->applyLin(1,-val); - return ret.retn(); - } - case 2: - { - MEDCouplingAutoRefCountObjectPtr aaaa=DataArrayInt::New(); aaaa->useArray(&aa[0],false,CPP_DEALLOC,1,(int)aa.size()); - return DataArrayInt::Substract(self,aaaa); - } - case 3: - { - return DataArrayInt::Substract(self,a); - } - case 4: - { - MEDCouplingAutoRefCountObjectPtr aaaa=aaa->buildDAInt(1,self->getNumberOfComponents()); - return DataArrayInt::Substract(self,aaaa); - } - default: - throw INTERP_KERNEL::Exception(msg); - } - } - - DataArrayInt *__rsub__(PyObject *obj) throw(INTERP_KERNEL::Exception) - { - const char msg[]="Unexpected situation in __rsub__ !"; - int val; - DataArrayInt *a; - std::vector aa; - DataArrayIntTuple *aaa; - int sw; - convertObjToPossibleCpp1(obj,sw,val,aa,a,aaa); - switch(sw) - { - case 1: - { - MEDCouplingAutoRefCountObjectPtr ret=self->deepCpy(); - ret->applyLin(-1,val); - return ret.retn(); - } - case 2: - { - MEDCouplingAutoRefCountObjectPtr aaaa=DataArrayInt::New(); aaaa->useArray(&aa[0],false,CPP_DEALLOC,1,(int)aa.size()); - return DataArrayInt::Substract(aaaa,self); - } - case 4: - { - MEDCouplingAutoRefCountObjectPtr aaaa=aaa->buildDAInt(1,self->getNumberOfComponents()); - return DataArrayInt::Substract(aaaa,self); - } - default: - throw INTERP_KERNEL::Exception(msg); - } - } - - PyObject *___isub___(PyObject *trueSelf, PyObject *obj) throw(INTERP_KERNEL::Exception) - { - const char msg[]="Unexpected situation in __isub__ !"; - int val; - DataArrayInt *a; - std::vector aa; - DataArrayIntTuple *aaa; - int sw; - convertObjToPossibleCpp1(obj,sw,val,aa,a,aaa); - switch(sw) - { - case 1: - { - self->applyLin(1,-val); - Py_XINCREF(trueSelf); - return trueSelf; - } - case 2: - { - MEDCouplingAutoRefCountObjectPtr bb=DataArrayInt::New(); bb->useArray(&aa[0],false,CPP_DEALLOC,1,(int)aa.size()); - self->substractEqual(bb); - Py_XINCREF(trueSelf); - return trueSelf; - } - case 3: - { - self->substractEqual(a); - Py_XINCREF(trueSelf); - return trueSelf; - } - case 4: - { - MEDCouplingAutoRefCountObjectPtr aaaa=aaa->buildDAInt(1,self->getNumberOfComponents()); - self->substractEqual(aaaa); - Py_XINCREF(trueSelf); - return trueSelf; - } - default: - throw INTERP_KERNEL::Exception(msg); - } - } - - DataArrayInt *__mul__(PyObject *obj) throw(INTERP_KERNEL::Exception) - { - const char msg[]="Unexpected situation in __mul__ !"; - int val; - DataArrayInt *a; - std::vector aa; - DataArrayIntTuple *aaa; - int sw; - convertObjToPossibleCpp1(obj,sw,val,aa,a,aaa); - switch(sw) - { - case 1: - { - MEDCouplingAutoRefCountObjectPtr ret=self->deepCpy(); - ret->applyLin(val,0); - return ret.retn(); - } - case 2: - { - MEDCouplingAutoRefCountObjectPtr aaaa=DataArrayInt::New(); aaaa->useArray(&aa[0],false,CPP_DEALLOC,1,(int)aa.size()); - return DataArrayInt::Multiply(self,aaaa); - } - case 3: - { - return DataArrayInt::Multiply(self,a); - } - case 4: - { - MEDCouplingAutoRefCountObjectPtr aaaa=aaa->buildDAInt(1,self->getNumberOfComponents()); - return DataArrayInt::Multiply(self,aaaa); - } - default: - throw INTERP_KERNEL::Exception(msg); - } - } - - DataArrayInt *__rmul__(PyObject *obj) throw(INTERP_KERNEL::Exception) - { - const char msg[]="Unexpected situation in __rmul__ !"; - int val; - DataArrayInt *a; - std::vector aa; - DataArrayIntTuple *aaa; - int sw; - convertObjToPossibleCpp1(obj,sw,val,aa,a,aaa); - switch(sw) - { - case 1: - { - MEDCouplingAutoRefCountObjectPtr ret=self->deepCpy(); - ret->applyLin(val,0); - return ret.retn(); - } - case 2: - { - MEDCouplingAutoRefCountObjectPtr aaaa=DataArrayInt::New(); aaaa->useArray(&aa[0],false,CPP_DEALLOC,1,(int)aa.size()); - return DataArrayInt::Multiply(self,aaaa); - } - case 4: - { - MEDCouplingAutoRefCountObjectPtr aaaa=aaa->buildDAInt(1,self->getNumberOfComponents()); - return DataArrayInt::Multiply(self,aaaa); - } - default: - throw INTERP_KERNEL::Exception(msg); - } - } - - PyObject *___imul___(PyObject *trueSelf, PyObject *obj) throw(INTERP_KERNEL::Exception) - { - const char msg[]="Unexpected situation in __imul__ !"; - int val; - DataArrayInt *a; - std::vector aa; - DataArrayIntTuple *aaa; - int sw; - convertObjToPossibleCpp1(obj,sw,val,aa,a,aaa); - switch(sw) - { - case 1: - { - self->applyLin(val,0); - Py_XINCREF(trueSelf); - return trueSelf; - } - case 2: - { - MEDCouplingAutoRefCountObjectPtr bb=DataArrayInt::New(); bb->useArray(&aa[0],false,CPP_DEALLOC,1,(int)aa.size()); - self->multiplyEqual(bb); - Py_XINCREF(trueSelf); - return trueSelf; - } - case 3: - { - self->multiplyEqual(a); - Py_XINCREF(trueSelf); - return trueSelf; - } - case 4: - { - MEDCouplingAutoRefCountObjectPtr aaaa=aaa->buildDAInt(1,self->getNumberOfComponents()); - self->multiplyEqual(aaaa); - Py_XINCREF(trueSelf); - return trueSelf; - } - default: - throw INTERP_KERNEL::Exception(msg); - } - } - - DataArrayInt *__div__(PyObject *obj) throw(INTERP_KERNEL::Exception) - { - const char msg[]="Unexpected situation in __div__ !"; - int val; - DataArrayInt *a; - std::vector aa; - DataArrayIntTuple *aaa; - int sw; - convertObjToPossibleCpp1(obj,sw,val,aa,a,aaa); - switch(sw) - { - case 1: - { - MEDCouplingAutoRefCountObjectPtr ret=self->deepCpy(); - ret->applyDivideBy(val); - return ret.retn(); - } - case 2: - { - MEDCouplingAutoRefCountObjectPtr aaaa=DataArrayInt::New(); aaaa->useArray(&aa[0],false,CPP_DEALLOC,1,(int)aa.size()); - return DataArrayInt::Divide(self,aaaa); - } - case 3: - { - return DataArrayInt::Divide(self,a); - } - case 4: - { - MEDCouplingAutoRefCountObjectPtr aaaa=aaa->buildDAInt(1,self->getNumberOfComponents()); - return DataArrayInt::Divide(self,aaaa); - } - default: - throw INTERP_KERNEL::Exception(msg); - } - } - - DataArrayInt *__rdiv__(PyObject *obj) throw(INTERP_KERNEL::Exception) - { - const char msg[]="Unexpected situation in __rdiv__ !"; - int val; - DataArrayInt *a; - std::vector aa; - DataArrayIntTuple *aaa; - int sw; - convertObjToPossibleCpp1(obj,sw,val,aa,a,aaa); - switch(sw) - { - case 1: - { - MEDCouplingAutoRefCountObjectPtr ret=self->deepCpy(); - ret->applyInv(val); - return ret.retn(); - } - case 2: - { - MEDCouplingAutoRefCountObjectPtr aaaa=DataArrayInt::New(); aaaa->useArray(&aa[0],false,CPP_DEALLOC,1,(int)aa.size()); - return DataArrayInt::Divide(aaaa,self); - } - case 4: - { - MEDCouplingAutoRefCountObjectPtr aaaa=aaa->buildDAInt(1,self->getNumberOfComponents()); - return DataArrayInt::Divide(aaaa,self); - } - default: - throw INTERP_KERNEL::Exception(msg); - } - } - - PyObject *___idiv___(PyObject *trueSelf, PyObject *obj) throw(INTERP_KERNEL::Exception) - { - const char msg[]="Unexpected situation in __idiv__ !"; - int val; - DataArrayInt *a; - std::vector aa; - DataArrayIntTuple *aaa; - int sw; - convertObjToPossibleCpp1(obj,sw,val,aa,a,aaa); - switch(sw) - { - case 1: - { - self->applyDivideBy(val); - Py_XINCREF(trueSelf); - return trueSelf; - } - case 2: - { - MEDCouplingAutoRefCountObjectPtr bb=DataArrayInt::New(); bb->useArray(&aa[0],false,CPP_DEALLOC,1,(int)aa.size()); - self->divideEqual(bb); - Py_XINCREF(trueSelf); - return trueSelf; - } - case 3: - { - self->divideEqual(a); - Py_XINCREF(trueSelf); - return trueSelf; - } - case 4: - { - MEDCouplingAutoRefCountObjectPtr aaaa=aaa->buildDAInt(1,self->getNumberOfComponents()); - self->divideEqual(aaaa); - Py_XINCREF(trueSelf); - return trueSelf; - } - default: - throw INTERP_KERNEL::Exception(msg); - } - } - - DataArrayInt *__mod__(PyObject *obj) throw(INTERP_KERNEL::Exception) - { - const char msg[]="Unexpected situation in __mod__ !"; - int val; - DataArrayInt *a; - std::vector aa; - DataArrayIntTuple *aaa; - int sw; - convertObjToPossibleCpp1(obj,sw,val,aa,a,aaa); - switch(sw) - { - case 1: - { - MEDCouplingAutoRefCountObjectPtr ret=self->deepCpy(); - ret->applyModulus(val); - return ret.retn(); - } - case 2: - { - MEDCouplingAutoRefCountObjectPtr aaaa=DataArrayInt::New(); aaaa->useArray(&aa[0],false,CPP_DEALLOC,1,(int)aa.size()); - return DataArrayInt::Modulus(self,aaaa); - } - case 3: - { - return DataArrayInt::Modulus(self,a); - } - case 4: - { - MEDCouplingAutoRefCountObjectPtr aaaa=aaa->buildDAInt(1,self->getNumberOfComponents()); - return DataArrayInt::Modulus(self,aaaa); - } - default: - throw INTERP_KERNEL::Exception(msg); - } - } - - DataArrayInt *__rmod__(PyObject *obj) throw(INTERP_KERNEL::Exception) - { - const char msg[]="Unexpected situation in __rmod__ !"; - int val; - DataArrayInt *a; - std::vector aa; - DataArrayIntTuple *aaa; - int sw; - convertObjToPossibleCpp1(obj,sw,val,aa,a,aaa); - switch(sw) - { - case 1: - { - MEDCouplingAutoRefCountObjectPtr ret=self->deepCpy(); - ret->applyRModulus(val); - return ret.retn(); - } - case 2: - { - MEDCouplingAutoRefCountObjectPtr aaaa=DataArrayInt::New(); aaaa->useArray(&aa[0],false,CPP_DEALLOC,1,(int)aa.size()); - return DataArrayInt::Modulus(aaaa,self); - } - case 3: - { - return DataArrayInt::Modulus(a,self); - } - case 4: - { - MEDCouplingAutoRefCountObjectPtr aaaa=aaa->buildDAInt(1,self->getNumberOfComponents()); - return DataArrayInt::Modulus(aaaa,self); - } - default: - throw INTERP_KERNEL::Exception(msg); - } - } - - PyObject *___imod___(PyObject *trueSelf, PyObject *obj) throw(INTERP_KERNEL::Exception) - { - const char msg[]="Unexpected situation in __imod__ !"; - int val; - DataArrayInt *a; - std::vector aa; - DataArrayIntTuple *aaa; - int sw; - convertObjToPossibleCpp1(obj,sw,val,aa,a,aaa); - switch(sw) - { - case 1: - { - self->applyModulus(val); - Py_XINCREF(trueSelf); - return trueSelf; - } - case 3: - { - self->modulusEqual(a); - Py_XINCREF(trueSelf); - return trueSelf; - } - case 4: - { - MEDCouplingAutoRefCountObjectPtr aaaa=aaa->buildDAInt(1,self->getNumberOfComponents()); - self->modulusEqual(aaaa); - Py_XINCREF(trueSelf); - return trueSelf; - } - default: - throw INTERP_KERNEL::Exception(msg); - } - } - - DataArrayInt *__pow__(PyObject *obj) throw(INTERP_KERNEL::Exception) - { - const char msg[]="Unexpected situation in __pow__ !"; - int val; - DataArrayInt *a; - std::vector aa; - DataArrayIntTuple *aaa; - int sw; - convertObjToPossibleCpp1(obj,sw,val,aa,a,aaa); - switch(sw) - { - case 1: - { - MEDCouplingAutoRefCountObjectPtr ret=self->deepCpy(); - ret->applyPow(val); - return ret.retn(); - } - case 2: - { - MEDCouplingAutoRefCountObjectPtr aaaa=DataArrayInt::New(); aaaa->useArray(&aa[0],false,CPP_DEALLOC,1,(int)aa.size()); - return DataArrayInt::Pow(self,aaaa); - } - case 3: - { - return DataArrayInt::Pow(self,a); - } - case 4: - { - MEDCouplingAutoRefCountObjectPtr aaaa=aaa->buildDAInt(1,self->getNumberOfComponents()); - return DataArrayInt::Pow(self,aaaa); - } - default: - throw INTERP_KERNEL::Exception(msg); - } - } - - DataArrayInt *__rpow__(PyObject *obj) throw(INTERP_KERNEL::Exception) - { - const char msg[]="Unexpected situation in __rpow__ !"; - int val; - DataArrayInt *a; - std::vector aa; - DataArrayIntTuple *aaa; - int sw; - convertObjToPossibleCpp1(obj,sw,val,aa,a,aaa); - switch(sw) - { - case 1: - { - MEDCouplingAutoRefCountObjectPtr ret=self->deepCpy(); - ret->applyRPow(val); - return ret.retn(); - } - case 2: - { - MEDCouplingAutoRefCountObjectPtr aaaa=DataArrayInt::New(); aaaa->useArray(&aa[0],false,CPP_DEALLOC,1,(int)aa.size()); - return DataArrayInt::Pow(aaaa,self); - } - case 3: - { - return DataArrayInt::Pow(a,self); - } - case 4: - { - MEDCouplingAutoRefCountObjectPtr aaaa=aaa->buildDAInt(1,self->getNumberOfComponents()); - return DataArrayInt::Pow(aaaa,self); - } - default: - throw INTERP_KERNEL::Exception(msg); - } - } - - PyObject *___ipow___(PyObject *trueSelf, PyObject *obj) throw(INTERP_KERNEL::Exception) - { - const char msg[]="Unexpected situation in __ipow__ !"; - int val; - DataArrayInt *a; - std::vector aa; - DataArrayIntTuple *aaa; - int sw; - convertObjToPossibleCpp1(obj,sw,val,aa,a,aaa); - switch(sw) - { - case 1: - { - self->applyPow(val); - Py_XINCREF(trueSelf); - return trueSelf; - } - case 3: - { - self->powEqual(a); - Py_XINCREF(trueSelf); - return trueSelf; - } - case 4: - { - MEDCouplingAutoRefCountObjectPtr aaaa=aaa->buildDAInt(1,self->getNumberOfComponents()); - self->powEqual(aaaa); - Py_XINCREF(trueSelf); - return trueSelf; - } - default: - throw INTERP_KERNEL::Exception(msg); - } - } - - std::string __repr__() const throw(INTERP_KERNEL::Exception) - { - std::ostringstream oss; - self->reprQuickOverview(oss); - return oss.str(); - } - - void pushBackValsSilent(PyObject *li) throw(INTERP_KERNEL::Exception) - { - int szArr,sw,iTypppArr; - std::vector stdvecTyyppArr; - const int *tmp=convertObjToPossibleCpp1_Safe(li,sw,szArr,iTypppArr,stdvecTyyppArr); - self->pushBackValsSilent(tmp,tmp+szArr); - } - - PyObject *partitionByDifferentValues() const throw(INTERP_KERNEL::Exception) - { - std::vector ret1; - std::vector ret0=self->partitionByDifferentValues(ret1); - std::size_t sz=ret0.size(); - PyObject *pyRet=PyTuple_New(2); - PyObject *pyRet0=PyList_New((int)sz); - PyObject *pyRet1=PyList_New((int)sz); - for(std::size_t i=0;isearchRangesInListOfIds(listOfIds,ret0,ret1); - PyObject *pyRet=PyTuple_New(2); - PyTuple_SetItem(pyRet,0,SWIG_NewPointerObj(SWIG_as_voidptr(ret0),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 )); - PyTuple_SetItem(pyRet,1,SWIG_NewPointerObj(SWIG_as_voidptr(ret1),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 )); - return pyRet; - } - - PyObject *isRange() const throw(INTERP_KERNEL::Exception) - { - int a(0),b(0),c(0); - bool ret(self->isRange(a,b,c)); - PyObject *pyRet=PyTuple_New(2); - PyObject *ret0Py=ret?Py_True:Py_False,*ret1Py(0); - Py_XINCREF(ret0Py); - PyTuple_SetItem(pyRet,0,ret0Py); - if(ret) - ret1Py=PySlice_New(PyInt_FromLong(a),PyInt_FromLong(b),PyInt_FromLong(c)); - else - { - ret1Py=Py_None; - Py_XINCREF(ret1Py); - } - PyTuple_SetItem(pyRet,1,ret1Py); - return pyRet; - } - - // serialization - static PyObject *___new___(PyObject *cls, PyObject *args) throw(INTERP_KERNEL::Exception) - { - static const char MSG[]="DataArrayInt.__new__ : the args in input is expected to be a tuple !"; - if(!PyTuple_Check(args)) - throw INTERP_KERNEL::Exception(MSG); - PyObject *builtinsd(PyEval_GetBuiltins());//borrowed - PyObject *obj(PyDict_GetItemString(builtinsd,"object"));//borrowed - PyObject *selfMeth(PyObject_GetAttrString(obj,"__new__")); - // - PyObject *tmp0(PyTuple_New(1)); - PyTuple_SetItem(tmp0,0,cls); Py_XINCREF(cls); - PyObject *instance(PyObject_CallObject(selfMeth,tmp0)); - Py_DECREF(tmp0); - Py_DECREF(selfMeth); - PyObject *initMeth(PyObject_GetAttrString(instance,"__init__")); - int sz(PyTuple_Size(args)); - - if(PyTuple_Size(args)==2 && PyDict_Check(PyTuple_GetItem(args,1)) && PyDict_Size(PyTuple_GetItem(args,1))==1 ) - {// NOT general case. only true if in unpickeling context ! call __init__. Because for all other cases, __init__ is called right after __new__ ! - PyObject *zeNumpyRepr(0); - PyObject *tmp1(PyInt_FromLong(0)); - zeNumpyRepr=PyDict_GetItem(PyTuple_GetItem(args,1),tmp1);//borrowed - Py_DECREF(tmp1); - PyObject *tmp3(PyTuple_New(1)); - PyTuple_SetItem(tmp3,0,zeNumpyRepr); Py_XINCREF(zeNumpyRepr); - PyObject *tmp2(PyObject_CallObject(initMeth,tmp3)); - Py_XDECREF(tmp2); - Py_DECREF(tmp3); - } - Py_DECREF(initMeth); - return instance; - } - - PyObject *__getnewargs__() throw(INTERP_KERNEL::Exception) - { -#ifdef WITH_NUMPY - if(!self->isAllocated()) - throw INTERP_KERNEL::Exception("PyWrap of DataArrayInt.__getnewargs__ : self is not allocated !"); - PyObject *ret(PyTuple_New(1)); - PyObject *ret0(PyDict_New()); - PyObject *numpyArryObj(ParaMEDMEM_DataArrayInt_toNumPyArray(self)); - {// create a dict to discriminite in __new__ if __init__ should be called. Not beautiful but not idea ... - PyObject *tmp1(PyInt_FromLong(0)); - PyDict_SetItem(ret0,tmp1,numpyArryObj); Py_DECREF(tmp1); Py_DECREF(numpyArryObj); - PyTuple_SetItem(ret,0,ret0); - } - return ret; -#else - throw INTERP_KERNEL::Exception("PyWrap of DataArrayInt.__getnewargs__ : not implemented because numpy is not active in your configuration ! No serialization/unserialization available without numpy !"); -#endif - } - } - }; - - class DataArrayIntTuple; - - class DataArrayIntIterator - { - public: - DataArrayIntIterator(DataArrayInt *da); - ~DataArrayIntIterator(); - %extend - { - PyObject *next() - { - DataArrayIntTuple *ret=self->nextt(); - if(ret) - return SWIG_NewPointerObj(SWIG_as_voidptr(ret),SWIGTYPE_p_ParaMEDMEM__DataArrayIntTuple,SWIG_POINTER_OWN | 0); - else - { - PyErr_SetString(PyExc_StopIteration,"No more data."); - return 0; - } - } - } - }; - - class DataArrayIntTuple - { - public: - int getNumberOfCompo() const throw(INTERP_KERNEL::Exception); - DataArrayInt *buildDAInt(int nbOfTuples, int nbOfCompo) const throw(INTERP_KERNEL::Exception); - %extend - { - std::string __str__() const throw(INTERP_KERNEL::Exception) - { - return self->repr(); - } - - int __int__() const throw(INTERP_KERNEL::Exception) - { - return self->intValue(); - } - - DataArrayInt *buildDAInt() throw(INTERP_KERNEL::Exception) - { - return self->buildDAInt(1,self->getNumberOfCompo()); - } - - PyObject *___iadd___(PyObject *trueSelf, PyObject *obj) throw(INTERP_KERNEL::Exception) - { - MEDCouplingAutoRefCountObjectPtr ret=self->buildDAInt(1,self->getNumberOfCompo()); - ParaMEDMEM_DataArrayInt____iadd___(ret,0,obj); - Py_XINCREF(trueSelf); - return trueSelf; - } - - PyObject *___isub___(PyObject *trueSelf, PyObject *obj) throw(INTERP_KERNEL::Exception) - { - MEDCouplingAutoRefCountObjectPtr ret=self->buildDAInt(1,self->getNumberOfCompo()); - ParaMEDMEM_DataArrayInt____isub___(ret,0,obj); - Py_XINCREF(trueSelf); - return trueSelf; - } - - PyObject *___imul___(PyObject *trueSelf, PyObject *obj) throw(INTERP_KERNEL::Exception) - { - MEDCouplingAutoRefCountObjectPtr ret=self->buildDAInt(1,self->getNumberOfCompo()); - ParaMEDMEM_DataArrayInt____imul___(ret,0,obj); - Py_XINCREF(trueSelf); - return trueSelf; - } - - PyObject *___idiv___(PyObject *trueSelf, PyObject *obj) throw(INTERP_KERNEL::Exception) - { - MEDCouplingAutoRefCountObjectPtr ret=self->buildDAInt(1,self->getNumberOfCompo()); - ParaMEDMEM_DataArrayInt____idiv___(ret,0,obj); - Py_XINCREF(trueSelf); - return trueSelf; - } - - PyObject *___imod___(PyObject *trueSelf, PyObject *obj) throw(INTERP_KERNEL::Exception) - { - MEDCouplingAutoRefCountObjectPtr ret=self->buildDAInt(1,self->getNumberOfCompo()); - ParaMEDMEM_DataArrayInt____imod___(ret,0,obj); - Py_XINCREF(trueSelf); - return trueSelf; - } - - PyObject *__len__() throw(INTERP_KERNEL::Exception) - { - return PyInt_FromLong(self->getNumberOfCompo()); - } - - PyObject *__getitem__(PyObject *obj) throw(INTERP_KERNEL::Exception) - { - const char msg2[]="DataArrayIntTuple::__getitem__ : Mismatch of slice values in 2nd parameter (components) !"; - int sw; - int singleVal; - std::vector multiVal; - std::pair > slic; - ParaMEDMEM::DataArrayInt *daIntTyypp=0; - const int *pt=self->getConstPointer(); - int nbc=self->getNumberOfCompo(); - convertObjToPossibleCpp2WithNegIntInterp(obj,nbc,sw,singleVal,multiVal,slic,daIntTyypp); - switch(sw) - { - case 1: - { - if(singleVal>=nbc) - { - std::ostringstream oss; - oss << "Requesting for id " << singleVal << " having only " << nbc << " components !"; - PyErr_SetString(PyExc_StopIteration,oss.str().c_str()); - return 0; - } - if(singleVal>=0) - return PyInt_FromLong(pt[singleVal]); - else - { - if(nbc+singleVal>0) - return PyInt_FromLong(pt[nbc+singleVal]); - else - { - std::ostringstream oss; - oss << "Requesting for id " << singleVal << " having only " << nbc << " components !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - } - } - case 2: - { - PyObject *t=PyTuple_New(multiVal.size()); - for(int j=0;j<(int)multiVal.size();j++) - { - int cid=multiVal[j]; - if(cid>=nbc) - { - std::ostringstream oss; - oss << "Requesting for id #" << cid << " having only " << nbc << " components !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - PyTuple_SetItem(t,j,PyInt_FromLong(pt[cid])); - } - return t; - } - case 3: - { - int sz=DataArray::GetNumberOfItemGivenBES(slic.first,slic.second.first,slic.second.second,msg2); - PyObject *t=PyTuple_New(sz); - for(int j=0;j multiValV; - std::pair > slicV; - ParaMEDMEM::DataArrayIntTuple *daIntTyyppV=0; - int nbc=self->getNumberOfCompo(); - convertObjToPossibleCpp22(value,nbc,sw1,singleValV,multiValV,slicV,daIntTyyppV); - int singleVal; - std::vector multiVal; - std::pair > slic; - ParaMEDMEM::DataArrayInt *daIntTyypp=0; - int *pt=self->getPointer(); - convertObjToPossibleCpp2WithNegIntInterp(obj,nbc,sw2,singleVal,multiVal,slic,daIntTyypp); - switch(sw2) - { - case 1: - { - if(singleVal>=nbc) - { - std::ostringstream oss; - oss << "Requesting for setting id # " << singleVal << " having only " << nbc << " components !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - switch(sw1) - { - case 1: - { - pt[singleVal]=singleValV; - return self; - } - case 2: - { - if(multiValV.size()!=1) - { - std::ostringstream oss; - oss << "Requesting for setting id # " << singleVal << " with a list or tuple with size != 1 ! "; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - pt[singleVal]=multiValV[0]; - return self; - } - case 4: - { - pt[singleVal]=daIntTyyppV->getConstPointer()[0]; - return self; - } - default: - throw INTERP_KERNEL::Exception(msg); - } - } - case 2: - { - switch(sw1) - { - case 1: - { - for(std::vector::const_iterator it=multiVal.begin();it!=multiVal.end();it++) - { - if(*it>=nbc) - { - std::ostringstream oss; - oss << "Requesting for setting id # " << *it << " having only " << nbc << " components !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - pt[*it]=singleValV; - } - return self; - } - case 2: - { - if(multiVal.size()!=multiValV.size()) - { - std::ostringstream oss; - oss << "Mismatch length of during assignment : " << multiValV.size() << " != " << multiVal.size() << " !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - for(int i=0;i<(int)multiVal.size();i++) - { - int pos=multiVal[i]; - if(pos>=nbc) - { - std::ostringstream oss; - oss << "Requesting for setting id # " << pos << " having only " << nbc << " components !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - pt[multiVal[i]]=multiValV[i]; - } - return self; - } - case 4: - { - const int *ptV=daIntTyyppV->getConstPointer(); - if(nbc>daIntTyyppV->getNumberOfCompo()) - { - std::ostringstream oss; - oss << "Mismatch length of during assignment : " << nbc << " != " << daIntTyyppV->getNumberOfCompo() << " !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - std::copy(ptV,ptV+nbc,pt); - return self; - } - default: - throw INTERP_KERNEL::Exception(msg); - } - } - case 3: - { - int sz=DataArray::GetNumberOfItemGivenBES(slic.first,slic.second.first,slic.second.second,msg2); - switch(sw1) - { - case 1: - { - for(int j=0;jgetConstPointer(); - if(sz>daIntTyyppV->getNumberOfCompo()) - { - std::ostringstream oss; - oss << "Mismatch length of during assignment : " << nbc << " != " << daIntTyyppV->getNumberOfCompo() << " !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - for(int j=0;j& tupl) const throw(INTERP_KERNEL::Exception); - bool presenceOfTuple(const std::vector& tupl) const throw(INTERP_KERNEL::Exception); - char getMaxValue(int& tupleId) const throw(INTERP_KERNEL::Exception); - char getMaxValueInArray() const throw(INTERP_KERNEL::Exception); - char getMinValue(int& tupleId) const throw(INTERP_KERNEL::Exception); - char getMinValueInArray() const throw(INTERP_KERNEL::Exception); - DataArrayInt *getIdsInRange(char vmin, char vmax) const throw(INTERP_KERNEL::Exception); - static DataArrayChar *Aggregate(const DataArrayChar *a1, const DataArrayChar *a2) throw(INTERP_KERNEL::Exception); - static DataArrayChar *Meld(const DataArrayChar *a1, const DataArrayChar *a2) throw(INTERP_KERNEL::Exception); - %extend - { - int __len__() const throw(INTERP_KERNEL::Exception) - { - if(self->isAllocated()) - { - return self->getNumberOfTuples(); - } - else - { - throw INTERP_KERNEL::Exception("DataArrayChar::__len__ : Instance is NOT allocated !"); - } - } - - PyObject *isEqualIfNotWhy(const DataArrayChar& other) const throw(INTERP_KERNEL::Exception) - { - std::string ret1; - bool ret0=self->isEqualIfNotWhy(other,ret1); - PyObject *ret=PyTuple_New(2); - PyObject *ret0Py=ret0?Py_True:Py_False; - Py_XINCREF(ret0Py); - PyTuple_SetItem(ret,0,ret0Py); - PyTuple_SetItem(ret,1,PyString_FromString(ret1.c_str())); - return ret; - } - - DataArrayChar *renumber(PyObject *li) throw(INTERP_KERNEL::Exception) - { - void *da=0; - int res1=SWIG_ConvertPtr(li,&da,SWIGTYPE_p_ParaMEDMEM__DataArrayInt, 0 | 0 ); - if (!SWIG_IsOK(res1)) - { - int size; - INTERP_KERNEL::AutoPtr tmp=convertPyToNewIntArr2(li,&size); - if(size!=self->getNumberOfTuples()) - { - throw INTERP_KERNEL::Exception("Invalid list length ! Must be equal to number of tuples !"); - } - return self->renumber(tmp); - } - else - { - DataArrayInt *da2=reinterpret_cast< DataArrayInt * >(da); - if(!da2) - throw INTERP_KERNEL::Exception("Not null DataArrayInt instance expected !"); - da2->checkAllocated(); - int size=self->getNumberOfTuples(); - if(size!=self->getNumberOfTuples()) - { - throw INTERP_KERNEL::Exception("Invalid list length ! Must be equal to number of tuples !"); - } - return self->renumber(da2->getConstPointer()); - } - } - - DataArrayChar *renumberR(PyObject *li) throw(INTERP_KERNEL::Exception) - { - void *da=0; - int res1=SWIG_ConvertPtr(li,&da,SWIGTYPE_p_ParaMEDMEM__DataArrayInt, 0 | 0 ); - if (!SWIG_IsOK(res1)) - { - int size; - INTERP_KERNEL::AutoPtr tmp=convertPyToNewIntArr2(li,&size); - if(size!=self->getNumberOfTuples()) - { - throw INTERP_KERNEL::Exception("Invalid list length ! Must be equal to number of tuples !"); - } - return self->renumberR(tmp); - } - else - { - DataArrayInt *da2=reinterpret_cast< DataArrayInt * >(da); - if(!da2) - throw INTERP_KERNEL::Exception("Not null DataArrayInt instance expected !"); - da2->checkAllocated(); - int size=self->getNumberOfTuples(); - if(size!=self->getNumberOfTuples()) - { - throw INTERP_KERNEL::Exception("Invalid list length ! Must be equal to number of tuples !"); - } - return self->renumberR(da2->getConstPointer()); - } - } - - DataArrayChar *renumberAndReduce(PyObject *li, int newNbOfTuple) throw(INTERP_KERNEL::Exception) - { - void *da=0; - int res1=SWIG_ConvertPtr(li,&da,SWIGTYPE_p_ParaMEDMEM__DataArrayInt, 0 | 0 ); - if (!SWIG_IsOK(res1)) - { - int size; - INTERP_KERNEL::AutoPtr tmp=convertPyToNewIntArr2(li,&size); - if(size!=self->getNumberOfTuples()) - { - throw INTERP_KERNEL::Exception("Invalid list length ! Must be equal to number of tuples !"); - } - return self->renumberAndReduce(tmp,newNbOfTuple); - } - else - { - DataArrayInt *da2=reinterpret_cast< DataArrayInt * >(da); - if(!da2) - throw INTERP_KERNEL::Exception("Not null DataArrayInt instance expected !"); - da2->checkAllocated(); - int size=self->getNumberOfTuples(); - if(size!=self->getNumberOfTuples()) - { - throw INTERP_KERNEL::Exception("Invalid list length ! Must be equal to number of tuples !"); - } - return self->renumberAndReduce(da2->getConstPointer(),newNbOfTuple); - } - } - - static DataArrayChar *Aggregate(PyObject *dachs) throw(INTERP_KERNEL::Exception) - { - std::vector tmp; - convertFromPyObjVectorOfObj(dachs,SWIGTYPE_p_ParaMEDMEM__DataArrayChar,"DataArrayChar",tmp); - return DataArrayChar::Aggregate(tmp); - } - - static DataArrayChar *Meld(PyObject *dachs) throw(INTERP_KERNEL::Exception) - { - std::vector tmp; - convertFromPyObjVectorOfObj(dachs,SWIGTYPE_p_ParaMEDMEM__DataArrayChar,"DataArrayChar",tmp); - return DataArrayChar::Meld(tmp); - } - } - }; - - class DataArrayByteIterator; - - class DataArrayByte : public DataArrayChar - { - public: - static DataArrayByte *New(); - DataArrayByteIterator *iterator() throw(INTERP_KERNEL::Exception); - DataArrayByte *performCpy(bool deepCpy) const throw(INTERP_KERNEL::Exception); - char byteValue() const throw(INTERP_KERNEL::Exception); - %extend - { - DataArrayByte() throw(INTERP_KERNEL::Exception) - { - return DataArrayByte::New(); - } - - static DataArrayByte *New(PyObject *elt0, PyObject *nbOfTuples=0, PyObject *nbOfComp=0) throw(INTERP_KERNEL::Exception) - { - const char *msg="ParaMEDMEM::DataArrayByte::New : Available API are : \n-DataArrayByte.New()\n--DataArrayByte.New([1,3,4])\n-DataArrayByte.New([1,3,4],3)\n-DataArrayByte.New([1,3,4,5],2,2)\n-DataArrayByte.New(5)\n-DataArrayByte.New(5,2) !"; - if(PyList_Check(elt0) || PyTuple_Check(elt0)) - { - if(nbOfTuples) - { - if(PyInt_Check(nbOfTuples)) - { - int nbOfTuples1=PyInt_AS_LONG(nbOfTuples); - if(nbOfTuples1<0) - throw INTERP_KERNEL::Exception("DataArrayByte::New : should be a positive set of allocated memory !"); - if(nbOfComp) - { - if(PyInt_Check(nbOfComp)) - {//DataArrayByte.New([1,3,4,5],2,2) - int nbOfCompo=PyInt_AS_LONG(nbOfComp); - if(nbOfCompo<0) - throw INTERP_KERNEL::Exception("DataArrayByte::New : should be a positive number of components !"); - MEDCouplingAutoRefCountObjectPtr ret=DataArrayByte::New(); - std::vector tmp=fillArrayWithPyListInt2(elt0,nbOfTuples1,nbOfCompo); - ret->alloc(nbOfTuples1,nbOfCompo); std::copy(tmp.begin(),tmp.end(),ret->getPointer()); - return ret.retn(); - } - else - throw INTERP_KERNEL::Exception(msg); - } - else - {//DataArrayByte.New([1,3,4],3) - MEDCouplingAutoRefCountObjectPtr ret=DataArrayByte::New(); - int tmpp1=-1; - std::vector tmp=fillArrayWithPyListInt2(elt0,nbOfTuples1,tmpp1); - ret->alloc(nbOfTuples1,tmpp1); std::copy(tmp.begin(),tmp.end(),ret->getPointer()); - return ret.retn(); - } - } - else - throw INTERP_KERNEL::Exception(msg); - } - else - {// DataArrayByte.New([1,3,4]) - MEDCouplingAutoRefCountObjectPtr ret=DataArrayByte::New(); - int tmpp1=-1,tmpp2=-1; - std::vector tmp=fillArrayWithPyListInt2(elt0,tmpp1,tmpp2); - ret->alloc(tmpp1,tmpp2); std::copy(tmp.begin(),tmp.end(),ret->getPointer()); - return ret.retn(); - } - } - else if(PyInt_Check(elt0)) - { - int nbOfTuples1=PyInt_AS_LONG(elt0); - if(nbOfTuples1<0) - throw INTERP_KERNEL::Exception("DataArrayByte::New : should be a positive set of allocated memory !"); - if(nbOfTuples) - { - if(!nbOfComp) - { - if(PyInt_Check(nbOfTuples)) - {//DataArrayByte.New(5,2) - int nbOfCompo=PyInt_AS_LONG(nbOfTuples); - if(nbOfCompo<0) - throw INTERP_KERNEL::Exception("DataArrayByte::New : should be a positive number of components !"); - MEDCouplingAutoRefCountObjectPtr ret=DataArrayByte::New(); - ret->alloc(nbOfTuples1,nbOfCompo); - return ret.retn(); - } - else - throw INTERP_KERNEL::Exception(msg); - } - else - throw INTERP_KERNEL::Exception(msg); - } - else - {//DataArrayByte.New(5) - MEDCouplingAutoRefCountObjectPtr ret=DataArrayByte::New(); - ret->alloc(nbOfTuples1,1); - return ret.retn(); - } - } - else - throw INTERP_KERNEL::Exception(msg); - } - - DataArrayByte(PyObject *elt0, PyObject *nbOfTuples=0, PyObject *nbOfComp=0) throw(INTERP_KERNEL::Exception) - { - return ParaMEDMEM_DataArrayByte_New__SWIG_1(elt0,nbOfTuples,nbOfComp); - } - - std::string __repr__() const throw(INTERP_KERNEL::Exception) - { - std::ostringstream oss; - self->reprQuickOverview(oss); - return oss.str(); - } - - int __int__() const throw(INTERP_KERNEL::Exception) - { - return (int) self->byteValue(); - } - - DataArrayByteIterator *__iter__() throw(INTERP_KERNEL::Exception) - { - return self->iterator(); - } - - int getIJ(int tupleId, int compoId) const throw(INTERP_KERNEL::Exception) - { - return (int)self->getIJ(tupleId,compoId); - } - - int getIJSafe(int tupleId, int compoId) const throw(INTERP_KERNEL::Exception) - { - return (int)self->getIJSafe(tupleId,compoId); - } - - std::string __str__() const throw(INTERP_KERNEL::Exception) - { - return self->repr(); - } - - PyObject *toStrList() const throw(INTERP_KERNEL::Exception) - { - const char *vals=self->getConstPointer(); - int nbOfComp=self->getNumberOfComponents(); - int nbOfTuples=self->getNumberOfTuples(); - return convertCharArrToPyListOfTuple(vals,nbOfComp,nbOfTuples); - } - - bool presenceOfTuple(PyObject *tupl) const throw(INTERP_KERNEL::Exception) - { - int sz=-1,sw=-1; - int ival=-1; std::vector ivval; - const int *pt=convertObjToPossibleCpp1_Safe(tupl,sw,sz,ival,ivval); - std::vector vals(sz); - std::copy(pt,pt+sz,vals.begin()); - return self->presenceOfTuple(vals); - } - - bool presenceOfValue(PyObject *vals) const throw(INTERP_KERNEL::Exception) - { - int sz=-1,sw=-1; - int ival=-1; std::vector ivval; - const int *pt=convertObjToPossibleCpp1_Safe(vals,sw,sz,ival,ivval); - std::vector vals2(sz); - std::copy(pt,pt+sz,vals2.begin()); - return self->presenceOfValue(vals2); - } - - int locateValue(PyObject *vals) const throw(INTERP_KERNEL::Exception) - { - int sz=-1,sw=-1; - int ival=-1; std::vector ivval; - const int *pt=convertObjToPossibleCpp1_Safe(vals,sw,sz,ival,ivval); - std::vector vals2(sz); - std::copy(pt,pt+sz,vals2.begin()); - return self->locateValue(vals2); - } - - int locateTuple(PyObject *tupl) const throw(INTERP_KERNEL::Exception) - { - int sz=-1,sw=-1; - int ival=-1; std::vector ivval; - const int *pt=convertObjToPossibleCpp1_Safe(tupl,sw,sz,ival,ivval); - std::vector vals(sz); - std::copy(pt,pt+sz,vals.begin()); - return self->locateTuple(vals); - } - - int search(PyObject *strOrListOfInt) const throw(INTERP_KERNEL::Exception) - { - int sz=-1,sw=-1; - int ival=-1; std::vector ivval; - const int *pt=convertObjToPossibleCpp1_Safe(strOrListOfInt,sw,sz,ival,ivval); - std::vector vals(sz); - std::copy(pt,pt+sz,vals.begin()); - return self->search(vals); - } - - PyObject *getTuple(int tupleId) throw(INTERP_KERNEL::Exception) - { - int sz=self->getNumberOfComponents(); - INTERP_KERNEL::AutoPtr tmp=new char[sz]; - self->getTuple(tupleId,tmp); - PyObject *ret=PyTuple_New(sz); - for(int i=0;igetMaxValue(tmp); - PyObject *ret=PyTuple_New(2); - PyTuple_SetItem(ret,0,PyInt_FromLong(r1)); - PyTuple_SetItem(ret,1,PyInt_FromLong(tmp)); - return ret; - } - - PyObject *getMinValue() const throw(INTERP_KERNEL::Exception) - { - int tmp; - int r1=(int)self->getMinValue(tmp); - PyObject *ret=PyTuple_New(2); - PyTuple_SetItem(ret,0,PyInt_FromLong(r1)); - PyTuple_SetItem(ret,1,PyInt_FromLong(tmp)); - return ret; - } - - int index(PyObject *obj) const throw(INTERP_KERNEL::Exception) - { - int nbOfCompo=self->getNumberOfComponents(); - switch(nbOfCompo) - { - case 1: - { - if(PyInt_Check(obj)) - { - int val=(int)PyInt_AS_LONG(obj); - return self->locateValue(val); - } - else - throw INTERP_KERNEL::Exception("DataArrayByte::index : 'this' contains one component and trying to find an element which is not an integer !"); - } - default: - return ParaMEDMEM_DataArrayByte_locateTuple(self,obj); - } - } - - bool __contains__(PyObject *obj) const throw(INTERP_KERNEL::Exception) - { - int nbOfCompo=self->getNumberOfComponents(); - switch(nbOfCompo) - { - case 0: - return false; - case 1: - { - if(PyInt_Check(obj)) - { - int val=(int)PyInt_AS_LONG(obj); - return self->presenceOfValue(val); - } - else - throw INTERP_KERNEL::Exception("DataArrayByte::__contains__ : 'this' contains one component and trying to find an element which is not an integer !"); - } - default: - return ParaMEDMEM_DataArrayByte_presenceOfTuple(self,obj); - } - } - - DataArrayByte *__setitem__(PyObject *obj, PyObject *value) throw(INTERP_KERNEL::Exception) - { - self->checkAllocated(); - const char msg[]="Unexpected situation in __setitem__ !"; - int nbOfTuples(self->getNumberOfTuples()),nbOfComponents(self->getNumberOfComponents()); - int sw1,sw2; - int i1; - std::vector v1; - DataArrayInt *d1=0; - DataArrayIntTuple *dd1=0; - convertObjToPossibleCpp1(value,sw1,i1,v1,d1,dd1); - int it1,ic1; - std::vector vt1,vc1; - std::pair > pt1,pc1; - DataArrayInt *dt1=0,*dc1=0; - convertObjToPossibleCpp3(obj,nbOfTuples,nbOfComponents,sw2,it1,ic1,vt1,vc1,pt1,pc1,dt1,dc1); - MEDCouplingAutoRefCountObjectPtr tmp; - switch(sw2) - { - case 1: - { - switch(sw1) - { - case 1: - self->setPartOfValuesSimple1(i1,it1,it1+1,1,0,nbOfComponents,1); - return self; - default: - throw INTERP_KERNEL::Exception(msg); - } - break; - } - case 2: - { - switch(sw1) - { - case 1: - self->setPartOfValuesSimple3(i1,&vt1[0],&vt1[0]+vt1.size(),0,nbOfComponents,1); - return self; - default: - throw INTERP_KERNEL::Exception(msg); - } - break; - } - case 3: - { - switch(sw1) - { - case 1: - self->setPartOfValuesSimple1(i1,pt1.first,pt1.second.first,pt1.second.second,0,nbOfComponents,1); - return self; - default: - throw INTERP_KERNEL::Exception(msg); - } - break; - } - case 4: - { - switch(sw1) - { - case 1: - self->setPartOfValuesSimple3(i1,dt1->getConstPointer(),dt1->getConstPointer()+dt1->getNbOfElems(),0,nbOfComponents,1); - return self; - default: - throw INTERP_KERNEL::Exception(msg); - } - break; - } - case 5: - { - switch(sw1) - { - case 1: - self->setPartOfValuesSimple1(i1,it1,it1+1,1,ic1,ic1+1,1); - return self; - default: - throw INTERP_KERNEL::Exception(msg); - } - break; - } - case 6: - { - switch(sw1) - { - case 1: - self->setPartOfValuesSimple3(i1,&vt1[0],&vt1[0]+vt1.size(),ic1,ic1+1,1); - return self; - default: - throw INTERP_KERNEL::Exception(msg); - } - break; - } - case 7: - { - switch(sw1) - { - case 1: - self->setPartOfValuesSimple1(i1,pt1.first,pt1.second.first,pt1.second.second,ic1,ic1+1,1); - return self; - default: - throw INTERP_KERNEL::Exception(msg); - } - break; - } - case 8: - { - switch(sw1) - { - case 1: - self->setPartOfValuesSimple3(i1,dt1->getConstPointer(),dt1->getConstPointer()+dt1->getNbOfElems(),ic1,ic1+1,1); - return self; - default: - throw INTERP_KERNEL::Exception(msg); - } - break; - } - case 9: - { - switch(sw1) - { - case 1: - self->setPartOfValuesSimple2(i1,&it1,&it1+1,&vc1[0],&vc1[0]+vc1.size()); - return self; - default: - throw INTERP_KERNEL::Exception(msg); - } - break; - } - case 10: - { - switch(sw1) - { - case 1: - self->setPartOfValuesSimple2(i1,&vt1[0],&vt1[0]+vt1.size(),&vc1[0],&vc1[0]+vc1.size()); - return self; - default: - throw INTERP_KERNEL::Exception(msg); - } - break; - } - case 11: - { - switch(sw1) - { - case 1: - self->setPartOfValuesSimple4(i1,pt1.first,pt1.second.first,pt1.second.second,&vc1[0],&vc1[0]+vc1.size()); - return self; - default: - throw INTERP_KERNEL::Exception(msg); - } - break; - } - case 12: - { - switch(sw1) - { - case 1: - self->setPartOfValuesSimple2(i1,dt1->getConstPointer(),dt1->getConstPointer()+dt1->getNbOfElems(),&vc1[0],&vc1[0]+vc1.size()); - return self; - default: - throw INTERP_KERNEL::Exception(msg); - } - break; - } - case 13: - { - switch(sw1) - { - case 1: - self->setPartOfValuesSimple1(i1,it1,it1+1,1,pc1.first,pc1.second.first,pc1.second.second); - return self; - default: - throw INTERP_KERNEL::Exception(msg); - } - break; - } - case 14: - { - switch(sw1) - { - case 1: - self->setPartOfValuesSimple3(i1,&vt1[0],&vt1[0]+vt1.size(),pc1.first,pc1.second.first,pc1.second.second); - return self; - default: - throw INTERP_KERNEL::Exception(msg); - } - break; - } - case 15: - { - switch(sw1) - { - case 1: - self->setPartOfValuesSimple1(i1,pt1.first,pt1.second.first,pt1.second.second,pc1.first,pc1.second.first,pc1.second.second); - return self; - default: - throw INTERP_KERNEL::Exception(msg); - } - break; - } - case 16: - { - switch(sw1) - { - case 1: - self->setPartOfValuesSimple3(i1,dt1->getConstPointer(),dt1->getConstPointer()+dt1->getNbOfElems(),pc1.first,pc1.second.first,pc1.second.second); - return self; - default: - throw INTERP_KERNEL::Exception(msg); - } - break; - } - default: - throw INTERP_KERNEL::Exception(msg); - } - return self; - } - } - }; - - class DataArrayByteTuple; - - class DataArrayByteIterator - { - public: - DataArrayByteIterator(DataArrayByte *da); - ~DataArrayByteIterator(); - }; - - class DataArrayByteTuple - { - public: - std::string repr() const throw(INTERP_KERNEL::Exception); - DataArrayByte *buildDAByte(int nbOfTuples, int nbOfCompo) const throw(INTERP_KERNEL::Exception); - %extend - { - std::string __str__() const throw(INTERP_KERNEL::Exception) - { - return self->repr(); - } - - char __int__() const throw(INTERP_KERNEL::Exception) - { - return self->byteValue(); - } - - DataArrayByte *buildDAByte() throw(INTERP_KERNEL::Exception) - { - return self->buildDAByte(1,self->getNumberOfCompo()); - } - } - }; - - class DataArrayAsciiCharIterator; - - class DataArrayAsciiChar : public DataArrayChar - { - public: - static DataArrayAsciiChar *New(); - DataArrayAsciiCharIterator *iterator() throw(INTERP_KERNEL::Exception); - DataArrayAsciiChar *performCpy(bool deepCpy) const throw(INTERP_KERNEL::Exception); - char asciiCharValue() const throw(INTERP_KERNEL::Exception); - %extend - { - DataArrayAsciiChar() throw(INTERP_KERNEL::Exception) - { - return DataArrayAsciiChar::New(); - } - - static DataArrayAsciiChar *New(PyObject *elt0, PyObject *nbOfTuples=0, PyObject *nbOfComp=0) throw(INTERP_KERNEL::Exception) - { - const char *msg="ParaMEDMEM::DataArrayAsciiChar::New : Available API are : \n-DataArrayAsciiChar.New()\n-DataArrayAsciiChar.New([1,3,4])\n-DataArrayAsciiChar.New([\"abc\",\"de\",\"fghi\"])\n-DataArrayAsciiChar.New([\"abc\",\"de\",\"fghi\"],\"t\")\n-DataArrayAsciiChar.New([1,3,4],3)\n-DataArrayAsciiChar.New([1,3,4,5],2,2)\n-DataArrayAsciiChar.New(5)\n-DataArrayAsciiChar.New(5,2) !"; - if(PyList_Check(elt0) || PyTuple_Check(elt0)) - { - if(nbOfTuples) - { - if(PyInt_Check(nbOfTuples)) - { - int nbOfTuples1=PyInt_AS_LONG(nbOfTuples); - if(nbOfTuples1<0) - throw INTERP_KERNEL::Exception("DataArrayAsciiChar::New : should be a positive set of allocated memory !"); - if(nbOfComp) - { - if(PyInt_Check(nbOfComp)) - {//DataArrayAsciiChar.New([1,3,4,5],2,2) - int nbOfCompo=PyInt_AS_LONG(nbOfComp); - if(nbOfCompo<0) - throw INTERP_KERNEL::Exception("DataArrayAsciiChar::New : should be a positive number of components !"); - MEDCouplingAutoRefCountObjectPtr ret=DataArrayAsciiChar::New(); - std::vector tmp=fillArrayWithPyListInt2(elt0,nbOfTuples1,nbOfCompo); - ret->alloc(nbOfTuples1,nbOfCompo); std::copy(tmp.begin(),tmp.end(),ret->getPointer()); - return ret.retn(); - } - else - throw INTERP_KERNEL::Exception(msg); - } - else - {//DataArrayAsciiChar.New([1,3,4],3) - MEDCouplingAutoRefCountObjectPtr ret=DataArrayAsciiChar::New(); - int tmpp1=-1; - std::vector tmp=fillArrayWithPyListInt2(elt0,nbOfTuples1,tmpp1); - ret->alloc(nbOfTuples1,tmpp1); std::copy(tmp.begin(),tmp.end(),ret->getPointer()); - return ret.retn(); - } - } - else if(PyString_Check(nbOfTuples)) - { - if(PyString_Size(nbOfTuples)!=1) - throw INTERP_KERNEL::Exception(msg); - //DataArrayAsciiChar.New(["abc","de","fghi"],"t") - std::vector tmp; - if(fillStringVector(elt0,tmp)) - return DataArrayAsciiChar::New(tmp,PyString_AsString(nbOfTuples)[0]); - else - throw INTERP_KERNEL::Exception(msg); - } - else - throw INTERP_KERNEL::Exception(msg); - } - else - { - std::vector tmmp; - if(fillStringVector(elt0,tmmp)) - //DataArrayAsciiChar.New(["abc","de","fghi"]) - return DataArrayAsciiChar::New(tmmp,' '); - else - { - // DataArrayAsciiChar.New([1,3,4]) - MEDCouplingAutoRefCountObjectPtr ret=DataArrayAsciiChar::New(); - int tmpp1=-1,tmpp2=-1; - std::vector tmp=fillArrayWithPyListInt2(elt0,tmpp1,tmpp2); - ret->alloc(tmpp1,tmpp2); std::copy(tmp.begin(),tmp.end(),ret->getPointer()); - return ret.retn(); - } - } - } - else if(PyInt_Check(elt0)) - { - int nbOfTuples1=PyInt_AS_LONG(elt0); - if(nbOfTuples1<0) - throw INTERP_KERNEL::Exception("DataArrayAsciiChar::New : should be a positive set of allocated memory !"); - if(nbOfTuples) - { - if(!nbOfComp) - { - if(PyInt_Check(nbOfTuples)) - {//DataArrayAsciiChar.New(5,2) - int nbOfCompo=PyInt_AS_LONG(nbOfTuples); - if(nbOfCompo<0) - throw INTERP_KERNEL::Exception("DataArrayAsciiChar::New : should be a positive number of components !"); - MEDCouplingAutoRefCountObjectPtr ret=DataArrayAsciiChar::New(); - ret->alloc(nbOfTuples1,nbOfCompo); - return ret.retn(); - } - else - throw INTERP_KERNEL::Exception(msg); - } - else - throw INTERP_KERNEL::Exception(msg); - } - else - {//DataArrayAsciiChar.New(5) - MEDCouplingAutoRefCountObjectPtr ret=DataArrayAsciiChar::New(); - ret->alloc(nbOfTuples1,1); - return ret.retn(); - } - } - else - throw INTERP_KERNEL::Exception(msg); - } - - DataArrayAsciiChar(PyObject *elt0, PyObject *nbOfTuples=0, PyObject *nbOfComp=0) throw(INTERP_KERNEL::Exception) - { - return ParaMEDMEM_DataArrayAsciiChar_New__SWIG_1(elt0,nbOfTuples,nbOfComp); - } - - std::string __repr__() const throw(INTERP_KERNEL::Exception) - { - std::ostringstream oss; - self->reprQuickOverview(oss); - return oss.str(); - } - - DataArrayAsciiCharIterator *__iter__() throw(INTERP_KERNEL::Exception) - { - return self->iterator(); - } - - std::string getIJ(int tupleId, int compoId) const throw(INTERP_KERNEL::Exception) - { - char tmp[2]; tmp[1]='\0'; - tmp[0]=self->getIJ(tupleId,compoId); - return std::string(tmp); - } - - std::string getIJSafe(int tupleId, int compoId) const throw(INTERP_KERNEL::Exception) - { - char tmp[2]; tmp[1]='\0'; - tmp[0]=self->getIJSafe(tupleId,compoId); - return std::string(tmp); - } - - std::string __str__() const throw(INTERP_KERNEL::Exception) - { - return self->repr(); - } - - PyObject *toStrList() const throw(INTERP_KERNEL::Exception) - { - const char *vals=self->getConstPointer(); - int nbOfComp=self->getNumberOfComponents(); - int nbOfTuples=self->getNumberOfTuples(); - return convertCharArrToPyListOfTuple(vals,nbOfComp,nbOfTuples); - } - - bool presenceOfTuple(PyObject *tupl) const throw(INTERP_KERNEL::Exception) - { - if(PyString_Check(tupl)) - { - Py_ssize_t sz=PyString_Size(tupl); - std::vector vals(sz); - std::copy(PyString_AsString(tupl),PyString_AsString(tupl)+sz,vals.begin()); - return self->presenceOfTuple(vals); - } - else - throw INTERP_KERNEL::Exception("DataArrayAsciiChar::presenceOfTuple : only strings in input supported !"); - } - - bool presenceOfValue(PyObject *vals) const throw(INTERP_KERNEL::Exception) - { - if(PyString_Check(vals)) - { - Py_ssize_t sz=PyString_Size(vals); - std::vector vals2(sz); - std::copy(PyString_AsString(vals),PyString_AsString(vals)+sz,vals2.begin()); - return self->presenceOfValue(vals2); - } - else - throw INTERP_KERNEL::Exception("DataArrayAsciiChar::presenceOfValue : only strings in input supported !"); - } - - int locateValue(PyObject *vals) const throw(INTERP_KERNEL::Exception) - { - if(PyString_Check(vals)) - { - Py_ssize_t sz=PyString_Size(vals); - std::vector vals2(sz); - std::copy(PyString_AsString(vals),PyString_AsString(vals)+sz,vals2.begin()); - return self->locateValue(vals2); - } - else - throw INTERP_KERNEL::Exception("DataArrayAsciiChar::locateValue : only strings in input supported !"); - } - - int locateTuple(PyObject *tupl) const throw(INTERP_KERNEL::Exception) - { - if(PyString_Check(tupl)) - { - Py_ssize_t sz=PyString_Size(tupl); - std::vector vals(sz); - std::copy(PyString_AsString(tupl),PyString_AsString(tupl)+sz,vals.begin()); - return self->locateTuple(vals); - } - else - throw INTERP_KERNEL::Exception("DataArrayAsciiChar::locateTuple : only strings in input supported !"); - } - - int search(PyObject *strOrListOfInt) const throw(INTERP_KERNEL::Exception) - { - if(PyString_Check(strOrListOfInt)) - { - Py_ssize_t sz=PyString_Size(strOrListOfInt); - std::vector vals(sz); - std::copy(PyString_AsString(strOrListOfInt),PyString_AsString(strOrListOfInt)+sz,vals.begin()); - return self->search(vals); - } - else - throw INTERP_KERNEL::Exception("DataArrayAsciiChar::search : only strings in input supported !"); - } - - PyObject *getTuple(int tupleId) const throw(INTERP_KERNEL::Exception) - { - int sz=self->getNumberOfComponents(); - INTERP_KERNEL::AutoPtr tmp=new char[sz+1]; tmp[sz]='\0'; - self->getTuple(tupleId,tmp); - return PyString_FromString(tmp); - } - - PyObject *getMaxValue() const throw(INTERP_KERNEL::Exception) - { - int tmp; - char tmp2[2]; tmp2[1]='\0'; - tmp2[0]=self->getMaxValue(tmp); - PyObject *ret=PyTuple_New(2); - PyTuple_SetItem(ret,0,PyString_FromString(tmp2)); - PyTuple_SetItem(ret,1,PyInt_FromLong(tmp)); - return ret; - } - - PyObject *getMinValue() const throw(INTERP_KERNEL::Exception) - { - int tmp; - char tmp2[2]; tmp2[1]='\0'; - tmp2[0]=self->getMinValue(tmp); - PyObject *ret=PyTuple_New(2); - PyTuple_SetItem(ret,0,PyString_FromString(tmp2)); - PyTuple_SetItem(ret,1,PyInt_FromLong(tmp)); - return ret; - } - - int index(PyObject *obj) const throw(INTERP_KERNEL::Exception) - { - int nbOfCompo=self->getNumberOfComponents(); - switch(nbOfCompo) - { - case 1: - { - if(PyString_Check(obj)) - { - Py_ssize_t sz=PyString_Size(obj); - char *pt=PyString_AsString(obj); - if(sz==1) - return self->locateValue(pt[0]); - else - throw INTERP_KERNEL::Exception("DataArrayAsciiChar::index : 'this' contains one component and trying to find a string with size different from 1 !"); - } - else - throw INTERP_KERNEL::Exception("DataArrayAsciiChar::index : 'this' contains one component and trying to find an element which is not an integer !"); - } - default: - return ParaMEDMEM_DataArrayAsciiChar_locateTuple(self,obj); - } - } - - bool __contains__(PyObject *obj) const throw(INTERP_KERNEL::Exception) - { - int nbOfCompo=self->getNumberOfComponents(); - switch(nbOfCompo) - { - case 0: - return false; - case 1: - { - if(PyString_Check(obj)) - { - Py_ssize_t sz=PyString_Size(obj); - char *pt=PyString_AsString(obj); - if(sz==1) - return self->presenceOfValue(pt[0]); - else - throw INTERP_KERNEL::Exception("DataArrayAsciiChar::__contains__ : 'this' contains one component and trying to find a string with size different from 1 !"); - } - else - throw INTERP_KERNEL::Exception("DataArrayAsciiChar::__contains__ : 'this' contains one component and trying to find an element which is not an integer !"); - } - default: - return ParaMEDMEM_DataArrayAsciiChar_presenceOfTuple(self,obj); - } - } - - PyObject *__getitem__(PyObject *obj) const throw(INTERP_KERNEL::Exception) - { - int sw,iTypppArr; - std::vector stdvecTyyppArr; - std::pair > sTyyppArr; - ParaMEDMEM::DataArrayInt *daIntTyypp=0; - convertObjToPossibleCpp2WithNegIntInterp(obj,self->getNumberOfTuples(),sw,iTypppArr,stdvecTyyppArr,sTyyppArr,daIntTyypp); - switch(sw) - { - case 1: - return ParaMEDMEM_DataArrayAsciiChar_getTuple(self,iTypppArr); - case 2: - return convertDataArrayChar(self->selectByTupleIdSafe(&stdvecTyyppArr[0],&stdvecTyyppArr[0]+stdvecTyyppArr.size()), SWIG_POINTER_OWN | 0 ); - case 3: - return convertDataArrayChar(self->selectByTupleId2(sTyyppArr.first,sTyyppArr.second.first,sTyyppArr.second.second), SWIG_POINTER_OWN | 0 ); - case 4: - return convertDataArrayChar(self->selectByTupleIdSafe(daIntTyypp->begin(),daIntTyypp->end()), SWIG_POINTER_OWN | 0 ); - default: - throw INTERP_KERNEL::Exception("DataArrayAsciiChar::__getitem__ : supporting int, list of int, tuple of int, DataArrayInt and slice in input !"); - } - } - - DataArrayAsciiChar *__setitem__(PyObject *obj, PyObject *value) throw(INTERP_KERNEL::Exception) - { - static const char msg[]="DataArrayAsciiChar::__setitem__ : supporting int, list of int, tuple of int, DataArrayInt and slice in input, and 4 types accepted in value : string, list or tuple of strings having same size, not null DataArrayChar instance."; - int sw1,iTypppArr; - std::vector stdvecTyyppArr; - std::pair > sTyyppArr; - ParaMEDMEM::DataArrayInt *daIntTyypp=0; - int nbOfCompo=self->getNumberOfComponents(); - int nbOfTuples=self->getNumberOfTuples(); - convertObjToPossibleCpp2WithNegIntInterp(obj,nbOfTuples,sw1,iTypppArr,stdvecTyyppArr,sTyyppArr,daIntTyypp); - int sw2; - char vc; std::string sc; std::vector vsc; DataArrayChar *dacc=0; - convertObjToPossibleCpp6(value,sw2,vc,sc,vsc,dacc); - switch(sw1) - { - case 1: - {//obj int - switch(sw2) - {//value char - case 1: - { - self->setPartOfValuesSimple3(vc,&iTypppArr,&iTypppArr+1,0,nbOfCompo,1); - return self; - } - //value string - case 2: - { - MEDCouplingAutoRefCountObjectPtr tmp=DataArrayAsciiChar::New(sc); - self->setPartOfValues3(tmp,&iTypppArr,&iTypppArr+1,0,nbOfCompo,1,false); - return self; - } - //value vector - case 3: - { - MEDCouplingAutoRefCountObjectPtr tmp=DataArrayAsciiChar::New(vsc,' '); - self->setPartOfValues3(tmp,&iTypppArr,&iTypppArr+1,0,nbOfCompo,1,false); - return self; - } - //value DataArrayChar - case 4: - { - self->setPartOfValues3(dacc,&iTypppArr,&iTypppArr+1,0,nbOfCompo,1,false); - return self; - } - default: - throw INTERP_KERNEL::Exception(msg); - } - } - case 2: - {//obj list-tuple[int] - switch(sw2) - { - {//value char - case 1: - { - self->setPartOfValuesSimple3(vc,&stdvecTyyppArr[0],&stdvecTyyppArr[0]+stdvecTyyppArr.size(),0,nbOfCompo,1); - return self; - } - //value string - case 2: - { - MEDCouplingAutoRefCountObjectPtr tmp=DataArrayAsciiChar::New(sc); - self->setPartOfValues3(tmp,&stdvecTyyppArr[0],&stdvecTyyppArr[0]+stdvecTyyppArr.size(),0,nbOfCompo,1,false); - return self; - } - //value vector - case 3: - { - MEDCouplingAutoRefCountObjectPtr tmp=DataArrayAsciiChar::New(vsc,' '); - self->setPartOfValues3(tmp,&stdvecTyyppArr[0],&stdvecTyyppArr[0]+stdvecTyyppArr.size(),0,nbOfCompo,1,false); - return self; - } - //value DataArrayChar - case 4: - { - self->setPartOfValues3(dacc,&stdvecTyyppArr[0],&stdvecTyyppArr[0]+stdvecTyyppArr.size(),0,nbOfCompo,1,false); - return self; - } - default: - throw INTERP_KERNEL::Exception(msg); - } - } - } - case 3: - {//slice - switch(sw2) - { - {//value char - case 1: - { - self->setPartOfValuesSimple1(vc,sTyyppArr.first,sTyyppArr.second.first,sTyyppArr.second.second,0,nbOfCompo,1); - return self; - } - //value string - case 2: - { - MEDCouplingAutoRefCountObjectPtr tmp=DataArrayAsciiChar::New(sc); - self->setPartOfValues1(tmp,sTyyppArr.first,sTyyppArr.second.first,sTyyppArr.second.second,0,nbOfCompo,1,false); - return self; - } - //value vector - case 3: - { - MEDCouplingAutoRefCountObjectPtr tmp=DataArrayAsciiChar::New(vsc,' '); - self->setPartOfValues1(tmp,sTyyppArr.first,sTyyppArr.second.first,sTyyppArr.second.second,0,nbOfCompo,1,false); - return self; - } - //value DataArrayChar - case 4: - { - self->setPartOfValues1(dacc,sTyyppArr.first,sTyyppArr.second.first,sTyyppArr.second.second,0,nbOfCompo,1,false); - return self; - } - default: - throw INTERP_KERNEL::Exception(msg); - } - } - } - case 4: - {//DataArrayInt - switch(sw2) - { - {//value char - case 1: - { - self->setPartOfValuesSimple3(vc,daIntTyypp->begin(),daIntTyypp->end(),0,nbOfCompo,1); - return self; - } - //value string - case 2: - { - MEDCouplingAutoRefCountObjectPtr tmp=DataArrayAsciiChar::New(sc); - self->setPartOfValues3(tmp,daIntTyypp->begin(),daIntTyypp->end(),0,nbOfCompo,1,false); - return self; - } - //value vector - case 3: - { - MEDCouplingAutoRefCountObjectPtr tmp=DataArrayAsciiChar::New(vsc,' '); - self->setPartOfValues3(tmp,daIntTyypp->begin(),daIntTyypp->end(),0,nbOfCompo,1,false); - return self; - } - //value DataArrayChar - case 4: - { - self->setPartOfValues3(dacc,daIntTyypp->begin(),daIntTyypp->end(),0,nbOfCompo,1,false); - return self; - } - default: - throw INTERP_KERNEL::Exception(msg); - } - } - } - default: - throw INTERP_KERNEL::Exception(msg); - } - } - } - }; - - class DataArrayAsciiCharTuple; - - class DataArrayAsciiCharIterator - { - public: - DataArrayAsciiCharIterator(DataArrayAsciiChar *da); - ~DataArrayAsciiCharIterator(); - %extend - { - PyObject *next() - { - DataArrayAsciiCharTuple *ret=self->nextt(); - if(ret) - return SWIG_NewPointerObj(SWIG_as_voidptr(ret),SWIGTYPE_p_ParaMEDMEM__DataArrayAsciiCharTuple,SWIG_POINTER_OWN | 0); - else - { - PyErr_SetString(PyExc_StopIteration,"No more data."); - return 0; - } - } - } - }; - - class DataArrayAsciiCharTuple - { - public: - int getNumberOfCompo() const throw(INTERP_KERNEL::Exception); - DataArrayAsciiChar *buildDAAsciiChar(int nbOfTuples, int nbOfCompo) const throw(INTERP_KERNEL::Exception); - %extend - { - std::string __str__() const throw(INTERP_KERNEL::Exception) - { - return self->repr(); - } - - DataArrayAsciiChar *buildDAAsciiChar() throw(INTERP_KERNEL::Exception) - { - return self->buildDAAsciiChar(1,self->getNumberOfCompo()); - } - } - }; -} diff --git a/src/MEDCoupling_Swig/MEDCouplingNumPyTest.py b/src/MEDCoupling_Swig/MEDCouplingNumPyTest.py deleted file mode 100644 index e5d7943bf..000000000 --- a/src/MEDCoupling_Swig/MEDCouplingNumPyTest.py +++ /dev/null @@ -1,672 +0,0 @@ -# -*- coding: iso-8859-1 -*- -# Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 -# 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 -# - -from MEDCoupling import * - -if MEDCouplingHasNumPyBindings(): - from numpy import * - pass - -from platform import architecture -from sys import getrefcount - -import os,gc,weakref,unittest - -class MEDCouplingNumPyTest(unittest.TestCase): - - @unittest.skipUnless(MEDCouplingHasNumPyBindings(),"requires numpy") - def test1(self): - sz=20 - a=array(0,dtype=int32) - a.resize(sz) - a[:]=4 - self.assertEqual(getrefcount(a),2) - a=a.cumsum(dtype=int32) - a=array(a,dtype=int64) ; a=array(a,dtype=int32) - self.assertEqual(getrefcount(a),2) - d=DataArrayInt(a) - d[:]=2 - # - e=DataArrayInt(sz) ; e.fillWithValue(2) - self.assertTrue(d.isEqual(e)) - # - a[:]=4 ; e.fillWithValue(4) - self.assertTrue(d.isEqual(e)) - pass - - @unittest.skipUnless(MEDCouplingHasNumPyBindings(),"requires numpy") - def test2(self): - sz=20 - a=array(0,dtype=int32) - a.resize(sz,2) - self.assertEqual(getrefcount(a),2) - b=a.reshape(2*sz) - self.assertEqual(getrefcount(a),3) - self.assertEqual(getrefcount(b),2) - b[:]=5 - d=DataArrayInt(b) - # - e=DataArrayInt(sz*2) ; e.fillWithValue(5) - self.assertTrue(d.isEqual(e)) - pass - - @unittest.skipUnless(MEDCouplingHasNumPyBindings(),"requires numpy") - def test3(self): - sz=10 - a=array(0,dtype=int32) - a.resize(sz,2) - b=a.reshape(2*sz) - c=a.reshape(2,sz) - b[:]=6 - b[7:17]=7 - d=DataArrayInt(b) - self.assertTrue(d.isEqual(DataArrayInt([6,6,6,6,6,6,6,7,7,7,7,7,7,7,7,7,7,6,6,6]))) - # - a=zeros((10,2),dtype=int32) - b=a.T - c=b.view() - a.shape=20 - a[3:]=10. - d=DataArrayInt(a) - self.assertTrue(d.isEqual(DataArrayInt([0,0,0,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10]))) - pass - - @unittest.skipUnless(MEDCouplingHasNumPyBindings(),"requires numpy") - def test4(self): - a=zeros(20,dtype=int32) - b = a[::-1] - self.assertRaises(InterpKernelException,DataArrayInt.New,b) # b is not contiguous in memory - pass - - @unittest.skipUnless(MEDCouplingHasNumPyBindings(),"requires numpy") - def test5(self): - a=arange(20,dtype=int32) - self.assertEqual(weakref.getweakrefcount(a),0) - d=DataArrayInt(a) - self.assertEqual(weakref.getweakrefcount(a),1) - self.assertTrue(not a.flags["OWNDATA"]) - self.assertTrue(d.isIdentity()) - self.assertEqual(len(d),20) - a[:]=2 # modifying a and d because a and d share the same chunk of data - self.assertTrue(d.isUniform(2)) - del d # d is destroyed, a retrieves its ownership of its initial chunk of data - ##@@ Ensure a pass of the garbage collector so that the de-allocator of d is called - import gc - gc.collect() - self.assertTrue(a.flags["OWNDATA"]) - a[:]=4 # a can be used has usual - self.assertTrue(DataArrayInt(a).isUniform(4)) - pass - - @unittest.skipUnless(MEDCouplingHasNumPyBindings(),"requires numpy") - def test6(self): - a=arange(20,dtype=int32) - d=DataArrayInt(a) # d owns data of a - e=DataArrayInt(a) # a not owned -> e only an access to chunk of a - self.assertTrue(d.isIdentity()) - self.assertTrue(e.isIdentity()) - a[:]=6 - self.assertTrue(d.isUniform(6)) - self.assertTrue(e.isUniform(6)) - del a # a destroyed -> d no change because owned and e array is has no more data set - ##@@ Ensure a pass of the garbage collector so that the de-allocator of d is called - import gc - gc.collect() - self.assertTrue(d.isUniform(6)) - self.assertTrue(not e.isAllocated()) - pass - - @unittest.skipUnless(MEDCouplingHasNumPyBindings(),"requires numpy") - def test7(self): - a=array(0,dtype=int32) ; a.resize(10,2) - b=a.reshape(20) - c=a.reshape(2,10) - d=DataArrayInt(b) # d owns data of a - e=DataArrayInt(b) # a not owned -> e only an access to chunk of a - f=DataArrayInt(b) # a not owned -> e only an access to chunk of a - del d # d removed -> a ownes again data - ##@@ Ensure a pass of the garbage collector so that the de-allocator of d is called - import gc - gc.collect() - self.assertTrue(e.isUniform(0)) - e[:]=6 - self.assertTrue(e.isUniform(6)) - self.assertTrue(f.isUniform(6)) - self.assertEqual(b.tolist(),[6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6]) - self.assertEqual(a.tolist(),[[6,6],[6,6],[6,6],[6,6],[6,6],[6,6],[6,6],[6,6],[6,6],[6,6]]) - b[:]=arange(20) - del b # no impact on e and f because a is the base of a. - ##@@ Ensure a pass of the garbage collector so that the de-allocator of d is called - gc.collect() - self.assertTrue(f.isIdentity()) - self.assertTrue(e.isIdentity()) - del a # a destroyed, but as c has its base set to a, a exists -> e and f not allocated - ##@@ Ensure a pass of the garbage collector so that the de-allocator of d is called - gc.collect() - self.assertTrue(f.isIdentity()) - self.assertTrue(e.isIdentity()) - del c # c killed -> a killed -> e and d are put into not allocated state - ##@@ Ensure a pass of the garbage collector so that the de-allocator of d is called - gc.collect() - self.assertTrue(not e.isAllocated()) - self.assertTrue(not f.isAllocated()) - pass - - @unittest.skipUnless(MEDCouplingHasNumPyBindings(),"requires numpy") - def test8(self): - a=arange(20,dtype=int32) - self.assertTrue(a.flags["OWNDATA"]) - d=DataArrayInt(a) # d owns data of a - self.assertTrue(not a.flags["OWNDATA"]) - d.pushBackSilent(20)# d pushBack so release of chunk of data -> a becomes owner of its data again - self.assertTrue(a.flags["OWNDATA"]) - self.assertTrue(d.isEqual(DataArrayInt([0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20]))) - self.assertEqual(a.tolist(),[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19]) - pass - - @unittest.skipUnless(MEDCouplingHasNumPyBindings(),"requires numpy") - def test9(self): - sz=20 - a=array(0,dtype=float64) - a.resize(sz) - a[:]=4 - self.assertEqual(getrefcount(a),2) - a=a.cumsum(dtype=float64) - self.assertEqual(getrefcount(a),2) - d=DataArrayDouble(a) - d[:]=2 - # - e=DataArrayDouble(sz) ; e.fillWithValue(2) - self.assertTrue(d.isEqual(e,1e-14)) - # - a[:]=4 ; e.fillWithValue(4) - self.assertTrue(d.isEqual(e,1e-14)) - pass - - @unittest.skipUnless(MEDCouplingHasNumPyBindings(),"requires numpy") - def test10(self): - sz=20 - a=array(0,dtype=float64) - a.resize(sz,2) - self.assertEqual(getrefcount(a),2) - b=a.reshape(2*sz) - self.assertEqual(getrefcount(a),3) - self.assertEqual(getrefcount(b),2) - b[:]=5 - d=DataArrayDouble(b) - # - e=DataArrayDouble(sz*2) ; e.fillWithValue(5) - self.assertTrue(d.isEqual(e,1e-14)) - pass - - @unittest.skipUnless(MEDCouplingHasNumPyBindings(),"requires numpy") - def test11(self): - sz=10 - a=array(0,dtype=float64) - a.resize(sz,2) - b=a.reshape(2*sz) - c=a.reshape(2,sz) - b[:]=6 - b[7:17]=7 - d=DataArrayDouble(b) - self.assertTrue(d.isEqual(DataArrayDouble([6,6,6,6,6,6,6,7,7,7,7,7,7,7,7,7,7,6,6,6]),1e-14)) - # - a=zeros((10,2),dtype=float64) - b=a.T - c=b.view() - a.shape=20 - a[3:]=10. - d=DataArrayDouble(a) - self.assertTrue(d.isEqual(DataArrayDouble([0,0,0,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10]),1e-14)) - pass - - @unittest.skipUnless(MEDCouplingHasNumPyBindings(),"requires numpy") - def test12(self): - a=zeros(20,dtype=float64) - b = a[::-1] - self.assertRaises(InterpKernelException,DataArrayDouble.New,b) # b is not contiguous in memory - pass - - @unittest.skipUnless(MEDCouplingHasNumPyBindings(),"requires numpy") - def test13(self): - a=arange(20,dtype=float64) - self.assertEqual(weakref.getweakrefcount(a),0) - d=DataArrayDouble(a) - self.assertEqual(weakref.getweakrefcount(a),1) - self.assertTrue(not a.flags["OWNDATA"]) - self.assertTrue(d.isEqual(DataArrayDouble([0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19]),1e-14)) - self.assertEqual(len(d),20) - a[:]=2 # modifying a and d because a and d share the same chunk of data - self.assertTrue(d.isUniform(2,1e-14)) - del d # d is destroyed, a retrieves its ownership of its initial chunk of data - ##@@ Ensure a pass of the garbage collector so that the de-allocator of d is called - import gc - gc.collect() - self.assertTrue(a.flags["OWNDATA"]) - a[:]=4 # a can be used has usual - self.assertTrue(DataArrayDouble(a).isUniform(4,1e-14)) - pass - - @unittest.skipUnless(MEDCouplingHasNumPyBindings(),"requires numpy") - def test14(self): - a=arange(20,dtype=float64) - d=DataArrayDouble(a) # d owns data of a - e=DataArrayDouble(a) # a not owned -> e only an access to chunk of a - self.assertTrue(d.isEqual(DataArrayDouble([0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19]),1e-14)) - self.assertTrue(e.isEqual(DataArrayDouble([0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19]),1e-14)) - a[:]=6 - self.assertTrue(d.isUniform(6,1e-14)) - self.assertTrue(e.isUniform(6,1e-14)) - del a # a destroyed -> d no change because owned and e array is has no more data set - ##@@ Ensure a pass of the garbage collector so that the de-allocator of d is called - import gc - gc.collect() - self.assertTrue(d.isUniform(6,1e-14)) - self.assertTrue(not e.isAllocated()) - pass - - @unittest.skipUnless(MEDCouplingHasNumPyBindings(),"requires numpy") - def test15(self): - a=array(0,dtype=float64) ; a.resize(10,2) - b=a.reshape(20) - c=a.reshape(2,10) - d=DataArrayDouble(b) # d owns data of a - e=DataArrayDouble(b) # a not owned -> e only an access to chunk of a - f=DataArrayDouble(b) # a not owned -> e only an access to chunk of a - del d # d removed -> a ownes again data - ##@@ Ensure a pass of the garbage collector so that the de-allocator of d is called - import gc - gc.collect() - self.assertTrue(e.isUniform(0,1e-14)) - e[:]=6 - self.assertTrue(e.isUniform(6,1e-14)) - self.assertTrue(f.isUniform(6,1e-14)) - self.assertEqual(b.tolist(),[6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6]) - self.assertEqual(a.tolist(),[[6,6],[6,6],[6,6],[6,6],[6,6],[6,6],[6,6],[6,6],[6,6],[6,6]]) - b[:]=arange(20) - del b # no impact on e and f because a is the base of a. - ##@@ Ensure a pass of the garbage collector so that the de-allocator of d is called - gc.collect() - self.assertTrue(f.isEqual(DataArrayDouble([0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19]),1e-14)) - self.assertTrue(e.isEqual(DataArrayDouble([0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19]),1e-14)) - del a # a destroyed, but as c has its base set to a, a exists -> e and f not allocated - ##@@ Ensure a pass of the garbage collector so that the de-allocator of d is called - gc.collect() - self.assertTrue(f.isEqual(DataArrayDouble([0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19]),1e-14)) - self.assertTrue(e.isEqual(DataArrayDouble([0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19]),1e-14)) - del c # c killed -> a killed -> e and d are put into not allocated state - ##@@ Ensure a pass of the garbage collector so that the de-allocator of d is called - gc.collect() - self.assertTrue(not e.isAllocated()) - self.assertTrue(not f.isAllocated()) - pass - - @unittest.skipUnless(MEDCouplingHasNumPyBindings(),"requires numpy") - def test16(self): - a=arange(20,dtype=float64) - self.assertTrue(a.flags["OWNDATA"]) - d=DataArrayDouble(a) # d owns data of a - self.assertTrue(not a.flags["OWNDATA"]) - d.pushBackSilent(20)# d pushBack so release of chunk of data -> a becomes owner of its data again - self.assertTrue(a.flags["OWNDATA"]) - self.assertTrue(d.isEqual(DataArrayDouble([0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20]),1e-14)) - self.assertEqual(a.tolist(),[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19]) - pass - - @unittest.skipUnless(MEDCouplingHasNumPyBindings(),"requires numpy") - def test17(self): - d=DataArrayInt.Range(0,20,1) - a=d.toNumPyArray() - self.assertTrue(not a.flags["OWNDATA"]) - a[-2:]=100 - self.assertTrue(d.isEqual(DataArrayInt([0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,100,100]))) - self.assertEqual(a.tolist(),[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,100,100]) - del a - ##@@ Ensure a pass of the garbage collector so that the de-allocator of d is called - import gc - gc.collect() - self.assertTrue(d.isEqual(DataArrayInt([0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,100,100]))) - # - d.rearrange(2) - a=d.toNumPyArray() - self.assertTrue(not a.flags["OWNDATA"]) - a[-2:]=200 - self.assertTrue(d.isEqual(DataArrayInt([0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,200,200,200,200],10,2))) - self.assertEqual(a.tolist(),[[0,1],[2,3],[4,5],[6,7],[8,9],[10,11],[12,13],[14,15],[200,200],[200,200]]) - del a - ##@@ Ensure a pass of the garbage collector so that the de-allocator of d is called - gc.collect() - self.assertTrue(d.isEqual(DataArrayInt([0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,200,200,200,200],10,2))) - pass - - @unittest.skipUnless(MEDCouplingHasNumPyBindings(),"requires numpy") - def test18(self): - d=DataArrayInt.Range(0,20,1) - d=d.convertToDblArr() - a=d.toNumPyArray() - self.assertTrue(not a.flags["OWNDATA"]) - a[-2:]=100 - self.assertTrue(d.isEqual(DataArrayDouble([0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,100,100]),1e-14)) - self.assertEqual(a.tolist(),[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,100,100]) - del a - ##@@ Ensure a pass of the garbage collector so that the de-allocator of d is called - import gc - gc.collect() - self.assertTrue(d.isEqual(DataArrayDouble([0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,100,100]),1e-14)) - # - d.rearrange(2) - a=d.toNumPyArray() - self.assertTrue(not a.flags["OWNDATA"]) - a[-2:]=200 - self.assertTrue(d.isEqual(DataArrayDouble([0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,200,200,200,200],10,2),1e-14)) - self.assertEqual(a.tolist(),[[0,1],[2,3],[4,5],[6,7],[8,9],[10,11],[12,13],[14,15],[200,200],[200,200]]) - del a - ##@@ Ensure a pass of the garbage collector so that the de-allocator of d is called - gc.collect() - self.assertTrue(d.isEqual(DataArrayDouble([0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,200,200,200,200],10,2),1e-14)) - pass - - @unittest.skipUnless(MEDCouplingHasNumPyBindings(),"requires numpy") - def test19(self): - sz=20 - a=array(0,dtype=int32) - a.resize(sz/2,2) - a[:]=4 - self.assertEqual(getrefcount(a),2) - d=DataArrayInt(a) - self.assertEqual(10,d.getNumberOfTuples()) - self.assertEqual(2,d.getNumberOfComponents()) - self.assertEqual(sz,d.getNbOfElems()) - self.assertTrue(d.isEqual(DataArrayInt([(4,4),(4,4),(4,4),(4,4),(4,4),(4,4),(4,4),(4,4),(4,4),(4,4)]))) - a[:]=7 - self.assertTrue(d.isEqual(DataArrayInt([(7,7),(7,7),(7,7),(7,7),(7,7),(7,7),(7,7),(7,7),(7,7),(7,7)]))) - # - b=a.reshape((2,5,2)) - self.assertRaises(InterpKernelException,DataArrayInt.New,b) # b has not dimension in [0,1] ! - pass - - @unittest.skipUnless(MEDCouplingHasNumPyBindings(),"requires numpy") - def test20(self): - sz=20 - a=array(0,dtype=float64) - a.resize(sz/2,2) - a[:]=4 - self.assertEqual(getrefcount(a),2) - d=DataArrayDouble(a) - self.assertEqual(10,d.getNumberOfTuples()) - self.assertEqual(2,d.getNumberOfComponents()) - self.assertEqual(sz,d.getNbOfElems()) - self.assertTrue(d.isEqual(DataArrayDouble([(4.,4.),(4.,4.),(4.,4.),(4.,4.),(4.,4.),(4.,4.),(4.,4.),(4.,4.),(4.,4.),(4.,4.)]),1e-14)) - a[:]=7 - self.assertTrue(d.isEqual(DataArrayDouble([(7.,7.),(7.,7.),(7.,7.),(7.,7.),(7.,7.),(7.,7.),(7.,7.),(7.,7.),(7.,7.),(7.,7.)]),1e-14)) - # - b=a.reshape((2,5,2)) - self.assertRaises(InterpKernelException,DataArrayDouble.New,b) # b has not dimension in [0,1] ! - pass - - @unittest.skipUnless(MEDCouplingHasNumPyBindings(),"requires numpy") - def test21(self): - #tests that only DataArray*(npArray) contructor is available - a=array(0,dtype=int32) - a.resize(20) - DataArrayInt(a) - self.assertRaises(InterpKernelException,DataArrayInt.New,a,20) - self.assertRaises(InterpKernelException,DataArrayInt.New,a,20,1) - a=array(0,dtype=float64) - a.resize(20) - DataArrayDouble(a) - self.assertRaises(InterpKernelException,DataArrayDouble.New,a,20) - self.assertRaises(InterpKernelException,DataArrayDouble.New,a,20,1) - pass - - @unittest.skipUnless(MEDCouplingHasNumPyBindings(),"requires numpy") - def test22(self): - d=DataArrayDouble(10) - d.iota() - a=d.toNumPyArray() - self.assertTrue(not a.flags["OWNDATA"]) - del d - gc.collect() - self.assertTrue(a.flags["OWNDATA"]) - self.assertEqual(a.tolist(),[0.,1.,2.,3.,4.,5.,6.,7.,8.,9.]) - # - d=DataArrayInt(10) - d.iota() - a=d.toNumPyArray() - self.assertTrue(not a.flags["OWNDATA"]) - del d - gc.collect() - self.assertTrue(a.flags["OWNDATA"]) - self.assertEqual(a.tolist(),[0,1,2,3,4,5,6,7,8,9]) - pass - - @unittest.skipUnless(MEDCouplingHasNumPyBindings(),"requires numpy") - def test23(self): - d=DataArrayDouble(10) - d.iota() - a=d.toNumPyArray() - b=d.toNumPyArray() - c=d.toNumPyArray() - self.assertTrue(not a.flags["OWNDATA"]) - self.assertTrue(not b.flags["OWNDATA"]) - self.assertTrue(not c.flags["OWNDATA"]) - self.assertEqual(a.tolist(),[0.,1.,2.,3.,4.,5.,6.,7.,8.,9.]) - self.assertEqual(b.tolist(),[0.,1.,2.,3.,4.,5.,6.,7.,8.,9.]) - self.assertEqual(c.tolist(),[0.,1.,2.,3.,4.,5.,6.,7.,8.,9.]) - del d - gc.collect() - self.assertTrue(a.flags["OWNDATA"]) - self.assertTrue(not b.flags["OWNDATA"]) - self.assertTrue(not c.flags["OWNDATA"]) - self.assertEqual(a.tolist(),[0.,1.,2.,3.,4.,5.,6.,7.,8.,9.]) - self.assertEqual(b.tolist(),[0.,1.,2.,3.,4.,5.,6.,7.,8.,9.]) - self.assertEqual(c.tolist(),[0.,1.,2.,3.,4.,5.,6.,7.,8.,9.]) - # - d=DataArrayInt(10) - d.iota() - a=d.toNumPyArray() - b=d.toNumPyArray() - c=d.toNumPyArray() - self.assertTrue(not a.flags["OWNDATA"]) - self.assertTrue(not b.flags["OWNDATA"]) - self.assertTrue(not c.flags["OWNDATA"]) - self.assertEqual(a.tolist(),[0,1,2,3,4,5,6,7,8,9]) - self.assertEqual(b.tolist(),[0,1,2,3,4,5,6,7,8,9]) - self.assertEqual(c.tolist(),[0,1,2,3,4,5,6,7,8,9]) - del d - gc.collect() - self.assertTrue(a.flags["OWNDATA"]) - self.assertTrue(not b.flags["OWNDATA"]) - self.assertTrue(not c.flags["OWNDATA"]) - self.assertEqual(a.tolist(),[0,1,2,3,4,5,6,7,8,9]) - self.assertEqual(b.tolist(),[0,1,2,3,4,5,6,7,8,9]) - self.assertEqual(c.tolist(),[0,1,2,3,4,5,6,7,8,9]) - pass - - @unittest.skipUnless(MEDCouplingHasNumPyBindings(),"requires numpy") - def test24(self): - d=DataArrayDouble(10) - d.iota() - a=d.toNumPyArray() - self.assertEqual(a.tolist(),[0.,1.,2.,3.,4.,5.,6.,7.,8.,9.]) - self.assertTrue(not a.flags["OWNDATA"]) - self.assertTrue(a.base is None) - del a - gc.collect() - a=d.toNumPyArray() - self.assertEqual(a.tolist(),[0.,1.,2.,3.,4.,5.,6.,7.,8.,9.]) - self.assertTrue(not a.flags["OWNDATA"]) - self.assertTrue(a.base is None) - b=d.toNumPyArray() - self.assertEqual(a.tolist(),[0.,1.,2.,3.,4.,5.,6.,7.,8.,9.]) - self.assertEqual(b.tolist(),[0.,1.,2.,3.,4.,5.,6.,7.,8.,9.]) - self.assertTrue(not a.flags["OWNDATA"]) - self.assertTrue(not b.flags["OWNDATA"]) - self.assertTrue(b.base is a) - del a - gc.collect() - self.assertEqual(b.tolist(),[0.,1.,2.,3.,4.,5.,6.,7.,8.,9.]) - self.assertTrue(not b.flags["OWNDATA"]) - del d - gc.collect() - self.assertEqual(b.tolist(),[0.,1.,2.,3.,4.,5.,6.,7.,8.,9.]) - self.assertTrue(not b.flags["OWNDATA"]) - # - d=DataArrayInt(10) - d.iota() - a=d.toNumPyArray() - self.assertEqual(a.tolist(),[0,1,2,3,4,5,6,7,8,9]) - self.assertTrue(not a.flags["OWNDATA"]) - self.assertTrue(a.base is None) - del a - gc.collect() - a=d.toNumPyArray() - self.assertEqual(a.tolist(),[0,1,2,3,4,5,6,7,8,9]) - self.assertTrue(not a.flags["OWNDATA"]) - self.assertTrue(a.base is None) - b=d.toNumPyArray() - self.assertEqual(a.tolist(),[0,1,2,3,4,5,6,7,8,9]) - self.assertEqual(b.tolist(),[0,1,2,3,4,5,6,7,8,9]) - self.assertTrue(not a.flags["OWNDATA"]) - self.assertTrue(not b.flags["OWNDATA"]) - self.assertTrue(b.base is a) - del a - gc.collect() - self.assertEqual(b.tolist(),[0.,1.,2.,3.,4.,5.,6.,7.,8.,9.]) - self.assertTrue(not b.flags["OWNDATA"]) - del d - gc.collect() - self.assertEqual(b.tolist(),[0.,1.,2.,3.,4.,5.,6.,7.,8.,9.]) - self.assertTrue(not b.flags["OWNDATA"]) - pass - - @unittest.skipUnless(MEDCouplingHasNumPyBindings(),"requires numpy") - def test25(self): - a=arange(10,dtype=int32) - b=DataArrayInt(a) - c=DataArrayInt(a) - d=DataArrayInt(a) - self.assertTrue(b.isIdentity()) ; self.assertEqual(len(b),10) - self.assertTrue(c.isIdentity()) ; self.assertEqual(len(c),10) - self.assertTrue(d.isIdentity()) ; self.assertEqual(len(d),10) - c.pushBackSilent(10) # c and a,b are dissociated - self.assertTrue(b.isIdentity()) ; self.assertEqual(len(b),10) - self.assertTrue(c.isIdentity()) ; self.assertEqual(len(c),11) - self.assertTrue(d.isIdentity()) ; self.assertEqual(len(d),10) - del a - gc.collect() - self.assertTrue(b.isIdentity()) ; self.assertEqual(len(b),10) - self.assertTrue(c.isIdentity()) ; self.assertEqual(len(c),11) - self.assertTrue(not d.isAllocated()) - del b - gc.collect() - self.assertTrue(c.isIdentity()) ; self.assertEqual(len(c),11) - # - a=arange(10,dtype=int32) - b=DataArrayInt(a) - c=DataArrayInt(a) - self.assertTrue(b.isIdentity()) ; self.assertEqual(len(b),10) - self.assertTrue(c.isIdentity()) ; self.assertEqual(len(c),10) - b.pushBackSilent(10) # c and a,b are dissociated - self.assertTrue(b.isIdentity()) ; self.assertEqual(len(b),11) - self.assertTrue(c.isIdentity()) ; self.assertEqual(len(c),10) - del a - gc.collect() - self.assertTrue(b.isIdentity()) ; self.assertEqual(len(b),11) - self.assertTrue(not c.isAllocated()) - del b - gc.collect() - self.assertTrue(not c.isAllocated()) - # - a=float64(arange(5,dtype=int32)) - b=DataArrayDouble(a) - c=DataArrayDouble(a) - d=DataArrayDouble(a) - self.assertTrue(b.isEqual(DataArrayDouble([0.,1.,2.,3.,4.]),1e-12)) - self.assertTrue(c.isEqual(DataArrayDouble([0.,1.,2.,3.,4.]),1e-12)) - self.assertTrue(d.isEqual(DataArrayDouble([0.,1.,2.,3.,4.]),1e-12)) - c.pushBackSilent(10.) # c and a,b are dissociated - self.assertTrue(b.isEqual(DataArrayDouble([0.,1.,2.,3.,4.]),1e-12)) - self.assertTrue(c.isEqual(DataArrayDouble([0.,1.,2.,3.,4.,10.]),1e-12)) - self.assertTrue(d.isEqual(DataArrayDouble([0.,1.,2.,3.,4.]),1e-12)) - del a - gc.collect() - self.assertTrue(b.isEqual(DataArrayDouble([0.,1.,2.,3.,4.]),1e-12)) - self.assertTrue(c.isEqual(DataArrayDouble([0.,1.,2.,3.,4.,10.]),1e-12)) - self.assertTrue(not d.isAllocated()) - del b - gc.collect() - self.assertTrue(c.isEqual(DataArrayDouble([0.,1.,2.,3.,4.,10.]),1e-12)) - # - a=float64(arange(5,dtype=int32)) - b=DataArrayDouble(a) - c=DataArrayDouble(a) - self.assertTrue(b.isEqual(DataArrayDouble([0.,1.,2.,3.,4.]),1e-12)) - self.assertTrue(c.isEqual(DataArrayDouble([0.,1.,2.,3.,4.]),1e-12)) - b.pushBackSilent(10.) # c and a,b are dissociated - self.assertTrue(b.isEqual(DataArrayDouble([0.,1.,2.,3.,4.,10.]),1e-12)) - self.assertTrue(c.isEqual(DataArrayDouble([0.,1.,2.,3.,4.]),1e-12)) - del a - gc.collect() - self.assertTrue(b.isEqual(DataArrayDouble([0.,1.,2.,3.,4.,10.]),1e-12)) - self.assertTrue(not c.isAllocated()) - del b - gc.collect() - self.assertTrue(not c.isAllocated()) - pass - - @unittest.skipUnless(MEDCouplingHasNumPyBindings(),"requires numpy") - def test26(self): - d=DataArrayInt(15) ; d.iota() - d.rearrange(3) - a=d.toNumPyArray() - self.assertEqual(a.ndim,2) - self.assertEqual(a.size,15) - self.assertEqual(a.shape,(5,3)) - self.assertEqual(a.strides,(12,4)) - self.assertEqual(a.nbytes,60) - self.assertEqual(a.itemsize,4) - self.assertEqual(a.tolist(),[[0,1,2],[3,4,5],[6,7,8],[9,10,11],[12,13,14]]) - # - d2=d.convertToDblArr() - a2=d2.toNumPyArray() - self.assertEqual(a2.ndim,2) - self.assertEqual(a2.size,15) - self.assertEqual(a2.shape,(5,3)) - self.assertEqual(a2.strides,(24,8)) - self.assertEqual(a2.nbytes,120) - self.assertEqual(a2.itemsize,8) - self.assertEqual(a2.tolist(),[[0.,1.,2.],[3.,4.,5.],[6.,7.,8.],[9.,10.,11.],[12.,13.,14.]]) - pass - - @unittest.skipUnless(MEDCouplingHasNumPyBindings(),"requires numpy") - def test27(self): - m0=DenseMatrix(DataArrayDouble([2,3,4,5,1,6]),2,3) - m0np=m0.toNumPyMatrix() - self.assertEqual(m0np.shape,(2,3)) - self.assertEqual(m0np.tolist(),[[2.0,3.0,4.0],[5.0,1.0,6.0]]) - pass - - def setUp(self): - pass - pass - -#gc.set_debug(gc.DEBUG_LEAK) -unittest.main() diff --git a/src/MEDCoupling_Swig/MEDCouplingPickleTest.py b/src/MEDCoupling_Swig/MEDCouplingPickleTest.py deleted file mode 100644 index 677b11082..000000000 --- a/src/MEDCoupling_Swig/MEDCouplingPickleTest.py +++ /dev/null @@ -1,300 +0,0 @@ -# -*- coding: iso-8859-1 -*- -# Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 -# 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 -# - -from MEDCoupling import * -from MEDCouplingDataForTest import MEDCouplingDataForTest - -if MEDCouplingHasNumPyBindings(): - from numpy import * - pass - -from platform import architecture -from sys import getrefcount - -import os,gc,weakref,cPickle,unittest - -class MEDCouplingPickleTest(unittest.TestCase): - @unittest.skipUnless(MEDCouplingHasNumPyBindings(),"requires numpy") - def test1(self): - """ Test of a simple DataArrayDouble.""" - x=DataArrayDouble(10,1) ; x.iota() ; x.rearrange(2) ; x.setInfoOnComponents(["aa","bbb"]) - x.setName("toto") - pickled=cPickle.dumps(x,cPickle.HIGHEST_PROTOCOL) - xx=cPickle.loads(pickled) - self.assertTrue(xx.isEqual(x,1e-16)) - # Bigger to check that the behavior is OK for large strings. - x=DataArrayDouble(1200) ; x.iota() ; x.setInfoOnComponents(["aa"]) - x.setName("titi") - pickled=cPickle.dumps(x,cPickle.HIGHEST_PROTOCOL) - xx=cPickle.loads(pickled) - self.assertTrue(xx.isEqual(x,1e-16)) - pass - - @unittest.skipUnless(MEDCouplingHasNumPyBindings(),"requires numpy") - def test2(self): - """ Test of a simple DataArrayInt.""" - x=DataArrayInt(10) ; x.iota() ; x.rearrange(2) ; x.setInfoOnComponents(["aa","bbb"]) - x.setName("toto") - pickled=cPickle.dumps(x,cPickle.HIGHEST_PROTOCOL) - xx=cPickle.loads(pickled) - self.assertTrue(xx.isEqual(x)) - # Bigger to check that the behavior is OK for large strings. - x=DataArrayInt(1200) ; x.iota() ; x.setInfoOnComponents(["aa"]) - x.setName("titi") - pickled=cPickle.dumps(x,cPickle.HIGHEST_PROTOCOL) - xx=cPickle.loads(pickled) - self.assertTrue(xx.isEqual(x)) - pass - - @unittest.skipUnless(MEDCouplingHasNumPyBindings(),"requires numpy") - def test3(self): - """ Test of a MEDCouplingUMesh pickeling.""" - arr=DataArrayDouble(10) ; arr.iota() - m=MEDCouplingCMesh() ; m.setCoords(arr,arr,arr) - m=m.buildUnstructured() - m.setName("mesh") - m.getCoords().setInfoOnComponents(["aa","bbb","ddddd"]) - m.checkCoherency() - st=cPickle.dumps(m,cPickle.HIGHEST_PROTOCOL) - m2=cPickle.loads(st) - self.assertTrue(m2.isEqual(m,1e-16)) - pass - - @unittest.skipUnless(MEDCouplingHasNumPyBindings(),"requires numpy") - def test4(self): - """ Idem test3 except that here serialization/deserialization is done explicitely.""" - arr=DataArrayDouble(10) ; arr.iota() - m=MEDCouplingCMesh() ; m.setCoords(arr,arr,arr) - m=m.buildUnstructured() - m.setName("mesh") - m.getCoords().setInfoOnComponents(["aa","bbb","ddddd"]) - m.checkCoherency() - # - a0,a1,a2=m.getTinySerializationInformation() - b0,b1=m.serialize() - m2=MEDCouplingUMesh() - m2.unserialization(a0,a1,b0,b1,a2); - self.assertTrue(m2.isEqual(m,1e-16)) - pass - - @unittest.skipUnless(MEDCouplingHasNumPyBindings(),"requires numpy") - def test5(self): - """ Test of a MEDCouplingCMesh pickeling.""" - arrX=DataArrayDouble(10) ; arrX.iota() ; arrX.setInfoOnComponents(["aa"]) - arrY=DataArrayDouble(5) ; arrY.iota() ; arrY.setInfoOnComponents(["bbb"]) - arrZ=DataArrayDouble(7) ; arrZ.iota() ; arrZ.setInfoOnComponents(["cccc"]) - # - m=MEDCouplingCMesh() ; m.setCoords(arrX,arrY,arrZ) - m.setName("mesh") - m.checkCoherency() - st=cPickle.dumps(m,cPickle.HIGHEST_PROTOCOL) - m2=cPickle.loads(st) - self.assertTrue(m2.isEqual(m,1e-16)) - self.assertTrue(m2.getCoordsAt(0).isEqual(arrX,1e-16)) - pass - - @unittest.skipUnless(MEDCouplingHasNumPyBindings(),"requires numpy") - def test6(self): - """ Test of a MEDCoupling1SGTUMesh pickeling.""" - arr=DataArrayDouble(10) ; arr.iota() - m=MEDCouplingCMesh() ; m.setCoords(arr,arr) - m=m.build1SGTUnstructured() - self.assertTrue(isinstance(m,MEDCoupling1SGTUMesh)) - st=cPickle.dumps(m,cPickle.HIGHEST_PROTOCOL) - m2=cPickle.loads(st) - self.assertTrue(m2.isEqual(m,1e-16)) - pass - - @unittest.skipUnless(MEDCouplingHasNumPyBindings(),"requires numpy") - def test7(self): - """ Test of a MEDCoupling1DGTUMesh pickeling.""" - arr=DataArrayDouble(10) ; arr.iota() - m=MEDCouplingCMesh() ; m.setCoords(arr,arr) - m=m.buildUnstructured() ; m.convertAllToPoly() - m=MEDCoupling1DGTUMesh(m) - self.assertTrue(isinstance(m,MEDCoupling1DGTUMesh)) - st=cPickle.dumps(m,cPickle.HIGHEST_PROTOCOL) - m2=cPickle.loads(st) - self.assertTrue(m2.isEqual(m,1e-16)) - pass - - @unittest.skipUnless(MEDCouplingHasNumPyBindings(),"requires numpy") - def test8(self): - """ Test of a MEDCouplingExtrudedMesh pickeling.""" - arrX=DataArrayDouble(10) ; arrX.iota() ; arrX.setInfoOnComponents(["aa"]) - arrY=DataArrayDouble(5) ; arrY.iota() ; arrY.setInfoOnComponents(["bbb"]) - arrZ=DataArrayDouble(7) ; arrZ.iota() ; arrZ.setInfoOnComponents(["cccc"]) - m=MEDCouplingCMesh() ; m.setCoords(arrX,arrY,arrZ) - mesh3D=m.buildUnstructured() ; del m - # - m=MEDCouplingCMesh() ; m.setCoords(arrX,arrY) - mesh2D=m.buildUnstructured() ; del m - # - mesh2D.setCoords(mesh3D.getCoords()) - mesh=MEDCouplingExtrudedMesh(mesh3D,mesh2D,0) ; del mesh3D,mesh2D - self.assertTrue(isinstance(mesh,MEDCouplingExtrudedMesh)) - st=cPickle.dumps(mesh,cPickle.HIGHEST_PROTOCOL) - m2=cPickle.loads(st) - self.assertTrue(m2.isEqual(mesh,1e-16)) - pass - - @unittest.skipUnless(MEDCouplingHasNumPyBindings(),"requires numpy") - def test9(self): - """ Test of a MEDCouplingCurveLinearMesh pickeling.""" - arrX=DataArrayDouble(10) ; arrX.iota() ; arrX.setInfoOnComponents(["aa"]) - arrY=DataArrayDouble(5) ; arrY.iota() ; arrY.setInfoOnComponents(["bbb"]) - m=MEDCouplingCMesh() ; m.setCoords(arrX,arrY) - m=m.buildUnstructured() - # - mesh=MEDCouplingCurveLinearMesh() ; mesh.setCoords(m.getCoords()) ; del m - mesh.setNodeGridStructure([10,5]) - st=cPickle.dumps(mesh,cPickle.HIGHEST_PROTOCOL) - m2=cPickle.loads(st) - self.assertTrue(m2.isEqual(mesh,1e-16)) - pass - - @unittest.skipUnless(MEDCouplingHasNumPyBindings(),"requires numpy") - def test10(self): - """ Test of a MEDCouplingIMesh pickeling.""" - m=MEDCouplingIMesh("mesh",3,DataArrayInt([3,1,4]),DataArrayDouble([1.5,2.5,3.5]),DataArrayDouble((0.5,1.,0.25))) ; m.setAxisUnit("km") - m.checkCoherency() - st=cPickle.dumps(m,cPickle.HIGHEST_PROTOCOL) - m2=cPickle.loads(st) - self.assertTrue(m2.isEqual(m,1e-16)) - self.assertEqual(m2.getName(),m.getName()) - pass - - @unittest.skipUnless(MEDCouplingHasNumPyBindings(),"requires numpy") - def test11(self): - """ Test of MEDCouplingFieldDouble lying on MEDCouplingCMesh pickeling. """ - arrX=DataArrayDouble(10) ; arrX.iota() ; arrX.setInfoOnComponents(["aa"]) - arrY=DataArrayDouble(5) ; arrY.iota() ; arrY.setInfoOnComponents(["bbb"]) - m=MEDCouplingCMesh() ; m.setCoords(arrX,arrY) - f=m.getMeasureField(True) - f.setName("aname") - a=f.getArray() - b=a[:] ; b.iota(7000.) - f.setArray(DataArrayDouble.Meld(a,b)) - f.getArray().setInfoOnComponents(["u1","vv2"]) - f.checkCoherency(); - # - st=cPickle.dumps(f,cPickle.HIGHEST_PROTOCOL) - f2=cPickle.loads(st) - self.assertTrue(f2.isEqual(f,1e-16,1e-16)) - self.assertTrue(f2.getMesh().isEqual(f.getMesh(),1e-16)) - pass - - @unittest.skipUnless(MEDCouplingHasNumPyBindings(),"requires numpy") - def test12(self): - """ Test of MEDCouplingFieldDouble on Gauss Points lying on MEDCouplingUMesh pickeling.""" - _a=0.446948490915965; - _b=0.091576213509771; - _p1=0.11169079483905; - _p2=0.0549758718227661; - refCoo1=[ 0.,0., 1.,0., 0.,1. ] - gsCoo1=[ 2*_b-1, 1-4*_b, 2*_b-1, 2.07*_b-1, 1-4*_b, - 2*_b-1, 1-4*_a, 2*_a-1, 2*_a-1, 1-4*_a, 2*_a-1, 2*_a-1 ] - wg1=[ 4*_p2, 4*_p2, 4*_p2, 4*_p1, 4*_p1, 4*_p1 ] - _refCoo1=refCoo1 - _gsCoo1=gsCoo1 - _wg1=wg1 - # - m=MEDCouplingDataForTest.build2DTargetMesh_1(); - f=MEDCouplingFieldDouble.New(ON_GAUSS_PT,NO_TIME); - f.setMesh(m); - self.assertEqual(5,f.getNumberOfMeshPlacesExpected()); - self.assertEqual(0,f.getNbOfGaussLocalization()); - f.setGaussLocalizationOnType(NORM_TRI3,_refCoo1,_gsCoo1,_wg1); - f.setGaussLocalizationOnType(NORM_TRI3,_refCoo1,_gsCoo1,_wg1); # not a bug only to check that it works well - self.assertRaises(InterpKernelException,f.setGaussLocalizationOnType,NORM_QUAD4,_refCoo1,_gsCoo1,_wg1) - self.assertEqual(1,f.getNbOfGaussLocalization()); - refCoo2=[ 0.,0., 1.,0., 1.,1., 0.,1. ] - _refCoo2=refCoo2 - _gsCoo1=_gsCoo1[0:4] - _wg1=_wg1[0:2] - f.setGaussLocalizationOnType(NORM_QUAD4,_refCoo2,_gsCoo1,_wg1); - self.assertEqual(2,f.getNbOfGaussLocalization()); - array=DataArrayDouble.New(); - ptr=18*2*[None] - for i in xrange(18*2): - ptr[i]=float(i+1) - array.setValues(ptr,18,2); - ptr=array.getPointer(); - f.setArray(array); - f.setName("MyFirstFieldOnGaussPoint"); - f.checkCoherency(); - self.assertAlmostEqual(27.,f.getIJK(2,5,0),14); - self.assertAlmostEqual(16.,f.getIJK(1,5,1),14); - # - f.clearGaussLocalizations(); - self.assertEqual(0,f.getNbOfGaussLocalization()); - self.assertRaises(InterpKernelException,f.checkCoherency); - ids1=[0,1,3,4] - self.assertRaises(InterpKernelException,f.setGaussLocalizationOnCells,ids1,_refCoo2,_gsCoo1,_wg1); - self.assertEqual(0,f.getNbOfGaussLocalization()); - ids2=[0,4] - f.setGaussLocalizationOnCells(ids2,_refCoo2,_gsCoo1,_wg1); - self.assertEqual(1,f.getNbOfGaussLocalization()); - self.assertEqual(0,f.getGaussLocalizationIdOfOneCell(0)); - self.assertRaises(InterpKernelException,f.getGaussLocalizationIdOfOneCell,1); - ids3=[1,2] - f.setGaussLocalizationOnCells(ids3,_refCoo1,_gsCoo1,_wg1); - self.assertEqual(2,f.getNbOfGaussLocalization()); - self.assertEqual(0,f.getGaussLocalizationIdOfOneCell(0)); - self.assertEqual(1,f.getGaussLocalizationIdOfOneCell(1)); - self.assertEqual(1,f.getGaussLocalizationIdOfOneCell(2)); - self.assertRaises(InterpKernelException,f.checkCoherency);#<- cell 3 has no localization - ids4=[3] - _gsCoo2=_gsCoo1; - _wg2=_wg1; - _gsCoo2[0]=0.8888777776666; - _wg2[0]=0.1234567892377; - f.setGaussLocalizationOnCells(ids4,_refCoo2,_gsCoo2,_wg2); - self.assertEqual(3,f.getNbOfGaussLocalization()); - tmpIds=f.getCellIdsHavingGaussLocalization(0); - self.assertEqual(ids2,list(tmpIds.getValues())); - self.assertRaises(InterpKernelException,f.checkCoherency);#<- it's always not ok because undelying array not with the good size. - array2=f.getArray().substr(0,10); - f.setArray(array2); - f.checkCoherency(); - #### - st=cPickle.dumps(f,cPickle.HIGHEST_PROTOCOL) - f2=cPickle.loads(st) - self.assertTrue(f2.isEqual(f,1e-16,1e-16)) - self.assertTrue(f2.getMesh().isEqual(f.getMesh(),1e-16)) - pass - - def test13(self): - eStr="This is an exception." - e=InterpKernelException(eStr) - self.assertEqual(e.what(),eStr) - st=cPickle.dumps(e,cPickle.HIGHEST_PROTOCOL) - e2=cPickle.loads(st) - self.assertTrue(e is not e2) - self.assertTrue(isinstance(e2,InterpKernelException)) - self.assertEqual(e2.what(),eStr) - pass - - def setUp(self): - pass - pass - -if __name__=="__main__": - unittest.main() diff --git a/src/MEDCoupling_Swig/MEDCouplingRefCountObject.i b/src/MEDCoupling_Swig/MEDCouplingRefCountObject.i deleted file mode 100644 index 48003ef55..000000000 --- a/src/MEDCoupling_Swig/MEDCouplingRefCountObject.i +++ /dev/null @@ -1,168 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 -// 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) - -namespace INTERP_KERNEL -{ - class Exception - { - public: - Exception(const char* what); - ~Exception() throw (); - const char *what() const throw (); - %extend - { - std::string __str__() const - { - return std::string(self->what()); - } - } - }; -} - -namespace ParaMEDMEM -{ - class TimeLabel - { - public: - void declareAsNew() const; - virtual void updateTime() const; - unsigned int getTimeOfThis() const; - protected: - ~TimeLabel(); - }; -} - -namespace ParaMEDMEM -{ - typedef enum - { - C_DEALLOC = 2, - CPP_DEALLOC = 3 - } DeallocType; - - const char *MEDCouplingVersionStr(); - int MEDCouplingVersion(); - int MEDCouplingSizeOfVoidStar(); - bool MEDCouplingByteOrder(); - const char *MEDCouplingByteOrderStr(); - - class BigMemoryObject - { - public: - std::size_t getHeapMemorySize() const throw(INTERP_KERNEL::Exception); - std::string getHeapMemorySizeStr() const throw(INTERP_KERNEL::Exception); - bool isObjectInTheProgeny(const BigMemoryObject *obj) const throw(INTERP_KERNEL::Exception); - virtual std::size_t getHeapMemorySizeWithoutChildren() const throw(INTERP_KERNEL::Exception); - virtual ~BigMemoryObject(); - %extend - { - virtual PyObject *getDirectChildren() const throw(INTERP_KERNEL::Exception) - { - std::vector c(self->getDirectChildren()); - PyObject *ret(PyList_New(c.size())); - for(std::size_t i=0;i c(self->getAllTheProgeny()); - PyObject *ret(PyList_New(c.size())); - for(std::size_t i=0;i cppObjs; - convertFromPyObjVectorOfObj(objs,SWIGTYPE_p_ParaMEDMEM__BigMemoryObject,"BigMemoryObject",cppObjs); - return BigMemoryObject::GetHeapMemorySizeOfObjs(cppObjs); - } - } - }; - - class RefCountObjectOnly - { - public: - bool decrRef() const; - void incrRef() const; - int getRCValue() const; - protected: - ~RefCountObjectOnly(); - }; - - class RefCountObject : public RefCountObjectOnly, public BigMemoryObject - { - protected: - ~RefCountObject(); - }; -} - -%inline -{ - PyObject *MEDCouplingVersionMajMinRel() - { - int tmp0=0,tmp1=0,tmp2=0; - MEDCouplingVersionMajMinRel(tmp0,tmp1,tmp2); - PyObject *res = PyList_New(3); - PyList_SetItem(res,0,SWIG_From_int(tmp0)); - PyList_SetItem(res,1,SWIG_From_int(tmp1)); - PyList_SetItem(res,2,SWIG_From_int(tmp2)); - return res; - } - - bool MEDCouplingHasNumPyBindings() - { -#ifdef WITH_NUMPY - return true; -#else - return false; -#endif - } - - bool MEDCouplingHasSciPyBindings() - { -#ifdef WITH_SCIPY - return true; -#else - return false; -#endif - } - - std::string MEDCouplingCompletionScript() throw(INTERP_KERNEL::Exception) - { - static const char script[]="import rlcompleter,readline\nreadline.parse_and_bind('tab:complete')"; - std::ostringstream oss; oss << "MEDCouplingCompletionScript : error when trying to activate completion ! readline not present ?\nScript is :\n" << script; - if(PyRun_SimpleString(script)!=0) - throw INTERP_KERNEL::Exception(oss.str().c_str()); - return std::string(script); - } -} - -%pythoncode %{ -def INTERPKERNELExceptionReduceFunct(a,b): - ret=InterpKernelException.__new__(a) - ret.__init__(*b) - return ret -def INTERPKERNELExceptionReduce(self): - return INTERPKERNELExceptionReduceFunct,(InterpKernelException,(self.what(),)) -%} diff --git a/src/MEDCoupling_Swig/MEDCouplingRemapper.i b/src/MEDCoupling_Swig/MEDCouplingRemapper.i deleted file mode 100644 index 135958b88..000000000 --- a/src/MEDCoupling_Swig/MEDCouplingRemapper.i +++ /dev/null @@ -1,222 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 -// 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 -// - -%module MEDCouplingRemapper - -#define MEDCOUPLING_EXPORT -#define INTERPKERNEL_EXPORT -#define MEDCOUPLINGREMAPPER_EXPORT - -%{ -#include "MEDCouplingMemArray.hxx" -#include "MEDCouplingUMesh.hxx" -#include "MEDCouplingField.hxx" -#include "MEDCouplingFieldDouble.hxx" -#include "MEDCouplingRemapper.hxx" - -using namespace ParaMEDMEM; -using namespace INTERP_KERNEL; -%} - -%newobject ParaMEDMEM::MEDCouplingRemapper::transferField; -%newobject ParaMEDMEM::MEDCouplingRemapper::reverseTransferField; - -%include "MEDCouplingCommon.i" -%include "InterpolationOptions.hxx" - -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 - { - private: - void updateTime() const; - public: - MEDCouplingRemapper(); - ~MEDCouplingRemapper(); - int prepare(const MEDCouplingMesh *srcMesh, const MEDCouplingMesh *targetMesh, const std::string& method) throw(INTERP_KERNEL::Exception); - int prepareEx(const MEDCouplingFieldTemplate *src, const MEDCouplingFieldTemplate *target) throw(INTERP_KERNEL::Exception); - void transfer(const MEDCouplingFieldDouble *srcField, MEDCouplingFieldDouble *targetField, double dftValue) throw(INTERP_KERNEL::Exception); - void partialTransfer(const MEDCouplingFieldDouble *srcField, MEDCouplingFieldDouble *targetField) throw(INTERP_KERNEL::Exception); - void reverseTransfer(MEDCouplingFieldDouble *srcField, const MEDCouplingFieldDouble *targetField, double dftValue) throw(INTERP_KERNEL::Exception); - MEDCouplingFieldDouble *transferField(const MEDCouplingFieldDouble *srcField, double dftValue) throw(INTERP_KERNEL::Exception); - MEDCouplingFieldDouble *reverseTransferField(const MEDCouplingFieldDouble *targetField, double dftValue) throw(INTERP_KERNEL::Exception); - bool setOptionInt(const std::string& key, int value) throw(INTERP_KERNEL::Exception); - bool setOptionDouble(const std::string& key, double value) throw(INTERP_KERNEL::Exception); - bool setOptionString(const std::string& key, const std::string& value) throw(INTERP_KERNEL::Exception); - int getInterpolationMatrixPolicy() const throw(INTERP_KERNEL::Exception); - void setInterpolationMatrixPolicy(int newInterpMatPol) throw(INTERP_KERNEL::Exception); - // - int nullifiedTinyCoeffInCrudeMatrixAbs(double maxValAbs) throw(INTERP_KERNEL::Exception); - int nullifiedTinyCoeffInCrudeMatrix(double scaleFactor) throw(INTERP_KERNEL::Exception); - double getMaxValueInCrudeMatrix() const throw(INTERP_KERNEL::Exception); - int getNumberOfColsOfMatrix() const throw(INTERP_KERNEL::Exception); - static std::string BuildMethodFrom(const std::string& meth1, const std::string& meth2) throw(INTERP_KERNEL::Exception); - %extend - { - PyObject *getCrudeMatrix() const throw(INTERP_KERNEL::Exception) - { - const std::vector >& m=self->getCrudeMatrix(); - std::size_t sz=m.size(); - PyObject *ret=PyList_New(sz); - for(std::size_t i=0;i& row=m[i]; - PyObject *ret0=PyDict_New(); - for(std::map::const_iterator it=row.begin();it!=row.end();it++) - PyDict_SetItem(ret0,PyInt_FromLong((*it).first),PyFloat_FromDouble((*it).second)); - PyList_SetItem(ret,i,ret0); - } - return ret; - } -#if defined(WITH_NUMPY) && defined(WITH_SCIPY) - PyObject *getCrudeCSRMatrix() const throw(INTERP_KERNEL::Exception) - { - return ToCSRMatrix(self->getCrudeMatrix(),self->getNumberOfColsOfMatrix()); - } -#endif - } - }; -} - -%pythoncode %{ -def ParaMEDMEMDataArrayDoublenew(cls,*args): - import _MEDCouplingRemapper - return _MEDCouplingRemapper.DataArrayDouble____new___(cls,args) -def ParaMEDMEMDataArrayDoubleIadd(self,*args): - import _MEDCouplingRemapper - return _MEDCouplingRemapper.DataArrayDouble____iadd___(self, self, *args) -def ParaMEDMEMDataArrayDoubleIsub(self,*args): - import _MEDCouplingRemapper - return _MEDCouplingRemapper.DataArrayDouble____isub___(self, self, *args) -def ParaMEDMEMDataArrayDoubleImul(self,*args): - import _MEDCouplingRemapper - return _MEDCouplingRemapper.DataArrayDouble____imul___(self, self, *args) -def ParaMEDMEMDataArrayDoubleIdiv(self,*args): - import _MEDCouplingRemapper - return _MEDCouplingRemapper.DataArrayDouble____idiv___(self, self, *args) -def ParaMEDMEMDataArrayDoubleIpow(self,*args): - import _MEDCouplingRemapper - return _MEDCouplingRemapper.DataArrayDouble____ipow___(self, self, *args) -def ParaMEDMEMMEDCouplingFieldDoublenew(cls,*args): - import _MEDCouplingRemapper - return _MEDCouplingRemapper.MEDCouplingFieldDouble____new___(cls,args) -def ParaMEDMEMMEDCouplingFieldDoubleIadd(self,*args): - import _MEDCouplingRemapper - return _MEDCouplingRemapper.MEDCouplingFieldDouble____iadd___(self, self, *args) -def ParaMEDMEMMEDCouplingFieldDoubleIsub(self,*args): - import _MEDCouplingRemapper - return _MEDCouplingRemapper.MEDCouplingFieldDouble____isub___(self, self, *args) -def ParaMEDMEMMEDCouplingFieldDoubleImul(self,*args): - import _MEDCouplingRemapper - return _MEDCouplingRemapper.MEDCouplingFieldDouble____imul___(self, self, *args) -def ParaMEDMEMMEDCouplingFieldDoubleIdiv(self,*args): - import _MEDCouplingRemapper - return _MEDCouplingRemapper.MEDCouplingFieldDouble____idiv___(self, self, *args) -def ParaMEDMEMMEDCouplingFieldDoubleIpow(self,*args): - import _MEDCouplingRemapper - return _MEDCouplingRemapper.MEDCouplingFieldDouble____ipow___(self, self, *args) -def ParaMEDMEMDataArrayIntnew(cls,*args): - import _MEDCouplingRemapper - return _MEDCouplingRemapper.DataArrayInt____new___(cls,args) -def ParaMEDMEMDataArrayIntnew(cls,*args): - import _MEDCoupling - return _MEDCoupling.DataArrayInt____new___(cls,args) -def ParaMEDMEMDataArrayIntIadd(self,*args): - import _MEDCouplingRemapper - return _MEDCouplingRemapper.DataArrayInt____iadd___(self, self, *args) -def ParaMEDMEMDataArrayIntIsub(self,*args): - import _MEDCouplingRemapper - return _MEDCouplingRemapper.DataArrayInt____isub___(self, self, *args) -def ParaMEDMEMDataArrayIntImul(self,*args): - import _MEDCouplingRemapper - return _MEDCouplingRemapper.DataArrayInt____imul___(self, self, *args) -def ParaMEDMEMDataArrayIntIdiv(self,*args): - import _MEDCouplingRemapper - return _MEDCouplingRemapper.DataArrayInt____idiv___(self, self, *args) -def ParaMEDMEMDataArrayIntImod(self,*args): - import _MEDCouplingRemapper - return _MEDCouplingRemapper.DataArrayInt____imod___(self, self, *args) -def ParaMEDMEMDataArrayIntIpow(self,*args): - import _MEDCouplingRemapper - return _MEDCouplingRemapper.DataArrayInt____ipow___(self, self, *args) -def ParaMEDMEMDataArrayDoubleTupleIadd(self,*args): - import _MEDCouplingRemapper - return _MEDCouplingRemapper.DataArrayDoubleTuple____iadd___(self, self, *args) -def ParaMEDMEMDataArrayDoubleTupleIsub(self,*args): - import _MEDCouplingRemapper - return _MEDCouplingRemapper.DataArrayDoubleTuple____isub___(self, self, *args) -def ParaMEDMEMDataArrayDoubleTupleImul(self,*args): - import _MEDCouplingRemapper - return _MEDCouplingRemapper.DataArrayDoubleTuple____imul___(self, self, *args) -def ParaMEDMEMDataArrayDoubleTupleIdiv(self,*args): - import _MEDCouplingRemapper - return _MEDCouplingRemapper.DataArrayDoubleTuple____idiv___(self, self, *args) -def ParaMEDMEMDataArrayIntTupleIadd(self,*args): - import _MEDCouplingRemapper - return _MEDCouplingRemapper.DataArrayIntTuple____iadd___(self, self, *args) -def ParaMEDMEMDataArrayIntTupleIsub(self,*args): - import _MEDCouplingRemapper - return _MEDCouplingRemapper.DataArrayIntTuple____isub___(self, self, *args) -def ParaMEDMEMDataArrayIntTupleImul(self,*args): - import _MEDCouplingRemapper - return _MEDCouplingRemapper.DataArrayIntTuple____imul___(self, self, *args) -def ParaMEDMEMDataArrayIntTupleIdiv(self,*args): - import _MEDCouplingRemapper - return _MEDCouplingRemapper.DataArrayIntTuple____idiv___(self, self, *args) -def ParaMEDMEMDataArrayIntTupleImod(self,*args): - import _MEDCouplingRemapper - return _MEDCouplingRemapper.DataArrayIntTuple____imod___(self, self, *args) -def ParaMEDMEMDenseMatrixIadd(self,*args): - import _MEDCouplingRemapper - return _MEDCouplingRemapper.DenseMatrix____iadd___(self, self, *args) -def ParaMEDMEMDenseMatrixIsub(self,*args): - import _MEDCouplingRemapper - return _MEDCouplingRemapper.DenseMatrix____isub___(self, self, *args) -def ParaMEDMEMMEDCouplingUMeshnew(cls,*args): - import _MEDCouplingRemapper - return _MEDCouplingRemapper.MEDCouplingUMesh____new___(cls,args) -def ParaMEDMEMMEDCoupling1DGTUMeshnew(cls,*args): - import _MEDCouplingRemapper - return _MEDCouplingRemapper.MEDCoupling1DGTUMesh____new___(cls,args) -def ParaMEDMEMMEDCoupling1SGTUMeshnew(cls,*args): - import _MEDCouplingRemapper - return _MEDCouplingRemapper.MEDCoupling1SGTUMesh____new___(cls,args) -def ParaMEDMEMMEDCouplingCurveLinearMeshnew(cls,*args): - import _MEDCouplingRemapper - return _MEDCouplingRemapper.MEDCouplingCurveLinearMesh____new___(cls,args) -def ParaMEDMEMMEDCouplingCMeshnew(cls,*args): - import _MEDCouplingRemapper - return _MEDCouplingRemapper.MEDCouplingCMesh____new___(cls,args) -def ParaMEDMEMMEDCouplingIMeshnew(cls,*args): - import _MEDCouplingRemapper - return _MEDCouplingRemapper.MEDCouplingIMesh____new___(cls,args) -def ParaMEDMEMMEDCouplingExtrudedMeshnew(cls,*args): - import _MEDCouplingRemapper - return _MEDCouplingRemapper.MEDCouplingExtrudedMesh____new___(cls,args) -%} - -%include "MEDCouplingFinalize.i" diff --git a/src/MEDCoupling_Swig/MEDCouplingRemapperTest.py b/src/MEDCoupling_Swig/MEDCouplingRemapperTest.py deleted file mode 100644 index ba5ba6428..000000000 --- a/src/MEDCoupling_Swig/MEDCouplingRemapperTest.py +++ /dev/null @@ -1,907 +0,0 @@ -# -*- coding: iso-8859-1 -*- -# Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 -# 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 -# - -from MEDCouplingDataForTest import MEDCouplingDataForTest -from MEDCouplingRemapper import * -from math import * -import unittest - -class MEDCouplingBasicsTest(unittest.TestCase): - def testRemapper1(self): - sourceMesh=self.build2DSourceMesh_1(); - targetMesh=self.build2DTargetMesh_1(); - remapper=MEDCouplingRemapper() - remapper.setPrecision(1e-12); - remapper.setIntersectionType(Triangulation); - self.failUnless(remapper.prepare(sourceMesh,targetMesh,"P0P0")==1); - srcField=MEDCouplingFieldDouble.New(ON_CELLS); - srcField.setNature(ConservativeVolumic); - srcField.setMesh(sourceMesh); - array=DataArrayDouble.New(); - ptr=sourceMesh.getNumberOfCells()*[None] - for i in xrange(sourceMesh.getNumberOfCells()): - ptr[i]=float(i+7) - pass - array.setValues(ptr,sourceMesh.getNumberOfCells(),1); - srcField.setArray(array); - srcField.setName("abc") ; srcField.setDescription("def") - srcField.setTime(7.7,9,10) - trgfield=remapper.transferField(srcField,4.57); - self.assertEqual("abc",trgfield.getName()) - self.assertEqual("def",trgfield.getDescription()) - a,b,c=trgfield.getTime() - self.assertAlmostEqual(7.7,a,14) - self.assertEqual(b,9) - self.assertEqual(c,10) - values=trgfield.getArray().getValues(); - valuesExpected=[7.5 ,7. ,7.,8.,7.5]; - for i in xrange(targetMesh.getNumberOfCells()): - self.failUnless(abs(values[i]-valuesExpected[i])<1e-12); - pass - self.failUnless(1==trgfield.getArray().getNumberOfComponents()); - pass - - def testPrepareEx1(self): - sourceMesh=self.build2DSourceMesh_1(); - targetMesh=self.build2DTargetMesh_3(); - # - remapper=MEDCouplingRemapper(); - remapper.setPrecision(1e-12); - remapper.setIntersectionType(Triangulation); - srcFt=MEDCouplingFieldTemplate.New(ON_CELLS); - trgFt=MEDCouplingFieldTemplate.New(ON_CELLS); - srcFt.setMesh(sourceMesh); - trgFt.setMesh(targetMesh); - self.assertEqual(1,remapper.prepareEx(srcFt,trgFt)); - srcField=MEDCouplingFieldDouble.New(ON_CELLS); - srcField.setNature(ConservativeVolumic); - srcField.setMesh(sourceMesh); - array=DataArrayDouble.New(); - ptr=sourceMesh.getNumberOfCells()*[None] - for i in xrange(sourceMesh.getNumberOfCells()): - ptr[i]=float(i+7); - pass - array.setValues(ptr,sourceMesh.getNumberOfCells(),1); - srcField.setArray(array); - trgfield=remapper.transferField(srcField,4.220173); - values=trgfield.getArray().getValues(); - valuesExpected=[7.75, 7.0625, 4.220173,8.0] - self.assertEqual(4,trgfield.getArray().getNumberOfTuples()); - self.assertEqual(1,trgfield.getArray().getNumberOfComponents()); - for i0 in xrange(4): - self.assertAlmostEqual(valuesExpected[i0],values[i0],12); - pass - pass - - def testPartialTransfer1(self): - sourceMesh=self.build2DSourceMesh_1(); - targetMesh=self.build2DTargetMesh_3(); - # - remapper=MEDCouplingRemapper(); - remapper.setPrecision(1e-12); - remapper.setIntersectionType(Triangulation); - srcFt=MEDCouplingFieldTemplate.New(ON_CELLS); - trgFt=MEDCouplingFieldTemplate.New(ON_CELLS); - srcFt.setMesh(sourceMesh); - trgFt.setMesh(targetMesh); - self.assertEqual(1,remapper.prepareEx(srcFt,trgFt)); - srcField=MEDCouplingFieldDouble.New(ON_CELLS); - srcField.setNature(ConservativeVolumic); - srcField.setMesh(sourceMesh); - array=DataArrayDouble.New(); - ptr=sourceMesh.getNumberOfCells()*[None] - for i in xrange(sourceMesh.getNumberOfCells()): - ptr[i]=float(i+7); - pass - array.setValues(ptr,sourceMesh.getNumberOfCells(),1); - srcField.setArray(array); - trgfield=MEDCouplingFieldDouble.New(ON_CELLS); - trgfield.setNature(ConservativeVolumic); - trgfield.setMesh(targetMesh); - array=DataArrayDouble.New(); - ptr=targetMesh.getNumberOfCells()*[None] - for i in xrange(targetMesh.getNumberOfCells()): - ptr[i]=4.220173; - pass - array.setValues(ptr,targetMesh.getNumberOfCells(),1); - trgfield.setArray(array); - remapper.partialTransfer(srcField,trgfield); - values=trgfield.getArray().getValues(); - valuesExpected=[7.75, 7.0625, 4.220173,8.0] - self.assertEqual(4,trgfield.getArray().getNumberOfTuples()); - self.assertEqual(1,trgfield.getArray().getNumberOfComponents()); - for i0 in xrange(4): - self.assertAlmostEqual(valuesExpected[i0],values[i0],12); - pass - pass - - def testPrepareUC(self): - # 1D - coords=DataArrayDouble([0.,0.5,0.7]) - src=MEDCouplingUMesh("",1) ; src.setCoords(coords) - src.allocateCells(2) ; src.insertNextCell(NORM_SEG2,[0,1]) ; src.insertNextCell(NORM_SEG2,[1,2]) ; src.finishInsertingCells() - trg=MEDCouplingCMesh() ; arr=DataArrayDouble([-0.7,-0.1,0.2,0.7,2.,2.3]) - trg.setCoordsAt(0,arr) - fieldSrc=MEDCouplingFieldDouble(ON_CELLS,NO_TIME) ; fieldSrc.setMesh(src) ; arrSrc=DataArrayDouble([10.,30.]) - fieldSrc.setNature(Integral) ; fieldSrc.setArray(arrSrc) - rem=MEDCouplingRemapper() - rem.prepare(src,trg,"P0P0") - trgField=rem.transferField(fieldSrc,-7.) - expected1=[-7.,4.,36.,-7.,-7.] - self.assertEqual(5,trgField.getArray().getNumberOfTuples()) - self.assertEqual(5,len(expected1)) - for i,val in enumerate(expected1): - self.assertAlmostEqual(expected1[i],trgField.getArray().getIJ(i,0),12); - pass - # 2D - coords=DataArrayDouble([0.,0.,0.,1.,1.,1.,1.,0.,0.5,-0.2],5,2) - src=MEDCouplingUMesh("",2) ; src.setCoords(coords) - src.allocateCells(2) ; src.insertNextCell(NORM_TRI3,[0,1,2]) ; src.insertNextCell(NORM_TRI3,[3,4,0]) ; src.finishInsertingCells() - trg=MEDCouplingCMesh() ; arr=DataArrayDouble([-0.7,-0.1,0.2,0.7,2.,2.3]) - trg.setCoordsAt(0,arr) ; trg.setCoordsAt(1,arr) - fieldSrc=MEDCouplingFieldDouble(ON_CELLS,NO_TIME) ; fieldSrc.setMesh(src) ; arrSrc=DataArrayDouble([10.,30.]) - fieldSrc.setNature(Integral) ; fieldSrc.setArray(arrSrc) - rem=MEDCouplingRemapper() - rem.prepare(src,trg,"P0P0") - trgField=rem.transferField(fieldSrc,-7.) - expected2=[-7.,-7.,7.35,0.15,-7.,-7.,2.8,14.85,5.25,-7.,-7.,2.,2.5,-7.,-7.,-7.,1.2,3.,0.9,-7.,-7.,-7.,-7.,-7.,-7.] - self.assertEqual(25,trgField.getArray().getNumberOfTuples()) - self.assertEqual(25,len(expected2)) - for i,val in enumerate(expected2): - self.assertAlmostEqual(expected2[i],trgField.getArray().getIJ(i,0),12); - pass - # 3D - coords=DataArrayDouble([0.,0.,0.,0.,1.,0.,1.,1.,0.,1.,0.,0.,0.5,-0.2,0.,0.1,0.8,1.,0.5,0.,1.],7,3) - src=MEDCouplingUMesh("",3) ; src.setCoords(coords) - src.allocateCells(2) ; src.insertNextCell(NORM_TETRA4,[0,1,2,5]) ; src.insertNextCell(NORM_TETRA4,[3,4,0,6]) ; src.finishInsertingCells() - trg=MEDCouplingCMesh() ; arr=DataArrayDouble([-0.7,-0.1,0.2,0.7,2.,2.3]) ; arr2=DataArrayDouble([-0.7,0.2,0.6,1.2,2.]) - trg.setCoordsAt(0,arr) ; trg.setCoordsAt(1,arr) ; trg.setCoordsAt(2,arr2) - src.checkCoherency2(1e-10) - trg.checkCoherency() - fieldSrc=MEDCouplingFieldDouble(ON_CELLS,NO_TIME) ; fieldSrc.setMesh(src) ; arrSrc=DataArrayDouble([10.,30.]) - fieldSrc.setNature(Integral) ; fieldSrc.setArray(arrSrc) - rem=MEDCouplingRemapper() - rem.prepare(src,trg,"P0P0") - trgField=rem.transferField(fieldSrc,-7.) - expected3=[-7.,-7.,2.925,0.015,-7.,-7.,0.9392,8.595,2.265,-7.,-7.,1.1008,1.1192,-7.,-7.,-7.,0.6392,1.6408,0.2808,-7.,-7.,-7.,-7.,-7.,-7.,-7.,-7.,0.81,-7.,-7.,-7.,0.1208,11.55,0.96,-7.,-7.,1.1752,0.6592,-7.,-7.,-7.,0.8512,1.7744,0.0192,-7.,-7.,-7.,-7.,-7.,-7.,-7.,-7.,-7.,-7.,-7.,-7.,-7.,1.92,-7.,-7.,-7.,0.12578571428571422,0.007314285714285673,-7.,-7.,-7.,0.3189253968253971,0.1879746031746033,-7.,-7.,-7.,-7.,-7.,-7.,-7.,-7.,-7.,-7.,-7.,-7.,-7.,-7.,-7.,-7.,-7.,-7.,-7.,-7.,-7.,-7.,-7.,-7.,-7.,-7.,-7.,-7.,-7.,-7.,-7.,-7.] - self.assertEqual(100,trgField.getArray().getNumberOfTuples()) - self.assertEqual(100,len(expected3)) - for i,val in enumerate(expected3): - self.assertAlmostEqual(expected3[i],trgField.getArray().getIJ(i,0),12); - pass - pass - - def testPrepareCU(self): - # 1D - coords=DataArrayDouble([0.,0.5,0.7]) - trg=MEDCouplingUMesh("",1) ; trg.setCoords(coords) - trg.allocateCells(2) ; trg.insertNextCell(NORM_SEG2,[0,1]) ; trg.insertNextCell(NORM_SEG2,[1,2]) ; trg.finishInsertingCells() - src=MEDCouplingCMesh() ; arr=DataArrayDouble([-0.7,-0.1,0.2,0.7,2.,2.3]) - src.setCoordsAt(0,arr) - fieldSrc=MEDCouplingFieldDouble(ON_CELLS,NO_TIME) ; fieldSrc.setMesh(src) ; arrTrg=DataArrayDouble([10.,30.,40.,70.,80.]) - fieldSrc.setNature(Integral) ; fieldSrc.setArray(arrTrg) - rem=MEDCouplingRemapper() - rem.prepare(src,trg,"P0P0") - trgField=rem.transferField(fieldSrc,-7.) - expected1=[44.,16.] - self.assertEqual(2.,trgField.getArray().getNumberOfTuples()) - self.assertEqual(2,len(expected1)) - for i,val in enumerate(expected1): - self.assertAlmostEqual(expected1[i],trgField.getArray().getIJ(i,0),12); - pass - # 2D - coords=DataArrayDouble([0.,0.,0.,1.,1.,1.,1.,0.,0.5,-0.2],5,2) - trg=MEDCouplingUMesh("",2) ; trg.setCoords(coords) - trg.allocateCells(2) ; trg.insertNextCell(NORM_TRI3,[0,1,2]) ; trg.insertNextCell(NORM_TRI3,[3,4,0]) ; trg.finishInsertingCells() - src=MEDCouplingCMesh() ; arr=DataArrayDouble([-0.7,-0.1,0.2,0.7,2.,2.3]) - src.setCoordsAt(0,arr) ; src.setCoordsAt(1,arr) - fieldSrc=MEDCouplingFieldDouble(ON_CELLS,NO_TIME) ; fieldSrc.setMesh(src) ; arrSrc=DataArrayDouble([10.,30.,40.,70.,80.,110.,130.,140.,170.,180.,210.,230.,240.,270.,280.,310.,330.,340.,370.,380.,410.,430.,440.,470.,480.]) - fieldSrc.setNature(Integral) ; fieldSrc.setArray(arrSrc) - rem=MEDCouplingRemapper() - rem.prepare(src,trg,"P0P0") - trgField=rem.transferField(fieldSrc,-7.) - expected2=[441.3050624589086,68.69529914529915] - self.assertEqual(2,trgField.getArray().getNumberOfTuples()) - self.assertEqual(2,len(expected2)) - for i,val in enumerate(expected2): - self.assertAlmostEqual(expected2[i],trgField.getArray().getIJ(i,0),12); - pass - # 3D - coords=DataArrayDouble([0.,0.,0.,0.,1.,0.,1.,1.,0.,1.,0.,0.,0.5,-0.2,0.,0.1,0.8,1.,0.5,0.,1.],7,3) - trg=MEDCouplingUMesh("",3) ; trg.setCoords(coords) - trg.allocateCells(2) ; trg.insertNextCell(NORM_TETRA4,[0,1,2,5]) ; trg.insertNextCell(NORM_TETRA4,[3,4,0,6]) ; trg.finishInsertingCells() - src=MEDCouplingCMesh() ; arr=DataArrayDouble([-0.7,-0.1,0.2,0.7,2.,2.3]) ; arr2=DataArrayDouble([-0.7,0.2,0.6,1.2,2.]) - src.setCoordsAt(0,arr) ; src.setCoordsAt(1,arr) ; src.setCoordsAt(2,arr2) - trg.checkCoherency2(1e-10) - src.checkCoherency() - fieldSrc=MEDCouplingFieldDouble(ON_CELLS,NO_TIME) ; fieldSrc.setMesh(src) ; arrSrc=DataArrayDouble(100) ; arrSrc.iota(7.7) - fieldSrc.setNature(Integral) ; fieldSrc.setArray(arrSrc) - rem=MEDCouplingRemapper() - rem.prepare(src,trg,"P0P0") - trgField=rem.transferField(fieldSrc,-7.) - expected3=[39.635196634558845,12.13422356758468] - self.assertEqual(2,trgField.getArray().getNumberOfTuples()) - self.assertEqual(2,len(expected3)) - for i,val in enumerate(expected3): - self.assertAlmostEqual(expected3[i],trgField.getArray().getIJ(i,0),12); - pass - pass - - def testPrepareCC(self): - # 1D - src=MEDCouplingCMesh() ; arr=DataArrayDouble([-0.7,-0.1,0.2,0.7,2.,2.3]) - src.setCoordsAt(0,arr) - trg=MEDCouplingCMesh() ; arr=DataArrayDouble([-0.9,-0.1,0.15]) - trg.setCoordsAt(0,arr) - fieldSrc=MEDCouplingFieldDouble(ON_CELLS,NO_TIME) ; fieldSrc.setMesh(src) ; arrTrg=DataArrayDouble([10.,30.,40.,70.,80.]) - fieldSrc.setNature(Integral) ; fieldSrc.setArray(arrTrg) - rem=MEDCouplingRemapper() - rem.prepare(src,trg,"P0P0") - trgField=rem.transferField(fieldSrc,-7.) - expected1=[10.,25.] - self.assertEqual(2.,trgField.getArray().getNumberOfTuples()) - self.assertEqual(2,len(expected1)) - for i,val in enumerate(expected1): - self.assertAlmostEqual(expected1[i],trgField.getArray().getIJ(i,0),12); - pass - # 2D - src=MEDCouplingCMesh() ; arr=DataArrayDouble([-0.7,-0.1,0.2,0.7,2.,2.3]) - src.setCoordsAt(0,arr) ; src.setCoordsAt(1,arr) - trg=MEDCouplingCMesh() ; arr=DataArrayDouble([-0.9,-0.1,0.15]) - trg.setCoordsAt(0,arr) ; trg.setCoordsAt(1,arr) - fieldSrc=MEDCouplingFieldDouble(ON_CELLS,NO_TIME) ; fieldSrc.setMesh(src) ; arrSrc=DataArrayDouble([10.,30.,40.,70.,80.,110.,130.,140.,170.,180.,210.,230.,240.,270.,280.,310.,330.,340.,370.,380.,410.,430.,440.,470.,480.]) - fieldSrc.setNature(Integral) ; fieldSrc.setArray(arrSrc) - rem=MEDCouplingRemapper() - rem.prepare(src,trg,"P0P0") - trgField=rem.transferField(fieldSrc,-7.) - expected2=[10.,25.,91.66666666666666,90.27777777777777] - self.assertEqual(4,trgField.getArray().getNumberOfTuples()) - self.assertEqual(4,len(expected2)) - for i,val in enumerate(expected2): - self.assertAlmostEqual(expected2[i],trgField.getArray().getIJ(i,0),12); - pass - # 3D - src=MEDCouplingCMesh() ; arr=DataArrayDouble([-0.7,-0.1,0.2,0.7,2.,2.3]) - src.setCoordsAt(0,arr) ; src.setCoordsAt(1,arr) ; src.setCoordsAt(2,arr) - trg=MEDCouplingCMesh() ; arr=DataArrayDouble([-0.9,-0.1,0.15]) - trg.setCoordsAt(0,arr) ; trg.setCoordsAt(1,arr) ; trg.setCoordsAt(2,arr) - fieldSrc=MEDCouplingFieldDouble(ON_CELLS,NO_TIME) ; fieldSrc.setMesh(src) ; arrSrc=DataArrayDouble(125) ; arrSrc.iota(7.7) - fieldSrc.setNature(Integral) ; fieldSrc.setArray(arrSrc) ; fieldSrc.checkCoherency() - rem=MEDCouplingRemapper() - rem.prepare(src,trg,"P0P0") - trgField=rem.transferField(fieldSrc,-7.) - expected3=[7.7, 7.249999999999999, 10.583333333333332, 9.513888888888886, 27.25, 23.40277777777777, 26.180555555555546, 22.39583333333333] - self.assertEqual(8,trgField.getArray().getNumberOfTuples()) - self.assertEqual(8,len(expected3)) - for i,val in enumerate(expected3): - self.assertAlmostEqual(expected3[i],trgField.getArray().getIJ(i,0),12); - pass - pass - - # Bug when source mesh is not homogeneously oriented in source mesh - def testNonRegressionNonHomegenousOrriented3DCells(self): - csrc=DataArrayDouble([-0.15240000188350677,0,0,-0.1086929515004158,0,0,-0.15240000188350677,0.018142856657505035,0,-0.13054648041725159,0.0090714283287525177,0.019050000235438347,-0.13054648041725159,0.0090714283287525177,0],5,3) - src1=MEDCouplingUMesh("src",3) ; src1.allocateCells(0) ; src1.insertNextCell(NORM_TETRA4,[0,1,4,3]) ; src1.insertNextCell(NORM_TETRA4,[2,0,4,3]) - src2=MEDCouplingUMesh("src",3) ; src2.allocateCells(0) ; src2.insertNextCell(NORM_TETRA4,[0,4,1,3]) ; src2.insertNextCell(NORM_TETRA4,[2,0,4,3]) - src1.setCoords(csrc) ; src2.setCoords(csrc) - ctrg=DataArrayDouble([-0.15240000188350677,-0.038100000470876694,0,0.32379999756813049,-0.038100000470876694,0,-0.15240000188350677,0.076200000941753387,0,0.32379999756813049,0.076200000941753387,0,-0.15240000188350677,-0.038100000470876694,0.076200000941753387,0.32379999756813049,-0.038100000470876694,0.076200000941753387,-0.15240000188350677,0.076200000941753387,0.076200000941753387,0.32379999756813049,0.076200000941753387,0.076200000941753387],8,3) - trg=MEDCouplingUMesh("trg",3) ; trg.allocateCells(0) ; trg.insertNextCell(NORM_HEXA8,[0,1,3,2,4,5,7,6]) - trg.setCoords(ctrg) - rem1=MEDCouplingRemapper() ; rem1.setSplittingPolicy(PLANAR_FACE_5) ; rem1.prepare(src1,trg,"P0P0") - rem2=MEDCouplingRemapper() ; rem2.setSplittingPolicy(PLANAR_FACE_5) ; rem2.prepare(src1,trg,"P0P0") - mat1=rem1.getCrudeMatrix() ; mat2=rem2.getCrudeMatrix() - self.assertEqual(1,len(mat1)) ; self.assertEqual(1,len(mat2)) - self.assertEqual(mat1[0].keys(),mat2[0].keys()) ; self.assertEqual([0,1],mat1[0].keys()) - self.assertAlmostEqual(1.25884108122e-06,mat1[0][0],16) ; self.assertAlmostEqual(1.25884108122e-06,mat2[0][0],16) - self.assertAlmostEqual(1.25884086663e-06,mat1[0][1],16) ; self.assertAlmostEqual(1.25884086663e-06,mat2[0][1],16) - # - d=DataArrayDouble([13.45,27.67],2,1) - f1=MEDCouplingFieldDouble(ON_CELLS,ONE_TIME) ; f1.setMesh(src1) ; f1.setArray(d) ; f1.setNature(RevIntegral) - f2=MEDCouplingFieldDouble(ON_CELLS,ONE_TIME) ; f2.setMesh(src2) ; f2.setArray(d) ; f2.setNature(RevIntegral) - f11=rem1.transferField(f1,1e300) ; f22=rem2.transferField(f2,1e300) - expected1=DataArrayDouble([0.012480539537637884]) - self.assertTrue(f11.getArray().isEqual(expected1,1e-15)) - self.assertTrue(f22.getArray().isEqual(expected1,1e-15)) - # - f1.setNature(Integral) ; f2.setNature(Integral) - f11=rem1.transferField(f1,1e300) ; f22=rem2.transferField(f2,1e300) - # - expected2=DataArrayDouble([41.12]) - self.assertTrue(f11.getArray().isEqual(expected2,1e-13)) - self.assertTrue(f22.getArray().isEqual(expected2,1e-13)) - pass - - def testCellToNodeReverse3D(self): - c=DataArrayDouble([0.,1.,2.5]) - cc=MEDCouplingCMesh() - cc.setCoords(c,c,c) - um=cc.buildUnstructured() - f=um.getMeasureField(ON_CELLS) - # - n2o=um.simplexize(PLANAR_FACE_5) - f.setArray(f.getArray()[n2o]) - f.checkCoherency() - f.setNature(ConservativeVolumic) - f.setTime(5.6,7,8) - f.setName("toto") ; f.setDescription("aDescription") - p=MEDCouplingRemapper() - p.setIntersectionType(Barycentric) - p.prepare(um,um,"P1P0") - fNode=p.reverseTransferField(f,1e300) - self.assertEqual("toto",fNode.getName()) - self.assertEqual("aDescription",fNode.getDescription()) - a,b,c=fNode.getTime() - self.assertAlmostEqual(5.6,a,14) - self.assertEqual(7,b) ; self.assertEqual(8,c) - # - integExpected=34.328125 - self.assertAlmostEqual(fNode.integral(False)[0],integExpected,14) - self.assertAlmostEqual(f.integral(False)[0],integExpected,14) - pass - - def testGauss2Gauss2DValidated(self): - srcFt=MEDCouplingDataForTest.buildFieldOnGauss_1() - trgFt=MEDCouplingDataForTest.buildFieldOnGauss_2() - src=MEDCouplingFieldDouble(srcFt) - self.assertEqual(srcFt.getMesh().getHiddenCppPointer(),src.getMesh().getHiddenCppPointer()) - self.assertEqual(srcFt.getDiscretization().getHiddenCppPointer(),src.getDiscretization().getHiddenCppPointer()) - #values given by ASTER usecase - src.setArray(DataArrayDouble([1.,1.,0.,0.,1.,1.,1.,1.,0.,0.,1.,1.,1.,1.,1.,1.,0.,0.,0.,0.,1.,1.,1.,1.,1.,1.,1.,1.,0.,0.,0.,0.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,0.,0.,0.,0.,0.,0.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,0.,0.,0.,0.,0.,0.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,0.,0.,0.,0.,0.,0.,0.,0.,0.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,0.,0.,0.,0.,0.,0.,0.,0.,0.,1.,1.,1.,1.,1.,1.,1.,1.,1.])) - src.getArray().setInfoOnComponents(["DOMA"]) - rem=MEDCouplingRemapper() - rem.setIntersectionType(PointLocator) - rem.prepareEx(srcFt,trgFt) - trg=rem.transferField(src,1e300) - self.assertEqual(trg.getMesh().getHiddenCppPointer(),trgFt.getMesh().getHiddenCppPointer()) - self.assertEqual(trg.getDiscretization().getHiddenCppPointer(),trgFt.getDiscretization().getHiddenCppPointer()) - #values given after interpolation in ASTER - arrExpected=DataArrayDouble([1.,1.,1.,0.,0.,0.,1.,1.,1.,1.,1.,0.,0.,0.,1.,1.,1.,1.,1.,0.,0.,0.,1.,1.,1.,1.,1.,0.,0.,0.,1.,1.,1.,1.,1.,0.,0.,0.,1.,1.,1.,1.,1.,1.,1.,0.,0.,1.,0.,1.,1.,0.,1.,1.,1.,1.,1.,1.,1.,1.,1.,0.,0.,1.,0.,1.,1.,0.,1.,1.,1.,1.,1.,1.,1.,1.,1.,0.,0.,1.,0.,1.,1.,0.,1.,1.,1.,1.,1.,1.,1.,1.,1.,0.,0.,1.,0.,1.,1.,0.,1.,1.,1.,1.,1.,1.,1.,1.,1.,0.,0.,1.,0.,1.,1.,0.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,0.,1.,0.,0.,0.,0.,1.,1.,1.,0.,0.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,0.,1.,0.,0.,0.,0.,1.,1.,1.,0.,0.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,0.,1.,0.,0.,0.,0.,1.,1.,1.,0.,0.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,0.,1.,0.,0.,0.,0.,1.,1.,1.,0.,0.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,0.,1.,0.,0.,0.,0.,1.,1.,1.,0.,0.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,0.,0.,1.,0.,0.,0.,1.,0.,0.,1.,1.,0.,0.,1.,0.,0.,0.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,0.,0.,1.,0.,0.,0.,1.,0.,0.,1.,1.,0.,0.,1.,0.,0.,0.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,0.,0.,1.,0.,0.,0.,1.,0.,0.,1.,1.,0.,0.,1.,0.,0.,0.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,0.,0.,1.,0.,0.,0.,1.,0.,0.,1.,1.,0.,0.,1.,0.,0.,0.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,0.,0.,1.,0.,0.,0.,1.,0.,0.,1.,1.,0.,0.,1.,0.,0.,0.,1.,1.,1.,1.,1.,1.,1.,1.,1.]) ; arrExpected.setInfoOnComponents(["DOMA"]) - self.assertTrue(trg.getArray().isEqual(arrExpected,1e-12)) - # - # second part of the test : reverse source and target - # - rem.prepareEx(trgFt,srcFt)# sorry trgFt is in the place of source and srcFt in the place of target it is not a bug - trg=MEDCouplingFieldDouble(trgFt) - #values given after interpolation in ASTER - trg.setArray(DataArrayDouble([1.,1.,0.,0.,1.,0.,1.,1.,1.,1.,0.,0.,1.,0.,1.,1.,1.,1.,0.,0.,1.,0.,1.,1.,1.,1.,0.,0.,1.,0.,1.,1.,1.,1.,0.,0.,1.,0.,1.,1.,1.,1.,1.,1.,1.,0.,0.,1.,0.,1.,1.,0.,1.,1.,1.,1.,1.,1.,1.,1.,1.,0.,0.,1.,0.,1.,1.,0.,1.,1.,1.,1.,1.,1.,1.,1.,1.,0.,0.,1.,0.,1.,1.,0.,1.,1.,1.,1.,1.,1.,1.,1.,1.,0.,0.,1.,0.,1.,1.,0.,1.,1.,1.,1.,1.,1.,1.,1.,1.,0.,0.,1.,0.,1.,1.,0.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,0.,1.,0.,0.,0.,0.,1.,1.,0.,0.,0.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,0.,1.,0.,0.,0.,0.,1.,1.,0.,0.,0.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,0.,1.,0.,0.,0.,0.,1.,1.,0.,0.,0.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,0.,1.,0.,0.,0.,0.,1.,1.,0.,0.,0.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,0.,1.,0.,0.,0.,0.,1.,1.,0.,0.,0.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,0.,0.,1.,0.,0.,0.,1.,0.,0.,1.,1.,0.,0.,1.,0.,0.,0.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,0.,0.,1.,0.,0.,0.,1.,0.,0.,1.,1.,0.,0.,1.,0.,0.,0.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,0.,0.,1.,0.,0.,0.,1.,0.,0.,1.,1.,0.,0.,1.,0.,0.,0.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,0.,0.,1.,0.,0.,0.,1.,0.,0.,1.,1.,0.,0.,1.,0.,0.,0.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,0.,0.,1.,0.,0.,0.,1.,0.,0.,1.,1.,0.,0.,1.,0.,0.,0.,1.,1.,1.,1.,1.,1.,1.,1.,1.])) - trg.getArray().setInfoOnComponents(["DOMA"]) - src=rem.transferField(trg,1e300) - #values given after interpolation in ASTER - arrExpected2=DataArrayDouble([1.,1.,0.,0.,1.,1.,1.,1.,0.,0.,1.,1.,1.,1.,1.,1.,0.,0.,0.,0.,1.,1.,1., 1.,1.,1.,1.,1.,0.,0.,0.,0.,0.,1.,1.,1.,1.,1.,1.,1.,1.,1.,0.,0.,0.,0.,0.,0.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,0.,0.,0.,0.,0.,0.,1.,1.,1.,1.,1.,1.,1.,1.,0.,1.,1.,0.,1.,1.,1.,1.,0.,0.,0.,0.,1.,0.,0.,0.,1.,1.,1.,0.,1.,1.,1.,1.,1.,1.,0.,0.,1.,1.,0.,1.,1.,1.,0.,1.,0.,0.,0.,1.,0.,0.,0.,1.,1.,1.,0.,1.,1.,1.,1.,1.]) ; arrExpected2.setInfoOnComponents(["DOMA"]) - # modification of values in ASTER due to modification of algorithm - # target PG 82 in target cell 32(C)/36 PG 1(C)/9 is in source cell 58(C)/120 source Gauss point 113 (1(C)/4). Values must be 1. and not 0. - arrExpected2.setIJ(82,0,1.) - self.assertTrue(src.getArray().isEqual(arrExpected2,1e-12)) - pass - - def testGauss2Gauss3DValidated(self): - srcFt=MEDCouplingDataForTest.buildFieldOnGauss_3() - trgFt=MEDCouplingDataForTest.buildFieldOnGauss_4() - src=MEDCouplingFieldDouble(srcFt) - self.assertEqual(srcFt.getMesh().getHiddenCppPointer(),src.getMesh().getHiddenCppPointer()) - self.assertEqual(srcFt.getDiscretization().getHiddenCppPointer(),src.getDiscretization().getHiddenCppPointer()) - #values given by ASTER usecase - src.setArray(DataArrayDouble([0.,1.,1.,1.,1.,1.,0.,0.,0.,0.,0.,0.,0.,0.,0.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,0.,0.,0.,0.,0.,1.,1.,0.,0.,1.,1.,1.,1.,0.,0.,1.,1.,0.,0.])) - src.getArray().setInfoOnComponents(["DOMA"]) - rem=MEDCouplingRemapper() - rem.setIntersectionType(PointLocator) - rem.prepareEx(srcFt,trgFt) - trg=rem.transferField(src,1e300) - self.assertEqual(trg.getMesh().getHiddenCppPointer(),trgFt.getMesh().getHiddenCppPointer()) - self.assertEqual(trg.getDiscretization().getHiddenCppPointer(),trgFt.getDiscretization().getHiddenCppPointer()) - #values given after interpolation in ASTER - arrExpected=DataArrayDouble([0.,1.,1.,1.,1.,1.,0.,0.,0.,0.,0.,0.,0.,0.,0.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,0.,1.,0.,0.,0.,1.,1.,0.,0.,1.,1.,1.,1.,0.,1.,1.,1.,0.,1.]) ; arrExpected.setInfoOnComponents(["DOMA"]) - self.assertTrue(trg.getArray().isEqual(arrExpected,1e-12)) - # - # second part of the test : reverse source and target - # - rem.prepareEx(trgFt,srcFt)# sorry trgFt is in the place of source and srcFt in the place of target it is not a bug - trg=MEDCouplingFieldDouble(trgFt) - #values given after interpolation in ASTER - trg.setArray(DataArrayDouble([0.,1.,1.,1.,1.,1.,0.,0.,0.,0.,0.,0.,0.,0.,0.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,0.,0.,1.,1.,0.,0.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.])) - trg.getArray().setInfoOnComponents(["DOMA"]) - src=rem.transferField(trg,1e300) - #values given after interpolation in ASTER - arrExpected2=DataArrayDouble([0.,1.,1.,1.,1.,1.,0.,0.,0.,0.,0.,0.,0.,0.,0.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,0.,1.,0.,1.,0.,1.,1.,1.,0.,1.,1.,1.,1.,0.,1.,1.,1.,0.,1.]) ; arrExpected2.setInfoOnComponents(["DOMA"]) - self.assertTrue(src.getArray().isEqual(arrExpected2,1e-12)) - pass - - def testSwig2MixOfUMesh(self): - arr0=DataArrayDouble([0,1,1.5]) ; arr1=DataArrayDouble([0,1]) - sc=MEDCouplingCMesh() ; sc.setCoords(arr0,arr1,arr1) - tc=sc.deepCpy() ; tc.translate([0.4,0.3,0.3]) - # umesh-umesh - # 90 (umesh-1sgtumesh) - rem=MEDCouplingRemapper() ; rem.setIntersectionType(Triangulation) - s=sc.buildUnstructured() ; t=tc.build1SGTUnstructured() - self.assertTrue(isinstance(s,MEDCouplingUMesh)) - self.assertTrue(isinstance(t,MEDCoupling1SGTUMesh)) - rem.prepare(s,t,"P0P0") - mat=rem.getCrudeMatrix() - self.assertEqual(2,len(mat)) ; self.assertEqual(2,len(mat[0])) ; self.assertEqual(1,len(mat[1])) - self.assertAlmostEqual(0.294,mat[0][0],14) ; self.assertAlmostEqual(0.196,mat[0][1],14) ; self.assertAlmostEqual(0.049,mat[1][1],14) - del s,t - # 91 (umesh-1dgtumesh) - rem=MEDCouplingRemapper() ; rem.setIntersectionType(Triangulation) - s=sc.buildUnstructured() ; t=tc.buildUnstructured() ; t.convertAllToPoly() ; t=MEDCoupling1DGTUMesh(t) - self.assertTrue(isinstance(s,MEDCouplingUMesh)) - self.assertTrue(isinstance(t,MEDCoupling1DGTUMesh)) - rem.prepare(s,t,"P0P0") - mat=rem.getCrudeMatrix() - self.assertEqual(2,len(mat)) ; self.assertEqual(2,len(mat[0])) ; self.assertEqual(1,len(mat[1])) - self.assertAlmostEqual(0.294,mat[0][0],14) ; self.assertAlmostEqual(0.196,mat[0][1],14) ; self.assertAlmostEqual(0.049,mat[1][1],14) - del s,t - # 165 (1sgtumesh-umesh) - rem=MEDCouplingRemapper() ; rem.setIntersectionType(Triangulation) - s=sc.build1SGTUnstructured() ; t=tc.buildUnstructured() - self.assertTrue(isinstance(s,MEDCoupling1SGTUMesh)) - self.assertTrue(isinstance(t,MEDCouplingUMesh)) - rem.prepare(s,t,"P0P0") - mat=rem.getCrudeMatrix() - self.assertEqual(2,len(mat)) ; self.assertEqual(2,len(mat[0])) ; self.assertEqual(1,len(mat[1])) - self.assertAlmostEqual(0.294,mat[0][0],14) ; self.assertAlmostEqual(0.196,mat[0][1],14) ; self.assertAlmostEqual(0.049,mat[1][1],14) - del s,t - # 181 (1dgtumesh-umesh - rem=MEDCouplingRemapper() ; rem.setIntersectionType(Triangulation) - s=sc.buildUnstructured() ; s.convertAllToPoly() ; s=MEDCoupling1DGTUMesh(s) ; t=tc.buildUnstructured() - self.assertTrue(isinstance(s,MEDCoupling1DGTUMesh)) - self.assertTrue(isinstance(t,MEDCouplingUMesh)) - rem.prepare(s,t,"P0P0") - mat=rem.getCrudeMatrix() - self.assertEqual(2,len(mat)) ; self.assertEqual(2,len(mat[0])) ; self.assertEqual(1,len(mat[1])) - self.assertAlmostEqual(0.294,mat[0][0],14) ; self.assertAlmostEqual(0.196,mat[0][1],14) ; self.assertAlmostEqual(0.049,mat[1][1],14) - del s,t - # 170 (1sgtumesh-1sgtumesh) - rem=MEDCouplingRemapper() ; rem.setIntersectionType(Triangulation) - s=sc.build1SGTUnstructured() ; t=tc.build1SGTUnstructured() - self.assertTrue(isinstance(s,MEDCoupling1SGTUMesh)) - self.assertTrue(isinstance(t,MEDCoupling1SGTUMesh)) - rem.prepare(s,t,"P0P0") - mat=rem.getCrudeMatrix() - self.assertEqual(2,len(mat)) ; self.assertEqual(2,len(mat[0])) ; self.assertEqual(1,len(mat[1])) - self.assertAlmostEqual(0.294,mat[0][0],14) ; self.assertAlmostEqual(0.196,mat[0][1],14) ; self.assertAlmostEqual(0.049,mat[1][1],14) - del s,t - # 171 (1sgtumesh-1dgtumesh) - rem=MEDCouplingRemapper() ; rem.setIntersectionType(Triangulation) - s=sc.build1SGTUnstructured() ; t=tc.buildUnstructured() ; t.convertAllToPoly() ; t=MEDCoupling1DGTUMesh(t) - self.assertTrue(isinstance(s,MEDCoupling1SGTUMesh)) - self.assertTrue(isinstance(t,MEDCoupling1DGTUMesh)) - rem.prepare(s,t,"P0P0") - mat=rem.getCrudeMatrix() - self.assertEqual(2,len(mat)) ; self.assertEqual(2,len(mat[0])) ; self.assertEqual(1,len(mat[1])) - self.assertAlmostEqual(0.294,mat[0][0],14) ; self.assertAlmostEqual(0.196,mat[0][1],14) ; self.assertAlmostEqual(0.049,mat[1][1],14) - del s,t - # 186 (1dgtumesh-1sgtumesh) - rem=MEDCouplingRemapper() ; rem.setIntersectionType(Triangulation) - s=sc.buildUnstructured() ; s.convertAllToPoly() ; s=MEDCoupling1DGTUMesh(s) ; t=tc.build1SGTUnstructured() - self.assertTrue(isinstance(s,MEDCoupling1DGTUMesh)) - self.assertTrue(isinstance(t,MEDCoupling1SGTUMesh)) - rem.prepare(s,t,"P0P0") - mat=rem.getCrudeMatrix() - self.assertEqual(2,len(mat)) ; self.assertEqual(2,len(mat[0])) ; self.assertEqual(1,len(mat[1])) - self.assertAlmostEqual(0.294,mat[0][0],14) ; self.assertAlmostEqual(0.196,mat[0][1],14) ; self.assertAlmostEqual(0.049,mat[1][1],14) - del s,t - # 187 (1dgtumesh-1dgtumesh) - rem=MEDCouplingRemapper() ; rem.setIntersectionType(Triangulation) - s=sc.buildUnstructured() ; s.convertAllToPoly() ; s=MEDCoupling1DGTUMesh(s) ; t=tc.buildUnstructured() ; t.convertAllToPoly() ; t=MEDCoupling1DGTUMesh(t) - self.assertTrue(isinstance(s,MEDCoupling1DGTUMesh)) - self.assertTrue(isinstance(t,MEDCoupling1DGTUMesh)) - rem.prepare(s,t,"P0P0") - mat=rem.getCrudeMatrix() - self.assertEqual(2,len(mat)) ; self.assertEqual(2,len(mat[0])) ; self.assertEqual(1,len(mat[1])) - self.assertAlmostEqual(0.294,mat[0][0],14) ; self.assertAlmostEqual(0.196,mat[0][1],14) ; self.assertAlmostEqual(0.049,mat[1][1],14) - del s,t - # (umesh-cmesh) - # 167 (1sgtumesh-cmesh) - rem=MEDCouplingRemapper() ; rem.setIntersectionType(Triangulation) - s=sc.build1SGTUnstructured() ; t=tc.deepCpy() - self.assertTrue(isinstance(s,MEDCoupling1SGTUMesh)) - self.assertTrue(isinstance(t,MEDCouplingCMesh)) - rem.prepare(s,t,"P0P0") - mat=rem.getCrudeMatrix() - self.assertEqual(2,len(mat)) ; self.assertEqual(2,len(mat[0])) ; self.assertEqual(1,len(mat[1])) - self.assertAlmostEqual(0.294,mat[0][0],14) ; self.assertAlmostEqual(0.196,mat[0][1],14) ; self.assertAlmostEqual(0.049,mat[1][1],14) - del s,t - # 183 (1dgtumesh-cmesh) - #rem=MEDCouplingRemapper() ; rem.setIntersectionType(Triangulation) - #s=sc.buildUnstructured() ; s.convertAllToPoly() ; s=MEDCoupling1DGTUMesh(s) ; t=tc.deepCpy() - #self.assertTrue(isinstance(s,MEDCoupling1DGTUMesh)) - #self.assertTrue(isinstance(t,MEDCouplingCMesh)) - #rem.prepare(s,t,"P0P0") - #mat=rem.getCrudeMatrix() - #self.assertEqual(2,len(mat)) ; self.assertEqual(2,len(mat[0])) ; self.assertEqual(1,len(mat[1])) - #self.assertAlmostEqual(0.294,mat[0][0],14) ; self.assertAlmostEqual(0.196,mat[0][1],14) ; self.assertAlmostEqual(0.049,mat[1][1],14) - #del s,t - # (cmesh-umesh) - # 122 (cmesh-1sgtumesh) - rem=MEDCouplingRemapper() ; rem.setIntersectionType(Triangulation) - s=sc.deepCpy() ; t=tc.build1SGTUnstructured() - self.assertTrue(isinstance(s,MEDCouplingCMesh)) - self.assertTrue(isinstance(t,MEDCoupling1SGTUMesh)) - rem.prepare(s,t,"P0P0") - mat=rem.getCrudeMatrix() - self.assertEqual(2,len(mat)) ; self.assertEqual(2,len(mat[0])) ; self.assertEqual(1,len(mat[1])) - self.assertAlmostEqual(0.294,mat[0][0],14) ; self.assertAlmostEqual(0.196,mat[0][1],14) ; self.assertAlmostEqual(0.049,mat[1][1],14) - del s,t - # 123 (cmesh-1dgtumesh) - #rem=MEDCouplingRemapper() ; rem.setIntersectionType(Triangulation) - #s=sc.deepCpy() ; t=tc.buildUnstructured() ; t.convertAllToPoly() ; t=MEDCoupling1DGTUMesh(t) - #self.assertTrue(isinstance(s,MEDCouplingCMesh)) - #self.assertTrue(isinstance(t,MEDCoupling1DGTUMesh)) - #rem.prepare(s,t,"P0P0") - #mat=rem.getCrudeMatrix() - #self.assertEqual(2,len(mat)) ; self.assertEqual(2,len(mat[0])) ; self.assertEqual(1,len(mat[1])) - #self.assertAlmostEqual(0.294,mat[0][0],14) ; self.assertAlmostEqual(0.196,mat[0][1],14) ; self.assertAlmostEqual(0.049,mat[1][1],14) - #del s,t - pass - - def testSwig2BarycentricP1P13D_1(self): - sCoo=DataArrayDouble([0.313,0.00218,6.90489,0.313,0.10692667,6.90489,0.313,0.10692667,6.96790167,0.313,0.00218,6.9773125,0.313,0.21167333,6.90489,0.313,0.21167333,6.95849083,0.313,0.31642,6.90489,0.313,0.31642,6.94908,0.313,0.09383333,7.04891667,0.313,0.00218,7.049735,0.313,0.18548667,7.04809833,0.313,0.27714,7.04728,0.313,0.05782667,7.133205,0.313,0.00218,7.1221575,0.313,0.11347333,7.1442525,0.313,0.16912,7.1553,0.313,0.02509333,7.19458,0.313,0.00218,7.19458,0.313,0.04800667,7.19458,0.313,0.07092,7.19458,0.31005609,0.00218,6.90460005,0.31005609,0.10692667,6.90460005,0.29776312,0.10692667,6.96640097,0.29592716,0.00218,6.97563097,0.31005609,0.21167333,6.90460005,0.29959908,0.21167333,6.95717096,0.31005609,0.31642,6.90460005,0.30143505,0.31642,6.94794095,0.28195788,0.09383333,7.04585928,0.28179823,0.00218,7.04666189,0.28211753,0.18548667,7.04505668,0.28227718,0.27714,7.04425407,0.26551404,0.05782667,7.12852804,0.2676693,0.00218,7.11769282,0.26335878,0.11347333,7.13936327,0.26120352,0.16912,7.15019849,0.25354037,0.02509333,7.18872374,0.25354037,0.00218,7.18872374,0.25354037,0.04800667,7.18872374,0.25354037,0.07092,7.18872374,0.30722531,0.00218,6.90374134,0.30722531,0.10692667,6.90374134,0.28311179,0.10692667,6.96195653,0.27951042,0.00218,6.97065101,0.30722531,0.21167333,6.90374134,0.28671316,0.21167333,6.95326205,0.30722531,0.31642,6.90374134,0.29031453,0.31642,6.94456758,0.25210869,0.09383333,7.03680463,0.25179553,0.00218,7.03756067,0.25242185,0.18548667,7.03604859,0.25273501,0.27714,7.03529255,0.21985294,0.05782667,7.1146769,0.22408063,0.00218,7.10447034,0.21562524,0.11347333,7.12488346,0.21139755,0.16912,7.13509002,0.19636574,0.02509333,7.17138,0.19636574,0.00218,7.17138,0.19636574,0.04800667,7.17138,0.19636574,0.07092,7.17138,0.30461645,0.00218,6.90234688,0.30461645,0.10692667,6.90234688,0.26960904,0.10692667,6.95473916,0.26438066,0.00218,6.96256398,0.30461645,0.21167333,6.90234688,0.27483742,0.21167333,6.94691434,0.30461645,0.31642,6.90234688,0.2800658,0.31642,6.93908952,0.22459952,0.09383333,7.02210067,0.22414487,0.00218,7.02278109,0.22505416,0.18548667,7.02142025,0.2255088,0.27714,7.02073983,0.17777143,0.05782667,7.09218386,0.18390909,0.00218,7.0829982,0.17163377,0.11347333,7.10136952,0.1654961,0.16912,7.11055518,0.1436733,0.02509333,7.14321531,0.1436733,0.00218,7.14321531,0.1436733,0.04800667,7.14321531,0.1436733,0.07092,7.14321531,0.30232976,0.00218,6.90047024,0.30232976,0.10692667,6.90047024,0.25777378,0.10692667,6.94502622,0.25111932,0.00218,6.95168068,0.30232976,0.21167333,6.90047024,0.26442825,0.21167333,6.93837175,0.30232976,0.31642,6.90047024,0.27108271,0.31642,6.93171729,0.20048753,0.09383333,7.00231247,0.19990888,0.00218,7.00289112,0.20106618,0.18548667,7.00173382,0.20164482,0.27714,7.00115518,0.14088667,0.05782667,7.06191333,0.14869844,0.00218,7.05410156,0.13307491,0.11347333,7.06972509,0.12526315,0.16912,7.07753685,0.097488,0.02509333,7.105312,0.097488,0.00218,7.105312,0.097488,0.04800667,7.105312,0.097488,0.07092,7.105312,0.30045312,0.00218,6.89818355,0.30045312,0.10692667,6.89818355,0.24806084,0.10692667,6.93319096,0.24023602,0.00218,6.93841934,0.30045312,0.21167333,6.89818355,0.25588566,0.21167333,6.92796258,0.30045312,0.31642,6.89818355,0.26371048,0.31642,6.9227342,0.18069933,0.09383333,6.97820048,0.18001891,0.00218,6.97865513,0.18137975,0.18548667,6.97774584,0.18206017,0.27714,6.9772912,0.11061614,0.05782667,7.02502857,0.1198018,0.00218,7.01889091,0.10143048,0.11347333,7.03116623,0.09224482,0.16912,7.0373039,0.05958469,0.02509333,7.0591267,0.05958469,0.00218,7.0591267,0.05958469,0.04800667,7.0591267,0.05958469,0.07092,7.0591267,0.29905866,0.00218,6.89557469,0.29905866,0.10692667,6.89557469,0.24084347,0.10692667,6.91968821,0.23214899,0.00218,6.92328958,0.29905866,0.21167333,6.89557469,0.24953795,0.21167333,6.91608684,0.29905866,0.31642,6.89557469,0.25823242,0.31642,6.91248547,0.16599537,0.09383333,6.95069131,0.16523933,0.00218,6.95100447,0.16675141,0.18548667,6.95037815,0.16750745,0.27714,6.95006499,0.0881231,0.05782667,6.98294706,0.09832966,0.00218,6.97871937,0.07791654,0.11347333,6.98717476,0.06770998,0.16912,6.99140245,0.03142,0.02509333,7.00643426,0.03142,0.00218,7.00643426,0.03142,0.04800667,7.00643426,0.03142,0.07092,7.00643426,0.29819995,0.00218,6.89274391,0.29819995,0.10692667,6.89274391,0.23639903,0.10692667,6.90503688,0.22716903,0.00218,6.90687284,0.29819995,0.21167333,6.89274391,0.24562904,0.21167333,6.90320092,0.29819995,0.31642,6.89274391,0.25485905,0.31642,6.90136495,0.15694072,0.09383333,6.92084212,0.15613811,0.00218,6.92100177,0.15774332,0.18548667,6.92068247,0.15854593,0.27714,6.92052282,0.07427196,0.05782667,6.93728596,0.08510718,0.00218,6.9351307,0.06343673,0.11347333,6.93944122,0.05260151,0.16912,6.94159648,0.01407626,0.02509333,6.94925963,0.01407626,0.00218,6.94925963,0.01407626,0.04800667,6.94925963,0.01407626,0.07092,6.94925963,0.29792818,0.00218,6.89054043,0.29792818,0.10692667,6.89054043,0.23499241,0.10692667,6.89363227,0.22559291,0.00218,6.89409403,0.29792818,0.21167333,6.89054043,0.24439191,0.21167333,6.8931705,0.29792818,0.31642,6.89054043,0.25379141,0.31642,6.89270873,0.154075,0.09383333,6.89760748,0.15325765,0.00218,6.89764764,0.15489234,0.18548667,6.89756733,0.15570969,0.27714,6.89752718,0.06988819,0.05782667,6.90174332,0.08092238,0.00218,6.90120124,0.058854,0.11347333,6.90228539,0.04781981,0.16912,6.90282747,0.00858712,0.02509333,6.90475485,0.00858712,0.00218,6.90475485,0.00858712,0.04800667,6.90475485,0.00858712,0.07092,6.90475485,0.29791,0.00218,6.820902,0.29791,0.10692667,6.820902,0.23489833,0.10692667,6.820902,0.2254875,0.00218,6.820902,0.29791,0.21167333,6.820902,0.24430917,0.21167333,6.820902,0.29791,0.31642,6.820902,0.25372,0.31642,6.820902,0.15388333,0.09383333,6.820902,0.153065,0.00218,6.820902,0.15470167,0.18548667,6.820902,0.15552,0.27714,6.820902,0.069595,0.05782667,6.820902,0.0806425,0.00218,6.820902,0.0585475,0.11347333,6.820902,0.0475,0.16912,6.820902,0.00822,0.02509333,6.820902,0.00822,0.00218,6.820902,0.00822,0.04800667,6.820902,0.00822,0.07092,6.820902],200,3) - sConn=DataArrayInt([0,1,2,3,20,21,22,23,1,4,5,2,21,24,25,22,4,6,7,5,24,26,27,25,3,2,8,9,23,22,28,29,2,5,10,8,22,25,30,28,5,7,11,10,25,27,31,30,9,8,12,13,29,28,32,33,8,10,14,12,28,30,34,32,10,11,15,14,30,31,35,34,13,12,16,17,33,32,36,37,12,14,18,16,32,34,38,36,14,15,19,18,34,35,39,38,20,21,22,23,40,41,42,43,21,24,25,22,41,44,45,42,24,26,27,25,44,46,47,45,23,22,28,29,43,42,48,49,22,25,30,28,42,45,50,48,25,27,31,30,45,47,51,50,29,28,32,33,49,48,52,53,28,30,34,32,48,50,54,52,30,31,35,34,50,51,55,54,33,32,36,37,53,52,56,57,32,34,38,36,52,54,58,56,34,35,39,38,54,55,59,58,40,41,42,43,60,61,62,63,41,44,45,42,61,64,65,62,44,46,47,45,64,66,67,65,43,42,48,49,63,62,68,69,42,45,50,48,62,65,70,68,45,47,51,50,65,67,71,70,49,48,52,53,69,68,72,73,48,50,54,52,68,70,74,72,50,51,55,54,70,71,75,74,53,52,56,57,73,72,76,77,52,54,58,56,72,74,78,76,54,55,59,58,74,75,79,78,60,61,62,63,80,81,82,83,61,64,65,62,81,84,85,82,64,66,67,65,84,86,87,85,63,62,68,69,83,82,88,89,62,65,70,68,82,85,90,88,65,67,71,70,85,87,91,90,69,68,72,73,89,88,92,93,68,70,74,72,88,90,94,92,70,71,75,74,90,91,95,94,73,72,76,77,93,92,96,97,72,74,78,76,92,94,98,96,74,75,79,78,94,95,99,98,80,81,82,83,100,101,102,103,81,84,85,82,101,104,105,102,84,86,87,85,104,106,107,105,83,82,88,89,103,102,108,109,82,85,90,88,102,105,110,108,85,87,91,90,105,107,111,110,89,88,92,93,109,108,112,113,88,90,94,92,108,110,114,112,90,91,95,94,110,111,115,114,93,92,96,97,113,112,116,117,92,94,98,96,112,114,118,116,94,95,99,98,114,115,119,118,100,101,102,103,120,121,122,123,101,104,105,102,121,124,125,122,104,106,107,105,124,126,127,125,103,102,108,109,123,122,128,129,102,105,110,108,122,125,130,128,105,107,111,110,125,127,131,130,109,108,112,113,129,128,132,133,108,110,114,112,128,130,134,132,110,111,115,114,130,131,135,134,113,112,116,117,133,132,136,137,112,114,118,116,132,134,138,136,114,115,119,118,134,135,139,138,120,121,122,123,140,141,142,143,121,124,125,122,141,144,145,142,124,126,127,125,144,146,147,145,123,122,128,129,143,142,148,149,122,125,130,128,142,145,150,148,125,127,131,130,145,147,151,150,129,128,132,133,149,148,152,153,128,130,134,132,148,150,154,152,130,131,135,134,150,151,155,154,133,132,136,137,153,152,156,157,132,134,138,136,152,154,158,156,134,135,139,138,154,155,159,158,140,141,142,143,160,161,162,163,141,144,145,142,161,164,165,162,144,146,147,145,164,166,167,165,143,142,148,149,163,162,168,169,142,145,150,148,162,165,170,168,145,147,151,150,165,167,171,170,149,148,152,153,169,168,172,173,148,150,154,152,168,170,174,172,150,151,155,154,170,171,175,174,153,152,156,157,173,172,176,177,152,154,158,156,172,174,178,176,154,155,159,158,174,175,179,178,160,161,162,163,180,181,182,183,161,164,165,162,181,184,185,182,164,166,167,165,184,186,187,185,163,162,168,169,183,182,188,189,162,165,170,168,182,185,190,188,165,167,171,170,185,187,191,190,169,168,172,173,189,188,192,193,168,170,174,172,188,190,194,192,170,171,175,174,190,191,195,194,173,172,176,177,193,192,196,197,172,174,178,176,192,194,198,196,174,175,179,178,194,195,199,198]) - s=MEDCoupling1SGTUMesh("target",NORM_HEXA8) ; s.setCoords(sCoo) - s.setNodalConnectivity(sConn) - # - tCoo=DataArrayDouble([0.328,0.012,6.8598,0.328,0.168320184237353,6.8598,0.328,0.324640368474706,6.8598,0.328,0.0,6.8598,0.298,0.012,6.8598,0.1565,0.012,6.8598,0.180205346493166,0.144794653506834,6.8598,0.298,0.168320184237353,6.8598,0.0,0.012,6.8598,0.0916755774886107,0.233324422511389,6.8598,0.298,0.324640368474706,6.8598,0.298,0.0,6.8598,0.1565,0.0,6.8598,0.0,0.0,6.8598,0.328,0.012,7.2298,0.328,0.168320184237353,7.2298,0.328,0.324640368474706,7.2298,0.328,0.0,7.2298,0.298,0.012,7.2298,0.1565,0.012,7.2298,0.180205346493166,0.144794653506834,7.2298,0.298,0.168320184237353,7.2298,0.0,0.012,7.2298,0.0916755774886107,0.233324422511389,7.2298,0.298,0.324640368474706,7.2298,0.298,0.0,7.2298,0.1565,0.0,7.2298,0.0,0.0,7.2298],28,3) - tConn=DataArrayInt([4,5,6,7,18,19,20,21,5,8,9,6,19,22,23,20,6,9,10,7,20,23,24,21,11,12,5,4,25,26,19,18,12,13,8,5,26,27,22,19,3,11,4,0,17,25,18,14,0,4,7,1,14,18,21,15,1,7,10,2,15,21,24,16]) - t=MEDCoupling1SGTUMesh("target",NORM_HEXA8) ; t.setCoords(tCoo) - t.setNodalConnectivity(tConn) - # - s.simplexize(PLANAR_FACE_5) - aRemapper=MEDCouplingRemapper() - aRemapper.setPrecision(1e-12) - aRemapper.setIntersectionType(Barycentric) - self.assertEqual(aRemapper.prepare(s,t,'P1P1'),1) - m=aRemapper.getCrudeMatrix() - self.assertEqual(len(m),28) - for i in xrange(28): - if i not in [5,6]: - self.assertEqual(len(m[i]),0) - pass - pass - self.assertEqual(len(m[5]),4) - self.assertEqual(len(m[6]),4) - self.assertAlmostEqual(0.10714286103952797,m[5][168],12) - self.assertAlmostEqual(0.35691534416938014,m[5][169],12) - self.assertAlmostEqual(0.04492099619713096,m[5][163],12) - self.assertAlmostEqual(0.49102079859396097,m[5][189],12) - self.assertAlmostEqual(0.14039089397104254,m[6][185],12) - self.assertAlmostEqual(0.16362822318261033,m[6][162],12) - self.assertAlmostEqual(0.3438363717836785 ,m[6][188],12) - self.assertAlmostEqual(0.3521445110626687 ,m[6][170],12) - pass - - @unittest.skipUnless(MEDCouplingHasNumPyBindings() and MEDCouplingHasSciPyBindings(),"requires numpy AND scipy") - def testGetCrudeCSRMatrix1(self): - """ testing CSR matrix output using numpy/scipy. - """ - from scipy.sparse import spdiags #diags - import scipy - from numpy import array - arr=DataArrayDouble(3) ; arr.iota() - m=MEDCouplingCMesh() ; m.setCoords(arr,arr) - src=m.buildUnstructured() - trg=src.deepCpy() ; trg=trg[[0,1,3]] - trg.getCoords()[:]*=0.5 ; trg.getCoords()[:]+=[0.3,0.25] - # Let's interpolate. - rem=MEDCouplingRemapper() - rem.prepare(src,trg,"P0P0") - # Internal crude sparse matrix computed. Let's manipulate it using CSR matrix in scipy. - for i in xrange(10): - m=rem.getCrudeCSRMatrix() - pass - m2=rem.getCrudeCSRMatrix() - diff=m-m2 - self.assertTrue(isinstance(m,scipy.sparse.csr.csr_matrix)) - self.assertEqual(m.getnnz(),7) - self.assertAlmostEqual(m[0,0],0.25,12) - self.assertAlmostEqual(m[1,0],0.1,12) - self.assertAlmostEqual(m[1,1],0.15,12) - self.assertAlmostEqual(m[2,0],0.05,12) - self.assertAlmostEqual(m[2,1],0.075,12) - self.assertAlmostEqual(m[2,2],0.05,12) - self.assertAlmostEqual(m[2,3],0.075,12) - self.assertEqual(diff.getnnz(),0) - # IntegralGlobConstraint (division by sum of cols) - colSum=m.sum(axis=0) - # version 0.12.0 # m_0=m*diags(array(1/colSum),[0]) - m_0=m*spdiags(array(1/colSum),[0],colSum.shape[1],colSum.shape[1]) - del colSum - self.assertAlmostEqual(m_0[0,0],0.625,12) - self.assertAlmostEqual(m_0[1,0],0.25,12) - self.assertAlmostEqual(m_0[1,1],0.6666666666666667,12) - self.assertAlmostEqual(m_0[2,0],0.125,12) - self.assertAlmostEqual(m_0[2,1],0.3333333333333333,12) - self.assertAlmostEqual(m_0[2,2],1.,12) - self.assertAlmostEqual(m_0[2,3],1.,12) - self.assertEqual(m_0.getnnz(),7) - # ConservativeVolumic (division by sum of rows) - rowSum=m.sum(axis=1) - # version 0.12.0 # m_1=diags(array(1/rowSum.transpose()),[0])*m - m_1=spdiags(array(1/rowSum.transpose()),[0],rowSum.shape[0],rowSum.shape[0])*m - del rowSum - self.assertAlmostEqual(m_1[0,0],1.,12) - self.assertAlmostEqual(m_1[1,0],0.4,12) - self.assertAlmostEqual(m_1[1,1],0.6,12) - self.assertAlmostEqual(m_1[2,0],0.2,12) - self.assertAlmostEqual(m_1[2,1],0.3,12) - self.assertAlmostEqual(m_1[2,2],0.2,12) - self.assertAlmostEqual(m_1[2,3],0.3,12) - self.assertEqual(m_1.getnnz(),7) - pass - - @unittest.skipUnless(MEDCouplingHasNumPyBindings() and MEDCouplingHasSciPyBindings(),"requires numpy AND scipy") - def testP0P1Bary_1(self): - a=MEDCouplingUMesh("a",2) - a.allocateCells() - conna=[0,1,3,2,1,4,5,3,4,6,7,5,6,8,9,7,8,10,11,9,10,12,13,11,12,14,15,13,14,16,17,15,16,18,19,17,18,20,21,19,20,22,23,21,22,24,25,23,24,26,27,25] - a.setCoords(DataArrayDouble([1.54,0,-0.01,1.54,0.02,-0.01,1.54,0,0.01,1.54,0.02,0.01,1.54,0.04,-0.01,1.54,0.04,0.01,1.54,0.06,-0.01,1.54,0.06,0.01,1.54,0.08,-0.01,1.54,0.08,0.01,1.54,0.1,-0.01,1.54,0.1,0.01,1.54,0.12,-0.01,1.54,0.12,0.01,1.54,0.14,-0.01,1.54,0.14,0.01,1.54,0.16,-0.01,1.54,0.16,0.01,1.54,0.18,-0.01,1.54,0.18,0.01,1.54,0.2,-0.01,1.54,0.2,0.01,1.54,0.22,-0.01,1.54,0.22,0.01,1.54,0.24,-0.01,1.54,0.24,0.01,1.54,0.26,-0.01,1.54,0.26,0.01],28,3)) - for i in xrange(13): - a.insertNextCell(NORM_QUAD4,conna[4*i:4*(i+1)]) - pass - a.finishInsertingCells() ; a.simplexize(0) - # - connb=[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,0,2,39,3,5,40,6,8,41,9,11,42,12,14,43,15,17,44,18,20,45,21,23,46,24,26,47,27,29,48,30,32,49,33,35,50,36,38,51,52,2,39,53,5,40,54,8,41,55,11,42,56,14,43,57,17,44,58,20,45,59,23,46,60,26,47,61,29,48,62,32,49,63,35,50,64,38,51,52,2,65,53,5,66,54,8,67,55,11,68,56,14,69,57,17,70,58,20,71,59,23,72,60,26,73,61,29,74,62,32,75,63,35,76,64,38,77,53,2,65,54,5,66,55,8,67,56,11,68,57,14,69,58,17,70,59,20,71,60,23,72,61,26,73,62,29,74,63,32,75,64,35,76,78,38,77,53,2,40,54,5,41,55,8,42,56,11,43,57,14,44,58,17,45,59,20,46,60,23,47,61,26,48,62,29,49,63,32,50,64,35,51,78,38,79,3,2,40,6,5,41,9,8,42,12,11,43,15,14,44,18,17,45,21,20,46,24,23,47,27,26,48,30,29,49,33,32,50,36,35,51,80,38,79,3,2,1,6,5,4,9,8,7,12,11,10,15,14,13,18,17,16,21,20,19,24,23,22,27,26,25,30,29,28,33,32,31,36,35,34,80,38,37] - b=MEDCouplingUMesh("b",2) - b.allocateCells() - for i in xrange(104): - b.insertNextCell(NORM_TRI3,connb[3*i:3*(i+1)]) - pass - b.setCoords(DataArrayDouble([1.54,0,-0.01,1.54,0.01,-0.01,1.54,0.01,0,1.54,0.02,-0.01,1.54,0.03,-0.01,1.54,0.03,0,1.54,0.04,-0.01,1.54,0.05,-0.01,1.54,0.05,0,1.54,0.06,-0.01,1.54,0.07,-0.01,1.54,0.07,0,1.54,0.08,-0.01,1.54,0.09,-0.01,1.54,0.09,0,1.54,0.1,-0.01,1.54,0.11,-0.01,1.54,0.11,0,1.54,0.12,-0.01,1.54,0.13,-0.01,1.54,0.13,0,1.54,0.14,-0.01,1.54,0.15,-0.01,1.54,0.15,0,1.54,0.16,-0.01,1.54,0.17,-0.01,1.54,0.17,0,1.54,0.18,-0.01,1.54,0.19,-0.01,1.54,0.19,0,1.54,0.2,-0.01,1.54,0.21,-0.01,1.54,0.21,0,1.54,0.22,-0.01,1.54,0.23,-0.01,1.54,0.23,0,1.54,0.24,-0.01,1.54,0.25,-0.01,1.54,0.25,0,1.54,0,0,1.54,0.02,0,1.54,0.04,0,1.54,0.06,0,1.54,0.08,0,1.54,0.1,0,1.54,0.12,0,1.54,0.14,0,1.54,0.16,0,1.54,0.18,0,1.54,0.2,0,1.54,0.22,0,1.54,0.24,0,1.54,0,0.01,1.54,0.02,0.01,1.54,0.04,0.01,1.54,0.06,0.01,1.54,0.08,0.01,1.54,0.1,0.01,1.54,0.12,0.01,1.54,0.14,0.01,1.54,0.16,0.01,1.54,0.18,0.01,1.54,0.2,0.01,1.54,0.22,0.01,1.54,0.24,0.01,1.54,0.01,0.01,1.54,0.03,0.01,1.54,0.05,0.01,1.54,0.07,0.01,1.54,0.09,0.01,1.54,0.11,0.01,1.54,0.13,0.01,1.54,0.15,0.01,1.54,0.17,0.01,1.54,0.19,0.01,1.54,0.21,0.01,1.54,0.23,0.01,1.54,0.25,0.01,1.54,0.26,0.01,1.54,0.26,0,1.54,0.26,-0.01],81,3)) - # - rem=MEDCouplingRemapper() ; rem.setIntersectionType(Barycentric) - rem.prepare(a,b,"P1P0") - m0=rem.getCrudeCSRMatrix() - self.assertEqual(m0.nnz,312) - # - ids=4*[None] ; vs=4*[None] - ids[0]=DataArrayInt([0,3,6,9,12,15,18,21,24,27,30,33,36,39,42,45,48,51,54,57,60,63,66,69,72,75,158,161,164,167,170,173,176,179,182,185,188,191,194,197,200,203,206,209,212,215,218,221,224,227,230,233]) ; vs[0]=10./3. - ids[1]=DataArrayInt([1,2,4,5,7,8,10,11,13,14,16,17,19,20,22,23,25,26,28,29,31,32,34,35,37,38,40,41,43,44,46,47,49,50,52,53,55,56,58,59,61,62,64,65,67,68,70,71,73,74,76,77,80,83,86,89,92,95,98,101,104,107,110,113,116,117,120,123,126,129,132,135,138,141,144,147,150,153,156,157,159,160,162,163,165,166,168,169,171,172,174,175,177,178,180,181,183,184,186,187,189,190,192,193,195,196,198,199,201,202,204,205,207,208,210,211,213,214,216,217,219,220,222,223,225,226,228,229,231,232,234,237,240,243,246,249,252,255,258,261,264,267,270,275,278,281,284,287,290,293,296,299,302,305,308,311]) ; vs[1]=5./6. - ids[2]=DataArrayInt([78,81,84,87,90,93,96,99,102,105,108,111,114,119,122,125,128,131,134,137,140,143,146,149,152,155,236,239,242,245,248,251,254,257,260,263,266,269,272,273,276,279,282,285,288,291,294,297,300,303,306,309]) ; vs[2]=5./3. - ids[3]=DataArrayInt([79,82,85,88,91,94,97,100,103,106,109,112,115,118,121,124,127,130,133,136,139,142,145,148,151,154,235,238,241,244,247,250,253,256,259,262,265,268,271,274,277,280,283,286,289,292,295,298,301,304,307,310]) ; vs[3]=2.5 - vals=DataArrayDouble(312,1) - for idd,v in zip(ids,vs): - vals[idd]=v - pass - vals*=1e-5 - eps0=DataArrayDouble(m0.data)-vals ; eps0.abs() - self.assertTrue(eps0.getIdsInRange(1e-17,1e300).empty()) - self.assertTrue(DataArrayInt(m0.indices).isEqual(DataArrayInt([0,1,3,1,4,5,4,6,7,6,8,9,8,10,11,10,12,13,12,14,15,14,16,17,16,18,19,18,20,21,20,22,23,22,24,25,24,26,27,0,2,3,1,3,5,4,5,7,6,7,9,8,9,11,10,11,13,12,13,15,14,15,17,16,17,19,18,19,21,20,21,23,22,23,25,24,25,27,0,2,3,1,3,5,4,5,7,6,7,9,8,9,11,10,11,13,12,13,15,14,15,17,16,17,19,18,19,21,20,21,23,22,23,25,24,25,27,0,2,3,1,3,5,4,5,7,6,7,9,8,9,11,10,11,13,12,13,15,14,15,17,16,17,19,18,19,21,20,21,23,22,23,25,24,25,27,0,2,3,1,3,5,4,5,7,6,7,9,8,9,11,10,11,13,12,13,15,14,15,17,16,17,19,18,19,21,20,21,23,22,23,25,24,25,27,0,1,3,1,4,5,4,6,7,6,8,9,8,10,11,10,12,13,12,14,15,14,16,17,16,18,19,18,20,21,20,22,23,22,24,25,24,26,27,0,1,3,1,4,5,4,6,7,6,8,9,8,10,11,10,12,13,12,14,15,14,16,17,16,18,19,18,20,21,20,22,23,22,24,25,24,26,27,0,1,3,1,4,5,4,6,7,6,8,9,8,10,11,10,12,13,12,14,15,14,16,17,16,18,19,18,20,21,20,22,23,22,24,25,24,26,27]))) - self.assertTrue(DataArrayInt(m0.indptr).isEqual(DataArrayInt([0,3,6,9,12,15,18,21,24,27,30,33,36,39,42,45,48,51,54,57,60,63,66,69,72,75,78,81,84,87,90,93,96,99,102,105,108,111,114,117,120,123,126,129,132,135,138,141,144,147,150,153,156,159,162,165,168,171,174,177,180,183,186,189,192,195,198,201,204,207,210,213,216,219,222,225,228,231,234,237,240,243,246,249,252,255,258,261,264,267,270,273,276,279,282,285,288,291,294,297,300,303,306,309,312]))) - # - rem2=MEDCouplingRemapper() ; rem2.setIntersectionType(Barycentric) - rem2.prepare(b,a,"P0P1") - m1=rem2.getCrudeCSRMatrix() - self.assertEqual(m1.nnz,312) - # - m1=rem2.getCrudeCSRMatrix() - m1t=m1.transpose() - delta=m0-m1t - self.assertTrue(DataArrayDouble(delta.data).isUniform(0.,1e-17)) - pass - - @unittest.skipUnless(MEDCouplingHasNumPyBindings() and MEDCouplingHasSciPyBindings(),"requires numpy AND scipy") - def testNonConformWithRemapper_1(self): - coo=DataArrayDouble([-0.396700000780411,-0.134843245350081,-0.0361311386958691,-0.407550009429364,-0.13484324535008,-0.0361311386958923,-0.396700000780411,-0.132191446077668,-0.0448729493559049,-0.407550009429364,-0.132191446077666,-0.0448729493559254,-0.396700000780411,-0.128973582738749,-0.0534226071577727,-0.407550009429364,-0.128973582738747,-0.0534226071577904,-0.396700000780411,-0.128348829636458,-0.0346583696473619,-0.407550009429364,-0.128348829636457,-0.0346583696473822,-0.396700000780411,-0.125874740261886,-0.0430683597970123,-0.407550009429364,-0.125874740261885,-0.0430683597970302,-0.396700000780411,-0.122905344829122,-0.051310216195766,-0.407550009429364,-0.12290534482912,-0.0513102161957814],12,3) - conn=DataArrayInt([2,9,3,11,2,3,5,11,2,8,9,11,2,10,8,11,2,5,4,11,2,4,10,11,3,0,1,6,3,1,7,6,3,2,0,6,3,8,2,6,3,7,9,6,3,9,8,6]) - m=MEDCoupling1SGTUMesh("mesh",NORM_TETRA4) - m.setNodalConnectivity(conn) - m.setCoords(coo) - # m is ready - m1,d,di,rd,rdi=m.buildUnstructured().buildDescendingConnectivity() - rdi2=rdi.deltaShiftIndex() - cellIds=rdi2.getIdsEqual(1) - skinAndNonConformCells=m1[cellIds] - skinAndNonConformCells.zipCoords() # at this point skinAndNonConformCells contains non conform cells and skin cells. Now trying to split them in two parts. - # - rem=MEDCouplingRemapper() - rem.setMaxDistance3DSurfIntersect(1e-12) - rem.setMinDotBtwPlane3DSurfIntersect(0.99)# this line is important it is to tell to remapper to select only cells with very close orientation - rem.prepare(skinAndNonConformCells,skinAndNonConformCells,"P0P0") - mat=rem.getCrudeCSRMatrix() - indptr=DataArrayInt(mat.indptr) - indptr2=indptr.deltaShiftIndex() - cellIdsOfNonConformCells=indptr2.getIdsNotEqual(1) - cellIdsOfSkin=indptr2.getIdsEqual(1) - self.assertTrue(cellIdsOfSkin.isEqual(DataArrayInt([1,2,3,5,6,7,8,9,10,11,12,13,14,15,16,17,19,20,21,23]))) - self.assertTrue(cellIdsOfNonConformCells.isEqual(DataArrayInt([0,4,18,22]))) - pass - - def test3D1DOnP1P0_1(self): - """ This test focused on P1P0 interpolation with a source with meshDim=1 spaceDim=3 and a target with meshDim=3. - This test has revealed a bug in remapper. A reverse matrix is computed so a reverse method should be given in input. - """ - target=MEDCouplingCMesh() - arrX=DataArrayDouble([0,1]) ; arrY=DataArrayDouble([0,1]) ; arrZ=DataArrayDouble(11) ; arrZ.iota() - target.setCoords(arrX,arrY,arrZ) - target=target.buildUnstructured() ; target.setName("TargetSecondaire") - # - sourceCoo=DataArrayDouble([(0.5,0.5,0.1),(0.5,0.5,1.2),(0.5,0.5,1.6),(0.5,0.5,1.8),(0.5,0.5,2.43),(0.5,0.5,2.55),(0.5,0.5,4.1),(0.5,0.5,4.4),(0.5,0.5,4.9),(0.5,0.5,5.1),(0.5,0.5,7.6),(0.5,0.5,7.7),(0.5,0.5,8.2),(0.5,0.5,8.4),(0.5,0.5,8.6),(0.5,0.5,8.8),(0.5,0.5,9.2),(0.5,0.5,9.6),(0.5,0.5,11.5)]) - source=MEDCoupling1SGTUMesh("SourcePrimaire",NORM_SEG2) - source.setCoords(sourceCoo) - source.allocateCells() - for i in xrange(len(sourceCoo)-1): - source.insertNextCell([i,i+1]) - pass - source=source.buildUnstructured() - fsource=MEDCouplingFieldDouble(ON_NODES) ; fsource.setName("field") - fsource.setMesh(source) - arr=DataArrayDouble(len(sourceCoo)) ; arr.iota(0.7) ; arr*=arr - fsource.setArray(arr) - fsource.setNature(ConservativeVolumic) - # - rem=MEDCouplingRemapper() - rem.setIntersectionType(PointLocator) - rem.prepare(source,target,"P1P0") - f2Test=rem.transferField(fsource,-27) - self.assertEqual(f2Test.getName(),fsource.getName()) - self.assertEqual(f2Test.getMesh().getHiddenCppPointer(),target.getHiddenCppPointer()) - expArr=DataArrayDouble([0.49,7.956666666666667,27.29,-27,59.95666666666667,94.09,-27,125.69,202.89,296.09]) - self.assertTrue(f2Test.getArray().isEqual(expArr,1e-12)) - f2Test=rem.reverseTransferField(f2Test,-36) - self.assertEqual(f2Test.getName(),fsource.getName()) - self.assertEqual(f2Test.getMesh().getHiddenCppPointer(),source.getHiddenCppPointer()) - expArr2=DataArrayDouble([0.49,7.956666666666667,7.956666666666667,7.956666666666667,27.29,27.29,59.95666666666667,59.95666666666667,59.95666666666667,94.09,125.69,125.69,202.89,202.89,202.89,202.89,296.09,296.09,-36.]) - self.assertTrue(f2Test.getArray().isEqual(expArr2,1e-12)) - pass - - def testRemapperAMR1(self): - """ This test is the origin of the ref values for MEDCouplingBasicsTest.testAMR2""" - coarse=DataArrayDouble(35) ; coarse.iota(0) #X=5,Y=7 - fine=DataArrayDouble(3*2*4*4) ; fine.iota(0) #X=3,Y=2 refined by 4 - MEDCouplingIMesh.CondenseFineToCoarse([5,7],fine,[(1,4),(2,4)],[4,4],coarse) - # - m=MEDCouplingCartesianAMRMesh("mesh",2,[6,8],[0.,0.],[1.,1.]) - trgMesh=m.buildUnstructured() - m.addPatch([(1,4),(2,4)],[4,4]) - srcMesh=m[0].getMesh().buildUnstructured() - srcField=MEDCouplingFieldDouble(ON_CELLS) - fine2=DataArrayDouble(3*2*4*4) ; fine2.iota(0) ; srcField.setArray(fine2) - srcField.setMesh(srcMesh) ; srcField.setNature(Integral) - # - trgField=MEDCouplingFieldDouble(ON_CELLS) - coarse2=DataArrayDouble(35) ; coarse2.iota(0) ; trgField.setArray(coarse2) - trgField.setMesh(trgMesh) ; trgField.setNature(Integral) - # - rem=MEDCouplingRemapper() - rem.prepare(srcMesh,trgMesh,"P0P0") - rem.partialTransfer(srcField,trgField) - # - self.assertTrue(coarse.isEqual(trgField.getArray(),1e-12)) - pass - - @unittest.skipUnless(MEDCouplingHasNumPyBindings() and MEDCouplingHasSciPyBindings(),"requires numpy AND scipy") - def test1DPointLocator1(self): - """This test focuses on PointLocator for P1P1 in 1D and 2DCurve.""" - from numpy import array - from scipy.sparse import diags,csr_matrix,identity - ## basic case 1D - arrS=DataArrayInt.Range(0,11,1).convertToDblArr() - arrT=DataArrayDouble([0.1,1.7,5.5,9.6]) - mS=MEDCouplingCMesh() ; mS.setCoords(arrS) - mT=MEDCouplingCMesh() ; mT.setCoords(arrT) - rem=MEDCouplingRemapper() - rem.setIntersectionType(PointLocator) - self.assertEqual(rem.prepare(mS.buildUnstructured(),mT.buildUnstructured(),"P1P1"),1) - m=rem.getCrudeCSRMatrix() - rowSum=m.sum(axis=1) - m=diags(array(1/rowSum.transpose()),[0])*m - # expected matrix - row=array([0,0,1,1,2,2,3,3]) - col=array([0,1,1,2,5,6,9,10]) - data=array([0.9,0.1,0.3,0.7,0.5,0.5,0.4,0.6]) - mExp0=csr_matrix((data,(row,col)),shape=(4,11)) - # compute diff and check - diff=abs(m-mExp0) - self.assertAlmostEqual(diff.max(),0.,14) - ## full specific case 1D where target=source - rem=MEDCouplingRemapper() - rem.setIntersectionType(PointLocator) - self.assertEqual(rem.prepare(mS.buildUnstructured(),mS.buildUnstructured(),"P1P1"),1) - m=rem.getCrudeCSRMatrix() - rowSum=m.sum(axis=1) - m=diags(array(1/rowSum.transpose()),[0])*m - # expected matrix - mExp1=identity(11) - diff=abs(m-mExp1) - self.assertAlmostEqual(diff.max(),0.,14) - ## case where some points in target are not in source - arrT=DataArrayDouble([-0.2,0.1,1.7,5.5,10.3]) - mT=MEDCouplingCMesh() ; mT.setCoords(arrT) - mT=mT.buildUnstructured() - rem=MEDCouplingRemapper() - rem.setIntersectionType(PointLocator) - self.assertEqual(rem.prepare(mS.buildUnstructured(),mT,"P1P1"),1) - m=rem.getCrudeCSRMatrix() - row=array([1,1,2,2,3,3]) - col=array([0,1,1,2,5,6]) - data=array([0.9,0.1,0.3,0.7,0.5,0.5]) - mExp2=csr_matrix((data,(row,col)),shape=(5,11)) - diff=abs(m-mExp2) - self.assertAlmostEqual(diff.max(),0.,14) - ## basic case 2D Curve - arrS=DataArrayInt.Range(0,11,1).convertToDblArr() - arrT=DataArrayDouble([0.1,1.7,5.5,9.6]) - mS=MEDCouplingCMesh() ; mS.setCoords(arrS) - mT=MEDCouplingCMesh() ; mT.setCoords(arrT) - mS=mS.buildUnstructured() ; mS.changeSpaceDimension(2) - mT=mT.buildUnstructured() ; mT.changeSpaceDimension(2) - mS.rotate([-1.,-1.],1.2) - mT.rotate([-1.,-1.],1.2) - rem=MEDCouplingRemapper() - rem.setIntersectionType(PointLocator) - self.assertEqual(rem.prepare(mS,mT,"P1P1"),1) - m=rem.getCrudeCSRMatrix() - rowSum=m.sum(axis=1) - m=diags(array(1/rowSum.transpose()),[0])*m - diff=abs(m-mExp0) - self.assertAlmostEqual(diff.max(),0.,14) - pass - - def build2DSourceMesh_1(self): - sourceCoords=[-0.3,-0.3, 0.7,-0.3, -0.3,0.7, 0.7,0.7] - sourceConn=[0,3,1,0,2,3] - sourceMesh=MEDCouplingUMesh.New("my name of mesh 2D",2) - sourceMesh.allocateCells(2); - sourceMesh.insertNextCell(NORM_TRI3,3,sourceConn[0:3]); - sourceMesh.insertNextCell(NORM_TRI3,3,sourceConn[3:6]); - sourceMesh.finishInsertingCells(); - myCoords=DataArrayDouble.New(); - myCoords.setValues(sourceCoords,4,2); - sourceMesh.setCoords(myCoords); - return sourceMesh; - - def build2DTargetMesh_1(self): - targetCoords=[-0.3,-0.3, 0.2,-0.3, 0.7,-0.3, -0.3,0.2, 0.2,0.2, 0.7,0.2, -0.3,0.7, 0.2,0.7, 0.7,0.7 ] - targetConn=[0,3,4,1, 1,4,2, 4,5,2, 6,7,4,3, 7,8,5,4] - targetMesh=MEDCouplingUMesh.New(); - targetMesh.setMeshDimension(2); - targetMesh.allocateCells(5); - targetMesh.insertNextCell(NORM_QUAD4,4,targetConn[0:4]); - targetMesh.insertNextCell(NORM_TRI3,3,targetConn[4:7]); - targetMesh.insertNextCell(NORM_TRI3,3,targetConn[7:10]); - targetMesh.insertNextCell(NORM_QUAD4,4,targetConn[10:14]); - targetMesh.insertNextCell(NORM_QUAD4,4,targetConn[14:18]); - targetMesh.finishInsertingCells(); - myCoords=DataArrayDouble.New(); - myCoords.setValues(targetCoords,9,2); - targetMesh.setCoords(myCoords); - return targetMesh; - - def build2DTargetMesh_3(self): - targetCoords=[-0.6,-0.4, -0.1,-0.4, 1.1,-0.4, 2.1,-0.4, -0.6,0.1, -0.1,0.1, 1.1,0.1, 2.1,0.1, -0.6,1.1, -0.1,1.1] - targetConn=[0,4,5,1, 1,5,6,2, 2,6,7,3, 4,8,9,5] - targetMesh=MEDCouplingUMesh.New(); - targetMesh.setMeshDimension(2); - targetMesh.allocateCells(4); - for i in xrange(4): - targetMesh.insertNextCell(NORM_QUAD4,4,targetConn[4*i:4*(i+1)]) - pass - targetMesh.finishInsertingCells(); - myCoords=DataArrayDouble.New(); - myCoords.setValues(targetCoords,10,2); - targetMesh.setCoords(myCoords); - return targetMesh; - pass - - def setUp(self): - pass - pass - -unittest.main() diff --git a/src/MEDCoupling_Swig/MEDCouplingTimeDiscretization.i b/src/MEDCoupling_Swig/MEDCouplingTimeDiscretization.i deleted file mode 100644 index 411033e59..000000000 --- a/src/MEDCoupling_Swig/MEDCouplingTimeDiscretization.i +++ /dev/null @@ -1,171 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 -// 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) - -namespace ParaMEDMEM -{ - class MEDCouplingTimeDiscretization : public TimeLabel, public BigMemoryObject - { - public: - static MEDCouplingTimeDiscretization *New(TypeOfTimeDiscretization type) throw(INTERP_KERNEL::Exception); - void setTimeUnit(const char *unit); - const char *getTimeUnit() const; - virtual void copyTinyAttrFrom(const MEDCouplingTimeDiscretization& other) throw(INTERP_KERNEL::Exception); - 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 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); - virtual TypeOfTimeDiscretization getEnum() const throw(INTERP_KERNEL::Exception); - virtual void synchronizeTimeWith(const MEDCouplingMesh *mesh) throw(INTERP_KERNEL::Exception); - virtual MEDCouplingTimeDiscretization *aggregate(const MEDCouplingTimeDiscretization *other) const throw(INTERP_KERNEL::Exception); - virtual MEDCouplingTimeDiscretization *aggregate(const std::vector& other) const throw(INTERP_KERNEL::Exception); - virtual MEDCouplingTimeDiscretization *meld(const MEDCouplingTimeDiscretization *other) const throw(INTERP_KERNEL::Exception); - virtual MEDCouplingTimeDiscretization *dot(const MEDCouplingTimeDiscretization *other) const throw(INTERP_KERNEL::Exception); - virtual MEDCouplingTimeDiscretization *crossProduct(const MEDCouplingTimeDiscretization *other) const throw(INTERP_KERNEL::Exception); - virtual MEDCouplingTimeDiscretization *max(const MEDCouplingTimeDiscretization *other) const throw(INTERP_KERNEL::Exception); - virtual MEDCouplingTimeDiscretization *min(const MEDCouplingTimeDiscretization *other) const throw(INTERP_KERNEL::Exception); - virtual MEDCouplingTimeDiscretization *add(const MEDCouplingTimeDiscretization *other) const throw(INTERP_KERNEL::Exception); - virtual void addEqual(const MEDCouplingTimeDiscretization *other) throw(INTERP_KERNEL::Exception); - virtual MEDCouplingTimeDiscretization *substract(const MEDCouplingTimeDiscretization *other) const throw(INTERP_KERNEL::Exception); - virtual void substractEqual(const MEDCouplingTimeDiscretization *other) throw(INTERP_KERNEL::Exception); - virtual MEDCouplingTimeDiscretization *multiply(const MEDCouplingTimeDiscretization *other) const throw(INTERP_KERNEL::Exception); - virtual void multiplyEqual(const MEDCouplingTimeDiscretization *other) throw(INTERP_KERNEL::Exception); - virtual MEDCouplingTimeDiscretization *divide(const MEDCouplingTimeDiscretization *other) const throw(INTERP_KERNEL::Exception); - virtual void divideEqual(const MEDCouplingTimeDiscretization *other) throw(INTERP_KERNEL::Exception); - virtual MEDCouplingTimeDiscretization *pow(const MEDCouplingTimeDiscretization *other) const throw(INTERP_KERNEL::Exception); - virtual void powEqual(const MEDCouplingTimeDiscretization *other) throw(INTERP_KERNEL::Exception); - virtual MEDCouplingTimeDiscretization *performCpy(bool deepCpy) const throw(INTERP_KERNEL::Exception); - void setTimeTolerance(double val); - double getTimeTolerance() const; - virtual void checkNoTimePresence() const throw(INTERP_KERNEL::Exception); - virtual void checkTimePresence(double time) const throw(INTERP_KERNEL::Exception); - 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() throw(INTERP_KERNEL::Exception); - const DataArrayDouble *getArray() const throw(INTERP_KERNEL::Exception); - 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); - virtual void getValueForTime(double time, const std::vector& vals, double *res) const throw(INTERP_KERNEL::Exception); - 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); - virtual double getStartTime(int& iteration, int& order) const throw(INTERP_KERNEL::Exception); - virtual double getEndTime(int& iteration, int& order) const throw(INTERP_KERNEL::Exception); - void setTime(double time, int iteration, int order) throw(INTERP_KERNEL::Exception); - void setIteration(int it) throw(INTERP_KERNEL::Exception); - void setOrder(int order) throw(INTERP_KERNEL::Exception); - void setTimeValue(double val) throw(INTERP_KERNEL::Exception); - virtual void setStartIteration(int it) throw(INTERP_KERNEL::Exception); - virtual void setEndIteration(int it) throw(INTERP_KERNEL::Exception); - virtual void setStartOrder(int order) throw(INTERP_KERNEL::Exception); - virtual void setEndOrder(int order) throw(INTERP_KERNEL::Exception); - virtual void setStartTimeValue(double time) throw(INTERP_KERNEL::Exception); - virtual void setEndTimeValue(double time) throw(INTERP_KERNEL::Exception); - virtual void setStartTime(double time, int iteration, int order) throw(INTERP_KERNEL::Exception); - virtual void setEndTime(double time, int iteration, int order) throw(INTERP_KERNEL::Exception); - virtual void getValueOnTime(int eltId, double time, double *value) const throw(INTERP_KERNEL::Exception); - virtual void getValueOnDiscTime(int eltId, int iteration, int order, double *value) const throw(INTERP_KERNEL::Exception); - // - virtual MEDCouplingTimeDiscretization *doublyContractedProduct() const throw(INTERP_KERNEL::Exception); - virtual MEDCouplingTimeDiscretization *determinant() const throw(INTERP_KERNEL::Exception); - virtual MEDCouplingTimeDiscretization *eigenValues() const throw(INTERP_KERNEL::Exception); - virtual MEDCouplingTimeDiscretization *eigenVectors() const throw(INTERP_KERNEL::Exception); - virtual MEDCouplingTimeDiscretization *inverse() const throw(INTERP_KERNEL::Exception); - 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) 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); - virtual void fillFromAnalytic3(const DataArrayDouble *loc, int nbOfComp, const std::vector& varsOrder, const char *func) throw(INTERP_KERNEL::Exception); - // - virtual ~MEDCouplingTimeDiscretization(); - }; - - class MEDCouplingNoTimeLabel : public MEDCouplingTimeDiscretization - { - public: - MEDCouplingNoTimeLabel(); - MEDCouplingNoTimeLabel(const MEDCouplingTimeDiscretization& other, bool deepCpy); - public: - static const TypeOfTimeDiscretization DISCRETIZATION=NO_TIME; - static const char REPR[]; - }; - - class MEDCouplingWithTimeStep : public MEDCouplingTimeDiscretization - { - public: - MEDCouplingWithTimeStep(); - public: - static const TypeOfTimeDiscretization DISCRETIZATION=ONE_TIME; - static const char REPR[]; - }; - - class MEDCouplingConstOnTimeInterval : public MEDCouplingTimeDiscretization - { - protected: - MEDCouplingConstOnTimeInterval(); - MEDCouplingConstOnTimeInterval(const MEDCouplingConstOnTimeInterval& other, bool deepCpy); - public: - static const TypeOfTimeDiscretization DISCRETIZATION=CONST_ON_TIME_INTERVAL; - static const char REPR[]; - }; - - class MEDCouplingTwoTimeSteps : public MEDCouplingTimeDiscretization - { - }; - - class MEDCouplingLinearTime : public MEDCouplingTwoTimeSteps - { - public: - MEDCouplingLinearTime(); - public: - static const TypeOfTimeDiscretization DISCRETIZATION=LINEAR_TIME; - static const char REPR[]; - }; -} - -#endif diff --git a/src/MEDCoupling_Swig/MEDCouplingTypemaps.i b/src/MEDCoupling_Swig/MEDCouplingTypemaps.i deleted file mode 100644 index 94bed84df..000000000 --- a/src/MEDCoupling_Swig/MEDCouplingTypemaps.i +++ /dev/null @@ -1,457 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 -// 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 "MEDCouplingDataArrayTypemaps.i" - -static PyObject *convertMesh(ParaMEDMEM::MEDCouplingMesh *mesh, int owner) throw(INTERP_KERNEL::Exception) -{ - PyObject *ret=0; - if(!mesh) - { - Py_XINCREF(Py_None); - return Py_None; - } - if(dynamic_cast(mesh)) - ret=SWIG_NewPointerObj((void*)mesh,SWIGTYPE_p_ParaMEDMEM__MEDCouplingUMesh,owner); - if(dynamic_cast(mesh)) - ret=SWIG_NewPointerObj((void*)mesh,SWIGTYPE_p_ParaMEDMEM__MEDCoupling1SGTUMesh,owner); - if(dynamic_cast(mesh)) - ret=SWIG_NewPointerObj((void*)mesh,SWIGTYPE_p_ParaMEDMEM__MEDCoupling1DGTUMesh,owner); - if(dynamic_cast(mesh)) - ret=SWIG_NewPointerObj((void*)mesh,SWIGTYPE_p_ParaMEDMEM__MEDCouplingExtrudedMesh,owner); - if(dynamic_cast(mesh)) - ret=SWIG_NewPointerObj((void*)mesh,SWIGTYPE_p_ParaMEDMEM__MEDCouplingCMesh,owner); - if(dynamic_cast(mesh)) - ret=SWIG_NewPointerObj((void*)mesh,SWIGTYPE_p_ParaMEDMEM__MEDCouplingCurveLinearMesh,owner); - if(dynamic_cast(mesh)) - ret=SWIG_NewPointerObj((void*)mesh,SWIGTYPE_p_ParaMEDMEM__MEDCouplingIMesh,owner); - if(!ret) - throw INTERP_KERNEL::Exception("Not recognized type of mesh on downcast !"); - return ret; -} - -static PyObject *convertFieldDiscretization(ParaMEDMEM::MEDCouplingFieldDiscretization *fd, int owner) throw(INTERP_KERNEL::Exception) -{ - PyObject *ret=0; - if(!fd) - { - Py_XINCREF(Py_None); - return Py_None; - } - if(dynamic_cast(fd)) - ret=SWIG_NewPointerObj(reinterpret_cast(fd),SWIGTYPE_p_ParaMEDMEM__MEDCouplingFieldDiscretizationP0,owner); - if(dynamic_cast(fd)) - ret=SWIG_NewPointerObj(reinterpret_cast(fd),SWIGTYPE_p_ParaMEDMEM__MEDCouplingFieldDiscretizationP1,owner); - if(dynamic_cast(fd)) - ret=SWIG_NewPointerObj(reinterpret_cast(fd),SWIGTYPE_p_ParaMEDMEM__MEDCouplingFieldDiscretizationGauss,owner); - if(dynamic_cast(fd)) - ret=SWIG_NewPointerObj(reinterpret_cast(fd),SWIGTYPE_p_ParaMEDMEM__MEDCouplingFieldDiscretizationGaussNE,owner); - if(dynamic_cast(fd)) - ret=SWIG_NewPointerObj(reinterpret_cast(fd),SWIGTYPE_p_ParaMEDMEM__MEDCouplingFieldDiscretizationKriging,owner); - if(!ret) - throw INTERP_KERNEL::Exception("Not recognized type of field discretization on downcast !"); - return ret; -} - -static PyObject* convertMultiFields(ParaMEDMEM::MEDCouplingMultiFields *mfs, int owner) throw(INTERP_KERNEL::Exception) -{ - PyObject *ret=0; - if(!mfs) - { - Py_XINCREF(Py_None); - return Py_None; - } - if(dynamic_cast(mfs)) - ret=SWIG_NewPointerObj((void*)mfs,SWIGTYPE_p_ParaMEDMEM__MEDCouplingFieldOverTime,owner); - else - ret=SWIG_NewPointerObj((void*)mfs,SWIGTYPE_p_ParaMEDMEM__MEDCouplingMultiFields,owner); - return ret; -} - -static PyObject *convertPartDefinition(ParaMEDMEM::PartDefinition *pd, int owner) throw(INTERP_KERNEL::Exception) -{ - PyObject *ret=0; - if(!pd) - { - Py_XINCREF(Py_None); - return Py_None; - } - if(dynamic_cast(pd)) - ret=SWIG_NewPointerObj((void*)pd,SWIGTYPE_p_ParaMEDMEM__DataArrayPartDefinition,owner); - else - ret=SWIG_NewPointerObj((void*)pd,SWIGTYPE_p_ParaMEDMEM__SlicePartDefinition,owner); - return ret; -} - -static PyObject *convertCartesianAMRMesh(ParaMEDMEM::MEDCouplingCartesianAMRMeshGen *mesh, int owner) throw(INTERP_KERNEL::Exception) -{ - if(!mesh) - { - Py_XINCREF(Py_None); - return Py_None; - } - if(dynamic_cast(mesh)) - { - return SWIG_NewPointerObj(reinterpret_cast(mesh),SWIGTYPE_p_ParaMEDMEM__MEDCouplingCartesianAMRMeshSub,owner); - } - if(dynamic_cast(mesh)) - { - return SWIG_NewPointerObj(reinterpret_cast(mesh),SWIGTYPE_p_ParaMEDMEM__MEDCouplingCartesianAMRMesh,owner); - } - throw INTERP_KERNEL::Exception("convertCartesianAMRMesh wrap : unrecognized type of cartesian AMR mesh !"); -} - -static PyObject *convertDataForGodFather(ParaMEDMEM::MEDCouplingDataForGodFather *data, int owner) throw(INTERP_KERNEL::Exception) -{ - if(!data) - { - Py_XINCREF(Py_None); - return Py_None; - } - if(dynamic_cast(data)) - { - return SWIG_NewPointerObj(reinterpret_cast(data),SWIGTYPE_p_ParaMEDMEM__MEDCouplingAMRAttribute,owner); - } - throw INTERP_KERNEL::Exception("convertDataForGodFather wrap : unrecognized data type for AMR !"); -} - -static PyObject *convertCartesianAMRPatch(ParaMEDMEM::MEDCouplingCartesianAMRPatchGen *patch, int owner) throw(INTERP_KERNEL::Exception) -{ - if(!patch) - { - Py_XINCREF(Py_None); - return Py_None; - } - if(dynamic_cast(patch)) - { - return SWIG_NewPointerObj(reinterpret_cast(patch),SWIGTYPE_p_ParaMEDMEM__MEDCouplingCartesianAMRPatchGF,owner); - } - if(dynamic_cast(patch)) - { - return SWIG_NewPointerObj(reinterpret_cast(patch),SWIGTYPE_p_ParaMEDMEM__MEDCouplingCartesianAMRPatch,owner); - } - throw INTERP_KERNEL::Exception("convertCartesianAMRPatch wrap : unrecognized type of cartesian AMR patch !"); -} - -static ParaMEDMEM::MEDCouplingFieldDouble *ParaMEDMEM_MEDCouplingFieldDouble___add__Impl(ParaMEDMEM::MEDCouplingFieldDouble *self, PyObject *obj) throw(INTERP_KERNEL::Exception) -{ - const char msg[]="Unexpected situation in MEDCouplingFieldDouble.__add__ ! Expecting a not null MEDCouplingFieldDouble or DataArrayDouble or DataArrayDoubleTuple instance, or a list of double, or a double."; - const char msg2[]="in MEDCouplingFieldDouble.__add__ : self field has no Array of values set !"; - void *argp; - // - if(SWIG_IsOK(SWIG_ConvertPtr(obj,&argp,SWIGTYPE_p_ParaMEDMEM__MEDCouplingFieldDouble,0|0))) - { - ParaMEDMEM::MEDCouplingFieldDouble *other=reinterpret_cast< ParaMEDMEM::MEDCouplingFieldDouble * >(argp); - if(other) - return (*self)+(*other); - else - throw INTERP_KERNEL::Exception(msg); - } - // - double val; - ParaMEDMEM::DataArrayDouble *a; - ParaMEDMEM::DataArrayDoubleTuple *aa; - std::vector bb; - int sw; - convertObjToPossibleCpp5(obj,sw,val,a,aa,bb); - switch(sw) - { - case 1: - { - if(!self->getArray()) - throw INTERP_KERNEL::Exception(msg2); - ParaMEDMEM::MEDCouplingAutoRefCountObjectPtr ret=self->getArray()->deepCpy(); - ret->applyLin(1.,val); - ParaMEDMEM::MEDCouplingAutoRefCountObjectPtr ret2=self->clone(false); - ret2->setArray(ret); - return ret2.retn(); - } - case 2: - { - if(!self->getArray()) - throw INTERP_KERNEL::Exception(msg2); - ParaMEDMEM::MEDCouplingAutoRefCountObjectPtr ret=ParaMEDMEM::DataArrayDouble::Add(self->getArray(),a); - ParaMEDMEM::MEDCouplingAutoRefCountObjectPtr ret2=self->clone(false); - ret2->setArray(ret); - return ret2.retn(); - } - case 3: - { - if(!self->getArray()) - throw INTERP_KERNEL::Exception(msg2); - ParaMEDMEM::MEDCouplingAutoRefCountObjectPtr aaa=aa->buildDADouble(1,self->getNumberOfComponents()); - ParaMEDMEM::MEDCouplingAutoRefCountObjectPtr ret=ParaMEDMEM::DataArrayDouble::Add(self->getArray(),aaa); - ParaMEDMEM::MEDCouplingAutoRefCountObjectPtr ret2=self->clone(false); - ret2->setArray(ret); - return ret2.retn(); - } - case 4: - { - if(!self->getArray()) - throw INTERP_KERNEL::Exception(msg2); - ParaMEDMEM::MEDCouplingAutoRefCountObjectPtr aaa=ParaMEDMEM::DataArrayDouble::New(); aaa->useArray(&bb[0],false,ParaMEDMEM::CPP_DEALLOC,1,(int)bb.size()); - ParaMEDMEM::MEDCouplingAutoRefCountObjectPtr ret=ParaMEDMEM::DataArrayDouble::Add(self->getArray(),aaa); - ParaMEDMEM::MEDCouplingAutoRefCountObjectPtr ret2=self->clone(false); - ret2->setArray(ret); - return ret2.retn(); - } - default: - { throw INTERP_KERNEL::Exception(msg); } - } -} - -static ParaMEDMEM::MEDCouplingFieldDouble *ParaMEDMEM_MEDCouplingFieldDouble___radd__Impl(ParaMEDMEM::MEDCouplingFieldDouble *self, PyObject *obj) throw(INTERP_KERNEL::Exception) -{ - return ParaMEDMEM_MEDCouplingFieldDouble___add__Impl(self,obj); -} - -static ParaMEDMEM::MEDCouplingFieldDouble *ParaMEDMEM_MEDCouplingFieldDouble___rsub__Impl(ParaMEDMEM::MEDCouplingFieldDouble *self, PyObject *obj) throw(INTERP_KERNEL::Exception) -{ - const char msg[]="Unexpected situation in MEDCouplingFieldDouble.__rsub__ ! Expecting a not null MEDCouplingFieldDouble or DataArrayDouble or DataArrayDoubleTuple instance, or a list of double, or a double."; - const char msg2[]="in MEDCouplingFieldDouble.__rsub__ : self field has no Array of values set !"; - void *argp; - // - if(SWIG_IsOK(SWIG_ConvertPtr(obj,&argp,SWIGTYPE_p_ParaMEDMEM__MEDCouplingFieldDouble,0|0))) - { - ParaMEDMEM::MEDCouplingFieldDouble *other=reinterpret_cast< ParaMEDMEM::MEDCouplingFieldDouble * >(argp); - if(other) - return (*other)-(*self); - else - throw INTERP_KERNEL::Exception(msg); - } - // - double val; - ParaMEDMEM::DataArrayDouble *a; - ParaMEDMEM::DataArrayDoubleTuple *aa; - std::vector bb; - int sw; - convertObjToPossibleCpp5(obj,sw,val,a,aa,bb); - switch(sw) - { - case 1: - { - if(!self->getArray()) - throw INTERP_KERNEL::Exception(msg2); - ParaMEDMEM::MEDCouplingAutoRefCountObjectPtr ret=self->getArray()->deepCpy(); - ret->applyLin(-1.,val); - ParaMEDMEM::MEDCouplingAutoRefCountObjectPtr ret2=self->clone(false); - ret2->setArray(ret); - return ret2.retn(); - } - case 2: - { - if(!self->getArray()) - throw INTERP_KERNEL::Exception(msg2); - ParaMEDMEM::MEDCouplingAutoRefCountObjectPtr ret=ParaMEDMEM::DataArrayDouble::Substract(a,self->getArray()); - ParaMEDMEM::MEDCouplingAutoRefCountObjectPtr ret2=self->clone(false); - ret2->setArray(ret); - return ret2.retn(); - } - case 3: - { - if(!self->getArray()) - throw INTERP_KERNEL::Exception(msg2); - ParaMEDMEM::MEDCouplingAutoRefCountObjectPtr aaa=aa->buildDADouble(1,self->getNumberOfComponents()); - ParaMEDMEM::MEDCouplingAutoRefCountObjectPtr ret=ParaMEDMEM::DataArrayDouble::Substract(aaa,self->getArray()); - ParaMEDMEM::MEDCouplingAutoRefCountObjectPtr ret2=self->clone(false); - ret2->setArray(ret); - return ret2.retn(); - } - case 4: - { - if(!self->getArray()) - throw INTERP_KERNEL::Exception(msg2); - ParaMEDMEM::MEDCouplingAutoRefCountObjectPtr aaa=ParaMEDMEM::DataArrayDouble::New(); aaa->useArray(&bb[0],false,ParaMEDMEM::CPP_DEALLOC,1,(int)bb.size()); - ParaMEDMEM::MEDCouplingAutoRefCountObjectPtr ret=ParaMEDMEM::DataArrayDouble::Substract(aaa,self->getArray()); - ParaMEDMEM::MEDCouplingAutoRefCountObjectPtr ret2=self->clone(false); - ret2->setArray(ret); - return ret2.retn(); - } - default: - { throw INTERP_KERNEL::Exception(msg); } - } -} - -static ParaMEDMEM::MEDCouplingFieldDouble *ParaMEDMEM_MEDCouplingFieldDouble___mul__Impl(ParaMEDMEM::MEDCouplingFieldDouble *self, PyObject *obj) throw(INTERP_KERNEL::Exception) -{ - const char msg[]="Unexpected situation in MEDCouplingFieldDouble.__mul__ ! Expecting a not null MEDCouplingFieldDouble or DataArrayDouble or DataArrayDoubleTuple instance, or a list of double, or a double."; - const char msg2[]="in MEDCouplingFieldDouble.__mul__ : self field has no Array of values set !"; - void *argp; - // - if(SWIG_IsOK(SWIG_ConvertPtr(obj,&argp,SWIGTYPE_p_ParaMEDMEM__MEDCouplingFieldDouble,0|0))) - { - ParaMEDMEM::MEDCouplingFieldDouble *other=reinterpret_cast< ParaMEDMEM::MEDCouplingFieldDouble * >(argp); - if(other) - return (*self)*(*other); - else - throw INTERP_KERNEL::Exception(msg); - } - // - double val; - ParaMEDMEM::DataArrayDouble *a; - ParaMEDMEM::DataArrayDoubleTuple *aa; - std::vector bb; - int sw; - convertObjToPossibleCpp5(obj,sw,val,a,aa,bb); - switch(sw) - { - case 1: - { - if(!self->getArray()) - throw INTERP_KERNEL::Exception(msg2); - ParaMEDMEM::MEDCouplingAutoRefCountObjectPtr ret=self->getArray()->deepCpy(); - ret->applyLin(val,0.); - ParaMEDMEM::MEDCouplingAutoRefCountObjectPtr ret2=self->clone(false); - ret2->setArray(ret); - return ret2.retn(); - } - case 2: - { - if(!self->getArray()) - throw INTERP_KERNEL::Exception(msg2); - ParaMEDMEM::MEDCouplingAutoRefCountObjectPtr ret=ParaMEDMEM::DataArrayDouble::Multiply(self->getArray(),a); - ParaMEDMEM::MEDCouplingAutoRefCountObjectPtr ret2=self->clone(false); - ret2->setArray(ret); - return ret2.retn(); - } - case 3: - { - if(!self->getArray()) - throw INTERP_KERNEL::Exception(msg2); - ParaMEDMEM::MEDCouplingAutoRefCountObjectPtr aaa=aa->buildDADouble(1,self->getNumberOfComponents()); - ParaMEDMEM::MEDCouplingAutoRefCountObjectPtr ret=ParaMEDMEM::DataArrayDouble::Multiply(self->getArray(),aaa); - ParaMEDMEM::MEDCouplingAutoRefCountObjectPtr ret2=self->clone(false); - ret2->setArray(ret); - return ret2.retn(); - } - case 4: - { - if(!self->getArray()) - throw INTERP_KERNEL::Exception(msg2); - ParaMEDMEM::MEDCouplingAutoRefCountObjectPtr aaa=ParaMEDMEM::DataArrayDouble::New(); aaa->useArray(&bb[0],false,ParaMEDMEM::CPP_DEALLOC,1,(int)bb.size()); - ParaMEDMEM::MEDCouplingAutoRefCountObjectPtr ret=ParaMEDMEM::DataArrayDouble::Multiply(self->getArray(),aaa); - ParaMEDMEM::MEDCouplingAutoRefCountObjectPtr ret2=self->clone(false); - ret2->setArray(ret); - return ret2.retn(); - } - default: - { throw INTERP_KERNEL::Exception(msg); } - } -} - -ParaMEDMEM::MEDCouplingFieldDouble *ParaMEDMEM_MEDCouplingFieldDouble___rmul__Impl(ParaMEDMEM::MEDCouplingFieldDouble *self, PyObject *obj) throw(INTERP_KERNEL::Exception) -{ - return ParaMEDMEM_MEDCouplingFieldDouble___mul__Impl(self,obj); -} - -ParaMEDMEM::MEDCouplingFieldDouble *ParaMEDMEM_MEDCouplingFieldDouble___rdiv__Impl(ParaMEDMEM::MEDCouplingFieldDouble *self, PyObject *obj) throw(INTERP_KERNEL::Exception) -{ - const char msg[]="Unexpected situation in MEDCouplingFieldDouble.__rdiv__ ! Expecting a not null MEDCouplingFieldDouble or DataArrayDouble or DataArrayDoubleTuple instance, or a list of double, or a double."; - const char msg2[]="in MEDCouplingFieldDouble.__div__ : self field has no Array of values set !"; - void *argp; - // - if(SWIG_IsOK(SWIG_ConvertPtr(obj,&argp,SWIGTYPE_p_ParaMEDMEM__MEDCouplingFieldDouble,0|0))) - { - ParaMEDMEM::MEDCouplingFieldDouble *other=reinterpret_cast< ParaMEDMEM::MEDCouplingFieldDouble * >(argp); - if(other) - return (*other)/(*self); - else - throw INTERP_KERNEL::Exception(msg); - } - // - double val; - ParaMEDMEM::DataArrayDouble *a; - ParaMEDMEM::DataArrayDoubleTuple *aa; - std::vector bb; - int sw; - convertObjToPossibleCpp5(obj,sw,val,a,aa,bb); - switch(sw) - { - case 1: - { - if(!self->getArray()) - throw INTERP_KERNEL::Exception(msg2); - ParaMEDMEM::MEDCouplingAutoRefCountObjectPtr ret=self->getArray()->deepCpy(); - ret->applyInv(val); - ParaMEDMEM::MEDCouplingAutoRefCountObjectPtr ret2=self->clone(false); - ret2->setArray(ret); - return ret2.retn(); - } - case 2: - { - if(!self->getArray()) - throw INTERP_KERNEL::Exception(msg2); - ParaMEDMEM::MEDCouplingAutoRefCountObjectPtr ret=ParaMEDMEM::DataArrayDouble::Divide(a,self->getArray()); - ParaMEDMEM::MEDCouplingAutoRefCountObjectPtr ret2=self->clone(false); - ret2->setArray(ret); - return ret2.retn(); - } - case 3: - { - if(!self->getArray()) - throw INTERP_KERNEL::Exception(msg2); - ParaMEDMEM::MEDCouplingAutoRefCountObjectPtr aaa=aa->buildDADouble(1,self->getNumberOfComponents()); - ParaMEDMEM::MEDCouplingAutoRefCountObjectPtr ret=ParaMEDMEM::DataArrayDouble::Divide(aaa,self->getArray()); - ParaMEDMEM::MEDCouplingAutoRefCountObjectPtr ret2=self->clone(false); - ret2->setArray(ret); - return ret2.retn(); - } - case 4: - { - if(!self->getArray()) - throw INTERP_KERNEL::Exception(msg2); - ParaMEDMEM::MEDCouplingAutoRefCountObjectPtr aaa=ParaMEDMEM::DataArrayDouble::New(); aaa->useArray(&bb[0],false,ParaMEDMEM::CPP_DEALLOC,1,(int)bb.size()); - ParaMEDMEM::MEDCouplingAutoRefCountObjectPtr ret=ParaMEDMEM::DataArrayDouble::Divide(aaa,self->getArray()); - ParaMEDMEM::MEDCouplingAutoRefCountObjectPtr ret2=self->clone(false); - ret2->setArray(ret); - return ret2.retn(); - } - default: - { throw INTERP_KERNEL::Exception(msg); } - } -} - -static PyObject *NewMethWrapCallInitOnlyIfEmptyDictInInput(PyObject *cls, PyObject *args, const char *clsName) -{ - if(!PyTuple_Check(args)) - { - std::ostringstream oss; oss << clsName << ".__new__ : the args in input is expected to be a tuple !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - PyObject *builtinsd(PyEval_GetBuiltins());//borrowed - PyObject *obj(PyDict_GetItemString(builtinsd,"object"));//borrowed - PyObject *selfMeth(PyObject_GetAttrString(obj,"__new__")); - // - PyObject *tmp0(PyTuple_New(1)); - PyTuple_SetItem(tmp0,0,cls); Py_XINCREF(cls); - PyObject *instance(PyObject_CallObject(selfMeth,tmp0)); - Py_DECREF(tmp0); - Py_DECREF(selfMeth); - if(PyTuple_Size(args)==2 && PyDict_Check(PyTuple_GetItem(args,1)) && PyDict_Size(PyTuple_GetItem(args,1))==0 ) - {// NOT general case. only true if in unpickeling context ! call __init__. Because for all other cases, __init__ is called right after __new__ ! - PyObject *initMeth(PyObject_GetAttrString(instance,"__init__")); - PyObject *tmp3(PyTuple_New(0)); - PyObject *tmp2(PyObject_CallObject(initMeth,tmp3)); - Py_XDECREF(tmp2); - Py_DECREF(tmp3); - Py_DECREF(initMeth); - } - return instance; -} diff --git a/src/MEDLoader/CMakeLists.txt b/src/MEDLoader/CMakeLists.txt deleted file mode 100644 index 40538ed30..000000000 --- a/src/MEDLoader/CMakeLists.txt +++ /dev/null @@ -1,84 +0,0 @@ -# Copyright (C) 2012-2015 CEA/DEN, EDF 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, 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 -# 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) - -ADD_DEFINITIONS(${HDF5_DEFINITIONS} ${MEDFILE_DEFINITIONS} ${XDR_DEFINITIONS}) - -IF(SALOME_MED_ENABLE_PYTHON) - ADD_SUBDIRECTORY(Swig) -ENDIF(SALOME_MED_ENABLE_PYTHON) - -IF(SALOME_BUILD_TESTS) - ADD_SUBDIRECTORY(Test) -ENDIF(SALOME_BUILD_TESTS) - -SET(MEDLOADER_XDR_INCLUDE_DIRS) -SET(MEDLOADER_XDR_LIBRARIES) - -IF(WIN32) - IF(SALOME_MED_MEDLOADER_USE_XDR) - ADD_DEFINITIONS(-DNOMINMAX) - SET(MEDLOADER_XDR_INCLUDE_DIRS ${XDR_INCLUDE_DIRS}) - SET(MEDLOADER_XDR_LIBRARIES ${XDR_LIBRARIES}) - ENDIF(SALOME_MED_MEDLOADER_USE_XDR) -ELSE(WIN32) - SET(MEDLOADER_XDR_INCLUDE_DIRS ${XDR_INCLUDE_DIRS}) -ENDIF(WIN32) - -INCLUDE_DIRECTORIES( - ${MEDFILE_INCLUDE_DIRS} - ${HDF5_INCLUDE_DIRS} - ${MEDLOADER_XDR_INCLUDE_DIRS} - ${CMAKE_CURRENT_SOURCE_DIR}/../MEDCoupling - ${CMAKE_CURRENT_SOURCE_DIR}/../INTERP_KERNEL - ${CMAKE_CURRENT_SOURCE_DIR}/../INTERP_KERNEL/Bases - ${CMAKE_CURRENT_SOURCE_DIR}/../INTERP_KERNEL/Geometric2D - ${CMAKE_CURRENT_SOURCE_DIR}/../INTERP_KERNEL/ExprEval - ${CMAKE_CURRENT_SOURCE_DIR}/../INTERP_KERNEL/GaussPoints - ) - -SET(medloader_SOURCES - MEDLoader.cxx - MEDLoaderBase.cxx - MEDFileUtilities.cxx - MEDFileMesh.cxx - MEDFileMeshElt.cxx - MEDFileBasis.cxx - MEDFileMeshLL.cxx - MEDFileField.cxx - MEDFileJoint.cxx - MEDFileParameter.cxx - MEDFileData.cxx - MEDFileFieldOverView.cxx - MEDFileMeshReadSelector.cxx - SauvMedConvertor.cxx - SauvReader.cxx - SauvWriter.cxx - ) - -ADD_LIBRARY(medloader SHARED ${medloader_SOURCES}) -SET_TARGET_PROPERTIES(medloader PROPERTIES COMPILE_FLAGS "") -TARGET_LINK_LIBRARIES(medloader medcoupling ${MEDFILE_C_LIBRARIES} ${HDF5_LIBRARIES} ${MEDLOADER_XDR_LIBRARIES}) -INSTALL(TARGETS medloader EXPORT ${PROJECT_NAME}TargetGroup DESTINATION ${SALOME_INSTALL_LIBS}) - -FILE(GLOB medloader_HEADERS_HXX "${CMAKE_CURRENT_SOURCE_DIR}/*.hxx") -INSTALL(FILES ${medloader_HEADERS_HXX} DESTINATION ${SALOME_INSTALL_HEADERS}) - -# To allow usage as SWIG dependencies: -SET(medloader_HEADERS_HXX PARENT_SCOPE) diff --git a/src/MEDLoader/MEDFileBasis.cxx b/src/MEDLoader/MEDFileBasis.cxx deleted file mode 100644 index 8e61dfb0e..000000000 --- a/src/MEDLoader/MEDFileBasis.cxx +++ /dev/null @@ -1,49 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 -// 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 "MEDFileBasis.hxx" - -#include - -using namespace ParaMEDMEM; - -MEDFileString::MEDFileString(int maxLgth):_max_lgth(maxLgth),_content(new char[maxLgth+1]) -{ - std::fill(_content,_content+maxLgth+1,'\0'); -} - -MEDFileString::~MEDFileString() -{ - delete [] _content; -} - -void MEDFileString::set(const char *s) -{ - if((int)strlen(s)>_max_lgth) - throw INTERP_KERNEL::Exception("Name is too long to be stored in MEDfile !"); - std::fill(_content,_content+_max_lgth+1,'\0'); - strcpy(_content,s); -} - -std::string MEDFileString::getRepr() const -{ - return std::string(_content); -} - diff --git a/src/MEDLoader/MEDFileBasis.hxx b/src/MEDLoader/MEDFileBasis.hxx deleted file mode 100644 index 41f402787..000000000 --- a/src/MEDLoader/MEDFileBasis.hxx +++ /dev/null @@ -1,62 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 -// 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 __MEDFILEBASIS_HXX__ -#define __MEDFILEBASIS_HXX__ - -#include "InterpKernelException.hxx" - -#include -#include - -namespace ParaMEDMEM -{ - class MEDFileString - { - public: - MEDFileString(int maxLgth); - ~MEDFileString(); - void set(const char *s); - char *getPointer() { return _content; } - const char *getReprForWrite() const { return _content; } - std::string getRepr() const; - private: - int _max_lgth; - char *_content; - }; - - - class MEDFileMultiString - { - public: - MEDFileMultiString(int nbOfCompo, int maxLgthPerCompo); - ~MEDFileMultiString(); - void set(int compoId, const char *s); - const char *getReprForWrite() const; - std::vector getRepr() const; - std::string getReprPerComp(int compId) const; - private: - int _nb_of_comp; - int _max_lgth_per_comp; - char *_content; - }; -} - -#endif diff --git a/src/MEDLoader/MEDFileData.cxx b/src/MEDLoader/MEDFileData.cxx deleted file mode 100644 index a979b38f5..000000000 --- a/src/MEDLoader/MEDFileData.cxx +++ /dev/null @@ -1,252 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 -// 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 "MEDFileData.hxx" - -using namespace ParaMEDMEM; - -MEDFileData *MEDFileData::New(const std::string& fileName) -{ - return new MEDFileData(fileName); -} - -MEDFileData *MEDFileData::New() -{ - return new MEDFileData; -} - -MEDFileData *MEDFileData::deepCpy() const -{ - MEDCouplingAutoRefCountObjectPtr fields; - if((const MEDFileFields *)_fields) - fields=_fields->deepCpy(); - MEDCouplingAutoRefCountObjectPtr meshes; - if((const MEDFileMeshes *)_meshes) - meshes=_meshes->deepCpy(); - MEDCouplingAutoRefCountObjectPtr params; - if((const MEDFileParameters *)_params) - params=_params->deepCpy(); - MEDCouplingAutoRefCountObjectPtr joints; - MEDCouplingAutoRefCountObjectPtr ret=MEDFileData::New(); - ret->_fields=fields; ret->_meshes=meshes; ret->_params=params; - return ret.retn(); -} - -std::size_t MEDFileData::getHeapMemorySizeWithoutChildren() const -{ - return 0; -} - -std::vector MEDFileData::getDirectChildrenWithNull() const -{ - std::vector ret; - ret.push_back((const MEDFileFields *)_fields); - ret.push_back((const MEDFileMeshes *)_meshes); - ret.push_back((const MEDFileParameters *)_params); - return ret; - -} - -/** Return a borrowed reference (caller is not responsible for object destruction) */ -MEDFileFields *MEDFileData::getFields() const -{ - return const_cast(static_cast(_fields)); -} - -/** Return a borrowed reference (caller is not responsible for object destruction) */ -MEDFileMeshes *MEDFileData::getMeshes() const -{ - return const_cast(static_cast(_meshes)); -} - -/** Return a borrowed reference (caller is not responsible for object destruction) */ -MEDFileParameters *MEDFileData::getParams() const -{ - return const_cast(static_cast(_params)); -} - -void MEDFileData::setFields(MEDFileFields *fields) -{ - if(fields) - fields->incrRef(); - _fields=fields; -} - -void MEDFileData::setMeshes(MEDFileMeshes *meshes) -{ - if(meshes) - meshes->incrRef(); - _meshes=meshes; -} - -void MEDFileData::setParams(MEDFileParameters *params) -{ - if(params) - params->incrRef(); - _params=params; -} - -int MEDFileData::getNumberOfFields() const -{ - const MEDFileFields *f=_fields; - if(!f) - throw INTERP_KERNEL::Exception("MEDFileData::getNumberOfFields : no fields set !"); - return f->getNumberOfFields(); -} - -int MEDFileData::getNumberOfMeshes() const -{ - const MEDFileMeshes *m=_meshes; - if(!m) - throw INTERP_KERNEL::Exception("MEDFileData::getNumberOfMeshes : no meshes set !"); - return m->getNumberOfMeshes(); -} - -int MEDFileData::getNumberOfParams() const -{ - const MEDFileParameters *p=_params; - if(!p) - throw INTERP_KERNEL::Exception("MEDFileData::getNumberOfParams : no params set !"); - return p->getNumberOfParams(); -} - -std::string MEDFileData::simpleRepr() const -{ - std::ostringstream oss; - oss << "(***************)\n(* MEDFileData *)\n(***************)\n\nFields part :\n*************\n\n"; - const MEDFileFields *tmp=_fields; - if(tmp) - { - tmp->simpleRepr(0,oss); - oss << std::endl; - } - else - oss << "No fields set !!!\n\n"; - oss << "Meshes part :\n*************\n\n"; - const MEDFileMeshes *tmp2=_meshes; - if(tmp2) - { - tmp2->simpleReprWithoutHeader(oss); - } - else - oss << "No meshes set !!!\n\n"; - oss << "Params part :\n*************\n\n"; - const MEDFileParameters *tmp3=_params; - if(tmp3) - { - tmp3->simpleReprWithoutHeader(oss); - } - else - oss << "No params set !!!\n"; - return oss.str(); -} - -bool MEDFileData::changeMeshNames(const std::vector< std::pair >& modifTab) -{ - bool ret=false; - MEDFileFields *fields=_fields; - if(fields) - ret=fields->changeMeshNames(modifTab) || ret; - MEDFileMeshes *meshes=_meshes; - if(meshes) - ret=meshes->changeNames(modifTab) || ret; - return ret; -} - -bool MEDFileData::changeMeshName(const std::string& oldMeshName, const std::string& newMeshName) -{ - std::string oldName(oldMeshName); - std::vector< std::pair > v(1); - v[0].first=oldName; v[0].second=newMeshName; - return changeMeshNames(v); -} - -/*! - * This method performs unpolyzation in meshes in \a this and if it leads to a modification to one or more than one meshes in \a this - * the fields are automatically renumbered (for those impacted, that is to say here fields on cells and fields on gauss points on impacted fields) - * - * \return If true is returned it means that some meshes in \a this has been modified and eventually fields have been renumbered. - * \n If false \a this remains unchanged. - */ -bool MEDFileData::unPolyzeMeshes() -{ - MEDFileMeshes *ms=_meshes; - if(!ms) - return false; - std::vector< MEDFileMesh * > meshesImpacted; - std::vector< DataArrayInt * > renumParamsOfMeshImpacted;//same size as meshesImpacted - std::vector< std::vector > oldCodeOfMeshImpacted,newCodeOfMeshImpacted;//same size as meshesImpacted - std::vector > memSaverIfThrow;//same size as meshesImpacted - for(int i=0;igetNumberOfMeshes();i++) - { - MEDFileMesh *m=ms->getMeshAtPos(i); - if(m) - { - std::vector oldCode,newCode; - DataArrayInt *o2nRenumCell=0; - bool modif=m->unPolyze(oldCode,newCode,o2nRenumCell); - if(!modif) - continue; - renumParamsOfMeshImpacted.push_back(o2nRenumCell); memSaverIfThrow.push_back(o2nRenumCell); - oldCodeOfMeshImpacted.push_back(oldCode); - newCodeOfMeshImpacted.push_back(newCode); - meshesImpacted.push_back(m); - } - } - if(!meshesImpacted.empty()) - { - MEDFileFields *fs=_fields; - if(fs) - for(std::size_t i=0;irenumberEntitiesLyingOnMesh(meshesImpacted[i]->getName(),oldCodeOfMeshImpacted[i],newCodeOfMeshImpacted[i],renumParamsOfMeshImpacted[i]); - } - return !meshesImpacted.empty(); -} - -MEDFileData::MEDFileData() -{ -} - -MEDFileData::MEDFileData(const std::string& fileName) -try -{ - _fields=MEDFileFields::New(fileName); - _meshes=MEDFileMeshes::New(fileName); - _params=MEDFileParameters::New(fileName); -} -catch(INTERP_KERNEL::Exception& e) -{ - throw e; -} - -void MEDFileData::write(const std::string& fileName, int mode) const -{ - med_access_mode medmod=MEDFileUtilities::TraduceWriteMode(mode); - MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName.c_str(),medmod); - const MEDFileMeshes *ms=_meshes; - if(ms) - ms->write(fid); - const MEDFileFields *fs=_fields; - if(fs) - fs->writeLL(fid); - const MEDFileParameters *ps=_params; - if(ps) - ps->writeLL(fid); -} diff --git a/src/MEDLoader/MEDFileData.hxx b/src/MEDLoader/MEDFileData.hxx deleted file mode 100644 index ce7a2ea36..000000000 --- a/src/MEDLoader/MEDFileData.hxx +++ /dev/null @@ -1,68 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 -// 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 __MEDFILEDATA_HXX__ -#define __MEDFILEDATA_HXX__ - -#include "MEDCouplingAutoRefCountObjectPtr.hxx" -#include "MEDFileParameter.hxx" -#include "MEDFileField.hxx" -#include "MEDFileMesh.hxx" - -namespace ParaMEDMEM -{ - /*! - * User class. - */ - class MEDFileData : public RefCountObject, public MEDFileWritable - { - public: - MEDLOADER_EXPORT static MEDFileData *New(const std::string& fileName); - MEDLOADER_EXPORT static MEDFileData *New(); - MEDLOADER_EXPORT MEDFileData *deepCpy() const; - MEDLOADER_EXPORT std::size_t getHeapMemorySizeWithoutChildren() const; - MEDLOADER_EXPORT std::vector getDirectChildrenWithNull() const; - MEDLOADER_EXPORT MEDFileFields *getFields() const; - MEDLOADER_EXPORT MEDFileMeshes *getMeshes() const; - MEDLOADER_EXPORT MEDFileParameters *getParams() const; - MEDLOADER_EXPORT void setFields(MEDFileFields *fields); - MEDLOADER_EXPORT void setMeshes(MEDFileMeshes *meshes); - MEDLOADER_EXPORT void setParams(MEDFileParameters *params); - MEDLOADER_EXPORT int getNumberOfFields() const; - MEDLOADER_EXPORT int getNumberOfMeshes() const; - MEDLOADER_EXPORT int getNumberOfParams() const; - MEDLOADER_EXPORT std::string simpleRepr() const; - // - MEDLOADER_EXPORT bool changeMeshNames(const std::vector< std::pair >& modifTab); - MEDLOADER_EXPORT bool changeMeshName(const std::string& oldMeshName, const std::string& newMeshName); - MEDLOADER_EXPORT bool unPolyzeMeshes(); - // - MEDLOADER_EXPORT void write(const std::string& fileName, int mode) const; - private: - MEDFileData(); - MEDFileData(const std::string& fileName); - private: - MEDCouplingAutoRefCountObjectPtr _fields; - MEDCouplingAutoRefCountObjectPtr _meshes; - MEDCouplingAutoRefCountObjectPtr _params; - }; -} - -#endif diff --git a/src/MEDLoader/MEDFileField.cxx b/src/MEDLoader/MEDFileField.cxx deleted file mode 100644 index 932e70028..000000000 --- a/src/MEDLoader/MEDFileField.cxx +++ /dev/null @@ -1,10491 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 -// 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 "MEDFileField.hxx" -#include "MEDFileMesh.hxx" -#include "MEDLoaderBase.hxx" -#include "MEDFileUtilities.hxx" -#include "MEDFileSafeCaller.txx" -#include "MEDFileFieldOverView.hxx" - -#include "MEDCouplingFieldDouble.hxx" -#include "MEDCouplingFieldDiscretization.hxx" - -#include "InterpKernelAutoPtr.hxx" -#include "CellModel.hxx" - -#include -#include - -extern med_geometry_type typmai[MED_N_CELL_FIXED_GEO]; -extern INTERP_KERNEL::NormalizedCellType typmai2[MED_N_CELL_FIXED_GEO]; -extern med_geometry_type typmainoeud[1]; -extern med_geometry_type typmai3[34]; - -using namespace ParaMEDMEM; - -const char MEDFileField1TSWithoutSDA::TYPE_STR[]="FLOAT64"; -const char MEDFileIntField1TSWithoutSDA::TYPE_STR[]="INT32"; - -MEDFileFieldLoc *MEDFileFieldLoc::New(med_idt fid, const std::string& locName) -{ - return new MEDFileFieldLoc(fid,locName); -} - -MEDFileFieldLoc *MEDFileFieldLoc::New(med_idt fid, int id) -{ - return new MEDFileFieldLoc(fid,id); -} - -MEDFileFieldLoc *MEDFileFieldLoc::New(const std::string& locName, INTERP_KERNEL::NormalizedCellType geoType, const std::vector& refCoo, const std::vector& gsCoo, const std::vector& w) -{ - return new MEDFileFieldLoc(locName,geoType,refCoo,gsCoo,w); -} - -MEDFileFieldLoc::MEDFileFieldLoc(med_idt fid, const std::string& locName):_name(locName) -{ - med_geometry_type geotype; - med_geometry_type sectiongeotype; - int nsectionmeshcell; - INTERP_KERNEL::AutoPtr geointerpname=MEDLoaderBase::buildEmptyString(MED_NAME_SIZE); - INTERP_KERNEL::AutoPtr sectionmeshname=MEDLoaderBase::buildEmptyString(MED_NAME_SIZE); - MEDlocalizationInfoByName(fid,locName.c_str(),&geotype,&_dim,&_nb_gauss_pt,geointerpname,sectionmeshname,&nsectionmeshcell,§iongeotype); - _geo_type=(INTERP_KERNEL::NormalizedCellType)(std::distance(typmai3,std::find(typmai3,typmai3+34,geotype))); - const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(_geo_type); - _nb_node_per_cell=cm.getNumberOfNodes(); - _ref_coo.resize(_dim*_nb_node_per_cell); - _gs_coo.resize(_dim*_nb_gauss_pt); - _w.resize(_nb_gauss_pt); - MEDlocalizationRd(fid,locName.c_str(),MED_FULL_INTERLACE,&_ref_coo[0],&_gs_coo[0],&_w[0]); -} - -MEDFileFieldLoc::MEDFileFieldLoc(med_idt fid, int id) -{ - med_geometry_type geotype; - med_geometry_type sectiongeotype; - int nsectionmeshcell; - INTERP_KERNEL::AutoPtr locName=MEDLoaderBase::buildEmptyString(MED_NAME_SIZE); - INTERP_KERNEL::AutoPtr geointerpname=MEDLoaderBase::buildEmptyString(MED_NAME_SIZE); - INTERP_KERNEL::AutoPtr sectionmeshname=MEDLoaderBase::buildEmptyString(MED_NAME_SIZE); - MEDlocalizationInfo(fid,id+1,locName,&geotype,&_dim,&_nb_gauss_pt,geointerpname,sectionmeshname,&nsectionmeshcell,§iongeotype); - _name=locName; - _geo_type=(INTERP_KERNEL::NormalizedCellType)(std::distance(typmai3,std::find(typmai3,typmai3+34,geotype))); - const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(_geo_type); - _nb_node_per_cell=cm.getNumberOfNodes(); - _ref_coo.resize(_dim*_nb_node_per_cell); - _gs_coo.resize(_dim*_nb_gauss_pt); - _w.resize(_nb_gauss_pt); - MEDlocalizationRd(fid,locName,MED_FULL_INTERLACE,&_ref_coo[0],&_gs_coo[0],&_w[0]); -} - -MEDFileFieldLoc::MEDFileFieldLoc(const std::string& locName, INTERP_KERNEL::NormalizedCellType geoType, - const std::vector& refCoo, const std::vector& gsCoo, const std::vector& w):_name(locName),_geo_type(geoType),_ref_coo(refCoo),_gs_coo(gsCoo), - _w(w) -{ - const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(_geo_type); - _dim=cm.getDimension(); - _nb_node_per_cell=cm.getNumberOfNodes(); - _nb_gauss_pt=_w.size(); -} - -MEDFileFieldLoc *MEDFileFieldLoc::deepCpy() const -{ - return new MEDFileFieldLoc(*this); -} - -std::size_t MEDFileFieldLoc::getHeapMemorySizeWithoutChildren() const -{ - return (_ref_coo.capacity()+_gs_coo.capacity()+_w.capacity())*sizeof(double)+_name.capacity(); -} - -std::vector MEDFileFieldLoc::getDirectChildrenWithNull() const -{ - return std::vector(); -} - -void MEDFileFieldLoc::simpleRepr(std::ostream& oss) const -{ - static const char OFF7[]="\n "; - oss << "\"" << _name << "\"" << OFF7; - oss << "GeoType=" << INTERP_KERNEL::CellModel::GetCellModel(_geo_type).getRepr() << OFF7; - oss << "Dimension=" << _dim << OFF7; - oss << "Number of Gauss points=" << _nb_gauss_pt << OFF7; - oss << "Number of nodes per cell=" << _nb_node_per_cell << OFF7; - oss << "RefCoords="; std::copy(_ref_coo.begin(),_ref_coo.end(),std::ostream_iterator(oss," ")); oss << OFF7; - oss << "Weights="; std::copy(_w.begin(),_w.end(),std::ostream_iterator(oss," ")); oss << OFF7; - oss << "GaussPtsCoords="; std::copy(_gs_coo.begin(),_gs_coo.end(),std::ostream_iterator(oss," ")); oss << std::endl; -} - -void MEDFileFieldLoc::setName(const std::string& name) -{ - _name=name; -} - -bool MEDFileFieldLoc::isEqual(const MEDFileFieldLoc& other, double eps) const -{ - if(_name!=other._name) - return false; - if(_dim!=other._dim) - return false; - if(_nb_gauss_pt!=other._nb_gauss_pt) - return false; - if(_nb_node_per_cell!=other._nb_node_per_cell) - return false; - if(_geo_type!=other._geo_type) - return false; - if(!MEDCouplingGaussLocalization::AreAlmostEqual(_ref_coo,other._ref_coo,eps)) - return false; - if(!MEDCouplingGaussLocalization::AreAlmostEqual(_gs_coo,other._gs_coo,eps)) - return false; - if(!MEDCouplingGaussLocalization::AreAlmostEqual(_w,other._w,eps)) - return false; - - return true; -} - -void MEDFileFieldLoc::writeLL(med_idt fid) const -{ - MEDlocalizationWr(fid,_name.c_str(),typmai3[(int)_geo_type],_dim,&_ref_coo[0],MED_FULL_INTERLACE,_nb_gauss_pt,&_gs_coo[0],&_w[0],MED_NO_INTERPOLATION,MED_NO_MESH_SUPPORT); -} - -std::string MEDFileFieldLoc::repr() const -{ - std::ostringstream oss; oss.precision(15); - const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(_geo_type); - oss << "Localization \"" << _name << "\" :\n" << " - Geometric Type : " << cm.getRepr(); - oss << "\n - Dimension : " << _dim << "\n - Number of gauss points : "; - oss << _nb_gauss_pt << "\n - Number of nodes in cell : " << _nb_node_per_cell; - oss << "\n - Ref coords are : "; - int sz=_ref_coo.size(); - if(sz%_dim==0) - { - int nbOfTuples=sz/_dim; - for(int i=0;i(oss," ")); - oss << "\n - Gauss coords in reference element : "; - sz=_gs_coo.size(); - if(sz%_dim==0) - { - int nbOfTuples=sz/_dim; - for(int i=0;i(oss," ")); - oss << "\n - Weights of Gauss coords are : "; std::copy(_w.begin(),_w.end(),std::ostream_iterator(oss," ")); - return oss.str(); -} - -void MEDFileFieldPerMeshPerTypePerDisc::assignFieldNoProfile(int& start, int offset, int nbOfCells, const MEDCouplingFieldDouble *field, const DataArray *arrr, MEDFileFieldGlobsReal& glob, const MEDFileFieldNameScope& nasc) -{ - _type=field->getTypeOfField(); - _start=start; - switch(_type) - { - case ON_CELLS: - { - getOrCreateAndGetArray()->setContigPartOfSelectedValues2(_start,arrr,offset,offset+nbOfCells,1); - _end=_start+nbOfCells; - _nval=nbOfCells; - break; - } - case ON_GAUSS_NE: - { - MEDCouplingAutoRefCountObjectPtr arr=field->getDiscretization()->getOffsetArr(field->getMesh()); - const int *arrPtr=arr->getConstPointer(); - getOrCreateAndGetArray()->setContigPartOfSelectedValues2(_start,arrr,arrPtr[offset],arrPtr[offset+nbOfCells],1); - _end=_start+(arrPtr[offset+nbOfCells]-arrPtr[offset]); - _nval=nbOfCells; - break; - } - case ON_GAUSS_PT: - { - const MEDCouplingFieldDiscretization *disc=field->getDiscretization(); - const MEDCouplingGaussLocalization& gsLoc=field->getGaussLocalization(_loc_id); - const MEDCouplingFieldDiscretizationGauss *disc2=dynamic_cast(disc); - if(!disc2) - throw INTERP_KERNEL::Exception("assignFieldNoProfile : invalid call to this method ! Internal Error !"); - const DataArrayInt *dai=disc2->getArrayOfDiscIds(); - MEDCouplingAutoRefCountObjectPtr dai2=disc2->getOffsetArr(field->getMesh()); - const int *dai2Ptr=dai2->getConstPointer(); - int nbi=gsLoc.getWeights().size(); - MEDCouplingAutoRefCountObjectPtr da2=dai->selectByTupleId2(offset,offset+nbOfCells,1); - MEDCouplingAutoRefCountObjectPtr da3=da2->getIdsEqual(_loc_id); - const int *da3Ptr=da3->getConstPointer(); - if(da3->getNumberOfTuples()!=nbOfCells) - {//profile : for gauss even in NoProfile !!! - std::ostringstream oss; oss << "Pfl_" << nasc.getName() << "_" << INTERP_KERNEL::CellModel::GetCellModel(getGeoType()).getRepr() << "_" << _loc_id; - _profile=oss.str(); - da3->setName(_profile.c_str()); - glob.appendProfile(da3); - } - MEDCouplingAutoRefCountObjectPtr da4=DataArrayInt::New(); - _nval=da3->getNbOfElems(); - da4->alloc(_nval*nbi,1); - int *da4Ptr=da4->getPointer(); - for(int i=0;i<_nval;i++) - { - int ref=dai2Ptr[offset+da3Ptr[i]]; - for(int j=0;jsetContigPartOfSelectedValues(_start,arrr,da4); - _end=_start+_nval*nbi; - glob.appendLoc(_localization.c_str(),getGeoType(),gsLoc.getRefCoords(),gsLoc.getGaussCoords(),gsLoc.getWeights()); - break; - } - default: - throw INTERP_KERNEL::Exception("MEDFileFieldPerMeshPerTypePerDisc::assignFieldNoProfile : not implemented yet for such discretization type of field !"); - } - start=_end; -} - -/*! - * Leaf method of field with profile assignement. This method is the most general one. No optimization is done here. - * \param [in] pflName input containing name of profile if any. 0 if no profile (except for GAUSS_PT where a no profile can hide a profile when splitted by loc_id). - * \param [in] multiTypePfl is the end user profile specified in high level API - * \param [in] idsInPfl is the selection into the \a multiTypePfl whole profile that corresponds to the current geometric type. - * \param [in] locIds is the profile needed to be created for MED file format. It can be null if all cells of current geometric type are fetched in \a multiTypePfl. - * \b WARNING if not null the MED file profile can be subdivided again in case of Gauss points. - * \param [in] mesh is the mesh coming from the MEDFileMesh instance in correspondance with the MEDFileField. The mesh inside the \a field is simply ignored. - */ -void MEDFileFieldPerMeshPerTypePerDisc::assignFieldProfile(bool isPflAlone, int& start, const DataArrayInt *multiTypePfl, const DataArrayInt *idsInPfl, DataArrayInt *locIds, int nbOfEltsInWholeMesh, const MEDCouplingFieldDouble *field, const DataArray *arrr, const MEDCouplingMesh *mesh, MEDFileFieldGlobsReal& glob, const MEDFileFieldNameScope& nasc) -{ - _profile.clear(); - _type=field->getTypeOfField(); - std::string pflName(multiTypePfl->getName()); - std::ostringstream oss; oss << pflName; - if(_type!=ON_NODES) - { - if(!isPflAlone) - { const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(getGeoType()); oss << "_" << cm.getRepr(); } - } - else - { oss << "_NODE"; } - if(locIds) - { - if(pflName.empty()) - throw INTERP_KERNEL::Exception("MEDFileFieldPerMeshPerTypePerDisc::assignFieldProfile : existing profile with empty name !"); - if(_type!=ON_GAUSS_PT) - { - locIds->setName(oss.str().c_str()); - glob.appendProfile(locIds); - _profile=oss.str(); - } - } - _start=start; - switch(_type) - { - case ON_NODES: - { - _nval=idsInPfl->getNumberOfTuples(); - getOrCreateAndGetArray()->setContigPartOfSelectedValues2(_start,arrr,0,arrr->getNumberOfTuples(),1); - _end=_start+_nval; - break; - } - case ON_CELLS: - { - _nval=idsInPfl->getNumberOfTuples(); - getOrCreateAndGetArray()->setContigPartOfSelectedValues(_start,arrr,idsInPfl); - _end=_start+_nval; - break; - } - case ON_GAUSS_NE: - { - MEDCouplingAutoRefCountObjectPtr arr=field->getDiscretization()->getOffsetArr(mesh); - MEDCouplingAutoRefCountObjectPtr arr2=arr->deltaShiftIndex(); - MEDCouplingAutoRefCountObjectPtr arr3=arr2->selectByTupleId(multiTypePfl->begin(),multiTypePfl->end()); - arr3->computeOffsets2(); - MEDCouplingAutoRefCountObjectPtr tmp=idsInPfl->buildExplicitArrByRanges(arr3); - int trueNval=tmp->getNumberOfTuples(); - _nval=idsInPfl->getNumberOfTuples(); - getOrCreateAndGetArray()->setContigPartOfSelectedValues(_start,arrr,tmp); - _end=_start+trueNval; - break; - } - case ON_GAUSS_PT: - { - const MEDCouplingFieldDiscretizationGauss *disc2=dynamic_cast(field->getDiscretization()); - if(!disc2) - throw INTERP_KERNEL::Exception("addNewEntryIfNecessaryGauss : invalid call to this method ! Internal Error !"); - const DataArrayInt *da1=disc2->getArrayOfDiscIds(); - const MEDCouplingGaussLocalization& gsLoc=field->getGaussLocalization(_loc_id); - MEDCouplingAutoRefCountObjectPtr da2=da1->selectByTupleId(idsInPfl->begin(),idsInPfl->end()); - MEDCouplingAutoRefCountObjectPtr da3=da2->getIdsEqual(_loc_id); - MEDCouplingAutoRefCountObjectPtr da4=idsInPfl->selectByTupleId(da3->begin(),da3->end()); - // - MEDCouplingAutoRefCountObjectPtr mesh2=mesh->buildPart(multiTypePfl->begin(),multiTypePfl->end()); - MEDCouplingAutoRefCountObjectPtr arr=disc2->getOffsetArr(mesh2); - // - MEDCouplingAutoRefCountObjectPtr tmp=DataArrayInt::New(); - int trueNval=0; - for(const int *pt=da4->begin();pt!=da4->end();pt++) - trueNval+=arr->getIJ(*pt+1,0)-arr->getIJ(*pt,0); - tmp->alloc(trueNval,1); - int *tmpPtr=tmp->getPointer(); - for(const int *pt=da4->begin();pt!=da4->end();pt++) - for(int j=arr->getIJ(*pt,0);jgetIJ(*pt+1,0);j++) - *tmpPtr++=j; - // - _nval=da4->getNumberOfTuples(); - getOrCreateAndGetArray()->setContigPartOfSelectedValues(_start,arrr,tmp); - _end=_start+trueNval; - oss << "_loc_" << _loc_id; - if(locIds) - { - MEDCouplingAutoRefCountObjectPtr da5=locIds->selectByTupleId(da3->begin(),da3->end()); - da5->setName(oss.str().c_str()); - glob.appendProfile(da5); - _profile=oss.str(); - } - else - { - if(da3->getNumberOfTuples()!=nbOfEltsInWholeMesh || !da3->isIdentity()) - { - da3->setName(oss.str().c_str()); - glob.appendProfile(da3); - _profile=oss.str(); - } - } - std::ostringstream oss2; oss2 << "Loc_" << nasc.getName() << "_" << INTERP_KERNEL::CellModel::GetCellModel(getGeoType()).getRepr() << "_" << _loc_id; - _localization=oss2.str(); - glob.appendLoc(_localization.c_str(),getGeoType(),gsLoc.getRefCoords(),gsLoc.getGaussCoords(),gsLoc.getWeights()); - break; - } - default: - throw INTERP_KERNEL::Exception("MEDFileFieldPerMeshPerTypePerDisc::assignFieldProfile : not implemented yet for such discretization type of field !"); - } - start=_end; -} - -void MEDFileFieldPerMeshPerTypePerDisc::assignNodeFieldNoProfile(int& start, const MEDCouplingFieldDouble *field, const DataArray *arrr, MEDFileFieldGlobsReal& glob) -{ - _start=start; - _nval=arrr->getNumberOfTuples(); - getOrCreateAndGetArray()->setContigPartOfSelectedValues2(_start,arrr,0,_nval,1); - _end=_start+_nval; - start=_end; -} - -MEDFileFieldPerMeshPerTypePerDisc *MEDFileFieldPerMeshPerTypePerDisc::NewOnRead(MEDFileFieldPerMeshPerType *fath, TypeOfField type, int profileIt, const PartDefinition *pd) -{ - return new MEDFileFieldPerMeshPerTypePerDisc(fath,type,profileIt,pd); -} - -MEDFileFieldPerMeshPerTypePerDisc *MEDFileFieldPerMeshPerTypePerDisc::New(MEDFileFieldPerMeshPerType *fath, TypeOfField type, int locId) -{ - return new MEDFileFieldPerMeshPerTypePerDisc(fath,type,locId,std::string()); -} - -MEDFileFieldPerMeshPerTypePerDisc *MEDFileFieldPerMeshPerTypePerDisc::New(const MEDFileFieldPerMeshPerTypePerDisc& other) -{ - return new MEDFileFieldPerMeshPerTypePerDisc(other); -} - -std::size_t MEDFileFieldPerMeshPerTypePerDisc::getHeapMemorySizeWithoutChildren() const -{ - return _profile.capacity()+_localization.capacity()+sizeof(MEDFileFieldPerMeshPerTypePerDisc); -} - -std::vector MEDFileFieldPerMeshPerTypePerDisc::getDirectChildrenWithNull() const -{ - std::vector ret(1); - ret[0]=(const PartDefinition*)_pd; - return ret; -} - -MEDFileFieldPerMeshPerTypePerDisc *MEDFileFieldPerMeshPerTypePerDisc::deepCpy(MEDFileFieldPerMeshPerType *father) const -{ - MEDCouplingAutoRefCountObjectPtr ret=new MEDFileFieldPerMeshPerTypePerDisc(*this); - ret->_father=father; - return ret.retn(); -} - -MEDFileFieldPerMeshPerTypePerDisc::MEDFileFieldPerMeshPerTypePerDisc(MEDFileFieldPerMeshPerType *fath, TypeOfField atype, int profileIt, const PartDefinition *pd) -try:_type(atype),_father(fath),_profile_it(profileIt),_pd(const_cast(pd)) -{ - if(pd) - pd->incrRef(); -} -catch(INTERP_KERNEL::Exception& e) -{ - throw e; -} - -MEDFileFieldPerMeshPerTypePerDisc::MEDFileFieldPerMeshPerTypePerDisc(MEDFileFieldPerMeshPerType *fath, TypeOfField type, int locId, const std::string& dummy):_type(type),_father(fath),_loc_id(locId) -{ -} - -MEDFileFieldPerMeshPerTypePerDisc::MEDFileFieldPerMeshPerTypePerDisc(const MEDFileFieldPerMeshPerTypePerDisc& other):RefCountObject(other),_type(other._type),_father(0),_start(other._start),_end(other._end),_nval(other._nval),_profile(other._profile),_localization(other._localization),_loc_id(other._loc_id),_profile_it(other._profile_it),_pd(other._pd),_tmp_work1(other._tmp_work1) -{ -} - -MEDFileFieldPerMeshPerTypePerDisc::MEDFileFieldPerMeshPerTypePerDisc():_type(ON_CELLS),_father(0),_start(-std::numeric_limits::max()),_end(-std::numeric_limits::max()), - _nval(-std::numeric_limits::max()),_loc_id(-std::numeric_limits::max()) -{ -} - -void MEDFileFieldPerMeshPerTypePerDisc::goReadZeValuesInFile(med_idt fid, const std::string& fieldName, int nbOfCompo, int iteration, int order, med_entity_type menti, med_geometry_type mgeoti, unsigned char *startFeedingPtr) -{ - const PartDefinition *pd(_pd); - if(!pd) - { - INTERP_KERNEL::AutoPtr locname(MEDLoaderBase::buildEmptyString(MED_NAME_SIZE)); - int nbi,tmp1; - med_int nbValsInFile(MEDfieldnValueWithProfileByName(fid,fieldName.c_str(),iteration,order,menti,mgeoti,_profile.c_str(),MED_COMPACT_PFLMODE,&tmp1,locname,&nbi)); - if(_end-_start!=nbValsInFile*nbi) - { - std::ostringstream oss; oss << "MEDFileFieldPerMeshPerTypePerDisc::goReadZeValuesInFile : The number of tuples to read is " << nbValsInFile << "*" << nbi << " (nb integration points) ! But in data structure it values " << _end-_start << " is expected !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - MEDFILESAFECALLERRD0(MEDfieldValueWithProfileRd,(fid,fieldName.c_str(),iteration,order,menti,mgeoti,MED_COMPACT_PFLMODE,_profile.c_str(),MED_FULL_INTERLACE,MED_ALL_CONSTITUENT,startFeedingPtr)); - } - else - { - if(!_profile.empty()) - throw INTERP_KERNEL::Exception("MEDFileFieldPerMeshPerTypePerDisc::goReadZeValuesInFile : not implemented !"); - INTERP_KERNEL::AutoPtr pflname(MEDLoaderBase::buildEmptyString(MED_NAME_SIZE)),locname(MEDLoaderBase::buildEmptyString(MED_NAME_SIZE)); - int profilesize,nbi; - int overallNval(MEDfieldnValueWithProfile(fid,fieldName.c_str(),iteration,order,menti,mgeoti,_profile_it+1,MED_COMPACT_PFLMODE,pflname,&profilesize,locname,&nbi)); - const SlicePartDefinition *spd(dynamic_cast(pd)); - if(spd) - { - int start,stop,step; - spd->getSlice(start,stop,step); - int nbOfEltsToLoad(DataArray::GetNumberOfItemGivenBES(start,stop,step,"MEDFileFieldPerMeshPerTypePerDisc::goReadZeValuesInFile")); - med_filter filter=MED_FILTER_INIT; - MEDfilterBlockOfEntityCr(fid,/*nentity*/overallNval,/*nvaluesperentity*/nbi,/*nconstituentpervalue*/nbOfCompo, - MED_ALL_CONSTITUENT,MED_FULL_INTERLACE,MED_COMPACT_STMODE,MED_NO_PROFILE, - /*start*/start+1,/*stride*/step,/*count*/1,/*blocksize*/nbOfEltsToLoad, - /*lastblocksize=useless because count=1*/0,&filter); - MEDFILESAFECALLERRD0(MEDfieldValueAdvancedRd,(fid,fieldName.c_str(),iteration,order,menti,mgeoti,&filter,startFeedingPtr)); - MEDfilterClose(&filter); - return ; - } - const DataArrayPartDefinition *dpd(dynamic_cast(pd)); - if(dpd) - { - dpd->checkCoherency(); - MEDCouplingAutoRefCountObjectPtr myIds(dpd->toDAI()); - int a(myIds->getMinValueInArray()),b(myIds->getMaxValueInArray()); - myIds->applyLin(1,-a); - int nbOfEltsToLoad(b-a+1); - med_filter filter=MED_FILTER_INIT; - {//TODO : manage int32 ! - MEDCouplingAutoRefCountObjectPtr tmp(DataArrayDouble::New()); - tmp->alloc(nbOfEltsToLoad,nbOfCompo); - MEDfilterBlockOfEntityCr(fid,/*nentity*/overallNval,/*nvaluesperentity*/nbi,/*nconstituentpervalue*/nbOfCompo, - MED_ALL_CONSTITUENT,MED_FULL_INTERLACE,MED_COMPACT_STMODE,MED_NO_PROFILE, - /*start*/a+1,/*stride*/1,/*count*/1,/*blocksize*/nbOfEltsToLoad, - /*lastblocksize=useless because count=1*/0,&filter); - MEDFILESAFECALLERRD0(MEDfieldValueAdvancedRd,(fid,fieldName.c_str(),iteration,order,menti,mgeoti,&filter,reinterpret_cast(tmp->getPointer()))); - MEDCouplingAutoRefCountObjectPtr feeder(DataArrayDouble::New()); - feeder->useExternalArrayWithRWAccess(reinterpret_cast(startFeedingPtr),_nval,nbOfCompo); - feeder->setContigPartOfSelectedValues(0,tmp,myIds); - } - MEDfilterClose(&filter); - } - else - throw INTERP_KERNEL::Exception("Not implemented yet for not slices!"); - } -} - -const MEDFileFieldPerMeshPerType *MEDFileFieldPerMeshPerTypePerDisc::getFather() const -{ - return _father; -} - -void MEDFileFieldPerMeshPerTypePerDisc::loadOnlyStructureOfDataRecursively(med_idt fid, int& start, const MEDFileFieldNameScope& nasc) -{ - INTERP_KERNEL::AutoPtr locname(MEDLoaderBase::buildEmptyString(MED_NAME_SIZE)); - INTERP_KERNEL::AutoPtr pflname(MEDLoaderBase::buildEmptyString(MED_NAME_SIZE)); - std::string fieldName(nasc.getName()),meshName(getMeshName()); - int iteration(getIteration()),order(getOrder()); - TypeOfField type(getType()); - INTERP_KERNEL::NormalizedCellType geoType(getGeoType()); - int profilesize,nbi; - med_geometry_type mgeoti; - med_entity_type menti(MEDFileFieldPerMeshPerType::ConvertIntoMEDFileType(type,geoType,mgeoti)); - int zeNVal(MEDfieldnValueWithProfile(fid,fieldName.c_str(),iteration,order,menti,mgeoti,_profile_it+1,MED_COMPACT_PFLMODE,pflname,&profilesize,locname,&nbi)); - _profile=MEDLoaderBase::buildStringFromFortran(pflname,MED_NAME_SIZE); - _localization=MEDLoaderBase::buildStringFromFortran(locname,MED_NAME_SIZE); - const PartDefinition *pd(_pd); - if(!pd) - { - _nval=zeNVal; - } - else - { - if(!_profile.empty()) - throw INTERP_KERNEL::Exception("MEDFileFieldPerMeshPerTypePerDisc::loadOnlyStructureOfDataRecursively : profiles are not managed yet with part of def !"); - _nval=pd->getNumberOfElems(); - } - _start=start; - _end=start+_nval*nbi; - start=_end; - if(type==ON_CELLS && !_localization.empty()) - { - if(_localization!="MED_GAUSS_ELNO")//For compatibily with MED2.3 - setType(ON_GAUSS_PT); - else - { - setType(ON_GAUSS_NE); - _localization.clear(); - } - } -} - -void MEDFileFieldPerMeshPerTypePerDisc::loadBigArray(med_idt fid, const MEDFileFieldNameScope& nasc) -{ - std::string fieldName(nasc.getName()),meshName(getMeshName()); - int iteration(getIteration()),order(getOrder()); - TypeOfField type(getType()); - INTERP_KERNEL::NormalizedCellType geoType(getGeoType()); - med_geometry_type mgeoti; - med_entity_type menti(MEDFileFieldPerMeshPerType::ConvertIntoMEDFileType(type,geoType,mgeoti)); - if(_start>_end) - throw INTERP_KERNEL::Exception("MEDFileFieldPerMeshPerTypePerDisc::loadBigArray : internal error in range !"); - if(_start==_end) - return ; - DataArray *arr(getOrCreateAndGetArray());//arr is not null due to the spec of getOrCreateAndGetArray - if(_start<0 || _start>=arr->getNumberOfTuples()) - { - std::ostringstream oss; oss << "MEDFileFieldPerMeshPerTypePerDisc::loadBigArray : Invalid start ("<< _start << ") regarding admissible range of allocated array [0," << arr->getNumberOfTuples() << ") !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - if(_end<0 || _end>arr->getNumberOfTuples()) - { - std::ostringstream oss; oss << "MEDFileFieldPerMeshPerTypePerDisc::loadBigArray : Invalid start ("<< _start << ") regarding admissible range of allocated array [0," << arr->getNumberOfTuples() << "] !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - int nbOfCompo(arr->getNumberOfComponents()); - DataArrayDouble *arrD(dynamic_cast(arr)); - if(arrD) - { - double *startFeeding(arrD->getPointer()+_start*nbOfCompo); - goReadZeValuesInFile(fid,fieldName,nbOfCompo,iteration,order,menti,mgeoti,reinterpret_cast(startFeeding)); - return ; - } - DataArrayInt *arrI(dynamic_cast(arr)); - if(arrI) - { - int *startFeeding(arrI->getPointer()+_start*nbOfCompo); - goReadZeValuesInFile(fid,fieldName,nbOfCompo,iteration,order,menti,mgeoti,reinterpret_cast(startFeeding)); - return ; - } - throw INTERP_KERNEL::Exception("Error on array reading ! Unrecognized type of field ! Should be in FLOAT64 or INT32 !"); -} - -/*! - * Set a \c this->_start **and** \c this->_end keeping the same delta between the two. - */ -void MEDFileFieldPerMeshPerTypePerDisc::setNewStart(int newValueOfStart) -{ - int delta=_end-_start; - _start=newValueOfStart; - _end=_start+delta; -} - -int MEDFileFieldPerMeshPerTypePerDisc::getIteration() const -{ - return _father->getIteration(); -} - -int MEDFileFieldPerMeshPerTypePerDisc::getOrder() const -{ - return _father->getOrder(); -} - -double MEDFileFieldPerMeshPerTypePerDisc::getTime() const -{ - return _father->getTime(); -} - -std::string MEDFileFieldPerMeshPerTypePerDisc::getMeshName() const -{ - return _father->getMeshName(); -} - -void MEDFileFieldPerMeshPerTypePerDisc::simpleRepr(int bkOffset, std::ostream& oss, int id) const -{ - const char startLine[]=" ## "; - std::string startLine2(bkOffset,' '); - startLine2+=startLine; - MEDCouplingFieldDiscretization *tmp=MEDCouplingFieldDiscretization::New(_type); - oss << startLine2 << "Localization #" << id << "." << std::endl; - oss << startLine2 << " Type=" << tmp->getRepr() << "." << std::endl; - delete tmp; - oss << startLine2 << " This type discretization lies on profile : \"" << _profile << "\" and on the following localization : \"" << _localization << "\"." << std::endl; - oss << startLine2 << " This type discretization has " << _end-_start << " tuples (start=" << _start << ", end=" << _end << ")." << std::endl; - oss << startLine2 << " This type discretization has " << (_end-_start)/_nval << " integration points." << std::endl; -} - -TypeOfField MEDFileFieldPerMeshPerTypePerDisc::getType() const -{ - return _type; -} - -void MEDFileFieldPerMeshPerTypePerDisc::fillTypesOfFieldAvailable(std::set& types) const -{ - types.insert(_type); -} - -void MEDFileFieldPerMeshPerTypePerDisc::setType(TypeOfField newType) -{ - _type=newType; -} - -INTERP_KERNEL::NormalizedCellType MEDFileFieldPerMeshPerTypePerDisc::getGeoType() const -{ - return _father->getGeoType(); -} - -int MEDFileFieldPerMeshPerTypePerDisc::getNumberOfComponents() const -{ - return _father->getNumberOfComponents(); -} - -int MEDFileFieldPerMeshPerTypePerDisc::getNumberOfTuples() const -{ - return _end-_start; -} - -DataArray *MEDFileFieldPerMeshPerTypePerDisc::getOrCreateAndGetArray() -{ - return _father->getOrCreateAndGetArray(); -} - -const DataArray *MEDFileFieldPerMeshPerTypePerDisc::getOrCreateAndGetArray() const -{ - const MEDFileFieldPerMeshPerType *fath=_father; - return fath->getOrCreateAndGetArray(); -} - -const std::vector& MEDFileFieldPerMeshPerTypePerDisc::getInfo() const -{ - return _father->getInfo(); -} - -std::string MEDFileFieldPerMeshPerTypePerDisc::getProfile() const -{ - return _profile; -} - -void MEDFileFieldPerMeshPerTypePerDisc::setProfile(const std::string& newPflName) -{ - _profile=newPflName; -} - -std::string MEDFileFieldPerMeshPerTypePerDisc::getLocalization() const -{ - return _localization; -} - -void MEDFileFieldPerMeshPerTypePerDisc::setLocalization(const std::string& newLocName) -{ - _localization=newLocName; -} - -void MEDFileFieldPerMeshPerTypePerDisc::changePflsRefsNamesGen(const std::vector< std::pair, std::string > >& mapOfModif) -{ - for(std::vector< std::pair, std::string > >::const_iterator it2=mapOfModif.begin();it2!=mapOfModif.end();it2++) - { - if(std::find((*it2).first.begin(),(*it2).first.end(),_profile)!=(*it2).first.end()) - { - _profile=(*it2).second; - return; - } - } -} - -void MEDFileFieldPerMeshPerTypePerDisc::changeLocsRefsNamesGen(const std::vector< std::pair, std::string > >& mapOfModif) -{ - for(std::vector< std::pair, std::string > >::const_iterator it2=mapOfModif.begin();it2!=mapOfModif.end();it2++) - { - if(std::find((*it2).first.begin(),(*it2).first.end(),_localization)!=(*it2).first.end()) - { - _localization=(*it2).second; - return; - } - } -} - -void MEDFileFieldPerMeshPerTypePerDisc::getFieldAtLevel(TypeOfField type, const MEDFileFieldGlobsReal *glob, std::vector< std::pair >& dads, std::vector& pfls, std::vector& locs, std::vector& geoTypes) const -{ - if(type!=_type) - return ; - dads.push_back(std::pair(_start,_end)); - geoTypes.push_back(getGeoType()); - if(_profile.empty()) - pfls.push_back(0); - else - { - pfls.push_back(glob->getProfile(_profile.c_str())); - } - if(_localization.empty()) - locs.push_back(-1); - else - { - locs.push_back(glob->getLocalizationId(_localization.c_str())); - } -} - -void MEDFileFieldPerMeshPerTypePerDisc::fillValues(int discId, int& startEntryId, std::vector< std::pair,std::pair > >& entries) const -{ - entries[startEntryId]=std::pair ,std::pair >(std::pair(getGeoType(),discId),std::pair(_start,_end)); - startEntryId++; -} - -void MEDFileFieldPerMeshPerTypePerDisc::writeLL(med_idt fid, const MEDFileFieldNameScope& nasc) const -{ - TypeOfField type=getType(); - INTERP_KERNEL::NormalizedCellType geoType=getGeoType(); - med_geometry_type mgeoti; - med_entity_type menti=MEDFileFieldPerMeshPerType::ConvertIntoMEDFileType(type,geoType,mgeoti); - const DataArray *arr=getOrCreateAndGetArray(); - if(!arr) - throw INTERP_KERNEL::Exception("MEDFileFieldPerMeshPerTypePerDisc::writeLL : no array set !"); - const DataArrayDouble *arrD=dynamic_cast(arr); - const DataArrayInt *arrI=dynamic_cast(arr); - const unsigned char *locToWrite=0; - if(arrD) - locToWrite=reinterpret_cast(arrD->getConstPointer()+_start*arr->getNumberOfComponents()); - else if(arrI) - locToWrite=reinterpret_cast(arrI->getConstPointer()+_start*arr->getNumberOfComponents()); - else - throw INTERP_KERNEL::Exception("MEDFileFieldPerMeshPerTypePerDisc::writeLL : not recognized type of values ! Supported are FLOAT64 and INT32 !"); - MEDFILESAFECALLERWR0(MEDfieldValueWithProfileWr,(fid,nasc.getName().c_str(),getIteration(),getOrder(),getTime(),menti,mgeoti, - MED_COMPACT_PFLMODE,_profile.c_str(),_localization.c_str(),MED_FULL_INTERLACE,MED_ALL_CONSTITUENT,_nval, - locToWrite)); -} - -void MEDFileFieldPerMeshPerTypePerDisc::getCoarseData(TypeOfField& type, std::pair& dad, std::string& pfl, std::string& loc) const -{ - type=_type; - pfl=_profile; - loc=_localization; - dad.first=_start; dad.second=_end; -} - -/*! - * \param [in] codeOfMesh is of format returned by MEDCouplingUMesh::getDistributionOfTypes. And for each *i* oldCode[3*i+2] gives the position (MEDFileUMesh::PutInThirdComponentOfCodeOffset). - * This code corresponds to the distribution of types in the corresponding mesh. - * \param [out] ptToFill memory zone where the output will be stored. - * \return the size of data pushed into output param \a ptToFill - */ -int MEDFileFieldPerMeshPerTypePerDisc::fillEltIdsFromCode(int offset, const std::vector& codeOfMesh, const MEDFileFieldGlobsReal& glob, int *ptToFill) const -{ - _loc_id=offset; - std::ostringstream oss; - std::size_t nbOfType=codeOfMesh.size()/3; - int found=-1; - for(std::size_t i=0;igetNumberOfTuples()!=_nval) - { - const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(getGeoType()); - oss << "MEDFileFieldPerMeshPerTypePerDisc::fillEltIdsFromCode : for geometric type " << cm.getRepr() << ", field is defined on profile \"" << _profile << "\" and size of profile is "; - oss << _nval; - oss << pfl->getNumberOfTuples() << " whereas the number of ids is set to " << _nval << " for this geometric type !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - int offset2=codeOfMesh[3*found+2]; - for(const int *pflId=pfl->begin();pflId!=pfl->end();pflId++) - { - if(*pflId > MEDFileFieldPerMeshPerTypePerDisc::SplitPerDiscretization(const std::vector< const MEDFileFieldPerMeshPerTypePerDisc *>& entries) -{ - int id=0; - std::map,int> m; - std::vector< std::vector< const MEDFileFieldPerMeshPerTypePerDisc *> > ret; - for(std::vector< const MEDFileFieldPerMeshPerTypePerDisc *>::const_iterator it=entries.begin();it!=entries.end();it++) - if(m.find(std::pair((*it)->getLocalization(),(*it)->getType()))==m.end()) - m[std::pair((*it)->getLocalization(),(*it)->getType())]=id++; - ret.resize(id); - for(std::vector< const MEDFileFieldPerMeshPerTypePerDisc *>::const_iterator it=entries.begin();it!=entries.end();it++) - ret[m[std::pair((*it)->getLocalization(),(*it)->getType())]].push_back(*it); - return ret; -} - -/*! - * - \c this->_loc_id mutable attribute is used for elt id in mesh offsets. - * - * \param [in] offset the offset id used to take into account that \a result is not compulsary empty in input - * \param [in] entriesOnSameDisc some entries **on same localization** if not the result can be invalid. The _start and _end on them are relative to \a arr parameter. - * \param [in] explicitIdsInMesh ids in mesh of the considered chunk. - * \param [in] newCode one of the input parameter to explicit the new geo type dispatch (in classical format same than those asked by MEDFileFields::renumberEntitiesLyingOnMesh) - * \param [in,out] glob if necessary by the method, new profiles can be added to it - * \param [in,out] arr after the call of this method \a arr is renumbered to be compliant with added entries to \a result. - * \param [out] result All new entries will be appended on it. - * \return false if the configuration of renumbering leads to an unnecessary resplit of input \a entriesOnSameDisc. If not true is returned (the most general case !) - */ -bool MEDFileFieldPerMeshPerTypePerDisc::RenumberChunks(int offset, const std::vector< const MEDFileFieldPerMeshPerTypePerDisc *>& entriesOnSameDisc, - const DataArrayInt *explicitIdsInMesh, - const std::vector& newCode, - MEDFileFieldGlobsReal& glob, DataArrayDouble *arr, - std::vector< MEDCouplingAutoRefCountObjectPtr >& result) -{ - if(entriesOnSameDisc.empty()) - return false; - TypeOfField type=entriesOnSameDisc[0]->getType(); - int szEntities=0,szTuples=0; - for(std::vector< const MEDFileFieldPerMeshPerTypePerDisc *>::const_iterator it=entriesOnSameDisc.begin();it!=entriesOnSameDisc.end();it++) - { szEntities+=(*it)->_nval; szTuples+=(*it)->_end-(*it)->_start; } - int nbi=szTuples/szEntities; - if(szTuples%szEntities!=0) - throw INTERP_KERNEL::Exception("MEDFileFieldPerMeshPerTypePerDisc::RenumberChunks : internal error the splitting into same dicretization failed !"); - MEDCouplingAutoRefCountObjectPtr renumTuples=DataArrayInt::New(); renumTuples->alloc(szTuples,1); - MEDCouplingAutoRefCountObjectPtr ranges=MEDCouplingUMesh::ComputeRangesFromTypeDistribution(newCode); - std::vector< MEDCouplingAutoRefCountObjectPtr > newGeoTypesPerChunk(entriesOnSameDisc.size()); - std::vector< const DataArrayInt * > newGeoTypesPerChunk2(entriesOnSameDisc.size()); - std::vector< MEDCouplingAutoRefCountObjectPtr > newGeoTypesPerChunk_bis(entriesOnSameDisc.size()); - std::vector< const DataArrayInt * > newGeoTypesPerChunk3(entriesOnSameDisc.size()); - MEDCouplingAutoRefCountObjectPtr newGeoTypesPerChunk4=DataArrayInt::New(); newGeoTypesPerChunk4->alloc(szEntities,nbi); - int id=0; - for(std::vector< const MEDFileFieldPerMeshPerTypePerDisc *>::const_iterator it=entriesOnSameDisc.begin();it!=entriesOnSameDisc.end();it++,id++) - { - int startOfEltIdOfChunk=(*it)->_start; - MEDCouplingAutoRefCountObjectPtr newEltIds=explicitIdsInMesh->substr(startOfEltIdOfChunk,startOfEltIdOfChunk+(*it)->_nval); - MEDCouplingAutoRefCountObjectPtr rangeIdsForChunk=newEltIds->findRangeIdForEachTuple(ranges); - MEDCouplingAutoRefCountObjectPtr idsInRrangeForChunk=newEltIds->findIdInRangeForEachTuple(ranges); - // - MEDCouplingAutoRefCountObjectPtr tmp=rangeIdsForChunk->duplicateEachTupleNTimes(nbi); rangeIdsForChunk->rearrange(nbi); - newGeoTypesPerChunk4->setPartOfValues1(tmp,(*it)->_tmp_work1-offset,(*it)->_tmp_work1+(*it)->_nval*nbi-offset,1,0,nbi,1); - // - newGeoTypesPerChunk[id]=rangeIdsForChunk; newGeoTypesPerChunk2[id]=rangeIdsForChunk; - newGeoTypesPerChunk_bis[id]=idsInRrangeForChunk; newGeoTypesPerChunk3[id]=idsInRrangeForChunk; - } - MEDCouplingAutoRefCountObjectPtr newGeoTypesEltIdsAllGather=DataArrayInt::Aggregate(newGeoTypesPerChunk2); newGeoTypesPerChunk.clear(); newGeoTypesPerChunk2.clear(); - MEDCouplingAutoRefCountObjectPtr newGeoTypesEltIdsAllGather2=DataArrayInt::Aggregate(newGeoTypesPerChunk3); newGeoTypesPerChunk_bis.clear(); newGeoTypesPerChunk3.clear(); - MEDCouplingAutoRefCountObjectPtr diffVals=newGeoTypesEltIdsAllGather->getDifferentValues(); - MEDCouplingAutoRefCountObjectPtr renumEltIds=newGeoTypesEltIdsAllGather->buildPermArrPerLevel(); - // - MEDCouplingAutoRefCountObjectPtr renumTupleIds=newGeoTypesPerChunk4->buildPermArrPerLevel(); - // - MEDCouplingAutoRefCountObjectPtr arrPart=arr->substr(offset,offset+szTuples); - arrPart->renumberInPlace(renumTupleIds->begin()); - arr->setPartOfValues1(arrPart,offset,offset+szTuples,1,0,arrPart->getNumberOfComponents(),1); - bool ret=false; - const int *idIt=diffVals->begin(); - std::list li(entriesOnSameDisc.begin(),entriesOnSameDisc.end()); - int offset2=0; - for(int i=0;igetNumberOfTuples();i++,idIt++) - { - MEDCouplingAutoRefCountObjectPtr ids=newGeoTypesEltIdsAllGather->getIdsEqual(*idIt); - MEDCouplingAutoRefCountObjectPtr subIds=newGeoTypesEltIdsAllGather2->selectByTupleId(ids->begin(),ids->end()); - int nbEntityElts=subIds->getNumberOfTuples(); - bool ret2; - MEDCouplingAutoRefCountObjectPtr eltToAdd=MEDFileFieldPerMeshPerTypePerDisc:: - NewObjectOnSameDiscThanPool(type,(INTERP_KERNEL::NormalizedCellType)newCode[3*(*idIt)],subIds,!subIds->isIdentity() || nbEntityElts!=newCode[3*(*idIt)+1],nbi, - offset+offset2, - li,glob,ret2); - ret=ret || ret2; - result.push_back(eltToAdd); - offset2+=nbEntityElts*nbi; - } - ret=ret || li.empty(); - return ret; -} - -/*! - * \param [in] typeF type of field of new chunk - * \param [in] geoType the geometric type of the chunk - * \param [in] idsOfMeshElt the entity ids of mesh (cells or nodes) of the new chunk. - * \param [in] isPfl specifies if a profile is requested regarding size of \a idsOfMeshElt and the number of such entities regarding underlying mesh. - * \param [in] nbi number of integration points - * \param [in] offset The offset in the **global array of data**. - * \param [in,out] entriesOnSameDisc the pool **on the same discretization** inside which it will be attempted to find an existing entry corresponding exactly - * to the new chunk to create. - * \param [in,out] glob the global shared info that will be requested for existing profiles or to append a new profile if needed. - * \param [out] notInExisting If false the return newly allocated entry is not coming from \a entriesOnSameDisc. If true the output comes from copy of \a entriesOnSameDisc - * and corresponding entry erased from \a entriesOnSameDisc. - * \return a newly allocated chunk - */ -MEDFileFieldPerMeshPerTypePerDisc *MEDFileFieldPerMeshPerTypePerDisc::NewObjectOnSameDiscThanPool(TypeOfField typeF, INTERP_KERNEL::NormalizedCellType geoType, DataArrayInt *idsOfMeshElt, - bool isPfl, int nbi, int offset, - std::list< const MEDFileFieldPerMeshPerTypePerDisc *>& entriesOnSameDisc, - MEDFileFieldGlobsReal& glob, - bool ¬InExisting) -{ - int nbMeshEntities=idsOfMeshElt->getNumberOfTuples(); - std::list< const MEDFileFieldPerMeshPerTypePerDisc *>::iterator it=entriesOnSameDisc.begin(); - for(;it!=entriesOnSameDisc.end();it++) - { - if(((INTERP_KERNEL::NormalizedCellType)(*it)->_loc_id)==geoType && (*it)->_nval==nbMeshEntities) - { - if(!isPfl) - { - if((*it)->_profile.empty()) - break; - else - if(!(*it)->_profile.empty()) - { - const DataArrayInt *pfl=glob.getProfile((*it)->_profile.c_str()); - if(pfl->isEqualWithoutConsideringStr(*idsOfMeshElt)) - break; - } - } - } - } - if(it==entriesOnSameDisc.end()) - { - notInExisting=true; - MEDFileFieldPerMeshPerTypePerDisc *ret=new MEDFileFieldPerMeshPerTypePerDisc; - ret->_type=typeF; - ret->_loc_id=(int)geoType; - ret->_nval=nbMeshEntities; - ret->_start=offset; - ret->_end=ret->_start+ret->_nval*nbi; - if(isPfl) - { - idsOfMeshElt->setName(glob.createNewNameOfPfl().c_str()); - glob.appendProfile(idsOfMeshElt); - ret->_profile=idsOfMeshElt->getName(); - } - //tony treatment of localization - return ret; - } - else - { - notInExisting=false; - MEDFileFieldPerMeshPerTypePerDisc *ret=MEDFileFieldPerMeshPerTypePerDisc::New(*(*it)); - ret->_loc_id=(int)geoType; - ret->setNewStart(offset); - entriesOnSameDisc.erase(it); - return ret; - } - -} - -MEDFileFieldPerMeshPerType *MEDFileFieldPerMeshPerType::NewOnRead(med_idt fid, MEDFileFieldPerMesh *fath, TypeOfField type, INTERP_KERNEL::NormalizedCellType geoType, const MEDFileFieldNameScope& nasc, const PartDefinition *pd) -{ - return new MEDFileFieldPerMeshPerType(fid,fath,type,geoType,nasc,pd); -} - -MEDFileFieldPerMeshPerType *MEDFileFieldPerMeshPerType::New(MEDFileFieldPerMesh *fath, INTERP_KERNEL::NormalizedCellType geoType) -{ - return new MEDFileFieldPerMeshPerType(fath,geoType); -} - -std::size_t MEDFileFieldPerMeshPerType::getHeapMemorySizeWithoutChildren() const -{ - return _field_pm_pt_pd.capacity()*sizeof(MEDCouplingAutoRefCountObjectPtr); -} - -std::vector MEDFileFieldPerMeshPerType::getDirectChildrenWithNull() const -{ - std::vector ret; - for(std::vector< MEDCouplingAutoRefCountObjectPtr >::const_iterator it=_field_pm_pt_pd.begin();it!=_field_pm_pt_pd.end();it++) - ret.push_back((const MEDFileFieldPerMeshPerTypePerDisc *)*it); - return ret; -} - -MEDFileFieldPerMeshPerType *MEDFileFieldPerMeshPerType::deepCpy(MEDFileFieldPerMesh *father) const -{ - MEDCouplingAutoRefCountObjectPtr ret=new MEDFileFieldPerMeshPerType(*this); - ret->_father=father; - std::size_t i=0; - for(std::vector< MEDCouplingAutoRefCountObjectPtr >::const_iterator it=_field_pm_pt_pd.begin();it!=_field_pm_pt_pd.end();it++,i++) - { - if((const MEDFileFieldPerMeshPerTypePerDisc *)*it) - ret->_field_pm_pt_pd[i]=(*it)->deepCpy((MEDFileFieldPerMeshPerType *)ret); - } - return ret.retn(); -} - -void MEDFileFieldPerMeshPerType::assignFieldNoProfile(int& start, int offset, int nbOfCells, const MEDCouplingFieldDouble *field, const DataArray *arr, MEDFileFieldGlobsReal& glob, const MEDFileFieldNameScope& nasc) -{ - std::vector pos=addNewEntryIfNecessary(field,offset,nbOfCells); - for(std::vector::const_iterator it=pos.begin();it!=pos.end();it++) - _field_pm_pt_pd[*it]->assignFieldNoProfile(start,offset,nbOfCells,field,arr,glob,nasc); -} - -/*! - * This method is the most general one. No optimization is done here. - * \param [in] multiTypePfl is the end user profile specified in high level API - * \param [in] idsInPfl is the selection into the \a multiTypePfl whole profile that corresponds to the current geometric type. - * \param [in] locIds is the profile needed to be created for MED file format. It can be null if all cells of current geometric type are fetched in \a multiTypePfl. - * \b WARNING if not null the MED file profile can be subdivided again in case of Gauss points. - * \param [in] nbOfEltsInWholeMesh nb of elts of type \a this->_geo_type in \b WHOLE mesh - * \param [in] mesh is the mesh coming from the MEDFileMesh instance in correspondance with the MEDFileField. The mesh inside the \a field is simply ignored. - */ -void MEDFileFieldPerMeshPerType::assignFieldProfile(bool isPflAlone, int& start, const DataArrayInt *multiTypePfl, const DataArrayInt *idsInPfl, DataArrayInt *locIds, int nbOfEltsInWholeMesh, const MEDCouplingFieldDouble *field, const DataArray *arr, const MEDCouplingMesh *mesh, MEDFileFieldGlobsReal& glob, const MEDFileFieldNameScope& nasc) -{ - std::vector pos=addNewEntryIfNecessary(field,idsInPfl); - for(std::vector::const_iterator it=pos.begin();it!=pos.end();it++) - _field_pm_pt_pd[*it]->assignFieldProfile(isPflAlone,start,multiTypePfl,idsInPfl,locIds,nbOfEltsInWholeMesh,field,arr,mesh,glob,nasc); -} - -void MEDFileFieldPerMeshPerType::assignNodeFieldNoProfile(int& start, const MEDCouplingFieldDouble *field, const DataArray *arr, MEDFileFieldGlobsReal& glob) -{ - _field_pm_pt_pd.resize(1); - _field_pm_pt_pd[0]=MEDFileFieldPerMeshPerTypePerDisc::New(this,ON_NODES,-3); - _field_pm_pt_pd[0]->assignNodeFieldNoProfile(start,field,arr,glob); -} - -void MEDFileFieldPerMeshPerType::assignNodeFieldProfile(int& start, const DataArrayInt *pfl, const MEDCouplingFieldDouble *field, const DataArray *arr, MEDFileFieldGlobsReal& glob, const MEDFileFieldNameScope& nasc) -{ - MEDCouplingAutoRefCountObjectPtr pfl2=pfl->deepCpy(); - if(!arr || !arr->isAllocated()) - throw INTERP_KERNEL::Exception("MEDFileFieldPerMeshPerType::assignNodeFieldProfile : input array is null, or not allocated !"); - _field_pm_pt_pd.resize(1); - _field_pm_pt_pd[0]=MEDFileFieldPerMeshPerTypePerDisc::New(this,ON_NODES,-3); - _field_pm_pt_pd[0]->assignFieldProfile(true,start,pfl,pfl2,pfl2,-1,field,arr,0,glob,nasc);//mesh is not requested so 0 is send. -} - -std::vector MEDFileFieldPerMeshPerType::addNewEntryIfNecessary(const MEDCouplingFieldDouble *field, int offset, int nbOfCells) -{ - TypeOfField type=field->getTypeOfField(); - if(type!=ON_GAUSS_PT) - { - int locIdToFind=MEDFileFieldPerMeshPerTypePerDisc::ConvertType(type,0); - int sz=_field_pm_pt_pd.size(); - bool found=false; - for(int j=0;jgetLocId()==locIdToFind) - { - _field_pm_pt_pd[j]=MEDFileFieldPerMeshPerTypePerDisc::New(this,type,locIdToFind); - found=true; - } - } - if(!found) - { - _field_pm_pt_pd.resize(sz+1); - _field_pm_pt_pd[sz]=MEDFileFieldPerMeshPerTypePerDisc::New(this,type,locIdToFind); - } - std::vector ret(1,(int)sz); - return ret; - } - else - { - std::vector ret2=addNewEntryIfNecessaryGauss(field,offset,nbOfCells); - int sz2=ret2.size(); - std::vector ret3(sz2); - int k=0; - for(int i=0;igetLocId()==locIdToFind) - { - _field_pm_pt_pd[j]=MEDFileFieldPerMeshPerTypePerDisc::New(this,type,locIdToFind); - ret3[k++]=j; - found=true; - } - } - if(!found) - { - _field_pm_pt_pd.resize(sz+1); - _field_pm_pt_pd[sz]=MEDFileFieldPerMeshPerTypePerDisc::New(this,type,locIdToFind); - ret3[k++]=sz; - } - } - return ret3; - } -} - -std::vector MEDFileFieldPerMeshPerType::addNewEntryIfNecessaryGauss(const MEDCouplingFieldDouble *field, int offset, int nbOfCells) -{ - const MEDCouplingFieldDiscretization *disc=field->getDiscretization(); - const MEDCouplingFieldDiscretizationGauss *disc2=dynamic_cast(disc); - if(!disc2) - throw INTERP_KERNEL::Exception("addNewEntryIfNecessaryGauss : invalid call to this method ! Internal Error !"); - const DataArrayInt *da=disc2->getArrayOfDiscIds(); - if(!da) - throw INTERP_KERNEL::Exception("addNewEntryIfNecessaryGauss (no profile) : no localization ids per cell array available ! The input Gauss node field is maybe invalid !"); - MEDCouplingAutoRefCountObjectPtr da2=da->selectByTupleId2(offset,offset+nbOfCells,1); - MEDCouplingAutoRefCountObjectPtr retTmp=da2->getDifferentValues(); - if(retTmp->presenceOfValue(-1)) - throw INTERP_KERNEL::Exception("addNewEntryIfNecessaryGauss : some cells have no dicretization description !"); - std::vector ret(retTmp->begin(),retTmp->end()); - return ret; -} - -std::vector MEDFileFieldPerMeshPerType::addNewEntryIfNecessary(const MEDCouplingFieldDouble *field, const DataArrayInt *subCells) -{ - TypeOfField type=field->getTypeOfField(); - if(type!=ON_GAUSS_PT) - { - int locIdToFind=MEDFileFieldPerMeshPerTypePerDisc::ConvertType(type,0); - int sz=_field_pm_pt_pd.size(); - bool found=false; - for(int j=0;jgetLocId()==locIdToFind) - { - _field_pm_pt_pd[j]=MEDFileFieldPerMeshPerTypePerDisc::New(this,type,locIdToFind); - found=true; - } - } - if(!found) - { - _field_pm_pt_pd.resize(sz+1); - _field_pm_pt_pd[sz]=MEDFileFieldPerMeshPerTypePerDisc::New(this,type,locIdToFind); - } - std::vector ret(1,0); - return ret; - } - else - { - std::vector ret2=addNewEntryIfNecessaryGauss(field,subCells); - int sz2=ret2.size(); - std::vector ret3(sz2); - int k=0; - for(int i=0;igetLocId()==locIdToFind) - { - _field_pm_pt_pd[j]=MEDFileFieldPerMeshPerTypePerDisc::New(this,type,locIdToFind); - ret3[k++]=j; - found=true; - } - } - if(!found) - { - _field_pm_pt_pd.resize(sz+1); - _field_pm_pt_pd[sz]=MEDFileFieldPerMeshPerTypePerDisc::New(this,type,locIdToFind); - ret3[k++]=sz; - } - } - return ret3; - } -} - -std::vector MEDFileFieldPerMeshPerType::addNewEntryIfNecessaryGauss(const MEDCouplingFieldDouble *field, const DataArrayInt *subCells) -{ - const MEDCouplingFieldDiscretization *disc=field->getDiscretization(); - const MEDCouplingFieldDiscretizationGauss *disc2=dynamic_cast(disc); - if(!disc2) - throw INTERP_KERNEL::Exception("addNewEntryIfNecessaryGauss : invalid call to this method ! Internal Error !"); - const DataArrayInt *da=disc2->getArrayOfDiscIds(); - if(!da) - throw INTERP_KERNEL::Exception("addNewEntryIfNecessaryGauss : no localization ids per cell array available ! The input Gauss node field is maybe invalid !"); - MEDCouplingAutoRefCountObjectPtr da2=da->selectByTupleIdSafe(subCells->getConstPointer(),subCells->getConstPointer()+subCells->getNumberOfTuples()); - MEDCouplingAutoRefCountObjectPtr retTmp=da2->getDifferentValues(); - if(retTmp->presenceOfValue(-1)) - throw INTERP_KERNEL::Exception("addNewEntryIfNecessaryGauss : some cells have no dicretization description !"); - std::vector ret(retTmp->begin(),retTmp->end()); - return ret; -} - -const MEDFileFieldPerMesh *MEDFileFieldPerMeshPerType::getFather() const -{ - return _father; -} - -void MEDFileFieldPerMeshPerType::getDimension(int& dim) const -{ - const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(_geo_type); - int curDim=(int)cm.getDimension(); - dim=std::max(dim,curDim); -} - -void MEDFileFieldPerMeshPerType::fillTypesOfFieldAvailable(std::set& types) const -{ - for(std::vector< MEDCouplingAutoRefCountObjectPtr >::const_iterator it=_field_pm_pt_pd.begin();it!=_field_pm_pt_pd.end();it++) - { - (*it)->fillTypesOfFieldAvailable(types); - } -} - -void MEDFileFieldPerMeshPerType::fillFieldSplitedByType(std::vector< std::pair >& dads, std::vector& types, std::vector& pfls, std::vector& locs) const -{ - int sz=_field_pm_pt_pd.size(); - dads.resize(sz); types.resize(sz); pfls.resize(sz); locs.resize(sz); - for(int i=0;igetCoarseData(types[i],dads[i],pfls[i],locs[i]); - } -} - -int MEDFileFieldPerMeshPerType::getIteration() const -{ - return _father->getIteration(); -} - -int MEDFileFieldPerMeshPerType::getOrder() const -{ - return _father->getOrder(); -} - -double MEDFileFieldPerMeshPerType::getTime() const -{ - return _father->getTime(); -} - -std::string MEDFileFieldPerMeshPerType::getMeshName() const -{ - return _father->getMeshName(); -} - -void MEDFileFieldPerMeshPerType::simpleRepr(int bkOffset, std::ostream& oss, int id) const -{ - const char startLine[]=" ## "; - std::string startLine2(bkOffset,' '); - std::string startLine3(startLine2); - startLine3+=startLine; - if(_geo_type!=INTERP_KERNEL::NORM_ERROR) - { - const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(_geo_type); - oss << startLine3 << "Entry geometry type #" << id << " is lying on geometry types " << cm.getRepr() << "." << std::endl; - } - else - oss << startLine3 << "Entry geometry type #" << id << " is lying on NODES." << std::endl; - oss << startLine3 << "Entry is defined on " << _field_pm_pt_pd.size() << " localizations." << std::endl; - int i=0; - for(std::vector< MEDCouplingAutoRefCountObjectPtr >::const_iterator it=_field_pm_pt_pd.begin();it!=_field_pm_pt_pd.end();it++,i++) - { - const MEDFileFieldPerMeshPerTypePerDisc *cur=(*it); - if(cur) - cur->simpleRepr(bkOffset,oss,i); - else - { - oss << startLine2 << " ## " << "Localization #" << i << " is empty !" << std::endl; - } - } -} - -void MEDFileFieldPerMeshPerType::getSizes(int& globalSz, int& nbOfEntries) const -{ - for(std::vector< MEDCouplingAutoRefCountObjectPtr >::const_iterator it=_field_pm_pt_pd.begin();it!=_field_pm_pt_pd.end();it++) - { - globalSz+=(*it)->getNumberOfTuples(); - } - nbOfEntries+=(int)_field_pm_pt_pd.size(); -} - -INTERP_KERNEL::NormalizedCellType MEDFileFieldPerMeshPerType::getGeoType() const -{ - return _geo_type; -} - - -int MEDFileFieldPerMeshPerType::getNumberOfComponents() const -{ - return _father->getNumberOfComponents(); -} - -bool MEDFileFieldPerMeshPerType::presenceOfMultiDiscPerGeoType() const -{ - std::size_t nb(0); - for(std::vector< MEDCouplingAutoRefCountObjectPtr >::const_iterator it=_field_pm_pt_pd.begin();it!=_field_pm_pt_pd.end();it++) - { - const MEDFileFieldPerMeshPerTypePerDisc *fmtd(*it); - if(fmtd) - nb++; - } - return nb>1; -} - -DataArray *MEDFileFieldPerMeshPerType::getOrCreateAndGetArray() -{ - return _father->getOrCreateAndGetArray(); -} - -const DataArray *MEDFileFieldPerMeshPerType::getOrCreateAndGetArray() const -{ - const MEDFileFieldPerMesh *fath=_father; - return fath->getOrCreateAndGetArray(); -} - -const std::vector& MEDFileFieldPerMeshPerType::getInfo() const -{ - return _father->getInfo(); -} - -std::vector MEDFileFieldPerMeshPerType::getPflsReallyUsed() const -{ - std::vector ret; - std::set ret2; - for(std::vector< MEDCouplingAutoRefCountObjectPtr >::const_iterator it1=_field_pm_pt_pd.begin();it1!=_field_pm_pt_pd.end();it1++) - { - std::string tmp=(*it1)->getProfile(); - if(!tmp.empty()) - if(ret2.find(tmp)==ret2.end()) - { - ret.push_back(tmp); - ret2.insert(tmp); - } - } - return ret; -} - -std::vector MEDFileFieldPerMeshPerType::getLocsReallyUsed() const -{ - std::vector ret; - std::set ret2; - for(std::vector< MEDCouplingAutoRefCountObjectPtr >::const_iterator it1=_field_pm_pt_pd.begin();it1!=_field_pm_pt_pd.end();it1++) - { - std::string tmp=(*it1)->getLocalization(); - if(!tmp.empty() && tmp!=MED_GAUSS_ELNO) - if(ret2.find(tmp)==ret2.end()) - { - ret.push_back(tmp); - ret2.insert(tmp); - } - } - return ret; -} - -std::vector MEDFileFieldPerMeshPerType::getPflsReallyUsedMulti() const -{ - std::vector ret; - std::set ret2; - for(std::vector< MEDCouplingAutoRefCountObjectPtr >::const_iterator it1=_field_pm_pt_pd.begin();it1!=_field_pm_pt_pd.end();it1++) - { - std::string tmp=(*it1)->getProfile(); - if(!tmp.empty()) - ret.push_back(tmp); - } - return ret; -} - -std::vector MEDFileFieldPerMeshPerType::getLocsReallyUsedMulti() const -{ - std::vector ret; - for(std::vector< MEDCouplingAutoRefCountObjectPtr >::const_iterator it1=_field_pm_pt_pd.begin();it1!=_field_pm_pt_pd.end();it1++) - { - std::string tmp=(*it1)->getLocalization(); - if(!tmp.empty() && tmp!=MED_GAUSS_ELNO) - ret.push_back(tmp); - } - return ret; -} - -void MEDFileFieldPerMeshPerType::changePflsRefsNamesGen(const std::vector< std::pair, std::string > >& mapOfModif) -{ - for(std::vector< MEDCouplingAutoRefCountObjectPtr >::iterator it1=_field_pm_pt_pd.begin();it1!=_field_pm_pt_pd.end();it1++) - (*it1)->changePflsRefsNamesGen(mapOfModif); -} - -void MEDFileFieldPerMeshPerType::changeLocsRefsNamesGen(const std::vector< std::pair, std::string > >& mapOfModif) -{ - for(std::vector< MEDCouplingAutoRefCountObjectPtr >::iterator it1=_field_pm_pt_pd.begin();it1!=_field_pm_pt_pd.end();it1++) - (*it1)->changeLocsRefsNamesGen(mapOfModif); -} - -MEDFileFieldPerMeshPerTypePerDisc *MEDFileFieldPerMeshPerType::getLeafGivenLocId(int locId) -{ - if(_field_pm_pt_pd.empty()) - { - const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(_geo_type); - std::ostringstream oss; oss << "MEDFileFieldPerMeshPerType::getLeafGivenLocId : no localizations for geotype \"" << cm.getRepr() << "\" !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - if(locId>=0 && locId<(int)_field_pm_pt_pd.size()) - return _field_pm_pt_pd[locId]; - const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(_geo_type); - std::ostringstream oss2; oss2 << "MEDFileFieldPerMeshPerType::getLeafGivenLocId : no such locId available (" << locId; - oss2 << ") for geometric type \"" << cm.getRepr() << "\" It should be in [0," << _field_pm_pt_pd.size() << ") !"; - throw INTERP_KERNEL::Exception(oss2.str().c_str()); - return static_cast(0); -} - -const MEDFileFieldPerMeshPerTypePerDisc *MEDFileFieldPerMeshPerType::getLeafGivenLocId(int locId) const -{ - if(_field_pm_pt_pd.empty()) - { - const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(_geo_type); - std::ostringstream oss; oss << "MEDFileFieldPerMeshPerType::getLeafGivenLocId : no localizations for geotype \"" << cm.getRepr() << "\" !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - if(locId>=0 && locId<(int)_field_pm_pt_pd.size()) - return _field_pm_pt_pd[locId]; - const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(_geo_type); - std::ostringstream oss2; oss2 << "MEDFileFieldPerMeshPerType::getLeafGivenLocId : no such locId available (" << locId; - oss2 << ") for geometric type \"" << cm.getRepr() << "\" It should be in [0," << _field_pm_pt_pd.size() << ") !"; - throw INTERP_KERNEL::Exception(oss2.str().c_str()); - return static_cast(0); -} - -void MEDFileFieldPerMeshPerType::getFieldAtLevel(int meshDim, TypeOfField type, const MEDFileFieldGlobsReal *glob, std::vector< std::pair >& dads, std::vector& pfls, std::vector& locs, std::vector& geoTypes) const -{ - if(_geo_type!=INTERP_KERNEL::NORM_ERROR) - { - const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(_geo_type); - if(meshDim!=(int)cm.getDimension()) - return ; - } - for(std::vector< MEDCouplingAutoRefCountObjectPtr >::const_iterator it=_field_pm_pt_pd.begin();it!=_field_pm_pt_pd.end();it++) - (*it)->getFieldAtLevel(type,glob,dads,pfls,locs,geoTypes); -} - -void MEDFileFieldPerMeshPerType::fillValues(int& startEntryId, std::vector< std::pair,std::pair > >& entries) const -{ - int i=0; - for(std::vector< MEDCouplingAutoRefCountObjectPtr >::const_iterator it=_field_pm_pt_pd.begin();it!=_field_pm_pt_pd.end();it++,i++) - { - (*it)->fillValues(i,startEntryId,entries); - } -} - -void MEDFileFieldPerMeshPerType::setLeaves(const std::vector< MEDCouplingAutoRefCountObjectPtr< MEDFileFieldPerMeshPerTypePerDisc > >& leaves) -{ - _field_pm_pt_pd=leaves; - for(std::vector< MEDCouplingAutoRefCountObjectPtr >::iterator it=_field_pm_pt_pd.begin();it!=_field_pm_pt_pd.end();it++) - (*it)->setFather(this); -} - -/*! - * \param [in,out] globalNum a global numbering counter for the renumbering. - * \param [out] its - list of pair (start,stop) kept - * \return bool - false if the type of field \a tof is not contained in \a this. - */ -bool MEDFileFieldPerMeshPerType::keepOnlySpatialDiscretization(TypeOfField tof, int &globalNum, std::vector< std::pair >& its) -{ - bool ret(false); - std::vector< MEDCouplingAutoRefCountObjectPtr > newPmPtPd; - for(std::vector< MEDCouplingAutoRefCountObjectPtr >::iterator it=_field_pm_pt_pd.begin();it!=_field_pm_pt_pd.end();it++) - if((*it)->getType()==tof) - { - newPmPtPd.push_back(*it); - std::pair bgEnd; bgEnd.first=(*it)->getStart(); bgEnd.second=(*it)->getEnd(); - (*it)->setNewStart(globalNum); - globalNum=(*it)->getEnd(); - its.push_back(bgEnd); - ret=true; - } - if(ret) - _field_pm_pt_pd=newPmPtPd; - return ret; -} - -/*! - * \param [in,out] globalNum a global numbering counter for the renumbering. - * \param [out] its - list of pair (start,stop) kept - * \return bool - false if the type of field \a tof is not contained in \a this. - */ -bool MEDFileFieldPerMeshPerType::keepOnlyGaussDiscretization(std::size_t idOfDisc, int &globalNum, std::vector< std::pair >& its) -{ - if(_field_pm_pt_pd.size()<=idOfDisc) - return false; - MEDCouplingAutoRefCountObjectPtr elt(_field_pm_pt_pd[idOfDisc]); - std::vector< MEDCouplingAutoRefCountObjectPtr > newPmPtPd(1,elt); - std::pair bgEnd; bgEnd.first=_field_pm_pt_pd[idOfDisc]->getStart(); bgEnd.second=_field_pm_pt_pd[idOfDisc]->getEnd(); - elt->setNewStart(globalNum); - globalNum=elt->getEnd(); - its.push_back(bgEnd); - _field_pm_pt_pd=newPmPtPd; - return true; -} - -MEDFileFieldPerMeshPerType::MEDFileFieldPerMeshPerType(MEDFileFieldPerMesh *fath, INTERP_KERNEL::NormalizedCellType geoType):_father(fath),_geo_type(geoType) -{ -} - -MEDFileFieldPerMeshPerType::MEDFileFieldPerMeshPerType(med_idt fid, MEDFileFieldPerMesh *fath, TypeOfField type, INTERP_KERNEL::NormalizedCellType geoType, const MEDFileFieldNameScope& nasc, const PartDefinition *pd):_father(fath),_geo_type(geoType) -{ - INTERP_KERNEL::AutoPtr pflName=MEDLoaderBase::buildEmptyString(MED_NAME_SIZE); - INTERP_KERNEL::AutoPtr locName=MEDLoaderBase::buildEmptyString(MED_NAME_SIZE); - med_geometry_type mgeoti; - med_entity_type menti(ConvertIntoMEDFileType(type,geoType,mgeoti)); - int nbProfiles(MEDfieldnProfile(fid,nasc.getName().c_str(),getIteration(),getOrder(),menti,mgeoti,pflName,locName)); - _field_pm_pt_pd.resize(nbProfiles); - for(int i=0;i >::iterator it=_field_pm_pt_pd.begin();it!=_field_pm_pt_pd.end();it++) - (*it)->loadOnlyStructureOfDataRecursively(fid,start,nasc); -} - -void MEDFileFieldPerMeshPerType::loadBigArraysRecursively(med_idt fid, const MEDFileFieldNameScope& nasc) -{ - for(std::vector< MEDCouplingAutoRefCountObjectPtr >::iterator it=_field_pm_pt_pd.begin();it!=_field_pm_pt_pd.end();it++) - (*it)->loadBigArray(fid,nasc); -} - -void MEDFileFieldPerMeshPerType::writeLL(med_idt fid, const MEDFileFieldNameScope& nasc) const -{ - for(std::vector< MEDCouplingAutoRefCountObjectPtr >::const_iterator it=_field_pm_pt_pd.begin();it!=_field_pm_pt_pd.end();it++) - { - (*it)->copyOptionsFrom(*this); - (*it)->writeLL(fid,nasc); - } -} - -med_entity_type MEDFileFieldPerMeshPerType::ConvertIntoMEDFileType(TypeOfField ikType, INTERP_KERNEL::NormalizedCellType ikGeoType, med_geometry_type& medfGeoType) -{ - switch(ikType) - { - case ON_CELLS: - medfGeoType=typmai3[(int)ikGeoType]; - return MED_CELL; - case ON_NODES: - medfGeoType=MED_NONE; - return MED_NODE; - case ON_GAUSS_NE: - medfGeoType=typmai3[(int)ikGeoType]; - return MED_NODE_ELEMENT; - case ON_GAUSS_PT: - medfGeoType=typmai3[(int)ikGeoType]; - return MED_CELL; - default: - throw INTERP_KERNEL::Exception("MEDFileFieldPerMeshPerType::ConvertIntoMEDFileType : unexpected entity type ! internal error"); - } - return MED_UNDEF_ENTITY_TYPE; -} - -MEDFileFieldPerMesh *MEDFileFieldPerMesh::NewOnRead(med_idt fid, MEDFileAnyTypeField1TSWithoutSDA *fath, int meshCsit, int meshIteration, int meshOrder, const MEDFileFieldNameScope& nasc, const MEDFileMesh *mm, const std::vector< std::pair > *entities) -{ - return new MEDFileFieldPerMesh(fid,fath,meshCsit,meshIteration,meshOrder,nasc,mm,entities); -} - -MEDFileFieldPerMesh *MEDFileFieldPerMesh::New(MEDFileAnyTypeField1TSWithoutSDA *fath, const MEDCouplingMesh *mesh) -{ - return new MEDFileFieldPerMesh(fath,mesh); -} - -std::size_t MEDFileFieldPerMesh::getHeapMemorySizeWithoutChildren() const -{ - return _mesh_name.capacity()+_field_pm_pt.capacity()*sizeof(MEDCouplingAutoRefCountObjectPtr< MEDFileFieldPerMeshPerType >); -} - -std::vector MEDFileFieldPerMesh::getDirectChildrenWithNull() const -{ - std::vector ret; - for(std::vector< MEDCouplingAutoRefCountObjectPtr< MEDFileFieldPerMeshPerType > >::const_iterator it=_field_pm_pt.begin();it!=_field_pm_pt.end();it++) - ret.push_back((const MEDFileFieldPerMeshPerType *)*it); - return ret; -} - -MEDFileFieldPerMesh *MEDFileFieldPerMesh::deepCpy(MEDFileAnyTypeField1TSWithoutSDA *father) const -{ - MEDCouplingAutoRefCountObjectPtr< MEDFileFieldPerMesh > ret=new MEDFileFieldPerMesh(*this); - ret->_father=father; - std::size_t i=0; - for(std::vector< MEDCouplingAutoRefCountObjectPtr< MEDFileFieldPerMeshPerType > >::const_iterator it=_field_pm_pt.begin();it!=_field_pm_pt.end();it++,i++) - { - if((const MEDFileFieldPerMeshPerType *)*it) - ret->_field_pm_pt[i]=(*it)->deepCpy((MEDFileFieldPerMesh *)(ret)); - } - return ret.retn(); -} - -void MEDFileFieldPerMesh::simpleRepr(int bkOffset, std::ostream& oss, int id) const -{ - std::string startLine(bkOffset,' '); - oss << startLine << "## Field part (" << id << ") lying on mesh \"" << _mesh_name << "\", Mesh iteration=" << _mesh_iteration << ". Mesh order=" << _mesh_order << "." << std::endl; - oss << startLine << "## Field is defined on " << _field_pm_pt.size() << " types." << std::endl; - int i=0; - for(std::vector< MEDCouplingAutoRefCountObjectPtr< MEDFileFieldPerMeshPerType > >::const_iterator it=_field_pm_pt.begin();it!=_field_pm_pt.end();it++,i++) - { - const MEDFileFieldPerMeshPerType *cur=*it; - if(cur) - cur->simpleRepr(bkOffset,oss,i); - else - { - oss << startLine << " ## Entry geometry type #" << i << " is empty !" << std::endl; - } - } -} - -void MEDFileFieldPerMesh::copyTinyInfoFrom(const MEDCouplingMesh *mesh) -{ - _mesh_name=mesh->getName(); - mesh->getTime(_mesh_iteration,_mesh_order); -} - -void MEDFileFieldPerMesh::assignFieldNoProfileNoRenum(int& start, const std::vector& code, const MEDCouplingFieldDouble *field, const DataArray *arr, MEDFileFieldGlobsReal& glob, const MEDFileFieldNameScope& nasc) -{ - int nbOfTypes=code.size()/3; - int offset=0; - for(int i=0;iassignFieldNoProfile(start,offset,nbOfCells,field,arr,glob,nasc); - offset+=nbOfCells; - } -} - -/*! - * This method is the most general one. No optimization is done here. - * \param [in] multiTypePfl is the end user profile specified in high level API - * \param [in] code is the code of \a mesh[multiTypePfl] mesh. It is of size of number of different geometric types into \a mesh[multiTypePfl]. - * \param [in] code2 is the code of the \b WHOLE mesh on the same level. So all types in \a code are in \a code2. - * \param [in] idsInPflPerType is the selection into the \a multiTypePfl whole profile that corresponds to the given geometric type. This vector is always 3 times smaller than \a code. - * \param [in] idsPerType is a vector containing the profiles needed to be created for MED file format. \b WARNING these processed MED file profiles can be subdivided again in case of Gauss points. - * \param [in] mesh is the mesh coming from the MEDFileMesh instance in correspondance with the MEDFileField. The mesh inside the \a field is simply ignored. - */ -void MEDFileFieldPerMesh::assignFieldProfile(int& start, const DataArrayInt *multiTypePfl, const std::vector& code, const std::vector& code2, const std::vector& idsInPflPerType, const std::vector& idsPerType, const MEDCouplingFieldDouble *field, const DataArray *arr, const MEDCouplingMesh *mesh, MEDFileFieldGlobsReal& glob, const MEDFileFieldNameScope& nasc) -{ - int nbOfTypes(code.size()/3); - for(int i=0;iassignFieldProfile(nbOfTypes==1,start,multiTypePfl,idsInPflPerType[i],pfl,code2[3*found+1],field,arr,mesh,glob,nasc); - } -} - -void MEDFileFieldPerMesh::assignNodeFieldNoProfile(int& start, const MEDCouplingFieldDouble *field, const DataArray *arr, MEDFileFieldGlobsReal& glob) -{ - int pos=addNewEntryIfNecessary(INTERP_KERNEL::NORM_ERROR); - _field_pm_pt[pos]->assignNodeFieldNoProfile(start,field,arr,glob); -} - -void MEDFileFieldPerMesh::assignNodeFieldProfile(int& start, const DataArrayInt *pfl, const MEDCouplingFieldDouble *field, const DataArray *arr, MEDFileFieldGlobsReal& glob, const MEDFileFieldNameScope& nasc) -{ - int pos=addNewEntryIfNecessary(INTERP_KERNEL::NORM_ERROR); - _field_pm_pt[pos]->assignNodeFieldProfile(start,pfl,field,arr,glob,nasc); -} - -void MEDFileFieldPerMesh::loadOnlyStructureOfDataRecursively(med_idt fid, int& start, const MEDFileFieldNameScope& nasc) -{ - for(std::vector< MEDCouplingAutoRefCountObjectPtr< MEDFileFieldPerMeshPerType > >::iterator it=_field_pm_pt.begin();it!=_field_pm_pt.end();it++) - (*it)->loadOnlyStructureOfDataRecursively(fid,start,nasc); -} - -void MEDFileFieldPerMesh::loadBigArraysRecursively(med_idt fid, const MEDFileFieldNameScope& nasc) -{ - for(std::vector< MEDCouplingAutoRefCountObjectPtr< MEDFileFieldPerMeshPerType > >::iterator it=_field_pm_pt.begin();it!=_field_pm_pt.end();it++) - (*it)->loadBigArraysRecursively(fid,nasc); -} - -void MEDFileFieldPerMesh::writeLL(med_idt fid, const MEDFileFieldNameScope& nasc) const -{ - int nbOfTypes=_field_pm_pt.size(); - for(int i=0;icopyOptionsFrom(*this); - _field_pm_pt[i]->writeLL(fid,nasc); - } -} - -void MEDFileFieldPerMesh::getDimension(int& dim) const -{ - for(std::vector< MEDCouplingAutoRefCountObjectPtr< MEDFileFieldPerMeshPerType > >::const_iterator it=_field_pm_pt.begin();it!=_field_pm_pt.end();it++) - (*it)->getDimension(dim); -} - -void MEDFileFieldPerMesh::fillTypesOfFieldAvailable(std::set& types) const -{ - for(std::vector< MEDCouplingAutoRefCountObjectPtr< MEDFileFieldPerMeshPerType > >::const_iterator it=_field_pm_pt.begin();it!=_field_pm_pt.end();it++) - (*it)->fillTypesOfFieldAvailable(types); -} - -std::vector< std::vector< std::pair > > MEDFileFieldPerMesh::getFieldSplitedByType(std::vector& types, std::vector< std::vector >& typesF, std::vector< std::vector >& pfls, std::vector< std::vector > & locs) const -{ - int sz=_field_pm_pt.size(); - std::vector< std::vector > > ret(sz); - types.resize(sz); typesF.resize(sz); pfls.resize(sz); locs.resize(sz); - for(int i=0;igetGeoType(); - _field_pm_pt[i]->fillFieldSplitedByType(ret[i],typesF[i],pfls[i],locs[i]); - } - return ret; -} - -double MEDFileFieldPerMesh::getTime() const -{ - int tmp1,tmp2; - return _father->getTime(tmp1,tmp2); -} - -int MEDFileFieldPerMesh::getIteration() const -{ - return _father->getIteration(); -} - -int MEDFileFieldPerMesh::getOrder() const -{ - return _father->getOrder(); -} - -int MEDFileFieldPerMesh::getNumberOfComponents() const -{ - return _father->getNumberOfComponents(); -} - -bool MEDFileFieldPerMesh::presenceOfMultiDiscPerGeoType() const -{ - for(std::vector< MEDCouplingAutoRefCountObjectPtr< MEDFileFieldPerMeshPerType > >::const_iterator it=_field_pm_pt.begin();it!=_field_pm_pt.end();it++) - { - const MEDFileFieldPerMeshPerType *fpmt(*it); - if(!fpmt) - continue; - if(fpmt->presenceOfMultiDiscPerGeoType()) - return true; - } - return false; -} - -DataArray *MEDFileFieldPerMesh::getOrCreateAndGetArray() -{ - if(!_father) - throw INTERP_KERNEL::Exception("MEDFileFieldPerMesh::getOrCreateAndGetArray : no father ! internal error !"); - return _father->getOrCreateAndGetArray(); -} - -const DataArray *MEDFileFieldPerMesh::getOrCreateAndGetArray() const -{ - if(!_father) - throw INTERP_KERNEL::Exception("MEDFileFieldPerMesh::getOrCreateAndGetArray : no father ! internal error !"); - return _father->getOrCreateAndGetArray(); -} - -const std::vector& MEDFileFieldPerMesh::getInfo() const -{ - return _father->getInfo(); -} - -/*! - * type,geoTypes,dads,pfls,locs are input parameters. They should have the same size. - * Before the call of this method 'geoTypes','dads','pfls','locs' must be reorganized so that types in geoTypes are contiguous and ordered following typmai2 array. - * It returns 2 output vectors : - * - 'code' of size 3*sz where sz is the number of different values into 'geoTypes' - * - 'notNullPfls' contains sz2 values that are extracted from 'pfls' in which null profiles have been removed. - * 'code' and 'notNullPfls' are in MEDCouplingUMesh::checkTypeConsistencyAndContig format. - */ -void MEDFileFieldPerMesh::SortArraysPerType(const MEDFileFieldGlobsReal *glob, TypeOfField type, const std::vector& geoTypes, const std::vector< std::pair >& dads, const std::vector& pfls, const std::vector& locs, std::vector& code, std::vector& notNullPfls) -{ - int notNullPflsSz=0; - int nbOfArrs=geoTypes.size(); - for(int i=0;i geoTypes3(geoTypes.begin(),geoTypes.end()); - int nbOfDiffGeoTypes=geoTypes3.size(); - code.resize(3*nbOfDiffGeoTypes); - notNullPfls.resize(notNullPflsSz); - notNullPflsSz=0; - int j=0; - for(int i=0;i notNullTmp; - if(pfls[j]) - notNullTmp.push_back(pfls[j]); - j++; - for(;j > tmpDads(dads.begin()+startZone,dads.begin()+j); - std::vector tmpPfls(pfls.begin()+startZone,pfls.begin()+j); - std::vector tmpLocs(locs.begin()+startZone,locs.begin()+j); - code[3*i]=(int)refType; - std::vector refType2(1,refType); - code[3*i+1]=ComputeNbOfElems(glob,type,refType2,tmpDads,tmpLocs); - if(notNullTmp.empty()) - code[3*i+2]=-1; - else - { - notNullPfls[notNullPflsSz]=DataArrayInt::Aggregate(notNullTmp); - code[3*i+2]=notNullPflsSz++; - } - } -} - -/*! - * 'dads' 'geoTypes' and 'locs' are input parameters that should have same size sz. sz should be >=1. - */ -int MEDFileFieldPerMesh::ComputeNbOfElems(const MEDFileFieldGlobsReal *glob, TypeOfField type, const std::vector& geoTypes, const std::vector< std::pair >& dads, const std::vector& locs) -{ - int sz=dads.size(); - int ret=0; - for(int i=0;igetNbOfGaussPtPerCell(locs[i]); - ret+=(dads[i].second-dads[i].first)/nbOfGaussPtPerCell; - } - } - return ret; -} - -std::vector MEDFileFieldPerMesh::getPflsReallyUsed() const -{ - std::vector ret; - std::set ret2; - for(std::vector< MEDCouplingAutoRefCountObjectPtr< MEDFileFieldPerMeshPerType > >::const_iterator it=_field_pm_pt.begin();it!=_field_pm_pt.end();it++) - { - std::vector tmp=(*it)->getPflsReallyUsed(); - for(std::vector::const_iterator it2=tmp.begin();it2!=tmp.end();it2++) - if(ret2.find(*it2)==ret2.end()) - { - ret.push_back(*it2); - ret2.insert(*it2); - } - } - return ret; -} - -std::vector MEDFileFieldPerMesh::getPflsReallyUsedMulti() const -{ - std::vector ret; - for(std::vector< MEDCouplingAutoRefCountObjectPtr< MEDFileFieldPerMeshPerType > >::const_iterator it=_field_pm_pt.begin();it!=_field_pm_pt.end();it++) - { - std::vector tmp=(*it)->getPflsReallyUsedMulti(); - ret.insert(ret.end(),tmp.begin(),tmp.end()); - } - return ret; -} - -std::vector MEDFileFieldPerMesh::getLocsReallyUsed() const -{ - std::vector ret; - std::set ret2; - for(std::vector< MEDCouplingAutoRefCountObjectPtr< MEDFileFieldPerMeshPerType > >::const_iterator it=_field_pm_pt.begin();it!=_field_pm_pt.end();it++) - { - std::vector tmp=(*it)->getLocsReallyUsed(); - for(std::vector::const_iterator it2=tmp.begin();it2!=tmp.end();it2++) - if(ret2.find(*it2)==ret2.end()) - { - ret.push_back(*it2); - ret2.insert(*it2); - } - } - return ret; -} - -std::vector MEDFileFieldPerMesh::getLocsReallyUsedMulti() const -{ - std::vector ret; - for(std::vector< MEDCouplingAutoRefCountObjectPtr< MEDFileFieldPerMeshPerType > >::const_iterator it=_field_pm_pt.begin();it!=_field_pm_pt.end();it++) - { - std::vector tmp=(*it)->getLocsReallyUsedMulti(); - ret.insert(ret.end(),tmp.begin(),tmp.end()); - } - return ret; -} - -bool MEDFileFieldPerMesh::changeMeshNames(const std::vector< std::pair >& modifTab) -{ - for(std::vector< std::pair >::const_iterator it=modifTab.begin();it!=modifTab.end();it++) - { - if((*it).first==_mesh_name) - { - _mesh_name=(*it).second; - return true; - } - } - return false; -} - -bool MEDFileFieldPerMesh::renumberEntitiesLyingOnMesh(const std::string& meshName, const std::vector& oldCode, const std::vector& newCode, const DataArrayInt *renumO2N, - MEDFileFieldGlobsReal& glob) -{ - if(_mesh_name!=meshName) - return false; - std::set typesToKeep; - for(std::size_t i=0;i,std::pair > > entries; - std::vector< const MEDFileFieldPerMeshPerTypePerDisc *> entriesKept; - std::vector< const MEDFileFieldPerMeshPerTypePerDisc *> otherEntries; - getUndergroundDataArrayExt(entries); - DataArray *arr0=getOrCreateAndGetArray();//tony - if(!arr0) - throw INTERP_KERNEL::Exception("MEDFileFieldPerMesh::renumberEntitiesLyingOnMesh : DataArray storing values of field is null !"); - DataArrayDouble *arr=dynamic_cast(arr0);//tony - if(!arr0) - throw INTERP_KERNEL::Exception("MEDFileFieldPerMesh::renumberEntitiesLyingOnMesh : DataArray storing values is double ! Not managed for the moment !"); - int sz=0; - if(!arr) - throw INTERP_KERNEL::Exception("MEDFileFieldPerMesh::renumberEntitiesLyingOnMesh : DataArrayDouble storing values of field is null !"); - for(std::vector< std::pair,std::pair > >::const_iterator it=entries.begin();it!=entries.end();it++) - { - if(typesToKeep.find((*it).first.first)!=typesToKeep.end()) - { - entriesKept.push_back(getLeafGivenTypeAndLocId((*it).first.first,(*it).first.second)); - sz+=(*it).second.second-(*it).second.first; - } - else - otherEntries.push_back(getLeafGivenTypeAndLocId((*it).first.first,(*it).first.second)); - } - MEDCouplingAutoRefCountObjectPtr renumDefrag=DataArrayInt::New(); renumDefrag->alloc(arr->getNumberOfTuples(),1); renumDefrag->fillWithZero(); - //////////////////// - MEDCouplingAutoRefCountObjectPtr explicitIdsOldInMesh=DataArrayInt::New(); explicitIdsOldInMesh->alloc(sz,1);//sz is a majorant of the real size. A realloc will be done after - int *workI2=explicitIdsOldInMesh->getPointer(); - int sz1=0,sz2=0,sid=1; - std::vector< std::vector< const MEDFileFieldPerMeshPerTypePerDisc *> > entriesKeptML=MEDFileFieldPerMeshPerTypePerDisc::SplitPerDiscretization(entriesKept); - // std::vector tupleIdOfStartOfNewChuncksV(entriesKeptML.size()); - for(std::vector< std::vector< const MEDFileFieldPerMeshPerTypePerDisc *> >::const_iterator itL1=entriesKeptML.begin();itL1!=entriesKeptML.end();itL1++,sid++) - { - // tupleIdOfStartOfNewChuncksV[sid-1]=sz2; - MEDCouplingAutoRefCountObjectPtr explicitIdsOldInArr=DataArrayInt::New(); explicitIdsOldInArr->alloc(sz,1); - int *workI=explicitIdsOldInArr->getPointer(); - for(std::vector< const MEDFileFieldPerMeshPerTypePerDisc *>::const_iterator itL2=(*itL1).begin();itL2!=(*itL1).end();itL2++) - { - int delta1=(*itL2)->fillTupleIds(workI); workI+=delta1; sz1+=delta1; - (*itL2)->setLocId(sz2); - (*itL2)->_tmp_work1=(*itL2)->getStart(); - int delta2=(*itL2)->fillEltIdsFromCode(sz2,oldCode,glob,workI2); workI2+=delta2; sz2+=delta2; - } - renumDefrag->setPartOfValuesSimple3(sid,explicitIdsOldInArr->begin(),explicitIdsOldInArr->end(),0,1,1); - } - explicitIdsOldInMesh->reAlloc(sz2); - int tupleIdOfStartOfNewChuncks=arr->getNumberOfTuples()-sz2; - //////////////////// - MEDCouplingAutoRefCountObjectPtr permArrDefrag=renumDefrag->buildPermArrPerLevel(); renumDefrag=0; - // perform redispatching of non concerned MEDFileFieldPerMeshPerTypePerDisc - std::vector< MEDCouplingAutoRefCountObjectPtr > otherEntriesNew; - for(std::vector< const MEDFileFieldPerMeshPerTypePerDisc *>::const_iterator it=otherEntries.begin();it!=otherEntries.end();it++) - { - otherEntriesNew.push_back(MEDFileFieldPerMeshPerTypePerDisc::New(*(*it))); - otherEntriesNew.back()->setNewStart(permArrDefrag->getIJ((*it)->getStart(),0)); - otherEntriesNew.back()->setLocId((*it)->getGeoType()); - } - std::vector< MEDCouplingAutoRefCountObjectPtr > entriesKeptNew; - std::vector< const MEDFileFieldPerMeshPerTypePerDisc *> entriesKeptNew2; - for(std::vector< const MEDFileFieldPerMeshPerTypePerDisc *>::const_iterator it=entriesKept.begin();it!=entriesKept.end();it++) - { - MEDCouplingAutoRefCountObjectPtr elt=MEDFileFieldPerMeshPerTypePerDisc::New(*(*it)); - int newStart=elt->getLocId(); - elt->setLocId((*it)->getGeoType()); - elt->setNewStart(newStart); - elt->_tmp_work1=permArrDefrag->getIJ(elt->_tmp_work1,0); - entriesKeptNew.push_back(elt); - entriesKeptNew2.push_back(elt); - } - MEDCouplingAutoRefCountObjectPtr arr2=arr->renumber(permArrDefrag->getConstPointer()); - // perform redispatching of concerned MEDFileFieldPerMeshPerTypePerDisc -> values are in arr2 - MEDCouplingAutoRefCountObjectPtr explicitIdsNewInMesh=renumO2N->selectByTupleId(explicitIdsOldInMesh->begin(),explicitIdsOldInMesh->end()); - std::vector< std::vector< const MEDFileFieldPerMeshPerTypePerDisc *> > entriesKeptPerDisc=MEDFileFieldPerMeshPerTypePerDisc::SplitPerDiscretization(entriesKeptNew2); - bool ret=false; - for(std::vector< std::vector< const MEDFileFieldPerMeshPerTypePerDisc *> >::const_iterator it4=entriesKeptPerDisc.begin();it4!=entriesKeptPerDisc.end();it4++) - { - sid=0; - /*for(std::vector< const MEDFileFieldPerMeshPerTypePerDisc *>::const_iterator itL2=(*it4).begin();itL2!=(*it4).end();itL2++) - { - MEDFileFieldPerMeshPerTypePerDisc *curNC=const_cast(*itL2); - curNC->setNewStart(permArrDefrag->getIJ((*itL2)->getStart(),0)-tupleIdOfStartOfNewChuncks+tupleIdOfStartOfNewChuncksV[sid]); - }*/ - ret=MEDFileFieldPerMeshPerTypePerDisc::RenumberChunks(tupleIdOfStartOfNewChuncks,*it4,explicitIdsNewInMesh,newCode, - glob,arr2,otherEntriesNew) || ret; - } - if(!ret) - return false; - // Assign new dispatching - assignNewLeaves(otherEntriesNew); - arr->cpyFrom(*arr2); - return true; -} - -/*! - * \param [in,out] globalNum a global numbering counter for the renumbering. - * \param [out] its - list of pair (start,stop) kept - */ -void MEDFileFieldPerMesh::keepOnlySpatialDiscretization(TypeOfField tof, int &globalNum, std::vector< std::pair >& its) -{ - std::vector< MEDCouplingAutoRefCountObjectPtr< MEDFileFieldPerMeshPerType > > ret; - for(std::vector< MEDCouplingAutoRefCountObjectPtr< MEDFileFieldPerMeshPerType > >::iterator it=_field_pm_pt.begin();it!=_field_pm_pt.end();it++) - { - std::vector< std::pair > its2; - if((*it)->keepOnlySpatialDiscretization(tof,globalNum,its2)) - { - ret.push_back(*it); - its.insert(its.end(),its2.begin(),its2.end()); - } - } - _field_pm_pt=ret; -} - -/*! - * \param [in,out] globalNum a global numbering counter for the renumbering. - * \param [out] its - list of pair (start,stop) kept - */ -void MEDFileFieldPerMesh::keepOnlyGaussDiscretization(std::size_t idOfDisc, int &globalNum, std::vector< std::pair >& its) -{ - std::vector< MEDCouplingAutoRefCountObjectPtr< MEDFileFieldPerMeshPerType > > ret; - for(std::vector< MEDCouplingAutoRefCountObjectPtr< MEDFileFieldPerMeshPerType > >::iterator it=_field_pm_pt.begin();it!=_field_pm_pt.end();it++) - { - std::vector< std::pair > its2; - if((*it)->keepOnlyGaussDiscretization(idOfDisc,globalNum,its2)) - { - ret.push_back(*it); - its.insert(its.end(),its2.begin(),its2.end()); - } - } - _field_pm_pt=ret; -} - -void MEDFileFieldPerMesh::assignNewLeaves(const std::vector< MEDCouplingAutoRefCountObjectPtr< MEDFileFieldPerMeshPerTypePerDisc > >& leaves) -{ - std::map > > types; - for( std::vector< MEDCouplingAutoRefCountObjectPtr< MEDFileFieldPerMeshPerTypePerDisc > >::const_iterator it=leaves.begin();it!=leaves.end();it++) - types[(INTERP_KERNEL::NormalizedCellType)(*it)->getLocId()].push_back(*it); - // - std::vector< MEDCouplingAutoRefCountObjectPtr< MEDFileFieldPerMeshPerType > > fieldPmPt(types.size()); - std::map > >::const_iterator it1=types.begin(); - std::vector< MEDCouplingAutoRefCountObjectPtr< MEDFileFieldPerMeshPerType > >::iterator it2=fieldPmPt.begin(); - for(;it1!=types.end();it1++,it2++) - { - MEDCouplingAutoRefCountObjectPtr elt=MEDFileFieldPerMeshPerType::New(this,(INTERP_KERNEL::NormalizedCellType)((*it1).second[0]->getLocId())); - elt->setLeaves((*it1).second); - *it2=elt; - } - _field_pm_pt=fieldPmPt; -} - -void MEDFileFieldPerMesh::changePflsRefsNamesGen(const std::vector< std::pair, std::string > >& mapOfModif) -{ - for(std::vector< MEDCouplingAutoRefCountObjectPtr< MEDFileFieldPerMeshPerType > >::iterator it=_field_pm_pt.begin();it!=_field_pm_pt.end();it++) - (*it)->changePflsRefsNamesGen(mapOfModif); -} - -void MEDFileFieldPerMesh::changeLocsRefsNamesGen(const std::vector< std::pair, std::string > >& mapOfModif) -{ - for(std::vector< MEDCouplingAutoRefCountObjectPtr< MEDFileFieldPerMeshPerType > >::iterator it=_field_pm_pt.begin();it!=_field_pm_pt.end();it++) - (*it)->changeLocsRefsNamesGen(mapOfModif); -} - -/*! - * \param [in] mesh is the whole mesh - */ -MEDCouplingFieldDouble *MEDFileFieldPerMesh::getFieldOnMeshAtLevel(TypeOfField type, const MEDFileFieldGlobsReal *glob, const MEDCouplingMesh *mesh, bool& isPfl, MEDCouplingAutoRefCountObjectPtr& arrOut, const MEDFileFieldNameScope& nasc) const -{ - if(_field_pm_pt.empty()) - throw INTERP_KERNEL::Exception("MEDFileFieldPerMesh::getFieldOnMeshAtLevel : no types field set !"); - // - std::vector< std::pair > dads; - std::vector pfls; - std::vector notNullPflsPerGeoType; - std::vector locs,code; - std::vector geoTypes; - for(std::vector< MEDCouplingAutoRefCountObjectPtr< MEDFileFieldPerMeshPerType > >::const_iterator it=_field_pm_pt.begin();it!=_field_pm_pt.end();it++) - (*it)->getFieldAtLevel(mesh->getMeshDimension(),type,glob,dads,pfls,locs,geoTypes); - // Sort by types - SortArraysPerType(glob,type,geoTypes,dads,pfls,locs,code,notNullPflsPerGeoType); - if(code.empty()) - { - std::ostringstream oss; oss << "MEDFileFieldPerMesh::getFieldOnMeshAtLevel : " << "The field \"" << nasc.getName() << "\" exists but not with such spatial discretization or such dimension specified !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - // - std::vector< MEDCouplingAutoRefCountObjectPtr > notNullPflsPerGeoType2(notNullPflsPerGeoType.begin(),notNullPflsPerGeoType.end()); - std::vector< const DataArrayInt *> notNullPflsPerGeoType3(notNullPflsPerGeoType.begin(),notNullPflsPerGeoType.end()); - if(type!=ON_NODES) - { - DataArrayInt *arr=mesh->checkTypeConsistencyAndContig(code,notNullPflsPerGeoType3); - if(!arr) - return finishField(type,glob,dads,locs,mesh,isPfl,arrOut,nasc); - else - { - MEDCouplingAutoRefCountObjectPtr arr2(arr); - return finishField2(type,glob,dads,locs,geoTypes,mesh,arr,isPfl,arrOut,nasc); - } - } - else - { - if(code.size()!=3) - throw INTERP_KERNEL::Exception("MEDFileFieldPerMesh::getFieldOnMeshAtLevel : internal error #1 !"); - int nb=code[1]; - if(code[2]==-1) - { - if(nb!=mesh->getNumberOfNodes()) - { - std::ostringstream oss; oss << "MEDFileFieldPerMesh::getFieldOnMeshAtLevel : There is a problem there is " << nb << " nodes in field whereas there is " << mesh->getNumberOfNodes(); - oss << " nodes in mesh !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - return finishField(type,glob,dads,locs,mesh,isPfl,arrOut,nasc); - } - else - return finishFieldNode2(glob,dads,locs,mesh,notNullPflsPerGeoType3[0],isPfl,arrOut,nasc); - } -} - -DataArray *MEDFileFieldPerMesh::getFieldOnMeshAtLevelWithPfl(TypeOfField type, const MEDCouplingMesh *mesh, DataArrayInt *&pfl, const MEDFileFieldGlobsReal *glob, const MEDFileFieldNameScope& nasc) const -{ - if(_field_pm_pt.empty()) - throw INTERP_KERNEL::Exception("MEDFileFieldPerMesh::getFieldOnMeshAtLevel : no types field set !"); - // - std::vector > dads; - std::vector pfls; - std::vector notNullPflsPerGeoType; - std::vector locs,code; - std::vector geoTypes; - for(std::vector< MEDCouplingAutoRefCountObjectPtr< MEDFileFieldPerMeshPerType > >::const_iterator it=_field_pm_pt.begin();it!=_field_pm_pt.end();it++) - (*it)->getFieldAtLevel(mesh->getMeshDimension(),type,glob,dads,pfls,locs,geoTypes); - // Sort by types - SortArraysPerType(glob,type,geoTypes,dads,pfls,locs,code,notNullPflsPerGeoType); - if(code.empty()) - { - std::ostringstream oss; oss << "MEDFileFieldPerMesh::getFieldOnMeshAtLevelWithPfl : " << "The field \"" << nasc.getName() << "\" exists but not with such spatial discretization or such dimension specified !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - std::vector< MEDCouplingAutoRefCountObjectPtr > notNullPflsPerGeoType2(notNullPflsPerGeoType.begin(),notNullPflsPerGeoType.end()); - std::vector< const DataArrayInt *> notNullPflsPerGeoType3(notNullPflsPerGeoType.begin(),notNullPflsPerGeoType.end()); - if(type!=ON_NODES) - { - MEDCouplingAutoRefCountObjectPtr arr=mesh->checkTypeConsistencyAndContig(code,notNullPflsPerGeoType3); - return finishField4(dads,arr,mesh->getNumberOfCells(),pfl); - } - else - { - if(code.size()!=3) - throw INTERP_KERNEL::Exception("MEDFileFieldPerMesh::getFieldOnMeshAtLevel : internal error #1 !"); - int nb=code[1]; - if(code[2]==-1) - { - if(nb!=mesh->getNumberOfNodes()) - { - std::ostringstream oss; oss << "MEDFileFieldPerMesh::getFieldOnMeshAtLevel : There is a problem there is " << nb << " nodes in field whereas there is " << mesh->getNumberOfNodes(); - oss << " nodes in mesh !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - } - return finishField4(dads,code[2]==-1?0:notNullPflsPerGeoType3[0],mesh->getNumberOfNodes(),pfl); - } - // - return 0; -} - -void MEDFileFieldPerMesh::getUndergroundDataArrayExt(std::vector< std::pair,std::pair > >& entries) const -{ - int globalSz=0; - int nbOfEntries=0; - for(std::vector< MEDCouplingAutoRefCountObjectPtr< MEDFileFieldPerMeshPerType > >::const_iterator it=_field_pm_pt.begin();it!=_field_pm_pt.end();it++) - { - (*it)->getSizes(globalSz,nbOfEntries); - } - entries.resize(nbOfEntries); - nbOfEntries=0; - for(std::vector< MEDCouplingAutoRefCountObjectPtr< MEDFileFieldPerMeshPerType > >::const_iterator it=_field_pm_pt.begin();it!=_field_pm_pt.end();it++) - { - (*it)->fillValues(nbOfEntries,entries); - } -} - -MEDFileFieldPerMeshPerTypePerDisc *MEDFileFieldPerMesh::getLeafGivenTypeAndLocId(INTERP_KERNEL::NormalizedCellType typ, int locId) -{ - for(std::vector< MEDCouplingAutoRefCountObjectPtr< MEDFileFieldPerMeshPerType > >::iterator it=_field_pm_pt.begin();it!=_field_pm_pt.end();it++) - { - if((*it)->getGeoType()==typ) - return (*it)->getLeafGivenLocId(locId); - } - const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(typ); - std::ostringstream oss; oss << "MEDFileFieldPerMesh::getLeafGivenTypeAndLocId : no such geometric type \"" << cm.getRepr() << "\" in this !" << std::endl; - oss << "Possiblities are : "; - for(std::vector< MEDCouplingAutoRefCountObjectPtr< MEDFileFieldPerMeshPerType > >::const_iterator it=_field_pm_pt.begin();it!=_field_pm_pt.end();it++) - { - const INTERP_KERNEL::CellModel& cm2=INTERP_KERNEL::CellModel::GetCellModel((*it)->getGeoType()); - oss << "\"" << cm2.getRepr() << "\", "; - } - throw INTERP_KERNEL::Exception(oss.str().c_str()); -} - -const MEDFileFieldPerMeshPerTypePerDisc *MEDFileFieldPerMesh::getLeafGivenTypeAndLocId(INTERP_KERNEL::NormalizedCellType typ, int locId) const -{ - for(std::vector< MEDCouplingAutoRefCountObjectPtr< MEDFileFieldPerMeshPerType > >::const_iterator it=_field_pm_pt.begin();it!=_field_pm_pt.end();it++) - { - if((*it)->getGeoType()==typ) - return (*it)->getLeafGivenLocId(locId); - } - const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(typ); - std::ostringstream oss; oss << "MEDFileFieldPerMesh::getLeafGivenTypeAndLocId : no such geometric type \"" << cm.getRepr() << "\" in this !" << std::endl; - oss << "Possiblities are : "; - for(std::vector< MEDCouplingAutoRefCountObjectPtr< MEDFileFieldPerMeshPerType > >::const_iterator it=_field_pm_pt.begin();it!=_field_pm_pt.end();it++) - { - const INTERP_KERNEL::CellModel& cm2=INTERP_KERNEL::CellModel::GetCellModel((*it)->getGeoType()); - oss << "\"" << cm2.getRepr() << "\", "; - } - throw INTERP_KERNEL::Exception(oss.str().c_str()); -} - -int MEDFileFieldPerMesh::addNewEntryIfNecessary(INTERP_KERNEL::NormalizedCellType type) -{ - int i=0; - int pos=std::distance(typmai2,std::find(typmai2,typmai2+MED_N_CELL_FIXED_GEO,type)); - std::vector< MEDCouplingAutoRefCountObjectPtr< MEDFileFieldPerMeshPerType > >::iterator it2=_field_pm_pt.begin(); - for(std::vector< MEDCouplingAutoRefCountObjectPtr< MEDFileFieldPerMeshPerType > >::iterator it=_field_pm_pt.begin();it!=_field_pm_pt.end();it++,i++) - { - INTERP_KERNEL::NormalizedCellType curType=(*it)->getGeoType(); - if(type==curType) - return i; - else - { - int pos2=std::distance(typmai2,std::find(typmai2,typmai2+MED_N_CELL_FIXED_GEO,curType)); - if(pos>pos2) - it2=it+1; - } - } - int ret=std::distance(_field_pm_pt.begin(),it2); - _field_pm_pt.insert(it2,MEDFileFieldPerMeshPerType::New(this,type)); - return ret; -} - -/*! - * 'dads' and 'locs' input parameters have the same number of elements - * \param [in] mesh is \b NOT the global mesh, but the possibly reduced mesh. \a mesh parameter will be directly aggregated in the returned field - */ -MEDCouplingFieldDouble *MEDFileFieldPerMesh::finishField(TypeOfField type, const MEDFileFieldGlobsReal *glob, - const std::vector< std::pair >& dads, const std::vector& locs, - const MEDCouplingMesh *mesh, bool& isPfl, MEDCouplingAutoRefCountObjectPtr& arrOut, const MEDFileFieldNameScope& nasc) const -{ - isPfl=false; - MEDCouplingAutoRefCountObjectPtr ret=MEDCouplingFieldDouble::New(type,ONE_TIME); - ret->setMesh(mesh); ret->setName(nasc.getName().c_str()); ret->setTime(getTime(),getIteration(),getOrder()); ret->setTimeUnit(nasc.getDtUnit().c_str()); - MEDCouplingAutoRefCountObjectPtr da=getOrCreateAndGetArray()->selectByTupleRanges(dads); - const std::vector& infos=getInfo(); - da->setInfoOnComponents(infos); - da->setName(""); - if(type==ON_GAUSS_PT) - { - int offset=0; - int nbOfArrs=dads.size(); - for(int i=0;i > dads2(1,dads[i]); const std::vector locs2(1,locs[i]); - const std::vector geoTypes2(1,INTERP_KERNEL::NORM_ERROR); - int nbOfElems=ComputeNbOfElems(glob,type,geoTypes2,dads2,locs2); - MEDCouplingAutoRefCountObjectPtr di=DataArrayInt::New(); - di->alloc(nbOfElems,1); - di->iota(offset); - const MEDFileFieldLoc& fl=glob->getLocalizationFromId(locs[i]); - ret->setGaussLocalizationOnCells(di->getConstPointer(),di->getConstPointer()+nbOfElems,fl.getRefCoords(),fl.getGaussCoords(),fl.getGaussWeights()); - offset+=nbOfElems; - } - } - arrOut=da; - return ret.retn(); -} - -/*! - * This method is an extension of MEDFileFieldPerMesh::finishField method. It deals with profiles. This method should be called when type is different from ON_NODES. - * 'dads', 'locs' and 'geoTypes' input parameters have the same number of elements. - * No check of this is performed. 'da' array contains an array in old2New style to be applyied to mesh to obtain the right support. - * The order of cells in the returned field is those imposed by the profile. - * \param [in] mesh is the global mesh. - */ -MEDCouplingFieldDouble *MEDFileFieldPerMesh::finishField2(TypeOfField type, const MEDFileFieldGlobsReal *glob, - const std::vector >& dads, const std::vector& locs, - const std::vector& geoTypes, - const MEDCouplingMesh *mesh, const DataArrayInt *da, bool& isPfl, MEDCouplingAutoRefCountObjectPtr& arrOut, const MEDFileFieldNameScope& nasc) const -{ - if(da->isIdentity()) - { - int nbOfTuples=da->getNumberOfTuples(); - if(nbOfTuples==mesh->getNumberOfCells()) - return finishField(type,glob,dads,locs,mesh,isPfl,arrOut,nasc); - } - MEDCouplingAutoRefCountObjectPtr m2=mesh->buildPart(da->getConstPointer(),da->getConstPointer()+da->getNbOfElems()); - m2->setName(mesh->getName().c_str()); - MEDCouplingAutoRefCountObjectPtr ret=finishField(type,glob,dads,locs,m2,isPfl,arrOut,nasc); - isPfl=true; - return ret.retn(); -} - -/*! - * This method is the complement of MEDFileFieldPerMesh::finishField2 method except that this method works for node profiles. - */ -MEDCouplingFieldDouble *MEDFileFieldPerMesh::finishFieldNode2(const MEDFileFieldGlobsReal *glob, - const std::vector >& dads, const std::vector& locs, - const MEDCouplingMesh *mesh, const DataArrayInt *da, bool& isPfl, MEDCouplingAutoRefCountObjectPtr& arrOut, const MEDFileFieldNameScope& nasc) const -{ - if(da->isIdentity()) - { - int nbOfTuples=da->getNumberOfTuples(); - if(nbOfTuples==mesh->getNumberOfNodes())//No problem for NORM_ERROR because it is in context of node - return finishField(ON_NODES,glob,dads,locs,mesh,isPfl,arrOut,nasc); - } - // Treatment of particular case where nodal field on pfl is requested with a meshDimRelToMax=1. - const MEDCouplingUMesh *meshu=dynamic_cast(mesh); - if(meshu) - { - if(meshu->getNodalConnectivity()==0) - { - MEDCouplingAutoRefCountObjectPtr ret=finishField(ON_CELLS,glob,dads,locs,mesh,isPfl,arrOut,nasc); - int nb=da->getNbOfElems(); - const int *ptr=da->getConstPointer(); - MEDCouplingUMesh *meshuc=const_cast(meshu); - meshuc->allocateCells(nb); - for(int i=0;iinsertNextCell(INTERP_KERNEL::NORM_POINT1,1,ptr+i); - meshuc->finishInsertingCells(); - ret->setMesh(meshuc); - const MEDCouplingFieldDiscretization *disc=ret->getDiscretization(); - if(!disc) throw INTERP_KERNEL::Exception("MEDFileFieldPerMesh::finishFieldNode2 : internal error, no discretization on field !"); - disc->checkCoherencyBetween(meshuc,arrOut); - return ret.retn(); - } - } - // - MEDCouplingAutoRefCountObjectPtr ret=finishField(ON_NODES,glob,dads,locs,mesh,isPfl,arrOut,nasc); - isPfl=true; - DataArrayInt *arr2=0; - MEDCouplingAutoRefCountObjectPtr cellIds=mesh->getCellIdsFullyIncludedInNodeIds(da->getConstPointer(),da->getConstPointer()+da->getNbOfElems()); - MEDCouplingAutoRefCountObjectPtr mesh2=mesh->buildPartAndReduceNodes(cellIds->getConstPointer(),cellIds->getConstPointer()+cellIds->getNbOfElems(),arr2); - MEDCouplingAutoRefCountObjectPtr arr3(arr2); - int nnodes=mesh2->getNumberOfNodes(); - if(nnodes==(int)da->getNbOfElems()) - { - MEDCouplingAutoRefCountObjectPtr da3=da->transformWithIndArrR(arr2->begin(),arr2->end()); - arrOut->renumberInPlace(da3->getConstPointer()); - mesh2->setName(mesh->getName().c_str()); - ret->setMesh(mesh2); - return ret.retn(); - } - else - { - std::ostringstream oss; oss << "MEDFileFieldPerMesh::finishFieldNode2 : The field on nodes lies on a node profile so that it is impossible to find a submesh having exactly the same nodes of that profile !!!"; - oss << "So it is impossible to return a well definied MEDCouplingFieldDouble instance on specified mesh on a specified meshDim !" << std::endl; - oss << "To retrieve correctly such a field you have 3 possibilities :" << std::endl; - oss << " - use an another meshDim compatible with the field on nodes (MED file does not have such information)" << std::endl; - oss << " - use an another a meshDimRelToMax equal to 1 -> it will return a mesh with artificial cell POINT1 containing the profile !" << std::endl; - oss << " - if definitely the node profile has no link with mesh connectivity use MEDFileField1TS::getFieldWithProfile or MEDFileFieldMultiTS::getFieldWithProfile methods instead !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - return 0; -} - -/*! - * This method is the most light method of field retrieving. - */ -DataArray *MEDFileFieldPerMesh::finishField4(const std::vector >& dads, const DataArrayInt *pflIn, int nbOfElems, DataArrayInt *&pflOut) const -{ - if(!pflIn) - { - pflOut=DataArrayInt::New(); - pflOut->alloc(nbOfElems,1); - pflOut->iota(0); - } - else - { - pflOut=const_cast(pflIn); - pflOut->incrRef(); - } - MEDCouplingAutoRefCountObjectPtr safePfl(pflOut); - MEDCouplingAutoRefCountObjectPtr da=getOrCreateAndGetArray()->selectByTupleRanges(dads); - const std::vector& infos=getInfo(); - int nbOfComp=infos.size(); - for(int i=0;isetInfoOnComponent(i,infos[i].c_str()); - safePfl->incrRef(); - return da.retn(); -} - - -/// @cond INTERNAL - -class MFFPMIter -{ -public: - static MFFPMIter *NewCell(const std::vector< std::pair > *entities); - static bool IsPresenceOfNode(const std::vector< std::pair > *entities); - virtual ~MFFPMIter() { } - virtual void begin() = 0; - virtual bool finished() const = 0; - virtual void next() = 0; - virtual int current() const = 0; -}; - -class MFFPMIterSimple : public MFFPMIter -{ -public: - MFFPMIterSimple():_pos(0) { } - void begin() { _pos=0; } - bool finished() const { return _pos>=MED_N_CELL_FIXED_GEO; } - void next() { _pos++; } - int current() const { return _pos; } -private: - int _pos; -}; - -class MFFPMIter2 : public MFFPMIter -{ -public: - MFFPMIter2(const std::vector& cts); - void begin() { _it=_ids.begin(); } - bool finished() const { return _it==_ids.end(); } - void next() { _it++; } - int current() const { return *_it; } -private: - std::vector _ids; - std::vector::const_iterator _it; -}; - -MFFPMIter *MFFPMIter::NewCell(const std::vector< std::pair > *entities) -{ - if(!entities) - return new MFFPMIterSimple; - else - { - std::vector tmp; - for(std::vector< std::pair >::const_iterator it=(*entities).begin();it!=(*entities).end();it++) - { - if((*it).first==ON_CELLS || (*it).first==ON_GAUSS_NE || (*it).first==ON_GAUSS_PT) - tmp.push_back((*it).second); - } - return new MFFPMIter2(tmp); - } -} - -bool MFFPMIter::IsPresenceOfNode(const std::vector< std::pair > *entities) -{ - if(!entities) - return true; - else - { - for(std::vector< std::pair >::const_iterator it=(*entities).begin();it!=(*entities).end();it++) - if((*it).first==ON_NODES) - return true; - return false; - } -} - -MFFPMIter2::MFFPMIter2(const std::vector& cts) -{ - std::size_t sz(cts.size()); - _ids.resize(sz); - for(std::size_t i=0;i > *entities):_mesh_iteration(meshIteration),_mesh_order(meshOrder), - _father(fath) -{ - INTERP_KERNEL::AutoPtr meshName(MEDLoaderBase::buildEmptyString(MED_NAME_SIZE)); - INTERP_KERNEL::AutoPtr pflName(MEDLoaderBase::buildEmptyString(MED_NAME_SIZE)); - INTERP_KERNEL::AutoPtr locName(MEDLoaderBase::buildEmptyString(MED_NAME_SIZE)); - const MEDFileUMesh *mmu(dynamic_cast(mm)); - INTERP_KERNEL::AutoCppPtr iter0(MFFPMIter::NewCell(entities)); - for(iter0->begin();!iter0->finished();iter0->next()) - { - int nbProfile (MEDfield23nProfile(fid,nasc.getName().c_str(),getIteration(),getOrder(),MED_CELL ,typmai[iter0->current()],meshCsit+1,meshName,pflName,locName)); - std::string name0(MEDLoaderBase::buildStringFromFortran(meshName,MED_NAME_SIZE+1)); - int nbProfile2(MEDfield23nProfile(fid,nasc.getName().c_str(),getIteration(),getOrder(),MED_NODE_ELEMENT,typmai[iter0->current()],meshCsit+1,meshName,pflName,locName)); - std::string name1(MEDLoaderBase::buildStringFromFortran(meshName,MED_NAME_SIZE+1)); - if(nbProfile>0 || nbProfile2>0) - { - const PartDefinition *pd(0); - if(mmu) - pd=mmu->getPartDefAtLevel(mmu->getRelativeLevOnGeoType(typmai2[iter0->current()]),typmai2[iter0->current()]); - _field_pm_pt.push_back(MEDFileFieldPerMeshPerType::NewOnRead(fid,this,ON_CELLS,typmai2[iter0->current()],nasc,pd)); - if(nbProfile>0) - _mesh_name=name0; - else - _mesh_name=name1; - } - } - if(MFFPMIter::IsPresenceOfNode(entities)) - { - int nbProfile(MEDfield23nProfile(fid,nasc.getName().c_str(),getIteration(),getOrder(),MED_NODE,MED_NONE,meshCsit+1,meshName,pflName,locName)); - if(nbProfile>0) - { - const PartDefinition *pd(0); - if(mmu) - pd=mmu->getPartDefAtLevel(1,INTERP_KERNEL::NORM_ERROR); - _field_pm_pt.push_back(MEDFileFieldPerMeshPerType::NewOnRead(fid,this,ON_NODES,INTERP_KERNEL::NORM_ERROR,nasc,pd)); - _mesh_name=MEDLoaderBase::buildStringFromFortran(meshName,MED_NAME_SIZE+1); - } - } -} - -MEDFileFieldPerMesh::MEDFileFieldPerMesh(MEDFileAnyTypeField1TSWithoutSDA *fath, const MEDCouplingMesh *mesh):_father(fath) -{ - copyTinyInfoFrom(mesh); -} - -void MEDFileFieldGlobs::loadProfileInFile(med_idt fid, int id, const std::string& pflName) -{ - if(id>=(int)_pfls.size()) - _pfls.resize(id+1); - _pfls[id]=DataArrayInt::New(); - int lgth(MEDprofileSizeByName(fid,pflName.c_str())); - _pfls[id]->setName(pflName); - _pfls[id]->alloc(lgth,1); - MEDFILESAFECALLERRD0(MEDprofileRd,(fid,pflName.c_str(),_pfls[id]->getPointer())); - _pfls[id]->applyLin(1,-1,0);//Converting into C format -} - -void MEDFileFieldGlobs::loadProfileInFile(med_idt fid, int i) -{ - INTERP_KERNEL::AutoPtr pflName=MEDLoaderBase::buildEmptyString(MED_NAME_SIZE); - int sz; - MEDFILESAFECALLERRD0(MEDprofileInfo,(fid,i+1,pflName,&sz)); - std::string pflCpp=MEDLoaderBase::buildStringFromFortran(pflName,MED_NAME_SIZE); - if(i>=(int)_pfls.size()) - _pfls.resize(i+1); - _pfls[i]=DataArrayInt::New(); - _pfls[i]->alloc(sz,1); - _pfls[i]->setName(pflCpp.c_str()); - MEDFILESAFECALLERRD0(MEDprofileRd,(fid,pflName,_pfls[i]->getPointer())); - _pfls[i]->applyLin(1,-1,0);//Converting into C format -} - -void MEDFileFieldGlobs::writeGlobals(med_idt fid, const MEDFileWritable& opt) const -{ - int nbOfPfls=_pfls.size(); - for(int i=0;i cpy=_pfls[i]->deepCpy(); - cpy->applyLin(1,1,0); - INTERP_KERNEL::AutoPtr pflName=MEDLoaderBase::buildEmptyString(MED_NAME_SIZE); - MEDLoaderBase::safeStrCpy(_pfls[i]->getName().c_str(),MED_NAME_SIZE,pflName,opt.getTooLongStrPolicy()); - MEDFILESAFECALLERWR0(MEDprofileWr,(fid,pflName,_pfls[i]->getNumberOfTuples(),cpy->getConstPointer())); - } - // - int nbOfLocs=_locs.size(); - for(int i=0;iwriteLL(fid); -} - -void MEDFileFieldGlobs::appendGlobs(const MEDFileFieldGlobs& other, double eps) -{ - std::vector pfls=getPfls(); - for(std::vector< MEDCouplingAutoRefCountObjectPtr >::const_iterator it=other._pfls.begin();it!=other._pfls.end();it++) - { - std::vector::iterator it2=std::find(pfls.begin(),pfls.end(),(*it)->getName()); - if(it2==pfls.end()) - { - _pfls.push_back(*it); - } - else - { - int id=std::distance(pfls.begin(),it2); - if(!(*it)->isEqual(*_pfls[id])) - { - std::ostringstream oss; oss << "MEDFileFieldGlobs::appendGlobs : Profile \"" << (*it)->getName() << "\" already exists and is different from those expecting to be append !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - } - } - std::vector locs=getLocs(); - for(std::vector< MEDCouplingAutoRefCountObjectPtr >::const_iterator it=other._locs.begin();it!=other._locs.end();it++) - { - std::vector::iterator it2=std::find(locs.begin(),locs.end(),(*it)->getName()); - if(it2==locs.end()) - { - _locs.push_back(*it); - } - else - { - int id=std::distance(locs.begin(),it2); - if(!(*it)->isEqual(*_locs[id],eps)) - { - std::ostringstream oss; oss << "MEDFileFieldGlobs::appendGlobs : Localization \"" << (*it)->getName() << "\" already exists and is different from those expecting to be append !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - } - } -} - -void MEDFileFieldGlobs::checkGlobsPflsPartCoherency(const std::vector& pflsUsed) const -{ - for(std::vector::const_iterator it=pflsUsed.begin();it!=pflsUsed.end();it++) - getProfile((*it).c_str()); -} - -void MEDFileFieldGlobs::checkGlobsLocsPartCoherency(const std::vector& locsUsed) const -{ - for(std::vector::const_iterator it=locsUsed.begin();it!=locsUsed.end();it++) - getLocalization((*it).c_str()); -} - -void MEDFileFieldGlobs::loadGlobals(med_idt fid, const MEDFileFieldGlobsReal& real) -{ - std::vector profiles=real.getPflsReallyUsed(); - int sz=profiles.size(); - _pfls.resize(sz); - for(int i=0;i locs=real.getLocsReallyUsed(); - sz=locs.size(); - _locs.resize(sz); - for(int i=0;i)+_locs.capacity()*sizeof(MEDCouplingAutoRefCountObjectPtr); -} - -std::vector MEDFileFieldGlobs::getDirectChildrenWithNull() const -{ - std::vector ret; - for(std::vector< MEDCouplingAutoRefCountObjectPtr< DataArrayInt > >::const_iterator it=_pfls.begin();it!=_pfls.end();it++) - ret.push_back((const DataArrayInt *)*it); - for(std::vector< MEDCouplingAutoRefCountObjectPtr >::const_iterator it=_locs.begin();it!=_locs.end();it++) - ret.push_back((const MEDFileFieldLoc *)*it); - return ret; -} - -MEDFileFieldGlobs *MEDFileFieldGlobs::deepCpy() const -{ - MEDCouplingAutoRefCountObjectPtr ret=new MEDFileFieldGlobs(*this); - std::size_t i=0; - for(std::vector< MEDCouplingAutoRefCountObjectPtr >::const_iterator it=_pfls.begin();it!=_pfls.end();it++,i++) - { - if((const DataArrayInt *)*it) - ret->_pfls[i]=(*it)->deepCpy(); - } - i=0; - for(std::vector< MEDCouplingAutoRefCountObjectPtr >::const_iterator it=_locs.begin();it!=_locs.end();it++,i++) - { - if((const MEDFileFieldLoc*)*it) - ret->_locs[i]=(*it)->deepCpy(); - } - return ret.retn(); -} - -/*! - * \throw if a profile in \a pfls in not in \a this. - * \throw if a localization in \a locs in not in \a this. - * \sa MEDFileFieldGlobs::deepCpyPart - */ -MEDFileFieldGlobs *MEDFileFieldGlobs::shallowCpyPart(const std::vector& pfls, const std::vector& locs) const -{ - MEDCouplingAutoRefCountObjectPtr ret=MEDFileFieldGlobs::New(); - for(std::vector::const_iterator it1=pfls.begin();it1!=pfls.end();it1++) - { - DataArrayInt *pfl=const_cast(getProfile((*it1).c_str())); - if(!pfl) - throw INTERP_KERNEL::Exception("MEDFileFieldGlobs::shallowCpyPart : internal error ! pfl null !"); - pfl->incrRef(); - MEDCouplingAutoRefCountObjectPtr pfl2(pfl); - ret->_pfls.push_back(pfl2); - } - for(std::vector::const_iterator it2=locs.begin();it2!=locs.end();it2++) - { - MEDFileFieldLoc *loc=const_cast(&getLocalization((*it2).c_str())); - if(!loc) - throw INTERP_KERNEL::Exception("MEDFileFieldGlobs::shallowCpyPart : internal error ! loc null !"); - loc->incrRef(); - MEDCouplingAutoRefCountObjectPtr loc2(loc); - ret->_locs.push_back(loc2); - } - ret->setFileName(getFileName()); - return ret.retn(); -} - -/*! - * \throw if a profile in \a pfls in not in \a this. - * \throw if a localization in \a locs in not in \a this. - * \sa MEDFileFieldGlobs::shallowCpyPart - */ -MEDFileFieldGlobs *MEDFileFieldGlobs::deepCpyPart(const std::vector& pfls, const std::vector& locs) const -{ - MEDCouplingAutoRefCountObjectPtr ret=MEDFileFieldGlobs::New(); - for(std::vector::const_iterator it1=pfls.begin();it1!=pfls.end();it1++) - { - DataArrayInt *pfl=const_cast(getProfile((*it1).c_str())); - if(!pfl) - throw INTERP_KERNEL::Exception("MEDFileFieldGlobs::deepCpyPart : internal error ! pfl null !"); - ret->_pfls.push_back(pfl->deepCpy()); - } - for(std::vector::const_iterator it2=locs.begin();it2!=locs.end();it2++) - { - MEDFileFieldLoc *loc=const_cast(&getLocalization((*it2).c_str())); - if(!loc) - throw INTERP_KERNEL::Exception("MEDFileFieldGlobs::deepCpyPart : internal error ! loc null !"); - ret->_locs.push_back(loc->deepCpy()); - } - ret->setFileName(getFileName()); - return ret.retn(); -} - -MEDFileFieldGlobs::MEDFileFieldGlobs(const std::string& fname):_file_name(fname) -{ -} - -MEDFileFieldGlobs::MEDFileFieldGlobs() -{ -} - -MEDFileFieldGlobs::~MEDFileFieldGlobs() -{ -} - -void MEDFileFieldGlobs::simpleRepr(std::ostream& oss) const -{ - oss << "Profiles :\n"; - std::size_t n=_pfls.size(); - for(std::size_t i=0;igetName() << "\"\n"; - else - oss << "EMPTY !\n"; - } - n=_locs.size(); - oss << "Localizations :\n"; - for(std::size_t i=0;isimpleRepr(oss); - else - oss<< "EMPTY !\n"; - } -} - -void MEDFileFieldGlobs::setFileName(const std::string& fileName) -{ - _file_name=fileName; -} - -void MEDFileFieldGlobs::changePflsNamesInStruct(const std::vector< std::pair, std::string > >& mapOfModif) -{ - for(std::vector< MEDCouplingAutoRefCountObjectPtr >::iterator it=_pfls.begin();it!=_pfls.end();it++) - { - DataArrayInt *elt(*it); - if(elt) - { - std::string name(elt->getName()); - for(std::vector< std::pair, std::string > >::const_iterator it2=mapOfModif.begin();it2!=mapOfModif.end();it2++) - { - if(std::find((*it2).first.begin(),(*it2).first.end(),name)!=(*it2).first.end()) - { - elt->setName((*it2).second.c_str()); - return; - } - } - } - } -} - -void MEDFileFieldGlobs::changeLocsNamesInStruct(const std::vector< std::pair, std::string > >& mapOfModif) -{ - for(std::vector< MEDCouplingAutoRefCountObjectPtr >::iterator it=_locs.begin();it!=_locs.end();it++) - { - MEDFileFieldLoc *elt(*it); - if(elt) - { - std::string name(elt->getName()); - for(std::vector< std::pair, std::string > >::const_iterator it2=mapOfModif.begin();it2!=mapOfModif.end();it2++) - { - if(std::find((*it2).first.begin(),(*it2).first.end(),name)!=(*it2).first.end()) - { - elt->setName((*it2).second.c_str()); - return; - } - } - } - } -} - -int MEDFileFieldGlobs::getNbOfGaussPtPerCell(int locId) const -{ - if(locId<0 || locId>=(int)_locs.size()) - throw INTERP_KERNEL::Exception("MEDFileFieldGlobs::getNbOfGaussPtPerCell : Invalid localization id !"); - return _locs[locId]->getNbOfGaussPtPerCell(); -} - -const MEDFileFieldLoc& MEDFileFieldGlobs::getLocalization(const std::string& locName) const -{ - return getLocalizationFromId(getLocalizationId(locName)); -} - -const MEDFileFieldLoc& MEDFileFieldGlobs::getLocalizationFromId(int locId) const -{ - if(locId<0 || locId>=(int)_locs.size()) - throw INTERP_KERNEL::Exception("MEDFileFieldGlobs::getLocalizationFromId : Invalid localization id !"); - return *_locs[locId]; -} - -/// @cond INTERNAL -namespace ParaMEDMEMImpl -{ - class LocFinder - { - public: - LocFinder(const std::string& loc):_loc(loc) { } - bool operator() (const MEDCouplingAutoRefCountObjectPtr& loc) { return loc->isName(_loc); } - private: - const std::string &_loc; - }; - - class PflFinder - { - public: - PflFinder(const std::string& pfl):_pfl(pfl) { } - bool operator() (const MEDCouplingAutoRefCountObjectPtr& pfl) { return _pfl==pfl->getName(); } - private: - const std::string& _pfl; - }; -} -/// @endcond - -int MEDFileFieldGlobs::getLocalizationId(const std::string& loc) const -{ - std::vector< MEDCouplingAutoRefCountObjectPtr >::const_iterator it=std::find_if(_locs.begin(),_locs.end(),ParaMEDMEMImpl::LocFinder(loc)); - if(it==_locs.end()) - { - std::ostringstream oss; oss << "MEDFileFieldGlobs::getLocalisationId : no such localisation name : \"" << loc << "\" Possible localizations are : "; - for(it=_locs.begin();it!=_locs.end();it++) - oss << "\"" << (*it)->getName() << "\", "; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - return std::distance(_locs.begin(),it); -} - -/*! - * The returned value is never null. - */ -const DataArrayInt *MEDFileFieldGlobs::getProfile(const std::string& pflName) const -{ - std::string pflNameCpp(pflName); - std::vector< MEDCouplingAutoRefCountObjectPtr >::const_iterator it=std::find_if(_pfls.begin(),_pfls.end(),ParaMEDMEMImpl::PflFinder(pflNameCpp)); - if(it==_pfls.end()) - { - std::ostringstream oss; oss << "MEDFileFieldGlobs::getProfile: no such profile name : \"" << pflNameCpp << "\" Possible profiles are : "; - for(it=_pfls.begin();it!=_pfls.end();it++) - oss << "\"" << (*it)->getName() << "\", "; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - return *it; -} - -const DataArrayInt *MEDFileFieldGlobs::getProfileFromId(int pflId) const -{ - if(pflId<0 || pflId>=(int)_pfls.size()) - throw INTERP_KERNEL::Exception("MEDFileFieldGlobs::getProfileFromId : Invalid profile id !"); - return _pfls[pflId]; -} - -MEDFileFieldLoc& MEDFileFieldGlobs::getLocalizationFromId(int locId) -{ - if(locId<0 || locId>=(int)_locs.size()) - throw INTERP_KERNEL::Exception("MEDFileFieldGlobs::getLocalizationFromId : Invalid localization id !"); - return *_locs[locId]; -} - -MEDFileFieldLoc& MEDFileFieldGlobs::getLocalization(const std::string& locName) -{ - return getLocalizationFromId(getLocalizationId(locName)); -} - -/*! - * The returned value is never null. - */ -DataArrayInt *MEDFileFieldGlobs::getProfile(const std::string& pflName) -{ - std::string pflNameCpp(pflName); - std::vector< MEDCouplingAutoRefCountObjectPtr >::iterator it=std::find_if(_pfls.begin(),_pfls.end(),ParaMEDMEMImpl::PflFinder(pflNameCpp)); - if(it==_pfls.end()) - { - std::ostringstream oss; oss << "MEDFileFieldGlobs::getProfile: no such profile name : \"" << pflNameCpp << "\" Possible profiles are : "; - for(it=_pfls.begin();it!=_pfls.end();it++) - oss << "\"" << (*it)->getName() << "\", "; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - return *it; -} - -DataArrayInt *MEDFileFieldGlobs::getProfileFromId(int pflId) -{ - if(pflId<0 || pflId>=(int)_pfls.size()) - throw INTERP_KERNEL::Exception("MEDFileFieldGlobs::getProfileFromId : Invalid profile id !"); - return _pfls[pflId]; -} - -void MEDFileFieldGlobs::killProfileIds(const std::vector& pflIds) -{ - std::vector< MEDCouplingAutoRefCountObjectPtr > newPfls; - int i=0; - for(std::vector< MEDCouplingAutoRefCountObjectPtr >::const_iterator it=_pfls.begin();it!=_pfls.end();it++,i++) - { - if(std::find(pflIds.begin(),pflIds.end(),i)==pflIds.end()) - newPfls.push_back(*it); - } - _pfls=newPfls; -} - -void MEDFileFieldGlobs::killLocalizationIds(const std::vector& locIds) -{ - std::vector< MEDCouplingAutoRefCountObjectPtr > newLocs; - int i=0; - for(std::vector< MEDCouplingAutoRefCountObjectPtr >::const_iterator it=_locs.begin();it!=_locs.end();it++,i++) - { - if(std::find(locIds.begin(),locIds.end(),i)==locIds.end()) - newLocs.push_back(*it); - } - _locs=newLocs; -} - -std::vector MEDFileFieldGlobs::getPfls() const -{ - int sz=_pfls.size(); - std::vector ret(sz); - for(int i=0;igetName(); - return ret; -} - -std::vector MEDFileFieldGlobs::getLocs() const -{ - int sz=_locs.size(); - std::vector ret(sz); - for(int i=0;igetName(); - return ret; -} - -bool MEDFileFieldGlobs::existsPfl(const std::string& pflName) const -{ - std::vector v=getPfls(); - std::string s(pflName); - return std::find(v.begin(),v.end(),s)!=v.end(); -} - -bool MEDFileFieldGlobs::existsLoc(const std::string& locName) const -{ - std::vector v=getLocs(); - std::string s(locName); - return std::find(v.begin(),v.end(),s)!=v.end(); -} - -std::vector< std::vector > MEDFileFieldGlobs::whichAreEqualProfiles() const -{ - std::map > m; - int i=0; - for(std::vector< MEDCouplingAutoRefCountObjectPtr >::const_iterator it=_pfls.begin();it!=_pfls.end();it++,i++) - { - const DataArrayInt *tmp=(*it); - if(tmp) - { - m[tmp->getHashCode()].push_back(i); - } - } - std::vector< std::vector > ret; - for(std::map >::const_iterator it2=m.begin();it2!=m.end();it2++) - { - if((*it2).second.size()>1) - { - std::vector ret0; - bool equalityOrNot=false; - for(std::vector::const_iterator it3=(*it2).second.begin();it3!=(*it2).second.end();it3++) - { - std::vector::const_iterator it4=it3; it4++; - for(;it4!=(*it2).second.end();it4++) - { - if(_pfls[*it3]->isEqualWithoutConsideringStr(*_pfls[*it4])) - { - if(!equalityOrNot) - ret0.push_back(*it3); - ret0.push_back(*it4); - equalityOrNot=true; - } - } - } - if(!ret0.empty()) - ret.push_back(ret0); - } - } - return ret; -} - -std::vector< std::vector > MEDFileFieldGlobs::whichAreEqualLocs(double eps) const -{ - throw INTERP_KERNEL::Exception("MEDFileFieldGlobs::whichAreEqualLocs : no implemented yet ! Sorry !"); -} - -void MEDFileFieldGlobs::appendProfile(DataArrayInt *pfl) -{ - std::string name(pfl->getName()); - if(name.empty()) - throw INTERP_KERNEL::Exception("MEDFileFieldGlobs::appendProfile : unsupported profiles with no name !"); - for(std::vector< MEDCouplingAutoRefCountObjectPtr >::const_iterator it=_pfls.begin();it!=_pfls.end();it++) - if(name==(*it)->getName()) - { - if(!pfl->isEqual(*(*it))) - { - std::ostringstream oss; oss << "MEDFileFieldGlobs::appendProfile : profile \"" << name << "\" already exists and is different from existing !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - } - pfl->incrRef(); - _pfls.push_back(pfl); -} - -void MEDFileFieldGlobs::appendLoc(const std::string& locName, INTERP_KERNEL::NormalizedCellType geoType, const std::vector& refCoo, const std::vector& gsCoo, const std::vector& w) -{ - std::string name(locName); - if(name.empty()) - throw INTERP_KERNEL::Exception("MEDFileFieldGlobs::appendLoc : unsupported localizations with no name !"); - MEDCouplingAutoRefCountObjectPtr obj=MEDFileFieldLoc::New(locName,geoType,refCoo,gsCoo,w); - for(std::vector< MEDCouplingAutoRefCountObjectPtr >::const_iterator it=_locs.begin();it!=_locs.end();it++) - if((*it)->isName(locName)) - { - if(!(*it)->isEqual(*obj,1e-12)) - { - std::ostringstream oss; oss << "MEDFileFieldGlobs::appendLoc : localization \"" << name << "\" already exists and is different from existing !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - } - _locs.push_back(obj); -} - -std::string MEDFileFieldGlobs::createNewNameOfPfl() const -{ - std::vector names=getPfls(); - return CreateNewNameNotIn("NewPfl_",names); -} - -std::string MEDFileFieldGlobs::createNewNameOfLoc() const -{ - std::vector names=getLocs(); - return CreateNewNameNotIn("NewLoc_",names); -} - -std::string MEDFileFieldGlobs::CreateNewNameNotIn(const std::string& prefix, const std::vector& namesToAvoid) -{ - for(std::size_t sz=0;sz<100000;sz++) - { - std::ostringstream tryName; - tryName << prefix << sz; - if(std::find(namesToAvoid.begin(),namesToAvoid.end(),tryName.str())==namesToAvoid.end()) - return tryName.str(); - } - throw INTERP_KERNEL::Exception("MEDFileFieldGlobs::CreateNewNameNotIn : impossible to create an additional profile limit of 100000 profiles reached !"); -} - -/*! - * Creates a MEDFileFieldGlobsReal on a given file name. Nothing is read here. - * \param [in] fname - the file name. - */ -MEDFileFieldGlobsReal::MEDFileFieldGlobsReal(const std::string& fname):_globals(MEDFileFieldGlobs::New(fname)) -{ -} - -/*! - * Creates an empty MEDFileFieldGlobsReal. - */ -MEDFileFieldGlobsReal::MEDFileFieldGlobsReal():_globals(MEDFileFieldGlobs::New()) -{ -} - -std::size_t MEDFileFieldGlobsReal::getHeapMemorySizeWithoutChildren() const -{ - return 0; -} - -std::vector MEDFileFieldGlobsReal::getDirectChildrenWithNull() const -{ - std::vector ret; - ret.push_back((const MEDFileFieldGlobs *)_globals); - return ret; -} - -/*! - * Returns a string describing profiles and Gauss points held in \a this. - * \return std::string - the description string. - */ -void MEDFileFieldGlobsReal::simpleReprGlobs(std::ostream& oss) const -{ - const MEDFileFieldGlobs *glob=_globals; - std::ostringstream oss2; oss2 << glob; - std::string stars(oss2.str().length(),'*'); - oss << "Globals information on fields (at " << oss2.str() << "):" << "\n************************************" << stars << "\n\n"; - if(glob) - glob->simpleRepr(oss); - else - oss << "NO GLOBAL INFORMATION !\n"; -} - -void MEDFileFieldGlobsReal::resetContent() -{ - _globals=MEDFileFieldGlobs::New(); -} - -MEDFileFieldGlobsReal::~MEDFileFieldGlobsReal() -{ -} - -/*! - * Copies references to profiles and Gauss points from another MEDFileFieldGlobsReal. - * \param [in] other - the other MEDFileFieldGlobsReal to copy data from. - */ -void MEDFileFieldGlobsReal::shallowCpyGlobs(const MEDFileFieldGlobsReal& other) -{ - _globals=other._globals; -} - -/*! - * Copies references to ** only used ** by \a this, profiles and Gauss points from another MEDFileFieldGlobsReal. - * \param [in] other - the other MEDFileFieldGlobsReal to copy data from. - */ -void MEDFileFieldGlobsReal::shallowCpyOnlyUsedGlobs(const MEDFileFieldGlobsReal& other) -{ - const MEDFileFieldGlobs *otherg(other._globals); - if(!otherg) - return ; - _globals=otherg->shallowCpyPart(getPflsReallyUsed(),getLocsReallyUsed()); -} - -/*! - * Copies deeply to ** only used ** by \a this, profiles and Gauss points from another MEDFileFieldGlobsReal. - * \param [in] other - the other MEDFileFieldGlobsReal to copy data from. - */ -void MEDFileFieldGlobsReal::deepCpyOnlyUsedGlobs(const MEDFileFieldGlobsReal& other) -{ - const MEDFileFieldGlobs *otherg(other._globals); - if(!otherg) - return ; - _globals=otherg->deepCpyPart(getPflsReallyUsed(),getLocsReallyUsed()); -} - -void MEDFileFieldGlobsReal::deepCpyGlobs(const MEDFileFieldGlobsReal& other) -{ - _globals=other._globals; - if((const MEDFileFieldGlobs *)_globals) - _globals=other._globals->deepCpy(); -} - -/*! - * Adds profiles and Gauss points held by another MEDFileFieldGlobsReal to \a this one. - * \param [in] other - the MEDFileFieldGlobsReal to copy data from. - * \param [in] eps - a precision used to compare Gauss points with same name held by - * \a this and \a other MEDFileFieldGlobsReal. - * \throw If \a this and \a other hold profiles with equal names but different ids. - * \throw If \a this and \a other hold different Gauss points with equal names. - */ -void MEDFileFieldGlobsReal::appendGlobs(const MEDFileFieldGlobsReal& other, double eps) -{ - const MEDFileFieldGlobs *thisGlobals(_globals),*otherGlobals(other._globals); - if(thisGlobals==otherGlobals) - return ; - if(!thisGlobals) - { - _globals=other._globals; - return ; - } - _globals->appendGlobs(*other._globals,eps); -} - -void MEDFileFieldGlobsReal::checkGlobsCoherency() const -{ - checkGlobsPflsPartCoherency(); - checkGlobsLocsPartCoherency(); -} - -void MEDFileFieldGlobsReal::checkGlobsPflsPartCoherency() const -{ - contentNotNull()->checkGlobsPflsPartCoherency(getPflsReallyUsed()); -} - -void MEDFileFieldGlobsReal::checkGlobsLocsPartCoherency() const -{ - contentNotNull()->checkGlobsLocsPartCoherency(getLocsReallyUsed()); -} - -void MEDFileFieldGlobsReal::loadProfileInFile(med_idt fid, int id, const std::string& pflName) -{ - contentNotNull()->loadProfileInFile(fid,id,pflName); -} - -void MEDFileFieldGlobsReal::loadProfileInFile(med_idt fid, int id) -{ - contentNotNull()->loadProfileInFile(fid,id); -} - -void MEDFileFieldGlobsReal::loadGlobals(med_idt fid) -{ - contentNotNull()->loadGlobals(fid,*this); -} - -void MEDFileFieldGlobsReal::loadAllGlobals(med_idt fid) -{ - contentNotNull()->loadAllGlobals(fid); -} - -void MEDFileFieldGlobsReal::writeGlobals(med_idt fid, const MEDFileWritable& opt) const -{ - contentNotNull()->writeGlobals(fid,opt); -} - -/*! - * Returns names of all profiles. To get only used profiles call getPflsReallyUsed() - * or getPflsReallyUsedMulti(). - * \return std::vector - a sequence of names of all profiles. - */ -std::vector MEDFileFieldGlobsReal::getPfls() const -{ - return contentNotNull()->getPfls(); -} - -/*! - * Returns names of all localizations. To get only used localizations call getLocsReallyUsed() - * or getLocsReallyUsedMulti(). - * \return std::vector - a sequence of names of all localizations. - */ -std::vector MEDFileFieldGlobsReal::getLocs() const -{ - return contentNotNull()->getLocs(); -} - -/*! - * Checks if the profile with a given name exists. - * \param [in] pflName - the profile name of interest. - * \return bool - \c true if the profile named \a pflName exists. - */ -bool MEDFileFieldGlobsReal::existsPfl(const std::string& pflName) const -{ - return contentNotNull()->existsPfl(pflName); -} - -/*! - * Checks if the localization with a given name exists. - * \param [in] locName - the localization name of interest. - * \return bool - \c true if the localization named \a locName exists. - */ -bool MEDFileFieldGlobsReal::existsLoc(const std::string& locName) const -{ - return contentNotNull()->existsLoc(locName); -} - -std::string MEDFileFieldGlobsReal::createNewNameOfPfl() const -{ - return contentNotNull()->createNewNameOfPfl(); -} - -std::string MEDFileFieldGlobsReal::createNewNameOfLoc() const -{ - return contentNotNull()->createNewNameOfLoc(); -} - -/*! - * Sets the name of a MED file. - * \param [inout] fileName - the file name. - */ -void MEDFileFieldGlobsReal::setFileName(const std::string& fileName) -{ - contentNotNull()->setFileName(fileName); -} - -/*! - * Finds equal profiles. Two profiles are considered equal if they contain the same ids - * in the same order. - * \return std::vector< std::vector > - a sequence of groups of equal profiles. - * Each item of this sequence is a vector containing ids of equal profiles. - */ -std::vector< std::vector > MEDFileFieldGlobsReal::whichAreEqualProfiles() const -{ - return contentNotNull()->whichAreEqualProfiles(); -} - -/*! - * Finds equal localizations. - * \param [in] eps - a precision used to compare real values of the localizations. - * \return std::vector< std::vector > - a sequence of groups of equal localizations. - * Each item of this sequence is a vector containing ids of equal localizations. - */ -std::vector< std::vector > MEDFileFieldGlobsReal::whichAreEqualLocs(double eps) const -{ - return contentNotNull()->whichAreEqualLocs(eps); -} - -/*! - * Renames the profiles. References to profiles (a reference is a profile name) are not changed. - * \param [in] mapOfModif - a sequence describing required renaming. 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 name of the first item. - */ -void MEDFileFieldGlobsReal::changePflsNamesInStruct(const std::vector< std::pair, std::string > >& mapOfModif) -{ - contentNotNull()->changePflsNamesInStruct(mapOfModif); -} - -/*! - * Renames the localizations. References to localizations (a reference is a localization name) are not changed. - * \param [in] mapOfModif - a sequence describing required renaming. 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 name of the first item. - */ -void MEDFileFieldGlobsReal::changeLocsNamesInStruct(const std::vector< std::pair, std::string > >& mapOfModif) -{ - contentNotNull()->changeLocsNamesInStruct(mapOfModif); -} - -/*! - * Replaces references to some profiles (a reference is a profile name) by references - * to other profiles and, contrary to changePflsRefsNamesGen(), renames the profiles - * them-selves accordingly.
- * This method is a generalization of changePflName(). - * \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. - * \sa changePflsRefsNamesGen() - * \sa changePflName() - */ -void MEDFileFieldGlobsReal::changePflsNames(const std::vector< std::pair, std::string > >& mapOfModif) -{ - changePflsRefsNamesGen(mapOfModif); - changePflsNamesInStruct(mapOfModif); -} - -/*! - * Replaces references to some localizations (a reference is a localization name) by references - * to other localizations and, contrary to changeLocsRefsNamesGen(), renames the localizations - * them-selves accordingly.
- * This method is a generalization of changeLocName(). - * \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. - * \sa changeLocsRefsNamesGen() - * \sa changeLocName() - */ -void MEDFileFieldGlobsReal::changeLocsNames(const std::vector< std::pair, std::string > >& mapOfModif) -{ - changeLocsRefsNamesGen(mapOfModif); - changeLocsNamesInStruct(mapOfModif); -} - -/*! - * Renames the profile having a given name and updates references to this profile. - * \param [in] oldName - the name of the profile to rename. - * \param [in] newName - a new name of the profile. - * \sa changePflsNames(). - */ -void MEDFileFieldGlobsReal::changePflName(const std::string& oldName, const std::string& newName) -{ - std::vector< std::pair, std::string > > mapOfModif(1); - std::pair, std::string > p(std::vector(1,std::string(oldName)),std::string(newName)); - mapOfModif[0]=p; - changePflsNames(mapOfModif); -} - -/*! - * Renames the localization having a given name and updates references to this localization. - * \param [in] oldName - the name of the localization to rename. - * \param [in] newName - a new name of the localization. - * \sa changeLocsNames(). - */ -void MEDFileFieldGlobsReal::changeLocName(const std::string& oldName, const std::string& newName) -{ - std::vector< std::pair, std::string > > mapOfModif(1); - std::pair, std::string > p(std::vector(1,std::string(oldName)),std::string(newName)); - mapOfModif[0]=p; - changeLocsNames(mapOfModif); -} - -/*! - * Removes duplicated profiles. Returns a map used to update references to removed - * profiles via changePflsRefsNamesGen(). - * Equal profiles are found using whichAreEqualProfiles(). - * \return std::vector< std::pair, std::string > > - - * a sequence describing the performed replacements of profiles. Each element of - * this sequence is a pair whose - * - the first item is a vector of profile names replaced by the second item, - * - the second item is a profile name replacing every profile of the first item. - */ -std::vector< std::pair, std::string > > MEDFileFieldGlobsReal::zipPflsNames() -{ - std::vector< std::vector > pseudoRet=whichAreEqualProfiles(); - std::vector< std::pair, std::string > > ret(pseudoRet.size()); - int i=0; - for(std::vector< std::vector >::const_iterator it=pseudoRet.begin();it!=pseudoRet.end();it++,i++) - { - std::vector< std::string > tmp((*it).size()); - int j=0; - for(std::vector::const_iterator it2=(*it).begin();it2!=(*it).end();it2++,j++) - tmp[j]=std::string(getProfileFromId(*it2)->getName()); - std::pair, std::string > p(tmp,tmp.front()); - ret[i]=p; - std::vector tmp2((*it).begin()+1,(*it).end()); - killProfileIds(tmp2); - } - changePflsRefsNamesGen(ret); - return ret; -} - -/*! - * Removes duplicated localizations. Returns a map used to update references to removed - * localizations via changeLocsRefsNamesGen(). - * Equal localizations are found using whichAreEqualLocs(). - * \param [in] eps - a precision used to compare real values of the localizations. - * \return std::vector< std::pair, std::string > > - - * a sequence describing the performed replacements of localizations. Each element of - * this sequence is a pair whose - * - the first item is a vector of localization names replaced by the second item, - * - the second item is a localization name replacing every localization of the first item. - */ -std::vector< std::pair, std::string > > MEDFileFieldGlobsReal::zipLocsNames(double eps) -{ - std::vector< std::vector > pseudoRet=whichAreEqualLocs(eps); - std::vector< std::pair, std::string > > ret(pseudoRet.size()); - int i=0; - for(std::vector< std::vector >::const_iterator it=pseudoRet.begin();it!=pseudoRet.end();it++,i++) - { - std::vector< std::string > tmp((*it).size()); - int j=0; - for(std::vector::const_iterator it2=(*it).begin();it2!=(*it).end();it2++,j++) - tmp[j]=std::string(getLocalizationFromId(*it2).getName()); - std::pair, std::string > p(tmp,tmp.front()); - ret[i]=p; - std::vector tmp2((*it).begin()+1,(*it).end()); - killLocalizationIds(tmp2); - } - changeLocsRefsNamesGen(ret); - return ret; -} - -/*! - * Returns number of Gauss points per cell in a given localization. - * \param [in] locId - an id of the localization of interest. - * \return int - the number of the Gauss points per cell. - */ -int MEDFileFieldGlobsReal::getNbOfGaussPtPerCell(int locId) const -{ - return contentNotNull()->getNbOfGaussPtPerCell(locId); -} - -/*! - * Returns an id of a localization by its name. - * \param [in] loc - the localization name of interest. - * \return int - the id of the localization. - * \throw If there is no a localization named \a loc. - */ -int MEDFileFieldGlobsReal::getLocalizationId(const std::string& loc) const -{ - return contentNotNull()->getLocalizationId(loc); -} - -/*! - * Returns the name of the MED file. - * \return const std::string& - the MED file name. - */ -std::string MEDFileFieldGlobsReal::getFileName() const -{ - return contentNotNull()->getFileName(); -} - -/*! - * Returns a localization object by its name. - * \param [in] locName - the name of the localization of interest. - * \return const MEDFileFieldLoc& - the localization object having the name \a locName. - * \throw If there is no a localization named \a locName. - */ -const MEDFileFieldLoc& MEDFileFieldGlobsReal::getLocalization(const std::string& locName) const -{ - return contentNotNull()->getLocalization(locName); -} - -/*! - * Returns a localization object by its id. - * \param [in] locId - the id of the localization of interest. - * \return const MEDFileFieldLoc& - the localization object having the id \a locId. - * \throw If there is no a localization with id \a locId. - */ -const MEDFileFieldLoc& MEDFileFieldGlobsReal::getLocalizationFromId(int locId) const -{ - return contentNotNull()->getLocalizationFromId(locId); -} - -/*! - * Returns a profile array by its name. - * \param [in] pflName - the name of the profile of interest. - * \return const DataArrayInt * - the profile array having the name \a pflName. - * \throw If there is no a profile named \a pflName. - */ -const DataArrayInt *MEDFileFieldGlobsReal::getProfile(const std::string& pflName) const -{ - return contentNotNull()->getProfile(pflName); -} - -/*! - * Returns a profile array by its id. - * \param [in] pflId - the id of the profile of interest. - * \return const DataArrayInt * - the profile array having the id \a pflId. - * \throw If there is no a profile with id \a pflId. - */ -const DataArrayInt *MEDFileFieldGlobsReal::getProfileFromId(int pflId) const -{ - return contentNotNull()->getProfileFromId(pflId); -} - -/*! - * Returns a localization object, apt for modification, by its id. - * \param [in] locId - the id of the localization of interest. - * \return MEDFileFieldLoc& - a non-const reference to the localization object - * having the id \a locId. - * \throw If there is no a localization with id \a locId. - */ -MEDFileFieldLoc& MEDFileFieldGlobsReal::getLocalizationFromId(int locId) -{ - return contentNotNull()->getLocalizationFromId(locId); -} - -/*! - * Returns a localization object, apt for modification, by its name. - * \param [in] locName - the name of the localization of interest. - * \return MEDFileFieldLoc& - a non-const reference to the localization object - * having the name \a locName. - * \throw If there is no a localization named \a locName. - */ -MEDFileFieldLoc& MEDFileFieldGlobsReal::getLocalization(const std::string& locName) -{ - return contentNotNull()->getLocalization(locName); -} - -/*! - * Returns a profile array, apt for modification, by its name. - * \param [in] pflName - the name of the profile of interest. - * \return DataArrayInt * - a non-const pointer to the profile array having the name \a pflName. - * \throw If there is no a profile named \a pflName. - */ -DataArrayInt *MEDFileFieldGlobsReal::getProfile(const std::string& pflName) -{ - return contentNotNull()->getProfile(pflName); -} - -/*! - * Returns a profile array, apt for modification, by its id. - * \param [in] pflId - the id of the profile of interest. - * \return DataArrayInt * - a non-const pointer to the profile array having the id \a pflId. - * \throw If there is no a profile with id \a pflId. - */ -DataArrayInt *MEDFileFieldGlobsReal::getProfileFromId(int pflId) -{ - return contentNotNull()->getProfileFromId(pflId); -} - -/*! - * Removes profiles given by their ids. No data is updated to track this removal. - * \param [in] pflIds - a sequence of ids of the profiles to remove. - */ -void MEDFileFieldGlobsReal::killProfileIds(const std::vector& pflIds) -{ - contentNotNull()->killProfileIds(pflIds); -} - -/*! - * Removes localizations given by their ids. No data is updated to track this removal. - * \param [in] locIds - a sequence of ids of the localizations to remove. - */ -void MEDFileFieldGlobsReal::killLocalizationIds(const std::vector& locIds) -{ - contentNotNull()->killLocalizationIds(locIds); -} - -/*! - * Stores a profile array. - * \param [in] pfl - the profile array to store. - * \throw If the name of \a pfl is empty. - * \throw If a profile with the same name as that of \a pfl already exists but contains - * different ids. - */ -void MEDFileFieldGlobsReal::appendProfile(DataArrayInt *pfl) -{ - contentNotNull()->appendProfile(pfl); -} - -/*! - * Adds a new localization of Gauss points. - * \param [in] locName - the name of the new localization. - * \param [in] geoType - a geometrical type of the reference cell. - * \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] w - the weights of Gauss points. - * \throw If \a locName is empty. - * \throw If a localization with the name \a locName already exists but is - * different form the new one. - */ -void MEDFileFieldGlobsReal::appendLoc(const std::string& locName, INTERP_KERNEL::NormalizedCellType geoType, const std::vector& refCoo, const std::vector& gsCoo, const std::vector& w) -{ - contentNotNull()->appendLoc(locName,geoType,refCoo,gsCoo,w); -} - -MEDFileFieldGlobs *MEDFileFieldGlobsReal::contentNotNull() -{ - MEDFileFieldGlobs *g(_globals); - if(!g) - throw INTERP_KERNEL::Exception("MEDFileFieldGlobsReal::contentNotNull : no content in not const !"); - return g; -} - -const MEDFileFieldGlobs *MEDFileFieldGlobsReal::contentNotNull() const -{ - const MEDFileFieldGlobs *g(_globals); - if(!g) - throw INTERP_KERNEL::Exception("MEDFileFieldGlobsReal::contentNotNull : no content in const !"); - return g; -} - -//= MEDFileFieldNameScope - -MEDFileFieldNameScope::MEDFileFieldNameScope() -{ -} - -MEDFileFieldNameScope::MEDFileFieldNameScope(const std::string& fieldName):_name(fieldName) -{ -} - -/*! - * Returns the name of \a this field. - * \return std::string - a string containing the field name. - */ -std::string MEDFileFieldNameScope::getName() const -{ - return _name; -} - -/*! - * Sets name of \a this field - * \param [in] name - the new field name. - */ -void MEDFileFieldNameScope::setName(const std::string& fieldName) -{ - _name=fieldName; -} - -std::string MEDFileFieldNameScope::getDtUnit() const -{ - return _dt_unit; -} - -void MEDFileFieldNameScope::setDtUnit(const std::string& dtUnit) -{ - _dt_unit=dtUnit; -} - -void MEDFileFieldNameScope::copyNameScope(const MEDFileFieldNameScope& other) -{ - _name=other._name; - _dt_unit=other._dt_unit; -} - -//= MEDFileAnyTypeField1TSWithoutSDA - -void MEDFileAnyTypeField1TSWithoutSDA::deepCpyLeavesFrom(const MEDFileAnyTypeField1TSWithoutSDA& other) -{ - _field_per_mesh.resize(other._field_per_mesh.size()); - std::size_t i=0; - for(std::vector< MEDCouplingAutoRefCountObjectPtr< MEDFileFieldPerMesh > >::const_iterator it=other._field_per_mesh.begin();it!=other._field_per_mesh.end();it++,i++) - { - if((const MEDFileFieldPerMesh *)*it) - _field_per_mesh[i]=(*it)->deepCpy(this); - } -} - -/*! - * Prints a string describing \a this field into a stream. This string is outputted - * by \c print Python command. - * \param [in] bkOffset - number of white spaces printed at the beginning of each line. - * \param [in,out] oss - the out stream. - * \param [in] f1tsId - the field index within a MED file. If \a f1tsId < 0, the tiny - * info id printed, else, not. - */ -void MEDFileAnyTypeField1TSWithoutSDA::simpleRepr(int bkOffset, std::ostream& oss, int f1tsId) const -{ - std::string startOfLine(bkOffset,' '); - oss << startOfLine << "Field "; - if(bkOffset==0) - oss << "[Type=" << getTypeStr() << "] with name \"" << getName() << "\" "; - oss << "on one time Step "; - if(f1tsId>=0) - oss << "(" << f1tsId << ") "; - oss << "on iteration=" << _iteration << " order=" << _order << "." << std::endl; - oss << startOfLine << "Time attached is : " << _dt << " [" << _dt_unit << "]." << std::endl; - const DataArray *arr=getUndergroundDataArray(); - if(arr) - { - const std::vector &comps=arr->getInfoOnComponents(); - if(f1tsId<0) - { - oss << startOfLine << "Field has " << comps.size() << " components with the following infos :" << std::endl; - for(std::vector::const_iterator it=comps.begin();it!=comps.end();it++) - oss << startOfLine << " - \"" << (*it) << "\"" << std::endl; - } - if(arr->isAllocated()) - { - oss << startOfLine << "Whole field contains " << arr->getNumberOfTuples() << " tuples." << std::endl; - } - else - oss << startOfLine << "The array of the current field has not allocated yet !" << std::endl; - } - else - { - oss << startOfLine << "Field infos are empty ! Not defined yet !" << std::endl; - } - oss << startOfLine << "----------------------" << std::endl; - if(!_field_per_mesh.empty()) - { - int i=0; - for(std::vector< MEDCouplingAutoRefCountObjectPtr< MEDFileFieldPerMesh > >::const_iterator it2=_field_per_mesh.begin();it2!=_field_per_mesh.end();it2++,i++) - { - const MEDFileFieldPerMesh *cur=(*it2); - if(cur) - cur->simpleRepr(bkOffset,oss,i); - else - oss << startOfLine << "Field per mesh #" << i << " is not defined !" << std::endl; - } - } - else - { - oss << startOfLine << "Field is not defined on any meshes !" << std::endl; - } - oss << startOfLine << "----------------------" << std::endl; -} - -std::vector< MEDCouplingAutoRefCountObjectPtr > MEDFileAnyTypeField1TSWithoutSDA::splitComponents() const -{ - const DataArray *arr(getUndergroundDataArray()); - if(!arr) - throw INTERP_KERNEL::Exception("MEDFileAnyTypeField1TSWithoutSDA::splitComponents : no array defined !"); - int nbOfCompo=arr->getNumberOfComponents(); - std::vector< MEDCouplingAutoRefCountObjectPtr > ret(nbOfCompo); - for(int i=0;i v(1,i); - MEDCouplingAutoRefCountObjectPtr arr2=arr->keepSelectedComponents(v); - ret[i]->setArray(arr2); - } - return ret; -} - -MEDFileAnyTypeField1TSWithoutSDA::MEDFileAnyTypeField1TSWithoutSDA(const std::string& fieldName, int csit, int iteration, int order):MEDFileFieldNameScope(fieldName),_iteration(iteration),_order(order),_csit(csit),_nb_of_tuples_to_be_allocated(-2) -{ -} - -MEDFileAnyTypeField1TSWithoutSDA::MEDFileAnyTypeField1TSWithoutSDA():_iteration(-1),_order(-1),_dt(0.),_csit(-1),_nb_of_tuples_to_be_allocated(-1) -{ -} - -/*! - * Returns the maximal dimension of supporting elements. Returns -2 if \a this is - * empty. Returns -1 if this in on nodes. - * \return int - the dimension of \a this. - */ -int MEDFileAnyTypeField1TSWithoutSDA::getDimension() const -{ - int ret=-2; - for(std::vector< MEDCouplingAutoRefCountObjectPtr< MEDFileFieldPerMesh > >::const_iterator it=_field_per_mesh.begin();it!=_field_per_mesh.end();it++) - (*it)->getDimension(ret); - return ret; -} - -/*! - * Returns the mesh name. - * \return std::string - a string holding the mesh name. - * \throw If \c _field_per_mesh.empty() - */ -std::string MEDFileAnyTypeField1TSWithoutSDA::getMeshName() const -{ - if(_field_per_mesh.empty()) - throw INTERP_KERNEL::Exception("MEDFileFieldPerMeshPerTypePerDisc::getMeshName : No field set !"); - return _field_per_mesh[0]->getMeshName(); -} - -void MEDFileAnyTypeField1TSWithoutSDA::setMeshName(const std::string& newMeshName) -{ - std::string oldName(getMeshName()); - std::vector< std::pair > v(1); - v[0].first=oldName; v[0].second=newMeshName; - changeMeshNames(v); -} - -bool MEDFileAnyTypeField1TSWithoutSDA::changeMeshNames(const std::vector< std::pair >& modifTab) -{ - bool ret=false; - for(std::vector< MEDCouplingAutoRefCountObjectPtr< MEDFileFieldPerMesh > >::iterator it=_field_per_mesh.begin();it!=_field_per_mesh.end();it++) - { - MEDFileFieldPerMesh *cur(*it); - if(cur) - ret=cur->changeMeshNames(modifTab) || ret; - } - return ret; -} - -/*! - * Returns the number of iteration of the state of underlying mesh. - * \return int - the iteration number. - * \throw If \c _field_per_mesh.empty() - */ -int MEDFileAnyTypeField1TSWithoutSDA::getMeshIteration() const -{ - if(_field_per_mesh.empty()) - throw INTERP_KERNEL::Exception("MEDFileFieldPerMeshPerTypePerDisc::getMeshIteration : No field set !"); - return _field_per_mesh[0]->getMeshIteration(); -} - -/*! - * Returns the order number of iteration of the state of underlying mesh. - * \return int - the order number. - * \throw If \c _field_per_mesh.empty() - */ -int MEDFileAnyTypeField1TSWithoutSDA::getMeshOrder() const -{ - if(_field_per_mesh.empty()) - throw INTERP_KERNEL::Exception("MEDFileFieldPerMeshPerTypePerDisc::getMeshOrder : No field set !"); - return _field_per_mesh[0]->getMeshOrder(); -} - -/*! - * Checks if \a this field is tagged by a given iteration number and a given - * iteration order number. - * \param [in] iteration - the iteration number of interest. - * \param [in] order - the iteration order number of interest. - * \return bool - \c true if \a this->getIteration() == \a iteration && - * \a this->getOrder() == \a order. - */ -bool MEDFileAnyTypeField1TSWithoutSDA::isDealingTS(int iteration, int order) const -{ - return iteration==_iteration && order==_order; -} - -/*! - * Returns number of iteration and order number of iteration when - * \a this field has been calculated. - * \return std::pair - a pair of the iteration number and the iteration - * order number. - */ -std::pair MEDFileAnyTypeField1TSWithoutSDA::getDtIt() const -{ - std::pair p; - fillIteration(p); - return p; -} - -/*! - * Returns number of iteration and order number of iteration when - * \a this field has been calculated. - * \param [in,out] p - a pair returning the iteration number and the iteration - * order number. - */ -void MEDFileAnyTypeField1TSWithoutSDA::fillIteration(std::pair& p) const -{ - p.first=_iteration; - p.second=_order; -} - -/*! - * Returns all types of spatial discretization of \a this field. - * \param [in,out] types - a sequence of types of \a this field. - */ -void MEDFileAnyTypeField1TSWithoutSDA::fillTypesOfFieldAvailable(std::vector& types) const -{ - std::set types2; - for(std::vector< MEDCouplingAutoRefCountObjectPtr< MEDFileFieldPerMesh > >::const_iterator it=_field_per_mesh.begin();it!=_field_per_mesh.end();it++) - { - (*it)->fillTypesOfFieldAvailable(types2); - } - std::back_insert_iterator< std::vector > bi(types); - std::copy(types2.begin(),types2.end(),bi); -} - -/*! - * Returns all types of spatial discretization of \a this field. - * \return std::vector - a sequence of types of spatial discretization - * of \a this field. - */ -std::vector MEDFileAnyTypeField1TSWithoutSDA::getTypesOfFieldAvailable() const -{ - std::vector ret; - fillTypesOfFieldAvailable(ret); - return ret; -} - -std::vector MEDFileAnyTypeField1TSWithoutSDA::getPflsReallyUsed2() const -{ - std::vector ret; - std::set ret2; - for(std::vector< MEDCouplingAutoRefCountObjectPtr< MEDFileFieldPerMesh > >::const_iterator it=_field_per_mesh.begin();it!=_field_per_mesh.end();it++) - { - std::vector tmp=(*it)->getPflsReallyUsed(); - for(std::vector::const_iterator it2=tmp.begin();it2!=tmp.end();it2++) - if(ret2.find(*it2)==ret2.end()) - { - ret.push_back(*it2); - ret2.insert(*it2); - } - } - return ret; -} - -std::vector MEDFileAnyTypeField1TSWithoutSDA::getLocsReallyUsed2() const -{ - std::vector ret; - std::set ret2; - for(std::vector< MEDCouplingAutoRefCountObjectPtr< MEDFileFieldPerMesh > >::const_iterator it=_field_per_mesh.begin();it!=_field_per_mesh.end();it++) - { - std::vector tmp=(*it)->getLocsReallyUsed(); - for(std::vector::const_iterator it2=tmp.begin();it2!=tmp.end();it2++) - if(ret2.find(*it2)==ret2.end()) - { - ret.push_back(*it2); - ret2.insert(*it2); - } - } - return ret; -} - -std::vector MEDFileAnyTypeField1TSWithoutSDA::getPflsReallyUsedMulti2() const -{ - std::vector ret; - for(std::vector< MEDCouplingAutoRefCountObjectPtr< MEDFileFieldPerMesh > >::const_iterator it=_field_per_mesh.begin();it!=_field_per_mesh.end();it++) - { - std::vector tmp=(*it)->getPflsReallyUsedMulti(); - ret.insert(ret.end(),tmp.begin(),tmp.end()); - } - return ret; -} - -std::vector MEDFileAnyTypeField1TSWithoutSDA::getLocsReallyUsedMulti2() const -{ - std::vector ret; - std::set ret2; - for(std::vector< MEDCouplingAutoRefCountObjectPtr< MEDFileFieldPerMesh > >::const_iterator it=_field_per_mesh.begin();it!=_field_per_mesh.end();it++) - { - std::vector tmp=(*it)->getLocsReallyUsedMulti(); - ret.insert(ret.end(),tmp.begin(),tmp.end()); - } - return ret; -} - -void MEDFileAnyTypeField1TSWithoutSDA::changePflsRefsNamesGen2(const std::vector< std::pair, std::string > >& mapOfModif) -{ - for(std::vector< MEDCouplingAutoRefCountObjectPtr< MEDFileFieldPerMesh > >::iterator it=_field_per_mesh.begin();it!=_field_per_mesh.end();it++) - (*it)->changePflsRefsNamesGen(mapOfModif); -} - -void MEDFileAnyTypeField1TSWithoutSDA::changeLocsRefsNamesGen2(const std::vector< std::pair, std::string > >& mapOfModif) -{ - for(std::vector< MEDCouplingAutoRefCountObjectPtr< MEDFileFieldPerMesh > >::iterator it=_field_per_mesh.begin();it!=_field_per_mesh.end();it++) - (*it)->changeLocsRefsNamesGen(mapOfModif); -} - -/*! - * Returns all attributes of parts of \a this field lying on a given mesh. - * Each part differs from other ones by a type of supporting mesh entity. The _i_-th - * item of every of returned sequences refers to the _i_-th part of \a this field. - * Thus all sequences returned by this method are of the same length equal to number - * of different types of supporting entities.
- * A field part can include sub-parts with several different spatial discretizations, - * \ref ParaMEDMEM::ON_CELLS "ON_CELLS" and \ref ParaMEDMEM::ON_GAUSS_PT "ON_GAUSS_PT" - * for example. Hence, some of the returned sequences contains nested sequences, and an item - * of a nested sequence corresponds to a type of spatial discretization.
- * This method allows for iteration over MEDFile DataStructure without any overhead. - * \param [in] mname - a name of a mesh of interest. It can be \c NULL, which is valid - * for the case with only one underlying mesh. (Actually, the number of meshes is - * not checked if \a mname == \c NULL). - * \param [in,out] types - a sequence of types of underlying mesh entities. A type per - * a field part is returned. - * \param [in,out] typesF - a sequence of sequences of types of spatial discretizations. - * This sequence is of the same length as \a types. - * \param [in,out] pfls - a sequence returning a profile name per each type of spatial - * discretization. A profile name can be empty. - * Length of this and of nested sequences is the same as that of \a typesF. - * \param [in,out] locs - a sequence returning a localization name per each type of spatial - * discretization. A localization name can be empty. - * Length of this and of nested sequences is the same as that of \a typesF. - * \return std::vector< std::vector< std::pair > > - a sequence holding a range - * of ids of tuples within the data array, per each type of spatial - * discretization within one mesh entity type. - * Length of this and of nested sequences is the same as that of \a typesF. - * \throw If no field is lying on \a mname. - */ -std::vector< std::vector< std::pair > > MEDFileAnyTypeField1TSWithoutSDA::getFieldSplitedByType(const std::string& mname, std::vector& types, std::vector< std::vector >& typesF, std::vector< std::vector >& pfls, std::vector< std::vector >& locs) const -{ - int meshId=0; - if(!mname.empty()) - meshId=getMeshIdFromMeshName(mname); - else - if(_field_per_mesh.empty()) - throw INTERP_KERNEL::Exception("MEDFileField1TSWithoutSDA::getFieldSplitedByType : This is empty !"); - return _field_per_mesh[meshId]->getFieldSplitedByType(types,typesF,pfls,locs); -} - -/*! - * Returns dimensions of mesh elements \a this field lies on. The returned value is a - * maximal absolute dimension and values returned via the out parameter \a levs are - * dimensions relative to the maximal absolute dimension.
- * This method is designed for MEDFileField1TS instances that have a discretization - * \ref ParaMEDMEM::ON_CELLS "ON_CELLS", - * \ref ParaMEDMEM::ON_GAUSS_PT "ON_GAUSS_PT", - * \ref ParaMEDMEM::ON_GAUSS_NE "ON_GAUSS_NE". - * Only these 3 discretizations will be taken into account here. If \a this is - * \ref ParaMEDMEM::ON_NODES "ON_NODES", -1 is returned and \a levs are empty.
- * This method is useful to make the link between the dimension of the underlying mesh - * and the levels of \a this, because it is possible that the highest dimension of \a this - * field is not equal to the dimension of the underlying mesh. - * - * Let's consider the following case: - * - mesh \a m1 has a meshDimension 3 and has non empty levels [0,-1,-2] with elements - * TETRA4, HEXA8, TRI3 and SEG2. - * - field \a f1 lies on \a m1 and is defined on 3D and 1D elements TETRA4 and SEG2. - * - field \a f2 lies on \a m1 and is defined on 2D and 1D elements TRI3 and SEG2. - * - * In this case \a f1->getNonEmptyLevels() returns (3,[0,-2]) and \a - * f2->getNonEmptyLevels() returns (2,[0,-1]).
- * The returned values can be used for example to retrieve a MEDCouplingFieldDouble lying - * on elements of a certain relative level by calling getFieldAtLevel(). \a meshDimRelToMax - * parameter of getFieldAtLevel() is computed basing on the returned values as this: - * meshDimRelToMax = absDim - meshDim + relativeLev . - * For example
- * to retrieve the highest level of - * \a f1: f1->getFieldAtLevel( ON_CELLS, 3-3+0 ); // absDim - meshDim + relativeLev
- * to retrieve the lowest level of \a f1: f1->getFieldAtLevel( ON_CELLS, 3-3+(-2) );
- * to retrieve the highest level of \a f2: f2->getFieldAtLevel( ON_CELLS, 2-3+0 );
- * to retrieve the lowest level of \a f2: f2->getFieldAtLevel( ON_CELLS, 2-3+(-1) ). - * \param [in] mname - a name of a mesh of interest. It can be \c NULL, which is valid - * for the case with only one underlying mesh. (Actually, the number of meshes is - * not checked if \a mname == \c NULL). - * \param [in,out] levs - a sequence returning the dimensions relative to the maximal - * absolute one. They are in decreasing order. This sequence is cleared before - * filling it in. - * \return int - the maximal absolute dimension of elements \a this fields lies on. - * \throw If no field is lying on \a mname. - */ -int MEDFileAnyTypeField1TSWithoutSDA::getNonEmptyLevels(const std::string& mname, std::vector& levs) const -{ - levs.clear(); - int meshId=getMeshIdFromMeshName(mname); - std::vector types; - std::vector< std::vector > typesF; - std::vector< std::vector > pfls, locs; - _field_per_mesh[meshId]->getFieldSplitedByType(types,typesF,pfls,locs); - if(types.empty()) - throw INTERP_KERNEL::Exception("MEDFileField1TSWithoutSDA::getNonEmptyLevels : 'this' is empty !"); - std::set st(types.begin(),types.end()); - if(st.size()==1 && (*st.begin())==INTERP_KERNEL::NORM_ERROR) - return -1; - st.erase(INTERP_KERNEL::NORM_ERROR); - std::set ret1; - for(std::set::const_iterator it=st.begin();it!=st.end();it++) - { - const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(*it); - ret1.insert((int)cm.getDimension()); - } - int ret=*std::max_element(ret1.begin(),ret1.end()); - std::copy(ret1.rbegin(),ret1.rend(),std::back_insert_iterator >(levs)); - std::transform(levs.begin(),levs.end(),levs.begin(),std::bind2nd(std::plus(),-ret)); - return ret; -} - -/*! - * \param [in] mName specifies the underlying mesh name. This value can be pointer 0 for users that do not deal with fields on multi mesh. - * \param [in] typ is for the geometric cell type (or INTERP_KERNEL::NORM_ERROR for node field) entry to find the right MEDFileFieldPerMeshPerTypePerDisc instance to set. - * \param [in] locId is the localization id to find the right MEDFileFieldPerMeshPerTypePerDisc instance to set. It corresponds to the position of - * \c pfls[std::distance(types.begin(),std::find(types.begin(),typ)] vector in MEDFileField1TSWithoutSDA::getFieldSplitedByType. For non gausspoints field users, the value is 0. - */ -MEDFileFieldPerMeshPerTypePerDisc *MEDFileAnyTypeField1TSWithoutSDA::getLeafGivenMeshAndTypeAndLocId(const std::string& mName, INTERP_KERNEL::NormalizedCellType typ, int locId) -{ - int mid=getMeshIdFromMeshName(mName); - return _field_per_mesh[mid]->getLeafGivenTypeAndLocId(typ,locId); -} - -/*! - * \param [in] mName specifies the underlying mesh name. This value can be pointer 0 for users that do not deal with fields on multi mesh. - * \param [in] typ is for the geometric cell type (or INTERP_KERNEL::NORM_ERROR for node field) entry to find the right MEDFileFieldPerMeshPerTypePerDisc instance to set. - * \param [in] locId is the localization id to find the right MEDFileFieldPerMeshPerTypePerDisc instance to set. It corresponds to the position of - * \c pfls[std::distance(types.begin(),std::find(types.begin(),typ)] vector in MEDFileField1TSWithoutSDA::getFieldSplitedByType. For non gausspoints field users, the value is 0. - */ -const MEDFileFieldPerMeshPerTypePerDisc *MEDFileAnyTypeField1TSWithoutSDA::getLeafGivenMeshAndTypeAndLocId(const std::string& mName, INTERP_KERNEL::NormalizedCellType typ, int locId) const -{ - int mid=getMeshIdFromMeshName(mName); - return _field_per_mesh[mid]->getLeafGivenTypeAndLocId(typ,locId); -} - -/*! - * \param [in] mName specifies the underlying mesh name. This value can be pointer 0 for users that do not deal with fields on multi mesh. - */ -int MEDFileAnyTypeField1TSWithoutSDA::getMeshIdFromMeshName(const std::string& mName) const -{ - if(_field_per_mesh.empty()) - throw INTERP_KERNEL::Exception("MEDFileField1TSWithoutSDA::getMeshIdFromMeshName : No field set !"); - if(mName.empty()) - return 0; - std::string mName2(mName); - int ret=0; - std::vector msg; - for(std::vector< MEDCouplingAutoRefCountObjectPtr< MEDFileFieldPerMesh > >::const_iterator it=_field_per_mesh.begin();it!=_field_per_mesh.end();it++,ret++) - if(mName2==(*it)->getMeshName()) - return ret; - else - msg.push_back((*it)->getMeshName()); - std::ostringstream oss; oss << "MEDFileField1TSWithoutSDA::getMeshIdFromMeshName : No such mesh \"" << mName2 << "\" as underlying mesh of field \"" << getName() << "\" !\n"; - oss << "Possible meshes are : "; - for(std::vector::const_iterator it2=msg.begin();it2!=msg.end();it2++) - oss << "\"" << (*it2) << "\" "; - throw INTERP_KERNEL::Exception(oss.str().c_str()); -} - -int MEDFileAnyTypeField1TSWithoutSDA::addNewEntryIfNecessary(const MEDCouplingMesh *mesh) -{ - if(!mesh) - throw INTERP_KERNEL::Exception("MEDFileAnyTypeField1TSWithoutSDA::addNewEntryIfNecessary : input mesh is NULL !"); - std::string tmp(mesh->getName()); - if(tmp.empty()) - throw INTERP_KERNEL::Exception("MEDFileField1TSWithoutSDA::addNewEntryIfNecessary : empty mesh name ! unsupported by MED file !"); - std::vector< MEDCouplingAutoRefCountObjectPtr< MEDFileFieldPerMesh > >::const_iterator it=_field_per_mesh.begin(); - int i=0; - for(;it!=_field_per_mesh.end();it++,i++) - { - if((*it)->getMeshName()==tmp) - return i; - } - int sz=_field_per_mesh.size(); - _field_per_mesh.resize(sz+1); - _field_per_mesh[sz]=MEDFileFieldPerMesh::New(this,mesh); - return sz; -} - -bool MEDFileAnyTypeField1TSWithoutSDA::renumberEntitiesLyingOnMesh(const std::string& meshName, const std::vector& oldCode, const std::vector& newCode, const DataArrayInt *renumO2N, - MEDFileFieldGlobsReal& glob) -{ - bool ret=false; - for(std::vector< MEDCouplingAutoRefCountObjectPtr< MEDFileFieldPerMesh > >::iterator it=_field_per_mesh.begin();it!=_field_per_mesh.end();it++) - { - MEDFileFieldPerMesh *fpm(*it); - if(fpm) - ret=fpm->renumberEntitiesLyingOnMesh(meshName,oldCode,newCode,renumO2N,glob) || ret; - } - return ret; -} - -/*! - * This method splits \a this into several sub-parts so that each sub parts have exactly one spatial discretization. This method implements the minimal - * splitting that leads to single spatial discretization of this. - * - * \sa splitMultiDiscrPerGeoTypes - */ -std::vector< MEDCouplingAutoRefCountObjectPtr > MEDFileAnyTypeField1TSWithoutSDA::splitDiscretizations() const -{ - std::vector types; - std::vector< std::vector > typesF; - std::vector< std::vector > pfls,locs; - std::vector< std::vector > > bgEnd(getFieldSplitedByType(getMeshName().c_str(),types,typesF,pfls,locs)); - std::set allEnt; - for(std::vector< std::vector >::const_iterator it1=typesF.begin();it1!=typesF.end();it1++) - for(std::vector::const_iterator it2=(*it1).begin();it2!=(*it1).end();it2++) - allEnt.insert(*it2); - std::vector< MEDCouplingAutoRefCountObjectPtr > ret(allEnt.size()); - std::set::const_iterator it3(allEnt.begin()); - for(std::size_t i=0;i > its; - ret[i]=shallowCpy(); - int newLgth(ret[i]->keepOnlySpatialDiscretization(*it3,its)); - ret[i]->updateData(newLgth,its); - } - return ret; -} - -/*! - * This method performs a sub splitting as splitDiscretizations does but finer. This is the finest spliting level that can be done. - * This method implements the minimal splitting so that each returned elements are mono Gauss discretization per geometric type. - * - * \sa splitDiscretizations - */ -std::vector< MEDCouplingAutoRefCountObjectPtr > MEDFileAnyTypeField1TSWithoutSDA::splitMultiDiscrPerGeoTypes() const -{ - std::vector types; - std::vector< std::vector > typesF; - std::vector< std::vector > pfls,locs; - std::vector< std::vector > > bgEnd(getFieldSplitedByType(getMeshName().c_str(),types,typesF,pfls,locs)); - std::set allEnt; - std::size_t nbOfMDPGT(0),ii(0); - for(std::vector< std::vector >::const_iterator it1=typesF.begin();it1!=typesF.end();it1++,ii++) - { - nbOfMDPGT=std::max(nbOfMDPGT,locs[ii].size()); - for(std::vector::const_iterator it2=(*it1).begin();it2!=(*it1).end();it2++) - allEnt.insert(*it2); - } - if(allEnt.size()!=1) - throw INTERP_KERNEL::Exception("MEDFileAnyTypeField1TSWithoutSDA::splitMultiDiscrPerGeoTypes : this field is expected to be defined only on one spatial discretization !"); - if(nbOfMDPGT==0) - throw INTERP_KERNEL::Exception("MEDFileAnyTypeField1TSWithoutSDA::splitMultiDiscrPerGeoTypes : empty field !"); - if(nbOfMDPGT==1) - { - std::vector< MEDCouplingAutoRefCountObjectPtr > ret0(1); - ret0[0]=const_cast(this); this->incrRef(); - return ret0; - } - std::vector< MEDCouplingAutoRefCountObjectPtr > ret(nbOfMDPGT); - for(std::size_t i=0;i > its; - ret[i]=shallowCpy(); - int newLgth(ret[i]->keepOnlyGaussDiscretization(i,its)); - ret[i]->updateData(newLgth,its); - } - return ret; -} - -int MEDFileAnyTypeField1TSWithoutSDA::keepOnlySpatialDiscretization(TypeOfField tof, std::vector< std::pair >& its) -{ - int globalCounter(0); - for(std::vector< MEDCouplingAutoRefCountObjectPtr< MEDFileFieldPerMesh > >::iterator it=_field_per_mesh.begin();it!=_field_per_mesh.end();it++) - (*it)->keepOnlySpatialDiscretization(tof,globalCounter,its); - return globalCounter; -} - -int MEDFileAnyTypeField1TSWithoutSDA::keepOnlyGaussDiscretization(std::size_t idOfDisc, std::vector< std::pair >& its) -{ - int globalCounter(0); - for(std::vector< MEDCouplingAutoRefCountObjectPtr< MEDFileFieldPerMesh > >::iterator it=_field_per_mesh.begin();it!=_field_per_mesh.end();it++) - (*it)->keepOnlyGaussDiscretization(idOfDisc,globalCounter,its); - return globalCounter; -} - -void MEDFileAnyTypeField1TSWithoutSDA::updateData(int newLgth, const std::vector< std::pair >& oldStartStops) -{ - if(_nb_of_tuples_to_be_allocated>=0) - { - _nb_of_tuples_to_be_allocated=newLgth; - const DataArray *oldArr(getUndergroundDataArray()); - if(oldArr) - { - MEDCouplingAutoRefCountObjectPtr newArr(createNewEmptyDataArrayInstance()); - newArr->setInfoAndChangeNbOfCompo(oldArr->getInfoOnComponents()); - setArray(newArr); - _nb_of_tuples_to_be_allocated=newLgth;//force the _nb_of_tuples_to_be_allocated because setArray has been used specialy - } - return ; - } - if(_nb_of_tuples_to_be_allocated==-1) - return ; - if(_nb_of_tuples_to_be_allocated==-2 || _nb_of_tuples_to_be_allocated==-3) - { - const DataArray *oldArr(getUndergroundDataArray()); - if(!oldArr || !oldArr->isAllocated()) - throw INTERP_KERNEL::Exception("MEDFileAnyTypeField1TSWithoutSDA::updateData : internal error 1 !"); - MEDCouplingAutoRefCountObjectPtr newArr(createNewEmptyDataArrayInstance()); - newArr->alloc(newLgth,getNumberOfComponents()); - if(oldArr) - newArr->copyStringInfoFrom(*oldArr); - int pos=0; - for(std::vector< std::pair >::const_iterator it=oldStartStops.begin();it!=oldStartStops.end();it++) - { - if((*it).second<(*it).first) - throw INTERP_KERNEL::Exception("MEDFileAnyTypeField1TSWithoutSDA::updateData : the range in the leaves was invalid !"); - newArr->setContigPartOfSelectedValues2(pos,oldArr,(*it).first,(*it).second,1); - pos+=(*it).second-(*it).first; - } - setArray(newArr); - return ; - } - throw INTERP_KERNEL::Exception("MEDFileAnyTypeField1TSWithoutSDA::updateData : internal error 2 !"); -} - -void MEDFileAnyTypeField1TSWithoutSDA::writeLL(med_idt fid, const MEDFileWritable& opts, const MEDFileFieldNameScope& nasc) const -{ - if(_field_per_mesh.empty()) - throw INTERP_KERNEL::Exception("MEDFileField1TSWithoutSDA::writeLL : empty field !"); - if(_field_per_mesh.size()>1) - throw INTERP_KERNEL::Exception("MEDFileField1TSWithoutSDA::writeLL : In MED3.0 mode in writting mode only ONE underlying mesh supported !"); - _field_per_mesh[0]->copyOptionsFrom(opts); - _field_per_mesh[0]->writeLL(fid,nasc); -} - -/*! - * This methods returns true is the allocation has been needed leading to a modification of state in \a this->_nb_of_tuples_to_be_allocated. - * If false is returned the memory allocation is not required. - */ -bool MEDFileAnyTypeField1TSWithoutSDA::allocIfNecessaryTheArrayToReceiveDataFromFile() -{ - if(_nb_of_tuples_to_be_allocated>=0) - { - getOrCreateAndGetArray()->alloc(_nb_of_tuples_to_be_allocated,getNumberOfComponents()); - _nb_of_tuples_to_be_allocated=-2; - return true; - } - if(_nb_of_tuples_to_be_allocated==-2 || _nb_of_tuples_to_be_allocated==-3) - return false; - if(_nb_of_tuples_to_be_allocated==-1) - throw INTERP_KERNEL::Exception("MEDFileAnyTypeField1TSWithoutSDA::allocIfNecessaryTheArrayToReceiveDataFromFile : trying to read from a file an empty instance ! Need to prepare the structure before !"); - if(_nb_of_tuples_to_be_allocated<-3) - throw INTERP_KERNEL::Exception("MEDFileAnyTypeField1TSWithoutSDA::allocIfNecessaryTheArrayToReceiveDataFromFile : internal error !"); - throw INTERP_KERNEL::Exception("MEDFileAnyTypeField1TSWithoutSDA::allocIfNecessaryTheArrayToReceiveDataFromFile : internal error !"); -} - -void MEDFileAnyTypeField1TSWithoutSDA::loadOnlyStructureOfDataRecursively(med_idt fid, const MEDFileFieldNameScope& nasc, const MEDFileMeshes *ms, const std::vector< std::pair > *entities) -{ - med_int numdt,numit; - med_float dt; - med_int nmesh; - med_bool localMesh; - med_int meshnumdt,meshnumit; - INTERP_KERNEL::AutoPtr meshName=MEDLoaderBase::buildEmptyString(MED_NAME_SIZE); - MEDFILESAFECALLERRD0(MEDfieldComputingStepInfo,(fid,nasc.getName().c_str(),_csit,&numdt,&numit,&_dt)); - MEDFILESAFECALLERRD0(MEDfield23ComputingStepMeshInfo,(fid,nasc.getName().c_str(),_csit,&numdt,&numit,&dt,&nmesh,meshName,&localMesh,&meshnumdt,&meshnumit)); - if(_iteration!=numdt || _order!=numit) - throw INTERP_KERNEL::Exception("MEDFileAnyTypeField1TSWithoutSDA::loadBigArraysRecursively : unexpected exception internal error !"); - _field_per_mesh.resize(nmesh); - // - MEDFileMesh *mm(0); - if(ms) - { - std::string meshNameCpp(MEDLoaderBase::buildStringFromFortran(meshName,MED_NAME_SIZE+1)); - mm=ms->getMeshWithName(meshNameCpp); - } - // - for(int i=0;iloadOnlyStructureOfDataRecursively(fid,_nb_of_tuples_to_be_allocated,nasc); -} - -void MEDFileAnyTypeField1TSWithoutSDA::loadBigArraysRecursively(med_idt fid, const MEDFileFieldNameScope& nasc) -{ - allocIfNecessaryTheArrayToReceiveDataFromFile(); - for(std::vector< MEDCouplingAutoRefCountObjectPtr< MEDFileFieldPerMesh > >::iterator it=_field_per_mesh.begin();it!=_field_per_mesh.end();it++) - (*it)->loadBigArraysRecursively(fid,nasc); -} - -void MEDFileAnyTypeField1TSWithoutSDA::loadBigArraysRecursivelyIfNecessary(med_idt fid, const MEDFileFieldNameScope& nasc) -{ - if(allocIfNecessaryTheArrayToReceiveDataFromFile()) - for(std::vector< MEDCouplingAutoRefCountObjectPtr< MEDFileFieldPerMesh > >::iterator it=_field_per_mesh.begin();it!=_field_per_mesh.end();it++) - (*it)->loadBigArraysRecursively(fid,nasc); -} - -void MEDFileAnyTypeField1TSWithoutSDA::loadStructureAndBigArraysRecursively(med_idt fid, const MEDFileFieldNameScope& nasc, const MEDFileMeshes *ms, const std::vector< std::pair > *entities) -{ - loadOnlyStructureOfDataRecursively(fid,nasc,ms,entities); - loadBigArraysRecursively(fid,nasc); -} - -void MEDFileAnyTypeField1TSWithoutSDA::unloadArrays() -{ - DataArray *thisArr(getUndergroundDataArray()); - if(thisArr && thisArr->isAllocated()) - { - _nb_of_tuples_to_be_allocated=thisArr->getNumberOfTuples(); - thisArr->desallocate(); - } -} - -std::size_t MEDFileAnyTypeField1TSWithoutSDA::getHeapMemorySizeWithoutChildren() const -{ - return _dt_unit.capacity()+_field_per_mesh.capacity()*sizeof(MEDCouplingAutoRefCountObjectPtr< MEDFileFieldPerMesh >); -} - -std::vector MEDFileAnyTypeField1TSWithoutSDA::getDirectChildrenWithNull() const -{ - std::vector ret; - if(getUndergroundDataArray()) - ret.push_back(getUndergroundDataArray()); - for(std::vector< MEDCouplingAutoRefCountObjectPtr< MEDFileFieldPerMesh > >::const_iterator it=_field_per_mesh.begin();it!=_field_per_mesh.end();it++) - ret.push_back((const MEDFileFieldPerMesh *)*it); - return ret; -} - -/*! - * Adds a MEDCouplingFieldDouble to \a this. The underlying mesh of the given field is - * checked if its elements are sorted suitable for writing to MED file ("STB" stands for - * "Sort By Type"), if not, an exception is thrown. - * \param [in] field - the field to add to \a this. The array of field \a field is ignored - * \param [in] arr - the array of values. - * \param [in,out] glob - the global data where profiles and localization present in - * \a field, if any, are added. - * \throw If the name of \a field is empty. - * \throw If the data array of \a field is not set. - * \throw If \a this->_arr is already allocated but has different number of components - * than \a field. - * \throw If the underlying mesh of \a field has no name. - * \throw If elements in the mesh are not in the order suitable for writing to the MED file. - */ -void MEDFileAnyTypeField1TSWithoutSDA::setFieldNoProfileSBT(const MEDCouplingFieldDouble *field, const DataArray *arr, MEDFileFieldGlobsReal& glob, const MEDFileFieldNameScope& nasc) -{ - const MEDCouplingMesh *mesh=field->getMesh(); - // - TypeOfField type=field->getTypeOfField(); - std::vector dummy; - int start=copyTinyInfoFrom(field,arr); - int pos=addNewEntryIfNecessary(mesh); - if(type!=ON_NODES) - { - std::vector code=MEDFileField1TSWithoutSDA::CheckSBTMesh(mesh); - _field_per_mesh[pos]->assignFieldNoProfileNoRenum(start,code,field,arr,glob,nasc); - } - else - _field_per_mesh[pos]->assignNodeFieldNoProfile(start,field,arr,glob); -} - -/*! - * Adds a MEDCouplingFieldDouble to \a this. Specified entities of a given dimension - * of a given mesh are used as the support of the given field (a real support is not used). - * Elements of the given mesh must be sorted suitable for writing to MED file. - * Order of underlying mesh entities of the given field specified by \a profile parameter - * is not prescribed; this method permutes field values to have them sorted by element - * type as required for writing to MED file. A new profile is added only if no equal - * profile is missing. - * \param [in] field - the field to add to \a this. The field double values are ignored. - * \param [in] arrOfVals - the values of the field \a field used. - * \param [in] mesh - the supporting mesh of \a field. - * \param [in] meshDimRelToMax - a relative dimension of mesh entities \a field lies on. - * \param [in] profile - ids of mesh entities on which corresponding field values lie. - * \param [in,out] glob - the global data where profiles and localization present in - * \a field, if any, are added. - * \throw If either \a field or \a mesh or \a profile has an empty name. - * \throw If there are no mesh entities of \a meshDimRelToMax dimension in \a mesh. - * \throw If the data array of \a field is not set. - * \throw If \a this->_arr is already allocated but has different number of components - * than \a field. - * \throw If elements in \a mesh are not in the order suitable for writing to the MED file. - * \sa setFieldNoProfileSBT() - */ -void MEDFileAnyTypeField1TSWithoutSDA::setFieldProfile(const MEDCouplingFieldDouble *field, const DataArray *arrOfVals, const MEDFileMesh *mesh, int meshDimRelToMax, const DataArrayInt *profile, MEDFileFieldGlobsReal& glob, const MEDFileFieldNameScope& nasc) -{ - if(!field) - throw INTERP_KERNEL::Exception("MEDFileAnyTypeField1TSWithoutSDA::setFieldProfile : input field is null !"); - if(!arrOfVals || !arrOfVals->isAllocated()) - throw INTERP_KERNEL::Exception("MEDFileAnyTypeField1TSWithoutSDA::setFieldProfile : input array is null or not allocated !"); - TypeOfField type=field->getTypeOfField(); - std::vector idsInPflPerType; - std::vector idsPerType; - std::vector code,code2; - MEDCouplingAutoRefCountObjectPtr m=mesh->getGenMeshAtLevel(meshDimRelToMax); - if(type!=ON_NODES) - { - m->splitProfilePerType(profile,code,idsInPflPerType,idsPerType); - std::vector< MEDCouplingAutoRefCountObjectPtr > idsInPflPerType2(idsInPflPerType.size()); std::copy(idsInPflPerType.begin(),idsInPflPerType.end(),idsInPflPerType2.begin()); - std::vector< MEDCouplingAutoRefCountObjectPtr > idsPerType2(idsPerType.size()); std::copy(idsPerType.begin(),idsPerType.end(),idsPerType2.begin()); - std::vector idsPerType3(idsPerType.size()); std::copy(idsPerType.begin(),idsPerType.end(),idsPerType3.begin()); - // start of check - MEDCouplingAutoRefCountObjectPtr field2=field->clone(false); - int nbOfTuplesExp=field2->getNumberOfTuplesExpectedRegardingCode(code,idsPerType3); - if(nbOfTuplesExp!=arrOfVals->getNumberOfTuples()) - { - std::ostringstream oss; oss << "MEDFileAnyTypeField1TSWithoutSDA::setFieldProfile : The array is expected to have " << nbOfTuplesExp << " tuples ! It has " << arrOfVals->getNumberOfTuples() << " !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - // end of check - int start=copyTinyInfoFrom(field,arrOfVals); - code2=m->getDistributionOfTypes(); - // - int pos=addNewEntryIfNecessary(m); - _field_per_mesh[pos]->assignFieldProfile(start,profile,code,code2,idsInPflPerType,idsPerType,field,arrOfVals,m,glob,nasc); - } - else - { - if(!profile || !profile->isAllocated() || profile->getNumberOfComponents()!=1) - throw INTERP_KERNEL::Exception("MEDFileAnyTypeField1TSWithoutSDA::setFieldProfile : input profile is null, not allocated or with number of components != 1 !"); - std::vector v(3); v[0]=-1; v[1]=profile->getNumberOfTuples(); v[2]=0; - std::vector idsPerType3(1); idsPerType3[0]=profile; - int nbOfTuplesExp=field->getNumberOfTuplesExpectedRegardingCode(v,idsPerType3); - if(nbOfTuplesExp!=arrOfVals->getNumberOfTuples()) - { - std::ostringstream oss; oss << "MEDFileAnyTypeField1TSWithoutSDA::setFieldProfile : For node field, the array is expected to have " << nbOfTuplesExp << " tuples ! It has " << arrOfVals->getNumberOfTuples() << " !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - int start=copyTinyInfoFrom(field,arrOfVals); - int pos=addNewEntryIfNecessary(m); - _field_per_mesh[pos]->assignNodeFieldProfile(start,profile,field,arrOfVals,glob,nasc); - } -} - -/*! - * \param [in] newNbOfTuples - The new nb of tuples to be allocated. - */ -void MEDFileAnyTypeField1TSWithoutSDA::allocNotFromFile(int newNbOfTuples) -{ - if(_nb_of_tuples_to_be_allocated>=0) - throw INTERP_KERNEL::Exception("MEDFileAnyTypeField1TSWithoutSDA::allocNotFromFile : the object is expected to be appended to a data coming from a file but not loaded ! Load before appending data !"); - DataArray *arr(getOrCreateAndGetArray()); - arr->alloc(newNbOfTuples,arr->getNumberOfComponents()); - _nb_of_tuples_to_be_allocated=-3; -} - -/*! - * Copies tiny info and allocates \a this->_arr instance of DataArrayDouble to - * append data of a given MEDCouplingFieldDouble. So that the size of \a this->_arr becomes - * larger by the size of \a field. Returns an id of the first not filled - * tuple of \a this->_arr. - * \param [in] field - the field to copy the info on components and the name from. - * \return int - the id of first not initialized tuple of \a this->_arr. - * \throw If the name of \a field is empty. - * \throw If the data array of \a field is not set. - * \throw If \a this->_arr is already allocated but has different number of components - * than \a field. - */ -int MEDFileAnyTypeField1TSWithoutSDA::copyTinyInfoFrom(const MEDCouplingFieldDouble *field, const DataArray *arr) -{ - if(!field) - throw INTERP_KERNEL::Exception("MEDFileAnyTypeField1TSWithoutSDA::copyTinyInfoFrom : input field is NULL !"); - std::string name(field->getName()); - setName(name.c_str()); - setDtUnit(field->getTimeUnit()); - if(name.empty()) - throw INTERP_KERNEL::Exception("MEDFileField1TSWithoutSDA::copyTinyInfoFrom : unsupported fields with no name in MED file !"); - if(!arr) - throw INTERP_KERNEL::Exception("MEDFileField1TSWithoutSDA::copyTinyInfoFrom : no array set !"); - if(!arr->isAllocated()) - throw INTERP_KERNEL::Exception("MEDFileField1TSWithoutSDA::copyTinyInfoFrom : array is not allocated !"); - _dt=field->getTime(_iteration,_order); - getOrCreateAndGetArray()->setInfoAndChangeNbOfCompo(arr->getInfoOnComponents()); - if(!getOrCreateAndGetArray()->isAllocated()) - { - allocNotFromFile(arr->getNumberOfTuples()); - return 0; - } - else - { - int oldNbOfTuples=getOrCreateAndGetArray()->getNumberOfTuples(); - int newNbOfTuples=oldNbOfTuples+arr->getNumberOfTuples(); - getOrCreateAndGetArray()->reAlloc(newNbOfTuples); - _nb_of_tuples_to_be_allocated=-3; - return oldNbOfTuples; - } -} - -/*! - * Returns number of components in \a this field - * \return int - the number of components. - */ -int MEDFileAnyTypeField1TSWithoutSDA::getNumberOfComponents() const -{ - return getOrCreateAndGetArray()->getNumberOfComponents(); -} - -/*! - * Change info on components in \a this. - * \throw If size of \a infos is not equal to the number of components already in \a this. - */ -void MEDFileAnyTypeField1TSWithoutSDA::setInfo(const std::vector& infos) -{ - DataArray *arr=getOrCreateAndGetArray(); - arr->setInfoOnComponents(infos);//will throw an exception if number of components mimatches -} - -/*! - * Returns info on components of \a this field. - * \return const std::vector& - a sequence of strings each being an - * information on _i_-th component. - */ -const std::vector& MEDFileAnyTypeField1TSWithoutSDA::getInfo() const -{ - const DataArray *arr=getOrCreateAndGetArray(); - return arr->getInfoOnComponents(); -} - -/*! - * Returns a mutable info on components of \a this field. - * \return std::vector& - a sequence of strings each being an - * information on _i_-th component. - */ -std::vector& MEDFileAnyTypeField1TSWithoutSDA::getInfo() -{ - DataArray *arr=getOrCreateAndGetArray(); - return arr->getInfoOnComponents(); -} - -bool MEDFileAnyTypeField1TSWithoutSDA::presenceOfMultiDiscPerGeoType() const -{ - for(std::vector< MEDCouplingAutoRefCountObjectPtr< MEDFileFieldPerMesh > >::const_iterator it=_field_per_mesh.begin();it!=_field_per_mesh.end();it++) - { - const MEDFileFieldPerMesh *fpm(*it); - if(!fpm) - continue; - if(fpm->presenceOfMultiDiscPerGeoType()) - return true; - } - return false; -} - -/*! - * Returns a new MEDCouplingFieldDouble of given type lying on a given support. - * \param [in] type - a spatial discretization of the new field. - * \param [in] meshDimRelToMax - a relative dimension of the supporting mesh entities. - * \param [in] mName - a name of the supporting mesh. - * \param [in] renumPol - specifies how to permute values of the result field according to - * the optional numbers of cells and nodes, if any. The valid values are - * - 0 - do not permute. - * - 1 - permute cells. - * - 2 - permute nodes. - * - 3 - permute cells and nodes. - * - * \param [in] glob - the global data storing profiles and localization. - * \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 MED file is not readable. - * \throw If there is no mesh named \a mName in the MED file. - * \throw If there are no mesh entities of \a meshDimRelToMax dimension in the mesh. - * \throw If no field of \a this is lying on the mesh \a mName. - * \throw If no field values of the given \a type or given \a meshDimRelToMax are available. - */ -MEDCouplingFieldDouble *MEDFileAnyTypeField1TSWithoutSDA::getFieldAtLevel(TypeOfField type, int meshDimRelToMax, const std::string& mName, int renumPol, const MEDFileFieldGlobsReal *glob, MEDCouplingAutoRefCountObjectPtr& arrOut, const MEDFileFieldNameScope& nasc) const -{ - MEDCouplingAutoRefCountObjectPtr mm; - if(mName.empty()) - mm=MEDFileMesh::New(glob->getFileName(),getMeshName().c_str(),getMeshIteration(),getMeshOrder()); - else - mm=MEDFileMesh::New(glob->getFileName(),mName,getMeshIteration(),getMeshOrder()); - return MEDFileAnyTypeField1TSWithoutSDA::getFieldOnMeshAtLevel(type,meshDimRelToMax,renumPol,glob,mm,arrOut,nasc); -} - -/*! - * Returns a new MEDCouplingFieldDouble of given type lying on a given support. - * \param [in] type - a spatial discretization of the new field. - * \param [in] meshDimRelToMax - a relative dimension of the supporting mesh entities. - * \param [in] renumPol - specifies how to permute values of the result field according to - * the optional numbers of cells and nodes, if any. The valid values are - * - 0 - do not permute. - * - 1 - permute cells. - * - 2 - permute nodes. - * - 3 - permute cells and nodes. - * - * \param [in] glob - the global data storing profiles and localization. - * \param [in] mesh - the supporting mesh. - * \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 MED file is not readable. - * \throw If no field of \a this is lying on \a mesh. - * \throw If there are no mesh entities of \a meshDimRelToMax dimension in the mesh. - * \throw If no field values of the given \a type or given \a meshDimRelToMax are available. - */ -MEDCouplingFieldDouble *MEDFileAnyTypeField1TSWithoutSDA::getFieldOnMeshAtLevel(TypeOfField type, int meshDimRelToMax, int renumPol, const MEDFileFieldGlobsReal *glob, const MEDFileMesh *mesh, MEDCouplingAutoRefCountObjectPtr& arrOut, const MEDFileFieldNameScope& nasc) const -{ - MEDCouplingAutoRefCountObjectPtr m=mesh->getGenMeshAtLevel(meshDimRelToMax,false); - const DataArrayInt *d=mesh->getNumberFieldAtLevel(meshDimRelToMax); - const DataArrayInt *e=mesh->getNumberFieldAtLevel(1); - if(meshDimRelToMax==1) - (static_cast((MEDCouplingMesh *)m))->setMeshDimension(0); - return MEDFileAnyTypeField1TSWithoutSDA::getFieldOnMeshAtLevel(type,renumPol,glob,m,d,e,arrOut,nasc); -} - -/*! - * Returns a new MEDCouplingFieldDouble of a given type lying on the top level cells of a - * given mesh. - * \param [in] type - a spatial discretization of the new field. - * \param [in] mName - a name of the supporting mesh. - * \param [in] renumPol - specifies how to permute values of the result field according to - * the optional numbers of cells and nodes, if any. The valid values are - * - 0 - do not permute. - * - 1 - permute cells. - * - 2 - permute nodes. - * - 3 - permute cells and nodes. - * - * \param [in] glob - the global data storing profiles and localization. - * \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 MED file is not readable. - * \throw If there is no mesh named \a mName in the MED file. - * \throw If there are no mesh entities in the mesh. - * \throw If no field values of the given \a type are available. - */ -MEDCouplingFieldDouble *MEDFileAnyTypeField1TSWithoutSDA::getFieldAtTopLevel(TypeOfField type, const std::string& mName, int renumPol, const MEDFileFieldGlobsReal *glob, MEDCouplingAutoRefCountObjectPtr& arrOut, const MEDFileFieldNameScope& nasc) const -{ - MEDCouplingAutoRefCountObjectPtr mm; - if(mName.empty()) - mm=MEDFileMesh::New(glob->getFileName(),getMeshName().c_str(),getMeshIteration(),getMeshOrder()); - else - mm=MEDFileMesh::New(glob->getFileName(),mName,getMeshIteration(),getMeshOrder()); - int absDim=getDimension(); - int meshDimRelToMax=absDim-mm->getMeshDimension(); - return MEDFileAnyTypeField1TSWithoutSDA::getFieldOnMeshAtLevel(type,meshDimRelToMax,renumPol,glob,mm,arrOut,nasc); -} - -/*! - * Returns a new MEDCouplingFieldDouble of given type lying on a given support. - * \param [in] type - a spatial discretization of the new field. - * \param [in] renumPol - specifies how to permute values of the result field according to - * the optional numbers of cells and nodes, if any. The valid values are - * - 0 - do not permute. - * - 1 - permute cells. - * - 2 - permute nodes. - * - 3 - permute cells and nodes. - * - * \param [in] glob - the global data storing profiles and localization. - * \param [in] mesh - the supporting mesh. - * \param [in] cellRenum - the cell numbers array used for permutation of the result - * field according to \a renumPol. - * \param [in] nodeRenum - the node numbers array used for permutation of the result - * field according to \a renumPol. - * \return MEDCouplingFieldDouble * - a new instance of MEDCouplingFieldDouble. The - * caller is to delete this field using decrRef() as it is no more needed. - * \throw If there are no mesh entities of \a meshDimRelToMax dimension in the mesh. - * \throw If no field of \a this is lying on \a mesh. - * \throw If no field values of the given \a type or given \a meshDimRelToMax are available. - */ -MEDCouplingFieldDouble *MEDFileAnyTypeField1TSWithoutSDA::getFieldOnMeshAtLevel(TypeOfField type, int renumPol, const MEDFileFieldGlobsReal *glob, const MEDCouplingMesh *mesh, const DataArrayInt *cellRenum, const DataArrayInt *nodeRenum, MEDCouplingAutoRefCountObjectPtr& arrOut, const MEDFileFieldNameScope& nasc) const -{ - static const char msg1[]="MEDFileField1TSWithoutSDA::getFieldOnMeshAtLevel : request for a renumbered field following mesh numbering whereas it is a profile field !"; - int meshId=getMeshIdFromMeshName(mesh->getName()); - bool isPfl=false; - MEDCouplingAutoRefCountObjectPtr ret=_field_per_mesh[meshId]->getFieldOnMeshAtLevel(type,glob,mesh,isPfl,arrOut,nasc); - switch(renumPol) - { - case 0: - { - //no need to test _field_per_mesh.empty() because geMeshName has already done it - return ret.retn(); - } - case 3: - case 1: - { - if(isPfl) - throw INTERP_KERNEL::Exception(msg1); - //no need to test _field_per_mesh.empty() because geMeshName has already done it - if(cellRenum) - { - if((int)cellRenum->getNbOfElems()!=mesh->getNumberOfCells()) - { - std::ostringstream oss; oss << "MEDFileField1TSWithoutSDA::getFieldOnMeshAtLevel : Request of simple renumbering but it seems that underlying mesh \"" << mesh->getName() << "\" of requested field "; - oss << "\"" << getName() << "\" has partial renumbering (some geotype has no renumber) !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - MEDCouplingFieldDiscretization *disc=ret->getDiscretization(); - if(!disc) throw INTERP_KERNEL::Exception("MEDFileAnyTypeField1TSWithoutSDA::getFieldOnMeshAtLevel : internal error, no discretization on field !"); - std::vector arrOut2(1,arrOut); - // 2 following lines replace ret->renumberCells(cellRenum->getConstPointer()) if not DataArrayDouble - disc->renumberArraysForCell(ret->getMesh(),arrOut2,cellRenum->getConstPointer(),true); - (const_cast(ret->getMesh()))->renumberCells(cellRenum->getConstPointer(),true); - } - if(renumPol==1) - return ret.retn(); - } - case 2: - { - //no need to test _field_per_mesh.empty() because geMeshName has already done it - if(isPfl) - throw INTERP_KERNEL::Exception(msg1); - if(nodeRenum) - { - if((int)nodeRenum->getNbOfElems()!=mesh->getNumberOfNodes()) - { - std::ostringstream oss; oss << "MEDFileField1TSWithoutSDA::getFieldOnMeshAtLevel : Request of simple renumbering but it seems that underlying mesh \"" << mesh->getName() << "\" of requested field "; - oss << "\"" << nasc.getName() << "\" not defined on all nodes !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - MEDCouplingAutoRefCountObjectPtr nodeRenumSafe=nodeRenum->checkAndPreparePermutation(); - if(!dynamic_cast((DataArray *)arrOut)) - throw INTERP_KERNEL::Exception("MEDFileField1TSWithoutSDA::getFieldOnMeshAtLevel : node renumbering not implemented for not double DataArrays !"); - ret->renumberNodes(nodeRenumSafe->getConstPointer()); - } - return ret.retn(); - } - default: - throw INTERP_KERNEL::Exception("MEDFileField1TSWithoutSDA::getFieldOnMeshAtLevel : unsupported renum policy ! Dealing with policy 0 1 2 and 3 !"); - } -} - -/*! - * Returns values and a profile of the field of a given type lying on a given support. - * \param [in] type - a spatial discretization of the field. - * \param [in] meshDimRelToMax - a relative dimension of the supporting mesh entities. - * \param [in] mesh - the supporting mesh. - * \param [out] pfl - a new instance of DataArrayInt holding ids of mesh entities the - * field of interest lies on. If the field lies on all entities of the given - * dimension, all ids in \a pfl are zero. The caller is to delete this array - * using decrRef() as it is no more needed. - * \param [in] glob - the global data storing profiles and localization. - * \return DataArrayDouble * - a new instance of DataArrayDouble holding values of the - * field. The caller is to delete this array using decrRef() as it is no more needed. - * \throw If there are no mesh entities of \a meshDimRelToMax dimension in \a mesh. - * \throw If no field of \a this is lying on \a mesh. - * \throw If no field values of the given \a type are available. - */ -DataArray *MEDFileAnyTypeField1TSWithoutSDA::getFieldWithProfile(TypeOfField type, int meshDimRelToMax, const MEDFileMesh *mesh, DataArrayInt *&pfl, const MEDFileFieldGlobsReal *glob, const MEDFileFieldNameScope& nasc) const -{ - MEDCouplingAutoRefCountObjectPtr m=mesh->getGenMeshAtLevel(meshDimRelToMax); - int meshId=getMeshIdFromMeshName(mesh->getName().c_str()); - MEDCouplingAutoRefCountObjectPtr ret=_field_per_mesh[meshId]->getFieldOnMeshAtLevelWithPfl(type,m,pfl,glob,nasc); - ret->setName(nasc.getName().c_str()); - return ret.retn(); -} - -//= MEDFileField1TSWithoutSDA - -/*! - * Throws if a given value is not a valid (non-extended) relative dimension. - * \param [in] meshDimRelToMax - the relative dimension value. - * \throw If \a meshDimRelToMax > 0. - */ -void MEDFileField1TSWithoutSDA::CheckMeshDimRel(int meshDimRelToMax) -{ - if(meshDimRelToMax>0) - throw INTERP_KERNEL::Exception("CheckMeshDimRel : This is a meshDimRel not a meshDimRelExt ! So value should be <=0 !"); -} - -/*! - * Checks if elements of a given mesh are in the order suitable for writing - * to the MED file. If this is not so, an exception is thrown. In a case of success, returns a - * vector describing types of elements and their number. - * \param [in] mesh - the mesh to check. - * \return std::vector - a vector holding for each element type (1) item of - * INTERP_KERNEL::NormalizedCellType, (2) number of elements, (3) -1. - * These values are in full-interlace mode. - * \throw If elements in \a mesh are not in the order suitable for writing to the MED file. - */ -std::vector MEDFileField1TSWithoutSDA::CheckSBTMesh(const MEDCouplingMesh *mesh) -{ - if(!mesh) - throw INTERP_KERNEL::Exception("MEDFileField1TSWithoutSDA::CheckSBTMesh : input mesh is NULL !"); - std::set geoTypes=mesh->getAllGeoTypes(); - int nbOfTypes=geoTypes.size(); - std::vector code(3*nbOfTypes); - MEDCouplingAutoRefCountObjectPtr arr1=DataArrayInt::New(); - arr1->alloc(nbOfTypes,1); - int *arrPtr=arr1->getPointer(); - std::set::const_iterator it=geoTypes.begin(); - for(int i=0;i arr2=arr1->checkAndPreparePermutation(); - const int *arrPtr2=arr2->getConstPointer(); - int i=0; - for(it=geoTypes.begin();it!=geoTypes.end();it++,i++) - { - int pos=arrPtr2[i]; - int nbCells=mesh->getNumberOfCellsWithType(*it); - code[3*pos]=(int)(*it); - code[3*pos+1]=nbCells; - code[3*pos+2]=-1;//no profiles - } - std::vector idsPerType;//no profiles - DataArrayInt *da=mesh->checkTypeConsistencyAndContig(code,idsPerType); - if(da) - { - da->decrRef(); - throw INTERP_KERNEL::Exception("MEDFileField1TSWithoutSDA::CheckSBTMesh : underlying mesh is not sorted by type as MED file expects !"); - } - return code; -} - -MEDFileField1TSWithoutSDA *MEDFileField1TSWithoutSDA::New(const std::string& fieldName, int csit, int iteration, int order, const std::vector& infos) -{ - return new MEDFileField1TSWithoutSDA(fieldName,csit,iteration,order,infos); -} - -/*! - * Returns all attributes and values of parts of \a this field lying on a given mesh. - * Each part differs from other ones by a type of supporting mesh entity. The _i_-th - * item of every of returned sequences refers to the _i_-th part of \a this field. - * Thus all sequences returned by this method are of the same length equal to number - * of different types of supporting entities.
- * A field part can include sub-parts with several different spatial discretizations, - * \ref ParaMEDMEM::ON_CELLS "ON_CELLS" and \ref ParaMEDMEM::ON_GAUSS_PT "ON_GAUSS_PT" - * for example. Hence, some of the returned sequences contains nested sequences, and an item - * of a nested sequence corresponds to a type of spatial discretization.
- * This method allows for iteration over MEDFile DataStructure with a reduced overhead. - * The overhead is due to selecting values into new instances of DataArrayDouble. - * \param [in] mname - a name of a mesh of interest. It can be \c NULL, which is valid - * for the case with only one underlying mesh. (Actually, the number of meshes is - * not checked if \a mname == \c NULL). - * \param [in,out] types - a sequence of types of underlying mesh entities. A type per - * a field part is returned. - * \param [in,out] typesF - a sequence of sequences of types of spatial discretizations. - * A field part can include sub-parts with several different spatial discretizations, - * \ref ParaMEDMEM::ON_CELLS "ON_CELLS" and - * \ref ParaMEDMEM::ON_GAUSS_PT "ON_GAUSS_PT" for example. - * This sequence is of the same length as \a types. - * \param [in,out] pfls - a sequence returning a profile name per each type of spatial - * discretization. A profile name can be empty. - * Length of this and of nested sequences is the same as that of \a typesF. - * \param [in,out] locs - a sequence returning a localization name per each type of spatial - * discretization. A localization name can be empty. - * Length of this and of nested sequences is the same as that of \a typesF. - * \return std::vector< std::vector > - a sequence holding arrays of values - * per each type of spatial discretization within one mesh entity type. - * The caller is to delete each DataArrayDouble using decrRef() as it is no more needed. - * Length of this and of nested sequences is the same as that of \a typesF. - * \throw If no field is lying on \a mname. - */ -std::vector< std::vector > MEDFileField1TSWithoutSDA::getFieldSplitedByType2(const std::string& mname, std::vector& types, std::vector< std::vector >& typesF, std::vector< std::vector >& pfls, std::vector< std::vector >& locs) const -{ - int meshId=0; - if(!mname.empty()) - meshId=getMeshIdFromMeshName(mname); - else - if(_field_per_mesh.empty()) - throw INTERP_KERNEL::Exception("MEDFileField1TSWithoutSDA::getFieldSplitedByType : This is empty !"); - std::vector< std::vector< std::pair > > ret0=_field_per_mesh[meshId]->getFieldSplitedByType(types,typesF,pfls,locs); - int nbOfRet=ret0.size(); - std::vector< std::vector > ret(nbOfRet); - for(int i=0;i >& p=ret0[i]; - int nbOfRet1=p.size(); - ret[i].resize(nbOfRet1); - for(int j=0;jselectByTupleId2(p[j].first,p[j].second,1); - ret[i][j]=tmp; - } - } - return ret; -} - -/*! - * Returns a pointer to the underground DataArrayDouble instance. So the - * caller should not decrRef() it. This method allows for a direct access to the field - * values. This method is quite unusable if there is more than a nodal field or a cell - * field on single geometric cell type. - * \return DataArrayDouble * - the pointer to the field values array. - */ -DataArrayDouble *MEDFileField1TSWithoutSDA::getUndergroundDataArrayDouble() const -{ - const DataArrayDouble *ret=_arr; - if(ret) - return const_cast(ret); - else - return 0; -} - -const char *MEDFileField1TSWithoutSDA::getTypeStr() const -{ - return TYPE_STR; -} - -MEDFileIntField1TSWithoutSDA *MEDFileField1TSWithoutSDA::convertToInt() const -{ - MEDCouplingAutoRefCountObjectPtr ret(new MEDFileIntField1TSWithoutSDA); - ret->MEDFileAnyTypeField1TSWithoutSDA::operator =(*this); - ret->deepCpyLeavesFrom(*this); - const DataArrayDouble *arr(_arr); - if(arr) - { - MEDCouplingAutoRefCountObjectPtr arr2(arr->convertToIntArr()); - ret->setArray(arr2); - } - return ret.retn(); -} - -/*! - * Returns a pointer to the underground DataArrayDouble instance. So the - * caller should not decrRef() it. This method allows for a direct access to the field - * values. This method is quite unusable if there is more than a nodal field or a cell - * field on single geometric cell type. - * \return DataArrayDouble * - the pointer to the field values array. - */ -DataArray *MEDFileField1TSWithoutSDA::getUndergroundDataArray() const -{ - return getUndergroundDataArrayDouble(); -} - -/*! - * Returns a pointer to the underground DataArrayDouble instance and a - * sequence describing parameters of a support of each part of \a this field. The - * caller should not decrRef() the returned DataArrayDouble. This method allows for a - * direct access to the field values. This method is intended for the field lying on one - * mesh only. - * \param [in,out] entries - the sequence describing parameters of a support of each - * part of \a this field. Each item of this sequence consists of two parts. The - * first part describes a type of mesh entity and an id of discretization of a - * current field part. The second part describes a range of values [begin,end) - * within the returned array relating to the current field part. - * \return DataArrayDouble * - the pointer to the field values array. - * \throw If the number of underlying meshes is not equal to 1. - * \throw If no field values are available. - * \sa getUndergroundDataArray() - */ -DataArrayDouble *MEDFileField1TSWithoutSDA::getUndergroundDataArrayDoubleExt(std::vector< std::pair,std::pair > >& entries) const -{ - if(_field_per_mesh.size()!=1) - throw INTERP_KERNEL::Exception("MEDFileField1TSWithoutSDA::getUndergroundDataArrayExt : field lies on several meshes, this method has no sense !"); - if(_field_per_mesh[0]==0) - throw INTERP_KERNEL::Exception("MEDFileField1TSWithoutSDA::getUndergroundDataArrayExt : no field specified !"); - _field_per_mesh[0]->getUndergroundDataArrayExt(entries); - return getUndergroundDataArrayDouble(); -} - -/*! - * Returns a pointer to the underground DataArrayDouble instance and a - * sequence describing parameters of a support of each part of \a this field. The - * caller should not decrRef() the returned DataArrayDouble. This method allows for a - * direct access to the field values. This method is intended for the field lying on one - * mesh only. - * \param [in,out] entries - the sequence describing parameters of a support of each - * part of \a this field. Each item of this sequence consists of two parts. The - * first part describes a type of mesh entity and an id of discretization of a - * current field part. The second part describes a range of values [begin,end) - * within the returned array relating to the current field part. - * \return DataArrayDouble * - the pointer to the field values array. - * \throw If the number of underlying meshes is not equal to 1. - * \throw If no field values are available. - * \sa getUndergroundDataArray() - */ -DataArray *MEDFileField1TSWithoutSDA::getUndergroundDataArrayExt(std::vector< std::pair,std::pair > >& entries) const -{ - return getUndergroundDataArrayDoubleExt(entries); -} - -MEDFileField1TSWithoutSDA::MEDFileField1TSWithoutSDA(const std::string& fieldName, int csit, int iteration, int order, const std::vector& infos):MEDFileAnyTypeField1TSWithoutSDA(fieldName,csit,iteration,order) -{ - DataArrayDouble *arr(getOrCreateAndGetArrayDouble()); - arr->setInfoAndChangeNbOfCompo(infos); -} - -MEDFileField1TSWithoutSDA::MEDFileField1TSWithoutSDA():MEDFileAnyTypeField1TSWithoutSDA() -{ -} - -MEDFileAnyTypeField1TSWithoutSDA *MEDFileField1TSWithoutSDA::shallowCpy() const -{ - MEDCouplingAutoRefCountObjectPtr ret(new MEDFileField1TSWithoutSDA(*this)); - ret->deepCpyLeavesFrom(*this); - return ret.retn(); -} - -MEDFileAnyTypeField1TSWithoutSDA *MEDFileField1TSWithoutSDA::deepCpy() const -{ - MEDCouplingAutoRefCountObjectPtr ret=static_cast(shallowCpy()); - if((const DataArrayDouble *)_arr) - ret->_arr=_arr->deepCpy(); - return ret.retn(); -} - -void MEDFileField1TSWithoutSDA::setArray(DataArray *arr) -{ - if(!arr) - { - _nb_of_tuples_to_be_allocated=-1; - _arr=0; - return ; - } - DataArrayDouble *arrC=dynamic_cast(arr); - if(!arrC) - throw INTERP_KERNEL::Exception("MEDFileField1TSWithoutSDA::setArray : the input not null array is not of type DataArrayDouble !"); - else - _nb_of_tuples_to_be_allocated=-3; - arrC->incrRef(); - _arr=arrC; -} - -DataArray *MEDFileField1TSWithoutSDA::createNewEmptyDataArrayInstance() const -{ - return DataArrayDouble::New(); -} - -DataArrayDouble *MEDFileField1TSWithoutSDA::getOrCreateAndGetArrayDouble() -{ - DataArrayDouble *ret=_arr; - if(ret) - return ret; - _arr=DataArrayDouble::New(); - return _arr; -} - -DataArray *MEDFileField1TSWithoutSDA::getOrCreateAndGetArray() -{ - return getOrCreateAndGetArrayDouble(); -} - -const DataArrayDouble *MEDFileField1TSWithoutSDA::getOrCreateAndGetArrayDouble() const -{ - const DataArrayDouble *ret=_arr; - if(ret) - return ret; - DataArrayDouble *ret2=DataArrayDouble::New(); - const_cast(this)->_arr=DataArrayDouble::New(); - return ret2; -} - -const DataArray *MEDFileField1TSWithoutSDA::getOrCreateAndGetArray() const -{ - return getOrCreateAndGetArrayDouble(); -} - -//= MEDFileIntField1TSWithoutSDA - -MEDFileIntField1TSWithoutSDA *MEDFileIntField1TSWithoutSDA::New(const std::string& fieldName, int csit, int iteration, int order, const std::vector& infos) -{ - return new MEDFileIntField1TSWithoutSDA(fieldName,csit,iteration,order,infos); -} - -MEDFileIntField1TSWithoutSDA::MEDFileIntField1TSWithoutSDA():MEDFileAnyTypeField1TSWithoutSDA() -{ -} - -MEDFileIntField1TSWithoutSDA::MEDFileIntField1TSWithoutSDA(const std::string& fieldName, int csit, int iteration, int order, - const std::vector& infos):MEDFileAnyTypeField1TSWithoutSDA(fieldName,csit,iteration,order) -{ - DataArrayInt *arr(getOrCreateAndGetArrayInt()); - arr->setInfoAndChangeNbOfCompo(infos); -} - -const char *MEDFileIntField1TSWithoutSDA::getTypeStr() const -{ - return TYPE_STR; -} - -MEDFileField1TSWithoutSDA *MEDFileIntField1TSWithoutSDA::convertToDouble() const -{ - MEDCouplingAutoRefCountObjectPtr ret(new MEDFileField1TSWithoutSDA); - ret->MEDFileAnyTypeField1TSWithoutSDA::operator =(*this); - ret->deepCpyLeavesFrom(*this); - const DataArrayInt *arr(_arr); - if(arr) - { - MEDCouplingAutoRefCountObjectPtr arr2(arr->convertToDblArr()); - ret->setArray(arr2); - } - return ret.retn(); -} - -/*! - * Returns a pointer to the underground DataArrayInt instance. So the - * caller should not decrRef() it. This method allows for a direct access to the field - * values. This method is quite unusable if there is more than a nodal field or a cell - * field on single geometric cell type. - * \return DataArrayInt * - the pointer to the field values array. - */ -DataArray *MEDFileIntField1TSWithoutSDA::getUndergroundDataArray() const -{ - return getUndergroundDataArrayInt(); -} - -/*! - * Returns a pointer to the underground DataArrayInt instance. So the - * caller should not decrRef() it. This method allows for a direct access to the field - * values. This method is quite unusable if there is more than a nodal field or a cell - * field on single geometric cell type. - * \return DataArrayInt * - the pointer to the field values array. - */ -DataArrayInt *MEDFileIntField1TSWithoutSDA::getUndergroundDataArrayInt() const -{ - const DataArrayInt *ret=_arr; - if(ret) - return const_cast(ret); - else - return 0; -} - -/*! - * Returns a pointer to the underground DataArrayInt instance and a - * sequence describing parameters of a support of each part of \a this field. The - * caller should not decrRef() the returned DataArrayInt. This method allows for a - * direct access to the field values. This method is intended for the field lying on one - * mesh only. - * \param [in,out] entries - the sequence describing parameters of a support of each - * part of \a this field. Each item of this sequence consists of two parts. The - * first part describes a type of mesh entity and an id of discretization of a - * current field part. The second part describes a range of values [begin,end) - * within the returned array relating to the current field part. - * \return DataArrayInt * - the pointer to the field values array. - * \throw If the number of underlying meshes is not equal to 1. - * \throw If no field values are available. - * \sa getUndergroundDataArray() - */ -DataArray *MEDFileIntField1TSWithoutSDA::getUndergroundDataArrayExt(std::vector< std::pair,std::pair > >& entries) const -{ - return getUndergroundDataArrayIntExt(entries); -} - -/*! - * Returns a pointer to the underground DataArrayInt instance and a - * sequence describing parameters of a support of each part of \a this field. The - * caller should not decrRef() the returned DataArrayInt. This method allows for a - * direct access to the field values. This method is intended for the field lying on one - * mesh only. - * \param [in,out] entries - the sequence describing parameters of a support of each - * part of \a this field. Each item of this sequence consists of two parts. The - * first part describes a type of mesh entity and an id of discretization of a - * current field part. The second part describes a range of values [begin,end) - * within the returned array relating to the current field part. - * \return DataArrayInt * - the pointer to the field values array. - * \throw If the number of underlying meshes is not equal to 1. - * \throw If no field values are available. - * \sa getUndergroundDataArray() - */ -DataArrayInt *MEDFileIntField1TSWithoutSDA::getUndergroundDataArrayIntExt(std::vector< std::pair,std::pair > >& entries) const -{ - if(_field_per_mesh.size()!=1) - throw INTERP_KERNEL::Exception("MEDFileField1TSWithoutSDA::getUndergroundDataArrayExt : field lies on several meshes, this method has no sense !"); - if(_field_per_mesh[0]==0) - throw INTERP_KERNEL::Exception("MEDFileField1TSWithoutSDA::getUndergroundDataArrayExt : no field specified !"); - _field_per_mesh[0]->getUndergroundDataArrayExt(entries); - return getUndergroundDataArrayInt(); -} - -MEDFileAnyTypeField1TSWithoutSDA *MEDFileIntField1TSWithoutSDA::shallowCpy() const -{ - MEDCouplingAutoRefCountObjectPtr ret(new MEDFileIntField1TSWithoutSDA(*this)); - ret->deepCpyLeavesFrom(*this); - return ret.retn(); -} - -MEDFileAnyTypeField1TSWithoutSDA *MEDFileIntField1TSWithoutSDA::deepCpy() const -{ - MEDCouplingAutoRefCountObjectPtr ret=static_cast(shallowCpy()); - if((const DataArrayInt *)_arr) - ret->_arr=_arr->deepCpy(); - return ret.retn(); -} - -void MEDFileIntField1TSWithoutSDA::setArray(DataArray *arr) -{ - if(!arr) - { - _nb_of_tuples_to_be_allocated=-1; - _arr=0; - return ; - } - DataArrayInt *arrC=dynamic_cast(arr); - if(!arrC) - throw INTERP_KERNEL::Exception("MEDFileIntField1TSWithoutSDA::setArray : the input not null array is not of type DataArrayInt !"); - else - _nb_of_tuples_to_be_allocated=-3; - arrC->incrRef(); - _arr=arrC; -} - -DataArray *MEDFileIntField1TSWithoutSDA::createNewEmptyDataArrayInstance() const -{ - return DataArrayInt::New(); -} - -DataArrayInt *MEDFileIntField1TSWithoutSDA::getOrCreateAndGetArrayInt() -{ - DataArrayInt *ret=_arr; - if(ret) - return ret; - _arr=DataArrayInt::New(); - return _arr; -} - -DataArray *MEDFileIntField1TSWithoutSDA::getOrCreateAndGetArray() -{ - return getOrCreateAndGetArrayInt(); -} - -const DataArrayInt *MEDFileIntField1TSWithoutSDA::getOrCreateAndGetArrayInt() const -{ - const DataArrayInt *ret=_arr; - if(ret) - return ret; - DataArrayInt *ret2=DataArrayInt::New(); - const_cast(this)->_arr=DataArrayInt::New(); - return ret2; -} - -const DataArray *MEDFileIntField1TSWithoutSDA::getOrCreateAndGetArray() const -{ - return getOrCreateAndGetArrayInt(); -} - -MEDFileAnyTypeField1TS::MEDFileAnyTypeField1TS() -{ -} - -//= MEDFileAnyTypeField1TS - -MEDFileAnyTypeField1TSWithoutSDA *MEDFileAnyTypeField1TS::BuildContentFrom(med_idt fid, const std::string& fileName, bool loadAll, const MEDFileMeshes *ms) -{ - med_field_type typcha; - // - std::vector infos; - std::string dtunit,fieldName; - LocateField2(fid,fileName,0,true,fieldName,typcha,infos,dtunit); - MEDCouplingAutoRefCountObjectPtr ret; - switch(typcha) - { - case MED_FLOAT64: - { - ret=MEDFileField1TSWithoutSDA::New(fieldName.c_str(),-1,-1/*iteration*/,-1/*order*/,std::vector()); - break; - } - case MED_INT32: - { - ret=MEDFileIntField1TSWithoutSDA::New(fieldName.c_str(),-1,-1/*iteration*/,-1/*order*/,std::vector()); - break; - } - default: - { - std::ostringstream oss; oss << "MEDFileAnyTypeField1TS::BuildContentFrom(fileName) : file \'" << fileName << "\' contains field with name \'" << fieldName << "\' but the type of the first field is not in [MED_FLOAT64, MED_INT32] !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - } - ret->setDtUnit(dtunit.c_str()); - ret->getOrCreateAndGetArray()->setInfoAndChangeNbOfCompo(infos); - // - med_int numdt,numit; - med_float dt; - MEDFILESAFECALLERRD0(MEDfieldComputingStepInfo,(fid,fieldName.c_str(),1,&numdt,&numit,&dt)); - ret->setTime(numdt,numit,dt); - ret->_csit=1; - if(loadAll) - ret->loadStructureAndBigArraysRecursively(fid,*((const MEDFileAnyTypeField1TSWithoutSDA*)ret),ms,0); - else - ret->loadOnlyStructureOfDataRecursively(fid,*((const MEDFileAnyTypeField1TSWithoutSDA*)ret),ms,0); - return ret.retn(); -} - -MEDFileAnyTypeField1TS::MEDFileAnyTypeField1TS(const std::string& fileName, bool loadAll, const MEDFileMeshes *ms) -try:MEDFileFieldGlobsReal(fileName) -{ - MEDFileUtilities::CheckFileForRead(fileName); - MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName.c_str(),MED_ACC_RDONLY); - _content=BuildContentFrom(fid,fileName,loadAll,ms); - loadGlobals(fid); -} -catch(INTERP_KERNEL::Exception& e) -{ - throw e; -} - -MEDFileAnyTypeField1TSWithoutSDA *MEDFileAnyTypeField1TS::BuildContentFrom(med_idt fid, const std::string& fileName, const std::string& fieldName, bool loadAll, const MEDFileMeshes *ms) -{ - med_field_type typcha; - std::vector infos; - std::string dtunit; - int iii=-1; - int nbSteps=LocateField(fid,fileName,fieldName,iii,typcha,infos,dtunit); - MEDCouplingAutoRefCountObjectPtr ret; - switch(typcha) - { - case MED_FLOAT64: - { - ret=MEDFileField1TSWithoutSDA::New(fieldName,-1,-1/*iteration*/,-1/*order*/,std::vector()); - break; - } - case MED_INT32: - { - ret=MEDFileIntField1TSWithoutSDA::New(fieldName,-1,-1/*iteration*/,-1/*order*/,std::vector()); - break; - } - default: - { - std::ostringstream oss; oss << "MEDFileAnyTypeField1TS::BuildContentFrom(fileName,fieldName) : file \'" << fileName << "\' contains field with name \'" << fieldName << "\' but the type of field is not in [MED_FLOAT64, MED_INT32] !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - } - ret->setDtUnit(dtunit.c_str()); - ret->getOrCreateAndGetArray()->setInfoAndChangeNbOfCompo(infos); - // - if(nbSteps<1) - { - std::ostringstream oss; oss << "MEDFileField1TS(fileName,fieldName) : file \'" << fileName << "\' contains field with name \'" << fieldName << "\' but there is no time steps on it !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - // - med_int numdt,numit; - med_float dt; - MEDFILESAFECALLERRD0(MEDfieldComputingStepInfo,(fid,fieldName.c_str(),1,&numdt,&numit,&dt)); - ret->setTime(numdt,numit,dt); - ret->_csit=1; - if(loadAll) - ret->loadStructureAndBigArraysRecursively(fid,*((const MEDFileAnyTypeField1TSWithoutSDA*)ret),ms,0); - else - ret->loadOnlyStructureOfDataRecursively(fid,*((const MEDFileAnyTypeField1TSWithoutSDA*)ret),ms,0); - return ret.retn(); -} - -MEDFileAnyTypeField1TS::MEDFileAnyTypeField1TS(const std::string& fileName, const std::string& fieldName, bool loadAll, const MEDFileMeshes *ms) -try:MEDFileFieldGlobsReal(fileName) -{ - MEDFileUtilities::CheckFileForRead(fileName); - MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName.c_str(),MED_ACC_RDONLY); - _content=BuildContentFrom(fid,fileName,fieldName,loadAll,ms); - loadGlobals(fid); -} -catch(INTERP_KERNEL::Exception& e) -{ - throw e; -} - -MEDFileAnyTypeField1TS *MEDFileAnyTypeField1TS::BuildNewInstanceFromContent(MEDFileAnyTypeField1TSWithoutSDA *c, const std::string& fileName) -{ - if(!c) - throw INTERP_KERNEL::Exception("MEDFileAnyTypeField1TS::BuildNewInstanceFromContent : empty content in input : unable to build a new instance !"); - if(dynamic_cast(c)) - { - MEDCouplingAutoRefCountObjectPtr ret=MEDFileField1TS::New(); - ret->setFileName(fileName); - ret->_content=c; c->incrRef(); - return ret.retn(); - } - if(dynamic_cast(c)) - { - MEDCouplingAutoRefCountObjectPtr ret=MEDFileIntField1TS::New(); - ret->setFileName(fileName); - ret->_content=c; c->incrRef(); - return ret.retn(); - } - throw INTERP_KERNEL::Exception("MEDFileAnyTypeField1TS::BuildNewInstanceFromContent : internal error ! a content of type different from FLOAT64 and INT32 has been built but not intercepted !"); -} - -MEDFileAnyTypeField1TS *MEDFileAnyTypeField1TS::New(const std::string& fileName, bool loadAll) -{ - MEDFileUtilities::CheckFileForRead(fileName); - MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName.c_str(),MED_ACC_RDONLY); - MEDCouplingAutoRefCountObjectPtr c=BuildContentFrom(fid,fileName,loadAll,0); - MEDCouplingAutoRefCountObjectPtr ret=BuildNewInstanceFromContent(c,fileName); - ret->loadGlobals(fid); - return ret.retn(); -} - -MEDFileAnyTypeField1TS *MEDFileAnyTypeField1TS::New(const std::string& fileName, const std::string& fieldName, bool loadAll) -{ - MEDFileUtilities::CheckFileForRead(fileName); - MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName.c_str(),MED_ACC_RDONLY); - MEDCouplingAutoRefCountObjectPtr c=BuildContentFrom(fid,fileName,fieldName,loadAll,0); - MEDCouplingAutoRefCountObjectPtr ret=BuildNewInstanceFromContent(c,fileName); - ret->loadGlobals(fid); - return ret.retn(); -} - -MEDFileAnyTypeField1TS *MEDFileAnyTypeField1TS::New(const std::string& fileName, const std::string& fieldName, int iteration, int order, bool loadAll) -{ - MEDFileUtilities::CheckFileForRead(fileName); - MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName.c_str(),MED_ACC_RDONLY); - MEDCouplingAutoRefCountObjectPtr c=BuildContentFrom(fid,fileName,fieldName,iteration,order,loadAll,0); - MEDCouplingAutoRefCountObjectPtr ret=BuildNewInstanceFromContent(c,fileName); - ret->loadGlobals(fid); - return ret.retn(); -} - -MEDFileAnyTypeField1TSWithoutSDA *MEDFileAnyTypeField1TS::BuildContentFrom(med_idt fid, const std::string& fileName, const std::string& fieldName, int iteration, int order, bool loadAll, const MEDFileMeshes *ms) -{ - med_field_type typcha; - std::vector infos; - std::string dtunit; - int iii=-1; - int nbOfStep2=LocateField(fid,fileName,fieldName,iii,typcha,infos,dtunit); - MEDCouplingAutoRefCountObjectPtr ret; - switch(typcha) - { - case MED_FLOAT64: - { - ret=MEDFileField1TSWithoutSDA::New(fieldName,-1,iteration,order,std::vector()); - break; - } - case MED_INT32: - { - ret=MEDFileIntField1TSWithoutSDA::New(fieldName,-1,iteration,order,std::vector()); - break; - } - default: - { - std::ostringstream oss; oss << "MEDFileAnyTypeField1TS::BuildContentFrom(fileName,fieldName,iteration,order) : file \'" << fileName << "\' contains field with name \'" << fieldName << "\' but the type of field is not in [MED_FLOAT64, MED_INT32] !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - } - ret->setDtUnit(dtunit.c_str()); - ret->getOrCreateAndGetArray()->setInfoAndChangeNbOfCompo(infos); - // - bool found=false; - std::vector< std::pair > dtits(nbOfStep2); - for(int i=0;i_csit=i+1; - } - else - dtits[i]=std::pair(numdt,numit); - } - if(!found) - { - std::ostringstream oss; oss << "No such iteration (" << iteration << "," << order << ") in existing field '" << fieldName << "' in file '" << fileName << "' ! Available iterations are : "; - for(std::vector< std::pair >::const_iterator iter=dtits.begin();iter!=dtits.end();iter++) - oss << "(" << (*iter).first << "," << (*iter).second << "), "; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - if(loadAll) - ret->loadStructureAndBigArraysRecursively(fid,*((const MEDFileAnyTypeField1TSWithoutSDA*)ret),ms,0); - else - ret->loadOnlyStructureOfDataRecursively(fid,*((const MEDFileAnyTypeField1TSWithoutSDA*)ret),ms,0); - return ret.retn(); -} - -MEDFileAnyTypeField1TS::MEDFileAnyTypeField1TS(const std::string& fileName, const std::string& fieldName, int iteration, int order, bool loadAll, const MEDFileMeshes *ms) -try:MEDFileFieldGlobsReal(fileName) -{ - MEDFileUtilities::CheckFileForRead(fileName); - MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName.c_str(),MED_ACC_RDONLY); - _content=BuildContentFrom(fid,fileName.c_str(),fieldName.c_str(),iteration,order,loadAll,ms); - loadGlobals(fid); -} -catch(INTERP_KERNEL::Exception& e) -{ - throw e; -} - -/*! - * This constructor is a shallow copy constructor. If \a shallowCopyOfContent is true the content of \a other is shallow copied. - * If \a shallowCopyOfContent is false, \a other is taken to be the content of \a this. - * - * \warning this is a shallow copy constructor - */ -MEDFileAnyTypeField1TS::MEDFileAnyTypeField1TS(const MEDFileAnyTypeField1TSWithoutSDA& other, bool shallowCopyOfContent) -{ - if(!shallowCopyOfContent) - { - const MEDFileAnyTypeField1TSWithoutSDA *otherPtr(&other); - otherPtr->incrRef(); - _content=const_cast(otherPtr); - } - else - { - _content=other.shallowCpy(); - } -} - -int MEDFileAnyTypeField1TS::LocateField2(med_idt fid, const std::string& fileName, int fieldIdCFormat, bool checkFieldId, std::string& fieldName, med_field_type& typcha, std::vector& infos, std::string& dtunitOut) -{ - if(checkFieldId) - { - int nbFields=MEDnField(fid); - if(fieldIdCFormat>=nbFields) - { - std::ostringstream oss; oss << "MEDFileAnyTypeField1TS::LocateField2(fileName) : in file \'" << fileName << "\' number of fields is " << nbFields << " ! Trying to request for id " << fieldIdCFormat << " !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - } - int ncomp(MEDfieldnComponent(fid,fieldIdCFormat+1)); - INTERP_KERNEL::AutoPtr comp=MEDLoaderBase::buildEmptyString(ncomp*MED_SNAME_SIZE); - INTERP_KERNEL::AutoPtr unit=MEDLoaderBase::buildEmptyString(ncomp*MED_SNAME_SIZE); - INTERP_KERNEL::AutoPtr dtunit=MEDLoaderBase::buildEmptyString(MED_LNAME_SIZE); - INTERP_KERNEL::AutoPtr nomcha=MEDLoaderBase::buildEmptyString(MED_NAME_SIZE); - INTERP_KERNEL::AutoPtr nomMaa=MEDLoaderBase::buildEmptyString(MED_NAME_SIZE); - med_bool localMesh; - int nbOfStep; - MEDFILESAFECALLERRD0(MEDfieldInfo,(fid,fieldIdCFormat+1,nomcha,nomMaa,&localMesh,&typcha,comp,unit,dtunit,&nbOfStep)); - fieldName=MEDLoaderBase::buildStringFromFortran(nomcha,MED_NAME_SIZE); - dtunitOut=MEDLoaderBase::buildStringFromFortran(dtunit,MED_LNAME_SIZE); - infos.clear(); infos.resize(ncomp); - for(int j=0;j& infos, std::string& dtunitOut) -{ - int nbFields=MEDnField(fid); - bool found=false; - std::vector fns(nbFields); - int nbOfStep2=-1; - for(int i=0;i::const_iterator it=fns.begin();it!=fns.end();it++) - oss << "\"" << *it << "\" "; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - return nbOfStep2; -} - -/*! - * This method as MEDFileField1TSW::setLocNameOnLeaf, is dedicated for advanced user that a want a very fine control on their data structure - * without overhead. This method can be called only regarding information returned by MEDFileField1TSWithoutSDA::getFieldSplitedByType or MEDFileField1TSWithoutSDA::getFieldSplitedByType2. - * This method changes the attribute (here it's profile name) of the leaf datastructure (MEDFileFieldPerMeshPerTypePerDisc instance). - * It is the responsability of the caller to invoke MEDFileFieldGlobs::appendProfile or MEDFileFieldGlobs::getProfile - * to keep a valid instance. - * If \b this do not have any leaf that correspond to the request of the input parameter (\b mName, \b typ, \b locId) an INTERP_KERNEL::Exception will be thrown. - * If \b newPflName profile name does not already exist the profile with old name will be renamed with name \b newPflName. - * If \b newPflName already exists and that \b forceRenameOnGlob is false (the default) an INTERP_KERNEL::Exception will be thrown to avoid big confusion. In this case the called should rename before the profile name with name \b newPflName. - * - * \param [in] mName specifies the underlying mesh name. This value can be pointer 0 for users that do not deal with fields on multi mesh. - * \param [in] typ is for the geometric cell type (or INTERP_KERNEL::NORM_ERROR for node field) entry to find the right MEDFileFieldPerMeshPerTypePerDisc instance to set. - * \param [in] locId is the localization id to find the right MEDFileFieldPerMeshPerTypePerDisc instance to set. It corresponds to the position of - * \c pfls[std::distance(types.begin(),std::find(types.begin(),typ)] vector in MEDFileField1TSWithoutSDA::getFieldSplitedByType. For non gausspoints field users, the value is 0. - * \param [in] newLocName is the new localization name. - * \param [in] forceRenameOnGlob specifies the behaviour in case of profile \b newPflName already exists. If true, the renaming is done without check. It can lead to major bug. - * If false, an exception will be thrown to force user to change previously the name of the profile with name \b newPflName - */ -void MEDFileAnyTypeField1TS::setProfileNameOnLeaf(const std::string& mName, INTERP_KERNEL::NormalizedCellType typ, int locId, const std::string& newPflName, bool forceRenameOnGlob) -{ - MEDFileFieldPerMeshPerTypePerDisc *disc=getLeafGivenMeshAndTypeAndLocId(mName,typ,locId); - std::string oldPflName=disc->getProfile(); - std::vector vv=getPflsReallyUsedMulti(); - int nbOfOcc=std::count(vv.begin(),vv.end(),oldPflName); - if(forceRenameOnGlob || (!existsPfl(newPflName) && nbOfOcc==1)) - { - disc->setProfile(newPflName); - DataArrayInt *pfl=getProfile(oldPflName.c_str()); - pfl->setName(newPflName); - } - else - { - std::ostringstream oss; oss << "MEDFileField1TS::setProfileNameOnLeaf : Profile \"" << newPflName << "\" already exists or referenced more than one !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } -} - -/*! - * This method as MEDFileField1TSW::setProfileNameOnLeaf, is dedicated for advanced user that a want a very fine control on their data structure - * without overhead. This method can be called only regarding information returned by MEDFileField1TSWithoutSDA::getFieldSplitedByType or MEDFileField1TSWithoutSDA::getFieldSplitedByType2. - * This method changes the attribute (here it's localization name) of the leaf datastructure (MEDFileFieldPerMeshPerTypePerDisc instance). - * It is the responsability of the caller to invoke MEDFileFieldGlobs::appendProfile or MEDFileFieldGlobs::getProfile - * to keep a valid instance. - * If \b this do not have any leaf that correspond to the request of the input parameter (\b mName, \b typ, \b locId) an INTERP_KERNEL::Exception will be thrown. - * This method is an extension of MEDFileField1TSWithoutSDA::setProfileNameOnLeafExt method because it performs a modification of global info. - * If \b newLocName profile name does not already exist the localization with old name will be renamed with name \b newLocName. - * If \b newLocName already exists an INTERP_KERNEL::Exception will be thrown to avoid big confusion. In this case the called should rename before the profile name with name \b newLocName. - * - * \param [in] mName specifies the underlying mesh name. This value can be pointer 0 for users that do not deal with fields on multi mesh. - * \param [in] typ is for the geometric cell type (or INTERP_KERNEL::NORM_ERROR for node field) entry to find the right MEDFileFieldPerMeshPerTypePerDisc instance to set. - * \param [in] locId is the localization id to find the right MEDFileFieldPerMeshPerTypePerDisc instance to set. It corresponds to the position of - * \c pfls[std::distance(types.begin(),std::find(types.begin(),typ)] vector in MEDFileField1TSWithoutSDA::getFieldSplitedByType. For non gausspoints field users, the value is 0. - * \param [in] newLocName is the new localization name. - * \param [in] forceRenameOnGlob specifies the behaviour in case of profile \b newLocName already exists. If true, the renaming is done without check. It can lead to major bug. - * If false, an exception will be thrown to force user to change previously the name of the profile with name \b newLocName - */ -void MEDFileAnyTypeField1TS::setLocNameOnLeaf(const std::string& mName, INTERP_KERNEL::NormalizedCellType typ, int locId, const std::string& newLocName, bool forceRenameOnGlob) -{ - MEDFileFieldPerMeshPerTypePerDisc *disc=getLeafGivenMeshAndTypeAndLocId(mName,typ,locId); - std::string oldLocName=disc->getLocalization(); - std::vector vv=getLocsReallyUsedMulti(); - int nbOfOcc=std::count(vv.begin(),vv.end(),oldLocName); - if(forceRenameOnGlob || (!existsLoc(newLocName) && nbOfOcc==1)) - { - disc->setLocalization(newLocName); - MEDFileFieldLoc& loc=getLocalization(oldLocName.c_str()); - loc.setName(newLocName); - } - else - { - std::ostringstream oss; oss << "MEDFileField1TS::setLocNameOnLeaf : Localization \"" << newLocName << "\" already exists or referenced more than one !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } -} - -MEDFileAnyTypeField1TSWithoutSDA *MEDFileAnyTypeField1TS::contentNotNullBase() -{ - MEDFileAnyTypeField1TSWithoutSDA *ret=_content; - if(!ret) - throw INTERP_KERNEL::Exception("MEDFileAnyTypeField1TS : content is expected to be not null !"); - return ret; -} - -const MEDFileAnyTypeField1TSWithoutSDA *MEDFileAnyTypeField1TS::contentNotNullBase() const -{ - const MEDFileAnyTypeField1TSWithoutSDA *ret=_content; - if(!ret) - throw INTERP_KERNEL::Exception("MEDFileAnyTypeField1TS : const content is expected to be not null !"); - return ret; -} - -/*! - * Writes \a this field into a MED file specified by its name. - * \param [in] fileName - the MED file name. - * \param [in] mode - the writing mode. For more on \a mode, see \ref AdvMEDLoaderBasics. - * - 2 - erase; an existing file is removed. - * - 1 - append; same data should not be present in an existing file. - * - 0 - overwrite; same data present in an existing file is overwritten. - * \throw If the field name is not set. - * \throw If no field data is set. - * \throw If \a mode == 1 and the same data is present in an existing file. - */ -void MEDFileAnyTypeField1TS::write(const std::string& fileName, int mode) const -{ - med_access_mode medmod=MEDFileUtilities::TraduceWriteMode(mode); - MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName.c_str(),medmod); - writeLL(fid); -} - -/*! - * This method alloc the arrays and load potentially huge arrays contained in this field. - * This method should be called when a MEDFileAnyTypeField1TS::New constructor has been with false as the last parameter. - * This method can be also called to refresh or reinit values from a file. - * - * \throw If the fileName is not set or points to a non readable MED file. - * \sa MEDFileAnyTypeField1TS::loadArraysIfNecessary - */ -void MEDFileAnyTypeField1TS::loadArrays() -{ - if(getFileName().empty()) - throw INTERP_KERNEL::Exception("MEDFileAnyTypeField1TS::loadArrays : the structure does not come from a file !"); - MEDFileUtilities::AutoFid fid=MEDfileOpen(getFileName().c_str(),MED_ACC_RDONLY); - contentNotNullBase()->loadBigArraysRecursively(fid,*contentNotNullBase()); -} - -/*! - * This method behaves as MEDFileAnyTypeField1TS::loadArrays does, the first call, if \a this was built using a file without loading big arrays. - * But once data loaded once, this method does nothing. Contrary to MEDFileAnyTypeField1TS::loadArrays and MEDFileAnyTypeField1TS::unloadArrays - * this method does not throw if \a this does not come from file read. - * - * \sa MEDFileAnyTypeField1TS::loadArrays, MEDFileAnyTypeField1TS::unloadArrays - */ -void MEDFileAnyTypeField1TS::loadArraysIfNecessary() -{ - if(!getFileName().empty()) - { - MEDFileUtilities::AutoFid fid=MEDfileOpen(getFileName().c_str(),MED_ACC_RDONLY); - contentNotNullBase()->loadBigArraysRecursivelyIfNecessary(fid,*contentNotNullBase()); - } -} - -/*! - * This method releases potentially big data arrays and so returns to the same heap memory than status loaded with 'loadAll' parameter set to false. - * \b WARNING, this method does release arrays even if \a this does not come from a load of a MED file. - * So this method can lead to a loss of data. If you want to unload arrays safely call MEDFileAnyTypeField1TS::unloadArraysWithoutDataLoss instead. - * - * \sa MEDFileAnyTypeField1TS::loadArrays, MEDFileAnyTypeField1TS::loadArraysIfNecessary, MEDFileAnyTypeField1TS::unloadArraysWithoutDataLoss - */ -void MEDFileAnyTypeField1TS::unloadArrays() -{ - contentNotNullBase()->unloadArrays(); -} - -/*! - * This method potentially releases big data arrays if \a this is coming from a file. If \a this has been built from scratch this method will have no effect. - * This method is the symetrical method of MEDFileAnyTypeField1TS::loadArraysIfNecessary. - * This method is useful to reduce \b safely amount of heap memory necessary for \a this by using MED file as database. - * - * \sa MEDFileAnyTypeField1TS::loadArraysIfNecessary - */ -void MEDFileAnyTypeField1TS::unloadArraysWithoutDataLoss() -{ - if(!getFileName().empty()) - contentNotNullBase()->unloadArrays(); -} - -void MEDFileAnyTypeField1TS::writeLL(med_idt fid) const -{ - int nbComp=getNumberOfComponents(); - INTERP_KERNEL::AutoPtr comp=MEDLoaderBase::buildEmptyString(nbComp*MED_SNAME_SIZE); - INTERP_KERNEL::AutoPtr unit=MEDLoaderBase::buildEmptyString(nbComp*MED_SNAME_SIZE); - for(int i=0;iwriteLL(fid,*this,*contentNotNullBase()); -} - -std::size_t MEDFileAnyTypeField1TS::getHeapMemorySizeWithoutChildren() const -{ - return MEDFileFieldGlobsReal::getHeapMemorySizeWithoutChildren(); -} - -std::vector MEDFileAnyTypeField1TS::getDirectChildrenWithNull() const -{ - std::vector ret(MEDFileFieldGlobsReal::getDirectChildrenWithNull()); - ret.push_back((const MEDFileAnyTypeField1TSWithoutSDA *)_content); - return ret; -} - -/*! - * Returns a string describing \a this field. This string is outputted - * by \c print Python command. - */ -std::string MEDFileAnyTypeField1TS::simpleRepr() const -{ - std::ostringstream oss; - contentNotNullBase()->simpleRepr(0,oss,-1); - simpleReprGlobs(oss); - return oss.str(); -} - -/*! - * This method returns all profiles whose name is non empty used. - * \b WARNING If profile is used several times it will be reported \b only \b once. - * To get non empty name profiles as time as they appear in \b this call MEDFileField1TS::getPflsReallyUsedMulti instead. - */ -std::vector MEDFileAnyTypeField1TS::getPflsReallyUsed() const -{ - return contentNotNullBase()->getPflsReallyUsed2(); -} - -/*! - * This method returns all localizations whose name is non empty used. - * \b WARNING If localization is used several times it will be reported \b only \b once. - */ -std::vector MEDFileAnyTypeField1TS::getLocsReallyUsed() const -{ - return contentNotNullBase()->getLocsReallyUsed2(); -} - -/*! - * This method returns all profiles whose name is non empty used. - * \b WARNING contrary to MEDFileField1TS::getPflsReallyUsed, if profile is used several times it will be reported as time as it appears. - */ -std::vector MEDFileAnyTypeField1TS::getPflsReallyUsedMulti() const -{ - return contentNotNullBase()->getPflsReallyUsedMulti2(); -} - -/*! - * This method returns all localizations whose name is non empty used. - * \b WARNING contrary to MEDFileField1TS::getLocsReallyUsed if localization is used several times it will be reported as time as it appears. - */ -std::vector MEDFileAnyTypeField1TS::getLocsReallyUsedMulti() const -{ - return contentNotNullBase()->getLocsReallyUsedMulti2(); -} - -void MEDFileAnyTypeField1TS::changePflsRefsNamesGen(const std::vector< std::pair, std::string > >& mapOfModif) -{ - contentNotNullBase()->changePflsRefsNamesGen2(mapOfModif); -} - -void MEDFileAnyTypeField1TS::changeLocsRefsNamesGen(const std::vector< std::pair, std::string > >& mapOfModif) -{ - contentNotNullBase()->changeLocsRefsNamesGen2(mapOfModif); -} - -int MEDFileAnyTypeField1TS::getDimension() const -{ - return contentNotNullBase()->getDimension(); -} - -int MEDFileAnyTypeField1TS::getIteration() const -{ - return contentNotNullBase()->getIteration(); -} - -int MEDFileAnyTypeField1TS::getOrder() const -{ - return contentNotNullBase()->getOrder(); -} - -double MEDFileAnyTypeField1TS::getTime(int& iteration, int& order) const -{ - return contentNotNullBase()->getTime(iteration,order); -} - -void MEDFileAnyTypeField1TS::setTime(int iteration, int order, double val) -{ - contentNotNullBase()->setTime(iteration,order,val); -} - -std::string MEDFileAnyTypeField1TS::getName() const -{ - return contentNotNullBase()->getName(); -} - -void MEDFileAnyTypeField1TS::setName(const std::string& name) -{ - contentNotNullBase()->setName(name); -} - -void MEDFileAnyTypeField1TS::simpleRepr(int bkOffset, std::ostream& oss, int f1tsId) const -{ - contentNotNullBase()->simpleRepr(bkOffset,oss,f1tsId); -} - -std::string MEDFileAnyTypeField1TS::getDtUnit() const -{ - return contentNotNullBase()->getDtUnit(); -} - -void MEDFileAnyTypeField1TS::setDtUnit(const std::string& dtUnit) -{ - contentNotNullBase()->setDtUnit(dtUnit); -} - -std::string MEDFileAnyTypeField1TS::getMeshName() const -{ - return contentNotNullBase()->getMeshName(); -} - -void MEDFileAnyTypeField1TS::setMeshName(const std::string& newMeshName) -{ - contentNotNullBase()->setMeshName(newMeshName); -} - -bool MEDFileAnyTypeField1TS::changeMeshNames(const std::vector< std::pair >& modifTab) -{ - return contentNotNullBase()->changeMeshNames(modifTab); -} - -int MEDFileAnyTypeField1TS::getMeshIteration() const -{ - return contentNotNullBase()->getMeshIteration(); -} - -int MEDFileAnyTypeField1TS::getMeshOrder() const -{ - return contentNotNullBase()->getMeshOrder(); -} - -int MEDFileAnyTypeField1TS::getNumberOfComponents() const -{ - return contentNotNullBase()->getNumberOfComponents(); -} - -bool MEDFileAnyTypeField1TS::isDealingTS(int iteration, int order) const -{ - return contentNotNullBase()->isDealingTS(iteration,order); -} - -std::pair MEDFileAnyTypeField1TS::getDtIt() const -{ - return contentNotNullBase()->getDtIt(); -} - -void MEDFileAnyTypeField1TS::fillIteration(std::pair& p) const -{ - contentNotNullBase()->fillIteration(p); -} - -void MEDFileAnyTypeField1TS::fillTypesOfFieldAvailable(std::vector& types) const -{ - contentNotNullBase()->fillTypesOfFieldAvailable(types); -} - -void MEDFileAnyTypeField1TS::setInfo(const std::vector& infos) -{ - contentNotNullBase()->setInfo(infos); -} - -const std::vector& MEDFileAnyTypeField1TS::getInfo() const -{ - return contentNotNullBase()->getInfo(); -} -std::vector& MEDFileAnyTypeField1TS::getInfo() -{ - return contentNotNullBase()->getInfo(); -} - -bool MEDFileAnyTypeField1TS::presenceOfMultiDiscPerGeoType() const -{ - return contentNotNullBase()->presenceOfMultiDiscPerGeoType(); -} - -MEDFileFieldPerMeshPerTypePerDisc *MEDFileAnyTypeField1TS::getLeafGivenMeshAndTypeAndLocId(const std::string& mName, INTERP_KERNEL::NormalizedCellType typ, int locId) -{ - return contentNotNullBase()->getLeafGivenMeshAndTypeAndLocId(mName,typ,locId); -} - -const MEDFileFieldPerMeshPerTypePerDisc *MEDFileAnyTypeField1TS::getLeafGivenMeshAndTypeAndLocId(const std::string& mName, INTERP_KERNEL::NormalizedCellType typ, int locId) const -{ - return contentNotNullBase()->getLeafGivenMeshAndTypeAndLocId(mName,typ,locId); -} - -int MEDFileAnyTypeField1TS::getNonEmptyLevels(const std::string& mname, std::vector& levs) const -{ - return contentNotNullBase()->getNonEmptyLevels(mname,levs); -} - -std::vector MEDFileAnyTypeField1TS::getTypesOfFieldAvailable() const -{ - return contentNotNullBase()->getTypesOfFieldAvailable(); -} - -std::vector< std::vector > > MEDFileAnyTypeField1TS::getFieldSplitedByType(const std::string& mname, std::vector& types, std::vector< std::vector >& typesF, - std::vector< std::vector >& pfls, std::vector< std::vector >& locs) const -{ - return contentNotNullBase()->getFieldSplitedByType(mname,types,typesF,pfls,locs); -} - -/*! - * This method returns as MEDFileAnyTypeField1TS new instances as number of components in \a this. - * The returned instances are deep copy of \a this except that for globals that are share with those contained in \a this. - * ** WARNING ** do no forget to rename the ouput instances to avoid to write n-times in the same MED file field ! - */ -std::vector< MEDCouplingAutoRefCountObjectPtr< MEDFileAnyTypeField1TS > > MEDFileAnyTypeField1TS::splitComponents() const -{ - const MEDFileAnyTypeField1TSWithoutSDA *content(_content); - if(!content) - throw INTERP_KERNEL::Exception("MEDFileAnyTypeField1TS::splitComponents : no content in this ! Unable to split components !"); - std::vector< MEDCouplingAutoRefCountObjectPtr > contentsSplit=content->splitComponents(); - std::size_t sz(contentsSplit.size()); - std::vector< MEDCouplingAutoRefCountObjectPtr< MEDFileAnyTypeField1TS > > ret(sz); - for(std::size_t i=0;i_content=contentsSplit[i]; - } - return ret; -} - -/*! - * This method returns as MEDFileAnyTypeField1TS new instances as number of spatial discretizations in \a this. - * The returned instances are shallowed copied of \a this except that for globals that are share with those contained in \a this. - */ -std::vector< MEDCouplingAutoRefCountObjectPtr< MEDFileAnyTypeField1TS > > MEDFileAnyTypeField1TS::splitDiscretizations() const -{ - const MEDFileAnyTypeField1TSWithoutSDA *content(_content); - if(!content) - throw INTERP_KERNEL::Exception("MEDFileAnyTypeField1TS::splitDiscretizations : no content in this ! Unable to split discretization !"); - std::vector< MEDCouplingAutoRefCountObjectPtr > contentsSplit(content->splitDiscretizations()); - std::size_t sz(contentsSplit.size()); - std::vector< MEDCouplingAutoRefCountObjectPtr< MEDFileAnyTypeField1TS > > ret(sz); - for(std::size_t i=0;i_content=contentsSplit[i]; - } - return ret; -} - -/*! - * This method returns as MEDFileAnyTypeField1TS new instances as number of maximal number of discretization in \a this. - * The returned instances are shallowed copied of \a this except that for globals that are share with those contained in \a this. - */ -std::vector< MEDCouplingAutoRefCountObjectPtr< MEDFileAnyTypeField1TS > > MEDFileAnyTypeField1TS::splitMultiDiscrPerGeoTypes() const -{ - const MEDFileAnyTypeField1TSWithoutSDA *content(_content); - if(!content) - throw INTERP_KERNEL::Exception("MEDFileAnyTypeField1TS::splitMultiDiscrPerGeoTypes : no content in this ! Unable to split discretization !"); - std::vector< MEDCouplingAutoRefCountObjectPtr > contentsSplit(content->splitMultiDiscrPerGeoTypes()); - std::size_t sz(contentsSplit.size()); - std::vector< MEDCouplingAutoRefCountObjectPtr< MEDFileAnyTypeField1TS > > ret(sz); - for(std::size_t i=0;i_content=contentsSplit[i]; - } - return ret; -} - -MEDFileAnyTypeField1TS *MEDFileAnyTypeField1TS::deepCpy() const -{ - MEDCouplingAutoRefCountObjectPtr ret=shallowCpy(); - if((const MEDFileAnyTypeField1TSWithoutSDA *)_content) - ret->_content=_content->deepCpy(); - ret->deepCpyGlobs(*this); - return ret.retn(); -} - -int MEDFileAnyTypeField1TS::copyTinyInfoFrom(const MEDCouplingFieldDouble *field, const DataArray *arr) -{ - return contentNotNullBase()->copyTinyInfoFrom(field,arr); -} - -//= MEDFileField1TS - -/*! - * Returns a new instance of MEDFileField1TS holding data of the first time step of - * the first field that has been read from a specified MED file. - * \param [in] fileName - the name of the MED file to read. - * \return MEDFileField1TS * - a new instance of MEDFileFieldMultiTS. The caller - * is to delete this field using decrRef() as it is no more needed. - * \throw If reading the file fails. - */ -MEDFileField1TS *MEDFileField1TS::New(const std::string& fileName, bool loadAll) -{ - MEDCouplingAutoRefCountObjectPtr ret(new MEDFileField1TS(fileName,loadAll,0)); - ret->contentNotNull(); - return ret.retn(); -} - -/*! - * Returns a new instance of MEDFileField1TS holding data of the first time step of - * a given field that has been read from a specified MED file. - * \param [in] fileName - the name of the MED file to read. - * \param [in] fieldName - the name of the field to read. - * \return MEDFileField1TS * - a new instance of MEDFileFieldMultiTS. The caller - * is to delete this field using decrRef() as it is no more needed. - * \throw If reading the file fails. - * \throw If there is no field named \a fieldName in the file. - */ -MEDFileField1TS *MEDFileField1TS::New(const std::string& fileName, const std::string& fieldName, bool loadAll) -{ - MEDCouplingAutoRefCountObjectPtr ret(new MEDFileField1TS(fileName,fieldName,loadAll,0)); - ret->contentNotNull(); - return ret.retn(); -} - -/*! - * Returns a new instance of MEDFileField1TS holding data of a given time step of - * a given field that has been read from a specified MED file. - * \param [in] fileName - the name of the MED file to read. - * \param [in] fieldName - the name of the field to read. - * \param [in] iteration - the iteration number of a required time step. - * \param [in] order - the iteration order number of required time step. - * \return MEDFileField1TS * - a new instance of MEDFileFieldMultiTS. The caller - * is to delete this field using decrRef() as it is no more needed. - * \throw If reading the file fails. - * \throw If there is no field named \a fieldName in the file. - * \throw If the required time step is missing from the file. - */ -MEDFileField1TS *MEDFileField1TS::New(const std::string& fileName, const std::string& fieldName, int iteration, int order, bool loadAll) -{ - MEDCouplingAutoRefCountObjectPtr ret(new MEDFileField1TS(fileName,fieldName,iteration,order,loadAll,0)); - ret->contentNotNull(); - return ret.retn(); -} - -/*! - * Returns a new instance of MEDFileField1TS. If \a shallowCopyOfContent is true the content of \a other is shallow copied. - * If \a shallowCopyOfContent is false, \a other is taken to be the content of \a this. - * - * Returns a new instance of MEDFileField1TS holding either a shallow copy - * of a given MEDFileField1TSWithoutSDA ( \a other ) or \a other itself. - * \warning this is a shallow copy constructor - * \param [in] other - a MEDFileField1TSWithoutSDA to copy. - * \param [in] shallowCopyOfContent - if \c true, a shallow copy of \a other is created. - * \return MEDFileField1TS * - a new instance of MEDFileField1TS. The caller - * is to delete this field using decrRef() as it is no more needed. - */ -MEDFileField1TS *MEDFileField1TS::New(const MEDFileField1TSWithoutSDA& other, bool shallowCopyOfContent) -{ - MEDCouplingAutoRefCountObjectPtr ret=new MEDFileField1TS(other,shallowCopyOfContent); - ret->contentNotNull(); - return ret.retn(); -} - -/*! - * Returns a new empty instance of MEDFileField1TS. - * \return MEDFileField1TS * - a new instance of MEDFileField1TS. The caller - * is to delete this field using decrRef() as it is no more needed. - */ -MEDFileField1TS *MEDFileField1TS::New() -{ - MEDCouplingAutoRefCountObjectPtr ret=new MEDFileField1TS; - ret->contentNotNull(); - return ret.retn(); -} - -/*! - * This method performs a copy with datatype modification ( float64->int32 ) of \a this. The globals information are copied - * following the given input policy. - * - * \param [in] isDeepCpyGlobs - a boolean that indicates the behaviour concerning globals (profiles and localizations) - * By default (true) the globals are deeply copied. - * \return MEDFileIntField1TS * - a new object that is the result of the conversion of \a this to int32 field. - */ -MEDFileIntField1TS *MEDFileField1TS::convertToInt(bool isDeepCpyGlobs) const -{ - MEDCouplingAutoRefCountObjectPtr ret; - const MEDFileAnyTypeField1TSWithoutSDA *content(_content); - if(content) - { - const MEDFileField1TSWithoutSDA *contc=dynamic_cast(content); - if(!contc) - throw INTERP_KERNEL::Exception("MEDFileField1TS::convertToInt : the content inside this is not FLOAT64 ! This is incoherent !"); - MEDCouplingAutoRefCountObjectPtr newc(contc->convertToInt()); - ret=static_cast(MEDFileAnyTypeField1TS::BuildNewInstanceFromContent((MEDFileIntField1TSWithoutSDA *)newc,getFileName())); - } - else - ret=MEDFileIntField1TS::New(); - if(isDeepCpyGlobs) - ret->deepCpyGlobs(*this); - else - ret->shallowCpyGlobs(*this); - return ret.retn(); -} - -const MEDFileField1TSWithoutSDA *MEDFileField1TS::contentNotNull() const -{ - const MEDFileAnyTypeField1TSWithoutSDA *pt(_content); - if(!pt) - throw INTERP_KERNEL::Exception("MEDFileField1TS::contentNotNull : the content pointer is null !"); - const MEDFileField1TSWithoutSDA *ret=dynamic_cast(pt); - if(!ret) - throw INTERP_KERNEL::Exception("MEDFileField1TS::contentNotNull : the content pointer is not null but it is not of type double ! Reason is maybe that the read field has not the type FLOAT64 !"); - return ret; -} - -MEDFileField1TSWithoutSDA *MEDFileField1TS::contentNotNull() -{ - MEDFileAnyTypeField1TSWithoutSDA *pt(_content); - if(!pt) - throw INTERP_KERNEL::Exception("MEDFileField1TS::contentNotNull : the non const content pointer is null !"); - MEDFileField1TSWithoutSDA *ret=dynamic_cast(pt); - if(!ret) - throw INTERP_KERNEL::Exception("MEDFileField1TS::contentNotNull : the non const content pointer is not null but it is not of type double ! Reason is maybe that the read field has not the type FLOAT64 !"); - return ret; -} - -void MEDFileField1TS::SetDataArrayDoubleInField(MEDCouplingFieldDouble *f, MEDCouplingAutoRefCountObjectPtr& arr) -{ - if(!f) - throw INTERP_KERNEL::Exception("MEDFileField1TS::SetDataArrayDoubleInField : input field is NULL !"); - if(!((DataArray*)arr)) - throw INTERP_KERNEL::Exception("MEDFileField1TS::SetDataArrayDoubleInField : no array !"); - DataArrayDouble *arrOutC=dynamic_cast((DataArray*)arr); - if(!arrOutC) - throw INTERP_KERNEL::Exception("MEDFileField1TS::SetDataArrayDoubleInField : mismatch between dataArrays type and MEDFileField1TS ! Expected double !"); - f->setArray(arrOutC); -} - -DataArrayDouble *MEDFileField1TS::ReturnSafelyDataArrayDouble(MEDCouplingAutoRefCountObjectPtr& arr) -{ - if(!((DataArray*)arr)) - throw INTERP_KERNEL::Exception("MEDFileField1TS::ReturnSafelyDataArrayDouble : no array !"); - DataArrayDouble *arrOutC=dynamic_cast((DataArray*)arr); - if(!arrOutC) - throw INTERP_KERNEL::Exception("MEDFileField1TS::ReturnSafelyDataArrayDouble : mismatch between dataArrays type and MEDFileField1TS ! Expected double !"); - arrOutC->incrRef(); - return arrOutC; -} - -MEDFileField1TS::MEDFileField1TS(const std::string& fileName, bool loadAll, const MEDFileMeshes *ms) -try:MEDFileAnyTypeField1TS(fileName,loadAll,ms) -{ -} -catch(INTERP_KERNEL::Exception& e) -{ throw e; } - -MEDFileField1TS::MEDFileField1TS(const std::string& fileName, const std::string& fieldName, bool loadAll, const MEDFileMeshes *ms) -try:MEDFileAnyTypeField1TS(fileName,fieldName,loadAll,ms) -{ -} -catch(INTERP_KERNEL::Exception& e) -{ throw e; } - -MEDFileField1TS::MEDFileField1TS(const std::string& fileName, const std::string& fieldName, int iteration, int order, bool loadAll, const MEDFileMeshes *ms) -try:MEDFileAnyTypeField1TS(fileName,fieldName,iteration,order,loadAll,ms) -{ -} -catch(INTERP_KERNEL::Exception& e) -{ throw e; } - -/*! - * This constructor is a shallow copy constructor. If \a shallowCopyOfContent is true the content of \a other is shallow copied. - * If \a shallowCopyOfContent is false, \a other is taken to be the content of \a this. - * - * \warning this is a shallow copy constructor - */ -MEDFileField1TS::MEDFileField1TS(const MEDFileField1TSWithoutSDA& other, bool shallowCopyOfContent) -try:MEDFileAnyTypeField1TS(other,shallowCopyOfContent) -{ -} -catch(INTERP_KERNEL::Exception& e) -{ throw e; } - -MEDFileField1TS::MEDFileField1TS() -{ - _content=new MEDFileField1TSWithoutSDA; -} - -/*! - * Returns a new MEDCouplingFieldDouble of a given type lying on - * mesh entities of a given dimension of the first mesh in MED file. If \a this field - * has not been constructed via file reading, an exception is thrown. - * For more info, see \ref AdvMEDLoaderAPIFieldRW - * \param [in] type - a spatial discretization of interest. - * \param [in] meshDimRelToMax - a relative dimension of the supporting mesh entities. - * \param [in] renumPol - specifies how to permute values of the result field according to - * the optional numbers of cells and nodes, if any. The valid values are - * - 0 - do not permute. - * - 1 - permute cells. - * - 2 - permute nodes. - * - 3 - permute cells and nodes. - * - * \return MEDCouplingFieldDouble * - a new instance of MEDCouplingFieldDouble. The - * caller is to delete this field using decrRef() as it is no more needed. - * \throw If \a this field has not been constructed via file reading. - * \throw If the MED file is not readable. - * \throw If there is no mesh in the MED file. - * \throw If there are no mesh entities of \a meshDimRelToMax dimension in the mesh. - * \throw If no field values of the given \a type or given \a meshDimRelToMax are available. - * \sa getFieldOnMeshAtLevel() - */ -MEDCouplingFieldDouble *MEDFileField1TS::getFieldAtLevel(TypeOfField type, int meshDimRelToMax, int renumPol) const -{ - if(getFileName().empty()) - throw INTERP_KERNEL::Exception("MEDFileField1TS::getFieldAtLevel : Request for a method that can be used for instances coming from file loading ! Use getFieldOnMeshAtLevel method instead !"); - MEDCouplingAutoRefCountObjectPtr arrOut; - MEDCouplingAutoRefCountObjectPtr ret=contentNotNull()->getFieldAtLevel(type,meshDimRelToMax,std::string(),renumPol,this,arrOut,*contentNotNull()); - MEDFileField1TS::SetDataArrayDoubleInField(ret,arrOut); - return ret.retn(); -} - -/*! - * Returns a new MEDCouplingFieldDouble of a given type lying on - * the top level cells of the first mesh in MED file. If \a this field - * has not been constructed via file reading, an exception is thrown. - * For more info, see \ref AdvMEDLoaderAPIFieldRW - * \param [in] type - a spatial discretization of interest. - * \param [in] renumPol - specifies how to permute values of the result field according to - * the optional numbers of cells and nodes, if any. The valid values are - * - 0 - do not permute. - * - 1 - permute cells. - * - 2 - permute nodes. - * - 3 - permute cells and nodes. - * - * \return MEDCouplingFieldDouble * - a new instance of MEDCouplingFieldDouble. The - * caller is to delete this field using decrRef() as it is no more needed. - * \throw If \a this field has not been constructed via file reading. - * \throw If the MED file is not readable. - * \throw If there is no mesh in the MED file. - * \throw If no field values of the given \a type. - * \throw If no field values lying on the top level support. - * \sa getFieldAtLevel() - */ -MEDCouplingFieldDouble *MEDFileField1TS::getFieldAtTopLevel(TypeOfField type, int renumPol) const -{ - if(getFileName().empty()) - throw INTERP_KERNEL::Exception("MEDFileField1TS::getFieldAtTopLevel : Request for a method that can be used for instances coming from file loading ! Use getFieldOnMeshAtTopLevel method instead !"); - MEDCouplingAutoRefCountObjectPtr arrOut; - MEDCouplingAutoRefCountObjectPtr ret=contentNotNull()->getFieldAtTopLevel(type,std::string(),renumPol,this,arrOut,*contentNotNull()); - MEDFileField1TS::SetDataArrayDoubleInField(ret,arrOut); - return ret.retn(); -} - -/*! - * Returns a new MEDCouplingFieldDouble of given type lying on a given mesh. - * For more info, see \ref AdvMEDLoaderAPIFieldRW - * \param [in] type - a spatial discretization of the new field. - * \param [in] mesh - the supporting mesh. - * \param [in] renumPol - specifies how to permute values of the result field according to - * the optional numbers of cells and nodes, if any. The valid values are - * - 0 - do not permute. - * - 1 - permute cells. - * - 2 - permute nodes. - * - 3 - permute cells and nodes. - * - * \return MEDCouplingFieldDouble * - a new instance of MEDCouplingFieldDouble. The - * caller is to delete this field using decrRef() as it is no more needed. - * \throw If no field of \a this is lying on \a mesh. - * \throw If the mesh is empty. - * \throw If no field values of the given \a type are available. - * \sa getFieldAtLevel() - * \sa getFieldOnMeshAtLevel() - */ -MEDCouplingFieldDouble *MEDFileField1TS::getFieldOnMeshAtLevel(TypeOfField type, const MEDCouplingMesh *mesh, int renumPol) const -{ - MEDCouplingAutoRefCountObjectPtr arrOut; - MEDCouplingAutoRefCountObjectPtr ret=contentNotNull()->getFieldOnMeshAtLevel(type,renumPol,this,mesh,0,0,arrOut,*contentNotNull()); - MEDFileField1TS::SetDataArrayDoubleInField(ret,arrOut); - return ret.retn(); -} - -/*! - * Returns a new MEDCouplingFieldDouble of a given type lying on a given support. - * For more info, see \ref AdvMEDLoaderAPIFieldRW - * \param [in] type - a spatial discretization of interest. - * \param [in] meshDimRelToMax - a relative dimension of the supporting mesh entities. - * \param [in] mesh - the supporting mesh. - * \param [in] renumPol - specifies how to permute values of the result field according to - * the optional numbers of cells and nodes, if any. The valid values are - * - 0 - do not permute. - * - 1 - permute cells. - * - 2 - permute nodes. - * - 3 - permute cells and nodes. - * - * \return MEDCouplingFieldDouble * - a new instance of MEDCouplingFieldDouble. The - * caller is to delete this field using decrRef() as it is no more needed. - * \throw If there are no mesh entities of \a meshDimRelToMax dimension in the mesh. - * \throw If no field of \a this is lying on \a mesh. - * \throw If no field values of the given \a type or given \a meshDimRelToMax are available. - * \sa getFieldAtLevel() - * \sa getFieldOnMeshAtLevel() - */ -MEDCouplingFieldDouble *MEDFileField1TS::getFieldOnMeshAtLevel(TypeOfField type, int meshDimRelToMax, const MEDFileMesh *mesh, int renumPol) const -{ - MEDCouplingAutoRefCountObjectPtr arrOut; - MEDCouplingAutoRefCountObjectPtr ret=contentNotNull()->getFieldOnMeshAtLevel(type,meshDimRelToMax,renumPol,this,mesh,arrOut,*contentNotNull()); - MEDFileField1TS::SetDataArrayDoubleInField(ret,arrOut); - return ret.retn(); -} - -/*! - * Returns a new MEDCouplingFieldDouble of a given type lying on a given support. - * This method is called "Old" because in MED3 norm a field has only one meshName - * attached, so this method is for readers of MED2 files. If \a this field - * has not been constructed via file reading, an exception is thrown. - * For more info, see \ref AdvMEDLoaderAPIFieldRW - * \param [in] type - a spatial discretization of interest. - * \param [in] mName - a name of the supporting mesh. - * \param [in] meshDimRelToMax - a relative dimension of the supporting mesh entities. - * \param [in] renumPol - specifies how to permute values of the result field according to - * the optional numbers of cells and nodes, if any. The valid values are - * - 0 - do not permute. - * - 1 - permute cells. - * - 2 - permute nodes. - * - 3 - permute cells and nodes. - * - * \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 MED file is not readable. - * \throw If there is no mesh named \a mName in the MED file. - * \throw If there are no mesh entities of \a meshDimRelToMax dimension in the mesh. - * \throw If \a this field has not been constructed via file reading. - * \throw If no field of \a this is lying on the mesh named \a mName. - * \throw If no field values of the given \a type or given \a meshDimRelToMax are available. - * \sa getFieldAtLevel() - */ -MEDCouplingFieldDouble *MEDFileField1TS::getFieldAtLevelOld(TypeOfField type, const std::string& mname, int meshDimRelToMax, int renumPol) const -{ - if(getFileName().empty()) - throw INTERP_KERNEL::Exception("MEDFileField1TS::getFieldAtLevelOld : Request for a method that can be used for instances coming from file loading ! Use getFieldOnMeshAtLevel method instead !"); - MEDCouplingAutoRefCountObjectPtr arrOut; - MEDCouplingAutoRefCountObjectPtr ret=contentNotNull()->getFieldAtLevel(type,meshDimRelToMax,mname,renumPol,this,arrOut,*contentNotNull()); - MEDFileField1TS::SetDataArrayDoubleInField(ret,arrOut); - return ret.retn(); -} - -/*! - * Returns values and a profile of the field of a given type lying on a given support. - * For more info, see \ref AdvMEDLoaderAPIFieldRW - * \param [in] type - a spatial discretization of the field. - * \param [in] meshDimRelToMax - a relative dimension of the supporting mesh entities. - * \param [in] mesh - the supporting mesh. - * \param [out] pfl - a new instance of DataArrayInt holding ids of mesh entities the - * field of interest lies on. If the field lies on all entities of the given - * dimension, all ids in \a pfl are zero. The caller is to delete this array - * using decrRef() as it is no more needed. - * \return DataArrayDouble * - a new instance of DataArrayDouble holding values of the - * field. The caller is to delete this array using decrRef() as it is no more needed. - * \throw If there are no mesh entities of \a meshDimRelToMax dimension in \a mesh. - * \throw If no field of \a this is lying on \a mesh. - * \throw If no field values of the given \a type or given \a meshDimRelToMax are available. - */ -DataArrayDouble *MEDFileField1TS::getFieldWithProfile(TypeOfField type, int meshDimRelToMax, const MEDFileMesh *mesh, DataArrayInt *&pfl) const -{ - MEDCouplingAutoRefCountObjectPtr ret=contentNotNull()->getFieldWithProfile(type,meshDimRelToMax,mesh,pfl,this,*contentNotNull()); - return MEDFileField1TS::ReturnSafelyDataArrayDouble(ret); -} - -/*! - * Adds a MEDCouplingFieldDouble to \a this. The underlying mesh of the given field is - * checked if its elements are sorted suitable for writing to MED file ("STB" stands for - * "Sort By Type"), if not, an exception is thrown. - * For more info, see \ref AdvMEDLoaderAPIFieldRW - * \param [in] field - the field to add to \a this. - * \throw If the name of \a field is empty. - * \throw If the data array of \a field is not set. - * \throw If the data array is already allocated but has different number of components - * than \a field. - * \throw If the underlying mesh of \a field has no name. - * \throw If elements in the mesh are not in the order suitable for writing to the MED file. - */ -void MEDFileField1TS::setFieldNoProfileSBT(const MEDCouplingFieldDouble *field) -{ - setFileName(""); - contentNotNull()->setFieldNoProfileSBT(field,field->getArray(),*this,*contentNotNull()); -} - -/*! - * Adds a MEDCouplingFieldDouble to \a this. As described in \ref MEDLoaderMainC a field in MED file sense - * can be an aggregation of several MEDCouplingFieldDouble instances. - * The mesh support of input parameter \a field is ignored here, it can be NULL. - * The support of field \a field is expected to be those computed with the input parameter \a mesh, \a meshDimRelToMax, - * and \a profile. - * - * This method will check that the field based on the computed support is coherent. If not an exception will be thrown. - * A new profile is added only if no equal profile is missing. - * For more info, see \ref AdvMEDLoaderAPIFieldRW - * \param [in] field - the field to add to \a this. The mesh support of field is ignored. - * \param [in] mesh - the supporting mesh of \a field. - * \param [in] meshDimRelToMax - a relative dimension of mesh entities \a field lies on (useless if field spatial discretization is ON_NODES). - * \param [in] profile - ids of mesh entities on which corresponding field values lie. - * \throw If either \a field or \a mesh or \a profile has an empty name. - * \throw If there are no mesh entities of \a meshDimRelToMax dimension in \a mesh. - * \throw If the data array of \a field is not set. - * \throw If the data array of \a this is already allocated but has different number of - * components than \a field. - * \throw If elements in \a mesh are not in the order suitable for writing to the MED file. - * \sa setFieldNoProfileSBT() - */ -void MEDFileField1TS::setFieldProfile(const MEDCouplingFieldDouble *field, const MEDFileMesh *mesh, int meshDimRelToMax, const DataArrayInt *profile) -{ - setFileName(""); - contentNotNull()->setFieldProfile(field,field->getArray(),mesh,meshDimRelToMax,profile,*this,*contentNotNull()); -} - -MEDFileAnyTypeField1TS *MEDFileField1TS::shallowCpy() const -{ - return new MEDFileField1TS(*this); -} - -DataArrayDouble *MEDFileField1TS::getUndergroundDataArray() const -{ - return contentNotNull()->getUndergroundDataArrayDouble(); -} - -DataArrayDouble *MEDFileField1TS::getUndergroundDataArrayExt(std::vector< std::pair,std::pair > >& entries) const -{ - return contentNotNull()->getUndergroundDataArrayDoubleExt(entries); -} - -std::vector< std::vector > MEDFileField1TS::getFieldSplitedByType2(const std::string& mname, std::vector& types, std::vector< std::vector >& typesF, - std::vector< std::vector >& pfls, std::vector< std::vector >& locs) const -{ - return contentNotNull()->getFieldSplitedByType2(mname,types,typesF,pfls,locs); -} - -//= MEDFileIntField1TS - -MEDFileIntField1TS *MEDFileIntField1TS::New() -{ - MEDCouplingAutoRefCountObjectPtr ret=new MEDFileIntField1TS; - ret->contentNotNull(); - return ret.retn(); -} - -MEDFileIntField1TS *MEDFileIntField1TS::New(const std::string& fileName, bool loadAll) -{ - MEDCouplingAutoRefCountObjectPtr ret(new MEDFileIntField1TS(fileName,loadAll,0)); - ret->contentNotNull(); - return ret.retn(); -} - -MEDFileIntField1TS *MEDFileIntField1TS::New(const std::string& fileName, const std::string& fieldName, bool loadAll) -{ - MEDCouplingAutoRefCountObjectPtr ret(new MEDFileIntField1TS(fileName,fieldName,loadAll,0)); - ret->contentNotNull(); - return ret.retn(); -} - -MEDFileIntField1TS *MEDFileIntField1TS::New(const std::string& fileName, const std::string& fieldName, int iteration, int order, bool loadAll) -{ - MEDCouplingAutoRefCountObjectPtr ret(new MEDFileIntField1TS(fileName,fieldName,iteration,order,loadAll,0)); - ret->contentNotNull(); - return ret.retn(); -} - -MEDFileIntField1TS *MEDFileIntField1TS::New(const MEDFileIntField1TSWithoutSDA& other, bool shallowCopyOfContent) -{ - MEDCouplingAutoRefCountObjectPtr ret=new MEDFileIntField1TS(other,shallowCopyOfContent); - ret->contentNotNull(); - return ret.retn(); -} - -MEDFileIntField1TS::MEDFileIntField1TS() -{ - _content=new MEDFileIntField1TSWithoutSDA; -} - -MEDFileIntField1TS::MEDFileIntField1TS(const std::string& fileName, bool loadAll, const MEDFileMeshes *ms) -try:MEDFileAnyTypeField1TS(fileName,loadAll,ms) -{ -} -catch(INTERP_KERNEL::Exception& e) -{ throw e; } - -MEDFileIntField1TS::MEDFileIntField1TS(const std::string& fileName, const std::string& fieldName, bool loadAll, const MEDFileMeshes *ms) -try:MEDFileAnyTypeField1TS(fileName,fieldName,loadAll,ms) -{ -} -catch(INTERP_KERNEL::Exception& e) -{ throw e; } - -MEDFileIntField1TS::MEDFileIntField1TS(const std::string& fileName, const std::string& fieldName, int iteration, int order, bool loadAll, const MEDFileMeshes *ms) -try:MEDFileAnyTypeField1TS(fileName,fieldName,iteration,order,loadAll,ms) -{ -} -catch(INTERP_KERNEL::Exception& e) -{ throw e; } - -/*! - * This constructor is a shallow copy constructor. If \a shallowCopyOfContent is true the content of \a other is shallow copied. - * If \a shallowCopyOfContent is false, \a other is taken to be the content of \a this. - * - * \warning this is a shallow copy constructor - */ -MEDFileIntField1TS::MEDFileIntField1TS(const MEDFileIntField1TSWithoutSDA& other, bool shallowCopyOfContent):MEDFileAnyTypeField1TS(other,shallowCopyOfContent) -{ -} - -MEDFileAnyTypeField1TS *MEDFileIntField1TS::shallowCpy() const -{ - return new MEDFileIntField1TS(*this); -} - -/*! - * This method performs a copy with datatype modification ( int32->float64 ) of \a this. The globals information are copied - * following the given input policy. - * - * \param [in] isDeepCpyGlobs - a boolean that indicates the behaviour concerning globals (profiles and localizations) - * By default (true) the globals are deeply copied. - * \return MEDFileField1TS * - a new object that is the result of the conversion of \a this to float64 field. - */ -MEDFileField1TS *MEDFileIntField1TS::convertToDouble(bool isDeepCpyGlobs) const -{ - MEDCouplingAutoRefCountObjectPtr ret; - const MEDFileAnyTypeField1TSWithoutSDA *content(_content); - if(content) - { - const MEDFileIntField1TSWithoutSDA *contc=dynamic_cast(content); - if(!contc) - throw INTERP_KERNEL::Exception("MEDFileIntField1TS::convertToInt : the content inside this is not INT32 ! This is incoherent !"); - MEDCouplingAutoRefCountObjectPtr newc(contc->convertToDouble()); - ret=static_cast(MEDFileAnyTypeField1TS::BuildNewInstanceFromContent((MEDFileField1TSWithoutSDA *)newc,getFileName())); - } - else - ret=MEDFileField1TS::New(); - if(isDeepCpyGlobs) - ret->deepCpyGlobs(*this); - else - ret->shallowCpyGlobs(*this); - return ret.retn(); -} - -/*! - * Adds a MEDCouplingFieldDouble to \a this. The underlying mesh of the given field is - * checked if its elements are sorted suitable for writing to MED file ("STB" stands for - * "Sort By Type"), if not, an exception is thrown. - * For more info, see \ref AdvMEDLoaderAPIFieldRW - * \param [in] field - the field to add to \a this. The field double values are ignored. - * \param [in] arrOfVals - the values of the field \a field used. - * \throw If the name of \a field is empty. - * \throw If the data array of \a field is not set. - * \throw If the data array is already allocated but has different number of components - * than \a field. - * \throw If the underlying mesh of \a field has no name. - * \throw If elements in the mesh are not in the order suitable for writing to the MED file. - */ -void MEDFileIntField1TS::setFieldNoProfileSBT(const MEDCouplingFieldDouble *field, const DataArrayInt *arrOfVals) -{ - setFileName(""); - contentNotNull()->setFieldNoProfileSBT(field,arrOfVals,*this,*contentNotNull()); -} - -/*! - * Adds a MEDCouplingFieldDouble to \a this. As described in \ref MEDLoaderMainC a field in MED file sense - * can be an aggregation of several MEDCouplingFieldDouble instances. - * The mesh support of input parameter \a field is ignored here, it can be NULL. - * The support of field \a field is expected to be those computed with the input parameter \a mesh, \a meshDimRelToMax, - * and \a profile. - * - * This method will check that the field based on the computed support is coherent. If not an exception will be thrown. - * A new profile is added only if no equal profile is missing. - * For more info, see \ref AdvMEDLoaderAPIFieldRW - * \param [in] field - the field to add to \a this. The field double values and mesh support are ignored. - * \param [in] arrOfVals - the values of the field \a field used. - * \param [in] mesh - the supporting mesh of \a field. - * \param [in] meshDimRelToMax - a relative dimension of mesh entities \a field lies on (useless if field spatial discretization is ON_NODES). - * \param [in] profile - ids of mesh entities on which corresponding field values lie. - * \throw If either \a field or \a mesh or \a profile has an empty name. - * \throw If there are no mesh entities of \a meshDimRelToMax dimension in \a mesh. - * \throw If the data array of \a field is not set. - * \throw If the data array of \a this is already allocated but has different number of - * components than \a field. - * \throw If elements in \a mesh are not in the order suitable for writing to the MED file. - * \sa setFieldNoProfileSBT() - */ -void MEDFileIntField1TS::setFieldProfile(const MEDCouplingFieldDouble *field, const DataArrayInt *arrOfVals, const MEDFileMesh *mesh, int meshDimRelToMax, const DataArrayInt *profile) -{ - setFileName(""); - contentNotNull()->setFieldProfile(field,arrOfVals,mesh,meshDimRelToMax,profile,*this,*contentNotNull()); -} - -const MEDFileIntField1TSWithoutSDA *MEDFileIntField1TS::contentNotNull() const -{ - const MEDFileAnyTypeField1TSWithoutSDA *pt(_content); - if(!pt) - throw INTERP_KERNEL::Exception("MEDFileIntField1TS::contentNotNull : the content pointer is null !"); - const MEDFileIntField1TSWithoutSDA *ret=dynamic_cast(pt); - if(!ret) - throw INTERP_KERNEL::Exception("MEDFileIntField1TS::contentNotNull : the content pointer is not null but it is not of type int32 ! Reason is maybe that the read field has not the type INT32 !"); - return ret; -} - -MEDCouplingFieldDouble *MEDFileIntField1TS::getFieldAtLevel(TypeOfField type, int meshDimRelToMax, DataArrayInt* &arrOut, int renumPol) const -{ - if(getFileName().empty()) - throw INTERP_KERNEL::Exception("MEDFileIntField1TS::getFieldAtLevel : Request for a method that can be used for instances coming from file loading ! Use getFieldOnMeshAtLevel method instead !"); - MEDCouplingAutoRefCountObjectPtr arrOut2; - MEDCouplingAutoRefCountObjectPtr ret=contentNotNull()->getFieldAtLevel(type,meshDimRelToMax,std::string(),renumPol,this,arrOut2,*contentNotNull()); - DataArrayInt *arrOutC=dynamic_cast((DataArray *)arrOut2); - if(!arrOutC) - throw INTERP_KERNEL::Exception("MEDFileIntField1TS::getFieldAtLevelOld : mismatch between dataArrays type and MEDFileIntField1TS ! Expected int32 !"); - arrOut=arrOutC; - arrOut->incrRef(); // arrOut2 dies at the end of the func - return ret.retn(); -} - -DataArrayInt *MEDFileIntField1TS::ReturnSafelyDataArrayInt(MEDCouplingAutoRefCountObjectPtr& arr) -{ - if(!((DataArray *)arr)) - throw INTERP_KERNEL::Exception("MEDFileIntField1TS::ReturnSafelyDataArrayInt : input DataArray is NULL !"); - DataArrayInt *arrC=dynamic_cast((DataArray *)arr); - if(!arrC) - throw INTERP_KERNEL::Exception("MEDFileIntField1TS::ReturnSafelyDataArrayInt : input DataArray is not of type INT32 !"); - arrC->incrRef(); - return arrC; -} - -/*! - * Returns a new MEDCouplingFieldDouble of a given type lying on - * the top level cells of the first mesh in MED file. If \a this field - * has not been constructed via file reading, an exception is thrown. - * For more info, see \ref AdvMEDLoaderAPIFieldRW - * \param [in] type - a spatial discretization of interest. - * \param [out] arrOut - the DataArrayInt containing values of field. - * \param [in] renumPol - specifies how to permute values of the result field according to - * the optional numbers of cells and nodes, if any. The valid values are - * - 0 - do not permute. - * - 1 - permute cells. - * - 2 - permute nodes. - * - 3 - permute cells and nodes. - * - * \return MEDCouplingFieldDouble * - a new instance of MEDCouplingFieldDouble. The - * caller is to delete this field using decrRef() as it is no more needed. - * \throw If \a this field has not been constructed via file reading. - * \throw If the MED file is not readable. - * \throw If there is no mesh in the MED file. - * \throw If no field values of the given \a type. - * \throw If no field values lying on the top level support. - * \sa getFieldAtLevel() - */ -MEDCouplingFieldDouble *MEDFileIntField1TS::getFieldAtTopLevel(TypeOfField type, DataArrayInt* &arrOut, int renumPol) const -{ - if(getFileName().empty()) - throw INTERP_KERNEL::Exception("MEDFileField1TS::getFieldAtTopLevel : Request for a method that can be used for instances coming from file loading ! Use getFieldOnMeshAtTopLevel method instead !"); - MEDCouplingAutoRefCountObjectPtr arr; - MEDCouplingAutoRefCountObjectPtr ret=contentNotNull()->getFieldAtTopLevel(type,std::string(),renumPol,this,arr,*contentNotNull()); - arrOut=MEDFileIntField1TS::ReturnSafelyDataArrayInt(arr); - return ret.retn(); -} - -/*! - * Returns a new MEDCouplingFieldDouble of given type lying on a given mesh. - * For more info, see \ref AdvMEDLoaderAPIFieldRW - * \param [in] type - a spatial discretization of the new field. - * \param [in] mesh - the supporting mesh. - * \param [out] arrOut - the DataArrayInt containing values of field. - * \param [in] renumPol - specifies how to permute values of the result field according to - * the optional numbers of cells and nodes, if any. The valid values are - * - 0 - do not permute. - * - 1 - permute cells. - * - 2 - permute nodes. - * - 3 - permute cells and nodes. - * - * \return MEDCouplingFieldDouble * - a new instance of MEDCouplingFieldDouble. The - * caller is to delete this field using decrRef() as it is no more needed. - * \throw If no field of \a this is lying on \a mesh. - * \throw If the mesh is empty. - * \throw If no field values of the given \a type are available. - * \sa getFieldAtLevel() - * \sa getFieldOnMeshAtLevel() - */ -MEDCouplingFieldDouble *MEDFileIntField1TS::getFieldOnMeshAtLevel(TypeOfField type, const MEDCouplingMesh *mesh, DataArrayInt* &arrOut, int renumPol) const -{ - MEDCouplingAutoRefCountObjectPtr arr; - MEDCouplingAutoRefCountObjectPtr ret=contentNotNull()->getFieldOnMeshAtLevel(type,renumPol,this,mesh,0,0,arr,*contentNotNull()); - arrOut=MEDFileIntField1TS::ReturnSafelyDataArrayInt(arr); - return ret.retn(); -} - -/*! - * Returns a new MEDCouplingFieldDouble of a given type lying on a given support. - * For more info, see \ref AdvMEDLoaderAPIFieldRW - * \param [in] type - a spatial discretization of interest. - * \param [in] meshDimRelToMax - a relative dimension of the supporting mesh entities. - * \param [out] arrOut - the DataArrayInt containing values of field. - * \param [in] mesh - the supporting mesh. - * \param [in] renumPol - specifies how to permute values of the result field according to - * the optional numbers of cells and nodes, if any. The valid values are - * - 0 - do not permute. - * - 1 - permute cells. - * - 2 - permute nodes. - * - 3 - permute cells and nodes. - * - * \return MEDCouplingFieldDouble * - a new instance of MEDCouplingFieldDouble. The - * caller is to delete this field using decrRef() as it is no more needed. - * \throw If there are no mesh entities of \a meshDimRelToMax dimension in the mesh. - * \throw If no field of \a this is lying on \a mesh. - * \throw If no field values of the given \a type or given \a meshDimRelToMax are available. - * \sa getFieldAtLevel() - * \sa getFieldOnMeshAtLevel() - */ -MEDCouplingFieldDouble *MEDFileIntField1TS::getFieldOnMeshAtLevel(TypeOfField type, int meshDimRelToMax, const MEDFileMesh *mesh, DataArrayInt* &arrOut, int renumPol) const -{ - MEDCouplingAutoRefCountObjectPtr arr; - MEDCouplingAutoRefCountObjectPtr ret=contentNotNull()->getFieldOnMeshAtLevel(type,meshDimRelToMax,renumPol,this,mesh,arr,*contentNotNull()); - arrOut=MEDFileIntField1TS::ReturnSafelyDataArrayInt(arr); - return ret.retn(); -} - -/*! - * Returns a new MEDCouplingFieldDouble of a given type lying on a given support. - * This method is called "Old" because in MED3 norm a field has only one meshName - * attached, so this method is for readers of MED2 files. If \a this field - * has not been constructed via file reading, an exception is thrown. - * For more info, see \ref AdvMEDLoaderAPIFieldRW - * \param [in] type - a spatial discretization of interest. - * \param [in] mName - a name of the supporting mesh. - * \param [in] meshDimRelToMax - a relative dimension of the supporting mesh entities. - * \param [out] arrOut - the DataArrayInt containing values of field. - * \param [in] renumPol - specifies how to permute values of the result field according to - * the optional numbers of cells and nodes, if any. The valid values are - * - 0 - do not permute. - * - 1 - permute cells. - * - 2 - permute nodes. - * - 3 - permute cells and nodes. - * - * \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 MED file is not readable. - * \throw If there is no mesh named \a mName in the MED file. - * \throw If there are no mesh entities of \a meshDimRelToMax dimension in the mesh. - * \throw If \a this field has not been constructed via file reading. - * \throw If no field of \a this is lying on the mesh named \a mName. - * \throw If no field values of the given \a type or given \a meshDimRelToMax are available. - * \sa getFieldAtLevel() - */ -MEDCouplingFieldDouble *MEDFileIntField1TS::getFieldAtLevelOld(TypeOfField type, const std::string& mname, int meshDimRelToMax, DataArrayInt* &arrOut, int renumPol) const -{ - if(getFileName().empty()) - throw INTERP_KERNEL::Exception("MEDFileField1TS::getFieldAtLevelOld : Request for a method that can be used for instances coming from file loading ! Use getFieldOnMeshAtLevel method instead !"); - MEDCouplingAutoRefCountObjectPtr arr; - MEDCouplingAutoRefCountObjectPtr ret=contentNotNull()->getFieldAtLevel(type,meshDimRelToMax,mname,renumPol,this,arr,*contentNotNull()); - arrOut=MEDFileIntField1TS::ReturnSafelyDataArrayInt(arr); - return ret.retn(); -} - -/*! - * Returns values and a profile of the field of a given type lying on a given support. - * For more info, see \ref AdvMEDLoaderAPIFieldRW - * \param [in] type - a spatial discretization of the field. - * \param [in] meshDimRelToMax - a relative dimension of the supporting mesh entities. - * \param [in] mesh - the supporting mesh. - * \param [out] pfl - a new instance of DataArrayInt holding ids of mesh entities the - * field of interest lies on. If the field lies on all entities of the given - * dimension, all ids in \a pfl are zero. The caller is to delete this array - * using decrRef() as it is no more needed. - * \return DataArrayInt * - a new instance of DataArrayInt holding values of the - * field. The caller is to delete this array using decrRef() as it is no more needed. - * \throw If there are no mesh entities of \a meshDimRelToMax dimension in \a mesh. - * \throw If no field of \a this is lying on \a mesh. - * \throw If no field values of the given \a type or given \a meshDimRelToMax are available. - */ -DataArrayInt *MEDFileIntField1TS::getFieldWithProfile(TypeOfField type, int meshDimRelToMax, const MEDFileMesh *mesh, DataArrayInt *&pfl) const -{ - MEDCouplingAutoRefCountObjectPtr arr=contentNotNull()->getFieldWithProfile(type,meshDimRelToMax,mesh,pfl,this,*contentNotNull()); - return MEDFileIntField1TS::ReturnSafelyDataArrayInt(arr); -} - -MEDFileIntField1TSWithoutSDA *MEDFileIntField1TS::contentNotNull() -{ - MEDFileAnyTypeField1TSWithoutSDA *pt(_content); - if(!pt) - throw INTERP_KERNEL::Exception("MEDFileIntField1TS::contentNotNull : the non const content pointer is null !"); - MEDFileIntField1TSWithoutSDA *ret=dynamic_cast(pt); - if(!ret) - throw INTERP_KERNEL::Exception("MEDFileIntField1TS::contentNotNull : the non const content pointer is not null but it is not of type int32 ! Reason is maybe that the read field has not the type INT32 !"); - return ret; -} - -DataArrayInt *MEDFileIntField1TS::getUndergroundDataArray() const -{ - return contentNotNull()->getUndergroundDataArrayInt(); -} - -//= MEDFileAnyTypeFieldMultiTSWithoutSDA - -MEDFileAnyTypeFieldMultiTSWithoutSDA::MEDFileAnyTypeFieldMultiTSWithoutSDA() -{ -} - -MEDFileAnyTypeFieldMultiTSWithoutSDA::MEDFileAnyTypeFieldMultiTSWithoutSDA(const std::string& fieldName):MEDFileFieldNameScope(fieldName) -{ -} - -/*! - * \param [in] fieldId field id in C mode - */ -MEDFileAnyTypeFieldMultiTSWithoutSDA::MEDFileAnyTypeFieldMultiTSWithoutSDA(med_idt fid, int fieldId, bool loadAll, const MEDFileMeshes *ms, const std::vector< std::pair > *entities) -{ - med_field_type typcha; - std::string dtunitOut; - int nbOfStep=MEDFileAnyTypeField1TS::LocateField2(fid,"",fieldId,false,_name,typcha,_infos,dtunitOut); - setDtUnit(dtunitOut.c_str()); - loadStructureOrStructureAndBigArraysRecursively(fid,nbOfStep,typcha,loadAll,ms,entities); -} - -MEDFileAnyTypeFieldMultiTSWithoutSDA::MEDFileAnyTypeFieldMultiTSWithoutSDA(med_idt fid, const std::string& fieldName, med_field_type fieldTyp, const std::vector& infos, int nbOfStep, const std::string& dtunit, bool loadAll, const MEDFileMeshes *ms, const std::vector< std::pair > *entities) -try:MEDFileFieldNameScope(fieldName),_infos(infos) -{ - setDtUnit(dtunit.c_str()); - loadStructureOrStructureAndBigArraysRecursively(fid,nbOfStep,fieldTyp,loadAll,ms,entities); -} -catch(INTERP_KERNEL::Exception& e) -{ - throw e; -} - -std::size_t MEDFileAnyTypeFieldMultiTSWithoutSDA::getHeapMemorySizeWithoutChildren() const -{ - std::size_t ret(_name.capacity()+_infos.capacity()*sizeof(std::string)+_time_steps.capacity()*sizeof(MEDCouplingAutoRefCountObjectPtr)); - for(std::vector::const_iterator it=_infos.begin();it!=_infos.end();it++) - ret+=(*it).capacity(); - return ret; -} - -std::vector MEDFileAnyTypeFieldMultiTSWithoutSDA::getDirectChildrenWithNull() const -{ - std::vector ret; - for(std::vector< MEDCouplingAutoRefCountObjectPtr >::const_iterator it=_time_steps.begin();it!=_time_steps.end();it++) - ret.push_back((const MEDFileAnyTypeField1TSWithoutSDA *)*it); - return ret; -} - -/*! - * If one of the id in [ \a startIds , \a endIds ) points to a null element, there is not throw. Simply, this empty element is added as if it were not - * NULL. - */ -MEDFileAnyTypeFieldMultiTSWithoutSDA *MEDFileAnyTypeFieldMultiTSWithoutSDA::buildFromTimeStepIds(const int *startIds, const int *endIds) const -{ - MEDCouplingAutoRefCountObjectPtr ret=createNew(); - ret->setInfo(_infos); - int sz=(int)_time_steps.size(); - for(const int *id=startIds;id!=endIds;id++) - { - if(*id>=0 && *id tse2; - if(tse) - { - tse->incrRef(); - tse2=(const_cast(tse)); - } - ret->pushBackTimeStep(tse2); - } - else - { - std::ostringstream oss; oss << "MEDFileAnyTypeFieldMultiTSWithoutSDA::buildFromTimeStepIds : At pos #" << std::distance(startIds,id) << " value is " << *id; - oss << " ! Should be in [0," << sz << ") !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - } - if(ret->getNumberOfTS()>0) - ret->synchronizeNameScope(); - ret->copyNameScope(*this); - return ret.retn(); -} - -/*! - * If one of the id in the input range points to a null element, there is not throw. Simply, this empty element is added as if it were not - * NULL. - */ -MEDFileAnyTypeFieldMultiTSWithoutSDA *MEDFileAnyTypeFieldMultiTSWithoutSDA::buildFromTimeStepIds2(int bg, int end, int step) const -{ - static const char msg[]="MEDFileAnyTypeFieldMultiTSWithoutSDA::buildFromTimeStepIds2"; - int nbOfEntriesToKeep=DataArrayInt::GetNumberOfItemGivenBESRelative(bg,end,step,msg); - MEDCouplingAutoRefCountObjectPtr ret=createNew(); - ret->setInfo(_infos); - int sz=(int)_time_steps.size(); - int j=bg; - for(int i=0;i=0 && j tse2; - if(tse) - { - tse->incrRef(); - tse2=(const_cast(tse)); - } - ret->pushBackTimeStep(tse2); - } - else - { - std::ostringstream oss; oss << "MEDFileAnyTypeFieldMultiTSWithoutSDA::buildFromTimeStepIds : At pos #" << i << " value is " << j; - oss << " ! Should be in [0," << sz << ") !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - } - if(ret->getNumberOfTS()>0) - ret->synchronizeNameScope(); - ret->copyNameScope(*this); - return ret.retn(); -} - -MEDFileAnyTypeFieldMultiTSWithoutSDA *MEDFileAnyTypeFieldMultiTSWithoutSDA::partOfThisLyingOnSpecifiedTimeSteps(const std::vector< std::pair >& timeSteps) const -{ - int id=0; - MEDCouplingAutoRefCountObjectPtr ids=DataArrayInt::New(); ids->alloc(0,1); - for(std::vector< MEDCouplingAutoRefCountObjectPtr >::const_iterator it=_time_steps.begin();it!=_time_steps.end();it++,id++) - { - const MEDFileAnyTypeField1TSWithoutSDA *cur(*it); - if(!cur) - continue; - std::pair p(cur->getIteration(),cur->getOrder()); - if(std::find(timeSteps.begin(),timeSteps.end(),p)!=timeSteps.end()) - ids->pushBackSilent(id); - } - return buildFromTimeStepIds(ids->begin(),ids->end()); -} - -MEDFileAnyTypeFieldMultiTSWithoutSDA *MEDFileAnyTypeFieldMultiTSWithoutSDA::partOfThisNotLyingOnSpecifiedTimeSteps(const std::vector< std::pair >& timeSteps) const -{ - int id=0; - MEDCouplingAutoRefCountObjectPtr ids=DataArrayInt::New(); ids->alloc(0,1); - for(std::vector< MEDCouplingAutoRefCountObjectPtr >::const_iterator it=_time_steps.begin();it!=_time_steps.end();it++,id++) - { - const MEDFileAnyTypeField1TSWithoutSDA *cur(*it); - if(!cur) - continue; - std::pair p(cur->getIteration(),cur->getOrder()); - if(std::find(timeSteps.begin(),timeSteps.end(),p)==timeSteps.end()) - ids->pushBackSilent(id); - } - return buildFromTimeStepIds(ids->begin(),ids->end()); -} - -bool MEDFileAnyTypeFieldMultiTSWithoutSDA::presenceOfMultiDiscPerGeoType() const -{ - for(std::vector< MEDCouplingAutoRefCountObjectPtr >::const_iterator it=_time_steps.begin();it!=_time_steps.end();it++) - { - const MEDFileAnyTypeField1TSWithoutSDA *cur(*it); - if(!cur) - continue; - if(cur->presenceOfMultiDiscPerGeoType()) - return true; - } - return false; -} - -const std::vector& MEDFileAnyTypeFieldMultiTSWithoutSDA::getInfo() const -{ - return _infos; -} - -void MEDFileAnyTypeFieldMultiTSWithoutSDA::setInfo(const std::vector& info) -{ - _infos=info; -} - -int MEDFileAnyTypeFieldMultiTSWithoutSDA::getTimeStepPos(int iteration, int order) const -{ - int ret=0; - for(std::vector< MEDCouplingAutoRefCountObjectPtr >::const_iterator it=_time_steps.begin();it!=_time_steps.end();it++,ret++) - { - const MEDFileAnyTypeField1TSWithoutSDA *pt(*it); - if(pt->isDealingTS(iteration,order)) - return ret; - } - std::ostringstream oss; oss << "MEDFileFieldMultiTS::getTimeStepPos : Muli timestep field on time (" << iteration << "," << order << ") does not exist ! Available (iteration,order) are :\n"; - std::vector< std::pair > vp=getIterations(); - for(std::vector< std::pair >::const_iterator it2=vp.begin();it2!=vp.end();it2++) - oss << "(" << (*it2).first << "," << (*it2).second << ") "; - throw INTERP_KERNEL::Exception(oss.str().c_str()); -} - -const MEDFileAnyTypeField1TSWithoutSDA& MEDFileAnyTypeFieldMultiTSWithoutSDA::getTimeStepEntry(int iteration, int order) const -{ - return *_time_steps[getTimeStepPos(iteration,order)]; -} - -MEDFileAnyTypeField1TSWithoutSDA& MEDFileAnyTypeFieldMultiTSWithoutSDA::getTimeStepEntry(int iteration, int order) -{ - return *_time_steps[getTimeStepPos(iteration,order)]; -} - -std::string MEDFileAnyTypeFieldMultiTSWithoutSDA::getMeshName() const -{ - if(_time_steps.empty()) - throw INTERP_KERNEL::Exception("MEDFileFieldMultiTSWithoutSDA::getMeshName : not time steps !"); - return _time_steps[0]->getMeshName(); -} - -void MEDFileAnyTypeFieldMultiTSWithoutSDA::setMeshName(const std::string& newMeshName) -{ - std::string oldName(getMeshName()); - std::vector< std::pair > v(1); - v[0].first=oldName; v[0].second=newMeshName; - changeMeshNames(v); -} - -bool MEDFileAnyTypeFieldMultiTSWithoutSDA::changeMeshNames(const std::vector< std::pair >& modifTab) -{ - bool ret=false; - for(std::vector< MEDCouplingAutoRefCountObjectPtr >::iterator it=_time_steps.begin();it!=_time_steps.end();it++) - { - MEDFileAnyTypeField1TSWithoutSDA *cur(*it); - if(cur) - ret=cur->changeMeshNames(modifTab) || ret; - } - return ret; -} - -/*! - * See doc at MEDFileField1TSWithoutSDA::getUndergroundDataArray - */ -DataArray *MEDFileAnyTypeFieldMultiTSWithoutSDA::getUndergroundDataArray(int iteration, int order) const -{ - return getTimeStepEntry(iteration,order).getUndergroundDataArray(); -} - -/*! - * See doc at MEDFileField1TSWithoutSDA::getUndergroundDataArrayExt - */ -DataArray *MEDFileAnyTypeFieldMultiTSWithoutSDA::getUndergroundDataArrayExt(int iteration, int order, std::vector< std::pair,std::pair > >& entries) const -{ - return getTimeStepEntry(iteration,order).getUndergroundDataArrayExt(entries); -} - -bool MEDFileAnyTypeFieldMultiTSWithoutSDA::renumberEntitiesLyingOnMesh(const std::string& meshName, const std::vector& oldCode, const std::vector& newCode, const DataArrayInt *renumO2N, - MEDFileFieldGlobsReal& glob) -{ - bool ret=false; - for(std::vector< MEDCouplingAutoRefCountObjectPtr >::iterator it=_time_steps.begin();it!=_time_steps.end();it++) - { - MEDFileAnyTypeField1TSWithoutSDA *f1ts(*it); - if(f1ts) - ret=f1ts->renumberEntitiesLyingOnMesh(meshName,oldCode,newCode,renumO2N,glob) || ret; - } - return ret; -} - -void MEDFileAnyTypeFieldMultiTSWithoutSDA::simpleRepr(int bkOffset, std::ostream& oss, int fmtsId) const -{ - std::string startLine(bkOffset,' '); - oss << startLine << "Field multi time steps [Type=" << getTypeStr() << "]"; - if(fmtsId>=0) - oss << " (" << fmtsId << ")"; - oss << " has the following name: \"" << _name << "\"." << std::endl; - oss << startLine << "Field multi time steps has " << _infos.size() << " components with the following infos :" << std::endl; - for(std::vector::const_iterator it=_infos.begin();it!=_infos.end();it++) - { - oss << startLine << " - \"" << *it << "\"" << std::endl; - } - int i=0; - for(std::vector< MEDCouplingAutoRefCountObjectPtr >::const_iterator it=_time_steps.begin();it!=_time_steps.end();it++,i++) - { - std::string chapter(17,'0'+i); - oss << startLine << chapter << std::endl; - const MEDFileAnyTypeField1TSWithoutSDA *cur=(*it); - if(cur) - cur->simpleRepr(bkOffset+2,oss,i); - else - oss << startLine << " Field on one time step #" << i << " is not defined !" << std::endl; - oss << startLine << chapter << std::endl; - } -} - -std::vector< std::pair > MEDFileAnyTypeFieldMultiTSWithoutSDA::getTimeSteps(std::vector& ret1) const -{ - std::size_t sz=_time_steps.size(); - std::vector< std::pair > ret(sz); - ret1.resize(sz); - for(std::size_t i=0;igetTime(ret[i].first,ret[i].second); - } - else - { - std::ostringstream oss; oss << "MEDFileFieldMultiTSWithoutSDA::getTimeSteps : At rank #" << i << " time step is not defined. Invoke eraseEmptyTS method !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - } - return ret; -} - -void MEDFileAnyTypeFieldMultiTSWithoutSDA::pushBackTimeStep(MEDCouplingAutoRefCountObjectPtr& tse) -{ - MEDFileAnyTypeField1TSWithoutSDA *tse2(tse); - if(!tse2) - throw INTERP_KERNEL::Exception("MEDFileAnyTypeFieldMultiTSWithoutSDA::pushBackTimeStep : input content object is null !"); - checkCoherencyOfType(tse2); - if(_time_steps.empty()) - { - setName(tse2->getName().c_str()); - setInfo(tse2->getInfo()); - } - checkThatComponentsMatch(tse2->getInfo()); - _time_steps.push_back(tse); -} - -void MEDFileAnyTypeFieldMultiTSWithoutSDA::synchronizeNameScope() -{ - std::size_t nbOfCompo=_infos.size(); - for(std::vector< MEDCouplingAutoRefCountObjectPtr >::iterator it=_time_steps.begin();it!=_time_steps.end();it++) - { - MEDFileAnyTypeField1TSWithoutSDA *cur=(*it); - if(cur) - { - if((cur->getInfo()).size()!=nbOfCompo) - { - std::ostringstream oss; oss << "MEDFileAnyTypeFieldMultiTSWithoutSDA::synchronizeNameScope : Mismatch in the number of components of parts ! Should be " << nbOfCompo; - oss << " ! but the field at iteration=" << cur->getIteration() << " order=" << cur->getOrder() << " has " << (cur->getInfo()).size() << " components !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - cur->copyNameScope(*this); - } - } -} - -void MEDFileAnyTypeFieldMultiTSWithoutSDA::loadStructureOrStructureAndBigArraysRecursively(med_idt fid, int nbPdt, med_field_type fieldTyp, bool loadAll, const MEDFileMeshes *ms, const std::vector< std::pair > *entities) -{ - _time_steps.resize(nbPdt); - for(int i=0;i > ts; - med_int numdt=0,numo=0; - med_int meshIt=0,meshOrder=0; - med_float dt=0.0; - MEDFILESAFECALLERRD0(MEDfieldComputingStepMeshInfo,(fid,_name.c_str(),i+1,&numdt,&numo,&dt,&meshIt,&meshOrder)); - switch(fieldTyp) - { - case MED_FLOAT64: - { - _time_steps[i]=MEDFileField1TSWithoutSDA::New(_name.c_str(),i+1,numdt,numo,_infos); - break; - } - case MED_INT32: - { - _time_steps[i]=MEDFileIntField1TSWithoutSDA::New(_name.c_str(),i+1,numdt,numo,_infos); - break; - } - default: - throw INTERP_KERNEL::Exception("MEDFileAnyTypeFieldMultiTSWithoutSDA::loadStructureOrStructureAndBigArraysRecursively : managed field type are : FLOAT64, INT32 !"); - } - if(loadAll) - _time_steps[i]->loadStructureAndBigArraysRecursively(fid,*this,ms,entities); - else - _time_steps[i]->loadOnlyStructureOfDataRecursively(fid,*this,ms,entities); - } -} - -void MEDFileAnyTypeFieldMultiTSWithoutSDA::writeLL(med_idt fid, const MEDFileWritable& opts) const -{ - if(_time_steps.empty()) - throw INTERP_KERNEL::Exception("MEDFileFieldMultiTSWithoutSDA::writeLL : no time steps set !"); - checkThatNbOfCompoOfTSMatchThis(); - std::vector infos(getInfo()); - int nbComp=infos.size(); - INTERP_KERNEL::AutoPtr comp=MEDLoaderBase::buildEmptyString(nbComp*MED_SNAME_SIZE); - INTERP_KERNEL::AutoPtr unit=MEDLoaderBase::buildEmptyString(nbComp*MED_SNAME_SIZE); - for(int i=0;iwriteLL(fid,opts,*this); -} - -void MEDFileAnyTypeFieldMultiTSWithoutSDA::loadBigArraysRecursively(med_idt fid, const MEDFileFieldNameScope& nasc) -{ - for(std::vector< MEDCouplingAutoRefCountObjectPtr >::iterator it=_time_steps.begin();it!=_time_steps.end();it++) - { - MEDFileAnyTypeField1TSWithoutSDA *elt(*it); - if(elt) - elt->loadBigArraysRecursively(fid,nasc); - } -} - -void MEDFileAnyTypeFieldMultiTSWithoutSDA::loadBigArraysRecursivelyIfNecessary(med_idt fid, const MEDFileFieldNameScope& nasc) -{ - for(std::vector< MEDCouplingAutoRefCountObjectPtr >::iterator it=_time_steps.begin();it!=_time_steps.end();it++) - { - MEDFileAnyTypeField1TSWithoutSDA *elt(*it); - if(elt) - elt->loadBigArraysRecursivelyIfNecessary(fid,nasc); - } -} - -void MEDFileAnyTypeFieldMultiTSWithoutSDA::unloadArrays() -{ - for(std::vector< MEDCouplingAutoRefCountObjectPtr >::iterator it=_time_steps.begin();it!=_time_steps.end();it++) - { - MEDFileAnyTypeField1TSWithoutSDA *elt(*it); - if(elt) - elt->unloadArrays(); - } -} - -int MEDFileAnyTypeFieldMultiTSWithoutSDA::getNumberOfTS() const -{ - return _time_steps.size(); -} - -void MEDFileAnyTypeFieldMultiTSWithoutSDA::eraseEmptyTS() -{ - std::vector< MEDCouplingAutoRefCountObjectPtr > newTS; - for(std::vector< MEDCouplingAutoRefCountObjectPtr >::const_iterator it=_time_steps.begin();it!=_time_steps.end();it++) - { - const MEDFileAnyTypeField1TSWithoutSDA *tmp=(*it); - if(tmp) - newTS.push_back(*it); - } - _time_steps=newTS; -} - -void MEDFileAnyTypeFieldMultiTSWithoutSDA::eraseTimeStepIds(const int *startIds, const int *endIds) -{ - std::vector< MEDCouplingAutoRefCountObjectPtr > newTS; - int maxId=(int)_time_steps.size(); - int ii=0; - std::set idsToDel; - for(const int *id=startIds;id!=endIds;id++,ii++) - { - if(*id>=0 && *id b(sz,true); - int j=bg; - for(int i=0;i > newTS; - for(std::size_t i=0;i >::const_iterator it=_time_steps.begin();it!=_time_steps.end();it++,ret++) - { - const MEDFileAnyTypeField1TSWithoutSDA *tmp(*it); - if(tmp) - { - int it2,ord; - tmp->getTime(it2,ord); - if(it2==iteration && order==ord) - return ret; - else - oss << "(" << it2 << "," << ord << "), "; - } - } - throw INTERP_KERNEL::Exception(oss.str().c_str()); -} - -int MEDFileAnyTypeFieldMultiTSWithoutSDA::getPosGivenTime(double time, double eps) const -{ - int ret=0; - std::ostringstream oss; oss << "MEDFileFieldMultiTSWithoutSDA::getPosGivenTime : No such time step " << time << "! \nPossibilities are : "; - oss.precision(15); - for(std::vector< MEDCouplingAutoRefCountObjectPtr >::const_iterator it=_time_steps.begin();it!=_time_steps.end();it++,ret++) - { - const MEDFileAnyTypeField1TSWithoutSDA *tmp(*it); - if(tmp) - { - int it2,ord; - double ti=tmp->getTime(it2,ord); - if(fabs(time-ti) > MEDFileAnyTypeFieldMultiTSWithoutSDA::getIterations() const -{ - int lgth=_time_steps.size(); - std::vector< std::pair > ret(lgth); - for(int i=0;ifillIteration(ret[i]); - return ret; -} - -/*! - * This method has 3 inputs 'iteration' 'order' 'mname'. 'mname' can be null if the user is the general case where there is only one meshName lying on 'this' - * This method returns two things. - * - The absolute dimension of 'this' in first parameter. - * - The available ext levels relative to the absolute dimension returned in first parameter. These relative levels are relative - * to the first output parameter. The values in 'levs' will be returned in decreasing order. - * - * This method is designed for MEDFileFieldMultiTS instances that have a discritization ON_CELLS, ON_GAUSS_NE and ON_GAUSS. - * Only these 3 discretizations will be taken into account here. - * - * If 'this' is empty this method will throw an INTERP_KERNEL::Exception. - * If there is \b only node fields defined in 'this' -1 is returned and 'levs' output parameter will be empty. In this - * case the caller has to know the underlying mesh it refers to. By defaut it is the level 0 of the corresponding mesh. - * - * This method is usefull to make the link between meshDimension of the underlying mesh in 'this' and the levels on 'this'. - * It is possible (even if it is not common) that the highest level in 'this' were not equal to the meshDimension of the underlying mesh in 'this'. - * - * Let's consider the typical following case : - * - a mesh 'm1' has a meshDimension 3 and has the following non empty levels - * [0,-1,-2] for example 'm1' lies on TETRA4, HEXA8 TRI3 and SEG2 - * - 'f1' lies on 'm1' and is defined on 3D and 1D cells for example - * TETRA4 and SEG2 - * - 'f2' lies on 'm1' too and is defined on 2D and 1D cells for example TRI3 and SEG2 - * - * In this case f1->getNonEmptyLevelsExt will return (3,[0,-2]) and f2->getNonEmptyLevelsExt will return (2,[0,-1]) - * - * To retrieve the highest level of f1 it should be done, f1->getFieldAtLevel(ON_CELLS,3-3+0);//absDim-meshDim+relativeLev - * To retrieve the lowest level of f1 it should be done, f1->getFieldAtLevel(ON_CELLS,3-3+(-2));//absDim-meshDim+relativeLev - * To retrieve the highest level of f2 it should be done, f1->getFieldAtLevel(ON_CELLS,2-3+0);//absDim-meshDim+relativeLev - * To retrieve the lowest level of f2 it should be done, f1->getFieldAtLevel(ON_CELLS,2-3+(-1));//absDim-meshDim+relativeLev - */ -int MEDFileAnyTypeFieldMultiTSWithoutSDA::getNonEmptyLevels(int iteration, int order, const std::string& mname, std::vector& levs) const -{ - return getTimeStepEntry(iteration,order).getNonEmptyLevels(mname,levs); -} - -const MEDFileAnyTypeField1TSWithoutSDA *MEDFileAnyTypeFieldMultiTSWithoutSDA::getTimeStepAtPos2(int pos) const -{ - if(pos<0 || pos>=(int)_time_steps.size()) - { - std::ostringstream oss; oss << "MEDFileAnyTypeFieldMultiTSWithoutSDA::getTimeStepAtPos2 : request for pos #" << pos << " whereas should be in [0," << _time_steps.size() << ") !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - const MEDFileAnyTypeField1TSWithoutSDA *item=_time_steps[pos]; - if(item==0) - { - std::ostringstream oss; oss << "MEDFileAnyTypeFieldMultiTSWithoutSDA::getTimeStepAtPos2 : request for pos #" << pos << ", this pos id exists but the underlying Field1TS is null !"; - oss << "\nTry to use following method eraseEmptyTS !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - return item; -} - -MEDFileAnyTypeField1TSWithoutSDA *MEDFileAnyTypeFieldMultiTSWithoutSDA::getTimeStepAtPos2(int pos) -{ - if(pos<0 || pos>=(int)_time_steps.size()) - { - std::ostringstream oss; oss << "MEDFileAnyTypeFieldMultiTSWithoutSDA::getTimeStepAtPos2 : request for pos #" << pos << " whereas should be in [0," << _time_steps.size() << ") !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - MEDFileAnyTypeField1TSWithoutSDA *item=_time_steps[pos]; - if(item==0) - { - std::ostringstream oss; oss << "MEDFileAnyTypeFieldMultiTSWithoutSDA::getTimeStepAtPos2 : request for pos #" << pos << ", this pos id exists but the underlying Field1TS is null !"; - oss << "\nTry to use following method eraseEmptyTS !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - return item; -} - -std::vector MEDFileAnyTypeFieldMultiTSWithoutSDA::getPflsReallyUsed2() const -{ - std::vector ret; - std::set ret2; - for(std::vector< MEDCouplingAutoRefCountObjectPtr< MEDFileAnyTypeField1TSWithoutSDA > >::const_iterator it=_time_steps.begin();it!=_time_steps.end();it++) - { - std::vector tmp=(*it)->getPflsReallyUsed2(); - for(std::vector::const_iterator it2=tmp.begin();it2!=tmp.end();it2++) - if(ret2.find(*it2)==ret2.end()) - { - ret.push_back(*it2); - ret2.insert(*it2); - } - } - return ret; -} - -std::vector MEDFileAnyTypeFieldMultiTSWithoutSDA::getLocsReallyUsed2() const -{ - std::vector ret; - std::set ret2; - for(std::vector< MEDCouplingAutoRefCountObjectPtr< MEDFileAnyTypeField1TSWithoutSDA > >::const_iterator it=_time_steps.begin();it!=_time_steps.end();it++) - { - std::vector tmp=(*it)->getLocsReallyUsed2(); - for(std::vector::const_iterator it2=tmp.begin();it2!=tmp.end();it2++) - if(ret2.find(*it2)==ret2.end()) - { - ret.push_back(*it2); - ret2.insert(*it2); - } - } - return ret; -} - -std::vector MEDFileAnyTypeFieldMultiTSWithoutSDA::getPflsReallyUsedMulti2() const -{ - std::vector ret; - for(std::vector< MEDCouplingAutoRefCountObjectPtr< MEDFileAnyTypeField1TSWithoutSDA > >::const_iterator it=_time_steps.begin();it!=_time_steps.end();it++) - { - std::vector tmp=(*it)->getPflsReallyUsedMulti2(); - ret.insert(ret.end(),tmp.begin(),tmp.end()); - } - return ret; -} - -std::vector MEDFileAnyTypeFieldMultiTSWithoutSDA::getLocsReallyUsedMulti2() const -{ - std::vector ret; - for(std::vector< MEDCouplingAutoRefCountObjectPtr< MEDFileAnyTypeField1TSWithoutSDA > >::const_iterator it=_time_steps.begin();it!=_time_steps.end();it++) - { - std::vector tmp=(*it)->getLocsReallyUsedMulti2(); - ret.insert(ret.end(),tmp.begin(),tmp.end()); - } - return ret; -} - -void MEDFileAnyTypeFieldMultiTSWithoutSDA::changePflsRefsNamesGen2(const std::vector< std::pair, std::string > >& mapOfModif) -{ - for(std::vector< MEDCouplingAutoRefCountObjectPtr< MEDFileAnyTypeField1TSWithoutSDA > >::iterator it=_time_steps.begin();it!=_time_steps.end();it++) - (*it)->changePflsRefsNamesGen2(mapOfModif); -} - -void MEDFileAnyTypeFieldMultiTSWithoutSDA::changeLocsRefsNamesGen2(const std::vector< std::pair, std::string > >& mapOfModif) -{ - for(std::vector< MEDCouplingAutoRefCountObjectPtr< MEDFileAnyTypeField1TSWithoutSDA > >::iterator it=_time_steps.begin();it!=_time_steps.end();it++) - (*it)->changeLocsRefsNamesGen2(mapOfModif); -} - -std::vector< std::vector > MEDFileAnyTypeFieldMultiTSWithoutSDA::getTypesOfFieldAvailable() const -{ - int lgth=_time_steps.size(); - std::vector< std::vector > ret(lgth); - for(int i=0;ifillTypesOfFieldAvailable(ret[i]); - return ret; -} - -/*! - * entry point for users that want to iterate into MEDFile DataStructure without any overhead. - */ -std::vector< std::vector< std::pair > > MEDFileAnyTypeFieldMultiTSWithoutSDA::getFieldSplitedByType(int iteration, int order, const std::string& mname, std::vector& types, std::vector< std::vector >& typesF, std::vector< std::vector >& pfls, std::vector< std::vector >& locs) const -{ - return getTimeStepEntry(iteration,order).getFieldSplitedByType(mname,types,typesF,pfls,locs); -} - -MEDFileAnyTypeFieldMultiTSWithoutSDA *MEDFileAnyTypeFieldMultiTSWithoutSDA::deepCpy() const -{ - MEDCouplingAutoRefCountObjectPtr ret=shallowCpy(); - std::size_t i=0; - for(std::vector< MEDCouplingAutoRefCountObjectPtr >::const_iterator it=_time_steps.begin();it!=_time_steps.end();it++,i++) - { - if((const MEDFileAnyTypeField1TSWithoutSDA *)*it) - ret->_time_steps[i]=(*it)->deepCpy(); - } - return ret.retn(); -} - -std::vector< MEDCouplingAutoRefCountObjectPtr > MEDFileAnyTypeFieldMultiTSWithoutSDA::splitComponents() const -{ - std::size_t sz(_infos.size()),sz2(_time_steps.size()); - std::vector< MEDCouplingAutoRefCountObjectPtr > ret(sz); - std::vector< std::vector< MEDCouplingAutoRefCountObjectPtr > > ts(sz2); - for(std::size_t i=0;i_infos.resize(1); ret[i]->_infos[0]=_infos[i]; - } - for(std::size_t i=0;i > ret1=_time_steps[i]->splitComponents(); - if(ret1.size()!=sz) - { - std::ostringstream oss; oss << "MEDFileAnyTypeFieldMultiTSWithoutSDA::splitComponents : At rank #" << i << " number of components is " << ret1.size() << " whereas it should be for all time steps " << sz << " !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - ts[i]=ret1; - } - for(std::size_t i=0;i_time_steps[j]=ts[j][i]; - return ret; -} - -/*! - * This method splits into discretization each time steps in \a this. - * ** WARNING ** the returned instances are not compulsary defined on the same time steps series ! - */ -std::vector< MEDCouplingAutoRefCountObjectPtr > MEDFileAnyTypeFieldMultiTSWithoutSDA::splitDiscretizations() const -{ - std::size_t sz(_time_steps.size()); - std::vector< std::vector< MEDCouplingAutoRefCountObjectPtr > > items(sz); - for(std::size_t i=0;isplitDiscretizations(); - } - // - std::vector< MEDCouplingAutoRefCountObjectPtr > ret; - std::vector< std::vector< MEDCouplingAutoRefCountObjectPtr > > ret2; - std::vector< TypeOfField > types; - for(std::vector< std::vector< MEDCouplingAutoRefCountObjectPtr > >::const_iterator it0=items.begin();it0!=items.end();it0++) - for(std::vector< MEDCouplingAutoRefCountObjectPtr >::const_iterator it1=(*it0).begin();it1!=(*it0).end();it1++) - { - std::vector ts=(*it1)->getTypesOfFieldAvailable(); - if(ts.size()!=1) - throw INTERP_KERNEL::Exception("MEDFileAnyTypeFieldMultiTSWithoutSDA::splitDiscretizations : it appears that the splitting of MEDFileAnyTypeField1TSWithoutSDA::splitDiscretizations has returned invalid result !"); - std::vector< TypeOfField >::iterator it2=std::find(types.begin(),types.end(),ts[0]); - if(it2==types.end()) - types.push_back(ts[0]); - } - ret.resize(types.size()); ret2.resize(types.size()); - for(std::vector< std::vector< MEDCouplingAutoRefCountObjectPtr > >::const_iterator it0=items.begin();it0!=items.end();it0++) - for(std::vector< MEDCouplingAutoRefCountObjectPtr >::const_iterator it1=(*it0).begin();it1!=(*it0).end();it1++) - { - TypeOfField typ=(*it1)->getTypesOfFieldAvailable()[0]; - std::size_t pos=std::distance(types.begin(),std::find(types.begin(),types.end(),typ)); - ret2[pos].push_back(*it1); - } - for(std::size_t i=0;i elt(createNew()); - for(std::vector< MEDCouplingAutoRefCountObjectPtr >::iterator it1=ret2[i].begin();it1!=ret2[i].end();it1++) - elt->pushBackTimeStep(*it1);//also updates infos in elt - ret[i]=elt; - elt->MEDFileFieldNameScope::operator=(*this); - } - return ret; -} - -/*! - * Contrary to splitDiscretizations method this method makes the hypothesis that the times series are **NOT** impacted by the splitting of multi discretization. - */ -std::vector< MEDCouplingAutoRefCountObjectPtr > MEDFileAnyTypeFieldMultiTSWithoutSDA::splitMultiDiscrPerGeoTypes() const -{ - std::size_t sz(_time_steps.size()); - std::vector< std::vector< MEDCouplingAutoRefCountObjectPtr > > items(sz); - std::size_t szOut(std::numeric_limits::max()); - for(std::size_t i=0;isplitMultiDiscrPerGeoTypes(); - if(szOut==std::numeric_limits::max()) - szOut=items[i].size(); - else - if(items[i].size()!=szOut) - throw INTERP_KERNEL::Exception("MEDFileAnyTypeFieldMultiTSWithoutSDA::splitMultiDiscrPerGeoTypes : The splitting per discretization is expected to be same among time steps !"); - } - if(szOut==std::numeric_limits::max()) - throw INTERP_KERNEL::Exception("MEDFileAnyTypeFieldMultiTSWithoutSDA::splitMultiDiscrPerGeoTypes : empty field !"); - std::vector< MEDCouplingAutoRefCountObjectPtr > ret(szOut); - for(std::size_t i=0;i elt(createNew()); - for(std::size_t j=0;jpushBackTimeStep(items[j][i]); - ret[i]=elt; - elt->MEDFileFieldNameScope::operator=(*this); - } - return ret; -} - -void MEDFileAnyTypeFieldMultiTSWithoutSDA::copyTinyInfoFrom(const MEDCouplingFieldDouble *field, const DataArray *arr) -{ - _name=field->getName(); - if(_name.empty()) - throw INTERP_KERNEL::Exception("MEDFileFieldMultiTSWithoutSDA::copyTinyInfoFrom : unsupported fields with no name in MED file !"); - if(!arr) - throw INTERP_KERNEL::Exception("MEDFileFieldMultiTSWithoutSDA::copyTinyInfoFrom : no array set !"); - _infos=arr->getInfoOnComponents(); -} - -void MEDFileAnyTypeFieldMultiTSWithoutSDA::checkCoherencyOfTinyInfo(const MEDCouplingFieldDouble *field, const DataArray *arr) const -{ - static const char MSG[]="MEDFileFieldMultiTSWithoutSDA::checkCoherencyOfTinyInfo : invalid "; - if(_name!=field->getName()) - { - std::ostringstream oss; oss << MSG << "name ! should be \"" << _name; - oss << "\" and it is set in input field to \"" << field->getName() << "\" !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - if(!arr) - throw INTERP_KERNEL::Exception("MEDFileFieldMultiTSWithoutSDA::checkCoherencyOfTinyInfo : no array set !"); - checkThatComponentsMatch(arr->getInfoOnComponents()); -} - -void MEDFileAnyTypeFieldMultiTSWithoutSDA::checkThatComponentsMatch(const std::vector& compos) const -{ - static const char MSG[]="MEDFileFieldMultiTSWithoutSDA::checkThatComponentsMatch : "; - if(getInfo().size()!=compos.size()) - { - std::ostringstream oss; oss << MSG << "mismatch of number of components between this (" << getInfo().size() << ") and "; - oss << " number of components of element to append (" << compos.size() << ") !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - if(_infos!=compos) - { - std::ostringstream oss; oss << MSG << "components have same size but are different ! should be \""; - std::copy(_infos.begin(),_infos.end(),std::ostream_iterator(oss,", ")); - oss << " But compo in input fields are : "; - std::copy(compos.begin(),compos.end(),std::ostream_iterator(oss,", ")); - oss << " !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } -} - -void MEDFileAnyTypeFieldMultiTSWithoutSDA::checkThatNbOfCompoOfTSMatchThis() const -{ - std::size_t sz=_infos.size(); - int j=0; - for(std::vector< MEDCouplingAutoRefCountObjectPtr >::const_iterator it=_time_steps.begin();it!=_time_steps.end();it++,j++) - { - const MEDFileAnyTypeField1TSWithoutSDA *elt(*it); - if(elt) - if(elt->getInfo().size()!=sz) - { - std::ostringstream oss; oss << "MEDFileAnyTypeFieldMultiTSWithoutSDA::checkThatNbOfCompoOfTSMatchThis : At pos #" << j << " the number of components is equal to "; - oss << elt->getInfo().size() << " whereas it is expected to be equal to " << sz << " !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - } -} - -void MEDFileAnyTypeFieldMultiTSWithoutSDA::appendFieldNoProfileSBT(const MEDCouplingFieldDouble *field, const DataArray *arr, MEDFileFieldGlobsReal& glob) -{ - if(!field) - throw INTERP_KERNEL::Exception("MEDFileAnyTypeFieldMultiTSWithoutSDA::appendFieldNoProfileSBT : input field is NULL !"); - if(!_time_steps.empty()) - checkCoherencyOfTinyInfo(field,arr); - MEDFileAnyTypeField1TSWithoutSDA *objC=createNew1TSWithoutSDAEmptyInstance(); - MEDCouplingAutoRefCountObjectPtr obj(objC); - objC->setFieldNoProfileSBT(field,arr,glob,*this); - copyTinyInfoFrom(field,arr); - _time_steps.push_back(obj); -} - -void MEDFileAnyTypeFieldMultiTSWithoutSDA::appendFieldProfile(const MEDCouplingFieldDouble *field, const DataArray *arr, const MEDFileMesh *mesh, int meshDimRelToMax, const DataArrayInt *profile, MEDFileFieldGlobsReal& glob) -{ - if(!field) - throw INTERP_KERNEL::Exception("MEDFileIntFieldMultiTSWithoutSDA::appendFieldNoProfileSBT : input field is NULL !"); - if(!_time_steps.empty()) - checkCoherencyOfTinyInfo(field,arr); - MEDFileField1TSWithoutSDA *objC=new MEDFileField1TSWithoutSDA; - MEDCouplingAutoRefCountObjectPtr obj(objC); - objC->setFieldProfile(field,arr,mesh,meshDimRelToMax,profile,glob,*this); - copyTinyInfoFrom(field,arr); - _time_steps.push_back(obj); -} - -void MEDFileAnyTypeFieldMultiTSWithoutSDA::setIteration(int i, MEDCouplingAutoRefCountObjectPtr ts) -{ - int sz=(int)_time_steps.size(); - if(i<0 || i>=sz) - { - std::ostringstream oss; oss << "MEDFileAnyTypeFieldMultiTSWithoutSDA::setIteration : trying to set element at place #" << i << " should be in [0," << sz << ") !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - const MEDFileAnyTypeField1TSWithoutSDA *tsPtr(ts); - if(tsPtr) - { - if(tsPtr->getNumberOfComponents()!=(int)_infos.size()) - { - std::ostringstream oss; oss << "MEDFileAnyTypeFieldMultiTSWithoutSDA::setIteration : trying to set element with " << tsPtr->getNumberOfComponents() << " components ! Should be " << _infos.size() << " !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - } - _time_steps[i]=ts; -} - -//= MEDFileFieldMultiTSWithoutSDA - -MEDFileFieldMultiTSWithoutSDA *MEDFileFieldMultiTSWithoutSDA::New(med_idt fid, const std::string& fieldName, med_field_type fieldTyp, const std::vector& infos, int nbOfStep, const std::string& dtunit, bool loadAll, const MEDFileMeshes *ms, const std::vector< std::pair > *entities) -{ - return new MEDFileFieldMultiTSWithoutSDA(fid,fieldName,fieldTyp,infos,nbOfStep,dtunit,loadAll,ms,entities); -} - -MEDFileFieldMultiTSWithoutSDA::MEDFileFieldMultiTSWithoutSDA() -{ -} - -MEDFileFieldMultiTSWithoutSDA::MEDFileFieldMultiTSWithoutSDA(const std::string& fieldName):MEDFileAnyTypeFieldMultiTSWithoutSDA(fieldName) -{ -} - -/*! - * \param [in] fieldId field id in C mode - */ -MEDFileFieldMultiTSWithoutSDA::MEDFileFieldMultiTSWithoutSDA(med_idt fid, int fieldId, bool loadAll, const MEDFileMeshes *ms, const std::vector< std::pair > *entities) -try:MEDFileAnyTypeFieldMultiTSWithoutSDA(fid,fieldId,loadAll,ms,entities) -{ -} -catch(INTERP_KERNEL::Exception& e) -{ throw e; } - -MEDFileFieldMultiTSWithoutSDA::MEDFileFieldMultiTSWithoutSDA(med_idt fid, const std::string& fieldName, med_field_type fieldTyp, const std::vector& infos, int nbOfStep, const std::string& dtunit, bool loadAll, const MEDFileMeshes *ms, const std::vector< std::pair > *entities) -try:MEDFileAnyTypeFieldMultiTSWithoutSDA(fid,fieldName,fieldTyp,infos,nbOfStep,dtunit,loadAll,ms,entities) -{ -} -catch(INTERP_KERNEL::Exception& e) -{ throw e; } - -MEDFileAnyTypeField1TSWithoutSDA *MEDFileFieldMultiTSWithoutSDA::createNew1TSWithoutSDAEmptyInstance() const -{ - return new MEDFileField1TSWithoutSDA; -} - -void MEDFileFieldMultiTSWithoutSDA::checkCoherencyOfType(const MEDFileAnyTypeField1TSWithoutSDA *f1ts) const -{ - if(!f1ts) - throw INTERP_KERNEL::Exception("MEDFileFieldMultiTSWithoutSDA::checkCoherencyOfType : input field1TS is NULL ! Impossible to check !"); - const MEDFileField1TSWithoutSDA *f1tsC=dynamic_cast(f1ts); - if(!f1tsC) - throw INTERP_KERNEL::Exception("MEDFileFieldMultiTSWithoutSDA::checkCoherencyOfType : the input field1TS is not a FLOAT64 type !"); -} - -const char *MEDFileFieldMultiTSWithoutSDA::getTypeStr() const -{ - return MEDFileField1TSWithoutSDA::TYPE_STR; -} - -MEDFileAnyTypeFieldMultiTSWithoutSDA *MEDFileFieldMultiTSWithoutSDA::shallowCpy() const -{ - return new MEDFileFieldMultiTSWithoutSDA(*this); -} - -MEDFileAnyTypeFieldMultiTSWithoutSDA *MEDFileFieldMultiTSWithoutSDA::createNew() const -{ - return new MEDFileFieldMultiTSWithoutSDA; -} - -/*! - * entry point for users that want to iterate into MEDFile DataStructure with a reduced overhead because output arrays are extracted (created) specially - * for the call of this method. That's why the DataArrayDouble instance in returned vector of vector should be dealed by the caller. - */ -std::vector< std::vector > MEDFileFieldMultiTSWithoutSDA::getFieldSplitedByType2(int iteration, int order, const std::string& mname, std::vector& types, std::vector< std::vector >& typesF, std::vector< std::vector >& pfls, std::vector< std::vector >& locs) const -{ - const MEDFileAnyTypeField1TSWithoutSDA& myF1TS=getTimeStepEntry(iteration,order); - const MEDFileField1TSWithoutSDA *myF1TSC=dynamic_cast(&myF1TS); - if(!myF1TSC) - throw INTERP_KERNEL::Exception("MEDFileFieldMultiTSWithoutSDA::getFieldSplitedByType2 : mismatch of type of field expecting FLOAT64 !"); - return myF1TSC->getFieldSplitedByType2(mname,types,typesF,pfls,locs); -} - -MEDFileIntFieldMultiTSWithoutSDA *MEDFileFieldMultiTSWithoutSDA::convertToInt() const -{ - MEDCouplingAutoRefCountObjectPtr ret(new MEDFileIntFieldMultiTSWithoutSDA); - ret->MEDFileAnyTypeFieldMultiTSWithoutSDA::operator =(*this); - int i=0; - for(std::vector< MEDCouplingAutoRefCountObjectPtr >::const_iterator it=_time_steps.begin();it!=_time_steps.end();it++,i++) - { - const MEDFileAnyTypeField1TSWithoutSDA *eltToConv(*it); - if(eltToConv) - { - const MEDFileField1TSWithoutSDA *eltToConvC=dynamic_cast(eltToConv); - if(!eltToConvC) - throw INTERP_KERNEL::Exception("MEDFileFieldMultiTSWithoutSDA::convertToInt : presence of an invalid 1TS type ! Should be of type FLOAT64 !"); - MEDCouplingAutoRefCountObjectPtr elt=eltToConvC->convertToInt(); - ret->setIteration(i,elt); - } - } - return ret.retn(); -} - -//= MEDFileAnyTypeFieldMultiTS - -MEDFileAnyTypeFieldMultiTS::MEDFileAnyTypeFieldMultiTS() -{ -} - -MEDFileAnyTypeFieldMultiTS::MEDFileAnyTypeFieldMultiTS(const std::string& fileName, bool loadAll, const MEDFileMeshes *ms) -try:MEDFileFieldGlobsReal(fileName) -{ - MEDFileUtilities::CheckFileForRead(fileName); - MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName.c_str(),MED_ACC_RDONLY); - _content=BuildContentFrom(fid,fileName,loadAll,ms); - loadGlobals(fid); -} -catch(INTERP_KERNEL::Exception& e) -{ - throw e; -} - -MEDFileAnyTypeFieldMultiTSWithoutSDA *MEDFileAnyTypeFieldMultiTS::BuildContentFrom(med_idt fid, const std::string& fileName, const std::string& fieldName, bool loadAll, const MEDFileMeshes *ms, const std::vector< std::pair > *entities) -{ - med_field_type typcha; - std::vector infos; - std::string dtunit; - int i=-1; - MEDFileAnyTypeField1TS::LocateField(fid,fileName,fieldName,i,typcha,infos,dtunit); - MEDCouplingAutoRefCountObjectPtr ret; - switch(typcha) - { - case MED_FLOAT64: - { - ret=new MEDFileFieldMultiTSWithoutSDA(fid,i,loadAll,ms,entities); - break; - } - case MED_INT32: - { - ret=new MEDFileIntFieldMultiTSWithoutSDA(fid,i,loadAll,ms,entities); - break; - } - default: - { - std::ostringstream oss; oss << "MEDFileAnyTypeFieldMultiTS::BuildContentFrom(fileName,fieldName) : file \'" << fileName << "\' contains field with name \'" << fieldName << "\' but the type of field is not in [MED_FLOAT64, MED_INT32] !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - } - ret->setDtUnit(dtunit.c_str()); - return ret.retn(); -} - -MEDFileAnyTypeFieldMultiTSWithoutSDA *MEDFileAnyTypeFieldMultiTS::BuildContentFrom(med_idt fid, const std::string& fileName, bool loadAll, const MEDFileMeshes *ms) -{ - med_field_type typcha; - // - std::vector infos; - std::string dtunit,fieldName; - MEDFileAnyTypeField1TS::LocateField2(fid,fileName,0,true,fieldName,typcha,infos,dtunit); - MEDCouplingAutoRefCountObjectPtr ret; - switch(typcha) - { - case MED_FLOAT64: - { - ret=new MEDFileFieldMultiTSWithoutSDA(fid,0,loadAll,ms,0); - break; - } - case MED_INT32: - { - ret=new MEDFileIntFieldMultiTSWithoutSDA(fid,0,loadAll,ms,0); - break; - } - default: - { - std::ostringstream oss; oss << "MEDFileAnyTypeFieldMultiTS::BuildContentFrom(fileName) : file \'" << fileName << "\' contains field with name \'" << fieldName << "\' but the type of the first field is not in [MED_FLOAT64, MED_INT32] !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - } - ret->setDtUnit(dtunit.c_str()); - return ret.retn(); -} - -MEDFileAnyTypeFieldMultiTS *MEDFileAnyTypeFieldMultiTS::BuildNewInstanceFromContent(MEDFileAnyTypeFieldMultiTSWithoutSDA *c, const std::string& fileName) -{ - if(!c) - throw INTERP_KERNEL::Exception("MEDFileAnyTypeFieldMultiTS::BuildNewInstanceFromContent : empty content in input : unable to build a new instance !"); - if(dynamic_cast(c)) - { - MEDCouplingAutoRefCountObjectPtr ret=MEDFileFieldMultiTS::New(); - ret->setFileName(fileName); - ret->_content=c; c->incrRef(); - return ret.retn(); - } - if(dynamic_cast(c)) - { - MEDCouplingAutoRefCountObjectPtr ret=MEDFileIntFieldMultiTS::New(); - ret->setFileName(fileName); - ret->_content=c; c->incrRef(); - return ret.retn(); - } - throw INTERP_KERNEL::Exception("MEDFileAnyTypeFieldMultiTS::BuildNewInstanceFromContent : internal error ! a content of type different from FLOAT64 and INT32 has been built but not intercepted !"); -} - -MEDFileAnyTypeFieldMultiTS::MEDFileAnyTypeFieldMultiTS(const std::string& fileName, const std::string& fieldName, bool loadAll, const MEDFileMeshes *ms, const std::vector< std::pair > *entities) -try:MEDFileFieldGlobsReal(fileName) -{ - MEDFileUtilities::CheckFileForRead(fileName); - MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName.c_str(),MED_ACC_RDONLY); - _content=BuildContentFrom(fid,fileName,fieldName,loadAll,ms,entities); - loadGlobals(fid); -} -catch(INTERP_KERNEL::Exception& e) -{ - throw e; -} - -//= MEDFileIntFieldMultiTSWithoutSDA - -MEDFileIntFieldMultiTSWithoutSDA *MEDFileIntFieldMultiTSWithoutSDA::New(med_idt fid, const std::string& fieldName, med_field_type fieldTyp, const std::vector& infos, int nbOfStep, const std::string& dtunit, bool loadAll, const MEDFileMeshes *ms, const std::vector< std::pair > *entities) -{ - return new MEDFileIntFieldMultiTSWithoutSDA(fid,fieldName,fieldTyp,infos,nbOfStep,dtunit,loadAll,ms,entities); -} - -MEDFileIntFieldMultiTSWithoutSDA::MEDFileIntFieldMultiTSWithoutSDA() -{ -} - -MEDFileIntFieldMultiTSWithoutSDA::MEDFileIntFieldMultiTSWithoutSDA(const std::string& fieldName):MEDFileAnyTypeFieldMultiTSWithoutSDA(fieldName) -{ -} - -MEDFileIntFieldMultiTSWithoutSDA::MEDFileIntFieldMultiTSWithoutSDA(med_idt fid, const std::string& fieldName, med_field_type fieldTyp, const std::vector& infos, int nbOfStep, const std::string& dtunit, bool loadAll, const MEDFileMeshes *ms, const std::vector< std::pair > *entities) -try:MEDFileAnyTypeFieldMultiTSWithoutSDA(fid,fieldName,fieldTyp,infos,nbOfStep,dtunit,loadAll,ms,entities) -{ -} -catch(INTERP_KERNEL::Exception& e) -{ throw e; } - -/*! - * \param [in] fieldId field id in C mode - */ -MEDFileIntFieldMultiTSWithoutSDA::MEDFileIntFieldMultiTSWithoutSDA(med_idt fid, int fieldId, bool loadAll, const MEDFileMeshes *ms, const std::vector< std::pair > *entities) -try:MEDFileAnyTypeFieldMultiTSWithoutSDA(fid,fieldId,loadAll,ms,entities) -{ -} -catch(INTERP_KERNEL::Exception& e) -{ throw e; } - -MEDFileAnyTypeField1TSWithoutSDA *MEDFileIntFieldMultiTSWithoutSDA::createNew1TSWithoutSDAEmptyInstance() const -{ - return new MEDFileIntField1TSWithoutSDA; -} - -void MEDFileIntFieldMultiTSWithoutSDA::checkCoherencyOfType(const MEDFileAnyTypeField1TSWithoutSDA *f1ts) const -{ - if(!f1ts) - throw INTERP_KERNEL::Exception("MEDFileIntFieldMultiTSWithoutSDA::checkCoherencyOfType : input field1TS is NULL ! Impossible to check !"); - const MEDFileIntField1TSWithoutSDA *f1tsC=dynamic_cast(f1ts); - if(!f1tsC) - throw INTERP_KERNEL::Exception("MEDFileIntFieldMultiTSWithoutSDA::checkCoherencyOfType : the input field1TS is not a INT32 type !"); -} - -const char *MEDFileIntFieldMultiTSWithoutSDA::getTypeStr() const -{ - return MEDFileIntField1TSWithoutSDA::TYPE_STR; -} - -MEDFileAnyTypeFieldMultiTSWithoutSDA *MEDFileIntFieldMultiTSWithoutSDA::shallowCpy() const -{ - return new MEDFileIntFieldMultiTSWithoutSDA(*this); -} - -MEDFileAnyTypeFieldMultiTSWithoutSDA *MEDFileIntFieldMultiTSWithoutSDA::createNew() const -{ - return new MEDFileIntFieldMultiTSWithoutSDA; -} - -MEDFileFieldMultiTSWithoutSDA *MEDFileIntFieldMultiTSWithoutSDA::convertToDouble() const -{ - MEDCouplingAutoRefCountObjectPtr ret(new MEDFileFieldMultiTSWithoutSDA); - ret->MEDFileAnyTypeFieldMultiTSWithoutSDA::operator =(*this); - int i=0; - for(std::vector< MEDCouplingAutoRefCountObjectPtr >::const_iterator it=_time_steps.begin();it!=_time_steps.end();it++,i++) - { - const MEDFileAnyTypeField1TSWithoutSDA *eltToConv(*it); - if(eltToConv) - { - const MEDFileIntField1TSWithoutSDA *eltToConvC=dynamic_cast(eltToConv); - if(!eltToConvC) - throw INTERP_KERNEL::Exception("MEDFileIntFieldMultiTSWithoutSDA::convertToInt : presence of an invalid 1TS type ! Should be of type INT32 !"); - MEDCouplingAutoRefCountObjectPtr elt=eltToConvC->convertToDouble(); - ret->setIteration(i,elt); - } - } - return ret.retn(); -} - -//= MEDFileAnyTypeFieldMultiTS - -/*! - * Returns a new instance of MEDFileFieldMultiTS or MEDFileIntFieldMultiTS holding data of the first field - * that has been read from a specified MED file. - * \param [in] fileName - the name of the MED file to read. - * \return MEDFileFieldMultiTS * - a new instance of MEDFileFieldMultiTS or MEDFileIntFieldMultiTS. The caller - * is to delete this field using decrRef() as it is no more needed. - * \throw If reading the file fails. - */ -MEDFileAnyTypeFieldMultiTS *MEDFileAnyTypeFieldMultiTS::New(const std::string& fileName, bool loadAll) -{ - MEDFileUtilities::CheckFileForRead(fileName); - MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName.c_str(),MED_ACC_RDONLY); - MEDCouplingAutoRefCountObjectPtr c=BuildContentFrom(fid,fileName,loadAll,0); - MEDCouplingAutoRefCountObjectPtr ret=BuildNewInstanceFromContent(c,fileName); - ret->loadGlobals(fid); - return ret.retn(); -} - -/*! - * Returns a new instance of MEDFileFieldMultiTS or MEDFileIntFieldMultiTS holding data of a given field - * that has been read from a specified MED file. - * \param [in] fileName - the name of the MED file to read. - * \param [in] fieldName - the name of the field to read. - * \return MEDFileFieldMultiTS * - a new instance of MEDFileFieldMultiTS or MEDFileIntFieldMultiTS. The caller - * is to delete this field using decrRef() as it is no more needed. - * \throw If reading the file fails. - * \throw If there is no field named \a fieldName in the file. - */ -MEDFileAnyTypeFieldMultiTS *MEDFileAnyTypeFieldMultiTS::New(const std::string& fileName, const std::string& fieldName, bool loadAll) -{ - MEDFileUtilities::CheckFileForRead(fileName); - MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName.c_str(),MED_ACC_RDONLY); - MEDCouplingAutoRefCountObjectPtr c(BuildContentFrom(fid,fileName,fieldName,loadAll,0,0)); - MEDCouplingAutoRefCountObjectPtr ret=BuildNewInstanceFromContent(c,fileName); - ret->loadGlobals(fid); - return ret.retn(); -} - -/*! - * This constructor is a shallow copy constructor. If \a shallowCopyOfContent is true the content of \a other is shallow copied. - * If \a shallowCopyOfContent is false, \a other is taken to be the content of \a this. - * - * \warning this is a shallow copy constructor - */ -MEDFileAnyTypeFieldMultiTS::MEDFileAnyTypeFieldMultiTS(const MEDFileAnyTypeFieldMultiTSWithoutSDA& other, bool shallowCopyOfContent) -{ - if(!shallowCopyOfContent) - { - const MEDFileAnyTypeFieldMultiTSWithoutSDA *otherPtr(&other); - otherPtr->incrRef(); - _content=const_cast(otherPtr); - } - else - { - _content=other.shallowCpy(); - } -} - -MEDFileAnyTypeFieldMultiTSWithoutSDA *MEDFileAnyTypeFieldMultiTS::contentNotNullBase() -{ - MEDFileAnyTypeFieldMultiTSWithoutSDA *ret=_content; - if(!ret) - throw INTERP_KERNEL::Exception("MEDFileAnyTypeFieldMultiTS : content is expected to be not null !"); - return ret; -} - -const MEDFileAnyTypeFieldMultiTSWithoutSDA *MEDFileAnyTypeFieldMultiTS::contentNotNullBase() const -{ - const MEDFileAnyTypeFieldMultiTSWithoutSDA *ret=_content; - if(!ret) - throw INTERP_KERNEL::Exception("MEDFileAnyTypeFieldMultiTS : const content is expected to be not null !"); - return ret; -} - -std::vector MEDFileAnyTypeFieldMultiTS::getPflsReallyUsed() const -{ - return contentNotNullBase()->getPflsReallyUsed2(); -} - -std::vector MEDFileAnyTypeFieldMultiTS::getLocsReallyUsed() const -{ - return contentNotNullBase()->getLocsReallyUsed2(); -} - -std::vector MEDFileAnyTypeFieldMultiTS::getPflsReallyUsedMulti() const -{ - return contentNotNullBase()->getPflsReallyUsedMulti2(); -} - -std::vector MEDFileAnyTypeFieldMultiTS::getLocsReallyUsedMulti() const -{ - return contentNotNullBase()->getLocsReallyUsedMulti2(); -} - -void MEDFileAnyTypeFieldMultiTS::changePflsRefsNamesGen(const std::vector< std::pair, std::string > >& mapOfModif) -{ - contentNotNullBase()->changePflsRefsNamesGen2(mapOfModif); -} - -void MEDFileAnyTypeFieldMultiTS::changeLocsRefsNamesGen(const std::vector< std::pair, std::string > >& mapOfModif) -{ - contentNotNullBase()->changeLocsRefsNamesGen2(mapOfModif); -} - -int MEDFileAnyTypeFieldMultiTS::getNumberOfTS() const -{ - return contentNotNullBase()->getNumberOfTS(); -} - -void MEDFileAnyTypeFieldMultiTS::eraseEmptyTS() -{ - contentNotNullBase()->eraseEmptyTS(); -} - -void MEDFileAnyTypeFieldMultiTS::eraseTimeStepIds(const int *startIds, const int *endIds) -{ - contentNotNullBase()->eraseTimeStepIds(startIds,endIds); -} - -void MEDFileAnyTypeFieldMultiTS::eraseTimeStepIds2(int bg, int end, int step) -{ - contentNotNullBase()->eraseTimeStepIds2(bg,end,step); -} - -MEDFileAnyTypeFieldMultiTS *MEDFileAnyTypeFieldMultiTS::buildSubPart(const int *startIds, const int *endIds) const -{ - MEDCouplingAutoRefCountObjectPtr c=contentNotNullBase()->buildFromTimeStepIds(startIds,endIds); - MEDCouplingAutoRefCountObjectPtr ret=shallowCpy(); - ret->_content=c; - return ret.retn(); -} - -MEDFileAnyTypeFieldMultiTS *MEDFileAnyTypeFieldMultiTS::buildSubPartSlice(int bg, int end, int step) const -{ - MEDCouplingAutoRefCountObjectPtr c=contentNotNullBase()->buildFromTimeStepIds2(bg,end,step); - MEDCouplingAutoRefCountObjectPtr ret=shallowCpy(); - ret->_content=c; - return ret.retn(); -} - -std::vector< std::pair > MEDFileAnyTypeFieldMultiTS::getIterations() const -{ - return contentNotNullBase()->getIterations(); -} - -void MEDFileAnyTypeFieldMultiTS::pushBackTimeSteps(const std::vector& f1ts) -{ - for(std::vector::const_iterator it=f1ts.begin();it!=f1ts.end();it++) - pushBackTimeStep(*it); -} - -void MEDFileAnyTypeFieldMultiTS::pushBackTimeSteps(MEDFileAnyTypeFieldMultiTS *fmts) -{ - if(!fmts) - throw INTERP_KERNEL::Exception("MEDFileAnyTypeFieldMultiTS::pushBackTimeSteps : Input fmts is NULL !"); - int nbOfTS(fmts->getNumberOfTS()); - for(int i=0;i elt(fmts->getTimeStepAtPos(i)); - pushBackTimeStep(elt); - } -} - -void MEDFileAnyTypeFieldMultiTS::pushBackTimeStep(MEDFileAnyTypeField1TS *f1ts) -{ - if(!f1ts) - throw INTERP_KERNEL::Exception("MEDFileAnyTypeFieldMultiTSWithoutSDA::pushBackTimeStep : input pointer is NULL !"); - checkCoherencyOfType(f1ts); - f1ts->incrRef(); - MEDCouplingAutoRefCountObjectPtr f1tsSafe(f1ts); - MEDFileAnyTypeField1TSWithoutSDA *c=f1ts->contentNotNullBase(); - c->incrRef(); - MEDCouplingAutoRefCountObjectPtr cSafe(c); - if(!((MEDFileAnyTypeFieldMultiTSWithoutSDA *)_content)) - throw INTERP_KERNEL::Exception("MEDFileAnyTypeFieldMultiTSWithoutSDA::pushBackTimeStep : no content in this !"); - _content->pushBackTimeStep(cSafe); - appendGlobs(*f1ts,1e-12); -} - -void MEDFileAnyTypeFieldMultiTS::synchronizeNameScope() -{ - contentNotNullBase()->synchronizeNameScope(); -} - -int MEDFileAnyTypeFieldMultiTS::getPosOfTimeStep(int iteration, int order) const -{ - return contentNotNullBase()->getPosOfTimeStep(iteration,order); -} - -int MEDFileAnyTypeFieldMultiTS::getPosGivenTime(double time, double eps) const -{ - return contentNotNullBase()->getPosGivenTime(time,eps); -} - -int MEDFileAnyTypeFieldMultiTS::getNonEmptyLevels(int iteration, int order, const std::string& mname, std::vector& levs) const -{ - return contentNotNullBase()->getNonEmptyLevels(iteration,order,mname,levs); -} - -std::vector< std::vector > MEDFileAnyTypeFieldMultiTS::getTypesOfFieldAvailable() const -{ - return contentNotNullBase()->getTypesOfFieldAvailable(); -} - -std::vector< std::vector< std::pair > > MEDFileAnyTypeFieldMultiTS::getFieldSplitedByType(int iteration, int order, const std::string& mname, std::vector& types, std::vector< std::vector >& typesF, std::vector< std::vector >& pfls, std::vector< std::vector >& locs) const -{ - return contentNotNullBase()->getFieldSplitedByType(iteration,order,mname,types,typesF,pfls,locs); -} - -std::string MEDFileAnyTypeFieldMultiTS::getName() const -{ - return contentNotNullBase()->getName(); -} - -void MEDFileAnyTypeFieldMultiTS::setName(const std::string& name) -{ - contentNotNullBase()->setName(name); -} - -std::string MEDFileAnyTypeFieldMultiTS::getDtUnit() const -{ - return contentNotNullBase()->getDtUnit(); -} - -void MEDFileAnyTypeFieldMultiTS::setDtUnit(const std::string& dtUnit) -{ - contentNotNullBase()->setDtUnit(dtUnit); -} - -void MEDFileAnyTypeFieldMultiTS::simpleRepr(int bkOffset, std::ostream& oss, int fmtsId) const -{ - contentNotNullBase()->simpleRepr(bkOffset,oss,fmtsId); -} - -std::vector< std::pair > MEDFileAnyTypeFieldMultiTS::getTimeSteps(std::vector& ret1) const -{ - return contentNotNullBase()->getTimeSteps(ret1); -} - -std::string MEDFileAnyTypeFieldMultiTS::getMeshName() const -{ - return contentNotNullBase()->getMeshName(); -} - -void MEDFileAnyTypeFieldMultiTS::setMeshName(const std::string& newMeshName) -{ - contentNotNullBase()->setMeshName(newMeshName); -} - -bool MEDFileAnyTypeFieldMultiTS::changeMeshNames(const std::vector< std::pair >& modifTab) -{ - return contentNotNullBase()->changeMeshNames(modifTab); -} - -const std::vector& MEDFileAnyTypeFieldMultiTS::getInfo() const -{ - return contentNotNullBase()->getInfo(); -} - -bool MEDFileAnyTypeFieldMultiTS::presenceOfMultiDiscPerGeoType() const -{ - return contentNotNullBase()->presenceOfMultiDiscPerGeoType(); -} - -void MEDFileAnyTypeFieldMultiTS::setInfo(const std::vector& info) -{ - return contentNotNullBase()->setInfo(info); -} - -int MEDFileAnyTypeFieldMultiTS::getNumberOfComponents() const -{ - const std::vector ret=getInfo(); - return (int)ret.size(); -} - -void MEDFileAnyTypeFieldMultiTS::writeLL(med_idt fid) const -{ - writeGlobals(fid,*this); - contentNotNullBase()->writeLL(fid,*this); -} - -/*! - * Writes \a this field into a MED file specified by its name. - * \param [in] fileName - the MED file name. - * \param [in] mode - the writing mode. For more on \a mode, see \ref AdvMEDLoaderBasics. - * - 2 - erase; an existing file is removed. - * - 1 - append; same data should not be present in an existing file. - * - 0 - overwrite; same data present in an existing file is overwritten. - * \throw If the field name is not set. - * \throw If no field data is set. - * \throw If \a mode == 1 and the same data is present in an existing file. - */ -void MEDFileAnyTypeFieldMultiTS::write(const std::string& fileName, int mode) const -{ - med_access_mode medmod=MEDFileUtilities::TraduceWriteMode(mode); - MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName.c_str(),medmod); - writeLL(fid); -} - -/*! - * This method alloc the arrays and load potentially huge arrays contained in this field. - * This method should be called when a MEDFileAnyTypeFieldMultiTS::New constructor has been with false as the last parameter. - * This method can be also called to refresh or reinit values from a file. - * - * \throw If the fileName is not set or points to a non readable MED file. - */ -void MEDFileAnyTypeFieldMultiTS::loadArrays() -{ - if(getFileName().empty()) - throw INTERP_KERNEL::Exception("MEDFileAnyTypeFieldMultiTS::loadArrays : the structure does not come from a file !"); - MEDFileUtilities::AutoFid fid=MEDfileOpen(getFileName().c_str(),MED_ACC_RDONLY); - contentNotNullBase()->loadBigArraysRecursively(fid,*contentNotNullBase()); -} - -/*! - * This method behaves as MEDFileAnyTypeFieldMultiTS::loadArrays does, the first call, if \a this was built using a file without loading big arrays. - * But once data loaded once, this method does nothing. - * - * \throw If the fileName is not set or points to a non readable MED file. - * \sa MEDFileAnyTypeFieldMultiTS::loadArrays, MEDFileAnyTypeFieldMultiTS::unloadArrays - */ -void MEDFileAnyTypeFieldMultiTS::loadArraysIfNecessary() -{ - if(!getFileName().empty()) - { - MEDFileUtilities::AutoFid fid=MEDfileOpen(getFileName().c_str(),MED_ACC_RDONLY); - contentNotNullBase()->loadBigArraysRecursivelyIfNecessary(fid,*contentNotNullBase()); - } -} - -/*! - * This method releases potentially big data arrays and so returns to the same heap memory than status loaded with 'loadAll' parameter set to false. - * \b WARNING, this method does release arrays even if \a this does not come from a load of a MED file. - * So this method can lead to a loss of data. If you want to unload arrays safely call MEDFileAnyTypeFieldMultiTS::unloadArraysWithoutDataLoss instead. - * - * \sa MEDFileAnyTypeFieldMultiTS::loadArrays, MEDFileAnyTypeFieldMultiTS::loadArraysIfNecessary, MEDFileAnyTypeFieldMultiTS::unloadArraysWithoutDataLoss - */ -void MEDFileAnyTypeFieldMultiTS::unloadArrays() -{ - contentNotNullBase()->unloadArrays(); -} - -/*! - * This method potentially releases big data arrays if \a this is coming from a file. If \a this has been built from scratch this method will have no effect. - * This method is the symetrical method of MEDFileAnyTypeFieldMultiTS::loadArraysIfNecessary. - * This method is useful to reduce \b safely amount of heap memory necessary for \a this by using MED file as database. - * - * \sa MEDFileAnyTypeFieldMultiTS::loadArraysIfNecessary - */ -void MEDFileAnyTypeFieldMultiTS::unloadArraysWithoutDataLoss() -{ - if(!getFileName().empty()) - contentNotNullBase()->unloadArrays(); -} - -std::string MEDFileAnyTypeFieldMultiTS::simpleRepr() const -{ - std::ostringstream oss; - contentNotNullBase()->simpleRepr(0,oss,-1); - simpleReprGlobs(oss); - return oss.str(); -} - -std::size_t MEDFileAnyTypeFieldMultiTS::getHeapMemorySizeWithoutChildren() const -{ - return MEDFileFieldGlobsReal::getHeapMemorySizeWithoutChildren(); -} - -std::vector MEDFileAnyTypeFieldMultiTS::getDirectChildrenWithNull() const -{ - std::vector ret(MEDFileFieldGlobsReal::getDirectChildrenWithNull()); - ret.push_back((const MEDFileAnyTypeFieldMultiTSWithoutSDA *)_content); - return ret; -} - -/*! - * This method returns as MEDFileAnyTypeFieldMultiTS new instances as number of components in \a this. - * The returned instances are deep copy of \a this except that for globals that are share with those contained in \a this. - * ** WARNING ** do no forget to rename the ouput instances to avoid to write n-times in the same MED file field ! - */ -std::vector< MEDCouplingAutoRefCountObjectPtr< MEDFileAnyTypeFieldMultiTS > > MEDFileAnyTypeFieldMultiTS::splitComponents() const -{ - const MEDFileAnyTypeFieldMultiTSWithoutSDA *content(_content); - if(!content) - throw INTERP_KERNEL::Exception("MEDFileAnyTypeFieldMultiTS::splitComponents : no content in this ! Unable to split components !"); - std::vector< MEDCouplingAutoRefCountObjectPtr > contentsSplit=content->splitComponents(); - std::size_t sz(contentsSplit.size()); - std::vector< MEDCouplingAutoRefCountObjectPtr< MEDFileAnyTypeFieldMultiTS > > ret(sz); - for(std::size_t i=0;i_content=contentsSplit[i]; - } - return ret; -} - -/*! - * This method returns as MEDFileAnyTypeFieldMultiTS new instances as number of discretizations over time steps in \a this. - * The returned instances are shallow copied of \a this included globals that are share with those contained in \a this. - */ -std::vector< MEDCouplingAutoRefCountObjectPtr< MEDFileAnyTypeFieldMultiTS > > MEDFileAnyTypeFieldMultiTS::splitDiscretizations() const -{ - const MEDFileAnyTypeFieldMultiTSWithoutSDA *content(_content); - if(!content) - throw INTERP_KERNEL::Exception("MEDFileAnyTypeFieldMultiTS::splitDiscretizations : no content in this ! Unable to split discretizations !"); - std::vector< MEDCouplingAutoRefCountObjectPtr > contentsSplit(content->splitDiscretizations()); - std::size_t sz(contentsSplit.size()); - std::vector< MEDCouplingAutoRefCountObjectPtr< MEDFileAnyTypeFieldMultiTS > > ret(sz); - for(std::size_t i=0;i_content=contentsSplit[i]; - } - return ret; -} - -/*! - * This method returns as MEDFileAnyTypeFieldMultiTS new instances as number of sub-discretizations over time steps in \a this. - * The returned instances are shallow copied of \a this included globals that are share with those contained in \a this. - */ -std::vector< MEDCouplingAutoRefCountObjectPtr< MEDFileAnyTypeFieldMultiTS > > MEDFileAnyTypeFieldMultiTS::splitMultiDiscrPerGeoTypes() const -{ - const MEDFileAnyTypeFieldMultiTSWithoutSDA *content(_content); - if(!content) - throw INTERP_KERNEL::Exception("MEDFileAnyTypeFieldMultiTS::splitMultiDiscrPerGeoTypes : no content in this ! Unable to split discretizations !"); - std::vector< MEDCouplingAutoRefCountObjectPtr > contentsSplit(content->splitMultiDiscrPerGeoTypes()); - std::size_t sz(contentsSplit.size()); - std::vector< MEDCouplingAutoRefCountObjectPtr< MEDFileAnyTypeFieldMultiTS > > ret(sz); - for(std::size_t i=0;i_content=contentsSplit[i]; - } - return ret; -} - -MEDFileAnyTypeFieldMultiTS *MEDFileAnyTypeFieldMultiTS::deepCpy() const -{ - MEDCouplingAutoRefCountObjectPtr ret=shallowCpy(); - if((const MEDFileAnyTypeFieldMultiTSWithoutSDA *)_content) - ret->_content=_content->deepCpy(); - ret->deepCpyGlobs(*this); - return ret.retn(); -} - -MEDCouplingAutoRefCountObjectPtr MEDFileAnyTypeFieldMultiTS::getContent() -{ - return _content; -} - -/*! - * Returns a new MEDFileField1TS or MEDFileIntField1TS holding data of a given time step of \a this field. - * \param [in] iteration - the iteration number of a required time step. - * \param [in] order - the iteration order number of required time step. - * \return MEDFileField1TS * or MEDFileIntField1TS *- a new instance of MEDFileField1TS or MEDFileIntField1TS. The caller is to - * delete this field using decrRef() as it is no more needed. - * \throw If there is no required time step in \a this field. - */ -MEDFileAnyTypeField1TS *MEDFileAnyTypeFieldMultiTS::getTimeStep(int iteration, int order) const -{ - int pos=getPosOfTimeStep(iteration,order); - return getTimeStepAtPos(pos); -} - -/*! - * Returns a new MEDFileField1TS or MEDFileIntField1TS holding data of a given time step of \a this field. - * \param [in] time - the time of the time step of interest. - * \param [in] eps - a precision used to compare time values. - * \return MEDFileField1TS * - a new instance of MEDFileField1TS. The caller is to - * delete this field using decrRef() as it is no more needed. - * \throw If there is no required time step in \a this field. - */ -MEDFileAnyTypeField1TS *MEDFileAnyTypeFieldMultiTS::getTimeStepGivenTime(double time, double eps) const -{ - int pos=getPosGivenTime(time,eps); - return getTimeStepAtPos(pos); -} - -/*! - * This method groups not null items in \a vectFMTS per time step series. Two time series are considered equal if the list of their pair of integers iteration,order are equal. - * The float64 value of time attached to the pair of integers are not considered here. - * WARNING the returned pointers are not incremented. The caller is \b not responsible to deallocate them ! This method only reorganizes entries in \a vectFMTS. - * - * \param [in] vectFMTS - vector of not null fields defined on a same global data pointer. - * \throw If there is a null pointer in \a vectFMTS. - */ -std::vector< std::vector > MEDFileAnyTypeFieldMultiTS::SplitIntoCommonTimeSeries(const std::vector& vectFMTS) -{ - static const char msg[]="MEDFileAnyTypeFieldMultiTS::SplitIntoCommonTimeSeries : presence of null instance in input vector !"; - std::vector< std::vector > ret; - std::list lstFMTS(vectFMTS.begin(),vectFMTS.end()); - while(!lstFMTS.empty()) - { - std::list::iterator it(lstFMTS.begin()); - MEDFileAnyTypeFieldMultiTS *curIt(*it); - if(!curIt) - throw INTERP_KERNEL::Exception(msg); - std::vector< std::pair > refIts=curIt->getIterations(); - std::vector elt; - elt.push_back(curIt); it=lstFMTS.erase(it); - while(it!=lstFMTS.end()) - { - curIt=*it; - if(!curIt) - throw INTERP_KERNEL::Exception(msg); - std::vector< std::pair > curIts=curIt->getIterations(); - if(refIts==curIts) - { elt.push_back(curIt); it=lstFMTS.erase(it); } - else - it++; - } - ret.push_back(elt); - } - return ret; -} - -/*! - * This method splits the input list \a vectFMTS considering the aspect of the geometrical support over time. - * All returned instances in a subvector can be safely loaded, rendered along time - * All items must be defined on the same time step ids ( see MEDFileAnyTypeFieldMultiTS::SplitIntoCommonTimeSeries method ). - * Each item in \a vectFMTS is expected to have one and exactly one spatial discretization along time. - * All items in \a vectFMTS must lie on the mesh (located by meshname and time step) and compatible with the input mesh \a mesh (having the same name than those in items). - * All items in \a vectFMTS whose spatial discretization is not ON_NODES will appear once. - * For items in \a vectFMTS that are ON_NODES it is possible to appear several times (more than once or once) in the returned vector. - * - * \param [in] vectFMTS - list of multi times step part all defined each on a same spatial discretization along time and pointing to a mesh whose name is equal to \c mesh->getName(). - * \param [in] mesh - the mesh shared by all items in \a vectFMTS across time. - * \param [out] fsc - A vector having same size than returned vector. It specifies the support comporator of the corresponding vector of MEDFileAnyTypeFieldMultiTS in returned vector of vector. - * \return - A vector of vector of objects that contains the same pointers (objects) than thoose in \a vectFMTS except that there are organized differently. So pointers included in returned vector of vector should \b not been dealt by the caller. - * - * \throw If an element in \a vectFMTS has not only one spatial discretization set. - * \throw If an element in \a vectFMTS change of spatial discretization along time. - * \throw If an element in \a vectFMTS lies on a mesh with meshname different from those in \a mesh. - * \thorw If some elements in \a vectFMTS do not have the same times steps. - * \throw If mesh is null. - * \throw If an element in \a vectFMTS is null. - * \sa MEDFileAnyTypeFieldMultiTS::AreOnSameSupportAcrossTime - */ -std::vector< std::vector > MEDFileAnyTypeFieldMultiTS::SplitPerCommonSupport(const std::vector& vectFMTS, const MEDFileMesh *mesh, std::vector< MEDCouplingAutoRefCountObjectPtr >& fsc) -{ - static const char msg[]="MEDFileAnyTypeFieldMultiTS::SplitPerCommonSupport : presence of a null instance in the input vector !"; - if(!mesh) - throw INTERP_KERNEL::Exception("MEDFileAnyTypeFieldMultiTS::SplitPerCommonSupport : input mesh is null !"); - std::vector< std::vector > ret; - if(vectFMTS.empty()) - return ret; - std::vector::const_iterator it(vectFMTS.begin()); - MEDFileAnyTypeFieldMultiTS *frstElt(*it); - if(!frstElt) - throw INTERP_KERNEL::Exception(msg); - std::size_t i=0; - std::vector vectFMTSNotNodes; - std::vector vectFMTSNodes; - for(;it!=vectFMTS.end();it++,i++) - { - if(!(*it)) - throw INTERP_KERNEL::Exception(msg); - TypeOfField tof0,tof1; - if(CheckSupportAcrossTime(frstElt,*it,mesh,tof0,tof1)>0) - { - if(tof1!=ON_NODES) - vectFMTSNotNodes.push_back(*it); - else - vectFMTSNodes.push_back(*it); - } - else - vectFMTSNotNodes.push_back(*it); - } - std::vector< MEDCouplingAutoRefCountObjectPtr > cmps; - std::vector< std::vector > retCell=SplitPerCommonSupportNotNodesAlg(vectFMTSNotNodes,mesh,cmps); - ret=retCell; - for(std::vector::const_iterator it2=vectFMTSNodes.begin();it2!=vectFMTSNodes.end();it2++) - { - i=0; - bool isFetched(false); - for(std::vector< std::vector >::const_iterator it0=retCell.begin();it0!=retCell.end();it0++,i++) - { - if((*it0).empty()) - throw INTERP_KERNEL::Exception("MEDFileAnyTypeFieldMultiTS::SplitPerCommonSupport : internal error !"); - if(cmps[i]->isCompatibleWithNodesDiscr(*it2)) - { ret[i].push_back(*it2); isFetched=true; } - } - if(!isFetched) - { - std::vector tmp(1,*it2); - MEDCouplingAutoRefCountObjectPtr tmp2(MEDFileMeshStruct::New(mesh)); - ret.push_back(tmp); retCell.push_back(tmp); cmps.push_back(MEDFileFastCellSupportComparator::New(tmp2,*it2)); - } - } - fsc=cmps; - return ret; -} - -/*! - * WARNING no check here. The caller must be sure that all items in vectFMTS are coherent each other in time steps, only one same spatial discretization and not ON_NODES. - * \param [out] cmps - same size than the returned vector. - */ -std::vector< std::vector > MEDFileAnyTypeFieldMultiTS::SplitPerCommonSupportNotNodesAlg(const std::vector& vectFMTS, const MEDFileMesh *mesh, std::vector< MEDCouplingAutoRefCountObjectPtr >& cmps) -{ - std::vector< std::vector > ret; - std::list lstFMTS(vectFMTS.begin(),vectFMTS.end()); - while(!lstFMTS.empty()) - { - std::list::iterator it(lstFMTS.begin()); - MEDFileAnyTypeFieldMultiTS *ref(*it); - std::vector elt; - elt.push_back(ref); it=lstFMTS.erase(it); - MEDCouplingAutoRefCountObjectPtr mst(MEDFileMeshStruct::New(mesh)); - MEDCouplingAutoRefCountObjectPtr cmp(MEDFileFastCellSupportComparator::New(mst,ref)); - while(it!=lstFMTS.end()) - { - MEDFileAnyTypeFieldMultiTS *curIt(*it); - if(cmp->isEqual(curIt)) - { elt.push_back(curIt); it=lstFMTS.erase(it); } - else - it++; - } - ret.push_back(elt); cmps.push_back(cmp); - } - return ret; -} - -/*! - * This method scan the two main structs along time of \a f0 and \a f1 to see if there are all lying on the same mesh along time than those in \a mesh. - * \a f0 and \a f1 must be defined each only on a same spatial discretization even if this can be different each other. - * - * \throw If \a f0 or \a f1 has not only one spatial discretization set. - * \throw If \a f0 or \a f1 change of spatial discretization along time. - * \throw If \a f0 or \a f1 on a mesh with meshname different from those in \a mesh. - * \thorw If \a f0 and \a f1 do not have the same times steps. - * \throw If mesh is null. - * \throw If \a f0 or \a f1 is null. - * \sa MEDFileAnyTypeFieldMultiTS::SplitPerCommonSupport - */ -int MEDFileAnyTypeFieldMultiTS::CheckSupportAcrossTime(MEDFileAnyTypeFieldMultiTS *f0, MEDFileAnyTypeFieldMultiTS *f1, const MEDFileMesh *mesh, TypeOfField& tof0, TypeOfField& tof1) -{ - if(!mesh) - throw INTERP_KERNEL::Exception("MEDFileAnyTypeFieldMultiTS::CheckSupportAcrossTime : input mesh is null !"); - if(!f0 || !f1) - throw INTERP_KERNEL::Exception("MEDFileAnyTypeFieldMultiTS::CheckSupportAcrossTime : presence of null instance in fields over time !"); - if(f0->getMeshName()!=mesh->getName()) - { - std::ostringstream oss; oss << "MEDFileAnyTypeFieldMultiTS::CheckSupportAcrossTime : first field points to mesh \""<< f0->getMeshName() << "\" and input mesh to compare has name \"" << mesh->getName() << "\" !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - if(f1->getMeshName()!=mesh->getName()) - { - std::ostringstream oss; oss << "MEDFileAnyTypeFieldMultiTS::CheckSupportAcrossTime : second field points to mesh \""<< f1->getMeshName() << "\" and input mesh to compare has name \"" << mesh->getName() << "\" !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - int nts=f0->getNumberOfTS(); - if(nts!=f1->getNumberOfTS()) - throw INTERP_KERNEL::Exception("MEDFileAnyTypeFieldMultiTS::CheckSupportAcrossTime : number of time steps are not the same !"); - if(nts==0) - return nts; - for(int i=0;i f0cur=f0->getTimeStepAtPos(i); - MEDCouplingAutoRefCountObjectPtr f1cur=f1->getTimeStepAtPos(i); - std::vector tofs0(f0cur->getTypesOfFieldAvailable()),tofs1(f1cur->getTypesOfFieldAvailable()); - if(tofs0.size()!=1 || tofs1.size()!=1) - throw INTERP_KERNEL::Exception("MEDFileAnyTypeFieldMultiTS::CheckSupportAcrossTime : All time steps must be defined on only one spatial discretization !"); - if(i!=0) - { - if(tof0!=tofs0[0] || tof1!=tofs1[0]) - throw INTERP_KERNEL::Exception("MEDFileAnyTypeFieldMultiTS::CheckSupportAcrossTime : Across times steps MEDFileAnyTypeFieldMultiTS instances have to keep the same unique spatial discretization !"); - } - else - { tof0=tofs0[0]; tof1=tofs1[0]; } - if(f0cur->getMeshIteration()!=mesh->getIteration() || f0cur->getMeshOrder()!=mesh->getOrder()) - { - std::ostringstream oss; oss << "MEDFileAnyTypeFieldMultiTS::CheckSupportAcrossTime : first field points to mesh time step (" << f0cur->getMeshIteration() << ","<< f0cur->getMeshOrder() << ") whereas input mesh points to time step (" << mesh->getIteration() << "," << mesh->getOrder() << ") !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - if(f1cur->getMeshIteration()!=mesh->getIteration() || f1cur->getMeshOrder()!=mesh->getOrder()) - { - std::ostringstream oss; oss << "MEDFileAnyTypeFieldMultiTS::CheckSupportAcrossTime : second field points to mesh time step (" << f1cur->getMeshIteration() << ","<< f1cur->getMeshOrder() << ") whereas input mesh points to time step (" << mesh->getIteration() << "," << mesh->getOrder() << ") !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - if(f0cur->getIteration()!=f1cur->getIteration() || f0cur->getOrder()!=f1cur->getOrder()) - { - std::ostringstream oss; oss << "MEDFileAnyTypeFieldMultiTS::CheckSupportAcrossTime : all the time steps must be the same ! it is not the case (" << f0cur->getIteration() << "," << f0cur->getOrder() << ")!=(" << f1cur->getIteration() << "," << f1cur->getOrder() << ") !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - } - return nts; -} - -MEDFileAnyTypeFieldMultiTSIterator *MEDFileAnyTypeFieldMultiTS::iterator() -{ - return new MEDFileAnyTypeFieldMultiTSIterator(this); -} - -//= MEDFileFieldMultiTS - -/*! - * Returns a new empty instance of MEDFileFieldMultiTS. - * \return MEDFileFieldMultiTS * - a new instance of MEDFileFieldMultiTS. The caller - * is to delete this field using decrRef() as it is no more needed. - */ -MEDFileFieldMultiTS *MEDFileFieldMultiTS::New() -{ - return new MEDFileFieldMultiTS; -} - -/*! - * Returns a new instance of MEDFileFieldMultiTS holding data of the first field - * that has been read from a specified MED file. - * \param [in] fileName - the name of the MED file to read. - * \return MEDFileFieldMultiTS * - a new instance of MEDFileFieldMultiTS. The caller - * is to delete this field using decrRef() as it is no more needed. - * \throw If reading the file fails. - */ -MEDFileFieldMultiTS *MEDFileFieldMultiTS::New(const std::string& fileName, bool loadAll) -{ - MEDCouplingAutoRefCountObjectPtr ret=new MEDFileFieldMultiTS(fileName,loadAll,0); - ret->contentNotNull();//to check that content type matches with \a this type. - return ret.retn(); -} - -/*! - * Returns a new instance of MEDFileFieldMultiTS holding data of a given field - * that has been read from a specified MED file. - * \param [in] fileName - the name of the MED file to read. - * \param [in] fieldName - the name of the field to read. - * \return MEDFileFieldMultiTS * - a new instance of MEDFileFieldMultiTS. The caller - * is to delete this field using decrRef() as it is no more needed. - * \throw If reading the file fails. - * \throw If there is no field named \a fieldName in the file. - */ -MEDFileFieldMultiTS *MEDFileFieldMultiTS::New(const std::string& fileName, const std::string& fieldName, bool loadAll) -{ - MEDCouplingAutoRefCountObjectPtr ret=new MEDFileFieldMultiTS(fileName,fieldName,loadAll,0); - ret->contentNotNull();//to check that content type matches with \a this type. - return ret.retn(); -} - -/*! - * Returns a new instance of MEDFileFieldMultiTS. If \a shallowCopyOfContent is true the content of \a other is shallow copied. - * If \a shallowCopyOfContent is false, \a other is taken to be the content of \a this. - * - * Returns a new instance of MEDFileFieldMultiTS holding either a shallow copy - * of a given MEDFileFieldMultiTSWithoutSDA ( \a other ) or \a other itself. - * \warning this is a shallow copy constructor - * \param [in] other - a MEDFileField1TSWithoutSDA to copy. - * \param [in] shallowCopyOfContent - if \c true, a shallow copy of \a other is created. - * \return MEDFileFieldMultiTS * - a new instance of MEDFileFieldMultiTS. The caller - * is to delete this field using decrRef() as it is no more needed. - */ -MEDFileFieldMultiTS *MEDFileFieldMultiTS::New(const MEDFileFieldMultiTSWithoutSDA& other, bool shallowCopyOfContent) -{ - return new MEDFileFieldMultiTS(other,shallowCopyOfContent); -} - -MEDFileFieldMultiTS *MEDFileFieldMultiTS::LoadSpecificEntities(const std::string& fileName, const std::string& fieldName, const std::vector< std::pair >& entities, bool loadAll) -{ - MEDCouplingAutoRefCountObjectPtr ret(new MEDFileFieldMultiTS(fileName,fieldName,loadAll,0,&entities)); - ret->contentNotNull();//to check that content type matches with \a this type. - return ret.retn(); -} - -MEDFileAnyTypeFieldMultiTS *MEDFileFieldMultiTS::shallowCpy() const -{ - return new MEDFileFieldMultiTS(*this); -} - -void MEDFileFieldMultiTS::checkCoherencyOfType(const MEDFileAnyTypeField1TS *f1ts) const -{ - if(!f1ts) - throw INTERP_KERNEL::Exception("MEDFileFieldMultiTS::checkCoherencyOfType : input field1TS is NULL ! Impossible to check !"); - const MEDFileField1TS *f1tsC=dynamic_cast(f1ts); - if(!f1tsC) - throw INTERP_KERNEL::Exception("MEDFileFieldMultiTS::checkCoherencyOfType : the input field1TS is not a FLOAT64 type !"); -} - -/*! - * This method performs a copy with datatype modification ( float64->int32 ) of \a this. The globals information are copied - * following the given input policy. - * - * \param [in] isDeepCpyGlobs - a boolean that indicates the behaviour concerning globals (profiles and localizations) - * By default (true) the globals are deeply copied. - * \return MEDFileIntFieldMultiTS * - a new object that is the result of the conversion of \a this to int32 field. - */ -MEDFileIntFieldMultiTS *MEDFileFieldMultiTS::convertToInt(bool isDeepCpyGlobs) const -{ - MEDCouplingAutoRefCountObjectPtr ret; - const MEDFileAnyTypeFieldMultiTSWithoutSDA *content(_content); - if(content) - { - const MEDFileFieldMultiTSWithoutSDA *contc=dynamic_cast(content); - if(!contc) - throw INTERP_KERNEL::Exception("MEDFileFieldMultiTS::convertToInt : the content inside this is not FLOAT64 ! This is incoherent !"); - MEDCouplingAutoRefCountObjectPtr newc(contc->convertToInt()); - ret=static_cast(MEDFileAnyTypeFieldMultiTS::BuildNewInstanceFromContent((MEDFileIntFieldMultiTSWithoutSDA *)newc,getFileName())); - } - else - ret=MEDFileIntFieldMultiTS::New(); - if(isDeepCpyGlobs) - ret->deepCpyGlobs(*this); - else - ret->shallowCpyGlobs(*this); - return ret.retn(); -} - -/*! - * Returns a new MEDFileField1TS holding data of a given time step of \a this field. - * \param [in] pos - a time step id. - * \return MEDFileField1TS * - a new instance of MEDFileField1TS. The caller is to - * delete this field using decrRef() as it is no more needed. - * \throw If \a pos is not a valid time step id. - */ -MEDFileAnyTypeField1TS *MEDFileFieldMultiTS::getTimeStepAtPos(int pos) const -{ - const MEDFileAnyTypeField1TSWithoutSDA *item=contentNotNullBase()->getTimeStepAtPos2(pos); - if(!item) - { - std::ostringstream oss; oss << "MEDFileFieldMultiTS::getTimeStepAtPos : field at pos #" << pos << " is null !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - const MEDFileField1TSWithoutSDA *itemC=dynamic_cast(item); - if(itemC) - { - MEDCouplingAutoRefCountObjectPtr ret=MEDFileField1TS::New(*itemC,false); - ret->shallowCpyGlobs(*this); - return ret.retn(); - } - std::ostringstream oss; oss << "MEDFileFieldMultiTS::getTimeStepAtPos : type of field at pos #" << pos << " is not FLOAT64 !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); -} - -/*! - * Returns a new MEDCouplingFieldDouble of a given type, of a given time step, lying on - * mesh entities of a given dimension of the first mesh in MED file. - * For more info, see \ref AdvMEDLoaderAPIFieldRW - * \param [in] type - a spatial discretization of interest. - * \param [in] iteration - the iteration number of a required time step. - * \param [in] order - the iteration order number of required time step. - * \param [in] meshDimRelToMax - a relative dimension of the supporting mesh entities. - * \param [in] renumPol - specifies how to permute values of the result field according to - * the optional numbers of cells and nodes, if any. The valid values are - * - 0 - do not permute. - * - 1 - permute cells. - * - 2 - permute nodes. - * - 3 - permute cells and nodes. - * - * \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 MED file is not readable. - * \throw If there is no mesh in the MED file. - * \throw If there are no mesh entities of \a meshDimRelToMax dimension in the mesh. - * \throw If no field values of the required parameters are available. - */ -MEDCouplingFieldDouble *MEDFileFieldMultiTS::getFieldAtLevel(TypeOfField type, int iteration, int order, int meshDimRelToMax, int renumPol) const -{ - const MEDFileAnyTypeField1TSWithoutSDA& myF1TS=contentNotNullBase()->getTimeStepEntry(iteration,order); - const MEDFileField1TSWithoutSDA *myF1TSC=dynamic_cast(&myF1TS); - if(!myF1TSC) - throw INTERP_KERNEL::Exception("MEDFileFieldMultiTS::getFieldAtLevel : mismatch of type of field expecting FLOAT64 !"); - MEDCouplingAutoRefCountObjectPtr arrOut; - MEDCouplingAutoRefCountObjectPtr ret=myF1TSC->getFieldAtLevel(type,meshDimRelToMax,std::string(),renumPol,this,arrOut,*contentNotNullBase()); - MEDFileField1TS::SetDataArrayDoubleInField(ret,arrOut); - return ret.retn(); -} - -/*! - * Returns a new MEDCouplingFieldDouble of a given type, of a given time step, lying on - * the top level cells of the first mesh in MED file. - * For more info, see \ref AdvMEDLoaderAPIFieldRW - * \param [in] type - a spatial discretization of interest. - * \param [in] iteration - the iteration number of a required time step. - * \param [in] order - the iteration order number of required time step. - * \param [in] renumPol - specifies how to permute values of the result field according to - * the optional numbers of cells and nodes, if any. The valid values are - * - 0 - do not permute. - * - 1 - permute cells. - * - 2 - permute nodes. - * - 3 - permute cells and nodes. - * - * \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 MED file is not readable. - * \throw If there is no mesh in the MED file. - * \throw If no field values of the required parameters are available. - */ -MEDCouplingFieldDouble *MEDFileFieldMultiTS::getFieldAtTopLevel(TypeOfField type, int iteration, int order, int renumPol) const -{ - const MEDFileAnyTypeField1TSWithoutSDA& myF1TS=contentNotNullBase()->getTimeStepEntry(iteration,order); - const MEDFileField1TSWithoutSDA *myF1TSC=dynamic_cast(&myF1TS); - if(!myF1TSC) - throw INTERP_KERNEL::Exception("MEDFileFieldMultiTS::getFieldAtTopLevel : mismatch of type of field !"); - MEDCouplingAutoRefCountObjectPtr arrOut; - MEDCouplingAutoRefCountObjectPtr ret=myF1TSC->getFieldAtTopLevel(type,std::string(),renumPol,this,arrOut,*contentNotNullBase()); - MEDFileField1TS::SetDataArrayDoubleInField(ret,arrOut); - return ret.retn(); -} - -/*! - * Returns a new MEDCouplingFieldDouble of a given type, of a given time step, lying on - * a given support. - * For more info, see \ref AdvMEDLoaderAPIFieldRW - * \param [in] type - a spatial discretization of interest. - * \param [in] iteration - the iteration number of a required time step. - * \param [in] order - the iteration order number of required time step. - * \param [in] meshDimRelToMax - a relative dimension of the supporting mesh entities. - * \param [in] mesh - the supporting mesh. - * \param [in] renumPol - specifies how to permute values of the result field according to - * the optional numbers of cells and nodes, if any. The valid values are - * - 0 - do not permute. - * - 1 - permute cells. - * - 2 - permute nodes. - * - 3 - permute cells and nodes. - * - * \return MEDCouplingFieldDouble * - a new instance of MEDCouplingFieldDouble. The - * caller is to delete this field using decrRef() as it is no more needed. - * \throw If there are no mesh entities of \a meshDimRelToMax dimension in the mesh. - * \throw If no field of \a this is lying on \a mesh. - * \throw If no field values of the required parameters are available. - */ -MEDCouplingFieldDouble *MEDFileFieldMultiTS::getFieldOnMeshAtLevel(TypeOfField type, int iteration, int order, int meshDimRelToMax, const MEDFileMesh *mesh, int renumPol) const -{ - const MEDFileAnyTypeField1TSWithoutSDA& myF1TS=contentNotNullBase()->getTimeStepEntry(iteration,order); - const MEDFileField1TSWithoutSDA *myF1TSC=dynamic_cast(&myF1TS); - if(!myF1TSC) - throw INTERP_KERNEL::Exception("MEDFileFieldMultiTS::getFieldOnMeshAtLevel : mismatch of type of field !"); - MEDCouplingAutoRefCountObjectPtr arrOut; - MEDCouplingAutoRefCountObjectPtr ret=myF1TSC->getFieldOnMeshAtLevel(type,meshDimRelToMax,renumPol,this,mesh,arrOut,*contentNotNullBase()); - MEDFileField1TS::SetDataArrayDoubleInField(ret,arrOut); - return ret.retn(); -} - -/*! - * Returns a new MEDCouplingFieldDouble of given type, of a given time step, lying on a - * given support. - * For more info, see \ref AdvMEDLoaderAPIFieldRW - * \param [in] type - a spatial discretization of the new field. - * \param [in] iteration - the iteration number of a required time step. - * \param [in] order - the iteration order number of required time step. - * \param [in] mesh - the supporting mesh. - * \param [in] renumPol - specifies how to permute values of the result field according to - * the optional numbers of cells and nodes, if any. The valid values are - * - 0 - do not permute. - * - 1 - permute cells. - * - 2 - permute nodes. - * - 3 - permute cells and nodes. - * - * \return MEDCouplingFieldDouble * - a new instance of MEDCouplingFieldDouble. The - * caller is to delete this field using decrRef() as it is no more needed. - * \throw If no field of \a this is lying on \a mesh. - * \throw If no field values of the required parameters are available. - */ -MEDCouplingFieldDouble *MEDFileFieldMultiTS::getFieldOnMeshAtLevel(TypeOfField type, int iteration, int order, const MEDCouplingMesh *mesh, int renumPol) const -{ - const MEDFileAnyTypeField1TSWithoutSDA& myF1TS=contentNotNullBase()->getTimeStepEntry(iteration,order); - const MEDFileField1TSWithoutSDA *myF1TSC=dynamic_cast(&myF1TS); - if(!myF1TSC) - throw INTERP_KERNEL::Exception("MEDFileFieldMultiTS::getFieldOnMeshAtLevel : mismatch of type of field !"); - MEDCouplingAutoRefCountObjectPtr arrOut; - MEDCouplingAutoRefCountObjectPtr ret=myF1TSC->getFieldOnMeshAtLevel(type,renumPol,this,mesh,0,0,arrOut,*contentNotNullBase()); - MEDFileField1TS::SetDataArrayDoubleInField(ret,arrOut); - return ret.retn(); -} - -/*! - * This method has a close behaviour than MEDFileFieldMultiTS::getFieldAtLevel. - * This method is called 'old' because the user should give the mesh name he wants to use for it's field. - * This method is useful for MED2 file format when field on different mesh was autorized. - */ -MEDCouplingFieldDouble *MEDFileFieldMultiTS::getFieldAtLevelOld(TypeOfField type, const std::string& mname, int iteration, int order, int meshDimRelToMax, int renumPol) const -{ - const MEDFileAnyTypeField1TSWithoutSDA& myF1TS=contentNotNullBase()->getTimeStepEntry(iteration,order); - const MEDFileField1TSWithoutSDA *myF1TSC=dynamic_cast(&myF1TS); - if(!myF1TSC) - throw INTERP_KERNEL::Exception("MEDFileFieldMultiTS::getFieldAtLevelOld : mismatch of type of field !"); - MEDCouplingAutoRefCountObjectPtr arrOut; - MEDCouplingAutoRefCountObjectPtr ret=myF1TSC->getFieldAtLevel(type,meshDimRelToMax,mname,renumPol,this,arrOut,*contentNotNullBase()); - MEDFileField1TS::SetDataArrayDoubleInField(ret,arrOut); - return ret.retn(); -} - -/*! - * Returns values and a profile of the field of a given type, of a given time step, - * lying on a given support. - * For more info, see \ref AdvMEDLoaderAPIFieldRW - * \param [in] type - a spatial discretization of the field. - * \param [in] iteration - the iteration number of a required time step. - * \param [in] order - the iteration order number of required time step. - * \param [in] meshDimRelToMax - a relative dimension of the supporting mesh entities. - * \param [in] mesh - the supporting mesh. - * \param [out] pfl - a new instance of DataArrayInt holding ids of mesh entities the - * field of interest lies on. If the field lies on all entities of the given - * dimension, all ids in \a pfl are zero. The caller is to delete this array - * using decrRef() as it is no more needed. - * \param [in] glob - the global data storing profiles and localization. - * \return DataArrayDouble * - a new instance of DataArrayDouble holding values of the - * field. The caller is to delete this array using decrRef() as it is no more needed. - * \throw If there are no mesh entities of \a meshDimRelToMax dimension in \a mesh. - * \throw If no field of \a this is lying on \a mesh. - * \throw If no field values of the required parameters are available. - */ -DataArrayDouble *MEDFileFieldMultiTS::getFieldWithProfile(TypeOfField type, int iteration, int order, int meshDimRelToMax, const MEDFileMesh *mesh, DataArrayInt *&pfl) const -{ - const MEDFileAnyTypeField1TSWithoutSDA& myF1TS=contentNotNullBase()->getTimeStepEntry(iteration,order); - const MEDFileField1TSWithoutSDA *myF1TSC=dynamic_cast(&myF1TS); - if(!myF1TSC) - throw INTERP_KERNEL::Exception("MEDFileFieldMultiTS::getFieldWithProfile : mismatch of type of field !"); - MEDCouplingAutoRefCountObjectPtr ret=myF1TSC->getFieldWithProfile(type,meshDimRelToMax,mesh,pfl,this,*contentNotNullBase()); - return MEDFileField1TS::ReturnSafelyDataArrayDouble(ret); -} - -const MEDFileFieldMultiTSWithoutSDA *MEDFileFieldMultiTS::contentNotNull() const -{ - const MEDFileAnyTypeFieldMultiTSWithoutSDA *pt(_content); - if(!pt) - throw INTERP_KERNEL::Exception("MEDFileFieldMultiTS::contentNotNull : the content pointer is null !"); - const MEDFileFieldMultiTSWithoutSDA *ret=dynamic_cast(pt); - if(!ret) - throw INTERP_KERNEL::Exception("MEDFileFieldMultiTS::contentNotNull : the content pointer is not null but it is not of type double ! Reason is maybe that the read field has not the type FLOAT64 !"); - return ret; -} - -MEDFileFieldMultiTSWithoutSDA *MEDFileFieldMultiTS::contentNotNull() -{ - MEDFileAnyTypeFieldMultiTSWithoutSDA *pt(_content); - if(!pt) - throw INTERP_KERNEL::Exception("MEDFileFieldMultiTS::contentNotNull : the non const content pointer is null !"); - MEDFileFieldMultiTSWithoutSDA *ret=dynamic_cast(pt); - if(!ret) - throw INTERP_KERNEL::Exception("MEDFileFieldMultiTS::contentNotNull : the non const content pointer is not null but it is not of type double ! Reason is maybe that the read field has not the type FLOAT64 !"); - return ret; -} - -/*! - * Adds a MEDCouplingFieldDouble to \a this as another time step. The underlying mesh of - * the given field is checked if its elements are sorted suitable for writing to MED file - * ("STB" stands for "Sort By Type"), if not, an exception is thrown. - * For more info, see \ref AdvMEDLoaderAPIFieldRW - * \param [in] field - the field to add to \a this. - * \throw If the name of \a field is empty. - * \throw If the data array of \a field is not set. - * \throw If existing time steps have different name or number of components than \a field. - * \throw If the underlying mesh of \a field has no name. - * \throw If elements in the mesh are not in the order suitable for writing to the MED file. - */ -void MEDFileFieldMultiTS::appendFieldNoProfileSBT(const MEDCouplingFieldDouble *field) -{ - const DataArrayDouble *arr=0; - if(field) - arr=field->getArray(); - contentNotNull()->appendFieldNoProfileSBT(field,arr,*this); -} - -/*! - * Adds a MEDCouplingFieldDouble to \a this as another time step. - * The mesh support of input parameter \a field is ignored here, it can be NULL. - * The support of field \a field is expected to be those computed with the input parameter \a mesh, \a meshDimRelToMax, - * and \a profile. - * - * This method will check that the field based on the computed support is coherent. If not an exception will be thrown. - * A new profile is added only if no equal profile is missing. - * For more info, see \ref AdvMEDLoaderAPIFieldRW - * \param [in] field - the field to add to \a this. The mesh support of field is ignored. - * \param [in] mesh - the supporting mesh of \a field. - * \param [in] meshDimRelToMax - a relative dimension of mesh entities \a field lies on (useless if field spatial discretization is ON_NODES). - * \param [in] profile - ids of mesh entities on which corresponding field values lie. - * \throw If either \a field or \a mesh or \a profile has an empty name. - * \throw If there are no mesh entities of \a meshDimRelToMax dimension in \a mesh. - * \throw If the data array of \a field is not set. - * \throw If the data array of \a this is already allocated but has different number of - * components than \a field. - * \throw If elements in \a mesh are not in the order suitable for writing to the MED file. - * \sa setFieldNoProfileSBT() - */ -void MEDFileFieldMultiTS::appendFieldProfile(const MEDCouplingFieldDouble *field, const MEDFileMesh *mesh, int meshDimRelToMax, const DataArrayInt *profile) -{ - const DataArrayDouble *arr=0; - if(field) - arr=field->getArray(); - contentNotNull()->appendFieldProfile(field,arr,mesh,meshDimRelToMax,profile,*this); -} - -MEDFileFieldMultiTS::MEDFileFieldMultiTS() -{ - _content=new MEDFileFieldMultiTSWithoutSDA; -} - -MEDFileFieldMultiTS::MEDFileFieldMultiTS(const std::string& fileName, bool loadAll, const MEDFileMeshes *ms) -try:MEDFileAnyTypeFieldMultiTS(fileName,loadAll,ms) -{ -} -catch(INTERP_KERNEL::Exception& e) -{ throw e; } - -MEDFileFieldMultiTS::MEDFileFieldMultiTS(const std::string& fileName, const std::string& fieldName, bool loadAll, const MEDFileMeshes *ms, const std::vector< std::pair > *entities) -try:MEDFileAnyTypeFieldMultiTS(fileName,fieldName,loadAll,ms,entities) -{ -} -catch(INTERP_KERNEL::Exception& e) -{ throw e; } - -MEDFileFieldMultiTS::MEDFileFieldMultiTS(const MEDFileFieldMultiTSWithoutSDA& other, bool shallowCopyOfContent):MEDFileAnyTypeFieldMultiTS(other,shallowCopyOfContent) -{ -} - -std::vector< std::vector > MEDFileFieldMultiTS::getFieldSplitedByType2(int iteration, int order, const std::string& mname, std::vector& types, std::vector< std::vector >& typesF, std::vector< std::vector >& pfls, std::vector< std::vector >& locs) const -{ - return contentNotNull()->getFieldSplitedByType2(iteration,order,mname,types,typesF,pfls,locs); -} - -DataArrayDouble *MEDFileFieldMultiTS::getUndergroundDataArray(int iteration, int order) const -{ - return static_cast(contentNotNull()->getUndergroundDataArray(iteration,order)); -} - -DataArrayDouble *MEDFileFieldMultiTS::getUndergroundDataArrayExt(int iteration, int order, std::vector< std::pair,std::pair > >& entries) const -{ - return static_cast(contentNotNull()->getUndergroundDataArrayExt(iteration,order,entries)); -} - -//= MEDFileAnyTypeFieldMultiTSIterator - -MEDFileAnyTypeFieldMultiTSIterator::MEDFileAnyTypeFieldMultiTSIterator(MEDFileAnyTypeFieldMultiTS *fmts):_fmts(fmts),_iter_id(0),_nb_iter(0) -{ - if(fmts) - { - fmts->incrRef(); - _nb_iter=fmts->getNumberOfTS(); - } -} - -MEDFileAnyTypeFieldMultiTSIterator::~MEDFileAnyTypeFieldMultiTSIterator() -{ -} - -MEDFileAnyTypeField1TS *MEDFileAnyTypeFieldMultiTSIterator::nextt() -{ - if(_iter_id<_nb_iter) - { - MEDFileAnyTypeFieldMultiTS *fmts(_fmts); - if(fmts) - return fmts->getTimeStepAtPos(_iter_id++); - else - return 0; - } - else - return 0; -} - -//= MEDFileIntFieldMultiTS - -/*! - * Returns a new empty instance of MEDFileFieldMultiTS. - * \return MEDFileIntFieldMultiTS * - a new instance of MEDFileIntFieldMultiTS. The caller - * is to delete this field using decrRef() as it is no more needed. - */ -MEDFileIntFieldMultiTS *MEDFileIntFieldMultiTS::New() -{ - return new MEDFileIntFieldMultiTS; -} - -/*! - * Returns a new instance of MEDFileIntFieldMultiTS holding data of the first field - * that has been read from a specified MED file. - * \param [in] fileName - the name of the MED file to read. - * \return MEDFileFieldMultiTS * - a new instance of MEDFileIntFieldMultiTS. The caller - * is to delete this field using decrRef() as it is no more needed. - * \throw If reading the file fails. - */ -MEDFileIntFieldMultiTS *MEDFileIntFieldMultiTS::New(const std::string& fileName, bool loadAll) -{ - MEDCouplingAutoRefCountObjectPtr ret=new MEDFileIntFieldMultiTS(fileName,loadAll,0); - ret->contentNotNull();//to check that content type matches with \a this type. - return ret.retn(); -} - -/*! - * Returns a new instance of MEDFileIntFieldMultiTS holding data of a given field - * that has been read from a specified MED file. - * \param [in] fileName - the name of the MED file to read. - * \param [in] fieldName - the name of the field to read. - * \return MEDFileFieldMultiTS * - a new instance of MEDFileIntFieldMultiTS. The caller - * is to delete this field using decrRef() as it is no more needed. - * \throw If reading the file fails. - * \throw If there is no field named \a fieldName in the file. - */ -MEDFileIntFieldMultiTS *MEDFileIntFieldMultiTS::New(const std::string& fileName, const std::string& fieldName, bool loadAll) -{ - MEDCouplingAutoRefCountObjectPtr ret=new MEDFileIntFieldMultiTS(fileName,fieldName,loadAll,0); - ret->contentNotNull();//to check that content type matches with \a this type. - return ret.retn(); -} - -/*! - * Returns a new instance of MEDFileIntFieldMultiTS. If \a shallowCopyOfContent is true the content of \a other is shallow copied. - * If \a shallowCopyOfContent is false, \a other is taken to be the content of \a this. - * - * Returns a new instance of MEDFileIntFieldMultiTS holding either a shallow copy - * of a given MEDFileIntFieldMultiTSWithoutSDA ( \a other ) or \a other itself. - * \warning this is a shallow copy constructor - * \param [in] other - a MEDFileIntField1TSWithoutSDA to copy. - * \param [in] shallowCopyOfContent - if \c true, a shallow copy of \a other is created. - * \return MEDFileIntFieldMultiTS * - a new instance of MEDFileIntFieldMultiTS. The caller - * is to delete this field using decrRef() as it is no more needed. - */ -MEDFileIntFieldMultiTS *MEDFileIntFieldMultiTS::New(const MEDFileIntFieldMultiTSWithoutSDA& other, bool shallowCopyOfContent) -{ - return new MEDFileIntFieldMultiTS(other,shallowCopyOfContent); -} - -MEDFileIntFieldMultiTS *MEDFileIntFieldMultiTS::LoadSpecificEntities(const std::string& fileName, const std::string& fieldName, const std::vector< std::pair >& entities, bool loadAll) -{ - MEDCouplingAutoRefCountObjectPtr ret=new MEDFileIntFieldMultiTS(fileName,fieldName,loadAll,0,&entities); - ret->contentNotNull();//to check that content type matches with \a this type. - return ret.retn(); -} - -/*! - * This method performs a copy with datatype modification ( int32->float64 ) of \a this. The globals information are copied - * following the given input policy. - * - * \param [in] isDeepCpyGlobs - a boolean that indicates the behaviour concerning globals (profiles and localizations) - * By default (true) the globals are deeply copied. - * \return MEDFileFieldMultiTS * - a new object that is the result of the conversion of \a this to float64 field. - */ -MEDFileFieldMultiTS *MEDFileIntFieldMultiTS::convertToDouble(bool isDeepCpyGlobs) const -{ - MEDCouplingAutoRefCountObjectPtr ret; - const MEDFileAnyTypeFieldMultiTSWithoutSDA *content(_content); - if(content) - { - const MEDFileIntFieldMultiTSWithoutSDA *contc=dynamic_cast(content); - if(!contc) - throw INTERP_KERNEL::Exception("MEDFileIntFieldMultiTS::convertToInt : the content inside this is not INT32 ! This is incoherent !"); - MEDCouplingAutoRefCountObjectPtr newc(contc->convertToDouble()); - ret=static_cast(MEDFileAnyTypeFieldMultiTS::BuildNewInstanceFromContent((MEDFileFieldMultiTSWithoutSDA *)newc,getFileName())); - } - else - ret=MEDFileFieldMultiTS::New(); - if(isDeepCpyGlobs) - ret->deepCpyGlobs(*this); - else - ret->shallowCpyGlobs(*this); - return ret.retn(); -} - -MEDFileAnyTypeFieldMultiTS *MEDFileIntFieldMultiTS::shallowCpy() const -{ - return new MEDFileIntFieldMultiTS(*this); -} - -void MEDFileIntFieldMultiTS::checkCoherencyOfType(const MEDFileAnyTypeField1TS *f1ts) const -{ - if(!f1ts) - throw INTERP_KERNEL::Exception("MEDFileIntFieldMultiTS::checkCoherencyOfType : input field1TS is NULL ! Impossible to check !"); - const MEDFileIntField1TS *f1tsC=dynamic_cast(f1ts); - if(!f1tsC) - throw INTERP_KERNEL::Exception("MEDFileIntFieldMultiTS::checkCoherencyOfType : the input field1TS is not a INT32 type !"); -} - -/*! - * Returns a new MEDCouplingFieldDouble of a given type, of a given time step, lying on - * mesh entities of a given dimension of the first mesh in MED file. - * For more info, see \ref AdvMEDLoaderAPIFieldRW - * \param [in] type - a spatial discretization of interest. - * \param [in] iteration - the iteration number of a required time step. - * \param [in] order - the iteration order number of required time step. - * \param [in] meshDimRelToMax - a relative dimension of the supporting mesh entities. - * \param [out] arrOut - the DataArrayInt containing values of field. - * \param [in] renumPol - specifies how to permute values of the result field according to - * the optional numbers of cells and nodes, if any. The valid values are - * - 0 - do not permute. - * - 1 - permute cells. - * - 2 - permute nodes. - * - 3 - permute cells and nodes. - * - * \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 MED file is not readable. - * \throw If there is no mesh in the MED file. - * \throw If there are no mesh entities of \a meshDimRelToMax dimension in the mesh. - * \throw If no field values of the required parameters are available. - */ -MEDCouplingFieldDouble *MEDFileIntFieldMultiTS::getFieldAtLevel(TypeOfField type, int iteration, int order, int meshDimRelToMax, DataArrayInt* &arrOut, int renumPol) const -{ - const MEDFileAnyTypeField1TSWithoutSDA& myF1TS=contentNotNullBase()->getTimeStepEntry(iteration,order); - const MEDFileIntField1TSWithoutSDA *myF1TSC=dynamic_cast(&myF1TS); - if(!myF1TSC) - throw INTERP_KERNEL::Exception("MEDFileIntFieldMultiTS::getFieldAtLevel : mismatch of type of field expecting INT32 !"); - MEDCouplingAutoRefCountObjectPtr arr; - MEDCouplingAutoRefCountObjectPtr ret=myF1TSC->getFieldAtLevel(type,meshDimRelToMax,std::string(),renumPol,this,arr,*contentNotNullBase()); - arrOut=MEDFileIntField1TS::ReturnSafelyDataArrayInt(arr); - return ret.retn(); -} - -/*! - * Returns a new MEDCouplingFieldDouble of a given type, of a given time step, lying on - * the top level cells of the first mesh in MED file. - * For more info, see \ref AdvMEDLoaderAPIFieldRW - * \param [in] type - a spatial discretization of interest. - * \param [in] iteration - the iteration number of a required time step. - * \param [in] order - the iteration order number of required time step. - * \param [out] arrOut - the DataArrayInt containing values of field. - * \param [in] renumPol - specifies how to permute values of the result field according to - * the optional numbers of cells and nodes, if any. The valid values are - * - 0 - do not permute. - * - 1 - permute cells. - * - 2 - permute nodes. - * - 3 - permute cells and nodes. - * - * \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 MED file is not readable. - * \throw If there is no mesh in the MED file. - * \throw If no field values of the required parameters are available. - */ -MEDCouplingFieldDouble *MEDFileIntFieldMultiTS::getFieldAtTopLevel(TypeOfField type, int iteration, int order, DataArrayInt* &arrOut, int renumPol) const -{ - const MEDFileAnyTypeField1TSWithoutSDA& myF1TS=contentNotNullBase()->getTimeStepEntry(iteration,order); - const MEDFileIntField1TSWithoutSDA *myF1TSC=dynamic_cast(&myF1TS); - if(!myF1TSC) - throw INTERP_KERNEL::Exception("MEDFileIntFieldMultiTS::getFieldAtTopLevel : mismatch of type of field ! INT32 expected !"); - MEDCouplingAutoRefCountObjectPtr arr; - MEDCouplingAutoRefCountObjectPtr ret=myF1TSC->getFieldAtTopLevel(type,std::string(),renumPol,this,arr,*contentNotNullBase()); - arrOut=MEDFileIntField1TS::ReturnSafelyDataArrayInt(arr); - return ret.retn(); -} - -/*! - * Returns a new MEDCouplingFieldDouble of a given type, of a given time step, lying on - * a given support. - * For more info, see \ref AdvMEDLoaderAPIFieldRW - * \param [in] type - a spatial discretization of interest. - * \param [in] iteration - the iteration number of a required time step. - * \param [in] order - the iteration order number of required time step. - * \param [out] arrOut - the DataArrayInt containing values of field. - * \param [in] meshDimRelToMax - a relative dimension of the supporting mesh entities. - * \param [in] mesh - the supporting mesh. - * \param [in] renumPol - specifies how to permute values of the result field according to - * the optional numbers of cells and nodes, if any. The valid values are - * - 0 - do not permute. - * - 1 - permute cells. - * - 2 - permute nodes. - * - 3 - permute cells and nodes. - * - * \return MEDCouplingFieldDouble * - a new instance of MEDCouplingFieldDouble. The - * caller is to delete this field using decrRef() as it is no more needed. - * \throw If there are no mesh entities of \a meshDimRelToMax dimension in the mesh. - * \throw If no field of \a this is lying on \a mesh. - * \throw If no field values of the required parameters are available. - */ -MEDCouplingFieldDouble *MEDFileIntFieldMultiTS::getFieldOnMeshAtLevel(TypeOfField type, int iteration, int order, int meshDimRelToMax, const MEDFileMesh *mesh, DataArrayInt* &arrOut, int renumPol) const -{ - const MEDFileAnyTypeField1TSWithoutSDA& myF1TS=contentNotNullBase()->getTimeStepEntry(iteration,order); - const MEDFileIntField1TSWithoutSDA *myF1TSC=dynamic_cast(&myF1TS); - if(!myF1TSC) - throw INTERP_KERNEL::Exception("MEDFileFieldMultiTS::getFieldOnMeshAtLevel : mismatch of type of field ! INT32 expected !"); - MEDCouplingAutoRefCountObjectPtr arr; - MEDCouplingAutoRefCountObjectPtr ret=myF1TSC->getFieldOnMeshAtLevel(type,meshDimRelToMax,renumPol,this,mesh,arr,*contentNotNullBase()); - arrOut=MEDFileIntField1TS::ReturnSafelyDataArrayInt(arr); - return ret.retn(); -} - -/*! - * Returns a new MEDCouplingFieldDouble of given type, of a given time step, lying on a - * given support. - * For more info, see \ref AdvMEDLoaderAPIFieldRW - * \param [in] type - a spatial discretization of the new field. - * \param [in] iteration - the iteration number of a required time step. - * \param [in] order - the iteration order number of required time step. - * \param [in] mesh - the supporting mesh. - * \param [out] arrOut - the DataArrayInt containing values of field. - * \param [in] renumPol - specifies how to permute values of the result field according to - * the optional numbers of cells and nodes, if any. The valid values are - * - 0 - do not permute. - * - 1 - permute cells. - * - 2 - permute nodes. - * - 3 - permute cells and nodes. - * - * \return MEDCouplingFieldDouble * - a new instance of MEDCouplingFieldDouble. The - * caller is to delete this field using decrRef() as it is no more needed. - * \throw If no field of \a this is lying on \a mesh. - * \throw If no field values of the required parameters are available. - */ -MEDCouplingFieldDouble *MEDFileIntFieldMultiTS::getFieldOnMeshAtLevel(TypeOfField type, int iteration, int order, const MEDCouplingMesh *mesh, DataArrayInt* &arrOut, int renumPol) const -{ - const MEDFileAnyTypeField1TSWithoutSDA& myF1TS=contentNotNullBase()->getTimeStepEntry(iteration,order); - const MEDFileIntField1TSWithoutSDA *myF1TSC=dynamic_cast(&myF1TS); - if(!myF1TSC) - throw INTERP_KERNEL::Exception("MEDFileFieldIntMultiTS::getFieldOnMeshAtLevel : mismatch of type of field ! INT32 expected !"); - MEDCouplingAutoRefCountObjectPtr arr; - MEDCouplingAutoRefCountObjectPtr ret=myF1TSC->getFieldOnMeshAtLevel(type,renumPol,this,mesh,0,0,arr,*contentNotNullBase()); - arrOut=MEDFileIntField1TS::ReturnSafelyDataArrayInt(arr); - return ret.retn(); -} - -/*! - * This method has a close behaviour than MEDFileIntFieldMultiTS::getFieldAtLevel. - * This method is called 'old' because the user should give the mesh name he wants to use for it's field. - * This method is useful for MED2 file format when field on different mesh was autorized. - */ -MEDCouplingFieldDouble *MEDFileIntFieldMultiTS::getFieldAtLevelOld(TypeOfField type, int iteration, int order, const std::string& mname, int meshDimRelToMax, DataArrayInt* &arrOut, int renumPol) const -{ - const MEDFileAnyTypeField1TSWithoutSDA& myF1TS=contentNotNullBase()->getTimeStepEntry(iteration,order); - const MEDFileIntField1TSWithoutSDA *myF1TSC=dynamic_cast(&myF1TS); - if(!myF1TSC) - throw INTERP_KERNEL::Exception("MEDFileFieldMultiTS::getFieldOnMeshAtLevel : mismatch of type of field ! INT32 expected !"); - MEDCouplingAutoRefCountObjectPtr arr; - MEDCouplingAutoRefCountObjectPtr ret=myF1TSC->getFieldAtLevel(type,meshDimRelToMax,mname,renumPol,this,arr,*contentNotNullBase()); - arrOut=MEDFileIntField1TS::ReturnSafelyDataArrayInt(arr); - return ret.retn(); -} - -/*! - * Returns values and a profile of the field of a given type, of a given time step, - * lying on a given support. - * For more info, see \ref AdvMEDLoaderAPIFieldRW - * \param [in] type - a spatial discretization of the field. - * \param [in] iteration - the iteration number of a required time step. - * \param [in] order - the iteration order number of required time step. - * \param [in] meshDimRelToMax - a relative dimension of the supporting mesh entities. - * \param [in] mesh - the supporting mesh. - * \param [out] pfl - a new instance of DataArrayInt holding ids of mesh entities the - * field of interest lies on. If the field lies on all entities of the given - * dimension, all ids in \a pfl are zero. The caller is to delete this array - * using decrRef() as it is no more needed. - * \param [in] glob - the global data storing profiles and localization. - * \return DataArrayInt * - a new instance of DataArrayInt holding values of the - * field. The caller is to delete this array using decrRef() as it is no more needed. - * \throw If there are no mesh entities of \a meshDimRelToMax dimension in \a mesh. - * \throw If no field of \a this is lying on \a mesh. - * \throw If no field values of the required parameters are available. - */ -DataArrayInt *MEDFileIntFieldMultiTS::getFieldWithProfile(TypeOfField type, int iteration, int order, int meshDimRelToMax, const MEDFileMesh *mesh, DataArrayInt *&pfl) const -{ - const MEDFileAnyTypeField1TSWithoutSDA& myF1TS=contentNotNullBase()->getTimeStepEntry(iteration,order); - const MEDFileIntField1TSWithoutSDA *myF1TSC=dynamic_cast(&myF1TS); - if(!myF1TSC) - throw INTERP_KERNEL::Exception("MEDFileIntFieldMultiTS::getFieldWithProfile : mismatch of type of field ! INT32 expected !"); - MEDCouplingAutoRefCountObjectPtr ret=myF1TSC->getFieldWithProfile(type,meshDimRelToMax,mesh,pfl,this,*contentNotNullBase()); - return MEDFileIntField1TS::ReturnSafelyDataArrayInt(ret); -} - -/*! - * Returns a new MEDFileIntField1TS holding data of a given time step of \a this field. - * \param [in] pos - a time step id. - * \return MEDFileIntField1TS * - a new instance of MEDFileIntField1TS. The caller is to - * delete this field using decrRef() as it is no more needed. - * \throw If \a pos is not a valid time step id. - */ -MEDFileAnyTypeField1TS *MEDFileIntFieldMultiTS::getTimeStepAtPos(int pos) const -{ - const MEDFileAnyTypeField1TSWithoutSDA *item=contentNotNullBase()->getTimeStepAtPos2(pos); - if(!item) - { - std::ostringstream oss; oss << "MEDFileIntFieldMultiTS::getTimeStepAtPos : field at pos #" << pos << " is null !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - const MEDFileIntField1TSWithoutSDA *itemC=dynamic_cast(item); - if(itemC) - { - MEDCouplingAutoRefCountObjectPtr ret=MEDFileIntField1TS::New(*itemC,false); - ret->shallowCpyGlobs(*this); - return ret.retn(); - } - std::ostringstream oss; oss << "MEDFileIntFieldMultiTS::getTimeStepAtPos : type of field at pos #" << pos << " is not INT32 !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); -} - -/*! - * Adds a MEDCouplingFieldDouble to \a this as another time step. The underlying mesh of - * the given field is checked if its elements are sorted suitable for writing to MED file - * ("STB" stands for "Sort By Type"), if not, an exception is thrown. - * For more info, see \ref AdvMEDLoaderAPIFieldRW - * \param [in] field - the field to add to \a this. - * \throw If the name of \a field is empty. - * \throw If the data array of \a field is not set. - * \throw If existing time steps have different name or number of components than \a field. - * \throw If the underlying mesh of \a field has no name. - * \throw If elements in the mesh are not in the order suitable for writing to the MED file. - */ -void MEDFileIntFieldMultiTS::appendFieldNoProfileSBT(const MEDCouplingFieldDouble *field, const DataArrayInt *arrOfVals) -{ - contentNotNull()->appendFieldNoProfileSBT(field,arrOfVals,*this); -} - -/*! - * Adds a MEDCouplingFieldDouble to \a this as another time step. - * The mesh support of input parameter \a field is ignored here, it can be NULL. - * The support of field \a field is expected to be those computed with the input parameter \a mesh, \a meshDimRelToMax, - * and \a profile. - * - * This method will check that the field based on the computed support is coherent. If not an exception will be thrown. - * A new profile is added only if no equal profile is missing. - * For more info, see \ref AdvMEDLoaderAPIFieldRW - * \param [in] field - the field to add to \a this. The field double values and mesh support are ignored. - * \param [in] arrOfVals - the values of the field \a field used. - * \param [in] mesh - the supporting mesh of \a field. - * \param [in] meshDimRelToMax - a relative dimension of mesh entities \a field lies on (useless if field spatial discretization is ON_NODES). - * \param [in] profile - ids of mesh entities on which corresponding field values lie. - * \throw If either \a field or \a mesh or \a profile has an empty name. - * \throw If there are no mesh entities of \a meshDimRelToMax dimension in \a mesh. - * \throw If the data array of \a field is not set. - * \throw If the data array of \a this is already allocated but has different number of - * components than \a field. - * \throw If elements in \a mesh are not in the order suitable for writing to the MED file. - * \sa setFieldNoProfileSBT() - */ -void MEDFileIntFieldMultiTS::appendFieldProfile(const MEDCouplingFieldDouble *field, const DataArrayInt *arrOfVals, const MEDFileMesh *mesh, int meshDimRelToMax, const DataArrayInt *profile) -{ - contentNotNull()->appendFieldProfile(field,arrOfVals,mesh,meshDimRelToMax,profile,*this); -} - -const MEDFileIntFieldMultiTSWithoutSDA *MEDFileIntFieldMultiTS::contentNotNull() const -{ - const MEDFileAnyTypeFieldMultiTSWithoutSDA *pt(_content); - if(!pt) - throw INTERP_KERNEL::Exception("MEDFileIntFieldMultiTS::contentNotNull : the content pointer is null !"); - const MEDFileIntFieldMultiTSWithoutSDA *ret=dynamic_cast(pt); - if(!ret) - throw INTERP_KERNEL::Exception("MEDFileIntFieldMultiTS::contentNotNull : the content pointer is not null but it is not of type int ! Reason is maybe that the read field has not the type INT32 !"); - return ret; -} - -MEDFileIntFieldMultiTSWithoutSDA *MEDFileIntFieldMultiTS::contentNotNull() -{ - MEDFileAnyTypeFieldMultiTSWithoutSDA *pt(_content); - if(!pt) - throw INTERP_KERNEL::Exception("MEDFileIntFieldMultiTS::contentNotNull : the non const content pointer is null !"); - MEDFileIntFieldMultiTSWithoutSDA *ret=dynamic_cast(pt); - if(!ret) - throw INTERP_KERNEL::Exception("MEDFileIntFieldMultiTS::contentNotNull : the non const content pointer is not null but it is not of type int ! Reason is maybe that the read field has not the type INT32 !"); - return ret; -} - -MEDFileIntFieldMultiTS::MEDFileIntFieldMultiTS() -{ - _content=new MEDFileIntFieldMultiTSWithoutSDA; -} - -MEDFileIntFieldMultiTS::MEDFileIntFieldMultiTS(const MEDFileIntFieldMultiTSWithoutSDA& other, bool shallowCopyOfContent):MEDFileAnyTypeFieldMultiTS(other,shallowCopyOfContent) -{ -} - -MEDFileIntFieldMultiTS::MEDFileIntFieldMultiTS(const std::string& fileName, bool loadAll, const MEDFileMeshes *ms) -try:MEDFileAnyTypeFieldMultiTS(fileName,loadAll,ms) -{ -} -catch(INTERP_KERNEL::Exception& e) -{ throw e; } - -MEDFileIntFieldMultiTS::MEDFileIntFieldMultiTS(const std::string& fileName, const std::string& fieldName, bool loadAll, const MEDFileMeshes *ms, const std::vector< std::pair > *entities) -try:MEDFileAnyTypeFieldMultiTS(fileName,fieldName,loadAll,ms,entities) -{ -} -catch(INTERP_KERNEL::Exception& e) -{ throw e; } - -DataArrayInt *MEDFileIntFieldMultiTS::getUndergroundDataArray(int iteration, int order) const -{ - return static_cast(contentNotNull()->getUndergroundDataArray(iteration,order)); -} - -//= MEDFileFields - -MEDFileFields *MEDFileFields::New() -{ - return new MEDFileFields; -} - -MEDFileFields *MEDFileFields::New(const std::string& fileName, bool loadAll) -{ - return new MEDFileFields(fileName,loadAll,0,0); -} - -MEDFileFields *MEDFileFields::LoadPartOf(const std::string& fileName, bool loadAll, const MEDFileMeshes *ms) -{ - return new MEDFileFields(fileName,loadAll,ms,0); -} - -MEDFileFields *MEDFileFields::LoadSpecificEntities(const std::string& fileName, const std::vector< std::pair >& entities, bool loadAll) -{ - return new MEDFileFields(fileName,loadAll,0,&entities); -} - -std::size_t MEDFileFields::getHeapMemorySizeWithoutChildren() const -{ - std::size_t ret(MEDFileFieldGlobsReal::getHeapMemorySizeWithoutChildren()); - ret+=_fields.capacity()*sizeof(MEDCouplingAutoRefCountObjectPtr); - return ret; -} - -std::vector MEDFileFields::getDirectChildrenWithNull() const -{ - std::vector ret; - for(std::vector< MEDCouplingAutoRefCountObjectPtr >::const_iterator it=_fields.begin();it!=_fields.end();it++) - ret.push_back((const MEDFileAnyTypeFieldMultiTSWithoutSDA *)*it); - return ret; -} - -MEDFileFields *MEDFileFields::deepCpy() const -{ - MEDCouplingAutoRefCountObjectPtr ret=shallowCpy(); - std::size_t i=0; - for(std::vector< MEDCouplingAutoRefCountObjectPtr >::const_iterator it=_fields.begin();it!=_fields.end();it++,i++) - { - if((const MEDFileAnyTypeFieldMultiTSWithoutSDA*)*it) - ret->_fields[i]=(*it)->deepCpy(); - } - ret->deepCpyGlobs(*this); - return ret.retn(); -} - -MEDFileFields *MEDFileFields::shallowCpy() const -{ - return new MEDFileFields(*this); -} - -/*! - * This method scans for all fields in \a this which time steps ids are common. Time step are discriminated by the pair of integer (iteration,order) whatever - * the double time value. If all returned time steps are \b exactly those for all fields in \a this output parameter \a areThereSomeForgottenTS will be set to false. - * If \a areThereSomeForgottenTS is set to true, only the sorted intersection of time steps present for all fields in \a this will be returned. - * - * \param [out] areThereSomeForgottenTS - indicates to the caller if there is some time steps in \a this that are not present for all fields in \a this. - * \return the sorted list of time steps (specified with a pair of integer iteration first and order second) present for all fields in \a this. - * - * \sa MEDFileFields::partOfThisLyingOnSpecifiedTimeSteps, MEDFileFields::partOfThisNotLyingOnSpecifiedTimeSteps - */ -std::vector< std::pair > MEDFileFields::getCommonIterations(bool& areThereSomeForgottenTS) const -{ - std::set< std::pair > s; - bool firstShot=true; - areThereSomeForgottenTS=false; - for(std::vector< MEDCouplingAutoRefCountObjectPtr >::const_iterator it=_fields.begin();it!=_fields.end();it++) - { - if(!(const MEDFileAnyTypeFieldMultiTSWithoutSDA*)*it) - continue; - std::vector< std::pair > v=(*it)->getIterations(); - std::set< std::pair > s1; std::copy(v.begin(),v.end(),std::inserter(s1,s1.end())); - if(firstShot) - { s=s1; firstShot=false; } - else - { - std::set< std::pair > s2; std::set_intersection(s.begin(),s.end(),s1.begin(),s1.end(),std::inserter(s2,s2.end())); - if(s!=s2) - areThereSomeForgottenTS=true; - s=s2; - } - } - std::vector< std::pair > ret; - std::copy(s.begin(),s.end(),std::back_insert_iterator< std::vector< std::pair > >(ret)); - return ret; -} - -int MEDFileFields::getNumberOfFields() const -{ - return _fields.size(); -} - -std::vector MEDFileFields::getFieldsNames() const -{ - std::vector ret(_fields.size()); - int i=0; - for(std::vector< MEDCouplingAutoRefCountObjectPtr >::const_iterator it=_fields.begin();it!=_fields.end();it++,i++) - { - const MEDFileAnyTypeFieldMultiTSWithoutSDA *f=(*it); - if(f) - { - ret[i]=f->getName(); - } - else - { - std::ostringstream oss; oss << "MEDFileFields::getFieldsNames : At rank #" << i << " field is not defined !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - } - return ret; -} - -std::vector MEDFileFields::getMeshesNames() const -{ - std::vector ret; - for(std::vector< MEDCouplingAutoRefCountObjectPtr >::const_iterator it=_fields.begin();it!=_fields.end();it++) - { - const MEDFileAnyTypeFieldMultiTSWithoutSDA *cur(*it); - if(cur) - ret.push_back(cur->getMeshName()); - } - return ret; -} - -std::string MEDFileFields::simpleRepr() const -{ - std::ostringstream oss; - oss << "(*****************)\n(* MEDFileFields *)\n(*****************)\n\n"; - simpleRepr(0,oss); - return oss.str(); -} - -void MEDFileFields::simpleRepr(int bkOffset, std::ostream& oss) const -{ - int nbOfFields=getNumberOfFields(); - std::string startLine(bkOffset,' '); - oss << startLine << "There are " << nbOfFields << " fields in this :" << std::endl; - int i=0; - for(std::vector< MEDCouplingAutoRefCountObjectPtr >::const_iterator it=_fields.begin();it!=_fields.end();it++,i++) - { - const MEDFileAnyTypeFieldMultiTSWithoutSDA *cur=(*it); - if(cur) - { - oss << startLine << " - # "<< i << " has the following name : \"" << cur->getName() << "\"." << std::endl; - } - else - { - oss << startLine << " - not defined !" << std::endl; - } - } - i=0; - for(std::vector< MEDCouplingAutoRefCountObjectPtr >::const_iterator it=_fields.begin();it!=_fields.end();it++,i++) - { - const MEDFileAnyTypeFieldMultiTSWithoutSDA *cur=(*it); - std::string chapter(17,'0'+i); - oss << startLine << chapter << std::endl; - if(cur) - { - cur->simpleRepr(bkOffset+2,oss,i); - } - else - { - oss << startLine << " - not defined !" << std::endl; - } - oss << startLine << chapter << std::endl; - } - simpleReprGlobs(oss); -} - -MEDFileFields::MEDFileFields() -{ -} - -MEDFileFields::MEDFileFields(const std::string& fileName, bool loadAll, const MEDFileMeshes *ms, const std::vector< std::pair > *entities) -try:MEDFileFieldGlobsReal(fileName) -{ - MEDFileUtilities::CheckFileForRead(fileName); - MEDFileUtilities::AutoFid fid(MEDfileOpen(fileName.c_str(),MED_ACC_RDONLY)); - int nbFields(MEDnField(fid)); - _fields.resize(nbFields); - med_field_type typcha; - for(int i=0;i infos; - std::string fieldName,dtunit; - int nbOfStep(MEDFileAnyTypeField1TS::LocateField2(fid,fileName,i,false,fieldName,typcha,infos,dtunit)); - switch(typcha) - { - case MED_FLOAT64: - { - _fields[i]=MEDFileFieldMultiTSWithoutSDA::New(fid,fieldName.c_str(),typcha,infos,nbOfStep,dtunit,loadAll,ms,entities); - break; - } - case MED_INT32: - { - _fields[i]=MEDFileIntFieldMultiTSWithoutSDA::New(fid,fieldName.c_str(),typcha,infos,nbOfStep,dtunit,loadAll,ms,entities); - break; - } - default: - { - std::ostringstream oss; oss << "constructor MEDFileFields(fileName) : file \'" << fileName << "\' at pos #" << i << " field has name \'" << fieldName << "\' but the type of field is not in [MED_FLOAT64, MED_INT32] !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - } - } - loadAllGlobals(fid); -} -catch(INTERP_KERNEL::Exception& e) -{ - throw e; -} - -void MEDFileFields::writeLL(med_idt fid) const -{ - int i=0; - writeGlobals(fid,*this); - for(std::vector< MEDCouplingAutoRefCountObjectPtr >::const_iterator it=_fields.begin();it!=_fields.end();it++,i++) - { - const MEDFileAnyTypeFieldMultiTSWithoutSDA *elt=*it; - if(!elt) - { - std::ostringstream oss; oss << "MEDFileFields::write : at rank #" << i << "/" << _fields.size() << " field is empty !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - elt->writeLL(fid,*this); - } -} - -void MEDFileFields::write(const std::string& fileName, int mode) const -{ - med_access_mode medmod=MEDFileUtilities::TraduceWriteMode(mode); - MEDFileUtilities::AutoFid fid(MEDfileOpen(fileName.c_str(),medmod)); - writeLL(fid); -} - -/*! - * This method alloc the arrays and load potentially huge arrays contained in this field. - * This method should be called when a MEDFileAnyTypeFieldMultiTS::New constructor has been with false as the last parameter. - * This method can be also called to refresh or reinit values from a file. - * - * \throw If the fileName is not set or points to a non readable MED file. - */ -void MEDFileFields::loadArrays() -{ - if(getFileName().empty()) - throw INTERP_KERNEL::Exception("MEDFileFields::loadArrays : the structure does not come from a file !"); - MEDFileUtilities::AutoFid fid=MEDfileOpen(getFileName().c_str(),MED_ACC_RDONLY); - for(std::vector< MEDCouplingAutoRefCountObjectPtr >::iterator it=_fields.begin();it!=_fields.end();it++) - { - MEDFileAnyTypeFieldMultiTSWithoutSDA *elt(*it); - if(elt) - elt->loadBigArraysRecursively(fid,*elt); - } -} - -/*! - * This method behaves as MEDFileFields::loadArrays does, the first call, if \a this was built using a file without loading big arrays. - * But once data loaded once, this method does nothing. - * - * \throw If the fileName is not set or points to a non readable MED file. - * \sa MEDFileFields::loadArrays, MEDFileFields::unloadArrays - */ -void MEDFileFields::loadArraysIfNecessary() -{ - if(!getFileName().empty()) - { - MEDFileUtilities::AutoFid fid=MEDfileOpen(getFileName().c_str(),MED_ACC_RDONLY); - for(std::vector< MEDCouplingAutoRefCountObjectPtr >::iterator it=_fields.begin();it!=_fields.end();it++) - { - MEDFileAnyTypeFieldMultiTSWithoutSDA *elt(*it); - if(elt) - elt->loadBigArraysRecursivelyIfNecessary(fid,*elt); - } - } -} - -/*! - * This method releases potentially big data arrays and so returns to the same heap memory than status loaded with 'loadAll' parameter set to false. - * \b WARNING, this method does release arrays even if \a this does not come from a load of a MED file. - * So this method can lead to a loss of data. If you want to unload arrays safely call MEDFileFields::unloadArraysWithoutDataLoss instead. - * - * \sa MEDFileFields::loadArrays, MEDFileFields::loadArraysIfNecessary, MEDFileFields::unloadArraysWithoutDataLoss - */ -void MEDFileFields::unloadArrays() -{ - for(std::vector< MEDCouplingAutoRefCountObjectPtr >::iterator it=_fields.begin();it!=_fields.end();it++) - { - MEDFileAnyTypeFieldMultiTSWithoutSDA *elt(*it); - if(elt) - elt->unloadArrays(); - } -} - -/*! - * This method potentially releases big data arrays if \a this is coming from a file. If \a this has been built from scratch this method will have no effect. - * This method is the symetrical method of MEDFileFields::loadArraysIfNecessary. - * This method is useful to reduce \b safely amount of heap memory necessary for \a this by using MED file as database. - * - * \sa MEDFileFields::loadArraysIfNecessary - */ -void MEDFileFields::unloadArraysWithoutDataLoss() -{ - if(!getFileName().empty()) - unloadArrays(); -} - -std::vector MEDFileFields::getPflsReallyUsed() const -{ - std::vector ret; - std::set ret2; - for(std::vector< MEDCouplingAutoRefCountObjectPtr< MEDFileAnyTypeFieldMultiTSWithoutSDA > >::const_iterator it=_fields.begin();it!=_fields.end();it++) - { - std::vector tmp=(*it)->getPflsReallyUsed2(); - for(std::vector::const_iterator it2=tmp.begin();it2!=tmp.end();it2++) - if(ret2.find(*it2)==ret2.end()) - { - ret.push_back(*it2); - ret2.insert(*it2); - } - } - return ret; -} - -std::vector MEDFileFields::getLocsReallyUsed() const -{ - std::vector ret; - std::set ret2; - for(std::vector< MEDCouplingAutoRefCountObjectPtr< MEDFileAnyTypeFieldMultiTSWithoutSDA > >::const_iterator it=_fields.begin();it!=_fields.end();it++) - { - std::vector tmp=(*it)->getLocsReallyUsed2(); - for(std::vector::const_iterator it2=tmp.begin();it2!=tmp.end();it2++) - if(ret2.find(*it2)==ret2.end()) - { - ret.push_back(*it2); - ret2.insert(*it2); - } - } - return ret; -} - -std::vector MEDFileFields::getPflsReallyUsedMulti() const -{ - std::vector ret; - for(std::vector< MEDCouplingAutoRefCountObjectPtr< MEDFileAnyTypeFieldMultiTSWithoutSDA > >::const_iterator it=_fields.begin();it!=_fields.end();it++) - { - std::vector tmp=(*it)->getPflsReallyUsedMulti2(); - ret.insert(ret.end(),tmp.begin(),tmp.end()); - } - return ret; -} - -std::vector MEDFileFields::getLocsReallyUsedMulti() const -{ - std::vector ret; - for(std::vector< MEDCouplingAutoRefCountObjectPtr< MEDFileAnyTypeFieldMultiTSWithoutSDA > >::const_iterator it=_fields.begin();it!=_fields.end();it++) - { - std::vector tmp=(*it)->getLocsReallyUsed2(); - ret.insert(ret.end(),tmp.begin(),tmp.end()); - } - return ret; -} - -void MEDFileFields::changePflsRefsNamesGen(const std::vector< std::pair, std::string > >& mapOfModif) -{ - for(std::vector< MEDCouplingAutoRefCountObjectPtr< MEDFileAnyTypeFieldMultiTSWithoutSDA > >::iterator it=_fields.begin();it!=_fields.end();it++) - (*it)->changePflsRefsNamesGen2(mapOfModif); -} - -void MEDFileFields::changeLocsRefsNamesGen(const std::vector< std::pair, std::string > >& mapOfModif) -{ - for(std::vector< MEDCouplingAutoRefCountObjectPtr< MEDFileAnyTypeFieldMultiTSWithoutSDA > >::iterator it=_fields.begin();it!=_fields.end();it++) - (*it)->changeLocsRefsNamesGen2(mapOfModif); -} - -void MEDFileFields::resize(int newSize) -{ - _fields.resize(newSize); -} - -void MEDFileFields::pushFields(const std::vector& fields) -{ - for(std::vector::const_iterator it=fields.begin();it!=fields.end();it++) - pushField(*it); -} - -void MEDFileFields::pushField(MEDFileAnyTypeFieldMultiTS *field) -{ - if(!field) - throw INTERP_KERNEL::Exception("MEDFileFields::pushMesh : invalid input pointer ! should be different from 0 !"); - _fields.push_back(field->getContent()); - appendGlobs(*field,1e-12); -} - -void MEDFileFields::setFieldAtPos(int i, MEDFileAnyTypeFieldMultiTS *field) -{ - if(!field) - throw INTERP_KERNEL::Exception("MEDFileFields::setFieldAtPos : invalid input pointer ! should be different from 0 !"); - if(i>=(int)_fields.size()) - _fields.resize(i+1); - _fields[i]=field->getContent(); - appendGlobs(*field,1e-12); -} - -void MEDFileFields::destroyFieldAtPos(int i) -{ - destroyFieldsAtPos(&i,&i+1); -} - -void MEDFileFields::destroyFieldsAtPos(const int *startIds, const int *endIds) -{ - std::vector b(_fields.size(),true); - for(const int *i=startIds;i!=endIds;i++) - { - if(*i<0 || *i>=(int)_fields.size()) - { - std::ostringstream oss; oss << "MEDFileFields::destroyFieldsAtPos : Invalid given id in input (" << *i << ") should be in [0," << _fields.size() << ") !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - b[*i]=false; - } - std::vector< MEDCouplingAutoRefCountObjectPtr > fields(std::count(b.begin(),b.end(),true)); - std::size_t j=0; - for(std::size_t i=0;i<_fields.size();i++) - if(b[i]) - fields[j++]=_fields[i]; - _fields=fields; -} - -void MEDFileFields::destroyFieldsAtPos2(int bg, int end, int step) -{ - static const char msg[]="MEDFileFields::destroyFieldsAtPos2"; - int nbOfEntriesToKill=DataArrayInt::GetNumberOfItemGivenBESRelative(bg,end,step,msg); - std::vector b(_fields.size(),true); - int k=bg; - for(int i=0;i=(int)_fields.size()) - { - std::ostringstream oss; oss << "MEDFileFields::destroyFieldsAtPos2 : Invalid given id in input (" << k << ") should be in [0," << _fields.size() << ") !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - b[k]=false; - } - std::vector< MEDCouplingAutoRefCountObjectPtr > fields(std::count(b.begin(),b.end(),true)); - std::size_t j=0; - for(std::size_t i=0;i<_fields.size();i++) - if(b[i]) - fields[j++]=_fields[i]; - _fields=fields; -} - -bool MEDFileFields::changeMeshNames(const std::vector< std::pair >& modifTab) -{ - bool ret=false; - for(std::vector< MEDCouplingAutoRefCountObjectPtr >::iterator it=_fields.begin();it!=_fields.end();it++) - { - MEDFileAnyTypeFieldMultiTSWithoutSDA *cur(*it); - if(cur) - ret=cur->changeMeshNames(modifTab) || ret; - } - return ret; -} - -/*! - * \param [in] meshName the name of the mesh that will be renumbered. - * \param [in] oldCode is of format returned by MEDCouplingUMesh::getDistributionOfTypes. And for each *i* oldCode[3*i+2] gives the position (MEDFileUMesh::PutInThirdComponentOfCodeOffset). - * This code corresponds to the distribution of types in the corresponding mesh. - * \param [in] newCode idem to param \a oldCode except that here the new distribution is given. - * \param [in] renumO2N the old to new renumber array. - * \return If true a renumbering has been performed. The structure in \a this has been modified. If false, nothing has been done: it is typically the case if \a meshName is not refered by any - * field in \a this. - */ -bool MEDFileFields::renumberEntitiesLyingOnMesh(const std::string& meshName, const std::vector& oldCode, const std::vector& newCode, const DataArrayInt *renumO2N) -{ - bool ret=false; - for(std::vector< MEDCouplingAutoRefCountObjectPtr >::iterator it=_fields.begin();it!=_fields.end();it++) - { - MEDFileAnyTypeFieldMultiTSWithoutSDA *fmts(*it); - if(fmts) - { - ret=fmts->renumberEntitiesLyingOnMesh(meshName,oldCode,newCode,renumO2N,*this) || ret; - } - } - return ret; -} - -MEDFileAnyTypeFieldMultiTS *MEDFileFields::getFieldAtPos(int i) const -{ - if(i<0 || i>=(int)_fields.size()) - { - std::ostringstream oss; oss << "MEDFileFields::getFieldAtPos : Invalid given id in input (" << i << ") should be in [0," << _fields.size() << ") !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - const MEDFileAnyTypeFieldMultiTSWithoutSDA *fmts=_fields[i]; - if(!fmts) - return 0; - MEDCouplingAutoRefCountObjectPtr ret; - const MEDFileFieldMultiTSWithoutSDA *fmtsC=dynamic_cast(fmts); - const MEDFileIntFieldMultiTSWithoutSDA *fmtsC2=dynamic_cast(fmts); - if(fmtsC) - ret=MEDFileFieldMultiTS::New(*fmtsC,false); - else if(fmtsC2) - ret=MEDFileIntFieldMultiTS::New(*fmtsC2,false); - else - { - std::ostringstream oss; oss << "MEDFileFields::getFieldAtPos : At pos #" << i << " field is neither double (FLOAT64) nor integer (INT32) !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - ret->shallowCpyGlobs(*this); - return ret.retn(); -} - -/*! - * Return a shallow copy of \a this reduced to the fields ids defined in [ \a startIds , endIds ). - * This method is accessible in python using __getitem__ with a list in input. - * \return a new object that the caller should deal with. - */ -MEDFileFields *MEDFileFields::buildSubPart(const int *startIds, const int *endIds) const -{ - MEDCouplingAutoRefCountObjectPtr ret=shallowCpy(); - std::size_t sz=std::distance(startIds,endIds); - std::vector< MEDCouplingAutoRefCountObjectPtr > fields(sz); - int j=0; - for(const int *i=startIds;i!=endIds;i++,j++) - { - if(*i<0 || *i>=(int)_fields.size()) - { - std::ostringstream oss; oss << "MEDFileFields::buildSubPart : Invalid given id in input (" << *i << ") should be in [0," << _fields.size() << ") !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - fields[j]=_fields[*i]; - } - ret->_fields=fields; - return ret.retn(); -} - -MEDFileAnyTypeFieldMultiTS *MEDFileFields::getFieldWithName(const std::string& fieldName) const -{ - return getFieldAtPos(getPosFromFieldName(fieldName)); -} - -/*! - * This method removes, if any, fields in \a this having no time steps. - * If there is one or more than one such field in \a this true is returned and those fields will not be referenced anymore in \a this. - * - * If false is returned \a this does not contain such fields. If false is returned this method can be considered as const. - */ -bool MEDFileFields::removeFieldsWithoutAnyTimeStep() -{ - std::vector > newFields; - for(std::vector< MEDCouplingAutoRefCountObjectPtr >::const_iterator it=_fields.begin();it!=_fields.end();it++) - { - const MEDFileAnyTypeFieldMultiTSWithoutSDA *elt(*it); - if(elt) - { - if(elt->getNumberOfTS()>0) - newFields.push_back(*it); - } - } - if(_fields.size()==newFields.size()) - return false; - _fields=newFields; - return true; -} - -/*! - * This method returns a new object containing part of \a this fields lying on mesh name specified by the input parameter \a meshName. - * This method can be seen as a filter applied on \a this, that returns an object containing - * reduced the list of fields compared to those in \a this. The returned object is a new object but the object on which it lies are only - * shallow copied from \a this. - * - * \param [in] meshName - the name of the mesh on w - * \return a new object that the caller should deal with. - */ -MEDFileFields *MEDFileFields::partOfThisLyingOnSpecifiedMeshName(const std::string& meshName) const -{ - MEDCouplingAutoRefCountObjectPtr ret=MEDFileFields::New(); - for(std::vector< MEDCouplingAutoRefCountObjectPtr >::const_iterator it=_fields.begin();it!=_fields.end();it++) - { - const MEDFileAnyTypeFieldMultiTSWithoutSDA *cur=(*it); - if(!cur) - continue; - if(cur->getMeshName()==meshName) - { - cur->incrRef(); - MEDCouplingAutoRefCountObjectPtr cur2(const_cast(cur)); - ret->_fields.push_back(cur2); - } - } - ret->shallowCpyOnlyUsedGlobs(*this); - return ret.retn(); -} - -/*! - * This method returns a new object containing part of \a this fields lying ** exactly ** on the time steps specified by input parameter \a timeSteps. - * Input time steps are specified using a pair of integer (iteration, order). - * This method can be seen as a filter applied on \a this, that returns an object containing the same number of fields than those in \a this, - * but for each multitimestep only the time steps in \a timeSteps are kept. - * Typically the input parameter \a timeSteps comes from the call of MEDFileFields::getCommonIterations. - * - * The returned object points to shallow copy of elements in \a this. - * - * \param [in] timeSteps - the time steps given by a vector of pair of integers (iteration,order) - * \throw If there is a field in \a this that is \b not defined on a time step in the input \a timeSteps. - * \sa MEDFileFields::getCommonIterations, MEDFileFields::partOfThisNotLyingOnSpecifiedTimeSteps - */ -MEDFileFields *MEDFileFields::partOfThisLyingOnSpecifiedTimeSteps(const std::vector< std::pair >& timeSteps) const -{ - MEDCouplingAutoRefCountObjectPtr ret=MEDFileFields::New(); - for(std::vector< MEDCouplingAutoRefCountObjectPtr >::const_iterator it=_fields.begin();it!=_fields.end();it++) - { - const MEDFileAnyTypeFieldMultiTSWithoutSDA *cur=(*it); - if(!cur) - continue; - MEDCouplingAutoRefCountObjectPtr elt=cur->partOfThisLyingOnSpecifiedTimeSteps(timeSteps); - ret->_fields.push_back(elt); - } - ret->shallowCpyOnlyUsedGlobs(*this); - return ret.retn(); -} - -/*! - * \sa MEDFileFields::getCommonIterations, MEDFileFields::partOfThisLyingOnSpecifiedTimeSteps - */ -MEDFileFields *MEDFileFields::partOfThisNotLyingOnSpecifiedTimeSteps(const std::vector< std::pair >& timeSteps) const -{ - MEDCouplingAutoRefCountObjectPtr ret=MEDFileFields::New(); - for(std::vector< MEDCouplingAutoRefCountObjectPtr >::const_iterator it=_fields.begin();it!=_fields.end();it++) - { - const MEDFileAnyTypeFieldMultiTSWithoutSDA *cur=(*it); - if(!cur) - continue; - MEDCouplingAutoRefCountObjectPtr elt=cur->partOfThisNotLyingOnSpecifiedTimeSteps(timeSteps); - if(elt->getNumberOfTS()!=0) - ret->_fields.push_back(elt); - } - ret->shallowCpyOnlyUsedGlobs(*this); - return ret.retn(); -} - -MEDFileFieldsIterator *MEDFileFields::iterator() -{ - return new MEDFileFieldsIterator(this); -} - -int MEDFileFields::getPosFromFieldName(const std::string& fieldName) const -{ - std::string tmp(fieldName); - std::vector poss; - for(std::size_t i=0;i<_fields.size();i++) - { - const MEDFileAnyTypeFieldMultiTSWithoutSDA *f=_fields[i]; - if(f) - { - std::string fname(f->getName()); - if(tmp==fname) - return i; - else - poss.push_back(fname); - } - } - std::ostringstream oss; oss << "MEDFileFields::getPosFromFieldName : impossible to find field '" << tmp << "' in this ! Possibilities are : "; - std::copy(poss.begin(),poss.end(),std::ostream_iterator(oss,", ")); - oss << " !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); -} - -MEDFileFieldsIterator::MEDFileFieldsIterator(MEDFileFields *fs):_fs(fs),_iter_id(0),_nb_iter(0) -{ - if(fs) - { - fs->incrRef(); - _nb_iter=fs->getNumberOfFields(); - } -} - -MEDFileFieldsIterator::~MEDFileFieldsIterator() -{ -} - -MEDFileAnyTypeFieldMultiTS *MEDFileFieldsIterator::nextt() -{ - if(_iter_id<_nb_iter) - { - MEDFileFields *fs(_fs); - if(fs) - return fs->getFieldAtPos(_iter_id++); - else - return 0; - } - else - return 0; -} diff --git a/src/MEDLoader/MEDFileField.hxx b/src/MEDLoader/MEDFileField.hxx deleted file mode 100644 index bf0e31351..000000000 --- a/src/MEDLoader/MEDFileField.hxx +++ /dev/null @@ -1,1171 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 -// 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 __MEDFILEFIELD_HXX__ -#define __MEDFILEFIELD_HXX__ - -#include "MEDLoaderDefines.hxx" - -#include "MEDFileFieldOverView.hxx" -#include "MEDFileUtilities.hxx" - -#include "MEDCouplingAutoRefCountObjectPtr.hxx" -#include "MEDCouplingRefCountObject.hxx" -#include "MEDCouplingMemArray.hxx" - -#include "NormalizedUnstructuredMesh.hxx" -#include "InterpKernelException.hxx" - -#include -#include -#include -#include - -#include "med.h" - -namespace ParaMEDMEM -{ - class MEDFileFieldGlobs; - class MEDCouplingMesh; - class MEDCouplingFieldDouble; - class MEDFileMesh; - - class MEDFileFieldLoc : public RefCountObject - { - public: - MEDLOADER_EXPORT void simpleRepr(std::ostream& oss) const; - MEDLOADER_EXPORT std::string getName() const { return _name; } - MEDLOADER_EXPORT void setName(const std::string& name); - static MEDFileFieldLoc *New(med_idt fid, const std::string& locName); - static MEDFileFieldLoc *New(med_idt fid, int id); - static MEDFileFieldLoc *New(const std::string& locName, INTERP_KERNEL::NormalizedCellType geoType, const std::vector& refCoo, const std::vector& gsCoo, const std::vector& w); - std::size_t getHeapMemorySizeWithoutChildren() const; - std::vector getDirectChildrenWithNull() const; - MEDFileFieldLoc *deepCpy() const; - MEDLOADER_EXPORT int getNbOfGaussPtPerCell() const { return _nb_gauss_pt; } - MEDLOADER_EXPORT void writeLL(med_idt fid) const; - MEDLOADER_EXPORT std::string repr() const; - MEDLOADER_EXPORT bool isName(const std::string& name) const { return _name==name; } - MEDLOADER_EXPORT int getDimension() const { return _dim; } - MEDLOADER_EXPORT int getNumberOfGaussPoints() const { return _nb_gauss_pt; } - MEDLOADER_EXPORT int getNumberOfPointsInCells() const { return _nb_node_per_cell; } - MEDLOADER_EXPORT const std::vector& getRefCoords() const { return _ref_coo; } - MEDLOADER_EXPORT const std::vector& getGaussCoords() const { return _gs_coo; } - MEDLOADER_EXPORT const std::vector& getGaussWeights() const { return _w; } - MEDLOADER_EXPORT INTERP_KERNEL::NormalizedCellType getGeoType() const { return _geo_type; } - MEDLOADER_EXPORT bool isEqual(const MEDFileFieldLoc& other, double eps) const; - private: - MEDFileFieldLoc(med_idt fid, const std::string& locName); - MEDFileFieldLoc(med_idt fid, int id); - MEDFileFieldLoc(const std::string& locName, INTERP_KERNEL::NormalizedCellType geoType, const std::vector& refCoo, const std::vector& gsCoo, const std::vector& w); - private: - int _dim; - int _nb_gauss_pt; - int _nb_node_per_cell; - std::string _name; - INTERP_KERNEL::NormalizedCellType _geo_type; - std::vector _ref_coo; - std::vector _gs_coo; - std::vector _w; - }; - - /// @cond INTERNAL - class MEDFileAnyTypeField1TSWithoutSDA; - class MEDFileFieldPerMeshPerType; - class MEDFileField1TSWithoutSDA; - class MEDFileFieldNameScope; - class MEDFileFieldGlobsReal; - class MEDFileFieldPerMesh; - class PartDefinition; - - class MEDFileFieldPerMeshPerTypePerDisc : public RefCountObject, public MEDFileWritable - { - public: - static MEDFileFieldPerMeshPerTypePerDisc *NewOnRead(MEDFileFieldPerMeshPerType *fath, TypeOfField type, int profileIt, const PartDefinition *pd); - static MEDFileFieldPerMeshPerTypePerDisc *New(MEDFileFieldPerMeshPerType *fath, TypeOfField type, int locId); - static MEDFileFieldPerMeshPerTypePerDisc *New(const MEDFileFieldPerMeshPerTypePerDisc& other); - std::size_t getHeapMemorySizeWithoutChildren() const; - std::vector getDirectChildrenWithNull() const; - MEDFileFieldPerMeshPerTypePerDisc *deepCpy(MEDFileFieldPerMeshPerType *father) const; - void assignFieldNoProfile(int& start, int offset, int nbOfCells, const MEDCouplingFieldDouble *field, const DataArray *arrr, MEDFileFieldGlobsReal& glob, const MEDFileFieldNameScope& nasc); - void assignFieldProfile(bool isPflAlone, int& start, const DataArrayInt *multiTypePfl, const DataArrayInt *idsInPfl, DataArrayInt *locIds, int nbOfEltsInWholeMesh, const MEDCouplingFieldDouble *field, const DataArray *arrr, const MEDCouplingMesh *mesh, MEDFileFieldGlobsReal& glob, const MEDFileFieldNameScope& nasc); - void assignNodeFieldNoProfile(int& start, const MEDCouplingFieldDouble *field, const DataArray *arrr, MEDFileFieldGlobsReal& glob); - void getCoarseData(TypeOfField& type, std::pair& dad, std::string& pfl, std::string& loc) const; - void writeLL(med_idt fid, const MEDFileFieldNameScope& nasc) const; - const MEDFileFieldPerMeshPerType *getFather() const; - void loadOnlyStructureOfDataRecursively(med_idt fid, int& start, const MEDFileFieldNameScope& nasc); - void loadBigArray(med_idt fid, const MEDFileFieldNameScope& nasc); - void setNewStart(int newValueOfStart); - int getIteration() const; - int getOrder() const; - double getTime() const; - std::string getMeshName() const; - TypeOfField getType() const; - void simpleRepr(int bkOffset, std::ostream& oss, int id) const; - void fillTypesOfFieldAvailable(std::set& types) const; - void setType(TypeOfField newType); - INTERP_KERNEL::NormalizedCellType getGeoType() const; - int getNumberOfComponents() const; - int getNumberOfTuples() const; - int getStart() const { return _start; } - int getEnd() const { return _end; } - DataArray *getOrCreateAndGetArray(); - const DataArray *getOrCreateAndGetArray() const; - const std::vector& getInfo() const; - std::string getProfile() const; - void setProfile(const std::string& newPflName); - std::string getLocalization() const; - void setLocalization(const std::string& newLocName); - int getLocId() const { return _loc_id; } - void setLocId(int newId) const { _loc_id=newId; } - void setFather(MEDFileFieldPerMeshPerType *newFather) { _father=newFather; } - void changePflsRefsNamesGen(const std::vector< std::pair, std::string > >& mapOfModif); - void changeLocsRefsNamesGen(const std::vector< std::pair, std::string > >& mapOfModif); - void getFieldAtLevel(TypeOfField type, const MEDFileFieldGlobsReal *glob, std::vector< std::pair >& dads, std::vector& pfls, std::vector& locs, - std::vector& geoTypes) const; - void fillValues(int discId, int& startEntryId, std::vector< std::pair,std::pair > >& entries) const; - int fillEltIdsFromCode(int offset, const std::vector& codeOfMesh, const MEDFileFieldGlobsReal& glob, int *ptToFill) const; - int fillTupleIds(int *ptToFill) const; - static int ConvertType(TypeOfField type, int locId); - static std::vector< std::vector< const MEDFileFieldPerMeshPerTypePerDisc *> > SplitPerDiscretization(const std::vector< const MEDFileFieldPerMeshPerTypePerDisc *>& entries); - static bool RenumberChunks(int offset, const std::vector< const MEDFileFieldPerMeshPerTypePerDisc *>& entriesOnSameDisc, - const DataArrayInt *explicitIdsInMesh, const std::vector& newCode, - MEDFileFieldGlobsReal& glob, DataArrayDouble *arr, std::vector< MEDCouplingAutoRefCountObjectPtr >& result); - static MEDFileFieldPerMeshPerTypePerDisc *NewObjectOnSameDiscThanPool(TypeOfField typeF, INTERP_KERNEL::NormalizedCellType geoType, DataArrayInt *idsOfMeshElt, - bool isPfl, int nbi, int offset, std::list< const MEDFileFieldPerMeshPerTypePerDisc *>& entriesOnSameDisc, - MEDFileFieldGlobsReal& glob, bool ¬InExisting); - private: - MEDFileFieldPerMeshPerTypePerDisc(MEDFileFieldPerMeshPerType *fath, TypeOfField type, int profileIt, const PartDefinition *pd); - MEDFileFieldPerMeshPerTypePerDisc(MEDFileFieldPerMeshPerType *fath, TypeOfField type, int profileIt, const std::string& dummy); - MEDFileFieldPerMeshPerTypePerDisc(const MEDFileFieldPerMeshPerTypePerDisc& other); - MEDFileFieldPerMeshPerTypePerDisc(); - private: - void goReadZeValuesInFile(med_idt fid, const std::string& fieldName, int nbOfCompo, int iteration, int order, med_entity_type menti, med_geometry_type mgeoti, unsigned char *startFeedingPtr); - private: - TypeOfField _type; - MEDFileFieldPerMeshPerType *_father; - int _start; - int _end; - //! _nval is different than end-start in case of ON_GAUSS_PT and ON_GAUSS_NE ! (_nval=(_end-_start)/nbi) - int _nval; - std::string _profile; - std::string _localization; - //! only on assignement -3 : ON_NODES, -2 : ON_CELLS, -1 : ON_GAUSS_NE, 0..* : ON_GAUSS_PT - mutable int _loc_id; - mutable int _profile_it; - MEDCouplingAutoRefCountObjectPtr _pd; - public: - mutable int _tmp_work1; - }; - - class MEDFileFieldPerMeshPerType : public RefCountObject, public MEDFileWritable - { - public: - static MEDFileFieldPerMeshPerType *New(MEDFileFieldPerMesh *fath, INTERP_KERNEL::NormalizedCellType geoType); - static MEDFileFieldPerMeshPerType *NewOnRead(med_idt fid, MEDFileFieldPerMesh *fath, TypeOfField type, INTERP_KERNEL::NormalizedCellType geoType, const MEDFileFieldNameScope& nasc, const PartDefinition *pd); - std::size_t getHeapMemorySizeWithoutChildren() const; - std::vector getDirectChildrenWithNull() const; - MEDFileFieldPerMeshPerType *deepCpy(MEDFileFieldPerMesh *father) const; - void assignFieldNoProfile(int& start, int offset, int nbOfCells, const MEDCouplingFieldDouble *field, const DataArray *arr, MEDFileFieldGlobsReal& glob, const MEDFileFieldNameScope& nasc); - void assignFieldProfile(bool isPflAlone, int& start, const DataArrayInt *multiTypePfl, const DataArrayInt *idsInPfl, DataArrayInt *locIds, int nbOfEltsInWholeMesh, const MEDCouplingFieldDouble *field, const DataArray *arr, const MEDCouplingMesh *mesh, MEDFileFieldGlobsReal& glob, const MEDFileFieldNameScope& nasc); - void assignNodeFieldNoProfile(int& start, const MEDCouplingFieldDouble *field, const DataArray *arr, MEDFileFieldGlobsReal& glob); - void assignNodeFieldProfile(int& start, const DataArrayInt *pfl, const MEDCouplingFieldDouble *field, const DataArray *arr, MEDFileFieldGlobsReal& glob, const MEDFileFieldNameScope& nasc); - const MEDFileFieldPerMesh *getFather() const; - void loadOnlyStructureOfDataRecursively(med_idt fid, int &start, const MEDFileFieldNameScope& nasc); - void loadBigArraysRecursively(med_idt fid, const MEDFileFieldNameScope& nasc); - void writeLL(med_idt fid, const MEDFileFieldNameScope& nasc) const; - void getDimension(int& dim) const; - void fillTypesOfFieldAvailable(std::set& types) const; - void fillFieldSplitedByType(std::vector< std::pair >& dads, std::vector& types, std::vector& pfls, std::vector& locs) const; - int getIteration() const; - int getOrder() const; - double getTime() const; - std::string getMeshName() const; - void simpleRepr(int bkOffset, std::ostream& oss, int id) const; - void getSizes(int& globalSz, int& nbOfEntries) const; - INTERP_KERNEL::NormalizedCellType getGeoType() const; - int getNumberOfComponents() const; - bool presenceOfMultiDiscPerGeoType() const; - DataArray *getOrCreateAndGetArray(); - const DataArray *getOrCreateAndGetArray() const; - const std::vector& getInfo() const; - std::vector getPflsReallyUsed() const; - std::vector getLocsReallyUsed() const; - std::vector getPflsReallyUsedMulti() const; - std::vector getLocsReallyUsedMulti() const; - void changePflsRefsNamesGen(const std::vector< std::pair, std::string > >& mapOfModif); - void changeLocsRefsNamesGen(const std::vector< std::pair, std::string > >& mapOfModif); - MEDFileFieldPerMeshPerTypePerDisc *getLeafGivenLocId(int locId); - const MEDFileFieldPerMeshPerTypePerDisc *getLeafGivenLocId(int locId) const; - void getFieldAtLevel(int meshDim, TypeOfField type, const MEDFileFieldGlobsReal *glob, std::vector< std::pair >& dads, std::vector& pfls, std::vector& locs, std::vector& geoTypes) const; - void fillValues(int& startEntryId, std::vector< std::pair,std::pair > >& entries) const; - void setLeaves(const std::vector< MEDCouplingAutoRefCountObjectPtr< MEDFileFieldPerMeshPerTypePerDisc > >& leaves); - bool keepOnlySpatialDiscretization(TypeOfField tof, int &globalNum, std::vector< std::pair >& its); - bool keepOnlyGaussDiscretization(std::size_t idOfDisc, int &globalNum, std::vector< std::pair >& its); - static med_entity_type ConvertIntoMEDFileType(TypeOfField ikType, INTERP_KERNEL::NormalizedCellType ikGeoType, med_geometry_type& medfGeoType); - private: - std::vector addNewEntryIfNecessary(const MEDCouplingFieldDouble *field, int offset, int nbOfCells); - std::vector addNewEntryIfNecessaryGauss(const MEDCouplingFieldDouble *field, int offset, int nbOfCells); - std::vector addNewEntryIfNecessary(const MEDCouplingFieldDouble *field, const DataArrayInt *subCells); - std::vector addNewEntryIfNecessaryGauss(const MEDCouplingFieldDouble *field, const DataArrayInt *subCells); - MEDFileFieldPerMeshPerType(med_idt fid, MEDFileFieldPerMesh *fath, TypeOfField type, INTERP_KERNEL::NormalizedCellType geoType, const MEDFileFieldNameScope& nasc, const PartDefinition *pd); - MEDFileFieldPerMeshPerType(MEDFileFieldPerMesh *fath, INTERP_KERNEL::NormalizedCellType geoType); - private: - MEDFileFieldPerMesh *_father; - std::vector< MEDCouplingAutoRefCountObjectPtr > _field_pm_pt_pd; - INTERP_KERNEL::NormalizedCellType _geo_type; - }; - - class MEDFileMesh; - - class MEDFileFieldPerMesh : public RefCountObject, public MEDFileWritable - { - public: - static MEDFileFieldPerMesh *New(MEDFileAnyTypeField1TSWithoutSDA *fath, const MEDCouplingMesh *mesh); - static MEDFileFieldPerMesh *NewOnRead(med_idt fid, MEDFileAnyTypeField1TSWithoutSDA *fath, int meshCsit, int meshIteration, int meshOrder, const MEDFileFieldNameScope& nasc, const MEDFileMesh *mm, const std::vector< std::pair > *entities); - std::size_t getHeapMemorySizeWithoutChildren() const; - std::vector getDirectChildrenWithNull() const; - MEDFileFieldPerMesh *deepCpy(MEDFileAnyTypeField1TSWithoutSDA *father) const; - void simpleRepr(int bkOffset,std::ostream& oss, int id) const; - void copyTinyInfoFrom(const MEDCouplingMesh *mesh); - void assignFieldProfile(int& start, const DataArrayInt *multiTypePfl, const std::vector& code, const std::vector& code2, const std::vector& idsInPflPerType, const std::vector& idsPerType, const MEDCouplingFieldDouble *field, const DataArray *arr, const MEDCouplingMesh *mesh, MEDFileFieldGlobsReal& glob, const MEDFileFieldNameScope& nasc); - void assignFieldNoProfileNoRenum(int& start, const std::vector& code, const MEDCouplingFieldDouble *field, const DataArray *arr, MEDFileFieldGlobsReal& glob, const MEDFileFieldNameScope& nasc); - void assignNodeFieldNoProfile(int& start, const MEDCouplingFieldDouble *field, const DataArray *arr, MEDFileFieldGlobsReal& glob); - void assignNodeFieldProfile(int& start, const DataArrayInt *pfl, const MEDCouplingFieldDouble *field, const DataArray *arr, MEDFileFieldGlobsReal& glob, const MEDFileFieldNameScope& nasc); - void loadOnlyStructureOfDataRecursively(med_idt fid, int &start, const MEDFileFieldNameScope& nasc); - void loadBigArraysRecursively(med_idt fid, const MEDFileFieldNameScope& nasc); - void writeLL(med_idt fid, const MEDFileFieldNameScope& nasc) const; - void fillTypesOfFieldAvailable(std::set& types) const; - std::vector< std::vector< std::pair > > getFieldSplitedByType(std::vector& types, std::vector< std::vector >& typesF, std::vector< std::vector >& pfls, std::vector< std::vector >& locs) const; - void getDimension(int& dim) const; - double getTime() const; - int getIteration() const; - int getOrder() const; - int getMeshIteration() const { return _mesh_iteration; } - int getMeshOrder() const { return _mesh_order; } - std::string getMeshName() const { return _mesh_name; } - int getNumberOfComponents() const; - bool presenceOfMultiDiscPerGeoType() const; - DataArray *getOrCreateAndGetArray(); - const DataArray *getOrCreateAndGetArray() const; - const std::vector& getInfo() const; - std::vector getPflsReallyUsed() const; - std::vector getLocsReallyUsed() const; - std::vector getPflsReallyUsedMulti() const; - std::vector getLocsReallyUsedMulti() const; - bool changeMeshNames(const std::vector< std::pair >& modifTab); - bool renumberEntitiesLyingOnMesh(const std::string& meshName, const std::vector& oldCode, const std::vector& newCode, const DataArrayInt *renumO2N, MEDFileFieldGlobsReal& glob); - void keepOnlySpatialDiscretization(TypeOfField tof, int &globalNum, std::vector< std::pair >& its); - void keepOnlyGaussDiscretization(std::size_t idOfDisc, int &globalNum, std::vector< std::pair >& its); - void changePflsRefsNamesGen(const std::vector< std::pair, std::string > >& mapOfModif); - void changeLocsRefsNamesGen(const std::vector< std::pair, std::string > >& mapOfModif); - MEDCouplingFieldDouble *getFieldOnMeshAtLevel(TypeOfField type, const MEDFileFieldGlobsReal *glob, const MEDCouplingMesh *mesh, bool& isPfl, MEDCouplingAutoRefCountObjectPtr &arrOut, const MEDFileFieldNameScope& nasc) const; - DataArray *getFieldOnMeshAtLevelWithPfl(TypeOfField type, const MEDCouplingMesh *mesh, DataArrayInt *&pfl, const MEDFileFieldGlobsReal *glob, const MEDFileFieldNameScope& nasc) const; - void getUndergroundDataArrayExt(std::vector< std::pair,std::pair > >& entries) const; - MEDFileFieldPerMeshPerTypePerDisc *getLeafGivenTypeAndLocId(INTERP_KERNEL::NormalizedCellType typ, int locId); - const MEDFileFieldPerMeshPerTypePerDisc *getLeafGivenTypeAndLocId(INTERP_KERNEL::NormalizedCellType typ, int locId) const; - private: - int addNewEntryIfNecessary(INTERP_KERNEL::NormalizedCellType type); - MEDCouplingFieldDouble *finishField(TypeOfField type, const MEDFileFieldGlobsReal *glob, - const std::vector< std::pair >& dads, const std::vector& locs, const MEDCouplingMesh *mesh, bool& isPfl, MEDCouplingAutoRefCountObjectPtr &arrOut, const MEDFileFieldNameScope& nasc) const; - MEDCouplingFieldDouble *finishField2(TypeOfField type, const MEDFileFieldGlobsReal *glob, - const std::vector< std::pair >& dads, const std::vector& locs, - const std::vector& geoTypes, - const MEDCouplingMesh *mesh, const DataArrayInt *da, bool& isPfl, MEDCouplingAutoRefCountObjectPtr &arrOut, const MEDFileFieldNameScope& nasc) const; - MEDCouplingFieldDouble *finishFieldNode2(const MEDFileFieldGlobsReal *glob, - const std::vector< std::pair >& dads, const std::vector& locs, - const MEDCouplingMesh *mesh, const DataArrayInt *da, bool& isPfl, MEDCouplingAutoRefCountObjectPtr &arrOut, const MEDFileFieldNameScope& nasc) const; - DataArray *finishField4(const std::vector< std::pair >& dads, const DataArrayInt *pflIn, int nbOfElems, DataArrayInt *&pflOut) const; - void assignNewLeaves(const std::vector< MEDCouplingAutoRefCountObjectPtr< MEDFileFieldPerMeshPerTypePerDisc > >& leaves); - static void SortArraysPerType(const MEDFileFieldGlobsReal *glob, TypeOfField type, - const std::vector& geoTypes, const std::vector< std::pair >& dads, const std::vector& pfls, const std::vector& locs, - std::vector& code, std::vector& notNullPfls); - static int ComputeNbOfElems(const MEDFileFieldGlobsReal *glob, TypeOfField type, const std::vector& geoTypes, const std::vector< std::pair >& dads, const std::vector& locs); - MEDFileFieldPerMesh(med_idt fid, MEDFileAnyTypeField1TSWithoutSDA *fath, int meshCsit, int meshIteration, int meshOrder, const MEDFileFieldNameScope& nasc, const MEDFileMesh *mm, const std::vector< std::pair > *entities); - MEDFileFieldPerMesh(MEDFileAnyTypeField1TSWithoutSDA *fath, const MEDCouplingMesh *mesh); - private: - std::string _mesh_name; - int _mesh_iteration; - int _mesh_order; - MEDFileAnyTypeField1TSWithoutSDA *_father; - std::vector< MEDCouplingAutoRefCountObjectPtr< MEDFileFieldPerMeshPerType > > _field_pm_pt; - }; - - class MEDFileFieldGlobsReal; - - class MEDFileFieldGlobs : public RefCountObject - { - public: - static MEDFileFieldGlobs *New(const std::string& fname); - static MEDFileFieldGlobs *New(); - std::size_t getHeapMemorySizeWithoutChildren() const; - std::vector getDirectChildrenWithNull() const; - MEDFileFieldGlobs *deepCpy() const; - MEDFileFieldGlobs *shallowCpyPart(const std::vector& pfls, const std::vector& locs) const; - MEDFileFieldGlobs *deepCpyPart(const std::vector& pfls, const std::vector& locs) const; - void simpleRepr(std::ostream& oss) const; - void appendGlobs(const MEDFileFieldGlobs& other, double eps); - void checkGlobsPflsPartCoherency(const std::vector& pflsUsed) const; - void checkGlobsLocsPartCoherency(const std::vector& locsUsed) const; - void loadProfileInFile(med_idt fid, int id, const std::string& pflName); - void loadProfileInFile(med_idt fid, int id); - void loadGlobals(med_idt fid, const MEDFileFieldGlobsReal& real); - void loadAllGlobals(med_idt fid); - void writeGlobals(med_idt fid, const MEDFileWritable& opt) const; - std::vector getPfls() const; - std::vector getLocs() const; - bool existsPfl(const std::string& pflName) const; - bool existsLoc(const std::string& locName) const; - std::string createNewNameOfPfl() const; - std::string createNewNameOfLoc() const; - std::vector< std::vector > whichAreEqualProfiles() const; - std::vector< std::vector > whichAreEqualLocs(double eps) const; - void setFileName(const std::string& fileName); - void changePflsNamesInStruct(const std::vector< std::pair, std::string > >& mapOfModif); - void changeLocsNamesInStruct(const std::vector< std::pair, std::string > >& mapOfModif); - int getNbOfGaussPtPerCell(int locId) const; - int getLocalizationId(const std::string& loc) const; - std::string getFileName() const { return _file_name; } - const MEDFileFieldLoc& getLocalizationFromId(int locId) const; - const MEDFileFieldLoc& getLocalization(const std::string& locName) const; - const DataArrayInt *getProfileFromId(int pflId) const; - const DataArrayInt *getProfile(const std::string& pflName) const; - MEDFileFieldLoc& getLocalizationFromId(int locId); - MEDFileFieldLoc& getLocalization(const std::string& locName); - DataArrayInt *getProfile(const std::string& pflName); - DataArrayInt *getProfileFromId(int pflId); - void killProfileIds(const std::vector& pflIds); - void killLocalizationIds(const std::vector& locIds); - // - void appendProfile(DataArrayInt *pfl); - void appendLoc(const std::string& locName, INTERP_KERNEL::NormalizedCellType geoType, const std::vector& refCoo, const std::vector& gsCoo, const std::vector& w); - // - static std::string CreateNewNameNotIn(const std::string& prefix, const std::vector& namesToAvoid); - protected: - MEDFileFieldGlobs(const std::string& fname); - MEDFileFieldGlobs(); - ~MEDFileFieldGlobs(); - protected: - std::vector< MEDCouplingAutoRefCountObjectPtr > _pfls; - std::vector< MEDCouplingAutoRefCountObjectPtr > _locs; - std::string _file_name; - }; - - /// @endcond INTERNAL - - class MEDFileFieldGlobsReal - { - public: - MEDLOADER_EXPORT MEDFileFieldGlobsReal(const std::string& fname); - MEDLOADER_EXPORT MEDFileFieldGlobsReal(); - MEDLOADER_EXPORT std::size_t getHeapMemorySizeWithoutChildren() const; - MEDLOADER_EXPORT std::vector getDirectChildrenWithNull() const; - MEDLOADER_EXPORT void simpleReprGlobs(std::ostream& oss) const; - MEDLOADER_EXPORT void resetContent(); - MEDLOADER_EXPORT void shallowCpyGlobs(const MEDFileFieldGlobsReal& other); - MEDLOADER_EXPORT void deepCpyGlobs(const MEDFileFieldGlobsReal& other); - MEDLOADER_EXPORT void shallowCpyOnlyUsedGlobs(const MEDFileFieldGlobsReal& other); - MEDLOADER_EXPORT void deepCpyOnlyUsedGlobs(const MEDFileFieldGlobsReal& other); - MEDLOADER_EXPORT void appendGlobs(const MEDFileFieldGlobsReal& other, double eps); - MEDLOADER_EXPORT void checkGlobsCoherency() const; - MEDLOADER_EXPORT void checkGlobsPflsPartCoherency() const; - MEDLOADER_EXPORT void checkGlobsLocsPartCoherency() const; - MEDLOADER_EXPORT virtual std::vector getPflsReallyUsed() const = 0; - MEDLOADER_EXPORT virtual std::vector getLocsReallyUsed() const = 0; - MEDLOADER_EXPORT virtual std::vector getPflsReallyUsedMulti() const = 0; - MEDLOADER_EXPORT virtual std::vector getLocsReallyUsedMulti() const = 0; - MEDLOADER_EXPORT virtual void changePflsRefsNamesGen(const std::vector< std::pair, std::string > >& mapOfModif) = 0; - MEDLOADER_EXPORT virtual void changeLocsRefsNamesGen(const std::vector< std::pair, std::string > >& mapOfModif) = 0; - MEDLOADER_EXPORT virtual ~MEDFileFieldGlobsReal(); - // - MEDLOADER_EXPORT void loadProfileInFile(med_idt fid, int id, const std::string& pflName); - MEDLOADER_EXPORT void loadProfileInFile(med_idt fid, int id); - MEDLOADER_EXPORT void loadGlobals(med_idt fid); - MEDLOADER_EXPORT void loadAllGlobals(med_idt fid); - MEDLOADER_EXPORT void writeGlobals(med_idt fid, const MEDFileWritable& opt) const; - MEDLOADER_EXPORT std::vector getPfls() const; - MEDLOADER_EXPORT std::vector getLocs() const; - MEDLOADER_EXPORT bool existsPfl(const std::string& pflName) const; - MEDLOADER_EXPORT bool existsLoc(const std::string& locName) const; - MEDLOADER_EXPORT std::string createNewNameOfPfl() const; - MEDLOADER_EXPORT std::string createNewNameOfLoc() const; - MEDLOADER_EXPORT std::vector< std::vector > whichAreEqualProfiles() const; - MEDLOADER_EXPORT std::vector< std::vector > whichAreEqualLocs(double eps) const; - MEDLOADER_EXPORT void setFileName(const std::string& fileName); - MEDLOADER_EXPORT void changePflsNamesInStruct(const std::vector< std::pair, std::string > >& mapOfModif); - MEDLOADER_EXPORT void changeLocsNamesInStruct(const std::vector< std::pair, std::string > >& mapOfModif); - MEDLOADER_EXPORT void changePflsNames(const std::vector< std::pair, std::string > >& mapOfModif); - MEDLOADER_EXPORT void changeLocsNames(const std::vector< std::pair, std::string > >& mapOfModif); - MEDLOADER_EXPORT void changePflName(const std::string& oldName, const std::string& newName); - MEDLOADER_EXPORT void changeLocName(const std::string& oldName, const std::string& newName); - MEDLOADER_EXPORT std::vector< std::pair, std::string > > zipPflsNames(); - MEDLOADER_EXPORT std::vector< std::pair, std::string > > zipLocsNames(double eps); - MEDLOADER_EXPORT int getNbOfGaussPtPerCell(int locId) const; - MEDLOADER_EXPORT int getLocalizationId(const std::string& loc) const; - MEDLOADER_EXPORT std::string getFileName() const; - MEDLOADER_EXPORT const MEDFileFieldLoc& getLocalizationFromId(int locId) const; - MEDLOADER_EXPORT const MEDFileFieldLoc& getLocalization(const std::string& locName) const; - MEDLOADER_EXPORT MEDFileFieldLoc& getLocalizationFromId(int locId); - MEDLOADER_EXPORT MEDFileFieldLoc& getLocalization(const std::string& locName); - MEDLOADER_EXPORT const DataArrayInt *getProfile(const std::string& pflName) const; - MEDLOADER_EXPORT const DataArrayInt *getProfileFromId(int pflId) const; - MEDLOADER_EXPORT DataArrayInt *getProfile(const std::string& pflName); - MEDLOADER_EXPORT DataArrayInt *getProfileFromId(int pflId); - MEDLOADER_EXPORT void killProfileIds(const std::vector& pflIds); - MEDLOADER_EXPORT void killLocalizationIds(const std::vector& locIds); - // - MEDLOADER_EXPORT void appendProfile(DataArrayInt *pfl); - MEDLOADER_EXPORT void appendLoc(const std::string& locName, INTERP_KERNEL::NormalizedCellType geoType, const std::vector& refCoo, const std::vector& gsCoo, const std::vector& w); - protected: - MEDFileFieldGlobs *contentNotNull(); - const MEDFileFieldGlobs *contentNotNull() const; - protected: - MEDCouplingAutoRefCountObjectPtr< MEDFileFieldGlobs > _globals; - }; - - class MEDFileFieldNameScope - { - public: - MEDLOADER_EXPORT MEDFileFieldNameScope(); - MEDLOADER_EXPORT MEDFileFieldNameScope(const std::string& fieldName); - MEDLOADER_EXPORT std::string getName() const; - MEDLOADER_EXPORT void setName(const std::string& fieldName); - MEDLOADER_EXPORT std::string getDtUnit() const; - MEDLOADER_EXPORT void setDtUnit(const std::string& dtUnit); - MEDLOADER_EXPORT void copyNameScope(const MEDFileFieldNameScope& other); - protected: - std::string _name; - std::string _dt_unit; - }; - - class MEDFileMeshes; - - /*! - * SDA is for Shared Data Arrays such as profiles. - */ - class MEDFileAnyTypeField1TSWithoutSDA : public RefCountObject, public MEDFileFieldNameScope - { - public: - MEDLOADER_EXPORT MEDFileAnyTypeField1TSWithoutSDA(); - MEDLOADER_EXPORT MEDFileAnyTypeField1TSWithoutSDA(const std::string& fieldName, int csit, int iteration, int order); - MEDLOADER_EXPORT int getIteration() const { return _iteration; } - MEDLOADER_EXPORT int getOrder() const { return _order; } - MEDLOADER_EXPORT double getTime(int& iteration, int& order) const { iteration=_iteration; order=_order; return _dt; } - MEDLOADER_EXPORT void setTime(int iteration, int order, double val) { _dt=val; _iteration=iteration; _order=order; } - MEDLOADER_EXPORT int getDimension() const; - MEDLOADER_EXPORT std::string getMeshName() const; - MEDLOADER_EXPORT void setMeshName(const std::string& newMeshName); - MEDLOADER_EXPORT bool changeMeshNames(const std::vector< std::pair >& modifTab); - MEDLOADER_EXPORT int getMeshIteration() const; - MEDLOADER_EXPORT int getMeshOrder() const; - MEDLOADER_EXPORT bool isDealingTS(int iteration, int order) const; - MEDLOADER_EXPORT std::pair getDtIt() const; - MEDLOADER_EXPORT void fillIteration(std::pair& p) const; - MEDLOADER_EXPORT void fillTypesOfFieldAvailable(std::vector& types) const; - MEDLOADER_EXPORT std::vector getTypesOfFieldAvailable() const; - // - MEDLOADER_EXPORT std::vector getPflsReallyUsed2() const; - MEDLOADER_EXPORT std::vector getLocsReallyUsed2() const; - MEDLOADER_EXPORT std::vector getPflsReallyUsedMulti2() const; - MEDLOADER_EXPORT std::vector getLocsReallyUsedMulti2() const; - MEDLOADER_EXPORT void changePflsRefsNamesGen2(const std::vector< std::pair, std::string > >& mapOfModif); - MEDLOADER_EXPORT void changeLocsRefsNamesGen2(const std::vector< std::pair, std::string > >& mapOfModif); - // - MEDLOADER_EXPORT int getNonEmptyLevels(const std::string& mname, std::vector& levs) const; - MEDLOADER_EXPORT std::vector< std::vector > > getFieldSplitedByType(const std::string& mname, std::vector& types, std::vector< std::vector >& typesF, std::vector< std::vector >& pfls, std::vector< std::vector >& locs) const; - // - MEDLOADER_EXPORT MEDFileFieldPerMeshPerTypePerDisc *getLeafGivenMeshAndTypeAndLocId(const std::string& mName, INTERP_KERNEL::NormalizedCellType typ, int locId); - MEDLOADER_EXPORT const MEDFileFieldPerMeshPerTypePerDisc *getLeafGivenMeshAndTypeAndLocId(const std::string& mName, INTERP_KERNEL::NormalizedCellType typ, int locId) const; - MEDLOADER_EXPORT void deepCpyLeavesFrom(const MEDFileAnyTypeField1TSWithoutSDA& other); - public: - MEDLOADER_EXPORT int getNumberOfComponents() const; - MEDLOADER_EXPORT const std::vector& getInfo() const; - MEDLOADER_EXPORT std::vector& getInfo(); - MEDLOADER_EXPORT bool presenceOfMultiDiscPerGeoType() const; - MEDLOADER_EXPORT void setInfo(const std::vector& infos); - MEDLOADER_EXPORT std::size_t getHeapMemorySizeWithoutChildren() const; - MEDLOADER_EXPORT std::vector getDirectChildrenWithNull() const; - MEDLOADER_EXPORT int copyTinyInfoFrom(const MEDCouplingFieldDouble *field, const DataArray *arr); - MEDLOADER_EXPORT void setFieldNoProfileSBT(const MEDCouplingFieldDouble *field, const DataArray *arr, MEDFileFieldGlobsReal& glob, const MEDFileFieldNameScope& nasc); - MEDLOADER_EXPORT void setFieldProfile(const MEDCouplingFieldDouble *field, const DataArray *arrOfVals, const MEDFileMesh *mesh, int meshDimRelToMax, const DataArrayInt *profile, MEDFileFieldGlobsReal& glob, const MEDFileFieldNameScope& nasc); - MEDLOADER_EXPORT virtual void simpleRepr(int bkOffset, std::ostream& oss, int f1tsId) const; - MEDLOADER_EXPORT virtual MEDFileAnyTypeField1TSWithoutSDA *deepCpy() const = 0; - MEDLOADER_EXPORT virtual MEDFileAnyTypeField1TSWithoutSDA *shallowCpy() const = 0; - MEDLOADER_EXPORT virtual std::vector< MEDCouplingAutoRefCountObjectPtr > splitComponents() const; - MEDLOADER_EXPORT virtual const char *getTypeStr() const = 0; - MEDLOADER_EXPORT virtual DataArray *getUndergroundDataArray() const = 0; - MEDLOADER_EXPORT virtual DataArray *getUndergroundDataArrayExt(std::vector< std::pair,std::pair > >& entries) const = 0; - MEDLOADER_EXPORT virtual void setArray(DataArray *arr) = 0; - MEDLOADER_EXPORT virtual DataArray *createNewEmptyDataArrayInstance() const = 0; - MEDLOADER_EXPORT virtual DataArray *getOrCreateAndGetArray() = 0; - MEDLOADER_EXPORT virtual const DataArray *getOrCreateAndGetArray() const = 0; - public: - MEDLOADER_EXPORT MEDCouplingFieldDouble *getFieldAtLevel(TypeOfField type, int meshDimRelToMax, const std::string& mName, int renumPol, const MEDFileFieldGlobsReal *glob, MEDCouplingAutoRefCountObjectPtr &arrOut, const MEDFileFieldNameScope& nasc) const; - MEDLOADER_EXPORT MEDCouplingFieldDouble *getFieldOnMeshAtLevel(TypeOfField type, int meshDimRelToMax, int renumPol, const MEDFileFieldGlobsReal *glob, const MEDFileMesh *mesh, MEDCouplingAutoRefCountObjectPtr &arrOut, const MEDFileFieldNameScope& nasc) const; - MEDLOADER_EXPORT MEDCouplingFieldDouble *getFieldAtTopLevel(TypeOfField type, const std::string& mName, int renumPol, const MEDFileFieldGlobsReal *glob, MEDCouplingAutoRefCountObjectPtr &arrOut, const MEDFileFieldNameScope& nasc) const; - MEDLOADER_EXPORT MEDCouplingFieldDouble *getFieldOnMeshAtLevel(TypeOfField type, int renumPol, const MEDFileFieldGlobsReal *glob, const MEDCouplingMesh *mesh, const DataArrayInt *cellRenum, const DataArrayInt *nodeRenum, MEDCouplingAutoRefCountObjectPtr &arrOut, const MEDFileFieldNameScope& nasc) const; - DataArray *getFieldWithProfile(TypeOfField type, int meshDimRelToMax, const MEDFileMesh *mesh, DataArrayInt *&pfl, const MEDFileFieldGlobsReal *glob, const MEDFileFieldNameScope& nasc) const; - public: - MEDLOADER_EXPORT bool renumberEntitiesLyingOnMesh(const std::string& meshName, const std::vector& oldCode, const std::vector& newCode, const DataArrayInt *renumO2N, MEDFileFieldGlobsReal& glob); - MEDLOADER_EXPORT std::vector< MEDCouplingAutoRefCountObjectPtr > splitDiscretizations() const; - MEDLOADER_EXPORT std::vector< MEDCouplingAutoRefCountObjectPtr > splitMultiDiscrPerGeoTypes() const; - MEDLOADER_EXPORT int keepOnlySpatialDiscretization(TypeOfField tof, std::vector< std::pair >& its); - MEDLOADER_EXPORT int keepOnlyGaussDiscretization(std::size_t idOfDisc, std::vector< std::pair >& its); - public: - MEDLOADER_EXPORT void allocNotFromFile(int newNbOfTuples); - MEDLOADER_EXPORT bool allocIfNecessaryTheArrayToReceiveDataFromFile(); - MEDLOADER_EXPORT void loadOnlyStructureOfDataRecursively(med_idt fid, const MEDFileFieldNameScope& nasc, const MEDFileMeshes *ms, const std::vector< std::pair > *entities); - MEDLOADER_EXPORT void loadBigArraysRecursively(med_idt fid, const MEDFileFieldNameScope& nasc); - MEDLOADER_EXPORT void loadBigArraysRecursivelyIfNecessary(med_idt fid, const MEDFileFieldNameScope& nasc); - MEDLOADER_EXPORT void loadStructureAndBigArraysRecursively(med_idt fid, const MEDFileFieldNameScope& nasc, const MEDFileMeshes *ms, const std::vector< std::pair > *entities); - MEDLOADER_EXPORT void unloadArrays(); - MEDLOADER_EXPORT void writeLL(med_idt fid, const MEDFileWritable& opts, const MEDFileFieldNameScope& nasc) const; - protected: - int getMeshIdFromMeshName(const std::string& mName) const; - int addNewEntryIfNecessary(const MEDCouplingMesh *mesh); - void updateData(int newLgth, const std::vector< std::pair >& oldStartStops); - protected: - std::vector< MEDCouplingAutoRefCountObjectPtr< MEDFileFieldPerMesh > > _field_per_mesh; - int _iteration; - int _order; - double _dt; - public: - //! only useable on reading - mutable int _csit; - // -3 means allocated and build from scratch - // -2 means allocated and read from a file - // -1 means not allocated and build from scratch - // >=0 means not allocated and read from a file - mutable int _nb_of_tuples_to_be_allocated; - }; - - class MEDFileIntField1TSWithoutSDA; - - /*! - * SDA is for Shared Data Arrays such as profiles. - */ - class MEDFileField1TSWithoutSDA : public MEDFileAnyTypeField1TSWithoutSDA - { - public: - MEDLOADER_EXPORT const char *getTypeStr() const; - MEDLOADER_EXPORT DataArray *getUndergroundDataArray() const; - MEDLOADER_EXPORT DataArray *getUndergroundDataArrayExt(std::vector< std::pair,std::pair > >& entries) const; - MEDLOADER_EXPORT DataArrayDouble *getUndergroundDataArrayDouble() const; - MEDLOADER_EXPORT DataArrayDouble *getUndergroundDataArrayDoubleExt(std::vector< std::pair,std::pair > >& entries) const; - MEDLOADER_EXPORT std::vector< std::vector > getFieldSplitedByType2(const std::string& mname, std::vector& types, std::vector< std::vector >& typesF, std::vector< std::vector >& pfls, std::vector< std::vector >& locs) const; - MEDLOADER_EXPORT static void CheckMeshDimRel(int meshDimRelToMax); - MEDLOADER_EXPORT static std::vector CheckSBTMesh(const MEDCouplingMesh *mesh); - MEDLOADER_EXPORT static MEDFileField1TSWithoutSDA *New(const std::string& fieldName, int csit, int iteration, int order, const std::vector& infos); - public: - MEDLOADER_EXPORT MEDFileField1TSWithoutSDA(); - MEDLOADER_EXPORT MEDFileField1TSWithoutSDA(const std::string& fieldName, int csit, int iteration, int order, const std::vector& infos); - MEDLOADER_EXPORT MEDFileAnyTypeField1TSWithoutSDA *shallowCpy() const; - MEDLOADER_EXPORT MEDFileAnyTypeField1TSWithoutSDA *deepCpy() const; - MEDLOADER_EXPORT void setArray(DataArray *arr); - MEDLOADER_EXPORT DataArray *createNewEmptyDataArrayInstance() const; - MEDLOADER_EXPORT DataArray *getOrCreateAndGetArray(); - MEDLOADER_EXPORT const DataArray *getOrCreateAndGetArray() const; - MEDLOADER_EXPORT DataArrayDouble *getOrCreateAndGetArrayDouble(); - MEDLOADER_EXPORT const DataArrayDouble *getOrCreateAndGetArrayDouble() const; - MEDLOADER_EXPORT MEDFileIntField1TSWithoutSDA *convertToInt() const; - protected: - MEDCouplingAutoRefCountObjectPtr< DataArrayDouble > _arr; - public: - static const char TYPE_STR[]; - }; - - /*! - * SDA is for Shared Data Arrays such as profiles. - */ - class MEDFileIntField1TSWithoutSDA : public MEDFileAnyTypeField1TSWithoutSDA - { - public: - MEDLOADER_EXPORT MEDFileIntField1TSWithoutSDA(); - MEDLOADER_EXPORT static MEDFileIntField1TSWithoutSDA *New(const std::string& fieldName, int csit, int iteration, int order, const std::vector& infos); - MEDLOADER_EXPORT MEDFileAnyTypeField1TSWithoutSDA *deepCpy() const; - MEDLOADER_EXPORT MEDFileAnyTypeField1TSWithoutSDA *shallowCpy() const; - MEDLOADER_EXPORT const char *getTypeStr() const; - MEDLOADER_EXPORT DataArray *getUndergroundDataArray() const; - MEDLOADER_EXPORT DataArray *getUndergroundDataArrayExt(std::vector< std::pair,std::pair > >& entries) const; - MEDLOADER_EXPORT void setArray(DataArray *arr); - MEDLOADER_EXPORT DataArray *createNewEmptyDataArrayInstance() const; - MEDLOADER_EXPORT DataArray *getOrCreateAndGetArray(); - MEDLOADER_EXPORT const DataArray *getOrCreateAndGetArray() const; - MEDLOADER_EXPORT DataArrayInt *getOrCreateAndGetArrayInt(); - MEDLOADER_EXPORT const DataArrayInt *getOrCreateAndGetArrayInt() const; - MEDLOADER_EXPORT DataArrayInt *getUndergroundDataArrayInt() const; - MEDLOADER_EXPORT DataArrayInt *getUndergroundDataArrayIntExt(std::vector< std::pair,std::pair > >& entries) const; - MEDLOADER_EXPORT MEDFileField1TSWithoutSDA *convertToDouble() const; - protected: - MEDFileIntField1TSWithoutSDA(const std::string& fieldName, int csit, int iteration, int order, const std::vector& infos); - protected: - MEDCouplingAutoRefCountObjectPtr< DataArrayInt > _arr; - public: - MEDLOADER_EXPORT static const char TYPE_STR[]; - }; - - /*! - * User class. - */ - class MEDFileAnyTypeField1TS : public RefCountObject, public MEDFileWritable, public MEDFileFieldGlobsReal - { - protected: - MEDLOADER_EXPORT MEDFileAnyTypeField1TS(); - MEDLOADER_EXPORT MEDFileAnyTypeField1TS(const std::string& fileName, bool loadAll, const MEDFileMeshes *ms); - MEDLOADER_EXPORT MEDFileAnyTypeField1TS(const std::string& fileName, const std::string& fieldName, bool loadAll, const MEDFileMeshes *ms); - MEDLOADER_EXPORT MEDFileAnyTypeField1TS(const std::string& fileName, const std::string& fieldName, int iteration, int order, bool loadAll, const MEDFileMeshes *ms); - MEDLOADER_EXPORT MEDFileAnyTypeField1TS(const MEDFileAnyTypeField1TSWithoutSDA& other, bool shallowCopyOfContent); - MEDLOADER_EXPORT static MEDFileAnyTypeField1TS *BuildNewInstanceFromContent(MEDFileAnyTypeField1TSWithoutSDA *c, const std::string& fileName); - MEDLOADER_EXPORT static MEDFileAnyTypeField1TSWithoutSDA *BuildContentFrom(med_idt fid, const std::string& fileName, bool loadAll, const MEDFileMeshes *ms); - MEDLOADER_EXPORT static MEDFileAnyTypeField1TSWithoutSDA *BuildContentFrom(med_idt fid, const std::string& fileName, const std::string& fieldName, bool loadAll, const MEDFileMeshes *ms); - MEDLOADER_EXPORT static MEDFileAnyTypeField1TSWithoutSDA *BuildContentFrom(med_idt fid, const std::string& fileName, const std::string& fieldName, int iteration, int order, bool loadAll, const MEDFileMeshes *ms); - MEDLOADER_EXPORT void writeLL(med_idt fid) const; - // direct forwarding to MEDFileAnyTypeField1TSWithoutSDA instance _content - public: - MEDLOADER_EXPORT static MEDFileAnyTypeField1TS *New(const std::string& fileName, bool loadAll=true); - MEDLOADER_EXPORT static MEDFileAnyTypeField1TS *New(const std::string& fileName, const std::string& fieldName, bool loadAll=true); - MEDLOADER_EXPORT static MEDFileAnyTypeField1TS *New(const std::string& fileName, const std::string& fieldName, int iteration, int order, bool loadAll=true); - MEDLOADER_EXPORT int getDimension() const; - MEDLOADER_EXPORT int getIteration() const; - MEDLOADER_EXPORT int getOrder() const; - MEDLOADER_EXPORT double getTime(int& iteration, int& order) const; - MEDLOADER_EXPORT void setTime(int iteration, int order, double val); - MEDLOADER_EXPORT std::string getName() const; - MEDLOADER_EXPORT void setName(const std::string& name); - MEDLOADER_EXPORT std::string simpleRepr() const; - MEDLOADER_EXPORT void simpleRepr(int bkOffset, std::ostream& oss, int f1tsId) const; - MEDLOADER_EXPORT std::string getDtUnit() const; - MEDLOADER_EXPORT void setDtUnit(const std::string& dtUnit); - MEDLOADER_EXPORT std::string getMeshName() const; - MEDLOADER_EXPORT void setMeshName(const std::string& newMeshName); - MEDLOADER_EXPORT bool changeMeshNames(const std::vector< std::pair >& modifTab); - MEDLOADER_EXPORT int getMeshIteration() const; - MEDLOADER_EXPORT int getMeshOrder() const; - MEDLOADER_EXPORT int getNumberOfComponents() const; - MEDLOADER_EXPORT bool isDealingTS(int iteration, int order) const; - MEDLOADER_EXPORT std::pair getDtIt() const; - MEDLOADER_EXPORT void fillIteration(std::pair& p) const; - MEDLOADER_EXPORT void fillTypesOfFieldAvailable(std::vector& types) const; - MEDLOADER_EXPORT void setInfo(const std::vector& infos); - MEDLOADER_EXPORT const std::vector& getInfo() const; - MEDLOADER_EXPORT std::vector& getInfo(); - MEDLOADER_EXPORT bool presenceOfMultiDiscPerGeoType() const; - MEDLOADER_EXPORT std::vector getTypesOfFieldAvailable() const; - MEDLOADER_EXPORT std::vector< std::vector > > getFieldSplitedByType(const std::string& mname, std::vector& types, std::vector< std::vector >& typesF, - std::vector< std::vector >& pfls, std::vector< std::vector >& locs) const; - MEDLOADER_EXPORT MEDFileFieldPerMeshPerTypePerDisc *getLeafGivenMeshAndTypeAndLocId(const std::string& mName, INTERP_KERNEL::NormalizedCellType typ, int locId); - MEDLOADER_EXPORT const MEDFileFieldPerMeshPerTypePerDisc *getLeafGivenMeshAndTypeAndLocId(const std::string& mName, INTERP_KERNEL::NormalizedCellType typ, int locId) const; - MEDLOADER_EXPORT int getNonEmptyLevels(const std::string& mname, std::vector& levs) const; - public: - MEDLOADER_EXPORT void write(const std::string& fileName, int mode) const; - MEDLOADER_EXPORT void loadArrays(); - MEDLOADER_EXPORT void loadArraysIfNecessary(); - MEDLOADER_EXPORT void unloadArrays(); - MEDLOADER_EXPORT void unloadArraysWithoutDataLoss(); - MEDLOADER_EXPORT std::vector< MEDCouplingAutoRefCountObjectPtr< MEDFileAnyTypeField1TS > > splitComponents() const; - MEDLOADER_EXPORT std::vector< MEDCouplingAutoRefCountObjectPtr< MEDFileAnyTypeField1TS > > splitDiscretizations() const; - MEDLOADER_EXPORT std::vector< MEDCouplingAutoRefCountObjectPtr< MEDFileAnyTypeField1TS > > splitMultiDiscrPerGeoTypes() const; - MEDLOADER_EXPORT MEDFileAnyTypeField1TS *deepCpy() const; - MEDLOADER_EXPORT int copyTinyInfoFrom(const MEDCouplingFieldDouble *field, const DataArray *arr); - MEDLOADER_EXPORT virtual MEDFileAnyTypeField1TS *shallowCpy() const = 0; - public: - //! underground method see MEDFileField1TSWithoutSDA::setProfileNameOnLeaf - MEDLOADER_EXPORT void setProfileNameOnLeaf(const std::string& mName, INTERP_KERNEL::NormalizedCellType typ, int locId, const std::string& newPflName, bool forceRenameOnGlob=false); - //! underground method see MEDFileField1TSWithoutSDA::setLocNameOnLeaf - MEDLOADER_EXPORT void setLocNameOnLeaf(const std::string& mName, INTERP_KERNEL::NormalizedCellType typ, int locId, const std::string& newLocName, bool forceRenameOnGlob=false); - MEDLOADER_EXPORT std::size_t getHeapMemorySizeWithoutChildren() const; - MEDLOADER_EXPORT std::vector getDirectChildrenWithNull() const; - MEDLOADER_EXPORT std::vector getPflsReallyUsed() const; - MEDLOADER_EXPORT std::vector getLocsReallyUsed() const; - MEDLOADER_EXPORT std::vector getPflsReallyUsedMulti() const; - MEDLOADER_EXPORT std::vector getLocsReallyUsedMulti() const; - MEDLOADER_EXPORT void changePflsRefsNamesGen(const std::vector< std::pair, std::string > >& mapOfModif); - MEDLOADER_EXPORT void changeLocsRefsNamesGen(const std::vector< std::pair, std::string > >& mapOfModif); - public: - MEDLOADER_EXPORT static int LocateField2(med_idt fid, const std::string& fileName, int fieldIdCFormat, bool checkFieldId, std::string& fieldName, med_field_type& typcha, std::vector& infos, std::string& dtunitOut); - MEDLOADER_EXPORT static int LocateField(med_idt fid, const std::string& fileName, const std::string& fieldName, int& posCFormat, med_field_type& typcha, std::vector& infos, std::string& dtunitOut); - public: - MEDLOADER_EXPORT virtual med_field_type getMEDFileFieldType() const = 0; - MEDLOADER_EXPORT MEDFileAnyTypeField1TSWithoutSDA *contentNotNullBase(); - MEDLOADER_EXPORT const MEDFileAnyTypeField1TSWithoutSDA *contentNotNullBase() const; - protected: - MEDCouplingAutoRefCountObjectPtr _content; - }; - - class MEDFileIntField1TS; - - /*! - * User class. - */ - class MEDFileField1TS : public MEDFileAnyTypeField1TS - { - public: - MEDLOADER_EXPORT static MEDFileField1TS *New(const std::string& fileName, bool loadAll=true); - MEDLOADER_EXPORT static MEDFileField1TS *New(const std::string& fileName, const std::string& fieldName, bool loadAll=true); - MEDLOADER_EXPORT static MEDFileField1TS *New(const std::string& fileName, const std::string& fieldName, int iteration, int order, bool loadAll=true); - MEDLOADER_EXPORT static MEDFileField1TS *New(const MEDFileField1TSWithoutSDA& other, bool shallowCopyOfContent); - MEDLOADER_EXPORT static MEDFileField1TS *New(); - MEDLOADER_EXPORT MEDFileIntField1TS *convertToInt(bool isDeepCpyGlobs=true) const; - // - MEDLOADER_EXPORT MEDCouplingFieldDouble *getFieldAtLevel(TypeOfField type, int meshDimRelToMax, int renumPol=0) const; - MEDLOADER_EXPORT MEDCouplingFieldDouble *getFieldAtTopLevel(TypeOfField type, int renumPol=0) const; - MEDLOADER_EXPORT MEDCouplingFieldDouble *getFieldOnMeshAtLevel(TypeOfField type, int meshDimRelToMax, const MEDFileMesh *mesh, int renumPol=0) const; - MEDLOADER_EXPORT MEDCouplingFieldDouble *getFieldOnMeshAtLevel(TypeOfField type, const MEDCouplingMesh *mesh, int renumPol=0) const; - MEDLOADER_EXPORT MEDCouplingFieldDouble *getFieldAtLevelOld(TypeOfField type, const std::string& mname, int meshDimRelToMax, int renumPol=0) const; - MEDLOADER_EXPORT DataArrayDouble *getFieldWithProfile(TypeOfField type, int meshDimRelToMax, const MEDFileMesh *mesh, DataArrayInt *&pfl) const; - // - MEDLOADER_EXPORT void setFieldNoProfileSBT(const MEDCouplingFieldDouble *field); - MEDLOADER_EXPORT void setFieldProfile(const MEDCouplingFieldDouble *field, const MEDFileMesh *mesh, int meshDimRelToMax, const DataArrayInt *profile); - // direct forwarding to MEDFileField1TSWithoutSDA instance _content - public: - MEDLOADER_EXPORT MEDFileAnyTypeField1TS *shallowCpy() const; - MEDLOADER_EXPORT DataArrayDouble *getUndergroundDataArray() const; - MEDLOADER_EXPORT DataArrayDouble *getUndergroundDataArrayExt(std::vector< std::pair,std::pair > >& entries) const; - - MEDLOADER_EXPORT std::vector< std::vector > getFieldSplitedByType2(const std::string& mname, std::vector& types, std::vector< std::vector >& typesF, - std::vector< std::vector >& pfls, std::vector< std::vector >& locs) const; - public: - MEDLOADER_EXPORT static void SetDataArrayDoubleInField(MEDCouplingFieldDouble *f, MEDCouplingAutoRefCountObjectPtr& arr); - MEDLOADER_EXPORT static DataArrayDouble *ReturnSafelyDataArrayDouble(MEDCouplingAutoRefCountObjectPtr& arr); - private: - med_field_type getMEDFileFieldType() const { return MED_FLOAT64; } - const MEDFileField1TSWithoutSDA *contentNotNull() const; - MEDFileField1TSWithoutSDA *contentNotNull(); - private: - ~MEDFileField1TS() { } - MEDFileField1TS(const std::string& fileName, bool loadAll, const MEDFileMeshes *ms); - MEDFileField1TS(const std::string& fileName, const std::string& fieldName, bool loadAll, const MEDFileMeshes *ms); - MEDFileField1TS(const std::string& fileName, const std::string& fieldName, int iteration, int order, bool loadAll, const MEDFileMeshes *ms); - MEDFileField1TS(const MEDFileField1TSWithoutSDA& other, bool shallowCopyOfContent); - MEDFileField1TS(); - }; - - class MEDFileIntField1TS : public MEDFileAnyTypeField1TS - { - public: - MEDLOADER_EXPORT static MEDFileIntField1TS *New(); - MEDLOADER_EXPORT static MEDFileIntField1TS *New(const std::string& fileName, bool loadAll=true); - MEDLOADER_EXPORT static MEDFileIntField1TS *New(const std::string& fileName, const std::string& fieldName, bool loadAll=true); - MEDLOADER_EXPORT static MEDFileIntField1TS *New(const std::string& fileName, const std::string& fieldName, int iteration, int order, bool loadAll=true); - MEDLOADER_EXPORT static MEDFileIntField1TS *New(const MEDFileIntField1TSWithoutSDA& other, bool shallowCopyOfContent); - MEDLOADER_EXPORT MEDFileField1TS *convertToDouble(bool isDeepCpyGlobs=true) const; - MEDLOADER_EXPORT MEDFileAnyTypeField1TS *shallowCpy() const; - // - MEDLOADER_EXPORT MEDCouplingFieldDouble *getFieldAtLevel(TypeOfField type, int meshDimRelToMax, DataArrayInt* &arrOut, int renumPol=0) const; - MEDLOADER_EXPORT MEDCouplingFieldDouble *getFieldAtTopLevel(TypeOfField type, DataArrayInt* &arrOut, int renumPol=0) const; - MEDLOADER_EXPORT MEDCouplingFieldDouble *getFieldOnMeshAtLevel(TypeOfField type, int meshDimRelToMax, const MEDFileMesh *mesh, DataArrayInt* &arrOut, int renumPol=0) const; - MEDLOADER_EXPORT MEDCouplingFieldDouble *getFieldOnMeshAtLevel(TypeOfField type, const MEDCouplingMesh *mesh, DataArrayInt* &arrOut, int renumPol=0) const; - MEDLOADER_EXPORT MEDCouplingFieldDouble *getFieldAtLevelOld(TypeOfField type, const std::string& mname, int meshDimRelToMax, DataArrayInt* &arrOut, int renumPol=0) const; - MEDLOADER_EXPORT DataArrayInt *getFieldWithProfile(TypeOfField type, int meshDimRelToMax, const MEDFileMesh *mesh, DataArrayInt *&pfl) const; - // - MEDLOADER_EXPORT void setFieldNoProfileSBT(const MEDCouplingFieldDouble *field, const DataArrayInt *arrOfVals); - MEDLOADER_EXPORT void setFieldProfile(const MEDCouplingFieldDouble *field, const DataArrayInt *arrOfVals, const MEDFileMesh *mesh, int meshDimRelToMax, const DataArrayInt *profile); - MEDLOADER_EXPORT DataArrayInt *getUndergroundDataArray() const; - public: - MEDLOADER_EXPORT static DataArrayInt *ReturnSafelyDataArrayInt(MEDCouplingAutoRefCountObjectPtr& arr); - private: - med_field_type getMEDFileFieldType() const { return MED_INT32; } - const MEDFileIntField1TSWithoutSDA *contentNotNull() const; - MEDFileIntField1TSWithoutSDA *contentNotNull(); - private: - ~MEDFileIntField1TS() { } - MEDFileIntField1TS(); - MEDFileIntField1TS(const std::string& fileName, bool loadAll, const MEDFileMeshes *ms); - MEDFileIntField1TS(const std::string& fileName, const std::string& fieldName, bool loadAll, const MEDFileMeshes *ms); - MEDFileIntField1TS(const std::string& fileName, const std::string& fieldName, int iteration, int order, bool loadAll, const MEDFileMeshes *ms); - MEDFileIntField1TS(const MEDFileIntField1TSWithoutSDA& other, bool shallowCopyOfContent); - }; - - class MEDFileAnyTypeFieldMultiTSWithoutSDA : public RefCountObject, public MEDFileFieldNameScope - { - protected: - MEDFileAnyTypeFieldMultiTSWithoutSDA(); - MEDFileAnyTypeFieldMultiTSWithoutSDA(const std::string& fieldName); - MEDFileAnyTypeFieldMultiTSWithoutSDA(med_idt fid, int fieldId, bool loadAll, const MEDFileMeshes *ms, const std::vector< std::pair > *entities); - MEDFileAnyTypeFieldMultiTSWithoutSDA(med_idt fid, const std::string& fieldName, med_field_type fieldTyp, const std::vector& infos, int nbOfStep, const std::string& dtunit, bool loadAll, const MEDFileMeshes *ms, const std::vector< std::pair > *entities); - public: - MEDLOADER_EXPORT std::size_t getHeapMemorySizeWithoutChildren() const; - MEDLOADER_EXPORT std::vector getDirectChildrenWithNull() const; - MEDLOADER_EXPORT virtual MEDFileAnyTypeFieldMultiTSWithoutSDA *deepCpy() const; - MEDLOADER_EXPORT virtual std::vector< MEDCouplingAutoRefCountObjectPtr > splitComponents() const; - MEDLOADER_EXPORT virtual std::vector< MEDCouplingAutoRefCountObjectPtr > splitDiscretizations() const; - MEDLOADER_EXPORT virtual std::vector< MEDCouplingAutoRefCountObjectPtr > splitMultiDiscrPerGeoTypes() const; - MEDLOADER_EXPORT virtual const char *getTypeStr() const = 0; - MEDLOADER_EXPORT virtual MEDFileAnyTypeFieldMultiTSWithoutSDA *shallowCpy() const = 0; - MEDLOADER_EXPORT virtual MEDFileAnyTypeFieldMultiTSWithoutSDA *createNew() const = 0; - MEDLOADER_EXPORT virtual MEDFileAnyTypeField1TSWithoutSDA *createNew1TSWithoutSDAEmptyInstance() const = 0; - MEDLOADER_EXPORT virtual void checkCoherencyOfType(const MEDFileAnyTypeField1TSWithoutSDA *f1ts) const = 0; - MEDLOADER_EXPORT const std::vector& getInfo() const; - MEDLOADER_EXPORT bool presenceOfMultiDiscPerGeoType() const; - MEDLOADER_EXPORT void setInfo(const std::vector& info); - MEDLOADER_EXPORT int getTimeStepPos(int iteration, int order) const; - MEDLOADER_EXPORT const MEDFileAnyTypeField1TSWithoutSDA& getTimeStepEntry(int iteration, int order) const; - MEDLOADER_EXPORT MEDFileAnyTypeField1TSWithoutSDA& getTimeStepEntry(int iteration, int order); - MEDLOADER_EXPORT std::string getMeshName() const; - MEDLOADER_EXPORT void setMeshName(const std::string& newMeshName); - MEDLOADER_EXPORT bool changeMeshNames(const std::vector< std::pair >& modifTab); - MEDLOADER_EXPORT int getNumberOfTS() const; - MEDLOADER_EXPORT void eraseEmptyTS(); - MEDLOADER_EXPORT void eraseTimeStepIds(const int *startIds, const int *endIds); - MEDLOADER_EXPORT void eraseTimeStepIds2(int bg, int end, int step); - MEDLOADER_EXPORT MEDFileAnyTypeFieldMultiTSWithoutSDA *buildFromTimeStepIds(const int *startIds, const int *endIds) const; - MEDLOADER_EXPORT MEDFileAnyTypeFieldMultiTSWithoutSDA *buildFromTimeStepIds2(int bg, int end, int step) const; - MEDLOADER_EXPORT MEDFileAnyTypeFieldMultiTSWithoutSDA *partOfThisLyingOnSpecifiedTimeSteps(const std::vector< std::pair >& timeSteps) const; - MEDLOADER_EXPORT MEDFileAnyTypeFieldMultiTSWithoutSDA *partOfThisNotLyingOnSpecifiedTimeSteps(const std::vector< std::pair >& timeSteps) const; - MEDLOADER_EXPORT int getPosOfTimeStep(int iteration, int order) const; - MEDLOADER_EXPORT int getPosGivenTime(double time, double eps=1e-8) const; - MEDLOADER_EXPORT std::vector< std::pair > getIterations() const; - MEDLOADER_EXPORT std::vector< std::pair > getTimeSteps(std::vector& ret1) const; - MEDLOADER_EXPORT void pushBackTimeStep(MEDCouplingAutoRefCountObjectPtr& tse); - MEDLOADER_EXPORT void synchronizeNameScope(); - MEDLOADER_EXPORT void simpleRepr(int bkOffset, std::ostream& oss, int fmtsId) const; - MEDLOADER_EXPORT int getNonEmptyLevels(int iteration, int order, const std::string& mname, std::vector& levs) const; - MEDLOADER_EXPORT void appendFieldNoProfileSBT(const MEDCouplingFieldDouble *field, const DataArray *arr, MEDFileFieldGlobsReal& glob); - MEDLOADER_EXPORT void appendFieldProfile(const MEDCouplingFieldDouble *field, const DataArray *arr, const MEDFileMesh *mesh, int meshDimRelToMax, const DataArrayInt *profile, MEDFileFieldGlobsReal& glob); - MEDLOADER_EXPORT std::vector< std::vector< std::pair > > getFieldSplitedByType(int iteration, int order, const std::string& mname, std::vector& types, std::vector< std::vector >& typesF, std::vector< std::vector >& pfls, std::vector< std::vector >& locs) const; - MEDLOADER_EXPORT std::vector< std::vector > getTypesOfFieldAvailable() const; - MEDLOADER_EXPORT DataArray *getUndergroundDataArray(int iteration, int order) const; - MEDLOADER_EXPORT DataArray *getUndergroundDataArrayExt(int iteration, int order, std::vector< std::pair,std::pair > >& entries) const; - MEDLOADER_EXPORT bool renumberEntitiesLyingOnMesh(const std::string& meshName, const std::vector& oldCode, const std::vector& newCode, const DataArrayInt *renumO2N, MEDFileFieldGlobsReal& glob); - MEDLOADER_EXPORT void loadStructureOrStructureAndBigArraysRecursively(med_idt fid, int nbPdt, med_field_type fieldTyp, bool loadAll, const MEDFileMeshes *ms, const std::vector< std::pair > *entities); - MEDLOADER_EXPORT void writeLL(med_idt fid, const MEDFileWritable& opts) const; - MEDLOADER_EXPORT void loadBigArraysRecursively(med_idt fid, const MEDFileFieldNameScope& nasc); - MEDLOADER_EXPORT void loadBigArraysRecursivelyIfNecessary(med_idt fid, const MEDFileFieldNameScope& nasc); - MEDLOADER_EXPORT void unloadArrays(); - public: - MEDLOADER_EXPORT const MEDFileAnyTypeField1TSWithoutSDA *getTimeStepAtPos2(int pos) const; - MEDLOADER_EXPORT MEDFileAnyTypeField1TSWithoutSDA *getTimeStepAtPos2(int pos); - MEDLOADER_EXPORT std::vector getPflsReallyUsed2() const; - MEDLOADER_EXPORT std::vector getLocsReallyUsed2() const; - MEDLOADER_EXPORT std::vector getPflsReallyUsedMulti2() const; - MEDLOADER_EXPORT std::vector getLocsReallyUsedMulti2() const; - MEDLOADER_EXPORT void changePflsRefsNamesGen2(const std::vector< std::pair, std::string > >& mapOfModif); - MEDLOADER_EXPORT void changeLocsRefsNamesGen2(const std::vector< std::pair, std::string > >& mapOfModif); - MEDLOADER_EXPORT void setIteration(int i, MEDCouplingAutoRefCountObjectPtr ts); - protected: - virtual med_field_type getMEDFileFieldType() const = 0; - void copyTinyInfoFrom(const MEDCouplingFieldDouble *field, const DataArray *arr); - void checkCoherencyOfTinyInfo(const MEDCouplingFieldDouble *field, const DataArray *arr) const; - void checkThatComponentsMatch(const std::vector& compos) const; - void checkThatNbOfCompoOfTSMatchThis() const; - protected: - std::vector _infos; - std::vector< MEDCouplingAutoRefCountObjectPtr > _time_steps; - }; - - class MEDFileIntFieldMultiTSWithoutSDA; - - class MEDFileFieldMultiTSWithoutSDA : public MEDFileAnyTypeFieldMultiTSWithoutSDA - { - public: - MEDLOADER_EXPORT static MEDFileFieldMultiTSWithoutSDA *New(med_idt fid, const std::string& fieldName, med_field_type fieldTyp, const std::vector& infos, int nbOfStep, const std::string& dtunit, bool loadAll, const MEDFileMeshes *ms, const std::vector< std::pair > *entities); - MEDLOADER_EXPORT MEDFileFieldMultiTSWithoutSDA(med_idt fid, int fieldId, bool loadAll, const MEDFileMeshes *ms, const std::vector< std::pair > *entities); - MEDLOADER_EXPORT const char *getTypeStr() const; - MEDLOADER_EXPORT MEDFileAnyTypeFieldMultiTSWithoutSDA *shallowCpy() const; - MEDLOADER_EXPORT MEDFileAnyTypeFieldMultiTSWithoutSDA *createNew() const; - MEDLOADER_EXPORT std::vector< std::vector > getFieldSplitedByType2(int iteration, int order, const std::string& mname, std::vector& types, std::vector< std::vector >& typesF, std::vector< std::vector >& pfls, std::vector< std::vector >& locs) const; - MEDLOADER_EXPORT MEDFileIntFieldMultiTSWithoutSDA *convertToInt() const; - protected: - MEDFileFieldMultiTSWithoutSDA(const std::string& fieldName); - MEDFileFieldMultiTSWithoutSDA(med_idt fid, const std::string& fieldName, med_field_type fieldTyp, const std::vector& infos, int nbOfStep, const std::string& dtunit, bool loadAll, const MEDFileMeshes *ms, const std::vector< std::pair > *entities); - med_field_type getMEDFileFieldType() const { return MED_FLOAT64; } - MEDFileAnyTypeField1TSWithoutSDA *createNew1TSWithoutSDAEmptyInstance() const; - void checkCoherencyOfType(const MEDFileAnyTypeField1TSWithoutSDA *f1ts) const; - public: - MEDLOADER_EXPORT MEDFileFieldMultiTSWithoutSDA(); - }; - - class MEDFileIntFieldMultiTSWithoutSDA : public MEDFileAnyTypeFieldMultiTSWithoutSDA - { - public: - MEDLOADER_EXPORT static MEDFileIntFieldMultiTSWithoutSDA *New(med_idt fid, const std::string& fieldName, med_field_type fieldTyp, const std::vector& infos, int nbOfStep, const std::string& dtunit, bool loadAll, const MEDFileMeshes *ms, const std::vector< std::pair > *entities); - MEDLOADER_EXPORT MEDFileIntFieldMultiTSWithoutSDA(med_idt fid, int fieldId, bool loadAll, const MEDFileMeshes *ms, const std::vector< std::pair > *entities); - MEDLOADER_EXPORT const char *getTypeStr() const; - MEDLOADER_EXPORT MEDFileAnyTypeFieldMultiTSWithoutSDA *shallowCpy() const; - MEDLOADER_EXPORT MEDFileAnyTypeFieldMultiTSWithoutSDA *createNew() const; - MEDLOADER_EXPORT MEDFileFieldMultiTSWithoutSDA *convertToDouble() const; - protected: - MEDFileIntFieldMultiTSWithoutSDA(const std::string& fieldName); - MEDFileIntFieldMultiTSWithoutSDA(med_idt fid, const std::string& fieldName, med_field_type fieldTyp, const std::vector& infos, int nbOfStep, const std::string& dtunit, bool loadAll, const MEDFileMeshes *ms, const std::vector< std::pair > *entities); - med_field_type getMEDFileFieldType() const { return MED_INT32; } - MEDFileAnyTypeField1TSWithoutSDA *createNew1TSWithoutSDAEmptyInstance() const; - void checkCoherencyOfType(const MEDFileAnyTypeField1TSWithoutSDA *f1ts) const; - public: - MEDLOADER_EXPORT MEDFileIntFieldMultiTSWithoutSDA(); - }; - - class MEDFileAnyTypeFieldMultiTSIterator; - class MEDFileFastCellSupportComparator; - /*! - * User class. - */ - class MEDFileAnyTypeFieldMultiTS : public RefCountObject, public MEDFileWritable, public MEDFileFieldGlobsReal - { - protected: - MEDFileAnyTypeFieldMultiTS(); - MEDFileAnyTypeFieldMultiTS(const std::string& fileName, bool loadAll, const MEDFileMeshes *ms); - MEDFileAnyTypeFieldMultiTS(const std::string& fileName, const std::string& fieldName, bool loadAll, const MEDFileMeshes *ms, const std::vector< std::pair > *entities=0); - MEDFileAnyTypeFieldMultiTS(const MEDFileAnyTypeFieldMultiTSWithoutSDA& other, bool shallowCopyOfContent); - static MEDFileAnyTypeFieldMultiTS *BuildNewInstanceFromContent(MEDFileAnyTypeFieldMultiTSWithoutSDA *c, const std::string& fileName); - static MEDFileAnyTypeFieldMultiTSWithoutSDA *BuildContentFrom(med_idt fid, const std::string& fileName, bool loadAll, const MEDFileMeshes *ms); - static MEDFileAnyTypeFieldMultiTSWithoutSDA *BuildContentFrom(med_idt fid, const std::string& fileName, const std::string& fieldName, bool loadAll, const MEDFileMeshes *ms, const std::vector< std::pair > *entities); - public: - MEDLOADER_EXPORT static MEDFileAnyTypeFieldMultiTS *New(const std::string& fileName, bool loadAll=true); - MEDLOADER_EXPORT static MEDFileAnyTypeFieldMultiTS *New(const std::string& fileName, const std::string& fieldName, bool loadAll=true); - MEDLOADER_EXPORT void loadArrays(); - MEDLOADER_EXPORT void loadArraysIfNecessary(); - MEDLOADER_EXPORT void unloadArrays(); - MEDLOADER_EXPORT void unloadArraysWithoutDataLoss(); - MEDLOADER_EXPORT void write(const std::string& fileName, int mode) const; - MEDLOADER_EXPORT void writeLL(med_idt fid) const; - MEDLOADER_EXPORT std::size_t getHeapMemorySizeWithoutChildren() const; - MEDLOADER_EXPORT std::vector getDirectChildrenWithNull() const; - MEDLOADER_EXPORT virtual MEDFileAnyTypeFieldMultiTS *deepCpy() const; - MEDLOADER_EXPORT std::vector< MEDCouplingAutoRefCountObjectPtr< MEDFileAnyTypeFieldMultiTS > > splitComponents() const; - MEDLOADER_EXPORT std::vector< MEDCouplingAutoRefCountObjectPtr< MEDFileAnyTypeFieldMultiTS > > splitDiscretizations() const; - MEDLOADER_EXPORT std::vector< MEDCouplingAutoRefCountObjectPtr< MEDFileAnyTypeFieldMultiTS > > splitMultiDiscrPerGeoTypes() const; - MEDLOADER_EXPORT virtual MEDFileAnyTypeFieldMultiTS *shallowCpy() const = 0; - MEDLOADER_EXPORT virtual void checkCoherencyOfType(const MEDFileAnyTypeField1TS *f1ts) const = 0; - // - MEDLOADER_EXPORT virtual MEDFileAnyTypeField1TS *getTimeStepAtPos(int pos) const = 0; - MEDLOADER_EXPORT MEDFileAnyTypeField1TS *getTimeStep(int iteration, int order) const; - MEDLOADER_EXPORT MEDFileAnyTypeField1TS *getTimeStepGivenTime(double time, double eps=1e-8) const; - MEDLOADER_EXPORT static std::vector< std::vector > SplitIntoCommonTimeSeries(const std::vector& vectFMTS); - MEDLOADER_EXPORT static std::vector< std::vector > SplitPerCommonSupport(const std::vector& vectFMTS, const MEDFileMesh *mesh, std::vector< MEDCouplingAutoRefCountObjectPtr >& fsc); - MEDLOADER_EXPORT static int CheckSupportAcrossTime(MEDFileAnyTypeFieldMultiTS *f0, MEDFileAnyTypeFieldMultiTS *f1, const MEDFileMesh *mesh, TypeOfField& tof0, TypeOfField& tof1); - public:// direct forwarding to MEDFileField1TSWithoutSDA instance _content - MEDLOADER_EXPORT std::string getName() const; - MEDLOADER_EXPORT void setName(const std::string& name); - MEDLOADER_EXPORT std::string getDtUnit() const; - MEDLOADER_EXPORT void setDtUnit(const std::string& dtUnit); - MEDLOADER_EXPORT std::string getMeshName() const; - MEDLOADER_EXPORT void setMeshName(const std::string& newMeshName); - MEDLOADER_EXPORT std::string simpleRepr() const; - MEDLOADER_EXPORT void simpleRepr(int bkOffset, std::ostream& oss, int fmtsId) const; - MEDLOADER_EXPORT int getNumberOfTS() const; - MEDLOADER_EXPORT void eraseEmptyTS(); - MEDLOADER_EXPORT void eraseTimeStepIds(const int *startIds, const int *endIds); - MEDLOADER_EXPORT void eraseTimeStepIds2(int bg, int end, int step); - MEDLOADER_EXPORT MEDFileAnyTypeFieldMultiTS *buildSubPart(const int *startIds, const int *endIds) const; - MEDLOADER_EXPORT MEDFileAnyTypeFieldMultiTS *buildSubPartSlice(int bg, int end, int step) const; - MEDLOADER_EXPORT std::vector< std::pair > getTimeSteps(std::vector& ret1) const; - MEDLOADER_EXPORT std::vector< std::pair > getIterations() const; - MEDLOADER_EXPORT void pushBackTimeSteps(const std::vector& f1ts); - MEDLOADER_EXPORT void pushBackTimeSteps(MEDFileAnyTypeFieldMultiTS *fmts); - MEDLOADER_EXPORT void pushBackTimeStep(MEDFileAnyTypeField1TS *f1ts); - MEDLOADER_EXPORT void synchronizeNameScope(); - MEDLOADER_EXPORT int getPosOfTimeStep(int iteration, int order) const; - MEDLOADER_EXPORT int getPosGivenTime(double time, double eps=1e-8) const; - MEDLOADER_EXPORT MEDFileAnyTypeFieldMultiTSIterator *iterator(); - MEDLOADER_EXPORT bool changeMeshNames(const std::vector< std::pair >& modifTab); - MEDLOADER_EXPORT const std::vector& getInfo() const; - MEDLOADER_EXPORT bool presenceOfMultiDiscPerGeoType() const; - MEDLOADER_EXPORT void setInfo(const std::vector& info); - MEDLOADER_EXPORT int getNumberOfComponents() const; - MEDLOADER_EXPORT int getNonEmptyLevels(int iteration, int order, const std::string& mname, std::vector& levs) const; - MEDLOADER_EXPORT std::vector< std::vector > getTypesOfFieldAvailable() const; - MEDLOADER_EXPORT std::vector< std::vector< std::pair > > getFieldSplitedByType(int iteration, int order, const std::string& mname, std::vector& types, std::vector< std::vector >& typesF, std::vector< std::vector >& pfls, std::vector< std::vector >& locs) const; - MEDLOADER_EXPORT MEDCouplingAutoRefCountObjectPtr getContent(); - public: - MEDLOADER_EXPORT std::vector getPflsReallyUsed() const; - MEDLOADER_EXPORT std::vector getLocsReallyUsed() const; - MEDLOADER_EXPORT std::vector getPflsReallyUsedMulti() const; - MEDLOADER_EXPORT std::vector getLocsReallyUsedMulti() const; - MEDLOADER_EXPORT void changePflsRefsNamesGen(const std::vector< std::pair, std::string > >& mapOfModif); - MEDLOADER_EXPORT void changeLocsRefsNamesGen(const std::vector< std::pair, std::string > >& mapOfModif); - protected: - MEDFileAnyTypeFieldMultiTSWithoutSDA *contentNotNullBase(); - const MEDFileAnyTypeFieldMultiTSWithoutSDA *contentNotNullBase() const; - private: - static std::vector< std::vector > SplitPerCommonSupportNotNodesAlg(const std::vector& vectFMTS, const MEDFileMesh *mesh, std::vector< MEDCouplingAutoRefCountObjectPtr >& cmps); - protected: - MEDCouplingAutoRefCountObjectPtr _content; - }; - - class MEDFileIntFieldMultiTS; - - /*! - * User class. - */ - class MEDFileFieldMultiTS : public MEDFileAnyTypeFieldMultiTS - { - public: - MEDLOADER_EXPORT static MEDFileFieldMultiTS *New(); - MEDLOADER_EXPORT static MEDFileFieldMultiTS *New(const std::string& fileName, bool loadAll=true); - MEDLOADER_EXPORT static MEDFileFieldMultiTS *New(const std::string& fileName, const std::string& fieldName, bool loadAll=true); - MEDLOADER_EXPORT static MEDFileFieldMultiTS *New(const MEDFileFieldMultiTSWithoutSDA& other, bool shallowCopyOfContent); - MEDLOADER_EXPORT static MEDFileFieldMultiTS *LoadSpecificEntities(const std::string& fileName, const std::string& fieldName, const std::vector< std::pair >& entities, bool loadAll=true); - MEDLOADER_EXPORT MEDFileAnyTypeFieldMultiTS *shallowCpy() const; - MEDLOADER_EXPORT void checkCoherencyOfType(const MEDFileAnyTypeField1TS *f1ts) const; - MEDLOADER_EXPORT MEDFileIntFieldMultiTS *convertToInt(bool isDeepCpyGlobs=true) const; - // - MEDLOADER_EXPORT MEDFileAnyTypeField1TS *getTimeStepAtPos(int pos) const; - MEDLOADER_EXPORT MEDFileAnyTypeField1TS *getTimeStep(int iteration, int order) const; - MEDLOADER_EXPORT MEDFileAnyTypeField1TS *getTimeStepGivenTime(double time, double eps=1e-8) const; - // - MEDLOADER_EXPORT MEDCouplingFieldDouble *getFieldAtLevel(TypeOfField type, int iteration, int order, int meshDimRelToMax, int renumPol=0) const; - MEDLOADER_EXPORT MEDCouplingFieldDouble *getFieldAtTopLevel(TypeOfField type, int iteration, int order, int renumPol=0) const; - MEDLOADER_EXPORT MEDCouplingFieldDouble *getFieldOnMeshAtLevel(TypeOfField type, int iteration, int order, int meshDimRelToMax, const MEDFileMesh *mesh, int renumPol=0) const; - MEDLOADER_EXPORT MEDCouplingFieldDouble *getFieldOnMeshAtLevel(TypeOfField type, int iteration, int order, const MEDCouplingMesh *mesh, int renumPol=0) const; - MEDLOADER_EXPORT MEDCouplingFieldDouble *getFieldAtLevelOld(TypeOfField type, const std::string& mname, int iteration, int order, int meshDimRelToMax, int renumPol=0) const; - MEDLOADER_EXPORT DataArrayDouble *getFieldWithProfile(TypeOfField type, int iteration, int order, int meshDimRelToMax, const MEDFileMesh *mesh, DataArrayInt *&pfl) const; - // - MEDLOADER_EXPORT void appendFieldNoProfileSBT(const MEDCouplingFieldDouble *field); - MEDLOADER_EXPORT void appendFieldProfile(const MEDCouplingFieldDouble *field, const MEDFileMesh *mesh, int meshDimRelToMax, const DataArrayInt *profile); - MEDLOADER_EXPORT std::vector< std::vector > getFieldSplitedByType2(int iteration, int order, const std::string& mname, std::vector& types, std::vector< std::vector >& typesF, std::vector< std::vector >& pfls, std::vector< std::vector >& locs) const; - MEDLOADER_EXPORT DataArrayDouble *getUndergroundDataArray(int iteration, int order) const; - MEDLOADER_EXPORT DataArrayDouble *getUndergroundDataArrayExt(int iteration, int order, std::vector< std::pair,std::pair > >& entries) const; - private: - const MEDFileFieldMultiTSWithoutSDA *contentNotNull() const; - MEDFileFieldMultiTSWithoutSDA *contentNotNull(); - private: - ~MEDFileFieldMultiTS() { } - MEDFileFieldMultiTS(); - MEDFileFieldMultiTS(const MEDFileFieldMultiTSWithoutSDA& other, bool shallowCopyOfContent); - MEDFileFieldMultiTS(const std::string& fileName, bool loadAll, const MEDFileMeshes *ms); - MEDFileFieldMultiTS(const std::string& fileName, const std::string& fieldName, bool loadAll, const MEDFileMeshes *ms, const std::vector< std::pair > *entities=0); - }; - - /*! - * User class. - */ - class MEDFileIntFieldMultiTS : public MEDFileAnyTypeFieldMultiTS - { - public: - MEDLOADER_EXPORT static MEDFileIntFieldMultiTS *New(); - MEDLOADER_EXPORT static MEDFileIntFieldMultiTS *New(const std::string& fileName, bool loadAll=true); - MEDLOADER_EXPORT static MEDFileIntFieldMultiTS *New(const std::string& fileName, const std::string& fieldName, bool loadAll=true); - MEDLOADER_EXPORT static MEDFileIntFieldMultiTS *New(const MEDFileIntFieldMultiTSWithoutSDA& other, bool shallowCopyOfContent); - MEDLOADER_EXPORT static MEDFileIntFieldMultiTS *LoadSpecificEntities(const std::string& fileName, const std::string& fieldName, const std::vector< std::pair >& entities, bool loadAll=true); - MEDLOADER_EXPORT MEDFileAnyTypeFieldMultiTS *shallowCpy() const; - MEDLOADER_EXPORT void checkCoherencyOfType(const MEDFileAnyTypeField1TS *f1ts) const; - MEDLOADER_EXPORT MEDFileAnyTypeField1TS *getTimeStepAtPos(int pos) const; - MEDLOADER_EXPORT MEDFileFieldMultiTS *convertToDouble(bool isDeepCpyGlobs=true) const; - // - MEDLOADER_EXPORT MEDCouplingFieldDouble *getFieldAtLevel(TypeOfField type, int iteration, int order, int meshDimRelToMax, DataArrayInt* &arrOut, int renumPol=0) const; - MEDLOADER_EXPORT MEDCouplingFieldDouble *getFieldAtTopLevel(TypeOfField type, int iteration, int order, DataArrayInt* &arrOut, int renumPol=0) const; - MEDLOADER_EXPORT MEDCouplingFieldDouble *getFieldOnMeshAtLevel(TypeOfField type, int iteration, int order, int meshDimRelToMax, const MEDFileMesh *mesh, DataArrayInt* &arrOut, int renumPol=0) const; - MEDLOADER_EXPORT MEDCouplingFieldDouble *getFieldOnMeshAtLevel(TypeOfField type, int iteration, int order, const MEDCouplingMesh *mesh, DataArrayInt* &arrOut, int renumPol=0) const; - MEDLOADER_EXPORT MEDCouplingFieldDouble *getFieldAtLevelOld(TypeOfField type, int iteration, int order, const std::string& mname, int meshDimRelToMax, DataArrayInt* &arrOut, int renumPol=0) const; - MEDLOADER_EXPORT DataArrayInt *getFieldWithProfile(TypeOfField type, int iteration, int order, int meshDimRelToMax, const MEDFileMesh *mesh, DataArrayInt *&pfl) const; - // - MEDLOADER_EXPORT void appendFieldNoProfileSBT(const MEDCouplingFieldDouble *field, const DataArrayInt *arrOfVals); - MEDLOADER_EXPORT void appendFieldProfile(const MEDCouplingFieldDouble *field, const DataArrayInt *arrOfVals, const MEDFileMesh *mesh, int meshDimRelToMax, const DataArrayInt *profile); - // - MEDLOADER_EXPORT DataArrayInt *getUndergroundDataArray(int iteration, int order) const; - private: - const MEDFileIntFieldMultiTSWithoutSDA *contentNotNull() const; - MEDFileIntFieldMultiTSWithoutSDA *contentNotNull(); - private: - ~MEDFileIntFieldMultiTS() { } - MEDFileIntFieldMultiTS(); - MEDFileIntFieldMultiTS(const MEDFileIntFieldMultiTSWithoutSDA& other, bool shallowCopyOfContent); - MEDFileIntFieldMultiTS(const std::string& fileName, bool loadAll, const MEDFileMeshes *ms); - MEDFileIntFieldMultiTS(const std::string& fileName, const std::string& fieldName, bool loadAll, const MEDFileMeshes *ms, const std::vector< std::pair > *entities=0); - }; - - class MEDFileAnyTypeFieldMultiTSIterator - { - public: - MEDLOADER_EXPORT MEDFileAnyTypeFieldMultiTSIterator(MEDFileAnyTypeFieldMultiTS *fmts); - MEDLOADER_EXPORT ~MEDFileAnyTypeFieldMultiTSIterator(); - MEDLOADER_EXPORT MEDFileAnyTypeField1TS *nextt(); - private: - MEDCouplingAutoRefCountObjectPtr _fmts; - int _iter_id; - int _nb_iter; - }; - - class MEDFileFieldsIterator; - - /*! - * Use class. - */ - class MEDFileFields : public RefCountObject, public MEDFileFieldGlobsReal, public MEDFileWritable - { - public: - MEDLOADER_EXPORT static MEDFileFields *New(); - MEDLOADER_EXPORT static MEDFileFields *New(const std::string& fileName, bool loadAll=true); - MEDLOADER_EXPORT static MEDFileFields *LoadPartOf(const std::string& fileName, bool loadAll=true, const MEDFileMeshes *ms=0); - MEDLOADER_EXPORT static MEDFileFields *LoadSpecificEntities(const std::string& fileName, const std::vector< std::pair >& entities, bool loadAll=true); - MEDLOADER_EXPORT std::size_t getHeapMemorySizeWithoutChildren() const; - MEDLOADER_EXPORT std::vector getDirectChildrenWithNull() const; - MEDLOADER_EXPORT MEDFileFields *deepCpy() const; - MEDLOADER_EXPORT MEDFileFields *shallowCpy() const; - MEDLOADER_EXPORT void write(const std::string& fileName, int mode) const; - MEDLOADER_EXPORT void writeLL(med_idt fid) const; - MEDLOADER_EXPORT void loadArrays(); - MEDLOADER_EXPORT void loadArraysIfNecessary(); - MEDLOADER_EXPORT void unloadArrays(); - MEDLOADER_EXPORT void unloadArraysWithoutDataLoss(); - MEDLOADER_EXPORT int getNumberOfFields() const; - MEDLOADER_EXPORT std::vector< std::pair > getCommonIterations(bool& areThereSomeForgottenTS) const; - MEDLOADER_EXPORT std::vector getFieldsNames() const; - MEDLOADER_EXPORT std::vector getMeshesNames() const; - MEDLOADER_EXPORT std::string simpleRepr() const; - MEDLOADER_EXPORT void simpleRepr(int bkOffset, std::ostream& oss) const; - // - MEDLOADER_EXPORT void resize(int newSize); - MEDLOADER_EXPORT void pushField(MEDFileAnyTypeFieldMultiTS *field); - MEDLOADER_EXPORT void pushFields(const std::vector& fields); - MEDLOADER_EXPORT void setFieldAtPos(int i, MEDFileAnyTypeFieldMultiTS *field); - MEDLOADER_EXPORT int getPosFromFieldName(const std::string& fieldName) const; - MEDLOADER_EXPORT MEDFileAnyTypeFieldMultiTS *getFieldAtPos(int i) const; - MEDLOADER_EXPORT MEDFileAnyTypeFieldMultiTS *getFieldWithName(const std::string& fieldName) const; - MEDLOADER_EXPORT MEDFileFields *buildSubPart(const int *startIds, const int *endIds) const; - MEDLOADER_EXPORT bool removeFieldsWithoutAnyTimeStep(); - MEDLOADER_EXPORT MEDFileFields *partOfThisLyingOnSpecifiedMeshName(const std::string& meshName) const; - MEDLOADER_EXPORT MEDFileFields *partOfThisLyingOnSpecifiedTimeSteps(const std::vector< std::pair >& timeSteps) const; - MEDLOADER_EXPORT MEDFileFields *partOfThisNotLyingOnSpecifiedTimeSteps(const std::vector< std::pair >& timeSteps) const; - MEDLOADER_EXPORT MEDFileFieldsIterator *iterator(); - MEDLOADER_EXPORT void destroyFieldAtPos(int i); - MEDLOADER_EXPORT void destroyFieldsAtPos(const int *startIds, const int *endIds); - MEDLOADER_EXPORT void destroyFieldsAtPos2(int bg, int end, int step); - MEDLOADER_EXPORT bool changeMeshNames(const std::vector< std::pair >& modifTab); - MEDLOADER_EXPORT bool renumberEntitiesLyingOnMesh(const std::string& meshName, const std::vector& oldCode, const std::vector& newCode, const DataArrayInt *renumO2N); - public: - MEDLOADER_EXPORT std::vector getPflsReallyUsed() const; - MEDLOADER_EXPORT std::vector getLocsReallyUsed() const; - MEDLOADER_EXPORT std::vector getPflsReallyUsedMulti() const; - MEDLOADER_EXPORT std::vector getLocsReallyUsedMulti() const; - MEDLOADER_EXPORT void changePflsRefsNamesGen(const std::vector< std::pair, std::string > >& mapOfModif); - MEDLOADER_EXPORT void changeLocsRefsNamesGen(const std::vector< std::pair, std::string > >& mapOfModif); - private: - ~MEDFileFields() { } - MEDFileFields(); - MEDFileFields(const std::string& fileName, bool loadAll, const MEDFileMeshes *ms, const std::vector< std::pair > *entities); - private: - std::vector< MEDCouplingAutoRefCountObjectPtr > _fields; - }; - - class MEDFileFieldsIterator - { - public: - MEDLOADER_EXPORT MEDFileFieldsIterator(MEDFileFields *fs); - MEDLOADER_EXPORT ~MEDFileFieldsIterator(); - MEDLOADER_EXPORT MEDFileAnyTypeFieldMultiTS *nextt(); - private: - MEDCouplingAutoRefCountObjectPtr _fs; - int _iter_id; - int _nb_iter; - }; -} - -#endif diff --git a/src/MEDLoader/MEDFileFieldOverView.cxx b/src/MEDLoader/MEDFileFieldOverView.cxx deleted file mode 100644 index 4f0367cb2..000000000 --- a/src/MEDLoader/MEDFileFieldOverView.cxx +++ /dev/null @@ -1,2427 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 -// 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 "MEDFileFieldOverView.hxx" -#include "MEDFileField.hxx" -#include "MEDFileMesh.hxx" - -#include "MEDCouplingFieldDiscretization.hxx" -#include "CellModel.hxx" - -using namespace ParaMEDMEM; - -const unsigned char MEDMeshMultiLev::PARAMEDMEM_2_VTKTYPE[MEDMeshMultiLev::PARAMEDMEM_2_VTKTYPE_LGTH]= -{1,3,21,5,9,7,22,34,23,28,255,255,255,255,10,14,13,255,12,255,24,255,16,27,255,26,255,29,255,255,25,42,36,4}; - -const unsigned char MEDMeshMultiLev::HEXA27_PERM_ARRAY[27]={0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,24,22,21,23,20,25,26}; - -const char MEDFileField1TSStructItem2::NEWLY_CREATED_PFL_NAME[]="???"; - -MEDFileMeshStruct *MEDFileMeshStruct::New(const MEDFileMesh *mesh) -{ - return new MEDFileMeshStruct(mesh); -} - -std::size_t MEDFileMeshStruct::getHeapMemorySizeWithoutChildren() const -{ - std::size_t ret(0); - for(std::vector< std::vector >::const_iterator it0=_geo_types_distrib.begin();it0!=_geo_types_distrib.end();it0++) - ret+=(*it0).capacity()*sizeof(int); - ret+=_geo_types_distrib.capacity()*sizeof(std::vector); - return ret; -} - -std::vector MEDFileMeshStruct::getDirectChildrenWithNull() const -{ - return std::vector(); -} - -MEDFileMeshStruct::MEDFileMeshStruct(const MEDFileMesh *mesh):_mesh(mesh) -{ - std::vector levs(mesh->getNonEmptyLevels()); - _name=mesh->getName(); - _nb_nodes=mesh->getNumberOfNodes(); - if(!levs.empty()) - { - _geo_types_distrib.resize(-(*std::min_element(levs.begin(),levs.end()))+1); - for(std::vector::const_iterator lev=levs.begin();lev!=levs.end();lev++) - _geo_types_distrib[-(*lev)]=mesh->getDistributionOfTypes(*lev); - } -} - -int MEDFileMeshStruct::getLevelOfGeoType(INTERP_KERNEL::NormalizedCellType t) const -{ - int j=0; - for(std::vector< std::vector >::const_iterator it1=_geo_types_distrib.begin();it1!=_geo_types_distrib.end();it1++,j--) - { - std::size_t sz=(*it1).size(); - if(sz%3!=0) - throw INTERP_KERNEL::Exception("MEDFileMeshStruct::getLevelOfGeoType : internal error in code !"); - std::size_t nbGeo=sz/3; - for(std::size_t i=0;i >::const_iterator it1=_geo_types_distrib.begin();it1!=_geo_types_distrib.end();it1++) - { - std::size_t sz=(*it1).size(); - if(sz%3!=0) - throw INTERP_KERNEL::Exception("MEDFileMeshStruct::getNumberOfElemsOfGeoType : internal error in code !"); - std::size_t nbGeo=sz/3; - for(std::size_t i=0;i >::const_iterator it1=_geo_types_distrib.begin();it1!=_geo_types_distrib.end();it1++) - { - std::size_t sz=(*it1).size(); - if(sz%3!=0) - throw INTERP_KERNEL::Exception("MEDFileMeshStruct::doesManageGeoType : internal error in code !"); - std::size_t nbGeo=sz/3; - for(std::size_t i=0;ihasImplicitPart()) - throw INTERP_KERNEL::Exception("MEDFileMeshStruct::appendIfImplicitType : by default no implicit geo type can be appended !"); - static const char MSG[]="MEDFileMeshStruct::appendIfImplicitType : the distribution does not looks like structured standard !"; - if(_geo_types_distrib.size()!=1) - throw INTERP_KERNEL::Exception(MSG); - std::size_t sz(_geo_types_distrib[0].size()); - if(sz%3!=0) - throw INTERP_KERNEL::Exception("MEDFileMeshStruct::appendIfImplicitType : internal error in code !"); - std::size_t nbGeo(sz/3); - if(nbGeo!=1) - throw INTERP_KERNEL::Exception(MSG); - std::vector arr(3); arr[0]=(int)t; arr[1]=_mesh->buildImplicitPartIfAny(t); arr[2]=-1; - _geo_types_distrib.push_back(arr); -} - - -int MEDFileMeshStruct::getNumberOfLevs() const -{ - return (int)_geo_types_distrib.size(); -} - -int MEDFileMeshStruct::getNumberOfGeoTypesInLev(int relativeLev) const -{ - int pos(-relativeLev); - if(pos<0 || pos>=(int)_geo_types_distrib.size()) - throw INTERP_KERNEL::Exception("MEDFileMeshStruct::getNumberOfGeoTypesInLev : invalid level specified !"); - std::size_t sz=_geo_types_distrib[pos].size(); - if(sz%3!=0) - throw INTERP_KERNEL::Exception("MEDFileMeshStruct::getNumberOfGeoTypesInLev : internal error in code !"); - return (int)(sz/3); -} - -//= - -std::size_t MEDMeshMultiLev::getHeapMemorySizeWithoutChildren() const -{ - return 0; -} - -std::vector MEDMeshMultiLev::getDirectChildrenWithNull() const -{ - return std::vector(); -} - -MEDMeshMultiLev *MEDMeshMultiLev::New(const MEDFileMesh *m, const std::vector& levs) -{ - if(!m) - throw INTERP_KERNEL::Exception("MEDMeshMultiLev::New : null input pointer !"); - const MEDFileUMesh *um(dynamic_cast(m)); - if(um) - return MEDUMeshMultiLev::New(um,levs); - const MEDFileCMesh *cm(dynamic_cast(m)); - if(cm) - return MEDCMeshMultiLev::New(cm,levs); - const MEDFileCurveLinearMesh *clm(dynamic_cast(m)); - if(clm) - return MEDCurveLinearMeshMultiLev::New(clm,levs); - throw INTERP_KERNEL::Exception("MEDMeshMultiLev::New : unrecognized type of mesh ! Must be in [MEDFileUMesh,MEDFileCMesh,MEDFileCurveLinearMesh] !"); -} - -MEDMeshMultiLev *MEDMeshMultiLev::New(const MEDFileMesh *m, const std::vector& gts, const std::vector& pfls, const std::vector& nbEntities) -{ - if(!m) - throw INTERP_KERNEL::Exception("MEDMeshMultiLev::New 2 : null input pointer !"); - const MEDFileUMesh *um(dynamic_cast(m)); - if(um) - return MEDUMeshMultiLev::New(um,gts,pfls,nbEntities); - const MEDFileCMesh *cm(dynamic_cast(m)); - if(cm) - return MEDCMeshMultiLev::New(cm,gts,pfls,nbEntities); - const MEDFileCurveLinearMesh *clm(dynamic_cast(m)); - if(clm) - return MEDCurveLinearMeshMultiLev::New(clm,gts,pfls,nbEntities); - throw INTERP_KERNEL::Exception("MEDMeshMultiLev::New 2 : unrecognized type of mesh ! Must be in [MEDFileUMesh,MEDFileCMesh,MEDFileCurveLinearMesh] !"); -} - -MEDMeshMultiLev *MEDMeshMultiLev::NewOnlyOnNode(const MEDFileMesh *m, const DataArrayInt *pflOnNode) -{ - MEDCouplingAutoRefCountObjectPtr ret(MEDMeshMultiLev::New(m,m->getNonEmptyLevels())); - ret->selectPartOfNodes(pflOnNode); - return ret.retn(); -} - -void MEDMeshMultiLev::setNodeReduction(const DataArrayInt *nr) -{ - if(nr) - nr->incrRef(); - _node_reduction=const_cast(nr); -} - -void MEDMeshMultiLev::setCellReduction(const DataArrayInt *cr) -{ - if(_pfls.size()!=1) - throw INTERP_KERNEL::Exception("MEDMeshMultiLev::setCellReduction : can be used only for single geo type mesh !"); - _pfls[0]=const_cast(cr); - if(cr) - cr->incrRef(); -} - -bool MEDMeshMultiLev::isFastlyTheSameStruct(const MEDFileField1TSStructItem& fst, const MEDFileFieldGlobsReal *globs) const -{ - if(fst.getType()==ON_NODES) - { - if(fst.getNumberOfItems()!=1) - throw INTERP_KERNEL::Exception("MEDMeshMultiLev::isFastlyTheSameStruct : unexpected situation for nodes !"); - const MEDFileField1TSStructItem2& p(fst[0]); - std::string pflName(p.getPflName()); - const DataArrayInt *nr(_node_reduction); - if(pflName.empty() && !nr) - return true; - if(!pflName.empty() && !nr) - return false; - if(pflName==nr->getName()) - return true; - return false; - } - else - { - std::size_t sz(fst.getNumberOfItems()); - if(sz!=_geo_types.size()) - return false; - int strt(0); - for(std::size_t i=0;i ret(const_cast(vals)); ret->incrRef(); - if(isFastlyTheSameStruct(fst,globs)) - return ret.retn(); - else - return constructDataArray(fst,globs,vals); -} - -/*! - * \param [out] famIds - Can be null. If not null the instance has to be dealt by the caller (decrRef). - * \param [out] isWithoutCopy - When true the returned instance \a famIds if not null is directly those in the data structure. - */ -void MEDMeshMultiLev::retrieveFamilyIdsOnCells(DataArrayInt *& famIds, bool& isWithoutCopy) const -{ - const DataArrayInt *fids(_cell_fam_ids); - if(!fids) - { famIds=0; isWithoutCopy=true; return ; } - std::size_t sz(_geo_types.size()); - bool presenceOfPfls(false); - for(std::size_t i=0;i(fids); famIds->incrRef(); isWithoutCopy=_mesh->isObjectInTheProgeny(famIds); return ; } - //bad luck the slowest part - isWithoutCopy=false; - std::vector< MEDCouplingAutoRefCountObjectPtr > retSafe(sz); - std::vector< const DataArrayInt *> ret(sz); - int start(0); - for(std::size_t i=0;i tmp(fids->selectByTupleId2(start,start+lgth,1)); - retSafe[i]=tmp->selectByTupleIdSafe(pfl->begin(),pfl->end()); - } - else - { - retSafe[i]=fids->selectByTupleId2(start,start+lgth,1); - } - ret[i]=retSafe[i]; - start+=lgth; - } - famIds=DataArrayInt::Aggregate(ret); -} - -/*! - * \param [out] numIds - Can be null. If not null the instance has to be dealt by the caller (decrRef). - * \param [out] isWithoutCopy - When true the returned instance \a numIds if not null is directly those in the data structure. - */ -void MEDMeshMultiLev::retrieveNumberIdsOnCells(DataArrayInt *& numIds, bool& isWithoutCopy) const -{ - const DataArrayInt *nids(_cell_num_ids); - if(!nids) - { numIds=0; isWithoutCopy=true; return ; } - std::size_t sz(_geo_types.size()); - bool presenceOfPfls(false); - for(std::size_t i=0;i(nids); numIds->incrRef(); isWithoutCopy=_mesh->isObjectInTheProgeny(numIds); return ; } - //bad luck the slowest part - isWithoutCopy=false; - std::vector< MEDCouplingAutoRefCountObjectPtr > retSafe(sz); - std::vector< const DataArrayInt *> ret(sz); - int start(0); - for(std::size_t i=0;i tmp(nids->selectByTupleId2(start,start+lgth,1)); - retSafe[i]=tmp->selectByTupleIdSafe(pfl->begin(),pfl->end()); - } - else - { - retSafe[i]=nids->selectByTupleId2(start,start+lgth,1); - } - ret[i]=retSafe[i]; - start+=lgth; - } - numIds=DataArrayInt::Aggregate(ret); -} - -/*! - * \param [out] famIds - Can be null. If not null the instance has to be dealt by the caller (decrRef). - * \param [out] isWithoutCopy - When true the returned instance \a famIds if not null is directly those in the data structure. - */ -void MEDMeshMultiLev::retrieveFamilyIdsOnNodes(DataArrayInt *& famIds, bool& isWithoutCopy) const -{ - const DataArrayInt *fids(_node_fam_ids); - if(!fids) - { famIds=0; isWithoutCopy=true; return ; } - const DataArrayInt *nr(_node_reduction); - if(nr) - { - isWithoutCopy=false; - famIds=fids->selectByTupleIdSafe(nr->begin(),nr->end()); - } - else - { - famIds=const_cast(fids); famIds->incrRef(); - isWithoutCopy=_mesh->isObjectInTheProgeny(famIds); - } -} - -/*! - * \param [out] numIds - Can be null. If not null the instance has to be dealt by the caller (decrRef). - * \param [out] isWithoutCopy - When true the returned instance \a numIds if not null is directly those in the data structure. - */ -void MEDMeshMultiLev::retrieveNumberIdsOnNodes(DataArrayInt *& numIds, bool& isWithoutCopy) const -{ - const DataArrayInt *fids(_node_num_ids); - if(!fids) - { numIds=0; isWithoutCopy=true; return ; } - const DataArrayInt *nr(_node_reduction); - if(nr) - { - isWithoutCopy=false; - numIds=fids->selectByTupleIdSafe(nr->begin(),nr->end()); - } - else - { - numIds=const_cast(fids); numIds->incrRef(); - isWithoutCopy=_mesh->isObjectInTheProgeny(numIds); - } -} - -std::vector< INTERP_KERNEL::NormalizedCellType > MEDMeshMultiLev::getGeoTypes() const -{ - return _geo_types; -} - -void MEDMeshMultiLev::setFamilyIdsOnCells(DataArrayInt *famIds) -{ - _cell_fam_ids=famIds; - if(famIds) - famIds->incrRef(); -} - -void MEDMeshMultiLev::setNumberIdsOnCells(DataArrayInt *numIds) -{ - _cell_num_ids=numIds; - if(numIds) - numIds->incrRef(); -} - -void MEDMeshMultiLev::setFamilyIdsOnNodes(DataArrayInt *famIds) -{ - _node_fam_ids=famIds; - if(famIds) - famIds->incrRef(); -} - -void MEDMeshMultiLev::setNumberIdsOnNodes(DataArrayInt *numIds) -{ - _node_num_ids=numIds; - if(numIds) - numIds->incrRef(); -} - -std::string MEDMeshMultiLev::getPflNameOfId(int id) const -{ - std::size_t sz(_pfls.size()); - if(id<0 || id>=(int)sz) - throw INTERP_KERNEL::Exception("MEDMeshMultiLev::getPflNameOfId : invalid input id !"); - const DataArrayInt *pfl(_pfls[id]); - if(!pfl) - return std::string(""); - return pfl->getName(); -} - -/*! - * Returns the number of cells having geometric type \a t. - * The profiles are **NOT** taken into account here. - */ -int MEDMeshMultiLev::getNumberOfCells(INTERP_KERNEL::NormalizedCellType t) const -{ - std::size_t sz(_nb_entities.size()); - for(std::size_t i=0;ideepCpy(); - if(pflName.empty() && nr) - throw INTERP_KERNEL::Exception("MEDMeshMultiLev::constructDataArray : unexpected situation for nodes 2 !"); - if(!pflName.empty() && nr) - { - MEDCouplingAutoRefCountObjectPtr p1(globs->getProfile(pflName.c_str())->deepCpy()); - MEDCouplingAutoRefCountObjectPtr p2(nr->deepCpy()); - p1->sort(true); p2->sort(true); - if(!p1->isEqualWithoutConsideringStr(*p2)) - throw INTERP_KERNEL::Exception("MEDMeshMultiLev::constructDataArray : it appears that a profile on nodes does not cover the cells correctly !"); - p1=DataArrayInt::FindPermutationFromFirstToSecond(globs->getProfile(pflName.c_str()),nr); - MEDCouplingAutoRefCountObjectPtr ret(vals->deepCpy()); - ret->renumberInPlace(p1->begin()); - return ret.retn(); - } - if(!pflName.empty() && !nr) - { - MEDCouplingAutoRefCountObjectPtr p1(globs->getProfile(pflName.c_str())->deepCpy()); - p1->sort(true); - if(!p1->isIdentity() || p1->getNumberOfTuples()!=getNumberOfNodes()) - throw INTERP_KERNEL::Exception("MEDMeshMultiLev::constructDataArray : unexpected situation for nodes 4 !"); - MEDCouplingAutoRefCountObjectPtr ret(vals->deepCpy()); - ret->renumberInPlace(globs->getProfile(pflName.c_str())->begin()); - return ret.retn(); - } - throw INTERP_KERNEL::Exception("MEDMeshMultiLev::constructDataArray : unexpected situation for nodes 5 !"); - } - else - { - std::size_t sz(fst.getNumberOfItems()); - std::set s(_geo_types.begin(),_geo_types.end()); - if(s.size()!=_geo_types.size()) - throw INTERP_KERNEL::Exception("MEDMeshMultiLev::constructDataArray : unexpected situation for cells 2 !"); - std::vector< const DataArray *> arr(s.size()); - std::vector< MEDCouplingAutoRefCountObjectPtr > arrSafe(s.size()); - int iii(0); - int nc(vals->getNumberOfComponents()); - std::vector compInfo(vals->getInfoOnComponents()); - for(std::vector< INTERP_KERNEL::NormalizedCellType >::const_iterator it=_geo_types.begin();it!=_geo_types.end();it++,iii++) - { - const DataArrayInt *thisP(_pfls[iii]); - std::vector ps; - for(std::size_t i=0;igetNbOfIntegrationPts(globs)); - const DataArrayInt *otherP(ps[0]->getPfl(globs)); - const std::pair& strtStop(ps[0]->getStartStop()); - MEDCouplingAutoRefCountObjectPtr ret(vals->selectByTupleId2(strtStop.first,strtStop.second,1)); - if(!thisP && !otherP) - { - arrSafe[iii]=ret; arr[iii]=ret; - continue; - } - if(thisP && otherP) - { - MEDCouplingAutoRefCountObjectPtr p1(otherP->invertArrayN2O2O2N(getNumberOfCells(ps[0]->getGeo()))); - MEDCouplingAutoRefCountObjectPtr p2(thisP->deepCpy()); - p2->transformWithIndArr(p1->begin(),p1->end()); - //p1=p2->getIdsNotEqual(-1); - //p1=p2->selectByTupleIdSafe(p1->begin(),p1->end()); - ret->rearrange(nbi*nc); ret=ret->selectByTupleIdSafe(p2->begin(),p2->end()); ret->rearrange(nc); ret->setInfoOnComponents(compInfo); - arrSafe[iii]=ret; arr[iii]=ret; - continue; - } - if(!thisP && otherP) - { - MEDCouplingAutoRefCountObjectPtr p1(otherP->deepCpy()); - p1->sort(true); - p1->checkAllIdsInRange(0,getNumberOfCells(ps[0]->getGeo())); - p1=DataArrayInt::FindPermutationFromFirstToSecond(otherP,p1); - ret->rearrange(nbi*nc); ret->renumberInPlace(p1->begin()); ret->rearrange(nc); ret->setInfoOnComponents(compInfo); - arrSafe[iii]=ret; arr[iii]=ret; - continue; - } - throw INTERP_KERNEL::Exception("MEDMeshMultiLev::constructDataArray : unexpected situation for cells 3 !"); - } - else - { - std::vector< const DataArrayInt * >otherPS(ps.size()); - std::vector< const DataArray * > arr2(ps.size()); - std::vector< MEDCouplingAutoRefCountObjectPtr > arr2Safe(ps.size()); - std::vector< const DataArrayInt * > nbis(ps.size()); - std::vector< MEDCouplingAutoRefCountObjectPtr > nbisSafe(ps.size()); - int jj(0); - for(std::vector::const_iterator it2=ps.begin();it2!=ps.end();it2++,jj++) - { - int nbi((*it2)->getNbOfIntegrationPts(globs)); - const DataArrayInt *otherPfl((*it2)->getPfl(globs)); - const std::pair& strtStop((*it2)->getStartStop()); - MEDCouplingAutoRefCountObjectPtr ret2(vals->selectByTupleId2(strtStop.first,strtStop.second,1)); - if(!otherPfl) - throw INTERP_KERNEL::Exception("MEDMeshMultiLev::constructDataArray : unexpected situation for cells 4 !"); - arr2[jj]=ret2; arr2Safe[jj]=ret2; otherPS[jj]=otherPfl; - nbisSafe[jj]=DataArrayInt::New(); nbisSafe[jj]->alloc(otherPfl->getNumberOfTuples(),1); nbisSafe[jj]->fillWithValue(nbi); - nbis[jj]=nbisSafe[jj]; - } - MEDCouplingAutoRefCountObjectPtr arr3(DataArray::Aggregate(arr2)); - MEDCouplingAutoRefCountObjectPtr otherP(DataArrayInt::Aggregate(otherPS)); - MEDCouplingAutoRefCountObjectPtr zenbis(DataArrayInt::Aggregate(nbis)); - MEDCouplingAutoRefCountObjectPtr otherPN(otherP->invertArrayN2O2O2N(getNumberOfCells(*it))); - MEDCouplingAutoRefCountObjectPtr p1; - if(thisP) - p1=DataArrayInt::FindPermutationFromFirstToSecond(otherP,thisP); - else - p1=otherP->deepCpy(); - MEDCouplingAutoRefCountObjectPtr zenbisN(zenbis->renumber(p1->begin())); - zenbisN->computeOffsets2(); - jj=0; - for(std::vector::const_iterator it2=ps.begin();it2!=ps.end();it2++,jj++) - { - //int nbi((*it2)->getNbOfIntegrationPts(globs)); - const DataArrayInt *otherPfl((*it2)->getPfl(globs)); - const std::pair& strtStop((*it2)->getStartStop()); - MEDCouplingAutoRefCountObjectPtr ret2(vals->selectByTupleId2(strtStop.first,strtStop.second,1)); - // - MEDCouplingAutoRefCountObjectPtr p2(otherPfl->deepCpy()); - p2->transformWithIndArr(otherPN->begin(),otherPN->end()); - p2->transformWithIndArr(p1->begin(),p1->end()); - MEDCouplingAutoRefCountObjectPtr idsN(p2->buildExplicitArrByRanges(zenbisN)); - arr3->setPartOfValuesBase3(ret2,idsN->begin(),idsN->end(),0,nc,1); - } - arrSafe[iii]=arr3; arr[iii]=arr3; - continue; - } - } - return DataArray::Aggregate(arr); - } -} - -/*! - * This method is called to add NORM_POINT1 cells in \a this so that orphan nodes in \a verticesToAdd will be fetched. - */ -void MEDMeshMultiLev::appendVertices(const DataArrayInt *verticesToAdd, DataArrayInt *nr) -{ - int nbOfVertices(verticesToAdd->getNumberOfTuples()); - std::size_t sz(_pfls.size()); - _pfls.resize(sz+1); - _geo_types.resize(sz+1,INTERP_KERNEL::NORM_POINT1); - _nb_entities.resize(sz+1,nbOfVertices); - _node_reduction=nr; nr->incrRef(); - _nb_nodes+=nbOfVertices; - const DataArrayInt *cf(_cell_fam_ids),*cn(_cell_num_ids),*nf(_node_fam_ids),*nn(_node_num_ids); - if(cf) - { - MEDCouplingAutoRefCountObjectPtr tmp; - std::vector a(2); - a[0]=cf; - if(nf) - tmp=nf->selectByTupleIdSafe(verticesToAdd->begin(),verticesToAdd->end()); - else - { - tmp=DataArrayInt::New(); tmp->alloc(nbOfVertices,1); tmp->fillWithZero(); - } - a[1]=tmp; - _cell_fam_ids=DataArrayInt::Aggregate(a); - } - if(cn) - { - MEDCouplingAutoRefCountObjectPtr tmp; - std::vector a(2); - a[0]=cn; - if(nn) - tmp=nn->selectByTupleIdSafe(verticesToAdd->begin(),verticesToAdd->end()); - else - { - tmp=DataArrayInt::New(); tmp->alloc(nbOfVertices,1); tmp->fillWithZero(); - } - a[1]=tmp; - _cell_num_ids=DataArrayInt::Aggregate(a); - } -} - -MEDMeshMultiLev::MEDMeshMultiLev(const MEDFileMesh *mesh):_mesh(mesh),_nb_nodes(0) -{ -} - -MEDMeshMultiLev::MEDMeshMultiLev(const MEDFileMesh *mesh, int nbNodes, const std::vector& gts, const std::vector& pfls, const std::vector& nbEntities):_mesh(mesh),_geo_types(gts),_nb_entities(nbEntities),_nb_nodes(nbNodes) -{ - std::size_t sz(_geo_types.size()); - if(sz!=pfls.size() || sz!=nbEntities.size()) - throw INTERP_KERNEL::Exception("MEDMeshMultiLev::MEDMeshMultiLev : input vector must have the same size !"); - _pfls.resize(sz); - for(std::size_t i=0;iincrRef(); - _pfls[i]=const_cast(pfls[i]); - } -} - -MEDMeshMultiLev::MEDMeshMultiLev(const MEDMeshMultiLev& other):RefCountObject(other),_mesh(other._mesh),_pfls(other._pfls),_geo_types(other._geo_types),_nb_entities(other._nb_entities),_node_reduction(other._node_reduction),_nb_nodes(other._nb_nodes),_cell_fam_ids(other._cell_fam_ids),_cell_num_ids(other._cell_num_ids),_node_fam_ids(other._node_fam_ids),_node_num_ids(other._node_num_ids) -{ -} - -//= - -MEDUMeshMultiLev *MEDUMeshMultiLev::New(const MEDFileUMesh *m, const std::vector& levs) -{ - return new MEDUMeshMultiLev(m,levs); -} - -MEDUMeshMultiLev::MEDUMeshMultiLev(const MEDFileUMesh *m, const std::vector& levs):MEDMeshMultiLev(m) -{ - if(!m) - throw INTERP_KERNEL::Exception("MEDUMeshMultiLev constructor : null input pointer !"); - std::vector v; - for(std::vector::const_iterator it=levs.begin();it!=levs.end();it++) - { - std::vector vTmp(m->getDirectUndergroundSingleGeoTypeMeshes(*it)); - v.insert(v.end(),vTmp.begin(),vTmp.end()); - } - std::size_t sz(v.size()); - if(v.empty()) - { - _coords=m->getCoords(); _coords->incrRef(); - } - _parts.resize(sz); - _pfls.resize(sz); - _geo_types.resize(sz); - _nb_entities.resize(sz); - for(std::size_t i=0;iincrRef(); - else - throw INTERP_KERNEL::Exception("MEDUMeshMultiLev constructor : presence of a null pointer !"); - _parts[i]=obj; - _geo_types[i]=obj->getCellModelEnum(); - _nb_entities[i]=obj->getNumberOfCells(); - } - // ids fields management - bool cellFamIdsNoCpy(levs.size()==1); - if(cellFamIdsNoCpy) - { - const DataArrayInt *tmp(m->getFamilyFieldAtLevel(levs[0])); - if(tmp) - { - tmp->incrRef(); - _cell_fam_ids=(const_cast(tmp)); - } - } - else - { - std::vector tmps(levs.size()); - bool f(true); - for(std::size_t i=0;igetFamilyFieldAtLevel(levs[i]); - if(!tmps[i]) - f=false; - } - if(f && !tmps.empty()) - _cell_fam_ids=DataArrayInt::Aggregate(tmps); - } - bool cellNumIdsNoCpy(levs.size()==1); - if(cellNumIdsNoCpy) - { - const DataArrayInt *tmp(m->getNumberFieldAtLevel(levs[0])); - if(tmp) - { - tmp->incrRef(); - _cell_num_ids=(const_cast(tmp)); - } - } - else - { - std::vector tmps(levs.size()); - bool n(true); - for(std::size_t i=0;igetNumberFieldAtLevel(levs[i]); - if(!tmps[i]) - n=false; - } - if(n && !tmps.empty()) - _cell_num_ids=DataArrayInt::Aggregate(tmps); - } - // node part - { - const DataArrayInt *tmp(m->getFamilyFieldAtLevel(1)); - if(tmp) - { - tmp->incrRef(); - _node_fam_ids=(const_cast(tmp)); - } - } - { - const DataArrayInt *tmp(m->getNumberFieldAtLevel(1)); - if(tmp) - { - tmp->incrRef(); - _node_num_ids=(const_cast(tmp)); - } - } -} - -MEDUMeshMultiLev *MEDUMeshMultiLev::New(const MEDFileUMesh *m, const std::vector& gts, const std::vector& pfls, const std::vector& nbEntities) -{ - return new MEDUMeshMultiLev(m,gts,pfls,nbEntities); -} - -MEDUMeshMultiLev::MEDUMeshMultiLev(const MEDFileUMesh *m, const std::vector& gts, const std::vector& pfls, const std::vector& nbEntities):MEDMeshMultiLev(m,m->getNumberOfNodes(),gts,pfls,nbEntities) -{ - std::size_t sz(gts.size()); - if(sz<1) - throw INTERP_KERNEL::Exception("constructor of MEDUMeshMultiLev : number of different geo type must be >= 1 !"); - unsigned dim(INTERP_KERNEL::CellModel::GetCellModel(gts[0]).getDimension()); - _parts.resize(sz); - bool isSameDim(true),isNoPfl(true); - for(std::size_t i=0;igetDirectUndergroundSingleGeoTypeMesh(gts[i])); - if(INTERP_KERNEL::CellModel::GetCellModel(gts[i]).getDimension()!=dim) - isSameDim=false; - if(pfls[i]) - isNoPfl=false; - if(elt) - elt->incrRef(); - _parts[i]=elt; - } - // ids fields management - int lev((int)dim-m->getMeshDimension()); - if(isSameDim && isNoPfl && m->getGeoTypesAtLevel(lev)==gts)//optimized part - { - const DataArrayInt *famIds(m->getFamilyFieldAtLevel(lev)); - if(famIds) - { _cell_fam_ids=const_cast(famIds); famIds->incrRef(); } - const DataArrayInt *numIds(m->getNumberFieldAtLevel(lev)); - if(numIds) - { _cell_num_ids=const_cast(numIds); numIds->incrRef(); } - famIds=m->getFamilyFieldAtLevel(1); - if(famIds) - { _node_fam_ids=const_cast(famIds); famIds->incrRef(); } - numIds=m->getNumberFieldAtLevel(1); - if(numIds) - { _node_num_ids=const_cast(numIds); numIds->incrRef(); } - return ; - } - // - std::vector< MEDCouplingAutoRefCountObjectPtr > famIdsSafe(sz); - std::vector famIds(sz); - bool f(true); - for(std::size_t i=0;iextractFamilyFieldOnGeoType(gts[i]); - famIds[i]=famIdsSafe[i]; - if(!famIds[i]) - f=false; - } - if(f) - _cell_fam_ids=DataArrayInt::Aggregate(famIds); - std::vector< MEDCouplingAutoRefCountObjectPtr > numIdsSafe(sz); - std::vector numIds(sz); - bool n(true); - for(std::size_t i=0;iextractNumberFieldOnGeoType(gts[i]); - numIds[i]=numIdsSafe[i]; - if(!numIds[i]) - n=false; - } - if(n) - _cell_num_ids=DataArrayInt::Aggregate(numIds); - // node ids management - const DataArrayInt *nodeFamIds(m->getFamilyFieldAtLevel(1)); - if(nodeFamIds) - { _node_fam_ids=const_cast(nodeFamIds); nodeFamIds->incrRef(); } - const DataArrayInt *nodeNumIds(m->getNumberFieldAtLevel(1)); - if(nodeNumIds) - { _node_num_ids=const_cast(nodeNumIds); nodeNumIds->incrRef(); } -} - -void MEDUMeshMultiLev::selectPartOfNodes(const DataArrayInt *pflNodes) -{ - if(!pflNodes || !pflNodes->isAllocated()) - return ; - std::size_t sz(_parts.size()); - std::vector< MEDCouplingAutoRefCountObjectPtr > a(sz); - std::vector< const DataArrayInt *> aa(sz); - for(std::size_t i=0;i m(_parts[i]); - if(pfl) - m=dynamic_cast(_parts[i]->buildPartOfMySelfKeepCoords(pfl->begin(),pfl->end())); - DataArrayInt *cellIds=0; - m->fillCellIdsToKeepFromNodeIds(pflNodes->begin(),pflNodes->end(),true,cellIds); - MEDCouplingAutoRefCountObjectPtr cellIdsSafe(cellIds); - MEDCouplingAutoRefCountObjectPtr m2(m->buildPartOfMySelfKeepCoords(cellIds->begin(),cellIds->end())); - int tmp=-1; - MEDCouplingAutoRefCountObjectPtr o2n(m2->getNodeIdsInUse(tmp)); - a[i]=o2n->invertArrayO2N2N2O(tmp); aa[i]=a[i]; - if(pfl) - _pfls[i]=pfl->selectByTupleIdSafe(cellIds->begin(),cellIds->end()); - else - _pfls[i]=cellIdsSafe; - } - if(!aa.empty()) - _node_reduction=DataArrayInt::Aggregate(aa);//general case - else - _node_reduction=pflNodes->deepCpy();//case where no cells in read mesh. - _node_reduction->sort(true); - _node_reduction=_node_reduction->buildUnique(); - if(_node_reduction->getNumberOfTuples()==pflNodes->getNumberOfTuples()) - return ;//This is the classical case where the input node profile corresponds perfectly to a subset of cells in _parts - if(_node_reduction->getNumberOfTuples()>pflNodes->getNumberOfTuples()) - throw INTERP_KERNEL::Exception("MEDUMeshMultiLev::selectPartOfNodes : internal error in MEDCoupling during cell select from a list of nodes !"); - // Here the cells available in _parts is not enough to cover all the nodes in pflNodes. So adding vertices cells in _parts... - MEDCouplingAutoRefCountObjectPtr pflNodes2(pflNodes->deepCpy()); - pflNodes2->sort(true); - MEDCouplingAutoRefCountObjectPtr diff(pflNodes2->buildSubstractionOptimized(_node_reduction)); - appendVertices(diff,pflNodes2); -} - -MEDMeshMultiLev *MEDUMeshMultiLev::prepare() const -{ - return new MEDUMeshMultiLev(*this); -} - -MEDUMeshMultiLev::MEDUMeshMultiLev(const MEDUMeshMultiLev& other):MEDMeshMultiLev(other),_parts(other._parts),_coords(other._coords) -{ -} - -MEDUMeshMultiLev::MEDUMeshMultiLev(const MEDStructuredMeshMultiLev& other, const MEDCouplingAutoRefCountObjectPtr& part):MEDMeshMultiLev(other) -{ - _parts.resize(1); - _parts[0]=part; - _geo_types.resize(1); _geo_types[0]=part->getCellModelEnum(); - _nb_entities.resize(1); _nb_entities[0]=part->getNumberOfCells(); - _pfls.resize(1); _pfls[0]=0; -} - -/*! - * To be called only once ! Because due to some optimizations (sometimes aggressive) the internal state can be changed... - * If returned value is false output pointer \a coords is not the internal pointer. If returned value is true output pointer \a coords is directly the internal pointer. - * If true is returned, the \a coords output parameter should be used with care (non const method call) to avoid to change the internal state of MEDFileUMesh instance. - */ -bool MEDUMeshMultiLev::buildVTUArrays(DataArrayDouble *& coords, DataArrayByte *&types, DataArrayInt *&cellLocations, DataArrayInt *& cells, DataArrayInt *&faceLocations, DataArrayInt *&faces) const -{ - const DataArrayDouble *tmp(0); - if(_parts.empty()) - tmp=_coords; - else - tmp=_parts[0]->getCoords(); - if(!tmp) - throw INTERP_KERNEL::Exception("MEDUMeshMultiLev::getVTUArrays : the coordinates are null !"); - MEDCouplingAutoRefCountObjectPtr a(const_cast(tmp)); tmp->incrRef(); - int szBCE(0),szD(0),szF(0); - bool isPolyh(false); - int iii(0); - for(std::vector< MEDCouplingAutoRefCountObjectPtr >::const_iterator it=_parts.begin();it!=_parts.end();it++,iii++) - { - const MEDCoupling1GTUMesh *cur(*it); - if(!cur) - throw INTERP_KERNEL::Exception("MEDUMeshMultiLev::getVTUArrays : a part is null !"); - // - const DataArrayInt *pfl(_pfls[iii]); - MEDCouplingAutoRefCountObjectPtr cur2; - if(!pfl) - { cur2=const_cast(cur); cur2->incrRef(); } - else - { cur2=dynamic_cast(cur->buildPartOfMySelfKeepCoords(pfl->begin(),pfl->end())); cur=cur2; } - // - int curNbCells(cur->getNumberOfCells()); - szBCE+=curNbCells; - if((*it)->getCellModelEnum()!=INTERP_KERNEL::NORM_POLYHED) - szD+=cur->getNodalConnectivity()->getNumberOfTuples()+curNbCells; - else - { - isPolyh=true; - MEDCouplingAutoRefCountObjectPtr tmp2(cur->computeEffectiveNbOfNodesPerCell()); - szD+=tmp2->accumulate(0)+curNbCells; - szF+=2*curNbCells+cur->getNodalConnectivity()->getNumberOfTuples(); - } - } - MEDCouplingAutoRefCountObjectPtr b(DataArrayByte::New()); b->alloc(szBCE,1); char *bPtr(b->getPointer()); - MEDCouplingAutoRefCountObjectPtr c(DataArrayInt::New()); c->alloc(szBCE,1); int *cPtr(c->getPointer()); - MEDCouplingAutoRefCountObjectPtr d(DataArrayInt::New()); d->alloc(szD,1); int *dPtr(d->getPointer()); - MEDCouplingAutoRefCountObjectPtr e(DataArrayInt::New()),f(DataArrayInt::New()); int *ePtr(0),*fPtr(0); - if(isPolyh) - { e->alloc(szBCE,1); ePtr=e->getPointer(); f->alloc(szF,1); fPtr=f->getPointer(); } - int k(0); - iii=0; - for(std::vector< MEDCouplingAutoRefCountObjectPtr >::const_iterator it=_parts.begin();it!=_parts.end();it++,iii++) - { - const MEDCoupling1GTUMesh *cur(*it); - // - const DataArrayInt *pfl(_pfls[iii]); - MEDCouplingAutoRefCountObjectPtr cur2; - if(!pfl) - { cur2=const_cast(cur); cur2->incrRef(); } - else - { cur2=dynamic_cast(cur->buildPartOfMySelfKeepCoords(pfl->begin(),pfl->end())); cur=cur2; } - // - int curNbCells(cur->getNumberOfCells()); - int gt((int)cur->getCellModelEnum()); - if(gt<0 || gt>=PARAMEDMEM_2_VTKTYPE_LGTH) - throw INTERP_KERNEL::Exception("MEDUMeshMultiLev::getVTUArrays : invalid geometric type !"); - unsigned char gtvtk(PARAMEDMEM_2_VTKTYPE[gt]); - if(gtvtk==255) - throw INTERP_KERNEL::Exception("MEDUMeshMultiLev::getVTUArrays : no VTK type for the requested INTERP_KERNEL geometric type !"); - std::fill(bPtr,bPtr+curNbCells,gtvtk); bPtr+=curNbCells; - const MEDCoupling1SGTUMesh *scur(dynamic_cast(cur)); - const MEDCoupling1DGTUMesh *dcur(dynamic_cast(cur)); - const int *connPtr(cur->getNodalConnectivity()->begin()); - if(!scur && !dcur) - throw INTERP_KERNEL::Exception("MEDUMeshMultiLev::getVTUArrays : internal error !"); - if(scur) - { - if(cur->getCellModelEnum()!=INTERP_KERNEL::NORM_HEXA27) - { - int nnpc(scur->getNumberOfNodesPerCell()); - for(int i=0;igetNodalConnectivityIndex()->begin()); - if(cur->getCellModelEnum()!=INTERP_KERNEL::NORM_POLYHED) - { - for(int i=0;i s(connPtr+connIPtr[0],connPtr+connIPtr[1]); s.erase(-1); - *dPtr++=(int)s.size(); - dPtr=std::copy(s.begin(),s.end(),dPtr); - *cPtr++=k; k+=(int)s.size()+1; - } - } - if(isPolyh) - { - connIPtr=dcur->getNodalConnectivityIndex()->begin(); - if(cur->getCellModelEnum()!=INTERP_KERNEL::NORM_POLYHED) - { std::fill(ePtr,ePtr+curNbCells,-1); ePtr+=curNbCells; } - else - { - int kk(0); - for(int i=0;igetNumberOfComponents()!=3) - a=a->changeNbOfComponents(3,0.); - coords=a.retn(); types=b.retn(); cellLocations=c.retn(); cells=d.retn(); - if(!isPolyh) - { faceLocations=0; faces=0; } - else - { faceLocations=e.retn(); faces=f.retn(); } - return _mesh->isObjectInTheProgeny(coords); -} - -void MEDUMeshMultiLev::reorderNodesIfNecessary(MEDCouplingAutoRefCountObjectPtr& coords, DataArrayInt *nodalConnVTK, DataArrayInt *polyhedNodalConnVTK) const -{ - const DataArrayInt *nr(_node_reduction); - if(!nr) - return ; - if(nodalConnVTK->empty() && !polyhedNodalConnVTK) - { - coords=(coords->selectByTupleIdSafe(nr->begin(),nr->end())); - return ; - } - int sz(coords->getNumberOfTuples()); - std::vector b(sz,false); - const int *work(nodalConnVTK->begin()),*endW(nodalConnVTK->end()); - while(work!=endW) - { - int nb(*work++); - for(int i=0;i=0 && *workbegin(); endW=polyhedNodalConnVTK->end(); - while(work!=endW) - { - int nb(*work++); - for(int i=0;i=0 && *workgetNumberOfTuples()) - throw INTERP_KERNEL::Exception("MEDUMeshMultiLev::reorderNodesIfNecessary : internal error #3 !"); - // Go renumbering ! - MEDCouplingAutoRefCountObjectPtr o2n(DataArrayInt::New()); o2n->alloc(sz,1); - int *o2nPtr(o2n->getPointer()); - int newId(0); - for(int i=0;ibegin()); - MEDCouplingAutoRefCountObjectPtr n2o(o2n->invertArrayO2N2N2O(nr->getNumberOfTuples())); - MEDCouplingAutoRefCountObjectPtr perm(DataArrayInt::FindPermutationFromFirstToSecond(n2o,nr)); - const int *permPtr(perm->begin()); - int *work2(nodalConnVTK->getPointer()),*endW2(nodalConnVTK->getPointer()+nodalConnVTK->getNumberOfTuples()); - while(work2!=endW2) - { - int nb(*work2++); - for(int i=0;igetPointer(); endW2=polyhedNodalConnVTK->getPointer()+polyhedNodalConnVTK->getNumberOfTuples(); - while(work2!=endW2) - { - int nb(*work2++); - for(int i=0;iselectByTupleIdSafe(nr->begin(),nr->end())); -} - - -void MEDUMeshMultiLev::appendVertices(const DataArrayInt *verticesToAdd, DataArrayInt *nr) -{ - int nbOfCells(verticesToAdd->getNumberOfTuples());//it is not a bug cells are NORM_POINT1 - MEDMeshMultiLev::appendVertices(verticesToAdd,nr); - MEDCouplingAutoRefCountObjectPtr elt(MEDCoupling1SGTUMesh::New("",INTERP_KERNEL::NORM_POINT1)); - elt->allocateCells(nbOfCells); - for(int i=0;igetIJ(i,0)); - elt->insertNextCell(&pt,&pt+1); - } - if(_parts.empty()) - throw INTERP_KERNEL::Exception("MEDUMeshMultiLev::appendVertices : parts are empty !"); - elt->setCoords(_parts[0]->getCoords()); - MEDCouplingAutoRefCountObjectPtr elt2((MEDCoupling1SGTUMesh *)elt); elt2->incrRef(); - _parts.push_back(elt2); -} - -//= - -MEDStructuredMeshMultiLev::MEDStructuredMeshMultiLev(const MEDFileStructuredMesh *m, const std::vector& lev):MEDMeshMultiLev(m),_is_internal(true) -{ - initStdFieldOfIntegers(m); -} - -MEDStructuredMeshMultiLev::MEDStructuredMeshMultiLev(const MEDFileStructuredMesh *m, int nbOfNodes, const std::vector& gts, const std::vector& pfls, const std::vector& nbEntities):MEDMeshMultiLev(m,nbOfNodes,gts,pfls,nbEntities),_is_internal(true) -{ - initStdFieldOfIntegers(m); -} - -MEDStructuredMeshMultiLev::MEDStructuredMeshMultiLev(const MEDStructuredMeshMultiLev& other):MEDMeshMultiLev(other),_is_internal(true),_face_fam_ids(other._face_fam_ids),_face_num_ids(other._face_num_ids) -{ -} - -void MEDStructuredMeshMultiLev::initStdFieldOfIntegers(const MEDFileStructuredMesh *m) -{ - // ids fields management - const DataArrayInt *tmp(0); - tmp=m->getFamilyFieldAtLevel(0); - if(tmp) - { - tmp->incrRef(); - _cell_fam_ids=const_cast(tmp); - } - tmp=m->getNumberFieldAtLevel(0); - if(tmp) - { - tmp->incrRef(); - _cell_num_ids=const_cast(tmp); - } - // - tmp=0; - tmp=m->getFamilyFieldAtLevel(1); - if(tmp) - { - tmp->incrRef(); - _node_fam_ids=const_cast(tmp); - } - tmp=m->getNumberFieldAtLevel(1); - if(tmp) - { - tmp->incrRef(); - _node_num_ids=const_cast(tmp); - } - // faces (if any) - tmp=m->getFamilyFieldAtLevel(-1); - if(tmp) - { - tmp->incrRef(); - _face_fam_ids=const_cast(tmp); - } - tmp=m->getNumberFieldAtLevel(-1); - if(tmp) - { - tmp->incrRef(); - _face_num_ids=const_cast(tmp); - } -} - -void MEDStructuredMeshMultiLev::moveFaceToCell() const -{ - const_cast(this)->_cell_fam_ids=_face_fam_ids; const_cast(this)->_face_fam_ids=0; - const_cast(this)->_cell_num_ids=_face_num_ids; const_cast(this)->_face_num_ids=0; -} - -bool MEDStructuredMeshMultiLev::prepareForImplicitUnstructuredMeshCase(MEDMeshMultiLev *&ret) const -{ - ret=0; - if(_geo_types.empty()) - return false; - if(_geo_types.size()!=1) - throw INTERP_KERNEL::Exception("MEDStructuredMeshMultiLev::prepareForImplicitUnstructuredMeshCase only one geo types supported at most supported for the moment !"); - INTERP_KERNEL::NormalizedCellType gt(MEDCouplingStructuredMesh::GetGeoTypeGivenMeshDimension(_mesh->getMeshDimension())); - if(_geo_types[0]==gt) - return false; - MEDCoupling1GTUMesh *facesIfPresent((static_cast(_mesh))->getImplicitFaceMesh()); - if(!facesIfPresent) - return false; - const DataArrayInt *pfl(0),*nr(_node_reduction); - if(!_pfls.empty()) - pfl=_pfls[0]; - MEDCouplingAutoRefCountObjectPtr facesIfPresent2(facesIfPresent); facesIfPresent->incrRef(); - moveFaceToCell(); - MEDCouplingAutoRefCountObjectPtr ret2(new MEDUMeshMultiLev(*this,facesIfPresent2)); - if(pfl) - ret2->setCellReduction(pfl); - if(nr) - throw INTERP_KERNEL::Exception("MEDStructuredMeshMultiLev::prepareForImplicitUnstructuredMeshCase : case is not treated yet for node reduction on implicit unstructured mesh."); - ret=ret2.retn(); - return true; -} - -void MEDStructuredMeshMultiLev::dealWithImplicitUnstructuredMesh(const MEDFileMesh *m) -{ - const DataArrayInt *tmp(0); - tmp=m->getFamilyFieldAtLevel(-1); - if(tmp) - { - tmp->incrRef(); - _cell_fam_ids=const_cast(tmp); - } - tmp=m->getNumberFieldAtLevel(-1); - if(tmp) - { - tmp->incrRef(); - _cell_num_ids=const_cast(tmp); - } -} - -void MEDStructuredMeshMultiLev::selectPartOfNodes(const DataArrayInt *pflNodes) -{ - if(!pflNodes || !pflNodes->isAllocated()) - return ; - std::vector ngs(getNodeGridStructure()); - MEDCouplingAutoRefCountObjectPtr conn(MEDCouplingStructuredMesh::Build1GTNodalConnectivity(&ngs[0],&ngs[0]+ngs.size())); - MEDCouplingAutoRefCountObjectPtr m(MEDCoupling1SGTUMesh::New("",MEDCouplingStructuredMesh::GetGeoTypeGivenMeshDimension(ngs.size()))); - m->setNodalConnectivity(conn); - const DataArrayInt *pfl(_pfls[0]); - if(pfl) - { - m=dynamic_cast(m->buildPartOfMySelfKeepCoords(pfl->begin(),pfl->end())); - } - DataArrayInt *cellIds=0; - m->fillCellIdsToKeepFromNodeIds(pflNodes->begin(),pflNodes->end(),true,cellIds); - MEDCouplingAutoRefCountObjectPtr cellIdsSafe(cellIds); - MEDCouplingAutoRefCountObjectPtr m2(m->buildPartOfMySelfKeepCoords(cellIds->begin(),cellIds->end())); - int tmp=-1; - _node_reduction=m2->getNodeIdsInUse(tmp); - if(pfl) - _pfls[0]=pfl->selectByTupleIdSafe(cellIds->begin(),cellIds->end()); - else - _pfls[0]=cellIdsSafe; -} - -//= - -MEDCMeshMultiLev *MEDCMeshMultiLev::New(const MEDFileCMesh *m, const std::vector& levs) -{ - return new MEDCMeshMultiLev(m,levs); -} - -MEDCMeshMultiLev *MEDCMeshMultiLev::New(const MEDFileCMesh *m, const std::vector& gts, const std::vector& pfls, const std::vector& nbEntities) -{ - return new MEDCMeshMultiLev(m,gts,pfls,nbEntities); -} - -MEDCMeshMultiLev::MEDCMeshMultiLev(const MEDFileCMesh *m, const std::vector& levs):MEDStructuredMeshMultiLev(m,levs) -{ - if(!m) - throw INTERP_KERNEL::Exception("MEDCMeshMultiLev constructor : null input pointer !"); - if(levs.size()!=1 || levs[0]!=0) - throw INTERP_KERNEL::Exception("MEDCMeshMultiLev constructor : levels supported is 0 only !"); - int sdim(m->getSpaceDimension()); - _coords.resize(sdim); - for(int i=0;i(m->getMesh()->getCoordsAt(i))); - if(!elt) - throw INTERP_KERNEL::Exception("MEDCMeshMultiLev constructor 2 : presence of null pointer for an vector of double along an axis !"); - elt->incrRef(); - _coords[i]=elt; - } -} - -MEDCMeshMultiLev::MEDCMeshMultiLev(const MEDFileCMesh *m, const std::vector& gts, const std::vector& pfls, const std::vector& nbEntities):MEDStructuredMeshMultiLev(m,m->getNumberOfNodes(),gts,pfls,nbEntities) -{ - if(!m) - throw INTERP_KERNEL::Exception("MEDCMeshMultiLev constructor 2 : null input pointer !"); - if(gts.size()!=1 || pfls.size()!=1) - throw INTERP_KERNEL::Exception("MEDCMeshMultiLev constructor 2 : lengthes of gts and pfls must be equal to one !"); - int mdim(m->getMeshDimension()); - INTERP_KERNEL::NormalizedCellType gt(MEDCouplingStructuredMesh::GetGeoTypeGivenMeshDimension(mdim)); - if(gt==gts[0]) - { - _coords.resize(mdim); - for(int i=0;i(m->getMesh()->getCoordsAt(i))); - if(!elt) - throw INTERP_KERNEL::Exception("MEDCMeshMultiLev constructor 2 : presence of null pointer for an vector of double along an axis !"); - _coords[i]=elt; _coords[i]->incrRef(); - } - } - else - dealWithImplicitUnstructuredMesh(m); -} - -MEDCMeshMultiLev::MEDCMeshMultiLev(const MEDCMeshMultiLev& other):MEDStructuredMeshMultiLev(other),_coords(other._coords) -{ -} - -std::vector MEDCMeshMultiLev::getNodeGridStructure() const -{ - std::vector ret(_coords.size()); - for(std::size_t i=0;i<_coords.size();i++) - ret[i]=_coords[i]->getNumberOfTuples(); - return ret; -} - -MEDMeshMultiLev *MEDCMeshMultiLev::prepare() const -{ - MEDMeshMultiLev *retSpecific(0); - if(prepareForImplicitUnstructuredMeshCase(retSpecific)) - return retSpecific; - const DataArrayInt *pfl(0),*nr(_node_reduction); - if(!_pfls.empty()) - pfl=_pfls[0]; - MEDCouplingAutoRefCountObjectPtr nnr; - std::vector cgs,ngs(getNodeGridStructure()); - cgs.resize(ngs.size()); - std::transform(ngs.begin(),ngs.end(),cgs.begin(),std::bind2nd(std::plus(),-1)); - if(pfl) - { - std::vector< std::pair > cellParts; - MEDCouplingAutoRefCountObjectPtr ret2; - if(MEDCouplingStructuredMesh::IsPartStructured(pfl->begin(),pfl->end(),cgs,cellParts)) - { - MEDCouplingAutoRefCountObjectPtr ret(new MEDCMeshMultiLev(*this)); - ret->_is_internal=false; - if(nr) - { nnr=nr->deepCpy(); nnr->sort(true); ret->setNodeReduction(nnr); } - ret->_nb_entities[0]=pfl->getNumberOfTuples(); - ret->_pfls[0]=0; - std::vector< MEDCouplingAutoRefCountObjectPtr > coords(_coords.size()); - for(std::size_t i=0;i<_coords.size();i++) - coords[i]=_coords[i]->selectByTupleId2(cellParts[i].first,cellParts[i].second+1,1); - ret->_coords=coords; - ret2=(MEDCMeshMultiLev *)ret; ret2->incrRef(); - } - else - { - MEDCouplingAutoRefCountObjectPtr m(MEDCouplingCMesh::New()); - for(std::size_t i=0;isetCoordsAt(i,_coords[i]); - MEDCouplingAutoRefCountObjectPtr m2(m->build1SGTUnstructured()); - MEDCouplingAutoRefCountObjectPtr m3=dynamic_cast(m2->buildPartOfMySelfKeepCoords(pfl->begin(),pfl->end())); - MEDCouplingAutoRefCountObjectPtr ret(new MEDUMeshMultiLev(*this,m3)); - if(nr) - { m3->zipCoords(); nnr=nr->deepCpy(); nnr->sort(true); ret->setNodeReduction(nnr); } - ret2=(MEDUMeshMultiLev *)ret; ret2->incrRef(); - } - const DataArrayInt *famIds(_cell_fam_ids),*numIds(_cell_num_ids); - if(famIds) - { - MEDCouplingAutoRefCountObjectPtr tmp(famIds->selectByTupleIdSafe(pfl->begin(),pfl->end())); - ret2->setFamilyIdsOnCells(tmp); - } - if(numIds) - { - MEDCouplingAutoRefCountObjectPtr tmp(numIds->selectByTupleIdSafe(pfl->begin(),pfl->end())); - ret2->setNumberIdsOnCells(tmp); - } - return ret2.retn(); - - } - else - { - MEDCouplingAutoRefCountObjectPtr ret(new MEDCMeshMultiLev(*this)); - if(nr) - { nnr=nr->deepCpy(); nnr->sort(true); ret->setNodeReduction(nnr); } - return ret.retn(); - } -} - -/*! - * \a param [out] isInternal if true the returned pointers are those in main data structure. If false those pointers have been built espacially for that method. - */ -std::vector< DataArrayDouble * > MEDCMeshMultiLev::buildVTUArrays(bool& isInternal) const -{ - isInternal=_is_internal; - std::size_t sz(_coords.size()); - std::vector< DataArrayDouble * > ret(sz); - for(std::size_t i=0;i((const DataArrayDouble *)_coords[i]); - ret[i]->incrRef(); - } - return ret; -} - -//= - -MEDCurveLinearMeshMultiLev *MEDCurveLinearMeshMultiLev::New(const MEDFileCurveLinearMesh *m, const std::vector& levs) -{ - return new MEDCurveLinearMeshMultiLev(m,levs); -} - -MEDCurveLinearMeshMultiLev *MEDCurveLinearMeshMultiLev::New(const MEDFileCurveLinearMesh *m, const std::vector& gts, const std::vector& pfls, const std::vector& nbEntities) -{ - return new MEDCurveLinearMeshMultiLev(m,gts,pfls,nbEntities); -} - -MEDCurveLinearMeshMultiLev::MEDCurveLinearMeshMultiLev(const MEDFileCurveLinearMesh *m, const std::vector& levs):MEDStructuredMeshMultiLev(m,levs) -{ - if(!m) - throw INTERP_KERNEL::Exception("MEDCurveLinearMeshMultiLev constructor : null input pointer !"); - if(levs.size()!=1 || levs[0]!=0) - throw INTERP_KERNEL::Exception("MEDCurveLinearMeshMultiLev constructor : levels supported is 0 only !"); - DataArrayDouble *coords(const_cast(m->getMesh()->getCoords())); - if(!coords) - throw INTERP_KERNEL::Exception("MEDCurveLinearMeshMultiLev constructor 2 : no coords set !"); - coords->incrRef(); - _coords=coords; - _structure=m->getMesh()->getNodeGridStructure(); -} - -MEDCurveLinearMeshMultiLev::MEDCurveLinearMeshMultiLev(const MEDFileCurveLinearMesh *m, const std::vector& gts, const std::vector& pfls, const std::vector& nbEntities):MEDStructuredMeshMultiLev(m,m->getNumberOfNodes(),gts,pfls,nbEntities) -{ - if(!m) - throw INTERP_KERNEL::Exception("MEDCurveLinearMeshMultiLev constructor 2 : null input pointer !"); - if(gts.size()!=1 || pfls.size()!=1) - throw INTERP_KERNEL::Exception("MEDCurveLinearMeshMultiLev constructor 2 : lengthes of gts and pfls must be equal to one !"); - INTERP_KERNEL::NormalizedCellType gt(MEDCouplingStructuredMesh::GetGeoTypeGivenMeshDimension(m->getMeshDimension())); - if(gt==gts[0]) - { - DataArrayDouble *coords(const_cast(m->getMesh()->getCoords())); - if(!coords) - throw INTERP_KERNEL::Exception("MEDCurveLinearMeshMultiLev constructor 2 : no coords set !"); - coords->incrRef(); - _coords=coords; - _structure=m->getMesh()->getNodeGridStructure(); - } - else - dealWithImplicitUnstructuredMesh(m); -} - -MEDCurveLinearMeshMultiLev::MEDCurveLinearMeshMultiLev(const MEDCurveLinearMeshMultiLev& other):MEDStructuredMeshMultiLev(other),_coords(other._coords),_structure(other._structure) -{ -} - -std::vector MEDCurveLinearMeshMultiLev::getNodeGridStructure() const -{ - return _structure; -} - -MEDMeshMultiLev *MEDCurveLinearMeshMultiLev::prepare() const -{ - MEDMeshMultiLev *retSpecific(0); - if(prepareForImplicitUnstructuredMeshCase(retSpecific)) - return retSpecific; - const DataArrayInt *pfl(0),*nr(_node_reduction); - if(!_pfls.empty()) - pfl=_pfls[0]; - MEDCouplingAutoRefCountObjectPtr nnr; - std::vector cgs,ngs(getNodeGridStructure()); - cgs.resize(ngs.size()); - std::transform(ngs.begin(),ngs.end(),cgs.begin(),std::bind2nd(std::plus(),-1)); - if(pfl) - { - std::vector< std::pair > cellParts,nodeParts; - MEDCouplingAutoRefCountObjectPtr ret2; - if(MEDCouplingStructuredMesh::IsPartStructured(pfl->begin(),pfl->end(),cgs,cellParts)) - { - nodeParts=cellParts; - std::vector st(ngs.size()); - for(std::size_t i=0;i p(MEDCouplingStructuredMesh::BuildExplicitIdsFrom(ngs,nodeParts)); - MEDCouplingAutoRefCountObjectPtr ret(new MEDCurveLinearMeshMultiLev(*this)); - ret->_is_internal=false; - if(nr) - { nnr=nr->deepCpy(); nnr->sort(true); ret->setNodeReduction(nnr); } - ret->_nb_entities[0]=pfl->getNumberOfTuples(); - ret->_pfls[0]=0; - ret->_coords=_coords->selectByTupleIdSafe(p->begin(),p->end()); - ret->_structure=st; - ret2=(MEDCurveLinearMeshMultiLev *)ret; ret2->incrRef(); - } - else - { - MEDCouplingAutoRefCountObjectPtr m(MEDCouplingCurveLinearMesh::New()); - m->setCoords(_coords); m->setNodeGridStructure(&_structure[0],&_structure[0]+_structure.size()); - MEDCouplingAutoRefCountObjectPtr m2(m->build1SGTUnstructured()); - MEDCouplingAutoRefCountObjectPtr m3=dynamic_cast(m2->buildPartOfMySelfKeepCoords(pfl->begin(),pfl->end())); - MEDCouplingAutoRefCountObjectPtr ret(new MEDUMeshMultiLev(*this,m3)); - if(nr) - { m3->zipCoords(); nnr=nr->deepCpy(); nnr->sort(true); ret->setNodeReduction(nnr); } - ret2=(MEDUMeshMultiLev *)ret; ret2->incrRef(); - } - const DataArrayInt *famIds(_cell_fam_ids),*numIds(_cell_num_ids); - if(famIds) - { - MEDCouplingAutoRefCountObjectPtr tmp(famIds->selectByTupleIdSafe(pfl->begin(),pfl->end())); - ret2->setFamilyIdsOnCells(tmp); - } - if(numIds) - { - MEDCouplingAutoRefCountObjectPtr tmp(numIds->selectByTupleIdSafe(pfl->begin(),pfl->end())); - ret2->setNumberIdsOnCells(tmp); - } - return ret2.retn(); - } - else - { - MEDCouplingAutoRefCountObjectPtr ret(new MEDCurveLinearMeshMultiLev(*this)); - if(nr) - { nnr=nr->deepCpy(); nnr->sort(true); ret->setNodeReduction(nnr); } - return ret.retn(); - } -} - -void MEDCurveLinearMeshMultiLev::buildVTUArrays(DataArrayDouble *&coords, std::vector& nodeStrct, bool& isInternal) const -{ - isInternal=_is_internal; - nodeStrct=_structure; - const DataArrayDouble *coo(_coords); - if(!coo) - throw INTERP_KERNEL::Exception("MEDCurveLinearMeshMultiLev::buildVTUArrays : null pointer on coordinates !"); - coords=const_cast(coo); coords->incrRef(); -} - -//= - -MEDFileField1TSStructItem2::MEDFileField1TSStructItem2() -{ -} - -MEDFileField1TSStructItem2::MEDFileField1TSStructItem2(INTERP_KERNEL::NormalizedCellType a, const std::pair& b, const std::string& c, const std::string& d):_geo_type(a),_start_end(b),_pfl(DataArrayInt::New()),_loc(d),_nb_of_entity(-1) -{ - _pfl->setName(c.c_str()); -} - -void MEDFileField1TSStructItem2::checkWithMeshStructForCells(const MEDFileMeshStruct *mst, const MEDFileFieldGlobsReal *globs) -{ - if(!mst->doesManageGeoType(_geo_type)) - { - MEDFileMeshStruct *mstUnConstCasted(const_cast(mst)); - mstUnConstCasted->appendIfImplicitType(_geo_type); - } - int nbOfEnt=mst->getNumberOfElemsOfGeoType(_geo_type); - checkInRange(nbOfEnt,1,globs); -} - -void MEDFileField1TSStructItem2::checkWithMeshStructForGaussNE(const MEDFileMeshStruct *mst, const MEDFileFieldGlobsReal *globs) -{ - int nbOfEnt=mst->getNumberOfElemsOfGeoType(_geo_type); - const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(_geo_type); - checkInRange(nbOfEnt,(int)cm.getNumberOfNodes(),globs); -} - -void MEDFileField1TSStructItem2::checkWithMeshStructForGaussPT(const MEDFileMeshStruct *mst, const MEDFileFieldGlobsReal *globs) -{ - if(!globs) - throw INTERP_KERNEL::Exception("MEDFileField1TSStructItem2::checkWithMeshStructForGaussPT : no globals specified !"); - if(_loc.empty()) - throw INTERP_KERNEL::Exception("MEDFileField1TSStructItem2::checkWithMeshStructForGaussPT : no localization specified !"); - const MEDFileFieldLoc& loc=globs->getLocalization(_loc.c_str()); - int nbOfEnt=mst->getNumberOfElemsOfGeoType(_geo_type); - checkInRange(nbOfEnt,loc.getNumberOfGaussPoints(),globs); -} - -int MEDFileField1TSStructItem2::getNbOfIntegrationPts(const MEDFileFieldGlobsReal *globs) const -{ - if(_loc.empty()) - { - if(getPflName().empty()) - return (_start_end.second-_start_end.first)/_nb_of_entity; - else - return (_start_end.second-_start_end.first)/getPfl(globs)->getNumberOfTuples(); - } - else - { - const MEDFileFieldLoc& loc(globs->getLocalization(_loc.c_str())); - return loc.getNumberOfGaussPoints(); - } -} - -std::string MEDFileField1TSStructItem2::getPflName() const -{ - return _pfl->getName(); -} - -const DataArrayInt *MEDFileField1TSStructItem2::getPfl(const MEDFileFieldGlobsReal *globs) const -{ - if(!_pfl->isAllocated()) - { - if(_pfl->getName().empty()) - return 0; - else - return globs->getProfile(_pfl->getName().c_str()); - } - else - return _pfl; -} - -/*! - * \param [in] nbOfEntity - number of entity that can be either cells or nodes. Not other possiblity. - * \param [in] nip - number of integration points. 1 for ON_CELLS and NO_NODES - */ -void MEDFileField1TSStructItem2::checkInRange(int nbOfEntity, int nip, const MEDFileFieldGlobsReal *globs) -{ - _nb_of_entity=nbOfEntity; - if(_pfl->getName().empty()) - { - if(nbOfEntity!=(_start_end.second-_start_end.first)/nip) - throw INTERP_KERNEL::Exception("MEDFileField1TSStructItem2::checkInRange : Mismatch between number of entities and size of field !"); - return ; - } - else - { - if(!globs) - throw INTERP_KERNEL::Exception("MEDFileField1TSStructItem2::checkInRange : Presence of a profile on field whereas no globals found in file !"); - const DataArrayInt *pfl=globs->getProfile(_pfl->getName().c_str()); - if(!pfl) - throw INTERP_KERNEL::Exception("MEDFileField1TSStructItem2::checkInRange : Presence of a profile on field whereas no such profile found in file !"); - pfl->checkAllIdsInRange(0,nbOfEntity); - } -} - -bool MEDFileField1TSStructItem2::isFastlyEqual(int& startExp, INTERP_KERNEL::NormalizedCellType gt, const std::string& pflName) const -{ - if(startExp!=_start_end.first) - return false; - if(gt!=_geo_type) - return false; - if(getPflName()!=pflName) - return false; - startExp=_start_end.second; - return true; -} - -bool MEDFileField1TSStructItem2::operator==(const MEDFileField1TSStructItem2& other) const -{ - //_nb_of_entity is not taken into account here. It is not a bug, because no mesh consideration needed here to perform fast compare. - //idem for _loc. It is not an effective attribute for support comparison. - return _geo_type==other._geo_type && _start_end==other._start_end && _pfl->getName()==other._pfl->getName(); -} - -bool MEDFileField1TSStructItem2::isCellSupportEqual(const MEDFileField1TSStructItem2& other, const MEDFileFieldGlobsReal *globs) const -{ - if(_geo_type!=other._geo_type) - return false; - if(_nb_of_entity!=other._nb_of_entity) - return false; - if((_pfl->getName().empty() && !other._pfl->getName().empty()) || (!_pfl->getName().empty() && other._pfl->getName().empty())) - return false; - if(_pfl->getName().empty() && other._pfl->getName().empty()) - return true; - const DataArrayInt *pfl1(getPfl(globs)),*pfl2(other.getPfl(globs)); - return pfl1->isEqualWithoutConsideringStr(*pfl2); -} - -bool MEDFileField1TSStructItem2::isNodeSupportEqual(const MEDFileField1TSStructItem2& other, const MEDFileFieldGlobsReal *globs) const -{ - return isCellSupportEqual(other,globs); -} - -/*! - * \a objs must be non empty. \a objs should contain items having same geometric type. - */ -MEDFileField1TSStructItem2 MEDFileField1TSStructItem2::BuildAggregationOf(const std::vector& objs, const MEDFileFieldGlobsReal *globs) -{ - if(objs.empty()) - throw INTERP_KERNEL::Exception("MEDFileField1TSStructItem2::BuildAggregationOf : empty input !"); - if(objs.size()==1) - return MEDFileField1TSStructItem2(*objs[0]); - INTERP_KERNEL::NormalizedCellType gt(objs[0]->_geo_type); - int nbEntityRef(objs[0]->_nb_of_entity); - std::size_t sz(objs.size()); - std::vector arrs(sz); - for(std::size_t i=0;i_geo_type) - throw INTERP_KERNEL::Exception("MEDFileField1TSStructItem2::BuildAggregationOf : invalid situation ! All input must have the same geo type !"); - if(nbEntityRef!=obj->_nb_of_entity) - throw INTERP_KERNEL::Exception("MEDFileField1TSStructItem2::BuildAggregationOf : invalid situation ! All input must have the global nb of entity !"); - if(obj->_pfl->getName().empty()) - throw INTERP_KERNEL::Exception("MEDFileField1TSStructItem2::BuildAggregationOf : invalid situation ! Several same geo type chunk must all lie on profiles !"); - arrs[i]=globs->getProfile(obj->_pfl->getName().c_str()); - } - MEDCouplingAutoRefCountObjectPtr arr(DataArrayInt::Aggregate(arrs)); - arr->sort(); - int oldNbTuples(arr->getNumberOfTuples()); - arr=arr->buildUnique(); - if(oldNbTuples!=arr->getNumberOfTuples()) - throw INTERP_KERNEL::Exception("MEDFileField1TSStructItem2::BuildAggregationOf : some entities are present several times !"); - if(arr->isIdentity() && oldNbTuples==nbEntityRef) - { - std::pair p(0,nbEntityRef); - std::string a,b; - MEDFileField1TSStructItem2 ret(gt,p,a,b); - ret._nb_of_entity=nbEntityRef; - return ret; - } - else - { - arr->setName(NEWLY_CREATED_PFL_NAME); - std::pair p(0,oldNbTuples); - std::string a,b; - MEDFileField1TSStructItem2 ret(gt,p,a,b); - ret._nb_of_entity=nbEntityRef; - ret._pfl=arr; - return ret; - } -} - -std::size_t MEDFileField1TSStructItem2::getHeapMemorySizeWithoutChildren() const -{ - std::size_t ret(_loc.capacity()); - return ret; -} - -std::vector MEDFileField1TSStructItem2::getDirectChildrenWithNull() const -{ - std::vector ret; - ret.push_back((const DataArrayInt *)_pfl); - return ret; -} - -//= - -MEDFileField1TSStructItem::MEDFileField1TSStructItem(TypeOfField a, const std::vector< MEDFileField1TSStructItem2 >& b):_computed(false),_type(a),_items(b) -{ -} - -void MEDFileField1TSStructItem::checkWithMeshStruct(const MEDFileMeshStruct *mst, const MEDFileFieldGlobsReal *globs) -{ - switch(_type) - { - case ON_NODES: - { - int nbOfEnt=mst->getNumberOfNodes(); - if(_items.size()!=1) - throw INTERP_KERNEL::Exception("MEDFileField1TSStructItem::checkWithMeshStruct : for nodes field only one subdivision supported !"); - _items[0].checkInRange(nbOfEnt,1,globs); - break ; - } - case ON_CELLS: - { - for(std::vector< MEDFileField1TSStructItem2 >::iterator it=_items.begin();it!=_items.end();it++) - (*it).checkWithMeshStructForCells(mst,globs); - break; - } - case ON_GAUSS_NE: - { - for(std::vector< MEDFileField1TSStructItem2 >::iterator it=_items.begin();it!=_items.end();it++) - (*it).checkWithMeshStructForGaussNE(mst,globs); - break; - } - case ON_GAUSS_PT: - { - for(std::vector< MEDFileField1TSStructItem2 >::iterator it=_items.begin();it!=_items.end();it++) - (*it).checkWithMeshStructForGaussPT(mst,globs); - break; - } - default: - throw INTERP_KERNEL::Exception("MEDFileField1TSStructItem::checkWithMeshStruct : not managed field type !"); - } -} - -bool MEDFileField1TSStructItem::operator==(const MEDFileField1TSStructItem& other) const -{ - if(_type!=other._type) - return false; - if(_items.size()!=other._items.size()) - return false; - for(std::size_t i=0;i<_items.size();i++) - if(!(_items[i]==other._items[i])) - return false; - return true; -} - -bool MEDFileField1TSStructItem::isCellSupportEqual(const MEDFileField1TSStructItem& other, const MEDFileFieldGlobsReal *globs) const -{ - if(_type!=other._type) - return false; - if(_items.size()!=other._items.size()) - return false; - for(std::size_t i=0;i<_items.size();i++) - if(!(_items[i].isCellSupportEqual(other._items[i],globs))) - return false; - return true; -} - -bool MEDFileField1TSStructItem::isNodeSupportEqual(const MEDFileField1TSStructItem& other, const MEDFileFieldGlobsReal *globs) const -{ - if(_type!=other._type) - return false; - if(_items.size()!=other._items.size()) - return false; - for(std::size_t i=0;i<_items.size();i++) - if(!(_items[i].isNodeSupportEqual(other._items[i],globs))) - return false; - return true; -} - -bool MEDFileField1TSStructItem::isEntityCell() const -{ - if(_type==ON_NODES) - return false; - else - return true; -} - -class CmpGeo -{ -public: - CmpGeo(INTERP_KERNEL::NormalizedCellType geoTyp):_geo_type(geoTyp) { } - bool operator()(const std::pair< INTERP_KERNEL::NormalizedCellType, std::vector > & v) const { return _geo_type==v.first; } -private: - INTERP_KERNEL::NormalizedCellType _geo_type; -}; - -MEDFileField1TSStructItem MEDFileField1TSStructItem::simplifyMeOnCellEntity(const MEDFileFieldGlobsReal *globs) const -{ - if(!isEntityCell()) - throw INTERP_KERNEL::Exception("MEDFileField1TSStructItem::simplifyMeOnCellEntity : must be on ON_CELLS, ON_GAUSS_NE or ON_GAUSS_PT !"); - std::vector< std::pair< INTERP_KERNEL::NormalizedCellType, std::vector > > m; - std::size_t i=0; - for(std::vector< MEDFileField1TSStructItem2 >::const_iterator it=_items.begin();it!=_items.end();it++,i++) - { - std::vector< std::pair< INTERP_KERNEL::NormalizedCellType, std::vector > >::iterator it0(std::find_if(m.begin(),m.end(),CmpGeo((*it).getGeo()))); - if(it0==m.end()) - m.push_back(std::pair< INTERP_KERNEL::NormalizedCellType, std::vector >((*it).getGeo(),std::vector(1,i))); - else - (*it0).second.push_back(i); - } - if(m.size()==_items.size()) - { - MEDFileField1TSStructItem ret(*this); - ret._type=ON_CELLS; - return ret; - } - std::size_t sz(m.size()); - std::vector< MEDFileField1TSStructItem2 > items(sz); - for(i=0;i& ids=m[i].second; - std::vectorobjs(ids.size()); - for(std::size_t j=0;jgetNumberOfNodes()); - if(otherNodeIt.getPflName().empty()) - {//on all nodes - if(!ret0) - return false; - std::vector nodesFetched(nbOfNodes,false); - meshSt->getTheMesh()->whichAreNodesFetched(*this,globs,nodesFetched); - if(std::find(nodesFetched.begin(),nodesFetched.end(),false)==nodesFetched.end()) - return theFirstLevFull==0; - else - return false; - } - else - { - const DataArrayInt *pfl=globs->getProfile(otherNodeIt.getPflName().c_str()); - MEDCouplingAutoRefCountObjectPtr cpyPfl(pfl->deepCpy()); - cpyPfl->sort(); - if(cpyPfl->isIdentity() && cpyPfl->getNumberOfTuples()==nbOfNodes) - {//on all nodes also ! - if(!ret0) - return false; - return theFirstLevFull==0; - } - std::vector nodesFetched(nbOfNodes,false); - meshSt->getTheMesh()->whichAreNodesFetched(*this,globs,nodesFetched); - return cpyPfl->isFittingWith(nodesFetched); - } -} - -bool MEDFileField1TSStructItem::isFullyOnOneLev(const MEDFileMeshStruct *meshSt, int& theFirstLevFull) const -{ - if(_type!=ON_CELLS) - throw INTERP_KERNEL::Exception("MEDFileField1TSStructItem::isFullyOnOneLev : works only for ON_CELLS discretization !"); - if(_items.empty()) - throw INTERP_KERNEL::Exception("MEDFileField1TSStructItem::isFullyOnOneLev : items vector is empty !"); - int nbOfLevs(meshSt->getNumberOfLevs()); - if(nbOfLevs==0) - throw INTERP_KERNEL::Exception("MEDFileField1TSStructItem::isFullyOnOneLev : no levels in input mesh structure !"); - std::vector levs(nbOfLevs); - theFirstLevFull=1; - std::set gts; - for(std::vector< MEDFileField1TSStructItem2 >::const_iterator it=_items.begin();it!=_items.end();it++) - { - if(!(*it).getPflName().empty()) - return false; - INTERP_KERNEL::NormalizedCellType gt((*it).getGeo()); - if(gts.find(gt)!=gts.end()) - throw INTERP_KERNEL::Exception("MEDFileField1TSStructItem::isFullyOnOneLev : internal error !"); - gts.insert(gt); - int pos(meshSt->getLevelOfGeoType((*it).getGeo())); - levs[-pos]++; - } - for(int i=0;igetNumberOfGeoTypesInLev(-i)==levs[i]) - { theFirstLevFull=-i; return true; } - return false; -} - -const MEDFileField1TSStructItem2& MEDFileField1TSStructItem::operator[](std::size_t i) const -{ - if(i>=_items.size()) - throw INTERP_KERNEL::Exception("MEDFileField1TSStructItem::operator[] : input is not in valid range !"); - return _items[i]; -} - -std::size_t MEDFileField1TSStructItem::getHeapMemorySizeWithoutChildren() const -{ - std::size_t ret(_items.size()*sizeof(MEDFileField1TSStructItem2)); - return ret; -} - -std::vector MEDFileField1TSStructItem::getDirectChildrenWithNull() const -{ - std::vector ret; - for(std::vector< MEDFileField1TSStructItem2 >::const_iterator it=_items.begin();it!=_items.end();it++) - ret.push_back(&(*it)); - return ret; -} - -MEDMeshMultiLev *MEDFileField1TSStructItem::buildFromScratchDataSetSupportOnCells(const MEDFileMeshStruct *mst, const MEDFileFieldGlobsReal *globs) const -{ - std::size_t sz(_items.size()); - std::vector a0(sz); - std::vector a1(sz); - std::vector a2(sz); - std::size_t i(0); - for(std::vector< MEDFileField1TSStructItem2 >::const_iterator it=_items.begin();it!=_items.end();it++,i++) - { - a0[i]=(*it).getGeo(); - a1[i]=(*it).getPfl(globs); - a2[i]=mst->getNumberOfElemsOfGeoType((*it).getGeo()); - } - return MEDMeshMultiLev::New(mst->getTheMesh(),a0,a1,a2); -} - -std::vector MEDFileField1TSStructItem::getGeoTypes(const MEDFileMesh *m) const -{ - std::vector ret; - if(_type==ON_NODES) - { - if(!_items.empty() && _items[0].getPflName().empty()) - { - if(m) - return m->getAllGeoTypes(); - else - return ret; - } - else - return ret; - } - for(std::vector< MEDFileField1TSStructItem2 >::const_iterator it=_items.begin();it!=_items.end();it++) - { - INTERP_KERNEL::NormalizedCellType elt((*it).getGeo()); - std::vector::iterator it2(std::find(ret.begin(),ret.end(),elt)); - if(it2==ret.end()) - ret.push_back(elt); - } - return ret; -} - -MEDFileField1TSStructItem MEDFileField1TSStructItem::BuildItemFrom(const MEDFileAnyTypeField1TS *ref, const MEDFileMeshStruct *meshSt) -{ - std::vector< MEDFileField1TSStructItem2 > anItems; - // - std::vector< std::vector > pfls,locs; - std::vector< std::vector > typesF; - std::vector geoTypes; - std::vector< std::vector > > strtEnds=ref->getFieldSplitedByType(std::string(),geoTypes,typesF,pfls,locs); - std::size_t nbOfGeoTypes(geoTypes.size()); - if(nbOfGeoTypes==0) - throw INTERP_KERNEL::Exception("MEDFileField1TSStruct : not null by empty ref !"); - if(typesF[0].empty()) - throw INTERP_KERNEL::Exception("MEDFileField1TSStruct : internal error #1 bis !"); - TypeOfField atype(typesF[0][0]); - for(std::size_t i=0;i::const_iterator it=_already_checked.begin();it!=_already_checked.end();it++) - { - if((*it)==b) - return true; - } - return false; -} - -/*! - * Not const because \a other structure will be added to the \c _already_checked attribute in case of success. - */ -bool MEDFileField1TSStruct::isSupportSameAs(const MEDFileAnyTypeField1TS *other, const MEDFileMeshStruct *meshSt) -{ - if(_already_checked.empty()) - throw INTERP_KERNEL::Exception("MEDFileField1TSStruct::isSupportSameAs : no ref !"); - MEDFileField1TSStructItem b(MEDFileField1TSStructItem::BuildItemFrom(other,meshSt)); - if(!_already_checked[0].isEntityCell() || !b.isEntityCell()) - throw INTERP_KERNEL::Exception("MEDFileField1TSStruct::isSupportSameAs : only available on cell entities !"); - MEDFileField1TSStructItem other1(b.simplifyMeOnCellEntity(other)); - int found=-1,i=0; - for(std::vector::const_iterator it=_already_checked.begin();it!=_already_checked.end();it++,i++) - if((*it).isComputed()) - { found=i; break; } - bool ret(false); - if(found==-1) - { - MEDFileField1TSStructItem this1(_already_checked[0].simplifyMeOnCellEntity(other)); - ret=this1.isCellSupportEqual(other1,other); - if(ret) - _already_checked.push_back(this1); - } - else - ret=_already_checked[found].isCellSupportEqual(other1,other); - if(ret) - _already_checked.push_back(b); - return ret; -} - -/*! - * \param [in] other - a field with only one spatial discretization : ON_NODES. - */ -bool MEDFileField1TSStruct::isCompatibleWithNodesDiscr(const MEDFileAnyTypeField1TS *other, const MEDFileMeshStruct *meshSt) -{ - if(_already_checked.empty()) - throw INTERP_KERNEL::Exception("MEDFileField1TSStruct::isCompatibleWithNodesDiscr : no ref !"); - MEDFileField1TSStructItem other1(MEDFileField1TSStructItem::BuildItemFrom(other,meshSt)); - if(_already_checked[0].isEntityCell()) - { - int found=-1,i=0; - for(std::vector::const_iterator it=_already_checked.begin();it!=_already_checked.end();it++,i++) - if((*it).isComputed()) - { found=i; break; } - bool ret(false); - if(found==-1) - { - MEDFileField1TSStructItem this1(_already_checked[0].simplifyMeOnCellEntity(other)); - ret=this1.isCompatibleWithNodesDiscr(other1,meshSt,other); - if(ret) - _already_checked.push_back(this1); - } - else - ret=_already_checked[found].isCompatibleWithNodesDiscr(other1,meshSt,other); - if(ret) - _already_checked.push_back(other1); - return ret; - } - else - return _already_checked[0].isNodeSupportEqual(other1,other); -} - -std::size_t MEDFileField1TSStruct::getHeapMemorySizeWithoutChildren() const -{ - std::size_t ret(_already_checked.capacity()*sizeof(MEDFileField1TSStructItem)); - return ret; -} - -std::vector MEDFileField1TSStruct::getDirectChildrenWithNull() const -{ - std::vector ret; - for(std::vector::const_iterator it=_already_checked.begin();it!=_already_checked.end();it++) - ret.push_back(&(*it)); - return ret; -} - -MEDMeshMultiLev *MEDFileField1TSStruct::buildFromScratchDataSetSupport(const MEDFileMeshStruct *mst, const MEDFileFieldGlobsReal *globs) const -{ - if(_already_checked.empty()) - throw INTERP_KERNEL::Exception("MEDFileField1TSStruct::buildFromScratchDataSetSupport : No outline structure in this !"); - int pos0(-1),pos1(-1); - if(presenceOfCellDiscr(pos0)) - { - MEDCouplingAutoRefCountObjectPtr ret(_already_checked[pos0].buildFromScratchDataSetSupportOnCells(mst,globs)); - if(presenceOfPartialNodeDiscr(pos1)) - ret->setNodeReduction(_already_checked[pos1][0].getPfl(globs)); - return ret.retn(); - } - else - { - if(!presenceOfPartialNodeDiscr(pos1)) - {//we have only all nodes, no cell definition info -> all existing levels !; - return MEDMeshMultiLev::New(mst->getTheMesh(),mst->getTheMesh()->getNonEmptyLevels()); - } - else - return MEDMeshMultiLev::NewOnlyOnNode(mst->getTheMesh(),_already_checked[pos1][0].getPfl(globs)); - } -} - -bool MEDFileField1TSStruct::isDataSetSupportFastlyEqualTo(const MEDFileField1TSStruct& other, const MEDFileFieldGlobsReal *globs) const -{ - int b0,b1; - bool a0(presenceOfCellDiscr(b0)),a1(presenceOfPartialNodeDiscr(b1)); - int d0,d1; - bool c0(other.presenceOfCellDiscr(d0)),c1(other.presenceOfPartialNodeDiscr(d1)); - if(a0!=c0 || a1!=c1) - return false; - if(a0) - if(!_already_checked[b0].isCellSupportEqual(other._already_checked[d0],globs)) - return false; - if(a1) - if(!_already_checked[b1].isNodeSupportEqual(other._already_checked[d1],globs)) - return false; - return true; -} - -std::vector MEDFileField1TSStruct::getGeoTypes(const MEDFileMesh *m) const -{ - std::vector ret; - for(std::vector::const_iterator it=_already_checked.begin();it!=_already_checked.end();it++) - { - std::vector ret2((*it).getGeoTypes(m)); - for(std::vector::const_iterator it2=ret2.begin();it2!=ret2.end();it2++) - { - if(*it2==INTERP_KERNEL::NORM_ERROR) - continue; - std::vector::iterator it3(std::find(ret.begin(),ret.end(),*it2)); - if(it3==ret.end()) - ret.push_back(*it2); - } - } - return ret; -} - -/*! - * Returns true if presence in \a this of discretization ON_CELLS, ON_GAUSS_PT, ON_GAUSS_NE. - * If true is returned the pos of the easiest is returned. The easiest is the first element in \a this having the less splitted subparts. - */ -bool MEDFileField1TSStruct::presenceOfCellDiscr(int& pos) const -{ - std::size_t refSz(std::numeric_limits::max()); - bool ret(false); - int i(0); - for(std::vector::const_iterator it=_already_checked.begin();it!=_already_checked.end();it++,i++) - { - if((*it).getType()!=ON_NODES) - { - ret=true; - std::size_t sz((*it).getNumberOfItems()); - if(refSz>sz) - { pos=i; refSz=sz; } - } - } - if(refSz==0) - throw INTERP_KERNEL::Exception("MEDFileField1TSStruct::presenceOfCellDiscr : an element in this on entity CELL is empty !"); - return ret; -} - -/*! - * Returns true if presence in \a this of discretization ON_NODES. - * If true is returned the pos of the first element containing the single subpart. - */ -bool MEDFileField1TSStruct::presenceOfPartialNodeDiscr(int& pos) const -{ - int i(0); - for(std::vector::const_iterator it=_already_checked.begin();it!=_already_checked.end();it++,i++) - { - if((*it).getType()==ON_NODES) - { - std::size_t sz((*it).getNumberOfItems()); - if(sz==1) - { - if(!(*it)[0].getPflName().empty()) - { pos=i; return true; } - } - else - throw INTERP_KERNEL::Exception("MEDFileField1TSStruct::presenceOfPartialNodeDiscr : an element in this on entity NODE is split into several parts !"); - } - } - return false; -} - -//= - -MEDFileFastCellSupportComparator *MEDFileFastCellSupportComparator::New(const MEDFileMeshStruct *m, const MEDFileAnyTypeFieldMultiTS *ref) -{ - return new MEDFileFastCellSupportComparator(m,ref); -} - -MEDFileFastCellSupportComparator::MEDFileFastCellSupportComparator(const MEDFileMeshStruct *m, const MEDFileAnyTypeFieldMultiTS *ref) -{ - if(!m) - throw INTERP_KERNEL::Exception("MEDFileFastCellSupportComparator constructor : null input mesh struct !"); - _mesh_comp=const_cast(m); _mesh_comp->incrRef(); - int nbPts=ref->getNumberOfTS(); - _f1ts_cmps.resize(nbPts); - for(int i=0;i elt=ref->getTimeStepAtPos(i); - try - { - _f1ts_cmps[i]=MEDFileField1TSStruct::New(elt,_mesh_comp); - _f1ts_cmps[i]->checkWithMeshStruct(_mesh_comp,elt); - } - catch(INTERP_KERNEL::Exception& e) - { - std::ostringstream oss; oss << "Problem in field with name \"" << ref->getName() << "\"" << std::endl; - oss << "More Details : " << e.what(); - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - } -} - -std::size_t MEDFileFastCellSupportComparator::getHeapMemorySizeWithoutChildren() const -{ - std::size_t ret(_f1ts_cmps.capacity()*sizeof(MEDCouplingAutoRefCountObjectPtr)); - return ret; -} - -std::vector MEDFileFastCellSupportComparator::getDirectChildrenWithNull() const -{ - std::vector ret; - const MEDFileMeshStruct *mst(_mesh_comp); - if(mst) - ret.push_back(mst); - for(std::vector< MEDCouplingAutoRefCountObjectPtr >::const_iterator it=_f1ts_cmps.begin();it!=_f1ts_cmps.end();it++) - ret.push_back((const MEDFileField1TSStruct *)*it); - return ret; -} - -bool MEDFileFastCellSupportComparator::isEqual(const MEDFileAnyTypeFieldMultiTS *other) -{ - int nbPts=other->getNumberOfTS(); - if(nbPts!=(int)_f1ts_cmps.size()) - { - std::ostringstream oss; oss << "MEDFileFastCellSupportComparator::isEqual : unexpected nb of time steps in input ! Should be " << _f1ts_cmps.size() << " it is in reality " << nbPts << " !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - for(int i=0;i elt=other->getTimeStepAtPos(i); - if(!_f1ts_cmps[i]->isEqualConsideringThePast(elt,_mesh_comp)) - if(!_f1ts_cmps[i]->isSupportSameAs(elt,_mesh_comp)) - return false; - } - return true; -} - -bool MEDFileFastCellSupportComparator::isCompatibleWithNodesDiscr(const MEDFileAnyTypeFieldMultiTS *other) -{ - int nbPts=other->getNumberOfTS(); - if(nbPts!=(int)_f1ts_cmps.size()) - { - std::ostringstream oss; oss << "MEDFileFastCellSupportComparator::isCompatibleWithNodesDiscr : unexpected nb of time steps in input ! Should be " << _f1ts_cmps.size() << " it is in reality " << nbPts << " !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - for(int i=0;i elt=other->getTimeStepAtPos(i); - if(!_f1ts_cmps[i]->isCompatibleWithNodesDiscr(elt,_mesh_comp)) - return false; - } - return true; -} - -MEDMeshMultiLev *MEDFileFastCellSupportComparator::buildFromScratchDataSetSupport(int timeStepId, const MEDFileFieldGlobsReal *globs) const -{ - if(timeStepId<0 || timeStepId>=(int)_f1ts_cmps.size()) - { - std::ostringstream oss; oss << "MEDFileFastCellSupportComparator::buildFromScratchDataSetSupport : requested time step id #" << timeStepId << " is not in [0," << _f1ts_cmps.size() << ") !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - const MEDFileField1TSStruct *obj(_f1ts_cmps[timeStepId]); - if(!obj) - { - std::ostringstream oss; oss << "MEDFileFastCellSupportComparator::buildFromScratchDataSetSupport : at time step id #" << timeStepId << " no field structure overview defined !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - return obj->buildFromScratchDataSetSupport(_mesh_comp,globs); -} - -bool MEDFileFastCellSupportComparator::isDataSetSupportEqualToThePreviousOne(int timeStepId, const MEDFileFieldGlobsReal *globs) const -{ - if(timeStepId<=0 || timeStepId>=(int)_f1ts_cmps.size()) - { - std::ostringstream oss; oss << "MEDFileFastCellSupportComparator::isDataSetSupportEqualToThePreviousOne : requested time step id #" << timeStepId << " is not in [1," << _f1ts_cmps.size() << ") !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - const MEDFileField1TSStruct *obj(_f1ts_cmps[timeStepId]); - const MEDFileField1TSStruct *objRef(_f1ts_cmps[timeStepId-1]); - return objRef->isDataSetSupportFastlyEqualTo(*obj,globs); -} - -int MEDFileFastCellSupportComparator::getNumberOfTS() const -{ - return _f1ts_cmps.size(); -} - -std::vector MEDFileFastCellSupportComparator::getGeoTypesAt(int timeStepId, const MEDFileMesh *m) const -{ - if(timeStepId<0 || timeStepId>=(int)_f1ts_cmps.size()) - { - std::ostringstream oss; oss << "MEDFileFastCellSupportComparator::getGeoTypesAt : requested time step id #" << timeStepId << " is not in [0," << _f1ts_cmps.size() << ") !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - const MEDFileField1TSStruct *elt(_f1ts_cmps[timeStepId]); - if(!elt) - { - std::ostringstream oss; oss << "MEDFileFastCellSupportComparator::getGeoTypesAt : requested time step id #" << timeStepId << " points to a NULL pointer !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - return elt->getGeoTypes(m); -} diff --git a/src/MEDLoader/MEDFileFieldOverView.hxx b/src/MEDLoader/MEDFileFieldOverView.hxx deleted file mode 100644 index 25384f4bd..000000000 --- a/src/MEDLoader/MEDFileFieldOverView.hxx +++ /dev/null @@ -1,311 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 -// 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 __MEDFILEFIELDOVERVIEW_HXX__ -#define __MEDFILEFIELDOVERVIEW_HXX__ - -#include "MEDLoaderDefines.hxx" - -#include "MEDCouplingAutoRefCountObjectPtr.hxx" -#include "MEDCouplingRefCountObject.hxx" -#include "MEDCoupling1GTUMesh.hxx" - -#include "NormalizedUnstructuredMesh.hxx" -#include "InterpKernelException.hxx" - -#include - -namespace ParaMEDMEM -{ - class DataArrayInt; - class MEDCouplingMesh; - class MEDFileMesh; - class MEDFileUMesh; - class MEDFileCMesh; - class MEDFileStructuredMesh; - class MEDFileCurveLinearMesh; - class MEDFileFieldGlobs; - class MEDFileFieldGlobsReal; - class MEDFileAnyTypeField1TS; - class MEDFileAnyTypeFieldMultiTS; - - class MEDFileMeshStruct : public RefCountObject - { - public: - MEDLOADER_EXPORT static MEDFileMeshStruct *New(const MEDFileMesh *mesh); - std::size_t getHeapMemorySizeWithoutChildren() const; - std::vector getDirectChildrenWithNull() const; - const MEDFileMesh *getTheMesh() const { return _mesh; } - int getNumberOfNodes() const { return _nb_nodes; } - bool doesManageGeoType(INTERP_KERNEL::NormalizedCellType t) const; - int getNumberOfElemsOfGeoType(INTERP_KERNEL::NormalizedCellType t) const; - int getLevelOfGeoType(INTERP_KERNEL::NormalizedCellType t) const; - int getNumberOfLevs() const; - int getNumberOfGeoTypesInLev(int relativeLev) const; - // non const methods - void appendIfImplicitType(INTERP_KERNEL::NormalizedCellType t); - private: - MEDFileMeshStruct(const MEDFileMesh *mesh); - private: - const MEDFileMesh *_mesh; - std::string _name; - int _nb_nodes; - std::vector< std::vector > _geo_types_distrib; - }; - - class MEDFileField1TSStructItem; - - class MEDMeshMultiLev : public RefCountObject - { - public: - std::size_t getHeapMemorySizeWithoutChildren() const; - std::vector getDirectChildrenWithNull() const; - public: - static MEDMeshMultiLev *New(const MEDFileMesh *m, const std::vector& gts, const std::vector& pfls, const std::vector& nbEntities); - static MEDMeshMultiLev *New(const MEDFileMesh *m, const std::vector& levs); - static MEDMeshMultiLev *NewOnlyOnNode(const MEDFileMesh *m, const DataArrayInt *pflOnNode); - void setNodeReduction(const DataArrayInt *nr); - void setCellReduction(const DataArrayInt *cr); - bool isFastlyTheSameStruct(const MEDFileField1TSStructItem& fst, const MEDFileFieldGlobsReal *globs) const; - MEDLOADER_EXPORT DataArray *buildDataArray(const MEDFileField1TSStructItem& fst, const MEDFileFieldGlobsReal *globs, const DataArray *vals) const; - MEDLOADER_EXPORT void retrieveFamilyIdsOnCells(DataArrayInt *& famIds, bool& isWithoutCopy) const; - MEDLOADER_EXPORT void retrieveNumberIdsOnCells(DataArrayInt *& numIds, bool& isWithoutCopy) const; - MEDLOADER_EXPORT void retrieveFamilyIdsOnNodes(DataArrayInt *& famIds, bool& isWithoutCopy) const; - MEDLOADER_EXPORT void retrieveNumberIdsOnNodes(DataArrayInt *& numIds, bool& isWithoutCopy) const; - MEDLOADER_EXPORT std::vector< INTERP_KERNEL::NormalizedCellType > getGeoTypes() const; - void setFamilyIdsOnCells(DataArrayInt *famIds); - void setNumberIdsOnCells(DataArrayInt *numIds); - void setFamilyIdsOnNodes(DataArrayInt *famIds); - void setNumberIdsOnNodes(DataArrayInt *numIds); - virtual void selectPartOfNodes(const DataArrayInt *pflNodes) = 0; - virtual MEDMeshMultiLev *prepare() const = 0; - int getNumberOfCells(INTERP_KERNEL::NormalizedCellType t) const; - int getNumberOfNodes() const; - protected: - std::string getPflNameOfId(int id) const; - DataArray *constructDataArray(const MEDFileField1TSStructItem& fst, const MEDFileFieldGlobsReal *globs, const DataArray *vals) const; - virtual void appendVertices(const DataArrayInt *verticesToAdd, DataArrayInt *nr); - protected: - MEDMeshMultiLev(const MEDFileMesh *mesh); - MEDMeshMultiLev(const MEDMeshMultiLev& other); - MEDMeshMultiLev(const MEDFileMesh *mesh, int nbNodes, const std::vector& gts, const std::vector& pfls, const std::vector& nbEntities); - protected: - const MEDFileMesh *_mesh; - std::vector< MEDCouplingAutoRefCountObjectPtr > _pfls; - std::vector< INTERP_KERNEL::NormalizedCellType > _geo_types; - std::vector _nb_entities; - MEDCouplingAutoRefCountObjectPtr _node_reduction; - int _nb_nodes; - // - MEDCouplingAutoRefCountObjectPtr _cell_fam_ids; - MEDCouplingAutoRefCountObjectPtr _cell_num_ids; - MEDCouplingAutoRefCountObjectPtr _node_fam_ids; - MEDCouplingAutoRefCountObjectPtr _node_num_ids; - public: - MEDLOADER_EXPORT static const int PARAMEDMEM_2_VTKTYPE_LGTH=34; - MEDLOADER_EXPORT static const unsigned char PARAMEDMEM_2_VTKTYPE[PARAMEDMEM_2_VTKTYPE_LGTH]; - MEDLOADER_EXPORT static const unsigned char HEXA27_PERM_ARRAY[27]; - }; - - class MEDStructuredMeshMultiLev; - - class MEDUMeshMultiLev : public MEDMeshMultiLev - { - public: - static MEDUMeshMultiLev *New(const MEDFileUMesh *m, const std::vector& levs); - static MEDUMeshMultiLev *New(const MEDFileUMesh *m, const std::vector& gts, const std::vector& pfls, const std::vector& nbEntities); - void selectPartOfNodes(const DataArrayInt *pflNodes); - MEDMeshMultiLev *prepare() const; - MEDUMeshMultiLev(const MEDStructuredMeshMultiLev& other, const MEDCouplingAutoRefCountObjectPtr& part); - MEDLOADER_EXPORT bool buildVTUArrays(DataArrayDouble *& coords, DataArrayByte *&types, DataArrayInt *&cellLocations, DataArrayInt *& cells, DataArrayInt *&faceLocations, DataArrayInt *&faces) const; - protected: - void appendVertices(const DataArrayInt *verticesToAdd, DataArrayInt *nr); - private: - void reorderNodesIfNecessary(MEDCouplingAutoRefCountObjectPtr& coords, DataArrayInt *nodalConnVTK, DataArrayInt *polyhedNodalConnVTK) const; - private: - MEDUMeshMultiLev(const MEDUMeshMultiLev& other); - MEDUMeshMultiLev(const MEDFileUMesh *m, const std::vector& levs); - MEDUMeshMultiLev(const MEDFileUMesh *m, const std::vector& gts, const std::vector& pfls, const std::vector& nbEntities); - private: - std::vector< MEDCouplingAutoRefCountObjectPtr > _parts; - //! this attribute is used only for mesh with no cells but having coordinates. For classical umeshes those pointer is equal to pointer of coordinates of instances in this->_parts. - MEDCouplingAutoRefCountObjectPtr _coords; - }; - - class MEDStructuredMeshMultiLev : public MEDMeshMultiLev - { - public: - void selectPartOfNodes(const DataArrayInt *pflNodes); - virtual std::vector getNodeGridStructure() const = 0; - protected: - MEDStructuredMeshMultiLev(const MEDStructuredMeshMultiLev& other); - MEDStructuredMeshMultiLev(const MEDFileStructuredMesh *m, const std::vector& lev); - MEDStructuredMeshMultiLev(const MEDFileStructuredMesh *m, int nbOfNodes, const std::vector& gts, const std::vector& pfls, const std::vector& nbEntities); - void dealWithImplicitUnstructuredMesh(const MEDFileMesh *m); - protected: - void moveFaceToCell() const; - bool prepareForImplicitUnstructuredMeshCase(MEDMeshMultiLev *&ret) const; - private: - void initStdFieldOfIntegers(const MEDFileStructuredMesh *m); - protected: - bool _is_internal; - MEDCouplingAutoRefCountObjectPtr _face_fam_ids; - MEDCouplingAutoRefCountObjectPtr _face_num_ids; - }; - - class MEDCMeshMultiLev : public MEDStructuredMeshMultiLev - { - public: - static MEDCMeshMultiLev *New(const MEDFileCMesh *m, const std::vector& levs); - static MEDCMeshMultiLev *New(const MEDFileCMesh *m, const std::vector& gts, const std::vector& pfls, const std::vector& nbEntities); - std::vector getNodeGridStructure() const; - MEDMeshMultiLev *prepare() const; - MEDLOADER_EXPORT std::vector< DataArrayDouble * > buildVTUArrays(bool& isInternal) const; - private: - MEDCMeshMultiLev(const MEDCMeshMultiLev& other); - MEDCMeshMultiLev(const MEDFileCMesh *m, const std::vector& levs); - MEDCMeshMultiLev(const MEDFileCMesh *m, const std::vector& gts, const std::vector& pfls, const std::vector& nbEntities); - private: - std::vector< MEDCouplingAutoRefCountObjectPtr > _coords; - }; - - class MEDCurveLinearMeshMultiLev : public MEDStructuredMeshMultiLev - { - public: - static MEDCurveLinearMeshMultiLev *New(const MEDFileCurveLinearMesh *m, const std::vector& levs); - static MEDCurveLinearMeshMultiLev *New(const MEDFileCurveLinearMesh *m, const std::vector& gts, const std::vector& pfls , const std::vector& nbEntities); - std::vector getNodeGridStructure() const; - MEDMeshMultiLev *prepare() const; - MEDLOADER_EXPORT void buildVTUArrays(DataArrayDouble *&coords, std::vector& nodeStrct, bool& isInternal) const; - private: - MEDCurveLinearMeshMultiLev(const MEDCurveLinearMeshMultiLev& other); - MEDCurveLinearMeshMultiLev(const MEDFileCurveLinearMesh *m, const std::vector& levs); - MEDCurveLinearMeshMultiLev(const MEDFileCurveLinearMesh *m, const std::vector& gts, const std::vector& pfls, const std::vector& nbEntities); - private: - MEDCouplingAutoRefCountObjectPtr _coords; - std::vector _structure; - }; - - class MEDFileField1TSStructItem2 : public BigMemoryObject - { - public: - MEDFileField1TSStructItem2(); - MEDFileField1TSStructItem2(INTERP_KERNEL::NormalizedCellType a, const std::pair& b, const std::string& pfl, const std::string& loc); - void checkWithMeshStructForCells(const MEDFileMeshStruct *mst, const MEDFileFieldGlobsReal *globs); - void checkWithMeshStructForGaussNE(const MEDFileMeshStruct *mst, const MEDFileFieldGlobsReal *globs); - void checkWithMeshStructForGaussPT(const MEDFileMeshStruct *mst, const MEDFileFieldGlobsReal *globs); - // - MEDLOADER_EXPORT std::size_t getHeapMemorySizeWithoutChildren() const; - MEDLOADER_EXPORT std::vector getDirectChildrenWithNull() const; - // - const DataArrayInt *getPfl(const MEDFileFieldGlobsReal *globs) const; - INTERP_KERNEL::NormalizedCellType getGeo() const { return _geo_type; } - int getNbEntity() const { return _nb_of_entity; } - const std::pair& getStartStop() const { return _start_end; } - std::string getPflName() const; - int getNbOfIntegrationPts(const MEDFileFieldGlobsReal *globs) const; - //! warning this method also set _nb_of_entity attribute ! - void checkInRange(int nbOfEntity, int nip, const MEDFileFieldGlobsReal *globs); - bool isFastlyEqual(int& startExp, INTERP_KERNEL::NormalizedCellType gt, const std::string& pflName) const; - bool operator==(const MEDFileField1TSStructItem2& other) const; - bool isCellSupportEqual(const MEDFileField1TSStructItem2& other, const MEDFileFieldGlobsReal *globs) const; - bool isNodeSupportEqual(const MEDFileField1TSStructItem2& other, const MEDFileFieldGlobsReal *globs) const; - static MEDFileField1TSStructItem2 BuildAggregationOf(const std::vector& objs, const MEDFileFieldGlobsReal *globs); - public: - static const char NEWLY_CREATED_PFL_NAME[]; - private: - INTERP_KERNEL::NormalizedCellType _geo_type; - std::pair _start_end; - MEDCouplingAutoRefCountObjectPtr _pfl; - std::string _loc; - int _nb_of_entity; - }; - - class MEDFileField1TSStructItem : public BigMemoryObject - { - public: - MEDFileField1TSStructItem():_computed(false),_type(ON_CELLS) { } - MEDFileField1TSStructItem(TypeOfField a, const std::vector< MEDFileField1TSStructItem2 >& b); - void checkWithMeshStruct(const MEDFileMeshStruct *mst, const MEDFileFieldGlobsReal *globs); - bool operator==(const MEDFileField1TSStructItem& other) const; - MEDLOADER_EXPORT std::size_t getHeapMemorySizeWithoutChildren() const; - MEDLOADER_EXPORT std::vector getDirectChildrenWithNull() const; - bool isEntityCell() const; - bool isComputed() const { return _computed; } - TypeOfField getType() const { return _type; } - std::size_t getNumberOfItems() const { return _items.size(); } - const MEDFileField1TSStructItem2& operator[](std::size_t i) const; - // - bool isCellSupportEqual(const MEDFileField1TSStructItem& other, const MEDFileFieldGlobsReal *globs) const; - bool isNodeSupportEqual(const MEDFileField1TSStructItem& other, const MEDFileFieldGlobsReal *globs) const; - MEDFileField1TSStructItem simplifyMeOnCellEntity(const MEDFileFieldGlobsReal *globs) const; - bool isCompatibleWithNodesDiscr(const MEDFileField1TSStructItem& other, const MEDFileMeshStruct *meshSt, const MEDFileFieldGlobsReal *globs) const; - bool isFullyOnOneLev(const MEDFileMeshStruct *meshSt, int& theFirstLevFull) const; - std::vector getGeoTypes(const MEDFileMesh *m) const; - MEDLOADER_EXPORT MEDMeshMultiLev *buildFromScratchDataSetSupportOnCells(const MEDFileMeshStruct *mst, const MEDFileFieldGlobsReal *globs) const; - MEDLOADER_EXPORT static MEDFileField1TSStructItem BuildItemFrom(const MEDFileAnyTypeField1TS *ref, const MEDFileMeshStruct *meshSt); - private: - bool _computed; - TypeOfField _type; - std::vector< MEDFileField1TSStructItem2 > _items; - }; - - class MEDFileField1TSStruct : public RefCountObject - { - public: - static MEDFileField1TSStruct *New(const MEDFileAnyTypeField1TS *ref, MEDFileMeshStruct *mst); - void checkWithMeshStruct(MEDFileMeshStruct *mst, const MEDFileFieldGlobsReal *globs); - std::size_t getHeapMemorySizeWithoutChildren() const; - std::vector getDirectChildrenWithNull() const; - bool isEqualConsideringThePast(const MEDFileAnyTypeField1TS *other, const MEDFileMeshStruct *mst) const; - bool isSupportSameAs(const MEDFileAnyTypeField1TS *other, const MEDFileMeshStruct *meshSt); - bool isCompatibleWithNodesDiscr(const MEDFileAnyTypeField1TS *other, const MEDFileMeshStruct *meshSt); - MEDLOADER_EXPORT MEDMeshMultiLev *buildFromScratchDataSetSupport(const MEDFileMeshStruct *mst, const MEDFileFieldGlobsReal *globs) const; - bool isDataSetSupportFastlyEqualTo(const MEDFileField1TSStruct& other, const MEDFileFieldGlobsReal *globs) const; - std::vector getGeoTypes(const MEDFileMesh *m) const; - private: - MEDFileField1TSStruct(const MEDFileAnyTypeField1TS *ref, MEDFileMeshStruct *mst); - bool presenceOfCellDiscr(int& pos) const; - bool presenceOfPartialNodeDiscr(int& pos) const; - private: - std::vector _already_checked; - }; - - class MEDFileFastCellSupportComparator : public RefCountObject - { - public: - MEDLOADER_EXPORT static MEDFileFastCellSupportComparator *New(const MEDFileMeshStruct *m, const MEDFileAnyTypeFieldMultiTS *ref); - MEDLOADER_EXPORT MEDMeshMultiLev *buildFromScratchDataSetSupport(int timeStepId, const MEDFileFieldGlobsReal *globs) const; - MEDLOADER_EXPORT bool isDataSetSupportEqualToThePreviousOne(int timeStepId, const MEDFileFieldGlobsReal *globs) const; - MEDLOADER_EXPORT int getNumberOfTS() const; - MEDLOADER_EXPORT std::vector getGeoTypesAt(int timeStepId, const MEDFileMesh *m) const; - bool isEqual(const MEDFileAnyTypeFieldMultiTS *other); - bool isCompatibleWithNodesDiscr(const MEDFileAnyTypeFieldMultiTS *other); - std::size_t getHeapMemorySizeWithoutChildren() const; - std::vector getDirectChildrenWithNull() const; - private: - MEDFileFastCellSupportComparator(const MEDFileMeshStruct *m, const MEDFileAnyTypeFieldMultiTS *ref); - private: - MEDCouplingAutoRefCountObjectPtr _mesh_comp; - std::vector< MEDCouplingAutoRefCountObjectPtr > _f1ts_cmps; - }; -} - -#endif diff --git a/src/MEDLoader/MEDFileJoint.cxx b/src/MEDLoader/MEDFileJoint.cxx deleted file mode 100644 index 2db32825a..000000000 --- a/src/MEDLoader/MEDFileJoint.cxx +++ /dev/null @@ -1,839 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// - -#include "MEDFileJoint.hxx" -#include "MEDFileUtilities.hxx" -#include "MEDLoader.hxx" -#include "MEDLoaderBase.hxx" -#include "MEDFileSafeCaller.txx" - -#include "CellModel.hxx" -#include "InterpKernelAutoPtr.hxx" - -extern med_geometry_type typmai[MED_N_CELL_FIXED_GEO]; -extern INTERP_KERNEL::NormalizedCellType typmai2[MED_N_CELL_FIXED_GEO]; -extern med_geometry_type typmai3[34]; - -using namespace ParaMEDMEM; - -std::size_t MEDFileJointCorrespondence::getHeapMemorySizeWithoutChildren() const -{ - return sizeof(MEDCouplingAutoRefCountObjectPtr); -} - -std::vector MEDFileJointCorrespondence::getDirectChildrenWithNull() const -{ - return std::vector(); -} - -MEDFileJointCorrespondence::MEDFileJointCorrespondence(): - _is_nodal( true ), - _loc_geo_type( INTERP_KERNEL::NORM_ERROR ), - _rem_geo_type( INTERP_KERNEL::NORM_ERROR ) -{ -} - -/*! - * Constructor. - * \param [in] correspondence - correspondence. - * \param [in] is_nodal - is the correspondence of cells or nodes. - * \param [in] loc_geo_type - the local geometry type of correspondence. - * \param [in] rem_geo_type - the remote geometry type of correspondence. - */ -MEDFileJointCorrespondence::MEDFileJointCorrespondence(DataArrayInt* correspondence, - bool isNodal, - INTERP_KERNEL::NormalizedCellType loc_geo_type, - INTERP_KERNEL::NormalizedCellType rem_geo_type): - _is_nodal( isNodal ), - _loc_geo_type( loc_geo_type ), - _rem_geo_type( rem_geo_type ) -{ - MEDFileJointCorrespondence::setCorrespondence( correspondence ); -} - -MEDFileJointCorrespondence* MEDFileJointCorrespondence::New(DataArrayInt* correspondence, - INTERP_KERNEL::NormalizedCellType loc_geo_type, - INTERP_KERNEL::NormalizedCellType rem_geo_type) -{ - return new MEDFileJointCorrespondence(correspondence, /*isNodal=*/false, loc_geo_type, rem_geo_type ); -} - -/*! - * Returns a new MEDFileJointCorrespondence of nodes - */ -MEDFileJointCorrespondence *MEDFileJointCorrespondence::New(DataArrayInt* correspondence) -{ - return new MEDFileJointCorrespondence(correspondence); -} - -/*! - * Returns a new undefined MEDFileJointCorrespondence - */ - -MEDFileJointCorrespondence *MEDFileJointCorrespondence::New() -{ - return new MEDFileJointCorrespondence(); -} - -/*! - * Writes \a this joint into a MED file specified by its name. - * \param [in] fileName - the MED file name. - * \param [in] mode - the writing mode. For more on \a mode, see \ref AdvMEDLoaderBasics. - * - 2 - erase; an existing file is removed. - * - 1 - append; same data should not be present in an existing file. - * - 0 - overwrite; same data present in an existing file is overwritten. - * \param [in] order - order. - * \param [in] iteration - iteration. - * \throw If the mesh name is not set. - * \throw If \a mode == 1 and the same data is present in an existing file. - */ -void MEDFileJointCorrespondence::write(const std::string& fileName, int mode, const std::string& localMeshName, const std::string& jointName, int order, int iteration) const -{ - med_access_mode medmod=MEDFileUtilities::TraduceWriteMode(mode); - MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName.c_str(),medmod); - - std::ostringstream oss; oss << "MEDFileJointCorrespondence : error on attempt to write in file : \"" << fileName << "\""; - MEDFileUtilities::CheckMEDCode(fid,fid,oss.str()); - - if (( !_is_nodal ) && - ( _loc_geo_type == INTERP_KERNEL::NORM_ERROR || - _rem_geo_type == INTERP_KERNEL::NORM_ERROR )) - { - throw INTERP_KERNEL::Exception( "Geometric type not specified for a cell Joint" ); - } - - if ( (const DataArrayInt *)_correspondence ) - { - writeLL(fid, localMeshName, jointName, order, iteration); - } - else - { - throw INTERP_KERNEL::Exception("MEDFileJointCorrespondence::write : correspondence array not defined"); - } -} - -void MEDFileJointCorrespondence::writeLL(med_idt fid, const std::string& localMeshName, const std::string& jointName, int order, int iteration) const -{ - if ( _is_nodal ) - { - MEDFILESAFECALLERWR0(MEDsubdomainCorrespondenceWr,(fid, localMeshName.c_str(), jointName.c_str(), - order, iteration, - MED_NODE, MED_NONE, - MED_NODE, MED_NONE, - _correspondence->getNbOfElems()/2, - _correspondence->getConstPointer())); - } - else - { - MEDFILESAFECALLERWR0(MEDsubdomainCorrespondenceWr,(fid, localMeshName.c_str(), jointName.c_str(), - order, iteration, - MED_CELL, typmai3[ _loc_geo_type ], - MED_CELL, typmai3[ _rem_geo_type ], - _correspondence->getNbOfElems()/2, - _correspondence->getConstPointer())); - } -} - -void MEDFileJointCorrespondence::setCorrespondence(DataArrayInt *corr) -{ - _correspondence=corr; - if ( corr ) - corr->incrRef(); -} - -/*! - * Checks if \a this and another mesh are equal. - * \param [in] other - the mesh to compare with. - * \return bool - \c true if the meshes are equal, \c false, else. - */ -bool MEDFileJointCorrespondence::isEqual(const MEDFileJointCorrespondence *other) const -{ - if(_is_nodal!=other->_is_nodal) - return false; - if(_loc_geo_type!=other->_loc_geo_type) - return false; - if(_rem_geo_type!=other->_rem_geo_type) - return false; - if(!_correspondence->isEqual(*other->_correspondence)) - return false; - return true; -} - -MEDFileJointCorrespondence *MEDFileJointCorrespondence::deepCpy() const -{ - MEDCouplingAutoRefCountObjectPtr ret=new MEDFileJointCorrespondence(*this); - return ret.retn(); -} - -MEDFileJointCorrespondence *MEDFileJointCorrespondence::shallowCpy() const -{ - MEDCouplingAutoRefCountObjectPtr ret=new MEDFileJointCorrespondence(*this); - return ret.retn(); -} - -/*! - * Returns a string describing \a this mesh. This description includes the correspondence and - * the number correspondence. - * \return std::string - the joint information string. - */ -std::string MEDFileJointCorrespondence::simpleRepr() const -{ - std::ostringstream oss; - oss << "(*************************************)\n(* JOINT_CORRESPOND INFORMATION: *)\n(*************************************)\n"; - oss << "- entity type of the correspondence : " << ( getIsNodal() ? "NODE" : "CELL" ) << "\n"; - oss << "- Local geometry type of the correspondence : " << INTERP_KERNEL::CellModel::GetCellModel( _loc_geo_type ).getRepr() << "\n"; - oss << "- Remote geometry type of the correspondence : " << INTERP_KERNEL::CellModel::GetCellModel( _rem_geo_type ).getRepr() << "\n"; - if ( (const DataArrayInt *)_correspondence ) - { - oss << "- Number entity of the correspondence : " << getCorrespondence()->getNumberOfTuples() << "\n"; - - const DataArrayInt* tmp=getCorrespondence(); - oss << "- Correspondence : <<"; - for(const int *it=tmp->begin();it!=tmp->end();it++) - oss<< *it << " "; - } - else - { - oss << "- Number entity of the correspondence : 0\n"; - } - oss << std::endl; - return oss.str(); -} - - -MEDFileJointOneStep::MEDFileJointOneStep():_order(-1),_iteration(-1) -{ -} - -std::size_t MEDFileJointOneStep::getHeapMemorySizeWithoutChildren() const -{ - return _correspondences.capacity()*sizeof(MEDCouplingAutoRefCountObjectPtr); -} - -std::vector MEDFileJointOneStep::getDirectChildrenWithNull() const -{ - return std::vector(); -} - -MEDFileJointOneStep *MEDFileJointOneStep::New(int dt, int it) -{ - MEDFileJointOneStep* j = new MEDFileJointOneStep(); - j->setOrder( dt ); - j->setIteration( it ); - return j; -} - -/*! - * Returns a new MEDFileJointOneStep. - * \param [in] fileName - the name of MED file to read. - * \param [in] mName - the name of the mesh to read. - * \param [in] jointName - the joint name. - * \param [in] num - the number of an iteration. - * \return MEDFileMesh * - a new instance of MEDFileJointOneStep. - * \throw If the file is not readable. - * \throw If there is no mesh with given attributes in the file. - */ -MEDFileJointOneStep *MEDFileJointOneStep::New(const std::string& fileName, const std::string& mName, const std::string& jointName, int num) -{ - MEDFileUtilities::CheckFileForRead(fileName); - MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName.c_str(), MED_ACC_RDONLY); - return new MEDFileJointOneStep(fid, mName, jointName, num); -} - -MEDFileJointOneStep* MEDFileJointOneStep::New(med_idt fid, const std::string& mName, const std::string& jointName, int num) -{ - return new MEDFileJointOneStep( fid, mName, jointName, num); -} - -MEDFileJointOneStep::MEDFileJointOneStep(med_idt fid, const std::string& mName, const std::string& jointName, int num) -{ - int order, iteration, ncorrespondence; - MEDFILESAFECALLERRD0(MEDsubdomainComputingStepInfo,(fid, mName.c_str(), jointName.c_str(), num, &order, &iteration, &ncorrespondence)); - MEDFileJointOneStep::setOrder(order); - MEDFileJointOneStep::setIteration(iteration); - for ( int cur_it = 1; cur_it <= ncorrespondence; ++cur_it ) - { - int num_entity; - med_entity_type loc_ent_type, rem_ent_type; - med_geometry_type loc_geo_type, rem_geo_type; - MEDFILESAFECALLERRD0(MEDsubdomainCorrespondenceSizeInfo,(fid, mName.c_str(), jointName.c_str(), order, iteration, cur_it, - &loc_ent_type, &loc_geo_type, &rem_ent_type, &rem_geo_type, &num_entity)); - if ( num_entity > 0 ) - { - MEDCouplingAutoRefCountObjectPtr correspondence=DataArrayInt::New(); - correspondence->alloc(num_entity*2, 1); - MEDFILESAFECALLERRD0(MEDsubdomainCorrespondenceRd,(fid, mName.c_str(), jointName.c_str(), order, iteration, loc_ent_type, - loc_geo_type, rem_ent_type, rem_geo_type, correspondence->getPointer())); - MEDFileJointCorrespondence *cor=MEDFileJointCorrespondence::New(); - cor->setIsNodal( loc_ent_type == MED_NODE ); - cor->setLocalGeometryType ( convertGeometryType( loc_geo_type )); - cor->setRemoteGeometryType( convertGeometryType( rem_geo_type )); - cor->setCorrespondence( correspondence ); - _correspondences.push_back(cor); - } - } -} - -/*! - * Writes \a this joint into a MED file specified by its name. - * \param [in] fileName - the MED file name. - * \param [in] mode - the writing mode. For more on \a mode, see \ref AdvMEDLoaderBasics. - * - 2 - erase; an existing file is removed. - * - 1 - append; same data should not be present in an existing file. - * - 0 - overwrite; same data present in an existing file is overwritten. - * \throw If the mesh name is not set. - * \throw If \a mode == 1 and the same data is present in an existing file. - */ -void MEDFileJointOneStep::write(const std::string& fileName, int mode, const std::string& localMeshName, const std::string& jointName) const -{ - med_access_mode medmod=MEDFileUtilities::TraduceWriteMode(mode); - MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName.c_str(),medmod); - std::ostringstream oss; oss << "MEDFileJointOneStep : error on attempt to write in file : \"" << fileName << "\""; - MEDFileUtilities::CheckMEDCode(fid,fid,oss.str()); - if ( _correspondences.empty() ) - throw INTERP_KERNEL::Exception("MEDFileJointOneStep::write : no correspondences defined !"); - writeLL(fid, localMeshName, jointName); -} - -void MEDFileJointOneStep::writeLL(med_idt fid, const std::string& localMeshName, const std::string& jointName) const -{ - for(std::vector< MEDCouplingAutoRefCountObjectPtr >::const_iterator it=_correspondences.begin();it!=_correspondences.end();it++) - { - (*it)->writeLL(fid, localMeshName, jointName, getOrder(), getIteration()); - } -} - -void MEDFileJointOneStep::pushCorrespondence(MEDFileJointCorrespondence* correspondence) -{ - if(!correspondence) - throw INTERP_KERNEL::Exception("MEDFileJointCorrespondence::pushCorrespondence : invalid input pointer ! should be different from 0 !"); - _correspondences.push_back(correspondence); - correspondence->incrRef(); -} - -int MEDFileJointOneStep::getNumberOfCorrespondences() const -{ - return _correspondences.size(); -} - -/** Return a borrowed reference (caller is not responsible) */ -MEDFileJointCorrespondence *MEDFileJointOneStep::getCorrespondenceAtPos(int i) const -{ - if(i<0 || i>=(int)_correspondences.size()) - { - std::ostringstream oss; oss << "MEDFileJointOneStep::getCorrespondenceAtPos : invalid correspondence id given in parameter ! Should be in [0;" << _correspondences.size() << ") !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - const MEDFileJointCorrespondence* ret = _correspondences[i]; - return const_cast( ret ); -} - -/*! - * Checks if \a this and another Joint are equal. - * \param [in] other - the Joint to compare with. - * \return bool - \c true if the Joints are equal, \c false, else. - */ -bool MEDFileJointOneStep::isEqual(const MEDFileJointOneStep *other) const -{ - if(_order!=other->_order) - return false; - if(_iteration!=other->_iteration) - return false; - if ( getNumberOfCorrespondences() != other->getNumberOfCorrespondences() ) - return false; - - std::vector found( getNumberOfCorrespondences(), false ); - for(int i=0; iisEqual(other->getCorrespondenceAtPos(j))) - { - found[ j ] = true; - break; - } - } - if ( j == getNumberOfCorrespondences() ) - return false; - } - return true; -} - -MEDFileJointOneStep *MEDFileJointOneStep::deepCpy() const -{ - std::vector< MEDCouplingAutoRefCountObjectPtr > correspondences(_correspondences.size()); - std::size_t i=0; - for(std::vector< MEDCouplingAutoRefCountObjectPtr >::const_iterator it=_correspondences.begin();it!=_correspondences.end();it++,i++) - if((const MEDFileJointCorrespondence *)*it) - correspondences[i]=(*it)->deepCpy(); - MEDCouplingAutoRefCountObjectPtr ret= new MEDFileJointOneStep; - ret->_correspondences=correspondences; - return ret.retn(); -} - -MEDFileJointOneStep *MEDFileJointOneStep::shallowCpy() const -{ - MEDCouplingAutoRefCountObjectPtr ret=new MEDFileJointOneStep(*this); - return ret.retn(); -} - -/*! - * Returns a string describing \a this Joint. This description includes the correspondence and - * the number of correspondences. - * \return std::string - the joint information string. - */ -std::string MEDFileJointOneStep::simpleRepr() const -{ - std::ostringstream oss; - oss << "(*************************************)\n(* JOINT_ONE_STEP INFORMATION: *)\n(*************************************)\n"; - oss << "- Number of the correspondences : <<" << _correspondences.size() << ">>\n"; - for(std::vector< MEDCouplingAutoRefCountObjectPtr >::const_iterator it=_correspondences.begin();it!=_correspondences.end();it++) - { - oss << (*it)->simpleRepr(); - } - return oss.str(); -} -INTERP_KERNEL::NormalizedCellType MEDFileJointOneStep::convertGeometryType(med_geometry_type geotype) -{ - INTERP_KERNEL::NormalizedCellType result=INTERP_KERNEL::NORM_ERROR; - for(int i=0; i); -} - -std::vector MEDFileJoint::getDirectChildrenWithNull() const -{ - return std::vector(); -} - -MEDFileJoint *MEDFileJoint::New() -{ - return new MEDFileJoint(); -} - -MEDFileJoint *MEDFileJoint::New(const std::string& fileName, const std::string& mName, int curJoint) -{ - MEDFileUtilities::CheckFileForRead(fileName); - MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName.c_str(), MED_ACC_RDONLY); - return new MEDFileJoint(fid,mName,curJoint); -} - -MEDFileJoint *MEDFileJoint::New(med_idt fid, const std::string& mName, int curJoint) -{ - return new MEDFileJoint(fid,mName,curJoint); -} - -MEDFileJoint *MEDFileJoint::New(const std::string& jointName, const std::string& locMeshName, const std::string& remoteMeshName, int remoteMeshNum) -{ - MEDFileJoint* j = new MEDFileJoint(); - j->setJointName( jointName ); - j->setLocalMeshName( locMeshName ); - j->setRemoteMeshName( remoteMeshName ); - j->setDomainNumber( remoteMeshNum ); - return j; -} - -MEDFileJoint::MEDFileJoint() -{ -} - -/*! - * Returns a new MEDFileJoint holding the mesh data that has been read from a given MED - * file. The Joint to load is specified by mesh name and a Joint iteration. - * \param [in] fileName - the name of MED file to read. - * \param [in] mName - the name of the mesh to read. - * \param [in] curJoint - the iteration number of current joint. - * \return MEDFileJoint * - a new instance of MEDFileJoint. - * \throw If the file is not readable. - * \throw If there is no mesh with given attributes in the file. - */ -MEDFileJoint::MEDFileJoint(med_idt fid, const std::string& mName, int curJoint) -{ - INTERP_KERNEL::AutoPtr joint_name=MEDLoaderBase::buildEmptyString(MED_NAME_SIZE); - INTERP_KERNEL::AutoPtr desc_name=MEDLoaderBase::buildEmptyString(MED_COMMENT_SIZE); - INTERP_KERNEL::AutoPtr rem_mesh_name=MEDLoaderBase::buildEmptyString(MED_NAME_SIZE); - int domain_number=0, nstep=0, nocstpncorrespondence=0; - MEDFILESAFECALLERRD0(MEDsubdomainJointInfo,(fid,mName.c_str(), curJoint, joint_name, desc_name, &domain_number,rem_mesh_name, - &nstep, &nocstpncorrespondence)); - setLocalMeshName(mName); - setRemoteMeshName(MEDLoaderBase::buildStringFromFortran(rem_mesh_name,MED_NAME_SIZE)); - setDescription(MEDLoaderBase::buildStringFromFortran(desc_name,MED_COMMENT_SIZE)); - setJointName(MEDLoaderBase::buildStringFromFortran(joint_name,MED_NAME_SIZE)); - setDomainNumber(domain_number); - for(int cur_step=1; cur_step <= nstep; ++cur_step) - { - MEDFileJointOneStep *cor=MEDFileJointOneStep::New(fid, mName.c_str(), getJointName(), cur_step); - _joint.push_back(cor); - } -} - -/*! - * Writes \a this joint into a MED file specified by its name. - * \param [in] fileName - the MED file name. - * \param [in] mode - the writing mode. For more on \a mode, see \ref AdvMEDLoaderBasics. - * - 2 - erase; an existing file is removed. - * - 1 - append; same data should not be present in an existing file. - * - 0 - overwrite; same data present in an existing file is overwritten. - * \throw If the mesh name is not set. - * \throw If \a mode == 1 and the same data is present in an existing file. - */ -void MEDFileJoint::write(const std::string& fileName, int mode) const -{ - med_access_mode medmod=MEDFileUtilities::TraduceWriteMode(mode); - MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName.c_str(),medmod); - std::ostringstream oss; oss << "MEDFileJoint : error on attempt to write in file : \"" << fileName << "\""; - MEDFileUtilities::CheckMEDCode(fid,fid,oss.str()); - write(fid); -} - -void MEDFileJoint::write(med_idt fid) const -{ - // if ( _loc_mesh_name.empty() ) - // throw INTERP_KERNEL::Exception("MEDFileJoint::write : name of a local mesh not defined!"); - MEDFILESAFECALLERWR0(MEDsubdomainJointCr,(fid,getLocalMeshName().c_str(),getJointName().c_str(),getDescription().c_str(),getDomainNumber(),getRemoteMeshName().c_str())); - for(std::vector< MEDCouplingAutoRefCountObjectPtr >::const_iterator it=_joint.begin();it!=_joint.end();it++) { - (*it)->writeLL(fid, getLocalMeshName(),getJointName()); - } -} - -void MEDFileJoint::pushStep(MEDFileJointOneStep* step) -{ - if(!step) - throw INTERP_KERNEL::Exception("MEDFileJoint::pushStep : invalid input pointer ! should be different from 0 !"); - _joint.push_back(step); - step->incrRef(); -} - -int MEDFileJoint::getNumberOfSteps() const -{ - return _joint.size(); -} - -/** Return a borrowed reference (caller is not responsible) */ -MEDFileJointOneStep *MEDFileJoint::getStepAtPos(int i) const -{ - if(i<0 || i>=(int)_joint.size()) - { - std::ostringstream oss; oss << "MEDFileJoint::getStepAtPos : invalid step id given in parameter ! Should be in [0;" << _joint.size() << ") !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - const MEDFileJointOneStep* ret = _joint[i]; - return const_cast( ret ); -} - -/*! - * Checks if \a this and another Joint are equal. - * \param [in] other - the Joint to compare with. - * \return bool - \c true if the Joints are equal, \c false, else. - */ -bool MEDFileJoint::isEqual(const MEDFileJoint *other) const -{ - if(_loc_mesh_name!=other->_loc_mesh_name) - return false; - if(_joint_name!=other->_joint_name) - return false; - if(_desc_name!=other->_desc_name) - return false; - if(_rem_mesh_name!=other->_rem_mesh_name) - return false; - if(_domain_number!=other->_domain_number) - return false; - std::vector found( getNumberOfSteps(), false ); - for(int i=0; iisEqual(other->getStepAtPos(j))) - { - found[ j ] = true; - break; - } - } - if ( j == getNumberOfSteps() ) - return false; - } - return true; -} - -MEDFileJoint *MEDFileJoint::deepCpy() const -{ - std::vector< MEDCouplingAutoRefCountObjectPtr > joint(_joint.size()); - std::size_t i=0; - for(std::vector< MEDCouplingAutoRefCountObjectPtr >::const_iterator it=_joint.begin();it!=_joint.end();it++,i++) - if((const MEDFileJointOneStep *)*it) - joint[i]=(*it)->deepCpy(); - MEDCouplingAutoRefCountObjectPtr ret=MEDFileJoint::New(); - ret->_joint=joint; - return ret.retn(); -} - -MEDFileJoint *MEDFileJoint::shallowCpy() const -{ - MEDCouplingAutoRefCountObjectPtr ret=new MEDFileJoint(*this); - return ret.retn(); -} - -bool MEDFileJoint::changeJointNames(const std::vector< std::pair >& modifTab) -{ - for(std::vector< std::pair >::const_iterator it=modifTab.begin();it!=modifTab.end();it++) - { - if((*it).first==_joint_name) - { - _joint_name=(*it).second; - return true; - } - } - return false; -} - -/*! - * Returns a string describing \a this mesh. This description includes the correspondence and - * the number correspondence. - * \return std::string - the joint information string. - */ -std::string MEDFileJoint::simpleRepr() const -{ - std::ostringstream oss; - oss << "(*************************************)\n(* JOINT INFORMATION: *)\n(*************************************)\n"; - oss << "- Local Mesh name : <<" << getLocalMeshName() << ">>\n"; - oss << "- Remote Mesh name : <<" << getRemoteMeshName() << ">>\n"; - oss << "- Description : <<" << getDescription() << ">>\n"; - oss << "- Joint name : <<" << getJointName() << ">>\n"; - oss << "- Domain number : " << getDomainNumber() << "\n"; - for(std::vector< MEDCouplingAutoRefCountObjectPtr >::const_iterator it=_joint.begin();it!=_joint.end();it++) - { - oss << (*it)->simpleRepr(); - } - return oss.str(); -} - -MEDFileJoints *MEDFileJoints::New() -{ - return new MEDFileJoints; -} - -MEDFileJoints *MEDFileJoints::New(const std::string& fileName, const std::string& meshName) -{ - MEDFileUtilities::CheckFileForRead(fileName); - MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName.c_str(), MED_ACC_RDONLY); - return new MEDFileJoints( fid, meshName ); -} - -MEDFileJoints *MEDFileJoints::New(med_idt fid, const std::string& meshName) -{ - return new MEDFileJoints( fid, meshName ); -} - -void MEDFileJoints::write(med_idt fid) const -{ - for(std::vector< MEDCouplingAutoRefCountObjectPtr >::const_iterator it=_joints.begin();it!=_joints.end();it++) - { - (*it)->write(fid); - } -} - -void MEDFileJoints::write(const std::string& fileName, int mode) const -{ - med_access_mode medmod=MEDFileUtilities::TraduceWriteMode(mode); - MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName.c_str(),medmod); - std::ostringstream oss; oss << "MEDFileJoints : error on attempt to write in file : \"" << fileName << "\""; - MEDFileUtilities::CheckMEDCode(fid,fid,oss.str()); - write(fid); -} - -std::string MEDFileJoints::getMeshName() const -{ - for ( size_t i = 0; i <= _joints.size(); ++i ) - if ( (const MEDFileJoint*) _joints[i] ) - return _joints[i]->getLocalMeshName(); - - return ""; -} - -int MEDFileJoints::getNumberOfJoints() const -{ - return _joints.size(); -} - -/** Return a borrowed reference (caller is not responsible) */ -MEDFileJoint *MEDFileJoints::getJointAtPos(int i) const -{ - if(i<0 || i>=(int)_joints.size()) - { - std::ostringstream oss; oss << "MEDFileJoints::getJointAtPos : invalid joint id given in parameter ! Should be in [0;" << _joints.size() << ") !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - const MEDFileJoint* ret = _joints[i]; - return const_cast( ret ); -} - - -/** Return a borrowed reference (caller is not responsible) */ -MEDFileJoint *MEDFileJoints::getJointWithName(const std::string& jname) const -{ - std::vector js=getJointsNames(); - std::vector::iterator it=std::find(js.begin(),js.end(),jname); - if(it==js.end()) - { - std::ostringstream oss; oss << "MEDFileJoints::getJointWithName : Joint \"" << jname << "\" does not exist in this ! Existing are : "; - std::copy(js.begin(),js.end(),std::ostream_iterator(oss," ")); - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - return getJointAtPos((int)std::distance(js.begin(),it)); -} - -std::vector MEDFileJoints::getJointsNames() const -{ - std::vector ret(_joints.size()); - int i=0; - for(std::vector< MEDCouplingAutoRefCountObjectPtr >::const_iterator it=_joints.begin();it!=_joints.end();it++,i++) - { - const MEDFileJoint *f=(*it); - if(f) - { - ret[i]=f->getJointName(); - } - else - { - std::ostringstream oss; oss << "MEDFileJoints::getJointsNames : At rank #" << i << " joint is not defined !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - } - return ret; -} - -bool MEDFileJoints::changeJointNames(const std::vector< std::pair >& modifTab) -{ - bool ret=false; - for(std::vector< MEDCouplingAutoRefCountObjectPtr >::iterator it=_joints.begin();it!=_joints.end();it++) - { - MEDFileJoint *cur(*it); - if(cur) - ret=cur->changeJointNames(modifTab) || ret; - } - return ret; -} - -void MEDFileJoints::resize(int newSize) -{ - _joints.resize(newSize); -} - -void MEDFileJoints::pushJoint(MEDFileJoint *joint) -{ - if(!joint) - throw INTERP_KERNEL::Exception("MEDFileJoints::pushJoint() : invalid input pointer ! should be different from 0 !"); - if ( !_joints.empty() && - _joints[0]->getLocalMeshName() != joint->getLocalMeshName() ) - throw INTERP_KERNEL::Exception("MEDFileJoints::pushJoint() : different names of local meshes ! should be equal !"); - - _joints.push_back(joint); - joint->incrRef(); -} - -void MEDFileJoints::setJointAtPos(int i, MEDFileJoint *joint) -{ - if(!joint) - throw INTERP_KERNEL::Exception("MEDFileJoints::setJointAtPos : invalid input pointer ! should be different from 0 !"); - if(i>=(int)_joints.size()) - _joints.resize(i+1); - _joints[i]=joint; - joint->incrRef(); -} - -void MEDFileJoints::destroyJointAtPos(int i) -{ - if(i<0 || i>=(int)_joints.size()) - { - std::ostringstream oss; oss << "MEDFileJoints::destroyJointAtPos : Invalid given id in input (" << i << ") should be in [0," << _joints.size() << ") !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - _joints.erase(_joints.begin()+i); -} - -MEDFileJoints::MEDFileJoints() -{ -} - -MEDFileJoints::MEDFileJoints(med_idt fid, const std::string& meshName) -{ - int num_joint=MEDnSubdomainJoint(fid, meshName.c_str() ); - for(int i = 1; i <= num_joint; i++) - _joints.push_back(MEDFileJoint::New(fid,meshName,i)); -} - -MEDFileJoints *MEDFileJoints::deepCpy() const -{ - std::vector< MEDCouplingAutoRefCountObjectPtr > joints(_joints.size()); - std::size_t i=0; - for(std::vector< MEDCouplingAutoRefCountObjectPtr >::const_iterator it=_joints.begin();it!=_joints.end();it++,i++) - if((const MEDFileJoint *)*it) - joints[i]=(*it)->deepCpy(); - MEDCouplingAutoRefCountObjectPtr ret=MEDFileJoints::New(); - ret->_joints=joints; - return ret.retn(); -} - -std::size_t MEDFileJoints::getHeapMemorySizeWithoutChildren() const -{ - return _joints.capacity()*(sizeof(MEDCouplingAutoRefCountObjectPtr)); -} - -std::vector MEDFileJoints::getDirectChildrenWithNull() const -{ - std::vector ret; - for(std::vector< MEDCouplingAutoRefCountObjectPtr >::const_iterator it=_joints.begin();it!=_joints.end();it++) - ret.push_back((const MEDFileJoint *)*it); - return ret; -} - -std::string MEDFileJoints::simpleRepr() const -{ - std::ostringstream oss; - oss << "(*****************)\n(* MEDFileJoints *)\n(*****************)\n\n"; - simpleReprWithoutHeader(oss); - return oss.str(); -} - -void MEDFileJoints::simpleReprWithoutHeader(std::ostream& oss) const -{ - int nbOfJoints=getNumberOfJoints(); - oss << "There are " << nbOfJoints << " joints with the following names : \n"; - std::vector jns=getJointsNames(); - for(int i=0;i >::const_iterator it=_joints.begin();it!=_joints.end();it++) - { - oss << (*it)->simpleRepr(); - } -} diff --git a/src/MEDLoader/MEDFileJoint.hxx b/src/MEDLoader/MEDFileJoint.hxx deleted file mode 100644 index 1d32312f8..000000000 --- a/src/MEDLoader/MEDFileJoint.hxx +++ /dev/null @@ -1,194 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 -// 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 __MEDFILEJOINT_HXX__ -#define __MEDFILEJOINT_HXX__ - -#include "MEDLoaderDefines.hxx" -#include "MEDFileUtilities.hxx" -#include "MEDCouplingMemArray.hxx" -#include "MEDCouplingAutoRefCountObjectPtr.hxx" - -namespace ParaMEDMEM -{ -/*! - * \brief Joint Correspondence enumerates pairs of corresponding entities of a - * certain geometrical type in adjacent mesh domains. - * Correspondence of nodes is constructed when you specify no cell type, - * else Correspondence of cells is constructed. - */ -class MEDFileJointCorrespondence : public RefCountObject, public MEDFileWritable -{ -public: - MEDLOADER_EXPORT static MEDFileJointCorrespondence *New(); - MEDLOADER_EXPORT static MEDFileJointCorrespondence *New(DataArrayInt* correspondence); // nodes - MEDLOADER_EXPORT static MEDFileJointCorrespondence *New(DataArrayInt* correspondence, // cells - INTERP_KERNEL::NormalizedCellType loc_geo_type, - INTERP_KERNEL::NormalizedCellType rem_geo_type); - MEDLOADER_EXPORT std::size_t getHeapMemorySizeWithoutChildren() const; - MEDLOADER_EXPORT std::vector getDirectChildrenWithNull() const; - MEDLOADER_EXPORT MEDFileJointCorrespondence *deepCpy() const; - MEDLOADER_EXPORT MEDFileJointCorrespondence *shallowCpy() const; - MEDLOADER_EXPORT bool isEqual(const MEDFileJointCorrespondence *other) const; - MEDLOADER_EXPORT void setIsNodal(bool isNodal) { _is_nodal = isNodal; } - MEDLOADER_EXPORT bool getIsNodal() const { return _is_nodal; } - MEDLOADER_EXPORT void setLocalGeometryType(INTERP_KERNEL::NormalizedCellType type) { _loc_geo_type=type; } - MEDLOADER_EXPORT INTERP_KERNEL::NormalizedCellType getLocalGeometryType() const { return _loc_geo_type; } - MEDLOADER_EXPORT void setRemoteGeometryType(INTERP_KERNEL::NormalizedCellType type) { _rem_geo_type=type; } - MEDLOADER_EXPORT INTERP_KERNEL::NormalizedCellType getRemoteGeometryType() const { return _rem_geo_type; } - MEDLOADER_EXPORT void setCorrespondence(DataArrayInt *corr); - MEDLOADER_EXPORT const DataArrayInt *getCorrespondence() const { return _correspondence; } - MEDLOADER_EXPORT void write(const std::string& fileName, int mode, const std::string& localMeshName, const std::string& jointName, int order, int iteration) const; - - MEDLOADER_EXPORT std::string simpleRepr() const; - MEDLOADER_EXPORT void writeLL(med_idt fid, const std::string& localMeshName, const std::string& jointName, int order, int iteration) const; -private: - MEDFileJointCorrespondence(); - MEDFileJointCorrespondence(DataArrayInt* correspondence, - bool is_nodal = true, - INTERP_KERNEL::NormalizedCellType loc_geo_type = INTERP_KERNEL::NORM_ERROR, - INTERP_KERNEL::NormalizedCellType rem_geo_type = INTERP_KERNEL::NORM_ERROR); -private: - bool _is_nodal; - INTERP_KERNEL::NormalizedCellType _loc_geo_type; - INTERP_KERNEL::NormalizedCellType _rem_geo_type; - MEDCouplingAutoRefCountObjectPtr _correspondence; -}; - -/*! - * \brief Joint of one iteration holds correspondences of entities of all types - */ -class MEDFileJointOneStep : public RefCountObject, public MEDFileWritable -{ -public: - MEDLOADER_EXPORT static MEDFileJointOneStep *New(int dt=-1, int it=-1); - MEDLOADER_EXPORT static MEDFileJointOneStep *New(const std::string& fileName, const std::string& mName, const std::string& jointName, int number=1); - MEDLOADER_EXPORT static MEDFileJointOneStep *New(med_idt fid, const std::string& mName, const std::string& jointName, int number=1); - MEDLOADER_EXPORT std::size_t getHeapMemorySizeWithoutChildren() const; - MEDLOADER_EXPORT std::vector getDirectChildrenWithNull() const; - MEDLOADER_EXPORT MEDFileJointOneStep *deepCpy() const; - MEDLOADER_EXPORT MEDFileJointOneStep *shallowCpy() const; - MEDLOADER_EXPORT bool isEqual(const MEDFileJointOneStep *other) const; - MEDLOADER_EXPORT void setOrder(int order) { _order=order; } - MEDLOADER_EXPORT int getOrder() const { return _order; } - MEDLOADER_EXPORT void setIteration(int it) { _iteration=it; } - MEDLOADER_EXPORT int getIteration() const { return _iteration; } - MEDLOADER_EXPORT void pushCorrespondence(MEDFileJointCorrespondence* correspondence); - MEDLOADER_EXPORT int getNumberOfCorrespondences() const; - MEDLOADER_EXPORT MEDFileJointCorrespondence *getCorrespondenceAtPos(int i) const; - - MEDLOADER_EXPORT void write(const std::string& fileName, int mode, const std::string& localMeshName, const std::string& jointName) const; - - MEDLOADER_EXPORT std::string simpleRepr() const; - MEDLOADER_EXPORT void writeLL(med_idt fid, const std::string& localMeshName, const std::string& jointName) const; -private: - MEDFileJointOneStep(); - MEDFileJointOneStep(med_idt fid, const std::string& mName, const std::string& jointName, int number); - MEDLOADER_EXPORT INTERP_KERNEL::NormalizedCellType convertGeometryType(med_geometry_type geotype); -protected: - int _order; - int _iteration; -private: - std::vector > _correspondences; -}; - -/*! - * \brief Joint holds a sequence of joints of different iterations relating to - * a pair of mesh domains: a local one and a distant one - */ -class MEDFileJoint : public RefCountObject, public MEDFileWritable -{ -public: - MEDLOADER_EXPORT static MEDFileJoint *New(); - MEDLOADER_EXPORT static MEDFileJoint *New(const std::string& fileName, const std::string& mName, int num); - MEDLOADER_EXPORT static MEDFileJoint *New(med_idt fid, const std::string& mName, int num); - MEDLOADER_EXPORT static MEDFileJoint *New(const std::string& jointName, const std::string& locMeshName, const std::string& remoteMeshName, int remoteMeshNum ); - MEDLOADER_EXPORT std::size_t getHeapMemorySizeWithoutChildren() const; - MEDLOADER_EXPORT std::vector getDirectChildrenWithNull() const; - MEDLOADER_EXPORT MEDFileJoint *deepCpy() const; - MEDLOADER_EXPORT MEDFileJoint *shallowCpy() const; - MEDLOADER_EXPORT bool isEqual(const MEDFileJoint *other) const; - MEDLOADER_EXPORT void setLocalMeshName(const std::string& name) { _loc_mesh_name=name; } - MEDLOADER_EXPORT std::string getLocalMeshName() const { return _loc_mesh_name; } - MEDLOADER_EXPORT void setRemoteMeshName(const std::string& name) { _rem_mesh_name=name; } - MEDLOADER_EXPORT std::string getRemoteMeshName() const { return _rem_mesh_name; } - MEDLOADER_EXPORT void setDescription(const std::string& name) { _desc_name=name; } - MEDLOADER_EXPORT std::string getDescription() const { return _desc_name; } - MEDLOADER_EXPORT void setJointName(const std::string& name) { _joint_name=name; } - MEDLOADER_EXPORT std::string getJointName() const { return _joint_name; } - MEDLOADER_EXPORT bool changeJointNames(const std::vector< std::pair >& modifTab); - MEDLOADER_EXPORT void setDomainNumber(const int& number) { _domain_number=number; } - MEDLOADER_EXPORT int getDomainNumber() const { return _domain_number; } - MEDLOADER_EXPORT void pushStep(MEDFileJointOneStep* step); - MEDLOADER_EXPORT int getNumberOfSteps() const; - MEDLOADER_EXPORT MEDFileJointOneStep *getStepAtPos(int i) const; - - MEDLOADER_EXPORT void write(const std::string& fileName, int mode) const; - MEDLOADER_EXPORT void write(med_idt fid) const; - - MEDLOADER_EXPORT std::string simpleRepr() const; - private: - MEDFileJoint(); - MEDFileJoint(med_idt fid, const std::string& mName, int num); - private: - std::string _loc_mesh_name; - std::string _joint_name; - std::string _desc_name; - int _domain_number; - std::string _rem_mesh_name; - std::vector< MEDCouplingAutoRefCountObjectPtr > _joint; - }; - - /*! - * \brief Joints of a mesh domain relating to all other mesh domains - */ - class MEDFileJoints : public RefCountObject, public MEDFileWritable - { - public: - MEDLOADER_EXPORT static MEDFileJoints *New(); - MEDLOADER_EXPORT static MEDFileJoints *New(const std::string& fileName, const std::string& meshName); - MEDLOADER_EXPORT static MEDFileJoints *New(med_idt fid, const std::string& meshName); - MEDLOADER_EXPORT MEDFileJoints *deepCpy() const; - MEDLOADER_EXPORT std::size_t getHeapMemorySizeWithoutChildren() const; - MEDLOADER_EXPORT std::vector getDirectChildrenWithNull() const; - MEDLOADER_EXPORT std::string simpleRepr() const; - MEDLOADER_EXPORT void simpleReprWithoutHeader(std::ostream& oss) const; - MEDLOADER_EXPORT void write(const std::string& fileName, int mode) const; - MEDLOADER_EXPORT void write(med_idt fid) const; - MEDLOADER_EXPORT std::string getMeshName() const; - MEDLOADER_EXPORT int getNumberOfJoints() const; - MEDLOADER_EXPORT MEDFileJoint *getJointAtPos(int i) const; - MEDLOADER_EXPORT MEDFileJoint *getJointWithName(const std::string& jname) const; - MEDLOADER_EXPORT std::vector getJointsNames() const; - MEDLOADER_EXPORT bool changeJointNames(const std::vector< std::pair >& modifTab); - // - MEDLOADER_EXPORT void resize(int newSize); - MEDLOADER_EXPORT void pushJoint(MEDFileJoint *joint); - MEDLOADER_EXPORT void setJointAtPos(int i, MEDFileJoint *joint); - MEDLOADER_EXPORT void destroyJointAtPos(int i); - private: - ~MEDFileJoints() { } - MEDFileJoints(); - MEDFileJoints(med_idt fid, const std::string& meshName); - private: - std::vector< MEDCouplingAutoRefCountObjectPtr > _joints; - }; -} - -#endif diff --git a/src/MEDLoader/MEDFileMesh.cxx b/src/MEDLoader/MEDFileMesh.cxx deleted file mode 100644 index a2ae03287..000000000 --- a/src/MEDLoader/MEDFileMesh.cxx +++ /dev/null @@ -1,6779 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 -// 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 "MEDFileMesh.hxx" -#include "MEDFileUtilities.hxx" -#include "MEDFileFieldOverView.hxx" -#include "MEDFileField.hxx" -#include "MEDLoader.hxx" -#include "MEDFileSafeCaller.txx" -#include "MEDLoaderBase.hxx" - -#include "MEDCouplingUMesh.hxx" - -#include "InterpKernelAutoPtr.hxx" - -#include -#include - -extern med_geometry_type typmai3[34]; - -using namespace ParaMEDMEM; - -const char MEDFileMesh::DFT_FAM_NAME[]="FAMILLE_ZERO"; - -MEDFileMesh::MEDFileMesh():_order(-1),_iteration(-1),_time(0.),_univ_wr_status(true) -{ -} - -std::size_t MEDFileMesh::getHeapMemorySizeWithoutChildren() const -{ - std::size_t ret(_dt_unit.capacity()+_name.capacity()+_univ_name.capacity()+_desc_name.capacity()); - for(std::map >::const_iterator it=_groups.begin();it!=_groups.end();it++) - { - ret+=(*it).first.capacity()+(*it).second.capacity()*sizeof(std::string); - for(std::vector::const_iterator it2=(*it).second.begin();it2!=(*it).second.end();it2++) - ret+=(*it2).capacity(); - } - for(std::map::const_iterator it=_families.begin();it!=_families.end();it++) - ret+=(*it).first.capacity()+sizeof(int); - return ret; -} - -std::vector MEDFileMesh::getDirectChildrenWithNull() const -{ - return std::vector(); -} - -/*! - * Returns a new MEDFileMesh holding the mesh data that has been read from a given MED - * file. The first mesh in the file is loaded. - * \param [in] fileName - the name of MED file to read. - * \return MEDFileMesh * - a new instance of MEDFileMesh. The caller is to delete this - * mesh using decrRef() as it is no more needed. - * \throw If the file is not readable. - * \throw If there is no meshes in the file. - * \throw If the mesh in the file is of a not supported type. - */ -MEDFileMesh *MEDFileMesh::New(const std::string& fileName, MEDFileMeshReadSelector *mrs) -{ - std::vector ms=MEDLoader::GetMeshNames(fileName); - if(ms.empty()) - { - std::ostringstream oss; oss << "MEDFileMesh::New : no meshes in file \"" << fileName << "\" !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - MEDFileUtilities::CheckFileForRead(fileName); - ParaMEDMEM::MEDCouplingMeshType meshType; - MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName.c_str(),MED_ACC_RDONLY); - int dt,it; - std::string dummy2; - MEDFileMeshL2::GetMeshIdFromName(fid,ms.front(),meshType,dt,it,dummy2); - switch(meshType) - { - case UNSTRUCTURED: - { - MEDCouplingAutoRefCountObjectPtr ret=MEDFileUMesh::New(); - ret->loadUMeshFromFile(fid,ms.front(),dt,it,mrs); - ret->loadJointsFromFile(fid); - return (MEDFileUMesh *)ret.retn(); - } - case CARTESIAN: - { - MEDCouplingAutoRefCountObjectPtr ret=MEDFileCMesh::New(); - ret->loadCMeshFromFile(fid,ms.front(),dt,it,mrs); - ret->loadJointsFromFile(fid); - return (MEDFileCMesh *)ret.retn(); - } - case CURVE_LINEAR: - { - MEDCouplingAutoRefCountObjectPtr ret=MEDFileCurveLinearMesh::New(); - ret->loadCLMeshFromFile(fid,ms.front(),dt,it,mrs); - ret->loadJointsFromFile(fid); - return (MEDFileCurveLinearMesh *)ret.retn(); - } - default: - { - std::ostringstream oss; oss << "MEDFileMesh::New : MED file exists and has mesh '" << ms.front() << "' exists but unsupported type yet !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - } -} - -/*! - * Returns a new MEDFileMesh holding the mesh data that has been read from a given MED - * file. The mesh to load is specified by its name and numbers of a time step and an - * iteration. - * \param [in] fileName - the name of MED file to read. - * \param [in] mName - the name of the mesh to read. - * \param [in] dt - the number of a time step. - * \param [in] it - the number of an iteration. - * \param [in] joints - the sub-domain joints to use instead of those that can be read - * from the MED file. Usually this joints are those just read by another iteration - * of mName mesh, when this method is called by MEDFileMeshMultiTS::New() - * \return MEDFileMesh * - a new instance of MEDFileMesh. The caller is to delete this - * mesh using decrRef() as it is no more needed. - * \throw If the file is not readable. - * \throw If there is no mesh with given attributes in the file. - * \throw If the mesh in the file is of a not supported type. - */ -MEDFileMesh *MEDFileMesh::New(const std::string& fileName, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs, MEDFileJoints* joints) -{ - MEDFileUtilities::CheckFileForRead(fileName); - ParaMEDMEM::MEDCouplingMeshType meshType; - MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName.c_str(),MED_ACC_RDONLY); - int dummy0,dummy1; - std::string dummy2; - MEDFileMeshL2::GetMeshIdFromName(fid,mName,meshType,dummy0,dummy1,dummy2); - switch(meshType) - { - case UNSTRUCTURED: - { - MEDCouplingAutoRefCountObjectPtr ret=MEDFileUMesh::New(); - ret->loadUMeshFromFile(fid,mName,dt,it,mrs); - ret->loadJointsFromFile(fid,joints); - return (MEDFileUMesh *)ret.retn(); - } - case CARTESIAN: - { - MEDCouplingAutoRefCountObjectPtr ret=MEDFileCMesh::New(); - ret->loadCMeshFromFile(fid,mName,dt,it,mrs); - ret->loadJointsFromFile(fid,joints); - return (MEDFileCMesh *)ret.retn(); - } - case CURVE_LINEAR: - { - MEDCouplingAutoRefCountObjectPtr ret=MEDFileCurveLinearMesh::New(); - ret->loadCLMeshFromFile(fid,mName,dt,it,mrs); - ret->loadJointsFromFile(fid,joints); - return (MEDFileCurveLinearMesh *)ret.retn(); - } - default: - { - std::ostringstream oss; oss << "MEDFileMesh::New : MED file exists and has mesh '" << mName << "' exists but unsupported type yet !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - } -} - -/*! - * Writes \a this mesh into an open MED file specified by its descriptor. - * \param [in] fid - the MED file descriptor. - * \throw If the mesh name is not set. - * \throw If the file is open for reading only. - * \throw If the writing mode == 1 and the same data is present in an existing file. - */ -void MEDFileMesh::write(med_idt fid) const -{ - if(!existsFamily(0)) - const_cast(this)->addFamily(DFT_FAM_NAME,0); - if(_name.empty()) - throw INTERP_KERNEL::Exception("MEDFileMesh : name is empty. MED file ask for a NON EMPTY name !"); - writeLL(fid); -} - -/*! - * Writes \a this mesh into a MED file specified by its name. - * \param [in] fileName - the MED file name. - * \param [in] mode - the writing mode. For more on \a mode, see \ref AdvMEDLoaderBasics. - * - 2 - erase; an existing file is removed. - * - 1 - append; same data should not be present in an existing file. - * - 0 - overwrite; same data present in an existing file is overwritten. - * \throw If the mesh name is not set. - * \throw If \a mode == 1 and the same data is present in an existing file. - */ -void MEDFileMesh::write(const std::string& fileName, int mode) const -{ - med_access_mode medmod=MEDFileUtilities::TraduceWriteMode(mode); - MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName.c_str(),medmod); - std::ostringstream oss; oss << "MEDFileMesh : error on attempt to write in file : \"" << fileName << "\""; - MEDFileUtilities::CheckMEDCode(fid,fid,oss.str()); - write(fid); -} - -/*! - * Checks if \a this and another mesh are equal. - * \param [in] other - the mesh to compare with. - * \param [in] eps - a precision used to compare real values. - * \param [in,out] what - the string returning description of unequal data. - * \return bool - \c true if the meshes are equal, \c false, else. - */ -bool MEDFileMesh::isEqual(const MEDFileMesh *other, double eps, std::string& what) const -{ - if(_order!=other->_order) - { - what="Orders differ !"; - return false; - } - if(_iteration!=other->_iteration) - { - what="Iterations differ !"; - return false; - } - if(fabs(_time-other->_time)>eps) - { - what="Time values differ !"; - return false; - } - if(_dt_unit!=other->_dt_unit) - { - what="Time units differ !"; - return false; - } - if(_name!=other->_name) - { - what="Names differ !"; - return false; - } - //univ_name has been ignored -> not a bug because it is a mutable attribute - if(_desc_name!=other->_desc_name) - { - what="Description names differ !"; - return false; - } - if(!areGrpsEqual(other,what)) - return false; - if(!areFamsEqual(other,what)) - return false; - return true; -} - -void MEDFileMesh::setName(const std::string& name) -{ - _name=name; -} - -/*! - * Clears redundant attributes of incorporated data arrays. - */ -void MEDFileMesh::clearNonDiscrAttributes() const -{ - -} - -bool MEDFileMesh::changeNames(const std::vector< std::pair >& modifTab) -{ - for(std::vector< std::pair >::const_iterator it=modifTab.begin();it!=modifTab.end();it++) - { - if((*it).first==_name) - { - _name=(*it).second; - return true; - } - } - return false; -} - -/*! - * Copies data on groups and families from another mesh. - * \param [in] other - the mesh to copy the data from. - */ -void MEDFileMesh::copyFamGrpMapsFrom(const MEDFileMesh& other) -{ - _groups=other._groups; - _families=other._families; -} - - -/*! - * This method clear all the groups in the map. - * So this method does not operate at all on arrays. - * So this method can lead to orphan families. - * - * \sa MEDFileMesh::clearFamMap, MEDFileMesh::clearFamGrpMaps - */ -void MEDFileMesh::clearGrpMap() -{ - _groups.clear(); -} - -/*! - * This method clear all the families in the map. - * So this method does not operate at all on arrays. - * WARNING ! if there are some groups lying on cleared families, those groups will be impacted ! - * - * \sa MEDFileMesh::clearFamMap, MEDFileMesh::clearFamGrpMaps - */ -void MEDFileMesh::clearFamMap() -{ - _families.clear(); -} - -/*! - * This method clear all the families and groups in the map. - * So this method does not operate at all on arrays. - * As all groups and families entry will be removed after - * the call of MEDFileMesh::setFamilyFieldArr method with 0 or None (python) in the 2nd parameter can be useful to reduce the size of the object. - * - * \sa MEDFileMesh::clearFamMap, MEDFileMesh::clearFamMap - */ -void MEDFileMesh::clearFamGrpMaps() -{ - clearGrpMap(); - clearFamMap(); -} - -/*! - * Returns names of families constituting a group. - * \param [in] name - the name of the group of interest. - * \return std::vector - a sequence of names of the families. - * \throw If the name of a nonexistent group is specified. - */ -std::vector MEDFileMesh::getFamiliesOnGroup(const std::string& name) const -{ - std::string oname(name); - std::map >::const_iterator it=_groups.find(oname); - if(it==_groups.end()) - { - std::vector grps=getGroupsNames(); - std::ostringstream oss; oss << "No such groupname \"" << name << "\" !\nAvailable groups are :"; - std::copy(grps.begin(),grps.end(),std::ostream_iterator(oss," ")); - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - return (*it).second; -} - -/*! - * Returns names of families constituting some groups. - * \param [in] grps - a sequence of names of groups of interest. - * \return std::vector - a sequence of names of the families. - * \throw If a name of a nonexistent group is present in \a grps. - */ -std::vector MEDFileMesh::getFamiliesOnGroups(const std::vector& grps) const -{ - std::set fams; - for(std::vector::const_iterator it=grps.begin();it!=grps.end();it++) - { - std::map >::const_iterator it2=_groups.find(*it); - if(it2==_groups.end()) - { - std::ostringstream oss; oss << "No such group in mesh \"" << _name << "\" : " << *it; - std::vector grps2=getGroupsNames(); oss << "\" !\nAvailable groups are :"; - std::copy(grps2.begin(),grps2.end(),std::ostream_iterator(oss," ")); - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - fams.insert((*it2).second.begin(),(*it2).second.end()); - } - std::vector fams2(fams.begin(),fams.end()); - return fams2; -} - -/*! - * Returns ids of families constituting a group. - * \param [in] name - the name of the group of interest. - * \return std::vector - sequence of ids of the families. - * \throw If the name of a nonexistent group is specified. - */ -std::vector MEDFileMesh::getFamiliesIdsOnGroup(const std::string& name) const -{ - std::string oname(name); - std::map >::const_iterator it=_groups.find(oname); - std::vector grps=getGroupsNames(); - if(it==_groups.end()) - { - std::ostringstream oss; oss << "No such groupname \"" << name << "\" !\nAvailable groups are :"; - std::copy(grps.begin(),grps.end(),std::ostream_iterator(oss," ")); - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - return getFamiliesIds((*it).second); -} - -/*! - * Sets names of families constituting a group. If data on families of this group is - * already present, it is overwritten. Every family in \a fams is checked, and if a - family is not yet in \a this mesh, the default group id \c 0 is assigned to it. - * \param [in] name - the name of the group of interest. - * \param [in] fams - a sequence of names of families constituting the group. - */ -void MEDFileMesh::setFamiliesOnGroup(const std::string& name, const std::vector& fams) -{ - std::string oname(name); - _groups[oname]=fams; - for(std::vector::const_iterator it1=fams.begin();it1!=fams.end();it1++) - { - std::map::iterator it2=_families.find(*it1); - if(it2==_families.end()) - _families[*it1]=0; - } -} - -/*! - * Sets families constituting a group. The families are specified by their ids. - * If a family name is not found by its id, an exception is thrown. - * If several families have same id, the first one in lexical order is taken. - * \param [in] name - the name of the group of interest. - * \param [in] famIds - a sequence of ids of families constituting the group. - * \throw If a family name is not found by its id. - */ -void MEDFileMesh::setFamiliesIdsOnGroup(const std::string& name, const std::vector& famIds) -{ - std::string oname(name); - std::vector fams(famIds.size()); - int i=0; - for(std::vector::const_iterator it1=famIds.begin();it1!=famIds.end();it1++,i++) - { - std::string name2=getFamilyNameGivenId(*it1); - fams[i]=name2; - } - _groups[oname]=fams; -} - -/*! - * Returns names of groups including a given family. - * \param [in] name - the name of the family of interest. - * \return std::vector - a sequence of names of groups including the family. - */ -std::vector MEDFileMesh::getGroupsOnFamily(const std::string& name) const -{ - std::vector ret; - for(std::map >::const_iterator it1=_groups.begin();it1!=_groups.end();it1++) - { - for(std::vector::const_iterator it2=(*it1).second.begin();it2!=(*it1).second.end();it2++) - if((*it2)==name) - { - ret.push_back((*it1).first); - break; - } - } - return ret; -} - -/*! - * Adds an existing family to groups. - * \param [in] famName - a name of family to add to \a grps. - * \param [in] grps - a sequence of group names to add the family in. - * \throw If a family named \a famName not yet exists. - */ -void MEDFileMesh::setGroupsOnFamily(const std::string& famName, const std::vector& grps) -{ - std::string fName(famName); - const std::map::const_iterator it=_families.find(fName); - if(it==_families.end()) - { - std::vector fams=getFamiliesNames(); - std::ostringstream oss; oss << "No such familyname \"" << fName << "\" !\nAvailable families are :"; - std::copy(fams.begin(),fams.end(),std::ostream_iterator(oss," ")); - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - for(std::vector::const_iterator it3=grps.begin();it3!=grps.end();it3++) - { - std::map< std::string, std::vector >::iterator it2=_groups.find(*it3); - if(it2!=_groups.end()) - (*it2).second.push_back(fName); - else - { - std::vector grps2(1,fName); - _groups[*it3]=grps2; - } - } -} - -/*! - * Returns names of all groups of \a this mesh. - * \return std::vector - a sequence of group names. - */ -std::vector MEDFileMesh::getGroupsNames() const -{ - std::vector ret(_groups.size()); - int i=0; - for(std::map >::const_iterator it=_groups.begin();it!=_groups.end();it++,i++) - ret[i]=(*it).first; - return ret; -} - -/*! - * Returns names of all families of \a this mesh. - * \return std::vector - a sequence of family names. - */ -std::vector MEDFileMesh::getFamiliesNames() const -{ - std::vector ret(_families.size()); - int i=0; - for(std::map::const_iterator it=_families.begin();it!=_families.end();it++,i++) - ret[i]=(*it).first; - return ret; -} - -/*! - * Changes a name of every family, included in one group only, to be same as the group name. - * \throw If there are families with equal names in \a this mesh. - */ -void MEDFileMesh::assignFamilyNameWithGroupName() -{ - std::map > groups(_groups); - std::map newFams; - for(std::map::const_iterator it=_families.begin();it!=_families.end();it++) - { - std::vector grps=getGroupsOnFamily((*it).first); - if(grps.size()==1 && groups[grps[0]].size()==1) - { - if(newFams.find(grps[0])!=newFams.end()) - { - std::ostringstream oss; oss << "MEDFileMesh::assignFamilyNameWithGroupName : Family \"" << grps[0] << "\" already exists !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - newFams[grps[0]]=(*it).second; - std::vector& grps2=groups[grps[0]]; - std::size_t pos=std::distance(grps2.begin(),std::find(grps2.begin(),grps2.end(),(*it).first)); - grps2[pos]=grps[0]; - } - else - { - if(newFams.find((*it).first)!=newFams.end()) - { - std::ostringstream oss; oss << "MEDFileMesh::assignFamilyNameWithGroupName : Family \"" << (*it).first << "\" already exists !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - newFams[(*it).first]=(*it).second; - } - } - _families=newFams; - _groups=groups; -} - -/*! - * Removes all groups lying on no family. If there is no empty groups, \a this is let untouched. - * - * \return the removed groups. - */ -std::vector MEDFileMesh::removeEmptyGroups() -{ - std::vector ret; - std::map > newGrps; - for(std::map >::const_iterator it=_groups.begin();it!=_groups.end();it++) - { - if((*it).second.empty()) - ret.push_back((*it).first); - else - newGrps[(*it).first]=(*it).second; - } - if(!ret.empty()) - _groups=newGrps; - return ret; -} - -/*! - * Removes a group from \a this mesh. - * \param [in] name - the name of the group to remove. - * \throw If no group with such a \a name exists. - */ -void MEDFileMesh::removeGroup(const std::string& name) -{ - std::string oname(name); - std::map >::iterator it=_groups.find(oname); - std::vector grps=getGroupsNames(); - if(it==_groups.end()) - { - std::ostringstream oss; oss << "No such groupname \"" << name << "\" !\nAvailable groups are :"; - std::copy(grps.begin(),grps.end(),std::ostream_iterator(oss," ")); - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - _groups.erase(it); -} - -/*! - * Removes a family from \a this mesh. - * \param [in] name - the name of the family to remove. - * \throw If no family with such a \a name exists. - */ -void MEDFileMesh::removeFamily(const std::string& name) -{ - std::string oname(name); - std::map::iterator it=_families.find(oname); - std::vector fams=getFamiliesNames(); - if(it==_families.end()) - { - std::ostringstream oss; oss << "No such familyname \"" << name << "\" !\nAvailable families are :"; - std::copy(fams.begin(),fams.end(),std::ostream_iterator(oss," ")); - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - _families.erase(it); - for(std::map >::iterator it3=_groups.begin();it3!=_groups.end();it3++) - { - std::vector& v=(*it3).second; - std::vector::iterator it4=std::find(v.begin(),v.end(),oname); - if(it4!=v.end()) - v.erase(it4); - } -} - -/*! - * Removes all groups in \a this that are orphan. A group is orphan if this group lies on - * a set of families, themselves orphan. A family is said orphan if its id appears nowhere in - * family field whatever its level. This method also suppresses the orphan families. - * - * \return - The list of removed groups names. - * - * \sa MEDFileMesh::removeOrphanFamilies. - */ -std::vector MEDFileMesh::removeOrphanGroups() -{ - removeOrphanFamilies(); - return removeEmptyGroups(); -} - -/*! - * Removes all families in \a this that are orphan. A family is said orphan if its id appears nowhere in - * family field whatever its level. Groups are updated in consequence, that is to say all groups lying on orphan family, will see their families list modified. - * - * \return - The list of removed families names. - * \sa MEDFileMesh::removeOrphanGroups. - */ -std::vector MEDFileMesh::removeOrphanFamilies() -{ - MEDCouplingAutoRefCountObjectPtr allFamIdsInUse=computeAllFamilyIdsInUse(); - std::vector ret; - if(!((DataArrayInt*)allFamIdsInUse)) - { - ret=getFamiliesNames(); - _families.clear(); _groups.clear(); - return ret; - } - std::map famMap; - std::map > grps(_groups); - for(std::map::const_iterator it=_families.begin();it!=_families.end();it++) - { - if(allFamIdsInUse->presenceOfValue((*it).second)) - famMap[(*it).first]=(*it).second; - else - { - ret.push_back((*it).first); - std::vector grpsOnEraseFam=getGroupsOnFamily((*it).first); - for(std::vector::const_iterator it2=grpsOnEraseFam.begin();it2!=grpsOnEraseFam.end();it2++) - { - std::map >::iterator it3=grps.find(*it2);//it3!=grps.empty() thanks to copy - std::vector& famv=(*it3).second; - std::vector::iterator it4=std::find(famv.begin(),famv.end(),(*it).first);//it4!=famv.end() thanks to copy - famv.erase(it4); - } - } - } - if(!ret.empty()) - { _families=famMap; _groups=grps; } - return ret; -} - -/*! - * This method operates only on maps in \a this. The arrays are not considered here. So this method will remove a family (except "FAMILLE_ZERO" family) if no group lies on it whatever - * this family is orphan or not. - * - * \warning this method is different from removeOrphanFamilies that scans family field array to find orphan families. - */ -void MEDFileMesh::removeFamiliesReferedByNoGroups() -{ - std::map fams; - std::set sfams; - for(std::map::const_iterator it=_families.begin();it!=_families.end();it++) - sfams.insert((*it).first); - for(std::map >::const_iterator it0=_groups.begin();it0!=_groups.end();it0++) - for(std::vector::const_iterator it1=(*it0).second.begin();it1!=(*it0).second.end();it1++) - sfams.erase(*it1); - for(std::set::const_iterator it=sfams.begin();it!=sfams.end();it++) - if(*it!=DFT_FAM_NAME) - _families.erase(*it); -} - -/*! - * This method has no impact on groups. This method only works on families. This method firstly removes families not refered by any groups in \a this, then all unused entities - * are put as belonging to family 0 ("FAMILLE_ZERO"). Finally, all orphanFamilies are killed. - * This method raises an exception if "FAMILLE_ZERO" is already belonging to a group. - * - * \sa MEDFileMesh::removeOrphanFamilies - */ -void MEDFileMesh::rearrangeFamilies() -{ - checkOrphanFamilyZero(); - removeFamiliesReferedByNoGroups(); - // - std::vector levels(getNonEmptyLevelsExt()); - std::set idsRefed; - for(std::map::const_iterator it=_families.begin();it!=_families.end();it++) - idsRefed.insert((*it).second); - for(std::vector::const_iterator it=levels.begin();it!=levels.end();it++) - { - const DataArrayInt *fams(0); - try - { - fams=getFamilyFieldAtLevel(*it); - } - catch(INTERP_KERNEL::Exception& e) { } - if(!fams) - continue; - std::vector v(fams->getNumberOfTuples(),false); - for(std::set::const_iterator pt=idsRefed.begin();pt!=idsRefed.end();pt++) - fams->switchOnTupleEqualTo(*pt,v); - MEDCouplingAutoRefCountObjectPtr unfetchedIds(DataArrayInt::BuildListOfSwitchedOff(v)); - if(!unfetchedIds->empty()) - { - MEDCouplingAutoRefCountObjectPtr newFams(fams->deepCpy()); - newFams->setPartOfValuesSimple3(0,unfetchedIds->begin(),unfetchedIds->end(),0,1,1); - setFamilyFieldArr(*it,newFams); - } - } - removeOrphanFamilies(); -} - -/*! - * This method only checks that "FAMILLE_ZERO" is orphan (not belonging to a group). - */ -void MEDFileMesh::checkOrphanFamilyZero() const -{ - for(std::map >::const_iterator it=_groups.begin();it!=_groups.end();it++) - { - if(std::find((*it).second.begin(),(*it).second.end(),DFT_FAM_NAME)!=(*it).second.end()) - { - std::ostringstream oss; oss << "MEDFileMesh::rearrangeFamilies : Groups \"" << (*it).first << "\" is lying on family \"" << DFT_FAM_NAME << "\" !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - } -} - -/*! - * Renames a group in \a this mesh. - * \param [in] oldName - a current name of the group to rename. - * \param [in] newName - a new group name. - * \throw If no group named \a oldName exists in \a this mesh. - * \throw If a group named \a newName already exists. - */ -void MEDFileMesh::changeGroupName(const std::string& oldName, const std::string& newName) -{ - std::string oname(oldName); - std::map >::iterator it=_groups.find(oname); - std::vector grps=getGroupsNames(); - if(it==_groups.end()) - { - std::ostringstream oss; oss << "No such groupname \"" << oldName << "\" !\nAvailable groups are :"; - std::copy(grps.begin(),grps.end(),std::ostream_iterator(oss," ")); - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - std::string nname(newName); - std::map >::iterator it2=_groups.find(nname); - if(it2!=_groups.end()) - { - std::ostringstream oss; oss << "Such groupname \"" << newName << "\" already exists ! Kill it before !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - std::vector cpy=(*it).second; - _groups.erase(it); - _groups[newName]=cpy; -} - -/*! - * Changes an id of a family in \a this mesh. - * This method calls changeFamilyIdArr(). - * \param [in] oldId - a current id of the family. - * \param [in] newId - a new family id. - */ -void MEDFileMesh::changeFamilyId(int oldId, int newId) -{ - changeFamilyIdArr(oldId,newId); - std::map fam2; - for(std::map::const_iterator it=_families.begin();it!=_families.end();it++) - { - if((*it).second==oldId) - fam2[(*it).first]=newId; - else - fam2[(*it).first]=(*it).second; - } - _families=fam2; -} - -/*! - * Renames a family in \a this mesh. - * \param [in] oldName - a current name of the family to rename. - * \param [in] newName - a new family name. - * \throw If no family named \a oldName exists in \a this mesh. - * \throw If a family named \a newName already exists. - */ -void MEDFileMesh::changeFamilyName(const std::string& oldName, const std::string& newName) -{ - std::string oname(oldName); - std::map::iterator it=_families.find(oname); - std::vector fams=getFamiliesNames(); - if(it==_families.end()) - { - std::ostringstream oss; oss << "No such familyname \"" << oldName << "\" !\nAvailable families are :"; - std::copy(fams.begin(),fams.end(),std::ostream_iterator(oss," ")); - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - std::string nname(newName); - std::map::iterator it2=_families.find(nname); - if(it2!=_families.end()) - { - std::ostringstream oss; oss << "Such familyname \"" << newName << " already exists ! Kill it before !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - int cpy=(*it).second; - _families.erase(it); - _families[newName]=cpy; - for(std::map >::iterator it3=_groups.begin();it3!=_groups.end();it3++) - { - std::vector& v=(*it3).second; - std::vector::iterator it4=std::find(v.begin(),v.end(),oname); - if(it4!=v.end()) - (*it4)=nname; - } -} - -/*! - * Checks if \a this and another mesh contains the same families. - * \param [in] other - the mesh to compare with \a this one. - * \param [in,out] what - an unused parameter. - * \return bool - \c true if number of families and their ids are the same in the two - * meshes. Families with the id == \c 0 are not considered. - */ -bool MEDFileMesh::areFamsEqual(const MEDFileMesh *other, std::string& what) const -{ - if(_families==other->_families) - return true; - std::map fam0; - std::map fam1; - for(std::map::const_iterator it=_families.begin();it!=_families.end();it++) - if((*it).second!=0) - fam0[(*it).first]=(*it).second; - for(std::map::const_iterator it=other->_families.begin();it!=other->_families.end();it++) - if((*it).second!=0) - fam1[(*it).first]=(*it).second; - return fam0==fam1; -} - -/*! - * Checks if \a this and another mesh contains the same groups. - * \param [in] other - the mesh to compare with \a this one. - * \param [in,out] what - a string describing a difference of groups of the two meshes - * in case if this method returns \c false. - * \return bool - \c true if number of groups and families constituting them are the - * same in the two meshes. - */ -bool MEDFileMesh::areGrpsEqual(const MEDFileMesh *other, std::string& what) const -{ - if(_groups==other->_groups) - return true; - bool ret=true; - std::size_t sz=_groups.size(); - if(sz!=other->_groups.size()) - { - what="Groups differ because not same number !\n"; - ret=false; - } - if(ret) - { - std::map >::const_iterator it1=_groups.begin(); - for(std::size_t i=0;i >::const_iterator it2=other->_groups.find((*it1).first); - if(it2!=other->_groups.end()) - { - std::set s1((*it1).second.begin(),(*it1).second.end()); - std::set s2((*it2).second.begin(),(*it2).second.end()); - ret=(s1==s2); - } - else - { - ret=false; - what="A group in first mesh exists not in other !\n"; - } - } - } - if(!ret) - { - std::ostringstream oss; oss << "Groups description differs :\n"; - oss << "First group description :\n"; - for(std::map >::const_iterator it=_groups.begin();it!=_groups.end();it++) - { - oss << " Group \"" << (*it).first << "\" on following families :\n"; - for(std::vector::const_iterator it2=(*it).second.begin();it2!=(*it).second.end();it2++) - oss << " \"" << *it2 << "\n"; - } - oss << "Second group description :\n"; - for(std::map >::const_iterator it=other->_groups.begin();it!=other->_groups.end();it++) - { - oss << " Group \"" << (*it).first << "\" on following families :\n"; - for(std::vector::const_iterator it2=(*it).second.begin();it2!=(*it).second.end();it2++) - oss << " \"" << *it2 << "\n"; - } - what+=oss.str(); - } - return ret; -} - -/*! - * Checks if a group with a given name exists in \a this mesh. - * \param [in] groupName - the group name. - * \return bool - \c true the group \a groupName exists in \a this mesh. - */ -bool MEDFileMesh::existsGroup(const std::string& groupName) const -{ - std::string grpName(groupName); - return _groups.find(grpName)!=_groups.end(); -} - -/*! - * Checks if a family with a given id exists in \a this mesh. - * \param [in] famId - the family id. - * \return bool - \c true the family with the id \a famId exists in \a this mesh. - */ -bool MEDFileMesh::existsFamily(int famId) const -{ - for(std::map::const_iterator it2=_families.begin();it2!=_families.end();it2++) - if((*it2).second==famId) - return true; - return false; -} - -/*! - * Checks if a family with a given name exists in \a this mesh. - * \param [in] familyName - the family name. - * \return bool - \c true the family \a familyName exists in \a this mesh. - */ -bool MEDFileMesh::existsFamily(const std::string& familyName) const -{ - std::string fname(familyName); - return _families.find(fname)!=_families.end(); -} - -/*! - * Sets an id of a family. - * \param [in] familyName - the family name. - * \param [in] id - a new id of the family. - */ -void MEDFileMesh::setFamilyId(const std::string& familyName, int id) -{ - std::string fname(familyName); - _families[fname]=id; -} - -void MEDFileMesh::setFamilyIdUnique(const std::string& familyName, int id) -{ - std::string fname(familyName); - for(std::map::const_iterator it=_families.begin();it!=_families.end();it++) - if((*it).second==id) - { - if((*it).first!=familyName) - { - std::ostringstream oss; oss << "MEDFileMesh::setFamilyIdUnique : Family id #" << id << " is already belonging to family with name \"" << (*it).first << "\" !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - } - _families[fname]=id; -} - -/*! - * Adds a family to \a this mesh. - * \param [in] familyName - a name of the family. - * \param [in] famId - an id of the family. - * \throw If a family with the same name or id already exists in \a this mesh. - */ -void MEDFileMesh::addFamily(const std::string& familyName, int famId) -{ - std::string fname(familyName); - std::map::const_iterator it=_families.find(fname); - if(it==_families.end()) - { - for(std::map::const_iterator it2=_families.begin();it2!=_families.end();it2++) - if((*it2).second==famId) - { - std::ostringstream oss; - oss << "MEDFileMesh::addFamily : Family \"" << (*it2).first << "\" already exists with specified id : " << famId << " !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - _families[fname]=famId; - } - else - { - if((*it).second!=famId) - { - std::ostringstream oss; - oss << "MEDFileMesh::addFamily : Family \"" << fname << "\" already exists but has id set to " << (*it).second << " different from asked famId " << famId << " !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - } -} - -/*! - * Creates a group including all mesh entities of given dimension. - * \warning This method does \b not guarantee that the created group includes mesh - * entities of only \a meshDimRelToMaxExt dimension in the case if some family id is - * present in family fields of different dimensions. To assure this, call - * ensureDifferentFamIdsPerLevel() \b before calling this method. - * \param [in] meshDimRelToMaxExt - a relative dimension of mesh entities to include to - * the group. - * \param [in] groupName - a name of the new group. - * \throw If a group named \a groupName already exists. - * \throw If no mesh entities of dimension \a meshDimRelToMaxExt exist in \a this mesh. - * \throw If no family field of dimension \a meshDimRelToMaxExt is present in \a this mesh. - */ -void MEDFileMesh::createGroupOnAll(int meshDimRelToMaxExt, const std::string& groupName) -{ - std::string grpName(groupName); - std::vector levs=getNonEmptyLevelsExt(); - if(std::find(levs.begin(),levs.end(),meshDimRelToMaxExt)==levs.end()) - { - std::ostringstream oss; oss << "MEDFileMesh::createGroupOnAll : The relative ext dimension " << meshDimRelToMaxExt << " is not available !" << std::endl; - oss << "Available relative ext levels are : "; - std::copy(levs.begin(),levs.end(),std::ostream_iterator(oss," ")); - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - if(existsGroup(groupName)) - { - std::ostringstream oss; oss << "MEDFileMesh::createGroupOnAll : The groups \"" << grpName << "\" already exists in this !" << std::endl; - oss << "Already existing groups are : "; - std::copy(levs.begin(),levs.end(),std::ostream_iterator(oss," ")); - oss << std::endl << "Please choose an another group name or call removeGroup(\"" << grpName << "\") method !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - const DataArrayInt *fieldFamIds=getFamilyFieldAtLevel(meshDimRelToMaxExt); - if(fieldFamIds==0) - throw INTERP_KERNEL::Exception("MEDFileMesh::createGroupOnAll : Family field arr ids is not defined for this level !"); - MEDCouplingAutoRefCountObjectPtr famIds=fieldFamIds->getDifferentValues(); - std::vector familiesOnWholeGroup; - for(const int *it=famIds->begin();it!=famIds->end();it++) - { - bool tmp; - familiesOnWholeGroup.push_back(findOrCreateAndGiveFamilyWithId(*it,tmp)); - } - _groups[grpName]=familiesOnWholeGroup; -} - -/*! - * Ensures that given family ids do not present in family fields of dimensions different - * than given ones. If a family id is present in the family fields of dimensions different - * than the given ones, a new family is created and the whole data is updated accordingly. - * \param [in] famIds - a sequence of family ids to check. - * \param [in] vMeshDimRelToMaxExt - a sequence of relative dimensions to which the \a - * famIds should exclusively belong. - * \return bool - \c true if no modification is done in \a this mesh by this method. - */ -bool MEDFileMesh::keepFamIdsOnlyOnLevs(const std::vector& famIds, const std::vector& vMeshDimRelToMaxExt) -{ - std::set levsInput(vMeshDimRelToMaxExt.begin(),vMeshDimRelToMaxExt.end()); - std::vector levs=getNonEmptyLevelsExt(); - std::set levs2(levs.begin(),levs.end()); - std::vector levsToTest; - std::set_difference(levs2.begin(),levs2.end(),levsInput.begin(),levsInput.end(),std::back_insert_iterator< std::vector >(levsToTest)); - std::set famIds2(famIds.begin(),famIds.end()); - bool ret=true; - int maxFamId=1; - if(!_families.empty()) - maxFamId=getMaxFamilyId()+1; - std::vector allFams=getFamiliesNames(); - for(std::vector::const_iterator it=levsToTest.begin();it!=levsToTest.end();it++) - { - const DataArrayInt *fieldFamIds=getFamilyFieldAtLevel(*it); - if(fieldFamIds) - { - MEDCouplingAutoRefCountObjectPtr famIds3=fieldFamIds->getDifferentValues(); - std::vector tmp; - std::set_intersection(famIds3->begin(),famIds3->end(),famIds2.begin(),famIds2.end(),std::back_insert_iterator< std::vector >(tmp)); - for(std::vector::const_iterator it2=tmp.begin();it2!=tmp.end();it2++) - { - ret=false; - std::string famName=getFamilyNameGivenId(*it2); - std::ostringstream oss; oss << "Family_" << maxFamId; - std::string zeName=CreateNameNotIn(oss.str(),allFams); - addFamilyOnAllGroupsHaving(famName,zeName); - _families[zeName]=maxFamId; - (const_cast(fieldFamIds))->changeValue(*it2,maxFamId); - maxFamId++; - } - } - } - return ret; -} - -/*! - * Adds a family to a given group in \a this mesh. If the group with a given name does - * not exist, it is created. - * \param [in] grpName - the name of the group to add the family in. - * \param [in] famName - the name of the family to add to the group named \a grpName. - * \throw If \a grpName or \a famName is an empty string. - * \throw If no family named \a famName is present in \a this mesh. - */ -void MEDFileMesh::addFamilyOnGrp(const std::string& grpName, const std::string& famName) -{ - std::string grpn(grpName); - std::string famn(famName); - if(grpn.empty() || famn.empty()) - throw INTERP_KERNEL::Exception("MEDFileMesh::addFamilyOnGrp : input strings must be non null !"); - std::vector fams=getFamiliesNames(); - if(std::find(fams.begin(),fams.end(),famn)==fams.end()) - { - std::ostringstream oss; oss << "MEDFileMesh::addFamilyOnGrp : Family \"" << famn << "\" does not exist !" << std::endl; - oss << "Create this family or choose an existing one ! Existing fams are : "; - std::copy(fams.begin(),fams.end(),std::ostream_iterator(oss," ")); oss << "."; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - std::map >::iterator it=_groups.find(grpn); - if(it==_groups.end()) - { - _groups[grpn].push_back(famn); - } - else - { - std::vector::iterator it2=std::find((*it).second.begin(),(*it).second.end(),famn); - if(it2==(*it).second.end()) - (*it).second.push_back(famn); - } -} - -/*! - * This method adds to all groups lying on family with name 'famName' the other family name 'otherFamName'. - * This method is quite underground because it can lead to unconsistency because family 'otherFamName' is \b not added into _families. - * This method is used by MEDFileMesh::keepFamIdsOnlyOnLevs method. - */ -void MEDFileMesh::addFamilyOnAllGroupsHaving(const std::string& famName, const std::string& otherFamName) -{ - std::string famNameCpp(famName); - std::string otherCpp(otherFamName); - for(std::map >::iterator it=_groups.begin();it!=_groups.end();it++) - { - std::vector& v=(*it).second; - if(std::find(v.begin(),v.end(),famNameCpp)!=v.end()) - { - v.push_back(otherCpp); - } - } -} - -/*! - * \param [in] ids ids and group name of the new group to add. The ids should be sorted and different each other (MED file norm). - * \parma [in,out] famArr family array on level of interest to be renumbered. The input pointer should be not \c NULL (no check of that will be performed) - */ -void MEDFileMesh::addGroupUnderground(bool isNodeGroup, const DataArrayInt *ids, DataArrayInt *famArr) -{ - if(!ids) - throw INTERP_KERNEL::Exception("MEDFileUMesh::addGroup : NULL pointer in input !"); - std::string grpName(ids->getName()); - if(grpName.empty()) - throw INTERP_KERNEL::Exception("MEDFileUMesh::addGroup : empty group name ! MED file format do not accept empty group name !"); - ids->checkStrictlyMonotonic(true); - famArr->incrRef(); MEDCouplingAutoRefCountObjectPtr famArrTmp(famArr); - std::vector grpsNames=getGroupsNames(); - if(std::find(grpsNames.begin(),grpsNames.end(),grpName)!=grpsNames.end()) - { - std::ostringstream oss; oss << "MEDFileUMesh::addGroup : Group with name \"" << grpName << "\" already exists ! Destroy it before calling this method !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - std::list< MEDCouplingAutoRefCountObjectPtr > allFamIds(getAllNonNullFamilyIds()); - allFamIds.erase(std::find(allFamIds.begin(),allFamIds.end(),famArrTmp)); - MEDCouplingAutoRefCountObjectPtr famIds=famArr->selectByTupleIdSafe(ids->begin(),ids->end()); - MEDCouplingAutoRefCountObjectPtr diffFamIds=famIds->getDifferentValues(); - std::vector familyIds; - std::vector< MEDCouplingAutoRefCountObjectPtr > idsPerfamiliyIds; - int maxVal=getTheMaxAbsFamilyId()+1; - std::map families(_families); - std::map > groups(_groups); - std::vector fams; - bool created(false); - for(const int *famId=diffFamIds->begin();famId!=diffFamIds->end();famId++) - { - MEDCouplingAutoRefCountObjectPtr ids2Tmp=famIds->getIdsEqual(*famId); - MEDCouplingAutoRefCountObjectPtr ids2=ids->selectByTupleId(ids2Tmp->begin(),ids2Tmp->end()); - MEDCouplingAutoRefCountObjectPtr ids1=famArr->getIdsEqual(*famId); - MEDCouplingAutoRefCountObjectPtr ret0(ids1->buildSubstractionOptimized(ids2)); - if(ret0->empty()) - { - bool isFamPresent=false; - for(std::list< MEDCouplingAutoRefCountObjectPtr >::const_iterator itl=allFamIds.begin();itl!=allFamIds.end() && !isFamPresent;itl++) - isFamPresent=(*itl)->presenceOfValue(*famId); - if(!isFamPresent) - { familyIds.push_back(*famId); idsPerfamiliyIds.push_back(ret0); fams.push_back(FindOrCreateAndGiveFamilyWithId(families,*famId,created)); } // adding *famId in grp - else - { - familyIds.push_back(isNodeGroup?maxVal:-maxVal); idsPerfamiliyIds.push_back(ids2); - std::string locFamName=FindOrCreateAndGiveFamilyWithId(families,isNodeGroup?maxVal:-maxVal,created); - fams.push_back(locFamName); - if(existsFamily(*famId)) - { - std::string locFamName2=getFamilyNameGivenId(*famId); std::vector v(2); v[0]=locFamName2; v[1]=locFamName; - ChangeAllGroupsContainingFamily(groups,getFamilyNameGivenId(*famId),v); - } - maxVal++; - } // modifying all other groups on *famId to lie on maxVal and lie the grp on maxVal - } - else - { - familyIds.push_back(isNodeGroup?maxVal:-maxVal); idsPerfamiliyIds.push_back(ret0); // modifying all other groups on *famId to lie on maxVal and on maxVal+1 - familyIds.push_back(isNodeGroup?maxVal+1:-maxVal-1); idsPerfamiliyIds.push_back(ids2);//grp lie only on maxVal+1 - std::string n2(FindOrCreateAndGiveFamilyWithId(families,isNodeGroup?maxVal+1:-maxVal-1,created)); fams.push_back(n2); - if(existsFamily(*famId)) - { - std::string n1(FindOrCreateAndGiveFamilyWithId(families,isNodeGroup?maxVal:-maxVal,created)); std::vector v(2); v[0]=n1; v[1]=n2; - ChangeAllGroupsContainingFamily(groups,getFamilyNameGivenId(*famId),v); - } - maxVal+=2; - } - } - for(std::size_t i=0;isetPartOfValuesSimple3(familyIds[i],da->begin(),da->end(),0,1,1); - } - _families=families; - _groups=groups; - _groups[grpName]=fams; -} - -void MEDFileMesh::changeAllGroupsContainingFamily(const std::string& familyNameToChange, const std::vector& newFamiliesNames) -{ - ChangeAllGroupsContainingFamily(_groups,familyNameToChange,newFamiliesNames); -} - -void MEDFileMesh::ChangeAllGroupsContainingFamily(std::map >& groups, const std::string& familyNameToChange, const std::vector& newFamiliesNames) -{ - std::string fam(familyNameToChange); - for(std::map >::iterator it=groups.begin();it!=groups.end();it++) - { - std::vector& fams((*it).second); - std::vector::iterator it2=std::find(fams.begin(),fams.end(),fam); - if(it2!=fams.end()) - { - fams.erase(it2); - fams.insert(fams.end(),newFamiliesNames.begin(),newFamiliesNames.end()); - } - } -} - -/*! - * Returns a name of the family having a given id or, if no such a family exists, creates - * a new uniquely named family and returns its name. - * \param [in] id - the id of the family whose name is required. - * \param [out] created - returns \c true if the new family has been created, \c false, else. - * \return std::string - the name of the existing or the created family. - * \throw If it is not possible to create a unique family name. - */ -std::string MEDFileMesh::findOrCreateAndGiveFamilyWithId(int id, bool& created) -{ - return FindOrCreateAndGiveFamilyWithId(_families,id,created); -} - -/*! - * If it exists a family whose family id is equal to 'id' this method behaves as MEDFileMesh::getFamilyNameGivenId. - * In this case, 'this' internal states remains unchanged and 'created' out parameter will be set to false. - * If there is no family whose family id is equal to 'id' a family is created with a name different from those - * already existing. In this case 'created' will be returned with a value set to true, and internal state - * will be modified. - * This method will throws an exception if it is not possible to create a unique family name. - */ -std::string MEDFileMesh::FindOrCreateAndGiveFamilyWithId(std::map& families, int id, bool& created) -{ - std::vector famAlreadyExisting(families.size()); - int ii=0; - for(std::map::const_iterator it=families.begin();it!=families.end();it++,ii++) - { - if((*it).second!=id) - { - famAlreadyExisting[ii]=(*it).first; - } - else - { - created=false; - return (*it).first; - } - } - created=true; - std::ostringstream oss; oss << "Family_" << id; - std::string ret=CreateNameNotIn(oss.str(),famAlreadyExisting); - families[ret]=id; - return ret; -} - -/*! - * Sets names and ids of all families in \a this mesh. - * \param [in] info - a map of a family name to a family id. - */ -void MEDFileMesh::setFamilyInfo(const std::map& info) -{ - _families=info; -} - -/*! - * Sets names of all groups and families constituting them in \a this mesh. - * \param [in] info - a map of a group name to a vector of names of families - * constituting the group. - */ -void MEDFileMesh::setGroupInfo(const std::map >&info) -{ - _groups=info; -} - -/*! - * Returns an id of the family having a given name. - * \param [in] name - the name of the family of interest. - * \return int - the id of the family of interest. - * \throw If no family with such a \a name exists. - */ -int MEDFileMesh::getFamilyId(const std::string& name) const -{ - std::string oname(name); - std::map::const_iterator it=_families.find(oname); - std::vector fams=getFamiliesNames(); - if(it==_families.end()) - { - std::ostringstream oss; oss << "No such familyname \"" << name << "\" !\nAvailable families are :"; - std::copy(fams.begin(),fams.end(),std::ostream_iterator(oss," ")); - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - return (*it).second; -} - -/*! - * Returns ids of the families having given names. - * \param [in] fams - a sequence of the names of families of interest. - * \return std::vector - a sequence of the ids of families of interest. - * \throw If \a fams contains a name of an inexistent family. - */ -std::vector MEDFileMesh::getFamiliesIds(const std::vector& fams) const -{ - std::vector ret(fams.size()); - int i=0; - for(std::vector::const_iterator it=fams.begin();it!=fams.end();it++,i++) - { - std::map::const_iterator it2=_families.find(*it); - if(it2==_families.end()) - { - std::vector fams2=getFamiliesNames(); - std::ostringstream oss; oss << "No such familyname \"" << *it << "\" in input list !\nAvailable families are :"; - std::copy(fams2.begin(),fams2.end(),std::ostream_iterator(oss," ")); - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - ret[i]=(*it2).second; - } - return ret; -} - -/*! - * Returns a maximal abs(id) of families in \a this mesh. - * \return int - the maximal norm of family id. - * \throw If there are no families in \a this mesh. - */ -int MEDFileMesh::getMaxAbsFamilyId() const -{ - if(_families.empty()) - throw INTERP_KERNEL::Exception("MEDFileMesh::getMaxFamilyId : no families set !"); - int ret=-std::numeric_limits::max(); - for(std::map::const_iterator it=_families.begin();it!=_families.end();it++) - { - ret=std::max(std::abs((*it).second),ret); - } - return ret; -} - -/*! - * Returns a maximal id of families in \a this mesh. - * \return int - the maximal family id. - * \throw If there are no families in \a this mesh. - */ -int MEDFileMesh::getMaxFamilyId() const -{ - if(_families.empty()) - throw INTERP_KERNEL::Exception("MEDFileMesh::getMaxFamilyId : no families set !"); - int ret=-std::numeric_limits::max(); - for(std::map::const_iterator it=_families.begin();it!=_families.end();it++) - { - ret=std::max((*it).second,ret); - } - return ret; -} - -/*! - * Returns a minimal id of families in \a this mesh. - * \return int - the minimal family id. - * \throw If there are no families in \a this mesh. - */ -int MEDFileMesh::getMinFamilyId() const -{ - if(_families.empty()) - throw INTERP_KERNEL::Exception("MEDFileMesh::getMinFamilyId : no families set !"); - int ret=std::numeric_limits::max(); - for(std::map::const_iterator it=_families.begin();it!=_families.end();it++) - { - ret=std::min((*it).second,ret); - } - return ret; -} - -/*! - * Returns a maximal id of families in \a this mesh. Not only named families are - * considered but all family fields as well. - * \return int - the maximal family id. - */ -int MEDFileMesh::getTheMaxAbsFamilyId() const -{ - int m1=-std::numeric_limits::max(); - for(std::map::const_iterator it=_families.begin();it!=_families.end();it++) - m1=std::max(std::abs((*it).second),m1); - int m2=getMaxAbsFamilyIdInArrays(); - return std::max(m1,m2); -} - -/*! - * Returns a maximal id of families in \a this mesh. Not only named families are - * considered but all family fields as well. - * \return int - the maximal family id. - */ -int MEDFileMesh::getTheMaxFamilyId() const -{ - int m1=-std::numeric_limits::max(); - for(std::map::const_iterator it=_families.begin();it!=_families.end();it++) - m1=std::max((*it).second,m1); - int m2=getMaxFamilyIdInArrays(); - return std::max(m1,m2); -} - -/*! - * Returns a minimal id of families in \a this mesh. Not only named families are - * considered but all family fields as well. - * \return int - the minimal family id. - */ -int MEDFileMesh::getTheMinFamilyId() const -{ - int m1=std::numeric_limits::max(); - for(std::map::const_iterator it=_families.begin();it!=_families.end();it++) - m1=std::min((*it).second,m1); - int m2=getMinFamilyIdInArrays(); - return std::min(m1,m2); -} - -/*! - * This method only considers the maps. The contain of family array is ignored here. - * - * \sa MEDFileMesh::computeAllFamilyIdsInUse - */ -DataArrayInt *MEDFileMesh::getAllFamiliesIdsReferenced() const -{ - MEDCouplingAutoRefCountObjectPtr ret=DataArrayInt::New(); - std::set v; - for(std::map::const_iterator it=_families.begin();it!=_families.end();it++) - v.insert((*it).second); - ret->alloc((int)v.size(),1); - std::copy(v.begin(),v.end(),ret->getPointer()); - return ret.retn(); -} - -/*! - * This method does not consider map of family name, family id. Only family field array on different levels is considered. - * - * \sa MEDFileMesh::getAllFamiliesIdsReferenced - */ -DataArrayInt *MEDFileMesh::computeAllFamilyIdsInUse() const -{ - std::vector famLevs=getFamArrNonEmptyLevelsExt(); - MEDCouplingAutoRefCountObjectPtr ret; - for(std::vector::const_iterator it=famLevs.begin();it!=famLevs.end();it++) - { - const DataArrayInt *arr=getFamilyFieldAtLevel(*it);//arr not null due to spec of getFamArrNonEmptyLevelsExt - MEDCouplingAutoRefCountObjectPtr dv=arr->getDifferentValues(); - if((DataArrayInt *) ret) - ret=dv->buildUnion(ret); - else - ret=dv; - } - return ret.retn(); -} - -/*! - * true is returned if no modification has been needed. false if family - * renumbering has been needed. - */ -bool MEDFileMesh::ensureDifferentFamIdsPerLevel() -{ - std::vector levs=getNonEmptyLevelsExt(); - std::set allFamIds; - int maxId=getMaxFamilyId()+1; - std::map > famIdsToRenum; - for(std::vector::const_iterator it=levs.begin();it!=levs.end();it++) - { - const DataArrayInt *fam=getFamilyFieldAtLevel(*it); - if(fam) - { - MEDCouplingAutoRefCountObjectPtr tmp=fam->getDifferentValues(); - std::set r2; - std::set_intersection(tmp->begin(),tmp->end(),allFamIds.begin(),allFamIds.end(),std::inserter(r2,r2.end())); - if(!r2.empty()) - famIdsToRenum[*it].insert(famIdsToRenum[*it].end(),r2.begin(),r2.end()); - std::set r3; - std::set_union(tmp->begin(),tmp->end(),allFamIds.begin(),allFamIds.end(),std::inserter(r3,r3.end())); - } - } - if(famIdsToRenum.empty()) - return true; - MEDCouplingAutoRefCountObjectPtr allIds=getAllFamiliesIdsReferenced(); - for(std::map >::const_iterator it2=famIdsToRenum.begin();it2!=famIdsToRenum.end();it2++) - { - DataArrayInt *fam=const_cast(getFamilyFieldAtLevel((*it2).first)); - int *famIdsToChange=fam->getPointer(); - std::map ren; - for(std::vector::const_iterator it3=(*it2).second.begin();it3!=(*it2).second.end();it3++,maxId++) - { - if(allIds->presenceOfValue(*it3)) - { - std::string famName=getFamilyNameGivenId(*it3); - std::vector grps=getGroupsOnFamily(famName); - ren[*it3]=maxId; - bool dummy; - std::string newFam=findOrCreateAndGiveFamilyWithId(maxId,dummy); - for(std::vector::const_iterator it4=grps.begin();it4!=grps.end();it4++) - addFamilyOnGrp((*it4),newFam); - } - } - MEDCouplingAutoRefCountObjectPtr ids=fam->getIdsEqualList(&(*it2).second[0],&(*it2).second[0]+(*it2).second.size()); - for(const int *id=ids->begin();id!=ids->end();id++) - famIdsToChange[*id]=ren[famIdsToChange[*id]]; - } - return false; -} - -/*! - * This method normalizes fam id with the policy explained underneath. This policy is close to those implemented in SMESH. - * Level #0 famids > 0, Level #-1 famids < 0, Level #-2 famids=0, Level #1 famids=0 - * This policy is those used by SMESH and Trio and that is the opposite of those in MED file. - * This method will throw an exception if a same family id is detected in different level. - * \warning This policy is the opposite of those in MED file documentation ... - */ -void MEDFileMesh::normalizeFamIdsTrio() -{ - ensureDifferentFamIdsPerLevel(); - MEDCouplingAutoRefCountObjectPtr allIds=getAllFamiliesIdsReferenced(); - std::vector levs=getNonEmptyLevelsExt(); - std::set levsS(levs.begin(),levs.end()); - std::set famsFetched; - std::map families; - if(std::find(levs.begin(),levs.end(),0)!=levs.end()) - { - levsS.erase(0); - const DataArrayInt *fam=getFamilyFieldAtLevel(0); - if(fam) - { - int refId=1; - MEDCouplingAutoRefCountObjectPtr tmp=fam->getDifferentValues(); - std::map ren; - for(const int *it=tmp->begin();it!=tmp->end();it++,refId++) - ren[*it]=refId; - int nbOfTuples=fam->getNumberOfTuples(); - int *start=const_cast(fam)->getPointer(); - for(int *w=start;w!=start+nbOfTuples;w++) - *w=ren[*w]; - for(const int *it=tmp->begin();it!=tmp->end();it++) - { - if(allIds->presenceOfValue(*it)) - { - std::string famName=getFamilyNameGivenId(*it); - families[famName]=ren[*it]; - famsFetched.insert(famName); - } - } - } - } - if(std::find(levs.begin(),levs.end(),-1)!=levs.end()) - { - levsS.erase(-1); - const DataArrayInt *fam=getFamilyFieldAtLevel(-1); - if(fam) - { - int refId=-1; - MEDCouplingAutoRefCountObjectPtr tmp=fam->getDifferentValues(); - std::map ren; - for(const int *it=tmp->begin();it!=tmp->end();it++,refId--) - ren[*it]=refId; - int nbOfTuples=fam->getNumberOfTuples(); - int *start=const_cast(fam)->getPointer(); - for(int *w=start;w!=start+nbOfTuples;w++) - *w=ren[*w]; - for(const int *it=tmp->begin();it!=tmp->end();it++) - { - if(allIds->presenceOfValue(*it)) - { - std::string famName=getFamilyNameGivenId(*it); - families[famName]=ren[*it]; - famsFetched.insert(famName); - } - } - } - } - for(std::set::const_iterator it2=levsS.begin();it2!=levsS.end();it2++) - { - DataArrayInt *fam=const_cast(getFamilyFieldAtLevel(*it2)); - if(fam) - { - MEDCouplingAutoRefCountObjectPtr tmp=fam->getDifferentValues(); - fam->fillWithZero(); - for(const int *it3=tmp->begin();it3!=tmp->end();it3++) - if(allIds->presenceOfValue(*it3)) - { - std::string famName=getFamilyNameGivenId(*it3); - families[famName]=0; - famsFetched.insert(famName); - } - } - } - // - std::vector allFams=getFamiliesNames(); - std::set allFamsS(allFams.begin(),allFams.end()); - std::set unFetchedIds; - std::set_difference(allFamsS.begin(),allFamsS.end(),famsFetched.begin(),famsFetched.end(),std::inserter(unFetchedIds,unFetchedIds.end())); - for(std::set::const_iterator it4=unFetchedIds.begin();it4!=unFetchedIds.end();it4++) - families[*it4]=_families[*it4]; - _families=families; -} - -/*! - * This method normalizes fam id with the following policy. - * Level #0 famids < 0, Level #-1 famids < 0 and for Level #1 famids >= 0 - * This policy is those defined in the MED file format but is the opposite of those implemented in SMESH and Trio. - * This method will throw an exception if a same family id is detected in different level. - */ -void MEDFileMesh::normalizeFamIdsMEDFile() -{ - ensureDifferentFamIdsPerLevel(); - MEDCouplingAutoRefCountObjectPtr allIds=getAllFamiliesIdsReferenced(); - std::vector levs=getNonEmptyLevelsExt(); - std::set levsS(levs.begin(),levs.end()); - std::set famsFetched; - std::map families; - int refId=1; - if(std::find(levs.begin(),levs.end(),1)!=levs.end()) - { - levsS.erase(1); - const DataArrayInt *fam=getFamilyFieldAtLevel(1); - if(fam) - { - MEDCouplingAutoRefCountObjectPtr tmp=fam->getDifferentValues(); - std::map ren; - for(const int *it=tmp->begin();it!=tmp->end();it++,refId++) - ren[*it]=refId; - int nbOfTuples=fam->getNumberOfTuples(); - int *start=const_cast(fam)->getPointer(); - for(int *w=start;w!=start+nbOfTuples;w++) - *w=ren[*w]; - for(const int *it=tmp->begin();it!=tmp->end();it++) - { - if(allIds->presenceOfValue(*it)) - { - std::string famName=getFamilyNameGivenId(*it); - families[famName]=ren[*it]; - famsFetched.insert(famName); - } - } - } - } - refId=-1; - for(std::set::const_reverse_iterator it2=levsS.rbegin();it2!=levsS.rend();it2++) - { - const DataArrayInt *fam=getFamilyFieldAtLevel(*it2); - if(fam) - { - MEDCouplingAutoRefCountObjectPtr tmp=fam->getDifferentValues(); - std::map ren; - for(const int *it=tmp->begin();it!=tmp->end();it++,refId--) - ren[*it]=refId; - int nbOfTuples=fam->getNumberOfTuples(); - int *start=const_cast(fam)->getPointer(); - for(int *w=start;w!=start+nbOfTuples;w++) - *w=ren[*w]; - for(const int *it=tmp->begin();it!=tmp->end();it++) - { - if(allIds->presenceOfValue(*it)) - { - std::string famName=getFamilyNameGivenId(*it); - families[famName]=ren[*it]; - famsFetched.insert(famName); - } - } - } - } - // - std::vector allFams=getFamiliesNames(); - std::set allFamsS(allFams.begin(),allFams.end()); - std::set unFetchedIds; - std::set_difference(allFamsS.begin(),allFamsS.end(),famsFetched.begin(),famsFetched.end(),std::inserter(unFetchedIds,unFetchedIds.end())); - for(std::set::const_iterator it4=unFetchedIds.begin();it4!=unFetchedIds.end();it4++) - families[*it4]=_families[*it4]; - _families=families; -} - -/*! - * Returns a name of the family by its id. If there are several families having the given - * id, the name first in lexical order is returned. - * \param [in] id - the id of the family whose name is required. - * \return std::string - the name of the found family. - * \throw If no family with the given \a id exists. - */ -std::string MEDFileMesh::getFamilyNameGivenId(int id) const -{ - for(std::map::const_iterator it=_families.begin();it!=_families.end();it++) - if((*it).second==id) - return (*it).first; - std::ostringstream oss; oss << "MEDFileUMesh::getFamilyNameGivenId : no such family id : " << id; - throw INTERP_KERNEL::Exception(oss.str().c_str()); -} - -/*! - * Returns a string describing \a this mesh. This description includes the mesh name and - * the mesh description string. - * \return std::string - the mesh information string. - */ -std::string MEDFileMesh::simpleRepr() const -{ - std::ostringstream oss; - oss << "(*************************************)\n(* GENERAL INFORMATION ON THE MESH : *)\n(*************************************)\n"; - oss << "- Name of the mesh : <<" << getName() << ">>\n"; - oss << "- Description associated to the mesh : " << getDescription() << std::endl; - return oss.str(); -} - -/*! - * This method is nearly like getFamilyFieldAtLevel method. Except that if the array does not exist at the specified level \a meshDimRelToMaxExt - * an empty one is created. - */ -DataArrayInt *MEDFileMesh::getOrCreateAndGetFamilyFieldAtLevel(int meshDimRelToMaxExt) -{ - DataArrayInt *ret(getFamilyFieldAtLevel(meshDimRelToMaxExt)); - if(ret) - return ret; - MEDCouplingAutoRefCountObjectPtr arr(DataArrayInt::New()); - arr->alloc(getSizeAtLevel(meshDimRelToMaxExt),1); - arr->fillWithZero(); - setFamilyFieldArr(meshDimRelToMaxExt,arr); - return getFamilyFieldAtLevel(meshDimRelToMaxExt); -} - -/*! - * Returns ids of mesh entities contained in a given group of a given dimension. - * \param [in] meshDimRelToMaxExt - a relative dimension of the mesh entities whose ids - * are required. - * \param [in] grp - the name of the group 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 group. The caller - * is to delete this array using decrRef() as it is no more needed. - * \throw If the name of a nonexistent group is specified. - * \throw If the family field is missing for \a meshDimRelToMaxExt. - */ -DataArrayInt *MEDFileMesh::getGroupArr(int meshDimRelToMaxExt, const std::string& grp, bool renum) const -{ - std::vector tmp(1); - tmp[0]=grp; - DataArrayInt *ret=getGroupsArr(meshDimRelToMaxExt,tmp,renum); - ret->setName(grp); - return ret; -} - -/*! - * Returns ids of mesh entities contained in given groups of a given dimension. - * \param [in] meshDimRelToMaxExt - a relative dimension of the mesh entities whose ids - * are required. - * \param [in] grps - the names of the groups 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 groups. The caller - * is to delete this array using decrRef() as it is no more needed. - * \throw If the name of a nonexistent group is present in \a grps. - * \throw If the family field is missing for \a meshDimRelToMaxExt. - */ -DataArrayInt *MEDFileMesh::getGroupsArr(int meshDimRelToMaxExt, const std::vector& grps, bool renum) const -{ - std::vector fams2=getFamiliesOnGroups(grps); - return getFamiliesArr(meshDimRelToMaxExt,fams2,renum); -} - -/*! - * Returns ids of mesh entities contained in a given family of a given dimension. - * \param [in] meshDimRelToMaxExt - a relative dimension of the mesh entities whose ids - * are required. - * \param [in] fam - the name of the family 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 family. 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::getFamilyArr(int meshDimRelToMaxExt, const std::string& fam, bool renum) const -{ - std::vector tmp(1); - tmp[0]=fam; - DataArrayInt *ret=getFamiliesArr(meshDimRelToMaxExt,tmp,renum); - ret->setName(fam); - return ret; -} - -/*! - * Returns ids of nodes contained in a given group. - * \param [in] grp - the name of the group of interest. - * \param [in] renum - if \c true, the optional numbers of nodes, if available, are - * returned instead of ids. - * \return DataArrayInt * - a new instance of DataArrayInt holding either ids or - * numbers, if available and required, of nodes of the group. The caller - * is to delete this array using decrRef() as it is no more needed. - * \throw If the name of a nonexistent group is specified. - * \throw If the family field is missing for nodes. - */ -DataArrayInt *MEDFileMesh::getNodeGroupArr(const std::string& grp, bool renum) const -{ - std::vector tmp(1); - tmp[0]=grp; - DataArrayInt *ret=getNodeGroupsArr(tmp,renum); - ret->setName(grp); - return ret; -} - -/*! - * Returns ids of nodes contained in given groups. - * \param [in] grps - the names of the groups of interest. - * \param [in] renum - if \c true, the optional numbers of nodes, if available, are - * returned instead of ids. - * \return DataArrayInt * - a new instance of DataArrayInt holding either ids or - * numbers, if available and required, of nodes of the groups. The caller - * is to delete this array using decrRef() as it is no more needed. - * \throw If the name of a nonexistent group is present in \a grps. - * \throw If the family field is missing for nodes. - */ -DataArrayInt *MEDFileMesh::getNodeGroupsArr(const std::vector& grps, bool renum) const -{ - return getGroupsArr(1,grps,renum); -} - -/*! - * Returns ids of nodes contained in a given group. - * \param [in] grp - the name of the group of interest. - * \param [in] renum - if \c true, the optional numbers of nodes, if available, are - * returned instead of ids. - * \return DataArrayInt * - a new instance of DataArrayInt holding either ids or - * numbers, if available and required, of nodes of the group. The caller - * is to delete this array using decrRef() as it is no more needed. - * \throw If the name of a nonexistent group is specified. - * \throw If the family field is missing for nodes. - */ -DataArrayInt *MEDFileMesh::getNodeFamilyArr(const std::string& fam, bool renum) const -{ - std::vector tmp(1); - tmp[0]=fam; - DataArrayInt *ret=getNodeFamiliesArr(tmp,renum); - ret->setName(fam); - return ret; -} - -/*! - * Returns ids of nodes contained in given families. - * \param [in] fams - the names of the families of interest. - * \param [in] renum - if \c true, the optional numbers of nodes, if available, are - * returned instead of ids. - * \return DataArrayInt * - a new instance of DataArrayInt holding either ids or - * numbers, if available and required, of nodes 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 nodes. - */ -DataArrayInt *MEDFileMesh::getNodeFamiliesArr(const std::vector& fams, bool renum) const -{ - return getFamiliesArr(1,fams,renum); -} - -/*! - * Adds groups of given dimension and creates corresponding families and family fields - * given ids of mesh entities of each group. - * \param [in] meshDimRelToMaxExt - the relative mesh dimension of given mesh entities. - * \param [in] grps - a sequence of arrays of ids each describing a group. - * \param [in] renum - \c true means that \a grps contains not ids but optional numbers - * of mesh entities. - * \throw If names of some groups in \a grps are equal. - * \throw If \a grps includes a group with an empty name. - * \throw If \a grps includes invalid ids (or numbers if \a renum == \c true ). - * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh. - */ -void MEDFileMesh::setGroupsAtLevel(int meshDimRelToMaxExt, const std::vector& grps, bool renum) -{ - if(grps.empty()) - return ; - std::set grpsName; - std::vector grpsName2(grps.size()); - int i=0; - - for(std::vector::const_iterator it=grps.begin();it!=grps.end();it++,i++) - { - grpsName.insert((*it)->getName()); - grpsName2[i]=(*it)->getName(); - } - if(grpsName.size()!=grps.size()) - throw INTERP_KERNEL::Exception("MEDFileUMesh::setGroupsAtLevel : groups name must be different each other !"); - if(grpsName.find(std::string(""))!=grpsName.end()) - throw INTERP_KERNEL::Exception("MEDFileUMesh::setGroupsAtLevel : groups name must be different empty string !"); - int sz=getSizeAtLevel(meshDimRelToMaxExt); - MEDCouplingAutoRefCountObjectPtr fam; - std::vector< std::vector > fidsOfGroups; - if(!renum) - { - fam=DataArrayInt::MakePartition(grps,sz,fidsOfGroups); - } - else - { - std::vector< MEDCouplingAutoRefCountObjectPtr > grps2(grps.size()); - for(unsigned int ii=0;iisetName(grps[ii]->getName()); - } - std::vector grps3(grps2.begin(),grps2.end()); - fam=DataArrayInt::MakePartition(grps3,sz,fidsOfGroups); - } - int offset=1; - if(!_families.empty()) - offset=getMaxAbsFamilyId()+1; - TranslateFamilyIds(meshDimRelToMaxExt==1?offset:-offset,fam,fidsOfGroups); - MEDCouplingAutoRefCountObjectPtr ids=fam->getDifferentValues(); - appendFamilyEntries(ids,fidsOfGroups,grpsName2); - setFamilyFieldArr(meshDimRelToMaxExt,fam); -} - -/*! - * This method append into '_families' attribute the families whose ids are in 'famIds'. Warning 'famIds' are expected to be ids - * not in '_families'. Groups information are given in parameters in order to give to families representative names. - * For the moment, the two last input parameters are not taken into account. - */ -void MEDFileMesh::appendFamilyEntries(const DataArrayInt *famIds, const std::vector< std::vector >& fidsOfGrps, const std::vector& grpNames) -{ - std::map famInv; - for(const int *it=famIds->begin();it!=famIds->end();it++) - { - std::ostringstream oss; - oss << "Family_" << (*it); - _families[oss.str()]=(*it); - famInv[*it]=oss.str(); - } - int i=0; - for(std::vector< std::vector >::const_iterator it1=fidsOfGrps.begin();it1!=fidsOfGrps.end();it1++,i++) - { - for(std::vector::const_iterator it2=(*it1).begin();it2!=(*it1).end();it2++) - { - _groups[grpNames[i]].push_back(famInv[*it2]); - } - } -} - -std::vector MEDFileMesh::getAllGeoTypes() const -{ - std::vector levs(getNonEmptyLevels()); - std::vector ret; - for(std::vector::const_iterator it=levs.begin();it!=levs.end();it++) - { - std::vector elts(getGeoTypesAtLevel(*it)); - ret.insert(ret.end(),elts.begin(),elts.end()); - } - return ret; -} - -std::vector MEDFileMesh::getDistributionOfTypes(int meshDimRelToMax) const -{ - MEDCouplingAutoRefCountObjectPtr mLev(getGenMeshAtLevel(meshDimRelToMax)); - return mLev->getDistributionOfTypes(); -} - -void MEDFileMesh::TranslateFamilyIds(int offset, DataArrayInt *famArr, std::vector< std::vector >& famIdsPerGrp) -{ - famArr->applyLin(offset>0?1:-1,offset,0); - for(std::vector< std::vector >::iterator it1=famIdsPerGrp.begin();it1!=famIdsPerGrp.end();it1++) - { - if(offset<0) - std::transform((*it1).begin(),(*it1).end(),(*it1).begin(),std::negate()); - std::transform((*it1).begin(),(*it1).end(),(*it1).begin(),std::bind2nd(std::plus(),offset)); - } -} - -/*! - * Warning no check is done on 'nameTry' in parameter. It should be non empty. - * This method returns a name close to 'nameTry' so that it is not already into 'namesToAvoid'. - * If this method fails to find such a name it will throw an exception. - */ -std::string MEDFileMesh::CreateNameNotIn(const std::string& nameTry, const std::vector& namesToAvoid) -{ - //attempt #0 - if(std::find(namesToAvoid.begin(),namesToAvoid.end(),nameTry)==namesToAvoid.end()) - return nameTry; - //attempt #1 - std::size_t len=nameTry.length(); - for(std::size_t ii=1;ii=1) - { - for(std::size_t i=1;i<30;i++) - { - std::string tmp1(nameTry.at(0),i); - tmp1+=nameTry; - if(std::find(namesToAvoid.begin(),namesToAvoid.end(),tmp1)==namesToAvoid.end()) - return tmp1; - } - } - //attempt #3 - std::string tmp2; - for(std::vector::const_iterator it2=namesToAvoid.begin();it2!=namesToAvoid.end();it2++) - tmp2+=(*it2); - if(std::find(namesToAvoid.begin(),namesToAvoid.end(),tmp2)==namesToAvoid.end()) - return tmp2; - throw INTERP_KERNEL::Exception("MEDFileMesh::CreateNameNotIn : impossible to find a not already used name !"); -} - -int MEDFileMesh::PutInThirdComponentOfCodeOffset(std::vector& code, int strt) -{ - std::size_t nbOfChunks=code.size()/3; - if(code.size()%3!=0) - throw INTERP_KERNEL::Exception("MEDFileMesh::PutInThirdComponentOfCodeOffset : code has invalid size : should be of size 3*x !"); - int ret=strt; - for(std::size_t i=0;igetName(); - else - { - std::string name(m->getName()); - if(!name.empty()) - { - if(_name!=name) - { - std::ostringstream oss; oss << "MEDFileMesh::dealWithTinyInfo : name of current MEDfile mesh is '" << _name << "' whereas name of input mesh is : '"; - oss << name << "' ! Names must match !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - } - } - if(_desc_name.empty()) - _desc_name=m->getDescription(); - else - { - std::string name(m->getDescription()); - if(!name.empty()) - { - if(_desc_name!=name) - { - std::ostringstream oss; oss << "MEDFileMesh::dealWithTinyInfo : description of current MEDfile mesh is '" << _desc_name << "' whereas name of input mesh is : '"; - oss << name << "' ! Names must match !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - } - } -} - -void MEDFileMesh::getFamilyRepr(std::ostream& oss) const -{ - oss << "(**************************)\n(* FAMILIES OF THE MESH : *)\n(**************************)\n"; - for(std::map::const_iterator it=_families.begin();it!=_families.end();it++) - { - oss << "- Family with name \"" << (*it).first << "\" with number " << (*it).second << std::endl; - oss << " - Groups lying on this family : "; - std::vector grps=getGroupsOnFamily((*it).first); - std::copy(grps.begin(),grps.end(),std::ostream_iterator(oss," ")); - oss << std::endl << std::endl; - } -} - -/*! - * Returns a new MEDFileUMesh holding the mesh data that has been read from a given MED - * file. The mesh to load is specified by its name and numbers of a time step and an - * iteration. - * \param [in] fileName - the name of MED file to read. - * \param [in] mName - the name of the mesh to read. - * \param [in] dt - the number of a time step. - * \param [in] it - the number of an iteration. - * \return MEDFileUMesh * - a new instance of MEDFileUMesh. The caller is to delete this - * mesh using decrRef() as it is no more needed. - * \throw If the file is not readable. - * \throw If there is no mesh with given attributes in the file. - * \throw If the mesh in the file is not an unstructured one. - */ -MEDFileUMesh *MEDFileUMesh::New(const std::string& fileName, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs) -{ - MEDFileUtilities::CheckFileForRead(fileName); - MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName.c_str(),MED_ACC_RDONLY); - return new MEDFileUMesh(fid,mName,dt,it,mrs); -} - -/*! - * Returns a new MEDFileUMesh holding the mesh data that has been read from a given MED - * file. The first mesh in the file is loaded. - * \param [in] fileName - the name of MED file to read. - * \return MEDFileUMesh * - a new instance of MEDFileUMesh. The caller is to delete this - * mesh using decrRef() as it is no more needed. - * \throw If the file is not readable. - * \throw If there is no meshes in the file. - * \throw If the mesh in the file is not an unstructured one. - */ -MEDFileUMesh *MEDFileUMesh::New(const std::string& fileName, MEDFileMeshReadSelector *mrs) -{ - std::vector ms=MEDLoader::GetMeshNames(fileName); - if(ms.empty()) - { - std::ostringstream oss; oss << "MEDFileUMesh::New : no meshes in file \"" << fileName << "\" !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - MEDFileUtilities::CheckFileForRead(fileName); - MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName.c_str(),MED_ACC_RDONLY); - int dt,it; - ParaMEDMEM::MEDCouplingMeshType meshType; - std::string dummy2; - MEDFileMeshL2::GetMeshIdFromName(fid,ms.front(),meshType,dt,it,dummy2); - return new MEDFileUMesh(fid,ms.front(),dt,it,mrs); -} - -/*! - * Returns an empty instance of MEDFileUMesh. - * \return MEDFileUMesh * - a new instance of MEDFileUMesh. The caller is to delete this - * mesh using decrRef() as it is no more needed. - */ -MEDFileUMesh *MEDFileUMesh::New() -{ - return new MEDFileUMesh; -} - -/*! - * This method loads from file with name \a fileName the mesh called \a mName as New does. The difference is that - * here only a part of cells contained in the file will be loaded. The selection of cell is specified using the two consecutive parameters - * \a types and \a slicPerTyp. This method allows to load from a mesh (typically huge) in a MED file a part of cells of that mesh. - * The part of cells is specified using triplet (start,stop,step) for each geometric type. Only nodes lying on selected cells will be loaded to reduce - * at most the memory consumtion. - * - * \param [in] fileName - the name of the file. - * \param [in] mName - the name of the mesh to be read. - * \param [in] types - the list of the geo types of which some part will be taken. A geometric type in \a types must appear only once at most. - * \param [in] slicPerType - an array of size 3 times larger than \a types that specifies for each type in \a types (in the same order) resp the start, the stop and the step. - * \param [in] dt - the iteration, that is to say the first element of the pair that locates the asked time step. - * \param [in] it - the order, that is to say the second element of the pair that locates the asked time step. - * \param [in] mrs - the request for what to be loaded. - * \return MEDFileUMesh * - a new instance of MEDFileUMesh. The caller is to delete this mesh using decrRef() as it is no more needed. - */ -MEDFileUMesh *MEDFileUMesh::LoadPartOf(const std::string& fileName, const std::string& mName, const std::vector& types, const std::vector& slicPerTyp, int dt, int it, MEDFileMeshReadSelector *mrs) -{ - MEDFileUtilities::CheckFileForRead(fileName); - MEDFileUtilities::AutoFid fid(MEDfileOpen(fileName.c_str(),MED_ACC_RDONLY)); - return MEDFileUMesh::LoadPartOf(fid,mName,types,slicPerTyp,dt,it,mrs); -} - -/*! - * Please refer to the other MEDFileUMesh::LoadPartOf method that has the same semantic and the same parameter (excepted the first). - * This method is \b NOT wrapped into python. - */ -MEDFileUMesh *MEDFileUMesh::LoadPartOf(med_idt fid, const std::string& mName, const std::vector& types, const std::vector& slicPerTyp, int dt, int it, MEDFileMeshReadSelector *mrs) -{ - MEDCouplingAutoRefCountObjectPtr ret(MEDFileUMesh::New()); - ret->loadPartUMeshFromFile(fid,mName,types,slicPerTyp,dt,it,mrs); - return ret.retn(); -} - -std::size_t MEDFileUMesh::getHeapMemorySizeWithoutChildren() const -{ - std::size_t ret(MEDFileMesh::getHeapMemorySizeWithoutChildren()); - ret+=_ms.capacity()*(sizeof(MEDCouplingAutoRefCountObjectPtr)); - return ret; -} - -std::vector MEDFileUMesh::getDirectChildrenWithNull() const -{ - std::vector ret(MEDFileMesh::getDirectChildrenWithNull()); - ret.push_back((const DataArrayDouble*)_coords); - ret.push_back((const DataArrayInt *)_fam_coords); - ret.push_back((const DataArrayInt *)_num_coords); - ret.push_back((const DataArrayInt *)_rev_num_coords); - ret.push_back((const DataArrayAsciiChar *)_name_coords); - ret.push_back((const PartDefinition *)_part_coords); - for(std::vector< MEDCouplingAutoRefCountObjectPtr >::const_iterator it=_ms.begin();it!=_ms.end();it++) - ret.push_back((const MEDFileUMeshSplitL1*) *it); - return ret; -} - -MEDFileMesh *MEDFileUMesh::shallowCpy() const -{ - MEDCouplingAutoRefCountObjectPtr ret=new MEDFileUMesh(*this); - return ret.retn(); -} - -MEDFileMesh *MEDFileUMesh::createNewEmpty() const -{ - return new MEDFileUMesh; -} - -MEDFileMesh *MEDFileUMesh::deepCpy() const -{ - MEDCouplingAutoRefCountObjectPtr ret=new MEDFileUMesh(*this); - if((const DataArrayDouble*)_coords) - ret->_coords=_coords->deepCpy(); - if((const DataArrayInt*)_fam_coords) - ret->_fam_coords=_fam_coords->deepCpy(); - if((const DataArrayInt*)_num_coords) - ret->_num_coords=_num_coords->deepCpy(); - if((const DataArrayInt*)_rev_num_coords) - ret->_rev_num_coords=_rev_num_coords->deepCpy(); - if((const DataArrayAsciiChar*)_name_coords) - ret->_name_coords=_name_coords->deepCpy(); - std::size_t i=0; - for(std::vector< MEDCouplingAutoRefCountObjectPtr >::const_iterator it=_ms.begin();it!=_ms.end();it++,i++) - { - if((const MEDFileUMeshSplitL1 *)(*it)) - ret->_ms[i]=(*it)->deepCpy(ret->_coords); - } - if((const PartDefinition*)_part_coords) - ret->_part_coords=_part_coords->deepCpy(); - return ret.retn(); -} - -/*! - * Checks if \a this and another mesh are equal. - * \param [in] other - the mesh to compare with. - * \param [in] eps - a precision used to compare real values. - * \param [in,out] what - the string returning description of unequal data. - * \return bool - \c true if the meshes are equal, \c false, else. - */ -bool MEDFileUMesh::isEqual(const MEDFileMesh *other, double eps, std::string& what) const -{ - if(!MEDFileMesh::isEqual(other,eps,what)) - return false; - const MEDFileUMesh *otherC=dynamic_cast(other); - if(!otherC) - { - what="Mesh types differ ! This is unstructured and other is NOT !"; - return false; - } - clearNonDiscrAttributes(); - otherC->clearNonDiscrAttributes(); - const DataArrayDouble *coo1=_coords; - const DataArrayDouble *coo2=otherC->_coords; - if((coo1==0 && coo2!=0) || (coo1!=0 && coo2==0)) - { - what="Mismatch of coordinates ! One is defined and not other !"; - return false; - } - if(coo1) - { - bool ret=coo1->isEqual(*coo2,eps); - if(!ret) - { - what="Coords differ !"; - return false; - } - } - const DataArrayInt *famc1=_fam_coords; - const DataArrayInt *famc2=otherC->_fam_coords; - if((famc1==0 && famc2!=0) || (famc1!=0 && famc2==0)) - { - what="Mismatch of families arr on nodes ! One is defined and not other !"; - return false; - } - if(famc1) - { - bool ret=famc1->isEqual(*famc2); - if(!ret) - { - what="Families arr on node differ !"; - return false; - } - } - const DataArrayInt *numc1=_num_coords; - const DataArrayInt *numc2=otherC->_num_coords; - if((numc1==0 && numc2!=0) || (numc1!=0 && numc2==0)) - { - what="Mismatch of numbering arr on nodes ! One is defined and not other !"; - return false; - } - if(numc1) - { - bool ret=numc1->isEqual(*numc2); - if(!ret) - { - what="Numbering arr on node differ !"; - return false; - } - } - const DataArrayAsciiChar *namec1=_name_coords; - const DataArrayAsciiChar *namec2=otherC->_name_coords; - if((namec1==0 && namec2!=0) || (namec1!=0 && namec2==0)) - { - what="Mismatch of naming arr on nodes ! One is defined and not other !"; - return false; - } - if(namec1) - { - bool ret=namec1->isEqual(*namec2); - if(!ret) - { - what="Names arr on node differ !"; - return false; - } - } - if(_ms.size()!=otherC->_ms.size()) - { - what="Number of levels differs !"; - return false; - } - std::size_t sz=_ms.size(); - for(std::size_t i=0;i_ms[i]; - if((s1==0 && s2!=0) || (s1!=0 && s2==0)) - { - what="Mismatch of presence of sub levels !"; - return false; - } - if(s1) - { - bool ret=s1->isEqual(s2,eps,what); - if(!ret) - return false; - } - } - const PartDefinition *pd0(_part_coords),*pd1(otherC->_part_coords); - if(!pd0 && !pd1) - return true; - if((!pd0 && pd1) || (pd0 && !pd1)) - { - what=std::string("node part def is defined only for one among this or other !"); - return false; - } - return pd0->isEqual(pd1,what); -} - -/*! - * Clears redundant attributes of incorporated data arrays. - */ -void MEDFileUMesh::clearNonDiscrAttributes() const -{ - MEDFileMesh::clearNonDiscrAttributes(); - const DataArrayDouble *coo1=_coords; - if(coo1) - (const_cast(coo1))->setName("");//This parameter is not discriminant for comparison - const DataArrayInt *famc1=_fam_coords; - if(famc1) - (const_cast(famc1))->setName("");//This parameter is not discriminant for comparison - const DataArrayInt *numc1=_num_coords; - if(numc1) - (const_cast(numc1))->setName("");//This parameter is not discriminant for comparison - const DataArrayAsciiChar *namc1=_name_coords; - if(namc1) - (const_cast(namc1))->setName("");//This parameter is not discriminant for comparison - for(std::vector< MEDCouplingAutoRefCountObjectPtr >::const_iterator it=_ms.begin();it!=_ms.end();it++) - { - const MEDFileUMeshSplitL1 *tmp=(*it); - if(tmp) - tmp->clearNonDiscrAttributes(); - } -} - -void MEDFileUMesh::setName(const std::string& name) -{ - for(std::vector< MEDCouplingAutoRefCountObjectPtr >::iterator it=_ms.begin();it!=_ms.end();it++) - if((MEDFileUMeshSplitL1 *)(*it)!=0) - (*it)->setName(name); - MEDFileMesh::setName(name); -} - -MEDFileUMesh::MEDFileUMesh() -{ -} - -MEDFileUMesh::MEDFileUMesh(med_idt fid, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs) -try -{ - loadUMeshFromFile(fid,mName,dt,it,mrs); - loadJointsFromFile(fid); - } -catch(INTERP_KERNEL::Exception& e) -{ - throw e; -} - -/*! - * This method loads only a part of specified cells (given by range of cell ID per geometric type) - * See MEDFileUMesh::LoadPartOf for detailed description. - * - * \sa loadUMeshFromFile - */ -void MEDFileUMesh::loadPartUMeshFromFile(med_idt fid, const std::string& mName, const std::vector& types, const std::vector& slicPerTyp, int dt, int it, MEDFileMeshReadSelector *mrs) -{ - MEDFileUMeshL2 loaderl2; - ParaMEDMEM::MEDCouplingMeshType meshType; - int dummy0,dummy1; - std::string dummy2; - int mid(MEDFileUMeshL2::GetMeshIdFromName(fid,mName,meshType,dummy0,dummy1,dummy2)); - if(meshType!=UNSTRUCTURED) - { - std::ostringstream oss; oss << "loadPartUMeshFromFile : Trying to load as unstructured an existing mesh with name '" << mName << "' !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - loaderl2.loadPart(fid,mid,mName,types,slicPerTyp,dt,it,mrs); - dispatchLoadedPart(fid,loaderl2,mName,mrs); -} - -/*! - * \brief Write joints in a file - */ -void MEDFileMesh::writeJoints(med_idt fid) const -{ - if ( (const MEDFileJoints*) _joints ) - _joints->write(fid); -} - -/*! - * \brief Load joints in a file or use provided ones - */ -//================================================================================ -/*! - * \brief Load joints in a file or use provided ones - * \param [in] fid - MED file descriptor - * \param [in] toUseInstedOfReading - optional joints to use instead of reading, - * Usually this joints are those just read by another iteration - * of namesake mesh, when this method is called by MEDFileMeshMultiTS::New() - */ -//================================================================================ - -void MEDFileMesh::loadJointsFromFile(med_idt fid, MEDFileJoints* toUseInstedOfReading) -{ - if ( toUseInstedOfReading ) - setJoints( toUseInstedOfReading ); - else - _joints = MEDFileJoints::New( fid, _name ); -} - -/*! - * \brief Return number of joints, which is equal to number of adjacent mesh domains - */ -int MEDFileMesh::getNumberOfJoints() -{ - return ( (MEDFileJoints*) _joints ) ? _joints->getNumberOfJoints() : 0; -} - -/*! - * \brief Return joints with all adjacent mesh domains - */ -MEDFileJoints * MEDFileMesh::getJoints() const -{ - return const_cast(& (*_joints)); -} - -void MEDFileMesh::setJoints( MEDFileJoints* joints ) -{ - if ( joints != _joints ) - { - _joints = joints; - if ( joints ) - joints->incrRef(); - } -} - -/*! - * This method loads \b all \b the \b mesh \a mName in the file with \a fid descriptor. - * - * \sa loadPartUMeshFromFile - */ -void MEDFileUMesh::loadUMeshFromFile(med_idt fid, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs) -{ - MEDFileUMeshL2 loaderl2; - ParaMEDMEM::MEDCouplingMeshType meshType; - int dummy0,dummy1; - std::string dummy2; - int mid(MEDFileUMeshL2::GetMeshIdFromName(fid,mName,meshType,dummy0,dummy1,dummy2)); - if(meshType!=UNSTRUCTURED) - { - std::ostringstream oss; oss << "Trying to load as unstructured an existing mesh with name '" << mName << "' !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - loaderl2.loadAll(fid,mid,mName,dt,it,mrs); - dispatchLoadedPart(fid,loaderl2,mName,mrs); -} - -void MEDFileUMesh::dispatchLoadedPart(med_idt fid, const MEDFileUMeshL2& loaderl2, const std::string& mName, MEDFileMeshReadSelector *mrs) -{ - int lev=loaderl2.getNumberOfLevels(); - _ms.resize(lev); - for(int i=0;iisNodeFamilyFieldReading()) - _fam_coords=loaderl2.getCoordsFamily(); - if(!mrs || mrs->isNodeNumFieldReading()) - _num_coords=loaderl2.getCoordsNum(); - if(!mrs || mrs->isNodeNameFieldReading()) - _name_coords=loaderl2.getCoordsName(); - _part_coords=loaderl2.getPartDefOfCoo(); - computeRevNum(); -} - -MEDFileUMesh::~MEDFileUMesh() -{ -} - -void MEDFileUMesh::writeLL(med_idt fid) const -{ - const DataArrayDouble *coo=_coords; - INTERP_KERNEL::AutoPtr maa=MEDLoaderBase::buildEmptyString(MED_NAME_SIZE); - INTERP_KERNEL::AutoPtr desc=MEDLoaderBase::buildEmptyString(MED_COMMENT_SIZE); - MEDLoaderBase::safeStrCpy(_name.c_str(),MED_NAME_SIZE,maa,_too_long_str); - MEDLoaderBase::safeStrCpy(_desc_name.c_str(),MED_COMMENT_SIZE,desc,_too_long_str); - int spaceDim=coo?coo->getNumberOfComponents():0; - int mdim(0); - if(!_ms.empty()) - mdim=getMeshDimension(); - INTERP_KERNEL::AutoPtr comp=MEDLoaderBase::buildEmptyString(spaceDim*MED_SNAME_SIZE); - INTERP_KERNEL::AutoPtr unit=MEDLoaderBase::buildEmptyString(spaceDim*MED_SNAME_SIZE); - for(int i=0;igetInfoOnComponent(i); - std::string c,u; - MEDLoaderBase::splitIntoNameAndUnit(info,c,u); - MEDLoaderBase::safeStrCpy2(c.c_str(),MED_SNAME_SIZE-1,comp+i*MED_SNAME_SIZE,_too_long_str);//MED_TAILLE_PNOM-1 to avoid to write '\0' on next compo - MEDLoaderBase::safeStrCpy2(u.c_str(),MED_SNAME_SIZE-1,unit+i*MED_SNAME_SIZE,_too_long_str);//MED_TAILLE_PNOM-1 to avoid to write '\0' on next compo - } - MEDFILESAFECALLERWR0(MEDmeshCr,(fid,maa,spaceDim,mdim,MED_UNSTRUCTURED_MESH,desc,"",MED_SORT_DTIT,MED_CARTESIAN,comp,unit)); - if(_univ_wr_status) - MEDFILESAFECALLERWR0(MEDmeshUniversalNameWr,(fid,maa)); - std::string meshName(MEDLoaderBase::buildStringFromFortran(maa,MED_NAME_SIZE)); - MEDFileUMeshL2::WriteCoords(fid,meshName,_iteration,_order,_time,_coords,_fam_coords,_num_coords,_name_coords); - for(std::vector< MEDCouplingAutoRefCountObjectPtr >::const_iterator it=_ms.begin();it!=_ms.end();it++) - if((const MEDFileUMeshSplitL1 *)(*it)!=0) - (*it)->write(fid,meshName,mdim); - MEDFileUMeshL2::WriteFamiliesAndGrps(fid,meshName,_families,_groups,_too_long_str); - - writeJoints(fid); -} - -/*! - * Returns relative dimensions of mesh entities (excluding nodes) present in \a this mesh. - * \return std::vector - a sequence of the relative dimensions. - */ -std::vector MEDFileUMesh::getNonEmptyLevels() const -{ - std::vector ret; - int lev=0; - for(std::vector< MEDCouplingAutoRefCountObjectPtr >::const_iterator it=_ms.begin();it!=_ms.end();it++,lev--) - if((const MEDFileUMeshSplitL1 *)(*it)!=0) - if(!(*it)->empty()) - ret.push_back(lev); - return ret; -} - -/*! - * Returns relative dimensions of mesh entities (including nodes) present in \a this mesh. - * \return std::vector - a sequence of the relative dimensions. - */ -std::vector MEDFileUMesh::getNonEmptyLevelsExt() const -{ - std::vector ret0=getNonEmptyLevels(); - if((const DataArrayDouble *) _coords) - { - std::vector ret(ret0.size()+1); - ret[0]=1; - std::copy(ret0.begin(),ret0.end(),ret.begin()+1); - return ret; - } - return ret0; -} - -std::vector MEDFileUMesh::getFamArrNonEmptyLevelsExt() const -{ - std::vector ret; - const DataArrayInt *famCoo(_fam_coords); - if(famCoo) - ret.push_back(1); - int lev=0; - for(std::vector< MEDCouplingAutoRefCountObjectPtr >::const_iterator it=_ms.begin();it!=_ms.end();it++,lev--) - { - const MEDFileUMeshSplitL1 *cur(*it); - if(cur) - if(cur->getFamilyField()) - ret.push_back(lev); - } - return ret; -} - -std::vector MEDFileUMesh::getNumArrNonEmptyLevelsExt() const -{ - std::vector ret; - const DataArrayInt *numCoo(_num_coords); - if(numCoo) - ret.push_back(1); - int lev=0; - for(std::vector< MEDCouplingAutoRefCountObjectPtr >::const_iterator it=_ms.begin();it!=_ms.end();it++,lev--) - { - const MEDFileUMeshSplitL1 *cur(*it); - if(cur) - if(cur->getNumberField()) - ret.push_back(lev); - } - return ret; -} - -std::vector MEDFileUMesh::getNameArrNonEmptyLevelsExt() const -{ - std::vector ret; - const DataArrayAsciiChar *nameCoo(_name_coords); - if(nameCoo) - ret.push_back(1); - int lev=0; - for(std::vector< MEDCouplingAutoRefCountObjectPtr >::const_iterator it=_ms.begin();it!=_ms.end();it++,lev--) - { - const MEDFileUMeshSplitL1 *cur(*it); - if(cur) - if(cur->getNameField()) - ret.push_back(lev); - } - return ret; -} - -/*! - * Returns all relative mesh levels (**excluding nodes**) where a given group is defined. - * To include nodes, call getGrpNonEmptyLevelsExt() method. - * \param [in] grp - the name of the group of interest. - * \return std::vector - a sequence of the relative dimensions. - */ -std::vector MEDFileUMesh::getGrpNonEmptyLevels(const std::string& grp) const -{ - std::vector fams=getFamiliesOnGroup(grp); - return getFamsNonEmptyLevels(fams); -} - -/*! - * Returns all relative mesh levels (including nodes) where a given group is defined. - * \param [in] grp - the name of the group of interest. - * \return std::vector - a sequence of the relative dimensions. - */ -std::vector MEDFileUMesh::getGrpNonEmptyLevelsExt(const std::string& grp) const -{ - std::vector fams=getFamiliesOnGroup(grp); - return getFamsNonEmptyLevelsExt(fams); -} - -/*! - * Returns all relative mesh levels (**excluding nodes**) where a given family is defined. - * To include nodes, call getFamNonEmptyLevelsExt() method. - * \param [in] fam - the name of the family of interest. - * \return std::vector - a sequence of the relative dimensions. - */ -std::vector MEDFileUMesh::getFamNonEmptyLevels(const std::string& fam) const -{ - std::vector fams(1,std::string(fam)); - return getFamsNonEmptyLevels(fams); -} - -/*! - * Returns all relative mesh levels (including nodes) where a given family is defined. - * \param [in] fam - the name of the family of interest. - * \return std::vector - a sequence of the relative dimensions. - */ -std::vector MEDFileUMesh::getFamNonEmptyLevelsExt(const std::string& fam) const -{ - std::vector fams(1,std::string(fam)); - return getFamsNonEmptyLevelsExt(fams); -} - -/*! - * Returns all relative mesh levels (**excluding nodes**) where given groups are defined. - * To include nodes, call getGrpsNonEmptyLevelsExt() method. - * \param [in] grps - a sequence of names of the groups of interest. - * \return std::vector - a sequence of the relative dimensions. - */ -std::vector MEDFileUMesh::getGrpsNonEmptyLevels(const std::vector& grps) const -{ - std::vector fams=getFamiliesOnGroups(grps); - return getFamsNonEmptyLevels(fams); -} - -/*! - * Returns all relative mesh levels (including nodes) where given groups are defined. - * \param [in] grps - a sequence of names of the groups of interest. - * \return std::vector - a sequence of the relative dimensions. - */ -std::vector MEDFileUMesh::getGrpsNonEmptyLevelsExt(const std::vector& grps) const -{ - std::vector fams=getFamiliesOnGroups(grps); - return getFamsNonEmptyLevelsExt(fams); -} - -/*! - * Returns all relative mesh levels (**excluding nodes**) where given families are defined. - * To include nodes, call getFamsNonEmptyLevelsExt() method. - * \param [in] fams - the name of the family of interest. - * \return std::vector - a sequence of the relative dimensions. - */ -std::vector MEDFileUMesh::getFamsNonEmptyLevels(const std::vector& fams) const -{ - std::vector ret; - std::vector levs=getNonEmptyLevels(); - std::vector famIds=getFamiliesIds(fams); - for(std::vector::const_iterator it=levs.begin();it!=levs.end();it++) - if(_ms[-(*it)]->presenceOfOneFams(famIds)) - ret.push_back(*it); - return ret; -} - -/*! - * Returns all relative mesh levels (including nodes) where given families are defined. - * \param [in] fams - the names of the families of interest. - * \return std::vector - a sequence of the relative dimensions. - */ -std::vector MEDFileUMesh::getFamsNonEmptyLevelsExt(const std::vector& fams) const -{ - std::vector ret0=getFamsNonEmptyLevels(fams); - const DataArrayInt *famCoords=_fam_coords; - if(!famCoords) - return ret0; - std::vector famIds=getFamiliesIds(fams); - if(famCoords->presenceOfValue(famIds)) - { - std::vector ret(ret0.size()+1); - ret[0]=1; - std::copy(ret0.begin(),ret0.end(),ret.begin()+1); - return ret; - } - else - return ret0; -} - -/*! - * Returns names of groups that partly or fully appear on the level \a meshDimRelToMaxExt. - * \param [in] meshDimRelToMaxExt - a relative dimension of interest. - * \return std::vector - a sequence of group names at \a meshDimRelToMaxExt - * level. - */ -std::vector MEDFileUMesh::getGroupsOnSpecifiedLev(int meshDimRelToMaxExt) const -{ - std::vector ret; - std::vector allGrps=getGroupsNames(); - for(std::vector::const_iterator it=allGrps.begin();it!=allGrps.end();it++) - { - std::vector levs=getGrpNonEmptyLevelsExt((*it)); - if(std::find(levs.begin(),levs.end(),meshDimRelToMaxExt)!=levs.end()) - ret.push_back(*it); - } - return ret; -} - -int MEDFileUMesh::getMaxAbsFamilyIdInArrays() const -{ - int ret=-std::numeric_limits::max(),tmp=-1; - if((const DataArrayInt *)_fam_coords) - { - int val=_fam_coords->getMaxValue(tmp); - ret=std::max(ret,std::abs(val)); - } - for(std::vector< MEDCouplingAutoRefCountObjectPtr >::const_iterator it=_ms.begin();it!=_ms.end();it++) - { - if((const MEDFileUMeshSplitL1 *)(*it)) - { - const DataArrayInt *da=(*it)->getFamilyField(); - if(da) - { - int val=da->getMaxValue(tmp); - ret=std::max(ret,std::abs(val)); - } - } - } - return ret; -} - -int MEDFileUMesh::getMaxFamilyIdInArrays() const -{ - int ret=-std::numeric_limits::max(),tmp=-1; - if((const DataArrayInt *)_fam_coords) - { - int val=_fam_coords->getMaxValue(tmp); - ret=std::max(ret,val); - } - for(std::vector< MEDCouplingAutoRefCountObjectPtr >::const_iterator it=_ms.begin();it!=_ms.end();it++) - { - if((const MEDFileUMeshSplitL1 *)(*it)) - { - const DataArrayInt *da=(*it)->getFamilyField(); - if(da) - { - int val=da->getMaxValue(tmp); - ret=std::max(ret,val); - } - } - } - return ret; -} - -int MEDFileUMesh::getMinFamilyIdInArrays() const -{ - int ret=std::numeric_limits::max(),tmp=-1; - if((const DataArrayInt *)_fam_coords) - { - int val=_fam_coords->getMinValue(tmp); - ret=std::min(ret,val); - } - for(std::vector< MEDCouplingAutoRefCountObjectPtr >::const_iterator it=_ms.begin();it!=_ms.end();it++) - { - if((const MEDFileUMeshSplitL1 *)(*it)) - { - const DataArrayInt *da=(*it)->getFamilyField(); - if(da) - { - int val=da->getMinValue(tmp); - ret=std::min(ret,val); - } - } - } - return ret; -} - -/*! - * Returns the dimension on cells in \a this mesh. - * \return int - the mesh dimension. - * \throw If there are no cells in this mesh. - */ -int MEDFileUMesh::getMeshDimension() const -{ - int lev=0; - for(std::vector< MEDCouplingAutoRefCountObjectPtr >::const_iterator it=_ms.begin();it!=_ms.end();it++,lev++) - if((const MEDFileUMeshSplitL1 *)(*it)!=0) - return (*it)->getMeshDimension()+lev; - throw INTERP_KERNEL::Exception("MEDFileUMesh::getMeshDimension : impossible to find a mesh dimension !"); -} - -/*! - * Returns the space dimension of \a this mesh that is equal to number of components in - * the node coordinates array. - * \return int - the space dimension of \a this mesh. - * \throw If the node coordinates array is not available. - */ -int MEDFileUMesh::getSpaceDimension() const -{ - const DataArrayDouble *coo=_coords; - if(!coo) - throw INTERP_KERNEL::Exception(" MEDFileUMesh::getSpaceDimension : no coords set !"); - return coo->getNumberOfComponents(); -} - -/*! - * Returns a string describing \a this mesh. - * \return std::string - the mesh information string. - */ -std::string MEDFileUMesh::simpleRepr() const -{ - std::ostringstream oss; - oss << MEDFileMesh::simpleRepr(); - const DataArrayDouble *coo=_coords; - oss << "- The dimension of the space is "; - static const char MSG1[]= "*** NO COORDS SET ***"; - static const char MSG2[]= "*** NO CONNECTIVITY SET FOR THIS LEVEL***"; - if(coo) - oss << _coords->getNumberOfComponents() << std::endl; - else - oss << MSG1 << std::endl; - oss << "- Type of the mesh : UNSTRUCTURED\n"; - oss << "- Number of nodes : "; - if(coo) - oss << _coords->getNumberOfTuples() << std::endl; - else - oss << MSG1 << std::endl; - std::size_t nbOfLev=_ms.size(); - oss << "- Number of levels allocated : " << nbOfLev << std::endl; - for(std::size_t i=0;igetMeshDimension() << std::endl; - lev->simpleRepr(oss); - } - else - oss << MSG2 << std::endl; - } - oss << "- Number of families : " << _families.size() << std::endl << std::endl; - if(coo) - { - oss << "(***********************)\n(* NODES OF THE MESH : *)\n(***********************)\n"; - oss << "- Names of coordinates :" << std::endl; - std::vector vars=coo->getVarsOnComponent(); - std::copy(vars.begin(),vars.end(),std::ostream_iterator(oss," ")); - oss << std::endl << "- Units of coordinates : " << std::endl; - std::vector units=coo->getUnitsOnComponent(); - std::copy(units.begin(),units.end(),std::ostream_iterator(oss," ")); - } - oss << std::endl << std::endl; - getFamilyRepr(oss); - return oss.str(); -} - -/*! - * Returns a full textual description of \a this mesh. - * \return std::string - the string holding the mesh description. - */ -std::string MEDFileUMesh::advancedRepr() const -{ - return simpleRepr(); -} - -/*! - * 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 MEDFileUMesh::getSizeAtLevel(int meshDimRelToMaxExt) const -{ - if(meshDimRelToMaxExt==1) - { - if(!((const DataArrayDouble *)_coords)) - throw INTERP_KERNEL::Exception("MEDFileUMesh::getSizeAtLevel : no coordinates specified !"); - return _coords->getNumberOfTuples(); - } - return getMeshAtLevSafe(meshDimRelToMaxExt)->getSize(); -} - -/*! - * 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 \c NULL. - */ -const DataArrayInt *MEDFileUMesh::getFamilyFieldAtLevel(int meshDimRelToMaxExt) const -{ - if(meshDimRelToMaxExt==1) - return _fam_coords; - const MEDFileUMeshSplitL1 *l1(getMeshAtLevSafe(meshDimRelToMaxExt)); - return l1->getFamilyField(); -} - -DataArrayInt *MEDFileUMesh::getFamilyFieldAtLevel(int meshDimRelToMaxExt) -{ - if(meshDimRelToMaxExt==1) - return _fam_coords; - MEDFileUMeshSplitL1 *l1(getMeshAtLevSafe(meshDimRelToMaxExt)); - return l1->getFamilyField(); -} - -/*! - * 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 *MEDFileUMesh::getNumberFieldAtLevel(int meshDimRelToMaxExt) const -{ - if(meshDimRelToMaxExt==1) - return _num_coords; - const MEDFileUMeshSplitL1 *l1=getMeshAtLevSafe(meshDimRelToMaxExt); - return l1->getNumberField(); -} - -const DataArrayAsciiChar *MEDFileUMesh::getNameFieldAtLevel(int meshDimRelToMaxExt) const -{ - if(meshDimRelToMaxExt==1) - return _name_coords; - const MEDFileUMeshSplitL1 *l1=getMeshAtLevSafe(meshDimRelToMaxExt); - return l1->getNameField(); -} - -/*! - * This method returns for a specified relative level \a meshDimRelToMaxExt the part effectively read (if the instance is the result of the read of a file). - * - * \param [in] meshDimRelToMaxExt - the extended relative level for which the part definition is requested. - * \param [in] gt - The input geometric type for which the part definition is requested. - * \return the part definition owned by \a this. So no need to deallocate the returned instance. - */ -const PartDefinition *MEDFileUMesh::getPartDefAtLevel(int meshDimRelToMaxExt, INTERP_KERNEL::NormalizedCellType gt) const -{ - if(meshDimRelToMaxExt==1) - return _part_coords; - const MEDFileUMeshSplitL1 *l1(getMeshAtLevSafe(meshDimRelToMaxExt)); - return l1->getPartDef(gt); -} - -int MEDFileUMesh::getNumberOfNodes() const -{ - const DataArrayDouble *coo(_coords); - if(!coo) - throw INTERP_KERNEL::Exception(" MEDFileUMesh::getNumberOfNodes : no coords set !"); - return coo->getNumberOfTuples(); -} - -int MEDFileUMesh::getNumberOfCellsAtLevel(int meshDimRelToMaxExt) const -{ - const MEDFileUMeshSplitL1 *l1(getMeshAtLevSafe(meshDimRelToMaxExt)); - return l1->getNumberOfCells(); -} - -bool MEDFileUMesh::hasImplicitPart() const -{ - return false; -} - -int MEDFileUMesh::buildImplicitPartIfAny(INTERP_KERNEL::NormalizedCellType gt) const -{ - throw INTERP_KERNEL::Exception("MEDFileUMesh::buildImplicitPartIfAny : unstructured meshes do not have implicit part !"); -} - -void MEDFileUMesh::releaseImplicitPartIfAny() const -{ -} - -void MEDFileUMesh::whichAreNodesFetched(const MEDFileField1TSStructItem& st, const MEDFileFieldGlobsReal *globs, std::vector& nodesFetched) const -{ - std::size_t sz(st.getNumberOfItems()); - for(std::size_t i=0;icomputeNodeIdsAlg(nodesFetched); - else - { - const DataArrayInt *arr(globs->getProfile(st[i].getPflName())); - MEDCouplingAutoRefCountObjectPtr m2(dynamic_cast(m->buildPartOfMySelf(arr->begin(),arr->end(),true))); - m2->computeNodeIdsAlg(nodesFetched); - } - } -} - -/*! - * 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 *MEDFileUMesh::getRevNumberFieldAtLevel(int meshDimRelToMaxExt) const -{ - if(meshDimRelToMaxExt==1) - { - if(!((const DataArrayInt *)_num_coords)) - throw INTERP_KERNEL::Exception("MEDFileUMesh::getRevNumberFieldAtLevel : no coordinates renum specified !"); - return _rev_num_coords; - } - const MEDFileUMeshSplitL1 *l1=getMeshAtLevSafe(meshDimRelToMaxExt); - return l1->getRevNumberField(); -} - -/*! - * 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 *MEDFileUMesh::getCoords() const -{ - MEDCouplingAutoRefCountObjectPtr tmp(_coords); - if((DataArrayDouble *)tmp) - { - return tmp; - } - return 0; -} - -/*! - * Returns a new MEDCouplingUMesh corresponding to mesh entities included in a given - * group of \a this mesh. Only mesh entities of a given dimension are included in the - * new mesh. - * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities of interest. - * \param [in] grp - the name of the group whose mesh entities are included in the - * new mesh. - * \param [in] renum - if \c true, cells and nodes of the result mesh are permuted - * according to the optional numbers of entities, if available. - * \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 name of a nonexistent group is specified. - * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh. - */ -MEDCouplingUMesh *MEDFileUMesh::getGroup(int meshDimRelToMaxExt, const std::string& grp, bool renum) const -{ - synchronizeTinyInfoOnLeaves(); - std::vector tmp(1); - tmp[0]=grp; - return getGroups(meshDimRelToMaxExt,tmp,renum); -} - -/*! - * Returns a new MEDCouplingUMesh corresponding to mesh entities included in given - * groups of \a this mesh. Only mesh entities of a given dimension are included in the - * new mesh. - * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities of interest. - * \param [in] grps - a sequence of group names whose mesh entities are included in the - * new mesh. - * \param [in] renum - if \c true, cells and nodes of the result mesh are permuted - * according to the optional numbers of entities, if available. - * \return MEDCouplingUMesh * - a new instance of MEDCouplingUMesh. The caller is to - * delete this mesh using decrRef() as it is no more needed. - * \throw If a name of a nonexistent group is present in \a grps. - * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh. - */ -MEDCouplingUMesh *MEDFileUMesh::getGroups(int meshDimRelToMaxExt, const std::vector& grps, bool renum) const -{ - synchronizeTinyInfoOnLeaves(); - std::vector fams2=getFamiliesOnGroups(grps); - MEDCouplingAutoRefCountObjectPtr zeRet=getFamilies(meshDimRelToMaxExt,fams2,renum); - if(grps.size()==1 && ((MEDCouplingUMesh *)zeRet)) - zeRet->setName(grps[0]); - return zeRet.retn(); -} - -/*! - * Returns a new MEDCouplingUMesh corresponding to mesh entities included in a given - * family of \a this mesh. Only mesh entities of a given dimension are included in the - * new mesh. - * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities of interest. - * \param [in] fam - the name of the family whose mesh entities are included in the - * new mesh. - * \param [in] renum - if \c true, cells and nodes of the result mesh are permuted - * according to the optional numbers of entities, if available. - * \return MEDCouplingUMesh * - a new instance of MEDCouplingUMesh. The caller is to - * delete this mesh using decrRef() as it is no more needed. - * \throw If a name of a nonexistent family is present in \a grps. - * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh. - */ -MEDCouplingUMesh *MEDFileUMesh::getFamily(int meshDimRelToMaxExt, const std::string& fam, bool renum) const -{ - synchronizeTinyInfoOnLeaves(); - std::vector tmp(1); - tmp[0]=fam; - return getFamilies(meshDimRelToMaxExt,tmp,renum); -} - -/*! - * Returns a new MEDCouplingUMesh corresponding to mesh entities included in given - * families of \a this mesh. Only mesh entities of a given dimension are included in the - * new mesh. - * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities of interest. - * \param [in] fams - a sequence of family names whose mesh entities are included in the - * new mesh. - * \param [in] renum - if \c true, cells and nodes of the result mesh are permuted - * according to the optional numbers of entities, if available. - * \return MEDCouplingUMesh * - a new instance of MEDCouplingUMesh. The caller is to - * delete this mesh using decrRef() as it is no more needed. - * \throw If a name of a nonexistent family is present in \a fams. - * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh. - */ -MEDCouplingUMesh *MEDFileUMesh::getFamilies(int meshDimRelToMaxExt, const std::vector& fams, bool renum) const -{ - synchronizeTinyInfoOnLeaves(); - if(meshDimRelToMaxExt==1) - { - MEDCouplingAutoRefCountObjectPtr arr=getFamiliesArr(1,fams,renum); - MEDCouplingAutoRefCountObjectPtr ret=MEDCouplingUMesh::New(); - MEDCouplingAutoRefCountObjectPtr c=_coords->selectByTupleId(arr->getConstPointer(),arr->getConstPointer()+arr->getNbOfElems()); - ret->setCoords(c); - return ret.retn(); - } - std::vector famIds=getFamiliesIds(fams); - const MEDFileUMeshSplitL1 *l1=getMeshAtLevSafe(meshDimRelToMaxExt); - MEDCouplingAutoRefCountObjectPtr zeRet; - if(!famIds.empty()) - zeRet=l1->getFamilyPart(&famIds[0],&famIds[0]+famIds.size(),renum); - else - zeRet=l1->getFamilyPart(0,0,renum); - if(fams.size()==1 && ((MEDCouplingUMesh *)zeRet)) - zeRet->setName(fams[0]); - return zeRet.retn(); -} - -/*! - * 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 *MEDFileUMesh::getFamiliesArr(int meshDimRelToMaxExt, const std::vector& fams, bool renum) const -{ - std::vector famIds=getFamiliesIds(fams); - if(meshDimRelToMaxExt==1) - { - if((const DataArrayInt *)_fam_coords) - { - MEDCouplingAutoRefCountObjectPtr da; - if(!famIds.empty()) - da=_fam_coords->getIdsEqualList(&famIds[0],&famIds[0]+famIds.size()); - else - da=_fam_coords->getIdsEqualList(0,0); - if(renum) - return MEDFileUMeshSplitL1::Renumber(_num_coords,da); - else - return da.retn(); - } - else - throw INTERP_KERNEL::Exception("MEDFileUMesh::getFamiliesArr : no family array specified on nodes !"); - } - const MEDFileUMeshSplitL1 *l1=getMeshAtLevSafe(meshDimRelToMaxExt); - if(!famIds.empty()) - return l1->getFamilyPartArr(&famIds[0],&famIds[0]+famIds.size(),renum); - else - return l1->getFamilyPartArr(0,0,renum); -} - -/*! - * Returns a MEDCouplingUMesh of a given relative dimension. - * \warning If \a meshDimRelToMaxExt == 1 (which means nodes), the returned mesh **is not - * valid**. This is a feature, because MEDLoader does not create cells that do not exist! - * To build a valid MEDCouplingUMesh from the returned one in this case, - * call MEDCouplingUMesh::Build0DMeshFromCoords(). - * \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 MEDCouplingUMesh * - a pointer to MEDCouplingUMesh 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. - * \sa getGenMeshAtLevel() - */ -MEDCouplingUMesh *MEDFileUMesh::getMeshAtLevel(int meshDimRelToMaxExt, bool renum) const -{ - synchronizeTinyInfoOnLeaves(); - if(meshDimRelToMaxExt==1) - { - if(!renum) - { - MEDCouplingUMesh *umesh=MEDCouplingUMesh::New(); - MEDCouplingAutoRefCountObjectPtr cc=_coords->deepCpy(); - umesh->setCoords(cc); - MEDFileUMeshSplitL1::ClearNonDiscrAttributes(umesh); - umesh->setName(getName()); - return umesh; - } - } - const MEDFileUMeshSplitL1 *l1=getMeshAtLevSafe(meshDimRelToMaxExt); - return l1->getWholeMesh(renum); -} - -/*! - * Returns a MEDCouplingUMesh of a given relative dimension. - * \warning If \a meshDimRelToMaxExt == 1 (which means nodes), the returned mesh **is not - * valid**. This is a feature, because MEDLoader does not create cells that do not exist! - * To build a valid MEDCouplingUMesh from the returned one in this case, - * call MEDCouplingUMesh::Build0DMeshFromCoords(). - * \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 MEDCouplingUMesh that the caller is to - * delete using decrRef() as it is no more needed. - * \throw If there are no mesh entities of \a meshDimRelToMax dimension in \a this mesh. - * \sa getMeshAtLevel() - */ -MEDCouplingMesh *MEDFileUMesh::getGenMeshAtLevel(int meshDimRelToMax, bool renum) const -{ - return getMeshAtLevel(meshDimRelToMax,renum); -} - -std::vector MEDFileUMesh::getDistributionOfTypes(int meshDimRelToMax) const -{ - const MEDFileUMeshSplitL1 *l1(getMeshAtLevSafe(meshDimRelToMax)); - return l1->getDistributionOfTypes(); -} - -/*! - * Returns a MEDCouplingUMesh of a relative dimension == 0. - * \param [in] renum - if \c true, the returned mesh is permuted according to the - * optional numbers of mesh entities. - * \return MEDCouplingUMesh * - a pointer to MEDCouplingUMesh that the caller is to - * delete using decrRef() as it is no more needed. - * \throw If there are no mesh entities of the relative dimension == 0 in \a this mesh. - */ -MEDCouplingUMesh *MEDFileUMesh::getLevel0Mesh(bool renum) const -{ - return getMeshAtLevel(0,renum); -} - -/*! - * Returns a MEDCouplingUMesh of a relative dimension == -1. - * \param [in] renum - if \c true, the returned mesh is permuted according to the - * optional numbers of mesh entities. - * \return MEDCouplingUMesh * - a pointer to MEDCouplingUMesh that the caller is to - * delete using decrRef() as it is no more needed. - * \throw If there are no mesh entities of the relative dimension == -1 in \a this mesh. - */ -MEDCouplingUMesh *MEDFileUMesh::getLevelM1Mesh(bool renum) const -{ - return getMeshAtLevel(-1,renum); -} - -/*! - * Returns a MEDCouplingUMesh of a relative dimension == -2. - * \param [in] renum - if \c true, the returned mesh is permuted according to the - * optional numbers of mesh entities. - * \return MEDCouplingUMesh * - a pointer to MEDCouplingUMesh that the caller is to - * delete using decrRef() as it is no more needed. - * \throw If there are no mesh entities of the relative dimension == -2 in \a this mesh. - */ -MEDCouplingUMesh *MEDFileUMesh::getLevelM2Mesh(bool renum) const -{ - return getMeshAtLevel(-2,renum); -} - -/*! - * Returns a MEDCouplingUMesh of a relative dimension == -3. - * \param [in] renum - if \c true, the returned mesh is permuted according to the - * optional numbers of mesh entities. - * \return MEDCouplingUMesh * - a pointer to MEDCouplingUMesh that the caller is to - * delete using decrRef() as it is no more needed. - * \throw If there are no mesh entities of the relative dimension == -3 in \a this mesh. - */ -MEDCouplingUMesh *MEDFileUMesh::getLevelM3Mesh(bool renum) const -{ - return getMeshAtLevel(-3,renum); -} - -/*! - * This method is for advanced users. There is two storing strategy of mesh in \a this. - * Either MEDCouplingUMesh, or vector of MEDCoupling1GTUMesh instances. - * When assignement is done the first one is done, which is not optimal in write mode for MED file. - * This method allows to switch from MEDCouplingUMesh mode to MEDCoupling1GTUMesh mode. - */ -void MEDFileUMesh::forceComputationOfParts() const -{ - for(std::vector< MEDCouplingAutoRefCountObjectPtr >::const_iterator it=_ms.begin();it!=_ms.end();it++) - { - const MEDFileUMeshSplitL1 *elt(*it); - if(elt) - elt->forceComputationOfParts(); - } -} - -/*! - * This method returns a vector of mesh parts containing each exactly one geometric type. - * This method will never launch an automatic computation of split by type (an INTERP_KERNEL::Exception will be then thrown). - * This method is only for memory aware users. - * The returned pointers are **NOT** new object pointer. No need to mange them. - */ -std::vector MEDFileUMesh::getDirectUndergroundSingleGeoTypeMeshes(int meshDimRelToMax) const -{ - const MEDFileUMeshSplitL1 *sp(getMeshAtLevSafe(meshDimRelToMax)); - return sp->getDirectUndergroundSingleGeoTypeMeshes(); -} - -/*! - * This method returns the part of \a this having the geometric type \a gt. - * If such part is not existing an exception will be thrown. - * The returned pointer is **NOT** new object pointer. No need to mange it. - */ -MEDCoupling1GTUMesh *MEDFileUMesh::getDirectUndergroundSingleGeoTypeMesh(INTERP_KERNEL::NormalizedCellType gt) const -{ - const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(gt); - int lev=(int)cm.getDimension()-getMeshDimension(); - const MEDFileUMeshSplitL1 *sp(getMeshAtLevSafe(lev)); - return sp->getDirectUndergroundSingleGeoTypeMesh(gt); -} - -/*! - * Given a relative level \a meshDimRelToMax it returns the sorted vector of geometric types present in \a this. - * \throw if the reqsuested \a meshDimRelToMax does not exist. - */ -std::vector MEDFileUMesh::getGeoTypesAtLevel(int meshDimRelToMax) const -{ - const MEDFileUMeshSplitL1 *sp(getMeshAtLevSafe(meshDimRelToMax)); - return sp->getGeoTypes(); -} - -/*! - * This method extracts from whole family field ids the part relative to the input parameter \a gt. - * \param [in] gt - the geometric type for which the family field is asked. - * \return DataArrayInt * - a pointer to DataArrayInt that the caller is to - * delete using decrRef() as it is no more needed. - * \sa MEDFileUMesh::extractNumberFieldOnGeoType - */ -DataArrayInt *MEDFileUMesh::extractFamilyFieldOnGeoType(INTERP_KERNEL::NormalizedCellType gt) const -{ - const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(gt); - int lev=(int)cm.getDimension()-getMeshDimension(); - const MEDFileUMeshSplitL1 *sp(getMeshAtLevSafe(lev)); - return sp->extractFamilyFieldOnGeoType(gt); -} - -/*! - * This method extracts from whole number field ids the part relative to the input parameter \a gt. - * \param [in] gt - the geometric type for which the number field is asked. - * \return DataArrayInt * - a pointer to DataArrayInt that the caller is to - * delete using decrRef() as it is no more needed. - * \sa MEDFileUMesh::extractFamilyFieldOnGeoType - */ -DataArrayInt *MEDFileUMesh::extractNumberFieldOnGeoType(INTERP_KERNEL::NormalizedCellType gt) const -{ - const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(gt); - int lev=(int)cm.getDimension()-getMeshDimension(); - const MEDFileUMeshSplitL1 *sp(getMeshAtLevSafe(lev)); - return sp->extractNumberFieldOnGeoType(gt); -} - -/*! - * This method returns for specified geometric type \a gt the relative level to \a this. - * If the relative level is empty an exception will be thrown. - */ -int MEDFileUMesh::getRelativeLevOnGeoType(INTERP_KERNEL::NormalizedCellType gt) const -{ - const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(gt); - int ret((int)cm.getDimension()-getMeshDimension()); - getMeshAtLevSafe(ret);//To test that returned value corresponds to a valid level. - return ret; -} - -const MEDFileUMeshSplitL1 *MEDFileUMesh::getMeshAtLevSafe(int meshDimRelToMaxExt) const -{ - if(meshDimRelToMaxExt==1) - throw INTERP_KERNEL::Exception("Dimension request is invalid : asking for node level (1) !"); - if(meshDimRelToMaxExt>1) - throw INTERP_KERNEL::Exception("Dimension request is invalid (>1) !"); - int tracucedRk=-meshDimRelToMaxExt; - if(tracucedRk>=(int)_ms.size()) - throw INTERP_KERNEL::Exception("Invalid mesh dim relative to max given ! Too low !"); - if((const MEDFileUMeshSplitL1 *)_ms[tracucedRk]==0) - throw INTERP_KERNEL::Exception("On specified lev (or entity) no cells exists !"); - return _ms[tracucedRk]; -} - -MEDFileUMeshSplitL1 *MEDFileUMesh::getMeshAtLevSafe(int meshDimRelToMaxExt) -{ - if(meshDimRelToMaxExt==1) - throw INTERP_KERNEL::Exception("Dimension request is invalid : asking for node level (1) !"); - if(meshDimRelToMaxExt>1) - throw INTERP_KERNEL::Exception("Dimension request is invalid (>1) !"); - int tracucedRk=-meshDimRelToMaxExt; - if(tracucedRk>=(int)_ms.size()) - throw INTERP_KERNEL::Exception("Invalid mesh dim relative to max given ! Too low !"); - if((const MEDFileUMeshSplitL1 *)_ms[tracucedRk]==0) - throw INTERP_KERNEL::Exception("On specified lev (or entity) no cells exists !"); - return _ms[tracucedRk]; -} - -void MEDFileUMesh::checkMeshDimCoherency(int meshDim, int meshDimRelToMax) const -{ - if(-meshDimRelToMax>=(int)_ms.size()) - throw INTERP_KERNEL::Exception("MEDFileUMesh::checkMeshDimCoherency : The meshdim of mesh is not managed by 'this' !"); - int i=0; - for(std::vector< MEDCouplingAutoRefCountObjectPtr >::const_iterator it=_ms.begin();it!=_ms.end();it++,i++) - { - if(((const MEDFileUMeshSplitL1*) (*it))!=0) - { - int ref=(*it)->getMeshDimension(); - if(ref+i!=meshDim-meshDimRelToMax) - throw INTERP_KERNEL::Exception("MEDFileUMesh::checkMeshDimCoherency : no coherency between levels !"); - } - } -} - -/*! - * Sets the node coordinates array of \a this mesh. - * \param [in] coords - the new node coordinates array. - * \throw If \a coords == \c NULL. - */ -void MEDFileUMesh::setCoords(DataArrayDouble *coords) -{ - if(!coords) - throw INTERP_KERNEL::Exception("MEDFileUMesh::setCoords : null pointer in input !"); - coords->checkAllocated(); - int nbOfTuples=coords->getNumberOfTuples(); - _coords=coords; - coords->incrRef(); - _fam_coords=DataArrayInt::New(); - _fam_coords->alloc(nbOfTuples,1); - _fam_coords->fillWithZero(); - for(std::vector< MEDCouplingAutoRefCountObjectPtr >::iterator it=_ms.begin();it!=_ms.end();it++) - if((MEDFileUMeshSplitL1 *)(*it)) - (*it)->setCoords(coords); -} - -/*! - * Removes all groups of a given dimension in \a this mesh. - * \param [in] meshDimRelToMaxExt - the relative dimension of interest. - * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh. - */ -void MEDFileUMesh::eraseGroupsAtLevel(int meshDimRelToMaxExt) -{ - if(meshDimRelToMaxExt==1) - { - if((DataArrayInt *)_fam_coords) - _fam_coords->fillWithZero(); - return ; - } - MEDFileUMeshSplitL1 *l1=getMeshAtLevSafe(meshDimRelToMaxExt); - l1->eraseFamilyField(); - optimizeFamilies(); -} - -/*! - * Removes all families with ids not present in the family fields of \a this mesh. - */ -void MEDFileUMesh::optimizeFamilies() -{ - std::vector levs=getNonEmptyLevelsExt(); - std::set allFamsIds; - for(std::vector::const_iterator it=levs.begin();it!=levs.end();it++) - { - const DataArrayInt *ffield=getFamilyFieldAtLevel(*it); - MEDCouplingAutoRefCountObjectPtr ids=ffield->getDifferentValues(); - std::set res; - std::set_union(ids->begin(),ids->end(),allFamsIds.begin(),allFamsIds.end(),std::inserter(res,res.begin())); - allFamsIds=res; - } - std::set famNamesToKill; - for(std::map::const_iterator it=_families.begin();it!=_families.end();it++) - { - if(allFamsIds.find((*it).second)!=allFamsIds.end()) - famNamesToKill.insert((*it).first); - } - for(std::set::const_iterator it=famNamesToKill.begin();it!=famNamesToKill.end();it++) - _families.erase(*it); - std::vector grpNamesToKill; - for(std::map >::iterator it=_groups.begin();it!=_groups.end();it++) - { - std::vector tmp; - for(std::vector::const_iterator it2=(*it).second.begin();it2!=(*it).second.end();it2++) - { - if(famNamesToKill.find(*it2)==famNamesToKill.end()) - tmp.push_back(*it2); - } - if(!tmp.empty()) - (*it).second=tmp; - else - tmp.push_back((*it).first); - } - for(std::vector::const_iterator it=grpNamesToKill.begin();it!=grpNamesToKill.end();it++) - _groups.erase(*it); -} - -/** - * \b this must be filled at level 0 and -1, typically the -1 level being (part of) the descending connectivity - * of the top level. This method build a "crack", or an inner boundary, in \b this along the group of level -1 named grpNameM1. - * The boundary is built according to the following method: - * - all nodes along the boundary which are not lying on an internal extremity of the (-1)-level group are duplicated (so the - * coordinates array is extended). - * - new (-1)-level cells are built lying on those new nodes. So the edges/faces along the group are duplicated. - * After this operation a top-level cell bordering the group will loose some neighbors (typically the cell which is on the - * other side of the group is no more a neighbor) - * - finally, the connectivity of (part of) the top level-cells bordering the group is also modified so that some cells - * bordering the newly created boundary use the newly computed nodes. - * - * \param[in] grpNameM1 name of the (-1)-level group defining the boundary - * \param[out] nodesDuplicated ids of the initial nodes which have been duplicated (and whose copy is put at the end of - * the coord array) - * \param[out] cellsModified ids of the cells whose connectivity has been modified (to use the newly created nodes) - * \param[out] cellsNotModified ids of the rest of cells bordering the new boundary whose connectivity remains unchanged. - */ -void MEDFileUMesh::buildInnerBoundaryAlongM1Group(const std::string& grpNameM1, DataArrayInt *&nodesDuplicated, - DataArrayInt *&cellsModified, DataArrayInt *&cellsNotModified) -{ - std::vector levs=getNonEmptyLevels(); - if(std::find(levs.begin(),levs.end(),0)==levs.end() || std::find(levs.begin(),levs.end(),-1)==levs.end()) - throw INTERP_KERNEL::Exception("MEDFileUMesh::buildInnerBoundaryAlongM1Group : This method works only for mesh definied on level 0 and -1 !"); - MEDCouplingAutoRefCountObjectPtr m0=getMeshAtLevel(0); - MEDCouplingAutoRefCountObjectPtr m1=getMeshAtLevel(-1); - int nbNodes=m0->getNumberOfNodes(); - MEDCouplingAutoRefCountObjectPtr m11=getGroup(-1,grpNameM1); - DataArrayInt *tmp00=0,*tmp11=0,*tmp22=0; - m0->findNodesToDuplicate(*m11,tmp00,tmp11,tmp22); - MEDCouplingAutoRefCountObjectPtr nodeIdsToDuplicate(tmp00); - MEDCouplingAutoRefCountObjectPtr cellsToModifyConn0(tmp11); - MEDCouplingAutoRefCountObjectPtr cellsToModifyConn1(tmp22); - MEDCouplingAutoRefCountObjectPtr tmp0=static_cast(m0->buildPartOfMySelf(cellsToModifyConn0->begin(),cellsToModifyConn0->end(),true)); - // node renumbering of cells in m1 impacted by duplication of node but not in group 'grpNameM1' on level -1 - MEDCouplingAutoRefCountObjectPtr descTmp0=DataArrayInt::New(),descITmp0=DataArrayInt::New(),revDescTmp0=DataArrayInt::New(),revDescITmp0=DataArrayInt::New(); - MEDCouplingAutoRefCountObjectPtr tmp0Desc=tmp0->buildDescendingConnectivity(descTmp0,descITmp0,revDescTmp0,revDescITmp0); - descTmp0=0; descITmp0=0; revDescTmp0=0; revDescITmp0=0; - MEDCouplingAutoRefCountObjectPtr cellsInM1ToRenumW2=tmp0Desc->getCellIdsLyingOnNodes(nodeIdsToDuplicate->begin(),nodeIdsToDuplicate->end(),false); - MEDCouplingAutoRefCountObjectPtr cellsInM1ToRenumW3=static_cast(tmp0Desc->buildPartOfMySelf(cellsInM1ToRenumW2->begin(),cellsInM1ToRenumW2->end(),true)); - DataArrayInt *cellsInM1ToRenumW4Tmp=0; - m1->areCellsIncludedIn(cellsInM1ToRenumW3,2,cellsInM1ToRenumW4Tmp); - MEDCouplingAutoRefCountObjectPtr cellsInM1ToRenumW4(cellsInM1ToRenumW4Tmp); - MEDCouplingAutoRefCountObjectPtr cellsInM1ToRenumW5=cellsInM1ToRenumW4->getIdsInRange(0,m1->getNumberOfCells()); - cellsInM1ToRenumW5->transformWithIndArr(cellsInM1ToRenumW4->begin(),cellsInM1ToRenumW4->end()); - MEDCouplingAutoRefCountObjectPtr grpIds=getGroupArr(-1,grpNameM1); - MEDCouplingAutoRefCountObjectPtr cellsInM1ToRenum=cellsInM1ToRenumW5->buildSubstraction(grpIds); - MEDCouplingAutoRefCountObjectPtr m1Part=static_cast(m1->buildPartOfMySelf(cellsInM1ToRenum->begin(),cellsInM1ToRenum->end(),true)); - m1Part->duplicateNodesInConn(nodeIdsToDuplicate->begin(),nodeIdsToDuplicate->end(),nbNodes); - m1->setPartOfMySelf(cellsInM1ToRenum->begin(),cellsInM1ToRenum->end(),*m1Part); - // end of node renumbering of cells in m1 impacted by duplication of node but not in group of level -1 'grpNameM1' - tmp0->duplicateNodes(nodeIdsToDuplicate->begin(),nodeIdsToDuplicate->end()); - m0->setCoords(tmp0->getCoords()); - m0->setPartOfMySelf(cellsToModifyConn0->begin(),cellsToModifyConn0->end(),*tmp0); - m1->setCoords(m0->getCoords()); - _coords=m0->getCoords(); _coords->incrRef(); - // duplication of cells in group 'grpNameM1' on level -1 - m11->duplicateNodesInConn(nodeIdsToDuplicate->begin(),nodeIdsToDuplicate->end(),nbNodes); m11->setCoords(m0->getCoords()); - std::vector v(2); v[0]=m1; v[1]=m11; - MEDCouplingAutoRefCountObjectPtr newm1=MEDCouplingUMesh::AggregateSortedByTypeMeshesOnSameCoords(v,tmp00,tmp11); - MEDCouplingAutoRefCountObjectPtr szOfCellGrpOfSameType(tmp00); - MEDCouplingAutoRefCountObjectPtr idInMsOfCellGrpOfSameType(tmp11); - // - newm1->setName(getName()); - const DataArrayInt *fam=getFamilyFieldAtLevel(-1); - if(!fam) - throw INTERP_KERNEL::Exception("MEDFileUMesh::buildInnerBoundaryAlongM1Group : internal problem !"); - MEDCouplingAutoRefCountObjectPtr newFam=DataArrayInt::New(); - newFam->alloc(newm1->getNumberOfCells(),1); - // Get a new family ID: care must be taken if we need a positive ID or a negative one: - // Positive ID for family of nodes, negative for all the rest. - int idd; - if (m1->getMeshDimension() == 0) - idd=getMaxFamilyId()+1; - else - idd=getMinFamilyId()-1; - int globStart=0,start=0,end,globEnd; - int nbOfChunks=szOfCellGrpOfSameType->getNumberOfTuples(); - for(int i=0;igetIJ(i,0); - if(idInMsOfCellGrpOfSameType->getIJ(i,0)==0) - { - end=start+szOfCellGrpOfSameType->getIJ(i,0); - MEDCouplingAutoRefCountObjectPtr part=fam->selectByTupleId2(start,end,1); - newFam->setPartOfValues1(part,globStart,globEnd,1,0,1,1,true); - start=end; - } - else - { - newFam->setPartOfValuesSimple1(idd,globStart,globEnd,1,0,1,1); - } - globStart=globEnd; - } - newm1->setCoords(getCoords()); - setMeshAtLevel(-1,newm1); - setFamilyFieldArr(-1,newFam); - std::string grpName2(grpNameM1); grpName2+="_dup"; - addFamily(grpName2,idd); - addFamilyOnGrp(grpName2,grpName2); - // - fam=_fam_coords; - if(fam) - { - int newNbOfNodes=getCoords()->getNumberOfTuples(); - newFam=DataArrayInt::New(); newFam->alloc(newNbOfNodes,1); - newFam->setPartOfValues1(fam,0,nbNodes,1,0,1,1,true); - newFam->setPartOfValuesSimple1(0,nbNodes,newNbOfNodes,1,0,1,1); - _fam_coords=newFam; - } - nodesDuplicated=nodeIdsToDuplicate.retn(); - cellsModified=cellsToModifyConn0.retn(); - cellsNotModified=cellsToModifyConn1.retn(); -} - -/*! - * \param [out] oldCode retrieves the distribution of types before the call if true is returned - * \param [out] newCode etrieves the distribution of types after the call if true is returned - * \param [out] o2nRenumCell tells for **all levels** the old 2 new renumbering of cells. - * - * \return false if no modification has been performed linked to the unpolyzation. Neither cell type, not cell numbers. When false is returned no need of field on cells or on gauss renumbering. - * Inversely, if true is returned, it means that distribution of cell by geometric type has changed and field on cell and field on gauss point must be renumbered. - */ -bool MEDFileUMesh::unPolyze(std::vector& oldCode, std::vector& newCode, DataArrayInt *& o2nRenumCell) -{ - o2nRenumCell=0; oldCode.clear(); newCode.clear(); - std::vector levs=getNonEmptyLevels(); - bool ret=false; - std::vector< const DataArrayInt* > renumCellsSplited;//same than memorySaverIfThrow - std::vector< MEDCouplingAutoRefCountObjectPtr > memorySaverIfThrow;//same than renumCellsSplited only in case of throw - int start=0; - int end=0; - for(std::vector::reverse_iterator it=levs.rbegin();it!=levs.rend();it++) - { - MEDCouplingAutoRefCountObjectPtr m=getMeshAtLevel(*it); - std::vector code1=m->getDistributionOfTypes(); - end=PutInThirdComponentOfCodeOffset(code1,start); - oldCode.insert(oldCode.end(),code1.begin(),code1.end()); - bool hasChanged=m->unPolyze(); - DataArrayInt *fake=0; - MEDCouplingAutoRefCountObjectPtr o2nCellsPart=m->getLevArrPerCellTypes(MEDCouplingUMesh::MEDMEM_ORDER, - MEDCouplingUMesh::MEDMEM_ORDER+MEDCouplingUMesh::N_MEDMEM_ORDER,fake); - fake->decrRef(); - renumCellsSplited.push_back(o2nCellsPart); memorySaverIfThrow.push_back(o2nCellsPart); - if(hasChanged) - { - MEDCouplingAutoRefCountObjectPtr o2nCellsPart2=o2nCellsPart->buildPermArrPerLevel(); - m->renumberCells(o2nCellsPart2->getConstPointer(),false); - ret=true; - MEDCouplingAutoRefCountObjectPtr famField2,numField2; - const DataArrayInt *famField=getFamilyFieldAtLevel(*it); if(famField) { famField->incrRef(); famField2=const_cast(famField); } - const DataArrayInt *numField=getNumberFieldAtLevel(*it); if(numField) { numField->incrRef(); numField2=const_cast(numField); } - setMeshAtLevel(*it,m); - std::vector code2=m->getDistributionOfTypes(); - end=PutInThirdComponentOfCodeOffset(code2,start); - newCode.insert(newCode.end(),code2.begin(),code2.end()); - // - if(o2nCellsPart2->isIdentity()) - continue; - if(famField) - { - MEDCouplingAutoRefCountObjectPtr newFamField=famField->renumber(o2nCellsPart2->getConstPointer()); - setFamilyFieldArr(*it,newFamField); - } - if(numField) - { - MEDCouplingAutoRefCountObjectPtr newNumField=numField->renumber(o2nCellsPart2->getConstPointer()); - setRenumFieldArr(*it,newNumField); - } - } - else - { - newCode.insert(newCode.end(),code1.begin(),code1.end()); - } - start=end; - } - if(ret) - { - MEDCouplingAutoRefCountObjectPtr renumCells=DataArrayInt::Aggregate(renumCellsSplited); - MEDCouplingAutoRefCountObjectPtr o2nRenumCellRet=renumCells->buildPermArrPerLevel(); - o2nRenumCell=o2nRenumCellRet.retn(); - } - return ret; -} - -/*! \cond HIDDEN_ITEMS */ -struct MEDLoaderAccVisit1 -{ - MEDLoaderAccVisit1():_new_nb_of_nodes(0) { } - int operator()(bool val) { return val?_new_nb_of_nodes++:-1; } - int _new_nb_of_nodes; -}; -/*! \endcond */ - -/*! - * Array returned is the correspondance in \b old \b to \b new format. The returned array is newly created and should be dealt by the caller. - * The maximum value stored in returned array is the number of nodes of \a this minus 1 after call of this method. - * The size of returned array is the number of nodes of the old (previous to the call of this method) number of nodes. - * -1 values in returned array means that the corresponding old node is no more used. - * - * \return newly allocated array containing correspondance in \b old \b to \b new format. If all nodes in \a this are fetched \c NULL pointer is returned and nothing - * is modified in \a this. - * \throw If no coordinates are set in \a this or if there is in any available mesh in \a this a cell having a nodal connectivity containing a node id not in the range of - * set coordinates. - */ -DataArrayInt *MEDFileUMesh::zipCoords() -{ - const DataArrayDouble *coo(getCoords()); - if(!coo) - throw INTERP_KERNEL::Exception("MEDFileUMesh::zipCoords : no coordinates set in this !"); - int nbOfNodes(coo->getNumberOfTuples()); - std::vector nodeIdsInUse(nbOfNodes,false); - std::vector neLevs(getNonEmptyLevels()); - for(std::vector::const_iterator lev=neLevs.begin();lev!=neLevs.end();lev++) - { - const MEDFileUMeshSplitL1 *zeLev(getMeshAtLevSafe(*lev)); - if(zeLev->isMeshStoredSplitByType()) - { - std::vector ms(zeLev->getDirectUndergroundSingleGeoTypeMeshes()); - for(std::vector::const_iterator it=ms.begin();it!=ms.end();it++) - if(*it) - (*it)->computeNodeIdsAlg(nodeIdsInUse); - } - else - { - MEDCouplingAutoRefCountObjectPtr mesh(zeLev->getWholeMesh(false)); - mesh->computeNodeIdsAlg(nodeIdsInUse); - } - } - int nbrOfNodesInUse((int)std::count(nodeIdsInUse.begin(),nodeIdsInUse.end(),true)); - if(nbrOfNodesInUse==nbOfNodes) - return 0;//no need to update _part_coords - MEDCouplingAutoRefCountObjectPtr ret(DataArrayInt::New()); ret->alloc(nbOfNodes,1); - std::transform(nodeIdsInUse.begin(),nodeIdsInUse.end(),ret->getPointer(),MEDLoaderAccVisit1()); - MEDCouplingAutoRefCountObjectPtr ret2(ret->invertArrayO2N2N2OBis(nbrOfNodesInUse)); - MEDCouplingAutoRefCountObjectPtr newCoords(coo->selectByTupleIdSafe(ret2->begin(),ret2->end())); - MEDCouplingAutoRefCountObjectPtr newFamCoords; - MEDCouplingAutoRefCountObjectPtr newNameCoords; - if((const DataArrayInt *)_fam_coords) - newFamCoords=_fam_coords->selectByTupleIdSafe(ret2->begin(),ret2->end()); - MEDCouplingAutoRefCountObjectPtr newNumCoords; - if((const DataArrayInt *)_num_coords) - newNumCoords=_num_coords->selectByTupleIdSafe(ret2->begin(),ret2->end()); - if((const DataArrayAsciiChar *)_name_coords) - newNameCoords=static_cast(_name_coords->selectByTupleIdSafe(ret2->begin(),ret2->end())); - _coords=newCoords; _fam_coords=newFamCoords; _num_coords=newNumCoords; _name_coords=newNameCoords; _rev_num_coords=0; - for(std::vector< MEDCouplingAutoRefCountObjectPtr >::iterator it=_ms.begin();it!=_ms.end();it++) - { - if((MEDFileUMeshSplitL1*)*it) - { - (*it)->renumberNodesInConn(ret->begin()); - (*it)->setCoords(_coords); - } - } - // updates _part_coords - const PartDefinition *pc(_part_coords); - if(pc) - { - MEDCouplingAutoRefCountObjectPtr tmpPD(DataArrayPartDefinition::New(ret2)); - _part_coords=tmpPD->composeWith(pc); - } - return ret.retn(); -} - -/*! - * This method performs an extrusion along a path defined by \a m1D. - * \a this is expected to be a mesh with max mesh dimension equal to 2. - * \a m1D is expected to be a mesh with space dimesion equal to 3 and mesh dimension equal to 1. - * Mesh dimensions of returned mesh is incremented by one compared to thoose in \a this. - * This method scans all levels in \a this - * and put them in the returned mesh. All groups in \a this are also put in the returned mesh. - * - * \param [in] m1D - the mesh defining the extrusion path. - * \param [in] policy - defines the policy of extrusion (see MEDCouplingUMesh::buildExtrudedMesh for more details) - * \return - a new reference on mesh (you have to deal with using decrRef). The returned mesh will have the same name than \a this. - * - * \sa MEDCouplingUMesh::buildExtrudedMesh - */ -MEDFileUMesh *MEDFileUMesh::buildExtrudedMesh(const MEDCouplingUMesh *m1D, int policy) const -{ - if(getMeshDimension()!=2) - throw INTERP_KERNEL::Exception("MEDFileUMesh::buildExtrudedMesh : this is expected to be with mesh dimension equal to 2 !"); - MEDCouplingAutoRefCountObjectPtr ret(MEDFileUMesh::New()); - m1D->checkCoherency(); - if(m1D->getMeshDimension()!=1) - throw INTERP_KERNEL::Exception("MEDFileUMesh::buildExtrudedMesh : input mesh must have a mesh dimension equal to one !"); - int nbRep(m1D->getNumberOfCells()); - std::vector levs(getNonEmptyLevels()); - std::vector grps(getGroupsNames()); - std::vector< MEDCouplingAutoRefCountObjectPtr > zeList; - DataArrayDouble *coords(0); - std::size_t nbOfLevsOut(levs.size()+1); - std::vector< MEDCouplingAutoRefCountObjectPtr > o2ns(nbOfLevsOut); - for(std::vector::const_iterator lev=levs.begin();lev!=levs.end();lev++) - { - MEDCouplingAutoRefCountObjectPtr item(getMeshAtLevel(*lev)); - item=item->clone(false); - item->changeSpaceDimension(3+(*lev),0.);//no problem non const but change DataArrayDouble for coordinates do not alter data - MEDCouplingAutoRefCountObjectPtr tmp(static_cast(m1D->deepCpy())); - tmp->changeSpaceDimension(3+(*lev),0.); - MEDCouplingAutoRefCountObjectPtr elt(item->buildExtrudedMesh(tmp,policy)); - zeList.push_back(elt); - if(*lev==0) - coords=elt->getCoords(); - } - if(!coords) - throw INTERP_KERNEL::Exception("MEDFileUMesh::buildExtrudedMesh : internal error !"); - for(std::vector< MEDCouplingAutoRefCountObjectPtr >::iterator it=zeList.begin();it!=zeList.end();it++) - { - (*it)->setName(getName()); - (*it)->setCoords(coords); - } - for(std::size_t ii=0;ii!=zeList.size();ii++) - { - int lev(levs[ii]); - MEDCouplingAutoRefCountObjectPtr elt(zeList[ii]); - if(lev<=-1) - { - MEDCouplingAutoRefCountObjectPtr elt1(getMeshAtLevel(lev+1)); - MEDCouplingAutoRefCountObjectPtr elt2(elt1->clone(false)); - MEDCouplingAutoRefCountObjectPtr tmp(elt2->getNodalConnectivity()->deepCpy()); - elt2->setConnectivity(tmp,elt2->getNodalConnectivityIndex()); - elt2->shiftNodeNumbersInConn(nbRep*elt1->getNumberOfNodes()); - elt1->setCoords(elt->getCoords()); elt2->setCoords(elt->getCoords()); - std::vector elts(3); - elts[0]=elt; elts[1]=elt1; elts[2]=elt2; - elt=MEDCouplingUMesh::MergeUMeshesOnSameCoords(elts); - elt->setName(getName()); - } - // - o2ns[ii]=elt->sortCellsInMEDFileFrmt(); - ret->setMeshAtLevel(lev,elt); - } - MEDCouplingAutoRefCountObjectPtr endLev(getMeshAtLevel(levs.back())),endLev2; - endLev=endLev->clone(false); endLev->setCoords(coords); - MEDCouplingAutoRefCountObjectPtr tmp(endLev->getNodalConnectivity()->deepCpy()); - endLev2=endLev->clone(false); endLev2->setConnectivity(tmp,endLev->getNodalConnectivityIndex()); - endLev2->shiftNodeNumbersInConn(nbRep*getNumberOfNodes()); - endLev=MEDCouplingUMesh::MergeUMeshesOnSameCoords(endLev,endLev2); - o2ns[levs.size()]=endLev->sortCellsInMEDFileFrmt(); - endLev->setName(getName()); - ret->setMeshAtLevel(levs.back()-1,endLev); - // - for(std::size_t ii=0;ii!=zeList.size();ii++) - { - int lev(levs[ii]); - std::vector< MEDCouplingAutoRefCountObjectPtr > outGrps; - std::vector< const DataArrayInt * > outGrps2; - if(lev<=-1) - { - for(std::vector::const_iterator grp=grps.begin();grp!=grps.end();grp++) - { - MEDCouplingAutoRefCountObjectPtr grpArr(getGroupArr(lev+1,*grp)); - if(!grpArr->empty()) - { - MEDCouplingAutoRefCountObjectPtr grpArr1(grpArr->deepCpy()),grpArr2(grpArr->deepCpy()); - int offset0(zeList[ii]->getNumberOfCells()); - int offset1(offset0+getNumberOfCellsAtLevel(lev+1)); - grpArr1->applyLin(1,offset0); grpArr2->applyLin(1,offset1); - std::ostringstream oss; oss << grpArr2->getName() << "_top"; - grpArr2->setName(oss.str()); - grpArr1->transformWithIndArr(o2ns[ii]->begin(),o2ns[ii]->end()); - grpArr2->transformWithIndArr(o2ns[ii]->begin(),o2ns[ii]->end()); - outGrps.push_back(grpArr1); outGrps.push_back(grpArr2); - outGrps2.push_back(grpArr1); outGrps2.push_back(grpArr2); - } - } - } - // - for(std::vector::const_iterator grp=grps.begin();grp!=grps.end();grp++) - { - MEDCouplingAutoRefCountObjectPtr grpArr(getGroupArr(lev,*grp)); - if(!grpArr->empty()) - { - int nbCellsB4Extrusion(getNumberOfCellsAtLevel(lev)); - std::vector< MEDCouplingAutoRefCountObjectPtr > grpArrs(nbRep); - std::vector< const DataArrayInt *> grpArrs2(nbRep); - for(int iii=0;iiideepCpy(); grpArrs[iii]->applyLin(1,iii*nbCellsB4Extrusion); - grpArrs2[iii]=grpArrs[iii]; - } - MEDCouplingAutoRefCountObjectPtr grpArrExt(DataArrayInt::Aggregate(grpArrs2)); - grpArrExt->transformWithIndArr(o2ns[ii]->begin(),o2ns[ii]->end()); - std::ostringstream grpName; grpName << *grp << "_extruded"; - grpArrExt->setName(grpName.str()); - outGrps.push_back(grpArrExt); - outGrps2.push_back(grpArrExt); - } - } - ret->setGroupsAtLevel(lev,outGrps2); - } - std::vector< MEDCouplingAutoRefCountObjectPtr > outGrps; - std::vector< const DataArrayInt * > outGrps2; - for(std::vector::const_iterator grp=grps.begin();grp!=grps.end();grp++) - { - MEDCouplingAutoRefCountObjectPtr grpArr1(getGroupArr(levs.back(),*grp)); - if(grpArr1->empty()) - continue; - MEDCouplingAutoRefCountObjectPtr grpArr2(grpArr1->deepCpy()); - std::ostringstream grpName; grpName << *grp << "_top"; - grpArr2->setName(grpName.str()); - grpArr2->applyLin(1,getNumberOfCellsAtLevel(levs.back())); - outGrps.push_back(grpArr1); outGrps.push_back(grpArr2); - outGrps2.push_back(grpArr1); outGrps2.push_back(grpArr2); - } - ret->setGroupsAtLevel(levs.back()-1,outGrps2); - return ret.retn(); -} - -/*! - * This method converts all linear cells in \a this into quadratic cells (following the \a conversionType policy). - * All the cells converted are put in the returned instance. This method applies all the groups and families in \a this to returned instance. - * Groups on nodes and families on nodes are copied directly to the returned instance without transformation. - * - * \param [in] conversionType - conversionType specifies the type of conversion expected. Only 0 (default) and 1 are supported presently. 0 those that creates the 'most' simple - * corresponding quadratic cells. 1 is those creating the 'most' complex. - * \param [in] eps - detection threshold for coordinates. - * \return A new instance that is the result of the conversion. The caller has the ownership of this returned instance. - * - * \sa MEDCouplingUMesh::convertLinearCellsToQuadratic , quadraticToLinear - */ -MEDFileUMesh *MEDFileUMesh::linearToQuadratic(int conversionType, double eps) const -{ - MEDCouplingAutoRefCountObjectPtr ret(MEDFileUMesh::New()); - int initialNbNodes(getNumberOfNodes()); - MEDCouplingAutoRefCountObjectPtr m0Tmp(getMeshAtLevel(0)); - MEDCouplingAutoRefCountObjectPtr m0(dynamic_cast(m0Tmp->deepCpy())); - { - MEDCouplingAutoRefCountObjectPtr notUsed(m0->convertLinearCellsToQuadratic(conversionType)); - } - DataArrayDouble *zeCoords(m0->getCoords()); - ret->setMeshAtLevel(0,m0); - std::vector levs(getNonEmptyLevels()); - const DataArrayInt *famField(getFamilyFieldAtLevel(0)); - if(famField) - { - MEDCouplingAutoRefCountObjectPtr famFieldCpy(famField->deepCpy()); - ret->setFamilyFieldArr(0,famFieldCpy); - } - famField=getFamilyFieldAtLevel(1); - if(famField) - { - MEDCouplingAutoRefCountObjectPtr fam(DataArrayInt::New()); fam->alloc(zeCoords->getNumberOfTuples(),1); - fam->fillWithZero(); - fam->setPartOfValues1(famField,0,initialNbNodes,1,0,1,1); - ret->setFamilyFieldArr(1,fam); - } - ret->copyFamGrpMapsFrom(*this); - MEDCouplingAutoRefCountObjectPtr partZeCoords(zeCoords->selectByTupleId2(initialNbNodes,zeCoords->getNumberOfTuples(),1)); - for(std::vector::const_iterator lev=levs.begin();lev!=levs.end();lev++) - { - if(*lev==0) - continue; - MEDCouplingAutoRefCountObjectPtr m1Tmp(getMeshAtLevel(*lev)); - MEDCouplingAutoRefCountObjectPtr m1(dynamic_cast(m1Tmp->deepCpy())); - if(m1->getMeshDimension()!=0) - { - { - MEDCouplingAutoRefCountObjectPtr notUsed(m1->convertLinearCellsToQuadratic(conversionType)); - }//kill unused notUsed var - MEDCouplingAutoRefCountObjectPtr m1Coords(m1->getCoords()->selectByTupleId2(initialNbNodes,m1->getNumberOfNodes(),1)); - DataArrayInt *b(0); - bool a(partZeCoords->areIncludedInMe(m1Coords,eps,b)); - MEDCouplingAutoRefCountObjectPtr bSafe(b); - if(!a) - { - std::ostringstream oss; oss << "MEDFileUMesh::linearCellsToQuadratic : for level " << *lev << " problem to identify nodes generated !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - b->applyLin(1,initialNbNodes); - MEDCouplingAutoRefCountObjectPtr l0(DataArrayInt::New()); l0->alloc(initialNbNodes,1); l0->iota(); - std::vector v(2); v[0]=l0; v[1]=b; - MEDCouplingAutoRefCountObjectPtr renum(DataArrayInt::Aggregate(v)); - m1->renumberNodesInConn(renum->begin()); - } - m1->setCoords(zeCoords); - ret->setMeshAtLevel(*lev,m1); - famField=getFamilyFieldAtLevel(*lev); - if(famField) - { - MEDCouplingAutoRefCountObjectPtr famFieldCpy(famField->deepCpy()); - ret->setFamilyFieldArr(*lev,famFieldCpy); - } - } - return ret.retn(); -} - -/*! - * This method converts all quadratic cells in \a this into linear cells. - * All the cells converted are put in the returned instance. This method applies all the groups and families in \a this to returned instance. - * Groups on nodes and families on nodes are copied directly to the returned instance without transformation. - * - * \param [in] eps - detection threshold for coordinates. - * \return A new instance that is the result of the conversion. The caller has the ownership of this returned instance. - * - * \sa MEDCouplingUMesh::convertLinearCellsToQuadratic , linearToQuadratic - */ -MEDFileUMesh *MEDFileUMesh::quadraticToLinear(double eps) const -{ - MEDCouplingAutoRefCountObjectPtr ret(MEDFileUMesh::New()); - MEDCouplingAutoRefCountObjectPtr m0Tmp(getMeshAtLevel(0)); - MEDCouplingAutoRefCountObjectPtr m0(dynamic_cast(m0Tmp->deepCpy())); - m0->convertQuadraticCellsToLinear(); - m0->zipCoords(); - DataArrayDouble *zeCoords(m0->getCoords()); - ret->setMeshAtLevel(0,m0); - std::vector levs(getNonEmptyLevels()); - const DataArrayInt *famField(getFamilyFieldAtLevel(0)); - if(famField) - { - MEDCouplingAutoRefCountObjectPtr famFieldCpy(famField->deepCpy()); - ret->setFamilyFieldArr(0,famFieldCpy); - } - famField=getFamilyFieldAtLevel(1); - if(famField) - { - MEDCouplingAutoRefCountObjectPtr fam(famField->selectByTupleId2(0,zeCoords->getNumberOfTuples(),1)); - ret->setFamilyFieldArr(1,fam); - } - ret->copyFamGrpMapsFrom(*this); - for(std::vector::const_iterator lev=levs.begin();lev!=levs.end();lev++) - { - if(*lev==0) - continue; - MEDCouplingAutoRefCountObjectPtr m1Tmp(getMeshAtLevel(*lev)); - MEDCouplingAutoRefCountObjectPtr m1(dynamic_cast(m1Tmp->deepCpy())); - m1->convertQuadraticCellsToLinear(); - m1->zipCoords(); - DataArrayInt *b(0); - bool a(zeCoords->areIncludedInMe(m1->getCoords(),eps,b)); - MEDCouplingAutoRefCountObjectPtr bSafe(b); - if(!a) - { - std::ostringstream oss; oss << "MEDFileUMesh::quadraticToLinear : for level " << *lev << " problem to identify nodes generated !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - m1->renumberNodesInConn(b->begin()); - m1->setCoords(zeCoords); - ret->setMeshAtLevel(*lev,m1); - famField=getFamilyFieldAtLevel(*lev); - if(famField) - { - MEDCouplingAutoRefCountObjectPtr famFieldCpy(famField->deepCpy()); - ret->setFamilyFieldArr(*lev,famFieldCpy); - } - } - return ret.retn(); -} - -void MEDFileUMesh::serialize(std::vector& tinyDouble, std::vector& tinyInt, std::vector& tinyStr, std::vector< MEDCouplingAutoRefCountObjectPtr >& bigArraysI, MEDCouplingAutoRefCountObjectPtr& bigArrayD) -{ - clearNonDiscrAttributes(); - forceComputationOfParts(); - tinyDouble.clear(); tinyInt.clear(); tinyStr.clear(); bigArraysI.clear(); bigArrayD=0; - std::vector layer0; - layer0.push_back(_order); //0 i - layer0.push_back(_iteration);//1 i - layer0.push_back(getSpaceDimension());//2 i - tinyDouble.push_back(_time);//0 d - tinyStr.push_back(_name);//0 s - tinyStr.push_back(_desc_name);//1 s - for(int i=0;igetInfoOnComponent(i)); - layer0.push_back((int)_families.size());//3 i <- key info aa layer#0 - for(std::map::const_iterator it=_families.begin();it!=_families.end();it++) - { - tinyStr.push_back((*it).first); - layer0.push_back((*it).second); - } - layer0.push_back((int)_groups.size());//3+aa i <- key info bb layer#0 - for(std::map >::const_iterator it0=_groups.begin();it0!=_groups.end();it0++) - { - layer0.push_back((int)(*it0).second.size()); - tinyStr.push_back((*it0).first); - for(std::vector::const_iterator it1=((*it0).second).begin();it1!=((*it0).second).end();it1++) - tinyStr.push_back(*it1); - } - // sizeof(layer0)==3+aa+1+bb layer#0 - bigArrayD=_coords;// 0 bd - bigArraysI.push_back(_fam_coords);// 0 bi - bigArraysI.push_back(_num_coords);// 1 bi - const PartDefinition *pd(_part_coords); - if(!pd) - layer0.push_back(-1); - else - { - std::vector tmp0; - pd->serialize(tmp0,bigArraysI); - tinyInt.push_back(tmp0.size()); - tinyInt.insert(tinyInt.end(),tmp0.begin(),tmp0.end()); - } - // - std::vector layer1; - std::vector levs(getNonEmptyLevels()); - layer1.push_back((int)levs.size());// 0 i <- key - layer1.insert(layer1.end(),levs.begin(),levs.end()); - for(std::vector::const_iterator it=levs.begin();it!=levs.end();it++) - { - const MEDFileUMeshSplitL1 *lev(getMeshAtLevSafe(*it)); - lev->serialize(layer1,bigArraysI); - } - // put layers all together. - tinyInt.push_back(layer0.size()); - tinyInt.insert(tinyInt.end(),layer0.begin(),layer0.end()); - tinyInt.push_back(layer1.size()); - tinyInt.insert(tinyInt.end(),layer1.begin(),layer1.end()); -} - -void MEDFileUMesh::unserialize(std::vector& tinyDouble, std::vector& tinyInt, std::vector& tinyStr, - std::vector< MEDCouplingAutoRefCountObjectPtr >& bigArraysI, MEDCouplingAutoRefCountObjectPtr& bigArrayD) -{ - int sz0(tinyInt[0]); - std::vector layer0(tinyInt.begin()+1,tinyInt.begin()+1+sz0); - int sz1(tinyInt[sz0+1]); - std::vector layer1(tinyInt.begin()+2+sz0,tinyInt.begin()+2+sz0+sz1); - // - std::reverse(layer0.begin(),layer0.end()); - std::reverse(layer1.begin(),layer1.end()); - std::reverse(tinyDouble.begin(),tinyDouble.end()); - std::reverse(tinyStr.begin(),tinyStr.end()); - std::reverse(bigArraysI.begin(),bigArraysI.end()); - // - _order=layer0.back(); layer0.pop_back(); - _iteration=layer0.back(); layer0.pop_back(); - int spaceDim(layer0.back()); layer0.pop_back(); - _time=tinyDouble.back(); tinyDouble.pop_back(); - _name=tinyStr.back(); tinyStr.pop_back(); - _desc_name=tinyStr.back(); tinyStr.pop_back(); - _coords=bigArrayD; _coords->rearrange(spaceDim); - for(int i=0;isetInfoOnComponent(i,tinyStr.back()); - tinyStr.pop_back(); - } - int nbOfFams(layer0.back()); layer0.pop_back(); - _families.clear(); - for(int i=0;i fams(nbOfFamsOnGrp); - for(int j=0;j tmp0(layer0.begin(),layer0.begin()+isPd); - layer0.erase(layer0.begin(),layer0.begin()+isPd); - _part_coords=PartDefinition::Unserialize(tmp0,bigArraysI); - } - if(!layer0.empty()) - throw INTERP_KERNEL::Exception("MEDFileUMesh::unserialize : something wrong during unserialization #1 !"); - // - int nbLevs(layer1.back()); layer1.pop_back(); - std::vector levs(layer1.rbegin(),layer1.rbegin()+nbLevs); layer1.erase(layer1.end()-nbLevs,layer1.end()); - _ms.clear(); - int maxLev(-(*std::min_element(levs.begin(),levs.end()))); - _ms.resize(maxLev+1); - for(int i=0;igetName() == "". - * \throw If \a ids does not respect the MED file norm. - * \throw If a group with name \a ids->getName() already exists. - */ -void MEDFileUMesh::addNodeGroup(const DataArrayInt *ids) -{ - const DataArrayDouble *coords(_coords); - if(!coords) - throw INTERP_KERNEL::Exception("MEDFileUMesh::addNodeGroup : no coords set !"); - int nbOfNodes(coords->getNumberOfTuples()); - if(!((DataArrayInt *)_fam_coords)) - { _fam_coords=DataArrayInt::New(); _fam_coords->alloc(nbOfNodes,1); _fam_coords->fillWithZero(); } - // - addGroupUnderground(true,ids,_fam_coords); -} - -/*! - * Adds a group of nodes/cells/faces/edges to \a this mesh. - * - * \param [in] ids - a DataArrayInt providing ids and a name of the group to add. - * The ids should be sorted and different each other (MED file norm). - * - * \warning this method can alter default "FAMILLE_ZERO" family. - * For users sensitive to this a call to MEDFileMesh::rearrangeFamilies will be necessary after addGroup session. - * - * \throw If the node coordinates array is not set. - * \throw If \a ids == \c NULL. - * \throw If \a ids->getName() == "". - * \throw If \a ids does not respect the MED file norm. - * \throw If a group with name \a ids->getName() already exists. - */ -void MEDFileUMesh::addGroup(int meshDimRelToMaxExt, const DataArrayInt *ids) -{ - std::vector levs(getNonEmptyLevelsExt()); - if(std::find(levs.begin(),levs.end(),meshDimRelToMaxExt)==levs.end()) - { - std::ostringstream oss; oss << "MEDFileUMesh::addGroup : level " << meshDimRelToMaxExt << " not available ! Should be in "; - std::copy(levs.begin(),levs.end(),std::ostream_iterator(oss," ")); oss << " !"; throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - if(meshDimRelToMaxExt==1) - { addNodeGroup(ids); return ; } - MEDFileUMeshSplitL1 *lev(getMeshAtLevSafe(meshDimRelToMaxExt)); - DataArrayInt *fam(lev->getOrCreateAndGetFamilyField()); - addGroupUnderground(false,ids,fam); -} - -/*! - * Changes a name of a family specified by its id. - * \param [in] id - the id of the family of interest. - * \param [in] newFamName - the new family name. - * \throw If no family with the given \a id exists. - */ -void MEDFileUMesh::setFamilyNameAttachedOnId(int id, const std::string& newFamName) -{ - std::string oldName=getFamilyNameGivenId(id); - _families.erase(oldName); - _families[newFamName]=id; -} - -/*! - * Removes a mesh of a given dimension. - * \param [in] meshDimRelToMax - the relative dimension of interest. - * \throw If there is no mesh at level \a meshDimRelToMax in \a this mesh. - */ -void MEDFileUMesh::removeMeshAtLevel(int meshDimRelToMax) -{ - std::vector levSet=getNonEmptyLevels(); - std::vector::const_iterator it=std::find(levSet.begin(),levSet.end(),meshDimRelToMax); - if(it==levSet.end()) - throw INTERP_KERNEL::Exception("MEDFileUMesh::removeMeshAtLevel : the requested level is not existing !"); - int pos=(-meshDimRelToMax); - _ms[pos]=0; -} - -/*! - * Sets a new MEDCoupling1GTUMesh at a given level in \a this mesh. - * \param [in] meshDimRelToMax - a relative level to set the mesh at. - * \param [in] m - the new mesh to set. - * \throw If the name or the description of \a this mesh and \a m are not empty and are - * different. - * \throw If the node coordinates array is set \a this in mesh and \a m refers to - * another node coordinates array. - * \throw If the mesh dimension of \a m does not correspond to \a meshDimRelToMax or - * to the existing meshes of other levels of \a this mesh. - */ -void MEDFileUMesh::setMeshAtLevel(int meshDimRelToMax, MEDCoupling1GTUMesh *m) -{ - MEDCouplingAutoRefCountObjectPtr elt(new MEDFileUMeshSplitL1(m)); - checkAndGiveEntryInSplitL1(meshDimRelToMax,m)=elt; -} - -/*! - * Sets a new MEDCouplingUMesh at a given level in \a this mesh. - * \param [in] meshDimRelToMax - a relative level to set the mesh at. - * \param [in] m - the new mesh to set. - * \param [in] newOrOld - if \c true, cells in \a m are sorted by type to be ready for - * writing \a this mesh in a MED file. - * \throw If the name or the description of \a this mesh and \a m are not empty and are - * different. - * \throw If the node coordinates array is set \a this in mesh and \a m refers to - * another node coordinates array. - * \throw If the mesh dimension of \a m does not correspond to \a meshDimRelToMax or - * to the existing meshes of other levels of \a this mesh. - */ -void MEDFileUMesh::setMeshAtLevel(int meshDimRelToMax, MEDCouplingUMesh *m, bool newOrOld) -{ - MEDCouplingAutoRefCountObjectPtr elt(new MEDFileUMeshSplitL1(m,newOrOld)); - checkAndGiveEntryInSplitL1(meshDimRelToMax,m)=elt; -} - -MEDCouplingAutoRefCountObjectPtr& MEDFileUMesh::checkAndGiveEntryInSplitL1(int meshDimRelToMax, MEDCouplingPointSet *m) -{ - dealWithTinyInfo(m); - std::vector levSet=getNonEmptyLevels(); - if(std::find(levSet.begin(),levSet.end(),meshDimRelToMax)==levSet.end()) - { - if((DataArrayDouble *)_coords==0) - { - DataArrayDouble *c=m->getCoords(); - if(c) - c->incrRef(); - _coords=c; - } - if(m->getCoords()!=_coords) - throw INTERP_KERNEL::Exception("MEDFileUMesh::setMeshAtLevel : Invalid Given Mesh ! The coordinates are not the same ! try to use tryToShareSameCoords !"); - int sz=(-meshDimRelToMax)+1; - if(sz>=(int)_ms.size()) - _ms.resize(sz); - checkMeshDimCoherency(m->getMeshDimension(),meshDimRelToMax); - return _ms[sz-1]; - } - else - return _ms[-meshDimRelToMax]; -} - -/*! - * This method allows to set at once the content of different levels in \a this. - * This method is equivalent to a series of call to MEDFileUMesh::setMeshAtLevel. - * - * \param [in] ms - List of unstructured meshes lying on the same coordinates and having different mesh dimesnion. - * \param [in] renum - the parameter (set to false by default) that tells the beheviour if there is a mesh on \a ms that is not geo type sorted. - * If false, an exception ois thrown. If true the mesh is reordered automatically. It is highly recommanded to let this parameter to false. - * - * \throw If \a there is a null pointer in \a ms. - * \sa MEDFileUMesh::setMeshAtLevel - */ -void MEDFileUMesh::setMeshes(const std::vector& ms, bool renum) -{ - if(ms.empty()) - return ; - const MEDCouplingUMesh *mRef=ms[0]; - if(!mRef) - throw INTERP_KERNEL::Exception("MEDFileUMesh::setMeshes : null instance in the first element of input meshes !"); - std::string name(mRef->getName()); - const DataArrayDouble *coo(mRef->getCoords()); - std::set s; - int zeDim=-1; - for(std::vector::const_iterator it=ms.begin();it!=ms.end();it++) - { - const MEDCouplingUMesh *cur(*it); - if(!cur) - throw INTERP_KERNEL::Exception("MEDFileUMesh::setMeshes : null instance in input vector of meshes !"); - if(coo!=cur->getCoords()) - throw INTERP_KERNEL::Exception("MEDFileUMesh::setMeshes : The input meshes do not share the same coordinates !"); - int mdim=cur->getMeshDimension(); - zeDim=std::max(zeDim,mdim); - if(s.find(mdim)!=s.end()) - throw INTERP_KERNEL::Exception("MEDFileUMesh::setMeshes : The input meshes must share the same coordinates pointer, and should have different mesh dimension each other !"); - } - for(std::vector::const_iterator it=ms.begin();it!=ms.end();it++) - { - int mdim=(*it)->getMeshDimension(); - setName((*it)->getName()); - setMeshAtLevel(mdim-zeDim,const_cast(*it),renum); - } - setName(name); -} - -/*! - * Creates one MEDCouplingUMesh at a given level in \a this mesh from a sequence of - * meshes each representing a group, and creates corresponding groups in \a this mesh. - * The given meshes must share the same node coordinates array. - * \param [in] meshDimRelToMax - the relative dimension to create the mesh and groups at. - * \param [in] ms - the sequence of meshes. Each mesh in \a ms represents a group to - * create in \a this mesh. - * \throw If \a ms is empty. - * \throw If dimension of meshes in \a ms does not correspond to \a meshDimRelToMax or - * to the existing meshes of other levels of \a this mesh. - * \throw If the meshes in \a ms do not share the same node coordinates array. - * \throw If the node coordinates array of \a this mesh (if any) is not the same as that - * of the given meshes. - * \throw If \a ms[ i ] is not well defined (MEDCouplingUMesh::checkCoherency()). - * \throw If names of some meshes in \a ms are equal. - * \throw If \a ms includes a mesh with an empty name. - */ -void MEDFileUMesh::setGroupsFromScratch(int meshDimRelToMax, const std::vector& ms, bool renum) -{ - if(ms.empty()) - throw INTERP_KERNEL::Exception("MEDFileUMesh::setGroupsFromScratch : expecting a non empty vector !"); - int sz=(-meshDimRelToMax)+1; - if(sz>=(int)_ms.size()) - _ms.resize(sz); - checkMeshDimCoherency(ms[0]->getMeshDimension(),meshDimRelToMax); - DataArrayDouble *coo=checkMultiMesh(ms); - if((DataArrayDouble *)_coords==0) - { - coo->incrRef(); - _coords=coo; - } - else - if((DataArrayDouble *)_coords!=coo) - throw INTERP_KERNEL::Exception("MEDFileUMesh::setGroupsFromScratch : coordinates mismatches !"); - std::vector corr; - MEDCouplingAutoRefCountObjectPtr m=MEDCouplingUMesh::FuseUMeshesOnSameCoords(ms,_zipconn_pol,corr); - std::vector< MEDCouplingAutoRefCountObjectPtr > corr3(corr.begin(),corr.end()); - setMeshAtLevel(meshDimRelToMax,m,renum); - std::vector corr2(corr.begin(),corr.end()); - setGroupsAtLevel(meshDimRelToMax,corr2,true); -} - -/*! - * Creates groups at a given level in \a this mesh from a sequence of - * meshes each representing a group. - * The given meshes must share the same node coordinates array. - * \param [in] meshDimRelToMax - the relative dimension to create the groups at. - * \param [in] ms - the sequence of meshes. Each mesh in \a ms represents a group to - * create in \a this mesh. - * \param [in] renum - if \c true, then the optional numbers of entities are taken into - * account. - * \throw If \a ms is empty. - * \throw If dimension of meshes in \a ms does not correspond to \a meshDimRelToMax or - * to the existing meshes of other levels of \a this mesh. - * \throw If the meshes in \a ms do not share the same node coordinates array. - * \throw If the node coordinates array of \a this mesh (if any) is not the same as that - * of the given meshes. - * \throw If \a ms[ i ] is not well defined (MEDCouplingUMesh::checkCoherency()). - * \throw If names of some meshes in \a ms are equal. - * \throw If \a ms includes a mesh with an empty name. - */ -void MEDFileUMesh::setGroupsOnSetMesh(int meshDimRelToMax, const std::vector& ms, bool renum) -{ - if(ms.empty()) - throw INTERP_KERNEL::Exception("MEDFileUMesh::setGroupsOnSetMesh : expecting a non empty vector !"); - int sz=(-meshDimRelToMax)+1; - if(sz>=(int)_ms.size()) - _ms.resize(sz); - checkMeshDimCoherency(ms[0]->getMeshDimension(),meshDimRelToMax); - DataArrayDouble *coo=checkMultiMesh(ms); - if((DataArrayDouble *)_coords==0) - { - coo->incrRef(); - _coords=coo; - } - else - if((DataArrayDouble *)_coords!=coo) - throw INTERP_KERNEL::Exception("MEDFileUMesh::setGroupsOnSetMesh : coordinates mismatches !"); - MEDCouplingUMesh *m=getMeshAtLevel(meshDimRelToMax,renum); - std::vector< MEDCouplingAutoRefCountObjectPtr > corr(ms.size()); - int i=0; - for(std::vector::const_iterator it=ms.begin();it!=ms.end();it++,i++) - { - DataArrayInt *arr=0; - bool test=m->areCellsIncludedIn(*it,_zipconn_pol,arr); - corr[i]=arr; - if(!test) - { - std::ostringstream oss; oss << "MEDFileUMesh::setGroupsOnSetMesh : mesh #" << i << " is not part of whole mesh !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - } - std::vector corr2(corr.begin(),corr.end()); - setGroupsAtLevel(meshDimRelToMax,corr2,renum); -} - -DataArrayDouble *MEDFileUMesh::checkMultiMesh(const std::vector& ms) const -{ - const DataArrayDouble *ret=ms[0]->getCoords(); - int mdim=ms[0]->getMeshDimension(); - for(unsigned int i=1;icheckCoherency(); - if(ms[i]->getCoords()!=ret) - throw INTERP_KERNEL::Exception("MEDFileUMesh::checkMultiMesh : meshes must share the same coords !"); - if(ms[i]->getMeshDimension()!=mdim) - throw INTERP_KERNEL::Exception("MEDFileUMesh::checkMultiMesh : meshes have not same mesh dimension !"); - } - return const_cast(ret); -} - -/*! - * 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 MEDFileUMesh::setFamilyFieldArr(int meshDimRelToMaxExt, DataArrayInt *famArr) -{ - if(meshDimRelToMaxExt==1) - { - if(!famArr) - { - _fam_coords=0; - return ; - } - DataArrayDouble *coo(_coords); - if(!coo) - throw INTERP_KERNEL::Exception("MEDFileUMesh::setFamilyFieldArr : the coordinates have not been set !"); - famArr->checkNbOfTuplesAndComp(coo->getNumberOfTuples(),1,"MEDFileUMesh::setFamilyFieldArr : Problem in size of node family arr ! "); - famArr->incrRef(); - _fam_coords=famArr; - return ; - } - if(meshDimRelToMaxExt>1) - throw INTERP_KERNEL::Exception("MEDFileUMesh::setFamilyFieldArr : Dimension request is invalid (>1) !"); - int traducedRk=-meshDimRelToMaxExt; - if(traducedRk>=(int)_ms.size()) - throw INTERP_KERNEL::Exception("Invalid mesh dim relative to max given ! Too low !"); - if((MEDFileUMeshSplitL1 *)_ms[traducedRk]==0) - throw INTERP_KERNEL::Exception("On specified lev (or entity) no cells exists !"); - return _ms[traducedRk]->setFamilyArr(famArr); -} - -/*! - * 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 MEDFileUMesh::setRenumFieldArr(int meshDimRelToMaxExt, DataArrayInt *renumArr) -{ - if(meshDimRelToMaxExt==1) - { - if(!renumArr) - { - _num_coords=0; - _rev_num_coords=0; - return ; - } - DataArrayDouble *coo(_coords); - if(!coo) - throw INTERP_KERNEL::Exception("MEDFileUMesh::setRenumFieldArr : the coordinates have not been set !"); - renumArr->checkNbOfTuplesAndComp(coo->getNumberOfTuples(),1,"MEDFileUMesh::setRenumArr : Problem in size of node numbering arr ! "); - renumArr->incrRef(); - _num_coords=renumArr; - computeRevNum(); - return ; - } - if(meshDimRelToMaxExt>1) - throw INTERP_KERNEL::Exception("MEDFileUMesh::setRenumArr : Dimension request is invalid (>1) !"); - int traducedRk=-meshDimRelToMaxExt; - if(traducedRk>=(int)_ms.size()) - throw INTERP_KERNEL::Exception("Invalid mesh dim relative to max given ! Too low !"); - if((MEDFileUMeshSplitL1 *)_ms[traducedRk]==0) - throw INTERP_KERNEL::Exception("On specified lev (or entity) no cells exists !"); - return _ms[traducedRk]->setRenumArr(renumArr); -} - -/*! - * Sets the optional names of mesh entities of a given dimension. - * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities. - * \param [in] nameArr - the array of the names. - * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh. - * \throw If \a nameArr has an invalid size. - */ -void MEDFileUMesh::setNameFieldAtLevel(int meshDimRelToMaxExt, DataArrayAsciiChar *nameArr) -{ - if(meshDimRelToMaxExt==1) - { - if(!nameArr) - { - _name_coords=0; - return ; - } - DataArrayDouble *coo(_coords); - if(!coo) - throw INTERP_KERNEL::Exception("MEDFileUMesh::setNameFieldAtLevel : the coordinates have not been set !"); - nameArr->checkNbOfTuplesAndComp(coo->getNumberOfTuples(),MED_SNAME_SIZE,"MEDFileUMesh::setNameFieldAtLevel : Problem in size of node numbering arr ! "); - nameArr->incrRef(); - _name_coords=nameArr; - return ; - } - if(meshDimRelToMaxExt>1) - throw INTERP_KERNEL::Exception("MEDFileUMesh::setNameFieldAtLevel : Dimension request is invalid (>1) !"); - int traducedRk=-meshDimRelToMaxExt; - if(traducedRk>=(int)_ms.size()) - throw INTERP_KERNEL::Exception("Invalid mesh dim relative to max given ! Too low !"); - if((MEDFileUMeshSplitL1 *)_ms[traducedRk]==0) - throw INTERP_KERNEL::Exception("On specified lev (or entity) no cells exists !"); - return _ms[traducedRk]->setNameArr(nameArr); -} - -void MEDFileUMesh::synchronizeTinyInfoOnLeaves() const -{ - for(std::vector< MEDCouplingAutoRefCountObjectPtr >::const_iterator it=_ms.begin();it!=_ms.end();it++) - if((const MEDFileUMeshSplitL1 *)(*it)) - (*it)->synchronizeTinyInfo(*this); -} - -/*! - * This method is called by MEDFileMesh::changeFamilyId. It performs only one part of the family id modification. - */ -void MEDFileUMesh::changeFamilyIdArr(int oldId, int newId) -{ - DataArrayInt *arr=_fam_coords; - if(arr) - arr->changeValue(oldId,newId); - for(std::vector< MEDCouplingAutoRefCountObjectPtr >::iterator it=_ms.begin();it!=_ms.end();it++) - { - MEDFileUMeshSplitL1 *sp=(*it); - if(sp) - { - sp->changeFamilyIdArr(oldId,newId); - } - } -} - -std::list< MEDCouplingAutoRefCountObjectPtr > MEDFileUMesh::getAllNonNullFamilyIds() const -{ - std::list< MEDCouplingAutoRefCountObjectPtr > ret; - const DataArrayInt *da(_fam_coords); - if(da) - { da->incrRef(); ret.push_back(MEDCouplingAutoRefCountObjectPtr(const_cast(da))); } - for(std::vector< MEDCouplingAutoRefCountObjectPtr >::const_iterator it=_ms.begin();it!=_ms.end();it++) - { - const MEDFileUMeshSplitL1 *elt(*it); - if(elt) - { - da=elt->getFamilyField(); - if(da) - { da->incrRef(); ret.push_back(MEDCouplingAutoRefCountObjectPtr(const_cast(da))); } - } - } - return ret; -} - -void MEDFileUMesh::computeRevNum() const -{ - if((const DataArrayInt *)_num_coords) - { - int pos; - int maxValue=_num_coords->getMaxValue(pos); - _rev_num_coords=_num_coords->invertArrayN2O2O2N(maxValue+1); - } -} - -std::size_t MEDFileStructuredMesh::getHeapMemorySizeWithoutChildren() const -{ - return MEDFileMesh::getHeapMemorySizeWithoutChildren(); -} - -std::vector MEDFileStructuredMesh::getDirectChildrenWithNull() const -{ - std::vector ret(MEDFileMesh::getDirectChildrenWithNull()); - ret.push_back((const DataArrayInt *)_fam_nodes); - ret.push_back((const DataArrayInt *)_num_nodes); - ret.push_back((const DataArrayAsciiChar *)_names_nodes); - ret.push_back((const DataArrayInt *)_fam_cells); - ret.push_back((const DataArrayInt *)_num_cells); - ret.push_back((const DataArrayAsciiChar *)_names_cells); - ret.push_back((const DataArrayInt *)_fam_faces); - ret.push_back((const DataArrayInt *)_num_faces); - ret.push_back((const DataArrayInt *)_rev_num_nodes); - ret.push_back((const DataArrayAsciiChar *)_names_faces); - ret.push_back((const DataArrayInt *)_rev_num_cells); - ret.push_back((const MEDCoupling1SGTUMesh*)_faces_if_necessary); - return ret; -} - -int MEDFileStructuredMesh::getMaxAbsFamilyIdInArrays() const -{ - int ret=-std::numeric_limits::max(),tmp=-1; - if((const DataArrayInt *)_fam_nodes) - { - int val=_fam_nodes->getMaxValue(tmp); - ret=std::max(ret,std::abs(val)); - } - if((const DataArrayInt *)_fam_cells) - { - int val=_fam_cells->getMaxValue(tmp); - ret=std::max(ret,std::abs(val)); - } - if((const DataArrayInt *)_fam_faces) - { - int val=_fam_faces->getMaxValue(tmp); - ret=std::max(ret,std::abs(val)); - } - return ret; -} - -int MEDFileStructuredMesh::getMaxFamilyIdInArrays() const -{ - int ret=-std::numeric_limits::max(),tmp=-1; - if((const DataArrayInt *)_fam_nodes) - { - int val=_fam_nodes->getMaxValue(tmp); - ret=std::max(ret,val); - } - if((const DataArrayInt *)_fam_cells) - { - int val=_fam_cells->getMaxValue(tmp); - ret=std::max(ret,val); - } - if((const DataArrayInt *)_fam_faces) - { - int val=_fam_faces->getMaxValue(tmp); - ret=std::max(ret,val); - } - return ret; -} - -int MEDFileStructuredMesh::getMinFamilyIdInArrays() const -{ - int ret=std::numeric_limits::max(),tmp=-1; - if((const DataArrayInt *)_fam_nodes) - { - int val=_fam_nodes->getMinValue(tmp); - ret=std::min(ret,val); - } - if((const DataArrayInt *)_fam_cells) - { - int val=_fam_cells->getMinValue(tmp); - ret=std::min(ret,val); - } - if((const DataArrayInt *)_fam_faces) - { - int val=_fam_faces->getMinValue(tmp); - ret=std::min(ret,val); - } - return ret; -} - -bool MEDFileStructuredMesh::isEqual(const MEDFileMesh *other, double eps, std::string& what) const -{ - if(!MEDFileMesh::isEqual(other,eps,what)) - return false; - const MEDFileStructuredMesh *otherC=dynamic_cast(other); - if(!otherC) - { - what="Mesh types differ ! This is structured and other is NOT !"; - return false; - } - const DataArrayInt *famc1=_fam_nodes; - const DataArrayInt *famc2=otherC->_fam_nodes; - if((famc1==0 && famc2!=0) || (famc1!=0 && famc2==0)) - { - what="Mismatch of families arr on nodes ! One is defined and not other !"; - return false; - } - if(famc1) - { - bool ret=famc1->isEqual(*famc2); - if(!ret) - { - what="Families arr on nodes differ !"; - return false; - } - } - famc1=_fam_cells; - famc2=otherC->_fam_cells; - if((famc1==0 && famc2!=0) || (famc1!=0 && famc2==0)) - { - what="Mismatch of families arr on cells ! One is defined and not other !"; - return false; - } - if(famc1) - { - bool ret=famc1->isEqual(*famc2); - if(!ret) - { - what="Families arr on cells differ !"; - return false; - } - } - famc1=_fam_faces; - famc2=otherC->_fam_faces; - if((famc1==0 && famc2!=0) || (famc1!=0 && famc2==0)) - { - what="Mismatch of families arr on faces ! One is defined and not other !"; - return false; - } - if(famc1) - { - bool ret=famc1->isEqual(*famc2); - if(!ret) - { - what="Families arr on faces differ !"; - return false; - } - } - famc1=_num_nodes; - famc2=otherC->_num_nodes; - if((famc1==0 && famc2!=0) || (famc1!=0 && famc2==0)) - { - what="Mismatch of numbering arr on nodes ! One is defined and not other !"; - return false; - } - if(famc1) - { - bool ret=famc1->isEqual(*famc2); - if(!ret) - { - what="Numbering arr on nodes differ !"; - return false; - } - } - famc1=_num_cells; - famc2=otherC->_num_cells; - if((famc1==0 && famc2!=0) || (famc1!=0 && famc2==0)) - { - what="Mismatch of numbering arr on cells ! One is defined and not other !"; - return false; - } - if(famc1) - { - bool ret=famc1->isEqual(*famc2); - if(!ret) - { - what="Numbering arr on cells differ !"; - return false; - } - } - famc1=_num_faces; - famc2=otherC->_num_faces; - if((famc1==0 && famc2!=0) || (famc1!=0 && famc2==0)) - { - what="Mismatch of numbering arr on faces ! One is defined and not other !"; - return false; - } - if(famc1) - { - bool ret=famc1->isEqual(*famc2); - if(!ret) - { - what="Numbering arr on faces differ !"; - return false; - } - } - const DataArrayAsciiChar *d1=_names_cells; - const DataArrayAsciiChar *d2=otherC->_names_cells; - if((d1==0 && d2!=0) || (d1!=0 && d2==0)) - { - what="Mismatch of naming arr on cells ! One is defined and not other !"; - return false; - } - if(d1) - { - bool ret=d1->isEqual(*d2); - if(!ret) - { - what="Naming arr on cells differ !"; - return false; - } - } - d1=_names_faces; - d2=otherC->_names_faces; - if((d1==0 && d2!=0) || (d1!=0 && d2==0)) - { - what="Mismatch of naming arr on faces ! One is defined and not other !"; - return false; - } - if(d1) - { - bool ret=d1->isEqual(*d2); - if(!ret) - { - what="Naming arr on faces differ !"; - return false; - } - } - d1=_names_nodes; - d2=otherC->_names_nodes; - if((d1==0 && d2!=0) || (d1!=0 && d2==0)) - { - what="Mismatch of naming arr on nodes ! One is defined and not other !"; - return false; - } - if(d1) - { - bool ret=d1->isEqual(*d2); - if(!ret) - { - what="Naming arr on nodes differ !"; - return false; - } - } - return true; -} - -void MEDFileStructuredMesh::clearNonDiscrAttributes() const -{ - MEDFileMesh::clearNonDiscrAttributes(); - const DataArrayInt *tmp=_fam_nodes; - if(tmp) - (const_cast(tmp))->setName(""); - tmp=_num_nodes; - if(tmp) - (const_cast(tmp))->setName(""); - tmp=_fam_cells; - if(tmp) - (const_cast(tmp))->setName(""); - tmp=_num_cells; - if(tmp) - (const_cast(tmp))->setName(""); - tmp=_fam_faces; - if(tmp) - (const_cast(tmp))->setName(""); - tmp=_num_faces; - if(tmp) - (const_cast(tmp))->setName(""); -} - -/*! - * 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 *MEDFileStructuredMesh::getFamiliesArr(int meshDimRelToMaxExt, const std::vector& fams, bool renum) const -{ - std::vector famIds(getFamiliesIds(fams)); - switch(meshDimRelToMaxExt) - { - case 1: - { - if((const DataArrayInt *)_fam_nodes) - { - MEDCouplingAutoRefCountObjectPtr da; - if(!famIds.empty()) - da=_fam_nodes->getIdsEqualList(&famIds[0],&famIds[0]+famIds.size()); - else - da=_fam_nodes->getIdsEqualList(0,0); - if(renum) - return MEDFileUMeshSplitL1::Renumber(_num_nodes,da); - else - return da.retn(); - } - else - throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getFamiliesArr : no family array specified on nodes !"); - break; - } - case 0: - { - if((const DataArrayInt *)_fam_cells) - { - MEDCouplingAutoRefCountObjectPtr da; - if(!famIds.empty()) - da=_fam_cells->getIdsEqualList(&famIds[0],&famIds[0]+famIds.size()); - else - da=_fam_cells->getIdsEqualList(0,0); - if(renum) - return MEDFileUMeshSplitL1::Renumber(_num_cells,da); - else - return da.retn(); - } - else - throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getFamiliesArr : no family array specified on cells !"); - break; - } - case -1: - { - if((const DataArrayInt *)_fam_faces) - { - MEDCouplingAutoRefCountObjectPtr da; - if(!famIds.empty()) - da=_fam_faces->getIdsEqualList(&famIds[0],&famIds[0]+famIds.size()); - else - da=_fam_faces->getIdsEqualList(0,0); - if(renum) - return MEDFileUMeshSplitL1::Renumber(_num_faces,da); - else - return da.retn(); - } - else - throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getFamiliesArr : no family array specified on faces !"); - break; - } - default: - throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getFamiliesArr : input meshDimRelative must be in [0,1,-1] !"); - } - throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getFamiliesArr : unmanaged case !"); -} - -/*! - * 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. - * \throw If \a meshDimRelToMaxExt != 0 and \a meshDimRelToMaxExt != 1 and \a meshDimRelToMaxExt != -1. - */ -void MEDFileStructuredMesh::setFamilyFieldArr(int meshDimRelToMaxExt, DataArrayInt *famArr) -{ - const MEDCouplingStructuredMesh *mesh(getStructuredMesh()); - if(!mesh) - throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::setFamilyFieldArr : no structured mesh specified ! Impossible to set family array !"); - switch(meshDimRelToMaxExt) - { - case 0: - { - int nbCells=mesh->getNumberOfCells(); - famArr->checkNbOfTuplesAndComp(nbCells,1,"MEDFileStructuredMesh::setFamilyFieldArr : Problem in size of Family arr ! Mismatch with number of cells of mesh !"); - _fam_cells=famArr; - break; - } - case 1: - { - int nbNodes=mesh->getNumberOfNodes(); - famArr->checkNbOfTuplesAndComp(nbNodes,1,"MEDFileStructuredMesh::setFamilyFieldArr : Problem in size of Family arr ! Mismatch with number of nodes of mesh !"); - _fam_nodes=famArr; - break; - } - case -1: - { - int nbCells=mesh->getNumberOfCellsOfSubLevelMesh(); - famArr->checkNbOfTuplesAndComp(nbCells,1,"MEDFileStructuredMesh::setFamilyFieldArr : Problem in size of Family arr ! Mismatch with number of faces of mesh !"); - _fam_faces=famArr; - break; - } - default: - throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::setFamilyFieldArr : Only available for levels 0 or 1 or -1 !"); - } - if(famArr) - famArr->incrRef(); -} - -/*! - * 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. - * \throw If \a meshDimRelToMaxExt != 0 and \a meshDimRelToMaxExt != 1. - */ -void MEDFileStructuredMesh::setRenumFieldArr(int meshDimRelToMaxExt, DataArrayInt *renumArr) -{ - const MEDCouplingStructuredMesh *mesh=getStructuredMesh(); - if(!mesh) - throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::setRenumFieldArr : no structured mesh specified ! Impossible to set number array !"); - switch(meshDimRelToMaxExt) - { - case 0: - { - int nbCells=mesh->getNumberOfCells(); - renumArr->checkNbOfTuplesAndComp(nbCells,1,"MEDFileStructuredMesh::setRenumFieldArr : Problem in size of Renum arr ! Mismatch with number of cells of mesh !"); - _num_cells=renumArr; - break; - } - case 1: - { - int nbNodes=mesh->getNumberOfNodes(); - renumArr->checkNbOfTuplesAndComp(nbNodes,1,"MEDFileStructuredMesh::setRenumFieldArr : Problem in size of Family arr ! Mismatch with number of nodes of mesh !"); - _num_nodes=renumArr; - break; - } - case -1: - { - int nbCells=mesh->getNumberOfCellsOfSubLevelMesh(); - renumArr->checkNbOfTuplesAndComp(nbCells,1,"MEDFileStructuredMesh::setRenumFieldArr : Problem in size of Renum arr ! Mismatch with number of faces of mesh !"); - _num_faces=renumArr; - break; - } - default: - throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::setRenumFieldArr : Only available for levels 0 or 1 or -1 !"); - } - if(renumArr) - renumArr->incrRef(); -} - -/*! - * Sets the optional names of mesh entities of a given dimension. - * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities. - * \param [in] nameArr - the array of the names. - * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh. - * \throw If \a nameArr has an invalid size. - */ -void MEDFileStructuredMesh::setNameFieldAtLevel(int meshDimRelToMaxExt, DataArrayAsciiChar *nameArr) -{ - const MEDCouplingStructuredMesh *mesh(getStructuredMesh()); - if(!mesh) - throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::setNameFieldAtLevel : no structured mesh specified ! Impossible to set names array !"); - switch(meshDimRelToMaxExt) - { - case 0: - { - int nbCells=mesh->getNumberOfCells(); - nameArr->checkNbOfTuplesAndComp(nbCells,MED_SNAME_SIZE,"MEDFileStructuredMesh::setNameFieldAtLevel : Problem in size of names arr ! Mismatch with number of cells of mesh !"); - _names_cells=nameArr; - break; - } - case 1: - { - int nbNodes=mesh->getNumberOfNodes(); - nameArr->checkNbOfTuplesAndComp(nbNodes,MED_SNAME_SIZE,"MEDFileStructuredMesh::setNameFieldAtLevel : Problem in size of names arr ! Mismatch with number of nodes of mesh !"); - _names_nodes=nameArr; - break; - } - case -1: - { - int nbCells=mesh->getNumberOfCellsOfSubLevelMesh(); - nameArr->checkNbOfTuplesAndComp(nbCells,MED_SNAME_SIZE,"MEDFileStructuredMesh::setNameFieldAtLevel : Problem in size of names arr ! Mismatch with number of faces of mesh !"); - _names_cells=nameArr; - } - default: - throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::setNameFieldAtLevel : Only available for levels 0 or 1 or -1 !"); - } - if(nameArr) - nameArr->incrRef(); -} - -/*! - * Adds a group of nodes to \a this mesh. - * \param [in] ids - a DataArrayInt providing ids and a name of the group to add. - * The ids should be sorted and different each other (MED file norm). - * - * \warning this method can alter default "FAMILLE_ZERO" family. - * For users sensitive to this a call to MEDFileMesh::rearrangeFamilies will be necessary after addGroup session. - * - * \throw If the node coordinates array is not set. - * \throw If \a ids == \c NULL. - * \throw If \a ids->getName() == "". - * \throw If \a ids does not respect the MED file norm. - * \throw If a group with name \a ids->getName() already exists. - */ -void MEDFileStructuredMesh::addNodeGroup(const DataArrayInt *ids) -{ - addGroup(1,ids); -} - -/*! - * Adds a group of nodes/cells/faces/edges to \a this mesh. - * - * \param [in] ids - a DataArrayInt providing ids and a name of the group to add. - * The ids should be sorted and different each other (MED file norm). - * - * \warning this method can alter default "FAMILLE_ZERO" family. - * For users sensitive to this a call to MEDFileMesh::rearrangeFamilies will be necessary after addGroup session. - * - * \throw If the node coordinates array is not set. - * \throw If \a ids == \c NULL. - * \throw If \a ids->getName() == "". - * \throw If \a ids does not respect the MED file norm. - * \throw If a group with name \a ids->getName() already exists. - */ -void MEDFileStructuredMesh::addGroup(int meshDimRelToMaxExt, const DataArrayInt *ids) -{ - DataArrayInt *fam(getOrCreateAndGetFamilyFieldAtLevel(meshDimRelToMaxExt)); - addGroupUnderground(false,ids,fam); - return ; -} - -/*! - * 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 \c NULL. - * \throw If \a meshDimRelToMaxExt != 0 and \a meshDimRelToMaxExt != 1. - */ -const DataArrayInt *MEDFileStructuredMesh::getFamilyFieldAtLevel(int meshDimRelToMaxExt) const -{ - switch(meshDimRelToMaxExt) - { - case 0: - return _fam_cells; - case 1: - return _fam_nodes; - case -1: - return _fam_faces; - default: - throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getFamilyFieldAtLevel : Only available for levels 0 or 1 or -1 !"); - } -} - -/*! - * 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 \c NULL. - * \throw If \a meshDimRelToMaxExt != 0 and \a meshDimRelToMaxExt != 1. - */ -DataArrayInt *MEDFileStructuredMesh::getFamilyFieldAtLevel(int meshDimRelToMaxExt) -{ - switch(meshDimRelToMaxExt) - { - case 0: - return _fam_cells; - case 1: - return _fam_nodes; - case -1: - return _fam_faces; - default: - throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getFamilyFieldAtLevel : Only available for levels 0 or 1 or -1 !"); - } -} - -/*! - * 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. - * \throw If \a meshDimRelToMaxExt != 0 and \a meshDimRelToMaxExt != 1. - */ -const DataArrayInt *MEDFileStructuredMesh::getNumberFieldAtLevel(int meshDimRelToMaxExt) const -{ - switch(meshDimRelToMaxExt) - { - case 0: - return _num_cells; - case 1: - return _num_nodes; - case -1: - return _num_faces; - default: - throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getNumberFieldAtLevel : Only available for levels 0 or 1 or -1 !"); - } -} - -/*! - * 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 \a meshDimRelToMaxExt != 0 and \a meshDimRelToMaxExt != 1. - * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh. - */ -const DataArrayInt *MEDFileStructuredMesh::getRevNumberFieldAtLevel(int meshDimRelToMaxExt) const -{ - if(meshDimRelToMaxExt!=0 && meshDimRelToMaxExt!=1) - throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getRevNumberFieldAtLevel : Only available for levels 0 or 1 !"); - if(meshDimRelToMaxExt==0) - { - if((const DataArrayInt *)_num_cells) - { - int pos; - int maxValue=_num_cells->getMaxValue(pos); - _rev_num_cells=_num_cells->invertArrayN2O2O2N(maxValue+1); - return _rev_num_cells; - } - else - throw INTERP_KERNEL::Exception("MEDFileCMesh::getRevNumberFieldAtLevel : no cell renumbering for a request on reverse numbering !"); - } - else - { - if((const DataArrayInt *)_num_nodes) - { - int pos; - int maxValue=_num_nodes->getMaxValue(pos); - _rev_num_nodes=_num_nodes->invertArrayN2O2O2N(maxValue+1); - return _rev_num_nodes; - } - else - throw INTERP_KERNEL::Exception("MEDFileCMesh::getRevNumberFieldAtLevel : no node renumbering for a request on reverse numbering !"); - } -} - -const DataArrayAsciiChar *MEDFileStructuredMesh::getNameFieldAtLevel(int meshDimRelToMaxExt) const -{ - switch(meshDimRelToMaxExt) - { - case 0: - return _names_cells; - case 1: - return _names_nodes; - case -1: - return _names_faces; - default: - throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getNameFieldAtLevel : Only available for levels 0 or 1 or -1 !"); - } -} - -/*! - * Returns relative dimensions of mesh entities (excluding nodes) present in \a this mesh. - * \return std::vector - a sequence of the relative dimensions: [0]. - */ -std::vector MEDFileStructuredMesh::getNonEmptyLevels() const -{ - std::vector ret(1); - return ret; -} - -/*! - * Returns relative dimensions of mesh entities (including nodes) present in \a this mesh. - * \return std::vector - a sequence of the relative dimensions: [1,0]. - */ -std::vector MEDFileStructuredMesh::getNonEmptyLevelsExt() const -{ - std::vector ret(2); - ret[0]=1; - return ret; -} - -/*! - * Returns the set of extensive levels (nodes included) where not NULL family arr are defined. - */ -std::vector MEDFileStructuredMesh::getFamArrNonEmptyLevelsExt() const -{ - std::vector ret; - const DataArrayInt *famNodes(_fam_nodes),*famCells(_fam_cells),*famFaces(_fam_faces); - if(famNodes) - ret.push_back(1); - if(famCells) - ret.push_back(0); - if(famFaces) - ret.push_back(-1); - return ret; -} - -/*! - * Returns the set of extensive levels (nodes included) where not NULL numbering arr are defined. - */ -std::vector MEDFileStructuredMesh::getNumArrNonEmptyLevelsExt() const -{ - std::vector ret; - const DataArrayInt *numNodes(_num_nodes),*numCells(_num_cells),*numFaces(_num_faces); - if(numNodes) - ret.push_back(1); - if(numCells) - ret.push_back(0); - if(numFaces) - ret.push_back(-1); - return ret; -} - -/*! - * Returns the set of extensive levels (nodes included) where not NULL naming arr are defined. - */ -std::vector MEDFileStructuredMesh::getNameArrNonEmptyLevelsExt() const -{ - std::vector ret; - const DataArrayAsciiChar *namesNodes(_names_nodes),*namesCells(_names_cells),*namesFaces(_names_faces); - if(namesNodes) - ret.push_back(1); - if(namesCells) - ret.push_back(0); - if(namesFaces) - ret.push_back(-1); - return ret; -} - -/*! - * no implementation here, it is not a bug, but intresically no polyhedra in \a this. - */ -bool MEDFileStructuredMesh::unPolyze(std::vector& oldCode, std::vector& newCode, DataArrayInt *& o2nRenumCell) -{ - oldCode.clear(); newCode.clear(); o2nRenumCell=0; - return false; -} - -void MEDFileStructuredMesh::changeFamilyIdArr(int oldId, int newId) -{ - DataArrayInt *arr=_fam_nodes; - if(arr) - arr->changeValue(oldId,newId); - arr=_fam_cells; - if(arr) - arr->changeValue(oldId,newId); - arr=_fam_faces; - if(arr) - arr->changeValue(oldId,newId); -} - -std::list< MEDCouplingAutoRefCountObjectPtr > MEDFileStructuredMesh::getAllNonNullFamilyIds() const -{ - std::list< MEDCouplingAutoRefCountObjectPtr > ret; - const DataArrayInt *da(_fam_nodes); - if(da) - { da->incrRef(); ret.push_back(MEDCouplingAutoRefCountObjectPtr(const_cast(da))); } - da=_fam_cells; - if(da) - { da->incrRef(); ret.push_back(MEDCouplingAutoRefCountObjectPtr(const_cast(da))); } - da=_fam_faces; - if(da) - { da->incrRef(); ret.push_back(MEDCouplingAutoRefCountObjectPtr(const_cast(da))); } - return ret; -} - -void MEDFileStructuredMesh::deepCpyAttributes() -{ - if((const DataArrayInt*)_fam_nodes) - _fam_nodes=_fam_nodes->deepCpy(); - if((const DataArrayInt*)_num_nodes) - _num_nodes=_num_nodes->deepCpy(); - if((const DataArrayAsciiChar*)_names_nodes) - _names_nodes=_names_nodes->deepCpy(); - if((const DataArrayInt*)_fam_cells) - _fam_cells=_fam_cells->deepCpy(); - if((const DataArrayInt*)_num_cells) - _num_cells=_num_cells->deepCpy(); - if((const DataArrayAsciiChar*)_names_cells) - _names_cells=_names_cells->deepCpy(); - if((const DataArrayInt*)_fam_faces) - _fam_faces=_fam_faces->deepCpy(); - if((const DataArrayInt*)_num_faces) - _num_faces=_num_faces->deepCpy(); - if((const DataArrayAsciiChar*)_names_faces) - _names_faces=_names_faces->deepCpy(); - if((const DataArrayInt*)_rev_num_nodes) - _rev_num_nodes=_rev_num_nodes->deepCpy(); - if((const DataArrayInt*)_rev_num_cells) - _rev_num_cells=_rev_num_cells->deepCpy(); -} - -/*! - * Returns a pointer to mesh at the specified level (here 0 is compulsary for cartesian mesh). - * - * \return a pointer to cartesian mesh that need to be managed by the caller. - * \warning the returned pointer has to be managed by the caller. - */ - -/*! - * Returns a pointer to MEDCouplingStructuredMesh held by \a this. - * \param [in] meshDimRelToMax - it must be \c 0 or \c -1. - * \param [in] renum - it must be \c false. - * \return MEDCouplingMesh * - a pointer to MEDCouplingMesh that the caller is to - * delete using decrRef() as it is no more needed. - */ -MEDCouplingMesh *MEDFileStructuredMesh::getGenMeshAtLevel(int meshDimRelToMax, bool renum) const -{ - if(renum) - throw INTERP_KERNEL::Exception("MEDFileCurveLinearMesh does not support renumbering ! To do it perform request of renum array directly !"); - const MEDCouplingStructuredMesh *m(getStructuredMesh()); - switch(meshDimRelToMax) - { - case 0: - { - if(m) - m->incrRef(); - return const_cast(m); - } - case -1: - { - if(!m) - throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getGenMeshAtLevel : level -1 requested must be non empty to be able to compute unstructured sub mesh !"); - buildMinusOneImplicitPartIfNeeded(); - MEDCouplingMesh *ret(_faces_if_necessary); - if(ret) - ret->incrRef(); - return ret; - } - default: - throw INTERP_KERNEL::Exception("MEDFileCurveLinearMesh does not support multi level for mesh 0 expected as input !"); - } -} - -/*! - * 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 MEDFileStructuredMesh::getSizeAtLevel(int meshDimRelToMaxExt) const -{ - const MEDCouplingStructuredMesh *cmesh(getStructuredMesh()); - if(!cmesh) - throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getSizeAtLevel : No structured mesh set !"); - switch(meshDimRelToMaxExt) - { - case 0: - return cmesh->getNumberOfCells(); - case 1: - return cmesh->getNumberOfNodes(); - case -1: - return cmesh->getNumberOfCellsOfSubLevelMesh(); - default: - throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getSizeAtLevel : Only available for levels 0 or 1 or -1 !"); - } -} - -int MEDFileStructuredMesh::getNumberOfNodes() const -{ - const MEDCouplingStructuredMesh *cmesh(getStructuredMesh()); - if(!cmesh) - throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getNumberOfNodes : no cartesian mesh set !"); - return cmesh->getNumberOfNodes(); -} - -int MEDFileStructuredMesh::getNumberOfCellsAtLevel(int meshDimRelToMaxExt) const -{ - const MEDCouplingStructuredMesh *cmesh(getStructuredMesh()); - if(!cmesh) - throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getNumberOfNodes : no cartesian mesh set !"); - switch(meshDimRelToMaxExt) - { - case 0: - return cmesh->getNumberOfCells(); - case -1: - return cmesh->getNumberOfCellsOfSubLevelMesh(); - default: - throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getNumberOfNodes : only meshDimRelToMax=0 and meshDimRelToMax=-1 supported !"); - } -} - -bool MEDFileStructuredMesh::hasImplicitPart() const -{ - return true; -} - -/*! - * \sa MEDFileStructuredMesh::getImplicitFaceMesh - */ -int MEDFileStructuredMesh::buildImplicitPartIfAny(INTERP_KERNEL::NormalizedCellType gt) const -{ - static const char MSG[]="MEDFileStructuredMesh::buildImplicitPartIfAny : the given geo type is not manageable by a structured mesh !"; - const MEDCoupling1SGTUMesh *zeFaceMesh(_faces_if_necessary); - if(!zeFaceMesh) - { - const INTERP_KERNEL::CellModel& cm(INTERP_KERNEL::CellModel::GetCellModel(MEDCouplingStructuredMesh::GetGeoTypeGivenMeshDimension(getMeshDimension()))); - if(cm.getReverseExtrudedType()!=gt) - throw INTERP_KERNEL::Exception(MSG); - buildImplicitPart(); - return getStructuredMesh()->getNumberOfCellsOfSubLevelMesh(); - } - else - { - if(gt!=zeFaceMesh->getCellModelEnum()) - throw INTERP_KERNEL::Exception(MSG); - return zeFaceMesh->getNumberOfCells(); - } -} - -void MEDFileStructuredMesh::buildMinusOneImplicitPartIfNeeded() const -{ - const MEDCoupling1SGTUMesh *zeFaceMesh(_faces_if_necessary); - if(!zeFaceMesh) - buildImplicitPart(); -} - -void MEDFileStructuredMesh::buildImplicitPart() const -{ - const MEDCouplingStructuredMesh *mcmesh(getStructuredMesh()); - if(!mcmesh) - throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::buildImplicitPart : Unable to build the implicit part of structured mesh because no structured mesh at level 0 defined !"); - _faces_if_necessary=mcmesh->build1SGTSubLevelMesh(); -} - -void MEDFileStructuredMesh::releaseImplicitPartIfAny() const -{ - _faces_if_necessary=0; -} - -/*! - * Retrieves the internal pointer (no decrRef requested) of the implicit face mesh if any. - * To force to build it you can invoke MEDFileStructuredMesh::buildImplicitPartIfAny method. - * - * \sa MEDFileStructuredMesh::buildImplicitPartIfAny - */ -MEDCoupling1SGTUMesh *MEDFileStructuredMesh::getImplicitFaceMesh() const -{ - return _faces_if_necessary; -} - -std::vector MEDFileStructuredMesh::getGeoTypesAtLevel(int meshDimRelToMax) const -{ - const MEDCouplingStructuredMesh *cmesh(getStructuredMesh()); - if(!cmesh) - throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getGeoTypesAtLevel : No structured mesh set !"); - switch(meshDimRelToMax) - { - case 0: - { - std::vector ret(1,cmesh->getTypeOfCell(0)); - return ret; - } - case -1: - { - int mdim(cmesh->getMeshDimension()); - if(mdim<1) - throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getGeoTypesAtLevel : only one level available for structured meshes ! Input 0 is mandatory or 0D mesh !"); - std::vector ret(1,MEDCouplingStructuredMesh::GetGeoTypeGivenMeshDimension(mdim-1)); - return ret; - } - default: - throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getGeoTypesAtLevel : only 2 levels available at most : 0 and -1 !"); - } -} - -void MEDFileStructuredMesh::whichAreNodesFetched(const MEDFileField1TSStructItem& st, const MEDFileFieldGlobsReal *globs, std::vector& nodesFetched) const -{ - if(st.getNumberOfItems()!=1) - throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::whichAreNodesFetched : The sturture of field is not lying on single geo type ! it is not managed yet for structured mesh !"); - if(st[0].getGeo()!=MEDCouplingStructuredMesh::GetGeoTypeGivenMeshDimension(getMeshDimension())) - throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::whichAreNodesFetched : The sturture of field is not lying on expected geo type !"); - if(getNumberOfNodes()!=(int)nodesFetched.size()) - throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::whichAreNodesFetched : invalid size of array !"); - if(st[0].getPflName().empty()) - { - std::fill(nodesFetched.begin(),nodesFetched.end(),true); - return ; - } - const DataArrayInt *arr(globs->getProfile(st[0].getPflName())); - const MEDCouplingStructuredMesh *cmesh=getStructuredMesh();//cmesh not null because getNumberOfNodes called before - int sz(nodesFetched.size()); - for(const int *work=arr->begin();work!=arr->end();work++) - { - std::vector conn; - cmesh->getNodeIdsOfCell(*work,conn); - for(std::vector::const_iterator it=conn.begin();it!=conn.end();it++) - if(*it>=0 && *it& famCells, MEDCouplingAutoRefCountObjectPtr& numCells, MEDCouplingAutoRefCountObjectPtr& namesCells) -{ - med_bool chgt=MED_FALSE,trsf=MED_FALSE; - med_geometry_type geoTypeReq=MEDFileStructuredMesh::GetGeoTypeFromMeshDim(meshDim); - int nbOfElt(0); - nbOfElt=MEDmeshnEntity(fid,mName.c_str(),dt,it,MED_CELL,geoTypeReq,MED_FAMILY_NUMBER,MED_NODAL,&chgt,&trsf); - if(nbOfElt>0) - { - if(!mrs || mrs->isCellFamilyFieldReading()) - { - famCells=DataArrayInt::New(); - famCells->alloc(nbOfElt,1); - MEDFILESAFECALLERRD0(MEDmeshEntityFamilyNumberRd,(fid,mName.c_str(),dt,it,MED_CELL,geoTypeReq,famCells->getPointer())); - } - } - nbOfElt=MEDmeshnEntity(fid,mName.c_str(),dt,it,MED_CELL,geoTypeReq,MED_NUMBER,MED_NODAL,&chgt,&trsf); - if(nbOfElt>0) - { - if(!mrs || mrs->isCellNumFieldReading()) - { - numCells=DataArrayInt::New(); - numCells->alloc(nbOfElt,1); - MEDFILESAFECALLERRD0(MEDmeshEntityNumberRd,(fid,mName.c_str(),dt,it,MED_CELL,geoTypeReq,numCells->getPointer())); - } - } - nbOfElt=MEDmeshnEntity(fid,mName.c_str(),dt,it,MED_CELL,geoTypeReq,MED_NAME,MED_NODAL,&chgt,&trsf); - if(nbOfElt>0) - { - if(!mrs || mrs->isCellNameFieldReading()) - { - namesCells=DataArrayAsciiChar::New(); - namesCells->alloc(nbOfElt+1,MED_SNAME_SIZE);//not a bug to avoid the memory corruption due to last \0 at the end - MEDFILESAFECALLERRD0(MEDmeshEntityNameRd,(fid,mName.c_str(),dt,it,MED_CELL,geoTypeReq,namesCells->getPointer())); - namesCells->reAlloc(nbOfElt);//not a bug to avoid the memory corruption due to last \0 at the end - } - } -} - -void MEDFileStructuredMesh::loadStrMeshFromFile(MEDFileStrMeshL2 *strm, med_idt fid, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs) -{ - setName(strm->getName()); - setDescription(strm->getDescription()); - setUnivName(strm->getUnivName()); - setIteration(strm->getIteration()); - setOrder(strm->getOrder()); - setTimeValue(strm->getTime()); - setTimeUnit(strm->getTimeUnit()); - MEDFileMeshL2::ReadFamiliesAndGrps(fid,mName,_families,_groups,mrs); - med_bool chgt=MED_FALSE,trsf=MED_FALSE; - int nbOfElt(MEDmeshnEntity(fid,mName.c_str(),dt,it,MED_NODE,MED_NONE,MED_FAMILY_NUMBER,MED_NODAL,&chgt,&trsf)); - if(nbOfElt>0) - { - if(!mrs || mrs->isNodeFamilyFieldReading()) - { - int nbNodes(getNumberOfNodes()); - if(nbOfElt>nbNodes) - throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::loadStrMeshFromFile : invalid size of family node array regarding number of nodes in this ! File seems to be corrupted !"); - _fam_nodes=DataArrayInt::New(); - _fam_nodes->alloc(nbNodes,1);//yes nbNodes and not nbOfElt see next line. - if(nbNodes>nbOfElt)//yes it appends some times... It explains surely the mdump implementation. Bug revealed by PARAVIS EDF #2475 on structured.med file where only 12 first nodes are !=0 so nbOfElt=12 and nbOfNodes=378... - _fam_nodes->fillWithZero(); - MEDFILESAFECALLERRD0(MEDmeshEntityFamilyNumberRd,(fid,mName.c_str(),dt,it,MED_NODE,MED_NONE,_fam_nodes->getPointer())); - } - } - nbOfElt=MEDmeshnEntity(fid,mName.c_str(),dt,it,MED_NODE,MED_NONE,MED_NUMBER,MED_NODAL,&chgt,&trsf); - if(nbOfElt>0) - { - if(!mrs || mrs->isNodeNumFieldReading()) - { - _num_nodes=DataArrayInt::New(); - _num_nodes->alloc(nbOfElt,1); - MEDFILESAFECALLERRD0(MEDmeshEntityNumberRd,(fid,mName.c_str(),dt,it,MED_NODE,MED_NONE,_num_nodes->getPointer())); - } - } - nbOfElt=MEDmeshnEntity(fid,mName.c_str(),dt,it,MED_NODE,MED_NONE,MED_NAME,MED_NODAL,&chgt,&trsf); - if(nbOfElt>0) - { - if(!mrs || mrs->isNodeNameFieldReading()) - { - _names_nodes=DataArrayAsciiChar::New(); - _names_nodes->alloc(nbOfElt+1,MED_SNAME_SIZE);//not a bug to avoid the memory corruption due to last \0 at the end - MEDFILESAFECALLERRD0(MEDmeshEntityNameRd,(fid,mName.c_str(),dt,it,MED_NODE,MED_NONE,_names_nodes->getPointer())); - _names_nodes->reAlloc(nbOfElt);//not a bug to avoid the memory corruption due to last \0 at the end - } - } - int meshDim(getStructuredMesh()->getMeshDimension()); - LoadStrMeshDAFromFile(fid,meshDim,dt,it,mName,mrs,_fam_cells,_num_cells,_names_cells); - if(meshDim>=1) - LoadStrMeshDAFromFile(fid,meshDim-1,dt,it,mName,mrs,_fam_faces,_num_faces,_names_faces); -} - -void MEDFileStructuredMesh::writeStructuredLL(med_idt fid, const std::string& maa) const -{ - int meshDim(getStructuredMesh()->getMeshDimension()); - med_geometry_type geoTypeReq(GetGeoTypeFromMeshDim(meshDim)),geoTypeReq2(GetGeoTypeFromMeshDim(meshDim-1)); - // - if((const DataArrayInt *)_fam_cells) - MEDFILESAFECALLERWR0(MEDmeshEntityFamilyNumberWr,(fid,maa.c_str(),_iteration,_order,MED_CELL,geoTypeReq,_fam_cells->getNumberOfTuples(),_fam_cells->getConstPointer())); - if((const DataArrayInt *)_fam_faces) - MEDFILESAFECALLERWR0(MEDmeshEntityFamilyNumberWr,(fid,maa.c_str(),_iteration,_order,MED_CELL,geoTypeReq2,_fam_faces->getNumberOfTuples(),_fam_faces->getConstPointer())); - if((const DataArrayInt *)_fam_nodes) - MEDFILESAFECALLERWR0(MEDmeshEntityFamilyNumberWr,(fid,maa.c_str(),_iteration,_order,MED_NODE,MED_NONE,_fam_nodes->getNumberOfTuples(),_fam_nodes->getConstPointer())); - if((const DataArrayInt *)_num_cells) - MEDFILESAFECALLERWR0(MEDmeshEntityNumberWr,(fid,maa.c_str(),_iteration,_order,MED_CELL,geoTypeReq,_num_cells->getNumberOfTuples(),_num_cells->getConstPointer())); - if((const DataArrayInt *)_num_faces) - MEDFILESAFECALLERWR0(MEDmeshEntityNumberWr,(fid,maa.c_str(),_iteration,_order,MED_CELL,geoTypeReq2,_num_faces->getNumberOfTuples(),_num_faces->getConstPointer())); - if((const DataArrayInt *)_num_nodes) - MEDFILESAFECALLERWR0(MEDmeshEntityNumberWr,(fid,maa.c_str(),_iteration,_order,MED_NODE,MED_NONE,_num_nodes->getNumberOfTuples(),_num_nodes->getConstPointer())); - if((const DataArrayAsciiChar *)_names_cells) - { - if(_names_cells->getNumberOfComponents()!=MED_SNAME_SIZE) - { - std::ostringstream oss; oss << "MEDFileStructuredMesh::writeStructuredLL : expected a name field on cells with number of components set to " << MED_SNAME_SIZE; - oss << " ! The array has " << _names_cells->getNumberOfComponents() << " components !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - MEDFILESAFECALLERWR0(MEDmeshEntityNameWr,(fid,maa.c_str(),_iteration,_order,MED_CELL,geoTypeReq,_names_cells->getNumberOfTuples(),_names_cells->getConstPointer())); - } - if((const DataArrayAsciiChar *)_names_faces) - { - if(_names_faces->getNumberOfComponents()!=MED_SNAME_SIZE) - { - std::ostringstream oss; oss << "MEDFileStructuredMesh::writeStructuredLL : expected a name field on faces with number of components set to " << MED_SNAME_SIZE; - oss << " ! The array has " << _names_faces->getNumberOfComponents() << " components !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - MEDFILESAFECALLERWR0(MEDmeshEntityNameWr,(fid,maa.c_str(),_iteration,_order,MED_CELL,geoTypeReq2,_names_faces->getNumberOfTuples(),_names_faces->getConstPointer())); - } - if((const DataArrayAsciiChar *)_names_nodes) - { - if(_names_nodes->getNumberOfComponents()!=MED_SNAME_SIZE) - { - std::ostringstream oss; oss << "MEDFileStructuredMesh::writeStructuredLL : expected a name field on nodes with number of components set to " << MED_SNAME_SIZE; - oss << " ! The array has " << _names_cells->getNumberOfComponents() << " components !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - MEDFILESAFECALLERWR0(MEDmeshEntityNameWr,(fid,maa.c_str(),_iteration,_order,MED_NODE,MED_NONE,_names_nodes->getNumberOfTuples(),_names_nodes->getConstPointer())); - } - // - MEDFileUMeshL2::WriteFamiliesAndGrps(fid,maa.c_str(),_families,_groups,_too_long_str); -} - -/*! - * Returns an empty instance of MEDFileCMesh. - * \return MEDFileCMesh * - a new instance of MEDFileCMesh. The caller is to delete this - * mesh using decrRef() as it is no more needed. - */ -MEDFileCMesh *MEDFileCMesh::New() -{ - return new MEDFileCMesh; -} - -/*! - * Returns a new MEDFileCMesh holding the mesh data that has been read from a given MED - * file. The first mesh in the file is loaded. - * \param [in] fileName - the name of MED file to read. - * \return MEDFileCMesh * - a new instance of MEDFileCMesh. The caller is to delete this - * mesh using decrRef() as it is no more needed. - * \throw If the file is not readable. - * \throw If there is no meshes in the file. - * \throw If the mesh in the file is not a Cartesian one. - */ -MEDFileCMesh *MEDFileCMesh::New(const std::string& fileName, MEDFileMeshReadSelector *mrs) -{ - std::vector ms=MEDLoader::GetMeshNames(fileName); - if(ms.empty()) - { - std::ostringstream oss; oss << "MEDFileUMesh::New : no meshes in file \"" << fileName << "\" !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - MEDFileUtilities::CheckFileForRead(fileName); - MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName.c_str(),MED_ACC_RDONLY); - int dt,it; - ParaMEDMEM::MEDCouplingMeshType meshType; - std::string dummy2; - MEDFileMeshL2::GetMeshIdFromName(fid,ms.front(),meshType,dt,it,dummy2); - return new MEDFileCMesh(fid,ms.front(),dt,it,mrs); -} - -/*! - * Returns a new MEDFileCMesh holding the mesh data that has been read from a given MED - * file. The mesh to load is specified by its name and numbers of a time step and an - * iteration. - * \param [in] fileName - the name of MED file to read. - * \param [in] mName - the name of the mesh to read. - * \param [in] dt - the number of a time step. - * \param [in] it - the number of an iteration. - * \return MEDFileCMesh * - a new instance of MEDFileCMesh. The caller is to delete this - * mesh using decrRef() as it is no more needed. - * \throw If the file is not readable. - * \throw If there is no mesh with given attributes in the file. - * \throw If the mesh in the file is not a Cartesian one. - */ -MEDFileCMesh *MEDFileCMesh::New(const std::string& fileName, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs) -{ - MEDFileUtilities::CheckFileForRead(fileName); - MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName.c_str(),MED_ACC_RDONLY); - return new MEDFileCMesh(fid,mName,dt,it,mrs); -} - -std::size_t MEDFileCMesh::getHeapMemorySizeWithoutChildren() const -{ - return MEDFileStructuredMesh::getHeapMemorySizeWithoutChildren(); -} - -std::vector MEDFileCMesh::getDirectChildrenWithNull() const -{ - std::vector ret(MEDFileStructuredMesh::getDirectChildrenWithNull()); - ret.push_back((const MEDCouplingCMesh *)_cmesh); - return ret; -} - -/*! - * Returns the dimension on cells in \a this mesh. - * \return int - the mesh dimension. - * \throw If there are no cells in this mesh. - */ -int MEDFileCMesh::getMeshDimension() const -{ - if(!((const MEDCouplingCMesh*)_cmesh)) - throw INTERP_KERNEL::Exception("MEDFileCMesh::getMeshDimension : unable to get meshdimension because no mesh set !"); - return _cmesh->getMeshDimension(); -} - -/*! - * Returns the dimension on nodes in \a this mesh. - * \return int - the space dimension. - * \throw If there are no cells in this mesh. - */ -int MEDFileCMesh::getSpaceDimension() const -{ - if(!((const MEDCouplingCMesh*)_cmesh)) - throw INTERP_KERNEL::Exception("MEDFileCMesh::getSpaceDimension : unable to get spacedimension because no mesh set !"); - return _cmesh->getSpaceDimension(); -} - -/*! - * Returns a string describing \a this mesh. - * \return std::string - the mesh information string. - */ -std::string MEDFileCMesh::simpleRepr() const -{ - return MEDFileStructuredMesh::simpleRepr(); -} - -/*! - * Returns a full textual description of \a this mesh. - * \return std::string - the string holding the mesh description. - */ -std::string MEDFileCMesh::advancedRepr() const -{ - return simpleRepr(); -} - -MEDFileMesh *MEDFileCMesh::shallowCpy() const -{ - MEDCouplingAutoRefCountObjectPtr ret=new MEDFileCMesh(*this); - return ret.retn(); -} - -MEDFileMesh *MEDFileCMesh::createNewEmpty() const -{ - return new MEDFileCMesh; -} - -MEDFileMesh *MEDFileCMesh::deepCpy() const -{ - MEDCouplingAutoRefCountObjectPtr ret=new MEDFileCMesh(*this); - if((const MEDCouplingCMesh*)_cmesh) - ret->_cmesh=static_cast(_cmesh->deepCpy()); - ret->deepCpyAttributes(); - return ret.retn(); -} - -/*! - * Checks if \a this and another mesh are equal. - * \param [in] other - the mesh to compare with. - * \param [in] eps - a precision used to compare real values. - * \param [in,out] what - the string returning description of unequal data. - * \return bool - \c true if the meshes are equal, \c false, else. - */ -bool MEDFileCMesh::isEqual(const MEDFileMesh *other, double eps, std::string& what) const -{ - if(!MEDFileStructuredMesh::isEqual(other,eps,what)) - return false; - const MEDFileCMesh *otherC=dynamic_cast(other); - if(!otherC) - { - what="Mesh types differ ! This is cartesian and other is NOT !"; - return false; - } - clearNonDiscrAttributes(); - otherC->clearNonDiscrAttributes(); - const MEDCouplingCMesh *coo1=_cmesh; - const MEDCouplingCMesh *coo2=otherC->_cmesh; - if((coo1==0 && coo2!=0) || (coo1!=0 && coo2==0)) - { - what="Mismatch of cartesian meshes ! One is defined and not other !"; - return false; - } - if(coo1) - { - bool ret=coo1->isEqual(coo2,eps); - if(!ret) - { - what="cartesian meshes differ !"; - return false; - } - } - return true; -} - -/*! - * Clears redundant attributes of incorporated data arrays. - */ -void MEDFileCMesh::clearNonDiscrAttributes() const -{ - MEDFileStructuredMesh::clearNonDiscrAttributes(); - MEDFileUMeshSplitL1::ClearNonDiscrAttributes(_cmesh);//to it is not a bug umeshsplit have already the method implemented -} - -MEDFileCMesh::MEDFileCMesh() -{ -} - -MEDFileCMesh::MEDFileCMesh(med_idt fid, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs) -try -{ - loadCMeshFromFile(fid,mName,dt,it,mrs); - loadJointsFromFile(fid); -} -catch(INTERP_KERNEL::Exception& e) -{ - throw e; -} - -void MEDFileCMesh::loadCMeshFromFile(med_idt fid, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs) -{ - ParaMEDMEM::MEDCouplingMeshType meshType; - int dummy0,dummy1; - std::string dtunit; - int mid=MEDFileMeshL2::GetMeshIdFromName(fid,mName,meshType,dummy0,dummy1,dtunit); - if(meshType!=CARTESIAN) - { - std::ostringstream oss; oss << "Trying to load as cartesian an existing mesh with name '" << mName << "' that is NOT cartesian !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - MEDFileCMeshL2 loaderl2; - loaderl2.loadAll(fid,mid,mName,dt,it); - MEDCouplingCMesh *mesh=loaderl2.getMesh(); - mesh->incrRef(); - _cmesh=mesh; - loadStrMeshFromFile(&loaderl2,fid,mName,dt,it,mrs); -} - -/*! - * Returns a const pointer to MEDCouplingCMesh held by \a this mesh. - * \return const MEDCouplingCMesh * - a pointer to the held MEDCouplingCMesh. - */ -const MEDCouplingCMesh *MEDFileCMesh::getMesh() const -{ - synchronizeTinyInfoOnLeaves(); - return _cmesh; -} - -const MEDCouplingStructuredMesh *MEDFileCMesh::getStructuredMesh() const -{ - synchronizeTinyInfoOnLeaves(); - return _cmesh; -} - -/*! - * Sets the MEDCouplingCMesh holding the data of \a this mesh. - * \param [in] m - the new MEDCouplingCMesh to refer to. - * \throw If the name or the description of \a this mesh and \a m are not empty and are - * different. - */ -void MEDFileCMesh::setMesh(MEDCouplingCMesh *m) -{ - dealWithTinyInfo(m); - if(m) - m->incrRef(); - _cmesh=m; -} - -void MEDFileCMesh::writeLL(med_idt fid) const -{ - INTERP_KERNEL::AutoPtr maa=MEDLoaderBase::buildEmptyString(MED_NAME_SIZE); - INTERP_KERNEL::AutoPtr desc=MEDLoaderBase::buildEmptyString(MED_COMMENT_SIZE); - INTERP_KERNEL::AutoPtr dtunit=MEDLoaderBase::buildEmptyString(MED_LNAME_SIZE); - MEDLoaderBase::safeStrCpy(_name.c_str(),MED_NAME_SIZE,maa,_too_long_str); - MEDLoaderBase::safeStrCpy(_desc_name.c_str(),MED_COMMENT_SIZE,desc,_too_long_str); - MEDLoaderBase::safeStrCpy(_dt_unit.c_str(),MED_LNAME_SIZE,dtunit,_too_long_str); - int spaceDim(_cmesh->getSpaceDimension()); - INTERP_KERNEL::AutoPtr comp=MEDLoaderBase::buildEmptyString(spaceDim*MED_SNAME_SIZE); - INTERP_KERNEL::AutoPtr unit=MEDLoaderBase::buildEmptyString(spaceDim*MED_SNAME_SIZE); - for(int i=0;igetCoordsAt(i)->getInfoOnComponent(0)); - std::string c,u; - MEDLoaderBase::splitIntoNameAndUnit(info,c,u); - MEDLoaderBase::safeStrCpy2(c.c_str(),MED_SNAME_SIZE-1,comp+i*MED_SNAME_SIZE,_too_long_str);//MED_TAILLE_PNOM-1 to avoid to write '\0' on next compo - MEDLoaderBase::safeStrCpy2(u.c_str(),MED_SNAME_SIZE-1,unit+i*MED_SNAME_SIZE,_too_long_str);//MED_TAILLE_PNOM-1 to avoid to write '\0' on next compo - } - MEDFILESAFECALLERWR0(MEDmeshCr,(fid,maa,spaceDim,spaceDim,MED_STRUCTURED_MESH,desc,dtunit,MED_SORT_DTIT,MED_CARTESIAN,comp,unit)); - if(_univ_wr_status) - MEDFILESAFECALLERWR0(MEDmeshUniversalNameWr,(fid,maa)); - MEDFILESAFECALLERWR0(MEDmeshGridTypeWr,(fid,maa,MED_CARTESIAN_GRID)); - for(int i=0;igetCoordsAt(i); - MEDFILESAFECALLERWR0(MEDmeshGridIndexCoordinateWr,(fid,maa,_iteration,_order,_time,i+1,da->getNumberOfTuples(),da->getConstPointer())); - } - // - std::string meshName(MEDLoaderBase::buildStringFromFortran(maa,MED_NAME_SIZE)); - MEDFileStructuredMesh::writeStructuredLL(fid,meshName); - - writeJoints(fid); -} - -void MEDFileCMesh::synchronizeTinyInfoOnLeaves() const -{ - const MEDCouplingCMesh *cmesh=_cmesh; - if(!cmesh) - return; - (const_cast(cmesh))->setName(_name); - (const_cast(cmesh))->setDescription(_desc_name); - (const_cast(cmesh))->setTime(_time,_iteration,_order); - (const_cast(cmesh))->setTimeUnit(_dt_unit); -} - -MEDFileCurveLinearMesh *MEDFileCurveLinearMesh::New() -{ - return new MEDFileCurveLinearMesh; -} - -MEDFileCurveLinearMesh *MEDFileCurveLinearMesh::New(const std::string& fileName, MEDFileMeshReadSelector *mrs) -{ - std::vector ms=MEDLoader::GetMeshNames(fileName); - if(ms.empty()) - { - std::ostringstream oss; oss << "MEDFileUMesh::New : no meshes in file \"" << fileName << "\" !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - MEDFileUtilities::CheckFileForRead(fileName); - MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName.c_str(),MED_ACC_RDONLY); - int dt,it; - ParaMEDMEM::MEDCouplingMeshType meshType; - std::string dummy2; - MEDFileMeshL2::GetMeshIdFromName(fid,ms.front(),meshType,dt,it,dummy2); - return new MEDFileCurveLinearMesh(fid,ms.front(),dt,it,mrs); -} - -MEDFileCurveLinearMesh *MEDFileCurveLinearMesh::New(const std::string& fileName, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs) -{ - MEDFileUtilities::CheckFileForRead(fileName); - MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName.c_str(),MED_ACC_RDONLY); - return new MEDFileCurveLinearMesh(fid,mName,dt,it,mrs); -} - -std::size_t MEDFileCurveLinearMesh::getHeapMemorySizeWithoutChildren() const -{ - return MEDFileStructuredMesh::getHeapMemorySizeWithoutChildren(); -} - -std::vector MEDFileCurveLinearMesh::getDirectChildrenWithNull() const -{ - std::vector ret(MEDFileStructuredMesh::getDirectChildrenWithNull()); - ret.push_back((const MEDCouplingCurveLinearMesh *)_clmesh); - return ret; -} - -MEDFileMesh *MEDFileCurveLinearMesh::shallowCpy() const -{ - MEDCouplingAutoRefCountObjectPtr ret=new MEDFileCurveLinearMesh(*this); - return ret.retn(); -} - -MEDFileMesh *MEDFileCurveLinearMesh::createNewEmpty() const -{ - return new MEDFileCurveLinearMesh; -} - -MEDFileMesh *MEDFileCurveLinearMesh::deepCpy() const -{ - MEDCouplingAutoRefCountObjectPtr ret=new MEDFileCurveLinearMesh(*this); - if((const MEDCouplingCurveLinearMesh*)_clmesh) - ret->_clmesh=static_cast(_clmesh->deepCpy()); - ret->deepCpyAttributes(); - return ret.retn(); -} - -int MEDFileCurveLinearMesh::getMeshDimension() const -{ - if(!((const MEDCouplingCurveLinearMesh*)_clmesh)) - throw INTERP_KERNEL::Exception("MEDFileCurveLinearMesh::getMeshDimension : unable to get meshdimension because no mesh set !"); - return _clmesh->getMeshDimension(); -} - -std::string MEDFileCurveLinearMesh::simpleRepr() const -{ - return MEDFileStructuredMesh::simpleRepr(); -} - -std::string MEDFileCurveLinearMesh::advancedRepr() const -{ - return simpleRepr(); -} - -bool MEDFileCurveLinearMesh::isEqual(const MEDFileMesh *other, double eps, std::string& what) const -{ - if(!MEDFileStructuredMesh::isEqual(other,eps,what)) - return false; - const MEDFileCurveLinearMesh *otherC=dynamic_cast(other); - if(!otherC) - { - what="Mesh types differ ! This is curve linear and other is NOT !"; - return false; - } - clearNonDiscrAttributes(); - otherC->clearNonDiscrAttributes(); - const MEDCouplingCurveLinearMesh *coo1=_clmesh; - const MEDCouplingCurveLinearMesh *coo2=otherC->_clmesh; - if((coo1==0 && coo2!=0) || (coo1!=0 && coo2==0)) - { - what="Mismatch of curve linear meshes ! One is defined and not other !"; - return false; - } - if(coo1) - { - bool ret=coo1->isEqual(coo2,eps); - if(!ret) - { - what="curve linear meshes differ !"; - return false; - } - } - return true; -} - -void MEDFileCurveLinearMesh::clearNonDiscrAttributes() const -{ - MEDFileStructuredMesh::clearNonDiscrAttributes(); - MEDFileUMeshSplitL1::ClearNonDiscrAttributes(_clmesh);//to it is not a bug umeshsplit have already the method implemented -} - -void MEDFileCurveLinearMesh::synchronizeTinyInfoOnLeaves() const -{ - const MEDCouplingCurveLinearMesh *clmesh=_clmesh; - if(!clmesh) - return; - (const_cast(clmesh))->setName(_name); - (const_cast(clmesh))->setDescription(_desc_name); - (const_cast(clmesh))->setTime(_time,_iteration,_order); - (const_cast(clmesh))->setTimeUnit(_dt_unit); -} - -const MEDCouplingCurveLinearMesh *MEDFileCurveLinearMesh::getMesh() const -{ - synchronizeTinyInfoOnLeaves(); - return _clmesh; -} - -void MEDFileCurveLinearMesh::setMesh(MEDCouplingCurveLinearMesh *m) -{ - dealWithTinyInfo(m); - if(m) - m->incrRef(); - _clmesh=m; -} - -const MEDCouplingStructuredMesh *MEDFileCurveLinearMesh::getStructuredMesh() const -{ - synchronizeTinyInfoOnLeaves(); - return _clmesh; -} - -MEDFileCurveLinearMesh::MEDFileCurveLinearMesh() -{ -} - -MEDFileCurveLinearMesh::MEDFileCurveLinearMesh(med_idt fid, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs) -try -{ - loadCLMeshFromFile(fid,mName,dt,it,mrs); - loadJointsFromFile(fid); -} -catch(INTERP_KERNEL::Exception& e) -{ - throw e; -} - -void MEDFileCurveLinearMesh::writeLL(med_idt fid) const -{ - INTERP_KERNEL::AutoPtr maa=MEDLoaderBase::buildEmptyString(MED_NAME_SIZE); - INTERP_KERNEL::AutoPtr desc=MEDLoaderBase::buildEmptyString(MED_COMMENT_SIZE); - INTERP_KERNEL::AutoPtr dtunit=MEDLoaderBase::buildEmptyString(MED_LNAME_SIZE); - MEDLoaderBase::safeStrCpy(_name.c_str(),MED_NAME_SIZE,maa,_too_long_str); - MEDLoaderBase::safeStrCpy(_desc_name.c_str(),MED_COMMENT_SIZE,desc,_too_long_str); - MEDLoaderBase::safeStrCpy(_dt_unit.c_str(),MED_LNAME_SIZE,dtunit,_too_long_str); - int spaceDim=_clmesh->getSpaceDimension(); - int meshDim=_clmesh->getMeshDimension(); - INTERP_KERNEL::AutoPtr comp=MEDLoaderBase::buildEmptyString(spaceDim*MED_SNAME_SIZE); - INTERP_KERNEL::AutoPtr unit=MEDLoaderBase::buildEmptyString(spaceDim*MED_SNAME_SIZE); - const DataArrayDouble *coords=_clmesh->getCoords(); - if(!coords) - throw INTERP_KERNEL::Exception("MEDFileCurveLinearMesh::writeLL : no coordinates set !"); - for(int i=0;igetCoords()->getInfoOnComponent(i)); - std::string c,u; - MEDLoaderBase::splitIntoNameAndUnit(info,c,u); - MEDLoaderBase::safeStrCpy2(c.c_str(),MED_SNAME_SIZE-1,comp+i*MED_SNAME_SIZE,_too_long_str);//MED_TAILLE_PNOM-1 to avoid to write '\0' on next compo - MEDLoaderBase::safeStrCpy2(u.c_str(),MED_SNAME_SIZE-1,unit+i*MED_SNAME_SIZE,_too_long_str);//MED_TAILLE_PNOM-1 to avoid to write '\0' on next compo - } - MEDFILESAFECALLERWR0(MEDmeshCr,(fid,maa,spaceDim,meshDim,MED_STRUCTURED_MESH,desc,dtunit,MED_SORT_DTIT,MED_CARTESIAN,comp,unit)); - if(_univ_wr_status) - MEDFILESAFECALLERWR0(MEDmeshUniversalNameWr,(fid,maa)); - MEDFILESAFECALLERWR0(MEDmeshGridTypeWr,(fid,maa,MED_CURVILINEAR_GRID)); - std::vector nodeGridSt=_clmesh->getNodeGridStructure(); - MEDFILESAFECALLERWR0(MEDmeshGridStructWr,(fid,maa,_iteration,_order,_time,&nodeGridSt[0])); - - MEDFILESAFECALLERWR0(MEDmeshNodeCoordinateWr,(fid,maa,_iteration,_order,_time,MED_FULL_INTERLACE,coords->getNumberOfTuples(),coords->begin())); - // - std::string meshName(MEDLoaderBase::buildStringFromFortran(maa,MED_NAME_SIZE)); - MEDFileStructuredMesh::writeStructuredLL(fid,meshName); - - writeJoints(fid); -} - -void MEDFileCurveLinearMesh::loadCLMeshFromFile(med_idt fid, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs) -{ - ParaMEDMEM::MEDCouplingMeshType meshType; - int dummy0,dummy1; - std::string dtunit; - int mid=MEDFileMeshL2::GetMeshIdFromName(fid,mName,meshType,dummy0,dummy1,dtunit); - if(meshType!=CURVE_LINEAR) - { - std::ostringstream oss; oss << "Trying to load as curve linear an existing mesh with name '" << mName << "' that is NOT curve linear !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - MEDFileCLMeshL2 loaderl2; - loaderl2.loadAll(fid,mid,mName,dt,it); - MEDCouplingCurveLinearMesh *mesh=loaderl2.getMesh(); - mesh->incrRef(); - _clmesh=mesh; - loadStrMeshFromFile(&loaderl2,fid,mName,dt,it,mrs); -} - -MEDFileMeshMultiTS *MEDFileMeshMultiTS::New() -{ - return new MEDFileMeshMultiTS; -} - -MEDFileMeshMultiTS *MEDFileMeshMultiTS::New(const std::string& fileName) -{ - return new MEDFileMeshMultiTS(fileName); -} - -MEDFileMeshMultiTS *MEDFileMeshMultiTS::New(const std::string& fileName, const std::string& mName) -{ - return new MEDFileMeshMultiTS(fileName,mName); -} - -MEDFileMeshMultiTS *MEDFileMeshMultiTS::deepCpy() const -{ - MEDCouplingAutoRefCountObjectPtr ret=MEDFileMeshMultiTS::New(); - std::vector< MEDCouplingAutoRefCountObjectPtr > meshOneTs(_mesh_one_ts.size()); - std::size_t i=0; - for(std::vector< MEDCouplingAutoRefCountObjectPtr >::const_iterator it=_mesh_one_ts.begin();it!=_mesh_one_ts.end();it++,i++) - if((const MEDFileMesh *)*it) - meshOneTs[i]=(*it)->deepCpy(); - ret->_mesh_one_ts=meshOneTs; - return ret.retn(); -} - -std::size_t MEDFileMeshMultiTS::getHeapMemorySizeWithoutChildren() const -{ - return _mesh_one_ts.capacity()*sizeof(MEDCouplingAutoRefCountObjectPtr); -} - -std::vector MEDFileMeshMultiTS::getDirectChildrenWithNull() const -{ - std::vector ret; - for(std::vector< MEDCouplingAutoRefCountObjectPtr >::const_iterator it=_mesh_one_ts.begin();it!=_mesh_one_ts.end();it++) - ret.push_back((const MEDFileMesh *)*it); - return ret; -} - -std::string MEDFileMeshMultiTS::getName() const -{ - if(_mesh_one_ts.empty()) - throw INTERP_KERNEL::Exception("MEDFileMeshMultiTS::getName : no time steps set !"); - return _mesh_one_ts[0]->getName(); -} - -void MEDFileMeshMultiTS::setName(const std::string& newMeshName) -{ - std::string oldName(getName()); - std::vector< std::pair > v(1); - v[0].first=oldName; v[0].second=newMeshName; - changeNames(v); -} - -bool MEDFileMeshMultiTS::changeNames(const std::vector< std::pair >& modifTab) -{ - bool ret=false; - for(std::vector< MEDCouplingAutoRefCountObjectPtr >::iterator it=_mesh_one_ts.begin();it!=_mesh_one_ts.end();it++) - { - MEDFileMesh *cur(*it); - if(cur) - ret=cur->changeNames(modifTab) || ret; - } - return ret; -} - -MEDFileMesh *MEDFileMeshMultiTS::getOneTimeStep() const -{ - if(_mesh_one_ts.empty()) - throw INTERP_KERNEL::Exception("MEDFileMeshMultiTS::getOneTimeStep : empty time step set !"); - return const_cast(static_cast(_mesh_one_ts[0])); -} - -void MEDFileMeshMultiTS::setOneTimeStep(MEDFileMesh *mesh1TimeStep) -{ - if(!mesh1TimeStep) - throw INTERP_KERNEL::Exception("MEDFileMeshMultiTS::setOneTimeStep : input pointer should be different from 0 !"); - _mesh_one_ts.resize(1); - mesh1TimeStep->incrRef(); - //MEDCouplingAutoRefCountObjectPtr toto=mesh1TimeStep; - _mesh_one_ts[0]=mesh1TimeStep; -} - -MEDFileJoints * MEDFileMeshMultiTS::getJoints() const -{ - if ( MEDFileMesh* m = getOneTimeStep() ) - return m->getJoints(); - return 0; -} - -/*! - * \brief Set Joints that are common to all time-stamps - */ -void MEDFileMeshMultiTS::setJoints( MEDFileJoints* joints ) -{ - for(std::vector< MEDCouplingAutoRefCountObjectPtr >::iterator it=_mesh_one_ts.begin();it!=_mesh_one_ts.end();it++) - { - (*it)->setJoints( joints ); - } -} - -void MEDFileMeshMultiTS::write(med_idt fid) const -{ - MEDFileJoints *joints(getJoints()); - bool jointsWritten(false); - - for(std::vector< MEDCouplingAutoRefCountObjectPtr >::const_iterator it=_mesh_one_ts.begin();it!=_mesh_one_ts.end();it++) - { - if ( jointsWritten ) - const_cast(**it).setJoints( 0 ); - else - jointsWritten = true; - - (*it)->copyOptionsFrom(*this); - (*it)->write(fid); - } - - (const_cast(this))->setJoints( joints ); // restore joints -} - -void MEDFileMeshMultiTS::write(const std::string& fileName, int mode) const -{ - med_access_mode medmod=MEDFileUtilities::TraduceWriteMode(mode); - MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName.c_str(),medmod); - std::ostringstream oss; oss << "MEDFileMesh : error on attempt to write in file : \"" << fileName << "\""; - MEDFileUtilities::CheckMEDCode(fid,fid,oss.str()); - write(fid); -} - -void MEDFileMeshMultiTS::loadFromFile(const std::string& fileName, const std::string& mName) -{ - MEDFileJoints* joints = 0; - if ( !_mesh_one_ts.empty() && getOneTimeStep() ) - { - // joints of mName already read, pass them to MEDFileMesh::New() to prevent repeated reading - joints = getOneTimeStep()->getJoints(); - } - - _mesh_one_ts.clear(); //for the moment to be improved - _mesh_one_ts.push_back( MEDFileMesh::New(fileName,mName,-1,-1,0, joints )); -} - -MEDFileMeshMultiTS::MEDFileMeshMultiTS() -{ -} - -MEDFileMeshMultiTS::MEDFileMeshMultiTS(const std::string& fileName) -try -{ - std::vector ms=MEDLoader::GetMeshNames(fileName); - if(ms.empty()) - { - std::ostringstream oss; oss << "MEDFileUMesh::New : no meshes in file \"" << fileName << "\" !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - MEDFileUtilities::CheckFileForRead(fileName); - MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName.c_str(),MED_ACC_RDONLY); - int dt,it; - ParaMEDMEM::MEDCouplingMeshType meshType; - std::string dummy2; - MEDFileMeshL2::GetMeshIdFromName(fid,ms.front(),meshType,dt,it,dummy2); - loadFromFile(fileName,ms.front()); -} -catch(INTERP_KERNEL::Exception& e) -{ - throw e; -} - -MEDFileMeshMultiTS::MEDFileMeshMultiTS(const std::string& fileName, const std::string& mName) -try -{ - loadFromFile(fileName,mName); -} -catch(INTERP_KERNEL::Exception& e) -{ - throw e; -} - -MEDFileMeshes *MEDFileMeshes::New() -{ - return new MEDFileMeshes; -} - -MEDFileMeshes *MEDFileMeshes::New(const std::string& fileName) -{ - return new MEDFileMeshes(fileName); -} - -void MEDFileMeshes::write(med_idt fid) const -{ - checkCoherency(); - for(std::vector< MEDCouplingAutoRefCountObjectPtr >::const_iterator it=_meshes.begin();it!=_meshes.end();it++) - { - (*it)->copyOptionsFrom(*this); - (*it)->write(fid); - } -} - -void MEDFileMeshes::write(const std::string& fileName, int mode) const -{ - med_access_mode medmod=MEDFileUtilities::TraduceWriteMode(mode); - MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName.c_str(),medmod); - std::ostringstream oss; oss << "MEDFileMesh : error on attempt to write in file : \"" << fileName << "\""; - MEDFileUtilities::CheckMEDCode(fid,fid,oss.str()); - checkCoherency(); - write(fid); -} - -int MEDFileMeshes::getNumberOfMeshes() const -{ - return _meshes.size(); -} - -MEDFileMeshesIterator *MEDFileMeshes::iterator() -{ - return new MEDFileMeshesIterator(this); -} - -/** Return a borrowed reference (caller is not responsible) */ -MEDFileMesh *MEDFileMeshes::getMeshAtPos(int i) const -{ - if(i<0 || i>=(int)_meshes.size()) - { - std::ostringstream oss; oss << "MEDFileMeshes::getMeshAtPos : invalid mesh id given in parameter ! Should be in [0;" << _meshes.size() << ") !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - return _meshes[i]->getOneTimeStep(); -} - -/** Return a borrowed reference (caller is not responsible) */ -MEDFileMesh *MEDFileMeshes::getMeshWithName(const std::string& mname) const -{ - std::vector ms=getMeshesNames(); - std::vector::iterator it=std::find(ms.begin(),ms.end(),mname); - if(it==ms.end()) - { - std::ostringstream oss; oss << "MEDFileMeshes::getMeshWithName : Mesh \"" << mname << "\" does not exist in this ! Existing are : "; - std::copy(ms.begin(),ms.end(),std::ostream_iterator(oss," ")); - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - return getMeshAtPos((int)std::distance(ms.begin(),it)); -} - -std::vector MEDFileMeshes::getMeshesNames() const -{ - std::vector ret(_meshes.size()); - int i=0; - for(std::vector< MEDCouplingAutoRefCountObjectPtr >::const_iterator it=_meshes.begin();it!=_meshes.end();it++,i++) - { - const MEDFileMeshMultiTS *f=(*it); - if(f) - { - ret[i]=f->getName(); - } - else - { - std::ostringstream oss; oss << "MEDFileMeshes::getMeshesNames : At rank #" << i << " mesh is not defined !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - } - return ret; -} -/*const MEDFileJoints* MEDFileMeshes::getJoints() const -{ - const MEDFileJoints *ret=_joints; - if(!ret) - { - std::ostringstream oss; oss << "MEDFileMeshes::getJoints : joints is not defined !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - return ret; -}*/ - -bool MEDFileMeshes::changeNames(const std::vector< std::pair >& modifTab) -{ - bool ret=false; - for(std::vector< MEDCouplingAutoRefCountObjectPtr >::iterator it=_meshes.begin();it!=_meshes.end();it++) - { - MEDFileMeshMultiTS *cur(*it); - if(cur) - ret=cur->changeNames(modifTab) || ret; - } - return ret; -} - -void MEDFileMeshes::resize(int newSize) -{ - _meshes.resize(newSize); -} - -void MEDFileMeshes::pushMesh(MEDFileMesh *mesh) -{ - if(!mesh) - throw INTERP_KERNEL::Exception("MEDFileMeshes::pushMesh : invalid input pointer ! should be different from 0 !"); - MEDFileMeshMultiTS *elt=MEDFileMeshMultiTS::New(); - elt->setOneTimeStep(mesh); - _meshes.push_back(elt); -} - -void MEDFileMeshes::setMeshAtPos(int i, MEDFileMesh *mesh) -{ - if(!mesh) - throw INTERP_KERNEL::Exception("MEDFileMeshes::setMeshAtPos : invalid input pointer ! should be different from 0 !"); - if(i>=(int)_meshes.size()) - _meshes.resize(i+1); - MEDFileMeshMultiTS *elt=MEDFileMeshMultiTS::New(); - elt->setOneTimeStep(mesh); - _meshes[i]=elt; -} - -void MEDFileMeshes::destroyMeshAtPos(int i) -{ - if(i<0 || i>=(int)_meshes.size()) - { - std::ostringstream oss; oss << "MEDFileMeshes::destroyMeshAtPos : Invalid given id in input (" << i << ") should be in [0," << _meshes.size() << ") !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - _meshes.erase(_meshes.begin()+i); -} - -void MEDFileMeshes::loadFromFile(const std::string& fileName) -{ - std::vector ms=MEDLoader::GetMeshNames(fileName); - int i=0; - _meshes.resize(ms.size()); - for(std::vector::const_iterator it=ms.begin();it!=ms.end();it++,i++) - _meshes[i]=MEDFileMeshMultiTS::New(fileName,(*it)); -} - -MEDFileMeshes::MEDFileMeshes() -{ -} - -MEDFileMeshes::MEDFileMeshes(const std::string& fileName) -try -{ - loadFromFile(fileName); -} -catch(INTERP_KERNEL::Exception& /*e*/) -{ -} - -MEDFileMeshes *MEDFileMeshes::deepCpy() const -{ - std::vector< MEDCouplingAutoRefCountObjectPtr > meshes(_meshes.size()); - std::size_t i=0; - for(std::vector< MEDCouplingAutoRefCountObjectPtr >::const_iterator it=_meshes.begin();it!=_meshes.end();it++,i++) - if((const MEDFileMeshMultiTS *)*it) - meshes[i]=(*it)->deepCpy(); - MEDCouplingAutoRefCountObjectPtr ret=MEDFileMeshes::New(); - ret->_meshes=meshes; - return ret.retn(); -} - -std::size_t MEDFileMeshes::getHeapMemorySizeWithoutChildren() const -{ - return _meshes.capacity()*(sizeof(MEDCouplingAutoRefCountObjectPtr)); -} - -std::vector MEDFileMeshes::getDirectChildrenWithNull() const -{ - std::vector ret; - for(std::vector< MEDCouplingAutoRefCountObjectPtr >::const_iterator it=_meshes.begin();it!=_meshes.end();it++) - ret.push_back((const MEDFileMeshMultiTS *)*it); - return ret; -} - -std::string MEDFileMeshes::simpleRepr() const -{ - std::ostringstream oss; - oss << "(*****************)\n(* MEDFileMeshes *)\n(*****************)\n\n"; - simpleReprWithoutHeader(oss); - return oss.str(); -} - -void MEDFileMeshes::simpleReprWithoutHeader(std::ostream& oss) const -{ - int nbOfMeshes=getNumberOfMeshes(); - oss << "There are " << nbOfMeshes << " meshes with the following names : \n"; - std::vector mns=getMeshesNames(); - for(int i=0;i s; - for(std::vector< MEDCouplingAutoRefCountObjectPtr >::const_iterator it=_meshes.begin();it!=_meshes.end();it++,i++) - { - const MEDFileMeshMultiTS *elt=(*it); - if(!elt) - { - std::ostringstream oss; oss << MSG << i << "/" << _meshes.size() << " is empty !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - std::size_t sz=s.size(); - s.insert(std::string((*it)->getName())); - if(s.size()==sz) - { - std::ostringstream oss; oss << MSG << i << " has a name (\"" << (*it)->getName() << "\") already used by an another mesh in list !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - } -} - -MEDFileMeshesIterator::MEDFileMeshesIterator(MEDFileMeshes *ms):_ms(ms),_iter_id(0),_nb_iter(0) -{ - if(ms) - { - ms->incrRef(); - _nb_iter=ms->getNumberOfMeshes(); - } -} - -MEDFileMeshesIterator::~MEDFileMeshesIterator() -{ -} - -MEDFileMesh *MEDFileMeshesIterator::nextt() -{ - if(_iter_id<_nb_iter) - { - MEDFileMeshes *ms(_ms); - if(ms) - return ms->getMeshAtPos(_iter_id++); - else - return 0; - } - else - return 0; -} diff --git a/src/MEDLoader/MEDFileMesh.hxx b/src/MEDLoader/MEDFileMesh.hxx deleted file mode 100644 index 87ffb429a..000000000 --- a/src/MEDLoader/MEDFileMesh.hxx +++ /dev/null @@ -1,548 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 -// 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 __MEDFILEMESH_HXX__ -#define __MEDFILEMESH_HXX__ - -#include "MEDLoaderDefines.hxx" -#include "MEDFileMeshLL.hxx" -#include "MEDFileUtilities.hxx" -#include "MEDCouplingPartDefinition.hxx" -#include "MEDFileMeshReadSelector.hxx" -#include "MEDFileJoint.hxx" - -#include -#include - -namespace ParaMEDMEM -{ - class MEDFileFieldGlobsReal; - class MEDFileField1TSStructItem; - - class MEDFileMesh : public RefCountObject, public MEDFileWritable - { - public: - MEDLOADER_EXPORT static MEDFileMesh *New(const std::string& fileName, MEDFileMeshReadSelector *mrs=0); - MEDLOADER_EXPORT static MEDFileMesh *New(const std::string& fileName, const std::string& mName, int dt=-1, int it=-1, MEDFileMeshReadSelector *mrs=0, MEDFileJoints* joints=0); - MEDLOADER_EXPORT std::size_t getHeapMemorySizeWithoutChildren() const; - MEDLOADER_EXPORT std::vector getDirectChildrenWithNull() const; - MEDLOADER_EXPORT virtual MEDFileMesh *createNewEmpty() const = 0; - MEDLOADER_EXPORT virtual MEDFileMesh *deepCpy() const = 0; - MEDLOADER_EXPORT virtual MEDFileMesh *shallowCpy() const = 0; - MEDLOADER_EXPORT virtual bool isEqual(const MEDFileMesh *other, double eps, std::string& what) const; - MEDLOADER_EXPORT virtual void clearNonDiscrAttributes() const; - MEDLOADER_EXPORT virtual void setName(const std::string& name); - MEDLOADER_EXPORT bool changeNames(const std::vector< std::pair >& modifTab); - MEDLOADER_EXPORT std::string getName() const { return _name; } - MEDLOADER_EXPORT std::string getUnivName() const { return _univ_name; } - MEDLOADER_EXPORT bool getUnivNameWrStatus() const { return _univ_wr_status; } - MEDLOADER_EXPORT void setUnivNameWrStatus(bool newStatus) { _univ_wr_status=newStatus; } - MEDLOADER_EXPORT void setDescription(const std::string& name) { _desc_name=name; } - MEDLOADER_EXPORT std::string getDescription() const { return _desc_name; } - MEDLOADER_EXPORT void setOrder(int order) { _order=order; } - MEDLOADER_EXPORT int getOrder() const { return _order; } - MEDLOADER_EXPORT void setIteration(int it) { _iteration=it; } - MEDLOADER_EXPORT int getIteration() const { return _iteration; } - MEDLOADER_EXPORT void setTimeValue(double time) { _time=time; } - MEDLOADER_EXPORT void setTime(int dt, int it, double time) { _time=time; _iteration=dt; _order=it; } - MEDLOADER_EXPORT double getTime(int& dt, int& it) { dt=_iteration; it=_order; return _time; } - MEDLOADER_EXPORT double getTimeValue() const { return _time; } - MEDLOADER_EXPORT void setTimeUnit(const std::string& unit) { _dt_unit=unit; } - MEDLOADER_EXPORT std::string getTimeUnit() const { return _dt_unit; } - MEDLOADER_EXPORT std::vector getAllGeoTypes() const; - MEDLOADER_EXPORT virtual int getNumberOfNodes() const = 0; - MEDLOADER_EXPORT virtual int getNumberOfCellsAtLevel(int meshDimRelToMaxExt) const = 0; - MEDLOADER_EXPORT virtual bool hasImplicitPart() const = 0; - MEDLOADER_EXPORT virtual int buildImplicitPartIfAny(INTERP_KERNEL::NormalizedCellType gt) const = 0; - MEDLOADER_EXPORT virtual void releaseImplicitPartIfAny() const = 0; - MEDLOADER_EXPORT virtual std::vector getGeoTypesAtLevel(int meshDimRelToMax) const = 0; - MEDLOADER_EXPORT virtual std::vector getNonEmptyLevels() const = 0; - MEDLOADER_EXPORT virtual std::vector getNonEmptyLevelsExt() const = 0; - MEDLOADER_EXPORT virtual std::vector getFamArrNonEmptyLevelsExt() const = 0; - MEDLOADER_EXPORT virtual std::vector getNumArrNonEmptyLevelsExt() const = 0; - MEDLOADER_EXPORT virtual std::vector getNameArrNonEmptyLevelsExt() const = 0; - MEDLOADER_EXPORT virtual void write(const std::string& fileName, int mode) const; - MEDLOADER_EXPORT virtual void write(med_idt fid) const; - MEDLOADER_EXPORT virtual int getSizeAtLevel(int meshDimRelToMaxExt) const = 0; - MEDLOADER_EXPORT virtual MEDCouplingMesh *getGenMeshAtLevel(int meshDimRelToMax, bool renum=false) const = 0; - MEDLOADER_EXPORT virtual std::vector getDistributionOfTypes(int meshDimRelToMax) const; - MEDLOADER_EXPORT virtual void whichAreNodesFetched(const MEDFileField1TSStructItem& st, const MEDFileFieldGlobsReal *globs, std::vector& nodesFetched) const = 0; - // - MEDLOADER_EXPORT bool areFamsEqual(const MEDFileMesh *other, std::string& what) const; - MEDLOADER_EXPORT bool areGrpsEqual(const MEDFileMesh *other, std::string& what) const; - MEDLOADER_EXPORT bool existsGroup(const std::string& groupName) const; - MEDLOADER_EXPORT bool existsFamily(int famId) const; - MEDLOADER_EXPORT bool existsFamily(const std::string& familyName) const; - MEDLOADER_EXPORT void setFamilyId(const std::string& familyName, int id); - MEDLOADER_EXPORT void setFamilyIdUnique(const std::string& familyName, int id); - MEDLOADER_EXPORT virtual void addFamily(const std::string& familyName, int id); - MEDLOADER_EXPORT virtual void createGroupOnAll(int meshDimRelToMaxExt, const std::string& groupName); - MEDLOADER_EXPORT virtual bool keepFamIdsOnlyOnLevs(const std::vector& famIds, const std::vector& levs); - MEDLOADER_EXPORT void addFamilyOnGrp(const std::string& grpName, const std::string& famName); - MEDLOADER_EXPORT std::string findOrCreateAndGiveFamilyWithId(int id, bool& created); - MEDLOADER_EXPORT void setFamilyInfo(const std::map& info); - MEDLOADER_EXPORT void setGroupInfo(const std::map >&info); - MEDLOADER_EXPORT void copyFamGrpMapsFrom(const MEDFileMesh& other); - MEDLOADER_EXPORT void clearGrpMap(); - MEDLOADER_EXPORT void clearFamMap(); - MEDLOADER_EXPORT void clearFamGrpMaps(); - MEDLOADER_EXPORT const std::map& getFamilyInfo() const { return _families; } - MEDLOADER_EXPORT const std::map >& getGroupInfo() const { return _groups; } - MEDLOADER_EXPORT std::vector getFamiliesOnGroup(const std::string& name) const; - MEDLOADER_EXPORT std::vector getFamiliesOnGroups(const std::vector& grps) const; - MEDLOADER_EXPORT std::vector getFamiliesIdsOnGroup(const std::string& name) const; - MEDLOADER_EXPORT void setFamiliesOnGroup(const std::string& name, const std::vector& fams); - MEDLOADER_EXPORT void setFamiliesIdsOnGroup(const std::string& name, const std::vector& famIds); - MEDLOADER_EXPORT std::vector getGroupsOnFamily(const std::string& name) const; - MEDLOADER_EXPORT void setGroupsOnFamily(const std::string& famName, const std::vector& grps); - MEDLOADER_EXPORT std::vector getGroupsNames() const; - MEDLOADER_EXPORT std::vector getFamiliesNames() const; - MEDLOADER_EXPORT void assignFamilyNameWithGroupName(); - MEDLOADER_EXPORT std::vector removeEmptyGroups(); - MEDLOADER_EXPORT void removeGroup(const std::string& name); - MEDLOADER_EXPORT void removeFamily(const std::string& name); - MEDLOADER_EXPORT std::vector removeOrphanGroups(); - MEDLOADER_EXPORT std::vector removeOrphanFamilies(); - MEDLOADER_EXPORT void removeFamiliesReferedByNoGroups(); - MEDLOADER_EXPORT void rearrangeFamilies(); - MEDLOADER_EXPORT void checkOrphanFamilyZero() const; - MEDLOADER_EXPORT void changeGroupName(const std::string& oldName, const std::string& newName); - MEDLOADER_EXPORT void changeFamilyName(const std::string& oldName, const std::string& newName); - MEDLOADER_EXPORT void changeFamilyId(int oldId, int newId); - MEDLOADER_EXPORT void changeAllGroupsContainingFamily(const std::string& familyNameToChange, const std::vector& newFamiliesNames); - MEDLOADER_EXPORT int getFamilyId(const std::string& name) const; - MEDLOADER_EXPORT int getMaxAbsFamilyId() const; - MEDLOADER_EXPORT int getMaxFamilyId() const; - MEDLOADER_EXPORT int getMinFamilyId() const; - MEDLOADER_EXPORT int getTheMaxAbsFamilyId() const; - MEDLOADER_EXPORT int getTheMaxFamilyId() const; - MEDLOADER_EXPORT int getTheMinFamilyId() const; - MEDLOADER_EXPORT virtual int getMaxAbsFamilyIdInArrays() const = 0; - MEDLOADER_EXPORT virtual int getMaxFamilyIdInArrays() const = 0; - MEDLOADER_EXPORT virtual int getMinFamilyIdInArrays() const = 0; - MEDLOADER_EXPORT DataArrayInt *getAllFamiliesIdsReferenced() const; - MEDLOADER_EXPORT DataArrayInt *computeAllFamilyIdsInUse() const; - MEDLOADER_EXPORT std::vector getFamiliesIds(const std::vector& famNames) const; - MEDLOADER_EXPORT std::string getFamilyNameGivenId(int id) const; - MEDLOADER_EXPORT bool ensureDifferentFamIdsPerLevel(); - MEDLOADER_EXPORT void normalizeFamIdsTrio(); - MEDLOADER_EXPORT void normalizeFamIdsMEDFile(); - MEDLOADER_EXPORT virtual int getMeshDimension() const = 0; - MEDLOADER_EXPORT virtual std::string simpleRepr() const; - MEDLOADER_EXPORT virtual std::string advancedRepr() const = 0; - // - MEDLOADER_EXPORT virtual void setGroupsAtLevel(int meshDimRelToMaxExt, const std::vector& grps, bool renum=false); - MEDLOADER_EXPORT virtual void setFamilyFieldArr(int meshDimRelToMaxExt, DataArrayInt *famArr) = 0; - MEDLOADER_EXPORT virtual void setRenumFieldArr(int meshDimRelToMaxExt, DataArrayInt *renumArr) = 0; - MEDLOADER_EXPORT virtual void setNameFieldAtLevel(int meshDimRelToMaxExt, DataArrayAsciiChar *nameArr) = 0; - MEDLOADER_EXPORT virtual void addNodeGroup(const DataArrayInt *ids) = 0; - MEDLOADER_EXPORT virtual void addGroup(int meshDimRelToMaxExt, const DataArrayInt *ids) = 0; - MEDLOADER_EXPORT virtual const DataArrayInt *getFamilyFieldAtLevel(int meshDimRelToMaxExt) const = 0; - MEDLOADER_EXPORT virtual DataArrayInt *getFamilyFieldAtLevel(int meshDimRelToMaxExt) = 0; - MEDLOADER_EXPORT DataArrayInt *getOrCreateAndGetFamilyFieldAtLevel(int meshDimRelToMaxExt); - MEDLOADER_EXPORT virtual const DataArrayInt *getNumberFieldAtLevel(int meshDimRelToMaxExt) const = 0; - MEDLOADER_EXPORT virtual const DataArrayInt *getRevNumberFieldAtLevel(int meshDimRelToMaxExt) const = 0; - MEDLOADER_EXPORT virtual const DataArrayAsciiChar *getNameFieldAtLevel(int meshDimRelToMaxExt) const = 0; - MEDLOADER_EXPORT virtual DataArrayInt *getFamiliesArr(int meshDimRelToMaxExt, const std::vector& fams, bool renum=false) const = 0; - MEDLOADER_EXPORT virtual DataArrayInt *getGroupsArr(int meshDimRelToMaxExt, const std::vector& grps, bool renum=false) const; - MEDLOADER_EXPORT virtual DataArrayInt *getGroupArr(int meshDimRelToMaxExt, const std::string& grp, bool renum=false) const; - MEDLOADER_EXPORT virtual DataArrayInt *getFamilyArr(int meshDimRelToMaxExt, const std::string& fam, bool renum=false) const; - MEDLOADER_EXPORT virtual DataArrayInt *getNodeGroupArr(const std::string& grp, bool renum=false) const; - MEDLOADER_EXPORT virtual DataArrayInt *getNodeGroupsArr(const std::vector& grps, bool renum=false) const; - MEDLOADER_EXPORT virtual DataArrayInt *getNodeFamilyArr(const std::string& fam, bool renum=false) const; - MEDLOADER_EXPORT virtual DataArrayInt *getNodeFamiliesArr(const std::vector& fams, bool renum=false) const; - // tools - MEDLOADER_EXPORT virtual bool unPolyze(std::vector& oldCode, std::vector& newCode, DataArrayInt *& o2nRenumCell) = 0; - MEDLOADER_EXPORT int getNumberOfJoints(); - MEDLOADER_EXPORT MEDFileJoints *getJoints() const; - MEDLOADER_EXPORT void setJoints( MEDFileJoints* joints ); - protected: - MEDFileMesh(); - //! protected because no way in MED file API to specify this name - void setUnivName(const std::string& name) { _univ_name=name; } - void addFamilyOnAllGroupsHaving(const std::string& famName, const std::string& otherFamName); - virtual void writeLL(med_idt fid) const = 0; - void dealWithTinyInfo(const MEDCouplingMesh *m); - virtual void synchronizeTinyInfoOnLeaves() const = 0; - void getFamilyRepr(std::ostream& oss) const; - virtual void appendFamilyEntries(const DataArrayInt *famIds, const std::vector< std::vector >& fidsOfGrps, const std::vector& grpNames); - virtual void changeFamilyIdArr(int oldId, int newId) = 0; - virtual std::list< MEDCouplingAutoRefCountObjectPtr > getAllNonNullFamilyIds() const = 0; - void addGroupUnderground(bool isNodeGroup, const DataArrayInt *ids, DataArrayInt *famArr); - static void TranslateFamilyIds(int offset, DataArrayInt *famArr, std::vector< std::vector >& famIdsPerGrp); - static void ChangeAllGroupsContainingFamily(std::map >& groups, const std::string& familyNameToChange, const std::vector& newFamiliesNames); - static std::string FindOrCreateAndGiveFamilyWithId(std::map& families, int id, bool& created); - static std::string CreateNameNotIn(const std::string& nameTry, const std::vector& namesToAvoid); - static int PutInThirdComponentOfCodeOffset(std::vector& code, int strt); - void writeJoints(med_idt fid) const; - void loadJointsFromFile(med_idt fid, MEDFileJoints* toUseInstedOfReading=0); - protected: - int _order; - int _iteration; - double _time; - std::string _dt_unit; - std::string _name; - //! this attribute do not impact the state of instance -> mutable - mutable std::string _univ_name; - bool _univ_wr_status; - std::string _desc_name; - MEDCouplingAutoRefCountObjectPtr _joints; - protected: - std::map > _groups; - std::map _families; - public: - MEDLOADER_EXPORT static const char DFT_FAM_NAME[]; - }; - - class MEDFileUMesh : public MEDFileMesh - { - friend class MEDFileMesh; - public: - MEDLOADER_EXPORT static MEDFileUMesh *New(const std::string& fileName, const std::string& mName, int dt=-1, int it=-1, MEDFileMeshReadSelector *mrs=0); - MEDLOADER_EXPORT static MEDFileUMesh *New(const std::string& fileName, MEDFileMeshReadSelector *mrs=0); - MEDLOADER_EXPORT static MEDFileUMesh *New(); - MEDLOADER_EXPORT static MEDFileUMesh *LoadPartOf(const std::string& fileName, const std::string& mName, const std::vector& types, const std::vector& slicPerTyp, int dt=-1, int it=-1, MEDFileMeshReadSelector *mrs=0); - MEDLOADER_EXPORT static MEDFileUMesh *LoadPartOf(med_idt fid, const std::string& mName, const std::vector& types, const std::vector& slicPerTyp, int dt=-1, int it=-1, MEDFileMeshReadSelector *mrs=0); - MEDLOADER_EXPORT std::size_t getHeapMemorySizeWithoutChildren() const; - MEDLOADER_EXPORT std::vector getDirectChildrenWithNull() const; - MEDLOADER_EXPORT MEDFileMesh *createNewEmpty() const; - MEDLOADER_EXPORT MEDFileMesh *deepCpy() const; - MEDLOADER_EXPORT MEDFileMesh *shallowCpy() const; - MEDLOADER_EXPORT bool isEqual(const MEDFileMesh *other, double eps, std::string& what) const; - MEDLOADER_EXPORT void clearNonDiscrAttributes() const; - MEDLOADER_EXPORT void setName(const std::string& name); - // - MEDLOADER_EXPORT int getMaxAbsFamilyIdInArrays() const; - MEDLOADER_EXPORT int getMaxFamilyIdInArrays() const; - MEDLOADER_EXPORT int getMinFamilyIdInArrays() const; - MEDLOADER_EXPORT int getMeshDimension() const; - MEDLOADER_EXPORT int getSpaceDimension() const; - MEDLOADER_EXPORT std::string simpleRepr() const; - MEDLOADER_EXPORT std::string advancedRepr() const; - MEDLOADER_EXPORT int getSizeAtLevel(int meshDimRelToMaxExt) const; - MEDLOADER_EXPORT const DataArrayInt *getFamilyFieldAtLevel(int meshDimRelToMaxExt) const; - MEDLOADER_EXPORT DataArrayInt *getFamilyFieldAtLevel(int meshDimRelToMaxExt); - MEDLOADER_EXPORT const DataArrayInt *getNumberFieldAtLevel(int meshDimRelToMaxExt) const; - MEDLOADER_EXPORT const DataArrayInt *getRevNumberFieldAtLevel(int meshDimRelToMaxExt) const; - MEDLOADER_EXPORT const DataArrayAsciiChar *getNameFieldAtLevel(int meshDimRelToMaxExt) const; - MEDLOADER_EXPORT const PartDefinition *getPartDefAtLevel(int meshDimRelToMaxExt, INTERP_KERNEL::NormalizedCellType gt=INTERP_KERNEL::NORM_ERROR) const; - MEDLOADER_EXPORT int getNumberOfNodes() const; - MEDLOADER_EXPORT int getNumberOfCellsAtLevel(int meshDimRelToMaxExt) const; - MEDLOADER_EXPORT bool hasImplicitPart() const; - MEDLOADER_EXPORT int buildImplicitPartIfAny(INTERP_KERNEL::NormalizedCellType gt) const; - MEDLOADER_EXPORT void releaseImplicitPartIfAny() const; - MEDLOADER_EXPORT std::vector getGeoTypesAtLevel(int meshDimRelToMax) const; - MEDLOADER_EXPORT void whichAreNodesFetched(const MEDFileField1TSStructItem& st, const MEDFileFieldGlobsReal *globs, std::vector& nodesFetched) const; - MEDLOADER_EXPORT std::vector getNonEmptyLevels() const; - MEDLOADER_EXPORT std::vector getNonEmptyLevelsExt() const; - MEDLOADER_EXPORT std::vector getFamArrNonEmptyLevelsExt() const; - MEDLOADER_EXPORT std::vector getNumArrNonEmptyLevelsExt() const; - MEDLOADER_EXPORT std::vector getNameArrNonEmptyLevelsExt() const; - MEDLOADER_EXPORT std::vector getGrpNonEmptyLevels(const std::string& grp) const; - MEDLOADER_EXPORT std::vector getGrpNonEmptyLevelsExt(const std::string& grp) const; - MEDLOADER_EXPORT std::vector getFamNonEmptyLevels(const std::string& fam) const; - MEDLOADER_EXPORT std::vector getFamNonEmptyLevelsExt(const std::string& fam) const; - MEDLOADER_EXPORT std::vector getGrpsNonEmptyLevels(const std::vector& grps) const; - MEDLOADER_EXPORT std::vector getGrpsNonEmptyLevelsExt(const std::vector& grps) const; - MEDLOADER_EXPORT std::vector getFamsNonEmptyLevels(const std::vector& fams) const; - MEDLOADER_EXPORT std::vector getFamsNonEmptyLevelsExt(const std::vector& fams) const; - MEDLOADER_EXPORT std::vector getGroupsOnSpecifiedLev(int meshDimRelToMaxExt) const; - MEDLOADER_EXPORT DataArrayDouble *getCoords() const; - MEDLOADER_EXPORT MEDCouplingUMesh *getGroup(int meshDimRelToMaxExt, const std::string& grp, bool renum=false) const; - MEDLOADER_EXPORT MEDCouplingUMesh *getGroups(int meshDimRelToMaxExt, const std::vector& grps, bool renum=false) const; - MEDLOADER_EXPORT MEDCouplingUMesh *getFamily(int meshDimRelToMaxExt, const std::string& fam, bool renum=false) const; - MEDLOADER_EXPORT MEDCouplingUMesh *getFamilies(int meshDimRelToMaxExt, const std::vector& fams, bool renum=false) const; - MEDLOADER_EXPORT DataArrayInt *getFamiliesArr(int meshDimRelToMaxExt, const std::vector& fams, bool renum=false) const; - MEDLOADER_EXPORT MEDCouplingUMesh *getMeshAtLevel(int meshDimRelToMaxExt, bool renum=false) const; - MEDLOADER_EXPORT MEDCouplingMesh *getGenMeshAtLevel(int meshDimRelToMax, bool renum=false) const; - MEDLOADER_EXPORT std::vector getDistributionOfTypes(int meshDimRelToMax) const; - MEDLOADER_EXPORT MEDCouplingUMesh *getLevel0Mesh(bool renum=false) const; - MEDLOADER_EXPORT MEDCouplingUMesh *getLevelM1Mesh(bool renum=false) const; - MEDLOADER_EXPORT MEDCouplingUMesh *getLevelM2Mesh(bool renum=false) const; - MEDLOADER_EXPORT MEDCouplingUMesh *getLevelM3Mesh(bool renum=false) const; - MEDLOADER_EXPORT void forceComputationOfParts() const; - MEDLOADER_EXPORT std::vector getDirectUndergroundSingleGeoTypeMeshes(int meshDimRelToMax) const; - MEDLOADER_EXPORT MEDCoupling1GTUMesh *getDirectUndergroundSingleGeoTypeMesh(INTERP_KERNEL::NormalizedCellType gt) const; - MEDLOADER_EXPORT DataArrayInt *extractFamilyFieldOnGeoType(INTERP_KERNEL::NormalizedCellType gt) const; - MEDLOADER_EXPORT DataArrayInt *extractNumberFieldOnGeoType(INTERP_KERNEL::NormalizedCellType gt) const; - MEDLOADER_EXPORT int getRelativeLevOnGeoType(INTERP_KERNEL::NormalizedCellType gt) const; - // - MEDLOADER_EXPORT void setFamilyNameAttachedOnId(int id, const std::string& newFamName); - MEDLOADER_EXPORT void setCoords(DataArrayDouble *coords); - MEDLOADER_EXPORT void eraseGroupsAtLevel(int meshDimRelToMaxExt); - MEDLOADER_EXPORT void setFamilyFieldArr(int meshDimRelToMaxExt, DataArrayInt *famArr); - MEDLOADER_EXPORT void setRenumFieldArr(int meshDimRelToMaxExt, DataArrayInt *renumArr); - MEDLOADER_EXPORT void setNameFieldAtLevel(int meshDimRelToMaxExt, DataArrayAsciiChar *nameArr); - MEDLOADER_EXPORT void addNodeGroup(const DataArrayInt *ids); - MEDLOADER_EXPORT void addGroup(int meshDimRelToMaxExt, const DataArrayInt *ids); - MEDLOADER_EXPORT void removeMeshAtLevel(int meshDimRelToMax); - MEDLOADER_EXPORT void setMeshAtLevel(int meshDimRelToMax, MEDCoupling1GTUMesh *m); - MEDLOADER_EXPORT void setMeshAtLevel(int meshDimRelToMax, MEDCouplingUMesh *m, bool newOrOld=false); - MEDLOADER_EXPORT void setMeshes(const std::vector& ms, bool renum=false); - MEDLOADER_EXPORT void setGroupsFromScratch(int meshDimRelToMax, const std::vector& ms, bool renum=false); - MEDLOADER_EXPORT void setGroupsOnSetMesh(int meshDimRelToMax, const std::vector& ms, bool renum=false); - MEDLOADER_EXPORT void optimizeFamilies(); - // tools - MEDLOADER_EXPORT void buildInnerBoundaryAlongM1Group(const std::string& grpNameM1, DataArrayInt *&nodesDuplicated, DataArrayInt *&cellsModified, DataArrayInt *&cellsNotModified); - MEDLOADER_EXPORT bool unPolyze(std::vector& oldCode, std::vector& newCode, DataArrayInt *& o2nRenumCell); - MEDLOADER_EXPORT DataArrayInt *zipCoords(); - MEDLOADER_EXPORT MEDFileUMesh *buildExtrudedMesh(const MEDCouplingUMesh *m1D, int policy) const; - MEDLOADER_EXPORT MEDFileUMesh *linearToQuadratic(int conversionType=0, double eps=1e-12) const; - MEDLOADER_EXPORT MEDFileUMesh *quadraticToLinear(double eps=1e-12) const; - // serialization - MEDLOADER_EXPORT void serialize(std::vector& tinyDouble, std::vector& tinyInt, std::vector& tinyStr, - std::vector< MEDCouplingAutoRefCountObjectPtr >& bigArraysI, MEDCouplingAutoRefCountObjectPtr& bigArrayD); - MEDLOADER_EXPORT void unserialize(std::vector& tinyDouble, std::vector& tinyInt, std::vector& tinyStr, - std::vector< MEDCouplingAutoRefCountObjectPtr >& bigArraysI, MEDCouplingAutoRefCountObjectPtr& bigArrayD); - private: - MEDLOADER_EXPORT ~MEDFileUMesh(); - void writeLL(med_idt fid) const; - MEDFileUMesh(); - MEDFileUMesh(med_idt fid, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs); - void loadPartUMeshFromFile(med_idt fid, const std::string& mName, const std::vector& types, const std::vector& slicPerTyp, int dt=-1, int it=-1, MEDFileMeshReadSelector *mrs=0); - void loadUMeshFromFile(med_idt fid, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs); - void dispatchLoadedPart(med_idt fid, const MEDFileUMeshL2& loaderl2, const std::string& mName, MEDFileMeshReadSelector *mrs); - const MEDFileUMeshSplitL1 *getMeshAtLevSafe(int meshDimRelToMaxExt) const; - MEDFileUMeshSplitL1 *getMeshAtLevSafe(int meshDimRelToMaxExt); - void checkMeshDimCoherency(int meshDim, int meshDimRelToMax) const; - DataArrayDouble *checkMultiMesh(const std::vector& ms) const; - void computeRevNum() const; - void synchronizeTinyInfoOnLeaves() const; - void changeFamilyIdArr(int oldId, int newId); - std::list< MEDCouplingAutoRefCountObjectPtr > getAllNonNullFamilyIds() const; - MEDCouplingAutoRefCountObjectPtr& checkAndGiveEntryInSplitL1(int meshDimRelToMax, MEDCouplingPointSet *m); - private: - std::vector< MEDCouplingAutoRefCountObjectPtr > _ms; - MEDCouplingAutoRefCountObjectPtr _coords; - MEDCouplingAutoRefCountObjectPtr _fam_coords; - MEDCouplingAutoRefCountObjectPtr _num_coords; - MEDCouplingAutoRefCountObjectPtr _name_coords; - mutable MEDCouplingAutoRefCountObjectPtr _rev_num_coords; - MEDCouplingAutoRefCountObjectPtr _part_coords; - }; - - class MEDFileStructuredMesh : public MEDFileMesh - { - friend class MEDFileMesh; - public: - MEDLOADER_EXPORT std::size_t getHeapMemorySizeWithoutChildren() const; - MEDLOADER_EXPORT std::vector getDirectChildrenWithNull() const; - MEDLOADER_EXPORT int getMaxAbsFamilyIdInArrays() const; - MEDLOADER_EXPORT int getMaxFamilyIdInArrays() const; - MEDLOADER_EXPORT int getMinFamilyIdInArrays() const; - MEDLOADER_EXPORT bool isEqual(const MEDFileMesh *other, double eps, std::string& what) const; - MEDLOADER_EXPORT void clearNonDiscrAttributes() const; - MEDLOADER_EXPORT DataArrayInt *getFamiliesArr(int meshDimRelToMaxExt, const std::vector& fams, bool renum=false) const; - MEDLOADER_EXPORT const DataArrayInt *getFamilyFieldAtLevel(int meshDimRelToMaxExt) const; - MEDLOADER_EXPORT DataArrayInt *getFamilyFieldAtLevel(int meshDimRelToMaxExt); - MEDLOADER_EXPORT void setFamilyFieldArr(int meshDimRelToMaxExt, DataArrayInt *famArr); - MEDLOADER_EXPORT void setRenumFieldArr(int meshDimRelToMaxExt, DataArrayInt *renumArr); - MEDLOADER_EXPORT void setNameFieldAtLevel(int meshDimRelToMaxExt, DataArrayAsciiChar *nameArr); - MEDLOADER_EXPORT void addNodeGroup(const DataArrayInt *ids); - MEDLOADER_EXPORT void addGroup(int meshDimRelToMaxExt, const DataArrayInt *ids); - MEDLOADER_EXPORT const DataArrayInt *getNumberFieldAtLevel(int meshDimRelToMaxExt) const; - MEDLOADER_EXPORT const DataArrayInt *getRevNumberFieldAtLevel(int meshDimRelToMaxExt) const; - MEDLOADER_EXPORT const DataArrayAsciiChar *getNameFieldAtLevel(int meshDimRelToMaxExt) const; - MEDLOADER_EXPORT std::vector getNonEmptyLevels() const; - MEDLOADER_EXPORT std::vector getNonEmptyLevelsExt() const; - MEDLOADER_EXPORT std::vector getFamArrNonEmptyLevelsExt() const; - MEDLOADER_EXPORT std::vector getNumArrNonEmptyLevelsExt() const; - MEDLOADER_EXPORT std::vector getNameArrNonEmptyLevelsExt() const; - MEDCouplingMesh *getGenMeshAtLevel(int meshDimRelToMax, bool renum=false) const; - MEDLOADER_EXPORT int getSizeAtLevel(int meshDimRelToMaxExt) const; - MEDLOADER_EXPORT int getNumberOfNodes() const; - MEDLOADER_EXPORT int getNumberOfCellsAtLevel(int meshDimRelToMaxExt) const; - MEDLOADER_EXPORT bool hasImplicitPart() const; - MEDLOADER_EXPORT int buildImplicitPartIfAny(INTERP_KERNEL::NormalizedCellType gt) const; - MEDLOADER_EXPORT void releaseImplicitPartIfAny() const; - MEDLOADER_EXPORT MEDCoupling1SGTUMesh *getImplicitFaceMesh() const; - MEDLOADER_EXPORT std::vector getGeoTypesAtLevel(int meshDimRelToMax) const; - MEDLOADER_EXPORT void whichAreNodesFetched(const MEDFileField1TSStructItem& st, const MEDFileFieldGlobsReal *globs, std::vector& nodesFetched) const; - MEDLOADER_EXPORT virtual const MEDCouplingStructuredMesh *getStructuredMesh() const = 0; - // tools - MEDLOADER_EXPORT bool unPolyze(std::vector& oldCode, std::vector& newCode, DataArrayInt *& o2nRenumCell); - protected: - ~MEDFileStructuredMesh() { } - void changeFamilyIdArr(int oldId, int newId); - std::list< MEDCouplingAutoRefCountObjectPtr > getAllNonNullFamilyIds() const; - void deepCpyAttributes(); - void loadStrMeshFromFile(MEDFileStrMeshL2 *strm, med_idt fid, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs); - void writeStructuredLL(med_idt fid, const std::string& maa) const; - void buildImplicitPart() const; - void buildMinusOneImplicitPartIfNeeded() const; - static med_geometry_type GetGeoTypeFromMeshDim(int meshDim); - private: - static void LoadStrMeshDAFromFile(med_idt fid, int meshDim, int dt, int it, const std::string& mName, MEDFileMeshReadSelector *mrs, - MEDCouplingAutoRefCountObjectPtr& famCells, MEDCouplingAutoRefCountObjectPtr& numCells, MEDCouplingAutoRefCountObjectPtr& namesCells); - private: - MEDCouplingAutoRefCountObjectPtr _fam_nodes; - MEDCouplingAutoRefCountObjectPtr _num_nodes; - MEDCouplingAutoRefCountObjectPtr _names_nodes; - MEDCouplingAutoRefCountObjectPtr _fam_cells; - MEDCouplingAutoRefCountObjectPtr _num_cells; - MEDCouplingAutoRefCountObjectPtr _names_cells; - MEDCouplingAutoRefCountObjectPtr _fam_faces; - MEDCouplingAutoRefCountObjectPtr _num_faces; - MEDCouplingAutoRefCountObjectPtr _names_faces; - mutable MEDCouplingAutoRefCountObjectPtr _rev_num_nodes; - mutable MEDCouplingAutoRefCountObjectPtr _rev_num_cells; - mutable MEDCouplingAutoRefCountObjectPtr _faces_if_necessary; - }; - - class MEDFileCMesh : public MEDFileStructuredMesh - { - friend class MEDFileMesh; - public: - MEDLOADER_EXPORT static MEDFileCMesh *New(); - MEDLOADER_EXPORT static MEDFileCMesh *New(const std::string& fileName, MEDFileMeshReadSelector *mrs=0); - MEDLOADER_EXPORT static MEDFileCMesh *New(const std::string& fileName, const std::string& mName, int dt=-1, int it=-1, MEDFileMeshReadSelector *mrs=0); - MEDLOADER_EXPORT std::size_t getHeapMemorySizeWithoutChildren() const; - MEDLOADER_EXPORT std::vector getDirectChildrenWithNull() const; - MEDLOADER_EXPORT MEDFileMesh *createNewEmpty() const; - MEDLOADER_EXPORT MEDFileMesh *deepCpy() const; - MEDLOADER_EXPORT MEDFileMesh *shallowCpy() const; - MEDLOADER_EXPORT bool isEqual(const MEDFileMesh *other, double eps, std::string& what) const; - MEDLOADER_EXPORT int getMeshDimension() const; - MEDLOADER_EXPORT int getSpaceDimension() const; - MEDLOADER_EXPORT std::string simpleRepr() const; - MEDLOADER_EXPORT std::string advancedRepr() const; - MEDLOADER_EXPORT void clearNonDiscrAttributes() const; - MEDLOADER_EXPORT const MEDCouplingCMesh *getMesh() const; - MEDLOADER_EXPORT void setMesh(MEDCouplingCMesh *m); - private: - ~MEDFileCMesh() { } - const MEDCouplingStructuredMesh *getStructuredMesh() const; - void writeLL(med_idt fid) const; - MEDFileCMesh(); - void synchronizeTinyInfoOnLeaves() const; - MEDFileCMesh(med_idt fid, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs); - void loadCMeshFromFile(med_idt fid, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs); - private: - MEDCouplingAutoRefCountObjectPtr _cmesh; - }; - - class MEDFileCurveLinearMesh : public MEDFileStructuredMesh - { - friend class MEDFileMesh; - public: - MEDLOADER_EXPORT static MEDFileCurveLinearMesh *New(); - MEDLOADER_EXPORT static MEDFileCurveLinearMesh *New(const std::string& fileName, MEDFileMeshReadSelector *mrs=0); - MEDLOADER_EXPORT static MEDFileCurveLinearMesh *New(const std::string& fileName, const std::string& mName, int dt=-1, int it=-1, MEDFileMeshReadSelector *mrs=0); - MEDLOADER_EXPORT std::size_t getHeapMemorySizeWithoutChildren() const; - MEDLOADER_EXPORT std::vector getDirectChildrenWithNull() const; - MEDLOADER_EXPORT MEDFileMesh *createNewEmpty() const; - MEDLOADER_EXPORT MEDFileMesh *deepCpy() const; - MEDLOADER_EXPORT MEDFileMesh *shallowCpy() const; - MEDLOADER_EXPORT bool isEqual(const MEDFileMesh *other, double eps, std::string& what) const; - MEDLOADER_EXPORT int getMeshDimension() const; - MEDLOADER_EXPORT std::string simpleRepr() const; - MEDLOADER_EXPORT std::string advancedRepr() const; - MEDLOADER_EXPORT void clearNonDiscrAttributes() const; - MEDLOADER_EXPORT const MEDCouplingCurveLinearMesh *getMesh() const; - MEDLOADER_EXPORT void setMesh(MEDCouplingCurveLinearMesh *m); - private: - ~MEDFileCurveLinearMesh() { } - MEDFileCurveLinearMesh(); - MEDFileCurveLinearMesh(med_idt fid, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs); - const MEDCouplingStructuredMesh *getStructuredMesh() const; - void synchronizeTinyInfoOnLeaves() const; - void writeLL(med_idt fid) const; - void loadCLMeshFromFile(med_idt fid, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs);//to imp - private: - MEDCouplingAutoRefCountObjectPtr _clmesh; - }; - - class MEDFileMeshMultiTS : public RefCountObject, public MEDFileWritable - { - public: - MEDLOADER_EXPORT static MEDFileMeshMultiTS *New(); - MEDLOADER_EXPORT static MEDFileMeshMultiTS *New(const std::string& fileName); - MEDLOADER_EXPORT static MEDFileMeshMultiTS *New(const std::string& fileName, const std::string& mName); - MEDLOADER_EXPORT MEDFileMeshMultiTS *deepCpy() const; - MEDLOADER_EXPORT std::size_t getHeapMemorySizeWithoutChildren() const; - MEDLOADER_EXPORT std::vector getDirectChildrenWithNull() const; - MEDLOADER_EXPORT std::string getName() const; - MEDLOADER_EXPORT void setName(const std::string& newMeshName); - MEDLOADER_EXPORT bool changeNames(const std::vector< std::pair >& modifTab); - MEDLOADER_EXPORT MEDFileMesh *getOneTimeStep() const; - MEDLOADER_EXPORT void write(med_idt fid) const; - MEDLOADER_EXPORT void write(const std::string& fileName, int mode) const; - MEDLOADER_EXPORT void setOneTimeStep(MEDFileMesh *mesh1TimeStep); - MEDLOADER_EXPORT MEDFileJoints *getJoints() const; - MEDLOADER_EXPORT void setJoints( MEDFileJoints* joints ); - private: - ~MEDFileMeshMultiTS() { } - void loadFromFile(const std::string& fileName, const std::string& mName); - MEDFileMeshMultiTS(); - MEDFileMeshMultiTS(const std::string& fileName); - MEDFileMeshMultiTS(const std::string& fileName, const std::string& mName); - private: - std::vector< MEDCouplingAutoRefCountObjectPtr > _mesh_one_ts; - }; - - class MEDFileMeshesIterator; - - class MEDFileMeshes : public RefCountObject, public MEDFileWritable - { - public: - MEDLOADER_EXPORT static MEDFileMeshes *New(); - MEDLOADER_EXPORT static MEDFileMeshes *New(const std::string& fileName); - MEDLOADER_EXPORT MEDFileMeshes *deepCpy() const; - MEDLOADER_EXPORT std::size_t getHeapMemorySizeWithoutChildren() const; - MEDLOADER_EXPORT std::vector getDirectChildrenWithNull() const; - MEDLOADER_EXPORT std::string simpleRepr() const; - MEDLOADER_EXPORT void simpleReprWithoutHeader(std::ostream& oss) const; - MEDLOADER_EXPORT void write(const std::string& fileName, int mode) const; - MEDLOADER_EXPORT void write(med_idt fid) const; - MEDLOADER_EXPORT int getNumberOfMeshes() const; - MEDLOADER_EXPORT MEDFileMeshesIterator *iterator(); - MEDLOADER_EXPORT MEDFileMesh *getMeshAtPos(int i) const; - MEDLOADER_EXPORT MEDFileMesh *getMeshWithName(const std::string& mname) const; - MEDLOADER_EXPORT std::vector getMeshesNames() const; - MEDLOADER_EXPORT bool changeNames(const std::vector< std::pair >& modifTab); - // - MEDLOADER_EXPORT void resize(int newSize); - MEDLOADER_EXPORT void pushMesh(MEDFileMesh *mesh); - MEDLOADER_EXPORT void setMeshAtPos(int i, MEDFileMesh *mesh); - MEDLOADER_EXPORT void destroyMeshAtPos(int i); - private: - ~MEDFileMeshes() { } - void checkCoherency() const; - void loadFromFile(const std::string& fileName); - MEDFileMeshes(); - MEDFileMeshes(const std::string& fileName); - private: - std::vector< MEDCouplingAutoRefCountObjectPtr > _meshes; - }; - - class MEDFileMeshesIterator - { - public: - MEDLOADER_EXPORT MEDFileMeshesIterator(MEDFileMeshes *ms); - MEDLOADER_EXPORT ~MEDFileMeshesIterator(); - MEDLOADER_EXPORT MEDFileMesh *nextt(); - private: - MEDCouplingAutoRefCountObjectPtr _ms; - int _iter_id; - int _nb_iter; - }; -} - -#endif diff --git a/src/MEDLoader/MEDFileMeshElt.cxx b/src/MEDLoader/MEDFileMeshElt.cxx deleted file mode 100644 index c2aa5504e..000000000 --- a/src/MEDLoader/MEDFileMeshElt.cxx +++ /dev/null @@ -1,404 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 -// 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 "MEDFileMeshElt.hxx" -#include "MEDFileSafeCaller.txx" -#include "MEDFileMeshReadSelector.hxx" - -#include "MEDCouplingUMesh.hxx" - -#include "InterpKernelException.hxx" -#include "InterpKernelAutoPtr.hxx" -#include "CellModel.hxx" - -#include - -extern med_geometry_type typmai3[34]; - -using namespace ParaMEDMEM; - -MEDFileUMeshPerType *MEDFileUMeshPerType::New(med_idt fid, const char *mName, int dt, int it, int mdim, med_geometry_type geoElt, INTERP_KERNEL::NormalizedCellType geoElt2, MEDFileMeshReadSelector *mrs) -{ - med_entity_type whichEntity; - if(!isExisting(fid,mName,dt,it,geoElt,whichEntity)) - return 0; - return new MEDFileUMeshPerType(fid,mName,dt,it,mdim,geoElt,geoElt2,whichEntity,mrs); -} - -MEDFileUMeshPerType *MEDFileUMeshPerType::NewPart(med_idt fid, const char *mName, int dt, int it, int mdim, INTERP_KERNEL::NormalizedCellType geoElt2, int strt, int stp, int step, MEDFileMeshReadSelector *mrs) -{ - int geoElt2i((int)geoElt2); - if(geoElt2i<0 || geoElt2i>=34) - throw INTERP_KERNEL::Exception("MEDFileUMeshPerType::NewPart : Not recognized MEDCoupling/MEDLoader geometric type !"); - med_geometry_type geoElt(typmai3[geoElt2]); - med_entity_type whichEntity; - if(!isExisting(fid,mName,dt,it,geoElt,whichEntity)) - throw INTERP_KERNEL::Exception("MEDFileUMeshPerType::NewPart : The specified geo type is not present in the specified mesh !"); - MEDCouplingAutoRefCountObjectPtr ret(new MEDFileUMeshPerType); - ret->loadPart(fid,mName,dt,it,mdim,geoElt,geoElt2,whichEntity,strt,stp,step,mrs); - return ret.retn(); -} - -std::size_t MEDFileUMeshPerType::getHeapMemorySizeWithoutChildren() const -{ - return 0; -} - -std::vector MEDFileUMeshPerType::getDirectChildrenWithNull() const -{ - std::vector ret; - ret.push_back((const MEDCoupling1GTUMesh *)_m); - ret.push_back((const DataArrayInt *)_num); - ret.push_back((const DataArrayInt *)_fam); - ret.push_back((const DataArrayAsciiChar *)_names); - return ret; -} - -bool MEDFileUMeshPerType::isExisting(med_idt fid, const char *mName, int dt, int it, med_geometry_type geoElt, med_entity_type& whichEntity) -{ - static const med_entity_type entities[3]={MED_CELL,MED_DESCENDING_FACE,MED_DESCENDING_EDGE}; - int nbOfElt=0; - for(int i=0;i<3;i++) - { - med_bool changement,transformation; - int tmp(MEDmeshnEntity(fid,mName,dt,it,entities[i],geoElt,MED_CONNECTIVITY,MED_NODAL,&changement,&transformation)); - if(tmp>nbOfElt) - { - nbOfElt=tmp; - whichEntity=entities[i]; - if(i>0) - std::cerr << "WARNING : MEDFile has been detected to be no compilant with MED 3 : Please change entity in MEDFile for geotype " << geoElt << std::endl; - } - } - return nbOfElt>0; -} - -int MEDFileUMeshPerType::getDim() const -{ - return _m->getMeshDimension(); -} - -MEDFileUMeshPerType::MEDFileUMeshPerType() -{ -} - -MEDFileUMeshPerType::MEDFileUMeshPerType(med_idt fid, const char *mName, int dt, int it, int mdim, med_geometry_type geoElt, INTERP_KERNEL::NormalizedCellType type, - med_entity_type entity, MEDFileMeshReadSelector *mrs):_entity(entity) -{ - med_bool changement,transformation; - int curNbOfElem(MEDmeshnEntity(fid,mName,dt,it,entity,geoElt,MED_CONNECTIVITY,MED_NODAL,&changement,&transformation)); - const INTERP_KERNEL::CellModel& cm(INTERP_KERNEL::CellModel::GetCellModel(type)); - if(!cm.isDynamic()) - { - loadFromStaticType(fid,mName,dt,it,mdim,curNbOfElem,geoElt,type,entity,mrs); - return; - } - if(type==INTERP_KERNEL::NORM_POLYGON || type==INTERP_KERNEL::NORM_QPOLYG) - { - loadPolyg(fid,mName,dt,it,mdim,curNbOfElem,geoElt,entity,mrs); - return; - } - //if(type==INTERP_KERNEL::NORM_POLYHED) - loadPolyh(fid,mName,dt,it,mdim,curNbOfElem,geoElt,entity,mrs); -} - -void MEDFileUMeshPerType::loadPart(med_idt fid, const char *mName, int dt, int it, int mdim, med_geometry_type geoElt, INTERP_KERNEL::NormalizedCellType type, - med_entity_type entity, int strt, int end, int step, MEDFileMeshReadSelector *mrs) -{ - med_bool changement,transformation; - int curNbOfElem(MEDmeshnEntity(fid,mName,dt,it,entity,geoElt,MED_CONNECTIVITY,MED_NODAL,&changement,&transformation)); - const INTERP_KERNEL::CellModel& cm(INTERP_KERNEL::CellModel::GetCellModel(type)); - _pd=PartDefinition::New(strt,end,step); - if(!cm.isDynamic()) - { - loadPartStaticType(fid,mName,dt,it,mdim,curNbOfElem,geoElt,type,entity,strt,end,step,mrs); - } - else - throw INTERP_KERNEL::Exception("MEDFileUMeshPerType::loadPart : not implemented yet for the dynamic type !"); -} - -void MEDFileUMeshPerType::loadFromStaticType(med_idt fid, const char *mName, int dt, int it, int mdim, int curNbOfElem, med_geometry_type geoElt, INTERP_KERNEL::NormalizedCellType type, - med_entity_type entity, MEDFileMeshReadSelector *mrs) -{ - _m=MEDCoupling1SGTUMesh::New(mName,type); - MEDCoupling1SGTUMesh *mc(dynamic_cast((MEDCoupling1GTUMesh *)_m)); - MEDCouplingAutoRefCountObjectPtr conn(DataArrayInt::New()); - int nbOfNodesPerCell(mc->getNumberOfNodesPerCell()); - conn->alloc(nbOfNodesPerCell*curNbOfElem,1); - MEDFILESAFECALLERRD0(MEDmeshElementConnectivityRd,(fid,mName,dt,it,entity,geoElt,MED_NODAL,MED_FULL_INTERLACE,conn->getPointer())); - std::transform(conn->begin(),conn->end(),conn->getPointer(),std::bind2nd(std::plus(),-1)); - mc->setNodalConnectivity(conn); - loadCommonPart(fid,mName,dt,it,mdim,curNbOfElem,geoElt,entity,mrs); -} - -void MEDFileUMeshPerType::loadPartStaticType(med_idt fid, const char *mName, int dt, int it, int mdim, int curNbOfElem, med_geometry_type geoElt, INTERP_KERNEL::NormalizedCellType type, - med_entity_type entity, int strt, int end, int step, MEDFileMeshReadSelector *mrs) -{ - if(strt<0) - throw INTERP_KERNEL::Exception("MEDFileUMeshPerType::loadPartStaticType : start pos is negative !"); - if(end>curNbOfElem) - throw INTERP_KERNEL::Exception("MEDFileUMeshPerType::loadPartStaticType : end is after the authorized range !"); - int nbOfEltsToLoad(DataArray::GetNumberOfItemGivenBES(strt,end,step,"MEDFileUMeshPerType::loadPartStaticType")); - _m=MEDCoupling1SGTUMesh::New(mName,type); - MEDCoupling1SGTUMesh *mc(dynamic_cast((MEDCoupling1GTUMesh *)_m)); - MEDCouplingAutoRefCountObjectPtr conn(DataArrayInt::New()); - int nbOfNodesPerCell(mc->getNumberOfNodesPerCell()); - conn->alloc(nbOfNodesPerCell*nbOfEltsToLoad,1); - med_filter filter=MED_FILTER_INIT; - MEDfilterBlockOfEntityCr(fid,/*nentity*/curNbOfElem,/*nvaluesperentity*/1,/*nconstituentpervalue*/nbOfNodesPerCell, - MED_ALL_CONSTITUENT,MED_FULL_INTERLACE,MED_COMPACT_STMODE,MED_NO_PROFILE, - /*start*/strt+1,/*stride*/step,/*count*/1,/*blocksize*/nbOfEltsToLoad, - /*lastblocksize=useless because count=1*/0,&filter); - MEDFILESAFECALLERRD0(MEDmeshElementConnectivityAdvancedRd,(fid,mName,dt,it,entity,geoElt,MED_NODAL,&filter,conn->getPointer())); - MEDfilterClose(&filter); - std::transform(conn->begin(),conn->end(),conn->getPointer(),std::bind2nd(std::plus(),-1)); - mc->setNodalConnectivity(conn); - loadPartOfCellCommonPart(fid,mName,strt,end,step,dt,it,mdim,curNbOfElem,geoElt,entity,mrs); -} - -void MEDFileUMeshPerType::loadCommonPart(med_idt fid, const char *mName, int dt, int it, int mdim, int curNbOfElem, med_geometry_type geoElt, - med_entity_type entity, MEDFileMeshReadSelector *mrs) -{ - med_bool changement,transformation; - _fam=0; - if(MEDmeshnEntity(fid,mName,dt,it,entity,geoElt,MED_FAMILY_NUMBER,MED_NODAL,&changement,&transformation)>0) - { - if(!mrs || mrs->isCellFamilyFieldReading()) - { - _fam=DataArrayInt::New(); - _fam->alloc(curNbOfElem,1); - if(MEDmeshEntityFamilyNumberRd(fid,mName,dt,it,entity,geoElt,_fam->getPointer())!=0) - std::fill(_fam->getPointer(),_fam->getPointer()+curNbOfElem,0); - } - } - _num=0; - if(MEDmeshnEntity(fid,mName,dt,it,entity,geoElt,MED_NUMBER,MED_NODAL,&changement,&transformation)>0) - { - if(!mrs || mrs->isCellNumFieldReading()) - { - _num=DataArrayInt::New(); - _num->alloc(curNbOfElem,1); - if(MEDmeshEntityNumberRd(fid,mName,dt,it,entity,geoElt,_num->getPointer())!=0) - _num=0; - } - } - _names=0; - if(MEDmeshnEntity(fid,mName,dt,it,entity,geoElt,MED_NAME,MED_NODAL,&changement,&transformation)>0) - { - if(!mrs || mrs->isCellNameFieldReading()) - { - _names=DataArrayAsciiChar::New(); - _names->alloc(curNbOfElem+1,MED_SNAME_SIZE);//not a bug to avoid the memory corruption due to last \0 at the end - if(MEDmeshEntityNameRd(fid,mName,dt,it,entity,geoElt,_names->getPointer())!=0) - _names=0; - else - _names->reAlloc(curNbOfElem);//not a bug to avoid the memory corruption due to last \0 at the end - } - } -} - -void MEDFileUMeshPerType::loadPartOfCellCommonPart(med_idt fid, const char *mName, int strt, int stp, int step, int dt, int it, int mdim, int curNbOfElem, med_geometry_type geoElt, med_entity_type entity, MEDFileMeshReadSelector *mrs) -{ - med_bool changement,transformation; - _fam=0; - int nbOfEltsToLoad(DataArray::GetNumberOfItemGivenBES(strt,stp,step,"MEDFileUMeshPerType::loadPartOfCellCommonPart")); - if(MEDmeshnEntity(fid,mName,dt,it,entity,geoElt,MED_FAMILY_NUMBER,MED_NODAL,&changement,&transformation)>0) - { - if(!mrs || mrs->isCellFamilyFieldReading()) - { - _fam=DataArrayInt::New(); - _fam->alloc(nbOfEltsToLoad,1); - med_filter filter=MED_FILTER_INIT; - MEDfilterBlockOfEntityCr(fid,/*nentity*/curNbOfElem,/*nvaluesperentity*/1,/*nconstituentpervalue*/1, - MED_ALL_CONSTITUENT,MED_FULL_INTERLACE,MED_COMPACT_STMODE,MED_NO_PROFILE, - /*start*/strt+1,/*stride*/step,/*count*/1,/*blocksize*/nbOfEltsToLoad, - /*lastblocksize=useless because count=1*/0,&filter); - if(MEDmeshEntityAttributeAdvancedRd(fid,mName,MED_FAMILY_NUMBER,dt,it,entity,geoElt,&filter,_fam->getPointer())!=0) - _fam->fillWithZero(); - MEDfilterClose(&filter); - } - } - _num=0; - if(MEDmeshnEntity(fid,mName,dt,it,entity,geoElt,MED_NUMBER,MED_NODAL,&changement,&transformation)>0) - { - if(!mrs || mrs->isCellNumFieldReading()) - { - _num=DataArrayInt::New(); - _num->alloc(nbOfEltsToLoad,1); - med_filter filter=MED_FILTER_INIT; - MEDfilterBlockOfEntityCr(fid,/*nentity*/curNbOfElem,/*nvaluesperentity*/1,/*nconstituentpervalue*/1, - MED_ALL_CONSTITUENT,MED_FULL_INTERLACE,MED_COMPACT_STMODE,MED_NO_PROFILE, - /*start*/strt+1,/*stride*/step,/*count*/1,/*blocksize*/nbOfEltsToLoad, - /*lastblocksize=useless because count=1*/0,&filter); - if(MEDmeshEntityAttributeAdvancedRd(fid,mName,MED_NUMBER,dt,it,entity,geoElt,&filter,_num->getPointer())!=0) - _num->fillWithZero(); - MEDfilterClose(&filter); - } - } - _names=0; - if(MEDmeshnEntity(fid,mName,dt,it,entity,geoElt,MED_NAME,MED_NODAL,&changement,&transformation)>0) - { - if(!mrs || mrs->isCellNameFieldReading()) - { - _names=DataArrayAsciiChar::New(); - _names->alloc(nbOfEltsToLoad+1,MED_SNAME_SIZE);//not a bug to avoid the memory corruption due to last \0 at the end - med_filter filter=MED_FILTER_INIT; - MEDfilterBlockOfEntityCr(fid,/*nentity*/curNbOfElem,/*nvaluesperentity*/1,/*nconstituentpervalue*/1, - MED_ALL_CONSTITUENT,MED_FULL_INTERLACE,MED_COMPACT_STMODE,MED_NO_PROFILE, - /*start*/strt+1,/*stride*/step,/*count*/1,/*blocksize*/nbOfEltsToLoad, - /*lastblocksize=useless because count=1*/0,&filter); - if(MEDmeshEntityAttributeAdvancedRd(fid,mName,MED_NAME,dt,it,entity,geoElt,&filter,_names->getPointer())!=0) - _names=0; - else - _names->reAlloc(nbOfEltsToLoad);//not a bug to avoid the memory corruption due to last \0 at the end - MEDfilterClose(&filter); - } - } -} - -void MEDFileUMeshPerType::loadPolyg(med_idt fid, const char *mName, int dt, int it, int mdim, int arraySize, med_geometry_type geoElt, - med_entity_type entity, MEDFileMeshReadSelector *mrs) -{ - med_bool changement,transformation; - med_int curNbOfElem(MEDmeshnEntity(fid,mName,dt,it,entity,geoElt,MED_INDEX_NODE,MED_NODAL,&changement,&transformation)-1); - _m=MEDCoupling1DGTUMesh::New(mName,geoElt==MED_POLYGON?INTERP_KERNEL::NORM_POLYGON:INTERP_KERNEL::NORM_QPOLYG); - MEDCouplingAutoRefCountObjectPtr mc(DynamicCast(_m)); - MEDCouplingAutoRefCountObjectPtr conn(DataArrayInt::New()),connI(DataArrayInt::New()); - conn->alloc(arraySize,1); connI->alloc(curNbOfElem+1,1); - MEDFILESAFECALLERRD0(MEDmeshPolygon2Rd,(fid,mName,dt,it,MED_CELL,geoElt,MED_NODAL,connI->getPointer(),conn->getPointer())); - std::transform(conn->begin(),conn->end(),conn->getPointer(),std::bind2nd(std::plus(),-1)); - std::transform(connI->begin(),connI->end(),connI->getPointer(),std::bind2nd(std::plus(),-1)); - mc->setNodalConnectivity(conn,connI); - loadCommonPart(fid,mName,dt,it,mdim,curNbOfElem,geoElt,entity,mrs); -} - -void MEDFileUMeshPerType::loadPolyh(med_idt fid, const char *mName, int dt, int it, int mdim, int connFaceLgth, med_geometry_type geoElt, - med_entity_type entity, MEDFileMeshReadSelector *mrs) -{ - med_bool changement,transformation; - med_int indexFaceLgth(MEDmeshnEntity(fid,mName,dt,it,MED_CELL,MED_POLYHEDRON,MED_INDEX_NODE,MED_NODAL,&changement,&transformation)); - int curNbOfElem(MEDmeshnEntity(fid,mName,dt,it,MED_CELL,MED_POLYHEDRON,MED_INDEX_FACE,MED_NODAL,&changement,&transformation)-1); - _m=MEDCoupling1DGTUMesh::New(mName,INTERP_KERNEL::NORM_POLYHED); - MEDCouplingAutoRefCountObjectPtr mc(DynamicCastSafe(_m)); - INTERP_KERNEL::AutoPtr index=new int[curNbOfElem+1]; - INTERP_KERNEL::AutoPtr indexFace=new int[indexFaceLgth]; - INTERP_KERNEL::AutoPtr locConn=new int[connFaceLgth]; - MEDFILESAFECALLERRD0(MEDmeshPolyhedronRd,(fid,mName,dt,it,MED_CELL,MED_NODAL,index,indexFace,locConn)); - MEDCouplingAutoRefCountObjectPtr conn(DataArrayInt::New()),connI(DataArrayInt::New()); - int arraySize=connFaceLgth; - for(int i=0;ialloc(arraySize,1); - int *wFinalConn=conn->getPointer(); - connI->alloc(curNbOfElem+1,1); - int *finalIndex(connI->getPointer()); - finalIndex[0]=0; - for(int i=0;i(),-1)); - for(int j=index[i];j(),-1)); - } - } - mc->setNodalConnectivity(conn,connI); - loadCommonPart(fid,mName,dt,it,mdim,curNbOfElem,MED_POLYHEDRON,entity,mrs); -} - -void MEDFileUMeshPerType::Write(med_idt fid, const std::string& mname, int mdim, const MEDCoupling1GTUMesh *m, const DataArrayInt *fam, const DataArrayInt *num, const DataArrayAsciiChar *names) -{ - int nbOfCells=m->getNumberOfCells(); - if(nbOfCells<1) - return ; - int dt,it; - double timm=m->getTime(dt,it); - INTERP_KERNEL::NormalizedCellType ikt=m->getTypeOfCell(0); - const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(ikt); - med_geometry_type curMedType=typmai3[(int)ikt]; - if(!cm.isDynamic()) - { - const MEDCoupling1SGTUMesh *m0(dynamic_cast(m)); - if(!m0) - throw INTERP_KERNEL::Exception("MEDFileUMeshPerType::Write : internal error #1 !"); - MEDCouplingAutoRefCountObjectPtr arr(m0->getNodalConnectivity()->deepCpy()); - std::transform(arr->begin(),arr->end(),arr->getPointer(),std::bind2nd(std::plus(),1)); - MEDFILESAFECALLERWR0(MEDmeshElementConnectivityWr,(fid,mname.c_str(),dt,it,timm,MED_CELL,curMedType,MED_NODAL,MED_FULL_INTERLACE,nbOfCells,arr->begin())); - } - else - { - const MEDCoupling1DGTUMesh *m0(dynamic_cast(m)); - if(!m0) - throw INTERP_KERNEL::Exception("MEDFileUMeshPerType::Write : internal error #2 !"); - if(ikt==INTERP_KERNEL::NORM_POLYGON || ikt==INTERP_KERNEL::NORM_QPOLYG) - { - MEDCouplingAutoRefCountObjectPtr arr(m0->getNodalConnectivity()->deepCpy()),arrI(m0->getNodalConnectivityIndex()->deepCpy()); - std::transform(arr->begin(),arr->end(),arr->getPointer(),std::bind2nd(std::plus(),1)); - std::transform(arrI->begin(),arrI->end(),arrI->getPointer(),std::bind2nd(std::plus(),1)); - MEDFILESAFECALLERWR0(MEDmeshPolygon2Wr,(fid,mname.c_str(),dt,it,timm,MED_CELL,ikt==INTERP_KERNEL::NORM_POLYGON?MED_POLYGON:MED_POLYGON2,MED_NODAL,nbOfCells+1,arrI->begin(),arr->begin())); - } - else - { - const int *conn(m0->getNodalConnectivity()->begin()),*connI(m0->getNodalConnectivityIndex()->begin()); - int meshLgth=m0->getNodalConnectivityLength(); - int nbOfFaces=std::count(conn,conn+meshLgth,-1)+nbOfCells; - INTERP_KERNEL::AutoPtr tab1=new int[nbOfCells+1]; - int *w1=tab1; *w1=1; - INTERP_KERNEL::AutoPtr tab2=new int[nbOfFaces+1]; - int *w2=tab2; *w2=1; - INTERP_KERNEL::AutoPtr bigtab=new int[meshLgth]; - int *bt=bigtab; - for(int i=0;i(),1)); - int nbOfNode=std::distance(w,wend); - w2[1]=w2[0]+nbOfNode; - if(wend!=conn+connI[i+1]) - w=wend+1; - else - w=wend; - nbOfFaces2++; - } - w1[1]=w1[0]+nbOfFaces2; - } - MEDFILESAFECALLERWR0(MEDmeshPolyhedronWr,(fid,mname.c_str(),dt,it,timm,MED_CELL,MED_NODAL,nbOfCells+1,tab1,nbOfFaces+1,tab2,bigtab)); - } - } - if(fam) - MEDFILESAFECALLERWR0(MEDmeshEntityFamilyNumberWr,(fid,mname.c_str(),dt,it,MED_CELL,curMedType,nbOfCells,fam->getConstPointer())); - if(num) - MEDFILESAFECALLERWR0(MEDmeshEntityNumberWr,(fid,mname.c_str(),dt,it,MED_CELL,curMedType,nbOfCells,num->getConstPointer())); - if(names) - { - if(names->getNumberOfComponents()!=MED_SNAME_SIZE) - { - std::ostringstream oss; oss << "MEDFileUMeshPerType::write : expected a name field on cells with number of components set to " << MED_SNAME_SIZE; - oss << " ! The array has " << names->getNumberOfComponents() << " components !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - MEDFILESAFECALLERWR0(MEDmeshEntityNameWr,(fid,mname.c_str(),dt,it,MED_CELL,curMedType,nbOfCells,names->getConstPointer())); - } -} diff --git a/src/MEDLoader/MEDFileMeshElt.hxx b/src/MEDLoader/MEDFileMeshElt.hxx deleted file mode 100644 index 9d57bc1e8..000000000 --- a/src/MEDLoader/MEDFileMeshElt.hxx +++ /dev/null @@ -1,79 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 -// 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 __MEDFILEMESHELT_HXX__ -#define __MEDFILEMESHELT_HXX__ - -#include "MEDCouplingMemArray.hxx" -#include "MEDCoupling1GTUMesh.hxx" -#include "MEDCouplingPartDefinition.hxx" -#include "MEDCouplingAutoRefCountObjectPtr.hxx" - -#include "NormalizedUnstructuredMesh.hxx" - -#include "med.h" - -namespace ParaMEDMEM -{ - class MEDCouplingUMesh; - class MEDFileMeshReadSelector; - - class MEDFileUMeshPerType : public RefCountObject - { - public: - static MEDFileUMeshPerType *New(med_idt fid, const char *mName, int dt, int it, int mdim, med_geometry_type geoElt, INTERP_KERNEL::NormalizedCellType geoElt2, MEDFileMeshReadSelector *mrs); - static MEDFileUMeshPerType *NewPart(med_idt fid, const char *mName, int dt, int it, int mdim, INTERP_KERNEL::NormalizedCellType geoElt2, int strt, int stp, int step, MEDFileMeshReadSelector *mrs); - static bool isExisting(med_idt fid, const char *mName, int dt, int it, med_geometry_type geoElt, med_entity_type& whichEntity); - std::size_t getHeapMemorySizeWithoutChildren() const; - std::vector getDirectChildrenWithNull() const; - int getDim() const; - MEDCoupling1GTUMesh *getMesh() const { return const_cast((const MEDCoupling1GTUMesh *)_m); } - const DataArrayInt *getFam() const { return _fam; } - const DataArrayInt *getNum() const { return _num; } - const DataArrayAsciiChar *getNames() const { return _names; } - const PartDefinition *getPartDef() const { return _pd; } - static void Write(med_idt fid, const std::string& mname, int mdim, const MEDCoupling1GTUMesh *m, const DataArrayInt *fam, const DataArrayInt *num, const DataArrayAsciiChar *names); - private: - MEDFileUMeshPerType(); - MEDFileUMeshPerType(med_idt fid, const char *mName, int dt, int it, int mdim, med_geometry_type geoElt, INTERP_KERNEL::NormalizedCellType type, - med_entity_type entity, MEDFileMeshReadSelector *mrs); - void loadPart(med_idt fid, const char *mName, int dt, int it, int mdim, med_geometry_type geoElt, INTERP_KERNEL::NormalizedCellType type, - med_entity_type entity, int strt, int end, int step, MEDFileMeshReadSelector *mrs); - void loadFromStaticType(med_idt fid, const char *mName, int dt, int it, int mdim, int curNbOfElem, med_geometry_type geoElt, INTERP_KERNEL::NormalizedCellType type, - med_entity_type entity, MEDFileMeshReadSelector *mrs); - void loadPartStaticType(med_idt fid, const char *mName, int dt, int it, int mdim, int curNbOfElem, med_geometry_type geoElt, INTERP_KERNEL::NormalizedCellType type, - med_entity_type entity, int strt, int end, int step, MEDFileMeshReadSelector *mrs); - void loadPolyg(med_idt fid, const char *mName, int dt, int it, int mdim, int arraySize, med_geometry_type geoElt, - med_entity_type entity, MEDFileMeshReadSelector *mrs); - void loadPolyh(med_idt fid, const char *mName, int dt, int it, int mdim, int connFaceLgth, med_geometry_type geoElt, - med_entity_type entity, MEDFileMeshReadSelector *mrs); - void loadCommonPart(med_idt fid, const char *mName, int dt, int it, int mdim, int curNbOfElem, med_geometry_type geoElt, med_entity_type entity, MEDFileMeshReadSelector *mrs); - void loadPartOfCellCommonPart(med_idt fid, const char *mName, int strt, int stp, int step, int dt, int it, int mdim, int curNbOfElem, med_geometry_type geoElt, med_entity_type entity, MEDFileMeshReadSelector *mrs); - private: - MEDCouplingAutoRefCountObjectPtr _m; - MEDCouplingAutoRefCountObjectPtr _num; - MEDCouplingAutoRefCountObjectPtr _fam; - MEDCouplingAutoRefCountObjectPtr _names; - MEDCouplingAutoRefCountObjectPtr _pd; - med_entity_type _entity; - }; -} - -#endif diff --git a/src/MEDLoader/MEDFileMeshLL.cxx b/src/MEDLoader/MEDFileMeshLL.cxx deleted file mode 100644 index 218f7bb72..000000000 --- a/src/MEDLoader/MEDFileMeshLL.cxx +++ /dev/null @@ -1,1707 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 -// 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 "MEDFileMeshLL.hxx" -#include "MEDFileMesh.hxx" -#include "MEDLoaderBase.hxx" -#include "MEDFileSafeCaller.txx" -#include "MEDFileMeshReadSelector.hxx" - -#include "MEDCouplingUMesh.hxx" - -#include "InterpKernelAutoPtr.hxx" -#include "CellModel.hxx" - -#include - -extern med_geometry_type typmai[MED_N_CELL_FIXED_GEO]; -extern INTERP_KERNEL::NormalizedCellType typmai2[MED_N_CELL_FIXED_GEO]; -extern med_geometry_type typmainoeud[1]; - -using namespace ParaMEDMEM; - -MEDFileMeshL2::MEDFileMeshL2():_name(MED_NAME_SIZE),_description(MED_COMMENT_SIZE),_univ_name(MED_LNAME_SIZE),_dt_unit(MED_LNAME_SIZE) -{ -} - -std::size_t MEDFileMeshL2::getHeapMemorySizeWithoutChildren() const -{ - return 0; -} - -std::vector MEDFileMeshL2::getDirectChildrenWithNull() const -{ - return std::vector(); -} - -int MEDFileMeshL2::GetMeshIdFromName(med_idt fid, const std::string& mname, ParaMEDMEM::MEDCouplingMeshType& meshType, int& dt, int& it, std::string& dtunit1) -{ - med_mesh_type type_maillage; - char maillage_description[MED_COMMENT_SIZE+1]; - char dtunit[MED_LNAME_SIZE+1]; - med_int spaceDim,dim; - char nommaa[MED_NAME_SIZE+1]; - med_int n=MEDnMesh(fid); - bool found=false; - int ret=-1; - med_sorting_type stype; - std::vector ms; - int nstep; - med_axis_type axistype; - for(int i=0;i axisname=MEDLoaderBase::buildEmptyString(naxis*MED_SNAME_SIZE); - INTERP_KERNEL::AutoPtr axisunit=MEDLoaderBase::buildEmptyString(naxis*MED_SNAME_SIZE); - MEDFILESAFECALLERRD0(MEDmeshInfo,(fid,i+1,nommaa,&spaceDim,&dim,&type_maillage,maillage_description,dtunit,&stype,&nstep,&axistype,axisname,axisunit)); - dtunit1=MEDLoaderBase::buildStringFromFortran(dtunit,sizeof(dtunit)); - std::string cur=MEDLoaderBase::buildStringFromFortran(nommaa,sizeof(nommaa)); - ms.push_back(cur); - if(cur==mname) - { - found=true; - ret=i+1; - } - } - if(!found) - { - std::ostringstream oss; - oss << "No such meshname (" << mname << ") in file ! Must be in : "; - std::copy(ms.begin(),ms.end(),std::ostream_iterator(oss,", ")); - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - switch(type_maillage) - { - case MED_UNSTRUCTURED_MESH: - meshType=UNSTRUCTURED; - break; - case MED_STRUCTURED_MESH: - { - med_grid_type gt; - MEDFILESAFECALLERRD0(MEDmeshGridTypeRd,(fid,mname.c_str(),>)); - switch(gt) - { - case MED_CARTESIAN_GRID: - meshType=CARTESIAN; - break; - case MED_CURVILINEAR_GRID: - meshType=CURVE_LINEAR; - break; - default: - throw INTERP_KERNEL::Exception("MEDFileUMeshL2::getMeshIdFromName : unrecognized structured mesh type ! Supported are :\n - cartesian\n - curve linear\n"); - } - break; - } - default: - throw INTERP_KERNEL::Exception("MEDFileUMeshL2::getMeshIdFromName : unrecognized mesh type !"); - } - med_int numdt,numit; - med_float dtt; - MEDFILESAFECALLERRD0(MEDmeshComputationStepInfo,(fid,mname.c_str(),1,&numdt,&numit,&dtt)); - dt=numdt; it=numit; - return ret; -} - -double MEDFileMeshL2::CheckMeshTimeStep(med_idt fid, const std::string& mName, int nstep, int dt, int it) -{ - bool found=false; - med_int numdt,numit; - med_float dtt; - std::vector< std::pair > p(nstep); - for(int i=0;i(numdt,numit); - found=(numdt==dt) && (numit==numit); - } - if(!found) - { - std::ostringstream oss; oss << "No such iteration=" << dt << ",order=" << it << " numbers found for mesh '" << mName << "' ! "; - oss << "Possibilities are : "; - for(int i=0;i MEDFileMeshL2::getAxisInfoOnMesh(med_idt fid, int mId, const std::string& mName, ParaMEDMEM::MEDCouplingMeshType& meshType, int& nstep, int& Mdim) -{ - med_mesh_type type_maillage; - med_int spaceDim; - med_sorting_type stype; - med_axis_type axistype; - int naxis(MEDmeshnAxis(fid,mId)); - INTERP_KERNEL::AutoPtr nameTmp=MEDLoaderBase::buildEmptyString(MED_NAME_SIZE); - INTERP_KERNEL::AutoPtr axisname=MEDLoaderBase::buildEmptyString(naxis*MED_SNAME_SIZE); - INTERP_KERNEL::AutoPtr axisunit=MEDLoaderBase::buildEmptyString(naxis*MED_SNAME_SIZE); - INTERP_KERNEL::AutoPtr univTmp=MEDLoaderBase::buildEmptyString(MED_LNAME_SIZE); - if(MEDmeshInfo(fid,mId,nameTmp,&spaceDim,&Mdim,&type_maillage,_description.getPointer(),_dt_unit.getPointer(), - &stype,&nstep,&axistype,axisname,axisunit)!=0) - throw INTERP_KERNEL::Exception("A problem has been detected when trying to get info on mesh !"); - MEDmeshUniversalNameRd(fid,nameTmp,_univ_name.getPointer());// do not protect MEDFILESAFECALLERRD0 call : Thanks to fra.med. - switch(type_maillage) - { - case MED_UNSTRUCTURED_MESH: - meshType=UNSTRUCTURED; - break; - case MED_STRUCTURED_MESH: - { - med_grid_type gt; - MEDFILESAFECALLERRD0(MEDmeshGridTypeRd,(fid,mName.c_str(),>)); - switch(gt) - { - case MED_CARTESIAN_GRID: - meshType=CARTESIAN; - break; - case MED_CURVILINEAR_GRID: - meshType=CURVE_LINEAR; - break; - default: - throw INTERP_KERNEL::Exception("MEDFileUMeshL2::getAxisInfoOnMesh : unrecognized structured mesh type ! Supported are :\n - cartesian\n - curve linear\n"); - } - break; - } - default: - throw INTERP_KERNEL::Exception("MEDFileUMeshL2::getMeshIdFromName : unrecognized mesh type !"); - } - // - std::vector infosOnComp(naxis); - for(int i=0;i& fams, std::map >& grps, MEDFileMeshReadSelector *mrs) -{ - if(mrs && !(mrs->isCellFamilyFieldReading() || mrs->isNodeFamilyFieldReading())) - return ; - char nomfam[MED_NAME_SIZE+1]; - med_int numfam; - int nfam=MEDnFamily(fid,meshName.c_str()); - for(int i=0;i attide=new med_int[natt]; - INTERP_KERNEL::AutoPtr attval=new med_int[natt]; - INTERP_KERNEL::AutoPtr attdes=new char[MED_COMMENT_SIZE*natt+1]; - INTERP_KERNEL::AutoPtr gro=new char[MED_LNAME_SIZE*ngro+1]; - MEDfamily23Info(fid,meshName.c_str(),i+1,nomfam,attide,attval,attdes,&numfam,gro); - std::string famName=MEDLoaderBase::buildStringFromFortran(nomfam,MED_NAME_SIZE); - fams[famName]=numfam; - for(int j=0;j& fams, const std::map >& grps, int tooLongStrPol) -{ - for(std::map::const_iterator it=fams.begin();it!=fams.end();it++) - { - std::vector grpsOfFam; - for(std::map >::const_iterator it1=grps.begin();it1!=grps.end();it1++) - { - if(std::find((*it1).second.begin(),(*it1).second.end(),(*it).first)!=(*it1).second.end()) - grpsOfFam.push_back((*it1).first); - } - int ngro=grpsOfFam.size(); - INTERP_KERNEL::AutoPtr groName=MEDLoaderBase::buildEmptyString(MED_LNAME_SIZE*ngro); - int i=0; - for(std::vector::const_iterator it2=grpsOfFam.begin();it2!=grpsOfFam.end();it2++,i++) - MEDLoaderBase::safeStrCpy2((*it2).c_str(),MED_LNAME_SIZE-1,groName+i*MED_LNAME_SIZE,tooLongStrPol); - INTERP_KERNEL::AutoPtr famName=MEDLoaderBase::buildEmptyString(MED_NAME_SIZE); - MEDLoaderBase::safeStrCpy((*it).first.c_str(),MED_NAME_SIZE,famName,tooLongStrPol); - int ret=MEDfamilyCr(fid,mname.c_str(),famName,(*it).second,ngro,groName); - ret++; - } -} - -MEDFileUMeshL2::MEDFileUMeshL2() -{ -} - -std::vector MEDFileUMeshL2::loadCommonPart(med_idt fid, int mId, const std::string& mName, int dt, int it, int& Mdim) -{ - Mdim=-3; - _name.set(mName.c_str()); - int nstep; - ParaMEDMEM::MEDCouplingMeshType meshType; - std::vector ret(getAxisInfoOnMesh(fid,mId,mName.c_str(),meshType,nstep,Mdim)); - if(nstep==0) - { - Mdim=-4; - return std::vector(); - } - if(meshType!=UNSTRUCTURED) - throw INTERP_KERNEL::Exception("Invalid mesh type ! You are expected an unstructured one whereas in file it is not an unstructured !"); - _time=CheckMeshTimeStep(fid,mName,nstep,dt,it); - _iteration=dt; - _order=it; - return ret; -} - -void MEDFileUMeshL2::loadAll(med_idt fid, int mId, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs) -{ - int Mdim; - std::vector infosOnComp(loadCommonPart(fid,mId,mName,dt,it,Mdim)); - if(Mdim==-4) - return ; - loadConnectivity(fid,Mdim,mName,dt,it,mrs);//to improve check (dt,it) coherency - loadCoords(fid,mId,infosOnComp,mName,dt,it); -} - -void MEDFileUMeshL2::loadPart(med_idt fid, int mId, const std::string& mName, const std::vector& types, const std::vector& slicPerTyp, int dt, int it, MEDFileMeshReadSelector *mrs) -{ - int Mdim; - std::vector infosOnComp(loadCommonPart(fid,mId,mName,dt,it,Mdim)); - if(Mdim==-4) - return ; - loadPartOfConnectivity(fid,Mdim,mName,types,slicPerTyp,dt,it,mrs); - med_bool changement,transformation; - int nCoords(MEDmeshnEntity(fid,mName.c_str(),dt,it,MED_NODE,MED_NONE,MED_COORDINATE,MED_NO_CMODE,&changement,&transformation)); - std::vector fetchedNodeIds(nCoords,false); - for(std::vector< std::vector< MEDCouplingAutoRefCountObjectPtr > >::const_iterator it0=_per_type_mesh.begin();it0!=_per_type_mesh.end();it0++) - for(std::vector< MEDCouplingAutoRefCountObjectPtr >::const_iterator it1=(*it0).begin();it1!=(*it0).end();it1++) - (*it1)->getMesh()->computeNodeIdsAlg(fetchedNodeIds); - int nMin(std::distance(fetchedNodeIds.begin(),std::find(fetchedNodeIds.begin(),fetchedNodeIds.end(),true))); - int nMax(std::distance(fetchedNodeIds.rbegin(),std::find(fetchedNodeIds.rbegin(),fetchedNodeIds.rend(),true))); - nMax=nCoords-nMax; - for(std::vector< std::vector< MEDCouplingAutoRefCountObjectPtr > >::const_iterator it0=_per_type_mesh.begin();it0!=_per_type_mesh.end();it0++) - for(std::vector< MEDCouplingAutoRefCountObjectPtr >::const_iterator it1=(*it0).begin();it1!=(*it0).end();it1++) - (*it1)->getMesh()->renumberNodesWithOffsetInConn(-nMin); - loadPartCoords(fid,mId,infosOnComp,mName,dt,it,nMin,nMax); -} - -void MEDFileUMeshL2::loadConnectivity(med_idt fid, int mdim, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs) -{ - _per_type_mesh.resize(1); - _per_type_mesh[0].clear(); - for(int j=0;j& types, const std::vector& slicPerTyp, int dt, int it, MEDFileMeshReadSelector *mrs) -{ - std::size_t nbOfTypes(types.size()); - if(slicPerTyp.size()!=3*nbOfTypes) - throw INTERP_KERNEL::Exception("MEDFileUMeshL2::loadPartOfConnectivity : The size of slicPerTyp array is expected to be equal to 3 times size of array types !"); - std::set types2(types.begin(),types.end()); - if(types2.size()!=nbOfTypes) - throw INTERP_KERNEL::Exception("MEDFileUMeshL2::loadPartOfConnectivity : the geometric types in types array must appear once !"); - _per_type_mesh.resize(1); - _per_type_mesh[0].clear(); - for(std::size_t ii=0;ii tmp(MEDFileUMeshPerType::NewPart(fid,mName.c_str(),dt,it,mdim,types[ii],strt,stp,step,mrs)); - _per_type_mesh[0].push_back(tmp); - } - sortTypes(); -} - -void MEDFileUMeshL2::loadCoords(med_idt fid, int mId, const std::vector& infosOnComp, const std::string& mName, int dt, int it) -{ - int spaceDim((int)infosOnComp.size()); - med_bool changement,transformation; - int nCoords(MEDmeshnEntity(fid,mName.c_str(),dt,it,MED_NODE,MED_NONE,MED_COORDINATE,MED_NO_CMODE,&changement,&transformation)); - _coords=DataArrayDouble::New(); - _coords->alloc(nCoords,spaceDim); - double *coordsPtr(_coords->getPointer()); - if (nCoords) - MEDFILESAFECALLERRD0(MEDmeshNodeCoordinateRd,(fid,mName.c_str(),dt,it,MED_FULL_INTERLACE,coordsPtr)); - if(MEDmeshnEntity(fid,mName.c_str(),dt,it,MED_NODE,MED_NO_GEOTYPE,MED_FAMILY_NUMBER,MED_NODAL,&changement,&transformation)>0) - { - _fam_coords=DataArrayInt::New(); - _fam_coords->alloc(nCoords,1); - MEDFILESAFECALLERRD0(MEDmeshEntityFamilyNumberRd,(fid,mName.c_str(),dt,it,MED_NODE,MED_NO_GEOTYPE,_fam_coords->getPointer())); - } - else - _fam_coords=0; - if(MEDmeshnEntity(fid,mName.c_str(),dt,it,MED_NODE,MED_NO_GEOTYPE,MED_NUMBER,MED_NODAL,&changement,&transformation)>0) - { - _num_coords=DataArrayInt::New(); - _num_coords->alloc(nCoords,1); - MEDFILESAFECALLERRD0(MEDmeshEntityNumberRd,(fid,mName.c_str(),dt,it,MED_NODE,MED_NO_GEOTYPE,_num_coords->getPointer())); - } - else - _num_coords=0; - if(MEDmeshnEntity(fid,mName.c_str(),dt,it,MED_NODE,MED_NO_GEOTYPE,MED_NAME,MED_NODAL,&changement,&transformation)>0) - { - _name_coords=DataArrayAsciiChar::New(); - _name_coords->alloc(nCoords+1,MED_SNAME_SIZE);//not a bug to avoid the memory corruption due to last \0 at the end - MEDFILESAFECALLERRD0(MEDmeshEntityNameRd,(fid,mName.c_str(),dt,it,MED_NODE,MED_NO_GEOTYPE,_name_coords->getPointer())); - _name_coords->reAlloc(nCoords);//not a bug to avoid the memory corruption due to last \0 at the end - } - else - _name_coords=0; - for(int i=0;isetInfoOnComponent(i,infosOnComp[i]); -} - -void MEDFileUMeshL2::loadPartCoords(med_idt fid, int mId, const std::vector& infosOnComp, const std::string& mName, int dt, int it, int nMin, int nMax) -{ - med_bool changement,transformation; - int spaceDim((int)infosOnComp.size()),nCoords(MEDmeshnEntity(fid,mName.c_str(),dt,it,MED_NODE,MED_NONE,MED_COORDINATE,MED_NO_CMODE,&changement,&transformation)); - _coords=DataArrayDouble::New(); - int nbNodesToLoad(nMax-nMin); - _coords->alloc(nbNodesToLoad,spaceDim); - med_filter filter=MED_FILTER_INIT,filter2=MED_FILTER_INIT; - MEDfilterBlockOfEntityCr(fid,/*nentity*/nCoords,/*nvaluesperentity*/1,/*nconstituentpervalue*/spaceDim, - MED_ALL_CONSTITUENT,MED_FULL_INTERLACE,MED_COMPACT_STMODE,MED_NO_PROFILE, - /*start*/nMin+1,/*stride*/1,/*count*/1,/*blocksize*/nbNodesToLoad, - /*lastblocksize=useless because count=1*/0,&filter); - MEDFILESAFECALLERRD0(MEDmeshNodeCoordinateAdvancedRd,(fid,mName.c_str(),dt,it,&filter,_coords->getPointer())); - _part_coords=PartDefinition::New(nMin,nMax,1); - MEDfilterClose(&filter); - MEDfilterBlockOfEntityCr(fid,nCoords,1,1,MED_ALL_CONSTITUENT,MED_FULL_INTERLACE,MED_COMPACT_STMODE, - MED_NO_PROFILE,nMin+1,1,1,nbNodesToLoad,0,&filter2); - if(MEDmeshnEntity(fid,mName.c_str(),dt,it,MED_NODE,MED_NO_GEOTYPE,MED_FAMILY_NUMBER,MED_NODAL,&changement,&transformation)>0) - { - _fam_coords=DataArrayInt::New(); - _fam_coords->alloc(nbNodesToLoad,1); - MEDFILESAFECALLERRD0(MEDmeshEntityAttributeAdvancedRd,(fid,mName.c_str(),MED_FAMILY_NUMBER,dt,it,MED_NODE,MED_NO_GEOTYPE,&filter2,_fam_coords->getPointer())); - } - else - _fam_coords=0; - if(MEDmeshnEntity(fid,mName.c_str(),dt,it,MED_NODE,MED_NO_GEOTYPE,MED_NUMBER,MED_NODAL,&changement,&transformation)>0) - { - _num_coords=DataArrayInt::New(); - _num_coords->alloc(nbNodesToLoad,1); - MEDFILESAFECALLERRD0(MEDmeshEntityAttributeAdvancedRd,(fid,mName.c_str(),MED_NUMBER,dt,it,MED_NODE,MED_NO_GEOTYPE,&filter2,_num_coords->getPointer())); - } - else - _num_coords=0; - if(MEDmeshnEntity(fid,mName.c_str(),dt,it,MED_NODE,MED_NO_GEOTYPE,MED_NAME,MED_NODAL,&changement,&transformation)>0) - { - _name_coords=DataArrayAsciiChar::New(); - _name_coords->alloc(nbNodesToLoad+1,MED_SNAME_SIZE);//not a bug to avoid the memory corruption due to last \0 at the end - MEDFILESAFECALLERRD0(MEDmeshEntityAttributeAdvancedRd,(fid,mName.c_str(),MED_NAME,dt,it,MED_NODE,MED_NO_GEOTYPE,&filter2,_name_coords->getPointer())); - _name_coords->reAlloc(nbNodesToLoad);//not a bug to avoid the memory corruption due to last \0 at the end - } - else - _name_coords=0; - MEDfilterClose(&filter2); - _coords->setInfoOnComponents(infosOnComp); -} - -void MEDFileUMeshL2::sortTypes() -{ - std::set mdims; - std::vector< MEDCouplingAutoRefCountObjectPtr > tmp(_per_type_mesh[0]); - _per_type_mesh.clear(); - for(std::vector< MEDCouplingAutoRefCountObjectPtr >::const_iterator it=tmp.begin();it!=tmp.end();it++) - mdims.insert((*it)->getDim()); - if(mdims.empty()) - return; - int mdim=*mdims.rbegin(); - _per_type_mesh.resize(mdim+1); - for(int dim=mdim+1;dim!=0;dim--) - { - std::vector< MEDCouplingAutoRefCountObjectPtr >& elt=_per_type_mesh[mdim+1-dim]; - for(std::vector< MEDCouplingAutoRefCountObjectPtr >::const_iterator it=tmp.begin();it!=tmp.end();it++) - if((*it)->getDim()==dim-1) - elt.push_back(*it); - } - // suppression of contiguous empty levels at the end of _per_type_mesh. - int nbOfUselessLev=0; - bool isFirst=true; - for(std::vector< std::vector< MEDCouplingAutoRefCountObjectPtr > >::reverse_iterator it2=_per_type_mesh.rbegin();it2!=_per_type_mesh.rend();it2++) - { - if((*it2).empty() && isFirst) - { - nbOfUselessLev++; - } - else - isFirst=false; - } - _per_type_mesh.resize(_per_type_mesh.size()-nbOfUselessLev); -} - -void MEDFileUMeshL2::WriteCoords(med_idt fid, const std::string& mname, int dt, int it, double time, const DataArrayDouble *coords, const DataArrayInt *famCoords, const DataArrayInt *numCoords, const DataArrayAsciiChar *nameCoords) -{ - if(!coords) - return ; - MEDFILESAFECALLERWR0(MEDmeshNodeCoordinateWr,(fid,mname.c_str(),dt,it,time,MED_FULL_INTERLACE,coords->getNumberOfTuples(),coords->getConstPointer())); - if(famCoords) - MEDFILESAFECALLERWR0(MEDmeshEntityFamilyNumberWr,(fid,mname.c_str(),dt,it,MED_NODE,MED_NO_GEOTYPE,famCoords->getNumberOfTuples(),famCoords->getConstPointer())); - if(numCoords) - MEDFILESAFECALLERWR0(MEDmeshEntityNumberWr,(fid,mname.c_str(),dt,it,MED_NODE,MED_NO_GEOTYPE,numCoords->getNumberOfTuples(),numCoords->getConstPointer())); - if(nameCoords) - { - if(nameCoords->getNumberOfComponents()!=MED_SNAME_SIZE) - { - std::ostringstream oss; oss << " MEDFileUMeshL2::WriteCoords : expected a name field on nodes with number of components set to " << MED_SNAME_SIZE; - oss << " ! The array has " << nameCoords->getNumberOfComponents() << " components !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - MEDFILESAFECALLERWR0(MEDmeshEntityNameWr,(fid,mname.c_str(),dt,it,MED_NODE,MED_NO_GEOTYPE,nameCoords->getNumberOfTuples(),nameCoords->getConstPointer())); - } -} - -bool MEDFileUMeshL2::isFamDefinedOnLev(int levId) const -{ - for(std::vector< MEDCouplingAutoRefCountObjectPtr >::const_iterator it=_per_type_mesh[levId].begin();it!=_per_type_mesh[levId].end();it++) - if((*it)->getFam()==0) - return false; - return true; -} - -bool MEDFileUMeshL2::isNumDefinedOnLev(int levId) const -{ - for(std::vector< MEDCouplingAutoRefCountObjectPtr >::const_iterator it=_per_type_mesh[levId].begin();it!=_per_type_mesh[levId].end();it++) - if((*it)->getNum()==0) - return false; - return true; -} - -bool MEDFileUMeshL2::isNamesDefinedOnLev(int levId) const -{ - for(std::vector< MEDCouplingAutoRefCountObjectPtr >::const_iterator it=_per_type_mesh[levId].begin();it!=_per_type_mesh[levId].end();it++) - if((*it)->getNames()==0) - return false; - return true; -} - -MEDFileCMeshL2::MEDFileCMeshL2() -{ -} - -void MEDFileCMeshL2::loadAll(med_idt fid, int mId, const std::string& mName, int dt, int it) -{ - _name.set(mName.c_str()); - int nstep; - int Mdim; - ParaMEDMEM::MEDCouplingMeshType meshType; - std::vector infosOnComp=getAxisInfoOnMesh(fid,mId,mName.c_str(),meshType,nstep,Mdim); - if(meshType!=CARTESIAN) - throw INTERP_KERNEL::Exception("Invalid mesh type ! You are expected a structured one whereas in file it is not a structured !"); - _time=CheckMeshTimeStep(fid,mName,nstep,dt,it); - _iteration=dt; - _order=it; - // - med_grid_type gridtype; - MEDFILESAFECALLERRD0(MEDmeshGridTypeRd,(fid,mName.c_str(),&gridtype)); - if(gridtype!=MED_CARTESIAN_GRID) - throw INTERP_KERNEL::Exception("Invalid structured mesh ! Expected cartesian mesh type !"); - _cmesh=MEDCouplingCMesh::New(); - for(int i=0;i da=DataArrayDouble::New(); - da->alloc(nbOfElt,1); - da->setInfoOnComponent(0,infosOnComp[i]); - MEDFILESAFECALLERRD0(MEDmeshGridIndexCoordinateRd,(fid,mName.c_str(),dt,it,i+1,da->getPointer())); - _cmesh->setCoordsAt(i,da); - } -} - -med_data_type MEDFileCMeshL2::GetDataTypeCorrespondingToSpaceId(int id) -{ - switch(id) - { - case 0: - return MED_COORDINATE_AXIS1; - case 1: - return MED_COORDINATE_AXIS2; - case 2: - return MED_COORDINATE_AXIS3; - default: - throw INTERP_KERNEL::Exception("Invalid meshdim detected in Cartesian Grid !"); - } -} - -MEDFileCLMeshL2::MEDFileCLMeshL2() -{ -} - -void MEDFileCLMeshL2::loadAll(med_idt fid, int mId, const std::string& mName, int dt, int it) -{ - _name.set(mName.c_str()); - int nstep; - int Mdim; - ParaMEDMEM::MEDCouplingMeshType meshType; - std::vector infosOnComp=getAxisInfoOnMesh(fid,mId,mName,meshType,nstep,Mdim); - if(meshType!=CURVE_LINEAR) - throw INTERP_KERNEL::Exception("Invalid mesh type ! You are expected a structured one whereas in file it is not a structured !"); - _time=CheckMeshTimeStep(fid,mName,nstep,dt,it); - _iteration=dt; - _order=it; - // - _clmesh=MEDCouplingCurveLinearMesh::New(); - INTERP_KERNEL::AutoPtr stGrid=new int[Mdim]; - MEDFILESAFECALLERRD0(MEDmeshGridStructRd,(fid,mName.c_str(),dt,it,stGrid)); - _clmesh->setNodeGridStructure(stGrid,((int *)stGrid)+Mdim); - med_bool chgt=MED_FALSE,trsf=MED_FALSE; - int nbNodes(MEDmeshnEntity(fid,mName.c_str(),dt,it,MED_NODE,MED_NONE,MED_COORDINATE,MED_NO_CMODE,&chgt,&trsf)); - MEDCouplingAutoRefCountObjectPtr da=DataArrayDouble::New(); - da->alloc(nbNodes,infosOnComp.size()); - da->setInfoOnComponents(infosOnComp); - MEDFILESAFECALLERRD0(MEDmeshNodeCoordinateRd,(fid,mName.c_str(),dt,it,MED_FULL_INTERLACE,da->getPointer())); - _clmesh->setCoords(da); -} - -MEDFileUMeshPermCompute::MEDFileUMeshPermCompute(const MEDFileUMeshSplitL1* st):_st(st),_mpt_time(0),_num_time(0) -{ -} - -/*! - * Warning it returns an instance to deallocate !!!! - */ -MEDFileUMeshPermCompute::operator MEDCouplingUMesh *() const -{ - _st->_num->updateTime(); - if((MEDCouplingUMesh *)_m==0) - { - updateTime(); - _m=static_cast(_st->_m_by_types.getUmesh()->deepCpy()); - _m->renumberCells(_st->_num->getConstPointer(),true); - return _m.retn(); - } - else - { - if(_mpt_time==_st->_m_by_types.getTimeOfThis() && _num_time==_st->_num->getTimeOfThis()) - return _m.retn(); - else - { - updateTime(); - _m=static_cast(_st->_m_by_types.getUmesh()->deepCpy()); - _m->renumberCells(_st->_num->getConstPointer(),true); - return _m.retn(); - } - } -} - -void MEDFileUMeshPermCompute::operator=(MEDCouplingUMesh *m) -{ - _m=m; -} - -void MEDFileUMeshPermCompute::updateTime() const -{ - _mpt_time=_st->_m_by_types.getTimeOfThis(); - _num_time=_st->_num->getTimeOfThis(); -} - -std::vector MEDFileUMeshPermCompute::getDirectChildrenWithNull() const -{ - std::vector ret; - ret.push_back((const MEDCouplingUMesh *)_m); - return ret; -} - -std::size_t MEDFileUMeshPermCompute::getHeapMemorySizeWithoutChildren() const -{ - return sizeof(MEDFileUMeshPermCompute); -} - -MEDFileUMeshSplitL1::MEDFileUMeshSplitL1(const MEDFileUMeshSplitL1& other):RefCountObject(other),_m_by_types(other._m_by_types),_fam(other._fam),_num(other._num),_names(other._names),_rev_num(other._rev_num),_m(this) -{ -} - -MEDFileUMeshSplitL1::MEDFileUMeshSplitL1(const MEDFileUMeshL2& l2, const std::string& mName, int id):_m(this) -{ - const std::vector< MEDCouplingAutoRefCountObjectPtr >& v=l2.getLev(id); - if(v.empty()) - return; - int sz=v.size(); - std::vector ms(sz); - std::vector fams(sz),nums(sz); - std::vector names(sz); - std::vector pds(sz); - for(int i=0;igetMesh()); - MEDCouplingAutoRefCountObjectPtr tmp2=l2.getCoords(); - elt->setCoords(tmp2); - ms[i]=elt; - pds[i]=v[i]->getPartDef(); - } - _m_by_types.assignParts(ms); - _m_by_types.assignDefParts(pds); - if(l2.isFamDefinedOnLev(id)) - { - for(int i=0;igetFam(); - if(sz!=1) - _fam=DataArrayInt::Aggregate(fams); - else - { - fams[0]->incrRef(); - _fam=const_cast(fams[0]); - } - } - if(l2.isNumDefinedOnLev(id)) - { - for(int i=0;igetNum(); - if(sz!=1) - _num=DataArrayInt::Aggregate(nums); - else - { - nums[0]->incrRef(); - _num=const_cast(nums[0]); - } - computeRevNum(); - } - if(l2.isNamesDefinedOnLev(id)) - { - for(int i=0;igetNames(); - _names=dynamic_cast(DataArrayChar::Aggregate(names)); - } -} - -MEDFileUMeshSplitL1::MEDFileUMeshSplitL1(MEDCoupling1GTUMesh *m):_m(this) -{ - std::vector< const MEDCoupling1GTUMesh * > v(1); - v[0]=m; - assignParts(v); -} - -MEDFileUMeshSplitL1::MEDFileUMeshSplitL1(MEDCouplingUMesh *m):_m(this) -{ - assignMesh(m,true); -} - -MEDFileUMeshSplitL1::MEDFileUMeshSplitL1(MEDCouplingUMesh *m, bool newOrOld):_m(this) -{ - assignMesh(m,newOrOld); -} - -void MEDFileUMeshSplitL1::setName(const std::string& name) -{ - _m_by_types.setName(name); -} - -std::size_t MEDFileUMeshSplitL1::getHeapMemorySizeWithoutChildren() const -{ - return 0; -} - -std::vector MEDFileUMeshSplitL1::getDirectChildrenWithNull() const -{ - std::vector ret; - ret.push_back(&_m_by_types); - ret.push_back(&_m); - ret.push_back((const DataArrayInt*)_fam); - ret.push_back((const DataArrayInt*)_num); - ret.push_back((const DataArrayInt*)_rev_num); - ret.push_back((const DataArrayAsciiChar*)_names); - return ret; -} - -MEDFileUMeshSplitL1 *MEDFileUMeshSplitL1::deepCpy(DataArrayDouble *coords) const -{ - MEDCouplingAutoRefCountObjectPtr ret=new MEDFileUMeshSplitL1(*this); - ret->_m_by_types=_m_by_types.deepCpy(coords); - if((const DataArrayInt *)_fam) - ret->_fam=_fam->deepCpy(); - if((const DataArrayInt *)_num) - ret->_num=_num->deepCpy(); - if((const DataArrayInt *)_rev_num) - ret->_rev_num=_rev_num->deepCpy(); - if((const DataArrayAsciiChar *)_names) - ret->_names=_names->deepCpy(); - return ret.retn(); -} - -bool MEDFileUMeshSplitL1::isEqual(const MEDFileUMeshSplitL1 *other, double eps, std::string& what) const -{ - if(!_m_by_types.isEqual(other->_m_by_types,eps,what)) - return false; - const DataArrayInt *d1=_fam; - const DataArrayInt *d2=other->_fam; - if((d1==0 && d2!=0) || (d1!=0 && d2==0)) - { - what="Presence of family arr in one sublevel and not in other!"; - return false; - } - if(d1) - if(!d1->isEqual(*d2)) - { - what="family arr at a sublevel are not deeply equal !"; - return false; - } - d1=_num; - d2=other->_num; - if((d1==0 && d2!=0) || (d1!=0 && d2==0)) - { - what="Presence of cell numbering arr in one sublevel and not in other!"; - return false; - } - if(d1) - if(!d1->isEqual(*d2)) - { - what="Numbering cell arr at a sublevel are not deeply equal !"; - return false; - } - const DataArrayAsciiChar *e1=_names; - const DataArrayAsciiChar *e2=other->_names; - if((e1==0 && e2!=0) || (e1!=0 && e2==0)) - { - what="Presence of cell names arr in one sublevel and not in other!"; - return false; - } - if(e1) - if(!e1->isEqual(*e2)) - { - what="Name cell arr at a sublevel are not deeply equal !"; - return false; - } - return true; -} - -void MEDFileUMeshSplitL1::synchronizeTinyInfo(const MEDFileMesh& master) const -{ - _m_by_types.synchronizeTinyInfo(master); -} - -void MEDFileUMeshSplitL1::clearNonDiscrAttributes() const -{ - _m_by_types.clearNonDiscrAttributes(); -} - -void MEDFileUMeshSplitL1::ClearNonDiscrAttributes(const MEDCouplingMesh *tmp) -{ - if(!tmp) - return ; - (const_cast(tmp))->setName(""); - (const_cast(tmp))->setDescription(""); - (const_cast(tmp))->setTime(0.,-1,-1); - (const_cast(tmp))->setTimeUnit(""); -} - -void MEDFileUMeshSplitL1::setCoords(DataArrayDouble *coords) -{ - _m_by_types.setCoords(coords); -} - -void MEDFileUMeshSplitL1::assignMesh(MEDCouplingUMesh *m, bool newOrOld) -{ - if(newOrOld) - { - m->incrRef(); - _m=m; - _m_by_types.assignUMesh(dynamic_cast(m->deepCpy())); - MEDCouplingAutoRefCountObjectPtr da=_m_by_types.getUmesh()->getRenumArrForConsecutiveCellTypesSpec(typmai2,typmai2+MED_N_CELL_FIXED_GEO); - if(!da->isIdentity()) - { - _num=da->invertArrayO2N2N2O(m->getNumberOfCells()); - _m.updateTime(); - computeRevNum(); - _m_by_types.getUmesh()->renumberCells(da->getConstPointer(),false); - } - } - else - { - if(!m->checkConsecutiveCellTypesAndOrder(typmai2,typmai2+MED_N_CELL_FIXED_GEO)) - throw INTERP_KERNEL::Exception("MEDFileUMeshSplitL1::assignMesh : the mode of mesh setting expects to follow the MED file numbering convention ! it is not the case !"); - m->incrRef(); - _m_by_types.assignUMesh(m); - } - assignCommonPart(); -} - -void MEDFileUMeshSplitL1::forceComputationOfParts() const -{ - _m_by_types.forceComputationOfPartsFromUMesh(); -} - -void MEDFileUMeshSplitL1::assignParts(const std::vector< const MEDCoupling1GTUMesh * >& mParts) -{ - _m_by_types.assignParts(mParts); - assignCommonPart(); -} - -MEDFileUMeshSplitL1::MEDFileUMeshSplitL1():_m(this) -{ -} - -void MEDFileUMeshSplitL1::assignCommonPart() -{ - _fam=DataArrayInt::New(); - _fam->alloc(_m_by_types.getSize(),1); - _fam->fillWithValue(0); -} - -bool MEDFileUMeshSplitL1::empty() const -{ - return _m_by_types.empty(); -} - -bool MEDFileUMeshSplitL1::presenceOfOneFams(const std::vector& ids) const -{ - const DataArrayInt *fam=_fam; - if(!fam) - return false; - return fam->presenceOfValue(ids); -} - -int MEDFileUMeshSplitL1::getMeshDimension() const -{ - return _m_by_types.getMeshDimension(); -} - -void MEDFileUMeshSplitL1::simpleRepr(std::ostream& oss) const -{ - std::vector code=_m_by_types.getDistributionOfTypes(); - int nbOfTypes=code.size()/3; - for(int i=0;i eltsToKeep=_fam->getIdsEqualList(idsBg,idsEnd); - MEDCouplingUMesh *m=(MEDCouplingUMesh *)_m_by_types.getUmesh()->buildPartOfMySelf(eltsToKeep->getConstPointer(),eltsToKeep->getConstPointer()+eltsToKeep->getNumberOfTuples(),true); - if(renum) - return renumIfNeeded(m,eltsToKeep->getConstPointer()); - return m; -} - -DataArrayInt *MEDFileUMeshSplitL1::getFamilyPartArr(const int *idsBg, const int *idsEnd, bool renum) const -{ - MEDCouplingAutoRefCountObjectPtr da=_fam->getIdsEqualList(idsBg,idsEnd); - if(renum) - return renumIfNeededArr(da); - return da.retn(); -} - -std::vector MEDFileUMeshSplitL1::getGeoTypes() const -{ - return _m_by_types.getGeoTypes(); -} - -MEDCouplingUMesh *MEDFileUMeshSplitL1::getWholeMesh(bool renum) const -{ - MEDCouplingAutoRefCountObjectPtr tmp; - if(renum && ((const DataArrayInt *)_num)) - tmp=_m; - else - { tmp=_m_by_types.getUmesh(); if(tmp) tmp->incrRef(); } - return tmp.retn(); -} - -int MEDFileUMeshSplitL1::getNumberOfCells() const -{ - return _m_by_types.getNumberOfCells(); -} - -DataArrayInt *MEDFileUMeshSplitL1::extractFamilyFieldOnGeoType(INTERP_KERNEL::NormalizedCellType gt) const -{ - const DataArrayInt *fam(_fam); - if(!fam) - return 0; - int start(0),stop(0); - _m_by_types.getStartStopOfGeoTypeWithoutComputation(gt,start,stop); - return fam->selectByTupleId2(start,stop,1); -} - -DataArrayInt *MEDFileUMeshSplitL1::extractNumberFieldOnGeoType(INTERP_KERNEL::NormalizedCellType gt) const -{ - const DataArrayInt *num(_num); - if(!num) - return 0; - int start(0),stop(0); - _m_by_types.getStartStopOfGeoTypeWithoutComputation(gt,start,stop); - return num->selectByTupleId2(start,stop,1); -} - -DataArrayInt *MEDFileUMeshSplitL1::getOrCreateAndGetFamilyField() -{ - if((DataArrayInt *)_fam) - return _fam; - int nbOfTuples=_m_by_types.getSize(); - _fam=DataArrayInt::New(); _fam->alloc(nbOfTuples,1); _fam->fillWithZero(); - return _fam; -} - -const DataArrayInt *MEDFileUMeshSplitL1::getFamilyField() const -{ - return _fam; -} - -const DataArrayInt *MEDFileUMeshSplitL1::getNumberField() const -{ - return _num; -} - -const DataArrayInt *MEDFileUMeshSplitL1::getRevNumberField() const -{ - return _rev_num; -} - -const DataArrayAsciiChar *MEDFileUMeshSplitL1::getNameField() const -{ - return _names; -} - -const PartDefinition *MEDFileUMeshSplitL1::getPartDef(INTERP_KERNEL::NormalizedCellType gt) const -{ - return _m_by_types.getPartDefOfWithoutComputation(gt); -} - -void MEDFileUMeshSplitL1::eraseFamilyField() -{ - _fam->fillWithZero(); -} - -/*! - * This method ignores _m and _m_by_types. - */ -void MEDFileUMeshSplitL1::setGroupsFromScratch(const std::vector& ms, std::map& familyIds, - std::map >& groups) -{ - std::vector< DataArrayInt * > corr; - _m=MEDCouplingUMesh::FuseUMeshesOnSameCoords(ms,0,corr); - std::vector< MEDCouplingAutoRefCountObjectPtr > corrMSafe(corr.begin(),corr.end()); - std::vector< std::vector > fidsOfGroups; - std::vector< const DataArrayInt * > corr2(corr.begin(),corr.end()); - _fam=DataArrayInt::MakePartition(corr2,((MEDCouplingUMesh *)_m)->getNumberOfCells(),fidsOfGroups); - int nbOfCells=((MEDCouplingUMesh *)_m)->getNumberOfCells(); - std::map newfams; - std::map famIdTrad; - TraduceFamilyNumber(fidsOfGroups,familyIds,famIdTrad,newfams); - int *w=_fam->getPointer(); - for(int i=0;i ms(_m_by_types.getParts()); - int start=0; - for(std::vector::const_iterator it=ms.begin();it!=ms.end();it++) - { - int nbCells=(*it)->getNumberOfCells(); - int end=start+nbCells; - MEDCouplingAutoRefCountObjectPtr fam,num; - MEDCouplingAutoRefCountObjectPtr names; - if((const DataArrayInt *)_fam) - fam=_fam->substr(start,end); - if((const DataArrayInt *)_num) - num=_num->substr(start,end); - if((const DataArrayAsciiChar *)_names) - names=static_cast(_names->substr(start,end)); - MEDFileUMeshPerType::Write(fid,mName,mdim,(*it),fam,num,names); - start=end; - } -} - -void MEDFileUMeshSplitL1::renumberNodesInConn(const int *newNodeNumbersO2N) -{ - _m_by_types.renumberNodesInConnWithoutComputation(newNodeNumbersO2N); -} - -void MEDFileUMeshSplitL1::serialize(std::vector& tinyInt, std::vector< MEDCouplingAutoRefCountObjectPtr >& bigArraysI) const -{ - bigArraysI.push_back(_fam); - bigArraysI.push_back(_num); - _m_by_types.serialize(tinyInt,bigArraysI); -} - -void MEDFileUMeshSplitL1::unserialize(const std::string& name, DataArrayDouble *coo, std::vector& tinyInt, std::vector< MEDCouplingAutoRefCountObjectPtr >& bigArraysI) -{ - _fam=bigArraysI.back(); bigArraysI.pop_back(); - _num=bigArraysI.back(); bigArraysI.pop_back(); - _m_by_types.unserialize(name,coo,tinyInt,bigArraysI); -} - -void MEDFileUMeshSplitL1::changeFamilyIdArr(int oldId, int newId) -{ - DataArrayInt *arr=_fam; - if(arr) - arr->changeValue(oldId,newId); -} - -void MEDFileUMeshSplitL1::setFamilyArr(DataArrayInt *famArr) -{ - if(!famArr) - { - _fam=0; - return ; - } - int sz(_m_by_types.getSize()); - famArr->checkNbOfTuplesAndComp(sz,1,"MEDFileUMeshSplitL1::setFamilyArr : Problem in size of Family arr ! "); - famArr->incrRef(); - _fam=famArr; -} - -DataArrayInt *MEDFileUMeshSplitL1::getFamilyField() -{ - return _fam; -} - -void MEDFileUMeshSplitL1::setRenumArr(DataArrayInt *renumArr) -{ - if(!renumArr) - { - _num=0; - _rev_num=0; - return ; - } - int sz(_m_by_types.getSize()); - renumArr->checkNbOfTuplesAndComp(sz,1,"MEDFileUMeshSplitL1::setRenumArr : Problem in size of numbering arr ! "); - renumArr->incrRef(); - _num=renumArr; - computeRevNum(); -} - -void MEDFileUMeshSplitL1::setNameArr(DataArrayAsciiChar *nameArr) -{ - if(!nameArr) - { - _names=0; - return ; - } - int sz(_m_by_types.getSize()); - nameArr->checkNbOfTuplesAndComp(sz,MED_SNAME_SIZE,"MEDFileUMeshSplitL1::setNameArr : Problem in size of name arr ! "); - nameArr->incrRef(); - _names=nameArr; -} - -MEDCouplingUMesh *MEDFileUMeshSplitL1::Renumber2(const DataArrayInt *renum, MEDCouplingUMesh *m, const int *cellIds) -{ - if(renum==0) - return m; - if(cellIds==0) - m->renumberCells(renum->getConstPointer(),true); - else - { - MEDCouplingAutoRefCountObjectPtr locnum=renum->selectByTupleId(cellIds,cellIds+m->getNumberOfCells()); - m->renumberCells(locnum->getConstPointer(),true); - } - return m; -} - -MEDFileUMeshSplitL1 *MEDFileUMeshSplitL1::Unserialize(const std::string& name, DataArrayDouble *coo, std::vector& tinyInt, std::vector< MEDCouplingAutoRefCountObjectPtr >& bigArraysI) -{ - MEDCouplingAutoRefCountObjectPtr ret(new MEDFileUMeshSplitL1); - ret->unserialize(name,coo,tinyInt,bigArraysI); - return ret.retn(); -} - -MEDCouplingUMesh *MEDFileUMeshSplitL1::renumIfNeeded(MEDCouplingUMesh *m, const int *cellIds) const -{ - return Renumber2(_num,m,cellIds); -} - -DataArrayInt *MEDFileUMeshSplitL1::Renumber(const DataArrayInt *renum, const DataArrayInt *da) -{ - if((const DataArrayInt *)renum==0) - { - da->incrRef(); - return const_cast(da); - } - return renum->selectByTupleId(da->getConstPointer(),da->getConstPointer()+da->getNumberOfTuples()); -} - -DataArrayInt *MEDFileUMeshSplitL1::renumIfNeededArr(const DataArrayInt *da) const -{ - return Renumber(_num,da); -} - -std::vector MEDFileUMeshSplitL1::GetNewFamiliesNumber(int nb, const std::map& families) -{ - int id=-1; - for(std::map::const_iterator it=families.begin();it!=families.end();it++) - id=std::max(id,(*it).second); - if(id==-1) - id=0; - std::vector ret(nb); - for(int i=1;i<=nb;i++) - ret[i]=id+i; - return ret; -} - -void MEDFileUMeshSplitL1::TraduceFamilyNumber(const std::vector< std::vector >& fidsGrps, std::map& familyIds, - std::map& famIdTrad, std::map& newfams) -{ - std::set allfids; - //tony -} - -void MEDFileUMeshSplitL1::computeRevNum() const -{ - int pos; - int maxValue=_num->getMaxValue(pos); - _rev_num=_num->invertArrayN2O2O2N(maxValue+1); -} - -//= - -MEDFileUMeshAggregateCompute::MEDFileUMeshAggregateCompute():_mp_time(0),_m_time(0) -{ -} - -void MEDFileUMeshAggregateCompute::setName(const std::string& name) -{ - if(_m_time>=_mp_time) - { - MEDCouplingUMesh *um(_m); - if(um) - um->setName(name); - } - if(_mp_time>=_m_time) - { - for(std::vector< MEDCouplingAutoRefCountObjectPtr >::iterator it=_m_parts.begin();it!=_m_parts.end();it++) - { - MEDCoupling1GTUMesh *tmp(*it); - if(tmp) - tmp->setName(name); - } - } -} - -void MEDFileUMeshAggregateCompute::assignParts(const std::vector< const MEDCoupling1GTUMesh * >& mParts) -{ - std::size_t sz(mParts.size()); - std::vector< MEDCouplingAutoRefCountObjectPtr > ret(sz); - for(std::size_t i=0;i(elt); elt->incrRef(); - } - _m_parts=ret; - _part_def.clear(); _part_def.resize(sz); - _mp_time=std::max(_mp_time,_m_time)+1; - _m=0; -} - -void MEDFileUMeshAggregateCompute::assignDefParts(const std::vector& partDefs) -{ - if(_mp_time<_m_time) - throw INTERP_KERNEL::Exception("MEDFileUMeshAggregateCompute::assignDefParts : the parts require a computation !"); - std::size_t sz(partDefs.size()); - if(_part_def.size()!=partDefs.size() || _part_def.size()!=_m_parts.size()) - throw INTERP_KERNEL::Exception("MEDFileUMeshAggregateCompute::assignDefParts : sizes of vectors of part definition mismatch !"); - for(std::size_t i=0;iincrRef(); - _part_def[i]=const_cast(elt); - } -} - -void MEDFileUMeshAggregateCompute::assignUMesh(MEDCouplingUMesh *m) -{ - _m=m; - _m_parts.clear(); - _m_time=std::max(_mp_time,_m_time)+1; -} - -MEDCouplingUMesh *MEDFileUMeshAggregateCompute::getUmesh() const -{ - if(_mp_time<=_m_time) - return _m; - std::vector< const MEDCoupling1GTUMesh *> mp(_m_parts.size()); - std::copy(_m_parts.begin(),_m_parts.end(),mp.begin()); - _m=MEDCoupling1GTUMesh::AggregateOnSameCoordsToUMesh(mp); - _m_parts.clear();//to avoid memory peak ! - _m_time=_mp_time+1;//+1 is important ! That is to say that only _m is OK not _m_parts because cleared ! - return _m; -} - -int MEDFileUMeshAggregateCompute::getNumberOfCells() const -{ - if(_mp_time<=_m_time) - return _m->getNumberOfCells(); - int ret(0); - for(std::vector< MEDCouplingAutoRefCountObjectPtr >::const_iterator it=_m_parts.begin();it!=_m_parts.end();it++) - ret+=(*it)->getNumberOfCells(); - return ret; -} - -std::vector MEDFileUMeshAggregateCompute::getGeoTypes() const -{ - if(_mp_time>=_m_time) - { - std::size_t sz(_m_parts.size()); - std::vector ret(sz); - for(std::size_t i=0;igetCellModelEnum(); - return ret; - } - else - return _m->getAllGeoTypesSorted(); -} - -std::vector MEDFileUMeshAggregateCompute::retrievePartsWithoutComputation() const -{ - if(_mp_time<_m_time) - throw INTERP_KERNEL::Exception("MEDFileUMeshAggregateCompute::getPartsWithoutComputation : the parts require a computation !"); - // - std::vector ret(_m_parts.size()); - std::size_t i(0); - for(std::vector< MEDCouplingAutoRefCountObjectPtr >::const_iterator it=_m_parts.begin();it!=_m_parts.end();it++,i++) - { - const MEDCoupling1GTUMesh *elt(*it); - ret[i]=const_cast(elt); - } - return ret; -} - -std::vector MEDFileUMeshAggregateCompute::getParts() const -{ - if(_mp_time<_m_time) - forceComputationOfPartsFromUMesh(); - return retrievePartsWithoutComputation(); -} - -MEDCoupling1GTUMesh *MEDFileUMeshAggregateCompute::retrievePartWithoutComputation(INTERP_KERNEL::NormalizedCellType gt) const -{ - std::vector v(retrievePartsWithoutComputation()); - std::size_t sz(v.size()); - for(std::size_t i=0;igetCellModelEnum()==gt) - return v[i]; - } - throw INTERP_KERNEL::Exception("MEDFileUMeshAggregateCompute::getPartWithoutComputation : the geometric type is not existing !"); -} - -void MEDFileUMeshAggregateCompute::getStartStopOfGeoTypeWithoutComputation(INTERP_KERNEL::NormalizedCellType gt, int& start, int& stop) const -{ - start=0; stop=0; - std::vector v(retrievePartsWithoutComputation()); - std::size_t sz(v.size()); - for(std::size_t i=0;igetCellModelEnum()==gt) - { - stop=start+v[i]->getNumberOfCells(); - return; - } - else - start+=v[i]->getNumberOfCells(); - } - } - throw INTERP_KERNEL::Exception("MEDFileUMeshAggregateCompute::getStartStopOfGeoTypeWithoutComputation : the geometric type is not existing !"); -} - -void MEDFileUMeshAggregateCompute::renumberNodesInConnWithoutComputation(const int *newNodeNumbersO2N) -{ - if(_mp_time>_m_time) - { - for(std::vector< MEDCouplingAutoRefCountObjectPtr >::iterator it=_m_parts.begin();it!=_m_parts.end();it++) - { - MEDCoupling1GTUMesh *m(*it); - if(m) - m->renumberNodesInConn(newNodeNumbersO2N); - } - } - else - { - MEDCouplingUMesh *m(getUmesh()); - if(!m) - return; - m->renumberNodesInConn(newNodeNumbersO2N); - } -} - -void MEDFileUMeshAggregateCompute::forceComputationOfPartsFromUMesh() const -{ - const MEDCouplingUMesh *m(_m); - if(!m) - { - if(_m_parts.empty()) - throw INTERP_KERNEL::Exception("MEDFileUMeshAggregateCompute::forceComputationOfPartsFromUMesh : null UMesh !"); - else - return ;// no needs to compte parts they are already here ! - } - std::vector ms(m->splitByType()); - std::vector< MEDCouplingAutoRefCountObjectPtr > msMSafe(ms.begin(),ms.end()); - std::size_t sz(msMSafe.size()); - _m_parts.resize(sz); - for(std::size_t i=0;igetCellModelEnum()==gt) - return _part_def[i]; - } - throw INTERP_KERNEL::Exception("MEDFileUMeshAggregateCompute::getPartDefOfWithoutComputation : The input geo type is not existing in this !"); -} - -void MEDFileUMeshAggregateCompute::serialize(std::vector& tinyInt, std::vector< MEDCouplingAutoRefCountObjectPtr >& bigArraysI) const -{ - if(_mp_time<_m_time) - throw INTERP_KERNEL::Exception("MEDFileUMeshAggregateCompute::serialize : the parts require a computation !"); - std::size_t sz(_m_parts.size()); - tinyInt.push_back((int)sz); - for(std::size_t i=0;igetCellModelEnum()); - const MEDCoupling1SGTUMesh *mesh1(dynamic_cast(mesh)); - const MEDCoupling1DGTUMesh *mesh2(dynamic_cast(mesh)); - if(mesh1) - { - DataArrayInt *elt(mesh1->getNodalConnectivity()); - if(elt) - elt->incrRef(); - MEDCouplingAutoRefCountObjectPtr elt1(elt); - bigArraysI.push_back(elt1); - } - else if(mesh2) - { - DataArrayInt *elt1(mesh2->getNodalConnectivity()),*elt2(mesh2->getNodalConnectivityIndex()); - if(elt1) - elt1->incrRef(); - if(elt2) - elt2->incrRef(); - MEDCouplingAutoRefCountObjectPtr elt11(elt1),elt22(elt2); - bigArraysI.push_back(elt11); bigArraysI.push_back(elt22); - } - else - throw INTERP_KERNEL::Exception("MEDFileUMeshAggregateCompute::serialize : unrecognized single geo type mesh !"); - const PartDefinition *pd(_part_def[i]); - if(!pd) - tinyInt.push_back(-1); - else - { - std::vector tinyTmp; - pd->serialize(tinyTmp,bigArraysI); - tinyInt.push_back((int)tinyTmp.size()); - tinyInt.insert(tinyInt.end(),tinyTmp.begin(),tinyTmp.end()); - } - } -} - -void MEDFileUMeshAggregateCompute::unserialize(const std::string& name, DataArrayDouble *coo, std::vector& tinyInt, std::vector< MEDCouplingAutoRefCountObjectPtr >& bigArraysI) -{ - int nbParts(tinyInt.back()); tinyInt.pop_back(); - _part_def.clear(); _part_def.resize(nbParts); - _m_parts.clear(); _m_parts.resize(nbParts); - for(int i=0;i mesh(MEDCoupling1GTUMesh::New(name,tp)); - mesh->setCoords(coo); - MEDCoupling1SGTUMesh *mesh1(dynamic_cast((MEDCoupling1GTUMesh *) mesh)); - MEDCoupling1DGTUMesh *mesh2(dynamic_cast((MEDCoupling1GTUMesh *) mesh)); - if(mesh1) - { - mesh1->setNodalConnectivity(bigArraysI.back()); bigArraysI.pop_back(); - } - else if(mesh2) - { - MEDCouplingAutoRefCountObjectPtr elt0,elt1; - elt0=bigArraysI.back(); bigArraysI.pop_back(); - elt1=bigArraysI.back(); bigArraysI.pop_back(); - mesh2->setNodalConnectivity(elt0,elt1); - } - else - throw INTERP_KERNEL::Exception("MEDFileUMeshAggregateCompute::unserialize : unrecognized single geo type mesh !"); - _m_parts[i]=mesh; - int pdid(tinyInt.back()); tinyInt.pop_back(); - if(pdid!=-1) - _part_def[i]=PartDefinition::Unserialize(tinyInt,bigArraysI); - _mp_time=std::max(_mp_time,_m_time)+1; - } -} - -/*! - * This method returns true if \a this is stored split by type false if stored in a merged unstructured mesh. - */ -bool MEDFileUMeshAggregateCompute::isStoredSplitByType() const -{ - return _mp_time>=_m_time; -} - -std::size_t MEDFileUMeshAggregateCompute::getTimeOfThis() const -{ - if(_mp_time>_m_time) - return getTimeOfParts(); - if(_m_time>_mp_time) - return getTimeOfUMesh(); - return std::max(getTimeOfParts(),getTimeOfUMesh()); -} - -std::size_t MEDFileUMeshAggregateCompute::getTimeOfParts() const -{ - std::size_t ret(0); - for(std::vector< MEDCouplingAutoRefCountObjectPtr >::const_iterator it=_m_parts.begin();it!=_m_parts.end();it++) - { - const MEDCoupling1GTUMesh *elt(*it); - if(!elt) - throw INTERP_KERNEL::Exception("MEDFileUMeshAggregateCompute::getTimeOfParts : null obj in parts !"); - ret=std::max(ret,elt->getTimeOfThis()); - } - if(ret==0) - throw INTERP_KERNEL::Exception("MEDFileUMeshAggregateCompute::getTimeOfParts : parts is empty !"); - return ret; -} - -std::size_t MEDFileUMeshAggregateCompute::getTimeOfUMesh() const -{ - const MEDCouplingUMesh *m(_m); - if(!m) - throw INTERP_KERNEL::Exception("MEDFileUMeshAggregateCompute::getTimeOfUMesh : unmesh is null !"); - return m->getTimeOfThis(); -} - -std::size_t MEDFileUMeshAggregateCompute::getHeapMemorySizeWithoutChildren() const -{ - std::size_t ret(_m_parts.size()*sizeof(MEDCouplingAutoRefCountObjectPtr)); - return ret; -} - -std::vector MEDFileUMeshAggregateCompute::getDirectChildrenWithNull() const -{ - std::vector ret; - for(std::vector< MEDCouplingAutoRefCountObjectPtr >::const_iterator it=_m_parts.begin();it!=_m_parts.end();it++) - ret.push_back((const MEDCoupling1GTUMesh *)*it); - ret.push_back((const MEDCouplingUMesh *)_m); - return ret; -} - -MEDFileUMeshAggregateCompute MEDFileUMeshAggregateCompute::deepCpy(DataArrayDouble *coords) const -{ - MEDFileUMeshAggregateCompute ret; - ret._m_parts.resize(_m_parts.size()); - for(std::size_t i=0;i<_m_parts.size();i++) - { - const MEDCoupling1GTUMesh *elt(_m_parts[i]); - if(elt) - { - ret._m_parts[i]=static_cast(elt->deepCpy()); - ret._m_parts[i]->setCoords(coords); - } - } - ret._mp_time=_mp_time; ret._m_time=_m_time; - if((const MEDCouplingUMesh *)_m) - { - ret._m=static_cast(_m->deepCpy()); - ret._m->setCoords(coords); - } - std::size_t sz(_part_def.size()); - ret._part_def.clear(); ret._part_def.resize(sz); - for(std::size_t i=0;ideepCpy(); - } - return ret; -} - -bool MEDFileUMeshAggregateCompute::isEqual(const MEDFileUMeshAggregateCompute& other, double eps, std::string& what) const -{ - const MEDCouplingUMesh *m1(getUmesh()); - const MEDCouplingUMesh *m2(other.getUmesh()); - if((m1==0 && m2!=0) || (m1!=0 && m2==0)) - { - what="Presence of mesh in one sublevel and not in other!"; - return false; - } - if(m1) - { - std::string what2; - if(!m1->isEqualIfNotWhy(m2,eps,what2)) - { - what=std::string("meshes at a sublevel are not deeply equal (")+what2+std::string(")!"); - return false; - } - } - std::size_t sz(_part_def.size()); - if(sz!=other._part_def.size()) - { - what=std::string("number of subdivision per geo type for part definition is not the same !"); - return false; - } - for(std::size_t i=0;iisEqual(pd1,what)); - if(!ret) - return false; - } - return true; -} - -void MEDFileUMeshAggregateCompute::clearNonDiscrAttributes() const -{ - for(std::vector< MEDCouplingAutoRefCountObjectPtr >::const_iterator it=_m_parts.begin();it!=_m_parts.end();it++) - MEDFileUMeshSplitL1::ClearNonDiscrAttributes(*it); - MEDFileUMeshSplitL1::ClearNonDiscrAttributes(_m); -} - -void MEDFileUMeshAggregateCompute::synchronizeTinyInfo(const MEDFileMesh& master) const -{ - for(std::vector< MEDCouplingAutoRefCountObjectPtr >::const_iterator it=_m_parts.begin();it!=_m_parts.end();it++) - { - const MEDCoupling1GTUMesh *tmp(*it); - if(tmp) - { - (const_cast(tmp))->setName(master.getName().c_str()); - (const_cast(tmp))->setDescription(master.getDescription().c_str()); - (const_cast(tmp))->setTime(master.getTimeValue(),master.getIteration(),master.getOrder()); - (const_cast(tmp))->setTimeUnit(master.getTimeUnit()); - } - } - const MEDCouplingUMesh *m(_m); - if(m) - { - (const_cast(m))->setName(master.getName().c_str()); - (const_cast(m))->setDescription(master.getDescription().c_str()); - (const_cast(m))->setTime(master.getTimeValue(),master.getIteration(),master.getOrder()); - (const_cast(m))->setTimeUnit(master.getTimeUnit()); - } -} - -bool MEDFileUMeshAggregateCompute::empty() const -{ - if(_mp_time<_m_time) - return ((const MEDCouplingUMesh *)_m)==0; - //else _mp_time>=_m_time) - return _m_parts.empty(); -} - -int MEDFileUMeshAggregateCompute::getMeshDimension() const -{ - if(_mp_time<_m_time) - { - const MEDCouplingUMesh *m(_m); - if(!m) - throw INTERP_KERNEL::Exception("MEDFileUMeshAggregateCompute::getMeshDimension : no umesh in this !"); - return m->getMeshDimension(); - } - else - { - if(_m_parts.empty()) - throw INTERP_KERNEL::Exception("MEDFileUMeshAggregateCompute::getMeshDimension : part mesh is empty !"); - const MEDCoupling1GTUMesh *m(_m_parts[0]); - if(!m) - throw INTERP_KERNEL::Exception("MEDFileUMeshAggregateCompute::getMeshDimension : part mesh contains null instance !"); - return m->getMeshDimension(); - } -} - -std::vector MEDFileUMeshAggregateCompute::getDistributionOfTypes() const -{ - if(_mp_time<_m_time) - { - const MEDCouplingUMesh *m(_m); - if(!m) - throw INTERP_KERNEL::Exception("MEDFileUMeshAggregateCompute::getDistributionOfTypes : no umesh in this !"); - return m->getDistributionOfTypes(); - } - else - { - std::vector ret; - for(std::vector< MEDCouplingAutoRefCountObjectPtr >::const_iterator it=_m_parts.begin();it!=_m_parts.end();it++) - { - const MEDCoupling1GTUMesh *tmp(*it); - if(!tmp) - throw INTERP_KERNEL::Exception("MEDFileUMeshAggregateCompute::getDistributionOfTypes : part mesh contains null instance !"); - std::vector ret0(tmp->getDistributionOfTypes()); - ret.insert(ret.end(),ret0.begin(),ret0.end()); - } - return ret; - } -} - -int MEDFileUMeshAggregateCompute::getSize() const -{ - if(_mp_time<_m_time) - { - const MEDCouplingUMesh *m(_m); - if(!m) - throw INTERP_KERNEL::Exception("MEDFileUMeshAggregateCompute::getSize : no umesh in this !"); - return m->getNumberOfCells(); - } - else - { - int ret=0; - for(std::vector< MEDCouplingAutoRefCountObjectPtr >::const_iterator it=_m_parts.begin();it!=_m_parts.end();it++) - { - const MEDCoupling1GTUMesh *m(*it); - if(!m) - throw INTERP_KERNEL::Exception("MEDFileUMeshAggregateCompute::getSize : part mesh contains null instance !"); - ret+=m->getNumberOfCells(); - } - return ret; - } -} - -void MEDFileUMeshAggregateCompute::setCoords(DataArrayDouble *coords) -{ - for(std::vector< MEDCouplingAutoRefCountObjectPtr >::iterator it=_m_parts.begin();it!=_m_parts.end();it++) - { - MEDCoupling1GTUMesh *tmp(*it); - if(tmp) - (*it)->setCoords(coords); - } - MEDCouplingUMesh *m(_m); - if(m) - m->setCoords(coords); -} diff --git a/src/MEDLoader/MEDFileMeshLL.hxx b/src/MEDLoader/MEDFileMeshLL.hxx deleted file mode 100644 index b6872efc7..000000000 --- a/src/MEDLoader/MEDFileMeshLL.hxx +++ /dev/null @@ -1,274 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 -// 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 __MEDFILEMESHLL_HXX__ -#define __MEDFILEMESHLL_HXX__ - -#include "MEDFileBasis.hxx" -#include "MEDFileMeshElt.hxx" - -#include "MEDCouplingUMesh.hxx" -#include "MEDCouplingCMesh.hxx" -#include "MEDCoupling1GTUMesh.hxx" -#include "MEDCouplingPartDefinition.hxx" -#include "MEDCouplingCurveLinearMesh.hxx" -#include "MEDCouplingAutoRefCountObjectPtr.hxx" - -#include "med.h" - -#include - -namespace ParaMEDMEM -{ - class MEDFileMeshReadSelector; - - class MEDFileMeshL2 : public RefCountObject - { - public: - MEDFileMeshL2(); - std::size_t getHeapMemorySizeWithoutChildren() const; - std::vector getDirectChildrenWithNull() const; - const char *getName() const { return _name.getReprForWrite(); } - const char *getDescription() const { return _description.getReprForWrite(); } - const char *getUnivName() const { return _univ_name.getReprForWrite(); } - const char *getTimeUnit() const { return _dt_unit.getReprForWrite(); } - int getIteration() const { return _iteration; } - int getOrder() const { return _order; } - double getTime() const { return _time; } - MEDCouplingAutoRefCountObjectPtr getPartDefOfCoo() const { return _part_coords; } - std::vector getAxisInfoOnMesh(med_idt fid, int mId, const std::string& mName, ParaMEDMEM::MEDCouplingMeshType& meshType, int& nstep, int& Mdim); - static int GetMeshIdFromName(med_idt fid, const std::string& mName, ParaMEDMEM::MEDCouplingMeshType& meshType, int& dt, int& it, std::string& dtunit1); - static double CheckMeshTimeStep(med_idt fid, const std::string& mname, int nstep, int dt, int it); - static void ReadFamiliesAndGrps(med_idt fid, const std::string& mname, std::map& fams, std::map >& grps, MEDFileMeshReadSelector *mrs); - static void WriteFamiliesAndGrps(med_idt fid, const std::string& mname, const std::map& fams, const std::map >& grps, int tooLongStrPol); - protected: - MEDFileString _name; - MEDFileString _description; - MEDFileString _univ_name; - MEDFileString _dt_unit; - int _iteration; - int _order; - double _time; - MEDCouplingAutoRefCountObjectPtr _part_coords; - }; - - class MEDFileUMeshL2 : public MEDFileMeshL2 - { - public: - MEDFileUMeshL2(); - std::vector loadCommonPart(med_idt fid, int mId, const std::string& mName, int dt, int it, int& Mdim); - void loadAll(med_idt fid, int mId, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs); - void loadPart(med_idt fid, int mId, const std::string& mName, const std::vector& types, const std::vector& slicPerTyp, int dt, int it, MEDFileMeshReadSelector *mrs); - void loadConnectivity(med_idt fid, int mdim, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs); - void loadPartOfConnectivity(med_idt fid, int mdim, const std::string& mName, const std::vector& types, const std::vector& slicPerTyp, int dt, int it, MEDFileMeshReadSelector *mrs); - void loadCoords(med_idt fid, int mId, const std::vector& infosOnComp, const std::string& mName, int dt, int it); - void loadPartCoords(med_idt fid, int mId, const std::vector& infosOnComp, const std::string& mName, int dt, int it, int nMin, int nMax); - int getNumberOfLevels() const { return _per_type_mesh.size(); } - bool emptyLev(int levId) const { return _per_type_mesh[levId].empty(); } - const std::vector< MEDCouplingAutoRefCountObjectPtr >& getLev(int levId) const { return _per_type_mesh[levId]; } - bool isFamDefinedOnLev(int levId) const; - bool isNumDefinedOnLev(int levId) const; - bool isNamesDefinedOnLev(int levId) const; - MEDCouplingAutoRefCountObjectPtr getCoords() const { return _coords; } - MEDCouplingAutoRefCountObjectPtr getCoordsFamily() const { return _fam_coords; } - MEDCouplingAutoRefCountObjectPtr getCoordsNum() const { return _num_coords; } - MEDCouplingAutoRefCountObjectPtr getCoordsName() const { return _name_coords; } - static void WriteCoords(med_idt fid, const std::string& mname, int dt, int it, double time, const DataArrayDouble *coords, const DataArrayInt *famCoords, const DataArrayInt *numCoords, const DataArrayAsciiChar *nameCoords); - private: - void sortTypes(); - private: - std::vector< std::vector< MEDCouplingAutoRefCountObjectPtr > > _per_type_mesh; - MEDCouplingAutoRefCountObjectPtr _coords; - MEDCouplingAutoRefCountObjectPtr _fam_coords; - MEDCouplingAutoRefCountObjectPtr _num_coords; - MEDCouplingAutoRefCountObjectPtr _name_coords; - }; - - class MEDFileStrMeshL2 : public MEDFileMeshL2 - { - }; - - class MEDFileCMeshL2 : public MEDFileStrMeshL2 - { - public: - MEDFileCMeshL2(); - void loadAll(med_idt fid, int mId, const std::string& mName, int dt, int it); - MEDCouplingCMesh *getMesh() { return _cmesh; } - private: - static med_data_type GetDataTypeCorrespondingToSpaceId(int id); - private: - MEDCouplingAutoRefCountObjectPtr _cmesh; - }; - - class MEDFileCLMeshL2 : public MEDFileStrMeshL2 - { - public: - MEDFileCLMeshL2(); - void loadAll(med_idt fid, int mId, const std::string& mName, int dt, int it); - MEDCouplingCurveLinearMesh *getMesh() { return _clmesh; } - private: - MEDCouplingAutoRefCountObjectPtr _clmesh; - }; - - class MEDFileMesh; - class MEDFileUMeshSplitL1; - - class MEDFileUMeshPermCompute : public BigMemoryObject - { - public: - MEDFileUMeshPermCompute(const MEDFileUMeshSplitL1* st); - operator MEDCouplingUMesh *() const; - void operator=(MEDCouplingUMesh *m); - void updateTime() const; - std::vector getDirectChildrenWithNull() const; - std::size_t getHeapMemorySizeWithoutChildren() const; - private: - const MEDFileUMeshSplitL1 *_st; - mutable std::size_t _mpt_time; - mutable std::size_t _num_time; - mutable MEDCouplingAutoRefCountObjectPtr _m; - }; - - class MEDFileUMeshAggregateCompute : public BigMemoryObject - { - public: - MEDFileUMeshAggregateCompute(); - void setName(const std::string& name); - void assignParts(const std::vector< const MEDCoupling1GTUMesh * >& mParts); - void assignDefParts(const std::vector& partDefs); - void assignUMesh(MEDCouplingUMesh *m); - MEDCouplingUMesh *getUmesh() const; - int getNumberOfCells() const; - std::vector getParts() const; - std::vector getGeoTypes() const; - std::vector retrievePartsWithoutComputation() const; - MEDCoupling1GTUMesh *retrievePartWithoutComputation(INTERP_KERNEL::NormalizedCellType gt) const; - void getStartStopOfGeoTypeWithoutComputation(INTERP_KERNEL::NormalizedCellType gt, int& start, int& stop) const; - void renumberNodesInConnWithoutComputation(const int *newNodeNumbersO2N); - bool isStoredSplitByType() const; - std::size_t getTimeOfThis() const; - std::size_t getHeapMemorySizeWithoutChildren() const; - std::vector getDirectChildrenWithNull() const; - MEDFileUMeshAggregateCompute deepCpy(DataArrayDouble *coords) const; - bool isEqual(const MEDFileUMeshAggregateCompute& other, double eps, std::string& what) const; - void clearNonDiscrAttributes() const; - void synchronizeTinyInfo(const MEDFileMesh& master) const; - bool empty() const; - int getMeshDimension() const; - std::vector getDistributionOfTypes() const; - int getSize() const; - void setCoords(DataArrayDouble *coords); - void forceComputationOfPartsFromUMesh() const; - const PartDefinition *getPartDefOfWithoutComputation(INTERP_KERNEL::NormalizedCellType gt) const; - void serialize(std::vector& tinyInt, std::vector< MEDCouplingAutoRefCountObjectPtr >& bigArraysI) const; - void unserialize(const std::string& name, DataArrayDouble *coo, std::vector& tinyInt, std::vector< MEDCouplingAutoRefCountObjectPtr >& bigArraysI); - private: - std::size_t getTimeOfParts() const; - std::size_t getTimeOfUMesh() const; - private: - mutable std::vector< MEDCouplingAutoRefCountObjectPtr > _m_parts; - mutable std::size_t _mp_time; - mutable std::size_t _m_time; - mutable MEDCouplingAutoRefCountObjectPtr _m; - mutable std::vector< MEDCouplingAutoRefCountObjectPtr > _part_def; - }; - - class MEDFileUMeshSplitL1 : public RefCountObject - { - friend class MEDFileUMeshPermCompute; - public: - MEDFileUMeshSplitL1(const MEDFileUMeshSplitL1& other); - MEDFileUMeshSplitL1(const MEDFileUMeshL2& l2, const std::string& mName, int id); - MEDFileUMeshSplitL1(MEDCoupling1GTUMesh *m); - MEDFileUMeshSplitL1(MEDCouplingUMesh *m); - MEDFileUMeshSplitL1(MEDCouplingUMesh *m, bool newOrOld); - void setName(const std::string& name); - std::size_t getHeapMemorySizeWithoutChildren() const; - std::vector getDirectChildrenWithNull() const; - MEDFileUMeshSplitL1 *deepCpy(DataArrayDouble *coords) const; - void setCoords(DataArrayDouble *coords); - bool isEqual(const MEDFileUMeshSplitL1 *other, double eps, std::string& what) const; - void clearNonDiscrAttributes() const; - void synchronizeTinyInfo(const MEDFileMesh& master) const; - void assignMesh(MEDCouplingUMesh *m, bool newOrOld); - void assignParts(const std::vector< const MEDCoupling1GTUMesh * >& mParts); - void forceComputationOfParts() const; - bool empty() const; - bool presenceOfOneFams(const std::vector& ids) const; - int getMeshDimension() const; - void simpleRepr(std::ostream& oss) const; - int getSize() const; - MEDCouplingUMesh *getFamilyPart(const int *idsBg, const int *idsEnd, bool renum) const; - DataArrayInt *getFamilyPartArr(const int *idsBg, const int *idsEnd, bool renum) const; - MEDCouplingUMesh *getWholeMesh(bool renum) const; - int getNumberOfCells() const; - bool isMeshStoredSplitByType() const { return _m_by_types.isStoredSplitByType(); } - std::vector getGeoTypes() const; - std::vector getDirectUndergroundSingleGeoTypeMeshes() const { return _m_by_types.retrievePartsWithoutComputation(); } - MEDCoupling1GTUMesh *getDirectUndergroundSingleGeoTypeMesh(INTERP_KERNEL::NormalizedCellType gt) const { return _m_by_types.retrievePartWithoutComputation(gt); } - DataArrayInt *extractFamilyFieldOnGeoType(INTERP_KERNEL::NormalizedCellType gt) const; - DataArrayInt *extractNumberFieldOnGeoType(INTERP_KERNEL::NormalizedCellType gt) const; - std::vector getDistributionOfTypes() const { return _m_by_types.getDistributionOfTypes(); } - DataArrayInt *getOrCreateAndGetFamilyField(); - const DataArrayInt *getFamilyField() const; - const DataArrayInt *getNumberField() const; - const DataArrayAsciiChar *getNameField() const; - const DataArrayInt *getRevNumberField() const; - const PartDefinition *getPartDef(INTERP_KERNEL::NormalizedCellType gt) const; - void eraseFamilyField(); - void setGroupsFromScratch(const std::vector& ms, std::map& familyIds, - std::map >& groups); - void write(med_idt fid, const std::string& mName, int mdim) const; - // - void setFamilyArr(DataArrayInt *famArr); - DataArrayInt *getFamilyField(); - void setRenumArr(DataArrayInt *renumArr); - void setNameArr(DataArrayAsciiChar *nameArr); - void changeFamilyIdArr(int oldId, int newId); - // - void renumberNodesInConn(const int *newNodeNumbersO2N); - // - void serialize(std::vector& tinyInt, std::vector< MEDCouplingAutoRefCountObjectPtr >& bigArraysI) const; - void unserialize(const std::string& name, DataArrayDouble *coo, std::vector& tinyInt, std::vector< MEDCouplingAutoRefCountObjectPtr >& bigArraysI); - // - static void ClearNonDiscrAttributes(const MEDCouplingMesh *tmp); - static std::vector GetNewFamiliesNumber(int nb, const std::map& families); - static void TraduceFamilyNumber(const std::vector< std::vector >& fidsGrps, std::map& familyIds, - std::map& famIdTrad, std::map& newfams); - static DataArrayInt *Renumber(const DataArrayInt *renum, const DataArrayInt *da); - static MEDCouplingUMesh *Renumber2(const DataArrayInt *renum, MEDCouplingUMesh *m, const int *cellIds); - static MEDFileUMeshSplitL1 *Unserialize(const std::string& name, DataArrayDouble *coo, std::vector& tinyInt, std::vector< MEDCouplingAutoRefCountObjectPtr >& bigArraysI); - private: - MEDFileUMeshSplitL1(); - void assignCommonPart(); - MEDCouplingUMesh *renumIfNeeded(MEDCouplingUMesh *m, const int *cellIds) const; - DataArrayInt *renumIfNeededArr(const DataArrayInt *da) const; - void computeRevNum() const; - private: - MEDFileUMeshAggregateCompute _m_by_types; - MEDCouplingAutoRefCountObjectPtr _fam; - MEDCouplingAutoRefCountObjectPtr _num; - MEDCouplingAutoRefCountObjectPtr _names; - mutable MEDCouplingAutoRefCountObjectPtr _rev_num; - MEDFileUMeshPermCompute _m; - }; -} - -#endif diff --git a/src/MEDLoader/MEDFileMeshReadSelector.cxx b/src/MEDLoader/MEDFileMeshReadSelector.cxx deleted file mode 100644 index e7ac589b0..000000000 --- a/src/MEDLoader/MEDFileMeshReadSelector.cxx +++ /dev/null @@ -1,145 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 -// 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 "MEDFileMeshReadSelector.hxx" - -using namespace ParaMEDMEM; - -MEDFileMeshReadSelector::MEDFileMeshReadSelector():_code(0xFFFFFFFF) -{ -} - -MEDFileMeshReadSelector::MEDFileMeshReadSelector(unsigned int code):_code(code) -{ -} - -unsigned int MEDFileMeshReadSelector::getCode() const -{ - return _code; -} - -void MEDFileMeshReadSelector::setCode(unsigned int newCode) -{ - _code=newCode; -} - -bool MEDFileMeshReadSelector::isCellFamilyFieldReading() const -{ - return _code & 0x00000001; -} - -bool MEDFileMeshReadSelector::isNodeFamilyFieldReading() const -{ - return _code & 0x00000002; -} - -bool MEDFileMeshReadSelector::isCellNameFieldReading() const -{ - return _code & 0x00000004; -} - -bool MEDFileMeshReadSelector::isNodeNameFieldReading() const -{ - return _code & 0x00000008; -} - -bool MEDFileMeshReadSelector::isCellNumFieldReading() const -{ - return _code & 0x00000010; -} - -bool MEDFileMeshReadSelector::isNodeNumFieldReading() const -{ - return _code & 0x00000020; -} - -void MEDFileMeshReadSelector::setCellFamilyFieldReading(bool b) -{ - unsigned int code(_code & 0xFFFFFFFE); - unsigned int b2=b?1:0; - //b2<<=0; - code+=b2; - _code=code; -} - -void MEDFileMeshReadSelector::setNodeFamilyFieldReading(bool b) -{ - unsigned int code(_code & 0xFFFFFFFD); - unsigned int b2=b?1:0; - b2<<=1; - code+=b2; - _code=code; -} - -void MEDFileMeshReadSelector::setCellNameFieldReading(bool b) -{ - unsigned int code(_code & 0xFFFFFFFB); - unsigned int b2=b?1:0; - b2<<=2; - code+=b2; - _code=code; -} - -void MEDFileMeshReadSelector::setNodeNameFieldReading(bool b) -{ - unsigned int code(_code & 0xFFFFFFF7); - unsigned int b2=b?1:0; - b2<<=3; - code+=b2; - _code=code; -} - -void MEDFileMeshReadSelector::setCellNumFieldReading(bool b) -{ - unsigned int code(_code & 0xFFFFFFEF); - unsigned int b2=b?1:0; - b2<<=4; - code+=b2; - _code=code; -} - -void MEDFileMeshReadSelector::setNodeNumFieldReading(bool b) -{ - unsigned int code(_code & 0xFFFFFFDF); - unsigned int b2=b?1:0; - b2<<=5; - code+=b2; - _code=code; -} - -void MEDFileMeshReadSelector::reprAll(std::ostream& str) const -{ - str << "MEDFileMeshReadSelector (code=" << _code << ") : \n"; - str << "Read family field on cells : " << ReprStatus(isCellFamilyFieldReading()) << std::endl; - str << "Read family field on nodes : " << ReprStatus(isNodeFamilyFieldReading()) << std::endl; - str << "Read name field on cells : " << ReprStatus(isCellNameFieldReading()) << std::endl; - str << "Read name field on nodes : " << ReprStatus(isNodeNameFieldReading()) << std::endl; - str << "Read number field on cells : " << ReprStatus(isCellNumFieldReading()) << std::endl; - str << "Read number field name on nodes : " << ReprStatus(isNodeNumFieldReading()); -} - -std::string MEDFileMeshReadSelector::ReprStatus(bool v) -{ - if(v) - return std::string("ON"); - else - return std::string("OFF"); -} - diff --git a/src/MEDLoader/MEDFileMeshReadSelector.hxx b/src/MEDLoader/MEDFileMeshReadSelector.hxx deleted file mode 100644 index 2a90b7dc0..000000000 --- a/src/MEDLoader/MEDFileMeshReadSelector.hxx +++ /dev/null @@ -1,64 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 -// 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 __MEDFILEMESHREADSELECTOR_HXX__ -#define __MEDFILEMESHREADSELECTOR_HXX__ - -#include "MEDLoaderDefines.hxx" - -#include -#include - -namespace ParaMEDMEM -{ - class MEDLOADER_EXPORT MEDFileMeshReadSelector - { - public: - MEDFileMeshReadSelector(); - MEDFileMeshReadSelector(unsigned int code); - unsigned int getCode() const; - void setCode(unsigned int newCode); - bool isCellFamilyFieldReading() const; - bool isNodeFamilyFieldReading() const; - bool isCellNameFieldReading() const; - bool isNodeNameFieldReading() const; - bool isCellNumFieldReading() const; - bool isNodeNumFieldReading() const; - void setCellFamilyFieldReading(bool b); - void setNodeFamilyFieldReading(bool b); - void setCellNameFieldReading(bool b); - void setNodeNameFieldReading(bool b); - void setCellNumFieldReading(bool b); - void setNodeNumFieldReading(bool b); - void reprAll(std::ostream& str) const; - private: - static std::string ReprStatus(bool v); - private: - //bit #0 cell family field - //bit #1 node family field - //bit #2 cell name field - //bit #3 node name field - //bit #4 cell num field - //bit #5 node num field - unsigned int _code; - }; -} - -#endif diff --git a/src/MEDLoader/MEDFileParameter.cxx b/src/MEDLoader/MEDFileParameter.cxx deleted file mode 100644 index d6aa3c46b..000000000 --- a/src/MEDLoader/MEDFileParameter.cxx +++ /dev/null @@ -1,920 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 -// 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 "MEDFileParameter.hxx" -#include "MEDFileUtilities.hxx" -#include "MEDFileSafeCaller.txx" -#include "MEDLoaderBase.hxx" - -#include "InterpKernelAutoPtr.hxx" - -#include - -using namespace ParaMEDMEM; - -MEDFileParameter1TS::MEDFileParameter1TS(int iteration, int order, double time):_iteration(iteration),_order(order),_time(time) -{ -} - -MEDFileParameter1TS::MEDFileParameter1TS():_iteration(-1),_order(-1),_time(0.) -{ -} - -bool MEDFileParameter1TS::isEqual(const MEDFileParameter1TS *other, double eps, std::string& what) const -{ - std::ostringstream oss; - if(!other) - { what="Other is null"; return false; } - if(_iteration!=other->_iteration) - { oss << "iteration number mismatches " << _iteration << " != " << other->_iteration; what=oss.str(); return false; } - if(_order!=other->_order) - { oss << "order number mismatches " << _iteration << " != " << other->_iteration; what=oss.str(); return false; } - if(fabs(_time-other->_time)>eps) - { oss << "time mismatches " << _time << " != " << other->_time << " eps=" << eps; what=oss.str(); return false; } - return true; -} - -MEDFileParameter1TS *MEDFileParameterDouble1TSWTI::deepCpy() const -{ - return new MEDFileParameterDouble1TSWTI(*this); -} - -bool MEDFileParameterDouble1TSWTI::isEqual(const MEDFileParameter1TS *other, double eps, std::string& what) const -{ - if(!MEDFileParameter1TS::isEqual(other,eps,what)) - return false; - const MEDFileParameterDouble1TSWTI *otherC=dynamic_cast(other); - if(!otherC) - { what="IsEqual fails because this is double parameter other no !"; return false; } - if(fabs(_arr-otherC->_arr)>eps) - { std::ostringstream oss; oss << "value differ " << _arr << " != " << otherC->_arr << " (eps=" << eps << ")"; return false; } - return true; -} - -std::size_t MEDFileParameterDouble1TSWTI::getHeapMemorySizeWithoutChildren() const -{ - return sizeof(MEDFileParameterDouble1TSWTI); -} - -std::vector MEDFileParameterDouble1TSWTI::getDirectChildrenWithNull() const -{ - return std::vector(); -} - -std::string MEDFileParameterDouble1TSWTI::simpleRepr() const -{ - std::ostringstream oss; - simpleRepr2(0,oss); - return oss.str(); -} - -void MEDFileParameterDouble1TSWTI::simpleRepr2(int bkOffset, std::ostream& oss) const -{ - std::string startOfLine(bkOffset,' '); - oss << startOfLine << "ParameterDoubleItem with (iteration,order) = (" << _iteration << "," << _order << ")" << std::endl; - oss << startOfLine << "Time associacited = " << _time << std::endl; - oss << startOfLine << "The value is ***** " << _arr << " *****" << std::endl; -} - -MEDFileParameterDouble1TSWTI *MEDFileParameterDouble1TSWTI::New(int iteration, int order, double time) -{ - return new MEDFileParameterDouble1TSWTI(iteration,order,time); -} - -MEDFileParameterDouble1TSWTI::MEDFileParameterDouble1TSWTI():_arr(std::numeric_limits::max()) -{ -} - -MEDFileParameterDouble1TSWTI::MEDFileParameterDouble1TSWTI(int iteration, int order, double time):MEDFileParameter1TS(iteration,order,time) -{ -} - -void MEDFileParameterDouble1TSWTI::finishLoading(med_idt fid, const std::string& name, int dt, int it, int nbOfSteps) -{ - std::ostringstream oss; oss << "MEDFileParameterDouble1TS::finishLoading : no specified time step (" << dt << "," << it << ") ! Time steps available : "; - for(int i=0;i(&_arr))); - return ; - } - else - { - oss << "(" << locDt << "," << locIt << ")"; - if(i!=nbOfSteps-1) - oss << ", "; - } - } - throw INTERP_KERNEL::Exception(oss.str().c_str()); -} - -void MEDFileParameterDouble1TSWTI::readValue(med_idt fid, const std::string& name) -{ - MEDFILESAFECALLERRD0(MEDparameterValueRd,(fid,name.c_str(),_iteration,_order,reinterpret_cast(&_arr))); -} - -void MEDFileParameterDouble1TSWTI::finishLoading(med_idt fid, const std::string& name, int timeStepId) -{ - int locDt,locIt; - double dt; - MEDFILESAFECALLERRD0(MEDparameterComputationStepInfo,(fid,name.c_str(),timeStepId+1,&locDt,&locIt,&dt)); - _iteration=locDt; _order=locIt; _time=dt; - MEDFILESAFECALLERRD0(MEDparameterValueRd,(fid,name.c_str(),_iteration,_order,reinterpret_cast(&_arr))); -} - -void MEDFileParameterDouble1TSWTI::writeLL(med_idt fid, const std::string& name, const MEDFileWritable& mw) const -{ - char nameW[MED_NAME_SIZE+1]; - MEDLoaderBase::safeStrCpy(name.c_str(),MED_NAME_SIZE,nameW,mw.getTooLongStrPolicy()); - MEDFILESAFECALLERWR0(MEDparameterValueWr,(fid,nameW,_iteration,_order,_time,reinterpret_cast(&_arr))); -} - -std::size_t MEDFileParameterTinyInfo::getHeapMemSizeOfStrings() const -{ - return _dt_unit.capacity()+_name.capacity()+_desc_name.capacity(); -} - -bool MEDFileParameterTinyInfo::isEqualStrings(const MEDFileParameterTinyInfo& other, std::string& what) const -{ - std::ostringstream oss; - if(_name!=other._name) - { oss << "name differ ! this=" << _name << " and other=" << other._name; what=oss.str(); return false; } - if(_desc_name!=other._desc_name) - { oss << "name differ ! this=" << _desc_name << " and other=" << other._desc_name; what=oss.str(); return false; } - if(_dt_unit!=other._dt_unit) - { oss << "unit of time differ ! this=" << _dt_unit << " and other=" << other._dt_unit; what=oss.str(); return false; } - return true; -} - -void MEDFileParameterTinyInfo::writeLLHeader(med_idt fid, med_parameter_type typ) const -{ - char nameW[MED_NAME_SIZE+1],descW[MED_COMMENT_SIZE+1],dtunitW[MED_SNAME_SIZE+1]; - MEDLoaderBase::safeStrCpy(_name.c_str(),MED_NAME_SIZE,nameW,getTooLongStrPolicy()); - MEDLoaderBase::safeStrCpy(_desc_name.c_str(),MED_COMMENT_SIZE,descW,getTooLongStrPolicy()); - MEDLoaderBase::safeStrCpy(_dt_unit.c_str(),MED_SNAME_SIZE,dtunitW,getTooLongStrPolicy()); - MEDFILESAFECALLERWR0(MEDparameterCr,(fid,nameW,typ,descW,dtunitW)); -} - -void MEDFileParameterTinyInfo::mainRepr(int bkOffset, std::ostream& oss) const -{ - std::string startOfLine(bkOffset,' '); - oss << startOfLine << "Parameter with name \"" << _name << "\"" << std::endl; - oss << startOfLine << "Parameter with description \"" << _desc_name << "\"" << std::endl; - oss << startOfLine << "Parameter with unit name \"" << _dt_unit << "\"" << std::endl; -} - -MEDFileParameterDouble1TS *MEDFileParameterDouble1TS::New() -{ - return new MEDFileParameterDouble1TS; -} - -MEDFileParameterDouble1TS *MEDFileParameterDouble1TS::New(const std::string& fileName) -{ - return new MEDFileParameterDouble1TS(fileName); -} - -MEDFileParameterDouble1TS *MEDFileParameterDouble1TS::New(const std::string& fileName, const std::string& paramName) -{ - return new MEDFileParameterDouble1TS(fileName,paramName); -} - -MEDFileParameterDouble1TS *MEDFileParameterDouble1TS::New(const std::string& fileName, const std::string& paramName, int dt, int it) -{ - return new MEDFileParameterDouble1TS(fileName,paramName,dt,it); -} - -MEDFileParameterDouble1TS::MEDFileParameterDouble1TS() -{ -} - -MEDFileParameterDouble1TS::MEDFileParameterDouble1TS(const std::string& fileName, const std::string& paramName, int dt, int it) -{ - MEDFileUtilities::CheckFileForRead(fileName); - MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName.c_str(),MED_ACC_RDONLY); - int nbPar=MEDnParameter(fid); - std::ostringstream oss; oss << "MEDFileParameterDouble1TS : no double param name \"" << paramName << "\" ! Double Parameters available are : "; - INTERP_KERNEL::AutoPtr pName=MEDLoaderBase::buildEmptyString(MED_NAME_SIZE); - INTERP_KERNEL::AutoPtr descName=MEDLoaderBase::buildEmptyString(MED_COMMENT_SIZE); - INTERP_KERNEL::AutoPtr unitName=MEDLoaderBase::buildEmptyString(MED_SNAME_SIZE); - med_parameter_type paramType; - for(int i=0;i pName=MEDLoaderBase::buildEmptyString(MED_NAME_SIZE); - INTERP_KERNEL::AutoPtr descName=MEDLoaderBase::buildEmptyString(MED_COMMENT_SIZE); - INTERP_KERNEL::AutoPtr unitName=MEDLoaderBase::buildEmptyString(MED_SNAME_SIZE); - med_parameter_type paramType; - for(int i=0;i0) - { - _dt_unit=MEDLoaderBase::buildStringFromFortran(unitName,MED_SNAME_SIZE); - _name=paramNameCpp; - _desc_name=MEDLoaderBase::buildStringFromFortran(descName,MED_COMMENT_SIZE); - finishLoading(fid,_name,0); - return ; - } - else - { - std::ostringstream oss2; oss2 << "Param name \"" << paramName << "\" exists but no time steps on it !"; - throw INTERP_KERNEL::Exception(oss2.str().c_str()); - } - } - else - { - oss << paramNameCpp; - if(i!=nbPar-1) oss << ", "; - } - } - throw INTERP_KERNEL::Exception(oss.str().c_str()); -} - -MEDFileParameterDouble1TS::MEDFileParameterDouble1TS(const std::string& fileName) -{ - MEDFileUtilities::CheckFileForRead(fileName); - MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName.c_str(),MED_ACC_RDONLY); - int nbPar=MEDnParameter(fid); - if(nbPar<1) - { - std::ostringstream oss2; oss2 << "No parameter in file \"" << fileName << "\" !"; - throw INTERP_KERNEL::Exception(oss2.str().c_str()); - } - INTERP_KERNEL::AutoPtr pName=MEDLoaderBase::buildEmptyString(MED_NAME_SIZE); - INTERP_KERNEL::AutoPtr descName=MEDLoaderBase::buildEmptyString(MED_COMMENT_SIZE); - INTERP_KERNEL::AutoPtr unitName=MEDLoaderBase::buildEmptyString(MED_SNAME_SIZE); - med_parameter_type paramType; - int nbOfSteps; - MEDFILESAFECALLERRD0(MEDparameterInfo,(fid,1,pName,¶mType,descName,unitName,&nbOfSteps)); - std::string paramNameCpp=MEDLoaderBase::buildStringFromFortran(pName,MED_NAME_SIZE); - if(paramType==MED_FLOAT64) - { - if(nbOfSteps>0) - { - _dt_unit=MEDLoaderBase::buildStringFromFortran(unitName,MED_SNAME_SIZE); - _name=paramNameCpp; - _desc_name=MEDLoaderBase::buildStringFromFortran(descName,MED_COMMENT_SIZE); - finishLoading(fid,_name,0); - return ; - } - else - { - std::ostringstream oss2; oss2 << "Double param name \"" << paramNameCpp << "\" exists in file \""<< fileName << "\"but no time steps on it !"; - throw INTERP_KERNEL::Exception(oss2.str().c_str()); - } - } - else - { - std::ostringstream oss2; oss2 << "First parameter in file \"" << fileName << "\" is not double !"; - throw INTERP_KERNEL::Exception(oss2.str().c_str()); - } -} - -bool MEDFileParameterDouble1TS::isEqual(const MEDFileParameter1TS *other, double eps, std::string& what) const -{ - if(!MEDFileParameterDouble1TSWTI::isEqual(other,eps,what)) - return false; - const MEDFileParameterDouble1TS *otherC=dynamic_cast(other); - if(!otherC) - { what="Other is not of type MEDFileParameterDouble1TS as this"; return false; } - if(!isEqualStrings(*otherC,what)) - return false; - return true; -} - -MEDFileParameter1TS *MEDFileParameterDouble1TS::deepCpy() const -{ - return new MEDFileParameterDouble1TS(*this); -} - -std::string MEDFileParameterDouble1TS::simpleRepr() const -{ - std::ostringstream oss; - MEDFileParameterTinyInfo::mainRepr(0,oss); - MEDFileParameterDouble1TSWTI::simpleRepr2(0,oss); - return oss.str(); -} - -std::size_t MEDFileParameterDouble1TS::getHeapMemorySizeWithoutChildren() const -{ - return getHeapMemSizeOfStrings()+sizeof(MEDFileParameterDouble1TS); -} - -std::vector MEDFileParameterDouble1TS::getDirectChildrenWithNull() const -{ - return std::vector(); -} - -void MEDFileParameterDouble1TS::write(const std::string& fileName, int mode) const -{ - med_access_mode medmod=MEDFileUtilities::TraduceWriteMode(mode); - MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName.c_str(),medmod); - MEDFileParameterTinyInfo::writeLLHeader(fid,MED_FLOAT64); - MEDFileParameterDouble1TSWTI::writeLL(fid,_name,*this); -} - -MEDFileParameterMultiTS *MEDFileParameterMultiTS::New() -{ - return new MEDFileParameterMultiTS; -} - -MEDFileParameterMultiTS *MEDFileParameterMultiTS::New(const std::string& fileName) -{ - return new MEDFileParameterMultiTS(fileName); -} - -MEDFileParameterMultiTS *MEDFileParameterMultiTS::New(const std::string& fileName, const std::string& paramName) -{ - return new MEDFileParameterMultiTS(fileName,paramName); -} - -MEDFileParameterMultiTS::MEDFileParameterMultiTS() -{ -} - -MEDFileParameterMultiTS::MEDFileParameterMultiTS(const MEDFileParameterMultiTS& other, bool deepCopy):MEDFileParameterTinyInfo(other),_param_per_ts(other._param_per_ts) -{ - if(deepCopy) - for(std::size_t i=0;i<_param_per_ts.size();i++) - { - const MEDFileParameter1TS *elt=_param_per_ts[i]; - if(elt) - _param_per_ts[i]=elt->deepCpy(); - } -} - -MEDFileParameterMultiTS::MEDFileParameterMultiTS(const std::string& fileName) -{ - MEDFileUtilities::CheckFileForRead(fileName); - MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName.c_str(),MED_ACC_RDONLY); - int nbPar=MEDnParameter(fid); - if(nbPar<1) - { - std::ostringstream oss; oss << "MEDFileParameterMultiTS : no parameter in file \"" << fileName << "\" !" ; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - INTERP_KERNEL::AutoPtr pName=MEDLoaderBase::buildEmptyString(MED_NAME_SIZE); - INTERP_KERNEL::AutoPtr descName=MEDLoaderBase::buildEmptyString(MED_COMMENT_SIZE); - INTERP_KERNEL::AutoPtr unitName=MEDLoaderBase::buildEmptyString(MED_SNAME_SIZE); - med_parameter_type paramType; - int nbOfSteps; - MEDFILESAFECALLERRD0(MEDparameterInfo,(fid,1,pName,¶mType,descName,unitName,&nbOfSteps)); - std::string paramNameCpp=MEDLoaderBase::buildStringFromFortran(pName,MED_NAME_SIZE); - _dt_unit=MEDLoaderBase::buildStringFromFortran(unitName,MED_SNAME_SIZE); - _name=paramNameCpp; - _desc_name=MEDLoaderBase::buildStringFromFortran(descName,MED_COMMENT_SIZE); - finishLoading(fid,paramType,nbOfSteps); -} - -MEDFileParameterMultiTS::MEDFileParameterMultiTS(const std::string& fileName, const std::string& paramName) -{ - MEDFileUtilities::CheckFileForRead(fileName); - MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName.c_str(),MED_ACC_RDONLY); - int nbPar=MEDnParameter(fid); - std::ostringstream oss; oss << "MEDFileParameterDouble1TS : no double param name \"" << paramName << "\" ! Double Parameters available are : "; - INTERP_KERNEL::AutoPtr pName=MEDLoaderBase::buildEmptyString(MED_NAME_SIZE); - INTERP_KERNEL::AutoPtr descName=MEDLoaderBase::buildEmptyString(MED_COMMENT_SIZE); - INTERP_KERNEL::AutoPtr unitName=MEDLoaderBase::buildEmptyString(MED_SNAME_SIZE); - med_parameter_type paramType; - for(int i=0;i0) - { - _dt_unit=MEDLoaderBase::buildStringFromFortran(unitName,MED_SNAME_SIZE); - _name=paramNameCpp; - _desc_name=MEDLoaderBase::buildStringFromFortran(descName,MED_COMMENT_SIZE); - finishLoading(fid,paramType,nbOfSteps); - return ; - } - else - { - std::ostringstream oss2; oss2 << "Param name \"" << paramName << "\" exists but no time steps on it !"; - throw INTERP_KERNEL::Exception(oss2.str().c_str()); - } - } - else - { - oss << paramNameCpp; - if(i!=nbPar-1) oss << ", "; - } - } - throw INTERP_KERNEL::Exception(oss.str().c_str()); -} - -void MEDFileParameterMultiTS::finishLoading(med_idt fid, med_parameter_type typ, int nbOfSteps) -{ - _param_per_ts.resize(nbOfSteps); - for(int i=0;ireadValue(fid,_name.c_str()); - break; - /*case MED_INT32; - _param_per_ts[i]=; - break;*/ - default: - throw INTERP_KERNEL::Exception("MEDFileParameterMultiTS::finishLoading : supporting only FLOAT64 !"); - } - } -} - -std::size_t MEDFileParameterMultiTS::getHeapMemorySizeWithoutChildren() const -{ - std::size_t ret(sizeof(MEDFileParameterMultiTS)); - ret+=sizeof(MEDCouplingAutoRefCountObjectPtr)*_param_per_ts.capacity(); - return ret; -} - -std::vector MEDFileParameterMultiTS::getDirectChildrenWithNull() const -{ - std::vector ret; - for(std::vector< MEDCouplingAutoRefCountObjectPtr >::const_iterator it=_param_per_ts.begin();it!=_param_per_ts.end();it++) - ret.push_back((const MEDFileParameter1TS *)*it); - return ret; -} - -MEDFileParameterMultiTS *MEDFileParameterMultiTS::deepCpy() const -{ - return new MEDFileParameterMultiTS(*this,true); -} - -bool MEDFileParameterMultiTS::isEqual(const MEDFileParameterMultiTS *other, double eps, std::string& what) const -{ - if(!other) - { what="other is null !"; return false; } - if(_param_per_ts.size()!=other->_param_per_ts.size()) - { what="number of time steps differs !"; return false; } - std::ostringstream oss; - for(std::size_t i=0;i<_param_per_ts.size();i++) - { - const MEDFileParameter1TS *a(_param_per_ts[i]),*b(other->_param_per_ts[i]); - if((a && !b) || (!a && b)) - { oss << "At time step id #" << i << " pointer is defined on one side not in the other !"; what=oss.str(); return false; } - if(a) - if(!a->isEqual(b,eps,what)) - { oss << " At time step id #" << i << " non equality !"; what+=oss.str(); return false; } - } - return true; -} - -void MEDFileParameterMultiTS::write(const std::string& fileName, int mode) const -{ - med_access_mode medmod=MEDFileUtilities::TraduceWriteMode(mode); - MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName.c_str(),medmod); - writeLL(fid,*this); -} - -void MEDFileParameterMultiTS::writeLL(med_idt fid, const MEDFileWritable& mw) const -{ - std::set diffType; - for(std::vector< MEDCouplingAutoRefCountObjectPtr >::const_iterator it=_param_per_ts.begin();it!=_param_per_ts.end();it++) - { - const MEDFileParameter1TS *elt(*it); - if(dynamic_cast(elt)) - diffType.insert(MED_FLOAT64); - } - if(diffType.size()>1) - throw INTERP_KERNEL::Exception("MEDFileParameterMultiTS::writeLL : impossible to mix type of data in parameters in MED file ! Only float64 or only int32 ..."); - if(diffType.empty()) - return; - med_parameter_type typ=*diffType.begin(); - MEDFileParameterTinyInfo::writeLLHeader(fid,typ); - for(std::vector< MEDCouplingAutoRefCountObjectPtr >::const_iterator it=_param_per_ts.begin();it!=_param_per_ts.end();it++) - { - const MEDFileParameter1TS *elt(*it); - if(elt) - elt->writeLL(fid,_name,mw); - } -} - -std::string MEDFileParameterMultiTS::simpleRepr() const -{ - std::ostringstream oss; - simpleRepr2(0,oss); - return oss.str(); -} - -void MEDFileParameterMultiTS::simpleRepr2(int bkOffset, std::ostream& oss) const -{ - MEDFileParameterTinyInfo::mainRepr(bkOffset,oss); - for(std::vector< MEDCouplingAutoRefCountObjectPtr >::const_iterator it=_param_per_ts.begin();it!=_param_per_ts.end();it++) - { - const MEDFileParameter1TS *elt(*it); - if(elt) - elt->simpleRepr2(bkOffset+2,oss); - } -} - -void MEDFileParameterMultiTS::appendValue(int dt, int it, double time, double val) -{ - MEDCouplingAutoRefCountObjectPtr elt=MEDFileParameterDouble1TSWTI::New(dt,it,time); - elt->setValue(val); - MEDCouplingAutoRefCountObjectPtr elt2((MEDFileParameterDouble1TSWTI*)elt); elt2->incrRef(); - _param_per_ts.push_back(elt2); -} - -double MEDFileParameterMultiTS::getDoubleValue(int iteration, int order) const -{ - int pos=getPosOfTimeStep(iteration,order); - const MEDFileParameter1TS *elt=_param_per_ts[pos]; - if(!elt) - { - std::ostringstream oss; oss << "MEDFileParameterMultiTS::getDoubleValue : time iteration it=" << iteration << " order=" << order; - oss << " exists but elt is empty !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - const MEDFileParameterDouble1TSWTI *eltC=dynamic_cast(elt); - if(!eltC) - { - std::ostringstream oss; oss << "MEDFileParameterMultiTS::getDoubleValue : time iteration it=" << iteration << " order=" << order; - oss << " exists but not double !"; - } - return eltC->getValue(); -} - -int MEDFileParameterMultiTS::getPosOfTimeStep(int iteration, int order) const -{ - int ret=0; - std::ostringstream oss; oss << "MEDFileParameterMultiTS::getPosOfTimeStep : no such iteration=" << iteration << " order=" << order << " ! Possibilities are :"; - for(std::vector< MEDCouplingAutoRefCountObjectPtr >::const_iterator it=_param_per_ts.begin();it!=_param_per_ts.end();it++,ret++) - { - const MEDFileParameter1TS *elt(*it); - if(elt) - { - if(elt->getIteration()==iteration && elt->getOrder()==order) - return ret; - else - oss << "(" << elt->getIteration() << "," << elt->getOrder() << "), "; - } - } - throw INTERP_KERNEL::Exception(oss.str().c_str()); -} - -int MEDFileParameterMultiTS::getPosGivenTime(double time, double eps) const -{ - int ret=0; - std::ostringstream oss; oss << "MEDFileParameterMultiTS::getPosGivenTime : no such time=" << time << " ! Possibilities are :"; - for(std::vector< MEDCouplingAutoRefCountObjectPtr >::const_iterator it=_param_per_ts.begin();it!=_param_per_ts.end();it++,ret++) - { - const MEDFileParameter1TS *elt(*it); - if(elt) - { - if(fabs(elt->getTimeValue()-time)<=eps) - return ret; - else - oss << elt->getTimeValue() << ", "; - } - } - throw INTERP_KERNEL::Exception(oss.str().c_str()); -} - -/*! - * \return an internal pointer that can be null. Warning the caller is \b not responsible of the returned pointer. - */ -MEDFileParameter1TS *MEDFileParameterMultiTS::getTimeStepAtPos(int posId) const -{ - if(posId<0 || posId>=(int)_param_per_ts.size()) - { - std::ostringstream oss; oss << "MEDFileParameterMultiTS::getTimeStepAtPos : invalid pos ! Should be in [0," << _param_per_ts.size() << ") !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - return const_cast(static_cast(_param_per_ts[posId])); -} - -void MEDFileParameterMultiTS::eraseTimeStepIds(const int *startIds, const int *endIds) -{ - std::vector b(_param_per_ts.size(),true); - int len=(int)_param_per_ts.size(); - for(const int *w=startIds;w!=endIds;w++) - if(*w>=0 && *w > paramPerTs(newNb); - std::size_t j=0; - for(std::size_t i=0;i<_param_per_ts.size();i++) - if(b[i]) - paramPerTs[j++]=_param_per_ts[i]; - _param_per_ts=paramPerTs; -} - -int MEDFileParameterMultiTS::getNumberOfTS() const -{ - return (int) getIterations().size(); -} - -std::vector< std::pair > MEDFileParameterMultiTS::getIterations() const -{ - std::vector< std::pair > ret; - for(std::vector< MEDCouplingAutoRefCountObjectPtr >::const_iterator it=_param_per_ts.begin();it!=_param_per_ts.end();it++) - { - const MEDFileParameter1TS *elt(*it); - if(elt) - ret.push_back(std::pair(elt->getIteration(),elt->getOrder())); - } - return ret; -} - -/*! - * \param [out] ret1 - */ -std::vector< std::pair > MEDFileParameterMultiTS::getTimeSteps(std::vector& ret1) const -{ - std::vector< std::pair > ret0; - ret1.clear(); - for(std::vector< MEDCouplingAutoRefCountObjectPtr >::const_iterator it=_param_per_ts.begin();it!=_param_per_ts.end();it++) - { - const MEDFileParameter1TS *elt(*it); - if(elt) - { - ret0.push_back(std::pair(elt->getIteration(),elt->getOrder())); - ret1.push_back(elt->getTimeValue()); - } - } - return ret0; -} - -MEDFileParameters *MEDFileParameters::New() -{ - return new MEDFileParameters; -} - -MEDFileParameters *MEDFileParameters::New(const std::string& fileName) -{ - return new MEDFileParameters(fileName); -} - -MEDFileParameters::MEDFileParameters(const std::string& fileName) -{ - MEDFileUtilities::CheckFileForRead(fileName); - MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName.c_str(),MED_ACC_RDONLY); - int nbPar=MEDnParameter(fid); - _params.resize(nbPar); - INTERP_KERNEL::AutoPtr pName=MEDLoaderBase::buildEmptyString(MED_NAME_SIZE); - INTERP_KERNEL::AutoPtr descName=MEDLoaderBase::buildEmptyString(MED_COMMENT_SIZE); - INTERP_KERNEL::AutoPtr unitName=MEDLoaderBase::buildEmptyString(MED_SNAME_SIZE); - med_parameter_type paramType; - for(int i=0;i)*_params.capacity(); - return ret; -} - -std::vector MEDFileParameters::getDirectChildrenWithNull() const -{ - std::vector ret; - for(std::vector< MEDCouplingAutoRefCountObjectPtr >::const_iterator it=_params.begin();it!=_params.end();it++) - ret.push_back((const MEDFileParameterMultiTS *)*it); - return ret; -} - -MEDFileParameters *MEDFileParameters::deepCpy() const -{ - return new MEDFileParameters(*this,true); -} - -bool MEDFileParameters::isEqual(const MEDFileParameters *other, double eps, std::string& what) const -{ - if(!other) - { what="other is null !"; return false; } - if(_params.size()!=other->_params.size()) - { what="number of parameters differs !"; return false; } - std::ostringstream oss; - for(std::size_t i=0;i<_params.size();i++) - { - const MEDFileParameterMultiTS *a(_params[i]),*b(other->_params[i]); - if((a && !b) || (!a && b)) - { oss << "At param with id #" << i << " pointer is defined on one side not in the other !"; what=oss.str(); return false; } - if(a) - if(!a->isEqual(b,eps,what)) - { oss << " At param with id #" << i << " non equality !"; what+=oss.str(); return false; } - } - return true; -} - -MEDFileParameters::MEDFileParameters(const MEDFileParameters& other, bool deepCopy):MEDFileWritable(other),_params(other._params) -{ - if(deepCopy) - for(std::size_t i=0;i<_params.size();i++) - { - const MEDFileParameterMultiTS *elt=_params[i]; - if(elt) - _params[i]=elt->deepCpy(); - } -} - -void MEDFileParameters::write(const std::string& fileName, int mode) const -{ - med_access_mode medmod=MEDFileUtilities::TraduceWriteMode(mode); - MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName.c_str(),medmod); - writeLL(fid); -} - -void MEDFileParameters::writeLL(med_idt fid) const -{ - for(std::vector< MEDCouplingAutoRefCountObjectPtr >::const_iterator it=_params.begin();it!=_params.end();it++) - { - const MEDFileParameterMultiTS *elt(*it); - if(elt) - elt->writeLL(fid,*this); - } -} - -std::vector MEDFileParameters::getParamsNames() const -{ - std::vector ret(_params.size()); - int i=0; - for(std::vector< MEDCouplingAutoRefCountObjectPtr >::const_iterator it=_params.begin();it!=_params.end();it++,i++) - { - const MEDFileParameterMultiTS *p=(*it); - if(p) - { - ret[i]=p->getName(); - } - else - { - std::ostringstream oss; oss << "MEDFileParameters::getParamsNames : At rank #" << i << " param is not defined !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - } - return ret; -} - -std::string MEDFileParameters::simpleRepr() const -{ - std::ostringstream oss; - simpleReprWithoutHeader(oss); - return oss.str(); -} - -void MEDFileParameters::simpleReprWithoutHeader(std::ostream& oss) const -{ - for(std::vector< MEDCouplingAutoRefCountObjectPtr >::const_iterator it=_params.begin();it!=_params.end();it++) - { - const MEDFileParameterMultiTS *elt(*it); - if(elt) - elt->simpleRepr2(2,oss); - } -} - -void MEDFileParameters::resize(int newSize) -{ - if(newSize<0) - throw INTERP_KERNEL::Exception("MEDFileParameters::resize : should be positive !"); - _params.resize(newSize); -} - -void MEDFileParameters::pushParam(MEDFileParameterMultiTS *param) -{ - if(param) - param->incrRef(); - MEDCouplingAutoRefCountObjectPtr elt(param); - _params.push_back(elt); -} - -void MEDFileParameters::setParamAtPos(int i, MEDFileParameterMultiTS *param) -{ - if(i<0) - throw INTERP_KERNEL::Exception("MEDFileParameters::setParamAtPos : should be positive !"); - if(i>=(int)_params.size()) - _params.resize(i+1); - if(param) - param->incrRef(); - MEDCouplingAutoRefCountObjectPtr elt(param); - _params[i]=elt; -} - -/*! - * \return an internal pointer that can be null. Warning the caller is \b not responsible of the returned pointer. - */ -MEDFileParameterMultiTS *MEDFileParameters::getParamAtPos(int i) const -{ - if(i<0 || i>=(int)_params.size()) - { - std::ostringstream oss; oss << "MEDFileParameters::getParamAtPos : should be in [0," << _params.size() << ") !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - const MEDFileParameterMultiTS *elt=_params[i]; - return const_cast(elt); -} - -/*! - * \return an internal pointer that can be null. Warning the caller is \b not responsible of the returned pointer. - */ -MEDFileParameterMultiTS *MEDFileParameters::getParamWithName(const std::string& paramName) const -{ - int pos=getPosFromParamName(paramName); - return getParamAtPos(pos); -} - -void MEDFileParameters::destroyParamAtPos(int i) -{ - if(i<0 || i>=(int)_params.size()) - { - std::ostringstream oss; oss << "MEDFileParameters::destroyParamAtPos : should be in [0," << _params.size() << ") !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - _params[i]=MEDCouplingAutoRefCountObjectPtr(0); -} - -int MEDFileParameters::getPosFromParamName(const std::string& paramName) const -{ - std::ostringstream oss; oss << "MEDFileParameters::getPosFromParamName : no such name=" << paramName << " ! Possibilities are :"; - int ret=0; - for(std::vector< MEDCouplingAutoRefCountObjectPtr >::const_iterator it=_params.begin();it!=_params.end();it++,ret++) - { - const MEDFileParameterMultiTS *elt(*it); - if(elt) - { - if(std::string(elt->getName())==paramName) - return ret; - else - oss << elt->getName() << ", "; - } - } - throw INTERP_KERNEL::Exception(oss.str().c_str()); -} - -int MEDFileParameters::getNumberOfParams() const -{ - return (int)_params.size(); -} diff --git a/src/MEDLoader/MEDFileParameter.hxx b/src/MEDLoader/MEDFileParameter.hxx deleted file mode 100644 index f223fc78c..000000000 --- a/src/MEDLoader/MEDFileParameter.hxx +++ /dev/null @@ -1,187 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 -// 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 __MEDFILEPARAMETER_HXX__ -#define __MEDFILEPARAMETER_HXX__ - -#include "MEDLoaderDefines.hxx" -#include "MEDFileUtilities.hxx" -#include "MEDCouplingMemArray.hxx" -#include "MEDCouplingAutoRefCountObjectPtr.hxx" - -namespace ParaMEDMEM -{ - class MEDFileParameter1TS : public RefCountObject - { - public: - MEDLOADER_EXPORT virtual MEDFileParameter1TS *deepCpy() const = 0; - MEDLOADER_EXPORT virtual bool isEqual(const MEDFileParameter1TS *other, double eps, std::string& what) const; - MEDLOADER_EXPORT virtual void simpleRepr2(int bkOffset, std::ostream& oss) const = 0; - MEDLOADER_EXPORT virtual void readValue(med_idt fid, const std::string& name) = 0; - MEDLOADER_EXPORT virtual void writeLL(med_idt fid, const std::string& name, const MEDFileWritable& mw) const = 0; - public: - MEDLOADER_EXPORT void setIteration(int it) { _iteration=it; } - MEDLOADER_EXPORT int getIteration() const { return _iteration; } - MEDLOADER_EXPORT void setOrder(int order) { _order=order; } - MEDLOADER_EXPORT int getOrder() const { return _order; } - MEDLOADER_EXPORT void setTimeValue(double time) { _time=time; } - MEDLOADER_EXPORT void setTime(int dt, int it, double time) { _time=time; _iteration=dt; _order=it; } - MEDLOADER_EXPORT double getTime(int& dt, int& it) { dt=_iteration; it=_order; return _time; } - MEDLOADER_EXPORT double getTimeValue() const { return _time; } - protected: - MEDFileParameter1TS(int iteration, int order, double time); - MEDFileParameter1TS(); - protected: - int _iteration; - int _order; - double _time; - }; - - class MEDFileParameterDouble1TSWTI : public MEDFileParameter1TS - { - public: - MEDLOADER_EXPORT static MEDFileParameterDouble1TSWTI *New(int iteration, int order, double time); - MEDLOADER_EXPORT MEDFileParameter1TS *deepCpy() const; - MEDLOADER_EXPORT void setValue(double val) { _arr=val; } - MEDLOADER_EXPORT double getValue() const { return _arr; } - MEDLOADER_EXPORT bool isEqual(const MEDFileParameter1TS *other, double eps, std::string& what) const; - MEDLOADER_EXPORT std::size_t getHeapMemorySizeWithoutChildren() const; - MEDLOADER_EXPORT std::vector getDirectChildrenWithNull() const; - MEDLOADER_EXPORT void readValue(med_idt fid, const std::string& name); - MEDLOADER_EXPORT std::string simpleRepr() const; - protected: - MEDFileParameterDouble1TSWTI(); - MEDFileParameterDouble1TSWTI(int iteration, int order, double time); - void simpleRepr2(int bkOffset, std::ostream& oss) const; - void finishLoading(med_idt fid, const std::string& name, int dt, int it, int nbOfSteps); - void finishLoading(med_idt fid, const std::string& name, int timeStepId); - void writeLL(med_idt fid, const std::string& name, const MEDFileWritable& mw) const; - protected: - double _arr; - }; - - class MEDFileParameterTinyInfo : public MEDFileWritable - { - public: - MEDLOADER_EXPORT void setDescription(const std::string& name) { _desc_name=name; } - MEDLOADER_EXPORT std::string getDescription() const { return _desc_name; } - MEDLOADER_EXPORT void setTimeUnit(const std::string& unit) { _dt_unit=unit; } - MEDLOADER_EXPORT std::string getTimeUnit() const { return _dt_unit; } - MEDLOADER_EXPORT std::size_t getHeapMemSizeOfStrings() const; - MEDLOADER_EXPORT bool isEqualStrings(const MEDFileParameterTinyInfo& other, std::string& what) const; - protected: - void writeLLHeader(med_idt fid, med_parameter_type typ) const; - void mainRepr(int bkOffset, std::ostream& oss) const; - protected: - std::string _dt_unit; - std::string _name; - std::string _desc_name; - }; - - class MEDFileParameterDouble1TS : public MEDFileParameterDouble1TSWTI, public MEDFileParameterTinyInfo - { - public: - MEDLOADER_EXPORT static MEDFileParameterDouble1TS *New(); - MEDLOADER_EXPORT static MEDFileParameterDouble1TS *New(const std::string& fileName); - MEDLOADER_EXPORT static MEDFileParameterDouble1TS *New(const std::string& fileName, const std::string& paramName); - MEDLOADER_EXPORT static MEDFileParameterDouble1TS *New(const std::string& fileName, const std::string& paramName, int dt, int it); - MEDLOADER_EXPORT virtual MEDFileParameter1TS *deepCpy() const; - MEDLOADER_EXPORT virtual bool isEqual(const MEDFileParameter1TS *other, double eps, std::string& what) const; - MEDLOADER_EXPORT virtual std::string simpleRepr() const; - MEDLOADER_EXPORT std::size_t getHeapMemorySizeWithoutChildren() const; - MEDLOADER_EXPORT std::vector getDirectChildrenWithNull() const; - MEDLOADER_EXPORT void setName(const std::string& name) { _name=name; } - MEDLOADER_EXPORT std::string getName() const { return _name; } - MEDLOADER_EXPORT void write(const std::string& fileName, int mode) const; - private: - MEDFileParameterDouble1TS(); - MEDFileParameterDouble1TS(const std::string& fileName); - MEDFileParameterDouble1TS(const std::string& fileName, const std::string& paramName); - MEDFileParameterDouble1TS(const std::string& fileName, const std::string& paramName, int dt, int it); - }; - - class MEDFileParameterMultiTS : public RefCountObject, public MEDFileParameterTinyInfo - { - public: - MEDLOADER_EXPORT static MEDFileParameterMultiTS *New(); - MEDLOADER_EXPORT static MEDFileParameterMultiTS *New(const std::string& fileName); - MEDLOADER_EXPORT static MEDFileParameterMultiTS *New(const std::string& fileName, const std::string& paramName); - MEDLOADER_EXPORT std::string getName() const { return _name; } - MEDLOADER_EXPORT void setName(const std::string& name) { _name=name; } - MEDLOADER_EXPORT std::size_t getHeapMemorySizeWithoutChildren() const; - MEDLOADER_EXPORT std::vector getDirectChildrenWithNull() const; - MEDLOADER_EXPORT MEDFileParameterMultiTS *deepCpy() const; - MEDLOADER_EXPORT bool isEqual(const MEDFileParameterMultiTS *other, double eps, std::string& what) const; - MEDLOADER_EXPORT void write(const std::string& fileName, int mode) const; - MEDLOADER_EXPORT void writeLL(med_idt fid, const MEDFileWritable& mw) const; - MEDLOADER_EXPORT std::string simpleRepr() const; - MEDLOADER_EXPORT void appendValue(int dt, int it, double time, double val); - MEDLOADER_EXPORT double getDoubleValue(int iteration, int order) const; - MEDLOADER_EXPORT int getPosOfTimeStep(int iteration, int order) const; - MEDLOADER_EXPORT int getPosGivenTime(double time, double eps=1e-8) const; - MEDLOADER_EXPORT MEDFileParameter1TS *getTimeStepAtPos(int posId) const; - MEDLOADER_EXPORT void eraseTimeStepIds(const int *startIds, const int *endIds); - MEDLOADER_EXPORT int getNumberOfTS() const; - MEDLOADER_EXPORT std::vector< std::pair > getIterations() const; - MEDLOADER_EXPORT std::vector< std::pair > getTimeSteps(std::vector& ret1) const; - MEDLOADER_EXPORT void simpleRepr2(int bkOffset, std::ostream& oss) const; - protected: - MEDFileParameterMultiTS(); - MEDFileParameterMultiTS(const MEDFileParameterMultiTS& other, bool deepCopy); - MEDFileParameterMultiTS(const std::string& fileName); - MEDFileParameterMultiTS(const std::string& fileName, const std::string& paramName); - void finishLoading(med_idt fid, med_parameter_type typ, int nbOfSteps); - protected: - std::vector< MEDCouplingAutoRefCountObjectPtr > _param_per_ts; - }; - - class MEDFileParameters : public RefCountObject, public MEDFileWritable - { - public: - MEDLOADER_EXPORT static MEDFileParameters *New(); - MEDLOADER_EXPORT static MEDFileParameters *New(const std::string& fileName); - MEDLOADER_EXPORT std::size_t getHeapMemorySizeWithoutChildren() const; - MEDLOADER_EXPORT std::vector getDirectChildrenWithNull() const; - MEDLOADER_EXPORT MEDFileParameters *deepCpy() const; - MEDLOADER_EXPORT bool isEqual(const MEDFileParameters *other, double eps, std::string& what) const; - MEDLOADER_EXPORT void write(const std::string& fileName, int mode) const; - MEDLOADER_EXPORT void writeLL(med_idt fid) const; - MEDLOADER_EXPORT std::vector getParamsNames() const; - MEDLOADER_EXPORT std::string simpleRepr() const; - MEDLOADER_EXPORT void simpleReprWithoutHeader(std::ostream& oss) const; - MEDLOADER_EXPORT void resize(int newSize); - MEDLOADER_EXPORT void pushParam(MEDFileParameterMultiTS *param); - MEDLOADER_EXPORT void setParamAtPos(int i, MEDFileParameterMultiTS *param); - MEDLOADER_EXPORT MEDFileParameterMultiTS *getParamAtPos(int i) const; - MEDLOADER_EXPORT MEDFileParameterMultiTS *getParamWithName(const std::string& paramName) const; - MEDLOADER_EXPORT void destroyParamAtPos(int i); - MEDLOADER_EXPORT int getPosFromParamName(const std::string& paramName) const; - MEDLOADER_EXPORT int getNumberOfParams() const; - protected: - void simpleRepr2(int bkOffset, std::ostream& oss) const; - MEDFileParameters(const std::string& fileName); - MEDFileParameters(const MEDFileParameters& other, bool deepCopy); - MEDFileParameters(); - protected: - std::vector< MEDCouplingAutoRefCountObjectPtr > _params; - }; -} - -#endif diff --git a/src/MEDLoader/MEDFileSafeCaller.txx b/src/MEDLoader/MEDFileSafeCaller.txx deleted file mode 100644 index 2ce1bd6cf..000000000 --- a/src/MEDLoader/MEDFileSafeCaller.txx +++ /dev/null @@ -1,41 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 -// 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 (EDF R&D) - -#ifndef __MEDFILESAFECALLER_TXX__ -#define __MEDFILESAFECALLER_TXX__ - -#include "med.h" - -#include "InterpKernelException.hxx" - -#include - -// TXX extension to avoid to be installed. - -// This macro calls safely MEDFile functions returning 0 -#define MEDFILESAFECALLER0(a,b) { med_err retCode(a b); \ - if(retCode!=0) { std::ostringstream osszz; osszz << "Return code of MEDFile call \"" << #a << "\" is not 0 as expected ! ( Return code was "<< retCode << " at " << __FILE__ << ":" << __LINE__ << " )"; throw INTERP_KERNEL::Exception(osszz.str().c_str()); } } - -#define MEDFILESAFECALLERRD0(a,b) MEDFILESAFECALLER0(a,b) - -#define MEDFILESAFECALLERWR0(a,b) { med_err retCode(a b); \ - if(retCode!=0) { std::ostringstream osszz; osszz << "Return code of MEDFile call \"" << #a << "\" is not 0 as expected during writing operation ! ( Return code was "<< retCode << " at " << __FILE__ << ":" << __LINE__ << " ). Check write access on MED file ?"; throw INTERP_KERNEL::Exception(osszz.str().c_str()); } } - -#endif diff --git a/src/MEDLoader/MEDFileUtilities.cxx b/src/MEDLoader/MEDFileUtilities.cxx deleted file mode 100644 index a52d8a28b..000000000 --- a/src/MEDLoader/MEDFileUtilities.cxx +++ /dev/null @@ -1,147 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 -// 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 "MEDFileUtilities.hxx" -#include "MEDLoaderBase.hxx" - -#include - -med_access_mode MEDFileUtilities::TraduceWriteMode(int medloaderwritemode) -{ - switch(medloaderwritemode) - { - case 2: - return MED_ACC_CREAT; - case 1: - return MED_ACC_RDEXT; - case 0: - return MED_ACC_RDWR; - default: - throw INTERP_KERNEL::Exception("Invalid write mode specified ! must be 0(write with no question), 1(append) or 2(creation)"); - } -} - -const char *MEDFileUtilities::GetReadableMEDFieldType(med_field_type ft) -{ - static const char medFloat64[]="MED_FLOAT64"; - static const char medInt32[]="MED_INT32"; - static const char medInt64[]="MED_INT64"; - switch(ft) - { - case MED_FLOAT64: - return medFloat64; - case MED_INT32: - return medInt32; - case MED_INT64: - return medInt64; - default: - throw INTERP_KERNEL::Exception("Non supported field type ! Should be FLOAT64, INT32 or INT64 !"); - } -} - -void MEDFileUtilities::CheckMEDCode(int code, med_idt fid, const std::string& msg) -{ - if(code<0) - { - std::ostringstream oss; - oss << "MEDFile has returned an error code (" << code <<") : " << msg; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } -} - -void MEDFileUtilities::CheckFileForRead(const std::string& fileName) -{ - int status=MEDLoaderBase::getStatusOfFile(fileName); - std::ostringstream oss; - oss << " File : \"" << fileName << "\""; - switch(status) - { - case MEDLoaderBase::DIR_LOCKED: - { - oss << " has been detected as unreadable : impossible to read anything !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - case MEDLoaderBase::NOT_EXIST: - { - oss << " has been detected as NOT EXISTING : impossible to read anything !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - case MEDLoaderBase::EXIST_WRONLY: - { - oss << " has been detected as WRITE ONLY : impossible to read anything !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - } - AutoFid fid=MEDfileOpen(fileName.c_str(),MED_ACC_RDONLY); - if(fid<0) - { - oss << " has been detected as unreadable by MED file : impossible to read anything !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - oss << " has been detected readable but "; - int major,minor,release; - MEDfileNumVersionRd(fid,&major,&minor,&release); - if(major<2 || (major==2 && minor<2)) - { - oss << "version of MED file is < 2.2 : impossible to read anything !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } -} - -MEDFileUtilities::AutoFid::AutoFid(med_idt fid):_fid(fid) -{ -} - -MEDFileUtilities::AutoFid::~AutoFid() -{ - MEDfileClose(_fid); -} - -ParaMEDMEM::MEDFileWritable::MEDFileWritable():_too_long_str(0),_zipconn_pol(2) -{ -} - -void ParaMEDMEM::MEDFileWritable::copyOptionsFrom(const MEDFileWritable& other) const -{ - _too_long_str=other._too_long_str; - _zipconn_pol=other._zipconn_pol; -} - -int ParaMEDMEM::MEDFileWritable::getTooLongStrPolicy() const -{ - return _too_long_str; -} - -void ParaMEDMEM::MEDFileWritable::setTooLongStrPolicy(int newVal) -{ - if(newVal!=2 && newVal!=1 && newVal!=0) - throw INTERP_KERNEL::Exception("MEDFileWritable::setTooLongStrPolicy : invalid policy should be in 0,1 or 2 !"); - _too_long_str=newVal; -} - -int ParaMEDMEM::MEDFileWritable::getZipConnPolicy() -{ - return _zipconn_pol; -} - -void ParaMEDMEM::MEDFileWritable::setZipConnPolicy(int newVal) -{ - _zipconn_pol=newVal; -} diff --git a/src/MEDLoader/MEDFileUtilities.hxx b/src/MEDLoader/MEDFileUtilities.hxx deleted file mode 100644 index ffac85a16..000000000 --- a/src/MEDLoader/MEDFileUtilities.hxx +++ /dev/null @@ -1,64 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 -// 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 __MEDFILEUTILITIES_HXX__ -#define __MEDFILEUTILITIES_HXX__ - -#include "InterpKernelException.hxx" -#include "MEDLoaderDefines.hxx" - -#include "med.h" - -namespace MEDFileUtilities -{ - med_access_mode TraduceWriteMode(int medloaderwritemode); - const char *GetReadableMEDFieldType(med_field_type ft); - void CheckMEDCode(int code, med_idt fid, const std::string& msg); - void CheckFileForRead(const std::string& fileName); - - class AutoFid - { - public: - AutoFid(med_idt fid); - operator med_idt() const { return _fid; } - ~AutoFid(); - private: - med_idt _fid; - }; -} - -namespace ParaMEDMEM -{ - class MEDLOADER_EXPORT MEDFileWritable - { - public: - MEDFileWritable(); - void copyOptionsFrom(const MEDFileWritable& other) const; - int getTooLongStrPolicy() const; - void setTooLongStrPolicy(int newVal); - int getZipConnPolicy(); - void setZipConnPolicy(int newVal); - protected://policies on write - mutable int _too_long_str; - mutable int _zipconn_pol; - }; -} - -#endif diff --git a/src/MEDLoader/MEDLoader.cxx b/src/MEDLoader/MEDLoader.cxx deleted file mode 100644 index 70c6d889a..000000000 --- a/src/MEDLoader/MEDLoader.cxx +++ /dev/null @@ -1,1585 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 -// 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 "MEDLoader.hxx" -#include "MEDLoaderBase.hxx" -#include "MEDFileUtilities.hxx" -#include "MEDFileSafeCaller.txx" -#include "MEDFileMesh.hxx" -#include "MEDFileField.hxx" -#include "CellModel.hxx" -#include "MEDCouplingUMesh.hxx" -#include "MEDCouplingMemArray.hxx" -#include "MEDCouplingFieldDouble.hxx" -#include "MEDCouplingGaussLocalization.hxx" -#include "MEDCouplingAutoRefCountObjectPtr.hxx" - -#include "InterpKernelAutoPtr.hxx" - -#include "med.h" - -#include -#include -#include -#include -#include -#include -#include -#include - -/*! \class MEDLoader - * - * \brief Static class offering the "basic" API to read and write MED files/ - * - * This class implements only static methods and offers the high level API to access MED files. - * Take a look at \ref medloader for more details. - * - */ - -med_geometry_type typmai[MED_N_CELL_FIXED_GEO] = { MED_POINT1, - MED_SEG2, - MED_SEG3, - MED_SEG4, - MED_TRIA3, - MED_QUAD4, - MED_TRIA6, - MED_TRIA7, - MED_QUAD8, - MED_QUAD9, - MED_TETRA4, - MED_PYRA5, - MED_PENTA6, - MED_HEXA8, - MED_OCTA12, - MED_TETRA10, - MED_PYRA13, - MED_PENTA15, - MED_HEXA20, - MED_HEXA27, - MED_POLYGON, - MED_POLYGON2, - MED_POLYHEDRON }; - -med_geometry_type typmainoeud[1] = { MED_NONE }; - -INTERP_KERNEL::NormalizedCellType typmai2[MED_N_CELL_FIXED_GEO] = { INTERP_KERNEL::NORM_POINT1, - INTERP_KERNEL::NORM_SEG2, - INTERP_KERNEL::NORM_SEG3, - INTERP_KERNEL::NORM_SEG4, - INTERP_KERNEL::NORM_TRI3, - INTERP_KERNEL::NORM_QUAD4, - INTERP_KERNEL::NORM_TRI6, - INTERP_KERNEL::NORM_TRI7, - INTERP_KERNEL::NORM_QUAD8, - INTERP_KERNEL::NORM_QUAD9, - INTERP_KERNEL::NORM_TETRA4, - INTERP_KERNEL::NORM_PYRA5, - INTERP_KERNEL::NORM_PENTA6, - INTERP_KERNEL::NORM_HEXA8, - INTERP_KERNEL::NORM_HEXGP12, - INTERP_KERNEL::NORM_TETRA10, - INTERP_KERNEL::NORM_PYRA13, - INTERP_KERNEL::NORM_PENTA15, - INTERP_KERNEL::NORM_HEXA20, - INTERP_KERNEL::NORM_HEXA27, - INTERP_KERNEL::NORM_POLYGON, - INTERP_KERNEL::NORM_QPOLYG, - INTERP_KERNEL::NORM_POLYHED }; - -med_geometry_type typmai3[34] = { MED_POINT1,//0 - MED_SEG2,//1 - MED_SEG3,//2 - MED_TRIA3,//3 - MED_QUAD4,//4 - MED_POLYGON,//5 - MED_TRIA6,//6 - MED_TRIA7,//7 - MED_QUAD8,//8 - MED_QUAD9,//9 - MED_SEG4,//10 - MED_NONE,//11 - MED_NONE,//12 - MED_NONE,//13 - MED_TETRA4,//14 - MED_PYRA5,//15 - MED_PENTA6,//16 - MED_NONE,//17 - MED_HEXA8,//18 - MED_NONE,//19 - MED_TETRA10,//20 - MED_NONE,//21 - MED_OCTA12,//22 - MED_PYRA13,//23 - MED_NONE,//24 - MED_PENTA15,//25 - MED_NONE,//26 - MED_HEXA27,//27 - MED_NONE,//28 - MED_NONE,//29 - MED_HEXA20,//30 - MED_POLYHEDRON,//31 - MED_POLYGON2,//32 - MED_NONE//33 -}; - -double MEDLoader::_EPS_FOR_NODE_COMP=1.e-12; - -int MEDLoader::_COMP_FOR_CELL=0; - -int MEDLoader::_TOO_LONG_STR=0; - -using namespace ParaMEDMEM; - -/// @cond INTERNAL - -namespace MEDLoaderNS -{ - int readUMeshDimFromFile(const std::string& fileName, const std::string& meshName, std::vector& possibilities); - void dispatchElems(int nbOfElemCell, int nbOfElemFace, int& nbOfElem, med_entity_type& whichEntity); - void writeFieldWithoutReadingAndMappingOfMeshInFile(const std::string& fileName, const ParaMEDMEM::MEDCouplingFieldDouble *f, bool writeFromScratch); - med_int getIdFromMeshName(med_idt fid, const std::string& meshName, std::string& trueMeshName); - std::vector getMeshNamesFid(med_idt fid); -} - -/// @endcond - - -/// @cond INTERNAL - -/*! - * This method returns a first quick overview of mesh with name \a meshName into the file \a fileName. - * @param possibilities the relativeToMeshDim authorized to returned maxdim. This vector is systematically cleared at the begin of this method. - * @return the maximal mesh dimension of specified mesh. If nothing found -1 is returned. - */ -int MEDLoaderNS::readUMeshDimFromFile(const std::string& fileName, const std::string& meshName, std::vector& possibilities) -{ - possibilities.clear(); - MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName.c_str(),MED_ACC_RDONLY); - int ret; - std::set poss; - char nommaa[MED_NAME_SIZE+1]; - char maillage_description[MED_COMMENT_SIZE+1]; - med_mesh_type type_maillage; - med_int Sdim,Mdim; - std::string trueMeshName; - med_int meshId=getIdFromMeshName(fid,meshName,trueMeshName); - INTERP_KERNEL::AutoPtr dt_unit=MEDLoaderBase::buildEmptyString(MED_LNAME_SIZE); - med_sorting_type sortingType; - med_int nstep; - med_axis_type axisType; - int naxis(MEDmeshnAxis(fid,meshId)); - INTERP_KERNEL::AutoPtr axisname=MEDLoaderBase::buildEmptyString(naxis*MED_SNAME_SIZE); - INTERP_KERNEL::AutoPtr axisunit=MEDLoaderBase::buildEmptyString(naxis*MED_SNAME_SIZE); - MEDFILESAFECALLERRD0(MEDmeshInfo,(fid,meshId,nommaa,&Sdim,&Mdim,&type_maillage,maillage_description,dt_unit,&sortingType,&nstep,&axisType,axisname,axisunit)); - // limitation - if(nstep!=1) - { - throw INTERP_KERNEL::Exception("multisteps on mesh not managed yet !"); - } - med_int numdt,numit; - med_float dt; - MEDFILESAFECALLERRD0(MEDmeshComputationStepInfo,(fid,nommaa,1,&numdt,&numit,&dt)); - // endlimitation - for(int i=0;i0) - { - INTERP_KERNEL::NormalizedCellType type=typmai2[i]; - int curDim=(int)INTERP_KERNEL::CellModel::GetCellModel(type).getDimension(); - poss.insert(curDim); - } - } - if(!poss.empty()) - { - ret=*poss.rbegin(); - for(std::set::const_reverse_iterator it=poss.rbegin();it!=poss.rend();it++) - possibilities.push_back(*it-ret); - } - else - ret=-2; - return ret; -} - -med_int MEDLoaderNS::getIdFromMeshName(med_idt fid, const std::string& meshName, std::string& trueMeshName) - { - if(meshName.empty()) - { - std::vector meshes=getMeshNamesFid(fid); - if(meshes.empty()) - throw INTERP_KERNEL::Exception("No mesh in file"); - trueMeshName=meshes[0]; - return 1; - } - std::string meshNameStr(meshName); - std::vector meshes=getMeshNamesFid(fid); - if(meshes.empty()) - throw INTERP_KERNEL::Exception("No mesh in file"); - std::vector::iterator iter=std::find(meshes.begin(),meshes.end(),meshNameStr); - if(iter==meshes.end()) - { - std::ostringstream os2; - os2 << "MeshName '" << meshName << "' not in file : meshes available : "; - std::copy(meshes.begin(),meshes.end(),std::ostream_iterator(os2," ")); - throw INTERP_KERNEL::Exception(os2.str().c_str()); - } - trueMeshName=meshName; - return iter-meshes.begin()+1; - } - -std::vector MEDLoaderNS::getMeshNamesFid(med_idt fid) -{ - med_mesh_type type_maillage; - char maillage_description[MED_COMMENT_SIZE+1]; - char dtunit[MED_COMMENT_SIZE+1]; - med_int space_dim; - med_int mesh_dim; - char nommaa[MED_NAME_SIZE+1]; - med_axis_type axistype; - med_sorting_type stype; - med_int n=MEDnMesh(fid); - std::vector ret(n); - for(int i=0;i axisname=MEDLoaderBase::buildEmptyString(naxis*MED_SNAME_SIZE); - INTERP_KERNEL::AutoPtr axisunit=MEDLoaderBase::buildEmptyString(naxis*MED_SNAME_SIZE); - int nstep; - MEDFILESAFECALLERRD0(MEDmeshInfo,(fid,i+1,nommaa,&space_dim,&mesh_dim,&type_maillage,maillage_description,dtunit,&stype,&nstep,&axistype,axisname,axisunit)); - std::string cur=MEDLoaderBase::buildStringFromFortran(nommaa,sizeof(nommaa)); - ret[i]=cur; - } - return ret; -} - -/*! - * This methods allows to merger all entities and to considerate only cell types. - */ -void MEDLoaderNS::dispatchElems(int nbOfElemCell, int nbOfElemFace, int& nbOfElem, med_entity_type& whichEntity) -{ - if(nbOfElemCell>=nbOfElemFace) - { - whichEntity=MED_CELL; - nbOfElem=nbOfElemCell; - } - else - { - whichEntity=MED_CELL; - nbOfElem=nbOfElemFace; - } -} - -/// @endcond - -void MEDLoader::AssignStaticWritePropertiesTo(ParaMEDMEM::MEDFileWritable& obj) -{ - obj.setTooLongStrPolicy(_TOO_LONG_STR); -} - -bool MEDLoader::HasXDR() -{ -#ifdef HAS_XDR - return true; -#else - return false; -#endif -} - -std::string MEDLoader::MEDFileVersionStr() -{ - return std::string(MED_VERSION_STR); -} - -void MEDLoader::MEDFileVersion(int& major, int& minor, int& release) -{ - major=MED_NUM_MAJEUR; - minor=MED_NUM_MINEUR; - release=MED_NUM_RELEASE; -} - -/*! - * This method sets the epsilon value used for node comparison when trying to buid a profile for a field on node/cell on an already written mesh. - */ -void MEDLoader::SetEpsilonForNodeComp(double val) -{ - _EPS_FOR_NODE_COMP=val; -} - -/*! - * This method sets the policy comparison when trying to fit the already written mesh on a field. The semantic of the policy is specified in MEDCouplingUMesh::zipConnectivityTraducer. - */ -void MEDLoader::SetCompPolicyForCell(int val) -{ - _COMP_FOR_CELL=val; -} - -/*! - * This method set the behaviour of MEDLoader when a too long string is seen in datastructure before copy it in MED file. - * By default (0) an exception is thrown. If equal to 1 a warning is emitted in std_err but no exception is thrown. - */ -void MEDLoader::SetTooLongStrPolicy(int val) -{ - _TOO_LONG_STR=val; -} - -/*! - * Given a 'fileName' and a 'meshName' this method returns global information concerning this mesh. - * It returns, in this order : - * - number of cells sorted by dimension and by geometry type. The first entry in the vector is the maximal dimension, the 2nd in the vector is the maximal dimension-1... - * - the mesh dimension - * - the space dimension - * - the number of nodes - */ -std::vector< std::vector< std::pair > > MEDLoader::GetUMeshGlobalInfo(const std::string& fileName, const std::string& meshName, int &meshDim, int& spaceDim, int& numberOfNodes) -{ - CheckFileForRead(fileName); - MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName.c_str(),MED_ACC_RDONLY); - std::set poss; - char nommaa[MED_NAME_SIZE+1]; - char maillage_description[MED_COMMENT_SIZE+1]; - med_mesh_type type_maillage; - std::string trueMeshName; - med_int meshId=MEDLoaderNS::getIdFromMeshName(fid,meshName,trueMeshName); - INTERP_KERNEL::AutoPtr dt_unit=MEDLoaderBase::buildEmptyString(MED_LNAME_SIZE); - med_sorting_type sortingType; - med_int nstep; - med_axis_type axisType; - int naxis(MEDmeshnAxis(fid,meshId)); - INTERP_KERNEL::AutoPtr axisname=MEDLoaderBase::buildEmptyString(naxis*MED_SNAME_SIZE); - INTERP_KERNEL::AutoPtr axisunit=MEDLoaderBase::buildEmptyString(naxis*MED_SNAME_SIZE); - MEDFILESAFECALLERRD0(MEDmeshInfo,(fid,meshId,nommaa,&spaceDim,&meshDim,&type_maillage,maillage_description,dt_unit,&sortingType,&nstep,&axisType,axisname,axisunit)); - if(type_maillage!=MED_UNSTRUCTURED_MESH) - { - std::ostringstream oss; oss << "MEDLoader::GetUMeshGlobalInfo : Mesh \""<< meshName << "\" in file \"" << fileName; - oss << "\" exists but it is not an unstructured mesh ! This method is not relevant for mesh types that are not unstructured !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - // limitation - if(nstep!=1) - throw INTERP_KERNEL::Exception("MEDLoader::GetUMeshGlobalInfo : multisteps on mesh not managed !"); - med_int numdt,numit; - med_float dt; - MEDFILESAFECALLERRD0(MEDmeshComputationStepInfo,(fid,nommaa,1,&numdt,&numit,&dt)); - // endlimitation - std::vector dims; - std::vector< std::pair > geoTypes; - med_bool changement,transformation; - for(int i=0;i0) - { - INTERP_KERNEL::NormalizedCellType typp=typmai2[i]; - int mdimCell=INTERP_KERNEL::CellModel::GetCellModel(typp).getDimension(); - dims.push_back(mdimCell); - geoTypes.push_back(std::pair(typp,curNbOfElemM)); - } - } - int maxLev=*std::max_element(dims.begin(),dims.end()); - int lowLev=*std::min_element(dims.begin(),dims.end()); - int nbOfLevels=maxLev-lowLev+1; - std::vector< std::vector< std::pair > > ret(nbOfLevels); - for(std::size_t i=0;i MEDLoader::GetMeshNames(const std::string& fileName) -{ - CheckFileForRead(fileName); - MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName.c_str(),MED_ACC_RDONLY); - std::vector ret=MEDLoaderNS::getMeshNamesFid(fid); - return ret; -} - -std::vector< std::pair > MEDLoader::GetComponentsNamesOfField(const std::string& fileName, const std::string& fieldName) -{ - CheckFileForRead(fileName); - MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName.c_str(),MED_ACC_RDONLY); - med_int nbFields(MEDnField(fid)); - std::vector fields(nbFields); - med_field_type typcha; - for(int i=0;i comp=new char[ncomp*MED_SNAME_SIZE+1]; - INTERP_KERNEL::AutoPtr unit=new char[ncomp*MED_SNAME_SIZE+1]; - INTERP_KERNEL::AutoPtr dt_unit=MEDLoaderBase::buildEmptyString(MED_LNAME_SIZE); - med_int nbPdt; - med_bool localmesh; - INTERP_KERNEL::AutoPtr maa_ass=MEDLoaderBase::buildEmptyString(MED_NAME_SIZE); - INTERP_KERNEL::AutoPtr nomcha=MEDLoaderBase::buildEmptyString(MED_NAME_SIZE); - MEDFILESAFECALLERRD0(MEDfieldInfo,(fid,i+1,nomcha,maa_ass,&localmesh,&typcha,comp,unit,dt_unit,&nbPdt)); - std::string meshName=MEDLoaderBase::buildStringFromFortran(maa_ass,MED_NAME_SIZE); - std::string curFieldName=MEDLoaderBase::buildStringFromFortran(nomcha,MED_NAME_SIZE+1); - if(curFieldName==fieldName) - { - std::vector< std::pair > ret(ncomp); - for(int j=0;j(MEDLoaderBase::buildStringFromFortran(((char *)comp)+j*MED_SNAME_SIZE,MED_SNAME_SIZE), - MEDLoaderBase::buildStringFromFortran(((char *)unit)+j*MED_SNAME_SIZE,MED_SNAME_SIZE)); - return ret; - } - fields[i]=curFieldName; - } - std::ostringstream oss; oss << "MEDLoader::GetComponentsNamesOfField : no such field \"" << fieldName << "\" in file \"" << fileName << "\" !" << std::endl; - oss << "Possible field names are : " << std::endl; - std::copy(fields.begin(),fields.end(),std::ostream_iterator(oss," ")); - throw INTERP_KERNEL::Exception(oss.str().c_str()); -} - -std::vector MEDLoader::GetMeshNamesOnField(const std::string& fileName, const std::string& fieldName) -{ - CheckFileForRead(fileName); - std::vector ret; - // - MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName.c_str(),MED_ACC_RDONLY); - med_int nbFields=MEDnField(fid); - // - med_field_type typcha; - INTERP_KERNEL::AutoPtr dt_unit=MEDLoaderBase::buildEmptyString(MED_LNAME_SIZE); - INTERP_KERNEL::AutoPtr nomcha=MEDLoaderBase::buildEmptyString(MED_NAME_SIZE); - med_bool localmesh; - // - for(int i=0;i comp=new char[ncomp*MED_SNAME_SIZE+1]; - INTERP_KERNEL::AutoPtr unit=new char[ncomp*MED_SNAME_SIZE+1]; - med_int nbPdt; - INTERP_KERNEL::AutoPtr maa_ass=MEDLoaderBase::buildEmptyString(MED_NAME_SIZE); - MEDFILESAFECALLERRD0(MEDfieldInfo,(fid,i+1,nomcha,maa_ass,&localmesh,&typcha,comp,unit,dt_unit,&nbPdt)); - std::string meshName=MEDLoaderBase::buildStringFromFortran(maa_ass,MED_NAME_SIZE); - std::string curFieldName=MEDLoaderBase::buildStringFromFortran(nomcha,MED_NAME_SIZE+1); - if(curFieldName==fieldName) - ret.push_back(meshName); - } - return ret; -} - -std::vector MEDLoader::GetMeshFamiliesNames(const std::string& fileName, const std::string& meshName) -{ - CheckFileForRead(fileName); - MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName.c_str(),MED_ACC_RDONLY); - med_int nfam=MEDnFamily(fid,meshName.c_str()); - std::vector ret(nfam); - char nomfam[MED_NAME_SIZE+1]; - med_int numfam; - for(int i=0;i attide=new med_int[natt]; - INTERP_KERNEL::AutoPtr attval=new med_int[natt]; - INTERP_KERNEL::AutoPtr attdes=new char[MED_COMMENT_SIZE*natt+1]; - INTERP_KERNEL::AutoPtr gro=new char[MED_LNAME_SIZE*ngro+1]; - MEDfamily23Info(fid,meshName.c_str(),i+1,nomfam,attide,attval,attdes,&numfam,gro); - std::string cur=MEDLoaderBase::buildStringFromFortran(nomfam,sizeof(nomfam)); - ret[i]=cur; - } - return ret; -} - - -std::vector MEDLoader::GetMeshFamiliesNamesOnGroup(const std::string& fileName, const std::string& meshName, const std::string& grpName) -{ - CheckFileForRead(fileName); - MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName.c_str(),MED_ACC_RDONLY); - med_int nfam=MEDnFamily(fid,meshName.c_str()); - std::vector ret; - char nomfam[MED_NAME_SIZE+1]; - med_int numfam; - for(int i=0;i attide=new med_int[natt]; - INTERP_KERNEL::AutoPtr attval=new med_int[natt]; - INTERP_KERNEL::AutoPtr attdes=new char[MED_COMMENT_SIZE*natt+1]; - INTERP_KERNEL::AutoPtr gro=new char[MED_LNAME_SIZE*ngro+1]; - MEDfamily23Info(fid,meshName.c_str(),i+1,nomfam,attide,attval,attdes,&numfam,gro); - std::string cur=MEDLoaderBase::buildStringFromFortran(nomfam,sizeof(nomfam)); - for(int j=0;j MEDLoader::GetMeshGroupsNamesOnFamily(const std::string& fileName, const std::string& meshName, const std::string& famName) -{ - CheckFileForRead(fileName); - MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName.c_str(),MED_ACC_RDONLY); - med_int nfam=MEDnFamily(fid,meshName.c_str()); - std::vector ret; - char nomfam[MED_NAME_SIZE+1]; - med_int numfam; - bool found=false; - for(int i=0;i attide=new med_int[natt]; - INTERP_KERNEL::AutoPtr attval=new med_int[natt]; - INTERP_KERNEL::AutoPtr attdes=new char[MED_COMMENT_SIZE*natt+1]; - INTERP_KERNEL::AutoPtr gro=new char[MED_LNAME_SIZE*ngro+1]; - MEDfamily23Info(fid,meshName.c_str(),i+1,nomfam,attide,attval,attdes,&numfam,gro); - std::string cur=MEDLoaderBase::buildStringFromFortran(nomfam,sizeof(nomfam)); - found=(cur==famName); - if(found) - for(int j=0;j MEDLoader::GetMeshGroupsNames(const std::string& fileName, const std::string& meshName) -{ - CheckFileForRead(fileName); - MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName.c_str(),MED_ACC_RDONLY); - med_int nfam=MEDnFamily(fid,meshName.c_str()); - std::vector ret; - char nomfam[MED_NAME_SIZE+1]; - med_int numfam; - for(int i=0;i attide=new med_int[natt]; - INTERP_KERNEL::AutoPtr attval=new med_int[natt]; - INTERP_KERNEL::AutoPtr attdes=new char[MED_COMMENT_SIZE*natt+1]; - INTERP_KERNEL::AutoPtr gro=new char[MED_LNAME_SIZE*ngro+1]; - MEDfamily23Info(fid,meshName.c_str(),i+1,nomfam,attide,attval,attdes,&numfam,gro); - for(int j=0;j MEDLoader::GetTypesOfField(const std::string& fileName, const std::string& meshName, const std::string& fieldName) -{ - std::vector ret; - MEDCouplingAutoRefCountObjectPtr fs(MEDFileAnyTypeFieldMultiTS::New(fileName,fieldName,false)); - if(fs->getMeshName()!=meshName) - { - std::ostringstream oss; oss << "MEDLoader::GetTypesOfField : The field \"" << fieldName << "\" in file \"" << fileName << "\" is not lying on mesh \"" << meshName << "\""; - oss << " The name of the mesh in file is \"" << fs->getMeshName() << "\"!"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - int nbTS(fs->getNumberOfTS()); - if(nbTS==0) - return ret; - for(int i=0;i f1ts(fs->getTimeStepAtPos(i)); - std::vector tof(f1ts->getTypesOfFieldAvailable()); - for(std::vector::const_iterator it=tof.begin();it!=tof.end();it++) - if(std::find(ret.begin(),ret.end(),*it)==ret.end()) - ret.push_back(*it); - } - // sort ret to put before ON_NODES then ON_CELLS then the remaining. - std::vector ret2; - if(std::find(ret.begin(),ret.end(),ON_NODES)!=ret.end()) - ret2.push_back(ON_NODES); - if(std::find(ret.begin(),ret.end(),ON_CELLS)!=ret.end()) - ret2.push_back(ON_CELLS); - for(std::vector::const_iterator it=ret.begin();it!=ret.end();it++) - if(*it!=ON_NODES && *it!=ON_CELLS) - ret2.push_back(*it); - return ret2; -} - -std::vector MEDLoader::GetAllFieldNames(const std::string& fileName) -{ - CheckFileForRead(fileName); - std::vector ret; - MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName.c_str(),MED_ACC_RDONLY); - med_int nbFields=MEDnField(fid); - med_field_type typcha; - for(int i=0;i comp=new char[ncomp*MED_SNAME_SIZE+1]; - INTERP_KERNEL::AutoPtr unit=new char[ncomp*MED_SNAME_SIZE+1]; - INTERP_KERNEL::AutoPtr nomcha=MEDLoaderBase::buildEmptyString(MED_NAME_SIZE); - INTERP_KERNEL::AutoPtr maa_ass=MEDLoaderBase::buildEmptyString(MED_NAME_SIZE); - INTERP_KERNEL::AutoPtr dt_unit=new char[MED_LNAME_SIZE+1]; - med_int nbPdt; - med_bool localmesh; - MEDFILESAFECALLERRD0(MEDfieldInfo,(fid,i+1,nomcha,maa_ass,&localmesh,&typcha,comp,unit,dt_unit,&nbPdt)); - ret.push_back(std::string(nomcha)); - } - return ret; -} - -std::vector MEDLoader::GetAllFieldNamesOnMesh(const std::string& fileName, const std::string& meshName) -{ - CheckFileForRead(fileName); - std::vector ret; - MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName.c_str(),MED_ACC_RDONLY); - med_int nbFields=MEDnField(fid); - // - med_field_type typcha; - char *maa_ass=MEDLoaderBase::buildEmptyString(MED_NAME_SIZE); - char *nomcha=MEDLoaderBase::buildEmptyString(MED_NAME_SIZE); - // - for(int i=0;i comp=new char[ncomp*MED_SNAME_SIZE+1]; - INTERP_KERNEL::AutoPtr unit=new char[ncomp*MED_SNAME_SIZE+1]; - INTERP_KERNEL::AutoPtr dt_unit=new char[MED_LNAME_SIZE+1]; - med_int nbPdt; - med_bool localmesh; - MEDFILESAFECALLERRD0(MEDfieldInfo,(fid,i+1,nomcha,maa_ass,&localmesh,&typcha,comp,unit,dt_unit,&nbPdt)); - std::string curFieldName=MEDLoaderBase::buildStringFromFortran(nomcha,MED_NAME_SIZE+1); - std::string curMeshName=MEDLoaderBase::buildStringFromFortran(maa_ass,MED_NAME_SIZE+1); - // - if(curMeshName==meshName) - ret.push_back(curFieldName); - } - delete [] maa_ass; - delete [] nomcha; - return ret; -} - -std::vector MEDLoader::GetFieldNamesOnMesh(ParaMEDMEM::TypeOfField type, const std::string& fileName, const std::string& meshName) -{ - CheckFileForRead(fileName); - switch(type) - { - case ON_CELLS: - return GetCellFieldNamesOnMesh(fileName,meshName); - case ON_NODES: - return GetNodeFieldNamesOnMesh(fileName,meshName); - default: - throw INTERP_KERNEL::Exception("Type of field specified not managed ! manages are ON_NODES or ON_CELLS !"); - } -} - -std::vector MEDLoader::GetCellFieldNamesOnMesh(const std::string& fileName, const std::string& meshName) -{ - CheckFileForRead(fileName); - std::vector ret; - MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName.c_str(),MED_ACC_RDONLY); - med_int nbFields=MEDnField(fid); - // - med_field_type typcha; - //med_int nbpdtnor=0,pflsize,*pflval,lnsize; - med_int numdt=0,numo=0; - med_float dt=0.0; - char pflname[MED_NAME_SIZE+1]=""; - char locname[MED_NAME_SIZE+1]=""; - INTERP_KERNEL::AutoPtr maa_ass=MEDLoaderBase::buildEmptyString(MED_NAME_SIZE); - INTERP_KERNEL::AutoPtr dt_unit=MEDLoaderBase::buildEmptyString(MED_LNAME_SIZE); - INTERP_KERNEL::AutoPtr nomcha=MEDLoaderBase::buildEmptyString(MED_NAME_SIZE); - med_bool localmesh; - med_int nbPdt; - // - for(int i=0;i comp=new char[ncomp*MED_SNAME_SIZE+1]; - INTERP_KERNEL::AutoPtr unit=new char[ncomp*MED_SNAME_SIZE+1]; - MEDFILESAFECALLERRD0(MEDfieldInfo,(fid,i+1,nomcha,maa_ass,&localmesh,&typcha,comp,unit,dt_unit,&nbPdt)); - std::string curFieldName=MEDLoaderBase::buildStringFromFortran(nomcha,MED_NAME_SIZE+1); - std::string curMeshName=MEDLoaderBase::buildStringFromFortran(maa_ass,MED_NAME_SIZE+1); - int profilesize,nbi; - if(curMeshName==meshName) - { - bool found=false; - for(int j=0;j0) - { - MEDFILESAFECALLERRD0(MEDfieldComputingStepInfo,(fid,nomcha,1,&numdt,&numo,&dt)); - med_int nbOfVal(MEDfieldnValueWithProfile(fid,nomcha,numdt,numo,MED_CELL,typmai[j],1,MED_COMPACT_PFLMODE, - pflname,&profilesize,locname,&nbi)); - if(nbOfVal>0) - { - found=true; - ret.push_back(curFieldName); - } - } - } - } - } - return ret; -} - -std::vector MEDLoader::GetNodeFieldNamesOnMesh(const std::string& fileName, const std::string& meshName) -{ - CheckFileForRead(fileName); - std::vector ret; - MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName.c_str(),MED_ACC_RDONLY); - med_int nbFields=MEDnField(fid); - char pflname[MED_NAME_SIZE+1]=""; - char locname[MED_NAME_SIZE+1]=""; - // - med_field_type typcha; - med_int numdt=0,numo=0; - med_float dt=0.0; - INTERP_KERNEL::AutoPtr maa_ass=MEDLoaderBase::buildEmptyString(MED_NAME_SIZE); - INTERP_KERNEL::AutoPtr dt_unit=MEDLoaderBase::buildEmptyString(MED_LNAME_SIZE); - INTERP_KERNEL::AutoPtr nomcha=MEDLoaderBase::buildEmptyString(MED_NAME_SIZE); - med_bool localmesh; - // - for(int i=0;i comp=new char[ncomp*MED_SNAME_SIZE+1]; - INTERP_KERNEL::AutoPtr unit=new char[ncomp*MED_SNAME_SIZE+1]; - med_int nbPdt; - MEDFILESAFECALLERRD0(MEDfieldInfo,(fid,i+1,nomcha,maa_ass,&localmesh,&typcha,comp,unit,dt_unit,&nbPdt)); - std::string curFieldName=MEDLoaderBase::buildStringFromFortran(nomcha,MED_NAME_SIZE+1); - std::string curMeshName=MEDLoaderBase::buildStringFromFortran(maa_ass,MED_NAME_SIZE+1); - if(nbPdt>0) - { - int profilesize,nbi; - MEDFILESAFECALLERRD0(MEDfieldComputingStepInfo,(fid,nomcha,1,&numdt,&numo,&dt)); - med_int nbOfVal(MEDfieldnValueWithProfile(fid,nomcha,numdt,numo,MED_NODE,MED_NONE,1,MED_COMPACT_PFLMODE, - pflname,&profilesize,locname,&nbi)); - if(curMeshName==meshName && nbOfVal>0) - { - ret.push_back(curFieldName); - } - } - } - return ret; -} - -std::vector< std::pair< std::pair, double> > MEDLoader::GetAllFieldIterations(const std::string& fileName, const std::string& fieldName) -{ - CheckFileForRead(fileName); - std::vector< std::pair< std::pair, double > > ret; - MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName.c_str(),MED_ACC_RDONLY); - med_int nbFields=MEDnField(fid); - // - med_field_type typcha; - med_int numdt=0,numo=0; - med_float dt=0.0; - INTERP_KERNEL::AutoPtr maa_ass=MEDLoaderBase::buildEmptyString(MED_NAME_SIZE); - INTERP_KERNEL::AutoPtr dt_unit=MEDLoaderBase::buildEmptyString(MED_LNAME_SIZE); - INTERP_KERNEL::AutoPtr nomcha=MEDLoaderBase::buildEmptyString(MED_NAME_SIZE); - med_bool localmesh; - // - std::ostringstream oss; oss << "MEDLoader::GetAllFieldIterations : No field with name \"" << fieldName<< "\" in file \"" << fileName << "\" ! Possible fields are : "; - for(int i=0;i comp=new char[ncomp*MED_SNAME_SIZE+1]; - INTERP_KERNEL::AutoPtr unit=new char[ncomp*MED_SNAME_SIZE+1]; - med_int nbPdt; - MEDFILESAFECALLERRD0(MEDfieldInfo,(fid,i+1,nomcha,maa_ass,&localmesh,&typcha,comp,unit,dt_unit,&nbPdt)); - std::string curFieldName=MEDLoaderBase::buildStringFromFortran(nomcha,MED_NAME_SIZE+1); - if(curFieldName==fieldName) - { - for(int k=0;k maa_ass=MEDLoaderBase::buildEmptyString(MED_NAME_SIZE); - INTERP_KERNEL::AutoPtr dt_unit=MEDLoaderBase::buildEmptyString(MED_LNAME_SIZE); - INTERP_KERNEL::AutoPtr nomcha=MEDLoaderBase::buildEmptyString(MED_NAME_SIZE); - // - bool found=false; - bool found2=false; - double ret=std::numeric_limits::max(); - for(int i=0;i comp=new char[ncomp*MED_SNAME_SIZE+1]; - INTERP_KERNEL::AutoPtr unit=new char[ncomp*MED_SNAME_SIZE+1]; - med_int nbPdt; - MEDFILESAFECALLERRD0(MEDfieldInfo,(fid,i+1,nomcha,maa_ass,&local,&typcha,comp,unit,dt_unit,&nbPdt)); - std::string curFieldName=MEDLoaderBase::buildStringFromFortran(nomcha,MED_NAME_SIZE+1); - if(curFieldName==fieldName) - { - found=true; - for(int k=0;k > MEDLoader::GetFieldIterations(ParaMEDMEM::TypeOfField type, const std::string& fileName, const std::string& meshName, const std::string& fieldName) -{ - CheckFileForRead(fileName); - switch(type) - { - case ON_CELLS: - return GetCellFieldIterations(fileName,meshName,fieldName); - case ON_NODES: - return GetNodeFieldIterations(fileName,meshName,fieldName); - default: - throw INTERP_KERNEL::Exception("Type of field specified not managed ! manages are ON_NODES or ON_CELLS !"); - } -} - -std::vector< std::pair > MEDLoader::GetCellFieldIterations(const std::string& fileName, const std::string& meshName, const std::string& fieldName) -{ - CheckFileForRead(fileName); - std::string meshNameCpp(meshName); - std::vector< std::pair > ret; - MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName.c_str(),MED_ACC_RDONLY); - med_int nbFields=MEDnField(fid); - // - med_field_type typcha; - med_int numdt=0,numo=0; - med_float dt=0.0; - char pflname[MED_NAME_SIZE+1]=""; - char locname[MED_NAME_SIZE+1]=""; - INTERP_KERNEL::AutoPtr maa_ass=MEDLoaderBase::buildEmptyString(MED_NAME_SIZE); - INTERP_KERNEL::AutoPtr dt_unit=MEDLoaderBase::buildEmptyString(MED_LNAME_SIZE); - INTERP_KERNEL::AutoPtr nomcha=MEDLoaderBase::buildEmptyString(MED_NAME_SIZE); - med_bool localmesh; - // - std::ostringstream oss; oss << "MEDLoader::GetCellFieldIterations : No cell Field field with name \"" << fieldName<< "\" in file \"" << fileName << "\" ! Possible fields are : "; - std::set s2; - for(int i=0;i comp=new char[ncomp*MED_SNAME_SIZE+1]; - INTERP_KERNEL::AutoPtr unit=new char[ncomp*MED_SNAME_SIZE+1]; - med_int nbPdt; - MEDFILESAFECALLERRD0(MEDfieldInfo,(fid,i+1,nomcha,maa_ass,&localmesh,&typcha,comp,unit,dt_unit,&nbPdt)); - std::string curFieldName=MEDLoaderBase::buildStringFromFortran(nomcha,MED_NAME_SIZE+1); - if(curFieldName==fieldName) - { - bool found=false; - for(int j=0;j0) - { - if(meshNameCpp==maa_ass_cpp) - { - found=true; - ret.push_back(std::make_pair(numdt,numo)); - } - else - s2.insert(maa_ass_cpp); - } - } - } - } - else - { - oss << "\"" << curFieldName << "\""; - if(i!=nbFields-1) oss << ", "; - } - } - if(ret.empty()) - { - if(!s2.empty()) - { - oss << ". Cell Field \"" << fieldName << "\" exists but lies on meshes with names : \""; - std::copy(s2.begin(),s2.end(),std::ostream_iterator(oss,"\", \"")); - } - oss << " !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - return ret; -} - -std::vector< std::pair > MEDLoader::GetNodeFieldIterations(const std::string& fileName, const std::string& meshName, const std::string& fieldName) -{ - CheckFileForRead(fileName); - std::string meshNameCpp(meshName); - std::vector< std::pair > ret; - MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName.c_str(),MED_ACC_RDONLY); - med_int nbFields=MEDnField(fid); - // - med_field_type typcha; - med_int numdt=0,numo=0; - med_float dt=0.0; - char pflname[MED_NAME_SIZE+1]=""; - char locname[MED_NAME_SIZE+1]=""; - INTERP_KERNEL::AutoPtr maa_ass=MEDLoaderBase::buildEmptyString(MED_NAME_SIZE); - INTERP_KERNEL::AutoPtr dt_unit=MEDLoaderBase::buildEmptyString(MED_LNAME_SIZE); - INTERP_KERNEL::AutoPtr nomcha=MEDLoaderBase::buildEmptyString(MED_NAME_SIZE); - med_bool localmesh; - // - std::ostringstream oss; oss << "MEDLoader::GetNodeFieldIterations : No node Field field with name \"" << fieldName<< "\" in file \"" << fileName << "\" ! Possible fields are : "; - std::set s2; - for(int i=0;i comp=new char[ncomp*MED_SNAME_SIZE+1]; - INTERP_KERNEL::AutoPtr unit=new char[ncomp*MED_SNAME_SIZE+1]; - med_int nbPdt; - MEDFILESAFECALLERRD0(MEDfieldInfo,(fid,i+1,nomcha,maa_ass,&localmesh,&typcha,comp,unit,dt_unit,&nbPdt)); - std::string curFieldName=MEDLoaderBase::buildStringFromFortran(nomcha,MED_NAME_SIZE+1); - if(curFieldName==fieldName) - { - for(int k=0;k0) - { - if(meshNameCpp==maa_ass_cpp) - { ret.push_back(std::make_pair(numdt,numo)); } - else - s2.insert(maa_ass_cpp); - } - } - } - else - { - oss << "\"" << curFieldName << "\""; - if(i!=nbFields-1) oss << ", "; - } - } - if(ret.empty()) - { - if(!s2.empty()) - { - oss << ". Node Field \"" << fieldName << "\" exists but lies on meshes with names : \""; - std::copy(s2.begin(),s2.end(),std::ostream_iterator(oss,"\", \"")); - } - oss << " !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - return ret; -} - -ParaMEDMEM::MEDCouplingMesh *MEDLoader::ReadMeshFromFile(const std::string& fileName, const std::string& meshName, int meshDimRelToMax) -{ - CheckFileForRead(fileName); - MEDCouplingAutoRefCountObjectPtr mm(MEDFileMesh::New(fileName,meshName)); - MEDFileMesh *mmPtr(mm); - MEDFileUMesh *mmuPtr=dynamic_cast(mmPtr); - if(mmuPtr) - return mmuPtr->getMeshAtLevel(meshDimRelToMax,true); - MEDFileCMesh *mmcPtr=dynamic_cast(mmPtr); - if(mmcPtr) - { - const MEDCouplingCMesh *ret(mmcPtr->getMesh()); ret->incrRef(); - return const_cast(ret); - } - MEDFileCurveLinearMesh *mmc2Ptr=dynamic_cast(mmPtr); - if(mmc2Ptr) - { - const MEDCouplingCurveLinearMesh *ret(mmc2Ptr->getMesh()); ret->incrRef(); - return const_cast(ret); - } - std::ostringstream oss; oss << "MEDLoader::ReadMeshFromFile : The mesh \"" << meshName << "\" in file \"" << fileName << "\" has not a recognized type !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); -} - -ParaMEDMEM::MEDCouplingMesh *MEDLoader::ReadMeshFromFile(const std::string& fileName, int meshDimRelToMax) -{ - CheckFileForRead(fileName); - MEDCouplingAutoRefCountObjectPtr mm(MEDFileMesh::New(fileName)); - MEDFileMesh *mmPtr(mm); - MEDFileUMesh *mmuPtr=dynamic_cast(mmPtr); - if(mmuPtr) - return mmuPtr->getMeshAtLevel(meshDimRelToMax,true); - MEDFileCMesh *mmcPtr=dynamic_cast(mmPtr); - if(mmcPtr) - { - const MEDCouplingCMesh *ret(mmcPtr->getMesh()); ret->incrRef(); - return const_cast(ret); - } - MEDFileCurveLinearMesh *mmc2Ptr=dynamic_cast(mmPtr); - if(mmc2Ptr) - { - const MEDCouplingCurveLinearMesh *ret(mmc2Ptr->getMesh()); ret->incrRef(); - return const_cast(ret); - } - std::ostringstream oss; oss << "MEDLoader::ReadMeshFromFile (2) : The first mesh \"" << mm->getName() << "\" in file \"" << fileName << "\" has not a recognized type !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); -} - -ParaMEDMEM::MEDCouplingUMesh *MEDLoader::ReadUMeshFromFile(const std::string& fileName, const std::string& meshName, int meshDimRelToMax) -{ - CheckFileForRead(fileName); - MEDCouplingAutoRefCountObjectPtr mm(MEDFileMesh::New(fileName,meshName)); - MEDFileMesh *mmPtr(mm); - MEDFileUMesh *mmuPtr=dynamic_cast(mmPtr); - if(!mmuPtr) - { - std::ostringstream oss; oss << "MEDLoader::ReadUMeshFromFile : With fileName=\""<< fileName << "\", meshName=\""<< meshName << "\" exists but it is not an unstructured mesh !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - return mmuPtr->getMeshAtLevel(meshDimRelToMax,true); -} - -ParaMEDMEM::MEDCouplingUMesh *MEDLoader::ReadUMeshFromFile(const std::string& fileName, int meshDimRelToMax) -{ - CheckFileForRead(fileName); - MEDCouplingAutoRefCountObjectPtr mm(MEDFileMesh::New(fileName)); - MEDFileMesh *mmPtr(mm); - MEDFileUMesh *mmuPtr=dynamic_cast(mmPtr); - if(!mmuPtr) - { - std::ostringstream oss; oss << "MEDLoader::ReadUMeshFromFile : With fileName=\""<< fileName << "\", meshName (the first) =\""<< mm->getName() << "\" exists but it is not an unstructured mesh !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - return mmuPtr->getMeshAtLevel(meshDimRelToMax,true); -} - -int MEDLoader::ReadUMeshDimFromFile(const std::string& fileName, const std::string& meshName) -{ - CheckFileForRead(fileName); - std::vector poss; - return MEDLoaderNS::readUMeshDimFromFile(fileName,meshName,poss); -} - -ParaMEDMEM::MEDCouplingUMesh *MEDLoader::ReadUMeshFromFamilies(const std::string& fileName, const std::string& meshName, int meshDimRelToMax, const std::vector& fams) -{ - CheckFileForRead(fileName); - MEDCouplingAutoRefCountObjectPtr mm(MEDFileMesh::New(fileName,meshName)); - MEDFileMesh *mmPtr(mm); - MEDFileUMesh *mmuPtr=dynamic_cast(mmPtr); - if(!mmuPtr) - { - std::ostringstream oss; oss << "MEDLoader::ReadUMeshFromFamilies : With fileName=\""<< fileName << "\", meshName (the first) =\""<< mm->getName() << "\" exists but it is not an unstructured mesh !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - return mmuPtr->getFamilies(meshDimRelToMax,fams,true); -} - -ParaMEDMEM::MEDCouplingUMesh *MEDLoader::ReadUMeshFromGroups(const std::string& fileName, const std::string& meshName, int meshDimRelToMax, const std::vector& grps) -{ - CheckFileForRead(fileName); - MEDCouplingAutoRefCountObjectPtr mm=MEDFileMesh::New(fileName,meshName); - MEDFileMesh *mmPtr(mm); - MEDFileUMesh *mmuPtr=dynamic_cast(mmPtr); - if(!mmuPtr) - { - std::ostringstream oss; oss << "MEDLoader::ReadUMeshFromGroups : With fileName=\""<< fileName << "\", meshName (the first) =\""<< mm->getName() << "\" exists but it is not an unstructured mesh !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - return mmuPtr->getGroups(meshDimRelToMax,grps,true); -} - -ParaMEDMEM::MEDCouplingFieldDouble *MEDLoader::ReadField(ParaMEDMEM::TypeOfField type, const std::string& fileName, const std::string& meshName, int meshDimRelToMax, const std::string& fieldName, int iteration, int order) -{ - CheckFileForRead(fileName); - switch(type) - { - case ON_CELLS: - return ReadFieldCell(fileName,meshName,meshDimRelToMax,fieldName,iteration,order); - case ON_NODES: - return ReadFieldNode(fileName,meshName,meshDimRelToMax,fieldName,iteration,order); - case ON_GAUSS_PT: - return ReadFieldGauss(fileName,meshName,meshDimRelToMax,fieldName,iteration,order); - case ON_GAUSS_NE: - return ReadFieldGaussNE(fileName,meshName,meshDimRelToMax,fieldName,iteration,order); - default: - throw INTERP_KERNEL::Exception("Type of field specified not managed ! manages are ON_NODES, ON_CELLS, ON_GAUSS_PT or ON_GAUSS_NE !"); - } -} - -std::vector MEDLoader::ReadFieldsOnSameMesh(ParaMEDMEM::TypeOfField type, const std::string& fileName, const std::string& meshName, int meshDimRelToMax, const std::string& fieldName, - const std::vector >& its) -{ - if(its.empty()) - return std::vector(); - CheckFileForRead(fileName); - std::vector ret(its.size()); - std::vector< MEDCouplingAutoRefCountObjectPtr > retSafe(its.size()); - if(its.empty()) - return ret; - //Retrieving mesh of rank 0 and field on rank 0 too. - MEDCouplingAutoRefCountObjectPtr mm=MEDFileMesh::New(fileName,meshName); - MEDFileMesh *mmPtr(mm); - MEDFileUMesh *mmuPtr=dynamic_cast(mmPtr); - if(!mmuPtr) - throw INTERP_KERNEL::Exception("MEDLoader::ReadFieldsOnSameMesh : only unstructured mesh is managed !"); - MEDCouplingAutoRefCountObjectPtr m=mmuPtr->getMeshAtLevel(meshDimRelToMax); - const DataArrayInt *o2n=mmuPtr->getNumberFieldAtLevel(meshDimRelToMax); - MEDCouplingAutoRefCountObjectPtr m2(m->clone(true)); - if(o2n) - m2->renumberCells(o2n->begin(),true); - int i=0; - for(std::vector >::const_iterator it=its.begin();it!=its.end();it++,i++) - { - MEDCouplingAutoRefCountObjectPtr ff=MEDFileField1TS::New(fileName,fieldName,(*it).first,(*it).second); - MEDCouplingAutoRefCountObjectPtr retElt=ff->getFieldOnMeshAtLevel(type,m); - if(o2n) - retElt->renumberCells(o2n->begin(),true); - retElt->setMesh(m2); - retSafe[i]=retElt; - } - i=0; - for(std::vector >::const_iterator it=its.begin();it!=its.end();it++,i++) - ret[i]=retSafe[i].retn(); - return ret; -} - -std::vector MEDLoader::ReadFieldsCellOnSameMesh(const std::string& fileName, const std::string& meshName, int meshDimRelToMax, const std::string& fieldName, - const std::vector >& its) -{ - return ReadFieldsOnSameMesh(ON_CELLS,fileName,meshName,meshDimRelToMax,fieldName,its); -} - -std::vector MEDLoader::ReadFieldsNodeOnSameMesh(const std::string& fileName, const std::string& meshName, int meshDimRelToMax, const std::string& fieldName, - const std::vector >& its) -{ - return ReadFieldsOnSameMesh(ON_NODES,fileName,meshName,meshDimRelToMax,fieldName,its); -} - -std::vector MEDLoader::ReadFieldsGaussOnSameMesh(const std::string& fileName, const std::string& meshName, int meshDimRelToMax, const std::string& fieldName, - const std::vector >& its) -{ - return ReadFieldsOnSameMesh(ON_GAUSS_PT,fileName,meshName,meshDimRelToMax,fieldName,its); -} - -std::vector MEDLoader::ReadFieldsGaussNEOnSameMesh(const std::string& fileName, const std::string& meshName, int meshDimRelToMax, const std::string& fieldName, - const std::vector >& its) -{ - return ReadFieldsOnSameMesh(ON_GAUSS_NE,fileName,meshName,meshDimRelToMax,fieldName,its); -} - -ParaMEDMEM::MEDCouplingFieldDouble *MEDLoader::ReadFieldCell(const std::string& fileName, const std::string& meshName, int meshDimRelToMax, const std::string& fieldName, int iteration, int order) -{ - MEDCouplingAutoRefCountObjectPtr ff=MEDFileField1TS::New(fileName,fieldName,iteration,order); - MEDCouplingAutoRefCountObjectPtr mm=MEDFileMesh::New(fileName,meshName); - MEDCouplingAutoRefCountObjectPtr m=mm->getGenMeshAtLevel(meshDimRelToMax,false); - MEDFileMesh *mPtr(mm); - MEDFileUMesh *muPtr=dynamic_cast(mPtr); - MEDCouplingAutoRefCountObjectPtr ret=ff->getFieldOnMeshAtLevel(ON_CELLS,m); - if(muPtr) - { - const DataArrayInt *num=muPtr->getNumberFieldAtLevel(meshDimRelToMax); - if(num) - ret->renumberCells(num->begin()); - } - return ret.retn(); -} - -ParaMEDMEM::MEDCouplingFieldDouble *MEDLoader::ReadFieldNode(const std::string& fileName, const std::string& meshName, int meshDimRelToMax, const std::string& fieldName, int iteration, int order) -{ - MEDCouplingAutoRefCountObjectPtr ff=MEDFileField1TS::New(fileName,fieldName,iteration,order); - MEDCouplingAutoRefCountObjectPtr mm=MEDFileMesh::New(fileName,meshName); - MEDCouplingAutoRefCountObjectPtr m=mm->getGenMeshAtLevel(meshDimRelToMax,false); - MEDFileMesh *mPtr(mm); - MEDCouplingAutoRefCountObjectPtr ret=ff->getFieldOnMeshAtLevel(ON_NODES,m); - MEDFileUMesh *muPtr=dynamic_cast(mPtr); - if(ff->getPflsReallyUsed().empty()) - { - if(muPtr) - { - const DataArrayInt *num=muPtr->getNumberFieldAtLevel(meshDimRelToMax); - if(num) - ret->renumberCells(num->begin()); - } - } - else - { - DataArrayInt *pfl=0,*arr2=0; - MEDCouplingAutoRefCountObjectPtr arr=ff->getFieldWithProfile(ON_NODES,meshDimRelToMax,mm,pfl); - MEDCouplingAutoRefCountObjectPtr pflSafe(pfl); - MEDCouplingAutoRefCountObjectPtr mp=m->getCellIdsFullyIncludedInNodeIds(pfl->begin(),pfl->end()); - MEDCouplingAutoRefCountObjectPtr mzip=static_cast(m->buildPartAndReduceNodes(mp->begin(),mp->end(),arr2)); - MEDCouplingAutoRefCountObjectPtr arr2Safe(arr2); - MEDCouplingAutoRefCountObjectPtr arr3=arr2->invertArrayO2N2N2O(mzip->getNumberOfNodes()); - MEDCouplingAutoRefCountObjectPtr pflSorted(pflSafe->deepCpy()); pflSorted->sort(true); - if(!arr3->isEqualWithoutConsideringStr(*pflSorted)) - throw INTERP_KERNEL::Exception("MEDLoader::ReadFieldNode : not implemented yet !"); - if(!arr3->isEqualWithoutConsideringStr(*pflSafe)) - { - MEDCouplingAutoRefCountObjectPtr o2n2=pflSafe->checkAndPreparePermutation(); - MEDCouplingAutoRefCountObjectPtr n2o2=o2n2->invertArrayO2N2N2O(o2n2->getNumberOfTuples()); - mzip->renumberNodes(n2o2->begin(),n2o2->getNumberOfTuples()); - arr->setName(""); - ret->setArray(arr); - } - ret->setMesh(mzip); - } - return ret.retn(); -} - -ParaMEDMEM::MEDCouplingFieldDouble *MEDLoader::ReadFieldGauss(const std::string& fileName, const std::string& meshName, int meshDimRelToMax, const std::string& fieldName, int iteration, int order) -{ - MEDCouplingAutoRefCountObjectPtr ff=MEDFileField1TS::New(fileName,fieldName,iteration,order); - MEDCouplingAutoRefCountObjectPtr mm=MEDFileMesh::New(fileName,meshName); - MEDCouplingAutoRefCountObjectPtr m=mm->getGenMeshAtLevel(meshDimRelToMax,false); - MEDFileMesh *mPtr(mm); - MEDFileUMesh *muPtr=dynamic_cast(mPtr); - MEDCouplingAutoRefCountObjectPtr ret=ff->getFieldOnMeshAtLevel(ON_GAUSS_PT,m); - if(muPtr) - { - const DataArrayInt *num=muPtr->getNumberFieldAtLevel(meshDimRelToMax); - if(num) - ret->renumberCells(num->begin()); - } - return ret.retn(); -} - -ParaMEDMEM::MEDCouplingFieldDouble *MEDLoader::ReadFieldGaussNE(const std::string& fileName, const std::string& meshName, int meshDimRelToMax, const std::string& fieldName, int iteration, int order) -{ - MEDCouplingAutoRefCountObjectPtr ff=MEDFileField1TS::New(fileName,fieldName,iteration,order); - MEDCouplingAutoRefCountObjectPtr mm=MEDFileMesh::New(fileName,meshName); - MEDCouplingAutoRefCountObjectPtr m=mm->getGenMeshAtLevel(meshDimRelToMax,false); - MEDFileMesh *mPtr(mm); - MEDFileUMesh *muPtr=dynamic_cast(mPtr); - MEDCouplingAutoRefCountObjectPtr ret=ff->getFieldOnMeshAtLevel(ON_GAUSS_NE,m); - if(muPtr) - { - const DataArrayInt *num=muPtr->getNumberFieldAtLevel(meshDimRelToMax); - if(num) - ret->renumberCells(num->begin()); - } - return ret.retn(); -} - -void MEDLoader::WriteMesh(const std::string& fileName, const ParaMEDMEM::MEDCouplingMesh *mesh, bool writeFromScratch) -{ - if(!mesh) - throw INTERP_KERNEL::Exception("MEDLoader::WriteMesh : input mesh is null !"); - const MEDCouplingUMesh *um(dynamic_cast(mesh)); - if(um) - { - WriteUMesh(fileName,um,writeFromScratch); - return ; - } - int mod=writeFromScratch?2:0; - const MEDCoupling1GTUMesh *um2(dynamic_cast(mesh)); - if(um2) - { - MEDCouplingAutoRefCountObjectPtr mmu(MEDFileUMesh::New()); - AssignStaticWritePropertiesTo(*mmu); - mmu->setMeshAtLevel(0,const_cast(um2)); - mmu->write(fileName,mod); - return ; - } - const MEDCouplingCMesh *um3(dynamic_cast(mesh)); - if(um3) - { - MEDCouplingAutoRefCountObjectPtr mmc(MEDFileCMesh::New()); - AssignStaticWritePropertiesTo(*mmc); - mmc->setMesh(const_cast(um3)); - mmc->write(fileName,mod); - return ; - } - const MEDCouplingCurveLinearMesh *um4(dynamic_cast(mesh)); - if(um4) - { - MEDCouplingAutoRefCountObjectPtr mmc(MEDFileCurveLinearMesh::New()); - AssignStaticWritePropertiesTo(*mmc); - mmc->setMesh(const_cast(um4)); - mmc->write(fileName,mod); - return ; - } - throw INTERP_KERNEL::Exception("MEDLoader::WriteMesh : only MEDCouplingUMesh, MEDCoupling1GTUMesh, MEDCouplingCMesh, MEDCouplingCurveLinear are dealed in this API for the moment !"); -} - -void MEDLoader::WriteUMesh(const std::string& fileName, const ParaMEDMEM::MEDCouplingUMesh *mesh, bool writeFromScratch) -{ - if(!mesh) - throw INTERP_KERNEL::Exception("MEDLoader::WriteUMesh : input mesh is null !"); - int mod=writeFromScratch?2:0; - MEDCouplingAutoRefCountObjectPtr m(MEDFileUMesh::New()); - AssignStaticWritePropertiesTo(*m); - MEDCouplingAutoRefCountObjectPtr mcpy(static_cast(mesh->deepCpy())); - m->setMeshAtLevel(0,mcpy,true); - m->write(fileName,mod); -} - -void MEDLoader::WriteUMeshDep(const std::string& fileName, const ParaMEDMEM::MEDCouplingUMesh *mesh, bool writeFromScratch) -{ - MEDLoader::WriteUMesh(fileName,mesh,writeFromScratch); -} - -void MEDLoader::WriteUMeshesPartition(const std::string& fileName, const std::string& meshNameC, const std::vector& meshes, bool writeFromScratch) -{ - std::string meshName(meshNameC); - if(meshName.empty()) - throw INTERP_KERNEL::Exception("Trying to write a unstructured mesh with no name ! MED file format needs a not empty mesh name : change 2nd parameter !"); - int status=MEDLoaderBase::getStatusOfFile(fileName); - if(status!=MEDLoaderBase::EXIST_RW && status!=MEDLoaderBase::NOT_EXIST) - { - std::ostringstream oss; oss << "File with name \'" << fileName << "\' has not valid permissions !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - MEDCouplingAutoRefCountObjectPtr m(MEDFileUMesh::New()); - AssignStaticWritePropertiesTo(*m); - m->setGroupsFromScratch(0,meshes,true); - m->setName(meshNameC); - int mod=writeFromScratch?2:0; - m->write(fileName,mod); -} - -void MEDLoader::WriteUMeshesPartitionDep(const std::string& fileName, const std::string& meshNameC, const std::vector& meshes, bool writeFromScratch) -{ - WriteUMeshesPartition(fileName,meshNameC,meshes,writeFromScratch); -} - -void MEDLoader::WriteUMeshes(const std::string& fileName, const std::vector& meshes, bool writeFromScratch) -{ - int mod=writeFromScratch?2:0; - MEDCouplingAutoRefCountObjectPtr m(MEDFileUMesh::New()); - AssignStaticWritePropertiesTo(*m); - m->setMeshes(meshes,true); - m->write(fileName,mod); -} - -void MEDLoaderNS::writeFieldWithoutReadingAndMappingOfMeshInFile(const std::string& fileName, const ParaMEDMEM::MEDCouplingFieldDouble *f, bool writeFromScratch) -{ - MEDCouplingAutoRefCountObjectPtr ff(MEDFileField1TS::New()); - MEDLoader::AssignStaticWritePropertiesTo(*ff); - MEDCouplingAutoRefCountObjectPtr f2(f->deepCpy()); - const MEDCouplingMesh *m(f2->getMesh()); - const MEDCouplingUMesh *um(dynamic_cast(m)); - const MEDCoupling1GTUMesh *um2(dynamic_cast(m)); - const MEDCouplingCMesh *um3(dynamic_cast(m)); - const MEDCouplingCurveLinearMesh *um4(dynamic_cast(m)); - MEDCouplingAutoRefCountObjectPtr mm; - int mod=writeFromScratch?2:0; - if(um) - { - MEDCouplingAutoRefCountObjectPtr mmu(MEDFileUMesh::New()); - MEDLoader::AssignStaticWritePropertiesTo(*mmu); - MEDCouplingAutoRefCountObjectPtr o2n(um->getRenumArrForMEDFileFrmt()); - MEDCouplingAutoRefCountObjectPtr n2o(o2n->invertArrayO2N2N2O(o2n->getNumberOfTuples())); - f2->renumberCells(o2n->begin(),false); - mmu->setMeshAtLevel(0,const_cast(static_cast(f2->getMesh()))); - mmu->setRenumFieldArr(0,n2o); - ff->setFieldNoProfileSBT(f2); - mmu->write(fileName,mod); - } - else if(um2) - { - MEDCouplingAutoRefCountObjectPtr mmu(MEDFileUMesh::New()); - MEDLoader::AssignStaticWritePropertiesTo(*mmu); - mmu->setMeshAtLevel(0,const_cast(um2)); - ff->setFieldNoProfileSBT(f2); - mmu->write(fileName,mod); - } - else if(um3) - { - MEDCouplingAutoRefCountObjectPtr mmc(MEDFileCMesh::New()); - MEDLoader::AssignStaticWritePropertiesTo(*mmc); - mmc->setMesh(const_cast(um3)); - ff->setFieldNoProfileSBT(f2); - mmc->write(fileName,mod); - } - else if(um4) - { - MEDCouplingAutoRefCountObjectPtr mmc(MEDFileCurveLinearMesh::New()); - MEDLoader::AssignStaticWritePropertiesTo(*mmc); - mmc->setMesh(const_cast(um4)); - ff->setFieldNoProfileSBT(f2); - mmc->write(fileName,mod); - } - else - throw INTERP_KERNEL::Exception("MEDLoaderNS::writeFieldWithoutReadingAndMappingOfMeshInFile : only MEDCouplingUMesh, MEDCoupling1GTUMesh, MEDCouplingCMesh, MEDCouplingCurveLinear are dealed in this API for the moment !"); - ff->write(fileName,0); -} - -void MEDLoader::WriteField(const std::string& fileName, const ParaMEDMEM::MEDCouplingFieldDouble *f, bool writeFromScratch) -{ - if(!f) - throw INTERP_KERNEL::Exception("MEDLoader::WriteField : input field is NULL !"); - f->checkCoherency(); - int status=MEDLoaderBase::getStatusOfFile(fileName); - if(status!=MEDLoaderBase::EXIST_RW && status!=MEDLoaderBase::NOT_EXIST) - { - std::ostringstream oss; oss << "File with name \'" << fileName << "\' has not valid permissions !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - if(writeFromScratch || (!writeFromScratch && status==MEDLoaderBase::NOT_EXIST)) - { - MEDLoaderNS::writeFieldWithoutReadingAndMappingOfMeshInFile(fileName,f,true); - } - else - { - std::vector meshNames=GetMeshNames(fileName); - if(!f->getMesh()) - throw INTERP_KERNEL::Exception("MEDLoader::WriteField : trying to write a field with no mesh !"); - std::string fileNameCpp(f->getMesh()->getName()); - if(std::find(meshNames.begin(),meshNames.end(),fileNameCpp)==meshNames.end()) - MEDLoaderNS::writeFieldWithoutReadingAndMappingOfMeshInFile(fileName,f,false); - else - { - MEDCouplingAutoRefCountObjectPtr mm(MEDFileMesh::New(fileName,f->getMesh()->getName().c_str())); - AssignStaticWritePropertiesTo(*mm); - const MEDFileMesh *mmPtr(mm); - const MEDFileUMesh *mmuPtr=dynamic_cast(mmPtr); - if(!mmuPtr) - throw INTERP_KERNEL::Exception("MEDLoader::WriteField : only umeshes are supported now !"); - MEDCouplingAutoRefCountObjectPtr f2(f->deepCpy()); - MEDCouplingUMesh *m=dynamic_cast(const_cast(f2->getMesh())); - if(!m) - throw INTERP_KERNEL::Exception("MEDLoader::WriteField : only umesh in input field supported !"); - MEDCouplingAutoRefCountObjectPtr o2n=m->getRenumArrForMEDFileFrmt(); - f2->renumberCells(o2n->begin(),false); - m=static_cast(const_cast(f2->getMesh())); - MEDCouplingAutoRefCountObjectPtr mread=mmuPtr->getMeshAtLevel(m->getMeshDimension()-mm->getMeshDimension()); - if(f2->getTypeOfField()!=ON_NODES) - { - m->tryToShareSameCoordsPermute(*mread,_EPS_FOR_NODE_COMP); - DataArrayInt *part=0; - bool b=mread->areCellsIncludedIn(m,_COMP_FOR_CELL,part); - MEDCouplingAutoRefCountObjectPtr partSafe(part); - if(!b) - { - std::ostringstream oss; oss << "MEDLoader::WriteField : The file \""<< fileName << "\" already contains a mesh named \""<< f->getMesh()->getName() << "\" and this mesh in the file is not compatible (a subpart) with the mesh you intend to write ! This is maybe due to a too strict policy ! Try with to lease it by calling SetCompPolicyForCell !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - MEDCouplingAutoRefCountObjectPtr f1ts(MEDFileField1TS::New()); - AssignStaticWritePropertiesTo(*f1ts); - if(part->isIdentity() && part->getNumberOfTuples()==mread->getNumberOfCells()) - f1ts->setFieldNoProfileSBT(f2); - else - { - part->setName(f1ts->createNewNameOfPfl().c_str()); - f1ts->setFieldProfile(f2,mm,m->getMeshDimension()-mm->getMeshDimension(),part); - } - f1ts->write(fileName,0); - return ; - } - else - { - DataArrayInt *part=0; - bool b=mread->getCoords()->areIncludedInMe(m->getCoords(),_EPS_FOR_NODE_COMP,part); - MEDCouplingAutoRefCountObjectPtr partSafe(part); - if(!b) - { - std::ostringstream oss; oss << "MEDLoader::WriteField : The file \""<< fileName << "\" already contains a mesh named \""<< f->getMesh()->getName() << "\" and this mesh in the file is not compatible (a subpart regarding nodes) with the mesh you intend to write ! This is maybe due to a too strict epsilon ! Try with to lease it by calling SetEpsilonForNodeComp !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - MEDCouplingAutoRefCountObjectPtr f1ts(MEDFileField1TS::New()); - AssignStaticWritePropertiesTo(*f1ts); - if(part->isIdentity() && part->getNumberOfTuples()==mread->getNumberOfNodes()) - f1ts->setFieldNoProfileSBT(f2); - else - { - part->setName(f1ts->createNewNameOfPfl().c_str()); - f1ts->setFieldProfile(f2,mm,m->getMeshDimension()-mm->getMeshDimension(),part); - } - f1ts->write(fileName,0); - } - } - } -} - -void MEDLoader::WriteFieldDep(const std::string& fileName, const ParaMEDMEM::MEDCouplingFieldDouble *f, bool writeFromScratch) -{ - WriteField(fileName,f,writeFromScratch); -} - -void MEDLoader::WriteFieldUsingAlreadyWrittenMesh(const std::string& fileName, const ParaMEDMEM::MEDCouplingFieldDouble *f) -{ - if(!f) - throw INTERP_KERNEL::Exception("MEDLoader::WriteFieldUsingAlreadyWrittenMesh : input field is null !"); - f->checkCoherency(); - int status=MEDLoaderBase::getStatusOfFile(fileName); - if(status!=MEDLoaderBase::EXIST_RW) - { - std::ostringstream oss; oss << "File with name \'" << fileName << "\' has not valid permissions or not exists !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - MEDCouplingAutoRefCountObjectPtr f1ts(MEDFileField1TS::New()); - AssignStaticWritePropertiesTo(*f1ts); - MEDCouplingUMesh *m(dynamic_cast(const_cast(f->getMesh()))); - if(m) - { - MEDCouplingAutoRefCountObjectPtr o2n(m->getRenumArrForMEDFileFrmt()); - MEDCouplingAutoRefCountObjectPtr f2(f->deepCpy()); - f2->renumberCells(o2n->begin(),false); - f1ts->setFieldNoProfileSBT(f2); - } - else - f1ts->setFieldNoProfileSBT(f); - f1ts->write(fileName,0); -} diff --git a/src/MEDLoader/MEDLoader.hxx b/src/MEDLoader/MEDLoader.hxx deleted file mode 100644 index df2bfa462..000000000 --- a/src/MEDLoader/MEDLoader.hxx +++ /dev/null @@ -1,111 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 -// 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 __MEDLOADER_HXX__ -#define __MEDLOADER_HXX__ - -#include "MEDLoaderDefines.hxx" -#include "InterpKernelException.hxx" -#include "MEDCouplingRefCountObject.hxx" -#include "NormalizedUnstructuredMesh.hxx" - -#include -#include - -namespace ParaMEDMEM -{ - class DataArrayInt; - class MEDCouplingMesh; - class MEDCouplingUMesh; - class MEDCouplingFieldDouble; - class MEDFileWritable; -} - -class MEDLOADER_EXPORT MEDLoader -{ -public: - static void SetEpsilonForNodeComp(double val); - static void SetCompPolicyForCell(int val); - static void SetTooLongStrPolicy(int val); - static bool HasXDR(); - static std::string MEDFileVersionStr(); - static void MEDFileVersion(int& major, int& minor, int& release); - static void CheckFileForRead(const std::string& fileName); - static std::vector GetMeshNames(const std::string& fileName); - static std::vector< std::vector< std::pair > > GetUMeshGlobalInfo(const std::string& fileName, const std::string& meshName, int &meshDim, int& spaceDim, int& numberOfNodes); - static std::vector< std::pair > GetComponentsNamesOfField(const std::string& fileName, const std::string& fieldName); - static std::vector GetMeshNamesOnField(const std::string& fileName, const std::string& fieldName); - static std::vector GetMeshGroupsNames(const std::string& fileName, const std::string& meshName); - static std::vector GetMeshFamiliesNames(const std::string& fileName, const std::string& meshName); - static std::vector GetMeshFamiliesNamesOnGroup(const std::string& fileName, const std::string& meshName, const std::string& grpName); - static std::vector GetMeshGroupsNamesOnFamily(const std::string& fileName, const std::string& meshName, const std::string& famName); - static std::vector GetAllFieldNames(const std::string& fileName); - static std::vector GetAllFieldNamesOnMesh(const std::string& fileName, const std::string& meshName); - static std::vector GetTypesOfField(const std::string& fileName, const std::string& meshName, const std::string& fieldName); - static std::vector GetFieldNamesOnMesh(ParaMEDMEM::TypeOfField type, const std::string& fileName, const std::string& meshName); - static std::vector GetCellFieldNamesOnMesh(const std::string& fileName, const std::string& meshName); - static std::vector GetNodeFieldNamesOnMesh(const std::string& fileName, const std::string& meshName); - static std::vector< std::pair > GetFieldIterations(ParaMEDMEM::TypeOfField type, const std::string& fileName, const std::string& meshName, const std::string& fieldName); - static std::vector< std::pair > GetCellFieldIterations(const std::string& fileName, const std::string& meshName, const std::string& fieldName); - static std::vector< std::pair > GetNodeFieldIterations(const std::string& fileName, const std::string& meshName, const std::string& fieldName); - static std::vector< std::pair< std::pair, double> > GetAllFieldIterations(const std::string& fileName, const std::string& fieldName); - static double GetTimeAttachedOnFieldIteration(const std::string& fileName, const std::string& fieldName, int iteration, int order); - static ParaMEDMEM::MEDCouplingUMesh *ReadUMeshFromFamilies(const std::string& fileName, const std::string& meshName, int meshDimRelToMax, const std::vector& fams); - static ParaMEDMEM::MEDCouplingUMesh *ReadUMeshFromGroups(const std::string& fileName, const std::string& meshName, int meshDimRelToMax, const std::vector& grps); - static ParaMEDMEM::MEDCouplingMesh *ReadMeshFromFile(const std::string& fileName, const std::string& meshName, int meshDimRelToMax=0); - static ParaMEDMEM::MEDCouplingMesh *ReadMeshFromFile(const std::string& fileName, int meshDimRelToMax=0); - static ParaMEDMEM::MEDCouplingUMesh *ReadUMeshFromFile(const std::string& fileName, const std::string& meshName, int meshDimRelToMax=0); - static ParaMEDMEM::MEDCouplingUMesh *ReadUMeshFromFile(const std::string& fileName, int meshDimRelToMax=0); - static int ReadUMeshDimFromFile(const std::string& fileName, const std::string& meshName); - static ParaMEDMEM::MEDCouplingFieldDouble *ReadField(ParaMEDMEM::TypeOfField type, const std::string& fileName, const std::string& meshName, int meshDimRelToMax, const std::string& fieldName, int iteration, int order); - static std::vector ReadFieldsOnSameMesh(ParaMEDMEM::TypeOfField type, const std::string& fileName, const std::string& meshName, int meshDimRelToMax, const std::string& fieldName, - const std::vector >& its); - static std::vector ReadFieldsCellOnSameMesh(const std::string& fileName, const std::string& meshName, int meshDimRelToMax, const std::string& fieldName, - const std::vector >& its); - static std::vector ReadFieldsNodeOnSameMesh(const std::string& fileName, const std::string& meshName, int meshDimRelToMax, const std::string& fieldName, - const std::vector >& its); - static std::vector ReadFieldsGaussOnSameMesh(const std::string& fileName, const std::string& meshName, int meshDimRelToMax, const std::string& fieldName, - const std::vector >& its); - static std::vector ReadFieldsGaussNEOnSameMesh(const std::string& fileName, const std::string& meshName, int meshDimRelToMax, const std::string& fieldName, - const std::vector >& its); - static ParaMEDMEM::MEDCouplingFieldDouble *ReadFieldCell(const std::string& fileName, const std::string& meshName, int meshDimRelToMax, const std::string& fieldName, int iteration, int order); - static ParaMEDMEM::MEDCouplingFieldDouble *ReadFieldNode(const std::string& fileName, const std::string& meshName, int meshDimRelToMax, const std::string& fieldName, int iteration, int order); - static ParaMEDMEM::MEDCouplingFieldDouble *ReadFieldGauss(const std::string& fileName, const std::string& meshName, int meshDimRelToMax, const std::string& fieldName, int iteration, int order); - static ParaMEDMEM::MEDCouplingFieldDouble *ReadFieldGaussNE(const std::string& fileName, const std::string& meshName, int meshDimRelToMax, const std::string& fieldName, int iteration, int order); - static void WriteMesh(const std::string& fileName, const ParaMEDMEM::MEDCouplingMesh *mesh, bool writeFromScratch); - static void WriteUMesh(const std::string& fileName, const ParaMEDMEM::MEDCouplingUMesh *mesh, bool writeFromScratch); - static void WriteUMeshDep(const std::string& fileName, const ParaMEDMEM::MEDCouplingUMesh *mesh, bool writeFromScratch); - static void WriteUMeshesPartition(const std::string& fileName, const std::string& meshName, const std::vector& meshes, bool writeFromScratch); - static void WriteUMeshesPartitionDep(const std::string& fileName, const std::string& meshName, const std::vector& meshes, bool writeFromScratch); - static void WriteUMeshes(const std::string& fileName, const std::vector& meshes, bool writeFromScratch); - static void WriteField(const std::string& fileName, const ParaMEDMEM::MEDCouplingFieldDouble *f, bool writeFromScratch); - static void WriteFieldDep(const std::string& fileName, const ParaMEDMEM::MEDCouplingFieldDouble *f, bool writeFromScratch); - static void WriteFieldUsingAlreadyWrittenMesh(const std::string& fileName, const ParaMEDMEM::MEDCouplingFieldDouble *f); -public: - static void AssignStaticWritePropertiesTo(ParaMEDMEM::MEDFileWritable& obj); -private: - MEDLoader(); -public: - static double _EPS_FOR_NODE_COMP; - static int _COMP_FOR_CELL; - static int _TOO_LONG_STR; -}; - -#endif diff --git a/src/MEDLoader/MEDLoaderBase.cxx b/src/MEDLoader/MEDLoaderBase.cxx deleted file mode 100644 index 13db3d9d9..000000000 --- a/src/MEDLoader/MEDLoaderBase.cxx +++ /dev/null @@ -1,237 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 -// 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 "MEDLoaderBase.hxx" -#include "InterpKernelException.hxx" - -#include -#include -#include -#include - -const char MEDLoaderBase::WHITE_SPACES[]=" \n"; - -int MEDLoaderBase::getStatusOfFile(const std::string& fileName) -{ - std::ifstream ifs; - ifs.open(fileName.c_str()); - if((ifs.rdstate() & std::ifstream::failbit)!=0) - { - ifs.close(); - return NOT_EXIST; - } - std::ofstream ofs(fileName.c_str(),std::ios_base::app); - if((ofs.rdstate() & std::ofstream::failbit)!=0) - { - return EXIST_RDONLY; - } - return EXIST_RW; -} - -char *MEDLoaderBase::buildEmptyString(int lgth) -{ - char *ret=new char[lgth+1]; - std::fill(ret,ret+lgth,' '); - ret[lgth]='\0'; - return ret; -} - -void MEDLoaderBase::getDirAndBaseName(const std::string& fullName, std::string& dirName, std::string& baseName) -{ - std::size_t pos=fullName.find_last_of(getPathSep()); - if(pos!=std::string::npos) - { - dirName=fullName.substr(0,pos); - baseName=fullName.substr(pos+1); - } - else - { - dirName.clear(); - baseName=fullName; - } -} - -std::string MEDLoaderBase::joinPath(const std::string& dirName, const std::string& baseName) -{ - if(!dirName.empty()) - return dirName+getPathSep()+baseName; - else - return baseName; -} - -std::string MEDLoaderBase::getPathSep() -{ -#ifndef WIN32 - return std::string("/"); -#else - return std::string("\\"); -#endif -} - -std::string MEDLoaderBase::buildUnionUnit(const char *name, int nameLgth, const char *unit, int unitLgth) -{ - std::string ret(buildStringFromFortran(name,nameLgth)); - std::string unitCpp(buildStringFromFortran(unit,unitLgth)); - if(unitCpp.empty() || unitCpp[0]=='\0') - return ret; - ret+=" ["; - ret+=unitCpp; - ret+="]"; - return ret; -} - -void MEDLoaderBase::splitIntoNameAndUnit(const std::string& s, std::string& name, std::string& unit) -{ - std::string::size_type f1=s.find_first_of('['); - std::string::size_type f2=s.find_last_of(']'); - if(f1!=std::string::npos && f2!=std::string::npos) - { - if(f1maxLgth) - { - if(behaviour==0 || behaviour>1) - { - std::ostringstream oss; oss << "A string : \"" << src << "\" has been detected to be too long for MED File ( > " << maxLgth << ") !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - else if(behaviour==1) - { - std::string s=zipString(src,maxLgth); - std::cerr << "A string : \"" << src << "\" has been detected to be too long for MED File ( > " << maxLgth << ") : "; - std::cerr << "zipping to : " << s << "\n"; - strcpy(dest,s.c_str()); - return ; - } - } - strcpy(dest,src); -} - -/*! - * This method is equivalent to MEDLoaderBase::safeStrCpy except that here no '\0' car is put. - * This method should be used for multi string in one string. - */ -void MEDLoaderBase::safeStrCpy2(const char *src, int maxLgth, char *dest, int behaviour) -{ - if((int)strlen(src)>maxLgth) - { - if(behaviour==0 || behaviour>1) - { - std::ostringstream oss; oss << "A string : \"" << src << "\" has been detected to be too long for MED File ( > " << maxLgth << ") !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - else if(behaviour==1) - { - std::string s=zipString(src,maxLgth); - std::cerr << "A string : \"" << src << "\" has been detected to be too long for MED File ( > " << maxLgth << ") : "; - std::cerr << "zipping to : " << s << "\n"; - strcpy(dest,s.c_str()); - return ; - } - } - int n=strlen(src); - strncpy(dest,src,n); -} - -std::string MEDLoaderBase::buildStringFromFortran(const char *expr, int lgth) -{ - std::string ret(expr,lgth); - std::string whiteSpaces(WHITE_SPACES); - std::size_t lgthReal=strlen(ret.c_str()); - std::string ret2=ret.substr(0,lgthReal); - std::size_t found=ret2.find_last_not_of(whiteSpaces); - if (found!=std::string::npos) - ret2.erase(found+1); - else - ret2.clear();//ret is all whitespace - return ret2; -} - -/*! - * This method given the target size to respect 'sizeToRespect' tries to reduce size of 'src' string. - * This method uses several soft methods to do its job. But if it fails a simple cut of string will be performed. - */ -std::string MEDLoaderBase::zipString(const std::string& src, int sizeToRespect) -{ - std::string s(src); - strip(s); - if((int)s.length()<=sizeToRespect) - return s; - s=src; - zipEqualConsChar(s,3); - if((int)s.length()<=sizeToRespect) - return s; - s=src; - zipEqualConsChar(s,2); - if((int)s.length()<=sizeToRespect) - return s; - s=src; - return s.substr(0,sizeToRespect); -} - -/*! - * This method see if there is in 's' more than 'minConsSmChar' consecutive same character. - * If yes, the group will be zipped using only one character for this group. - * If no such group is found, s remains unchanged. - */ -void MEDLoaderBase::zipEqualConsChar(std::string& s, int minConsSmChar) -{ - for(std::string::iterator it=s.begin();it!=s.end();it++) - { - char tmp=*it; - int sz=1; - for(std::string::iterator it2=it+1;it2!=s.end() && *it2==tmp;it2++) - sz++; - if(sz>=minConsSmChar) - s.erase(it+1,it+sz); - } -} - diff --git a/src/MEDLoader/MEDLoaderBase.hxx b/src/MEDLoader/MEDLoaderBase.hxx deleted file mode 100644 index 5ff6cf6e8..000000000 --- a/src/MEDLoader/MEDLoaderBase.hxx +++ /dev/null @@ -1,54 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 -// 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 __MEDLOADERBASE_HXX__ -#define __MEDLOADERBASE_HXX__ - -#include "MEDLoaderDefines.hxx" -#include "InterpKernelException.hxx" - -#include - -class MEDLOADER_EXPORT MEDLoaderBase -{ -public: - static int getStatusOfFile(const std::string& fileName); - static char *buildEmptyString(int lgth); - static void getDirAndBaseName(const std::string& fullName, std::string& dirName, std::string& baseName); - static std::string getPathSep(); - static std::string joinPath(const std::string& dirName, const std::string& baseName); - static std::string buildUnionUnit(const char *name, int nameLgth, const char *unit, int unitLgth); - static void splitIntoNameAndUnit(const std::string& s, std::string& name, std::string& unit); - static void strip(std::string& s); - static void safeStrCpy(const char *src, int maxLgth, char *dest, int behaviour); - static void safeStrCpy2(const char *src, int maxLgth, char *dest, int behaviour); - static std::string buildStringFromFortran(const char *expr, int lgth); - static void zipEqualConsChar(std::string& s, int minConsSmChar); - static std::string zipString(const std::string& src, int sizeToRespect); -public: - static const int EXIST_RW=0; - static const int NOT_EXIST=1; - static const int EXIST_RDONLY=2; - static const int EXIST_WRONLY=3; - static const int DIR_LOCKED=4; - static const char WHITE_SPACES[]; -}; - -#endif diff --git a/src/MEDLoader/MEDLoaderDefines.hxx b/src/MEDLoader/MEDLoaderDefines.hxx deleted file mode 100644 index fd92fc66b..000000000 --- a/src/MEDLoader/MEDLoaderDefines.hxx +++ /dev/null @@ -1,34 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 -// 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 __MEDLOADERDEFINES_HXX__ -#define __MEDLOADERDEFINES_HXX__ - -#ifdef WIN32 -# if defined medloader_EXPORTS -# define MEDLOADER_EXPORT __declspec(dllexport) -# else -# define MEDLOADER_EXPORT __declspec(dllimport) -# endif -#else -# define MEDLOADER_EXPORT -#endif - -#endif diff --git a/src/MEDLoader/SauvMedConvertor.cxx b/src/MEDLoader/SauvMedConvertor.cxx deleted file mode 100644 index dd2ba8961..000000000 --- a/src/MEDLoader/SauvMedConvertor.cxx +++ /dev/null @@ -1,3830 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 -// 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 -// -// File : SauvMedConvertor.cxx -// Created : Tue Aug 16 14:43:20 2011 -// Author : Edward AGAPOV (eap) -// - -#include "SauvMedConvertor.hxx" - -#include "CellModel.hxx" -#include "MEDFileMesh.hxx" -#include "MEDFileField.hxx" -#include "MEDFileData.hxx" -#include "MEDCouplingFieldDouble.hxx" - -#include -#include -#include -#include -#include - -#include -#include -#include - -#ifdef WIN32 -#include -#else -#include -#endif - -#ifdef HAS_XDR -#include -#endif - -using namespace SauvUtilities; -using namespace ParaMEDMEM; - -namespace -{ - // for ASCII file reader - const int GIBI_MaxOutputLen = 150; // max length of a line in the sauve file - const int GIBI_BufferSize = 16184; // for buffered reading - - using namespace INTERP_KERNEL; - - const size_t MaxMedCellType = NORM_ERROR; - const size_t NbGibiCellTypes = 47; - const TCellType GibiTypeToMed[NbGibiCellTypes] = - { - /*1 */ NORM_POINT1 ,/*2 */ NORM_SEG2 ,/*3 */ NORM_SEG3 ,/*4 */ NORM_TRI3 ,/*5 */ NORM_ERROR , - /*6 */ NORM_TRI6 ,/*7 */ NORM_ERROR ,/*8 */ NORM_QUAD4 ,/*9 */ NORM_ERROR ,/*10*/ NORM_QUAD8 , - /*11*/ NORM_ERROR ,/*12*/ NORM_ERROR ,/*13*/ NORM_ERROR ,/*14*/ NORM_HEXA8 ,/*15*/ NORM_HEXA20 , - /*16*/ NORM_PENTA6 ,/*17*/ NORM_PENTA15,/*18*/ NORM_ERROR ,/*19*/ NORM_ERROR ,/*20*/ NORM_ERROR , - /*21*/ NORM_ERROR ,/*22*/ NORM_ERROR ,/*23*/ NORM_TETRA4 ,/*24*/ NORM_TETRA10,/*25*/ NORM_PYRA5 , - /*26*/ NORM_PYRA13 ,/*27*/ NORM_ERROR ,/*28*/ NORM_ERROR ,/*29*/ NORM_ERROR ,/*30*/ NORM_ERROR , - /*31*/ NORM_ERROR ,/*32*/ NORM_ERROR ,/*33*/ NORM_ERROR ,/*34*/ NORM_ERROR ,/*35*/ NORM_ERROR , - /*36*/ NORM_ERROR ,/*37*/ NORM_ERROR ,/*38*/ NORM_ERROR ,/*39*/ NORM_ERROR ,/*40*/ NORM_ERROR , - /*41*/ NORM_ERROR ,/*42*/ NORM_ERROR ,/*43*/ NORM_ERROR ,/*44*/ NORM_ERROR ,/*45*/ NORM_ERROR , - /*46*/ NORM_ERROR ,/*47*/ NORM_ERROR - }; - - //================================================================================ - /*! - * \brief Return dimension of a group - */ - //================================================================================ - - unsigned getDim( const Group* grp ) - { - return SauvUtilities::getDimension( grp->_groups.empty() ? grp->_cellType : grp->_groups[0]->_cellType ); - } - - //================================================================================ - /*! - * \brief Converts connectivity of quadratic elements - */ - //================================================================================ - - inline void ConvertQuadratic( const INTERP_KERNEL::NormalizedCellType type, - const Cell & aCell ) - { - if ( const int * conn = getGibi2MedQuadraticInterlace( type )) - { - Cell* ma = const_cast(&aCell); - std::vector< Node* > new_nodes( ma->_nodes.size() ); - for (std:: size_t i = 0; i < new_nodes.size(); ++i ) - new_nodes[ i ] = ma->_nodes[ conn[ i ]]; - ma->_nodes.swap( new_nodes ); - } - } - - //================================================================================ - /*! - * \brief Returns a vector of pairs of node indices to inverse a med volume element - */ - //================================================================================ - - void getReverseVector (const INTERP_KERNEL::NormalizedCellType type, - std::vector > & swapVec ) - { - swapVec.clear(); - - switch ( type ) - { - case NORM_TETRA4: - swapVec.resize(1); - swapVec[0] = std::make_pair( 1, 2 ); - break; - case NORM_PYRA5: - swapVec.resize(1); - swapVec[0] = std::make_pair( 1, 3 ); - break; - case NORM_PENTA6: - swapVec.resize(2); - swapVec[0] = std::make_pair( 1, 2 ); - swapVec[1] = std::make_pair( 4, 5 ); - break; - case NORM_HEXA8: - swapVec.resize(2); - swapVec[0] = std::make_pair( 1, 3 ); - swapVec[1] = std::make_pair( 5, 7 ); - break; - case NORM_TETRA10: - swapVec.resize(3); - swapVec[0] = std::make_pair( 1, 2 ); - swapVec[1] = std::make_pair( 4, 6 ); - swapVec[2] = std::make_pair( 8, 9 ); - break; - case NORM_PYRA13: - swapVec.resize(4); - swapVec[0] = std::make_pair( 1, 3 ); - swapVec[1] = std::make_pair( 5, 8 ); - swapVec[2] = std::make_pair( 6, 7 ); - swapVec[3] = std::make_pair( 10, 12 ); - break; - case NORM_PENTA15: - swapVec.resize(4); - swapVec[0] = std::make_pair( 1, 2 ); - swapVec[1] = std::make_pair( 4, 5 ); - swapVec[2] = std::make_pair( 6, 8 ); - swapVec[3] = std::make_pair( 9, 11 ); - break; - case NORM_HEXA20: - swapVec.resize(7); - swapVec[0] = std::make_pair( 1, 3 ); - swapVec[1] = std::make_pair( 5, 7 ); - swapVec[2] = std::make_pair( 8, 11 ); - swapVec[3] = std::make_pair( 9, 10 ); - swapVec[4] = std::make_pair( 12, 15 ); - swapVec[5] = std::make_pair( 13, 14 ); - swapVec[6] = std::make_pair( 17, 19 ); - break; - // case NORM_SEG3: no need to reverse edges - // swapVec.resize(1); - // swapVec[0] = std::make_pair( 1, 2 ); - // break; - case NORM_TRI6: - swapVec.resize(2); - swapVec[0] = std::make_pair( 1, 2 ); - swapVec[1] = std::make_pair( 3, 5 ); - break; - case NORM_QUAD8: - swapVec.resize(3); - swapVec[0] = std::make_pair( 1, 3 ); - swapVec[1] = std::make_pair( 4, 7 ); - swapVec[2] = std::make_pair( 5, 6 ); - break; - default:; - } - } - - //================================================================================ - /*! - * \brief Inverses element orientation using vector of indices to swap - */ - //================================================================================ - - inline void reverse(const Cell & aCell, const std::vector > & swapVec ) - { - Cell* ma = const_cast(&aCell); - for ( unsigned i = 0; i < swapVec.size(); ++i ) - std::swap( ma->_nodes[ swapVec[i].first ], - ma->_nodes[ swapVec[i].second ]); - if ( swapVec.empty() ) - ma->_reverse = true; - else - ma->_reverse = false; - } - //================================================================================ - /*! - * \brief Comparator of cells by number used for ordering cells within a med group - */ - struct TCellByIDCompare - { - bool operator () (const Cell* i1, const Cell* i2) - { - return i1->_number < i2->_number; - } - }; - typedef std::map< const Cell*, unsigned, TCellByIDCompare > TCellToOrderMap; - - //================================================================================ - /*! - * \brief Fill Group::_relocTable if necessary - */ - //================================================================================ - - void setRelocationTable( Group* grp, TCellToOrderMap& cell2order ) - { - if ( !grp->_isProfile ) return; - - // check if relocation table is necessary - bool isRelocated = false; - unsigned newOrder = 0; - TCellToOrderMap::iterator c2oIt = cell2order.begin(), c2oEnd = cell2order.end(); - for ( ; !isRelocated && c2oIt != c2oEnd; ++c2oIt, ++newOrder ) - isRelocated = ( c2oIt->second != newOrder ); - - if ( isRelocated ) - { - grp->_relocTable.resize( cell2order.size() ); - for ( newOrder = 0, c2oIt = cell2order.begin(); c2oIt != c2oEnd; ++c2oIt, ++newOrder ) - grp->_relocTable[ c2oIt->second ] = newOrder; - } - } -} - -namespace // define default GAUSS points -{ - typedef std::vector TDoubleVector; - typedef double* TCoordSlice; - typedef int TInt; - //--------------------------------------------------------------- - //! Shape function definitions - //--------------------------------------------------------------- - struct TShapeFun - { - TInt myDim; - TInt myNbRef; - TDoubleVector myRefCoord; - - TShapeFun(TInt theDim = 0, TInt theNbRef = 0) - :myDim(theDim),myNbRef(theNbRef),myRefCoord(theNbRef*theDim) {} - - TInt GetNbRef() const { return myNbRef; } - - TCoordSlice GetCoord(TInt theRefId) { return &myRefCoord[0] + theRefId * myDim; } - }; - //--------------------------------------------------------------- - /*! - * \brief Description of family of integration points - */ - //--------------------------------------------------------------- - struct TGaussDef - { - int myType; //!< element geometry (EGeometrieElement or med_geometrie_element) - TDoubleVector myRefCoords; //!< description of reference points - TDoubleVector myCoords; //!< coordinates of Gauss points - TDoubleVector myWeights; //!< weights, len(weights)== - - /*! - * \brief Creates definition of gauss points family - * \param geomType - element geometry (EGeometrieElement or med_geometrie_element) - * \param nbPoints - nb gauss point - * \param variant - [1-3] to choose the variant of definition - * - * Throws in case of invalid parameters - * variant == 1 refers to "Fonctions de forme et points d'integration - * des elements finis" v7.4 by J. PELLET, X. DESROCHES, 15/09/05 - * variant == 2 refers to the same doc v6.4 by J.P. LEFEBVRE, X. DESROCHES, 03/07/03 - * variant == 3 refers to the same doc v6.4, second variant for 2D elements - */ - TGaussDef(const int geomType, const int nbPoints, const int variant=1); - - int dim() const { return SauvUtilities::getDimension( NormalizedCellType( myType )); } - int nbPoints() const { return myWeights.capacity(); } - - private: - void add(const double x, const double weight); - void add(const double x, const double y, const double weight); - void add(const double x, const double y, const double z, const double weight); - void setRefCoords(const TShapeFun& aShapeFun) { myRefCoords = aShapeFun.myRefCoord; } - }; - struct TSeg2a: TShapeFun { - TSeg2a(); - }; - struct TSeg3a: TShapeFun { - TSeg3a(); - }; - struct TTria3a: TShapeFun { - TTria3a(); - }; - struct TTria6a: TShapeFun { - TTria6a(); - }; - struct TTria3b: TShapeFun { - TTria3b(); - }; - struct TTria6b: TShapeFun { - TTria6b(); - }; - struct TQuad4a: TShapeFun { - TQuad4a(); - }; - struct TQuad8a: TShapeFun { - TQuad8a(); - }; - struct TQuad4b: TShapeFun { - TQuad4b(); - }; - struct TQuad8b: TShapeFun { - TQuad8b(); - }; - struct TTetra4a: TShapeFun { - TTetra4a(); - }; - struct TTetra10a: TShapeFun { - TTetra10a(); - }; - struct TTetra4b: TShapeFun { - TTetra4b(); - }; - struct TTetra10b: TShapeFun { - TTetra10b(); - }; - struct THexa8a: TShapeFun { - THexa8a(); - }; - struct THexa20a: TShapeFun { - THexa20a(TInt theDim = 3, TInt theNbRef = 20); - }; - struct THexa27a: THexa20a { - THexa27a(); - }; - struct THexa8b: TShapeFun { - THexa8b(); - }; - struct THexa20b: TShapeFun { - THexa20b(TInt theDim = 3, TInt theNbRef = 20); - }; - struct TPenta6a: TShapeFun { - TPenta6a(); - }; - struct TPenta6b: TShapeFun { - TPenta6b(); - }; - struct TPenta15a: TShapeFun { - TPenta15a(); - }; - struct TPenta15b: TShapeFun { - TPenta15b(); - }; - struct TPyra5a: TShapeFun { - TPyra5a(); - }; - struct TPyra5b: TShapeFun { - TPyra5b(); - }; - struct TPyra13a: TShapeFun { - TPyra13a(); - }; - struct TPyra13b: TShapeFun { - TPyra13b(); - }; - - void TGaussDef::add(const double x, const double weight) - { - if ( dim() != 1 ) - THROW_IK_EXCEPTION("TGaussDef: dim() != 1"); - if ( myWeights.capacity() == myWeights.size() ) - THROW_IK_EXCEPTION("TGaussDef: Extra gauss point"); - myCoords.push_back( x ); - myWeights.push_back( weight ); - } - void TGaussDef::add(const double x, const double y, const double weight) - { - if ( dim() != 2 ) - THROW_IK_EXCEPTION("TGaussDef: dim() != 2"); - if ( myWeights.capacity() == myWeights.size() ) - THROW_IK_EXCEPTION("TGaussDef: Extra gauss point"); - myCoords.push_back( x ); - myCoords.push_back( y ); - myWeights.push_back( weight ); - } - void TGaussDef::add(const double x, const double y, const double z, const double weight) - { - if ( dim() != 3 ) - THROW_IK_EXCEPTION("TGaussDef: dim() != 3"); - if ( myWeights.capacity() == myWeights.size() ) - THROW_IK_EXCEPTION("TGaussDef: Extra gauss point"); - myCoords.push_back( x ); - myCoords.push_back( y ); - myCoords.push_back( z ); - myWeights.push_back( weight ); - } - - //--------------------------------------------------------------- - TSeg2a::TSeg2a():TShapeFun(1,2) - { - TInt aNbRef = GetNbRef(); - for(TInt aRefId = 0; aRefId < aNbRef; aRefId++){ - TCoordSlice aCoord = GetCoord(aRefId); - switch(aRefId){ - case 0: aCoord[0] = -1.0; break; - case 1: aCoord[0] = 1.0; break; - } - } - } - //--------------------------------------------------------------- - TSeg3a::TSeg3a():TShapeFun(1,3) - { - TInt aNbRef = GetNbRef(); - for(TInt aRefId = 0; aRefId < aNbRef; aRefId++){ - TCoordSlice aCoord = GetCoord(aRefId); - switch(aRefId){ - case 0: aCoord[0] = -1.0; break; - case 1: aCoord[0] = 1.0; break; - case 2: aCoord[0] = 0.0; break; - } - } - } - //--------------------------------------------------------------- - TTria3a::TTria3a(): - TShapeFun(2,3) - { - TInt aNbRef = GetNbRef(); - for(TInt aRefId = 0; aRefId < aNbRef; aRefId++){ - TCoordSlice aCoord = GetCoord(aRefId); - switch(aRefId){ - case 0: aCoord[0] = -1.0; aCoord[1] = 1.0; break; - case 1: aCoord[0] = -1.0; aCoord[1] = -1.0; break; - case 2: aCoord[0] = 1.0; aCoord[1] = -1.0; break; - } - } - } - //--------------------------------------------------------------- - TTria6a::TTria6a():TShapeFun(2,6) - { - TInt aNbRef = GetNbRef(); - for(TInt aRefId = 0; aRefId < aNbRef; aRefId++){ - TCoordSlice aCoord = GetCoord(aRefId); - switch(aRefId){ - case 0: aCoord[0] = -1.0; aCoord[1] = 1.0; break; - case 1: aCoord[0] = -1.0; aCoord[1] = -1.0; break; - case 2: aCoord[0] = 1.0; aCoord[1] = -1.0; break; - - case 3: aCoord[0] = -1.0; aCoord[1] = 1.0; break; - case 4: aCoord[0] = 0.0; aCoord[1] = -1.0; break; - case 5: aCoord[0] = 0.0; aCoord[1] = 0.0; break; - } - } - } - //--------------------------------------------------------------- - TTria3b::TTria3b(): - TShapeFun(2,3) - { - TInt aNbRef = GetNbRef(); - for(TInt aRefId = 0; aRefId < aNbRef; aRefId++){ - TCoordSlice aCoord = GetCoord(aRefId); - switch(aRefId){ - case 0: aCoord[0] = 0.0; aCoord[1] = 0.0; break; - case 1: aCoord[0] = 1.0; aCoord[1] = 0.0; break; - case 2: aCoord[0] = 0.0; aCoord[1] = 1.0; break; - } - } - } - //--------------------------------------------------------------- - TTria6b::TTria6b(): - TShapeFun(2,6) - { - TInt aNbRef = GetNbRef(); - for(TInt aRefId = 0; aRefId < aNbRef; aRefId++){ - TCoordSlice aCoord = GetCoord(aRefId); - switch(aRefId){ - case 0: aCoord[0] = 0.0; aCoord[1] = 0.0; break; - case 1: aCoord[0] = 1.0; aCoord[1] = 0.0; break; - case 2: aCoord[0] = 0.0; aCoord[1] = 1.0; break; - - case 3: aCoord[0] = 0.5; aCoord[1] = 0.0; break; - case 4: aCoord[0] = 0.5; aCoord[1] = 0.5; break; - case 5: aCoord[0] = 0.0; aCoord[1] = 0.5; break; - } - } - } - //--------------------------------------------------------------- - TQuad4a::TQuad4a(): - TShapeFun(2,4) - { - TInt aNbRef = GetNbRef(); - for(TInt aRefId = 0; aRefId < aNbRef; aRefId++){ - TCoordSlice aCoord = GetCoord(aRefId); - switch(aRefId){ - case 0: aCoord[0] = -1.0; aCoord[1] = 1.0; break; - case 1: aCoord[0] = -1.0; aCoord[1] = -1.0; break; - case 2: aCoord[0] = 1.0; aCoord[1] = -1.0; break; - case 3: aCoord[0] = 1.0; aCoord[1] = 1.0; break; - } - } - } - //--------------------------------------------------------------- - TQuad8a::TQuad8a(): - TShapeFun(2,8) - { - TInt aNbRef = GetNbRef(); - for(TInt aRefId = 0; aRefId < aNbRef; aRefId++){ - TCoordSlice aCoord = GetCoord(aRefId); - switch(aRefId){ - case 0: aCoord[0] = -1.0; aCoord[1] = 1.0; break; - case 1: aCoord[0] = -1.0; aCoord[1] = -1.0; break; - case 2: aCoord[0] = 1.0; aCoord[1] = -1.0; break; - case 3: aCoord[0] = 1.0; aCoord[1] = 1.0; break; - - case 4: aCoord[0] = -1.0; aCoord[1] = 0.0; break; - case 5: aCoord[0] = 0.0; aCoord[1] = -1.0; break; - case 6: aCoord[0] = 1.0; aCoord[1] = 0.0; break; - case 7: aCoord[0] = 0.0; aCoord[1] = 1.0; break; - } - } - } - //--------------------------------------------------------------- - TQuad4b::TQuad4b(): - TShapeFun(2,4) - { - TInt aNbRef = GetNbRef(); - for(TInt aRefId = 0; aRefId < aNbRef; aRefId++){ - TCoordSlice aCoord = GetCoord(aRefId); - switch(aRefId){ - case 0: aCoord[0] = -1.0; aCoord[1] = -1.0; break; - case 1: aCoord[0] = 1.0; aCoord[1] = -1.0; break; - case 2: aCoord[0] = 1.0; aCoord[1] = 1.0; break; - case 3: aCoord[0] = -1.0; aCoord[1] = 1.0; break; - } - } - } - //--------------------------------------------------------------- - TQuad8b::TQuad8b(): - TShapeFun(2,8) - { - TInt aNbRef = GetNbRef(); - for(TInt aRefId = 0; aRefId < aNbRef; aRefId++){ - TCoordSlice aCoord = GetCoord(aRefId); - switch(aRefId){ - case 0: aCoord[0] = -1.0; aCoord[1] = -1.0; break; - case 1: aCoord[0] = 1.0; aCoord[1] = -1.0; break; - case 2: aCoord[0] = 1.0; aCoord[1] = 1.0; break; - case 3: aCoord[0] = -1.0; aCoord[1] = 1.0; break; - - case 4: aCoord[0] = 0.0; aCoord[1] = -1.0; break; - case 5: aCoord[0] = 1.0; aCoord[1] = 0.0; break; - case 6: aCoord[0] = 0.0; aCoord[1] = 1.0; break; - case 7: aCoord[0] = -1.0; aCoord[1] = 0.0; break; - } - } - } - //--------------------------------------------------------------- - TTetra4a::TTetra4a(): - TShapeFun(3,4) - { - TInt aNbRef = GetNbRef(); - for(TInt aRefId = 0; aRefId < aNbRef; aRefId++){ - TCoordSlice aCoord = GetCoord(aRefId); - switch(aRefId){ - case 0: aCoord[0] = 0.0; aCoord[1] = 1.0; aCoord[2] = 0.0; break; - case 1: aCoord[0] = 0.0; aCoord[1] = 0.0; aCoord[2] = 1.0; break; - case 2: aCoord[0] = 0.0; aCoord[1] = 0.0; aCoord[2] = 0.0; break; - case 3: aCoord[0] = 1.0; aCoord[1] = 0.0; aCoord[2] = 0.0; break; - } - } - } - //--------------------------------------------------------------- - TTetra10a::TTetra10a(): - TShapeFun(3,10) - { - TInt aNbRef = GetNbRef(); - for(TInt aRefId = 0; aRefId < aNbRef; aRefId++){ - TCoordSlice aCoord = GetCoord(aRefId); - switch(aRefId){ - case 0: aCoord[0] = 0.0; aCoord[1] = 1.0; aCoord[2] = 0.0; break; - case 1: aCoord[0] = 0.0; aCoord[1] = 0.0; aCoord[2] = 1.0; break; - case 2: aCoord[0] = 0.0; aCoord[1] = 0.0; aCoord[2] = 0.0; break; - case 3: aCoord[0] = 1.0; aCoord[1] = 0.0; aCoord[2] = 0.0; break; - - case 4: aCoord[0] = 0.0; aCoord[1] = 0.5; aCoord[2] = 0.5; break; - case 5: aCoord[0] = 0.0; aCoord[1] = 0.0; aCoord[2] = 0.5; break; - case 6: aCoord[0] = 0.0; aCoord[1] = 0.5; aCoord[2] = 0.0; break; - - case 7: aCoord[0] = 0.5; aCoord[1] = 0.5; aCoord[2] = 0.0; break; - case 8: aCoord[0] = 0.5; aCoord[1] = 0.0; aCoord[2] = 0.5; break; - case 9: aCoord[0] = 0.5; aCoord[1] = 0.0; aCoord[2] = 0.0; break; - } - } - } - //--------------------------------------------------------------- - TTetra4b::TTetra4b(): - TShapeFun(3,4) - { - TInt aNbRef = GetNbRef(); - for(TInt aRefId = 0; aRefId < aNbRef; aRefId++){ - TCoordSlice aCoord = GetCoord(aRefId); - switch(aRefId){ - case 0: aCoord[0] = 0.0; aCoord[1] = 1.0; aCoord[2] = 0.0; break; - case 2: aCoord[0] = 0.0; aCoord[1] = 0.0; aCoord[2] = 1.0; break; - case 1: aCoord[0] = 0.0; aCoord[1] = 0.0; aCoord[2] = 0.0; break; - case 3: aCoord[0] = 1.0; aCoord[1] = 0.0; aCoord[2] = 0.0; break; - } - } - } - //--------------------------------------------------------------- - TTetra10b::TTetra10b(): - TShapeFun(3,10) - { - TInt aNbRef = GetNbRef(); - for(TInt aRefId = 0; aRefId < aNbRef; aRefId++){ - TCoordSlice aCoord = GetCoord(aRefId); - switch(aRefId){ - case 0: aCoord[0] = 0.0; aCoord[1] = 1.0; aCoord[2] = 0.0; break; - case 2: aCoord[0] = 0.0; aCoord[1] = 0.0; aCoord[2] = 1.0; break; - case 1: aCoord[0] = 0.0; aCoord[1] = 0.0; aCoord[2] = 0.0; break; - case 3: aCoord[0] = 1.0; aCoord[1] = 0.0; aCoord[2] = 0.0; break; - - case 6: aCoord[0] = 0.0; aCoord[1] = 0.5; aCoord[2] = 0.5; break; - case 5: aCoord[0] = 0.0; aCoord[1] = 0.0; aCoord[2] = 0.5; break; - case 4: aCoord[0] = 0.0; aCoord[1] = 0.5; aCoord[2] = 0.0; break; - - case 7: aCoord[0] = 0.5; aCoord[1] = 0.5; aCoord[2] = 0.0; break; - case 9: aCoord[0] = 0.5; aCoord[1] = 0.0; aCoord[2] = 0.5; break; - case 8: aCoord[0] = 0.5; aCoord[1] = 0.0; aCoord[2] = 0.0; break; - } - } - } - //--------------------------------------------------------------- - THexa8a::THexa8a(): - TShapeFun(3,8) - { - TInt aNbRef = GetNbRef(); - for(TInt aRefId = 0; aRefId < aNbRef; aRefId++){ - TCoordSlice aCoord = GetCoord(aRefId); - switch(aRefId){ - case 0: aCoord[0] = -1.0; aCoord[1] = -1.0; aCoord[2] = -1.0; break; - case 1: aCoord[0] = 1.0; aCoord[1] = -1.0; aCoord[2] = -1.0; break; - case 2: aCoord[0] = 1.0; aCoord[1] = 1.0; aCoord[2] = -1.0; break; - case 3: aCoord[0] = -1.0; aCoord[1] = 1.0; aCoord[2] = -1.0; break; - case 4: aCoord[0] = -1.0; aCoord[1] = -1.0; aCoord[2] = 1.0; break; - case 5: aCoord[0] = 1.0; aCoord[1] = -1.0; aCoord[2] = 1.0; break; - case 6: aCoord[0] = 1.0; aCoord[1] = 1.0; aCoord[2] = 1.0; break; - case 7: aCoord[0] = -1.0; aCoord[1] = 1.0; aCoord[2] = 1.0; break; - } - } - } - //--------------------------------------------------------------- - THexa20a::THexa20a(TInt theDim, TInt theNbRef): - TShapeFun(theDim,theNbRef) - { - TInt aNbRef = myRefCoord.size(); - for(TInt aRefId = 0; aRefId < aNbRef; aRefId++){ - TCoordSlice aCoord = GetCoord(aRefId); - switch(aRefId){ - case 0: aCoord[0] = -1.0; aCoord[1] = -1.0; aCoord[2] = -1.0; break; - case 1: aCoord[0] = 1.0; aCoord[1] = -1.0; aCoord[2] = -1.0; break; - case 2: aCoord[0] = 1.0; aCoord[1] = 1.0; aCoord[2] = -1.0; break; - case 3: aCoord[0] = -1.0; aCoord[1] = 1.0; aCoord[2] = -1.0; break; - case 4: aCoord[0] = -1.0; aCoord[1] = -1.0; aCoord[2] = 1.0; break; - case 5: aCoord[0] = 1.0; aCoord[1] = -1.0; aCoord[2] = 1.0; break; - case 6: aCoord[0] = 1.0; aCoord[1] = 1.0; aCoord[2] = 1.0; break; - case 7: aCoord[0] = -1.0; aCoord[1] = 1.0; aCoord[2] = 1.0; break; - - case 8: aCoord[0] = 0.0; aCoord[1] = -1.0; aCoord[2] = -1.0; break; - case 9: aCoord[0] = 1.0; aCoord[1] = 0.0; aCoord[2] = -1.0; break; - case 10: aCoord[0] = 0.0; aCoord[1] = 1.0; aCoord[2] = -1.0; break; - case 11: aCoord[0] = -1.0; aCoord[1] = 0.0; aCoord[2] = -1.0; break; - case 12: aCoord[0] = -1.0; aCoord[1] = -1.0; aCoord[2] = 0.0; break; - case 13: aCoord[0] = 1.0; aCoord[1] = -1.0; aCoord[2] = 0.0; break; - case 14: aCoord[0] = 1.0; aCoord[1] = 1.0; aCoord[2] = 0.0; break; - case 15: aCoord[0] = -1.0; aCoord[1] = 1.0; aCoord[2] = 0.0; break; - case 16: aCoord[0] = 0.0; aCoord[1] = -1.0; aCoord[2] = 1.0; break; - case 17: aCoord[0] = 1.0; aCoord[1] = 0.0; aCoord[2] = 1.0; break; - case 18: aCoord[0] = 0.0; aCoord[1] = 1.0; aCoord[2] = 1.0; break; - case 19: aCoord[0] = -1.0; aCoord[1] = 0.0; aCoord[2] = 1.0; break; - } - } - } - //--------------------------------------------------------------- - THexa27a::THexa27a(): - THexa20a(3,27) - { - TInt aNbRef = myRefCoord.size(); - for(TInt aRefId = 0; aRefId < aNbRef; aRefId++){ - TCoordSlice aCoord = GetCoord(aRefId); - switch(aRefId){ - case 20: aCoord[0] = 0.0; aCoord[1] = 0.0; aCoord[2] = -1.0; break; - case 21: aCoord[0] = 0.0; aCoord[1] = -1.0; aCoord[2] = 0.0; break; - case 22: aCoord[0] = 1.0; aCoord[1] = 0.0; aCoord[2] = 0.0; break; - case 23: aCoord[0] = 0.0; aCoord[1] = 1.0; aCoord[2] = 0.0; break; - case 24: aCoord[0] = -1.0; aCoord[1] = 0.0; aCoord[2] = 0.0; break; - case 25: aCoord[0] = 0.0; aCoord[1] = 0.0; aCoord[2] = 1.0; break; - case 26: aCoord[0] = 0.0; aCoord[1] = 0.0; aCoord[2] = 0.0; break; - } - } - } - //--------------------------------------------------------------- - THexa8b::THexa8b(): - TShapeFun(3,8) - { - TInt aNbRef = GetNbRef(); - for(TInt aRefId = 0; aRefId < aNbRef; aRefId++){ - TCoordSlice aCoord = GetCoord(aRefId); - switch(aRefId){ - case 0: aCoord[0] = -1.0; aCoord[1] = -1.0; aCoord[2] = -1.0; break; - case 3: aCoord[0] = 1.0; aCoord[1] = -1.0; aCoord[2] = -1.0; break; - case 2: aCoord[0] = 1.0; aCoord[1] = 1.0; aCoord[2] = -1.0; break; - case 1: aCoord[0] = -1.0; aCoord[1] = 1.0; aCoord[2] = -1.0; break; - case 4: aCoord[0] = -1.0; aCoord[1] = -1.0; aCoord[2] = 1.0; break; - case 7: aCoord[0] = 1.0; aCoord[1] = -1.0; aCoord[2] = 1.0; break; - case 6: aCoord[0] = 1.0; aCoord[1] = 1.0; aCoord[2] = 1.0; break; - case 5: aCoord[0] = -1.0; aCoord[1] = 1.0; aCoord[2] = 1.0; break; - } - } - } - //--------------------------------------------------------------- - THexa20b::THexa20b(TInt theDim, TInt theNbRef): - TShapeFun(theDim,theNbRef) - { - TInt aNbRef = myRefCoord.size(); - for(TInt aRefId = 0; aRefId < aNbRef; aRefId++){ - TCoordSlice aCoord = GetCoord(aRefId); - switch(aRefId){ - case 0: aCoord[0] = -1.0; aCoord[1] = -1.0; aCoord[2] = -1.0; break; - case 3: aCoord[0] = 1.0; aCoord[1] = -1.0; aCoord[2] = -1.0; break; - case 2: aCoord[0] = 1.0; aCoord[1] = 1.0; aCoord[2] = -1.0; break; - case 1: aCoord[0] = -1.0; aCoord[1] = 1.0; aCoord[2] = -1.0; break; - case 4: aCoord[0] = -1.0; aCoord[1] = -1.0; aCoord[2] = 1.0; break; - case 7: aCoord[0] = 1.0; aCoord[1] = -1.0; aCoord[2] = 1.0; break; - case 6: aCoord[0] = 1.0; aCoord[1] = 1.0; aCoord[2] = 1.0; break; - case 5: aCoord[0] = -1.0; aCoord[1] = 1.0; aCoord[2] = 1.0; break; - - case 11: aCoord[0] = 0.0; aCoord[1] = -1.0; aCoord[2] = -1.0; break; - case 10: aCoord[0] = 1.0; aCoord[1] = 0.0; aCoord[2] = -1.0; break; - case 9: aCoord[0] = 0.0; aCoord[1] = 1.0; aCoord[2] = -1.0; break; - case 8: aCoord[0] = -1.0; aCoord[1] = 0.0; aCoord[2] = -1.0; break; - case 16: aCoord[0] = -1.0; aCoord[1] = -1.0; aCoord[2] = 0.0; break; - case 19: aCoord[0] = 1.0; aCoord[1] = -1.0; aCoord[2] = 0.0; break; - case 18: aCoord[0] = 1.0; aCoord[1] = 1.0; aCoord[2] = 0.0; break; - case 17: aCoord[0] = -1.0; aCoord[1] = 1.0; aCoord[2] = 0.0; break; - case 15: aCoord[0] = 0.0; aCoord[1] = -1.0; aCoord[2] = 1.0; break; - case 14: aCoord[0] = 1.0; aCoord[1] = 0.0; aCoord[2] = 1.0; break; - case 13: aCoord[0] = 0.0; aCoord[1] = 1.0; aCoord[2] = 1.0; break; - case 12: aCoord[0] = -1.0; aCoord[1] = 0.0; aCoord[2] = 1.0; break; - } - } - } - //--------------------------------------------------------------- - TPenta6a::TPenta6a(): - TShapeFun(3,6) - { - TInt aNbRef = myRefCoord.size(); - for(TInt aRefId = 0; aRefId < aNbRef; aRefId++){ - TCoordSlice aCoord = GetCoord(aRefId); - switch(aRefId){ - case 0: aCoord[0] = -1.0; aCoord[1] = 1.0; aCoord[2] = 0.0; break; - case 1: aCoord[0] = -1.0; aCoord[1] = -0.0; aCoord[2] = 1.0; break; - case 2: aCoord[0] = -1.0; aCoord[1] = 0.0; aCoord[2] = 0.0; break; - case 3: aCoord[0] = 1.0; aCoord[1] = 1.0; aCoord[2] = 0.0; break; - case 4: aCoord[0] = 1.0; aCoord[1] = 0.0; aCoord[2] = 1.0; break; - case 5: aCoord[0] = 1.0; aCoord[1] = 0.0; aCoord[2] = 0.0; break; - } - } - } - //--------------------------------------------------------------- - TPenta6b::TPenta6b(): - TShapeFun(3,6) - { - TInt aNbRef = myRefCoord.size(); - for(TInt aRefId = 0; aRefId < aNbRef; aRefId++){ - TCoordSlice aCoord = GetCoord(aRefId); - switch(aRefId){ - case 0: aCoord[0] = -1.0; aCoord[1] = 1.0; aCoord[2] = 0.0; break; - case 2: aCoord[0] = -1.0; aCoord[1] = -0.0; aCoord[2] = 1.0; break; - case 1: aCoord[0] = -1.0; aCoord[1] = 0.0; aCoord[2] = 0.0; break; - case 3: aCoord[0] = 1.0; aCoord[1] = 1.0; aCoord[2] = 0.0; break; - case 5: aCoord[0] = 1.0; aCoord[1] = 0.0; aCoord[2] = 1.0; break; - case 4: aCoord[0] = 1.0; aCoord[1] = 0.0; aCoord[2] = 0.0; break; - } - } - } - //--------------------------------------------------------------- - TPenta15a::TPenta15a(): - TShapeFun(3,15) - { - TInt aNbRef = myRefCoord.size(); - for(TInt aRefId = 0; aRefId < aNbRef; aRefId++){ - TCoordSlice aCoord = GetCoord(aRefId); - switch(aRefId){ - case 0: aCoord[0] = -1.0; aCoord[1] = 1.0; aCoord[2] = 0.0; break; - case 1: aCoord[0] = -1.0; aCoord[1] = -0.0; aCoord[2] = 1.0; break; - case 2: aCoord[0] = -1.0; aCoord[1] = 0.0; aCoord[2] = 0.0; break; - case 3: aCoord[0] = 1.0; aCoord[1] = 1.0; aCoord[2] = 0.0; break; - case 4: aCoord[0] = 1.0; aCoord[1] = 0.0; aCoord[2] = 1.0; break; - case 5: aCoord[0] = 1.0; aCoord[1] = 0.0; aCoord[2] = 0.0; break; - - case 6: aCoord[0] = -1.0; aCoord[1] = 0.5; aCoord[2] = 0.5; break; - case 7: aCoord[0] = -1.0; aCoord[1] = 0.0; aCoord[2] = 0.5; break; - case 8: aCoord[0] = -1.0; aCoord[1] = 0.5; aCoord[2] = 0.0; break; - case 9: aCoord[0] = 0.0; aCoord[1] = 1.0; aCoord[2] = 0.0; break; - case 10: aCoord[0] = 0.0; aCoord[1] = 0.0; aCoord[2] = 1.0; break; - case 11: aCoord[0] = 0.0; aCoord[1] = 0.0; aCoord[2] = 0.0; break; - case 12: aCoord[0] = 1.0; aCoord[1] = 0.5; aCoord[2] = 0.5; break; - case 13: aCoord[0] = 1.0; aCoord[1] = 0.0; aCoord[2] = 0.5; break; - case 14: aCoord[0] = 1.0; aCoord[1] = 0.5; aCoord[2] = 0.0; break; - } - } - } - //--------------------------------------------------------------- - TPenta15b::TPenta15b(): - TShapeFun(3,15) - { - TInt aNbRef = myRefCoord.size(); - for(TInt aRefId = 0; aRefId < aNbRef; aRefId++){ - TCoordSlice aCoord = GetCoord(aRefId); - switch(aRefId){ - case 0: aCoord[0] = -1.0; aCoord[1] = 1.0; aCoord[2] = 0.0; break; - case 2: aCoord[0] = -1.0; aCoord[1] = -0.0; aCoord[2] = 1.0; break; - case 1: aCoord[0] = -1.0; aCoord[1] = 0.0; aCoord[2] = 0.0; break; - case 3: aCoord[0] = 1.0; aCoord[1] = 1.0; aCoord[2] = 0.0; break; - case 5: aCoord[0] = 1.0; aCoord[1] = 0.0; aCoord[2] = 1.0; break; - case 4: aCoord[0] = 1.0; aCoord[1] = 0.0; aCoord[2] = 0.0; break; - - case 8: aCoord[0] = -1.0; aCoord[1] = 0.5; aCoord[2] = 0.5; break; - case 7: aCoord[0] = -1.0; aCoord[1] = 0.0; aCoord[2] = 0.5; break; - case 6: aCoord[0] = -1.0; aCoord[1] = 0.5; aCoord[2] = 0.0; break; - case 12: aCoord[0] = 0.0; aCoord[1] = 1.0; aCoord[2] = 0.0; break; - case 14: aCoord[0] = 0.0; aCoord[1] = 0.0; aCoord[2] = 1.0; break; - case 13: aCoord[0] = 0.0; aCoord[1] = 0.0; aCoord[2] = 0.0; break; - case 11: aCoord[0] = 1.0; aCoord[1] = 0.5; aCoord[2] = 0.5; break; - case 10: aCoord[0] = 1.0; aCoord[1] = 0.0; aCoord[2] = 0.5; break; - case 9: aCoord[0] = 1.0; aCoord[1] = 0.5; aCoord[2] = 0.0; break; - } - } - } - //--------------------------------------------------------------- - TPyra5a::TPyra5a(): - TShapeFun(3,5) - { - TInt aNbRef = myRefCoord.size(); - for(TInt aRefId = 0; aRefId < aNbRef; aRefId++){ - TCoordSlice aCoord = GetCoord(aRefId); - switch(aRefId){ - case 0: aCoord[0] = 1.0; aCoord[1] = 0.0; aCoord[2] = 0.0; break; - case 1: aCoord[0] = 0.0; aCoord[1] = 1.0; aCoord[2] = 0.0; break; - case 2: aCoord[0] = -1.0; aCoord[1] = 0.0; aCoord[2] = 0.0; break; - case 3: aCoord[0] = 0.0; aCoord[1] = -1.0; aCoord[2] = 0.0; break; - case 4: aCoord[0] = 0.0; aCoord[1] = 0.0; aCoord[2] = 1.0; break; - } - } - } - //--------------------------------------------------------------- - TPyra5b::TPyra5b(): - TShapeFun(3,5) - { - TInt aNbRef = myRefCoord.size(); - for(TInt aRefId = 0; aRefId < aNbRef; aRefId++){ - TCoordSlice aCoord = GetCoord(aRefId); - switch(aRefId){ - case 0: aCoord[0] = 1.0; aCoord[1] = 0.0; aCoord[2] = 0.0; break; - case 3: aCoord[0] = 0.0; aCoord[1] = 1.0; aCoord[2] = 0.0; break; - case 2: aCoord[0] = -1.0; aCoord[1] = 0.0; aCoord[2] = 0.0; break; - case 1: aCoord[0] = 0.0; aCoord[1] = -1.0; aCoord[2] = 0.0; break; - case 4: aCoord[0] = 0.0; aCoord[1] = 0.0; aCoord[2] = 1.0; break; - } - } - } - //--------------------------------------------------------------- - TPyra13a::TPyra13a(): - TShapeFun(3,13) - { - TInt aNbRef = myRefCoord.size(); - for(TInt aRefId = 0; aRefId < aNbRef; aRefId++){ - TCoordSlice aCoord = GetCoord(aRefId); - switch(aRefId){ - case 0: aCoord[0] = 1.0; aCoord[1] = 0.0; aCoord[2] = 0.0; break; - case 1: aCoord[0] = 0.0; aCoord[1] = 1.0; aCoord[2] = 0.0; break; - case 2: aCoord[0] = -1.0; aCoord[1] = 0.0; aCoord[2] = 0.0; break; - case 3: aCoord[0] = 0.0; aCoord[1] = -1.0; aCoord[2] = 0.0; break; - case 4: aCoord[0] = 0.0; aCoord[1] = 0.0; aCoord[2] = 1.0; break; - - case 5: aCoord[0] = 0.5; aCoord[1] = 0.5; aCoord[2] = 0.0; break; - case 6: aCoord[0] = -0.5; aCoord[1] = 0.5; aCoord[2] = 0.0; break; - case 7: aCoord[0] = -0.5; aCoord[1] = -0.5; aCoord[2] = 0.0; break; - case 8: aCoord[0] = 0.5; aCoord[1] = -0.5; aCoord[2] = 0.0; break; - case 9: aCoord[0] = 0.5; aCoord[1] = 0.0; aCoord[2] = 0.5; break; - case 10: aCoord[0] = 0.0; aCoord[1] = 0.5; aCoord[2] = 0.5; break; - case 11: aCoord[0] = -0.5; aCoord[1] = 0.0; aCoord[2] = 0.5; break; - case 12: aCoord[0] = 0.0; aCoord[1] = -0.5; aCoord[2] = 0.5; break; - } - } - } - //--------------------------------------------------------------- - TPyra13b::TPyra13b(): - TShapeFun(3,13) - { - TInt aNbRef = myRefCoord.size(); - for(TInt aRefId = 0; aRefId < aNbRef; aRefId++){ - TCoordSlice aCoord = GetCoord(aRefId); - switch(aRefId){ - case 0: aCoord[0] = 1.0; aCoord[1] = 0.0; aCoord[2] = 0.0; break; - case 3: aCoord[0] = 0.0; aCoord[1] = 1.0; aCoord[2] = 0.0; break; - case 2: aCoord[0] = -1.0; aCoord[1] = 0.0; aCoord[2] = 0.0; break; - case 1: aCoord[0] = 0.0; aCoord[1] = -1.0; aCoord[2] = 0.0; break; - case 4: aCoord[0] = 0.0; aCoord[1] = 0.0; aCoord[2] = 1.0; break; - - case 8: aCoord[0] = 0.5; aCoord[1] = 0.5; aCoord[2] = 0.0; break; - case 7: aCoord[0] = -0.5; aCoord[1] = 0.5; aCoord[2] = 0.0; break; - case 6: aCoord[0] = -0.5; aCoord[1] = -0.5; aCoord[2] = 0.0; break; - case 5: aCoord[0] = 0.5; aCoord[1] = -0.5; aCoord[2] = 0.0; break; - case 9: aCoord[0] = 0.5; aCoord[1] = 0.0; aCoord[2] = 0.5; break; - case 12: aCoord[0] = 0.0; aCoord[1] = 0.5; aCoord[2] = 0.5; break; - case 11: aCoord[0] = -0.5; aCoord[1] = 0.0; aCoord[2] = 0.5; break; - case 10: aCoord[0] = 0.0; aCoord[1] = -0.5; aCoord[2] = 0.5; break; - } - } - } - /*! - * \brief Fill definition of gauss points family - */ - - TGaussDef::TGaussDef(const int geom, const int nbGauss, const int variant) - { - myType = geom; - myCoords .reserve( nbGauss * dim() ); - myWeights.reserve( nbGauss ); - - switch ( geom ) { - - case NORM_SEG2: - case NORM_SEG3: - if (geom == NORM_SEG2) setRefCoords( TSeg2a() ); - else setRefCoords( TSeg3a() ); - switch ( nbGauss ) { - case 1: { - add( 0.0, 2.0 ); break; - } - case 2: { - const double a = 0.577350269189626; - add( a, 1.0 ); - add( -a, 1.0 ); break; - } - case 3: { - const double a = 0.774596669241; - const double P1 = 1./1.8; - const double P2 = 1./1.125; - add( -a, P1 ); - add( 0, P2 ); - add( a, P1 ); break; - } - case 4: { - const double a = 0.339981043584856, b = 0.861136311594053; - const double P1 = 0.652145154862546, P2 = 0.347854845137454 ; - add( a, P1 ); - add( -a, P1 ); - add( b, P2 ); - add( -b, P2 ); break; - } - default: - THROW_IK_EXCEPTION("TGaussDef: Invalid nb of gauss points for SEG"< alfa - const double a = (6 + sqrt(15.))/21.; - const double b = (6 - sqrt(15.))/21.; - const double P1 = (155 + sqrt(15.))/2400.; - const double P2 = (155 - sqrt(15.))/2400.; //___ - add( -d, 1/3., 1/3., c1*9/80. );//___ - add( -d, a, a, c1*P1 ); - add( -d, 1-2*a, a, c1*P1 ); - add( -d, a, 1-2*a, c1*P1 );//___ - add( -d, b, b, c1*P2 ); - add( -d, 1-2*b, b, c1*P2 ); - add( -d, b, 1-2*b, c1*P2 );//___ - add( 0., 1/3., 1/3., c2*9/80. );//___ - add( 0., a, a, c2*P1 ); - add( 0., 1-2*a, a, c2*P1 ); - add( 0., a, 1-2*a, c2*P1 );//___ - add( 0., b, b, c2*P2 ); - add( 0., 1-2*b, b, c2*P2 ); - add( 0., b, 1-2*b, c2*P2 );//___ - add( d, 1/3., 1/3., c1*9/80. );//___ - add( d, a, a, c1*P1 ); - add( d, 1-2*a, a, c1*P1 ); - add( d, a, 1-2*a, c1*P1 );//___ - add( d, b, b, c1*P2 ); - add( d, 1-2*b, b, c1*P2 ); - add( d, b, 1-2*b, c1*P2 );//___ - break; - } - default: - THROW_IK_EXCEPTION("TGaussDef: Invalid nb of gauss points for PENTA: " < conn; - static const int hexa20 [] = {0,6,4,2, 12,18,16,14, 7,5,3,1, 19,17,15,13, 8,11,10,9}; - static const int penta15[] = {0,2,4, 9,11,13, 1,3,5, 10,12,14, 6,8,7}; - static const int pyra13 [] = {0,2,4,6, 12, 1,3,5,7, 8,9,10,11}; - static const int tetra10[] = {0,2,4, 9, 1,3,5, 6,7,8}; - static const int quad8 [] = {0,2,4,6, 1,3,5,7}; - static const int tria6 [] = {0,2,4, 1,3,5}; - static const int seg3 [] = {0,2,1}; - if ( conn.empty() ) - { - conn.resize( MaxMedCellType + 1, 0 ); - conn[ NORM_HEXA20 ] = hexa20; - conn[ NORM_PENTA15] = penta15; - conn[ NORM_PYRA13 ] = pyra13; - conn[ NORM_TETRA10] = tetra10; - conn[ NORM_SEG3 ] = seg3; - conn[ NORM_TRI6 ] = tria6; - conn[ NORM_QUAD8 ] = quad8; - } - return conn[ type ]; -} - -//================================================================================ -/*! - * \brief Avoid coping sortedNodeIDs - */ -//================================================================================ - -Cell::Cell(const Cell& ma) - : _nodes(ma._nodes), _reverse(ma._reverse), _sortedNodeIDs(0), _number(ma._number) -{ - if ( ma._sortedNodeIDs ) - { - _sortedNodeIDs = new int[ _nodes.size() ]; - std::copy( ma._sortedNodeIDs, ma._sortedNodeIDs + _nodes.size(), _sortedNodeIDs ); - } -} - -//================================================================================ -/*! - * \brief Rerturn the i-th link of face - */ -//================================================================================ - -SauvUtilities::Link Cell::link(int i) const -{ - int i2 = ( i + 1 ) % _nodes.size(); - if ( _reverse ) - return std::make_pair( _nodes[i2]->_number, _nodes[i]->_number ); - else - return std::make_pair( _nodes[i]->_number, _nodes[i2]->_number ); -} - -//================================================================================ -/*! - * \brief creates if needed and return _sortedNodeIDs - */ -//================================================================================ - -const TID* Cell::getSortedNodes() const -{ - if ( !_sortedNodeIDs ) - { - size_t l=_nodes.size(); - _sortedNodeIDs = new int[ l ]; - - for (size_t i=0; i!=l; ++i) - _sortedNodeIDs[i]=_nodes[i]->_number; - std::sort( _sortedNodeIDs, _sortedNodeIDs + l ); - } - return _sortedNodeIDs; -} - -//================================================================================ -/*! - * \brief Compare sorted ids of cell nodes - */ -//================================================================================ - -bool Cell::operator< (const Cell& ma) const -{ - if ( _nodes.size() == 1 ) - return _nodes[0] < ma._nodes[0]; - - const int* v1 = getSortedNodes(); - const int* v2 = ma.getSortedNodes(); - for ( const int* vEnd = v1 + _nodes.size(); v1 < vEnd; ++v1, ++v2 ) - if(*v1 != *v2) - return *v1 < *v2; - return false; -} - -//================================================================================ -/*! - * \brief Dump a Cell - */ -//================================================================================ - -std::ostream& SauvUtilities::operator<< (std::ostream& os, const SauvUtilities::Cell& ma) -{ - os << "cell " << ma._number << " (" << ma._nodes.size() << " nodes) : < " << ma._nodes[0]->_number; - for( size_t i=1; i!=ma._nodes.size(); ++i) - os << ", " << ma._nodes[i]->_number; -#ifdef _DEBUG_ - os << " > sortedNodes: "; - if ( ma._sortedNodeIDs ) { - os << "< "; - for( size_t i=0; i!=ma._nodes.size(); ++i) - os << ( i ? ", " : "" ) << ma._sortedNodeIDs[i]; - os << " >"; - } - else { - os << "NULL"; - } -#endif - return os; -} - -//================================================================================ -/*! - * \brief Return nb of elements in the group - */ -//================================================================================ - -int Group::size() const -{ - int sizze = 0; - if ( !_relocTable.empty() ) - sizze = _relocTable.size(); - else if ( _medGroup ) - sizze = _medGroup->getNumberOfTuples(); - else if ( !_cells.empty() ) - sizze = _cells.size(); - else - for ( size_t i = 0; i < _groups.size(); ++i ) - sizze += _groups[i]->size(); - return sizze; -} - -//================================================================================ -/*! - * \brief Conver gibi element type to med one - */ -//================================================================================ - -INTERP_KERNEL::NormalizedCellType SauvUtilities::gibi2medGeom( size_t gibiType ) -{ - if ( gibiType < 1 || gibiType > NbGibiCellTypes ) - return NORM_ERROR; - - return GibiTypeToMed[ gibiType - 1 ]; -} - -//================================================================================ -/*! - * \brief Conver med element type to gibi one - */ -//================================================================================ - -int SauvUtilities::med2gibiGeom( INTERP_KERNEL::NormalizedCellType medGeomType ) -{ - for ( unsigned int i = 0; i < NbGibiCellTypes; i++ ) - if ( GibiTypeToMed[ i ] == medGeomType ) - return i + 1; - - return -1; -} - -//================================================================================ -/*! - * \brief Remember the file name - */ -//================================================================================ - -FileReader::FileReader(const char* fileName):_fileName(fileName),_iRead(0),_nbToRead(0) -{ -} - -//================================================================================ -/*! - * \brief Constructor of ASCII sauve file reader - */ -//================================================================================ - -ASCIIReader::ASCIIReader(const char* fileName) - :FileReader(fileName), - _file(-1) -{ -} - -//================================================================================ -/*! - * \brief Return true - */ -//================================================================================ - -bool ASCIIReader::isASCII() const -{ - return true; -} - -//================================================================================ -/*! - * \brief Try to open an ASCII file - */ -//================================================================================ - -bool ASCIIReader::open() -{ -#ifdef WIN32 - _file = ::_open (_fileName.c_str(), _O_RDONLY|_O_BINARY); -#else - _file = ::open (_fileName.c_str(), O_RDONLY); -#endif - if (_file >= 0) - { - _start = new char [GIBI_BufferSize]; // working buffer beginning - //_tmpBuf = new char [GIBI_MaxOutputLen]; - _ptr = _start; - _eptr = _start; - _lineNb = 0; - } - else - { - //THROW_IK_EXCEPTION("Can't open file "<<_fileName << " fd: " << _file); - } - return (_file >= 0); -} - -//================================================================================ -/*! - * \brief Close the file - */ -//================================================================================ - -ASCIIReader::~ASCIIReader() -{ - if (_file >= 0) - { - ::close (_file); - if (_start != 0L) - { - delete [] _start; - //delete [] _tmpBuf; - _start = 0; - } - _file = -1; - } -} - -//================================================================================ -/*! - * \brief Return a next line of the file - */ -//================================================================================ - -bool ASCIIReader::getNextLine (char* & line, bool raiseOEF /*= true*/ ) -{ - if ( getLine( line )) return true; - if ( raiseOEF ) - THROW_IK_EXCEPTION("Unexpected EOF on ln "<<_lineNb); - return false; -} - -//================================================================================ -/*! - * \brief Read a next line of the file if necessary - */ -//================================================================================ - -bool ASCIIReader::getLine(char* & line) -{ - bool aResult = true; - // Check the state of the buffer; - // if there is too little left, read the next portion of data - int nBytesRest = _eptr - _ptr; - if (nBytesRest < GIBI_MaxOutputLen) - { - if (nBytesRest > 0) - { - // move the remaining portion to the buffer beginning - for ( int i = 0; i < nBytesRest; ++i ) - _start[i] = _ptr[i]; - //memcpy (_tmpBuf, _ptr, nBytesRest); - //memcpy (_start, _tmpBuf, nBytesRest); - } - else - { - nBytesRest = 0; - } - _ptr = _start; - const int nBytesRead = ::read (_file, - &_start [nBytesRest], - GIBI_BufferSize - nBytesRest); - nBytesRest += nBytesRead; - _eptr = &_start [nBytesRest]; - } - // Check the buffer for the end-of-line - char * ptr = _ptr; - while (true) - { - // Check for end-of-the-buffer, the ultimate criterion for termination - if (ptr >= _eptr) - { - if (nBytesRest <= 0) - aResult = false; - else - _eptr[-1] = '\0'; - break; - } - // seek the line-feed character - if (ptr[0] == '\n') - { - if (ptr[-1] == '\r') - ptr[-1] = '\0'; - ptr[0] = '\0'; - ++ptr; - break; - } - ++ptr; - } - // Output the result - line = _ptr; - _ptr = ptr; - _lineNb++; - - return aResult; -} - -//================================================================================ -/*! - * \brief Prepare for iterating over given nb of values - * \param nbToRead - nb of fields to read - * \param nbPosInLine - nb of fields in one line - * \param width - field width - * \param shift - shift from line beginning to the field start - */ -//================================================================================ - -void ASCIIReader::init( int nbToRead, int nbPosInLine, int width, int shift /*= 0*/ ) -{ - _nbToRead = nbToRead; - _nbPosInLine = nbPosInLine; - _width = width; - _shift = shift; - _iPos = _iRead = 0; - if ( _nbToRead ) - { - getNextLine( _curPos ); - _curPos = _curPos + _shift; - } - else - { - _curPos = 0; - } - _curLocale.clear(); -} - -//================================================================================ -/*! - * \brief Prepare for iterating over given nb of string values - */ -//================================================================================ - -void ASCIIReader::initNameReading(int nbValues, int width /*= 8*/) -{ - init( nbValues, 72 / ( width + 1 ), width, 1 ); -} - -//================================================================================ -/*! - * \brief Prepare for iterating over given nb of integer values - */ -//================================================================================ - -void ASCIIReader::initIntReading(int nbValues) -{ - init( nbValues, 10, 8 ); -} - -//================================================================================ -/*! - * \brief Prepare for iterating over given nb of real values - */ -//================================================================================ - -void ASCIIReader::initDoubleReading(int nbValues) -{ - init( nbValues, 3, 22 ); - - // Correction 2 of getDouble(): set "C" numeric locale to read numbers - // with dot decimal point separator, as it is in SAUVE files - _curLocale = setlocale(LC_NUMERIC, "C"); -} - -//================================================================================ -/*! - * \brief Return true if not all values have been read - */ -//================================================================================ - -bool ASCIIReader::more() const -{ - bool result = false; - if ( _iRead < _nbToRead) - { - if ( _curPos ) result = true; - } - return result; -} - -//================================================================================ -/*! - * \brief Go to the nex value - */ -//================================================================================ - -void ASCIIReader::next() -{ - if ( !more() ) - THROW_IK_EXCEPTION("SauvUtilities::ASCIIReader::next(): no more() values to read"); - ++_iRead; - ++_iPos; - if ( _iRead < _nbToRead ) - { - if ( _iPos >= _nbPosInLine ) - { - getNextLine( _curPos ); - _curPos = _curPos + _shift; - _iPos = 0; - } - else - { - _curPos = _curPos + _width + _shift; - } - } - else - { - _curPos = 0; - if ( !_curLocale.empty() ) - { - setlocale(LC_NUMERIC, _curLocale.c_str()); - _curLocale.clear(); - } - } -} - -//================================================================================ -/*! - * \brief Return the current integer value - */ -//================================================================================ - -int ASCIIReader::getInt() const -{ - // fix for two glued ints (issue 0021009): - // Line nb | File contents - // ------------------------------------------------------------------------------------ - // 53619905 | 1 2 6 8 - // 53619906 | SCALAIRE - // 53619907 | -63312600499 1 0 0 0 -2 0 2 - // where -63312600499 is actualy -633 and 12600499 - char hold=_curPos[_width]; - _curPos[_width] = '\0'; - int result = atoi( _curPos ); - _curPos[_width] = hold; - return result; - //return atoi(str()); -} - -//================================================================================ -/*! - * \brief Return the current float value - */ -//================================================================================ - -float ASCIIReader::getFloat() const -{ - return getDouble(); -} - -//================================================================================ -/*! - * \brief Return the current double value - */ -//================================================================================ - -double ASCIIReader::getDouble() const -{ - //std::string aStr (_curPos); - - // Correction: add missing 'E' specifier - // int aPosStart = aStr.find_first_not_of(" \t"); - // if (aPosStart < (int)aStr.length()) { - // int aPosSign = aStr.find_first_of("+-", aPosStart + 1); // pass the leading symbol, as it can be a sign - // if (aPosSign < (int)aStr.length()) { - // if (aStr[aPosSign - 1] != 'e' && aStr[aPosSign - 1] != 'E') - // aStr.insert(aPosSign, "E", 1); - // } - // } - - // Different Correction (more optimal) - // Sample: - // 0.00000000000000E+00 -2.37822406690632E+01 6.03062748797469E+01 - // 7.70000000000000-100 7.70000000000000+100 7.70000000000000+100 - //0123456789012345678901234567890123456789012345678901234567890123456789 - const size_t posE = 18; - std::string aStr (_curPos); - if ( aStr.find('E') < 0 && aStr.find('e') < 0 ) - { - if ( aStr.size() < posE+1 ) - THROW_IK_EXCEPTION("No more doubles (line #" << lineNb() << ")"); - aStr.insert( posE, "E", 1 ); - return atof(aStr.c_str()); - } - return atof( _curPos ); -} - -//================================================================================ -/*! - * \brief Return the current string value - */ -//================================================================================ - -std::string ASCIIReader::getName() const -{ - int len = _width; - while (( _curPos[len-1] == ' ' || _curPos[len-1] == 0) && len > 0 ) - len--; - return std::string( _curPos, len ); -} - -//================================================================================ -/*! - * \brief Constructor of a binary sauve file reader - */ -//================================================================================ - -XDRReader::XDRReader(const char* fileName) :FileReader(fileName), _xdrs_file(NULL) -{ -} - -//================================================================================ -/*! - * \brief Close the XDR sauve file - */ -//================================================================================ - -XDRReader::~XDRReader() -{ -#ifdef HAS_XDR - if ( _xdrs_file ) - { - xdr_destroy((XDR*)_xdrs); - free((XDR*)_xdrs); - ::fclose(_xdrs_file); - _xdrs_file = NULL; - } -#endif -} - -//================================================================================ -/*! - * \brief Return false - */ -//================================================================================ - -bool XDRReader::isASCII() const -{ - return false; -} - -//================================================================================ -/*! - * \brief Try to open an XRD file - */ -//================================================================================ - -bool XDRReader::open() -{ - bool xdr_ok = false; -#ifdef HAS_XDR -#ifdef WIN32 - if ((_xdrs_file = ::fopen(_fileName.c_str(), "rb"))) -#else - if ((_xdrs_file = ::fopen(_fileName.c_str(), "r"))) -#endif - { - _xdrs = (XDR *)malloc(sizeof(XDR)); - xdrstdio_create((XDR*)_xdrs, _xdrs_file, XDR_DECODE); - - const int maxsize = 10; - char icha[maxsize+1]; - char* icha2 = icha; - if (( xdr_ok = xdr_string((XDR*)_xdrs, &icha2, maxsize))) - { - icha[maxsize] = '\0'; - xdr_ok = (strcmp(icha, "CASTEM XDR") == 0); - } - if ( !xdr_ok ) - { - xdr_destroy((XDR*)_xdrs); - free((XDR*)_xdrs); - fclose(_xdrs_file); - _xdrs_file = NULL; - } - } -#endif - return xdr_ok; -} - -//================================================================================ -/*! - * \brief A stub - */ -//================================================================================ - -bool XDRReader::getNextLine (char* &, bool ) -{ - return true; -} - -//================================================================================ -/*! - * \brief Prepare for iterating over given nb of values - * \param nbToRead - nb of fields to read - * \param width - field width - */ -//================================================================================ - -void XDRReader::init( int nbToRead, int width/*=0*/ ) -{ - if(_iRead < _nbToRead) - { - std::cout << "_iRead, _nbToRead : " << _iRead << " " << _nbToRead << std::endl; - std::cout << "Unfinished iteration before new one !" << std::endl; - THROW_IK_EXCEPTION("SauvUtilities::XDRReader::init(): Unfinished iteration before new one !"); - } - _iRead = 0; - _nbToRead = nbToRead; - _width = width; -} - -//================================================================================ -/*! - * \brief Prepare for iterating over given nb of string values - */ -//================================================================================ - -void XDRReader::initNameReading(int nbValues, int width) -{ - init( nbValues, width ); - _xdr_kind = _xdr_kind_char; - if(nbValues*width) - { - unsigned int nels = nbValues*width; - _xdr_cvals = (char*)malloc((nels+1)*sizeof(char)); -#ifdef HAS_XDR - xdr_string((XDR*)_xdrs, &_xdr_cvals, nels); -#endif - _xdr_cvals[nels] = '\0'; - } -} - -//================================================================================ -/*! - * \brief Prepare for iterating over given nb of integer values - */ -//================================================================================ - -void XDRReader::initIntReading(int nbValues) -{ - init( nbValues ); - _xdr_kind = _xdr_kind_int; - if(nbValues) - { -#ifdef HAS_XDR - unsigned int nels = nbValues; - unsigned int actual_nels; - _xdr_ivals = (int*)malloc(nels*sizeof(int)); - xdr_array((XDR*)_xdrs, (char **)&_xdr_ivals, &actual_nels, nels, sizeof(int), (xdrproc_t)xdr_int); -#endif - } -} - -//================================================================================ -/*! - * \brief Prepare for iterating over given nb of real values - */ -//================================================================================ - -void XDRReader::initDoubleReading(int nbValues) -{ - init( nbValues ); - _xdr_kind = _xdr_kind_double; - if(nbValues) - { -#ifdef HAS_XDR - unsigned int nels = nbValues; - unsigned int actual_nels; - _xdr_dvals = (double*)malloc(nels*sizeof(double)); - xdr_array((XDR*)_xdrs, (char **)&_xdr_dvals, &actual_nels, nels, sizeof(double), (xdrproc_t)xdr_double); -#endif - } -} - -//================================================================================ -/*! - * \brief Return true if not all values have been read - */ -//================================================================================ - -bool XDRReader::more() const -{ - return _iRead < _nbToRead; -} - -//================================================================================ -/*! - * \brief Go to the nex value - */ -//================================================================================ - -void XDRReader::next() -{ - if ( !more() ) - THROW_IK_EXCEPTION("SauvUtilities::XDRReader::next(): no more() values to read"); - - ++_iRead; - if ( _iRead < _nbToRead ) - { - } - else - { - if(_xdr_kind == _xdr_kind_char) free(_xdr_cvals); - if(_xdr_kind == _xdr_kind_int) free(_xdr_ivals); - if(_xdr_kind == _xdr_kind_double) free(_xdr_dvals); - _xdr_kind = _xdr_kind_null; - } -} - -//================================================================================ -/*! - * \brief Return the current integer value - */ -//================================================================================ - -int XDRReader::getInt() const -{ - if(_iRead < _nbToRead) - { - return _xdr_ivals[_iRead]; - } - else - { - int result = 0; -#ifdef HAS_XDR - xdr_int((XDR*)_xdrs, &result); -#endif - return result; - } -} - -//================================================================================ -/*! - * \brief Return the current float value - */ -//================================================================================ - -float XDRReader::getFloat() const -{ - float result = 0; -#ifdef HAS_XDR - xdr_float((XDR*)_xdrs, &result); -#endif - return result; -} - -//================================================================================ -/*! - * \brief Return the current double value - */ -//================================================================================ - -double XDRReader::getDouble() const -{ - if(_iRead < _nbToRead) - { - return _xdr_dvals[_iRead]; - } - else - { - double result = 0; -#ifdef HAS_XDR - xdr_double((XDR*)_xdrs, &result); -#endif - return result; - } -} - -//================================================================================ -/*! - * \brief Return the current string value - */ -//================================================================================ - -std::string XDRReader::getName() const -{ - int len = _width; - char* s = _xdr_cvals + _iRead*_width; - while (( s[len-1] == ' ' || s[len-1] == 0) && len > 0 ) - len--; - return std::string( s, len ); -} - -//================================================================================ -/*! - * \brief Throw an exception if not all needed data is present - */ -//================================================================================ - -void IntermediateMED::checkDataAvailability() const -{ - if ( _spaceDim == 0 ) - THROW_IK_EXCEPTION("Wrong file format"); // it is the first record in the sauve file - - if ( _groups.empty() ) - THROW_IK_EXCEPTION("No elements have been read"); - - if ( _points.empty() || _nbNodes == 0 ) - THROW_IK_EXCEPTION("Nodes of elements are not filled"); - - if ( _coords.empty() ) - THROW_IK_EXCEPTION("Node coordinates are missing"); - - if ( _coords.size() < _nbNodes * _spaceDim ) - THROW_IK_EXCEPTION("Nodes and coordinates mismatch"); -} - -//================================================================================ -/*! - * \brief Safely adds a new Group - */ -//================================================================================ - -Group* IntermediateMED::addNewGroup(std::vector* groupsToFix) -{ - if ( _groups.size() == _groups.capacity() ) // re-allocation would occure - { - std::vector newGroups( _groups.size() ); - newGroups.push_back( Group() ); - - for ( size_t i = 0; i < _groups.size(); ++i ) - { - // avoid copying _cells - std::vector cells; - cells.swap( _groups[i]._cells ); - newGroups[i] = _groups[i]; - newGroups[i]._cells.swap( cells ); - - // correct pointers to sub-groups - for ( size_t j = 0; j < _groups[i]._groups.size(); ++j ) - { - int iG = _groups[i]._groups[j] - &_groups[0]; - newGroups[i]._groups[j] = & newGroups[ iG ]; - } - } - - // fix given groups - if ( groupsToFix ) - for ( size_t i = 0; i < groupsToFix->size(); ++i ) - if ( (*groupsToFix)[i] ) - { - int iG = (*groupsToFix)[i] - &_groups[0]; - (*groupsToFix)[i] = & newGroups[ iG ]; - } - - // fix field supports - for ( int isNode = 0; isNode < 2; ++isNode ) - { - std::vector& fields = isNode ? _nodeFields : _cellFields; - for ( size_t i = 0; i < fields.size(); ++i ) - { - if ( !fields[i] ) continue; - for ( size_t j = 0; j < fields[i]->_sub.size(); ++j ) - if ( fields[i]->_sub[j]._support ) - { - int iG = fields[i]->_sub[j]._support - &_groups[0]; - fields[i]->_sub[j]._support = & newGroups[ iG ]; - } - if ( fields[i]->_group ) - { - int iG = fields[i]->_group - &_groups[0]; - fields[i]->_group = & newGroups[ iG ]; - } - } - } - - _groups.swap( newGroups ); - } - else - { - _groups.push_back( Group() ); - } - return &_groups.back(); -} - -//================================================================================ -/*! - * \brief Makes ParaMEDMEM::MEDFileData from self - */ -//================================================================================ - -ParaMEDMEM::MEDFileData* IntermediateMED::convertInMEDFileDS() -{ - MEDCouplingAutoRefCountObjectPtr< MEDFileUMesh > mesh = makeMEDFileMesh(); - MEDCouplingAutoRefCountObjectPtr< MEDFileFields > fields = makeMEDFileFields(mesh); - - MEDCouplingAutoRefCountObjectPtr< MEDFileMeshes > meshes = MEDFileMeshes::New(); - MEDCouplingAutoRefCountObjectPtr< MEDFileData > medData = MEDFileData::New(); - meshes->pushMesh( mesh ); - medData->setMeshes( meshes ); - if ( fields ) medData->setFields( fields ); - - return medData.retn(); -} - -//================================================================================ -/*! - * \brief Creates ParaMEDMEM::MEDFileUMesh from its data - */ -//================================================================================ - -ParaMEDMEM::MEDFileUMesh* IntermediateMED::makeMEDFileMesh() -{ - // check if all needed piles are present - checkDataAvailability(); - - // set long names - setGroupLongNames(); - - // fix element orientation - if ( _spaceDim == 2 || _spaceDim == 1 ) - orientElements2D(); - else if ( _spaceDim == 3 ) - orientElements3D(); - - // process groups - decreaseHierarchicalDepthOfSubgroups(); - eraseUselessGroups(); - //detectMixDimGroups(); - - // assign IDs - _points.numberNodes(); - numberElements(); - - // make the med mesh - - MEDFileUMesh* mesh = MEDFileUMesh::New(); - - DataArrayDouble *coords = getCoords(); - setConnectivity( mesh, coords ); - setGroups( mesh ); - - coords->decrRef(); - - if ( !mesh->getName().c_str() || strlen( mesh->getName().c_str() ) == 0 ) - mesh->setName( "MESH" ); - - return mesh; -} - -//================================================================================ -/*! - * \brief Set long names to groups - */ -//================================================================================ - -void IntermediateMED::setGroupLongNames() -{ - // IMP 0020434: mapping GIBI names to MED names - // set med names to objects (mesh, fields, support, group or other) - - std::set treatedGroups; - - std::list::iterator itGIBItoMED = _listGIBItoMED_mail.begin(); - for (; itGIBItoMED != _listGIBItoMED_mail.end(); itGIBItoMED++) - { - if ( (int)_groups.size() < itGIBItoMED->gibi_id ) continue; - - SauvUtilities::Group & grp = _groups[itGIBItoMED->gibi_id - 1]; - - // if there are several names for grp then the 1st name is the name - // of grp and the rest ones are names of groups referring grp (issue 0021311) - const bool isRefName = !treatedGroups.insert( itGIBItoMED->gibi_id ).second; - if ( !isRefName ) - { - grp._name = _mapStrings[ itGIBItoMED->med_id ]; - } - else if ( !grp._refNames.empty() && grp._refNames.back().empty() ) - { - for ( unsigned i = 0; i < grp._refNames.size(); ++i ) - if ( grp._refNames[i].empty() ) - grp._refNames[i] = _mapStrings[ (*itGIBItoMED).med_id ]; - } - else - { - grp._refNames.push_back( _mapStrings[ (*itGIBItoMED).med_id ]); - } - } -} - -//================================================================================ -/*! - * \brief Set long names to fields - */ -//================================================================================ - -void IntermediateMED::setFieldLongNames(std::set< std::string >& usedNames) -{ - std::list::iterator itGIBItoMED = _listGIBItoMED_cham.begin(); - for (; itGIBItoMED != _listGIBItoMED_cham.end(); itGIBItoMED++) - { - if (itGIBItoMED->gibi_pile == PILE_FIELD) - { - _cellFields[itGIBItoMED->gibi_id - 1]->_name = _mapStrings[itGIBItoMED->med_id]; - } - else if (itGIBItoMED->gibi_pile == PILE_NODES_FIELD) - { - _nodeFields[itGIBItoMED->gibi_id - 1]->_name = _mapStrings[itGIBItoMED->med_id]; - } - } // iterate on _listGIBItoMED_cham - - for (itGIBItoMED =_listGIBItoMED_comp.begin(); itGIBItoMED != _listGIBItoMED_comp.end(); itGIBItoMED++) - { - std::string medName = _mapStrings[itGIBItoMED->med_id]; - std::string gibiName = _mapStrings[itGIBItoMED->gibi_id]; - - bool name_found = false; - for ( int isNodal = 0; isNodal < 2 && !name_found; ++isNodal ) - { - std::vector & fields = isNodal ? _nodeFields : _cellFields; - for ( size_t ifi = 0; ifi < fields.size() && !name_found; ifi++) - { - if (medName.find( fields[ifi]->_name + "." ) == 0 ) - { - std::vector& aSubDs = fields[ifi]->_sub; - int nbSub = aSubDs.size(); - for (int isu = 0; isu < nbSub; isu++) - for (int ico = 0; ico < aSubDs[isu].nbComponents(); ico++) - { - if (aSubDs[isu].compName(ico) == gibiName) - { - std::string medNameCompo = medName.substr( fields[ifi]->_name.size() + 1 ); - fields[ifi]->_sub[isu].compName(ico) = medNameCompo; - } - } - } - } - } - } // iterate on _listGIBItoMED_comp - - for ( size_t i = 0; i < _nodeFields.size() ; i++) - usedNames.insert( _nodeFields[i]->_name ); - for ( size_t i = 0; i < _cellFields.size() ; i++) - usedNames.insert( _cellFields[i]->_name ); -} - -//================================================================================ -/*! - * \brief Decrease hierarchical depth of subgroups - */ -//================================================================================ - -void IntermediateMED::decreaseHierarchicalDepthOfSubgroups() -{ - for (size_t i=0; i!=_groups.size(); ++i) - { - Group& grp = _groups[i]; - for (size_t j = 0; j < grp._groups.size(); ++j ) - { - Group & sub_grp = *grp._groups[j]; - if ( !sub_grp._groups.empty() ) - { - // replace j with its 1st subgroup - grp._groups[j] = sub_grp._groups[0]; - // push back the rest subs - grp._groups.insert( grp._groups.end(), ++sub_grp._groups.begin(), sub_grp._groups.end() ); - } - } - // remove empty sub-_groups - std::vector< Group* > newSubGroups; - newSubGroups.reserve( grp._groups.size() ); - for (size_t j = 0; j < grp._groups.size(); ++j ) - if ( !grp._groups[j]->empty() ) - newSubGroups.push_back( grp._groups[j] ); - if ( newSubGroups.size() < grp._groups.size() ) - grp._groups.swap( newSubGroups ); - } -} - -//================================================================================ -/*! - * \brief Erase _groups that won't be converted - */ -//================================================================================ - -void IntermediateMED::eraseUselessGroups() -{ - // propagate _isProfile=true to sub-groups of composite groups - // for (size_t int i=0; i!=_groups.size(); ++i) - // { - // Group* grp = _groups[i]; - // if ( grp->_isProfile && !grp->_groups.empty() ) - // for (size_t j = 0; j < grp->_groups.size(); ++j ) - // grp->_groups[j]->_isProfile=true; - // } - std::set groups2convert; - // keep not named sub-groups of field supports - for (size_t i=0; i!=_groups.size(); ++i) - { - Group& grp = _groups[i]; - if ( grp._isProfile && !grp._groups.empty() ) - groups2convert.insert( grp._groups.begin(), grp._groups.end() ); - } - - // keep named groups and their subgroups - for (size_t i=0; i!=_groups.size(); ++i) - { - Group& grp = _groups[i]; - if ( !grp._name.empty() && !grp.empty() ) - { - groups2convert.insert( &grp ); - groups2convert.insert( grp._groups.begin(), grp._groups.end() ); - } - } - // erase groups that are not in groups2convert and not _isProfile - for (size_t i=0; i!=_groups.size(); ++i) - { - Group* grp = &_groups[i]; - if ( !grp->_isProfile && !groups2convert.count( grp ) ) - { - grp->_cells.clear(); - grp->_groups.clear(); - } - } -} - -//================================================================================ -/*! - * \brief Detect _groups of mixed dimension - */ -//================================================================================ - -void IntermediateMED::detectMixDimGroups() -{ - //hasMixedCells = false; - for ( size_t i=0; i < _groups.size(); ++i ) - { - Group& grp = _groups[i]; - if ( grp._groups.size() < 2 ) - continue; - - // check if sub-groups have different dimension - unsigned dim1 = getDim( &grp ); - for ( size_t j = 1; j < grp._groups.size(); ++j ) - { - unsigned dim2 = getDim( grp._groups[j] ); - if ( dim1 != dim2 ) - { - grp._cells.clear(); - grp._groups.clear(); - if ( !grp._name.empty() ) - std::cout << "Erase a group with elements of different dim |" << grp._name << "|"<< std::endl; - break; - } - } - } -} - -//================================================================================ -/*! - * \brief Fix connectivity of elements in 2D space - */ -//================================================================================ - -void IntermediateMED::orientElements2D() -{ - std::set::const_iterator elemIt, elemEnd; - std::vector< std::pair > swapVec; - - // ------------------------------------ - // fix connectivity of quadratic edges - // ------------------------------------ - std::set& quadEdges = _cellsByType[ INTERP_KERNEL::NORM_SEG3 ]; - if ( !quadEdges.empty() ) - { - elemIt = quadEdges.begin(), elemEnd = quadEdges.end(); - for ( ; elemIt != elemEnd; ++elemIt ) - ConvertQuadratic( INTERP_KERNEL::NORM_SEG3, *elemIt ); - } - - CellsByDimIterator faceIt( *this, 2 ); - while ( const std::set * faces = faceIt.nextType() ) - { - TCellType cellType = faceIt.type(); - bool isQuadratic = getGibi2MedQuadraticInterlace( cellType ); - - getReverseVector( cellType, swapVec ); - - // ------------------------------------ - // fix connectivity of quadratic faces - // ------------------------------------ - if ( isQuadratic ) - for ( elemIt = faces->begin(), elemEnd = faces->end(); elemIt != elemEnd; elemIt++ ) - ConvertQuadratic( cellType, *elemIt ); - - // -------------------------- - // orient faces clockwise - // -------------------------- - // COMMENTED for issue 0022612 note 17739 - // int iQuad = isQuadratic ? 2 : 1; - // for ( elemIt = faces->begin(), elemEnd = faces->end(); elemIt != elemEnd; elemIt++ ) - // { - // // look for index of the most left node - // int iLeft = 0, iNode, nbNodes = elemIt->_nodes.size() / iQuad; - // double x, minX = nodeCoords( elemIt->_nodes[0] )[0]; - // for ( iNode = 1; iNode < nbNodes; ++iNode ) - // if (( x = nodeCoords( elemIt->_nodes[ iNode ])[ 0 ]) < minX ) - // minX = x, iLeft = iNode; - - // // indeces of the nodes neighboring the most left one - // int iPrev = ( iLeft - 1 < 0 ) ? nbNodes - 1 : iLeft - 1; - // int iNext = ( iLeft + 1 == nbNodes ) ? 0 : iLeft + 1; - // // find components of prev-left and left-next vectors - // double xP = nodeCoords( elemIt->_nodes[ iPrev ])[ 0 ]; - // double yP = nodeCoords( elemIt->_nodes[ iPrev ])[ 1 ]; - // double xN = nodeCoords( elemIt->_nodes[ iNext ])[ 0 ]; - // double yN = nodeCoords( elemIt->_nodes[ iNext ])[ 1 ]; - // double xL = nodeCoords( elemIt->_nodes[ iLeft ])[ 0 ]; - // double yL = nodeCoords( elemIt->_nodes[ iLeft ])[ 1 ]; - // double xPL = xL - xP, yPL = yL - yP; // components of prev-left vector - // double xLN = xN - xL, yLN = yN - yL; // components of left-next vector - // // normalise y of the vectors - // double modPL = sqrt ( xPL * xPL + yPL * yPL ); - // double modLN = sqrt ( xLN * xLN + yLN * yLN ); - // if ( modLN > std::numeric_limits::min() && - // modPL > std::numeric_limits::min() ) - // { - // yPL /= modPL; - // yLN /= modLN; - // // summary direction of neighboring links must be positive - // bool clockwise = ( yPL + yLN > 0 ); - // if ( !clockwise ) - // reverse( *elemIt, swapVec ); - // } - // } - } -} - -//================================================================================ -/*! - * \brief Fix connectivity of elements in 3D space - */ -//================================================================================ - -void IntermediateMED::orientElements3D() -{ - // set _reverse flags of faces - // COMMENTED for issue 0022612 note 17739 - //orientFaces3D(); - - // ----------------- - // fix connectivity - // ----------------- - - std::set::const_iterator elemIt, elemEnd; - std::vector< std::pair > swapVec; - - for ( int dim = 1; dim <= 3; ++dim ) - { - CellsByDimIterator cellsIt( *this, dim ); - while ( const std::set * elems = cellsIt.nextType() ) - { - TCellType cellType = cellsIt.type(); - bool isQuadratic = getGibi2MedQuadraticInterlace( cellType ); - getReverseVector( cellType, swapVec ); - - elemIt = elems->begin(), elemEnd = elems->end(); - for ( ; elemIt != elemEnd; elemIt++ ) - { - // GIBI connectivity -> MED one - if( isQuadratic ) - ConvertQuadratic( cellType, *elemIt ); - - // reverse faces - if ( elemIt->_reverse ) - reverse ( *elemIt, swapVec ); - } - } - } - - // COMMENTED for issue 0022612 note 17739 - //orientVolumes(); -} - -//================================================================================ -/*! - * \brief Orient equally (by setting _reverse flag) all connected faces in 3D space - */ -//================================================================================ - -void IntermediateMED::orientFaces3D() -{ - // fill map of links and their faces - std::set faces; - std::map fgm; - std::map > linkFacesMap; - std::map >::iterator lfIt, lfIt2; - - for (size_t i=0; i!=_groups.size(); ++i) - { - Group& grp = _groups[i]; - if ( !grp._cells.empty() && getDimension( grp._cellType ) == 2 ) - for ( size_t j = 0; j < grp._cells.size(); ++j ) - if ( faces.insert( grp._cells[j] ).second ) - { - for ( size_t k = 0; k < grp._cells[j]->_nodes.size(); ++k ) - linkFacesMap[ grp._cells[j]->link( k ) ].push_back( grp._cells[j] ); - fgm.insert( std::make_pair( grp._cells[j], &grp )); - } - } - // dump linkFacesMap - // for ( lfIt = linkFacesMap.begin(); lfIt!=linkFacesMap.end(); lfIt++) { - // cout<< "LINK: " << lfIt->first.first << "-" << lfIt->first.second << std::endl; - // std::list & fList = lfIt->second; - // std::list::iterator fIt = fList.begin(); - // for ( ; fIt != fList.end(); fIt++ ) - // cout << "\t" << **fIt << fgm[*fIt]->nom << std::endl; - // } - - // Each oriented link must appear in one face only, else a face is reversed. - - std::queue faceQueue; /* the queue contains well oriented faces - whose neighbors orientation is to be checked */ - bool manifold = true; - while ( !linkFacesMap.empty() ) - { - if ( faceQueue.empty() ) - { - assert( !linkFacesMap.begin()->second.empty() ); - faceQueue.push( linkFacesMap.begin()->second.front() ); - } - while ( !faceQueue.empty() ) - { - const Cell* face = faceQueue.front(); - faceQueue.pop(); - - // loop on links of - for ( int i = 0; i < (int)face->_nodes.size(); ++i ) - { - Link link = face->link( i ); - // find the neighbor faces - lfIt = linkFacesMap.find( link ); - int nbFaceByLink = 0; - std::list< const Cell* > ml; - if ( lfIt != linkFacesMap.end() ) - { - std::list & fList = lfIt->second; - std::list::iterator fIt = fList.begin(); - assert( fIt != fList.end() ); - for ( ; fIt != fList.end(); fIt++, nbFaceByLink++ ) - { - ml.push_back( *fIt ); - if ( *fIt != face ) // wrongly oriented neighbor face - { - const Cell* badFace = *fIt; - // reverse and remove badFace from linkFacesMap - for ( int j = 0; j < (int)badFace->_nodes.size(); ++j ) - { - Link badlink = badFace->link( j ); - if ( badlink == link ) continue; - lfIt2 = linkFacesMap.find( badlink ); - if ( lfIt2 != linkFacesMap.end() ) - { - std::list & ff = lfIt2->second; - std::list::iterator lfIt3 = find( ff.begin(), ff.end(), badFace ); - // check if badFace has been found, - // else we can't erase it - // case of degenerated face in edge - if (lfIt3 != ff.end()) - { - ff.erase( lfIt3 ); - if ( ff.empty() ) - linkFacesMap.erase( lfIt2 ); - } - } - } - badFace->_reverse = true; // reverse - //INFOS_MED( "REVERSE " << *badFace ); - faceQueue.push( badFace ); - } - } - linkFacesMap.erase( lfIt ); - } - // add good neighbors to the queue - Link revLink( link.second, link.first ); - lfIt = linkFacesMap.find( revLink ); - if ( lfIt != linkFacesMap.end() ) - { - std::list & fList = lfIt->second; - std::list::iterator fIt = fList.begin(); - for ( ; fIt != fList.end(); fIt++, nbFaceByLink++ ) - { - ml.push_back( *fIt ); - if ( *fIt != face ) - faceQueue.push( *fIt ); - } - linkFacesMap.erase( lfIt ); - } - if ( nbFaceByLink > 2 ) - { - if ( manifold ) - { - std::list::iterator ii = ml.begin(); - std::cout << nbFaceByLink << " faces by 1 link:" << std::endl; - for( ; ii!= ml.end(); ii++ ) - std::cout << "in sub-mesh <" << fgm[ *ii ]->_name << "> " << **ii << std::endl; - } - manifold = false; - } - } // loop on links of the being checked face - } // loop on the face queue - } // while ( !linkFacesMap.empty() ) - - if ( !manifold ) - std::cout << " -> Non manifold mesh, faces orientation may be incorrect" << std::endl; -} - -//================================================================================ -/*! - * \brief Orient volumes according to MED conventions: - * normal of a bottom (first) face should be outside - */ -//================================================================================ - -void IntermediateMED::orientVolumes() -{ - std::set::const_iterator elemIt, elemEnd; - std::vector< std::pair > swapVec; - - CellsByDimIterator cellsIt( *this, 3 ); - while ( const std::set * elems = cellsIt.nextType() ) - { - TCellType cellType = cellsIt.type(); - elemIt = elems->begin(), elemEnd = elems->end(); - int nbBottomNodes = 0; - switch ( cellType ) - { - case NORM_TETRA4: - case NORM_TETRA10: - case NORM_PENTA6: - case NORM_PENTA15: - nbBottomNodes = 3; break; - case NORM_PYRA5: - case NORM_PYRA13: - case NORM_HEXA8: - case NORM_HEXA20: - nbBottomNodes = 4; break; - default: continue; - } - getReverseVector( cellType, swapVec ); - - for ( ; elemIt != elemEnd; elemIt++ ) - { - // find a normal to the bottom face - const double* n[4]; - n[0] = nodeCoords( elemIt->_nodes[0]); // 3 bottom nodes - n[1] = nodeCoords( elemIt->_nodes[1]); - n[2] = nodeCoords( elemIt->_nodes[2]); - n[3] = nodeCoords( elemIt->_nodes[nbBottomNodes]); // a top node - double vec01[3]; // vector n[0]-n[1] - vec01[0] = n[1][0] - n[0][0]; - vec01[1] = n[1][1] - n[0][1]; - vec01[2] = n[1][2] - n[0][2]; - double vec02 [3]; // vector n[0]-n[2] - vec02[0] = n[2][0] - n[0][0]; - vec02[1] = n[2][1] - n[0][1]; - vec02[2] = n[2][2] - n[0][2]; - double normal [3]; // vec01 ^ vec02 - normal[0] = vec01[1] * vec02[2] - vec01[2] * vec02[1]; - normal[1] = vec01[2] * vec02[0] - vec01[0] * vec02[2]; - normal[2] = vec01[0] * vec02[1] - vec01[1] * vec02[0]; - // check if the 102 angle is convex - if ( nbBottomNodes > 3 ) - { - const double* n3 = nodeCoords( elemIt->_nodes[nbBottomNodes-1] );// last bottom node - double vec03 [3]; // vector n[0]-n3 - vec03[0] = n3[0] - n[0][0]; - vec03[1] = n3[1] - n[0][1]; - vec03[2] = n3[2] - n[0][2]; - if ( fabs( normal[0]+normal[1]+normal[2] ) <= std::numeric_limits::max() ) // vec01 || vec02 - { - normal[0] = vec01[1] * vec03[2] - vec01[2] * vec03[1]; // vec01 ^ vec03 - normal[1] = vec01[2] * vec03[0] - vec01[0] * vec03[2]; - normal[2] = vec01[0] * vec03[1] - vec01[1] * vec03[0]; - } - else - { - double vec [3]; // normal ^ vec01 - vec[0] = normal[1] * vec01[2] - normal[2] * vec01[1]; - vec[1] = normal[2] * vec01[0] - normal[0] * vec01[2]; - vec[2] = normal[0] * vec01[1] - normal[1] * vec01[0]; - double dot2 = vec[0]*vec03[0] + vec[1]*vec03[1] + vec[2]*vec03[2]; // vec*vec03 - if ( dot2 < 0 ) // concave -> reverse normal - { - normal[0] *= -1; - normal[1] *= -1; - normal[2] *= -1; - } - } - } - // direction from top to bottom - double tbDir[3]; - tbDir[0] = n[0][0] - n[3][0]; - tbDir[1] = n[0][1] - n[3][1]; - tbDir[2] = n[0][2] - n[3][2]; - - // compare 2 directions: normal and top-bottom - double dot = normal[0]*tbDir[0] + normal[1]*tbDir[1] + normal[2]*tbDir[2]; - if ( dot < 0. ) // need reverse - reverse( *elemIt, swapVec ); - - } // loop on volumes of one geometry - } // loop on 3D geometry types - -} - -//================================================================================ -/*! - * \brief Assign new IDs to nodes by skipping not used nodes and return their number - */ -//================================================================================ - -int NodeContainer::numberNodes() -{ - int id = 1; - for ( size_t i = 0; i < _nodes.size(); ++i ) - for ( size_t j = 0; j < _nodes[i].size(); ++j ) - if ( _nodes[i][j].isUsed() ) - _nodes[i][j]._number = id++; - return id-1; -} - - -//================================================================================ -/*! - * \brief Assign new IDs to elements - */ -//================================================================================ - -void IntermediateMED::numberElements() -{ - std::set::const_iterator elemIt, elemEnd; - - // numbering _cells of type NORM_POINT1 by node number - { - const std::set& points = _cellsByType[ INTERP_KERNEL::NORM_POINT1 ]; - elemIt = points.begin(), elemEnd = points.end(); - for ( ; elemIt != elemEnd; ++elemIt ) - elemIt->_number = elemIt->_nodes[0]->_number; - } - - // numbering 1D-3D _cells - for ( int dim = 1; dim <= 3; ++dim ) - { - // check if re-numeration is needed (to try to keep elem oreder as in sauve file ) - bool ok = true, renumEntity = false; - CellsByDimIterator cellsIt( *this, dim ); - int prevNbElems = 0; - while ( const std::set * typeCells = cellsIt.nextType() ) - { - TID minNumber = std::numeric_limits::max(), maxNumber = 0; - for ( elemIt = typeCells->begin(), elemEnd = typeCells->end(); elemIt!=elemEnd; ++elemIt) - { - if ( elemIt->_number < minNumber ) minNumber = elemIt->_number; - if ( elemIt->_number > maxNumber ) maxNumber = elemIt->_number; - } - TID typeSize = typeCells->size(); - if ( typeSize != maxNumber - minNumber + 1 ) - ok = false; - if ( prevNbElems != 0 ) { - if ( minNumber == 1 ) - renumEntity = true; - else if ( prevNbElems+1 != (int)minNumber ) - ok = false; - } - prevNbElems += typeSize; - } - - if ( ok && renumEntity ) // each geom type was numerated separately - { - cellsIt.init( dim ); - prevNbElems = cellsIt.nextType()->size(); // no need to renumber the first type - while ( const std::set * typeCells = cellsIt.nextType() ) - { - for ( elemIt = typeCells->begin(), elemEnd = typeCells->end(); elemIt!=elemEnd; ++elemIt) - elemIt->_number += prevNbElems; - prevNbElems += typeCells->size(); - } - } - if ( !ok ) - { - int cellID=1; - cellsIt.init( dim ); - while ( const std::set * typeCells = cellsIt.nextType() ) - for ( elemIt = typeCells->begin(), elemEnd = typeCells->end(); elemIt!=elemEnd; ++elemIt) - elemIt->_number = cellID++; - } - } -} - -//================================================================================ -/*! - * \brief Creates coord array - */ -//================================================================================ - -ParaMEDMEM::DataArrayDouble * IntermediateMED::getCoords() -{ - DataArrayDouble* coordArray = DataArrayDouble::New(); - coordArray->alloc( _nbNodes, _spaceDim ); - double * coordPrt = coordArray->getPointer(); - for ( int i = 0, nb = _points.size(); i < nb; ++i ) - { - Node* n = getNode( i+1 ); - if ( n->isUsed() ) - { - const double* nCoords = nodeCoords( n ); - std::copy( nCoords, nCoords+_spaceDim, coordPrt ); - coordPrt += _spaceDim; - } - } - return coordArray; -} - -//================================================================================ -/*! - * \brief Sets connectivity of elements to the mesh - * \param mesh - mesh to fill in - * \param coords - coordinates that must be shared by all meshes of different dim - */ -//================================================================================ - -void IntermediateMED::setConnectivity( ParaMEDMEM::MEDFileUMesh* mesh, - ParaMEDMEM::DataArrayDouble* coords ) -{ - int meshDim = 0; - - mesh->setCoords( coords ); - - std::set::const_iterator elemIt, elemEnd; - for ( int dim = 3; dim > 0; --dim ) - { - CellsByDimIterator dimCells( *this, dim ); - - int nbOfCells = 0; - while ( const std::set * cells = dimCells.nextType() ) - nbOfCells += cells->size(); - if ( nbOfCells == 0 ) - continue; - - if ( !meshDim ) meshDim = dim; - - MEDCouplingUMesh* dimMesh = MEDCouplingUMesh::New(); - dimMesh->setCoords( coords ); - dimMesh->setMeshDimension( dim ); - dimMesh->allocateCells( nbOfCells ); - - int prevNbCells = 0; - dimCells.init( dim ); - while ( const std::set * cells = dimCells.nextType() ) - { - // fill connectivity array to take into account order of elements in the sauv file - const int nbCellNodes = cells->begin()->_nodes.size(); - std::vector< TID > connectivity( cells->size() * nbCellNodes ); - int * nodalConnOfCell; - for ( elemIt = cells->begin(), elemEnd = cells->end(); elemIt != elemEnd; ++elemIt ) - { - const Cell& cell = *elemIt; - const int index = cell._number - 1 - prevNbCells; - nodalConnOfCell = &connectivity[ index * nbCellNodes ]; - if ( cell._reverse ) - for ( int i = nbCellNodes-1; i >= 0; --i ) - *nodalConnOfCell++ = cell._nodes[i]->_number - 1; - else - for ( int i = 0; i < nbCellNodes; ++i ) - *nodalConnOfCell++ = cell._nodes[i]->_number - 1; - } - prevNbCells += cells->size(); - - // fill dimMesh - TCellType cellType = dimCells.type(); - nodalConnOfCell = &connectivity[0]; - for ( size_t i = 0; i < cells->size(); ++i, nodalConnOfCell += nbCellNodes ) - dimMesh->insertNextCell( cellType, nbCellNodes, nodalConnOfCell ); - } - dimMesh->finishInsertingCells(); - mesh->setMeshAtLevel( dim - meshDim, dimMesh ); - dimMesh->decrRef(); - } -} - -//================================================================================ -/*! - * \brief Fill in the mesh with groups - * \param mesh - mesh to fill in - */ -//================================================================================ - -void IntermediateMED::setGroups( ParaMEDMEM::MEDFileUMesh* mesh ) -{ - bool isMeshNameSet = false; - const int meshDim = mesh->getMeshDimension(); - for ( int dim = 0; dim <= meshDim; ++dim ) - { - const int meshDimRelToMaxExt = ( dim == 0 ? 1 : dim - meshDim ); - - std::vector medGroups; - std::vector > refGroups; - for ( size_t i = 0; i < _groups.size(); ++i ) - { - Group& grp = _groups[i]; - if ( (int)getDim( &grp ) != dim && - grp._groups.empty() ) // to allow groups on diff dims - continue; - // convert only named groups or field supports - if ( grp.empty() || (grp._name.empty() && !grp._isProfile )) - continue; - //if ( grp._medGroup ) continue; // already converted - - // sort cells by ID and remember their initial order in the group - TCellToOrderMap cell2order; - unsigned orderInGroup = 0; - std::vector< Group* > groupVec; - if ( grp._groups.empty() ) groupVec.push_back( & grp ); - else groupVec = grp._groups; - for ( size_t iG = 0; iG < groupVec.size(); ++iG ) - { - Group* aG = groupVec[ iG ]; - if ( (int)getDim( aG ) != dim ) - continue; - for ( size_t iC = 0; iC < aG->_cells.size(); ++iC ) - cell2order.insert( cell2order.end(), std::make_pair( aG->_cells[iC], orderInGroup++ )); - } - if ( cell2order.empty() ) - continue; - bool isSelfIntersect = ( orderInGroup != cell2order.size() ); - if ( isSelfIntersect ) // self intersecting group - { - std::ostringstream msg; - msg << "Self intersecting sub-mesh: id = " << i+1 - << ", name = |" << grp._name << "|" << std::endl - << " nb unique elements = " << cell2order.size() << std::endl - << " total nb elements = " << orderInGroup; - if ( grp._isProfile ) - { - THROW_IK_EXCEPTION( msg.str() ); - } - else - { - std::cout << msg.str() << std::endl; - } - } - // create a med group - grp._medGroup = DataArrayInt::New(); - grp._medGroup->setName( grp._name.c_str() ); - grp._medGroup->alloc( cell2order.size(), /*nbOfCompo=*/1 ); - int * idsPtr = grp._medGroup->getPointer(); - TCellToOrderMap::iterator cell2orderIt, cell2orderEnd = cell2order.end(); - for ( cell2orderIt = cell2order.begin(); cell2orderIt != cell2orderEnd; ++cell2orderIt ) - *idsPtr++ = (*cell2orderIt).first->_number - 1; - - // try to set the mesh name - if ( !isMeshNameSet && - dim == meshDim && - !grp._name.empty() && - grp.size() == mesh->getSizeAtLevel( meshDimRelToMaxExt )) - { - mesh->setName( grp._name.c_str() ); - isMeshNameSet = true; - } - if ( !grp._name.empty() ) - { - medGroups.push_back( grp._medGroup ); - } - // set relocation table - setRelocationTable( &grp, cell2order ); - - // Issue 0021311. Use case: a gibi group has references (recorded in pile 1) - // and several names (pile 27) refer (pile 10) to this group. - // We create a copy of this group per each named reference - std::set uniqueNames; - uniqueNames.insert( grp._name ); - for ( unsigned iRef = 0 ; iRef < grp._refNames.size(); ++iRef ) - if ( !grp._refNames[ iRef ].empty() && - uniqueNames.insert( grp._refNames[ iRef ]).second ) // for name uniqueness (23155) - { - refGroups.push_back( grp._medGroup->deepCpy() ); - refGroups.back()->setName( grp._refNames[ iRef ].c_str() ); - medGroups.push_back( refGroups.back() ); - } - } - mesh->setGroupsAtLevel( meshDimRelToMaxExt, medGroups ); - } -} - -//================================================================================ -/*! - * \brief Return true if the group is on all elements and return its relative dimension - */ -//================================================================================ - -bool IntermediateMED::isOnAll( const Group* grp, int & dimRel ) const -{ - int dim = getDim( grp ); - - int nbElems = 0; - if ( dim == 0 ) - { - nbElems = _nbNodes; - dimRel = 0; - } - else - { - CellsByDimIterator dimCells( *this, dim ); - while ( const std::set * cells = dimCells.nextType() ) - nbElems += cells->size(); - - int meshDim = 3; - for ( ; meshDim > 0; --meshDim ) - { - dimCells.init( meshDim ); - if ( dimCells.nextType() ) - break; - } - dimRel = dim - meshDim; - } - - bool onAll = ( nbElems == grp->size() ); - return onAll; -} - -//================================================================================ -/*! - * \brief Makes fields from own data - */ -//================================================================================ - -ParaMEDMEM::MEDFileFields * IntermediateMED::makeMEDFileFields(ParaMEDMEM::MEDFileUMesh* mesh) -{ - if ( _nodeFields.empty() && _cellFields.empty() ) return 0; - - // set long names - std::set< std::string > usedFieldNames; - setFieldLongNames(usedFieldNames); - - MEDFileFields* fields = MEDFileFields::New(); - - for ( size_t i = 0; i < _nodeFields.size(); ++i ) - setFields( _nodeFields[i], fields, mesh, i+1, usedFieldNames ); - - for ( size_t i = 0; i < _cellFields.size(); ++i ) - setFields( _cellFields[i], fields, mesh, i+1, usedFieldNames ); - - return fields; -} - -//================================================================================ -/*! - * \brief Make med fields from a SauvUtilities::DoubleField - */ -//================================================================================ - -void IntermediateMED::setFields( SauvUtilities::DoubleField* fld, - ParaMEDMEM::MEDFileFields* medFields, - ParaMEDMEM::MEDFileUMesh* mesh, - const TID castemID, - std::set< std::string >& usedFieldNames) -{ - bool sameNbGauss = true; - if ( !fld || !fld->isMedCompatible( sameNbGauss )) return; - - if ( !sameNbGauss ) - fld->splitSubWithDiffNbGauss(); - - // if ( !fld->hasCommonSupport() ): - // each sub makes MEDFileFieldMultiTS - // else: - // unite several subs into a MEDCouplingFieldDouble - - const bool uniteSubs = fld->hasCommonSupport() && sameNbGauss; - if ( !uniteSubs ) - std::cout << "Castem field #" << castemID << " <" << fld->_name - << "> is incompatible with MED format, so we split it into several fields:" << std::endl; - - for ( size_t iSub = 0; iSub < fld->_sub.size(); ) - { - // set field name - if ( !uniteSubs || fld->_name.empty() ) - makeFieldNewName( usedFieldNames, fld ); - - // allocate values - DataArrayDouble * values = DataArrayDouble::New(); - values->alloc( fld->getNbTuples(iSub), fld->_sub[iSub].nbComponents() ); - - // set values - double * valPtr = values->getPointer(); - if ( uniteSubs ) - { - int nbElems = fld->_group->size(); - for ( int elemShift = 0; elemShift < nbElems && iSub < fld->_sub.size(); ) - elemShift += fld->setValues( valPtr, iSub++, elemShift ); - setTS( fld, values, medFields, mesh ); - } - else - { - fld->setValues( valPtr, iSub ); - setTS( fld, values, medFields, mesh, iSub++ ); - - std::cout << fld->_name << " with compoments"; - for ( size_t i = 0; i < (size_t)fld->_sub[iSub-1].nbComponents(); ++i ) - std::cout << " " << fld->_sub[iSub-1]._comp_names[ i ]; - std::cout << std::endl; - } - } -} - -//================================================================================ -/*! - * \brief Store value array of a field into med fields - */ -//================================================================================ - -void IntermediateMED::setTS( SauvUtilities::DoubleField* fld, - ParaMEDMEM::DataArrayDouble* values, - ParaMEDMEM::MEDFileFields* medFields, - ParaMEDMEM::MEDFileUMesh* mesh, - const int iSub) -{ - // treat a field support - const Group* support = fld->getSupport( iSub ); - int dimRel; - const bool onAll = isOnAll( support, dimRel ); - if ( !onAll && support->_name.empty() ) - { - const_cast(support)->_name += "PFL_" + fld->_name; - support->_medGroup->setName( support->_name.c_str() ); - } - - // make and fill a time-stamp - - MEDCouplingFieldDouble * timeStamp = MEDCouplingFieldDouble::New( fld->getMedType( iSub ), - fld->getMedTimeDisc() ); - timeStamp->setName( fld->_name.c_str() ); - timeStamp->setDescription( fld->_description.c_str() ); - // set the mesh - if ( onAll ) - { - MEDCouplingAutoRefCountObjectPtr - < MEDCouplingUMesh > dimMesh = mesh->getMeshAtLevel( dimRel ); - timeStamp->setMesh( dimMesh ); - } - else if ( timeStamp->getTypeOfField() == ParaMEDMEM::ON_NODES ) - { - DataArrayDouble * coo = mesh->getCoords(); - MEDCouplingAutoRefCountObjectPtr - subCoo = coo->selectByTupleId(support->_medGroup->begin(), - support->_medGroup->end()); - MEDCouplingAutoRefCountObjectPtr< MEDCouplingUMesh > nodeSubMesh = - MEDCouplingUMesh::Build0DMeshFromCoords( subCoo ); - timeStamp->setMesh( nodeSubMesh ); - } - else - { - MEDCouplingAutoRefCountObjectPtr - < MEDCouplingUMesh > dimMesh = mesh->getMeshAtLevel( dimRel ); - MEDCouplingAutoRefCountObjectPtr - subMesh = dimMesh->buildPart(support->_medGroup->begin(), - support->_medGroup->end()); - timeStamp->setMesh( subMesh); - } - // set values - for ( size_t i = 0; i < (size_t)fld->_sub[iSub].nbComponents(); ++i ) - values->setInfoOnComponent( i, fld->_sub[iSub]._comp_names[ i ].c_str() ); - timeStamp->setArray( values ); - values->decrRef(); - // set gauss points - if ( timeStamp->getTypeOfField() == ParaMEDMEM::ON_GAUSS_PT ) - { - TGaussDef gaussDef( fld->_sub[iSub]._support->_cellType, - fld->_sub[iSub].nbGauss() ); - timeStamp->setGaussLocalizationOnType( fld->_sub[iSub]._support->_cellType, - gaussDef.myRefCoords, - gaussDef.myCoords, - gaussDef.myWeights ); - } - // get a field to add the time-stamp - bool isNewMedField = false; - if ( !fld->_curMedField || fld->_name != fld->_curMedField->getName() ) - { - fld->_curMedField = MEDFileFieldMultiTS::New(); - isNewMedField = true; - } - - // set an order - const int nbTS = fld->_curMedField->getNumberOfTS(); - if ( nbTS > 0 ) - timeStamp->setOrder( nbTS ); - - // add the time-stamp - timeStamp->checkCoherency(); - if ( onAll ) - fld->_curMedField->appendFieldNoProfileSBT( timeStamp ); - else - fld->_curMedField->appendFieldProfile( timeStamp, mesh, dimRel, support->_medGroup ); - timeStamp->decrRef(); - - if ( isNewMedField ) // timeStamp must be added before this - { - medFields->pushField( fld->_curMedField ); - } -} - -//================================================================================ -/*! - * \brief Make a new unique name for a field - */ -//================================================================================ - -void IntermediateMED::makeFieldNewName(std::set< std::string >& usedNames, - SauvUtilities::DoubleField* fld ) -{ - std::string base = fld->_name; - if ( base.empty() ) - { - base = "F_"; - } - else - { - std::string::size_type pos = base.rfind('_'); - if ( pos != std::string::npos ) - base = base.substr( 0, pos+1 ); - else - base += '_'; - } - - int i = 1; - do - { - fld->_name = base + SauvUtilities::toString( i++ ); - } - while( !usedNames.insert( fld->_name ).second ); -} - -//================================================================================ -/*! - * \brief Split sub-components with different nb of gauss points into several sub-components - * \param [in,out] fld - a field to split if necessary - */ -//================================================================================ - -void DoubleField::splitSubWithDiffNbGauss() -{ - for ( size_t iSub = 0; iSub < _sub.size(); ++iSub ) - { - if ( _sub[iSub].isSameNbGauss() ) continue; - - _sub.insert( _sub.begin() + iSub + 1, 1, _Sub_data() ); - _Sub_data & subToSplit = _sub[iSub]; - _Sub_data & subNew = _sub[iSub+1]; - size_t iDiff = 1; - while ( subToSplit._nb_gauss[ 0 ] == subToSplit._nb_gauss[ iDiff ] ) - ++iDiff; - subNew._support = subToSplit._support; - subNew._comp_names.assign( subToSplit._comp_names.begin() + iDiff, - subToSplit._comp_names.end() ); - subNew._nb_gauss.assign ( subToSplit._nb_gauss.begin() + iDiff, - subToSplit._nb_gauss.end() ); - subToSplit._comp_names.resize( iDiff ); - subToSplit._nb_gauss.resize ( iDiff ); - } -} - -//================================================================================ -/*! - * \brief Return a vector ready to fill in - */ -//================================================================================ - -std::vector< double >& DoubleField::addComponent( int nb_values ) -{ - _comp_values.push_back( std::vector< double >() ); - std::vector< double >& res = _comp_values.back(); - res.resize( nb_values ); - return res; -} - -DoubleField::~DoubleField() -{ - if(_curMedField) - _curMedField->decrRef(); -} - -//================================================================================ -/*! - * \brief Returns a supporting group - */ -//================================================================================ - -const Group* DoubleField::getSupport( const int iSub ) const -{ - return _group ? _group : _sub[iSub]._support; -} - -//================================================================================ -/*! - * \brief Return true if each sub-component is a time stamp - */ -//================================================================================ - -bool DoubleField::isMultiTimeStamps() const -{ - if ( _sub.size() < 2 ) - return false; - bool sameSupports = true; - Group* grpp1 = _sub[0]._support;// grpp NOT grp because XDR under Windows defines grp... - for ( size_t i = 1; i < _sub.size() && sameSupports; ++i ) - sameSupports = ( grpp1 == _sub[i]._support ); - - return sameSupports; -} - -//================================================================================ -/*! - * \brief True if the field can be converted into the med field - */ -//================================================================================ - -bool DoubleField::isMedCompatible(bool& sameNbGauss) const -{ - for ( size_t iSub = 0; iSub < _sub.size(); ++iSub ) - { - if ( !getSupport(iSub) || !getSupport(iSub)->_medGroup ) - THROW_IK_EXCEPTION("SauvReader INTERNAL ERROR: NULL field support"); - - sameNbGauss = true; - if ( !_sub[iSub].isSameNbGauss() ) - { - std::cout << "Field <" << _name << "> : different nb of gauss points in components" << std::endl; - sameNbGauss = false; - //return false; - } - } - return true; -} - -//================================================================================ -/*! - * \brief return true if all sub-components has same components and same nbGauss - */ -//================================================================================ - -bool DoubleField::hasSameComponentsBySupport() const -{ - std::vector< _Sub_data >::const_iterator sub_data = _sub.begin(); - const _Sub_data& first_sub_data = *sub_data; - for ( ++sub_data ; sub_data != _sub.end(); ++sub_data ) - { - if ( first_sub_data._comp_names != sub_data->_comp_names ) - return false; // diff names of components - - if ( first_sub_data._nb_gauss != sub_data->_nb_gauss && - first_sub_data._support->_cellType == sub_data->_support->_cellType) - return false; // diff nb of gauss points on same cell type - } - return true; -} - -//================================================================================ -/*! - * \brief Return type of MEDCouplingFieldDouble - */ -//================================================================================ - -ParaMEDMEM::TypeOfField DoubleField::getMedType( const int iSub ) const -{ - using namespace INTERP_KERNEL; - - const Group* grp = hasCommonSupport() ? _group : _sub[iSub]._support; - if ( _sub[iSub].nbGauss() > 1 ) - { - const CellModel& cm = CellModel::GetCellModel( _sub[iSub]._support->_cellType ); - return (int) cm.getNumberOfNodes() == _sub[iSub].nbGauss() ? ON_GAUSS_NE : ON_GAUSS_PT; - } - else - { - return getDim( grp ) == 0 ? ON_NODES : ON_CELLS; - } -} - -//================================================================================ -/*! - * \brief Return TypeOfTimeDiscretization - */ -//================================================================================ - -ParaMEDMEM::TypeOfTimeDiscretization DoubleField::getMedTimeDisc() const -{ - return ONE_TIME; - // NO_TIME = 4, - // ONE_TIME = 5, - // LINEAR_TIME = 6, - // CONST_ON_TIME_INTERVAL = 7 -} - -//================================================================================ -/*! - * \brief Return nb tuples to be used to allocate DataArrayDouble - */ -//================================================================================ - -int DoubleField::getNbTuples( const int iSub ) const -{ - int nb = 0; - if ( hasCommonSupport() && !_group->_groups.empty() ) - for ( size_t i = 0; i < _group->_groups.size(); ++i ) - nb += _sub[i].nbGauss() * _sub[i]._support->size(); - else - nb = _sub[iSub].nbGauss() * getSupport(iSub)->size(); - return nb; -} - -//================================================================================ -/*! - * \brief Store values of a sub-component and return nb of elements in the iSub - */ -//================================================================================ - -int DoubleField::setValues( double * valPtr, const int iSub, const int elemShift ) const -{ - // find values for iSub - int iComp = 0; - for ( int iS = 0; iS < iSub; ++iS ) - iComp += _sub[iS].nbComponents(); - const std::vector< double > * compValues = &_comp_values[ iComp ]; - - // Set values - - const std::vector< unsigned >& relocTable = getSupport( iSub )->_relocTable; - - const int nbElems = _sub[iSub]._support->size(); - const int nbGauss = _sub[iSub].nbGauss(); - const int nbComponents = _sub[iSub].nbComponents(); - const int nbValsByElem = nbComponents * nbGauss; - - // check nb values - int nbVals = 0; - for ( iComp = 0; iComp < nbComponents; ++iComp ) - nbVals += compValues[iComp].size(); - const bool isConstField = ( nbVals == nbComponents ); // one value per component (issue 22321) - if ( !isConstField && nbVals != nbElems * nbValsByElem ) - THROW_IK_EXCEPTION("SauvMedConvertor.cxx: support size mismatches field size"); - - // compute nb values in previous subs - int valsShift = 0; - for ( int iS = iSub-1, shift = elemShift; shift > 0; --iS) - { - int nbE = _sub[iS]._support->size(); - shift -= nbE; - valsShift += nbE * _sub[iS].nbComponents() * _sub[iS].nbGauss(); - } - - if ( isConstField ) - for ( int iE = 0; iE < nbElems; ++iE ) - { - int iMed = valsShift + nbValsByElem * ( relocTable.empty() ? iE : relocTable[iE+elemShift]-elemShift ); - for ( iComp = 0; iComp < nbComponents; ++iComp ) - valPtr[ iMed + iComp ] = compValues[iComp][ 0 ]; - } - else - for ( int iE = 0; iE < nbElems; ++iE ) - { - int iMed = valsShift + nbValsByElem * ( relocTable.empty() ? iE : relocTable[iE+elemShift]-elemShift ); - for ( iComp = 0; iComp < nbComponents; ++iComp ) - for ( int iG = 0; iG < nbGauss; ++iG ) - valPtr[ iMed + iG * nbComponents + iComp ] = compValues[iComp][ iE * nbGauss + iG ]; - } - return nbElems; -} - -//================================================================================ -/*! - * \brief Destructor of IntermediateMED - */ -//================================================================================ - -IntermediateMED::~IntermediateMED() -{ - for ( size_t i = 0; i < _nodeFields.size(); ++i ) - if ( _nodeFields[i] ) - delete _nodeFields[i]; - _nodeFields.clear(); - - for ( size_t i = 0; i < _cellFields.size(); ++i ) - if ( _cellFields[i] ) - delete _cellFields[i]; - _cellFields.clear(); - - for ( size_t i = 0; i < _groups.size(); ++i ) - if ( _groups[i]._medGroup ) - _groups[i]._medGroup->decrRef(); -} - -//================================================================================ -/*! - * \brief CellsByDimIterator constructor - */ -CellsByDimIterator::CellsByDimIterator( const IntermediateMED & medi, int dimm) -{ - myImed = & medi; - init( dimm ); -} -/*! - * \brief Initialize iteration on cells of given dimention - */ -void CellsByDimIterator::init(const int dimm) -{ - myCurType = -1; - myTypeEnd = INTERP_KERNEL::NORM_HEXA20 + 1; - myDim = dimm; -} -/*! - * \brief return next set of Cell's of required dimension - */ -const std::set< Cell > * CellsByDimIterator::nextType() -{ - while ( ++myCurType < myTypeEnd ) - if ( !myImed->_cellsByType[myCurType].empty() && ( myDim < 0 || dim(false) == myDim )) - return & myImed->_cellsByType[myCurType]; - return 0; -} -/*! - * \brief return dimension of cells returned by the last or further next() - */ -int CellsByDimIterator::dim(const bool last) const -{ - int typp = myCurType; - if ( !last ) - while ( typp < myTypeEnd && myImed->_cellsByType[typp].empty() ) - ++typp; - return typp < myTypeEnd ? getDimension( TCellType( typp )) : 4; -} -// END CellsByDimIterator ======================================================== - diff --git a/src/MEDLoader/SauvMedConvertor.hxx b/src/MEDLoader/SauvMedConvertor.hxx deleted file mode 100644 index b52cacd0f..000000000 --- a/src/MEDLoader/SauvMedConvertor.hxx +++ /dev/null @@ -1,388 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 -// 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 -// -// File : SauvMedConvertor.hxx -// Created : Tue Aug 16 14:14:02 2011 -// Author : Edward AGAPOV (eap) -// - -#ifndef __SauvMedConvertor_HXX__ -#define __SauvMedConvertor_HXX__ - -#include "InterpKernelException.hxx" -#include "NormalizedUnstructuredMesh.hxx" -#include "MEDCouplingRefCountObject.hxx" -#include "SauvUtilities.hxx" - -#include -#include -#include -#include -#include - -namespace ParaMEDMEM -{ - class DataArrayDouble; - class DataArrayInt; - class MEDFileData; - class MEDFileFields; - class MEDFileFieldMultiTS; - class MEDFileUMesh; -} - -namespace SauvUtilities -{ - struct IntermediateMED; - - // ============================================================================== - typedef int TID; // an ID countered from 1 - typedef std::pair Link; // a pair of node numbers - - typedef INTERP_KERNEL::NormalizedCellType TCellType; - - // ============================================================================== - struct Node - { - TID _number; - size_t _coordID; - - Node():_number(0){} - bool isUsed() const { return _number != 0; } - }; - - // ============================================================================== - struct Cell - { - std::vector< Node* > _nodes; - mutable bool _reverse; // to reverse orienation of a face only - mutable TID* _sortedNodeIDs; // for comparison - mutable TID _number; - - Cell(size_t nnNodes=0) : _nodes(nnNodes),_reverse(false),_sortedNodeIDs(0),_number(0) {} - Cell(const Cell& ma); - void init() const { if ( _sortedNodeIDs ) delete [] _sortedNodeIDs; _sortedNodeIDs = 0; } - ~Cell() { init(); } - - const TID* getSortedNodes() const; // creates if needed and return _sortedNodeIDs - bool operator < (const Cell& ma) const; - Link link(int i) const; - - private: - Cell& operator=(const Cell& ma); - }; - std::ostream& operator << (std::ostream& os, const Cell& ma); - - // ============================================================================== - struct Group - { - TCellType _cellType; - std::string _name; - std::vector _cells; - std::vector< Group* > _groups; // des sous-groupes composant le Group - bool _isProfile; // is a field support or not - std::vector _refNames; /* names of groups referring this one; - _refNames is resized according to nb of references - while reading a group (pile 1) and it is filled with - names while reading long names (pile 27); each named - reference is converted into a copy of the medGroup - (issue 0021311) - */ - ParaMEDMEM::DataArrayInt* _medGroup; // result of conversion - std::vector< unsigned > _relocTable; // for _cells[i] gives its index in _medGroup - - bool empty() const { return _cells.empty() && _groups.empty(); } - int size() const; - Group():_cellType(INTERP_KERNEL::NORM_ERROR), _isProfile(false), _medGroup(NULL) {} - }; - - // ============================================================================== - struct DoubleField - { - // a field contains several subcomponents each referring to its own support and - // having several named components - // ---------------------------------------------------------------------------- - struct _Sub_data // a subcomponent - // -------------------------------- - { - Group* _support; // support - std::vector _comp_names; // component names - std::vector _nb_gauss; // nb values per element in a component - - void setData( int nb_comp, Group* supp ) - { _support = supp; _comp_names.resize(nb_comp); _nb_gauss.resize(nb_comp,1); } - int nbComponents() const { return _comp_names.size(); } - std::string & compName( int i_comp ) { return _comp_names[ i_comp ]; } - bool isSameNbGauss() const { return *std::max_element( _nb_gauss.begin(), _nb_gauss.end() ) == - *std::min_element( _nb_gauss.begin(), _nb_gauss.end() ); } - int nbGauss() const { return _nb_gauss[0] ? _nb_gauss[0] : 1; } - bool hasGauss() const { return nbGauss() > 1; } - }; - // ---------------------------------------------------------------------------- - TID _idInFile; - std::string _name; - std::string _description; // field description - std::vector< _Sub_data > _sub; - Group* _group; /* if _group == NULL then each subcomponent makes a - separate med field, else all subcomponents - are converted into timestamps of one med field. - The latter is possible only if nb of components in all subs - is the same and supports of subcomponents do not overlap - */ - std::vector< std::vector< double > > _comp_values; - ParaMEDMEM::MEDFileFieldMultiTS* _curMedField; - - DoubleField( int nb_sub, int total_nb_comp ) - : _sub(nb_sub), _group(NULL), _curMedField(NULL) { _comp_values.reserve( total_nb_comp ); } - ~DoubleField(); - std::vector< double >& addComponent( int nb_values ); // return a vector ready to fill in - bool hasCommonSupport() const { return _group; } // true if there is one support for all subs - bool hasSameComponentsBySupport() const; - - bool isMultiTimeStamps() const; - bool isMedCompatible(bool& sameNbGauss) const; - ParaMEDMEM::TypeOfField getMedType( const int iSub=0 ) const; - ParaMEDMEM::TypeOfTimeDiscretization getMedTimeDisc() const; - int getNbTuples( const int iSub=0 ) const; - int getNbValuesPerElement( const int iSub=0 ) const; - int getNbGauss( const int iSub=0 ) const; - const Group* getSupport( const int iSub=0 ) const; - int setValues( double * valPtr, const int iSub, const int elemShift=0 ) const; - void splitSubWithDiffNbGauss(); - - //virtual void dump(std::ostream&) const; - //virtual ~DoubleField() {} - }; - // ============================================================================== - /*! - * \if developper - * Iterator on set of Cell's of given dimension - * \endif - */ - class CellsByDimIterator - { - public: - CellsByDimIterator( const IntermediateMED & medi, int dim=-1); // dim=-1 - for all dimensions - void init(const int dim=-1); - - //!< return next set of Cell's of required dimension - const std::set * nextType(); - //!< return dimension of Cell's returned by the last or further next() - int dim(const bool last=true) const; - //!< return type of Cell's returned by the last next() - TCellType type() const { return TCellType( myCurType ); } - - private: - const IntermediateMED* myImed; - int myCurType, myTypeEnd; - int myDim; - }; - - // ============================================================================== - /*! - * \if developper - * Container of Node's. Prevents re-allocation at addition of Node's - * \endif - */ - class NodeContainer - { - std::vector< std::vector< Node > > _nodes; - public: - Node* getNode( const TID nID ) - { - const size_t chunkSize = 1000; - const size_t chunkID = (nID-1) / chunkSize; - const size_t pos = (nID-1) % chunkSize; - if ( _nodes.size() < chunkID+1 ) - { - std::vector< std::vector< Node > > newNodes(chunkID+1); - for ( size_t i = 0; i < _nodes.size(); ++i ) - newNodes[i].swap( _nodes[i] ); - for ( size_t i = _nodes.size(); i < newNodes.size(); ++i ) - newNodes[i].resize( chunkSize ); - _nodes.swap( newNodes ); - } - return & _nodes[chunkID][pos]; - } - bool empty() const { return _nodes.empty(); } - size_t size() const { return empty() ? 0 : _nodes.size() * _nodes[0].size(); } - int numberNodes(); - }; - - // ============================================================================== - /*! - * \if developper - * Intermediate structure used to store data read from the Sauve format file. - * The structure provides functions that transform the stored data to the MED format - * - * The elements inserted in maillage are ordered in order to avoid duplicated elements. - * \endif - */ - struct IntermediateMED - { - unsigned _spaceDim; - unsigned _nbNodes; - NodeContainer _points; - std::vector _coords; - std::vector _groups; - std::vector _nodeFields; - std::vector _cellFields; - - // IMP 0020434: mapping GIBI names to MED names - std::list _listGIBItoMED_mail; // to read from table "MED_MAIL" of PILE_TABLES - std::list _listGIBItoMED_cham; // to read from table "MED_CHAM" of PILE_TABLES - std::list _listGIBItoMED_comp; // to read from table "MED_COMP" of PILE_TABLES - std::map _mapStrings; // to read from PILE_STRINGS - - IntermediateMED(): _spaceDim(0), _nbNodes(0) {} - ~IntermediateMED(); - - Node* getNode( TID nID ) { return _points.getNode( nID ); } - int getNbCellsOfType( TCellType type ) const { return _cellsByType[type].size(); } - const Cell* insert(TCellType type, const Cell& ma) { return &( *_cellsByType[type].insert( ma ).first ); } - Group* addNewGroup(std::vector* groupsToFix=0); - ParaMEDMEM::MEDFileData* convertInMEDFileDS(); - - private: - - ParaMEDMEM::MEDFileUMesh* makeMEDFileMesh(); - ParaMEDMEM::DataArrayDouble * getCoords(); - void setConnectivity( ParaMEDMEM::MEDFileUMesh* mesh, ParaMEDMEM::DataArrayDouble* coords ); - void setGroups( ParaMEDMEM::MEDFileUMesh* mesh ); - ParaMEDMEM::MEDFileFields * makeMEDFileFields(ParaMEDMEM::MEDFileUMesh* mesh); - void setFields( SauvUtilities::DoubleField* fld, - ParaMEDMEM::MEDFileFields* medFields, - ParaMEDMEM::MEDFileUMesh* mesh, - const TID castemID, - std::set< std::string >& usedNames); - void setTS( SauvUtilities::DoubleField* fld, - ParaMEDMEM::DataArrayDouble* values, - ParaMEDMEM::MEDFileFields* medFields, - ParaMEDMEM::MEDFileUMesh* mesh, - const int iSub=0); - void checkDataAvailability() const; - void setGroupLongNames(); - void setFieldLongNames(std::set< std::string >& usedNames); - void makeFieldNewName(std::set< std::string >& usedNames, - SauvUtilities::DoubleField* fld ); - void decreaseHierarchicalDepthOfSubgroups(); - void eraseUselessGroups(); - void detectMixDimGroups(); - void orientElements2D(); - void orientElements3D(); - void orientFaces3D(); - void orientVolumes(); - void numberElements(); - bool isOnAll( const Group* grp, int & dimRel ) const; - const double* nodeCoords( const Node* n ) { return &_coords[ (n->_coordID-1) * _spaceDim ]; } - - // IntermediateMED() - // { myNodesNumerated = myMaillesNumerated = myGroupsTreated = false; currentTypeMailles = 0; } - // ~IntermediateMED(); - - //bool myNodesNumerated, myMaillesNumerated; - - // mailles groupped by geom type; use insert() for filling in and - // _CellsByDimIterator for exploring it - //std::set<_Cell> maillage; - std::set< Cell > _cellsByType[ INTERP_KERNEL::NORM_HEXA20 + 1 ]; - friend class CellsByDimIterator; - }; - -// ============================================================================== - /*! - * \brief ASCII sauve file reader - */ - class ASCIIReader : public FileReader - { - public: - ASCIIReader(const char* fileName); - virtual ~ASCIIReader(); - virtual bool isASCII() const; - virtual bool open(); - virtual bool getNextLine (char* & line, bool raiseOEF = true ); - virtual void initNameReading(int nbValues, int width = 8); - virtual void initIntReading(int nbValues); - virtual void initDoubleReading(int nbValues); - virtual bool more() const; - virtual void next(); - virtual int getInt() const; - virtual float getFloat() const; - virtual double getDouble() const; - virtual std::string getName() const; - int lineNb() const { return _lineNb; } - - private: - - bool getLine(char* & line); - void init( int nbToRead, int nbPosInLine, int width, int shift = 0 ); - - // getting a line from the file - int _file; - char* _start; // working buffer beginning - char* _ptr; - char* _eptr; - int _lineNb; - - // line parsing - int _iPos, _nbPosInLine, _width, _shift; - char* _curPos; - }; -// ============================================================================== - /*! - * \brief XDR (binary) sauve file reader - */ - class XDRReader : public FileReader - { - public: - XDRReader(const char* fileName); - virtual ~XDRReader(); - virtual bool isASCII() const; - virtual bool open(); - virtual bool getNextLine (char* & line, bool raiseOEF = true ); - virtual void initNameReading(int nbValues, int width = 8); - virtual void initIntReading(int nbValues); - virtual void initDoubleReading(int nbValues); - virtual bool more() const; - virtual void next(); - virtual int getInt() const; - virtual float getFloat() const; - virtual double getDouble() const; - virtual std::string getName() const; - - private: - - void init( int nbToRead, int width = 0 ); - - FILE* _xdrs_file; - void* _xdrs; - int* _xdr_ivals; - double* _xdr_dvals; - char* _xdr_cvals; - int _width; - int _xdr_kind; - enum - { - _xdr_kind_null, - _xdr_kind_char, - _xdr_kind_int, - _xdr_kind_double - }; - }; -} - -#endif diff --git a/src/MEDLoader/SauvReader.cxx b/src/MEDLoader/SauvReader.cxx deleted file mode 100644 index 77c7c4f21..000000000 --- a/src/MEDLoader/SauvReader.cxx +++ /dev/null @@ -1,1216 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 -// 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 -// -// File : SauvReader.cxx -// Created : Tue Aug 16 13:57:42 2011 -// Author : Edward AGAPOV (eap) -// - -#include "SauvReader.hxx" - -#include "SauvMedConvertor.hxx" -#include "MEDCouplingAutoRefCountObjectPtr.hxx" -#include "NormalizedUnstructuredMesh.hxx" -#include "MEDCouplingRefCountObject.hxx" - -#include -#include -#include - -using namespace ParaMEDMEM; -using namespace SauvUtilities; -using namespace std; - -#define GIBI_EQUAL(var_str, stat_str) (strncmp (var_str, stat_str, strlen(stat_str)) == 0) - -//================================================================================ -/*! - * \brief Creates a reader of a given sauve file - */ -//================================================================================ - -SauvReader* SauvReader::New(const std::string& fileName) -{ - if ( fileName.empty() ) THROW_IK_EXCEPTION("Invalid file name"); - - ParaMEDMEM::MEDCouplingAutoRefCountObjectPtr< SauvUtilities::FileReader> parser; - - // try to open as XRD - parser = new XDRReader( fileName.c_str() ); - if ( parser->open() ) - { - SauvReader* reader = new SauvReader; - reader->_fileReader = parser.retn(); - return reader; - } - - // try to open as ASCII - parser = new ASCIIReader( fileName.c_str() ); - if ( parser->open() ) - { - SauvReader* reader = new SauvReader; - reader->_fileReader = parser.retn(); - return reader; - } - - THROW_IK_EXCEPTION("Unable to open file |"<< fileName << "|"); -} -//================================================================================ -/*! - * \brief Destructor - */ -//================================================================================ - -SauvReader::~SauvReader() -{ - _fileReader->decrRef(); -} - -std::size_t SauvReader::getHeapMemorySizeWithoutChildren() const -{ - return 0; -} - -std::vector SauvReader::getDirectChildrenWithNull() const -{ - return std::vector(); -} - -//================================================================================ -/*! - * \brief Return current line of ASCII file to report an error - */ -//================================================================================ - -std::string SauvReader::lineNb() const -{ - if ( isASCII() ) - return string(" (line #") + SauvUtilities::toString - ( static_cast( _fileReader )->lineNb() ) + ")"; - - return ""; -} - -//================================================================================ -/*! - * \brief Reads contents of the sauve file and convert it to MEDFileData - */ -//================================================================================ - -ParaMEDMEM::MEDFileData * SauvReader::loadInMEDFileDS() -{ - SauvUtilities::IntermediateMED iMed; // intermadiate DS - _iMed = &iMed; - - char* line; // a current line - const char* enregistrement_type=" ENREGISTREMENT DE TYPE"; - - while ( getNextLine(line, /*raiseOEF=*/false)) // external loop looking for "ENREGISTREMENT DE TYPE" - { - if ( isASCII() && !GIBI_EQUAL( line, enregistrement_type )) - continue; // "ENREGISTREMENT DE TYPE" not found -> read the next line - - // read the number of a record - int recordNumber; - if ( isASCII() ) - recordNumber = atoi( line + strlen(enregistrement_type) + 1 ); - else - recordNumber = getInt(); - - // read the record - if ( recordNumber == 2 ) - readRecord2(); - else if (recordNumber == 4 ) - readRecord4(); - else if (recordNumber == 7 ) - readRecord7(); - else if (recordNumber == 5 ) - break; // stop reading - else - if ( !isASCII() ) - THROW_IK_EXCEPTION("XDR : ENREGISTREMENT DE TYPE " << recordNumber << " not implemented!!!"); - } - - ParaMEDMEM::MEDFileData* medFileData = iMed.convertInMEDFileDS(); - - return medFileData; -} - -//================================================================================ -/*! - * \brief Reads "ENREGISTREMENT DE TYPE 4" - */ -//================================================================================ - -void SauvReader::readRecord4() -{ - if ( !isASCII() ) - { - getInt(); // skip NIVEAU - getInt(); // skip ERREUR - _iMed->_spaceDim = getInt(); - getFloat(); // skip DENSITE - } - else - { - char* line; - getNextLine(line); - const char* s = " NIVEAU 15 NIVEAU ERREUR 0 DIMENSION"; - _iMed->_spaceDim = atoi( line + strlen( s ) + 1 ); - if ( !GIBI_EQUAL( line, " NIVEAU" )) - THROW_IK_EXCEPTION( "Could not read space dimension" << lineNb() ); - } - if ( _iMed->_spaceDim < 1 ) - THROW_IK_EXCEPTION( "Invalid space dimension:" << _iMed->_spaceDim ); -} - -//================================================================================ -/*! - * \brief Reads "ENREGISTREMENT DE TYPE 7" - */ -//================================================================================ - -void SauvReader::readRecord7() -{ - if ( !isASCII() ) - { - getInt(); // skip NOMBRE INFO CASTEM2000 - getInt(); // skip IFOUR - getInt(); // skip NIFOUR - getInt(); // skip IFOMOD - getInt(); // skip IECHO - getInt(); // skip IIMPI - getInt(); // skip IOSPI - getInt(); // skip ISOTYP - getInt(); // skip NSDPGE - } - else - { - // skip 3 lines: - // NOMBRE INFO CASTEM2000 8 - // IFOUR 2 NIFOUR 0 IFOMOD 2 IECHO 1 IIMPI 0 IOSPI 0 ISOTYP 1 - // NSDPGE 0 - char* line; - getNextLine(line); - getNextLine(line); - getNextLine(line); - } -} - -//================================================================================ -/*! - * \brief Reads the pile number, nb of objects and nb named of objects - */ -//================================================================================ - -int SauvReader::readPileNumber(int& nbNamedObjects, int& nbObjects) -{ - // FORMAT(' PILE NUMERO',I4,'NBRE ObjectS NOMMES',I8,'NBRE ObjectS',I8) - int pileNumber; - if ( !isASCII() ) - { - initIntReading(3); - pileNumber = getInt(); next(); - nbNamedObjects = getInt(); next(); - nbObjects = getInt(); next(); - } - else - { - char* line; - getNextLine(line); - const char *s1 = " PILE NUMERO", *s2 = "NBRE ObjectS NOMMES", *s3 = "NBRE ObjectS"; - if ( ! GIBI_EQUAL( line, s1 ) ) - THROW_IK_EXCEPTION("Could not read the pile number " << lineNb() ); - line = line + strlen(s1); - pileNumber = atoi( line ); - line = line + 4 + strlen(s2); - nbNamedObjects = atoi( line ); - line = line + 8 + strlen(s3); - nbObjects = atoi( line ); - } - if ( nbNamedObjects<0 ) - THROW_IK_EXCEPTION("Invalid nb of named objects: " << nbNamedObjects << lineNb() ); - if ( nbObjects<0) - THROW_IK_EXCEPTION("Invalid nb of objects: " << nbObjects << lineNb() ); - // It appears to be a valid case - // if ( nbObjects_spaceDim == 0 ) - THROW_IK_EXCEPTION("Missing ENREGISTREMENT DE TYPE 4"); - - // read a pile number - int pileNumber, nbNamedObjects, nbObjects; - pileNumber = readPileNumber(nbNamedObjects, nbObjects); - - if ( !_encounteredPiles.insert( pileNumber ).second && // piles may repeat - isASCII()) - return; - - // read object names and their indices - vector objectNames(nbNamedObjects); - for ( initNameReading( nbNamedObjects ); more(); next() ) - objectNames[ index() ] = getName(); - - vector nameIndices(nbNamedObjects); - for ( initIntReading( nbNamedObjects ); more(); next() ) - nameIndices[ index() ] = getInt(); - - switch ( pileNumber ) - { - case PILE_SOUS_MAILLAGE: - read_PILE_SOUS_MAILLAGE(nbObjects, objectNames, nameIndices); - break; - case PILE_NODES_FIELD: - read_PILE_NODES_FIELD(nbObjects, objectNames, nameIndices); - break; - case PILE_TABLES: - read_PILE_TABLES(nbObjects, objectNames, nameIndices); - break; - case PILE_LREEL: - read_PILE_LREEL(nbObjects, objectNames, nameIndices); - break; - case PILE_LOGIQUES: - read_PILE_LOGIQUES(nbObjects, objectNames, nameIndices); - break; - case PILE_FLOATS: - read_PILE_FLOATS(nbObjects, objectNames, nameIndices); - break; - case PILE_INTEGERS: - read_PILE_INTEGERS(nbObjects, objectNames, nameIndices); - break; - case PILE_STRINGS: - read_PILE_STRINGS(nbObjects, objectNames, nameIndices); - break; - case PILE_LMOTS: - read_PILE_LMOTS(nbObjects, objectNames, nameIndices); - break; - case PILE_NOEUDS: - read_PILE_NOEUDS(nbObjects, objectNames, nameIndices); - break; - case PILE_COORDONNEES: - read_PILE_COORDONNEES(nbObjects, objectNames, nameIndices); - break; - case PILE_MODL: - read_PILE_MODL(nbObjects, objectNames, nameIndices); - break; - case PILE_FIELD: - read_PILE_FIELD(nbObjects, objectNames, nameIndices); - break; - default: - if ( !isASCII() ) - THROW_IK_EXCEPTION("XDR : reading PILE " << pileNumber << " not implemented !!!"); - } -} - -//================================================================================ -/*! - * \brief Reads "PILE NUMERO 1": gibi sub-meshes that are converted into med groups - */ -//================================================================================ - -void SauvReader::read_PILE_SOUS_MAILLAGE(const int nbObjects, - std::vector& objectNames, - std::vector& nameIndices) -{ - _iMed->_groups.reserve(nbObjects*2); // fields may add some groups - - char* line; - map strangeGroupType; - int i; - - for (int object=0; object!=nbObjects; ++object) // loop on sub-groups - { - initIntReading( 5 ); - int castemCellType = getIntNext(); - int nbSubGroups = getIntNext(); - int nbReferences = getIntNext(); - int nbNodesPerElem = getIntNext(); - int nbElements = getIntNext(); - - _iMed->_groups.push_back(Group()); - SauvUtilities::Group & group = _iMed->_groups.back(); - - // Issue 0021311. Allocate places for names of referring groups - // that will be possibly filled after reading long names from - // PILE_TABLES and PILE_STRINGS - group._refNames.resize( nbReferences ); - - // castemCellType=0 corresponds to a sub-mesh composed of other sub-meshes - if (castemCellType==0 && nbSubGroups>0) - { - group._groups.resize( nbSubGroups ); - for ( initIntReading( nbSubGroups ); more(); next() ) - group._groups[ index() ] = & _iMed->_groups[ getInt() - 1 ]; - //std::sort( group._groups.begin(), group._groups.end() ); // for _groups comparison in getFieldSupport() - } - // skip references - if ( isASCII() ) - for ( i = 0; i < nbReferences; i += 10 ) // FORMAT(10I8) - getNextLine(line); - else - for (initIntReading(nbReferences); more(); next()); - - // skip colors - if ( isASCII() ) - for ( i = 0; i < nbElements; i += 10 ) - getNextLine(line); - else - for (initIntReading(nbElements); more(); next()); - - // not a composite group - if (castemCellType>0 && nbSubGroups==0) - { - group._cellType = SauvUtilities::gibi2medGeom(castemCellType); - - initIntReading( nbElements * nbNodesPerElem ); - if ( group._cellType == INTERP_KERNEL::NORM_ERROR ) // look for group end - { - for ( ; more(); next()); - strangeGroupType.insert( make_pair( object, castemCellType )); - } - else - { - // if ( group._cellType == MED_POINT1 ) group._cellType = NORM_ERROR; // issue 21199 - - // read connectivity of elements of a group - SauvUtilities::Cell ma( nbNodesPerElem ); - SauvUtilities::Node* pNode; - group._cells.resize( nbElements ); - for ( i = 0; i < nbElements; ++i ) - { - ma.init(); - for ( int n = 0; n < nbNodesPerElem; ++n ) - { - int nodeID = getIntNext(); - pNode = _iMed->getNode( nodeID ); - ma._nodes[n] = pNode; - _iMed->_nbNodes += ( !pNode->isUsed() ); - pNode->_number = nodeID; - } - ma._number = _iMed->getNbCellsOfType( group._cellType ) + 1; - group._cells[i] = _iMed->insert( group._cellType, ma ); - } - } - } - } // loop on groups - - // set group names - for (i=0; i!=(int)objectNames.size(); ++i) - { - int grpID = nameIndices[i]; - SauvUtilities::Group & grp = _iMed->_groups[ grpID-1 ]; - if ( !grp._name.empty() ) // a group has several names - { // create a group with subgroup grp and named grp.name - SauvUtilities::Group* newGroup = _iMed->addNewGroup(); - newGroup->_groups.push_back( &_iMed->_groups[ grpID-1 ]); - newGroup->_name = grp._name; - } - grp._name=objectNames[i]; -#ifdef _DEBUG - map::iterator it = strangeGroupType.find( grpID - 1 ); - if ( it != strangeGroupType.end() ) - cout << "Skip " << grp._name << " of not supported CASTEM type: " << it->second << endl; -#endif - } -} // read_PILE_SOUS_MAILLAGE() - -//================================================================================ -/*! - * \brief Skip "PILE NUMERO 18" of XDR file - */ -//================================================================================ - -void SauvReader::read_PILE_LREEL (const int nbObjects, std::vector&, std::vector&) -{ - if ( isXRD() ) - { - for (int object=0; object!=nbObjects; ++object) // pour chaque Group - { - initIntReading(1); - int nb_vals = getIntNext(); - initDoubleReading(nb_vals); - for(int i=0; i&, std::vector&) -{ - if ( isXRD() ) - { - initIntReading(1); - int nb_vals = getIntNext(); - initIntReading(nb_vals); - for(int i=0; i&, std::vector&) -{ - if ( isXRD() ) - { - initIntReading(1); - int nb_vals = getIntNext(); - initDoubleReading(nb_vals); - for(int i=0; i&, std::vector&) -{ - if ( isXRD() ) - { - initIntReading(1); - int nb_vals = getIntNext(); - initIntReading(nb_vals); - for(int i=0; i&, std::vector&) -{ - if ( isXRD() ) - { - for (int object=0; object!=nbObjects; ++object) // pour chaque Group - { - initIntReading(2); - int len = getIntNext(); - int nb_vals = getIntNext(); - int nb_char = len*nb_vals; - int nb_char_tmp = 0; - int fixed_length = 71; - while (nb_char_tmp < nb_char) - { - int remain_len = nb_char - nb_char_tmp; - int width; - if ( remain_len > fixed_length ) - { - width = fixed_length; - } - else - { - width = remain_len; - } - initNameReading(1, width); - next(); - nb_char_tmp += width; - } - } - } -} - -//================================================================================ -/*! - * \brief Skip "PILE NUMERO 38" of XDR file - */ -//================================================================================ - -void SauvReader::read_PILE_MODL (const int nbObjects, std::vector&, std::vector&) -{ - if ( isXRD() ) - { - for (int object=0; object!=nbObjects; ++object) // pour chaque Group - { - // see wrmodl.eso - initIntReading(10); - int n1 = getIntNext(); - int nm2 = getIntNext(); - int nm3 = getIntNext(); - int nm4 = getIntNext(); - int nm5 = getIntNext(); - int n45 = getIntNext(); - /*int nm6 =*/ getIntNext(); - /*int nm7 =*/ getIntNext(); - next(); - next(); - int nm1 = n1 * n45; - int nm9 = n1 * 16; - for (initIntReading(nm1); more(); next()); - for (initIntReading(nm9); more(); next()); - for (initNameReading(nm5, 8); more(); next()); - for (initNameReading(nm2, 8); more(); next()); - for (initNameReading(nm3, 8); more(); next()); - for (initIntReading(nm4); more(); next()); - } - } -} // Fin case pile 38 - -//================================================================================ -/*! - * \brief Read "PILE NUMERO 32": links to node coordinates - */ -//================================================================================ - -void SauvReader::read_PILE_NOEUDS (const int nbObjects, std::vector&, std::vector&) -{ - initIntReading(1); - int nb_indices = getIntNext(); - - if (nb_indices != nbObjects) - THROW_IK_EXCEPTION("Error of reading PILE NUMERO " << PILE_NOEUDS << lineNb() ); - - for ( initIntReading( nbObjects ); more(); next() ) - { - int coordID = getInt(); - _iMed->getNode( index()+1 )->_coordID = coordID; - } -} - -//================================================================================ -/*! - * \brief Read "PILE NUMERO 33": node coordinates - */ -//================================================================================ - -void SauvReader::read_PILE_COORDONNEES (const int nbObjects, std::vector&, std::vector&) -{ - initIntReading(1); - int nbReals = getIntNext(); - - if ( nbReals < (int)(_iMed->_nbNodes*(_iMed->_spaceDim+1)) ) - THROW_IK_EXCEPTION("Error of reading PILE NUMERO " << PILE_COORDONNEES << lineNb() ); - - // there are coordinates + density for each node - _iMed->_coords.resize( nbReals - nbReals/(_iMed->_spaceDim+1)); - double* coordPtr = &_iMed->_coords[0]; - - initDoubleReading( nbReals ); - while ( more() ) - { - for (unsigned j = 0; j < _iMed->_spaceDim; ++j, next()) - *coordPtr++ = getDouble(); - // skip density - getDouble(); - next(); - } -} - -//================================================================================ -/*! - * \brief Find or create a Group equal to a given field support - */ -//================================================================================ - -void SauvReader::setFieldSupport(const vector& supports, - SauvUtilities::DoubleField* field) -{ - SauvUtilities::Group* group = NULL; - set sup_set( supports.begin(), supports.end() ); - if ( sup_set.size() == 1 ) // one or equal supports - { - group = supports[0]; - } - else - { - // check if sub-components are on cells of different types - map nbGaussByCellType; - for ( size_t i = 0; i < supports.size(); ++i ) - { - map::iterator ct2ng = nbGaussByCellType.find( supports[i]->_cellType ); - if ( ct2ng == nbGaussByCellType.end() ) - nbGaussByCellType[ supports[i]->_cellType ] = field->_sub[i].nbGauss(); - else if ( ct2ng->second != field->_sub[i].nbGauss() ) - return; - } - bool isSameCellType = ( nbGaussByCellType.size() == 1 ); - // try to find an existing composite group with the same sub-groups - if ( isSameCellType ) - for ( size_t i = 0; i < _iMed->_groups.size() && !group; ++i ) - { - Group & grp = _iMed->_groups[i]; - if (sup_set.size() == grp._groups.size()) - { - bool sameOrder = true; - for ( size_t j = 0; j < supports.size() && sameOrder; ++j ) - sameOrder = ( supports[j] == grp._groups[ j % grp._groups.size() ]); - if ( sameOrder ) - group = & _iMed->_groups[i]; - } - } - if ( !group ) // no such a group, add a new one - { - vector newGroups( supports.begin(), - supports.begin() + sup_set.size() ); - // check if supports includes newGroups in the same order - bool sameOrder = true; - for ( size_t j = newGroups.size(); j < supports.size() && sameOrder; ++j ) - sameOrder = ( supports[j] == newGroups[ j % newGroups.size() ]); - if ( sameOrder ) - { - group = _iMed->addNewGroup( & newGroups ); - group->_groups.swap( newGroups ); - } - } - // sort field sub-components and supports by cell type - if ( group && !isSameCellType ) - { - // sort groups - vector& groups = group->_groups; - bool isModified = false, isSwapped = true; - while ( isSwapped ) - { - isSwapped = false; - for ( size_t i = 1; i < groups.size(); ++i ) - { - int nbN1 = groups[i-1]->empty() ? 0 : groups[i-1]->_cells[0]->_nodes.size(); - int nbN2 = groups[i ]->empty() ? 0 : groups[i ]->_cells[0]->_nodes.size(); - if ( nbN1 > nbN2 ) - { - isSwapped = isModified = true; - std::swap( groups[i], groups[i-1] ); - } - } - } - // relocate sub-components according to a new order of groups - if ( isModified ) - { - vector< DoubleField::_Sub_data > newSub ( field->_sub.size() ); - vector< vector< double > > newValues( field->_comp_values.size() ); - size_t iFromSub = 0, iNewSub = 0, iNewComp = 0; - for ( ; iFromSub < field->_sub.size(); iFromSub += groups.size() ) - { - size_t iFromComp = iNewComp; - for ( size_t iG = 0; iG < groups.size(); ++iG ) - { - size_t iComp = iFromComp; - for ( size_t iSub = iFromSub; iSub < field->_sub.size(); ++iSub ) - if ( field->_sub[ iSub ]._support == groups[ iG ] ) - { - newSub[ iNewSub++ ] = field->_sub[ iSub ]; - int iC = 0, nbC = field->_sub[ iSub ].nbComponents(); - for ( ; iC < nbC; ++iC ) - newValues[ iNewComp++ ].swap( field->_comp_values[ iComp++ ]); - break; - } - else - { - iComp += field->_sub[ iSub ].nbComponents(); - } - } - } - field->_sub.swap( newSub ); - field->_comp_values.swap( newValues ); - } - } - } - if ( group ) - group->_isProfile = true; - - field->_group = group; -} - -//================================================================================ -/*! - * \brief Set field names - */ -//================================================================================ - -void SauvReader::setFieldNames(const vector& fields, - const vector& objets_nommes, - const vector& indices_objets_nommes) -{ - unsigned i; - for ( i = 0; i < indices_objets_nommes.size(); ++i ) - { - int fieldIndex = indices_objets_nommes[ i ]; - if ( fields[ fieldIndex - 1 ] ) - fields[ fieldIndex - 1 ]->_name = objets_nommes[ i ]; - } -} - -//================================================================================ -/*! - * \brief Read "PILE NUMERO 2": NODE FIELDS - */ -//================================================================================ - -void SauvReader::read_PILE_NODES_FIELD (const int nbObjects, - std::vector& objectNames, - std::vector& nameIndices) -{ - _iMed->_nodeFields.resize( nbObjects, (SauvUtilities::DoubleField*) 0 ); - for (int object=0; object!=nbObjects; ++object) // loop on fields - { - // EXAMPLE ( with no values ) - - // (1) 4 7 2 1 - // (2) -88 0 3 -89 0 1 -90 0 2 -91 - // (2) 0 1 - // (3) FX FY FZ FZ FX FY FLX - // (4) 0 0 0 0 0 0 0 - // (5) cree par muc pri - // (6) - // (7) 2 - - // (1): nb subcomponents, nb components(total), IFOUR, nb attributes - int nb_sub, total_nb_comp, nb_attr; - int i_sub, i_comp; - initIntReading( 4 ); - nb_sub = getIntNext(); - total_nb_comp = getIntNext(); - next(); // ignore IFOUR - nb_attr = getIntNext(); - if ( nb_sub < 0 || total_nb_comp < 0 || nb_attr < 0 ) - THROW_IK_EXCEPTION("Error of field reading " << lineNb()); - - // (2) loop on subcomponents of a field, for each read - // (a) support, (b) number of values and (c) number of components - vector supports( nb_sub ); - vector nb_values ( nb_sub ); - vector nb_comps ( nb_sub ); - int total_nb_values = 0; - initIntReading( nb_sub * 3 ); - for ( i_sub = 0; i_sub < nb_sub; ++i_sub ) - { - int supId = -getIntNext(); // (a) reference to support - if ( supId < 1 || supId > (int)_iMed->_groups.size() ) - THROW_IK_EXCEPTION("Wrong mesh reference: "<< supId << lineNb() ); - supports[ i_sub ] = &_iMed->_groups[ supId-1 ]; // (a) reference to support - - nb_values[ i_sub ] = getIntNext(); // (b) nb points - total_nb_values += nb_values[ i_sub ]; - if ( nb_values[ i_sub ] < 0 ) - THROW_IK_EXCEPTION(" Wrong nb of points: " << nb_values[ i_sub ] << lineNb() ); - nb_comps[ i_sub ] = getInt(); next(); // (c) nb of components in i_sub - } - - // create a field if there are values - SauvUtilities::DoubleField* fdouble = 0; - if ( total_nb_values > 0 ) - fdouble = new DoubleField( nb_sub, total_nb_comp ); - _iMed->_nodeFields[ object ] = fdouble; - - // (3) component names - initNameReading( total_nb_comp, 4 ); - for ( i_sub = 0; i_sub < nb_sub; ++i_sub ) - { - // store support id and nb components of a sub - if ( fdouble ) - fdouble->_sub[ i_sub ].setData( nb_comps[ i_sub ], supports[ i_sub ] ); - for ( i_comp = 0; i_comp < nb_comps[ i_sub ]; ++i_comp, next() ) - { - // store component name - string compName = getName(); - if ( fdouble ) - fdouble->_sub[ i_sub ].compName( i_comp ) = compName; - } - } - // (4) nb harmonics ( ignored ) - for ( initIntReading( total_nb_comp ); more(); next() ); - // (5) TYPE ( ignored ) - for (initNameReading(1, /*length=*/71); more(); next()); - // (6) TITRE ( ignored ) - for (initNameReading(1, /*length=*/71); more(); next()); - // (7) attributes ( ignored ) - for ( initIntReading( nb_attr ); more(); next() ); - - for ( i_sub = 0; i_sub < nb_sub; ++i_sub ) - { - // loop on components: read values - initDoubleReading( nb_values[ i_sub ] * nb_comps[ i_sub ] ); - for ( i_comp = 0; i_comp < nb_comps[ i_sub ]; ++i_comp ) - { - if ( fdouble ) - { - vector& vals = fdouble->addComponent( nb_values[ i_sub ] ); - for ( int i = 0; more() && i < nb_values[ i_sub ]; next(), ++i ) - vals[ i ] = getDouble(); - } - else - { - for ( int i = 0; i < nb_values[ i_sub ]; next(), ++i ); - } - } - } // loop on subcomponents of a field - - // set a supporting group including all subs supports but only - // if all subs have the same components - if ( fdouble && fdouble->hasSameComponentsBySupport() ) - setFieldSupport( supports, fdouble ); - else - for ( i_sub = 0; i_sub < nb_sub; ++i_sub ) - fdouble->_sub[ i_sub ]._support->_isProfile = true; - - } // end loop on field objects - - // set field names - setFieldNames( _iMed->_nodeFields, objectNames, nameIndices ); - -} // read_PILE_NODES_FIELD() - -//================================================================================ -/*! - * \brief Read "PILE NUMERO 39": FIELDS - */ -//================================================================================ - -void SauvReader::read_PILE_FIELD (const int nbObjects, - std::vector& objectNames, - std::vector& nameIndices) -{ - // REAL EXAMPLE - - // (1) 1 2 6 16 - // (2) CARACTERISTIQUES - // (3) -15 317773 4 0 0 0 -2 0 3 - // (4) 317581 - // (5) 0 - // (6) 317767 317761 317755 317815 - // (7) YOUN NU H SIGY - // (8) REAL*8 REAL*8 REAL*8 REAL*8 - // (9) 1 1 0 0 - // (10) 2.00000000000000E+05 - // (11) 1 1 0 0 - // (12) 3.30000000000000E-01 - // (13) 1 1 0 0 - // (14) 1.00000000000000E+04 - // (15) 6 706 0 0 - // (16) 1.00000000000000E+02 1.00000000000000E+02 1.00000000000000E+02 - // (17) 1.00000000000000E+02 1.00000000000000E+02 1.00000000000000E+02 - // (18) ... - - _iMed->_cellFields.resize( nbObjects, (SauvUtilities::DoubleField*) 0 ); - for (int object=0; object!=nbObjects; ++object) // pour chaque field - { - initIntReading( 4 ); - int i_sub, nb_sub = getIntNext(); // (1) 2 6 - next(); // skip "2" - next(); // skip "6" - int title_length = getIntNext(); // <title length> - if ( nb_sub < 1 ) - THROW_IK_EXCEPTION("Error of field reading: wrong nb of subcomponents " << nb_sub << lineNb() ); - - string description; - if ( title_length ) - { - if ( isXRD() ) - { - initNameReading(1, title_length); - description = getName(); - next(); - } - else - { - char* line; - getNextLine( line ); // (2) title - const int len = 72; // line length - description = string(line + len - title_length, title_length); // title is right justified - } - } - // look for a line starting with '-' : <reference to support> - if ( isXRD() ) - { - initIntReading( nb_sub * 9 ); - } - else - { - do { - initIntReading( nb_sub * 9 ); - } while ( getInt() >= 0 ); - } - int total_nb_comp = 0; - vector<Group*> supports( nb_sub ); - vector<int> nb_comp( nb_sub ); - for ( i_sub = 0; i_sub < nb_sub; ++i_sub ) - { // (3) - int supportId = -getIntNext(); // <reference to support> - next(); // ignore <address> - nb_comp [ i_sub ] = getIntNext(); // <nb of components in the sub> - for ( int i = 0; i < 6; ++i ) next(); // ignore 6 ints, in example "0 0 0 -2 0 3" - - if ( supportId < 1 || supportId > (int)_iMed->_groups.size() ) - THROW_IK_EXCEPTION("Error of field reading: wrong mesh reference "<< supportId << lineNb() ); - if ( nb_comp[ i_sub ] < 0 ) - THROW_IK_EXCEPTION("Error of field reading: wrong nb of components " <<nb_comp[ i_sub ] << lineNb() ); - - supports[ i_sub ] = &_iMed->_groups[ supportId-1 ]; - total_nb_comp += nb_comp[ i_sub ]; - } - // (4) dummy strings - for ( initNameReading( nb_sub, 17 ); more(); next() ); - // (5) dummy strings - for ( initNameReading( nb_sub ); more(); next() ); - - // loop on subcomponents of a field, each of which refers to - // a certain support and has its own number of components; - // read component values - SauvUtilities::DoubleField* fdouble = 0; - for ( i_sub = 0; i_sub < nb_sub; ++ i_sub ) - { - vector<string> comp_names( nb_comp[ i_sub ]), comp_type( nb_comp[ i_sub ]); - // (6) nb_comp addresses of MELVAL structure - for ( initIntReading( nb_comp[ i_sub ] ); more(); next() ); - // (7) component names - for ( initNameReading( nb_comp[ i_sub ] ); more(); next() ) - comp_names[ index() ] = getName(); - // (8) component type - for ( initNameReading( nb_comp[ i_sub ], 17 ); more(); next() ) // 17 is name width - { - comp_type[ index() ] = getName(); - // component types must be the same - if ( index() > 0 && comp_type[ index() ] != comp_type[ index() - 1] ) - THROW_IK_EXCEPTION( "Error of field reading: diff component types <" - << comp_type[ index() ] << "> != <" << comp_type[ index() - 1 ] - << ">" << lineNb() ); - } - // now type is known, create a field, one for all subs - bool isReal = (nb_comp[i_sub] > 0) ? (comp_type[0] == "REAL*8") : true; - if ( !fdouble && total_nb_comp ) - { - if ( !isReal ) - cout << "Warning: read NOT REAL field, type <" << comp_type[0] << ">" << lineNb() << endl; - _iMed->_cellFields[ object ] = fdouble = new SauvUtilities::DoubleField( nb_sub, total_nb_comp ); - fdouble->_description = description; - } - // store support id and nb components of a sub - if ( fdouble ) - fdouble->_sub[ i_sub ].setData( nb_comp[ i_sub ], supports[ i_sub ]); - // loop on components: read values - for ( int i_comp = 0; i_comp < nb_comp[ i_sub ]; ++i_comp ) - { - // (9) nb of values - initIntReading( 4 ); - int nb_val_by_elem = getIntNext(); - int nb_values = getIntNext(); - next(); - next(); - fdouble->_sub[ i_sub ]._nb_gauss[ i_comp ] = nb_val_by_elem; - - // (10) values - nb_values *= nb_val_by_elem; - if ( fdouble ) - { - vector<double> & vals = fdouble->addComponent( nb_values ); - for ( isReal ? initDoubleReading( nb_values ) : initIntReading( nb_values ); more(); next()) - vals[ index() ] = getDouble(); - // store component name - fdouble->_sub[ i_sub ].compName( i_comp ) = comp_names[ i_comp ]; - } - else - { - for ( isReal ? initDoubleReading( nb_values ) : initIntReading( nb_values ); more(); next() ) ; - } - } - } // loop on subcomponents of a field - - // set id of a group including all sub supports but only - // if all subs have the same nb of components - if ( fdouble && fdouble->hasSameComponentsBySupport() ) - setFieldSupport( supports, fdouble ); - else - for ( i_sub = 0; i_sub < nb_sub; ++i_sub ) - fdouble->_sub[ i_sub ]._support->_isProfile = true; - - } // end loop on field objects - - // set field names - setFieldNames( _iMed->_cellFields, objectNames, nameIndices ); - -} // read_PILE_FIELD() - -//================================================================================ -/*! - * \brief Read "PILE NUMERO 10": TABLES - */ -//================================================================================ - -void SauvReader::read_PILE_TABLES (const int nbObjects, - std::vector<std::string>& objectNames, - std::vector<int>& nameIndices) -{ - // IMP 0020434: mapping GIBI names to MED names - - string table_med_mail = "MED_MAIL"; - string table_med_cham = "MED_CHAM"; - string table_med_comp = "MED_COMP"; - int table_med_mail_id = -1; - int table_med_cham_id = -1; - int table_med_comp_id = -1; - for (size_t iname = 0; iname < objectNames.size(); iname++) - if (objectNames[iname] == table_med_mail) table_med_mail_id = nameIndices[iname]; - else if (objectNames[iname] == table_med_cham) table_med_cham_id = nameIndices[iname]; - else if (objectNames[iname] == table_med_comp) table_med_comp_id = nameIndices[iname]; - - if ( isASCII() ) - if (table_med_mail_id < 0 && table_med_cham_id < 0 && table_med_comp_id < 0) - return; - - for (int itable = 1; itable <= nbObjects; itable++) - { - // read tables "MED_MAIL", "MED_CHAM" and "MED_COMP", that keeps correspondence - // between GIBI names (8 symbols if any) and MED names (possibly longer) - initIntReading(1); - int nb_table_vals = getIntNext(); - if (nb_table_vals < 0) - THROW_IK_EXCEPTION("Error of reading PILE NUMERO 10" << lineNb() ); - - int name_i_med_pile; - initIntReading(nb_table_vals); - for (int i = 0; i < nb_table_vals/4; i++) - { - if (itable == table_med_mail_id || - itable == table_med_cham_id || - itable == table_med_comp_id) - { - nameGIBItoMED name_i; - name_i_med_pile = getIntNext(); - name_i.med_id = getIntNext(); - name_i.gibi_pile = getIntNext(); - name_i.gibi_id = getIntNext(); - - if (name_i_med_pile != PILE_STRINGS) - { - // error: med(long) names are always kept in PILE_STRINGS - } - if (itable == table_med_mail_id) - { - if (name_i.gibi_pile != PILE_SOUS_MAILLAGE) { - // error: must be PILE_SOUS_MAILLAGE - } - _iMed->_listGIBItoMED_mail.push_back(name_i); - } - else if (itable == table_med_cham_id) - { - if (name_i.gibi_pile != PILE_FIELD && - name_i.gibi_pile != PILE_NODES_FIELD) - { - // error: must be PILE_FIELD or PILE_NODES_FIELD - } - _iMed->_listGIBItoMED_cham.push_back(name_i); - } - else if (itable == table_med_comp_id) - { - if (name_i.gibi_pile != PILE_STRINGS) - { - // error: gibi(short) names of components are kept in PILE_STRINGS - } - _iMed->_listGIBItoMED_comp.push_back(name_i); - } - } - else - { - // pass table - for ( int ii = 0; ii < 4; ++ii ) next(); - } - } - } // for (int itable = 0; itable < nbObjects; itable++) -} - -//================================================================================ -/*! - * \brief Read "PILE NUMERO 27" - */ -//================================================================================ - -void SauvReader::read_PILE_STRINGS (const int nbObjects, - std::vector<std::string>& objectNames, - std::vector<int>& nameIndices) -{ - // IMP 0020434: mapping GIBI names to MED names - initIntReading(2); - int stringLen = getIntNext(); - int nbSubStrings = getIntNext(); - if (nbSubStrings != nbObjects) - THROW_IK_EXCEPTION("Error of reading PILE NUMERO 27" << lineNb() ); - - string aWholeString; - if ( isXRD() ) - { - const int fixedLength = 71; - while ((int)aWholeString.length() < stringLen) - { - int remainLen = stringLen - aWholeString.length(); - int len; - if ( remainLen > fixedLength ) - { - len = fixedLength; - } - else - { - len = remainLen; - } - initNameReading(1, len); - aWholeString += getName(); - next(); - } - } - else - { - char* line; - const int fixedLength = 71; - while ((int)aWholeString.length() < stringLen) - { - getNextLine( line ); - int remainLen = stringLen - aWholeString.length(); - if ( remainLen > fixedLength ) - { - aWholeString += line + 1; - } - else - { - aWholeString += line + ( 72 - remainLen ); - } - } - } - int prevOffset = 0; - int currOffset = 0; - initIntReading(nbSubStrings); - for (int istr = 1; istr <= nbSubStrings; istr++, next()) - { - currOffset = getInt(); - // fill mapStrings - _iMed->_mapStrings[istr] = aWholeString.substr(prevOffset, currOffset - prevOffset); - prevOffset = currOffset; - } -} diff --git a/src/MEDLoader/SauvReader.hxx b/src/MEDLoader/SauvReader.hxx deleted file mode 100644 index 4be5977b3..000000000 --- a/src/MEDLoader/SauvReader.hxx +++ /dev/null @@ -1,104 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 -// 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 -// -// File : SauvReader.hxx -// Created : Tue Aug 16 13:04:25 2011 -// Author : Edward AGAPOV (eap) -// -#ifndef __SAUVREADER_HXX__ -#define __SAUVREADER_HXX__ - -#include "MEDLoaderDefines.hxx" -#include "InterpKernelException.hxx" -#include "SauvUtilities.hxx" -#include "MEDCouplingRefCountObject.hxx" - -#include <vector> -#include <string> -#include <set> - -namespace SauvUtilities -{ - class FileReader; - struct IntermediateMED; - struct Group; - struct DoubleField; -} -namespace ParaMEDMEM -{ - class MEDFileData; - -class SauvReader : public ParaMEDMEM::RefCountObject -{ - public: - MEDLOADER_EXPORT static SauvReader* New(const std::string& fileName); - MEDLOADER_EXPORT ParaMEDMEM::MEDFileData * loadInMEDFileDS(); - MEDLOADER_EXPORT ~SauvReader(); - - private: - std::size_t getHeapMemorySizeWithoutChildren() const; - std::vector<const BigMemoryObject *> getDirectChildrenWithNull() const; - void readRecord2(); - void readRecord4(); - void readRecord7(); - - int readPileNumber(int& nbNamedObjects, int& nbObjects); - void read_PILE_SOUS_MAILLAGE(const int nbObjects, std::vector<std::string>& objectNames, std::vector<int>& nameIndices); - void read_PILE_NODES_FIELD (const int nbObjects, std::vector<std::string>& objectNames, std::vector<int>& nameIndices); - void read_PILE_TABLES (const int nbObjects, std::vector<std::string>& objectNames, std::vector<int>& nameIndices); - void read_PILE_LREEL (const int nbObjects, std::vector<std::string>& objectNames, std::vector<int>& nameIndices); - void read_PILE_LOGIQUES (const int nbObjects, std::vector<std::string>& objectNames, std::vector<int>& nameIndices); - void read_PILE_FLOATS (const int nbObjects, std::vector<std::string>& objectNames, std::vector<int>& nameIndices); - void read_PILE_INTEGERS (const int nbObjects, std::vector<std::string>& objectNames, std::vector<int>& nameIndices); - void read_PILE_STRINGS (const int nbObjects, std::vector<std::string>& objectNames, std::vector<int>& nameIndices); - void read_PILE_LMOTS (const int nbObjects, std::vector<std::string>& objectNames, std::vector<int>& nameIndices); - void read_PILE_NOEUDS (const int nbObjects, std::vector<std::string>& objectNames, std::vector<int>& nameIndices); - void read_PILE_COORDONNEES (const int nbObjects, std::vector<std::string>& objectNames, std::vector<int>& nameIndices); - void read_PILE_MODL (const int nbObjects, std::vector<std::string>& objectNames, std::vector<int>& nameIndices); - void read_PILE_FIELD (const int nbObjects, std::vector<std::string>& objectNames, std::vector<int>& nameIndices); - - void setFieldSupport(const std::vector<SauvUtilities::Group*>& supports, - SauvUtilities::DoubleField* field); - void setFieldNames(const std::vector<SauvUtilities::DoubleField*>& fields, - const std::vector<std::string>& objectNames, - const std::vector<int>& nameIndices); - - bool isASCII() const { return _fileReader->isASCII(); } - bool isXRD() const { return !isASCII(); } - bool getNextLine (char* & line, bool raiseOEF = true ) { return _fileReader->getNextLine( line, raiseOEF ); } - void initNameReading(int nbValues, int width = 8) { _fileReader->initNameReading( nbValues, width ); } - void initIntReading(int nbValues) { _fileReader->initIntReading( nbValues ); } - void initDoubleReading(int nbValues) { _fileReader->initDoubleReading( nbValues ); } - bool more() const { return _fileReader->more(); } - void next() { _fileReader->next(); } - int index() const { return _fileReader->index(); } - int getInt() const { return _fileReader->getInt(); } - int getIntNext() { int i = getInt(); next(); return i; } - float getFloat() const { return _fileReader->getFloat(); } - double getDouble() const { return _fileReader->getDouble(); } - std::string getName() const { return _fileReader->getName(); } - std::string lineNb() const; - - - std::set<int> _encounteredPiles; - - SauvUtilities::FileReader* _fileReader; - SauvUtilities::IntermediateMED* _iMed; -}; -} -#endif diff --git a/src/MEDLoader/SauvUtilities.hxx b/src/MEDLoader/SauvUtilities.hxx deleted file mode 100644 index 3fa32d79e..000000000 --- a/src/MEDLoader/SauvUtilities.hxx +++ /dev/null @@ -1,120 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 -// 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 -// -// File : SauvUtilities.hxx -// Created : Mon Aug 22 18:27:34 2011 -// Author : Edward AGAPOV (eap) - -#ifndef __SAUVUTILITIES_HXX__ -#define __SAUVUTILITIES_HXX__ - -#include "MEDLoaderDefines.hxx" -#include "MEDCouplingRefCountObject.hxx" -#include "NormalizedUnstructuredMesh.hxx" - -#include <string> -#include <sstream> - -#define THROW_IK_EXCEPTION(text) \ - { \ - std::ostringstream oss; oss << text; \ - throw INTERP_KERNEL::Exception(oss.str().c_str()); \ - } - -namespace SauvUtilities -{ - INTERP_KERNEL::NormalizedCellType MEDLOADER_EXPORT gibi2medGeom( size_t gibiType ); - int med2gibiGeom( INTERP_KERNEL::NormalizedCellType medGeomType ); - const int * getGibi2MedQuadraticInterlace( INTERP_KERNEL::NormalizedCellType type ); - unsigned getDimension( INTERP_KERNEL::NormalizedCellType type ); - - enum Readable_Piles - { - PILE_SOUS_MAILLAGE=1 , - PILE_NODES_FIELD =2 , - PILE_TABLES =10, - PILE_LREEL =18, - PILE_LOGIQUES =24, - PILE_FLOATS =25, - PILE_INTEGERS =26, - PILE_STRINGS =27, - PILE_LMOTS =29, - PILE_NOEUDS =32, - PILE_COORDONNEES =33, - PILE_MODL =38, - PILE_FIELD =39, - PILE_LAST_READABLE=39 - }; - - //================================================================================ - /*! - * \brief Converts anything to string - */ - //================================================================================ - - template<class T> std::string toString(const T& anything) - { - std::ostringstream s; s << anything; return s.str(); - } - - // ============================================================================== - // IMP 0020434: mapping GIBI names to MED names - struct nameGIBItoMED - { - // GIBI value - int gibi_pile; // PILE_SOUS_MAILLAGE or PILE_FIELD/PILE_NODES_FIELD, or PILE_STRINGS(for components) - int gibi_id; - std::string gibi_name; // used only for components - // MED value - // med_pile = 27; // PILE_STRINGS - int med_id; // used only on reading - std::string med_name; // used only on writing - }; - - // ============================================================================== - /*! - * \brief Base class for ASCII and XDR file readers - */ - class FileReader : public ParaMEDMEM::RefCountObject - { - public: - FileReader(const char* fileName); - virtual ~FileReader() {} - virtual bool isASCII() const = 0; - - virtual bool open() = 0; - virtual bool getNextLine (char* & line, bool raiseOEF = true ) = 0; - virtual void initNameReading(int nbValues, int width = 8) = 0; - virtual void initIntReading(int nbValues) = 0; - virtual void initDoubleReading(int nbValues) = 0; - virtual bool more() const = 0; - virtual void next() = 0; - virtual int index() const { return _iRead; } - virtual int getInt() const = 0; - virtual float getFloat() const = 0; - virtual double getDouble() const = 0; - virtual std::string getName() const = 0; - protected: - std::size_t getHeapMemorySizeWithoutChildren() const { return 0; } - std::vector<const BigMemoryObject *> getDirectChildrenWithNull() const { return std::vector<const BigMemoryObject *>(); } - protected: - std::string _fileName, _curLocale; - int _iRead, _nbToRead; - }; -} -#endif diff --git a/src/MEDLoader/SauvWriter.cxx b/src/MEDLoader/SauvWriter.cxx deleted file mode 100644 index 701ab1e95..000000000 --- a/src/MEDLoader/SauvWriter.cxx +++ /dev/null @@ -1,1378 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 -// 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 -// -// File : SauvWriter.cxx -// Created : Wed Aug 24 12:55:55 2011 -// Author : Edward AGAPOV (eap) - -#include "SauvWriter.hxx" - -#include "InterpKernelException.hxx" -#include "MEDFileMesh.hxx" -#include "MEDFileField.hxx" -#include "MEDFileData.hxx" -#include "CellModel.hxx" - -#include <fstream> -#include <sstream> -#include <iostream> -#include <cstdlib> -#include <iomanip> - -using namespace ParaMEDMEM; -using namespace SauvUtilities; -using namespace std; - -#define INFOS_MED(txt) cout << txt << endl; - -namespace -{ - const char* zeroI8 = " 0"; // FORMAT(I8) - - // ============================================================ - // the class writes endl to the file as soon as <limit> fields - // have been written after the last endl - // ============================================================ - - class TFieldCounter - { - fstream& _file; - int _count, _limit; - public: - TFieldCounter(fstream& f, int limit=0): _file(f), _limit(limit) { init(); } - void init(int limit=0) // init, is done by stop() as well - { if (limit) _limit = limit; _count = 0; } - void operator++(int) // next - { if ( ++_count == _limit ) { _file << endl; init(); }} - void stop() // init() and write endl if there was no endl after the last written field - { if ( _count ) _file << endl; init(); } - ~TFieldCounter() { stop(); } - }; - - //================================================================================ - /*! - * \brief Return a name of a field support on all elements - */ - //================================================================================ - - string noProfileName( INTERP_KERNEL::NormalizedCellType type ) - { - return "INTERP_KERNEL::NormalizedCellType_" + SauvUtilities::toString( type ); - } - - //================================================================================ - /*! - * \brief Remove white spaces from the head and tail - */ - //================================================================================ - - string cleanName( const string& theName ) - { - string name = theName; - if ( !name.empty() ) - { - // cut off leading white spaces - string::size_type firstChar = name.find_first_not_of(" \t"); - if (firstChar < name.length()) - { - name = name.substr(firstChar); - } - else - { - name = ""; // only whitespaces there - remove them - } - // cut off trailing white spaces - string::size_type lastChar = name.find_last_not_of(" \t"); - if (lastChar < name.length()) - name = name.substr(0, lastChar + 1); - } - return name; - } - - //================================================================================ - /*! - * \brief Converts MED long names into SAUVE short ones, returnes a healed long name - */ - //================================================================================ - - string addName (map<string,int>& nameMap, - map<string,int>& namePrefixesMap, - const string& theName, - const int index) - { - // Converts names like: - // MED: GIBI: - // TEMPERATURE_FLUIDE -> TEMPE001 - // TEMPERATURE_SOLIDE -> TEMPE002 - // PRESSION -> PRESSION - // NU -> NU - // VOLUM001 -> VOLUM001 - // VOLUMOFOBJECT -> VOLUM003 - // VOLUM002 -> VOLUM002 - string healedName = cleanName(theName); - int ind = index; - - if (!healedName.empty()) - { - string name = healedName; - int len = name.length(); - for (int i = 0; i < len; ++i) - name[i] = toupper(name[i]); - - bool doResave = false; // only for tracing - - // I. Save a short name as it is - if (len <= 8) - { - INFOS_MED("Save <" << theName << "> as <" << name << ">"); - - map<string,int>::iterator it = nameMap.find(name); - if (it != nameMap.end()) - { - // There is already such name in the map. - - // a. Replace in the map the old pair by the current one - int old_ind = nameMap[name]; - nameMap[name] = ind; - // b. Rebuild the old pair (which was in the map, - // it seems to be built automatically by step II) - ind = old_ind; - // continue with step II - doResave = true; // only for tracing - } - else - { - // Save in the map - nameMap.insert(make_pair(name, ind)); - - // Update loc_index for this name (if last free characters represents a number) - // to avoid conflicts with long names, same in first 5 characters - if (len == 8) - { - int new_loc_index = atoi(name.c_str() + 5); - if (new_loc_index > 0) - { - // prefix - string str = name.substr(0,5); - if (namePrefixesMap.find(str) != namePrefixesMap.end()) - { - int old_loc_index = namePrefixesMap[str]; - if (new_loc_index < old_loc_index) new_loc_index = old_loc_index; - } - namePrefixesMap[str] = new_loc_index; - } - } - return healedName; - } - } // if (len <= 8) - - // II. Cut long name and add a numeric suffix - - // first 5 or less characters of the name - if (len > 5) name = name.substr(0,5); - - // numeric suffix - map<string,int>::iterator name2ind = namePrefixesMap.insert( make_pair( name, 0 )).first; - string numSuffix = SauvUtilities::toString( ++(name2ind->second) ); - - if ( numSuffix.size() + name.size() > 8 ) - THROW_IK_EXCEPTION("Can't write not unique name: " << healedName); - - if ( numSuffix.size() < 3 ) - numSuffix.insert( 0, 3 - numSuffix.size(), '0' ); - - name += numSuffix; - nameMap.insert(make_pair(name, ind)); - - if (doResave) - { - INFOS_MED("Resave previous <" << healedName << "> as <" << name << ">"); - } - else - { - INFOS_MED("Save <" << theName << "> as <" << name << ">"); - } - } - return healedName; - } -} - -SauvWriter::SauvWriter():_cpy_grp_if_on_single_family(false) -{ -} - -SauvWriter* SauvWriter::New() -{ - return new SauvWriter; -} - -std::size_t SauvWriter::getHeapMemorySizeWithoutChildren() const -{ - return 0; -} - -std::vector<const BigMemoryObject *> SauvWriter::getDirectChildrenWithNull() const -{ - return std::vector<const BigMemoryObject *>(); -} - -void SauvWriter::setCpyGrpIfOnASingleFamilyStatus(bool status) -{ - _cpy_grp_if_on_single_family=status; -} - -bool SauvWriter::getCpyGrpIfOnASingleFamilyStatus() const -{ - return _cpy_grp_if_on_single_family; -} - -//================================================================================ -/*! - * \brief Fills own DS by MEDFileData - */ -//================================================================================ - -void SauvWriter::setMEDFileDS(const MEDFileData* medData, - unsigned meshIndex) -{ - if ( !medData) THROW_IK_EXCEPTION("NULL MEDFileData"); - - MEDFileMeshes * meshes = medData->getMeshes(); - MEDFileFields * fields = medData->getFields(); - if ( !meshes) THROW_IK_EXCEPTION("No meshes in MEDFileData"); - - _fileMesh = meshes->getMeshAtPos( meshIndex ); - _fileMesh->incrRef(); - - if ( fields ) - for ( int i = 0; i < fields->getNumberOfFields(); ++i ) - { - MEDFileAnyTypeFieldMultiTS * fB = fields->getFieldAtPos(i); - MEDFileFieldMultiTS * f = dynamic_cast<MEDFileFieldMultiTS *>(fB); - if(!f) - continue;// fields on int32 not managed - if ( f->getMeshName() == _fileMesh->getName() ) - { - vector< vector<TypeOfField> > fTypes = f->getTypesOfFieldAvailable(); - if ( fTypes[0].size() == 1 && fTypes[0][0] == ON_NODES ) - _nodeFields.push_back( f ); - else - _cellFields.push_back( f ); - } - } -} - -//================================================================================ -/*! - * \brief Adds a submesh - */ -//================================================================================ - -SauvWriter::SubMesh* SauvWriter::addSubMesh(const std::string& name, int dimRelExt) -{ - if ( _subs.capacity() < _subs.size() + 1 ) - THROW_IK_EXCEPTION("SauvWriter: INTERNAL error, wrong evaluation of nb of sub-meshes"); - _subs.resize( _subs.size() + 1 ); - SubMesh& sm = _subs.back(); - sm._name = name; - sm._dimRelExt = dimRelExt; - return &sm; -} -//================================================================================ -/*! - * \brief Returns nb of cell types - */ -//================================================================================ - -int SauvWriter::SubMesh::nbTypes() const -{ - int nb = 0; - for (int i = 0; i < cellIDsByTypeSize(); ++i ) - nb += int( !_cellIDsByType[i].empty() ); - return nb; -} - -//================================================================================ -/*! - * \brief Fill _subs - */ -//================================================================================ - -void SauvWriter::fillSubMeshes( int& nbSauvObjects, map<string,int>& nameNbMap ) -{ - // evaluate nb of _subs in order to avoid re-allocation of _subs - int nbSubs = 1; // for the very mesh - nbSubs += _fileMesh->getFamilyInfo().size() + 4; // + 4 zero families (for each dimRelExt) - nbSubs += _fileMesh->getGroupInfo().size(); - nbSubs += evaluateNbProfileSubMeshes(); - _subs.clear(); - _subs.reserve( nbSubs ); - - fillFamilySubMeshes(); - fillGroupSubMeshes(); - fillProfileSubMeshes(); - - // fill names of SubMesh'es and count nb of sauv sub-meshes they will be stored into - nbSauvObjects = 0; - map<string,int> namePrefixMap; - for ( size_t i = 0; i < _subs.size(); ++i ) - { - SubMesh& sm = _subs[i]; - - sm._nbSauvObjects = 0; - if ( sm._subs.empty() ) - { - sm._nbSauvObjects = sm.nbTypes(); - } - else - { - sm._nbSauvObjects = 1; - } - - sm._id = nbSauvObjects+1; - nbSauvObjects += sm._nbSauvObjects; - - if ( sm._nbSauvObjects ) - sm._name = addName( nameNbMap, namePrefixMap, sm._name, sm._id ); - - if ( sm._nbSauvObjects && !sm._name.empty() ) - { - nameGIBItoMED aMEDName; - aMEDName.gibi_pile = PILE_SOUS_MAILLAGE; - aMEDName.gibi_id = sm._id; - aMEDName.med_name = sm._name; - _longNames[ LN_MAIL ].push_back(aMEDName); - } - } -} - -//================================================================================ -/*! - * \brief fill sub-meshes of families - */ -//================================================================================ - -void SauvWriter::fillFamilySubMeshes() -{ - SubMesh* nilSm = (SubMesh*) 0; - std::vector<int> dims = _fileMesh->getNonEmptyLevelsExt(); - for ( size_t iDim = 0; iDim < dims.size(); ++iDim ) - { - int dimRelExt = dims[ iDim ]; - MEDCouplingAutoRefCountObjectPtr< MEDCouplingMesh > mesh = _fileMesh->getGenMeshAtLevel(dimRelExt); - const DataArrayInt * famIds = _fileMesh->getFamilyFieldAtLevel(dimRelExt); - if ( !famIds ) continue; - - int curFamID = 0; - SubMesh* curSubMesh = addSubMesh( "", dimRelExt ); // submesh of zero family - _famIDs2Sub[0] = curSubMesh; - int sub0Index = _subs.size()-1; - - const int * famID = famIds->begin(), * famIDEnd = famIds->end(); - for ( int cellID = 0; famID < famIDEnd; ++famID, cellID++ ) - { - if ( *famID != curFamID ) - { - curFamID = *famID; - map< int, SubMesh* >::iterator f2s = _famIDs2Sub.insert( make_pair( curFamID, nilSm )).first; - if ( !f2s->second ) - f2s->second = addSubMesh( "", dimRelExt ); // no names for families - curSubMesh = f2s->second; - } - INTERP_KERNEL::NormalizedCellType cellType = - dimRelExt == 1 ? INTERP_KERNEL::NORM_POINT1 : mesh->getTypeOfCell( cellID ); - curSubMesh->_cellIDsByType[ cellType ].push_back( cellID ); - } - - if ( dimRelExt == 1 ) - { - // clear submesh of nodal zero family - _famIDs2Sub[0]->_cellIDsByType[ INTERP_KERNEL::NORM_POINT1 ].clear(); - } - else if ( dimRelExt == 0 ) - { - // make a submesh including all cells - if ( sub0Index == (int)(_subs.size()-1) ) - { - _famIDs2Sub[0]->_name = _fileMesh->getName(); // there is the zero family only - } - else - { - curSubMesh = addSubMesh( _fileMesh->getName(), dimRelExt ); - if ( _famIDs2Sub[0]->nbTypes() == 0 ) - sub0Index++; // skip an empty zero family - for ( size_t i = sub0Index; i < _subs.size()-1; ++i ) - curSubMesh->_subs.push_back( & _subs[i] ); - } - } - } -} - -//================================================================================ -/*! - * \brief fill sub-meshes of groups - */ -//================================================================================ - -void SauvWriter::fillGroupSubMeshes() -{ - const map<string, vector<string> >& grpFams = _fileMesh->getGroupInfo(); - map<string, vector<string> >::const_iterator g2ff = grpFams.begin(); - for ( ; g2ff != grpFams.end(); ++g2ff ) - { - const string& groupName = g2ff->first; - const vector<string>& famNames = g2ff->second; - if ( famNames.empty() ) continue; - std::vector<SubMesh*> famSubMeshes( famNames.size() ); - std::size_t k = 0; - for ( size_t i = 0; i < famNames.size(); ++i ) - { - int famID = _fileMesh->getFamilyId( famNames[i].c_str() ); - map< int, SubMesh* >::iterator i2f = _famIDs2Sub.find( famID ); - if ( i2f != _famIDs2Sub.end() ) - { - famSubMeshes[ k ] = i2f->second; - ++k; - } - } - // if a family exists but has no element, no submesh has been found for this family - // => we have to resize famSubMeshes with the number of submeshes stored - if (k != famNames.size()) - famSubMeshes.resize(k); - SubMesh* grpSubMesh = addSubMesh( groupName, famSubMeshes[0]->_dimRelExt ); - if(!_cpy_grp_if_on_single_family) - grpSubMesh->_subs.swap( famSubMeshes ); - else - { - /* If a group sub mesh consists of only one family, the group is written as - * a copy of this family. - * A mesh composed of only one submesh may cause an issue with some Gibi operators.*/ - if (famSubMeshes.size() == 1) - { - for(int i = 0; i < famSubMeshes[0]->cellIDsByTypeSize() ; i++) - { - grpSubMesh->_cellIDsByType[i] = famSubMeshes[0]->_cellIDsByType[i]; - } - } - else - grpSubMesh->_subs.swap( famSubMeshes ); - } - } -} - - -//================================================================================ -/*! - * \brief fill sub-meshes of profiles - */ -//================================================================================ - -void SauvWriter::fillProfileSubMeshes() -{ - _profile2Sub.clear(); - SubMesh* nilSm = (SubMesh*) 0; - for ( int isOnNodes = 0; isOnNodes < 2; ++isOnNodes ) - { - vector< MEDCouplingAutoRefCountObjectPtr< MEDFileFieldMultiTS > > - fields = isOnNodes ? _nodeFields : _cellFields; - for ( size_t i = 0; i < fields.size(); ++i ) - { - vector< pair<int,int> > iters = fields[i]->getIterations(); - - vector<INTERP_KERNEL::NormalizedCellType> types; - vector< vector<TypeOfField> > typesF; - vector< vector<string> > pfls, locs; - fields[i]->getFieldSplitedByType( iters[0].first, iters[0].second, - _fileMesh->getName().c_str(), types, typesF, pfls, locs); - int dimRelExt; - for ( size_t iType = 0; iType < types.size(); ++iType ) - { - if ( types[iType] == INTERP_KERNEL::NORM_ERROR ) - dimRelExt = 1; // on nodes - else - dimRelExt = getDimension( types[iType] ) - _fileMesh->getMeshDimension(); - for ( size_t iPfl = 0; iPfl < pfls[iType].size(); ++iPfl ) - { - bool isOnAll = pfls[iType][iPfl].empty(); - if ( isOnAll ) pfls[iType][iPfl] = noProfileName( types[iType] ); - map< string, SubMesh* >::iterator pfl2sm = - _profile2Sub.insert( make_pair( pfls[iType][iPfl], nilSm )).first; - if ( !pfl2sm->second ) - { - SubMesh* sm = pfl2sm->second = addSubMesh( "", dimRelExt ); // no names for profiles - const DataArrayInt * pfl = isOnAll ? 0 : fields[i]->getProfile( pfls[iType][iPfl].c_str() ); - makeProfileIDs( sm, types[iType], pfl ); - } - } - } - } - } -} - -//================================================================================ -/*! - * \brief Return max possible nb of sub-meshes to decsribe field supports - */ -//================================================================================ - -int SauvWriter::evaluateNbProfileSubMeshes() const -{ - int nb = 0; - for ( size_t i = 0; i < _nodeFields.size(); ++i ) - nb += 1 + _nodeFields[i]->getPflsReallyUsed().size(); - - for ( size_t i = 0; i < _cellFields.size(); ++i ) - { - nb += _cellFields[i]->getPflsReallyUsed().size(); - - vector< pair<int,int> > iters = _cellFields[i]->getIterations(); - - vector<INTERP_KERNEL::NormalizedCellType> types; - vector< vector<TypeOfField> > typesF; - vector< vector<string> > pfls, locs; - _cellFields[i]->getFieldSplitedByType( iters[0].first, iters[0].second, - _fileMesh->getName().c_str(), types, typesF, pfls, locs); - nb += 2 * types.size(); // x 2 - a type can be on nodes and on cells at the same time - } - - return nb; -} - -//================================================================================ -/*! - * \brief Transorm a profile into ids of mesh elements - */ -//================================================================================ - -void SauvWriter::makeProfileIDs( SubMesh* sm, - INTERP_KERNEL::NormalizedCellType type, - const DataArrayInt* profile ) -{ - MEDCouplingAutoRefCountObjectPtr< MEDCouplingMesh > - mesh = _fileMesh->getGenMeshAtLevel(sm->_dimRelExt); - const MEDCouplingUMesh* uMesh = dynamic_cast< const MEDCouplingUMesh* > ((const MEDCouplingMesh*) mesh ); - - if ( sm->_dimRelExt == 1 ) type = INTERP_KERNEL::NORM_POINT1; - vector< int >& ids = sm->_cellIDsByType[ type ]; - - if ( sm->_dimRelExt == 1 || !uMesh ) - { - // profile on nodes or mesh is CARTESIAN - if ( profile ) - { - ids.assign( profile->begin(), profile->end() ); - } - else // on all - { - ids.resize( sm->_dimRelExt == 1 ? mesh->getNumberOfNodes() : mesh->getNumberOfCells() ); - for ( size_t i = 0; i < ids.size(); ++i ) - ids[i]=i; - } - } - else - { - // profile on cells - vector<int> code(3); - code[0] = type; - if ( profile ) // on profile - { - code[1] = profile->getNumberOfTuples(); - code[2] = 0; - } - else // on all cells - { - code[1] = mesh->getNumberOfCellsWithType( type ); - code[2] = -1; - } - vector<const DataArrayInt *> idsPerType( 1, profile ); - MEDCouplingAutoRefCountObjectPtr<DataArrayInt> - resIDs = uMesh->checkTypeConsistencyAndContig( code, idsPerType ); - if (( const DataArrayInt *) resIDs ) - { - ids.assign( resIDs->begin(), resIDs->end() ); - } - else // mesh includes only one type - { - int nbE = code[1]; - for ( ids.resize( nbE ); nbE; --nbE ) - ids[ nbE-1 ] = nbE-1; - } - } -} - -//================================================================================ -/*! - * \brief Write its data into the SAUVE file - */ -//================================================================================ - -void SauvWriter::write(const std::string& fileName) -{ - std::fstream fileStream; - fileStream.open( fileName.c_str(), ios::out); - if -#ifdef WIN32 - ( !fileStream || !fileStream.is_open() ) -#else - ( !fileStream || !fileStream.rdbuf()->is_open() ) -#endif - THROW_IK_EXCEPTION("Can't open the file |"<<fileName<<"|"); - _sauvFile = &fileStream; - - _subs.clear(); - _famIDs2Sub.clear(); - _profile2Sub.clear(); - _longNames[ LN_MAIL ].clear(); - _longNames[ LN_CHAM ].clear(); - _longNames[ LN_COMP ].clear(); - - map<string,int> fldNamePrefixMap; - - writeFileHead(); - writeSubMeshes(); - writeNodes(); - writeNodalFields(fldNamePrefixMap); - writeElemFields(fldNamePrefixMap); - writeLongNames(); - writeLastRecord(); - - _sauvFile->close(); -} -//================================================================================ -/*! - * \brief Writes "ENREGISTREMENT DE TYPE" 4 and 7 - */ -//================================================================================ - -void SauvWriter::writeFileHead() -{ - MEDCouplingAutoRefCountObjectPtr< MEDCouplingMesh > mesh = _fileMesh->getGenMeshAtLevel(0); - - *_sauvFile - << " ENREGISTREMENT DE TYPE 4" << endl - << " NIVEAU 16 NIVEAU ERREUR 0 DIMENSION " << mesh->getSpaceDimension() <<endl - << " DENSITE 0.00000E+00" << endl - << " ENREGISTREMENT DE TYPE 7" << endl - << " NOMBRE INFO CASTEM2000 8" <<endl - << " IFOUR -1 NIFOUR 0 IFOMOD -1 IECHO 1 IIMPI 0 IOSPI 0 ISOTYP 1" << endl - << " NSDPGE 0" << endl; -} - -//================================================================================ -/*! - * \brief Writes names of objects - */ -//================================================================================ - -void SauvWriter::writeNames( const map<string,int>& nameNbMap ) -{ - if ( !nameNbMap.empty() ) - { - // write names of objects - // * 8001 FORMAT(8(1X,A8)) - TFieldCounter fcount( *_sauvFile, 8 ); - *_sauvFile << left; - map<string,int>::const_iterator nameNbIt = nameNbMap.begin(); - for ( ; nameNbIt != nameNbMap.end(); nameNbIt++, fcount++ ) - *_sauvFile << " " << setw(8) << nameNbIt->first; - fcount.stop(); - *_sauvFile << right; - - // write IDs of named objects in the pile - // * 8000 FORMAT(10I8) - nameNbIt = nameNbMap.begin(); - for ( fcount.init(10); nameNbIt != nameNbMap.end(); nameNbIt++, fcount++ ) - *_sauvFile << setw(8) << nameNbIt->second; - } -} - -//================================================================================ -/*! - * \brief Writes "PILE NUMERO 1" - */ -//================================================================================ - -void SauvWriter::writeSubMeshes() -{ - int nbSauvObjects; - map<string,int> nameNbMap; - fillSubMeshes( nbSauvObjects, nameNbMap ); - - // * 800 FORMAT (' ENREGISTREMENT DE TYPE', I4) - *_sauvFile << " ENREGISTREMENT DE TYPE 2" << endl; - // * 801 FORMAT(' PILE NUMERO',I4,'NBRE OBJETS NOMMES',I8,'NBRE OBJETS',I8) - *_sauvFile << " PILE NUMERO 1NBRE OBJETS NOMMES" << setw(8) << nameNbMap.size() << - "NBRE OBJETS" << setw(8) << nbSauvObjects <<endl; - - writeNames( nameNbMap ); - - TFieldCounter fcount( *_sauvFile, 10 ); // 10 intergers per line - - for ( size_t iSub = 0; iSub < _subs.size(); ++iSub ) - { - SubMesh& sm = _subs[iSub]; - if ( sm._nbSauvObjects < 1 ) continue; - - // The first record of each sub-mesh writes - // - type of cells; zero means a compound object whose the 2nd record enumerates its components - // - number of components of a compound object - // - number of references; each reference means a "pointer" to this sub-mesh - // - number of nodes per cell - // - number of cells - - if ( !sm._subs.empty() ) - { - writeCompoundSubMesh(iSub); - } - else - { - // write each sub-type as a SAUV sub-mesh - MEDCouplingAutoRefCountObjectPtr< MEDCouplingMesh > - mesh = _fileMesh->getGenMeshAtLevel( sm._dimRelExt ); - MEDCouplingAutoRefCountObjectPtr< MEDCouplingUMesh> - umesh = mesh->buildUnstructured(); - - for ( int iType=0; iType < sm.cellIDsByTypeSize(); ++iType ) - { - const vector<int>& cellIDs = sm._cellIDsByType[iType]; - if ( cellIDs.empty() ) continue; - - INTERP_KERNEL::NormalizedCellType - cellType = INTERP_KERNEL::NormalizedCellType( iType ); - const INTERP_KERNEL::CellModel & - cell = INTERP_KERNEL::CellModel::GetCellModel( cellType ); - int castemType = SauvUtilities::med2gibiGeom( cellType ); - unsigned nbElemNodes = cell.getNumberOfNodes(); - unsigned nbElems = cellIDs.size(); - - *_sauvFile << setw(8) << castemType - << zeroI8 - << zeroI8 - << setw(8) << nbElemNodes - << setw(8) << nbElems << endl; - - // write color of each element - // * 8000 FORMAT(10I8) - for ( size_t i = 0; i < nbElems; ++i, fcount++ ) *_sauvFile << zeroI8; - fcount.stop(); - - // write connectivity - // gibi IDs are in FORTRAN mode while MEDCoupling IDs are in C mode - if ( sm._dimRelExt == 1 ) // nodes - { - for ( size_t i = 0; i < nbElems; ++i, fcount++ ) - *_sauvFile << setw(8) << ( cellIDs[i] + 1 ); - } - else - { - // indices to transform MED connectivity to GIBI one - const int * toMedConn = getGibi2MedQuadraticInterlace( cellType ); - - vector< int > cellConn( nbElemNodes ), transformedConn( nbElemNodes ); - for ( size_t i = 0; i < nbElems; ++i ) - { - cellConn.clear(); - umesh->getNodeIdsOfCell( cellIDs[i], cellConn ); - if ( toMedConn ) - { - for ( unsigned j = 0; j < nbElemNodes; ++j ) - transformedConn[ toMedConn[ j ]] = cellConn[ j ]; - cellConn.swap( transformedConn ); - } - for ( unsigned j = 0; j < nbElemNodes; ++j, fcount++ ) - *_sauvFile << setw(8) << ( cellConn[j] + 1 ); - } - } - fcount.stop(); - - } // loop on cell types - } // not a compound object - } // loop on sub-meshes -} - -//================================================================================ -/*! - * \brief Writes a sum-mesh composed of other sum-meshes - * This submesh corresponds to a med mesh or group composed of families - */ -//================================================================================ - -void SauvWriter::writeCompoundSubMesh(int iSub) -{ - SubMesh& sm = _subs[iSub]; - if ( sm._nbSauvObjects < 1 || sm._subs.empty()) return; - - vector< int > subIDs; - for ( size_t i = 0; i < sm._subs.size(); ++i ) // loop on sub-meshes of families - for ( int j = 0; j < sm._subs[i]->_nbSauvObjects; ++j ) - subIDs.push_back( sm._subs[i]->_id + j ); - - *_sauvFile << zeroI8 - << setw(8) << subIDs.size() - << zeroI8 - << zeroI8 - << zeroI8 << endl; - - TFieldCounter fcount( *_sauvFile, 10 ); // 10 intergers per line - for ( size_t i = 0; i < subIDs.size(); ++i, fcount++ ) - *_sauvFile << setw(8) << subIDs[i]; -} - -//================================================================================ -/*! - * \brief Write piles relating to nodes - */ -//================================================================================ - -void SauvWriter::writeNodes() -{ - MEDCouplingAutoRefCountObjectPtr< MEDCouplingMesh > mesh = _fileMesh->getGenMeshAtLevel( 1 ); - MEDCouplingAutoRefCountObjectPtr< MEDCouplingUMesh > umesh = mesh->buildUnstructured(); - - // write the index connecting nodes with their coodrinates - - const int nbNodes = umesh->getNumberOfNodes(); - *_sauvFile << " ENREGISTREMENT DE TYPE 2" << endl - << " PILE NUMERO 32NBRE OBJETS NOMMES 0NBRE OBJETS" << setw(8) << nbNodes << endl; - *_sauvFile << setw(8) << nbNodes << endl; - // - TFieldCounter fcount( *_sauvFile, 10 );// * 8000 FORMAT(10I8) - for ( int i = 0; i < nbNodes; ++i, fcount++ ) - *_sauvFile << setw(8) << i + 1; - fcount.stop(); - - // write coordinates and density of nodes - - *_sauvFile << " ENREGISTREMENT DE TYPE 2" << endl; - *_sauvFile << " PILE NUMERO 33NBRE OBJETS NOMMES 0NBRE OBJETS 1" << endl; - // - const int dim = umesh->getSpaceDimension(); - const int nbValues = nbNodes * ( dim + 1 ); - *_sauvFile << setw(8) << nbValues << endl; - - // * 8003 FORMAT(1P,3E22.14) - const char* density = " 0.00000000000000E+00"; - fcount.init(3); - _sauvFile->precision(14); - _sauvFile->setf( ios_base::scientific, ios_base::floatfield ); - _sauvFile->setf( ios_base::uppercase ); - MEDCouplingAutoRefCountObjectPtr< DataArrayDouble> coordArray = umesh->getCoordinatesAndOwner(); - const double precision = 1.e-99; // PAL12077 - for ( int i = 0; i < nbNodes; ++i) - { - for ( int j = 0; j < dim; ++j, fcount++ ) - { - double coo = coordArray->getIJ( i, j ); - bool zero = ( -precision < coo && coo < precision ); - *_sauvFile << setw(22) << ( zero ? 0.0 : coo ); - } - *_sauvFile << density; - fcount++; - } -} - -//================================================================================ -/*! - * \brief Store correspondence between GIBI (short) and MED (long) names - * - * IMP 0020434: mapping GIBI names to MED names - * Store correspondence between GIBI and MED names as one PILE_STRINGS and one - * PILE_TABLES (in three tables: MED_MAIL, MED_CHAM and MED_COMP) - */ -//================================================================================ - -void SauvWriter::writeLongNames() -{ - int nbTables = - 3 - _longNames[ LN_MAIL ].empty() - _longNames[ LN_CHAM ].empty() - _longNames[ LN_COMP ].empty(); - if (nbTables == 0) return; - - // --------------------- - // Write the TABLE pile - // --------------------- - - *_sauvFile << " ENREGISTREMENT DE TYPE 2" << endl - << " PILE NUMERO 10NBRE OBJETS NOMMES" << setw(8) << nbTables - << "NBRE OBJETS" << setw(8) << nbTables << endl; - // table names - if (!_longNames[ LN_MAIL ].empty()) *_sauvFile << " MED_MAIL"; - if (!_longNames[ LN_CHAM ].empty()) *_sauvFile << " MED_CHAM"; - if (!_longNames[ LN_COMP ].empty()) *_sauvFile << " MED_COMP"; - *_sauvFile << endl; - // table indices - for ( int i = 0; i < nbTables; ++i ) *_sauvFile << setw(8) << i+1; - *_sauvFile << endl; - - string theWholeString; // concatenated long names - vector<int> theOffsets; - int iStr = 1; - TFieldCounter fcount (*_sauvFile, 10); - - for ( int iTbl = 0; iTbl < LN_NB; ++iTbl ) - { - vector<nameGIBItoMED>& longNames = _longNames[ iTbl ]; - if ( longNames.empty() ) continue; - const bool isComp = ( iTbl == LN_COMP); - - // to assure unique MED names - set<string> medUniqueNames; - - *_sauvFile << setw(8) << longNames.size()*4 << endl; // Nb of table values - - vector<nameGIBItoMED>::iterator itGIBItoMED = longNames.begin(); - for (; itGIBItoMED != longNames.end(); itGIBItoMED++, iStr++) - { - // PILE of i-th key (med name) - *_sauvFile << setw(8) << PILE_STRINGS; - fcount++; - // ID of i-th key (med name) - *_sauvFile << setw(8) << iStr; - fcount++; - // PILE of i-th value (gibi name) - *_sauvFile << setw(8) << itGIBItoMED->gibi_pile; - fcount++; - // ID of i-th value (gibi name) - *_sauvFile << setw(8) << ( isComp ? ++iStr : itGIBItoMED->gibi_id ); - fcount++; - - // add a MED name to the string (while making it be unique for sub-meshes and fields) - string aMedName = itGIBItoMED->med_name; - if ( !isComp ) - for (int ind = 1; !medUniqueNames.insert(aMedName).second; ++ind ) - aMedName = itGIBItoMED->med_name + "_" + SauvUtilities::toString( ind ); - theWholeString += aMedName; - - // add an offset - theOffsets.push_back( theWholeString.size() ); - if ( isComp ) - { - theWholeString += itGIBItoMED->gibi_name; - theOffsets.push_back( theWholeString.size() ); - } - } - fcount.stop(); - } - - // ---------------------- - // Write the STRING pile - // ---------------------- - - const int nbNames = theOffsets.size(); - *_sauvFile << " ENREGISTREMENT DE TYPE 2" << endl - << " PILE NUMERO 27NBRE OBJETS NOMMES" << zeroI8 << "NBRE OBJETS" << setw(8) << nbNames << endl - << setw(8) << theWholeString.length() << setw(8) << nbNames << endl; - - // write the whole string - const int fixedLength = 71; - for ( string::size_type aPos = 0; aPos < theWholeString.length(); aPos += fixedLength) - *_sauvFile << setw(72) << theWholeString.substr(aPos, fixedLength) << endl; - - // write the offsets - for ( size_t i = 0; i < theOffsets.size(); ++i, fcount++ ) - *_sauvFile << setw(8) << theOffsets[i]; -} - -//================================================================================ -/*! - * \brief Write beginning of field record - */ -//================================================================================ - -void SauvWriter::writeFieldNames( const bool isNodal, - std::map<std::string,int>& fldNamePrefixMap) -{ - vector< MEDCouplingAutoRefCountObjectPtr< MEDFileFieldMultiTS > >& - flds = isNodal ? _nodeFields : _cellFields; - map<string,int> nameNbMap; - - for ( size_t iF = 0; iF < flds.size(); ++iF ) - { - string name = addName( nameNbMap, fldNamePrefixMap, flds[iF]->getName(), iF+1 ); - nameGIBItoMED aMEDName; - aMEDName.gibi_pile = isNodal ? PILE_NODES_FIELD : PILE_FIELD; - aMEDName.gibi_id = iF+1; - aMEDName.med_name = name; - _longNames[ LN_CHAM ].push_back(aMEDName); - } - - *_sauvFile << " ENREGISTREMENT DE TYPE 2" << endl - << ( isNodal ? " PILE NUMERO 2" : " PILE NUMERO 39") - << "NBRE OBJETS NOMMES" << setw(8) << nameNbMap.size() - << "NBRE OBJETS" << setw(8) << flds.size() << endl; - writeNames( nameNbMap ); -} - -//================================================================================ -/*! - * \brief Make short names of field components - * - * IMP 0020434: mapping GIBI names to MED names - */ -//================================================================================ - -void SauvWriter::makeCompNames(const string& fieldName, - const vector<string>& compInfo, - map<string, string>& mapMedToGibi) -{ - for ( size_t i = 0; i < compInfo.size(); ++i ) - mapMedToGibi[compInfo[i]] = cleanName( compInfo[i] ); - - int compIndex = 1; - map<string, string>::iterator namesIt = mapMedToGibi.begin(); - for (; namesIt != mapMedToGibi.end(); namesIt++) - { - string & compGibiName = (*namesIt).second; - if (compGibiName.size() > 4) { - // use new name in form "CXXX", where "XXX" is a number - do - { - compGibiName = SauvUtilities::toString( compIndex++ ); - if ( compGibiName.size() < 3 ) - compGibiName.insert( 0, 3 - compGibiName.size(), '0' ); - compGibiName = "C" + compGibiName; - } - while (mapMedToGibi.count(compGibiName) > 0); // real component name could be CXXX - } - - string compMedName = fieldName + "." + namesIt->first; - nameGIBItoMED aMEDName; - aMEDName.med_name = compMedName; - aMEDName.gibi_pile = PILE_STRINGS; - aMEDName.gibi_name = compGibiName; - _longNames[ LN_COMP ].push_back(aMEDName); - } -} - -//================================================================================ -/*! - * \brief Writes "PILE NUMERO 2": fields on nodes - */ -//================================================================================ - -void SauvWriter::writeNodalFields(map<string,int>& fldNamePrefixMap) -{ - writeFieldNames( /*isNodal=*/true, fldNamePrefixMap ); - - TFieldCounter fcount (*_sauvFile, 10); - - // EXAMPLE ( with no values ) - - // (1) 4 7 2 1 - // (2) -88 0 3 -89 0 1 -90 0 2 -91 - // (2) 0 1 - // (3) FX FY FZ FZ FX FY FLX - // (4) 0 0 0 0 0 0 0 - // (5) cree par muc pri - // (6) - // (7) 2 - for ( size_t iF = 0; iF < _nodeFields.size(); ++iF ) - { - // (1) write nb subcomponents, nb components(total) - vector< pair<int,int> > iters = _nodeFields[iF]->getIterations(); - const vector<string>& compInfo = _nodeFields[iF]->getInfo(); - const int nbSub = iters.size(); - const int nbComp = compInfo.size(); - const int totalNbComp = nbSub * nbComp; - *_sauvFile << setw(8) << nbSub - << setw(8) << totalNbComp - << setw(8) << -1 // IFOUR - << setw(8) << 0 << endl; // nb attributes - - // (2) for each sub-component (iteration) - // write support, number of values and number of components - fcount.init(10); - vector< int > vals(3); - for ( std::size_t iIt = 0; iIt < iters.size(); ++iIt ) - { - pair<int,int> it = iters[iIt]; - - vector<INTERP_KERNEL::NormalizedCellType> types; - vector< vector<TypeOfField> > typesF; - vector< vector<string> > pfls, locs; - vector< vector< std::pair<int,int> > > valsVec; - valsVec=_nodeFields[iF]->getFieldSplitedByType( it.first, it.second, _fileMesh->getName().c_str(), - types, typesF, pfls, locs); - // believe that there can be only one type in a nodal field, - // so do not use a loop on types - if ( pfls[0][0].empty() ) pfls[0][0] = noProfileName( types[0] ); - map< string, SubMesh* >::iterator pfl2Sub = _profile2Sub.find( pfls[0][0] ); - if ( pfl2Sub == _profile2Sub.end() ) - THROW_IK_EXCEPTION( "SauvWriter::writeNodalFields(): no sub-mesh for profile |" - << pfls[0][0] << "|"); - vals[0] = -pfl2Sub->second->_id; - vals[1] = (valsVec[0][0].second-valsVec[0][0].first); - vals[2] = compInfo.size(); - for ( size_t i = 0; i < vals.size(); ++i, fcount++ ) - *_sauvFile << setw(8) << vals[i]; - } - fcount.stop(); - - // (3) Write names of components - map<string, string> mapMedToGibi; - makeCompNames( _nodeFields[iF]->getName(), compInfo, mapMedToGibi ); - fcount.init(8); - *_sauvFile << left; - for ( std::size_t iIt = 0; iIt < iters.size(); ++iIt ) - for ( size_t i = 0; i < compInfo.size(); ++i, fcount++ ) - *_sauvFile << " " << setw(4) << mapMedToGibi[compInfo[i]]; - *_sauvFile << right; - fcount.stop(); - - // (4) nb harmonics - fcount.init(10); - for ( size_t i = 0; i < (std::size_t)totalNbComp; ++i, fcount++ ) - *_sauvFile << " " << setw(8) << 0; - fcount.stop(); - - string description = _nodeFields[iF]->getName(); - *_sauvFile << endl; // (5) TYPE - *_sauvFile << setw(72) << description.substr(0,71) << endl; // (6) TITRE - //*_sauvFile << endl; // (7) 0 attributes - - // write values of each component - fcount.init( 3 ); // 3 values per a line - for ( std::size_t iIt = 0; iIt < iters.size(); ++iIt ) - { - pair<int,int> it = iters[iIt]; - - vector<INTERP_KERNEL::NormalizedCellType> types; - vector< vector<TypeOfField> > typesF; - vector< vector<string> > pfls, locs; - vector< vector< std::pair<int,int> > > valsVec; - valsVec = _nodeFields[iF]->getFieldSplitedByType( it.first, it.second, _fileMesh->getName().c_str(), - types, typesF, pfls, locs); - // believe that there can be only one type in a nodal field, - // so do not perform a loop on types - const DataArrayDouble* valsArray = _nodeFields[iF]->getUndergroundDataArray(it.first, it.second); - for ( size_t j = 0; j < compInfo.size(); ++j ) - { - for ( size_t i = valsVec[0][0].first; i < (std::size_t)valsVec[0][0].second; ++i, fcount++ ) - *_sauvFile << setw(22) << valsArray->getIJ( i, j ); - fcount.stop(); - } - } - } // loop on fiels -} - -//================================================================================ -/*! - * \brief Writes "PILE NUMERO 39": fields on cells - */ -//================================================================================ - -void SauvWriter::writeElemFields(map<string,int>& fldNamePrefixMap) -{ - writeFieldNames( /*isNodal=*/false, fldNamePrefixMap ); - - TFieldCounter fcount (*_sauvFile, 10); - - // REAL EXAMPLE - - // (1) 1 2 6 16 - // (2) CARACTERISTIQUES - // (3) -15 317773 4 0 0 0 -2 0 3 - // (4) 317581 - // (5) 0 - // (6) 317767 317761 317755 317815 - // (7) YOUN NU H SIGY - // (8) REAL*8 REAL*8 REAL*8 REAL*8 - // (9) 1 1 0 0 - // (10) 2.00000000000000E+05 - // (9) 1 1 0 0 - // (10) 3.30000000000000E-01 - // (9) 1 1 0 0 - // (10) 1.00000000000000E+04 - // (9) 6 706 0 0 - // (10) 1.00000000000000E+02 1.00000000000000E+02 1.00000000000000E+02 - // (10) 1.00000000000000E+02 1.00000000000000E+02 1.00000000000000E+02 - // (10) ... - - for ( size_t iF = 0; iF < _cellFields.size(); ++iF ) - { - // count nb of sub-components - int iSub, nbSub = 0; - vector< pair<int,int> > iters = _cellFields[iF]->getIterations(); - for ( std::size_t iIt = 0; iIt < iters.size(); ++iIt ) - { - pair<int,int> it = iters[iIt]; - - vector<INTERP_KERNEL::NormalizedCellType> types; - vector< vector<TypeOfField> > typesF; - vector< vector<string> > pfls, locs; - vector< vector< std::pair<int,int> > > valsVec; - valsVec = _cellFields[iF]->getFieldSplitedByType( it.first, it.second, _fileMesh->getName().c_str(), - types, typesF, pfls, locs); - for ( size_t i = 0; i < valsVec.size(); ++i ) - nbSub += valsVec[i].size(); - } - // (1) write nb sub-components, title length - *_sauvFile << setw(8) << nbSub - << setw(8) << -1 // whatever - << setw(8) << 6 // whatever - << setw(8) << 72 << endl; // title length - // (2) title - string title = _cellFields[iF]->getName(); - *_sauvFile << setw(72) << title.substr(0,71) << endl; - *_sauvFile << setw(72) << " " << endl; - - // (3) support, nb components - vector<int> vals(9, 0); - const vector<string>& compInfo = _cellFields[iF]->getInfo(); - vals[2] = compInfo.size(); - fcount.init(10); - for ( std::size_t iIt = 0; iIt < iters.size(); ++iIt ) - { - pair<int,int> it = iters[iIt]; - - vector<INTERP_KERNEL::NormalizedCellType> types; - vector< vector<TypeOfField> > typesF; - vector< vector<string> > pfls, locs; - _cellFields[iF]->getFieldSplitedByType( it.first, it.second, _fileMesh->getName().c_str(), - types, typesF, pfls, locs); - for ( size_t iType = 0; iType < pfls.size(); ++iType ) - for ( size_t iP = 0; iP < pfls[iType].size(); ++iP ) - { - if ( pfls[iType][iP].empty() ) pfls[iType][iP] = noProfileName( types[iType] ); - map< string, SubMesh* >::iterator pfl2Sub = _profile2Sub.find( pfls[iType][iP] ); - if ( pfl2Sub == _profile2Sub.end() ) - THROW_IK_EXCEPTION( "SauvWriter::writeElemFields(): no sub-mesh for profile |" - << pfls[iType][iP] << "|"); - const int supportID = pfl2Sub->second->_id; - vals[0] = -supportID; - - for ( size_t i = 0; i < vals.size(); ++i, fcount++ ) - *_sauvFile << setw(8) << vals[ i ]; - } - } - fcount.stop(); - - // (4) dummy strings - for ( fcount.init(4), iSub = 0; iSub < nbSub; ++iSub, fcount++ ) - *_sauvFile << " "; - fcount.stop(); - - // (5) dummy strings - for ( fcount.init(8), iSub = 0; iSub < nbSub; ++iSub, fcount++ ) - *_sauvFile << " "; - fcount.stop(); - - // loop on sub-components of a field, each of which refers to - // a certain support and has its own number of components - for ( std::size_t iIt = 0; iIt < iters.size(); ++iIt ) - { - pair<int,int> it = iters[iIt]; - writeElemTimeStamp( iF, it.first, it.second ); - } - } // loop on cell fields -} - -//================================================================================ -/*! - * \brief Write one elemental time stamp - */ -//================================================================================ - -void SauvWriter::writeElemTimeStamp(int iF, int iter, int order) -{ - // (6) 317767 317761 317755 317815 - // (7) YOUN NU H SIGY - // (8) REAL*8 REAL*8 REAL*8 REAL*8 - // (9) 1 1 0 0 - // (10) 2.00000000000000E+05 - // (9) 1 1 0 0 - // (10) 3.30000000000000E-01 - // (9) 1 1 0 0 - // (10) 1.00000000000000E+04 - // (9) 6 706 0 0 - // (10) 1.00000000000000E+02 1.00000000000000E+02 1.00000000000000E+02 - // (10) 1.00000000000000E+02 1.00000000000000E+02 1.00000000000000E+02 - - TFieldCounter fcount (*_sauvFile, 10); - - vector<INTERP_KERNEL::NormalizedCellType> types; - vector< vector<TypeOfField> > typesF; - vector< vector<string> > pfls, locs; - vector< vector< std::pair<int,int> > > valsVec; - valsVec = _cellFields[iF]->getFieldSplitedByType( iter, order, _fileMesh->getName().c_str(), - types, typesF, pfls, locs); - for ( size_t iType = 0; iType < pfls.size(); ++iType ) - for ( size_t iP = 0; iP < pfls[iType].size(); ++iP ) - { - const vector<string>& compInfo = _cellFields[iF]->getInfo(); - - // (6) component addresses - int iComp = 0, nbComp = compInfo.size(); - for ( fcount.init(10); iComp < nbComp; ++iComp, fcount++ ) - *_sauvFile << setw(8) << 777; // a good number - fcount.stop(); - - // (7) component names - map<string, string> mapMedToGibi; - makeCompNames( _cellFields[iF]->getName(), compInfo, mapMedToGibi ); - *_sauvFile << left; - for ( fcount.init(8), iComp = 0; iComp < nbComp; ++iComp, fcount++ ) - *_sauvFile << " " << setw(8) << mapMedToGibi[compInfo[iComp]]; - fcount.stop(); - - // (8) component types - for ( fcount.init(4), iComp = 0; iComp < nbComp; ++iComp, fcount++ ) - *_sauvFile << " " << setw(17) << "REAL*8"; - fcount.stop(); - *_sauvFile << right; - - // (9) nb values per element, nb of elements - int nbPntPerCell = 1; - if ( !locs[iType][iP].empty() ) - { - int locID = _cellFields[iF]->getLocalizationId( locs[iType][iP].c_str() ); - nbPntPerCell = _cellFields[iF]->getNbOfGaussPtPerCell( locID ); - } - else if ( typesF[iType][iP] == ON_GAUSS_NE ) - { - nbPntPerCell = INTERP_KERNEL::CellModel::GetCellModel(types[iType]).getNumberOfNodes(); - } - - // (10) values - const std::pair<int,int>& bgEnd = valsVec[iType][iP]; - const DataArrayDouble* valArray = _cellFields[iF]->getUndergroundDataArray(iter, order); - for ( iComp = 0; iComp < nbComp; ++iComp ) - { - *_sauvFile << setw(8) << nbPntPerCell - << setw(8) << (bgEnd.second-bgEnd.first) / nbPntPerCell - << setw(8) << 0 - << setw(8) << 0 - << endl; - fcount.init(3); - for ( size_t i = bgEnd.first; i < (size_t) bgEnd.second; ++i, fcount++ ) - *_sauvFile << setw(22) << valArray->getIJ( i, iComp ); - fcount.stop(); - } - } -} - -//================================================================================ -/*! - * \brief Write the last record of the SAUV file - */ -//================================================================================ - -void SauvWriter::writeLastRecord() -{ - *_sauvFile << " ENREGISTREMENT DE TYPE 5" << endl; - *_sauvFile << "LABEL AUTOMATIQUE : 1" << endl; -} diff --git a/src/MEDLoader/SauvWriter.hxx b/src/MEDLoader/SauvWriter.hxx deleted file mode 100644 index 7887296e3..000000000 --- a/src/MEDLoader/SauvWriter.hxx +++ /dev/null @@ -1,118 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 -// 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 -// -// File : SauvWriter.hxx -// Created : Wed Aug 24 11:18:49 2011 -// Author : Edward AGAPOV (eap) - -#ifndef __SAUVWRITER_HXX__ -#define __SAUVWRITER_HXX__ - -#include "MEDLoaderDefines.hxx" -#include "MEDCouplingRefCountObject.hxx" -#include "NormalizedUnstructuredMesh.hxx" -#include "SauvUtilities.hxx" -#include "MEDCouplingAutoRefCountObjectPtr.hxx" - -#include <vector> -#include <string> -#include <map> - -namespace ParaMEDMEM -{ - class MEDFileData; - class MEDFileMesh; - class MEDFileFieldMultiTS; - class DataArrayInt; - - /*! - * \brief Class to write a MEDFileData into a SAUVE format file - */ - class SauvWriter : public ParaMEDMEM::RefCountObject - { - public: - MEDLOADER_EXPORT static SauvWriter *New(); - MEDLOADER_EXPORT void setMEDFileDS(const MEDFileData* medData, unsigned meshIndex = 0); - MEDLOADER_EXPORT void write(const std::string& fileName); - MEDLOADER_EXPORT void setCpyGrpIfOnASingleFamilyStatus(bool status); - MEDLOADER_EXPORT bool getCpyGrpIfOnASingleFamilyStatus() const; - private: - SauvWriter(); - std::size_t getHeapMemorySizeWithoutChildren() const; - std::vector<const BigMemoryObject *> getDirectChildrenWithNull() const; - /*! - * \brief Class representing a GIBI sub-mesh (described in the pile 1 of the SAUVE file). - * It stands for a named med sub-mesh (family, etc) and contains either cell IDs or other sub-meshes. - */ - struct SubMesh - { - std::vector<int> _cellIDsByType[ INTERP_KERNEL::NORM_MAXTYPE+1 ]; - std::vector<SubMesh*> _subs; - std::string _name; - int _id; - int _nbSauvObjects; - int _dimRelExt; - int nbTypes() const; - static int cellIDsByTypeSize() { return INTERP_KERNEL::NORM_MAXTYPE+1; } - }; - SubMesh* addSubMesh(const std::string& name, int dimRelExt); - - void fillSubMeshes(int& nbSauvObjects, std::map<std::string,int>& nameNbMap); - void fillFamilySubMeshes(); - void fillGroupSubMeshes(); - void fillProfileSubMeshes(); - int evaluateNbProfileSubMeshes() const; - void makeCompNames(const std::string& fieldName, - const std::vector<std::string>& compInfo, - std::map<std::string, std::string>& compMedToGibi ); - void makeProfileIDs( SubMesh* sm, - INTERP_KERNEL::NormalizedCellType type, - const DataArrayInt* profile ); - void writeFileHead(); - void writeSubMeshes(); - void writeCompoundSubMesh(int iSub); - void writeNodes(); - void writeLongNames(); - void writeNodalFields(std::map<std::string,int>& fldNamePrefixMap); - void writeElemFields(std::map<std::string,int>& fldNamePrefixMap); - void writeFieldNames(const bool isNodal, std::map<std::string,int>& fldNamePrefixMap); - void writeElemTimeStamp(int iF, int iter, int order); - void writeLastRecord(); - void writeNames( const std::map<std::string,int>& nameNbMap ); - - private: - - MEDCouplingAutoRefCountObjectPtr< MEDFileMesh > _fileMesh; - std::vector< MEDCouplingAutoRefCountObjectPtr< MEDFileFieldMultiTS > > _nodeFields; - std::vector< MEDCouplingAutoRefCountObjectPtr< MEDFileFieldMultiTS > > _cellFields; - - std::vector<SubMesh> _subs; - std::map< int, SubMesh* > _famIDs2Sub; - std::map< std::string, SubMesh* > _profile2Sub; - enum - { - LN_MAIL=0, LN_CHAM, LN_COMP, LN_NB - }; - std::vector<SauvUtilities::nameGIBItoMED> _longNames[ LN_NB ]; - - std::fstream* _sauvFile; - bool _cpy_grp_if_on_single_family; - }; -} - -#endif diff --git a/src/MEDLoader/Swig/CMakeLists.txt b/src/MEDLoader/Swig/CMakeLists.txt deleted file mode 100644 index 6cef3ea9a..000000000 --- a/src/MEDLoader/Swig/CMakeLists.txt +++ /dev/null @@ -1,110 +0,0 @@ -# Copyright (C) 2012-2015 CEA/DEN, EDF 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, 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 -# 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) - -FIND_PACKAGE(SWIG REQUIRED) -INCLUDE(${SWIG_USE_FILE}) - -ADD_DEFINITIONS(${PYTHON_DEFINITIONS}) - -SET_SOURCE_FILES_PROPERTIES(MEDLoader.i PROPERTIES CPLUSPLUS ON) -SET_SOURCE_FILES_PROPERTIES(MEDLoader.i PROPERTIES SWIG_DEFINITIONS "-shadow") -SET(SWIG_MODULE_MEDLoader_EXTRA_FLAGS ${SWIG_EXTRA_FLAGS_FOR_NUMPYANDSCIPY}) - -SET (MEDLoader_SWIG_DPYS_FILES - MEDLoaderCommon.i - MEDLoaderTypemaps.i) - -INCLUDE_DIRECTORIES( - ${PYTHON_INCLUDE_DIRS} - ${MEDFILE_INCLUDE_DIRS} - ${HDF5_INCLUDE_DIRS} - ${CMAKE_CURRENT_SOURCE_DIR} - ${CMAKE_CURRENT_SOURCE_DIR}/.. - ${CMAKE_CURRENT_SOURCE_DIR}/../../MEDCoupling_Swig - ${CMAKE_CURRENT_SOURCE_DIR}/../../MEDCoupling - ${CMAKE_CURRENT_SOURCE_DIR}/../../INTERP_KERNEL - ${CMAKE_CURRENT_SOURCE_DIR}/../../INTERP_KERNEL/Bases - ${CMAKE_CURRENT_SOURCE_DIR}/../../INTERP_KERNEL/Geometric2D - ${CMAKE_CURRENT_SOURCE_DIR}/../../INTERP_KERNEL/ExprEval - ${CMAKE_CURRENT_SOURCE_DIR}/../../INTERP_KERNEL/GaussPoints - ${PROJECT_BINARY_DIR}/doc -) - -SET (SWIG_MODULE_MEDLoader_EXTRA_DEPS ${MEDLoader_SWIG_DPYS_FILES} - ${medloader_HEADERS_HXX} - ${medcoupling_HEADERS_HXX} ${medcoupling_HEADERS_TXX} - ${interpkernel_HEADERS_HXX} ${interpkernel_HEADERS_TXX}) - -# SWIG must run after the doc if we want to have the docstrings extracted from Doxygen -# into the Python module: -IF(SALOME_BUILD_DOC) - LIST(APPEND SWIG_MODULE_MEDLoader_EXTRA_FLAGS -DWITH_DOCSTRINGS) - LIST(APPEND SWIG_MODULE_MEDLoader_EXTRA_DEPS - ${PROJECT_BINARY_DIR}/doc/MEDLoader_doc.i - swig_ready) -ENDIF() - -SWIG_ADD_MODULE(MEDLoader python MEDLoader.i) -SWIG_LINK_LIBRARIES(MEDLoader ${PYTHON_LIBRARIES} ${PLATFORM_LIBS} medloader medcoupling) -IF(WIN32) - SET_TARGET_PROPERTIES(_MEDLoader PROPERTIES DEBUG_OUTPUT_NAME _MEDLoader_d) -ENDIF(WIN32) - -INSTALL(TARGETS _MEDLoader DESTINATION ${SALOME_INSTALL_PYTHON}) -INSTALL(FILES MEDLoader.i MEDLoaderTypemaps.i MEDLoaderCommon.i DESTINATION ${SALOME_INSTALL_HEADERS}) - -SET(PYFILES_TO_INSTALL ${CMAKE_CURRENT_BINARY_DIR}/MEDLoader.py) -SALOME_INSTALL_SCRIPTS("${PYFILES_TO_INSTALL}" ${SALOME_INSTALL_PYTHON}) - -INSTALL(FILES MEDLoaderDataForTest.py MEDLoaderTest.py MEDLoaderTest2.py MEDLoaderTest3.py MEDLoaderTest4.py SauvLoaderTest.py MEDLoaderExamplesTest.py MEDLoaderCouplingTrainingSession.py CaseIO.py CaseReader.py CaseWriter.py VTKReader.py MEDLoaderSplitter.py medutilities.py DESTINATION ${SALOME_INSTALL_SCRIPT_SCRIPTS}) -INSTALL(FILES med2sauv PERMISSIONS OWNER_EXECUTE OWNER_WRITE OWNER_READ GROUP_EXECUTE GROUP_READ WORLD_EXECUTE WORLD_READ DESTINATION ${SALOME_INSTALL_BINS} ) -INSTALL(FILES sauv2med PERMISSIONS OWNER_EXECUTE OWNER_WRITE OWNER_READ GROUP_EXECUTE GROUP_READ WORLD_EXECUTE WORLD_READ DESTINATION ${SALOME_INSTALL_BINS} ) -INSTALL(FILES case2med PERMISSIONS OWNER_EXECUTE OWNER_WRITE OWNER_READ GROUP_EXECUTE GROUP_READ WORLD_EXECUTE WORLD_READ DESTINATION ${SALOME_INSTALL_BINS} ) -INSTALL(FILES med2case PERMISSIONS OWNER_EXECUTE OWNER_WRITE OWNER_READ GROUP_EXECUTE GROUP_READ WORLD_EXECUTE WORLD_READ DESTINATION ${SALOME_INSTALL_BINS} ) - -SALOME_GENERATE_TESTS_ENVIRONMENT(tests_env) - -ADD_TEST(MEDLoaderTest ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/MEDLoaderTest.py) -SET_TESTS_PROPERTIES(MEDLoaderTest PROPERTIES ENVIRONMENT "${tests_env}") -ADD_TEST(MEDLoaderTest2 ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/MEDLoaderTest2.py) -SET_TESTS_PROPERTIES(MEDLoaderTest2 PROPERTIES ENVIRONMENT "${tests_env}") -ADD_TEST(MEDLoaderTest3 ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/MEDLoaderTest3.py) -SET_TESTS_PROPERTIES(MEDLoaderTest3 PROPERTIES ENVIRONMENT "${tests_env}") -ADD_TEST(MEDLoaderTest4 ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/MEDLoaderTest4.py) -SET_TESTS_PROPERTIES(MEDLoaderTest4 PROPERTIES ENVIRONMENT "${tests_env}") -ADD_TEST(MEDLoaderExamplesTest ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/MEDLoaderExamplesTest.py) -SET_TESTS_PROPERTIES(MEDLoaderExamplesTest PROPERTIES ENVIRONMENT "${tests_env}") -ADD_TEST(SauvLoaderTest ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/SauvLoaderTest.py) -SET_TESTS_PROPERTIES(SauvLoaderTest PROPERTIES ENVIRONMENT "${tests_env}") - -IF(NUMPY_FOUND) - ADD_TEST(MEDLoaderCouplingTrainingSession ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/MEDLoaderCouplingTrainingSession.py) - SET_TESTS_PROPERTIES(MEDLoaderCouplingTrainingSession PROPERTIES ENVIRONMENT "${tests_env}") -ENDIF(NUMPY_FOUND) - -# Application tests - -SET(TEST_INSTALL_DIRECTORY ${SALOME_INSTALL_SCRIPT_SCRIPTS}/test/MEDCoupling/MEDLoader/Swig) - -INSTALL(FILES MEDLoaderDataForTest.py MEDLoaderTest.py MEDLoaderTest2.py MEDLoaderTest3.py MEDLoaderTest4.py SauvLoaderTest.py MEDLoaderExamplesTest.py MEDLoaderCouplingTrainingSession.py CaseIO.py CaseReader.py CaseWriter.py VTKReader.py MEDLoaderSplitter.py medutilities.py DESTINATION ${TEST_INSTALL_DIRECTORY}) - -INSTALL(FILES CTestTestfileInstall.cmake - DESTINATION ${TEST_INSTALL_DIRECTORY} - RENAME CTestTestfile.cmake) diff --git a/src/MEDLoader/Swig/CTestTestfileInstall.cmake b/src/MEDLoader/Swig/CTestTestfileInstall.cmake deleted file mode 100644 index 819a91abd..000000000 --- a/src/MEDLoader/Swig/CTestTestfileInstall.cmake +++ /dev/null @@ -1,40 +0,0 @@ -# Copyright (C) 2015 CEA/DEN, EDF 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, 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 -# 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_TEST(MEDLoaderTest python MEDLoaderTest.py) -SET_TESTS_PROPERTIES(MEDLoaderTest PROPERTIES LABELS "${COMPONENT_NAME}") - -ADD_TEST(MEDLoaderTest2 python MEDLoaderTest2.py) -SET_TESTS_PROPERTIES(MEDLoaderTest2 PROPERTIES LABELS "${COMPONENT_NAME}") - -ADD_TEST(MEDLoaderTest3 python MEDLoaderTest3.py) -SET_TESTS_PROPERTIES(MEDLoaderTest3 PROPERTIES LABELS "${COMPONENT_NAME}") - -ADD_TEST(MEDLoaderTest4 python MEDLoaderTest4.py) -SET_TESTS_PROPERTIES(MEDLoaderTest4 PROPERTIES LABELS "${COMPONENT_NAME}") - -ADD_TEST(MEDLoaderExamplesTest python MEDLoaderExamplesTest.py) -SET_TESTS_PROPERTIES(MEDLoaderExamplesTest PROPERTIES LABELS "${COMPONENT_NAME}") - -ADD_TEST(SauvLoaderTest python SauvLoaderTest.py) -SET_TESTS_PROPERTIES(SauvLoaderTest PROPERTIES LABELS "${COMPONENT_NAME}") - -# if numpy is used -ADD_TEST(MEDLoaderCouplingTrainingSession python MEDLoaderCouplingTrainingSession.py) -SET_TESTS_PROPERTIES(MEDLoaderCouplingTrainingSession PROPERTIES LABELS "${COMPONENT_NAME}") diff --git a/src/MEDLoader/Swig/CaseIO.py b/src/MEDLoader/Swig/CaseIO.py deleted file mode 100644 index 1adece4ed..000000000 --- a/src/MEDLoader/Swig/CaseIO.py +++ /dev/null @@ -1,31 +0,0 @@ -# -*- coding: iso-8859-1 -*- -# Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 -# 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/DM2S/STMF/LGLS) - -from MEDLoader import * - -class CaseIO: - dictMCTyp={NORM_HEXA8:"hexa8",NORM_POLYHED:"nfaced",NORM_QUAD4:"quad4",NORM_POLYGON:"nsided",NORM_POINT1:"point",NORM_SEG2:"bar2",NORM_SEG3:"bar3",NORM_TRI3:"tria3",NORM_TRI6:"tria6",NORM_QUAD8:"quad8",NORM_TETRA4:"tetra4",NORM_TETRA10:"tetra10",NORM_PYRA5:"pyramid5",NORM_PYRA13:"pyramid13",NORM_PENTA6:"penta6",NORM_PENTA15:"penta15",NORM_HEXA20:"hexa20"} - discSpatial={ON_CELLS:"element",ON_NODES:"node"} - dictCompo={1:"scalar",3:"vector",6:"tensor",9:"tensor9"} - dictMCTyp2=dict((v,k) for k,v in dictMCTyp.iteritems()) - discSpatial2=dict((v,k) for k,v in discSpatial.iteritems()) - dictCompo2=dict((v,k) for k,v in dictCompo.iteritems()) - pass diff --git a/src/MEDLoader/Swig/CaseReader.py b/src/MEDLoader/Swig/CaseReader.py deleted file mode 100644 index 7fc267180..000000000 --- a/src/MEDLoader/Swig/CaseReader.py +++ /dev/null @@ -1,419 +0,0 @@ -# -*- coding: iso-8859-1 -*- -# Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 -# 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/DM2S/STMF/LGLS) - -# http://www-vis.lbl.gov/NERSC/Software/ensight/doc/OnlineHelp/UM-C11.pdf -import numpy as np -from MEDLoader import * -from CaseIO import CaseIO -import sys,re - -class CaseReader(CaseIO): - """ Converting a file in the Case format (Ensight) to the MED format. - A new file with the same base name and the .med extension is created. - """ - - @classmethod - def New(cls,fileName): - """ Static constructor. """ - return CaseReader(fileName) - pass - - def __init__(self,fileName): - """ Constructor """ - self._fileName=fileName - self._dirName=os.path.dirname(self._fileName) - pass - - def __traduceMesh(self,name,typ,coords,cells): - """ Convert a CASE mesh into a MEDCouplingUMesh. """ - nbCoords=len(coords) - coo=np.array(coords,dtype="float64") ; coo=coo.reshape(nbCoords,3) - coo=DataArrayDouble(coo) ; coo=coo.fromNoInterlace() - ct=self.dictMCTyp2[typ] - m=MEDCouplingUMesh(name,MEDCouplingUMesh.GetDimensionOfGeometricType(ct)) - m.setCoords(coo) - nbNodesPerCell=MEDCouplingMesh.GetNumberOfNodesOfGeometricType(ct) - cI=DataArrayInt(len(cells)+1) ; cI.iota() ; cI*=nbNodesPerCell+1 - # - cells2=cells.reshape(len(cells),nbNodesPerCell) - if cells2.dtype=='int32': - c2=DataArrayInt(cells2) - else: - c2=DataArrayInt(np.array(cells2,dtype="int32")) - pass - c=DataArrayInt(len(cells),nbNodesPerCell+1) ; c[:,0]=ct ; c[:,1:]=c2-1 ; c.rearrange(1) - m.setConnectivity(c,cI,True) - m.checkCoherency2() - return m - - def __traduceMeshForPolyhed(self,name,coords,arr0,arr1,arr2): - nbCoords=len(coords) - coo=np.array(coords,dtype="float64") ; coo=coo.reshape(nbCoords,3) - coo=DataArrayDouble(coo) ; coo=coo.fromNoInterlace() - m=MEDCouplingUMesh(name,3) - m.setCoords(coo) - # - arr2=arr2[:]-1 - arr0mc0=DataArrayInt(arr0) ; arr0mc0.computeOffsets2() - arr0mc1=DataArrayInt(arr0).deepCpy() - arr0mc2=DataArrayInt(len(arr0),2) ; arr0mc2[:,0]=DataArrayInt(arr0)-1 ; arr0mc2[:,1]=1 ; arr0mc2.rearrange(1) ; arr0mc2.computeOffsets2() - arr0mc3=DataArrayInt.Range(0,2*len(arr0),2).buildExplicitArrByRanges(arr0mc2) - arr1mc0=DataArrayInt(arr1) ; arr1mc0.computeOffsets2() - arr1mc1=arr1mc0[arr0mc0] ; arr1mc1[1:]+=arr0mc0[1:] - arr1mc2=DataArrayInt(arr1).deepCpy() ; arr1mc2+=1 ; arr1mc2.computeOffsets2() - arr2mc0=(arr1mc2[1:])[arr0mc3] - # - c=DataArrayInt(arr1.size+arr2.size) - c[arr1mc1[:-1]]=NORM_POLYHED - c[arr2mc0]=-1 - a=arr2mc0.buildUnion(arr1mc1[:-1]).buildComplement(len(c)) - c[a]=DataArrayInt(arr2) - # - m.setConnectivity(c,arr1mc1,True) - m.checkCoherency2() - return m - - def __traduceMeshForPolygon(self,name,coords,arr0,arr1): - nbCoords=len(coords) - coo=np.array(coords,dtype="float64") ; coo=coo.reshape(nbCoords,3) - coo=DataArrayDouble(coo) ; coo=coo.fromNoInterlace() - m=MEDCouplingUMesh(name,2) - m.setCoords(coo) - # - arr0_0=DataArrayInt(arr0+1) ; arr0_0.computeOffsets2() - arr0_1=DataArrayInt(len(arr0),2) ; arr0_1[:,1]=DataArrayInt(arr0) ; arr0_1[:,0]=1 ; arr0_1.rearrange(1) ; arr0_1.computeOffsets2() - arr0_2=DataArrayInt.Range(1,2*len(arr0),2).buildExplicitArrByRanges(arr0_1) - c=DataArrayInt(len(arr0)+len(arr1)) ; c[:]=0 ; c[arr0_0[:-1]]=NORM_POLYGON - c[arr0_2]=DataArrayInt(arr1-1) - # - m.setConnectivity(c,arr0_0,True) - m.checkCoherency2() - return m - - def __convertGeo2MED(self,geoFileName): - """ Convert all the geometry (all the meshes) contained in teh CASE file into MEDCouplingUMesh'es. """ - fd=open(os.path.join(self._dirName,geoFileName),"r+b") ; fd.seek(0,2) ; end=fd.tell() ; fd.seek(0) ; title=fd.read(80) - title=title.strip().lower() - if "binary" not in title: - raise Exception("Error only binary geo files are supported for the moment !") - pass - zeType=True - if "fortran" in title: - mcmeshes=self.__convertGeo2MEDFortran(fd,end) ; zeType=False - else: - mcmeshes=self.__convertGeo2MEDC(fd,end) - # - ms=MEDFileMeshes() - ms.resize(len(mcmeshes)) - for i,m in enumerate(mcmeshes): - mlm=MEDFileUMesh() - mlm.setMeshAtLevel(0,m) - ms.setMeshAtPos(i,mlm) - pass - return mcmeshes,ms,zeType - - def __convertGeo2MEDFortran(self,fd,end): - mcmeshes=[] - fd.read(80) # comment 1 - fd.read(80) # comment 2 - fd.read(80) # node id - fd.read(80) # element id - pos=fd.tell() - elt=fd.read(80) ; elt=elt.strip() ; pos=fd.tell() - mcmeshes2=[] - typ="part" - nbOfTurn=0 - while abs(pos-end)>8 and "part" in typ: - if "part" not in elt: - raise Exception("Error on reading mesh fortran #1 !") - fd.seek(fd.tell()+4)# skip # - tmp=fd.read(80) ; meshName=tmp.split("P")[-1] - tmp=fd.read(80) - if "coordinates" not in tmp: - raise Exception("Error on reading mesh fortran #2 !") - pos=fd.tell() # 644 - if nbOfTurn==0: - pos+=76 # what else ? - else: - pos+=40 - pass - nbNodes=np.memmap(fd,dtype='>i4',mode='r',offset=int(pos),shape=(1,)).tolist()[0] - pos+=12 # what else ? - a=np.memmap(fd,dtype='>f4',mode='r',offset=int(pos),shape=(nbNodes)) - b=np.memmap(fd,dtype='>f4',mode='r',offset=int(pos+nbNodes*4+2*4),shape=(nbNodes)) - c=np.memmap(fd,dtype='>f4',mode='r',offset=int(pos+nbNodes*2*4+4*4),shape=(nbNodes)) - coo=np.zeros(dtype=">f4",shape=(nbNodes*3)) - coo[:nbNodes]=a ; coo[nbNodes:2*nbNodes]=b ; coo[2*nbNodes:]=c - coo=coo.reshape(nbNodes,3) - pos+=nbNodes*3*4 ; fd.seek(pos)#np.array(0,dtype='float%i'%(typeOfCoo)).nbytes - typ=fd.read(80).strip() ; pos=fd.tell() - zeK="" - for k in self.dictMCTyp2.keys(): - if k in typ: - zeK=k - break - pass - pass - pos+=8*4 # yeh man ! - nbCellsOfType=np.memmap(fd,dtype='>i4',mode='r',offset=int(pos),shape=(1,)).tolist()[0] - pos+=4 # for the number of cells - pos+=2*4 # because it's great ! - nbNodesPerCell=MEDCouplingMesh.GetNumberOfNodesOfGeometricType(self.dictMCTyp2[zeK]) - nodalConn=np.memmap(fd,dtype='>i4',mode='r',offset=pos,shape=(nbCellsOfType,nbNodesPerCell)) - meshName=meshName.strip() - mcmeshes2.append(self.__traduceMesh(meshName,zeK,coo,nodalConn)) - pos+=nbNodesPerCell*nbCellsOfType*4 - if abs(pos-end)>8: - fd.seek(pos) ;elt=fd.read(80) ; typ=elt[:] ; pos+=80 - pass - nbOfTurn+=1 - pass - #coo=mcmeshes2[0].getCoords() ; name=mcmeshes2[0].getName() - #for itmesh in mcmeshes2: itmesh.setCoords(coo) - #m=MEDCouplingUMesh.MergeUMeshesOnSameCoords(mcmeshes2) ; m.setName(name) - #mcmeshes.append(m) - return mcmeshes2 - - def __convertGeo2MEDC(self,fd,end): - fd.readline() - name=fd.readline().strip() ; fd.readline() ; fd.readline() - pos=fd.tell() - mcmeshes=[] - elt=fd.read(80) ; elt=elt.strip() ; pos+=80 - while pos!=end: - if "part" not in elt: - raise Exception("Error on reading mesh #1 !") - fd.seek(fd.tell()+4) - meshName=fd.read(80).strip() - if fd.read(len("coordinates"))!="coordinates": - raise Exception("Error on reading mesh #2 !") - pos=fd.tell() - typeOfCoo=np.memmap(fd,dtype='byte',mode='r',offset=int(pos),shape=(1)).tolist()[0] - pos+=1+17*4 - nbNodes=np.memmap(fd,dtype='int32',mode='r',offset=int(pos),shape=(1,)).tolist()[0] - pos+=4 - coo=np.memmap(fd,dtype='float32',mode='r',offset=int(pos),shape=(nbNodes,3)) - pos+=nbNodes*3*4 ; fd.seek(pos)#np.array(0,dtype='float%i'%(typeOfCoo)).nbytes - typ=fd.read(80).strip() ; pos=fd.tell() - mcmeshes2=[] - while pos!=end and typ!="part": - mctyp=self.dictMCTyp2[typ] - nbCellsOfType=np.memmap(fd,dtype='int32',mode='r',offset=int(pos),shape=(1,)).tolist()[0] - pos+=4 - if mctyp!=NORM_POLYHED and mctyp!=NORM_POLYGON: - nbNodesPerCell=MEDCouplingMesh.GetNumberOfNodesOfGeometricType(mctyp) - cells=np.memmap(fd,dtype='int32',mode='r',offset=pos,shape=(nbCellsOfType,nbNodesPerCell)) - pos+=nbCellsOfType*nbNodesPerCell*4 - fd.seek(pos) - mcmeshes2.append(self.__traduceMesh(meshName,typ,coo,cells)) - elif mctyp==NORM_POLYHED: - nbOfFacesPerCell=np.memmap(fd,dtype='int32',mode='r',offset=int(pos),shape=(nbCellsOfType,)) - pos+=nbCellsOfType*4 - szOfNbOfNodesPerFacePerCellArr=int(nbOfFacesPerCell.sum()) - arr1=np.memmap(fd,dtype='int32',mode='r',offset=int(pos),shape=(szOfNbOfNodesPerFacePerCellArr,))#arr1 -> nbOfNodesPerFacePerCellArr - pos+=szOfNbOfNodesPerFacePerCellArr*4 - szOfNodesPerFacePerCellArr=arr1.sum() - arr2=np.memmap(fd,dtype='int32',mode='r',offset=int(pos),shape=(szOfNodesPerFacePerCellArr,))#arr2 -> nodesPerFacePerCellArr - pos+=szOfNodesPerFacePerCellArr*4 ; fd.seek(pos) - mcmeshes2.append(self.__traduceMeshForPolyhed(meshName,coo,nbOfFacesPerCell,arr1,arr2)) - pass - else: - nbOfNodesPerCell=np.memmap(fd,dtype='int32',mode='r',offset=int(pos),shape=(nbCellsOfType,)) - pos+=nbCellsOfType*4 - szOfNbOfNodesPerCellArr=int(nbOfNodesPerCell.sum()) - arr1=np.memmap(fd,dtype='int32',mode='r',offset=int(pos),shape=(szOfNbOfNodesPerCellArr,)) - pos+=szOfNbOfNodesPerCellArr*4 ; fd.seek(pos) - mcmeshes2.append(self.__traduceMeshForPolygon(meshName,coo,nbOfNodesPerCell,arr1)) - if pos!=end: - elt=fd.read(80) ; elt=elt.strip() ; typ=elt[:] ; pos+=80 - pass - pass - coo=mcmeshes2[0].getCoords() ; name=mcmeshes2[0].getName() - for itmesh in mcmeshes2: itmesh.setCoords(coo) - m=MEDCouplingUMesh.MergeUMeshesOnSameCoords(mcmeshes2) ; m.setName(name) - mcmeshes.append(m) - pass - return mcmeshes - - - def __convertField(self,mlfields, mcmeshes, fileName, fieldName, discr, nbCompo, locId, it): - """ Convert the fields. """ - stars=re.search("[\*]+",fileName).group() - st="%0"+str(len(stars))+"i" - trueFileName=fileName.replace(stars,st%(it)) - fd=open(os.path.join(self._dirName,trueFileName),"r+b") ; fd.seek(0,2) ; end=fd.tell() ; fd.seek(0) - name=fd.readline().strip().split(" ")[0] - if name!=fieldName: - raise Exception("ConvertField : mismatch") - pos=fd.tell() - st=fd.read(80) ; st=st.strip() ; pos=fd.tell() - while pos!=end: - if st!="part": - raise Exception("ConvertField : mismatch #2") - fdisc=MEDCouplingFieldDiscretization.New(self.discSpatial2[discr]) - meshId=np.memmap(fd,dtype='int32',mode='r',offset=int(pos),shape=(1)).tolist()[0]-1 - nbOfValues=fdisc.getNumberOfTuples(mcmeshes[meshId]) - vals2=DataArrayDouble(nbOfValues,nbCompo) - fd.seek(pos+4) - st=fd.read(80).strip() ; pos=fd.tell() - offset=0 - while pos!=end and st!="part": - if st!="coordinates": - nbOfValsOfTyp=mcmeshes[meshId].getNumberOfCellsWithType(self.dictMCTyp2[st]) - else: - nbOfValsOfTyp=nbOfValues - pass - vals=np.memmap(fd,dtype='float32',mode='r',offset=int(pos),shape=(nbOfValsOfTyp,nbCompo))#np.memmap(fd,dtype='int32',mode='r',offset=159,shape=(1)) - vals2[offset:offset+nbOfValsOfTyp]=DataArrayDouble(np.array(vals,dtype='float64')).fromNoInterlace() - pos+=nbOfValsOfTyp*nbCompo*4 ; fd.seek(pos) - st=fd.read(80) ; st=st.strip() ; pos=fd.tell() - offset+=nbOfValsOfTyp - pass - f=MEDCouplingFieldDouble(self.discSpatial2[discr],ONE_TIME) ; f.setName("%s_%s"%(fieldName,mcmeshes[meshId].getName())) - f.setMesh(mcmeshes[meshId]) ; f.setArray(vals2) ; f.setTime(float(it),it,-1) - f.checkCoherency() - mlfields[locId+meshId].appendFieldNoProfileSBT(f) - pass - - def __convertFieldFortran(self,mlfields, mcmeshes, fileName, fieldName, discr, nbCompo, locId, it): - """ Convert the fields. """ - if re.search("[\*]+",fileName): - stars=re.search("[\*]+",fileName).group() - st="%0"+str(len(stars))+"i" - trueFileName=fileName.replace(stars,st%(it)) - pass - else: - trueFileName=fileName - pass - fd=open(os.path.join(self._dirName,trueFileName),"r+b") ; fd.seek(0,2) ; end=fd.tell() ; fd.seek(0) - name=fd.read(80) - if fieldName not in name: - raise Exception("ConvertField : mismatch") - pos=fd.tell() - st=fd.read(80) ; st=st.strip() ; pos=fd.tell() - if "part" not in st: - raise Exception("ConvertField : mismatch #2") - st=fd.read(80).strip() ; pos=fd.tell() - pos+=12 # I love it - offset=0 - nbTurn=0 - while pos!=end and "part" not in st: - fdisc=MEDCouplingFieldDiscretization.New(self.discSpatial2[discr]) - nbOfValues=fdisc.getNumberOfTuples(mcmeshes[nbTurn]) - vals2=DataArrayDouble(nbOfValues,nbCompo) - pos+=24 # I love it again ! - nbOfValsOfTyp=np.memmap(fd,dtype='>i4',mode='r',offset=pos,shape=(1)).tolist()[0]/4 - pos+=4 - vals=np.zeros(dtype=">f4",shape=(nbOfValsOfTyp*nbCompo)) - for iii in xrange(nbCompo): - valsTmp=np.memmap(fd,dtype='>f4',mode='r',offset=int(pos),shape=(nbOfValsOfTyp)) - vals[iii*nbOfValsOfTyp:(iii+1)*nbOfValsOfTyp]=valsTmp - pos+=nbOfValsOfTyp*4 - pos+=2*4 ## hey hey, that is the ultimate class ! - vals2.setInfoOnComponent(iii,chr(ord('X')+iii)) - pass - if pos>end: - pos=end - pass - vals=vals.reshape(nbOfValsOfTyp,nbCompo) - vals2[offset:offset+nbOfValsOfTyp]=DataArrayDouble(np.array(vals,dtype='float64')).fromNoInterlace() - if pos!=end: - fd.seek(pos) - st=fd.read(80) ; st=st.strip() ; pos=fd.tell() - st=fd.read(80) ; st=st.strip() ; pos=fd.tell() - pass - f=MEDCouplingFieldDouble(self.discSpatial2[discr],ONE_TIME) ; f.setName("%s_%s"%(fieldName,mcmeshes[nbTurn].getName())) - f.setMesh(mcmeshes[nbTurn]) ; f.setArray(vals2) ; f.setTime(float(it),it,-1) - f.checkCoherency() - mlfields[locId+nbTurn].appendFieldNoProfileSBT(f) - nbTurn+=1 - pass - pass - - def loadInMEDFileDS(self): - """ Load a CASE file into a MEDFileData object. """ - f=file(self._fileName) - lines=f.readlines() - ind=lines.index("GEOMETRY\n") - if ind==-1: - raise Exception("Error with file %s"%(fname)) - geoName=re.match("model:([\W]*)([\w\.]+)",lines[ind+1]).group(2) - m1,m2,typeOfFile=self.__convertGeo2MED(geoName) - fieldsInfo=[] ; nbOfTimeSteps=0 - if "VARIABLE\n" in lines: - ind=lines.index("VARIABLE\n") - end=len(lines)-1 - if "TIME\n" in lines: - end=lines.index("TIME\n") - pass - for i in xrange(ind+1,end): - m=re.match("^([\w]+)[\s]+\per[\s]+([\w]+)[\s]*\:[\s]*([\w]+)[\s]+([\S]+)$",lines[i]) - if m: - if m.groups()[0]=="constant": - continue - spatialDisc=m.groups()[1] ; fieldName=m.groups()[2] ; nbOfCompo=self.dictCompo2[m.groups()[0]] ; fieldFileName=m.groups()[3] - fieldsInfo.append((fieldName,spatialDisc,nbOfCompo,fieldFileName)) - pass - pass - - expr=re.compile("number[\s]+of[\s]+steps[\s]*\:[\s]*([\d]+)") - tmp=filter(expr.search,lines) - if len(tmp)!=0: - nbOfTimeSteps=int(expr.search(filter(expr.search,lines)[0]).group(1)) - expr=re.compile("filename[\s]+start[\s]+number[\s]*\:[\s]*([\d]+)") - startIt=int(expr.search(filter(expr.search,lines)[0]).group(1)) - expr=re.compile("filename[\s]+increment[\s]*\:[\s]*([\d]+)") - incrIt=int(expr.search(filter(expr.search,lines)[0]).group(1)) - else: - nbOfTimeSteps=1 - startIt=0 - incrIt=1 - pass - curIt=startIt - pass - mlfields=MEDFileFields() - mlfields.resize(len(fieldsInfo)*len(m1)) - i=0 - for field in fieldsInfo: - for m in m1: - mlfields.setFieldAtPos(i,MEDFileFieldMultiTS()) - i+=1 - pass - pass - for ts in xrange(nbOfTimeSteps): - i=0 - for field in fieldsInfo: - if typeOfFile: - self.__convertField(mlfields,m1,field[3],field[0],field[1],field[2],i,curIt); - else: - self.__convertFieldFortran(mlfields,m1,field[3],field[0],field[1],field[2],i,curIt) - pass - i+=len(m1) - pass - curIt+=incrIt - pass - ret=MEDFileData() - ret.setMeshes(m2) - del mlfields[filter(lambda x: len(mlfields[x])==0,range(len(mlfields)))] - ret.setFields(mlfields) - return ret - - pass diff --git a/src/MEDLoader/Swig/CaseWriter.py b/src/MEDLoader/Swig/CaseWriter.py deleted file mode 100644 index 73112ad65..000000000 --- a/src/MEDLoader/Swig/CaseWriter.py +++ /dev/null @@ -1,349 +0,0 @@ -# -*- coding: iso-8859-1 -*- -# Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 -# 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/DM2S/STMF/LGLS) - -import numpy as np -from CaseIO import CaseIO -from MEDLoader import * -import sys,re,os,mmap - -### www-vis.lbl.gov/NERSC/Software/ensight/doc/OnlineHelp/UM-C11.pdf - -class CaseWriter(CaseIO): - """ Converting MED file format in memory to a the Case file format (Ensight). - A new file with the same base name and the .case extension is created with its depencies (.geo ...). - """ - - header="""FORMAT -type: ensight gold -GEOMETRY -model: %(geofilewithoutpath)s -""" - header_varpart="""VARIABLE""" - header_timepart="""TIME -time set: 1 -number of steps: %(NbTimeSteps)i -filename start number: 0 -filename increment: 1 -time values: -%(TimeValues)s -""" - - @classmethod - def New(cls): - """ Static constructor. """ - return CaseWriter() - pass - - def __init__(self): - """ Constructor """ - self.__export_groups=False - pass - - def setMEDFileDS(self,medData): - """ Input should be MEDFileData instance """ - self._med_data=medData - pass - - def isExportingGroups(self): - """ return the status of exporting groups policy """ - return self.__export_groups - - def setExportingGroups(self,status): - assert(isinstance(status,bool)) - self.__export_groups=status - pass - - - def write(self,fileName): - """ Write into the specified fileName series the result """ - self._file_name=fileName - self._base_name_without_dir=os.path.splitext(os.path.basename(self._file_name))[0] - self._l=self._file_name.split(os.path.sep) ; self._l[-1]=os.path.splitext(self._l[-1])[0] - self._base_name_with_dir=os.path.sep.join(self._l) - self._real_written_file_name=[] - self._dico={} - for mesh in self._med_data.getMeshes(): - additionnalFileNamePart="" - if len(self._med_data.getMeshes())!=1: - additionnalFileNamePart="_%s"%(mesh.getName()) - pass - self._dico["geofilewithoutpath"]="%s%s.geo"%(self._base_name_without_dir,additionnalFileNamePart) - h0=self.header%self._dico - self.__writeMeshesPart(mesh,"%s%s.geo"%(self._base_name_with_dir,additionnalFileNamePart)) - # - h2=self.__writeFieldsPart(self._med_data.getFields().partOfThisLyingOnSpecifiedMeshName(mesh.getName())) - realWrittenCaseFileNameForCurMesh="%s%s.case"%(self._base_name_with_dir,additionnalFileNamePart) - fheader=open(realWrittenCaseFileNameForCurMesh,"w") ; fheader.write((h0+h2)%self._dico) - self._real_written_file_name.append(realWrittenCaseFileNameForCurMesh) - pass - return self._real_written_file_name - - def __writeMeshesPart(self,mdm,meshfn): - try: - os.remove(meshfn) - except: - pass - f=open(meshfn,"w+b") - sz=5*80 - # - assert(isinstance(mdm,MEDFileUMesh)) - ms2=[[mdm.getMeshAtLevel(lev) for lev in mdm.getNonEmptyLevels()[:1]]] - if self.__export_groups: - for grpnm in mdm.getGroupsNames(): - ms3=[] - for lev in mdm.getGrpNonEmptyLevels(grpnm)[:1]: - m=mdm.getGroup(lev,grpnm) ; m.zipCoords() - ms3.append(m) - pass - ms2.append(ms3) - pass - pass - for ms in ms2: - nn=ms[0].getNumberOfNodes() - sz+=self.__computeSizeOfGeoFile(ms,nn) - pass - pass - a=np.memmap(f,dtype='byte',mode='w+',offset=0,shape=(sz,)) ; a.flush() # truncate to set the size of the file - mm=mmap.mmap(f.fileno(),offset=0,length=0) - mm.write(self.__str80("C Binary")) - mm.write(self.__str80("Exported from MEDCoupling/MEDLoader SALOME version %s"%(MEDCouplingVersionStr()))) - mm.write(self.__str80("Conversion using CaseWriter class")) - mm.write(self.__str80("node id off")) - mm.write(self.__str80("element id off")) - for iii,ms in enumerate(ms2): - nn=ms[0].getNumberOfNodes() - mm.write(self.__str80("part")) - a=np.memmap(f,dtype='int32',mode='w+',offset=mm.tell(),shape=(1,)) - a[0]=iii+1 ; a.flush() ; mm.seek(mm.tell()+4) # part number maybe to change ? - name=ms[0].getName() - if iii>0: - name="%s_%s"%(ms2[0][0].getName(),name) - pass - mm.write(self.__str80(name)) - mm.write(self.__str80("coordinates")) - a=np.memmap(f,dtype='int32',mode='w+',offset=mm.tell(),shape=(1,)) - a[0]=nn ; a.flush() # number of nodes - mm.seek(mm.tell()+4) - coo=ms[0].getCoords() - spaceDim=coo.getNumberOfComponents() - if spaceDim!=3: - coo=coo.changeNbOfComponents(3,0.) - pass - a=np.memmap(f,dtype='float32',mode='w+',offset=mm.tell(),shape=(3,nn)) - c=coo.toNoInterlace() ; c.rearrange(1) ; cnp=c.toNumPyArray() ; cnp=cnp.reshape(3,nn) - a[:]=cnp ; a.flush() ; mm.seek(mm.tell()+3*nn*4) - for m in ms: - i=0 - for typ2,nbelem,dummy in m.getDistributionOfTypes(): - typ=typ2 - if typ not in self.dictMCTyp: - typ=MEDCouplingMesh.GetCorrespondingPolyType(typ) - pass - mp=m[i:i+nbelem] - mm.write(self.__str80(self.dictMCTyp[typ])) - a=np.memmap(f,dtype='int32',mode='w+',offset=mm.tell(),shape=(1,)) - a[0]=nbelem ; a.flush() ; mm.seek(mm.tell()+4) - if typ!=NORM_POLYHED and typ!=NORM_POLYGON: - nbNodesPerElem=MEDCouplingMesh.GetNumberOfNodesOfGeometricType(typ) - c=mp.getNodalConnectivity() ; c.rearrange(nbNodesPerElem+1) ; c=c[:,1:] ; c.rearrange(1) ; c+=1 - a=np.memmap(f,dtype='int32',mode='w+',offset=mm.tell(),shape=(nbNodesPerElem*nbelem,)) - a[:]=c.toNumPyArray() ; a.flush() ; mm.seek(mm.tell()+nbNodesPerElem*nbelem*4) - pass - elif typ==NORM_POLYHED: - mp.orientCorrectlyPolyhedrons() - c=mp.computeNbOfFacesPerCell() - a=np.memmap(f,dtype='int32',mode='w+',offset=mm.tell(),shape=(nbelem,)) - a[:]=c.toNumPyArray(); a.flush() ; mm.seek(mm.tell()+nbelem*4) - c=mp.getNodalConnectivity()[:] ; c.pushBackSilent(-1) ; c[mp.getNodalConnectivityIndex()[:-1]]=-1 ; ids=c.getIdsEqual(-1) ; nbOfNodesPerFace=ids.deltaShiftIndex()-1 - a=np.memmap(f,dtype='int32',mode='w+',offset=mm.tell(),shape=(len(nbOfNodesPerFace),)) - a[:]=nbOfNodesPerFace.toNumPyArray() ; a.flush() ; mm.seek(mm.tell()+len(nbOfNodesPerFace)*4) - ids2=ids.buildComplement(ids.back()+1) - c2=mp.getNodalConnectivity()[ids2]+1 - a=np.memmap(f,dtype='int32',mode='w+',offset=mm.tell(),shape=(len(c2),)) - a[:]=c2.toNumPyArray() ; a.flush() ; mm.seek(mm.tell()+len(c2)*4) - pass - else: - nbOfNodesPerCell=mp.getNodalConnectivityIndex().deltaShiftIndex()-1 - a=np.memmap(f,dtype='int32',mode='w+',offset=mm.tell(),shape=(len(nbOfNodesPerCell),)) - a[:]=nbOfNodesPerCell.toNumPyArray() ; a.flush() ; mm.seek(mm.tell()+len(nbOfNodesPerCell)*4) - ids2=mp.getNodalConnectivityIndex().buildComplement(mp.getNodalConnectivityIndex().back()+1) - c2=mp.getNodalConnectivity()[ids2]+1 - a=np.memmap(f,dtype='int32',mode='w+',offset=mm.tell(),shape=(len(c2),)) - a[:]=c2.toNumPyArray() ; a.flush() ; mm.seek(mm.tell()+len(c2)*4) - pass - i+=nbelem - pass - pass - pass - pass - - def __writeFieldsPart(self,mdfs): - if not mdfs: - return "" - self._ze_top_dict={} - its,areForgottenTS=mdfs.getCommonIterations() - if areForgottenTS: - print "WARNING : some iterations are NOT present in all fields ! Kept iterations are : %s !"%(str(its)) - pass - TimeValues="" - for it in its: - TimeValues+="%s\n"%(str(mdfs[0][it].getTime()[-1])) - pass - dictVars={} - for mdf in mdfs: - nbCompo=mdf.getNumberOfComponents() - if nbCompo not in self.dictCompo: - l=filter(lambda x:x-nbCompo>0,self.dictCompo.keys()) - if len(l)==0: - print "Field \"%s\" will be ignored because number of components (%i) is too big to be %s supported by case files !"%(mdf.getName(),nbCompo,str(self.dictCompo.keys())) - continue - pass - print "WARNING : Field \"%s\" will have its number of components (%i) set to %i, in order to be supported by case files (must be in %s) !"%(mdf.getName(),nbCompo,l[0],str(self.dictCompo.keys())) - nbCompo=l[0] - pass - if nbCompo in dictVars: - dictVars[nbCompo].append(mdf) - pass - else: - dictVars[nbCompo]=[mdf] - pass - pass - for mdf in mdfs: - nbCompo=mdf.getNumberOfComponents() - if nbCompo not in self.dictCompo: - l=filter(lambda x:x-nbCompo>0,self.dictCompo.keys()) - if len(l)==0: - continue; - nbCompo=l[0] - pass - for iii,it in enumerate(its): - ff=mdf[it] - isMultiDisc=len(ff.getTypesOfFieldAvailable())>1 - for typ in ff.getTypesOfFieldAvailable(): - l=self._l[:] ; l[-1]="%s%s.%s"%(self._base_name_without_dir,str(iii).rjust(4,"0"),ff.getName()) - if isMultiDisc: - l[-1]="%s_%s"(l[-1],MEDCouplingFieldDiscretization.New(typ).getStringRepr()) - pass - fffn=l[-1] - try: - os.remove(os.path.sep.join(l)) - except: - pass - f=open(os.path.sep.join(l),"w+b") - summ=0 - for geo,[(curTyp,(bg,end),pfl,loc)] in ff.getFieldSplitedByType(): - if typ==curTyp: - summ+=4*nbCompo*(end-bg)+80 - pass - pass - a=np.memmap(f,dtype='byte',mode='w+',offset=0,shape=(2*80+4+summ,)) ; a.flush() # truncate to set the size of the file - mm=mmap.mmap(f.fileno(),offset=0,length=0) - k1=ff.getName() - if isMultiDisc: - k1="%s_%s"%(k1,MEDCouplingFieldDiscretization.New(typ).getStringRepr()) - pass - mm.write(self.__str80(k1)) - mm.write(self.__str80("part")) - a=np.memmap(f,dtype='int32',mode='w+',offset=mm.tell(),shape=(1,)) - a[0]=1 ; a.flush() ; mm.seek(mm.tell()+4) # part number maybe to change ? - for geo,[(curTyp,(bg,end),pfl,loc)] in ff.getFieldSplitedByType(): - if pfl!="": - raise Exception("Field \"%s\" contains profiles ! Profiles are not supported yet !"%(mdf.getName())) - if typ==curTyp: - arr=ff.getUndergroundDataArray()[bg:end].changeNbOfComponents(nbCompo,0.) ; arr=arr.toNoInterlace() - if typ==ON_CELLS: - mm.write(self.__str80(self.dictMCTyp[geo])) - pass - elif typ==ON_NODES: - mm.write(self.__str80("coordinates")) - pass - else: - print "UnManaged type of field for field \"%s\" !"%(mdf.getName()) - pass - a=np.memmap(f,dtype='float32',mode='w+',offset=mm.tell(),shape=(nbCompo,end-bg)) - b=arr.toNumPyArray() ; b=b.reshape(nbCompo,end-bg) - a[:]=b - a.flush() ; mm.seek(mm.tell()+nbCompo*(end-bg)*4) - pass - pass - k="%s per %s"%(self.dictCompo[nbCompo],self.discSpatial[typ]) - if k in self._ze_top_dict: - if k1 in self._ze_top_dict[k]: - self._ze_top_dict[k][k1].append(fffn) - pass - else: - self._ze_top_dict[k][k1]=[fffn] - pass - else: - self._ze_top_dict[k]={k1:[fffn]} - pass - pass - pass - pass - headerPart="" - if len(self._ze_top_dict)!=0: - hvp=self.header_varpart[:] - for k in self._ze_top_dict: - for k1 in self._ze_top_dict[k]: - hvp+="\n%s: %s %s"%(k,k1,re.sub("([\d]{4})",4*"*",self._ze_top_dict[k][k1][0])) - pass - pass - hvp+="\n" - headerPart+=hvp - # - ddd={"NbTimeSteps":len(its),"TimeValues":TimeValues} - htp=self.header_timepart%ddd - headerPart+=htp - pass - return headerPart - - @classmethod - def __str80(cls,st): - if len(st)>79: - raise Exception("String \"%s\" is too long (>79) !"%(st)) - return st.ljust(79)+"\n" - - def __computeSizeOfGeoFile(self,listOfMeshes,nn): - sz=0 - for m in listOfMeshes: - distribTypes=m.getDistributionOfTypes() - sz+=80+4+2*80+4+nn*3*4 - i=0 - for typ2,nbelem,dummy in distribTypes: - typ=typ2 - if typ not in self.dictMCTyp: - typ=MEDCouplingMesh.GetCorrespondingPolyType() - pass - if typ!=NORM_POLYHED and typ!=NORM_POLYGON: - sz+=80+4+MEDCouplingMesh.GetNumberOfNodesOfGeometricType(typ)*nbelem*4 - pass - elif typ==NORM_POLYHED: - mplh=m[i:i+nbelem] ; delta=len(mplh.getNodalConnectivity())+nbelem - sz+=80+4+delta*4 - pass - else: - mplh=m[i:i+nbelem] ; delta=len(mplh.getNodalConnectivity()) - sz+=80+4+delta*4 - pass - i+=nbelem - pass - pass - return sz diff --git a/src/MEDLoader/Swig/MEDLoader.i b/src/MEDLoader/Swig/MEDLoader.i deleted file mode 100644 index d85b63816..000000000 --- a/src/MEDLoader/Swig/MEDLoader.i +++ /dev/null @@ -1,148 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 -// 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 "MEDLoaderCommon.i" - -%pythoncode %{ -def ParaMEDMEMDataArrayDoublenew(cls,*args): - import _MEDLoader - return _MEDLoader.DataArrayDouble____new___(cls,args) -def ParaMEDMEMDataArrayDoubleIadd(self,*args): - import _MEDLoader - return _MEDLoader.DataArrayDouble____iadd___(self, self, *args) -def ParaMEDMEMDataArrayDoubleIsub(self,*args): - import _MEDLoader - return _MEDLoader.DataArrayDouble____isub___(self, self, *args) -def ParaMEDMEMDataArrayDoubleImul(self,*args): - import _MEDLoader - return _MEDLoader.DataArrayDouble____imul___(self, self, *args) -def ParaMEDMEMDataArrayDoubleIdiv(self,*args): - import _MEDLoader - return _MEDLoader.DataArrayDouble____idiv___(self, self, *args) -def ParaMEDMEMDataArrayDoubleIpow(self,*args): - import _MEDLoader - return _MEDLoader.DataArrayDouble____ipow___(self, self, *args) -def ParaMEDMEMMEDCouplingFieldDoublenew(cls,*args): - import _MEDLoader - return _MEDLoader.MEDCouplingFieldDouble____new___(cls,args) -def ParaMEDMEMMEDCouplingFieldDoubleIadd(self,*args): - import _MEDLoader - return _MEDLoader.MEDCouplingFieldDouble____iadd___(self, self, *args) -def ParaMEDMEMMEDCouplingFieldDoubleIsub(self,*args): - import _MEDLoader - return _MEDLoader.MEDCouplingFieldDouble____isub___(self, self, *args) -def ParaMEDMEMMEDCouplingFieldDoubleImul(self,*args): - import _MEDLoader - return _MEDLoader.MEDCouplingFieldDouble____imul___(self, self, *args) -def ParaMEDMEMMEDCouplingFieldDoubleIdiv(self,*args): - import _MEDLoader - return _MEDLoader.MEDCouplingFieldDouble____idiv___(self, self, *args) -def ParaMEDMEMMEDCouplingFieldDoubleIpow(self,*args): - import _MEDLoader - return _MEDLoader.MEDCouplingFieldDouble____ipow___(self, self, *args) -def ParaMEDMEMDataArrayIntnew(cls,*args): - import _MEDLoader - return _MEDLoader.DataArrayInt____new___(cls,args) -def ParaMEDMEMDataArrayIntIadd(self,*args): - import _MEDLoader - return _MEDLoader.DataArrayInt____iadd___(self, self, *args) -def ParaMEDMEMDataArrayIntIsub(self,*args): - import _MEDLoader - return _MEDLoader.DataArrayInt____isub___(self, self, *args) -def ParaMEDMEMDataArrayIntImul(self,*args): - import _MEDLoader - return _MEDLoader.DataArrayInt____imul___(self, self, *args) -def ParaMEDMEMDataArrayIntIdiv(self,*args): - import _MEDLoader - return _MEDLoader.DataArrayInt____idiv___(self, self, *args) -def ParaMEDMEMDataArrayIntImod(self,*args): - import _MEDLoader - return _MEDLoader.DataArrayInt____imod___(self, self, *args) -def ParaMEDMEMDataArrayIntIpow(self,*args): - import _MEDLoader - return _MEDLoader.DataArrayInt____ipow___(self, self, *args) -def ParaMEDMEMDataArrayDoubleTupleIadd(self,*args): - import _MEDLoader - return _MEDLoader.DataArrayDoubleTuple____iadd___(self, self, *args) -def ParaMEDMEMDataArrayDoubleTupleIsub(self,*args): - import _MEDLoader - return _MEDLoader.DataArrayDoubleTuple____isub___(self, self, *args) -def ParaMEDMEMDataArrayDoubleTupleImul(self,*args): - import _MEDLoader - return _MEDLoader.DataArrayDoubleTuple____imul___(self, self, *args) -def ParaMEDMEMDataArrayDoubleTupleIdiv(self,*args): - import _MEDLoader - return _MEDLoader.DataArrayDoubleTuple____idiv___(self, self, *args) -def ParaMEDMEMDataArrayIntTupleIadd(self,*args): - import _MEDLoader - return _MEDLoader.DataArrayIntTuple____iadd___(self, self, *args) -def ParaMEDMEMDataArrayIntTupleIsub(self,*args): - import _MEDLoader - return _MEDLoader.DataArrayIntTuple____isub___(self, self, *args) -def ParaMEDMEMDataArrayIntTupleImul(self,*args): - import _MEDLoader - return _MEDLoader.DataArrayIntTuple____imul___(self, self, *args) -def ParaMEDMEMDataArrayIntTupleIdiv(self,*args): - import _MEDLoader - return _MEDLoader.DataArrayIntTuple____idiv___(self, self, *args) -def ParaMEDMEMDataArrayIntTupleImod(self,*args): - import _MEDLoader - return _MEDLoader.DataArrayIntTuple____imod___(self, self, *args) -def ParaMEDMEMDenseMatrixIadd(self,*args): - import _MEDLoader - return _MEDLoader.DenseMatrix____iadd___(self, self, *args) -def ParaMEDMEMDenseMatrixIsub(self,*args): - import _MEDLoader - return _MEDLoader.DenseMatrix____isub___(self, self, *args) -def ParaMEDMEMMEDCouplingUMeshnew(cls,*args): - import _MEDLoader - return _MEDLoader.MEDCouplingUMesh____new___(cls,args) -def ParaMEDMEMMEDCoupling1DGTUMeshnew(cls,*args): - import _MEDLoader - return _MEDLoader.MEDCoupling1DGTUMesh____new___(cls,args) -def ParaMEDMEMMEDCoupling1SGTUMeshnew(cls,*args): - import _MEDLoader - return _MEDLoader.MEDCoupling1SGTUMesh____new___(cls,args) -def ParaMEDMEMMEDCouplingCurveLinearMeshnew(cls,*args): - import _MEDLoader - return _MEDLoader.MEDCouplingCurveLinearMesh____new___(cls,args) -def ParaMEDMEMMEDCouplingCMeshnew(cls,*args): - import _MEDLoader - return _MEDLoader.MEDCouplingCMesh____new___(cls,args) -def ParaMEDMEMMEDCouplingIMeshnew(cls,*args): - import _MEDLoader - return _MEDLoader.MEDCouplingIMesh____new___(cls,args) -def ParaMEDMEMMEDCouplingExtrudedMeshnew(cls,*args): - import _MEDLoader - return _MEDLoader.MEDCouplingExtrudedMesh____new___(cls,args) -%} - -%pythoncode %{ -def ParaMEDMEMMEDFileUMeshnew(cls,*args): - import _MEDLoader - return _MEDLoader.MEDFileUMesh____new___(cls,args) -%} - -%include "MEDCouplingFinalize.i" - -%pythoncode %{ -MEDFileUMesh.__new__=classmethod(ParaMEDMEMMEDFileUMeshnew) -del ParaMEDMEMMEDFileUMeshnew -%} diff --git a/src/MEDLoader/Swig/MEDLoaderCommon.i b/src/MEDLoader/Swig/MEDLoaderCommon.i deleted file mode 100644 index 85d65699b..000000000 --- a/src/MEDLoader/Swig/MEDLoaderCommon.i +++ /dev/null @@ -1,3529 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 -// 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) - -%module MEDLoader - -#define MEDCOUPLING_EXPORT -#define MEDLOADER_EXPORT - -#ifdef WITH_DOCSTRINGS -%include "MEDLoader_doc.i" -#endif - -%include "MEDCouplingCommon.i" - -%{ -#include "MEDLoader.hxx" -#include "MEDFileJoint.hxx" -#include "MEDFileMesh.hxx" -#include "MEDFileField.hxx" -#include "MEDFileParameter.hxx" -#include "MEDFileData.hxx" -#include "MEDFileMeshReadSelector.hxx" -#include "MEDFileFieldOverView.hxx" -#include "MEDLoaderTypemaps.i" -#include "SauvReader.hxx" -#include "SauvWriter.hxx" - -using namespace ParaMEDMEM; -%} - -#if SWIG_VERSION >= 0x010329 -%template() std::vector<std::string>; -#endif - -%typemap(out) ParaMEDMEM::MEDFileMesh* -{ - $result=convertMEDFileMesh($1,$owner); -} - -%typemap(out) ParaMEDMEM::MEDFileParameter1TS* -{ - $result=convertMEDFileParameter1TS($1,$owner); -} - -%typemap(out) ParaMEDMEM::MEDFileAnyTypeFieldMultiTS* -{ - $result=convertMEDFileFieldMultiTS($1,$owner); -} - -%typemap(out) ParaMEDMEM::MEDFileAnyTypeField1TS* -{ - $result=convertMEDFileField1TS($1,$owner); -} - -%typemap(out) ParaMEDMEM::MEDMeshMultiLev* -{ - $result=convertMEDMeshMultiLev($1,$owner); -} - -%newobject MEDLoader::ReadUMeshFromFamilies; -%newobject MEDLoader::ReadUMeshFromGroups; -%newobject MEDLoader::ReadUMeshFromFile; -%newobject MEDLoader::ReadMeshFromFile; -%newobject MEDLoader::ReadField; -%newobject MEDLoader::ReadFieldCell; -%newobject MEDLoader::ReadFieldNode; -%newobject MEDLoader::ReadFieldGauss; -%newobject MEDLoader::ReadFieldGaussNE; -%newobject ParaMEDMEM::MEDFileMesh::New; -%newobject ParaMEDMEM::MEDFileMesh::createNewEmpty; -%newobject ParaMEDMEM::MEDFileMesh::deepCpy; -%newobject ParaMEDMEM::MEDFileMesh::shallowCpy; -%newobject ParaMEDMEM::MEDFileMesh::getGenMeshAtLevel; -%newobject ParaMEDMEM::MEDFileMesh::__getitem__; -%newobject ParaMEDMEM::MEDFileMesh::getGroupArr; -%newobject ParaMEDMEM::MEDFileMesh::getGroupsArr; -%newobject ParaMEDMEM::MEDFileMesh::getFamilyArr; -%newobject ParaMEDMEM::MEDFileMesh::getFamiliesArr; -%newobject ParaMEDMEM::MEDFileMesh::getNodeGroupArr; -%newobject ParaMEDMEM::MEDFileMesh::getNodeGroupsArr; -%newobject ParaMEDMEM::MEDFileMesh::getNodeFamilyArr; -%newobject ParaMEDMEM::MEDFileMesh::getNodeFamiliesArr; -%newobject ParaMEDMEM::MEDFileMesh::getAllFamiliesIdsReferenced; -%newobject ParaMEDMEM::MEDFileMesh::computeAllFamilyIdsInUse; -%newobject ParaMEDMEM::MEDFileData::getJoints; -%newobject ParaMEDMEM::MEDFileStructuredMesh::getImplicitFaceMesh; -%newobject ParaMEDMEM::MEDFileUMesh::New; -%newobject ParaMEDMEM::MEDFileUMesh::LoadPartOf; -%newobject ParaMEDMEM::MEDFileUMesh::getCoords; -%newobject ParaMEDMEM::MEDFileUMesh::getPartDefAtLevel; -%newobject ParaMEDMEM::MEDFileUMesh::getGroup; -%newobject ParaMEDMEM::MEDFileUMesh::getGroups; -%newobject ParaMEDMEM::MEDFileUMesh::getFamily; -%newobject ParaMEDMEM::MEDFileUMesh::getFamilies; -%newobject ParaMEDMEM::MEDFileUMesh::getMeshAtLevel; -%newobject ParaMEDMEM::MEDFileUMesh::getLevel0Mesh; -%newobject ParaMEDMEM::MEDFileUMesh::getLevelM1Mesh; -%newobject ParaMEDMEM::MEDFileUMesh::getLevelM2Mesh; -%newobject ParaMEDMEM::MEDFileUMesh::getLevelM3Mesh; -%newobject ParaMEDMEM::MEDFileUMesh::getDirectUndergroundSingleGeoTypeMesh; -%newobject ParaMEDMEM::MEDFileUMesh::extractFamilyFieldOnGeoType; -%newobject ParaMEDMEM::MEDFileUMesh::extractNumberFieldOnGeoType; -%newobject ParaMEDMEM::MEDFileUMesh::zipCoords; -%newobject ParaMEDMEM::MEDFileUMesh::buildExtrudedMesh; -%newobject ParaMEDMEM::MEDFileUMesh::linearToQuadratic; -%newobject ParaMEDMEM::MEDFileUMesh::quadraticToLinear; -%newobject ParaMEDMEM::MEDFileCMesh::New; -%newobject ParaMEDMEM::MEDFileCurveLinearMesh::New; -%newobject ParaMEDMEM::MEDFileMeshMultiTS::New; -%newobject ParaMEDMEM::MEDFileMeshMultiTS::deepCpy; -%newobject ParaMEDMEM::MEDFileMeshMultiTS::getOneTimeStep; -%newobject ParaMEDMEM::MEDFileMeshes::New; -%newobject ParaMEDMEM::MEDFileMeshes::deepCpy; -%newobject ParaMEDMEM::MEDFileMeshes::getMeshAtPos; -%newobject ParaMEDMEM::MEDFileMeshes::getMeshWithName; -%newobject ParaMEDMEM::MEDFileMeshes::__getitem__; -%newobject ParaMEDMEM::MEDFileMeshes::__iter__; - -%newobject ParaMEDMEM::MEDFileFields::New; -%newobject ParaMEDMEM::MEDFileFields::LoadPartOf; -%newobject ParaMEDMEM::MEDFileFields::LoadSpecificEntities; -%newobject ParaMEDMEM::MEDFileFields::deepCpy; -%newobject ParaMEDMEM::MEDFileFields::shallowCpy; -%newobject ParaMEDMEM::MEDFileFields::getFieldWithName; -%newobject ParaMEDMEM::MEDFileFields::getFieldAtPos; -%newobject ParaMEDMEM::MEDFileFields::partOfThisLyingOnSpecifiedMeshName; -%newobject ParaMEDMEM::MEDFileFields::partOfThisLyingOnSpecifiedTimeSteps; -%newobject ParaMEDMEM::MEDFileFields::partOfThisNotLyingOnSpecifiedTimeSteps; -%newobject ParaMEDMEM::MEDFileFields::__iter__; - -%newobject ParaMEDMEM::MEDFileAnyTypeFieldMultiTS::New; -%newobject ParaMEDMEM::MEDFileAnyTypeFieldMultiTS::deepCpy; -%newobject ParaMEDMEM::MEDFileAnyTypeFieldMultiTS::shallowCpy; -%newobject ParaMEDMEM::MEDFileAnyTypeFieldMultiTS::getTimeStepAtPos; -%newobject ParaMEDMEM::MEDFileAnyTypeFieldMultiTS::getTimeStep; -%newobject ParaMEDMEM::MEDFileAnyTypeFieldMultiTS::getTimeStepGivenTime; -%newobject ParaMEDMEM::MEDFileAnyTypeFieldMultiTS::__iter__; -%newobject ParaMEDMEM::MEDFileFieldMultiTS::New; -%newobject ParaMEDMEM::MEDFileFieldMultiTS::LoadSpecificEntities; -%newobject ParaMEDMEM::MEDFileFieldMultiTS::getFieldAtLevel; -%newobject ParaMEDMEM::MEDFileFieldMultiTS::getFieldAtTopLevel; -%newobject ParaMEDMEM::MEDFileFieldMultiTS::getFieldOnMeshAtLevel; -%newobject ParaMEDMEM::MEDFileFieldMultiTS::getFieldAtLevelOld; -%newobject ParaMEDMEM::MEDFileFieldMultiTS::getUndergroundDataArray; -%newobject ParaMEDMEM::MEDFileFieldMultiTS::convertToInt; -%newobject ParaMEDMEM::MEDFileIntFieldMultiTS::New; -%newobject ParaMEDMEM::MEDFileIntFieldMultiTS::LoadSpecificEntities; -%newobject ParaMEDMEM::MEDFileIntFieldMultiTS::getUndergroundDataArray; -%newobject ParaMEDMEM::MEDFileIntFieldMultiTS::convertToDouble; - -%newobject ParaMEDMEM::MEDFileAnyTypeField1TS::New; -%newobject ParaMEDMEM::MEDFileAnyTypeField1TS::shallowCpy; -%newobject ParaMEDMEM::MEDFileAnyTypeField1TS::deepCpy; -%newobject ParaMEDMEM::MEDFileField1TS::New; -%newobject ParaMEDMEM::MEDFileField1TS::getFieldAtLevel; -%newobject ParaMEDMEM::MEDFileField1TS::getFieldAtTopLevel; -%newobject ParaMEDMEM::MEDFileField1TS::getFieldOnMeshAtLevel; -%newobject ParaMEDMEM::MEDFileField1TS::getFieldAtLevelOld; -%newobject ParaMEDMEM::MEDFileField1TS::getUndergroundDataArray; -%newobject ParaMEDMEM::MEDFileField1TS::convertToInt; -%newobject ParaMEDMEM::MEDFileIntField1TS::New; -%newobject ParaMEDMEM::MEDFileIntField1TS::getUndergroundDataArray; -%newobject ParaMEDMEM::MEDFileIntField1TS::convertToDouble; - -%newobject ParaMEDMEM::MEDFileData::New; -%newobject ParaMEDMEM::MEDFileData::deepCpy; -%newobject ParaMEDMEM::MEDFileData::getMeshes; -%newobject ParaMEDMEM::MEDFileData::getFields; -%newobject ParaMEDMEM::MEDFileData::getParams; - -%newobject ParaMEDMEM::MEDFileParameterDouble1TS::New; -%newobject ParaMEDMEM::MEDFileParameterDouble1TS::deepCpy; -%newobject ParaMEDMEM::MEDFileParameterMultiTS::New; -%newobject ParaMEDMEM::MEDFileParameterMultiTS::deepCpy; -%newobject ParaMEDMEM::MEDFileParameterMultiTS::getTimeStepAtPos; -%newobject ParaMEDMEM::MEDFileParameterMultiTS::__getitem__; -%newobject ParaMEDMEM::MEDFileParameters::New; -%newobject ParaMEDMEM::MEDFileParameters::deepCpy; -%newobject ParaMEDMEM::MEDFileParameters::getParamAtPos; -%newobject ParaMEDMEM::MEDFileParameters::getParamWithName; -%newobject ParaMEDMEM::MEDFileParameters::__getitem__; - -%newobject ParaMEDMEM::MEDFileJointCorrespondence::New; -%newobject ParaMEDMEM::MEDFileJointCorrespondence::deepCpy; -%newobject ParaMEDMEM::MEDFileJointCorrespondence::shallowCpy; -%newobject ParaMEDMEM::MEDFileJointOneStep::New; -%newobject ParaMEDMEM::MEDFileJointOneStep::deepCpy; -%newobject ParaMEDMEM::MEDFileJointOneStep::shallowCpy; -%newobject ParaMEDMEM::MEDFileJoint::New; -%newobject ParaMEDMEM::MEDFileJoint::deepCpy; -%newobject ParaMEDMEM::MEDFileJoint::shallowCpy; -%newobject ParaMEDMEM::MEDFileJoints::New; -%newobject ParaMEDMEM::MEDFileJoints::deepCpy; -%newobject ParaMEDMEM::MEDFileJoints::getJointAtPos; -%newobject ParaMEDMEM::MEDFileJoints::getJointWithName; -%newobject ParaMEDMEM::MEDFileJoints::__getitem__; - -%newobject ParaMEDMEM::SauvWriter::New; -%newobject ParaMEDMEM::SauvReader::New; -%newobject ParaMEDMEM::SauvReader::loadInMEDFileDS; - -%newobject ParaMEDMEM::MEDFileMeshStruct::New; -%newobject ParaMEDMEM::MEDMeshMultiLev::prepare; -%newobject ParaMEDMEM::MEDMeshMultiLev::buildDataArray; -%newobject ParaMEDMEM::MEDFileFastCellSupportComparator::New; -%newobject ParaMEDMEM::MEDFileFastCellSupportComparator::buildFromScratchDataSetSupport; - -%feature("unref") MEDFileMesh "$this->decrRef();" -%feature("unref") MEDFileUMesh "$this->decrRef();" -%feature("unref") MEDFileCMesh "$this->decrRef();" -%feature("unref") MEDFileMeshMultiTS "$this->decrRef();" -%feature("unref") MEDFileMeshes "$this->decrRef();" -%feature("unref") MEDFileFieldLoc "$this->decrRef();" -%feature("unref") MEDFileAnyTypeField1TS "$this->decrRef();" -%feature("unref") MEDFileField1TS "$this->decrRef();" -%feature("unref") MEDFileIntField1TS "$this->decrRef();" -%feature("unref") MEDFileAnyTypeFieldMultiTS "$this->decrRef();" -%feature("unref") MEDFileFieldMultiTS "$this->decrRef();" -%feature("unref") MEDFileIntFieldMultiTS "$this->decrRef();" -%feature("unref") MEDFileFields "$this->decrRef();" -%feature("unref") MEDFileParameter1TS "$this->decrRef();" -%feature("unref") MEDFileParameterDouble1TSWTI "$this->decrRef();" -%feature("unref") MEDFileParameterDouble1TS "$this->decrRef();" -%feature("unref") MEDFileParameterMultiTS "$this->decrRef();" -%feature("unref") MEDFileParameters "$this->decrRef();" -%feature("unref") MEDFileJointCorrespondence "$this->decrRef();" -%feature("unref") MEDFileJointOneStep "$this->decrRef();" -%feature("unref") MEDFileJoint "$this->decrRef();" -%feature("unref") MEDFileJoints "$this->decrRef();" -%feature("unref") MEDFileData "$this->decrRef();" -%feature("unref") SauvReader "$this->decrRef();" -%feature("unref") SauvWriter "$this->decrRef();" -%feature("unref") MEDFileFastCellSupportComparator "$this->decrRef();" -%feature("unref") MEDMeshMultiLev "$this->decrRef();" -%feature("unref") MEDUMeshMultiLev "$this->decrRef();" -%feature("unref") MEDCMeshMultiLev "$this->decrRef();" -%feature("unref") MEDCurveLinearMeshMultiLev "$this->decrRef();" -%feature("unref") MEDFileMeshStruct "$this->decrRef();" - -class MEDLoader -{ -public: - static bool HasXDR(); - static std::string MEDFileVersionStr(); - static void SetEpsilonForNodeComp(double val) throw(INTERP_KERNEL::Exception); - static void SetCompPolicyForCell(int val) throw(INTERP_KERNEL::Exception); - static void SetTooLongStrPolicy(int val) throw(INTERP_KERNEL::Exception); - static void CheckFileForRead(const std::string& fileName) throw(INTERP_KERNEL::Exception); - static std::vector<std::string> GetMeshNames(const std::string& fileName) throw(INTERP_KERNEL::Exception); - static std::vector<std::string> GetMeshNamesOnField(const std::string& fileName, const std::string& fieldName) throw(INTERP_KERNEL::Exception); - static std::vector<std::string> GetMeshGroupsNames(const std::string& fileName, const std::string& meshName) throw(INTERP_KERNEL::Exception); - static std::vector<std::string> GetMeshFamiliesNames(const std::string& fileName, const std::string& meshName) throw(INTERP_KERNEL::Exception); - static std::vector<std::string> GetMeshFamiliesNamesOnGroup(const std::string& fileName, const std::string& meshName, const std::string& grpName) throw(INTERP_KERNEL::Exception); - static std::vector<std::string> GetMeshGroupsNamesOnFamily(const std::string& fileName, const std::string& meshName, const std::string& famName) throw(INTERP_KERNEL::Exception); - static std::vector<std::string> GetAllFieldNamesOnMesh(const std::string& fileName, const std::string& meshName) throw(INTERP_KERNEL::Exception); - static std::vector<std::string> GetAllFieldNames(const std::string& fileName) throw(INTERP_KERNEL::Exception); - static std::vector<std::string> GetFieldNamesOnMesh(ParaMEDMEM::TypeOfField type, const std::string& fileName, const std::string& meshName) throw(INTERP_KERNEL::Exception); - static std::vector<std::string> GetCellFieldNamesOnMesh(const std::string& fileName, const std::string& meshName) throw(INTERP_KERNEL::Exception); - static std::vector<std::string> GetNodeFieldNamesOnMesh(const std::string& fileName, const std::string& meshName) throw(INTERP_KERNEL::Exception); - static double GetTimeAttachedOnFieldIteration(const std::string& fileName, const std::string& fieldName, int iteration, int order) throw(INTERP_KERNEL::Exception); - static void AssignStaticWritePropertiesTo(ParaMEDMEM::MEDFileWritable& obj) throw(INTERP_KERNEL::Exception); - %extend - { - static PyObject *MEDFileVersion() - { - int major,minor,release; - MEDLoader::MEDFileVersion(major,minor,release); - PyObject *ret(PyTuple_New(3)); - PyTuple_SetItem(ret,0,SWIG_From_int(major)); - PyTuple_SetItem(ret,1,SWIG_From_int(minor)); - PyTuple_SetItem(ret,2,SWIG_From_int(release)); - return ret; - } - - static PyObject *GetFieldIterations(ParaMEDMEM::TypeOfField type, const std::string& fileName, const std::string& meshName, const std::string& fieldName) throw(INTERP_KERNEL::Exception) - { - std::vector< std::pair<int,int> > res=MEDLoader::GetFieldIterations(type,fileName,meshName,fieldName); - PyObject *ret=PyList_New(res.size()); - int rk=0; - for(std::vector< std::pair<int,int> >::const_iterator iter=res.begin();iter!=res.end();iter++,rk++) - { - PyObject *elt=PyTuple_New(2); - PyTuple_SetItem(elt,0,SWIG_From_int((*iter).first)); - PyTuple_SetItem(elt,1,SWIG_From_int((*iter).second)); - PyList_SetItem(ret,rk,elt); - } - return ret; - } - - static PyObject *GetAllFieldIterations(const std::string& fileName, const std::string& fieldName) throw(INTERP_KERNEL::Exception) - { - std::vector< std::pair< std::pair<int,int>, double> > res=MEDLoader::GetAllFieldIterations(fileName,fieldName); - PyObject *ret=PyList_New(res.size()); - int rk=0; - for(std::vector< std::pair< std::pair<int,int>, double> >::const_iterator iter=res.begin();iter!=res.end();iter++,rk++) - { - PyObject *elt=PyTuple_New(3); - PyTuple_SetItem(elt,0,SWIG_From_int((*iter).first.first)); - PyTuple_SetItem(elt,1,SWIG_From_int((*iter).first.second)); - PyTuple_SetItem(elt,2,SWIG_From_double((*iter).second)); - PyList_SetItem(ret,rk,elt); - } - return ret; - } - - static PyObject *GetCellFieldIterations(const std::string& fileName, const std::string& meshName, const std::string& fieldName) throw(INTERP_KERNEL::Exception) - { - std::vector< std::pair<int,int> > res=MEDLoader::GetCellFieldIterations(fileName,meshName,fieldName); - PyObject *ret=PyList_New(res.size()); - int rk=0; - for(std::vector< std::pair<int,int> >::const_iterator iter=res.begin();iter!=res.end();iter++,rk++) - { - PyObject *elt=PyTuple_New(2); - PyTuple_SetItem(elt,0,SWIG_From_int((*iter).first)); - PyTuple_SetItem(elt,1,SWIG_From_int((*iter).second)); - PyList_SetItem(ret,rk,elt); - } - return ret; - } - static PyObject *GetNodeFieldIterations(const std::string& fileName, const std::string& meshName, const std::string& fieldName) throw(INTERP_KERNEL::Exception) - { - std::vector< std::pair<int,int> > res=MEDLoader::GetNodeFieldIterations(fileName,meshName,fieldName); - PyObject *ret=PyList_New(res.size()); - int rk=0; - for(std::vector< std::pair<int,int> >::const_iterator iter=res.begin();iter!=res.end();iter++,rk++) - { - PyObject *elt=PyTuple_New(2); - PyTuple_SetItem(elt,0,SWIG_From_int((*iter).first)); - PyTuple_SetItem(elt,1,SWIG_From_int((*iter).second)); - PyList_SetItem(ret,rk,elt); - } - return ret; - } - static PyObject *GetComponentsNamesOfField(const std::string& fileName, const std::string& fieldName) throw(INTERP_KERNEL::Exception) - { - std::vector< std::pair<std::string,std::string> > res=MEDLoader::GetComponentsNamesOfField(fileName,fieldName); - PyObject *ret=PyList_New(res.size()); - int rk=0; - for(std::vector< std::pair<std::string,std::string> >::const_iterator iter=res.begin();iter!=res.end();iter++,rk++) - { - PyObject *elt=PyTuple_New(2); - PyTuple_SetItem(elt,0,PyString_FromString((*iter).first.c_str())); - PyTuple_SetItem(elt,1,PyString_FromString((*iter).second.c_str())); - PyList_SetItem(ret,rk,elt); - } - return ret; - } - static PyObject *GetUMeshGlobalInfo(const std::string& fileName, const std::string& meshName) throw(INTERP_KERNEL::Exception) - { - int meshDim,spaceDim,numberOfNodes; - std::vector< std::vector< std::pair<INTERP_KERNEL::NormalizedCellType,int> > > res=MEDLoader::GetUMeshGlobalInfo(fileName,meshName,meshDim,spaceDim,numberOfNodes); - PyObject *ret=PyTuple_New(4); - PyObject *elt0=PyList_New(res.size()); - int i=0; - for(std::vector< std::vector< std::pair<INTERP_KERNEL::NormalizedCellType,int> > >::const_iterator it=res.begin();it!=res.end();it++,i++) - { - const std::vector< std::pair<INTERP_KERNEL::NormalizedCellType,int> >&obj2=(*it); - int j=0; - PyObject *elt1=PyList_New(obj2.size()); - for(std::vector< std::pair<INTERP_KERNEL::NormalizedCellType,int> >::const_iterator it2=obj2.begin();it2!=obj2.end();it2++,j++) - { - PyObject *elt2=PyTuple_New(2); - PyTuple_SetItem(elt2,0,SWIG_From_int((int)(*it2).first)); - PyTuple_SetItem(elt2,1,SWIG_From_int((*it2).second)); - PyList_SetItem(elt1,j,elt2); - } - PyList_SetItem(elt0,i,elt1); - } - PyTuple_SetItem(ret,0,elt0); - PyTuple_SetItem(ret,1,SWIG_From_int(meshDim)); - PyTuple_SetItem(ret,2,SWIG_From_int(spaceDim)); - PyTuple_SetItem(ret,3,SWIG_From_int(numberOfNodes)); - return ret; - } - static PyObject *ReadFieldsOnSameMesh(ParaMEDMEM::TypeOfField type, const std::string& fileName, const std::string& meshName, int meshDimRelToMax, - const std::string& fieldName, PyObject *liIts) throw(INTERP_KERNEL::Exception) - { - std::vector<std::pair<int,int> > its=convertTimePairIdsFromPy(liIts); - std::vector<ParaMEDMEM::MEDCouplingFieldDouble *> res=MEDLoader::ReadFieldsOnSameMesh(type,fileName,meshName,meshDimRelToMax,fieldName,its); - return convertFieldDoubleVecToPy(res); - } - static void WriteUMeshesPartition(const std::string& fileName, const std::string& meshName, PyObject *li, bool writeFromScratch) throw(INTERP_KERNEL::Exception) - { - std::vector<const ParaMEDMEM::MEDCouplingUMesh *> v; - convertFromPyObjVectorOfObj<const ParaMEDMEM::MEDCouplingUMesh *>(li,SWIGTYPE_p_ParaMEDMEM__MEDCouplingUMesh,"MEDCouplingUMesh",v); - MEDLoader::WriteUMeshesPartition(fileName,meshName,v,writeFromScratch); - } - static void WriteUMeshesPartitionDep(const std::string& fileName, const std::string& meshName, PyObject *li, bool writeFromScratch) throw(INTERP_KERNEL::Exception) - { - std::vector<const ParaMEDMEM::MEDCouplingUMesh *> v; - convertFromPyObjVectorOfObj<const ParaMEDMEM::MEDCouplingUMesh *>(li,SWIGTYPE_p_ParaMEDMEM__MEDCouplingUMesh,"MEDCouplingUMesh",v); - MEDLoader::WriteUMeshesPartitionDep(fileName,meshName,v,writeFromScratch); - } - static void WriteUMeshes(const std::string& fileName, PyObject *li, bool writeFromScratch) throw(INTERP_KERNEL::Exception) - { - std::vector<const ParaMEDMEM::MEDCouplingUMesh *> v; - convertFromPyObjVectorOfObj<const ParaMEDMEM::MEDCouplingUMesh *>(li,SWIGTYPE_p_ParaMEDMEM__MEDCouplingUMesh,"MEDCouplingUMesh",v); - MEDLoader::WriteUMeshes(fileName,v,writeFromScratch); - } - static PyObject *GetTypesOfField(const std::string& fileName, const std::string& meshName, const std::string& fieldName) throw(INTERP_KERNEL::Exception) - { - std::vector< ParaMEDMEM::TypeOfField > v=MEDLoader::GetTypesOfField(fileName,meshName,fieldName); - int size=v.size(); - PyObject *ret=PyList_New(size); - for(int i=0;i<size;i++) - PyList_SetItem(ret,i,PyInt_FromLong((int)v[i])); - return ret; - } - static ParaMEDMEM::MEDCouplingUMesh *ReadUMeshFromGroups(const std::string& fileName, const std::string& meshName, int meshDimRelToMax, PyObject *li) throw(INTERP_KERNEL::Exception) - { - std::vector<std::string> grps; - converPyListToVecString(li,grps); - return MEDLoader::ReadUMeshFromGroups(fileName,meshName,meshDimRelToMax,grps); - } - static ParaMEDMEM::MEDCouplingUMesh *ReadUMeshFromFamilies(const std::string& fileName, const std::string& meshName, int meshDimRelToMax, PyObject *li) throw(INTERP_KERNEL::Exception) - { - std::vector<std::string> fams; - converPyListToVecString(li,fams); - return MEDLoader::ReadUMeshFromFamilies(fileName,meshName,meshDimRelToMax,fams); - } - } - static ParaMEDMEM::MEDCouplingMesh *ReadMeshFromFile(const std::string& fileName, const std::string& meshName, int meshDimRelToMax=0) throw(INTERP_KERNEL::Exception); - static ParaMEDMEM::MEDCouplingMesh *ReadMeshFromFile(const std::string& fileName, int meshDimRelToMax=0) throw(INTERP_KERNEL::Exception); - static ParaMEDMEM::MEDCouplingUMesh *ReadUMeshFromFile(const std::string& fileName, const std::string& meshName, int meshDimRelToMax=0) throw(INTERP_KERNEL::Exception); - static ParaMEDMEM::MEDCouplingUMesh *ReadUMeshFromFile(const std::string& fileName, int meshDimRelToMax=0) throw(INTERP_KERNEL::Exception); - static int ReadUMeshDimFromFile(const std::string& fileName, const std::string& meshName) throw(INTERP_KERNEL::Exception); - static ParaMEDMEM::MEDCouplingFieldDouble *ReadField(ParaMEDMEM::TypeOfField type, const std::string& fileName, const std::string& meshName, int meshDimRelToMax, const std::string& fieldName, int iteration, int order) throw(INTERP_KERNEL::Exception); - static ParaMEDMEM::MEDCouplingFieldDouble *ReadFieldCell(const std::string& fileName, const std::string& meshName, int meshDimRelToMax, const std::string& fieldName, int iteration, int order) throw(INTERP_KERNEL::Exception); - static ParaMEDMEM::MEDCouplingFieldDouble *ReadFieldNode(const std::string& fileName, const std::string& meshName, int meshDimRelToMax, const std::string& fieldName, int iteration, int order) throw(INTERP_KERNEL::Exception); - static ParaMEDMEM::MEDCouplingFieldDouble *ReadFieldGauss(const std::string& fileName, const std::string& meshName, int meshDimRelToMax, const std::string& fieldName, int iteration, int order) throw(INTERP_KERNEL::Exception); - static ParaMEDMEM::MEDCouplingFieldDouble *ReadFieldGaussNE(const std::string& fileName, const std::string& meshName, int meshDimRelToMax, const std::string& fieldName, int iteration, int order) throw(INTERP_KERNEL::Exception); - static void WriteMesh(const std::string& fileName, const ParaMEDMEM::MEDCouplingMesh *mesh, bool writeFromScratch) throw(INTERP_KERNEL::Exception); - static void WriteUMesh(const std::string& fileName, const ParaMEDMEM::MEDCouplingUMesh *mesh, bool writeFromScratch) throw(INTERP_KERNEL::Exception); - static void WriteUMeshDep(const std::string& fileName, const ParaMEDMEM::MEDCouplingUMesh *mesh, bool writeFromScratch) throw(INTERP_KERNEL::Exception); - static void WriteField(const std::string& fileName, const ParaMEDMEM::MEDCouplingFieldDouble *f, bool writeFromScratch) throw(INTERP_KERNEL::Exception); - static void WriteFieldDep(const std::string& fileName, const ParaMEDMEM::MEDCouplingFieldDouble *f, bool writeFromScratch) throw(INTERP_KERNEL::Exception); - static void WriteFieldUsingAlreadyWrittenMesh(const std::string& fileName, const ParaMEDMEM::MEDCouplingFieldDouble *f) throw(INTERP_KERNEL::Exception); -}; - -namespace ParaMEDMEM -{ - class MEDFileWritable - { - public: - void copyOptionsFrom(const MEDFileWritable& other) const; - int getTooLongStrPolicy() const throw(INTERP_KERNEL::Exception); - void setTooLongStrPolicy(int newVal) throw(INTERP_KERNEL::Exception); - int getZipConnPolicy() throw(INTERP_KERNEL::Exception); - void setZipConnPolicy(int newVal) throw(INTERP_KERNEL::Exception); - }; - - class MEDFileMeshReadSelector - { - public: - MEDFileMeshReadSelector(); - MEDFileMeshReadSelector(unsigned int code); - unsigned int getCode() const; - void setCode(unsigned int newCode); - bool isCellFamilyFieldReading() const; - bool isNodeFamilyFieldReading() const; - bool isCellNameFieldReading() const; - bool isNodeNameFieldReading() const; - bool isCellNumFieldReading() const; - bool isNodeNumFieldReading() const; - void setCellFamilyFieldReading(bool b); - void setNodeFamilyFieldReading(bool b); - void setCellNameFieldReading(bool b); - void setNodeNameFieldReading(bool b); - void setCellNumFieldReading(bool b); - void setNodeNumFieldReading(bool b); - %extend - { - std::string __str__() const throw(INTERP_KERNEL::Exception) - { - std::ostringstream oss; - self->reprAll(oss); - return oss.str(); - } - - std::string __repr__() const throw(INTERP_KERNEL::Exception) - { - std::ostringstream oss; oss << "MEDFileMeshReadSelector C++ instance at " << self << " (with code=" << self->getCode() << ")."; - return oss.str(); - } - } - }; - class MEDFileJointCorrespondence : public RefCountObject, public MEDFileWritable - { - public: - static MEDFileJointCorrespondence *New() throw(INTERP_KERNEL::Exception); - static MEDFileJointCorrespondence *New(DataArrayInt* correspondence) // nodes - throw(INTERP_KERNEL::Exception); - static MEDFileJointCorrespondence *New(DataArrayInt* correspondence, // cells - INTERP_KERNEL::NormalizedCellType loc_geo_type, - INTERP_KERNEL::NormalizedCellType rem_geo_type) - throw(INTERP_KERNEL::Exception); - std::vector<const BigMemoryObject *> getDirectChildrenWithNull() const; - MEDFileJointCorrespondence *deepCpy() const; - MEDFileJointCorrespondence *shallowCpy() const; - void setIsNodal(bool isNodal); - bool getIsNodal() const; - bool isEqual(const MEDFileJointCorrespondence *other) const; - void setLocalGeometryType(INTERP_KERNEL::NormalizedCellType type); - INTERP_KERNEL::NormalizedCellType getLocalGeometryType() const; - void setRemoteGeometryType(INTERP_KERNEL::NormalizedCellType type); - INTERP_KERNEL::NormalizedCellType getRemoteGeometryType() const; - void setCorrespondence(DataArrayInt *corr) throw(INTERP_KERNEL::Exception); - const DataArrayInt *getCorrespondence() const throw(INTERP_KERNEL::Exception); - void write(const std::string& fileName, int mode, const std::string& localMeshName, const std::string& jointName, int order, int iteration) const throw(INTERP_KERNEL::Exception); - std::string simpleRepr() const throw(INTERP_KERNEL::Exception); - %extend - { - MEDFileJointCorrespondence() - { - return MEDFileJointCorrespondence::New(); - } - MEDFileJointCorrespondence(DataArrayInt* correspondence) throw(INTERP_KERNEL::Exception) - { - return MEDFileJointCorrespondence::New(correspondence); - } - MEDFileJointCorrespondence(DataArrayInt* correspondence, // cells - INTERP_KERNEL::NormalizedCellType loc_geo_type, - INTERP_KERNEL::NormalizedCellType rem_geo_type) throw(INTERP_KERNEL::Exception) - { - return MEDFileJointCorrespondence::New(correspondence, loc_geo_type, rem_geo_type); - } - - std::string __str__() const throw(INTERP_KERNEL::Exception) - { - return self->simpleRepr(); - } - } - }; - - class MEDFileJointOneStep : public RefCountObject, public MEDFileWritable - { - public: - static MEDFileJointOneStep *New(int dt=-1, int it=-1) throw(INTERP_KERNEL::Exception); - static MEDFileJointOneStep *New(const std::string& fileName, const std::string& mName, const std::string& jointName, int number=1) throw(INTERP_KERNEL::Exception); - MEDFileJointOneStep *deepCpy() const; - MEDFileJointOneStep *shallowCpy() const; - bool isEqual(const MEDFileJointOneStep *other) const; - void setOrder(int order); - int getOrder() const; - void setIteration(int it); - int getIteration() const; - void pushCorrespondence(MEDFileJointCorrespondence* correspondence); - int getNumberOfCorrespondences() const; - MEDFileJointCorrespondence *getCorrespondenceAtPos(int i) const; - void write(const std::string& fileName, int mode, const std::string& localMeshName, const std::string& jointName) const throw(INTERP_KERNEL::Exception); - std::string simpleRepr() const throw(INTERP_KERNEL::Exception); - %extend - { - MEDFileJointOneStep() - { - return MEDFileJointOneStep::New(); - } - - MEDFileJointOneStep(const std::string& fileName, const std::string& mName, const std::string& jointName, int number) throw(INTERP_KERNEL::Exception) - { - return MEDFileJointOneStep::New(fileName,mName,jointName,number); - } - - std::string __str__() const throw(INTERP_KERNEL::Exception) - { - return self->simpleRepr(); - } - } - }; - class MEDFileJoint : public RefCountObject, public MEDFileWritable - { - public: - static MEDFileJoint *New() throw(INTERP_KERNEL::Exception); - static MEDFileJoint *New(const std::string& fileName, const std::string& mName, int num) throw(INTERP_KERNEL::Exception); - static MEDFileJoint *New(const std::string& jointName, const std::string& locMeshName, const std::string& remoteMeshName, int remoteMeshNum ) throw(INTERP_KERNEL::Exception); - MEDFileJoint *deepCpy() const; - MEDFileJoint *shallowCpy() const; - bool isEqual(const MEDFileJoint *other) const; - void setLocalMeshName(const std::string& name); - std::string getLocalMeshName() const; - void setRemoteMeshName(const std::string& name); - std::string getRemoteMeshName() const; - void setDescription(const std::string& name); - std::string getDescription() const; - void setJointName(const std::string& name); - std::string getJointName() const; - bool changeJointNames(const std::vector< std::pair<std::string,std::string> >& modifTab) throw(INTERP_KERNEL::Exception); - void setDomainNumber(const int& number); - int getDomainNumber() const; - void pushStep(MEDFileJointOneStep* step); - int getNumberOfSteps() const; - MEDFileJointOneStep *getStepAtPos(int i) const; - void write(const std::string& fileName, int mode) const throw(INTERP_KERNEL::Exception); - std::string simpleRepr() const; - %extend - { - MEDFileJoint() - { - return MEDFileJoint::New(); - } - - MEDFileJoint(const std::string& fileName, const std::string& mName, int num) throw(INTERP_KERNEL::Exception) - { - return MEDFileJoint::New(fileName,mName,num); - } - - std::string __str__() const throw(INTERP_KERNEL::Exception) - { - return self->simpleRepr(); - } - } - }; - - class MEDFileJoints : public RefCountObject, public MEDFileWritable - { - public: - static MEDFileJoints *New() throw(INTERP_KERNEL::Exception); - static MEDFileJoints *New(const std::string& fileName, const std::string& meshName) throw(INTERP_KERNEL::Exception); - MEDFileJoints *deepCpy() const; - std::string simpleRepr() const; - void write(const std::string& fileName, int mode) const throw(INTERP_KERNEL::Exception); - std::string getMeshName() const; - int getNumberOfJoints() const; - std::vector<std::string> getJointsNames() const; - bool changeJointNames(const std::vector< std::pair<std::string,std::string> >& modifTab) throw(INTERP_KERNEL::Exception); - void resize(int newSize) throw(INTERP_KERNEL::Exception); - void pushJoint(MEDFileJoint *joint); - void setJointAtPos(int i, MEDFileJoint *joint) throw(INTERP_KERNEL::Exception); - void destroyJointAtPos(int i) throw(INTERP_KERNEL::Exception); - %extend - { - MEDFileJoints() - { - return MEDFileJoints::New(); - } - - MEDFileJoints(const std::string& fileName, const std::string& meshName) throw(INTERP_KERNEL::Exception) - { - return MEDFileJoints::New(fileName,meshName); - } - - std::string __str__() const throw(INTERP_KERNEL::Exception) - { - return self->simpleRepr(); - } - - MEDFileJoint *__getitem__(PyObject *obj) throw(INTERP_KERNEL::Exception) - { - if(PyInt_Check(obj)) - { - MEDFileJoint *ret=self->getJointAtPos(InterpreteNegativeInt((int)PyInt_AS_LONG(obj),self->getNumberOfJoints())); - if(ret) - ret->incrRef(); - return ret; - } - else if(PyString_Check(obj)) - { - MEDFileJoint *ret=self->getJointWithName(PyString_AsString(obj)); - if(ret) - ret->incrRef(); - return ret; - } - else - throw INTERP_KERNEL::Exception("MEDFileJoints::__getitem__ : only integer or string with meshname supported !"); - } - - int __len__() const throw(INTERP_KERNEL::Exception) - { - return self->getNumberOfJoints(); - } - - MEDFileJoint *getJointAtPos(int i) const throw(INTERP_KERNEL::Exception) - { - MEDFileJoint *ret=self->getJointAtPos(i); - if(ret) - ret->incrRef(); - return ret; - } - - MEDFileJoint *getJointWithName(const std::string& paramName) const throw(INTERP_KERNEL::Exception) - { - MEDFileJoint *ret=self->getJointWithName(paramName); - if(ret) - ret->incrRef(); - return ret; - } - } - }; - - class MEDFileMesh : public RefCountObject, public MEDFileWritable - { - public: - static MEDFileMesh *New(const std::string& fileName, MEDFileMeshReadSelector *mrs=0) throw(INTERP_KERNEL::Exception); - static MEDFileMesh *New(const std::string& fileName, const std::string& mName, int dt=-1, int it=-1, MEDFileMeshReadSelector *mrs=0) throw(INTERP_KERNEL::Exception); - virtual MEDFileMesh *createNewEmpty() const throw(INTERP_KERNEL::Exception); - virtual MEDFileMesh *deepCpy() const throw(INTERP_KERNEL::Exception); - virtual MEDFileMesh *shallowCpy() const throw(INTERP_KERNEL::Exception); - virtual void clearNonDiscrAttributes() const throw(INTERP_KERNEL::Exception); - void setName(const std::string& name); - std::string getName(); - std::string getUnivName() const; - bool getUnivNameWrStatus() const; - void setUnivNameWrStatus(bool newStatus); - void setDescription(const std::string& name); - std::string getDescription() const; - void setOrder(int order); - int getOrder() const; - void setIteration(int it); - int getIteration(); - void setTimeValue(double time); - void setTime(int dt, int it, double time); - double getTimeValue() const; - void setTimeUnit(const std::string& unit); - std::string getTimeUnit() const; - virtual int getNumberOfNodes() const throw(INTERP_KERNEL::Exception); - virtual int getNumberOfCellsAtLevel(int meshDimRelToMaxExt) const throw(INTERP_KERNEL::Exception); - virtual bool hasImplicitPart() const throw(INTERP_KERNEL::Exception); - virtual int buildImplicitPartIfAny(INTERP_KERNEL::NormalizedCellType gt) const throw(INTERP_KERNEL::Exception); - virtual void releaseImplicitPartIfAny() const throw(INTERP_KERNEL::Exception); - virtual std::vector<int> getFamArrNonEmptyLevelsExt() const throw(INTERP_KERNEL::Exception); - virtual std::vector<int> getNumArrNonEmptyLevelsExt() const throw(INTERP_KERNEL::Exception); - virtual std::vector<int> getNameArrNonEmptyLevelsExt() const throw(INTERP_KERNEL::Exception); - virtual std::vector<int> getDistributionOfTypes(int meshDimRelToMax) const throw(INTERP_KERNEL::Exception); - std::vector<int> getNonEmptyLevels() const throw(INTERP_KERNEL::Exception); - std::vector<int> getNonEmptyLevelsExt() const throw(INTERP_KERNEL::Exception); - void write(const std::string& fileName, int mode) const throw(INTERP_KERNEL::Exception); - int getSizeAtLevel(int meshDimRelToMaxExt) const throw(INTERP_KERNEL::Exception); - // - bool existsGroup(const std::string& groupName) const throw(INTERP_KERNEL::Exception); - bool existsFamily(int famId) const throw(INTERP_KERNEL::Exception); - bool existsFamily(const std::string& familyName) const throw(INTERP_KERNEL::Exception); - void setFamilyId(const std::string& familyName, int id) throw(INTERP_KERNEL::Exception); - void setFamilyIdUnique(const std::string& familyName, int id) throw(INTERP_KERNEL::Exception); - void addFamily(const std::string& familyName, int id) throw(INTERP_KERNEL::Exception); - void addFamilyOnGrp(const std::string& grpName, const std::string& famName) throw(INTERP_KERNEL::Exception); - virtual void createGroupOnAll(int meshDimRelToMaxExt, const std::string& groupName) throw(INTERP_KERNEL::Exception); - virtual bool keepFamIdsOnlyOnLevs(const std::vector<int>& famIds, const std::vector<int>& levs) throw(INTERP_KERNEL::Exception); - void copyFamGrpMapsFrom(const MEDFileMesh& other) throw(INTERP_KERNEL::Exception); - void clearGrpMap() throw(INTERP_KERNEL::Exception); - void clearFamMap() throw(INTERP_KERNEL::Exception); - void clearFamGrpMaps() throw(INTERP_KERNEL::Exception); - const std::map<std::string,int>& getFamilyInfo() const throw(INTERP_KERNEL::Exception); - const std::map<std::string, std::vector<std::string> >& getGroupInfo() const throw(INTERP_KERNEL::Exception); - std::vector<std::string> getFamiliesOnGroup(const std::string& name) const throw(INTERP_KERNEL::Exception); - std::vector<std::string> getFamiliesOnGroups(const std::vector<std::string>& grps) const throw(INTERP_KERNEL::Exception); - std::vector<int> getFamiliesIdsOnGroup(const std::string& name) const throw(INTERP_KERNEL::Exception); - void setFamiliesOnGroup(const std::string& name, const std::vector<std::string>& fams) throw(INTERP_KERNEL::Exception); - void setFamiliesIdsOnGroup(const std::string& name, const std::vector<int>& famIds) throw(INTERP_KERNEL::Exception); - std::vector<std::string> getGroupsOnFamily(const std::string& name) const throw(INTERP_KERNEL::Exception); - void setGroupsOnFamily(const std::string& famName, const std::vector<std::string>& grps) throw(INTERP_KERNEL::Exception); - std::vector<std::string> getGroupsNames() const throw(INTERP_KERNEL::Exception); - std::vector<std::string> getFamiliesNames() const throw(INTERP_KERNEL::Exception); - void assignFamilyNameWithGroupName() throw(INTERP_KERNEL::Exception); - std::vector<std::string> removeEmptyGroups() throw(INTERP_KERNEL::Exception); - void removeGroup(const std::string& name) throw(INTERP_KERNEL::Exception); - void removeFamily(const std::string& name) throw(INTERP_KERNEL::Exception); - std::vector<std::string> removeOrphanGroups() throw(INTERP_KERNEL::Exception); - std::vector<std::string> removeOrphanFamilies() throw(INTERP_KERNEL::Exception); - void removeFamiliesReferedByNoGroups() throw(INTERP_KERNEL::Exception); - void rearrangeFamilies() throw(INTERP_KERNEL::Exception); - void checkOrphanFamilyZero() const throw(INTERP_KERNEL::Exception); - void changeGroupName(const std::string& oldName, const std::string& newName) throw(INTERP_KERNEL::Exception); - void changeFamilyName(const std::string& oldName, const std::string& newName) throw(INTERP_KERNEL::Exception); - void changeFamilyId(int oldId, int newId) throw(INTERP_KERNEL::Exception); - void changeAllGroupsContainingFamily(const std::string& familyNameToChange, const std::vector<std::string>& newFamiliesNames) throw(INTERP_KERNEL::Exception); - void setFamilyInfo(const std::map<std::string,int>& info); - void setGroupInfo(const std::map<std::string, std::vector<std::string> >&info); - int getFamilyId(const std::string& name) const throw(INTERP_KERNEL::Exception); - int getMaxAbsFamilyId() const throw(INTERP_KERNEL::Exception); - int getMaxFamilyId() const throw(INTERP_KERNEL::Exception); - int getMinFamilyId() const throw(INTERP_KERNEL::Exception); - int getTheMaxAbsFamilyId() const throw(INTERP_KERNEL::Exception); - int getTheMaxFamilyId() const throw(INTERP_KERNEL::Exception); - int getTheMinFamilyId() const throw(INTERP_KERNEL::Exception); - virtual int getMaxAbsFamilyIdInArrays() const throw(INTERP_KERNEL::Exception); - virtual int getMaxFamilyIdInArrays() const throw(INTERP_KERNEL::Exception); - virtual int getMinFamilyIdInArrays() const throw(INTERP_KERNEL::Exception); - DataArrayInt *getAllFamiliesIdsReferenced() const throw(INTERP_KERNEL::Exception); - DataArrayInt *computeAllFamilyIdsInUse() const throw(INTERP_KERNEL::Exception); - std::vector<int> getFamiliesIds(const std::vector<std::string>& famNames) const throw(INTERP_KERNEL::Exception); - std::string getFamilyNameGivenId(int id) const throw(INTERP_KERNEL::Exception); - bool ensureDifferentFamIdsPerLevel() throw(INTERP_KERNEL::Exception); - void normalizeFamIdsTrio() throw(INTERP_KERNEL::Exception); - void normalizeFamIdsMEDFile() throw(INTERP_KERNEL::Exception); - virtual int getMeshDimension() const throw(INTERP_KERNEL::Exception); - virtual std::string simpleRepr() const throw(INTERP_KERNEL::Exception); - virtual std::string advancedRepr() const throw(INTERP_KERNEL::Exception); - // - virtual MEDCouplingMesh *getGenMeshAtLevel(int meshDimRelToMax, bool renum=false) const throw(INTERP_KERNEL::Exception); - virtual void setFamilyFieldArr(int meshDimRelToMaxExt, DataArrayInt *famArr) throw(INTERP_KERNEL::Exception); - virtual void setRenumFieldArr(int meshDimRelToMaxExt, DataArrayInt *renumArr) throw(INTERP_KERNEL::Exception); - virtual void setNameFieldAtLevel(int meshDimRelToMaxExt, DataArrayAsciiChar *nameArr) throw(INTERP_KERNEL::Exception); - virtual void addNodeGroup(const DataArrayInt *ids) throw(INTERP_KERNEL::Exception); - virtual void addGroup(int meshDimRelToMaxExt, const DataArrayInt *ids) throw(INTERP_KERNEL::Exception); - virtual DataArrayInt *getFamiliesArr(int meshDimRelToMaxExt, const std::vector<std::string>& fams, bool renum=false) const throw(INTERP_KERNEL::Exception); - virtual DataArrayInt *getGroupsArr(int meshDimRelToMaxExt, const std::vector<std::string>& grps, bool renum=false) const throw(INTERP_KERNEL::Exception); - virtual DataArrayInt *getGroupArr(int meshDimRelToMaxExt, const std::string& grp, bool renum=false) const throw(INTERP_KERNEL::Exception); - virtual DataArrayInt *getFamilyArr(int meshDimRelToMaxExt, const std::string& fam, bool renum=false) const throw(INTERP_KERNEL::Exception); - virtual DataArrayInt *getNodeGroupArr(const std::string& grp, bool renum=false) const throw(INTERP_KERNEL::Exception); - virtual DataArrayInt *getNodeGroupsArr(const std::vector<std::string>& grps, bool renum=false) const throw(INTERP_KERNEL::Exception); - virtual DataArrayInt *getNodeFamilyArr(const std::string& fam, bool renum=false) const throw(INTERP_KERNEL::Exception); - virtual DataArrayInt *getNodeFamiliesArr(const std::vector<std::string>& fams, bool renum=false) const throw(INTERP_KERNEL::Exception); - int getNumberOfJoints(); - MEDFileJoints *getJoints(); - void setJoints( MEDFileJoints* joints ); - %extend - { - std::string __str__() const throw(INTERP_KERNEL::Exception) - { - return self->simpleRepr(); - } - - MEDCouplingMesh *__getitem__(int meshDimRelToMaxExt) const throw(INTERP_KERNEL::Exception) - { - return self->getGenMeshAtLevel(meshDimRelToMaxExt,false); - } - - PyObject *getTime() throw(INTERP_KERNEL::Exception) - { - int tmp1,tmp2; - double tmp0=self->getTime(tmp1,tmp2); - PyObject *res = PyList_New(3); - PyList_SetItem(res,0,SWIG_From_int(tmp1)); - PyList_SetItem(res,1,SWIG_From_int(tmp2)); - PyList_SetItem(res,2,SWIG_From_double(tmp0)); - return res; - } - - virtual PyObject *isEqual(const MEDFileMesh *other, double eps) const throw(INTERP_KERNEL::Exception) - { - std::string what; - bool ret0=self->isEqual(other,eps,what); - PyObject *res=PyList_New(2); - PyObject *ret0Py=ret0?Py_True:Py_False; - Py_XINCREF(ret0Py); - PyList_SetItem(res,0,ret0Py); - PyList_SetItem(res,1,PyString_FromString(what.c_str())); - return res; - } - - void setGroupsAtLevel(int meshDimRelToMaxExt, PyObject *li, bool renum=false) throw(INTERP_KERNEL::Exception) - { - std::vector<const DataArrayInt *> grps; - convertFromPyObjVectorOfObj<const ParaMEDMEM::DataArrayInt *>(li,SWIGTYPE_p_ParaMEDMEM__DataArrayInt,"DataArrayInt",grps); - self->setGroupsAtLevel(meshDimRelToMaxExt,grps,renum); - } - - PyObject *areFamsEqual(const MEDFileMesh *other) const throw(INTERP_KERNEL::Exception) - { - std::string what; - bool ret0=self->areFamsEqual(other,what); - PyObject *res=PyList_New(2); - PyObject *ret0Py=ret0?Py_True:Py_False; - Py_XINCREF(ret0Py); - PyList_SetItem(res,0,ret0Py); - PyList_SetItem(res,1,PyString_FromString(what.c_str())); - return res; - } - - PyObject *areGrpsEqual(const MEDFileMesh *other) const throw(INTERP_KERNEL::Exception) - { - std::string what; - bool ret0=self->areGrpsEqual(other,what); - PyObject *res=PyList_New(2); - PyObject *ret0Py=ret0?Py_True:Py_False; - Py_XINCREF(ret0Py); - PyList_SetItem(res,0,ret0Py); - PyList_SetItem(res,1,PyString_FromString(what.c_str())); - return res; - } - - PyObject *getAllGeoTypes() const throw(INTERP_KERNEL::Exception) - { - std::vector<INTERP_KERNEL::NormalizedCellType> result(self->getAllGeoTypes()); - std::vector<INTERP_KERNEL::NormalizedCellType>::const_iterator iL=result.begin(); - PyObject *res=PyList_New(result.size()); - for(int i=0;iL!=result.end(); i++, iL++) - PyList_SetItem(res,i,PyInt_FromLong(*iL)); - return res; - } - - PyObject *getGeoTypesAtLevel(int meshDimRelToMax) const throw(INTERP_KERNEL::Exception) - { - std::vector<INTERP_KERNEL::NormalizedCellType> result(self->getGeoTypesAtLevel(meshDimRelToMax)); - std::vector<INTERP_KERNEL::NormalizedCellType>::const_iterator iL=result.begin(); - PyObject *res=PyList_New(result.size()); - for(int i=0;iL!=result.end(); i++, iL++) - PyList_SetItem(res,i,PyInt_FromLong(*iL)); - return res; - } - - PyObject *getFamilyFieldAtLevel(int meshDimRelToMaxExt) const throw(INTERP_KERNEL::Exception) - { - const DataArrayInt *tmp=self->getFamilyFieldAtLevel(meshDimRelToMaxExt); - if(tmp) - tmp->incrRef(); - return SWIG_NewPointerObj(SWIG_as_voidptr(tmp),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 ); - } - - PyObject *getOrCreateAndGetFamilyFieldAtLevel(int meshDimRelToMaxExt) throw(INTERP_KERNEL::Exception) - { - const DataArrayInt *tmp=self->getOrCreateAndGetFamilyFieldAtLevel(meshDimRelToMaxExt); - if(tmp) - tmp->incrRef(); - return SWIG_NewPointerObj(SWIG_as_voidptr(tmp),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 ); - } - - PyObject *getNumberFieldAtLevel(int meshDimRelToMaxExt) const throw(INTERP_KERNEL::Exception) - { - const DataArrayInt *tmp=self->getNumberFieldAtLevel(meshDimRelToMaxExt); - if(tmp) - tmp->incrRef(); - return SWIG_NewPointerObj(SWIG_as_voidptr(tmp),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 ); - } - - PyObject *getRevNumberFieldAtLevel(int meshDimRelToMaxExt) const throw(INTERP_KERNEL::Exception) - { - const DataArrayInt *tmp=self->getRevNumberFieldAtLevel(meshDimRelToMaxExt); - if(tmp) - tmp->incrRef(); - return SWIG_NewPointerObj(SWIG_as_voidptr(tmp),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 ); - } - - PyObject *getNameFieldAtLevel(int meshDimRelToMaxExt) const throw(INTERP_KERNEL::Exception) - { - const DataArrayAsciiChar *tmp=self->getNameFieldAtLevel(meshDimRelToMaxExt); - if(tmp) - tmp->incrRef(); - return SWIG_NewPointerObj(SWIG_as_voidptr(tmp),SWIGTYPE_p_ParaMEDMEM__DataArrayAsciiChar, SWIG_POINTER_OWN | 0 ); - } - - PyObject *findOrCreateAndGiveFamilyWithId(int id, bool& created) throw(INTERP_KERNEL::Exception) - { - bool ret1; - std::string ret0=self->findOrCreateAndGiveFamilyWithId(id,ret1); - PyObject *ret=PyTuple_New(2); - PyTuple_SetItem(ret,0,PyString_FromString(ret0.c_str())); - PyTuple_SetItem(ret,1,SWIG_From_bool(ret1)); - return ret; - } - - PyObject *unPolyze() throw(INTERP_KERNEL::Exception) - { - DataArrayInt *ret3=0; - std::vector<int> ret1,ret2; - bool ret0=self->unPolyze(ret1,ret2,ret3); - PyObject *ret=PyTuple_New(4); - PyTuple_SetItem(ret,0,SWIG_From_bool(ret0)); - // - PyObject *retLev1_0=PyList_New((int)ret1.size()/3); - for(int j=0;j<(int)ret1.size()/3;j++) - { - PyObject *retLev2=PyList_New(3); - PyList_SetItem(retLev2,0,SWIG_From_int(ret1[3*j])); - PyList_SetItem(retLev2,1,SWIG_From_int(ret1[3*j+1])); - PyList_SetItem(retLev2,2,SWIG_From_int(ret1[3*j+2])); - PyList_SetItem(retLev1_0,j,retLev2); - } - PyTuple_SetItem(ret,1,retLev1_0); - // - PyObject *retLev1_1=PyList_New((int)ret2.size()/3); - for(int j=0;j<(int)ret2.size()/3;j++) - { - PyObject *retLev2=PyList_New(3); - PyList_SetItem(retLev2,0,SWIG_From_int(ret2[3*j])); - PyList_SetItem(retLev2,1,SWIG_From_int(ret2[3*j+1])); - PyList_SetItem(retLev2,2,SWIG_From_int(ret2[3*j+2])); - PyList_SetItem(retLev1_1,j,retLev2); - } - PyTuple_SetItem(ret,2,retLev1_1); - // - PyTuple_SetItem(ret,3,SWIG_NewPointerObj(SWIG_as_voidptr(ret3),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 )); - return ret; - } - } - }; - - class MEDFileUMesh : public MEDFileMesh - { - public: - static MEDFileUMesh *New(const std::string& fileName, const std::string& mName, int dt=-1, int it=-1, MEDFileMeshReadSelector *mrs=0) throw(INTERP_KERNEL::Exception); - static MEDFileUMesh *New(const std::string& fileName, MEDFileMeshReadSelector *mrs=0) throw(INTERP_KERNEL::Exception); - static MEDFileUMesh *New(); - ~MEDFileUMesh(); - int getSpaceDimension() const throw(INTERP_KERNEL::Exception); - int getRelativeLevOnGeoType(INTERP_KERNEL::NormalizedCellType gt) const throw(INTERP_KERNEL::Exception); - // - std::vector<int> getGrpNonEmptyLevels(const std::string& grp) const throw(INTERP_KERNEL::Exception); - std::vector<int> getGrpNonEmptyLevelsExt(const std::string& grp) const throw(INTERP_KERNEL::Exception); - std::vector<int> getFamNonEmptyLevels(const std::string& fam) const throw(INTERP_KERNEL::Exception); - std::vector<int> getFamNonEmptyLevelsExt(const std::string& fam) const throw(INTERP_KERNEL::Exception); - std::vector<int> getGrpsNonEmptyLevels(const std::vector<std::string>& grps) const throw(INTERP_KERNEL::Exception); - std::vector<int> getGrpsNonEmptyLevelsExt(const std::vector<std::string>& grps) const throw(INTERP_KERNEL::Exception); - std::vector<int> getFamsNonEmptyLevels(const std::vector<std::string>& fams) const throw(INTERP_KERNEL::Exception); - std::vector<int> getFamsNonEmptyLevelsExt(const std::vector<std::string>& fams) const throw(INTERP_KERNEL::Exception); - std::vector<std::string> getGroupsOnSpecifiedLev(int meshDimRelToMaxExt) const throw(INTERP_KERNEL::Exception); - MEDCouplingUMesh *getGroup(int meshDimRelToMaxExt, const std::string& grp, bool renum=false) const throw(INTERP_KERNEL::Exception); - MEDCouplingUMesh *getGroups(int meshDimRelToMaxExt, const std::vector<std::string>& grps, bool renum=false) const throw(INTERP_KERNEL::Exception); - MEDCouplingUMesh *getFamily(int meshDimRelToMaxExt, const std::string& fam, bool renum=false) const throw(INTERP_KERNEL::Exception); - MEDCouplingUMesh *getFamilies(int meshDimRelToMaxExt, const std::vector<std::string>& fams, bool renum=false) const throw(INTERP_KERNEL::Exception); - DataArrayInt *getNodeGroupsArr(const std::vector<std::string>& grps, bool renum=false) const throw(INTERP_KERNEL::Exception); - MEDCouplingUMesh *getMeshAtLevel(int meshDimRelToMaxExt, bool renum=false) const throw(INTERP_KERNEL::Exception); - MEDCouplingUMesh *getLevel0Mesh(bool renum=false) const throw(INTERP_KERNEL::Exception); - MEDCouplingUMesh *getLevelM1Mesh(bool renum=false) const throw(INTERP_KERNEL::Exception); - MEDCouplingUMesh *getLevelM2Mesh(bool renum=false) const throw(INTERP_KERNEL::Exception); - MEDCouplingUMesh *getLevelM3Mesh(bool renum=false) const throw(INTERP_KERNEL::Exception); - void forceComputationOfParts() const throw(INTERP_KERNEL::Exception); - // - void setFamilyNameAttachedOnId(int id, const std::string& newFamName) throw(INTERP_KERNEL::Exception); - void setCoords(DataArrayDouble *coords) throw(INTERP_KERNEL::Exception); - void eraseGroupsAtLevel(int meshDimRelToMaxExt) throw(INTERP_KERNEL::Exception); - void removeMeshAtLevel(int meshDimRelToMax) throw(INTERP_KERNEL::Exception); - void setMeshAtLevel(int meshDimRelToMax, MEDCoupling1GTUMesh *m) throw(INTERP_KERNEL::Exception); - void setMeshAtLevel(int meshDimRelToMax, MEDCouplingUMesh *m, bool newOrOld=false) throw(INTERP_KERNEL::Exception); - void optimizeFamilies() throw(INTERP_KERNEL::Exception); - DataArrayInt *zipCoords() throw(INTERP_KERNEL::Exception); - DataArrayInt *extractFamilyFieldOnGeoType(INTERP_KERNEL::NormalizedCellType gt) const throw(INTERP_KERNEL::Exception); - DataArrayInt *extractNumberFieldOnGeoType(INTERP_KERNEL::NormalizedCellType gt) const throw(INTERP_KERNEL::Exception); - MEDFileUMesh *buildExtrudedMesh(const MEDCouplingUMesh *m1D, int policy) const throw(INTERP_KERNEL::Exception); - MEDFileUMesh *linearToQuadratic(int conversionType=0, double eps=1e-12) const throw(INTERP_KERNEL::Exception); - MEDFileUMesh *quadraticToLinear(double eps=1e-12) const throw(INTERP_KERNEL::Exception); - %extend - { - MEDFileUMesh(const std::string& fileName, const std::string& mName, int dt=-1, int it=-1, MEDFileMeshReadSelector *mrs=0) throw(INTERP_KERNEL::Exception) - { - return MEDFileUMesh::New(fileName,mName,dt,it,mrs); - } - - MEDFileUMesh(const std::string& fileName, MEDFileMeshReadSelector *mrs=0) throw(INTERP_KERNEL::Exception) - { - return MEDFileUMesh::New(fileName,mrs); - } - - MEDFileUMesh() - { - return MEDFileUMesh::New(); - } - - // serialization - static PyObject *___new___(PyObject *cls, PyObject *args) throw(INTERP_KERNEL::Exception) - { - return NewMethWrapCallInitOnlyIfEmptyDictInInput(cls,args,"MEDFileUMesh"); - } - - static MEDFileUMesh *LoadPartOf(const std::string& fileName, const std::string& mName, PyObject *types, const std::vector<int>& slicPerTyp, int dt=-1, int it=-1, MEDFileMeshReadSelector *mrs=0) throw(INTERP_KERNEL::Exception) - { - std::vector<int> typesCpp1; - convertPyToNewIntArr3(types,typesCpp1); - std::size_t sz(typesCpp1.size()); - std::vector<INTERP_KERNEL::NormalizedCellType> typesCpp2(sz); - for(std::size_t ii=0;ii<sz;ii++) - typesCpp2[ii]=(INTERP_KERNEL::NormalizedCellType)typesCpp1[ii]; - return MEDFileUMesh::LoadPartOf(fileName,mName,typesCpp2,slicPerTyp,dt,it,mrs); - } - - PyObject *__getnewargs__() throw(INTERP_KERNEL::Exception) - {// put an empty dict in input to say to __new__ to call __init__... - PyObject *ret(PyTuple_New(1)); - PyObject *ret0(PyDict_New()); - PyTuple_SetItem(ret,0,ret0); - return ret; - } - - PyObject *__getstate__() throw(INTERP_KERNEL::Exception) - { - std::vector<double> a0; - std::vector<int> a1; - std::vector<std::string> a2; - std::vector< MEDCouplingAutoRefCountObjectPtr<DataArrayInt> > a3; - MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> a4; - self->serialize(a0,a1,a2,a3,a4); - PyObject *ret(PyTuple_New(5)); - PyTuple_SetItem(ret,0,convertDblArrToPyList2(a0)); - PyTuple_SetItem(ret,1,convertIntArrToPyList2(a1)); - int sz(a2.size()); - PyObject *ret2(PyList_New(sz)); - for(int i=0;i<sz;i++) - PyList_SetItem(ret2,i,PyString_FromString(a2[i].c_str())); - PyTuple_SetItem(ret,2,ret2); - sz=a3.size(); - PyObject *ret3(PyList_New(sz)); - for(int i=0;i<sz;i++) - { - DataArrayInt *elt(a3[i]); - if(elt) - elt->incrRef(); - PyList_SetItem(ret3,i,SWIG_NewPointerObj(SWIG_as_voidptr(elt),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 )); - } - PyTuple_SetItem(ret,3,ret3); - DataArrayDouble *ret4(a4); - if(ret4) - ret4->incrRef(); - PyTuple_SetItem(ret,4,SWIG_NewPointerObj(SWIG_as_voidptr(ret4),SWIGTYPE_p_ParaMEDMEM__DataArrayDouble, SWIG_POINTER_OWN | 0 )); - return ret; - } - - void __setstate__(PyObject *inp) throw(INTERP_KERNEL::Exception) - { - static const char MSG[]="MEDFileUMesh.__setstate__ : expected input is a tuple of size 4 !"; - if(!PyTuple_Check(inp)) - throw INTERP_KERNEL::Exception(MSG); - int sz(PyTuple_Size(inp)); - if(sz!=5) - throw INTERP_KERNEL::Exception(MSG); - std::vector<double> a0; - std::vector<int> a1; - std::vector<std::string> a2; - std::vector< MEDCouplingAutoRefCountObjectPtr<DataArrayInt> > a3; - MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> a4; - // - PyObject *a0py(PyTuple_GetItem(inp,0)),*a1py(PyTuple_GetItem(inp,1)),*a2py(PyTuple_GetItem(inp,2)); - int tmp(-1); - fillArrayWithPyListDbl3(a0py,tmp,a0); - convertPyToNewIntArr3(a1py,a1); - fillStringVector(a2py,a2); - // - PyObject *b0py(PyTuple_GetItem(inp,3)),*b1py(PyTuple_GetItem(inp,4)); - void *argp(0); - int status(SWIG_ConvertPtr(b1py,&argp,SWIGTYPE_p_ParaMEDMEM__DataArrayDouble,0|0)); - if(!SWIG_IsOK(status)) - throw INTERP_KERNEL::Exception(MSG); - a4=reinterpret_cast<DataArrayDouble *>(argp); - if((DataArrayDouble *)a4) - a4->incrRef(); - { - std::vector< DataArrayInt * > a3Tmp; - convertFromPyObjVectorOfObj<ParaMEDMEM::DataArrayInt *>(b0py,SWIGTYPE_p_ParaMEDMEM__DataArrayInt,"DataArrayInt",a3Tmp); - std::size_t sz(a3Tmp.size()); - a3.resize(sz); - for(std::size_t i=0;i<sz;i++) - { - a3[i]=a3Tmp[i]; - if(a3Tmp[i]) - a3Tmp[i]->incrRef(); - } - self->unserialize(a0,a1,a2,a3,a4); - } - } - - void __setitem__(int meshDimRelToMax, MEDCouplingPointSet *mesh) throw(INTERP_KERNEL::Exception) - { - if(!mesh) - throw INTERP_KERNEL::Exception("MEDFileUMesh::__setitem__ : Input mesh is NULL !"); - MEDCouplingUMesh *m0(dynamic_cast<MEDCouplingUMesh *>(mesh)); - if(m0) - { - self->setMeshAtLevel(meshDimRelToMax,m0,false); - return ; - } - MEDCoupling1GTUMesh *m1(dynamic_cast<MEDCoupling1GTUMesh *>(mesh)); - if(m1) - { - self->setMeshAtLevel(meshDimRelToMax,m1); - return ; - } - throw INTERP_KERNEL::Exception("MEDFileUMesh::__setitem__ : Not recognized input mesh !"); - } - - void __delitem__(int meshDimRelToMax) throw(INTERP_KERNEL::Exception) - { - self->removeMeshAtLevel(meshDimRelToMax); - } - - void setMeshes(PyObject *li, bool renum=false) throw(INTERP_KERNEL::Exception) - { - std::vector<const MEDCouplingUMesh *> ms; - convertFromPyObjVectorOfObj<const ParaMEDMEM::MEDCouplingUMesh *>(li,SWIGTYPE_p_ParaMEDMEM__MEDCouplingUMesh,"MEDCouplingUMesh",ms); - self->setMeshes(ms,renum); - } - - void setGroupsFromScratch(int meshDimRelToMax, PyObject *li, bool renum=false) throw(INTERP_KERNEL::Exception) - { - std::vector<const MEDCouplingUMesh *> ms; - convertFromPyObjVectorOfObj<const ParaMEDMEM::MEDCouplingUMesh *>(li,SWIGTYPE_p_ParaMEDMEM__MEDCouplingUMesh,"MEDCouplingUMesh",ms); - self->setGroupsFromScratch(meshDimRelToMax,ms,renum); - } - - void setGroupsOnSetMesh(int meshDimRelToMax, PyObject *li, bool renum=false) throw(INTERP_KERNEL::Exception) - { - std::vector<const MEDCouplingUMesh *> ms; - convertFromPyObjVectorOfObj<const ParaMEDMEM::MEDCouplingUMesh *>(li,SWIGTYPE_p_ParaMEDMEM__MEDCouplingUMesh,"MEDCouplingUMesh",ms); - self->setGroupsOnSetMesh(meshDimRelToMax,ms,renum); - } - - DataArrayDouble *getCoords() const throw(INTERP_KERNEL::Exception) - { - DataArrayDouble *ret=self->getCoords(); - if(ret) - ret->incrRef(); - return ret; - } - - PartDefinition *getPartDefAtLevel(int meshDimRelToMaxExt, INTERP_KERNEL::NormalizedCellType gt=INTERP_KERNEL::NORM_ERROR) const throw(INTERP_KERNEL::Exception) - { - const PartDefinition *ret(self->getPartDefAtLevel(meshDimRelToMaxExt,gt)); - if(ret) - ret->incrRef(); - return const_cast<PartDefinition *>(ret); - } - - PyObject *buildInnerBoundaryAlongM1Group(const std::string& grpNameM1) throw(INTERP_KERNEL::Exception) - { - DataArrayInt *ret0=0,*ret1=0,*ret2=0; - self->buildInnerBoundaryAlongM1Group(grpNameM1,ret0,ret1,ret2); - PyObject *ret=PyTuple_New(3); - PyTuple_SetItem(ret,0,SWIG_NewPointerObj(SWIG_as_voidptr(ret0),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 )); - PyTuple_SetItem(ret,1,SWIG_NewPointerObj(SWIG_as_voidptr(ret1),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 )); - PyTuple_SetItem(ret,2,SWIG_NewPointerObj(SWIG_as_voidptr(ret2),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 )); - return ret; - } - - MEDCoupling1GTUMesh *getDirectUndergroundSingleGeoTypeMesh(INTERP_KERNEL::NormalizedCellType gt) const throw(INTERP_KERNEL::Exception) - { - MEDCoupling1GTUMesh *ret(self->getDirectUndergroundSingleGeoTypeMesh(gt)); - if(ret) - ret->incrRef(); - return ret; - } - - PyObject *getDirectUndergroundSingleGeoTypeMeshes(int meshDimRelToMax) const throw(INTERP_KERNEL::Exception) - { - std::vector<MEDCoupling1GTUMesh *> tmp(self->getDirectUndergroundSingleGeoTypeMeshes(meshDimRelToMax)); - std::size_t sz(tmp.size()); - PyObject *ret=PyList_New(sz); - for(std::size_t i=0;i<sz;i++) - { - if(tmp[i]) - tmp[i]->incrRef(); - PyList_SetItem(ret,i,convertMesh(tmp[i], SWIG_POINTER_OWN | 0 )); - } - return ret; - } - } - }; - - class MEDFileStructuredMesh : public MEDFileMesh - { - public: - %extend - { - MEDCoupling1SGTUMesh *getImplicitFaceMesh() const throw(INTERP_KERNEL::Exception) - { - MEDCoupling1SGTUMesh *ret(self->getImplicitFaceMesh()); - if(ret) - ret->incrRef(); - return ret; - } - } - }; - - class MEDFileCMesh : public MEDFileStructuredMesh - { - public: - static MEDFileCMesh *New(); - static MEDFileCMesh *New(const std::string& fileName, MEDFileMeshReadSelector *mrs=0) throw(INTERP_KERNEL::Exception); - static MEDFileCMesh *New(const std::string& fileName, const std::string& mName, int dt=-1, int it=-1, MEDFileMeshReadSelector *mrs=0) throw(INTERP_KERNEL::Exception); - void setMesh(MEDCouplingCMesh *m) throw(INTERP_KERNEL::Exception); - int getSpaceDimension() const throw(INTERP_KERNEL::Exception); - %extend - { - MEDFileCMesh() - { - return MEDFileCMesh::New(); - } - - MEDFileCMesh(const std::string& fileName, MEDFileMeshReadSelector *mrs=0) throw(INTERP_KERNEL::Exception) - { - return MEDFileCMesh::New(fileName,mrs); - } - - MEDFileCMesh(const std::string& fileName, const std::string& mName, int dt=-1, int it=-1, MEDFileMeshReadSelector *mrs=0) throw(INTERP_KERNEL::Exception) - { - return MEDFileCMesh::New(fileName,mName,dt,it,mrs); - } - - PyObject *getMesh() const throw(INTERP_KERNEL::Exception) - { - const MEDCouplingCMesh *tmp=self->getMesh(); - if(tmp) - tmp->incrRef(); - return SWIG_NewPointerObj(SWIG_as_voidptr(tmp),SWIGTYPE_p_ParaMEDMEM__MEDCouplingCMesh, SWIG_POINTER_OWN | 0 ); - } - } - }; - - class MEDFileCurveLinearMesh : public MEDFileStructuredMesh - { - public: - static MEDFileCurveLinearMesh *New(); - static MEDFileCurveLinearMesh *New(const std::string& fileName, MEDFileMeshReadSelector *mrs=0) throw(INTERP_KERNEL::Exception); - static MEDFileCurveLinearMesh *New(const std::string& fileName, const std::string& mName, int dt=-1, int it=-1, MEDFileMeshReadSelector *mrs=0) throw(INTERP_KERNEL::Exception); - void setMesh(MEDCouplingCurveLinearMesh *m) throw(INTERP_KERNEL::Exception); - %extend - { - MEDFileCurveLinearMesh() - { - return MEDFileCurveLinearMesh::New(); - } - - MEDFileCurveLinearMesh(const std::string& fileName, MEDFileMeshReadSelector *mrs=0) throw(INTERP_KERNEL::Exception) - { - return MEDFileCurveLinearMesh::New(fileName,mrs); - } - - MEDFileCurveLinearMesh(const std::string& fileName, const std::string& mName, int dt=-1, int it=-1, MEDFileMeshReadSelector *mrs=0) throw(INTERP_KERNEL::Exception) - { - return MEDFileCurveLinearMesh::New(fileName,mName,dt,it,mrs); - } - - PyObject *getMesh() const throw(INTERP_KERNEL::Exception) - { - const MEDCouplingCurveLinearMesh *tmp=self->getMesh(); - if(tmp) - tmp->incrRef(); - return SWIG_NewPointerObj(SWIG_as_voidptr(tmp),SWIGTYPE_p_ParaMEDMEM__MEDCouplingCurveLinearMesh, SWIG_POINTER_OWN | 0 ); - } - } - }; - - class MEDFileMeshMultiTS : public RefCountObject, public MEDFileWritable - { - public: - static MEDFileMeshMultiTS *New(); - static MEDFileMeshMultiTS *New(const std::string& fileName) throw(INTERP_KERNEL::Exception); - static MEDFileMeshMultiTS *New(const std::string& fileName, const std::string& mName) throw(INTERP_KERNEL::Exception); - MEDFileMeshMultiTS *deepCpy() const throw(INTERP_KERNEL::Exception); - std::string getName() const throw(INTERP_KERNEL::Exception); - void write(const std::string& fileName, int mode) const throw(INTERP_KERNEL::Exception); - void setOneTimeStep(MEDFileMesh *mesh1TimeStep) throw(INTERP_KERNEL::Exception); - %extend - { - MEDFileMeshMultiTS() - { - return MEDFileMeshMultiTS::New(); - } - - MEDFileMeshMultiTS(const std::string& fileName) throw(INTERP_KERNEL::Exception) - { - return MEDFileMeshMultiTS::New(fileName); - } - - MEDFileMeshMultiTS(const std::string& fileName, const std::string& mName) throw(INTERP_KERNEL::Exception) - { - return MEDFileMeshMultiTS::New(fileName,mName); - } - - MEDFileMesh *getOneTimeStep() const throw(INTERP_KERNEL::Exception) - { - MEDFileMesh *ret=self->getOneTimeStep(); - if(ret) - ret->incrRef(); - return ret; - } - } - }; - - class MEDFileMeshesIterator - { - public: - %extend - { - PyObject *next() throw(INTERP_KERNEL::Exception) - { - MEDFileMesh *ret=self->nextt(); - if(ret) - { - ret->incrRef(); - return convertMEDFileMesh(ret,SWIG_POINTER_OWN | 0 ); - } - else - { - PyErr_SetString(PyExc_StopIteration,"No more data."); - return 0; - } - } - } - }; - - class MEDFileMeshes : public RefCountObject, public MEDFileWritable - { - public: - static MEDFileMeshes *New(); - static MEDFileMeshes *New(const std::string& fileName) throw(INTERP_KERNEL::Exception); - MEDFileMeshes *deepCpy() const throw(INTERP_KERNEL::Exception); - void write(const std::string& fileName, int mode) const throw(INTERP_KERNEL::Exception); - int getNumberOfMeshes() const throw(INTERP_KERNEL::Exception); - std::vector<std::string> getMeshesNames() const throw(INTERP_KERNEL::Exception); - // - void resize(int newSize) throw(INTERP_KERNEL::Exception); - void pushMesh(MEDFileMesh *mesh) throw(INTERP_KERNEL::Exception); - void setMeshAtPos(int i, MEDFileMesh *mesh) throw(INTERP_KERNEL::Exception); - void destroyMeshAtPos(int i) throw(INTERP_KERNEL::Exception); - %extend - { - MEDFileMeshes() - { - return MEDFileMeshes::New(); - } - - MEDFileMeshes(const std::string& fileName) throw(INTERP_KERNEL::Exception) - { - return MEDFileMeshes::New(fileName); - } - - std::string __str__() const throw(INTERP_KERNEL::Exception) - { - return self->simpleRepr(); - } - - MEDFileMesh *__getitem__(PyObject *obj) throw(INTERP_KERNEL::Exception) - { - if(PyInt_Check(obj)) - { - MEDFileMesh *ret=self->getMeshAtPos(InterpreteNegativeInt((int)PyInt_AS_LONG(obj),self->getNumberOfMeshes())); - if(ret) - ret->incrRef(); - return ret; - } - else if(PyString_Check(obj)) - { - MEDFileMesh *ret=self->getMeshWithName(PyString_AsString(obj)); - if(ret) - ret->incrRef(); - return ret; - } - else - throw INTERP_KERNEL::Exception("MEDFileMeshes::__getitem__ : only integer or string with meshname supported !"); - } - - MEDFileMeshes *__setitem__(int obj, MEDFileMesh *mesh) throw(INTERP_KERNEL::Exception) - { - self->setMeshAtPos(obj,mesh); - return self; - } - - MEDFileMeshesIterator *__iter__() throw(INTERP_KERNEL::Exception) - { - return self->iterator(); - } - - int __len__() const throw(INTERP_KERNEL::Exception) - { - return self->getNumberOfMeshes(); - } - - MEDFileMesh *getMeshAtPos(int i) const throw(INTERP_KERNEL::Exception) - { - MEDFileMesh *ret=self->getMeshAtPos(i); - if(ret) - ret->incrRef(); - return ret; - } - MEDFileMesh *getMeshWithName(const std::string& mname) const throw(INTERP_KERNEL::Exception) - { - MEDFileMesh *ret=self->getMeshWithName(mname); - if(ret) - ret->incrRef(); - return ret; - } - } - }; - - class MEDFileFieldLoc : public RefCountObject - { - public: - std::string getName() const; - int getDimension() const; - int getNumberOfGaussPoints() const; - int getNumberOfPointsInCells() const; - const std::vector<double>& getRefCoords() const; - const std::vector<double>& getGaussCoords() const; - const std::vector<double>& getGaussWeights() const; - bool isEqual(const MEDFileFieldLoc& other, double eps) const throw(INTERP_KERNEL::Exception); - %extend - { - std::string __str__() const throw(INTERP_KERNEL::Exception) - { - return self->repr(); - } - } - }; - - class MEDFileFieldGlobsReal - { - public: - void resetContent(); - void shallowCpyGlobs(const MEDFileFieldGlobsReal& other) throw(INTERP_KERNEL::Exception); - void deepCpyGlobs(const MEDFileFieldGlobsReal& other) throw(INTERP_KERNEL::Exception); - void shallowCpyOnlyUsedGlobs(const MEDFileFieldGlobsReal& other) throw(INTERP_KERNEL::Exception); - void deepCpyOnlyUsedGlobs(const MEDFileFieldGlobsReal& other) throw(INTERP_KERNEL::Exception); - void appendGlobs(const MEDFileFieldGlobsReal& other, double eps) throw(INTERP_KERNEL::Exception); - void checkGlobsCoherency() const throw(INTERP_KERNEL::Exception); - void checkGlobsPflsPartCoherency() const throw(INTERP_KERNEL::Exception); - void checkGlobsLocsPartCoherency() const throw(INTERP_KERNEL::Exception); - std::vector<std::string> getPfls() const throw(INTERP_KERNEL::Exception); - std::vector<std::string> getLocs() const throw(INTERP_KERNEL::Exception); - bool existsPfl(const std::string& pflName) const throw(INTERP_KERNEL::Exception); - bool existsLoc(const std::string& locName) const throw(INTERP_KERNEL::Exception); - std::string createNewNameOfPfl() const throw(INTERP_KERNEL::Exception); - std::string createNewNameOfLoc() const throw(INTERP_KERNEL::Exception); - std::vector< std::vector<int> > whichAreEqualProfiles() const throw(INTERP_KERNEL::Exception); - std::vector< std::vector<int> > whichAreEqualLocs(double eps) const throw(INTERP_KERNEL::Exception); - virtual std::vector<std::string> getPflsReallyUsed() const throw(INTERP_KERNEL::Exception); - virtual std::vector<std::string> getLocsReallyUsed() const throw(INTERP_KERNEL::Exception); - virtual std::vector<std::string> getPflsReallyUsedMulti() const throw(INTERP_KERNEL::Exception); - virtual std::vector<std::string> getLocsReallyUsedMulti() const throw(INTERP_KERNEL::Exception); - void killProfileIds(const std::vector<int>& pflIds) throw(INTERP_KERNEL::Exception); - void killLocalizationIds(const std::vector<int>& locIds) throw(INTERP_KERNEL::Exception); - void changePflName(const std::string& oldName, const std::string& newName) throw(INTERP_KERNEL::Exception); - void changeLocName(const std::string& oldName, const std::string& newName) throw(INTERP_KERNEL::Exception); - int getNbOfGaussPtPerCell(int locId) const throw(INTERP_KERNEL::Exception); - int getLocalizationId(const std::string& loc) const throw(INTERP_KERNEL::Exception); - %extend - { - PyObject *getProfile(const std::string& pflName) const throw(INTERP_KERNEL::Exception) - { - const DataArrayInt *ret=self->getProfile(pflName); - if(ret) - ret->incrRef(); - return SWIG_NewPointerObj(SWIG_as_voidptr(ret),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 ); - } - - PyObject *getProfileFromId(int pflId) const throw(INTERP_KERNEL::Exception) - { - const DataArrayInt *ret=self->getProfileFromId(pflId); - if(ret) - ret->incrRef(); - return SWIG_NewPointerObj(SWIG_as_voidptr(ret),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 ); - } - - PyObject *getLocalizationFromId(int locId) const throw(INTERP_KERNEL::Exception) - { - const MEDFileFieldLoc *loc=&self->getLocalizationFromId(locId); - if(loc) - loc->incrRef(); - return SWIG_NewPointerObj(SWIG_as_voidptr(loc),SWIGTYPE_p_ParaMEDMEM__MEDFileFieldLoc, SWIG_POINTER_OWN | 0 ); - } - - PyObject *getLocalization(const std::string& locName) const throw(INTERP_KERNEL::Exception) - { - const MEDFileFieldLoc *loc=&self->getLocalization(locName); - if(loc) - loc->incrRef(); - return SWIG_NewPointerObj(SWIG_as_voidptr(loc),SWIGTYPE_p_ParaMEDMEM__MEDFileFieldLoc, SWIG_POINTER_OWN | 0 ); - } - - PyObject *zipPflsNames() throw(INTERP_KERNEL::Exception) - { - std::vector< std::pair<std::vector<std::string>, std::string > > ret=self->zipPflsNames(); - return convertVecPairVecStToPy(ret); - } - - PyObject *zipLocsNames(double eps) throw(INTERP_KERNEL::Exception) - { - std::vector< std::pair<std::vector<std::string>, std::string > > ret=self->zipLocsNames(eps); - return convertVecPairVecStToPy(ret); - } - - void changePflsNames(PyObject *li) throw(INTERP_KERNEL::Exception) - { - std::vector< std::pair<std::vector<std::string>, std::string > > v=convertVecPairVecStFromPy(li); - self->changePflsNames(v); - } - - void changePflsRefsNamesGen(PyObject *li) throw(INTERP_KERNEL::Exception) - { - std::vector< std::pair<std::vector<std::string>, std::string > > v=convertVecPairVecStFromPy(li); - self->changePflsRefsNamesGen(v); - } - - void changePflsNamesInStruct(PyObject *li) throw(INTERP_KERNEL::Exception) - { - std::vector< std::pair<std::vector<std::string>, std::string > > v=convertVecPairVecStFromPy(li); - self->changePflsNamesInStruct(v); - } - - void changeLocsNames(PyObject *li) throw(INTERP_KERNEL::Exception) - { - std::vector< std::pair<std::vector<std::string>, std::string > > v=convertVecPairVecStFromPy(li); - self->changeLocsNames(v); - } - - void changeLocsRefsNamesGen(PyObject *li) throw(INTERP_KERNEL::Exception) - { - std::vector< std::pair<std::vector<std::string>, std::string > > v=convertVecPairVecStFromPy(li); - self->changeLocsRefsNamesGen(v); - } - - void changeLocsNamesInStruct(PyObject *li) throw(INTERP_KERNEL::Exception) - { - std::vector< std::pair<std::vector<std::string>, std::string > > v=convertVecPairVecStFromPy(li); - self->changeLocsNamesInStruct(v); - } - - std::string simpleReprGlobs() const throw(INTERP_KERNEL::Exception) - { - std::ostringstream oss; - self->simpleReprGlobs(oss); - return oss.str(); - } - } - }; - - class MEDFileAnyTypeField1TS : public RefCountObject, public MEDFileFieldGlobsReal, public MEDFileWritable - { - public: - static MEDFileAnyTypeField1TS *New(const std::string& fileName, bool loadAll=true) throw(INTERP_KERNEL::Exception); - static MEDFileAnyTypeField1TS *New(const std::string& fileName, const std::string& fieldName, bool loadAll=true) throw(INTERP_KERNEL::Exception); - static MEDFileAnyTypeField1TS *New(const std::string& fileName, const std::string& fieldName, int iteration, int order, bool loadAll=true) throw(INTERP_KERNEL::Exception); - void write(const std::string& fileName, int mode) const throw(INTERP_KERNEL::Exception); - void loadArrays() throw(INTERP_KERNEL::Exception); - void loadArraysIfNecessary() throw(INTERP_KERNEL::Exception); - void unloadArrays() throw(INTERP_KERNEL::Exception); - void unloadArraysWithoutDataLoss() throw(INTERP_KERNEL::Exception); - int getDimension() const throw(INTERP_KERNEL::Exception); - int getIteration() const throw(INTERP_KERNEL::Exception); - int getOrder() const throw(INTERP_KERNEL::Exception); - std::string getName() throw(INTERP_KERNEL::Exception); - void setName(const std::string& name) throw(INTERP_KERNEL::Exception); - std::string getMeshName() throw(INTERP_KERNEL::Exception); - void setMeshName(const std::string& newMeshName) throw(INTERP_KERNEL::Exception); - int getMeshIteration() const throw(INTERP_KERNEL::Exception); - int getMeshOrder() const throw(INTERP_KERNEL::Exception); - int getNumberOfComponents() const throw(INTERP_KERNEL::Exception); - bool isDealingTS(int iteration, int order) const throw(INTERP_KERNEL::Exception); - void setInfo(const std::vector<std::string>& infos) throw(INTERP_KERNEL::Exception); - const std::vector<std::string>& getInfo() const throw(INTERP_KERNEL::Exception); - bool presenceOfMultiDiscPerGeoType() const throw(INTERP_KERNEL::Exception); - void setTime(int iteration, int order, double val) throw(INTERP_KERNEL::Exception); - virtual MEDFileAnyTypeField1TS *shallowCpy() const throw(INTERP_KERNEL::Exception); - MEDFileAnyTypeField1TS *deepCpy() const throw(INTERP_KERNEL::Exception); - std::string getDtUnit() const throw(INTERP_KERNEL::Exception); - void setDtUnit(const std::string& dtUnit) throw(INTERP_KERNEL::Exception); - %extend - { - PyObject *getTime() throw(INTERP_KERNEL::Exception) - { - int tmp1,tmp2; - double tmp0=self->getTime(tmp1,tmp2); - PyObject *res = PyList_New(3); - PyList_SetItem(res,0,SWIG_From_int(tmp1)); - PyList_SetItem(res,1,SWIG_From_int(tmp2)); - PyList_SetItem(res,2,SWIG_From_double(tmp0)); - return res; - } - - PyObject *getDtIt() const throw(INTERP_KERNEL::Exception) - { - std::pair<int,int> res=self->getDtIt(); - PyObject *elt=PyTuple_New(2); - PyTuple_SetItem(elt,0,SWIG_From_int(res.first)); - PyTuple_SetItem(elt,1,SWIG_From_int(res.second)); - return elt; - } - - void setProfileNameOnLeaf(INTERP_KERNEL::NormalizedCellType typ, int locId, const std::string& newPflName, bool forceRenameOnGlob=false) throw(INTERP_KERNEL::Exception) - { - self->setProfileNameOnLeaf(0,typ,locId,newPflName,forceRenameOnGlob); - } - - void setLocNameOnLeaf(INTERP_KERNEL::NormalizedCellType typ, int locId, const std::string& newLocName, bool forceRenameOnGlob=false) throw(INTERP_KERNEL::Exception) - { - self->setLocNameOnLeaf(0,typ,locId,newLocName,forceRenameOnGlob); - } - - bool changeMeshNames(PyObject *li) throw(INTERP_KERNEL::Exception) - { - std::vector< std::pair<std::string,std::string> > modifTab=convertVecPairStStFromPy(li); - return self->changeMeshNames(modifTab); - } - - PyObject *getTypesOfFieldAvailable() const throw(INTERP_KERNEL::Exception) - { - std::vector<TypeOfField> ret=self->getTypesOfFieldAvailable(); - PyObject *ret2=PyList_New(ret.size()); - for(int i=0;i<(int)ret.size();i++) - PyList_SetItem(ret2,i,SWIG_From_int(ret[i])); - return ret2; - } - - PyObject *getNonEmptyLevels(const std::string& mname=std::string()) const throw(INTERP_KERNEL::Exception) - { - std::vector<int> ret1; - int ret0=self->getNonEmptyLevels(mname,ret1); - PyObject *elt=PyTuple_New(2); - PyTuple_SetItem(elt,0,SWIG_From_int(ret0)); - PyTuple_SetItem(elt,1,convertIntArrToPyList2(ret1)); - return elt; - } - - PyObject *getFieldSplitedByType(const std::string& mname=std::string()) const throw(INTERP_KERNEL::Exception) - { - std::vector<INTERP_KERNEL::NormalizedCellType> types; - std::vector< std::vector<TypeOfField> > typesF; - std::vector< std::vector<std::string> > pfls; - std::vector< std::vector<std::string> > locs; - std::vector< std::vector< std::pair<int,int> > > ret=self->getFieldSplitedByType(mname,types,typesF,pfls,locs); - int sz=ret.size(); - PyObject *ret2=PyList_New(sz); - for(int i=0;i<sz;i++) - { - const std::vector< std::pair<int,int> >& dadsI=ret[i]; - const std::vector<TypeOfField>& typesFI=typesF[i]; - const std::vector<std::string>& pflsI=pfls[i]; - const std::vector<std::string>& locsI=locs[i]; - PyObject *elt=PyTuple_New(2); - PyTuple_SetItem(elt,0,SWIG_From_int(types[i])); - int sz2=ret[i].size(); - PyObject *elt2=PyList_New(sz2); - for(int j=0;j<sz2;j++) - { - PyObject *elt3=PyTuple_New(4); - PyTuple_SetItem(elt3,0,SWIG_From_int(typesFI[j])); - PyObject *elt4=PyTuple_New(2); PyTuple_SetItem(elt4,0,SWIG_From_int(dadsI[j].first)); PyTuple_SetItem(elt4,1,SWIG_From_int(dadsI[j].second)); - PyTuple_SetItem(elt3,1,elt4); - PyTuple_SetItem(elt3,2,PyString_FromString(pflsI[j].c_str())); - PyTuple_SetItem(elt3,3,PyString_FromString(locsI[j].c_str())); - PyList_SetItem(elt2,j,elt3); - } - PyTuple_SetItem(elt,1,elt2); - PyList_SetItem(ret2,i,elt); - } - return ret2; - } - - PyObject *splitComponents() const throw(INTERP_KERNEL::Exception) - { - std::vector< MEDCouplingAutoRefCountObjectPtr< MEDFileAnyTypeField1TS > > ret=self->splitComponents(); - std::size_t sz=ret.size(); - PyObject *retPy=PyList_New(sz); - for(std::size_t i=0;i<sz;i++) - PyList_SetItem(retPy,i,convertMEDFileField1TS(ret[i].retn(), SWIG_POINTER_OWN | 0 )); - return retPy; - } - - PyObject *splitDiscretizations() const throw(INTERP_KERNEL::Exception) - { - std::vector< MEDCouplingAutoRefCountObjectPtr< MEDFileAnyTypeField1TS > > ret=self->splitDiscretizations(); - std::size_t sz=ret.size(); - PyObject *retPy=PyList_New(sz); - for(std::size_t i=0;i<sz;i++) - PyList_SetItem(retPy,i,convertMEDFileField1TS(ret[i].retn(), SWIG_POINTER_OWN | 0 )); - return retPy; - } - - PyObject *splitMultiDiscrPerGeoTypes() const throw(INTERP_KERNEL::Exception) - { - std::vector< MEDCouplingAutoRefCountObjectPtr< MEDFileAnyTypeField1TS > > ret=self->splitMultiDiscrPerGeoTypes(); - std::size_t sz=ret.size(); - PyObject *retPy=PyList_New(sz); - for(std::size_t i=0;i<sz;i++) - PyList_SetItem(retPy,i,convertMEDFileField1TS(ret[i].retn(), SWIG_POINTER_OWN | 0 )); - return retPy; - } - } - }; - - class MEDFileField1TS : public MEDFileAnyTypeField1TS - { - public: - static MEDFileField1TS *New(const std::string& fileName, const std::string& fieldName, int iteration, int order, bool loadAll=true) throw(INTERP_KERNEL::Exception); - static MEDFileField1TS *New(const std::string& fileName, const std::string& fieldName, bool loadAll=true) throw(INTERP_KERNEL::Exception); - static MEDFileField1TS *New(const std::string& fileName, bool loadAll=true) throw(INTERP_KERNEL::Exception); - static MEDFileField1TS *New(); - ParaMEDMEM::MEDFileIntField1TS *convertToInt(bool isDeepCpyGlobs=true) const throw(INTERP_KERNEL::Exception); - MEDCouplingFieldDouble *getFieldAtLevel(TypeOfField type, int meshDimRelToMax, int renumPol=0) const throw(INTERP_KERNEL::Exception); - MEDCouplingFieldDouble *getFieldAtTopLevel(TypeOfField type, int renumPol=0) const throw(INTERP_KERNEL::Exception); - MEDCouplingFieldDouble *getFieldOnMeshAtLevel(TypeOfField type, const MEDCouplingMesh *mesh, int renumPol=0) const throw(INTERP_KERNEL::Exception); - MEDCouplingFieldDouble *getFieldOnMeshAtLevel(TypeOfField type, int meshDimRelToMax, const MEDFileMesh *mesh, int renumPol=0) const throw(INTERP_KERNEL::Exception); - MEDCouplingFieldDouble *getFieldAtLevelOld(TypeOfField type, const std::string& mname, int meshDimRelToMax, int renumPol=0) const throw(INTERP_KERNEL::Exception); - // - void setFieldNoProfileSBT(const MEDCouplingFieldDouble *field) throw(INTERP_KERNEL::Exception); - void setFieldProfile(const MEDCouplingFieldDouble *field, const MEDFileMesh *mesh, int meshDimRelToMax, const DataArrayInt *profile) throw(INTERP_KERNEL::Exception); - void setProfileNameOnLeaf(const std::string& mName, INTERP_KERNEL::NormalizedCellType typ, int locId, const std::string& newPflName, bool forceRenameOnGlob=false) throw(INTERP_KERNEL::Exception); - void setLocNameOnLeaf(const std::string& mName, INTERP_KERNEL::NormalizedCellType typ, int locId, const std::string& newLocName, bool forceRenameOnGlob=false) throw(INTERP_KERNEL::Exception); - %extend - { - MEDFileField1TS(const std::string& fileName, bool loadAll=true) throw(INTERP_KERNEL::Exception) - { - return MEDFileField1TS::New(fileName,loadAll); - } - - MEDFileField1TS(const std::string& fileName, const std::string& fieldName, bool loadAll=true) throw(INTERP_KERNEL::Exception) - { - return MEDFileField1TS::New(fileName,fieldName,loadAll); - } - - MEDFileField1TS(const std::string& fileName, const std::string& fieldName, int iteration, int order, bool loadAll=true) throw(INTERP_KERNEL::Exception) - { - return MEDFileField1TS::New(fileName,fieldName,iteration,order,loadAll); - } - - MEDFileField1TS() - { - return MEDFileField1TS::New(); - } - - void copyTinyInfoFrom(const MEDCouplingFieldDouble *field) throw(INTERP_KERNEL::Exception) - { - const DataArrayDouble *arr=0; - if(field) - arr=field->getArray(); - self->copyTinyInfoFrom(field,arr); - } - - std::string __str__() const throw(INTERP_KERNEL::Exception) - { - return self->simpleRepr(); - } - - PyObject *getFieldWithProfile(TypeOfField type, int meshDimRelToMax, const MEDFileMesh *mesh) const throw(INTERP_KERNEL::Exception) - { - DataArrayInt *ret1=0; - DataArrayDouble *ret0=self->getFieldWithProfile(type,meshDimRelToMax,mesh,ret1); - PyObject *ret=PyTuple_New(2); - PyTuple_SetItem(ret,0,SWIG_NewPointerObj(SWIG_as_voidptr(ret0),SWIGTYPE_p_ParaMEDMEM__DataArrayDouble, SWIG_POINTER_OWN | 0 )); - PyTuple_SetItem(ret,1,SWIG_NewPointerObj(SWIG_as_voidptr(ret1),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 )); - return ret; - } - - PyObject *getFieldSplitedByType2(const std::string& mname=std::string()) const throw(INTERP_KERNEL::Exception) - { - std::vector<INTERP_KERNEL::NormalizedCellType> types; - std::vector< std::vector<TypeOfField> > typesF; - std::vector< std::vector<std::string> > pfls; - std::vector< std::vector<std::string> > locs; - std::vector< std::vector<DataArrayDouble *> > ret=self->getFieldSplitedByType2(mname,types,typesF,pfls,locs); - int sz=ret.size(); - PyObject *ret2=PyList_New(sz); - for(int i=0;i<sz;i++) - { - const std::vector<DataArrayDouble *>& dadsI=ret[i]; - const std::vector<TypeOfField>& typesFI=typesF[i]; - const std::vector<std::string>& pflsI=pfls[i]; - const std::vector<std::string>& locsI=locs[i]; - PyObject *elt=PyTuple_New(2); - PyTuple_SetItem(elt,0,SWIG_From_int(types[i])); - int sz2=ret[i].size(); - PyObject *elt2=PyList_New(sz2); - for(int j=0;j<sz2;j++) - { - PyObject *elt3=PyTuple_New(4); - PyTuple_SetItem(elt3,0,SWIG_From_int(typesFI[j])); - PyTuple_SetItem(elt3,1,SWIG_NewPointerObj(SWIG_as_voidptr(dadsI[j]),SWIGTYPE_p_ParaMEDMEM__DataArrayDouble, SWIG_POINTER_OWN | 0 )); - PyTuple_SetItem(elt3,2,PyString_FromString(pflsI[j].c_str())); - PyTuple_SetItem(elt3,3,PyString_FromString(locsI[j].c_str())); - PyList_SetItem(elt2,j,elt3); - } - PyTuple_SetItem(elt,1,elt2); - PyList_SetItem(ret2,i,elt); - } - return ret2; - } - - DataArrayDouble *getUndergroundDataArray() const throw(INTERP_KERNEL::Exception) - { - DataArrayDouble *ret=self->getUndergroundDataArray(); - if(ret) - ret->incrRef(); - return ret; - } - - PyObject *getUndergroundDataArrayExt() const throw(INTERP_KERNEL::Exception) - { - std::vector< std::pair<std::pair<INTERP_KERNEL::NormalizedCellType,int>,std::pair<int,int> > > elt1Cpp; - DataArrayDouble *elt0=self->getUndergroundDataArrayExt(elt1Cpp); - if(elt0) - elt0->incrRef(); - PyObject *ret=PyTuple_New(2); - PyTuple_SetItem(ret,0,SWIG_NewPointerObj(SWIG_as_voidptr(elt0),SWIGTYPE_p_ParaMEDMEM__DataArrayDouble, SWIG_POINTER_OWN | 0 )); - std::size_t sz=elt1Cpp.size(); - PyObject *elt=PyList_New(sz); - for(std::size_t i=0;i<sz;i++) - { - PyObject *elt1=PyTuple_New(2); - PyObject *elt2=PyTuple_New(2); - PyTuple_SetItem(elt2,0,SWIG_From_int((int)elt1Cpp[i].first.first)); - PyTuple_SetItem(elt2,1,SWIG_From_int(elt1Cpp[i].first.second)); - PyObject *elt3=PyTuple_New(2); - PyTuple_SetItem(elt3,0,SWIG_From_int(elt1Cpp[i].second.first)); - PyTuple_SetItem(elt3,1,SWIG_From_int(elt1Cpp[i].second.second)); - PyTuple_SetItem(elt1,0,elt2); - PyTuple_SetItem(elt1,1,elt3); - PyList_SetItem(elt,i,elt1); - } - PyTuple_SetItem(ret,1,elt); - return ret; - } - } - }; - - class MEDFileIntField1TS : public MEDFileAnyTypeField1TS - { - public: - static MEDFileIntField1TS *New(); - static MEDFileIntField1TS *New(const std::string& fileName, bool loadAll=true) throw(INTERP_KERNEL::Exception); - static MEDFileIntField1TS *New(const std::string& fileName, const std::string& fieldName, bool loadAll=true) throw(INTERP_KERNEL::Exception); - static MEDFileIntField1TS *New(const std::string& fileName, const std::string& fieldName, int iteration, int order, bool loadAll=true) throw(INTERP_KERNEL::Exception); - ParaMEDMEM::MEDFileField1TS *convertToDouble(bool isDeepCpyGlobs=true) const throw(INTERP_KERNEL::Exception); - // - void setFieldNoProfileSBT(const MEDCouplingFieldDouble *field, const DataArrayInt *arrOfVals) throw(INTERP_KERNEL::Exception); - void setFieldProfile(const MEDCouplingFieldDouble *field, const DataArrayInt *arrOfVals, const MEDFileMesh *mesh, int meshDimRelToMax, const DataArrayInt *profile) throw(INTERP_KERNEL::Exception); - %extend - { - MEDFileIntField1TS() throw(INTERP_KERNEL::Exception) - { - return MEDFileIntField1TS::New(); - } - - MEDFileIntField1TS(const std::string& fileName, bool loadAll=true) throw(INTERP_KERNEL::Exception) - { - return MEDFileIntField1TS::New(fileName,loadAll); - } - - MEDFileIntField1TS(const std::string& fileName, const std::string& fieldName, bool loadAll=true) throw(INTERP_KERNEL::Exception) - { - return MEDFileIntField1TS::New(fileName,fieldName,loadAll); - } - - MEDFileIntField1TS(const std::string& fileName, const std::string& fieldName, int iteration, int order, bool loadAll=true) throw(INTERP_KERNEL::Exception) - { - return MEDFileIntField1TS::New(fileName,fieldName,iteration,order,loadAll); - } - - std::string __str__() const throw(INTERP_KERNEL::Exception) - { - return self->simpleRepr(); - } - - PyObject *getFieldAtLevel(TypeOfField type, int meshDimRelToMax, int renumPol=0) const throw(INTERP_KERNEL::Exception) - { - DataArrayInt *ret1=0; - MEDCouplingFieldDouble *ret0=self->getFieldAtLevel(type,meshDimRelToMax,ret1,renumPol); - PyObject *ret=PyTuple_New(2); - PyTuple_SetItem(ret,0,SWIG_NewPointerObj(SWIG_as_voidptr(ret0),SWIGTYPE_p_ParaMEDMEM__MEDCouplingFieldDouble, SWIG_POINTER_OWN | 0 )); - PyTuple_SetItem(ret,1,SWIG_NewPointerObj(SWIG_as_voidptr(ret1),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 )); - return ret; - } - - PyObject *getFieldAtTopLevel(TypeOfField type, int renumPol=0) const throw(INTERP_KERNEL::Exception) - { - DataArrayInt *ret1=0; - MEDCouplingFieldDouble *ret0=self->getFieldAtTopLevel(type,ret1,renumPol); - PyObject *ret=PyTuple_New(2); - PyTuple_SetItem(ret,0,SWIG_NewPointerObj(SWIG_as_voidptr(ret0),SWIGTYPE_p_ParaMEDMEM__MEDCouplingFieldDouble, SWIG_POINTER_OWN | 0 )); - PyTuple_SetItem(ret,1,SWIG_NewPointerObj(SWIG_as_voidptr(ret1),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 )); - return ret; - } - - PyObject *getFieldOnMeshAtLevel(TypeOfField type, int meshDimRelToMax, const MEDFileMesh *mesh, int renumPol=0) const throw(INTERP_KERNEL::Exception) - { - DataArrayInt *ret1=0; - MEDCouplingFieldDouble *ret0=self->getFieldOnMeshAtLevel(type,meshDimRelToMax,mesh,ret1,renumPol); - PyObject *ret=PyTuple_New(2); - PyTuple_SetItem(ret,0,SWIG_NewPointerObj(SWIG_as_voidptr(ret0),SWIGTYPE_p_ParaMEDMEM__MEDCouplingFieldDouble, SWIG_POINTER_OWN | 0 )); - PyTuple_SetItem(ret,1,SWIG_NewPointerObj(SWIG_as_voidptr(ret1),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 )); - return ret; - } - - PyObject *getFieldOnMeshAtLevel(TypeOfField type, const MEDCouplingMesh *mesh, int renumPol=0) const throw(INTERP_KERNEL::Exception) - { - DataArrayInt *ret1=0; - MEDCouplingFieldDouble *ret0=self->getFieldOnMeshAtLevel(type,mesh,ret1,renumPol); - PyObject *ret=PyTuple_New(2); - PyTuple_SetItem(ret,0,SWIG_NewPointerObj(SWIG_as_voidptr(ret0),SWIGTYPE_p_ParaMEDMEM__MEDCouplingFieldDouble, SWIG_POINTER_OWN | 0 )); - PyTuple_SetItem(ret,1,SWIG_NewPointerObj(SWIG_as_voidptr(ret1),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 )); - return ret; - } - - PyObject *getFieldAtLevelOld(TypeOfField type, const std::string& mname, int meshDimRelToMax, int renumPol=0) const throw(INTERP_KERNEL::Exception) - { - DataArrayInt *ret1=0; - MEDCouplingFieldDouble *ret0=self->getFieldAtLevelOld(type,mname,meshDimRelToMax,ret1,renumPol); - PyObject *ret=PyTuple_New(2); - PyTuple_SetItem(ret,0,SWIG_NewPointerObj(SWIG_as_voidptr(ret0),SWIGTYPE_p_ParaMEDMEM__MEDCouplingFieldDouble, SWIG_POINTER_OWN | 0 )); - PyTuple_SetItem(ret,1,SWIG_NewPointerObj(SWIG_as_voidptr(ret1),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 )); - return ret; - } - - PyObject *getFieldWithProfile(TypeOfField type, int meshDimRelToMax, const MEDFileMesh *mesh) const throw(INTERP_KERNEL::Exception) - { - DataArrayInt *ret1=0; - DataArrayInt *ret0=self->getFieldWithProfile(type,meshDimRelToMax,mesh,ret1); - PyObject *ret=PyTuple_New(2); - PyTuple_SetItem(ret,0,SWIG_NewPointerObj(SWIG_as_voidptr(ret0),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 )); - PyTuple_SetItem(ret,1,SWIG_NewPointerObj(SWIG_as_voidptr(ret1),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 )); - return ret; - } - - DataArrayInt *getUndergroundDataArray() const throw(INTERP_KERNEL::Exception) - { - DataArrayInt *ret=self->getUndergroundDataArray(); - if(ret) - ret->incrRef(); - return ret; - } - } - }; - - class MEDFileAnyTypeFieldMultiTSIterator - { - public: - %extend - { - PyObject *next() throw(INTERP_KERNEL::Exception) - { - MEDFileAnyTypeField1TS *ret=self->nextt(); - if(ret) - return convertMEDFileField1TS(ret, SWIG_POINTER_OWN | 0 ); - else - { - PyErr_SetString(PyExc_StopIteration,"No more data."); - return 0; - } - } - } - }; - - class MEDFileAnyTypeFieldMultiTS : public RefCountObject, public MEDFileFieldGlobsReal, public MEDFileWritable - { - public: - static MEDFileAnyTypeFieldMultiTS *New(const std::string& fileName, bool loadAll=true) throw(INTERP_KERNEL::Exception); - static MEDFileAnyTypeFieldMultiTS *New(const std::string& fileName, const std::string& fieldName, bool loadAll=true) throw(INTERP_KERNEL::Exception); - MEDFileAnyTypeFieldMultiTS *deepCpy() const throw(INTERP_KERNEL::Exception); - virtual MEDFileAnyTypeFieldMultiTS *shallowCpy() const throw(INTERP_KERNEL::Exception); - std::string getName() const throw(INTERP_KERNEL::Exception); - void setName(const std::string& name) throw(INTERP_KERNEL::Exception); - std::string getDtUnit() const throw(INTERP_KERNEL::Exception); - void setDtUnit(const std::string& dtUnit) throw(INTERP_KERNEL::Exception); - std::string getMeshName() const throw(INTERP_KERNEL::Exception); - void setMeshName(const std::string& newMeshName) throw(INTERP_KERNEL::Exception); - const std::vector<std::string>& getInfo() const throw(INTERP_KERNEL::Exception); - bool presenceOfMultiDiscPerGeoType() const throw(INTERP_KERNEL::Exception); - int getNumberOfComponents() const throw(INTERP_KERNEL::Exception); - int getNumberOfTS() const throw(INTERP_KERNEL::Exception); - void eraseEmptyTS() throw(INTERP_KERNEL::Exception); - int getPosOfTimeStep(int iteration, int order) const throw(INTERP_KERNEL::Exception); - int getPosGivenTime(double time, double eps=1e-8) const throw(INTERP_KERNEL::Exception); - void write(const std::string& fileName, int mode) const throw(INTERP_KERNEL::Exception); - void loadArrays() throw(INTERP_KERNEL::Exception); - void loadArraysIfNecessary() throw(INTERP_KERNEL::Exception); - void unloadArrays() throw(INTERP_KERNEL::Exception); - void unloadArraysWithoutDataLoss() throw(INTERP_KERNEL::Exception); - // - virtual MEDFileAnyTypeField1TS *getTimeStepAtPos(int pos) const throw(INTERP_KERNEL::Exception); - MEDFileAnyTypeField1TS *getTimeStep(int iteration, int order) const throw(INTERP_KERNEL::Exception); - MEDFileAnyTypeField1TS *getTimeStepGivenTime(double time, double eps=1e-8) const throw(INTERP_KERNEL::Exception); - void pushBackTimeStep(MEDFileAnyTypeField1TS *f1ts) throw(INTERP_KERNEL::Exception); - void synchronizeNameScope() throw(INTERP_KERNEL::Exception); - %extend - { - int __len__() const throw(INTERP_KERNEL::Exception) - { - return self->getNumberOfTS(); - } - - int getTimeId(PyObject *elt0) const throw(INTERP_KERNEL::Exception) - { - if(elt0 && PyInt_Check(elt0)) - {//fmts[3] - int pos=PyInt_AS_LONG(elt0); - return pos; - } - else if(elt0 && PyTuple_Check(elt0)) - { - if(PyTuple_Size(elt0)==2) - { - PyObject *o0=PyTuple_GetItem(elt0,0); - PyObject *o1=PyTuple_GetItem(elt0,1); - if(PyInt_Check(o0) && PyInt_Check(o1)) - {//fmts(1,-1) - int iter=PyInt_AS_LONG(o0); - int order=PyInt_AS_LONG(o1); - return self->getPosOfTimeStep(iter,order); - } - else - throw INTERP_KERNEL::Exception("MEDFileAnyTypeFieldMultiTS::__getitem__ : invalid input param ! input is a tuple of size 2 but two integers are expected in this tuple to request a time steps !"); - } - else - throw INTERP_KERNEL::Exception("MEDFileAnyTypeFieldMultiTS::__getitem__ : invalid input param ! input is a tuple of size != 2 ! two integers are expected in this tuple to request a time steps !"); - } - else if(elt0 && PyFloat_Check(elt0)) - { - double val=PyFloat_AS_DOUBLE(elt0); - return self->getPosGivenTime(val); - } - else - throw INTERP_KERNEL::Exception("MEDFileAnyTypeFieldMultiTS::__getitem__ : invalid input params ! expected fmts[int], fmts[int,int] or fmts[double] to request time step !"); - } - - PyObject *getIterations() const throw(INTERP_KERNEL::Exception) - { - std::vector< std::pair<int,int> > res=self->getIterations(); - PyObject *ret=PyList_New(res.size()); - int rk=0; - for(std::vector< std::pair<int,int> >::const_iterator iter=res.begin();iter!=res.end();iter++,rk++) - { - PyObject *elt=PyTuple_New(2); - PyTuple_SetItem(elt,0,SWIG_From_int((*iter).first)); - PyTuple_SetItem(elt,1,SWIG_From_int((*iter).second)); - PyList_SetItem(ret,rk,elt); - } - return ret; - } - - PyObject *getTimeSteps() const throw(INTERP_KERNEL::Exception) - { - std::vector<double> ret1; - std::vector< std::pair<int,int> > ret=self->getTimeSteps(ret1); - std::size_t sz=ret.size(); - PyObject *ret2=PyList_New(sz); - for(std::size_t i=0;i<sz;i++) - { - PyObject *elt=PyTuple_New(3); - PyTuple_SetItem(elt,0,SWIG_From_int(ret[i].first)); - PyTuple_SetItem(elt,1,SWIG_From_int(ret[i].second)); - PyTuple_SetItem(elt,2,SWIG_From_double(ret1[i])); - PyList_SetItem(ret2,i,elt); - } - return ret2; - } - - PyObject *getTypesOfFieldAvailable() const throw(INTERP_KERNEL::Exception) - { - std::vector< std::vector<TypeOfField> > ret=self->getTypesOfFieldAvailable(); - PyObject *ret2=PyList_New(ret.size()); - for(int i=0;i<(int)ret.size();i++) - { - const std::vector<TypeOfField>& rett=ret[i]; - PyObject *ret3=PyList_New(rett.size()); - for(int j=0;j<(int)rett.size();j++) - PyList_SetItem(ret3,j,SWIG_From_int(rett[j])); - PyList_SetItem(ret2,i,ret3); - } - return ret2; - } - - PyObject *getNonEmptyLevels(int iteration, int order, const std::string& mname=std::string()) const throw(INTERP_KERNEL::Exception) - { - std::vector<int> ret1; - int ret0=self->getNonEmptyLevels(iteration,order,mname,ret1); - PyObject *elt=PyTuple_New(2); - PyTuple_SetItem(elt,0,SWIG_From_int(ret0)); - PyTuple_SetItem(elt,1,convertIntArrToPyList2(ret1)); - return elt; - } - - PyObject *getFieldSplitedByType(int iteration, int order, const std::string& mname=std::string()) const throw(INTERP_KERNEL::Exception) - { - std::vector<INTERP_KERNEL::NormalizedCellType> types; - std::vector< std::vector<TypeOfField> > typesF; - std::vector< std::vector<std::string> > pfls; - std::vector< std::vector<std::string> > locs; - std::vector< std::vector< std::pair<int,int> > > ret=self->getFieldSplitedByType(iteration,order,mname,types,typesF,pfls,locs); - int sz=ret.size(); - PyObject *ret2=PyList_New(sz); - for(int i=0;i<sz;i++) - { - const std::vector< std::pair<int,int> >& dadsI=ret[i]; - const std::vector<TypeOfField>& typesFI=typesF[i]; - const std::vector<std::string>& pflsI=pfls[i]; - const std::vector<std::string>& locsI=locs[i]; - PyObject *elt=PyTuple_New(2); - PyTuple_SetItem(elt,0,SWIG_From_int(types[i])); - int sz2=ret[i].size(); - PyObject *elt2=PyList_New(sz2); - for(int j=0;j<sz2;j++) - { - PyObject *elt3=PyTuple_New(4); - PyTuple_SetItem(elt3,0,SWIG_From_int(typesFI[j])); - PyObject *elt4=PyTuple_New(2); PyTuple_SetItem(elt4,0,SWIG_From_int(dadsI[j].first)); PyTuple_SetItem(elt4,1,SWIG_From_int(dadsI[j].second)); - PyTuple_SetItem(elt3,1,elt4); - PyTuple_SetItem(elt3,2,PyString_FromString(pflsI[j].c_str())); - PyTuple_SetItem(elt3,3,PyString_FromString(locsI[j].c_str())); - PyList_SetItem(elt2,j,elt3); - } - PyTuple_SetItem(elt,1,elt2); - PyList_SetItem(ret2,i,elt); - } - return ret2; - } - - std::vector<int> getTimeIds(PyObject *elts) const throw(INTERP_KERNEL::Exception) - { - if(PyList_Check(elts)) - { - int sz=PyList_Size(elts); - std::vector<int> ret(sz); - for(int i=0;i<sz;i++) - { - PyObject *elt=PyList_GetItem(elts,i); - ret[i]=ParaMEDMEM_MEDFileAnyTypeFieldMultiTS_getTimeId(self,elt); - } - return ret; - } - else - { - std::vector<int> ret(1); - ret[0]=ParaMEDMEM_MEDFileAnyTypeFieldMultiTS_getTimeId(self,elts); - return ret; - } - } - - void __delitem__(PyObject *elts) throw(INTERP_KERNEL::Exception) - { - if(PySlice_Check(elts)) - { - Py_ssize_t strt=2,stp=2,step=2; - PySliceObject *oC=reinterpret_cast<PySliceObject *>(elts); - GetIndicesOfSlice(oC,self->getNumberOfTS(),&strt,&stp,&step,"MEDFileAnyTypeFieldMultiTS.__delitem__ : error in input slice !"); - self->eraseTimeStepIds2(strt,stp,step); - } - else - { - std::vector<int> idsToRemove=ParaMEDMEM_MEDFileAnyTypeFieldMultiTS_getTimeIds(self,elts); - if(!idsToRemove.empty()) - self->eraseTimeStepIds(&idsToRemove[0],&idsToRemove[0]+idsToRemove.size()); - } - } - - void eraseTimeStepIds(PyObject *li) throw(INTERP_KERNEL::Exception) - { - int sw; - int pos1; - std::vector<int> pos2; - DataArrayInt *pos3=0; - DataArrayIntTuple *pos4=0; - convertObjToPossibleCpp1(li,sw,pos1,pos2,pos3,pos4); - switch(sw) - { - case 1: - { - self->eraseTimeStepIds(&pos1,&pos1+1); - return; - } - case 2: - { - if(pos2.empty()) - return; - self->eraseTimeStepIds(&pos2[0],&pos2[0]+pos2.size()); - return ; - } - case 3: - { - self->eraseTimeStepIds(pos3->begin(),pos3->end()); - return ; - } - default: - throw INTERP_KERNEL::Exception("MEDFileAnyTypeFieldMultiTS::eraseTimeStepIds : unexpected input array type recognized !"); - } - } - - MEDFileAnyTypeFieldMultiTSIterator *__iter__() throw(INTERP_KERNEL::Exception) - { - return self->iterator(); - } - - PyObject *__getitem__(PyObject *elt0) const throw(INTERP_KERNEL::Exception) - { - if(elt0 && PyList_Check(elt0)) - { - int sz=PyList_Size(elt0); - MEDCouplingAutoRefCountObjectPtr<DataArrayInt> da=DataArrayInt::New(); da->alloc(sz,1); - int *pt=da->getPointer(); - for(int i=0;i<sz;i++,pt++) - { - PyObject *elt1=PyList_GetItem(elt0,i); - *pt=MEDFileAnyTypeFieldMultiTSgetitemSingleTS__(self,elt1); - } - return convertMEDFileFieldMultiTS(self->buildSubPart(da->begin(),da->end()),SWIG_POINTER_OWN | 0); - } - else if(elt0 && PySlice_Check(elt0)) - { - Py_ssize_t strt=2,stp=2,step=2; - PySliceObject *oC=reinterpret_cast<PySliceObject *>(elt0); - GetIndicesOfSlice(oC,self->getNumberOfTS(),&strt,&stp,&step,"MEDFileAnyTypeFieldMultiTS.__getitem__ : error in input slice !"); - return convertMEDFileFieldMultiTS(self->buildSubPartSlice(strt,stp,step),SWIG_POINTER_OWN | 0); - } - else - return convertMEDFileField1TS(self->getTimeStepAtPos(MEDFileAnyTypeFieldMultiTSgetitemSingleTS__(self,elt0)),SWIG_POINTER_OWN | 0); - } - - bool changeMeshNames(PyObject *li) throw(INTERP_KERNEL::Exception) - { - std::vector< std::pair<std::string,std::string> > modifTab=convertVecPairStStFromPy(li); - return self->changeMeshNames(modifTab); - } - - PyObject *splitComponents() const throw(INTERP_KERNEL::Exception) - { - std::vector< MEDCouplingAutoRefCountObjectPtr< MEDFileAnyTypeFieldMultiTS > > ret=self->splitComponents(); - std::size_t sz=ret.size(); - PyObject *retPy=PyList_New(sz); - for(std::size_t i=0;i<sz;i++) - PyList_SetItem(retPy,i,convertMEDFileFieldMultiTS(ret[i].retn(), SWIG_POINTER_OWN | 0 )); - return retPy; - } - - PyObject *splitDiscretizations() const throw(INTERP_KERNEL::Exception) - { - std::vector< MEDCouplingAutoRefCountObjectPtr< MEDFileAnyTypeFieldMultiTS > > ret=self->splitDiscretizations(); - std::size_t sz=ret.size(); - PyObject *retPy=PyList_New(sz); - for(std::size_t i=0;i<sz;i++) - PyList_SetItem(retPy,i,convertMEDFileFieldMultiTS(ret[i].retn(), SWIG_POINTER_OWN | 0 )); - return retPy; - } - - PyObject *splitMultiDiscrPerGeoTypes() const throw(INTERP_KERNEL::Exception) - { - std::vector< MEDCouplingAutoRefCountObjectPtr< MEDFileAnyTypeFieldMultiTS > > ret=self->splitMultiDiscrPerGeoTypes(); - std::size_t sz=ret.size(); - PyObject *retPy=PyList_New(sz); - for(std::size_t i=0;i<sz;i++) - PyList_SetItem(retPy,i,convertMEDFileFieldMultiTS(ret[i].retn(), SWIG_POINTER_OWN | 0 )); - return retPy; - } - - void pushBackTimeSteps(PyObject *li) throw(INTERP_KERNEL::Exception) - { - void *argp(0); - int status(SWIG_ConvertPtr(li,&argp,SWIGTYPE_p_ParaMEDMEM__MEDFileAnyTypeFieldMultiTS,0|0)); - if(SWIG_IsOK(status)) - { - self->pushBackTimeSteps(reinterpret_cast<MEDFileAnyTypeFieldMultiTS *>(argp)); - } - else - { - std::vector<MEDFileAnyTypeField1TS *> tmp; - convertFromPyObjVectorOfObj<ParaMEDMEM::MEDFileAnyTypeField1TS *>(li,SWIGTYPE_p_ParaMEDMEM__MEDFileAnyTypeField1TS,"MEDFileAnyTypeField1TS",tmp); - self->pushBackTimeSteps(tmp); - } - } - - static PyObject *MEDFileAnyTypeFieldMultiTS::SplitIntoCommonTimeSeries(PyObject *li) throw(INTERP_KERNEL::Exception) - { - std::vector<MEDFileAnyTypeFieldMultiTS *> vectFMTS; - convertFromPyObjVectorOfObj<ParaMEDMEM::MEDFileAnyTypeFieldMultiTS *>(li,SWIGTYPE_p_ParaMEDMEM__MEDFileAnyTypeFieldMultiTS,"MEDFileAnyTypeFieldMultiTS",vectFMTS); - std::vector< std::vector<MEDFileAnyTypeFieldMultiTS *> > ret=MEDFileAnyTypeFieldMultiTS::SplitIntoCommonTimeSeries(vectFMTS); - std::size_t sz=ret.size(); - PyObject *retPy=PyList_New(sz); - for(std::size_t i=0;i<sz;i++) - { - std::size_t sz2=ret[i].size(); - PyObject *ret1Py=PyList_New(sz2); - for(std::size_t j=0;j<sz2;j++) - { - MEDFileAnyTypeFieldMultiTS *elt(ret[i][j]); - if(elt) - elt->incrRef(); - PyList_SetItem(ret1Py,j,convertMEDFileFieldMultiTS(elt,SWIG_POINTER_OWN | 0 )); - } - PyList_SetItem(retPy,i,ret1Py); - } - return retPy; - } - - static PyObject *MEDFileAnyTypeFieldMultiTS::SplitPerCommonSupport(PyObject *li, const MEDFileMesh *mesh) throw(INTERP_KERNEL::Exception) - { - std::vector<MEDFileAnyTypeFieldMultiTS *> vectFMTS; - convertFromPyObjVectorOfObj<ParaMEDMEM::MEDFileAnyTypeFieldMultiTS *>(li,SWIGTYPE_p_ParaMEDMEM__MEDFileAnyTypeFieldMultiTS,"MEDFileAnyTypeFieldMultiTS",vectFMTS); - std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileFastCellSupportComparator> > ret2; - std::vector< std::vector<MEDFileAnyTypeFieldMultiTS *> > ret=MEDFileAnyTypeFieldMultiTS::SplitPerCommonSupport(vectFMTS,mesh,ret2); - if(ret2.size()!=ret.size()) - { - std::ostringstream oss; oss << "MEDFileAnyTypeFieldMultiTS::SplitPerCommonSupport (PyWrap) : internal error ! Size of 2 vectors must match ! (" << ret.size() << "!=" << ret2.size() << ") !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - std::size_t sz=ret.size(); - PyObject *retPy=PyList_New(sz); - for(std::size_t i=0;i<sz;i++) - { - std::size_t sz2=ret[i].size(); - PyObject *ret0Py=PyTuple_New(2); - PyObject *ret1Py=PyList_New(sz2); - for(std::size_t j=0;j<sz2;j++) - { - MEDFileAnyTypeFieldMultiTS *elt(ret[i][j]); - if(elt) - elt->incrRef(); - PyList_SetItem(ret1Py,j,convertMEDFileFieldMultiTS(elt,SWIG_POINTER_OWN | 0 )); - } - PyTuple_SetItem(ret0Py,0,ret1Py); - PyTuple_SetItem(ret0Py,1,SWIG_NewPointerObj(SWIG_as_voidptr(ret2[i].retn()),SWIGTYPE_p_ParaMEDMEM__MEDFileFastCellSupportComparator, SWIG_POINTER_OWN | 0 )); - PyList_SetItem(retPy,i,ret0Py); - } - return retPy; - } - } - }; - - class MEDFileFieldMultiTS : public MEDFileAnyTypeFieldMultiTS - { - public: - static MEDFileFieldMultiTS *New() throw(INTERP_KERNEL::Exception); - static MEDFileFieldMultiTS *New(const std::string& fileName, bool loadAll=true) throw(INTERP_KERNEL::Exception); - static MEDFileFieldMultiTS *New(const std::string& fileName, const std::string& fieldName, bool loadAll=true) throw(INTERP_KERNEL::Exception); - // - MEDCouplingFieldDouble *getFieldAtLevel(TypeOfField type, int iteration, int order, int meshDimRelToMax, int renumPol=0) const throw(INTERP_KERNEL::Exception); - MEDCouplingFieldDouble *getFieldAtTopLevel(TypeOfField type, int iteration, int order, int renumPol=0) const throw(INTERP_KERNEL::Exception); - MEDCouplingFieldDouble *getFieldOnMeshAtLevel(TypeOfField type, int iteration, int order, int meshDimRelToMax, const MEDFileMesh *mesh, int renumPol=0) const throw(INTERP_KERNEL::Exception); - MEDCouplingFieldDouble *getFieldOnMeshAtLevel(TypeOfField type, int iteration, int order, const MEDCouplingMesh *mesh, int renumPol=0) const throw(INTERP_KERNEL::Exception); - MEDCouplingFieldDouble *getFieldAtLevelOld(TypeOfField type, const std::string& mname, int iteration, int order, int meshDimRelToMax, int renumPol=0) const throw(INTERP_KERNEL::Exception); - // - void appendFieldNoProfileSBT(const MEDCouplingFieldDouble *field) throw(INTERP_KERNEL::Exception); - void appendFieldProfile(const MEDCouplingFieldDouble *field, const MEDFileMesh *mesh, int meshDimRelToMax, const DataArrayInt *profile) throw(INTERP_KERNEL::Exception); - ParaMEDMEM::MEDFileIntFieldMultiTS *convertToInt(bool isDeepCpyGlobs=true) const throw(INTERP_KERNEL::Exception); - %extend - { - MEDFileFieldMultiTS() - { - return MEDFileFieldMultiTS::New(); - } - - MEDFileFieldMultiTS(const std::string& fileName, bool loadAll=true) throw(INTERP_KERNEL::Exception) - { - return MEDFileFieldMultiTS::New(fileName,loadAll); - } - - MEDFileFieldMultiTS(const std::string& fileName, const std::string& fieldName, bool loadAll=true) throw(INTERP_KERNEL::Exception) - { - return MEDFileFieldMultiTS::New(fileName,fieldName,loadAll); - } - - static MEDFileFieldMultiTS *LoadSpecificEntities(const std::string& fileName, const std::string& fieldName, PyObject *entities, bool loadAll=true) - { - std::vector<std::pair<int,int> > tmp(convertTimePairIdsFromPy(entities)); - std::size_t sz(tmp.size()); - std::vector< std::pair<TypeOfField,INTERP_KERNEL::NormalizedCellType> > entitiesCpp(sz); - for(std::size_t i=0;i<sz;i++) - { - entitiesCpp[i].first=(TypeOfField)tmp[i].first; - entitiesCpp[i].second=(INTERP_KERNEL::NormalizedCellType)tmp[i].second; - } - return MEDFileFieldMultiTS::LoadSpecificEntities(fileName,fieldName,entitiesCpp,loadAll); - } - - std::string __str__() const throw(INTERP_KERNEL::Exception) - { - return self->simpleRepr(); - } - - PyObject *getFieldWithProfile(TypeOfField type, int iteration, int order, int meshDimRelToMax, const MEDFileMesh *mesh) const throw(INTERP_KERNEL::Exception) - { - DataArrayInt *ret1=0; - DataArrayDouble *ret0=self->getFieldWithProfile(type,iteration,order,meshDimRelToMax,mesh,ret1); - PyObject *ret=PyTuple_New(2); - PyTuple_SetItem(ret,0,SWIG_NewPointerObj(SWIG_as_voidptr(ret0),SWIGTYPE_p_ParaMEDMEM__DataArrayDouble, SWIG_POINTER_OWN | 0 )); - PyTuple_SetItem(ret,1,SWIG_NewPointerObj(SWIG_as_voidptr(ret1),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 )); - return ret; - } - - PyObject *getFieldSplitedByType2(int iteration, int order, const std::string& mname=std::string()) const throw(INTERP_KERNEL::Exception) - { - std::vector<INTERP_KERNEL::NormalizedCellType> types; - std::vector< std::vector<TypeOfField> > typesF; - std::vector< std::vector<std::string> > pfls; - std::vector< std::vector<std::string> > locs; - std::vector< std::vector<DataArrayDouble *> > ret=self->getFieldSplitedByType2(iteration,order,mname,types,typesF,pfls,locs); - int sz=ret.size(); - PyObject *ret2=PyList_New(sz); - for(int i=0;i<sz;i++) - { - const std::vector<DataArrayDouble *>& dadsI=ret[i]; - const std::vector<TypeOfField>& typesFI=typesF[i]; - const std::vector<std::string>& pflsI=pfls[i]; - const std::vector<std::string>& locsI=locs[i]; - PyObject *elt=PyTuple_New(2); - PyTuple_SetItem(elt,0,SWIG_From_int(types[i])); - int sz2=ret[i].size(); - PyObject *elt2=PyList_New(sz2); - for(int j=0;j<sz2;j++) - { - PyObject *elt3=PyTuple_New(4); - PyTuple_SetItem(elt3,0,SWIG_From_int(typesFI[j])); - PyTuple_SetItem(elt3,1,SWIG_NewPointerObj(SWIG_as_voidptr(dadsI[j]),SWIGTYPE_p_ParaMEDMEM__DataArrayDouble, SWIG_POINTER_OWN | 0 )); - PyTuple_SetItem(elt3,2,PyString_FromString(pflsI[j].c_str())); - PyTuple_SetItem(elt3,3,PyString_FromString(locsI[j].c_str())); - PyList_SetItem(elt2,j,elt3); - } - PyTuple_SetItem(elt,1,elt2); - PyList_SetItem(ret2,i,elt); - } - return ret2; - } - DataArrayDouble *getUndergroundDataArray(int iteration, int order) const throw(INTERP_KERNEL::Exception) - { - DataArrayDouble *ret=self->getUndergroundDataArray(iteration,order); - if(ret) - ret->incrRef(); - return ret; - } - - PyObject *getUndergroundDataArrayExt(int iteration, int order) const throw(INTERP_KERNEL::Exception) - { - std::vector< std::pair<std::pair<INTERP_KERNEL::NormalizedCellType,int>,std::pair<int,int> > > elt1Cpp; - DataArrayDouble *elt0=self->getUndergroundDataArrayExt(iteration,order,elt1Cpp); - if(elt0) - elt0->incrRef(); - PyObject *ret=PyTuple_New(2); - PyTuple_SetItem(ret,0,SWIG_NewPointerObj(SWIG_as_voidptr(elt0),SWIGTYPE_p_ParaMEDMEM__DataArrayDouble, SWIG_POINTER_OWN | 0 )); - std::size_t sz=elt1Cpp.size(); - PyObject *elt=PyList_New(sz); - for(std::size_t i=0;i<sz;i++) - { - PyObject *elt1=PyTuple_New(2); - PyObject *elt2=PyTuple_New(2); - PyTuple_SetItem(elt2,0,SWIG_From_int(elt1Cpp[i].first.first)); - PyTuple_SetItem(elt2,1,SWIG_From_int(elt1Cpp[i].first.second)); - PyObject *elt3=PyTuple_New(2); - PyTuple_SetItem(elt3,0,SWIG_From_int(elt1Cpp[i].second.first)); - PyTuple_SetItem(elt3,1,SWIG_From_int(elt1Cpp[i].second.second)); - PyTuple_SetItem(elt1,0,elt2); - PyTuple_SetItem(elt1,1,elt3); - PyList_SetItem(elt,i,elt1); - } - PyTuple_SetItem(ret,1,elt); - return ret; - } - } - }; - - class MEDFileFieldsIterator - { - public: - %extend - { - PyObject *next() throw(INTERP_KERNEL::Exception) - { - MEDFileAnyTypeFieldMultiTS *ret=self->nextt(); - if(ret) - return convertMEDFileFieldMultiTS(ret, SWIG_POINTER_OWN | 0 ); - else - { - PyErr_SetString(PyExc_StopIteration,"No more data."); - return 0; - } - } - } - }; - - class MEDFileIntFieldMultiTS : public MEDFileAnyTypeFieldMultiTS - { - public: - static MEDFileIntFieldMultiTS *New(); - static MEDFileIntFieldMultiTS *New(const std::string& fileName, bool loadAll=true) throw(INTERP_KERNEL::Exception); - static MEDFileIntFieldMultiTS *New(const std::string& fileName, const std::string& fieldName, bool loadAll=true) throw(INTERP_KERNEL::Exception); - // - void appendFieldNoProfileSBT(const MEDCouplingFieldDouble *field, const DataArrayInt *arrOfVals) throw(INTERP_KERNEL::Exception); - void appendFieldProfile(const MEDCouplingFieldDouble *field, const DataArrayInt *arrOfVals, const MEDFileMesh *mesh, int meshDimRelToMax, const DataArrayInt *profile) throw(INTERP_KERNEL::Exception); - ParaMEDMEM::MEDFileFieldMultiTS *convertToDouble(bool isDeepCpyGlobs=true) const throw(INTERP_KERNEL::Exception); - %extend - { - MEDFileIntFieldMultiTS() - { - return MEDFileIntFieldMultiTS::New(); - } - - MEDFileIntFieldMultiTS(const std::string& fileName, bool loadAll=true) throw(INTERP_KERNEL::Exception) - { - return MEDFileIntFieldMultiTS::New(fileName,loadAll); - } - - MEDFileIntFieldMultiTS(const std::string& fileName, const std::string& fieldName, bool loadAll=true) throw(INTERP_KERNEL::Exception) - { - return MEDFileIntFieldMultiTS::New(fileName,fieldName,loadAll); - } - - static MEDFileIntFieldMultiTS *LoadSpecificEntities(const std::string& fileName, const std::string& fieldName, PyObject *entities, bool loadAll=true) - { - std::vector<std::pair<int,int> > tmp(convertTimePairIdsFromPy(entities)); - std::size_t sz(tmp.size()); - std::vector< std::pair<TypeOfField,INTERP_KERNEL::NormalizedCellType> > entitiesCpp(sz); - for(std::size_t i=0;i<sz;i++) - { - entitiesCpp[i].first=(TypeOfField)tmp[i].first; - entitiesCpp[i].second=(INTERP_KERNEL::NormalizedCellType)tmp[i].second; - } - return MEDFileIntFieldMultiTS::LoadSpecificEntities(fileName,fieldName,entitiesCpp,loadAll); - } - - std::string __str__() const throw(INTERP_KERNEL::Exception) - { - return self->simpleRepr(); - } - - PyObject *getFieldAtLevel(TypeOfField type, int iteration, int order, int meshDimRelToMax, int renumPol=0) const throw(INTERP_KERNEL::Exception) - { - DataArrayInt *ret1=0; - MEDCouplingFieldDouble *ret0=self->getFieldAtLevel(type,iteration,order,meshDimRelToMax,ret1,renumPol); - PyObject *ret=PyTuple_New(2); - PyTuple_SetItem(ret,0,SWIG_NewPointerObj(SWIG_as_voidptr(ret0),SWIGTYPE_p_ParaMEDMEM__MEDCouplingFieldDouble, SWIG_POINTER_OWN | 0 )); - PyTuple_SetItem(ret,1,SWIG_NewPointerObj(SWIG_as_voidptr(ret1),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 )); - return ret; - } - - PyObject *getFieldAtTopLevel(TypeOfField type, int iteration, int order, int renumPol=0) const throw(INTERP_KERNEL::Exception) - { - DataArrayInt *ret1=0; - MEDCouplingFieldDouble *ret0=self->getFieldAtTopLevel(type,iteration,order,ret1,renumPol); - PyObject *ret=PyTuple_New(2); - PyTuple_SetItem(ret,0,SWIG_NewPointerObj(SWIG_as_voidptr(ret0),SWIGTYPE_p_ParaMEDMEM__MEDCouplingFieldDouble, SWIG_POINTER_OWN | 0 )); - PyTuple_SetItem(ret,1,SWIG_NewPointerObj(SWIG_as_voidptr(ret1),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 )); - return ret; - } - - PyObject *getFieldOnMeshAtLevel(TypeOfField type, int iteration, int order, int meshDimRelToMax, const MEDFileMesh *mesh, int renumPol=0) const throw(INTERP_KERNEL::Exception) - { - DataArrayInt *ret1=0; - MEDCouplingFieldDouble *ret0=self->getFieldOnMeshAtLevel(type,iteration,order,meshDimRelToMax,mesh,ret1,renumPol); - PyObject *ret=PyTuple_New(2); - PyTuple_SetItem(ret,0,SWIG_NewPointerObj(SWIG_as_voidptr(ret0),SWIGTYPE_p_ParaMEDMEM__MEDCouplingFieldDouble, SWIG_POINTER_OWN | 0 )); - PyTuple_SetItem(ret,1,SWIG_NewPointerObj(SWIG_as_voidptr(ret1),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 )); - return ret; - } - - PyObject *getFieldOnMeshAtLevel(TypeOfField type, int iteration, int order, const MEDCouplingMesh *mesh, int renumPol=0) const throw(INTERP_KERNEL::Exception) - { - DataArrayInt *ret1=0; - MEDCouplingFieldDouble *ret0=self->getFieldOnMeshAtLevel(type,iteration,order,mesh,ret1,renumPol); - PyObject *ret=PyTuple_New(2); - PyTuple_SetItem(ret,0,SWIG_NewPointerObj(SWIG_as_voidptr(ret0),SWIGTYPE_p_ParaMEDMEM__MEDCouplingFieldDouble, SWIG_POINTER_OWN | 0 )); - PyTuple_SetItem(ret,1,SWIG_NewPointerObj(SWIG_as_voidptr(ret1),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 )); - return ret; - } - - PyObject *getFieldAtLevelOld(TypeOfField type, int iteration, int order, const std::string& mname, int meshDimRelToMax, int renumPol=0) const throw(INTERP_KERNEL::Exception) - { - DataArrayInt *ret1=0; - MEDCouplingFieldDouble *ret0=self->getFieldAtLevelOld(type,iteration,order,mname,meshDimRelToMax,ret1,renumPol); - PyObject *ret=PyTuple_New(2); - PyTuple_SetItem(ret,0,SWIG_NewPointerObj(SWIG_as_voidptr(ret0),SWIGTYPE_p_ParaMEDMEM__MEDCouplingFieldDouble, SWIG_POINTER_OWN | 0 )); - PyTuple_SetItem(ret,1,SWIG_NewPointerObj(SWIG_as_voidptr(ret1),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 )); - return ret; - } - - PyObject *getFieldWithProfile(TypeOfField type, int iteration, int order, int meshDimRelToMax, const MEDFileMesh *mesh) const throw(INTERP_KERNEL::Exception) - { - DataArrayInt *ret1=0; - DataArrayInt *ret0=self->getFieldWithProfile(type,iteration,order,meshDimRelToMax,mesh,ret1); - PyObject *ret=PyTuple_New(2); - PyTuple_SetItem(ret,0,SWIG_NewPointerObj(SWIG_as_voidptr(ret0),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 )); - PyTuple_SetItem(ret,1,SWIG_NewPointerObj(SWIG_as_voidptr(ret1),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 )); - return ret; - } - - DataArrayInt *getUndergroundDataArray(int iteration, int order) const throw(INTERP_KERNEL::Exception) - { - DataArrayInt *ret=self->getUndergroundDataArray(iteration,order); - if(ret) - ret->incrRef(); - return ret; - } - } - }; - - class MEDFileFields : public RefCountObject, public MEDFileFieldGlobsReal, public MEDFileWritable - { - public: - static MEDFileFields *New() throw(INTERP_KERNEL::Exception); - static MEDFileFields *New(const std::string& fileName, bool loadAll=true) throw(INTERP_KERNEL::Exception); - static MEDFileFields *LoadPartOf(const std::string& fileName, bool loadAll=true, const MEDFileMeshes *ms=0) throw(INTERP_KERNEL::Exception); - MEDFileFields *deepCpy() const throw(INTERP_KERNEL::Exception); - MEDFileFields *shallowCpy() const throw(INTERP_KERNEL::Exception); - void loadArrays() throw(INTERP_KERNEL::Exception); - void loadArraysIfNecessary() throw(INTERP_KERNEL::Exception); - void unloadArrays() throw(INTERP_KERNEL::Exception); - void unloadArraysWithoutDataLoss() throw(INTERP_KERNEL::Exception); - void write(const std::string& fileName, int mode) const throw(INTERP_KERNEL::Exception); - int getNumberOfFields() const; - std::vector<std::string> getFieldsNames() const throw(INTERP_KERNEL::Exception); - std::vector<std::string> getMeshesNames() const throw(INTERP_KERNEL::Exception); - // - void resize(int newSize) throw(INTERP_KERNEL::Exception); - void pushField(MEDFileAnyTypeFieldMultiTS *field) throw(INTERP_KERNEL::Exception); - void setFieldAtPos(int i, MEDFileAnyTypeFieldMultiTS *field) throw(INTERP_KERNEL::Exception); - int getPosFromFieldName(const std::string& fieldName) const throw(INTERP_KERNEL::Exception); - MEDFileAnyTypeFieldMultiTS *getFieldAtPos(int i) const throw(INTERP_KERNEL::Exception); - MEDFileAnyTypeFieldMultiTS *getFieldWithName(const std::string& fieldName) const throw(INTERP_KERNEL::Exception); - MEDFileFields *partOfThisLyingOnSpecifiedMeshName(const std::string& meshName) const throw(INTERP_KERNEL::Exception); - void destroyFieldAtPos(int i) throw(INTERP_KERNEL::Exception); - bool removeFieldsWithoutAnyTimeStep() throw(INTERP_KERNEL::Exception); - %extend - { - MEDFileFields() - { - return MEDFileFields::New(); - } - - MEDFileFields(const std::string& fileName, bool loadAll=true) throw(INTERP_KERNEL::Exception) - { - return MEDFileFields::New(fileName,loadAll); - } - - std::string __str__() const throw(INTERP_KERNEL::Exception) - { - return self->simpleRepr(); - } - - static MEDFileFields *LoadSpecificEntities(const std::string& fileName, PyObject *entities, bool loadAll=true) throw(INTERP_KERNEL::Exception) - { - std::vector<std::pair<int,int> > tmp(convertTimePairIdsFromPy(entities)); - std::size_t sz(tmp.size()); - std::vector< std::pair<TypeOfField,INTERP_KERNEL::NormalizedCellType> > entitiesCpp(sz); - for(std::size_t i=0;i<sz;i++) - { - entitiesCpp[i].first=(TypeOfField)tmp[i].first; - entitiesCpp[i].second=(INTERP_KERNEL::NormalizedCellType)tmp[i].second; - } - return MEDFileFields::LoadSpecificEntities(fileName,entitiesCpp,loadAll); - } - - PyObject *getCommonIterations() const throw(INTERP_KERNEL::Exception) - { - bool ret1; - std::vector< std::pair<int,int> > ret0=self->getCommonIterations(ret1); - PyObject *ret=PyTuple_New(2); - PyObject *ret_0=PyList_New(ret0.size()); - int rk=0; - for(std::vector< std::pair<int,int> >::const_iterator iter=ret0.begin();iter!=ret0.end();iter++,rk++) - { - PyObject *elt=PyTuple_New(2); - PyTuple_SetItem(elt,0,SWIG_From_int((*iter).first)); - PyTuple_SetItem(elt,1,SWIG_From_int((*iter).second)); - PyList_SetItem(ret_0,rk,elt); - } - PyTuple_SetItem(ret,0,ret_0); - PyObject *ret_1=ret1?Py_True:Py_False; Py_XINCREF(ret_1); - PyTuple_SetItem(ret,1,ret_1); - return ret; - } - - MEDFileFields *partOfThisLyingOnSpecifiedTimeSteps(PyObject *timeSteps) const throw(INTERP_KERNEL::Exception) - { - std::vector< std::pair<int,int> > ts=convertTimePairIdsFromPy(timeSteps); - return self->partOfThisLyingOnSpecifiedTimeSteps(ts); - } - - MEDFileFields *partOfThisNotLyingOnSpecifiedTimeSteps(PyObject *timeSteps) const throw(INTERP_KERNEL::Exception) - { - std::vector< std::pair<int,int> > ts=convertTimePairIdsFromPy(timeSteps); - return self->partOfThisNotLyingOnSpecifiedTimeSteps(ts); - } - - PyObject *__getitem__(PyObject *obj) throw(INTERP_KERNEL::Exception) - { - if(obj && PyList_Check(obj)) - { - int sz=PyList_Size(obj); - MEDCouplingAutoRefCountObjectPtr<DataArrayInt> da=DataArrayInt::New(); da->alloc(sz,1); - int *pt=da->getPointer(); - for(int i=0;i<sz;i++,pt++) - { - PyObject *elt1=PyList_GetItem(obj,i); - *pt=MEDFileFieldsgetitemSingleTS__(self,elt1); - } - return SWIG_NewPointerObj(SWIG_as_voidptr(self->buildSubPart(da->begin(),da->end())),SWIGTYPE_p_ParaMEDMEM__MEDFileFields, SWIG_POINTER_OWN | 0 ); - } - else - return convertMEDFileFieldMultiTS(self->getFieldAtPos(MEDFileFieldsgetitemSingleTS__(self,obj)), SWIG_POINTER_OWN | 0 ); - } - - MEDFileFields *__setitem__(int obj, MEDFileFieldMultiTS *field) throw(INTERP_KERNEL::Exception) - { - self->setFieldAtPos(obj,field); - return self; - } - - int __len__() const throw(INTERP_KERNEL::Exception) - { - return self->getNumberOfFields(); - } - - MEDFileFieldsIterator *__iter__() throw(INTERP_KERNEL::Exception) - { - return self->iterator(); - } - - bool changeMeshNames(PyObject *li) throw(INTERP_KERNEL::Exception) - { - std::vector< std::pair<std::string,std::string> > modifTab=convertVecPairStStFromPy(li); - return self->changeMeshNames(modifTab); - } - - int getPosOfField(PyObject *elt0) const throw(INTERP_KERNEL::Exception) - { - if(elt0 && PyInt_Check(elt0)) - {//fmts[3] - return PyInt_AS_LONG(elt0); - } - else if(elt0 && PyString_Check(elt0)) - return self->getPosFromFieldName(PyString_AsString(elt0)); - else - throw INTERP_KERNEL::Exception("MEDFileFields::getPosOfField : invalid input params ! expected fields[int], fields[string_of_field_name] !"); - } - - std::vector<int> getPosOfFields(PyObject *elts) const throw(INTERP_KERNEL::Exception) - { - if(PyList_Check(elts)) - { - int sz=PyList_Size(elts); - std::vector<int> ret(sz); - for(int i=0;i<sz;i++) - { - PyObject *elt=PyList_GetItem(elts,i); - ret[i]=ParaMEDMEM_MEDFileFields_getPosOfField(self,elt); - } - return ret; - } - else - { - std::vector<int> ret(1); - ret[0]=ParaMEDMEM_MEDFileFields_getPosOfField(self,elts); - return ret; - } - } - - void pushFields(PyObject *fields) throw(INTERP_KERNEL::Exception) - { - std::vector<MEDFileAnyTypeFieldMultiTS *> tmp; - convertFromPyObjVectorOfObj<ParaMEDMEM::MEDFileAnyTypeFieldMultiTS *>(fields,SWIGTYPE_p_ParaMEDMEM__MEDFileAnyTypeFieldMultiTS,"MEDFileAnyTypeFieldMultiTS",tmp); - self->pushFields(tmp); - } - - void __delitem__(PyObject *elts) throw(INTERP_KERNEL::Exception) - { - if(elts && PySlice_Check(elts)) - { - Py_ssize_t strt=2,stp=2,step=2; - PySliceObject *oC=reinterpret_cast<PySliceObject *>(elts); - GetIndicesOfSlice(oC,self->getNumberOfFields(),&strt,&stp,&step,"MEDFileFields.__delitem__ : error in input slice !"); - self->destroyFieldsAtPos2(strt,stp,step); - } - else - { - std::vector<int> idsToRemove=ParaMEDMEM_MEDFileFields_getPosOfFields(self,elts); - if(!idsToRemove.empty()) - self->destroyFieldsAtPos(&idsToRemove[0],&idsToRemove[0]+idsToRemove.size()); - } - } - } - }; - - class MEDFileParameter1TS : public RefCountObject - { - public: - void setIteration(int it); - int getIteration() const; - void setOrder(int order); - int getOrder() const; - void setTimeValue(double time); - void setTime(int dt, int it, double time); - double getTime(int& dt, int& it); - double getTimeValue() const; - }; - - class MEDFileParameterDouble1TSWTI : public MEDFileParameter1TS - { - public: - void setValue(double val) throw(INTERP_KERNEL::Exception); - double getValue() const throw(INTERP_KERNEL::Exception); - std::string simpleRepr() const throw(INTERP_KERNEL::Exception); - %extend - { - std::string __str__() const throw(INTERP_KERNEL::Exception) - { - return self->simpleRepr(); - } - } - }; - - class MEDFileParameterTinyInfo : public MEDFileWritable - { - public: - void setDescription(const std::string& name); - std::string getDescription() const; - void setTimeUnit(const std::string& unit); - std::string getTimeUnit() const; - }; - - class MEDFileParameterDouble1TS : public MEDFileParameterDouble1TSWTI, public MEDFileParameterTinyInfo - { - public: - static MEDFileParameterDouble1TS *New(); - static MEDFileParameterDouble1TS *New(const std::string& fileName) throw(INTERP_KERNEL::Exception); - static MEDFileParameterDouble1TS *New(const std::string& fileName, const std::string& paramName) throw(INTERP_KERNEL::Exception); - static MEDFileParameterDouble1TS *New(const std::string& fileName, const std::string& paramName, int dt, int it) throw(INTERP_KERNEL::Exception); - virtual MEDFileParameter1TS *deepCpy() const throw(INTERP_KERNEL::Exception); - virtual std::string simpleRepr() const throw(INTERP_KERNEL::Exception); - void setName(const std::string& name) throw(INTERP_KERNEL::Exception); - std::string getName() const throw(INTERP_KERNEL::Exception); - void write(const std::string& fileName, int mode) const throw(INTERP_KERNEL::Exception); - %extend - { - MEDFileParameterDouble1TS() - { - return MEDFileParameterDouble1TS::New(); - } - - MEDFileParameterDouble1TS(const std::string& fileName) throw(INTERP_KERNEL::Exception) - { - return MEDFileParameterDouble1TS::New(fileName); - } - - MEDFileParameterDouble1TS(const std::string& fileName, const std::string& paramName) throw(INTERP_KERNEL::Exception) - { - return MEDFileParameterDouble1TS::New(fileName,paramName); - } - - MEDFileParameterDouble1TS(const std::string& fileName, const std::string& paramName, int dt, int it) throw(INTERP_KERNEL::Exception) - { - return MEDFileParameterDouble1TS::New(fileName,paramName,dt,it); - } - - std::string __str__() const throw(INTERP_KERNEL::Exception) - { - return self->simpleRepr(); - } - - PyObject *isEqual(const MEDFileParameter1TS *other, double eps) const throw(INTERP_KERNEL::Exception) - { - std::string what; - bool ret0=self->isEqual(other,eps,what); - PyObject *res=PyList_New(2); - PyObject *ret0Py=ret0?Py_True:Py_False; - Py_XINCREF(ret0Py); - PyList_SetItem(res,0,ret0Py); - PyList_SetItem(res,1,PyString_FromString(what.c_str())); - return res; - } - } - }; - - class MEDFileParameterMultiTS : public RefCountObject, public MEDFileParameterTinyInfo - { - public: - static MEDFileParameterMultiTS *New(); - static MEDFileParameterMultiTS *New(const std::string& fileName) throw(INTERP_KERNEL::Exception); - static MEDFileParameterMultiTS *New(const std::string& fileName, const std::string& paramName) throw(INTERP_KERNEL::Exception); - std::string getName() const; - void setName(const std::string& name); - MEDFileParameterMultiTS *deepCpy() const throw(INTERP_KERNEL::Exception); - void write(const std::string& fileName, int mode) const throw(INTERP_KERNEL::Exception); - std::string simpleRepr() const throw(INTERP_KERNEL::Exception); - void appendValue(int dt, int it, double time, double val) throw(INTERP_KERNEL::Exception); - double getDoubleValue(int iteration, int order) const throw(INTERP_KERNEL::Exception); - int getPosOfTimeStep(int iteration, int order) const throw(INTERP_KERNEL::Exception); - int getPosGivenTime(double time, double eps=1e-8) const throw(INTERP_KERNEL::Exception); - int getNumberOfTS() const throw(INTERP_KERNEL::Exception); - %extend - { - MEDFileParameterMultiTS() - { - return MEDFileParameterMultiTS::New(); - } - - MEDFileParameterMultiTS(const std::string& fileName) - { - return MEDFileParameterMultiTS::New(fileName); - } - - MEDFileParameterMultiTS(const std::string& fileName, const std::string& paramName) - { - return MEDFileParameterMultiTS::New(fileName,paramName); - } - - std::string __str__() const throw(INTERP_KERNEL::Exception) - { - return self->simpleRepr(); - } - - PyObject *isEqual(const MEDFileParameterMultiTS *other, double eps) const throw(INTERP_KERNEL::Exception) - { - std::string what; - bool ret0=self->isEqual(other,eps,what); - PyObject *res=PyList_New(2); - PyObject *ret0Py=ret0?Py_True:Py_False; - Py_XINCREF(ret0Py); - PyList_SetItem(res,0,ret0Py); - PyList_SetItem(res,1,PyString_FromString(what.c_str())); - return res; - } - - void eraseTimeStepIds(PyObject *ids) throw(INTERP_KERNEL::Exception) - { - int sw; - int pos1; - std::vector<int> pos2; - DataArrayInt *pos3=0; - DataArrayIntTuple *pos4=0; - convertObjToPossibleCpp1(ids,sw,pos1,pos2,pos3,pos4); - switch(sw) - { - case 1: - { - self->eraseTimeStepIds(&pos1,&pos1+1); - return; - } - case 2: - { - if(pos2.empty()) - return; - self->eraseTimeStepIds(&pos2[0],&pos2[0]+pos2.size()); - return ; - } - case 3: - { - self->eraseTimeStepIds(pos3->begin(),pos3->end()); - return ; - } - default: - throw INTERP_KERNEL::Exception("MEDFileParameterMultiTS::eraseTimeStepIds : unexpected input array type recognized !"); - } - } - - int getTimeStepId(PyObject *elt0) const throw(INTERP_KERNEL::Exception) - { - if(elt0 && PyInt_Check(elt0)) - {//fmts[3] - int pos=InterpreteNegativeInt(PyInt_AS_LONG(elt0),self->getNumberOfTS()); - return pos; - } - else if(elt0 && PyTuple_Check(elt0)) - { - if(PyTuple_Size(elt0)==2) - { - PyObject *o0=PyTuple_GetItem(elt0,0); - PyObject *o1=PyTuple_GetItem(elt0,1); - if(PyInt_Check(o0) && PyInt_Check(o1)) - {//fmts(1,-1) - int iter=PyInt_AS_LONG(o0); - int order=PyInt_AS_LONG(o1); - return self->getPosOfTimeStep(iter,order); - } - else - throw INTERP_KERNEL::Exception("MEDFileParameterMultiTS::getTimeStepId : invalid input param ! input is a tuple of size 2 but two integers are expected in this tuple to request a time steps !"); - } - else - throw INTERP_KERNEL::Exception("MEDFileParameterMultiTS::getTimeStepId : invalid input param ! input is a tuple of size != 2 ! two integers are expected in this tuple to request a time steps !"); - } - else if(elt0 && PyFloat_Check(elt0)) - { - double val=PyFloat_AS_DOUBLE(elt0); - return self->getPosGivenTime(val); - } - else - throw INTERP_KERNEL::Exception("MEDFileParameterMultiTS::getTimeStepId : invalid input params ! expected fmts[int], fmts[int,int] or fmts[double] to request time step !"); - } - - MEDFileParameter1TS *__getitem__(PyObject *elt0) const throw(INTERP_KERNEL::Exception) - { - MEDFileParameter1TS *ret=self->getTimeStepAtPos(ParaMEDMEM_MEDFileParameterMultiTS_getTimeStepId(self,elt0)); - if(ret) - ret->incrRef(); - return ret; - } - - std::vector<int> getTimeStepIds(PyObject *elts) const throw(INTERP_KERNEL::Exception) - { - if(PyList_Check(elts)) - { - int sz=PyList_Size(elts); - std::vector<int> ret(sz); - for(int i=0;i<sz;i++) - { - PyObject *elt=PyList_GetItem(elts,i); - ret[i]=ParaMEDMEM_MEDFileParameterMultiTS_getTimeStepId(self,elt); - } - return ret; - } - else - { - std::vector<int> ret(1); - ret[0]=ParaMEDMEM_MEDFileParameterMultiTS_getTimeStepId(self,elts); - return ret; - } - } - - void __delitem__(PyObject *elts) throw(INTERP_KERNEL::Exception) - { - std::vector<int> idsToRemove=ParaMEDMEM_MEDFileParameterMultiTS_getTimeStepIds(self,elts); - if(!idsToRemove.empty()) - self->eraseTimeStepIds(&idsToRemove[0],&idsToRemove[0]+idsToRemove.size()); - } - - MEDFileParameter1TS *getTimeStepAtPos(int posId) const throw(INTERP_KERNEL::Exception) - { - MEDFileParameter1TS *ret=self->getTimeStepAtPos(posId); - if(ret) - ret->incrRef(); - return ret; - } - - PyObject *getIterations() const throw(INTERP_KERNEL::Exception) - { - std::vector< std::pair<int,int> > res=self->getIterations(); - PyObject *ret=PyList_New(res.size()); - int rk=0; - for(std::vector< std::pair<int,int> >::const_iterator iter=res.begin();iter!=res.end();iter++,rk++) - { - PyObject *elt=PyTuple_New(2); - PyTuple_SetItem(elt,0,SWIG_From_int((*iter).first)); - PyTuple_SetItem(elt,1,SWIG_From_int((*iter).second)); - PyList_SetItem(ret,rk,elt); - } - return ret; - } - - PyObject *getTimeSteps() const throw(INTERP_KERNEL::Exception) - { - std::vector<double> res2; - std::vector< std::pair<int,int> > res=self->getTimeSteps(res2); - PyObject *ret=PyList_New(res.size()); - int rk=0; - for(std::vector< std::pair<int,int> >::const_iterator iter=res.begin();iter!=res.end();iter++,rk++) - { - PyObject *elt=PyTuple_New(3); - PyTuple_SetItem(elt,0,SWIG_From_int((*iter).first)); - PyTuple_SetItem(elt,1,SWIG_From_int((*iter).second)); - PyTuple_SetItem(elt,2,SWIG_From_double(res2[rk])); - PyList_SetItem(ret,rk,elt); - } - return ret; - } - } - }; - - class MEDFileParameters : public RefCountObject, public MEDFileWritable - { - public: - static MEDFileParameters *New(); - static MEDFileParameters *New(const std::string& fileName) throw(INTERP_KERNEL::Exception); - MEDFileParameters *deepCpy() const throw(INTERP_KERNEL::Exception); - void write(const std::string& fileName, int mode) const throw(INTERP_KERNEL::Exception); - std::vector<std::string> getParamsNames() const throw(INTERP_KERNEL::Exception); - std::string simpleRepr() const throw(INTERP_KERNEL::Exception); - void resize(int newSize) throw(INTERP_KERNEL::Exception); - void pushParam(MEDFileParameterMultiTS *param) throw(INTERP_KERNEL::Exception); - void setParamAtPos(int i, MEDFileParameterMultiTS *param) throw(INTERP_KERNEL::Exception); - void destroyParamAtPos(int i) throw(INTERP_KERNEL::Exception); - int getPosFromParamName(const std::string& paramName) const throw(INTERP_KERNEL::Exception); - int getNumberOfParams() const throw(INTERP_KERNEL::Exception); - %extend - { - MEDFileParameters() - { - return MEDFileParameters::New(); - } - - MEDFileParameters(const std::string& fileName) - { - return MEDFileParameters::New(fileName); - } - - std::string __str__() const throw(INTERP_KERNEL::Exception) - { - return self->simpleRepr(); - } - - MEDFileParameterMultiTS *__getitem__(PyObject *obj) throw(INTERP_KERNEL::Exception) - { - if(PyInt_Check(obj)) - { - MEDFileParameterMultiTS *ret=self->getParamAtPos(InterpreteNegativeInt((int)PyInt_AS_LONG(obj),self->getNumberOfParams())); - if(ret) - ret->incrRef(); - return ret; - } - else if(PyString_Check(obj)) - { - MEDFileParameterMultiTS *ret=self->getParamWithName(PyString_AsString(obj)); - if(ret) - ret->incrRef(); - return ret; - } - else - throw INTERP_KERNEL::Exception("MEDFileParameters::__getitem__ : only integer or string with meshname supported !"); - } - - int __len__() const throw(INTERP_KERNEL::Exception) - { - return self->getNumberOfParams(); - } - - MEDFileParameterMultiTS *getParamAtPos(int i) const throw(INTERP_KERNEL::Exception) - { - MEDFileParameterMultiTS *ret=self->getParamAtPos(i); - if(ret) - ret->incrRef(); - return ret; - } - - MEDFileParameterMultiTS *getParamWithName(const std::string& paramName) const throw(INTERP_KERNEL::Exception) - { - MEDFileParameterMultiTS *ret=self->getParamWithName(paramName); - if(ret) - ret->incrRef(); - return ret; - } - - PyObject *isEqual(const MEDFileParameters *other, double eps) const throw(INTERP_KERNEL::Exception) - { - std::string what; - bool ret0=self->isEqual(other,eps,what); - PyObject *res=PyList_New(2); - PyObject *ret0Py=ret0?Py_True:Py_False; - Py_XINCREF(ret0Py); - PyList_SetItem(res,0,ret0Py); - PyList_SetItem(res,1,PyString_FromString(what.c_str())); - return res; - } - } - }; - - class MEDFileData : public RefCountObject, public MEDFileWritable - { - public: - static MEDFileData *New(const std::string& fileName) throw(INTERP_KERNEL::Exception); - static MEDFileData *New(); - MEDFileData *deepCpy() const throw(INTERP_KERNEL::Exception); - void setFields(MEDFileFields *fields) throw(INTERP_KERNEL::Exception); - void setMeshes(MEDFileMeshes *meshes) throw(INTERP_KERNEL::Exception); - void setParams(MEDFileParameters *params) throw(INTERP_KERNEL::Exception); - int getNumberOfFields() const throw(INTERP_KERNEL::Exception); - int getNumberOfMeshes() const throw(INTERP_KERNEL::Exception); - int getNumberOfParams() const throw(INTERP_KERNEL::Exception); - // - bool changeMeshName(const std::string& oldMeshName, const std::string& newMeshName) throw(INTERP_KERNEL::Exception); - bool unPolyzeMeshes() throw(INTERP_KERNEL::Exception); - // - void write(const std::string& fileName, int mode) const throw(INTERP_KERNEL::Exception); - %extend - { - MEDFileData(const std::string& fileName) throw(INTERP_KERNEL::Exception) - { - return MEDFileData::New(fileName); - } - - MEDFileData() - { - return MEDFileData::New(); - } - - std::string __str__() const throw(INTERP_KERNEL::Exception) - { - return self->simpleRepr(); - } - - MEDFileMeshes *getMeshes() const throw(INTERP_KERNEL::Exception) - { - MEDFileMeshes *ret=self->getMeshes(); - if(ret) - ret->incrRef(); - return ret; - } - - MEDFileParameters *getParams() const throw(INTERP_KERNEL::Exception) - { - MEDFileParameters *ret=self->getParams(); - if(ret) - ret->incrRef(); - return ret; - } - - MEDFileFields *getFields() const throw(INTERP_KERNEL::Exception) - { - MEDFileFields *ret=self->getFields(); - if(ret) - ret->incrRef(); - return ret; - } - - bool changeMeshNames(PyObject *li) throw(INTERP_KERNEL::Exception) - { - std::vector< std::pair<std::string,std::string> > modifTab=convertVecPairStStFromPy(li); - return self->changeMeshNames(modifTab); - } - } - }; - - class SauvReader : public RefCountObject - { - public: - static SauvReader* New(const std::string& fileName) throw(INTERP_KERNEL::Exception); - MEDFileData * loadInMEDFileDS() throw(INTERP_KERNEL::Exception); - %extend - { - SauvReader(const std::string& fileName) throw(INTERP_KERNEL::Exception) - { - return SauvReader::New(fileName); - } - } - }; - - class SauvWriter : public RefCountObject - { - public: - static SauvWriter * New(); - void setMEDFileDS(const MEDFileData* medData, unsigned meshIndex = 0) throw(INTERP_KERNEL::Exception); - void write(const std::string& fileName) throw(INTERP_KERNEL::Exception); - void setCpyGrpIfOnASingleFamilyStatus(bool status) throw(INTERP_KERNEL::Exception); - bool getCpyGrpIfOnASingleFamilyStatus() const throw(INTERP_KERNEL::Exception); - %extend - { - SauvWriter() throw(INTERP_KERNEL::Exception) - { - return SauvWriter::New(); - } - } - }; - - /////////////// - - class MEDFileMeshStruct; - - class MEDFileField1TSStructItem - { - public: - static MEDFileField1TSStructItem BuildItemFrom(const MEDFileAnyTypeField1TS *ref, const MEDFileMeshStruct *meshSt) throw(INTERP_KERNEL::Exception); - }; - - class MEDFileMeshStruct : public RefCountObject - { - public: - static MEDFileMeshStruct *New(const MEDFileMesh *mesh) throw(INTERP_KERNEL::Exception); - protected: - ~MEDFileMeshStruct(); - }; - - class MEDMeshMultiLev : public RefCountObject - { - public: - virtual MEDMeshMultiLev *prepare() const throw(INTERP_KERNEL::Exception); - DataArray *buildDataArray(const MEDFileField1TSStructItem& fst, const MEDFileFieldGlobsReal *globs, const DataArray *vals) const throw(INTERP_KERNEL::Exception); - protected: - ~MEDMeshMultiLev(); - public: - %extend - { - PyObject *retrieveFamilyIdsOnCells() const throw(INTERP_KERNEL::Exception) - { - DataArrayInt *famIds(0); - bool isWithoutCopy(false); - self->retrieveFamilyIdsOnCells(famIds,isWithoutCopy); - PyObject *ret=PyTuple_New(2); - PyObject *ret1Py=isWithoutCopy?Py_True:Py_False; - Py_XINCREF(ret1Py); - PyTuple_SetItem(ret,0,SWIG_NewPointerObj(SWIG_as_voidptr(famIds),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 )); - PyTuple_SetItem(ret,1,ret1Py); - return ret; - } - - PyObject *retrieveNumberIdsOnCells() const throw(INTERP_KERNEL::Exception) - { - DataArrayInt *numIds(0); - bool isWithoutCopy(false); - self->retrieveNumberIdsOnCells(numIds,isWithoutCopy); - PyObject *ret=PyTuple_New(2); - PyObject *ret1Py=isWithoutCopy?Py_True:Py_False; - Py_XINCREF(ret1Py); - PyTuple_SetItem(ret,0,SWIG_NewPointerObj(SWIG_as_voidptr(numIds),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 )); - PyTuple_SetItem(ret,1,ret1Py); - return ret; - } - - PyObject *retrieveFamilyIdsOnNodes() const throw(INTERP_KERNEL::Exception) - { - DataArrayInt *famIds(0); - bool isWithoutCopy(false); - self->retrieveFamilyIdsOnNodes(famIds,isWithoutCopy); - PyObject *ret=PyTuple_New(2); - PyObject *ret1Py=isWithoutCopy?Py_True:Py_False; - Py_XINCREF(ret1Py); - PyTuple_SetItem(ret,0,SWIG_NewPointerObj(SWIG_as_voidptr(famIds),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 )); - PyTuple_SetItem(ret,1,ret1Py); - return ret; - } - - PyObject *retrieveNumberIdsOnNodes() const throw(INTERP_KERNEL::Exception) - { - DataArrayInt *numIds(0); - bool isWithoutCopy(false); - self->retrieveNumberIdsOnNodes(numIds,isWithoutCopy); - PyObject *ret=PyTuple_New(2); - PyObject *ret1Py=isWithoutCopy?Py_True:Py_False; - Py_XINCREF(ret1Py); - PyTuple_SetItem(ret,0,SWIG_NewPointerObj(SWIG_as_voidptr(numIds),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 )); - PyTuple_SetItem(ret,1,ret1Py); - return ret; - } - - PyObject *getGeoTypes() const throw(INTERP_KERNEL::Exception) - { - std::vector< INTERP_KERNEL::NormalizedCellType > result(self->getGeoTypes()); - std::vector< INTERP_KERNEL::NormalizedCellType >::const_iterator iL(result.begin()); - PyObject *res(PyList_New(result.size())); - for(int i=0;iL!=result.end(); i++, iL++) - PyList_SetItem(res,i,PyInt_FromLong(*iL)); - return res; - } - } - }; - - class MEDUMeshMultiLev : public MEDMeshMultiLev - { - protected: - ~MEDUMeshMultiLev(); - public: - %extend - { - PyObject *buildVTUArrays() const throw(INTERP_KERNEL::Exception) - { - DataArrayDouble *coords(0); DataArrayByte *types(0); DataArrayInt *cellLocations(0),*cells(0),*faceLocations(0),*faces(0); - bool ncc(self->buildVTUArrays(coords,types,cellLocations,cells,faceLocations,faces)); - PyObject *ret0Py=ncc?Py_True:Py_False; - Py_XINCREF(ret0Py); - PyObject *ret=PyTuple_New(7); - PyTuple_SetItem(ret,0,ret0Py); - PyTuple_SetItem(ret,1,SWIG_NewPointerObj(SWIG_as_voidptr(coords),SWIGTYPE_p_ParaMEDMEM__DataArrayDouble, SWIG_POINTER_OWN | 0 )); - PyTuple_SetItem(ret,2,SWIG_NewPointerObj(SWIG_as_voidptr(types),SWIGTYPE_p_ParaMEDMEM__DataArrayByte, SWIG_POINTER_OWN | 0 )); - PyTuple_SetItem(ret,3,SWIG_NewPointerObj(SWIG_as_voidptr(cellLocations),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 )); - PyTuple_SetItem(ret,4,SWIG_NewPointerObj(SWIG_as_voidptr(cells),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 )); - PyTuple_SetItem(ret,5,SWIG_NewPointerObj(SWIG_as_voidptr(faceLocations),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 )); - PyTuple_SetItem(ret,6,SWIG_NewPointerObj(SWIG_as_voidptr(faces),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 )); - return ret; - } - } - }; - - class MEDStructuredMeshMultiLev : public MEDMeshMultiLev - { - protected: - ~MEDStructuredMeshMultiLev(); - }; - - class MEDCMeshMultiLev : public MEDStructuredMeshMultiLev - { - protected: - ~MEDCMeshMultiLev(); - public: - %extend - { - PyObject *buildVTUArrays() const throw(INTERP_KERNEL::Exception) - { - bool isInternal; - std::vector< DataArrayDouble * > objs(self->buildVTUArrays(isInternal)); - std::size_t sz(objs.size()); - PyObject *ret(PyTuple_New(2)); - PyObject *ret0=PyList_New(sz); - for(std::size_t i=0;i<sz;i++) - PyList_SetItem(ret0,i,SWIG_NewPointerObj(SWIG_as_voidptr(objs[i]),SWIGTYPE_p_ParaMEDMEM__DataArrayDouble, SWIG_POINTER_OWN | 0 )); - PyTuple_SetItem(ret,0,ret0); - PyObject *ret1Py(isInternal?Py_True:Py_False); - Py_XINCREF(ret1Py); - PyTuple_SetItem(ret,1,ret1Py); - return ret; - } - } - }; - - class MEDCurveLinearMeshMultiLev : public MEDStructuredMeshMultiLev - { - protected: - ~MEDCurveLinearMeshMultiLev(); - public: - %extend - { - PyObject *buildVTUArrays() const throw(INTERP_KERNEL::Exception) - { - DataArrayDouble *ret0(0); - std::vector<int> ret1; - bool ret2; - self->buildVTUArrays(ret0,ret1,ret2); - std::size_t sz(ret1.size()); - PyObject *ret=PyTuple_New(3); - PyTuple_SetItem(ret,0,SWIG_NewPointerObj(SWIG_as_voidptr(ret0),SWIGTYPE_p_ParaMEDMEM__DataArrayDouble, SWIG_POINTER_OWN | 0 )); - PyObject *ret1Py=PyList_New(sz); - for(std::size_t i=0;i<sz;i++) - PyList_SetItem(ret1Py,i,SWIG_From_int(ret1[i])); - PyTuple_SetItem(ret,1,ret1Py); - PyObject *ret2Py(ret2?Py_True:Py_False); - Py_XINCREF(ret2Py); - PyTuple_SetItem(ret,2,ret2Py); - return ret; - } - } - }; - - class MEDFileFastCellSupportComparator : public RefCountObject - { - public: - static MEDFileFastCellSupportComparator *New(const MEDFileMeshStruct *m, const MEDFileAnyTypeFieldMultiTS *ref) throw(INTERP_KERNEL::Exception); - MEDMeshMultiLev *buildFromScratchDataSetSupport(int timeStepId, const MEDFileFieldGlobsReal *globs) const throw(INTERP_KERNEL::Exception); - bool isDataSetSupportEqualToThePreviousOne(int timeStepId, const MEDFileFieldGlobsReal *globs) const throw(INTERP_KERNEL::Exception); - int getNumberOfTS() const throw(INTERP_KERNEL::Exception); - protected: - ~MEDFileFastCellSupportComparator(); - public: - %extend - { - PyObject *getGeoTypesAt(int timeStepId, const MEDFileMesh *m) const throw(INTERP_KERNEL::Exception) - { - std::vector< INTERP_KERNEL::NormalizedCellType > result(self->getGeoTypesAt(timeStepId,m)); - std::vector< INTERP_KERNEL::NormalizedCellType >::const_iterator iL(result.begin()); - PyObject *res(PyList_New(result.size())); - for(int i=0;iL!=result.end(); i++, iL++) - PyList_SetItem(res,i,PyInt_FromLong(*iL)); - return res; - } - } - }; -} diff --git a/src/MEDLoader/Swig/MEDLoaderCouplingTrainingSession.py b/src/MEDLoader/Swig/MEDLoaderCouplingTrainingSession.py deleted file mode 100644 index 8001e2798..000000000 --- a/src/MEDLoader/Swig/MEDLoaderCouplingTrainingSession.py +++ /dev/null @@ -1,592 +0,0 @@ -# -*- coding: iso-8859-1 -*- -# Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 -# 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/DM2S/STMF/LGLS) - -from MEDLoader import * -from MEDCouplingRemapper import * -import math, os - -d=DataArrayDouble.New(6,2) -d[:,0]=3. -d[:,1]=range(6) -d[:,1]*=math.pi/3. -d=d.fromPolarToCart() -d.setInfoOnComponents(["X [m]","Y [m]"]) -print d.getValues() -print d -print d.magnitude().isUniform(3.,1e-12) -# -radius=3. -translationToPerform=[[0.,0.],[3./2.*radius,-radius*math.sqrt(3.)/2],[3./2.*radius,radius*math.sqrt(3.)/2],[0.,radius*math.sqrt(3.)],[-3./2.*radius,radius*math.sqrt(3.)/2],[-3./2.*radius,-radius*math.sqrt(3.)/2],[0.,-radius*math.sqrt(3.)]] -ds=len(translationToPerform)*[None] -for pos,t in enumerate(translationToPerform): - ds[pos]=d[:] - ds[pos]+=t - pass -# -d2=DataArrayDouble.Aggregate(ds) -oldNbOfTuples=d2.getNumberOfTuples() -c,cI=d2.findCommonTuples(1e-12) -tmp=c[cI[0]:cI[0+1]] -print tmp -a=cI.deltaShiftIndex() -b=a-1 -myNewNbOfTuples=oldNbOfTuples-sum(b.getValues()) -o2n,newNbOfTuples=DataArrayInt.BuildOld2NewArrayFromSurjectiveFormat2(oldNbOfTuples,c,cI) -print "Ai je trouve le bon resultat ? %s"%(str(myNewNbOfTuples==newNbOfTuples)) ; assert myNewNbOfTuples==newNbOfTuples -# -d3=d2.renumberAndReduce(o2n,newNbOfTuples) -n2o=o2n.invertArrayO2N2N2O(newNbOfTuples) -d3_bis=d2[n2o] -print "Ai je trouve le bon resultat (2) ? %s"%(str(d3.isEqual(d3_bis,1e-12))) ; assert d3.isEqual(d3_bis,1e-12) -# -d3+=[3.3,4.4] -# d3 contains coordinates -m=MEDCouplingUMesh.New("My7hexagons",2) -m.setCoords(d3) -m.allocateCells(7) -for i in xrange(7): - m.insertNextCell(NORM_POLYGON,o2n[6*i:6*(i+1)].getValues()) - pass -m.finishInsertingCells() -m.checkCoherency() -# -m.writeVTK("My7hexagons.vtu") - -######## - -coords=[0.,0.,0., 1.,1.,0., 1.,1.25,0., 1.,0.,0., 1.,1.5,0., 2.,0.,0., 2.,1.,0., 1.,2.,0., 0.,2.,0., 3.,1.,0., - 3.,2.,0., 0.,1.,0., 1.,3.,0., 2.,2.,0., 2.,3.,0., - 0.,0.,1., 1.,1.,1., 1.,1.25,1., 1.,0.,1., 1.,1.5,1., 2.,0.,1., 2.,1.,1., 1.,2.,1., 0.,2.,1., 3.,1.,1., - 3.,2.,1., 0.,1.,1., 1.,3.,1., 2.,2.,1., 2.,3.,1., - 0.,0.,2., 1.,1.,2., 1.,1.25,2., 1.,0.,2., 1.,1.5,2., 2.,0.,2., 2.,1.,2., 1.,2.,2., 0.,2.,2., 3.,1.,2., - 3.,2.,2., 0.,1.,2., 1.,3.,2., 2.,2.,2., 2.,3.,2., - 0.,0.,3., 1.,1.,3., 1.,1.25,3., 1.,0.,3., 1.,1.5,3., 2.,0.,3., 2.,1.,3., 1.,2.,3., 0.,2.,3., 3.,1.,3., - 3.,2.,3., 0.,1.,3., 1.,3.,3., 2.,2.,3., 2.,3.,3.] -conn=[0,11,1,3,15,26,16,18, 1,2,4,7,13,6,-1,1,16,21,6,-1,6,21,28,13,-1,13,7,22,28,-1,7,4,19,22,-1,4,2,17,19,-1,2,1,16,17,-1,16,21,28,22,19,17, - 1,6,5,3,16,21,20,18, 13,10,9,6,28,25,24,21, 11,8,7,4,2,1,-1,11,26,16,1,-1,1,16,17,2,-1,2,17,19,4,-1,4,19,22,7,-1,7,8,23,22,-1,8,11,26,23,-1,26,16,17,19,22,23, - 7,12,14,13,22,27,29,28, 15,26,16,18,30,41,31,33, 16,17,19,22,28,21,-1,16,31,36,21,-1,21,36,43,28,-1,28,22,37,43,-1,22,19,34,37,-1,19,17,32,34,-1,17,16,31,32,-1,31,36,43,37,34,32, - 16,21,20,18,31,36,35,33, 28,25,24,21,43,40,39,36, 26,23,22,19,17,16,-1,26,41,31,16,-1,16,31,32,17,-1,17,32,34,19,-1,19,34,37,22,-1,22,23,38,37,-1,23,26,41,38,-1,41,31,32,34,37,38, - 22,27,29,28,37,42,44,43, 30,41,31,33,45,56,46,48, 31,32,34,37,43,36,-1,31,46,51,36,-1,36,51,58,43,-1,43,37,52,58,-1,37,34,49,52,-1,34,32,47,49,-1,32,31,46,47,-1,46,51,58,52,49,47, - 31,36,35,33,46,51,50,48, 43,40,39,36,58,55,54,51, 41,38,37,34,32,31,-1,41,56,46,31,-1,31,46,47,32,-1,32,47,49,34,-1,34,49,52,37,-1,37,38,53,52,-1,38,41,56,53,-1,56,46,47,49,52,53, - 37,42,44,43,52,57,59,58] -mesh3D=MEDCouplingUMesh.New("mesh3D",3); -mesh3D.allocateCells(18); -mesh3D.insertNextCell(NORM_HEXA8,conn[0:8]); mesh3D.insertNextCell(NORM_POLYHED,conn[8:51]); mesh3D.insertNextCell(NORM_HEXA8,conn[51:59]); mesh3D.insertNextCell(NORM_HEXA8,conn[59:67]); mesh3D.insertNextCell(NORM_POLYHED,conn[67:110]); mesh3D.insertNextCell(NORM_HEXA8,conn[110:118]); -mesh3D.insertNextCell(NORM_HEXA8,conn[118:126]); mesh3D.insertNextCell(NORM_POLYHED,conn[126:169]); mesh3D.insertNextCell(NORM_HEXA8,conn[169:177]); mesh3D.insertNextCell(NORM_HEXA8,conn[177:185]); mesh3D.insertNextCell(NORM_POLYHED,conn[185:228]); mesh3D.insertNextCell(NORM_HEXA8,conn[228:236]); -mesh3D.insertNextCell(NORM_HEXA8,conn[236:244]); mesh3D.insertNextCell(NORM_POLYHED,conn[244:287]); mesh3D.insertNextCell(NORM_HEXA8,conn[287:295]); mesh3D.insertNextCell(NORM_HEXA8,conn[295:303]); mesh3D.insertNextCell(NORM_POLYHED,conn[303:346]); mesh3D.insertNextCell(NORM_HEXA8,conn[346:354]); -mesh3D.finishInsertingCells(); -myCoords=DataArrayDouble.New(coords,60,3); -myCoords.setInfoOnComponents(["X [m]","Y [m]","Z [m]"]) -mesh3D.setCoords(myCoords); -mesh3D.orientCorrectlyPolyhedrons() -mesh3D.sortCellsInMEDFileFrmt() -mesh3D.checkCoherency() -renum=DataArrayInt.New(60) ; renum[:15]=range(15,30) ; renum[15:30]=range(15) ; renum[30:45]=range(45,60) ; renum[45:]=range(30,45) -mesh3D.renumberNodes(renum,60) -# -mesh3D.getCoords()[:]*=100. -mesh3D.getCoords().setInfoOnComponents(["X [cm]","Y [cm]","Z [cm]"]) -# -zLev=mesh3D.getCoords()[:,2] -zLev=zLev.getDifferentValues(1e-12) -zLev.sort() -# -tmp,cellIdsSol1=mesh3D.buildSlice3D([0.,0.,(zLev[1]+zLev[2])/2],[0.,0.,1.],1e-12) -bary=mesh3D.getBarycenterAndOwner() -baryZ=bary[:,2] -cellIdsSol2=baryZ.getIdsInRange(zLev[1],zLev[2]) -nodeIds=mesh3D.findNodesOnPlane([0.,0.,zLev[0]],[0.,0.,1.],1e-10) -mesh2D=mesh3D.buildFacePartOfMySelfNode(nodeIds,True) -extMesh=MEDCouplingExtrudedMesh.New(mesh3D,mesh2D,0) -cellIdsSol3=extMesh.getMesh3DIds()[mesh2D.getNumberOfCells():2*mesh2D.getNumberOfCells()] -for i in xrange(3): - exec("print cellIdsSol%s.getValues()"%(i+1)) -# -mesh3DPart=mesh3D[cellIdsSol2] # equivalent to mesh3DPart=mesh3D.buildPartOfMySelf(cellIdsSol2,True) -mesh3DPart.zipCoords() -print mesh3DPart.checkConsecutiveCellTypesAndOrder([NORM_HEXA8,NORM_POLYHED]) ; assert mesh3DPart.checkConsecutiveCellTypesAndOrder([NORM_HEXA8,NORM_POLYHED]) -print mesh3DPart.checkConsecutiveCellTypes() ; assert mesh3DPart.checkConsecutiveCellTypes() -#print mesh3DPart.advancedRepr() -# -baryXY=bary[:,[0,1]] -baryXY-=[250.,150.] -magn=baryXY.magnitude() -cellIds2Sol1=magn.getIdsInRange(0.,1e-12) -# -bary2=mesh2D.getBarycenterAndOwner()[:,[0,1]] -bary2-=[250.,150.] -magn=bary2.magnitude() -ids=magn.getIdsInRange(0.,1e-12) -idStart=int(ids) # ids is assumed to contain only one value, if not an exception is thrown -cellIds2Sol2=extMesh.getMesh3DIds()[range(idStart,mesh3D.getNumberOfCells(),mesh2D.getNumberOfCells())] -# -mesh3DSlice2=mesh3D[cellIds2Sol1] -mesh3DSlice2.zipCoords() -# -mesh3DSlice2bis=mesh3DSlice2.deepCpy() -mesh3DSlice2bis.translate([0.,1000.,0.]) -mesh3DSlice2All=MEDCouplingUMesh.MergeUMeshes([mesh3DSlice2,mesh3DSlice2bis]) -mesh3DSlice2All.writeVTK("mesh3DSlice2All.vtu") -# -mesh3DSurf,desc,descIndx,revDesc,revDescIndx=mesh3D.buildDescendingConnectivity() -numberOf3DCellSharing=revDescIndx.deltaShiftIndex() -cellIds=numberOf3DCellSharing.getIdsNotEqual(1) -mesh3DSurfInside=mesh3DSurf[cellIds] -mesh3DSurfInside.writeVTK("mesh3DSurfInside.vtu") - -###### - -xarr=DataArrayDouble.New(11,1) -xarr.iota(0.) -cmesh=MEDCouplingCMesh.New() -cmesh.setCoords(xarr,xarr,xarr) -mesh=cmesh.buildUnstructured() -mesh.convertToPolyTypes(DataArrayInt.Range(0,mesh.getNumberOfCells(),2)) -# - -f=mesh.fillFromAnalytic(ON_CELLS,1,"(x-5.)*(x-5.)+(y-5.)*(y-5.)+(z-5.)*(z-5.)") -f.setName("MyField") -# -f2=MEDCouplingFieldDouble.New(ON_CELLS,ONE_TIME) -f2.setMesh(mesh) -f2.setName("MyField2") -f2.fillFromAnalytic(1,"(x-5.)*(x-5.)+(y-5.)*(y-5.)+(z-5.)*(z-5.)") -print "f and f2 are equal : %s"%(f.isEqualWithoutConsideringStr(f2,1e-13,1e-12)) ; assert f.isEqualWithoutConsideringStr(f2,1e-13,1e-12) -# -ids1=f.getArray().getIdsInRange(0.,5.) -fPart1=f.buildSubPart(ids1) -ids2=f.getArray().getIdsInRange(50.,1.e300) -fPart2=f.buildSubPart(ids2) -#Renumbering cells to follow MED file -fPart1Cpy=fPart1.deepCpy() -o2n=fPart1Cpy.getMesh().sortCellsInMEDFileFrmt() -fPart1Cpy.getArray().renumberInPlace(o2n) -#Check that fPart1Cpy and fPart1 are the same -fPart1Cpy.substractInPlaceDM(fPart1,12,1e-12) -fPart1Cpy.getArray().abs() -print "Fields are the same ? %s"%(fPart1Cpy.getArray().accumulate()[0]<1e-12) ; assert fPart1Cpy.getArray().accumulate()[0]<1e-12 -# -fPart12=MEDCouplingFieldDouble.MergeFields([fPart1,fPart2]) -# evaluation on points -bary=fPart12.getMesh().getBarycenterAndOwner() -arr1=fPart12.getValueOnMulti(bary) -arr2=f.getValueOnMulti(bary) -delta=arr1-arr2 -delta.abs() -print "Check OK : %s"%(delta.accumulate()[0]<1e-12) ; assert delta.accumulate()[0]<1e-12 -# -print abs(fPart12.integral(0,True)-fPart12.getArray().accumulate()[0])<1e-10 ; assert abs(fPart12.integral(0,True)-fPart12.getArray().accumulate()[0])<1e-10 -fPart12.getMesh().scale([0.,0.,0.],1.2) -print abs(fPart12.integral(0,True)-fPart12.getArray().accumulate()[0]*1.2*1.2*1.2)<1e-8 ; assert abs(fPart12.integral(0,True)-fPart12.getArray().accumulate()[0]*1.2*1.2*1.2)<1e-8 -# Explosion of field -fVec=mesh.fillFromAnalytic(ON_CELLS,3,"(x-5.)*IVec+(y-5.)*JVec+(z-5.)*KVec") -fVecPart1=fVec.buildSubPart(ids1) -fVecPart1.setName("fVecPart1") -cells=fPart1.getMesh().getNumberOfCells()*[None] -for icell,vec in enumerate(fVecPart1.getArray()): - m=fPart1.getMesh()[[icell]] - m.zipCoords() - m.translate(vec) - cells[icell]=m - pass -meshFVecPart1Exploded=MEDCouplingUMesh.MergeUMeshes(cells) -fPart1.setMesh(meshFVecPart1Exploded) - -#### - -targetCoords=[-0.3,-0.3, 0.2,-0.3, 0.7,-0.3, -0.3,0.2, 0.2,0.2, 0.7,0.2, -0.3,0.7, 0.2,0.7, 0.7,0.7 ]; -targetConn=[0,3,4,1, 1,4,2, 4,5,2, 6,7,4,3, 7,8,5,4]; -targetMesh=MEDCouplingUMesh.New("MyMesh",2); -targetMesh.allocateCells(5); -targetMesh.insertNextCell(NORM_TRI3,3,targetConn[4:7]); -targetMesh.insertNextCell(NORM_TRI3,3,targetConn[7:10]); -targetMesh.insertNextCell(NORM_QUAD4,4,targetConn[0:4]); -targetMesh.insertNextCell(NORM_QUAD4,4,targetConn[10:14]); -targetMesh.insertNextCell(NORM_QUAD4,4,targetConn[14:18]); -targetMesh.finishInsertingCells(); -myCoords=DataArrayDouble.New(targetCoords,9,2); -myCoords.setInfoOnComponents(["X [km]","YY [mm]"]) -targetMesh.setCoords(myCoords); -# -MEDLoader.WriteUMesh("TargetMesh.med",targetMesh,True) -# -meshRead=MEDLoader.ReadUMeshFromFile("TargetMesh.med",targetMesh.getName(),0) -print "Is the mesh read in file equals targetMesh ? %s"%(meshRead.isEqual(targetMesh,1e-12)) ; assert meshRead.isEqual(targetMesh,1e-12) -# -f=MEDCouplingFieldDouble.New(ON_CELLS,ONE_TIME) -f.setTime(5.6,7,8) -f.setArray(targetMesh.getBarycenterAndOwner()) -f.setMesh(targetMesh) -f.setName("AFieldName") -MEDLoader.WriteField("MyFirstField.med",f,True) -# -f2=MEDLoader.ReadFieldCell("MyFirstField.med",f.getMesh().getName(),0,f.getName(),7,8) -print "Is the field read in file equals f ? %s"%(f2.isEqual(f,1e-12,1e-12)) ; assert f2.isEqual(f,1e-12,1e-12) -# -MEDLoader.WriteUMesh("MySecondField.med",f.getMesh(),True) -MEDLoader.WriteFieldUsingAlreadyWrittenMesh("MySecondField.med",f) -# -f2=f.clone(True) -f2.getArray()[:]*=2.0 -f2.setTime(7.8,9,10) -MEDLoader.WriteFieldUsingAlreadyWrittenMesh("MySecondField.med",f2) -# -f3=MEDLoader.ReadFieldCell("MySecondField.med",f.getMesh().getName(),0,f.getName(),7,8) -print "Is the field read in file equals f ? %s"%(f.isEqual(f3,1e-12,1e-12)) ; assert f.isEqual(f3,1e-12,1e-12) -f4=MEDLoader.ReadFieldCell("MySecondField.med",f.getMesh().getName(),0,f.getName(),9,10) -print "Is the field read in file equals f ? %s"%(f2.isEqual(f4,1e-12,1e-12)) ; assert f2.isEqual(f4,1e-12,1e-12) - -##### - -targetCoords=[-0.3,-0.3, 0.2,-0.3, 0.7,-0.3, -0.3,0.2, 0.2,0.2, 0.7,0.2, -0.3,0.7, 0.2,0.7, 0.7,0.7 ]; -targetConn=[0,3,4,1, 1,4,2, 4,5,2, 6,7,4,3, 7,8,5,4]; -targetMesh=MEDCouplingUMesh.New("MyMesh",2); -targetMesh.allocateCells(5); -targetMesh.insertNextCell(NORM_TRI3,3,targetConn[4:7]); -targetMesh.insertNextCell(NORM_TRI3,3,targetConn[7:10]); -targetMesh.insertNextCell(NORM_QUAD4,4,targetConn[0:4]); -targetMesh.insertNextCell(NORM_QUAD4,4,targetConn[10:14]); -targetMesh.insertNextCell(NORM_QUAD4,4,targetConn[14:18]); -targetMesh.finishInsertingCells(); -myCoords=DataArrayDouble.New(targetCoords,9,2); -myCoords.setInfoOnComponents(["X [km]","YY [mm]"]) -targetMesh.setCoords(myCoords); -# -targetMeshConsti=targetMesh.buildDescendingConnectivity()[0] -targetMesh1=targetMeshConsti[[3,4,7,8]] -targetMesh1.setName(targetMesh.getName()) -# -meshMEDFile=MEDFileUMesh.New() -meshMEDFile.setMeshAtLevel(0,targetMesh) -meshMEDFile.setMeshAtLevel(-1,targetMesh1) -# Some groups on cells Level 0 -grp0_0=DataArrayInt.New([0,1,3]) ; grp0_0.setName("grp0_Lev0") -grp1_0=DataArrayInt.New([1,2,3,4]) ; grp1_0.setName("grp1_Lev0") -meshMEDFile.setGroupsAtLevel(0,[grp0_0,grp1_0]) -# Some groups on cells Level -1 -grp0_M1=DataArrayInt.New([0,1]) ; grp0_M1.setName("grp0_LevM1") -grp1_M1=DataArrayInt.New([0,1,2]) ; grp1_M1.setName("grp1_LevM1") -grp2_M1=DataArrayInt.New([1,2,3]) ; grp2_M1.setName("grp2_LevM1") -meshMEDFile.setGroupsAtLevel(-1,[grp0_M1,grp1_M1,grp2_M1]) -# -meshMEDFile.write("TargetMesh2.med",2) # 2 stands for write from scratch -# -meshMEDFileRead=MEDFileMesh.New("TargetMesh2.med") -meshRead0=meshMEDFileRead.getMeshAtLevel(0) -meshRead1=meshMEDFileRead.getMeshAtLevel(-1) -print "Is the mesh at level 0 read in file equals targetMesh ? %s"%(meshRead0.isEqual(targetMesh,1e-12)) ; assert meshRead0.isEqual(targetMesh,1e-12) -print "Is the mesh at level -1 read in file equals targetMesh ? %s"%(meshRead1.isEqual(targetMesh1,1e-12)) ; assert meshRead1.isEqual(targetMesh1,1e-12) -# -print meshMEDFileRead.getGrpNonEmptyLevels("grp0_Lev0") -grp0_0_read=meshMEDFileRead.getGroupArr(0,"grp0_Lev0") -print "Is group \"grp0_Lev0\" are the same ? %s"%(grp0_0_read.isEqual(grp0_0)) ; assert grp0_0_read.isEqual(grp0_0) -# -# Fields -# -f=MEDCouplingFieldDouble.New(ON_CELLS,ONE_TIME) -f.setTime(5.6,7,8) -f.setArray(targetMesh.getBarycenterAndOwner()) -f.setMesh(targetMesh) -f.setName("AFieldName") -# -fMEDFile=MEDFileField1TS.New() -fMEDFile.setFieldNoProfileSBT(f) -# -fMEDFile.write("TargetMesh2.med",0) # 0 is very important here because we want to append to TargetMesh2.med and not to scratch it -# -fMEDFileRead=MEDFileField1TS.New("TargetMesh2.med",f.getName(),7,8) -fRead1=fMEDFileRead.getFieldOnMeshAtLevel(ON_CELLS,0,meshMEDFileRead) # fastest method. No read in file. -fRead2=fMEDFileRead.getFieldAtLevel(ON_CELLS,0) # basic method like, mesh is reread in file... -print "Does the field f remains the same using fast method ? %s"%(fRead1.isEqual(f,1e-12,1e-12)) ; assert fRead1.isEqual(f,1e-12,1e-12) -print "Does the field f remains the same using slow method ? %s"%(fRead2.isEqual(f,1e-12,1e-12)) ; assert fRead2.isEqual(f,1e-12,1e-12) -# -# Writing and Reading fields on profile using MEDLoader advanced API -# -pfl=DataArrayInt.New([1,2,3]) ; pfl.setName("My1stPfl") -fPart=f.buildSubPart(pfl) -fPart.setName("fPart") -# -fMEDFile2=MEDFileField1TS.New() -fMEDFile2.setFieldProfile(fPart,meshMEDFileRead,0,pfl) -fMEDFile2.write("TargetMesh2.med",0) # 0 is very important here because we want to append to TargetMesh2.med and not to scratch it -# -fMEDFileRead2=MEDFileField1TS.New("TargetMesh2.med",fPart.getName(),7,8) -fPartRead,pflRead=fMEDFileRead2.getFieldWithProfile(ON_CELLS,0,meshMEDFileRead) -print fPartRead.isEqualWithoutConsideringStr(fPart.getArray(),1e-12) ; assert fPartRead.isEqualWithoutConsideringStr(fPart.getArray(),1e-12) -print pflRead.isEqualWithoutConsideringStr(pfl) ; assert pflRead.isEqualWithoutConsideringStr(pfl) - -##### - -m0=MEDCouplingCMesh() -arr=DataArrayDouble(31,1) ; arr.iota(0.) -m0.setCoords(arr,arr) -m0=m0.buildUnstructured() -m00=m0[::2] ; m00.simplexize(0) ; m01=m0[1::2] -m0=MEDCouplingUMesh.MergeUMeshes([m00,m01]) -m0.getCoords()[:]*=1/15. -m0.setName("mesh") -# -CellField=MEDCouplingFieldDouble(ON_CELLS,ONE_TIME) ; CellField.setTime(5.6,5,6) ; CellField.setMesh(m0) -CellField.setName("CellField") -CellField.fillFromAnalytic(1,"exp(-((x-1)*(x-1)+(y-1)*(y-1)))") ; CellField.getArray().setInfoOnComponent(0,"powercell [W]") -NodeField=MEDCouplingFieldDouble(ON_NODES,ONE_TIME) ; NodeField.setTime(5.6,5,6) ; NodeField.setMesh(m0) -NodeField.setName("NodeField") -NodeField.fillFromAnalytic(1,"exp(-((x-1)*(x-1)+(y-1)*(y-1)))") ; NodeField.getArray().setInfoOnComponent(0,"powernode [W]") -# -proc0=m0.getCellsInBoundingBox([(0.,0.4),(0.,0.4)],1e-10) -proc1=proc0.buildComplement(m0.getNumberOfCells()) -# -NodeField0=NodeField[proc0] ; NodeField0.getMesh().setName(m0.getName()) ; CellField0=CellField[proc0] ; CellField0.setMesh(NodeField0.getMesh()) -NodeField1=NodeField[proc1] ; NodeField1.getMesh().setName(m0.getName()) ; CellField1=CellField[proc1] ; CellField1.setMesh(NodeField1.getMesh()) -# -proc0_fname="proc0.med" -MEDLoader.WriteField(proc0_fname,NodeField0,True) -MEDLoader.WriteFieldUsingAlreadyWrittenMesh(proc0_fname,CellField0) -proc1_fname="proc1.med" -MEDLoader.WriteField(proc1_fname,NodeField1,True) -MEDLoader.WriteFieldUsingAlreadyWrittenMesh(proc1_fname,CellField1) -# -CellField0_read=MEDLoader.ReadFieldCell("proc0.med","mesh",0,"CellField",5,6) -CellField1_read=MEDLoader.ReadFieldCell("proc1.med","mesh",0,"CellField",5,6) -CellField_read=MEDCouplingFieldDouble.MergeFields([CellField0_read,CellField1_read]) -CellFieldCpy=CellField.deepCpy() -CellFieldCpy.substractInPlaceDM(CellField_read,10,1e-12) -CellFieldCpy.getArray().abs() -print CellFieldCpy.getArray().isUniform(0.,1e-12) -# -NodeField0_read=MEDLoader.ReadFieldNode("proc0.med","mesh",0,"NodeField",5,6) -NodeField1_read=MEDLoader.ReadFieldNode("proc1.med","mesh",0,"NodeField",5,6) -NodeField_read=MEDCouplingFieldDouble.MergeFields([NodeField0_read,NodeField1_read]) -NodeField_read.mergeNodes(1e-10) -NodeFieldCpy=NodeField.deepCpy() -NodeFieldCpy.mergeNodes(1e-10) -NodeFieldCpy.substractInPlaceDM(NodeField_read,10,1e-12) -print NodeFieldCpy.getArray().isUniform(0.,1e-12) ; assert NodeFieldCpy.getArray().isUniform(0.,1e-12) -# -fileNames=["proc0.med","proc1.med"] -msML=[MEDFileMesh.New(fname) for fname in fileNames] -fsML=[MEDFileFields.New(fname) for fname in fileNames] -mergeMLMesh=MEDFileUMesh() -mergeMLFields=MEDFileFields() -for lev in msML[0].getNonEmptyLevels(): - o2nML=len(msML[0].getNonEmptyLevels())*[None] - cs=[mML.getCoords() for mML in msML] - mergeMLMesh.setCoords(DataArrayDouble.Aggregate(cs)) - ms=[mML.getMeshAtLevel(lev) for mML in msML] - m=MEDCouplingUMesh.MergeUMeshes(ms) ; m.setCoords(mergeMLMesh.getCoords()) - o2nML[lev]=m.sortCellsInMEDFileFrmt() - mergeMLMesh.setMeshAtLevel(lev,m) - pass -# -for fieldName in fsML[0].getFieldsNames(): - fmts=[fML[fieldName] for fML in fsML] - mergeField=MEDFileFieldMultiTS() - for dt,it,tim in fmts[0].getTimeSteps(): - fts=[fmt[dt,it] for fmt in fmts] - arrs=len(fts)*[None] - for typp in fts[0].getTypesOfFieldAvailable(): - arr1s=[] - if typp==ON_CELLS: - for ft in fts: - for geoTyp,smth in ft.getFieldSplitedByType(): - if geoTyp!=NORM_ERROR: - smth1=filter(lambda x:x[0]==ON_CELLS,smth) - arr2s=[ft.getUndergroundDataArray()[elt[1][0]:elt[1][1]] for elt in smth1] - arr1s.append(DataArrayDouble.Aggregate(arr2s)) - pass - pass - pass - pass - else: - for ft in fts: - smth=filter(lambda x:x[0]==NORM_ERROR,ft.getFieldSplitedByType()) - arr2=DataArrayDouble.Aggregate([ft.getUndergroundDataArray()[elt[1][0][1][0]:elt[1][0][1][1]] for elt in smth]) - arr1s.append(arr2) - pass - pass - arr=DataArrayDouble.Aggregate(arr1s) - if typp==ON_CELLS: - arr.renumberInPlace(o2nML[lev]) - mcf=MEDCouplingFieldDouble(typp,ONE_TIME) ; mcf.setName(fieldName) ; mcf.setTime(tim,dt,it) ; mcf.setArray(arr) - mcf.setMesh(mergeMLMesh.getMeshAtLevel(lev)) ; mcf.checkCoherency() - mergeField.appendFieldNoProfileSBT(mcf) - pass - pass - mergeMLFields.pushField(mergeField) - pass -mergeMLMesh.write("merge.med",2) -mergeMLFields.write("merge.med",0) - -##### - -arr=DataArrayDouble(11) ; arr.iota(0) -trgMesh=MEDCouplingCMesh() ; trgMesh.setCoords(arr,arr) ; trgMesh=trgMesh.buildUnstructured() -# -arr=DataArrayDouble(21) ; arr.iota(0) ; arr*=0.5 -srcMesh=MEDCouplingCMesh() ; srcMesh.setCoords(arr,arr) ; srcMesh=srcMesh.buildUnstructured() -# -tmp=srcMesh[:20] ; tmp.simplexize(0) -srcMesh=MEDCouplingUMesh.MergeUMeshes([tmp,srcMesh[20:]]) -# -remap=MEDCouplingRemapper() -remap.prepare(srcMesh,trgMesh,"P0P0") -# -myMatrix=remap.getCrudeMatrix() -print myMatrix # pour voir a quoi elle ressemble -sumByRows=DataArrayDouble(len(myMatrix)) -for i,wIt in enumerate(sumByRows): - su=0. - for it in myMatrix[i]: - su+=myMatrix[i][it] - wIt[0]=su -print "Does interpolation look OK ? %s"%(str(sumByRows.isUniform(1.,1e-12))) ; assert sumByRows.isUniform(1.,1e-12) -# -srcField=MEDCouplingFieldDouble(ON_CELLS,ONE_TIME) ; srcField.setMesh(srcMesh) -srcField.fillFromAnalytic(1,"7-sqrt((x-5.)*(x-5.)+(y-5.)*(y-5.))") ; CellField.getArray().setInfoOnComponent(0,"powercell [W]") -# -#remap.transferField(srcField,1e300) -srcField.setNature(ConservativeVolumic) -trgFieldCV=remap.transferField(srcField,1e300) -# -print "ConservativeVolumic %lf == %lf"%(srcField.integral(True)[0],trgFieldCV.integral(True)[0]) ; assert abs(srcField.integral(True)[0]-trgFieldCV.integral(True)[0])<1e-6 -print "ConservativeVolumic %lf != %lf"%(srcField.getArray().accumulate()[0],trgFieldCV.getArray().accumulate()[0]) ; assert abs(srcField.getArray().accumulate()[0]-trgFieldCV.getArray().accumulate()[0])>1e-6 -# -srcField.setNature(Integral) -trgFieldI=remap.transferField(srcField,1e300) -# -print "IntegralGlobConstraint %lf != %lf"%(srcField.integral(True)[0],trgFieldI.integral(True)[0]) ; assert abs(srcField.integral(True)[0]-trgFieldI.integral(True)[0])>1e-6 -print "IntegralGlobConstraint %lf == %lf"%(srcField.getArray().accumulate()[0],trgFieldI.getArray().accumulate()[0]) ; assert abs(srcField.getArray().accumulate()[0]-trgFieldI.getArray().accumulate()[0])<1e-6 - -###### - -from numpy import * -from math import acos - -med_root_dir=os.getenv("MED_ROOT_DIR") -agitateur_file=os.path.join(os.getenv("MED_ROOT_DIR"),"share","salome","resources","med","agitateur.med") -data=MEDFileData(agitateur_file) -ts=data.getFields()[0].getTimeSteps() -print ts -# -fMts=data.getFields()["DISTANCE_INTERFACE_ELEM_BODY_ELEM_DOM"] -f1ts=fMts[(2,-1)] -fMc=f1ts.getFieldAtLevel(ON_CELLS,0) -arr=fMc.getArray() -arr.getMinMaxPerComponent() # juste pour voir la plage de variation du champ par compo -ids=arr.getIdsInRange(0.,1.) -f2Mc=fMc[ids] -# -pressMts=data.getFields()["PRESSION_ELEM_DOM"] -press1ts=pressMts[(2,-1)] -pressMc=press1ts.getFieldAtLevel(ON_CELLS,0) -pressOnAgitateurMc=pressMc[ids] -# -pressOnAgitateurMc.getMesh().zipCoords() -# -agitateurMesh3DMc=pressOnAgitateurMc.getMesh() -m3DSurf,desc,descI,revDesc,revDescI=agitateurMesh3DMc.buildDescendingConnectivity() -nbOf3DCellSharing=revDescI.deltaShiftIndex() -ids2=nbOf3DCellSharing.getIdsEqual(1) -agitateurSkinMc=m3DSurf[ids2] -OffsetsOfTupleIdsInField=revDescI[ids2] -tupleIdsInField=revDesc[OffsetsOfTupleIdsInField] -pressOnSkinAgitateurMc=pressOnAgitateurMc[tupleIdsInField] -pressOnSkinAgitateurMc.setMesh(agitateurSkinMc) -# -pressSkin=pressOnSkinAgitateurMc.getArray() -pressSkin*=1e5 -areaSkin=agitateurSkinMc.getMeasureField(True).getArray() -forceSkin=pressSkin*areaSkin -normalSkin=agitateurSkinMc.buildOrthogonalField().getArray() -forceVectSkin=forceSkin*normalSkin -# -singlePolyhedron=agitateurMesh3DMc.buildSpreadZonesWithPoly() -singlePolyhedron.orientCorrectlyPolyhedrons() -centerOfMass=singlePolyhedron.getBarycenterAndOwner() - -barySkin=agitateurSkinMc.getBarycenterAndOwner() -posSkin=barySkin-centerOfMass - -torquePerCellOnSkin=DataArrayDouble.CrossProduct(posSkin,forceVectSkin) - -zeTorque=torquePerCellOnSkin.accumulate() -print "couple = %r N.m"%(zeTorque[2]) ; assert abs(zeTorque[2]-0.37)<1e-2 - -speedMts=data.getFields()["VITESSE_ELEM_DOM"] -speed1ts=speedMts[(2,-1)] -speedMc=speed1ts.getFieldAtLevel(ON_CELLS,0) -speedOnSkin=speedMc.getArray()[tupleIdsInField] -powerSkin=DataArrayDouble.Dot(forceVectSkin,speedOnSkin) -power=powerSkin.accumulate()[0] -print "power = %r W"%(power) ; assert abs(power-4.22)<1e-2 - -x2=posSkin[:,0]*posSkin[:,0] ; x2=x2.accumulate()[0] -y2=posSkin[:,1]*posSkin[:,1] ; y2=y2.accumulate()[0] -xy=posSkin[:,0]*posSkin[:,1] ; xy=xy.accumulate()[0] -inertiaSkin=matrix([[x2,xy],[xy,y2]]) -inertiaSkinValues,inertiaSkinVects=linalg.eig(inertiaSkin) -pos=max(enumerate(inertiaSkinValues),key=lambda x: x[1])[0] -vect0=inertiaSkinVects[pos].tolist()[0] -print vect0 - -def computeAngle(locAgitateur1ts): - fMc=locAgitateur1ts.getFieldAtLevel(ON_CELLS,0) - arr=fMc.getArray() - ids=arr.getIdsInRange(0.,1.) - f2Mc=fMc[ids] - m3DSurf,desc,descI,revDesc,revDescI=f2Mc.getMesh().buildDescendingConnectivity() - nbOf3DCellSharing=revDescI.deltaShiftIndex() - ids2=nbOf3DCellSharing.getIdsEqual(1) - agitateurSkinMc=m3DSurf[ids2] - # - singlePolyhedron=agitateurMesh3DMc.buildSpreadZonesWithPoly() - singlePolyhedron.orientCorrectlyPolyhedrons() - centerOfMass=singlePolyhedron.getBarycenterAndOwner() - bary=agitateurSkinMc.getBarycenterAndOwner() - posSkin=bary-centerOfMass - x2=posSkin[:,0]*posSkin[:,0] ; x2=x2.accumulate()[0] - y2=posSkin[:,1]*posSkin[:,1] ; y2=y2.accumulate()[0] - xy=posSkin[:,0]*posSkin[:,1] ; xy=xy.accumulate()[0] - inertiaSkin=matrix([[x2,xy],[xy,y2]]) - inertiaSkinValues,inertiaSkinVects=linalg.eig(inertiaSkin) - pos=max(enumerate(inertiaSkinValues),key=lambda x: x[1])[0] - vect0=inertiaSkinVects[pos].tolist()[0] - return vect0 - -vects=len(ts)*[None] -for itts,locAgitateur1ts in zip(ts,data.getFields()["DISTANCE_INTERFACE_ELEM_BODY_ELEM_DOM"]): - angle=computeAngle(locAgitateur1ts) - vects[itts[0]]=angle - pass - -angle2=len(ts)*[0.] -for pos in xrange(2,len(vects)): - norm1=sqrt(vects[pos-1][0]*vects[pos-1][0]+vects[pos-1][1]*vects[pos-1][1]) - norm2=sqrt(vects[pos][0]*vects[pos][0]+vects[pos][1]*vects[pos][1]) - crs=vects[pos-1][0]*vects[pos][0]+vects[pos-1][1]*vects[pos][1] - crs/=norm1 ; crs/=norm2 ; crs=min(crs,1.) - angle2[pos]=acos(crs)#/(ts[pos][2]-ts[pos-1][2]) - pass - -omega=sum(angle2)/(ts[-1][2]-ts[0][2]) -print sum(angle2) ; assert abs(sum(angle2)-1.12)<1e-2 -print "Au pdt (%d,%d) a %r s le couple est de : %r N.m, power/omega=%r N.m"%(ts[2][0],ts[2][1],ts[2][2],zeTorque[2],power/omega) -assert abs(power/omega-0.37)<1e-2 diff --git a/src/MEDLoader/Swig/MEDLoaderDataForTest.py b/src/MEDLoader/Swig/MEDLoaderDataForTest.py deleted file mode 100644 index e8f0f5332..000000000 --- a/src/MEDLoader/Swig/MEDLoaderDataForTest.py +++ /dev/null @@ -1,728 +0,0 @@ -# -*- coding: iso-8859-1 -*- -# Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 -# 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) - -from MEDLoader import * -from math import pi,e,sqrt - -class MEDLoaderDataForTest: - def build1DMesh_1(cls): - coords=[ 0.0, 0.3, 0.75, 1.0, 1.4, 1.3 ] - conn=[ 0,1, 1,2, 2,3 , 3,4,5] - mesh=MEDCouplingUMesh.New(); - mesh.setName("1DMesh_1"); - mesh.setMeshDimension(1); - mesh.allocateCells(4); - mesh.insertNextCell(NORM_SEG2,2,conn[0:2]) - mesh.insertNextCell(NORM_SEG2,2,conn[2:4]) - mesh.insertNextCell(NORM_SEG2,2,conn[4:6]) - mesh.insertNextCell(NORM_SEG3,3,conn[6:9]) - mesh.finishInsertingCells(); - myCoords=DataArrayDouble.New(); - myCoords.setValues(coords,6,1); - myCoords.setInfoOnComponent(0,"tototototototot [m*m*m*m*m*m*m*m]"); - mesh.setCoords(myCoords); - return mesh; - - def build2DCurveMesh_1(cls): - coords=[ 0.0,0.0, 0.3,0.3, 0.75,0.75, 1.0,1.0, 1.4,1.4, 1.3,1.3 ] - conn=[ 0,1, 1,2, 2,3 , 3,4,5] - mesh=MEDCouplingUMesh.New(); - mesh.setName("2DCurveMesh_1"); - mesh.setMeshDimension(1); - mesh.allocateCells(4); - mesh.insertNextCell(NORM_SEG2,2,conn[0:2]) - mesh.insertNextCell(NORM_SEG2,2,conn[2:4]) - mesh.insertNextCell(NORM_SEG2,2,conn[4:6]) - mesh.insertNextCell(NORM_SEG3,3,conn[6:9]) - mesh.finishInsertingCells(); - myCoords=DataArrayDouble.New(); - myCoords.setValues(coords,6,2); - mesh.setCoords(myCoords); - return mesh; - - def build2DMesh_1(cls): - targetCoords=[-0.3,-0.3, 0.2,-0.3, 0.7,-0.3, -0.3,0.2, 0.2,0.2, 0.7,0.2, -0.3,0.7, 0.2,0.7, 0.7,0.7, - -0.05,0.95, 0.2,1.2, 0.45,0.95] - targetConn=[1,4,2, 4,5,2, 6,10,8,9,11,7, 0,3,4,1, 6,7,4,3, 7,8,5,4] - targetMesh=MEDCouplingUMesh.New(); - targetMesh.setMeshDimension(2); - targetMesh.allocateCells(6); - targetMesh.setName("2DMesh_1"); - targetMesh.insertNextCell(NORM_TRI3,3,targetConn[0:3]) - targetMesh.insertNextCell(NORM_TRI3,3,targetConn[3:6]) - targetMesh.insertNextCell(NORM_TRI6,6,targetConn[6:12]) - targetMesh.insertNextCell(NORM_QUAD4,4,targetConn[12:16]) - targetMesh.insertNextCell(NORM_QUAD4,4,targetConn[16:20]) - targetMesh.insertNextCell(NORM_POLYGON,4,targetConn[20:24]) - targetMesh.finishInsertingCells(); - myCoords=DataArrayDouble.New(); - myCoords.setValues(targetCoords,12,2); - myCoords.setInfoOnComponent(0,"tototototototot [m]"); - myCoords.setInfoOnComponent(1,"energie [kW]"); - targetMesh.setCoords(myCoords) - return targetMesh; - - def build2DMesh_2(cls): - targetCoords=[-0.3,-0.3, 0.2,-0.3, 0.7,-0.3, -0.3,0.2, 0.2,0.2, 0.7,0.2, -0.3,0.7, 0.2,0.7, 0.7,0.7, - -0.05,0.95, 0.2,1.2, 0.45,0.95] - targetConn=[1,4,2, 4,5,2, 6,10,8,9,11,7, 0,3,4,1, 6,7,4,3, 7,8,5,4] - targetMesh=MEDCouplingUMesh.New(); - targetMesh.setMeshDimension(2); - targetMesh.allocateCells(5); - targetMesh.setName("2DMesh_2"); - targetMesh.insertNextCell(NORM_TRI3,3,targetConn[0:3]) - targetMesh.insertNextCell(NORM_TRI3,3,targetConn[3:6]) - targetMesh.insertNextCell(NORM_QUAD4,4,targetConn[12:16]) - targetMesh.insertNextCell(NORM_QUAD4,4,targetConn[16:20]) - targetMesh.insertNextCell(NORM_TRI6,6,targetConn[6:12]) - targetMesh.finishInsertingCells(); - myCoords=DataArrayDouble.New(); - myCoords.setValues(targetCoords,12,2); - myCoords.setInfoOnComponent(0,"toto [m]"); - myCoords.setInfoOnComponent(1,"energie [kW]"); - targetMesh.setCoords(myCoords); - return targetMesh; - - #this mesh has several cells duplicated ! it is not beautiful but efficient to test file WR. - def build2DMesh_3(cls): - targetCoords=[-0.3,-0.3, 0.2,-0.3, 0.7,-0.3, -0.3,0.2, 0.2,0.2, 0.7,0.2, -0.3,0.7, 0.2,0.7, 0.7,0.7, - -0.05,0.95, 0.2,1.2, 0.45,0.95] - targetConn=[1,4,2, 4,5,2, 6,10,8,9,11,7, 0,3,4,1, 6,7,4,3, 7,8,5,4] - targetMesh=MEDCouplingUMesh.New(); - targetMesh.setMeshDimension(2); - targetMesh.allocateCells(13); - targetMesh.setName("2DMesh_3"); - targetMesh.insertNextCell(NORM_TRI3,3,targetConn[0:3]) - targetMesh.insertNextCell(NORM_TRI3,3,targetConn[3:6]) - targetMesh.insertNextCell(NORM_TRI3,3,targetConn[0:3]) - targetMesh.insertNextCell(NORM_TRI3,3,targetConn[3:6]) - targetMesh.insertNextCell(NORM_TRI3,3,targetConn[0:3]) - targetMesh.insertNextCell(NORM_TRI3,3,targetConn[3:6]) - targetMesh.insertNextCell(NORM_QUAD4,4,targetConn[12:16]) - targetMesh.insertNextCell(NORM_QUAD4,4,targetConn[16:20]) - targetMesh.insertNextCell(NORM_QUAD4,4,targetConn[12:16]) - targetMesh.insertNextCell(NORM_QUAD4,4,targetConn[16:20]) - targetMesh.insertNextCell(NORM_TRI6,6,targetConn[6:12]) - targetMesh.insertNextCell(NORM_TRI6,6,targetConn[6:12]) - targetMesh.insertNextCell(NORM_TRI6,6,targetConn[6:12]) - targetMesh.finishInsertingCells(); - myCoords=DataArrayDouble.New(); - myCoords.setValues(targetCoords,12,2); - myCoords.setInfoOnComponent(0,"toto [m]"); - myCoords.setInfoOnComponent(1,"energie [kW]"); - targetMesh.setCoords(myCoords); - return targetMesh; - - def build3DMesh_1(cls): - coords=[0.,0.,0., 1.,1.,0., 1.,1.25,0., 0.,1.,0., 1.,1.5,0., 2.,0.,0., 2.,1.,0., 1.,2.,0., 0.,2.,0., 3.,1.,0., - 3.,2.,0., 0.,1.,0., 1.,3.,0., 2.,2.,0., 2.,3.,0., - 0.,0.,1., 1.,1.,1., 1.,1.25,1., 0.,1.,1., 1.,1.5,1., 2.,0.,1., 2.,1.,1., 1.,2.,1., 0.,2.,1., 3.,1.,1., - 3.,2.,1., 0.,1.,1., 1.,3.,1., 2.,2.,1., 2.,3.,1., - 0.,0.,2., 1.,1.,2., 1.,1.25,2., 0.,1.,2., 1.,1.5,2., 2.,0.,2., 2.,1.,2., 1.,2.,2., 0.,2.,2., 3.,1.,2., - 3.,2.,2., 0.,1.,2., 1.,3.,2., 2.,2.,2., 2.,3.,2., - 0.,0.,3., 1.,1.,3., 1.,1.25,3., 0.,1.,3., 1.,1.5,3., 2.,0.,3., 2.,1.,3., 1.,2.,3., 0.,2.,3., 3.,1.,3., - 3.,2.,3., 0.,1.,3., 1.,3.,3., 2.,2.,3., 2.,3.,3.] - conn=[ - # 0 - 0,11,1,3,15,26,16,18, 1,2,4,7,13,6,-1,1,16,21,6,-1,6,21,28,13,-1,13,7,22,28,-1,7,4,19,22,-1,4,2,17,19,-1,2,1,16,17,-1,16,21,28,22,19,17, - 1,6,5,3,16,21,20,18, 13,10,9,6,28,25,24,21, - 11,8,7,4,2,1,-1,11,26,16,1,-1,1,16,17,2,-1,2,17,19,4,-1,4,19,22,7,-1,7,8,23,22,-1,8,11,26,23,-1,26,16,17,19,22,23, - 7,12,14,13,22,27,29,28, - # 1 - 15,26,16,18,30,41,31,33, 16,17,19,22,28,21,-1,16,31,36,21,-1,21,36,43,28,-1,28,22,37,43,-1,22,19,34,37,-1,19,17,32,34,-1,17,16,31,32,-1,31,36,43,37,34,32, - 16,21,20,18,31,36,35,33, 28,25,24,21,43,40,39,36, - 26,23,22,19,17,16,-1,26,41,31,16,-1,16,31,32,17,-1,17,32,34,19,-1,19,34,37,22,-1,22,23,38,37,-1,23,26,41,38,-1,41,31,32,34,37,38, - 22,27,29,28,37,42,44,43, - # 2 - 30,41,31,33,45,56,46,48, 31,32,34,37,43,36,-1,31,46,51,36,-1,36,51,58,43,-1,43,37,52,58,-1,37,34,49,52,-1,34,32,47,49,-1,32,31,46,47,-1,46,51,58,52,49,47, - 31,36,35,33,46,51,50,48, 43,40,39,36,58,55,54,51, - 41,38,37,34,32,31,-1,41,56,46,31,-1,31,46,47,32,-1,32,47,49,34,-1,34,49,52,37,-1,37,38,53,52,-1,38,41,56,53,-1,56,46,47,49,52,53, - 37,42,44,43,52,57,59,58] - # - ret=MEDCouplingUMesh.New(); - ret.setName("3DMesh_1"); - ret.setMeshDimension(3); - ret.allocateCells(18); - # - ret.insertNextCell(NORM_HEXA8,8,conn[0:8]) - ret.insertNextCell(NORM_HEXA8,8,conn[51:59]) - ret.insertNextCell(NORM_HEXA8,8,conn[59:67]) - ret.insertNextCell(NORM_HEXA8,8,conn[110:118]) - # - ret.insertNextCell(NORM_HEXA8,8,conn[118:126]) - ret.insertNextCell(NORM_HEXA8,8,conn[169:177]) - ret.insertNextCell(NORM_HEXA8,8,conn[177:185]) - ret.insertNextCell(NORM_HEXA8,8,conn[228:236]) - # - ret.insertNextCell(NORM_HEXA8,8,conn[236:244]) - ret.insertNextCell(NORM_HEXA8,8,conn[287:295]) - ret.insertNextCell(NORM_HEXA8,8,conn[295:303]) - ret.insertNextCell(NORM_HEXA8,8,conn[346:354]) - # - ret.insertNextCell(NORM_POLYHED,43,conn[8:51]) - ret.insertNextCell(NORM_POLYHED,43,conn[67:110]) - ret.insertNextCell(NORM_POLYHED,43,conn[126:169]) - ret.insertNextCell(NORM_POLYHED,43,conn[185:228]) - ret.insertNextCell(NORM_POLYHED,43,conn[244:287]) - ret.insertNextCell(NORM_POLYHED,43,conn[303:346]) - # - ret.finishInsertingCells(); - myCoords=DataArrayDouble.New(); - myCoords.setValues(coords,60,3); - myCoords.setInfoOnComponent(0,"titi [m]"); - myCoords.setInfoOnComponent(1,"density power [MW/m^3]"); - myCoords.setInfoOnComponent(2,"t [kW]"); - ret.setCoords(myCoords); - return ret; - - def build3DSurfMesh_1(cls): - targetCoords=[-0.3,-0.3,-0.3, 0.2,-0.3,-0.3, 0.7,-0.3,-0.3, -0.3,0.2,-0.3, 0.2,0.2,-0.3, 0.7,0.2,-0.3, -0.3,0.7,-0.3, 0.2,0.7,-0.3, 0.7,0.7,-0.3 - ,-0.05,0.95,-0.3, 0.2,1.2,-0.3, 0.45,0.95,-0.3] - targetConn=[1,4,2, 4,5,2, 6,10,8,9,11,7, 0,3,4,1, 6,7,4,3, 7,8,5,4] - targetMesh=MEDCouplingUMesh.New(); - targetMesh.setMeshDimension(2); - targetMesh.allocateCells(6); - targetMesh.setName("3DSurfMesh_1"); - targetMesh.insertNextCell(NORM_TRI3,3,targetConn[0:3]) - targetMesh.insertNextCell(NORM_TRI3,3,targetConn[3:6]) - targetMesh.insertNextCell(NORM_QUAD4,4,targetConn[12:16]) - targetMesh.insertNextCell(NORM_QUAD4,4,targetConn[16:20]) - targetMesh.insertNextCell(NORM_TRI6,6,targetConn[6:12]) - targetMesh.insertNextCell(NORM_POLYGON,4,targetConn[20:24]) - targetMesh.finishInsertingCells(); - myCoords=DataArrayDouble.New(); - myCoords.setValues(targetCoords,12,3); - myCoords.setInfoOnComponent(0,"toto [m]"); - myCoords.setInfoOnComponent(2,"ff [km]");#component 1 is not set for test - targetMesh.setCoords(myCoords); - return targetMesh; - - def build3DMesh_2(cls): - m3dsurfBase=MEDLoaderDataForTest.build3DSurfMesh_1(); - numbers=[0,1,2,3,5] - m3dsurf=m3dsurfBase.buildPartOfMySelf(numbers,False); - m1dBase=MEDLoaderDataForTest.build1DMesh_1(); - numbers2=[0,1,2,3] - m1d=m1dBase.buildPartOfMySelf(numbers2,False); - m1d.changeSpaceDimension(3); - vec=[0.,1.,0.] - pt=[0.,0.,0.] - m1d.rotate(pt,vec,-pi/2.); - ret=m3dsurf.buildExtrudedMesh(m1d,0); - return ret; - - def buildMultiLevelMesh_1(cls): - coo=[10.,0.,10.,1.25,10.,2.5,10.,3.75,10.,5.,8.75,0.,8.75,1.25,8.75,2.5,8.75,3.75,8.75,5.,7.5,0.,7.5,1.25,7.5,2.5,7.5,3.75,7.5,5.,6.25,0.,6.25,1.25,6.25,2.5,6.25,3.75,6.25,5.,5.,0.,5.,1.25,5.,2.5,5.,3.75,5.,5.,3.75,0.,3.75,1.25,3.75,2.5,3.75,3.75,3.75,5.,2.5,0.,2.5,1.25,2.5,2.5,2.5,3.75,2.5,5.,1.25,0.,1.25,1.25,1.25,2.5,1.25,3.75,1.25,5.,0.,1.25,0.,2.5,0.,3.75,0.,5.,0.,0.,0.,5.,10.,5.,0.,10.,10.,10.,5.,5.,5.,5.,5.,10.,5.,10.,0.625,5.,1.25,5.,1.875,5.,2.5,5.,3.125,5.,3.75,5.,4.375,5.,5.,6.25,5.,7.5,5.,8.75,4.375,10.,3.75,10.,3.125,10.,2.5,10.,1.875,10.,1.25,10.,0.625,10.,0.,8.75,0.,7.5,0.,6.25,4.375,6.25,4.375,7.5,4.375,8.75,3.75,6.25,3.75,7.5,3.75,8.75,3.125,6.25,3.125,7.5,3.125,8.75,2.5,6.25,2.5,7.5,2.5,8.75,1.875,6.25,1.875,7.5,1.875,8.75,1.25,6.25,1.25,7.5,1.25,8.75,0.625,6.25,0.625,7.5,0.625,8.75,5.625,5.,6.25,5.,6.875,5.,7.5,5.,8.125,5.,8.75,5.,9.375,5.,10.,6.25,10.,7.5,10.,8.75,9.375,10.,8.75,10.,8.125,10.,7.5,10.,6.875,10.,6.25,10.,5.625,10.,5.,8.75,5.,7.5,5.,6.25,9.375,6.25,9.375,7.5,9.375,8.75,8.75,6.25,8.75,7.5,8.75,8.75,8.125,6.25,8.125,7.5,8.125,8.75,7.5,6.25,7.5,7.5,7.5,8.75,6.875,6.25,6.875,7.5,6.875,8.75,6.25,6.25,6.25,7.5,6.25,8.75,5.625,6.25,5.625,7.5,5.625,8.75] - coo2=DataArrayDouble.New() - coo2.setValues(coo,135,2) - coo2=coo2.changeNbOfComponents(3,0.) - coo2.setInfoOnComponent(0,"X [INCONNUE]") - coo2.setInfoOnComponent(1,"Y [INCONNUE]") - coo2.setInfoOnComponent(2,"Z [INCONNUE]") - c2tri=[0,1,6,0,6,5,1,2,6,2,7,6,2,3,8,2,8,7,3,4,8,4,9,8,5,6,11,5,11,10,6,7,11,7,12,11,7,8,13,7,13,12,8,9,13,9,14,13,10,11,16,10,16,15,11,12,16,12,17,16,12,13,18,12,18,17,13,14,18,14,19,18,15,16,21,15,21,20,16,17,21,17,22,21,17,18,23,17,23,22,18,19,23,19,24,23,20,21,26,20,26,25,21,22,26,22,27,26,22,23,28,22,28,27,23,24,28,24,29,28,25,26,31,25,31,30,26,27,31,27,32,31,27,28,33,27,33,32,28,29,33,29,34,33,30,31,36,30,36,35,31,32,36,32,37,36,32,33,38,32,38,37,33,34,38,34,39,38,35,36,40,35,40,44,36,37,40,37,41,40,37,38,42,37,42,41,38,39,42,39,43,42] - c2quad4=[46,101,114,100,101,102,115,114,102,103,116,115,103,48,104,116,100,114,117,99,114,115,118,117,115,116,119,118,116,104,105,119,99,117,120,98,117,118,121,120,118,119,122,121,119,105,106,122,98,120,123,97,120,121,124,123,121,122,125,124,122,106,107,125,97,123,126,96,123,124,127,126,124,125,128,127,125,107,108,128,96,126,129,95,126,127,130,129,127,128,131,130,128,108,109,131,95,129,132,94,129,130,133,132,130,131,134,133,131,109,110,134,94,132,113,50,132,133,112,113,133,134,111,112,134,110,51,111,49,60,73,59,60,61,74,73,61,62,75,74,62,52,63,75,59,73,76,58,73,74,77,76,74,75,78,77,75,63,64,78,58,76,79,57,76,77,80,79,77,78,81,80,78,64,65,81,57,79,82,56,79,80,83,82,80,81,84,83,81,65,66,84,56,82,85,55,82,83,86,85,83,84,87,86,84,66,67,87,55,85,88,54,85,86,89,88,86,87,90,89,87,67,68,90,54,88,91,53,88,89,92,91,89,90,93,92,90,68,69,93,53,91,72,45,91,92,71,72,92,93,70,71,93,69,47,70] - m2=MEDCouplingUMesh.New("ma",2) - m2.setCoords(coo2) - m2.allocateCells(128) - nbTri=len(c2tri)/3 - for i in xrange(nbTri): - m2.insertNextCell(NORM_TRI3,3,c2tri[3*i:3*i+3]) - pass - nbQua=len(c2quad4)/4 - for i in xrange(nbQua): - m2.insertNextCell(NORM_QUAD4,4,c2quad4[4*i:4*i+4]) - pass - m2.finishInsertingCells() - m2.setDescription("CREE PAR CODE_ASTER") - m1=MEDCouplingUMesh.New("ma",1) - m1.setCoords(coo2) - c1seg=[0,1,1,2,2,3,3,4,4,9,9,14,14,19,19,24,24,29,29,34,34,39,39,43,43,42,42,41,41,40,40,44,44,35,35,30,30,25,25,20,20,15,15,10,10,5,5,0,43,39,39,34,34,29,29,24,24,19,19,14,14,9,9,4,45,53,53,54,54,55,55,56,56,57,57,58,58,59,59,49,49,60,60,61,61,62,62,52,52,63,63,64,64,65,65,66,66,67,67,68,68,69,69,47,47,70,70,71,71,72,72,45,50,94,94,95,95,96,96,97,97,98,98,99,99,100,100,46,46,101,101,102,102,103,103,48,48,104,104,105,105,106,106,107,107,108,108,109,109,110,110,51,51,111,111,112,112,113,113,50] - m1.allocateCells(80) - for i in xrange(80): - m1.insertNextCell(NORM_SEG2,2,c1seg[2*i:2*i+2]) - pass - m1.finishInsertingCells() - m1.setDescription("CREE PAR CODE_ASTER") - m0=MEDCouplingUMesh.New("ma",0) - m0.setCoords(coo2) - c0pt=[44,0,47,48] - m0.allocateCells(4) - for i in xrange(4): - m0.insertNextCell(NORM_POINT1,1,[c0pt[i]]) - pass - m0.finishInsertingCells() - f2=DataArrayInt.New() - f2.alloc(128,1) - f2[:64]=-1 - f2[64:96]=-2 - f2[96:]=-3 - f1=DataArrayInt.New() - f1.alloc(80,1) - f1[:4]=-8 - f1[4:12]=-9 - f1[12:16]=-10 - f1[16:24]=-11 - f1[24:28]=-12 - f1[28:32]=-13 - f1[32:40]=-14 - f1[40:44]=-15 - f1[44:52]=-16 - f1[52:56]=-17 - f1[56:64]=-18 - f1[64:68]=-19 - f1[68:76]=-20 - f1[76:]=-21 - f0=DataArrayInt.New() - f0.setValues([-4,-5,-6,-7],4,1) - p=DataArrayInt.New() - p.alloc(135,1) - p.fillWithZero() - p1=DataArrayInt.New() - p1.alloc(13,1) - p1.iota(1) - p[[0,4,24,43,44,45,46,47,48,49,50,51,52]]=p1 - n2=DataArrayInt.New() - n2.alloc(128,1) - n2.iota(1) - n1=DataArrayInt.New() - n1.alloc(80,1) - n1.iota(133) - n0=DataArrayInt.New() - n0.alloc(4,1) - n0.iota(129) - fns=['A1A2____________________________', 'A1______________________________', 'A2A4____________________________', 'A2______________________________', 'A3A1____________________________', 'A3C5____________________________', 'A3______________________________', 'A4A3____________________________', 'A4______________________________', 'B1C1____________________________', 'B1______________________________', 'B2B4____________________________', 'B2______________________________', 'B3B1____________________________', 'B3______________________________', 'B4C3____________________________', 'B4______________________________', 'C1C4____________________________', 'C1______________________________', 'C2B2____________________________', 'C2______________________________', 'C3C2____________________________', 'C3______________________________', 'C4B3____________________________', 'C4______________________________', 'C5A4____________________________', 'C5______PMMA____________________', 'FAMILLE_ZERO', 'MESH____APPS____AP1_____________', 'MESH____APPS____AP2_____________', 'MESH____APPS____AP3_____________', 'MESH____APPS____AP4_____________', 'MESH____DALQ1___DALLE___________', 'MESH____DALQ2___DALLE___________', 'MESH____DALT3___DALLE___________'] - fids=[-11, 5, -8, 1, -10, -12, 4, -9, 2, -14, 6, -19, 7, -17, 8, -20, 9, -15, 10, -18, 11, -21, 12, -16, 13, -13, 3, 0, -4, -5, -6, -7, -3, -2, -1] - grpns=['A1', 'A1A2', 'A2', 'A2A4', 'A3', 'A3A1', 'A3C5', 'A4', 'A4A3', 'AP1', 'AP2', 'AP3', 'AP4', 'APPS', 'B1', 'B1C1', 'B2', 'B2B4', 'B3', 'B3B1', 'B4', 'B4C3', 'C1', 'C1C4', 'C2', 'C2B2', 'C3', 'C3C2', 'C4', 'C4B3', 'C5', 'C5A4', 'DALLE', 'DALQ1', 'DALQ2', 'DALT3', 'MESH', 'PMMA'] - famIdsPerGrp=[[5],[-11],[1],[-8],[4],[-10],[-12],[2],[-9],[-4],[-5],[-6],[-7],[-4,-5,-6,-7],[6],[-14],[7],[-19],[8],[-17],[9],[-20],[10],[-15],[11],[-18],[12],[-21],[13],[-16],[3],[-13],[-3,-2,-1],[-3],[-2],[-1],[-4,-5,-6,-7,-3,-2,-1],[3]] - return m2,m1,m0,f2,f1,f0,p,n2,n1,n0,fns,fids,grpns,famIdsPerGrp - - def buildMLMeshUnPolyze(cls,tester): - """Level 0 (meshDim=3) - 2 TETRA4 + 3 PENTA6 + 2 POLYH - # POLYH #0 becomes 1 TETRA4 - # POLYH #1 becomes HEXA8 - # Level -1 (meshDim=2) - 2 TRI3 + 3 QUAD4 + 4 POLYG - # POLYG #2 becomes TRI3""" - meshName="NightmareMesh" - # - coords=DataArrayDouble.New(38,3) ; coords.rearrange(1) ; coords.iota(1000.) ; coords.rearrange(3) ; coords.setInfoOnComponents(["X [m]","Y [m]","Z [m]"]) - mesh0=MEDCouplingUMesh(meshName,3) - type0=[NORM_TETRA4,NORM_TETRA4, NORM_PENTA6,NORM_PENTA6,NORM_PENTA6, NORM_POLYHED,NORM_POLYHED] - conn0=[[0,1,2,3],[4,5,6,7], [8,9,10,11,12,13],[14,15,16,17,18,19],[20,21,22,23,24,25], [26,27,28,-1,26,29,27,-1,27,29,28,-1,28,29,26],[30,31,32,33,-1,34,37,36,35,-1,30,34,35,31,-1,31,35,36,32,-1,32,36,37,33,-1,33,37,34,30]] - mesh0.allocateCells(len(type0)) - for typ,nodalConn in zip(type0,conn0): - mesh0.insertNextCell(typ,nodalConn); - pass - mesh0.finishInsertingCells() - mesh0.setCoords(coords) - - meshM1=MEDCouplingUMesh(meshName,2) - typeM1=[NORM_TRI3,NORM_TRI3, NORM_QUAD4,NORM_QUAD4,NORM_QUAD4, NORM_POLYGON,NORM_POLYGON,NORM_POLYGON,NORM_POLYGON] - connM1=[[0,1,2],[3,4,5], [6,7,8,9],[10,11,12,13],[14,15,16,17], [18,19,20,21,22],[23,24,25,26,27],[28,29,30],[31,32,33,34,35,36,37]] - meshM1.allocateCells(len(typeM1)) - for typ,nodalConn in zip(typeM1,connM1): - meshM1.insertNextCell(typ,nodalConn); - pass - meshM1.finishInsertingCells() - meshM1.setCoords(coords) - # - mm=MEDFileUMesh.New() - mm.setMeshAtLevel(0,mesh0) - mm.setMeshAtLevel(-1,meshM1) - grp0_L0=DataArrayInt.New([0,1,5,7]) ; grp0_L0.setName("grp0_L0") - grp1_L0=DataArrayInt.New([1,2,3,4,6]) ; grp1_L0.setName("grp1_L0") - tester.assertRaises(InterpKernelException,mm.setGroupsAtLevel,0,[grp0_L0,grp1_L0])# presence of 7 in grp0_L0 (only 7 cells at level 0) -> throw - grp0_L0=DataArrayInt.New([0,1,5,6]) ; grp0_L0.setName("grp0_L0") - mm.setGroupsAtLevel(0,[grp0_L0,grp1_L0]) - grp0_LM1=DataArrayInt.New([1,2,3,4,7]) ; grp0_LM1.setName("grp0_LM1") - grp1_LM1=DataArrayInt.New([2,3,4,5]) ; grp1_LM1.setName("grp1_LM1") - grp2_LM1=DataArrayInt.New([5,6,7,8]) ; grp2_LM1.setName("grp2_LM1") - mm.setGroupsAtLevel(-1,[grp0_LM1,grp1_LM1,grp2_LM1]) - grp0_Node=DataArrayInt.New([0,11,15,16]) ; grp0_Node.setName("grp0_Node") - grp1_Node=DataArrayInt.New([1,2,13,14,16]) ; grp1_Node.setName("grp1_Node") - mm.setGroupsAtLevel(1,[grp0_Node,grp1_Node]) - # - tester.assertRaises(InterpKernelException,mm.setRenumFieldArr,0,DataArrayInt.New([0,8,9,4,5,6,7,10]))# to big array - mm.setRenumFieldArr(0,DataArrayInt.New([0,8,9,4,5,6,7])) - da=DataArrayInt.New([0,8,9,4,5,6,7,11,12]) - mm.setRenumFieldArr(-1,da) - mm.setRenumFieldArr(-1,None) - mm.setRenumFieldArr(-1,da) - da=DataArrayInt.New(mm.getNumberOfNodes()+1) ; da.iota(8) ; tester.assertRaises(InterpKernelException,mm.setRenumFieldArr,1,da) # to big array more than number of nodes - da=DataArrayInt.New(mm.getNumberOfNodes()) ; da.iota(8) ; mm.setRenumFieldArr(1,da) - return mm - - def buildVecFieldOnCells_1(cls): - mesh=MEDLoaderDataForTest.build3DSurfMesh_1(); - nbOfCells=mesh.getNumberOfCells(); - f1=MEDCouplingFieldDouble.New(ON_CELLS,ONE_TIME); - f1.setName("VectorFieldOnCells"); - f1.setMesh(mesh); - array=DataArrayDouble.New(); - arr1=[0.,10.,20.,1.,11.,21.,2.,12.,22.,3.,13.,23.,4.,14.,24.,5.,15.,25.] - array.setValues(arr1,nbOfCells,3); - array.setInfoOnComponent(0,"power [MW/m^3]"); - array.setInfoOnComponent(1,"density [g/cm^3]"); - array.setInfoOnComponent(2,"temperature [K]"); - f1.setArray(array); - tmp=array.getPointer(); - f1.setTime(2.,0,1); - f1.checkCoherency(); - return f1; - - def buildVecFieldOnNodes_1(cls): - mesh=MEDLoaderDataForTest.build3DSurfMesh_1(); - nbOfNodes=mesh.getNumberOfNodes(); - f1=MEDCouplingFieldDouble.New(ON_NODES,ONE_TIME); - f1.setName("VectorFieldOnNodes"); - f1.setMesh(mesh); - array=DataArrayDouble.New(); - f1.setArray(array); - arr1=[70.,80.,90.,71.,81.,91.,72.,82.,92.,73.,83.,93.,74.,84.,94.,75.,85.,95., - 1000.,10010.,10020.,1001.,10011.,10021.,1002.,10012.,10022.,1003.,10013.,10023.,1004.,10014.,10024.,1005.,10015.,10025.] - array.setValues(arr1,nbOfNodes,3); - array.setInfoOnComponent(0,"power [MW/m^3]"); - array.setInfoOnComponent(1,"density [g/cm^3]"); - array.setInfoOnComponent(2,"temperature [K]"); - f1.setTime(2.12,2,3); - f1.checkCoherency(); - return f1; - - def buildVecFieldOnGauss_1(cls): - _a=0.446948490915965; - _b=0.091576213509771; - _p1=0.11169079483905; - _p2=0.0549758718227661; - refCoo1=[ 0.,0., 1.,0., 0.,1. ] - gsCoo1=[ 2*_b-1, 1-4*_b, 2*_b-1, 2.07*_b-1, 1-4*_b, - 2*_b-1, 1-4*_a, 2*_a-1, 2*_a-1, 1-4*_a, 2*_a-1, 2*_a-1 ]; - wg1=[ 4*_p2, 4*_p2, 4*_p2, 4*_p1, 4*_p1, 4*_p1 ] - _refCoo1=refCoo1; - _gsCoo1=gsCoo1; - _wg1=wg1; - m=MEDLoaderDataForTest.build2DMesh_2(); - f=MEDCouplingFieldDouble.New(ON_GAUSS_PT,ONE_TIME); - f.setTime(3.14,1,5); - f.setMesh(m); - f.setGaussLocalizationOnType(NORM_TRI3,_refCoo1,_gsCoo1,_wg1); - refCoo2=[-1.0,1.0, -1.0,-1.0, 1.0,-1.0, -1.0,0.0, 0.0,-1.0, 0.0,0.0 ] - _refCoo2=refCoo2; - _gsCoo1=_gsCoo1[0:6]; - _gsCoo2=_gsCoo1 - _wg1=_wg1[0:3]; - _wg2=_wg1 - refCoo3=[ 0.,0., 1.,0., 1.,1., 0.,1. ] - _refCoo3=refCoo3; - _gsCoo1=_gsCoo1[0:4]; - _wg1=_wg1[0:2]; - f.setGaussLocalizationOnType(NORM_QUAD4,_refCoo3,_gsCoo1,_wg1); - f.setGaussLocalizationOnType(NORM_TRI6,_refCoo2,_gsCoo2,_wg2); - array=DataArrayDouble.New(); - array.alloc(19,2); - ptr=array.getPointer(); - for i in xrange(19*2): - array.setIJ(0,i,float(i+7)); - pass - f.setArray(array); - f.setName("MyFirstFieldOnGaussPoint"); - array.setInfoOnComponent(0,"power [MW/m^3]"); - array.setInfoOnComponent(1,"density"); - f.checkCoherency(); - return f; - - def buildVecFieldOnGauss_2(cls): - _a=0.446948490915965; - _b=0.091576213509771; - _p1=0.11169079483905; - _p2=0.0549758718227661; - refCoo1=[ 0.,0., 1.,0., 0.,1. ] - gsCoo1=[ 2*_b-1, 1-4*_b, 2*_b-1, 2.07*_b-1, 1-4*_b, - 2*_b-1, 1-4*_a, 2*_a-1, 2*_a-1, 1-4*_a, 2*_a-1, 2*_a-1 ]; - wg1=[ 4*_p2, 4*_p2, 4*_p2, 4*_p1, 4*_p1, 4*_p1 ] - _refCoo1=refCoo1; - _gsCoo1=gsCoo1; - _wg1=wg1; - m=MEDLoaderDataForTest.build2DMesh_3(); - f=MEDCouplingFieldDouble.New(ON_GAUSS_PT,ONE_TIME); - f.setTime(3.14,1,5); - f.setMesh(m); - di=DataArrayInt.New(); di.setValues([0,2,3],3,1) - f.setGaussLocalizationOnCells(di,_refCoo1,_gsCoo1,_wg1) - _wg1[-1]*=2 - f.setGaussLocalizationOnCells([1,5],_refCoo1,_gsCoo1,_wg1); - _wg1[-1]*=2 - f.setGaussLocalizationOnCells([4],_refCoo1,_gsCoo1,_wg1); - refCoo2=[-1.0,1.0, -1.0,-1.0, 1.0,-1.0, -1.0,0.0, 0.0,-1.0, 0.0,0.0 ] - _refCoo2=refCoo2; - _gsCoo1=_gsCoo1[0:6]; - _gsCoo2=_gsCoo1 - _wg1=_wg1[0:3]; - _wg2=_wg1 - refCoo3=[ 0.,0., 1.,0., 1.,1., 0.,1. ] - _refCoo3=refCoo3; - _gsCoo1=_gsCoo1[0:4]; - _wg1=_wg1[0:2]; - f.setGaussLocalizationOnCells([6,7,8],_refCoo3,_gsCoo1,_wg1); - _wg1[-1]*=2 - f.setGaussLocalizationOnCells([9],_refCoo3,_gsCoo1,_wg1); - f.setGaussLocalizationOnType(NORM_TRI6,_refCoo2,_gsCoo2,_wg2); - array=DataArrayDouble.New(); - array.alloc(53,2); - ptr=array.getPointer(); - for i in xrange(53*2): - array.setIJ(0,i,float(i+7)); - pass - f.setArray(array); - f.setName("MyFirstFieldOnGaussPoint"); - array.setInfoOnComponent(0,"power [MW/m^3]"); - array.setInfoOnComponent(1,"density"); - f.checkCoherency(); - return f; - - # idem buildVecFieldOnGauss_2 except that different discretizations are sorted inside one type - def buildVecFieldOnGauss_2_Simpler(cls): - _a=0.446948490915965; - _b=0.091576213509771; - _p1=0.11169079483905; - _p2=0.0549758718227661; - refCoo1=[ 0.,0., 1.,0., 0.,1. ] - gsCoo1=[ 2*_b-1, 1-4*_b, 2*_b-1, 2.07*_b-1, 1-4*_b, - 2*_b-1, 1-4*_a, 2*_a-1, 2*_a-1, 1-4*_a, 2*_a-1, 2*_a-1 ]; - wg1=[ 4*_p2, 4*_p2, 4*_p2, 4*_p1, 4*_p1, 4*_p1 ] - _refCoo1=refCoo1; - _gsCoo1=gsCoo1; - _wg1=wg1; - m=MEDLoaderDataForTest.build2DMesh_3(); - f=MEDCouplingFieldDouble.New(ON_GAUSS_PT,ONE_TIME); - f.setTime(3.14,1,5); - f.setMesh(m); - di=DataArrayInt.New(); di.setValues([0,1,2],3,1) - f.setGaussLocalizationOnCells(di,_refCoo1,_gsCoo1,_wg1) - _wg1[-1]*=2 - f.setGaussLocalizationOnCells([3,4],_refCoo1,_gsCoo1,_wg1); - _wg1[-1]*=2 - f.setGaussLocalizationOnCells([5],_refCoo1,_gsCoo1,_wg1); - refCoo2=[-1.0,1.0, -1.0,-1.0, 1.0,-1.0, -1.0,0.0, 0.0,-1.0, 0.0,0.0 ] - _refCoo2=refCoo2; - _gsCoo1=_gsCoo1[0:6]; - _gsCoo2=_gsCoo1 - _wg1=_wg1[0:3]; - _wg2=_wg1 - refCoo3=[ 0.,0., 1.,0., 1.,1., 0.,1. ] - _refCoo3=refCoo3; - _gsCoo1=_gsCoo1[0:4]; - _wg1=_wg1[0:2]; - f.setGaussLocalizationOnCells([6,7,8],_refCoo3,_gsCoo1,_wg1); - _wg1[-1]*=2 - f.setGaussLocalizationOnCells([9],_refCoo3,_gsCoo1,_wg1); - f.setGaussLocalizationOnType(NORM_TRI6,_refCoo2,_gsCoo2,_wg2); - array=DataArrayDouble.New(); - array.alloc(53,2); - ptr=array.getPointer(); - for i in xrange(53*2): - array.setIJ(0,i,float(i+7)); - pass - f.setArray(array); - f.setName("MyFirstFieldOnGaussPoint"); - array.setInfoOnComponent(0,"power [MW/m^3]"); - array.setInfoOnComponent(1,"density"); - f.checkCoherency(); - return f; - - def buildVecFieldOnGaussNE_1(cls): - m=MEDLoaderDataForTest.build2DMesh_2(); - f=MEDCouplingFieldDouble.New(ON_GAUSS_NE,ONE_TIME); - f.setTime(3.14,1,5); - f.setMesh(m); - array=DataArrayDouble.New(); - array.alloc(20,2); - for i in xrange(2*20): - array.setIJ(0,i,float(i+8)); - f.setArray(array); - array.setInfoOnComponent(0,"power [W]"); - array.setInfoOnComponent(1,"temperature"); - f.setName("MyFieldOnGaussNE"); - f.checkCoherency(); - return f; - - def buildACompleteMEDDataStructureWithFieldsOnCells_1(cls): - coo=DataArrayDouble([0,0,1,0,2,0,0,1,1,1,2,1,0,2,1,2,2,2],9,2) - m0=MEDCouplingUMesh("mesh",2) - m0.setCoords(coo) - m0.allocateCells() - m0.insertNextCell(NORM_TRI3,[1,4,2]) - m0.insertNextCell(NORM_TRI3,[4,5,2]) - m0.insertNextCell(NORM_QUAD4,[0,3,4,1]) - m0.insertNextCell(NORM_QUAD4,[6,7,4,3]) - m0.insertNextCell(NORM_QUAD4,[7,8,5,4]) - m1=m0.computeSkin() - mm=MEDFileUMesh() - #2 levels - mm.setMeshAtLevel(0,m0) ; mm.setMeshAtLevel(-1,m1) - #some grps/families on the 2 levels - grp0=DataArrayInt([0,2,4]); grp0.setName("gr0_0_2_4") - grp1=DataArrayInt([1,2,3,4]); grp1.setName("gr0_1_2_3_4") - grp2=DataArrayInt([0,4]); grp2.setName("gr0_0_4") - mm.setGroupsAtLevel(0,[grp0,grp1,grp2]) - grp3=DataArrayInt([0,1]); grp3.setName("grM1_SegOnTri3") - grp4=DataArrayInt([2,3,4,5,6,7]); grp4.setName("grM1_SegOnQuad4") - grp5=DataArrayInt([0,3]); grp5.setName("grM1_bottom") - mm.setGroupsAtLevel(-1,[grp3,grp4,grp5]) - ms=MEDFileMeshes() - ms.pushMesh(mm) - # 3 fields - fs=MEDFileFields() - # 1st Field - fNoProfile - no profile on levels 0 - f1Name="fNoProfile" - timeStepsF1=[(0,-1,0.01),(1,-1,0.02)] - f1=MEDFileFieldMultiTS() - for i,(it,order,tim) in enumerate(timeStepsF1): - f11Tmp=MEDCouplingFieldDouble(ON_CELLS,ONE_TIME) - f11Tmp.setTime(tim,it,order) - f11Tmp.setMesh(m0) - arr=DataArrayDouble(m0.getNumberOfCells(),1) ; arr.iota() ; arr+=1+i ; arr*=0.1 - f11Tmp.setArray(arr) - f11Tmp.checkCoherency() - f11Tmp.setName(f1Name) - f1.appendFieldNoProfileSBT(f11Tmp) - pass - fs.pushField(f1) - # 2nd Field - fNoProfileMultiLevs - no profile on levels 0 and -1 - f2Name="fNoProfileMultiLevs" - timeStepsF2=[(0,-1,0.),(1,-1,0.1),(2,-1,0.2)] - f2=MEDFileFieldMultiTS() - for i,(it,order,tim) in enumerate(timeStepsF2): - f21Tmp=MEDCouplingFieldDouble(ON_CELLS,ONE_TIME) - f21Tmp.setTime(tim,it,order) - f21Tmp.setMesh(m0) - arr=DataArrayDouble(m0.getNumberOfCells(),1) ; arr.iota() ; arr+=1+i - f21Tmp.setArray(arr) - f21Tmp.checkCoherency() - f21Tmp.setName(f2Name) - f2.appendFieldNoProfileSBT(f21Tmp) - f22Tmp=MEDCouplingFieldDouble(ON_CELLS,ONE_TIME) - f22Tmp.setTime(tim,it,order) - f22Tmp.setMesh(m1) - arr=DataArrayDouble(m1.getNumberOfCells(),1) ; arr.iota() ; arr+=100+1+i - f22Tmp.setArray(arr) - f22Tmp.checkCoherency() - f22Tmp.setName(f2Name) - f2[it,order].setFieldNoProfileSBT(f22Tmp) - pass - fs.pushField(f2) - # 3rd field - fProfileMultiLevs - The most complex one - f3Name="fProfileMultiLevs" - timeStepsF3=[(0,-1,0.),(1,-1,10.),(2,-1,20.),(3,-1,30.),] - f3=MEDFileFieldMultiTS() - for i,(it,order,tim) in enumerate(timeStepsF3): - pfl1=DataArrayInt([0,1,3,4]) ; pfl1.setName("pfl1") - m0Part=m0[pfl1] - f31Tmp=MEDCouplingFieldDouble(ON_CELLS,ONE_TIME) - f31Tmp.setTime(tim,it,order) - f31Tmp.setMesh(m0Part) - arr=DataArrayDouble(m0Part.getNumberOfCells(),1) ; arr.iota() ; arr+=1000+i+1 - f31Tmp.setArray(arr) - f31Tmp.checkCoherency() - f31Tmp.setName(f3Name) - f3.appendFieldProfile(f31Tmp,mm,0,pfl1) - pfl2=DataArrayInt([0,3]) ; pfl2.setName("pfl2Bottom") - m1Part=m1[pfl2] - f32Tmp=MEDCouplingFieldDouble(ON_CELLS,ONE_TIME) - f32Tmp.setTime(tim,it,order) - f32Tmp.setMesh(m1Part) - arr=DataArrayDouble(m1Part.getNumberOfCells(),1) ; arr.iota() ; arr+=2000+1+i - f32Tmp.setArray(arr) - f32Tmp.checkCoherency() - f32Tmp.setName(f3Name) - f3[it,order].setFieldProfile(f32Tmp,mm,-1,pfl2) - pass - fs.pushField(f3) - # - data=MEDFileData() ; data.setMeshes(ms) ; data.setFields(fs) - return data - - def buildAMEDFileDataWithGroupOnOneFamilyForSauv(self): - # Coordinates - coords = [0.,0., 0.,1., 1.,1., 1.,0.] - # lvl 0 connectivity - conn2D = [1,2,3,4] - # lvl -1 connectivity - conn1D = [0,1, 1,2, 2,3, 4,1] - # lvl 0 mesh - mesh2D=MEDCouplingUMesh.New() - mesh2D.setMeshDimension(2) - mesh2D.allocateCells(1) - mesh2D.insertNextCell(NORM_QUAD4,4,conn2D) - mesh2D.finishInsertingCells() - # lvl -1 mesh - mesh1D=MEDCouplingUMesh.New() - mesh1D.setMeshDimension(1) - mesh1D.allocateCells(4) - mesh1D.insertNextCell(NORM_SEG2,2,conn1D[0:2]) - mesh1D.insertNextCell(NORM_SEG2,2,conn1D[2:4]) - mesh1D.insertNextCell(NORM_SEG2,2,conn1D[4:6]) - mesh1D.insertNextCell(NORM_SEG2,2,conn1D[6:8]) - mesh1D.finishInsertingCells() - # assigning coordinates - meshCoords=DataArrayDouble.New() - meshCoords.setValues(coords, 4, 2) - mesh2D.setCoords(meshCoords) - mesh1D.setCoords(meshCoords) - # Creating a multi level mesh - mm = MEDFileUMesh.New() - mm.setMeshAtLevel(0, mesh2D) - mm.setMeshAtLevel(-1, mesh1D) - mm.setName("carre") - # Creating groups - # Creating a group with an element on level -1 - grp0_LM1 = DataArrayInt.New([0]) - grp0_LM1.setName("grp0_LM1") - # Creating a group with all elements on level -1 - grp1_LM1 = DataArrayInt.New([0,1,2,3]) - grp1_LM1.setName("grp1_LM1") - # - mm.setGroupsAtLevel(-1,[grp0_LM1,grp1_LM1]) - # - ms=MEDFileMeshes.New() - ms.setMeshAtPos(0,mm) - mfd=MEDFileData.New() - mfd.setMeshes(ms) - # - return mfd - - build1DMesh_1=classmethod(build1DMesh_1) - build2DCurveMesh_1=classmethod(build2DCurveMesh_1) - build2DMesh_1=classmethod(build2DMesh_1) - build2DMesh_2=classmethod(build2DMesh_2) - build2DMesh_3=classmethod(build2DMesh_3) - build3DMesh_1=classmethod(build3DMesh_1) - build3DSurfMesh_1=classmethod(build3DSurfMesh_1) - build3DMesh_2=classmethod(build3DMesh_2) - buildMLMeshUnPolyze=classmethod(buildMLMeshUnPolyze) - buildMultiLevelMesh_1=classmethod(buildMultiLevelMesh_1) - buildVecFieldOnCells_1=classmethod(buildVecFieldOnCells_1) - buildVecFieldOnNodes_1=classmethod(buildVecFieldOnNodes_1) - buildVecFieldOnGauss_1=classmethod(buildVecFieldOnGauss_1) - buildVecFieldOnGauss_2=classmethod(buildVecFieldOnGauss_2) - buildVecFieldOnGauss_2_Simpler=classmethod(buildVecFieldOnGauss_2_Simpler) - buildVecFieldOnGaussNE_1=classmethod(buildVecFieldOnGaussNE_1) - buildACompleteMEDDataStructureWithFieldsOnCells_1=classmethod(buildACompleteMEDDataStructureWithFieldsOnCells_1) - buildAMEDFileDataWithGroupOnOneFamilyForSauv=classmethod(buildAMEDFileDataWithGroupOnOneFamilyForSauv) - pass diff --git a/src/MEDLoader/Swig/MEDLoaderExamplesTest.py b/src/MEDLoader/Swig/MEDLoaderExamplesTest.py deleted file mode 100644 index d7b6aa4cb..000000000 --- a/src/MEDLoader/Swig/MEDLoaderExamplesTest.py +++ /dev/null @@ -1,252 +0,0 @@ -# -*- coding: iso-8859-1 -*- -# Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 -# 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) - -from MEDLoader import * -import unittest -import os - -class MEDLoaderBasicsTest(unittest.TestCase): - def testExampleReadFieldOnAllEntity1(self): - from MEDLoaderDataForTest import MEDLoaderDataForTest -#! [PySnippetReadFieldOnAllEntity1_1] - fname="PyExamples1.med" - meshName="mesh" - fieldName="FieldOnAll" - iteration=3 - order=4 -#! [PySnippetReadFieldOnAllEntity1_1] -#! [PySnippetWriteFieldOnAllEntity1_2] - m=MEDLoaderDataForTest.build2DMesh_3() - m=m[:10] - m.setName(meshName) - f=m.getMeasureField(ON_CELLS) - f=f.buildNewTimeReprFromThis(ONE_TIME,False) - f.setTime(5.5,iteration,order) - f.setName(fieldName) - # MEDCoupling finished, MEDLoader advanced API specific part starting from here - mm=MEDFileUMesh.New() - mm.setMeshAtLevel(0,m) - ff=MEDFileField1TS.New() - ff.setFieldNoProfileSBT(f) - mm.write(fname,2) - ff.write(fname,0) -#! [PySnippetWriteFieldOnAllEntity1_2] -#! [PySnippetReadFieldOnAllEntity1_3] - medfileField1TS=MEDFileField1TS.New(fname,fieldName,iteration,order) - mm=MEDFileMesh.New(fname) - fread=medfileField1TS.getFieldOnMeshAtLevel(ON_CELLS,0,mm) - fread2=medfileField1TS.getFieldAtLevel(ON_CELLS,0) - self.assertTrue(fread.isEqual(f,1e-12,1e-12)) - self.assertTrue(fread2.isEqual(f,1e-12,1e-12)) -#! [PySnippetReadFieldOnAllEntity1_3] -#! [PySnippetReadFieldOnAllEntity1_4] - medfileFieldMTS=MEDFileFieldMultiTS.New(fname,fieldName) - mm=MEDFileMesh.New(fname) - fread=medfileFieldMTS.getFieldOnMeshAtLevel(ON_CELLS,iteration,order,0,mm) - fread2=medfileFieldMTS.getFieldAtLevel(ON_CELLS,iteration,order,0) - self.assertTrue(fread.isEqual(f,1e-12,1e-12)) - self.assertTrue(fread2.isEqual(f,1e-12,1e-12)) -#! [PySnippetReadFieldOnAllEntity1_4] -#! [PySnippetReadFieldOnAllEntity1_5] - medfileFieldMTS=MEDFileFieldMultiTS.New(fname,fieldName) - for medfileField1TS in medfileFieldMTS: - if medfileField1TS.getTime()[:2]==[iteration,order]: - fread=medfileField1TS.getFieldOnMeshAtLevel(ON_CELLS,0,mm) - fread2=medfileField1TS.getFieldAtLevel(ON_CELLS,0) - self.assertTrue(fread.isEqual(f,1e-12,1e-12)) - self.assertTrue(fread2.isEqual(f,1e-12,1e-12)) - pass - pass -#! [PySnippetReadFieldOnAllEntity1_5] - pass - - def testExampleReadFieldPartial1(self): - from MEDLoaderDataForTest import MEDLoaderDataForTest -#! [PySnippetReadFieldPartial1_1] - fname="PyExamples2.med" - meshName="mesh" - fieldName="FieldPartial" - iteration=3 - order=4 -#! [PySnippetReadFieldPartial1_1] -#! [PySnippetWriteFieldPartial1_2] - m=MEDLoaderDataForTest.build2DMesh_1() - m.sortCellsInMEDFileFrmt() - m.setName(meshName) - # end of generation of a mesh -> let's create a field on that mesh - f=m.getMeasureField(ON_CELLS) - f=f.buildNewTimeReprFromThis(ONE_TIME,False) - f.setTime(5.5,iteration,order) - f.setName(fieldName) - # The MEDCoupling part is finished -> let's perform advanced API - mm=MEDFileUMesh.New() - mm.setMeshAtLevel(0,m) # the MED file data structure is ready for writing. Of course mm could have been more complicated with groups, families, multilevel - # Let's building a sub field - pfl=DataArrayInt.New([1,3,4,5]) - pfl.setName("myPfl") # here it is necessary to give a name to be compliant with MED file - f=f[pfl] ; f.getMesh().setName(m.getName()) # of course f should be in coherence with pfl -> f[pfl] - # - ff=MEDFileField1TS.New() - tmp=f.getMesh() # useless line, only to show that mesh into f is not considered by MEDFileField1TS.setFieldProfile - f.setMesh(None) # useless line, only to show that mesh into f is not considered by MEDFileField1TS.setFieldProfile - ff.setFieldProfile(f,mm,0,pfl) - f.setMesh(tmp) # useless line, only to show that mesh into f is not considered by MEDFileField1TS.setFieldProfile - mm.write(fname,2) - ff.write(fname,0) -#! [PySnippetWriteFieldPartial1_2] -#! [PySnippetReadFieldPartial1_3] - mm=MEDFileMesh.New(fname) - medfileField1TS=MEDFileField1TS.New(fname,fieldName,iteration,order) - fread=medfileField1TS.getFieldOnMeshAtLevel(ON_CELLS,0,mm) - fread2=medfileField1TS.getFieldAtLevel(ON_CELLS,0) - self.assertTrue(fread.isEqual(f,1e-12,1e-12)) - self.assertTrue(fread2.isEqual(f,1e-12,1e-12)) -#! [PySnippetReadFieldPartial1_3] -#! [PySnippetReadFieldPartial1_4] - medfileField1TS=MEDFileField1TS.New(fname,fieldName,iteration,order) - mm=MEDFileMesh.New(fname) - valsRead,pflRead=medfileField1TS.getFieldWithProfile(ON_CELLS,0,mm) - self.assertEqual(valsRead.getName(),f.getName()) - valsRead.setName("") - self.assertTrue(valsRead.isEqual(f.getArray(),1e-12)) - pflRead.setName(pfl.getName()) - self.assertTrue(pflRead.isEqual(pfl)) -#! [PySnippetReadFieldPartial1_4] -#! [PySnippetReadFieldPartial1_5] - firstApproachMesh=fread.getMesh() - mm=MEDFileMesh.New(fname) - wholeMesh=mm.getMeshAtLevel(0) - wholeMesh.tryToShareSameCoords(firstApproachMesh,1e-12) - isIncluded,pflComputed=wholeMesh.areCellsIncludedIn(firstApproachMesh,2) - self.assertTrue(isIncluded) - self.assertEqual(pflComputed.getName(),mm.getName()) - pflComputed.setName(pflRead.getName()) - self.assertTrue(pflComputed.isEqual(pflRead)) -#! [PySnippetReadFieldPartial1_5] -#! [PySnippetReadFieldPartial1_6] - mm=MEDFileMesh.New(fname) - wholeMesh=mm.getMeshAtLevel(0) - computedMesh=wholeMesh[pflRead] ; computedMesh.setName(mm.getName()) - self.assertTrue(computedMesh.isEqual(fread.getMesh(),1e-12)) - fieldFromSecondApproach=MEDCouplingFieldDouble.New(ON_CELLS,ONE_TIME) - fieldFromSecondApproach.setName(medfileField1TS.getName()) - fieldFromSecondApproach.setMesh(computedMesh) - fieldFromSecondApproach.setArray(valsRead) - fieldFromSecondApproach.setTime(medfileField1TS.getTime()[2],medfileField1TS.getTime()[0],medfileField1TS.getTime()[1]) - self.assertTrue(fieldFromSecondApproach.isEqual(fread,1e-12,1e-12)) -#! [PySnippetReadFieldPartial1_6] - pass - - def testExampleMeshAdvAPI1(self): - da=DataArrayDouble.New([0.,1.1,2.3,3.6]) - meshName="Example2" - cmesh=MEDCouplingCMesh.New() ; cmesh.setCoords(da,da,da) - myMesh=cmesh.buildUnstructured() -#! [PySnippetMeshAdvAPI1_1] - self.assertTrue(isinstance(myMesh,MEDCouplingUMesh)) - myMesh.setName(meshName) - MEDLoader.WriteUMesh("wFile1.med",myMesh,True) -#! [PySnippetMeshAdvAPI1_1] - os.remove("wFile1.med") -#! [PySnippetMeshAdvAPI1_2] - self.assertTrue(isinstance(myMesh,MEDCouplingUMesh)) - myMesh.setName(meshName) - MEDLoader.WriteUMesh("wFile1.med",myMesh,False) -#! [PySnippetMeshAdvAPI1_2] - f=myMesh.getMeasureField(ON_CELLS) - f=f.buildNewTimeReprFromThis(ONE_TIME,False) - f.setName("myField") -#! [PySnippetMeshAdvAPI1_3] - MEDLoader.WriteUMesh("file3.med",f.getMesh(),True) - f.setTime(1.2,1,0) - fileNameMultiTimeStep="file3.med" - MEDLoader.WriteFieldUsingAlreadyWrittenMesh(fileNameMultiTimeStep,f) - f.setTime(1.3,2,0) - f.applyFunc("sqrt(x)"); - #Writing second time step with iteration==2 and order==0 - MEDLoader.WriteFieldUsingAlreadyWrittenMesh("file3.med",f); -#! [PySnippetMeshAdvAPI1_3] -#! [PySnippetMeshAdvAPI1_11] - timeStepsIds=MEDLoader.GetCellFieldIterations("file3.med","Example2","myField") - self.assertEqual([(1, 0),(2, 0)],timeStepsIds) - fs=MEDLoader.ReadFieldsOnSameMesh(ON_CELLS,"file3.med","Example2",0,"myField",timeStepsIds); -#! [PySnippetMeshAdvAPI1_11] - ### - myMesh0=myMesh[:] ; myMesh0.setName("Example2") - myMesh1=myMesh0.buildDescendingConnectivity()[0] ; myMesh1.setName(myMesh0.getName()) - myMesh2=myMesh1.buildDescendingConnectivity()[0] ; myMesh2.setName(myMesh0.getName()) - myMesh3=myMesh2.buildDescendingConnectivity()[0] ; myMesh3.setName(myMesh0.getName()) - mm=MEDFileUMesh.New() - mm.setMeshAtLevel(0,myMesh0) - mm.setMeshAtLevel(-1,myMesh1) - mm.setMeshAtLevel(-2,myMesh2) - mm.setMeshAtLevel(-3,myMesh3) - mm.write("file2.med",2) - F1Cell=MEDCouplingFieldDouble.New(ON_CELLS,ONE_TIME) - F1Cell.setMesh(myMesh0) - F1Cell.setArray(myMesh0.getCoords()[:myMesh0.getNumberOfCells()]) - F1Cell.setTime(1000.,2,3) - F1Cell.setName("F1Cell") - MEDLoader.WriteFieldUsingAlreadyWrittenMesh("file2.med",F1Cell) - F1Cell1=F1Cell.deepCpy() - F1Cell1.setMesh(myMesh1) - F1Cell1.setArray(myMesh1.getBarycenterAndOwner()) - MEDLoader.WriteFieldUsingAlreadyWrittenMesh("file2.med",F1Cell1) -#! [PySnippetMeshAdvAPI1_12] - f1Cell_3D=MEDLoader.ReadFieldCell("file2.med","Example2",0,"F1Cell",2,3) -#! [PySnippetMeshAdvAPI1_12] -#! [PySnippetMeshAdvAPI1_13] - f1Cell_2D=MEDLoader.ReadFieldCell("file2.med","Example2",-1,"F1Cell",2,3) -#! [PySnippetMeshAdvAPI1_13] - self.assertTrue(F1Cell.isEqual(f1Cell_3D,1e-12,1e-12)) -#! [PySnippetMeshAdvAPI1_8] - self.assertEqual(3,MEDLoader.ReadUMeshDimFromFile("file2.med","Example2")) -#! [PySnippetMeshAdvAPI1_8] -#! [PySnippetMeshAdvAPI1_7] - m2D=MEDLoader.ReadUMeshFromFile("file2.med","Example2",0) -#! [PySnippetMeshAdvAPI1_7] -#! [PySnippetMeshAdvAPI1_4] - m2D=MEDLoader.ReadUMeshFromFile("file2.med","Example2",-1) -#! [PySnippetMeshAdvAPI1_4] -#! [PySnippetMeshAdvAPI1_5] - m1D=MEDLoader.ReadUMeshFromFile("file2.med","Example2",-2) -#! [PySnippetMeshAdvAPI1_5] -#! [PySnippetMeshAdvAPI1_6] - m0D=MEDLoader.ReadUMeshFromFile("file2.med","Example2",-3) -#! [PySnippetMeshAdvAPI1_6] - for i in xrange(4): - mm.removeMeshAtLevel(-i) - pass - mm.setMeshAtLevel(0,myMesh1) - mm.setMeshAtLevel(-1,myMesh2) - mm.setName("MyMesh") - mm.write("file1.med",2) -#! [PySnippetMeshAdvAPI1_9] - m2D=MEDLoader.ReadUMeshFromFile("file1.med","MyMesh",0) -#! [PySnippetMeshAdvAPI1_9] -#! [PySnippetMeshAdvAPI1_10] - m1D=MEDLoader.ReadUMeshFromFile("file1.med","MyMesh",-1) -#! [PySnippetMeshAdvAPI1_10] - pass - - pass - -unittest.main() diff --git a/src/MEDLoader/Swig/MEDLoaderSplitter.py b/src/MEDLoader/Swig/MEDLoaderSplitter.py deleted file mode 100644 index 41e766794..000000000 --- a/src/MEDLoader/Swig/MEDLoaderSplitter.py +++ /dev/null @@ -1,115 +0,0 @@ -# -*- coding: iso-8859-1 -*- -# Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 -# 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/DM2S/STMF/LGLS) - -from MEDLoader import * -import os - -class MEDLoaderSplitter: - @classmethod - def New(cls,mfd,idsLst): - """ mfd is a MEDFileData instance containing only one mesh. idsLst is a list of DataArrayInt containing each the ids per processor """ - return MEDLoaderSplitter(fileName) - pass - - def __init__(self,mfd,idsLst): - """ mfd is a MEDFileData instance containing only one mesh. idsLst is a list of DataArrayInt containing each the ids per processor """ - mfmsh=mfd.getMeshes() - mfflds=mfd.getFields() - if len(mfmsh)!=1: - raise InterpKernelException("Works only with one mesh !") - mfflds=mfflds.partOfThisLyingOnSpecifiedMeshName(mfmsh[0].getName()) - retf=self.__splitFields(mfmsh[0],mfflds,idsLst) - retm=self.__splitMesh(mfmsh[0],idsLst) - self._mfd_splitted=[MEDFileData() for i in xrange(len(idsLst))] - for a,b,c in zip(self._mfd_splitted,retf,retm): - a.setFields(b) ; a.setMeshes(c) - pass - pass - - def getSplittedInstances(self): - return self._mfd_splitted - - @classmethod - def __splitMEDFileField1TSNode(cls,f,f1ts,ids): - fRet=f[ids] - f1ts.setFieldNoProfileSBT(fRet) - pass - - @classmethod - def __splitMEDFileField1TSCell(cls,f,f1ts,ids): - fRet=f[ids] - m=fRet.getMesh() ; m.zipCoords() - o2n=m.getRenumArrForMEDFileFrmt() ; fRet.renumberCells(o2n,False) - f1ts.setFieldNoProfileSBT(fRet) - pass - - def __splitMEDFileField1TS(self,mm,f1ts,idsLst): - ret=[MEDFileField1TS() for i in xrange(len(idsLst))] - dico={ON_CELLS:self.__splitMEDFileField1TSCell, - ON_NODES:self.__splitMEDFileField1TSNode, - ON_GAUSS_PT:self.__splitMEDFileField1TSCell, - ON_GAUSS_NE:self.__splitMEDFileField1TSCell} - for t in f1ts.getTypesOfFieldAvailable(): - f=f1ts.getFieldOnMeshAtLevel(t,0,mm) - for i,f0 in enumerate(ret): - dico[t](f,f0,idsLst[i]) - pass - pass - return ret - - def __splitFields(self,mm,mfflds,idsLst): - ret0=[MEDFileFields() for i in xrange(len(idsLst))] - for fmts in mfflds: - if len(fmts.getPflsReallyUsed())!=0: - print "Field \"%s\" contains profiles ! Not supported yet ! This field will be ignored !"%(fmts.getName()) - continue - pass - ret1=[MEDFileFieldMultiTS() for i in xrange(len(idsLst))] - for f1ts in fmts: - for fmtsPart,f1tsPart in zip(ret1,self.__splitMEDFileField1TS(mm,f1ts,idsLst)): - fmtsPart.pushBackTimeStep(f1tsPart) - pass - pass - for fieldsPart,fmtsPart in zip(ret0,ret1): - fieldsPart.pushField(fmtsPart); - pass - pass - return ret0 - - def __splitMesh(self,mfm,idsLst): - ret0=[MEDFileMeshes() for i in xrange(len(idsLst))] - m=mfm.getMeshAtLevel(0) - for ret,ids in zip(ret0,idsLst): - mlPart=mfm.createNewEmpty() - mPart=m[ids] ; trad=mPart.zipCoordsTraducer() - trad=trad.invertArrayO2N2N2O(mPart.getNumberOfNodes()) - mlPart.setMeshAtLevel(0,mPart) - if 0 in mfm.getFamArrNonEmptyLevelsExt(): - mlPart.setFamilyFieldArr(0,mfm.getFamilyFieldAtLevel(0)[ids]) - pass - if 1 in mfm.getFamArrNonEmptyLevelsExt(): - mlPart.setFamilyFieldArr(1,mfm.getFamilyFieldAtLevel(1)[trad]) - pass - mlPart.copyFamGrpMapsFrom(mfm) - ret.pushMesh(mlPart) - pass - return ret0 - pass diff --git a/src/MEDLoader/Swig/MEDLoaderTest.py b/src/MEDLoader/Swig/MEDLoaderTest.py deleted file mode 100644 index 38ee4afa9..000000000 --- a/src/MEDLoader/Swig/MEDLoaderTest.py +++ /dev/null @@ -1,756 +0,0 @@ -# -*- coding: iso-8859-1 -*- -# Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 -# 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) - -import MEDLoader -import unittest -from math import pi,e,sqrt -from MEDLoaderDataForTest import MEDLoaderDataForTest - -class MEDLoaderTest(unittest.TestCase): - def testMesh1DRW(self): - mesh=MEDLoaderDataForTest.build1DMesh_1(); - mesh.checkCoherency(); - MEDLoader.MEDLoader.WriteUMesh("Pyfile1.med",mesh,True); - mesh_rw=MEDLoader.MEDLoader.ReadUMeshFromFile("Pyfile1.med",mesh.getName(),0); - self.assertTrue(mesh.isEqual(mesh_rw,1e-12)); - pass - - def testMesh2DCurveRW(self): - mesh=MEDLoaderDataForTest.build2DCurveMesh_1(); - mesh.checkCoherency(); - MEDLoader.MEDLoader.WriteUMesh("Pyfile2.med",mesh,True); - mesh_rw=MEDLoader.MEDLoader.ReadUMeshFromFile("Pyfile2.med",mesh.getName(),0); - self.assertTrue(mesh.isEqual(mesh_rw,1e-12)); - pass - - def testMesh2DRW(self): - mesh=MEDLoaderDataForTest.build2DMesh_1(); - mesh.checkCoherency(); - MEDLoader.MEDLoader.WriteUMesh("Pyfile3.med",mesh,True); - mesh_rw=MEDLoader.MEDLoader.ReadUMeshFromFile("Pyfile3.med",mesh.getName(),0); - self.assertTrue(mesh.isEqual(mesh_rw,1e-12)); - pass - - def testMesh3DSurfRW(self): - mesh=MEDLoaderDataForTest.build3DSurfMesh_1(); - mesh.checkCoherency(); - MEDLoader.MEDLoader.WriteUMesh("Pyfile4.med",mesh,True); - mesh_rw=MEDLoader.MEDLoader.ReadUMeshFromFile("Pyfile4.med",mesh.getName(),0); - self.assertTrue(mesh.isEqual(mesh_rw,1e-12)); - pass - - def testMesh3DRW(self): - mesh=MEDLoaderDataForTest.build3DMesh_1(); - mesh.checkCoherency(); - MEDLoader.MEDLoader.WriteUMesh("Pyfile5.med",mesh,True); - mesh_rw=MEDLoader.MEDLoader.ReadUMeshFromFile("Pyfile5.med",mesh.getName(),0); - self.assertTrue(mesh.isEqual(mesh_rw,1e-12)); - pass - - def testFieldRW1(self): - f1=MEDLoaderDataForTest.buildVecFieldOnCells_1(); - MEDLoader.MEDLoader.WriteField("Pyfile6.med",f1,True); - f2=MEDLoader.MEDLoader.ReadFieldCell("Pyfile6.med",f1.getMesh().getName(),0,f1.getName(),0,1); - self.assertTrue(f1.isEqual(f2,1e-12,1e-12)); - # - f1=MEDLoaderDataForTest.buildVecFieldOnNodes_1(); - MEDLoader.MEDLoader.WriteField("Pyfile7.med",f1,True); - f2=MEDLoader.MEDLoader.ReadFieldNode("Pyfile7.med",f1.getMesh().getName(),0,f1.getName(),2,3); - self.assertTrue(f1.isEqual(f2,1e-12,1e-12)); - self.assertRaises(Exception,MEDLoader.MEDLoader.ReadFieldCell,"Pyfile7.med",f1.getMesh().getName(),0,f1.getName(),2,3); - pass - - def testFieldRW2(self): - fileName="Pyfile8.med"; - VAL1=12345.67890314; - VAL2=-1111111111111.; - f1=MEDLoaderDataForTest.buildVecFieldOnCells_1(); - MEDLoader.MEDLoader.WriteField(fileName,f1,True); - f1.setTime(10.,8,9); - f1.getArray().setIJ(0,0,VAL1); - MEDLoader.MEDLoader.WriteFieldUsingAlreadyWrittenMesh(fileName,f1); - f1.setTime(10.14,18,19); - f1.getArray().setIJ(0,0,VAL2); - MEDLoader.MEDLoader.WriteFieldUsingAlreadyWrittenMesh(fileName,f1); - #retrieving time steps... - f2=MEDLoader.MEDLoader.ReadFieldCell(fileName,f1.getMesh().getName(),0,f1.getName(),8,9); - f1.setTime(10.,8,9); - f1.getArray().setIJ(0,0,VAL1); - self.assertTrue(f1.isEqual(f2,1e-12,1e-12)); - f2=MEDLoader.MEDLoader.ReadFieldCell(fileName,f1.getMesh().getName(),0,f1.getName(),0,1); - f3=MEDLoaderDataForTest.buildVecFieldOnCells_1(); - self.assertTrue(f3.isEqual(f2,1e-12,1e-12)); - f2=MEDLoader.MEDLoader.ReadFieldCell(fileName,f1.getMesh().getName(),0,f1.getName(),18,19); - f1.setTime(10.14,18,19); - f1.getArray().setIJ(0,0,VAL2); - self.assertTrue(f1.isEqual(f2,1e-12,1e-12)); - #test of throw on invalid (dt,it) - self.assertRaises(Exception,MEDLoader.MEDLoader.ReadFieldCell,fileName,f1.getMesh().getName(),0,f1.getName(),28,19); - #ON NODES - f1=MEDLoaderDataForTest.buildVecFieldOnNodes_1(); - fileName2="Pyfile9.med"; - MEDLoader.MEDLoader.WriteField(fileName2,f1,True); - f1.setTime(110.,108,109); - tmp=f1.getArray().getPointer(); - f1.getArray().setIJ(0,3,VAL1); - MEDLoader.MEDLoader.WriteFieldUsingAlreadyWrittenMesh(fileName2,f1); - f1.setTime(210.,208,209); - f1.getArray().setIJ(0,3,VAL2); - MEDLoader.MEDLoader.WriteFieldUsingAlreadyWrittenMesh(fileName2,f1); - f2=MEDLoader.MEDLoader.ReadFieldNode(fileName2,f1.getMesh().getName(),0,f1.getName(),108,109); - f1.setTime(110.,108,109); - f1.getArray().setIJ(0,3,VAL1); - self.assertTrue(f1.isEqual(f2,1e-12,1e-12)); - f2=MEDLoader.MEDLoader.ReadFieldNode(fileName2,f1.getMesh().getName(),0,f1.getName(),2,3); - f3=MEDLoaderDataForTest.buildVecFieldOnNodes_1(); - self.assertTrue(f3.isEqual(f2,1e-12,1e-12)); - f2=MEDLoader.MEDLoader.ReadFieldNode(fileName2,f1.getMesh().getName(),0,f1.getName(),208,209); - f1.setTime(210.,208,209); - f1.getArray().setIJ(0,3,VAL2); - self.assertTrue(f1.isEqual(f2,1e-12,1e-12)); - pass - - # - # Multi field in a same file, but this field has several - # - def testFieldRW3(self): - fileName="Pyfile11.med"; - VAL1=12345.67890314; - VAL2=-1111111111111.; - name1="AField"; - name3="AMesh1"; - f1=MEDLoaderDataForTest.buildVecFieldOnCells_1(); - f1.getMesh().setName(name3); - f1.setName(name1); - f1.setTime(10.,8,9); - tmp=f1.getArray().getPointer(); - f1.getArray().setIJ(0,0,VAL1); - MEDLoader.MEDLoader.WriteField(fileName,f1,True); - f1.setTime(10.14,18,19); - f1.getArray().setIJ(0,0,VAL2); - MEDLoader.MEDLoader.WriteFieldUsingAlreadyWrittenMesh(fileName,f1); - f1.getMesh().setName(name3); - f1.setTime(10.55,28,29); - f1.getArray().setIJ(0,0,3*VAL1); - MEDLoader.MEDLoader.WriteFieldUsingAlreadyWrittenMesh(fileName,f1); - vec=MEDLoader.MEDLoader.GetMeshNamesOnField(fileName,name1); - f1.setTime(10.66,38,39); - f1.getArray().setIJ(0,0,3*VAL2); - MEDLoader.MEDLoader.WriteFieldUsingAlreadyWrittenMesh(fileName,f1); - f1.setTime(10.77,48,49); - f1.getArray().setIJ(0,0,4*VAL2); - MEDLoader.MEDLoader.WriteFieldUsingAlreadyWrittenMesh(fileName,f1); - #ON NODES - f1=MEDLoaderDataForTest.buildVecFieldOnNodes_1(); - f1.setName(name1); - f1.getMesh().setName(name3); - f1.setTime(110.,8,9); - MEDLoader.MEDLoader.WriteFieldUsingAlreadyWrittenMesh(fileName,f1); - f1.setTime(110.,108,109); - tmp=f1.getArray().getPointer(); - f1.getArray().setIJ(0,3,VAL1); - MEDLoader.MEDLoader.WriteFieldUsingAlreadyWrittenMesh(fileName,f1); - f1.setTime(210.,208,209); - f1.getArray().setIJ(0,3,VAL2); - MEDLoader.MEDLoader.WriteFieldUsingAlreadyWrittenMesh(fileName,f1); - # - it1=MEDLoader.MEDLoader.GetCellFieldIterations(fileName,name3,name1); - self.assertEqual(5,len(it1)); - self.assertEqual(8,it1[0][0]); self.assertEqual(9,it1[0][1]); - self.assertEqual(18,it1[1][0]); self.assertEqual(19,it1[1][1]); - self.assertEqual(28,it1[2][0]); self.assertEqual(29,it1[2][1]); - self.assertEqual(38,it1[3][0]); self.assertEqual(39,it1[3][1]); - self.assertEqual(48,it1[4][0]); self.assertEqual(49,it1[4][1]); - it3=MEDLoader.MEDLoader.GetNodeFieldIterations(fileName,name3,name1); - self.assertEqual(3,len(it3)); - self.assertEqual(8,it3[0][0]); self.assertEqual(9,it3[0][1]); - self.assertEqual(108,it3[1][0]); self.assertEqual(109,it3[1][1]); - self.assertEqual(208,it3[2][0]); self.assertEqual(209,it3[2][1]); - # - # - f1=MEDLoader.MEDLoader.ReadFieldCell(fileName,name3,0,name1,8,9); - self.assertAlmostEqual(VAL1,f1.getArray().getIJ(0,0),13); - f1=MEDLoader.MEDLoader.ReadFieldCell(fileName,name3,0,name1,18,19); - self.assertAlmostEqual(VAL2,f1.getArray().getIJ(0,0),13); - f1=MEDLoader.MEDLoader.ReadFieldCell(fileName,name3,0,name1,28,29); - self.assertAlmostEqual(3*VAL1,f1.getArray().getIJ(0,0),13); - f1=MEDLoader.MEDLoader.ReadFieldCell(fileName,name3,0,name1,38,39); - self.assertAlmostEqual(3*VAL2,f1.getArray().getIJ(0,0),13); - f1=MEDLoader.MEDLoader.ReadFieldCell(fileName,name3,0,name1,48,49); - self.assertAlmostEqual(4*VAL2,f1.getArray().getIJ(0,0),13); - # - f1=MEDLoader.MEDLoader.ReadFieldNode(fileName,name3,0,name1,8,9); - self.assertAlmostEqual(71.,f1.getArray().getIJ(0,3),13); - f1=MEDLoader.MEDLoader.ReadFieldNode(fileName,name3,0,name1,108,109); - self.assertAlmostEqual(VAL1,f1.getArray().getIJ(0,3),13); - f1=MEDLoader.MEDLoader.ReadFieldNode(fileName,name3,0,name1,208,209); - self.assertAlmostEqual(VAL2,f1.getArray().getIJ(0,3),13); - pass - - def testMultiMeshRW1(self): - fileName="Pyfile10.med"; - mesh1=MEDLoaderDataForTest.build3DMesh_1(); - part1=[1,2,4,13,15] - mesh2=mesh1.buildPartOfMySelf(part1,True); - mesh2.setName("mesh2"); - part2=[3,4,13,14] - mesh3=mesh1.buildPartOfMySelf(part2,True); - mesh3.setName("mesh3"); - mesh4=MEDLoader.MEDCouplingUMesh.New(); - mesh4.setName("mesh4"); - mesh4.setMeshDimension(3); - mesh4.allocateCells(1); - conn=[0,11,1,3] - mesh4.insertNextCell(MEDLoader.NORM_TETRA4,4,conn[0:4]) - mesh4.finishInsertingCells(); - mesh4.setCoords(mesh1.getCoords()); - meshes=[mesh1,mesh2,mesh3,mesh4] - mnane="3DToto"; - MEDLoader.MEDLoader.WriteUMeshesPartition(fileName,mnane,meshes,True); - # - mesh5=MEDLoader.MEDLoader.ReadUMeshFromFile(fileName,mnane); - mesh1.setName(mnane); - part3=[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17] - mesh6=mesh5.buildPartOfMySelf(part3,True); - mesh6.setName(mnane); - self.assertTrue(mesh6.isEqual(mesh1,1e-12)); - grps=MEDLoader.MEDLoader.GetMeshGroupsNames(fileName,mnane); - self.assertEqual(4,len(grps)); - grps.index("mesh2"); - grps.index("mesh3"); - grps.index("mesh4"); - grps.index("3DMesh_1"); - # - vec=("mesh2",); - mesh2_2=MEDLoader.MEDLoader.ReadUMeshFromGroups(fileName,mnane,0,vec); - self.assertTrue(mesh2_2.isEqual(mesh2,1e-12)); - vec=["mesh3"]; - mesh3_2=MEDLoader.MEDLoader.ReadUMeshFromGroups(fileName,mnane,0,vec); - self.assertTrue(mesh3_2.isEqual(mesh3,1e-12)); - vec=["mesh4"]; - mesh4_2=MEDLoader.MEDLoader.ReadUMeshFromGroups(fileName,mnane,0,vec); - self.assertTrue(mesh4_2.isEqual(mesh4,1e-12)); - vec="3DMesh_1"; - mesh1_2=MEDLoader.MEDLoader.ReadUMeshFromGroups(fileName,mnane,0,vec); - mesh1.setName("3DMesh_1"); - self.assertTrue(mesh1_2.isEqual(mesh1,1e-12)); - # - vec=["Family_-3","Family_-5"]; - mesh2_2=MEDLoader.MEDLoader.ReadUMeshFromFamilies(fileName,mnane,0,vec); - mesh2_2.setName("mesh2"); - self.assertTrue(mesh2_2.isEqual(mesh2,1e-12)); - # - ret=MEDLoader.MEDLoader.GetMeshFamiliesNamesOnGroup(fileName,"3DToto","3DMesh_1"); - self.assertEqual(4,len(ret)); - self.assertEqual(ret[0],"Family_-2"); - self.assertEqual(ret[1],"Family_-3"); - self.assertEqual(ret[2],"Family_-4"); - self.assertEqual(ret[3],"Family_-5"); - # - ret1=MEDLoader.MEDLoader.GetMeshGroupsNamesOnFamily(fileName,"3DToto","Family_-3"); - self.assertEqual(2,len(ret1)); - self.assertEqual(ret1[0],"3DMesh_1"); - self.assertEqual(ret1[1],"mesh2"); - pass - - def testFieldProfilRW1(self): - fileName="Pyfile12.med"; - mesh1=MEDLoaderDataForTest.build3DMesh_1(); - da,b,newNbOfNodes=mesh1.mergeNodes(1e-12); - MEDLoader.MEDLoader.WriteUMesh(fileName,mesh1,True); - part1=[1,2,4,13,15] - mesh2=mesh1.buildPartOfMySelf(part1,True); - mesh2.setName(mesh1.getName());#<- important for the test - # - nbOfCells=mesh2.getNumberOfCells(); - self.assertEqual(5,nbOfCells); - f1=MEDLoader.MEDCouplingFieldDouble.New(MEDLoader.ON_CELLS,MEDLoader.ONE_TIME); - f1.setName("VectorFieldOnCells"); - f1.setMesh(mesh2); - array=MEDLoader.DataArrayDouble.New(); - array.alloc(nbOfCells,2); - f1.setArray(array); - arr1=[71.,171.,10.,110.,20.,120.,30.,130.,40.,140.] - array.setValues(arr1,nbOfCells,2); - f1.setTime(3.14,2,7); - f1.checkCoherency(); - # - MEDLoader.MEDLoader.WriteField(fileName,f1,False);#<- False important for the test - # - f2=MEDLoader.MEDLoader.ReadFieldCell(fileName,f1.getMesh().getName(),0,f1.getName(),2,7); - tt=MEDLoader.MEDLoader.GetTypesOfField(fileName,f1.getMesh().getName(),f1.getName()); - self.assertEqual(tt,[MEDLoader.ON_CELLS]); - f2.checkCoherency(); - self.assertTrue(f1.isEqual(f2,1e-12,1e-12)); - # - pass - - def testFieldGaussRW1(self): - fileName="Pyfile13.med"; - f1=MEDLoaderDataForTest.buildVecFieldOnGauss_1(); - MEDLoader.MEDLoader.WriteField(fileName,f1,True); - f2=MEDLoader.MEDLoader.ReadField(MEDLoader.ON_GAUSS_PT,fileName,f1.getMesh().getName(),0,f1.getName(),1,5); - self.assertTrue(f1.isEqual(f2,1e-12,1e-12)); - pass - - def testFieldGaussNERW1(self): - fileName="Pyfile14.med"; - f1=MEDLoaderDataForTest.buildVecFieldOnGaussNE_1(); - MEDLoader.MEDLoader.WriteField(fileName,f1,True); - self.assertEqual([MEDLoader.ON_GAUSS_NE],MEDLoader.MEDLoader.GetTypesOfField(fileName,'2DMesh_2','MyFieldOnGaussNE')) #Bug 22/5/2014 - f2=MEDLoader.MEDLoader.ReadField(MEDLoader.ON_GAUSS_NE,fileName,f1.getMesh().getName(),0,f1.getName(),1,5); - self.assertTrue(f1.isEqual(f2,1e-12,1e-12)); - pass - - def testMesh3DSurfShuffleRW(self): - fileName="Pyfile15.med"; - mesh=MEDLoaderDataForTest.build3DSurfMesh_1(); - renumber1=[2,5,1,0,3,4] - mesh.renumberCells(renumber1,False); - mesh.checkCoherency(); - MEDLoader.MEDLoader.WriteUMesh(fileName,mesh,True); - mesh_rw=MEDLoader.MEDLoader.ReadUMeshFromFile(fileName,mesh.getName(),0); - self.assertTrue(mesh.isEqual(mesh_rw,1e-12)); - pass - - def testMultiFieldShuffleRW1(self): - fileName="Pyfile17.med"; - m=MEDLoaderDataForTest.build3DMesh_2(); - self.assertEqual(20,m.getNumberOfCells()); - self.assertEqual(45,m.getNumberOfNodes()); - polys=[1,4,6] - m.convertToPolyTypes(polys); - renum=[1,3,2,8,9,12,13,16,19,0,4,7,5,15,14,17,10,18,6,11] - m.renumberCells(renum,False); - m.orientCorrectlyPolyhedrons(); - # Writing - MEDLoader.MEDLoader.WriteUMesh(fileName,m,True); - f1Tmp=m.getMeasureField(False); - f1=f1Tmp.buildNewTimeReprFromThis(MEDLoader.ONE_TIME,False); - f1.setTime(0.,1,2); - f_1=f1.cloneWithMesh(True); - MEDLoader.MEDLoader.WriteFieldUsingAlreadyWrittenMesh(fileName,f1); - f1.applyFunc("2*x"); - f1.setTime(0.01,3,4); - f_2=f1.cloneWithMesh(True); - MEDLoader.MEDLoader.WriteFieldUsingAlreadyWrittenMesh(fileName,f1); - f1.applyFunc("2*x/3"); - f1.setTime(0.02,5,6); - f_3=f1.cloneWithMesh(True); - MEDLoader.MEDLoader.WriteFieldUsingAlreadyWrittenMesh(fileName,f1); - # Reading - its=[(1,2),(3,4),(5,6)]; - fs=MEDLoader.MEDLoader.ReadFieldsOnSameMesh(MEDLoader.ON_CELLS,fileName,f_1.getMesh().getName(),0,f_1.getName(),its); - self.assertEqual(3,len(fs)); - self.assertTrue(fs[0].isEqual(f_1,1e-12,1e-12)); - self.assertTrue(fs[1].isEqual(f_2,1e-12,1e-12)); - self.assertTrue(fs[2].isEqual(f_3,1e-12,1e-12)); - pass - - def testWriteUMeshesRW1(self): - fileName="Pyfile18.med"; - m3d=MEDLoaderDataForTest.build3DMesh_2(); - pt=[0.,0.,-0.3] - vec=[0.,0.,1.] - nodes=m3d.findNodesOnPlane(pt,vec,1e-12); - m2d=m3d.buildFacePartOfMySelfNode(nodes,True); - renumber=[1,2,0,4,3] - m2d.renumberCells(renumber,False); - m2d.setName("ExampleOfMultiDimW"); - meshes=[m2d,m3d] - MEDLoader.MEDLoader.WriteUMeshes(fileName,meshes,True); - m3d_bis=MEDLoader.MEDLoader.ReadUMeshFromFile(fileName,m2d.getName(),0); - self.assertTrue(not m3d_bis.isEqual(m3d,1e-12)); - m3d_bis.setName(m3d.getName()); - self.assertTrue(m3d_bis.isEqual(m3d,1e-12)); - m2d_bis=MEDLoader.MEDLoader.ReadUMeshFromFile(fileName,m2d.getName(),-1);#-1 for faces - self.assertTrue(m2d_bis.isEqual(m2d,1e-12)); - # Creation of a field on faces. - f1=MEDLoader.MEDCouplingFieldDouble.New(MEDLoader.ON_CELLS,MEDLoader.ONE_TIME); - f1.setName("FieldOnFacesShuffle"); - f1.setMesh(m2d); - array=MEDLoader.DataArrayDouble.New(); - arr1=[71.,171.,10.,110.,20.,120.,30.,130.,40.,140.] - array.setValues(arr1,m2d.getNumberOfCells(),2); - array.setInfoOnComponent(0,"plkj [mm]"); - array.setInfoOnComponent(1,"pqqqss [mm]"); - f1.setArray(array); - tmp=array.setValues(arr1,m2d.getNumberOfCells(),2); - f1.setTime(3.14,2,7); - f1.checkCoherency(); - MEDLoader.MEDLoader.WriteFieldUsingAlreadyWrittenMesh(fileName,f1); - f2=MEDLoader.MEDLoader.ReadFieldCell(fileName,f1.getMesh().getName(),-1,f1.getName(),2,7); - self.assertTrue(f2.isEqual(f1,1e-12,1e-12)); - pass - - def testFieldNodeProfilRW1(self): - fileName="Pyfile19.med"; - fileName2="Pyfile20.med"; - m=MEDLoaderDataForTest.build2DMesh_1(); - nbOfNodes=m.getNumberOfNodes(); - MEDLoader.MEDLoader.WriteUMesh(fileName,m,True); - f1=MEDLoader.MEDCouplingFieldDouble.New(MEDLoader.ON_NODES,MEDLoader.ONE_TIME); - f1.setName("VFieldOnNodes"); - f1.setMesh(m); - array=MEDLoader.DataArrayDouble.New(); - arr1=[1.,101.,2.,102.,3.,103.,4.,104.,5.,105.,6.,106.,7.,107.,8.,108.,9.,109.,10.,110.,11.,111.,12.,112.] - array.setValues(arr1,nbOfNodes,2); - f1.setArray(array); - array.setInfoOnComponent(0,"tyty [mm]"); - array.setInfoOnComponent(1,"uiop [MW]"); - f1.setTime(3.14,2,7); - f1.checkCoherency(); - arr2=[1,4] - f2=f1.buildSubPart(arr2); - f2.getMesh().setName(f1.getMesh().getName()); - MEDLoader.MEDLoader.WriteField(fileName,f2,False);#<- False important for the test - # - f3=MEDLoader.MEDLoader.ReadFieldNode(fileName,f2.getMesh().getName(),0,f2.getName(),2,7); - f3.checkCoherency(); - self.assertTrue(f3.isEqual(f2,1e-12,1e-12)); - # - arr3=[1,3,0,5,2,4] - f2.renumberNodes(arr3); - MEDLoader.MEDLoader.WriteUMesh(fileName2,m,True); - MEDLoader.MEDLoader.WriteField(fileName2,f2,False);#<- False important for the test - f3=MEDLoader.MEDLoader.ReadFieldNode(fileName2,f2.getMesh().getName(),0,f2.getName(),2,7); - f3.checkCoherency(); - self.assertTrue(f3.isEqual(f2,1e-12,1e-12)); - # - pass - - def testFieldNodeProfilRW2(self): - fileName="Pyfile23.med"; - mesh=MEDLoaderDataForTest.build3DSurfMesh_1(); - MEDLoader.MEDLoader.WriteUMesh(fileName,mesh,True); - # - f1=MEDLoader.MEDCouplingFieldDouble.New(MEDLoader.ON_NODES,MEDLoader.ONE_TIME); - f1.setName("FieldMix"); - f1.setMesh(mesh); - arr2=[1071.,1171.,1010.,1110.,1020.,1120.,1030.,1130.,1040.,1140.,1050.,1150., - 1060.,1160.,1070.,1170.,1080.,1180.,1090.,1190.,1091.,1191.,1092.,1192.]; - array=MEDLoader.DataArrayDouble.New(); - array.setValues(arr2,12,2); - f1.setArray(array); - array.setInfoOnComponent(0,"plkj [mm]"); - array.setInfoOnComponent(1,"pqqqss [mm]"); - tmp=array.getPointer(); - f1.setTime(3.17,2,7); - # - renumArr=[3,7,2,1,5,11,10,0,9,6,8,4] - f1.renumberNodes(renumArr); - f1.checkCoherency(); - MEDLoader.MEDLoader.WriteField(fileName,f1,False);#<- False important for the test - f2=MEDLoader.MEDLoader.ReadFieldNode(fileName,f1.getMesh().getName(),0,f1.getName(),2,7); - self.assertTrue(f2.isEqual(f1,1e-12,1e-12)); - # - pass - - def testMixCellAndNodesFieldRW1(self): - fileName="Pyfile21.med"; - mesh=MEDLoaderDataForTest.build3DSurfMesh_1(); - f1=MEDLoader.MEDCouplingFieldDouble.New(MEDLoader.ON_CELLS,MEDLoader.ONE_TIME); - f1.setName("FieldMix"); - f1.setMesh(mesh); - array=MEDLoader.DataArrayDouble.New(); - f1.setArray(array); - arr1=[71.,171.,10.,110.,20.,120.,30.,130.,40.,140.,50.,150.] - array.setValues(arr1,6,2); - array.setInfoOnComponent(0,"plkj [mm]"); - array.setInfoOnComponent(1,"pqqqss [mm]"); - f1.setTime(3.14,2,7); - f1.checkCoherency(); - # - f2=MEDLoader.MEDCouplingFieldDouble.New(MEDLoader.ON_NODES,MEDLoader.ONE_TIME); - f2.setName("FieldMix"); - f2.setMesh(mesh); - array=MEDLoader.DataArrayDouble.New(); - f2.setArray(array); - arr2=[1071.,1171.,1010.,1110.,1020.,1120.,1030.,1130.,1040.,1140.,1050.,1150., - 1060.,1160.,1070.,1170.,1080.,1180.,1090.,1190.,1091.,1191.,1092.,1192.] - array.setValues(arr2,12,2) - array.setInfoOnComponent(0,"plkj [mm]"); - array.setInfoOnComponent(1,"pqqqss [mm]"); - f2.setTime(3.14,2,7); - f2.checkCoherency(); - # - MEDLoader.MEDLoader.WriteField(fileName,f1,True); - ts=MEDLoader.MEDLoader.GetTypesOfField(fileName,f1.getMesh().getName(),f1.getName()); - self.assertEqual(1,len(ts)); - self.assertEqual(MEDLoader.ON_CELLS,ts[0]); - fs=MEDLoader.MEDLoader.GetAllFieldNamesOnMesh(fileName,f1.getMesh().getName()); - self.assertEqual(1,len(fs)); - self.assertTrue(fs[0]=="FieldMix"); - MEDLoader.MEDLoader.WriteFieldUsingAlreadyWrittenMesh(fileName,f2); - fs=MEDLoader.MEDLoader.GetAllFieldNamesOnMesh(fileName,f1.getMesh().getName()); - self.assertEqual(1,len(fs)); - self.assertTrue(fs[0]=="FieldMix"); - # - ts=MEDLoader.MEDLoader.GetTypesOfField(fileName,f1.getMesh().getName(),f1.getName()); - self.assertEqual(2,len(ts)); - self.assertEqual(MEDLoader.ON_NODES,ts[0]); - self.assertEqual(MEDLoader.ON_CELLS,ts[1]); - # - f3=MEDLoader.MEDLoader.ReadFieldNode(fileName,f1.getMesh().getName(),0,f1.getName(),2,7); - self.assertTrue(f3.isEqual(f2,1e-12,1e-12)); - f3=MEDLoader.MEDLoader.ReadFieldCell(fileName,f1.getMesh().getName(),0,f1.getName(),2,7); - self.assertTrue(f3.isEqual(f1,1e-12,1e-12)); - # - pass - - def testGetAllFieldNamesRW1(self): - fileName="Pyfile22.med"; - mesh=MEDLoaderDataForTest.build2DMesh_2(); - f1=MEDLoader.MEDCouplingFieldDouble.New(MEDLoader.ON_NODES,MEDLoader.ONE_TIME); - f1.setName("Field1"); - f1.setTime(3.44,5,6); - f1.setMesh(mesh); - f1.fillFromAnalytic(2,"x+y"); - MEDLoader.MEDLoader.WriteField(fileName,f1,True); - f1.setTime(1002.3,7,8); - f1.fillFromAnalytic(2,"x+77.*y"); - MEDLoader.MEDLoader.WriteFieldUsingAlreadyWrittenMesh(fileName,f1); - f1.setName("Field2"); - MEDLoader.MEDLoader.WriteField(fileName,f1,False); - f1.setName("Field3"); - mesh.setName("2DMesh_2Bis"); - MEDLoader.MEDLoader.WriteField(fileName,f1,False); - f1=MEDLoader.MEDCouplingFieldDouble.New(MEDLoader.ON_CELLS,MEDLoader.ONE_TIME); - f1.setName("Field8"); - f1.setTime(8.99,7,9); - f1.setMesh(mesh); - f1.fillFromAnalytic(3,"3*x+y"); - MEDLoader.MEDLoader.WriteField(fileName,f1,False); - fs=MEDLoader.MEDLoader.GetAllFieldNames(fileName); - self.assertEqual(4,len(fs)); - self.assertTrue(fs[0]=="Field1"); - self.assertTrue(fs[1]=="Field2"); - self.assertTrue(fs[2]=="Field3"); - self.assertTrue(fs[3]=="Field8"); - pass - - def testBigNbOfCompoNonReg(self): - fileName="Pyfile57.med" - m=MEDLoader.MEDCouplingCMesh() ; m.setCoords(MEDLoader.DataArrayDouble([0,1,2,3]),MEDLoader.DataArrayDouble([0,1]),MEDLoader.DataArrayDouble([0,1])) - m=m.buildUnstructured() ; m.setName("TinyMesh") - f=MEDLoader.MEDCouplingFieldDouble(MEDLoader.ON_CELLS) ; f.setMesh(m) - nbOfCompo=4100 - arr=MEDLoader.DataArrayDouble(nbOfCompo*3) ; arr.iota() - arr.rearrange(nbOfCompo) - arr.setInfoOnComponents(["c%i"%(i) for i in xrange(nbOfCompo)]) - f.setArray(arr) - f.setName("FieldBigCompo") - MEDLoader.MEDLoader.WriteField(fileName,f,True) - f2=MEDLoader.MEDLoader.ReadFieldCell(fileName,m.getName(),0,f.getName(),-1,-1) - self.assertTrue(f.isEqual(f2,1e-12,1e-12)) - pass - - def testMultiMeshTypeWrite0(self): - fname="Pyfile73.med" - m=MEDLoader.MEDCoupling1SGTUMesh("mesh",MEDLoader.NORM_QUAD4) ; m.allocateCells() - m.insertNextCell([0,2,1,3]) - m.setCoords(MEDLoader.DataArrayDouble([0.,0.,1.,1.,1.,0.,0.,1.],4,2)) - # - ms=[m.deepCpy() for i in xrange(4)] - for i,elt in enumerate(ms): - elt.translate([float(i)*1.5,0.]) - pass - # - m0=MEDLoader.MEDCoupling1SGTUMesh.Merge1SGTUMeshes(ms) - f=m0.getMeasureField(False) ; f.getArray().setInfoOnComponents(["ABC [defg]"]) - MEDLoader.MEDLoader.WriteField(fname,f,True) - # - fRead=MEDLoader.MEDLoader.ReadFieldCell(fname,"merge",0,f.getName(),-1,-1) - fRead.setMesh(MEDLoader.MEDCoupling1SGTUMesh(fRead.getMesh())) - self.assertTrue(f.isEqual(fRead,1e-12,1e-12)) - # - m0=m0.buildUnstructured() ; m0.convertAllToPoly() - m0=MEDLoader.MEDCoupling1DGTUMesh(m0) - f=m0.getMeasureField(False) ; f.getArray().setInfoOnComponents(["ABC [defg]"]) - MEDLoader.MEDLoader.WriteField(fname,f,True) - # - fRead=MEDLoader.MEDLoader.ReadFieldCell(fname,"merge",0,f.getName(),-1,-1) - fRead.setMesh(MEDLoader.MEDCoupling1DGTUMesh(fRead.getMesh())) - self.assertTrue(f.isEqual(fRead,1e-12,1e-12)) - # - m0=MEDLoader.MEDCouplingCMesh() - arr=MEDLoader.DataArrayDouble(4) ; arr.iota() - m0.setCoords(arr,arr) - m0.setName("mesh") - f=m0.getMeasureField(False) ; f.getArray().setInfoOnComponents(["ABC [defg]"]) - MEDLoader.MEDLoader.WriteField(fname,f,True) - # - fRead=MEDLoader.MEDLoader.ReadFieldCell(fname,"mesh",0,f.getName(),-1,-1) - self.assertTrue(f.isEqual(fRead,1e-12,1e-12)) - # - c=m0.buildUnstructured().getCoords() - m0=MEDLoader.MEDCouplingCurveLinearMesh("mesh") - m0.setNodeGridStructure([4,4]) - m0.setCoords(c) - f=m0.getMeasureField(False) ; f.getArray().setInfoOnComponents(["ABC [defg]"]) - MEDLoader.MEDLoader.WriteField(fname,f,True) - # - fRead=MEDLoader.MEDLoader.ReadFieldCell(fname,"mesh",0,f.getName(),-1,-1) - self.assertTrue(f.isEqual(fRead,1e-12,1e-12)) - pass - - def testMultiMeshTypeWrite1(self): - fname="Pyfile74.med" - m=MEDLoader.MEDCoupling1SGTUMesh("mesh",MEDLoader.NORM_QUAD4) ; m.allocateCells() - m.insertNextCell([0,2,1,3]) - m.setCoords(MEDLoader.DataArrayDouble([0.,0.,1.,1.,1.,0.,0.,1.],4,2)) - # - ms=[m.deepCpy() for i in xrange(4)] - for i,elt in enumerate(ms): - elt.translate([float(i)*1.5,0.]) - pass - m0=MEDLoader.MEDCoupling1SGTUMesh.Merge1SGTUMeshes(ms) - MEDLoader.MEDLoader.WriteMesh(fname,m0,True) - # - mRead=MEDLoader.MEDLoader.ReadMeshFromFile(fname,"merge",0) - self.assertTrue(isinstance(mRead,MEDLoader.MEDCouplingUMesh)) - mRead=MEDLoader.MEDCoupling1SGTUMesh(mRead) - self.assertTrue(m0.isEqual(mRead,1e-12)) - # - m0=m0.buildUnstructured() ; m0.convertAllToPoly() - m0=MEDLoader.MEDCoupling1DGTUMesh(m0) - MEDLoader.MEDLoader.WriteMesh(fname,m0,True) - # - mRead=MEDLoader.MEDLoader.ReadMeshFromFile(fname,"merge",0) - mRead=MEDLoader.MEDCoupling1DGTUMesh(mRead) - self.assertTrue(m0.isEqual(mRead,1e-12)) - # - m0=MEDLoader.MEDCouplingCMesh() - arr=MEDLoader.DataArrayDouble(4) ; arr.iota() - m0.setCoords(arr,arr) - m0.setName("mesh") - MEDLoader.MEDLoader.WriteMesh(fname,m0,True) - # - mRead=MEDLoader.MEDLoader.ReadMeshFromFile(fname,0) - self.assertTrue(isinstance(mRead,MEDLoader.MEDCouplingCMesh)) - self.assertTrue(m0.isEqual(mRead,1e-12)) - # - c=m0.buildUnstructured().getCoords() - m0=MEDLoader.MEDCouplingCurveLinearMesh("mesh") - m0.setNodeGridStructure([4,4]) - m0.setCoords(c) - MEDLoader.MEDLoader.WriteMesh(fname,m0,True) - # - mRead=MEDLoader.MEDLoader.ReadMeshFromFile(fname,0) - self.assertTrue(isinstance(mRead,MEDLoader.MEDCouplingCurveLinearMesh)) - self.assertTrue(m0.isEqual(mRead,1e-12)) - pass - - def testChangeGroupName(self): - """ This test is a non regression test on MEDFileUMesh.changeGroupName thanks to Alliance. - """ - mfd=MEDLoaderDataForTest.buildAMEDFileDataWithGroupOnOneFamilyForSauv() - mesh = mfd.getMeshes().getMeshAtPos(0) - mesh.changeGroupName("grp0_LM1", "xonall1") - self.assertTrue("xonall1" in mesh.getGroupsNames()) - pass - - def testFieldWithTooLongName(self): - """ This test is a non regression test, to check that in basic API the policies are taken into account. - """ - fname="Pyfile75.med" - # Coordinates - coords = [0.,0., 0.,1., 1.,1., 1.,0.] - # lvl 0 connectivity - conn2D = [1,2,3,4] - # lvl 0 mesh - m=MEDLoader.MEDCouplingUMesh.New("mesh",2) - m.allocateCells(1) - m.insertNextCell(MEDLoader.NORM_QUAD4,4,conn2D) - m.finishInsertingCells() - # assigning coordinates - meshCoords=MEDLoader.DataArrayDouble.New() - meshCoords.setValues(coords, 4, 2) - m.setCoords(meshCoords) - # - f=MEDLoader.MEDCouplingFieldDouble.New(MEDLoader.ON_CELLS,MEDLoader.ONE_TIME) - f.setMesh(m) - d=MEDLoader.DataArrayDouble.New() - d.alloc(1,1) - d.iota(1.) - # seting a long name - d.setInfoOnComponent(0,"CONCENTRATION of I129") - f.setArray(d) - f.setName("field") - # - mm=MEDLoader.MEDFileUMesh() - MEDLoader.MEDLoader.SetTooLongStrPolicy(2) - MEDLoader.MEDLoader.AssignStaticWritePropertiesTo(mm) - self.assertEqual(2,mm.getTooLongStrPolicy()) - MEDLoader.MEDLoader.SetTooLongStrPolicy(0) - MEDLoader.MEDLoader.AssignStaticWritePropertiesTo(mm) - self.assertEqual(0,mm.getTooLongStrPolicy()) - del mm - # - MEDLoader.MEDLoader.SetTooLongStrPolicy(2) - self.assertRaises(MEDLoader.InterpKernelException,MEDLoader.MEDLoader.WriteField,fname,f,True)# the component name is too long + policy 2 -> throw - f.getArray().setInfoOnComponent(0,'I129') - MEDLoader.MEDLoader.WriteField(fname,f,True) - pass - - def testUsingAlreadyWrittenMesh2(self): - """ This test focuses on MEDLoader.WriteFieldUsingAlreadyWrittenMesh with mesh different from UMesh. - """ - fname="Pyfile76.med" - mesh=MEDLoader.MEDCouplingCMesh("mesh") - arrX=MEDLoader.DataArrayDouble([0,1,2,3]) - arrY=MEDLoader.DataArrayDouble([0,2,3,5,7]) - arrZ=MEDLoader.DataArrayDouble([7]) - mesh.setCoords(arrX,arrY,arrZ) - # - f1=MEDLoader.MEDCouplingFieldDouble(MEDLoader.ON_NODES) ; f1.setName("f1") - f1.setMesh(mesh) - arr=MEDLoader.DataArrayDouble(20) ; arr.iota() - f1.setArray(arr) - f1.checkCoherency() - # - f2=MEDLoader.MEDCouplingFieldDouble(MEDLoader.ON_NODES) ; f2.setName("f2") - f2.setMesh(mesh) - arr=MEDLoader.DataArrayDouble(20) ; arr.iota() ; arr*=3 - f2.setArray(arr) - f2.checkCoherency() - # - f11=f1.deepCpy() ; (f11.getArray())[:]*=4 ; f11.setTime(1.1,5,6) - # - MEDLoader.MEDLoader.WriteMesh(fname,f1.getMesh(),True) - MEDLoader.MEDLoader.WriteFieldUsingAlreadyWrittenMesh(fname,f1) - MEDLoader.MEDLoader.WriteFieldUsingAlreadyWrittenMesh(fname,f2) - MEDLoader.MEDLoader.WriteFieldUsingAlreadyWrittenMesh(fname,f11) - ## - f1r=MEDLoader.MEDLoader.ReadFieldNode(fname,"mesh",0,"f1",-1,-1); - self.assertTrue(f1.isEqual(f1r,1e-12,1e-12)) - self.assertTrue(f1r.getArray().isEqual(MEDLoader.DataArrayDouble([0.,1.,2.,3.,4.,5.,6.,7.,8.,9.,10.,11.,12.,13.,14.,15.,16.,17.,18.,19.]),1e-12)) - f2r=MEDLoader.MEDLoader.ReadFieldNode(fname,"mesh",0,"f2",-1,-1); - self.assertTrue(f2.isEqual(f2r,1e-12,1e-12)) - self.assertTrue(f2r.getArray().isEqual(MEDLoader.DataArrayDouble([0.,3.,6.,9.,12.,15.,18.,21.,24.,27.,30.,33.,36.,39.,42.,45.,48.,51.,54.,57.]),1e-12)) - f3r=MEDLoader.MEDLoader.ReadFieldNode(fname,"mesh",0,"f1",5,6); - self.assertTrue(f11.isEqual(f3r,1e-12,1e-12)) - self.assertTrue(f3r.getArray().isEqual(MEDLoader.DataArrayDouble([0.,4.,8.,12.,16.,20.,24.,28.,32.,36.,40.,44.,48.,52.,56.,60.,64.,68.,72.,76.]),1e-12)) - pass - pass - -if __name__ == "__main__": - unittest.main() diff --git a/src/MEDLoader/Swig/MEDLoaderTest2.py b/src/MEDLoader/Swig/MEDLoaderTest2.py deleted file mode 100644 index 06cc645d0..000000000 --- a/src/MEDLoader/Swig/MEDLoaderTest2.py +++ /dev/null @@ -1,341 +0,0 @@ -# -*- coding: iso-8859-1 -*- -# Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 -# 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) - -from MEDLoader import * -import unittest -from math import pi,e,sqrt -from MEDLoaderDataForTest import MEDLoaderDataForTest - -class MEDLoaderTest(unittest.TestCase): - def testMesh1DRW(self): - mesh=MEDLoaderDataForTest.build1DMesh_1(); - mesh.checkCoherency(); - MEDLoader.WriteUMeshDep("Pyfile1.med",mesh,False); - mesh_rw=MEDLoader.ReadUMeshFromFile("Pyfile1.med",mesh.getName(),0); - self.assertTrue(mesh.isEqual(mesh_rw,1e-12)); - pass - - def testMesh2DCurveRW(self): - mesh=MEDLoaderDataForTest.build2DCurveMesh_1(); - mesh.checkCoherency(); - MEDLoader.WriteUMeshDep("Pyfile2.med",mesh,False); - mesh_rw=MEDLoader.ReadUMeshFromFile("Pyfile2.med",mesh.getName(),0); - self.assertTrue(mesh.isEqual(mesh_rw,1e-12)); - pass - - def testMesh2DRW(self): - mesh=MEDLoaderDataForTest.build2DMesh_1(); - mesh.checkCoherency(); - MEDLoader.WriteUMeshDep("Pyfile3.med",mesh,False); - mesh_rw=MEDLoader.ReadUMeshFromFile("Pyfile3.med",mesh.getName(),0); - self.assertTrue(mesh.isEqual(mesh_rw,1e-12)); - pass - - def testMesh3DSurfRW(self): - mesh=MEDLoaderDataForTest.build3DSurfMesh_1(); - mesh.checkCoherency(); - MEDLoader.WriteUMeshDep("Pyfile4.med",mesh,False); - mesh_rw=MEDLoader.ReadUMeshFromFile("Pyfile4.med",mesh.getName(),0); - self.assertTrue(mesh.isEqual(mesh_rw,1e-12)); - pass - - def testMesh3DRW(self): - mesh=MEDLoaderDataForTest.build3DMesh_1(); - mesh.checkCoherency(); - MEDLoader.WriteUMeshDep("Pyfile5.med",mesh,False); - mesh_rw=MEDLoader.ReadUMeshFromFile("Pyfile5.med",mesh.getName(),0); - self.assertTrue(mesh.isEqual(mesh_rw,1e-12)); - pass - - def testFieldRW1(self): - f1=MEDLoaderDataForTest.buildVecFieldOnCells_1(); - MEDLoader.WriteFieldDep("Pyfile6.med",f1,False); - f2=MEDLoader.ReadFieldCell("Pyfile6.med",f1.getMesh().getName(),0,f1.getName(),0,1); - self.assertTrue(f1.isEqual(f2,1e-12,1e-12)); - # - f1=MEDLoaderDataForTest.buildVecFieldOnNodes_1(); - MEDLoader.WriteFieldDep("Pyfile7.med",f1,False); - f2=MEDLoader.ReadFieldNode("Pyfile7.med",f1.getMesh().getName(),0,f1.getName(),2,3); - self.assertTrue(f1.isEqual(f2,1e-12,1e-12)); - pass - - def testFieldRW2(self): - fileName="Pyfile8.med"; - VAL1=12345.67890314; - VAL2=-1111111111111.; - f1=MEDLoaderDataForTest.buildVecFieldOnCells_1(); - MEDLoader.WriteFieldDep(fileName,f1,False); - f1.setTime(10.,8,9); - f1.getArray().setIJ(0,0,VAL1); - MEDLoader.WriteFieldUsingAlreadyWrittenMesh(fileName,f1); - f1.setTime(10.14,18,19); - f1.getArray().setIJ(0,0,VAL2); - MEDLoader.WriteFieldUsingAlreadyWrittenMesh(fileName,f1); - #retrieving time steps... - f2=MEDLoader.ReadFieldCell(fileName,f1.getMesh().getName(),0,f1.getName(),8,9); - f1.setTime(10.,8,9); - f1.getArray().setIJ(0,0,VAL1); - self.assertTrue(f1.isEqual(f2,1e-12,1e-12)); - f2=MEDLoader.ReadFieldCell(fileName,f1.getMesh().getName(),0,f1.getName(),0,1); - f3=MEDLoaderDataForTest.buildVecFieldOnCells_1(); - self.assertTrue(f3.isEqual(f2,1e-12,1e-12)); - f2=MEDLoader.ReadFieldCell(fileName,f1.getMesh().getName(),0,f1.getName(),18,19); - f1.setTime(10.14,18,19); - f1.getArray().setIJ(0,0,VAL2); - self.assertTrue(f1.isEqual(f2,1e-12,1e-12)); - #ON NODES - f1=MEDLoaderDataForTest.buildVecFieldOnNodes_1(); - fileName2="Pyfile9.med"; - MEDLoader.WriteFieldDep(fileName2,f1,False); - f1.setTime(110.,108,109); - tmp=f1.getArray().getPointer(); - f1.getArray().setIJ(0,3,VAL1); - MEDLoader.WriteFieldUsingAlreadyWrittenMesh(fileName2,f1); - f1.setTime(210.,208,209); - f1.getArray().setIJ(0,3,VAL2); - MEDLoader.WriteFieldUsingAlreadyWrittenMesh(fileName2,f1); - f2=MEDLoader.ReadFieldNode(fileName2,f1.getMesh().getName(),0,f1.getName(),108,109); - f1.setTime(110.,108,109); - f1.getArray().setIJ(0,3,VAL1); - self.assertTrue(f1.isEqual(f2,1e-12,1e-12)); - f2=MEDLoader.ReadFieldNode(fileName2,f1.getMesh().getName(),0,f1.getName(),2,3); - f3=MEDLoaderDataForTest.buildVecFieldOnNodes_1(); - self.assertTrue(f3.isEqual(f2,1e-12,1e-12)); - f2=MEDLoader.ReadFieldNode(fileName2,f1.getMesh().getName(),0,f1.getName(),208,209); - f1.setTime(210.,208,209); - f1.getArray().setIJ(0,3,VAL2); - self.assertTrue(f1.isEqual(f2,1e-12,1e-12)); - pass - - # - # Multi field in a same file, but this field has several - # - def testFieldRW3(self): - fileName="Pyfile11.med"; - VAL1=12345.67890314; - VAL2=-1111111111111.; - name1="AField"; - name3="AMesh1"; - f1=MEDLoaderDataForTest.buildVecFieldOnCells_1(); - f1.getMesh().setName(name3); - f1.setName(name1); - f1.setTime(10.,8,9); - tmp=f1.getArray().getPointer(); - f1.getArray().setIJ(0,0,VAL1); - MEDLoader.WriteFieldDep(fileName,f1,False); - f1.setTime(10.14,18,19); - f1.getArray().setIJ(0,0,VAL2); - MEDLoader.WriteFieldUsingAlreadyWrittenMesh(fileName,f1); - f1.getMesh().setName(name3); - f1.setTime(10.55,28,29); - f1.getArray().setIJ(0,0,3*VAL1); - MEDLoader.WriteFieldUsingAlreadyWrittenMesh(fileName,f1); - f1.setTime(10.66,38,39); - f1.getArray().setIJ(0,0,3*VAL2); - MEDLoader.WriteFieldUsingAlreadyWrittenMesh(fileName,f1); - f1.setTime(10.77,48,49); - f1.getArray().setIJ(0,0,4*VAL2); - MEDLoader.WriteFieldUsingAlreadyWrittenMesh(fileName,f1); - #ON NODES - f1=MEDLoaderDataForTest.buildVecFieldOnNodes_1(); - f1.setName(name1); - f1.getMesh().setName(name3); - f1.setTime(110.,8,9); - MEDLoader.WriteFieldUsingAlreadyWrittenMesh(fileName,f1); - f1.setTime(110.,108,109); - tmp=f1.getArray().getPointer(); - f1.getArray().setIJ(0,3,VAL1); - MEDLoader.WriteFieldUsingAlreadyWrittenMesh(fileName,f1); - f1.setTime(210.,208,209); - f1.getArray().setIJ(0,3,VAL2); - MEDLoader.WriteFieldUsingAlreadyWrittenMesh(fileName,f1); - # - it1=MEDLoader.GetCellFieldIterations(fileName,name3,name1); - self.assertEqual(5,len(it1)); - self.assertEqual(8,it1[0][0]); self.assertEqual(9,it1[0][1]); - self.assertEqual(18,it1[1][0]); self.assertEqual(19,it1[1][1]); - self.assertEqual(28,it1[2][0]); self.assertEqual(29,it1[2][1]); - self.assertEqual(38,it1[3][0]); self.assertEqual(39,it1[3][1]); - self.assertEqual(48,it1[4][0]); self.assertEqual(49,it1[4][1]); - it3=MEDLoader.GetNodeFieldIterations(fileName,name3,name1); - self.assertEqual(3,len(it3)); - self.assertEqual(8,it3[0][0]); self.assertEqual(9,it3[0][1]); - self.assertEqual(108,it3[1][0]); self.assertEqual(109,it3[1][1]); - self.assertEqual(208,it3[2][0]); self.assertEqual(209,it3[2][1]); - # - # - f1=MEDLoader.ReadFieldCell(fileName,name3,0,name1,8,9); - self.assertAlmostEqual(VAL1,f1.getArray().getIJ(0,0),13); - f1=MEDLoader.ReadFieldCell(fileName,name3,0,name1,18,19); - self.assertAlmostEqual(VAL2,f1.getArray().getIJ(0,0),13); - f1=MEDLoader.ReadFieldCell(fileName,name3,0,name1,28,29); - self.assertAlmostEqual(3*VAL1,f1.getArray().getIJ(0,0),13); - f1=MEDLoader.ReadFieldCell(fileName,name3,0,name1,38,39); - self.assertAlmostEqual(3*VAL2,f1.getArray().getIJ(0,0),13); - f1=MEDLoader.ReadFieldCell(fileName,name3,0,name1,48,49); - self.assertAlmostEqual(4*VAL2,f1.getArray().getIJ(0,0),13); - # - f1=MEDLoader.ReadFieldNode(fileName,name3,0,name1,8,9); - self.assertAlmostEqual(71.,f1.getArray().getIJ(0,3),13); - f1=MEDLoader.ReadFieldNode(fileName,name3,0,name1,108,109); - self.assertAlmostEqual(VAL1,f1.getArray().getIJ(0,3),13); - f1=MEDLoader.ReadFieldNode(fileName,name3,0,name1,208,209); - self.assertAlmostEqual(VAL2,f1.getArray().getIJ(0,3),13); - pass - - def testMultiMeshRW1(self): - fileName="Pyfile10.med"; - mesh1=MEDLoaderDataForTest.build3DMesh_1(); - part1=[1,2,4,13,15] - mesh2=mesh1.buildPartOfMySelf(part1,True); - mesh2.setName("mesh2"); - part2=[3,4,13,14] - mesh3=mesh1.buildPartOfMySelf(part2,True); - mesh3.setName("mesh3"); - mesh4=MEDCouplingUMesh.New(); - mesh4.setName("mesh4"); - mesh4.setMeshDimension(3); - mesh4.allocateCells(1); - conn=[0,11,1,3] - mesh4.insertNextCell(NORM_TETRA4,4,conn[0:4]) - mesh4.finishInsertingCells(); - mesh4.setCoords(mesh1.getCoords()); - meshes=[mesh1,mesh2,mesh3,mesh4] - mnane="3DToto"; - MEDLoader.WriteUMeshesPartitionDep(fileName,mnane,meshes,False); - # - mesh5=MEDLoader.ReadUMeshFromFile(fileName,mnane); - mesh1.setName(mnane); - part3=[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17] - mesh6=mesh5.buildPartOfMySelf(part3,True); - mesh6.setName(mnane); - self.assertTrue(mesh6.isEqual(mesh1,1e-12)); - grps=MEDLoader.GetMeshGroupsNames(fileName,mnane); - self.assertEqual(4,len(grps)); - grps.index("mesh2"); - grps.index("mesh3"); - grps.index("mesh4"); - grps.index("3DMesh_1"); - # - vec=["mesh2"]; - mesh2_2=MEDLoader.ReadUMeshFromGroups(fileName,mnane,0,vec); - self.assertTrue(mesh2_2.isEqual(mesh2,1e-12)); - vec=["mesh3"]; - mesh3_2=MEDLoader.ReadUMeshFromGroups(fileName,mnane,0,vec); - self.assertTrue(mesh3_2.isEqual(mesh3,1e-12)); - vec=["mesh4"]; - mesh4_2=MEDLoader.ReadUMeshFromGroups(fileName,mnane,0,vec); - self.assertTrue(mesh4_2.isEqual(mesh4,1e-12)); - vec=["3DMesh_1"]; - mesh1_2=MEDLoader.ReadUMeshFromGroups(fileName,mnane,0,vec); - mesh1.setName("3DMesh_1"); - self.assertTrue(mesh1_2.isEqual(mesh1,1e-12)); - # - vec=["Family_-5","Family_-3"]; - mesh2_2=MEDLoader.ReadUMeshFromFamilies(fileName,mnane,0,vec); - mesh2_2.setName("mesh2"); - self.assertTrue(mesh2_2.isEqual(mesh2,1e-12)); - pass - - def testMesh3DSurfShuffleRW(self): - fileName="Pyfile15.med"; - mesh=MEDLoaderDataForTest.build3DSurfMesh_1(); - renumber1=[2,5,1,0,3,4] - mesh.renumberCells(renumber1,False); - mesh.checkCoherency(); - MEDLoader.WriteUMeshDep(fileName,mesh,False); - mesh_rw=MEDLoader.ReadUMeshFromFile(fileName,mesh.getName(),0); - self.assertTrue(mesh.isEqual(mesh_rw,1e-12)); - pass - - def testMultiFieldShuffleRW1(self): - fileName="Pyfile17.med"; - m=MEDLoaderDataForTest.build3DMesh_2(); - self.assertEqual(20,m.getNumberOfCells()); - self.assertEqual(45,m.getNumberOfNodes()); - polys=[1,4,6] - m.convertToPolyTypes(polys); - renum=[1,3,2,8,9,12,13,16,19,0,4,7,5,15,14,17,10,18,6,11] - m.renumberCells(renum,False); - m.orientCorrectlyPolyhedrons(); - # Writing - MEDLoader.WriteUMeshDep(fileName,m,False); - f1Tmp=m.getMeasureField(False); - f1=f1Tmp.buildNewTimeReprFromThis(ONE_TIME,False); - f1.setTime(0.,1,2); - f_1=f1.cloneWithMesh(True); - MEDLoader.WriteFieldUsingAlreadyWrittenMesh(fileName,f1); - f1.applyFunc("2*x"); - f1.setTime(0.01,3,4); - f_2=f1.cloneWithMesh(True); - MEDLoader.WriteFieldUsingAlreadyWrittenMesh(fileName,f1); - f1.applyFunc("2*x/3"); - f1.setTime(0.02,5,6); - f_3=f1.cloneWithMesh(True); - MEDLoader.WriteFieldUsingAlreadyWrittenMesh(fileName,f1); - # Reading - its=[(1,2),(3,4),(5,6)]; - fs=MEDLoader.ReadFieldsOnSameMesh(ON_CELLS,fileName,f_1.getMesh().getName(),0,f_1.getName(),its); - self.assertEqual(3,len(fs)); - self.assertTrue(fs[0].isEqual(f_1,1e-12,1e-12)); - self.assertTrue(fs[1].isEqual(f_2,1e-12,1e-12)); - self.assertTrue(fs[2].isEqual(f_3,1e-12,1e-12)); - pass - - def testWriteUMeshesRW1(self): - fileName="Pyfile18.med"; - m3d=MEDLoaderDataForTest.build3DMesh_2(); - pt=[0.,0.,-0.3] - vec=[0.,0.,1.] - nodes=m3d.findNodesOnPlane(pt,vec,1e-12); - m2d=m3d.buildFacePartOfMySelfNode(nodes,True); - renumber=[1,2,0,4,3] - m2d.renumberCells(renumber,False); - m2d.setName("ExampleOfMultiDimW"); - meshes=[m2d,m3d] - MEDLoader.WriteUMeshes(fileName,meshes,False); - m3d_bis=MEDLoader.ReadUMeshFromFile(fileName,m2d.getName(),0); - self.assertTrue(not m3d_bis.isEqual(m3d,1e-12)); - m3d_bis.setName(m3d.getName()); - self.assertTrue(m3d_bis.isEqual(m3d,1e-12)); - m2d_bis=MEDLoader.ReadUMeshFromFile(fileName,m2d.getName(),-1);#-1 for faces - self.assertTrue(m2d_bis.isEqual(m2d,1e-12)); - # Creation of a field on faces. - f1=MEDCouplingFieldDouble.New(ON_CELLS,ONE_TIME); - f1.setName("FieldOnFacesShuffle"); - f1.setMesh(m2d); - array=DataArrayDouble.New(); - arr1=[71.,171.,10.,110.,20.,120.,30.,130.,40.,140.] - array.setValues(arr1,m2d.getNumberOfCells(),2); - array.setInfoOnComponent(0,"plkj [mm]"); - array.setInfoOnComponent(1,"pqqqss [mm]"); - f1.setArray(array); - tmp=array.setValues(arr1,m2d.getNumberOfCells(),2); - f1.setTime(3.14,2,7); - f1.checkCoherency(); - MEDLoader.WriteFieldUsingAlreadyWrittenMesh(fileName,f1); - f2=MEDLoader.ReadFieldCell(fileName,f1.getMesh().getName(),-1,f1.getName(),2,7); - self.assertTrue(f2.isEqual(f1,1e-12,1e-12)); - pass - pass - -if __name__ == "__main__": - unittest.main() diff --git a/src/MEDLoader/Swig/MEDLoaderTest3.py b/src/MEDLoader/Swig/MEDLoaderTest3.py deleted file mode 100644 index ce9e0e076..000000000 --- a/src/MEDLoader/Swig/MEDLoaderTest3.py +++ /dev/null @@ -1,4659 +0,0 @@ -# -*- coding: iso-8859-1 -*- -# Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 -# 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) - -from MEDLoader import * -import unittest -import platform -from math import pi,e,sqrt -from MEDLoaderDataForTest import MEDLoaderDataForTest - -class MEDLoaderTest(unittest.TestCase): - def testMEDMesh1(self): - fileName="Pyfile18.med" - mname="ExampleOfMultiDimW" - medmesh=MEDFileMesh.New(fileName,mname) - self.assertRaises(InterpKernelException,MEDFileMesh.New,fileName,"") - self.assertEqual((0,-1),medmesh.getNonEmptyLevels()) - m1_0=medmesh.getLevel0Mesh(True) - m1_1=MEDLoader.ReadUMeshFromFile(fileName,mname,0) - self.assertTrue(m1_0.isEqual(m1_1,1e-12)); - m2_0=medmesh.getLevelM1Mesh(True) - m2_1=MEDLoader.ReadUMeshFromFile(fileName,mname,-1) - self.assertTrue(m2_0.isEqual(m2_1,1e-12)); - pass - - def testMEDMesh2(self): - fileName="Pyfile10.med" - mname="3DToto" - outFileName="MEDFileMesh1.med" - medmesh=MEDFileUMesh.New(fileName,mname) - self.assertEqual((0,),medmesh.getNonEmptyLevels()) - m1_0=medmesh.getLevel0Mesh(True) - m1_1=MEDLoader.ReadUMeshFromFile(fileName,mname,0) - self.assertTrue(m1_0.isEqual(m1_1,1e-12)); - g1_0=medmesh.getGroup(0,"mesh2",True) - g1_1=MEDLoader.ReadUMeshFromGroups(fileName,mname,0,["mesh2"]); - self.assertTrue(g1_0.isEqual(g1_1,1e-12)); - g1_0=medmesh.getGroup(0,"mesh3",True) - g1_1=MEDLoader.ReadUMeshFromGroups(fileName,mname,0,["mesh3"]); - self.assertTrue(g1_0.isEqual(g1_1,1e-12)); - g1_0=medmesh.getGroups(0,["mesh3","mesh2"]) - g1_1=MEDLoader.ReadUMeshFromGroups(fileName,mname,0,["mesh3","mesh2"]); - g1_1.setName(g1_0.getName()) - self.assertTrue(g1_0.isEqual(g1_1,1e-12)); - g1_0=medmesh.getFamily(0,"Family_-3",True) - g1_1=MEDLoader.ReadUMeshFromFamilies(fileName,mname,0,["Family_-3"]); - self.assertTrue(g1_0.isEqual(g1_1,1e-12)); - g1_0=medmesh.getFamilies(0,["Family_-3","Family_-5"],True) - g1_1=MEDLoader.ReadUMeshFromFamilies(fileName,mname,0,["Family_-3","Family_-5"]); - g1_1.setName(g1_0.getName()) - self.assertTrue(g1_0.isEqual(g1_1,1e-12)); - self.assertTrue(g1_0.isEqual(g1_1,1e-12)); - medmesh.write(outFileName,2); - self.assertEqual([1,2,4,13,15],medmesh.getGroupArr(0,"mesh2",True).getValues()); - self.assertEqual([1,2,15],medmesh.getFamilyArr(0,"Family_-3",True).getValues()); - self.assertEqual([1,2,4,13,15],medmesh.getFamiliesArr(0,["Family_-5","Family_-3"],True).getValues()); - self.assertEqual([18,1,2,3,4,13,14,15],medmesh.getGroupsArr(0,["mesh2","mesh4","mesh3"],True).getValues()); - famn=medmesh.getFamilyNameGivenId(0) - self.assertRaises(InterpKernelException,medmesh.getNodeFamilyArr,famn,True); - #without renum - self.assertEqual([2,3,5,14,16],medmesh.getGroupArr(0,"mesh2").getValues()); - self.assertEqual([2,3,16],medmesh.getFamilyArr(0,"Family_-3").getValues()); - self.assertEqual([2,3,5,14,16],medmesh.getFamiliesArr(0,["Family_-5","Family_-3"]).getValues()); - self.assertEqual([0,2,3,4,5,14,15,16],medmesh.getGroupsArr(0,["mesh2","mesh3","mesh4"],False).getValues()); - self.assertRaises(InterpKernelException,medmesh.getNodeFamilyArr,famn,False); - pass - - # this tests emulates MEDMEM ( Except that it works ! ) The permutation are NOT taken into account - def testMEDMesh3(self): - outFileName="MEDFileMesh3.med" - c=DataArrayDouble.New() - coords=[-0.3,-0.3, 0.2,-0.3, 0.7,-0.3, -0.3,0.2, 0.2,0.2, 0.7,0.2, -0.3,0.7, 0.2,0.7, 0.7,0.7 ]; - targetConn=[0,3,4,1, 1,4,2, 4,5,2, 6,7,4,3, 7,8,5,4] - c.setValues(coords,9,2) - m=MEDCouplingUMesh.New(); - m.setMeshDimension(2); - m.allocateCells(5); - m.insertNextCell(NORM_TRI3,3,targetConn[4:7]) - m.insertNextCell(NORM_TRI3,3,targetConn[7:10]) - m.insertNextCell(NORM_QUAD4,4,targetConn[0:4]) - m.insertNextCell(NORM_POLYGON,4,targetConn[10:14]) - m.insertNextCell(NORM_POLYGON,4,targetConn[14:18]) - m.finishInsertingCells(); - m.setCoords(c) - m.checkCoherency() - m1=MEDCouplingUMesh.New(); - m1.setMeshDimension(1); - m1.allocateCells(3); - m1.insertNextCell(NORM_SEG2,2,[1,4]) - m1.insertNextCell(NORM_SEG2,2,[3,6]) - m1.insertNextCell(NORM_SEG3,3,[2,8,5]) - m1.finishInsertingCells(); - m1.setCoords(c) - m1.checkCoherency() - m2=MEDCouplingUMesh.New(); - m2.setMeshDimension(0); - m2.allocateCells(4); - m2.insertNextCell(NORM_POINT1,1,[1]) - m2.insertNextCell(NORM_POINT1,1,[3]) - m2.insertNextCell(NORM_POINT1,1,[2]) - m2.insertNextCell(NORM_POINT1,1,[6]) - m2.finishInsertingCells(); - m2.setCoords(c) - m2.checkCoherency() - # - mm=MEDFileUMesh.New() - self.assertTrue(mm.getUnivNameWrStatus()) - mm.setName("MyFirstMEDCouplingMEDmesh") - mm.setDescription("IHopeToConvinceLastMEDMEMUsers") - mm.setCoords(c) - mm.setMeshAtLevel(-1,m1); - mm.setMeshAtLevel(0,m); - mm.setMeshAtLevel(-2,m2); - # playing with groups - g1_2=DataArrayInt.New() - g1_2.setValues([1,3],2,1) - g1_2.setName("G1") - g2_2=DataArrayInt.New() - g2_2.setValues([1,2,3],3,1) - g2_2.setName("G2") - mm.setGroupsAtLevel(0,[g1_2,g2_2],False) - g1_1=DataArrayInt.New() - g1_1.setValues([0,1,2],3,1) - g1_1.setName("G1") - g2_1=DataArrayInt.New() - g2_1.setValues([0,2],2,1) - g2_1.setName("G2") - mm.setGroupsAtLevel(-1,[g1_1,g2_1],False) - g1_N=DataArrayInt.New() - g1_N.setValues(range(8),8,1) - g1_N.setName("G1") - g2_N=DataArrayInt.New() - g2_N.setValues(range(9),9,1) - g2_N.setName("G2") - mm.setGroupsAtLevel(1,[g1_N,g2_N],False) - mm.createGroupOnAll(0,"GrpOnAllCell") - # check content of mm - t=mm.getGroupArr(0,"G1",False) - self.assertTrue(g1_2.isEqual(t)); - t=mm.getGroupArr(0,"G2",False) - self.assertTrue(g2_2.isEqual(t)); - t=mm.getGroupArr(-1,"G1",False) - self.assertTrue(g1_1.isEqual(t)); - t=mm.getGroupArr(-1,"G2",False) - self.assertTrue(g2_1.isEqual(t)); - t=mm.getGroupArr(1,"G1",False) - self.assertTrue(g1_N.isEqual(t)); - t=mm.getGroupArr(1,"G2",False) - self.assertTrue(g2_N.isEqual(t)); - self.assertTrue(mm.existsGroup("GrpOnAllCell")); - t=mm.getGroupArr(0,"GrpOnAllCell") - self.assertTrue(t.getValues()==range(5)) - # - mmCpy=mm.deepCpy() - self.assertTrue(mm.isEqual(mmCpy,1e-12)[0]) ; del mm - mmCpy.write(outFileName,2); - # - mm=MEDFileMesh.New(outFileName) - # - self.assertEqual([NORM_TRI3,NORM_QUAD4,NORM_POLYGON],mm.getGeoTypesAtLevel(0)) - self.assertEqual([NORM_SEG2,NORM_SEG3],mm.getGeoTypesAtLevel(-1)) - self.assertEqual([NORM_POINT1],mm.getGeoTypesAtLevel(-2)) - mm0=mm.getDirectUndergroundSingleGeoTypeMesh(NORM_POLYGON) - self.assertTrue(isinstance(mm0,MEDCoupling1DGTUMesh)) - self.assertTrue(mm0.getNodalConnectivity().isEqual(DataArrayInt([6,7,4,3,7,8,5,4]))) - self.assertTrue(mm0.getNodalConnectivityIndex().isEqual(DataArrayInt([0,4,8]))) - lmm=mm.getDirectUndergroundSingleGeoTypeMeshes(0) - self.assertEqual(3,len(lmm)) - self.assertTrue(isinstance(lmm[0],MEDCoupling1SGTUMesh)) - self.assertTrue(isinstance(lmm[1],MEDCoupling1SGTUMesh)) - self.assertTrue(isinstance(lmm[2],MEDCoupling1DGTUMesh)) - # - self.assertTrue(mm.getUnivNameWrStatus()) - self.assertTrue(isinstance(mm.getUnivName(),str)) - self.assertTrue(len(mm.getUnivName())!=0) - mbis=mm.getMeshAtLevel(0) - m.setName(mm.getName()) ; m.setDescription(mm.getDescription()) - self.assertTrue(m.isEqual(mbis,1e-12)); - # - self.assertEqual(([[(3, 2), (4, 1), (5, 8)], [(1, 2), (2, 1)], [(0, 4)]], 2, 2, 9),MEDLoader.GetUMeshGlobalInfo(outFileName,"MyFirstMEDCouplingMEDmesh")) - pass - - # this test is the testMEDMesh3 except that permutation is dealed here - def testMEDMesh4(self): - outFileName="MEDFileMesh4.med" - c=DataArrayDouble.New() - coords=[-0.3,-0.3, 0.2,-0.3, 0.7,-0.3, -0.3,0.2, 0.2,0.2, 0.7,0.2, -0.3,0.7, 0.2,0.7, 0.7,0.7 ]; - targetConn=[0,3,4,1, 1,4,2, 4,5,2, 6,7,4,3, 7,8,5,4] - c.setValues(coords,9,2) - c.setInfoOnComponent(0,"abcdef [km]") - c.setInfoOnComponent(1,"ghij [MW]") - m=MEDCouplingUMesh.New(); - m.setMeshDimension(2); - m.allocateCells(5); - m.insertNextCell(NORM_QUAD4,4,targetConn[0:4]) - m.insertNextCell(NORM_TRI3,3,targetConn[4:7]) - m.insertNextCell(NORM_TRI3,3,targetConn[7:10]) - m.insertNextCell(NORM_QUAD4,4,targetConn[10:14]) - m.insertNextCell(NORM_QUAD4,4,targetConn[14:18]) - m.finishInsertingCells(); - m.setCoords(c) - m.checkCoherency() - m1=MEDCouplingUMesh.New(); - m1.setMeshDimension(1); - m1.allocateCells(3); - m1.insertNextCell(NORM_SEG2,2,[1,4]) - m1.insertNextCell(NORM_SEG3,3,[2,8,5]) - m1.insertNextCell(NORM_SEG2,2,[3,6]) - m1.finishInsertingCells(); - m1.setCoords(c) - m1.checkCoherency() - m2=MEDCouplingUMesh.New(); - m2.setMeshDimension(0); - m2.allocateCells(4); - m2.insertNextCell(NORM_POINT1,1,[1]) - m2.insertNextCell(NORM_POINT1,1,[3]) - m2.insertNextCell(NORM_POINT1,1,[2]) - m2.insertNextCell(NORM_POINT1,1,[6]) - m2.finishInsertingCells(); - m2.setCoords(c) - m2.checkCoherency() - # - mm=MEDFileUMesh.New() - mm.setName("My2ndMEDCouplingMEDmesh") - mm.setDescription("ThisIsImpossibleToDoWithMEDMEM") - mm.setCoords(c) - renumNode=DataArrayInt.New() - renumNode.setValues([10,11,12,13,14,15,16,17,18],9,1) - mm.setRenumFieldArr(1,renumNode) - mm.setMeshAtLevel(-1,m1,True); - mm.setMeshAtLevel(0,m,True); - mm.setMeshAtLevel(-2,m2,True); - mm.removeMeshAtLevel(-2) - mm.setMeshAtLevel(-2,m2,True); - # playing with groups - g1_2=DataArrayInt.New() - g1_2.setValues([2,3],2,1) - g1_2.setName("G1") - g2_2=DataArrayInt.New() - g2_2.setValues([2,0,3],3,1) - g2_2.setName("G2") - mm.setGroupsAtLevel(0,[g1_2,g2_2],True) - g1_1=DataArrayInt.New() - g1_1.setValues([0,2,1],3,1) - g1_1.setName("G1") - g2_1=DataArrayInt.New() - g2_1.setValues([0,2],2,1) - g2_1.setName("G2") - mm.setGroupsAtLevel(-1,[g1_1,g2_1],True) - g1_N=DataArrayInt.New() - g1_N.setValues([10,11,12,13,14,15,16,17],8,1) - g1_N.setName("G1") - g2_N=DataArrayInt.New() - g2_N.setValues([10,11,12,13,14,15,16,17,18],9,1) - g2_N.setName("G2") - mm.setGroupsAtLevel(1,[g1_N,g2_N],True) - # check content of mm - t=mm.getGroupArr(0,"G1",True) - self.assertTrue(g1_2.isEqual(t)); - t=mm.getGroupArr(0,"G2",True) - self.assertTrue(g2_2.isEqual(t)); - t=mm.getGroupArr(-1,"G1",True) - self.assertTrue(g1_1.isEqual(t)); - t=mm.getGroupArr(-1,"G2",True) - self.assertTrue(g2_1.isEqual(t)); - self.assertTrue(not mm.existsGroup("GrpOnAllCell")); - # - mm.write(outFileName,2); - mm2=MEDFileMesh.New(outFileName) - res=mm.isEqual(mm2,1e-12) - self.assertTrue(res[0]) - l=list(mm2.getFamiliesOnGroup("G2")) ; l.sort() - self.assertEqual(['Family_-3','Family_-4','Family_-7','Family_10','Family_11'],l) - mm2.keepFamIdsOnlyOnLevs([3],[-1]) - for lev in mm.getGrpNonEmptyLevelsExt("G2"): - self.assertEqual(mm.getGroupArr(lev,"G2").getValues(),mm2.getGroupArr(lev,"G2").getValues()) - pass - l=list(mm2.getFamiliesOnGroup("G2")) ; l.sort() - self.assertEqual(['Family_-3','Family_-4','Family_-7','Family_10','Family_11'],l) - # - self.assertEqual([-7,-7,-6],mm2.getFamilyFieldAtLevel(-1).getValues()) - mm2.getFamilyFieldAtLevel(-1).setIJ(1,0,-8) - self.assertEqual([-7,-8,-6],mm2.getFamilyFieldAtLevel(-1).getValues()) - self.assertTrue(not mm2.existsFamily("Family_-8")) - mm2.createGroupOnAll(-1,"GrpOnAllFace") - self.assertTrue(mm2.existsFamily("Family_-8")) - self.assertEqual(range(3),mm2.getGroupArr(-1,"GrpOnAllFace").getValues()) - pass - - #testing persistence of retrieved arrays - def testMEDMesh5(self): - fileName="Pyfile18.med" - mname="ExampleOfMultiDimW" - medmesh=MEDFileUMesh.New(fileName,mname) - m1_0=medmesh.getLevel0Mesh(True) - da1=medmesh.getFamilyFieldAtLevel(0) - del medmesh - self.assertEqual(20,m1_0.getNumberOfCells()) - self.assertEqual(20,da1.getNumberOfTuples()) - pass - - def testMEDMesh6(self): - outFileName="MEDFileMesh5.med" - m=MEDFileCMesh.New() - m.setTime(-1,-1,2.3) - m1=MEDCouplingCMesh.New(); - da=DataArrayDouble.New() - da.setValues([0.,1.,2.],3,1) - da.setInfoOnComponent(0,"XX [mm]") - m1.setCoordsAt(0,da) - da=DataArrayDouble.New() - da.setValues([0.,1.2],2,1) - da.setInfoOnComponent(0,"YY [km]") - m1.setCoordsAt(1,da) - da=DataArrayDouble.New() - da.setValues([0.,1.3],2,1) - da.setInfoOnComponent(0,"ZZ [um]") - m1.setCoordsAt(2,da) - m.setMesh(m1) - self.assertTrue(m[0].isEqual(m1,1e-12)) - self.assertTrue(isinstance(m[0],MEDCouplingCMesh)) - m.setName("myFirstCartMesh") - m.setDescription("mmmmpppppppp") - m.setTimeValue(2.3) - m.setTimeUnit("ms") - da=DataArrayInt.New() - da.setValues([0,0,1,0,1,2,4,3,0,1,2,2],12,1) - m.setFamilyFieldArr(1,da) - m.setFamilyId("family1",1) - da=m.getFamilyArr(1,"family1") - expected1=[2,4,9] - self.assertEqual(expected1,da.getValues()) - self.assertTrue(m.getUnivNameWrStatus()) - m.write(outFileName,2); - mm=MEDFileMesh.New(outFileName) - self.assertEqual([NORM_HEXA8],mm.getGeoTypesAtLevel(0)) - self.assertTrue(isinstance(mm,MEDFileCMesh)) - self.assertTrue(isinstance(mm.getUnivName(),str)) - self.assertTrue(len(mm.getUnivName())!=0) - self.assertTrue(m.isEqual(mm,1e-12)[0]) - self.assertEqual(expected1,mm.getFamilyArr(1,"family1").getValues()) - m2=mm.getMesh() - tt=m.getTime() - m1.setTime(tt[2],tt[0],tt[1]) - m1.setName(m.getName()) - m1.setTimeUnit(m.getTimeUnit()) - m1.setDescription(m.getDescription()) - self.assertTrue(m2.isEqual(m1,1e-12)); - pass - - def testMEDMesh7(self): - fileName="Pyfile24.med" - m2,m1,m0,f2,f1,f0,p,n2,n1,n0,fns,fids,grpns,famIdsPerGrp=MEDLoaderDataForTest.buildMultiLevelMesh_1() - m=MEDFileUMesh.New() - m.setCoords(m2.getCoords()) - m.setMeshAtLevel(0,m2) - m.setMeshAtLevel(-1,m1) - m.setMeshAtLevel(-2,m0) - m.setFamilyFieldArr(0,f2) - m.setFamilyFieldArr(-1,f1) - m.setFamilyFieldArr(-2,f0) - m.setFamilyFieldArr(1,p) - m.setRenumFieldArr(0,n2) - m.setRenumFieldArr(-1,n1) - m.setRenumFieldArr(-2,n0) - nbOfFams=len(fns) - for i in xrange(nbOfFams): - m.addFamily(fns[i],fids[i]) - pass - nbOfGrps=len(grpns) - for i in xrange(nbOfGrps): - m.setFamiliesIdsOnGroup(grpns[i],famIdsPerGrp[i]) - pass - m.setName(m2.getName()) - m.setDescription(m2.getDescription()) - # - self.assertEqual((-1,),m.getGrpNonEmptyLevels("A2A4")) - self.assertEqual((),m.getGrpNonEmptyLevels("A1")) - self.assertEqual((-2,),m.getGrpNonEmptyLevels("AP2")) - self.assertEqual((-1,-2),m.getGrpsNonEmptyLevels(["A2A4","AP2"])) - self.assertEqual((-1,),m.getFamNonEmptyLevels('A4A3____________________________')) - self.assertEqual((0,),m.getFamNonEmptyLevels('MESH____DALT3___DALLE___________')) - self.assertEqual((0,-1,),m.getFamsNonEmptyLevels(['MESH____DALT3___DALLE___________','A4A3____________________________'])) - self.assertEqual(('A1A2','A2A4','A3A1','A3C5','A4A3','B1C1','B2B4','B3B1','B4C3','C1C4','C2B2','C3C2','C4B3','C5A4'),m.getGroupsOnSpecifiedLev(-1)) - self.assertEqual(('DALLE','DALQ1','DALQ2','DALT3','MESH'),m.getGroupsOnSpecifiedLev(0)) - # - m.write(fileName,2) - self.assertRaises(InterpKernelException,MEDFileField1TS,fileName)#throw because no field in file fileName - pass - - def funcToTestDelItem(self,ff): - del ff[[0.02,(3,4)]] - pass - - #emulation of pointe.med file. - def testMEDField1(self): - mm=MEDFileMesh.New("Pyfile17.med") - mm.write("Pyfile17_bis.med",2) - ff=MEDFileFieldMultiTS("Pyfile17.med") - tsExpected=[[1,2],[3,4],[5,6]] - self.assertEqual(3,len(ff)) - for pos,f1ts in enumerate(ff): - self.assertEqual(tsExpected[pos],f1ts.getTime()[:2]) - self.assertEqual(type(f1ts),MEDFileField1TS) - pass - self.assertEqual("MeasureOfMesh_Extruded",ff.getName()) - self.assertEqual([3,4],ff[1].getTime()[:-1]) - self.assertEqual([3,4],ff[3,4].getTime()[:-1]) - self.assertEqual([3,4],ff[0.01].getTime()[:-1]) - ff.write("Pyfile17_bis.med",0) - # - ts=ff.getTimeSteps() ; ts=[elt[:-1] for elt in ts] - self.assertEqual([(1,2),(3,4),(5,6)],ts) - self.funcToTestDelItem(ff) - ts=ff.getTimeSteps() ; ts=[elt[:-1] for elt in ts] - self.assertEqual([(1,2)],ts) - pass - - #profiles - def testMEDField2(self): - mm=MEDFileMesh.New("Pyfile19.med") - mm.write("Pyfile19_bis.med",2) - ff=MEDFileFieldMultiTS.New("Pyfile19.med") - ff.write("Pyfile19_bis.med",0) - self.assertEqual([('tyty','mm'),('uiop','MW')],MEDLoader.GetComponentsNamesOfField("Pyfile19_bis.med","VFieldOnNodes")) - pass - - #gauss points - def testMEDField3(self): - mm=MEDFileMesh.New("Pyfile13.med") - mm.write("Pyfile13_bis.med",2) - ff=MEDFileFieldMultiTS.New("Pyfile13.med","MyFirstFieldOnGaussPoint") - ff.write("Pyfile13_bis.med",0) - ff=MEDFileField1TS.New("Pyfile13.med","MyFirstFieldOnGaussPoint",1,5) - f=ff.getFieldAtLevel(ON_GAUSS_PT,0) - f2=MEDLoader.ReadFieldGauss("Pyfile13.med",'2DMesh_2',0,'MyFirstFieldOnGaussPoint',1,5) - self.assertTrue(f.isEqual(f2,1e-12,1e-12)) - ff3=MEDFileField1TS.New("Pyfile13.med","MyFirstFieldOnGaussPoint") - f3=ff3.getFieldAtLevel(ON_GAUSS_PT,0) - self.assertTrue(f.isEqual(f3,1e-12,1e-12)) - ff4=MEDFileField1TS.New("Pyfile13.med") - f4=ff4.getFieldAtLevel(ON_GAUSS_PT,0) - self.assertTrue(f.isEqual(f4,1e-12,1e-12)) - pass - - #gauss NE - def testMEDField4(self): - mm=MEDFileMesh.New("Pyfile14.med") - mm.write("Pyfile14_bis.med",2) - ff=MEDFileFieldMultiTS.New("Pyfile14.med","MyFieldOnGaussNE") - ff.write("Pyfile14_bis.med",0) - ff=MEDFileField1TS.New("Pyfile14.med","MyFieldOnGaussNE",1,5) - f=ff.getFieldAtLevel(ON_GAUSS_NE,0) - f2=MEDLoader.ReadFieldGaussNE("Pyfile14.med",'2DMesh_2',0,"MyFieldOnGaussNE",1,5) - self.assertTrue(f.isEqual(f2,1e-12,1e-12)) - pass - - # MEDField get/set on pointe.med - def testMEDField5(self): - ff=MEDFileField1TS.New("Pyfile17.med","MeasureOfMesh_Extruded",1,2) - f=ff.getFieldAtLevel(ON_CELLS,0) - f2=MEDLoader.ReadFieldCell("Pyfile17.med","Extruded",0,"MeasureOfMesh_Extruded",1,2) - self.assertTrue(f.getMesh().getCoords().isEqual(f2.getMesh().getCoords(),1e-12)) - f.getMesh().tryToShareSameCoords(f2.getMesh(),1e-12) - f.changeUnderlyingMesh(f2.getMesh(),22,1e-12) - self.assertTrue(f.isEqual(f2,1e-12,1e-12)) - # no with renumbering - f=ff.getFieldAtLevel(ON_CELLS,0,1) - f2=MEDLoader.ReadFieldCell("Pyfile17.med","Extruded",0,"MeasureOfMesh_Extruded",1,2) - self.assertTrue(f.isEqual(f2,1e-12,1e-12)) - f=ff.getFieldAtLevel(ON_CELLS,0,3) - self.assertTrue(f.isEqual(f2,1e-12,1e-12)) - f=ff.getFieldAtLevel(ON_CELLS,0,2) - self.assertTrue(not f.isEqual(f2,1e-12,1e-12)) - f.changeUnderlyingMesh(f2.getMesh(),12,1e-12) - self.assertTrue(f.isEqual(f2,1e-12,1e-12)) - pass - - # MEDField get/set on profiles nodes - def testMEDField6(self): - ff=MEDFileFieldMultiTS.New("Pyfile7.med","VectorFieldOnNodes") - its=ff.getIterations() - self.assertRaises(InterpKernelException,ff.getFieldAtLevel,ON_CELLS,its[0][0],its[0][1],0)# request on cell and it is not on cells - f=ff.getFieldAtLevel(ON_NODES,its[0][0],its[0][1],0) - f2=MEDLoader.ReadFieldNode("Pyfile7.med",'3DSurfMesh_1',0,"VectorFieldOnNodes",its[0][0],its[0][1]) - self.assertTrue(f.isEqual(f2,1e-12,1e-12)) - ff=MEDFileFieldMultiTS.New("Pyfile19.med","VFieldOnNodes") - its=ff.getIterations() - f=ff.getFieldAtLevel(ON_NODES,its[0][0],its[0][1],0) - f2=MEDLoader.ReadFieldNode("Pyfile19.med",'2DMesh_1',0,"VFieldOnNodes",its[0][0],its[0][1]) - self.assertTrue(f.isEqual(f2,1e-12,1e-12)) - self.assertRaises(InterpKernelException,ff.getFieldAtLevel,ON_CELLS,its[0][0],its[0][1],0)# request on cell and it is not on cells - self.assertRaises(InterpKernelException,ff.getFieldAtLevel,ON_NODES,its[0][0],its[0][1],0,1)#request renumber following mesh : it is on profile ! - pass - - # MEDField get/set on profiles cells - def testMEDField7(self): - ff=MEDFileFieldMultiTS.New("Pyfile12.med","VectorFieldOnCells") - its=ff.getIterations() - f=ff.getFieldAtLevel(ON_CELLS,its[0][0],its[0][1],0) - f2=MEDLoader.ReadFieldCell("Pyfile12.med",'3DMesh_1',0,"VectorFieldOnCells",its[0][0],its[0][1]) - self.assertTrue(f.isEqual(f2,1e-12,1e-12)) - pass - - #first test of assignation. No profile and types sorted by type. - def testMEDField8(self): - fname="Pyfile25.med" - f1=MEDLoaderDataForTest.buildVecFieldOnCells_1(); - m1=f1.getMesh() - mm1=MEDFileUMesh.New() - mm1.setCoords(m1.getCoords()) - mm1.setMeshAtLevel(0,m1) - mm1.setName(m1.getName()) - mm1.write(fname,2) - ff1=MEDFileField1TS.New() - ff1.setFieldNoProfileSBT(f1) - ff1.write(fname,0) - f2=MEDLoader.ReadFieldCell(fname,f1.getMesh().getName(),0,f1.getName(),f1.getTime()[1],f1.getTime()[2]); - itt,orr,ti=ff1.getTime() - self.assertEqual(0,itt); self.assertEqual(1,orr); self.assertAlmostEqual(2.,ti,14); - self.assertTrue(f1.isEqual(f2,1e-12,1e-12)) - ff1.setTime(3,4,2.3) - itt,orr,ti=ff1.getTime() - self.assertEqual(3,itt); self.assertEqual(4,orr); self.assertAlmostEqual(2.3,ti,14); - da,infos=ff1.getUndergroundDataArrayExt() - f2.getArray().setName(da.getName())#da has the same name than f2 - self.assertTrue(da.isEqual(f2.getArray(),1e-12)) - self.assertEqual([((3, 0), (0, 2)), ((4, 0), (2, 4)), ((6, 0), (4, 5)), ((5, 0), (5, 6))],infos) - # - fname="Pyfile26.med" - f1=MEDLoaderDataForTest.buildVecFieldOnNodes_1(); - m1=f1.getMesh() - mm1=MEDFileUMesh.New() - mm1.setCoords(m1.getCoords()) - mm1.setMeshAtLevel(0,m1) - mm1.setName(m1.getName()) - mm1.write(fname,2) - ff1=MEDFileField1TS.New() - ff1.setFieldNoProfileSBT(f1) - nv=1456. - da=ff1.getUndergroundDataArray().setIJ(0,0,nv) - ff1.write(fname,0) - f2=MEDLoader.ReadFieldNode(fname,f1.getMesh().getName(),0,f1.getName(),f1.getTime()[1],f1.getTime()[2]) - self.assertTrue(not f1.isEqual(f2,1e-12,1e-12)) - f1.getArray().setIJ(0,0,nv) - self.assertTrue(f1.isEqual(f2,1e-12,1e-12)) - # - fname="Pyfile27.med" - f1=MEDLoaderDataForTest.buildVecFieldOnGaussNE_1(); - m1=f1.getMesh() - mm1=MEDFileUMesh.New() - mm1.setCoords(m1.getCoords()) - mm1.setMeshAtLevel(0,m1) - mm1.setName(m1.getName()) - mm1.write(fname,2) - ff1=MEDFileField1TS.New() - ff1.setFieldNoProfileSBT(f1) - ff1.write(fname,0) - f2=MEDLoader.ReadFieldGaussNE(fname,f1.getMesh().getName(),0,f1.getName(),f1.getTime()[1],f1.getTime()[2]) - self.assertTrue(f1.isEqual(f2,1e-12,1e-12)) - da,infos=ff1.getUndergroundDataArrayExt() - f2.getArray().setName(da.getName())#da has the same name than f2 - self.assertTrue(da.isEqual(f2.getArray(),1e-12)) - self.assertEqual([((3, 0), (0, 6)), ((4, 0), (6, 14)), ((6, 0), (14, 20))],infos) - # - fname="Pyfile28.med" - f1=MEDLoaderDataForTest.buildVecFieldOnGauss_2_Simpler(); - f1InvalidCpy=f1.deepCpy() - f1InvalidCpy.setDiscretization(MEDCouplingFieldDiscretizationGauss()) - f1InvalidCpy2=f1.deepCpy() - f1InvalidCpy2.setDiscretization(MEDCouplingFieldDiscretizationGauss()) - m1=f1.getMesh() - mm1=MEDFileUMesh.New() - mm1.setCoords(m1.getCoords()) - mm1.setMeshAtLevel(0,m1) - mm1.setName(m1.getName()) - mm1.write(fname,2) - ff1=MEDFileField1TS.New() - self.assertRaises(InterpKernelException,ff1.setFieldNoProfileSBT,f1InvalidCpy) # fails because no Gauss localization per cell set !* - f1InvalidCpy2.getDiscretization().setArrayOfDiscIds(f1.getDiscretization().getArrayOfDiscIds()) # fails because no Gauss localization set whereas gauss locid per cell given ! - self.assertRaises(InterpKernelException,ff1.setFieldNoProfileSBT,f1InvalidCpy2) - ff1.setFieldNoProfileSBT(f1) - ff1.write(fname,0) - ff2=MEDFileField1TS.New(fname,f1.getName(),f1.getTime()[1],f1.getTime()[2]) - f2=ff2.getFieldAtLevel(ON_GAUSS_PT,0) - self.assertTrue(f1.isEqual(f2,1e-12,1e-12)) - sbt=ff2.getFieldSplitedByType2() - loc1=ff2.getLocalization("Loc_MyFirstFieldOnGaussPoint_NORM_TRI6_5") - self.assertEqual("Loc_MyFirstFieldOnGaussPoint_NORM_TRI6_5",loc1.getName()) - self.assertEqual((-1, 1,-1,-1,1,-1,-1,0,0,-1,0,0),loc1.getRefCoords()) - self.assertEqual(6,loc1.getNumberOfPointsInCells()) - self.assertEqual(3,loc1.getNumberOfGaussPoints()) - self.assertEqual(2,loc1.getDimension()) - da,infos=ff2.getUndergroundDataArrayExt() - f2.getArray().setName(da.getName())#da has the same name than f2 - self.assertTrue(da.isEqual(f2.getArray(),1e-12)) - self.assertEqual(53,da.getNumberOfTuples()) - self.assertEqual([((3, 0), (0, 18)), ((3, 1), (18, 30)), ((3, 2), (30, 36)), ((4, 0), (36, 42)), ((4, 1), (42, 44)), ((6, 0), (44, 53))],infos) - # - pass - - def testMEDFileData1(self): - fname="Pyfile29.med" - d=MEDFileData.New() - # - m1=MEDLoaderDataForTest.build1DMesh_1() - mm1=MEDFileUMesh.New() ; mm1.setCoords(m1.getCoords()) ; mm1.setMeshAtLevel(0,m1) ; mm1.setName(m1.getName()) - mmm1=MEDFileMeshMultiTS.New() ; - mmm1.setOneTimeStep(mm1) - m2=MEDLoaderDataForTest.build2DCurveMesh_1() - mm2=MEDFileUMesh.New() ; mm2.setCoords(m2.getCoords()) ; mm2.setMeshAtLevel(0,m2) ; mm2.setName(m2.getName()) - mmm2=MEDFileMeshMultiTS.New() ; mmm2.setOneTimeStep(mm2) - ms=MEDFileMeshes.New(); ms.setMeshAtPos(0,mm1) ; ms.setMeshAtPos(1,mm2) - d.setMeshes(ms) - for name,mmm in zip(["1DMesh_1","2DCurveMesh_1"],ms): - self.assertEqual(name,mmm.getName()) - self.assertEqual(type(mmm),MEDFileUMesh) - pass - self.assertEqual(('1DMesh_1', '2DCurveMesh_1'),d.getMeshes().getMeshesNames()) - # - ff1=MEDFileFieldMultiTS.New() - ff21=MEDFileFieldMultiTS.New() - ff22=MEDFileFieldMultiTS.New() - f1=m1.getMeasureField(True) ; f1.setName("f1") ; f1=f1.buildNewTimeReprFromThis(ONE_TIME,False) - f1.getArray().setInfoOnComponent(0,"power [kW]") - ff1.appendFieldNoProfileSBT(f1) - f21=m2.getMeasureField(True) ; f21.setName("f21") ; f21=f21.buildNewTimeReprFromThis(ONE_TIME,False) - f21.getArray().setInfoOnComponent(0,"sta [mm]") ; - ff21.appendFieldNoProfileSBT(f21) - f22=f21.deepCpy() ; f22.setName("f22") ; f22=f22.buildNewTimeReprFromThis(ONE_TIME,False) ; - f22.applyFunc(2,"3*x*IVec+2*x*JVec") - f22.getArray().setInfoOnComponent(0,"distance [km]") ; f22.getArray().setInfoOnComponent(1,"displacement [cm]") - ff22.appendFieldNoProfileSBT(f22) - fs=MEDFileFields.New() - fs.pushField(ff1) ; fs.pushField(ff21) ; fs.pushField(ff22) - for name,fmts in zip(["f1","f21","f22"],fs): - self.assertEqual(name,fmts.getName()) - pass - d.setFields(fs) - # - fname2="Pyfile29_2.med" - d.write(fname2,2) - # - d2=MEDFileData.New(fname2) - self.assertEqual(2,d2.getNumberOfMeshes()) - self.assertEqual(3,d2.getNumberOfFields()) - self.assertTrue(isinstance(d2.getMeshes().getMeshAtPos(0),MEDFileUMesh)) - self.assertTrue(isinstance(d2.getMeshes()[0],MEDFileUMesh)) - self.assertTrue(isinstance(d2.getMeshes()['2DCurveMesh_1'],MEDFileUMesh)) - m1bis=d2.getMeshes().getMeshAtPos(0).getMeshAtLevel(0) - self.assertTrue(m1.isEqual(m1bis,1e-12)) - self.assertEqual(('f1', 'f21', 'f22'),d2.getFields().getFieldsNames()) - self.assertEqual([(-1,-1,0.0)],d2.getFields().getFieldAtPos(2).getTimeSteps()) - self.assertEqual([(-1,-1,0.0)],d2.getFields()[2].getTimeSteps()) - self.assertEqual([(-1,-1,0.0)],d2.getFields().getFieldWithName("f21").getTimeSteps()) - self.assertEqual([(-1,-1,0.0)],d2.getFields()["f21"].getTimeSteps()) - pass - - def testMEDField9(self): - # first test field profile WR. Full type but with some type missing - fname="Pyfile30.med" - m1=MEDLoaderDataForTest.build2DMesh_3() - mm1=MEDFileUMesh.New() ; mm1.setCoords(m1.getCoords()) ; mm1.setMeshAtLevel(0,m1) ; - mm1.write(fname,2) - ff1=MEDFileField1TS.New() - f1=MEDCouplingFieldDouble.New(ON_CELLS,ONE_TIME) ; f1.setName("F1") - d=DataArrayDouble.New() ; d.alloc(2*9,1) ; d.iota(7.); d.rearrange(2); d.setInfoOnComponent(0,"sigX [MPa]") ; d.setInfoOnComponent(1,"sigY [GPa]") - f1.setArray(d) # note that f1 is NOT defined fully (no mesh !). It is not a bug of test it is too test that MEDFileField1TS.appendFieldProfile is NOT sensible of that. - da=DataArrayInt.New(); da.alloc(9,1) ; da.iota(0) ; da.setName("sup1") - # - ff1.setFieldProfile(f1,mm1,0,da) - ff1.changePflsNames([(["sup1_NORM_QUAD4"],"ForV650")]) - ff1=ff1.deepCpy() - ff1.write(fname,0) - # - vals,pfl=ff1.getFieldWithProfile(ON_CELLS,0,mm1) ; vals.setName("") - self.assertTrue(pfl.isEqualWithoutConsideringStr(da))# profiles names cannot be contracted in pfl array name - self.assertTrue(vals.isEqual(d,1e-14)) - # - ff2=MEDFileField1TS.New(fname,f1.getName(),-1,-1) - ff3=MEDFileField1TS.New(fname,f1.getName(),-1,-1) - ff2.deepCpyGlobs(ff3) - sbt=ff2.getFieldSplitedByType2() - self.assertEqual(3,sbt[0][0])#TRI3 - self.assertEqual(0,sbt[0][1][0][0])#CELL For TRI3 - self.assertEqual("",sbt[0][1][0][2])#no profile For TRI3 - self.assertEqual([7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18],sbt[0][1][0][1].getValues())# values for TRI3 - self.assertEqual(4,sbt[1][0])#QUAD4 - self.assertEqual(0,sbt[1][1][0][0])#CELL For QUAD4 - self.assertEqual("ForV650",sbt[1][1][0][2])# profile For QUAD4 - self.assertEqual([19, 20, 21, 22, 23, 24],sbt[1][1][0][1].getValues())# values for QUAD4 - self.assertEqual([0],ff2.getTypesOfFieldAvailable()) - vals,pfl=ff2.getFieldWithProfile(ON_CELLS,0,mm1) ; vals.setName("") - self.assertTrue(pfl.isEqualWithoutConsideringStr(da)) - self.assertTrue(vals.isEqual(d,1e-14)) - pass - - def testMEDField10(self): - fname="Pyfile31.med" - m1=MEDLoaderDataForTest.build2DMesh_1() - m1.renumberCells([0,1,4,2,3,5],False) - mm1=MEDFileUMesh.New() ; mm1.setCoords(m1.getCoords()) ; mm1.setMeshAtLevel(0,m1) ; mm1.setName(m1.getName()) - mm1.write(fname,2) - ff1=MEDFileFieldMultiTS.New() - f1=MEDCouplingFieldDouble.New(ON_CELLS,ONE_TIME) ; f1.setName("F2") - d=DataArrayDouble.New() ; d.alloc(2*4,1) ; d.iota(7.); d.rearrange(2); d.setInfoOnComponent(0,"sigX [MPa]") ; d.setInfoOnComponent(1,"sigY [GPa]") - f1.setArray(d) # note that f1 is NOT defined fully (no mesh !). It is not a bug of test it is too test that MEDFileField1TS.appendFieldProfile is NOT sensible of that. - da=DataArrayInt.New(); da.setValues([0,1,2,4],4,1) ; da.setName("sup2") - # - ff1.appendFieldProfile(f1,mm1,0,da) - f1.setTime(1.2,1,2) ; e=d.applyFunc("2*x") ; e.copyStringInfoFrom(d) ; f1.setArray(e) ; - ff1.appendFieldProfile(f1,mm1,0,da) - ff1=ff1.deepCpy() - ff1.write(fname,0) - # - vals,pfl=ff1.getFieldWithProfile(ON_CELLS,1,2,0,mm1) ; vals.setName("") - self.assertTrue(pfl.isEqualWithoutConsideringStr(da)) - self.assertTrue(vals.isEqual(e,1e-14)) - vals,pfl=ff1.getFieldWithProfile(ON_CELLS,-1,-1,0,mm1) ; vals.setName("") - self.assertTrue(pfl.isEqualWithoutConsideringStr(da)) - self.assertTrue(vals.isEqual(d,1e-14)) - # - ff2=MEDFileFieldMultiTS.New(fname,f1.getName()) - self.assertEqual([(-1,-1,0.0), (1,2,1.2)],ff2.getTimeSteps()) - vals,pfl=ff2.getFieldWithProfile(ON_CELLS,1,2,0,mm1) ; vals.setName("") - self.assertTrue(pfl.isEqualWithoutConsideringStr(da)) - self.assertTrue(vals.isEqual(e,1e-14)) - vals,pfl=ff2.getFieldWithProfile(ON_CELLS,-1,-1,0,mm1) ; vals.setName("") - self.assertTrue(pfl.isEqualWithoutConsideringStr(da)) - self.assertTrue(vals.isEqual(d,1e-14)) - pass - - # idem testMEDField9 method except that here testing profile on nodes and not on cells. - def testMEDField11(self): - fname="Pyfile32.med" - m1=MEDLoaderDataForTest.build2DMesh_1() - m1.renumberCells([0,1,4,2,3,5],False) - mm1=MEDFileUMesh.New() ; mm1.setCoords(m1.getCoords()) ; mm1.setMeshAtLevel(0,m1) ; - mm1.write(fname,2) - ff1=MEDFileField1TS.New() - f1=MEDCouplingFieldDouble.New(ON_NODES,ONE_TIME) ; f1.setName("F1Node") - d=DataArrayDouble.New() ; d.alloc(2*6,1) ; d.iota(7.); d.rearrange(2); d.setInfoOnComponent(0,"sigX [MPa]") ; d.setInfoOnComponent(1,"sigY [GPa]") - f1.setArray(d) # note that f1 is NOT defined fully (no mesh !). It is not a bug of test it is too test that MEDFileField1TS.appendFieldProfile is NOT sensible of that. - da=DataArrayInt.New(); da.setValues([1,2,4,5,7,8],6,1) ; da.setName("sup1Node") - # - ff1.setFieldProfile(f1,mm1,0,da) - self.assertEqual(ff1.getNonEmptyLevels(),(-1, [])) - ff1.write(fname,0) - # - vals,pfl=ff1.getFieldWithProfile(ON_NODES,0,mm1) ; vals.setName("") - self.assertTrue(pfl.isEqualWithoutConsideringStr(da)) - self.assertTrue(vals.isEqual(d,1e-14)) - ## # - ff2=MEDFileField1TS.New(fname,f1.getName(),-1,-1) - vals,pfl=ff2.getFieldWithProfile(ON_NODES,0,mm1) ; vals.setName("") - self.assertTrue(pfl.isEqualWithoutConsideringStr(da)) - self.assertTrue(vals.isEqual(d,1e-14)) - pass - - def testMEDField12(self): - fname="Pyfile33.med" - m1=MEDLoaderDataForTest.build2DMesh_1() - m1.renumberCells([0,1,4,2,3,5],False) - mm1=MEDFileUMesh.New() ; mm1.setCoords(m1.getCoords()) ; mm1.setMeshAtLevel(0,m1) ; - mm1.write(fname,2) - ff1=MEDFileFieldMultiTS.New() - f1=MEDCouplingFieldDouble.New(ON_NODES,ONE_TIME) ; f1.setName("F1Node") - d=DataArrayDouble.New() ; d.alloc(2*6,1) ; d.iota(7.); d.rearrange(2); d.setInfoOnComponent(0,"sigX [MPa]") ; d.setInfoOnComponent(1,"sigY [GPa]") - f1.setArray(d) # note that f1 is NOT defined fully (no mesh !). It is not a bug of test it is too test that MEDFileField1TS.appendFieldProfile is NOT sensible of that. - da=DataArrayInt.New(); da.setValues([1,2,4,5,7,8],6,1) ; da.setName("sup1Node") - # - ff1.appendFieldProfile(f1,mm1,0,da) - f1.setTime(1.2,1,2) ; e=d.applyFunc("2*x") ; e.copyStringInfoFrom(d) ; f1.setArray(e) ; - ff1.appendFieldProfile(f1,mm1,0,da) - ff1.write(fname,0) - # - vals,pfl=ff1.getFieldWithProfile(ON_NODES,1,2,0,mm1) ; vals.setName("") - self.assertTrue(pfl.isEqualWithoutConsideringStr(da)) - self.assertTrue(vals.isEqual(e,1e-14)) - vals,pfl=ff1.getFieldWithProfile(ON_NODES,-1,-1,0,mm1) ; vals.setName("") - self.assertTrue(pfl.isEqualWithoutConsideringStr(da)) - self.assertTrue(vals.isEqual(d,1e-14)) - # - ff2=MEDFileFieldMultiTS.New(fname,f1.getName()) - vals,pfl=ff2.getFieldWithProfile(ON_NODES,1,2,0,mm1) ; vals.setName("") - self.assertTrue(pfl.isEqualWithoutConsideringStr(da)) - self.assertTrue(vals.isEqual(e,1e-14)) - vals,pfl=ff2.getFieldWithProfile(ON_NODES,-1,-1,0,mm1) ; vals.setName("") - self.assertTrue(pfl.isEqualWithoutConsideringStr(da)) - self.assertTrue(vals.isEqual(d,1e-14)) - pass - - def testMEDField13(self): - fname="Pyfile34.med" - m1=MEDLoaderDataForTest.build2DMesh_1() - m1.renumberCells([0,1,4,2,3,5],False) - tmp=m1.getName(); - m1=m1.buildPartOfMySelf(range(5),True) ; m1.setName(tmp) # suppression of last cell that is a polygon - mm1=MEDFileUMesh.New() ; mm1.setCoords(m1.getCoords()) ; mm1.setMeshAtLevel(0,m1) ; - mm1.write(fname,2) - ff1=MEDFileField1TS.New() - f1=MEDCouplingFieldDouble.New(ON_GAUSS_NE,ONE_TIME) ; f1.setName("F3Node") - d=DataArrayDouble.New() ; d.alloc(2*11,1) ; d.iota(7.); d.rearrange(2); d.setInfoOnComponent(0,"sigX [MPa]") ; d.setInfoOnComponent(1,"sigY [GPa]") - f1.setArray(d) # note that f1 is NOT defined fully (no mesh !). It is not a bug of test it is too test that MEDFileField1TS.appendFieldProfile is NOT sensible of that. - da=DataArrayInt.New(); da.setValues([0,2,3],3,1) ; da.setName("sup1NodeElt") - # - ff1.setFieldProfile(f1,mm1,0,da) - ff1.write(fname,0) - # - vals,pfl=ff1.getFieldWithProfile(ON_GAUSS_NE,0,mm1) ; vals.setName("") - self.assertTrue(pfl.isEqualWithoutConsideringStr(da)) - self.assertTrue(vals.isEqual(d,1e-14)) - # - ff2=MEDFileField1TS.New(fname,f1.getName(),-1,-1) - vals,pfl=ff2.getFieldWithProfile(ON_GAUSS_NE,0,mm1) ; vals.setName("") - self.assertTrue(pfl.isEqualWithoutConsideringStr(da)) - self.assertTrue(vals.isEqual(d,1e-14)) - pass - - def testMEDField14(self): - fname="Pyfile35.med" - m1=MEDLoaderDataForTest.build2DMesh_1() - m1.renumberCells([0,1,4,2,3,5],False) - tmp=m1.getName(); - m1=m1.buildPartOfMySelf(range(5),True) ; m1.setName(tmp) # suppression of last cell that is a polygon - mm1=MEDFileUMesh.New() ; mm1.setCoords(m1.getCoords()) ; mm1.setMeshAtLevel(0,m1) ; - mm1.write(fname,2) - ff1=MEDFileFieldMultiTS.New() - f1=MEDCouplingFieldDouble.New(ON_GAUSS_NE,ONE_TIME) ; f1.setName("F4Node") - d=DataArrayDouble.New() ; d.alloc(2*11,1) ; d.iota(7.); d.rearrange(2); d.setInfoOnComponent(0,"sigX [MPa]") ; d.setInfoOnComponent(1,"sigY [GPa]") - f1.setArray(d) # note that f1 is NOT defined fully (no mesh !). It is not a bug of test it is too test that MEDFileField1TS.appendFieldProfile is NOT sensible of that. - da=DataArrayInt.New(); da.setValues([0,2,3],3,1) ; da.setName("sup1NodeElt") - # - ff1.appendFieldProfile(f1,mm1,0,da) - f1.setTime(1.2,1,2) ; e=d.applyFunc("2*x") ; e.copyStringInfoFrom(d) ; f1.setArray(e) ; - ff1.appendFieldProfile(f1,mm1,0,da) - ff1.write(fname,0) - # - vals,pfl=ff1.getFieldWithProfile(ON_GAUSS_NE,-1,-1,0,mm1) ; vals.setName("") - self.assertTrue(pfl.isEqualWithoutConsideringStr(da)) - self.assertTrue(vals.isEqual(d,1e-14)) - vals,pfl=ff1.getFieldWithProfile(ON_GAUSS_NE,1,2,0,mm1) ; vals.setName("") - self.assertTrue(pfl.isEqualWithoutConsideringStr(da)) - self.assertTrue(vals.isEqual(e,1e-14)) - self.assertEqual([[3],[3]],ff1.getTypesOfFieldAvailable()) - # - ff2=MEDFileFieldMultiTS.New(fname,f1.getName()) - vals,pfl=ff1.getFieldWithProfile(ON_GAUSS_NE,-1,-1,0,mm1) ; vals.setName("") - self.assertTrue(pfl.isEqualWithoutConsideringStr(da)) - self.assertTrue(vals.isEqual(d,1e-14)) - vals,pfl=ff1.getFieldWithProfile(ON_GAUSS_NE,1,2,0,mm1) ; vals.setName("") - self.assertTrue(pfl.isEqualWithoutConsideringStr(da)) - self.assertTrue(vals.isEqual(e,1e-14)) - pass - # Tricky test of the case of in a MED file containing a Field on GAUSS_NE is lying on a profile that is reality represents all the geom entities of a level. - # By default when using setFieldProfile method such profile is not created because it is not useful ! So here a trick is used to force MEDLoader to do that - # for the necessity of the test ! The idea is too create artificially a mesh having one more fictious cell per type and to roll back right after ! - def testMEDField15(self): - fname="Pyfile36.med" - m0=MEDLoaderDataForTest.build2DMesh_1() - m0.renumberCells([0,1,4,2,3,5],False) - tmp=m0.getName(); - m1=m0.buildPartOfMySelf([0,1,1,2,3,3,4,4],True) ; m1.setName(tmp) # suppression of last cell that is a polygon and creation of one more cell per type - mm1=MEDFileUMesh.New() ; mm1.setCoords(m1.getCoords()) ; mm1.setMeshAtLevel(0,m1) ; - ff1=MEDFileField1TS.New() - f1=MEDCouplingFieldDouble.New(ON_GAUSS_NE,ONE_TIME) ; f1.setName("F4Node") - d=DataArrayDouble.New() ; d.alloc(2*20,1) ; d.iota(7.); d.rearrange(2); d.setInfoOnComponent(0,"sigX [MPa]") ; d.setInfoOnComponent(1,"sigY [GPa]") - f1.setArray(d) # note that f1 is NOT defined fully (no mesh !). It is not a bug of test it is too test that MEDFileField1TS.appendFieldProfile is NOT sensible of that. - da=DataArrayInt.New(); da.setValues([0,1,3,4,6],5,1) ; da.setName("sup1NodeElt") - # - ff1.setFieldProfile(f1,mm1,0,da) - m1=m0.buildPartOfMySelf(range(5),True) ; m1.setName(tmp) ; mm1.setMeshAtLevel(0,m1) ; - mm1.write(fname,2) - ff1.write(fname,0) - f1=ff1.getFieldOnMeshAtLevel(ON_GAUSS_NE,m1,0) - f2,p1=ff1.getFieldWithProfile(ON_GAUSS_NE,0,mm1) ; f2.setName("") - self.assertTrue(p1.isIdentity()) - self.assertEqual(5,p1.getNumberOfTuples()) - self.assertTrue(f1.getArray().isEqual(f2,1e-12)) - pass - # Test for getFieldAtTopLevel method - def testMEDField16(self): - fname="Pyfile37.med" - f1=MEDLoaderDataForTest.buildVecFieldOnCells_1(); - m1=f1.getMesh() - mm1=MEDFileUMesh.New() - mm1.setCoords(m1.getCoords()) - mm1.setMeshAtLevel(0,m1) - mm1.setName(m1.getName()) - ff1=MEDFileField1TS.New() - ff1.setFieldNoProfileSBT(f1) - m2=m1.buildDescendingConnectivity()[0] - m2.sortCellsInMEDFileFrmt() - m2.setName(m1.getName()) - mm1.setMeshAtLevel(-1,m2) - mm1.write(fname,2) - f2=m2.getMeasureField(True) - dd=DataArrayDouble.New() - dd.alloc(f2.getArray().getNumberOfTuples(),3) - dd[:,0]=f2.getArray() - dd[:,1]=2*f2.getArray() - dd[:,2]=3*f2.getArray() - f2=f2.buildNewTimeReprFromThis(ONE_TIME,False) - f2.setArray(dd) - f2.copyTinyStringsFrom(f1) - f2.copyTinyAttrFrom(f1) - ff1.setFieldNoProfileSBT(f2) - ff1.write(fname,0) - # Reading Pyfile37.med - ff2=MEDFileField1TS.New(fname,f2.getName(),0,1) - f1bis=ff2.getFieldAtLevel(ON_CELLS,0) - self.assertTrue(f1.isEqual(f1bis,1e-12,1e-12)) - f1bis=ff2.getFieldAtLevel(ON_CELLS,-1) - self.assertTrue(f2.isEqual(f1bis,1e-12,1e-12)) - f1bis=ff2.getFieldAtTopLevel(ON_CELLS) - self.assertTrue(f1.isEqual(f1bis,1e-12,1e-12)) - # More complex - fname="Pyfile38.med" - mm1.write(fname,2) - ff1=MEDFileField1TS.New() - ff1.setFieldNoProfileSBT(f2) - ff1.write(fname,0) - ff2=MEDFileField1TS.New(fname,f2.getName(),0,1) - f1bis=ff2.getFieldAtTopLevel(ON_CELLS) - self.assertTrue(f2.isEqual(f1bis,1e-12,1e-12)) - pass - - # Non regression test to check that globals are correctly appended on MEDFileFields::setFieldAtPos - def testMEDField17(self): - fname="Pyfile39.med" - m1=MEDLoaderDataForTest.build2DMesh_1() - m1.renumberCells([0,1,4,2,3,5],False) - mm1=MEDFileUMesh.New() ; mm1.setCoords(m1.getCoords()) ; mm1.setMeshAtLevel(0,m1) ; mm1.setName(m1.getName()) - mm1.write(fname,2) - ffs=MEDFileFields.New() - ff1=MEDFileFieldMultiTS.New() - f1=MEDCouplingFieldDouble.New(ON_CELLS,ONE_TIME) ; f1.setName("F2") - d=DataArrayDouble.New() ; d.alloc(2*4,1) ; d.iota(7.); d.rearrange(2); d.setInfoOnComponent(0,"sigX [MPa]") ; d.setInfoOnComponent(1,"sigY [GPa]") - f1.setArray(d) # note that f1 is NOT defined fully (no mesh !). It is not a bug of test it is too test that MEDFileField1TS.appendFieldProfile is NOT sensible of that. - da=DataArrayInt.New(); da.setValues([0,1,2,4],4,1) ; da.setName("sup2") - # - ff1.appendFieldProfile(f1,mm1,0,da) - f1.setTime(1.2,1,2) ; e=d.applyFunc("2*x") ; e.copyStringInfoFrom(d) ; f1.setArray(e) ; - ff1.appendFieldProfile(f1,mm1,0,da) - ffs.resize(1) - ffs.setFieldAtPos(0,ff1) - ffs=ffs.deepCpy() - ffs.write(fname,0) - # - ffsr=MEDFileFields.New(fname) - ff3=ffsr.getFieldAtPos(0) - f4=ff3.getFieldAtTopLevel(ON_CELLS,1,2) - self.assertTrue(f4.getArray().isEqual(f1.getArray(),1e-12)) - pass - - # Non regression test to check that globals are correctly appended on MEDFileFields::setFieldAtPos - def testMEDField18(self): - fname="Pyfile40.med" - m1=MEDLoaderDataForTest.build2DMesh_1() - m1.renumberCells([0,1,4,2,3,5],False) - mm1=MEDFileUMesh.New() ; mm1.setCoords(m1.getCoords()) ; mm1.setMeshAtLevel(0,m1) ; mm1.setName(m1.getName()) - mm1.write(fname,2) - ffs=MEDFileFields.New() - ff1=MEDFileFieldMultiTS.New() - f1=MEDCouplingFieldDouble.New(ON_CELLS,ONE_TIME) ; f1.setName("F2") - d=DataArrayDouble.New() ; d.alloc(2*4,1) ; d.iota(7.); d.rearrange(2); d.setInfoOnComponent(0,"sigX [MPa]") ; d.setInfoOnComponent(1,"sigY [GPa]") - f1.setArray(d) # note that f1 is NOT defined fully (no mesh !). It is not a bug of test it is too test that MEDFileField1TS.appendFieldProfile is NOT sensible of that. - da=DataArrayInt.New(); da.setValues([0,1,2,4],4,1) ; da.setName("sup2") - # - ff1.appendFieldProfile(f1,mm1,0,da) - f1.setTime(1.2,1,2) ; e=d.applyFunc("2*x") ; e.copyStringInfoFrom(d) ; f1.setArray(e) ; - ff1.appendFieldProfile(f1,mm1,0,da) - ffs.pushField(ff1) - ffs.write(fname,0) - # - ffsr=MEDFileFields.New(fname) - ff3=ffsr.getFieldAtPos(0) - f4=ff3.getFieldAtTopLevel(ON_CELLS,1,2) - self.assertTrue(f4.getArray().isEqual(f1.getArray(),1e-12)) - pass - - def testMEDFieldBug1(self): - fname="Pyfile13.med" - d=MEDFileData.New(fname) - self.assertEqual(('Loc_MyFirstFieldOnGaussPoint_NORM_QUAD4_1','Loc_MyFirstFieldOnGaussPoint_NORM_TRI3_0','Loc_MyFirstFieldOnGaussPoint_NORM_TRI6_2'),d.getFields().getFieldAtPos(0).getLocs()) - pass - - def testMEDMesh8(self): - m=MEDLoaderDataForTest.build1DMesh_1() - m.convertQuadraticCellsToLinear() - mm=MEDFileUMesh.New() - mm.setMeshAtLevel(0,m) - g1=DataArrayInt.New() ; g1.setValues([0,2],2,1) ; g1.setName("g1") - g2=DataArrayInt.New() ; g2.setValues([1,3],2,1) ; g2.setName("g2") - g3=DataArrayInt.New() ; g3.setValues([1,2,3],3,1) ; g3.setName("g3") - mm.setGroupsAtLevel(0,[g1,g2],False) - self.assertEqual(('g1','g2'),mm.getGroupsNames()) - self.assertEqual(('Family_-2','Family_-3'),mm.getFamiliesNames()) - self.assertEqual(('Family_-2',),mm.getFamiliesOnGroup('g1')) - self.assertEqual(('Family_-3',),mm.getFamiliesOnGroup('g2')) - mm.assignFamilyNameWithGroupName() - self.assertEqual(('g1','g2'),mm.getGroupsNames()) - self.assertEqual(('g1','g2'),mm.getFamiliesNames()) - self.assertEqual(('g1',),mm.getFamiliesOnGroup('g1')) - self.assertEqual(('g2',),mm.getFamiliesOnGroup('g2')) - # - mm=MEDFileUMesh.New() - mm.setMeshAtLevel(0,m) - mm.setGroupsAtLevel(0,[g1,g2,g3],False) - self.assertEqual(('g1','g2','g3'),mm.getGroupsNames()) - self.assertEqual(('Family_-2', 'Family_-4', 'Family_-5'),mm.getFamiliesNames()) - self.assertEqual(('Family_-2', 'Family_-4'),mm.getFamiliesOnGroup('g1')) - self.assertEqual(('Family_-5',),mm.getFamiliesOnGroup('g2')) - self.assertEqual(('Family_-4','Family_-5',),mm.getFamiliesOnGroup('g3')) - mm.assignFamilyNameWithGroupName() # here it does nothing because no such group-family bijection found - self.assertEqual(('g1','g2','g3'),mm.getGroupsNames()) - self.assertEqual(('Family_-2', 'Family_-4', 'Family_-5'),mm.getFamiliesNames()) - self.assertEqual(('Family_-2', 'Family_-4'),mm.getFamiliesOnGroup('g1')) - self.assertEqual(('Family_-5',),mm.getFamiliesOnGroup('g2')) - self.assertEqual(('Family_-4','Family_-5',),mm.getFamiliesOnGroup('g3')) - mm.changeFamilyId(5,6) - g=mm.getGroupArr(0,"g3") - self.assertTrue(g.isEqual(g3)); - g=mm.getGroupArr(0,"g2") - self.assertTrue(g.isEqual(g2)); - g=mm.getGroupArr(0,"g1") - self.assertTrue(g.isEqual(g1)); - pass - - # bug detected by gauthier - def testMEDLoaderMEDLoaderNSReadFieldDoubleDataInMedFile(self): - fname="Pyfile41.med" - f1=MEDLoaderDataForTest.buildVecFieldOnCells_1(); - m1=f1.getMesh() - mm1=MEDFileUMesh.New() - mm1.setCoords(m1.getCoords()) - mm1.setMeshAtLevel(0,m1) - mm1.write(fname,2) - ff1=MEDFileField1TS.New() - ff1.setFieldNoProfileSBT(f1) - ff1.write(fname,0) - # writing mesh1 and field1, now creation of mesh2 and field2 - f2=f1.deepCpy() - m2=f2.getMesh() - m2.translate([0.5,0.6,0.7]) - m2.setName("3DSurfMesh_2") - f2.getArray()[:]*=2. - f2.setName("VectorFieldOnCells2") - mm2=MEDFileUMesh.New() - mm2.setCoords(m2.getCoords()) - mm2.setMeshAtLevel(0,m2) - mm2.write(fname,0) - ff2=MEDFileField1TS.New() - ff2.setFieldNoProfileSBT(f2) - ff2.write(fname,0) - # - f3=MEDLoader.ReadFieldCell(fname,"3DSurfMesh_1",0,"VectorFieldOnCells",0,1) - self.assertTrue(f3.isEqual(f1,1e-12,1e-12)) - f4=MEDLoader.ReadFieldCell(fname,"3DSurfMesh_2",0,"VectorFieldOnCells2",0,1) - self.assertTrue(f4.isEqual(f2,1e-12,1e-12)) - pass - - def testMEDLoaderMultiLevelCellField1(self): - fname="Pyfile42.med" - m2,m1,m0,f2,f1,f0,p,n2,n1,n0,fns,fids,grpns,famIdsPerGrp=MEDLoaderDataForTest.buildMultiLevelMesh_1() - m=MEDFileUMesh.New() - m.setCoords(m2.getCoords()) - m.setMeshAtLevel(0,m2) - m.setMeshAtLevel(-1,m1) - m.setMeshAtLevel(-2,m0) - m.write(fname,2) - # - FieldName1="Field1" - compNames1=["comp1","comp2","comp3"] - ff1=MEDFileField1TS.New() - da2=DataArrayDouble.New() - da2.alloc(m2.getNumberOfCells()*len(compNames1),1) - da2.iota(7.) - da2.rearrange(len(compNames1)) - da2.setInfoOnComponents(compNames1) - f2=MEDCouplingFieldDouble.New(ON_CELLS,ONE_TIME) ; f2.setName(FieldName1) ; f2.setArray(da2) ; f2.setMesh(m2) ; f2.checkCoherency() - ff1.setFieldNoProfileSBT(f2) - self.assertEqual(ff1.getNonEmptyLevels(),(2, [0])) - da0=DataArrayDouble.New() - da0.alloc(m0.getNumberOfCells()*len(compNames1),1) - da0.iota(190.) - da0.rearrange(len(compNames1)) - da0.setInfoOnComponents(compNames1) - f0=MEDCouplingFieldDouble.New(ON_CELLS,ONE_TIME) ; f0.setName(FieldName1) ; f0.setArray(da0) ; f0.setMesh(m0) ; f0.checkCoherency() - ff1.setFieldNoProfileSBT(f0) - self.assertEqual(ff1.getNonEmptyLevels(),(2, [0,-2])) - da1=DataArrayDouble.New() - da1.alloc(m1.getNumberOfCells()*len(compNames1),1) - da1.iota(90.) - da1.rearrange(len(compNames1)) - da1.setInfoOnComponents(compNames1) - f1=MEDCouplingFieldDouble.New(ON_CELLS,ONE_TIME) ; f1.setName(FieldName1) ; f1.setArray(da1) ; f1.setMesh(m1) ; f1.checkCoherency() - ff1.setFieldNoProfileSBT(f1) - self.assertEqual(ff1.getNonEmptyLevels(),(2, [0,-1,-2])) - # - ff1.write(fname,0) - # - FieldName2="Field2" - compNames2=["comp11","comp22"] - ff2=MEDFileField1TS.New() - da0=DataArrayDouble.New() - da0.alloc(m0.getNumberOfCells()*2,1) - da0.iota(-190.) - da0.rearrange(2) - da0.setInfoOnComponents(compNames2) - f0=MEDCouplingFieldDouble.New(ON_CELLS,ONE_TIME) ; f0.setName(FieldName2) ; f0.setArray(da0) ; f0.setMesh(m0) ; f0.checkCoherency() - ff2.setFieldNoProfileSBT(f0) - self.assertEqual(ff2.getNonEmptyLevels(),(0, [0])) - da1=DataArrayDouble.New() - da1.alloc(m1.getNumberOfCells()*len(compNames2),1) - da1.iota(-90.) - da1.rearrange(len(compNames2)) - da1.setInfoOnComponents(compNames2) - f1=MEDCouplingFieldDouble.New(ON_CELLS,ONE_TIME) ; f1.setName(FieldName2) ; f1.setArray(da1) ; f1.setMesh(m1) ; f1.checkCoherency() - ff2.setFieldNoProfileSBT(f1) - self.assertEqual(ff2.getNonEmptyLevels(),(1, [0,-1])) - # - ff2.write(fname,0) - # - ff1=MEDFileField1TS.New(fname,FieldName1,-1,-1) - self.assertEqual(ff1.getNonEmptyLevels(),(2, [0,-1,-2])) - self.assertEqual(ff1.getFieldSplitedByType(),[(0, [(0, (0, 4), '', '')]), (1, [(0, (4, 84), '', '')]), (3, [(0, (84, 148), '', '')]), (4, [(0, (148, 212), '', '')])]) - ff2=MEDFileField1TS.New(fname,FieldName2,-1,-1) - self.assertEqual(ff2.getNonEmptyLevels(),(1, [0,-1])) - self.assertEqual(ff2.getFieldSplitedByType(),[(0, [(0, (0, 4), '', '')]), (1, [(0, (4, 84), '', '')])]) - pass - - def testFieldOnPflRetrieveOnMdimRelMax1(self): - fname="Pyfile43.med" - m2,m1,m0,f2,f1,f0,p,n2,n1,n0,fns,fids,grpns,famIdsPerGrp=MEDLoaderDataForTest.buildMultiLevelMesh_1() - m=MEDFileUMesh.New() - m.setMeshAtLevel(0,m2) - m.setMeshAtLevel(-1,m1) - m.setMeshAtLevel(-2,m0) - f=MEDFileField1TS.New() - ff=MEDCouplingFieldDouble.New(ON_NODES,ONE_TIME) - ff.setName("NodeFieldPfl") - arr=DataArrayDouble.New() ; arr.setValues([1.,10.,100.,2.,20.,200.],2,3) - ff.setArray(arr) - pfl=DataArrayInt.New() ; pfl.setValues([2,3],2,1) ; pfl.setName("PflNode") - f.setFieldProfile(ff,m,-2,pfl) - tes0=f.getFieldOnMeshAtLevel(ON_NODES,-1,m) - self.assertEqual(ON_NODES,tes0.getTypeOfField()) - self.assertEqual(1,tes0.getMesh().getMeshDimension()) - self.assertEqual(1,tes0.getMesh().getNumberOfCells()) - self.assertEqual(2,tes0.getMesh().getNumberOfNodes()) - self.assertEqual([1,0,1],tes0.getMesh().getNodalConnectivity().getValues()) - self.assertEqual([0,3],tes0.getMesh().getNodalConnectivityIndex().getValues()) - self.assertEqual(2,tes0.getArray().getNumberOfTuples()) - self.assertEqual(3,tes0.getArray().getNumberOfComponents()) - expected1=[1.,10.,100.,2.,20.,200.] - nodeCoordsWithValue1=[10.,2.5,0.] - nodeCoordsWithValue2=[10.,3.75,0.] - for i in xrange(3): - self.assertAlmostEqual(nodeCoordsWithValue1[i],tes0.getMesh().getCoordinatesOfNode(0)[i],13); - self.assertAlmostEqual(nodeCoordsWithValue2[i],tes0.getMesh().getCoordinatesOfNode(1)[i],13); - pass - for i in xrange(6): - self.assertAlmostEqual(expected1[i],tes0.getArray().getIJ(0,i),13); - pass - del tes0 - # - tes1=f.getFieldOnMeshAtLevel(ON_NODES,1,m) - self.assertEqual(ON_CELLS,tes1.getTypeOfField())# it is not a bug even if ON_NODES has been sepecified - self.assertEqual(0,tes1.getMesh().getMeshDimension()) - self.assertEqual(2,tes1.getMesh().getNumberOfCells()) - self.assertEqual(135,tes1.getMesh().getNumberOfNodes()) - self.assertEqual([0,2,0,3],tes1.getMesh().getNodalConnectivity().getValues()) - self.assertEqual([0,2,4],tes1.getMesh().getNodalConnectivityIndex().getValues()) - self.assertEqual(2,tes1.getArray().getNumberOfTuples()) - self.assertEqual(3,tes1.getArray().getNumberOfComponents()) - for i in xrange(6): - self.assertAlmostEqual(expected1[i],tes1.getArray().getIJ(0,i),13); - pass - m.write(fname,2) - f.write(fname,0) - # - pfl=DataArrayInt.New() ; pfl.setValues([3,2],2,1) ; pfl.setName("PflNode") - f=MEDFileField1TS.New() - f.setFieldProfile(ff,m,-2,pfl) - tes2=f.getFieldOnMeshAtLevel(ON_NODES,-1,m) - self.assertEqual(ON_NODES,tes2.getTypeOfField()) - self.assertEqual(1,tes2.getMesh().getMeshDimension()) - self.assertEqual(1,tes2.getMesh().getNumberOfCells()) - self.assertEqual(2,tes2.getMesh().getNumberOfNodes()) - self.assertEqual([1,0,1],tes2.getMesh().getNodalConnectivity().getValues()) - self.assertEqual([0,3],tes2.getMesh().getNodalConnectivityIndex().getValues()) - self.assertEqual(2,tes2.getArray().getNumberOfTuples()) - self.assertEqual(3,tes2.getArray().getNumberOfComponents()) - expected2=[2.,20.,200.,1.,10.,100.] - for i in xrange(3): - self.assertAlmostEqual(nodeCoordsWithValue1[i],tes2.getMesh().getCoordinatesOfNode(0)[i],13); - self.assertAlmostEqual(nodeCoordsWithValue2[i],tes2.getMesh().getCoordinatesOfNode(1)[i],13); - pass - for i in xrange(6): - self.assertAlmostEqual(expected2[i],tes2.getArray().getIJ(0,i),13);#compare tes2 and tes3 - pass - # - tes3=f.getFieldOnMeshAtLevel(ON_NODES,1,m) - self.assertEqual(ON_CELLS,tes3.getTypeOfField())# it is not a bug even if ON_NODES has been sepecified - self.assertEqual(0,tes3.getMesh().getMeshDimension()) - self.assertEqual(2,tes3.getMesh().getNumberOfCells()) - self.assertEqual(135,tes3.getMesh().getNumberOfNodes()) - self.assertEqual([0,3,0,2],tes3.getMesh().getNodalConnectivity().getValues()) - self.assertEqual([0,2,4],tes3.getMesh().getNodalConnectivityIndex().getValues()) - self.assertEqual(2,tes3.getArray().getNumberOfTuples()) - self.assertEqual(3,tes3.getArray().getNumberOfComponents()) - for i in xrange(6): - self.assertAlmostEqual(expected1[i],tes3.getArray().getIJ(0,i),13); - pass - pass - - def testBuildInnerBoundaryAlongM1Group1(self): - fname="Pyfile44.med" - m=MEDCouplingCMesh.New() - m.setCoordsAt(0,DataArrayDouble.New([0.,1.1,2.3,3.6,5.,6.5])) - m.setCoordsAt(1,DataArrayDouble.New([0.,1.1,2.3,3.6,5.])) - m=m.buildUnstructured() ; m.setName("AnthonyDuplicate") - m.getCoords().setInfoOnComponents(["X [km]","Z [mm]"]) - m2=m.buildDescendingConnectivity()[0][[8,11,14,20,21,22,23,24,25,26,31,32,33,34,35,36,37]] - m2.setName(m.getName()) - grp=DataArrayInt.New([4,6,8]) ; grp.setName("Grp") - grp2=DataArrayInt.New([9,16]) ; grp2.setName("Grp2") - mm=MEDFileUMesh.New() - mm.setMeshAtLevel(0,m) - mm.setMeshAtLevel(-1,m2) - mm.setGroupsAtLevel(-1,[grp,grp2]) - grpNode=DataArrayInt.New([4,21,23]) ; grpNode.setName("GrpNode") - mm.setGroupsAtLevel(1,[grpNode]) - ref0=[4,15,14,20,21,4,16,15,21,22,4,17,16,22,23] - ref1=[4,9,8,14,15,4,10,9,15,16,4,11,10,16,17] - ref2=[4,9,8,14,30,4,10,9,30,31,4,11,10,31,32] - # - self.assertEqual(30,mm.getNumberOfNodes()) - self.assertEqual(ref0,mm.getMeshAtLevel(0)[[12,13,14]].getNodalConnectivity().getValues()) - self.assertEqual(ref1,mm.getMeshAtLevel(0)[[7,8,9]].getNodalConnectivity().getValues()) - # - nodes,cells,cells2=mm.buildInnerBoundaryAlongM1Group("Grp") - self.assertEqual([15,16,17],nodes.getValues()); - self.assertEqual([7,8,9],cells.getValues()); - self.assertEqual([12,13,14],cells2.getValues()); - self.assertEqual(33,mm.getNumberOfNodes()) - self.assertEqual([4,6,8],mm.getGroupArr(-1,"Grp").getValues()) - self.assertEqual([9,16],mm.getGroupArr(-1,"Grp2").getValues()) - self.assertEqual([4,21,23],mm.getGroupArr(1,"GrpNode").getValues()) - self.assertEqual([17,18,19],mm.getGroupArr(-1,"Grp_dup").getValues()) - self.assertEqual(ref0,mm.getMeshAtLevel(0)[[12,13,14]].getNodalConnectivity().getValues())#cells 7,8,9 and 12,13,14 are lying on "Grp" but only 7,8 and 9 are renumbered - self.assertEqual(ref2,mm.getMeshAtLevel(0)[[7,8,9]].getNodalConnectivity().getValues())# - self.assertRaises(InterpKernelException,mm.getGroup(-1,"Grp_dup").checkGeoEquivalWith,mm.getGroup(-1,"Grp"),2,1e-12);# Grp_dup and Grp are not equal considering connectivity only - mm.getGroup(-1,"Grp_dup").checkGeoEquivalWith(mm.getGroup(-1,"Grp"),12,1e-12)# Grp_dup and Grp are equal considering connectivity and coordinates - refValues=DataArrayDouble.New([1.21,1.32,1.43,1.54,1.65,1.32,1.44,1.56,1.68,1.8,1.43,1.56,1.69,1.82,1.95,1.54,1.68,1.82,1.96,2.1]) - valsToTest=mm.getMeshAtLevel(0).getMeasureField(True).getArray() ; delta=(valsToTest-refValues) ; delta.abs() - self.assertTrue(delta.getMaxValue()[0]<1e-12) - # - mm.getCoords()[-len(nodes):]+=[0.,-0.3] - self.assertRaises(InterpKernelException,mm.getGroup(-1,"Grp_dup").checkGeoEquivalWith,mm.getGroup(-1,"Grp"),12,1e-12); - refValues2=refValues[:] ; refValues2[7:10]=[1.365,1.26,1.35] - valsToTest=mm.getMeshAtLevel(0).getMeasureField(True).getArray() ; delta=(valsToTest-refValues2) ; delta.abs() - self.assertTrue(delta.getMaxValue()[0]<1e-12) - mm.write(fname,2) - pass - - def testBuildInnerBoundaryAlongM1Group2(self): - fname="Pyfile45.med" - m=MEDCouplingCMesh.New() - m.setCoordsAt(0,DataArrayDouble.New([0.,1.1,2.3,3.6,5.,6.5])) - m.setCoordsAt(1,DataArrayDouble.New([0.,1.1,2.3,3.6,5.])) - m=m.buildUnstructured() ; m.setName("AnthonyDuplicate") - m.getCoords().setInfoOnComponents(["X [km]","Z [mm]"]) - m2=m.buildDescendingConnectivity()[0][[8,11,14,20,21,22,23,24,25,26,31,32,33,34,35,36,37]] - m2.setName(m.getName()) - grp=DataArrayInt.New([4,6]) ; grp.setName("Grp") - grp2=DataArrayInt.New([9,16]) ; grp2.setName("Grp2") - mm=MEDFileUMesh.New() - mm.setMeshAtLevel(0,m) - mm.setMeshAtLevel(-1,m2) - mm.setGroupsAtLevel(-1,[grp,grp2]) - grpNode=DataArrayInt.New([4,21,23]) ; grpNode.setName("GrpNode") - mm.setGroupsAtLevel(1,[grpNode]) - ref0=[4,15,14,20,21,4,16,15,21,22,4,17,16,22,23] - ref1=[4,9,8,14,15,4,10,9,15,16] - ref2=[4,9,8,14,30,4,10,9,30,16] - # - self.assertEqual(30,mm.getNumberOfNodes()) - self.assertEqual(ref0,mm.getMeshAtLevel(0)[[12,13,14]].getNodalConnectivity().getValues()) - self.assertEqual(ref1,mm.getMeshAtLevel(0)[[7,8]].getNodalConnectivity().getValues()) - # - nodes,cells,cells2=mm.buildInnerBoundaryAlongM1Group("Grp") - self.assertEqual([15],nodes.getValues()); - self.assertEqual([7,8],cells.getValues()); - self.assertEqual([12,13],cells2.getValues()); - self.assertEqual(31,mm.getNumberOfNodes()) - self.assertEqual([4,6],mm.getGroupArr(-1,"Grp").getValues()) - self.assertEqual([9,16],mm.getGroupArr(-1,"Grp2").getValues()) - self.assertEqual([4,21,23],mm.getGroupArr(1,"GrpNode").getValues()) - self.assertEqual([17,18],mm.getGroupArr(-1,"Grp_dup").getValues()) - self.assertEqual(ref0,mm.getMeshAtLevel(0)[[12,13,14]].getNodalConnectivity().getValues())#cells 7,8,9 and 12,13,14 are lying on "Grp" but only 7,8 and 9 are renumbered - self.assertEqual(ref2,mm.getMeshAtLevel(0)[[7,8]].getNodalConnectivity().getValues())# - self.assertRaises(InterpKernelException,mm.getGroup(-1,"Grp_dup").checkGeoEquivalWith,mm.getGroup(-1,"Grp"),2,1e-12);# Grp_dup and Grp are not equal considering connectivity only - mm.getGroup(-1,"Grp_dup").checkGeoEquivalWith(mm.getGroup(-1,"Grp"),12,1e-12)# Grp_dup and Grp are equal considering connectivity and coordinates - refValues=DataArrayDouble.New([1.21,1.32,1.43,1.54,1.65,1.32,1.44,1.56,1.68,1.8,1.43,1.56,1.69,1.82,1.95,1.54,1.68,1.82,1.96,2.1]) - valsToTest=mm.getMeshAtLevel(0).getMeasureField(True).getArray() ; delta=(valsToTest-refValues) ; delta.abs() - self.assertTrue(delta.getMaxValue()[0]<1e-12) - # - mm.getCoords()[-len(nodes):]+=[0.,-0.3] - self.assertRaises(InterpKernelException,mm.getGroup(-1,"Grp_dup").checkGeoEquivalWith,mm.getGroup(-1,"Grp"),12,1e-12); - refValues2=refValues[:] ; refValues2[7:9]=[1.365,1.47] - valsToTest=mm.getMeshAtLevel(0).getMeasureField(True).getArray() ; delta=(valsToTest-refValues2) ; delta.abs() - self.assertTrue(delta.getMaxValue()[0]<1e-12) - mm.write(fname,2) - pass - - def testBuildInnerBoundaryAlongM1Group3(self): - """ Test buildInnerBoundaryAlongM1Group() with *non-connex* cracks """ - fname = "Pyfile73.med" - m = MEDCouplingCMesh.New() - m.setCoordsAt(0, DataArrayDouble([0.0,1.1,2.3,3.6,5.0])) - m.setCoordsAt(1, DataArrayDouble([0.,1.,2.])) - m = m.buildUnstructured(); m.setName("simple") - m2 = m.buildDescendingConnectivity()[0] - m2.setName(m.getName()) - - # A crack in two non connected parts of the mesh: - grpSeg = DataArrayInt([3,19]) ; grpSeg.setName("Grp") - - mm = MEDFileUMesh.New() - mm.setMeshAtLevel(0,m) - mm.setMeshAtLevel(-1,m2) - mm.setGroupsAtLevel(-1,[grpSeg]) - nodes, cellsMod, cellsNotMod = mm.buildInnerBoundaryAlongM1Group("Grp") - self.assertEqual([1,13],nodes.getValues()); - self.assertEqual([0,6],cellsMod.getValues()); - self.assertEqual([1,7],cellsNotMod.getValues()); - self.assertEqual(17,mm.getNumberOfNodes()) - self.assertEqual([3,19],mm.getGroupArr(-1,"Grp").getValues()) - self.assertEqual([22,23],mm.getGroupArr(-1,"Grp_dup").getValues()) - ref0=[4, 15, 0, 5, 6, 4, 8, 7, 12, 16] - ref1=[4, 2, 1, 6, 7, 4, 9, 8, 13, 14] - self.assertEqual(ref0,mm.getMeshAtLevel(0)[[0,6]].getNodalConnectivity().getValues()) - self.assertEqual(ref1,mm.getMeshAtLevel(0)[[1,7]].getNodalConnectivity().getValues()) - self.assertRaises(InterpKernelException,mm.getGroup(-1,"Grp_dup").checkGeoEquivalWith,mm.getGroup(-1,"Grp"),2,1e-12);# Grp_dup and Grp are not equal considering connectivity only - mm.getGroup(-1,"Grp_dup").checkGeoEquivalWith(mm.getGroup(-1,"Grp"),12,1e-12)# Grp_dup and Grp are equal considering connectivity and coordinates - - refValues=DataArrayDouble([1.1, 1.2, 1.3, 1.4, 1.1, 1.2, 1.3, 1.4]) - valsToTest=mm.getMeshAtLevel(0).getMeasureField(True).getArray() ; delta=(valsToTest-refValues) ; delta.abs() - self.assertTrue(delta.getMaxValue()[0]<1e-10) - # - mm.getCoords()[-len(nodes):]+=[0.,-0.3] - self.assertRaises(InterpKernelException,mm.getGroup(-1,"Grp_dup").checkGeoEquivalWith,mm.getGroup(-1,"Grp"),12,1e-12); - refValues2=refValues[:] ; refValues2[0] = 1.265; refValues2[6] = 1.105 - valsToTest=mm.getMeshAtLevel(0).getMeasureField(True).getArray() ; delta=(valsToTest-refValues2) ; delta.abs() - self.assertTrue(delta.getMaxValue()[0]<1e-12) - mm.write(fname,2) - - def testBasicConstructors(self): - fname="Pyfile18.med" - m=MEDFileMesh.New(fname) - m=MEDFileMesh.New(fname,"ExampleOfMultiDimW",-1,-1) - m=MEDFileMesh.New(fname) - m=MEDFileUMesh(fname,"ExampleOfMultiDimW",-1,-1) - m=MEDFileUMesh(fname) - m=MEDFileUMesh() - self.testMEDMesh6() - m=MEDFileCMesh("MEDFileMesh5.med") - m=MEDFileCMesh("MEDFileMesh5.med","myFirstCartMesh",-1,-1) - m=MEDFileCMesh() - m=MEDFileMeshMultiTS() - m=MEDFileMeshMultiTS(fname) - m=MEDFileMeshMultiTS(fname,"ExampleOfMultiDimW") - m=MEDFileMeshes() - m=MEDFileMeshes(fname) - m=MEDFileField1TS() - m=MEDFileField1TS(fname,"FieldOnFacesShuffle",2,7) - m=MEDFileFieldMultiTS() - m=MEDFileFieldMultiTS(fname,"FieldOnFacesShuffle") - m=MEDFileFields() - m=MEDFileFields(fname) - m=MEDFileData() - m=MEDFileData(fname) - # - m=DataArrayInt() ; m=DataArrayInt(5,2) ; m=DataArrayInt([6,5,4,3,2,1],3,2) - m=DataArrayDouble() ; m=DataArrayDouble(5,2) ; m=DataArrayDouble([6,5,4,3,2,1],3,2) - m=MEDCouplingUMesh("jjj",2) ; m=MEDCouplingUMesh() - m=MEDCouplingCMesh() - m=MEDCouplingFieldDouble(ON_CELLS,ONE_TIME) - m=MEDCouplingFieldTemplate(ON_NODES) - m=MEDCouplingMultiFields([]) - m=MEDCouplingFieldOverTime([]) - pass - - # This is a non regression test. When a field lies partially on a mesh but fully on one of its geometric type. - def testBugSemiPartialField(self): - fname="Pyfile46.med" - m=MEDLoaderDataForTest.build2DMesh_3() - m=m[:10] ; m.setName("mesh") - f=m.getMeasureField(ON_CELLS) - f=f.buildNewTimeReprFromThis(ONE_TIME,False) - f.setTime(5.5,3,4) - f.setName("SemiPartialField") - # - f1=f[:6] ; f1.getMesh().setName(m.getName()) - f2=f[6:] ; f2.getMesh().setName(m.getName()) - # - mm=MEDFileUMesh.New() - mm.setMeshAtLevel(0,m) - ff=MEDFileField1TS.New() - ff.setFieldProfile(f1,mm,0,DataArrayInt.Range(0,6,1)) # no name on profile -> normally it is an error but in this special case - mm.write(fname,2) - ff.write(fname,0) - # - ff2=MEDFileField1TS.New(fname,f.getName(),f.getTime()[1],f.getTime()[2]) - fread=ff2.getFieldOnMeshAtLevel(ON_CELLS,0,mm) - fread2=ff2.getFieldAtLevel(ON_CELLS,0) - # - fread.checkCoherency() - fread2.checkCoherency() - self.assertTrue(fread.isEqual(f1,1e-12,1e-12)) - self.assertTrue(fread2.isEqual(f1,1e-12,1e-12)) - pass - - def testUnPolyze1(self): - fname="Pyfile47.med" - mm=MEDLoaderDataForTest.buildMLMeshUnPolyze(self) - ref=[13,14,14,12,12,12,12,12,12,12,12,13,12,14,14,13,15,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12] - self.assertEqual(ref,mm.getFamilyFieldAtLevel(1).getValues()) - self.assertEqual(mm.unPolyze()[:3],(True,[[3,2,0],[4,3,2],[5,4,5],[14,2,9],[16,3,11],[31,2,14]],[[3,3,0],[4,3,3],[5,3,6],[14,3,9],[16,3,12],[18,1,15]])) - mm.write(fname,2) - self.assertEqual(mm.getGroupArr(0,"grp0_L0").getValues(),[0,1,2,6]) - self.assertEqual(mm.getGroupArr(0,"grp1_L0").getValues(),[1,3,4,5,6]) - self.assertEqual(mm.getGroupArr(-1,"grp0_LM1").getValues(),[1,2,3,4,5]) - self.assertEqual(mm.getGroupArr(-1,"grp1_LM1").getValues(),[3,4,5,6]) - self.assertEqual(mm.getGroupArr(-1,"grp2_LM1").getValues(),[2,6,7,8]) - self.assertEqual(mm.getGroupArr(1,"grp0_Node").getValues(),[0,11,15,16]) - self.assertEqual(mm.getGroupArr(1,"grp1_Node").getValues(),[1,2,13,14,16]) - self.assertEqual(mm.getFamilyFieldAtLevel(1).getValues(),ref) - # to test - mm.setRenumFieldArr(0,None) - mm.setFamilyFieldArr(-1,None) - pass - - def testUnPolyze2(self): - fname="Pyfile48.med" - mfd=MEDFileData.New() - mm=MEDLoaderDataForTest.buildMLMeshUnPolyze(self) - meshes=MEDFileMeshes.New() - meshes.pushMesh(mm) - mfd.setMeshes(meshes) - fields=MEDFileFields.New() - mfd.setFields(fields) - ff=MEDFileFieldMultiTS.New() - fields.pushField(ff) - # - f0_0=MEDCouplingFieldDouble.New(ON_NODES,ONE_TIME) ; f0_0.setName("f0") - f0_0.setTime(9.5,3,4) - da=DataArrayDouble.New(38*2) ; da.iota(6.) ; da.rearrange(2) ; da.setInfoOnComponents(["Power [MW]","Density [kg/m^3]"]) - f0_0.setArray(da) - f0_0.setMesh(mm.getMeshAtLevel(0)) - ff.appendFieldNoProfileSBT(f0_0) - ff0=ff.getTimeStepAtPos(0) - f0_1=MEDCouplingFieldDouble.New(ON_CELLS,ONE_TIME) ; f0_1.setName("f0") - f0_1.setTime(9.5,3,4) - pfl=DataArrayInt.New([1,4,5,6]) ; pfl.setName("pfltest") - f0_1.setMesh(mm.getMeshAtLevel(0)[pfl]) - da=DataArrayDouble.New([1401.,101401.,1602.,101602.,3100.,103100.,3101.,103101.],4,2) ; da.setInfoOnComponents(["Power [MW]","Density [kg/m^3]"]) - f0_1.setArray(da) - ff0.setFieldProfile(f0_1,mm,0,pfl) - f0_2=MEDCouplingFieldDouble.New(ON_CELLS,ONE_TIME) ; f0_2.setName("f0")#provoquer error - f0_2.setTime(9.5,3,4) - pfl2=DataArrayInt.New([0,1,2,3,4,5,6,8]) ; pfl2.setName("pfltestM1") - da=DataArrayDouble.New([300.,100300.,301.,100301.,400.,100400.,401.,100401.,402.,100402.,3200.,103200.,3201.,103201.,3203.,103203.],8,2) ; da.setInfoOnComponents(["Power [MW]","Density [kg/m^3]"])#provoquer error - f0_2.setMesh(mm.getMeshAtLevel(-1)[pfl2]) - f0_2.setArray(da) - ff0.setFieldProfile(f0_2,mm,-1,pfl2) - mfd.getFields().shallowCpyGlobs(ff0) - # - mfd.unPolyzeMeshes() - # - fmts=mfd.getFields()[0] - self.assertEqual(fmts.getNumberOfTS(),1) - self.assertEqual(fmts.getTimeSteps(),[(3,4,9.5)]) - arr,entry=fmts.getUndergroundDataArrayExt(3,4) - self.assertEqual(entry,[((3,0),(38,40)),((4,0),(40,43)),((5,0),(43,46)),((14,0),(46,48)),((16,0),(48,49)),((18,0),(49,50)),((40,0),(0,38))]) - self.assertTrue(arr[38:40].isEqualWithoutConsideringStr(DataArrayDouble([300.0,100300.0,301.0,100301.0],2,2),1e-8)) - self.assertTrue(arr[40:43].isEqualWithoutConsideringStr(DataArrayDouble([400.0,100400.0,401.0,100401.0,402.0,100402.0],3,2),1e-8)) - self.assertTrue(arr[43:46].isEqualWithoutConsideringStr(DataArrayDouble([3200.0,103200.0,3201.0,103201.0,3203.0,103203.0],3,2),1e-8)) - self.assertTrue(arr[46:48].isEqualWithoutConsideringStr(DataArrayDouble([1401.0,101401.0,3100.0,103100.0],2,2),1e-8)) - self.assertTrue(arr[48:49].isEqualWithoutConsideringStr(DataArrayDouble([1602.0,101602.0],1,2),1e-8)) - self.assertTrue(arr[49:50].isEqualWithoutConsideringStr(DataArrayDouble([3101.0,103101.0],1,2),1e-8)) - self.assertEqual(('NewPfl_0','NewPfl_1','NewPfl_2'),fmts.getPflsReallyUsed()) - self.assertEqual([(3,[(0,(38,40),'NewPfl_0','')]),(4,[(0,(40,43),'','')]),(5,[(0,(43,46),'','')]),(14,[(0,(46,48),'NewPfl_1','')]),(16,[(0,(48,49),'NewPfl_2','')]),(18,[(0,(49,50),'','')]),(40,[(1,(0,38),'','')])],fmts.getFieldSplitedByType(3,4)) - self.assertEqual(fmts.getProfile("NewPfl_0").getValues(),[0,1]) - self.assertEqual(fmts.getProfile("NewPfl_1").getValues(),[1,2]) - self.assertEqual(fmts.getProfile("NewPfl_2").getValues(),[2]) - ftest0=fmts.getFieldOnMeshAtLevel(ON_CELLS,3,4,0,mfd.getMeshes()[0]) - self.assertTrue(ftest0.getArray().isEqualWithoutConsideringStr(DataArrayDouble([1401.,101401.,3100.,103100.,1602.,101602.,3101.,103101.],4,2),1e-8)) - self.assertEqual(ftest0.getMesh().getNodalConnectivity().getValues(),[14,4,5,6,7,14,26,27,28,29,16,20,21,22,23,24,25,18,30,31,32,33,34,35,36,37]) - self.assertEqual(ftest0.getMesh().getNodalConnectivityIndex().getValues(),[0,5,10,17,26]) - ftest1=fmts.getFieldOnMeshAtLevel(ON_CELLS,3,4,-1,mfd.getMeshes()[0]) - self.assertTrue(ftest1.getArray().isEqualWithoutConsideringStr(DataArrayDouble([300.,100300.,301.,100301.,400.,100400.,401.,100401.,402.,100402.,3200.,103200.,3201.,103201.,3203.,103203.]),1e-8)) - self.assertEqual(ftest1.getMesh().getNodalConnectivity().getValues(),[3,0,1,2,3,3,4,5,4,6,7,8,9,4,10,11,12,13,4,14,15,16,17,5,18,19,20,21,22,5,23,24,25,26,27,5,31,32,33,34,35,36,37]) - self.assertEqual(ftest1.getMesh().getNodalConnectivityIndex().getValues(),[0,4,8,13,18,23,29,35,43]) - # - mfd.write(fname,2) - pass - - def testGaussWriteOnPfl1(self): - fname="Pyfile49.med" - fname2="Pyfile50.med" - coords=DataArrayDouble([0.,0.,0.,1.,1.,1.,1.,0.,0.,0.5,0.5,1.,1.,0.5,0.5,0.],8,2) - mQ8=MEDCouplingUMesh("",2) ; mQ8.setCoords(coords) - mQ8.allocateCells(1) - mQ8.insertNextCell(NORM_QUAD8,range(8)) - mQ8.finishInsertingCells() - mQ4=MEDCouplingUMesh("",2) ; mQ4.setCoords(coords) - mQ4.allocateCells(1) - mQ4.insertNextCell(NORM_QUAD4,range(4)) - mQ4.finishInsertingCells() - mT3=MEDCouplingUMesh("",2) ; mT3.setCoords(coords) - mT3.allocateCells(1) - mT3.insertNextCell(NORM_TRI3,range(3)) - mT3.finishInsertingCells() - - tr=[[0.,4.],[2.,4.],[4.,4.],[6.,4.],[8.,4.],[10.,4.],[12.,4.],[14.,4.],[16.,4.],[18.,4.],[20.,4.],[0.,0.],[2.,0.], [0.,2.],[2.,2.],[4.,2.],[6.,2.],[8.,2.],[10.,2.],[12.,2.]] - ms=11*[mT3]+2*[mQ4]+7*[mQ8] - ms[:]=(elt.deepCpy() for elt in ms) - for m,t in zip(ms,tr): - d=m.getCoords() ; d+= t - pass - m=MEDCouplingUMesh.MergeUMeshes(ms) - m.setName("mesh") - m2=m[:13] ; m2.setName(m.getName()) - ### Use case 1 : Pfl on all tri3 and on all quad4. If we were on CELLS or GAUSS_NE no pfl were needed. But here 2 discs in tri3. - ### So here 2 pfls will be created (pfl_TRI3_loc_0 and pfl_TRI3_loc_1) - f=MEDCouplingFieldDouble.New(ON_GAUSS_PT,ONE_TIME) - f.setMesh(m2) - f.setTime(4.5,1,2) - da=DataArrayDouble(34) ; da.iota(3.) - f.setArray(da) - f.setName("fieldCellOnPflWithoutPfl") - fInvalid=f.deepCpy() - f.setGaussLocalizationOnCells([0,1,2,3,4,5,6,7,8],[0.,0.,1.,0.,1.,1.],[0.3,0.3,0.7,0.7],[0.8,0.2]) - f.setGaussLocalizationOnCells([9,10],[0.,0.,1.,0.,1.,1.],[0.3,0.3,0.7,0.7,0.8,0.8],[0.8,0.07,0.13]) - f.setGaussLocalizationOnCells([11,12],[0.,0.,1.,0.,1.,1.,0.,1.],[0.3,0.3,0.7,0.7,0.8,0.8,0.8,0.8,0.8,0.8],[0.8,0.07,0.1,0.01,0.02]) - f.checkCoherency() - fInvalid2=fInvalid.deepCpy() - fInvalid2.getDiscretization().setArrayOfDiscIds(f.getDiscretization().getArrayOfDiscIds()) - # - mm=MEDFileUMesh() - mm.setMeshAtLevel(0,m) - mm.write(fname,2) - # - f1ts=MEDFileField1TS.New() - pfl=DataArrayInt(range(13)) ; pfl.setName("pfl") - self.assertRaises(InterpKernelException,f1ts.setFieldProfile,fInvalid,mm,0,pfl) # fails because no Gauss localization per cell set ! - self.assertRaises(InterpKernelException,f1ts.setFieldProfile,fInvalid2,mm,0,pfl) # fails because no Gauss localization set whereas gauss locid per cell given ! - f1ts.setFieldProfile(f,mm,0,pfl) - f1ts.write(fname,0) - # - self.assertEqual(f1ts.getPfls(),('pfl_NORM_TRI3_loc_0', 'pfl_NORM_TRI3_loc_1')) - self.assertEqual(f1ts.getPflsReallyUsed(),('pfl_NORM_TRI3_loc_0', 'pfl_NORM_TRI3_loc_1')) - da1=DataArrayInt([0,1,2,3,4,5,6,7,8]) ; da1.setName("pfl_NORM_TRI3_loc_0") - self.assertTrue(f1ts.getProfile("pfl_NORM_TRI3_loc_0").isEqual(da1)) - da1=DataArrayInt([9,10]) ; da1.setName("pfl_NORM_TRI3_loc_1") - self.assertTrue(f1ts.getProfile("pfl_NORM_TRI3_loc_1").isEqual(da1)) - self.assertEqual(f1ts.getLocs(),('Loc_fieldCellOnPflWithoutPfl_NORM_TRI3_0', 'Loc_fieldCellOnPflWithoutPfl_NORM_TRI3_1', 'Loc_fieldCellOnPflWithoutPfl_NORM_QUAD4_2')) - self.assertEqual(f1ts.getLocsReallyUsed(),('Loc_fieldCellOnPflWithoutPfl_NORM_TRI3_0', 'Loc_fieldCellOnPflWithoutPfl_NORM_TRI3_1', 'Loc_fieldCellOnPflWithoutPfl_NORM_QUAD4_2')) - # - dataRead=MEDFileData.New(fname) - mRead=dataRead.getMeshes()[0] - f1tsRead=dataRead.getFields()[0][0] - f1tsRead.getFieldOnMeshAtLevel(ON_GAUSS_PT,0,mRead) - f2=f1tsRead.getFieldOnMeshAtLevel(ON_GAUSS_PT,0,mRead) - self.assertTrue(f.isEqual(f2,1e-12,1e-12)) - f2_bis=MEDLoader.ReadFieldGauss(fname,m.getName(),0,f.getName(),f.getTime()[1],f.getTime()[2]) - f2_bis.checkCoherency() - self.assertTrue(f.isEqual(f2_bis,1e-12,1e-12)) - # - MEDLoader.WriteField(fname2,f,True) - f2_ter=MEDLoader.ReadFieldGauss(fname2,m.getName(),0,f.getName(),f.getTime()[1],f.getTime()[2]) - self.assertTrue(f.isEqual(f2_ter,1e-12,1e-12)) - ## Use case 2 : Pfl on part tri3 with 2 disc and on part quad8 with 1 disc - f=MEDCouplingFieldDouble.New(ON_GAUSS_PT,ONE_TIME) - pfl=DataArrayInt([1,2,5,6,8,9,15,16,17,18]) ; pfl.setName("pfl2") - m2=m[pfl] ; m2.setName(m.getName()) - f.setMesh(m2) - f.setTime(4.5,1,2) - da=DataArrayDouble(35) ; da.iota(3.) - f.setArray(da) - f.setName("fieldCellOnPflWithoutPfl2") - f.setGaussLocalizationOnCells([0,1,3],[0.,0.,1.,0.,1.,1.],[0.3,0.3,0.7,0.7],[0.8,0.2]) - f.setGaussLocalizationOnCells([2,4,5],[0.,0.,1.,0.,1.,1.],[0.3,0.3,0.7,0.7,0.8,0.8],[0.8,0.07,0.13]) - f.setGaussLocalizationOnCells([6,7,8,9],[0.,0.,1.,0.,1.,1.,0.,1.,0.5,0.,1.,0.5,0.5,1.,0.,0.5],[0.3,0.3,0.7,0.7,0.8,0.8,0.8,0.8,0.8,0.8],[0.8,0.07,0.1,0.01,0.02]) - f.checkCoherency() - # - mm=MEDFileUMesh() - mm.setMeshAtLevel(0,m) - mm.write(fname,2) - f1ts=MEDFileField1TS.New() - f1ts.setFieldProfile(f,mm,0,pfl) - self.assertEqual(f1ts.getPfls(),('pfl2_NORM_TRI3_loc_0','pfl2_NORM_TRI3_loc_1','pfl2_NORM_QUAD8_loc_2')) - self.assertEqual(f1ts.getProfile("pfl2_NORM_TRI3_loc_0").getValues(),[1,2,6]) - self.assertEqual(f1ts.getProfile("pfl2_NORM_TRI3_loc_1").getValues(),[5,8,9]) - self.assertEqual(f1ts.getProfile("pfl2_NORM_QUAD8_loc_2").getValues(),[2,3,4,5]) - f1ts.write(fname,0) - dataRead=MEDFileData.New(fname) - mRead=dataRead.getMeshes()[0] - f1tsRead=dataRead.getFields()[0][0] - f1tsRead.getFieldOnMeshAtLevel(ON_GAUSS_PT,0,mRead) - f3=f1tsRead.getFieldOnMeshAtLevel(ON_GAUSS_PT,0,mRead) - f3.renumberCells([0,1,3,2,4,5,6,7,8,9]) - self.assertTrue(f.isEqual(f3,1e-12,1e-12)) - f3_bis=MEDLoader.ReadFieldGauss(fname,m.getName(),0,f.getName(),f.getTime()[1],f.getTime()[2]) - f3_bis.renumberCells([0,1,3,2,4,5,6,7,8,9]) - self.assertTrue(f.isEqual(f3_bis,1e-12,1e-12)) - # - MEDLoader.WriteField(fname2,f,True) - f3_ter=MEDLoader.ReadFieldGauss(fname2,m.getName(),0,f.getName(),f.getTime()[1],f.getTime()[2]) - f3_ter.renumberCells([0,1,3,2,4,5,6,7,8,9]) - self.assertTrue(f.isEqual(f3_ter,1e-12,1e-12)) - ## Use case 3 : no pfl but creation of pfls due to gauss pts - f=MEDCouplingFieldDouble.New(ON_GAUSS_PT,ONE_TIME) - f.setMesh(m) - f.setTime(4.5,1,2) - da=DataArrayDouble(60) ; da.iota(3.) - f.setArray(da) - f.setName("fieldCellWithoutPfl") - f.setGaussLocalizationOnCells([0,1,2,3,4,5,6,7,8],[0.,0.,1.,0.,1.,1.],[0.3,0.3,0.7,0.7],[0.8,0.2]) - f.setGaussLocalizationOnCells([9,10],[0.,0.,1.,0.,1.,1.],[0.3,0.3,0.7,0.7,0.8,0.8],[0.8,0.07,0.13]) - f.setGaussLocalizationOnCells([11,12],[0.,0.,1.,0.,1.,1.,0.,1.],[0.3,0.3,0.7,0.7,0.8,0.8,0.8,0.8,0.8,0.8],[0.8,0.07,0.1,0.01,0.02]) - f.setGaussLocalizationOnCells([13,14,15,17,18],[0.,0.,1.,0.,1.,1.,0.,1.,0.5,0.,1.,0.5,0.5,1.,0.,0.5],[0.3,0.3,0.7,0.7,0.8,0.8,0.8,0.8],[0.8,0.1,0.03,0.07]) - f.setGaussLocalizationOnCells([16,19],[0.,0.,1.,0.,1.,1.,0.,1.,0.5,0.,1.,0.5,0.5,1.,0.,0.5],[0.3,0.3,0.7,0.7,0.8,0.8],[0.8,0.1,0.1]) - f.checkCoherency() - mm=MEDFileUMesh() - mm.setMeshAtLevel(0,m) - f1ts=MEDFileField1TS.New() - f1ts.setFieldNoProfileSBT(f) - self.assertEqual(f1ts.getPfls(),('Pfl_fieldCellWithoutPfl_NORM_TRI3_0','Pfl_fieldCellWithoutPfl_NORM_TRI3_1','Pfl_fieldCellWithoutPfl_NORM_QUAD8_3','Pfl_fieldCellWithoutPfl_NORM_QUAD8_4')) - self.assertEqual(f1ts.getProfile("Pfl_fieldCellWithoutPfl_NORM_TRI3_0").getValues(),[0,1,2,3,4,5,6,7,8]) - self.assertEqual(f1ts.getProfile("Pfl_fieldCellWithoutPfl_NORM_TRI3_1").getValues(),[9,10]) - self.assertEqual(f1ts.getProfile("Pfl_fieldCellWithoutPfl_NORM_QUAD8_3").getValues(),[0,1,2,4,5]) - self.assertEqual(f1ts.getProfile("Pfl_fieldCellWithoutPfl_NORM_QUAD8_4").getValues(),[3,6]) - mm.write(fname,2) - f1ts.write(fname,0) - # - dataRead=MEDFileData.New(fname) - mRead=dataRead.getMeshes()[0] - f1tsRead=dataRead.getFields()[0][0] - f3=f1tsRead.getFieldOnMeshAtLevel(ON_GAUSS_PT,0,mRead) - f3.renumberCells([0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,17,18,16,19]) - self.assertTrue(f.isEqual(f3,1e-12,1e-12)) - f3_bis=MEDLoader.ReadFieldGauss(fname,m.getName(),0,f.getName(),f.getTime()[1],f.getTime()[2]) - f3_bis.renumberCells([0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,17,18,16,19]) - self.assertTrue(f.isEqual(f3_bis,1e-12,1e-12)) - # - MEDLoader.WriteField(fname2,f,True) - f3_ter=MEDLoader.ReadFieldGauss(fname2,m.getName(),0,f.getName(),f.getTime()[1],f.getTime()[2]) - f3_ter.renumberCells([0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,17,18,16,19]) - self.assertTrue(f.isEqual(f3_ter,1e-12,1e-12)) - pass - - # Testing profile on nodes when the profile is identity but not on all nodes. - def testMEDFieldPflOnNode1(self): - fname="Pyfile51.med" - coo=DataArrayDouble([0.,0.,0.5,0.,1.,0.,0.,0.5,0.5,0.5,1.,0.5,0.,1.,0.5,1.,1.,1.],9,2) - m0=MEDCouplingUMesh("Mesh",2) - m0.allocateCells(5) - m0.insertNextCell(NORM_TRI3,[1,4,2]) - m0.insertNextCell(NORM_TRI3,[4,5,2]) - m0.insertNextCell(NORM_QUAD4,[0,3,4,1]) - m0.insertNextCell(NORM_QUAD4,[3,6,7,4]) - m0.insertNextCell(NORM_QUAD4,[4,7,8,5]) - m0.finishInsertingCells() - m0.setCoords(coo) - m1=MEDCouplingUMesh(m0.getName(),1) - m1.allocateCells(9) - conn1=[0,1,0,3,3,4,4,1,5,4,2,4,1,2,3,6,5,8] - for i in xrange(9): - m1.insertNextCell(NORM_SEG2,conn1[2*i:2*i+2]) - pass - m1.finishInsertingCells() - m1.setCoords(coo) - # - m=MEDFileUMesh() - m.setMeshAtLevel(0,m0) - m.setMeshAtLevel(-1,m1) - # - dt=3 ; it=2 ; tim=4.5 - fieldNode0=MEDCouplingFieldDouble(ON_NODES,ONE_TIME) - fieldNode0.setName("fieldNode0") - fieldNode0.setTime(tim,dt,it) - pfl0=DataArrayInt([0,1,2,3,4]) ; pfl0.setName("PflIdentity0") # important to keep like that - arr=DataArrayDouble([10,11,12,13,14]) - fieldNode0.setArray(arr) - f0=MEDFileField1TS() - f0.setFieldProfile(fieldNode0,m,0,pfl0) - m.write(fname,2) ; f0.write(fname,0) - fieldNode1=MEDCouplingFieldDouble(ON_NODES,ONE_TIME) - fieldNode1.setName("fieldNode1") - fieldNode1.setTime(tim,dt,it) - pfl1=DataArrayInt([0,1,2,3,4,5,6]) ; pfl1.setName("PflIdentity1") - arr1=DataArrayDouble([20,21,22,23,24,25,26]) - fieldNode1.setArray(arr1) - f1=MEDFileField1TS() - f1.setFieldProfile(fieldNode1,m,-1,pfl1) - f1.write(fname,0) - del m,f0,m0,m1,f1 - ## Reading from file - m=MEDFileMesh.New(fname) - m0=m.getMeshAtLevel(0) - m00=m0.deepCpy() ; m00=m00[[0,2]] ; m00.setName(m.getName()) ; m00.zipCoords() - fieldNode0.setMesh(m00) - f0=MEDFileField1TS.New(fname,fieldNode0.getName(),dt,it) - ff0_1=f0.getFieldOnMeshAtLevel(ON_NODES,m0) - ff0_1.checkCoherency() - self.assertTrue(ff0_1.isEqual(fieldNode0,1e-12,1e-12)) - ff0_2=f0.getFieldAtLevel(ON_NODES,0) - ff0_2.checkCoherency() - self.assertTrue(ff0_2.isEqual(fieldNode0,1e-12,1e-12)) - ff0_3=f0.getFieldOnMeshAtLevel(ON_NODES,0,m) - ff0_3.checkCoherency() - self.assertTrue(ff0_3.isEqual(fieldNode0,1e-12,1e-12)) - ff0_4=MEDLoader.ReadFieldNode(fname,m.getName(),0,fieldNode0.getName(),dt,it) - ff0_4.checkCoherency() - self.assertTrue(ff0_4.isEqual(fieldNode0,1e-12,1e-12)) - f1=MEDFileField1TS.New(fname,fieldNode1.getName(),dt,it) - m1=m.getMeshAtLevel(-1) - m10=m1.deepCpy() ; m10=m10[[0,1,2,3,4,5,6,7]] ; m10.setName(m.getName()) ; m10.zipCoords() - fieldNode1.setMesh(m10) - ff1_1=f1.getFieldOnMeshAtLevel(ON_NODES,m1) - ff1_1.checkCoherency() - self.assertTrue(ff1_1.isEqual(fieldNode1,1e-12,1e-12)) - ff1_2=f1.getFieldAtLevel(ON_NODES,-1) - ff1_2.checkCoherency() - self.assertTrue(ff1_2.isEqual(fieldNode1,1e-12,1e-12)) - ff1_3=f1.getFieldOnMeshAtLevel(ON_NODES,-1,m) - ff1_3.checkCoherency() - self.assertTrue(ff1_3.isEqual(fieldNode1,1e-12,1e-12)) - ff1_4=MEDLoader.ReadFieldNode(fname,m.getName(),-1,fieldNode1.getName(),dt,it) - ff1_4.checkCoherency() - self.assertTrue(ff1_4.getMesh().isEqual(m10,1e-12)) - self.assertRaises(InterpKernelException,f1.getFieldOnMeshAtLevel,ON_NODES,m0) # error because impossible to build a sub mesh at level 0 lying on nodes [0,1,2,3,4,5,6] - self.assertRaises(InterpKernelException,f1.getFieldAtLevel,ON_NODES,0) # error because impossible to build a sub mesh at level 0 lying on nodes [0,1,2,3,4,5,6] - self.assertRaises(InterpKernelException,f1.getFieldOnMeshAtLevel,ON_NODES,0,m) # error because impossible to build a sub mesh at level 0 lying on nodes [0,1,2,3,4,5,6] - arr_r,pfl1_r=f1.getFieldWithProfile(ON_NODES,-1,m) - arr_r.setName(fieldNode1.getArray().getName()) - self.assertTrue(arr_r.isEqual(fieldNode1.getArray(),1e-12)) - pfl1_r.setName(pfl1.getName()) - self.assertTrue(pfl1_r.isEqual(pfl1)) - pass - - # Testing profile on nodes when the profile is identity but not on all nodes. - def testMEDFieldPflOnCell1(self): - fname="Pyfile52.med" - coo=DataArrayDouble([0.,0.,0.5,0.,1.,0.,0.,0.5,0.5,0.5,1.,0.5,0.,1.,0.5,1.,1.,1.],9,2) - m0=MEDCouplingUMesh("Mesh",2) - m0.allocateCells(5) - m0.insertNextCell(NORM_TRI3,[1,4,2]) - m0.insertNextCell(NORM_TRI3,[4,5,2]) - m0.insertNextCell(NORM_QUAD4,[0,3,4,1]) - m0.insertNextCell(NORM_QUAD4,[3,6,7,4]) - m0.insertNextCell(NORM_QUAD4,[4,7,8,5]) - m0.finishInsertingCells() - m0.setCoords(coo) - m1=MEDCouplingUMesh(m0.getName(),1) - m1.allocateCells(9) - conn1=[0,1,0,3,3,4,4,1,5,4,2,4,1,2,3,6,5,8] - for i in xrange(9): - m1.insertNextCell(NORM_SEG2,conn1[2*i:2*i+2]) - pass - m1.finishInsertingCells() - m1.setCoords(coo) - # - m=MEDFileUMesh() - m.setMeshAtLevel(0,m0) - m.setMeshAtLevel(-1,m1) - # - dt=3 ; it=2 ; tim=4.5 - fieldCell0=MEDCouplingFieldDouble(ON_CELLS,ONE_TIME) - fieldCell0.setName("fieldCell0") - fieldCell0.setTime(tim,dt,it) - pfl0=DataArrayInt([0,1,2]) ; pfl0.setName("PflIdentity0") # important to keep like that - arr=DataArrayDouble([10,11,12]) - fieldCell0.setArray(arr) - f0=MEDFileField1TS() - f0.setFieldProfile(fieldCell0,m,0,pfl0) - m.write(fname,2) ; f0.write(fname,0) - fieldCell1=MEDCouplingFieldDouble(ON_CELLS,ONE_TIME) - fieldCell1.setName("fieldCell1") - fieldCell1.setTime(tim,dt,it) - pfl1=DataArrayInt([0,1,2,3,4,5,6]) ; pfl1.setName("PflIdentity1") - arr1=DataArrayDouble([20,21,22,23,24,25,26]) - fieldCell1.setArray(arr1) - f1=MEDFileField1TS() - f1.setFieldProfile(fieldCell1,m,-1,pfl1) - f1.write(fname,0) - del m,f0,m0,m1,f1 - ## Reading from file - m=MEDFileMesh.New(fname) - m0=m.getMeshAtLevel(0) - m00=m0.deepCpy() ; m00=m00[pfl0] ; m00.setName(m.getName()) - fieldCell0.setMesh(m00) - f0=MEDFileField1TS.New(fname,fieldCell0.getName(),dt,it) - ff0_1=f0.getFieldOnMeshAtLevel(ON_CELLS,m0) - ff0_1.checkCoherency() - self.assertTrue(ff0_1.isEqual(fieldCell0,1e-12,1e-12)) - ff0_2=f0.getFieldAtLevel(ON_CELLS,0) - ff0_2.checkCoherency() - self.assertTrue(ff0_2.isEqual(fieldCell0,1e-12,1e-12)) - ff0_3=f0.getFieldOnMeshAtLevel(ON_CELLS,0,m) - ff0_3.checkCoherency() - self.assertTrue(ff0_3.isEqual(fieldCell0,1e-12,1e-12)) - ff0_4=MEDLoader.ReadFieldCell(fname,m.getName(),0,fieldCell0.getName(),dt,it) - ff0_4.checkCoherency() - self.assertTrue(ff0_4.isEqual(fieldCell0,1e-12,1e-12)) - f1=MEDFileField1TS.New(fname,fieldCell1.getName(),dt,it) - m1=m.getMeshAtLevel(-1) - m10=m1.deepCpy() ; m10=m10[pfl1] ; m10.setName(m.getName()) - fieldCell1.setMesh(m10) - ff1_1=f1.getFieldOnMeshAtLevel(ON_CELLS,m1) - ff1_1.checkCoherency() - self.assertTrue(ff1_1.isEqual(fieldCell1,1e-12,1e-12)) - ff1_2=f1.getFieldAtLevel(ON_CELLS,-1) - ff1_2.checkCoherency() - self.assertTrue(ff1_2.isEqual(fieldCell1,1e-12,1e-12)) - ff1_3=f1.getFieldOnMeshAtLevel(ON_CELLS,-1,m) - ff1_3.checkCoherency() - self.assertTrue(ff1_3.isEqual(fieldCell1,1e-12,1e-12)) - ff1_4=MEDLoader.ReadFieldCell(fname,m.getName(),-1,fieldCell1.getName(),dt,it) - ff1_4.checkCoherency() - self.assertTrue(ff1_4.getMesh().isEqual(m10,1e-12)) - self.assertRaises(InterpKernelException,f1.getFieldOnMeshAtLevel,ON_CELLS,m0) # error because impossible to build a sub mesh at level 0 lying on cells [0,1,2,3,4,5,6] - self.assertRaises(InterpKernelException,f1.getFieldAtLevel,ON_CELLS,0) # error because impossible to build a sub mesh at level 0 lying on cells [0,1,2,3,4,5,6] - self.assertRaises(InterpKernelException,f1.getFieldOnMeshAtLevel,ON_CELLS,0,m) # error because impossible to build a sub mesh at level 0 lying on cells [0,1,2,3,4,5,6] - arr_r,pfl1_r=f1.getFieldWithProfile(ON_CELLS,-1,m) - arr_r.setName(fieldCell1.getArray().getName()) - self.assertTrue(arr_r.isEqual(fieldCell1.getArray(),1e-12)) - pfl1_r.setName(pfl1.getName()) - self.assertTrue(pfl1_r.isEqual(pfl1)) - pass - - def testMEDFileUMeshZipCoords1(self): - m=MEDFileUMesh() - coo=DataArrayDouble(30) ; coo.iota(1.) ; coo.rearrange(3) ; coo.setInfoOnComponents(["aaa [b]","cc [dd]", "e [fff]"]) - m0=MEDCouplingUMesh("toto",2) ; m0.allocateCells(0) ; m0.insertNextCell(NORM_TRI3,[1,2,3]) ; m0.insertNextCell(NORM_QUAD4,[2,4,3,4]) ; m0.insertNextCell(NORM_POLYGON,[1,6,6,6,2]) - m1=MEDCouplingUMesh("toto",1) ; m1.allocateCells(0) ; m1.insertNextCell(NORM_SEG2,[1,6]) ; m1.insertNextCell(NORM_SEG2,[7,3]) - m2=MEDCouplingUMesh("toto",0) ; m2.allocateCells(0) ; m2.insertNextCell(NORM_POINT1,[2]) ; m2.insertNextCell(NORM_POINT1,[6]) ; m2.insertNextCell(NORM_POINT1,[8]) - m0.setCoords(coo) ; m.setMeshAtLevel(0,m0) - m1.setCoords(coo) ; m.setMeshAtLevel(-1,m1) - m2.setCoords(coo) ; m.setMeshAtLevel(-2,m2) - numCoo=DataArrayInt(10) ; numCoo.iota(3) ; m.setRenumFieldArr(1,numCoo) - famCoo=DataArrayInt(10) ; famCoo.iota(4) ; m.setFamilyFieldArr(1,famCoo) - da=DataArrayInt([20,30,40]) ; m.setRenumFieldArr(0,da) ; da=DataArrayInt([200,300,400]) ; m.setFamilyFieldArr(0,da) - da=DataArrayInt([50,60]) ; m.setRenumFieldArr(-1,da) ; da=DataArrayInt([500,600]) ; m.setFamilyFieldArr(-1,da) - da=DataArrayInt([70,80,90]) ; m.setRenumFieldArr(-2,da) ; da=DataArrayInt([700,800,900]) ; m.setFamilyFieldArr(-2,da) - o2n=m.zipCoords() - self.assertTrue(o2n.isEqual(DataArrayInt([-1,0,1,2,3,-1,4,5,6,-1]))) - self.assertTrue(m.getNumberFieldAtLevel(1).isEqual(DataArrayInt([4,5,6,7,9,10,11]))) - self.assertTrue(m.getFamilyFieldAtLevel(1).isEqual(DataArrayInt([5,6,7,8,10,11,12]))) - self.assertTrue(m.getMeshAtLevel(0).getNodalConnectivity().isEqual(DataArrayInt([3,0,1,2,4,1,3,2,3,5,0,4,4,4,1]))) - self.assertTrue(m.getMeshAtLevel(0).getNodalConnectivityIndex().isEqual(DataArrayInt([0,4,9,15]))) - self.assertTrue(m.getMeshAtLevel(-1).getNodalConnectivity().isEqual(DataArrayInt([1,0,4,1,5,2]))) - self.assertTrue(m.getMeshAtLevel(-1).getNodalConnectivityIndex().isEqual(DataArrayInt([0,3,6]))) - self.assertTrue(m.getMeshAtLevel(-2).getNodalConnectivity().isEqual(DataArrayInt([0,1,0,4,0,6]))) - self.assertTrue(m.getMeshAtLevel(-2).getNodalConnectivityIndex().isEqual(DataArrayInt([0,2,4,6]))) - pass - - def testMEDUMeshAddNodeGroup1(self): - fname="Pyfile53.med" - m=MEDFileUMesh() - coo=DataArrayDouble(39) ; coo.iota(1.) ; coo.rearrange(3) ; coo.setInfoOnComponents(["aaa [b]","cc [dd]", "e [fff]"]) - m0=MEDCouplingUMesh("toto",2) ; m0.allocateCells(0) ; m0.insertNextCell(NORM_TRI3,[1,2,3]) ; m0.insertNextCell(NORM_QUAD4,[2,4,3,4]) ; m0.insertNextCell(NORM_POLYGON,[1,6,6,6,2]) - m1=MEDCouplingUMesh("toto",1) ; m1.allocateCells(0) ; m1.insertNextCell(NORM_SEG2,[1,6]) ; m1.insertNextCell(NORM_SEG2,[7,3]) - m2=MEDCouplingUMesh("toto",0) ; m2.allocateCells(0) ; m2.insertNextCell(NORM_POINT1,[2]) ; m2.insertNextCell(NORM_POINT1,[6]) ; m2.insertNextCell(NORM_POINT1,[8]) - m0.setCoords(coo) ; m.setMeshAtLevel(0,m0) - m1.setCoords(coo) ; m.setMeshAtLevel(-1,m1) - m2.setCoords(coo) ; m.setMeshAtLevel(-2,m2) - # - mm=m.deepCpy() - famCoo=DataArrayInt([0,2,0,3,2,0,-1,0,0,0,0,-1,3]) ; mm.setFamilyFieldArr(1,famCoo) - da0=DataArrayInt([0,0,0]) ; mm.setFamilyFieldArr(0,da0) - da1=DataArrayInt([0,3]) ; mm.setFamilyFieldArr(-1,da1) - da2=DataArrayInt([0,0,0]) ; mm.setFamilyFieldArr(-2,da2) - mm.setFamilyId("MyFam",2) - mm.setFamilyId("MyOtherFam",3) - mm.setFamilyId("MyOther-1",-1) - mm.setFamiliesOnGroup("grp0",["MyOtherFam"]) - mm.setFamiliesOnGroup("grpA",["MyOther-1"]) - # - daTest=DataArrayInt([1,3,4,6,9,10,12]) ; daTest.setName("grp1") - mm.addNodeGroup(daTest) - self.assertTrue(mm.getGroupArr(1,daTest.getName()).isEqual(daTest)) - self.assertTrue(mm.getFamilyFieldAtLevel(1).isEqual(DataArrayInt([6,2,6,8,2,6,5,6,6,7,7,4,8]))) - for lev,arr in [(0,da0),(-1,da1),(-2,da2)]: - self.assertTrue(mm.getFamilyFieldAtLevel(lev).isEqual(arr)) - pass - self.assertEqual(mm.getFamiliesNames(),('Family_4','Family_5','Family_7','Family_8','MyFam','MyOther-1','MyOtherFam')) - self.assertEqual(mm.getGroupsNames(),('grp0','grp1','grpA')) - self.assertEqual(mm.getFamilyNameGivenId(3),'MyOtherFam') - self.assertEqual(mm.getFamilyNameGivenId(2),'MyFam') - for famName,famId in [('Family_4',4),('Family_5',5),('Family_7',7),('Family_8',8)]: - self.assertEqual(mm.getFamilyNameGivenId(famId),famName) - pass - self.assertEqual(mm.getFamiliesOnGroup("grp0"),('MyOtherFam','Family_8')) - da=DataArrayInt([3,12]) ; da.setName("grp0") - self.assertTrue(mm.getGroupArr(1,"grp0").isEqual(da)) - da.setValues([1]) - self.assertTrue(mm.getGroupArr(-1,"grp0").isEqual(da)) - mm.write(fname,2) - mm=MEDFileMesh.New(fname) - self.assertTrue(mm.getGroupArr(1,daTest.getName()).isEqual(daTest)) - self.assertTrue(mm.getFamilyFieldAtLevel(1).isEqual(DataArrayInt([6,2,6,8,2,6,5,6,6,7,7,4,8]))) - for lev,arr in [(0,da0),(-1,da1),(-2,da2)]: - self.assertTrue(mm.getFamilyFieldAtLevel(lev).isEqual(arr)) - pass - self.assertEqual(mm.getFamiliesNames(),('FAMILLE_ZERO','Family_4','Family_5','Family_7','Family_8','MyFam','MyOther-1','MyOtherFam')) - self.assertEqual(mm.getGroupsNames(),('grp0','grp1','grpA')) - self.assertEqual(mm.getFamilyNameGivenId(3),'MyOtherFam') - self.assertEqual(mm.getFamilyNameGivenId(2),'MyFam') - for famName,famId in [('Family_4',4),('Family_5',5),('Family_7',7),('Family_8',8)]: - self.assertEqual(mm.getFamilyNameGivenId(famId),famName) - pass - self.assertEqual(mm.getFamiliesOnGroup("grp0"),('Family_8','MyOtherFam')) - da=DataArrayInt([3,12]) ; da.setName("grp0") - self.assertTrue(mm.getGroupArr(1,"grp0").isEqual(da)) - da.setValues([1]) - self.assertTrue(mm.getGroupArr(-1,"grp0").isEqual(da)) - pass - - def testMEDUMeshAddGroup1(self): - fname="Pyfile54.med" - m=MEDFileUMesh() - coo=DataArrayDouble(9) ; coo.iota(1.) ; coo.rearrange(3) ; coo.setInfoOnComponents(["aaa [b]","cc [dd]", "e [fff]"]) - m0=MEDCouplingUMesh("toto",2) ; m0.allocateCells(0) - for i in xrange(7): - m0.insertNextCell(NORM_TRI3,[1,2,1]) - pass - for i in xrange(4): - m0.insertNextCell(NORM_QUAD4,[1,1,2,0]) - pass - for i in xrange(2): - m0.insertNextCell(NORM_POLYGON,[0,0,1,1,2,2]) - pass - m1=MEDCouplingUMesh("toto",1) ; m1.allocateCells(0) ; m1.insertNextCell(NORM_SEG2,[1,6]) ; m1.insertNextCell(NORM_SEG2,[7,3]) - m2=MEDCouplingUMesh("toto",0) ; m2.allocateCells(0) ; m2.insertNextCell(NORM_POINT1,[2]) ; m2.insertNextCell(NORM_POINT1,[6]) ; m2.insertNextCell(NORM_POINT1,[8]) - m0.setCoords(coo) ; m.setMeshAtLevel(0,m0) - m1.setCoords(coo) ; m.setMeshAtLevel(-1,m1) - m2.setCoords(coo) ; m.setMeshAtLevel(-2,m2) - # - mm=m.deepCpy() - famCoo=DataArrayInt([0,2,0,3,2,0,-1,0,0,0,0,-1,3]) ; mm.setFamilyFieldArr(0,famCoo) - da0=DataArrayInt([0,0,0]) ; mm.setFamilyFieldArr(1,da0) - da1=DataArrayInt([0,3]) ; mm.setFamilyFieldArr(-1,da1) - da2=DataArrayInt([0,0,0]) ; mm.setFamilyFieldArr(-2,da2) - mm.setFamilyId("MyFam",2) - mm.setFamilyId("MyOtherFam",3) - mm.setFamilyId("MyOther-1",-1) - mm.setFamiliesOnGroup("grp0",["MyOtherFam"]) - mm.setFamiliesOnGroup("grpA",["MyOther-1"]) - # - daTest=DataArrayInt([1,3,4,6,9,10,12]) ; daTest.setName("grp1") - mm.addGroup(0,daTest) - self.assertTrue(mm.getGroupArr(0,daTest.getName()).isEqual(daTest)) - self.assertTrue(mm.getFamilyFieldAtLevel(0).isEqual(DataArrayInt([-6,2,-6,-8,2,-6,-5,-6,-6,-7,-7,-4,-8]))) - for lev,arr in [(1,da0),(-1,da1),(-2,da2)]: - self.assertTrue(mm.getFamilyFieldAtLevel(lev).isEqual(arr)) - pass - self.assertEqual(mm.getFamiliesNames(),('Family_-4','Family_-5','Family_-7','Family_-8','MyFam','MyOther-1','MyOtherFam')) - self.assertEqual(mm.getGroupsNames(),('grp0','grp1','grpA')) - self.assertEqual(mm.getFamilyNameGivenId(3),'MyOtherFam') - self.assertEqual(mm.getFamilyNameGivenId(2),'MyFam') - for famName,famId in [('Family_-4',-4),('Family_-5',-5),('Family_-7',-7),('Family_-8',-8)]: - self.assertEqual(mm.getFamilyNameGivenId(famId),famName) - pass - self.assertEqual(mm.getFamiliesOnGroup("grp0"),('MyOtherFam','Family_-8')) - da=DataArrayInt([3,12]) ; da.setName("grp0") - self.assertTrue(mm.getGroupArr(0,"grp0").isEqual(da)) - da.setValues([1]) - self.assertTrue(mm.getGroupArr(-1,"grp0").isEqual(da)) - mm.write(fname,2) - mm=MEDFileMesh.New(fname) - self.assertTrue(mm.getGroupArr(0,daTest.getName()).isEqual(daTest)) - self.assertTrue(mm.getFamilyFieldAtLevel(0).isEqual(DataArrayInt([-6,2,-6,-8,2,-6,-5,-6,-6,-7,-7,-4,-8]))) - for lev,arr in [(1,da0),(-1,da1),(-2,da2)]: - self.assertTrue(mm.getFamilyFieldAtLevel(lev).isEqual(arr)) - pass - self.assertEqual(mm.getFamiliesNames(),('FAMILLE_ZERO','Family_-4','Family_-5','Family_-7','Family_-8','MyFam','MyOther-1','MyOtherFam')) - self.assertEqual(mm.getGroupsNames(),('grp0','grp1','grpA')) - self.assertEqual(mm.getFamilyNameGivenId(3),'MyOtherFam') - self.assertEqual(mm.getFamilyNameGivenId(2),'MyFam') - for famName,famId in [('Family_-4',-4),('Family_-5',-5),('Family_-7',-7),('Family_-8',-8)]: - self.assertEqual(mm.getFamilyNameGivenId(famId),famName) - pass - self.assertEqual(mm.getFamiliesOnGroup("grp0"),('Family_-8','MyOtherFam')) - da=DataArrayInt([3,12]) ; da.setName("grp0") - self.assertTrue(mm.getGroupArr(0,"grp0").isEqual(da)) - da.setValues([1]) - self.assertTrue(mm.getGroupArr(-1,"grp0").isEqual(da)) - pass - - def testHeapMem1(self): - a=DataArrayInt() ; aa=a.getHeapMemorySize() - a.alloc(0,1) - strMulFac=a.getHeapMemorySize()-aa ; del a ; del aa - # - m=MEDCouplingCMesh() - arr=DataArrayDouble(10,1) ; arr.iota(0) - m.setCoords(arr,arr) - m=m.buildUnstructured() - m.setName("mm") - f=m.getMeasureField(ON_CELLS) - self.assertIn(m.getHeapMemorySize(),xrange(3552-100,3552+100+4*strMulFac)) - self.assertIn(f.getHeapMemorySize(),xrange(4215-100,4215+100+8*strMulFac)) - # - mm=MEDFileUMesh() - mm.setMeshAtLevel(0,m) - self.assertIn(mm.getHeapMemorySize(),xrange(3889-100,3889+100+10*strMulFac)) - ff=MEDFileField1TS() - ff.setFieldNoProfileSBT(f) - self.assertIn(ff.getHeapMemorySize(),xrange(771-40,771+21+(4+1)*strMulFac)) - # - fff=MEDFileFieldMultiTS() - fff.appendFieldNoProfileSBT(f) - self.assertIn(fff.getHeapMemorySize(),xrange(815-50,815+30+(6+2)*strMulFac)) - f.setTime(1.,0,-1) - fff.appendFieldNoProfileSBT(f) - self.assertIn(fff.getHeapMemorySize(),xrange(1594-90,1594+50+(10+1)*strMulFac)) - self.assertIn(fff[0,-1].getHeapMemorySize(),xrange(771-40,771+20+(4+1)*strMulFac)) - f2=f[:50] - f2.setTime(2.,1,-1) - pfl=DataArrayInt.Range(0,50,1) ; pfl.setName("pfl") - fff.appendFieldProfile(f2,mm,0,pfl) - self.assertIn(fff.getHeapMemorySize(),xrange(2348-130,2348+100+(10+2)*strMulFac)) - self.assertIn(fff.getProfile("pfl").getHeapMemorySize(),xrange(204-10,204+10+2*strMulFac)) - self.assertIn(fff[1,-1].getHeapMemorySize(),xrange(738-50,738+30+4*strMulFac)) - pass - - def testCurveLinearMesh1(self): - fname="Pyfile55.med" - mesh=MEDCouplingCurveLinearMesh(); - mesh.setTime(2.3,4,5); - mesh.setTimeUnit("us"); - mesh.setName("Example of Cuve linear mesh"); - mesh.setDescription("buildCLMesh"); - a1=DataArrayDouble(3*20,1); - a1.iota(7.) ; a1.rearrange(3); - mesh.setCoords(a1); - mesh.setNodeGridStructure([4,5]); - mesh.checkCoherency(); - # - m=MEDFileCurveLinearMesh() - m.setMesh(mesh) - d=DataArrayInt(20) ; d.iota(4) - m.setFamilyFieldArr(1,d) - d3=DataArrayInt(20) ; d3.iota(400) - m.setRenumFieldArr(1,d3) - d2=DataArrayInt(12) ; d2.iota(40) - m.setFamilyFieldArr(0,d2) - d4=DataArrayInt(21) ; d4.iota(4000) - self.assertRaises(InterpKernelException,m.setRenumFieldArr,1,d4) - d4.popBackSilent() - m.setRenumFieldArr(1,d4) - m.write(fname,2) - # - m1=MEDFileCurveLinearMesh(fname) - mm=m1.getMesh() - self.assertTrue(mm.isEqual(mesh,1e-12)) - self.assertEqual(mm.getSpaceDimension(),3) - self.assertEqual(mm.getSpaceDimensionOnNodeStruct(),2) - # - m1=MEDFileMesh.New(fname) - self.assertTrue(isinstance(m1,MEDFileCurveLinearMesh)) - self.assertTrue(isinstance(m1.getUnivName(),str)) - self.assertTrue(len(m1.getUnivName())!=0) - self.assertTrue(m1.getMesh().isEqual(mesh,1e-12)) - pass - - def testParameters1(self): - fname="Pyfile56.med" - m=MEDCouplingCMesh() ; arr=DataArrayDouble([0.,1.2,3.5]) ; m.setCoords(arr,arr) ; m.setName("mesh") - mm=MEDFileCMesh() ; mm.setMesh(m) - ms=MEDFileMeshes() ; ms.pushMesh(mm) - data=MEDFileData() - p=MEDFileParameters() - data.setParams(p) ; data.setMeshes(ms) - pts=MEDFileParameterMultiTS() - pts.setName("A") ; pts.setDescription("An example of parameter") ; pts.setTimeUnit("ms") - pts.appendValue(1,2,3.4,567.89) - pts.appendValue(2,3,5.6,999.123) - pts2=pts.deepCpy() ; pts2.setName("B") ; pts2.setDescription("A second example") - p.pushParam(pts) ; p.pushParam(pts2) - data.write(fname,2) - p2=MEDFileParameters(fname) - self.assertTrue(p.isEqual(p2,1e-14)[0]) - self.assertAlmostEqual(p[1][1,2].getValue(),567.89,13) - p3=p.deepCpy() - pts4=pts2.deepCpy() - pts3=pts2.deepCpy() - self.assertTrue(pts3.isEqual(pts2,1e-14)[0]) - pts2.eraseTimeStepIds([0]) - self.assertTrue(not pts3.isEqual(pts2,1e-14)[0]) - del pts3[[3.4]] - self.assertTrue(pts3.isEqual(pts2,1e-14)[0]) - self.assertRaises(InterpKernelException,p[1].__getitem__,(1,2)) - self.assertRaises(InterpKernelException,p["B"].__getitem__,(1,2)) - self.assertAlmostEqual(p[0][1,2].getValue(),567.89,13) - self.assertAlmostEqual(p["A"][1,2].getValue(),567.89,13) - p=p3 - self.assertTrue(p.isEqual(p2,1e-14)[0]) - self.assertTrue(p2["B"].isEqual(pts,1e-14)[0]) - self.assertTrue(not p2["B"].isEqual(pts2,1e-14)[0]) - self.assertAlmostEqual(p2[0][1,2].getValue(),567.89,13) - self.assertEqual(p.getParamsNames(),('A','B')) - ptsr=MEDFileParameterMultiTS(fname,"B") - self.assertTrue(ptsr.isEqual(pts4,1e-14)[0]) - ptsr=MEDFileParameterMultiTS(fname) - self.assertTrue(ptsr.isEqual(pts,1e-14)[0]) - p1tsr=MEDFileParameterDouble1TS(fname) - self.assertEqual(p1tsr.getName(),"A") - self.assertAlmostEqual(p1tsr.getValue(),567.89,13) - p1tsr=MEDFileParameterDouble1TS(fname,"B") - self.assertEqual(p1tsr.getName(),"B") - self.assertAlmostEqual(p1tsr.getValue(),567.89,13) - p1tsr=MEDFileParameterDouble1TS(fname,"B",2,3) - self.assertEqual(p1tsr.getName(),"B") - self.assertAlmostEqual(p1tsr.getValue(),999.123,13) - data2=MEDFileData(fname) - self.assertEqual(2,data2.getNumberOfParams()) - self.assertAlmostEqual(data2.getParams()["B"][1,2].getValue(),567.89,13) - pass - - def testNamesOnCellAndNodesInMeshes1(self): - fname="Pyfile58.med" - fname2="Pyfile59.med" - m=MEDLoaderDataForTest.build3DSurfMesh_1() - m1=m.buildDescendingConnectivity()[0] - m1.sortCellsInMEDFileFrmt() - # - mm=MEDFileUMesh() - mm.setMeshAtLevel(0,m) - mm.setMeshAtLevel(-1,m1) - namesCellL0=DataArrayAsciiChar(6,16) - namesCellL0[:]=["CellL0#%.3d "%(i) for i in xrange(6)] - mm.setNameFieldAtLevel(0,namesCellL0) - namesCellL1=DataArrayAsciiChar.Aggregate([namesCellL0,namesCellL0,namesCellL0.substr(2)]) - namesCellL1[:]=["CellLM1#%.3d "%(i) for i in xrange(16)] - mm.setNameFieldAtLevel(-1,namesCellL1) - namesNodes=namesCellL1.substr(4,16) - namesNodes[:]=["Node#%.3d "%(i) for i in xrange(12)] - mm.setNameFieldAtLevel(1,namesNodes) - mm.write(fname,2) - # - mmr=MEDFileMesh.New(fname) - self.assertTrue(mm.getNameFieldAtLevel(0).isEqual(DataArrayAsciiChar(["CellL0#%.3d "%(i) for i in xrange(6)]))) - self.assertTrue(mm.getNameFieldAtLevel(-1).isEqual(DataArrayAsciiChar(["CellLM1#%.3d "%(i) for i in xrange(16)]))) - self.assertTrue(mm.getNameFieldAtLevel(1).isEqual(DataArrayAsciiChar(["Node#%.3d "%(i) for i in xrange(12)]))) - self.assertTrue(mm.isEqual(mmr,1e-12)[0]) - mmr.getNameFieldAtLevel(1).setIJ(0,0,'M') - self.assertTrue(not mm.isEqual(mmr,1e-12)[0]) - mmr.getNameFieldAtLevel(1).setIJ(0,0,'N') - self.assertTrue(mm.isEqual(mmr,1e-12)[0]) - mmCpy=mm.deepCpy() - self.assertTrue(mm.isEqual(mmCpy,1e-12)[0]) - # remove names on nodes - mmCpy.setNameFieldAtLevel(1,None) - self.assertTrue(not mm.isEqual(mmCpy,1e-12)[0]) - mm.setNameFieldAtLevel(1,None) - self.assertTrue(mm.isEqual(mmCpy,1e-12)[0]) - mm.setNameFieldAtLevel(-1,None) - mm.write(fname,2) - mmr=MEDFileMesh.New(fname) - self.assertEqual(mmr.getNameFieldAtLevel(1),None) - self.assertTrue(mmr.getNameFieldAtLevel(0).isEqual(DataArrayAsciiChar(["CellL0#%.3d "%(i) for i in xrange(6)]))) - self.assertEqual(mmr.getNameFieldAtLevel(-1),None) - # - c=MEDCouplingCMesh() - arr=DataArrayDouble([0.,1.1,2.3]) - c.setCoords(arr,arr) - c.setName("cmesh") - cc=MEDFileCMesh() - cc.setMesh(c) - cc.setNameFieldAtLevel(0,DataArrayAsciiChar(["Cell#%.3d "%(i) for i in xrange(4)])) - cc.setNameFieldAtLevel(1,DataArrayAsciiChar(["Node#%.3d "%(i) for i in xrange(9)])) - cc.write(fname2,2) - ccr=MEDFileMesh.New(fname2) - self.assertTrue(ccr.getNameFieldAtLevel(0).isEqual(DataArrayAsciiChar(["Cell#%.3d "%(i) for i in xrange(4)]))) - self.assertTrue(ccr.getNameFieldAtLevel(1).isEqual(DataArrayAsciiChar(["Node#%.3d "%(i) for i in xrange(9)]))) - self.assertTrue(cc.isEqual(ccr,1e-12)[0]) - ccr.getNameFieldAtLevel(1).setIJ(0,0,'M') - self.assertTrue(not cc.isEqual(ccr,1e-12)[0]) - ccr.getNameFieldAtLevel(1).setIJ(0,0,'N') - self.assertTrue(cc.isEqual(ccr,1e-12)[0]) - ccCpy=cc.deepCpy() - self.assertTrue(cc.isEqual(ccCpy,1e-12)[0]) - pass - - def testToExportInExamples1(self): - m=MEDCouplingCMesh() - arr=DataArrayDouble([0.,1.,2.,3.,4.]) - m.setCoords(arr,arr) - m=m.buildUnstructured() ; m.setName("mesh") - grp1=DataArrayInt([0,1,2,4,5,6,8,9,10,12,13,14]) ; grp1.setName("grp1") - grp2=DataArrayInt([3,7,11,15]) ; grp2.setName("grp2") - m2=m.computeSkin() - mm=MEDFileUMesh() - mm.setMeshAtLevel(0,m) - mm.setMeshAtLevel(-1,m2) - mm.setGroupsAtLevel(0,[grp1,grp2]) - mm.write("example.med",2) - # - m0=mm.getMeshAtLevel(0) - m1=mm.getMeshAtLevel(-1) - grp1=mm.getGroupArr(0,"grp1") - grp2=mm.getGroupArr(0,"grp2") - grps=[grp1,grp2] - whichGrp=DataArrayInt(m0.getNumberOfCells()) - whichGrp.fillWithValue(-1) - for grpId,grp in enumerate(grps): - whichGrp[grp]=grpId - pass - a,b,bI,c,cI=m0.buildDescendingConnectivity() - e,f=a.areCellsIncludedIn(m1,2) - self.assertTrue(e) - c2,c2I=MEDCouplingUMesh.ExtractFromIndexedArrays(f,c,cI) - self.assertTrue(c2I.deltaShiftIndex().isUniform(1)) - c2.transformWithIndArr(whichGrp) - splitOfM1=len(grps)*[None] - for grpId,grp in enumerate(grps): - tmp=c2.getIdsEqual(grpId) - splitOfM1[grpId]=tmp - pass - splitOfM1[0].isEqual(DataArrayInt([0,1,2,3,6,8,10,11,12,13])) - splitOfM1[1].isEqual(DataArrayInt([4,5,7,9,14,15])) - pass - - def testBugCorrection1(self): - fs=MEDFileFields() - fs.resize(3) - self.assertEqual(fs[0],None) - self.assertEqual(3,len(fs)) - pass - - def testCompareMEDFilesContainingOnlyFieldsOnCell1(self): - f1Name="Pyfile60.med" - f2Name="Pyfile61.med" - d1=MEDLoaderDataForTest.buildACompleteMEDDataStructureWithFieldsOnCells_1() - d1.write(f1Name,2) - d2=MEDLoaderDataForTest.buildACompleteMEDDataStructureWithFieldsOnCells_1() - d2.write(f2Name,2) - # reading and compare - d1=MEDFileData(f1Name) ; d2=MEDFileData(f2Name) - for mn in d1.getMeshes().getMeshesNames(): - m1=d1.getMeshes()[mn] - m2=d2.getMeshes()[mn] - for lev in m1.getNonEmptyLevels(): - grpsNames=m1.getGroupsOnSpecifiedLev(lev) - for grpName in grpsNames: - self.assertTrue(m1.getGroupArr(lev,grpName).isEqual(m2.getGroupArr(lev,grpName))) # compare groups - pass - pass - pass - for fieldn in d1.getFields().getFieldsNames(): - f1=d1.getFields()[fieldn] - f2=d2.getFields()[fieldn] - for it,order,tim in f1.getTimeSteps(): - f1t=f1[it,order] - f2t=f2[it,order] - if len(f1t.getPflsReallyUsed())!=0: - # profile case - for lev in f1t.getNonEmptyLevels()[1]: - arr1,pfl1=f1t.getFieldWithProfile(ON_CELLS,lev,m1) - arr2,pfl2=f2t.getFieldWithProfile(ON_CELLS,lev,m2) - self.assertTrue(pfl1.isEqual(pfl2)) - self.assertTrue(arr1.isEqual(arr2,1e-10)) - pass - pass - else: - # no profile case - for lev in f1t.getNonEmptyLevels()[1]: - f1mc=f1t.getFieldOnMeshAtLevel(ON_CELLS,lev,m1) - f2mc=f2t.getFieldOnMeshAtLevel(ON_CELLS,lev,m2) - self.assertTrue(f1mc.isEqual(f2mc,1e-10,1e-10)) - pass - pass - pass - pass - pass - - def testNonRegBugNormalizeFamIdsMEDFile1(self): - m=MEDCouplingCMesh() - arr=DataArrayDouble([0.,1.,2.,3.,4.]) - m.setCoords(arr,arr,arr) - m=m.buildUnstructured() - m2=m.buildDescendingConnectivity()[0] - m.setName("mesh") - g1=DataArrayInt([0,1,2,3]) ; g1.setName("g1") - g2=DataArrayInt([2,3,5,6]) ; g2.setName("g2") - g1Face=DataArrayInt([20,21,22,23]) ; g1Face.setName("g1Face") - g2Face=DataArrayInt([22,23,25,26]) ; g2Face.setName("g2Face") - g1Node=DataArrayInt([10,11,12,13]) ; g1Node.setName("g1Node") - g2Node=DataArrayInt([12,13,15,16]) ; g2Node.setName("g2Node") - mm=MEDFileUMesh() - mm.setMeshAtLevel(0,m) - mm.setGroupsAtLevel(0,[g1,g2]) - s1=set(mm.getFamiliesOnGroup("g1")) ; s2=set(mm.getFamiliesOnGroup("g2")) - self.assertEqual(mm.getGrpNonEmptyLevelsExt("g1"),(0,)) - self.assertEqual(mm.getGrpNonEmptyLevelsExt("g2"),(0,)) - mm.normalizeFamIdsMEDFile() - self.assertEqual(mm.getGrpNonEmptyLevelsExt("g1"),(0,)) - self.assertEqual(mm.getGrpNonEmptyLevelsExt("g2"),(0,)) - self.assertTrue(mm.getGroupArr(0,"g1").isEqual(g1)) - self.assertTrue(mm.getGroupArr(0,"g2").isEqual(g2)) - self.assertEqual(s1,set(mm.getFamiliesOnGroup("g1"))) - self.assertEqual(s2,set(mm.getFamiliesOnGroup("g2"))) - for g in mm.getGroupsOnSpecifiedLev(0): - for f in mm.getFamiliesIdsOnGroup(g): - self.assertTrue(f<0) - pass - pass - # - mm=MEDFileUMesh() - mm.setMeshAtLevel(0,m) - mm.setMeshAtLevel(-1,m2) - mm.setGroupsAtLevel(0,[g1,g2]) - mm.setGroupsAtLevel(-1,[g1Face,g2Face]) - s1=set(mm.getFamiliesOnGroup("g1")) ; s2=set(mm.getFamiliesOnGroup("g2")) - s3=set(mm.getFamiliesOnGroup("g1Face")) ; s4=set(mm.getFamiliesOnGroup("g2Face")) - self.assertEqual(mm.getGrpNonEmptyLevelsExt("g1"),(0,)) - self.assertEqual(mm.getGrpNonEmptyLevelsExt("g2"),(0,)) - self.assertEqual(mm.getGrpNonEmptyLevelsExt("g1Face"),(-1,)) - self.assertEqual(mm.getGrpNonEmptyLevelsExt("g2Face"),(-1,)) - mm.normalizeFamIdsMEDFile() - self.assertEqual(mm.getGrpNonEmptyLevelsExt("g1"),(0,)) - self.assertEqual(mm.getGrpNonEmptyLevelsExt("g2"),(0,)) - self.assertEqual(mm.getGrpNonEmptyLevelsExt("g1Face"),(-1,)) - self.assertEqual(mm.getGrpNonEmptyLevelsExt("g2Face"),(-1,)) - self.assertTrue(mm.getGroupArr(0,"g1").isEqual(g1)) - self.assertTrue(mm.getGroupArr(0,"g2").isEqual(g2)) - self.assertTrue(mm.getGroupArr(-1,"g1Face").isEqual(g1Face)) - self.assertTrue(mm.getGroupArr(-1,"g2Face").isEqual(g2Face)) - self.assertEqual(s1,set(mm.getFamiliesOnGroup("g1"))) - self.assertEqual(s2,set(mm.getFamiliesOnGroup("g2"))) - self.assertEqual(s3,set(mm.getFamiliesOnGroup("g1Face"))) - self.assertEqual(s4,set(mm.getFamiliesOnGroup("g2Face"))) - for lev in [0,-1]: - for g in mm.getGroupsOnSpecifiedLev(lev): - for f in mm.getFamiliesIdsOnGroup(g): - self.assertTrue(f<0) - pass - pass - pass - # - mm=MEDFileUMesh() - mm.setMeshAtLevel(0,m) - mm.setMeshAtLevel(-1,m2) - mm.setGroupsAtLevel(0,[g1,g2]) - mm.setGroupsAtLevel(-1,[g1Face,g2Face]) - mm.setGroupsAtLevel(1,[g1Node,g2Node]) - s1=set(mm.getFamiliesOnGroup("g1")) ; s2=set(mm.getFamiliesOnGroup("g2")) - s3=set(mm.getFamiliesOnGroup("g1Face")) ; s4=set(mm.getFamiliesOnGroup("g2Face")) - s5=set(mm.getFamiliesOnGroup("g1Node")) ; s6=set(mm.getFamiliesOnGroup("g2Node")) - self.assertEqual(mm.getGrpNonEmptyLevelsExt("g1"),(0,)) - self.assertEqual(mm.getGrpNonEmptyLevelsExt("g2"),(0,)) - self.assertEqual(mm.getGrpNonEmptyLevelsExt("g1Face"),(-1,)) - self.assertEqual(mm.getGrpNonEmptyLevelsExt("g2Face"),(-1,)) - self.assertEqual(mm.getGrpNonEmptyLevelsExt("g1Node"),(1,)) - self.assertEqual(mm.getGrpNonEmptyLevelsExt("g2Node"),(1,)) - mm.normalizeFamIdsMEDFile() - self.assertEqual(mm.getGrpNonEmptyLevelsExt("g1"),(0,)) - self.assertEqual(mm.getGrpNonEmptyLevelsExt("g2"),(0,)) - self.assertEqual(mm.getGrpNonEmptyLevelsExt("g1Face"),(-1,)) - self.assertEqual(mm.getGrpNonEmptyLevelsExt("g2Face"),(-1,)) - self.assertEqual(mm.getGrpNonEmptyLevelsExt("g1Node"),(1,)) - self.assertEqual(mm.getGrpNonEmptyLevelsExt("g2Node"),(1,)) - self.assertTrue(mm.getGroupArr(0,"g1").isEqual(g1)) - self.assertTrue(mm.getGroupArr(0,"g2").isEqual(g2)) - self.assertTrue(mm.getGroupArr(-1,"g1Face").isEqual(g1Face)) - self.assertTrue(mm.getGroupArr(-1,"g2Face").isEqual(g2Face)) - self.assertTrue(mm.getGroupArr(1,"g1Node").isEqual(g1Node)) - self.assertTrue(mm.getGroupArr(1,"g2Node").isEqual(g2Node)) - self.assertEqual(s1,set(mm.getFamiliesOnGroup("g1"))) - self.assertEqual(s2,set(mm.getFamiliesOnGroup("g2"))) - self.assertEqual(s3,set(mm.getFamiliesOnGroup("g1Face"))) - self.assertEqual(s4,set(mm.getFamiliesOnGroup("g2Face"))) - self.assertEqual(s5,set(mm.getFamiliesOnGroup("g1Node"))) - self.assertEqual(s6,set(mm.getFamiliesOnGroup("g2Node"))) - for lev in [0,-1]: - for g in mm.getGroupsOnSpecifiedLev(lev): - for f in mm.getFamiliesIdsOnGroup(g): - self.assertTrue(f<0) - pass - pass - pass - for g in mm.getGroupsOnSpecifiedLev(1): - for f in mm.getFamiliesIdsOnGroup(g): - self.assertTrue(f>0) - pass - pass - pass - - def testNonRegressionMantis22212ChangeGrpName(self): - fileName="Pyfile62.med" - m2,m1,m0,f2,f1,f0,p,n2,n1,n0,fns,fids,grpns,famIdsPerGrp=MEDLoaderDataForTest.buildMultiLevelMesh_1() - m=MEDFileUMesh.New() - m.setCoords(m2.getCoords()) - m.setMeshAtLevel(0,m2) - m.setMeshAtLevel(-1,m1) - m.setMeshAtLevel(-2,m0) - m.setFamilyFieldArr(0,f2) - m.setFamilyFieldArr(-1,f1) - m.setFamilyFieldArr(-2,f0) - m.setFamilyFieldArr(1,p) - nbOfFams=len(fns) - for i in xrange(nbOfFams): - m.addFamily(fns[i],fids[i]) - pass - nbOfGrps=len(grpns) - for i in xrange(nbOfGrps): - m.setFamiliesIdsOnGroup(grpns[i],famIdsPerGrp[i]) - pass - m.setName(m2.getName()) - m.setDescription(m2.getDescription()) - m.write(fileName,2) - # - mm0=MEDFileMesh.New(fileName) - mm1=MEDFileMesh.New(fileName) - groupNamesIni=MEDLoader.GetMeshGroupsNames(fileName,"ma") - for name in groupNamesIni: - mm1.changeGroupName(name,name+'N') - pass - mm1.write(fileName,2) - del mm1 - # - mm2=MEDFileMesh.New(fileName) - for name in groupNamesIni: - for lev in mm0.getGrpNonEmptyLevelsExt(name): - arr0=mm0.getGroupArr(lev,name) - arr2=mm2.getGroupArr(lev,name+'N') - arr0.setName(name+'N') - self.assertTrue(arr0.isEqual(arr2)) - pass - pass - pass - - def testInt32InMEDFileFieldStar1(self): - fname="Pyfile63.med" - f1=MEDLoaderDataForTest.buildVecFieldOnCells_1(); - arr=f1.getArray().convertToIntArr() - f1.setArray(None) - m1=f1.getMesh() - mm1=MEDFileUMesh.New() - mm1.setCoords(m1.getCoords()) - mm1.setMeshAtLevel(0,m1) - mm1.setName(m1.getName()) - mm1.write(fname,2) - ff1=MEDFileIntField1TS() - ff1.setFieldNoProfileSBT(f1,arr) - a,b=ff1.getFieldOnMeshAtLevel(0,ON_CELLS,mm1) - self.assertEqual(b.getInfoOnComponents(),['power [MW/m^3]','density [g/cm^3]','temperature [K]']) - self.assertTrue(b.isEqual(arr)) - self.assertTrue(a.isEqual(f1,1e-12,1e-12)) - ff1.write(fname,0) - ff2=MEDFileAnyTypeField1TS.New(fname) - self.assertEqual(ff2.getName(),"VectorFieldOnCells") - self.assertEqual(ff2.getTime(),[0,1,2.0]) - self.assertTrue(isinstance(ff2,MEDFileIntField1TS)) - a,b=ff1.getFieldOnMeshAtLevel(0,ON_CELLS,mm1) - self.assertEqual(b.getInfoOnComponents(),['power [MW/m^3]','density [g/cm^3]','temperature [K]']) - self.assertTrue(b.isEqual(arr)) - self.assertTrue(a.isEqual(f1,1e-12,1e-12)) - ff2.setTime(1,2,3.) - c=ff2.getUndergroundDataArray() ; c*=2 - ff2.write(fname,0) # 2 time steps in - ffs1=MEDFileAnyTypeFieldMultiTS.New(fname,"VectorFieldOnCells") - self.assertEqual(ffs1.getTimeSteps(),[(0, 1, 2.0), (1, 2, 3.0)]) - self.assertEqual(len(ffs1),2) - self.assertTrue(isinstance(ffs1,MEDFileIntFieldMultiTS)) - a,b=ffs1[2.].getFieldOnMeshAtLevel(0,ON_CELLS,mm1) - self.assertTrue(b.isEqual(arr)) - self.assertTrue(a.isEqual(f1,1e-12,1e-12)) - a,b=ffs1[2.].getFieldOnMeshAtLevel(0,ON_CELLS,mm1) - self.assertTrue(b.isEqual(arr)) - self.assertTrue(a.isEqual(f1,1e-12,1e-12)) - it=ffs1.__iter__() ; it.next() ; ff2bis=it.next() - a,b=ff2bis.getFieldOnMeshAtLevel(0,ON_CELLS,mm1) - self.assertTrue(b.isEqual(2*arr)) - f1.setTime(3.,1,2) - self.assertTrue(a.isEqual(f1,1e-12,1e-12)) - bc=DataArrayInt(6,3) ; bc[:]=0 ; bc.setInfoOnComponents(['power [MW/m^3]','density [g/cm^3]','temperature [K]']) - for it in ffs1: - a,b=it.getFieldOnMeshAtLevel(0,ON_CELLS,mm1) - bc+=b - pass - self.assertTrue(bc.isEqual(3*arr)) - nf1=MEDCouplingFieldDouble(ON_NODES) - nf1.setTime(9.,10,-1) - nf1.setMesh(f1.getMesh()) - narr=DataArrayInt(12,2) ; narr.setInfoOnComponents(["aa [u1]","bbbvv [ppp]"]) ; narr[:,0]=range(12) ; narr[:,1]=2*narr[:,0] - nf1.setName("VectorFieldOnNodes") - nff1=MEDFileIntField1TS.New() - nff1.setFieldNoProfileSBT(nf1,narr) - self.assertEqual(nff1.getInfo(),('aa [u1]','bbbvv [ppp]')) - self.assertEqual(nff1.getTime(),[10,-1,9.0]) - nff1.write(fname,0) - # - nf2=MEDCouplingFieldDouble(ON_NODES) - nf2.setTime(19.,20,-11) - nf2.setMesh(f1.getMesh()) - narr2=DataArrayInt(8,2) ; narr.setInfoOnComponents(["aapfl [u1]","bbbvvpfl [ppp]"]) ; narr2[:,0]=range(8) ; narr2[:,0]+=10 ; narr2[:,1]=3*narr2[:,0] - nf2.setName("VectorFieldOnNodesPfl") ; narr2.setName(nf2.getName()) - nff2=MEDFileIntField1TS.New() - npfl=DataArrayInt([1,2,4,5,6,7,10,11]) ; npfl.setName("npfl") - nff2.setFieldProfile(nf2,narr2,mm1,0,npfl) - nff2.getFieldWithProfile(ON_NODES,0,mm1) - a,b=nff2.getFieldWithProfile(ON_NODES,0,mm1) ; b.setName(npfl.getName()) - self.assertTrue(b.isEqual(npfl)) - self.assertTrue(a.isEqual(narr2)) - nff2.write(fname,0) - nff2bis=MEDFileIntField1TS(fname,"VectorFieldOnNodesPfl") - a,b=nff2bis.getFieldWithProfile(ON_NODES,0,mm1) ; b.setName(npfl.getName()) - self.assertTrue(b.isEqual(npfl)) - self.assertTrue(a.isEqual(narr2)) - # - nf3=MEDCouplingFieldDouble(ON_NODES) - nf3.setName("VectorFieldOnNodesDouble") - nf3.setTime(29.,30,-21) - nf3.setMesh(f1.getMesh()) - nf3.setArray(f1.getMesh().getCoords()) - nff3=MEDFileField1TS.New() - nff3.setFieldNoProfileSBT(nf3) - nff3.write(fname,0) - fs=MEDFileFields(fname) - self.assertEqual(len(fs),4) - ffs=[it for it in fs] - self.assertTrue(isinstance(ffs[0],MEDFileIntFieldMultiTS)) - self.assertTrue(isinstance(ffs[1],MEDFileIntFieldMultiTS)) - self.assertTrue(isinstance(ffs[2],MEDFileFieldMultiTS)) - self.assertTrue(isinstance(ffs[3],MEDFileIntFieldMultiTS)) - # - self.assertTrue(fs["VectorFieldOnCells"][0].getUndergroundDataArray().isEqualWithoutConsideringStr(arr)) - self.assertTrue(fs["VectorFieldOnCells"][1,2].getUndergroundDataArray().isEqualWithoutConsideringStr(2*arr)) - self.assertTrue(fs["VectorFieldOnNodesPfl"][0].getUndergroundDataArray().isEqualWithoutConsideringStr(narr2)) - self.assertTrue(fs["VectorFieldOnNodes"][9.].getUndergroundDataArray().isEqualWithoutConsideringStr(narr)) - self.assertTrue(fs["VectorFieldOnNodesDouble"][29.].getUndergroundDataArray().isEqualWithoutConsideringStr(f1.getMesh().getCoords(),1e-12)) - # - nf3_read=MEDFileFieldMultiTS(fname,"VectorFieldOnNodesDouble") - self.assertTrue(nf3_read[29.].getUndergroundDataArray().isEqualWithoutConsideringStr(f1.getMesh().getCoords(),1e-12)) - self.assertRaises(InterpKernelException,MEDFileIntFieldMultiTS.New,fname,"VectorFieldOnNodesDouble")# exception because trying to read a double field with int instance - self.assertRaises(InterpKernelException,MEDFileFieldMultiTS.New,fname,"VectorFieldOnNodes")# exception because trying to read a int field with double instance - MEDFileField1TS.New(fname,"VectorFieldOnNodesDouble",30,-21) - self.assertRaises(InterpKernelException,MEDFileIntField1TS.New,fname,"VectorFieldOnNodesDouble",30,-21)# exception because trying to read a double field with int instance - MEDFileIntField1TS.New(fname,"VectorFieldOnNodes",10,-1) - self.assertRaises(InterpKernelException,MEDFileField1TS.New,fname,"VectorFieldOnNodes",10,-1)# exception because trying to read a double field with int instance - # - self.assertEqual(fs.getMeshesNames(),('3DSurfMesh_1','3DSurfMesh_1','3DSurfMesh_1','3DSurfMesh_1')) - self.assertTrue(fs.changeMeshNames([('3DSurfMesh_1','3DSurfMesh')])) - self.assertEqual(fs.getMeshesNames(),('3DSurfMesh','3DSurfMesh','3DSurfMesh','3DSurfMesh')) - self.assertTrue(not fs.changeMeshNames([('3DSurfMesh_1','3DSurfMesh')])) - pass - - def testMEDFileFields1(self): - fname="Pyfile64.med" - f1=MEDCouplingFieldDouble(ON_NODES) - f1.setTime(0.001,0,-1) ; f1.setTimeUnit("us") - c=DataArrayDouble(12) ; c.iota(); m=MEDCouplingCMesh() ; m.setCoordsAt(0,c) ; m.setName("mesh") - mm=MEDFileCMesh() ; mm.setMesh(m) ; mm.write(fname,2) - f1.setMesh(m) - arr=DataArrayDouble(12,2) ; arr.setInfoOnComponents(["aa [u1]","bbbvv [ppp]"]) ; arr[:,0]=range(12) ; arr[:,1]=2*arr[:,0] - f1.setArray(arr) - f1.setName("Field1") - ff1=MEDFileField1TS.New() - ff1.setFieldNoProfileSBT(f1) - self.assertEqual(ff1.getDtUnit(),"us") - ff1.write(fname,0) - f1.setTime(1.001,1,-1) ; ff1=MEDFileField1TS.New() ; ff1.setFieldNoProfileSBT(f1) ; ff1.write(fname,0) - f1.setTime(2.001,2,-1) ; ff1=MEDFileField1TS.New() ; ff1.setFieldNoProfileSBT(f1) ; ff1.write(fname,0) - # - self.assertEqual(MEDFileFields(fname).getCommonIterations(),([(0,-1),(1,-1),(2,-1)],False)) - ff1s=MEDFileFieldMultiTS(fname,"Field1") - ff1s.setName("Field2") - ff1s.write(fname,0) - self.assertEqual(MEDFileFields(fname).getCommonIterations(),([(0,-1),(1,-1),(2,-1)],False)) - f1.setTime(3.001,3,-1) ; ff1=MEDFileField1TS.New() ; ff1.setFieldNoProfileSBT(f1) ; ff1.write(fname,0) - self.assertEqual(MEDFileFields(fname).getCommonIterations(),([(0,-1),(1,-1),(2,-1)],True)) - self.assertEqual(MEDFileFields(fname).partOfThisLyingOnSpecifiedTimeSteps([(1,-1)]).getCommonIterations(),([(1,-1)],False)) - self.assertEqual(MEDFileFields(fname).partOfThisNotLyingOnSpecifiedTimeSteps([(1,-1)]).getCommonIterations(),([(0,-1),(2,-1)],True)) - f1.setName("Field2") ; f1.setTime(3.001,3,-1) ; ff1=MEDFileField1TS.New() ; ff1.setFieldNoProfileSBT(f1) ; ff1.write(fname,0) - self.assertEqual(MEDFileFields(fname).getCommonIterations(),([(0,-1),(1,-1),(2,-1),(3,-1)],False)) - self.assertEqual(MEDFileFields(fname)[1].getDtUnit(),"us") - pass - - # Multi time steps and multi fields management without Globals (profiles, locs) aspects - def testMEDFileFields2(self): - fname="Pyfile65.med" - # to check that all is initialize - MEDFileField1TS().__str__() - MEDFileFieldMultiTS().__str__() - # building a mesh containing 4 tri3 + 5 quad4 - tri=MEDCouplingUMesh("tri",2) - tri.allocateCells() ; tri.insertNextCell(NORM_TRI3,[0,1,2]) - tri.setCoords(DataArrayDouble([(0.,0.),(0.,1.),(1.,0.)])) - tris=[tri.deepCpy() for i in xrange(4)] - for i,elt in enumerate(tris): elt.translate([i,0]) - tris=MEDCouplingUMesh.MergeUMeshes(tris) - quad=MEDCouplingUMesh("quad",2) - quad.allocateCells() ; quad.insertNextCell(NORM_QUAD4,[0,1,2,3]) - quad.setCoords(DataArrayDouble([(0.,0.),(0.,1.),(1.,1.),(1.,0.)])) - quads=[quad.deepCpy() for i in xrange(5)] - for i,elt in enumerate(quads): elt.translate([5+i,0]) - quads=MEDCouplingUMesh.MergeUMeshes(quads) - m=MEDCouplingUMesh.MergeUMeshes(tris,quads) - m.setName("mesh") ; m.getCoords().setInfoOnComponents(["XX [m]","YYY [km]"]) - # - fmts0_0=MEDFileFieldMultiTS() - fmts0_1=MEDFileFieldMultiTS() - # time steps - for i in xrange(10): - infos1=["aa [bb]","ccc [ddd]"] ; name1="1stField" - d=DataArrayDouble(18) ; d.iota(i*10) ; d.rearrange(2) ; d.setInfoOnComponents(infos1) - f=MEDCouplingFieldDouble(ON_CELLS) ; f.setName(name1) ; f.setArray(d) ; f.setMesh(m) - f.setTime(float(i+1)+0.1,i+1,-i-1) - fmts0_0.appendFieldNoProfileSBT(f) - f1ts=MEDFileField1TS() ; f1ts.setFieldNoProfileSBT(f) ; fmts0_1.pushBackTimeStep(f1ts) - self.assertEqual(fmts0_1.getName(),name1) - self.assertEqual(fmts0_0.getInfo(),('aa [bb]','ccc [ddd]')) - self.assertEqual(fmts0_1.getInfo(),('aa [bb]','ccc [ddd]')) - if i>1: - # components names have been modified to generate errors - d.setInfoOnComponents(['aa [bb]','eee [dd]']) - self.assertRaises(InterpKernelException,fmts0_0.appendFieldNoProfileSBT,f) - self.assertRaises(InterpKernelException,f1ts.setInfo,['aa [bb]'])#throw because mismatch of number of components - f1ts.setInfo(['aa [bb]','eee [dd]']) - self.assertRaises(InterpKernelException,fmts0_1.pushBackTimeStep,f1ts) - pass - # add a mismatch of nb of compos - pass - fmts0_2=fmts0_0.deepCpy() - fmts0_3=fmts0_0.deepCpy() - fmts0_4=fmts0_0.deepCpy() - fmts0_5=fmts0_0.shallowCpy() - self.assertTrue(len(fmts0_0)==10 and len(fmts0_1)==10 and len(fmts0_2)==10 and len(fmts0_3)==10 and len(fmts0_4)==10 and len(fmts0_5)==10) - del fmts0_2[::2] - self.assertTrue(len(fmts0_2)==5 and fmts0_2.getIterations()==[(2,-2),(4,-4),(6,-6),(8,-8),(10,-10)]) - del fmts0_3[[1.1,(6,-6),9]] - self.assertTrue(len(fmts0_3)==7 and fmts0_3.getIterations()==[(2,-2),(3,-3),(4,-4),(5,-5),(7,-7),(8,-8),(9,-9)]) - fmts0_6=fmts0_4[[1.1,(6,-6),8]] - self.assertTrue(isinstance(fmts0_6,MEDFileFieldMultiTS)) - self.assertTrue(len(fmts0_6)==3 and fmts0_6.getIterations()==[(1,-1),(6,-6),(9,-9)]) - fmts0_7=fmts0_4[::-3] - self.assertTrue(isinstance(fmts0_7,MEDFileFieldMultiTS)) - self.assertTrue(len(fmts0_7)==4 and fmts0_7.getIterations()==[(10,-10),(7,-7),(4,-4),(1,-1)]) - # - fs0=MEDFileFields() - fs0.pushField(fmts0_0) - fmts0_2.setName("2ndField") ; fs0.pushField(fmts0_2) - fmts0_3.setName("3rdField") ; fs0.pushField(fmts0_3) - fmts0_4.setName("4thField") ; fs0.pushField(fmts0_4) - self.assertTrue(len(fs0)==4 and fs0.getFieldsNames()==('1stField','2ndField','3rdField','4thField')) - fs0.write(fname,2) - fs0=MEDFileFields(fname) - self.assertEqual(fs0.getCommonIterations(),([(2,-2),(4,-4),(8,-8)],True)) - fs1=fs0.partOfThisLyingOnSpecifiedTimeSteps(fs0.getCommonIterations()[0]) - self.assertTrue(fs1.getFieldsNames()==('1stField','2ndField','3rdField','4thField') and fs1.getCommonIterations()==([(2,-2),(4,-4),(8,-8)],False)) - del fs1[["2ndField",3]] - self.assertTrue(fs1.getFieldsNames()==('1stField','3rdField') and fs1.getCommonIterations()==([(2,-2),(4,-4),(8,-8)],False)) - fs2=fs0[[0,"4thField"]] - self.assertTrue(isinstance(fs2,MEDFileFields)) - self.assertEqual(fs2.getFieldsNames(),('1stField','4thField')) - # - mm=MEDFileUMesh() ; mm.setMeshAtLevel(0,m) ; mm.write(fname,0) - pass - - # Multi time steps and multi fields management with Globals (profiles, locs) aspects - def testMEDFileFields3(self): - fname="Pyfile66.med" - # building a mesh containing 4 tri3 + 5 quad4 - tri=MEDCouplingUMesh("tri",2) - tri.allocateCells() ; tri.insertNextCell(NORM_TRI3,[0,1,2]) - tri.setCoords(DataArrayDouble([(0.,0.),(0.,1.),(1.,0.)])) - tris=[tri.deepCpy() for i in xrange(4)] - for i,elt in enumerate(tris): elt.translate([i,0]) - tris=MEDCouplingUMesh.MergeUMeshes(tris) - quad=MEDCouplingUMesh("quad",2) - quad.allocateCells() ; quad.insertNextCell(NORM_QUAD4,[0,1,2,3]) - quad.setCoords(DataArrayDouble([(0.,0.),(0.,1.),(1.,1.),(1.,0.)])) - quads=[quad.deepCpy() for i in xrange(5)] - for i,elt in enumerate(quads): elt.translate([5+i,0]) - quads=MEDCouplingUMesh.MergeUMeshes(quads) - m=MEDCouplingUMesh.MergeUMeshes(tris,quads) - m.setName("mesh") ; m.getCoords().setInfoOnComponents(["XX [m]","YYY [km]"]) - # - mm=MEDFileUMesh() ; mm.setMeshAtLevel(0,m) ; mm.write(fname,2) - # - pfl=DataArrayInt([0,1,2,3,4,5,6]) ; pfl.setName("pfl") - pfl2=DataArrayInt([0,1,2,3,4,5,6,8]) ; pfl2.setName("pfl2") - fmts0_0=MEDFileFieldMultiTS() - fmts0_1=MEDFileFieldMultiTS() - # time steps - for i in xrange(10): - infos1=["aa [bb]","ccc [ddd]"] ; name1="1stField" - d=DataArrayDouble(14) ; d.iota(i*10) ; d.rearrange(2) ; d.setInfoOnComponents(infos1) - f=MEDCouplingFieldDouble(ON_CELLS) ; f.setName(name1) ; f.setArray(d) ; f.setMesh(m) - f.setTime(float(i+1)+0.1,i+1,-i-1) - fmts0_0.appendFieldProfile(f,mm,0,pfl) - f1ts=MEDFileField1TS() ; f1ts.setFieldProfile(f,mm,0,pfl) ; fmts0_1.pushBackTimeStep(f1ts) - self.assertEqual(fmts0_0.getInfo(),('aa [bb]','ccc [ddd]')) - self.assertEqual(fmts0_1.getInfo(),('aa [bb]','ccc [ddd]')) - pass - # - self.assertEqual(fmts0_0.getPfls(),10*('pfl_NORM_QUAD4',)) - self.assertEqual(fmts0_1.getPfls(),('pfl_NORM_QUAD4',)) - fmts0_0.zipPflsNames() - self.assertEqual(fmts0_0.getPfls(),('pfl_NORM_QUAD4',)) - self.assertTrue(fmts0_1.getProfile("pfl_NORM_QUAD4").isEqual(fmts0_0.getProfile("pfl_NORM_QUAD4"))) - fmts0_2=fmts0_0.deepCpy() - fmts0_3=fmts0_0.deepCpy() - fmts0_4=fmts0_0.deepCpy() - fs0=MEDFileFields() - fs0.pushField(fmts0_0) - fmts0_2.setName("2ndField") ; fs0.pushField(fmts0_2) - fmts0_3.setName("3rdField") ; fs0.pushField(fmts0_3) - fmts0_4.setName("4thField") ; fs0.pushField(fmts0_4) - self.assertEqual(fs0.getPfls(),('pfl_NORM_QUAD4',)) - # - fmts0_5=MEDFileFieldMultiTS() - for i in xrange(7): - infos1=["aa [bb]","ccc [ddd]"] ; name1="1stField" - d=DataArrayDouble(16) ; d.iota(i*10) ; d.rearrange(2) ; d.setInfoOnComponents(infos1) - f=MEDCouplingFieldDouble(ON_CELLS) ; f.setName(name1) ; f.setArray(d) ; f.setMesh(m) - f.setTime(float(i+1)+0.1,i+1,-i-1) - f1ts=MEDFileField1TS() ; f1ts.setFieldProfile(f,mm,0,pfl2) ; fmts0_5.pushBackTimeStep(f1ts) - pass - fmts0_5.setName("5thField") ; fs0.pushField(fmts0_5) - self.assertEqual(fs0.getPfls(),('pfl_NORM_QUAD4','pfl2_NORM_QUAD4')) - fs0.checkGlobsCoherency() - fs0.write(fname,0) - pass - - def testSplitComponents1(self): - fname="Pyfile67.med" - # building a mesh containing 4 tri3 + 5 quad4 - tri=MEDCouplingUMesh("tri",2) - tri.allocateCells() ; tri.insertNextCell(NORM_TRI3,[0,1,2]) - tri.setCoords(DataArrayDouble([(0.,0.),(0.,1.),(1.,0.)])) - tris=[tri.deepCpy() for i in xrange(4)] - for i,elt in enumerate(tris): elt.translate([i,0]) - tris=MEDCouplingUMesh.MergeUMeshes(tris) - quad=MEDCouplingUMesh("quad",2) - quad.allocateCells() ; quad.insertNextCell(NORM_QUAD4,[0,1,2,3]) - quad.setCoords(DataArrayDouble([(0.,0.),(0.,1.),(1.,1.),(1.,0.)])) - quads=[quad.deepCpy() for i in xrange(5)] - for i,elt in enumerate(quads): elt.translate([5+i,0]) - quads=MEDCouplingUMesh.MergeUMeshes(quads) - m=MEDCouplingUMesh.MergeUMeshes(tris,quads) - m.setName("mesh") ; m.getCoords().setInfoOnComponents(["XX [m]","YYY [km]"]) - # - mm=MEDFileUMesh() ; mm.setMeshAtLevel(0,m) ; mm.write(fname,2) - # - pfl=DataArrayInt([0,1,2,3,4,5,6]) ; pfl.setName("pfl") - pfl2=DataArrayInt([0,1,2,3,4,5,6,8]) ; pfl2.setName("pfl2") - fs=MEDFileFields() - fmts0_1=MEDFileFieldMultiTS() - # time steps - infos1=['aa [bb]','ccc [ddd]',"ZZZZ [MW*s]"] - for i in xrange(10): - name1="1stField" - d=DataArrayDouble(21) ; d.iota(i*10) ; d.rearrange(3) ; d.setInfoOnComponents(infos1) - f=MEDCouplingFieldDouble(ON_CELLS) ; f.setName(name1) ; f.setArray(d) ; f.setMesh(m) - f.setTime(float(i+1)+0.1,i+1,-i-1) - f1ts=MEDFileField1TS() ; f1ts.setFieldProfile(f,mm,0,pfl) ; fmts0_1.pushBackTimeStep(f1ts) - self.assertEqual(fmts0_1.getInfo(),tuple(infos1)) - pass - fs.pushField(fmts0_1) - self.assertEqual(1,len(fs)) - l=fmts0_1.splitComponents() - self.assertEqual(3,len(l)) - for elt in l: self.assertEqual(10,len(elt)) - for elt in l: self.assertTrue(isinstance(elt,MEDFileFieldMultiTS)) - for elt in l: - elt.setName("%s_%s"%(elt.getName(),DataArray.GetVarNameFromInfo(elt.getInfo()[0]))) - pass - fs.pushFields(l) - self.assertEqual(4,len(fs)) - for elt in fs: self.assertEqual(10,len(elt)) - self.assertEqual(fs.getPfls(),('pfl_NORM_QUAD4',)) - self.assertEqual(fs.getPflsReallyUsed(),('pfl_NORM_QUAD4',)) - # - fs.write(fname,0) ; del fs - # - fs1=MEDFileFields(fname) - self.assertEqual(fs1.getPfls(),('pfl_NORM_QUAD4',)) - self.assertEqual(fs1.getPflsReallyUsed(),('pfl_NORM_QUAD4',)) - self.assertEqual(4,len(fs1)) - for i in xrange(10): - for j,fieldName in enumerate(['1stField_aa','1stField_ccc','1stField_ZZZZ']): - f1ts=fs1[fieldName][i] - f=f1ts.getFieldOnMeshAtLevel(ON_CELLS,0,mm) - d=DataArrayDouble(21) ; d.iota(i*10) ; d.rearrange(3) ; d=d[:,j] ; d.setInfoOnComponent(0,infos1[j]) - self.assertTrue(d.isEqual(f.getArray(),1e-13)) - pass - f1ts=fs1["1stField"][i] - f=f1ts.getFieldOnMeshAtLevel(ON_CELLS,0,mm) - d=DataArrayDouble(21) ; d.iota(i*10) ; d.rearrange(3) ; d.setInfoOnComponents(infos1) - self.assertTrue(d.isEqual(f.getArray(),1e-13)) - pass - pass - - def testMEDFileFieldConvertTo1(self): - fname="Pyfile68.med" - # building a mesh containing 4 tri3 + 5 quad4 - tri=MEDCouplingUMesh("tri",2) - tri.allocateCells() ; tri.insertNextCell(NORM_TRI3,[0,1,2]) - tri.setCoords(DataArrayDouble([(0.,0.),(0.,1.),(1.,0.)])) - tris=[tri.deepCpy() for i in xrange(4)] - for i,elt in enumerate(tris): elt.translate([i,0]) - tris=MEDCouplingUMesh.MergeUMeshes(tris) - quad=MEDCouplingUMesh("quad",2) - quad.allocateCells() ; quad.insertNextCell(NORM_QUAD4,[0,1,2,3]) - quad.setCoords(DataArrayDouble([(0.,0.),(0.,1.),(1.,1.),(1.,0.)])) - quads=[quad.deepCpy() for i in xrange(5)] - for i,elt in enumerate(quads): elt.translate([5+i,0]) - quads=MEDCouplingUMesh.MergeUMeshes(quads) - m=MEDCouplingUMesh.MergeUMeshes(tris,quads) - m.setName("mesh") ; m.getCoords().setInfoOnComponents(["XX [m]","YYY [km]"]) - mm=MEDFileUMesh() ; mm.setMeshAtLevel(0,m) - # - ff0=MEDFileField1TS() - f0=MEDCouplingFieldDouble(ON_CELLS,ONE_TIME) ; f0.setMesh(m) ; arr=DataArrayDouble(m.getNumberOfCells()*2) ; arr.iota() ; arr.rearrange(2) ; arr.setInfoOnComponents(["X [km]","YY [mm]"]) ; f0.setArray(arr) ; f0.setName("FieldCell") - f0.checkCoherency() - ff0.setFieldNoProfileSBT(f0) - # - fspExp=[(3,[(0,(0,4),'','')]),(4,[(0,(4,9),'','')])] - self.assertEqual(ff0.getFieldSplitedByType(),fspExp) - # - ff0i=ff0.convertToInt() - self.assertEqual(ff0i.getFieldSplitedByType(),fspExp) - self.assertTrue(arr.convertToIntArr().isEqual(ff0i.getUndergroundDataArray())) - # - ff1=ff0i.convertToDouble() - self.assertTrue(ff1.getUndergroundDataArray().isEqual(ff0.getUndergroundDataArray(),1e-13)) - self.assertEqual(ff1.getFieldSplitedByType(),fspExp) - # With profiles - del arr,f0,ff0,ff1,ff0i,fspExp - ff0=MEDFileField1TS() - f0=MEDCouplingFieldDouble(ON_CELLS,ONE_TIME) ; f0.setMesh(m[:7]) ; arr=DataArrayDouble(7*2) ; arr.iota() ; arr.rearrange(2) ; arr.setInfoOnComponents(["XX [pm]","YYY [hm]"]) ; f0.setArray(arr) ; f0.setName("FieldCellPfl") - f0.checkCoherency() - pfl=DataArrayInt.Range(0,7,1) ; pfl.setName("pfl") - ff0.setFieldProfile(f0,mm,0,pfl) - fspExp=[(3,[(0,(0,4),'','')]),(4,[(0,(4,7),'pfl_NORM_QUAD4','')])] - self.assertEqual(ff0.getFieldSplitedByType(),fspExp) - # - ff0i=ff0.convertToInt() - self.assertTrue(isinstance(ff0i,MEDFileIntField1TS)) - self.assertEqual(ff0i.getFieldSplitedByType(),fspExp) - self.assertTrue(arr.convertToIntArr().isEqual(ff0i.getUndergroundDataArray())) - # - ff1=ff0i.convertToDouble() - self.assertTrue(isinstance(ff1,MEDFileField1TS)) - self.assertTrue(ff1.getUndergroundDataArray().isEqual(ff0.getUndergroundDataArray(),1e-13)) - self.assertEqual(ff1.getFieldSplitedByType(),fspExp) - ## MultiTimeSteps - ff0=MEDFileFieldMultiTS() - f0=MEDCouplingFieldDouble(ON_CELLS,ONE_TIME) ; f0.setMesh(m[:7]) ; arr=DataArrayDouble(7*2) ; arr.iota() ; arr.rearrange(2) ; arr.setInfoOnComponents(["X [km]","YY [mm]"]) ; f0.setArray(arr) ; f0.setName("FieldCellMTime") ; f0.setTime(0.1,0,10) - f0.checkCoherency() - ff0.appendFieldProfile(f0,mm,0,pfl) - f0=MEDCouplingFieldDouble(ON_CELLS,ONE_TIME) ; f0.setMesh(m[:7]) ; arr=DataArrayDouble(7*2) ; arr.iota(100) ; arr.rearrange(2) ; arr.setInfoOnComponents(["X [km]","YY [mm]"]) ; f0.setArray(arr) ; f0.setName("FieldCellMTime") ; f0.setTime(1.1,1,11) - f0.checkCoherency() - ff0.appendFieldProfile(f0,mm,0,pfl) - f0=MEDCouplingFieldDouble(ON_CELLS,ONE_TIME) ; f0.setMesh(m[:7]) ; arr=DataArrayDouble(7*2) ; arr.iota(200) ; arr.rearrange(2) ; arr.setInfoOnComponents(["X [km]","YY [mm]"]) ; f0.setArray(arr) ; f0.setName("FieldCellMTime") ; f0.setTime(2.1,2,12) - f0.checkCoherency() - ff0.appendFieldProfile(f0,mm,0,pfl) - ff1=ff0.convertToInt() - self.assertTrue(isinstance(ff1,MEDFileIntFieldMultiTS)) - self.assertEqual(ff1.getTimeSteps(),[(0,10,0.1),(1,11,1.1),(2,12,2.1)]) - for delt,(dt,it,t) in zip([0,100,200],ff1.getTimeSteps()): - self.assertEqual(ff1.getFieldSplitedByType(dt,it),fspExp) - arr=ff1.getUndergroundDataArray(dt,it) - arr.isEqualWithoutConsideringStr(DataArrayInt.Range(delt,delt+7,1)) - pass - self.assertEqual(ff1.getPfls(),('pfl_NORM_QUAD4', 'pfl_NORM_QUAD4', 'pfl_NORM_QUAD4')) - # - mm.write(fname,2) - ff1.write(fname,0) - # - ff1=ff1.convertToDouble() - self.assertTrue(isinstance(ff1,MEDFileFieldMultiTS)) - self.assertEqual(ff1.getTimeSteps(),[(0,10,0.1),(1,11,1.1),(2,12,2.1)]) - for delt,(dt,it,t) in zip([0,100,200],ff1.getTimeSteps()): - self.assertEqual(ff1.getFieldSplitedByType(dt,it),fspExp) - arr=ff1.getUndergroundDataArray(dt,it) - arr.isEqualWithoutConsideringStr(DataArrayInt.Range(delt,delt+7,1).convertToDblArr(),1e-14) - pass - self.assertEqual(ff1.getPfls(),('pfl_NORM_QUAD4', 'pfl_NORM_QUAD4', 'pfl_NORM_QUAD4')) - # - ff1=MEDFileAnyTypeFieldMultiTS.New(fname,"FieldCellMTime") - self.assertTrue(isinstance(ff1,MEDFileIntFieldMultiTS)) - self.assertEqual(ff1.getTimeSteps(),[(0,10,0.1),(1,11,1.1),(2,12,2.1)]) - for delt,(dt,it,t) in zip([0,100,200],ff1.getTimeSteps()): - self.assertTrue(ff1.getFieldSplitedByType(dt,it),fspExp) - arr=ff1.getUndergroundDataArray(dt,it) - arr.isEqualWithoutConsideringStr(DataArrayInt.Range(delt,delt+7,1)) - pass - self.assertEqual(ff1.getPfls(),('pfl_NORM_QUAD4',)) - pass - - def testMEDFileFieldPartialLoading(self): - fname="Pyfile69.med" - # - a=DataArrayInt() ; aa=a.getHeapMemorySize() - a.alloc(0,1) - strMulFac=a.getHeapMemorySize()-aa ; del a ; del aa - # building a mesh containing 30 tri3 + 40 quad4 - tri=MEDCouplingUMesh("tri",2) - tri.allocateCells() ; tri.insertNextCell(NORM_TRI3,[0,1,2]) - tri.setCoords(DataArrayDouble([(0.,0.),(0.,1.),(1.,0.)])) - tris=[tri.deepCpy() for i in xrange(30)] - for i,elt in enumerate(tris): elt.translate([i,0]) - tris=MEDCouplingUMesh.MergeUMeshes(tris) - quad=MEDCouplingUMesh("quad",2) - quad.allocateCells() ; quad.insertNextCell(NORM_QUAD4,[0,1,2,3]) - quad.setCoords(DataArrayDouble([(0.,0.),(0.,1.),(1.,1.),(1.,0.)])) - quads=[quad.deepCpy() for i in xrange(40)] - for i,elt in enumerate(quads): elt.translate([40+i,0]) - quads=MEDCouplingUMesh.MergeUMeshes(quads) - m=MEDCouplingUMesh.MergeUMeshes(tris,quads) - m.setName("mesh") ; m.getCoords().setInfoOnComponents(["XX [m]","YYY [km]"]) - mm=MEDFileUMesh() ; mm.setMeshAtLevel(0,m) ; mm.write(fname,2) - # - ff0=MEDFileField1TS() - f0=MEDCouplingFieldDouble(ON_CELLS,ONE_TIME) ; f0.setMesh(m) ; arr=DataArrayDouble(m.getNumberOfCells()*2) ; arr.iota() ; arr.rearrange(2) ; arr.setInfoOnComponents(["X [km]","YY [mm]"]) ; f0.setArray(arr) ; f0.setName("FieldCell") - f0.checkCoherency() - ff0.setFieldNoProfileSBT(f0) - ff0.write(fname,0) - # - fspExp=[(3,[(0,(0,30),'','')]),(4,[(0,(30,70),'','')])] - self.assertEqual(ff0.getFieldSplitedByType(),fspExp) - # With profiles - ff0=MEDFileField1TS() - f0=MEDCouplingFieldDouble(ON_CELLS,ONE_TIME) ; f0.setMesh(m[:50]) ; arr=DataArrayDouble(50*2) ; arr.iota() ; arr.rearrange(2) ; arr.setInfoOnComponents(["XX [pm]","YYY [hm]"]) ; f0.setArray(arr) ; f0.setName("FieldCellPfl") - f0.checkCoherency() - pfl=DataArrayInt.Range(0,50,1) ; pfl.setName("pfl") - ff0.setFieldProfile(f0,mm,0,pfl) - fspExp=[(3,[(0,(0,30),'','')]),(4,[(0,(30,50),'pfl_NORM_QUAD4','')])] - self.assertEqual(ff0.getFieldSplitedByType(),fspExp) - ff0.write(fname,0) - # - ff0=MEDFileField1TS(fname,False) - self.assertEqual(ff0.getName(),"FieldCell") - self.assertTrue(not ff0.getUndergroundDataArray().isAllocated()) - self.assertEqual(ff0.getUndergroundDataArray().getInfoOnComponents(),['X [km]','YY [mm]']) - heap_memory_ref=ff0.getHeapMemorySize() - self.assertIn(heap_memory_ref,xrange(182,298+2*strMulFac)) - ff0.loadArrays() ## - arr=DataArrayDouble(140) ; arr.iota() ; arr.rearrange(2) - self.assertTrue(ff0.getUndergroundDataArray().isEqualWithoutConsideringStr(arr,1e-14)) - self.assertEqual(ff0.getHeapMemorySize()-heap_memory_ref,70*8*2) - # - ff0=MEDFileField1TS(fname,"FieldCellPfl",False) - self.assertEqual(ff0.getUndergroundDataArray().getInfoOnComponents(),["XX [pm]","YYY [hm]"]) - heap_memory_ref=ff0.getHeapMemorySize() - self.assertIn(heap_memory_ref,xrange(350,415+6*strMulFac)) - ff0.loadArrays() ## - arr=DataArrayDouble(100) ; arr.iota() ; arr.rearrange(2) - self.assertTrue(ff0.getUndergroundDataArray().isEqualWithoutConsideringStr(arr,1e-14)) - self.assertEqual(ff0.getHeapMemorySize()-heap_memory_ref,50*8*2) - ff0.loadArrays() ## - self.assertTrue(ff0.getUndergroundDataArray().isEqualWithoutConsideringStr(arr,1e-14)) - self.assertEqual(ff0.getHeapMemorySize()-heap_memory_ref,50*8*2) - ff0.getUndergroundDataArray().setIJ(30,1,5.5) - self.assertTrue(not ff0.getUndergroundDataArray().isEqualWithoutConsideringStr(arr,1e-14)) - ff0.loadArrays() ## - self.assertTrue(ff0.getUndergroundDataArray().isEqualWithoutConsideringStr(arr,1e-14)) - ff0.getUndergroundDataArray().setIJ(30,1,5.5) - self.assertTrue(not ff0.getUndergroundDataArray().isEqualWithoutConsideringStr(arr,1e-14)) - ff0.loadArraysIfNecessary() ## - self.assertEqual(ff0.getUndergroundDataArray().getIJ(30,1),5.5) - self.assertTrue(not ff0.getUndergroundDataArray().isEqualWithoutConsideringStr(arr,1e-14)) - heap_memory_ref=ff0.getHeapMemorySize() - self.assertIn(heap_memory_ref,xrange(1100,1215+2*strMulFac)) - ff0.unloadArrays() - hmd=ff0.getHeapMemorySize()-heap_memory_ref - self.assertEqual(hmd,-800) # -50*8*2 - ff0.loadArrays() ## - self.assertEqual(ff0.getHeapMemorySize()-heap_memory_ref,0) - # - ff0=MEDFileField1TS(fname,"FieldCellPfl",-1,-1,False) - heap_memory_ref=ff0.getHeapMemorySize() - self.assertIn(heap_memory_ref,xrange(299,415+6*strMulFac)) - ff0.loadArrays() ## - self.assertTrue(ff0.getUndergroundDataArray().isEqualWithoutConsideringStr(arr,1e-14)) - self.assertEqual(ff0.getHeapMemorySize()-heap_memory_ref,50*8*2) - # - fieldName="FieldCellMultiTS" - ff0=MEDFileFieldMultiTS() - for t in xrange(20): - f0=MEDCouplingFieldDouble(ON_CELLS,ONE_TIME) ; f0.setMesh(m) ; arr=DataArrayDouble(m.getNumberOfCells()*2) ; arr.iota(float(t+1000)) ; arr.rearrange(2) ; arr.setInfoOnComponents(["X [km]","YY [mm]"]) ; f0.setArray(arr) ; f0.setName(fieldName) - f0.setTime(float(t)+0.1,t,100+t) - f0.checkCoherency() - ff0.appendFieldNoProfileSBT(f0) - pass - ff0.write(fname,0) - # - ff0=MEDFileAnyTypeFieldMultiTS.New(fname,fieldName,False) - heap_memory_ref=ff0.getHeapMemorySize() - self.assertIn(heap_memory_ref,xrange(5536,5956+(80+26)*strMulFac)) - ff0.loadArrays() - self.assertEqual(ff0.getHeapMemorySize()-heap_memory_ref,20*70*8*2) - del ff0 - # - ffs=MEDFileFields(fname,False) - heap_memory_ref=ffs.getHeapMemorySize() - self.assertIn(heap_memory_ref,xrange(5335,6687+(80+50)*strMulFac)) - ffs.loadArrays() - self.assertEqual(ffs.getHeapMemorySize()-heap_memory_ref,20*70*8*2+70*8*2+50*8*2) - pass - - def testMEDFileMeshReadSelector1(self): - mrs=MEDFileMeshReadSelector() - self.assertTrue(mrs.isCellFamilyFieldReading() and mrs.isNodeFamilyFieldReading() and mrs.isCellNameFieldReading() and mrs.isNodeNameFieldReading() and mrs.isCellNumFieldReading() and mrs.isNodeNumFieldReading()) - mrs.__str__() ; mrs.__repr__() - # - mrs=MEDFileMeshReadSelector(0) - self.assertTrue(not mrs.isCellFamilyFieldReading() and not mrs.isNodeFamilyFieldReading() and not mrs.isCellNameFieldReading() and not mrs.isNodeNameFieldReading() and not mrs.isCellNumFieldReading() and not mrs.isNodeNumFieldReading()) - mrs=MEDFileMeshReadSelector(1) - self.assertTrue(mrs.isCellFamilyFieldReading() and not mrs.isNodeFamilyFieldReading() and not mrs.isCellNameFieldReading() and not mrs.isNodeNameFieldReading() and not mrs.isCellNumFieldReading() and not mrs.isNodeNumFieldReading()) - mrs=MEDFileMeshReadSelector(2) - self.assertTrue(not mrs.isCellFamilyFieldReading() and mrs.isNodeFamilyFieldReading() and not mrs.isCellNameFieldReading() and not mrs.isNodeNameFieldReading() and not mrs.isCellNumFieldReading() and not mrs.isNodeNumFieldReading()) - mrs=MEDFileMeshReadSelector(3) - self.assertTrue(mrs.isCellFamilyFieldReading() and mrs.isNodeFamilyFieldReading() and not mrs.isCellNameFieldReading() and not mrs.isNodeNameFieldReading() and not mrs.isCellNumFieldReading() and not mrs.isNodeNumFieldReading()) - mrs=MEDFileMeshReadSelector(4) - self.assertTrue(not mrs.isCellFamilyFieldReading() and not mrs.isNodeFamilyFieldReading() and mrs.isCellNameFieldReading() and not mrs.isNodeNameFieldReading() and not mrs.isCellNumFieldReading() and not mrs.isNodeNumFieldReading()) - mrs=MEDFileMeshReadSelector(5) - self.assertTrue(mrs.isCellFamilyFieldReading() and not mrs.isNodeFamilyFieldReading() and mrs.isCellNameFieldReading() and not mrs.isNodeNameFieldReading() and not mrs.isCellNumFieldReading() and not mrs.isNodeNumFieldReading()) - mrs=MEDFileMeshReadSelector(6) - self.assertTrue(not mrs.isCellFamilyFieldReading() and mrs.isNodeFamilyFieldReading() and mrs.isCellNameFieldReading() and not mrs.isNodeNameFieldReading() and not mrs.isCellNumFieldReading() and not mrs.isNodeNumFieldReading()) - mrs=MEDFileMeshReadSelector(7) - self.assertTrue(mrs.isCellFamilyFieldReading() and mrs.isNodeFamilyFieldReading() and mrs.isCellNameFieldReading() and not mrs.isNodeNameFieldReading() and not mrs.isCellNumFieldReading() and not mrs.isNodeNumFieldReading()) - mrs=MEDFileMeshReadSelector(8) - self.assertTrue(not mrs.isCellFamilyFieldReading() and not mrs.isNodeFamilyFieldReading() and not mrs.isCellNameFieldReading() and mrs.isNodeNameFieldReading() and not mrs.isCellNumFieldReading() and not mrs.isNodeNumFieldReading()) - mrs=MEDFileMeshReadSelector(9) - self.assertTrue(mrs.isCellFamilyFieldReading() and not mrs.isNodeFamilyFieldReading() and not mrs.isCellNameFieldReading() and mrs.isNodeNameFieldReading() and not mrs.isCellNumFieldReading() and not mrs.isNodeNumFieldReading()) - mrs=MEDFileMeshReadSelector(10) - self.assertTrue(not mrs.isCellFamilyFieldReading() and mrs.isNodeFamilyFieldReading() and not mrs.isCellNameFieldReading() and mrs.isNodeNameFieldReading() and not mrs.isCellNumFieldReading() and not mrs.isNodeNumFieldReading()) - mrs=MEDFileMeshReadSelector(11) - self.assertTrue(mrs.isCellFamilyFieldReading() and mrs.isNodeFamilyFieldReading() and not mrs.isCellNameFieldReading() and mrs.isNodeNameFieldReading() and not mrs.isCellNumFieldReading() and not mrs.isNodeNumFieldReading()) - mrs=MEDFileMeshReadSelector(12) - self.assertTrue(not mrs.isCellFamilyFieldReading() and not mrs.isNodeFamilyFieldReading() and mrs.isCellNameFieldReading() and mrs.isNodeNameFieldReading() and not mrs.isCellNumFieldReading() and not mrs.isNodeNumFieldReading()) - mrs=MEDFileMeshReadSelector(13) - self.assertTrue(mrs.isCellFamilyFieldReading() and not mrs.isNodeFamilyFieldReading() and mrs.isCellNameFieldReading() and mrs.isNodeNameFieldReading() and not mrs.isCellNumFieldReading() and not mrs.isNodeNumFieldReading()) - mrs=MEDFileMeshReadSelector(14) - self.assertTrue(not mrs.isCellFamilyFieldReading() and mrs.isNodeFamilyFieldReading() and mrs.isCellNameFieldReading() and mrs.isNodeNameFieldReading() and not mrs.isCellNumFieldReading() and not mrs.isNodeNumFieldReading()) - mrs=MEDFileMeshReadSelector(15) - self.assertTrue(mrs.isCellFamilyFieldReading() and mrs.isNodeFamilyFieldReading() and mrs.isCellNameFieldReading() and mrs.isNodeNameFieldReading() and not mrs.isCellNumFieldReading() and not mrs.isNodeNumFieldReading()) - mrs=MEDFileMeshReadSelector(16) - self.assertTrue(not mrs.isCellFamilyFieldReading() and not mrs.isNodeFamilyFieldReading() and not mrs.isCellNameFieldReading() and not mrs.isNodeNameFieldReading() and mrs.isCellNumFieldReading() and not mrs.isNodeNumFieldReading()) - mrs=MEDFileMeshReadSelector(17) - self.assertTrue(mrs.isCellFamilyFieldReading() and not mrs.isNodeFamilyFieldReading() and not mrs.isCellNameFieldReading() and not mrs.isNodeNameFieldReading() and mrs.isCellNumFieldReading() and not mrs.isNodeNumFieldReading()) - mrs=MEDFileMeshReadSelector(18) - self.assertTrue(not mrs.isCellFamilyFieldReading() and mrs.isNodeFamilyFieldReading() and not mrs.isCellNameFieldReading() and not mrs.isNodeNameFieldReading() and mrs.isCellNumFieldReading() and not mrs.isNodeNumFieldReading()) - mrs=MEDFileMeshReadSelector(19) - self.assertTrue(mrs.isCellFamilyFieldReading() and mrs.isNodeFamilyFieldReading() and not mrs.isCellNameFieldReading() and not mrs.isNodeNameFieldReading() and mrs.isCellNumFieldReading() and not mrs.isNodeNumFieldReading()) - mrs=MEDFileMeshReadSelector(20) - self.assertTrue(not mrs.isCellFamilyFieldReading() and not mrs.isNodeFamilyFieldReading() and mrs.isCellNameFieldReading() and not mrs.isNodeNameFieldReading() and mrs.isCellNumFieldReading() and not mrs.isNodeNumFieldReading()) - mrs=MEDFileMeshReadSelector(21) - self.assertTrue(mrs.isCellFamilyFieldReading() and not mrs.isNodeFamilyFieldReading() and mrs.isCellNameFieldReading() and not mrs.isNodeNameFieldReading() and mrs.isCellNumFieldReading() and not mrs.isNodeNumFieldReading()) - mrs=MEDFileMeshReadSelector(22) - self.assertTrue(not mrs.isCellFamilyFieldReading() and mrs.isNodeFamilyFieldReading() and mrs.isCellNameFieldReading() and not mrs.isNodeNameFieldReading() and mrs.isCellNumFieldReading() and not mrs.isNodeNumFieldReading()) - mrs=MEDFileMeshReadSelector(23) - self.assertTrue(mrs.isCellFamilyFieldReading() and mrs.isNodeFamilyFieldReading() and mrs.isCellNameFieldReading() and not mrs.isNodeNameFieldReading() and mrs.isCellNumFieldReading() and not mrs.isNodeNumFieldReading()) - mrs=MEDFileMeshReadSelector(24) - self.assertTrue(not mrs.isCellFamilyFieldReading() and not mrs.isNodeFamilyFieldReading() and not mrs.isCellNameFieldReading() and mrs.isNodeNameFieldReading() and mrs.isCellNumFieldReading() and not mrs.isNodeNumFieldReading()) - mrs=MEDFileMeshReadSelector(25) - self.assertTrue(mrs.isCellFamilyFieldReading() and not mrs.isNodeFamilyFieldReading() and not mrs.isCellNameFieldReading() and mrs.isNodeNameFieldReading() and mrs.isCellNumFieldReading() and not mrs.isNodeNumFieldReading()) - mrs=MEDFileMeshReadSelector(26) - self.assertTrue(not mrs.isCellFamilyFieldReading() and mrs.isNodeFamilyFieldReading() and not mrs.isCellNameFieldReading() and mrs.isNodeNameFieldReading() and mrs.isCellNumFieldReading() and not mrs.isNodeNumFieldReading()) - mrs=MEDFileMeshReadSelector(27) - self.assertTrue(mrs.isCellFamilyFieldReading() and mrs.isNodeFamilyFieldReading() and not mrs.isCellNameFieldReading() and mrs.isNodeNameFieldReading() and mrs.isCellNumFieldReading() and not mrs.isNodeNumFieldReading()) - mrs=MEDFileMeshReadSelector(28) - self.assertTrue(not mrs.isCellFamilyFieldReading() and not mrs.isNodeFamilyFieldReading() and mrs.isCellNameFieldReading() and mrs.isNodeNameFieldReading() and mrs.isCellNumFieldReading() and not mrs.isNodeNumFieldReading()) - mrs=MEDFileMeshReadSelector(29) - self.assertTrue(mrs.isCellFamilyFieldReading() and not mrs.isNodeFamilyFieldReading() and mrs.isCellNameFieldReading() and mrs.isNodeNameFieldReading() and mrs.isCellNumFieldReading() and not mrs.isNodeNumFieldReading()) - mrs=MEDFileMeshReadSelector(30) - self.assertTrue(not mrs.isCellFamilyFieldReading() and mrs.isNodeFamilyFieldReading() and mrs.isCellNameFieldReading() and mrs.isNodeNameFieldReading() and mrs.isCellNumFieldReading() and not mrs.isNodeNumFieldReading()) - mrs=MEDFileMeshReadSelector(31) - self.assertTrue(mrs.isCellFamilyFieldReading() and mrs.isNodeFamilyFieldReading() and mrs.isCellNameFieldReading() and mrs.isNodeNameFieldReading() and mrs.isCellNumFieldReading() and not mrs.isNodeNumFieldReading()) - mrs=MEDFileMeshReadSelector(32) - self.assertTrue(not mrs.isCellFamilyFieldReading() and not mrs.isNodeFamilyFieldReading() and not mrs.isCellNameFieldReading() and not mrs.isNodeNameFieldReading() and not mrs.isCellNumFieldReading() and mrs.isNodeNumFieldReading()) - mrs=MEDFileMeshReadSelector(33) - self.assertTrue(mrs.isCellFamilyFieldReading() and not mrs.isNodeFamilyFieldReading() and not mrs.isCellNameFieldReading() and not mrs.isNodeNameFieldReading() and not mrs.isCellNumFieldReading() and mrs.isNodeNumFieldReading()) - mrs=MEDFileMeshReadSelector(34) - self.assertTrue(not mrs.isCellFamilyFieldReading() and mrs.isNodeFamilyFieldReading() and not mrs.isCellNameFieldReading() and not mrs.isNodeNameFieldReading() and not mrs.isCellNumFieldReading() and mrs.isNodeNumFieldReading()) - mrs=MEDFileMeshReadSelector(35) - self.assertTrue(mrs.isCellFamilyFieldReading() and mrs.isNodeFamilyFieldReading() and not mrs.isCellNameFieldReading() and not mrs.isNodeNameFieldReading() and not mrs.isCellNumFieldReading() and mrs.isNodeNumFieldReading()) - mrs=MEDFileMeshReadSelector(36) - self.assertTrue(not mrs.isCellFamilyFieldReading() and not mrs.isNodeFamilyFieldReading() and mrs.isCellNameFieldReading() and not mrs.isNodeNameFieldReading() and not mrs.isCellNumFieldReading() and mrs.isNodeNumFieldReading()) - mrs=MEDFileMeshReadSelector(37) - self.assertTrue(mrs.isCellFamilyFieldReading() and not mrs.isNodeFamilyFieldReading() and mrs.isCellNameFieldReading() and not mrs.isNodeNameFieldReading() and not mrs.isCellNumFieldReading() and mrs.isNodeNumFieldReading()) - mrs=MEDFileMeshReadSelector(38) - self.assertTrue(not mrs.isCellFamilyFieldReading() and mrs.isNodeFamilyFieldReading() and mrs.isCellNameFieldReading() and not mrs.isNodeNameFieldReading() and not mrs.isCellNumFieldReading() and mrs.isNodeNumFieldReading()) - mrs=MEDFileMeshReadSelector(39) - self.assertTrue(mrs.isCellFamilyFieldReading() and mrs.isNodeFamilyFieldReading() and mrs.isCellNameFieldReading() and not mrs.isNodeNameFieldReading() and not mrs.isCellNumFieldReading() and mrs.isNodeNumFieldReading()) - mrs=MEDFileMeshReadSelector(40) - self.assertTrue(not mrs.isCellFamilyFieldReading() and not mrs.isNodeFamilyFieldReading() and not mrs.isCellNameFieldReading() and mrs.isNodeNameFieldReading() and not mrs.isCellNumFieldReading() and mrs.isNodeNumFieldReading()) - mrs=MEDFileMeshReadSelector(41) - self.assertTrue(mrs.isCellFamilyFieldReading() and not mrs.isNodeFamilyFieldReading() and not mrs.isCellNameFieldReading() and mrs.isNodeNameFieldReading() and not mrs.isCellNumFieldReading() and mrs.isNodeNumFieldReading()) - mrs=MEDFileMeshReadSelector(42) - self.assertTrue(not mrs.isCellFamilyFieldReading() and mrs.isNodeFamilyFieldReading() and not mrs.isCellNameFieldReading() and mrs.isNodeNameFieldReading() and not mrs.isCellNumFieldReading() and mrs.isNodeNumFieldReading()) - mrs=MEDFileMeshReadSelector(43) - self.assertTrue(mrs.isCellFamilyFieldReading() and mrs.isNodeFamilyFieldReading() and not mrs.isCellNameFieldReading() and mrs.isNodeNameFieldReading() and not mrs.isCellNumFieldReading() and mrs.isNodeNumFieldReading()) - mrs=MEDFileMeshReadSelector(44) - self.assertTrue(not mrs.isCellFamilyFieldReading() and not mrs.isNodeFamilyFieldReading() and mrs.isCellNameFieldReading() and mrs.isNodeNameFieldReading() and not mrs.isCellNumFieldReading() and mrs.isNodeNumFieldReading()) - mrs=MEDFileMeshReadSelector(45) - self.assertTrue(mrs.isCellFamilyFieldReading() and not mrs.isNodeFamilyFieldReading() and mrs.isCellNameFieldReading() and mrs.isNodeNameFieldReading() and not mrs.isCellNumFieldReading() and mrs.isNodeNumFieldReading()) - mrs=MEDFileMeshReadSelector(46) - self.assertTrue(not mrs.isCellFamilyFieldReading() and mrs.isNodeFamilyFieldReading() and mrs.isCellNameFieldReading() and mrs.isNodeNameFieldReading() and not mrs.isCellNumFieldReading() and mrs.isNodeNumFieldReading()) - mrs=MEDFileMeshReadSelector(47) - self.assertTrue(mrs.isCellFamilyFieldReading() and mrs.isNodeFamilyFieldReading() and mrs.isCellNameFieldReading() and mrs.isNodeNameFieldReading() and not mrs.isCellNumFieldReading() and mrs.isNodeNumFieldReading()) - mrs=MEDFileMeshReadSelector(48) - self.assertTrue(not mrs.isCellFamilyFieldReading() and not mrs.isNodeFamilyFieldReading() and not mrs.isCellNameFieldReading() and not mrs.isNodeNameFieldReading() and mrs.isCellNumFieldReading() and mrs.isNodeNumFieldReading()) - mrs=MEDFileMeshReadSelector(49) - self.assertTrue(mrs.isCellFamilyFieldReading() and not mrs.isNodeFamilyFieldReading() and not mrs.isCellNameFieldReading() and not mrs.isNodeNameFieldReading() and mrs.isCellNumFieldReading() and mrs.isNodeNumFieldReading()) - mrs=MEDFileMeshReadSelector(50) - self.assertTrue(not mrs.isCellFamilyFieldReading() and mrs.isNodeFamilyFieldReading() and not mrs.isCellNameFieldReading() and not mrs.isNodeNameFieldReading() and mrs.isCellNumFieldReading() and mrs.isNodeNumFieldReading()) - mrs=MEDFileMeshReadSelector(51) - self.assertTrue(mrs.isCellFamilyFieldReading() and mrs.isNodeFamilyFieldReading() and not mrs.isCellNameFieldReading() and not mrs.isNodeNameFieldReading() and mrs.isCellNumFieldReading() and mrs.isNodeNumFieldReading()) - mrs=MEDFileMeshReadSelector(52) - self.assertTrue(not mrs.isCellFamilyFieldReading() and not mrs.isNodeFamilyFieldReading() and mrs.isCellNameFieldReading() and not mrs.isNodeNameFieldReading() and mrs.isCellNumFieldReading() and mrs.isNodeNumFieldReading()) - mrs=MEDFileMeshReadSelector(53) - self.assertTrue(mrs.isCellFamilyFieldReading() and not mrs.isNodeFamilyFieldReading() and mrs.isCellNameFieldReading() and not mrs.isNodeNameFieldReading() and mrs.isCellNumFieldReading() and mrs.isNodeNumFieldReading()) - mrs=MEDFileMeshReadSelector(54) - self.assertTrue(not mrs.isCellFamilyFieldReading() and mrs.isNodeFamilyFieldReading() and mrs.isCellNameFieldReading() and not mrs.isNodeNameFieldReading() and mrs.isCellNumFieldReading() and mrs.isNodeNumFieldReading()) - mrs=MEDFileMeshReadSelector(55) - self.assertTrue(mrs.isCellFamilyFieldReading() and mrs.isNodeFamilyFieldReading() and mrs.isCellNameFieldReading() and not mrs.isNodeNameFieldReading() and mrs.isCellNumFieldReading() and mrs.isNodeNumFieldReading()) - mrs=MEDFileMeshReadSelector(56) - self.assertTrue(not mrs.isCellFamilyFieldReading() and not mrs.isNodeFamilyFieldReading() and not mrs.isCellNameFieldReading() and mrs.isNodeNameFieldReading() and mrs.isCellNumFieldReading() and mrs.isNodeNumFieldReading()) - mrs=MEDFileMeshReadSelector(57) - self.assertTrue(mrs.isCellFamilyFieldReading() and not mrs.isNodeFamilyFieldReading() and not mrs.isCellNameFieldReading() and mrs.isNodeNameFieldReading() and mrs.isCellNumFieldReading() and mrs.isNodeNumFieldReading()) - mrs=MEDFileMeshReadSelector(58) - self.assertTrue(not mrs.isCellFamilyFieldReading() and mrs.isNodeFamilyFieldReading() and not mrs.isCellNameFieldReading() and mrs.isNodeNameFieldReading() and mrs.isCellNumFieldReading() and mrs.isNodeNumFieldReading()) - mrs=MEDFileMeshReadSelector(59) - self.assertTrue(mrs.isCellFamilyFieldReading() and mrs.isNodeFamilyFieldReading() and not mrs.isCellNameFieldReading() and mrs.isNodeNameFieldReading() and mrs.isCellNumFieldReading() and mrs.isNodeNumFieldReading()) - mrs=MEDFileMeshReadSelector(60) - self.assertTrue(not mrs.isCellFamilyFieldReading() and not mrs.isNodeFamilyFieldReading() and mrs.isCellNameFieldReading() and mrs.isNodeNameFieldReading() and mrs.isCellNumFieldReading() and mrs.isNodeNumFieldReading()) - mrs=MEDFileMeshReadSelector(61) - self.assertTrue(mrs.isCellFamilyFieldReading() and not mrs.isNodeFamilyFieldReading() and mrs.isCellNameFieldReading() and mrs.isNodeNameFieldReading() and mrs.isCellNumFieldReading() and mrs.isNodeNumFieldReading()) - mrs=MEDFileMeshReadSelector(62) - self.assertTrue(not mrs.isCellFamilyFieldReading() and mrs.isNodeFamilyFieldReading() and mrs.isCellNameFieldReading() and mrs.isNodeNameFieldReading() and mrs.isCellNumFieldReading() and mrs.isNodeNumFieldReading()) - mrs=MEDFileMeshReadSelector(63) - self.assertTrue(mrs.isCellFamilyFieldReading() and mrs.isNodeFamilyFieldReading() and mrs.isCellNameFieldReading() and mrs.isNodeNameFieldReading() and mrs.isCellNumFieldReading() and mrs.isNodeNumFieldReading()) - # - mrs=MEDFileMeshReadSelector(63) - mrs.setCellFamilyFieldReading(False) - self.assertEqual(mrs.getCode(),62) - mrs.setCellFamilyFieldReading(True) - self.assertEqual(mrs.getCode(),63) - mrs.setNodeFamilyFieldReading(False) - self.assertEqual(mrs.getCode(),61) - mrs.setNodeFamilyFieldReading(True) - self.assertEqual(mrs.getCode(),63) - mrs.setCellNameFieldReading(False) - self.assertEqual(mrs.getCode(),59) - mrs.setCellNameFieldReading(True) - self.assertEqual(mrs.getCode(),63) - mrs.setNodeNameFieldReading(False) - self.assertEqual(mrs.getCode(),55) - mrs.setNodeNameFieldReading(True) - self.assertEqual(mrs.getCode(),63) - mrs.setCellNumFieldReading(False) - self.assertEqual(mrs.getCode(),47) - mrs.setCellNumFieldReading(True) - self.assertEqual(mrs.getCode(),63) - mrs.setNodeNumFieldReading(False) - self.assertEqual(mrs.getCode(),31) - mrs.setNodeNumFieldReading(True) - self.assertEqual(mrs.getCode(),63) - pass - - def testPartialReadOfMeshes(self): - fname="Pyfile70.med" - # building a mesh containing 4 tri3 + 5 quad4 - tri=MEDCouplingUMesh("tri",2) - tri.allocateCells() ; tri.insertNextCell(NORM_TRI3,[0,1,2]) - tri.setCoords(DataArrayDouble([(0.,0.),(0.,1.),(1.,0.)])) - tris=[tri.deepCpy() for i in xrange(4)] - for i,elt in enumerate(tris): elt.translate([i,0]) - tris=MEDCouplingUMesh.MergeUMeshes(tris) - quad=MEDCouplingUMesh("quad",2) - quad.allocateCells() ; quad.insertNextCell(NORM_QUAD4,[0,1,2,3]) - quad.setCoords(DataArrayDouble([(0.,0.),(0.,1.),(1.,1.),(1.,0.)])) - quads=[quad.deepCpy() for i in xrange(5)] - for i,elt in enumerate(quads): elt.translate([5+i,0]) - quads=MEDCouplingUMesh.MergeUMeshes(quads) - m=MEDCouplingUMesh.MergeUMeshes(tris,quads) - m.setName("mesh") ; m.getCoords().setInfoOnComponents(["XX [m]","YYY [km]"]) - m1=m.buildDescendingConnectivity()[0] - mm=MEDFileUMesh() ; mm.setMeshes([m,m1]) - # - grp0=DataArrayInt([1,2,3,5,6]) ; grp0.setName("grp0") - grp1=DataArrayInt([1,2,3,5,7,8]) ; grp1.setName("grp1") - mm.setGroupsAtLevel(0,[grp0,grp1]) - grp2=DataArrayInt.Range(0,32,2) ; grp2.setName("grp2") - grp3=DataArrayInt.Range(1,32,7) ; grp3.setName("grp3") - mm.setGroupsAtLevel(-1,[grp2,grp3]) - grp4=DataArrayInt.Range(0,32,2) ; grp4.setName("grp4") - grp5=DataArrayInt.Range(1,32,7) ; grp5.setName("grp5") - mm.setGroupsAtLevel(1,[grp4,grp5]) - mm.setRenumFieldArr(0,DataArrayInt.Range(2,11,1)) - mm.setRenumFieldArr(-1,DataArrayInt.Range(3,35,1)) - mm.setRenumFieldArr(1,DataArrayInt.Range(4,36,1)) - # - mm.write(fname,2) - ## - mm=MEDFileMesh.New(fname,"mesh",-1,-1,MEDFileMeshReadSelector()) - b4_ref_heap_mem=mm.getHeapMemorySize() - mm.getMeshAtLevel(0)## please let this line : force to move 1GTUMesh -> UMesh - mm.getMeshAtLevel(-1)## please let this line : force to move 1GTUMesh -> UMesh - ref_heap_mem=mm.getHeapMemorySize() - # check the gain of memory using 1GTUMesh instead of UMesh - self.assertTrue(ref_heap_mem-b4_ref_heap_mem>=(32+9)*4*2-32)# 32+9=nbCells 4=sizeof(int) 2=the types+index -32=loss linked to vector - # - mm=MEDFileMesh.New(fname,MEDFileMeshReadSelector(0)) - self.assertEqual(len(mm.getGroupsNames()),0) - self.assertTrue(mm.getMeshAtLevel(0).isEqual(m,1e-13)) - self.assertTrue(mm.getMeshAtLevel(-1).isEqual(m1,1e-13)) - self.assertTrue(mm.getFamilyFieldAtLevel(0) is None) - self.assertTrue(mm.getFamilyFieldAtLevel(-1) is None) - self.assertTrue(mm.getFamilyFieldAtLevel(1) is None) - self.assertTrue(mm.getNumberFieldAtLevel(0) is None) - self.assertTrue(mm.getNumberFieldAtLevel(-1) is None) - self.assertTrue(mm.getNumberFieldAtLevel(1) is None) - delta1=ref_heap_mem-mm.getHeapMemorySize() - self.assertTrue(delta1>=4*(32+9)*3+32*4*3) - # - mm=MEDFileMesh.New(fname,MEDFileMeshReadSelector(1)) - self.assertEqual(len(mm.getGroupsNames()),6) - self.assertTrue(mm.getMeshAtLevel(0).isEqual(m,1e-13)) - self.assertTrue(mm.getMeshAtLevel(-1).isEqual(m1,1e-13)) - self.assertTrue(mm.getFamilyFieldAtLevel(0)!=None) - self.assertTrue(mm.getFamilyFieldAtLevel(-1)!=None) - self.assertTrue(mm.getFamilyFieldAtLevel(1) is None) - self.assertTrue(mm.getNumberFieldAtLevel(0) is None) - self.assertTrue(mm.getNumberFieldAtLevel(-1) is None) - self.assertTrue(mm.getNumberFieldAtLevel(1) is None) - delta2=ref_heap_mem-mm.getHeapMemorySize() - self.assertTrue(delta2<delta1) - self.assertTrue(delta2>=4*(32+9)*1+32*4*3) - # - mm=MEDFileUMesh(fname,MEDFileMeshReadSelector(3)) - self.assertEqual(len(mm.getGroupsNames()),6) - self.assertTrue(mm.getMeshAtLevel(0).isEqual(m,1e-13)) - self.assertTrue(mm.getMeshAtLevel(-1).isEqual(m1,1e-13)) - self.assertTrue(mm.getFamilyFieldAtLevel(0)!=None) - self.assertTrue(mm.getFamilyFieldAtLevel(-1)!=None) - self.assertTrue(mm.getFamilyFieldAtLevel(1)!=None) - self.assertTrue(mm.getNumberFieldAtLevel(0) is None) - self.assertTrue(mm.getNumberFieldAtLevel(-1) is None) - self.assertTrue(mm.getNumberFieldAtLevel(1) is None) - delta3=ref_heap_mem-mm.getHeapMemorySize() - self.assertTrue(delta3<delta2) - self.assertTrue(delta3>=4*(32+9)*1+32*4*1) - # - mm=MEDFileUMesh(fname,"mesh",-1,-1,MEDFileMeshReadSelector(19)) - self.assertEqual(len(mm.getGroupsNames()),6) - self.assertTrue(mm.getMeshAtLevel(0).isEqual(m,1e-13)) - self.assertTrue(mm.getMeshAtLevel(-1).isEqual(m1,1e-13)) - self.assertTrue(mm.getFamilyFieldAtLevel(0)!=None) - self.assertTrue(mm.getFamilyFieldAtLevel(-1)!=None) - self.assertTrue(mm.getFamilyFieldAtLevel(1)!=None) - self.assertTrue(mm.getNumberFieldAtLevel(0)!=None) - self.assertTrue(mm.getNumberFieldAtLevel(-1)!=None) - self.assertTrue(mm.getNumberFieldAtLevel(1) is None) - delta4=ref_heap_mem-mm.getHeapMemorySize() - self.assertTrue(delta4<delta3) - self.assertTrue(delta4>=32*4*2) - # - mm=MEDFileUMesh.New(fname,"mesh",-1,-1,MEDFileMeshReadSelector(51)) - self.assertEqual(len(mm.getGroupsNames()),6) - self.assertTrue(mm.getMeshAtLevel(0).isEqual(m,1e-13)) - self.assertTrue(mm.getMeshAtLevel(-1).isEqual(m1,1e-13)) - self.assertTrue(mm.getFamilyFieldAtLevel(0)!=None) - self.assertTrue(mm.getFamilyFieldAtLevel(-1)!=None) - self.assertTrue(mm.getFamilyFieldAtLevel(1)!=None) - self.assertTrue(mm.getNumberFieldAtLevel(0)!=None) - self.assertTrue(mm.getNumberFieldAtLevel(-1)!=None) - self.assertTrue(mm.getNumberFieldAtLevel(1)!=None) - delta5=ref_heap_mem-mm.getHeapMemorySize() - self.assertTrue(delta5<delta4) - self.assertEqual(delta5,0) - pass - - # this test checks that setFieldProfile perform a check of the array length - # compared to the profile length. This test also checks that mesh attribute of field - # is not used by setFieldProfile (because across this test mesh is equal to None) - def testCheckCompatibilityPfl1(self): - # building a mesh containing 4 tri3 + 5 quad4 - tri=MEDCouplingUMesh("tri",2) - tri.allocateCells() ; tri.insertNextCell(NORM_TRI3,[0,1,2]) - tri.setCoords(DataArrayDouble([(0.,0.),(0.,1.),(1.,0.)])) - tris=[tri.deepCpy() for i in xrange(4)] - for i,elt in enumerate(tris): elt.translate([i,0]) - tris=MEDCouplingUMesh.MergeUMeshes(tris) - quad=MEDCouplingUMesh("quad",2) - quad.allocateCells() ; quad.insertNextCell(NORM_QUAD4,[0,1,2,3]) - quad.setCoords(DataArrayDouble([(0.,0.),(0.,1.),(1.,1.),(1.,0.)])) - quads=[quad.deepCpy() for i in xrange(5)] - for i,elt in enumerate(quads): elt.translate([5+i,0]) - quads=MEDCouplingUMesh.MergeUMeshes(quads) - m=MEDCouplingUMesh.MergeUMeshes(tris,quads) - m.setName("mesh") ; m.getCoords().setInfoOnComponents(["XX [m]","YYY [km]"]) - m1=m.buildDescendingConnectivity()[0] - mm=MEDFileUMesh() ; mm.setMeshes([m,m1]) - # - f1ts=MEDFileField1TS() - f=MEDCouplingFieldDouble(ON_NODES) - vals=DataArrayDouble(7) ; vals.iota(1000) - f.setArray(vals) - f.setName("anonymous") # f has no mesh it is not a bug - pfl=DataArrayInt([0,1,2,3,4,5,6]) ; pfl.setName("pfl") - f1ts.setFieldProfile(f,mm,0,pfl) - # - f1ts=MEDFileField1TS() - f=MEDCouplingFieldDouble(ON_NODES) - vals=DataArrayDouble(8) ; vals.iota(1000) - f.setArray(vals) - f.setName("anonymous") # f has no mesh it is not a bug - pfl=DataArrayInt([0,1,2,3,4,5,6]) ; pfl.setName("pfl") - self.assertRaises(InterpKernelException,f1ts.setFieldProfile,f,mm,0,pfl) - # - f1ts=MEDFileField1TS() - f=MEDCouplingFieldDouble(ON_CELLS) - vals=DataArrayDouble(7) ; vals.iota(1000) - f.setArray(vals) - f.setName("anonymous") # f has no mesh it is not a bug - pfl=DataArrayInt([1,2,3,5,6,7,8]) ; pfl.setName("pfl") - f1ts.setFieldProfile(f,mm,0,pfl) - self.assertTrue(f1ts.getUndergroundDataArray().isEqual(vals,1e-10)) - # - f1ts=MEDFileField1TS() - f=MEDCouplingFieldDouble(ON_GAUSS_PT) - vals=DataArrayDouble(27) ; vals.iota(1000) - f.setArray(vals) - f.setName("anonymous") # f has no mesh it is not a bug - pfl=DataArrayInt([1,2,3,5,6,7,8]) ; pfl.setName("pfl") - f.setMesh(m[pfl]) - f.setGaussLocalizationOnCells([0,1],[0.,0.,1.,0.,1.,1.],[0.3,0.3,0.7,0.7,0.1,0.1],[0.3,0.6,0.1]) - f.setGaussLocalizationOnCells([2],[0.,0.,1.,0.,1.,1.],[0.3,0.3],[1.]) - f.setGaussLocalizationOnCells([3,4,5,6],[0.,0.,1.,0.,1.,1.,0.,1.],[0.1,0.1,0.2,0.2,0.3,0.3,0.4,0.4,0.5,0.5],[0.2,0.3,0.4,0.07,0.03]) - f.setMesh(None) - f1ts.setFieldProfile(f,mm,0,pfl) - self.assertTrue(f1ts.getUndergroundDataArray().isEqual(vals,1e-10)) - vals=DataArrayDouble(26) ; vals.iota(1040) ; f.setArray(vals) - self.assertRaises(InterpKernelException,f1ts.setFieldProfile,f,mm,0,pfl) - vals=DataArrayDouble(27) ; vals.iota(1000) - self.assertTrue(f1ts.getUndergroundDataArray().isEqual(vals,1e-10)) - # - f1ts=MEDFileField1TS() - f=MEDCouplingFieldDouble(ON_GAUSS_NE) - vals=DataArrayDouble(25) ; vals.iota(1000) - f.setArray(vals) - f.setName("anonymous") # f has no mesh it is not a bug - pfl=DataArrayInt([1,2,3,5,6,7,8]) ; pfl.setName("pfl") - f1ts.setFieldProfile(f,mm,0,pfl) - self.assertTrue(f1ts.getUndergroundDataArray().isEqual(vals,1e-10)) - vals2=DataArrayDouble(26) ; vals2.iota(1050) - f.setArray(vals2) - self.assertRaises(InterpKernelException,f1ts.setFieldProfile,f,mm,0,pfl) - self.assertTrue(f1ts.getUndergroundDataArray().isEqual(vals,1e-10)) - # - f1ts=MEDFileField1TS() - self.assertRaises(InterpKernelException,f1ts.setFieldProfile,f,mm,0,pfl) - self.assertRaises(InterpKernelException,f1ts.setFieldProfile,f,mm,0,pfl) - f.setArray(vals) - f1ts.setFieldProfile(f,mm,0,pfl) - pass - - def testWRMeshWithNoCells(self): - fname="Pyfile71.med" - a=DataArrayDouble(4) ; a.iota() - c=MEDCouplingCMesh() ; c.setCoords(a,a) ; m0=c.buildUnstructured() - m00=MEDCouplingUMesh("mesh",1) ; m00.setCoords(m0.getCoords()) ; m00.allocateCells(0) - m=MEDFileUMesh() - m.setMeshAtLevel(0,m00) - m.setRenumFieldArr(1,DataArrayInt(range(10,26))) - m.setFamilyFieldArr(1,DataArrayInt([-1,-1,-1,-1,-1,-2,-2,-2,-2,-2,-2,0,-1,-3,-3,-3])) - m.write(fname,2) - del m,a,c,m0,m00 - # - m=MEDFileMesh.New(fname) - self.assertEqual((),m.getNonEmptyLevels()) - self.assertTrue(m.getCoords().isEqual(DataArrayDouble([(0,0),(1,0),(2,0),(3,0),(0,1),(1,1),(2,1),(3,1),(0,2),(1,2),(2,2),(3,2),(0,3),(1,3),(2,3),(3,3)]),1e-12)) - self.assertTrue(m.getNumberFieldAtLevel(1).isEqual(DataArrayInt(range(10,26)))) - self.assertTrue(m.getFamilyFieldAtLevel(1).isEqual(DataArrayInt([-1,-1,-1,-1,-1,-2,-2,-2,-2,-2,-2,0,-1,-3,-3,-3]))) - pass - - def testWRQPolyg1(self): - fname="Pyfile72.med" - m=MEDCoupling1SGTUMesh("mesh",NORM_QUAD4) ; m.allocateCells() - m.insertNextCell([0,2,1,3]) - m.setCoords(DataArrayDouble([0.,0.,1.,1.,1.,0.,0.,1.],4,2)) - # - ms=[m.deepCpy() for i in xrange(4)] - for i,elt in enumerate(ms): - elt.translate([float(i)*1.5,0.]) - pass - m0=MEDCoupling1SGTUMesh.Merge1SGTUMeshes(ms).buildUnstructured() - m0.convertAllToPoly() - # - ms=[m.deepCpy() for i in xrange(5)] - for i,elt in enumerate(ms): - elt.translate([float(i)*1.5,1.5]) - pass - m1=MEDCoupling1SGTUMesh.Merge1SGTUMeshes(ms).buildUnstructured() - m1.convertAllToPoly() - m1.convertLinearCellsToQuadratic() - # - m=MEDCouplingUMesh.MergeUMeshes(m0,m1) - ## - mm=MEDFileUMesh() - mm.setMeshAtLevel(0,m) - grp0=DataArrayInt([0,2,3]) ; grp0.setName("grp0") - grp1=DataArrayInt([4,6,7]) ; grp1.setName("grp1") - grp2=DataArrayInt([0,1,2,4,5,6]) ; grp2.setName("grp2") - mm.setGroupsAtLevel(0,[grp0,grp1,grp2]) - ## - mm.write(fname,2) - del mm - # - mm_read=MEDFileUMesh(fname) - self.assertTrue(mm_read.getGroupArr(0,"grp0").isEqual(grp0)) - self.assertTrue(mm_read.getGroupArr(0,"grp1").isEqual(grp1)) - self.assertTrue(mm_read.getGroupArr(0,"grp2").isEqual(grp2)) - self.assertTrue(mm_read.getMeshAtLevel(0).isEqual(m,1e-12)) - ## - f=MEDCouplingFieldDouble(ON_CELLS) ; f.setName("MyFirstField") - f.setMesh(m) - arr0=DataArrayDouble(9) ; arr0.iota() - arr1=DataArrayDouble(9) ; arr1.iota(100) - arr=DataArrayDouble.Meld(arr0,arr1) ; arr.setInfoOnComponents(["mm [kg]","sds [m]"]) - f.setArray(arr) ; f.checkCoherency() - f.setTime(5.6,1,2) - ff=MEDFileField1TS() - ff.setFieldNoProfileSBT(f) - ff.write(fname,0) - ## - ff_read=MEDFileField1TS(fname) - f_read=ff_read.getFieldOnMeshAtLevel(ON_CELLS,0,mm_read) - self.assertTrue(f_read.isEqual(f,1e-12,1e-12)) - pass - - def testLoadIfNecessaryOnFromScratchFields0(self): - """ - This test checks that a call to loadArraysIfNecessary works (does nothing) on field data structure whatever its level 1TS, MTS, Fields. - """ - fname="Pyfile77.med" - coords=DataArrayDouble([(0,0,0),(2,1,0),(1,0,0),(1,1,0),(2,0,0),(0,1,0)]) - m=MEDCouplingUMesh("mesh",2) ; m.setCoords(coords) - m.allocateCells() - m.insertNextCell(NORM_QUAD4,[0,5,3,2]) - m.insertNextCell(NORM_QUAD4,[4,2,3,1]) - m.finishInsertingCells() - # - mm=MEDFileUMesh() ; mm.setMeshAtLevel(0,m) - ms=MEDFileMeshes() ; ms.pushMesh(mm) - fs=MEDFileFields() - arrs=4*[None] - # - ff0=MEDFileFieldMultiTS() ; fs.pushField(ff0) - f0=MEDCouplingFieldDouble(ON_GAUSS_NE) ; f0.setMesh(m) ; f0.setTimeUnit("ms") - f0.setTime(1.1,1,1) - f0.setName("myELNOField") - arrs[0]=DataArrayDouble([7,5,3,1,5,3,1,7]) ; arrs[0].setInfoOnComponent(0,"Comp0") - f0.setArray(arrs[0]) - ff0.appendFieldNoProfileSBT(f0) - # - f0.setTime(2.2,2,1) - arrs[1]=DataArrayDouble([1,7,5,3,7,5,3,1]) ; arrs[1].setInfoOnComponent(0,"Comp0") - f0.setArray(arrs[1]) - ff0.appendFieldNoProfileSBT(f0) - # - f0.setTime(3.3,3,1) - arrs[2]=DataArrayDouble([3,1,7,5,1,7,5,3]) ; arrs[2].setInfoOnComponent(0,"Comp0") - f0.setArray(arrs[2]) - ff0.appendFieldNoProfileSBT(f0) - # - f0.setTime(4.4,4,1) - arrs[3]=DataArrayDouble([5,3,1,7,3,1,7,5]) ; arrs[3].setInfoOnComponent(0,"Comp0") - f0.setArray(arrs[3]) - ff0.appendFieldNoProfileSBT(f0) - # - for i,arr in enumerate(arrs): - self.assertTrue(fs[0][i].getUndergroundDataArray().isEqual(arr,1e-12)) - fs[0][i].loadArraysIfNecessary() - self.assertTrue(fs[0][i].getUndergroundDataArray().isEqual(arr,1e-12)) - pass - fs.loadArraysIfNecessary() - for i,arr in enumerate(arrs): - self.assertTrue(fs[0][i].getUndergroundDataArray().isEqual(arr,1e-12)) - pass - fs[0].loadArraysIfNecessary() - for i,arr in enumerate(arrs): - self.assertTrue(fs[0][i].getUndergroundDataArray().isEqual(arr,1e-12)) - pass - pass - - def testField1TSSetFieldNoProfileSBTPerGeoTypes(self): - """ This test is very important, because the same mechanism is used by the MEDReader to generate a field on all the mesh without any processing and memory. - """ - fname="Pyfile78.med" - coords=DataArrayDouble([-0.3,-0.3,0., 0.2,-0.3,0., 0.7,-0.3,0., -0.3,0.2,0., 0.2,0.2,0., 0.7,0.2,0., -0.3,0.7,0., 0.2,0.7,0., 0.7,0.7,0. ],9,3) - targetConn=[0,3,4,1, 1,4,2, 4,5,2, 6,7,4,3, 7,8,5,4]; - m0=MEDCouplingUMesh("mesh",3) ; m0.setCoords(coords) - m0.allocateCells() - for elt in [[0,1,2,3],[1,2,3,4],[2,3,4,5],[3,4,5,6],[4,5,6,7],[5,6,7,8]]:#6 - m0.insertNextCell(NORM_TETRA4,elt) - pass - for elt in [[0,1,2,3,4],[1,2,3,4,5],[2,3,4,5,6],[3,4,5,6,7],[4,5,6,7,8]]:#5 - m0.insertNextCell(NORM_PYRA5,elt) - pass - for elt in [[0,1,2,3,4,5],[1,2,3,4,5,6],[2,3,4,5,6,7],[3,4,5,6,7,8]]:#4 - m0.insertNextCell(NORM_PENTA6,elt) - pass - m0.checkCoherency2() - m1=MEDCouplingUMesh(); m1.setName("mesh") - m1.setMeshDimension(2); - m1.allocateCells(5); - m1.insertNextCell(NORM_TRI3,3,targetConn[4:7]); - m1.insertNextCell(NORM_TRI3,3,targetConn[7:10]); - m1.insertNextCell(NORM_QUAD4,4,targetConn[0:4]); - m1.insertNextCell(NORM_QUAD4,4,targetConn[10:14]); - m1.insertNextCell(NORM_QUAD4,4,targetConn[14:18]); - m1.setCoords(coords); - m3=MEDCouplingUMesh("mesh",0) ; m3.setCoords(coords) - m3.allocateCells() - m3.insertNextCell(NORM_POINT1,[2]) - m3.insertNextCell(NORM_POINT1,[3]) - m3.insertNextCell(NORM_POINT1,[4]) - m3.insertNextCell(NORM_POINT1,[5]) - # - mm=MEDFileUMesh() - mm.setMeshAtLevel(0,m0) - mm.setMeshAtLevel(-1,m1) - mm.setMeshAtLevel(-3,m3) - mm.write(fname,2) - #### The file is written only with one mesh and no fields. Let's put a field on it geo types per geo types. - mm=MEDFileMesh.New(fname) - fs=MEDFileFields() - fmts=MEDFileFieldMultiTS() - f1ts=MEDFileField1TS() - for lev in mm.getNonEmptyLevels(): - for gt in mm.getGeoTypesAtLevel(lev): - p0=mm.getDirectUndergroundSingleGeoTypeMesh(gt) - f=MEDCouplingFieldDouble(ON_CELLS) ; f.setMesh(p0) - arr=DataArrayDouble(f.getNumberOfTuplesExpected()) ; arr.iota() - f.setArray(arr) ; f.setName("f0") - f1ts.setFieldNoProfileSBT(f) - pass - pass - self.assertEqual(mm.getNonEmptyLevels(),(0,-1,-3)) - for lev in [0,-1,-3]: - mm.getDirectUndergroundSingleGeoTypeMeshes(lev) # please let this line, it is for the test to emulate that - pass - fmts.pushBackTimeStep(f1ts) - fs.pushField(fmts) - fs.write(fname,0) - del fs,fmts,f1ts - #### The file contains now one mesh and one cell field with all cells wathever their level ang type fetched. - fs=MEDFileFields(fname) - self.assertEqual(len(fs),1) - self.assertEqual(len(fs[0]),1) - f1ts=fs[0][0] - self.assertEqual(f1ts.getFieldSplitedByType(),[(0,[(0,(0,4),'','')]),(3,[(0,(4,6),'','')]),(4,[(0,(6,9),'','')]),(14,[(0,(9,15),'','')]),(15,[(0,(15,20),'','')]),(16,[(0,(20,24),'','')])]) - self.assertTrue(f1ts.getUndergroundDataArray().isEqual(DataArrayDouble([0,1,2,3,0,1,0,1,2,0,1,2,3,4,5,0,1,2,3,4,0,1,2,3]),1e-12)) - pass - - def testMEDFileUMeshSetName(self): - """ This test is a small but important one for MEDReader in sauv mode. When .sauv file is loaded the convertion is performed in memory and a preparation is done then. - This preparation makes access to internal MEDCouplingMesh pointers whose name must be updated. - """ - fname="Pyfile79.med" - targetConn=[0,3,4,1, 1,4,2, 4,5,2, 6,7,4,3, 7,8,5,4]; - mm=MEDFileUMesh() - m0=MEDCouplingUMesh() ; m0.setMeshDimension(2) # important no name here. - coords=DataArrayDouble([-0.3,-0.3,0., 0.2,-0.3,0., 0.7,-0.3,0., -0.3,0.2,0., 0.2,0.2,0., 0.7,0.2,0., -0.3,0.7,0., 0.2,0.7,0., 0.7,0.7,0. ],9,3) - m0.allocateCells(5); - m0.insertNextCell(NORM_TRI3,3,targetConn[4:7]); - m0.insertNextCell(NORM_TRI3,3,targetConn[7:10]); - m0.insertNextCell(NORM_QUAD4,4,targetConn[0:4]); - m0.insertNextCell(NORM_QUAD4,4,targetConn[10:14]); - m0.insertNextCell(NORM_QUAD4,4,targetConn[14:18]); - m0.setCoords(coords); - mm.setMeshAtLevel(0,m0) - m2=MEDCouplingUMesh() ; m2.setMeshDimension(0) ; m2.setCoords(coords) # important no name here. - m2.allocateCells() - m2.insertNextCell(NORM_POINT1,[2]) - m2.insertNextCell(NORM_POINT1,[3]) - m2.insertNextCell(NORM_POINT1,[4]) - m2.insertNextCell(NORM_POINT1,[5]) - mm.setMeshAtLevel(-2,m2) - self.assertEqual(mm.getName(),"") - self.assertEqual(mm.getMeshAtLevel(0).getName(),"") - mm.forceComputationOfParts() - self.assertEqual(mm.getDirectUndergroundSingleGeoTypeMesh(NORM_TRI3).getName(),"") - mm.setName("abc") - self.assertEqual(mm.getName(),"abc") - self.assertEqual(mm.getDirectUndergroundSingleGeoTypeMesh(NORM_TRI3).getName(),"abc") - self.assertEqual(mm.getDirectUndergroundSingleGeoTypeMesh(NORM_QUAD4).getName(),"abc") - self.assertEqual(mm.getDirectUndergroundSingleGeoTypeMesh(NORM_POINT1).getName(),"abc") - self.assertEqual(mm.getMeshAtLevel(0).getName(),"abc") - pass - - def testMEDFileFieldsUnloadArraysWithoutDataLoss1(self): - fileName="Pyfile80.med" - m=MEDCouplingCMesh() ; m.setName("cmesh") - arr=DataArrayDouble(6) ; arr.iota() - m.setCoords(arr,arr) - nbCells=m.getNumberOfCells() - self.assertEqual(25,nbCells) - f=MEDCouplingFieldDouble(ON_CELLS) - f.setName("FieldOnCell") ; f.setMesh(m) - arr=DataArrayDouble(nbCells) ; arr.iota() - mm=MEDFileCMesh() - mm.setMesh(m) - # - fmts=MEDFileFieldMultiTS() - # - for i in xrange(nbCells): - t=(float(i)+0.1,i+1,-i-2) - f.setTime(*t) - arr2=DataArrayDouble(nbCells) - perm=DataArrayInt(nbCells) ; perm.iota(i) ; perm%=nbCells - arr2[perm]=arr - f.setArray(arr2) - f1ts=MEDFileField1TS() - f1ts.setFieldNoProfileSBT(f) - fmts.pushBackTimeStep(f1ts) - pass - fmts.unloadArraysWithoutDataLoss() - self.assertTrue(fmts[0].getUndergroundDataArray().isEqual(DataArrayDouble([0.,1.,2.,3.,4.,5.,6.,7.,8.,9.,10.,11.,12.,13.,14.,15.,16.,17.,18.,19.,20.,21.,22.,23.,24.]),1e-12)) - fs=MEDFileFields() ; fs.pushField(fmts) - self.assertTrue(fs[0][0].getUndergroundDataArray().isEqual(DataArrayDouble([0.,1.,2.,3.,4.,5.,6.,7.,8.,9.,10.,11.,12.,13.,14.,15.,16.,17.,18.,19.,20.,21.,22.,23.,24.]),1e-12)) - fs.unloadArraysWithoutDataLoss() - self.assertTrue(fs[0][0].getUndergroundDataArray().isEqual(DataArrayDouble([0.,1.,2.,3.,4.,5.,6.,7.,8.,9.,10.,11.,12.,13.,14.,15.,16.,17.,18.,19.,20.,21.,22.,23.,24.]),1e-12)) - f1ts=fs[0][0] - self.assertTrue(f1ts.getUndergroundDataArray().isEqual(DataArrayDouble([0.,1.,2.,3.,4.,5.,6.,7.,8.,9.,10.,11.,12.,13.,14.,15.,16.,17.,18.,19.,20.,21.,22.,23.,24.]),1e-12)) - f1ts.unloadArraysWithoutDataLoss() - self.assertTrue(f1ts.getUndergroundDataArray().isEqual(DataArrayDouble([0.,1.,2.,3.,4.,5.,6.,7.,8.,9.,10.,11.,12.,13.,14.,15.,16.,17.,18.,19.,20.,21.,22.,23.,24.]),1e-12)) - mm.write(fileName,2) - fs.write(fileName,0) - del m,fmts,mm,f,f1ts - ## - mm=MEDFileMesh.New(fileName) - fmts=MEDFileFieldMultiTS(fileName) - self.assertTrue(fmts[0].getUndergroundDataArray().isEqual(DataArrayDouble([0.,1.,2.,3.,4.,5.,6.,7.,8.,9.,10.,11.,12.,13.,14.,15.,16.,17.,18.,19.,20.,21.,22.,23.,24.]),1e-12)) - fmts.unloadArraysWithoutDataLoss() - self.assertTrue(not fmts[0].getUndergroundDataArray().isAllocated()) - fmts.loadArraysIfNecessary() - self.assertTrue(fmts[0].getUndergroundDataArray().isEqual(DataArrayDouble([0.,1.,2.,3.,4.,5.,6.,7.,8.,9.,10.,11.,12.,13.,14.,15.,16.,17.,18.,19.,20.,21.,22.,23.,24.]),1e-12)) - del mm,fmts - fs=MEDFileFields(fileName) - self.assertTrue(fs[0][0].getUndergroundDataArray().isEqual(DataArrayDouble([0.,1.,2.,3.,4.,5.,6.,7.,8.,9.,10.,11.,12.,13.,14.,15.,16.,17.,18.,19.,20.,21.,22.,23.,24.]),1e-12)) - fs.unloadArraysWithoutDataLoss() - self.assertTrue(not fs[0][0].getUndergroundDataArray().isAllocated()) - fs.loadArraysIfNecessary() - self.assertTrue(fs[0][0].getUndergroundDataArray().isEqual(DataArrayDouble([0.,1.,2.,3.,4.,5.,6.,7.,8.,9.,10.,11.,12.,13.,14.,15.,16.,17.,18.,19.,20.,21.,22.,23.,24.]),1e-12)) - del fs - f1ts=MEDFileField1TS(fileName) - self.assertTrue(f1ts.getUndergroundDataArray().isEqual(DataArrayDouble([0.,1.,2.,3.,4.,5.,6.,7.,8.,9.,10.,11.,12.,13.,14.,15.,16.,17.,18.,19.,20.,21.,22.,23.,24.]),1e-12)) - f1ts.unloadArraysWithoutDataLoss() - self.assertTrue(not f1ts.getUndergroundDataArray().isAllocated()) - f1ts.loadArraysIfNecessary() - self.assertTrue(f1ts.getUndergroundDataArray().isEqual(DataArrayDouble([0.,1.,2.,3.,4.,5.,6.,7.,8.,9.,10.,11.,12.,13.,14.,15.,16.,17.,18.,19.,20.,21.,22.,23.,24.]),1e-12)) - pass - - def testMEDFileUMeshLoadPart1(self): - """ This method tests MEDFileUMesh.LoadPart that loads only a part of a specified mesh in a MED file. The part is specfied using a slice of cell ids. Only nodes on which cells lies are loaded to reduce at most the amount of - memory of the returned instance. - """ - fileName="Pyfile81.med" - arr=DataArrayDouble(6) ; arr.iota() - m=MEDCouplingCMesh() ; m.setCoords(arr,arr) - m=m.buildUnstructured() - m.setName("Mesh") - m.changeSpaceDimension(3,0.) - infos=["aa [b]","cc [de]","gg [klm]"] - m.getCoords().setInfoOnComponents(infos) - m.checkCoherency2() - mm=MEDFileUMesh() - mm.setMeshAtLevel(0,m) - m1=MEDCouplingCMesh() ; m1.setCoords(arr) ; m1.setName("Mesh") - m1=m1.buildUnstructured() ; m1.setCoords(m.getCoords()) - mm.setMeshAtLevel(-1,m1) - renum0=DataArrayInt([3,6,7,10,11,0,2,1,9,8,5,4,12,13,14,24,23,22,21,20,19,18,17,16,15]) - famField0=DataArrayInt([-3,-6,-7,-10,-11,0,-2,-1,-9,-8,-5,-4,-12,-13,-14,-24,-23,-22,-21,-20,-19,-18,-17,-16,-15]) - namesCellL0=DataArrayAsciiChar(25,16) - namesCellL0[:]=["Cell#%.3d "%(i) for i in xrange(25)] - renumM1=DataArrayInt([3,4,0,2,1]) - famFieldM1=DataArrayInt([-3,-4,0,-2,-1]) - mm.setRenumFieldArr(0,renum0) - mm.setFamilyFieldArr(0,famField0) - mm.setNameFieldAtLevel(0,namesCellL0) - mm.setRenumFieldArr(-1,renumM1) - mm.setFamilyFieldArr(-1,famFieldM1) - renum1=DataArrayInt([13,16,17,20,21,10,12,11,19,18,15,14,22,23,24,34,33,32,31,30,29,28,27,26,25,45,44,43,42,41,40,39,38,37,36,35]) - famField1=DataArrayInt([-13,-16,-17,-20,-21,-10,-12,-11,-19,-18,-15,-14,-22,-23,-24,-34,-33,-32,-31,-30,-29,-28,-27,-26,-25,-45,-44,-43,-42,-41,-40,-39,-38,-37,-36,-35]) - namesNodes=DataArrayAsciiChar(36,16) - namesNodes[:]=["Node#%.3d "%(i) for i in xrange(36)] - mm.setRenumFieldArr(1,renum1) - mm.setFamilyFieldArr(1,famField1) - mm.setNameFieldAtLevel(1,namesNodes) - mm.setFamilyId("Fam7",77) - mm.setFamilyId("Fam8",88) - mm.setGroupsOnFamily("Fam7",["Grp0","Grp1"]) - mm.setGroupsOnFamily("Fam8",["Grp1","Grp2"]) - mm.write(fileName,2) - # - mm0=MEDFileUMesh.LoadPartOf(fileName,"Mesh",[NORM_QUAD4],[0,10,1]) - self.assertEqual(mm0.getAllGeoTypes(),[NORM_QUAD4]) - self.assertTrue(mm0.getDirectUndergroundSingleGeoTypeMesh(NORM_QUAD4).getNodalConnectivity().isEqual(DataArrayInt([1,0,6,7,2,1,7,8,3,2,8,9,4,3,9,10,5,4,10,11,7,6,12,13,8,7,13,14,9,8,14,15,10,9,15,16,11,10,16,17]))) - coo=DataArrayDouble([(0,0,0),(1,0,0),(2,0,0),(3,0,0),(4,0,0),(5,0,0),(0,1,0),(1,1,0),(2,1,0),(3,1,0),(4,1,0),(5,1,0),(0,2,0),(1,2,0),(2,2,0),(3,2,0),(4,2,0),(5,2,0)]) ; coo.setInfoOnComponents(infos) - self.assertTrue(mm0.getCoords().isEqual(coo,1e-12)) - self.assertTrue(mm0.getFamilyFieldAtLevel(0).isEqual(famField0[:10])) - self.assertTrue(mm0.getNumberFieldAtLevel(0).isEqual(renum0[:10])) - self.assertTrue(mm0.getNameFieldAtLevel(0).isEqual(namesCellL0[:10])) - self.assertTrue(mm0.getFamilyFieldAtLevel(1).isEqual(famField1[:18])) - self.assertTrue(mm0.getNumberFieldAtLevel(1).isEqual(renum1[:18])) - self.assertTrue(mm0.getNameFieldAtLevel(1).isEqual(namesNodes[:18])) - # - mm1=MEDFileUMesh.LoadPartOf(fileName,"Mesh",[NORM_QUAD4],[11,25,1]) - self.assertEqual(mm1.getAllGeoTypes(),[NORM_QUAD4]) - self.assertTrue(mm1.getDirectUndergroundSingleGeoTypeMesh(NORM_QUAD4).getNodalConnectivity().isEqual(DataArrayInt([1,0,6,7,2,1,7,8,3,2,8,9,4,3,9,10,6,5,11,12,7,6,12,13,8,7,13,14,9,8,14,15,10,9,15,16,12,11,17,18,13,12,18,19,14,13,19,20,15,14,20,21,16,15,21,22]))) - coo=DataArrayDouble([(1,2,0),(2,2,0),(3,2,0),(4,2,0),(5,2,0),(0,3,0),(1,3,0),(2,3,0),(3,3,0),(4,3,0),(5,3,0),(0,4,0),(1,4,0),(2,4,0),(3,4,0),(4,4,0),(5,4,0),(0,5,0),(1,5,0),(2,5,0),(3,5,0),(4,5,0),(5,5,0)]) ; coo.setInfoOnComponents(infos) - self.assertTrue(mm1.getCoords().isEqual(coo,1e-12)) - self.assertTrue(mm1.getFamilyFieldAtLevel(0).isEqual(famField0[11:])) - self.assertTrue(mm1.getNumberFieldAtLevel(0).isEqual(renum0[11:])) - self.assertTrue(mm1.getNameFieldAtLevel(0).isEqual(namesCellL0[11:])) - self.assertTrue(mm1.getFamilyFieldAtLevel(1).isEqual(famField1[13:])) - self.assertTrue(mm1.getNumberFieldAtLevel(1).isEqual(renum1[13:])) - self.assertTrue(mm1.getNameFieldAtLevel(1).isEqual(namesNodes[13:])) - # - mm2=MEDFileUMesh.LoadPartOf(fileName,"Mesh",[NORM_SEG2,NORM_QUAD4],[0,5,1,1,10,1]) - self.assertEqual(mm2.getAllGeoTypes(),[NORM_QUAD4,NORM_SEG2]) - self.assertTrue(mm2.getFamilyFieldAtLevel(0).isEqual(famField0[1:10])) - self.assertTrue(mm2.getNumberFieldAtLevel(0).isEqual(renum0[1:10])) - self.assertTrue(mm2.getNameFieldAtLevel(0).isEqual(namesCellL0[1:10])) - self.assertTrue(mm2.getFamilyFieldAtLevel(-1).isEqual(famFieldM1)) - self.assertTrue(mm2.getNumberFieldAtLevel(-1).isEqual(renumM1)) - self.assertTrue(mm2.getNameFieldAtLevel(-1) is None) - self.assertTrue(mm2.getDirectUndergroundSingleGeoTypeMesh(NORM_QUAD4).getNodalConnectivity().isEqual(DataArrayInt([2,1,7,8,3,2,8,9,4,3,9,10,5,4,10,11,7,6,12,13,8,7,13,14,9,8,14,15,10,9,15,16,11,10,16,17]))) - self.assertTrue(mm2.getDirectUndergroundSingleGeoTypeMesh(NORM_SEG2).getNodalConnectivity().isEqual(DataArrayInt([0,1,1,2,2,3,3,4,4,5]))) - coo=DataArrayDouble([(0,0,0),(1,0,0),(2,0,0),(3,0,0),(4,0,0),(5,0,0),(0,1,0),(1,1,0),(2,1,0),(3,1,0),(4,1,0),(5,1,0),(0,2,0),(1,2,0),(2,2,0),(3,2,0),(4,2,0),(5,2,0)]) ; coo.setInfoOnComponents(infos) - self.assertTrue(mm2.getCoords().isEqual(coo,1e-12)) - self.assertTrue(mm2.getFamilyFieldAtLevel(1).isEqual(famField1[:18])) - self.assertTrue(mm2.getNumberFieldAtLevel(1).isEqual(renum1[:18])) - self.assertTrue(mm2.getNameFieldAtLevel(1).isEqual(namesNodes[:18])) - pass - - def testMEDFileFieldsLoadPart1(self): - """This method tests partial loading on fields on CELL. It is the same principle than those in testMEDFileUMeshLoadPart1. - """ - fileName="Pyfile82.med" - meshName="Mesh" - compos=["aa [kg]","bbb [m/s]"] - arr=DataArrayDouble(6) ; arr.iota() - m=MEDCouplingCMesh() ; m.setCoords(arr,arr) - m=m.buildUnstructured() - m.setName(meshName) - m.changeSpaceDimension(3,0.) - infos=["aa [b]","cc [de]","gg [klm]"] - m.getCoords().setInfoOnComponents(infos) - m.checkCoherency2() - f=MEDCouplingFieldDouble(ON_CELLS,ONE_TIME) ; f.setMesh(m) - f.setName("Field") - arr=DataArrayDouble(25,2) ; arr.setInfoOnComponents(compos) - arr[:,0]=range(25) - arr[:,1]=range(100,125) - f.setArray(arr) - MEDLoader.WriteField(fileName,f,2) - f=MEDCouplingFieldDouble(ON_NODES,ONE_TIME) ; f.setMesh(m) - f.setName("FieldNode") - arr=DataArrayDouble(36,2) ; arr.setInfoOnComponents(compos) - arr[:,0]=range(200,236) - arr[:,1]=range(300,336) - f.setArray(arr) - f.checkCoherency() - MEDLoader.WriteFieldUsingAlreadyWrittenMesh(fileName,f) - # - ms=MEDFileMeshes() - mm=MEDFileUMesh.LoadPartOf(fileName,meshName,[NORM_QUAD4],[0,6,1]) - ms.pushMesh(mm) - fs=MEDFileFields.LoadPartOf(fileName,False,ms) - self.assertEqual(fs[1][0].getFieldSplitedByType(),[(40,[(1,(0,14),'','')])]) - # - ms=MEDFileMeshes() - mm=MEDFileUMesh.LoadPartOf(fileName,meshName,[NORM_QUAD4],[3,15,1]) - ms.pushMesh(mm) - fs=MEDFileFields.LoadPartOf(fileName,False,ms) - fs=fs.deepCpy() - fs[0][0].loadArrays() - arr=DataArrayDouble(12,2) ; arr[:,0]=range(3,15) ; arr[:,1]=range(103,115) - arr.setInfoOnComponents(compos) - self.assertTrue(fs[0][0].getUndergroundDataArray().isEqual(arr,1e-12)) - fs[1][0].loadArrays() - arr=DataArrayDouble(21,2) ; arr[:,0]=range(203,224) ; arr[:,1]=range(303,324) - arr.setInfoOnComponents(compos) - self.assertTrue(fs[1][0].getUndergroundDataArray().isEqual(arr,1e-12)) - pass - - def testMEDFileWithoutCells1(self): - fileName="Pyfile83.med" - coo=DataArrayDouble([(0,0,0),(1,0,0),(2,0,0)]) - coo.setInfoOnComponents(["aa [m]","bbb [s]","cccc [m/s]"]) - mm=MEDFileUMesh() - mm.setCoords(coo) - mm.setName("mesh") - mm.write(fileName,2) - # - mm=MEDFileMesh.New(fileName) - self.assertEqual(mm.getName(),"mesh") - self.assertTrue(mm.getCoords().isEqual(coo,1e-12)) - pass - - def testZipCoordsWithLoadPart1(self): - """ Test close to Pyfile82.med except that here zipCoords on MEDFileUMesh is invoked here to see if the PartDef is correctly updated. - """ - fileName="Pyfile84.med" - meshName="Mesh" - compos=["aa [kg]","bbb [m/s]"] - arr=DataArrayDouble(6) ; arr.iota() - m=MEDCouplingCMesh() ; m.setCoords(arr,arr) - m=m.buildUnstructured() - m.setName(meshName) - m.changeSpaceDimension(3,0.) - infos=["aa [b]","cc [de]","gg [klm]"] - m.getCoords().setInfoOnComponents(infos) - m.checkCoherency2() - f=MEDCouplingFieldDouble(ON_CELLS,ONE_TIME) ; f.setMesh(m) - f.setName("Field") - arr=DataArrayDouble(25,2) ; arr.setInfoOnComponents(compos) - arr[:,0]=range(25) - arr[:,1]=range(100,125) - f.setArray(arr) - MEDLoader.WriteField(fileName,f,2) - f=MEDCouplingFieldDouble(ON_NODES,ONE_TIME) ; f.setMesh(m) - f.setName("FieldNode") - arr=DataArrayDouble(36,2) ; arr.setInfoOnComponents(compos) - arr[:,0]=range(200,236) - arr[:,1]=range(300,336) - f.setArray(arr) - f.checkCoherency() - MEDLoader.WriteFieldUsingAlreadyWrittenMesh(fileName,f) - # - ms=MEDFileMeshes() - mm=MEDFileUMesh.LoadPartOf(fileName,meshName,[NORM_QUAD4],[4,6,1]) - ms.pushMesh(mm) - spd=mm.getPartDefAtLevel(0,NORM_QUAD4) - self.assertEqual(spd.getSlice(),slice(4,6,1)) - spd=mm.getPartDefAtLevel(1) - self.assertEqual(spd.getSlice(),slice(4,14,1)) - self.assertTrue(spd.getNumberOfElems()==10 and spd.getNumberOfElems()==mm.getNumberOfNodes()) - mm.zipCoords() # <- The important line is here ! - spd=mm.getPartDefAtLevel(0,NORM_QUAD4) - self.assertEqual(spd.getSlice(),slice(4,6,1)) - spd=mm.getPartDefAtLevel(1) - self.assertTrue(spd.getNumberOfElems()==8 and spd.getNumberOfElems()==mm.getNumberOfNodes()) - self.assertTrue(spd.toDAI().isEqual(DataArrayInt([4,5,6,7,10,11,12,13]))) - fs=MEDFileFields.LoadPartOf(fileName,False,ms) - fs[0][0].loadArrays() - arr=DataArrayDouble([(4,104),(5,105)]) - arr.setInfoOnComponents(compos) - self.assertTrue(fs[0][0].getUndergroundDataArray().isEqual(arr,1e-12)) - fs[1][0].loadArrays() - arr=DataArrayDouble([(204,304),(205,305),(206,306),(207,307),(210,310),(211,311),(212,312),(213,313)]) - arr.setInfoOnComponents(compos) - self.assertTrue(fs[1][0].getUndergroundDataArray().isEqual(arr,1e-12)) - pass - - def testMEDFileCMeshSetGroupsAtLevel(self): - """ Non regression test to check that setGroupsAtLevel is available with MEDFileCMesh. - """ - m=MEDCouplingCMesh() ; m.setCoords(DataArrayDouble([0,1,2,3,4]),DataArrayDouble([0,1,2,3,4])) - m.setName("Mesh") - mm=MEDFileCMesh() ; mm.setMesh(m) - grp=DataArrayInt([1,3,4,5,7]) ; grp.setName("MyAssembly") - mm.setGroupsAtLevel(0,[grp]) - self.assertTrue(mm.getFamilyFieldAtLevel(0).isEqual(DataArrayInt([-1,-2,-1,-2,-2,-2,-1,-2,-1,-1,-1,-1,-1,-1,-1,-1]))) - pass - - def testMEDFileUMeshBuildExtrudedMesh1(self): - """ New functionality of MEDFileUMesh.buildExtrudedMesh.""" - fileName="Pyfile85.med" - meshName2D="Mesh" - meshName1D="Mesh1D" - meshName3DOut="Mesh3D" - # - d1=DataArrayInt([0,4,20,24]) - d2=DataArrayInt([0,1,2,3,7,8,12,13,17,18,19,20]) - # - a=DataArrayDouble(6) ; a.iota() - m=MEDCouplingCMesh() ; m.setCoords(a,a) - m=m.buildUnstructured() - d1c=d1.buildComplement(m.getNumberOfCells()) - m=m[d1c] ; m.zipCoords() - m0=m[d2] ; m1=m[d2.buildComplement(m.getNumberOfCells())] - m0.simplexize(0) - m=MEDCouplingUMesh.MergeUMeshesOnSameCoords([m0,m1]) - m.setName(meshName2D) - mMinus1,a,b,c,d=m.buildDescendingConnectivity() - e=d.deltaShiftIndex().getIdsEqual(1) - # - mm=MEDFileUMesh() - mm.setMeshAtLevel(0,m) ; mm.setMeshAtLevel(-1,mMinus1) - grp0=DataArrayInt([0,1,2,3,4,5,24,25,26]) ; grp0.setName("grp0") - mm.setGroupsAtLevel(0,[grp0]) - grp1=e ; grp1.setName("grp1") - mm.setGroupsAtLevel(-1,[grp1]) - mm.write(fileName,2) - # - a=DataArrayDouble(3) ; a.iota() - tmp=MEDCouplingCMesh() ; tmp.setCoords(a) ; tmp=tmp.buildUnstructured() - tmp.setName(meshName1D) - tmp.changeSpaceDimension(3) - tmp.setCoords(tmp.getCoords()[:,[1,2,0]]) - mm1D=MEDFileUMesh() - mm1D.setMeshAtLevel(0,tmp) - mm1D.write(fileName,0) - # test is here ! - mm2D=MEDFileMesh.New(fileName,meshName2D) - mm1D=MEDFileMesh.New(fileName,meshName1D) - m1D=mm1D.getMeshAtLevel(0) - mm3D=mm2D.buildExtrudedMesh(m1D,0) - # - self.assertEqual(mm3D.getName(),mm2D.getName()) - self.assertEqual(mm3D.getNumberOfCellsAtLevel(0),66) - self.assertEqual(mm3D.getNumberOfCellsAtLevel(-1),194) - self.assertEqual(mm3D.getGroupsNames(),('grp0','grp0_extruded','grp0_top','grp1','grp1_extruded','grp1_top')) - self.assertEqual(mm3D.getGrpNonEmptyLevels("grp0"),(-1,)) - self.assertEqual(mm3D.getGrpNonEmptyLevels("grp0_top"),(-1,)) - self.assertEqual(mm3D.getGrpNonEmptyLevels("grp0_extruded"),(0,)) - self.assertEqual(mm3D.getGrpNonEmptyLevels("grp1"),(-2,)) - self.assertEqual(mm3D.getGrpNonEmptyLevels("grp1_top"),(-2,)) - self.assertEqual(mm3D.getGrpNonEmptyLevels("grp1_extruded"),(-1,)) - d=DataArrayDouble([(1.,0.,0.),(2.,0.,0.),(3.,0.,0.),(4.,0.,0.),(0.,1.,0.),(1.,1.,0.),(2.,1.,0.),(3.,1.,0.),(4.,1.,0.),(5.,1.,0.),(0.,2.,0.),(1.,2.,0.),(2.,2.,0.),(3.,2.,0.),(4.,2.,0.),(5.,2.,0.),(0.,3.,0.),(1.,3.,0.),(2.,3.,0.),(3.,3.,0.),(4.,3.,0.),(5.,3.,0.),(0.,4.,0.),(1.,4.,0.),(2.,4.,0.),(3.,4.,0.),(4.,4.,0.),(5.,4.,0.),(1.,5.,0.),(2.,5.,0.),(3.,5.,0.),(4.,5.,0.),(1.,0.,1.),(2.,0.,1.),(3.,0.,1.),(4.,0.,1.),(0.,1.,1.),(1.,1.,1.),(2.,1.,1.),(3.,1.,1.),(4.,1.,1.),(5.,1.,1.),(0.,2.,1.),(1.,2.,1.),(2.,2.,1.),(3.,2.,1.),(4.,2.,1.),(5.,2.,1.),(0.,3.,1.),(1.,3.,1.),(2.,3.,1.),(3.,3.,1.),(4.,3.,1.),(5.,3.,1.),(0.,4.,1.),(1.,4.,1.),(2.,4.,1.),(3.,4.,1.),(4.,4.,1.),(5.,4.,1.),(1.,5.,1.),(2.,5.,1.),(3.,5.,1.),(4.,5.,1.),(1.,0.,2.),(2.,0.,2.),(3.,0.,2.),(4.,0.,2.),(0.,1.,2.),(1.,1.,2.),(2.,1.,2.),(3.,1.,2.),(4.,1.,2.),(5.,1.,2.),(0.,2.,2.),(1.,2.,2.),(2.,2.,2.),(3.,2.,2.),(4.,2.,2.),(5.,2.,2.),(0.,3.,2.),(1.,3.,2.),(2.,3.,2.),(3.,3.,2.),(4.,3.,2.),(5.,3.,2.),(0.,4.,2.),(1.,4.,2.),(2.,4.,2.),(3.,4.,2.),(4.,4.,2.),(5.,4.,2.),(1.,5.,2.),(2.,5.,2.),(3.,5.,2.),(4.,5.,2.)]) - self.assertTrue(mm3D.getCoords().isEqual(d,1e-12)) - d=DataArrayInt([16,1,0,5,33,32,37,16,1,5,6,33,37,38,16,2,1,6,34,33,38,16,2,6,7,34,38,39,16,3,2,7,35,34,39,16,3,7,8,35,39,40,16,5,4,10,37,36,42,16,5,10,11,37,42,43,16,9,8,14,41,40,46,16,9,14,15,41,46,47,16,11,10,16,43,42,48,16,11,16,17,43,48,49,16,15,14,20,47,46,52,16,15,20,21,47,52,53,16,17,16,22,49,48,54,16,17,22,23,49,54,55,16,21,20,26,53,52,58,16,21,26,27,53,58,59,16,24,23,28,56,55,60,16,24,28,29,56,60,61,16,25,24,29,57,56,61,16,25,29,30,57,61,62,16,26,25,30,58,57,62,16,26,30,31,58,62,63,16,33,32,37,65,64,69,16,33,37,38,65,69,70,16,34,33,38,66,65,70,16,34,38,39,66,70,71,16,35,34,39,67,66,71,16,35,39,40,67,71,72,16,37,36,42,69,68,74,16,37,42,43,69,74,75,16,41,40,46,73,72,78,16,41,46,47,73,78,79,16,43,42,48,75,74,80,16,43,48,49,75,80,81,16,47,46,52,79,78,84,16,47,52,53,79,84,85,16,49,48,54,81,80,86,16,49,54,55,81,86,87,16,53,52,58,85,84,90,16,53,58,59,85,90,91,16,56,55,60,88,87,92,16,56,60,61,88,92,93,16,57,56,61,89,88,93,16,57,61,62,89,93,94,16,58,57,62,90,89,94,16,58,62,63,90,94,95,18,6,5,11,12,38,37,43,44,18,7,6,12,13,39,38,44,45,18,8,7,13,14,40,39,45,46,18,12,11,17,18,44,43,49,50,18,13,12,18,19,45,44,50,51,18,14,13,19,20,46,45,51,52,18,18,17,23,24,50,49,55,56,18,19,18,24,25,51,50,56,57,18,20,19,25,26,52,51,57,58,18,38,37,43,44,70,69,75,76,18,39,38,44,45,71,70,76,77,18,40,39,45,46,72,71,77,78,18,44,43,49,50,76,75,81,82,18,45,44,50,51,77,76,82,83,18,46,45,51,52,78,77,83,84,18,50,49,55,56,82,81,87,88,18,51,50,56,57,83,82,88,89,18,52,51,57,58,84,83,89,90]) - self.assertTrue(mm3D[0].getNodalConnectivity().isEqual(d)) - d=DataArrayInt([0,7,14,21,28,35,42,49,56,63,70,77,84,91,98,105,112,119,126,133,140,147,154,161,168,175,182,189,196,203,210,217,224,231,238,245,252,259,266,273,280,287,294,301,308,315,322,329,336,345,354,363,372,381,390,399,408,417,426,435,444,453,462,471,480,489,498]) - self.assertTrue(mm3D[0].getNodalConnectivityIndex().isEqual(d)) - d=DataArrayInt([3,1,0,5,3,1,5,6,3,2,1,6,3,2,6,7,3,3,2,7,3,3,7,8,3,5,4,10,3,5,10,11,3,9,8,14,3,9,14,15,3,11,10,16,3,11,16,17,3,15,14,20,3,15,20,21,3,17,16,22,3,17,22,23,3,21,20,26,3,21,26,27,3,24,23,28,3,24,28,29,3,25,24,29,3,25,29,30,3,26,25,30,3,26,30,31,3,65,64,69,3,65,69,70,3,66,65,70,3,66,70,71,3,67,66,71,3,67,71,72,3,69,68,74,3,69,74,75,3,73,72,78,3,73,78,79,3,75,74,80,3,75,80,81,3,79,78,84,3,79,84,85,3,81,80,86,3,81,86,87,3,85,84,90,3,85,90,91,3,88,87,92,3,88,92,93,3,89,88,93,3,89,93,94,3,90,89,94,3,90,94,95,4,1,0,32,33,4,0,5,37,32,4,5,1,33,37,4,5,6,38,37,4,6,1,33,38,4,2,1,33,34,4,6,2,34,38,4,6,7,39,38,4,7,2,34,39,4,3,2,34,35,4,7,3,35,39,4,7,8,40,39,4,8,3,35,40,4,5,4,36,37,4,4,10,42,36,4,10,5,37,42,4,10,11,43,42,4,11,5,37,43,4,9,8,40,41,4,8,14,46,40,4,14,9,41,46,4,14,15,47,46,4,15,9,41,47,4,10,16,48,42,4,16,11,43,48,4,16,17,49,48,4,17,11,43,49,4,14,20,52,46,4,20,15,47,52,4,20,21,53,52,4,21,15,47,53,4,16,22,54,48,4,22,17,49,54,4,22,23,55,54,4,23,17,49,55,4,20,26,58,52,4,26,21,53,58,4,26,27,59,58,4,27,21,53,59,4,24,23,55,56,4,23,28,60,55,4,28,24,56,60,4,28,29,61,60,4,29,24,56,61,4,25,24,56,57,4,29,25,57,61,4,29,30,62,61,4,30,25,57,62,4,26,25,57,58,4,30,26,58,62,4,30,31,63,62,4,31,26,58,63,4,11,12,44,43,4,12,6,38,44,4,12,13,45,44,4,13,7,39,45,4,13,14,46,45,4,17,18,50,49,4,18,12,44,50,4,18,19,51,50,4,19,13,45,51,4,19,20,52,51,4,24,18,50,56,4,25,19,51,57,4,33,32,64,65,4,32,37,69,64,4,37,33,65,69,4,37,38,70,69,4,38,33,65,70,4,34,33,65,66,4,38,34,66,70,4,38,39,71,70,4,39,34,66,71,4,35,34,66,67,4,39,35,67,71,4,39,40,72,71,4,40,35,67,72,4,37,36,68,69,4,36,42,74,68,4,42,37,69,74,4,42,43,75,74,4,43,37,69,75,4,41,40,72,73,4,40,46,78,72,4,46,41,73,78,4,46,47,79,78,4,47,41,73,79,4,42,48,80,74,4,48,43,75,80,4,48,49,81,80,4,49,43,75,81,4,46,52,84,78,4,52,47,79,84,4,52,53,85,84,4,53,47,79,85,4,48,54,86,80,4,54,49,81,86,4,54,55,87,86,4,55,49,81,87,4,52,58,90,84,4,58,53,85,90,4,58,59,91,90,4,59,53,85,91,4,56,55,87,88,4,55,60,92,87,4,60,56,88,92,4,60,61,93,92,4,61,56,88,93,4,57,56,88,89,4,61,57,89,93,4,61,62,94,93,4,62,57,89,94,4,58,57,89,90,4,62,58,90,94,4,62,63,95,94,4,63,58,90,95,4,43,44,76,75,4,44,38,70,76,4,44,45,77,76,4,45,39,71,77,4,45,46,78,77,4,49,50,82,81,4,50,44,76,82,4,50,51,83,82,4,51,45,77,83,4,51,52,84,83,4,56,50,82,88,4,57,51,83,89,4,6,5,11,12,4,7,6,12,13,4,8,7,13,14,4,12,11,17,18,4,13,12,18,19,4,14,13,19,20,4,18,17,23,24,4,19,18,24,25,4,20,19,25,26,4,70,69,75,76,4,71,70,76,77,4,72,71,77,78,4,76,75,81,82,4,77,76,82,83,4,78,77,83,84,4,82,81,87,88,4,83,82,88,89,4,84,83,89,90]) - self.assertTrue(mm3D[-1].getNodalConnectivity().isEqual(d)) - d=DataArrayInt([0,4,8,12,16,20,24,28,32,36,40,44,48,52,56,60,64,68,72,76,80,84,88,92,96,100,104,108,112,116,120,124,128,132,136,140,144,148,152,156,160,164,168,172,176,180,184,188,192,197,202,207,212,217,222,227,232,237,242,247,252,257,262,267,272,277,282,287,292,297,302,307,312,317,322,327,332,337,342,347,352,357,362,367,372,377,382,387,392,397,402,407,412,417,422,427,432,437,442,447,452,457,462,467,472,477,482,487,492,497,502,507,512,517,522,527,532,537,542,547,552,557,562,567,572,577,582,587,592,597,602,607,612,617,622,627,632,637,642,647,652,657,662,667,672,677,682,687,692,697,702,707,712,717,722,727,732,737,742,747,752,757,762,767,772,777,782,787,792,797,802,807,812,817,822,827,832,837,842,847,852,857,862,867,872,877,882,887,892,897,902,907,912,917,922]) - self.assertTrue(mm3D[-1].getNodalConnectivityIndex().isEqual(d)) - d=DataArrayInt([1,1,0,1,0,5,1,5,1,1,5,6,1,6,1,1,2,1,1,6,2,1,6,7,1,7,2,1,3,2,1,7,3,1,7,8,1,8,3,1,5,4,1,4,10,1,10,5,1,10,11,1,11,5,1,9,8,1,8,14,1,14,9,1,14,15,1,15,9,1,10,16,1,16,11,1,16,17,1,17,11,1,14,20,1,20,15,1,20,21,1,21,15,1,16,22,1,22,17,1,22,23,1,23,17,1,20,26,1,26,21,1,26,27,1,27,21,1,24,23,1,23,28,1,28,24,1,28,29,1,29,24,1,25,24,1,29,25,1,29,30,1,30,25,1,26,25,1,30,26,1,30,31,1,31,26,1,11,12,1,12,6,1,12,13,1,13,7,1,13,14,1,17,18,1,18,12,1,18,19,1,19,13,1,19,20,1,24,18,1,25,19,1,65,64,1,64,69,1,69,65,1,69,70,1,70,65,1,66,65,1,70,66,1,70,71,1,71,66,1,67,66,1,71,67,1,71,72,1,72,67,1,69,68,1,68,74,1,74,69,1,74,75,1,75,69,1,73,72,1,72,78,1,78,73,1,78,79,1,79,73,1,74,80,1,80,75,1,80,81,1,81,75,1,78,84,1,84,79,1,84,85,1,85,79,1,80,86,1,86,81,1,86,87,1,87,81,1,84,90,1,90,85,1,90,91,1,91,85,1,88,87,1,87,92,1,92,88,1,92,93,1,93,88,1,89,88,1,93,89,1,93,94,1,94,89,1,90,89,1,94,90,1,94,95,1,95,90,1,75,76,1,76,70,1,76,77,1,77,71,1,77,78,1,81,82,1,82,76,1,82,83,1,83,77,1,83,84,1,88,82,1,89,83]) - self.assertTrue(mm3D[-2].getNodalConnectivity().isEqual(d)) - d=DataArrayInt(129) ; d.iota() ; d*=3 - self.assertTrue(mm3D[-2].getNodalConnectivityIndex().isEqual(d)) - # - self.assertEqual(mm3D.getGroupArr(-1,"grp0").getName(),"grp0") - self.assertEqual(mm3D.getGroupArr(-2,"grp1").getName(),"grp1") - self.assertTrue(mm3D.getGroupArr(-1,"grp0").isEqualWithoutConsideringStr(DataArrayInt([0,1,2,3,4,5,176,177,178]))) - self.assertTrue(mm3D.getGroupArr(-1,"grp0_top").isEqualWithoutConsideringStr(DataArrayInt([24,25,26,27,28,29,185,186,187]))) - self.assertTrue(mm3D.getGroupArr(-2,"grp1").isEqualWithoutConsideringStr(DataArrayInt([0,1,5,9,12,13,14,18,22,23,30,31,33,37,38,40,42,46,50,51]))) - self.assertTrue(mm3D.getGroupArr(-2,"grp1_top").isEqualWithoutConsideringStr(DataArrayInt([64,65,69,73,76,77,78,82,86,87,94,95,97,101,102,104,106,110,114,115]))) - self.assertTrue(mm3D.getGroupArr(0,"grp0_extruded").isEqualWithoutConsideringStr(DataArrayInt([0,1,2,3,4,5,24,25,26,27,28,29,48,49,50,57,58,59]))) - self.assertTrue(mm3D.getGroupArr(-1,"grp1_extruded").isEqualWithoutConsideringStr(DataArrayInt([48,49,53,57,60,61,62,66,70,71,78,79,81,85,86,88,90,94,98,99,112,113,117,121,124,125,126,130,134,135,142,143,145,149,150,152,154,158,162,163]))) - mm3D.setName("MeshExtruded") - mm3D.write(fileName,0) - pass - - @unittest.skipUnless(MEDCouplingHasNumPyBindings(),"requires numpy") - def testMEDFileUMeshPickeling1(self): - import cPickle - outFileName="Pyfile86.med" - c=DataArrayDouble([-0.3,-0.3, 0.2,-0.3, 0.7,-0.3, -0.3,0.2, 0.2,0.2, 0.7,0.2, -0.3,0.7, 0.2,0.7, 0.7,0.7 ],9,2) - c.setInfoOnComponents(["aa","bbb"]) - targetConn=[0,3,4,1, 1,4,2, 4,5,2, 6,7,4,3, 7,8,5,4] - m=MEDCouplingUMesh(); - m.setMeshDimension(2); - m.allocateCells(5); - m.insertNextCell(NORM_TRI3,3,targetConn[4:7]) - m.insertNextCell(NORM_TRI3,3,targetConn[7:10]) - m.insertNextCell(NORM_QUAD4,4,targetConn[0:4]) - m.insertNextCell(NORM_POLYGON,4,targetConn[10:14]) - m.insertNextCell(NORM_POLYGON,4,targetConn[14:18]) - m.finishInsertingCells(); - m.setCoords(c) - m.checkCoherency() - m1=MEDCouplingUMesh.New(); - m1.setMeshDimension(1); - m1.allocateCells(3); - m1.insertNextCell(NORM_SEG2,2,[1,4]) - m1.insertNextCell(NORM_SEG2,2,[3,6]) - m1.insertNextCell(NORM_SEG3,3,[2,8,5]) - m1.finishInsertingCells(); - m1.setCoords(c) - m1.checkCoherency() - m2=MEDCouplingUMesh.New(); - m2.setMeshDimension(0); - m2.allocateCells(4); - m2.insertNextCell(NORM_POINT1,1,[1]) - m2.insertNextCell(NORM_POINT1,1,[3]) - m2.insertNextCell(NORM_POINT1,1,[2]) - m2.insertNextCell(NORM_POINT1,1,[6]) - m2.finishInsertingCells(); - m2.setCoords(c) - m2.checkCoherency() - # - mm=MEDFileUMesh.New() - self.assertTrue(mm.getUnivNameWrStatus()) - mm.setName("MyFirstMEDCouplingMEDmesh") - mm.setDescription("IHopeToConvinceLastMEDMEMUsers") - mm.setCoords(c) - mm[-1]=m1; - mm[0]=m; - mm.setRenumFieldArr(0,DataArrayInt([32,41,50,56,7])) - mm[-2]=m2; - mm.setRenumFieldArr(-2,DataArrayInt([102,52,45,63])) - # playing with groups - g1_2=DataArrayInt.New() - g1_2.setValues([1,3],2,1) - g1_2.setName("G1") - g2_2=DataArrayInt.New() - g2_2.setValues([1,2,3],3,1) - g2_2.setName("G2") - mm.setGroupsAtLevel(0,[g1_2,g2_2],False) - g1_1=DataArrayInt.New() - g1_1.setValues([0,1,2],3,1) - g1_1.setName("G1") - g2_1=DataArrayInt.New() - g2_1.setValues([0,2],2,1) - g2_1.setName("G2") - mm.setGroupsAtLevel(-1,[g1_1,g2_1],False) - g1_N=DataArrayInt.New() - g1_N.setValues(range(8),8,1) - g1_N.setName("G1") - g2_N=DataArrayInt.New() - g2_N.setValues(range(9),9,1) - g2_N.setName("G2") - mm.setGroupsAtLevel(1,[g1_N,g2_N],False) - mm.createGroupOnAll(0,"GrpOnAllCell") - # check content of mm - t=mm.getGroupArr(0,"G1",False) - self.assertTrue(g1_2.isEqual(t)); - t=mm.getGroupArr(0,"G2",False) - self.assertTrue(g2_2.isEqual(t)); - t=mm.getGroupArr(-1,"G1",False) - self.assertTrue(g1_1.isEqual(t)); - t=mm.getGroupArr(-1,"G2",False) - self.assertTrue(g2_1.isEqual(t)); - t=mm.getGroupArr(1,"G1",False) - self.assertTrue(g1_N.isEqual(t)); - t=mm.getGroupArr(1,"G2",False) - self.assertTrue(g2_N.isEqual(t)); - self.assertTrue(mm.existsGroup("GrpOnAllCell")); - t=mm.getGroupArr(0,"GrpOnAllCell") - # - st=cPickle.dumps(mm,cPickle.HIGHEST_PROTOCOL) - mm2=cPickle.loads(st) - self.assertTrue(mm.isEqual(mm2,1e-12)[0]) - pass - - def testMEDFileFieldsLoadSpecificEntities1(self): - nbNodes=11 - fieldName="myField" - fileName="Pyfile87.med" - nbPdt=10 - meshName="Mesh" - # - m=MEDCouplingCMesh() - arr=DataArrayDouble(nbNodes) ; arr.iota() - m.setCoords(arr) - m=m.buildUnstructured() - m.setName(meshName) - # - fmts=MEDFileFieldMultiTS() - for i in xrange(nbPdt): - f=MEDCouplingFieldDouble(ON_NODES) - f.setMesh(m) - arr=DataArrayDouble(nbNodes) ; arr.iota() ; arr*=i - f.setArray(arr) - f.setName(fieldName) - f.setTime(float(i),i,0) - fmts.appendFieldNoProfileSBT(f) - pass - # - mm=MEDFileUMesh() ; mm[0]=m - fmts.write(fileName,2) - mm.write(fileName,0) - # - fs=MEDFileFields(fileName,False) - fs2=MEDFileFields.LoadSpecificEntities(fileName,[(ON_NODES,NORM_ERROR)],False) - fs.loadArraysIfNecessary() - fs2.loadArraysIfNecessary() - for i in xrange(nbPdt): - self.assertTrue(fs[fieldName][i].getUndergroundDataArray().isEqual(fs2[fieldName][i].getUndergroundDataArray(),1e-12)) - pass - m1=MEDCouplingCMesh() ; m1.setCoords(DataArrayDouble([0,1,2,3]),DataArrayDouble([0,1])) ; m1=m1.buildUnstructured() ; m1.simplexize(0) - m2=MEDCouplingCMesh() ; m2.setCoords(DataArrayDouble([3,4,5]),DataArrayDouble([0,1])) ; m2=m2.buildUnstructured() - m3=MEDCouplingUMesh.MergeUMeshes(m1,m2) ; m3.setName(meshName) - fmts=MEDFileFieldMultiTS() - for i in xrange(nbPdt): - f=MEDCouplingFieldDouble(ON_CELLS) - f.setMesh(m3) - arr=DataArrayDouble(8) ; arr.iota() ; arr*=i - f.setArray(arr) - f.setName(fieldName) - f.setTime(float(i),i,0) - fmts.appendFieldNoProfileSBT(f) - pass - mm=MEDFileUMesh() ; mm[0]=m3 - del mm[0] - self.assertEqual(mm.getNonEmptyLevels(),()) - mm[0]=m3 - self.assertEqual(mm.getNonEmptyLevels(),(0,)) - fmts.write(fileName,2) - fs=MEDFileFields(fileName,False) - fs2=MEDFileFields.LoadSpecificEntities(fileName,[(ON_CELLS,NORM_TRI3)],False) - fs3=MEDFileFieldMultiTS.LoadSpecificEntities(fileName,fieldName,[(ON_CELLS,NORM_QUAD4)],False) - fs4=MEDFileFields.LoadSpecificEntities(fileName,[(ON_CELLS,NORM_TRI3),(ON_CELLS,NORM_QUAD4)],False) - fs.loadArraysIfNecessary() - fs2.loadArraysIfNecessary() - fs3.loadArraysIfNecessary() - fs4.loadArraysIfNecessary() - for i in xrange(nbPdt): - self.assertTrue(fs[fieldName][i].getUndergroundDataArray()[:6].isEqual(fs2[fieldName][i].getUndergroundDataArray(),1e-12)) - self.assertTrue(fs[fieldName][i].getUndergroundDataArray()[6:8].isEqual(fs3[i].getUndergroundDataArray(),1e-12)) - self.assertTrue(fs[fieldName][i].getUndergroundDataArray().isEqual(fs4[fieldName][i].getUndergroundDataArray(),1e-12)) - pass - pass - - def testMEDFileLotsOfTSRW1(self): - nbNodes=11 - fieldName="myField" - fileName="Pyfile88.med" - nbPdt=300 # <- perftest = 30000 - meshName="Mesh" - # - maxPdt=100 # <- optimum = 500 - m=MEDCouplingCMesh() - arr=DataArrayDouble(nbNodes) ; arr.iota() - m.setCoords(arr) - m=m.buildUnstructured() - m.setName(meshName) - # - nbOfField=nbPdt/maxPdt - fs=MEDFileFields() - for j in xrange(nbOfField): - fmts=MEDFileFieldMultiTS() - s=DataArray.GetSlice(slice(0,nbPdt,1),j,nbOfField) - for i in xrange(s.start,s.stop,s.step): - f=MEDCouplingFieldDouble(ON_NODES) - f.setMesh(m) - arr=DataArrayDouble(nbNodes) ; arr.iota() ; arr*=i - f.setArray(arr) - f.setName("%s_%d"%(fieldName,j)) - f.setTime(float(i),i,0) - fmts.appendFieldNoProfileSBT(f) - pass - fs.pushField(fmts) - pass - # - mm=MEDFileUMesh() ; mm[0]=m - fs.write(fileName,2) - mm.write(fileName,0) - ############ - def appendInDict(d,key,val): - if key in d: - d[key].append(val) - else: - d[key]=[val] - pass - import re - allFields=MEDLoader.GetAllFieldNames(fileName) - allFieldsDict={} - pat=re.compile("([\d]+)([\s\S]+)$") - for st in allFields: - stRev=st[::-1] - m=pat.match(stRev) - if m: - appendInDict(allFieldsDict,m.group(2)[::-1],m.group(1)[::-1]) - pass - else: - appendInDict(allFieldsDict,st,'') - pass - pass - fs2=MEDFileFields() - for k in allFieldsDict: - if allFieldsDict[k]!=['']: - allFieldsDict[k]=sorted(allFieldsDict[k],key=lambda x: int(x)) - pass - fmts2=[] - for it in allFieldsDict[k]: - fmts2.append(MEDFileFieldMultiTS.LoadSpecificEntities(fileName,k+it,[(ON_NODES,NORM_ERROR)])) - pass - fmts2.reverse() - zeResu=fmts2.pop() - nbIter=len(fmts2) - for ii in xrange(nbIter): - zeResu.pushBackTimeSteps(fmts2.pop()) - pass - zeResu.setName(k) - fs2.pushField(zeResu) - pass - self.assertEqual(fs2[0].getTimeSteps(),[(i,0,float(i)) for i in xrange(nbPdt)]) - pass - - def testMEDFileMeshRearrangeFamIds1(self): - """ Test for bug EDF10720. The aim of this test is the call of MEDFileMesh.rearrangeFamilies.""" - fileName="Pyfile89.med" - meshName='Maillage_2' - mm=MEDFileUMesh() - coords=DataArrayDouble([(0.,0.,0.),(0.,0.,200.),(0.,200.,200.),(0.,200.,0.),(200.,0.,0.),(200.,0.,200.),(200.,200.,200.),(200.,200.,0.),(0.,0.,100.),(0.,100.,200.),(0.,200.,100.),(0.,100.,0.),(200.,0.,100.),(200.,100.,200.),(200.,200.,100.),(200.,100.,0.),(100.,0.,0.),(100.,0.,200.),(100.,200.,0.),(100.,200.,200.),(0.,116.87743909766768,83.12256090233232),(200.,116.87743909766768,83.12256090233232),(116.87743909766769,0.,116.87743909766769),(116.87743909766769,200.,116.87743909766769),(116.87743909766769,116.87743909766769,0.),(116.87743909766769,116.87743909766769,200.),(63.3851584383713,56.1391811199829,119.728314479261),(138.008709441123,116.039297556044,119.903790959468)]) - # - c0=DataArrayInt([14,1,26,9,8,14,17,26,1,8,14,27,26,17,22,14,26,16,20,8,14,8,0,16,11,14,16,20,11,24,14,25,20,26,27,14,22,26,24,27,14,26,16,22,24,14,8,26,22,17,14,20,9,25,26,14,19,20,25,23,14,23,6,27,25,14,19,23,10,20,14,27,22,21,24,14,27,21,14,18,14,26,9,25,17,14,13,27,25,17,14,27,18,24,21,14,22,21,15,12,14,27,20,24,18,14,23,25,27,20,14,13,27,6,25,14,23,27,6,14,14,15,16,22,12,14,27,17,13,22,14,22,27,21,13,14,24,16,22,15,14,24,18,7,21,14,12,4,15,16,14,22,12,5,13,14,8,26,16,22,14,13,27,21,14,14,20,18,10,3,14,14,27,18,23,14,14,27,6,13,14,21,22,13,12,14,25,26,17,27,14,19,9,25,20,14,26,24,20,16,14,22,24,15,21,14,9,26,1,17,14,23,27,18,20,14,20,11,18,3,14,14,18,21,7,14,19,2,9,10,14,19,23,25,6,14,18,23,20,10,14,20,26,8,9,14,22,13,5,17,14,24,11,18,20,14,21,15,7,24,14,19,20,10,9,14,20,26,27,24,14,16,8,11,20]) - c0i=DataArrayInt([0,5,10,15,20,25,30,35,40,45,50,55,60,65,70,75,80,85,90,95,100,105,110,115,120,125,130,135,140,145,150,155,160,165,170,175,180,185,190,195,200,205,210,215,220,225,230,235,240,245,250,255,260,265,270,275]) - m0=MEDCouplingUMesh(meshName,3) ; m0.setCoords(coords) - m0.setConnectivity(c0,c0i) - mm[0]=m0 - # - c1=DataArrayInt([3,8,20,11,3,8,9,20,3,9,2,10,3,20,9,10,3,0,8,11,3,9,8,1,3,20,10,3,3,11,20,3,3,15,21,12,3,5,12,13,3,21,13,12,3,15,12,4,3,14,6,13,3,14,13,21,3,7,14,21,3,7,21,15,3,5,22,12,3,4,12,16,3,17,1,8,3,16,8,0,3,5,17,22,3,12,22,16,3,22,17,8,3,16,22,8,3,10,2,19,3,7,18,14,3,14,23,6,3,3,10,18,3,23,19,6,3,18,23,14,3,10,19,23,3,10,23,18,3,3,18,11,3,7,24,18,3,15,4,16,3,11,16,0,3,7,15,24,3,18,24,11,3,24,15,16,3,11,24,16,3,9,19,2,3,19,25,6,3,17,5,13,3,1,17,9,3,25,13,6,3,9,25,19,3,17,13,25,3,17,25,9]) - c1i=DataArrayInt([0,4,8,12,16,20,24,28,32,36,40,44,48,52,56,60,64,68,72,76,80,84,88,92,96,100,104,108,112,116,120,124,128,132,136,140,144,148,152,156,160,164,168,172,176,180,184,188,192]) - m1=MEDCouplingUMesh(meshName,2) ; m1.setCoords(coords) - m1.setConnectivity(c1,c1i) - mm[-1]=m1 - # - c2=DataArrayInt([0,8,8,1,1,9,9,2,3,10,10,2,0,11,11,3,4,12,12,5,5,13,13,6,7,14,14,6,4,15,15,7,0,16,16,4,1,17,17,5,3,18,18,7,2,19,19,6]) - m2=MEDCoupling1SGTUMesh(meshName,NORM_SEG2) - m2.setNodalConnectivity(c2) ; m2.setCoords(coords) - mm[-2]=m2.buildUnstructured() - # - ref0=DataArrayInt(55) ; ref0[:]=0 - mm.setFamilyFieldArr(0,ref0) - mm.setFamilyFieldArr(1,DataArrayInt([0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0])) - ref1=DataArrayInt([0,0,0,0,0,0,0,0,-6,-6,-6,-6,-6,-6,-6,-6,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]) - mm.setFamilyFieldArr(-1,ref1) - ref2=DataArrayInt([0,0,-7,-7,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]) - mm.setFamilyFieldArr(-2,ref2) - # - for f,fid in (('FAMILLE_ZERO',0),('FAM_-6_Groupe_1',-6),('FAM_-7_Groupe_2',-7),('FAM_2_Groupe_3',2)): - mm.setFamilyId(f,fid) - for grp,fams in [('Groupe_1',('FAM_-6_Groupe_1',)),('Groupe_2',('FAM_-7_Groupe_2',)),('Groupe_3',('FAM_2_Groupe_3',))]: - mm.setFamiliesOnGroup(grp,fams) - mm.write(fileName,2) - # - mm=MEDFileMesh.New(fileName) - grp=mm.getGroup(-1,"Groupe_1") - dai=grp.computeFetchedNodeIds() - dai.setName("TOTO") - mm.addGroup(1,dai) - mm.rearrangeFamilies() # <- the aim of the test - self.assertTrue(dai.isEqual(mm.getGroupArr(1,"TOTO"))) - self.assertTrue(mm.getFamilyFieldAtLevel(0).isEqual(ref0)) - self.assertTrue(mm.getFamilyFieldAtLevel(-1).isEqual(ref1)) - self.assertTrue(mm.getFamilyFieldAtLevel(-2).isEqual(ref2)) - self.assertTrue(mm.getFamilyFieldAtLevel(1).isEqual(DataArrayInt([0,0,2,0,9,9,9,9,0,0,0,0,9,9,9,9,0,0,0,0,0,9,0,0,0,0,0,0]))) - allGrps=[('Groupe_1',('FAM_-6_Groupe_1',)),('Groupe_2',('FAM_-7_Groupe_2',)),('Groupe_3',('FAM_2_Groupe_3',)),('TOTO',('Family_9',))] - allFams=[('FAMILLE_ZERO',0),('FAM_-6_Groupe_1',-6),('FAM_-7_Groupe_2',-7),('FAM_2_Groupe_3',2),('Family_9',9)] - self.assertEqual(list(mm.getGroupsNames()),[elt[0] for elt in allGrps]) - for elt,fams in allGrps: - self.assertEqual(mm.getFamiliesOnGroup(elt),fams) - self.assertEqual(list(mm.getFamiliesNames()),[elt[0] for elt in allFams]) - for elt,eltId in allFams: - self.assertEqual(mm.getFamilyId(elt),eltId) - pass - - def testNonRegrCMeshSetFieldPfl1(self): - """ Non regression test. For structured mesh, push a false partial field in MEDFileField1TS using setFieldProfile.""" - ff=MEDFileField1TS() - meshName="mesh" - mm=MEDFileCMesh() - m=MEDCouplingCMesh() ; arr=DataArrayDouble(5) ; arr.iota() - m.setCoords(arr) - m.setName(meshName) - mm.setMesh(m) - field=MEDCouplingFieldDouble(ON_CELLS) - field.setMesh(m) - field.setArray(DataArrayDouble([1.2,2.3,3.4,4.5])) - field.setName("Field") - field.checkCoherency() - pfl=DataArrayInt([0,1,2,3]) ; pfl.setName("TUTU") #<- false profile because defined on all cells ! - ff.setFieldProfile(field,mm,0,pfl) # <- bug was revealed here ! - self.assertEqual(ff.getPfls(),()) - field2=ff.getFieldOnMeshAtLevel(ON_CELLS,0,mm) - self.assertTrue(field.isEqual(field2,1e-12,1e-12)) - del ff,mm,field,field2,pfl - # same with unstructured mesh - ff=MEDFileField1TS() - meshName="mesh" - mm=MEDFileUMesh() - m=MEDCouplingCMesh() ; arr=DataArrayDouble(5) ; arr.iota() - m.setCoords(arr) - m.setName(meshName) - m=m.buildUnstructured() - mm[0]=m - field=MEDCouplingFieldDouble(ON_CELLS) - field.setMesh(m) - field.setArray(DataArrayDouble([1.2,2.3,3.4,4.5])) - field.setName("Field") - field.checkCoherency() - pfl=DataArrayInt([0,1,2,3]) ; pfl.setName("TUTU") - ff.setFieldProfile(field,mm,0,pfl) - self.assertEqual(ff.getPfls(),()) - field2=ff.getFieldOnMeshAtLevel(ON_CELLS,0,mm) - self.assertTrue(field.isEqual(field2,1e-12,1e-12)) - pass - - def testMEDFileUMeshLinearToQuadraticAndRev1(self): - meshName="mesh" - fileName="Pyfile90.med" - fileName2="Pyfile91.med" - arr=DataArrayDouble(5) ; arr.iota() - m=MEDCouplingCMesh() ; m.setCoords(arr,arr) - m=m.buildUnstructured() - d=DataArrayInt([3,7,11,15]) - m1=m[d] - m1.simplexize(0) - m2=m[d.buildComplement(m.getNumberOfCells())] - m=MEDCouplingUMesh.MergeUMeshesOnSameCoords(m1,m2) - m.changeSpaceDimension(3,0.) - arr=DataArrayDouble(3) ; arr.iota() - m1D=MEDCouplingCMesh() ; m1D.setCoords(arr) ; m1D=m1D.buildUnstructured() ; m1D.changeSpaceDimension(3,0.) - m1D.setCoords(m1D.getCoords()[:,[1,2,0]]) - delta=m.getNumberOfNodes()*(m1D.getNumberOfNodes()-1) - m3D=m.buildExtrudedMesh(m1D,0) - m3D.sortCellsInMEDFileFrmt() - m3D.setName(meshName) - m2D=m ; m2D.setCoords(m3D.getCoords()) ; m2D.shiftNodeNumbersInConn(delta) ; m2D.setName(meshName) ; m2D.checkCoherency2() - m1D=m2D.computeSkin() ; m1D.setName(meshName) - m0D=MEDCouplingUMesh.Build0DMeshFromCoords(m3D.getCoords()) ; m0D.setName(meshName) ; m0D=m0D[[2,4,10]] - # - mm=MEDFileUMesh() - mm[0]=m3D ; mm[-1]=m2D ; mm[-2]=m1D ; mm[-3]=m0D - grpEdge0=DataArrayInt([1,2,3,5]) ; grpEdge0.setName("East") - grpEdge1=DataArrayInt([0,1]) ; grpEdge1.setName("Corner1") - grpFaceSouth=DataArrayInt([0,1,8,9,10]) ; grpFaceSouth.setName("SouthFace") - grpFaceNorth=DataArrayInt([6,7,17,18,19]) ; grpFaceNorth.setName("NorthFace") - diagFace=DataArrayInt([0,1,13,15,17]) ; diagFace.setName("DiagFace") - vol1=DataArrayInt([20,21,23,24]) ; vol1.setName("vol1") - vol2=DataArrayInt([2,3,4,5,21,24]) ; vol2.setName("vol2") - mm.setGroupsAtLevel(0,[vol1,vol2]) - mm.setGroupsAtLevel(-1,[grpFaceSouth,grpFaceNorth,diagFace]) - mm.setGroupsAtLevel(-2,[grpEdge0,grpEdge1]) - # - mmOut1=mm.linearToQuadratic(0,0.) - mmOut1.write(fileName2,2) - mmOut2=mmOut1.quadraticToLinear(0.) - self.assertTrue(mm.isEqual(mmOut2,1e-12)[0]) - pass - - def testMEDFileMeshAddGroup1(self): - m=MEDCouplingCMesh() - arrX=DataArrayDouble(9) ; arrX.iota() - arrY=DataArrayDouble(4) ; arrY.iota() - m.setCoords(arrX,arrY) - m.setName("mesh") - mm=MEDFileCMesh() - mm.setMesh(m) - grp0=DataArrayInt([3,5,6,21,22]) ; grp0.setName("grp0") - mm.addGroup(0,grp0) - grp1=DataArrayInt([3,4,5,8,18,19,22]) ; grp1.setName("grp1") - mm.addGroup(0,grp1) - grp2=DataArrayInt([0,1,2,10,11]) ; grp2.setName("grp2") - mm.addGroup(0,grp2) - grp3=DataArrayInt([23]) ; grp3.setName("grp3") - mm.addGroup(0,grp3) - for grp in [grp0,grp1,grp2,grp3]: - self.assertTrue(mm.getGroupArr(0,grp.getName()).isEqual(grp)) - self.assertEqual(mm.getGroupsNames(),('grp0','grp1','grp2','grp3')) - delta=12 - for grp in [grp0,grp1,grp2,grp3]: - grpNode=grp.deepCpy() ; grpNode+=delta ; grpNode.setName("%s_node"%grp.getName()) - mm.addGroup(1,grpNode) - self.assertEqual(mm.getGroupsNames(),('grp0','grp0_node','grp1','grp1_node','grp2','grp2_node','grp3','grp3_node')) - for grp in [grp0,grp1,grp2,grp3]: - self.assertTrue(mm.getGroupArr(0,grp.getName()).isEqual(grp)) - for grp in [grp0,grp1,grp2,grp3]: - grpExp=grp+delta ; grpExp.setName("%s_node"%grp.getName()) - self.assertTrue(mm.getGroupArr(1,"%s_node"%grp.getName()).isEqual(grpExp)) - mm.normalizeFamIdsMEDFile() - for grp in [grp0,grp1,grp2,grp3]: - self.assertTrue(mm.getGroupArr(0,grp.getName()).isEqual(grp)) - for grp in [grp0,grp1,grp2,grp3]: - grpExp=grp+delta ; grpExp.setName("%s_node"%grp.getName()) - self.assertTrue(mm.getGroupArr(1,"%s_node"%grp.getName()).isEqual(grpExp)) - pass - - pass - def testMEDFileJoint1(self): - fileName="Pyfile92.med" - coo=DataArrayDouble([(0,0,0),(1,0,0),(2,0,0)]) - coo.setInfoOnComponents(["x [cm]","y [cm]","z [cm]"]) - mm=MEDFileUMesh() - mm.setCoords(coo) - mm.setName("maa1") - mm.setDescription("un maillage") - mm.write(fileName,2) - node_correspond=MEDFileJointCorrespondence(DataArrayInt([1,2,3,4,5,6,7,8])) - cell_correspond=MEDFileJointCorrespondence(DataArrayInt([9,10,11,12]),NORM_TRI3,NORM_TRI3) - one_step_joint=MEDFileJointOneStep() - one_step_joint.pushCorrespondence(cell_correspond) - one_step_joint.pushCorrespondence(node_correspond) - one_joint=MEDFileJoint() - one_joint.pushStep(one_step_joint) - one_joint.setLocalMeshName("maa1") - one_joint.setRemoteMeshName("maa1") - one_joint.setDescription("joint_description") - one_joint.setJointName("joint_1") - one_joint.setDomainNumber(1) - self.assertEqual( one_joint.getLocalMeshName(), "maa1") - self.assertEqual( one_joint.getRemoteMeshName(), "maa1") - self.assertEqual( one_joint.getDescription(), "joint_description") - self.assertEqual( one_joint.getJointName(), "joint_1") - self.assertEqual( one_joint.getDomainNumber(), 1) - joints=MEDFileJoints() - joints.pushJoint(one_joint); - joints.write(fileName,0) - # read back - jointsR=MEDFileJoints(fileName,mm.getName()) - self.assertEqual( jointsR.getNumberOfJoints(), 1 ) - jR = jointsR.getJointAtPos(0) - self.assertTrue( jR.isEqual( one_joint )) - self.assertRaises( InterpKernelException, jointsR.getJointAtPos,1) - self.assertRaises( InterpKernelException, jointsR.destroyJointAtPos,1) - jointsR.destroyJointAtPos(0) - - pass - def testMEDFileJoint2(self): - fileNameWr="Pyfile93.med" - coo=DataArrayDouble([(0,0,0),(1,0,0),(2,0,0)]) - coo.setInfoOnComponents(["x [cm]","y [cm]","z [cm]"]) - mm=MEDFileUMesh() - mm.setCoords(coo) - mm.setName("maa1") - mm.setDescription("un maillage") - node_correspond=MEDFileJointCorrespondence(DataArrayInt([13,14,15,16])) - cell_correspond=MEDFileJointCorrespondence(DataArrayInt([17,18]),NORM_TETRA4,NORM_PENTA6) - one_step_joint=MEDFileJointOneStep() - two_step_joint=MEDFileJointOneStep() - one_joint=MEDFileJoint() - two_joint=MEDFileJoint() - one_step_joint.pushCorrespondence(node_correspond) - one_joint.pushStep(one_step_joint) - two_step_joint.pushCorrespondence(cell_correspond) - two_step_joint.pushCorrespondence(node_correspond) - two_joint.pushStep(two_step_joint) - one_joint.setLocalMeshName("maa1") - one_joint.setRemoteMeshName("maa1") - one_joint.setDescription("joint_description_1") - one_joint.setJointName("joint_1") - one_joint.setDomainNumber(1) - two_joint.setLocalMeshName("maa1") - two_joint.setRemoteMeshName("maa1") - two_joint.setDescription("joint_description_2") - two_joint.setJointName("joint_2") - two_joint.setDomainNumber(2) - joints=MEDFileJoints() - joints.pushJoint(one_joint) - joints.pushJoint(two_joint) - mm.setJoints( joints ) - mm.write(fileNameWr,2) - # - mm=MEDFileMesh.New(fileNameWr) - self.assertEqual( mm.getNumberOfJoints(), 2) - jointsR = mm.getJoints(); - self.assertEqual( jointsR.getMeshName(), mm.getName() ) - self.assertEqual( len( jointsR ), 2 ) - jointR1 = jointsR[0] - jointR2 = jointsR[1] - self.assertFalse( jointR1 is None ) - self.assertFalse( jointR2 is None ) - self.assertTrue( jointR1.isEqual( one_joint )) - self.assertTrue( jointR2.isEqual( two_joint )) - pass - - def testMEDFileJoint1(self): - node_correspond=MEDFileJointCorrespondence(DataArrayInt([1,2,3,4,5,6,7,8])) - cell_correspond=MEDFileJointCorrespondence(DataArrayInt([9,10,11,12]),NORM_TRI3,NORM_TRI3) - cell_correspon2=MEDFileJointCorrespondence(DataArrayInt([9,10,11]),NORM_TRI3,NORM_TRI3) - cell_correspon3=MEDFileJointCorrespondence(DataArrayInt([9,10,11,12]),NORM_TRI3,NORM_QUAD4) - joint1st_1=MEDFileJointOneStep() - joint1st_1.pushCorrespondence(cell_correspond) - joint1st_1.pushCorrespondence(node_correspond) - joint1st_2=MEDFileJointOneStep() - joint1st_2.pushCorrespondence(cell_correspond) - joint1st_2.pushCorrespondence(node_correspond) - joint1st_3=MEDFileJointOneStep() - joint1st_3.pushCorrespondence(node_correspond) - joint1st_3.pushCorrespondence(cell_correspond) - joint1st_4=MEDFileJointOneStep() - joint1st_4.pushCorrespondence(cell_correspond) - joint1st_5=MEDFileJointOneStep() - joint1st_5.pushCorrespondence(cell_correspon2) - joint1st_6=MEDFileJointOneStep() - joint1st_6.pushCorrespondence(cell_correspon3) - self.assertTrue( joint1st_1.isEqual( joint1st_2 )) - self.assertTrue( joint1st_1.isEqual( joint1st_3 )) - self.assertFalse( joint1st_1.isEqual( joint1st_4 )) - self.assertFalse( joint1st_4.isEqual( joint1st_5 )) - self.assertFalse( joint1st_4.isEqual( joint1st_6 )) - one_joint=MEDFileJoint() - one_joint.pushStep(joint1st_1) - one_joint.setLocalMeshName("maa1") - one_joint.setRemoteMeshName("maa2") - one_joint.setDescription("joint_description") - one_joint.setJointName("joint_1") - one_joint.setDomainNumber(1) - self.assertEqual( "maa1", one_joint.getLocalMeshName()) - self.assertEqual( "maa2", one_joint.getRemoteMeshName()) - self.assertEqual( "joint_description", one_joint.getDescription()) - self.assertEqual( 1, one_joint.getDomainNumber()) - self.assertEqual( "joint_1", one_joint.getJointName()) - pass - - @unittest.skipUnless('linux'==platform.system().lower(),"stderr redirection not ported on Windows ?") - def testMEDFileSafeCall0(self): - """ EDF11242 : check status of MED file calls to detect problems immediately. Sorry this test generates awful messages !""" - fname="Pyfile94.med" - errfname="Pyfile94.err" - class StdOutRedirect(object): - def __init__(self,fileName): - import os,sys - sys.stderr.flush() - self.stdoutOld=os.dup(2) - self.fdOfSinkFile=os.open(fileName,os.O_CREAT | os.O_RDWR) - fd2=os.dup2(self.fdOfSinkFile,2) - self.origPyVal=sys.stderr - class FlushFile(object): - def __init__(self,f): - self.f=f - def write(self,st): - self.f.write(st) - self.f.flush() - def flush(self): - return self.f.flush() - def isatty(self): - return self.f.isatty() - sys.stderr=FlushFile(os.fdopen(self.fdOfSinkFile,"w")) - def __del__(self): - import os,sys - sys.stderr=self.origPyVal - #os.fsync(self.fdOfSinkFile) - os.fsync(2) - os.dup2(self.stdoutOld,2) - os.close(self.stdoutOld) - import os - # first clean file if needed - if os.path.exists(fname): - os.remove(fname) - pass - # second : build a file from scratch - m=MEDCouplingCMesh() - arr=DataArrayDouble(11) ; arr.iota() - m.setCoords(arr,arr) - mm=MEDFileCMesh() - mm.setMesh(m) - mm.setName("mesh") - mm.write(fname,2) - # third : change permissions to remove write access on created file - os.chmod(fname,0444) - # four : try to append data on file -> check that it raises Exception - f=MEDCouplingFieldDouble(ON_CELLS) - f.setName("field") - f.setMesh(m) - f.setArray(DataArrayDouble(100)) - f.getArray()[:]=100. - f.checkCoherency() - f1ts=MEDFileField1TS() - f1ts.setFieldNoProfileSBT(f) - # redirect stderr - tmp=StdOutRedirect(errfname) - self.assertRaises(InterpKernelException,f1ts.write,fname,0) # it should raise ! - del tmp - # - if os.path.exists(errfname): - os.remove(errfname) - # - pass - - def testUnivStatus1(self): - """ Non regression test to check the effectiveness of univ write status.""" - fname="Pyfile95.med" - arr=DataArrayDouble(10) ; arr.iota() - m=MEDCouplingCMesh() ; m.setCoords(arr,arr) ; m.setName("mesh") - mm=MEDFileCMesh() ; mm.setMesh(m) - mm.setUnivNameWrStatus(False) # test is here - mm.write(fname,2) - mm=MEDFileCMesh(fname) - self.assertEqual(mm.getUnivName(),"") - mm.setUnivNameWrStatus(True) - mm.write(fname,2) - mm=MEDFileCMesh(fname) - self.assertTrue(mm.getUnivName()!="") - pass - - def testEmptyMesh(self): - """ MEDLoader should be able to consistently write and read an empty mesh (coords array - with 0 tuples """ - fname = "Pyfile96.med" - m = MEDCouplingUMesh('toto', 2) - m.setCoords(DataArrayDouble([], 0, 2)) - m.setConnectivity(DataArrayInt([]), DataArrayInt([0])) - mfu = MEDFileUMesh() - mfu.setMeshAtLevel(0, m) - mfu.write(fname, 2) - mfu2 = MEDFileUMesh(fname) - self.assertEqual('toto', mfu2.getName()) - lvl = mfu2.getNonEmptyLevels() - self.assertEqual((), lvl) - - @unittest.skipUnless(MEDCouplingHasNumPyBindings(),"requires numpy") - def testMEDFileUMeshPickeling2(self): - """ Check that pickalization can be performed on a unpickalized instance. Non regression test.""" - name="Mesh_1" - grpName1="HAUT" - grpName2="BASE" - hauteur=1. - nbOfNodesPerAxis=3 - arr=DataArrayDouble(nbOfNodesPerAxis) ; arr.iota() ; arr/=(nbOfNodesPerAxis-1) ; arr*=hauteur - m=MEDCouplingCMesh() ; m.setCoords(arr,arr,arr) ; m=m.buildUnstructured() ; m.setName(name) - mesh=MEDFileUMesh() ; mesh[0]=m - m1=m.computeSkin() ; mesh[-1]=m1 - # - bary1=m1.getBarycenterAndOwner()[:,2] - grp1=bary1.getIdsInRange(hauteur-1e-12,hauteur+1e-12) ; grp1.setName(grpName1) - grp2=bary1.getIdsInRange(0.-1e-12,0.+1e-12) ; grp2.setName(grpName2) - mesh.setGroupsAtLevel(-1,[grp1,grp2]) - - import cPickle - st=cPickle.dumps(mesh,2) - mm=cPickle.loads(st) - st2=cPickle.dumps(mm,2) - mm2=cPickle.loads(st2) - self.assertTrue(mesh.isEqual(mm2,1e-12)[0]) - pass - - pass - -if __name__ == "__main__": - unittest.main() diff --git a/src/MEDLoader/Swig/MEDLoaderTest4.py b/src/MEDLoader/Swig/MEDLoaderTest4.py deleted file mode 100644 index 706b63b09..000000000 --- a/src/MEDLoader/Swig/MEDLoaderTest4.py +++ /dev/null @@ -1,5120 +0,0 @@ -# -*- coding: iso-8859-1 -*- -# Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 -# 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) - -from MEDLoader import * -import unittest -from math import pi,e,sqrt - -class MEDLoaderTest4(unittest.TestCase): - """ - Test series to emulate the future MEDReader plugin for PARAVIS. - """ - def test1(self): - """ - This test is the most simple one. One time serie of one field with only cell fields with no profiles. - The only "difficulty" is that the cell field is lying on different levels (2D and 1D) to maximize the compatibility with ParaVIS. - """ - fname="ForMEDReader1.med" - # building a mesh containing 4 tri3 + 5 quad4 - tri=MEDCouplingUMesh("tri",2) - tri.allocateCells() ; tri.insertNextCell(NORM_TRI3,[0,1,2]) - tri.setCoords(DataArrayDouble([(0.,0.),(0.,1.),(1.,0.)])) - tris=[tri.deepCpy() for i in xrange(4)] - for i,elt in enumerate(tris): elt.translate([i,0]) - tris=MEDCouplingUMesh.MergeUMeshes(tris) - quad=MEDCouplingUMesh("quad",2) - quad.allocateCells() ; quad.insertNextCell(NORM_QUAD4,[0,1,2,3]) - quad.setCoords(DataArrayDouble([(0.,0.),(0.,1.),(1.,1.),(1.,0.)])) - quads=[quad.deepCpy() for i in xrange(5)] - for i,elt in enumerate(quads): elt.translate([5+i,0]) - quads=MEDCouplingUMesh.MergeUMeshes(quads) - m=MEDCouplingUMesh.MergeUMeshes(tris,quads) - m.setName("mesh") ; m.getCoords().setInfoOnComponents(["XX [m]","YYY [km]"]) - m1=m.buildDescendingConnectivity()[0] - mm=MEDFileUMesh() ; mm.setMeshes([m,m1]) - fam=DataArrayInt(9) ; fam.iota(0) ; mm.setFamilyFieldArr(0,fam) - fam=DataArrayInt(32) ; fam.iota(20) ; mm.setFamilyFieldArr(-1,fam) ; del fam - num=DataArrayInt(9) ; num.iota(100) ; mm.setRenumFieldArr(0,num) - num=DataArrayInt(32) ; num.iota(120) ; mm.setRenumFieldArr(-1,num) ; del num - # - fieldName="zeField" - fs=MEDFileFieldMultiTS() - ##### Time step 0 - i=0 - f=MEDFileField1TS() - fCell0=MEDCouplingFieldDouble(ON_CELLS) ; fCell0.setTime(float(i),i,0) - fCell0.setName(fieldName) ; fCell0.setMesh(m) - arr=DataArrayDouble(2*m.getNumberOfCells()) ; arr.iota(100) ; arr.rearrange(2) - fCell0.setArray(arr) ; arr.setInfoOnComponents(["Comp1 [m]","Com2 [s^2]"]) - fCell0.checkCoherency() - f.setFieldNoProfileSBT(fCell0) - fCell1=MEDCouplingFieldDouble(ON_CELLS) ; fCell1.setTime(float(i),i,0) - fCell1.setName(fieldName) ; fCell1.setMesh(m1) - arr=DataArrayDouble(2*m1.getNumberOfCells()) ; arr.iota(200) ; arr.rearrange(2) - fCell1.setArray(arr) ; arr.setInfoOnComponents(["Comp1 [m]","Com2 [s^2]"]) - fCell1.checkCoherency() - f.setFieldNoProfileSBT(fCell1) - fs.pushBackTimeStep(f) - ##### Time step 1 - i=1 - f=MEDFileField1TS() - fCell0=MEDCouplingFieldDouble(ON_CELLS) ; fCell0.setTime(float(i),i,0) - fCell0.setName(fieldName) ; fCell0.setMesh(m) - arr=DataArrayDouble(2*m.getNumberOfCells()) ; arr.iota(1100) ; arr.rearrange(2) - fCell0.setArray(arr) ; arr.setInfoOnComponents(["Comp1 [m]","Com2 [s^2]"]) - fCell0.checkCoherency() - f.setFieldNoProfileSBT(fCell0) - # - fCell1=MEDCouplingFieldDouble(ON_CELLS) ; fCell1.setTime(float(i),i,0) - fCell1.setName(fieldName) ; fCell1.setMesh(m1) - arr=DataArrayDouble(2*m1.getNumberOfCells()) ; arr.iota(1200) ; arr.rearrange(2) - fCell1.setArray(arr) ; arr.setInfoOnComponents(["Comp1 [m]","Com2 [s^2]"]) - fCell1.checkCoherency() - f.setFieldNoProfileSBT(fCell1) - fs.pushBackTimeStep(f) - ##### Time step 2 - i=2 - f=MEDFileField1TS() - fCell0=MEDCouplingFieldDouble(ON_CELLS) ; fCell0.setTime(float(i),i,0) - fCell0.setName(fieldName) ; fCell0.setMesh(m) - arr=DataArrayDouble(2*m.getNumberOfCells()) ; arr.iota(2100) ; arr.rearrange(2) - fCell0.setArray(arr) ; arr.setInfoOnComponents(["Comp1 [m]","Com2 [s^2]"]) - fCell0.checkCoherency() - f.setFieldNoProfileSBT(fCell0) - # - fCell1=MEDCouplingFieldDouble(ON_CELLS) ; fCell1.setTime(float(i),i,0) - fCell1.setName(fieldName) ; fCell1.setMesh(m1) - arr=DataArrayDouble(2*m1.getNumberOfCells()) ; arr.iota(2200) ; arr.rearrange(2) - fCell1.setArray(arr) ; arr.setInfoOnComponents(["Comp1 [m]","Com2 [s^2]"]) - fCell1.checkCoherency() - f.setFieldNoProfileSBT(fCell1) - fs.pushBackTimeStep(f) - ##### Time step 3 - i=3 - f=MEDFileField1TS() - # - fCell0=MEDCouplingFieldDouble(ON_CELLS) ; fCell0.setTime(float(i),i,0) - fCell0.setName(fieldName) ; fCell0.setMesh(m) - arr=DataArrayDouble(2*m.getNumberOfCells()) ; arr.iota(3100) ; arr.rearrange(2) - fCell0.setArray(arr) ; arr.setInfoOnComponents(["Comp1 [m]","Com2 [s^2]"]) - fCell0.checkCoherency() - f.setFieldNoProfileSBT(fCell0) - # - fCell1=MEDCouplingFieldDouble(ON_CELLS) ; fCell1.setTime(float(i),i,0) - fCell1.setName(fieldName) ; fCell1.setMesh(m1) - arr=DataArrayDouble(2*m1.getNumberOfCells()) ; arr.iota(3200) ; arr.rearrange(2) - fCell1.setArray(arr) ; arr.setInfoOnComponents(["Comp1 [m]","Com2 [s^2]"]) - fCell1.checkCoherency() - f.setFieldNoProfileSBT(fCell1) - # - fs.pushBackTimeStep(f) - ##### Time step 4 - i=4 - f=MEDFileField1TS() - # - fCell0=MEDCouplingFieldDouble(ON_CELLS) ; fCell0.setTime(float(i),i,0) - fCell0.setName(fieldName) ; fCell0.setMesh(m) - arr=DataArrayDouble(2*m.getNumberOfCells()) ; arr.iota(4100) ; arr.rearrange(2) - fCell0.setArray(arr) ; arr.setInfoOnComponents(["Comp1 [m]","Com2 [s^2]"]) - fCell0.checkCoherency() - f.setFieldNoProfileSBT(fCell0) - # - fCell1=MEDCouplingFieldDouble(ON_CELLS) ; fCell1.setTime(float(i),i,0) - fCell1.setName(fieldName) ; fCell1.setMesh(m1) - arr=DataArrayDouble(2*m1.getNumberOfCells()) ; arr.iota(4200) ; arr.rearrange(2) - fCell1.setArray(arr) ; arr.setInfoOnComponents(["Comp1 [m]","Com2 [s^2]"]) - fCell1.checkCoherency() - f.setFieldNoProfileSBT(fCell1) - fs.pushBackTimeStep(f) - mm.write(fname,2) - fs.write(fname,0) - a0Exp=mm.getCoords().deepCpy() - del m,m1,mm,fs,f,fCell0,fCell1 - ########## GO for reading in MEDReader, by not loading all. Mesh is fully loaded but not fields values - ms=MEDFileMeshes(fname) - fields=MEDFileFields(fname,False) # False is important to not read the values - fields.removeFieldsWithoutAnyTimeStep() - refMem=fields.getHeapMemorySize() - fields_per_mesh=[fields.partOfThisLyingOnSpecifiedMeshName(meshName) for meshName in ms.getMeshesNames()] - allFMTSLeavesToDisplay=[] - for fields in fields_per_mesh: - allFMTSLeavesToDisplay2=[] - for fmts in fields: - tmp=fmts.splitDiscretizations() - for itmp in tmp: - self.assertTrue(not itmp.presenceOfMultiDiscPerGeoType()) - pass - allFMTSLeavesToDisplay2+=tmp - pass - allFMTSLeavesToDisplay.append(allFMTSLeavesToDisplay2) - pass - self.assertEqual(len(allFMTSLeavesToDisplay),1) - self.assertEqual(len(allFMTSLeavesToDisplay[0]),1) - for fmts in allFMTSLeavesToDisplay[0]: - self.assertEqual(fmts.getTimeSteps(),[(0,0,0.),(1,0,1.),(2,0,2.),(3,0,3.),(4,0,4.)]) # All discretizations have the same time series - pass - allFMTSLeavesPerTimeSeries=MEDFileAnyTypeFieldMultiTS.SplitIntoCommonTimeSeries(sum(allFMTSLeavesToDisplay,[])) - self.assertEqual(len(allFMTSLeavesPerTimeSeries),1) - self.assertEqual(len(allFMTSLeavesPerTimeSeries[0]),1) - allFMTSLeavesPerCommonSupport=MEDFileAnyTypeFieldMultiTS.SplitPerCommonSupport(allFMTSLeavesPerTimeSeries[0],ms[ms.getMeshesNames()[0]]) - # - mst=MEDFileMeshStruct.New(ms[0]) - fcscp=allFMTSLeavesPerCommonSupport[0][1] - mml=fcscp.buildFromScratchDataSetSupport(0,fields) - mml2=mml.prepare() - self.assertTrue(isinstance(mml2,MEDUMeshMultiLev)) - for i in xrange(1,5): - self.assertTrue(fcscp.isDataSetSupportEqualToThePreviousOne(i,fields)) - pass - ncc,a0,a1,a2,a3,a4,a5=mml2.buildVTUArrays() - self.assertTrue(not ncc) - self.assertTrue(a0.isEqual(a0Exp.changeNbOfComponents(3,0.),1e-12)) - self.assertTrue(a1.isEqual(DataArrayByte([3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,5,5,5,5,9,9,9,9,9]))) - self.assertTrue(a2.isEqual(DataArrayInt([0,3,6,9,12,15,18,21,24,27,30,33,36,39,42,45,48,51,54,57,60,63,66,69,72,75,78,81,84,87,90,93,96,100,104,108,112,117,122,127,132]))) - self.assertTrue(a3.isEqual(DataArrayInt([2,0,1,2,1,2,2,2,0,2,3,4,2,4,5,2,5,3,2,6,7,2,7,8,2,8,6,2,9,10,2,10,11,2,11,9,2,12,13,2,13,14,2,14,15,2,15,12,2,16,17,2,17,18,2,18,19,2,19,16,2,20,21,2,21,22,2,22,23,2,23,20,2,24,25,2,25,26,2,26,27,2,27,24,2,28,29,2,29,30,2,30,31,2,31,28,3,0,1,2,3,3,4,5,3,6,7,8,3,9,10,11,4,12,13,14,15,4,16,17,18,19,4,20,21,22,23,4,24,25,26,27,4,28,29,30,31]))) - self.assertTrue(a4 is None) - self.assertTrue(a5 is None) - a6,a7=mml2.retrieveFamilyIdsOnCells() - self.assertTrue(a6.isEqual(DataArrayInt([20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,0,1,2,3,4,5,6,7,8]))) - self.assertTrue(not a7) - a8,a9=mml2.retrieveNumberIdsOnCells() - self.assertTrue(a8.isEqual(DataArrayInt([120,121,122,123,124,125,126,127,128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143,144,145,146,147,148,149,150,151,100,101,102,103,104,105,106,107,108]))) - self.assertTrue(not a9) - for i in xrange(5): - fsst=MEDFileField1TSStructItem.BuildItemFrom(fields[0][i],mst) - fields[0][i].loadArraysIfNecessary() - tmpMem=fields.getHeapMemorySize() - self.assertTrue(tmpMem-refMem>=41*2*8) - refMem=tmpMem - v=mml.buildDataArray(fsst,fields,fields[0][i].getUndergroundDataArray()) - self.assertEqual(v.getHiddenCppPointer(),fields[0][i].getUndergroundDataArray().getHiddenCppPointer()) - vExp=DataArrayDouble([200.,201.,202.,203.,204.,205.,206.,207.,208.,209.,210.,211.,212.,213.,214.,215.,216.,217.,218.,219.,220.,221.,222.,223.,224.,225.,226.,227.,228.,229.,230.,231.,232.,233.,234.,235.,236.,237.,238.,239.,240.,241.,242.,243.,244.,245.,246.,247.,248.,249.,250.,251.,252.,253.,254.,255.,256.,257.,258.,259.,260.,261.,262.,263.,100.,101.,102.,103.,104.,105.,106.,107.,108.,109.,110.,111.,112.,113.,114.,115.,116.,117.],41,2) ; vExp.setInfoOnComponents(['Comp1 [m]','Com2 [s^2]']) ; vExp+=i*1000 - self.assertTrue(v.isEqual(vExp,1e-12)) - pass - pass - - def test2(self): - """ - One time serie of one field with cell and node discretization in the same field with no profiles. - Here as there is no profile only one VTK support is requested. - """ - fname="ForMEDReader2.med" - # building a mesh containing 4 tri3 + 5 quad4 - tri=MEDCouplingUMesh("tri",2) - tri.allocateCells() ; tri.insertNextCell(NORM_TRI3,[0,1,2]) - tri.setCoords(DataArrayDouble([(0.,0.),(0.,1.),(1.,0.)])) - tris=[tri.deepCpy() for i in xrange(4)] - for i,elt in enumerate(tris): elt.translate([i,0]) - tris=MEDCouplingUMesh.MergeUMeshes(tris) - quad=MEDCouplingUMesh("quad",2) - quad.allocateCells() ; quad.insertNextCell(NORM_QUAD4,[0,1,2,3]) - quad.setCoords(DataArrayDouble([(0.,0.),(0.,1.),(1.,1.),(1.,0.)])) - quads=[quad.deepCpy() for i in xrange(5)] - for i,elt in enumerate(quads): elt.translate([5+i,0]) - quads=MEDCouplingUMesh.MergeUMeshes(quads) - m=MEDCouplingUMesh.MergeUMeshes(tris,quads) - m.setName("mesh") ; m.getCoords().setInfoOnComponents(["XX [m]","YYY [km]"]) - m1=m.buildDescendingConnectivity()[0] - mm=MEDFileUMesh() ; mm.setMeshes([m,m1]) - # - fieldName="zeField" - fs=MEDFileFieldMultiTS() - ##### Time step 0 - i=0 - f=MEDFileField1TS() - fCell0=MEDCouplingFieldDouble(ON_CELLS) ; fCell0.setTime(float(i),i,0) - fCell0.setName(fieldName) ; fCell0.setMesh(m) - arr=DataArrayDouble(2*m.getNumberOfCells()) ; arr.iota(100) ; arr.rearrange(2) - fCell0.setArray(arr) ; arr.setInfoOnComponents(["Comp1 [m]","Com2 [s^2]"]) - fCell0.checkCoherency() - f.setFieldNoProfileSBT(fCell0) - fCell1=MEDCouplingFieldDouble(ON_CELLS) ; fCell1.setTime(float(i),i,0) - fCell1.setName(fieldName) ; fCell1.setMesh(m1) - arr=DataArrayDouble(2*m1.getNumberOfCells()) ; arr.iota(200) ; arr.rearrange(2) - fCell1.setArray(arr) ; arr.setInfoOnComponents(["Comp1 [m]","Com2 [s^2]"]) - fCell1.checkCoherency() - f.setFieldNoProfileSBT(fCell1) - # - fNode=MEDCouplingFieldDouble(ON_NODES) ; fNode.setTime(float(i),i,0) - fNode.setName(fieldName) ; fNode.setMesh(m1) - arr=DataArrayDouble(2*m.getNumberOfNodes()) ; arr.iota(300) ; arr.rearrange(2) - fNode.setArray(arr) ; arr.setInfoOnComponents(["Comp1 [m]","Com2 [s^2]"]) - fNode.checkCoherency() - f.setFieldNoProfileSBT(fNode) - fs.pushBackTimeStep(f) - ##### Time step 1 - i=1 - f=MEDFileField1TS() - fCell0=MEDCouplingFieldDouble(ON_CELLS) ; fCell0.setTime(float(i),i,0) - fCell0.setName(fieldName) ; fCell0.setMesh(m) - arr=DataArrayDouble(2*m.getNumberOfCells()) ; arr.iota(1100) ; arr.rearrange(2) - fCell0.setArray(arr) ; arr.setInfoOnComponents(["Comp1 [m]","Com2 [s^2]"]) - fCell0.checkCoherency() - f.setFieldNoProfileSBT(fCell0) - # - fCell1=MEDCouplingFieldDouble(ON_CELLS) ; fCell1.setTime(float(i),i,0) - fCell1.setName(fieldName) ; fCell1.setMesh(m1) - arr=DataArrayDouble(2*m1.getNumberOfCells()) ; arr.iota(1200) ; arr.rearrange(2) - fCell1.setArray(arr) ; arr.setInfoOnComponents(["Comp1 [m]","Com2 [s^2]"]) - fCell1.checkCoherency() - f.setFieldNoProfileSBT(fCell1) - # - fNode=MEDCouplingFieldDouble(ON_NODES) ; fNode.setTime(float(i),i,0) - fNode.setName(fieldName) ; fNode.setMesh(m1) - arr=DataArrayDouble(2*m.getNumberOfNodes()) ; arr.iota(1300) ; arr.rearrange(2) - fNode.setArray(arr) ; arr.setInfoOnComponents(["Comp1 [m]","Com2 [s^2]"]) - fNode.checkCoherency() - f.setFieldNoProfileSBT(fNode) - fs.pushBackTimeStep(f) - ##### Time step 2 - i=2 - f=MEDFileField1TS() - fNode=MEDCouplingFieldDouble(ON_NODES) ; fNode.setTime(float(i),i,0) - fNode.setName(fieldName) ; fNode.setMesh(m1) - arr=DataArrayDouble(2*m.getNumberOfNodes()) ; arr.iota(2300) ; arr.rearrange(2) - fNode.setArray(arr) ; arr.setInfoOnComponents(["Comp1 [m]","Com2 [s^2]"]) - fNode.checkCoherency() - f.setFieldNoProfileSBT(fNode) - # - fCell0=MEDCouplingFieldDouble(ON_CELLS) ; fCell0.setTime(float(i),i,0) - fCell0.setName(fieldName) ; fCell0.setMesh(m) - arr=DataArrayDouble(2*m.getNumberOfCells()) ; arr.iota(2100) ; arr.rearrange(2) - fCell0.setArray(arr) ; arr.setInfoOnComponents(["Comp1 [m]","Com2 [s^2]"]) - fCell0.checkCoherency() - f.setFieldNoProfileSBT(fCell0) - # - fCell1=MEDCouplingFieldDouble(ON_CELLS) ; fCell1.setTime(float(i),i,0) - fCell1.setName(fieldName) ; fCell1.setMesh(m1) - arr=DataArrayDouble(2*m1.getNumberOfCells()) ; arr.iota(2200) ; arr.rearrange(2) - fCell1.setArray(arr) ; arr.setInfoOnComponents(["Comp1 [m]","Com2 [s^2]"]) - fCell1.checkCoherency() - f.setFieldNoProfileSBT(fCell1) - fs.pushBackTimeStep(f) - ##### Time step 3 - i=3 - f=MEDFileField1TS() - # - fCell0=MEDCouplingFieldDouble(ON_CELLS) ; fCell0.setTime(float(i),i,0) - fCell0.setName(fieldName) ; fCell0.setMesh(m) - arr=DataArrayDouble(2*m.getNumberOfCells()) ; arr.iota(3100) ; arr.rearrange(2) - fCell0.setArray(arr) ; arr.setInfoOnComponents(["Comp1 [m]","Com2 [s^2]"]) - fCell0.checkCoherency() - f.setFieldNoProfileSBT(fCell0) - # - fCell1=MEDCouplingFieldDouble(ON_CELLS) ; fCell1.setTime(float(i),i,0) - fCell1.setName(fieldName) ; fCell1.setMesh(m1) - arr=DataArrayDouble(2*m1.getNumberOfCells()) ; arr.iota(3200) ; arr.rearrange(2) - fCell1.setArray(arr) ; arr.setInfoOnComponents(["Comp1 [m]","Com2 [s^2]"]) - fCell1.checkCoherency() - f.setFieldNoProfileSBT(fCell1) - # - fNode=MEDCouplingFieldDouble(ON_NODES) ; fNode.setTime(float(i),i,0) - fNode.setName(fieldName) ; fNode.setMesh(m1) - arr=DataArrayDouble(2*m.getNumberOfNodes()) ; arr.iota(3300) ; arr.rearrange(2) - fNode.setArray(arr) ; arr.setInfoOnComponents(["Comp1 [m]","Com2 [s^2]"]) - fNode.checkCoherency() - f.setFieldNoProfileSBT(fNode) - # - fs.pushBackTimeStep(f) - ##### Time step 4 - i=4 - f=MEDFileField1TS() - # - fCell0=MEDCouplingFieldDouble(ON_CELLS) ; fCell0.setTime(float(i),i,0) - fCell0.setName(fieldName) ; fCell0.setMesh(m) - arr=DataArrayDouble(2*m.getNumberOfCells()) ; arr.iota(4100) ; arr.rearrange(2) - fCell0.setArray(arr) ; arr.setInfoOnComponents(["Comp1 [m]","Com2 [s^2]"]) - fCell0.checkCoherency() - f.setFieldNoProfileSBT(fCell0) - # - fCell1=MEDCouplingFieldDouble(ON_CELLS) ; fCell1.setTime(float(i),i,0) - fCell1.setName(fieldName) ; fCell1.setMesh(m1) - arr=DataArrayDouble(2*m1.getNumberOfCells()) ; arr.iota(4200) ; arr.rearrange(2) - fCell1.setArray(arr) ; arr.setInfoOnComponents(["Comp1 [m]","Com2 [s^2]"]) - fCell1.checkCoherency() - f.setFieldNoProfileSBT(fCell1) - # - fNode=MEDCouplingFieldDouble(ON_NODES) ; fNode.setTime(float(i),i,0) - fNode.setName(fieldName) ; fNode.setMesh(m1) - arr=DataArrayDouble(2*m.getNumberOfNodes()) ; arr.iota(4300) ; arr.rearrange(2) - fNode.setArray(arr) ; arr.setInfoOnComponents(["Comp1 [m]","Com2 [s^2]"]) - fNode.checkCoherency() - f.setFieldNoProfileSBT(fNode) - # - fs.pushBackTimeStep(f) - mm.write(fname,2) - fs.write(fname,0) - a0Exp=mm.getCoords().deepCpy() - del m,m1,mm,fs,f,fCell0,fCell1 - ########## GO for reading in MEDReader, by not loading all. Mesh is fully loaded but not fields values - ms=MEDFileMeshes(fname) - fields=MEDFileFields(fname,False) - fields.removeFieldsWithoutAnyTimeStep() - fields_per_mesh=[fields.partOfThisLyingOnSpecifiedMeshName(meshName) for meshName in ms.getMeshesNames()] - allFMTSLeavesToDisplay=[] - for fields in fields_per_mesh: - allFMTSLeavesToDisplay2=[] - for fmts in fields: - tmp=fmts.splitDiscretizations() - for itmp in tmp: - self.assertTrue(not itmp.presenceOfMultiDiscPerGeoType()) - pass - allFMTSLeavesToDisplay2+=tmp - pass - allFMTSLeavesToDisplay.append(allFMTSLeavesToDisplay2) - pass - self.assertEqual(len(allFMTSLeavesToDisplay),1) - self.assertEqual(len(allFMTSLeavesToDisplay[0]),2) - for fmts in allFMTSLeavesToDisplay[0]: - self.assertEqual(fmts.getTimeSteps(),[(0,0,0.),(1,0,1.),(2,0,2.),(3,0,3.),(4,0,4.)]) # All discretizations have the same time series - pass - allFMTSLeavesPerTimeSeries=MEDFileAnyTypeFieldMultiTS.SplitIntoCommonTimeSeries(sum(allFMTSLeavesToDisplay,[])) - self.assertEqual(len(allFMTSLeavesPerTimeSeries),1) - self.assertEqual(len(allFMTSLeavesPerTimeSeries[0]),2) - allFMTSLeavesPerCommonSupport=MEDFileAnyTypeFieldMultiTS.SplitPerCommonSupport(allFMTSLeavesPerTimeSeries[0],ms[ms.getMeshesNames()[0]]) - self.assertEqual(len(allFMTSLeavesPerCommonSupport),1) - self.assertEqual(len(allFMTSLeavesPerCommonSupport[0][0]),2) - # - mst=MEDFileMeshStruct.New(ms[0]) - fcscp=allFMTSLeavesPerCommonSupport[0][1] - mml=fcscp.buildFromScratchDataSetSupport(0,fields) - mml2=mml.prepare() - assert isinstance(mml2,MEDUMeshMultiLev) - for i in xrange(1,5): - self.assertTrue(fcscp.isDataSetSupportEqualToThePreviousOne(i,fields)) - pass - ncc,a0,a1,a2,a3,a4,a5=mml2.buildVTUArrays() - self.assertTrue(not ncc) - self.assertTrue(a0.isEqual(a0Exp.changeNbOfComponents(3,0.),1e-12)) - self.assertTrue(a1.isEqual(DataArrayByte([3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,5,5,5,5,9,9,9,9,9]))) - self.assertTrue(a2.isEqual(DataArrayInt([0,3,6,9,12,15,18,21,24,27,30,33,36,39,42,45,48,51,54,57,60,63,66,69,72,75,78,81,84,87,90,93,96,100,104,108,112,117,122,127,132]))) - self.assertTrue(a3.isEqual(DataArrayInt([2,0,1,2,1,2,2,2,0,2,3,4,2,4,5,2,5,3,2,6,7,2,7,8,2,8,6,2,9,10,2,10,11,2,11,9,2,12,13,2,13,14,2,14,15,2,15,12,2,16,17,2,17,18,2,18,19,2,19,16,2,20,21,2,21,22,2,22,23,2,23,20,2,24,25,2,25,26,2,26,27,2,27,24,2,28,29,2,29,30,2,30,31,2,31,28,3,0,1,2,3,3,4,5,3,6,7,8,3,9,10,11,4,12,13,14,15,4,16,17,18,19,4,20,21,22,23,4,24,25,26,27,4,28,29,30,31]))) - self.assertTrue(a4 is None) - self.assertTrue(a5 is None) - # for cells - for i in xrange(5): - f=allFMTSLeavesPerCommonSupport[0][0][0][i] - fsst=MEDFileField1TSStructItem.BuildItemFrom(f,mst)# Second 0 is for cells - f.loadArraysIfNecessary() - v=mml.buildDataArray(fsst,fields,f.getUndergroundDataArray()) - self.assertEqual(v.getHiddenCppPointer(),f.getUndergroundDataArray().getHiddenCppPointer()) - vExp=DataArrayDouble([200.,201.,202.,203.,204.,205.,206.,207.,208.,209.,210.,211.,212.,213.,214.,215.,216.,217.,218.,219.,220.,221.,222.,223.,224.,225.,226.,227.,228.,229.,230.,231.,232.,233.,234.,235.,236.,237.,238.,239.,240.,241.,242.,243.,244.,245.,246.,247.,248.,249.,250.,251.,252.,253.,254.,255.,256.,257.,258.,259.,260.,261.,262.,263.,100.,101.,102.,103.,104.,105.,106.,107.,108.,109.,110.,111.,112.,113.,114.,115.,116.,117.],41,2) ; vExp.setInfoOnComponents(['Comp1 [m]','Com2 [s^2]']) ; vExp+=i*1000 - self.assertTrue(v.isEqual(vExp,1e-12)) - pass - for i in xrange(5): - f=allFMTSLeavesPerCommonSupport[0][0][1][i] - fsst=MEDFileField1TSStructItem.BuildItemFrom(f,mst)# Second 0 is for cells - f.loadArraysIfNecessary() - v=mml.buildDataArray(fsst,fields,f.getUndergroundDataArray()) - self.assertEqual(v.getHiddenCppPointer(),f.getUndergroundDataArray().getHiddenCppPointer()) - vExp=DataArrayDouble([300.,301.,302.,303.,304.,305.,306.,307.,308.,309.,310.,311.,312.,313.,314.,315.,316.,317.,318.,319.,320.,321.,322.,323.,324.,325.,326.,327.,328.,329.,330.,331.,332.,333.,334.,335.,336.,337.,338.,339.,340.,341.,342.,343.,344.,345.,346.,347.,348.,349.,350.,351.,352.,353.,354.,355.,356.,357.,358.,359.,360.,361.,362.,363.],32,2) ; vExp.setInfoOnComponents(['Comp1 [m]','Com2 [s^2]']) ; vExp.setInfoOnComponents(['Comp1 [m]','Com2 [s^2]']) ; vExp+=i*1000 - self.assertTrue(v.isEqual(vExp,1e-12)) - pass - pass - - def test3(self): - """ This test is more advanced a same field is defined on CELLS for time steps 0, 2 and 4, and on NODES for time steps 1 and 3. - So two time step series on the same field. No profile here neither on cells nor on nodes. - """ - fname="ForMEDReader3.med" - # building a mesh containing 4 tri3 + 5 quad4 - tri=MEDCouplingUMesh("tri",2) - tri.allocateCells() ; tri.insertNextCell(NORM_TRI3,[0,1,2]) - tri.setCoords(DataArrayDouble([(0.,0.),(0.,1.),(1.,0.)])) - tris=[tri.deepCpy() for i in xrange(4)] - for i,elt in enumerate(tris): elt.translate([i,0]) - tris=MEDCouplingUMesh.MergeUMeshes(tris) - quad=MEDCouplingUMesh("quad",2) - quad.allocateCells() ; quad.insertNextCell(NORM_QUAD4,[0,1,2,3]) - quad.setCoords(DataArrayDouble([(0.,0.),(0.,1.),(1.,1.),(1.,0.)])) - quads=[quad.deepCpy() for i in xrange(5)] - for i,elt in enumerate(quads): elt.translate([5+i,0]) - quads=MEDCouplingUMesh.MergeUMeshes(quads) - m=MEDCouplingUMesh.MergeUMeshes(tris,quads) - m.setName("mesh") ; m.getCoords().setInfoOnComponents(["XX [m]","YYY [km]"]) - m1=m.buildDescendingConnectivity()[0] - mm=MEDFileUMesh() ; mm.setMeshes([m,m1]) - # - fieldName="zeField" - fs=MEDFileFieldMultiTS() - ##### Time step 0 on cells - i=0 - f=MEDFileField1TS() - fCell0=MEDCouplingFieldDouble(ON_CELLS) ; fCell0.setTime(float(i),i,0) - fCell0.setName(fieldName) ; fCell0.setMesh(m) - arr=DataArrayDouble(2*m.getNumberOfCells()) ; arr.iota(100) ; arr.rearrange(2) - fCell0.setArray(arr) ; arr.setInfoOnComponents(["Comp1 [m]","Com2 [s^2]"]) - fCell0.checkCoherency() - f.setFieldNoProfileSBT(fCell0) - fCell1=MEDCouplingFieldDouble(ON_CELLS) ; fCell1.setTime(float(i),i,0) - fCell1.setName(fieldName) ; fCell1.setMesh(m1) - arr=DataArrayDouble(2*m1.getNumberOfCells()) ; arr.iota(200) ; arr.rearrange(2) - fCell1.setArray(arr) ; arr.setInfoOnComponents(["Comp1 [m]","Com2 [s^2]"]) - fCell1.checkCoherency() - f.setFieldNoProfileSBT(fCell1) - fs.pushBackTimeStep(f) - ##### Time step 1 on nodes - i=1 - f=MEDFileField1TS() - fNode=MEDCouplingFieldDouble(ON_NODES) ; fNode.setTime(float(i),i,0) - fNode.setName(fieldName) ; fNode.setMesh(m1) - arr=DataArrayDouble(2*m.getNumberOfNodes()) ; arr.iota(1300) ; arr.rearrange(2) - fNode.setArray(arr) ; arr.setInfoOnComponents(["Comp1 [m]","Com2 [s^2]"]) - fNode.checkCoherency() - f.setFieldNoProfileSBT(fNode) - fs.pushBackTimeStep(f) - ##### Time step 2 on cells - i=2 - f=MEDFileField1TS() - fCell0=MEDCouplingFieldDouble(ON_CELLS) ; fCell0.setTime(float(i),i,0) - fCell0.setName(fieldName) ; fCell0.setMesh(m) - arr=DataArrayDouble(2*m.getNumberOfCells()) ; arr.iota(2100) ; arr.rearrange(2) - fCell0.setArray(arr) ; arr.setInfoOnComponents(["Comp1 [m]","Com2 [s^2]"]) - fCell0.checkCoherency() - f.setFieldNoProfileSBT(fCell0) - # - fCell1=MEDCouplingFieldDouble(ON_CELLS) ; fCell1.setTime(float(i),i,0) - fCell1.setName(fieldName) ; fCell1.setMesh(m1) - arr=DataArrayDouble(2*m1.getNumberOfCells()) ; arr.iota(2200) ; arr.rearrange(2) - fCell1.setArray(arr) ; arr.setInfoOnComponents(["Comp1 [m]","Com2 [s^2]"]) - fCell1.checkCoherency() - f.setFieldNoProfileSBT(fCell1) - fs.pushBackTimeStep(f) - ##### Time step 3 on nodes - i=3 - f=MEDFileField1TS() - fNode=MEDCouplingFieldDouble(ON_NODES) ; fNode.setTime(float(i),i,0) - fNode.setName(fieldName) ; fNode.setMesh(m1) - arr=DataArrayDouble(2*m.getNumberOfNodes()) ; arr.iota(3300) ; arr.rearrange(2) - fNode.setArray(arr) ; arr.setInfoOnComponents(["Comp1 [m]","Com2 [s^2]"]) - fNode.checkCoherency() - f.setFieldNoProfileSBT(fNode) - fs.pushBackTimeStep(f) - ##### Time step 4 - i=4 - f=MEDFileField1TS() - fCell0=MEDCouplingFieldDouble(ON_CELLS) ; fCell0.setTime(float(i),i,0) - fCell0.setName(fieldName) ; fCell0.setMesh(m) - arr=DataArrayDouble(2*m.getNumberOfCells()) ; arr.iota(4100) ; arr.rearrange(2) - fCell0.setArray(arr) ; arr.setInfoOnComponents(["Comp1 [m]","Com2 [s^2]"]) - fCell0.checkCoherency() - f.setFieldNoProfileSBT(fCell0) - # - fCell1=MEDCouplingFieldDouble(ON_CELLS) ; fCell1.setTime(float(i),i,0) - fCell1.setName(fieldName) ; fCell1.setMesh(m1) - arr=DataArrayDouble(2*m1.getNumberOfCells()) ; arr.iota(4200) ; arr.rearrange(2) - fCell1.setArray(arr) ; arr.setInfoOnComponents(["Comp1 [m]","Com2 [s^2]"]) - fCell1.checkCoherency() - f.setFieldNoProfileSBT(fCell1) - # - fs.pushBackTimeStep(f) - mm.write(fname,2) - fs.write(fname,0) - a0Exp=mm.getCoords().deepCpy() - del m,m1,mm,fs,f,fCell0,fCell1 - ########## GO for reading in MEDReader, by not loading all. Mesh is fully loaded but not fields values - ms=MEDFileMeshes(fname) - fields=MEDFileFields(fname,False) - fields.removeFieldsWithoutAnyTimeStep() - fields_per_mesh=[fields.partOfThisLyingOnSpecifiedMeshName(meshName) for meshName in ms.getMeshesNames()] - allFMTSLeavesToDisplay=[] - for fields in fields_per_mesh: - allFMTSLeavesToDisplay2=[] - for fmts in fields: - tmp=fmts.splitDiscretizations() - for itmp in tmp: - self.assertTrue(not itmp.presenceOfMultiDiscPerGeoType()) - pass - allFMTSLeavesToDisplay2+=tmp - pass - allFMTSLeavesToDisplay.append(allFMTSLeavesToDisplay2) - pass - self.assertEqual(len(allFMTSLeavesToDisplay),1) - self.assertEqual(len(allFMTSLeavesToDisplay[0]),2) - allFMTSLeavesPerTimeSeries=MEDFileAnyTypeFieldMultiTS.SplitIntoCommonTimeSeries(sum(allFMTSLeavesToDisplay,[])) - self.assertEqual(len(allFMTSLeavesPerTimeSeries),2) # two time series here : one for the cells, the second one for the nodes - self.assertEqual(len(allFMTSLeavesPerTimeSeries[0]),1) - self.assertEqual(len(allFMTSLeavesPerTimeSeries[1]),1) - allFMTSLeavesPerCommonSupport=MEDFileAnyTypeFieldMultiTS.SplitPerCommonSupport(allFMTSLeavesPerTimeSeries[0],ms[ms.getMeshesNames()[0]]) - self.assertEqual(len(allFMTSLeavesPerCommonSupport),1) - self.assertEqual(len(allFMTSLeavesPerCommonSupport[0][0]),1) - # - mst=MEDFileMeshStruct.New(ms[0]) - fcscp=allFMTSLeavesPerCommonSupport[0][1] # start with the cells - mml=fcscp.buildFromScratchDataSetSupport(0,fields) - mml2=mml.prepare() - self.assertTrue(isinstance(mml2,MEDUMeshMultiLev)) - for i in xrange(1,3): - self.assertTrue(fcscp.isDataSetSupportEqualToThePreviousOne(i,fields)) - pass - ncc,a0,a1,a2,a3,a4,a5=mml2.buildVTUArrays() - self.assertTrue(not ncc) - self.assertTrue(a0.isEqual(a0Exp.changeNbOfComponents(3,0.),1e-12)) - self.assertTrue(a1.isEqual(DataArrayByte([3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,5,5,5,5,9,9,9,9,9]))) - self.assertTrue(a2.isEqual(DataArrayInt([0,3,6,9,12,15,18,21,24,27,30,33,36,39,42,45,48,51,54,57,60,63,66,69,72,75,78,81,84,87,90,93,96,100,104,108,112,117,122,127,132]))) - self.assertTrue(a3.isEqual(DataArrayInt([2,0,1,2,1,2,2,2,0,2,3,4,2,4,5,2,5,3,2,6,7,2,7,8,2,8,6,2,9,10,2,10,11,2,11,9,2,12,13,2,13,14,2,14,15,2,15,12,2,16,17,2,17,18,2,18,19,2,19,16,2,20,21,2,21,22,2,22,23,2,23,20,2,24,25,2,25,26,2,26,27,2,27,24,2,28,29,2,29,30,2,30,31,2,31,28,3,0,1,2,3,3,4,5,3,6,7,8,3,9,10,11,4,12,13,14,15,4,16,17,18,19,4,20,21,22,23,4,24,25,26,27,4,28,29,30,31]))) - assert a4 is None - assert a5 is None - # for cells - for i in xrange(3): - f=allFMTSLeavesPerCommonSupport[0][0][0][i] - fsst=MEDFileField1TSStructItem.BuildItemFrom(f,mst)# Second 0 is for cells - f.loadArraysIfNecessary() - self.assertEqual(f.getName(),"zeField") - v=mml.buildDataArray(fsst,fields,f.getUndergroundDataArray()) - self.assertEqual(v.getHiddenCppPointer(),f.getUndergroundDataArray().getHiddenCppPointer()) - vExp=DataArrayDouble([200.,201.,202.,203.,204.,205.,206.,207.,208.,209.,210.,211.,212.,213.,214.,215.,216.,217.,218.,219.,220.,221.,222.,223.,224.,225.,226.,227.,228.,229.,230.,231.,232.,233.,234.,235.,236.,237.,238.,239.,240.,241.,242.,243.,244.,245.,246.,247.,248.,249.,250.,251.,252.,253.,254.,255.,256.,257.,258.,259.,260.,261.,262.,263.,100.,101.,102.,103.,104.,105.,106.,107.,108.,109.,110.,111.,112.,113.,114.,115.,116.,117.],41,2) ; vExp.setInfoOnComponents(['Comp1 [m]','Com2 [s^2]']) ; vExp+=i*2000 - self.assertTrue(v.isEqual(vExp,1e-12)) - pass - # for nodes - allFMTSLeavesPerCommonSupport=MEDFileAnyTypeFieldMultiTS.SplitPerCommonSupport(allFMTSLeavesPerTimeSeries[1],ms[ms.getMeshesNames()[0]]) - self.assertEqual(len(allFMTSLeavesPerCommonSupport),1) - self.assertEqual(len(allFMTSLeavesPerCommonSupport[0][0]),1) - fcscp=allFMTSLeavesPerCommonSupport[0][1] - mml=fcscp.buildFromScratchDataSetSupport(0,fields) - mml2=mml.prepare() - self.assertTrue(isinstance(mml2,MEDUMeshMultiLev)) - for i in xrange(1,2): - self.assertTrue(fcscp.isDataSetSupportEqualToThePreviousOne(i,fields)) - pass - ncc,a0,a1,a2,a3,a4,a5=mml2.buildVTUArrays() - self.assertTrue(not ncc) - self.assertTrue(a0.isEqual(a0Exp.changeNbOfComponents(3,0.),1e-12)) - self.assertTrue(a1.isEqual(DataArrayByte([5,5,5,5,9,9,9,9,9,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3]))) - self.assertTrue(a2.isEqual(DataArrayInt([0,4,8,12,16,21,26,31,36,41,44,47,50,53,56,59,62,65,68,71,74,77,80,83,86,89,92,95,98,101,104,107,110,113,116,119,122,125,128,131,134]))) - self.assertTrue(a3.isEqual(DataArrayInt([3,0,1,2,3,3,4,5,3,6,7,8,3,9,10,11,4,12,13,14,15,4,16,17,18,19,4,20,21,22,23,4,24,25,26,27,4,28,29,30,31,2,0,1,2,1,2,2,2,0,2,3,4,2,4,5,2,5,3,2,6,7,2,7,8,2,8,6,2,9,10,2,10,11,2,11,9,2,12,13,2,13,14,2,14,15,2,15,12,2,16,17,2,17,18,2,18,19,2,19,16,2,20,21,2,21,22,2,22,23,2,23,20,2,24,25,2,25,26,2,26,27,2,27,24,2,28,29,2,29,30,2,30,31,2,31,28]))) - self.assertTrue(a4 is None) - self.assertTrue(a5 is None) - for i in xrange(2): - f=allFMTSLeavesPerCommonSupport[0][0][0][i] - fsst=MEDFileField1TSStructItem.BuildItemFrom(f,mst)# Second 0 is for cells - f.loadArraysIfNecessary() - self.assertEqual(f.getName(),"zeField") - v=mml.buildDataArray(fsst,fields,f.getUndergroundDataArray()) - self.assertEqual(v.getHiddenCppPointer(),f.getUndergroundDataArray().getHiddenCppPointer()) - vExp=DataArrayDouble([300.,301.,302.,303.,304.,305.,306.,307.,308.,309.,310.,311.,312.,313.,314.,315.,316.,317.,318.,319.,320.,321.,322.,323.,324.,325.,326.,327.,328.,329.,330.,331.,332.,333.,334.,335.,336.,337.,338.,339.,340.,341.,342.,343.,344.,345.,346.,347.,348.,349.,350.,351.,352.,353.,354.,355.,356.,357.,358.,359.,360.,361.,362.,363.],32,2) ; vExp.setInfoOnComponents(['Comp1 [m]','Com2 [s^2]']) ; vExp.setInfoOnComponents(['Comp1 [m]','Com2 [s^2]']) ; vExp+=i*2000+1000 - self.assertTrue(v.isEqual(vExp,1e-12)) - pass - pass - - def test4(self): - """ This test defines 3 fields on nodes on the same mesh. All of these fields have no profile. - """ - fname="ForMEDReader4.med" - # building a mesh containing 4 tri3 + 5 quad4 - tri=MEDCouplingUMesh("tri",2) - tri.allocateCells() ; tri.insertNextCell(NORM_TRI3,[0,1,2]) - tri.setCoords(DataArrayDouble([(0.,0.),(0.,1.),(1.,0.)])) - tris=[tri.deepCpy() for i in xrange(4)] - for i,elt in enumerate(tris): elt.translate([i,0]) - tris=MEDCouplingUMesh.MergeUMeshes(tris) - quad=MEDCouplingUMesh("quad",2) - quad.allocateCells() ; quad.insertNextCell(NORM_QUAD4,[0,1,2,3]) - quad.setCoords(DataArrayDouble([(0.,0.),(0.,1.),(1.,1.),(1.,0.)])) - quads=[quad.deepCpy() for i in xrange(5)] - for i,elt in enumerate(quads): elt.translate([5+i,0]) - quads=MEDCouplingUMesh.MergeUMeshes(quads) - m=MEDCouplingUMesh.MergeUMeshes(tris,quads) - m.setName("mesh") ; m.getCoords().setInfoOnComponents(["XX [m]","YYY [km]"]) - mm=MEDFileUMesh() ; mm.setMeshes([m]) - # - fieldName1="zeField1" - fieldName2="zeField2" - fieldName3="zeField3" - fs1=MEDFileFieldMultiTS() ; fs2=MEDFileFieldMultiTS() ; fs3=MEDFileFieldMultiTS() - ##### Time step 0 - i=0 - f=MEDFileField1TS() - fNode=MEDCouplingFieldDouble(ON_NODES) ; fNode.setTime(float(i),i,0) - fNode.setName(fieldName1) ; fNode.setMesh(m) - arr=DataArrayDouble(2*m.getNumberOfNodes()) ; arr.iota(0+1000*i) ; arr.rearrange(2) - fNode.setArray(arr) ; arr.setInfoOnComponents(["Comp1_0 [m]","Com2_0 [s^2]"]) - fNode.checkCoherency() - f.setFieldNoProfileSBT(fNode) - fs1.pushBackTimeStep(f) - # - f=MEDFileField1TS() - fNode=MEDCouplingFieldDouble(ON_NODES) ; fNode.setTime(float(i),i,0) - fNode.setName(fieldName2) ; fNode.setMesh(m) - arr=DataArrayDouble(2*m.getNumberOfNodes()) ; arr.iota(100+1000*i) ; arr.rearrange(2) - fNode.setArray(arr) ; arr.setInfoOnComponents(["Comp1_1 [m]","Com2_1 [s^2]"]) - fNode.checkCoherency() - f.setFieldNoProfileSBT(fNode) - fs2.pushBackTimeStep(f) - # - f=MEDFileField1TS() - fNode=MEDCouplingFieldDouble(ON_NODES) ; fNode.setTime(float(i),i,0) - fNode.setName(fieldName3) ; fNode.setMesh(m) - arr=DataArrayDouble(2*m.getNumberOfNodes()) ; arr.iota(200+1000*i) ; arr.rearrange(2) - fNode.setArray(arr) ; arr.setInfoOnComponents(["Comp1_2 [m]","Com2_2 [s^2]"]) - fNode.checkCoherency() - f.setFieldNoProfileSBT(fNode) - fs3.pushBackTimeStep(f) - ##### Time step 1 - i=1 - f=MEDFileField1TS() - fNode=MEDCouplingFieldDouble(ON_NODES) ; fNode.setTime(float(i),i,0) - fNode.setName(fieldName1) ; fNode.setMesh(m) - arr=DataArrayDouble(2*m.getNumberOfNodes()) ; arr.iota(0+1000*i) ; arr.rearrange(2) - fNode.setArray(arr) ; arr.setInfoOnComponents(["Comp1_0 [m]","Com2_0 [s^2]"]) - fNode.checkCoherency() - f.setFieldNoProfileSBT(fNode) - fs1.pushBackTimeStep(f) - # - f=MEDFileField1TS() - fNode=MEDCouplingFieldDouble(ON_NODES) ; fNode.setTime(float(i),i,0) - fNode.setName(fieldName2) ; fNode.setMesh(m) - arr=DataArrayDouble(2*m.getNumberOfNodes()) ; arr.iota(100+1000*i) ; arr.rearrange(2) - fNode.setArray(arr) ; arr.setInfoOnComponents(["Comp1_1 [m]","Com2_1 [s^2]"]) - fNode.checkCoherency() - f.setFieldNoProfileSBT(fNode) - fs2.pushBackTimeStep(f) - # - f=MEDFileField1TS() - fNode=MEDCouplingFieldDouble(ON_NODES) ; fNode.setTime(float(i),i,0) - fNode.setName(fieldName3) ; fNode.setMesh(m) - arr=DataArrayDouble(2*m.getNumberOfNodes()) ; arr.iota(200+1000*i) ; arr.rearrange(2) - fNode.setArray(arr) ; arr.setInfoOnComponents(["Comp1_2 [m]","Com2_2 [s^2]"]) - fNode.checkCoherency() - f.setFieldNoProfileSBT(fNode) - fs3.pushBackTimeStep(f) - ##### Time step 2 - i=2 - f=MEDFileField1TS() - fNode=MEDCouplingFieldDouble(ON_NODES) ; fNode.setTime(float(i),i,0) - fNode.setName(fieldName1) ; fNode.setMesh(m) - arr=DataArrayDouble(2*m.getNumberOfNodes()) ; arr.iota(0+1000*i) ; arr.rearrange(2) - fNode.setArray(arr) ; arr.setInfoOnComponents(["Comp1_0 [m]","Com2_0 [s^2]"]) - fNode.checkCoherency() - f.setFieldNoProfileSBT(fNode) - fs1.pushBackTimeStep(f) - # - f=MEDFileField1TS() - fNode=MEDCouplingFieldDouble(ON_NODES) ; fNode.setTime(float(i),i,0) - fNode.setName(fieldName2) ; fNode.setMesh(m) - arr=DataArrayDouble(2*m.getNumberOfNodes()) ; arr.iota(100+1000*i) ; arr.rearrange(2) - fNode.setArray(arr) ; arr.setInfoOnComponents(["Comp1_1 [m]","Com2_1 [s^2]"]) - fNode.checkCoherency() - f.setFieldNoProfileSBT(fNode) - fs2.pushBackTimeStep(f) - # - f=MEDFileField1TS() - fNode=MEDCouplingFieldDouble(ON_NODES) ; fNode.setTime(float(i),i,0) - fNode.setName(fieldName3) ; fNode.setMesh(m) - arr=DataArrayDouble(2*m.getNumberOfNodes()) ; arr.iota(200+1000*i) ; arr.rearrange(2) - fNode.setArray(arr) ; arr.setInfoOnComponents(["Comp1_2 [m]","Com2_2 [s^2]"]) - fNode.checkCoherency() - f.setFieldNoProfileSBT(fNode) - fs3.pushBackTimeStep(f) - ##### Time step 3 - i=3 - f=MEDFileField1TS() - fNode=MEDCouplingFieldDouble(ON_NODES) ; fNode.setTime(float(i),i,0) - fNode.setName(fieldName1) ; fNode.setMesh(m) - arr=DataArrayDouble(2*m.getNumberOfNodes()) ; arr.iota(0+1000*i) ; arr.rearrange(2) - fNode.setArray(arr) ; arr.setInfoOnComponents(["Comp1_0 [m]","Com2_0 [s^2]"]) - fNode.checkCoherency() - f.setFieldNoProfileSBT(fNode) - fs1.pushBackTimeStep(f) - # - f=MEDFileField1TS() - fNode=MEDCouplingFieldDouble(ON_NODES) ; fNode.setTime(float(i),i,0) - fNode.setName(fieldName2) ; fNode.setMesh(m) - arr=DataArrayDouble(2*m.getNumberOfNodes()) ; arr.iota(100+1000*i) ; arr.rearrange(2) - fNode.setArray(arr) ; arr.setInfoOnComponents(["Comp1_1 [m]","Com2_1 [s^2]"]) - fNode.checkCoherency() - f.setFieldNoProfileSBT(fNode) - fs2.pushBackTimeStep(f) - # - f=MEDFileField1TS() - fNode=MEDCouplingFieldDouble(ON_NODES) ; fNode.setTime(float(i),i,0) - fNode.setName(fieldName3) ; fNode.setMesh(m) - arr=DataArrayDouble(2*m.getNumberOfNodes()) ; arr.iota(200+1000*i) ; arr.rearrange(2) - fNode.setArray(arr) ; arr.setInfoOnComponents(["Comp1_2 [m]","Com2_2 [s^2]"]) - fNode.checkCoherency() - f.setFieldNoProfileSBT(fNode) - fs3.pushBackTimeStep(f) - ##### Time step 4 - i=4 - f=MEDFileField1TS() - fNode=MEDCouplingFieldDouble(ON_NODES) ; fNode.setTime(float(i),i,0) - fNode.setName(fieldName1) ; fNode.setMesh(m) - arr=DataArrayDouble(2*m.getNumberOfNodes()) ; arr.iota(0+1000*i) ; arr.rearrange(2) - fNode.setArray(arr) ; arr.setInfoOnComponents(["Comp1_0 [m]","Com2_0 [s^2]"]) - fNode.checkCoherency() - f.setFieldNoProfileSBT(fNode) - fs1.pushBackTimeStep(f) - # - f=MEDFileField1TS() - fNode=MEDCouplingFieldDouble(ON_NODES) ; fNode.setTime(float(i),i,0) - fNode.setName(fieldName2) ; fNode.setMesh(m) - arr=DataArrayDouble(2*m.getNumberOfNodes()) ; arr.iota(100+1000*i) ; arr.rearrange(2) - fNode.setArray(arr) ; arr.setInfoOnComponents(["Comp1_1 [m]","Com2_1 [s^2]"]) - fNode.checkCoherency() - f.setFieldNoProfileSBT(fNode) - fs2.pushBackTimeStep(f) - # - f=MEDFileField1TS() - fNode=MEDCouplingFieldDouble(ON_NODES) ; fNode.setTime(float(i),i,0) - fNode.setName(fieldName3) ; fNode.setMesh(m) - arr=DataArrayDouble(2*m.getNumberOfNodes()) ; arr.iota(200+1000*i) ; arr.rearrange(2) - fNode.setArray(arr) ; arr.setInfoOnComponents(["Comp1_2 [m]","Com2_2 [s^2]"]) - fNode.checkCoherency() - f.setFieldNoProfileSBT(fNode) - fs3.pushBackTimeStep(f) - # - mm.write(fname,2) - fs1.write(fname,0) ; fs2.write(fname,0) ; fs3.write(fname,0) - a0Exp=mm.getCoords().deepCpy() - del m,mm,fs1,fs2,fs3,f,fNode - ########## GO for reading in MEDReader, by not loading all. Mesh is fully loaded but not fields values - ms=MEDFileMeshes(fname) - fields=MEDFileFields(fname,False) - fields.removeFieldsWithoutAnyTimeStep() - fields_per_mesh=[fields.partOfThisLyingOnSpecifiedMeshName(meshName) for meshName in ms.getMeshesNames()] - allFMTSLeavesToDisplay=[] - for fields in fields_per_mesh: - allFMTSLeavesToDisplay2=[] - for fmts in fields: - tmp=fmts.splitDiscretizations() - for itmp in tmp: - self.assertTrue(not itmp.presenceOfMultiDiscPerGeoType()) - pass - allFMTSLeavesToDisplay2+=tmp - pass - allFMTSLeavesToDisplay.append(allFMTSLeavesToDisplay2) - pass - self.assertEqual(len(allFMTSLeavesToDisplay),1) - self.assertEqual(len(allFMTSLeavesToDisplay[0]),3) - allFMTSLeavesPerTimeSeries=MEDFileAnyTypeFieldMultiTS.SplitIntoCommonTimeSeries(sum(allFMTSLeavesToDisplay,[])) - self.assertEqual(len(allFMTSLeavesPerTimeSeries),1) # one time serie here : because the 3 fields are defined on the same time steps - self.assertEqual(len(allFMTSLeavesPerTimeSeries[0]),3) - allFMTSLeavesPerCommonSupport=MEDFileAnyTypeFieldMultiTS.SplitPerCommonSupport(allFMTSLeavesPerTimeSeries[0],ms[ms.getMeshesNames()[0]]) - self.assertEqual(len(allFMTSLeavesPerCommonSupport),1) - self.assertEqual(len(allFMTSLeavesPerCommonSupport[0][0]),3) - # - mst=MEDFileMeshStruct.New(ms[0]) - fcscp=allFMTSLeavesPerCommonSupport[0][1] - self.assertEqual(len(allFMTSLeavesPerCommonSupport),1) - self.assertEqual(len(allFMTSLeavesPerCommonSupport[0][0]),3) - fcscp=allFMTSLeavesPerCommonSupport[0][1] - mml=fcscp.buildFromScratchDataSetSupport(0,fields) - mml2=mml.prepare() - self.assertTrue(isinstance(mml2,MEDUMeshMultiLev)) - for i in xrange(1,5): - self.assertTrue(fcscp.isDataSetSupportEqualToThePreviousOne(i,fields)) - pass - ncc,a0,a1,a2,a3,a4,a5=mml2.buildVTUArrays() - self.assertTrue(not ncc) - self.assertTrue(a0.isEqual(a0Exp.changeNbOfComponents(3,0.),1e-12)) - self.assertTrue(a1.isEqual(DataArrayByte([5,5,5,5,9,9,9,9,9]))) - self.assertTrue(a2.isEqual(DataArrayInt([0,4,8,12,16,21,26,31,36]))) - self.assertTrue(a3.isEqual(DataArrayInt([3,0,1,2,3,3,4,5,3,6,7,8,3,9,10,11,4,12,13,14,15,4,16,17,18,19,4,20,21,22,23,4,24,25,26,27,4,28,29,30,31]))) - self.assertTrue(a4 is None) - self.assertTrue(a5 is None) - # test all the time steps of the 1/1 time step serie, on field 1 - for i in xrange(5): - f=allFMTSLeavesPerCommonSupport[0][0][0][i] - fsst=MEDFileField1TSStructItem.BuildItemFrom(f,mst) - f.loadArraysIfNecessary() - v=mml.buildDataArray(fsst,fields,f.getUndergroundDataArray()) - self.assertEqual(f.getName(),fieldName1) - self.assertEqual(v.getHiddenCppPointer(),f.getUndergroundDataArray().getHiddenCppPointer()) - vExp=DataArrayDouble([0.,1.,2.,3.,4.,5.,6.,7.,8.,9.,10.,11.,12.,13.,14.,15.,16.,17.,18.,19.,20.,21.,22.,23.,24.,25.,26.,27.,28.,29.,30.,31.,32.,33.,34.,35.,36.,37.,38.,39.,40.,41.,42.,43.,44.,45.,46.,47.,48.,49.,50.,51.,52.,53.,54.,55.,56.,57.,58.,59.,60.,61.,62.,63.],32,2) ; vExp.setInfoOnComponents(['Comp1_0 [m]','Com2_0 [s^2]']) ; vExp+=i*1000 - self.assertTrue(v.isEqual(vExp,1e-12)) - pass - # test all the time steps of the 1/1 time step serie, on field 2 - for i in xrange(5): - f=allFMTSLeavesPerCommonSupport[0][0][1][i] - fsst=MEDFileField1TSStructItem.BuildItemFrom(f,mst) - f.loadArraysIfNecessary() - v=mml.buildDataArray(fsst,fields,f.getUndergroundDataArray()) - self.assertEqual(f.getName(),fieldName2) - self.assertEqual(v.getHiddenCppPointer(),f.getUndergroundDataArray().getHiddenCppPointer()) - vExp=DataArrayDouble([0.,1.,2.,3.,4.,5.,6.,7.,8.,9.,10.,11.,12.,13.,14.,15.,16.,17.,18.,19.,20.,21.,22.,23.,24.,25.,26.,27.,28.,29.,30.,31.,32.,33.,34.,35.,36.,37.,38.,39.,40.,41.,42.,43.,44.,45.,46.,47.,48.,49.,50.,51.,52.,53.,54.,55.,56.,57.,58.,59.,60.,61.,62.,63.],32,2) ; vExp.setInfoOnComponents(['Comp1_1 [m]','Com2_1 [s^2]']) ; vExp+=i*1000+100 - self.assertTrue(v.isEqual(vExp,1e-12)) - pass - # test all the time steps of the 1/1 time step serie, on field 3 - for i in xrange(5): - f=allFMTSLeavesPerCommonSupport[0][0][2][i] - fsst=MEDFileField1TSStructItem.BuildItemFrom(f,mst) - f.loadArraysIfNecessary() - v=mml.buildDataArray(fsst,fields,f.getUndergroundDataArray()) - self.assertEqual(f.getName(),fieldName3) - self.assertEqual(v.getHiddenCppPointer(),f.getUndergroundDataArray().getHiddenCppPointer()) - vExp=DataArrayDouble([0.,1.,2.,3.,4.,5.,6.,7.,8.,9.,10.,11.,12.,13.,14.,15.,16.,17.,18.,19.,20.,21.,22.,23.,24.,25.,26.,27.,28.,29.,30.,31.,32.,33.,34.,35.,36.,37.,38.,39.,40.,41.,42.,43.,44.,45.,46.,47.,48.,49.,50.,51.,52.,53.,54.,55.,56.,57.,58.,59.,60.,61.,62.,63.],32,2) ; vExp.setInfoOnComponents(['Comp1_2 [m]','Com2_2 [s^2]']) ; vExp+=i*1000+200 - self.assertTrue(v.isEqual(vExp,1e-12)) - pass - pass - - def test5(self): - """ This test plays with profiles both cell profiles and node profiles. Two first fields (resp on cells and on nodes) lie on the same mesh support whereas the third - mesh lies on a different mesh. - """ - fname="ForMEDReader5.med" - # building a mesh containing 6 tri3 + 5 quad4 - m=MEDCouplingUMesh("mesh",2) - coords=DataArrayDouble([(0,0),(1,0),(2,0),(3,0),(4,0),(0,1),(1,1),(2,1),(3,1),(4,1),(0,2),(1,2),(2,2),(3,2),(4,2)]) ; coords.setInfoOnComponents(["XX [m]","YYY [km]"]) - m.setCoords(coords) - m.allocateCells() - m.insertNextCell(NORM_TRI3,[2,7,3]) ; m.insertNextCell(NORM_TRI3,[7,8,3]) ; m.insertNextCell(NORM_TRI3,[3,8,4]) ; m.insertNextCell(NORM_TRI3,[8,9,4]) - m.insertNextCell(NORM_TRI3,[13,9,8]) ; m.insertNextCell(NORM_TRI3,[13,14,9]) - m.insertNextCell(NORM_QUAD4,[0,5,6,1]) ; m.insertNextCell(NORM_QUAD4,[1,6,7,2]) ; m.insertNextCell(NORM_QUAD4,[5,10,11,6]) ; m.insertNextCell(NORM_QUAD4,[6,11,12,7]) - m.insertNextCell(NORM_QUAD4,[12,13,8,7]) - mm=MEDFileUMesh() ; mm.setMeshes([m]) - fam=DataArrayInt(11) ; fam.iota(0) ; mm.setFamilyFieldArr(0,fam) ; del fam - num=DataArrayInt(11) ; num.iota(100) ; mm.setRenumFieldArr(0,num) ; del num - # - fieldName1="zeField1" ; pfl1=DataArrayInt([0,1,2,3,4,5]) ; pfl1.setName("pfl1") # on cells - fieldName2="zeField2" ; pfl2=DataArrayInt([2,3,4,7,8,9,13,14]) ; pfl2.setName("pfl2") # on nodes - fieldName3="zeField3" ; pfl3=DataArrayInt([0,1,2,3,4,5,9,10]) ; pfl3.setName("pfl3") # on cells but different support - fs1=MEDFileFieldMultiTS() ; fs2=MEDFileFieldMultiTS() ; fs3=MEDFileFieldMultiTS() - # - for i in xrange(5): - f=MEDFileField1TS() - fNode=MEDCouplingFieldDouble(ON_CELLS) ; fNode.setTime(float(i),i,0) - fNode.setName(fieldName1) - arr=DataArrayDouble(2*6) ; arr.iota(0+1000*i) ; arr.rearrange(2) - fNode.setArray(arr) ; arr.setInfoOnComponents(["Comp1_0 [m]","Com2_0 [s^2]"]) - f.setFieldProfile(fNode,mm,0,pfl1) - fs1.pushBackTimeStep(f) - # - f=MEDFileField1TS() - fNode=MEDCouplingFieldDouble(ON_NODES) ; fNode.setTime(float(i),i,0) - fNode.setName(fieldName2) - arr=DataArrayDouble(2*8) ; arr.iota(100+1000*i) ; arr.rearrange(2) - fNode.setArray(arr) ; arr.setInfoOnComponents(["Comp1_1 [m]","Com2_1 [s^2]"]) - f.setFieldProfile(fNode,mm,0,pfl2) - fs2.pushBackTimeStep(f) - # - f=MEDFileField1TS() - fNode=MEDCouplingFieldDouble(ON_CELLS) ; fNode.setTime(float(i),i,0) - fNode.setName(fieldName3) - arr=DataArrayDouble(2*8) ; arr.iota(200+1000*i) ; arr.rearrange(2) - fNode.setArray(arr) ; arr.setInfoOnComponents(["Comp1_2 [m]","Com2_2 [s^2]"]) - f.setFieldProfile(fNode,mm,0,pfl3) - fs3.pushBackTimeStep(f) - pass - mm.write(fname,2) - fs1.write(fname,0) ; fs2.write(fname,0) ; fs3.write(fname,0) - a0Exp=mm.getCoords().deepCpy() - del m,mm,fs1,fs2,fs3,f,fNode - ########## GO for reading in MEDReader,by not loading all. Mesh is fully loaded but not fields values - ms=MEDFileMeshes(fname) - fields=MEDFileFields(fname,False) - fields.removeFieldsWithoutAnyTimeStep() - fields_per_mesh=[fields.partOfThisLyingOnSpecifiedMeshName(meshName) for meshName in ms.getMeshesNames()] - allFMTSLeavesToDisplay=[] - for fields in fields_per_mesh: - allFMTSLeavesToDisplay2=[] - for fmts in fields: - tmp=fmts.splitDiscretizations() - for itmp in tmp: - self.assertTrue(not itmp.presenceOfMultiDiscPerGeoType()) - pass - allFMTSLeavesToDisplay2+=tmp - pass - allFMTSLeavesToDisplay.append(allFMTSLeavesToDisplay2) - pass - self.assertEqual(len(allFMTSLeavesToDisplay),1) - self.assertEqual(len(allFMTSLeavesToDisplay[0]),3) - allFMTSLeavesPerTimeSeries=MEDFileAnyTypeFieldMultiTS.SplitIntoCommonTimeSeries(sum(allFMTSLeavesToDisplay,[])) - self.assertEqual(len(allFMTSLeavesPerTimeSeries),1) # one time serie here : because the 3 fields are defined on the same time steps - self.assertEqual(len(allFMTSLeavesPerTimeSeries[0]),3) - allFMTSLeavesPerCommonSupport=MEDFileAnyTypeFieldMultiTS.SplitPerCommonSupport(allFMTSLeavesPerTimeSeries[0],ms[ms.getMeshesNames()[0]]) - ms[0].getDirectUndergroundSingleGeoTypeMeshes(0) - self.assertEqual(len(allFMTSLeavesPerCommonSupport),2) # 2 support here - self.assertEqual(len(allFMTSLeavesPerCommonSupport[0][0]),2) - self.assertEqual(len(allFMTSLeavesPerCommonSupport[1][0]),1) - # - mst=MEDFileMeshStruct.New(ms[0]) - fcscp=allFMTSLeavesPerCommonSupport[0][1] - mml=fcscp.buildFromScratchDataSetSupport(0,fields) - mml2=mml.prepare() - self.assertTrue(isinstance(mml2,MEDUMeshMultiLev)) - for i in xrange(1,5): - self.assertTrue((fcscp.isDataSetSupportEqualToThePreviousOne(i,fields))) - pass - ncc,a0,a1,a2,a3,a4,a5=mml2.buildVTUArrays() - self.assertTrue(not ncc) - self.assertTrue(a0.isEqual(a0Exp[pfl2].changeNbOfComponents(3,0.),1e-12)) - self.assertTrue(a1.isEqual(DataArrayByte([5,5,5,5,5,5]))) - self.assertTrue(a2.isEqual(DataArrayInt([0,4,8,12,16,20]))) - self.assertTrue(a3.isEqual(DataArrayInt([3,0,3,1,3,3,4,1,3,1,4,2,3,4,5,2,3,6,5,4,3,6,7,5]))) - assert a4 is None - assert a5 is None - a6,a7=mml2.retrieveFamilyIdsOnCells() - self.assertTrue(a6.isEqual(DataArrayInt([0,1,2,3,4,5]))) - self.assertTrue(not a7) - a8,a9=mml2.retrieveNumberIdsOnCells() - self.assertTrue(a8.isEqual(DataArrayInt([100,101,102,103,104,105]))) - self.assertTrue(not a9) - for i in xrange(5): - nbOfT=[6,8] - fieldNames=[fieldName1,fieldName2] - for j in xrange(2): - m={"i":j} - f=allFMTSLeavesPerCommonSupport[0][0][j][i] - fsst=MEDFileField1TSStructItem.BuildItemFrom(f,mst) - f.loadArraysIfNecessary() - v=mml.buildDataArray(fsst,fields,f.getUndergroundDataArray()) - self.assertEqual(f.getName(),fieldNames[j]) - self.assertEqual(v.getHiddenCppPointer(),f.getUndergroundDataArray().getHiddenCppPointer()) - vExp=DataArrayDouble(nbOfT[j]*2) ; vExp.iota(j*100+i*1000) ; vExp.rearrange(2) ; vExp.setInfoOnComponents(['Comp1_%(i)i [m]'%m,'Com2_%(i)i [s^2]'%m]) - self.assertTrue(v.isEqual(vExp,1e-12)) - pass - pass - # Let's go for the 2nd support - fcscp=allFMTSLeavesPerCommonSupport[1][1] - mml=fcscp.buildFromScratchDataSetSupport(0,fields) - mml2=mml.prepare() - self.assertTrue(isinstance(mml2,MEDUMeshMultiLev)) - for i in xrange(1,5): - self.assertTrue(fcscp.isDataSetSupportEqualToThePreviousOne(i,fields)) - pass - ncc,a0,a1,a2,a3,a4,a5=mml2.buildVTUArrays() - self.assertTrue(not ncc) - self.assertTrue(a0.isEqual(a0Exp.changeNbOfComponents(3,0.),1e-12)) - self.assertTrue(a1.isEqual(DataArrayByte([5,5,5,5,5,5,9,9]))) - self.assertTrue(a2.isEqual(DataArrayInt([0,4,8,12,16,20,24,29]))) - self.assertTrue(a3.isEqual(DataArrayInt([3,2,7,3,3,7,8,3,3,3,8,4,3,8,9,4,3,13,9,8,3,13,14,9,4,6,11,12,7,4,12,13,8,7]))) - self.assertTrue(a4 is None) - self.assertTrue(a5 is None) - a6,a7=mml2.retrieveFamilyIdsOnCells() - self.assertTrue(a6.isEqual(DataArrayInt([0,1,2,3,4,5,9,10]))) - self.assertTrue(not a7) - a8,a9=mml2.retrieveNumberIdsOnCells() - self.assertTrue(a8.isEqual(DataArrayInt([100,101,102,103,104,105,109,110]))) - self.assertTrue(not a9) - for i in xrange(5): - f=allFMTSLeavesPerCommonSupport[1][0][0][i] - fsst=MEDFileField1TSStructItem.BuildItemFrom(f,mst) - f.loadArraysIfNecessary() - v=mml.buildDataArray(fsst,fields,f.getUndergroundDataArray()) - self.assertEqual(f.getName(),"zeField3") - self.assertEqual(v.getHiddenCppPointer(),f.getUndergroundDataArray().getHiddenCppPointer()) - vExp=DataArrayDouble(8*2) ; vExp.iota(200+1000*i) ; vExp.rearrange(2) ; vExp.setInfoOnComponents(['Comp1_2 [m]'%m,'Com2_2 [s^2]'%m]) - self.assertTrue(v.isEqual(vExp,1e-12)) - pass - pass - - def test6(self): - """ This test plays with cartesian mesh and profiles. When a sub cartesian mesh can also be considered as a cartesian mesh it is done. - """ - fname="ForMEDReader6.med" - m=MEDCouplingCMesh("mesh") - coordsX=DataArrayDouble([0,1.1,2.2,3.3,4.4]) ; coordsX.setInfoOnComponents(["XX [m]"]) - coordsY=DataArrayDouble([0,1.7,3.4]) ; coordsY.setInfoOnComponents(["YYY [km]"]) - m.setCoords(coordsX,coordsY) - mm=MEDFileCMesh() ; mm.setMesh(m) - fam=DataArrayInt(8) ; fam.iota(0) ; mm.setFamilyFieldArr(0,fam) ; del fam - num=DataArrayInt(8) ; num.iota(100) ; mm.setRenumFieldArr(0,num) ; del num - num=DataArrayInt(15) ; num.iota(200) ; mm.setRenumFieldArr(1,num) ; del num - # - fieldName0="zeField0" ; # on cells - fieldName1="zeField1" ; pfl1=DataArrayInt([2,3,6,7]) ; pfl1.setName("pfl1") # on cells - fieldName2="zeField2" ; pfl2=DataArrayInt([2,3,4,7,8,9,12,13,14]) ; pfl2.setName("pfl2") # on nodes - fieldName3="zeField3" ; pfl3=DataArrayInt([2,3,5,7]) ; pfl3.setName("pfl3") # on cells but different support - fieldName4="zeField4" ;# on nodes - fs0=MEDFileFieldMultiTS() ; fs1=MEDFileFieldMultiTS() ; fs2=MEDFileFieldMultiTS() ; fs3=MEDFileFieldMultiTS() ; fs4=MEDFileFieldMultiTS() - # - for i in xrange(5): - f=MEDFileField1TS() - fNode=MEDCouplingFieldDouble(ON_CELLS) ; fNode.setTime(float(i),i,0) - fNode.setName(fieldName0) ; fNode.setMesh(m) - arr=DataArrayDouble(2*8) ; arr.iota(0+1000*i) ; arr.rearrange(2) - fNode.setArray(arr) ; arr.setInfoOnComponents(["Comp1_0 [m]","Com2_0 [s^2]"]) ; fNode.checkCoherency() - f.setFieldNoProfileSBT(fNode) - fs0.pushBackTimeStep(f) - # - f=MEDFileField1TS() - fNode=MEDCouplingFieldDouble(ON_CELLS) ; fNode.setTime(float(i),i,0) - fNode.setName(fieldName1) - arr=DataArrayDouble(2*4) ; arr.iota(100+1000*i) ; arr.rearrange(2) - fNode.setArray(arr) ; arr.setInfoOnComponents(["Comp1_1 [m]","Com2_1 [s^2]"]) - f.setFieldProfile(fNode,mm,0,pfl1) - self.assertEqual(pfl1.getName(),"pfl1") - fs1.pushBackTimeStep(f) - # - f=MEDFileField1TS() - fNode=MEDCouplingFieldDouble(ON_NODES) ; fNode.setTime(float(i),i,0) - fNode.setName(fieldName2) - arr=DataArrayDouble(2*9) ; arr.iota(200+1000*i) ; arr.rearrange(2) - fNode.setArray(arr) ; arr.setInfoOnComponents(["Comp1_2 [m]","Com2_2 [s^2]"]) - f.setFieldProfile(fNode,mm,0,pfl2) - self.assertEqual(pfl2.getName(),"pfl2") - fs2.pushBackTimeStep(f) - # - f=MEDFileField1TS() - fNode=MEDCouplingFieldDouble(ON_CELLS) ; fNode.setTime(float(i),i,0) - fNode.setName(fieldName3) - arr=DataArrayDouble(2*4) ; arr.iota(300+1000*i) ; arr.rearrange(2) - fNode.setArray(arr) ; arr.setInfoOnComponents(["Comp1_3 [m]","Com2_3 [s^2]"]) - f.setFieldProfile(fNode,mm,0,pfl3) - self.assertEqual(pfl3.getName(),"pfl3") - fs3.pushBackTimeStep(f) - # - f=MEDFileField1TS() - fNode=MEDCouplingFieldDouble(ON_NODES) ; fNode.setTime(float(i),i,0) - fNode.setName(fieldName4) ; fNode.setMesh(m) - arr=DataArrayDouble(2*15) ; arr.iota(400+1000*i) ; arr.rearrange(2) - fNode.setArray(arr) ; arr.setInfoOnComponents(["Comp1_4 [m]","Com2_4 [s^2]"]) ; fNode.checkCoherency() - f.setFieldNoProfileSBT(fNode) - fs4.pushBackTimeStep(f) - pass - mm.write(fname,2) - fs0.write(fname,0) ; fs1.write(fname,0) ; fs2.write(fname,0) ; fs3.write(fname,0) ; fs4.write(fname,0) - del m,mm,fs1,fs2,fs3,f,fNode - ########## GO for reading in MEDReader,by not loading all. Mesh is fully loaded but not fields values - ms=MEDFileMeshes(fname) - fields=MEDFileFields(fname,False) - fields.removeFieldsWithoutAnyTimeStep() - fields_per_mesh=[fields.partOfThisLyingOnSpecifiedMeshName(meshName) for meshName in ms.getMeshesNames()] - allFMTSLeavesToDisplay=[] - for fields in fields_per_mesh: - allFMTSLeavesToDisplay2=[] - for fmts in fields: - tmp=fmts.splitDiscretizations() - for itmp in tmp: - self.assertTrue(not itmp.presenceOfMultiDiscPerGeoType()) - pass - allFMTSLeavesToDisplay2+=tmp - pass - allFMTSLeavesToDisplay.append(allFMTSLeavesToDisplay2) - pass - self.assertEqual(len(allFMTSLeavesToDisplay),1) - self.assertEqual(len(allFMTSLeavesToDisplay[0]),5) - allFMTSLeavesPerTimeSeries=MEDFileAnyTypeFieldMultiTS.SplitIntoCommonTimeSeries(sum(allFMTSLeavesToDisplay,[])) - self.assertEqual(len(allFMTSLeavesPerTimeSeries),1) # one time serie here : because the 5 fields are defined on the same time steps - self.assertEqual(len(allFMTSLeavesPerTimeSeries[0]),5) - allFMTSLeavesPerCommonSupport=MEDFileAnyTypeFieldMultiTS.SplitPerCommonSupport(allFMTSLeavesPerTimeSeries[0],ms[ms.getMeshesNames()[0]]) - self.assertEqual(len(allFMTSLeavesPerCommonSupport),3) - self.assertEqual(len(allFMTSLeavesPerCommonSupport[0][0]),2) - self.assertEqual(len(allFMTSLeavesPerCommonSupport[1][0]),2) - self.assertEqual(len(allFMTSLeavesPerCommonSupport[2][0]),1) - # - mst=MEDFileMeshStruct.New(ms[0]) - # - fcscp=allFMTSLeavesPerCommonSupport[0][1] - mml=fcscp.buildFromScratchDataSetSupport(0,fields) - mml2=mml.prepare() - (a,b),c=mml2.buildVTUArrays() - self.assertTrue(c)# c is True here because the returned array is directly those coming from internal structure - self.assertTrue(a.isEqual(coordsX,1e-12)) - self.assertTrue(b.isEqual(coordsY,1e-12)) - self.assertTrue(isinstance(mml2,MEDCMeshMultiLev)) - for i in xrange(1,5): - self.assertTrue((fcscp.isDataSetSupportEqualToThePreviousOne(i,fields))) - pass - a6,a7=mml2.retrieveFamilyIdsOnCells() - self.assertTrue(a6.isEqual(DataArrayInt([0,1,2,3,4,5,6,7]))) - self.assertTrue(a7) # True because no copy - a8,a9=mml2.retrieveNumberIdsOnCells() - self.assertTrue(a8.isEqual(DataArrayInt([100,101,102,103,104,105,106,107]))) - self.assertTrue(a9) # True because no copy - a10,a11=mml2.retrieveNumberIdsOnNodes() - self.assertTrue(a10.isEqual(DataArrayInt([200,201,202,203,204,205,206,207,208,209,210,211,212,213,214]))) - self.assertTrue(a11) # True because no copy - for i in xrange(5): - f=allFMTSLeavesPerCommonSupport[0][0][0][i] - fsst=MEDFileField1TSStructItem.BuildItemFrom(f,mst) - f.loadArraysIfNecessary() - v=mml.buildDataArray(fsst,fields,f.getUndergroundDataArray()) - self.assertEqual(f.getName(),fieldName0) - self.assertEqual(v.getHiddenCppPointer(),f.getUndergroundDataArray().getHiddenCppPointer()) - vExp=DataArrayDouble(8*2) ; vExp.iota(0+i*1000) ; vExp.rearrange(2) ; vExp.setInfoOnComponents(['Comp1_0 [m]','Com2_0 [s^2]']) - self.assertTrue(v.isEqual(vExp,1e-12)) - # - f=allFMTSLeavesPerCommonSupport[0][0][1][i] - fsst=MEDFileField1TSStructItem.BuildItemFrom(f,mst) - f.loadArraysIfNecessary() - v=mml.buildDataArray(fsst,fields,f.getUndergroundDataArray()) - self.assertEqual(f.getName(),fieldName4) - self.assertEqual(v.getHiddenCppPointer(),f.getUndergroundDataArray().getHiddenCppPointer()) - vExp=DataArrayDouble(15*2) ; vExp.iota(400+i*1000) ; vExp.rearrange(2) ; vExp.setInfoOnComponents(['Comp1_4 [m]','Com2_4 [s^2]']) - self.assertTrue(v.isEqual(vExp,1e-12)) - pass - - fcscp=allFMTSLeavesPerCommonSupport[1][1] - mml=fcscp.buildFromScratchDataSetSupport(0,fields) - mml2=mml.prepare() - self.assertTrue(isinstance(mml2,MEDCMeshMultiLev)) # here the 2nd support is a part of CMesh that is also a CMesh -> CMesh not a UMesh - (a,b),c=mml2.buildVTUArrays() - self.assertTrue(not c)# c is False because this a sub support specialy built for buildVTUArrays - self.assertTrue(a.isEqual(coordsX[[2,3,4]],1e-12)) - self.assertTrue(b.isEqual(coordsY,1e-12)) - a6,a7=mml2.retrieveFamilyIdsOnCells() - self.assertTrue(a6.isEqual(DataArrayInt([2,3,6,7]))) - self.assertTrue(not a7) # False because copy - a8,a9=mml2.retrieveNumberIdsOnCells() - self.assertTrue(a8.isEqual(DataArrayInt([102,103,106,107]))) - self.assertTrue(not a9) # False because copy - a10,a11=mml2.retrieveNumberIdsOnNodes() - self.assertTrue(a10.isEqual(DataArrayInt([202,203,204,207,208,209,212,213,214]))) - self.assertTrue(not a11) # False because copy - for i in xrange(1,5): - self.assertTrue((fcscp.isDataSetSupportEqualToThePreviousOne(i,fields))) - pass - for i in xrange(5): - f=allFMTSLeavesPerCommonSupport[1][0][0][i] - fsst=MEDFileField1TSStructItem.BuildItemFrom(f,mst) - f.loadArraysIfNecessary() - v=mml.buildDataArray(fsst,fields,f.getUndergroundDataArray()) - self.assertEqual(f.getName(),fieldName1) - self.assertEqual(v.getHiddenCppPointer(),f.getUndergroundDataArray().getHiddenCppPointer()) - vExp=DataArrayDouble(4*2) ; vExp.iota(100+i*1000) ; vExp.rearrange(2) ; vExp.setInfoOnComponents(['Comp1_1 [m]','Com2_1 [s^2]']) - self.assertTrue(v.isEqual(vExp,1e-12)) - # - f=allFMTSLeavesPerCommonSupport[1][0][1][i] - fsst=MEDFileField1TSStructItem.BuildItemFrom(f,mst) - f.loadArraysIfNecessary() - v=mml.buildDataArray(fsst,fields,f.getUndergroundDataArray()) - self.assertEqual(f.getName(),fieldName2) - self.assertEqual(v.getHiddenCppPointer(),f.getUndergroundDataArray().getHiddenCppPointer()) - vExp=DataArrayDouble(9*2) ; vExp.iota(200+i*1000) ; vExp.rearrange(2) ; vExp.setInfoOnComponents(['Comp1_2 [m]','Com2_2 [s^2]']) - self.assertTrue(v.isEqual(vExp,1e-12)) - pass - # - fcscp=allFMTSLeavesPerCommonSupport[2][1] - mml=fcscp.buildFromScratchDataSetSupport(0,fields) - mml2=mml.prepare() - self.assertTrue(isinstance(mml2,MEDUMeshMultiLev)) # here the 3rd support is a part of CMesh but impossible to simplify more than a UMesh - ncc,a0,a1,a2,a3,a4,a5=mml2.buildVTUArrays() - self.assertTrue(not ncc) - a0Exp=DataArrayDouble([0.,0.,1.1,0.,2.2,0.,3.3,0.,4.4,0.,0.,1.7,1.1,1.7,2.2,1.7,3.3,1.7,4.4,1.7,0.,3.4,1.1,3.4,2.2,3.4,3.3,3.4,4.4,3.4],15,2) - a0Exp.setInfoOnComponents(["XX [m]","YYY [km]"]) - self.assertTrue(a0.isEqual(a0Exp.changeNbOfComponents(3,0.),1e-12)) - self.assertTrue(a1.isEqual(DataArrayByte([9,9,9,9]))) - self.assertTrue(a2.isEqual(DataArrayInt([0,5,10,15]))) - self.assertTrue(a3.isEqual(DataArrayInt([4,3,2,7,8,4,4,3,8,9,4,7,6,11,12,4,9,8,13,14]))) - self.assertTrue(a4 is None) - self.assertTrue(a5 is None) - a6,a7=mml2.retrieveFamilyIdsOnCells() - self.assertTrue(a6.isEqual(DataArrayInt([2,3,5,7]))) - self.assertTrue(not a7) # False because copy - a8,a9=mml2.retrieveNumberIdsOnCells() - self.assertTrue(a8.isEqual(DataArrayInt([102,103,105,107]))) - self.assertTrue(not a9) # False because copy - for i in xrange(5): - f=allFMTSLeavesPerCommonSupport[2][0][0][i] - fsst=MEDFileField1TSStructItem.BuildItemFrom(f,mst) - f.loadArraysIfNecessary() - v=mml.buildDataArray(fsst,fields,f.getUndergroundDataArray()) - self.assertEqual(f.getName(),fieldName3) - self.assertEqual(v.getHiddenCppPointer(),f.getUndergroundDataArray().getHiddenCppPointer()) - vExp=DataArrayDouble(4*2) ; vExp.iota(300+i*1000) ; vExp.rearrange(2) ; vExp.setInfoOnComponents(['Comp1_3 [m]','Com2_3 [s^2]']) - self.assertTrue(v.isEqual(vExp,1e-12)) - pass - pass - - def test7(self): - """ This test plays with curvilinear mesh and profiles. When a sub curvilinear mesh can also be considered as a cartesian mesh it is done. - This test is very similar to the test6. - """ - fname="ForMEDReader7.med" - m=MEDCouplingCurveLinearMesh("mesh") ; m.setNodeGridStructure([5,3]) - a0Exp=DataArrayDouble([0.,0.,1.1,0.,2.2,0.,3.3,0.,4.4,0.,0.,1.7,1.1,1.7,2.2,1.7,3.3,1.7,4.4,1.7,0.,3.4,1.1,3.4,2.2,3.4,3.3,3.4,4.4,3.4],15,2) - a0Exp.setInfoOnComponents(["XX [m]","YYY [km]"]) - m.setCoords(a0Exp) - mm=MEDFileCurveLinearMesh() ; mm.setMesh(m) - fam=DataArrayInt(8) ; fam.iota(0) ; mm.setFamilyFieldArr(0,fam) ; del fam - num=DataArrayInt(8) ; num.iota(100) ; mm.setRenumFieldArr(0,num) ; del num - # - fieldName0="zeField0" ; # on cells - fieldName1="zeField1" ; pfl1=DataArrayInt([2,3,6,7]) ; pfl1.setName("pfl1") # on cells - fieldName2="zeField2" ; pfl2=DataArrayInt([2,3,4,7,8,9,12,13,14]) ; pfl2.setName("pfl2") # on nodes - fieldName3="zeField3" ; pfl3=DataArrayInt([2,3,5,7]) ; pfl3.setName("pfl3") # on cells but different support - fieldName4="zeField4" ;# on nodes - fs0=MEDFileFieldMultiTS() ; fs1=MEDFileFieldMultiTS() ; fs2=MEDFileFieldMultiTS() ; fs3=MEDFileFieldMultiTS() ; fs4=MEDFileFieldMultiTS() - # - for i in xrange(5): - f=MEDFileField1TS() - fNode=MEDCouplingFieldDouble(ON_CELLS) ; fNode.setTime(float(i),i,0) - fNode.setName(fieldName0) ; fNode.setMesh(m) - arr=DataArrayDouble(2*8) ; arr.iota(0+1000*i) ; arr.rearrange(2) - fNode.setArray(arr) ; arr.setInfoOnComponents(["Comp1_0 [m]","Com2_0 [s^2]"]) ; fNode.checkCoherency() - f.setFieldNoProfileSBT(fNode) - fs0.pushBackTimeStep(f) - # - f=MEDFileField1TS() - fNode=MEDCouplingFieldDouble(ON_CELLS) ; fNode.setTime(float(i),i,0) - fNode.setName(fieldName1) - arr=DataArrayDouble(2*4) ; arr.iota(100+1000*i) ; arr.rearrange(2) - fNode.setArray(arr) ; arr.setInfoOnComponents(["Comp1_1 [m]","Com2_1 [s^2]"]) - f.setFieldProfile(fNode,mm,0,pfl1) - self.assertEqual(pfl1.getName(),"pfl1") - fs1.pushBackTimeStep(f) - # - f=MEDFileField1TS() - fNode=MEDCouplingFieldDouble(ON_NODES) ; fNode.setTime(float(i),i,0) - fNode.setName(fieldName2) - arr=DataArrayDouble(2*9) ; arr.iota(200+1000*i) ; arr.rearrange(2) - fNode.setArray(arr) ; arr.setInfoOnComponents(["Comp1_2 [m]","Com2_2 [s^2]"]) - f.setFieldProfile(fNode,mm,0,pfl2) - self.assertEqual(pfl2.getName(),"pfl2") - fs2.pushBackTimeStep(f) - # - f=MEDFileField1TS() - fNode=MEDCouplingFieldDouble(ON_CELLS) ; fNode.setTime(float(i),i,0) - fNode.setName(fieldName3) - arr=DataArrayDouble(2*4) ; arr.iota(300+1000*i) ; arr.rearrange(2) - fNode.setArray(arr) ; arr.setInfoOnComponents(["Comp1_3 [m]","Com2_3 [s^2]"]) - f.setFieldProfile(fNode,mm,0,pfl3) - self.assertEqual(pfl3.getName(),"pfl3") - fs3.pushBackTimeStep(f) - # - f=MEDFileField1TS() - fNode=MEDCouplingFieldDouble(ON_NODES) ; fNode.setTime(float(i),i,0) - fNode.setName(fieldName4) ; fNode.setMesh(m) - arr=DataArrayDouble(2*15) ; arr.iota(400+1000*i) ; arr.rearrange(2) - fNode.setArray(arr) ; arr.setInfoOnComponents(["Comp1_4 [m]","Com2_4 [s^2]"]) ; fNode.checkCoherency() - f.setFieldNoProfileSBT(fNode) - fs4.pushBackTimeStep(f) - pass - mm.write(fname,2) - fs0.write(fname,0) ; fs1.write(fname,0) ; fs2.write(fname,0) ; fs3.write(fname,0) ; fs4.write(fname,0) - del m,mm,fs1,fs2,fs3,f,fNode - ########## GO for reading in MEDReader,by not loading all. Mesh is fully loaded but not fields values - ms=MEDFileMeshes(fname) - fields=MEDFileFields(fname,False) - fields.removeFieldsWithoutAnyTimeStep() - fields_per_mesh=[fields.partOfThisLyingOnSpecifiedMeshName(meshName) for meshName in ms.getMeshesNames()] - allFMTSLeavesToDisplay=[] - for fields in fields_per_mesh: - allFMTSLeavesToDisplay2=[] - for fmts in fields: - tmp=fmts.splitDiscretizations() - for itmp in tmp: - self.assertTrue(not itmp.presenceOfMultiDiscPerGeoType()) - pass - allFMTSLeavesToDisplay2+=tmp - pass - allFMTSLeavesToDisplay.append(allFMTSLeavesToDisplay2) - pass - self.assertEqual(len(allFMTSLeavesToDisplay),1) - self.assertEqual(len(allFMTSLeavesToDisplay[0]),5) - allFMTSLeavesPerTimeSeries=MEDFileAnyTypeFieldMultiTS.SplitIntoCommonTimeSeries(sum(allFMTSLeavesToDisplay,[])) - self.assertEqual(len(allFMTSLeavesPerTimeSeries),1) # one time serie here : because the 5 fields are defined on the same time steps - self.assertEqual(len(allFMTSLeavesPerTimeSeries[0]),5) - allFMTSLeavesPerCommonSupport=MEDFileAnyTypeFieldMultiTS.SplitPerCommonSupport(allFMTSLeavesPerTimeSeries[0],ms[ms.getMeshesNames()[0]]) - self.assertEqual(len(allFMTSLeavesPerCommonSupport),3) - self.assertEqual(len(allFMTSLeavesPerCommonSupport[0][0]),2) - self.assertEqual(len(allFMTSLeavesPerCommonSupport[1][0]),2) - self.assertEqual(len(allFMTSLeavesPerCommonSupport[2][0]),1) - # - mst=MEDFileMeshStruct.New(ms[0]) - # - fcscp=allFMTSLeavesPerCommonSupport[0][1] - mml=fcscp.buildFromScratchDataSetSupport(0,fields) - mml2=mml.prepare() - self.assertTrue(isinstance(mml2,MEDCurveLinearMeshMultiLev)) - a,b,c=mml2.buildVTUArrays() - self.assertTrue(c)#True here because a is directly coming from internal data without copy - self.assertTrue(a.isEqual(a0Exp,1e-12)) - self.assertEqual(b,[5,3]) - a6,a7=mml2.retrieveFamilyIdsOnCells() - self.assertTrue(a6.isEqual(DataArrayInt([0,1,2,3,4,5,6,7]))) - self.assertTrue(a7) # True because no copy - a8,a9=mml2.retrieveNumberIdsOnCells() - self.assertTrue(a8.isEqual(DataArrayInt([100,101,102,103,104,105,106,107]))) - self.assertTrue(a9) # True because no copy - for i in xrange(1,5): - self.assertTrue((fcscp.isDataSetSupportEqualToThePreviousOne(i,fields))) - pass - for i in xrange(5): - f=allFMTSLeavesPerCommonSupport[0][0][0][i] - fsst=MEDFileField1TSStructItem.BuildItemFrom(f,mst) - f.loadArraysIfNecessary() - v=mml.buildDataArray(fsst,fields,f.getUndergroundDataArray()) - self.assertEqual(f.getName(),fieldName0) - self.assertEqual(v.getHiddenCppPointer(),f.getUndergroundDataArray().getHiddenCppPointer()) - vExp=DataArrayDouble(8*2) ; vExp.iota(0+i*1000) ; vExp.rearrange(2) ; vExp.setInfoOnComponents(['Comp1_0 [m]','Com2_0 [s^2]']) - self.assertTrue(v.isEqual(vExp,1e-12)) - # - f=allFMTSLeavesPerCommonSupport[0][0][1][i] - fsst=MEDFileField1TSStructItem.BuildItemFrom(f,mst) - f.loadArraysIfNecessary() - v=mml.buildDataArray(fsst,fields,f.getUndergroundDataArray()) - self.assertEqual(f.getName(),fieldName4) - self.assertEqual(v.getHiddenCppPointer(),f.getUndergroundDataArray().getHiddenCppPointer()) - vExp=DataArrayDouble(15*2) ; vExp.iota(400+i*1000) ; vExp.rearrange(2) ; vExp.setInfoOnComponents(['Comp1_4 [m]','Com2_4 [s^2]']) - self.assertTrue(v.isEqual(vExp,1e-12)) - pass - # - fcscp=allFMTSLeavesPerCommonSupport[1][1] - mml=fcscp.buildFromScratchDataSetSupport(0,fields) - mml2=mml.prepare() - self.assertTrue(isinstance(mml2,MEDCurveLinearMeshMultiLev)) # here the 2nd support is a part of CMesh that is also a CMesh -> CMesh not a UMesh - a,b,c=mml2.buildVTUArrays() - self.assertTrue(not c)#False here because a is the result of a computation not the internal strucutre - self.assertTrue(a.isEqual(a0Exp[pfl2],1e-12)) - self.assertEqual(b,[3,3]) - a6,a7=mml2.retrieveFamilyIdsOnCells() - self.assertTrue(a6.isEqual(DataArrayInt([2,3,6,7]))) - self.assertTrue(not a7) # False because copy - a8,a9=mml2.retrieveNumberIdsOnCells() - self.assertTrue(a8.isEqual(DataArrayInt([102,103,106,107]))) - self.assertTrue(not a9) # False because copy - for i in xrange(1,5): - self.assertTrue((fcscp.isDataSetSupportEqualToThePreviousOne(i,fields))) - pass - for i in xrange(5): - f=allFMTSLeavesPerCommonSupport[1][0][0][i] - fsst=MEDFileField1TSStructItem.BuildItemFrom(f,mst) - f.loadArraysIfNecessary() - v=mml.buildDataArray(fsst,fields,f.getUndergroundDataArray()) - self.assertEqual(f.getName(),fieldName1) - self.assertEqual(v.getHiddenCppPointer(),f.getUndergroundDataArray().getHiddenCppPointer()) - vExp=DataArrayDouble(4*2) ; vExp.iota(100+i*1000) ; vExp.rearrange(2) ; vExp.setInfoOnComponents(['Comp1_1 [m]','Com2_1 [s^2]']) - self.assertTrue(v.isEqual(vExp,1e-12)) - # - f=allFMTSLeavesPerCommonSupport[1][0][1][i] - fsst=MEDFileField1TSStructItem.BuildItemFrom(f,mst) - f.loadArraysIfNecessary() - v=mml.buildDataArray(fsst,fields,f.getUndergroundDataArray()) - self.assertEqual(f.getName(),fieldName2) - self.assertEqual(v.getHiddenCppPointer(),f.getUndergroundDataArray().getHiddenCppPointer()) - vExp=DataArrayDouble(9*2) ; vExp.iota(200+i*1000) ; vExp.rearrange(2) ; vExp.setInfoOnComponents(['Comp1_2 [m]','Com2_2 [s^2]']) - self.assertTrue(v.isEqual(vExp,1e-12)) - pass - # - fcscp=allFMTSLeavesPerCommonSupport[2][1] - mml=fcscp.buildFromScratchDataSetSupport(0,fields) - mml2=mml.prepare() - self.assertTrue(isinstance(mml2,MEDUMeshMultiLev)) # here the 3rd support is a part of CMesh but impossible to simplify more than a UMesh - ncc,a0,a1,a2,a3,a4,a5=mml2.buildVTUArrays() - self.assertTrue(not ncc) - a0Exp=DataArrayDouble([0.,0.,1.1,0.,2.2,0.,3.3,0.,4.4,0.,0.,1.7,1.1,1.7,2.2,1.7,3.3,1.7,4.4,1.7,0.,3.4,1.1,3.4,2.2,3.4,3.3,3.4,4.4,3.4],15,2) - a0Exp.setInfoOnComponents(["XX [m]","YYY [km]"]) - self.assertTrue(a0.isEqual(a0Exp.changeNbOfComponents(3,0.),1e-12)) - self.assertTrue(a1.isEqual(DataArrayByte([9,9,9,9]))) - self.assertTrue(a2.isEqual(DataArrayInt([0,5,10,15]))) - self.assertTrue(a3.isEqual(DataArrayInt([4,3,2,7,8,4,4,3,8,9,4,7,6,11,12,4,9,8,13,14]))) - self.assertTrue(a4 is None) - self.assertTrue(a5 is None) - a6,a7=mml2.retrieveFamilyIdsOnCells() - self.assertTrue(a6.isEqual(DataArrayInt([2,3,5,7]))) - self.assertTrue(not a7) # False because copy - a8,a9=mml2.retrieveNumberIdsOnCells() - self.assertTrue(a8.isEqual(DataArrayInt([102,103,105,107]))) - self.assertTrue(not a9) # False because copy - for i in xrange(5): - f=allFMTSLeavesPerCommonSupport[2][0][0][i] - fsst=MEDFileField1TSStructItem.BuildItemFrom(f,mst) - f.loadArraysIfNecessary() - v=mml.buildDataArray(fsst,fields,f.getUndergroundDataArray()) - self.assertEqual(f.getName(),fieldName3) - self.assertEqual(v.getHiddenCppPointer(),f.getUndergroundDataArray().getHiddenCppPointer()) - vExp=DataArrayDouble(4*2) ; vExp.iota(300+i*1000) ; vExp.rearrange(2) ; vExp.setInfoOnComponents(['Comp1_3 [m]','Com2_3 [s^2]']) - self.assertTrue(v.isEqual(vExp,1e-12)) - pass - pass - - def test8(self): - """ This test plays with with gauss fields with no profiles. - """ - fname="ForMEDReader8.med" - # building a mesh containing 6 tri3 + 5 quad4 - m=MEDCouplingUMesh("mesh",2) - coords=DataArrayDouble([(0,0),(1,0),(2,0),(3,0),(4,0),(0,1),(1,1),(2,1),(3,1),(4,1),(0,2),(1,2),(2,2),(3,2),(4,2)]) ; coords.setInfoOnComponents(["XX [m]","YYY [km]"]) - m.setCoords(coords) - m.allocateCells() - m.insertNextCell(NORM_TRI3,[2,7,3]) ; m.insertNextCell(NORM_TRI3,[7,8,3]) ; m.insertNextCell(NORM_TRI3,[3,8,4]) ; m.insertNextCell(NORM_TRI3,[8,9,4]) - m.insertNextCell(NORM_TRI3,[13,9,8]) ; m.insertNextCell(NORM_TRI3,[13,14,9]) - m.insertNextCell(NORM_QUAD4,[0,5,6,1]) ; m.insertNextCell(NORM_QUAD4,[1,6,7,2]) ; m.insertNextCell(NORM_QUAD4,[5,10,11,6]) ; m.insertNextCell(NORM_QUAD4,[6,11,12,7]) - m.insertNextCell(NORM_QUAD4,[12,13,8,7]) - mm=MEDFileUMesh() ; mm.setMeshes([m]) - # - fieldName0="zeField0" - fieldName1="zeField1" - fieldName2="zeField2" - fieldName3="zeField3" - fs0=MEDFileFieldMultiTS() ; fs1=MEDFileFieldMultiTS() ; fs2=MEDFileFieldMultiTS() ; fs3=MEDFileFieldMultiTS() - for i in xrange(5): - f=MEDFileField1TS() - fNode=MEDCouplingFieldDouble(ON_GAUSS_NE) ; fNode.setTime(float(i),i,0) - fNode.setName(fieldName0) ; fNode.setMesh(m) - arr=DataArrayDouble(2*38) ; arr.iota(0+1000*i) ; arr.rearrange(2) - fNode.setArray(arr) ; arr.setInfoOnComponents(["Comp1_0 [m]","Com2_0 [s^2]"]) ; fNode.checkCoherency() - f.setFieldNoProfileSBT(fNode) - fs0.pushBackTimeStep(f) - # - f=MEDFileField1TS() - fNode=MEDCouplingFieldDouble(ON_CELLS) ; fNode.setTime(float(i),i,0) - fNode.setName(fieldName1) ; fNode.setMesh(m) - arr=DataArrayDouble(2*11) ; arr.iota(100+1000*i) ; arr.rearrange(2) - fNode.setArray(arr) ; arr.setInfoOnComponents(["Comp1_1 [m]","Com2_1 [s^2]"]) ; fNode.checkCoherency() - f.setFieldNoProfileSBT(fNode) - fs1.pushBackTimeStep(f) - # - f=MEDFileField1TS() - fNode=MEDCouplingFieldDouble(ON_GAUSS_PT) ; fNode.setTime(float(i),i,0) - fNode.setName(fieldName2) ; fNode.setMesh(m) - fNode.setGaussLocalizationOnCells([0,1,2,3],[0.,0.,1.,0.,0.,1.],[0.5,0.5,0.7,0.7],[0.8,0.2]) - fNode.setGaussLocalizationOnCells([4,5],[0.,0.,1.,0.,0.,1.],[0.5,0.5,0.7,0.7,0.1,0.1,0.2,0.2,0.3,0.3],[0.8,0.05,0.1,0.04,0.01]) - fNode.setGaussLocalizationOnCells([6,7,8],[-1.,-1.,1.,-1.,1.,1.,-1.,1.],[0.5,0.5,0.7,0.7,0.1,0.1,0.2,0.2],[0.8,0.05,0.1,0.04]) - fNode.setGaussLocalizationOnCells([9,10],[-1.,-1.,1.,-1.,1.,1.,-1.,1.],[0.5,0.5,0.7,0.7,0.1,0.1,0.2,0.2,0.3,0.3,0.4,0.4,0.8,0.8],[0.8,0.05,0.1,0.01,0.02,0.005,0.005]) - arr=DataArrayDouble(2*(4*2+2*5+3*4+2*7)) ; arr.iota(300+1000*i) ; arr.rearrange(2) - fNode.setArray(arr) ; arr.setInfoOnComponents(["Comp1_2 [m]","Com2_2 [s^2]"]) ; fNode.checkCoherency() - f.setFieldNoProfileSBT(fNode) - fs2.pushBackTimeStep(f) - # - f=MEDFileField1TS() - fNode=MEDCouplingFieldDouble(ON_NODES) ; fNode.setTime(float(i),i,0) - fNode.setName(fieldName3) ; fNode.setMesh(m) - arr=DataArrayDouble(2*15) ; arr.iota(400+1000*i) ; arr.rearrange(2) - fNode.setArray(arr) ; arr.setInfoOnComponents(["Comp1_3 [m]","Com2_3 [s^2]"]) ; fNode.checkCoherency() - f.setFieldNoProfileSBT(fNode) - fs3.pushBackTimeStep(f) - # - pass - # - mm.write(fname,2) - fs0.write(fname,0) ; fs1.write(fname,0) ; fs2.write(fname,0) ; fs3.write(fname,0) - a0Exp=mm.getCoords().deepCpy() - del m,mm,fs1,fs2,fs3,f,fNode - ########## GO for reading in MEDReader,by not loading all. Mesh is fully loaded but not fields values - ms=MEDFileMeshes(fname) - fields=MEDFileFields(fname,False) - fields.removeFieldsWithoutAnyTimeStep() - fields_per_mesh=[fields.partOfThisLyingOnSpecifiedMeshName(meshName) for meshName in ms.getMeshesNames()] - allFMTSLeavesToDisplay=[] - for fields in fields_per_mesh: - allFMTSLeavesToDisplay2=[] - for fmts in fields: - tmp=fmts.splitDiscretizations() - #for itmp in tmp: - # self.assertTrue(not itmp.presenceOfMultiDiscPerGeoType()) - # pass - allFMTSLeavesToDisplay2+=tmp - pass - allFMTSLeavesToDisplay.append(allFMTSLeavesToDisplay2) - pass - self.assertEqual(len(allFMTSLeavesToDisplay),1) - self.assertEqual(len(allFMTSLeavesToDisplay[0]),4) - allFMTSLeavesPerTimeSeries=MEDFileAnyTypeFieldMultiTS.SplitIntoCommonTimeSeries(sum(allFMTSLeavesToDisplay,[])) - self.assertEqual(len(allFMTSLeavesPerTimeSeries),1) # one time serie here : because the 4 fields are defined on the same time steps - self.assertEqual(len(allFMTSLeavesPerTimeSeries[0]),4) - allFMTSLeavesPerCommonSupport=MEDFileAnyTypeFieldMultiTS.SplitPerCommonSupport(allFMTSLeavesPerTimeSeries[0],ms[ms.getMeshesNames()[0]]) - self.assertEqual(len(allFMTSLeavesPerCommonSupport),1) - self.assertEqual(len(allFMTSLeavesPerCommonSupport[0][0]),4) - # - mst=MEDFileMeshStruct.New(ms[0]) - # - fcscp=allFMTSLeavesPerCommonSupport[0][1] - mml=fcscp.buildFromScratchDataSetSupport(0,fields) - mml2=mml.prepare() - self.assertTrue(isinstance(mml2,MEDUMeshMultiLev)) - ncc,a0,a1,a2,a3,a4,a5=mml2.buildVTUArrays() - self.assertTrue(not ncc) - self.assertTrue(a0.isEqual(a0Exp.changeNbOfComponents(3,0.),1e-12)) - self.assertTrue(a1.isEqual(DataArrayByte([5,5,5,5,5,5,9,9,9,9,9]))) - self.assertTrue(a2.isEqual(DataArrayInt([0,4,8,12,16,20,24,29,34,39,44]))) - self.assertTrue(a3.isEqual(DataArrayInt([3,2,7,3,3,7,8,3,3,3,8,4,3,8,9,4,3,13,9,8,3,13,14,9,4,0,5,6,1,4,1,6,7,2,4,5,10,11,6,4,6,11,12,7,4,12,13,8,7]))) - self.assertTrue(a4 is None) - self.assertTrue(a5 is None) - for i in xrange(1,5): - self.assertTrue((fcscp.isDataSetSupportEqualToThePreviousOne(i,fields))) - pass - for i in xrange(5): - f=allFMTSLeavesPerCommonSupport[0][0][0][i] - fsst=MEDFileField1TSStructItem.BuildItemFrom(f,mst) - f.loadArraysIfNecessary() - v=mml.buildDataArray(fsst,fields,f.getUndergroundDataArray()) - self.assertEqual(f.getName(),fieldName0) - self.assertEqual(v.getHiddenCppPointer(),f.getUndergroundDataArray().getHiddenCppPointer()) - vExp=DataArrayDouble(38*2) ; vExp.iota(0+i*1000) ; vExp.rearrange(2) ; vExp.setInfoOnComponents(['Comp1_0 [m]','Com2_0 [s^2]']) - self.assertTrue(v.isEqual(vExp,1e-12)) - # - f=allFMTSLeavesPerCommonSupport[0][0][1][i] - fsst=MEDFileField1TSStructItem.BuildItemFrom(f,mst) - f.loadArraysIfNecessary() - v=mml.buildDataArray(fsst,fields,f.getUndergroundDataArray()) - self.assertEqual(f.getName(),fieldName1) - self.assertEqual(v.getHiddenCppPointer(),f.getUndergroundDataArray().getHiddenCppPointer()) - vExp=DataArrayDouble(11*2) ; vExp.iota(100+i*1000) ; vExp.rearrange(2) ; vExp.setInfoOnComponents(['Comp1_1 [m]','Com2_1 [s^2]']) - self.assertTrue(v.isEqual(vExp,1e-12)) - # - f=allFMTSLeavesPerCommonSupport[0][0][2][i] - fsst=MEDFileField1TSStructItem.BuildItemFrom(f,mst) - f.loadArraysIfNecessary() - v=mml.buildDataArray(fsst,fields,f.getUndergroundDataArray()) - self.assertEqual(f.getName(),fieldName2) - #self.assertEqual(v.getHiddenCppPointer(),f.getUndergroundDataArray().getHiddenCppPointer()) # not a bug - vExp=DataArrayDouble(44*2) ; vExp.iota(300+i*1000) ; vExp.rearrange(2) ; vExp.setInfoOnComponents(['Comp1_2 [m]','Com2_2 [s^2]']) - self.assertTrue(v.isEqual(vExp,1e-12)) - # - f=allFMTSLeavesPerCommonSupport[0][0][3][i] - fsst=MEDFileField1TSStructItem.BuildItemFrom(f,mst) - f.loadArraysIfNecessary() - v=mml.buildDataArray(fsst,fields,f.getUndergroundDataArray()) - self.assertEqual(f.getName(),fieldName3) - self.assertEqual(v.getHiddenCppPointer(),f.getUndergroundDataArray().getHiddenCppPointer()) - vExp=DataArrayDouble(15*2) ; vExp.iota(400+i*1000) ; vExp.rearrange(2) ; vExp.setInfoOnComponents(['Comp1_3 [m]','Com2_3 [s^2]']) - self.assertTrue(v.isEqual(vExp,1e-12)) - pass - # - pass - - def test9(self): - """ This test plays with with gauss fields with profiles. - """ - fname="ForMEDReader9.med" - # building a mesh containing 6 tri3 + 5 quad4 - m=MEDCouplingUMesh("mesh",2) - coords=DataArrayDouble([(0,0),(1,0),(2,0),(3,0),(4,0),(0,1),(1,1),(2,1),(3,1),(4,1),(0,2),(1,2),(2,2),(3,2),(4,2)]) ; coords.setInfoOnComponents(["XX [m]","YYY [km]"]) - m.setCoords(coords) - m.allocateCells() - m.insertNextCell(NORM_TRI3,[2,7,3]) ; m.insertNextCell(NORM_TRI3,[7,8,3]) ; m.insertNextCell(NORM_TRI3,[3,8,4]) ; m.insertNextCell(NORM_TRI3,[8,9,4]) - m.insertNextCell(NORM_TRI3,[13,9,8]) ; m.insertNextCell(NORM_TRI3,[13,14,9]) - m.insertNextCell(NORM_QUAD4,[0,5,6,1]) ; m.insertNextCell(NORM_QUAD4,[1,6,7,2]) ; m.insertNextCell(NORM_QUAD4,[5,10,11,6]) ; m.insertNextCell(NORM_QUAD4,[6,11,12,7]) - m.insertNextCell(NORM_QUAD4,[12,13,8,7]) - mm=MEDFileUMesh() ; mm.setMeshes([m]) - # - fieldName0="zeField0" - fieldName1="zeField1" - fieldName2="zeField2" - fieldName3="zeField3" - pfl1=DataArrayInt([0,1,7,9,10]) ; pfl1.setName("pfl1") # on cells - pfl2=DataArrayInt([1,2,3,6,7,8,11,12,13]) ; pfl2.setName("pfl2") # on nodes - fs0=MEDFileFieldMultiTS() ; fs1=MEDFileFieldMultiTS() ; fs2=MEDFileFieldMultiTS() ; fs3=MEDFileFieldMultiTS() - for i in xrange(5): - f=MEDFileField1TS() - fNode=MEDCouplingFieldDouble(ON_GAUSS_NE) ; fNode.setTime(float(i),i,0) - fNode.setName(fieldName0) - arr=DataArrayDouble(2*18) ; arr.iota(0+1000*i) ; arr.rearrange(2) - fNode.setArray(arr) ; arr.setInfoOnComponents(["Comp1_0 [m]","Com2_0 [s^2]"]) - f.setFieldProfile(fNode,mm,0,pfl1) - fs0.pushBackTimeStep(f) - # - f=MEDFileField1TS() - fNode=MEDCouplingFieldDouble(ON_CELLS) ; fNode.setTime(float(i),i,0) - fNode.setName(fieldName1) - arr=DataArrayDouble(2*5) ; arr.iota(100+1000*i) ; arr.rearrange(2) - fNode.setArray(arr) ; arr.setInfoOnComponents(["Comp1_1 [m]","Com2_1 [s^2]"]) - f.setFieldProfile(fNode,mm,0,pfl1) - fs1.pushBackTimeStep(f) - # - f=MEDFileField1TS() - fNode=MEDCouplingFieldDouble(ON_GAUSS_PT) ; fNode.setTime(float(i),i,0) - fNode.setName(fieldName2) ; fNode.setMesh(m[pfl1]) - fNode.setGaussLocalizationOnCells([0],[0.,0.,1.,0.,0.,1.],[0.5,0.5,0.7,0.7],[0.8,0.2]) - fNode.setGaussLocalizationOnCells([1],[0.,0.,1.,0.,0.,1.],[0.5,0.5,0.7,0.7,0.1,0.1,0.2,0.2,0.3,0.3],[0.8,0.05,0.1,0.04,0.01]) - fNode.setGaussLocalizationOnCells([2,3],[-1.,-1.,1.,-1.,1.,1.,-1.,1.],[0.5,0.5,0.7,0.7,0.1,0.1,0.2,0.2],[0.8,0.05,0.1,0.04]) - fNode.setGaussLocalizationOnCells([4],[-1.,-1.,1.,-1.,1.,1.,-1.,1.],[0.5,0.5,0.7,0.7,0.1,0.1,0.2,0.2,0.3,0.3,0.4,0.4,0.8,0.8],[0.8,0.05,0.1,0.01,0.02,0.005,0.005]) - arr=DataArrayDouble(2*(2*1+5*1+4*2+7*1)) ; arr.iota(300+1000*i) ; arr.rearrange(2) - fNode.setArray(arr) ; arr.setInfoOnComponents(["Comp1_2 [m]","Com2_2 [s^2]"]) ; fNode.checkCoherency() - f.setFieldProfile(fNode,mm,0,pfl1) - fs2.pushBackTimeStep(f) - # - f=MEDFileField1TS() - fNode=MEDCouplingFieldDouble(ON_NODES) ; fNode.setTime(float(i),i,0) - fNode.setName(fieldName3) - arr=DataArrayDouble(2*9) ; arr.iota(400+1000*i) ; arr.rearrange(2) - fNode.setArray(arr) ; arr.setInfoOnComponents(["Comp1_3 [m]","Com2_3 [s^2]"]) - f.setFieldProfile(fNode,mm,0,pfl2) - fs3.pushBackTimeStep(f) - # - pass - # - mm.write(fname,2) - fs0.write(fname,0) ; fs1.write(fname,0) ; fs2.write(fname,0) ; fs3.write(fname,0) - a0Exp=mm.getCoords().deepCpy() - del m,mm,fs1,fs2,fs3,f,fNode - ########## GO for reading in MEDReader,by not loading all. Mesh is fully loaded but not fields values - ms=MEDFileMeshes(fname) - fields=MEDFileFields(fname,False) - fields.removeFieldsWithoutAnyTimeStep() - fields_per_mesh=[fields.partOfThisLyingOnSpecifiedMeshName(meshName) for meshName in ms.getMeshesNames()] - allFMTSLeavesToDisplay=[] - for fields in fields_per_mesh: - allFMTSLeavesToDisplay2=[] - for fmts in fields: - tmp=fmts.splitDiscretizations() - #for itmp in tmp: - # self.assertTrue(not itmp.presenceOfMultiDiscPerGeoType()) - # pass - allFMTSLeavesToDisplay2+=tmp - pass - allFMTSLeavesToDisplay.append(allFMTSLeavesToDisplay2) - pass - self.assertEqual(len(allFMTSLeavesToDisplay),1) - self.assertEqual(len(allFMTSLeavesToDisplay[0]),4) - allFMTSLeavesPerTimeSeries=MEDFileAnyTypeFieldMultiTS.SplitIntoCommonTimeSeries(sum(allFMTSLeavesToDisplay,[])) - self.assertEqual(len(allFMTSLeavesPerTimeSeries),1) # one time serie here : because the 4 fields are defined on the same time steps - self.assertEqual(len(allFMTSLeavesPerTimeSeries[0]),4) - allFMTSLeavesPerCommonSupport=MEDFileAnyTypeFieldMultiTS.SplitPerCommonSupport(allFMTSLeavesPerTimeSeries[0],ms[ms.getMeshesNames()[0]]) - self.assertEqual(len(allFMTSLeavesPerCommonSupport),1) - self.assertEqual(len(allFMTSLeavesPerCommonSupport[0][0]),4) - # - mst=MEDFileMeshStruct.New(ms[0]) - # - fcscp=allFMTSLeavesPerCommonSupport[0][1] - mml=fcscp.buildFromScratchDataSetSupport(0,fields) - mml2=mml.prepare() - self.assertTrue(isinstance(mml2,MEDUMeshMultiLev)) - ncc,a0,a1,a2,a3,a4,a5=mml2.buildVTUArrays() - self.assertTrue(not ncc) - self.assertTrue(a0.isEqual(a0Exp[pfl2].changeNbOfComponents(3,0.),1e-12)) - self.assertTrue(a1.isEqual(DataArrayByte([5,5,9,9,9]))) - self.assertTrue(a2.isEqual(DataArrayInt([0,4,8,13,18]))) - self.assertTrue(a3.isEqual(DataArrayInt([3,1,4,2,3,4,5,2,4,0,3,4,1,4,3,6,7,4,4,7,8,5,4]))) - self.assertTrue(a4 is None) - self.assertTrue(a5 is None) - for i in xrange(1,5): - self.assertTrue((fcscp.isDataSetSupportEqualToThePreviousOne(i,fields))) - pass - for i in xrange(5): - f=allFMTSLeavesPerCommonSupport[0][0][0][i] - fsst=MEDFileField1TSStructItem.BuildItemFrom(f,mst) - f.loadArraysIfNecessary() - v=mml.buildDataArray(fsst,fields,f.getUndergroundDataArray()) - self.assertEqual(f.getName(),fieldName0) - self.assertEqual(v.getHiddenCppPointer(),f.getUndergroundDataArray().getHiddenCppPointer()) - vExp=DataArrayDouble(18*2) ; vExp.iota(0+i*1000) ; vExp.rearrange(2) ; vExp.setInfoOnComponents(['Comp1_0 [m]','Com2_0 [s^2]']) - self.assertTrue(v.isEqual(vExp,1e-12)) - # - f=allFMTSLeavesPerCommonSupport[0][0][1][i] - fsst=MEDFileField1TSStructItem.BuildItemFrom(f,mst) - f.loadArraysIfNecessary() - v=mml.buildDataArray(fsst,fields,f.getUndergroundDataArray()) - self.assertEqual(f.getName(),fieldName1) - self.assertEqual(v.getHiddenCppPointer(),f.getUndergroundDataArray().getHiddenCppPointer()) - vExp=DataArrayDouble(5*2) ; vExp.iota(100+i*1000) ; vExp.rearrange(2) ; vExp.setInfoOnComponents(['Comp1_1 [m]','Com2_1 [s^2]']) - self.assertTrue(v.isEqual(vExp,1e-12)) - # - f=allFMTSLeavesPerCommonSupport[0][0][2][i] - fsst=MEDFileField1TSStructItem.BuildItemFrom(f,mst) - f.loadArraysIfNecessary() - v=mml.buildDataArray(fsst,fields,f.getUndergroundDataArray()) - self.assertEqual(f.getName(),fieldName2) - #self.assertEqual(v.getHiddenCppPointer(),f.getUndergroundDataArray().getHiddenCppPointer()) # not a bug - vExp=DataArrayDouble(22*2) ; vExp.iota(300+i*1000) ; vExp.rearrange(2) ; vExp.setInfoOnComponents(['Comp1_2 [m]','Com2_2 [s^2]']) - self.assertTrue(v.isEqual(vExp,1e-12)) - # - f=allFMTSLeavesPerCommonSupport[0][0][3][i] - fsst=MEDFileField1TSStructItem.BuildItemFrom(f,mst) - f.loadArraysIfNecessary() - v=mml.buildDataArray(fsst,fields,f.getUndergroundDataArray()) - self.assertEqual(f.getName(),fieldName3) - self.assertEqual(v.getHiddenCppPointer(),f.getUndergroundDataArray().getHiddenCppPointer()) - vExp=DataArrayDouble(9*2) ; vExp.iota(400+i*1000) ; vExp.rearrange(2) ; vExp.setInfoOnComponents(['Comp1_3 [m]','Com2_3 [s^2]']) - self.assertTrue(v.isEqual(vExp,1e-12)) - pass - pass - - def test10(self): - """ This test plays with fields only on nodes containing profiles. - """ - fname="ForMEDReader10.med" - # building a mesh containing 6 tri3 + 5 quad4 - m=MEDCouplingUMesh("mesh",2) - coords=DataArrayDouble([(0,0),(1,0),(2,0),(3,0),(4,0),(0,1),(1,1),(2,1),(3,1),(4,1),(0,2),(1,2),(2,2),(3,2),(4,2)]) ; coords.setInfoOnComponents(["XX [m]","YYY [km]"]) - m.setCoords(coords) - m.allocateCells() - m.insertNextCell(NORM_TRI3,[2,7,3]) ; m.insertNextCell(NORM_TRI3,[7,8,3]) ; m.insertNextCell(NORM_TRI3,[3,8,4]) ; m.insertNextCell(NORM_TRI3,[8,9,4]) - m.insertNextCell(NORM_TRI3,[13,9,8]) ; m.insertNextCell(NORM_TRI3,[13,14,9]) - m.insertNextCell(NORM_QUAD4,[0,5,6,1]) ; m.insertNextCell(NORM_QUAD4,[1,6,7,2]) ; m.insertNextCell(NORM_QUAD4,[5,10,11,6]) ; m.insertNextCell(NORM_QUAD4,[6,11,12,7]) - m.insertNextCell(NORM_QUAD4,[12,13,8,7]) - mm=MEDFileUMesh() ; mm.setMeshes([m]) - # - fieldName0="zeField0" - fieldName1="zeField1" - fieldName2="zeField2" - pfl1=DataArrayInt([1,2,3,6,7,8,11,12,13]) ; pfl1.setName("pfl1") # on nodes - fs0=MEDFileFieldMultiTS() ; fs1=MEDFileFieldMultiTS() ; fs2=MEDFileFieldMultiTS() - for i in xrange(5): - f=MEDFileField1TS() - fNode=MEDCouplingFieldDouble(ON_NODES) ; fNode.setTime(float(i),i,0) - fNode.setName(fieldName0) - arr=DataArrayDouble(2*9) ; arr.iota(0+1000*i) ; arr.rearrange(2) - fNode.setArray(arr) ; arr.setInfoOnComponents(["Comp1_0 [m]","Com2_0 [s^2]"]) - f.setFieldProfile(fNode,mm,0,pfl1) - fs0.pushBackTimeStep(f) - # - f=MEDFileField1TS() - fNode=MEDCouplingFieldDouble(ON_NODES) ; fNode.setTime(float(i),i,0) - fNode.setName(fieldName1) - arr=DataArrayDouble(2*9) ; arr.iota(100+1000*i) ; arr.rearrange(2) - fNode.setArray(arr) ; arr.setInfoOnComponents(["Comp1_1 [m]","Com2_1 [s^2]"]) - f.setFieldProfile(fNode,mm,0,pfl1) - fs1.pushBackTimeStep(f) - # - f=MEDFileField1TS() - fNode=MEDCouplingFieldDouble(ON_NODES) ; fNode.setTime(float(i),i,0) - fNode.setName(fieldName2) - arr=DataArrayDouble(2*9) ; arr.iota(200+1000*i) ; arr.rearrange(2) - fNode.setArray(arr) ; arr.setInfoOnComponents(["Comp1_2 [m]","Com2_2 [s^2]"]) - f.setFieldProfile(fNode,mm,0,pfl1) - fs2.pushBackTimeStep(f) - # - pass - # - mm.write(fname,2) - fs0.write(fname,0) ; fs1.write(fname,0) ; fs2.write(fname,0) - a0Exp=mm.getCoords().deepCpy() - del m,mm,fs1,fs2,f,fNode - ########## GO for reading in MEDReader,by not loading all. Mesh is fully loaded but not fields values - ms=MEDFileMeshes(fname) - fields=MEDFileFields(fname,False) - fields.removeFieldsWithoutAnyTimeStep() - fields_per_mesh=[fields.partOfThisLyingOnSpecifiedMeshName(meshName) for meshName in ms.getMeshesNames()] - allFMTSLeavesToDisplay=[] - for fields in fields_per_mesh: - allFMTSLeavesToDisplay2=[] - for fmts in fields: - tmp=fmts.splitDiscretizations() - for itmp in tmp: - self.assertTrue(not itmp.presenceOfMultiDiscPerGeoType()) - pass - allFMTSLeavesToDisplay2+=tmp - pass - allFMTSLeavesToDisplay.append(allFMTSLeavesToDisplay2) - pass - self.assertEqual(len(allFMTSLeavesToDisplay),1) - self.assertEqual(len(allFMTSLeavesToDisplay[0]),3) - allFMTSLeavesPerTimeSeries=MEDFileAnyTypeFieldMultiTS.SplitIntoCommonTimeSeries(sum(allFMTSLeavesToDisplay,[])) - self.assertEqual(len(allFMTSLeavesPerTimeSeries),1) # one time serie here : because the 4 fields are defined on the same time steps - self.assertEqual(len(allFMTSLeavesPerTimeSeries[0]),3) - allFMTSLeavesPerCommonSupport=MEDFileAnyTypeFieldMultiTS.SplitPerCommonSupport(allFMTSLeavesPerTimeSeries[0],ms[ms.getMeshesNames()[0]]) - self.assertEqual(len(allFMTSLeavesPerCommonSupport),1) - self.assertEqual(len(allFMTSLeavesPerCommonSupport[0][0]),3) - # - mst=MEDFileMeshStruct.New(ms[0]) - # - fcscp=allFMTSLeavesPerCommonSupport[0][1] - mml=fcscp.buildFromScratchDataSetSupport(0,fields) - mml2=mml.prepare() - self.assertTrue(isinstance(mml2,MEDUMeshMultiLev)) - ncc,a0,a1,a2,a3,a4,a5=mml2.buildVTUArrays() - self.assertTrue(not ncc) - self.assertTrue(a0.isEqual(a0Exp[pfl1].changeNbOfComponents(3,0.),1e-12)) - self.assertTrue(a1.isEqual(DataArrayByte([5,5,9,9,9]))) - self.assertTrue(a2.isEqual(DataArrayInt([0,4,8,13,18]))) - self.assertTrue(a3.isEqual(DataArrayInt([3,1,4,2,3,4,5,2,4,0,3,4,1,4,3,6,7,4,4,7,8,5,4]))) - self.assertTrue(a4 is None) - self.assertTrue(a5 is None) - for i in xrange(1,5): - self.assertTrue((fcscp.isDataSetSupportEqualToThePreviousOne(i,fields))) - pass - for i in xrange(5): - f=allFMTSLeavesPerCommonSupport[0][0][0][i] - fsst=MEDFileField1TSStructItem.BuildItemFrom(f,mst) - f.loadArraysIfNecessary() - v=mml.buildDataArray(fsst,fields,f.getUndergroundDataArray()) - self.assertEqual(f.getName(),fieldName0) - #self.assertEqual(v.getHiddenCppPointer(),f.getUndergroundDataArray().getHiddenCppPointer()) # not a bug - vExp=DataArrayDouble(9*2) ; vExp.iota(0+i*1000) ; vExp.rearrange(2) ; vExp.setInfoOnComponents(['Comp1_0 [m]','Com2_0 [s^2]']) - self.assertTrue(v.isEqual(vExp,1e-12)) - # - f=allFMTSLeavesPerCommonSupport[0][0][1][i] - fsst=MEDFileField1TSStructItem.BuildItemFrom(f,mst) - f.loadArraysIfNecessary() - v=mml.buildDataArray(fsst,fields,f.getUndergroundDataArray()) - self.assertEqual(f.getName(),fieldName1) - #self.assertEqual(v.getHiddenCppPointer(),f.getUndergroundDataArray().getHiddenCppPointer()) # not a bug - vExp=DataArrayDouble(9*2) ; vExp.iota(100+i*1000) ; vExp.rearrange(2) ; vExp.setInfoOnComponents(['Comp1_1 [m]','Com2_1 [s^2]']) - self.assertTrue(v.isEqual(vExp,1e-12)) - # - f=allFMTSLeavesPerCommonSupport[0][0][2][i] - fsst=MEDFileField1TSStructItem.BuildItemFrom(f,mst) - f.loadArraysIfNecessary() - v=mml.buildDataArray(fsst,fields,f.getUndergroundDataArray()) - self.assertEqual(f.getName(),fieldName2) - #self.assertEqual(v.getHiddenCppPointer(),f.getUndergroundDataArray().getHiddenCppPointer()) # not a bug - vExp=DataArrayDouble(9*2) ; vExp.iota(200+i*1000) ; vExp.rearrange(2) ; vExp.setInfoOnComponents(['Comp1_2 [m]','Com2_2 [s^2]']) - self.assertTrue(v.isEqual(vExp,1e-12)) - pass - pass - - def test11(self): - """ This test is the ultimate test for the profiles with gauss points. It tests that even if there is non contiguous parts in definition of gauss points, it works ! - WARNING here, as no other discretizations exists, the priority is given to the field -> the mesh is renumbered to accelerate the build of array of field. - """ - fname="ForMEDReader11.med" - m=MEDCouplingCMesh("mesh") - arr=DataArrayDouble(5) ; arr.iota() - m.setCoords(arr,arr) - m=m.buildUnstructured() ; m.getCoords().setInfoOnComponents(["XX [m]","YYY [km]"]) - mm=MEDFileUMesh() ; mm.setMeshes([m]) - # - fieldName0="zeField0" - fs0=MEDFileFieldMultiTS() - for i in xrange(5): - f=MEDFileField1TS() - fNode=MEDCouplingFieldDouble(ON_GAUSS_PT) ; fNode.setTime(float(i),i,0) - fNode.setName(fieldName0) ; fNode.setMesh(m) - fNode.setGaussLocalizationOnCells([0,2,3,4,7,15],[-1.,-1.,1.,-1.,1.,1.,-1.,1.],[0.5,0.5,0.7,0.7],[0.8,0.2]) - fNode.setGaussLocalizationOnCells([1,5,8,9],[-1.,-1.,1.,-1.,1.,1.,-1.,1.],[0.5,0.5,0.7,0.7,0.1,0.1,0.2,0.2,0.3,0.3],[0.8,0.05,0.1,0.04,0.01]) - fNode.setGaussLocalizationOnCells([6,10,13],[-1.,-1.,1.,-1.,1.,1.,-1.,1.],[0.5,0.5,0.7,0.7,0.1,0.1,0.2,0.2],[0.8,0.05,0.1,0.04]) - fNode.setGaussLocalizationOnCells([11,12,14],[-1.,-1.,1.,-1.,1.,1.,-1.,1.],[0.5,0.5,0.7,0.7,0.1,0.1,0.2,0.2,0.3,0.3,0.4,0.4,0.8,0.8],[0.8,0.05,0.1,0.01,0.02,0.005,0.005]) - arr=DataArrayDouble(2*(2*6+5*4+4*3+7*3)) ; arr.iota(0+1000*i) ; arr.rearrange(2) - fNode.setArray(arr) ; arr.setInfoOnComponents(["Comp1_0 [m]","Com2_0 [s^2]"]) ; fNode.checkCoherency() - f.setFieldNoProfileSBT(fNode) - fs0.pushBackTimeStep(f) - pass - mm.write(fname,2) - fs0.write(fname,0) - a0Exp=mm.getCoords().deepCpy() - del m,mm,fs0,f,fNode - ########## GO for reading in MEDReader,by not loading all. Mesh is fully loaded but not fields values - ms=MEDFileMeshes(fname) - fields=MEDFileFields(fname,False) - fields.removeFieldsWithoutAnyTimeStep() - fields_per_mesh=[fields.partOfThisLyingOnSpecifiedMeshName(meshName) for meshName in ms.getMeshesNames()] - allFMTSLeavesToDisplay=[] - for fields in fields_per_mesh: - allFMTSLeavesToDisplay2=[] - for fmts in fields: - tmp=fmts.splitDiscretizations() - #for itmp in tmp: - # self.assertTrue(not itmp.presenceOfMultiDiscPerGeoType()) - # pass - allFMTSLeavesToDisplay2+=tmp - pass - allFMTSLeavesToDisplay.append(allFMTSLeavesToDisplay2) - pass - self.assertEqual(len(allFMTSLeavesToDisplay),1) - self.assertEqual(len(allFMTSLeavesToDisplay[0]),1) - allFMTSLeavesPerTimeSeries=MEDFileAnyTypeFieldMultiTS.SplitIntoCommonTimeSeries(sum(allFMTSLeavesToDisplay,[])) - self.assertEqual(len(allFMTSLeavesPerTimeSeries),1) # one time serie here : because the 1 field is defined on the same time steps - self.assertEqual(len(allFMTSLeavesPerTimeSeries[0]),1) - allFMTSLeavesPerCommonSupport=MEDFileAnyTypeFieldMultiTS.SplitPerCommonSupport(allFMTSLeavesPerTimeSeries[0],ms[ms.getMeshesNames()[0]]) - self.assertEqual(len(allFMTSLeavesPerCommonSupport),1) - self.assertEqual(len(allFMTSLeavesPerCommonSupport[0][0]),1) - # - mst=MEDFileMeshStruct.New(ms[0]) - # - fcscp=allFMTSLeavesPerCommonSupport[0][1] - mml=fcscp.buildFromScratchDataSetSupport(0,fields) - mml2=mml.prepare() - self.assertTrue(isinstance(mml2,MEDUMeshMultiLev)) - ncc,a0,a1,a2,a3,a4,a5=mml2.buildVTUArrays() - self.assertTrue(not ncc) - self.assertTrue(a0.isEqual(a0Exp.changeNbOfComponents(3,0.),1e-12)) - self.assertTrue(a1.isEqual(DataArrayByte([9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9]))) - self.assertTrue(a2.isEqual(DataArrayInt([0,5,10,15,20,25,30,35,40,45,50,55,60,65,70,75]))) - self.assertTrue(a3.isEqual(DataArrayInt([4,1,0,5,6,4,3,2,7,8,4,4,3,8,9,4,6,5,10,11,4,9,8,13,14,4,19,18,23,24,4,2,1,6,7,4,7,6,11,12,4,11,10,15,16,4,12,11,16,17,4,8,7,12,13,4,13,12,17,18,4,17,16,21,22,4,14,13,18,19,4,16,15,20,21,4,18,17,22,23]))) # <- here the mesh is renumbered : the mesh is equal to m[[0,2,3,4,7,15, 1,5,8,9, 6,10,13, 11,12,14]] - self.assertTrue(a4 is None) - self.assertTrue(a5 is None) - for i in xrange(1,5): - self.assertTrue((fcscp.isDataSetSupportEqualToThePreviousOne(i,fields))) - pass - for i in xrange(5): - f=allFMTSLeavesPerCommonSupport[0][0][0][i] - fsst=MEDFileField1TSStructItem.BuildItemFrom(f,mst) - f.loadArraysIfNecessary() - v=mml.buildDataArray(fsst,fields,f.getUndergroundDataArray()) - self.assertEqual(f.getName(),fieldName0) - self.assertEqual(v.getHiddenCppPointer(),f.getUndergroundDataArray().getHiddenCppPointer()) - vExp=DataArrayDouble([0.,1.,2.,3.,14.,15.,16.,17.,18.,19.,20.,21.,22.,23.,24.,25.,44.,45.,46.,47.,126.,127.,128.,129.,4.,5.,6.,7.,8.,9.,10.,11.,12.,13.,26.,27.,28.,29.,30.,31.,32.,33.,34.,35.,48.,49.,50.,51.,52.,53.,54.,55.,56.,57.,58.,59.,60.,61.,62.,63.,64.,65.,66.,67.,36.,37.,38.,39.,40.,41.,42.,43.,68.,69.,70.,71.,72.,73.,74.,75.,104.,105.,106.,107.,108.,109.,110.,111.,76.,77.,78.,79.,80.,81.,82.,83.,84.,85.,86.,87.,88.,89.,90.,91.,92.,93.,94.,95.,96.,97.,98.,99.,100.,101.,102.,103.,112.,113.,114.,115.,116.,117.,118.,119.,120.,121.,122.,123.,124.,125.],65,2) ; vExp.setInfoOnComponents(['Comp1_0 [m]','Com2_0 [s^2]']) - vExp+=i*1000 - self.assertTrue(v.isEqual(vExp,1e-12)) - pass - pass - - def test12(self): - """ This test is the second ultimate test for the profiles with gauss points. - This test is close to test11 but here a 2nd field on cells without profile. So here the mesh is expected to be the same than m. - """ - fname="ForMEDReader12.med" - m=MEDCouplingCMesh("mesh") - arr=DataArrayDouble(5) ; arr.iota() - m.setCoords(arr,arr) - m=m.buildUnstructured() ; m.getCoords().setInfoOnComponents(["XX [m]","YYY [km]"]) - mm=MEDFileUMesh() ; mm.setMeshes([m]) - # - fieldName0="zeField0" - fieldName1="zeField1" - fs0=MEDFileFieldMultiTS() ; fs1=MEDFileFieldMultiTS() - for i in xrange(5): - f=MEDFileField1TS() - fNode=MEDCouplingFieldDouble(ON_GAUSS_PT) ; fNode.setTime(float(i),i,0) - fNode.setName(fieldName0) ; fNode.setMesh(m) - fNode.setGaussLocalizationOnCells([0,2,3,4,7,15],[-1.,-1.,1.,-1.,1.,1.,-1.,1.],[0.5,0.5,0.7,0.7],[0.8,0.2]) - fNode.setGaussLocalizationOnCells([1,5,8,9],[-1.,-1.,1.,-1.,1.,1.,-1.,1.],[0.5,0.5,0.7,0.7,0.1,0.1,0.2,0.2,0.3,0.3],[0.8,0.05,0.1,0.04,0.01]) - fNode.setGaussLocalizationOnCells([6,10,13],[-1.,-1.,1.,-1.,1.,1.,-1.,1.],[0.5,0.5,0.7,0.7,0.1,0.1,0.2,0.2],[0.8,0.05,0.1,0.04]) - fNode.setGaussLocalizationOnCells([11,12,14],[-1.,-1.,1.,-1.,1.,1.,-1.,1.],[0.5,0.5,0.7,0.7,0.1,0.1,0.2,0.2,0.3,0.3,0.4,0.4,0.8,0.8],[0.8,0.05,0.1,0.01,0.02,0.005,0.005]) - arr=DataArrayDouble(2*(2*6+5*4+4*3+7*3)) ; arr.iota(0+1000*i) ; arr.rearrange(2) - fNode.setArray(arr) ; arr.setInfoOnComponents(["Comp1_0 [m]","Com2_0 [s^2]"]) ; fNode.checkCoherency() - f.setFieldNoProfileSBT(fNode) - fs0.pushBackTimeStep(f) - # - f=MEDFileField1TS() - fNode=MEDCouplingFieldDouble(ON_CELLS) ; fNode.setTime(float(i),i,0) - fNode.setName(fieldName1) ; fNode.setMesh(m) - arr=DataArrayDouble(2*16) ; arr.iota(300+1000*i) ; arr.rearrange(2) - fNode.setArray(arr) ; arr.setInfoOnComponents(["Comp1_1 [m]","Com2_1 [s^2]"]) ; fNode.checkCoherency() - f.setFieldNoProfileSBT(fNode) - fs1.pushBackTimeStep(f) - pass - mm.write(fname,2) - fs0.write(fname,0) ; fs1.write(fname,0) - a0Exp=mm.getCoords().deepCpy() - del m,mm,fs0,fs1,f,fNode - ########## GO for reading in MEDReader,by not loading all. Mesh is fully loaded but not fields values - ms=MEDFileMeshes(fname) - fields=MEDFileFields(fname,False) - fields.removeFieldsWithoutAnyTimeStep() - fields_per_mesh=[fields.partOfThisLyingOnSpecifiedMeshName(meshName) for meshName in ms.getMeshesNames()] - allFMTSLeavesToDisplay=[] - for fields in fields_per_mesh: - allFMTSLeavesToDisplay2=[] - for fmts in fields: - tmp=fmts.splitDiscretizations() - #for itmp in tmp: - # self.assertTrue(not itmp.presenceOfMultiDiscPerGeoType()) - # pass - allFMTSLeavesToDisplay2+=tmp - pass - allFMTSLeavesToDisplay.append(allFMTSLeavesToDisplay2) - pass - self.assertEqual(len(allFMTSLeavesToDisplay),1) - self.assertEqual(len(allFMTSLeavesToDisplay[0]),2) - allFMTSLeavesPerTimeSeries=MEDFileAnyTypeFieldMultiTS.SplitIntoCommonTimeSeries(sum(allFMTSLeavesToDisplay,[])) - self.assertEqual(len(allFMTSLeavesPerTimeSeries),1) # one time serie here : because the 2 fields are defined on the same time steps - self.assertEqual(len(allFMTSLeavesPerTimeSeries[0]),2) - allFMTSLeavesPerCommonSupport=MEDFileAnyTypeFieldMultiTS.SplitPerCommonSupport(allFMTSLeavesPerTimeSeries[0],ms[ms.getMeshesNames()[0]]) - self.assertEqual(len(allFMTSLeavesPerCommonSupport),1) - self.assertEqual(len(allFMTSLeavesPerCommonSupport[0][0]),2) - # - mst=MEDFileMeshStruct.New(ms[0]) - # - fcscp=allFMTSLeavesPerCommonSupport[0][1] - mml=fcscp.buildFromScratchDataSetSupport(0,fields) - mml2=mml.prepare() - self.assertTrue(isinstance(mml2,MEDUMeshMultiLev)) - ncc,a0,a1,a2,a3,a4,a5=mml2.buildVTUArrays() - self.assertTrue(not ncc) - self.assertTrue(a0.isEqual(a0Exp.changeNbOfComponents(3,0.),1e-12)) - self.assertTrue(a1.isEqual(DataArrayByte([9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9]))) - self.assertTrue(a2.isEqual(DataArrayInt([0,5,10,15,20,25,30,35,40,45,50,55,60,65,70,75]))) - self.assertTrue(a3.isEqual(DataArrayInt([4,1,0,5,6,4,2,1,6,7,4,3,2,7,8,4,4,3,8,9,4,6,5,10,11,4,7,6,11,12,4,8,7,12,13,4,9,8,13,14,4,11,10,15,16,4,12,11,16,17,4,13,12,17,18,4,14,13,18,19,4,16,15,20,21,4,17,16,21,22,4,18,17,22,23,4,19,18,23,24]))) # <- here the mesh is NOT renumbered : the mesh is equal to m - self.assertTrue(a4 is None) - self.assertTrue(a5 is None) - for i in xrange(1,5): - self.assertTrue((fcscp.isDataSetSupportEqualToThePreviousOne(i,fields))) - pass - for i in xrange(5): - f=allFMTSLeavesPerCommonSupport[0][0][0][i] - fsst=MEDFileField1TSStructItem.BuildItemFrom(f,mst) - f.loadArraysIfNecessary() - v=mml.buildDataArray(fsst,fields,f.getUndergroundDataArray()) - self.assertEqual(f.getName(),fieldName0) - #self.assertEqual(v.getHiddenCppPointer(),f.getUndergroundDataArray().getHiddenCppPointer()) # not a bug : huge reordering performed ! - vExp=DataArrayDouble(65*2) ; vExp.iota(0+i*1000) ; vExp.rearrange(2) ; vExp.setInfoOnComponents(['Comp1_0 [m]','Com2_0 [s^2]']) - self.assertTrue(v.isEqual(vExp,1e-12)) - # - f=allFMTSLeavesPerCommonSupport[0][0][1][i] - fsst=MEDFileField1TSStructItem.BuildItemFrom(f,mst) - f.loadArraysIfNecessary() - v=mml.buildDataArray(fsst,fields,f.getUndergroundDataArray()) - self.assertEqual(f.getName(),fieldName1) - self.assertEqual(v.getHiddenCppPointer(),f.getUndergroundDataArray().getHiddenCppPointer()) # not a bug : huge reordering performed ! - vExp=DataArrayDouble(16*2) ; vExp.iota(300+i*1000) ; vExp.rearrange(2) ; vExp.setInfoOnComponents(['Comp1_1 [m]','Com2_1 [s^2]']) - self.assertTrue(v.isEqual(vExp,1e-12)) - pass - - def test13(self): - """ Testing polyhedrons mixed with hexa8""" - fname="ForMEDReader13.med" - m=MEDCouplingUMesh("mesh",3) - m.allocateCells() - m.insertNextCell(NORM_HEXA8,[1,0,6,7,13,12,18,19]) ; m.insertNextCell(NORM_HEXA8,[2,1,7,8,14,13,19,20]) - m.insertNextCell(NORM_POLYHED,[3,2,8,9,-1,15,21,20,14,-1,3,15,14,2,-1,2,14,20,8,-1,8,20,21,9,-1,9,21,15,3]) - m.insertNextCell(NORM_POLYHED,[4,3,9,10,-1,16,22,21,15,-1,4,16,15,3,-1,3,15,21,9,-1,9,21,22,10,-1,10,22,16,4]) - m.insertNextCell(NORM_POLYHED,[5,4,10,11,-1,17,23,22,16,-1,5,17,16,4,-1,4,16,22,10,-1,10,22,23,11,-1,11,23,17,5]) - coords=DataArrayDouble([0.,0.,0.,1.,0.,0.,2.,0.,0.,3.,0.,0.,4.,0.,0.,5.,0.,0.,0.,1.,0.,1.,1.,0.,2.,1.,0.,3.,1.,0.,4.,1.,0.,5.,1.,0.,0.,0.,1.,1.,0.,1.,2.,0.,1.,3.,0.,1.,4.,0.,1.,5.,0.,1.,0.,1.,1.,1.,1.,1.,2.,1.,1.,3.,1.,1.,4.,1.,1.,5.,1.,1.],24,3) ; coords.setInfoOnComponents(["XX [m]","YYY [km]","ZZZZ [Mm]"]) - m.setCoords(coords) - mm=MEDFileUMesh() ; mm.setMeshes([m]) - fs0=MEDFileFieldMultiTS() ; fs1=MEDFileFieldMultiTS() ; fs2=MEDFileFieldMultiTS() ; fs3=MEDFileFieldMultiTS() - fieldName0="zeField0" - fieldName1="zeField1" - fieldName2="zeField2" ; pfl1=DataArrayInt([2,3]) ; pfl1.setName("pfl1") - fieldName3="zefield3" ; pfl2=DataArrayInt([2,3,4]) ; pfl2.setName("pfl2") - for i in xrange(5): - f=MEDFileField1TS() - fNode=MEDCouplingFieldDouble(ON_CELLS) ; fNode.setTime(float(i),i,0) - fNode.setName(fieldName0) ; fNode.setMesh(m) - arr=DataArrayDouble(2*5) ; arr.iota(0+1000*i) ; arr.rearrange(2) - fNode.setArray(arr) ; arr.setInfoOnComponents(["Comp1_0 [m]","Com2_0 [s^2]"]) ; fNode.checkCoherency() - f.setFieldNoProfileSBT(fNode) - fs0.pushBackTimeStep(f) - # - f=MEDFileField1TS() - fNode=MEDCouplingFieldDouble(ON_CELLS) ; fNode.setTime(float(i),i,0) - fNode.setName(fieldName1) ; fNode.setMesh(m) - arr=DataArrayDouble(2*5) ; arr.iota(100+1000*i) ; arr.rearrange(2) - fNode.setArray(arr) ; arr.setInfoOnComponents(["Comp1_1 [m]","Com2_1 [s^2]"]) ; fNode.checkCoherency() - f.setFieldNoProfileSBT(fNode) - fs1.pushBackTimeStep(f) - # - f=MEDFileField1TS() - fNode=MEDCouplingFieldDouble(ON_CELLS) ; fNode.setTime(float(i),i,0) - fNode.setName(fieldName2) ; fNode.setMesh(m[pfl1]) - arr=DataArrayDouble(2*2) ; arr.iota(200+1000*i) ; arr.rearrange(2) - fNode.setArray(arr) ; arr.setInfoOnComponents(["Comp1_2 [m]","Com2_2 [s^2]"]) ; fNode.checkCoherency() - f.setFieldProfile(fNode,mm,0,pfl1) - fs2.pushBackTimeStep(f) - # - f=MEDFileField1TS() - fNode=MEDCouplingFieldDouble(ON_CELLS) ; fNode.setTime(float(i),i,0) - fNode.setName(fieldName3) ; fNode.setMesh(m[pfl2]) - arr=DataArrayDouble(2*3) ; arr.iota(300+1000*i) ; arr.rearrange(2) - fNode.setArray(arr) ; arr.setInfoOnComponents(["Comp1_3 [m]","Com2_3 [s^2]"]) ; fNode.checkCoherency() - f.setFieldProfile(fNode,mm,0,pfl2) - fs3.pushBackTimeStep(f) - pass - mm.write(fname,2) - fs0.write(fname,0) ; fs1.write(fname,0) ; fs2.write(fname,0) ; fs3.write(fname,0) - a0Exp=mm.getCoords().deepCpy() - del m,mm,fs0 - ########## GO for reading in MEDReader,by not loading all. Mesh is fully loaded but not fields values - ms=MEDFileMeshes(fname) - fields=MEDFileFields(fname,False) - fields.removeFieldsWithoutAnyTimeStep() - fields_per_mesh=[fields.partOfThisLyingOnSpecifiedMeshName(meshName) for meshName in ms.getMeshesNames()] - allFMTSLeavesToDisplay=[] - for fields in fields_per_mesh: - allFMTSLeavesToDisplay2=[] - for fmts in fields: - tmp=fmts.splitDiscretizations() - for itmp in tmp: - self.assertTrue(not itmp.presenceOfMultiDiscPerGeoType()) - pass - allFMTSLeavesToDisplay2+=tmp - pass - allFMTSLeavesToDisplay.append(allFMTSLeavesToDisplay2) - pass - self.assertEqual(len(allFMTSLeavesToDisplay),1) - self.assertEqual(len(allFMTSLeavesToDisplay[0]),4) - allFMTSLeavesPerTimeSeries=MEDFileAnyTypeFieldMultiTS.SplitIntoCommonTimeSeries(sum(allFMTSLeavesToDisplay,[])) - self.assertEqual(len(allFMTSLeavesPerTimeSeries),1) # one time serie here : because the 2 fields are defined on the same time steps - self.assertEqual(len(allFMTSLeavesPerTimeSeries[0]),4) - allFMTSLeavesPerCommonSupport=MEDFileAnyTypeFieldMultiTS.SplitPerCommonSupport(allFMTSLeavesPerTimeSeries[0],ms[ms.getMeshesNames()[0]]) - self.assertEqual(len(allFMTSLeavesPerCommonSupport),3) - self.assertEqual(len(allFMTSLeavesPerCommonSupport[0][0]),2) - self.assertEqual(len(allFMTSLeavesPerCommonSupport[1][0]),1) - self.assertEqual(len(allFMTSLeavesPerCommonSupport[2][0]),1) - # - mst=MEDFileMeshStruct.New(ms[0]) - # - fcscp=allFMTSLeavesPerCommonSupport[0][1] - mml=fcscp.buildFromScratchDataSetSupport(0,fields) - mml2=mml.prepare() - self.assertTrue(isinstance(mml2,MEDUMeshMultiLev)) - ncc,a0,a1,a2,a3,a4,a5=mml2.buildVTUArrays() - self.assertTrue(ncc) - self.assertTrue(a0.isEqual(a0Exp,1e-12)) - self.assertTrue(a1.isEqual(DataArrayByte([12,12,42,42,42]))) - self.assertTrue(a2.isEqual(DataArrayInt([0,9,18,27,36]))) - self.assertTrue(a3.isEqual(DataArrayInt([8,1,0,6,7,13,12,18,19,8,2,1,7,8,14,13,19,20,8,2,3,8,9,14,15,20,21,8,3,4,9,10,15,16,21,22,8,4,5,10,11,16,17,22,23]))) - self.assertTrue(a4.isEqual(DataArrayInt([-1,-1,0,31,62]))) - self.assertTrue(a5.isEqual(DataArrayInt([6,4,3,2,8,9,4,15,21,20,14,4,3,15,14,2,4,2,14,20,8,4,8,20,21,9,4,9,21,15,3,6,4,4,3,9,10,4,16,22,21,15,4,4,16,15,3,4,3,15,21,9,4,9,21,22,10,4,10,22,16,4,6,4,5,4,10,11,4,17,23,22,16,4,5,17,16,4,4,4,16,22,10,4,10,22,23,11,4,11,23,17,5]))) - for i in xrange(1,5): - self.assertTrue((fcscp.isDataSetSupportEqualToThePreviousOne(i,fields))) - pass - pass - for i in xrange(5): - f=allFMTSLeavesPerCommonSupport[0][0][0][i] - fsst=MEDFileField1TSStructItem.BuildItemFrom(f,mst) - f.loadArraysIfNecessary() - v=mml.buildDataArray(fsst,fields,f.getUndergroundDataArray()) - self.assertEqual(f.getName(),fieldName0) - self.assertEqual(v.getHiddenCppPointer(),f.getUndergroundDataArray().getHiddenCppPointer()) - vExp=DataArrayDouble(5*2) ; vExp.iota(0+i*1000) ; vExp.rearrange(2) ; vExp.setInfoOnComponents(['Comp1_0 [m]','Com2_0 [s^2]']) - self.assertTrue(v.isEqual(vExp,1e-12)) - # - f=allFMTSLeavesPerCommonSupport[0][0][1][i] - fsst=MEDFileField1TSStructItem.BuildItemFrom(f,mst) - f.loadArraysIfNecessary() - v=mml.buildDataArray(fsst,fields,f.getUndergroundDataArray()) - self.assertEqual(f.getName(),fieldName1) - self.assertEqual(v.getHiddenCppPointer(),f.getUndergroundDataArray().getHiddenCppPointer()) - vExp=DataArrayDouble(5*2) ; vExp.iota(100+i*1000) ; vExp.rearrange(2) ; vExp.setInfoOnComponents(['Comp1_1 [m]','Com2_1 [s^2]']) - self.assertTrue(v.isEqual(vExp,1e-12)) - pass - # - fcscp=allFMTSLeavesPerCommonSupport[1][1] - mml=fcscp.buildFromScratchDataSetSupport(0,fields) - mml2=mml.prepare() - self.assertTrue(isinstance(mml2,MEDUMeshMultiLev)) - ncc,a0,a1,a2,a3,a4,a5=mml2.buildVTUArrays() - self.assertTrue(ncc) - self.assertTrue(a0.isEqual(a0Exp,1e-12)) - self.assertTrue(a1.isEqual(DataArrayByte([42,42]))) - self.assertTrue(a2.isEqual(DataArrayInt([0,9]))) - self.assertTrue(a3.isEqual(DataArrayInt([8,2,3,8,9,14,15,20,21,8,3,4,9,10,15,16,21,22]))) - self.assertTrue(a4.isEqual(DataArrayInt([0,31]))) - self.assertTrue(a5.isEqual(DataArrayInt([6,4,3,2,8,9,4,15,21,20,14,4,3,15,14,2,4,2,14,20,8,4,8,20,21,9,4,9,21,15,3,6,4,4,3,9,10,4,16,22,21,15,4,4,16,15,3,4,3,15,21,9,4,9,21,22,10,4,10,22,16,4]))) - for i in xrange(1,5): - self.assertTrue((fcscp.isDataSetSupportEqualToThePreviousOne(i,fields))) - pass - pass - for i in xrange(5): - f=allFMTSLeavesPerCommonSupport[1][0][0][i] - fsst=MEDFileField1TSStructItem.BuildItemFrom(f,mst) - f.loadArraysIfNecessary() - v=mml.buildDataArray(fsst,fields,f.getUndergroundDataArray()) - self.assertEqual(f.getName(),fieldName2) - self.assertEqual(v.getHiddenCppPointer(),f.getUndergroundDataArray().getHiddenCppPointer()) - vExp=DataArrayDouble(2*2) ; vExp.iota(200+i*1000) ; vExp.rearrange(2) ; vExp.setInfoOnComponents(['Comp1_2 [m]','Com2_2 [s^2]']) - self.assertTrue(v.isEqual(vExp,1e-12)) - pass - # - fcscp=allFMTSLeavesPerCommonSupport[2][1] - mml=fcscp.buildFromScratchDataSetSupport(0,fields) - mml2=mml.prepare() - self.assertTrue(isinstance(mml2,MEDUMeshMultiLev)) - ncc,a0,a1,a2,a3,a4,a5=mml2.buildVTUArrays() - self.assertTrue(ncc) - self.assertTrue(a0.isEqual(a0Exp,1e-12)) - self.assertTrue(a1.isEqual(DataArrayByte([42,42,42]))) - self.assertTrue(a2.isEqual(DataArrayInt([0,9,18]))) - self.assertTrue(a3.isEqual(DataArrayInt([8,2,3,8,9,14,15,20,21,8,3,4,9,10,15,16,21,22,8,4,5,10,11,16,17,22,23]))) - self.assertTrue(a4.isEqual(DataArrayInt([0,31,62]))) - self.assertTrue(a5.isEqual(DataArrayInt([6,4,3,2,8,9,4,15,21,20,14,4,3,15,14,2,4,2,14,20,8,4,8,20,21,9,4,9,21,15,3,6,4,4,3,9,10,4,16,22,21,15,4,4,16,15,3,4,3,15,21,9,4,9,21,22,10,4,10,22,16,4,6,4,5,4,10,11,4,17,23,22,16,4,5,17,16,4,4,4,16,22,10,4,10,22,23,11,4,11,23,17,5]))) - for i in xrange(1,5): - self.assertTrue((fcscp.isDataSetSupportEqualToThePreviousOne(i,fields))) - pass - pass - for i in xrange(5): - f=allFMTSLeavesPerCommonSupport[2][0][0][i] - fsst=MEDFileField1TSStructItem.BuildItemFrom(f,mst) - f.loadArraysIfNecessary() - v=mml.buildDataArray(fsst,fields,f.getUndergroundDataArray()) - self.assertEqual(f.getName(),fieldName3) - self.assertEqual(v.getHiddenCppPointer(),f.getUndergroundDataArray().getHiddenCppPointer()) - vExp=DataArrayDouble(3*2) ; vExp.iota(300+i*1000) ; vExp.rearrange(2) ; vExp.setInfoOnComponents(['Comp1_3 [m]','Com2_3 [s^2]']) - self.assertTrue(v.isEqual(vExp,1e-12)) - pass - pass - - def test14(self): - """ Testing only polyhedrons""" - fname="ForMEDReader14.med" - m=MEDCouplingUMesh("mesh",3) - m.allocateCells() - m.insertNextCell(NORM_POLYHED,[3,2,8,9,-1,15,21,20,14,-1,3,15,14,2,-1,2,14,20,8,-1,8,20,21,9,-1,9,21,15,3]) - m.insertNextCell(NORM_POLYHED,[4,3,9,10,-1,16,22,21,15,-1,4,16,15,3,-1,3,15,21,9,-1,9,21,22,10,-1,10,22,16,4]) - m.insertNextCell(NORM_POLYHED,[5,4,10,11,-1,17,23,22,16,-1,5,17,16,4,-1,4,16,22,10,-1,10,22,23,11,-1,11,23,17,5]) - coords=DataArrayDouble([0.,0.,0.,1.,0.,0.,2.,0.,0.,3.,0.,0.,4.,0.,0.,5.,0.,0.,0.,1.,0.,1.,1.,0.,2.,1.,0.,3.,1.,0.,4.,1.,0.,5.,1.,0.,0.,0.,1.,1.,0.,1.,2.,0.,1.,3.,0.,1.,4.,0.,1.,5.,0.,1.,0.,1.,1.,1.,1.,1.,2.,1.,1.,3.,1.,1.,4.,1.,1.,5.,1.,1.],24,3) ; coords.setInfoOnComponents(["XX [m]","YYY [km]","ZZZZ [Mm]"]) - m.setCoords(coords) - mm=MEDFileUMesh() ; mm.setMeshes([m]) - fs0=MEDFileFieldMultiTS() ; fs1=MEDFileFieldMultiTS() - fieldName0="zeField0" - fieldName1="zeField1" - for i in xrange(5): - f=MEDFileField1TS() - fNode=MEDCouplingFieldDouble(ON_CELLS) ; fNode.setTime(float(i),i,0) - fNode.setName(fieldName0) ; fNode.setMesh(m) - arr=DataArrayDouble(2*3) ; arr.iota(0+1000*i) ; arr.rearrange(2) - fNode.setArray(arr) ; arr.setInfoOnComponents(["Comp1_0 [m]","Com2_0 [s^2]"]) ; fNode.checkCoherency() - f.setFieldNoProfileSBT(fNode) - fs0.pushBackTimeStep(f) - # - f=MEDFileField1TS() - fNode=MEDCouplingFieldDouble(ON_CELLS) ; fNode.setTime(float(i),i,0) - fNode.setName(fieldName1) ; fNode.setMesh(m) - arr=DataArrayDouble(2*3) ; arr.iota(100+1000*i) ; arr.rearrange(2) - fNode.setArray(arr) ; arr.setInfoOnComponents(["Comp1_1 [m]","Com2_1 [s^2]"]) ; fNode.checkCoherency() - f.setFieldNoProfileSBT(fNode) - fs1.pushBackTimeStep(f) - pass - mm.write(fname,2) - fs0.write(fname,0) ; fs1.write(fname,0) - a0Exp=mm.getCoords().deepCpy() - del m,mm,fs0 - ########## GO for reading in MEDReader,by not loading all. Mesh is fully loaded but not fields values - ms=MEDFileMeshes(fname) - fields=MEDFileFields(fname,False) - fields.removeFieldsWithoutAnyTimeStep() - fields_per_mesh=[fields.partOfThisLyingOnSpecifiedMeshName(meshName) for meshName in ms.getMeshesNames()] - allFMTSLeavesToDisplay=[] - for fields in fields_per_mesh: - allFMTSLeavesToDisplay2=[] - for fmts in fields: - tmp=fmts.splitDiscretizations() - for itmp in tmp: - self.assertTrue(not itmp.presenceOfMultiDiscPerGeoType()) - pass - allFMTSLeavesToDisplay2+=tmp - pass - allFMTSLeavesToDisplay.append(allFMTSLeavesToDisplay2) - pass - self.assertEqual(len(allFMTSLeavesToDisplay),1) - self.assertEqual(len(allFMTSLeavesToDisplay[0]),2) - allFMTSLeavesPerTimeSeries=MEDFileAnyTypeFieldMultiTS.SplitIntoCommonTimeSeries(sum(allFMTSLeavesToDisplay,[])) - self.assertEqual(len(allFMTSLeavesPerTimeSeries),1) # one time serie here : because the 2 fields are defined on the same time steps - self.assertEqual(len(allFMTSLeavesPerTimeSeries[0]),2) - allFMTSLeavesPerCommonSupport=MEDFileAnyTypeFieldMultiTS.SplitPerCommonSupport(allFMTSLeavesPerTimeSeries[0],ms[ms.getMeshesNames()[0]]) - self.assertEqual(len(allFMTSLeavesPerCommonSupport),1) - self.assertEqual(len(allFMTSLeavesPerCommonSupport[0][0]),2) - # - mst=MEDFileMeshStruct.New(ms[0]) - # - fcscp=allFMTSLeavesPerCommonSupport[0][1] - mml=fcscp.buildFromScratchDataSetSupport(0,fields) - mml2=mml.prepare() - self.assertTrue(isinstance(mml2,MEDUMeshMultiLev)) - ncc,a0,a1,a2,a3,a4,a5=mml2.buildVTUArrays() - self.assertTrue(ncc) - self.assertTrue(a0.isEqual(a0Exp,1e-12)) - self.assertTrue(a1.isEqual(DataArrayByte([42,42,42]))) - self.assertTrue(a2.isEqual(DataArrayInt([0,9,18]))) - self.assertTrue(a3.isEqual(DataArrayInt([8,2,3,8,9,14,15,20,21,8,3,4,9,10,15,16,21,22,8,4,5,10,11,16,17,22,23]))) - self.assertTrue(a4.isEqual(DataArrayInt([0,31,62]))) - self.assertTrue(a5.isEqual(DataArrayInt([6,4,3,2,8,9,4,15,21,20,14,4,3,15,14,2,4,2,14,20,8,4,8,20,21,9,4,9,21,15,3,6,4,4,3,9,10,4,16,22,21,15,4,4,16,15,3,4,3,15,21,9,4,9,21,22,10,4,10,22,16,4,6,4,5,4,10,11,4,17,23,22,16,4,5,17,16,4,4,4,16,22,10,4,10,22,23,11,4,11,23,17,5]))) - for i in xrange(1,5): - self.assertTrue((fcscp.isDataSetSupportEqualToThePreviousOne(i,fields))) - pass - a6,a7=mml2.retrieveFamilyIdsOnCells() - self.assertTrue(a6.isEqual(DataArrayInt([0,0,0]))) - self.assertTrue(a7) - a8,a9=mml2.retrieveNumberIdsOnCells() - self.assertTrue(a8 is None) - self.assertTrue(a9) - for i in xrange(5): - f=allFMTSLeavesPerCommonSupport[0][0][0][i] - fsst=MEDFileField1TSStructItem.BuildItemFrom(f,mst) - f.loadArraysIfNecessary() - v=mml.buildDataArray(fsst,fields,f.getUndergroundDataArray()) - self.assertEqual(f.getName(),fieldName0) - self.assertEqual(v.getHiddenCppPointer(),f.getUndergroundDataArray().getHiddenCppPointer()) - vExp=DataArrayDouble(3*2) ; vExp.iota(0+i*1000) ; vExp.rearrange(2) ; vExp.setInfoOnComponents(['Comp1_0 [m]','Com2_0 [s^2]']) - self.assertTrue(v.isEqual(vExp,1e-12)) - # - f=allFMTSLeavesPerCommonSupport[0][0][1][i] - fsst=MEDFileField1TSStructItem.BuildItemFrom(f,mst) - f.loadArraysIfNecessary() - v=mml.buildDataArray(fsst,fields,f.getUndergroundDataArray()) - self.assertEqual(f.getName(),fieldName1) - self.assertEqual(v.getHiddenCppPointer(),f.getUndergroundDataArray().getHiddenCppPointer()) - vExp=DataArrayDouble(3*2) ; vExp.iota(100+i*1000) ; vExp.rearrange(2) ; vExp.setInfoOnComponents(['Comp1_1 [m]','Com2_1 [s^2]']) - self.assertTrue(v.isEqual(vExp,1e-12)) - pass - pass - - def test15(self): - """ - "ForMEDReader15.med" file has a spaceDim 3 mesh "mesh" (it is important !) - and a field "zeField" lying on a single geometric type for Cell discr and node part. - Test that can appear the most simple but it hides a big issue of MEDReader - that copies are reduced at most. So it can leads to SIGSEGV if the memory management is not OK for int* and double * similar between VTK and MEDCoupling. - """ - fname="ForMEDReader15.med" - m0=MEDCouplingCMesh() - arr=DataArrayDouble(3) ; arr.iota(0) - m0.setCoords(arr,arr,arr) - m0.setName("mesh") - m0=m0.buildUnstructured() - # - fieldName="zeField" - fCell=MEDCouplingFieldDouble(ON_CELLS) - fCell.setName(fieldName) - fCell.setMesh(m0) - # - fNode=MEDCouplingFieldDouble(ON_NODES) - fNode.setName(fieldName) - fNode.setMesh(m0) - # - mm=MEDFileUMesh() - mm.setMeshAtLevel(0,m0) - fam=DataArrayInt(8) ; fam.iota(0) ; mm.setFamilyFieldArr(0,fam) ; del fam - num=DataArrayInt(8) ; num.iota(100) ; mm.setRenumFieldArr(0,num) ; del num - # - ffs=MEDFileFieldMultiTS() - # TimeStep 0 - t=(1.,0,0) ; off=0. - f1ts=MEDFileField1TS() - a=DataArrayDouble(m0.getNumberOfCells()) ; a.iota(off) ; a.setInfoOnComponents(["xx [m]"]) - fCell.setArray(a) - fCell.setTime(*t) - fCell.checkCoherency() - a=DataArrayDouble(m0.getNumberOfNodes()) ; a.iota(off) ; a.setInfoOnComponents(["xx [m]"]) - a=a.negate() - fNode.setArray(a) - fNode.setTime(*t) - fNode.checkCoherency() - f1ts.setFieldNoProfileSBT(fCell) - f1ts.setFieldNoProfileSBT(fNode) - ffs.pushBackTimeStep(f1ts) - # TimeStep 1 - t=(2.1,1,0) ; off=100. - f1ts=MEDFileField1TS() - a=DataArrayDouble(m0.getNumberOfCells()) ; a.iota(off) ; a.setInfoOnComponents(["xx [m]"]) - fCell.setArray(a) - fCell.setTime(*t) - fCell.checkCoherency() - a=DataArrayDouble(m0.getNumberOfNodes()) ; a.iota(off) ; a.setInfoOnComponents(["xx [m]"]) - a=a.negate() - fNode.setArray(a) - fNode.setTime(*t) - fNode.checkCoherency() - f1ts.setFieldNoProfileSBT(fCell) - f1ts.setFieldNoProfileSBT(fNode) - ffs.pushBackTimeStep(f1ts) - # TimeStep 2 - t=(3.2,2,0) ; off=200. - f1ts=MEDFileField1TS() - a=DataArrayDouble(m0.getNumberOfCells()) ; a.iota(off) ; a.setInfoOnComponents(["xx [m]"]) - fCell.setArray(a) - fCell.setTime(*t) - fCell.checkCoherency() - a=DataArrayDouble(m0.getNumberOfNodes()) ; a.iota(off) ; a.setInfoOnComponents(["xx [m]"]) - a=a.negate() - fNode.setArray(a) - fNode.setTime(*t) - fNode.checkCoherency() - f1ts.setFieldNoProfileSBT(fCell) - f1ts.setFieldNoProfileSBT(fNode) - ffs.pushBackTimeStep(f1ts) - # TimeStep 3 - t=(4.3,3,1) ; off=300. - f1ts=MEDFileField1TS() - a=DataArrayDouble(m0.getNumberOfCells()) ; a.iota(off) ; a.setInfoOnComponents(["xx [m]"]) - fCell.setArray(a) - fCell.setTime(*t) - fCell.checkCoherency() - a=DataArrayDouble(m0.getNumberOfNodes()) ; a.iota(off) ; a.setInfoOnComponents(["xx [m]"]) - a=a.negate() - fNode.setArray(a) - fNode.setTime(*t) - fNode.checkCoherency() - f1ts.setFieldNoProfileSBT(fCell) - f1ts.setFieldNoProfileSBT(fNode) - ffs.pushBackTimeStep(f1ts) - # - mm.write(fname,2) - ffs.write(fname,0) - ########## GO for reading in MEDReader,by not loading all. Mesh is fully loaded but not fields values - ms=MEDFileMeshes(fname) - fields=MEDFileFields(fname,False) - fields.removeFieldsWithoutAnyTimeStep() - fields_per_mesh=[fields.partOfThisLyingOnSpecifiedMeshName(meshName) for meshName in ms.getMeshesNames()] - allFMTSLeavesToDisplay=[] - for fields in fields_per_mesh: - allFMTSLeavesToDisplay2=[] - for fmts in fields: - tmp=fmts.splitDiscretizations() - for itmp in tmp: - self.assertTrue(not itmp.presenceOfMultiDiscPerGeoType()) - pass - allFMTSLeavesToDisplay2+=tmp - pass - allFMTSLeavesToDisplay.append(allFMTSLeavesToDisplay2) - pass - self.assertEqual(len(allFMTSLeavesToDisplay),1) - self.assertEqual(len(allFMTSLeavesToDisplay[0]),2) - allFMTSLeavesPerTimeSeries=MEDFileAnyTypeFieldMultiTS.SplitIntoCommonTimeSeries(sum(allFMTSLeavesToDisplay,[])) - self.assertEqual(len(allFMTSLeavesPerTimeSeries),1) # one time serie here : because the 2 fields are defined on the same time steps - self.assertEqual(len(allFMTSLeavesPerTimeSeries[0]),2) - allFMTSLeavesPerCommonSupport=MEDFileAnyTypeFieldMultiTS.SplitPerCommonSupport(allFMTSLeavesPerTimeSeries[0],ms[ms.getMeshesNames()[0]]) - self.assertEqual(len(allFMTSLeavesPerCommonSupport),1) - self.assertEqual(len(allFMTSLeavesPerCommonSupport[0][0]),2) - # - mst=MEDFileMeshStruct.New(ms[0]) - # - fcscp=allFMTSLeavesPerCommonSupport[0][1] - mml=fcscp.buildFromScratchDataSetSupport(0,fields) - mml2=mml.prepare() - self.assertTrue(isinstance(mml2,MEDUMeshMultiLev)) - ncc,a0,a1,a2,a3,a4,a5=mml2.buildVTUArrays() - self.assertTrue(ncc) - self.assertTrue(a0.isEqual(DataArrayDouble([0.,0.,0.,1.,0.,0.,2.,0.,0.,0.,1.,0.,1.,1.,0.,2.,1.,0.,0.,2.,0.,1.,2.,0.,2.,2.,0.,0.,0.,1.,1.,0.,1.,2.,0.,1.,0.,1.,1.,1.,1.,1.,2.,1.,1.,0.,2.,1.,1.,2.,1.,2.,2.,1.,0.,0.,2.,1.,0.,2.,2.,0.,2.,0.,1.,2.,1.,1.,2.,2.,1.,2.,0.,2.,2.,1.,2.,2.,2.,2.,2.0],27,3),1e-12)) - self.assertTrue(a1.isEqual(DataArrayByte([12,12,12,12,12,12,12,12]))) - self.assertTrue(a2.isEqual(DataArrayInt([0,9,18,27,36,45,54,63]))) - self.assertTrue(a3.isEqual(DataArrayInt([8,1,0,3,4,10,9,12,13,8,2,1,4,5,11,10,13,14,8,4,3,6,7,13,12,15,16,8,5,4,7,8,14,13,16,17,8,10,9,12,13,19,18,21,22,8,11,10,13,14,20,19,22,23,8,13,12,15,16,22,21,24,25,8,14,13,16,17,23,22,25,26]))) - self.assertTrue(a4 is None) - self.assertTrue(a5 is None) - a6,a7=mml2.retrieveFamilyIdsOnCells() - self.assertTrue(a6.isEqual(DataArrayInt([0,1,2,3,4,5,6,7]))) - self.assertTrue(a7) # no copy here - a8,a9=mml2.retrieveNumberIdsOnCells() - self.assertTrue(a8.isEqual(DataArrayInt([100,101,102,103,104,105,106,107]))) - self.assertTrue(a9) # no copy here - pass - - def test16(self): - """ Here 2 meshes "mesh1" and "mesh2" and 4 fields (no profiles here) : - - "zeField1_0" (CELLS) and "zeField2_0" (NODES) on "mesh1" - - "zeField3_1" (CELLS) and "zeField4_1" (NODES) on "mesh2" - time steps series are the same for the whole 4 fields - """ - fname="ForMEDReader16.med" - m0=MEDCouplingCMesh() - arr=DataArrayDouble(3) ; arr.iota(0) - m0.setCoords(arr,arr,arr) - m0.setName("mesh1") - m0=m0.buildUnstructured() - # - fCell1=MEDCouplingFieldDouble(ON_CELLS) - fCell1.setName("zeField1_0") - fCell1.setMesh(m0) - # - fNode1=MEDCouplingFieldDouble(ON_NODES) - fNode1.setName("zeField2_0") - fNode1.setMesh(m0) - # - mms=MEDFileMeshes() - mm1=MEDFileUMesh() - mm1.setMeshAtLevel(0,m0) - fam=DataArrayInt([0,1,0,1,2,3,2,3]); mm1.setFamilyFieldArr(0,fam) ; del fam - num=DataArrayInt(8) ; num.iota(100) ; mm1.setRenumFieldArr(0,num) ; del num - mm1.setFamilyId("FAMILLE_ZERO",0) ; mm1.setFamilyId("Family1_1",1) ; mm1.setFamilyId("Family1_2",2) ; mm1.setFamilyId("Family1_3",3) ; mm1.setFamilyId("Family1_4",4) - mm1.setFamiliesIdsOnGroup("Grp1_1",[0,1]) ; mm1.setFamiliesIdsOnGroup("Grp1_2",[2,3]) - mms.pushMesh(mm1) ; del mm1 - # - m1=m0.deepCpy() ; m1.translate([2.5,0.,0.]) ; m1.setName("mesh2") - # - fCell2=MEDCouplingFieldDouble(ON_CELLS) - fCell2.setName("zeField3_1") - fCell2.setMesh(m1) - # - fNode2=MEDCouplingFieldDouble(ON_NODES) - fNode2.setName("zeField4_1") - fNode2.setMesh(m1) - # - mm2=MEDFileUMesh() - mm2.setMeshAtLevel(0,m1) - fam=DataArrayInt([0,1,0,1,2,3,2,3]); mm2.setFamilyFieldArr(0,fam) ; del fam - num=DataArrayInt(8) ; num.iota(200) ; mm2.setRenumFieldArr(0,num) ; del num - mm2.setFamilyId("FAMILLE_ZERO",0) ; mm2.setFamilyId("Family2_1",1) ; mm2.setFamilyId("Family2_2",2) ; mm2.setFamilyId("Family2_3",3) ; mm2.setFamilyId("Family2_4",4) - mm2.setFamiliesIdsOnGroup("Grp2_1",[0,1]) ; mm2.setFamiliesIdsOnGroup("Grp2_2",[2,3]) ; mm2.setFamiliesIdsOnGroup("Grp2_3",[1,2,3]) - mms.pushMesh(mm2) ; del mm2 - ffs1_1=MEDFileFieldMultiTS() - ffs1_2=MEDFileFieldMultiTS() - ffs2_1=MEDFileFieldMultiTS() - ffs2_2=MEDFileFieldMultiTS() - mts=MEDFileFields() - for elt in ffs1_1,ffs1_2,ffs2_1,ffs2_2: - mts.pushField(elt) - pass - # TimeStep 0 - t=(1.,0,0) ; off=0. - f1ts1=MEDFileField1TS() - f1ts2=MEDFileField1TS() - a=DataArrayDouble(m0.getNumberOfCells()) ; a.iota(off) ; a.setInfoOnComponents(["xx [m]"]) - fCell1.setArray(a) - fCell1.setTime(*t) - fCell1.checkCoherency() - a=DataArrayDouble(m0.getNumberOfNodes()) ; a.iota(off) ; a.setInfoOnComponents(["xx [m]"]) - a=a.negate() - fNode1.setArray(a) - fNode1.setTime(*t) - fNode1.checkCoherency() - f1ts1.setFieldNoProfileSBT(fCell1) ; ffs1_1.pushBackTimeStep(f1ts1) - f1ts2.setFieldNoProfileSBT(fNode1) ; ffs1_2.pushBackTimeStep(f1ts2) - # - f1ts1=MEDFileField1TS() - f1ts2=MEDFileField1TS() - a=DataArrayDouble(m1.getNumberOfCells()) ; a.iota(1000.+off) ; a.setInfoOnComponents(["xx [m]"]) - fCell2.setArray(a) - fCell2.setTime(*t) - fCell2.checkCoherency() - a=DataArrayDouble(m1.getNumberOfNodes()) ; a.iota(1000+off) ; a.setInfoOnComponents(["xx [m]"]) - a=a.negate() - fNode2.setArray(a) - fNode2.setTime(*t) - fNode2.checkCoherency() - f1ts1.setFieldNoProfileSBT(fCell2) ; ffs2_1.pushBackTimeStep(f1ts1) - f1ts2.setFieldNoProfileSBT(fNode2) ; ffs2_2.pushBackTimeStep(f1ts2) - # TimeStep 1 - t=(2.1,1,0) ; off=100. - f1ts1=MEDFileField1TS() - f1ts2=MEDFileField1TS() - a=DataArrayDouble(m0.getNumberOfCells()) ; a.iota(off) ; a.setInfoOnComponents(["xx [m]"]) - fCell1.setArray(a) - fCell1.setTime(*t) - fCell1.checkCoherency() - a=DataArrayDouble(m0.getNumberOfNodes()) ; a.iota(off) ; a.setInfoOnComponents(["xx [m]"]) - a=a.negate() - fNode1.setArray(a) - fNode1.setTime(*t) - fNode1.checkCoherency() - f1ts1.setFieldNoProfileSBT(fCell1) ; ffs1_1.pushBackTimeStep(f1ts1) - f1ts2.setFieldNoProfileSBT(fNode1) ; ffs1_2.pushBackTimeStep(f1ts2) - # - f1ts1=MEDFileField1TS() - f1ts2=MEDFileField1TS() - a=DataArrayDouble(m1.getNumberOfCells()) ; a.iota(1000.+off) ; a.setInfoOnComponents(["xx [m]"]) - fCell2.setArray(a) - fCell2.setTime(*t) - fCell2.checkCoherency() - a=DataArrayDouble(m1.getNumberOfNodes()) ; a.iota(1000+off) ; a.setInfoOnComponents(["xx [m]"]) - a=a.negate() - fNode2.setArray(a) - fNode2.setTime(*t) - fNode2.checkCoherency() - f1ts1.setFieldNoProfileSBT(fCell2) ; ffs2_1.pushBackTimeStep(f1ts1) - f1ts2.setFieldNoProfileSBT(fNode2) ; ffs2_2.pushBackTimeStep(f1ts2) - # TimeStep 2 - t=(3.1,2,0) ; off=200. - f1ts1=MEDFileField1TS() - f1ts2=MEDFileField1TS() - a=DataArrayDouble(m0.getNumberOfCells()) ; a.iota(off) ; a.setInfoOnComponents(["xx [m]"]) - fCell1.setArray(a) - fCell1.setTime(*t) - fCell1.checkCoherency() - a=DataArrayDouble(m0.getNumberOfNodes()) ; a.iota(off) ; a.setInfoOnComponents(["xx [m]"]) - a=a.negate() - fNode1.setArray(a) - fNode1.setTime(*t) - fNode1.checkCoherency() - f1ts1.setFieldNoProfileSBT(fCell1) ; ffs1_1.pushBackTimeStep(f1ts1) - f1ts2.setFieldNoProfileSBT(fNode1) ; ffs1_2.pushBackTimeStep(f1ts2) - # - f1ts1=MEDFileField1TS() - f1ts2=MEDFileField1TS() - a=DataArrayDouble(m1.getNumberOfCells()) ; a.iota(1000.+off) ; a.setInfoOnComponents(["xx [m]"]) - fCell2.setArray(a) - fCell2.setTime(*t) - fCell2.checkCoherency() - a=DataArrayDouble(m1.getNumberOfNodes()) ; a.iota(1000+off) ; a.setInfoOnComponents(["xx [m]"]) - a=a.negate() - fNode2.setArray(a) - fNode2.setTime(*t) - fNode2.checkCoherency() - f1ts1.setFieldNoProfileSBT(fCell2) ; ffs2_1.pushBackTimeStep(f1ts1) - f1ts2.setFieldNoProfileSBT(fNode2) ; ffs2_2.pushBackTimeStep(f1ts2) - # - mms.write(fname,2) ; mts.write(fname,0) - ########## GO for reading in MEDReader,by not loading all. Mesh is fully loaded but not fields values - ms=MEDFileMeshes(fname) - fields=MEDFileFields(fname,False) - fields.removeFieldsWithoutAnyTimeStep() - fields_per_mesh=[fields.partOfThisLyingOnSpecifiedMeshName(meshName) for meshName in ms.getMeshesNames()] - allFMTSLeavesToDisplay=[] - for fields in fields_per_mesh: - allFMTSLeavesToDisplay2=[] - for fmts in fields: - tmp=fmts.splitDiscretizations() - for itmp in tmp: - self.assertTrue(not itmp.presenceOfMultiDiscPerGeoType()) - pass - allFMTSLeavesToDisplay2+=tmp - pass - allFMTSLeavesToDisplay.append(allFMTSLeavesToDisplay2) - pass - self.assertEqual(len(allFMTSLeavesToDisplay),2) - self.assertEqual(len(allFMTSLeavesToDisplay[0]),2) - self.assertEqual(len(allFMTSLeavesToDisplay[1]),2) - allFMTSLeavesPerTimeSeries=MEDFileAnyTypeFieldMultiTS.SplitIntoCommonTimeSeries(sum(allFMTSLeavesToDisplay,[])) - self.assertEqual(len(allFMTSLeavesPerTimeSeries),1) # one time serie here : because the 2 fields are defined on the same time steps - self.assertEqual(len(allFMTSLeavesPerTimeSeries[0]),4) - allFMTSLeavesPerCommonSupport1=MEDFileAnyTypeFieldMultiTS.SplitPerCommonSupport(allFMTSLeavesToDisplay[0],ms[ms.getMeshesNames()[0]]) - self.assertEqual(len(allFMTSLeavesPerCommonSupport1),1) - self.assertEqual(len(allFMTSLeavesPerCommonSupport1[0][0]),2) - allFMTSLeavesPerCommonSupport2=MEDFileAnyTypeFieldMultiTS.SplitPerCommonSupport(allFMTSLeavesToDisplay[0],ms[ms.getMeshesNames()[0]]) - self.assertEqual(len(allFMTSLeavesPerCommonSupport2),1) - self.assertEqual(len(allFMTSLeavesPerCommonSupport2[0][0]),2) - pass - - def test17(self): - """ First test on GAUSS_NE (Elno). Here no Profiles. - 2 times steps. - """ - fname="ForMEDReader17.med" - fieldName1="MyFirstElno" - fieldName2="ACellField" - fieldName3="ANodeField" - coo=DataArrayDouble([0.,0.,1.,0.,2.,0.,0.,1.,1.,1.,2.,1.],6,2) - m=MEDCouplingUMesh("mesh",2) - m.setCoords(coo) - m.allocateCells() - m.insertNextCell(NORM_QUAD4,[0,3,4,1]) - m.insertNextCell(NORM_QUAD4,[1,4,5,2]) - m.checkCoherency2() - # - t=(1.1,0,-1) - f=MEDCouplingFieldDouble(ON_GAUSS_NE) ; f.setTime(*t) ; f.setMesh(m) - f.setArray(DataArrayDouble([3.,5.,7.,6.,2.,3.,11.,8.])) - f.setName(fieldName1) - f.checkCoherency() - MEDLoader.WriteField(fname,f,True) - f2=MEDCouplingFieldDouble(ON_CELLS) ; f2.setTime(*t) ; f2.setMesh(m) - f2.setArray(DataArrayDouble([7.,11.],2,1)) - f2.setName(fieldName2) - MEDLoader.WriteFieldUsingAlreadyWrittenMesh(fname,f2) - f3=MEDCouplingFieldDouble(ON_NODES) ; f3.setTime(*t) ; f3.setMesh(m) - f3.setArray(DataArrayDouble([1.,2.,4.,1.,2.,4.],6,1)) - f3.setName(fieldName3) - MEDLoader.WriteFieldUsingAlreadyWrittenMesh(fname,f3) - # - t=(2.1,1,-1) - f=MEDCouplingFieldDouble(ON_GAUSS_NE) ; f.setTime(*t) ; f.setMesh(m) - f.setArray(DataArrayDouble([7.,6.,3.,5.,11.,8.,2.,3.])) - f.setName(fieldName1) - f.checkCoherency() - MEDLoader.WriteFieldUsingAlreadyWrittenMesh(fname,f) - f2=MEDCouplingFieldDouble(ON_CELLS) ; f2.setTime(*t) ; f2.setMesh(m) - f2.setArray(DataArrayDouble([11.,7.],2,1)) - f2.setName(fieldName2) - MEDLoader.WriteFieldUsingAlreadyWrittenMesh(fname,f2) - f3=MEDCouplingFieldDouble(ON_NODES) ; f3.setTime(*t) ; f3.setMesh(m) - f3.setArray(DataArrayDouble([4.,2.,1.,4.,2.,1.],6,1)) - f3.setName(fieldName3) - MEDLoader.WriteFieldUsingAlreadyWrittenMesh(fname,f3) - ########## GO for reading in MEDReader,by not loading all. Mesh is fully loaded but not fields values - ms=MEDFileMeshes(fname) - fields=MEDFileFields(fname,False) - fields.removeFieldsWithoutAnyTimeStep() - fields_per_mesh=[fields.partOfThisLyingOnSpecifiedMeshName(meshName) for meshName in ms.getMeshesNames()] - allFMTSLeavesToDisplay=[] - for fields in fields_per_mesh: - allFMTSLeavesToDisplay2=[] - for fmts in fields: - tmp=fmts.splitDiscretizations() - for itmp in tmp: - self.assertTrue(not itmp.presenceOfMultiDiscPerGeoType()) - pass - allFMTSLeavesToDisplay2+=tmp - pass - allFMTSLeavesToDisplay.append(allFMTSLeavesToDisplay2) - pass - self.assertEqual(len(allFMTSLeavesToDisplay),1) - self.assertEqual(len(allFMTSLeavesToDisplay[0]),3) - allFMTSLeavesPerTimeSeries=MEDFileAnyTypeFieldMultiTS.SplitIntoCommonTimeSeries(sum(allFMTSLeavesToDisplay,[])) - self.assertEqual(len(allFMTSLeavesPerTimeSeries),1) - self.assertEqual(len(allFMTSLeavesPerTimeSeries[0]),3) - allFMTSLeavesPerCommonSupport1=MEDFileAnyTypeFieldMultiTS.SplitPerCommonSupport(allFMTSLeavesToDisplay[0],ms[ms.getMeshesNames()[0]]) - self.assertEqual(len(allFMTSLeavesPerCommonSupport1),1) - self.assertEqual(len(allFMTSLeavesPerCommonSupport1[0][0]),3) - # - mst=MEDFileMeshStruct.New(ms[0]) - # - fcscp=allFMTSLeavesPerCommonSupport1[0][1] - mml=fcscp.buildFromScratchDataSetSupport(0,fields) - mml2=mml.prepare() - self.assertTrue(isinstance(mml2,MEDUMeshMultiLev)) - ncc,a0,a1,a2,a3,a4,a5=mml2.buildVTUArrays() - self.assertTrue(not ncc) # spaceDim 2 -> VTK wants 3D - self.assertTrue(a0.isEqual(DataArrayDouble([0.,0.,0.,1.,0.,0.,2.,0.,0.,0.,1.,0.,1.,1.,0.,2.,1.,0.],6,3),1e-12)) - self.assertTrue(a1.isEqual(DataArrayByte([9,9]))) - self.assertTrue(a2.isEqual(DataArrayInt([0,5]))) - self.assertTrue(a3.isEqual(DataArrayInt([4,0,3,4,1,4,1,4,5,2]))) - self.assertTrue(a4 is None) - self.assertTrue(a5 is None) - a6,a7=mml2.retrieveFamilyIdsOnCells() - self.assertTrue(a6.isEqual(DataArrayInt([0,0]))) - self.assertTrue(a7) # no copy here - a8,a9=mml2.retrieveNumberIdsOnCells() - self.assertTrue(a8.isEqual(DataArrayInt([0,1]))) - self.assertTrue(a9) # no copy here - for i in xrange(1,2): - self.assertTrue((fcscp.isDataSetSupportEqualToThePreviousOne(i,fields))) - pass - vExp0=[DataArrayDouble([7.,11.]),DataArrayDouble([11.,7.])] - vExp1=[DataArrayDouble([3.,5.,7.,6.,2.,3.,11.,8.]),DataArrayDouble([7.,6.,3.,5.,11.,8.,2.,3.])] - for i in xrange(2): - f=allFMTSLeavesPerCommonSupport1[0][0][0][i] - fsst=MEDFileField1TSStructItem.BuildItemFrom(f,mst) - f.loadArraysIfNecessary() - v=mml.buildDataArray(fsst,fields,f.getUndergroundDataArray()) - self.assertEqual(f.getName(),fieldName2) - self.assertEqual(v.getHiddenCppPointer(),f.getUndergroundDataArray().getHiddenCppPointer()) - self.assertTrue(v.isEqual(vExp0[i],1e-12)) - # - f=allFMTSLeavesPerCommonSupport1[0][0][1][i] - fsst=MEDFileField1TSStructItem.BuildItemFrom(f,mst) - f.loadArraysIfNecessary() - v=mml.buildDataArray(fsst,fields,f.getUndergroundDataArray()) - self.assertEqual(f.getName(),fieldName1) - self.assertEqual(v.getHiddenCppPointer(),f.getUndergroundDataArray().getHiddenCppPointer()) - self.assertTrue(v.isEqual(vExp1[i],1e-12)) - pass - pass - - def test18(self): - """ First test on GAUSS_PT. Here no Profiles. 2 times steps. - """ - fname="ForMEDReader18.med" - fieldName1="MyFirstGauss" - fieldName2="ACellField" - fieldName3="ANodeField" - coo=DataArrayDouble([0.,0.,1.,0.,2.,0.,0.,1.,1.,1.,2.,1.],6,2) - m=MEDCouplingUMesh("mesh",2) - m.setCoords(coo) - m.allocateCells() - m.insertNextCell(NORM_QUAD4,[0,3,4,1]) - m.insertNextCell(NORM_QUAD4,[1,4,5,2]) - m.checkCoherency2() - # - t=(1.1,0,-1) - f=MEDCouplingFieldDouble(ON_GAUSS_PT) ; f.setTime(*t) ; f.setMesh(m) - f.setGaussLocalizationOnType(NORM_QUAD4,[-1.,-1.,1.,-1.,1.,1.,-1.,1.],[0.2,0.2,0.8,0.8],[0.7,0.3]) - f.setArray(DataArrayDouble([3.,5.,4.,6.])) ; f.getArray().setInfoOnComponents(["Smth"]) - f.setName(fieldName1) - f.checkCoherency() - MEDLoader.WriteField(fname,f,True) - f2=MEDCouplingFieldDouble(ON_CELLS) ; f2.setTime(*t) ; f2.setMesh(m) - f2.setArray(DataArrayDouble([7.,11.],2,1)) - f2.setName(fieldName2) - MEDLoader.WriteFieldUsingAlreadyWrittenMesh(fname,f2) - f3=MEDCouplingFieldDouble(ON_NODES) ; f3.setTime(*t) ; f3.setMesh(m) - f3.setArray(DataArrayDouble([1.,2.,4.,1.,2.,4.],6,1)) - f3.setName(fieldName3) - MEDLoader.WriteFieldUsingAlreadyWrittenMesh(fname,f3) - # - t=(2.1,1,-1) - f=MEDCouplingFieldDouble(ON_GAUSS_PT) ; f.setTime(*t) ; f.setMesh(m) - f.setGaussLocalizationOnType(NORM_QUAD4,[-1.,-1.,1.,-1.,1.,1.,-1.,1.],[0.2,0.2,0.8,0.8],[0.7,0.3]) - f.setArray(DataArrayDouble([5.,3.,6.,4.])) ; f.getArray().setInfoOnComponents(["Smth"]) - f.setName(fieldName1) - f.checkCoherency() - MEDLoader.WriteFieldUsingAlreadyWrittenMesh(fname,f) - f2=MEDCouplingFieldDouble(ON_CELLS) ; f2.setTime(*t) ; f2.setMesh(m) - f2.setArray(DataArrayDouble([11.,7.],2,1)) - f2.setName(fieldName2) - MEDLoader.WriteFieldUsingAlreadyWrittenMesh(fname,f2) - f3=MEDCouplingFieldDouble(ON_NODES) ; f3.setTime(*t) ; f3.setMesh(m) - f3.setArray(DataArrayDouble([4.,2.,1.,4.,2.,1.],6,1)) - f3.setName(fieldName3) - MEDLoader.WriteFieldUsingAlreadyWrittenMesh(fname,f3) - ########## GO for reading in MEDReader,by not loading all. Mesh is fully loaded but not fields values - ms=MEDFileMeshes(fname) - fields=MEDFileFields(fname,False) - fields.removeFieldsWithoutAnyTimeStep() - fields_per_mesh=[fields.partOfThisLyingOnSpecifiedMeshName(meshName) for meshName in ms.getMeshesNames()] - allFMTSLeavesToDisplay=[] - for fields in fields_per_mesh: - allFMTSLeavesToDisplay2=[] - for fmts in fields: - tmp=fmts.splitDiscretizations() - for itmp in tmp: - self.assertTrue(not itmp.presenceOfMultiDiscPerGeoType()) - pass - allFMTSLeavesToDisplay2+=tmp - pass - allFMTSLeavesToDisplay.append(allFMTSLeavesToDisplay2) - pass - self.assertEqual(len(allFMTSLeavesToDisplay),1) - self.assertEqual(len(allFMTSLeavesToDisplay[0]),3) - allFMTSLeavesPerTimeSeries=MEDFileAnyTypeFieldMultiTS.SplitIntoCommonTimeSeries(sum(allFMTSLeavesToDisplay,[])) - self.assertEqual(len(allFMTSLeavesPerTimeSeries),1) - self.assertEqual(len(allFMTSLeavesPerTimeSeries[0]),3) - allFMTSLeavesPerCommonSupport1=MEDFileAnyTypeFieldMultiTS.SplitPerCommonSupport(allFMTSLeavesToDisplay[0],ms[ms.getMeshesNames()[0]]) - self.assertEqual(len(allFMTSLeavesPerCommonSupport1),1) - self.assertEqual(len(allFMTSLeavesPerCommonSupport1[0][0]),3) - # - mst=MEDFileMeshStruct.New(ms[0]) - # - fcscp=allFMTSLeavesPerCommonSupport1[0][1] - self.assertEqual([NORM_QUAD4],fcscp.getGeoTypesAt(0,ms[0])) - mml=fcscp.buildFromScratchDataSetSupport(0,fields) - mml2=mml.prepare() - self.assertTrue(isinstance(mml2,MEDUMeshMultiLev)) - ncc,a0,a1,a2,a3,a4,a5=mml2.buildVTUArrays() - self.assertTrue(not ncc) # spaceDim 2 -> VTK wants 3D - self.assertTrue(a0.isEqual(DataArrayDouble([0.,0.,0.,1.,0.,0.,2.,0.,0.,0.,1.,0.,1.,1.,0.,2.,1.,0.],6,3),1e-12)) - self.assertTrue(a1.isEqual(DataArrayByte([9,9]))) - self.assertTrue(a2.isEqual(DataArrayInt([0,5]))) - self.assertTrue(a3.isEqual(DataArrayInt([4,0,3,4,1,4,1,4,5,2]))) - self.assertTrue(a4 is None) - self.assertTrue(a5 is None) - a6,a7=mml2.retrieveFamilyIdsOnCells() - self.assertTrue(a6.isEqual(DataArrayInt([0,0]))) - self.assertTrue(a7) # no copy here - a8,a9=mml2.retrieveNumberIdsOnCells() - self.assertTrue(a8.isEqual(DataArrayInt([0,1]))) - self.assertTrue(a9) # no copy here - for i in xrange(1,2): - self.assertTrue((fcscp.isDataSetSupportEqualToThePreviousOne(i,fields))) - pass - vExp0=[DataArrayDouble([7.,11.]),DataArrayDouble([11.,7.])] - vExp1=[DataArrayDouble([3.,5.,4.,6.]),DataArrayDouble([5.,3.,6.,4.])] - for i in xrange(2): - f=allFMTSLeavesPerCommonSupport1[0][0][0][i] - fsst=MEDFileField1TSStructItem.BuildItemFrom(f,mst) - f.loadArraysIfNecessary() - v=mml.buildDataArray(fsst,fields,f.getUndergroundDataArray()) - self.assertEqual(f.getName(),fieldName2) - self.assertEqual(v.getHiddenCppPointer(),f.getUndergroundDataArray().getHiddenCppPointer()) - self.assertTrue(v.isEqual(vExp0[i],1e-12)) - # - f=allFMTSLeavesPerCommonSupport1[0][0][1][i] - fsst=MEDFileField1TSStructItem.BuildItemFrom(f,mst) - f.loadArraysIfNecessary() - v=mml.buildDataArray(fsst,fields,f.getUndergroundDataArray()) - self.assertEqual(f.getName(),fieldName1) - self.assertEqual(v.getHiddenCppPointer(),f.getUndergroundDataArray().getHiddenCppPointer()) - vExp1[i].setInfoOnComponents(["Smth"]) - self.assertTrue(v.isEqual(vExp1[i],1e-12)) - pass - ## Now same exercise but with a different load strategy. All is load directly. - ms=MEDFileMeshes(fname) - fields=MEDFileFields(fname) # here all is read, the SauvReader (or other Reader) is emulated - fields_per_mesh=[fields.partOfThisLyingOnSpecifiedMeshName(meshName) for meshName in ms.getMeshesNames()] - allFMTSLeavesToDisplay=[] - for fields in fields_per_mesh: - allFMTSLeavesToDisplay2=[] - for fmts in fields: - tmp=fmts.splitDiscretizations() - for itmp in tmp: - self.assertTrue(not itmp.presenceOfMultiDiscPerGeoType()) - pass - allFMTSLeavesToDisplay2+=tmp - pass - allFMTSLeavesToDisplay.append(allFMTSLeavesToDisplay2) - pass - self.assertEqual(len(allFMTSLeavesToDisplay),1) - self.assertEqual(len(allFMTSLeavesToDisplay[0]),3) - allFMTSLeavesPerTimeSeries=MEDFileAnyTypeFieldMultiTS.SplitIntoCommonTimeSeries(sum(allFMTSLeavesToDisplay,[])) - self.assertEqual(len(allFMTSLeavesPerTimeSeries),1) - self.assertEqual(len(allFMTSLeavesPerTimeSeries[0]),3) - allFMTSLeavesPerCommonSupport1=MEDFileAnyTypeFieldMultiTS.SplitPerCommonSupport(allFMTSLeavesToDisplay[0],ms[ms.getMeshesNames()[0]]) - self.assertEqual(len(allFMTSLeavesPerCommonSupport1),1) - self.assertEqual(len(allFMTSLeavesPerCommonSupport1[0][0]),3) - # - mst=MEDFileMeshStruct.New(ms[0]) - # - fcscp=allFMTSLeavesPerCommonSupport1[0][1] - mml=fcscp.buildFromScratchDataSetSupport(0,fields) - mml2=mml.prepare() - self.assertTrue(isinstance(mml2,MEDUMeshMultiLev)) - ncc,a0,a1,a2,a3,a4,a5=mml2.buildVTUArrays() - self.assertTrue(not ncc) # spaceDim 2 -> VTK wants 3D - self.assertTrue(a0.isEqual(DataArrayDouble([0.,0.,0.,1.,0.,0.,2.,0.,0.,0.,1.,0.,1.,1.,0.,2.,1.,0.],6,3),1e-12)) - self.assertTrue(a1.isEqual(DataArrayByte([9,9]))) - self.assertTrue(a2.isEqual(DataArrayInt([0,5]))) - self.assertTrue(a3.isEqual(DataArrayInt([4,0,3,4,1,4,1,4,5,2]))) - self.assertTrue(a4 is None) - self.assertTrue(a5 is None) - a6,a7=mml2.retrieveFamilyIdsOnCells() - self.assertTrue(a6.isEqual(DataArrayInt([0,0]))) - self.assertTrue(a7) # no copy here - a8,a9=mml2.retrieveNumberIdsOnCells() - self.assertTrue(a8.isEqual(DataArrayInt([0,1]))) - self.assertTrue(a9) # no copy here - for i in xrange(1,2): - self.assertTrue((fcscp.isDataSetSupportEqualToThePreviousOne(i,fields))) - pass - vExp0=[DataArrayDouble([7.,11.]),DataArrayDouble([11.,7.])] - vExp1=[DataArrayDouble([3.,5.,4.,6.]),DataArrayDouble([5.,3.,6.,4.])] - for i in xrange(2): - f=allFMTSLeavesPerCommonSupport1[0][0][0][i] - fsst=MEDFileField1TSStructItem.BuildItemFrom(f,mst) # no load needed here - v=mml.buildDataArray(fsst,fields,f.getUndergroundDataArray()) - self.assertEqual(f.getName(),fieldName2) - self.assertEqual(v.getHiddenCppPointer(),f.getUndergroundDataArray().getHiddenCppPointer()) - self.assertTrue(v.isEqual(vExp0[i],1e-12)) - # - f=allFMTSLeavesPerCommonSupport1[0][0][1][i] - fsst=MEDFileField1TSStructItem.BuildItemFrom(f,mst) # no load needed here - v=mml.buildDataArray(fsst,fields,f.getUndergroundDataArray()) - self.assertEqual(f.getName(),fieldName1) - self.assertEqual(v.getHiddenCppPointer(),f.getUndergroundDataArray().getHiddenCppPointer()) - vExp1[i].setInfoOnComponents(["Smth"]) - self.assertTrue(v.isEqual(vExp1[i],1e-12)) - pass - pass - - def test19(self): - """ - This test is a simple non profile CELL field but lying on cells of dimension -1 (not 0 as "usual"). - """ - fname="ForMEDReader19.med" - fieldName="ACellFieldOnDimM1" - coo=DataArrayDouble(3) ; coo.iota() - m=MEDCouplingCMesh() ; m.setCoords(coo,coo,coo) ; m.setName("mesh") - m0=m.buildUnstructured() ; del m - m1=m0.computeSkin() - # - mm=MEDFileUMesh() - mm.setMeshAtLevel(0,m0) - mm.setMeshAtLevel(-1,m1) - ff=MEDFileFieldMultiTS() - # time 0 - t=(1.1,1,-1) - f=MEDCouplingFieldDouble(ON_CELLS) ; f.setTime(*t) ; f.setMesh(m1) - f.setName(fieldName) - arr=DataArrayDouble(24) ; arr.iota() ; arr.setInfoOnComponents(["AStr"]) - f.setArray(arr) - f.checkCoherency() - f1ts=MEDFileField1TS() ; f1ts.setFieldNoProfileSBT(f) - ff.pushBackTimeStep(f1ts) - # time 1 - t=(2.1,2,-2) - f=MEDCouplingFieldDouble(ON_CELLS) ; f.setTime(*t) ; f.setMesh(m1) - f.setName(fieldName) - arr=DataArrayDouble(24) ; arr.iota() ; arr.reverse() ; arr.setInfoOnComponents(["AStr"]) - f.setArray(arr) - f.checkCoherency() - f1ts=MEDFileField1TS() ; f1ts.setFieldNoProfileSBT(f) - ff.pushBackTimeStep(f1ts) - # - mm.write(fname,2) - ff.write(fname,0) - ########## GO for reading in MEDReader,by not loading all. Mesh is fully loaded but not fields values - ms=MEDFileMeshes(fname) - fields=MEDFileFields(fname,False) - fields.removeFieldsWithoutAnyTimeStep() - fields_per_mesh=[fields.partOfThisLyingOnSpecifiedMeshName(meshName) for meshName in ms.getMeshesNames()] - allFMTSLeavesToDisplay=[] - for fields in fields_per_mesh: - allFMTSLeavesToDisplay2=[] - for fmts in fields: - tmp=fmts.splitDiscretizations() - for itmp in tmp: - self.assertTrue(not itmp.presenceOfMultiDiscPerGeoType()) - pass - allFMTSLeavesToDisplay2+=tmp - pass - allFMTSLeavesToDisplay.append(allFMTSLeavesToDisplay2) - pass - self.assertEqual(len(allFMTSLeavesToDisplay),1) - self.assertEqual(len(allFMTSLeavesToDisplay[0]),1) - allFMTSLeavesPerTimeSeries=MEDFileAnyTypeFieldMultiTS.SplitIntoCommonTimeSeries(sum(allFMTSLeavesToDisplay,[])) - self.assertEqual(len(allFMTSLeavesPerTimeSeries),1) - self.assertEqual(len(allFMTSLeavesPerTimeSeries[0]),1) - allFMTSLeavesPerCommonSupport1=MEDFileAnyTypeFieldMultiTS.SplitPerCommonSupport(allFMTSLeavesToDisplay[0],ms[ms.getMeshesNames()[0]]) - self.assertEqual(len(allFMTSLeavesPerCommonSupport1),1) - self.assertEqual(len(allFMTSLeavesPerCommonSupport1[0][0]),1) - # - mst=MEDFileMeshStruct.New(ms[0]) - # - fcscp=allFMTSLeavesPerCommonSupport1[0][1] - mml=fcscp.buildFromScratchDataSetSupport(0,fields) - mml2=mml.prepare() - self.assertTrue(isinstance(mml2,MEDUMeshMultiLev)) - ncc,a0,a1,a2,a3,a4,a5=mml2.buildVTUArrays() - self.assertTrue(ncc) - self.assertTrue(a0.isEqual(DataArrayDouble([0.,0.,0.,1.,0.,0.,2.,0.,0.,0.,1.,0.,1.,1.,0.,2.,1.,0.,0.,2.,0.,1.,2.,0.,2.,2.,0.,0.,0.,1.,1.,0.,1.,2.,0.,1.,0.,1.,1.,1.,1.,1.,2.,1.,1.,0.,2.,1.,1.,2.,1.,2.,2.,1.,0.,0.,2.,1.,0.,2.,2.,0.,2.,0.,1.,2.,1.,1.,2.,2.,1.,2.,0.,2.,2.,1.,2.,2.,2.,2.,2.],27,3),1e-12)) - self.assertTrue(a1.isEqual(DataArrayByte([9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9]))) - self.assertTrue(a2.isEqual(DataArrayInt([0,5,10,15,20,25,30,35,40,45,50,55,60,65,70,75,80,85,90,95,100,105,110,115]))) - self.assertTrue(a3.isEqual(DataArrayInt([4,1,0,3,4,4,1,10,9,0,4,0,9,12,3,4,2,1,4,5,4,2,11,10,1,4,5,14,11,2,4,4,3,6,7,4,3,12,15,6,4,6,15,16,7,4,5,4,7,8,4,7,16,17,8,4,8,17,14,5,4,19,22,21,18,4,10,19,18,9,4,9,18,21,12,4,20,23,22,19,4,11,20,19,10,4,14,23,20,11,4,22,25,24,21,4,12,21,24,15,4,15,24,25,16,4,23,26,25,22,4,16,25,26,17,4,17,26,23,14]))) - self.assertTrue(a4 is None) - self.assertTrue(a5 is None) - a6,a7=mml2.retrieveFamilyIdsOnCells() - self.assertTrue(a6.isEqual(DataArrayInt([0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]))) - self.assertTrue(a7) # no copy here - a8,a9=mml2.retrieveNumberIdsOnCells() - self.assertTrue(a8 is None) - self.assertTrue(a9) # no copy here - a10,a11=mml2.retrieveFamilyIdsOnNodes() - self.assertTrue(not a10) - self.assertTrue(a11) # no copy here - a12,a13=mml2.retrieveNumberIdsOnNodes() - self.assertTrue(not a12) - self.assertTrue(a13) # no copy here - for i in xrange(1,2): - self.assertTrue((fcscp.isDataSetSupportEqualToThePreviousOne(i,fields))) - pass - for i in xrange(2): - f=allFMTSLeavesPerCommonSupport1[0][0][0][i] - fsst=MEDFileField1TSStructItem.BuildItemFrom(f,mst) - f.loadArraysIfNecessary() - v=mml.buildDataArray(fsst,fields,f.getUndergroundDataArray()) - self.assertEqual(f.getName(),fieldName) - self.assertEqual(v.getHiddenCppPointer(),f.getUndergroundDataArray().getHiddenCppPointer()) - vExp=DataArrayDouble(24) ; vExp.iota() - if i==1: vExp.reverse() - vExp.setInfoOnComponents(["AStr"]) - self.assertTrue(v.isEqual(vExp,1e-12)) - pass - pass - - def test20(self): - """ This test works with groups/families on cells AND on nodes. Here 4 fields each on same time steps (2). - 1 field on CELLS without profile, 1 field on CELLS with profile, 1 field on NODES without profile, 1 field on NODES with profile. - All of these 4 fields lies on a single mesh "mesh". The 2 fields on profile lies on a same support. - One drawback of this test : no multi geom type. Coming soon ! - """ - fname="ForMEDReader20.med" - fieldName0="ANodeField" - fieldName1="ACellField" - fieldName2="ANodeFieldPfl" - fieldName3="ACellFieldPfl" - pfl2=DataArrayInt([5,6,7,10,11,12,15,16,17,20,21,22]) ; pfl2.setName("pfl2") - pfl3=DataArrayInt([4,5,8,9,12,13]) ; pfl3.setName("pfl3") - # - arr=DataArrayDouble(5) ; arr.iota() - m=MEDCouplingCMesh("mesh") ; m.setCoords(arr,arr) - m=m.buildUnstructured() - mm=MEDFileUMesh() - mm.setMeshAtLevel(0,m) - fs=MEDFileFields() - fmts0=MEDFileFieldMultiTS() ; fs.pushField(fmts0) - fmts0.setDtUnit("s") - fmts1=MEDFileFieldMultiTS() ; fs.pushField(fmts1) - fmts1.setDtUnit("s") - fmts2=MEDFileFieldMultiTS() ; fs.pushField(fmts2) - fmts2.setDtUnit("s") - fmts3=MEDFileFieldMultiTS() ; fs.pushField(fmts3) - fmts3.setDtUnit("s") - #### - t=(1.1,0,-2) - f0=MEDCouplingFieldDouble(ON_NODES) ; f0.setMesh(m) - f0.setName(fieldName0) ; f0.setTime(*t) - da=m.getCoords().magnitude() ; da.setInfoOnComponents(["zeInfo"]) - f0.setArray(da) - f0.checkCoherency() - f1ts=MEDFileField1TS() - f1ts.setFieldNoProfileSBT(f0) - fmts0.pushBackTimeStep(f1ts) - # - f1=MEDCouplingFieldDouble(ON_CELLS) ; f1.setMesh(m) - f1.setName(fieldName1) ; f1.setTime(*t) - da=m.getBarycenterAndOwner().magnitude() ; da.setInfoOnComponents(["zeInfoCell"]) - f1.setArray(da) - f1.checkCoherency() - f1ts=MEDFileField1TS() - f1ts.setFieldNoProfileSBT(f1) - fmts1.pushBackTimeStep(f1ts) - # - f2=MEDCouplingFieldDouble(ON_NODES) ; mTmp=m[pfl3] ; mTmp.zipCoords() ; mTmp.setName(m.getName()) ; f2.setMesh(mTmp) - f2.setName(fieldName2) ; f2.setTime(*t) - da=m.getCoords().magnitude()[pfl2] ; da.setInfoOnComponents(["zzzz"]) - f2.setArray(da) - f2.checkCoherency() - f1ts=MEDFileField1TS() - f1ts.setFieldProfile(f2,mm,0,pfl2) - fmts2.pushBackTimeStep(f1ts) - # - f3=MEDCouplingFieldDouble(ON_CELLS) ; mTmp=m[pfl3] ; mTmp.setName(m.getName()) ; f3.setMesh(mTmp) - f3.setName(fieldName3) ; f3.setTime(*t) - da=mTmp.getBarycenterAndOwner().magnitude() ; da.setInfoOnComponents(["abcdefg"]) - f3.setArray(da) - f3.checkCoherency() - f1ts=MEDFileField1TS() - f1ts.setFieldProfile(f3,mm,0,pfl3) - fmts3.pushBackTimeStep(f1ts) - #### - t=(2.1,1,-3) - f0=MEDCouplingFieldDouble(ON_NODES) ; f0.setMesh(m) - f0.setName(fieldName0) ; f0.setTime(*t) - da=m.getCoords().magnitude() ; da.reverse() ; da.setInfoOnComponents(["zeInfo"]) - f0.setArray(da) - f0.checkCoherency() - f1ts=MEDFileField1TS() - f1ts.setFieldNoProfileSBT(f0) - fmts0.pushBackTimeStep(f1ts) - # - f1=MEDCouplingFieldDouble(ON_CELLS) ; f1.setMesh(m) - f1.setName(fieldName1) ; f1.setTime(*t) - da=m.getBarycenterAndOwner().magnitude() ; da.reverse() ; da.setInfoOnComponents(["zeInfoCell"]) - f1.setArray(da) - f1.checkCoherency() - f1ts=MEDFileField1TS() - f1ts.setFieldNoProfileSBT(f1) - fmts1.pushBackTimeStep(f1ts) - # - f2=MEDCouplingFieldDouble(ON_NODES) ; mTmp=m[pfl3] ; mTmp.zipCoords() ; mTmp.setName(m.getName()) ; f2.setMesh(mTmp) - f2.setName(fieldName2) ; f2.setTime(*t) - da=m.getCoords().magnitude()[pfl2] ; da.reverse() ; da.setInfoOnComponents(["zzzz"]) - f2.setArray(da) - f2.checkCoherency() - f1ts=MEDFileField1TS() - f1ts.setFieldProfile(f2,mm,0,pfl2) - fmts2.pushBackTimeStep(f1ts) - # - f3=MEDCouplingFieldDouble(ON_CELLS) ; mTmp=m[pfl3] ; mTmp.setName(m.getName()) ; f3.setMesh(mTmp) - f3.setName(fieldName3) ; f3.setTime(*t) - da=mTmp.getBarycenterAndOwner().magnitude() ; da.reverse() ; da.setInfoOnComponents(["abcdefg"]) - f3.setArray(da) - f3.checkCoherency() - f1ts=MEDFileField1TS() - f1ts.setFieldProfile(f3,mm,0,pfl3) - fmts3.pushBackTimeStep(f1ts) - #### - grp1=DataArrayInt([6,7,8,11,12,13,16,17,18]) ; grp1.setName("grp1") - grp2=DataArrayInt([10,11,15,16,20,21]) ; grp2.setName("grp2") - mm.setGroupsAtLevel(1,[grp1,grp2]) - grp3=DataArrayInt([4,5,6]) ; grp3.setName("grp3") - grp4=DataArrayInt([8,9,10]) ; grp4.setName("grp4") - mm.setGroupsAtLevel(0,[grp3,grp4]) - d=DataArrayInt(25) ; d.iota() ; d*=10 ; mm.setRenumFieldArr(1,d) - d=DataArrayInt(16) ; d.iota() ; d*=11 ; mm.setRenumFieldArr(0,d) - mm.write(fname,2) - fs.appendGlobs(fmts2,1e-12) - fs.appendGlobs(fmts3,1e-12) - fs.write(fname,0) - ########## GO for reading in MEDReader,by not loading all. Mesh is fully loaded but not fields values - ms=MEDFileMeshes(fname) - fields=MEDFileFields(fname,False) - fields.removeFieldsWithoutAnyTimeStep() - fields_per_mesh=[fields.partOfThisLyingOnSpecifiedMeshName(meshName) for meshName in ms.getMeshesNames()] - allFMTSLeavesToDisplay=[] - for fields in fields_per_mesh: - allFMTSLeavesToDisplay2=[] - for fmts in fields: - tmp=fmts.splitDiscretizations() - for itmp in tmp: - self.assertTrue(not itmp.presenceOfMultiDiscPerGeoType()) - pass - allFMTSLeavesToDisplay2+=tmp - pass - allFMTSLeavesToDisplay.append(allFMTSLeavesToDisplay2) - pass - self.assertEqual(len(allFMTSLeavesToDisplay),1) - self.assertEqual(len(allFMTSLeavesToDisplay[0]),4) - allFMTSLeavesPerTimeSeries=MEDFileAnyTypeFieldMultiTS.SplitIntoCommonTimeSeries(sum(allFMTSLeavesToDisplay,[])) - self.assertEqual(len(allFMTSLeavesPerTimeSeries),1) - self.assertEqual(len(allFMTSLeavesPerTimeSeries[0]),4) - allFMTSLeavesPerCommonSupport1=MEDFileAnyTypeFieldMultiTS.SplitPerCommonSupport(allFMTSLeavesToDisplay[0],ms[ms.getMeshesNames()[0]]) - self.assertEqual(len(allFMTSLeavesPerCommonSupport1),2) - self.assertEqual(len(allFMTSLeavesPerCommonSupport1[0][0]),2) - self.assertEqual(len(allFMTSLeavesPerCommonSupport1[1][0]),2) - # - mst=MEDFileMeshStruct.New(ms[0]) - # - fcscp=allFMTSLeavesPerCommonSupport1[0][1] - mml=fcscp.buildFromScratchDataSetSupport(0,fields) - mml2=mml.prepare() - self.assertTrue(isinstance(mml2,MEDUMeshMultiLev)) - ncc,a0,a1,a2,a3,a4,a5=mml2.buildVTUArrays() - self.assertTrue(not ncc) - self.assertTrue(a0.isEqual(DataArrayDouble([0.,0.,0.,1.,0.,0.,2.,0.,0.,3.,0.,0.,4.,0.,0.,0.,1.,0.,1.,1.,0.,2.,1.,0.,3.,1.,0.,4.,1.,0.,0.,2.,0.,1.,2.,0.,2.,2.,0.,3.,2.,0.,4.,2.,0.,0.,3.,0.,1.,3.,0.,2.,3.,0.,3.,3.,0.,4.,3.,0.,0.,4.,0.,1.,4.,0.,2.,4.,0.,3.,4.,0.,4.,4.,0.],25,3),1e-12)) - self.assertTrue(a1.isEqual(DataArrayByte([9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9]))) - self.assertTrue(a2.isEqual(DataArrayInt([0,5,10,15,20,25,30,35,40,45,50,55,60,65,70,75]))) - self.assertTrue(a3.isEqual(DataArrayInt([4,1,0,5,6,4,2,1,6,7,4,3,2,7,8,4,4,3,8,9,4,6,5,10,11,4,7,6,11,12,4,8,7,12,13,4,9,8,13,14,4,11,10,15,16,4,12,11,16,17,4,13,12,17,18,4,14,13,18,19,4,16,15,20,21,4,17,16,21,22,4,18,17,22,23,4,19,18,23,24]))) - self.assertTrue(a4 is None) - self.assertTrue(a5 is None) - a6,a7=mml2.retrieveFamilyIdsOnCells() - self.assertTrue(a6.isEqual(DataArrayInt([-5,-5,-5,-5,-6,-6,-6,-5,-7,-7,-7,-5,-5,-5,-5,-5]))) - self.assertTrue(a7) # no copy here - a8,a9=mml2.retrieveNumberIdsOnCells() - self.assertTrue(a8.isEqual(DataArrayInt([0,11,22,33,44,55,66,77,88,99,110,121,132,143,154,165]))) - self.assertTrue(a9) # no copy here - a10,a11=mml2.retrieveFamilyIdsOnNodes() - self.assertTrue(a10.isEqual(DataArrayInt([1,1,1,1,1,1,2,2,2,1,3,4,2,2,1,3,4,2,2,1,3,3,1,1,1]))) - self.assertTrue(a11) # no copy here - a12,a13=mml2.retrieveNumberIdsOnNodes() - self.assertTrue(a12.isEqual(DataArrayInt([0,10,20,30,40,50,60,70,80,90,100,110,120,130,140,150,160,170,180,190,200,210,220,230,240]))) - self.assertTrue(a13) # no copy here - for i in xrange(1,2): - self.assertTrue((fcscp.isDataSetSupportEqualToThePreviousOne(i,fields))) - pass - for i in xrange(2): - f=allFMTSLeavesPerCommonSupport1[0][0][0][i] - fsst=MEDFileField1TSStructItem.BuildItemFrom(f,mst) - f.loadArraysIfNecessary() - v=mml.buildDataArray(fsst,fields,f.getUndergroundDataArray()) - self.assertEqual(f.getName(),fieldName1) - self.assertEqual(v.getHiddenCppPointer(),f.getUndergroundDataArray().getHiddenCppPointer()) - vExp=DataArrayDouble([0.7071067811865476,1.5811388300841898,2.5495097567963922,3.5355339059327378,1.5811388300841898,2.1213203435596424,2.9154759474226504,3.8078865529319543,2.5495097567963922,2.9154759474226504,3.5355339059327378,4.301162633521313,3.5355339059327378,3.8078865529319543,4.301162633521313,4.949747468305833]) - if i==1: vExp.reverse() - vExp.setInfoOnComponents(["zeInfoCell"]) - self.assertTrue(v.isEqual(vExp,1e-12)) - # - f=allFMTSLeavesPerCommonSupport1[0][0][1][i] - fsst=MEDFileField1TSStructItem.BuildItemFrom(f,mst) - f.loadArraysIfNecessary() - v=mml.buildDataArray(fsst,fields,f.getUndergroundDataArray()) - self.assertEqual(f.getName(),fieldName0) - self.assertEqual(v.getHiddenCppPointer(),f.getUndergroundDataArray().getHiddenCppPointer()) - vExp=DataArrayDouble([0.,1.,2.,3.,4.,1.,1.4142135623730951,2.23606797749979,3.1622776601683795,4.123105625617661,2.,2.23606797749979,2.8284271247461903,3.605551275463989,4.47213595499958,3.,3.1622776601683795,3.605551275463989,4.242640687119285,5.,4.,4.123105625617661,4.47213595499958,5.,5.656854249492381]) - if i==1: vExp.reverse() - vExp.setInfoOnComponents(["zeInfo"]) - self.assertTrue(v.isEqual(vExp,1e-12)) - pass - ### Testing the 2nd support - fcscp=allFMTSLeavesPerCommonSupport1[1][1] - mml=fcscp.buildFromScratchDataSetSupport(0,fields) - mml2=mml.prepare() - self.assertTrue(isinstance(mml2,MEDUMeshMultiLev)) - ncc,a0,a1,a2,a3,a4,a5=mml2.buildVTUArrays() - self.assertTrue(not ncc) - self.assertTrue(not ncc) - self.assertTrue(a0.isEqual(DataArrayDouble([0.,1.,0.,1.,1.,0.,2.,1.,0.,0.,2.,0.,1.,2.,0.,2.,2.,0.,0.,3.,0.,1.,3.,0.,2.,3.,0.,0.,4.,0.,1.,4.,0.,2.,4.,0.],12,3),1e-12)) - self.assertTrue(a1.isEqual(DataArrayByte([9,9,9,9,9,9]))) - self.assertTrue(a2.isEqual(DataArrayInt([0,5,10,15,20,25]))) - self.assertTrue(a3.isEqual(DataArrayInt([4,1,0,3,4,4,2,1,4,5,4,4,3,6,7,4,5,4,7,8,4,7,6,9,10,4,8,7,10,11]))) - self.assertTrue(a4 is None) - self.assertTrue(a5 is None) - a6,a7=mml2.retrieveFamilyIdsOnCells() - self.assertTrue(a6.isEqual(DataArrayInt([-6,-6,-7,-7,-5,-5]))) - self.assertTrue(not a7) # copy here - a8,a9=mml2.retrieveNumberIdsOnCells() - self.assertTrue(a8.isEqual(DataArrayInt([44,55,88,99,132,143]))) - self.assertTrue(not a9) # copy here - a10,a11=mml2.retrieveFamilyIdsOnNodes() - self.assertTrue(a10.isEqual(DataArrayInt([1,2,2,3,4,2,3,4,2,3,3,1]))) - self.assertTrue(not a11) # copy here - a12,a13=mml2.retrieveNumberIdsOnNodes() - self.assertTrue(a12.isEqual(DataArrayInt([50,60,70,100,110,120,150,160,170,200,210,220]))) - self.assertTrue(not a13) # copy here - for i in xrange(2): - f=allFMTSLeavesPerCommonSupport1[1][0][0][i] - fsst=MEDFileField1TSStructItem.BuildItemFrom(f,mst) - f.loadArraysIfNecessary() - v=mml.buildDataArray(fsst,fields,f.getUndergroundDataArray()) - self.assertEqual(f.getName(),fieldName3) - self.assertEqual(v.getHiddenCppPointer(),f.getUndergroundDataArray().getHiddenCppPointer()) - vExp=DataArrayDouble([1.5811388300842,2.1213203435596,2.5495097567964,2.9154759474227,3.5355339059327,3.807886552932]) - if i==1: vExp.reverse() - vExp.setInfoOnComponents(["abcdefg"]) - self.assertTrue(v.isEqual(vExp,1e-12)) - # - f=allFMTSLeavesPerCommonSupport1[1][0][1][i] - fsst=MEDFileField1TSStructItem.BuildItemFrom(f,mst) - f.loadArraysIfNecessary() - v=mml.buildDataArray(fsst,fields,f.getUndergroundDataArray()) - self.assertEqual(f.getName(),fieldName2) - self.assertEqual(v.getHiddenCppPointer(),f.getUndergroundDataArray().getHiddenCppPointer()) - vExp=DataArrayDouble([1.,1.4142135623731,2.2360679774998,2.,2.2360679774998,2.8284271247462,3.,3.1622776601684,3.605551275464,4.,4.1231056256177,4.4721359549996]) - if i==1: vExp.reverse() - vExp.setInfoOnComponents(["zzzz"]) - self.assertTrue(v.isEqual(vExp,1e-12)) - pass - pass - - def test21(self): - """ Here the created MED file contains only a mesh. The aim here is to test capability of MEDReader to support no fields. - This test checks nothing but write a MED file to be used by MEDReader tests. - """ - fname="ForMEDReader21.med" - mm=MEDFileUMesh() - # - m0=MEDCouplingCMesh("mesh") ; arr=DataArrayDouble(5) ; arr.iota() ; m0.setCoords(arr,arr) ; m0=m0.buildUnstructured() - mm.setMeshAtLevel(0,m0) - grp0=DataArrayInt([5,6,9,10]) ; grp0.setName("Inside2D") - grp1=DataArrayInt([0,1,2,3,4,7,8,11,12,13,14,15]) ; grp1.setName("Border2D") - grp2=DataArrayInt([2,3,6,7]) ; grp2.setName("LowerRight2D") - mm.setGroupsAtLevel(0,[grp0,grp1,grp2]) - # - m1=MEDCouplingUMesh(m0.getName(),1) ; m1.setCoords(m0.getCoords()) ; m1.allocateCells() - for elt in [[0,1],[1,2],[2,3],[3,4],[4,9],[9,14],[14,19],[19,24],[24,23],[23,22],[22,21],[21,20],[20,15],[15,10],[10,5],[5,0],[2,7],[7,12],[12,17],[17,22], - [10,11],[11,12],[12,13],[13,14]]: - m1.insertNextCell(NORM_SEG2,elt) - pass - mm.setMeshAtLevel(-1,m1) - grp4=DataArrayInt([0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15]) ; grp4.setName("Border1D") - grp5=DataArrayInt([16,17,18,19,20,21,22,23]) ; grp5.setName("Inside1D") - grp6=DataArrayInt([18,19,22,23]) ; grp6.setName("UpperRight1D") - mm.setGroupsAtLevel(-1,[grp4,grp5,grp6]) - # - grp7=DataArrayInt([1,2,3,6,7,8,11,12,13,16,17,18,21,22,23]) ; grp7.setName("InsideYNode") - grp8=DataArrayInt([5,6,7,8,9,10,11,12,13,14,15,16,17,18,19]) ; grp8.setName("InsideXNode") - mm.setGroupsAtLevel(1,[grp7,grp8]) - # - mm.write(fname,2) - pass - - def test22(self): - """ Use case where a field on nodes (ANodeField) on a mesh defined both in meshdim 2 and meshdim 1. - The only possible geometrical support that suits the field is those with meshdim equal to 1 (-1 in relative). - """ - fname="ForMEDReader22.med" - fieldName0="ANodeField" - mm=MEDFileUMesh() - coo=DataArrayDouble([(4.,3.),(7.,3.),(2.,5.),(6.,5.),(9.,5.),(4.,7.),(8.,7.),(3.,8.),(9.,8.)]) - m0=MEDCouplingUMesh("mesh",2) ; m0.setCoords(coo) ; m0.allocateCells() ; m0.insertNextCell(NORM_TRI3,[2,3,0]) ; m0.insertNextCell(NORM_TRI3,[3,1,0]) ; m0.insertNextCell(NORM_TRI3,[3,4,1]) - mm.setMeshAtLevel(0,m0) - m1=MEDCouplingUMesh("mesh",1) ; m1.setCoords(coo) ; m1.allocateCells() ; m1.insertNextCell(NORM_SEG2,[2,0]) ; m1.insertNextCell(NORM_SEG2,[0,1]) ; m1.insertNextCell(NORM_SEG2,[1,4]) - m1.insertNextCell(NORM_SEG2,[3,5]) ; m1.insertNextCell(NORM_SEG2,[5,7]) ; m1.insertNextCell(NORM_SEG2,[3,6]) ; m1.insertNextCell(NORM_SEG2,[6,8]) - mm.setMeshAtLevel(-1,m1) - fs=MEDFileFields() - fmts0=MEDFileFieldMultiTS() ; fs.pushField(fmts0) - fmts0.setDtUnit("s") - # - t=(1.1,0,-2) - f0=MEDCouplingFieldDouble(ON_NODES) ; f0.setMesh(m1) - f0.setName(fieldName0) ; f0.setTime(*t) - da=DataArrayDouble(9) ; da.iota() ; da.setInfoOnComponents(["zeInfo"]) - f0.setArray(da) - f0.checkCoherency() - f1ts=MEDFileField1TS() - f1ts.setFieldNoProfileSBT(f0) - fmts0.pushBackTimeStep(f1ts) - # - t=(2.1,1,-3) - f0=MEDCouplingFieldDouble(ON_NODES) ; f0.setMesh(m1) - f0.setName(fieldName0) ; f0.setTime(*t) - da=DataArrayDouble(9) ; da.iota() ; da.reverse() ; da.setInfoOnComponents(["zeInfo"]) - f0.setArray(da) - f0.checkCoherency() - f1ts=MEDFileField1TS() - f1ts.setFieldNoProfileSBT(f0) - fmts0.pushBackTimeStep(f1ts) - # - mm.write(fname,2) - fs.write(fname,0) - ########## GO for reading in MEDReader,by not loading all. Mesh is fully loaded but not fields values - ms=MEDFileMeshes(fname) - fields=MEDFileFields(fname,False) - fields.removeFieldsWithoutAnyTimeStep() - fields_per_mesh=[fields.partOfThisLyingOnSpecifiedMeshName(meshName) for meshName in ms.getMeshesNames()] - allFMTSLeavesToDisplay=[] - for fields in fields_per_mesh: - allFMTSLeavesToDisplay2=[] - for fmts in fields: - tmp=fmts.splitDiscretizations() - for itmp in tmp: - self.assertTrue(not itmp.presenceOfMultiDiscPerGeoType()) - pass - allFMTSLeavesToDisplay2+=tmp - pass - allFMTSLeavesToDisplay.append(allFMTSLeavesToDisplay2) - pass - self.assertEqual(len(allFMTSLeavesToDisplay),1) - self.assertEqual(len(allFMTSLeavesToDisplay[0]),1) - allFMTSLeavesPerTimeSeries=MEDFileAnyTypeFieldMultiTS.SplitIntoCommonTimeSeries(sum(allFMTSLeavesToDisplay,[])) - self.assertEqual(len(allFMTSLeavesPerTimeSeries),1) - self.assertEqual(len(allFMTSLeavesPerTimeSeries[0]),1) - allFMTSLeavesPerCommonSupport1=MEDFileAnyTypeFieldMultiTS.SplitPerCommonSupport(allFMTSLeavesToDisplay[0],ms[ms.getMeshesNames()[0]]) - self.assertEqual(len(allFMTSLeavesPerCommonSupport1),1) - self.assertEqual(len(allFMTSLeavesPerCommonSupport1[0][0]),1) - # - mst=MEDFileMeshStruct.New(ms[0]) - # - fcscp=allFMTSLeavesPerCommonSupport1[0][1] - self.assertEqual([NORM_TRI3,NORM_SEG2],fcscp.getGeoTypesAt(0,ms[0]))#contains all cell types of underlying mesh because only nodes with no profiles - mml=fcscp.buildFromScratchDataSetSupport(0,fields) - mml2=mml.prepare() - self.assertTrue(isinstance(mml2,MEDUMeshMultiLev)) - ncc,a0,a1,a2,a3,a4,a5=mml2.buildVTUArrays() - self.assertTrue(not ncc) - self.assertTrue(a0.isEqual(DataArrayDouble([(4.,3.,0.),(7.,3.,0.),(2.,5.,0.),(6.,5.,0.),(9.,5.,0.),(4.,7.,0.),(8.,7.,0.),(3.,8.,0.),(9.,8.,0.)]),1e-12)) - self.assertTrue(a1.isEqual(DataArrayByte([5,5,5,3,3,3,3,3,3,3]))) - self.assertTrue(a2.isEqual(DataArrayInt([0,4,8,12,15,18,21,24,27,30]))) - self.assertTrue(a3.isEqual(DataArrayInt([3,2,3,0,3,3,1,0,3,3,4,1,2,2,0,2,0,1,2,1,4,2,3,5,2,5,7,2,3,6,2,6,8]))) - self.assertTrue(a4 is None) - self.assertTrue(a5 is None) - a6,a7=mml2.retrieveFamilyIdsOnCells() - self.assertTrue(a6.isEqual(DataArrayInt([0,0,0,0,0,0,0,0,0,0]))) - self.assertTrue(not a7) # copy here - a8,a9=mml2.retrieveNumberIdsOnCells() - self.assertTrue(not a8) - self.assertTrue(a9) # nocopy here - a10,a11=mml2.retrieveFamilyIdsOnNodes() - self.assertTrue(not a10) - self.assertTrue(a11) # no copy here - a12,a13=mml2.retrieveNumberIdsOnNodes() - self.assertTrue(not a12) - self.assertTrue(a13) # no copy here - # - f=allFMTSLeavesPerCommonSupport1[0][0][0][0] - fsst=MEDFileField1TSStructItem.BuildItemFrom(f,mst) - f.loadArraysIfNecessary() - v=mml.buildDataArray(fsst,fields,f.getUndergroundDataArray()) - self.assertEqual(f.getName(),fieldName0) - self.assertEqual(v.getHiddenCppPointer(),f.getUndergroundDataArray().getHiddenCppPointer()) - vExp=DataArrayDouble(9) ; vExp.iota() ; vExp.setInfoOnComponents(["zeInfo"]) - self.assertTrue(v.isEqual(vExp,1e-12)) - # - f=allFMTSLeavesPerCommonSupport1[0][0][0][1] - fsst=MEDFileField1TSStructItem.BuildItemFrom(f,mst) - f.loadArraysIfNecessary() - v=mml.buildDataArray(fsst,fields,f.getUndergroundDataArray()) - self.assertEqual(f.getName(),fieldName0) - self.assertEqual(v.getHiddenCppPointer(),f.getUndergroundDataArray().getHiddenCppPointer()) - vExp=DataArrayDouble(9) ; vExp.iota() ; vExp.setInfoOnComponents(["zeInfo"]) ; vExp.reverse() - self.assertTrue(v.isEqual(vExp,1e-12)) - pass - - def test23(self): - """ Non regression test 2219 of modes. Idem than test22 except that here the node field is on profile. - """ - fname="ForMEDReader23.med" - fieldName0="ANodeField" - mm=MEDFileUMesh() - coo=DataArrayDouble([(4.,3.),(7.,3.),(2.,5.),(6.,5.),(9.,5.),(4.,7.),(8.,7.),(3.,8.),(9.,8.)]) - m0=MEDCouplingUMesh("mesh",2) ; m0.setCoords(coo) ; m0.allocateCells() ; m0.insertNextCell(NORM_TRI3,[2,3,0]) ; m0.insertNextCell(NORM_TRI3,[3,1,0]) ; m0.insertNextCell(NORM_TRI3,[3,4,1]) - mm.setMeshAtLevel(0,m0) - m1=MEDCouplingUMesh("mesh",1) ; m1.setCoords(coo) ; m1.allocateCells() ; m1.insertNextCell(NORM_SEG2,[2,0]) ; m1.insertNextCell(NORM_SEG2,[0,1]) ; m1.insertNextCell(NORM_SEG2,[1,4]) - m1.insertNextCell(NORM_SEG2,[3,5]) ; m1.insertNextCell(NORM_SEG2,[5,7]) ; m1.insertNextCell(NORM_SEG2,[3,6]) ; m1.insertNextCell(NORM_SEG2,[6,8]) - mm.setMeshAtLevel(-1,m1) - fmts0=MEDFileFieldMultiTS() - fmts0.setDtUnit("s") - # - pfl=DataArrayInt([0,1,2,4]) ; pfl.setName("pfl") - pflCell=DataArrayInt([0,1,2]) ; m1Part=m1[pflCell] ; m1Part.zipCoords() - # - t=(1.1,0,-2) - f0=MEDCouplingFieldDouble(ON_NODES) ; f0.setMesh(m1Part) - f0.setName(fieldName0) ; f0.setTime(*t) - da=DataArrayDouble(4) ; da.iota() ; da.setInfoOnComponents(["zeInfo"]) - f0.setArray(da) - f0.checkCoherency() - f1ts=MEDFileField1TS() - f1ts.setFieldProfile(f0,mm,-1,pfl) - fmts0.pushBackTimeStep(f1ts) - # - t=(2.1,1,-3) - f0=MEDCouplingFieldDouble(ON_NODES) ; f0.setMesh(m1Part) - f0.setName(fieldName0) ; f0.setTime(*t) - da=DataArrayDouble(4) ; da.iota() ; da.reverse() ; da.setInfoOnComponents(["zeInfo"]) - f0.setArray(da) - f0.checkCoherency() - f1ts=MEDFileField1TS() - f1ts.setFieldProfile(f0,mm,-1,pfl) - fmts0.pushBackTimeStep(f1ts) - mm.write(fname,2) - fmts0.write(fname,0) - ########## GO for reading in MEDReader,by not loading all. Mesh is fully loaded but not fields values - ms=MEDFileMeshes(fname) - fields=MEDFileFields(fname,False) - fields.removeFieldsWithoutAnyTimeStep() - fields_per_mesh=[fields.partOfThisLyingOnSpecifiedMeshName(meshName) for meshName in ms.getMeshesNames()] - allFMTSLeavesToDisplay=[] - for fields in fields_per_mesh: - allFMTSLeavesToDisplay2=[] - for fmts in fields: - tmp=fmts.splitDiscretizations() - for itmp in tmp: - self.assertTrue(not itmp.presenceOfMultiDiscPerGeoType()) - pass - allFMTSLeavesToDisplay2+=tmp - pass - allFMTSLeavesToDisplay.append(allFMTSLeavesToDisplay2) - pass - self.assertEqual(len(allFMTSLeavesToDisplay),1) - self.assertEqual(len(allFMTSLeavesToDisplay[0]),1) - allFMTSLeavesPerTimeSeries=MEDFileAnyTypeFieldMultiTS.SplitIntoCommonTimeSeries(sum(allFMTSLeavesToDisplay,[])) - self.assertEqual(len(allFMTSLeavesPerTimeSeries),1) - self.assertEqual(len(allFMTSLeavesPerTimeSeries[0]),1) - allFMTSLeavesPerCommonSupport1=MEDFileAnyTypeFieldMultiTS.SplitPerCommonSupport(allFMTSLeavesToDisplay[0],ms[ms.getMeshesNames()[0]]) - self.assertEqual(len(allFMTSLeavesPerCommonSupport1),1) - self.assertEqual(len(allFMTSLeavesPerCommonSupport1[0][0]),1) - # - mst=MEDFileMeshStruct.New(ms[0]) - # - fcscp=allFMTSLeavesPerCommonSupport1[0][1] - mml=fcscp.buildFromScratchDataSetSupport(0,fields) - mml2=mml.prepare() - self.assertTrue(isinstance(mml2,MEDUMeshMultiLev)) - ncc,a0,a1,a2,a3,a4,a5=mml2.buildVTUArrays() - self.assertTrue(not ncc) - self.assertTrue(a0.isEqual(DataArrayDouble([(4.,3.,0.),(7.,3.,0.),(2.,5.,0.),(9.,5.,0.)]),1e-12)) - self.assertTrue(a1.isEqual(DataArrayByte([3,3,3]))) - self.assertTrue(a2.isEqual(DataArrayInt([0,3,6]))) - self.assertTrue(a3.isEqual(DataArrayInt([2,2,0,2,0,1,2,1,3]))) - self.assertTrue(a4 is None) - self.assertTrue(a5 is None) - a6,a7=mml2.retrieveFamilyIdsOnCells() - self.assertTrue(a6.isEqual(DataArrayInt([0,0,0]))) - self.assertTrue(not a7) # copy here - a8,a9=mml2.retrieveNumberIdsOnCells() - self.assertTrue(not a8) - self.assertTrue(a9) # nocopy here - a10,a11=mml2.retrieveFamilyIdsOnNodes() - self.assertTrue(not a10) - self.assertTrue(a11) # no copy here - a12,a13=mml2.retrieveNumberIdsOnNodes() - self.assertTrue(not a12) - self.assertTrue(a13) # no copy here - # - f=allFMTSLeavesPerCommonSupport1[0][0][0][0] - fsst=MEDFileField1TSStructItem.BuildItemFrom(f,mst) - f.loadArraysIfNecessary() - v=mml.buildDataArray(fsst,fields,f.getUndergroundDataArray()) - self.assertEqual(f.getName(),fieldName0) - vExp=DataArrayDouble(4) ; vExp.iota() ; vExp.setInfoOnComponents(["zeInfo"]) - self.assertTrue(v.isEqual(vExp,1e-12)) - # - f=allFMTSLeavesPerCommonSupport1[0][0][0][1] - fsst=MEDFileField1TSStructItem.BuildItemFrom(f,mst) - f.loadArraysIfNecessary() - v=mml.buildDataArray(fsst,fields,f.getUndergroundDataArray()) - self.assertEqual(f.getName(),fieldName0) - vExp=DataArrayDouble(4) ; vExp.iota() ; vExp.setInfoOnComponents(["zeInfo"]) ; vExp.reverse() - self.assertTrue(v.isEqual(vExp,1e-12)) - pass - - def test24(self): - """ Non regression test for cartesian mesh whose the 3rd direction has only one node. It a false 3D mesh. - """ - fname="ForMEDReader24.med" - fieldName0="zeFieldNode" - cmesh=MEDCouplingCMesh("mesh") - arr0=DataArrayDouble([0.,1.1,2.2,3.3,4.4]) - arr1=DataArrayDouble([0.,1.4,2.3]) - arr2=DataArrayDouble([5.]) - cmesh.setCoords(arr0,arr1,arr2) - fmts0=MEDFileFieldMultiTS() - fmts0.setDtUnit("s") - # - t=(1.1,2,3) - f=MEDCouplingFieldDouble(ON_NODES) ; f.setName(fieldName0) - f.setMesh(cmesh) - arr=DataArrayDouble(15) ; arr.setInfoOnComponents(["tutu"]) ; arr.iota() - f.setArray(arr) - f.setTime(*t) - f1ts=MEDFileField1TS() - f1ts.setFieldNoProfileSBT(f) - fmts0.pushBackTimeStep(f1ts) - # - t=(3.3,4,5) - arr=DataArrayDouble(15) ; arr.setInfoOnComponents(["tutu"]) ; arr.iota() - arr.reverse() - f.setArray(arr) - f.setTime(*t) - f1ts=MEDFileField1TS() - f1ts.setFieldNoProfileSBT(f) - fmts0.pushBackTimeStep(f1ts) - # - mm=MEDFileCMesh() ; mm.setMesh(cmesh) - mm.write(fname,2) - fmts0.write(fname,0) - ########## GO for reading in MEDReader,by not loading all. Mesh is fully loaded but not fields values - ms=MEDFileMeshes(fname) - fields=MEDFileFields(fname,False) - fields.removeFieldsWithoutAnyTimeStep() - fields_per_mesh=[fields.partOfThisLyingOnSpecifiedMeshName(meshName) for meshName in ms.getMeshesNames()] - allFMTSLeavesToDisplay=[] - for fields in fields_per_mesh: - allFMTSLeavesToDisplay2=[] - for fmts in fields: - tmp=fmts.splitDiscretizations() - for itmp in tmp: - self.assertTrue(not itmp.presenceOfMultiDiscPerGeoType()) - pass - allFMTSLeavesToDisplay2+=tmp - pass - allFMTSLeavesToDisplay.append(allFMTSLeavesToDisplay2) - pass - self.assertEqual(len(allFMTSLeavesToDisplay),1) - self.assertEqual(len(allFMTSLeavesToDisplay[0]),1) - allFMTSLeavesPerTimeSeries=MEDFileAnyTypeFieldMultiTS.SplitIntoCommonTimeSeries(sum(allFMTSLeavesToDisplay,[])) - self.assertEqual(len(allFMTSLeavesPerTimeSeries),1) - self.assertEqual(len(allFMTSLeavesPerTimeSeries[0]),1) - allFMTSLeavesPerCommonSupport=MEDFileAnyTypeFieldMultiTS.SplitPerCommonSupport(allFMTSLeavesToDisplay[0],ms[ms.getMeshesNames()[0]]) - self.assertEqual(len(allFMTSLeavesPerCommonSupport),1) - self.assertEqual(len(allFMTSLeavesPerCommonSupport[0][0]),1) - # - mst=MEDFileMeshStruct.New(ms[0]) - # - fcscp=allFMTSLeavesPerCommonSupport[0][1] - mml=fcscp.buildFromScratchDataSetSupport(0,fields) - mml2=mml.prepare() - self.assertTrue(isinstance(mml2,MEDCMeshMultiLev)) - (a,b,c),d=mml2.buildVTUArrays() - self.assertTrue(d)#d is True because the a,b and c are directly those in the internal data structure - self.assertTrue(a.isEqual(arr0,1e-12)) - self.assertTrue(b.isEqual(arr1,1e-12)) - self.assertTrue(c.isEqual(arr2,1e-12)) - for i in xrange(2): - f=allFMTSLeavesPerCommonSupport[0][0][0][i] - fsst=MEDFileField1TSStructItem.BuildItemFrom(f,mst) - f.loadArraysIfNecessary() - v=mml.buildDataArray(fsst,fields,f.getUndergroundDataArray()) - self.assertEqual(f.getName(),fieldName0) - self.assertEqual(v.getHiddenCppPointer(),f.getUndergroundDataArray().getHiddenCppPointer()) - vExp=DataArrayDouble(15) ; vExp.iota(0) ; vExp.setInfoOnComponents(["tutu"]) - if i==1: - vExp.reverse() - pass - self.assertTrue(v.isEqual(vExp,1e-12)) - pass - pass - - def test25(self): - """ A tricky test that reproduces an invalid behaviour - Here a same field is defined both on CELLS and GAUSS_PT, with a profile for each. - The problem appears on array computation when performing CELLS then GAUSS_PT and CELLS again. - """ - fname="ForMEDReader25.med" - m=MEDFileUMesh() - coords=DataArrayDouble([0.,0.,1.,0.,2.,0.,0.,1.,1.,1.,2.,1.,0.,2.,1.,2.,2.,2.,0.,3.,1.,3.,2.,3.,1.,4.,1.,5.,1.,6.],15,2) - m0=MEDCouplingUMesh("mesh",2) ; m0.setCoords(coords) - m0.allocateCells() - m0.insertNextCell(NORM_QUAD4,[0,3,4,1]) - m0.insertNextCell(NORM_QUAD4,[1,4,5,2]) - m0.insertNextCell(NORM_QUAD4,[3,6,7,4]) - m0.insertNextCell(NORM_QUAD4,[4,7,8,5]) - m0.insertNextCell(NORM_QUAD4,[6,9,10,7]) - m0.insertNextCell(NORM_QUAD4,[7,10,11,8]) - m.setMeshAtLevel(0,m0) - m1=MEDCouplingUMesh("mesh",1) ; m1.setCoords(coords) - m1.allocateCells() - m1.insertNextCell(NORM_SEG2,[10,12]) - m1.insertNextCell(NORM_SEG2,[12,13]) - m1.insertNextCell(NORM_SEG2,[13,14]) - m.setMeshAtLevel(-1,m1) - m.setFamilyFieldArr(0,DataArrayInt([-1,-2,-3,-4,-5,-6])) - m.setFamilyFieldArr(-1,DataArrayInt([-7,-8,-9])) - m.setFamilyFieldArr(1,DataArrayInt([3,4,5,6,7,8,9,10,11,12,13,14,15,16,17])) - m.setRenumFieldArr(0,DataArrayInt([101,102,103,104,105,106])) - m.setRenumFieldArr(-1,DataArrayInt([107,108,109])) - m.setRenumFieldArr(1,DataArrayInt([203,204,205,206,207,208,209,210,211,212,213,214,215,216,217])) - # - fmts=MEDFileFieldMultiTS() - info0=["aa","bbb"] - name0="zeField" - pflName0="pfl" - pflName1="pfl2" - # - f1ts=MEDFileField1TS() - f=MEDCouplingFieldDouble(ON_CELLS) ; f.setName(name0) - arr=DataArrayDouble([(-1,-11),(-2,-22)]) ; arr.setInfoOnComponents(info0) - f.setArray(arr) - pfl0=DataArrayInt([0,1]) ; pfl0.setName(pflName0) - f1ts.setFieldProfile(f,m,-1,pfl0) - del f - f2=MEDCouplingFieldDouble(ON_GAUSS_PT) ; f2.setName(name0) - arr=DataArrayDouble(15) ; arr.iota(1) - arr=DataArrayDouble.Meld(arr,arr+10) ; arr.setInfoOnComponents(info0) - f2.setArray(arr) - pfl1=DataArrayInt([1,3,5]) ; pfl1.setName(pflName1) - tmp=m0[pfl1] ; f2.setMesh(tmp) - f2.setGaussLocalizationOnType(NORM_QUAD4,[-1.,-1.,1.,-1.,1.,1.,-1.,1.],[-0.5,-0.5,0.5,-0.5,0.5,0.5,-0.5,0.5,0.,0.],[0.1,0.1,0.1,0.1,0.6]) - f2.checkCoherency() - f1ts.setFieldProfile(f2,m,0,pfl1) - fmts.pushBackTimeStep(f1ts) - # - m.write(fname,2) - fmts.write(fname,0) - ########## GO for reading in MEDReader,by not loading all. Mesh is fully loaded but not fields values - ms=MEDFileMeshes(fname) - fields=MEDFileFields(fname,False) # false is absolutely necessary for the test - fields.removeFieldsWithoutAnyTimeStep() - fields_per_mesh=[fields.partOfThisLyingOnSpecifiedMeshName(meshName) for meshName in ms.getMeshesNames()] - allFMTSLeavesToDisplay=[] - for fields in fields_per_mesh: - allFMTSLeavesToDisplay2=[] - for fmts in fields: - tmp=fmts.splitDiscretizations() - for itmp in tmp: - self.assertTrue(not itmp.presenceOfMultiDiscPerGeoType()) - pass - allFMTSLeavesToDisplay2+=tmp - pass - allFMTSLeavesToDisplay.append(allFMTSLeavesToDisplay2) - pass - self.assertEqual(len(allFMTSLeavesToDisplay),1) - self.assertEqual(len(allFMTSLeavesToDisplay[0]),2) - ### here the test is important !!! Pointers must be different ! - self.assertTrue(allFMTSLeavesToDisplay[0][0][0].getUndergroundDataArray().getHiddenCppPointer()!=allFMTSLeavesToDisplay[0][1][0].getUndergroundDataArray().getHiddenCppPointer()) - allFMTSLeavesPerTimeSeries=MEDFileAnyTypeFieldMultiTS.SplitIntoCommonTimeSeries(sum(allFMTSLeavesToDisplay,[])) - self.assertEqual(len(allFMTSLeavesPerTimeSeries),1) - self.assertEqual(len(allFMTSLeavesPerTimeSeries[0]),2) - ### here the test is important !!! Pointers must be different ! - self.assertTrue(allFMTSLeavesToDisplay[0][0][0].getUndergroundDataArray().getHiddenCppPointer()!=allFMTSLeavesToDisplay[0][1][0].getUndergroundDataArray().getHiddenCppPointer()) - allFMTSLeavesPerCommonSupport1=MEDFileAnyTypeFieldMultiTS.SplitPerCommonSupport(allFMTSLeavesToDisplay[0],ms[ms.getMeshesNames()[0]]) - self.assertTrue(allFMTSLeavesToDisplay[0][0][0].getUndergroundDataArray().getHiddenCppPointer()!=allFMTSLeavesToDisplay[0][1][0].getUndergroundDataArray().getHiddenCppPointer()) - self.assertEqual(len(allFMTSLeavesPerCommonSupport1),2) - self.assertEqual(len(allFMTSLeavesPerCommonSupport1[0][0]),1) - self.assertEqual(len(allFMTSLeavesPerCommonSupport1[1][0]),1) - # - mst=MEDFileMeshStruct.New(ms[0]) - # emulate first click - fcscp=allFMTSLeavesPerCommonSupport1[0][1] - self.assertEqual([NORM_SEG2],fcscp.getGeoTypesAt(0,ms[0])) - mml=fcscp.buildFromScratchDataSetSupport(0,fields) - mml2=mml.prepare() - self.assertTrue(isinstance(mml2,MEDUMeshMultiLev)) - ncc,a0,a1,a2,a3,a4,a5=mml2.buildVTUArrays() - self.assertTrue(not ncc) # copy here because 2D -> 3D - expCoords=coords.changeNbOfComponents(3,0.) - self.assertTrue(a0.isEqual(expCoords,1e-12)) - self.assertTrue(a1.isEqual(DataArrayByte([3,3]))) - self.assertTrue(a2.isEqual(DataArrayInt([0,3]))) - self.assertTrue(a3.isEqual(DataArrayInt([2,10,12,2,12,13]))) - self.assertTrue(a4 is None) - self.assertTrue(a5 is None) - a6,a7=mml2.retrieveFamilyIdsOnCells() - self.assertTrue(a6.isEqual(DataArrayInt([-7,-8]))) - self.assertTrue(not a7) # copy here because profile on cells - a8,a9=mml2.retrieveNumberIdsOnCells() - self.assertTrue(a8.isEqual(DataArrayInt([107,108]))) - self.assertTrue(not a9) # copy here because profile on cells - a10,a11=mml2.retrieveFamilyIdsOnNodes() - self.assertTrue(a10.isEqual(DataArrayInt([3,4,5,6,7,8,9,10,11,12,13,14,15,16,17]))) - self.assertTrue(a11) # no copy here - a12,a13=mml2.retrieveNumberIdsOnNodes() - self.assertTrue(a12.isEqual(DataArrayInt([203,204,205,206,207,208,209,210,211,212,213,214,215,216,217]))) - self.assertTrue(a13) # no copy here - fff0=allFMTSLeavesPerCommonSupport1[0][0][0][0] - fsst=MEDFileField1TSStructItem.BuildItemFrom(fff0,mst) - fff0.loadArraysIfNecessary() - self.assertEqual([ON_CELLS],fff0.getTypesOfFieldAvailable()) - v=mml.buildDataArray(fsst,fields,fff0.getUndergroundDataArray()) - self.assertEqual(fff0.getName(),name0) - self.assertEqual(v.getHiddenCppPointer(),fff0.getUndergroundDataArray().getHiddenCppPointer()) - vExp=DataArrayDouble([(-1,-11),(-2,-22)]) ; vExp.setInfoOnComponents(info0) - self.assertTrue(v.isEqual(vExp,1e-12)) - del fff0 - # emulate second click - fcscp=allFMTSLeavesPerCommonSupport1[1][1] - self.assertEqual([NORM_QUAD4],fcscp.getGeoTypesAt(0,ms[0])) - mml=fcscp.buildFromScratchDataSetSupport(0,fields) - mml2=mml.prepare() - self.assertTrue(isinstance(mml2,MEDUMeshMultiLev)) - ncc,a0,a1,a2,a3,a4,a5=mml2.buildVTUArrays() - self.assertTrue(not ncc) # copy here because 2D -> 3D - expCoords=coords.changeNbOfComponents(3,0.) - self.assertTrue(a0.isEqual(expCoords,1e-12)) - self.assertTrue(a1.isEqual(DataArrayByte([9,9,9]))) - self.assertTrue(a2.isEqual(DataArrayInt([0,5,10]))) - self.assertTrue(a3.isEqual(DataArrayInt([4,1,4,5,2,4,4,7,8,5,4,7,10,11,8]))) - self.assertTrue(a4 is None) - self.assertTrue(a5 is None) - a6,a7=mml2.retrieveFamilyIdsOnCells() - self.assertTrue(a6.isEqual(DataArrayInt([-2,-4,-6]))) - self.assertTrue(not a7) # copy here because profile on cells - a8,a9=mml2.retrieveNumberIdsOnCells() - self.assertTrue(a8.isEqual(DataArrayInt([102,104,106]))) - self.assertTrue(not a9) # copy here because profile on cells - a10,a11=mml2.retrieveFamilyIdsOnNodes() - self.assertTrue(a10.isEqual(DataArrayInt([3,4,5,6,7,8,9,10,11,12,13,14,15,16,17]))) - self.assertTrue(a11) # no copy here - a12,a13=mml2.retrieveNumberIdsOnNodes() - self.assertTrue(a12.isEqual(DataArrayInt([203,204,205,206,207,208,209,210,211,212,213,214,215,216,217]))) - self.assertTrue(a13) # no copy here - fff1=allFMTSLeavesPerCommonSupport1[1][0][0][0] - fsst=MEDFileField1TSStructItem.BuildItemFrom(fff1,mst) - fff1.loadArraysIfNecessary() - self.assertEqual([ON_GAUSS_PT],fff1.getTypesOfFieldAvailable()) - v=mml.buildDataArray(fsst,fields,fff1.getUndergroundDataArray()) - self.assertEqual(fff1.getName(),name0) - self.assertEqual(v.getHiddenCppPointer(),fff1.getUndergroundDataArray().getHiddenCppPointer()) - vExp=DataArrayDouble([1.,11.,2.,12.,3.,13.,4.,14.,5.,15.,6.,16.,7.,17.,8.,18.,9.,19.,10.,20.,11.,21.,12.,22.,13.,23.,14.,24.,15.,25.],15,2) ; vExp.setInfoOnComponents(info0) - self.assertTrue(v.isEqual(vExp,1e-12)) - # emulate third click - fcscp=allFMTSLeavesPerCommonSupport1[0][1] - mml=fcscp.buildFromScratchDataSetSupport(0,fields) - mml2=mml.prepare() - self.assertTrue(isinstance(mml2,MEDUMeshMultiLev)) - ncc,a0,a1,a2,a3,a4,a5=mml2.buildVTUArrays() - self.assertTrue(not ncc) # copy here because 2D -> 3D - expCoords=coords.changeNbOfComponents(3,0.) - self.assertTrue(a0.isEqual(expCoords,1e-12)) - self.assertTrue(a1.isEqual(DataArrayByte([3,3]))) - self.assertTrue(a2.isEqual(DataArrayInt([0,3]))) - self.assertTrue(a3.isEqual(DataArrayInt([2,10,12,2,12,13]))) - self.assertTrue(a4 is None) - self.assertTrue(a5 is None) - a6,a7=mml2.retrieveFamilyIdsOnCells() - self.assertTrue(a6.isEqual(DataArrayInt([-7,-8]))) - self.assertTrue(not a7) # copy here because profile on cells - a8,a9=mml2.retrieveNumberIdsOnCells() - self.assertTrue(a8.isEqual(DataArrayInt([107,108]))) - self.assertTrue(not a9) # copy here because profile on cells - a10,a11=mml2.retrieveFamilyIdsOnNodes() - self.assertTrue(a10.isEqual(DataArrayInt([3,4,5,6,7,8,9,10,11,12,13,14,15,16,17]))) - self.assertTrue(a11) # no copy here - a12,a13=mml2.retrieveNumberIdsOnNodes() - self.assertTrue(a12.isEqual(DataArrayInt([203,204,205,206,207,208,209,210,211,212,213,214,215,216,217]))) - self.assertTrue(a13) # no copy here - fff0=allFMTSLeavesPerCommonSupport1[0][0][0][0] - fsst=MEDFileField1TSStructItem.BuildItemFrom(fff0,mst) - fff0.loadArraysIfNecessary() - self.assertEqual([ON_CELLS],fff0.getTypesOfFieldAvailable()) - v=mml.buildDataArray(fsst,fields,fff0.getUndergroundDataArray()) - self.assertEqual(fff0.getName(),name0) - self.assertEqual(v.getHiddenCppPointer(),fff0.getUndergroundDataArray().getHiddenCppPointer()) - vExp=DataArrayDouble([(-1,-11),(-2,-22)]) ; vExp.setInfoOnComponents(info0) - self.assertTrue(v.isEqual(vExp,1e-12)) # <- THE test is here !!! - del fff0 - pass - - def test26(self): - """ Test focused on field on nodes (here f0Node and f1Node) lying on a profile of nodes that do not match perfectly a sub set of cells of its underlying mesh. See bug EDF 2405 and 2177. - For this type of fields the support will contain only vertices. - """ - fname="ForMEDReader26.med" - coords=DataArrayDouble([(0.,0.,0.),(1.,0.,0.),(2.,0.,0.),(3.,0.,0.),(0.,1.,0.),(1.,1.,0.),(2.,1.,0.),(3.,1.,0.),(0.,2.,0.),(1.,2.,0.),(2.,2.,0.),(3.,2.,0.),(0.,3.,0.),(1.,3.,0.),(2.,3.,0.),(3.,3.,0.)]) - m0=MEDCouplingUMesh("mesh",2) - m0.allocateCells() - for elt in [[2,6,3],[6,7,3],[9,6,5],[9,10,6]]: - m0.insertNextCell(NORM_TRI3,elt) - pass - for elt in [[0,4,5,1],[1,5,6,2],[4,8,9,5],[6,10,11,7],[8,12,13,9],[9,13,14,10],[10,14,15,11]]: - m0.insertNextCell(NORM_QUAD4,elt) - pass - m0.setCoords(coords) - ## - mm=MEDFileUMesh() - mm.setMeshAtLevel(0,m0) - mm.setFamilyFieldArr(0,DataArrayInt([-1,-2,-3,-4,-5,-6,-7,-8,-9,-10,-11])) - mm.setFamilyFieldArr(1,DataArrayInt([1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16])) - # - f1ts0Node=MEDFileField1TS() - f1ts1Node=MEDFileField1TS() - f1ts2Cell=MEDFileField1TS() - f1ts3Cell=MEDFileField1TS() - f1ts4Cell=MEDFileField1TS() - f1ts5Node=MEDFileField1TS() - # - pfl0=DataArrayInt([4,5,6,8,9,12]) ; pfl0.setName("pfl0") - pfl1=DataArrayInt([0,1,4,5,7,10]) ; pfl1.setName("pfl1") - pfl2=DataArrayInt([0,1,2,3,4,5,6,7,10,11,14,15]) ; pfl2.setName("pfl2") - # - f0Node=MEDCouplingFieldDouble(ON_NODES) ; f0Node.setName("f0Node") - arr0=DataArrayDouble(6) ; arr0.iota() - f0Node.setArray(arr0) - f1ts0Node.setFieldProfile(f0Node,mm,0,pfl0) - # - f1Node=MEDCouplingFieldDouble(ON_NODES) ; f1Node.setName("f1Node") - arr1=DataArrayDouble(6) ; arr1.iota() ; arr1.reverse() - f1Node.setArray(arr1) - f1ts1Node.setFieldProfile(f1Node,mm,0,pfl0) - # - f2Cell=MEDCouplingFieldDouble(ON_CELLS) ; f2Cell.setName("f2Cell") - arr2=DataArrayDouble([2,3,0,1,4,5]) - f2Cell.setArray(arr2) - f1ts2Cell.setFieldProfile(f2Cell,mm,0,pfl1) - # - f3Cell=MEDCouplingFieldDouble(ON_CELLS) ; f3Cell.setName("f3Cell") - arr3=DataArrayDouble([5,4,3,2,1,0]) - f3Cell.setArray(arr3) - f1ts3Cell.setFieldProfile(f3Cell,mm,0,pfl1) - # - f4Cell=MEDCouplingFieldDouble(ON_CELLS) ; f4Cell.setName("f4Cell") - arr4=DataArrayDouble([2,2,0,1,1,0]) - f4Cell.setArray(arr4) - f1ts4Cell.setFieldProfile(f4Cell,mm,0,pfl1) - # - f5Node=MEDCouplingFieldDouble(ON_NODES) ; f5Node.setName("f5Node") - arr5=DataArrayDouble([0,1,2,3,10,11,13,2,11,1,10,0]) - f5Node.setArray(arr5) - f1ts5Node.setFieldProfile(f5Node,mm,0,pfl2) - # - fs=MEDFileFields() - for f in [f1ts0Node,f1ts1Node,f1ts2Cell,f1ts3Cell,f1ts4Cell,f1ts5Node]: - fmts=MEDFileFieldMultiTS() - fmts.pushBackTimeStep(f) - fs.pushField(fmts) - pass - mm.write(fname,2) - fs.write(fname,0) - ########## GO for reading in MEDReader,by not loading all. Mesh is fully loaded but not fields values - ms=MEDFileMeshes(fname) - fields=MEDFileFields(fname,False) - fields.removeFieldsWithoutAnyTimeStep() - fields_per_mesh=[fields.partOfThisLyingOnSpecifiedMeshName(meshName) for meshName in ms.getMeshesNames()] - allFMTSLeavesToDisplay=[] - for fields in fields_per_mesh: - allFMTSLeavesToDisplay2=[] - for fmts in fields: - tmp=fmts.splitDiscretizations() - for itmp in tmp: - self.assertTrue(not itmp.presenceOfMultiDiscPerGeoType()) - pass - allFMTSLeavesToDisplay2+=tmp - pass - allFMTSLeavesToDisplay.append(allFMTSLeavesToDisplay2) - pass - self.assertEqual(len(allFMTSLeavesToDisplay),1) - self.assertEqual(len(allFMTSLeavesToDisplay[0]),6) - allFMTSLeavesPerTimeSeries=MEDFileAnyTypeFieldMultiTS.SplitIntoCommonTimeSeries(sum(allFMTSLeavesToDisplay,[])) - self.assertEqual(len(allFMTSLeavesPerTimeSeries),1) - self.assertEqual(len(allFMTSLeavesPerTimeSeries[0]),6) - allFMTSLeavesPerCommonSupport1=MEDFileAnyTypeFieldMultiTS.SplitPerCommonSupport(allFMTSLeavesToDisplay[0],ms[ms.getMeshesNames()[0]]) - self.assertEqual(len(allFMTSLeavesPerCommonSupport1),2) - self.assertEqual(len(allFMTSLeavesPerCommonSupport1[0][0]),4) - self.assertEqual(len(allFMTSLeavesPerCommonSupport1[1][0]),2)# <- the smart one is here - # - mst=MEDFileMeshStruct.New(ms[0]) - # - fcscp=allFMTSLeavesPerCommonSupport1[1][1] - mml=fcscp.buildFromScratchDataSetSupport(0,fields) - mml2=mml.prepare() - self.assertTrue(isinstance(mml2,MEDUMeshMultiLev)) - self.assertEqual([3,4,0],mml2.getGeoTypes()) - ncc,a0,a1,a2,a3,a4,a5=mml2.buildVTUArrays() - self.assertTrue(not ncc) - self.assertTrue(a0.isEqual(DataArrayDouble([0.,1.,0.,1.,1.,0.,2.,1.,0.,0.,2.,0.,1.,2.,0.,0.,3.,0.],6,3),1e-12)) - self.assertTrue(a1.isEqual(DataArrayByte([5,9,1]))) - self.assertTrue(a2.isEqual(DataArrayInt([0,4,9]))) - self.assertTrue(a3.isEqual(DataArrayInt([3,4,2,1,4,0,3,4,1,1,5]))) - self.assertTrue(a4 is None) - self.assertTrue(a5 is None) - a6,a7=mml2.retrieveFamilyIdsOnCells() - self.assertTrue(a6.isEqual(DataArrayInt([-3,-7,13]))) - self.assertTrue(not a7) # copy here because profile on cells - a8,a9=mml2.retrieveNumberIdsOnCells() - self.assertTrue(a8 is None) - self.assertTrue(a9) # no copy here because no number field - a10,a11=mml2.retrieveFamilyIdsOnNodes() - self.assertTrue(a10.isEqual(DataArrayInt([5,6,7,9,10,13]))) - self.assertTrue(not a11) # copy here - a12,a13=mml2.retrieveNumberIdsOnNodes() - self.assertTrue(a12 is None) - self.assertTrue(a13) # no copy here because no number field - # - fff0=allFMTSLeavesPerCommonSupport1[1][0][0][0] - fsst=MEDFileField1TSStructItem.BuildItemFrom(fff0,mst) - fff0.loadArraysIfNecessary() - v=mml2.buildDataArray(fsst,fields,fff0.getUndergroundDataArray()) - self.assertEqual(fff0.getName(),"f0Node") - self.assertEqual(v.getHiddenCppPointer(),fff0.getUndergroundDataArray().getHiddenCppPointer()) - vExp=DataArrayDouble([0.,1.,2.,3.,4.,5.]) - self.assertTrue(v.isEqual(vExp,1e-12)) # <- THE test is here !!! - # - fff1=allFMTSLeavesPerCommonSupport1[1][0][1][0] - fsst=MEDFileField1TSStructItem.BuildItemFrom(fff1,mst) - fff1.loadArraysIfNecessary() - v=mml2.buildDataArray(fsst,fields,fff1.getUndergroundDataArray()) - self.assertEqual(fff1.getName(),"f1Node") - self.assertEqual(v.getHiddenCppPointer(),fff1.getUndergroundDataArray().getHiddenCppPointer()) - vExp=DataArrayDouble([5.,4.,3.,2.,1.,0.]) - self.assertTrue(v.isEqual(vExp,1e-12)) # <- THE test is here !!! - pass - - def test27(self): - """ This test defines 2 fields f0 and f1 on nodes lying on an unstructured mesh with no cells. - f0 is a field on all nodes. f1 is a partial field on nodes. - """ - fname="ForMEDReader27.med" - coords=DataArrayDouble([(0.,0.,0.),(1.,0.,0.),(2.,0.,0.),(3.,0.,0.),(0.,1.,0.),(1.,1.,0.),(2.,1.,0.),(3.,1.,0.),(0.,2.,0.),(1.,2.,0.),(2.,2.,0.),(3.,2.,0.),(0.,3.,0.),(1.,3.,0.),(2.,3.,0.),(3.,3.,0.)]) - m0=MEDCouplingUMesh("mesh",2) - m0.allocateCells() - m0.setCoords(coords) - ## - mm=MEDFileUMesh() - mm.setMeshAtLevel(0,m0) - mm.setFamilyFieldArr(1,DataArrayInt([1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16])) - # - f1ts0=MEDFileField1TS() - f1ts1=MEDFileField1TS() - # - f0=MEDCouplingFieldDouble(ON_NODES) ; f0.setMesh(m0) ; f0.setName("f0NoPfl") - arr0=DataArrayDouble([0.,1.,2.,3.,1.,1.5,2.2,3.1,2.,2.2,3.,3.1,3.,3.1,3.5,4.]) - f0.setArray(arr0) - f0.checkCoherency() - f1ts0.setFieldNoProfileSBT(f0) - self.assertEqual(f1ts0.getMeshName(),"mesh") - # - pfl1=DataArrayInt([0,1,2,3,4,5,6,8,9,12]) ; pfl1.setName("pfl1") - f1=MEDCouplingFieldDouble(ON_NODES) ; f1.setName("f1Pfl") - arr1=DataArrayDouble([3.,2.,1.,0.,2.,1.5,0.,1.,0.,0.2]) - f1.setArray(arr1) - f1ts1.setFieldProfile(f1,mm,0,pfl1) - self.assertEqual(f1ts1.getMeshName(),"mesh") - # - fs=MEDFileFields() - fmts0=MEDFileFieldMultiTS() - fmts0.pushBackTimeStep(f1ts0) - fmts1=MEDFileFieldMultiTS() - fmts1.pushBackTimeStep(f1ts1) - fs.pushField(fmts0) ; fs.pushField(fmts1) - self.assertEqual(fs[0].getMeshName(),"mesh") - self.assertEqual(fs[1].getMeshName(),"mesh") - mm.write(fname,2) - fs.write(fname,0) - ########## GO for reading in MEDReader,by not loading all. Mesh is fully loaded but not fields values - ms=MEDFileMeshes(fname) - fields=MEDFileFields(fname,False) - fields.removeFieldsWithoutAnyTimeStep() - self.assertEqual(fields[0].getMeshName(),"mesh") - self.assertEqual(fields[1].getMeshName(),"mesh") - fields_per_mesh=[fields.partOfThisLyingOnSpecifiedMeshName(meshName) for meshName in ms.getMeshesNames()] - self.assertEqual(fields_per_mesh[0][0].getMeshName(),"mesh") - self.assertEqual(fields_per_mesh[0][1].getMeshName(),"mesh") - allFMTSLeavesToDisplay=[] - for fields in fields_per_mesh: - allFMTSLeavesToDisplay2=[] - for fmts in fields: - tmp=fmts.splitDiscretizations() - for itmp in tmp: - self.assertTrue(not itmp.presenceOfMultiDiscPerGeoType()) - pass - allFMTSLeavesToDisplay2+=tmp - pass - allFMTSLeavesToDisplay.append(allFMTSLeavesToDisplay2) - pass - self.assertEqual(len(allFMTSLeavesToDisplay),1) - self.assertEqual(len(allFMTSLeavesToDisplay[0]),2) - allFMTSLeavesPerTimeSeries=MEDFileAnyTypeFieldMultiTS.SplitIntoCommonTimeSeries(sum(allFMTSLeavesToDisplay,[])) - self.assertEqual(len(allFMTSLeavesPerTimeSeries),1) - self.assertEqual(len(allFMTSLeavesPerTimeSeries[0]),2) - allFMTSLeavesPerCommonSupport1=MEDFileAnyTypeFieldMultiTS.SplitPerCommonSupport(allFMTSLeavesToDisplay[0],ms[ms.getMeshesNames()[0]]) - self.assertEqual(len(allFMTSLeavesPerCommonSupport1),2) - self.assertEqual(len(allFMTSLeavesPerCommonSupport1[0][0]),1) - self.assertEqual(len(allFMTSLeavesPerCommonSupport1[1][0]),1) - # - mst=MEDFileMeshStruct.New(ms[0]) - # - fcscp=allFMTSLeavesPerCommonSupport1[0][1] - mml=fcscp.buildFromScratchDataSetSupport(0,fields) - mml2=mml.prepare() - self.assertTrue(isinstance(mml2,MEDUMeshMultiLev)) - ncc,a0,a1,a2,a3,a4,a5=mml2.buildVTUArrays() - self.assertTrue(ncc) - self.assertTrue(a0.isEqual(DataArrayDouble([(0.,0.,0.),(1.,0.,0.),(2.,0.,0.),(3.,0.,0.),(0.,1.,0.),(1.,1.,0.),(2.,1.,0.),(3.,1.,0.),(0.,2.,0.),(1.,2.,0.),(2.,2.,0.),(3.,2.,0.),(0.,3.,0.),(1.,3.,0.),(2.,3.,0.),(3.,3.,0.)]),1e-12)) - self.assertTrue(a1.isEqual(DataArrayByte([]))) - self.assertTrue(a2.isEqual(DataArrayInt([]))) - self.assertTrue(a3.isEqual(DataArrayInt([]))) - self.assertTrue(a4 is None) - self.assertTrue(a5 is None) - # - fff0=allFMTSLeavesPerCommonSupport1[0][0][0][0] - fsst=MEDFileField1TSStructItem.BuildItemFrom(fff0,mst) - fff0.loadArraysIfNecessary() - v=mml2.buildDataArray(fsst,fields,fff0.getUndergroundDataArray()) - self.assertEqual(fff0.getName(),"f0NoPfl") - self.assertEqual(v.getHiddenCppPointer(),fff0.getUndergroundDataArray().getHiddenCppPointer()) - vExp=DataArrayDouble([0.,1.,2.,3.,1.,1.5,2.2,3.1,2.,2.2,3.,3.1,3.,3.1,3.5,4]) - self.assertTrue(v.isEqual(vExp,1e-12)) - # - fcscp=allFMTSLeavesPerCommonSupport1[1][1] - mml=fcscp.buildFromScratchDataSetSupport(0,fields) - mml2=mml.prepare() - self.assertTrue(isinstance(mml2,MEDUMeshMultiLev)) - ncc,a0,a1,a2,a3,a4,a5=mml2.buildVTUArrays() - self.assertTrue(not ncc) - self.assertTrue(a0.isEqual(DataArrayDouble([(0,0,0),(1,0,0),(2,0,0),(3,0,0),(0,1,0),(1,1,0),(2,1,0),(0,2,0),(1,2,0),(0,3,0)]),1e-12)) - self.assertTrue(a1.isEqual(DataArrayByte([]))) - self.assertTrue(a2.isEqual(DataArrayInt([]))) - self.assertTrue(a3.isEqual(DataArrayInt([]))) - self.assertTrue(a4 is None) - self.assertTrue(a5 is None) - fff1=allFMTSLeavesPerCommonSupport1[1][0][0][0] - fsst=MEDFileField1TSStructItem.BuildItemFrom(fff1,mst) - fff1.loadArraysIfNecessary() - v=mml2.buildDataArray(fsst,fields,fff1.getUndergroundDataArray()) - self.assertEqual(fff1.getName(),"f1Pfl") - self.assertNotEqual(v.getHiddenCppPointer(),fff1.getUndergroundDataArray().getHiddenCppPointer()) # pointers are not equal because Profile - vExp=DataArrayDouble([3.,2.,1.,0.,2.,1.5,0.,1.,0.,0.2]) - self.assertTrue(v.isEqual(vExp,1e-12)) - pass - - def test28(self): - """ This test defines 2 fields f0,f1,f2,f3 lying on an unstructured mesh whith cells including NORM_POINT1. - Both f0 and f1 are on NODES and f2 and f3 are on cells. f1 and f2 share the same support. - f0 is on a nodal support that is not matchable with any cells (including NORM_POINT1) - This test is a more aggressive version of test26. - """ - fname="ForMEDReader28.med" - coords=DataArrayDouble([(0.,0.,0.),(1.,0.,0.),(2.,0.,0.),(3.,0.,0.),(0.,1.,0.),(1.,1.,0.),(2.,1.,0.),(3.,1.,0.),(0.,2.,0.),(1.,2.,0.),(2.,2.,0.),(3.,2.,0.),(0.,3.,0.),(1.,3.,0.),(2.,3.,0.),(3.,3.,0.)]) - m0=MEDCouplingUMesh("mesh",2) - m0.allocateCells() - for elt in [[2,6,3],[6,7,3],[9,6,5],[9,10,6]]: - m0.insertNextCell(NORM_TRI3,elt) - pass - for elt in [[0,4,5,1],[1,5,6,2],[4,8,9,5],[6,10,11,7],[8,12,13,9],[9,13,14,10],[10,14,15,11]]: - m0.insertNextCell(NORM_QUAD4,elt) - pass - m0.setCoords(coords) - m2=MEDCouplingUMesh("mesh",0) ; m2.setCoords(coords) - m2.allocateCells() - for elt in [[8],[13]]: - m2.insertNextCell(NORM_POINT1,elt) - pass - ## - mm=MEDFileUMesh() - mm.setMeshAtLevel(0,m0) - mm.setMeshAtLevel(-2,m2) - mm.setFamilyFieldArr(0,DataArrayInt([-1,-2,-3,-4,-5,-6,-7,-8,-9,-10,-11])) - mm.setFamilyFieldArr(-2,DataArrayInt([-12,-13])) - mm.setFamilyFieldArr(1,DataArrayInt([1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16])) - # - f1ts0Node=MEDFileField1TS() - f1ts1Node=MEDFileField1TS() - f1ts2Cell=MEDFileField1TS() - f1ts3Cell=MEDFileField1TS() - # - pfl0=DataArrayInt([4,5,6,8,9,12]) ; pfl0.setName("pfl0") - pfl1=DataArrayInt([0,1,4,5,7,10]) ; pfl1.setName("pfl1") - pfl2=DataArrayInt([0,1,2,3,4,5,6,7,10,11,14,15]) ; pfl2.setName("pfl2") - # - f0Node=MEDCouplingFieldDouble(ON_NODES) ; f0Node.setName("f0Node") - arr0=DataArrayDouble(6) ; arr0.iota() - f0Node.setArray(arr0) - f1ts0Node.setFieldProfile(f0Node,mm,0,pfl0) - # - f1Node=MEDCouplingFieldDouble(ON_NODES) ; f1Node.setName("f1Node") - arr1=DataArrayDouble(12) ; arr1.iota() ; arr1.reverse() - f1Node.setArray(arr1) - f1ts1Node.setFieldProfile(f1Node,mm,0,pfl2) - # - f2Cell=MEDCouplingFieldDouble(ON_CELLS) ; f2Cell.setName("f2Cell") - arr2=DataArrayDouble([2,3,0,1,4,5]) - f2Cell.setArray(arr2) - f1ts2Cell.setFieldProfile(f2Cell,mm,0,pfl1) - # - f3Cell=MEDCouplingFieldDouble(ON_CELLS) ; f3Cell.setName("f3Cell") - arr3=DataArrayDouble([5,4,3,2,1,0]) ; f3Cell.setArray(arr3) - f1ts3Cell.setFieldProfile(f3Cell,mm,0,pfl1) - f3Cell.setMesh(m2) - arr3=DataArrayDouble([-1.1,-3.1]) ; f3Cell.setArray(arr3) - f1ts3Cell.setFieldNoProfileSBT(f3Cell) - # - fs=MEDFileFields() - for f in [f1ts0Node,f1ts1Node,f1ts2Cell,f1ts3Cell]: - fmts=MEDFileFieldMultiTS() - fmts.pushBackTimeStep(f) - fs.pushField(fmts) - pass - mm.write(fname,2) - fs.write(fname,0) - ########## GO for reading in MEDReader,by not loading all. Mesh is fully loaded but not fields values - ms=MEDFileMeshes(fname) - fields=MEDFileFields(fname,False) - fields.removeFieldsWithoutAnyTimeStep() - fields_per_mesh=[fields.partOfThisLyingOnSpecifiedMeshName(meshName) for meshName in ms.getMeshesNames()] - allFMTSLeavesToDisplay=[] - for fields in fields_per_mesh: - allFMTSLeavesToDisplay2=[] - for fmts in fields: - tmp=fmts.splitDiscretizations() - for itmp in tmp: - self.assertTrue(not itmp.presenceOfMultiDiscPerGeoType()) - pass - allFMTSLeavesToDisplay2+=tmp - pass - allFMTSLeavesToDisplay.append(allFMTSLeavesToDisplay2) - pass - self.assertEqual(len(allFMTSLeavesToDisplay),1) - self.assertEqual(len(allFMTSLeavesToDisplay[0]),4) - allFMTSLeavesPerTimeSeries=MEDFileAnyTypeFieldMultiTS.SplitIntoCommonTimeSeries(sum(allFMTSLeavesToDisplay,[])) - self.assertEqual(len(allFMTSLeavesPerTimeSeries),1) - self.assertEqual(len(allFMTSLeavesPerTimeSeries[0]),4) - allFMTSLeavesPerCommonSupport1=MEDFileAnyTypeFieldMultiTS.SplitPerCommonSupport(allFMTSLeavesToDisplay[0],ms[ms.getMeshesNames()[0]]) - self.assertEqual(len(allFMTSLeavesPerCommonSupport1),3) - self.assertEqual(len(allFMTSLeavesPerCommonSupport1[0][0]),2) - self.assertEqual(len(allFMTSLeavesPerCommonSupport1[1][0]),1) - self.assertEqual(len(allFMTSLeavesPerCommonSupport1[2][0]),1) - # - mst=MEDFileMeshStruct.New(ms[0]) - # - fcscp=allFMTSLeavesPerCommonSupport1[2][1] - mml=fcscp.buildFromScratchDataSetSupport(0,fields) - mml2=mml.prepare() - self.assertTrue(isinstance(mml2,MEDUMeshMultiLev)) - ncc,a0,a1,a2,a3,a4,a5=mml2.buildVTUArrays() - self.assertTrue(not ncc) - self.assertTrue(a0.isEqual(DataArrayDouble([0.,1.,0.,1.,1.,0.,2.,1.,0.,0.,2.,0.,1.,2.,0.,0.,3.,0.],6,3),1e-12)) - self.assertTrue(a1.isEqual(DataArrayByte([5,9,1,1]))) - self.assertTrue(a2.isEqual(DataArrayInt([0,4,9,11]))) - self.assertTrue(a3.isEqual(DataArrayInt([3,4,2,1,4,0,3,4,1,1,3,1,5]))) - self.assertTrue(a4 is None) - self.assertTrue(a5 is None) - a6,a7=mml2.retrieveFamilyIdsOnCells() - self.assertTrue(a6.isEqual(DataArrayInt([-3,-7,-12,13]))) - self.assertTrue(not a7) # copy here because profile on cells - a8,a9=mml2.retrieveNumberIdsOnCells() - self.assertTrue(a8 is None) - self.assertTrue(a9) # no copy here because no number field - a10,a11=mml2.retrieveFamilyIdsOnNodes() - self.assertTrue(a10.isEqual(DataArrayInt([5,6,7,9,10,13]))) - self.assertTrue(not a11) # copy here - a12,a13=mml2.retrieveNumberIdsOnNodes() - self.assertTrue(a12 is None) - self.assertTrue(a13) # no copy here because no number field - # - fff0=allFMTSLeavesPerCommonSupport1[2][0][0][0] - fsst=MEDFileField1TSStructItem.BuildItemFrom(fff0,mst) - fff0.loadArraysIfNecessary() - v=mml2.buildDataArray(fsst,fields,fff0.getUndergroundDataArray()) - self.assertEqual(fff0.getName(),"f0Node") - self.assertEqual(v.getHiddenCppPointer(),fff0.getUndergroundDataArray().getHiddenCppPointer()) - vExp=DataArrayDouble([0.,1.,2.,3.,4.,5.]) - self.assertTrue(v.isEqual(vExp,1e-12)) # <- THE test is here !!! - ### - fcscp=allFMTSLeavesPerCommonSupport1[0][1] - mml=fcscp.buildFromScratchDataSetSupport(0,fields) - mml2=mml.prepare() - self.assertTrue(isinstance(mml2,MEDUMeshMultiLev)) - ncc,a0,a1,a2,a3,a4,a5=mml2.buildVTUArrays() - self.assertTrue(not ncc) - self.assertTrue(a0.isEqual(DataArrayDouble([(0,0,0),(1,0,0),(2,0,0),(3,0,0),(0,1,0),(1,1,0),(2,1,0),(3,1,0),(2,2,0),(3,2,0),(2,3,0),(3,3,0)]),1e-12)) - self.assertTrue(a1.isEqual(DataArrayByte([5,5,9,9,9,9]))) - self.assertTrue(a2.isEqual(DataArrayInt([0,4,8,13,18,23]))) - self.assertTrue(a3.isEqual(DataArrayInt([3,2,6,3,3,6,7,3,4,0,4,5,1,4,1,5,6,2,4,6,8,9,7,4,8,10,11,9]))) - self.assertTrue(a4 is None) - self.assertTrue(a5 is None) - fff1=allFMTSLeavesPerCommonSupport1[0][0][0][0] - fsst=MEDFileField1TSStructItem.BuildItemFrom(fff1,mst) - fff1.loadArraysIfNecessary() - v=mml2.buildDataArray(fsst,fields,fff1.getUndergroundDataArray()) - self.assertEqual(fff1.getName(),"f2Cell") - self.assertNotEqual(v.getHiddenCppPointer(),fff0.getUndergroundDataArray().getHiddenCppPointer()) - vExp=DataArrayDouble([2,3,0,1,4,5]) - self.assertTrue(v.isEqual(vExp,1e-12)) - fff2=allFMTSLeavesPerCommonSupport1[0][0][1][0] - fsst=MEDFileField1TSStructItem.BuildItemFrom(fff2,mst) - fff2.loadArraysIfNecessary() - v=mml2.buildDataArray(fsst,fields,fff2.getUndergroundDataArray()) - self.assertEqual(fff2.getName(),"f1Node") - self.assertNotEqual(v.getHiddenCppPointer(),fff0.getUndergroundDataArray().getHiddenCppPointer()) - vExp=DataArrayDouble([11,10,9,8,7,6,5,4,3,2,1,0]) - self.assertTrue(v.isEqual(vExp,1e-12)) - ### - fcscp=allFMTSLeavesPerCommonSupport1[1][1] - mml=fcscp.buildFromScratchDataSetSupport(0,fields) - mml2=mml.prepare() - self.assertTrue(isinstance(mml2,MEDUMeshMultiLev)) - ncc,a0,a1,a2,a3,a4,a5=mml2.buildVTUArrays() - self.assertTrue(ncc)# here all the 16 nodes are taken - self.assertTrue(a0.isEqual(DataArrayDouble([(0.,0.,0.),(1.,0.,0.),(2.,0.,0.),(3.,0.,0.),(0.,1.,0.),(1.,1.,0.),(2.,1.,0.),(3.,1.,0.),(0.,2.,0.),(1.,2.,0.),(2.,2.,0.),(3.,2.,0.),(0.,3.,0.),(1.,3.,0.),(2.,3.,0.),(3.,3.,0.)]),1e-12)) - self.assertTrue(a1.isEqual(DataArrayByte([1,1,5,5,9,9,9,9]))) - self.assertTrue(a2.isEqual(DataArrayInt([0,2,4,8,12,17,22,27]))) - self.assertTrue(a3.isEqual(DataArrayInt([1,8,1,13,3,2,6,3,3,6,7,3,4,0,4,5,1,4,1,5,6,2,4,6,10,11,7,4,10,14,15,11]))) - self.assertTrue(a4 is None) - self.assertTrue(a5 is None) - fff3=allFMTSLeavesPerCommonSupport1[1][0][0][0] - fsst=MEDFileField1TSStructItem.BuildItemFrom(fff3,mst) - fff3.loadArraysIfNecessary() - v=mml2.buildDataArray(fsst,fields,fff3.getUndergroundDataArray()) - self.assertEqual(fff3.getName(),"f3Cell") - self.assertNotEqual(v.getHiddenCppPointer(),fff0.getUndergroundDataArray().getHiddenCppPointer()) - vExp=DataArrayDouble([-1.1,-3.1,5,4,3,2,1,0]) - self.assertTrue(v.isEqual(vExp,1e-12)) - pass - - def test29(self): - """ This test focused on HEXA27 cell for which the MED numbering is not equal to the VTK numbering. So here the HEXA27 cell is those in MED file documentation (reference element). - """ - fname="ForMEDReader29.med" - coo=DataArrayDouble([[0.,2.,2.],[0.,0.,2.],[2.,0.,2.],[2.,2.,2.],[0.,2.,0.],[0.,0.,0.],[2.,0.,0.],[2.,2.,0.], [0.,1.,2.],[1.,0.,2.],[2.,1.,2.],[1.,2.,2.], [0.,1.,0.],[1.,0.,0.],[2.,1.,0.],[1.,2.,0.], [0.,2.,1.],[0.,0.,1.],[2.,0.,1.],[2.,2.,1.], [1.,1.,2.], [0.,1.,1.],[1.,0.,1.],[2.,1.,1.],[1.,2.,1.], [1.,1.,0.], [1.,1.,1.]]) - m=MEDCouplingUMesh("mesh",3) ; m.setCoords(coo) - m.allocateCells() - # MED = [0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26] - # VTK = [0,1,2,3,4,5,6,7, 8,9,10,11,12,13,14,15,16,17,18,19,24,22,21,23,20,25,26] - m.insertNextCell(NORM_HEXA27,[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26]) - fCell=MEDCouplingFieldDouble(ON_CELLS) ; fCell.setName("fCell") - arrCell=DataArrayDouble([7.]) ; arrCell.setInfoOnComponent(0,"smth") ; fCell.setArray(arrCell) - fCell.setMesh(m) - MEDLoader.WriteField(fname,fCell,True) - refCoo=[-1.,-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.,0.,1.,-1.,1.,0.,-1.,0.,-1.,-1.,-1.,0.,1.,0.,1.,1.,1.,0.,1.,0.,-1.,1.,-1.,-1.,0.,-1.,1.,0.,1.,1.,0.,1.,-1.,0.,0.,0.,-1.,-1.,0.,0.,0.,1.,0.,1.,0.,0.,0.,-1.,0.,0.,0.,1.,0.,0.,0.] - weights=[0.1714677640603571,0.27434842249657115,0.1714677640603571,0.27434842249657115,0.43895747599451346,0.27434842249657115,0.1714677640603571,0.27434842249657115,0.1714677640603571,0.27434842249657115,0.43895747599451346,0.27434842249657115,0.43895747599451346,0.7023319615912209,0.43895747599451346,0.27434842249657115,0.43895747599451346,0.27434842249657115,0.1714677640603571,0.27434842249657115,0.1714677640603571,0.27434842249657115,0.43895747599451346,0.27434842249657115,0.1714677640603571,0.27434842249657115,0.1714677640603571] - gCoords=[-0.774596669241483,-0.774596669241483,-0.774596669241483,-0.774596669241483,-0.774596669241483,0.0,-0.774596669241483,-0.774596669241483,0.774596669241483,-0.774596669241483,0.0,-0.774596669241483,-0.774596669241483,0.0,0.0,-0.774596669241483,0.0,0.774596669241483,-0.774596669241483,0.774596669241483,-0.774596669241483,-0.774596669241483,0.774596669241483,0.0,-0.774596669241483,0.774596669241483,0.774596669241483,0.0,-0.774596669241483,-0.774596669241483,0.0,-0.774596669241483,0.0,0.0,-0.774596669241483,0.774596669241483,0.0,0.0,-0.774596669241483,0.0,0.0,0.0,0.0,0.0,0.774596669241483,0.0,0.774596669241483,-0.774596669241483,0.0,0.774596669241483,0.0,0.0,0.774596669241483,0.774596669241483,0.774596669241483,-0.774596669241483,-0.774596669241483,0.774596669241483,-0.774596669241483,0.0,0.774596669241483,-0.774596669241483,0.774596669241483,0.774596669241483,0.0,-0.774596669241483,0.774596669241483,0.0,0.0,0.774596669241483,0.0,0.774596669241483,0.774596669241483,0.774596669241483,-0.774596669241483,0.774596669241483,0.774596669241483,0.0,0.774596669241483,0.774596669241483,0.774596669241483] - fGauss=MEDCouplingFieldDouble(ON_GAUSS_PT) ; fGauss.setName("fGauss") - fGauss.setMesh(m) - fGauss.setGaussLocalizationOnType(NORM_HEXA27,refCoo,gCoords,weights) - arrGauss=DataArrayDouble(fGauss.getNumberOfTuplesExpected()) ; arrGauss.setInfoOnComponent(0,"gaussc") ; arrGauss.iota() - fGauss.setArray(arrGauss) - MEDLoader.WriteFieldUsingAlreadyWrittenMesh(fname,fGauss) - ########## GO for reading in MEDReader,by not loading all. Mesh is fully loaded but not fields values - ms=MEDFileMeshes(fname) - fields=MEDFileFields(fname,False) - fields.removeFieldsWithoutAnyTimeStep() - fields_per_mesh=[fields.partOfThisLyingOnSpecifiedMeshName(meshName) for meshName in ms.getMeshesNames()] - allFMTSLeavesToDisplay=[] - for fields in fields_per_mesh: - allFMTSLeavesToDisplay2=[] - for fmts in fields: - tmp=fmts.splitDiscretizations() - for itmp in tmp: - self.assertTrue(not itmp.presenceOfMultiDiscPerGeoType()) - pass - allFMTSLeavesToDisplay2+=tmp - pass - allFMTSLeavesToDisplay.append(allFMTSLeavesToDisplay2) - pass - self.assertEqual(len(allFMTSLeavesToDisplay),1) - self.assertEqual(len(allFMTSLeavesToDisplay[0]),2) - allFMTSLeavesPerTimeSeries=MEDFileAnyTypeFieldMultiTS.SplitIntoCommonTimeSeries(sum(allFMTSLeavesToDisplay,[])) - self.assertEqual(len(allFMTSLeavesPerTimeSeries),1) - self.assertEqual(len(allFMTSLeavesPerTimeSeries[0]),2) - allFMTSLeavesPerCommonSupport1=MEDFileAnyTypeFieldMultiTS.SplitPerCommonSupport(allFMTSLeavesToDisplay[0],ms[ms.getMeshesNames()[0]]) - self.assertEqual(len(allFMTSLeavesPerCommonSupport1),1) - self.assertEqual(len(allFMTSLeavesPerCommonSupport1[0][0]),2) - # - mst=MEDFileMeshStruct.New(ms[0]) - # - fcscp=allFMTSLeavesPerCommonSupport1[0][1] - mml=fcscp.buildFromScratchDataSetSupport(0,fields) - mml2=mml.prepare() - self.assertTrue(isinstance(mml2,MEDUMeshMultiLev)) - ncc,a0,a1,a2,a3,a4,a5=mml2.buildVTUArrays() - self.assertTrue(a0.isEqual(coo,1e-12)) - self.assertTrue(a1.isEqual(DataArrayByte([29]))) - self.assertTrue(a2.isEqual(DataArrayInt([0]))) - # the connectivity must be not a iota as declared in m.insertNextCell - self.assertTrue(a3.isEqual(DataArrayInt([27,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,24,22,21,23,20,25,26])))# the test is on this line to check that connectivity has been processed for HEXA27 - self.assertTrue(a4 is None) - self.assertTrue(a5 is None) - ffCell=allFMTSLeavesPerCommonSupport1[0][0][0][0] - fsst=MEDFileField1TSStructItem.BuildItemFrom(ffCell,mst) - ffCell.loadArraysIfNecessary() - v=mml2.buildDataArray(fsst,fields,ffCell.getUndergroundDataArray()) - self.assertEqual(v.getHiddenCppPointer(),ffCell.getUndergroundDataArray().getHiddenCppPointer()) - self.assertEqual(ffCell.getName(),"fCell") - self.assertTrue(v.isEqual(arrCell,1e-12)) ; self.assertTrue(v.isEqualWithoutConsideringStr(DataArrayDouble([7.]),1e-12)) ; self.assertEqual(v.getInfoOnComponents(),["smth"]) - del ffCell - # - ffGauss=allFMTSLeavesPerCommonSupport1[0][0][1][0] - fsst=MEDFileField1TSStructItem.BuildItemFrom(ffGauss,mst) - ffGauss.loadArraysIfNecessary() - v=mml2.buildDataArray(fsst,fields,ffGauss.getUndergroundDataArray()) - self.assertEqual(v.getHiddenCppPointer(),ffGauss.getUndergroundDataArray().getHiddenCppPointer()) - self.assertEqual(ffGauss.getName(),"fGauss") - self.assertTrue(v.isEqual(arrGauss,1e-12)) ; self.assertTrue(v.isEqualWithoutConsideringStr(DataArrayDouble(range(27)),1e-12)) ; self.assertEqual(v.getInfoOnComponents(),["gaussc"]) - ffGauss=allFMTSLeavesPerCommonSupport1[0][0][1][0] - pass - - def test30(self): - """ This test is focused on cartesian meshes. Here the cartesian mesh "CartMesh" has a field on HEXA8 (FieldOnCells) and a field on QUAD4 (FieldOnFaces). - So the first one (FieldOnCells) lies on a cartesian mesh whereas the second one lies on unstructured one. - """ - fname="ForMEDReader30.med" - c=MEDCouplingCMesh() - arrX=DataArrayDouble(3) ; arrX.iota() - arrY=DataArrayDouble(4) ; arrY.iota() - arrZ=DataArrayDouble(5) ; arrZ.iota() - c.setCoords(arrX,arrY,arrZ) - c.setName("CartMesh") - cc=MEDFileCMesh() - cc.setMesh(c) - tmpFacesMesh=c.build1SGTSubLevelMesh() - famIdFaces=DataArrayInt(98) ; famIdFaces[:36]=-1 ; famIdFaces[36:68]=-2 ; famIdFaces[68:]=-3 - famIdCells=DataArrayInt(24) ; famIdCells[:]=0 - #cc.setFamilyFieldArr(0,famIdCells) - #cc.setFamilyFieldArr(-1,famIdFaces) - cc.addFamily("FacesX",-1) ; cc.addFamily("FacesY",-2) ; cc.addFamily("FacesZ",-3) - cc.setFamiliesOnGroup("FacesX1",["FacesX"]) - cc.setFamiliesOnGroup("FacesY1",["FacesY"]) - cc.setFamiliesOnGroup("FacesZ1",["FacesZ"]) - # - fmts0=MEDFileFieldMultiTS() - fmts1=MEDFileFieldMultiTS() - for i in xrange(30): - f1ts=MEDFileField1TS() - fFaces=MEDCouplingFieldDouble(ON_CELLS) ; fFaces.setName("FieldOnFaces") - arr=DataArrayDouble(98) ; arr.iota() ; arr[i]=100. - fFaces.setArray(arr) - fFaces.setTime(float(i)+0.1,i,-1) - fFaces.setMesh(tmpFacesMesh) - f1ts.setFieldNoProfileSBT(fFaces) - fmts0.pushBackTimeStep(f1ts) - # - f1ts=MEDFileField1TS() - fCells=MEDCouplingFieldDouble(ON_CELLS) ; fCells.setName("FieldOnCells") - arr=DataArrayDouble(24) ; arr.iota() ; arr[i%24]=30. - fCells.setArray(arr) - fCells.setTime(float(i)+0.1,i,-1) - fCells.setMesh(c) - f1ts.setFieldNoProfileSBT(fCells) - fmts1.pushBackTimeStep(f1ts) - pass - fs=MEDFileFields() - fs.pushField(fmts0) - fs.pushField(fmts1) - cc.write(fname,2) - fs.write(fname,0) - ########## GO for reading in MEDReader,by not loading all. Mesh is fully loaded but not fields values - ms=MEDFileMeshes(fname) - fields=MEDFileFields(fname,False) - fields.removeFieldsWithoutAnyTimeStep() - fields_per_mesh=[fields.partOfThisLyingOnSpecifiedMeshName(meshName) for meshName in ms.getMeshesNames()] - allFMTSLeavesToDisplay=[] - for fields in fields_per_mesh: - allFMTSLeavesToDisplay2=[] - for fmts in fields: - tmp=fmts.splitDiscretizations() - for itmp in tmp: - self.assertTrue(not itmp.presenceOfMultiDiscPerGeoType()) - pass - allFMTSLeavesToDisplay2+=tmp - pass - allFMTSLeavesToDisplay.append(allFMTSLeavesToDisplay2) - pass - self.assertEqual(len(allFMTSLeavesToDisplay),1) - self.assertEqual(len(allFMTSLeavesToDisplay[0]),2) - allFMTSLeavesPerTimeSeries=MEDFileAnyTypeFieldMultiTS.SplitIntoCommonTimeSeries(sum(allFMTSLeavesToDisplay,[])) - self.assertEqual(len(allFMTSLeavesPerTimeSeries),1) - self.assertEqual(len(allFMTSLeavesPerTimeSeries[0]),2) - allFMTSLeavesPerCommonSupport1=MEDFileAnyTypeFieldMultiTS.SplitPerCommonSupport(allFMTSLeavesToDisplay[0],ms[ms.getMeshesNames()[0]]) - self.assertEqual(len(allFMTSLeavesPerCommonSupport1),2) - self.assertEqual(len(allFMTSLeavesPerCommonSupport1[0][0]),1) - self.assertEqual(len(allFMTSLeavesPerCommonSupport1[1][0]),1) - # - mst=MEDFileMeshStruct.New(ms[0]) - # - fcscp=allFMTSLeavesPerCommonSupport1[0][1] - mml=fcscp.buildFromScratchDataSetSupport(0,fields) - mml2=mml.prepare() - self.assertTrue(isinstance(mml2,MEDCMeshMultiLev)) # here CMesh is important - (a,b,c),d=mml2.buildVTUArrays() - self.assertTrue(d)#d is True because the a,b and c are directly those in the internal data structure - self.assertTrue(a.isEqual(arrX,1e-12)) - self.assertTrue(b.isEqual(arrY,1e-12)) - self.assertTrue(c.isEqual(arrZ,1e-12)) - for i in xrange(30): - ffCell=allFMTSLeavesPerCommonSupport1[0][0][0][i] - fsst=MEDFileField1TSStructItem.BuildItemFrom(ffCell,mst) - ffCell.loadArraysIfNecessary() - v=mml2.buildDataArray(fsst,fields,ffCell.getUndergroundDataArray()) - self.assertEqual(v.getHiddenCppPointer(),ffCell.getUndergroundDataArray().getHiddenCppPointer()) - myarr=DataArrayDouble(24) ; myarr.iota() ; myarr[i%24]=30. - self.assertEqual(ffCell.getName(),"FieldOnCells") - self.assertTrue(v.isEqual(myarr,1e-12)) - pass - # - fcscp=allFMTSLeavesPerCommonSupport1[1][1] - mml=fcscp.buildFromScratchDataSetSupport(0,fields) - mml2=mml.prepare() - self.assertTrue(isinstance(mml2,MEDUMeshMultiLev)) # here UMesh is important - ref=ms[0].getImplicitFaceMesh().getCoords().getHiddenCppPointer() - ncc,a0,a1,a2,a3,a4,a5=mml2.buildVTUArrays() - self.assertEqual(ref,a0.getHiddenCppPointer()) - self.assertTrue(ncc) - self.assertTrue(a1.isEqual(DataArrayByte([9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9]))) - self.assertTrue(a2.isEqual(DataArrayInt([0,5,10,15,20,25,30,35,40,45,50,55,60,65,70,75,80,85,90,95,100,105,110,115,120,125,130,135,140,145,150,155,160,165,170,175,180,185,190,195,200,205,210,215,220,225,230,235,240,245,250,255,260,265,270,275,280,285,290,295,300,305,310,315,320,325,330,335,340,345,350,355,360,365,370,375,380,385,390,395,400,405,410,415,420,425,430,435,440,445,450,455,460,465,470,475,480,485]))) - self.assertTrue(a3.isEqual(DataArrayInt([4,0,12,15,3,4,12,24,27,15,4,24,36,39,27,4,36,48,51,39,4,3,15,18,6,4,15,27,30,18,4,27,39,42,30,4,39,51,54,42,4,6,18,21,9,4,18,30,33,21,4,30,42,45,33,4,42,54,57,45,4,1,13,16,4,4,13,25,28,16,4,25,37,40,28,4,37,49,52,40,4,4,16,19,7,4,16,28,31,19,4,28,40,43,31,4,40,52,55,43,4,7,19,22,10,4,19,31,34,22,4,31,43,46,34,4,43,55,58,46,4,2,14,17,5,4,14,26,29,17,4,26,38,41,29,4,38,50,53,41,4,5,17,20,8,4,17,29,32,20,4,29,41,44,32,4,41,53,56,44,4,8,20,23,11,4,20,32,35,23,4,32,44,47,35,4,44,56,59,47,4,0,12,13,1,4,12,24,25,13,4,24,36,37,25,4,36,48,49,37,4,1,13,14,2,4,13,25,26,14,4,25,37,38,26,4,37,49,50,38,4,3,15,16,4,4,15,27,28,16,4,27,39,40,28,4,39,51,52,40,4,4,16,17,5,4,16,28,29,17,4,28,40,41,29,4,40,52,53,41,4,6,18,19,7,4,18,30,31,19,4,30,42,43,31,4,42,54,55,43,4,7,19,20,8,4,19,31,32,20,4,31,43,44,32,4,43,55,56,44,4,9,21,22,10,4,21,33,34,22,4,33,45,46,34,4,45,57,58,46,4,10,22,23,11,4,22,34,35,23,4,34,46,47,35,4,46,58,59,47,4,0,1,4,3,4,3,4,7,6,4,6,7,10,9,4,1,2,5,4,4,4,5,8,7,4,7,8,11,10,4,12,13,16,15,4,15,16,19,18,4,18,19,22,21,4,13,14,17,16,4,16,17,20,19,4,19,20,23,22,4,24,25,28,27,4,27,28,31,30,4,30,31,34,33,4,25,26,29,28,4,28,29,32,31,4,31,32,35,34,4,36,37,40,39,4,39,40,43,42,4,42,43,46,45,4,37,38,41,40,4,40,41,44,43,4,43,44,47,46,4,48,49,52,51,4,51,52,55,54,4,54,55,58,57,4,49,50,53,52,4,52,53,56,55,4,55,56,59,58]))) - self.assertTrue(a4 is None) - self.assertTrue(a5 is None) - for i in xrange(30): - ffCell=allFMTSLeavesPerCommonSupport1[1][0][0][i] - fsst=MEDFileField1TSStructItem.BuildItemFrom(ffCell,mst) - ffCell.loadArraysIfNecessary() - v=mml2.buildDataArray(fsst,fields,ffCell.getUndergroundDataArray()) - self.assertEqual(v.getHiddenCppPointer(),ffCell.getUndergroundDataArray().getHiddenCppPointer()) - myarr=DataArrayDouble(98) ; myarr.iota() ; myarr[i]=100. - self.assertEqual(ffCell.getName(),"FieldOnFaces") - self.assertTrue(v.isEqual(myarr,1e-12)) - pass - pass - - def test31(self): - """non regression test of EDF 7972""" - fname="ForMEDReader31.med" - c=MEDCouplingCMesh() - arrX=DataArrayDouble(3) ; arrX.iota() - arrY=DataArrayDouble(4) ; arrY.iota() - arrZ=DataArrayDouble(5) ; arrZ.iota() - c.setCoords(arrX,arrY,arrZ) - c.setName("CartMesh") - cc=MEDFileCMesh() - cc.setMesh(c) - famIdCells=DataArrayInt(24) ; famIdCells[:]=0 - cc.setFamilyFieldArr(0,famIdCells) - #cc.setFamilyFieldArr(-1,famIdFaces) - cc.addFamily("FacesX",-1) ; cc.addFamily("FacesY",-2) ; cc.addFamily("FacesZ",-3) - cc.setFamiliesOnGroup("FacesX1",["FacesX"]) - cc.setFamiliesOnGroup("FacesY1",["FacesY"]) - cc.setFamiliesOnGroup("FacesZ1",["FacesZ"]) - fmts0=MEDFileFieldMultiTS() - fmts1=MEDFileFieldMultiTS() - pfl=DataArrayInt(11) ; pfl.iota() ; pfl.setName("PflOnHECA8") - for i in xrange(30): - f1ts=MEDFileField1TS() - fFaces=MEDCouplingFieldDouble(ON_CELLS) ; fFaces.setName("FieldOnCells") - arr=DataArrayDouble(11) ; arr.iota() ; arr[i%11]=100. - fFaces.setArray(arr) - fFaces.setTime(float(i)+0.1,i,-1) - fFaces.setMesh(c.buildUnstructured()[:11]) - f1ts.setFieldProfile(fFaces,cc,0,pfl)# here, a test is done to check that "NORM_HEXA8" string is not 30 times appended at the end of pfl name. - self.assertEqual("PflOnHECA8",pfl.getName()) - fmts0.pushBackTimeStep(f1ts) - pass - fs=MEDFileFields() - fs.pushField(fmts0) - cc.write(fname,2) - fs.write(fname,0) - ########## GO for reading in MEDReader,by not loading all. Mesh is fully loaded but not fields values - ms=MEDFileMeshes(fname) - fields=MEDFileFields(fname,False) - fields.removeFieldsWithoutAnyTimeStep() - fields_per_mesh=[fields.partOfThisLyingOnSpecifiedMeshName(meshName) for meshName in ms.getMeshesNames()] - allFMTSLeavesToDisplay=[] - for fields in fields_per_mesh: - allFMTSLeavesToDisplay2=[] - for fmts in fields: - tmp=fmts.splitDiscretizations() - for itmp in tmp: - self.assertTrue(not itmp.presenceOfMultiDiscPerGeoType()) - pass - allFMTSLeavesToDisplay2+=tmp - pass - allFMTSLeavesToDisplay.append(allFMTSLeavesToDisplay2) - pass - self.assertEqual(len(allFMTSLeavesToDisplay),1) - self.assertEqual(len(allFMTSLeavesToDisplay[0]),1) - allFMTSLeavesPerTimeSeries=MEDFileAnyTypeFieldMultiTS.SplitIntoCommonTimeSeries(sum(allFMTSLeavesToDisplay,[])) - self.assertEqual(len(allFMTSLeavesPerTimeSeries),1) - self.assertEqual(len(allFMTSLeavesPerTimeSeries[0]),1) - allFMTSLeavesPerCommonSupport1=MEDFileAnyTypeFieldMultiTS.SplitPerCommonSupport(allFMTSLeavesToDisplay[0],ms[ms.getMeshesNames()[0]]) - self.assertEqual(len(allFMTSLeavesPerCommonSupport1),1) - self.assertEqual(len(allFMTSLeavesPerCommonSupport1[0][0]),1) - # - mst=MEDFileMeshStruct.New(ms[0]) - # - fcscp=allFMTSLeavesPerCommonSupport1[0][1] - mml=fcscp.buildFromScratchDataSetSupport(0,fields) - mml2=mml.prepare() - self.assertTrue(isinstance(mml2,MEDUMeshMultiLev)) # here UMesh is important - ncc,a0,a1,a2,a3,a4,a5=mml2.buildVTUArrays() - self.assertTrue(not ncc)# here ncc=False because the coordinates are not in ms neither in children. This is the most important line in the test. - self.assertTrue(a0.isEqual(DataArrayDouble([0.,0.,0.,1.,0.,0.,2.,0.,0.,0.,1.,0.,1.,1.,0.,2.,1.,0.,0.,2.,0.,1.,2.,0.,2.,2.,0.,0.,3.,0.,1.,3.,0.,2.,3.,0.,0.,0.,1.,1.,0.,1.,2.,0.,1.,0.,1.,1.,1.,1.,1.,2.,1.,1.,0.,2.,1.,1.,2.,1.,2.,2.,1.,0.,3.,1.,1.,3.,1.,2.,3.,1.,0.,0.,2.,1.,0.,2.,2.,0.,2.,0.,1.,2.,1.,1.,2.,2.,1.,2.,0.,2.,2.,1.,2.,2.,2.,2.,2.,0.,3.,2.,1.,3.,2.,2.,3.,2.,0.,0.,3.,1.,0.,3.,2.,0.,3.,0.,1.,3.,1.,1.,3.,2.,1.,3.,0.,2.,3.,1.,2.,3.,2.,2.,3.,0.,3.,3.,1.,3.,3.,2.,3.,3.,0.,0.,4.,1.,0.,4.,2.,0.,4.,0.,1.,4.,1.,1.,4.,2.,1.,4.,0.,2.,4.,1.,2.,4.,2.,2.,4.,0.,3.,4.,1.,3.,4.,2.,3.,4.],60,3),1e-12)) - self.assertTrue(a1.isEqual(DataArrayByte([12,12,12,12,12,12,12,12,12,12,12]))) - self.assertTrue(a2.isEqual(DataArrayInt([0,9,18,27,36,45,54,63,72,81,90]))) - self.assertTrue(a3.isEqual(DataArrayInt([8,1,0,3,4,13,12,15,16,8,2,1,4,5,14,13,16,17,8,4,3,6,7,16,15,18,19,8,5,4,7,8,17,16,19,20,8,7,6,9,10,19,18,21,22,8,8,7,10,11,20,19,22,23,8,13,12,15,16,25,24,27,28,8,14,13,16,17,26,25,28,29,8,16,15,18,19,28,27,30,31,8,17,16,19,20,29,28,31,32,8,19,18,21,22,31,30,33,34]))) - self.assertTrue(a4 is None) - self.assertTrue(a5 is None) - for i in xrange(30): - ffCell=allFMTSLeavesPerCommonSupport1[0][0][0][i] - fsst=MEDFileField1TSStructItem.BuildItemFrom(ffCell,mst) - ffCell.loadArraysIfNecessary() - v=mml2.buildDataArray(fsst,fields,ffCell.getUndergroundDataArray()) - # self.assertEqual(v.getHiddenCppPointer(),ffCell.getUndergroundDataArray().getHiddenCppPointer()) # to be improved... maybe this line could be true - myarr=DataArrayDouble(11) ; myarr.iota() ; myarr[i%11]=100. - self.assertEqual(ffCell.getName(),"FieldOnCells") - self.assertTrue(v.isEqual(myarr,1e-12)) - pass - pass - - def test32(self): - """ This test is close to test30 except that here the profiles on dim-1 of structured mesh is considered here.""" - fname="ForMEDReader32.med" - c=MEDCouplingCMesh() - arrX=DataArrayDouble(3) ; arrX.iota() - arrY=DataArrayDouble(4) ; arrY.iota() - arrZ=DataArrayDouble(5) ; arrZ.iota() - c.setCoords(arrX,arrY,arrZ) - c.setName("CartMesh") - cc=MEDFileCMesh() - cc.setMesh(c) - tmpFacesMesh=c.build1SGTSubLevelMesh() - famIdFaces=DataArrayInt(98) ; famIdFaces[:36]=-1 ; famIdFaces[36:68]=-2 ; famIdFaces[68:]=-3 - famIdCells=DataArrayInt(24) ; famIdCells[:]=0 - cc.setFamilyFieldArr(0,famIdCells) - #cc.setFamilyFieldArr(-1,famIdFaces) - cc.addFamily("FacesX",-1) ; cc.addFamily("FacesY",-2) ; cc.addFamily("FacesZ",-3) - cc.setFamiliesOnGroup("FacesX1",["FacesX"]) - cc.setFamiliesOnGroup("FacesY1",["FacesY"]) - cc.setFamiliesOnGroup("FacesZ1",["FacesZ"]) - fmts0=MEDFileFieldMultiTS() - fmts1=MEDFileFieldMultiTS() - pfl=DataArrayInt(31) ; pfl.iota() ; pfl.setName("PflOnQUAD4") - for i in xrange(30): - f1ts=MEDFileField1TS() - fFaces=MEDCouplingFieldDouble(ON_CELLS) ; fFaces.setName("FieldOnFaces") - arr=DataArrayDouble(31) ; arr.iota() ; arr[i]=100. - fFaces.setArray(arr) - fFaces.setTime(float(i)+0.1,i,-1) - fFaces.setMesh(tmpFacesMesh[:31]) - f1ts.setFieldProfile(fFaces,cc,-1,pfl)# here, a test is done to check that "NORM_QUAD4" string is not 30 times appended at the end of pfl name. - self.assertEqual("PflOnQUAD4",pfl.getName()) - fmts0.pushBackTimeStep(f1ts) - # - f1ts=MEDFileField1TS() - fCells=MEDCouplingFieldDouble(ON_CELLS) ; fCells.setName("FieldOnCells") - arr=DataArrayDouble(24) ; arr.iota() ; arr[i%24]=30. - fCells.setArray(arr) - fCells.setTime(float(i)+0.1,i,-1) - fCells.setMesh(c) - f1ts.setFieldNoProfileSBT(fCells) - fmts1.pushBackTimeStep(f1ts) - pass - fs=MEDFileFields() - fs.pushField(fmts0) - fs.pushField(fmts1) - cc.write(fname,2) - fs.write(fname,0) - ########## GO for reading in MEDReader,by not loading all. Mesh is fully loaded but not fields values - ms=MEDFileMeshes(fname) - fields=MEDFileFields(fname,False) - fields.removeFieldsWithoutAnyTimeStep() - fields_per_mesh=[fields.partOfThisLyingOnSpecifiedMeshName(meshName) for meshName in ms.getMeshesNames()] - allFMTSLeavesToDisplay=[] - for fields in fields_per_mesh: - allFMTSLeavesToDisplay2=[] - for fmts in fields: - tmp=fmts.splitDiscretizations() - for itmp in tmp: - self.assertTrue(not itmp.presenceOfMultiDiscPerGeoType()) - pass - allFMTSLeavesToDisplay2+=tmp - pass - allFMTSLeavesToDisplay.append(allFMTSLeavesToDisplay2) - pass - self.assertEqual(len(allFMTSLeavesToDisplay),1) - self.assertEqual(len(allFMTSLeavesToDisplay[0]),2) - allFMTSLeavesPerTimeSeries=MEDFileAnyTypeFieldMultiTS.SplitIntoCommonTimeSeries(sum(allFMTSLeavesToDisplay,[])) - self.assertEqual(len(allFMTSLeavesPerTimeSeries),1) - self.assertEqual(len(allFMTSLeavesPerTimeSeries[0]),2) - allFMTSLeavesPerCommonSupport1=MEDFileAnyTypeFieldMultiTS.SplitPerCommonSupport(allFMTSLeavesToDisplay[0],ms[ms.getMeshesNames()[0]]) - self.assertEqual(len(allFMTSLeavesPerCommonSupport1),2) - self.assertEqual(len(allFMTSLeavesPerCommonSupport1[0][0]),1) - self.assertEqual(len(allFMTSLeavesPerCommonSupport1[1][0]),1) - # - mst=MEDFileMeshStruct.New(ms[0]) - # - fcscp=allFMTSLeavesPerCommonSupport1[0][1] - mml=fcscp.buildFromScratchDataSetSupport(0,fields) - mml2=mml.prepare() - self.assertTrue(isinstance(mml2,MEDCMeshMultiLev)) # here CMesh is important - (a,b,c),d=mml2.buildVTUArrays() - self.assertTrue(d)#d is True because the a,b and c are directly those in the internal data structure - self.assertTrue(a.isEqual(arrX,1e-12)) - self.assertTrue(b.isEqual(arrY,1e-12)) - self.assertTrue(c.isEqual(arrZ,1e-12)) - for i in xrange(30): - ffCell=allFMTSLeavesPerCommonSupport1[0][0][0][i] - fsst=MEDFileField1TSStructItem.BuildItemFrom(ffCell,mst) - ffCell.loadArraysIfNecessary() - v=mml2.buildDataArray(fsst,fields,ffCell.getUndergroundDataArray()) - self.assertEqual(v.getHiddenCppPointer(),ffCell.getUndergroundDataArray().getHiddenCppPointer()) - myarr=DataArrayDouble(24) ; myarr.iota() ; myarr[i%24]=30. - self.assertEqual(ffCell.getName(),"FieldOnCells") - self.assertTrue(v.isEqual(myarr,1e-12)) - pass - # - fcscp=allFMTSLeavesPerCommonSupport1[1][1] - mml=fcscp.buildFromScratchDataSetSupport(0,fields) - mml2=mml.prepare() - self.assertTrue(isinstance(mml2,MEDUMeshMultiLev)) # here UMesh is important - ncc,a0,a1,a2,a3,a4,a5=mml2.buildVTUArrays() - self.assertTrue(ncc)# True because, the coords are computed by the implicit unstructured level -1 structured mesh - self.assertTrue(a0.isEqual(DataArrayDouble([0.,0.,0.,1.,0.,0.,2.,0.,0.,0.,1.,0.,1.,1.,0.,2.,1.,0.,0.,2.,0.,1.,2.,0.,2.,2.,0.,0.,3.,0.,1.,3.,0.,2.,3.,0.,0.,0.,1.,1.,0.,1.,2.,0.,1.,0.,1.,1.,1.,1.,1.,2.,1.,1.,0.,2.,1.,1.,2.,1.,2.,2.,1.,0.,3.,1.,1.,3.,1.,2.,3.,1.,0.,0.,2.,1.,0.,2.,2.,0.,2.,0.,1.,2.,1.,1.,2.,2.,1.,2.,0.,2.,2.,1.,2.,2.,2.,2.,2.,0.,3.,2.,1.,3.,2.,2.,3.,2.,0.,0.,3.,1.,0.,3.,2.,0.,3.,0.,1.,3.,1.,1.,3.,2.,1.,3.,0.,2.,3.,1.,2.,3.,2.,2.,3.,0.,3.,3.,1.,3.,3.,2.,3.,3.,0.,0.,4.,1.,0.,4.,2.,0.,4.,0.,1.,4.,1.,1.,4.,2.,1.,4.,0.,2.,4.,1.,2.,4.,2.,2.,4.,0.,3.,4.,1.,3.,4.,2.,3.,4.],60,3),1e-12)) - self.assertTrue(a1.isEqual(DataArrayByte([9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9]))) - self.assertTrue(a2.isEqual(DataArrayInt([0,5,10,15,20,25,30,35,40,45,50,55,60,65,70,75,80,85,90,95,100,105,110,115,120,125,130,135,140,145,150]))) - self.assertTrue(a3.isEqual(DataArrayInt([4,0,12,15,3,4,12,24,27,15,4,24,36,39,27,4,36,48,51,39,4,3,15,18,6,4,15,27,30,18,4,27,39,42,30,4,39,51,54,42,4,6,18,21,9,4,18,30,33,21,4,30,42,45,33,4,42,54,57,45,4,1,13,16,4,4,13,25,28,16,4,25,37,40,28,4,37,49,52,40,4,4,16,19,7,4,16,28,31,19,4,28,40,43,31,4,40,52,55,43,4,7,19,22,10,4,19,31,34,22,4,31,43,46,34,4,43,55,58,46,4,2,14,17,5,4,14,26,29,17,4,26,38,41,29,4,38,50,53,41,4,5,17,20,8,4,17,29,32,20,4,29,41,44,32]))) - self.assertTrue(a4 is None) - self.assertTrue(a5 is None) - a6,a7=mml2.retrieveFamilyIdsOnCells() - self.assertTrue(a6 is None) - self.assertTrue(a7) - for i in xrange(30): - ffCell=allFMTSLeavesPerCommonSupport1[1][0][0][i] - fsst=MEDFileField1TSStructItem.BuildItemFrom(ffCell,mst) - ffCell.loadArraysIfNecessary() - v=mml2.buildDataArray(fsst,fields,ffCell.getUndergroundDataArray()) - self.assertEqual(v.getHiddenCppPointer(),ffCell.getUndergroundDataArray().getHiddenCppPointer()) - myarr=DataArrayDouble(31) ; myarr.iota() ; myarr[i]=100. - self.assertEqual(ffCell.getName(),"FieldOnFaces") - self.assertTrue(v.isEqual(myarr,1e-12)) - pass - pass - - def test33(self): - """Non regression test concerning polygons. Thanks Adrien. This bug can't be shown by simply reading an displaying a MED file containing only polygons. A filter must be applied on it to show it. The a2 array was responsible of that bug.""" - fname="ForMEDReader33.med" - fieldName="ACellField" - coo=DataArrayDouble([(5.5,0.5),(5.5,-0.5),(6.5,0.5),(6.5,-0.5),(6.5,1.5),(7.5,0.5),(7.5,-0.5),(7.5,1.5),(7.5,2.5),(8.5,0.5),(8.5,-0.5),(8.5,1.5),(8.5,2.5),(8.5,3.5),(8.55,0.5),(8.55,-0.5),(8.55,1.5),(8.55,2.5),(8.55,3.5)]) - m=MEDCouplingUMesh("mesh",2) - m.setCoords(coo) - m.allocateCells() - for i,c in enumerate([(1,0,2,3),(3,2,5,6),(2,4,7,5),(6,5,9,10),(5,7,11,9),(7,8,12,11),(10,9,14,15),(9,11,16,14),(11,12,17,16),(12,13,18,17)]): - if i<6: - typ=NORM_QUAD4 - pass - else: - typ=NORM_POLYGON - pass - m.insertNextCell(typ,c) - pass - mm=MEDFileUMesh() - mm.setMeshAtLevel(0,m) - mm.write(fname,2) - for i in xrange(15): - fCell0=MEDCouplingFieldDouble(ON_CELLS) ; fCell0.setTime(float(i)+0.1,i,0) - fCell0.setName(fieldName) ; fCell0.setMesh(m) - arr=DataArrayDouble(m.getNumberOfCells()) ; arr.iota(0) ; arr[i%10]=100. - fCell0.setArray(arr) ; arr.setInfoOnComponents(["Comp1 [m]"]) - fCell0.checkCoherency() - MEDLoader.WriteFieldUsingAlreadyWrittenMesh(fname,fCell0) - pass - ########## GO for reading in MEDReader,by not loading all. Mesh is fully loaded but not fields values - ms=MEDFileMeshes(fname) - fields=MEDFileFields(fname,False) - fields.removeFieldsWithoutAnyTimeStep() - fields_per_mesh=[fields.partOfThisLyingOnSpecifiedMeshName(meshName) for meshName in ms.getMeshesNames()] - allFMTSLeavesToDisplay=[] - for fields in fields_per_mesh: - allFMTSLeavesToDisplay2=[] - for fmts in fields: - tmp=fmts.splitDiscretizations() - for itmp in tmp: - self.assertTrue(not itmp.presenceOfMultiDiscPerGeoType()) - pass - allFMTSLeavesToDisplay2+=tmp - pass - allFMTSLeavesToDisplay.append(allFMTSLeavesToDisplay2) - pass - self.assertEqual(len(allFMTSLeavesToDisplay),1) - self.assertEqual(len(allFMTSLeavesToDisplay[0]),1) - allFMTSLeavesPerTimeSeries=MEDFileAnyTypeFieldMultiTS.SplitIntoCommonTimeSeries(sum(allFMTSLeavesToDisplay,[])) - self.assertEqual(len(allFMTSLeavesPerTimeSeries),1) - self.assertEqual(len(allFMTSLeavesPerTimeSeries[0]),1) - allFMTSLeavesPerCommonSupport1=MEDFileAnyTypeFieldMultiTS.SplitPerCommonSupport(allFMTSLeavesToDisplay[0],ms[ms.getMeshesNames()[0]]) - self.assertEqual(len(allFMTSLeavesPerCommonSupport1),1) - self.assertEqual(len(allFMTSLeavesPerCommonSupport1[0][0]),1) - # - mst=MEDFileMeshStruct.New(ms[0]) - # - fcscp=allFMTSLeavesPerCommonSupport1[0][1] - mml=fcscp.buildFromScratchDataSetSupport(0,fields) - mml2=mml.prepare() - self.assertTrue(isinstance(mml2,MEDUMeshMultiLev)) - ncc,a0,a1,a2,a3,a4,a5=mml2.buildVTUArrays() - self.assertTrue(not ncc)# false beacause 2D in MED file - self.assertTrue(a0.isEqual(DataArrayDouble([(5.5,0.5,0),(5.5,-0.5,0),(6.5,0.5,0),(6.5,-0.5,0),(6.5,1.5,0),(7.5,0.5,0),(7.5,-0.5,0),(7.5,1.5,0),(7.5,2.5,0),(8.5,0.5,0),(8.5,-0.5,0),(8.5,1.5,0),(8.5,2.5,0),(8.5,3.5,0),(8.55,0.5,0),(8.55,-0.5,0),(8.55,1.5,0),(8.55,2.5,0),(8.55,3.5,0)]),1e-12)) - self.assertTrue(a1.isEqual(DataArrayByte([9,9,9,9,9,9,7,7,7,7]))) - self.assertTrue(a2.isEqual(DataArrayInt([0,5,10,15,20,25,30,35,40,45])))# the bug was here. - self.assertTrue(a3.isEqual(DataArrayInt([4,1,0,2,3,4,3,2,5,6,4,2,4,7,5,4,6,5,9,10,4,5,7,11,9,4,7,8,12,11,4,10,9,14,15,4,9,11,16,14,4,11,12,17,16,4,12,13,18,17]))) - self.assertTrue(a4 is None) - self.assertTrue(a5 is None) - for i in xrange(15): - ffCell=allFMTSLeavesPerCommonSupport1[0][0][0][i] - fsst=MEDFileField1TSStructItem.BuildItemFrom(ffCell,mst) - ffCell.loadArraysIfNecessary() - v=mml2.buildDataArray(fsst,fields,ffCell.getUndergroundDataArray()) - self.assertEqual(v.getHiddenCppPointer(),ffCell.getUndergroundDataArray().getHiddenCppPointer()) - myarr=DataArrayDouble(10) ; myarr.iota() ; myarr[i%10]=100. ; myarr.setInfoOnComponent(0,"Comp1 [m]") - self.assertEqual(ffCell.getName(),fieldName) - self.assertTrue(v.isEqual(myarr,1e-12)) - pass - pass - - def test34(self): - """ This test is the thirs ultimate test (base on test12) for the profiles with gauss points. - This test highlight the hidden imp linked to bug #8655. - This test is close to test11 but here a 2nd field on cells without profile. So here the mesh is expected to be the same than m. - """ - fname="ForMEDReader34.med" - m=MEDCouplingCMesh("mesh") - arr=DataArrayDouble(5) ; arr.iota() - m.setCoords(arr,arr) - m=m.buildUnstructured() ; m.getCoords().setInfoOnComponents(["XX [m]","YYY [km]"]) - mm=MEDFileUMesh() ; mm.setMeshes([m]) - # - fieldName0="zeField0" - fieldName1="zeField1" - fs0=MEDFileFieldMultiTS() ; fs1=MEDFileFieldMultiTS() - for i in xrange(5): - f=MEDFileField1TS() - fNode=MEDCouplingFieldDouble(ON_GAUSS_PT) ; fNode.setTime(float(i),i,0) - fNode.setName(fieldName0) ; fNode.setMesh(m) - fNode.setGaussLocalizationOnCells([0,2,3,4,7,15],[-1.,-1.,1.,-1.,1.,1.,-1.,1.],[0.5,0.5,0.7,0.7],[0.8,0.2]) - fNode.setGaussLocalizationOnCells([1,5,8,9],[-1.,-1.,1.,-1.,1.,1.,-1.,1.],[0.5,0.5,0.7,0.7,0.1,0.1,0.2,0.2,0.3,0.3],[0.8,0.05,0.1,0.04,0.01]) - fNode.setGaussLocalizationOnCells([6,10,13],[-1.,-1.,1.,-1.,1.,1.,-1.,1.],[0.5,0.5,0.7,0.7,0.1,0.1,0.2,0.2],[0.8,0.05,0.1,0.04]) - fNode.setGaussLocalizationOnCells([11,12,14],[-1.,-1.,1.,-1.,1.,1.,-1.,1.],[0.5,0.5,0.7,0.7,0.1,0.1,0.2,0.2,0.3,0.3,0.4,0.4,0.8,0.8],[0.8,0.05,0.1,0.01,0.02,0.005,0.005]) - arr=DataArrayDouble(2*(2*6+5*4+4*3+7*3)) ; arr.iota(0+1000*i) ; arr.rearrange(2) - fNode.setArray(arr) ; arr.setInfoOnComponents(["Comp1_0 [m]","Com2_0 [s^2]"]) ; fNode.checkCoherency() - f.setFieldNoProfileSBT(fNode) - fs0.pushBackTimeStep(f) - # - f=MEDFileField1TS() - fNode=MEDCouplingFieldDouble(ON_CELLS) ; fNode.setTime(float(i),i,0) - fNode.setName(fieldName1) ; fNode.setMesh(m) - arr=DataArrayDouble(2*16) ; arr.iota(300+1000*i) ; arr.rearrange(2) - fNode.setArray(arr) ; arr.setInfoOnComponents(["Comp1_1 [m]","Com2_1 [s^2]"]) ; fNode.checkCoherency() - f.setFieldNoProfileSBT(fNode) - fs1.pushBackTimeStep(f) - pass - mm.write(fname,2) - fs0.write(fname,0) ; fs1.write(fname,0) - a0Exp=mm.getCoords().deepCpy() - del m,mm,fs0,fs1,f,fNode - ########## GO for reading in MEDReader,by not loading all. Mesh is fully loaded but not fields values - ms=MEDFileMeshes(fname) - fields=MEDFileFields(fname,False) - fields.removeFieldsWithoutAnyTimeStep() - fields_per_mesh=[fields.partOfThisLyingOnSpecifiedMeshName(meshName) for meshName in ms.getMeshesNames()] - allFMTSLeavesToDisplay=[] - for fields in fields_per_mesh: - allFMTSLeavesToDisplay2=[] - for fmts in fields: - tmp=fmts.splitDiscretizations() - for itmp in tmp: - if itmp.presenceOfMultiDiscPerGeoType(): - tmp2=itmp.splitMultiDiscrPerGeoTypes() - for iii,itmp2 in enumerate(tmp2): - name="%s_%i"%(itmp2.getName(),iii) - itmp2.setName(name) - allFMTSLeavesToDisplay2.append(itmp2) - pass - pass - else: - allFMTSLeavesToDisplay2.append(itmp) - pass - pass - allFMTSLeavesToDisplay.append(allFMTSLeavesToDisplay2) - pass - # Here 2 MED fields in input and at the end 5 ! 1+4 ! 4 fields have been built from zeField0 due to subspliting per dis / per geo type - self.assertEqual(len(allFMTSLeavesToDisplay),1) - self.assertEqual(len(allFMTSLeavesToDisplay[0]),5) - allFMTSLeavesPerTimeSeries=MEDFileAnyTypeFieldMultiTS.SplitIntoCommonTimeSeries(sum(allFMTSLeavesToDisplay,[])) - self.assertEqual(len(allFMTSLeavesPerTimeSeries),1) # one time serie here : because the 2 fields are defined on the same time steps - self.assertEqual(len(allFMTSLeavesPerTimeSeries[0]),5) - allFMTSLeavesPerCommonSupport=MEDFileAnyTypeFieldMultiTS.SplitPerCommonSupport(allFMTSLeavesPerTimeSeries[0],ms[ms.getMeshesNames()[0]]) - self.assertEqual(len(allFMTSLeavesPerCommonSupport),5) - for i in xrange(5): - self.assertEqual(len(allFMTSLeavesPerCommonSupport[i][0]),1) - # - mst=MEDFileMeshStruct.New(ms[0]) - # - fcscp=allFMTSLeavesPerCommonSupport[4][1] - mml=fcscp.buildFromScratchDataSetSupport(0,fields) - mml2=mml.prepare() - self.assertTrue(isinstance(mml2,MEDUMeshMultiLev)) - ncc,a0,a1,a2,a3,a4,a5=mml2.buildVTUArrays() - self.assertTrue(not ncc) - self.assertTrue(a0.isEqual(a0Exp.changeNbOfComponents(3,0.),1e-12)) - self.assertTrue(a1.isEqual(DataArrayByte([9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9]))) - self.assertTrue(a2.isEqual(DataArrayInt([0,5,10,15,20,25,30,35,40,45,50,55,60,65,70,75]))) - self.assertTrue(a3.isEqual(DataArrayInt([4,1,0,5,6,4,2,1,6,7,4,3,2,7,8,4,4,3,8,9,4,6,5,10,11,4,7,6,11,12,4,8,7,12,13,4,9,8,13,14,4,11,10,15,16,4,12,11,16,17,4,13,12,17,18,4,14,13,18,19,4,16,15,20,21,4,17,16,21,22,4,18,17,22,23,4,19,18,23,24]))) # <- here the mesh is NOT renumbered : the mesh is equal to m - self.assertTrue(a4 is None) - self.assertTrue(a5 is None) - for i in xrange(1,5): - self.assertTrue((fcscp.isDataSetSupportEqualToThePreviousOne(i,fields))) - pass - for i in xrange(5): - f=allFMTSLeavesPerCommonSupport[0][0][0][i] - fsst=MEDFileField1TSStructItem.BuildItemFrom(f,mst) - f.loadArraysIfNecessary() - v=mml.buildDataArray(fsst,fields,f.getUndergroundDataArray()) - self.assertEqual(f.getName(),fieldName0) - vExp=DataArrayDouble([(0.,1.),(2.,3.),(14.,15.),(16.,17.),(18.,19.),(20.,21.),(22.,23.),(24.,25.),(44.,45.),(46.,47.),(126.,127.),(128.,129.)]) - vExp.setInfoOnComponents(['Comp1_0 [m]','Com2_0 [s^2]']) - vExp+=i*1000 - self.assertTrue(v.isEqual(vExp,1e-12)) - # - f=allFMTSLeavesPerCommonSupport[1][0][0][i] - fsst=MEDFileField1TSStructItem.BuildItemFrom(f,mst) - f.loadArraysIfNecessary() - v=mml.buildDataArray(fsst,fields,f.getUndergroundDataArray()) - self.assertEqual(f.getName(),fieldName0) - vExp=DataArrayDouble([(4.,5.),(6.,7.),(8.,9.),(10.,11.),(12.,13.),(26.,27.),(28.,29.),(30.,31.),(32.,33.),(34.,35.),(48.,49.),(50.,51.),(52.,53.),(54.,55.),(56.,57.),(58.,59.),(60.,61.),(62.,63.),(64.,65.),(66.,67.)]) - vExp.setInfoOnComponents(['Comp1_0 [m]','Com2_0 [s^2]']) - vExp+=i*1000 - self.assertTrue(v.isEqual(vExp,1e-12)) - # - f=allFMTSLeavesPerCommonSupport[2][0][0][i] - fsst=MEDFileField1TSStructItem.BuildItemFrom(f,mst) - f.loadArraysIfNecessary() - v=mml.buildDataArray(fsst,fields,f.getUndergroundDataArray()) - self.assertEqual(f.getName(),fieldName0) - vExp=DataArrayDouble([(36.,37.),(38.,39.),(40.,41.),(42.,43.),(68.,69.),(70.,71.),(72.,73.),(74.,75.),(104.,105.),(106.,107.),(108.,109.),(110.,111.)]) - vExp.setInfoOnComponents(['Comp1_0 [m]','Com2_0 [s^2]']) - vExp+=i*1000 - self.assertTrue(v.isEqual(vExp,1e-12)) - # - f=allFMTSLeavesPerCommonSupport[3][0][0][i] - fsst=MEDFileField1TSStructItem.BuildItemFrom(f,mst) - f.loadArraysIfNecessary() - v=mml.buildDataArray(fsst,fields,f.getUndergroundDataArray()) - self.assertEqual(f.getName(),fieldName0) - vExp=DataArrayDouble([(76,77),(78,79),(80,81),(82,83),(84,85),(86,87),(88,89),(90,91),(92,93),(94,95),(96,97),(98,99),(100,101),(102,103),(112,113),(114,115),(116,117),(118,119),(120,121),(122,123),(124,125)]) - vExp.setInfoOnComponents(['Comp1_0 [m]','Com2_0 [s^2]']) - vExp+=i*1000 - self.assertTrue(v.isEqual(vExp,1e-12)) - # - f=allFMTSLeavesPerCommonSupport[4][0][0][i] - fsst=MEDFileField1TSStructItem.BuildItemFrom(f,mst) - f.loadArraysIfNecessary() - v=mml.buildDataArray(fsst,fields,f.getUndergroundDataArray()) - self.assertEqual(f.getName(),fieldName1) - self.assertEqual(v.getHiddenCppPointer(),f.getUndergroundDataArray().getHiddenCppPointer()) - vExp=DataArrayDouble(16*2) ; vExp.iota(300+i*1000) ; vExp.rearrange(2) ; vExp.setInfoOnComponents(['Comp1_1 [m]','Com2_1 [s^2]']) - self.assertTrue(v.isEqual(vExp,1e-12)) - pass - pass - - def test35(self): - """ Emulate MEDReader in // mode context. Here a Simple mesh having more nodes than really needed. This test focuses on that point particulary.""" - fname="ForMEDReader35.med" - arrX=DataArrayDouble(7) ; arrX.iota() - arrY=DataArrayDouble([0.,1.]) - m=MEDCouplingCMesh() ; m.setCoords(arrX,arrY) ; m=m.buildUnstructured() ; m=m[[0,5,1,4,2,3]] ; m.changeSpaceDimension(3,0.) ; m.setName("Mesh") - f=MEDCouplingFieldDouble(ON_CELLS) ; f.setMesh(m) ; f.setName("Field") ; f.setArray(DataArrayDouble([(0.1,1.1),(2.1,3.1),(4.1,5.1),(6.1,7.1),(8.1,9.1),(10.1,11.1)])) ; f.getArray().setInfoOnComponents(["aa","bbb"]) - MEDLoader.WriteUMesh(fname,m,True) - MEDLoader.WriteFieldUsingAlreadyWrittenMesh(fname,f) - ########## GO for reading in MEDReader,by not loading all. Mesh is fully loaded but not fields values - ms=MEDFileMeshes() # here we reproduce what is done by ParaMEDFileMeshes.ParaNew - ms.pushMesh(MEDFileUMesh.LoadPartOf(fname,"Mesh",[NORM_QUAD4],[0,2,1],-1,-1)); - ms[0].zipCoords() - # - fields=MEDFileFields.LoadPartOf(fname,False,ms); - fields.removeFieldsWithoutAnyTimeStep() - fields_per_mesh=[fields.partOfThisLyingOnSpecifiedMeshName(meshName) for meshName in ms.getMeshesNames()] - allFMTSLeavesToDisplay=[] - for fields in fields_per_mesh: - allFMTSLeavesToDisplay2=[] - for fmts in fields: - tmp=fmts.splitDiscretizations() - for itmp in tmp: - if itmp.presenceOfMultiDiscPerGeoType(): - tmp2=itmp.splitMultiDiscrPerGeoTypes() - for iii,itmp2 in enumerate(tmp2): - name="%s_%i"%(itmp2.getName(),iii) - itmp2.setName(name) - allFMTSLeavesToDisplay2.append(itmp2) - pass - pass - else: - allFMTSLeavesToDisplay2.append(itmp) - pass - pass - allFMTSLeavesToDisplay.append(allFMTSLeavesToDisplay2) - pass - # - self.assertEqual(len(allFMTSLeavesToDisplay),1) - self.assertEqual(len(allFMTSLeavesToDisplay[0]),1) - allFMTSLeavesPerTimeSeries=MEDFileAnyTypeFieldMultiTS.SplitIntoCommonTimeSeries(sum(allFMTSLeavesToDisplay,[])) - self.assertEqual(len(allFMTSLeavesPerTimeSeries),1) # one time serie here : because the 2 fields are defined on the same time steps - self.assertEqual(len(allFMTSLeavesPerTimeSeries[0]),1) - allFMTSLeavesPerCommonSupport=MEDFileAnyTypeFieldMultiTS.SplitPerCommonSupport(allFMTSLeavesPerTimeSeries[0],ms[ms.getMeshesNames()[0]]) - self.assertEqual(len(allFMTSLeavesPerCommonSupport),1) - self.assertEqual(len(allFMTSLeavesPerCommonSupport[0][0]),1) - # - mst=MEDFileMeshStruct.New(ms[0]) - # - fcscp=allFMTSLeavesPerCommonSupport[0][1] - mml=fcscp.buildFromScratchDataSetSupport(0,fields) - mml2=mml.prepare() - self.assertTrue(isinstance(mml2,MEDUMeshMultiLev)) - ncc,a0,a1,a2,a3,a4,a5=mml2.buildVTUArrays() - self.assertTrue(ncc) - self.assertTrue(a0.isEqual(m.getCoords()[[0,1,5,6,7,8,12,13]],1e-12))# <- the aim of the test - self.assertTrue(a1.isEqual(DataArrayByte([9,9]))) - self.assertTrue(a2.isEqual(DataArrayInt([0,5]))) - self.assertTrue(a3.isEqual(DataArrayInt([4,1,0,4,5,4,3,2,6,7]))) - self.assertTrue(a4 is None) - self.assertTrue(a5 is None) - f2=allFMTSLeavesPerCommonSupport[0][0][0][0] - fsst=MEDFileField1TSStructItem.BuildItemFrom(f2,mst) - f2.loadArraysIfNecessary() - v=mml.buildDataArray(fsst,fields,f2.getUndergroundDataArray()) - self.assertEqual(f2.getName(),f.getName()) - vExp=DataArrayDouble([(0.1,1.1),(2.1,3.1)]) - vExp.setInfoOnComponents(['aa','bbb']) - self.assertTrue(v.isEqual(vExp,1e-12)) - pass - - def test36(self): - """Bug EDF11027. Here mesh at level 0 (TRI3) does not fetch all the nodes. Level -1 (SEG2) does not fetch all the nodes neither. But all TRI3 + all SEG2 fetch all nodes. - aaa field on GAUSSPoints lying only on TRI3 share the same support than profile node field ccc. - But bbb field on all nodes is not on the same support. Past optimization that make the assumtion a support on all lev0 cells lies on all nodes is now over.""" - meshName="mesh" - fname="ForMEDReader36.med" - c=DataArrayDouble([(0,0),(1,0),(1,1),(0,1),(2,0),(-1,0),(1,2)]) - m0=MEDCoupling1SGTUMesh(meshName,NORM_TRI3) - m0.setCoords(c) - m0.setNodalConnectivity(DataArrayInt([0,2,1,3,2,0,2,4,1])) - mm=MEDFileUMesh() - mm[0]=m0 - m1=MEDCoupling1SGTUMesh(meshName,NORM_SEG2) - m1.setCoords(c) - m1.setNodalConnectivity(DataArrayInt([5,0,0,3,3,2,2,6])) - mm[-1]=m1 - # - zeTime=(1.1,2,3) - ff1=MEDFileField1TS() - f1=MEDCouplingFieldDouble(ON_NODES) ; f1.setMesh(m0) - arr=DataArrayDouble(7) ; arr.iota(2000) - f1.setArray(arr) - f1.setName("bbb") - f1.checkCoherency() - f1.setTime(*zeTime) - ff1.setFieldNoProfileSBT(f1) - # - ff2=MEDFileField1TS() - f2=MEDCouplingFieldDouble(ON_GAUSS_NE) ; f2.setMesh(m0) - arr=DataArrayDouble(9) ; arr.iota(4000) - f2.setArray(arr) - f2.setName("ddd") - f2.checkCoherency() - f2.setTime(*zeTime) - ff2.setFieldNoProfileSBT(f2) - # - ff3=MEDFileField1TS() - f3=MEDCouplingFieldDouble(ON_GAUSS_PT) ; f3.setMesh(m0) - f3.setGaussLocalizationOnType(NORM_TRI3,[0,0,1,0,0,1],[0.333333,0.333333],[0.5]) - arr=DataArrayDouble(3) ; arr.iota(1000) - f3.setArray(arr) - f3.checkCoherency() - f3.setTime(*zeTime) - f3.setName("aaa") - ff3.setFieldNoProfileSBT(f3) - # - ff4=MEDFileField1TS() - m0d=m0.deepCpy() ; m0d.zipCoords() - f4=MEDCouplingFieldDouble(ON_NODES) ; f4.setMesh(m0d) - arr=DataArrayDouble(5) ; arr.iota(3000) - f4.setArray(arr) - f4.setName("ccc") - f4.checkCoherency() - f4.setTime(*zeTime) - pfl=DataArrayInt([0,1,2,3,4]) ; pfl.setName("PFL") - ff4.setFieldProfile(f4,mm,0,pfl) - # - mm.write(fname,2) - ff3.write(fname,0) - ff1.write(fname,0) - ff4.write(fname,0) - ### - ms=MEDFileMeshes(fname) - fields=MEDFileFields(fname,False) - fields.removeFieldsWithoutAnyTimeStep() - fields_per_mesh=[fields.partOfThisLyingOnSpecifiedMeshName(meshName) for meshName in ms.getMeshesNames()] - allFMTSLeavesToDisplay=[] - for fields in fields_per_mesh: - allFMTSLeavesToDisplay2=[] - for fmts in fields: - tmp=fmts.splitDiscretizations() - for itmp in tmp: - self.assertTrue(not itmp.presenceOfMultiDiscPerGeoType()) - pass - allFMTSLeavesToDisplay2+=tmp - pass - allFMTSLeavesToDisplay.append(allFMTSLeavesToDisplay2) - pass - self.assertEqual(len(allFMTSLeavesToDisplay),1) - self.assertEqual(len(allFMTSLeavesToDisplay[0]),3) - allFMTSLeavesPerTimeSeries=MEDFileAnyTypeFieldMultiTS.SplitIntoCommonTimeSeries(sum(allFMTSLeavesToDisplay,[])) - self.assertEqual(len(allFMTSLeavesPerTimeSeries),1) - self.assertEqual(len(allFMTSLeavesPerTimeSeries[0]),3) - allFMTSLeavesPerCommonSupport1=MEDFileAnyTypeFieldMultiTS.SplitPerCommonSupport(allFMTSLeavesToDisplay[0],ms[ms.getMeshesNames()[0]]) - self.assertEqual(len(allFMTSLeavesPerCommonSupport1),2) - self.assertEqual(len(allFMTSLeavesPerCommonSupport1[0][0]),2) - self.assertEqual(len(allFMTSLeavesPerCommonSupport1[1][0]),1) - # - mst=MEDFileMeshStruct.New(ms[0]) - fcscp=allFMTSLeavesPerCommonSupport1[0][1] - mml=fcscp.buildFromScratchDataSetSupport(0,fields) - mml2=mml.prepare() - self.assertTrue(isinstance(mml2,MEDUMeshMultiLev)) - ncc,a0,a1,a2,a3,a4,a5=mml2.buildVTUArrays() - self.assertTrue(not ncc)# here ncc=False because the coordinates are not in ms neither in children. - self.assertTrue(a0.isEqual(DataArrayDouble([(0,0,0),(1,0,0),(1,1,0),(0,1,0),(2,0,0)]),1e-12)) - self.assertTrue(a1.isEqual(DataArrayByte([5,5,5]))) - self.assertTrue(a2.isEqual(DataArrayInt([0,4,8]))) - self.assertTrue(a3.isEqual(DataArrayInt([3,0,2,1,3,3,2,0,3,2,4,1]))) - self.assertTrue(a4 is None) - self.assertTrue(a5 is None) - for i in xrange(1): - ffCell=allFMTSLeavesPerCommonSupport1[0][0][0][i] - fsst=MEDFileField1TSStructItem.BuildItemFrom(ffCell,mst) - ffCell.loadArraysIfNecessary() - v=mml2.buildDataArray(fsst,fields,ffCell.getUndergroundDataArray()) - self.assertEqual(v.getHiddenCppPointer(),ffCell.getUndergroundDataArray().getHiddenCppPointer()) - v.isEqual(DataArrayDouble([1000,1001,1002]),1e-12) - # - ffCell=allFMTSLeavesPerCommonSupport1[0][0][1][i] - fsst=MEDFileField1TSStructItem.BuildItemFrom(ffCell,mst) - ffCell.loadArraysIfNecessary() - v=mml2.buildDataArray(fsst,fields,ffCell.getUndergroundDataArray()) - self.assertEqual(v.getHiddenCppPointer(),ffCell.getUndergroundDataArray().getHiddenCppPointer()) - v.isEqual(DataArrayDouble([3000,3001,3002,3003,3004]),1e-12) - pass - fcscp=allFMTSLeavesPerCommonSupport1[1][1] - mml=fcscp.buildFromScratchDataSetSupport(0,fields) - mml2=mml.prepare() - self.assertTrue(isinstance(mml2,MEDUMeshMultiLev)) - ncc,a0,a1,a2,a3,a4,a5=mml2.buildVTUArrays() - self.assertTrue(not ncc)# here ncc=False because the coordinates are not in ms neither in children. - self.assertTrue(a0.isEqual(DataArrayDouble([(0,0,0),(1,0,0),(1,1,0),(0,1,0),(2,0,0),(-1,0,0),(1,2,0)]),1e-12)) - self.assertTrue(a1.isEqual(DataArrayByte([5,5,5,3,3,3,3]))) - self.assertTrue(a2.isEqual(DataArrayInt([0,4,8,12,15,18,21]))) - self.assertTrue(a3.isEqual(DataArrayInt([3,0,2,1,3,3,2,0,3,2,4,1,2,5,0,2,0,3,2,3,2,2,2,6]))) - self.assertTrue(a4 is None) - self.assertTrue(a5 is None) - for i in xrange(1): - ffCell=allFMTSLeavesPerCommonSupport1[1][0][0][i] - fsst=MEDFileField1TSStructItem.BuildItemFrom(ffCell,mst) - ffCell.loadArraysIfNecessary() - v=mml2.buildDataArray(fsst,fields,ffCell.getUndergroundDataArray()) - self.assertEqual(v.getHiddenCppPointer(),ffCell.getUndergroundDataArray().getHiddenCppPointer()) - v.isEqual(DataArrayDouble([2000,2001,2002,2003,2004,2005,2006]),1e-12) - pass - pass - - pass - -if __name__ == "__main__": - unittest.main() diff --git a/src/MEDLoader/Swig/MEDLoaderTypemaps.i b/src/MEDLoader/Swig/MEDLoaderTypemaps.i deleted file mode 100644 index 5a415a685..000000000 --- a/src/MEDLoader/Swig/MEDLoaderTypemaps.i +++ /dev/null @@ -1,358 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 -// 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 <vector> - -static PyObject *convertMEDFileMesh(ParaMEDMEM::MEDFileMesh* mesh, int owner) throw(INTERP_KERNEL::Exception) -{ - PyObject *ret=0; - if(!mesh) - { - Py_XINCREF(Py_None); - return Py_None; - } - if(dynamic_cast<ParaMEDMEM::MEDFileUMesh *>(mesh)) - ret=SWIG_NewPointerObj((void*)mesh,SWIGTYPE_p_ParaMEDMEM__MEDFileUMesh,owner); - if(dynamic_cast<ParaMEDMEM::MEDFileCMesh *>(mesh)) - ret=SWIG_NewPointerObj((void*)mesh,SWIGTYPE_p_ParaMEDMEM__MEDFileCMesh,owner); - if(dynamic_cast<ParaMEDMEM::MEDFileCurveLinearMesh *>(mesh)) - ret=SWIG_NewPointerObj((void*)mesh,SWIGTYPE_p_ParaMEDMEM__MEDFileCurveLinearMesh,owner); - if(!ret) - throw INTERP_KERNEL::Exception("Not recognized type of MEDFileMesh on downcast !"); - return ret; -} - -static PyObject *convertMEDFileParameter1TS(ParaMEDMEM::MEDFileParameter1TS* p1ts, int owner) throw(INTERP_KERNEL::Exception) -{ - PyObject *ret=0; - if(!p1ts) - { - Py_XINCREF(Py_None); - return Py_None; - } - if(dynamic_cast<MEDFileParameterDouble1TS *>(p1ts)) - ret=SWIG_NewPointerObj((void*)p1ts,SWIGTYPE_p_ParaMEDMEM__MEDFileParameterDouble1TS,owner); - if(dynamic_cast<MEDFileParameterDouble1TSWTI *>(p1ts)) - ret=SWIG_NewPointerObj((void*)p1ts,SWIGTYPE_p_ParaMEDMEM__MEDFileParameterDouble1TSWTI,owner); - if(!ret) - throw INTERP_KERNEL::Exception("Not recognized type of MEDFileParameter1TS on downcast !"); - return ret; -} - -static PyObject *convertMEDFileField1TS(ParaMEDMEM::MEDFileAnyTypeField1TS *p, int owner) throw(INTERP_KERNEL::Exception) -{ - PyObject *ret=0; - if(!p) - { - Py_XINCREF(Py_None); - return Py_None; - } - if(dynamic_cast<MEDFileField1TS *>(p)) - ret=SWIG_NewPointerObj((void*)p,SWIGTYPE_p_ParaMEDMEM__MEDFileField1TS,owner); - if(dynamic_cast<MEDFileIntField1TS *>(p)) - ret=SWIG_NewPointerObj((void*)p,SWIGTYPE_p_ParaMEDMEM__MEDFileIntField1TS,owner); - if(!ret) - throw INTERP_KERNEL::Exception("Not recognized type of MEDFileAnyTypeField1TS on downcast !"); - return ret; -} - -static PyObject *convertMEDFileFieldMultiTS(ParaMEDMEM::MEDFileAnyTypeFieldMultiTS *p, int owner) throw(INTERP_KERNEL::Exception) -{ - PyObject *ret=0; - if(!p) - { - Py_XINCREF(Py_None); - return Py_None; - } - if(dynamic_cast<MEDFileFieldMultiTS *>(p)) - ret=SWIG_NewPointerObj((void*)p,SWIGTYPE_p_ParaMEDMEM__MEDFileFieldMultiTS,owner); - if(dynamic_cast<MEDFileIntFieldMultiTS *>(p)) - ret=SWIG_NewPointerObj((void*)p,SWIGTYPE_p_ParaMEDMEM__MEDFileIntFieldMultiTS,owner); - if(!ret) - throw INTERP_KERNEL::Exception("Not recognized type of MEDFileAnyTypeFieldMultiTS on downcast !"); - return ret; -} - -static PyObject *convertMEDMeshMultiLev(ParaMEDMEM::MEDMeshMultiLev *p, int owner) throw(INTERP_KERNEL::Exception) -{ - PyObject *ret=0; - if(!p) - { - Py_XINCREF(Py_None); - return Py_None; - } - if(dynamic_cast<MEDUMeshMultiLev *>(p)) - ret=SWIG_NewPointerObj((void*)p,SWIGTYPE_p_ParaMEDMEM__MEDUMeshMultiLev,owner); - if(dynamic_cast<MEDCMeshMultiLev *>(p)) - ret=SWIG_NewPointerObj((void*)p,SWIGTYPE_p_ParaMEDMEM__MEDCMeshMultiLev,owner); - if(dynamic_cast<MEDCurveLinearMeshMultiLev *>(p)) - ret=SWIG_NewPointerObj((void*)p,SWIGTYPE_p_ParaMEDMEM__MEDCurveLinearMeshMultiLev,owner); - if(!ret) - throw INTERP_KERNEL::Exception("Not recognized type of MEDMeshMultiLev on downcast !"); - return ret; -} - -static std::vector<std::pair<int,int> > convertTimePairIdsFromPy(PyObject *pyLi) throw(INTERP_KERNEL::Exception) -{ - std::vector<std::pair<int,int> > ret; - if(PyList_Check(pyLi)) - { - int size=PyList_Size(pyLi); - ret.resize(size); - for(int i=0;i<size;i++) - { - PyObject *o=PyList_GetItem(pyLi,i); - if(PyTuple_Check(o)) - { - std::pair<int,int> p; - int size2=PyTuple_Size(o); - if(size2!=2) - throw INTERP_KERNEL::Exception("tuples in list must be of size 2 (dt,it) !"); - PyObject *o0=PyTuple_GetItem(o,0); - if(PyInt_Check(o0)) - p.first=(int)PyInt_AS_LONG(o0); - else - throw INTERP_KERNEL::Exception("First elem of tuples in list must be integer : dt !"); - PyObject *o1=PyTuple_GetItem(o,1); - if(PyInt_Check(o1)) - p.second=(int)PyInt_AS_LONG(o1); - else - throw INTERP_KERNEL::Exception("Second elem of tuples in list must be integer : dt !"); - ret[i]=p; - } - else - throw INTERP_KERNEL::Exception("list must contain tuples only"); - } - } - else - throw INTERP_KERNEL::Exception("convertTimePairIdsFromPy : not a list"); - return ret; -} - -static void converPyListToVecString(PyObject *pyLi, std::vector<std::string>& v) -{ - if(PyList_Check(pyLi)) - { - int size=PyList_Size(pyLi); - v.resize(size); - for(int i=0;i<size;i++) - { - PyObject *o=PyList_GetItem(pyLi,i); - if(!PyString_Check(o)) - throw INTERP_KERNEL::Exception("In list passed in argument some elements are NOT strings ! Expected a list containing only strings !"); - const char *st=PyString_AsString(o); - v[i]=std::string(st); - } - } - else if(PyTuple_Check(pyLi)) - { - int size=PyTuple_Size(pyLi); - v.resize(size); - for(int i=0;i<size;i++) - { - PyObject *o=PyTuple_GetItem(pyLi,i); - if(!PyString_Check(o)) - throw INTERP_KERNEL::Exception("In tuple passed in argument some elements are NOT strings ! Expected a tuple containing only strings !"); - const char *st=PyString_AsString(o); - v[i]=std::string(st); - } - } - else if(PyString_Check(pyLi)) - { - v.resize(1); - v[0]=std::string((const char *)PyString_AsString(pyLi)); - } - else - { - throw INTERP_KERNEL::Exception("Unrecognized python argument : expected a list of string or tuple of string or string !"); - } -} - -static PyObject *convertFieldDoubleVecToPy(const std::vector<ParaMEDMEM::MEDCouplingFieldDouble *>& li) -{ - int sz=li.size(); - PyObject *ret=PyList_New(sz); - for(int i=0;i<sz;i++) - { - PyObject *o=SWIG_NewPointerObj((void*)li[i],SWIGTYPE_p_ParaMEDMEM__MEDCouplingFieldDouble,SWIG_POINTER_OWN | 0); - PyList_SetItem(ret,i,o); - } - return ret; -} - -PyObject *convertVecPairVecStToPy(const std::vector< std::pair<std::vector<std::string>, std::string > >& vec) -{ - int sz=(int)vec.size(); - PyObject *ret=PyList_New(sz); - for(int i=0;i<sz;i++) - { - PyObject *t=PyTuple_New(2); - int sz2=(int)vec[i].first.size(); - PyObject *ll=PyList_New(sz2); - for(int j=0;j<sz2;j++) - PyList_SetItem(ll,j,PyString_FromString(vec[i].first[j].c_str())); - PyTuple_SetItem(t,0,ll); - PyTuple_SetItem(t,1,PyString_FromString(vec[i].second.c_str())); - PyList_SetItem(ret,i,t); - } - return ret; -} - -std::vector< std::pair<std::string, std::string > > convertVecPairStStFromPy(PyObject *pyLi) -{ - std::vector< std::pair<std::string, std::string > > ret; - const char *msg="convertVecPairStStFromPy : Expecting PyList of Tuples of size 2 ! The first elt in tuple is one string and the 2nd one a string !"; - if(PyList_Check(pyLi)) - { - int size=PyList_Size(pyLi); - ret.resize(size); - for(int i=0;i<size;i++) - { - PyObject *o=PyList_GetItem(pyLi,i); - if(PyTuple_Check(o)) - { - std::pair<std::string, std::string> p; - int size2=PyTuple_Size(o); - if(size2!=2) - throw INTERP_KERNEL::Exception(msg); - PyObject *o0=PyTuple_GetItem(o,0); - if(PyString_Check(o0)) - p.first=std::string(PyString_AsString(o0)); - else - throw INTERP_KERNEL::Exception(msg); - PyObject *o1=PyTuple_GetItem(o,1); - if(PyString_Check(o1)) - p.second=std::string(PyString_AsString(o1)); - else - throw INTERP_KERNEL::Exception(msg); - ret[i]=p; - } - else - throw INTERP_KERNEL::Exception(msg); - } - return ret; - } - throw INTERP_KERNEL::Exception(msg); -} - -std::vector< std::pair<std::vector<std::string>, std::string > > convertVecPairVecStFromPy(PyObject *pyLi) -{ - std::vector< std::pair<std::vector<std::string>, std::string > > ret; - const char *msg="convertVecPairVecStFromPy : Expecting PyList of Tuples of size 2 ! The first elt in tuple is a list of strings and the 2nd one a string !"; - if(PyList_Check(pyLi)) - { - int size=PyList_Size(pyLi); - ret.resize(size); - for(int i=0;i<size;i++) - { - PyObject *o=PyList_GetItem(pyLi,i); - if(PyTuple_Check(o)) - { - std::pair<std::vector<std::string>, std::string> p; - int size2=PyTuple_Size(o); - if(size2!=2) - throw INTERP_KERNEL::Exception(msg); - PyObject *o0=PyTuple_GetItem(o,0); - if(PyList_Check(o0)) - { - int size3=PyList_Size(o0); - p.first.resize(size3); - for(int j=0;j<size3;j++) - { - PyObject *o0j=PyList_GetItem(o0,j); - if(PyString_Check(o0j)) - { - p.first[j]=std::string(PyString_AsString(o0j)); - } - else - throw INTERP_KERNEL::Exception(msg); - } - } - else - throw INTERP_KERNEL::Exception(msg); - PyObject *o1=PyTuple_GetItem(o,1); - if(PyString_Check(o1)) - p.second=std::string(PyString_AsString(o1)); - else - throw INTERP_KERNEL::Exception(msg); - ret[i]=p; - } - else - throw INTERP_KERNEL::Exception(msg); - } - return ret; - } - throw INTERP_KERNEL::Exception(msg); -} - -/*! - * Called by MEDFileAnyTypeFieldMultiTS::__getitem__ when \a elt0 is neither a list nor a slice. - * In this case a MEDFileAnyTypeField1TS object is returned. - */ -int MEDFileAnyTypeFieldMultiTSgetitemSingleTS__(const MEDFileAnyTypeFieldMultiTS *self, PyObject *elt0) throw(INTERP_KERNEL::Exception) -{ - if(elt0 && PyInt_Check(elt0)) - {//fmts[3] - return InterpreteNegativeInt(PyInt_AS_LONG(elt0),self->getNumberOfTS()); - } - else if(elt0 && PyTuple_Check(elt0)) - { - if(PyTuple_Size(elt0)==2) - { - PyObject *o0=PyTuple_GetItem(elt0,0); - PyObject *o1=PyTuple_GetItem(elt0,1); - if(PyInt_Check(o0) && PyInt_Check(o1)) - {//fmts(1,-1) - int iter=PyInt_AS_LONG(o0); - int order=PyInt_AS_LONG(o1); - return self->getPosOfTimeStep(iter,order); - } - else - throw INTERP_KERNEL::Exception("MEDFileAnyTypeFieldMultiTS::__getitem__ : invalid input param ! input is a tuple of size 2 but two integers are expected in this tuple to request a time steps !"); - } - else - throw INTERP_KERNEL::Exception("MEDFileAnyTypeFieldMultiTS::__getitem__ : invalid input param ! input is a tuple of size != 2 ! two integers are expected in this tuple to request a time steps !"); - } - else if(elt0 && PyFloat_Check(elt0)) - { - double val=PyFloat_AS_DOUBLE(elt0); - return self->getPosGivenTime(val); - } - else - throw INTERP_KERNEL::Exception("MEDFileAnyTypeFieldMultiTS::__getitem__ : invalid input params ! expected fmts[int], fmts[int,int], or fmts[double] to request one time step ! To request a series of time steps invoke fmts[slice], fmts[list of int], fmts[list of double], or fmts[list of int,int] !"); -} - -/*! - * Called by MEDFileAnyTypeFieldMultiTS::__getitem__ when \a obj is neither a list nor a slice. - * In this case a MEDFileAnyTypeField1TS object is returned. - */ -int MEDFileFieldsgetitemSingleTS__(const MEDFileFields *self, PyObject *obj) throw(INTERP_KERNEL::Exception) -{ - if(PyInt_Check(obj)) - { - return InterpreteNegativeInt((int)PyInt_AS_LONG(obj),self->getNumberOfFields()); - } - else if(PyString_Check(obj)) - { - return self->getPosFromFieldName(PyString_AsString(obj)); - } - else - throw INTERP_KERNEL::Exception("MEDFileFields::__getitem__ : only integer or string with fieldname supported !"); -} diff --git a/src/MEDLoader/Swig/SauvLoaderTest.py b/src/MEDLoader/Swig/SauvLoaderTest.py deleted file mode 100644 index 502e4e468..000000000 --- a/src/MEDLoader/Swig/SauvLoaderTest.py +++ /dev/null @@ -1,391 +0,0 @@ -# -*- coding: iso-8859-1 -*- -# Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 -# 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 : Edward AGAPOV (eap) - -from MEDLoader import * -import unittest, os -from MEDLoaderDataForTest import MEDLoaderDataForTest - -class SauvLoaderTest(unittest.TestCase): - - def testSauv2Med(self): - # get a file containing all types of readable piles - self.assertTrue( os.getenv("MED_ROOT_DIR") ) - sauvFile = os.path.join( os.getenv("MED_ROOT_DIR"), "share","salome", - "resources","med","allPillesTest.sauv") - self.assertTrue( os.access( sauvFile, os.F_OK)) - - # read SAUV and write MED - medFile = "SauvLoaderTest.med" - sr=SauvReader(sauvFile); - d2=sr.loadInMEDFileDS(); - d2.write(medFile,0); - - # check - self.assertEqual(1,d2.getNumberOfMeshes()) - self.assertEqual(8+97,d2.getNumberOfFields()) - mm = d2.getMeshes() - m = mm.getMeshAtPos(0) - self.assertEqual(17,len(m.getGroupsNames())) - - os.remove( medFile ) - pass - - def testMed2Sauv(self): - # read pointe.med - self.assertTrue( os.getenv("MED_ROOT_DIR") ) - medFile = os.path.join( os.getenv("MED_ROOT_DIR"), "share","salome", - "resources","med","pointe.med") - self.assertTrue( os.access( medFile, os.F_OK)) - pointeMed = MEDFileData.New( medFile ) - - # add 3 faces to pointeMed - pointeMedMesh = pointeMed.getMeshes().getMeshAtPos(0) - pointeM1D = MEDCouplingUMesh.New() - pointeM1D.setCoords( pointeMedMesh.getCoords() ) - pointeM1D.setMeshDimension( 2 ) - pointeM1D.allocateCells( 3 ) - pointeM1D.insertNextCell( NORM_TRI3, 3, [0,1,2]) - pointeM1D.insertNextCell( NORM_TRI3, 3, [0,1,3]) - pointeM1D.insertNextCell( NORM_QUAD4, 4, [10,11,12,13]) - pointeM1D.finishInsertingCells() - pointeMedMesh.setMeshAtLevel( -1, pointeM1D ) - pointeMed.getMeshes().setMeshAtPos( 0, pointeMedMesh ) - - # add a field on 2 faces to pointeMed - ff1=MEDFileFieldMultiTS.New() - f1=MEDCouplingFieldDouble.New(ON_GAUSS_NE,ONE_TIME) - #f1.setMesh( pointeM1D ) - f1.setName("Field on 2 faces") - d=DataArrayDouble.New() - d.alloc(3+4,2) - d.setInfoOnComponent(0,"sigX [MPa]") - d.setInfoOnComponent(1,"sigY [GPa]") - d.setValues([311,312,321,322,331,332,411,412,421,422,431,432,441,442],3+4,2) - f1.setArray(d) - da=DataArrayInt.New() - da.setValues([0,2],2,1) - da.setName("sup2") - ff1.appendFieldProfile(f1,pointeMedMesh,-1,da) - pointeMed.getFields().pushField( ff1 ) - - #remove fieldnodeint - pointeFields = pointeMed.getFields() - for i in range( pointeFields.getNumberOfFields() ): - if pointeFields.getFieldAtPos(i).getName() == "fieldnodeint": - pointeFields.destroyFieldAtPos( i ) - break - - # write pointeMed to SAUV - sauvFile = "SauvLoaderTest.sauv" - sw=SauvWriter(); - sw.setMEDFileDS(pointeMed); - sw.write(sauvFile); - - # read SAUV and check - sr=SauvReader.New(sauvFile); - d2=sr.loadInMEDFileDS(); - self.assertEqual(1,d2.getNumberOfMeshes()) - self.assertEqual(4,d2.getNumberOfFields()) - m = d2.getMeshes().getMeshAtPos(0) - self.assertEqual("maa1",m.getName()) - self.assertEqual(6,len(m.getGroupsNames())) - self.assertEqual(3,m.getMeshDimension()) - groups = m.getGroupsNames() - self.assertTrue( "groupe1" in groups ) - self.assertTrue( "groupe2" in groups ) - self.assertTrue( "groupe3" in groups ) - self.assertTrue( "groupe4" in groups ) - self.assertTrue( "groupe5" in groups ) - self.assertTrue( "maa1" in groups ) - self.assertEqual(16,m.getSizeAtLevel(0)) - um0 = m.getGenMeshAtLevel(0) - self.assertEqual(12, um0.getNumberOfCellsWithType( NORM_TETRA4 )) - self.assertEqual(2, um0.getNumberOfCellsWithType( NORM_PYRA5 )) - self.assertEqual(2, um0.getNumberOfCellsWithType( NORM_HEXA8 )) - um1 = m.getGenMeshAtLevel(-1) - self.assertEqual(2, um1.getNumberOfCellsWithType( NORM_TRI3 )) - pointeUM0 = pointeMedMesh.getGenMeshAtLevel(0) - self.assertTrue(m.getCoords().isEqualWithoutConsideringStr(pointeMedMesh.getCoords(),1e-12)) - self.assertEqual( um0.getMeasureField(0).accumulate(0), - pointeUM0.getMeasureField(0).accumulate(0),1e-12) - # check fields - # fieldnodedouble - fieldnodedoubleTS1 = pointeMed.getFields().getFieldWithName("fieldnodedouble") - fieldnodedoubleTS2 = d2.getFields().getFieldWithName("fieldnodedouble") - self.assertEqual( fieldnodedoubleTS1.getInfo(), fieldnodedoubleTS2.getInfo()) - self.assertEqual( fieldnodedoubleTS1.getNumberOfTS(), fieldnodedoubleTS2.getNumberOfTS()) - io1 = fieldnodedoubleTS1.getIterations() - io2 = fieldnodedoubleTS2.getIterations() - for i in range(fieldnodedoubleTS1.getNumberOfTS() ): - fnd1 = fieldnodedoubleTS1.getFieldOnMeshAtLevel(ON_NODES, io1[i][0],io1[i][1],pointeUM0) - fnd2 = fieldnodedoubleTS2.getFieldOnMeshAtLevel(ON_NODES, io2[i][0],io2[i][1],um0) - self.assertTrue( fnd1.getArray().isEqual( fnd2.getArray(), 1e-12 )) - # fieldcelldoublevector - fieldnodedoubleTS1 = pointeMed.getFields().getFieldWithName("fieldcelldoublevector") - fieldnodedoubleTS2 = d2.getFields().getFieldWithName("fieldcelldoublevector") - self.assertEqual( fieldnodedoubleTS1.getInfo(), fieldnodedoubleTS2.getInfo()) - self.assertEqual( fieldnodedoubleTS1.getNumberOfTS(), fieldnodedoubleTS2.getNumberOfTS()) - io1 = fieldnodedoubleTS1.getIterations() - io2 = fieldnodedoubleTS2.getIterations() - for i in range(fieldnodedoubleTS1.getNumberOfTS() ): - fnd1 = fieldnodedoubleTS1.getFieldOnMeshAtLevel(ON_CELLS, io1[i][0],io1[i][1],pointeUM0) - fnd2 = fieldnodedoubleTS2.getFieldOnMeshAtLevel(ON_CELLS, io2[i][0],io2[i][1],um0) - self.assertAlmostEqual( fnd1.accumulate(0), fnd2.accumulate(0) ) - self.assertAlmostEqual( fnd1.accumulate(1), fnd2.accumulate(1) ) - self.assertAlmostEqual( fnd1.accumulate(2), fnd2.accumulate(2) ) - # Field on 2 faces - fieldOnFaces = d2.getFields().getFieldWithName(f1.getName()) - io1 = fieldOnFaces.getIterations() - fof = fieldOnFaces.getFieldOnMeshAtLevel(f1.getTypeOfField(),io1[i][0],io1[i][1],um1) - self.assertTrue( d.isEqual( fof.getArray(), 1e-12 )) - pass - del sr - os.remove( sauvFile ) - pass - - def testSauv2MedWONodeFamilyNum(self): - """test for issue 0021673: [CEA 566] Bug in SauvWriter when writing meshes - having no family ids on nodes.""" - - myCoords=DataArrayDouble.New([-0.3,-0.3, 0.2,-0.3, 0.7,-0.3, -0.3,0.2, 0.2,0.2, 0.7,0.2, -0.3,0.7, 0.2,0.7, 0.7,0.7 ],9,2) - targetConn=[0,3,4,1, 1,4,2, 4,5,2, 6,7,4,3, 7,8,5,4]; - targetMesh=MEDCouplingUMesh.New("BugInSauvWriter",2); - targetMesh.allocateCells(5); - targetMesh.insertNextCell(NORM_TRI3,3,targetConn[4:7]); - targetMesh.insertNextCell(NORM_TRI3,3,targetConn[7:10]); - targetMesh.insertNextCell(NORM_QUAD4,4,targetConn[0:4]); - targetMesh.insertNextCell(NORM_QUAD4,4,targetConn[10:14]); - targetMesh.insertNextCell(NORM_QUAD4,4,targetConn[14:18]); - targetMesh.finishInsertingCells(); - targetMesh.setCoords(myCoords); - # - m=MEDFileUMesh.New() - m.setMeshAtLevel(0,targetMesh) - # start of bug - fam=DataArrayInt.New(targetMesh.getNumberOfNodes()) - fam[:]=0 - #m.setFamilyFieldArr(1,fam) - #end of bug - - ms=MEDFileMeshes.New() - ms.setMeshAtPos(0,m) - meddata=MEDFileData.New() - meddata.setMeshes(ms) - - medFile = "BugInSauvWriter.sauv" - sw=SauvWriter.New(); - sw.setMEDFileDS(meddata); - sw.write(medFile); - - os.remove( medFile ) - pass - - def testSauv2MedOnPipe1D(self): - """test for issue 0021745: [CEA 600] Some missing groups in mesh after reading a SAUV file with SauvReader.""" - sauvFile="Test_sauve_1D.sauv" - # Make a sauve file with a qudratic 1D mesh - m=MEDCouplingUMesh.New("pipe1D",1) - m.allocateCells(2); - targetConn=[0,2,1, 2,4,3] - m.insertNextCell(NORM_SEG3,3,targetConn[0:3]) - m.insertNextCell(NORM_SEG3,3,targetConn[3:6]) - m.finishInsertingCells(); - # coords - coords=[ 0.,1.,2.,4.,5. ]; - c=DataArrayDouble.New() - c.setValues(coords,5,1) - m.setCoords(c) - # MEDFileUMesh - mm=MEDFileUMesh.New() - mm.setName(m.getName()) - mm.setDescription("1D mesh") - mm.setCoords(c) - mm.setMeshAtLevel(0,m); - # MEDFileData - mfd1 = MEDFileData.New() - ms=MEDFileMeshes.New(); ms.setMeshAtPos(0,mm) - mfd1.setMeshes(ms) - # write - sw=SauvWriter.New() - sw.setMEDFileDS(mfd1) - sw.write(sauvFile) - # Check connectivity read from the sauv file - sr = SauvReader.New(sauvFile) - mfd2 = sr.loadInMEDFileDS() - mfMesh = mfd2.getMeshes()[0] - mesh = mfMesh.getMeshAtLevel(0) - self.assertTrue(mesh.getNodalConnectivity().isEqual(m.getNodalConnectivity())) - # - del sr - os.remove(sauvFile) - pass - - @unittest.skipUnless(MEDLoader.HasXDR(),"requires XDR") - def testMissingGroups(self): - """test for issue 0021749: [CEA 601] Some missing groups in mesh after reading a SAUV file with SauvReader.""" - self.assertTrue( os.getenv("MED_ROOT_DIR") ) - sauvFile = os.path.join( os.getenv("MED_ROOT_DIR"), "share","salome", - "resources","med","BDC-714.sauv") - self.assertTrue( os.access( sauvFile, os.F_OK)) - name_of_group_on_cells='Slice10:ABSORBER' - name_of_group_on_cells2='Slice10:00LR' - sr=SauvReader.New(sauvFile) - mfd2=sr.loadInMEDFileDS() - mfMesh=mfd2.getMeshes()[0] - # - self.assertTrue(name_of_group_on_cells in mfMesh.getGroupsNames()) - self.assertTrue(name_of_group_on_cells2 in mfMesh.getGroupsNames()) - self.assertEqual(270,len(mfMesh.getGroupsNames())) - # - ids1=mfMesh.getGroupArr(0,name_of_group_on_cells) - ids2=mfMesh.getGroupArr(0,name_of_group_on_cells2) - ids1.setName("") - ids2.setName("") - self.assertTrue(ids1.isEqual(ids2)) - pass - - def testGaussPt(self): - """issue 22321: [CEA 933] Bug when reading a sauve file containing field on Gauss Pt. - The problem was that a field ON_GAUSS_PT was created but no Gauss Localization - was defined""" - - # create a MEDFileData with a field ON_GAUSS_PT: 9 Gauss points, on 4 QUAD8 elements - f=MEDCouplingFieldDouble(ON_GAUSS_PT) - m=MEDCouplingUMesh("mesh",2) ; m.allocateCells() - m.insertNextCell(NORM_QUAD8,[0,2,4,6,1,3,5,7]) - m.insertNextCell(NORM_QUAD8,[2,9,11,4,8,10,12,3]) - m.insertNextCell(NORM_QUAD8,[6,4,14,16,5,13,15,17]) - m.insertNextCell(NORM_QUAD8,[4,11,19,14,12,18,20,13]) - m.setCoords(DataArrayDouble([(0,0),(0,0.25),(0,0.5),(0.25,0.5),(0.5,0.5),(0.5,0.25),(0.5,0),(0.25,0),(0,0.75),(0,1),(0.25,1),(0.5,1),(0.5,0.75),(0.75,0.5),(1,0.5),(1,0.25),(1,0),(0.75,0),(0.75,1),(1,1),(1,0.75)],21,2)) - f.setMesh(m) - arr=DataArrayDouble(4*9*2) ; arr.iota() ; arr.rearrange(2) ; arr.setInfoOnComponents(["YOUN []","NU []"]) - f.setArray(arr) - refCoo=[-1,-1,1,-1,1,1,-1,1,0,-1,1,0,0,1,-1,0] - gpCoo=[-0.7,-0.7,0.7,-0.7,0.7,0.7,-0.7,0.7,0,-0.7,0.7,0,0,0.7,-0.7,0,0,0] - wgt=[0.3,0.3,0.3,0.3,0.4,0.4,0.4,0.4,0.7] - f.setGaussLocalizationOnType(NORM_QUAD8,refCoo,gpCoo,wgt) - f.setName("SIGT") - f.checkCoherency() - # - mm=MEDFileUMesh() - mm.setMeshAtLevel(0,m) - mfm = MEDFileMeshes() - mfm.pushMesh( mm ) - ff=MEDFileField1TS() - ff.setFieldNoProfileSBT(f) - mfmts = MEDFileFieldMultiTS() - mfmts.pushBackTimeStep(ff) - mff = MEDFileFields() - mff.pushField( mfmts ) - mfd = MEDFileData.New() - mfd.setFields( mff ) - mfd.setMeshes( mfm ) - - # convert the MED file to a SAUV file - sauvFile = "SauvLoaderTest_testGaussPt.sauv" - sw=SauvWriter.New(); - sw.setMEDFileDS(mfd); - sw.write(sauvFile); - - # convert the SAUV file back to MED - sr=SauvReader.New(sauvFile); - d2=sr.loadInMEDFileDS(); - - self.assertEqual( 1, d2.getNumberOfFields() ) - self.assertEqual( 1, d2.getNumberOfMeshes() ) - mfm2 = d2.getMeshes()[0] - mff2 = d2.getFields()[0] - m2 = mfm2.getMeshAtLevel(0) - f2 = mff2.getTimeStepAtPos(0).getFieldOnMeshAtLevel(f.getTypeOfField(),0,mfm2) - f2.setGaussLocalizationOnType(NORM_QUAD8,refCoo,gpCoo,wgt) # not stored in SAUV - #f2.setOrder( f.getTime()[2] ) # not stored in SAUV - self.assertTrue( m2.isEqual( m, 1e-12 )) - self.assertTrue( f2.isEqual( f, 1e-12, 1e-12 )) - del sr - os.remove( sauvFile ) - pass - - def testSauvWriterGroupWithOneFamily(self): - """ - This test checks an option for sauv writing. It is requested here to copy a group from a family if a group is lying on a single family. - """ - import re - mfd=MEDLoaderDataForTest.buildAMEDFileDataWithGroupOnOneFamilyForSauv() - sauvFile = "mesh.sauv" - sw=SauvWriter.New() - sw.setMEDFileDS(mfd) - self.assertTrue(not sw.getCpyGrpIfOnASingleFamilyStatus()) - sw.setCpyGrpIfOnASingleFamilyStatus(True) - self.assertTrue(sw.getCpyGrpIfOnASingleFamilyStatus()) - sw.write(sauvFile) - - f = open(sauvFile) - # String pattern for the header of the sub meshes record ("PILE" number, number of named objects, number of objects) - pattern_pile= re.compile(r'\sPILE\sNUMERO\s+(?P<number>[0-9]+)NBRE\sOBJETS\sNOMMES\s+(?P<nbnamed>[0-9]+)NBRE\sOBJETS\s+(?P<nbobjects>[0-9]+)') - # String pattern for a sub mesh header (cell type, number of components and three numbers) - pattern_header=re.compile(r'\s+(?P<type>[0-9]+)\s+(?P<nbsubs>[0-9]+)\s+[0-9]+\s+[0-9]+\s+[0-9]+') - - nbobjects=0 - line = f.readline() - while(line): - match_pile = pattern_pile.match(line) - if match_pile: - number=int(match_pile.group("number")) - if number == 1: - nbnamed=int(match_pile.group("nbnamed")) - nbobjects=int(match_pile.group("nbobjects")) - break - pass - line=f.readline() - pass - - # Skipping the objects names - f.readline() - # Skipping the objects ids - f.readline() - - # Looking for each sub-mesh header - line = f.readline() - cur_object=0 - while(line and cur_object < nbobjects): - match_header=pattern_header.match(line) - if match_header: - cell_type=int(match_header.group("type")) - nb_subs=int(match_header.group("nbsubs")) - # Looking for a compound object - if cell_type == 0: - # Testing if there is only one component - self.assertTrue(nb_subs > 1) - else: - f.readline() - f.readline() - cur_object = cur_object + 1 - pass - pass - line=f.readline() - pass - f.close() - os.remove(sauvFile) - pass - - pass - -unittest.main() diff --git a/src/MEDLoader/Swig/VTKReader.py b/src/MEDLoader/Swig/VTKReader.py deleted file mode 100644 index b54174459..000000000 --- a/src/MEDLoader/Swig/VTKReader.py +++ /dev/null @@ -1,306 +0,0 @@ -# -*- coding: iso-8859-1 -*- -# Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 -# 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/DM2S/STMF) - -from MEDLoader import * - -class PVDReader: - @classmethod - def New(cls,fileName): - """ Static constructor. """ - return PVDReader(fileName) - pass - - def __init__(self,fileName): - self._fileName=fileName - pass - - def loadTopInfo(self): - fd=open(self._fileName,"r") - return self.__parseXML(fd) - - def __parseXML(self,fd): - import xml.sax - class PVD_SAX_Reader(xml.sax.ContentHandler): - def __init__(self): - self._tsteps=[] - pass - def startElement(self,name,attrs): - if name=="VTKFile": - if attrs["type"]!="Collection": - raise Exception("Mismatch between reader (PVD) type and file content !") - return - if name=="DataSet": - self._tsteps.append((float(attrs["timestep"]),str(attrs["file"]))) - return - pass - pass - rd=PVD_SAX_Reader() - parser=xml.sax.make_parser() - parser.setContentHandler(rd) - parser.parse(fd) - return rd - pass - -class PVTUReader: - @classmethod - def New(cls,fileName): - """ Static constructor. """ - return PVTUReader(fileName) - pass - - def __init__(self,fileName): - self._fileName=fileName - pass - - def loadParaInfo(self): - fd=open(self._fileName,"r") - return self.__parseXML(fd) - - def __parseXML(self,fd): - import xml.sax - class PVTU_SAX_Reader(xml.sax.ContentHandler): - def __init__(self): - self._data_array={2:self.DAPointData,3:self.DACellData} - self._node_fields=[] - self._cell_fields=[] - self._pfiles=[] - self._tmp=None - pass - def DAPointData(self,attrs): - self._node_fields.append((str(attrs["Name"]),int(attrs["NumberOfComponents"]))) - pass - def DACellData(self,attrs): - self._cell_fields.append((str(attrs["Name"]),int(attrs["NumberOfComponents"]))) - pass - def startElement(self,name,attrs): - if name=="VTKFile": - if attrs["type"]!="PUnstructuredGrid": - raise Exception("Mismatch between reader (PVTU) type and file content !") - return - if name=="Piece": - self._pfiles.append(str(attrs["Source"])) - return - if name=="PPointData": - self._tmp=2 - return - if name=="PCellData": - self._tmp=3 - return - if name=="PDataArray": - if self._tmp in self._data_array.keys(): - self._data_array[self._tmp](attrs) - pass - return - pass - pass - rd=PVTU_SAX_Reader() - parser=xml.sax.make_parser() - parser.setContentHandler(rd) - parser.parse(fd) - return rd - pass - -class VTURawReader: - """ Converting a VTU file in raw mode into the MED format. - """ - VTKTypes_2_MC=[-1,0,-1,1,33,3,-1,5,-1,4,14,-1,NORM_HEXA8,16,15,-1,22,-1,-1,-1,-1,2,6,8,20,30,25,23,9,27,-1,-1,-1,-1,7,-1,-1,-1,-1,-1,-1,-1,31] - - class NormalException(Exception): - def __init__(self,lineNb): - Exception.__init__(self) - self._line_nb=lineNb - def getLineNb(self): - return self._line_nb - pass - - class NotRawVTUException(Exception): - pass - - def loadInMEDFileDS(self): - import numpy as np - fd=open(self._fileName,"r") - ref,rd=self.__parseXML(fd) - # - ret=MEDFileData() - ms=MEDFileMeshes() ; ret.setMeshes(ms) - fs=MEDFileFields() ; ret.setFields(fs) - # - types=np.memmap(fd,dtype=rd._type_types,mode='r',offset=ref+rd._off_types,shape=(rd._nb_cells,)) - types=self.__swapIfNecessary(rd._bo,types) - # mesh dimension detection - types2=types.copy() ; types2.sort() ; types2=np.unique(types2) - meshDim=MEDCouplingMesh.GetDimensionOfGeometricType(self.VTKTypes_2_MC[types2[0]]) - for typ in types2[1:]: - md=MEDCouplingMesh.GetDimensionOfGeometricType(self.VTKTypes_2_MC[typ]) - if md!=meshDim: - raise Exception("MultiLevel umeshes not managed yet !") - pass - m=MEDCouplingUMesh("mesh",meshDim) - # coordinates - coo=np.memmap(fd,dtype=rd._type_coords,mode='r',offset=ref+rd._off_coords,shape=(rd._nb_nodes*rd._space_dim,)) - coo=self.__swapIfNecessary(rd._bo,coo) ; coo=DataArrayDouble(np.array(coo,dtype='float64')) ; coo.rearrange(rd._space_dim) - m.setCoords(coo) - # connectivity - offsets=np.memmap(fd,dtype=rd._type_off,mode='r',offset=ref+rd._off_off,shape=(rd._nb_cells,)) - offsets=self.__swapIfNecessary(rd._bo,offsets) ; connLgth=offsets[-1] ; offsets2=DataArrayInt(rd._nb_cells+1) ; offsets2.setIJ(0,0,0) - offsets2[1:]=DataArrayInt(offsets) - offsets3=offsets2.deltaShiftIndex() ; offsets2=offsets3.deepCpy() ; offsets3+=1 ; offsets3.computeOffsets2() - offsets=offsets3 - tmp1=DataArrayInt(len(offsets2),2) ; tmp1[:,0]=1 ; tmp1[:,1]=offsets2 ; tmp1.rearrange(1) ; tmp1.computeOffsets2() - tmp1=DataArrayInt.Range(1,2*len(offsets2),2).buildExplicitArrByRanges(tmp1) - conn=np.memmap(fd,dtype=rd._type_conn,mode='r',offset=ref+rd._off_conn,shape=(connLgth,)) - conn=self.__swapIfNecessary(rd._bo,conn) - types=np.array(types,dtype='int32') ; types=DataArrayInt(types) ; types.transformWithIndArr(self.VTKTypes_2_MC) - conn2=DataArrayInt(offsets.back()) - conn2[offsets[0:-1]]=types - conn2[tmp1]=DataArrayInt(conn) - m.setConnectivity(conn2,offsets,True) - m.checkCoherency() ; mm=MEDFileUMesh() ; mm.setMeshAtLevel(0,m) ; ms.pushMesh(mm) - # Fields on nodes and on cells - for spatialDisc,nbEnt,fields in [(ON_NODES,rd._nb_nodes,rd._node_fields),(ON_CELLS,rd._nb_cells,rd._cell_fields)]: - for name,typ,nbCompo,off in fields: - ff=MEDFileFieldMultiTS() - f=MEDCouplingFieldDouble(spatialDisc,ONE_TIME) - f.setName(name) ; f.setMesh(m) - vals=np.memmap(fd,dtype=typ,mode='r',offset=ref+off,shape=(nbEnt*nbCompo)) - vals=self.__swapIfNecessary(rd._bo,vals) - arr=DataArrayDouble(np.array(vals,dtype='float64')) ; arr.rearrange(nbCompo) - f.setArray(arr) ; f.checkCoherency() - f.setTime(self._time[0],self._time[1],0) - ff.appendFieldNoProfileSBT(f) - fs.pushField(ff) - pass - pass - return ret - - def __parseXML(self,fd): - import xml.sax - class VTU_SAX_Reader(xml.sax.ContentHandler): - def __init__(self): - self._loc=None - self._data_array={0:self.DAPoints,1:self.DACells,2:self.DAPointData,3:self.DACellData} - self._node_fields=[] - self._cell_fields=[] - pass - def setLocator(self,loc): - self._loc=loc - def DAPoints(self,attrs): - self._space_dim=int(attrs["NumberOfComponents"]) - self._type_coords=str(attrs["type"]).lower() - self._off_coords=int(attrs["offset"]) - pass - def DACells(self,attrs): - if attrs["Name"]=="connectivity": - self._type_conn=str(attrs["type"]).lower() - self._off_conn=int(attrs["offset"]) - pass - if attrs["Name"]=="offsets": - self._type_off=str(attrs["type"]).lower() - self._off_off=int(attrs["offset"]) - pass - if attrs["Name"]=="types": - self._type_types=str(attrs["type"]).lower() - self._off_types=int(attrs["offset"]) - pass - pass - def DAPointData(self,attrs): - self._node_fields.append((str(attrs["Name"]),str(attrs["type"]).lower(),int(attrs["NumberOfComponents"]),int(attrs["offset"]))) - pass - def DACellData(self,attrs): - self._cell_fields.append((str(attrs["Name"]),str(attrs["type"]).lower(),int(attrs["NumberOfComponents"]),int(attrs["offset"]))) - pass - def startElement(self,name,attrs): - if name=="VTKFile": - if attrs["type"]!="UnstructuredGrid": - raise Exception("Mismatch between reader (VTU) type and file content !") - self._bo=bool(["LittleEndian","BigEndian"].index(attrs["byte_order"])) - pass - if name=="Piece": - self._nb_cells=int(attrs["NumberOfCells"]) - self._nb_nodes=int(attrs["NumberOfPoints"]) - return - if name=="Points": - self._tmp=0 - return - if name=="Cells": - self._tmp=1 - return - if name=="PointData": - self._tmp=2 - return - if name=="CellData": - self._tmp=3 - return - if name=="DataArray": - self._data_array[self._tmp](attrs) - return - if name=="AppendedData": - if str(attrs["encoding"])=="raw": - raise VTURawReader.NormalException(self._loc.getLineNumber()) - else: - raise VTURawReader.NotRawVTUException("The file is not a raw VTU ! Change reader !") - pass - pass - rd=VTU_SAX_Reader() - parser=xml.sax.make_parser() - parser.setContentHandler(rd) - locator=xml.sax.expatreader.ExpatLocator(parser) - rd.setLocator(locator) - isOK=False - try: - parser.parse(fd) - except self.NormalException as e: - isOK=True - fd.seek(0) - for i in xrange(e.getLineNb()): fd.readline() - ref=fd.tell()+5 - pass - if not isOK: - raise Exception("Error in VTURawReader : not a raw format ?") - return ref,rd - - @classmethod - def New(cls,fileName,tim=(0.,0)): - """ Static constructor. """ - return VTURawReader(fileName,tim) - pass - - def __init__(self,fileName,tim=(0.,0)): - msg="The time specified in constructor as 2nd arg should be a tuple containing 2 values 1 float and 1 int !" - if type(tim)!=tuple: - raise Exception(msg) - if len(tim)!=2: - raise Exception(msg) - if type(tim[0])!=float or type(tim[1])!=int: - raise Exception(msg) - self._fileName=fileName - self._time=tim - pass - - def __swapIfNecessary(self,b,arr): - if b: - ret=arr.copy() - ret.byteswap(True) - return ret - else: - return arr - pass - pass diff --git a/src/MEDLoader/Swig/case2med b/src/MEDLoader/Swig/case2med deleted file mode 100755 index ef2e15286..000000000 --- a/src/MEDLoader/Swig/case2med +++ /dev/null @@ -1,54 +0,0 @@ -#!/usr/bin/env python -# -*- coding: iso-8859-1 -*- -# Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 -# 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 -# - -from CaseReader import CaseReader -from optparse import OptionParser -import os - -parser = OptionParser() -parser.set_usage("Convert a Case file to a MED file.\n %prog [options] case_file") -parser.add_option("-c", "--currentdir", action="store_true", dest="here", default=False, - help="Are generated MED file generated in current directory. By default not, MED file is generated in directory containing the input file (default False)") -(opts, args) = parser.parse_args() - -if len(args) != 1: - parser.print_usage() - exit(1) - pass - -fname=args[0] #"cas_test_simple.case" -if opts.here: - fOut=os.path.splitext(os.path.basename(fname))[0]+".med" - pass -else: - fOut=os.path.splitext(fname)[0]+".med" - pass -### -cr=CaseReader(fname) -try: - medfd=cr.loadInMEDFileDS() -except: - print "An error occured during the conversion!" - print "#######################################" - raise -medfd.write(fOut,2) -print "#########\nFile \"%s\" written !\n#########"%(fOut) - diff --git a/src/MEDLoader/Swig/med2case b/src/MEDLoader/Swig/med2case deleted file mode 100755 index bec9f4f30..000000000 --- a/src/MEDLoader/Swig/med2case +++ /dev/null @@ -1,63 +0,0 @@ -#!/usr/bin/env python -# -*- coding: iso-8859-1 -*- -# Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 -# 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/DM2S/STMF/LGLS) - -from MEDLoader import MEDFileData,InterpKernelException -from CaseWriter import CaseWriter -from optparse import OptionParser -import os - -parser = OptionParser() -parser.set_usage("Convert a MED file to a Case file.\n %prog [options] med_file") -parser.add_option("-g", "--groups", action="store_true", dest="groups", default=False, - help="Are groups in meshes stored in MEDFile exported in output case as subparts (default False)") -parser.add_option("-c", "--currentdir", action="store_true", dest="here", default=False, - help="Are generated case,geo files generated in current directory. By default not, files are generated in directory containing the input file (default False)") -(opts, args) = parser.parse_args() - -if len(args) != 1: - parser.print_usage() - exit(1) - pass - -fname=os.path.abspath(args[0]) #"cas_test_simple.case" -if opts.here: - fOut=os.path.splitext(os.path.basename(fname))[0]+".case" - pass -else: - fOut=os.path.splitext(fname)[0]+".case" - pass -### -try: - cw=CaseWriter.New() - cw.setExportingGroups(opts.groups) - mfd=MEDFileData(fname) - cw.setMEDFileDS(mfd) - listOfWrittenFileNames=cw.write(fOut) -except InterpKernelException as e: - print "An error occurred during the conversion!" - print "#######################################" - raise e -print "#########" -for l in listOfWrittenFileNames: - print "File \"%s\" successfully written !"%(l) - pass -print "#########" diff --git a/src/MEDLoader/Swig/med2sauv b/src/MEDLoader/Swig/med2sauv deleted file mode 100755 index 8ba498033..000000000 --- a/src/MEDLoader/Swig/med2sauv +++ /dev/null @@ -1,35 +0,0 @@ -#!/usr/bin/env python -# -- -# Copyright (C) 2009-2015 CEA/DEN, EDF 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, 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 -# 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 : Erwan ADAM (CEA) -# -- - -from sys import argv,path -from os.path import dirname,abspath,sep -from medutilities import med2sauv - -d = argv[0] -d = dirname(d) -d = abspath(d+sep+".."+sep+"lib") -if d not in path: - path.insert(0,d) - pass - -med2sauv(*argv[1:]) diff --git a/src/MEDLoader/Swig/medutilities.py b/src/MEDLoader/Swig/medutilities.py deleted file mode 100644 index 64c541868..000000000 --- a/src/MEDLoader/Swig/medutilities.py +++ /dev/null @@ -1,141 +0,0 @@ -# -*- coding: iso-8859-1 -*- -# -- -# Copyright (C) 2009-2015 CEA/DEN, EDF 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, 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 -# 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 : Erwan ADAM (CEA), Anthony GEAY (CEA) -# -- - -from MEDLoader import * - -def my_remove(f): - from os import remove - try: - remove(f) - except OSError: - pass - return - -def convert(file_in, driver_in, driver_out, format=1, file_out=None): - # - print file_in - # - if file_out is None: - file_out = file_in - if driver_out == "GIBI": - file_out += ".sauv" - elif driver_out == "MED": - file_out += ".med" - else: - msg = "Driver out %s is unknown"%(driver_out) - raise NotImplementedError(msg) - pass - print file_out - # - if driver_in == "GIBI": - sr = SauvReader.New(file_in) - mfd= sr.loadInMEDFileDS() - pass - elif driver_in == "MED": - mfd = MEDFileData(file_in) - pass - else: - raise NotImplementedError("Driver in %s is unknown"%(driver_in)) - # - my_remove(file_out) - # - if driver_out == "GIBI": - sw=SauvWriter.New() - sw.setMEDFileDS(mfd,0);#0 ? - sw.write(file_out) - # - mesh = mfd.getMeshes()[0] - mesh_dim = mesh.getSpaceDimension() - if mesh_dim >= 3: - from sys import platform - if platform in ["win32"]: - f = open(file_out) - content = f.read() - f.close() - content = content.replace("IFOUR -1", "IFOUR 2") - content = content.replace("IFOMOD -1", "IFOMOD 2") - f = open(file_out, "w") - f.write(content) - f.close() - else: - cmd = "sed" - cmd += ' -e "s/IFOUR -1/IFOUR 2/g"' - cmd += ' -e "s/IFOMOD -1/IFOMOD 2/g"' - # cmd += ' -e "s/IECHO 1/IECHO 0/g"' - cmd += ' %s > .dummy'%(file_out) - cmd += ' && ' - cmd += ' mv -f .dummy %s'%(file_out) - from os import system - system(cmd) - pass - pass - # - if format == 0: - from castemlauncher import CastemLauncher - dgibi_stream = "\n" - dgibi_stream += "OPTI REST FORMAT '%s' ;\n"%(file_out) - dgibi_stream += "REST FORMAT;\n" - file_out = file_out.replace('__format__', '') - dgibi_stream += "OPTI SAUV '%s' ;\n"%(file_out) - dgibi_stream += "SAUV ;\n" - cl = CastemLauncher(dgibi_stream) - cl.addTmpFiles(file_out+'__format__', "UTILNOTI", "UTILPROC") - cl.run() - pass - return - elif driver_out == "MED": - mfd.write(file_out,2) - return - else: - raise NotImplementedError("Driver in %s is unknown"%(driver_in)) - -def sauv2med(*argv): - argv = list(argv) - for arg in argv: - convert(arg, "GIBI", "MED") - pass - return - -def med2sauv(*argv): - argv = list(argv) - format = 1 - for arg in argv[:]: - if arg.find('--format') == 0: - argv.remove(arg) - try: - value = arg.split("=")[1] - except IndexError: - usage(1) - pass - try: - value = int(value) - except ValueError: - usage(1) - pass - format = value - pass - pass - for arg in argv: - convert(arg, "MED", "GIBI", format) - pass - return diff --git a/src/MEDLoader/Swig/sauv2med b/src/MEDLoader/Swig/sauv2med deleted file mode 100755 index d4f9cf693..000000000 --- a/src/MEDLoader/Swig/sauv2med +++ /dev/null @@ -1,35 +0,0 @@ -#!/usr/bin/env python -# -- -# Copyright (C) 2009-2015 CEA/DEN, EDF 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, 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 -# 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 : Erwan ADAM (CEA) -# -- - -from sys import argv,path -from os.path import dirname,abspath,sep -from medutilities import sauv2med - -d = argv[0] -d = dirname(d) -d = abspath(d+sep+".."+sep+"lib") -if d not in path: - path.insert(0,d) - pass - -sauv2med(*argv[1:]) diff --git a/src/MEDLoader/Test/CMakeLists.txt b/src/MEDLoader/Test/CMakeLists.txt deleted file mode 100644 index b13a46f85..000000000 --- a/src/MEDLoader/Test/CMakeLists.txt +++ /dev/null @@ -1,64 +0,0 @@ -# Copyright (C) 2012-2015 CEA/DEN, EDF 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, 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 -# 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_DIRECTORIES( - ${CPPUNIT_INCLUDE_DIRS} - ${HDF5_INCLUDE_DIRS} - ${MEDFILE_INCLUDE_DIRS} - ${CMAKE_CURRENT_SOURCE_DIR}/.. - ${CMAKE_CURRENT_SOURCE_DIR}/../../MEDCoupling - ${CMAKE_CURRENT_SOURCE_DIR}/../../INTERP_KERNEL - ${CMAKE_CURRENT_SOURCE_DIR}/../../INTERP_KERNEL/Bases - ${CMAKE_CURRENT_SOURCE_DIR}/../../INTERP_KERNELTest # For common CppUnitTest.hxx file - ) - -SET(TestMEDLoader_SOURCES - TestMEDLoader.cxx - MEDLoaderTest.cxx - ) - -SET(TestSauvLoader_SOURCES - TestSauvLoader.cxx - SauvLoaderTest.cxx - ) - -SALOME_GENERATE_TESTS_ENVIRONMENT(tests_env) - -ADD_EXECUTABLE(TestMEDLoader ${TestMEDLoader_SOURCES}) -TARGET_LINK_LIBRARIES(TestMEDLoader medloader ${CPPUNIT_LIBRARIES} ${PLATFORM_LIBS}) -ADD_TEST(TestMEDLoader TestMEDLoader) -SET_TESTS_PROPERTIES(TestMEDLoader PROPERTIES ENVIRONMENT "${tests_env}") - -ADD_EXECUTABLE(TestSauvLoader ${TestSauvLoader_SOURCES}) - -TARGET_LINK_LIBRARIES(TestSauvLoader medloader ${CPPUNIT_LIBRARIES} ${PLATFORM_LIBS}) -ADD_TEST(TestSauvLoader TestSauvLoader) -SET_TESTS_PROPERTIES(TestSauvLoader PROPERTIES ENVIRONMENT "${tests_env}") - -INSTALL(TARGETS TestMEDLoader TestSauvLoader DESTINATION ${SALOME_INSTALL_BINS}) - -# Application tests - -SET(TEST_INSTALL_DIRECTORY ${SALOME_INSTALL_SCRIPT_SCRIPTS}/test/MEDCoupling/MEDLoader) -INSTALL(TARGETS TestMEDLoader TestSauvLoader DESTINATION ${TEST_INSTALL_DIRECTORY}) - -INSTALL(FILES CTestTestfileInstall.cmake - DESTINATION ${TEST_INSTALL_DIRECTORY} - RENAME CTestTestfile.cmake) diff --git a/src/MEDLoader/Test/CTestTestfileInstall.cmake b/src/MEDLoader/Test/CTestTestfileInstall.cmake deleted file mode 100644 index 4cf399650..000000000 --- a/src/MEDLoader/Test/CTestTestfileInstall.cmake +++ /dev/null @@ -1,24 +0,0 @@ -# Copyright (C) 2015 CEA/DEN, EDF 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, 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 -# 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_TEST(TestMEDLoader TestMEDLoader) -SET_TESTS_PROPERTIES(TestMEDLoader PROPERTIES LABELS "${COMPONENT_NAME}") - -ADD_TEST(TestSauvLoader TestSauvLoader) -SET_TESTS_PROPERTIES(TestSauvLoader PROPERTIES LABELS "${COMPONENT_NAME}") diff --git a/src/MEDLoader/Test/MEDLoaderTest.cxx b/src/MEDLoader/Test/MEDLoaderTest.cxx deleted file mode 100644 index b6267238f..000000000 --- a/src/MEDLoader/Test/MEDLoaderTest.cxx +++ /dev/null @@ -1,1097 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 -// 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 "MEDLoaderTest.hxx" -#include "MEDLoader.hxx" -#include "MEDLoaderBase.hxx" -#include "MEDCouplingUMesh.hxx" -#include "MEDCouplingFieldDouble.hxx" -#include "MEDCouplingMemArray.hxx" - -#include <cmath> - -using namespace ParaMEDMEM; - -void MEDLoaderTest::testMesh1DRW() -{ - MEDCouplingUMesh *mesh=build1DMesh_1(); - mesh->checkCoherency(); - MEDLoader::WriteUMesh("file1.med",mesh,true); - MEDCouplingUMesh *mesh_rw=MEDLoader::ReadUMeshFromFile("file1.med",mesh->getName().c_str(),0); - CPPUNIT_ASSERT(mesh->isEqual(mesh_rw,1e-12)); - mesh_rw->decrRef(); - mesh->decrRef(); -} - -void MEDLoaderTest::testMesh2DCurveRW() -{ - MEDCouplingUMesh *mesh=build2DCurveMesh_1(); - mesh->checkCoherency(); - MEDLoader::WriteUMesh("file2.med",mesh,true); - MEDCouplingUMesh *mesh_rw=MEDLoader::ReadUMeshFromFile("file2.med",mesh->getName().c_str(),0); - CPPUNIT_ASSERT(mesh->isEqual(mesh_rw,1e-12)); - mesh_rw->decrRef(); - mesh->decrRef(); -} - -void MEDLoaderTest::testMesh2DRW() -{ - MEDCouplingUMesh *mesh=build2DMesh_1(); - mesh->checkCoherency(); - MEDLoader::WriteUMesh("file3.med",mesh,true); - MEDCouplingUMesh *mesh_rw=MEDLoader::ReadUMeshFromFile("file3.med",mesh->getName().c_str(),0); - CPPUNIT_ASSERT(mesh->isEqual(mesh_rw,1e-12)); - mesh_rw->decrRef(); - mesh->decrRef(); -} - -void MEDLoaderTest::testMesh3DSurfRW() -{ - MEDCouplingUMesh *mesh=build3DSurfMesh_1(); - mesh->checkCoherency(); - MEDLoader::WriteUMesh("file4.med",mesh,true); - MEDCouplingUMesh *mesh_rw=MEDLoader::ReadUMeshFromFile("file4.med",mesh->getName().c_str(),0); - CPPUNIT_ASSERT(mesh->isEqual(mesh_rw,1e-12)); - mesh_rw->decrRef(); - mesh->decrRef(); -} - -void MEDLoaderTest::testMesh3DRW() -{ - MEDCouplingUMesh *mesh=build3DMesh_1(); - mesh->checkCoherency(); - MEDLoader::WriteUMesh("file5.med",mesh,true); - MEDCouplingUMesh *mesh_rw=MEDLoader::ReadUMeshFromFile("file5.med",mesh->getName().c_str(),0); - CPPUNIT_ASSERT(mesh->isEqual(mesh_rw,1e-12)); - mesh_rw->decrRef(); - mesh->decrRef(); -} - -/*! - * Most basic test : one and only one MEDCoupling field in a new file. - */ -void MEDLoaderTest::testFieldRW1() -{ - MEDCouplingFieldDouble *f1=buildVecFieldOnCells_1(); - MEDLoader::WriteField("file6.med",f1,true); - MEDCouplingFieldDouble *f2=MEDLoader::ReadFieldCell("file6.med",f1->getMesh()->getName().c_str(),0,f1->getName().c_str(),0,1); - CPPUNIT_ASSERT(f1->isEqual(f2,1e-12,1e-12)); - f1->decrRef(); - f2->decrRef(); - // - f1=buildVecFieldOnNodes_1(); - MEDLoader::WriteField("file7.med",f1,true); - f2=MEDLoader::ReadFieldNode("file7.med",f1->getMesh()->getName().c_str(),0,f1->getName().c_str(),2,3); - CPPUNIT_ASSERT(f1->isEqual(f2,1e-12,1e-12)); - // testing kind message on error of field type. - CPPUNIT_ASSERT_THROW(MEDLoader::ReadFieldCell("file7.med",f1->getMesh()->getName().c_str(),0,f1->getName().c_str(),2,3),INTERP_KERNEL::Exception); - // - f1->decrRef(); - f2->decrRef(); -} - -/*! - * Multi field writing in a same file. - */ -void MEDLoaderTest::testFieldRW2() -{ - const char fileName[]="file8.med"; - static const double VAL1=12345.67890314; - static const double VAL2=-1111111111111.; - MEDCouplingFieldDouble *f1=buildVecFieldOnCells_1(); - MEDLoader::WriteField(fileName,f1,true); - f1->setTime(10.,8,9); - double *tmp=f1->getArray()->getPointer(); - tmp[0]=VAL1; - MEDLoader::WriteFieldUsingAlreadyWrittenMesh(fileName,f1); - f1->setTime(10.14,18,19); - tmp[0]=VAL2; - MEDLoader::WriteFieldUsingAlreadyWrittenMesh(fileName,f1); - //retrieving time steps... - MEDCouplingFieldDouble *f2=MEDLoader::ReadFieldCell(fileName,f1->getMesh()->getName().c_str(),0,f1->getName().c_str(),8,9); - f1->setTime(10.,8,9); - tmp[0]=VAL1; - CPPUNIT_ASSERT(f1->isEqual(f2,1e-12,1e-12)); - f2->decrRef(); - f2=MEDLoader::ReadFieldCell(fileName,f1->getMesh()->getName().c_str(),0,f1->getName().c_str(),0,1); - MEDCouplingFieldDouble *f3=buildVecFieldOnCells_1(); - CPPUNIT_ASSERT(f3->isEqual(f2,1e-12,1e-12)); - f3->decrRef(); - f2->decrRef(); - f2=MEDLoader::ReadFieldCell(fileName,f1->getMesh()->getName().c_str(),0,f1->getName().c_str(),18,19); - f1->setTime(10.14,18,19); - tmp[0]=VAL2; - CPPUNIT_ASSERT(f1->isEqual(f2,1e-12,1e-12)); - //test of throw on invalid (dt,it) - CPPUNIT_ASSERT_THROW(MEDLoader::ReadFieldCell(fileName,f1->getMesh()->getName().c_str(),0,f1->getName().c_str(),28,19),INTERP_KERNEL::Exception); - f2->decrRef(); - f1->decrRef(); - //ON NODES - f1=buildVecFieldOnNodes_1(); - const char fileName2[]="file9.med"; - MEDLoader::WriteField(fileName2,f1,true); - f1->setTime(110.,108,109); - tmp=f1->getArray()->getPointer(); - tmp[3]=VAL1; - MEDLoader::WriteFieldUsingAlreadyWrittenMesh(fileName2,f1); - f1->setTime(210.,208,209); - tmp[3]=VAL2; - MEDLoader::WriteFieldUsingAlreadyWrittenMesh(fileName2,f1); - f2=MEDLoader::ReadFieldNode(fileName2,f1->getMesh()->getName().c_str(),0,f1->getName().c_str(),108,109); - f1->setTime(110.,108,109); - tmp[3]=VAL1; - CPPUNIT_ASSERT(f1->isEqual(f2,1e-12,1e-12)); - f2->decrRef(); - f2=MEDLoader::ReadFieldNode(fileName2,f1->getMesh()->getName().c_str(),0,f1->getName().c_str(),2,3); - f3=buildVecFieldOnNodes_1(); - CPPUNIT_ASSERT(f3->isEqual(f2,1e-12,1e-12)); - f3->decrRef(); - f2->decrRef(); - f2=MEDLoader::ReadFieldNode(fileName2,f1->getMesh()->getName().c_str(),0,f1->getName().c_str(),208,209); - f1->setTime(210.,208,209); - tmp[3]=VAL2; - CPPUNIT_ASSERT(f1->isEqual(f2,1e-12,1e-12)); - f2->decrRef(); - f1->decrRef(); -} - -/*! - * Multi field in a same file, but this field has several - */ -void MEDLoaderTest::testFieldRW3() -{ - const char fileName[]="file11.med"; - static const double VAL1=12345.67890314; - static const double VAL2=-1111111111111.; - const char name1[]="AField"; - const char name3[]="AMesh1"; - MEDCouplingFieldDouble *f1=buildVecFieldOnCells_1(); - (const_cast<MEDCouplingMesh *>(f1->getMesh()))->setName(name3); - f1->setName(name1); - f1->setTime(10.,8,9); - double *tmp=f1->getArray()->getPointer(); - tmp[0]=VAL1; - MEDLoader::WriteField(fileName,f1,true); - f1->setTime(10.14,18,19); - tmp[0]=VAL2; - MEDLoader::WriteFieldUsingAlreadyWrittenMesh(fileName,f1); - f1->setTime(10.55,28,29); - tmp[0]=3*VAL1; - MEDLoader::WriteFieldUsingAlreadyWrittenMesh(fileName,f1); - f1->setTime(10.66,38,39); - tmp[0]=3*VAL2; - MEDLoader::WriteFieldUsingAlreadyWrittenMesh(fileName,f1); - f1->setTime(10.77,48,49); - tmp[0]=4*VAL2; - MEDLoader::WriteFieldUsingAlreadyWrittenMesh(fileName,f1); - //ON NODES - f1->decrRef(); - f1=buildVecFieldOnNodes_1(); - f1->setName(name1); - (const_cast<MEDCouplingMesh *>(f1->getMesh()))->setName(name3); - f1->setTime(110.,8,9); - MEDLoader::WriteFieldUsingAlreadyWrittenMesh(fileName,f1); - f1->setTime(110.,108,109); - tmp=f1->getArray()->getPointer(); - tmp[3]=VAL1; - MEDLoader::WriteFieldUsingAlreadyWrittenMesh(fileName,f1); - f1->setTime(210.,208,209); - tmp[3]=VAL2; - MEDLoader::WriteFieldUsingAlreadyWrittenMesh(fileName,f1); - // - std::vector< std::pair<int,int> > it1=MEDLoader::GetCellFieldIterations(fileName,name3,name1); - CPPUNIT_ASSERT_EQUAL(5,(int)it1.size()); - CPPUNIT_ASSERT_EQUAL(8,it1[0].first); CPPUNIT_ASSERT_EQUAL(9,it1[0].second); - CPPUNIT_ASSERT_EQUAL(18,it1[1].first); CPPUNIT_ASSERT_EQUAL(19,it1[1].second); - CPPUNIT_ASSERT_EQUAL(28,it1[2].first); CPPUNIT_ASSERT_EQUAL(29,it1[2].second); - CPPUNIT_ASSERT_EQUAL(38,it1[3].first); CPPUNIT_ASSERT_EQUAL(39,it1[3].second); - CPPUNIT_ASSERT_EQUAL(48,it1[4].first); CPPUNIT_ASSERT_EQUAL(49,it1[4].second); - std::vector< std::pair<int,int> > it3=MEDLoader::GetNodeFieldIterations(fileName,name3,name1); - CPPUNIT_ASSERT_EQUAL(3,(int)it3.size()); - CPPUNIT_ASSERT_EQUAL(8,it3[0].first); CPPUNIT_ASSERT_EQUAL(9,it3[0].second); - CPPUNIT_ASSERT_EQUAL(108,it3[1].first); CPPUNIT_ASSERT_EQUAL(109,it3[1].second); - CPPUNIT_ASSERT_EQUAL(208,it3[2].first); CPPUNIT_ASSERT_EQUAL(209,it3[2].second); - // - f1->decrRef(); - // - f1=MEDLoader::ReadFieldCell(fileName,name3,0,name1,8,9); - CPPUNIT_ASSERT_DOUBLES_EQUAL(VAL1,f1->getArray()->getConstPointer()[0],1e-13); - f1->decrRef(); - f1=MEDLoader::ReadFieldCell(fileName,name3,0,name1,18,19); - CPPUNIT_ASSERT_DOUBLES_EQUAL(VAL2,f1->getArray()->getConstPointer()[0],1e-13); - f1->decrRef(); - f1=MEDLoader::ReadFieldCell(fileName,name3,0,name1,28,29); - CPPUNIT_ASSERT_DOUBLES_EQUAL(3*VAL1,f1->getArray()->getConstPointer()[0],1e-13); - f1->decrRef(); - f1=MEDLoader::ReadFieldCell(fileName,name3,0,name1,38,39); - CPPUNIT_ASSERT_DOUBLES_EQUAL(3*VAL2,f1->getArray()->getConstPointer()[0],1e-13); - f1->decrRef(); - f1=MEDLoader::ReadFieldCell(fileName,name3,0,name1,48,49); - CPPUNIT_ASSERT_DOUBLES_EQUAL(4*VAL2,f1->getArray()->getConstPointer()[0],1e-13); - f1->decrRef(); - // - f1=MEDLoader::ReadFieldNode(fileName,name3,0,name1,8,9); - CPPUNIT_ASSERT_DOUBLES_EQUAL(71.,f1->getArray()->getConstPointer()[3],1e-13); - f1->decrRef(); - f1=MEDLoader::ReadFieldNode(fileName,name3,0,name1,108,109); - CPPUNIT_ASSERT_DOUBLES_EQUAL(VAL1,f1->getArray()->getConstPointer()[3],1e-13); - f1->decrRef(); - f1=MEDLoader::ReadFieldNode(fileName,name3,0,name1,208,209); - CPPUNIT_ASSERT_DOUBLES_EQUAL(VAL2,f1->getArray()->getConstPointer()[3],1e-13); - f1->decrRef(); -} - -void MEDLoaderTest::testMultiMeshRW1() -{ - const char fileName[]="file10.med"; - MEDCouplingUMesh *mesh1=build3DMesh_1(); - const int part1[5]={1,2,4,13,15}; - MEDCouplingUMesh *mesh2=(MEDCouplingUMesh *)mesh1->buildPartOfMySelf(part1,part1+5,true); - mesh2->setName("mesh2"); - const int part2[4]={3,4,13,14}; - MEDCouplingUMesh *mesh3=(MEDCouplingUMesh *)mesh1->buildPartOfMySelf(part2,part2+4,true); - mesh3->setName("mesh3"); - MEDCouplingUMesh *mesh4=MEDCouplingUMesh::New(); - mesh4->setName("mesh4"); - mesh4->setMeshDimension(3); - mesh4->allocateCells(1); - int conn[4]={0,11,1,3}; - mesh4->insertNextCell(INTERP_KERNEL::NORM_TETRA4,4,conn); - mesh4->finishInsertingCells(); - mesh4->setCoords(mesh1->getCoords()); - std::vector<const MEDCouplingUMesh *> meshes; - meshes.push_back(mesh1); - meshes.push_back(mesh2); - meshes.push_back(mesh3); - meshes.push_back(mesh4); - const char mnane[]="3DToto"; - MEDLoader::WriteUMeshesPartition(fileName,mnane,meshes,true); - // - MEDCouplingUMesh *mesh5=MEDLoader::ReadUMeshFromFile(fileName,mnane); - mesh1->setName(mnane); - const int part3[18]={0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17}; - MEDCouplingUMesh *mesh6=(MEDCouplingUMesh *)mesh5->buildPartOfMySelf(part3,part3+18,true); - mesh6->setName(mnane); - mesh5->decrRef(); - CPPUNIT_ASSERT(mesh6->isEqual(mesh1,1e-12)); - mesh6->decrRef(); - std::vector<std::string> grps=MEDLoader::GetMeshGroupsNames(fileName,mnane); - CPPUNIT_ASSERT_EQUAL(4,(int)grps.size()); - CPPUNIT_ASSERT(std::find(grps.begin(),grps.end(),std::string("mesh2"))!=grps.end()); - CPPUNIT_ASSERT(std::find(grps.begin(),grps.end(),std::string("mesh3"))!=grps.end()); - CPPUNIT_ASSERT(std::find(grps.begin(),grps.end(),std::string("mesh4"))!=grps.end()); - CPPUNIT_ASSERT(std::find(grps.begin(),grps.end(),std::string("3DMesh_1"))!=grps.end()); - // - std::vector<std::string> vec; - vec.push_back(std::string("mesh2")); - MEDCouplingUMesh *mesh2_2=MEDLoader::ReadUMeshFromGroups(fileName,mnane,0,vec); - CPPUNIT_ASSERT(mesh2_2->isEqual(mesh2,1e-12)); - mesh2_2->decrRef(); - vec.clear(); vec.push_back(std::string("mesh3")); - MEDCouplingUMesh *mesh3_2=MEDLoader::ReadUMeshFromGroups(fileName,mnane,0,vec); - CPPUNIT_ASSERT(mesh3_2->isEqual(mesh3,1e-12)); - mesh3_2->decrRef(); - vec.clear(); vec.push_back(std::string("mesh4")); - MEDCouplingUMesh *mesh4_2=MEDLoader::ReadUMeshFromGroups(fileName,mnane,0,vec); - CPPUNIT_ASSERT(mesh4_2->isEqual(mesh4,1e-12)); - mesh4_2->decrRef(); - vec.clear(); vec.push_back(std::string("3DMesh_1")); - MEDCouplingUMesh *mesh1_2=MEDLoader::ReadUMeshFromGroups(fileName,mnane,0,vec); - mesh1->setName("3DMesh_1"); - CPPUNIT_ASSERT(mesh1_2->isEqual(mesh1,1e-12)); - mesh1_2->decrRef(); - // - vec.clear(); vec.push_back(std::string("Family_-3")); vec.push_back(std::string("Family_-5")); - mesh2_2=MEDLoader::ReadUMeshFromFamilies(fileName,mnane,0,vec); - mesh2_2->setName("mesh2"); - CPPUNIT_ASSERT(mesh2_2->isEqual(mesh2,1e-12)); - mesh2_2->decrRef(); - // - std::vector<std::string> ret=MEDLoader::GetMeshFamiliesNamesOnGroup(fileName,"3DToto","3DMesh_1"); - CPPUNIT_ASSERT_EQUAL(4,(int)ret.size()); - CPPUNIT_ASSERT(ret[0]=="Family_-2"); - CPPUNIT_ASSERT(ret[1]=="Family_-3"); - CPPUNIT_ASSERT(ret[2]=="Family_-4"); - CPPUNIT_ASSERT(ret[3]=="Family_-5"); - // - std::vector<std::string> ret1=MEDLoader::GetMeshGroupsNamesOnFamily(fileName,"3DToto","Family_-3"); - CPPUNIT_ASSERT_EQUAL(2,(int)ret1.size()); - CPPUNIT_ASSERT(ret1[0]=="3DMesh_1"); - CPPUNIT_ASSERT(ret1[1]=="mesh2"); - // - mesh4->decrRef(); - mesh3->decrRef(); - mesh2->decrRef(); - mesh1->decrRef(); -} - -void MEDLoaderTest::testFieldProfilRW1() -{ - const char fileName[]="file12.med"; - MEDCouplingUMesh *mesh1=build3DMesh_1(); - bool b; - int newNbOfNodes; - DataArrayInt *da=mesh1->mergeNodes(1e-12,b,newNbOfNodes); - da->decrRef(); - MEDLoader::WriteUMesh(fileName,mesh1,true); - const int part1[5]={1,2,4,13,15}; - MEDCouplingUMesh *mesh2=(MEDCouplingUMesh *)mesh1->buildPartOfMySelf(part1,part1+5,true); - mesh2->setName(mesh1->getName().c_str());//<- important for the test - // - int nbOfCells=mesh2->getNumberOfCells(); - CPPUNIT_ASSERT_EQUAL(5,nbOfCells); - MEDCouplingFieldDouble *f1=MEDCouplingFieldDouble::New(ON_CELLS,ONE_TIME); - f1->setName("VectorFieldOnCells"); - f1->setMesh(mesh2); - DataArrayDouble *array=DataArrayDouble::New(); - array->alloc(nbOfCells,2); - f1->setArray(array); - array->decrRef(); - double *tmp=array->getPointer(); - const double arr1[10]={71.,171.,10.,110.,20.,120.,30.,130.,40.,140.}; - std::copy(arr1,arr1+10,tmp); - f1->setTime(3.14,2,7); - f1->checkCoherency(); - // - MEDLoader::WriteField(fileName,f1,false);//<- false important for the test - // - MEDCouplingFieldDouble *f2=MEDLoader::ReadFieldCell(fileName,f1->getMesh()->getName().c_str(),0,f1->getName().c_str(),2,7); - std::vector<ParaMEDMEM::TypeOfField> types=MEDLoader::GetTypesOfField(fileName,f1->getMesh()->getName().c_str(),f1->getName().c_str()); - CPPUNIT_ASSERT_EQUAL(1,(int)types.size()); - CPPUNIT_ASSERT(types[0]==ON_CELLS); - f2->checkCoherency(); - CPPUNIT_ASSERT(f1->isEqual(f2,1e-12,1e-12)); - // - f2->decrRef(); - f1->decrRef(); - mesh1->decrRef(); - mesh2->decrRef(); -} - -/*! - * Test MED file profiles. - */ -void MEDLoaderTest::testFieldNodeProfilRW1() -{ - const char fileName[]="file19.med"; - const char fileName2[]="file20.med"; - MEDCouplingUMesh *m=build2DMesh_1(); - int nbOfNodes=m->getNumberOfNodes(); - MEDLoader::WriteUMesh(fileName,m,true); - MEDCouplingFieldDouble *f1=MEDCouplingFieldDouble::New(ON_NODES,ONE_TIME); - f1->setName("VFieldOnNodes"); - f1->setMesh(m); - DataArrayDouble *array=DataArrayDouble::New(); - const double arr1[24]={1.,101.,2.,102.,3.,103.,4.,104.,5.,105.,6.,106.,7.,107.,8.,108.,9.,109.,10.,110.,11.,111.,12.,112.}; - array->alloc(nbOfNodes,2); - std::copy(arr1,arr1+24,array->getPointer()); - f1->setArray(array); - array->setInfoOnComponent(0,"tyty [mm]"); - array->setInfoOnComponent(1,"uiop [MW]"); - array->decrRef(); - f1->setTime(3.14,2,7); - f1->checkCoherency(); - const int arr2[2]={1,4};//node ids are 2,4,5,3,6,7 - MEDCouplingFieldDouble *f2=f1->buildSubPart(arr2,arr2+2); - (const_cast<MEDCouplingMesh *>(f2->getMesh()))->setName(f1->getMesh()->getName().c_str()); - MEDLoader::WriteField(fileName,f2,false);//<- false important for the test - // - MEDCouplingFieldDouble *f3=MEDLoader::ReadFieldNode(fileName,f2->getMesh()->getName().c_str(),0,f2->getName().c_str(),2,7); - f3->checkCoherency(); - CPPUNIT_ASSERT(f3->isEqual(f2,1e-12,1e-12)); - f3->decrRef(); - // - const int arr3[6]={1,3,0,5,2,4}; - f2->renumberNodes(arr3); - MEDLoader::WriteUMesh(fileName2,m,true); - MEDLoader::WriteField(fileName2,f2,false);//<- false important for the test - f3=MEDLoader::ReadFieldNode(fileName2,f2->getMesh()->getName().c_str(),0,f2->getName().c_str(),2,7); - f3->checkCoherency(); - CPPUNIT_ASSERT(f3->isEqual(f2,1e-12,1e-12)); - f3->decrRef(); - f2->decrRef(); - // - f1->decrRef(); - m->decrRef(); -} - -void MEDLoaderTest::testFieldNodeProfilRW2() -{ - const char fileName[]="file23.med"; - MEDCouplingUMesh *mesh=build3DSurfMesh_1(); - MEDLoader::WriteUMesh(fileName,mesh,true); - // - MEDCouplingFieldDouble *f1=MEDCouplingFieldDouble::New(ON_NODES,ONE_TIME); - f1->setName("FieldMix"); - f1->setMesh(mesh); - const double arr2[24]={ - 1071.,1171.,1010.,1110.,1020.,1120.,1030.,1130.,1040.,1140.,1050.,1150., - 1060.,1160.,1070.,1170.,1080.,1180.,1090.,1190.,1091.,1191.,1092.,1192. - }; - DataArrayDouble *array=DataArrayDouble::New(); - array->alloc(12,2); - f1->setArray(array); - array->setInfoOnComponent(0,"plkj [mm]"); - array->setInfoOnComponent(1,"pqqqss [mm]"); - array->decrRef(); - double *tmp=array->getPointer(); - std::copy(arr2,arr2+24,tmp); - f1->setTime(3.17,2,7); - // - const int renumArr[12]={3,7,2,1,5,11,10,0,9,6,8,4}; - f1->renumberNodes(renumArr); - f1->checkCoherency(); - MEDLoader::WriteField(fileName,f1,false);//<- false important for the test - MEDCouplingFieldDouble *f2=MEDLoader::ReadFieldNode(fileName,f1->getMesh()->getName().c_str(),0,f1->getName().c_str(),2,7); - CPPUNIT_ASSERT(f2->isEqual(f1,1e-12,1e-12)); - // - f2->decrRef(); - mesh->decrRef(); - f1->decrRef(); -} - -void MEDLoaderTest::testFieldGaussRW1() -{ - const char fileName[]="file13.med"; - MEDCouplingFieldDouble *f1=buildVecFieldOnGauss_1(); - MEDLoader::WriteField(fileName,f1,true); - MEDCouplingFieldDouble *f2=MEDLoader::ReadField(ON_GAUSS_PT,fileName,f1->getMesh()->getName().c_str(),0,f1->getName().c_str(),1,5); - CPPUNIT_ASSERT(f1->isEqual(f2,1e-12,1e-12)); - f2->decrRef(); - f1->decrRef(); -} - -void MEDLoaderTest::testFieldGaussNERW1() -{ - const char fileName[]="file14.med"; - MEDCouplingFieldDouble *f1=buildVecFieldOnGaussNE_1(); - MEDLoader::WriteField(fileName,f1,true); - std::vector<ParaMEDMEM::TypeOfField> tof(MEDLoader::GetTypesOfField(fileName,"2DMesh_2","MyFieldOnGaussNE")); - CPPUNIT_ASSERT_EQUAL(1,(int)tof.size()); - CPPUNIT_ASSERT(ON_GAUSS_NE==tof[0]); - MEDCouplingFieldDouble *f2=MEDLoader::ReadField(ON_GAUSS_NE,fileName,f1->getMesh()->getName().c_str(),0,f1->getName().c_str(),1,5); - CPPUNIT_ASSERT(f1->isEqual(f2,1e-12,1e-12)); - f2->decrRef(); - f1->decrRef(); -} - -void MEDLoaderTest::testLittleStrings1() -{ - std::string s("azeeeerrrtty"); - MEDLoaderBase::zipEqualConsChar(s,3); - CPPUNIT_ASSERT(s=="azertty"); -} - -void MEDLoaderTest::testSplitIntoNameAndUnit1() -{ - std::string s(" []"); - std::string c,u; - MEDLoaderBase::splitIntoNameAndUnit(s,c,u); - CPPUNIT_ASSERT(c.empty()); - CPPUNIT_ASSERT(u.empty()); - s=" lmmm kki jjj "; - MEDLoaderBase::strip(s); - CPPUNIT_ASSERT(s=="lmmm kki jjj"); - s=" "; - MEDLoaderBase::strip(s); - CPPUNIT_ASSERT(s.empty()); - s=""; - MEDLoaderBase::strip(s); - CPPUNIT_ASSERT(s.empty()); - s=" "; - MEDLoaderBase::strip(s); - CPPUNIT_ASSERT(s.empty()); - s=" pp"; - MEDLoaderBase::strip(s); - CPPUNIT_ASSERT(s=="pp"); -} - -void MEDLoaderTest::testMesh3DSurfShuffleRW() -{ - const char fileName[]="file15.med"; - MEDCouplingUMesh *mesh=build3DSurfMesh_1(); - const int renumber1[6]={2,5,1,0,3,4}; - mesh->renumberCells(renumber1,false); - mesh->checkCoherency(); - MEDLoader::WriteUMesh(fileName,mesh,true); - MEDCouplingUMesh *mesh_rw=MEDLoader::ReadUMeshFromFile(fileName,mesh->getName().c_str(),0); - CPPUNIT_ASSERT(mesh->isEqual(mesh_rw,1e-12)); - mesh_rw->decrRef(); - mesh->decrRef(); -} - -void MEDLoaderTest::testFieldShuffleRW1() -{ - const char fileName[]="file16.med"; - MEDCouplingUMesh *mesh=build3DSurfMesh_1(); - MEDCouplingFieldDouble *f1=MEDCouplingFieldDouble::New(ON_CELLS,ONE_TIME); - f1->setName("FieldOnCellsShuffle"); - f1->setMesh(mesh); - DataArrayDouble *array=DataArrayDouble::New(); - array->alloc(6,2); - f1->setArray(array); - array->decrRef(); - double *tmp=array->getPointer(); - const double arr1[12]={71.,171.,10.,110.,20.,120.,30.,130.,40.,140.,50.,150.}; - std::copy(arr1,arr1+12,tmp); - f1->setTime(3.14,2,7); - f1->checkCoherency(); - // - const int renumber1[6]={2,1,5,0,3,4}; - f1->renumberCells(renumber1,false); - MEDLoader::WriteField(fileName,f1,true); - MEDCouplingFieldDouble *f2=MEDLoader::ReadFieldCell(fileName,mesh->getName().c_str(),0,f1->getName().c_str(),2,7); - CPPUNIT_ASSERT(f2->isEqual(f1,1e-12,1e-12)); - f2->decrRef(); - // - mesh->decrRef(); - f1->decrRef(); -} - -/*! - * Shuffle de cells but no profile. Like pointe.med - */ -void MEDLoaderTest::testMultiFieldShuffleRW1() -{ - const char fileName[]="file17.med"; - MEDCouplingUMesh *m=build3DMesh_2(); - CPPUNIT_ASSERT_EQUAL(20,m->getNumberOfCells()); - CPPUNIT_ASSERT_EQUAL(45,m->getNumberOfNodes()); - const int polys[3]={1,4,6}; - std::vector<int> poly2(polys,polys+3); - m->convertToPolyTypes(&poly2[0],&poly2[0]+poly2.size()); - const int renum[20]={1,3,2,8,9,12,13,16,19,0,4,7,5,15,14,17,10,18,6,11}; - m->renumberCells(renum,false); - m->orientCorrectlyPolyhedrons(); - // Writing - MEDLoader::WriteUMesh(fileName,m,true); - MEDCouplingFieldDouble *f1Tmp=m->getMeasureField(false); - MEDCouplingFieldDouble *f1=f1Tmp->buildNewTimeReprFromThis(ONE_TIME,false); - f1Tmp->decrRef(); - f1->setTime(0.,1,2); - MEDCouplingFieldDouble *f_1=f1->cloneWithMesh(true); - MEDLoader::WriteFieldUsingAlreadyWrittenMesh(fileName,f1); - f1->applyFunc("2*x"); - f1->setTime(0.01,3,4); - MEDCouplingFieldDouble *f_2=f1->cloneWithMesh(true); - MEDLoader::WriteFieldUsingAlreadyWrittenMesh(fileName,f1); - f1->applyFunc("2*x/3"); - f1->setTime(0.02,5,6); - MEDCouplingFieldDouble *f_3=f1->cloneWithMesh(true); - MEDLoader::WriteFieldUsingAlreadyWrittenMesh(fileName,f1); - f1->decrRef(); - // Reading - std::vector<std::pair<int,int> > its; - its.push_back(std::pair<int,int>(1,2)); - its.push_back(std::pair<int,int>(3,4)); - its.push_back(std::pair<int,int>(5,6)); - std::vector<MEDCouplingFieldDouble *> fs=MEDLoader::ReadFieldsOnSameMesh(ON_CELLS,fileName,f_1->getMesh()->getName().c_str(),0,f_1->getName().c_str(),its); - CPPUNIT_ASSERT_EQUAL(3,(int)fs.size()); - const MEDCouplingMesh *mm=fs[0]->getMesh(); - CPPUNIT_ASSERT(fs[0]->isEqual(f_1,1e-12,1e-12)); - CPPUNIT_ASSERT(fs[1]->isEqual(f_2,1e-12,1e-12)); - CPPUNIT_ASSERT(fs[2]->isEqual(f_3,1e-12,1e-12)); - CPPUNIT_ASSERT(mm==fs[1]->getMesh());// <- important for the test - CPPUNIT_ASSERT(mm==fs[2]->getMesh());// <- important for the test - for(std::vector<MEDCouplingFieldDouble *>::iterator iter=fs.begin();iter!=fs.end();iter++) - (*iter)->decrRef(); - // - f_1->decrRef(); - f_2->decrRef(); - f_3->decrRef(); - // - m->decrRef(); -} - -void MEDLoaderTest::testWriteUMeshesRW1() -{ - const char fileName[]="file18.med"; - MEDCouplingUMesh *m3d=build3DMesh_2(); - const double pt[3]={0.,0.,-0.3}; - const double vec[3]={0.,0.,1.}; - std::vector<int> nodes; - m3d->findNodesOnPlane(pt,vec,1e-12,nodes); - MEDCouplingUMesh *m2d=(MEDCouplingUMesh *)m3d->buildFacePartOfMySelfNode(&nodes[0],&nodes[0]+nodes.size(),true); - const int renumber[5]={1,2,0,4,3}; - m2d->renumberCells(renumber,false); - m2d->setName("ExampleOfMultiDimW"); - std::vector<const MEDCouplingUMesh *> meshes; - meshes.push_back(m2d); - meshes.push_back(m3d); - MEDLoader::WriteUMeshes(fileName,meshes,true); - MEDCouplingUMesh *m3d_bis=MEDLoader::ReadUMeshFromFile(fileName,m2d->getName().c_str(),0); - CPPUNIT_ASSERT(!m3d_bis->isEqual(m3d,1e-12)); - m3d_bis->setName(m3d->getName().c_str()); - CPPUNIT_ASSERT(m3d_bis->isEqual(m3d,1e-12)); - MEDCouplingUMesh *m2d_bis=MEDLoader::ReadUMeshFromFile(fileName,m2d->getName().c_str(),-1);//-1 for faces - CPPUNIT_ASSERT(m2d_bis->isEqual(m2d,1e-12)); - // Creation of a field on faces. - MEDCouplingFieldDouble *f1=MEDCouplingFieldDouble::New(ON_CELLS,ONE_TIME); - f1->setName("FieldOnFacesShuffle"); - f1->setMesh(m2d); - DataArrayDouble *array=DataArrayDouble::New(); - array->alloc(m2d->getNumberOfCells(),2); - array->setInfoOnComponent(0,"plkj [mm]"); - array->setInfoOnComponent(1,"pqqqss [mm]"); - f1->setArray(array); - array->decrRef(); - double *tmp=array->getPointer(); - const double arr1[10]={71.,171.,10.,110.,20.,120.,30.,130.,40.,140.}; - std::copy(arr1,arr1+10,tmp); - f1->setTime(3.14,2,7); - f1->checkCoherency(); - MEDLoader::WriteFieldUsingAlreadyWrittenMesh(fileName,f1); - MEDCouplingFieldDouble *f2=MEDLoader::ReadFieldCell(fileName,f1->getMesh()->getName().c_str(),-1,f1->getName().c_str(),2,7); - CPPUNIT_ASSERT(f2->isEqual(f1,1e-12,1e-12)); - f1->decrRef(); - f2->decrRef(); - // - m2d_bis->decrRef(); - m3d_bis->decrRef(); - m2d->decrRef(); - m3d->decrRef(); -} - -void MEDLoaderTest::testMixCellAndNodesFieldRW1() -{ - const char fileName[]="file21.med"; - MEDCouplingUMesh *mesh=build3DSurfMesh_1(); - MEDCouplingFieldDouble *f1=MEDCouplingFieldDouble::New(ON_CELLS,ONE_TIME); - f1->setName("FieldMix"); - f1->setMesh(mesh); - DataArrayDouble *array=DataArrayDouble::New(); - array->alloc(6,2); - f1->setArray(array); - array->setInfoOnComponent(0,"plkj [mm]"); - array->setInfoOnComponent(1,"pqqqss [mm]"); - array->decrRef(); - double *tmp=array->getPointer(); - const double arr1[12]={71.,171.,10.,110.,20.,120.,30.,130.,40.,140.,50.,150.}; - std::copy(arr1,arr1+12,tmp); - f1->setTime(3.14,2,7); - f1->checkCoherency(); - // - MEDCouplingFieldDouble *f2=MEDCouplingFieldDouble::New(ON_NODES,ONE_TIME); - f2->setName("FieldMix"); - f2->setMesh(mesh); - array=DataArrayDouble::New(); - array->alloc(12,2); - f2->setArray(array); - array->setInfoOnComponent(0,"plkj [mm]"); - array->setInfoOnComponent(1,"pqqqss [mm]"); - array->decrRef(); - tmp=array->getPointer(); - const double arr2[24]={ - 1071.,1171.,1010.,1110.,1020.,1120.,1030.,1130.,1040.,1140.,1050.,1150., - 1060.,1160.,1070.,1170.,1080.,1180.,1090.,1190.,1091.,1191.,1092.,1192. - }; - std::copy(arr2,arr2+24,tmp); - f2->setTime(3.14,2,7); - f2->checkCoherency(); - // - MEDLoader::WriteField(fileName,f1,true); - std::vector<ParaMEDMEM::TypeOfField> ts=MEDLoader::GetTypesOfField(fileName,f1->getMesh()->getName().c_str(),f1->getName().c_str()); - CPPUNIT_ASSERT_EQUAL(1,(int)ts.size()); - CPPUNIT_ASSERT_EQUAL(ON_CELLS,ts[0]); - std::vector<std::string> fs=MEDLoader::GetAllFieldNamesOnMesh(fileName,f1->getMesh()->getName().c_str()); - CPPUNIT_ASSERT_EQUAL(1,(int)fs.size()); - CPPUNIT_ASSERT(fs[0]=="FieldMix"); - MEDLoader::WriteFieldUsingAlreadyWrittenMesh(fileName,f2); - fs=MEDLoader::GetAllFieldNamesOnMesh(fileName,f1->getMesh()->getName().c_str()); - CPPUNIT_ASSERT_EQUAL(1,(int)fs.size()); - CPPUNIT_ASSERT(fs[0]=="FieldMix"); - // - ts=MEDLoader::GetTypesOfField(fileName,f1->getMesh()->getName().c_str(),f1->getName().c_str()); - CPPUNIT_ASSERT_EQUAL(2,(int)ts.size()); - CPPUNIT_ASSERT_EQUAL(ON_NODES,ts[0]); - CPPUNIT_ASSERT_EQUAL(ON_CELLS,ts[1]); - // - MEDCouplingFieldDouble *f3=MEDLoader::ReadFieldNode(fileName,f1->getMesh()->getName().c_str(),0,f1->getName().c_str(),2,7); - CPPUNIT_ASSERT(f3->isEqual(f2,1e-12,1e-12)); - f3->decrRef(); - f3=MEDLoader::ReadFieldCell(fileName,f1->getMesh()->getName().c_str(),0,f1->getName().c_str(),2,7); - CPPUNIT_ASSERT(f3->isEqual(f1,1e-12,1e-12)); - f3->decrRef(); - // - f1->decrRef(); - f2->decrRef(); - mesh->decrRef(); -} - -void MEDLoaderTest::testGetAllFieldNamesRW1() -{ - const char fileName[]="file22.med"; - MEDCouplingUMesh *mesh=build2DMesh_2(); - MEDCouplingFieldDouble *f1=MEDCouplingFieldDouble::New(ON_NODES,ONE_TIME); - f1->setName("Field1"); - f1->setTime(3.44,5,6); - f1->setMesh(mesh); - f1->fillFromAnalytic(2,"x+y"); - MEDLoader::WriteField(fileName,f1,true); - f1->setTime(1002.3,7,8); - f1->fillFromAnalytic(2,"x+77.*y"); - MEDLoader::WriteFieldUsingAlreadyWrittenMesh(fileName,f1); - f1->setName("Field2"); - MEDLoader::WriteField(fileName,f1,false); - f1->setName("Field3"); - mesh->setName("2DMesh_2Bis"); - MEDLoader::WriteField(fileName,f1,false); - f1->decrRef(); - f1=MEDCouplingFieldDouble::New(ON_CELLS,ONE_TIME); - f1->setName("Field8"); - f1->setTime(8.99,7,9); - f1->setMesh(mesh); - f1->fillFromAnalytic(3,"3*x+y"); - MEDLoader::WriteField(fileName,f1,false); - f1->decrRef(); - std::vector<std::string> fs=MEDLoader::GetAllFieldNames(fileName); - CPPUNIT_ASSERT_EQUAL(4,(int)fs.size()); - CPPUNIT_ASSERT(fs[0]=="Field1"); - CPPUNIT_ASSERT(fs[1]=="Field2"); - CPPUNIT_ASSERT(fs[2]=="Field3"); - CPPUNIT_ASSERT(fs[3]=="Field8"); - mesh->decrRef(); -} - -MEDCouplingUMesh *MEDLoaderTest::build1DMesh_1() -{ - double coords[6]={ 0.0, 0.3, 0.75, 1.0, 1.4, 1.3 }; - int conn[9]={ 0,1, 1,2, 2,3 , 3,4,5}; - MEDCouplingUMesh *mesh=MEDCouplingUMesh::New(); - mesh->setName("1DMesh_1"); - mesh->setMeshDimension(1); - mesh->allocateCells(4); - mesh->insertNextCell(INTERP_KERNEL::NORM_SEG2,2,conn); - mesh->insertNextCell(INTERP_KERNEL::NORM_SEG2,2,conn+2); - mesh->insertNextCell(INTERP_KERNEL::NORM_SEG2,2,conn+4); - mesh->insertNextCell(INTERP_KERNEL::NORM_SEG3,3,conn+6); - mesh->finishInsertingCells(); - DataArrayDouble *myCoords=DataArrayDouble::New(); - myCoords->alloc(6,1); - myCoords->setInfoOnComponent(0,"tototototototot [m*m*m*m*m*m*m*m]"); - std::copy(coords,coords+6,myCoords->getPointer()); - mesh->setCoords(myCoords); - myCoords->decrRef(); - return mesh; -} - -MEDCouplingUMesh *MEDLoaderTest::build2DCurveMesh_1() -{ - double coords[12]={ 0.0,0.0, 0.3,0.3, 0.75,0.75, 1.0,1.0, 1.4,1.4, 1.3,1.3 }; - int conn[9]={ 0,1, 1,2, 2,3 , 3,4,5}; - MEDCouplingUMesh *mesh=MEDCouplingUMesh::New(); - mesh->setName("2DCurveMesh_1"); - mesh->setMeshDimension(1); - mesh->allocateCells(4); - mesh->insertNextCell(INTERP_KERNEL::NORM_SEG2,2,conn); - mesh->insertNextCell(INTERP_KERNEL::NORM_SEG2,2,conn+2); - mesh->insertNextCell(INTERP_KERNEL::NORM_SEG2,2,conn+4); - mesh->insertNextCell(INTERP_KERNEL::NORM_SEG3,3,conn+6); - mesh->finishInsertingCells(); - DataArrayDouble *myCoords=DataArrayDouble::New(); - myCoords->alloc(6,2); - std::copy(coords,coords+12,myCoords->getPointer()); - mesh->setCoords(myCoords); - myCoords->decrRef(); - return mesh; -} - -MEDCouplingUMesh *MEDLoaderTest::build2DMesh_1() -{ - double targetCoords[24]={-0.3,-0.3, 0.2,-0.3, 0.7,-0.3, -0.3,0.2, 0.2,0.2, 0.7,0.2, -0.3,0.7, 0.2,0.7, 0.7,0.7, -0.05,0.95, 0.2,1.2, 0.45,0.95 }; - int targetConn[24]={1,4,2, 4,5,2, 6,10,8,9,11,7, 0,3,4,1, 6,7,4,3, 7,8,5,4}; - MEDCouplingUMesh *targetMesh=MEDCouplingUMesh::New(); - targetMesh->setMeshDimension(2); - targetMesh->allocateCells(6); - targetMesh->setName("2DMesh_1"); - targetMesh->insertNextCell(INTERP_KERNEL::NORM_TRI3,3,targetConn); - targetMesh->insertNextCell(INTERP_KERNEL::NORM_TRI3,3,targetConn+3); - targetMesh->insertNextCell(INTERP_KERNEL::NORM_TRI6,6,targetConn+6); - targetMesh->insertNextCell(INTERP_KERNEL::NORM_QUAD4,4,targetConn+12); - targetMesh->insertNextCell(INTERP_KERNEL::NORM_QUAD4,4,targetConn+16); - targetMesh->insertNextCell(INTERP_KERNEL::NORM_POLYGON,4,targetConn+20); - targetMesh->finishInsertingCells(); - DataArrayDouble *myCoords=DataArrayDouble::New(); - myCoords->alloc(12,2); - myCoords->setInfoOnComponent(0,"tototototototot [m]"); - myCoords->setInfoOnComponent(1,"energie [kW]"); - std::copy(targetCoords,targetCoords+24,myCoords->getPointer()); - targetMesh->setCoords(myCoords); - myCoords->decrRef(); - return targetMesh; -} - -MEDCouplingUMesh *MEDLoaderTest::build2DMesh_2() -{ - double targetCoords[24]={ - -0.3,-0.3, 0.2,-0.3, 0.7,-0.3, -0.3,0.2, 0.2,0.2, 0.7,0.2, -0.3,0.7, 0.2,0.7, 0.7,0.7, - -0.05,0.95, 0.2,1.2, 0.45,0.95 - }; - int targetConn[24]={1,4,2, 4,5,2, 6,10,8,9,11,7, 0,3,4,1, 6,7,4,3, 7,8,5,4}; - MEDCouplingUMesh *targetMesh=MEDCouplingUMesh::New(); - targetMesh->setMeshDimension(2); - targetMesh->allocateCells(5); - targetMesh->setName("2DMesh_2"); - targetMesh->insertNextCell(INTERP_KERNEL::NORM_TRI3,3,targetConn); - targetMesh->insertNextCell(INTERP_KERNEL::NORM_TRI3,3,targetConn+3); - targetMesh->insertNextCell(INTERP_KERNEL::NORM_QUAD4,4,targetConn+12); - targetMesh->insertNextCell(INTERP_KERNEL::NORM_QUAD4,4,targetConn+16); - targetMesh->insertNextCell(INTERP_KERNEL::NORM_TRI6,6,targetConn+6); - targetMesh->finishInsertingCells(); - DataArrayDouble *myCoords=DataArrayDouble::New(); - myCoords->alloc(12,2); - myCoords->setInfoOnComponent(0,"toto [m]"); - myCoords->setInfoOnComponent(1,"energie [kW]"); - std::copy(targetCoords,targetCoords+24,myCoords->getPointer()); - targetMesh->setCoords(myCoords); - myCoords->decrRef(); - return targetMesh; -} - -MEDCouplingUMesh *MEDLoaderTest::build3DSurfMesh_1() -{ - double targetCoords[36]={ - -0.3,-0.3,-0.3, 0.2,-0.3,-0.3, 0.7,-0.3,-0.3, -0.3,0.2,-0.3, 0.2,0.2,-0.3, 0.7,0.2,-0.3, -0.3,0.7,-0.3, 0.2,0.7,-0.3, 0.7,0.7,-0.3 - ,-0.05,0.95,-0.3, 0.2,1.2,-0.3, 0.45,0.95,-0.3 - }; - int targetConn[24]={1,4,2, 4,5,2, 6,10,8,9,11,7, 0,3,4,1, 6,7,4,3, 7,8,5,4}; - MEDCouplingUMesh *targetMesh=MEDCouplingUMesh::New(); - targetMesh->setMeshDimension(2); - targetMesh->allocateCells(6); - targetMesh->setName("3DSurfMesh_1"); - targetMesh->insertNextCell(INTERP_KERNEL::NORM_TRI3,3,targetConn); - targetMesh->insertNextCell(INTERP_KERNEL::NORM_TRI3,3,targetConn+3); - targetMesh->insertNextCell(INTERP_KERNEL::NORM_QUAD4,4,targetConn+12); - targetMesh->insertNextCell(INTERP_KERNEL::NORM_QUAD4,4,targetConn+16); - targetMesh->insertNextCell(INTERP_KERNEL::NORM_TRI6,6,targetConn+6); - targetMesh->insertNextCell(INTERP_KERNEL::NORM_POLYGON,4,targetConn+20); - targetMesh->finishInsertingCells(); - DataArrayDouble *myCoords=DataArrayDouble::New(); - myCoords->alloc(12,3); - myCoords->setInfoOnComponent(0,"toto [m]"); - myCoords->setInfoOnComponent(2,"ff [km]");//component 1 is not set for test - std::copy(targetCoords,targetCoords+36,myCoords->getPointer()); - targetMesh->setCoords(myCoords); - myCoords->decrRef(); - return targetMesh; -} - -MEDCouplingUMesh *MEDLoaderTest::build3DMesh_1() -{ - double coords[180]={ - 0.,0.,0., 1.,1.,0., 1.,1.25,0., 0.,1.,0., 1.,1.5,0., 2.,0.,0., 2.,1.,0., 1.,2.,0., 0.,2.,0., 3.,1.,0., - 3.,2.,0., 0.,1.,0., 1.,3.,0., 2.,2.,0., 2.,3.,0., - 0.,0.,1., 1.,1.,1., 1.,1.25,1., 0.,1.,1., 1.,1.5,1., 2.,0.,1., 2.,1.,1., 1.,2.,1., 0.,2.,1., 3.,1.,1., - 3.,2.,1., 0.,1.,1., 1.,3.,1., 2.,2.,1., 2.,3.,1., - 0.,0.,2., 1.,1.,2., 1.,1.25,2., 0.,1.,2., 1.,1.5,2., 2.,0.,2., 2.,1.,2., 1.,2.,2., 0.,2.,2., 3.,1.,2., - 3.,2.,2., 0.,1.,2., 1.,3.,2., 2.,2.,2., 2.,3.,2., - 0.,0.,3., 1.,1.,3., 1.,1.25,3., 0.,1.,3., 1.,1.5,3., 2.,0.,3., 2.,1.,3., 1.,2.,3., 0.,2.,3., 3.,1.,3., - 3.,2.,3., 0.,1.,3., 1.,3.,3., 2.,2.,3., 2.,3.,3.}; - - int conn[354]={ - // 0 - 0,11,1,3,15,26,16,18, 1,2,4,7,13,6,-1,1,16,21,6,-1,6,21,28,13,-1,13,7,22,28,-1,7,4,19,22,-1,4,2,17,19,-1,2,1,16,17,-1,16,21,28,22,19,17, - 1,6,5,3,16,21,20,18, 13,10,9,6,28,25,24,21, - 11,8,7,4,2,1,-1,11,26,16,1,-1,1,16,17,2,-1,2,17,19,4,-1,4,19,22,7,-1,7,8,23,22,-1,8,11,26,23,-1,26,16,17,19,22,23, - 7,12,14,13,22,27,29,28, - // 1 - 15,26,16,18,30,41,31,33, 16,17,19,22,28,21,-1,16,31,36,21,-1,21,36,43,28,-1,28,22,37,43,-1,22,19,34,37,-1,19,17,32,34,-1,17,16,31,32,-1,31,36,43,37,34,32, - 16,21,20,18,31,36,35,33, 28,25,24,21,43,40,39,36, - 26,23,22,19,17,16,-1,26,41,31,16,-1,16,31,32,17,-1,17,32,34,19,-1,19,34,37,22,-1,22,23,38,37,-1,23,26,41,38,-1,41,31,32,34,37,38, - 22,27,29,28,37,42,44,43, - // 2 - 30,41,31,33,45,56,46,48, 31,32,34,37,43,36,-1,31,46,51,36,-1,36,51,58,43,-1,43,37,52,58,-1,37,34,49,52,-1,34,32,47,49,-1,32,31,46,47,-1,46,51,58,52,49,47, - 31,36,35,33,46,51,50,48, 43,40,39,36,58,55,54,51, - 41,38,37,34,32,31,-1,41,56,46,31,-1,31,46,47,32,-1,32,47,49,34,-1,34,49,52,37,-1,37,38,53,52,-1,38,41,56,53,-1,56,46,47,49,52,53, - 37,42,44,43,52,57,59,58 - }; - // - MEDCouplingUMesh *ret=MEDCouplingUMesh::New(); - ret->setName("3DMesh_1"); - ret->setMeshDimension(3); - ret->allocateCells(18); - // - ret->insertNextCell(INTERP_KERNEL::NORM_HEXA8,8,conn); - ret->insertNextCell(INTERP_KERNEL::NORM_HEXA8,8,conn+51); - ret->insertNextCell(INTERP_KERNEL::NORM_HEXA8,8,conn+59); - ret->insertNextCell(INTERP_KERNEL::NORM_HEXA8,8,conn+110); - // - ret->insertNextCell(INTERP_KERNEL::NORM_HEXA8,8,conn+118); - ret->insertNextCell(INTERP_KERNEL::NORM_HEXA8,8,conn+169); - ret->insertNextCell(INTERP_KERNEL::NORM_HEXA8,8,conn+177); - ret->insertNextCell(INTERP_KERNEL::NORM_HEXA8,8,conn+228); - // - ret->insertNextCell(INTERP_KERNEL::NORM_HEXA8,8,conn+236); - ret->insertNextCell(INTERP_KERNEL::NORM_HEXA8,8,conn+287); - ret->insertNextCell(INTERP_KERNEL::NORM_HEXA8,8,conn+295); - ret->insertNextCell(INTERP_KERNEL::NORM_HEXA8,8,conn+346); - // - ret->insertNextCell(INTERP_KERNEL::NORM_POLYHED,43,conn+8); - ret->insertNextCell(INTERP_KERNEL::NORM_POLYHED,43,conn+67); - ret->insertNextCell(INTERP_KERNEL::NORM_POLYHED,43,conn+126); - ret->insertNextCell(INTERP_KERNEL::NORM_POLYHED,43,conn+185); - ret->insertNextCell(INTERP_KERNEL::NORM_POLYHED,43,conn+244); - ret->insertNextCell(INTERP_KERNEL::NORM_POLYHED,43,conn+303); - // - ret->finishInsertingCells(); - DataArrayDouble *myCoords=DataArrayDouble::New(); - myCoords->alloc(60,3); - myCoords->setInfoOnComponent(0,"titi [m]"); - myCoords->setInfoOnComponent(1,"density power [MW/m^3]"); - myCoords->setInfoOnComponent(2,"t [kW]"); - std::copy(coords,coords+180,myCoords->getPointer()); - ret->setCoords(myCoords); - myCoords->decrRef(); - return ret; -} - -MEDCouplingUMesh *MEDLoaderTest::build3DMesh_2() -{ - MEDCouplingUMesh *m3dsurfBase=build3DSurfMesh_1(); - int numbers[5]={0,1,2,3,5}; - MEDCouplingUMesh *m3dsurf=(MEDCouplingUMesh *)m3dsurfBase->buildPartOfMySelf(numbers,numbers+5,false); - m3dsurfBase->decrRef(); - MEDCouplingUMesh *m1dBase=build1DMesh_1(); - int numbers2[4]={0,1,2,3}; - MEDCouplingUMesh *m1d=(MEDCouplingUMesh *)m1dBase->buildPartOfMySelf(numbers2,numbers2+4,false); - m1dBase->decrRef(); - m1d->changeSpaceDimension(3); - const double vec[3]={0.,1.,0.}; - const double pt[3]={0.,0.,0.}; - m1d->rotate(pt,vec,-M_PI/2.); - MEDCouplingUMesh *ret=m3dsurf->buildExtrudedMesh(m1d,0); - m1d->decrRef(); - m3dsurf->decrRef(); - return ret; -} - -MEDCouplingFieldDouble *MEDLoaderTest::buildVecFieldOnCells_1() -{ - MEDCouplingUMesh *mesh=build3DSurfMesh_1(); - int nbOfCells=mesh->getNumberOfCells(); - MEDCouplingFieldDouble *f1=MEDCouplingFieldDouble::New(ON_CELLS,ONE_TIME); - f1->setName("VectorFieldOnCells"); - f1->setMesh(mesh); - DataArrayDouble *array=DataArrayDouble::New(); - array->alloc(nbOfCells,3); - array->setInfoOnComponent(0,"power [MW/m^3]"); - array->setInfoOnComponent(1,"density [g/cm^3]"); - array->setInfoOnComponent(2,"temperature [K]"); - f1->setArray(array); - array->decrRef(); - double *tmp=array->getPointer(); - const double arr1[18]={0.,10.,20.,1.,11.,21.,2.,12.,22.,3.,13.,23.,4.,14.,24.,5.,15.,25.}; - std::copy(arr1,arr1+18,tmp); - f1->setTime(2.,0,1); - f1->checkCoherency(); - mesh->decrRef(); - return f1; -} - -MEDCouplingFieldDouble *MEDLoaderTest::buildVecFieldOnNodes_1() -{ - MEDCouplingUMesh *mesh=build3DSurfMesh_1(); - int nbOfNodes=mesh->getNumberOfNodes(); - MEDCouplingFieldDouble *f1=MEDCouplingFieldDouble::New(ON_NODES,ONE_TIME); - f1->setName("VectorFieldOnNodes"); - f1->setMesh(mesh); - DataArrayDouble *array=DataArrayDouble::New(); - array->alloc(nbOfNodes,3); - f1->setArray(array); - array->setInfoOnComponent(0,"power [MW/m^3]"); - array->setInfoOnComponent(1,"density [g/cm^3]"); - array->setInfoOnComponent(2,"temperature [K]"); - array->decrRef(); - double *tmp=array->getPointer(); - const double arr1[36]={ - 70.,80.,90.,71.,81.,91.,72.,82.,92.,73.,83.,93.,74.,84.,94.,75.,85.,95., - 1000.,10010.,10020.,1001.,10011.,10021.,1002.,10012.,10022.,1003.,10013.,10023.,1004.,10014.,10024.,1005.,10015.,10025., - }; - std::copy(arr1,arr1+36,tmp); - f1->setTime(2.12,2,3); - f1->checkCoherency(); - mesh->decrRef(); - return f1; -} - -MEDCouplingFieldDouble *MEDLoaderTest::buildVecFieldOnGauss_1() -{ - const double _a=0.446948490915965; - const double _b=0.091576213509771; - const double _p1=0.11169079483905; - const double _p2=0.0549758718227661; - const double refCoo1[6]={ 0.,0., 1.,0., 0.,1. }; - const double gsCoo1[12]={ 2*_b-1, 1-4*_b, 2*_b-1, 2.07*_b-1, 1-4*_b, - 2*_b-1, 1-4*_a, 2*_a-1, 2*_a-1, 1-4*_a, 2*_a-1, 2*_a-1 }; - const double wg1[6]={ 4*_p2, 4*_p2, 4*_p2, 4*_p1, 4*_p1, 4*_p1 }; - std::vector<double> _refCoo1(refCoo1,refCoo1+6); - std::vector<double> _gsCoo1(gsCoo1,gsCoo1+12); - std::vector<double> _wg1(wg1,wg1+6); - MEDCouplingUMesh *m=build2DMesh_2(); - MEDCouplingFieldDouble *f=MEDCouplingFieldDouble::New(ON_GAUSS_PT,ONE_TIME); - f->setTime(3.14,1,5); - f->setMesh(m); - f->setGaussLocalizationOnType(INTERP_KERNEL::NORM_TRI3,_refCoo1,_gsCoo1,_wg1); - const double refCoo2[12]={-1.0,1.0, -1.0,-1.0, 1.0,-1.0, -1.0,0.0, 0.0,-1.0, 0.0,0.0 }; - std::vector<double> _refCoo2(refCoo2,refCoo2+12); - std::vector<double> _gsCoo2(_gsCoo1); - std::vector<double> _wg2(_wg1); - _gsCoo2.resize(6); _wg2.resize(3); - const double refCoo3[8]={ 0.,0., 1.,0., 1.,1., 0.,1. }; - std::vector<double> _refCoo3(refCoo3,refCoo3+8); - _gsCoo1.resize(4); _wg1.resize(2); - f->setGaussLocalizationOnType(INTERP_KERNEL::NORM_QUAD4,_refCoo3,_gsCoo1,_wg1); - f->setGaussLocalizationOnType(INTERP_KERNEL::NORM_TRI6,_refCoo2,_gsCoo2,_wg2); - DataArrayDouble *array=DataArrayDouble::New(); - array->alloc(19,2); - double *ptr=array->getPointer(); - for(int i=0;i<19*2;i++) - ptr[i]=(double)(i+7); - f->setArray(array); - f->setName("MyFirstFieldOnGaussPoint"); - array->setInfoOnComponent(0,"power [MW/m^3]"); - array->setInfoOnComponent(1,"density"); - array->decrRef(); - f->checkCoherency(); - m->decrRef(); - return f; -} - -MEDCouplingFieldDouble *MEDLoaderTest::buildVecFieldOnGaussNE_1() -{ - MEDCouplingUMesh *m=build2DMesh_2(); - MEDCouplingFieldDouble *f=MEDCouplingFieldDouble::New(ON_GAUSS_NE,ONE_TIME); - f->setTime(3.14,1,5); - f->setMesh(m); - DataArrayDouble *array=DataArrayDouble::New(); - array->alloc(20,2); - double *ptr=array->getPointer(); - for(int i=0;i<20*2;i++) - ptr[i]=(double)(i+8); - f->setArray(array); - array->setInfoOnComponent(0,"power [W]"); - array->setInfoOnComponent(1,"temperature"); - f->setName("MyFieldOnGaussNE"); - array->decrRef(); - f->checkCoherency(); - m->decrRef(); - return f; -} - diff --git a/src/MEDLoader/Test/MEDLoaderTest.hxx b/src/MEDLoader/Test/MEDLoaderTest.hxx deleted file mode 100644 index e0e842995..000000000 --- a/src/MEDLoader/Test/MEDLoaderTest.hxx +++ /dev/null @@ -1,95 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 -// 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 __MEDLOADERTEST_HXX__ -#define __MEDLOADERTEST_HXX__ - -#include <cppunit/extensions/HelperMacros.h> - -namespace ParaMEDMEM -{ - class MEDCouplingUMesh; - class MEDCouplingFieldDouble; - - class MEDLoaderTest : public CppUnit::TestFixture - { - CPPUNIT_TEST_SUITE(MEDLoaderTest); - CPPUNIT_TEST( testMesh1DRW ); - CPPUNIT_TEST( testMesh2DCurveRW ); - CPPUNIT_TEST( testMesh2DRW ); - CPPUNIT_TEST( testMesh3DSurfRW ); - CPPUNIT_TEST( testMesh3DRW ); - CPPUNIT_TEST( testFieldRW1 ); - CPPUNIT_TEST( testFieldRW2 ); - CPPUNIT_TEST( testFieldRW3 ); - CPPUNIT_TEST( testMultiMeshRW1 ); - CPPUNIT_TEST( testFieldProfilRW1 ); - CPPUNIT_TEST( testFieldNodeProfilRW1 ); - CPPUNIT_TEST( testFieldNodeProfilRW2 ); - CPPUNIT_TEST( testFieldGaussRW1 ); - CPPUNIT_TEST( testFieldGaussNERW1 ); - CPPUNIT_TEST( testLittleStrings1 ); - CPPUNIT_TEST( testSplitIntoNameAndUnit1 ); - CPPUNIT_TEST( testMesh3DSurfShuffleRW ); - CPPUNIT_TEST( testFieldShuffleRW1 ); - CPPUNIT_TEST( testMultiFieldShuffleRW1 ); - CPPUNIT_TEST( testWriteUMeshesRW1 ); - CPPUNIT_TEST( testMixCellAndNodesFieldRW1 ); - CPPUNIT_TEST( testGetAllFieldNamesRW1 ); - CPPUNIT_TEST_SUITE_END(); - public: - void testMesh1DRW(); - void testMesh2DCurveRW(); - void testMesh2DRW(); - void testMesh3DSurfRW(); - void testMesh3DRW(); - void testFieldRW1(); - void testFieldRW2(); - void testFieldRW3(); - void testMultiMeshRW1(); - void testFieldProfilRW1(); - void testFieldNodeProfilRW1(); - void testFieldNodeProfilRW2(); - void testFieldGaussRW1(); - void testFieldGaussNERW1(); - void testLittleStrings1(); - void testSplitIntoNameAndUnit1(); - void testMesh3DSurfShuffleRW(); - void testFieldShuffleRW1(); - void testMultiFieldShuffleRW1(); - void testWriteUMeshesRW1(); - void testMixCellAndNodesFieldRW1(); - void testGetAllFieldNamesRW1(); - private: - MEDCouplingUMesh *build1DMesh_1(); - MEDCouplingUMesh *build2DCurveMesh_1(); - MEDCouplingUMesh *build2DMesh_1(); - MEDCouplingUMesh *build2DMesh_2(); - MEDCouplingUMesh *build3DSurfMesh_1(); - MEDCouplingUMesh *build3DMesh_1(); - MEDCouplingUMesh *build3DMesh_2(); - MEDCouplingFieldDouble *buildVecFieldOnCells_1(); - MEDCouplingFieldDouble *buildVecFieldOnNodes_1(); - MEDCouplingFieldDouble *buildVecFieldOnGauss_1(); - MEDCouplingFieldDouble *buildVecFieldOnGaussNE_1(); - }; -} - -#endif diff --git a/src/MEDLoader/Test/SauvLoaderTest.cxx b/src/MEDLoader/Test/SauvLoaderTest.cxx deleted file mode 100644 index b6195f6df..000000000 --- a/src/MEDLoader/Test/SauvLoaderTest.cxx +++ /dev/null @@ -1,354 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// - -#include "SauvLoaderTest.hxx" - -#include "SauvReader.hxx" -#include "SauvWriter.hxx" -#include "MEDFileData.hxx" -#include "MEDCouplingFieldDouble.hxx" -#include "MEDCouplingMemArray.hxx" - -#ifdef WIN32 -# include <windows.h> -#else -# include <unistd.h> -#endif - -#include <vector> -#include <string> - -using namespace ParaMEDMEM; - -void SauvLoaderTest::testSauv2Med() -{ - // read a file containing all types of readable piles - std::string file = getResourceFile("allPillesTest.sauv"); - MEDCouplingAutoRefCountObjectPtr<SauvReader> sr=SauvReader::New(file.c_str()); - MEDCouplingAutoRefCountObjectPtr<MEDFileData> d2=sr->loadInMEDFileDS(); - // write MED - d2->write("allPillesTest.med",0); - // check - CPPUNIT_ASSERT_EQUAL(1,d2->getNumberOfMeshes()); - CPPUNIT_ASSERT_EQUAL(8+97,d2->getNumberOfFields()); - MEDFileMesh * m = d2->getMeshes()->getMeshAtPos(0); - CPPUNIT_ASSERT_EQUAL(17,int(m->getGroupsNames().size())); -} - -void SauvLoaderTest::testMed2SauvOnAMeshWithVoidFamily() -{ - // Create a mesh with 2 quads. - const int spaceDim = 2; - const int nbOfNodes = 6; - double coords[nbOfNodes*spaceDim] = {0,0, 1,0, 1,1, 0,1, 2,0, 2,1}; - int conn[8]={0,1,2,3, 1,4,5,2}; - MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> mesh2d=MEDCouplingUMesh::New("Mesh",spaceDim); - mesh2d->allocateCells(2); - mesh2d->insertNextCell(INTERP_KERNEL::NORM_QUAD4,4,conn); - mesh2d->insertNextCell(INTERP_KERNEL::NORM_QUAD4,4,conn+4); - mesh2d->finishInsertingCells(); - MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> myCoords=DataArrayDouble::New(); - myCoords->alloc(nbOfNodes,spaceDim); - std::copy(coords,coords+nbOfNodes*spaceDim,myCoords->getPointer()); - mesh2d->setCoords(myCoords); - - // create a MedFileUMesh - MEDCouplingAutoRefCountObjectPtr<MEDFileUMesh> m= MEDFileUMesh::New(); - m->setMeshAtLevel(0,mesh2d); - - // Create families and groups - - MEDCouplingAutoRefCountObjectPtr<DataArrayInt> fam = DataArrayInt::New(); - fam->alloc(2,1); - int elemsFams[2] = {-2,-3}; - std::copy(elemsFams,elemsFams+2,fam->getPointer()); - - m->setFamilyFieldArr(0,fam); - - std::map<std::string,int> theFamilies; - theFamilies["FAM_-1"]=-1; - theFamilies["FAM_-2"]=-2; - theFamilies["FAM_-3"]=-3; - - std::map<std::string, std::vector<std::string> > theGroups; - theGroups["Group1"].push_back("FAM_-2"); - theGroups["Group2"].push_back("FAM_-3"); - theGroups["Grouptot"].push_back("FAM_-1"); - theGroups["Grouptot"].push_back("FAM_-2"); - theGroups["Grouptot"].push_back("FAM_-3"); - m->setFamilyInfo(theFamilies); - m->setGroupInfo(theGroups); - - // write to MED for visual check - //const char* medFile = "mesh_with_void_family.med"; - //m->write(medFile, 2); - - // write to SAUV - const char* sauvFile = "mesh_with_void_family.sauv"; - MEDCouplingAutoRefCountObjectPtr<MEDFileData> medData = MEDFileData::New(); - MEDCouplingAutoRefCountObjectPtr<MEDFileMeshes> medMeshes = MEDFileMeshes::New(); - MEDCouplingAutoRefCountObjectPtr<SauvWriter> sw=SauvWriter::New(); - medMeshes->setMeshAtPos(0, m); - medData->setMeshes(medMeshes); - sw->setMEDFileDS(medData); - sw->write(sauvFile); - - // read SAUV and check groups - MEDCouplingAutoRefCountObjectPtr<SauvReader> sr=SauvReader::New(sauvFile); - MEDCouplingAutoRefCountObjectPtr<MEDFileData> d2=sr->loadInMEDFileDS(); - MEDFileUMesh* m2 = static_cast<MEDFileUMesh*>( d2->getMeshes()->getMeshAtPos(0) ); - MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> group1 = m2->getGroup(0, "Group1"); - CPPUNIT_ASSERT_EQUAL(1,(int)group1->getNumberOfCells()); - MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> group2 = m2->getGroup(0, "Group2"); - CPPUNIT_ASSERT_EQUAL(1,(int)group2->getNumberOfCells()); - MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> grptot = m2->getGroup(0, "Grouptot"); - CPPUNIT_ASSERT_EQUAL(2,(int)grptot->getNumberOfCells()); -} - -void SauvLoaderTest::testSauv2MedOnA3SubsField() -{ - // read SAUV - std::string sauvFile = getResourceFile("portico_3subs.sauv"); - MEDCouplingAutoRefCountObjectPtr<SauvReader> sr=SauvReader::New(sauvFile.c_str()); - MEDCouplingAutoRefCountObjectPtr<MEDFileData> d2=sr->loadInMEDFileDS(); - // check mesh - MEDFileUMesh* m2 = static_cast<MEDFileUMesh*>(d2->getMeshes()->getMeshAtPos(0)); - MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> mesh1d = m2->getMeshAtLevel(0); - MEDCouplingAutoRefCountObjectPtr<MEDCouplingFieldDouble> length1dField = mesh1d->getMeasureField(0); - std::cout << "Length of 1d elements: " << length1dField->accumulate(0) << std::endl; - CPPUNIT_ASSERT_DOUBLES_EQUAL(3, length1dField->accumulate(0), 1e-12); - // check field - MEDCouplingAutoRefCountObjectPtr<MEDFileFieldMultiTS> field = - dynamic_cast<MEDFileFieldMultiTS *>(d2->getFields()->getFieldWithName("CHAM1D")); - std::cout << "Number of components in field: " << field->getInfo().size() << std::endl; - CPPUNIT_ASSERT_EQUAL(6,(int)field->getInfo().size()); - std::vector< std::pair<int,int> > timesteps = field->getIterations(); - - MEDCouplingAutoRefCountObjectPtr<MEDCouplingFieldDouble> field1d = - field->getFieldOnMeshAtLevel(ON_GAUSS_NE, timesteps[0].first, timesteps[0].second, 0, m2); - - // Check first component of the field - // 2 gauss points per element => 12 values - double values[12] = { - -7.687500000000e-03, - -7.687500000000e-03, - -4.562500000000e-03, - -4.562500000000e-03, - -8.208333333333e-03, - -8.208333333333e-03, - -6.125000000000e-03, - -6.125000000000e-03, - -4.041666666666e-03, - -4.041666666666e-03, - -6.111413346910e-07, - -6.111413346910e-07}; - - for (int i=0; i < field1d->getNumberOfTuples(); i++) - { - CPPUNIT_ASSERT_DOUBLES_EQUAL( values[i], field1d->getIJ(i, 0), 1e-12 ); - } -} - -void SauvLoaderTest::testMed2Sauv() -{ - // read pointe.med - std::string file = getResourceFile("pointe.med"); - MEDCouplingAutoRefCountObjectPtr<MEDFileData> pointeMed=MEDFileData::New(file.c_str()); - - // add 3 faces to pointeMed - MEDFileUMesh* pointeMedMesh = static_cast<MEDFileUMesh*>(pointeMed->getMeshes()->getMeshAtPos(0)); - MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> pointeM1D = MEDCouplingUMesh::New(); - DataArrayDouble *coords = pointeMedMesh->getCoords(); - pointeM1D->setCoords( coords ); - pointeM1D->setMeshDimension( 2 ); - pointeM1D->allocateCells( 3 ); - int conn[]= - { - 0,1,2, 0,1,3, 10,11,12,13 - }; - pointeM1D->insertNextCell( INTERP_KERNEL::NORM_TRI3, 3, conn); - pointeM1D->insertNextCell( INTERP_KERNEL::NORM_TRI3, 3, conn+3); - pointeM1D->insertNextCell( INTERP_KERNEL::NORM_QUAD4, 4, conn+6); - pointeM1D->finishInsertingCells(); - pointeMedMesh->setMeshAtLevel( -1, pointeM1D ); - pointeMed->getMeshes()->setMeshAtPos( 0, pointeMedMesh ); - - // add a field on 2 faces to pointeMed - MEDCouplingAutoRefCountObjectPtr<MEDFileFieldMultiTS> ff1=MEDFileFieldMultiTS::New(); - MEDCouplingAutoRefCountObjectPtr<MEDCouplingFieldDouble> f1=MEDCouplingFieldDouble::New(ON_GAUSS_NE,ONE_TIME); - f1->setMesh( pointeM1D ); - f1->setName("Field on 2 faces"); - MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> d=DataArrayDouble::New(); - d->alloc(3+4,2); - d->setInfoOnComponent(0,"sigX [MPa]"); - d->setInfoOnComponent(1,"sigY [GPa]"); - double vals[2*(3+4)] = - { - 311,312,321,322,331,332,411,412,421,422,431,432,441,442 - }; - std::copy(vals,vals+d->getNbOfElems(),d->getPointer()); - f1->setArray(d); - MEDCouplingAutoRefCountObjectPtr<DataArrayInt> da=DataArrayInt::New(); - int ids[] = - { - 0,2 - }; - da->alloc(2,1); - std::copy(ids,ids+da->getNbOfElems(),da->getPointer()); - da->setName("sup2"); - ff1->appendFieldProfile(f1,pointeMedMesh,-1,da); - pointeMed->getFields()->pushField( ff1 ); - - // remove "fieldnodeint" - MEDFileFields* pointeFields = pointeMed->getFields(); - for ( int i = 0; i < pointeFields->getNumberOfFields(); ++i ) - { - MEDCouplingAutoRefCountObjectPtr<MEDFileAnyTypeFieldMultiTS> ts = pointeFields->getFieldAtPos(i); - if ( std::string("fieldnodeint") == ts->getName()) - { - pointeFields->destroyFieldAtPos( i ); - break; - } - } - // write pointeMed to SAUV - const char* sauvFile = "pointe.sauv"; - MEDCouplingAutoRefCountObjectPtr<SauvWriter> sw=SauvWriter::New(); - sw->setMEDFileDS(pointeMed); - sw->write(sauvFile); - - // read SAUV and check - MEDCouplingAutoRefCountObjectPtr<SauvReader> sr=SauvReader::New(sauvFile); - MEDCouplingAutoRefCountObjectPtr<MEDFileData> d2=sr->loadInMEDFileDS(); - CPPUNIT_ASSERT_EQUAL(1,d2->getNumberOfMeshes()); - CPPUNIT_ASSERT_EQUAL(4,d2->getNumberOfFields()); - MEDFileUMesh * m = static_cast<MEDFileUMesh*>( d2->getMeshes()->getMeshAtPos(0) ); - CPPUNIT_ASSERT_EQUAL(std::string("maa1"),std::string(m->getName() )); - CPPUNIT_ASSERT_EQUAL(3,m->getMeshDimension()); - std::vector<std::string > groups = m->getGroupsNames(); - CPPUNIT_ASSERT_EQUAL(6,(int)groups.size()); - CPPUNIT_ASSERT( std::find(groups.begin(),groups.end(),"groupe1") != groups.end() ); - CPPUNIT_ASSERT( std::find(groups.begin(),groups.end(),"groupe2") != groups.end() ); - CPPUNIT_ASSERT( std::find(groups.begin(),groups.end(),"groupe3") != groups.end() ); - CPPUNIT_ASSERT( std::find(groups.begin(),groups.end(),"groupe4") != groups.end() ); - CPPUNIT_ASSERT( std::find(groups.begin(),groups.end(),"groupe5") != groups.end() ); - CPPUNIT_ASSERT( std::find(groups.begin(),groups.end(),"maa1") != groups.end() ); - CPPUNIT_ASSERT_EQUAL(16,m->getSizeAtLevel(0)); - MEDCouplingAutoRefCountObjectPtr<MEDCouplingMesh> um0 = m->getGenMeshAtLevel(0); - CPPUNIT_ASSERT_EQUAL(12, um0->getNumberOfCellsWithType( INTERP_KERNEL::NORM_TETRA4 )); - CPPUNIT_ASSERT_EQUAL(2, um0->getNumberOfCellsWithType( INTERP_KERNEL::NORM_PYRA5 )); - CPPUNIT_ASSERT_EQUAL(2, um0->getNumberOfCellsWithType( INTERP_KERNEL::NORM_HEXA8 )); - MEDCouplingAutoRefCountObjectPtr<MEDCouplingMesh> um1 = m->getGenMeshAtLevel(-1); - CPPUNIT_ASSERT_EQUAL(2, um1->getNumberOfCellsWithType( INTERP_KERNEL::NORM_TRI3 )); - MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> pointeUM0 = - static_cast<MEDCouplingUMesh*>( pointeMedMesh->getGenMeshAtLevel(0)); - DataArrayDouble *coo = m->getCoords(); - DataArrayDouble *pointeCoo = pointeMedMesh->getCoords(); - CPPUNIT_ASSERT(coo->isEqualWithoutConsideringStr(*pointeCoo,1e-12)); - MEDCouplingAutoRefCountObjectPtr<MEDCouplingFieldDouble> vol = um0->getMeasureField(0); - MEDCouplingAutoRefCountObjectPtr<MEDCouplingFieldDouble> pointeVol = pointeUM0->getMeasureField(0); - CPPUNIT_ASSERT_DOUBLES_EQUAL( vol->accumulate(0), pointeVol->accumulate(0),1e-12); - // check fields - // fieldnodedouble - MEDCouplingAutoRefCountObjectPtr<MEDFileFieldMultiTS> fieldnodedoubleTS1 = - dynamic_cast<MEDFileFieldMultiTS *>(pointeMed->getFields()->getFieldWithName("fieldnodedouble")); - MEDCouplingAutoRefCountObjectPtr<MEDFileFieldMultiTS> fieldnodedoubleTS2 = - dynamic_cast<MEDFileFieldMultiTS *>(d2->getFields()->getFieldWithName("fieldnodedouble")); - CPPUNIT_ASSERT_EQUAL( fieldnodedoubleTS1->getInfo().size(), fieldnodedoubleTS2->getInfo().size()); - for ( size_t i = 0; i < fieldnodedoubleTS1->getInfo().size(); ++i ) - CPPUNIT_ASSERT_EQUAL( fieldnodedoubleTS1->getInfo()[i], fieldnodedoubleTS2->getInfo()[i]); - CPPUNIT_ASSERT_EQUAL( fieldnodedoubleTS1->getNumberOfTS(), fieldnodedoubleTS2->getNumberOfTS()); - std::vector< std::pair<int,int> > io1 = fieldnodedoubleTS1->getIterations(); - std::vector< std::pair<int,int> > io2 = fieldnodedoubleTS2->getIterations(); - for ( int i =0; i < fieldnodedoubleTS1->getNumberOfTS(); ++i ) - { - MEDCouplingAutoRefCountObjectPtr<MEDCouplingFieldDouble> fnd1 = - fieldnodedoubleTS1->getFieldOnMeshAtLevel(ON_NODES, io1[i].first,io1[i].second,pointeUM0); - MEDCouplingAutoRefCountObjectPtr<MEDCouplingFieldDouble> fnd2 = - fieldnodedoubleTS2->getFieldOnMeshAtLevel(ON_NODES, io2[i].first,io2[i].second,um0); - CPPUNIT_ASSERT( fnd1->getArray()->isEqual( *fnd2->getArray(), 1e-12 )); - } - // fieldcelldoublevector - MEDCouplingAutoRefCountObjectPtr<MEDFileFieldMultiTS> fieldcelldoublevectorTS1 = - dynamic_cast<MEDFileFieldMultiTS *>(pointeMed->getFields()->getFieldWithName("fieldcelldoublevector")); - MEDCouplingAutoRefCountObjectPtr<MEDFileFieldMultiTS> fieldcelldoublevectorTS2 = - dynamic_cast<MEDFileFieldMultiTS *>(d2->getFields()->getFieldWithName("fieldcelldoublevector")); - CPPUNIT_ASSERT_EQUAL( fieldcelldoublevectorTS1->getInfo().size(), fieldcelldoublevectorTS2->getInfo().size()); - for ( size_t i = 0; i < fieldcelldoublevectorTS1->getInfo().size(); ++i ) - CPPUNIT_ASSERT_EQUAL( fieldcelldoublevectorTS1->getInfo()[i], fieldcelldoublevectorTS2->getInfo()[i]); - CPPUNIT_ASSERT_EQUAL( fieldcelldoublevectorTS1->getNumberOfTS(), fieldcelldoublevectorTS2->getNumberOfTS()); - io1 = fieldcelldoublevectorTS1->getIterations(); - io2 = fieldcelldoublevectorTS2->getIterations(); - for ( int i =0; i < fieldcelldoublevectorTS1->getNumberOfTS(); ++i ) - { - MEDCouplingAutoRefCountObjectPtr<MEDCouplingFieldDouble> fnd1 = - fieldcelldoublevectorTS1->getFieldOnMeshAtLevel(ON_CELLS, io1[i].first,io1[i].second,pointeUM0); - MEDCouplingAutoRefCountObjectPtr<MEDCouplingFieldDouble> fnd2 = - fieldcelldoublevectorTS2->getFieldOnMeshAtLevel(ON_CELLS, io2[i].first,io2[i].second,um0); - CPPUNIT_ASSERT_DOUBLES_EQUAL( fnd1->accumulate(0), fnd2->accumulate(0), 1e-12 ); - CPPUNIT_ASSERT_DOUBLES_EQUAL( fnd1->accumulate(1), fnd2->accumulate(1), 1e-12 ); - CPPUNIT_ASSERT_DOUBLES_EQUAL( fnd1->accumulate(2), fnd2->accumulate(2), 1e-12 ); - } - // "Field on 2 faces" - MEDCouplingAutoRefCountObjectPtr<MEDFileFieldMultiTS> fieldOnFaces = - dynamic_cast<MEDFileFieldMultiTS *>(d2->getFields()->getFieldWithName(f1->getName().c_str())); - io1 = fieldOnFaces->getIterations(); - MEDCouplingAutoRefCountObjectPtr<MEDCouplingFieldDouble> fof = - fieldOnFaces->getFieldOnMeshAtLevel(f1->getTypeOfField(),io1[0].first,io1[0].second,um1); - CPPUNIT_ASSERT( d->isEqual( *fof->getArray(), 1e-12 )); -} - -void SauvLoaderTest::tearDown() -{ - const int nbFilesToRemove = 3; - const char* fileToRemove[nbFilesToRemove] = { "allPillesTest.med", "pointe.sauv", "mesh_with_void_family.sauv" }; - for ( int i = 0; i < nbFilesToRemove; ++i ) - { -#ifdef WIN32 - if (GetFileAttributes(fileToRemove[i]) != INVALID_FILE_ATTRIBUTES) -#else - if (access(fileToRemove[i], F_OK) == 0) -#endif - remove(fileToRemove[i]); - } -} - -std::string SauvLoaderTest::getResourceFile( const std::string& filename ) -{ - std::string resourceFile = ""; - - if ( getenv("top_srcdir") ) { - // we are in 'make test' step - resourceFile = getenv("top_srcdir"); - resourceFile += "/resources/"; - } - else if ( getenv("MED_ROOT_DIR") ) { - // use MED_ROOT_DIR env.var - resourceFile = getenv("MED_ROOT_DIR"); - resourceFile += "/share/salome/resources/med/"; - } - resourceFile += filename; -#ifdef WIN32 - std::string fixedpath = resourceFile; - for ( int i=0; i < fixedpath.length(); ++i ) - if (fixedpath[i] == '/') - fixedpath[i] = '\\'; - return fixedpath; -#endif - return resourceFile; -} diff --git a/src/MEDLoader/Test/SauvLoaderTest.hxx b/src/MEDLoader/Test/SauvLoaderTest.hxx deleted file mode 100644 index 586285cad..000000000 --- a/src/MEDLoader/Test/SauvLoaderTest.hxx +++ /dev/null @@ -1,49 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 -// 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 __SauvLoaderTest_HXX__ -#define __SauvLoaderTest_HXX__ - -#include <cppunit/extensions/HelperMacros.h> - -#include "MEDLoaderTest.hxx" - -namespace ParaMEDMEM -{ - class SauvLoaderTest : public CppUnit::TestFixture - { - CPPUNIT_TEST_SUITE(SauvLoaderTest); - CPPUNIT_TEST( testSauv2Med ); - CPPUNIT_TEST( testMed2Sauv ); - CPPUNIT_TEST( testMed2SauvOnAMeshWithVoidFamily ); - CPPUNIT_TEST( testSauv2MedOnA3SubsField ); - CPPUNIT_TEST_SUITE_END(); - public: - void testSauv2Med(); - void testMed2Sauv(); - void testMed2SauvOnAMeshWithVoidFamily(); - void testSauv2MedOnA3SubsField(); - - public: - void tearDown(); - static std::string getResourceFile( const std::string& filename ); - }; -} - -#endif diff --git a/src/MEDLoader/Test/TestMEDLoader.cxx b/src/MEDLoader/Test/TestMEDLoader.cxx deleted file mode 100644 index 8800a0405..000000000 --- a/src/MEDLoader/Test/TestMEDLoader.cxx +++ /dev/null @@ -1,26 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 -// 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 "CppUnitTest.hxx" -#include "MEDLoaderTest.hxx" - -CPPUNIT_TEST_SUITE_REGISTRATION( ParaMEDMEM::MEDLoaderTest ); - -#include "BasicMainTest.hxx" diff --git a/src/MEDLoader/Test/TestSauvLoader.cxx b/src/MEDLoader/Test/TestSauvLoader.cxx deleted file mode 100644 index 4fdbcdbce..000000000 --- a/src/MEDLoader/Test/TestSauvLoader.cxx +++ /dev/null @@ -1,25 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// - -#include "CppUnitTest.hxx" -#include "SauvLoaderTest.hxx" - -CPPUNIT_TEST_SUITE_REGISTRATION( ParaMEDMEM::SauvLoaderTest ); - -#include "BasicMainTest.hxx" diff --git a/src/MEDPartitioner/CMakeLists.txt b/src/MEDPartitioner/CMakeLists.txt deleted file mode 100644 index 2404e49f9..000000000 --- a/src/MEDPartitioner/CMakeLists.txt +++ /dev/null @@ -1,147 +0,0 @@ -# Copyright (C) 2012-2015 CEA/DEN, EDF 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, 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 -# 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_DEFINITIONS(${HDF5_DEFINITIONS} ${MEDFILE_DEFINITIONS} ${LIBXML2_DEFINITIONS}) - -INCLUDE_DIRECTORIES( - ${LIBXML2_INCLUDE_DIR} - ${MEDFILE_INCLUDE_DIRS} - ${HDF5_INCLUDE_DIRS} - ${PTHREAD_INCLUDE_DIR} - ${CMAKE_CURRENT_SOURCE_DIR}/../MEDLoader - ${CMAKE_CURRENT_SOURCE_DIR}/../MEDCoupling - ${CMAKE_CURRENT_SOURCE_DIR}/../INTERP_KERNEL - ${CMAKE_CURRENT_SOURCE_DIR}/../INTERP_KERNEL/Bases - ${CMAKE_CURRENT_SOURCE_DIR}/../INTERP_KERNEL/Geometric2D - ${CMAKE_CURRENT_SOURCE_DIR}/../INTERP_KERNEL/ExprEval - ${CMAKE_CURRENT_SOURCE_DIR}/../INTERP_KERNEL/GaussPoints - ) - -IF(SALOME_MED_PARTITIONER_METIS) - ADD_DEFINITIONS(${METIS_DEFINITIONS}) - IF(SALOME_MED_METIS_V5) - ADD_DEFINITIONS("-DMED_ENABLE_METIS_V5") - ENDIF(SALOME_MED_METIS_V5) - INCLUDE_DIRECTORIES(${METIS_INCLUDE_DIRS}) -ENDIF(SALOME_MED_PARTITIONER_METIS) - - -######## -# VERY IMPORTANT PUT METIS BEFORE SCOTCH because -# metis.h is also in SCOTCH install dir !!! -######## -IF(SALOME_MED_PARTITIONER_SCOTCH) - ADD_DEFINITIONS(${SCOTCH_DEFINITIONS}) - INCLUDE_DIRECTORIES(${SCOTCH_INCLUDE_DIRS}) -ENDIF(SALOME_MED_PARTITIONER_SCOTCH) - -IF(SALOME_MED_PARTITIONER_PARMETIS) - ADD_DEFINITIONS(${PARMETIS_DEFINITIONS}) - INCLUDE_DIRECTORIES(${PARMETIS_INCLUDE_DIRS}) -ENDIF(SALOME_MED_PARTITIONER_PARMETIS) - -IF(SALOME_USE_MPI) - ADD_DEFINITIONS(${MPI_DEFINITIONS}) - INCLUDE_DIRECTORIES(${MPI_INCLUDE_DIRS}) -ENDIF(SALOME_USE_MPI) - -IF(SALOME_BUILD_TESTS) - ADD_SUBDIRECTORY(Test) -ENDIF(SALOME_BUILD_TESTS) - -SET(medpartitionercpp_HEADERS_HXX - MEDPARTITIONER_MeshCollection.hxx - MEDPARTITIONER_MeshCollectionDriver.hxx - MEDPARTITIONER_MeshCollectionMedXmlDriver.hxx - MEDPARTITIONER_MeshCollectionMedAsciiDriver.hxx - MEDPARTITIONER_ParallelTopology.hxx - MEDPARTITIONER_JointFinder.hxx - MEDPARTITIONER_Graph.hxx - MEDPARTITIONER_UserGraph.hxx - MEDPARTITIONER_Utils.hxx - MEDPARTITIONER.hxx - MEDPARTITIONER_ParaDomainSelector.hxx - MEDPARTITIONER_ConnectZone.hxx - MEDPARTITIONER_Topology.hxx - MEDPARTITIONER_MEDPartitioner.hxx - ) - -SET(medpartitionercpp_SOURCES - MEDPARTITIONER_MeshCollection.cxx - MEDPARTITIONER_MeshCollectionDriver.cxx - MEDPARTITIONER_MeshCollectionMedXmlDriver.cxx - MEDPARTITIONER_MeshCollectionMedAsciiDriver.cxx - MEDPARTITIONER_ParallelTopology.cxx - MEDPARTITIONER_Graph.cxx - MEDPARTITIONER_UserGraph.cxx - MEDPARTITIONER_Utils.cxx - MEDPARTITIONER_ParaDomainSelector.cxx - MEDPARTITIONER_ConnectZone.cxx - MEDPARTITIONER_metis.c - MEDPARTITIONER_MEDPartitioner.cxx - ) - -SET(medpartitionercpp_LDFLAGS - ${MEDFILE_C_LIBRARIES} - ${HDF5_LIBRARIES} - ${STDLIB} - ${LIBXML2_LIBRARIES} - interpkernel - medcoupling - medloader -) -IF(SALOME_MED_PARTITIONER_PARMETIS) - SET(medpartitionercpp_HEADERS_HXX ${medpartitionercpp_HEADERS_HXX} MEDPARTITIONER_ParMetisGraph.hxx) - SET(medpartitionercpp_SOURCES ${medpartitionercpp_SOURCES} MEDPARTITIONER_ParMetisGraph.cxx MEDPARTITIONER_MetisGraph.cxx) - SET(medpartitionercpp_DEFINITIONS "${medpartitionercpp_DEFINITIONS} ${PARMETIS_DEFINITIONS}") - SET(medpartitionercpp_LDFLAGS ${medpartitionercpp_LDFLAGS} ${PARMETIS_LIBRARIES}) -ENDIF(SALOME_MED_PARTITIONER_PARMETIS) -IF(SALOME_MED_PARTITIONER_METIS) - SET(medpartitionercpp_HEADERS_HXX ${medpartitionercpp_HEADERS_HXX} MEDPARTITIONER_MetisGraph.hxx) - SET(medpartitionercpp_SOURCES ${medpartitionercpp_SOURCES} MEDPARTITIONER_MetisGraph.cxx) - SET(medpartitionercpp_DEFINITIONS "${medpartitionercpp_DEFINITIONS} ${METIS_DEFINITIONS}") - SET(medpartitionercpp_LDFLAGS ${medpartitionercpp_LDFLAGS} ${METIS_LIBRARIES}) -ENDIF(SALOME_MED_PARTITIONER_METIS) -IF(SALOME_MED_PARTITIONER_SCOTCH) - SET(medpartitionercpp_HEADERS_HXX ${medpartitionercpp_HEADERS_HXX} MEDPARTITIONER_ScotchGraph.hxx) - SET(medpartitionercpp_SOURCES ${medpartitionercpp_SOURCES} MEDPARTITIONER_ScotchGraph.cxx) - SET(medpartitionercpp_DEFINITIONS "${medpartitionercpp_DEFINITIONS} ${SCOTCH_DEFINITIONS}") - SET(medpartitionercpp_LDFLAGS ${medpartitionercpp_LDFLAGS} ${SCOTCH_LIBRARIES}) -ENDIF(SALOME_MED_PARTITIONER_SCOTCH) - -IF(${SALOME_USE_MPI}) - SET(medpartitionercpp_SOURCES ${medpartitionercpp_SOURCES} MEDPARTITIONER_UtilsPara.cxx MEDPARTITIONER_JointFinder.cxx) - ADD_EXECUTABLE(medpartitioner_para medpartitioner_para.cxx) - SET(medpartitionercpp_LDFLAGS ${medpartitionercpp_LDFLAGS} ${MPI_LIBRARIES}) - SET_TARGET_PROPERTIES(medpartitioner_para PROPERTIES COMPILE_FLAGS "${medpartitionercpp_DEFINITIONS}") - TARGET_LINK_LIBRARIES(medpartitioner_para medpartitionercpp ${medpartitionercpp_LDFLAGS}) - INSTALL(TARGETS medpartitioner_para DESTINATION ${SALOME_INSTALL_BINS}) -ENDIF(${SALOME_USE_MPI}) - -ADD_DEFINITIONS(${medpartitionercpp_DEFINITIONS}) - -ADD_LIBRARY(medpartitionercpp SHARED ${medpartitionercpp_SOURCES}) -TARGET_LINK_LIBRARIES(medpartitionercpp ${medpartitionercpp_LDFLAGS} ${PLATFORM_LIBS} ${PTHREAD_LIBS}) -INSTALL(TARGETS medpartitionercpp DESTINATION ${SALOME_INSTALL_LIBS}) - -ADD_EXECUTABLE(medpartitioner medpartitioner.cxx) -TARGET_LINK_LIBRARIES(medpartitioner medpartitionercpp ${medpartitionercpp_LDFLAGS}) -INSTALL(TARGETS medpartitioner DESTINATION ${SALOME_INSTALL_BINS}) - -INSTALL(FILES ${medpartitionercpp_HEADERS_HXX} DESTINATION ${SALOME_INSTALL_HEADERS}) diff --git a/src/MEDPartitioner/MEDPARTITIONER.hxx b/src/MEDPartitioner/MEDPARTITIONER.hxx deleted file mode 100755 index 0996534cc..000000000 --- a/src/MEDPartitioner/MEDPARTITIONER.hxx +++ /dev/null @@ -1,33 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// - -#ifndef __MEDPARTITIONER_HXX__ -#define __MEDPARTITIONER_HXX__ - -#ifdef WIN32 -# if defined MEDPARTITIONERCPP_EXPORTS || defined medpartitionercpp_EXPORTS -# define MEDPARTITIONER_EXPORT __declspec( dllexport ) -# else -# define MEDPARTITIONER_EXPORT __declspec( dllimport ) -# endif -#else -# define MEDPARTITIONER_EXPORT -#endif - -#endif diff --git a/src/MEDPartitioner/MEDPARTITIONER_ConnectZone.cxx b/src/MEDPartitioner/MEDPARTITIONER_ConnectZone.cxx deleted file mode 100644 index 402d66249..000000000 --- a/src/MEDPartitioner/MEDPARTITIONER_ConnectZone.cxx +++ /dev/null @@ -1,339 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// - -#include "MEDPARTITIONER_ConnectZone.hxx" - -#include "MEDCouplingSkyLineArray.hxx" - -#include <map> - -using namespace ParaMEDMEM; - -MEDPARTITIONER::ConnectZone::ConnectZone(): - _name("") - ,_description("") - ,_local_domain_number(0) - ,_distant_domain_number(0) - ,_node_corresp(0) - ,_face_corresp(0) -{ -} - -MEDPARTITIONER::ConnectZone::~ConnectZone() -{ - delete _node_corresp; - delete _face_corresp; - for(std::map < std::pair <int, int>,MEDCouplingSkyLineArray * >::iterator iter=_entity_corresp.begin(); iter!=_entity_corresp.end();iter++) - { - delete iter->second; - } -} - -MEDPARTITIONER::ConnectZone::ConnectZone(const ConnectZone & myConnectZone): - _name(myConnectZone._name) - ,_description(myConnectZone._description) - ,_local_domain_number(myConnectZone._local_domain_number) - ,_distant_domain_number(myConnectZone._distant_domain_number) - ,_node_corresp(myConnectZone._node_corresp) - ,_face_corresp(myConnectZone._face_corresp) - ,_entity_corresp(myConnectZone._entity_corresp) -{ -} - -std::string MEDPARTITIONER::ConnectZone::getName() const -{ - return _name; -} - -std::string MEDPARTITIONER::ConnectZone::getDescription() const -{ - return _description; -} - -int MEDPARTITIONER::ConnectZone::getDistantDomainNumber() const -{ - return _distant_domain_number; -} - -int MEDPARTITIONER::ConnectZone::getLocalDomainNumber() const -{ - return _local_domain_number; -} - -ParaMEDMEM::MEDCouplingUMesh *MEDPARTITIONER::ConnectZone::getLocalMesh() const -{ - return _local_mesh; -} - -ParaMEDMEM::MEDCouplingUMesh *MEDPARTITIONER::ConnectZone::getDistantMesh() const -{ - return _distant_mesh; -} - -bool MEDPARTITIONER::ConnectZone::isEntityCorrespPresent(int localEntity, int distantEntity) const -{ - typedef std::map<std::pair<int,int>, MEDCouplingSkyLineArray*>::const_iterator map_iter; - for(map_iter iter=_entity_corresp.begin(); iter != _entity_corresp.end(); iter++) - { - if ((iter->first).first==localEntity && (iter->first).second==distantEntity) - return true; - } - return false; -} - -const int *MEDPARTITIONER::ConnectZone::getNodeCorrespIndex() const -{ - return _node_corresp->getIndex(); -} - -const int *MEDPARTITIONER::ConnectZone::getNodeCorrespValue() const -{ - return _node_corresp->getValue(); -} - -int MEDPARTITIONER::ConnectZone::getNodeNumber() const -{ - return _node_corresp->getNumberOf(); -} - -const ParaMEDMEM::MEDCouplingSkyLineArray * MEDPARTITIONER::ConnectZone::getNodeCorresp() const -{ - return _node_corresp; -} - -const int *MEDPARTITIONER::ConnectZone::getFaceCorrespIndex() const -{ - return _face_corresp->getIndex(); -} - -const int *MEDPARTITIONER::ConnectZone::getFaceCorrespValue() const -{ - return _face_corresp->getValue(); -} - -int MEDPARTITIONER::ConnectZone::getFaceNumber() const -{ - return _face_corresp->getNumberOf(); -} - -const ParaMEDMEM::MEDCouplingSkyLineArray * MEDPARTITIONER::ConnectZone::getFaceCorresp() const -{ - return _face_corresp; -} - -const int *MEDPARTITIONER::ConnectZone::getEntityCorrespIndex(int localEntity, - int distantEntity) const -{ - typedef std::map<std::pair<int,int>, MEDCouplingSkyLineArray*>::const_iterator map_iter; - - for(map_iter iter=_entity_corresp.begin();iter!=_entity_corresp.end();iter++) - { - if ((iter->first).first==localEntity && (iter->first).second==distantEntity) - return iter->second->getIndex(); - } - return 0; -} - -const int *MEDPARTITIONER::ConnectZone::getEntityCorrespValue(int localEntity, - int distantEntity) const -{ - typedef std::map<std::pair<int,int>, MEDCouplingSkyLineArray*>::const_iterator map_iter; - - for (map_iter iter=_entity_corresp.begin();iter!=_entity_corresp.end();iter++) - { - if ((iter->first).first==localEntity && (iter->first).second==distantEntity) - return iter->second->getValue(); - } - return 0; -} - -int MEDPARTITIONER::ConnectZone::getEntityCorrespNumber(int localEntity, - int distantEntity) const -{ - typedef std::map<std::pair<int,int>, MEDCouplingSkyLineArray*>::const_iterator map_iter; - - for(map_iter iter=_entity_corresp.begin();iter!=_entity_corresp.end();iter++) - { - if((iter->first).first==localEntity && (iter->first).second==distantEntity) - return iter->second->getNumberOf(); - } - return 0; -} - -int MEDPARTITIONER::ConnectZone::getEntityCorrespLength(int localEntity, - int distantEntity) const -{ - typedef std::map<std::pair<int,int>, MEDCouplingSkyLineArray*>::const_iterator map_iter; - - for (map_iter iter=_entity_corresp.begin(); iter != _entity_corresp.end(); iter++) - { - if ((iter->first).first==localEntity && (iter->first).second==distantEntity) - return iter->second->getLength(); - } - return 0; -} - -const ParaMEDMEM::MEDCouplingSkyLineArray * -MEDPARTITIONER::ConnectZone::getEntityCorresp(int localEntity, int distantEntity) const -{ - typedef std::map<std::pair<int,int>, MEDCouplingSkyLineArray*>::const_iterator map_iter; - - for (map_iter iter=_entity_corresp.begin(); iter != _entity_corresp.end(); iter++) - { - if ((iter->first).first==localEntity && (iter->first).second==distantEntity) - return iter->second; - } - return 0; -} - -std::vector< std::pair< int,int > > MEDPARTITIONER::ConnectZone::getEntities() const -{ - std::vector< std::pair< int,int > > types; - - std::map<std::pair<int,int>, MEDCouplingSkyLineArray*>::const_iterator - iter = _entity_corresp.begin(); - for ( ; iter != _entity_corresp.end(); iter++) - { - types.push_back( iter->first ); - } - - return types; -} - -void MEDPARTITIONER::ConnectZone::setName(const std::string& name) -{ - _name=name; -} - -void MEDPARTITIONER::ConnectZone::setDescription(const std::string& description) -{ - _description=description; -} - -void MEDPARTITIONER::ConnectZone::setDistantDomainNumber(int distantDomainNumber) -{ - _distant_domain_number=distantDomainNumber; -} - -void MEDPARTITIONER::ConnectZone::setLocalDomainNumber(int localDomainNumber) -{ - _local_domain_number=localDomainNumber; -} - -void MEDPARTITIONER::ConnectZone::setLocalMesh(ParaMEDMEM::MEDCouplingUMesh * localMesh) -{ - _local_mesh=localMesh; -} - -void MEDPARTITIONER::ConnectZone::setDistantMesh(ParaMEDMEM::MEDCouplingUMesh * distantMesh) -{ - _distant_mesh=distantMesh; -} - -/*! transforms an int array containing - * the node-node connections - * to a MEDCouplingSkyLineArray - */ -void MEDPARTITIONER::ConnectZone::setNodeCorresp(const int * nodeCorresp, int nbnode) -{ - MEDCouplingAutoRefCountObjectPtr<DataArrayInt> indexArr( DataArrayInt::New() ); - MEDCouplingAutoRefCountObjectPtr<DataArrayInt> valueArr( DataArrayInt::New() ); - indexArr->alloc( nbnode+1 ); - valueArr->alloc( 2*nbnode ); - int * index = indexArr->getPointer(); - int * value = valueArr->getPointer(); - for (int i=0; i<nbnode; i++) - { - index[i]=2*i; - value[2*i ]=nodeCorresp[2*i]; - value[2*i+1]=nodeCorresp[2*i+1]; - } - index[nbnode]=2*nbnode; - setNodeCorresp( new MEDCouplingSkyLineArray( indexArr, valueArr )); -} - -void MEDPARTITIONER::ConnectZone::setNodeCorresp(MEDCouplingSkyLineArray* array) -{ - if ( _node_corresp ) delete _node_corresp; - _node_corresp = array; -} - -/*! transforms an int array containing - * the face-face connections - * to a MEDCouplingSkyLineArray - */ -void MEDPARTITIONER::ConnectZone::setFaceCorresp(const int * faceCorresp, int nbface) -{ - MEDCouplingAutoRefCountObjectPtr<DataArrayInt> indexArr( DataArrayInt::New() ); - MEDCouplingAutoRefCountObjectPtr<DataArrayInt> valueArr( DataArrayInt::New() ); - indexArr->alloc( nbface+1 ); - valueArr->alloc( 2*nbface ); - int * index = indexArr->getPointer(); - int * value = valueArr->getPointer(); - for (int i=0; i<nbface; i++) - { - index[i]=2*i; - value[2*i]=faceCorresp[2*i]; - value[2*i+1]=faceCorresp[2*i+1]; - } - index[nbface]=2*nbface; - setFaceCorresp( new MEDCouplingSkyLineArray( indexArr, valueArr )); -} - -void MEDPARTITIONER::ConnectZone::setFaceCorresp(MEDCouplingSkyLineArray* array) -{ - if ( _face_corresp ) delete _face_corresp; - _face_corresp = array; -} - -/*! transforms an int array containing - * the entity-entity connections - * to a MEDCouplingSkyLineArray - * - * the resulting MEDCouplingSkyLineArray is put in the map - */ -void MEDPARTITIONER::ConnectZone::setEntityCorresp(int localEntity, int distantEntity, - const int *entityCorresp, int nbentity) -{ - MEDCouplingAutoRefCountObjectPtr<DataArrayInt> indexArr( DataArrayInt::New() ); - MEDCouplingAutoRefCountObjectPtr<DataArrayInt> valueArr( DataArrayInt::New() ); - indexArr->alloc( nbentity+1 ); - valueArr->alloc( 2*nbentity ); - int * index = indexArr->getPointer(); - int * value = valueArr->getPointer(); - for (int i=0; i<nbentity; i++) - { - index[i]=2*i; - value[2*i ]=entityCorresp[2*i]; - value[2*i+1]=entityCorresp[2*i+1]; - } - index[nbentity]=2*nbentity; - setEntityCorresp( localEntity, distantEntity, new MEDCouplingSkyLineArray(indexArr,valueArr)); -} - -void MEDPARTITIONER::ConnectZone::setEntityCorresp(int localEntity, int distantEntity, - MEDCouplingSkyLineArray *array) -{ - ParaMEDMEM::MEDCouplingSkyLineArray * nullArray = 0; - std::map < std::pair <int,int>, ParaMEDMEM::MEDCouplingSkyLineArray * >::iterator it; - it = _entity_corresp.insert - ( std::make_pair( std::make_pair(localEntity,distantEntity), nullArray )).first; - if ( it->second != nullArray ) delete it->second; - it->second = array; -} diff --git a/src/MEDPartitioner/MEDPARTITIONER_ConnectZone.hxx b/src/MEDPartitioner/MEDPARTITIONER_ConnectZone.hxx deleted file mode 100644 index 9572db1c8..000000000 --- a/src/MEDPartitioner/MEDPARTITIONER_ConnectZone.hxx +++ /dev/null @@ -1,102 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// - -#ifndef __MEDPARTITIONER_CONNECTZONE_HXX__ -#define __MEDPARTITIONER_CONNECTZONE_HXX__ - -#include "MEDPARTITIONER.hxx" - -namespace ParaMEDMEM -{ - class MEDCouplingUMesh; - class MEDCouplingSkyLineArray; -} - -#include <map> -#include <vector> -#include <string> - -namespace MEDPARTITIONER -{ - class MEDPARTITIONER_EXPORT ConnectZone - { - public : - ConnectZone(); - ~ConnectZone(); - ConnectZone(const ConnectZone & myConnectZone); - - std::string getName() const ; - std::string getDescription() const ; - int getDistantDomainNumber() const ; - int getLocalDomainNumber() const ; - ParaMEDMEM::MEDCouplingUMesh *getLocalMesh() const ; - ParaMEDMEM::MEDCouplingUMesh *getDistantMesh() const ; - - bool isEntityCorrespPresent(int localEntity,int distantEntity) const; - const int *getNodeCorrespIndex() const; - const int *getNodeCorrespValue() const; - int getNodeNumber() const; - const ParaMEDMEM::MEDCouplingSkyLineArray * getNodeCorresp() const; - const int *getFaceCorrespIndex() const; - const int *getFaceCorrespValue() const; - int getFaceNumber() const; - const ParaMEDMEM::MEDCouplingSkyLineArray * getFaceCorresp() const; - const int *getEntityCorrespIndex(int localEntity, - int distantEntity) const; - const int *getEntityCorrespValue(int localEntity, - int distantEntity) const; - int getEntityCorrespNumber(int localEntity, - int distantEntity) const; - int getEntityCorrespLength(int localEntity, - int distantEntity) const; - const ParaMEDMEM::MEDCouplingSkyLineArray * getEntityCorresp(int localEntity, - int distantEntity) const; - std::vector< std::pair< int,int > > getEntities() const; - - void setName(const std::string& name) ; - void setDescription(const std::string& description) ; - void setDistantDomainNumber(int distantDomainNumber) ; - void setLocalDomainNumber(int distantDomainNumber) ; - void setLocalMesh(ParaMEDMEM::MEDCouplingUMesh * localMesh) ; - void setDistantMesh(ParaMEDMEM::MEDCouplingUMesh * distantMesh) ; - - void setNodeCorresp(const int * nodeCorresp, int nbnode); - void setNodeCorresp(ParaMEDMEM::MEDCouplingSkyLineArray* array); - void setFaceCorresp(const int * faceCorresp, int nbface); - void setFaceCorresp(ParaMEDMEM::MEDCouplingSkyLineArray* array); - void setEntityCorresp(int localEntity, int distantEntity, - const int * entityCorresp, int nbentity); - void setEntityCorresp(int localEntity, int distantEntity, - ParaMEDMEM::MEDCouplingSkyLineArray *array); - private : - std::string _name; - std::string _description; - int _local_domain_number; - int _distant_domain_number; - - ParaMEDMEM::MEDCouplingUMesh * _local_mesh; - ParaMEDMEM::MEDCouplingUMesh * _distant_mesh; - - ParaMEDMEM::MEDCouplingSkyLineArray * _node_corresp; - ParaMEDMEM::MEDCouplingSkyLineArray * _face_corresp; - - std::map < std::pair <int,int>, ParaMEDMEM::MEDCouplingSkyLineArray * > _entity_corresp; - }; -} -# endif diff --git a/src/MEDPartitioner/MEDPARTITIONER_Graph.cxx b/src/MEDPartitioner/MEDPARTITIONER_Graph.cxx deleted file mode 100644 index 1904ae4f5..000000000 --- a/src/MEDPartitioner/MEDPARTITIONER_Graph.cxx +++ /dev/null @@ -1,56 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// - -#include "MEDPARTITIONER_Graph.hxx" - -#include "MEDCouplingSkyLineArray.hxx" - -#include <set> - -MEDPARTITIONER::Graph::Graph(ParaMEDMEM::MEDCouplingSkyLineArray *array, int *edgeweight):_graph(array),_partition(0),_edge_weight(edgeweight),_cell_weight(0) -{ -} - -MEDPARTITIONER::Graph::~Graph() -{ - delete _partition; - delete _graph; -} - -int MEDPARTITIONER::Graph::nbDomains() const -{ - std::set<int> domains; - if ( _partition ) - if ( ParaMEDMEM::DataArrayInt* array = _partition->getValueArray() ) - { - for ( const int * dom = array->begin(); dom != array->end(); ++dom ) - domains.insert( *dom ); - } - return domains.size(); -} - -const int *MEDPARTITIONER::Graph::getPart() const -{ - return _partition->getValue(); -} - -int MEDPARTITIONER::Graph::nbVertices() const -{ - return _graph->getNumberOf(); -} diff --git a/src/MEDPartitioner/MEDPARTITIONER_Graph.hxx b/src/MEDPartitioner/MEDPARTITIONER_Graph.hxx deleted file mode 100644 index 12227bdb0..000000000 --- a/src/MEDPartitioner/MEDPARTITIONER_Graph.hxx +++ /dev/null @@ -1,70 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// - -#ifndef __MEDPARTITIONER_GRAPH_HXX__ -#define __MEDPARTITIONER_GRAPH_HXX__ - -#include "MEDPARTITIONER.hxx" - -#include <string> - -namespace ParaMEDMEM -{ - class MEDCouplingSkyLineArray; -} - -namespace MEDPARTITIONER -{ - class ParaDomainSelector; - class MEDPARTITIONER_EXPORT Graph - { - public: - typedef enum {METIS,SCOTCH} splitter_type; - - Graph(){}; - //creates a graph from a SKYLINEARRAY - Graph(ParaMEDMEM::MEDCouplingSkyLineArray* graph, int* edgeweight=0); - virtual ~Graph(); - - void setEdgesWeights(int *edgeweight) { _edge_weight=edgeweight; } - void setVerticesWeights(int *cellweight) { _cell_weight=cellweight; } - - //computes partitioning of the graph - virtual void partGraph(int ndomain, const std::string& options_string="", ParaDomainSelector *sel=0) = 0; - - //returns the partitioning - const int *getPart() const; - - //returns the number of graph vertices (which can correspond to the cells in the mesh!) - int nbVertices() const; - - // returns nb of domains in _partition - int nbDomains() const; - - const ParaMEDMEM::MEDCouplingSkyLineArray *getGraph() const { return _graph; } - const ParaMEDMEM::MEDCouplingSkyLineArray *getPartition() const { return _partition; } - - protected: - ParaMEDMEM::MEDCouplingSkyLineArray* _graph; - ParaMEDMEM::MEDCouplingSkyLineArray* _partition; - int* _edge_weight; - int* _cell_weight; - }; -} -#endif diff --git a/src/MEDPartitioner/MEDPARTITIONER_JointFinder.cxx b/src/MEDPartitioner/MEDPARTITIONER_JointFinder.cxx deleted file mode 100644 index 1e826eac7..000000000 --- a/src/MEDPartitioner/MEDPARTITIONER_JointFinder.cxx +++ /dev/null @@ -1,212 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// - -#include "MEDPARTITIONER_JointFinder.hxx" -#include "MEDPARTITIONER_MeshCollection.hxx" -#include "MEDPARTITIONER_Topology.hxx" -#include "MEDPARTITIONER_ParaDomainSelector.hxx" -#include "MEDPARTITIONER_Utils.hxx" - -#include "MEDCouplingUMesh.hxx" -#include "BBTree.txx" - -/*! - * Method contributing to the distant cell graph - */ -MEDPARTITIONER::JointFinder::JointFinder(const MeshCollection& mc):_mesh_collection(mc),_domain_selector(mc.getParaDomainSelector()),_topology(mc.getTopology()) -{ -} - -MEDPARTITIONER::JointFinder::~JointFinder() -{ -} - -void MEDPARTITIONER::JointFinder::findCommonDistantNodes() -{ - int nbdomain=_topology->nbDomain(); - _distant_node_cell.resize(nbdomain); - _node_node.resize(nbdomain); - for (int i=0; i<nbdomain; i++) - { - _distant_node_cell[i].resize(nbdomain); - _node_node[i].resize(nbdomain); - } - int nbproc=_domain_selector->nbProcs(); - std::vector<BBTreeOfDim* > bbtree(nbdomain,(BBTreeOfDim*) 0); - std::vector<double* > bbxi(nbdomain,(double*) 0); - std::vector<ParaMEDMEM::DataArrayInt*> rev(nbdomain,(ParaMEDMEM::DataArrayInt*) 0); - std::vector<ParaMEDMEM::DataArrayInt*> revIndx(nbdomain,(ParaMEDMEM::DataArrayInt*) 0); - int meshDim=-1; - int spaceDim=-1; - - //init rev and revIndx and bbtree for my domain (of me:proc n) - for (int mydomain=0; mydomain<nbdomain; mydomain++) - { - if(!_domain_selector->isMyDomain(mydomain)) - continue; - const ParaMEDMEM::MEDCouplingUMesh* myMesh=_mesh_collection.getMesh(mydomain); - meshDim = myMesh->getMeshDimension(); - spaceDim= myMesh->getSpaceDimension(); - rev[mydomain] = ParaMEDMEM::DataArrayInt::New(); - revIndx[mydomain] = ParaMEDMEM::DataArrayInt::New(); - myMesh->getReverseNodalConnectivity(rev[mydomain],revIndx[mydomain]); - double* bbx=new double[2*spaceDim*myMesh->getNumberOfNodes()]; - for (int i=0; i<myMesh->getNumberOfNodes()*spaceDim; i++) - { - const double* coords=myMesh->getCoords()->getConstPointer(); - bbx[2*i]=(coords[i])-1e-12; - bbx[2*i+1]=bbx[2*i]+2e-12; - } - bbtree[mydomain]=new BBTreeOfDim( spaceDim, bbx,0,0,myMesh->getNumberOfNodes(),-1e-12); - //keep bbx because need it in getIntersectingElems - //no delete [] bbx yet - bbxi[mydomain]=bbx; - } - - //send my domains to other proc an receive other domains from other proc - for (int isource=0; isource<nbdomain; isource++) - { - for (int itarget=0; itarget<nbdomain; itarget++) - { - const ParaMEDMEM::MEDCouplingUMesh* sourceMesh=_mesh_collection.getMesh(isource); - if (_domain_selector->isMyDomain(isource)&&_domain_selector->isMyDomain(itarget)) - continue; - if (_domain_selector->isMyDomain(isource)) - { - //preparing data for treatment on target proc - int targetProc = _domain_selector->getProcessorID(itarget); - - std::vector<double> vec(spaceDim*sourceMesh->getNumberOfNodes()); - std::copy(sourceMesh->getCoords()->getConstPointer(),sourceMesh->getCoords()->getConstPointer()+sourceMesh->getNumberOfNodes()*spaceDim,&vec[0]); - SendDoubleVec(vec,targetProc); - - //retrieving target data for storage in commonDistantNodes array - std::vector<int> localCorrespondency; - RecvIntVec(localCorrespondency, targetProc); - for (std::size_t i=0; i<localCorrespondency.size()/2; i++) - { - _distant_node_cell[isource][itarget].insert(std::make_pair(localCorrespondency[2*i],localCorrespondency[2*i+1])); - } - - } - - if (_domain_selector->isMyDomain(itarget)) - { - //receiving data from source proc - int sourceProc = isource%nbproc; - std::vector<double> recvVec; - RecvDoubleVec(recvVec,sourceProc); - std::map<int,int> commonNodes; // (local nodes, distant nodes) list - for (int inode=0; inode<(recvVec.size()/spaceDim); inode++) - { - double* bbox=new double[2*spaceDim]; - for (int i=0; i<spaceDim; i++) - { - bbox[2*i]=recvVec[inode*spaceDim+i]-1e-12; - bbox[2*i+1]=bbox[2*i]+2e-12; - } - std::vector<int> inodes; - bbtree[itarget]->getIntersectingElems(bbox,inodes); - delete [] bbox; - - if (inodes.size()>0) - { - commonNodes.insert(std::make_pair(inodes[0],inode)); - } - - } - std::vector<int> nodeCellCorrespondency; - for (std::map<int,int>::iterator iter=commonNodes.begin(); iter!=commonNodes.end(); iter++) - { - _node_node[itarget][isource].push_back(std::make_pair(iter->first, iter->second));//storing node pairs in a vector - const int* revIndxPtr=revIndx[itarget]->getConstPointer(); - const int* revPtr=rev[itarget]->getConstPointer(); - for (int icell=revIndxPtr[iter->first]; icell<revIndxPtr[iter->first+1]; icell++) - { - nodeCellCorrespondency.push_back(iter->second); // - int globalCell=_topology->convertCellToGlobal(itarget,revPtr[icell]); - nodeCellCorrespondency.push_back(globalCell); - } - } - SendIntVec(nodeCellCorrespondency, sourceProc); //itarget proc send to other (otherLocalNode-itargetGlobalCell) - } - } - } - - //free rev(nbdomain) revIndx(nbdomain) bbtree(nbdomain) bbxi(nbdomain) - for (int i=0; i<nbdomain; i++) - { - if (rev[i]!=0) - rev[i]->decrRef(); - if (revIndx[i]!=0) - revIndx[i]->decrRef(); - if (bbtree[i]!=0) - delete bbtree[i]; - if (bbxi[i]!=0) - delete [] bbxi[i]; - } - - if (MyGlobals::_Verbose>100) - std::cout << "proc " << _domain_selector->rank() << " : end JointFinder::findCommonDistantNodes" << std::endl; -} - -std::vector<std::vector<std::multimap<int,int> > >& MEDPARTITIONER::JointFinder::getDistantNodeCell() -{ - return _distant_node_cell; -} - -std::vector<std::vector<std::vector<std::pair<int,int> > > >& MEDPARTITIONER::JointFinder::getNodeNode() -{ - return _node_node; -} - -void MEDPARTITIONER::JointFinder::print() -//it is for debug on small arrays under mpi 2,3 cpus -{ - int nbdomain=_topology->nbDomain(); - //MPI_Barrier(MPI_COMM_WORLD); - if (MyGlobals::_Is0verbose>0) - std::cout << "\nJointFinder print node-node (nn)iproc|itarget|isource|i|inodefirst-inodesecond\n\n" << - "JointFinder print distantNode=cell (nc)iproc|itarget|isource|inode=icell\n\n"; - for (int isource=0; isource<nbdomain; isource++) - { - for (int itarget=0; itarget<nbdomain; itarget++) - { - for (std::size_t i=0; i<_node_node[itarget][isource].size(); i++) - std::cout << " nn" << _domain_selector->rank() << itarget << "|" << isource << "|" << i << "|" << - _node_node[itarget][isource][i].first << "-" << - _node_node[itarget][isource][i].second; - } - } - std::cout<<std::endl; - //MPI_Barrier(MPI_COMM_WORLD); - for (int isource=0; isource<nbdomain; isource++) - { - for (int itarget=0; itarget<nbdomain; itarget++) - { - std::multimap<int,int>::iterator it; - for (it=_distant_node_cell[isource][itarget].begin() ; it!=_distant_node_cell[isource][itarget].end(); it++) - { - std::cout << " nc" << _domain_selector->rank() << "|" << itarget << "|" << isource << "|" << (*it).first << "=" << (*it).second; - } - } - } - std::cout << std::endl; - //MPI_Barrier(MPI_COMM_WORLD); -} diff --git a/src/MEDPartitioner/MEDPARTITIONER_JointFinder.hxx b/src/MEDPartitioner/MEDPARTITIONER_JointFinder.hxx deleted file mode 100644 index 4fcc9ace6..000000000 --- a/src/MEDPartitioner/MEDPARTITIONER_JointFinder.hxx +++ /dev/null @@ -1,52 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// - -#ifndef __MEDPARTITIONER_JOINTFINDER_HXX__ -#define __MEDPARTITIONER_JOINTFINDER_HXX__ - -#include "MEDPARTITIONER.hxx" - -#include <map> -#include <vector> - -namespace MEDPARTITIONER -{ - class Topology; - class MeshCollection; - class ParaDomainSelector; - - class MEDPARTITIONER_EXPORT JointFinder - { - public: - JointFinder(const MeshCollection& mc); - ~JointFinder(); - void findCommonDistantNodes(); - void print(); - std::vector<std::vector<std::multimap<int,int> > >& getDistantNodeCell(); - std::vector<std::vector<std::vector<std::pair<int,int> > > >& getNodeNode(); - private: - const MeshCollection& _mesh_collection; - const ParaDomainSelector *_domain_selector; - const Topology *_topology; - std::vector<std::vector<std::multimap<int,int> > > _distant_node_cell; - std::vector<std::vector<std::vector<std::pair<int,int> > > > _node_node; - - }; -} -#endif diff --git a/src/MEDPartitioner/MEDPARTITIONER_MEDPartitioner.cxx b/src/MEDPartitioner/MEDPARTITIONER_MEDPartitioner.cxx deleted file mode 100644 index 57e9ae919..000000000 --- a/src/MEDPartitioner/MEDPARTITIONER_MEDPartitioner.cxx +++ /dev/null @@ -1,161 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// - -#include "MEDPARTITIONER_MEDPartitioner.hxx" -#include "MEDPARTITIONER_MeshCollection.hxx" -#include "MEDPARTITIONER_Topology.hxx" -#include "MEDPARTITIONER_ParaDomainSelector.hxx" -#include "MEDPARTITIONER_ParallelTopology.hxx" -#include "MEDPARTITIONER_Utils.hxx" -#include "MEDPARTITIONER_Graph.hxx" -#include "MEDPARTITIONER_MetisGraph.hxx" -#include "MEDPARTITIONER_ScotchGraph.hxx" -#include "MEDPARTITIONER_MeshCollectionDriver.hxx" - -#include "MEDCouplingUMesh.hxx" -#include "MEDCouplingSkyLineArray.hxx" - -#include <iostream> -#include <vector> - -MEDPARTITIONER::MEDPartitioner::MEDPartitioner(const std::string& filename, int ndomains, const std::string& library,bool creates_boundary_faces, bool create_joints, bool mesure_memory): - _input_collection( 0 ), _output_collection( 0 ), _new_topology( 0 ) -{ - MyGlobals::_World_Size = 1; - MyGlobals::_Rank = 0; - MyGlobals::_Creates_Boundary_Faces = creates_boundary_faces; - MyGlobals::_Create_Joints = create_joints; - - ParaDomainSelector parallelizer(mesure_memory); - _input_collection=new MeshCollection(filename,parallelizer); - _input_collection->setParaDomainSelector( ¶llelizer ); - - MEDPARTITIONER::ParallelTopology* aPT = - (MEDPARTITIONER::ParallelTopology*) _input_collection->getTopology(); - aPT->setGlobalNumerotationDefault( _input_collection->getParaDomainSelector() ); - _input_collection->prepareFieldDescriptions(); - createPartitionCollection(ndomains, library, creates_boundary_faces, create_joints, mesure_memory); - - parallelizer.evaluateMemory(); -} - -MEDPARTITIONER::MEDPartitioner::MEDPartitioner(const ParaMEDMEM::MEDFileData* filedata, int ndomains, const std::string& library,bool creates_boundary_faces, bool create_joints, bool mesure_memory): - _input_collection( 0 ), _output_collection( 0 ), _new_topology( 0 ) -{ - MyGlobals::_World_Size = 1; - MyGlobals::_Rank = 0; - MyGlobals::_Creates_Boundary_Faces = creates_boundary_faces; - MyGlobals::_Create_Joints = create_joints; - - ParaDomainSelector parallelizer(mesure_memory); - _input_collection=new MeshCollection(); - _input_collection->setParaDomainSelector( ¶llelizer ); - _input_collection->retrieveDriver()->readMEDFileData(filedata); - - MEDPARTITIONER::ParallelTopology* aPT = - (MEDPARTITIONER::ParallelTopology*) _input_collection->getTopology(); - aPT->setGlobalNumerotationDefault( _input_collection->getParaDomainSelector() ); - _input_collection->prepareFieldDescriptions(); - createPartitionCollection(ndomains, library, creates_boundary_faces, create_joints, mesure_memory); - - parallelizer.evaluateMemory(); -} - -MEDPARTITIONER::MEDPartitioner::MEDPartitioner(const ParaMEDMEM::MEDFileData* filedata, MEDPARTITIONER ::Graph* graph, bool creates_boundary_faces, bool create_joints, bool mesure_memory): - _input_collection( 0 ), _output_collection( 0 ), _new_topology( 0 ) -{ - MyGlobals::_World_Size = 1; - MyGlobals::_Rank = 0; - MyGlobals::_Creates_Boundary_Faces = creates_boundary_faces; - MyGlobals::_Create_Joints = create_joints; - - ParaDomainSelector parallelizer(mesure_memory); - _input_collection=new MeshCollection(); - _input_collection->setParaDomainSelector( ¶llelizer ); - _input_collection->retrieveDriver()->readMEDFileData(filedata); - - MEDPARTITIONER::ParallelTopology* aPT = - (MEDPARTITIONER::ParallelTopology*) _input_collection->getTopology(); - aPT->setGlobalNumerotationDefault( _input_collection->getParaDomainSelector() ); - _input_collection->prepareFieldDescriptions(); - - _new_topology = new MEDPARTITIONER::ParallelTopology( graph, aPT, graph->nbDomains(), _input_collection->getMeshDimension() ); - _output_collection=new MeshCollection(*_input_collection,_new_topology,false,false); - _output_collection->filterFaceOnCell(); - - parallelizer.evaluateMemory(); -} - -MEDPARTITIONER::MEDPartitioner::~MEDPartitioner() -{ - delete _input_collection; _input_collection = 0; - delete _output_collection; _output_collection = 0; - delete _new_topology; _new_topology = 0; -} - -void MEDPARTITIONER::MEDPartitioner::createPartitionCollection(int ndomains, const std::string& library,bool creates_boundary_faces, bool create_joints, bool mesure_memory) -{ - //ParallelTopology* aPT = (ParallelTopology*) _input_collection->getTopology(); - if (library == "metis") - _new_topology = _input_collection->createPartition(ndomains,MEDPARTITIONER::Graph::METIS); - else - _new_topology = _input_collection->createPartition(ndomains,MEDPARTITIONER::Graph::SCOTCH); - _output_collection=new MeshCollection(*_input_collection,_new_topology,false,false); - _output_collection->filterFaceOnCell(); -} - -void MEDPARTITIONER::MEDPartitioner::write(const std::string& filename) -{ - ParaDomainSelector parallelizer(false); - _output_collection->setParaDomainSelector( ¶llelizer ); - _output_collection->write(filename); - parallelizer.evaluateMemory(); -} - -ParaMEDMEM::MEDFileData* MEDPARTITIONER::MEDPartitioner::getMEDFileData() -{ - return _output_collection->retrieveDriver()->getMEDFileData(); -} - -MEDPARTITIONER::Graph* MEDPARTITIONER::MEDPartitioner::Graph(ParaMEDMEM::MEDCouplingSkyLineArray* graph, Graph::splitter_type split, int* edgeweight) -{ - MEDPARTITIONER::Graph* cellGraph=0; - ParaMEDMEM::MEDCouplingSkyLineArray* arr = new ParaMEDMEM::MEDCouplingSkyLineArray(graph->getIndexArray(), graph->getValueArray()); - switch (split) - { - case Graph::METIS: - if ( !cellGraph ) - { -#ifdef MED_ENABLE_METIS - cellGraph=new METISGraph(arr,edgeweight); -#endif - } - if ( !cellGraph ) - throw INTERP_KERNEL::Exception("MEDPartitioner::Graph : PARMETIS/METIS is not available. Check your products, please."); - break; - case Graph::SCOTCH: -#ifdef MED_ENABLE_SCOTCH - cellGraph=new SCOTCHGraph(arr,edgeweight); -#else - throw INTERP_KERNEL::Exception("MEDPartitioner::Graph : SCOTCH is not available. Check your products, please."); -#endif - break; - } - return cellGraph; -} diff --git a/src/MEDPartitioner/MEDPARTITIONER_MEDPartitioner.hxx b/src/MEDPartitioner/MEDPARTITIONER_MEDPartitioner.hxx deleted file mode 100644 index fecaf0cc9..000000000 --- a/src/MEDPartitioner/MEDPARTITIONER_MEDPartitioner.hxx +++ /dev/null @@ -1,59 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// - -#ifndef __MEDPARTITIONER_MEDPARTITIONER_HXX__ -#define __MEDPARTITIONER_MEDPARTITIONER_HXX__ - -#include "MEDPARTITIONER.hxx" -#include "MEDPARTITIONER_Graph.hxx" - -#include <map> -#include <vector> - -namespace ParaMEDMEM -{ - class MEDFileData; -} - -namespace MEDPARTITIONER -{ - class Topology; - class MeshCollection; - - class MEDPARTITIONER_EXPORT MEDPartitioner - { - public: - MEDPartitioner(const std::string& filename, int ndomains=1, const std::string& library="metis",bool creates_boundary_faces=false, bool create_joints=false, bool mesure_memory=false); - MEDPartitioner(const ParaMEDMEM::MEDFileData* fileData, int ndomains=1, const std::string& library="metis",bool creates_boundary_faces=false, bool create_joints=false, bool mesure_memory=false); - MEDPartitioner(const ParaMEDMEM::MEDFileData* fileData, Graph* graph, bool creates_boundary_faces=false, bool create_joints=false, bool mesure_memory=false); - static MEDPARTITIONER::Graph* Graph(ParaMEDMEM::MEDCouplingSkyLineArray* graph, Graph::splitter_type split=Graph::METIS, int* edgeweight=0); - void write(const std::string& filename); - ParaMEDMEM::MEDFileData* getMEDFileData(); - ~MEDPartitioner(); - - ParaMEDMEM::MEDFileData *convertToMEDFileData(MeshCollection* meshcollection); - void createPartitionCollection(int ndomains, const std::string& library,bool creates_boundary_faces, bool create_joints, bool mesure_memory); - - private: - MeshCollection* _input_collection; - MeshCollection* _output_collection; - Topology* _new_topology; - }; -} -#endif diff --git a/src/MEDPartitioner/MEDPARTITIONER_MeshCollection.cxx b/src/MEDPartitioner/MEDPARTITIONER_MeshCollection.cxx deleted file mode 100644 index d0ad9d4cb..000000000 --- a/src/MEDPartitioner/MEDPARTITIONER_MeshCollection.cxx +++ /dev/null @@ -1,2459 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// - -#include "MEDPARTITIONER_MeshCollection.hxx" - -#include "MEDPARTITIONER_ConnectZone.hxx" -#include "MEDPARTITIONER_Graph.hxx" -#include "MEDPARTITIONER_MeshCollectionDriver.hxx" -#include "MEDPARTITIONER_MeshCollectionMedAsciiDriver.hxx" -#include "MEDPARTITIONER_MeshCollectionMedXmlDriver.hxx" -#include "MEDPARTITIONER_ParaDomainSelector.hxx" -#include "MEDPARTITIONER_ParallelTopology.hxx" -#include "MEDPARTITIONER_Topology.hxx" -#include "MEDPARTITIONER_UserGraph.hxx" -#include "MEDPARTITIONER_Utils.hxx" - -#ifdef HAVE_MPI -#include "MEDPARTITIONER_JointFinder.hxx" -#endif - -#include "MEDCouplingAutoRefCountObjectPtr.hxx" -#include "MEDCouplingFieldDouble.hxx" -#include "MEDCouplingMemArray.hxx" -#include "MEDCouplingNormalizedUnstructuredMesh.hxx" -#include "MEDCouplingSkyLineArray.hxx" -#include "MEDCouplingUMesh.hxx" -#include "MEDLoader.hxx" -#include "MEDLoaderBase.hxx" - -#ifdef HAVE_MPI -#include <mpi.h> -#endif - -#ifdef MED_ENABLE_PARMETIS -#include "MEDPARTITIONER_ParMetisGraph.hxx" -#endif -#ifdef MED_ENABLE_METIS -#include "MEDPARTITIONER_MetisGraph.hxx" -#endif -#ifdef MED_ENABLE_SCOTCH -#include "MEDPARTITIONER_ScotchGraph.hxx" -#endif - -#include <set> -#include <vector> -#include <string> -#include <limits> -#include <iostream> -#include <fstream> - -MEDPARTITIONER::MeshCollection::MeshCollection() - : _topology(0), - _owns_topology(false), - _driver(0), - _domain_selector( 0 ), - _i_non_empty_mesh(-1), - _driver_type(MEDPARTITIONER::MedXml), - _subdomain_boundary_creates( MyGlobals::_Creates_Boundary_Faces ), - _family_splitting(false), - _create_empty_groups(false), - _joint_finder(0) -{ -} - -/*!constructor creating a new mesh collection (mesh series + topology) - *from an old collection and a new topology - * - * On output, the constructor has built the meshes corresponding to the new mesh collection. - * The new topology has been updated so that face and node mappings are included. - * The families have been cast to their projections in the new topology. - * - * \param initial_collection collection from which the data (coordinates, connectivity) are taken - * \param topology topology containing the cell mappings - */ - -MEDPARTITIONER::MeshCollection::MeshCollection(MeshCollection& initialCollection, - Topology* topology, - bool family_splitting, - bool create_empty_groups) - : _topology(topology), - _owns_topology(false), - _driver(0), - _domain_selector( initialCollection._domain_selector ), - _i_non_empty_mesh(-1), - _name(initialCollection._name), - _driver_type(MEDPARTITIONER::MedXml), - _subdomain_boundary_creates(MyGlobals::_Creates_Boundary_Faces), - _family_splitting(family_splitting), - _create_empty_groups(create_empty_groups), - _joint_finder(0) -{ - std::vector<std::vector<std::vector<int> > > new2oldIds(initialCollection.getTopology()->nbDomain()); - std::vector<ParaMEDMEM::DataArrayInt*> o2nRenumber; - - castCellMeshes(initialCollection, new2oldIds, o2nRenumber ); - - //defining the name for the collection and the underlying meshes - setName(initialCollection.getName()); - - ///////////////// - //treating faces - ///////////////// - -#ifdef HAVE_MPI - if (MyGlobals::_Verbose>0 && MyGlobals::_World_Size>1) - MPI_Barrier(MPI_COMM_WORLD); //synchronize verbose messages -#endif - if (MyGlobals::_Is0verbose) - std::cout<<"treating faces"<<std::endl; - NodeMapping nodeMapping; - //nodeMapping contains the mapping between old nodes and new nodes - // (iolddomain,ioldnode)->(inewdomain,inewnode) - createNodeMapping(initialCollection, nodeMapping); - std::vector<std::vector<std::vector<int> > > new2oldFaceIds; - castFaceMeshes(initialCollection, nodeMapping, new2oldFaceIds); - - //////////////////// - //treating families - //////////////////// -#ifdef HAVE_MPI - if (MyGlobals::_Verbose>0 && MyGlobals::_World_Size>1) - MPI_Barrier(MPI_COMM_WORLD); //synchronize verbose messages -#endif - if (MyGlobals::_Is0verbose) - { - if (isParallelMode()) - std::cout << "ParallelMode on " << topology->nbDomain() << " Domains" << std::endl; - else - std::cout << "NOT ParallelMode on " << topology->nbDomain() << " Domains" << std::endl; - } - if (MyGlobals::_Is0verbose>10) - std::cout<<"treating cell and face families"<<std::endl; - - castIntField(initialCollection.getMesh(), - this->getMesh(), - initialCollection.getCellFamilyIds(), - "cellFamily"); - castIntField(initialCollection.getFaceMesh(), - this->getFaceMesh(), - initialCollection.getFaceFamilyIds(), - "faceFamily"); - - //treating groups -#ifdef HAVE_MPI - if (MyGlobals::_Verbose>0 && MyGlobals::_World_Size>1) - MPI_Barrier(MPI_COMM_WORLD); //synchronize verbose messages -#endif - if (MyGlobals::_Is0verbose) - std::cout << "treating groups" << std::endl; - _family_info=initialCollection.getFamilyInfo(); - _group_info=initialCollection.getGroupInfo(); - -#ifdef HAVE_MPI - if (MyGlobals::_Verbose>0 && MyGlobals::_World_Size>1) - MPI_Barrier(MPI_COMM_WORLD); //synchronize verbose messages -#endif - if (MyGlobals::_Is0verbose) - std::cout << "treating fields" << std::endl; - castAllFields(initialCollection,"cellFieldDouble"); - if (_i_non_empty_mesh<0) - { - for (size_t i=0; i<_mesh.size(); i++) - { - if (_mesh[i]) - { - _i_non_empty_mesh=i; //first existing one local - break; - } - } - } - - // find faces common with neighbor domains and put them in groups - buildBoundaryFaces(); - - //building the connect zones necessary for writing joints - buildConnectZones( nodeMapping, o2nRenumber, initialCollection.getTopology()->nbDomain() ); - - // delete o2nRenumber - for ( size_t i = 0; i < o2nRenumber.size(); ++i ) - if ( o2nRenumber[i] ) - o2nRenumber[i]->decrRef(); -} - -/*! - Creates the meshes using the topology underlying he mesh collection and the mesh data - coming from the ancient collection - \param initialCollection collection from which the data is extracted to create the new meshes - \param [out] o2nRenumber returns for each new domain a permutation array returned by sortCellsInMEDFileFrmt() -*/ - -void MEDPARTITIONER::MeshCollection::castCellMeshes(MeshCollection& initialCollection, - std::vector<std::vector<std::vector<int> > >& new2oldIds, - std::vector<ParaMEDMEM::DataArrayInt*> & o2nRenumber) -{ - if (MyGlobals::_Verbose>10) - std::cout << "proc " << MyGlobals::_Rank << " : castCellMeshes" << std::endl; - if (_topology==0) - throw INTERP_KERNEL::Exception("Topology has not been defined on call to castCellMeshes"); - - int nbNewDomain=_topology->nbDomain(); - int nbOldDomain=initialCollection.getTopology()->nbDomain(); - - _mesh.resize(nbNewDomain); - o2nRenumber.resize(nbNewDomain,0); - int rank=MyGlobals::_Rank; - //splitting the initial domains into smaller bits - std::vector<std::vector<ParaMEDMEM::MEDCouplingUMesh*> > splitMeshes; - splitMeshes.resize(nbNewDomain); - for (int inew=0; inew<nbNewDomain; inew++) - { - splitMeshes[inew].resize(nbOldDomain, (ParaMEDMEM::MEDCouplingUMesh*)0); - } - - for (int iold=0; iold<nbOldDomain; iold++) - { - if (!isParallelMode() || initialCollection._domain_selector->isMyDomain(iold)) - { - int size=(initialCollection._mesh)[iold]->getNumberOfCells(); - std::vector<int> globalids(size); - initialCollection.getTopology()->getCellList(iold, &globalids[0]); - std::vector<int> ilocalnew(size); //local - std::vector<int> ipnew(size); //idomain old - _topology->convertGlobalCellList(&globalids[0],size,&ilocalnew[0],&ipnew[0]); - - new2oldIds[iold].resize(nbNewDomain); - for (int i=0; i<(int)ilocalnew.size(); i++) - { - new2oldIds[iold][ipnew[i]].push_back(i); - } - for (int inew=0; inew<nbNewDomain; inew++) - { - splitMeshes[inew][iold]=(ParaMEDMEM::MEDCouplingUMesh*) - (initialCollection.getMesh())[iold]->buildPartOfMySelf(&new2oldIds[iold][inew][0], - &new2oldIds[iold][inew][0]+new2oldIds[iold][inew].size(), - true); - if (MyGlobals::_Verbose>400) - std::cout<< "proc " << rank << " : a splitMesh iold inew NbCells " << iold << " " << inew << " " - << splitMeshes[inew][iold]->getNumberOfCells() << std::endl; - } - } - } -#ifdef HAVE_MPI - if (isParallelMode()) - { - //if (MyGlobals::_Verbose>300) std::cout<<"proc "<<rank<<" : castCellMeshes send/receive"<<std::endl; - for (int iold=0; iold<nbOldDomain; iold++) - for(int inew=0; inew<nbNewDomain; inew++) - { - if (initialCollection._domain_selector->isMyDomain(iold) && _domain_selector->isMyDomain(inew)) - continue; - - if(initialCollection._domain_selector->isMyDomain(iold)) - _domain_selector->sendMesh(*(splitMeshes[inew][iold]),_domain_selector->getProcessorID(inew)); - - if (_domain_selector->isMyDomain(inew)) - _domain_selector->recvMesh(splitMeshes[inew][iold],_domain_selector->getProcessorID(iold)); - - } - } -#endif - - //fusing the split meshes - if (MyGlobals::_Verbose>200) - std::cout << "proc " << rank << " : castCellMeshes fusing" << std::endl; - for (int inew=0; inew<nbNewDomain ;inew++) - { - std::vector<const ParaMEDMEM::MEDCouplingUMesh*> meshes; - - for (int i=0; i<(int)splitMeshes[inew].size(); i++) - if (splitMeshes[inew][i]!=0) - if (splitMeshes[inew][i]->getNumberOfCells()>0) - meshes.push_back(splitMeshes[inew][i]); - - if (!isParallelMode()||_domain_selector->isMyDomain(inew)) - { - if (meshes.size()==0) - { - _mesh[inew]=CreateEmptyMEDCouplingUMesh(); - std::cout << "WARNING : castCellMeshes fusing : no meshes try another number of processors" << std::endl; - } - else - { - _mesh[inew]=ParaMEDMEM::MEDCouplingUMesh::MergeUMeshes(meshes); - o2nRenumber[inew]=_mesh[inew]->sortCellsInMEDFileFrmt(); - bool areNodesMerged; - int nbNodesMerged; - if (meshes.size()>1) - { - ParaMEDMEM::DataArrayInt* array=_mesh[inew]->mergeNodes(1e-12,areNodesMerged,nbNodesMerged); - array->decrRef(); // array is not used in this case - } - _mesh[inew]->zipCoords(); - } - } - for (int i=0;i<(int)splitMeshes[inew].size();i++) - if (splitMeshes[inew][i]!=0) - splitMeshes[inew][i]->decrRef(); - } - if (MyGlobals::_Verbose>300) - std::cout << "proc " << rank << " : castCellMeshes end fusing" << std::endl; -} - -/*! - \param initialCollection source mesh collection - \param nodeMapping structure containing the correspondency between nodes in the initial collection and the node(s) in the new collection -*/ -void MEDPARTITIONER::MeshCollection::createNodeMapping( MeshCollection& initialCollection, NodeMapping& nodeMapping) -{ - using std::vector; - using std::make_pair; - // NodeMapping reverseNodeMapping; - for (int iold=0; iold<initialCollection.getTopology()->nbDomain();iold++) - { - - double* bbox; - BBTreeOfDim* tree = 0; - int dim = 3; - if (!isParallelMode() || (_domain_selector->isMyDomain(iold))) - { - // std::map<pair<double,pair<double, double> >, int > nodeClassifier; - ParaMEDMEM::DataArrayDouble* coords = initialCollection.getMesh(iold)->getCoords(); - double* coordsPtr=coords->getPointer(); - dim = coords->getNumberOfComponents(); - int nvertices=initialCollection.getMesh(iold)->getNumberOfNodes(); - bbox=new double[nvertices*2*dim]; - - for (int i=0; i<nvertices*dim;i++) - { - bbox[i*2]=coordsPtr[i]-1e-8; - bbox[i*2+1]=coordsPtr[i]+1e-8; - } - tree=new BBTreeOfDim( dim, bbox,0,0,nvertices,1e-9); - } - - for (int inew=0; inew<_topology->nbDomain(); inew++) - { -#ifdef HAVE_MPI - //sending meshes for parallel computation - if (isParallelMode() && _domain_selector->isMyDomain(inew) && !_domain_selector->isMyDomain(iold)) - _domain_selector->sendMesh(*(getMesh(inew)), _domain_selector->getProcessorID(iold)); - else if (isParallelMode() && !_domain_selector->isMyDomain(inew)&& _domain_selector->isMyDomain(iold)) - { - ParaMEDMEM::MEDCouplingUMesh* mesh; - _domain_selector->recvMesh(mesh, _domain_selector->getProcessorID(inew)); - ParaMEDMEM::DataArrayDouble* coords = mesh->getCoords(); - for (int inode=0; inode<mesh->getNumberOfNodes();inode++) - { - double* coordsPtr=coords->getPointer()+inode*dim; - vector<int> elems; - tree->getElementsAroundPoint(coordsPtr,elems); - if (elems.size()==0) continue; - nodeMapping.insert(make_pair(make_pair(iold,elems[0]),make_pair(inew,inode))); - } - mesh->decrRef(); - } - else if (!isParallelMode() || (_domain_selector->isMyDomain(inew) && _domain_selector->isMyDomain(iold))) -#else - if (!isParallelMode() || (_domain_selector->isMyDomain(inew) && _domain_selector->isMyDomain(iold))) -#endif - { - ParaMEDMEM::DataArrayDouble* coords = getMesh(inew)->getCoords(); - for (int inode=0; inode<_mesh[inew]->getNumberOfNodes();inode++) - { - double* coordsPtr=coords->getPointer()+inode*dim; - vector<int> elems; - tree->getElementsAroundPoint(coordsPtr,elems); - if (elems.size()==0) continue; - nodeMapping.insert(make_pair(make_pair(iold,elems[0]),make_pair(inew,inode))); - } - } - } - if (!isParallelMode() || (_domain_selector->isMyDomain(iold))) - { - delete tree; - delete[] bbox; - } - } - -} - -void getNodeIds(ParaMEDMEM::MEDCouplingUMesh& meshOne, ParaMEDMEM::MEDCouplingUMesh& meshTwo, std::vector<int>& nodeIds) -{ - using std::vector; - using MEDPARTITIONER::BBTreeOfDim; - if (!&meshOne || !&meshTwo) return; //empty or not existing - double* bbox; - BBTreeOfDim* tree = 0; - int nv1=meshOne.getNumberOfNodes(); - ParaMEDMEM::DataArrayDouble* coords=meshOne.getCoords(); - int dim = coords->getNumberOfComponents(); - - bbox=new double[nv1*2*dim]; - double* coordsPtr=coords->getPointer(); - for (int i=0; i<nv1*dim; i++) - { - bbox[i*2]=coordsPtr[i]-1e-8; - bbox[i*2+1]=coordsPtr[i]+1e-8; - } - tree=new BBTreeOfDim( dim, bbox,0,0,nv1,1e-9); - - int nv2=meshTwo.getNumberOfNodes(); - nodeIds.resize(nv2,-1); - coords=meshTwo.getCoords(); - for (int inode=0; inode<nv2; inode++) - { - double* coordsPtr2=coords->getPointer()+inode*dim; - vector<int> elems; - tree->getElementsAroundPoint(coordsPtr2,elems); - if (elems.size()==0) continue; - nodeIds[inode]=elems[0]; - } - delete tree; - delete[] bbox; -} - -/*! - creates the face meshes on the new domains from the faces on the old domain and the node mapping - faces at the interface are duplicated -*/ -void MEDPARTITIONER::MeshCollection::castFaceMeshes(MeshCollection& initialCollection, - const std::multimap<std::pair<int,int>, std::pair<int,int> >& nodeMapping, - std::vector<std::vector<std::vector<int> > >& new2oldIds) -{ - //splitMeshes structure will contain the partition of - //the old faces on the new ones - //splitMeshes[4][2] contains the faces from old domain 2 - //that have to be added to domain 4 - - using std::vector; - using std::map; - using std::multimap; - using std::pair; - using std::make_pair; - - if (MyGlobals::_Verbose>10) - std::cout << "proc " << MyGlobals::_Rank << " : castFaceMeshes" << std::endl; - if (_topology==0) - throw INTERP_KERNEL::Exception("Topology has not been defined on call to castFaceMeshes"); - - int nbNewDomain=_topology->nbDomain(); - int nbOldDomain=initialCollection.getTopology()->nbDomain(); - - vector<ParaMEDMEM::MEDCouplingUMesh*>& meshesCastFrom=initialCollection.getFaceMesh(); - vector<ParaMEDMEM::MEDCouplingUMesh*>& meshesCastTo=this->getFaceMesh(); - - vector< vector<ParaMEDMEM::MEDCouplingUMesh*> > splitMeshes; - - splitMeshes.resize(nbNewDomain); - for (int inew=0; inew<nbNewDomain; inew++) - { - splitMeshes[inew].resize(nbOldDomain, (ParaMEDMEM::MEDCouplingUMesh*)0); - } - new2oldIds.resize(nbOldDomain); - for (int iold=0; iold<nbOldDomain; iold++) new2oldIds[iold].resize(nbNewDomain); - - //init null pointer for empty meshes - for (int inew=0; inew<nbNewDomain; inew++) - { - for (int iold=0; iold<nbOldDomain; iold++) - { - splitMeshes[inew][iold]=0; //null for empty meshes - new2oldIds[iold][inew].clear(); - } - } - - //loop over the old domains to analyse the faces and decide - //on which new domain they belong - for (int iold=0; iold<nbOldDomain; iold++) - { - if (isParallelMode() && !initialCollection._domain_selector->isMyDomain(iold)) continue; - if (MyGlobals::_Verbose>400) - std::cout<<"proc "<<MyGlobals::_Rank<<" : castFaceMeshes iodDomain "<<iold<<std::endl; - //initial face mesh known : in my domain - if (meshesCastFrom[iold] != 0) - { - for (int ielem=0; ielem<meshesCastFrom[iold]->getNumberOfCells(); ielem++) - { - vector<int> nodes; - meshesCastFrom[iold]->getNodeIdsOfCell(ielem,nodes); - - map <int,int> faces; - - //analysis of element ielem - //counters are set for the element - //for each source node, the mapping is interrogated and the domain counters - //are incremented for each target node - //the face is considered as going to target domains if the counter of the domain - //is equal to the number of nodes - for (int inode=0; inode<(int)nodes.size(); inode++) - { - typedef multimap<pair<int,int>,pair<int,int> >::const_iterator MI; - int mynode=nodes[inode]; - - pair <MI,MI> myRange = nodeMapping.equal_range(make_pair(iold,mynode)); - for (MI iter=myRange.first; iter!=myRange.second; iter++) - { - int inew=iter->second.first; - if (faces.find(inew)==faces.end()) - faces[inew]=1; - else - faces[inew]++; - } - } - - for (map<int,int>::iterator iter=faces.begin(); iter!=faces.end(); iter++) - { - if (iter->second==(int)nodes.size()) - //cvw eligible but may be have to be face of a cell of this->getMesh()[inew]? - //it is not sure here... - //done before writeMedfile on option?... see filterFaceOnCell() - new2oldIds[iold][iter->first].push_back(ielem); - } - } - - //creating the splitMeshes from the face ids - for (int inew=0; inew<nbNewDomain; inew++) - { - if (meshesCastFrom[iold]->getNumberOfCells() > 0) - { - splitMeshes[inew][iold]= - (ParaMEDMEM::MEDCouplingUMesh*) - ( meshesCastFrom[iold]->buildPartOfMySelf(&new2oldIds[iold][inew][0], - &new2oldIds[iold][inew][0]+new2oldIds[iold][inew].size(), - true) - ); - splitMeshes[inew][iold]->zipCoords(); - } - else - { - splitMeshes[inew][iold]=CreateEmptyMEDCouplingUMesh(); - } - } - } - else - { - std::cout<<"proc "<<MyGlobals::_Rank<<" : castFaceMeshes empty mesh from iodDomain "<<iold<<std::endl; - } - } - -#ifdef HAVE_MPI - //send/receive stuff - if (isParallelMode()) - { - ParaMEDMEM::MEDCouplingUMesh *empty=CreateEmptyMEDCouplingUMesh(); - for (int iold=0; iold<nbOldDomain; iold++) - for (int inew=0; inew<nbNewDomain; inew++) - { - if (initialCollection._domain_selector->isMyDomain(iold) && !_domain_selector->isMyDomain(inew)) - { - if (splitMeshes[inew][iold] != 0) - { - _domain_selector->sendMesh(*(splitMeshes[inew][iold]), _domain_selector->getProcessorID(inew)); - //std::cout << "proc " << MyGlobals::_Rank << " : castFaceMeshes send " <<inew<<" "<<iold<<" "<<splitMeshes[inew][iold]->getNumberOfCells()<<std::endl; - } - else - { - _domain_selector->sendMesh(*(empty), _domain_selector->getProcessorID(inew)); - //std::cout << "proc " << MyGlobals::_Rank << " : castFaceMeshes sen0 " <<inew<<" "<<iold<<std::endl; - } - } - if (!initialCollection._domain_selector->isMyDomain(iold) && _domain_selector->isMyDomain(inew)) - _domain_selector->recvMesh(splitMeshes[inew][iold], _domain_selector->getProcessorID(iold)); - //int nb=0; - //if (splitMeshes[inew][iold]) - // nb=splitMeshes[inew][iold]->getNumberOfCells(); - //std::cout << "proc " << MyGlobals::_Rank << " : castFaceMeshes recv "<<inew<<" "<<iold<<" "<<nb<<std::endl;//" "<<splitMeshes[inew][iold]->getNumberOfCells()<<std::endl; - } - empty->decrRef(); - } -#endif - - //fusing the split meshes - if (MyGlobals::_Verbose>200) - std::cout << "proc " << MyGlobals::_Rank << " : castFaceMeshes fusing" << std::endl; - meshesCastTo.resize(nbNewDomain); - for (int inew=0; inew<nbNewDomain; inew++) - { - vector<const ParaMEDMEM::MEDCouplingUMesh*> myMeshes; - for (int iold=0; iold<nbOldDomain; iold++) - { - ParaMEDMEM::MEDCouplingUMesh *umesh=splitMeshes[inew][iold]; - if (umesh!=0) - if (umesh->getNumberOfCells()>0) - myMeshes.push_back(umesh); - } - - ParaMEDMEM::MEDCouplingUMesh *bndMesh = 0; - if ( _subdomain_boundary_creates && - _mesh[inew] && - _mesh[inew]->getNumberOfCells()>0 ) - { - bndMesh = - ((ParaMEDMEM::MEDCouplingUMesh *)_mesh[inew]->buildBoundaryMesh(/*keepCoords=*/true)); - if (bndMesh->getNumberOfCells()>0) - myMeshes.push_back( bndMesh ); - } - - if (myMeshes.size()>0) - { - meshesCastTo[inew]=ParaMEDMEM::MEDCouplingUMesh::MergeUMeshes(myMeshes); - meshesCastTo[inew]->sortCellsInMEDFileFrmt()->decrRef(); - } - else - { - ParaMEDMEM::MEDCouplingUMesh *empty=CreateEmptyMEDCouplingUMesh(); - meshesCastTo[inew]=empty; - } - for (int iold=0; iold<nbOldDomain; iold++) - if (splitMeshes[inew][iold]!=0) - splitMeshes[inew][iold]->decrRef(); - if ( bndMesh ) - bndMesh->decrRef(); - } - if (MyGlobals::_Verbose>300) - std::cout << "proc " << MyGlobals::_Rank << " : castFaceMeshes end fusing" << std::endl; -} - - - -void MEDPARTITIONER::MeshCollection::castIntField(std::vector<ParaMEDMEM::MEDCouplingUMesh*>& meshesCastFrom, - std::vector<ParaMEDMEM::MEDCouplingUMesh*>& meshesCastTo, - std::vector<ParaMEDMEM::DataArrayInt*>& arrayFrom, - std::string nameArrayTo) -{ - using std::vector; - - int ioldMax=meshesCastFrom.size(); - int inewMax=meshesCastTo.size(); - - - //preparing bounding box trees for accelerating source-target node identifications - if (MyGlobals::_Verbose>99) - std::cout<<"making accelerating structures"<<std::endl; - std::vector<BBTreeOfDim* > acceleratingStructures(ioldMax); - std::vector<ParaMEDMEM::DataArrayDouble*>bbox(ioldMax); - for (int iold =0; iold< ioldMax; iold++) - if (isParallelMode() && _domain_selector->isMyDomain(iold)) - { - ParaMEDMEM::DataArrayDouble* sourceCoords=meshesCastFrom[iold]->getBarycenterAndOwner(); - bbox[iold]=sourceCoords->computeBBoxPerTuple(1.e-6); - acceleratingStructures[iold]=new BBTreeOfDim( sourceCoords->getNumberOfComponents(), bbox[iold]->getConstPointer(),0,0,bbox[iold]->getNumberOfTuples()); - sourceCoords->decrRef(); - } - // send-recv operations -#ifdef HAVE_MPI - for (int inew=0; inew<inewMax; inew++) - { - for (int iold=0; iold<ioldMax; iold++) - { - //sending arrays for distant domains - if (isParallelMode() && _domain_selector->isMyDomain(iold) && !_domain_selector->isMyDomain(inew)) - { - //send mesh - _domain_selector->sendMesh(*meshesCastFrom[iold],_domain_selector->getProcessorID(inew)); - //send vector - int size=arrayFrom[iold]->getNumberOfTuples(); //cvw may be -1! - vector<int>sendIds; - if (MyGlobals::_Verbose>400) std::cout<<"proc "<<_domain_selector->rank()<<" : castIntField SendIntVec size "<<size<<std::endl; - if (size>0) //no empty - { - sendIds.resize(size); - std::copy(arrayFrom[iold]->getPointer(),arrayFrom[iold]->getPointer()+size,&sendIds[0]); - } - else //empty - { - size=0; - sendIds.resize(size); - } - SendIntVec(sendIds, _domain_selector->getProcessorID(inew)); - } - //receiving arrays from distant domains - if (isParallelMode() && !_domain_selector->isMyDomain(iold) && _domain_selector->isMyDomain(inew)) - { - //receive mesh - vector<int> recvIds; - ParaMEDMEM::MEDCouplingUMesh* recvMesh; - _domain_selector->recvMesh(recvMesh,_domain_selector->getProcessorID(iold)); - //receive vector - if (MyGlobals::_Verbose>400) std::cout<<"proc "<<_domain_selector->rank()<<" : castIntField recIntVec "<<std::endl; - RecvIntVec(recvIds, _domain_selector->getProcessorID(iold)); - remapIntField(inew,iold,*recvMesh,*meshesCastTo[inew],&recvIds[0],nameArrayTo,0); - recvMesh->decrRef(); //cww is it correct? - } - } - } -#endif - - //local contributions and aggregation - for (int inew=0; inew<inewMax; inew++) - { - for (int iold=0; iold<ioldMax; iold++) - if (!isParallelMode() || ( _domain_selector->isMyDomain(iold) && _domain_selector->isMyDomain(inew))) - { - remapIntField(inew,iold,*meshesCastFrom[iold],*meshesCastTo[inew],arrayFrom[iold]->getConstPointer(),nameArrayTo,acceleratingStructures[iold]); - } - } - for (int iold=0; iold<ioldMax;iold++) - if (isParallelMode() && _domain_selector->isMyDomain(iold)) - { - bbox[iold]->decrRef(); - delete acceleratingStructures[iold]; - } -} - -void MEDPARTITIONER::MeshCollection::remapIntField(int inew, int iold, - const ParaMEDMEM::MEDCouplingUMesh& sourceMesh, - const ParaMEDMEM::MEDCouplingUMesh& targetMesh, - const int* fromArray, - std::string nameArrayTo, - const BBTreeOfDim* myTree) -{ - - if (sourceMesh.getNumberOfCells()<=0) return; //empty mesh could exist - ParaMEDMEM::DataArrayDouble* targetCoords=targetMesh.getBarycenterAndOwner(); - const double* tc=targetCoords->getConstPointer(); - int targetSize=targetMesh.getNumberOfCells(); - int sourceSize=sourceMesh.getNumberOfCells(); - if (MyGlobals::_Verbose>200) - std::cout<<"remap vers target de taille "<<targetSize<<std::endl; - std::vector<int> ccI; - std::string str,cle; - str=nameArrayTo+"_toArray"; - cle=Cle1ToStr(str,inew); - int* toArray; - - const BBTreeOfDim* tree; - bool cleantree=false; - ParaMEDMEM::DataArrayDouble* sourceBBox=0; - int dim = targetCoords->getNumberOfComponents(); - if (myTree==0) - { - sourceBBox=sourceMesh.getBarycenterAndOwner()->computeBBoxPerTuple(1e-8); - tree=new BBTreeOfDim( dim, sourceBBox->getConstPointer(),0,0, sourceBBox->getNumberOfTuples(),1e-10); - cleantree=true; - } - else tree=myTree; - //first time iold : create and initiate - if (_map_dataarray_int.find(cle)==_map_dataarray_int.end()) - { - if (MyGlobals::_Is0verbose>100) - std::cout << "create " << cle << " size " << targetSize << std::endl; - ParaMEDMEM::DataArrayInt* p=ParaMEDMEM::DataArrayInt::New(); - p->alloc(targetSize,1); - p->fillWithZero(); - toArray=p->getPointer(); - _map_dataarray_int[cle]=p; - } - else //other times iold: refind and complete - { - toArray=_map_dataarray_int.find(cle)->second->getPointer(); - } - - std::map< int, int > isource2nb; // count coincident elements - std::map<int,int>::iterator i2nb; - - for (int itargetnode=0; itargetnode<targetSize; itargetnode++) - { - std::vector<int> intersectingElems; - tree->getElementsAroundPoint(tc+itargetnode*dim,intersectingElems); - if (intersectingElems.size()!=0) - { - int isourcenode=intersectingElems[0]; - if ( intersectingElems.size() > 1 ) - { - i2nb = isource2nb.insert( std::make_pair( isourcenode, 0 )).first; - isourcenode = intersectingElems[ i2nb->second++ ]; - } - if ( isourcenode < sourceSize ) // protection from invalid elements - { - toArray[itargetnode]=fromArray[isourcenode]; - ccI.push_back(itargetnode); - ccI.push_back(isourcenode); - } - } - } - if (MyGlobals::_Verbose>200) - std::cout<<"nb points trouves"<<ccI.size()/2<<std::endl; - //memories intersection for future same job on fields (if no existing cle=no intersection) - str=Cle2ToStr(nameArrayTo+"_ccI",inew,iold); - if (MyGlobals::_Verbose>700) - std::cout << "proc " << MyGlobals::_Rank << " : map memorize '" << str << "'\n"; - - _map_dataarray_int[str]=CreateDataArrayIntFromVector(ccI, 2); - - targetCoords->decrRef(); - if (cleantree) delete tree; - if (sourceBBox !=0) sourceBBox->decrRef(); -} - -void MEDPARTITIONER::MeshCollection::castAllFields(MeshCollection& initialCollection, std::string nameArrayTo) -{ - if (nameArrayTo!="cellFieldDouble") - throw INTERP_KERNEL::Exception("Error castAllField only on cellFieldDouble"); - - std::string nameTo="typeData=6"; //resume the type of field casted - // send-recv operations - int ioldMax=initialCollection.getMesh().size(); - int inewMax=this->getMesh().size(); - int iFieldMax=initialCollection.getFieldDescriptions().size(); - if (MyGlobals::_Verbose>10) - std::cout << "castAllFields with:\n" << ReprVectorOfString(initialCollection.getFieldDescriptions()) << std::endl; - //see collection.prepareFieldDescriptions() - for (int ifield=0; ifield<iFieldMax; ifield++) - { - std::string descriptionField=initialCollection.getFieldDescriptions()[ifield]; - if (descriptionField.find(nameTo)==std::string::npos) - continue; //only nameTo accepted in Fields name description -#ifdef HAVE_MPI - for (int inew=0; inew<inewMax; inew++) - { - for (int iold=0; iold<ioldMax; iold++) - { - //sending arrays for distant domains - if (isParallelMode() && _domain_selector->isMyDomain(iold) && !_domain_selector->isMyDomain(inew)) - { - int target=_domain_selector->getProcessorID(inew); - ParaMEDMEM::DataArrayDouble* field=initialCollection.getField(descriptionField,iold); - if (MyGlobals::_Verbose>10) - std::cout << "proc " << _domain_selector->rank() << " : castAllFields sendDouble" << std::endl; - SendDataArrayDouble(field, target); - } - //receiving arrays from distant domains - if (isParallelMode() && !_domain_selector->isMyDomain(iold) && _domain_selector->isMyDomain(inew)) - { - int source=_domain_selector->getProcessorID(iold); - //receive vector - if (MyGlobals::_Verbose>10) - std::cout << "proc " << _domain_selector->rank() << " : castAllFields recvDouble" << std::endl; - ParaMEDMEM::DataArrayDouble* field=RecvDataArrayDouble(source); - remapDoubleField(inew,iold,field,nameArrayTo,descriptionField); - } - } - } -#endif - //local contributions and aggregation - for (int inew=0; inew<inewMax; inew++) - { - for (int iold=0; iold<ioldMax; iold++) - if (!isParallelMode() || ( _domain_selector->isMyDomain(iold) && _domain_selector->isMyDomain(inew))) - { - ParaMEDMEM::DataArrayDouble* field=initialCollection.getField(descriptionField,iold); - remapDoubleField(inew,iold,field,nameArrayTo,descriptionField); - } - } - } -} - -void MEDPARTITIONER::MeshCollection::remapDoubleField(int inew, int iold, - ParaMEDMEM::DataArrayDouble* fromArray, - std::string nameArrayTo, - std::string descriptionField) -//here we use 'cellFamily_ccI inew iold' set in remapIntField -{ - if (nameArrayTo!="cellFieldDouble") - throw INTERP_KERNEL::Exception("Error remapDoubleField only on cellFieldDouble"); - std::string key=Cle2ToStr("cellFamily_ccI",inew,iold); - - std::map<std::string,ParaMEDMEM::DataArrayInt*>::iterator it1; - it1=_map_dataarray_int.find(key); - if (it1==_map_dataarray_int.end()) - { - std::cerr << "proc " << MyGlobals::_Rank << " : remapDoubleField key '" << key << "' not found" << std::endl; - std::cerr << " trying remap of field double on cells : " << descriptionField << std::endl; - return; - } - //create ccI in remapIntField - ParaMEDMEM::DataArrayInt *ccI=it1->second; - if (MyGlobals::_Verbose>300) - std::cout << "proc " << MyGlobals::_Rank << " : remapDoubleField " << key << " size " << ccI->getNbOfElems() << std::endl; - - int nbcell=this->getMesh()[inew]->getNumberOfCells(); - int nbcomp=fromArray->getNumberOfComponents(); - int nbPtGauss=StrToInt(ExtractFromDescription(descriptionField, "nbPtGauss=")); - - std::string tag="inewFieldDouble="+IntToStr(inew); - key=descriptionField+SerializeFromString(tag); - int fromArrayNbOfElem=fromArray->getNbOfElems(); - int fromArrayNbOfComp=fromArray->getNumberOfComponents(); - int fromArrayNbOfCell=fromArrayNbOfElem/fromArrayNbOfComp/nbPtGauss; - - if (MyGlobals::_Verbose>1000) - { - std::cout<<"proc " << MyGlobals::_Rank << " nbcell " << nbcell << " nbcomp " << nbcomp << " nbPtGauss " << nbPtGauss << - " fromArray nbOfElems " << fromArrayNbOfElem << - " nbTuples " << fromArray->getNumberOfTuples() << - " nbcells " << fromArrayNbOfCell << - " nbComponents " << fromArray->getNumberOfComponents() << std::endl; - } - - ParaMEDMEM::DataArrayDouble* field=0; - std::map<std::string,ParaMEDMEM::DataArrayDouble*>::iterator it2; - it2=_map_dataarray_double.find(key); - if (it2==_map_dataarray_double.end()) - { - if (MyGlobals::_Verbose>300) - std::cout << "proc "<< MyGlobals::_Rank << " : remapDoubleField key '" << key << "' not found and create it" << std::endl; - field=ParaMEDMEM::DataArrayDouble::New(); - _map_dataarray_double[key]=field; - field->alloc(nbcell*nbPtGauss,nbcomp); - field->fillWithZero(); - } - else - { - field=it2->second; - if (field->getNumberOfTuples()!=nbcell*nbPtGauss || field->getNumberOfComponents()!=nbcomp) - { - std::cerr << "proc " << MyGlobals::_Rank << " : remapDoubleField3 pb of size " << - " trying remap of field double on cells : \n" << descriptionField << std::endl; - return; - } - } - - if (nbPtGauss==1) - { - field->setPartOfValuesAdv(fromArray,ccI); - } - else - { - //replaced by setPartOfValuesAdv if nbPtGauss==1 - int iMax=ccI->getNbOfElems(); - int* pccI=ccI->getPointer(); - double* pField=field->getPointer(); - double* pFrom=fromArray->getPointer(); - int itarget, isource, delta=nbPtGauss*nbcomp; - for (int i=0; i<iMax; i=i+2) //cell - { - itarget=pccI[i]; - isource=pccI[i+1]; - if ((itarget<0) || (itarget>=nbcell) || (isource<0) || (isource>=fromArrayNbOfCell)) - throw INTERP_KERNEL::Exception("Error field override"); - int ita=itarget*delta; - int iso=isource*delta; - for (int k=0; k<delta; k++) pField[ita+k]=pFrom[iso+k]; //components and gausspoints - } - } -} - -namespace -{ - using namespace ParaMEDMEM; - //================================================================================ - /*! - * \brief Sort correspondence ids of one domain and permute ids of the other accordingly - * \param [in,out] ids1 - ids of one domain - * \param [in,out] ids2 - ids of another domain - * \param [in] delta - a delta to change all ids - * \param [in] removeEqual - to remove equal ids - * \return DataArrayInt* - array of ids joined back - */ - //================================================================================ - - DataArrayInt* sortCorrespondences( DataArrayInt* ids1, - DataArrayInt* ids2, - int delta, - bool removeEqual = false) - { - // sort - MEDCouplingAutoRefCountObjectPtr< DataArrayInt > renumN2O = ids1->buildPermArrPerLevel(); - ids1->renumberInPlaceR( renumN2O->begin() ); - ids2->renumberInPlaceR( renumN2O->begin() ); - - if ( removeEqual ) - { - ids1 = ids1->buildUnique(); - ids2 = ids2->buildUnique(); - } - if ( delta != 0 ) - { - int * id = ids1->getPointer(); - for ( ; id < ids1->end(); ++id ) - ++(*id); - id = ids2->getPointer(); - for ( ; id < ids2->end(); ++id ) - ++(*id); - } - - // join - DataArrayInt* ids12 = DataArrayInt::Meld( ids1, ids2 ); // two components - ids12->rearrange( 1 ); // make one component - return ids12; - } - - //================================================================================ - /*! - * \brief Renumber ids according to mesh->sortCellsInMEDFileFrmt() - * \param [in,out] ids - cell ids to renumber - * \param [in] o2nRenumber - renumbering array in "Old to New" mode - */ - //================================================================================ - - void renumber( DataArrayInt* ids, const DataArrayInt* o2nRenumber ) - { - if ( !ids || !o2nRenumber ) - return; - int * id = ids->getPointer(); - const int * o2n = o2nRenumber->getConstPointer(); - for ( ; id < ids->end(); ++id ) - { - *id = o2n[ *id ]; - } - } -} - -//================================================================================ -/*! - * \brief Fill up ConnectZone's stored in _topology with nodal correspondences - * \param [in] nodeMapping - mapping between old nodes and new nodes - * (iolddomain,ioldnode)->(inewdomain,inewnode) - * \param [in] o2nRenumber - renumbering array returned by mesh->sortCellsInMEDFileFrmt() - * per a new domain - * \param [in] nbInitialDomains - nb of old domains - */ -//================================================================================ - -void MEDPARTITIONER::MeshCollection::buildConnectZones( const NodeMapping& nodeMapping, - const std::vector<ParaMEDMEM::DataArrayInt*> & o2nRenumber, - int nbInitialDomains) -{ - if ( !MyGlobals::_Create_Joints || _topology->nbDomain() < 2 ) - return; - - if ( MyGlobals::_World_Size > 1 ) - { - _topology->getCZ().clear(); - return; // not implemented for parallel mode - } - - // at construction, _topology creates cell correspondences basing on Graph information, - // and here we - // 1) add node correspondences, - // 2) split cell correspondences by cell geometry types - // 3) sort ids to be in ascending order - - const int nb_domains = _topology->nbDomain(); - - // ================================== - // 1) add node correspondences - // ================================== - - std::vector< std::vector< std::vector< int > > > nodeCorresp( nb_domains ); - for ( int idomain = 0; idomain < nb_domains; ++idomain ) - { - nodeCorresp[ idomain ].resize( nb_domains ); - } - - NodeMapping::const_iterator nmIt1, nmIt2 = nodeMapping.begin(); - for ( nmIt1 = nmIt2; nmIt1 != nodeMapping.end(); nmIt1 = nmIt2 ) - { - // look for an "old" node mapped into several "new" nodes in different domains - int nbSameOld = 0; - while ( ++nmIt2 != nodeMapping.end() && nmIt2->first == nmIt1->first ) - nbSameOld += ( nmIt2->second != nmIt1->second ); - - if ( nbSameOld > 0 ) - { - NodeMapping::const_iterator nmEnd = nmIt2; - for ( ; true; ++nmIt1 ) - { - nmIt2 = nmIt1; - if ( ++nmIt2 == nmEnd ) - break; - int dom1 = nmIt1->second.first; - int node1 = nmIt1->second.second; - for ( ; nmIt2 != nmEnd; ++nmIt2 ) - { - int dom2 = nmIt2->second.first; - int node2 = nmIt2->second.second; - if ( dom1 != dom2 ) - { - nodeCorresp[ dom1 ][ dom2 ].push_back( node1 ); - nodeCorresp[ dom1 ][ dom2 ].push_back( node2 ); - nodeCorresp[ dom2 ][ dom1 ].push_back( node2 ); - nodeCorresp[ dom2 ][ dom1 ].push_back( node1 ); - } - } - } - } - } - - // add nodeCorresp to czVec - - std::vector<MEDPARTITIONER::ConnectZone*>& czVec = _topology->getCZ(); - - for ( int idomain = 0; idomain < nb_domains; ++idomain ) - { - for ( int idomainNear = 0; idomainNear < nb_domains; ++idomainNear ) - { - std::vector< int > & corresp = nodeCorresp[ idomain ][ idomainNear ]; - if ( corresp.empty() ) - continue; - - MEDPARTITIONER::ConnectZone* cz = 0; - for ( size_t i = 0; i < czVec.size() && !cz; ++i ) - if ( czVec[i] && - czVec[i]->getLocalDomainNumber () == idomain && - czVec[i]->getDistantDomainNumber() == idomainNear ) - cz = czVec[i]; - - if ( !cz ) - { - cz = new MEDPARTITIONER::ConnectZone(); - cz->setName( "Nodal Connect Zone defined by MEDPARTITIONER" ); - cz->setLocalDomainNumber ( idomain ); - cz->setDistantDomainNumber( idomainNear ); - czVec.push_back(cz); - } - - cz->setNodeCorresp( &corresp[0], corresp.size()/2 ); - } - } - - // ========================================================== - // 2) split cell correspondences by cell geometry types - // ========================================================== - - for ( size_t i = 0; i < czVec.size(); ++i ) - { - MEDPARTITIONER::ConnectZone* cz = czVec[i]; - if ( !cz || - cz->getEntityCorrespNumber( 0,0 ) == 0 || - cz->getLocalDomainNumber () > (int)_mesh.size() || - cz->getDistantDomainNumber() > (int)_mesh.size() ) - continue; - ParaMEDMEM::MEDCouplingUMesh* mesh1 = _mesh[ cz->getLocalDomainNumber () ]; - ParaMEDMEM::MEDCouplingUMesh* mesh2 = _mesh[ cz->getDistantDomainNumber() ]; - - // separate ids of two domains - const ParaMEDMEM::MEDCouplingSkyLineArray *corrArray = cz->getEntityCorresp( 0, 0 ); - const DataArrayInt* ids12 = corrArray->getValueArray(); - MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ids1, ids2, ids12Sorted; - ids1 = ids12->selectByTupleId2( 0, corrArray->getLength(), 2 ); - ids2 = ids12->selectByTupleId2( 1, corrArray->getLength(), 2 ); - - // renumber cells according to mesh->sortCellsInMEDFileFrmt() - renumber( ids1, o2nRenumber[ cz->getLocalDomainNumber() ]); - renumber( ids2, o2nRenumber[ cz->getDistantDomainNumber() ]); - - // check nb cell types - std::set<INTERP_KERNEL::NormalizedCellType> types1, types2; - types1 = mesh1->getTypesOfPart( ids1->begin(), ids1->end() ); - types2 = mesh2->getTypesOfPart( ids2->begin(), ids2->end() ); - if ( types1.size() < 1 || types2.size() < 1 ) - continue; // parallel mode? - - MEDPARTITIONER::ConnectZone* cz21 = 0; // zone 2 -> 1 - for ( size_t j = 0; j < czVec.size() && !cz21; ++j ) - if ( czVec[j] && - czVec[j]->getLocalDomainNumber () == cz->getDistantDomainNumber() && - czVec[j]->getDistantDomainNumber() == cz->getLocalDomainNumber() ) - cz21 = czVec[j]; - - if ( types1.size() == 1 && types2.size() == 1 ) // split not needed, only sort - { - ids12Sorted = sortCorrespondences( ids1, ids2, /*delta=*/1 ); - cz->setEntityCorresp( *types1.begin(), *types2.begin(), - ids12Sorted->begin(), ids12Sorted->getNbOfElems() / 2 ); - - if ( cz21 )// set 2->1 correspondence - { - ids12Sorted = sortCorrespondences( ids2, ids1, /*delta=*/0 ); - cz21->setEntityCorresp( *types2.begin(), *types1.begin(), - ids12Sorted->begin(), ids12Sorted->getNbOfElems() / 2 ); - } - } - else // split and sort - { - typedef std::pair< std::vector< int >, std::vector< int > > T2Vecs; - T2Vecs idsByType[ INTERP_KERNEL::NORM_MAXTYPE ][ INTERP_KERNEL::NORM_MAXTYPE ]; - int t1, t2; - - const int nbIds = ids1->getNbOfElems(); - const int * p1 = ids1->begin(), * p2 = ids2->begin(); - for ( int i = 0; i < nbIds; ++i ) - { - t1 = mesh1->getTypeOfCell( p1[ i ]); - t2 = mesh2->getTypeOfCell( p2[ i ]); - T2Vecs & ids = idsByType[ t1 ][ t2 ]; - ids.first .push_back( p1[ i ]); - ids.second.push_back( p1[ i ]); - } - - const int maxType = int( INTERP_KERNEL::NORM_MAXTYPE ); - for ( t1 = 0; t1 < maxType; ++t1 ) - for ( t2 = 0; t2 < maxType; ++t2 ) - { - T2Vecs & ids = idsByType[ t1 ][ t2 ]; - if ( ids.first.empty() ) continue; - p1 = & ids.first[0]; - p2 = & ids.second[0]; - ids1->desallocate(); - ids1->pushBackValsSilent( p1, p1+ids.first.size() ); - ids2->desallocate(); - ids2->pushBackValsSilent( p2, p2+ids.first.size() ); - ids12Sorted = sortCorrespondences( ids1, ids2, /*delta=*/1 ); - - cz->setEntityCorresp( t1, t2, - ids12Sorted->begin(), ids12Sorted->getNbOfElems() / 2 ); - - if ( cz21 )// set 2->1 correspondence - { - ids12Sorted = sortCorrespondences( ids2, ids1, /*delta=*/0 ); - cz21->setEntityCorresp( t2, t1, - ids12Sorted->begin(), ids12Sorted->getNbOfElems() / 2 ); - break; - } - } - }// split and sort - - cz->setEntityCorresp( 0, 0, 0, 0 ); // erase ids computed by _topology - if ( cz21 ) - cz21->setEntityCorresp( 0, 0, 0, 0 ); - - } // loop on czVec - - - // ========================================== - // 3) sort node ids to be in ascending order - // ========================================== - - const bool removeEqual = ( nbInitialDomains > 1 ); - - for ( size_t i = 0; i < czVec.size(); ++i ) - { - MEDPARTITIONER::ConnectZone* cz = czVec[i]; - if ( !cz || cz->getNodeNumber() < 1 ) - continue; - if ( cz->getDistantDomainNumber() < cz->getLocalDomainNumber() ) - continue; // treat a pair of domains once - - MEDPARTITIONER::ConnectZone* cz21 = 0; // zone 2 -> 1 - for ( size_t j = 0; j < czVec.size() && !cz21; ++j ) - if ( czVec[j] && - czVec[j]->getLocalDomainNumber () == cz->getDistantDomainNumber() && - czVec[j]->getDistantDomainNumber() == cz->getLocalDomainNumber() ) - cz21 = czVec[j]; - - // separate ids of two domains - const ParaMEDMEM::MEDCouplingSkyLineArray *corrArray = cz->getNodeCorresp(); - const DataArrayInt *ids12 = corrArray->getValueArray(); - MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ids1, ids2, ids12Sorted; - ids1 = ids12->selectByTupleId2( 0, corrArray->getLength(), 2 ); - ids2 = ids12->selectByTupleId2( 1, corrArray->getLength(), 2 ); - - ids12Sorted = sortCorrespondences( ids1, ids2, /*delta=*/0, removeEqual ); - cz->setNodeCorresp( ids12Sorted->begin(), ids12Sorted->getNbOfElems() / 2 ); - - if ( cz21 )// set 2->1 correspondence - { - ids12Sorted = sortCorrespondences( ids2, ids1, /*delta=*/0, false ); - cz->setNodeCorresp( ids12Sorted->begin(), ids12Sorted->getNbOfElems() / 2 ); - } - } -} - -//================================================================================ -/*! - * \brief Find faces common with neighbor domains and put them in "JOINT_n_p_Faces" - * group (where "n" and "p" are domain IDs) - */ -//================================================================================ - -void MEDPARTITIONER::MeshCollection::buildBoundaryFaces() -{ - if (_topology->nbDomain() < 2 || !_subdomain_boundary_creates ) - return; - - if ( getMeshDimension() < 2 ) - return; - - using ParaMEDMEM::MEDCouplingUMesh; - using ParaMEDMEM::DataArrayDouble; - using ParaMEDMEM::DataArrayInt; - - std::vector<MEDCouplingUMesh*>& faceMeshes = getFaceMesh(); - int nbMeshes = faceMeshes.size(); - - //preparing bounding box trees for accelerating search of coincident faces - std::vector<BBTreeOfDim* > bbTrees(nbMeshes); - std::vector<DataArrayDouble*>bbox (nbMeshes); - for (int inew = 0; inew < nbMeshes-1; inew++) - if ( !isParallelMode() || _domain_selector->isMyDomain(inew) ) - { - DataArrayDouble* bcCoords = faceMeshes[inew]->getBarycenterAndOwner(); - bbox [inew] = bcCoords->computeBBoxPerTuple(1.e-6); - bbTrees[inew] = new BBTreeOfDim( bcCoords->getNumberOfComponents(), - bbox[inew]->getConstPointer(),0,0, - bbox[inew]->getNumberOfTuples()); - bcCoords->decrRef(); - } - - // loop on domains to find joint faces between them - for (int inew1 = 0; inew1 < nbMeshes; inew1++ ) - { - for (int inew2 = inew1+1; inew2 < nbMeshes; inew2++ ) - { - MEDCouplingUMesh* mesh1 = 0; - MEDCouplingUMesh* mesh2 = 0; - //MEDCouplingUMesh* recvMesh = 0; - bool mesh1Here = true, mesh2Here = true; - if (isParallelMode()) - { -#ifdef HAVE_MPI - mesh1Here = _domain_selector->isMyDomain(inew1); - mesh2Here = _domain_selector->isMyDomain(inew2); - if ( !mesh1Here && mesh2Here ) - { - //send mesh2 to domain of mesh1 - _domain_selector->sendMesh(*faceMeshes[inew2], - _domain_selector->getProcessorID(inew1)); - } - else if ( mesh1Here && !mesh2Here ) - { - //receiving mesh2 from a distant domain - _domain_selector->recvMesh(mesh2,_domain_selector->getProcessorID(inew2)); - if ( faceMeshes[ inew2 ] ) - faceMeshes[ inew2 ]->decrRef(); - faceMeshes[ inew2 ] = mesh2; - } -#endif - } - if ( mesh1Here && !mesh1 ) mesh1 = faceMeshes[ inew1 ]; - if ( mesh2Here && !mesh2 ) mesh2 = faceMeshes[ inew2 ]; - - // find coincident faces - std::vector< int > faces1, faces2; - if ( mesh1 && mesh2 ) - { - const DataArrayDouble* coords2 = mesh2->getBarycenterAndOwner(); - const double* c2 = coords2->getConstPointer(); - const int dim = coords2->getNumberOfComponents(); - const int nbFaces2 = mesh2->getNumberOfCells(); - const int nbFaces1 = mesh1->getNumberOfCells(); - - for (int i2 = 0; i2 < nbFaces2; i2++) - { - std::vector<int> coincFaces; - bbTrees[inew1]->getElementsAroundPoint( c2+i2*dim, coincFaces ); - if (coincFaces.size()!=0) - { - int i1 = coincFaces[0]; - // if ( coincFaces.size() > 1 ) - // { - // i2nb = isource2nb.insert( std::make_pair( i1 , 0 )).first; - // i1 = coincFaces[ i2nb->second++ ]; - // } - if ( i1 < nbFaces1 ) // protection from invalid elements - { - faces1.push_back( i1 ); - faces2.push_back( i2 ); - } - } - } - coords2->decrRef(); - } - - if ( isParallelMode()) - { -#ifdef HAVE_MPI - if ( mesh1Here && !mesh2Here ) - { - //send faces2 to domain of recvMesh - SendIntVec(faces2, _domain_selector->getProcessorID(inew2)); - } - else if ( !mesh1Here && mesh2Here ) - { - //receiving ids of faces from a domain of mesh1 - RecvIntVec(faces2, _domain_selector->getProcessorID(inew1)); - } -#endif - } - // if ( recvMesh ) - // recvMesh->decrRef(); - - // Create group "JOINT_inew1_inew2_Faces" and corresponding families - for ( int is2nd = 0; is2nd < 2; ++is2nd ) - { - createJointGroup( is2nd ? faces2 : faces1, - inew1 , inew2, is2nd ); - } - - } // loop on the 2nd domains (inew2) - } // loop on the 1st domains (inew1) - - - // delete bounding box trees - for (int inew = 0; inew < nbMeshes-1; inew++) - if (isParallelMode() && _domain_selector->isMyDomain(inew)) - { - bbox[inew]->decrRef(); - delete bbTrees[inew]; - } -} - -//================================================================================ -/*! - * \brief Create group "JOINT_inew1_inew2_Faces" and corresponding families - * \param faces - face ids to include into the group - * \param inew1 - index of the 1st domain - * \param inew2 - index of the 2nd domain - * \param is2nd - in which (1st or 2nd) domain to create the group - */ -//================================================================================ - -void MEDPARTITIONER::MeshCollection::createJointGroup( const std::vector< int >& faces, - const int inew1, - const int inew2, - const bool is2nd ) -{ - // get the name of JOINT group - std::string groupName; - { - std::ostringstream oss; - oss << "JOINT_" - << (is2nd ? inew2 : inew1 ) << "_" - << (is2nd ? inew1 : inew2 ) << "_" - << ( getMeshDimension()==2 ? "Edge" : "Face" ); - groupName = oss.str(); - } - - // remove existing "JOINT_*" group - _group_info.erase( groupName ); - - // get family IDs array - int* famIDs = 0; - int inew = (is2nd ? inew2 : inew1 ); - int totalNbFaces = _face_mesh[ inew ] ? _face_mesh[ inew ]->getNumberOfCells() : 0; - std::string cle = Cle1ToStr( "faceFamily_toArray", inew ); - if ( !_map_dataarray_int.count(cle) ) - { - if ( totalNbFaces > 0 ) - { - ParaMEDMEM::DataArrayInt* p=ParaMEDMEM::DataArrayInt::New(); - p->alloc( totalNbFaces, 1 ); - p->fillWithZero(); - famIDs = p->getPointer(); - _map_dataarray_int[cle]=p; - } - } - else - { - famIDs = _map_dataarray_int.find(cle)->second->getPointer(); - } - // find a family ID of an existing JOINT group - int familyID = 0; - std::map<std::string, int>::iterator name2id = _family_info.find( groupName ); - if ( name2id != _family_info.end() ) - familyID = name2id->second; - - // remove faces from the familyID-the family - if ( familyID != 0 && famIDs ) - for ( int i = 0; i < totalNbFaces; ++i ) - if ( famIDs[i] == familyID ) - famIDs[i] = 0; - - if ( faces.empty() ) - return; - - if ( familyID == 0 ) // generate a family ID for JOINT group - { - std::set< int > familyIDs; - for ( name2id = _family_info.begin(); name2id != _family_info.end(); ++name2id ) - familyIDs.insert( name2id->second ); - // find the next free family ID - int freeIdCount = inew1 * getNbOfGlobalMeshes() + inew2 + is2nd; - do - { - if ( !familyIDs.count( ++familyID )) - --freeIdCount; - } - while ( freeIdCount > 0 ); - } - - // push faces to familyID-th group - if ( faces.back() >= totalNbFaces ) - throw INTERP_KERNEL::Exception("MeshCollection::createJointGroup(): to high face ID"); - for ( size_t i = 0; i < faces.size(); ++i ) - famIDs[ faces[i] ] = familyID; - - // register JOINT group and family - _family_info[ groupName ] = familyID; // name of the group and family is same - _group_info [ groupName ].push_back( groupName ); -} - -/*! constructing the MESH collection from a distributed file - * - * \param filename name of the master file containing the list of all the MED files - */ -MEDPARTITIONER::MeshCollection::MeshCollection(const std::string& filename) - : _topology(0), - _owns_topology(true), - _driver(0), - _domain_selector( 0 ), - _i_non_empty_mesh(-1), - _driver_type(MEDPARTITIONER::Undefined), - _subdomain_boundary_creates(MyGlobals::_Creates_Boundary_Faces), - _family_splitting(false), - _create_empty_groups(false), - _joint_finder(0) -{ - try - { - _driver=new MeshCollectionMedXmlDriver(this); - _driver->read (filename.c_str()); - _driver_type = MedXml; - } - catch(...) - { // Handle all exceptions - if ( _driver ) delete _driver; _driver=0; - try - { - _driver=new MeshCollectionMedAsciiDriver(this); - _driver->read (filename.c_str()); - _driver_type=MedAscii; - } - catch(...) - { - delete _driver; - _driver=0; - throw INTERP_KERNEL::Exception("file does not comply with any recognized format"); - } - } - for ( int idomain = 0; idomain < (int)_mesh.size(); ++idomain ) - if ( _mesh[idomain] && _mesh[idomain]->getNumberOfNodes() > 0 ) - _i_non_empty_mesh = idomain; -} - -/*! Constructing the MESH collection from selected domains of a distributed file - * - * \param filename - name of the master file containing the list of all the MED files - * \param domainSelector - selector of domains to load - */ -MEDPARTITIONER::MeshCollection::MeshCollection(const std::string& filename, ParaDomainSelector& domainSelector) - : _topology(0), - _owns_topology(true), - _driver(0), - _domain_selector( &domainSelector ), - _i_non_empty_mesh(-1), - _driver_type(MEDPARTITIONER::Undefined), - _subdomain_boundary_creates(MyGlobals::_Creates_Boundary_Faces), - _family_splitting(false), - _create_empty_groups(false), - _joint_finder(0) -{ - std::string myfile=filename; - std::size_t found=myfile.find(".xml"); - if (found!=std::string::npos) //file .xml - { - try - { - _driver=new MeshCollectionMedXmlDriver(this); - _driver->read ( filename.c_str(), _domain_selector ); - _driver_type = MedXml; - } - catch(...) - { // Handle all exceptions - delete _driver; - throw INTERP_KERNEL::Exception("file .xml does not comply with any recognized format"); - } - } - else - { - found=myfile.find(".med"); - if (found!=std::string::npos) //file .med single - { - //make a temporary file .xml and retry MedXmlDriver - std::string xml="\ -<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n \ -<root>\n \ - <version maj=\"2\" min=\"3\" ver=\"1\"/>\n \ - <description what=\"\" when=\"\"/>\n \ - <content>\n \ - <mesh name=\"$meshName\"/>\n \ - </content>\n \ - <splitting>\n \ - <subdomain number=\"1\"/>\n \ - <global_numbering present=\"no\"/>\n \ - </splitting>\n \ - <files>\n \ - <subfile id=\"1\">\n \ - <name>$fileName</name>\n \ - <machine>localhost</machine>\n \ - </subfile>\n \ - </files>\n \ - <mapping>\n \ - <mesh name=\"$meshName\">\n \ - <chunk subdomain=\"1\">\n \ - <name>$meshName</name>\n \ - </chunk>\n \ - </mesh>\n \ - </mapping>\n \ -</root>\n"; - std::vector<std::string> meshNames=MEDLoader::GetMeshNames(myfile); - xml.replace(xml.find("$fileName"),9,myfile); - xml.replace(xml.find("$meshName"),9,meshNames[0]); - xml.replace(xml.find("$meshName"),9,meshNames[0]); - xml.replace(xml.find("$meshName"),9,meshNames[0]); - std::string nameFileXml(myfile); - nameFileXml.replace(nameFileXml.find(".med"),4,".xml"); - std::string nameFileXmlDN,nameFileXmlBN; - MEDLoaderBase::getDirAndBaseName(nameFileXml,nameFileXmlDN,nameFileXmlBN); - nameFileXml=MEDLoaderBase::joinPath(nameFileXmlDN,"medpartitioner_"+nameFileXmlBN); - if (_domain_selector->rank()==0) //only on to write it - { - std::ofstream f(nameFileXml.c_str()); - f<<xml; - f.close(); - } -#ifdef HAVE_MPI - if (MyGlobals::_World_Size>1) - MPI_Barrier(MPI_COMM_WORLD); //wait for creation of nameFileXml -#endif - try - { - _driver=new MeshCollectionMedXmlDriver(this); - _driver->read ( nameFileXml.c_str(), _domain_selector ); - _driver_type = MedXml; - } - catch(...) - { // Handle all exceptions - delete _driver; _driver=0; - throw INTERP_KERNEL::Exception("file medpartitioner_xxx.xml does not comply with any recognized format"); - } - } - else //no extension - { - try - { - _driver=new MeshCollectionMedAsciiDriver(this); - _driver->read ( filename.c_str(), _domain_selector ); - _driver_type=MedAscii; - } - catch(...) - { - delete _driver; - _driver=0; - throw INTERP_KERNEL::Exception("file name with no extension does not comply with any recognized format"); - } - } - } - // find non-empty domain mesh - for ( int idomain = 0; idomain < (int)_mesh.size(); ++idomain ) - if ( _mesh[idomain] && _mesh[idomain]->getNumberOfNodes() > 0 ) - _i_non_empty_mesh = idomain; - - try - { - //check for all proc/file compatibility of _field_descriptions -#ifdef HAVE_MPI - _field_descriptions=AllgathervVectorOfString(MyGlobals::_Field_Descriptions); -#else - _field_descriptions=MyGlobals::_Field_Descriptions; -#endif - } - catch(INTERP_KERNEL::Exception& e) - { - std::cerr << "proc " << MyGlobals::_Rank << " : INTERP_KERNEL_Exception : " << e.what() << std::endl; - throw INTERP_KERNEL::Exception("Something wrong verifying coherency of files med ands fields"); - } -#ifdef HAVE_MPI - try - { - //check for all proc/file compatibility of _family_info - std::vector<std::string> v2=AllgathervVectorOfString(VectorizeFromMapOfStringInt(_family_info)); - _family_info=DevectorizeToMapOfStringInt(v2); - } - catch(INTERP_KERNEL::Exception& e) - { - std::cerr << "proc " << MyGlobals::_Rank << " : INTERP_KERNEL_Exception : " << e.what() << std::endl; - throw INTERP_KERNEL::Exception("Something wrong merging all familyInfo"); - } - - try - { - //check for all proc/file compatibility of _group_info - std::vector<std::string> v2=AllgathervVectorOfString(VectorizeFromMapOfStringVectorOfString(_group_info)); - _group_info=DeleteDuplicatesInMapOfStringVectorOfString(DevectorizeToMapOfStringVectorOfString(v2)); - } - catch(INTERP_KERNEL::Exception& e) - { - std::cerr << "proc " << MyGlobals::_Rank << " : INTERP_KERNEL_Exception : " << e.what() << std::endl; - throw INTERP_KERNEL::Exception("Something wrong merging all groupInfo"); - } -#endif -} - -/*! constructing the MESH collection from a sequential MED-file - * - * \param filename MED file - * \param meshname name of the mesh that is to be read - */ -MEDPARTITIONER::MeshCollection::MeshCollection(const std::string& filename, const std::string& meshname) - : _topology(0), - _owns_topology(true), - _driver(0), - _domain_selector( 0 ), - _i_non_empty_mesh(-1), - _name(meshname), - _driver_type(MEDPARTITIONER::MedXml), - _subdomain_boundary_creates(MyGlobals::_Creates_Boundary_Faces), - _family_splitting(false), - _create_empty_groups(false), - _joint_finder(0) -{ - try // avoid memory leak in case of inexistent filename - { - retrieveDriver()->readSeq (filename.c_str(),meshname.c_str()); - } - catch (...) - { - delete _driver; - _driver=0; - throw INTERP_KERNEL::Exception("problem reading .med files"); - } - if ( _mesh[0] && _mesh[0]->getNumberOfNodes() > 0 ) - _i_non_empty_mesh = 0; -} - -MEDPARTITIONER::MeshCollection::~MeshCollection() -{ - for (int i=0; i<(int)_mesh.size();i++) - if (_mesh[i]!=0) _mesh[i]->decrRef(); - - for (int i=0; i<(int)_cell_family_ids.size();i++) - if (_cell_family_ids[i]!=0) - _cell_family_ids[i]->decrRef(); - - for (int i=0; i<(int)_face_mesh.size();i++) - if (_face_mesh[i]!=0) - _face_mesh[i]->decrRef(); - - for (int i=0; i<(int)_face_family_ids.size();i++) - if (_face_family_ids[i]!=0) - _face_family_ids[i]->decrRef(); - - for (std::map<std::string, ParaMEDMEM::DataArrayInt*>::iterator it=_map_dataarray_int.begin() ; it!=_map_dataarray_int.end(); it++ ) - if ((*it).second!=0) - (*it).second->decrRef(); - - for (std::map<std::string, ParaMEDMEM::DataArrayDouble*>::iterator it=_map_dataarray_double.begin() ; it!=_map_dataarray_double.end(); it++ ) - if ((*it).second!=0) - (*it).second->decrRef(); - - delete _driver; - if (_topology!=0 && _owns_topology) - delete _topology; -#ifdef HAVE_MPI - delete _joint_finder; -#endif -} - -/*! constructing the MESH collection from a file - * - * The method creates as many MED-files as there are domains in the - * collection. It also creates a master file that lists all the MED files. - * The MED files created in ths manner contain joints that describe the - * connectivity between subdomains. - * - * \param filename name of the master file that will contain the list of the MED files - * - */ -void MEDPARTITIONER::MeshCollection::write(const std::string& filename) -{ - //suppresses link with driver so that it can be changed for writing - delete _driver; - _driver=0; - retrieveDriver()->write (filename.c_str(), _domain_selector); -} - -/*! creates or gets the link to the collection driver - */ -MEDPARTITIONER::MeshCollectionDriver* MEDPARTITIONER::MeshCollection::retrieveDriver() -{ - if (_driver==0) - { - switch(_driver_type) - { - case MedXml: - _driver=new MeshCollectionMedXmlDriver(this); - break; - case MedAscii: - _driver=new MeshCollectionMedAsciiDriver(this); - break; - default: - throw INTERP_KERNEL::Exception("Unrecognized driver"); - } - } - return _driver; -} - - -/*! gets an existing driver - * - */ -MEDPARTITIONER::MeshCollectionDriver* MEDPARTITIONER::MeshCollection::getDriver() const -{ - return _driver; -} - -/*! - * retrieves the mesh dimension -*/ -int MEDPARTITIONER::MeshCollection::getMeshDimension() const -{ - return _i_non_empty_mesh < 0 ? -1 : _mesh[_i_non_empty_mesh]->getMeshDimension(); -} - -int MEDPARTITIONER::MeshCollection::getNbOfLocalMeshes() const -{ - int nb=0; - for (size_t i=0; i<_mesh.size(); i++) - { - if (_mesh[i]) nb++; - } - return nb; -} - -int MEDPARTITIONER::MeshCollection::getNbOfLocalCells() const -{ - int nb=0; - for (size_t i=0; i<_mesh.size(); i++) - { - if (_mesh[i]) nb=nb+_mesh[i]->getNumberOfCells(); - } - return nb; -} - -int MEDPARTITIONER::MeshCollection::getNbOfLocalFaces() const -{ - int nb=0; - for (size_t i=0; i<_face_mesh.size(); i++) - { - if (_face_mesh[i]) nb=nb+_face_mesh[i]->getNumberOfCells(); - } - return nb; -} - -std::vector<ParaMEDMEM::MEDCouplingUMesh*>& MEDPARTITIONER::MeshCollection::getMesh() -{ - return _mesh; -} - -std::vector<ParaMEDMEM::MEDCouplingUMesh*>& MEDPARTITIONER::MeshCollection::getFaceMesh() -{ - return _face_mesh; -} - -ParaMEDMEM::MEDCouplingUMesh* MEDPARTITIONER::MeshCollection::getMesh(int idomain) const -{ - return _mesh[idomain]; -} - -ParaMEDMEM::MEDCouplingUMesh* MEDPARTITIONER::MeshCollection::getFaceMesh(int idomain) -{ - return _face_mesh[idomain]; -} - -std::vector<MEDPARTITIONER::ConnectZone*>& MEDPARTITIONER::MeshCollection::getCZ() -{ - if ( _topology ) - return _topology->getCZ(); - - static std::vector<MEDPARTITIONER::ConnectZone*> noCZ; - return noCZ; -} - -MEDPARTITIONER::Topology* MEDPARTITIONER::MeshCollection::getTopology() const -{ - return _topology; -} - -void MEDPARTITIONER::MeshCollection::setTopology(Topology* topo, bool takeOwneship) -{ - if (_topology!=0) - { - throw INTERP_KERNEL::Exception("topology is already set"); - } - else - { - _topology = topo; - _owns_topology = takeOwneship; - } -} - -/*! Method creating the cell graph in serial mode - * - * \param array returns the pointer to the structure that contains the graph - * \param edgeweight returns the pointer to the table that contains the edgeweights - * (only used if indivisible regions are required) - */ -void MEDPARTITIONER::MeshCollection::buildCellGraph(ParaMEDMEM::MEDCouplingSkyLineArray* & array, int *& edgeweights ) -{ - - using std::map; - using std::vector; - using std::make_pair; - using std::pair; - - if (_topology->nbDomain()>1) throw INTERP_KERNEL::Exception("buildCellGraph should be used for one domain only"); - const ParaMEDMEM::MEDCouplingUMesh* mesh=_mesh[0]; - if (MyGlobals::_Verbose>50) - std::cout<<"getting nodal connectivity"<<std::endl; - - //looking for reverse nodal connectivity i global numbering - if (isParallelMode() && !_domain_selector->isMyDomain(0)) - { - vector<int> value; - vector<int> index(1,0); - - array=new ParaMEDMEM::MEDCouplingSkyLineArray(index,value); - return; - } - array=mesh->generateGraph(); -} -/*! Method creating the cell graph in multidomain mode - * - * \param array returns the pointer to the structure that contains the graph - * \param edgeweight returns the pointer to the table that contains the edgeweights - * (only used if indivisible regions are required) - */ -void MEDPARTITIONER::MeshCollection::buildParallelCellGraph(ParaMEDMEM::MEDCouplingSkyLineArray* & array, int *& edgeweights ) -{ - using std::multimap; - using std::vector; - using std::make_pair; - using std::pair; - - std::multimap< int, int > node2cell; - std::map< pair<int,int>, int > cell2cellcounter; - std::multimap<int,int> cell2cell; - - std::vector<std::vector<std::multimap<int,int> > > commonDistantNodes; - int nbdomain=_topology->nbDomain(); -#ifdef HAVE_MPI - if (isParallelMode()) - { - _joint_finder=new JointFinder(*this); - _joint_finder->findCommonDistantNodes(); - commonDistantNodes=_joint_finder->getDistantNodeCell(); - } - - if (MyGlobals::_Verbose>500) - _joint_finder->print(); -#endif - - if (MyGlobals::_Verbose>50) - std::cout<<"getting nodal connectivity"<<std::endl; - //looking for reverse nodal connectivity i global numbering - int meshDim = 3; - for (int idomain=0; idomain<nbdomain; idomain++) - { - if (isParallelMode() && !_domain_selector->isMyDomain(idomain)) - continue; - meshDim = _mesh[idomain]->getMeshDimension(); - - ParaMEDMEM::DataArrayInt* index=ParaMEDMEM::DataArrayInt::New(); - ParaMEDMEM::DataArrayInt* revConn=ParaMEDMEM::DataArrayInt::New(); - int nbNodes=_mesh[idomain]->getNumberOfNodes(); - _mesh[idomain]->getReverseNodalConnectivity(revConn,index); - //problem saturation over 1 000 000 nodes for 1 proc - if (MyGlobals::_Verbose>100) - std::cout << "proc " << MyGlobals::_Rank << " : getReverseNodalConnectivity done on " << nbNodes << " nodes" << std::endl; - int* index_ptr=index->getPointer(); - int* revConnPtr=revConn->getPointer(); - for (int i=0; i<nbNodes; i++) - { - for (int icell=index_ptr[i]; icell<index_ptr[i+1]; icell++) - { - int globalNode=_topology->convertNodeToGlobal(idomain,i); - int globalCell=_topology->convertCellToGlobal(idomain,revConnPtr[icell]); - node2cell.insert(make_pair(globalNode, globalCell)); - } - } - revConn->decrRef(); - index->decrRef(); -#ifdef HAVE_MPI - for (int iother=0; iother<nbdomain; iother++) - { - std::multimap<int,int>::iterator it; - int isource=idomain; - int itarget=iother; - for (it=_joint_finder->getDistantNodeCell()[isource][itarget].begin(); - it!=_joint_finder->getDistantNodeCell()[isource][itarget].end(); it++) - { - int globalNode=_topology->convertNodeToGlobal(idomain,(*it).first); - int globalCell=(*it).second; - node2cell.insert(make_pair(globalNode, globalCell)); - } - } -#endif - } //endfor idomain - - //creating graph arcs (cell to cell relations) - //arcs are stored in terms of (index,value) notation - // 0 3 5 6 6 - // 1 2 3 2 3 3 - // means 6 arcs (0,1), (0,2), (0,3), (1,2), (1,3), (2,3) - // in present version arcs are not doubled but reflexive (1,1) arcs are present for each cell - - //warning here one node have less than or equal effective number of cell with it - //but cell could have more than effective nodes - //because other equals nodes in other domain (with other global inode) - if (MyGlobals::_Verbose>50) - std::cout<< "proc " << MyGlobals::_Rank << " : creating graph arcs on nbNodes " << _topology->nbNodes() << std::endl; - - for (int inode=0;inode<_topology->nbNodes();inode++) - { - typedef multimap<int,int>::const_iterator MI; - std::pair <MI,MI> nodeRange=node2cell.equal_range(inode); - for (MI cell1=nodeRange.first;cell1!=nodeRange.second;cell1++) - for (MI cell2=nodeRange.first;cell2!=cell1;cell2++) - { - int icell1=cell1->second; - int icell2=cell2->second; - if (icell1>icell2) {int tmp=icell1; icell1=icell2; icell2=tmp;} - std::map<pair<int,int>,int>::iterator it=cell2cellcounter.find(make_pair(icell1,icell2)); - if (it==cell2cellcounter.end()) cell2cellcounter.insert(make_pair(make_pair(icell1,icell2),1)); - else (it->second)++; - } - } - // for (int icell1=0; icell1<_topology->nbCells(); icell1++) //on all nodes - // { - // typedef multimap<int,int>::const_iterator MI; - // std::pair <MI,MI> nodeRange=cell2node.equal_range(icell1); - // for (MI node1=nodeRange.first; node1!=nodeRange.second; node1++) //on nodes with icell - // { - // std::pair<MI,MI> cellRange=node2cell.equal_range(node1->second); - // for (MI cell2=cellRange.first; cell2!=cellRange.second; cell2++) //on one of these cell - // { - // int icell2=cell2->second; - // std::map<pair<int,int>,int>::iterator it=cell2cellcounter.find(make_pair(icell1,icell2)); - // if (it==cell2cellcounter.end()) cell2cellcounter.insert(make_pair(make_pair(icell1,icell2),1)); - // else (it->second)++; - // } - // } - // } - - - //converting the counter to a multimap structure - for (std::map<pair<int,int>,int>::const_iterator it=cell2cellcounter.begin(); - it!=cell2cellcounter.end(); - it++) - if (it->second>=meshDim) - { - cell2cell.insert(std::make_pair(it->first.first,it->first.second)); - cell2cell.insert(std::make_pair(it->first.second, it->first.first)); - } - - - if (MyGlobals::_Verbose>50) - std::cout << "proc " << MyGlobals::_Rank << " : create skylinearray" << std::endl; - //filling up index and value to create skylinearray structure - std::vector <int> index,value; - index.push_back(0); - int idep=0; - - for (int idomain=0; idomain<nbdomain; idomain++) - { - if (isParallelMode() && !_domain_selector->isMyDomain(idomain)) continue; - int nbCells=_mesh[idomain]->getNumberOfCells(); - for (int icell=0; icell<nbCells; icell++) - { - int size=0; - int globalCell=_topology->convertCellToGlobal(idomain,icell); - multimap<int,int>::iterator it; - pair<multimap<int,int>::iterator,multimap<int,int>::iterator> ret; - ret=cell2cell.equal_range(globalCell); - for (it=ret.first; it!=ret.second; ++it) - { - int ival=(*it).second; //no adding one existing yet - for (int i=idep ; i<idep+size ; i++) - { - if (value[i]==ival) - { - ival= -1; break; - } - } - if (ival!= -1) - { - value.push_back(ival); - size++; - } - } - idep=index[index.size()-1]+size; - index.push_back(idep); - } - } - - array=new ParaMEDMEM::MEDCouplingSkyLineArray(index,value); - - if (MyGlobals::_Verbose>100) - { - std::cout << "\nproc " << _domain_selector->rank() << " : end MeshCollection::buildCellGraph " << - index.size()-1 << " " << value.size() << std::endl; - int max=index.size()>15?15:index.size(); - if (index.size()>1) - { - for (int i=0; i<max; ++i) - std::cout<<index[i]<<" "; - std::cout << "... " << index[index.size()-1] << std::endl; - for (int i=0; i<max; ++i) - std::cout<< value[i] << " "; - int ll=index[index.size()-1]-1; - std::cout << "... (" << ll << ") " << value[ll-1] << " " << value[ll] << std::endl; - } - } - -} - - -/*! Creates the partition corresponding to the cell graph and the partition number - * - * \param nbdomain number of subdomains for the newly created graph - * - * returns a topology based on the new graph - */ -MEDPARTITIONER::Topology* MEDPARTITIONER::MeshCollection::createPartition(int nbdomain, - Graph::splitter_type split, - const std::string& options_string, - int *user_edge_weights, - int *user_vertices_weights) -{ - if (MyGlobals::_Verbose>10) - std::cout << "proc " << MyGlobals::_Rank << " : MeshCollection::createPartition : Building cell graph" << std::endl; - - if (nbdomain <1) - throw INTERP_KERNEL::Exception("Number of subdomains must be > 0"); - ParaMEDMEM::MEDCouplingSkyLineArray* array=0; - int* edgeweights=0; - - if (_topology->nbDomain()>1 || isParallelMode()) - buildParallelCellGraph(array,edgeweights); - else - buildCellGraph(array,edgeweights); - - Graph* cellGraph = 0; - switch (split) - { - case Graph::METIS: - if ( isParallelMode() && MyGlobals::_World_Size > 1 ) - { -#ifdef MED_ENABLE_PARMETIS - if (MyGlobals::_Verbose>10) - std::cout << "ParMETISGraph" << std::endl; - cellGraph=new ParMETISGraph(array,edgeweights); -#endif - } - if ( !cellGraph ) - { -#ifdef MED_ENABLE_METIS - if (MyGlobals::_Verbose>10) - std::cout << "METISGraph" << std::endl; - cellGraph=new METISGraph(array,edgeweights); -#endif - } - if ( !cellGraph ) - throw INTERP_KERNEL::Exception("MeshCollection::createPartition : PARMETIS/METIS is not available. Check your products, please."); - break; - - case Graph::SCOTCH: -#ifdef MED_ENABLE_SCOTCH - if (MyGlobals::_Verbose>10) - std::cout << "SCOTCHGraph" << std::endl; - cellGraph=new SCOTCHGraph(array,edgeweights); -#else - throw INTERP_KERNEL::Exception("MeshCollection::createPartition : SCOTCH is not available. Check your products, please."); -#endif - break; - } - - //!user-defined weights - if (user_edge_weights!=0) - cellGraph->setEdgesWeights(user_edge_weights); - if (user_vertices_weights!=0) - cellGraph->setVerticesWeights(user_vertices_weights); - - if (MyGlobals::_Is0verbose>10) - std::cout << "partitioning graph on " << nbdomain << " domains" << std::endl; - cellGraph->partGraph(nbdomain, options_string, _domain_selector); - - if (MyGlobals::_Is0verbose>10) - std::cout << "building new topology" << std::endl; - //cellGraph is a shared pointer - Topology *topology=0; - topology=new ParallelTopology (cellGraph, getTopology(), nbdomain, getMeshDimension()); - //cleaning - delete [] edgeweights; - delete cellGraph; - if (MyGlobals::_Verbose>11) - std::cout << "proc " << MyGlobals::_Rank << " : end MeshCollection::createPartition" << std::endl; - return topology; -} - -/*! Creates a topology for a partition specified by the user - * - * \param table user-specified partition (for each cell contains the domain number from 0 to n-1) - * - * returns a topology based on the new partition - */ -MEDPARTITIONER::Topology* MEDPARTITIONER::MeshCollection::createPartition(const int* partition) -{ - ParaMEDMEM::MEDCouplingSkyLineArray* array=0; - int* edgeweights=0; - - if ( _topology->nbDomain()>1) - buildParallelCellGraph(array,edgeweights); - else - buildCellGraph(array,edgeweights); - - Graph* cellGraph; - std::set<int> domains; - for (int i=0; i<_topology->nbCells(); i++) - { - domains.insert(partition[i]); - } - cellGraph=new UserGraph(array, partition, _topology->nbCells()); - - //cellGraph is a shared pointer - Topology *topology=0; - int nbdomain=domains.size(); - topology=new ParallelTopology (cellGraph, getTopology(), nbdomain, getMeshDimension()); - // if (array!=0) delete array; - delete cellGraph; - return topology; -} - -void MEDPARTITIONER::MeshCollection::setDomainNames(const std::string& name) -{ - for (int i=0; i<_topology->nbDomain(); i++) - { - std::ostringstream oss; - oss<<name<<"_"<<i; - if (!isParallelMode() || _domain_selector->isMyDomain(i)) - _mesh[i]->setName(oss.str()); - } -} - -ParaMEDMEM::DataArrayDouble *MEDPARTITIONER::MeshCollection::getField(std::string descriptionField, int iold) -//getField look for and read it if not done, and assume decrRef() in ~MeshCollection; -//something like MEDCouplingFieldDouble *f2=MEDLoader::ReadFieldCell(name,f1->getMesh()->getName(),0,f1->getName(),0,1); -{ - int rank=MyGlobals::_Rank; - std::string tag="ioldFieldDouble="+IntToStr(iold); - std::string descriptionIold=descriptionField+SerializeFromString(tag); - if (_map_dataarray_double.find(descriptionIold)!=_map_dataarray_double.end()) - { - if (MyGlobals::_Verbose>300) - std::cout << "proc " << rank << " : YET READ getField : " << descriptionIold << std::endl; - ParaMEDMEM::DataArrayDouble* res=_map_dataarray_double[descriptionIold]; - return res; - } - if (MyGlobals::_Verbose>200) - std::cout << "proc " << rank << " : TO BE READ getField : " << descriptionIold << std::endl; - std::string description, fileName, meshName, fieldName; - int typeField, DT, IT, entity; - fileName=MyGlobals::_File_Names[iold]; - if (MyGlobals::_Verbose>10) - std::cout << "proc " << MyGlobals::_Rank << " : in " << fileName << " " << iold << " " << descriptionIold << std::endl; - FieldShortDescriptionToData(descriptionIold, fieldName, typeField, entity, DT, IT); - meshName=MyGlobals::_Mesh_Names[iold]; - - ParaMEDMEM::MEDCouplingFieldDouble* f2=MEDLoader::ReadField((ParaMEDMEM::TypeOfField) typeField, - fileName, meshName, 0, fieldName, DT, IT); - - ParaMEDMEM::DataArrayDouble* res=f2->getArray(); - //to know names of components - std::vector<std::string> browse=BrowseFieldDouble(f2); - std::string localFieldInformation=descriptionIold+SerializeFromVectorOfString(browse); - if (MyGlobals::_Verbose>10) - std::cout << "proc " << MyGlobals::_Rank << " : localFieldInformation : " << localFieldInformation << std::endl; - MyGlobals::_General_Informations.push_back(localFieldInformation); - res->incrRef(); - f2->decrRef(); - _map_dataarray_double[descriptionIold]=res; - return res; -} - -void MEDPARTITIONER::MeshCollection::prepareFieldDescriptions() -//to have unique valid fields names/pointers/descriptions for partitionning -//filter _field_descriptions to be in all procs compliant and equal -{ - int nbfiles=MyGlobals::_File_Names.size(); //nb domains - if (nbfiles==0) - { - nbfiles=_topology->nbDomain(); - } - std::vector<std::string> r2; - //from allgatherv then vector(procs) of serialised vector(fields) of vector(description) data - for (int i=0; i<(int)_field_descriptions.size(); i++) - { - std::vector<std::string> r1=DeserializeToVectorOfString(_field_descriptions[i]); - for (int ii=0; ii<(int)r1.size(); ii++) - r2.push_back(r1[ii]); - } - //here vector(procs*fields) of serialised vector(description) data - _field_descriptions=r2; - int nbfields=_field_descriptions.size(); //on all domains - if ((nbfields%nbfiles)!=0) - { - if (MyGlobals::_Rank==0) - { - std::cerr<< "\nERROR : incoherent number of fields references in all files .med\n" << std::endl - << "fileMedNames :" << std::endl - << ReprVectorOfString(MyGlobals::_File_Names) - << "field_descriptions :" << std::endl - << ReprVectorOfString(MyGlobals::_Field_Descriptions); - } - throw INTERP_KERNEL::Exception("incoherent number of fields references in all files .med\n"); - } - _field_descriptions.resize(nbfields/nbfiles); - for (int i=0; i<(int)_field_descriptions.size(); i++) - { - std::string str=_field_descriptions[i]; - str=EraseTagSerialized(str,"idomain="); - str=EraseTagSerialized(str,"fileName="); - _field_descriptions[i]=str; - } -} - -//returns true if inodes of a face are in inodes of a cell -bool isFaceOncell(std::vector< int >& inodesFace, std::vector< int >& inodesCell) -{ - int ires=0; - int nbok=inodesFace.size(); - for (int i=0; i<nbok; i++) - { - int ii=inodesFace[i]; - if (ii<0) - std::cout << "isFaceOncell problem inodeface<0" << std::endl; - for (int j=0; j<(int)inodesCell.size(); j++) - { - if (ii==inodesCell[j]) - { - ires=ires+1; - break; //inode of face found - } - } - if (ires<i+1) - break; //inode of face not found do not continue... - } - return (ires==nbok); -} - -void MEDPARTITIONER::MeshCollection::filterFaceOnCell() -{ - for (int inew=0; inew<_topology->nbDomain(); inew++) - { - if (!isParallelMode() || _domain_selector->isMyDomain(inew)) - { - if (MyGlobals::_Verbose>200) - std::cout << "proc " << MyGlobals::_Rank << " : filterFaceOnCell on inewDomain " << inew << " nbOfFaces " << _face_mesh[inew]->getNumberOfCells() << std::endl; - ParaMEDMEM::MEDCouplingUMesh* mcel=_mesh[inew]; - ParaMEDMEM::MEDCouplingUMesh* mfac=_face_mesh[inew]; - - //to have cellnode=f(facenode)... inodeCell=nodeIds[inodeFace] - std::vector<int> nodeIds; - getNodeIds(*mcel, *mfac, nodeIds); - if (nodeIds.size()==0) - continue; //one empty mesh nothing to do - - ParaMEDMEM::DataArrayInt *revNodalCel=ParaMEDMEM::DataArrayInt::New(); - ParaMEDMEM::DataArrayInt *revNodalIndxCel=ParaMEDMEM::DataArrayInt::New(); - mcel->getReverseNodalConnectivity(revNodalCel,revNodalIndxCel); - int *revC=revNodalCel->getPointer(); - int *revIndxC=revNodalIndxCel->getPointer(); - - std::vector< int > faceOnCell; - std::vector< int > faceNotOnCell; - int nbface=mfac->getNumberOfCells(); - for (int iface=0; iface<nbface; iface++) - { - bool ok; - std::vector< int > inodesFace; - mfac->getNodeIdsOfCell(iface, inodesFace); - int nbnodFace=inodesFace.size(); - if ( nbnodFace != mfac->getNumberOfNodesInCell( iface )) - continue; // invalid node ids - //set inodesFace in mcel - int nbok = 0; - for (int i=0; i<nbnodFace; i++) - nbok += (( inodesFace[i]=nodeIds[inodesFace[i]] ) >= 0 ); - if ( nbok != nbnodFace ) - continue; - int inod=inodesFace[0]; - if (inod<0) - { - std::cout << "filterFaceOnCell problem 1" << std::endl; - continue; - } - int nbcell=revIndxC[inod+1]-revIndxC[inod]; - for (int j=0; j<nbcell; j++) //look for each cell with inod - { - int icel=revC[revIndxC[inod]+j]; - std::vector< int > inodesCell; - mcel->getNodeIdsOfCell(icel, inodesCell); - ok=isFaceOncell(inodesFace, inodesCell); - if (ok) break; - } - if (ok) - { - faceOnCell.push_back(iface); - } - else - { - faceNotOnCell.push_back(iface); - if (MyGlobals::_Is0verbose>300) - std::cout << "face NOT on cell " << iface << " " << faceOnCell.size()-1 << std::endl; - } - } - - revNodalCel->decrRef(); - revNodalIndxCel->decrRef(); - - // std::string keyy; - // keyy=Cle1ToStr("filterFaceOnCell",inew); - // _map_dataarray_int[keyy]=CreateDataArrayIntFromVector(faceOnCell); - // keyy=Cle1ToStr("filterNotFaceOnCell",inew); - // _map_dataarray_int[keyy]=CreateDataArrayIntFromVector(faceNotOnCell); - - // filter the face mesh - if ( faceOnCell.empty() ) - _face_mesh[inew] = CreateEmptyMEDCouplingUMesh(); - else - _face_mesh[inew] = (ParaMEDMEM::MEDCouplingUMesh *) - mfac->buildPartOfMySelf( &faceOnCell[0], &faceOnCell[0] + faceOnCell.size(),true); - mfac->decrRef(); - - // filter the face families - std::string key = Cle1ToStr("faceFamily_toArray",inew); - if ( getMapDataArrayInt().count( key )) - { - ParaMEDMEM::DataArrayInt * & fam = getMapDataArrayInt()[ key ]; - ParaMEDMEM::DataArrayInt * famFilter = ParaMEDMEM::DataArrayInt::New(); - famFilter->alloc(faceOnCell.size(),1); - int* pfamFilter = famFilter->getPointer(); - int* pfam = fam->getPointer(); - for ( size_t i=0; i<faceOnCell.size(); i++ ) - pfamFilter[i]=pfam[faceOnCell[i]]; - fam->decrRef(); - fam = famFilter; - } - } - } -} diff --git a/src/MEDPartitioner/MEDPARTITIONER_MeshCollection.hxx b/src/MEDPartitioner/MEDPARTITIONER_MeshCollection.hxx deleted file mode 100644 index 7f7ad1316..000000000 --- a/src/MEDPartitioner/MEDPARTITIONER_MeshCollection.hxx +++ /dev/null @@ -1,250 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// - -#ifndef __MEDPARTITIONER_MESHCOLLECTION_HXX__ -#define __MEDPARTITIONER_MESHCOLLECTION_HXX__ - -#include "MEDPARTITIONER.hxx" -#include "MEDPARTITIONER_Graph.hxx" -#include "MEDPARTITIONER_Utils.hxx" - -#include <map> -#include <vector> -#include <string> - -#include "BBTree.txx" - -namespace ParaMEDMEM -{ - class MEDCouplingUMesh; - class DataArrayInt; - class MEDCouplingSkyLineArray; -} - -namespace MEDPARTITIONER -{ - class Topology; - class MeshCollectionDriver; - class ParaDomainSelector; - class ConnectZone; - class JointFinder; - - typedef enum{MedAscii, MedXml, Undefined} DriverType; - typedef std::multimap<std::pair<int,int>, std::pair<int,int> > NodeMapping ; - typedef std::vector<std::pair<int,int> > NodeList; - - class MEDPARTITIONER_EXPORT MeshCollection - { - public: - MeshCollection(); - //Constructing from an existing mesh and a new topology - MeshCollection(MeshCollection&, Topology*, bool family_splitting=false, bool create_empty_groups=false); - //Constructing the mesh collection from a file - MeshCollection(const std::string& filename); - //Constructing the mesh collection from a file - MeshCollection(const std::string& filename, ParaDomainSelector& domainSelector); - //Constructing the mesh collection from a file - MeshCollection(const std::string& filename, const std::string& meshname); - ~MeshCollection(); - bool isParallelMode() const { return _domain_selector; } - - //writing to a distributed file - void write(const std::string& filename); - - //getting the driver - MeshCollectionDriver *retrieveDriver(); - MeshCollectionDriver *getDriver() const; - void setDriverType(MEDPARTITIONER::DriverType type) { _driver_type=type; } - - //creation of the cell graph - void buildCellGraph(ParaMEDMEM::MEDCouplingSkyLineArray* & array,int *& edgeweights ); - //creation of the cell graph - void buildParallelCellGraph(ParaMEDMEM::MEDCouplingSkyLineArray* & array,int *& edgeweights ); - - //creation and partition of the associated graph - Topology* createPartition(int nbdomain, Graph::splitter_type type = Graph::METIS, - const std::string& ="", int* edgeweights=0, int* verticesweights=0); - - //creation of a user specified partition - Topology* createPartition(const int* partition); - - //getting mesh dimension - int getMeshDimension() const; - int getNbOfLocalMeshes() const; - int getNbOfGlobalMeshes() const { return _mesh.size(); } - int getNbOfLocalCells() const; - int getNbOfLocalFaces() const; - - //getting a reference to mesh vector - std::vector<ParaMEDMEM::MEDCouplingUMesh*>& getMesh(); - std::vector<ParaMEDMEM::MEDCouplingUMesh*>& getFaceMesh(); - std::vector<std::vector<ParaMEDMEM::MEDCouplingUMesh*> >& getGroupMeshes(); - - ParaMEDMEM::MEDCouplingUMesh* getMesh(int idomain) const; - ParaMEDMEM::MEDCouplingUMesh* getFaceMesh(int idomain); - std::vector<ParaMEDMEM::MEDCouplingUMesh*>& getGroupMeshes(int idomain); - - std::vector<ParaMEDMEM::DataArrayInt*>& getCellFamilyIds() { return _cell_family_ids; } - std::vector<ParaMEDMEM::DataArrayInt*>& getFaceFamilyIds() { return _face_family_ids; } - - std::map<std::string, ParaMEDMEM::DataArrayInt*>& getMapDataArrayInt() { return _map_dataarray_int; } - std::map<std::string, ParaMEDMEM::DataArrayDouble*>& getMapDataArrayDouble() { return _map_dataarray_double; } - - std::map<std::string,int>& getFamilyInfo() { return _family_info; } - std::map<std::string, std::vector<std::string> >& getGroupInfo() { return _group_info; } - - ParaMEDMEM::DataArrayDouble* getField(std::string descriptionField, int iold); - std::vector<std::string>& getFieldDescriptions() { return _field_descriptions; } - void prepareFieldDescriptions(); - void filterFaceOnCell(); - - //getting a reference to connect zones vector - std::vector<MEDPARTITIONER::ConnectZone*>& getCZ(); - - //getting a pointer to topology - Topology* getTopology() const ; - ParaDomainSelector* getParaDomainSelector() const { return _domain_selector; } - void setParaDomainSelector(ParaDomainSelector* pds) { _domain_selector = pds; } - //setting a new topology - void setTopology(Topology* topology, bool takeOwneship); - - //getting/setting the name of the global mesh (as opposed - //to the name of a subdomain \a nn, which is name_nn) - std::string getName() const { return _name; } - void setName(const std::string& name) { _name=name; } - void setDomainNames(const std::string& name); - - void setNonEmptyMesh(int number) { _i_non_empty_mesh=number;} - - //getting/setting the description of the global mesh - std::string getDescription() const { return _description; } - void setDescription(const std::string& name) { _description=name; } - - //creates the node mapping between an old collection and the present one - void createNodeMapping(MeshCollection& initialCollection, - std::multimap<std::pair<int,int>,std::pair<int,int> >& nodeMapping); - - void castCellMeshes(MeshCollection& initialCollection, - std::vector<std::vector<std::vector<int> > >& new2oldIds, - std::vector<ParaMEDMEM::DataArrayInt*> & o2nRenumber); - - //creates faces on the new collection - void castFaceMeshes(MeshCollection& initialCollection, - const std::multimap<std::pair<int,int>, std::pair<int,int> >& nodeMapping, - std::vector<std::vector<std::vector<int> > >& new2oldIds); - - //constructing connect zones - void buildConnectZones( const NodeMapping& nodeMapping, - const std::vector<ParaMEDMEM::DataArrayInt*> & o2nRenumber, - int nbInitialDomains ); - - // Find faces common with neighbor domains and put them in groups - void buildBoundaryFaces(); - - private: - void castIntField(std::vector<ParaMEDMEM::MEDCouplingUMesh*>& meshesCastFrom, - std::vector<ParaMEDMEM::MEDCouplingUMesh*>& meshesCastTo, - std::vector<ParaMEDMEM::DataArrayInt*>& arrayFrom, - std::string nameArrayTo); - - void castAllFields(MeshCollection& initialCollection, - std::string nameArrayTo); - - void findCommonDistantNodes(std::vector<std::vector<std::multimap<int,int> > >& commonDistantNodes); - - - void remapIntField(int inew, int iold, - const ParaMEDMEM::MEDCouplingUMesh& sourceMesh, - const ParaMEDMEM::MEDCouplingUMesh& targetMesh, - const int* fromArray, - std::string nameArrayTo, - const BBTreeOfDim* tree); - - void remapDoubleField(int inew, int iold, - ParaMEDMEM::DataArrayDouble* fromArray, - std::string nameArrayTo, - std::string descriptionField); - - void createJointGroup( const std::vector< int >& faces, - const int inew1, - const int inew2, - const bool is2nd ); - private: - - //link to mesh_collection topology - Topology* _topology; - - //control over topology - bool _owns_topology; - - //Driver for read/write operations - MeshCollectionDriver* _driver; - - //Parallelizer - mark of parallel execution mode - ParaDomainSelector* _domain_selector; - - //links to meshes - std::vector<ParaMEDMEM::MEDCouplingUMesh*> _mesh; - std::vector<ParaMEDMEM::MEDCouplingUMesh*> _face_mesh; - - //index of a non empty mesh within _mesh (in parallel mode all of meshes can be empty) - int _i_non_empty_mesh; - - //family ids storages - std::vector<ParaMEDMEM::DataArrayInt*> _cell_family_ids; - std::vector<ParaMEDMEM::DataArrayInt*> _face_family_ids; - - //DataArrayInt* storages - std::map<std::string, ParaMEDMEM::DataArrayInt*> _map_dataarray_int; - //DataArrayDouble* storages - std::map<std::string, ParaMEDMEM::DataArrayDouble*> _map_dataarray_double; - - //fields to be partitioned - std::vector<std::string> _field_descriptions; - - //group family conversion - std::map<std::string, int> _family_info; - std::map<std::string, std::vector<std::string> > _group_info; - - //list of groups that are not to be splitted - std::vector<std::string> _indivisible_regions; - - //name of global mesh - std::string _name; - - //description of global mesh - std::string _description; - - //specifies the driver associated to the collection - DriverType _driver_type; - - //flag specifying that the splitter should create boundary constituent entity - //so that they are written in joints - bool _subdomain_boundary_creates; - - //flag specifying that families must be preserved by the splitting - bool _family_splitting; - - //flag specifying that groups must be created on all domains, even if they are empty - bool _create_empty_groups; - - JointFinder* _joint_finder; - }; -} -#endif diff --git a/src/MEDPartitioner/MEDPARTITIONER_MeshCollectionDriver.cxx b/src/MEDPartitioner/MEDPARTITIONER_MeshCollectionDriver.cxx deleted file mode 100644 index 68f12e7a5..000000000 --- a/src/MEDPartitioner/MEDPARTITIONER_MeshCollectionDriver.cxx +++ /dev/null @@ -1,462 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// - -#include "MEDPARTITIONER_MeshCollectionDriver.hxx" - -#include "MEDPARTITIONER_ConnectZone.hxx" -#include "MEDPARTITIONER_MeshCollection.hxx" -#include "MEDPARTITIONER_ParaDomainSelector.hxx" -#include "MEDPARTITIONER_ParallelTopology.hxx" -#include "MEDPARTITIONER_Utils.hxx" - -#include "MEDCouplingFieldDouble.hxx" -#include "MEDCouplingRefCountObject.hxx" -#include "MEDCouplingSkyLineArray.hxx" -#include "MEDCouplingUMesh.hxx" -#include "MEDFileData.hxx" -#include "MEDFileField.hxx" -#include "MEDFileJoint.hxx" -#include "MEDFileMesh.hxx" -#include "MEDLoader.hxx" - -#include <map> -#include <set> -#include <vector> -#include <string> -#include <fstream> -#include <iostream> - -#include <libxml/tree.h> -#include <libxml/parser.h> -#include <libxml/xpath.h> -#include <libxml/xpathInternals.h> - -#include "med.h" - -using namespace MEDPARTITIONER; - -MeshCollectionDriver::MeshCollectionDriver(MeshCollection* collection):_collection(collection) -{ -} - -/*!reads a unique MED File v>=2.1 - * and mounts the corresponding mesh in memory - *\param filename binary file - *\param meshname mesh name in the MED file - * */ -int MeshCollectionDriver::readSeq(const char* filename, const char* meshname) -{ - std::cout << "readSeq" << std::endl; - MyGlobals::_File_Names.resize(1); - MyGlobals::_File_Names[0]=std::string(filename); - - ParaMEDMEM::MEDFileUMesh* mfm=ParaMEDMEM::MEDFileUMesh::New(filename,meshname); - //puts the only mesh in the mesh vector - (_collection->getMesh()).push_back(mfm->getLevel0Mesh(false)); - (_collection->getFaceMesh()).push_back(mfm->getLevelM1Mesh(false)); - - //reading family ids - ParaMEDMEM::DataArrayInt* cellIds(mfm->getFamilyFieldAtLevel(0)->deepCpy()); - ParaMEDMEM::DataArrayInt* faceIds(mfm->getFamilyFieldAtLevel(-1)->deepCpy()); - (_collection->getCellFamilyIds()).push_back(cellIds); - (_collection->getFaceFamilyIds()).push_back(faceIds); - - //reading groups - (_collection->getFamilyInfo())=mfm->getFamilyInfo(); - (_collection->getGroupInfo())=mfm->getGroupInfo(); - - (_collection->getCZ()).clear(); - - ParallelTopology* aPT = new ParallelTopology((_collection->getMesh())); - _collection->setTopology(aPT, true); - _collection->setName(meshname); - _collection->setDomainNames(meshname); - return 0; -} - - -void MeshCollectionDriver::readMEDFileData(const ParaMEDMEM::MEDFileData* filedata) -{ - const int nbDomains = filedata->getMeshes()->getNumberOfMeshes(); - _collection->getMesh() .resize( nbDomains, 0 ); - _collection->getFaceMesh() .resize( nbDomains, 0 ); - _collection->getCellFamilyIds().resize( nbDomains, 0 ); - _collection->getFaceFamilyIds().resize( nbDomains, 0 ); - - for (int i=0; i<nbDomains; i++) - { - ParaMEDMEM::MEDFileUMesh *mfm = dynamic_cast<ParaMEDMEM::MEDFileUMesh *>(filedata->getMeshes()->getMeshAtPos(i)); - readData(mfm,i); - if ( mfm && mfm->getMeshDimension() > 0 ) - _collection->setNonEmptyMesh( i ); - } - - ParallelTopology* aPT = new ParallelTopology(_collection->getMesh()); - _collection->setTopology(aPT, true); - if ( nbDomains > 0 ) - { - _collection->setName( filedata->getMeshes()->getMeshAtPos(0)->getName() ); - _collection->setDomainNames( _collection->getName() ); - } - if ( ParaDomainSelector* domainSelector = _collection->getParaDomainSelector() ) - if ( _collection->isParallelMode() ) - { - //to know nb of cells on each proc to compute global cell ids from locally global - domainSelector->gatherNbOf(_collection->getMesh()); - } -} - -void MeshCollectionDriver::readFileData(std::string file,std::string meshname,int idomain) const -{ - ParaMEDMEM::MEDFileUMesh* mfm=ParaMEDMEM::MEDFileUMesh::New(file,meshname); - readData(mfm,idomain); - mfm->decrRef(); -} - -void MeshCollectionDriver::readData(ParaMEDMEM::MEDFileUMesh* mfm, int idomain) const -{ - std::vector<int> nonEmpty=mfm->getNonEmptyLevels(); - try - { - (_collection->getMesh())[idomain]=mfm->getLevel0Mesh(false); - //reading families groups - ParaMEDMEM::DataArrayInt* cellIds(mfm->getFamilyFieldAtLevel(0)->deepCpy()); - (_collection->getCellFamilyIds())[idomain]=cellIds; - } - catch(...) - { - (_collection->getMesh())[idomain]=CreateEmptyMEDCouplingUMesh(); // or 0 if you want tests; - ParaMEDMEM::DataArrayInt* empty=ParaMEDMEM::DataArrayInt::New(); - empty->alloc(0,1); - (_collection->getCellFamilyIds())[idomain]=empty; - std::cout<<"\nNO Level0Mesh (Cells)\n"; - } - try - { - if (nonEmpty.size()>1 && nonEmpty[1]==-1) - { - (_collection->getFaceMesh())[idomain]=mfm->getLevelM1Mesh(false); - //reading families groups - ParaMEDMEM::DataArrayInt* faceIds(mfm->getFamilyFieldAtLevel(-1)->deepCpy()); - (_collection->getFaceFamilyIds())[idomain]=faceIds; - if (MyGlobals::_Verbose>10) - std::cout << "proc " << MyGlobals::_Rank << " : WITH Faces\n"; - } - else - { - throw INTERP_KERNEL::Exception("no faces"); - } - } - catch(...) - { - (_collection->getFaceMesh())[idomain]=CreateEmptyMEDCouplingUMesh(); // or 0 if you want test; - ParaMEDMEM::DataArrayInt* empty=ParaMEDMEM::DataArrayInt::New(); - (_collection->getFaceFamilyIds())[idomain]=empty; - if (MyGlobals::_Verbose>10) - std::cout << "proc " << MyGlobals::_Rank << " : WITHOUT Faces\n"; - } - //reading groups - _collection->getFamilyInfo()=mfm->getFamilyInfo(); - _collection->getGroupInfo()=mfm->getGroupInfo(); -} - -void MeshCollectionDriver::readSubdomain(int idomain) -{ - std::string meshname=MyGlobals::_Mesh_Names[idomain]; - std::string file=MyGlobals::_File_Names[idomain]; - readFileData(file,meshname,idomain); - - std::vector<std::string> localInformation; - std::string str; - localInformation.push_back(str+"ioldDomain="+IntToStr(idomain)); - localInformation.push_back(str+"meshName="+meshname); - MyGlobals::_General_Informations.push_back(SerializeFromVectorOfString(localInformation)); - std::vector<std::string> localFields=BrowseAllFieldsOnMesh(file, meshname, idomain); - if (localFields.size()>0) - MyGlobals::_Field_Descriptions.push_back(SerializeFromVectorOfString(localFields)); -} - -ParaMEDMEM::MEDFileMesh* MeshCollectionDriver::getMesh(int idomain) const -{ - ParaMEDMEM::MEDFileUMesh* mfm = ParaMEDMEM::MEDFileUMesh::New(); - - ParaMEDMEM::MEDCouplingUMesh* cellMesh=_collection->getMesh(idomain); - ParaMEDMEM::MEDCouplingUMesh* faceMesh=_collection->getFaceMesh(idomain); - // std::string cleFilter=Cle1ToStr("filterFaceOnCell",idomain); - // ParaMEDMEM::DataArrayInt* filter=0; - // if (_collection->getMapDataArrayInt().find(cleFilter)!=_collection->getMapDataArrayInt().end()) - // { - // filter=_collection->getMapDataArrayInt().find(cleFilter)->second; - // int* index=filter->getPointer(); - // faceMeshFilter=(ParaMEDMEM::MEDCouplingUMesh *) faceMesh->buildPartOfMySelf(index,index+filter->getNbOfElems(),true); - // faceMesh=faceMeshFilter; - // } - // if (faceMeshFilter!=0) - // faceMeshFilter->decrRef(); - std::string finalMeshName=""; - if (MyGlobals::_General_Informations.size()!=0) - { - std::size_t found=MyGlobals::_General_Informations[0].find("finalMeshName="); - if ((found!=std::string::npos) && (found>0)) - { - finalMeshName=ExtractFromDescription(MyGlobals::_General_Informations[0], "finalMeshName="); - } - } - if (finalMeshName.empty()) - { - finalMeshName=_collection->getName(); - } - cellMesh->setName(finalMeshName); - mfm->setMeshAtLevel( 0, cellMesh ); - - faceMesh->checkCoherency(); - if (faceMesh->getNumberOfCells()>0) - { - faceMesh->tryToShareSameCoordsPermute(*cellMesh, 1e-10); - faceMesh->setName(finalMeshName); - mfm->setMeshAtLevel( -1, faceMesh ); - } - - // ParaMEDMEM::MEDCouplingUMesh* boundaryMesh=0; - // if (MyGlobals::_Creates_Boundary_Faces>0) - // { - // //try to write Boundary meshes - // bool keepCoords=false; //TODO or true - // boundaryMesh=(ParaMEDMEM::MEDCouplingUMesh *) cellMesh->buildBoundaryMesh(keepCoords); - // boundaryMesh->setName("boundaryMesh"); - // if (boundaryMesh!=0) - // { - // //doing that testMesh becomes second mesh sorted by alphabetical order of name - // MEDLoader::WriteUMesh(distfilename, boundaryMesh, false); - // boundaryMesh->decrRef(); - // } - - mfm->setFamilyInfo(_collection->getFamilyInfo()); - mfm->setGroupInfo(_collection->getGroupInfo()); - std::string key=Cle1ToStr("faceFamily_toArray",idomain); - if ( faceMesh->getNumberOfCells()>0 && _collection->getMapDataArrayInt().find(key)!=_collection->getMapDataArrayInt().end()) - mfm->setFamilyFieldArr(-1,_collection->getMapDataArrayInt().find(key)->second); - key=Cle1ToStr("cellFamily_toArray",idomain); - if (_collection->getMapDataArrayInt().find(key)!=_collection->getMapDataArrayInt().end()) - mfm->setFamilyFieldArr(0,_collection->getMapDataArrayInt().find(key)->second); - - // add joints - - using ParaMEDMEM::MEDCouplingAutoRefCountObjectPtr; - using ParaMEDMEM::MEDCouplingSkyLineArray; - using ParaMEDMEM::MEDFileJoint; - using ParaMEDMEM::MEDFileJointCorrespondence; - using ParaMEDMEM::MEDFileJointOneStep; - using ParaMEDMEM::MEDFileJoints; - using ParaMEDMEM::MEDFileJoints; - - if ( _collection->getCZ().size() > 0 ) - { - MEDCouplingAutoRefCountObjectPtr< MEDFileJoints > joints = MEDFileJoints::New(); - - for ( size_t i = 0; i < _collection->getCZ().size(); ++i ) - { - ConnectZone* cz = _collection->getCZ()[i]; - if ( !cz || - cz->getLocalDomainNumber() != idomain ) - continue; - { - std::ostringstream oss; - oss << "joint_" << cz->getDistantDomainNumber(); - cz->setName( oss.str() ); - } - { - std::ostringstream oss; - oss << "connect_zone_" << i; - cz->setDescription( oss.str() ); - } - - MEDCouplingAutoRefCountObjectPtr< MEDFileJoint> - joint = MEDFileJoint::New( cz->getName(), finalMeshName, - finalMeshName, cz->getDistantDomainNumber() ); - joint->setDescription( cz->getDescription() ); - joints->pushJoint( joint ); - - MEDCouplingAutoRefCountObjectPtr< MEDFileJointOneStep> j1st = MEDFileJointOneStep::New(); - joint->pushStep( j1st ); - - const MEDCouplingSkyLineArray * nodeCorr = cz->getNodeCorresp(); - if ( nodeCorr ) - { - MEDCouplingAutoRefCountObjectPtr< MEDFileJointCorrespondence > - corr = MEDFileJointCorrespondence::New( nodeCorr->getValueArray() ); - j1st->pushCorrespondence( corr ); - } - - std::vector< std::pair< int,int > > types = cz->getEntities(); - INTERP_KERNEL::NormalizedCellType t1, t2; - for ( size_t it = 0; it < types.size(); ++it ) - { - const MEDCouplingSkyLineArray * cellCorr = - cz->getEntityCorresp( types[it].first, types[it].second ); - if ( cellCorr && cellCorr->getNumberOf() > 0 ) - { - t1 = INTERP_KERNEL::NormalizedCellType( types[it].first ); - t2 = INTERP_KERNEL::NormalizedCellType( types[it].second ); - MEDCouplingAutoRefCountObjectPtr< MEDFileJointCorrespondence> - corr = MEDFileJointCorrespondence::New( cellCorr->getValueArray(), t1, t2 ); - j1st->pushCorrespondence( corr ); - } - } - } - mfm->setJoints( joints ); - } - - return mfm; -} - -ParaMEDMEM::MEDCouplingFieldDouble* MeshCollectionDriver::getField(std::string key, std::string description, ParaMEDMEM::DataArrayDouble* data, ParaMEDMEM::MEDFileMesh* mfm, int idomain) const -{ - std::string desc=description; - if (MyGlobals::_Verbose>20) - std::cout << "proc " << MyGlobals::_Rank << " : write field " << desc << std::endl; - std::string meshName, fieldName; - int typeField, DT, IT, entity; - FieldShortDescriptionToData(desc, fieldName, typeField, entity, DT, IT); - double time=StrToDouble(ExtractFromDescription(desc, "time=")); - int typeData=StrToInt(ExtractFromDescription(desc, "typeData=")); - std::string entityName=ExtractFromDescription(desc, "entityName="); - ParaMEDMEM::MEDCouplingFieldDouble* field=0; - if (typeData!=6) - { - std::cout << "WARNING : writeMedFile : typeData " << typeData << " not implemented for fields\n"; - } - if (entityName=="MED_CELL") - { - //there is a field of idomain to write - field=ParaMEDMEM::MEDCouplingFieldDouble::New(ParaMEDMEM::ON_CELLS,ParaMEDMEM::ONE_TIME); - } - if (entityName=="MED_NODE_ELEMENT") - { - //there is a field of idomain to write - field=ParaMEDMEM::MEDCouplingFieldDouble::New(ParaMEDMEM::ON_GAUSS_NE,ParaMEDMEM::ONE_TIME); - } - if (!field) - { - std::cout << "WARNING : writeMedFile : entityName " << entityName << " not implemented for fields\n"; - } - if (field && typeData==6) - { - field->setName(fieldName); - field->setMesh(mfm->getGenMeshAtLevel(0)); - ParaMEDMEM::DataArrayDouble *da=data; - //get information for components etc.. - std::vector<std::string> r1; - r1=SelectTagsInVectorOfString(MyGlobals::_General_Informations,"fieldName="+fieldName); - r1=SelectTagsInVectorOfString(r1,"typeField="+IntToStr(typeField)); - r1=SelectTagsInVectorOfString(r1,"DT="+IntToStr(DT)); - r1=SelectTagsInVectorOfString(r1,"IT="+IntToStr(IT)); - //not saved in file? field->setDescription(ExtractFromDescription(r1[0], "fieldDescription=")); - int nbc=StrToInt(ExtractFromDescription(r1[0], "nbComponents=")); - if (nbc==da->getNumberOfComponents()) - { - for (int i=0; i<nbc; i++) - da->setInfoOnComponent(i,ExtractFromDescription(r1[0], "componentInfo"+IntToStr(i)+"=")); - } - else - { - std::cerr << "Problem On field " << fieldName << " : number of components unexpected " << da->getNumberOfComponents() << std::endl; - } - field->setArray(da); - field->setTime(time,DT,IT); - field->checkCoherency(); - } - return field; -} - -void MeshCollectionDriver::writeMedFile(int idomain, const std::string& distfilename) const -{ - ParaMEDMEM::MEDFileMesh* mfm = getMesh( idomain ); - mfm->write(distfilename,2); - - std::string key="/inewFieldDouble="+IntToStr(idomain)+"/"; - std::map<std::string,ParaMEDMEM::DataArrayDouble*>::iterator it; - int nbfFieldFound=0; - for (it=_collection->getMapDataArrayDouble().begin() ; it!=_collection->getMapDataArrayDouble().end(); it++) - { - size_t found=(*it).first.find(key); - if (found==std::string::npos) - continue; - ParaMEDMEM::MEDCouplingFieldDouble* field=0; - field = getField(key, (*it).first, (*it).second, mfm, idomain); - nbfFieldFound++; - try - { - MEDLoader::WriteField(distfilename,field,false); - } - catch(INTERP_KERNEL::Exception& e) - { - //cout trying rewrite all data, only one field defined - std::string tmp,newName=distfilename; - std::string fieldName; - fieldName=field->getName(); - tmp+="_"+fieldName+"_"+IntToStr(nbfFieldFound)+".med"; - newName.replace(newName.find(".med"),4,tmp); - std::cout << "WARNING : writeMedFile : create a new file name with only one field because MEDLoader::WriteField throw:" << newName << std::endl; - MEDLoader::WriteField(newName,field,true); - } - } - mfm->decrRef(); -} - -ParaMEDMEM::MEDFileData* MeshCollectionDriver::getMEDFileData() -{ - ParaMEDMEM::MEDFileData* newdata = ParaMEDMEM::MEDFileData::New(); - - ParaMEDMEM::MEDCouplingAutoRefCountObjectPtr<ParaMEDMEM::MEDFileMeshes> meshes; - ParaMEDMEM::MEDCouplingAutoRefCountObjectPtr<ParaMEDMEM::MEDFileFields> fields; - meshes = ParaMEDMEM::MEDFileMeshes::New(); - fields = ParaMEDMEM::MEDFileFields::New(); - - for (size_t i=0; i<_collection->getMesh().size(); i++) - { - ParaMEDMEM::MEDFileMesh* mfm = getMesh( i ); - meshes->pushMesh(mfm); - - std::string key="/inewFieldDouble="+IntToStr(i)+"/"; - std::map<std::string,ParaMEDMEM::DataArrayDouble*>::iterator it; - ParaMEDMEM::MEDFileFieldMultiTS* fieldsMTS = ParaMEDMEM::MEDFileFieldMultiTS::New(); - for (it=_collection->getMapDataArrayDouble().begin() ; it!=_collection->getMapDataArrayDouble().end(); it++) - { - size_t found=(*it).first.find(key); - if (found==std::string::npos) - continue; - ParaMEDMEM::MEDCouplingFieldDouble* field=0; - field=getField(key, (*it).first, (*it).second, mfm, i); - ParaMEDMEM::MEDFileField1TS* f1ts = ParaMEDMEM::MEDFileField1TS::New(); - f1ts->setFieldNoProfileSBT(field); - fieldsMTS->pushBackTimeStep(f1ts); - - field->decrRef(); - f1ts->decrRef(); - } - fields->pushField(fieldsMTS); - - fieldsMTS->decrRef(); - mfm->decrRef(); - } - newdata->setMeshes(meshes); - newdata->setFields(fields); - return newdata; -} diff --git a/src/MEDPartitioner/MEDPARTITIONER_MeshCollectionDriver.hxx b/src/MEDPartitioner/MEDPARTITIONER_MeshCollectionDriver.hxx deleted file mode 100644 index c378a3408..000000000 --- a/src/MEDPartitioner/MEDPARTITIONER_MeshCollectionDriver.hxx +++ /dev/null @@ -1,63 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// - -#ifndef __MEDPARTITIONER_MESHCOLLECTIONDRIVER_HXX__ -#define __MEDPARTITIONER_MESHCOLLECTIONDRIVER_HXX__ - -#include "MEDPARTITIONER.hxx" - -#include <vector> -#include <string> - -namespace ParaMEDMEM -{ - class DataArrayDouble; - class MEDCouplingFieldDouble; - class MEDFileData; - class MEDFileMesh; - class MEDFileUMesh; -} - -namespace MEDPARTITIONER -{ - class MeshCollection; - class ParaDomainSelector; - - class MEDPARTITIONER_EXPORT MeshCollectionDriver - { - public: - MeshCollectionDriver(MeshCollection*); - virtual ~MeshCollectionDriver() { } - virtual int read(const char*, ParaDomainSelector* sel=0) = 0; - int readSeq(const char*,const char*); - ParaMEDMEM::MEDFileData *getMEDFileData(); - virtual void write(const char*, ParaDomainSelector* sel=0) const = 0; - void readMEDFileData(const ParaMEDMEM::MEDFileData* filedata); - protected: - void readSubdomain(int idomain); - void readData(ParaMEDMEM::MEDFileUMesh* mfm, int idomain) const; - void readFileData(std::string file,std::string meshname,int idomain) const; - ParaMEDMEM::MEDFileMesh* getMesh(int idomain) const; - ParaMEDMEM::MEDCouplingFieldDouble* getField(std::string key, std::string description, ParaMEDMEM::DataArrayDouble* data, ParaMEDMEM::MEDFileMesh* mfm, int idomain) const; - void writeMedFile(int idomain, const std::string& distfilename) const; - protected: - MeshCollection* _collection; - }; -} -#endif diff --git a/src/MEDPartitioner/MEDPARTITIONER_MeshCollectionMedAsciiDriver.cxx b/src/MEDPartitioner/MEDPARTITIONER_MeshCollectionMedAsciiDriver.cxx deleted file mode 100644 index 4eb8360cb..000000000 --- a/src/MEDPartitioner/MEDPARTITIONER_MeshCollectionMedAsciiDriver.cxx +++ /dev/null @@ -1,205 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// - -#include "MEDPARTITIONER_ParallelTopology.hxx" -#include "MEDPARTITIONER_MeshCollectionDriver.hxx" -#include "MEDPARTITIONER_MeshCollection.hxx" -#include "MEDPARTITIONER_MeshCollectionMedAsciiDriver.hxx" -#include "MEDPARTITIONER_ParaDomainSelector.hxx" -#include "MEDPARTITIONER_Utils.hxx" - -#include "MEDCouplingUMesh.hxx" -#include "MEDLoader.hxx" - -#include <map> -#include <set> -#include <vector> -#include <string> -#include <fstream> -#include <iostream> - -#include <libxml/tree.h> -#include <libxml/parser.h> -#include <libxml/xpath.h> -#include <libxml/xpathInternals.h> - -using namespace MEDPARTITIONER; - -MeshCollectionMedAsciiDriver::MeshCollectionMedAsciiDriver(MeshCollection* collection):MeshCollectionDriver(collection) -{ -} - -/*!reads a MED File v>=2.3 - * and mounts the corresponding meshes in memory - * the connect zones are created from the joints - * - *\param filename ascii file containing the list of MED v2.3 files - * */ - -int MeshCollectionMedAsciiDriver::read(ParaMEDMEM::MEDFileData* filedata) -{ - readMEDFileData(filedata); - - std::vector<MEDPARTITIONER::ConnectZone*> cz; // to fill from filedata - std::vector<int*> cellglobal; - std::vector<int*> nodeglobal; - std::vector<int*> faceglobal; - int size = (_collection->getMesh()).size(); - cellglobal.resize(size); - nodeglobal.resize(size); - faceglobal.resize(size); - for ( int idomain = 0; idomain < size; ++idomain ) - { - cellglobal[idomain]=0; - faceglobal[idomain]=0; - nodeglobal[idomain]=0; - if ( (_collection->getMesh())[idomain] && (_collection->getMesh())[idomain]->getNumberOfNodes() > 0 ) - _collection->setNonEmptyMesh(idomain); - } - //creation of topology from mesh and connect zones - ParallelTopology* aPT = new ParallelTopology((_collection->getMesh()), cz, cellglobal, nodeglobal, faceglobal); - _collection->setTopology(aPT,true); - - return 0; -} - -/*!reads a MED File v>=2.3 - * and mounts the corresponding meshes in memory - * the connect zones are created from the joints - * - *\param filename ascii file containing the list of MED v2.3 files - * */ - -int MeshCollectionMedAsciiDriver::read(const char* filename, ParaDomainSelector* domainSelector) -{ - //distributed meshes - std::vector<int*> cellglobal; - std::vector<int*> nodeglobal; - std::vector<int*> faceglobal; - int nbdomain; - - //reading ascii master file - try - { - std::ifstream asciiinput(filename); - if (!asciiinput) - throw INTERP_KERNEL::Exception("Master ASCII File does not exist"); - char charbuffer[512]; - asciiinput.getline(charbuffer,512); - - while (charbuffer[0]=='#') - { - asciiinput.getline(charbuffer,512); - } - - //reading number of domains - nbdomain=atoi(charbuffer); - MyGlobals::_File_Names.resize(nbdomain); - MyGlobals::_Mesh_Names.resize(nbdomain); - (_collection->getMesh()).resize(nbdomain); - cellglobal.resize(nbdomain); - nodeglobal.resize(nbdomain); - faceglobal.resize(nbdomain); - - if (nbdomain == 0) - throw INTERP_KERNEL::Exception("Empty ASCII master file"); - for (int i=0; i<nbdomain;i++) - { - //reading information about the domain - std::string mesh,host; - int idomain; - cellglobal[i]=0; - faceglobal[i]=0; - nodeglobal[i]=0; - - asciiinput >> mesh >> idomain >> MyGlobals::_Mesh_Names[i] >> host >> MyGlobals::_File_Names[i]; - - //Setting the name of the global mesh (which should be is the same for all the subdomains) - if (i==0) - _collection->setName(mesh); - - if (idomain!=i+1) - { - throw INTERP_KERNEL::Exception("domain must be written from 1 to N in ASCII file descriptor"); - } - if ( !domainSelector || domainSelector->isMyDomain(i)) - readSubdomain(i); - - } //loop on domains - } //of try - catch(...) - { - throw INTERP_KERNEL::Exception("I/O error reading parallel MED file"); - } - - //creation of topology from mesh and connect zones - ParallelTopology* aPT = new ParallelTopology((_collection->getMesh()), (_collection->getCZ()), cellglobal, nodeglobal, faceglobal); - _collection->setTopology(aPT, true); - - for (int i=0; i<nbdomain; i++) - { - delete [] cellglobal[i]; - delete [] nodeglobal[i]; - delete [] faceglobal[i]; - } - return 0; -} - -/*! writes the collection of meshes in a MED v2.3 file - * with the connect zones being written as joints - * \param filename name of the ascii file containing the meshes description - */ -void MeshCollectionMedAsciiDriver::write(const char* filename, ParaDomainSelector* domainSelector) const -{ - int nbdomains=_collection->getMesh().size(); - std::vector<std::string> filenames; - filenames.resize(nbdomains); - - //loop on the domains - for (int idomain=0; idomain<nbdomains; idomain++) - { - std::string distfilename; - std::ostringstream suffix; - suffix << filename << idomain+1 << ".med"; - distfilename=suffix.str(); - filenames[idomain]=distfilename; - - if ( !domainSelector || domainSelector->isMyDomain( idomain ) ) - { - if ( !_collection->getMesh()[idomain]->getNumberOfCells()==0 ) continue;//empty domain - MEDLoader::WriteUMesh(distfilename.c_str(),(_collection->getMesh())[idomain],true); - //writeSubdomain(idomain, nbdomains, distfilename.c_str(), domainSelector); - } - } - - //write master file - if ( !domainSelector || domainSelector->rank() == 0 ) - { - std::ofstream file(filename); - file << "#MED Fichier V 2.3"<<" " << std::endl; - file << "#" << " " << std::endl; - file << _collection->getMesh().size() << " " << std::endl; - - for (int idomain=0; idomain<nbdomains; idomain++) - file << _collection->getName() <<" "<< idomain+1 << " " - << (_collection->getMesh())[idomain]->getName() << " localhost " - << filenames[idomain] << " "<< std::endl; - } - -} diff --git a/src/MEDPartitioner/MEDPARTITIONER_MeshCollectionMedAsciiDriver.hxx b/src/MEDPartitioner/MEDPARTITIONER_MeshCollectionMedAsciiDriver.hxx deleted file mode 100644 index 2a22d9446..000000000 --- a/src/MEDPartitioner/MEDPARTITIONER_MeshCollectionMedAsciiDriver.hxx +++ /dev/null @@ -1,41 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// - -#ifndef __MEDPARTITIONER_MESHCOLLECTIONMEDASCIIDRIVER_HXX__ -#define __MEDPARTITIONER_MESHCOLLECTIONMEDASCIIDRIVER_HXX__ - -#include "MEDPARTITIONER.hxx" -#include "MEDPARTITIONER_MeshCollectionDriver.hxx" - -namespace MEDPARTITIONER -{ - class MeshCollection; - class MEDPARTITIONER_EXPORT MeshCollectionMedAsciiDriver : public MeshCollectionDriver - { - public: - MeshCollectionMedAsciiDriver(MeshCollection*); - virtual ~MeshCollectionMedAsciiDriver() { } - int read(const char*, ParaDomainSelector* sel=0); - int read(ParaMEDMEM::MEDFileData*); - void write(const char*, ParaDomainSelector* sel=0) const; - private: - std::string _master_filename; - }; -} -#endif diff --git a/src/MEDPartitioner/MEDPARTITIONER_MeshCollectionMedXmlDriver.cxx b/src/MEDPartitioner/MEDPARTITIONER_MeshCollectionMedXmlDriver.cxx deleted file mode 100644 index 0fcb460be..000000000 --- a/src/MEDPartitioner/MEDPARTITIONER_MeshCollectionMedXmlDriver.cxx +++ /dev/null @@ -1,306 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// - -#include "MEDPARTITIONER_ParallelTopology.hxx" -#include "MEDPARTITIONER_MeshCollectionDriver.hxx" -#include "MEDPARTITIONER_MeshCollection.hxx" -#include "MEDPARTITIONER_MeshCollectionMedXmlDriver.hxx" -#include "MEDPARTITIONER_ParaDomainSelector.hxx" -#include "MEDPARTITIONER_Utils.hxx" - -#include "MEDCouplingUMesh.hxx" -#include "MEDLoader.hxx" -#include "MEDFileMesh.hxx" - -#include <map> -#include <set> -#include <vector> -#include <string> -#include <cstring> -#include <fstream> -#include <sstream> -#include <iostream> -#ifdef WIN32 -#include <time.h> -#include <windows.h> -#endif - - -#include <libxml/tree.h> -#include <libxml/parser.h> -#include <libxml/xpath.h> -#include <libxml/xpathInternals.h> - -using namespace MEDPARTITIONER; - -/*!\class MeshCollectionMedXmlDriver - * - *\brief Driver for MED 3.2 files having Xml master files - * - * Driver for reading and writing distributed files - * for which the master file is written in an Xml format compliant with - * the MED 3.2 specification. - * The reading and writing of the meshes and fields are apart : - * the meshes must always be written/read before the fields. Reading/Writing fields - * is optional and is done field after field. API for reading/writing fields - * is written with a template so that FIELD<int> and FIELD<double> - * can be conveniently handled. - */ - -MeshCollectionMedXmlDriver::MeshCollectionMedXmlDriver(MeshCollection* collection):MeshCollectionDriver(collection) -{ -} - -/*!reads a MED File Xml Master File v>=2.3 - * and mounts the corresponding meshes in memory - * the connect zones are created from the joints - * - *\param filename Xml file containing the list of MED v2.3 files - * */ - -int MeshCollectionMedXmlDriver::read(const char* filename, ParaDomainSelector* domainSelector) -{ - //distributed meshes - int nbdomain; - _master_filename=filename; - - //reading ascii master file - try - { - //Setting up the Xml tree corresponding to filename - xmlDocPtr master_doc=xmlParseFile(filename); - - if (!master_doc) - throw INTERP_KERNEL::Exception("Xml Master File does not exist or is not compliant with Xml scheme"); - - //number of domains - xmlXPathContextPtr xpathCtx = xmlXPathNewContext(master_doc); - xmlXPathObjectPtr xpathObj = xmlXPathEvalExpression(BAD_CAST "//splitting/subdomain", xpathCtx); - if (xpathObj==0 || xpathObj->nodesetval->nodeNr ==0) - throw INTERP_KERNEL::Exception("Xml Master File does not contain /MED/splitting/subdomain node"); - - //as subdomain has only one property which is "number" - //it suffices to take the content of its first child - const char* mystring = (const char*)xpathObj->nodesetval->nodeTab[0]->properties->children->content; - sscanf(mystring, "%d", &nbdomain); - - //mesh name - xmlXPathFreeObject(xpathObj); - xpathObj = xmlXPathEvalExpression(BAD_CAST "//content/mesh", xpathCtx); - if (xpathObj==0 || xpathObj->nodesetval->nodeNr ==0) - throw INTERP_KERNEL::Exception("Xml Master File does not contain /MED/content/mesh node"); - _collection->setName( (const char*)xpathObj->nodesetval->nodeTab[0]->properties->children->content); - - //cout << "nb domain " << nbdomain << endl; - MyGlobals::_File_Names.resize(nbdomain); - MyGlobals::_Mesh_Names.resize(nbdomain); - (_collection->getMesh()).resize(nbdomain); - (_collection->getFaceMesh()).resize(nbdomain); - (_collection->getCellFamilyIds()).resize(nbdomain); - (_collection->getFaceFamilyIds()).resize(nbdomain); - - //retrieving the node which contains the file names - const char filechar[]="//files/subfile"; - xmlXPathFreeObject(xpathObj); - xpathObj = xmlXPathEvalExpression(BAD_CAST filechar, xpathCtx); - if (xpathObj==0 || xpathObj->nodesetval->nodeNr ==0) - throw INTERP_KERNEL::Exception("Xml Master File does not contain /MED/files/subfile nodes"); - int nbfiles = xpathObj->nodesetval ->nodeNr; - - for (int i=0; i<nbfiles;i++) - { - //reading information about the domain - std::string host; - //reading file names - std::ostringstream name_search_string; - name_search_string<<"//files/subfile[@id=\""<<i+1<<"\"]/name"; - xmlXPathObjectPtr xpathObjfilename = - xmlXPathEvalExpression(BAD_CAST name_search_string.str().c_str(),xpathCtx); - if (xpathObjfilename->nodesetval ==0) - throw INTERP_KERNEL::Exception("Error retrieving a file name from subfile of Xml Master File"); - MyGlobals::_File_Names[i]=(const char*)xpathObjfilename->nodesetval->nodeTab[0]->children->content; - - //reading the local mesh names - std::ostringstream mesh_search_string; - mesh_search_string<<"//mapping/mesh/chunk[@subdomain=\""<<i+1<<"\"]/name"; - - xmlXPathObjectPtr xpathMeshObj = xmlXPathEvalExpression(BAD_CAST mesh_search_string.str().c_str(),xpathCtx); - if (xpathMeshObj->nodesetval ==0) - throw INTERP_KERNEL::Exception("Error retrieving mesh name from chunk of Xml Master File"); - MyGlobals::_Mesh_Names[i]=(const char*)xpathMeshObj->nodesetval->nodeTab[0]->children->content; - - if ( !domainSelector || domainSelector->isMyDomain(i)) - readSubdomain(i); - xmlXPathFreeObject(xpathObjfilename); - xmlXPathFreeObject(xpathMeshObj); - } //loop on domains - - //LIBXML cleanup - xmlXPathFreeObject(xpathObj); - xmlXPathFreeContext(xpathCtx); - xmlFreeDoc(master_doc); - - } //of try - catch(...) - { - throw INTERP_KERNEL::Exception("I/O error reading parallel MED file"); - } - - ParallelTopology* aPT = new ParallelTopology(_collection->getMesh()); - //creation of topology from mesh and connect zones - if ( _collection->isParallelMode() ) - { - //to know nb of cells on each proc to compute global cell ids from locally global - domainSelector->gatherNbOf(_collection->getMesh()); - } - _collection->setTopology(aPT, true); - _collection->setDomainNames(_collection->getName()); - return 0; -} - - -/*! writes the collection of meshes in a - * MED v2.3 Xml file - * with the connect zones being written as joints - * \param filename name of the Xml file containing the meshes description - */ -void MeshCollectionMedXmlDriver::write(const char* filename, ParaDomainSelector* domainSelector) const -{ - xmlDocPtr master_doc = 0; - xmlNodePtr root_node = 0, node, node2; - char buff[256]; - - //Creating the Xml document - master_doc = xmlNewDoc(BAD_CAST "1.0"); - root_node = xmlNewNode(0, BAD_CAST "root"); - xmlDocSetRootElement(master_doc,root_node); - - //Creating child nodes - // Version tag - node = xmlNewChild(root_node, 0, BAD_CAST "version",0); - xmlNewProp(node, BAD_CAST "maj", BAD_CAST "2"); - xmlNewProp(node, BAD_CAST "min", BAD_CAST "3"); - xmlNewProp(node, BAD_CAST "ver", BAD_CAST "1"); - - //Description tag - time_t present; - char date[20]; -#ifndef WIN32 - time( &present); - struct tm *time_asc = localtime(&present); - sprintf(date,"%02d%02d%02d",time_asc->tm_year - ,time_asc->tm_mon+1 - ,time_asc->tm_mday); -#else - SYSTEMTIME st; - GetLocalTime ( &st ); - sprintf(date,"%02d%02d%02d", - st.wYear - ,st.wMonth - ,st.wDay); -#endif - - node = xmlNewChild(root_node,0, BAD_CAST "description",0); - - xmlNewProp(node, BAD_CAST "what", BAD_CAST _collection->getDescription().c_str()); - xmlNewProp(node, BAD_CAST "when", BAD_CAST date); - - //Content tag - node =xmlNewChild(root_node,0, BAD_CAST "content",0); - node2 = xmlNewChild(node, 0, BAD_CAST "mesh",0); - xmlNewProp(node2, BAD_CAST "name", BAD_CAST _collection->getName().c_str()); - - //Splitting tag - node=xmlNewChild(root_node,0,BAD_CAST "splitting",0); - node2=xmlNewChild(node,0,BAD_CAST "subdomain",0); - sprintf(buff, "%d", (int)_collection->getMesh().size()); - xmlNewProp(node2, BAD_CAST "number", BAD_CAST buff); - node2=xmlNewChild(node,0,BAD_CAST "global_numbering",0); - xmlNewProp(node2, BAD_CAST "present", BAD_CAST "yes"); - - //Files tag - xmlNodePtr file_node=xmlNewChild(root_node,0,BAD_CAST "files",0); - - //Mapping tag - node = xmlNewChild(root_node,0,BAD_CAST "mapping",0); - xmlNodePtr mesh_node = xmlNewChild(node, 0, BAD_CAST "mesh",0); - xmlNewProp(mesh_node, BAD_CAST "name", BAD_CAST _collection->getName().c_str()); - - int nbdomains= _collection->getMesh().size(); - - //loop on the domains - std::string finalMeshName=""; - if (MyGlobals::_General_Informations.size()!=0) - { - std::size_t found=MyGlobals::_General_Informations[0].find("finalMeshName="); - if ((found!=std::string::npos) && (found>0)) - { - finalMeshName=ExtractFromDescription(MyGlobals::_General_Informations[0], "finalMeshName="); - } - } - if (finalMeshName.empty()) - { - finalMeshName=_collection->getName(); - } - for (int idomain=nbdomains-1; idomain>=0;idomain--) - { - std::string distfilename; - std::ostringstream suffix; - suffix<<filename<<idomain+1<<".med"; - distfilename=suffix.str(); - - if ( !domainSelector || domainSelector->isMyDomain( idomain ) ) - { - if ( (_collection->getMesh())[idomain]->getNumberOfCells()==0 ) - continue; //empty domain - if (MyGlobals::_Verbose>1) - std::cout << "proc "<< domainSelector->rank() << " : writeMedFile " << distfilename - << " "<< (_collection->getMesh())[idomain]->getNumberOfCells() << " cells" - << " " << (_collection->getFaceMesh())[idomain]->getNumberOfCells() << " faces" - << " " << (_collection->getMesh())[idomain]->getNumberOfNodes()<<" nodes" << std::endl; - writeMedFile(idomain,distfilename); - } - - if (domainSelector->rank()==0) - { - //updating the ascii description file - node = xmlNewChild(file_node, 0, BAD_CAST "subfile",0); - sprintf (buff,"%d",idomain+1); - xmlNewProp(node, BAD_CAST "id", BAD_CAST buff); - xmlNewChild(node,0,BAD_CAST "name",BAD_CAST distfilename.c_str()); - xmlNewChild(node,0,BAD_CAST "machine",BAD_CAST "localhost"); - - node = xmlNewChild(mesh_node,0, BAD_CAST "chunk",0); - xmlNewProp(node, BAD_CAST "subdomain", BAD_CAST buff); - xmlNewChild(node,0,BAD_CAST "name", BAD_CAST finalMeshName.c_str()); - //xmlNewChild(node,0,BAD_CAST "name", BAD_CAST ((_collection->getMesh())[idomain]->getName()).c_str()); - } - } - - //create the ascii description file - if (domainSelector->rank()==0) - { - std::string myfile(filename); - myfile.append(".xml"); - if ( !domainSelector || domainSelector->rank() == 0 ) - xmlSaveFormatFileEnc(myfile.c_str(), master_doc, "UTF-8", 1); - } - xmlFreeDoc(master_doc); - xmlCleanupParser(); -} diff --git a/src/MEDPartitioner/MEDPARTITIONER_MeshCollectionMedXmlDriver.hxx b/src/MEDPartitioner/MEDPARTITIONER_MeshCollectionMedXmlDriver.hxx deleted file mode 100644 index 5e2049b4d..000000000 --- a/src/MEDPartitioner/MEDPARTITIONER_MeshCollectionMedXmlDriver.hxx +++ /dev/null @@ -1,40 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// - -#ifndef __MEDPARTITIONER_MESHCOLLECTIONMEDXMLDRIVER_HXX__ -#define __MEDPARTITIONER_MESHCOLLECTIONMEDXMLDRIVER_HXX__ - -#include "MEDPARTITIONER.hxx" -#include "MEDPARTITIONER_MeshCollectionDriver.hxx" - -namespace MEDPARTITIONER -{ - class MeshCollection; - class MEDPARTITIONER_EXPORT MeshCollectionMedXmlDriver : public MeshCollectionDriver - { - public: - MeshCollectionMedXmlDriver(MeshCollection*); - virtual ~MeshCollectionMedXmlDriver() { } - int read(const char*, ParaDomainSelector* sel=0); - void write(const char*, ParaDomainSelector* sel=0) const; - private : - std::string _master_filename; - }; -} -#endif diff --git a/src/MEDPartitioner/MEDPARTITIONER_MetisGraph.cxx b/src/MEDPartitioner/MEDPARTITIONER_MetisGraph.cxx deleted file mode 100644 index 7e3533815..000000000 --- a/src/MEDPartitioner/MEDPARTITIONER_MetisGraph.cxx +++ /dev/null @@ -1,119 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// - -#include "MEDPARTITIONER_MetisGraph.hxx" -#include "MEDPARTITIONER_ParaDomainSelector.hxx" -#include "MEDPARTITIONER_Utils.hxx" - -#include "MEDCouplingSkyLineArray.hxx" -#include "InterpKernelException.hxx" - -#include <iostream> - -extern "C" -{ -#include "MEDPARTITIONER_metis.h" -} - -using namespace MEDPARTITIONER; - -METISGraph::METISGraph():Graph() -{ -} - -METISGraph::METISGraph(ParaMEDMEM::MEDCouplingSkyLineArray* graph, int* edgeweight) - :Graph(graph,edgeweight) -{ -} - -METISGraph::~METISGraph() -{ -} - -void METISGraph::partGraph(int ndomain, - const std::string& options_string, - ParaDomainSelector *parallelizer) -{ - using std::vector; - if (MyGlobals::_Verbose>10) - std::cout << "proc " << MyGlobals::_Rank << " : METISGraph::partGraph" << std::endl; - - //number of graph vertices - int n=_graph->getNumberOf(); - //graph - int * xadj=const_cast<int*>(_graph->getIndex()); - int * adjncy=const_cast<int*>(_graph->getValue()); - //constraints - int * vwgt=_cell_weight; - int * adjwgt=_edge_weight; - int wgtflag=(_edge_weight!=0)?1:0+(_cell_weight!=0)?2:0; - //base 0 or 1 - int base=0; - //ndomain - int nparts=ndomain; - //options - /* - (0=default_option,option,random_seed) see defs.h - #define PMV3_OPTION_DBGLVL 1 - #define PMV3_OPTION_SEED 2 - #define PMV3_OPTION_IPART 3 - #define PMV3_OPTION_PSR 3 - seems no changes int options[4]={1,0,33,0}; //test for a random seed of 33 - */ - int options[20]={0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}; -#if !defined(MED_ENABLE_METIS) - throw INTERP_KERNEL::Exception("METISGraph::partGraph : METIS is not available. Check your products, please."); -#else - //output parameters - int edgecut; - int* partition=new int[n]; - - if(nparts >1) - { - if (MyGlobals::_Verbose>10) - std::cout << "METISGraph::partGraph METIS_PartGraph METIS_PartGraph(RecursiveOrKway)" << std::endl; - if (options_string != "k") - MEDPARTITIONER_METIS_PartGraphRecursive(&n, xadj, adjncy, vwgt, adjwgt, &wgtflag, - &base, &nparts, options, &edgecut, partition); - else - MEDPARTITIONER_METIS_PartGraphKway(&n, xadj, adjncy, vwgt, adjwgt, &wgtflag, - &base, &nparts, options, &edgecut, partition); - } - else //force this case because METIS send all 1 in value - { - for (int i=0; i<n; i++) - partition[i]=0; - } - vector<int> index(n+1); - vector<int> value(n); - index[0]=0; - for (int i=0; i<n; i++) - { - index[i+1]=index[i]+1; - value[i]=partition[i]; - } - delete [] partition; - - //creating a skylinearray with no copy of the index and partition array - //the fifth argument true specifies that only the pointers are passed - //to the object - _partition = new ParaMEDMEM::MEDCouplingSkyLineArray(index,value); -#endif -} - diff --git a/src/MEDPartitioner/MEDPARTITIONER_MetisGraph.hxx b/src/MEDPartitioner/MEDPARTITIONER_MetisGraph.hxx deleted file mode 100644 index 5954f9e4d..000000000 --- a/src/MEDPartitioner/MEDPARTITIONER_MetisGraph.hxx +++ /dev/null @@ -1,40 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// - -#ifndef __MEDPARTITIONER_METISGRAPH_HXX__ -#define __MEDPARTITIONER_METISGRAPH_HXX__ - -#include "MEDPARTITIONER.hxx" -#include "MEDPARTITIONER_Graph.hxx" - -#include <string> - -namespace MEDPARTITIONER -{ - class MEDPARTITIONER_EXPORT METISGraph : public Graph - { - public: - METISGraph(); - METISGraph(ParaMEDMEM::MEDCouplingSkyLineArray*, int *edgeweight=0); - virtual ~METISGraph(); - void partGraph(int ndomain, const std::string& options_string="", ParaDomainSelector *sel=0); - }; -} - -#endif diff --git a/src/MEDPartitioner/MEDPARTITIONER_ParMetisGraph.cxx b/src/MEDPartitioner/MEDPARTITIONER_ParMetisGraph.cxx deleted file mode 100644 index 4c424f09f..000000000 --- a/src/MEDPartitioner/MEDPARTITIONER_ParMetisGraph.cxx +++ /dev/null @@ -1,143 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// - -#include "MEDPARTITIONER_ParMetisGraph.hxx" -#include "MEDPARTITIONER_ParaDomainSelector.hxx" -#include "MEDPARTITIONER_Utils.hxx" - -#include "MEDCouplingSkyLineArray.hxx" -#include "InterpKernelException.hxx" - -#include <iostream> - -#ifdef MED_ENABLE_PARMETIS -#include <parmetis.h> -// #if PARMETIS_MAJOR_VERSION == 4 -// #define ParMETIS_PartKway ParMETIS_V3_PartKway -// #endif -#endif - -using namespace MEDPARTITIONER; - -ParMETISGraph::ParMETISGraph():Graph() -{ -} - -ParMETISGraph::ParMETISGraph(ParaMEDMEM::MEDCouplingSkyLineArray* graph, int* edgeweight) - :Graph(graph,edgeweight) -{ -} - -ParMETISGraph::~ParMETISGraph() -{ -} - -void ParMETISGraph::partGraph(int ndomain, - const std::string& options_string, - ParaDomainSelector *parallelizer) -{ - using std::vector; - vector<int> ran,vx,va; //for randomize - - if (MyGlobals::_Verbose>10) - std::cout << "proc " << MyGlobals::_Rank << " : ParMETISGraph::partGraph" << std::endl; - - // number of graph vertices - int n=_graph->getNumberOf(); - //graph - int * xadj=const_cast<int*>(_graph->getIndex()); - int * adjncy=const_cast<int*>(_graph->getValue()); - //constraints - int * vwgt=_cell_weight; - int * adjwgt=_edge_weight; - int wgtflag=(_edge_weight!=0)?1:0+(_cell_weight!=0)?2:0; - //base 0 or 1 - int base=0; - //ndomain - int nparts=ndomain; - //options - /* - (0=default_option,option,random_seed) see defs.h - #define PMV3_OPTION_DBGLVL 1 - #define PMV3_OPTION_SEED 2 - #define PMV3_OPTION_IPART 3 - #define PMV3_OPTION_PSR 3 - seems no changes int options[4]={1,0,33,0}; //test for a random seed of 33 - */ - int options[4]={0,0,0,0}; - // output parameters - int edgecut; -#if !defined(MED_ENABLE_PARMETIS) - throw INTERP_KERNEL::Exception("ParMETISGraph::partGraph : PARMETIS is not available. Check your products, please."); -#else - int* partition=new int[n]; - - if (MyGlobals::_Verbose>10) - std::cout << "proc " << MyGlobals::_Rank << " : ParMETISGraph::partGraph ParMETIS_PartKway new" << std::endl; - int * vtxdist=parallelizer->getProcVtxdist(); - MPI_Comm comm=MPI_COMM_WORLD; - ParMETIS_PartKway(vtxdist, xadj, adjncy, vwgt, - adjwgt, &wgtflag, &base, &nparts, options, - &edgecut, partition, &comm ); - - - /*doc from parmetis.h - void __cdecl ParMETIS_PartKway( - idxtype *vtxdist, idxtype *xadj, idxtype *adjncy, idxtype *vwgt, - idxtype *adjwgt, int *wgtflag, int *numflag, int *nparts, int *options, - int *edgecut, idxtype *part, MPI_Comm *comm); - - void __cdecl ParMETIS_V3_PartKway( - idxtype *vtxdist, idxtype *xadj, idxtype *adjncy, idxtype *vwgt, - idxtype *adjwgt, int *wgtflag, int *numflag, int *ncon, int *nparts, - float *tpwgts, float *ubvec, int *options, int *edgecut, idxtype *part, - MPI_Comm *comm); - */ - - vector<int> index(n+1); - vector<int> value(n); - index[0]=0; - if (ran.size()>0 && MyGlobals::_Atomize==0) //there is randomize - { - if (MyGlobals::_Is0verbose>100) - std::cout << "randomize" << std::endl; - for (int i=0; i<n; i++) - { - index[i+1]=index[i]+1; - value[ran[i]]=partition[i]; - } - } - else - { - for (int i=0; i<n; i++) - { - index[i+1]=index[i]+1; - value[i]=partition[i]; - } - } - delete [] partition; - - //creating a skylinearray with no copy of the index and partition array - //the fifth argument true specifies that only the pointers are passed - //to the object - - _partition = new ParaMEDMEM::MEDCouplingSkyLineArray(index,value); -#endif -} - diff --git a/src/MEDPartitioner/MEDPARTITIONER_ParMetisGraph.hxx b/src/MEDPartitioner/MEDPARTITIONER_ParMetisGraph.hxx deleted file mode 100644 index 2d61cec26..000000000 --- a/src/MEDPartitioner/MEDPARTITIONER_ParMetisGraph.hxx +++ /dev/null @@ -1,40 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// - -#ifndef __MEDPARTITIONER_ParMETISGraph_HXX__ -#define __MEDPARTITIONER_ParMETISGraph_HXX__ - -#include "MEDPARTITIONER.hxx" -#include "MEDPARTITIONER_Graph.hxx" - -#include <string> - -namespace MEDPARTITIONER -{ - class MEDPARTITIONER_EXPORT ParMETISGraph : public Graph - { - public: - ParMETISGraph(); - ParMETISGraph(ParaMEDMEM::MEDCouplingSkyLineArray*, int *edgeweight=0); - virtual ~ParMETISGraph(); - void partGraph(int ndomain, const std::string& options_string="", ParaDomainSelector *sel=0); - }; -} - -#endif diff --git a/src/MEDPartitioner/MEDPARTITIONER_ParaDomainSelector.cxx b/src/MEDPartitioner/MEDPARTITIONER_ParaDomainSelector.cxx deleted file mode 100644 index 7658b72f7..000000000 --- a/src/MEDPartitioner/MEDPARTITIONER_ParaDomainSelector.cxx +++ /dev/null @@ -1,674 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// - -#include "MEDPARTITIONER_ParaDomainSelector.hxx" -#include "MEDPARTITIONER_UserGraph.hxx" -#include "MEDPARTITIONER_Utils.hxx" - -#include "MEDCouplingUMesh.hxx" -#include "MEDCouplingSkyLineArray.hxx" - -#include <iostream> -#include <numeric> - -#ifdef HAVE_MPI -#include <mpi.h> -#endif - -/*! - * \brief Constructor. Find out my rank and world size - */ -MEDPARTITIONER::ParaDomainSelector::ParaDomainSelector(bool mesure_memory) - :_rank(0),_world_size(1), _nb_result_domains(-1), _init_time(0.0), - _mesure_memory(mesure_memory), _init_memory(0), _max_memory(0) -{ -#ifdef HAVE_MPI - if (MyGlobals::_Rank==-1) - { - MPI_Init(0,0); //do once only - MPI_Comm_size(MPI_COMM_WORLD,&_world_size) ; - MPI_Comm_rank(MPI_COMM_WORLD,&_rank) ; - } - else - { - _world_size=MyGlobals::_World_Size; - _rank=MyGlobals::_Rank; - } - _init_time = MPI_Wtime(); -#else - //sequential : no MPI - _world_size=1; - _rank=0; - if (MyGlobals::_Verbose>10) - std::cout << "WARNING : ParaDomainSelector contructor without parallel_mode World_Size=1 by default" << std::endl; -#endif - MyGlobals::_World_Size=_world_size; - MyGlobals::_Rank=_rank; - - if (MyGlobals::_Verbose>200) std::cout << "proc " << MyGlobals::_Rank << " of " << MyGlobals::_World_Size << std::endl; - evaluateMemory(); -} - -MEDPARTITIONER::ParaDomainSelector::~ParaDomainSelector() -{ -} - -/*! - * \brief Return true if is running on different hosts - */ -bool MEDPARTITIONER::ParaDomainSelector::isOnDifferentHosts() const -{ - evaluateMemory(); - if ( _world_size < 2 ) return false; - -#ifdef HAVE_MPI - char name_here[ MPI_MAX_PROCESSOR_NAME+1 ], name_there[ MPI_MAX_PROCESSOR_NAME+1 ]; - int size; - MPI_Get_processor_name( name_here, &size); - - int next_proc = (rank() + 1) % nbProcs(); - int prev_proc = (rank() - 1 + nbProcs()) % nbProcs(); - int tag = 1111111; - - MPI_Status status; - MPI_Sendrecv((void*)&name_here[0], MPI_MAX_PROCESSOR_NAME, MPI_CHAR, next_proc, tag, - (void*)&name_there[0], MPI_MAX_PROCESSOR_NAME, MPI_CHAR, prev_proc, tag, - MPI_COMM_WORLD, &status); - - //bug: (isOnDifferentHosts here and there) is not (isOnDifferentHosts somewhere) - //return string(name_here) != string(name_there); - - int sum_same = -1; - int same = 1; - if (std::string(name_here) != std::string(name_there)) - same=0; - MPI_Allreduce( &same, &sum_same, 1, MPI_INT, MPI_SUM, MPI_COMM_WORLD ); - return (sum_same != nbProcs()); -#endif - return false; -} - -/*! - * \brief Return true if the domain with domainIndex is to be loaded on this proc - * \param domainIndex - index of mesh domain - * \retval bool - to load or not - */ -bool MEDPARTITIONER::ParaDomainSelector::isMyDomain(int domainIndex) const -{ - evaluateMemory(); - return (_rank == getProcessorID( domainIndex )); -} - -/*! - * \brief Return processor id where the domain with domainIndex resides - * \param domainIndex - index of mesh domain - * \retval int - processor id - */ -int MEDPARTITIONER::ParaDomainSelector::getProcessorID(int domainIndex) const -{ - evaluateMemory(); - return ( domainIndex % _world_size ); -} - -/*! - * \brief Gather info on nb of cell entities on each processor and return total nb. - * - * Is called - * 1) for MED_CELL to know global id shift for domains at graph construction; - * 2) for sub-entity to know total nb of sub-entities before creating those of joints - */ -void MEDPARTITIONER::ParaDomainSelector::gatherNbOf(const std::vector<ParaMEDMEM::MEDCouplingUMesh*>& domain_meshes) -{ - evaluateMemory(); - // get nb of elems of each domain mesh - int nb_domains=domain_meshes.size(); - std::vector<int> nb_elems(nb_domains*2, 0); //NumberOfCells & NumberOfNodes - for (int i=0; i<nb_domains; ++i) - if ( domain_meshes[i] ) - { - nb_elems[i*2] = domain_meshes[i]->getNumberOfCells(); - nb_elems[i*2+1] = domain_meshes[i]->getNumberOfNodes(); - } - // receive nb of elems from other procs - std::vector<int> all_nb_elems; - if (MyGlobals::_World_Size==1) - { - all_nb_elems=nb_elems; - } - else - { -#ifdef HAVE_MPI - all_nb_elems.resize( nb_domains*2 ); - MPI_Allreduce((void*)&nb_elems[0], (void*)&all_nb_elems[0], nb_domains*2, MPI_INT, MPI_SUM, MPI_COMM_WORLD); -#else - throw INTERP_KERNEL::Exception("not(HAVE_MPI) incompatible with MPI_World_Size>1"); -#endif - } - int total_nb_cells=0, total_nb_nodes=0; - for (int i=0; i<nb_domains; ++i) - { - total_nb_cells+=all_nb_elems[i*2]; - total_nb_nodes+=all_nb_elems[i*2+1]; - } - - if (MyGlobals::_Is0verbose>10) - std::cout << "totalNbCells " << total_nb_cells << " totalNbNodes " << total_nb_nodes << std::endl; - - std::vector<int>& cell_shift_by_domain=_cell_shift_by_domain; - std::vector<int>& node_shift_by_domain=_node_shift_by_domain; - std::vector<int>& face_shift_by_domain=_face_shift_by_domain; - - std::vector< int > ordered_nbs_cell, ordered_nbs_node, domain_order(nb_domains); - ordered_nbs_cell.push_back(0); - ordered_nbs_node.push_back(0); - for (int iproc=0; iproc<nbProcs(); ++iproc) - for (int idomain=0; idomain<nb_domains; ++idomain) - if (getProcessorID( idomain )==iproc) - { - domain_order[idomain] = ordered_nbs_cell.size() - 1; - ordered_nbs_cell.push_back( ordered_nbs_cell.back() + all_nb_elems[idomain*2] ); - ordered_nbs_node.push_back( ordered_nbs_node.back() + all_nb_elems[idomain*2+1] ); - } - cell_shift_by_domain.resize( nb_domains+1, 0 ); - node_shift_by_domain.resize( nb_domains+1, 0 ); - face_shift_by_domain.resize( nb_domains+1, 0 ); - for (int idomain=0; idomain<nb_domains; ++idomain) - { - cell_shift_by_domain[ idomain ] = ordered_nbs_cell[ domain_order[ idomain ]]; - node_shift_by_domain[ idomain ] = ordered_nbs_node[ domain_order[ idomain ]]; - } - cell_shift_by_domain.back() = ordered_nbs_cell.back(); // to know total nb of elements - node_shift_by_domain.back() = ordered_nbs_node.back(); // to know total nb of elements - - if (MyGlobals::_Is0verbose>300) - { - std::cout << "proc " << MyGlobals::_Rank << " : cellShiftByDomain "; - for (int i=0; i<=nb_domains; ++i) - std::cout << cell_shift_by_domain[i] << "|"; - std::cout << std::endl; - std::cout << "proc " << MyGlobals::_Rank << " : nodeShiftBy_domain "; - for (int i=0; i<=nb_domains; ++i) - std::cout << node_shift_by_domain[i] << "|"; - std::cout << std::endl; - } - // fill _nb_vert_of_procs (is Vtxdist) - _nb_vert_of_procs.resize(_world_size+1); - _nb_vert_of_procs[0] = 0; // base = 0 - for (int i=0; i<nb_domains; ++i) - { - int rankk = getProcessorID(i); - _nb_vert_of_procs[rankk+1] += all_nb_elems[i*2]; - } - for (std::size_t i=1; i<_nb_vert_of_procs.size(); ++i) - _nb_vert_of_procs[i] += _nb_vert_of_procs[i-1]; // to CSR format : cumulated - - if (MyGlobals::_Is0verbose>200) - { - std::cout << "proc " << MyGlobals::_Rank << " : gatherNbOf : vtxdist is "; - for (int i = 0; i <= _world_size; ++i) - std::cout << _nb_vert_of_procs[i] << " "; - std::cout << std::endl; - } - - evaluateMemory(); - return; -} - -/*! - * \brief Return distribution of the graph vertices among the processors - * \retval int* - array containing nb of vertices (=cells) on all processors - * - * gatherNbOf() must be called before. - * The result array is to be used as the first arg of ParMETIS_V3_PartKway() and - * is freed by ParaDomainSelector. - */ -int *MEDPARTITIONER::ParaDomainSelector::getProcVtxdist() const -{ - evaluateMemory(); - if (_nb_vert_of_procs.empty()) - throw INTERP_KERNEL::Exception("_nb_vert_of_procs not set"); - return const_cast<int*>(& _nb_vert_of_procs[0]); -} - -/*! - * \brief Return nb of cells in domains with lower index. - * - * gatherNbOf() must be called before. - * Result added to local id on given domain gives id in the whole distributed mesh - */ -int MEDPARTITIONER::ParaDomainSelector::getDomainCellShift(int domainIndex) const -{ - evaluateMemory(); - if (_cell_shift_by_domain.empty()) - throw INTERP_KERNEL::Exception("_cell_shift_by_domain not set"); - return _cell_shift_by_domain[domainIndex]; -} - -int MEDPARTITIONER::ParaDomainSelector::getDomainNodeShift(int domainIndex) const -{ - evaluateMemory(); - if (_node_shift_by_domain.empty()) - throw INTERP_KERNEL::Exception("_node_shift_by_domain not set"); - return _node_shift_by_domain[domainIndex]; -} - -/*! - * \brief Return nb of nodes on processors with lower rank. - * - * gatherNbOf() must be called before. - * Result added to global id on this processor gives id in the whole distributed mesh - */ -int MEDPARTITIONER::ParaDomainSelector::getProcNodeShift() const -{ - evaluateMemory(); - if (_nb_vert_of_procs.empty()) - throw INTERP_KERNEL::Exception("_nb_vert_of_procs not set"); - return _nb_vert_of_procs[_rank]; -} - -/*! - * \brief Gather graphs from all processors into one - */ -std::auto_ptr<MEDPARTITIONER::Graph> MEDPARTITIONER::ParaDomainSelector::gatherGraph(const Graph* graph) const -{ - Graph* glob_graph = 0; - - evaluateMemory(); -#ifdef HAVE_MPI - - // --------------- - // Gather indices - // --------------- - - std::vector<int> index_size_of_proc( nbProcs() ); // index sizes - 1 - for ( std::size_t i = 1; i < _nb_vert_of_procs.size(); ++i ) - index_size_of_proc[i-1] = _nb_vert_of_procs[ i ] - _nb_vert_of_procs[ i-1 ]; - - int index_size = 1 + _cell_shift_by_domain.back(); - int *graph_index = new int[ index_size ]; - const int *index = graph->getGraph()->getIndex(); - int *proc_index_displacement = const_cast<int*>( & _nb_vert_of_procs[0] ); - - MPI_Allgatherv((void*) (index+1), // send local index except first 0 (or 1) - index_size_of_proc[_rank], // index size on this proc - MPI_INT, - (void*) graph_index, // receive indices - & index_size_of_proc[0], // index size on each proc - proc_index_displacement, // displacement of each proc index - MPI_INT, - MPI_COMM_WORLD); - graph_index[0] = index[0]; // it is not overwritten thanks to proc_index_displacement[0]==1 - - // get sizes of graph values on each proc by the got indices of graphs - std::vector< int > value_size_of_proc( nbProcs() ), proc_value_displacement(1,0); - for ( int i = 0; i < nbProcs(); ++i ) - { - if ( index_size_of_proc[i] > 0 ) - value_size_of_proc[i] = graph_index[ proc_index_displacement[ i+1 ]-1 ] - graph_index[0]; - else - value_size_of_proc[i] = 0; - proc_value_displacement.push_back( proc_value_displacement.back() + value_size_of_proc[i] ); - } - - // update graph_index - for ( int i = 1; i < nbProcs(); ++i ) - { - int shift = graph_index[ proc_index_displacement[i]-1 ]-graph_index[0]; - for ( int j = proc_index_displacement[i]; j < proc_index_displacement[i+1]; ++j ) - graph_index[ j ] += shift; - } - - // -------------- - // Gather values - // -------------- - - int value_size = graph_index[ index_size-1 ] - graph_index[ 0 ]; - int *graph_value = new int[ value_size ]; - const int *value = graph->getGraph()->getValue(); - - MPI_Allgatherv((void*) value, // send local value - value_size_of_proc[_rank], // value size on this proc - MPI_INT, - (void*) graph_value, // receive values - & value_size_of_proc[0], // value size on each proc - & proc_value_displacement[0], // displacement of each proc value - MPI_INT, - MPI_COMM_WORLD); - - // ----------------- - // Gather partition - // ----------------- - - int * partition = new int[ _cell_shift_by_domain.back() ]; - const int* part = graph->getPart(); - - MPI_Allgatherv((void*) part, // send local partition - index_size_of_proc[_rank], // index size on this proc - MPI_INT, - (void*)(partition-1), // -1 compensates proc_index_displacement[0]==1 - & index_size_of_proc[0], // index size on each proc - proc_index_displacement, // displacement of each proc index - MPI_INT, - MPI_COMM_WORLD); - - // ----------- - // Make graph - // ----------- - - // MEDCouplingSkyLineArray* array = - // new MEDCouplingSkyLineArray( index_size-1, value_size, graph_index, graph_value, true ); - - // glob_graph = new UserGraph( array, partition, index_size-1 ); - - evaluateMemory(); - - delete [] partition; - -#endif // HAVE_MPI - - return std::auto_ptr<Graph>( glob_graph ); -} - - -/*! - * \brief Set nb of cell/cell pairs in a joint between domains - */ -void MEDPARTITIONER::ParaDomainSelector::setNbCellPairs( int nb_cell_pairs, int dist_domain, int loc_domain ) -{ - // This method is needed for further computing global numbers of faces in joint. - // Store if both domains are on this proc else on one of procs only - if ( isMyDomain( dist_domain ) || dist_domain < loc_domain ) - { - if ( _nb_cell_pairs_by_joint.empty() ) - _nb_cell_pairs_by_joint.resize( _nb_result_domains*(_nb_result_domains+1), 0); - - int joint_id = jointId( loc_domain, dist_domain ); - _nb_cell_pairs_by_joint[ joint_id ] = nb_cell_pairs; - } - evaluateMemory(); -} - -//================================================================================ -/*! - * \brief Return nb of cell/cell pairs in a joint between domains on different procs - */ -//================================================================================ - -int MEDPARTITIONER::ParaDomainSelector::getNbCellPairs( int dist_domain, int loc_domain ) const -{ - evaluateMemory(); - - int joint_id = jointId( loc_domain, dist_domain ); - return _nb_cell_pairs_by_joint[ joint_id ]; -} - -//================================================================================ -/*! - * \brief Gather size of each joint - */ -//================================================================================ - -void MEDPARTITIONER::ParaDomainSelector::gatherNbCellPairs() -{ - if ( _nb_cell_pairs_by_joint.empty() ) - _nb_cell_pairs_by_joint.resize( _nb_result_domains*(_nb_result_domains+1), 0); - evaluateMemory(); - - std::vector< int > send_buf = _nb_cell_pairs_by_joint; -#ifdef HAVE_MPI - MPI_Allreduce((void*)&send_buf[0], - (void*)&_nb_cell_pairs_by_joint[0], - _nb_cell_pairs_by_joint.size(), - MPI_INT, MPI_SUM, MPI_COMM_WORLD); -#endif - // check that the set nbs of cell pairs are correct, - // namely that each joint is treated on one proc only - for ( std::size_t j = 0; j < _nb_cell_pairs_by_joint.size(); ++j ) - if ( _nb_cell_pairs_by_joint[j] != send_buf[j] && send_buf[j]>0 ) - throw INTERP_KERNEL::Exception("invalid nb of cell pairs"); -} - -//================================================================================ -/*! - * \brief Return the first global id of sub-entity for the joint - */ -//================================================================================ - -int MEDPARTITIONER::ParaDomainSelector::getFisrtGlobalIdOfSubentity( int loc_domain, int dist_domain ) const -{ - // total_nb_faces includes faces existing before creation of joint faces - // (got in gatherNbOf( MED_FACE )). - evaluateMemory(); - - int total_nb_faces = _face_shift_by_domain.empty() ? 0 : _face_shift_by_domain.back(); - int id = total_nb_faces + 1; - - if ( _nb_cell_pairs_by_joint.empty() ) - throw INTERP_KERNEL::Exception("gatherNbCellPairs() must be called before"); - int joint_id = jointId( loc_domain, dist_domain ); - for ( int j = 0; j < joint_id; ++j ) - id += _nb_cell_pairs_by_joint[ j ]; - - return id; -} - -//================================================================================ -/*! - * \brief Send-receive local ids of joint faces - */ -//================================================================================ - -int *MEDPARTITIONER::ParaDomainSelector::exchangeSubentityIds( int loc_domain, int dist_domain, - const std::vector<int>& loc_ids_here ) const -{ - int* loc_ids_dist = new int[ loc_ids_here.size()]; -#ifdef HAVE_MPI - int dest = getProcessorID( dist_domain ); - int tag = 2002 + jointId( loc_domain, dist_domain ); - MPI_Status status; - MPI_Sendrecv((void*)&loc_ids_here[0], loc_ids_here.size(), MPI_INT, dest, tag, - (void*) loc_ids_dist, loc_ids_here.size(), MPI_INT, dest, tag, - MPI_COMM_WORLD, &status); -#endif - evaluateMemory(); - - return loc_ids_dist; -} - -//================================================================================ -/*! - * \brief Return identifier for a joint - */ -//================================================================================ - -int MEDPARTITIONER::ParaDomainSelector::jointId( int local_domain, int distant_domain ) const -{ - evaluateMemory(); - if (_nb_result_domains < 0) - throw INTERP_KERNEL::Exception("setNbDomains() must be called before"); - - if ( local_domain < distant_domain ) - std::swap( local_domain, distant_domain ); - return local_domain * _nb_result_domains + distant_domain; -} - - -//================================================================================ -/*! - * \brief Return time passed from construction in seconds - */ -//================================================================================ - -double MEDPARTITIONER::ParaDomainSelector::getPassedTime() const -{ -#ifdef HAVE_MPI - return MPI_Wtime() - _init_time; -#else - return 0.0; -#endif -} - -/*! - Sends content of \a mesh to processor \a target. To be used with \a recvMesh method. - \param mesh mesh to be sent - \param target processor id of the target -*/ - -void MEDPARTITIONER::ParaDomainSelector::sendMesh(const ParaMEDMEM::MEDCouplingUMesh& mesh, int target) const -{ -#ifndef HAVE_MPI - throw INTERP_KERNEL::Exception("ParaDomainSelector::sendMesh : incoherent call in non_MPI mode"); -#else - if (MyGlobals::_Verbose>600) - std::cout << "proc " << _rank << " : sendMesh '" << mesh.getName() << "' size " << mesh.getNumberOfCells() << " to " << target << std::endl; - // First stage : sending sizes - // ------------------------------ - std::vector<int> tinyInfoLocal; - std::vector<std::string> tinyInfoLocalS; - std::vector<double> tinyInfoLocalD; - //Getting tiny info of local mesh to allow the distant proc to initialize and allocate - //the transmitted mesh. - mesh.getTinySerializationInformation(tinyInfoLocalD,tinyInfoLocal,tinyInfoLocalS); - tinyInfoLocal.push_back(mesh.getNumberOfCells()); - int tinySize=tinyInfoLocal.size(); - MPI_Send(&tinySize, 1, MPI_INT, target, 1113, MPI_COMM_WORLD); - MPI_Send(&tinyInfoLocal[0], tinyInfoLocal.size(), MPI_INT, target, 1112, MPI_COMM_WORLD); - - if (mesh.getNumberOfCells()>0) //no sends if empty - { - ParaMEDMEM::DataArrayInt *v1Local=0; - ParaMEDMEM::DataArrayDouble *v2Local=0; - //serialization of local mesh to send data to distant proc. - mesh.serialize(v1Local,v2Local); - int nbLocalElems=0; - int* ptLocal=0; - if(v1Local) //if empty getNbOfElems() is 1! - { - nbLocalElems=v1Local->getNbOfElems(); // if empty be 1! - ptLocal=v1Local->getPointer(); - } - MPI_Send(ptLocal, nbLocalElems, MPI_INT, target, 1111, MPI_COMM_WORLD); - int nbLocalElems2=0; - double *ptLocal2=0; - if(v2Local) //if empty be 0! - { - nbLocalElems2=v2Local->getNbOfElems(); - ptLocal2=v2Local->getPointer(); - } - MPI_Send(ptLocal2, nbLocalElems2, MPI_DOUBLE, target, 1110, MPI_COMM_WORLD); - if(v1Local) v1Local->decrRef(); - if(v2Local) v2Local->decrRef(); - } -#endif -} - -/*! Receives messages from proc \a source to fill mesh \a mesh. - To be used with \a sendMesh method. - \param mesh pointer to mesh that is filled - \param source processor id of the incoming messages -*/ -void MEDPARTITIONER::ParaDomainSelector::recvMesh(ParaMEDMEM::MEDCouplingUMesh*& mesh, int source)const -{ -#ifndef HAVE_MPI - throw INTERP_KERNEL::Exception("ParaDomainSelector::recvMesh : incoherent call in non_MPI mode"); -#else - // First stage : exchanging sizes - // ------------------------------ - std::vector<int> tinyInfoDistant; - std::vector<std::string> tinyInfoLocalS; - std::vector<double> tinyInfoDistantD(1); - //Getting tiny info of local mesh to allow the distant proc to initialize and allocate - //the transmitted mesh. - MPI_Status status; - int tinyVecSize; - MPI_Recv(&tinyVecSize, 1, MPI_INT, source, 1113, MPI_COMM_WORLD, &status); - tinyInfoDistant.resize(tinyVecSize); - std::fill(tinyInfoDistant.begin(),tinyInfoDistant.end(),0); - - MPI_Recv(&tinyInfoDistant[0], tinyVecSize, MPI_INT,source,1112,MPI_COMM_WORLD, &status); - //there was tinyInfoLocal.push_back(mesh.getNumberOfCells()); - int NumberOfCells=tinyInfoDistant[tinyVecSize-1]; - if (NumberOfCells>0) - { - ParaMEDMEM::DataArrayInt *v1Distant=ParaMEDMEM::DataArrayInt::New(); - ParaMEDMEM::DataArrayDouble *v2Distant=ParaMEDMEM::DataArrayDouble::New(); - //Building the right instance of copy of distant mesh. - ParaMEDMEM::MEDCouplingPointSet *distant_mesh_tmp= - ParaMEDMEM::MEDCouplingPointSet::BuildInstanceFromMeshType( - (ParaMEDMEM::MEDCouplingMeshType) tinyInfoDistant[0]); - std::vector<std::string> unusedTinyDistantSts; - mesh=dynamic_cast<ParaMEDMEM::MEDCouplingUMesh*> (distant_mesh_tmp); - - mesh->resizeForUnserialization(tinyInfoDistant,v1Distant,v2Distant,unusedTinyDistantSts); - int nbDistElem=0; - int *ptDist=0; - if(v1Distant) - { - nbDistElem=v1Distant->getNbOfElems(); - ptDist=v1Distant->getPointer(); - } - MPI_Recv(ptDist, nbDistElem, MPI_INT, source,1111, MPI_COMM_WORLD, &status); - double *ptDist2=0; - nbDistElem=0; - if(v2Distant) - { - nbDistElem=v2Distant->getNbOfElems(); - ptDist2=v2Distant->getPointer(); - } - MPI_Recv(ptDist2, nbDistElem, MPI_DOUBLE,source, 1110, MPI_COMM_WORLD, &status); - //finish unserialization - mesh->unserialization(tinyInfoDistantD,tinyInfoDistant,v1Distant,v2Distant,unusedTinyDistantSts); - if(v1Distant) v1Distant->decrRef(); - if(v2Distant) v2Distant->decrRef(); - } - else - { - mesh=CreateEmptyMEDCouplingUMesh(); - } - if (MyGlobals::_Verbose>600) - std::cout << "proc " << _rank << " : recvMesh '" << mesh->getName() << "' size " << mesh->getNumberOfCells() << " from " << source << std::endl; -#endif -} - -#ifndef WIN32 -#include <sys/sysinfo.h> -#endif - -/*! - * \brief Evaluate current memory usage and return the maximal one in KB - */ -int MEDPARTITIONER::ParaDomainSelector::evaluateMemory() const -{ - if ( _mesure_memory ) - { - int used_memory = 0; -#ifndef WIN32 - struct sysinfo si; - int err = sysinfo( &si ); - if ( !err ) - used_memory = (( si.totalram - si.freeram + si.totalswap - si.freeswap ) * si.mem_unit ) / 1024; -#endif - if ( used_memory > _max_memory ) - _max_memory = used_memory; - - if ( !_init_memory ) - _init_memory = used_memory; - } - return _max_memory - _init_memory; -} diff --git a/src/MEDPartitioner/MEDPARTITIONER_ParaDomainSelector.hxx b/src/MEDPartitioner/MEDPARTITIONER_ParaDomainSelector.hxx deleted file mode 100644 index 7db3c6082..000000000 --- a/src/MEDPartitioner/MEDPARTITIONER_ParaDomainSelector.hxx +++ /dev/null @@ -1,119 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// - -#ifndef __MEDPARTITIONER_PARADOMAINSELECTOR_HXX__ -#define __MEDPARTITIONER_PARADOMAINSELECTOR_HXX__ - -#include "MEDPARTITIONER.hxx" - -#include <memory> -#include <vector> - -namespace ParaMEDMEM -{ - class MEDCouplingUMesh; -} - -namespace MEDPARTITIONER -{ - class Graph; - class JointExchangeData; - - /*! - * \brief Communication helper in parallel mode - */ - class MEDPARTITIONER_EXPORT ParaDomainSelector - { - public: - ParaDomainSelector(bool mesure_memory=false); - ~ParaDomainSelector(); - - //processor rank - int rank() const { return _rank; } - //number of processors - int nbProcs() const { return _world_size; } - //true if is running on different hosts - bool isOnDifferentHosts() const; - //true if the domain with domainIndex is to be loaded on this proc - bool isMyDomain(int domainIndex) const; - //processor id where the domain with domainIndex resides - int getProcessorID(int domainIndex) const; - //Set nb of required domains. (Used to sort joints via jointId()) - void setNbDomains(int nb) { _nb_result_domains = nb; } - //identifier for a joint - int jointId( int local_domain, int distant_domain ) const; - - int getNbTotalCells() { return _cell_shift_by_domain.back(); } - int getNbTotalNodes() { return _node_shift_by_domain.back(); }; - int getNbTotalFaces() { return _face_shift_by_domain.back(); }; - - //Collect nb of entities on procs - void gatherNbOf(const std::vector<ParaMEDMEM::MEDCouplingUMesh*>& domain_meshes); - - //distribution of the graph vertices among the processors - int* getProcVtxdist() const; - - //nb of nodes on processors with lower rank - int getProcNodeShift() const; - //nb of cells in domains with lower index - int getDomainCellShift(int domainIndex) const; - //nb of nodes in domains with lower index - int getDomainNodeShift(int domainIndex) const; - - //Gather graphs from all processors into one - std::auto_ptr<Graph> gatherGraph(const Graph* graph) const; - - //Set nb of cell/cell pairs in a joint between domains - void setNbCellPairs( int nb_cell_pairs, int dist_domain, int loc_domain ); - //Gather size of each proc/proc joint - void gatherNbCellPairs(); - //nb of cell/cell pairs in a joint between domains on different procs - int getNbCellPairs( int dist_domain, int loc_domain ) const; - - //get the first global id of sub-entity for the joint - int getFisrtGlobalIdOfSubentity( int loc_domain, int dist_domain ) const; - //Send-receive local ids of joint faces - int* exchangeSubentityIds( int loc_domain, int dist_domain, - const std::vector<int>& loc_ids_here ) const; - //time passed from construction in seconds - double getPassedTime() const; - - //Evaluate current memory usage and return the maximal one in KB - int evaluateMemory() const; - - void sendMesh(const ParaMEDMEM::MEDCouplingUMesh& mesh, int target) const; - void recvMesh(ParaMEDMEM::MEDCouplingUMesh*& mesh, int source) const; - private: - int _rank; //my rank - int _world_size; //nb of processors - int _nb_result_domains; //required nb of domains - - std::vector< int > _nb_cell_pairs_by_joint; - std::vector< int > _nb_vert_of_procs; //graph vertices - std::vector< int > _cell_shift_by_domain; - std::vector< int > _node_shift_by_domain; - std::vector< int > _face_shift_by_domain; - - double _init_time; - bool _mesure_memory; - mutable int _init_memory; - mutable int _max_memory; - }; -} -#endif diff --git a/src/MEDPartitioner/MEDPARTITIONER_ParallelTopology.cxx b/src/MEDPartitioner/MEDPARTITIONER_ParallelTopology.cxx deleted file mode 100644 index b65d3fdd1..000000000 --- a/src/MEDPartitioner/MEDPARTITIONER_ParallelTopology.cxx +++ /dev/null @@ -1,674 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// - -#include "MEDPARTITIONER_MeshCollection.hxx" -#include "MEDPARTITIONER_Topology.hxx" -#include "MEDPARTITIONER_Graph.hxx" -#include "MEDPARTITIONER_ParaDomainSelector.hxx" -#include "MEDPARTITIONER_ParallelTopology.hxx" -#include "MEDPARTITIONER_ConnectZone.hxx" -#include "MEDPARTITIONER_Utils.hxx" - -#include "MEDCouplingSkyLineArray.hxx" -#include "MEDCouplingUMesh.hxx" -#include "InterpKernelHashMap.hxx" - -#include <set> -#include <map> -#include <vector> -#include <iostream> - -#ifdef HAVE_MPI -#include <mpi.h> -#endif - -using namespace MEDPARTITIONER; - -ParallelTopology::ParallelTopology():_nb_domain(0),_mesh_dimension(0) -{ -} - -//constructing topology according to mesh collection without global numerotation (use setGlobalNumerotation later) -ParallelTopology::ParallelTopology(const std::vector<ParaMEDMEM::MEDCouplingUMesh*>& meshes) -{ - _nb_domain=meshes.size(); - _nb_cells.resize(_nb_domain); - _nb_nodes.resize(_nb_domain); - // _nb_faces.resize(_nb_domain); - - if (MyGlobals::_Is0verbose>100) - std::cout << "new ParallelTopology\n"; - _loc_to_glob.resize(0); //precaution, need gatherNbOf() setGlobalNumerotation() - _node_loc_to_glob.resize(0); //precaution, need gatherNbOf() setGlobalNumerotation() - //_face_loc_to_glob.resize(_nb_domain); - _mesh_dimension = -1; - bool parallel_mode = false; - for (int idomain=0; !parallel_mode && idomain<_nb_domain; idomain++) - parallel_mode = (!meshes[idomain]); - - if (MyGlobals::_Is0verbose>20 && !parallel_mode) - std::cout << "WARNING : ParallelTopology contructor without parallel_mode" << std::endl; - for (int idomain=0; idomain<_nb_domain; idomain++) - { - if ( !meshes[idomain] ) continue; - if (_mesh_dimension==-1) - { - _mesh_dimension = meshes[idomain]->getMeshDimension(); - } - else - { - if (_mesh_dimension!=meshes[idomain]->getMeshDimension()) - throw INTERP_KERNEL::Exception("meshes dimensions incompatible"); - } - _nb_cells[idomain]=meshes[idomain]->getNumberOfCells(); - _nb_nodes[idomain]=meshes[idomain]->getNumberOfNodes(); - //note: in parallel mode _nb_cells and _nb_nodes are not complete now, needs gatherNbOf() - } -} - -//constructing _loc_to_glob etc by default, needs gatherNbOf() done -void ParallelTopology::setGlobalNumerotationDefault(ParaDomainSelector* domainSelector) -{ - if (MyGlobals::_Is0verbose>100) - std::cout<< "setGlobalNumerotationDefault on " << _nb_domain << " domains\n"; - if (_loc_to_glob.size()!=0) throw INTERP_KERNEL::Exception("a global numerotation is done yet"); - _loc_to_glob.resize(_nb_domain); - _node_loc_to_glob.resize(_nb_domain); - - //warning because _nb_cells[idomain] is 0 if not my domain(s) - //we set loc_to_glob etc.. only for my domain(s) - if (MyGlobals::_Is0verbose>500) - std::cout << "(c)idomain|ilocalCell|iglobalCell" << std::endl; - for (int idomain=0; idomain<_nb_domain; idomain++) - { - _loc_to_glob[idomain].resize(_nb_cells[idomain]); - int domainCellShift=domainSelector->getDomainCellShift(idomain); - for (int i=0; i<_nb_cells[idomain]; i++) - { - int global=domainCellShift+i ; - _glob_to_loc.insert(std::make_pair(global,std::make_pair(idomain,i))); - _loc_to_glob[idomain][i]=global; - if (MyGlobals::_Verbose>500) - std::cout << "c" << idomain << "|" << i << "|" << global << " "; - } - } -#ifdef HAVE_MPI - if (MyGlobals::_Verbose>500 && MyGlobals::_World_Size>1) MPI_Barrier(MPI_COMM_WORLD); //synchronize verbose trace -#endif - if (MyGlobals::_Is0verbose>500) std::cout << std::endl; - - if (MyGlobals::_Is0verbose>500) std::cout << "(n)idomain|ilocalNode|iglobalNode" << std::endl; - for (int idomain=0; idomain<_nb_domain; idomain++) - { - _node_loc_to_glob[idomain].resize(_nb_nodes[idomain]); - int domainNodeShift=domainSelector->getDomainNodeShift(idomain); - for (int i=0; i<_nb_nodes[idomain]; i++) - { - int global=domainNodeShift+i ; - _node_glob_to_loc.insert(std::make_pair(global,std::make_pair(idomain,i))); - _node_loc_to_glob[idomain][i]=global; - if (MyGlobals::_Verbose>500) - std::cout << "n" << idomain << "|" << i << "|" << global << " "; - } - } -#ifdef HAVE_MPI - if (MyGlobals::_Verbose>500 && MyGlobals::_World_Size>1) MPI_Barrier(MPI_COMM_WORLD); //synchronize verbose trace -#endif - if (MyGlobals::_Is0verbose>500) std::cout << std::endl; - - _nb_total_cells=domainSelector->getNbTotalCells(); - _nb_total_nodes=domainSelector->getNbTotalNodes(); - _nb_total_faces=domainSelector->getNbTotalFaces(); - if (MyGlobals::_Is0verbose>200) - std::cout << "globalNumerotation default done meshDimension " << _mesh_dimension << " nbTotalCells " << _nb_total_cells << " nbTotalNodes " << _nb_total_nodes << std::endl; -} - -//constructing topology according to mesh collection -ParallelTopology::ParallelTopology(const std::vector<ParaMEDMEM::MEDCouplingUMesh*>& meshes, - const std::vector<MEDPARTITIONER::ConnectZone*>& cz, - std::vector<int*>& cellglobal, - std::vector<int*>& nodeglobal, - std::vector<int*>& faceglobal) -{ - _nb_domain=meshes.size(); - int index_global=0; - int index_node_global=0; - int index_face_global=0; - - _nb_cells.resize(_nb_domain); - _nb_nodes.resize(_nb_domain); - // _nb_faces.resize(_nb_domain); - - _loc_to_glob.resize(_nb_domain); - _node_loc_to_glob.resize(_nb_domain); - // _face_loc_to_glob.resize(_nb_domain); - - bool parallel_mode = false; - for (int idomain=0; !parallel_mode && idomain<_nb_domain; idomain++) - parallel_mode = (!meshes[idomain]); - - for (int idomain=0; idomain<_nb_domain; idomain++) - { - if ( !meshes[idomain] ) continue; - _mesh_dimension = meshes[idomain]->getMeshDimension(); - - //creating cell maps - _nb_cells[idomain]=meshes[idomain]->getNumberOfCells(); - // cout << "Nb cells (domain "<<idomain<<") = "<<_nb_cells[idomain]; - _loc_to_glob[idomain].resize(_nb_cells[idomain]); - - if (cellglobal[idomain]==0 || parallel_mode) - { - //int cellDomainShift=_cell_shift_by_domain[idomain]; - //creating global numbering from scratch - for (int i=0; i<_nb_cells[idomain]; i++) - { - int global=i ;//cellDomainShift+i; - _glob_to_loc.insert(std::make_pair(global,std::make_pair(idomain,i))); - _loc_to_glob[idomain][i]=global; - index_global++; - } - } - //using global numbering coming from a previous numbering - else - { - for (int i=0; i<_nb_cells[idomain]; i++) - { - int global=cellglobal[idomain][i]; - _glob_to_loc.insert(std::make_pair(global,std::make_pair(idomain,i))); - //_loc_to_glob[make_pair(idomain,i+1)]=global; - _loc_to_glob[idomain][i]=global; - index_global++; - } - } - - //cas sequentiel - if (_nb_domain==1) - { - _nb_total_cells=index_global; - _nb_cells[0]=index_global; - _node_loc_to_glob[idomain].resize(meshes[idomain]->getNumberOfNodes()); - for (int i=0; i<meshes[idomain]->getNumberOfNodes(); i++) - { - _node_glob_to_loc.insert(std::make_pair(i,std::make_pair(0,i))); - _node_loc_to_glob[0][i]=i; - } - _nb_total_nodes=meshes[idomain]->getNumberOfNodes(); - _nb_nodes[0]=_nb_total_nodes; - return; - } - - //creating node maps - _nb_nodes[idomain]=meshes[idomain]->getNumberOfNodes(); - INTERP_KERNEL::HashMap <int,std::pair<int,int> > local2distant; - _node_loc_to_glob[idomain].resize(_nb_nodes[idomain]); - for (std::size_t icz=0; icz<cz.size(); icz++) - { - if (cz[icz]->getLocalDomainNumber() == idomain && - cz[icz]->getLocalDomainNumber()>cz[icz]->getDistantDomainNumber()) - { - int nb_node= cz[icz]->getNodeNumber(); - const int* node_corresp=cz[icz]->getNodeCorrespValue(); - int distant_ip = cz[icz]->getDistantDomainNumber(); - for (int i=0; i< nb_node; i++) - { - int local= node_corresp[i*2]; - int distant = node_corresp[i*2+1]; - local2distant.insert(std::make_pair(local, std::make_pair(distant_ip,distant))); - } - } - } - // setting mappings for all nodes - if (nodeglobal[idomain]==0) - { - for (int inode=0; inode<_nb_nodes[idomain]; inode++) - { - if (local2distant.find(inode)==local2distant.end()) - { - index_node_global++; - _node_glob_to_loc.insert(std::make_pair(index_node_global,std::make_pair(idomain,inode))); - //_node_loc_to_glob[make_pair(idomain,inode+1)]=index_node_global; - _node_loc_to_glob[idomain][inode]=index_node_global; - } - else - { - int ip = (local2distant.find(inode)->second).first; - int distant = (local2distant.find(inode)->second).second; - int global_number=_loc_to_glob[ip][distant]; - _node_glob_to_loc.insert(std::make_pair(global_number,std::make_pair(idomain,inode))); - _node_loc_to_glob[idomain][inode]=global_number; - } - } - } - //using former node numbering - else - { - for (int inode=0; inode<_nb_nodes[idomain]; inode++) - { - int global_number=nodeglobal[idomain][inode]; - _node_glob_to_loc.insert(std::make_pair(global_number,std::make_pair(idomain,inode))); - _node_loc_to_glob[idomain][inode]=global_number; - } - } - } - - _nb_total_cells=index_global; - _nb_total_nodes=index_node_global; - _nb_total_faces=index_face_global; -} - - -//constructing ParallelTopology from an old topology and a graph -ParallelTopology::ParallelTopology(Graph* graph, Topology* oldTopology, int nb_domain, int mesh_dimension) -{ - - _nb_domain=nb_domain; - _mesh_dimension=mesh_dimension; - - if (MyGlobals::_Verbose>200) - std::cout << "proc " << MyGlobals::_Rank << " : new topology oldNbDomain " << - oldTopology->nbDomain() << " newNbDomain " << _nb_domain << std::endl; - _nb_cells.resize(_nb_domain,0); - _nb_nodes.resize(_nb_domain,0); - _nb_faces.resize(_nb_domain,0); - - _loc_to_glob.resize(_nb_domain); - _node_loc_to_glob.resize(_nb_domain); - _face_loc_to_glob.resize(_nb_domain); - - const int* part=graph->getPart(); //all cells for this proc (may be more domains) - _nb_total_cells=graph->nbVertices(); //all cells for this proc (may be more domains) - if (MyGlobals::_Verbose>300) - std::cout << "proc " << MyGlobals::_Rank << " : topology from partition, nbTotalCells " << _nb_total_cells << std::endl; - - int icellProc=0; //all cells of my domains are concatenated in part - for (int iold=0; iold<oldTopology->nbDomain(); iold++) - { - int ioldNbCell=oldTopology->getCellNumber(iold); - //std::cout<<"proc "<<MyGlobals::_Rank<<" : cell number old domain "<<iold<<" : "<<ioldNbCell<<std::endl; - //if not my old domains getCellNumber is 0 - std::vector<int> globalids(ioldNbCell); - oldTopology->getCellList(iold, &globalids[0]); //unique global numerotation - for (int icell=0; icell<ioldNbCell; icell++) - { - int idomain=part[icellProc]; - _nb_cells[idomain]++; - icellProc++; - int iGlobalCell=globalids[icell]; - _loc_to_glob[idomain].push_back(iGlobalCell); - _glob_to_loc.insert(std::make_pair(iGlobalCell, std::make_pair(idomain, _nb_cells[idomain]))); - } - } - - if (MyGlobals::_Verbose>300) - for (int idomain=0; idomain<_nb_domain; idomain++) - std::cout << "proc " << MyGlobals::_Rank << " : nbCells in new domain " << idomain << " : " << _nb_cells[idomain] << std::endl; - - // JOINTs - - if ( MyGlobals::_Create_Joints && nb_domain > 1 ) - { - std::vector< std::vector< std::vector< int > > > cellCorresp( nb_domain ); - for ( int idomain = 0; idomain < nb_domain; ++idomain ) - { - cellCorresp[ idomain ].resize( nb_domain ); - } - const ParaMEDMEM::MEDCouplingSkyLineArray* skylinegraph = graph->getGraph(); - const int* index = skylinegraph->getIndex(); - const int* value = skylinegraph->getValue(); - const int nbCells = skylinegraph->getNumberOf(); - - for ( int iGlob = 0; iGlob < nbCells; ++iGlob ) - { - int iGlobDom = part[ iGlob ]; - for ( int i = index[ iGlob ]; i < index[ iGlob+1 ]; i++ ) - { - int iGlobNear = value[ i ]; - if ( iGlob > iGlobNear ) - continue; // treat ( iGlob, iGlobNear ) pair once - int iGlobNearDom = part[ iGlobNear ]; - if ( iGlobDom != iGlobNearDom ) - { - int iLoc = convertGlobalCell( iGlob ).second - 1; // to MEDCoupling fmt - int iLocNear = convertGlobalCell( iGlobNear ).second - 1; - cellCorresp[ iGlobDom ][ iGlobNearDom ].push_back( iLoc ); - cellCorresp[ iGlobDom ][ iGlobNearDom ].push_back( iLocNear ); - cellCorresp[ iGlobNearDom ][ iGlobDom ].push_back( iLocNear ); - cellCorresp[ iGlobNearDom ][ iGlobDom ].push_back( iLoc ); - } - } - } - for ( int idomain = 0; idomain < nb_domain; ++idomain ) - { - for ( int idomainNear = 0; idomainNear < nb_domain; ++idomainNear ) - { - std::vector< int > & corresp = cellCorresp[ idomain ][ idomainNear ]; - if ( corresp.empty() ) - continue; - MEDPARTITIONER::ConnectZone* cz = new MEDPARTITIONER::ConnectZone(); - cz->setName( "Connect Zone defined by MEDPARTITIONER" ); - cz->setDistantDomainNumber( idomainNear ); - cz->setLocalDomainNumber ( idomain ); - cz->setEntityCorresp( 0,0, &corresp[0], corresp.size()/2 ); - _connect_zones.push_back( cz ); - } - } - } -} - -ParallelTopology::~ParallelTopology() -{ - for ( size_t i = 0; i < _connect_zones.size(); ++i ) - { - delete _connect_zones[i]; - _connect_zones[i] = 0; - } - _connect_zones.clear(); -} - -/*!Converts a list of global node numbers - * to a distributed array with local cell numbers. - * - * If a node in the list is represented on several domains, - * only the first value is returned - * */ -void ParallelTopology::convertGlobalNodeList(const int* node_list, int nbnode, int* local, int* ip) -{ - if (_node_glob_to_loc.empty()) - throw INTERP_KERNEL::Exception("Node mapping has not yet been built"); - for (int i=0; i< nbnode; i++) - { - std::pair<int,int> local_node = _node_glob_to_loc.find(node_list[i])->second; - ip[i]=local_node.first; - local[i]=local_node.second; - } -} - -/*!Converts a list of global node numbers on domain ip - * to a distributed array with local cell numbers. - * - * If a node in the list is represented on several domains, - * only the value with domain ip is returned - * - * */ -void ParallelTopology::convertGlobalNodeList(const int* node_list, int nbnode, int* local, int ip) -{ - if (_node_glob_to_loc.empty()) - throw INTERP_KERNEL::Exception("Node mapping has not yet been built"); - - for (int i=0; i< nbnode; i++) - { - typedef INTERP_KERNEL::HashMultiMap<int,std::pair<int,int> >::iterator mmiter; - std::pair<mmiter,mmiter> range=_node_glob_to_loc.equal_range(node_list[i]); - for (mmiter it=range.first; it !=range.second; it++) - { - int ipfound=(it->second).first; - if (ipfound==ip) - local[i]=(it->second).second; - } - } -} - -/*!Converts a list of global node numbers - * to a distributed array with local cell numbers. - * - * If a node in the list is represented on several domains, - * all the values are put in the array - * */ -void ParallelTopology::convertGlobalNodeListWithTwins(const int* node_list, int nbnode, int*& local, int*& ip,int*& full_array, int& size) -{ - if (_node_glob_to_loc.empty()) - throw INTERP_KERNEL::Exception("Node mapping has not yet been built"); - - size=0; - for (int i=0; i< nbnode; i++) - { - int count= _node_glob_to_loc.count(node_list[i]); - size+=count; - } - int index=0; - ip=new int[size]; - local=new int[size]; - full_array=new int[size]; - for (int i=0; i< nbnode; i++) - { - typedef INTERP_KERNEL::HashMultiMap<int,std::pair<int,int> >::iterator mmiter; - std::pair<mmiter,mmiter> range=_node_glob_to_loc.equal_range(node_list[i]); - for (mmiter it=range.first; it !=range.second; it++) - { - ip[index]=(it->second).first; - local[index]=(it->second).second; - full_array [index]=node_list[i]; - index++; - } - - } -} - -/*!Converts a list of global face numbers - * to a distributed array with local face numbers. - * - * If a face in the list is represented on several domains, - * all the values are put in the array - * */ -void ParallelTopology::convertGlobalFaceListWithTwins(const int* face_list, int nbface, int*& local, int*& ip, int*& full_array,int& size) -{ - size=0; - for (int i=0; i< nbface; i++) - { - //int count = _face_glob_to_loc.count(face_list[i]); - //if (count >1) MESSAGE_MED("face en doublon "<<face_list[i]); - size+= _face_glob_to_loc.count(face_list[i]); - } - int index=0; - ip=new int[size]; - local=new int[size]; - full_array=new int[size]; - for (int i=0; i< nbface; i++) - { - typedef INTERP_KERNEL::HashMultiMap<int,std::pair<int,int> >::iterator mmiter; - std::pair<mmiter,mmiter> range=_face_glob_to_loc.equal_range(face_list[i]); - for (mmiter it=range.first; it !=range.second; it++) - { - ip[index]=(it->second).first; - local[index]=(it->second).second; - full_array[index]=face_list[i]; - index++; - } - - } -} - -//!converts a list of global cell numbers -//!to a distributed array with local cell numbers -void ParallelTopology::convertGlobalCellList(const int* cell_list, int nbcell, int* local, int* ip) -{ - for (int i=0; i<nbcell; i++) - { - INTERP_KERNEL::HashMap<int, std::pair<int,int> >::const_iterator iter = _glob_to_loc.find(cell_list[i]); - if (iter == _glob_to_loc.end()) - { - std::cerr << "proc " << MyGlobals::_Rank << " : KO cell_list[" << i << "] : " << cell_list[i] << std::endl; - throw INTERP_KERNEL::Exception("ParallelTopology::convertGlobalCellList : Cell not found"); - } - else - { - ip[i]=(iter->second).first; //no domain - local[i]=(iter->second).second; //no local cell - } - } -} - -/*!Converts a list of global face numbers - * to a distributed array with local face numbers - */ -void ParallelTopology::convertGlobalFaceList(const int* face_list, int nbface, int* local, int* ip) -{ - for (int i=0; i< nbface; i++) - { - INTERP_KERNEL::HashMap<int, std::pair<int,int> >::const_iterator iter = _face_glob_to_loc.find(face_list[i]); - if (iter == _face_glob_to_loc.end()) - { - throw INTERP_KERNEL::Exception("ParallelTopology::convertGlobalFaceList : Face not found"); - } - ip[i]=(iter->second).first; - local[i]=(iter->second).second; - } -} - -/*!Converts a list of global node numbers on domain ip - * to a distributed array with local cell numbers. - * - * If a node in the list is represented on several domains, - * only the value with domain ip is returned - * - */ -void ParallelTopology::convertGlobalFaceList(const int* face_list, int nbface, int* local, int ip) -{ - for (int i=0; i< nbface; i++) - { - typedef INTERP_KERNEL::HashMultiMap<int,std::pair<int,int> >::iterator mmiter; - std::pair<mmiter,mmiter> range=_face_glob_to_loc.equal_range(face_list[i]); - for (mmiter it=range.first; it !=range.second; it++) - { - int ipfound=(it->second).first; - if (ipfound==ip) - local[i]=(it->second).second; - - } - } -} - -//replacing a table of global numbering with a table with local numberings -// type_connectivity contains global connectivity for each type in input -// type_connectivity contains local connectivity for each type in output -void ParallelTopology::convertToLocal2ndVersion(int* nodes, int nbnodes, int idomain) -{ - for (int inode=0; inode<nbnodes; inode++) - { - // cout <<" inode :"<<inode<< " global = "<<type_connectivity[type][inode]; - int global = nodes[inode]; - typedef INTERP_KERNEL::HashMultiMap<int,std::pair<int,int> >::iterator mmiter; - std::pair<mmiter,mmiter> range=_node_glob_to_loc.equal_range(global); - for (mmiter it=range.first; it !=range.second; it++) - { - if ((it->second).first==idomain) - nodes[inode]=(it->second).second; - } - } -} - -/*! - * \brief Return max global face number - */ -int ParallelTopology::getMaxGlobalFace() const -{ - int max = 0; - TGlob2LocsMap::const_iterator g_l_l = _face_glob_to_loc.begin(); - for ( ; g_l_l != _face_glob_to_loc.end(); ++g_l_l ) - if ( g_l_l->first > max ) - max = g_l_l->first; - return max; -} - -int ParallelTopology::getNodeNumber() const -{ - if (_node_glob_to_loc.empty()) return 0; - std::set <int> keys; - for (INTERP_KERNEL::HashMultiMap<int, std::pair<int,int> >::const_iterator iter= _node_glob_to_loc.begin(); iter!=_node_glob_to_loc.end(); iter++) - { - keys.insert(iter->first); - } - return keys.size(); -} - -/*! - * retrieving list of nodes in global numbers - */ -void ParallelTopology::getNodeList(int idomain, int *list) const -{ - for (int i=0; i<_nb_nodes[idomain]; i++) - list[i]=_node_loc_to_glob[idomain][i]; -} - -/*! - * retrieving list of nodes in global numbers - */ -void ParallelTopology::getCellList(int idomain, int *list) const -{ - for (int i=0; i<_nb_cells[idomain];i++) - list[i]=_loc_to_glob[idomain][i]; -} - -int ParallelTopology::getFaceNumber() const -{ - if (_face_glob_to_loc.empty()) - return 0; - std::set <int> keys; - for (INTERP_KERNEL::HashMultiMap<int, std::pair<int,int> >::const_iterator iter= _face_glob_to_loc.begin(); iter!=_face_glob_to_loc.end(); iter++) - { - keys.insert(iter->first); - } - return keys.size(); -} - -/*! - * retrieving list of faces in global numbers - */ -void ParallelTopology::getFaceList(int idomain, int *list) const -{ - for (int i=0; i<_nb_faces[idomain];i++) - list[i]=_face_loc_to_glob[idomain][i]; -} - -int ParallelTopology::convertGlobalFace(int iglobal, int idomain) -{ - typedef INTERP_KERNEL::HashMultiMap<int, std::pair<int,int> >::const_iterator MMiter; - std::pair<MMiter,MMiter> eq = _face_glob_to_loc.equal_range(iglobal); - for (MMiter it=eq.first; it != eq.second; it++) - if (it->second.first == idomain) - return it->second.second; - return -1; -} - -int ParallelTopology::convertGlobalNode(int iglobal, int idomain) -{ - typedef INTERP_KERNEL::HashMultiMap<int, std::pair<int,int> >::const_iterator MMiter; - std::pair<MMiter,MMiter> eq = _node_glob_to_loc.equal_range(iglobal); - for (MMiter it=eq.first; it != eq.second; it++) - { - if (it->second.first == idomain) - return it->second.second; - } - return -1; -} - -std::vector<MEDPARTITIONER::ConnectZone*>& ParallelTopology::getCZ() -{ - return _connect_zones; -} - -/*! - * adding a face to the topology - */ -void ParallelTopology::appendFace(int idomain, int ilocal, int iglobal) -{ - _face_loc_to_glob[idomain].push_back(iglobal); - _face_glob_to_loc.insert(std::make_pair(iglobal,std::make_pair(idomain,ilocal))); -} diff --git a/src/MEDPartitioner/MEDPARTITIONER_ParallelTopology.hxx b/src/MEDPartitioner/MEDPARTITIONER_ParallelTopology.hxx deleted file mode 100644 index f18723fb2..000000000 --- a/src/MEDPartitioner/MEDPARTITIONER_ParallelTopology.hxx +++ /dev/null @@ -1,194 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// - -#ifndef __MEDPARTITIONER_PARALLELTOPOLOGY_HXX__ -#define __MEDPARTITIONER_PARALLELTOPOLOGY_HXX__ - -#include "MEDPARTITIONER.hxx" -#include "MEDPARTITIONER_Topology.hxx" - -#include "InterpKernelHashMap.hxx" - -#include <set> -#include <vector> - -namespace MEDPARTITIONER -{ - class Graph; - class MeshCollection; - class ParaDomainSelector; - - class MEDPARTITIONER_EXPORT ParallelTopology : public Topology - { - - public: - - ParallelTopology(); - ParallelTopology(const std::vector<ParaMEDMEM::MEDCouplingUMesh*>&); - ParallelTopology(const std::vector<ParaMEDMEM::MEDCouplingUMesh*>&, - const std::vector<MEDPARTITIONER::ConnectZone*>&, - std::vector<int*>&, - std::vector<int*>&, - std::vector<int*>&); - ParallelTopology(Graph* graph, Topology* oldTopology, int nbdomain, int mesh_dimension); - ~ParallelTopology(); - - void setGlobalNumerotationDefault(ParaDomainSelector* domainSelector); - - /*! converts a list of global cell numbers - * to a distributed array with local cell numbers - */ - void convertGlobalNodeList(const int*, int,int*,int*); - void convertGlobalNodeList(const int*, int,int*,int); - void convertGlobalNodeListWithTwins(const int* face_list, int nbnode, int*& local, int*& ip, int*& full_array, int& size); - - /*! converts a list of global node numbers - * to a distributed array with local cell numbers - */ - void convertGlobalCellList(const int*, int , int*, int *); - - /*! converts a list of global face numbers - * to a distributed array with local face numbers - */ - void convertGlobalFaceList(const int*, int , int*, int *); - void convertGlobalFaceList(const int*, int , int*, int); - void convertGlobalFaceListWithTwins(const int* face_list, int nbface, int*& local, int*& ip, int*& full_array,int& size); - - /*! converting node global numberings to local numberings */ - void convertToLocal2ndVersion(int* nodes, int nbnodes, int idomain); - - /*! converting node local numbering to global */ - int convertNodeToGlobal(int ip, int icell) const { return _node_loc_to_glob[ip][icell]; } - - /*! converting face local numbering to global */ - int convertFaceToGlobal(int ip, int iface) const { return _face_loc_to_glob[ip][iface]; } - - /*! converting cell global numbering to local */ - int convertCellToGlobal(int ip, int icell) const { return _loc_to_glob[ip][icell]; } - - void convertNodeToGlobal(int ip, const int* local, int n, int *global) const - { - for (int i=0; i<n; i++) - global[i]=_node_loc_to_glob[ip][local[i]]; - } - - void convertCellToGlobal(int ip, const int* local, int n, int *global) const - { - for (int i=0; i<n; i++) - global[i]=_loc_to_glob[ip][local[i]]; - } - - void convertFaceToGlobal(int ip, const int* local, int n, int *global) const - { - for (int i=0; i<n; i++) - global[i]=_face_loc_to_glob[ip][local[i]]; - } - - int nbDomain() const { return _nb_domain; } - - int nbCells() const { return _nb_total_cells; } - - int nbNodes() const { return _nb_total_nodes; } - - int nbCells( int idomain) const { return _nb_cells[idomain]; } - - /*! retrieving number of nodes */ - int getNodeNumber(int idomain) const { return _nb_nodes[idomain]; } - - int getNodeNumber() const; - - void getNodeList(int idomain, int* list) const; - - /*! retrieving cell numbers after merging in parallel mode */ - std::vector<int> & getFusedCellNumbers(int idomain) { return _cell_loc_to_glob_fuse[idomain]; } - - const std::vector<int>& getFusedCellNumbers(int idomain) const { return _cell_loc_to_glob_fuse[idomain]; } - - /*! retrieving face numbers after merging in parallel mode */ - std::vector<int> & getFusedFaceNumbers(int idomain) { return _face_loc_to_glob_fuse[idomain]; } - - const std::vector<int>& getFusedFaceNumbers(int idomain) const { return _face_loc_to_glob_fuse[idomain]; } - - /*! retrieving number of nodes */ - int getCellNumber(int idomain) const { return _nb_cells[idomain]; } - - int getCellDomainNumber(int global) const { return (_glob_to_loc.find(global)->second).first; } - - void getCellList(int idomain, int* list) const; - - int getFaceNumber(int idomain) const { return _nb_faces[idomain]; } - - int getFaceNumber() const; - - void getFaceList(int idomain, int* list) const; - - /*! converting a global cell number to a local representation (domain + local number) */ - std::pair<int,int> convertGlobalCell(int iglobal) const { return _glob_to_loc.find(iglobal)->second; } - - int convertGlobalFace(int iglobal, int idomain); - - int convertGlobalNode(int iglobal, int idomain); - - std::vector<MEDPARTITIONER::ConnectZone*>& getCZ(); - - //adding a face to the topology - void appendFace(int idomain, int ilocal, int iglobal); - - //return max global face number - int getMaxGlobalFace() const; - - private: - bool hasCellWithNodes( const MeshCollection&, int dom, const std::set<int>& nodes ); - - private: - //mapping global -> local - typedef INTERP_KERNEL::HashMultiMap<int,std::pair<int,int> > TGlob2DomainLoc; - - TGlob2DomainLoc _glob_to_loc; - TGlob2DomainLoc _node_glob_to_loc; - - //mapping local -> global - std::vector<std::vector<int> > _loc_to_glob; - std::vector<std::vector <int> > _node_loc_to_glob; - - // global numbers in parallel mode - std::vector<std::vector <int> > _cell_loc_to_glob_fuse; // glob nums after merging - std::vector<std::vector <int> > _face_loc_to_glob_fuse; // glob nums after merging - - //mapping global -> local - typedef INTERP_KERNEL::HashMultiMap<int,std::pair<int,int> > TGlob2LocsMap; - TGlob2LocsMap _face_glob_to_loc; - - //mapping local -> global - std::vector<std::vector <int> > _face_loc_to_glob; - std::vector<int> _nb_cells; - std::vector<int> _nb_nodes; - std::vector<int> _nb_faces; - int _nb_total_cells; - int _nb_total_nodes; - int _nb_total_faces; - int _nb_domain; - int _mesh_dimension; - - //links to connectzones - std::vector<MEDPARTITIONER::ConnectZone*> _connect_zones; - - }; -} -#endif diff --git a/src/MEDPartitioner/MEDPARTITIONER_ScotchGraph.cxx b/src/MEDPartitioner/MEDPARTITIONER_ScotchGraph.cxx deleted file mode 100644 index 1289291e1..000000000 --- a/src/MEDPartitioner/MEDPARTITIONER_ScotchGraph.cxx +++ /dev/null @@ -1,117 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// - -#include "MEDPARTITIONER_Graph.hxx" -#include "MEDPARTITIONER_ScotchGraph.hxx" -#include "MEDPARTITIONER_Utils.hxx" - -#include "MEDCouplingSkyLineArray.hxx" - -#include <cstdio> - -#ifdef MED_ENABLE_SCOTCH -extern "C" -{ -#define restrict -#include "scotch.h" -} -#endif - -using namespace MEDPARTITIONER; - -SCOTCHGraph::SCOTCHGraph():Graph() -{ -} - -SCOTCHGraph::SCOTCHGraph(ParaMEDMEM::MEDCouplingSkyLineArray* graph, int* edgeweight):Graph(graph,edgeweight) -{ -} - -SCOTCHGraph::~SCOTCHGraph() -{ -} - -void SCOTCHGraph::partGraph(int ndomain, const std::string& options_string, ParaDomainSelector* sel) -{ - if (MyGlobals::_Verbose>10) - std::cout << "proc " << MyGlobals::_Rank << " : SCOTCHGraph::partGraph" << std::endl; - - //number of graph vertices - int n = _graph->getNumberOf(); - //graph - int * xadj=const_cast<int*>(_graph->getIndex()); - int * adjncy=const_cast<int*>(_graph->getValue()); - //ndomain - int nparts=ndomain; - -#if !defined(MED_ENABLE_SCOTCH) - throw INTERP_KERNEL::Exception("SCOTCHGraph::partGraph : SCOTCH is not available. Check your products, please."); -#else - //output parameters - int* partition = new int[n+1]; - - SCOTCH_Graph scotch_graph; - SCOTCH_graphInit(&scotch_graph); - SCOTCH_graphBuild(&scotch_graph, - 0, //base first indice 0 - n, //nb of graph nodes - xadj, - 0, - _cell_weight, //graph vertices loads - 0, - xadj[n], //number of edges - adjncy, - _edge_weight); - SCOTCH_Strat scotch_strategy; - SCOTCH_stratInit(&scotch_strategy); - - //!user-defined options for the strategy - if (options_string!="") - SCOTCH_stratGraphMap(&scotch_strategy,options_string.c_str()); - - if (nparts>1) - { - if (MyGlobals::_Verbose>10) std::cout << "SCOTCHGraph::graphPart SCOTCH_graphPart" << std::endl; - SCOTCH_graphPart(&scotch_graph,nparts,&scotch_strategy,partition); - } - else //partition for 1 subdomain - { - for (int i=0; i<n+1; i++) - partition[i]=0; - } - - SCOTCH_stratExit(&scotch_strategy); - SCOTCH_graphExit(&scotch_graph); - - std::vector<int> index(n+1); - std::vector<int> value(n); - index[0]=0; - for (int i=0; i<n; i++) - { - index[i+1]=index[i]+1; - value[i]=partition[i]; - } - delete [] partition; - - //creating a skylinearray with no copy of the index and partition array - //the fifth argument true specifies that only the pointers are passed - //to the object - _partition = new ParaMEDMEM::MEDCouplingSkyLineArray(index,value); -#endif -} diff --git a/src/MEDPartitioner/MEDPARTITIONER_ScotchGraph.hxx b/src/MEDPartitioner/MEDPARTITIONER_ScotchGraph.hxx deleted file mode 100644 index 96f5854b0..000000000 --- a/src/MEDPartitioner/MEDPARTITIONER_ScotchGraph.hxx +++ /dev/null @@ -1,40 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// - -#ifndef __MEDPARTITIONER_SCOTCHGRAPH_HXX__ -#define __MEDPARTITIONER_SCOTCHGRAPH_HXX__ - -#include "MEDPARTITIONER.hxx" -#include "MEDPARTITIONER_Graph.hxx" - -#include <string> - -namespace MEDPARTITIONER -{ - class MEDPARTITIONER_EXPORT SCOTCHGraph : public Graph - { - public: - SCOTCHGraph(); - SCOTCHGraph(ParaMEDMEM::MEDCouplingSkyLineArray*, int* edgeweight=0); - virtual ~SCOTCHGraph(); - void partGraph(int ndomain, const std::string& options_string="", ParaDomainSelector* sel=0); - }; -} - -#endif diff --git a/src/MEDPartitioner/MEDPARTITIONER_Topology.hxx b/src/MEDPartitioner/MEDPARTITIONER_Topology.hxx deleted file mode 100644 index 018388c62..000000000 --- a/src/MEDPartitioner/MEDPARTITIONER_Topology.hxx +++ /dev/null @@ -1,112 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// - -#ifndef __MEDPARTITIONER_TOPOLOGY_HXX__ -#define __MEDPARTITIONER_TOPOLOGY_HXX__ - -#include "MEDPARTITIONER.hxx" - -#include <map> -#include <vector> - -namespace ParaMEDMEM -{ - class MEDCouplingUMesh; -} - -namespace MEDPARTITIONER -{ - class Graph; - class ConnectZone; - class MeshCollection; - class MEDPARTITIONER_FaceModel; - - class MEDPARTITIONER_EXPORT Topology - { - public: - Topology() { } - Topology(std::vector<ParaMEDMEM::MEDCouplingUMesh*>, std::vector<MEDPARTITIONER::ConnectZone*>) { } - virtual ~Topology() { } - - /*! converts a list of global cell numbers - * to a distributed array with local cell numbers - */ - virtual void convertGlobalNodeList(const int *list, int nb, int *local, int*ip) = 0; - virtual void convertGlobalNodeList(const int *list, int nb, int *local, int ip) = 0; - //converts a list of global node numbers - /*! to a distributed array with local cell numbers */ - virtual void convertGlobalCellList(const int*list , int nb, int *local, int*ip) = 0; - - /*! converts a list of global face numbers - * to a distributed array with local face numbers - */ - virtual void convertGlobalFaceList(const int*list , int nb, int* local, int*ip) = 0; - virtual void convertGlobalFaceList(const int*list , int nb, int* local, int ip) = 0; - virtual void convertGlobalFaceListWithTwins(const int *face_list, int nbface, int*& local, int*& ip, int*& full_array, int& size) = 0; - virtual void convertGlobalNodeListWithTwins(const int *face_list, int nbnode, int*& local, int*& ip, int*& full_array, int& size) = 0; - /*! number of doamins */ - virtual int nbDomain() const = 0; - /*! number of cells */ - virtual int nbCells() const = 0; - /*! number of nodes */ - virtual int nbNodes() const = 0; - /*! number of cells on a specific domain */ - virtual int nbCells(int idomain) const = 0; - /*! converting node global numberings to local numberings */ - virtual void convertToLocal2ndVersion(int*,int,int) = 0; - virtual int convertNodeToGlobal(int ip,int icell) const = 0; - virtual int convertFaceToGlobal(int ip,int icell) const = 0; - virtual int convertCellToGlobal(int ip,int icell) const = 0; - virtual void convertNodeToGlobal(int ip,const int *local, int n, int *global) const = 0; - virtual void convertCellToGlobal(int ip,const int *local, int n, int *global) const = 0; - virtual void convertFaceToGlobal(int ip,const int *local, int n, int *global) const = 0; - /*! retrieving number of nodes */ - virtual int getNodeNumber(int idomain) const = 0; - virtual int getNodeNumber() const = 0; - /*! retrieving list of nodes */ - virtual void getNodeList(int idomain, int *list) const = 0; - virtual std::vector<int> & getFusedCellNumbers(int idomain) = 0; - virtual const std::vector<int> & getFusedCellNumbers(int idomain) const = 0; - virtual std::vector<int> & getFusedFaceNumbers(int idomain) = 0; - virtual const std::vector<int> & getFusedFaceNumbers(int idomain) const = 0; - /*! retrieving number of nodes */ - virtual int getCellNumber(int idomain) const = 0; - /*! retrieving list of nodes */ - virtual void getCellList(int idomain, int *list) const = 0; - /*! retrieving number of faces */ - virtual int getFaceNumber(int idomain) const = 0; - virtual int getFaceNumber() const = 0; - /*! retrieving list of nodes */ - virtual void getFaceList(int idomain, int *list) const = 0; - /*! adding a face to the mapping */ - virtual void appendFace(int idomain, int ilocal, int iglobal) = 0; - /*! returns max global face number */ - virtual int getMaxGlobalFace() const = 0; - /*! converting a global cell number to a local representation */ - virtual std::pair<int,int> convertGlobalCell(int iglobal) const = 0; - /*! converting a global face number to a local representation */ - virtual int convertGlobalFace(int iglobal, int idomain) = 0; - /*! converting a global node number to a local representation */ - virtual int convertGlobalNode(int iglobal, int idomain) = 0; - /*! getting a reference to connect zones vector */ - virtual std::vector<MEDPARTITIONER::ConnectZone*>& getCZ() = 0; - }; -} - -#endif diff --git a/src/MEDPartitioner/MEDPARTITIONER_UserGraph.cxx b/src/MEDPartitioner/MEDPARTITIONER_UserGraph.cxx deleted file mode 100644 index 1d0808471..000000000 --- a/src/MEDPartitioner/MEDPARTITIONER_UserGraph.cxx +++ /dev/null @@ -1,59 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// - -#include "MEDPARTITIONER_Graph.hxx" -#include "MEDPARTITIONER_UserGraph.hxx" - -#include "MEDCouplingSkyLineArray.hxx" - -#include <iostream> -#include <vector> - -using namespace MEDPARTITIONER; - -/*! constructor that allows to specify the desired partition - * \param partition as table giving the domain number for each cell - * (domain numbers range from 0 to ndomain-1 - * \param n number of cells in the mesh - */ -UserGraph::UserGraph(ParaMEDMEM::MEDCouplingSkyLineArray *array, const int *partition, int n):Graph(array,0) -{ - - std::vector<int> index(n+1),value(n); - - index[0]=0; - for (int i=0; i<n; i++) - { - index[i+1]=index[i]+1; - value[i]=partition[i]; - } - - _partition = new ParaMEDMEM::MEDCouplingSkyLineArray(index,value); - -} - -UserGraph::~UserGraph() -{ -} - -void UserGraph::partGraph(int ndomain, const std::string& options, ParaDomainSelector* sel) -{ - std::cerr << "MEDPARTITIONER::UserGraph::partGraph() should not have to be used" << std::endl; -} - diff --git a/src/MEDPartitioner/MEDPARTITIONER_UserGraph.hxx b/src/MEDPartitioner/MEDPARTITIONER_UserGraph.hxx deleted file mode 100644 index d6c5f6b5b..000000000 --- a/src/MEDPartitioner/MEDPARTITIONER_UserGraph.hxx +++ /dev/null @@ -1,38 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// - -#ifndef __MEDPARTITIONER_USERGRAPH_HXX__ -#define __MEDPARTITIONER_USERGRAPH_HXX__ - -#include "MEDPARTITIONER.hxx" -#include "MEDPARTITIONER_Graph.hxx" - -#include <string> - -namespace MEDPARTITIONER -{ - class MEDPARTITIONER_EXPORT UserGraph : public Graph - { - public: - UserGraph(ParaMEDMEM::MEDCouplingSkyLineArray*, const int*, int); - virtual ~UserGraph(); - void partGraph(int, const std::string& options=std::string(""), ParaDomainSelector *sel=0); - }; -} -#endif diff --git a/src/MEDPartitioner/MEDPARTITIONER_Utils.cxx b/src/MEDPartitioner/MEDPARTITIONER_Utils.cxx deleted file mode 100644 index 861da009d..000000000 --- a/src/MEDPartitioner/MEDPARTITIONER_Utils.cxx +++ /dev/null @@ -1,880 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// - -#include "MEDPARTITIONER_Utils.hxx" - -#include "MEDLoader.hxx" -#include "MEDLoaderBase.hxx" -#include "MEDFileUtilities.hxx" -#include "CellModel.hxx" -#include "MEDCouplingUMesh.hxx" -#include "MEDCouplingFieldDouble.hxx" -#include "InterpKernelException.hxx" -#include "MEDCouplingAutoRefCountObjectPtr.hxx" -#include "InterpKernelAutoPtr.hxx" - -#include <fstream> -#include <iostream> -#include <iomanip> -#include <sstream> -#include <string> -#include <cstring> - -using namespace MEDPARTITIONER; - -int MEDPARTITIONER::MyGlobals::_Verbose=0; -int MEDPARTITIONER::MyGlobals::_Is0verbose=0; -int MEDPARTITIONER::MyGlobals::_Rank=-1; -int MEDPARTITIONER::MyGlobals::_World_Size=-1; -int MEDPARTITIONER::MyGlobals::_Randomize=0; -int MEDPARTITIONER::MyGlobals::_Atomize=0; -int MEDPARTITIONER::MyGlobals::_Creates_Boundary_Faces=0; -int MEDPARTITIONER::MyGlobals::_Create_Joints=0; -std::vector<std::string> MEDPARTITIONER::MyGlobals::_File_Names; -std::vector<std::string> MEDPARTITIONER::MyGlobals::_Mesh_Names; -std::vector<std::string> MEDPARTITIONER::MyGlobals::_Field_Descriptions; -std::vector<std::string> MEDPARTITIONER::MyGlobals::_General_Informations; - -std::string MEDPARTITIONER::Trim(const std::string& s,const std::string& drop) -{ - std::string r(s); - r.erase(r.find_last_not_of(drop)+1); - return r.erase(0,r.find_first_not_of(drop)); -} - -std::string MEDPARTITIONER::IntToStr(const int i) -{ - std::ostringstream oss; - oss << i; - return oss.str(); -} - -std::string MEDPARTITIONER::DoubleToStr(const double i) -{ - std::ostringstream oss; - oss << i; - return oss.str(); -} - -int MEDPARTITIONER::StrToInt(const std::string& s) -{ - int res; - std::istringstream iss(s); - iss >> res; - return res; -} - -double MEDPARTITIONER::StrToDouble(const std::string& s) -{ - double res; - std::istringstream iss(s); - iss >> res; - return res; -} - -bool MEDPARTITIONER::TestArg(const char *arg, const char *argExpected, std::string& argValue) -{ - argValue=""; - std::size_t i; - for (i=0; i<strlen(arg); i++) - { - if (arg[i]=='=') - break; - if (arg[i]!=argExpected[i]) - return false; - } - for (std::size_t j=i+1; j<strlen(arg); j++) - argValue+=arg[j]; - return true; -} - -std::vector<int> MEDPARTITIONER::CreateRandomSize(const int size) -{ - std::vector<int> res(size); - for (int i=0; i<size; i++) - res[i]=i; - //cvw TODO or not? srand( (unsigned)time( NULL ) ); - srand( MyGlobals::_Randomize ); - for (int i=0; i<size; i++) - { - int ii=rand()%size; - int tmp=res[ii]; - res[ii]=res[i]; - res[i]=tmp; - } - return res; -} - -/*! - * randomize a xadj and adjncy, renumbering vertices belong rand. Works only on one processor!!!! - */ -void MEDPARTITIONER::RandomizeAdj(int* xadj, int* adjncy, std::vector<int>& ran, std::vector<int>& vx, std::vector<int>& va) -{ - if (MyGlobals::_World_Size>1) - { - std::cerr << "MEDPARTITIONER::RandomizeAdj only works on one proc!" << std::endl; - return; - } - int size=ran.size(); - std::vector<int> invran(size); - for (int i=0; i<size; i++) - invran[ran[i]]=i; - vx.resize(size+1); - int lga=xadj[size]; - va.resize(lga); - int jj=0; - vx[0]=0; - for (int i=0; i<size; i++) - { - int ir=ran[i]; - int ii=xadj[ir]; - int lgj=xadj[ir+1]-ii; - for (int j=0; j<lgj; j++) - { - va[jj]=invran[adjncy[ii]]; - jj=jj+1; - ii=ii+1; - } - vx[i+1]=jj; - } -} - -void MEDPARTITIONER::TestRandomize() -{ - //int xadj[6]={0,2,5,9,12,13}; //for first debug only - //int adjncy[13]={1,4,0,2,4,1,3,4,2,4,4,3,4}; - int xadj[6]={0,2,5,9,12,13}; - int adjncy[13]={0,0,1,1,1,2,2,2,2,3,3,3,4}; - int size=5; - std::vector<int> r=CreateRandomSize(size); - std::vector<int> vx,va; - RandomizeAdj(&xadj[0],&adjncy[0],r,vx,va); -} - -std::string MEDPARTITIONER::ReprVectorOfString(const std::vector<std::string>& vec) -{ - if (vec.size()==0) - return std::string(" NONE\n"); - std::ostringstream oss; - for (std::vector<std::string>::const_iterator i=vec.begin(); i!=vec.end(); ++i) - oss << " -> '" << *i << "'" << std::endl; - return oss.str(); -} - -std::string MEDPARTITIONER::ReprVectorOfString(const std::vector<std::string>& vec, const std::string separator) -{ - if (vec.size()==0) - return std::string(" NONE\n"); - std::ostringstream oss; - for (std::vector<std::string>::const_iterator i=vec.begin(); i!=vec.end(); ++i) - oss << separator << *i; - return oss.str(); -} - -std::string MEDPARTITIONER::ReprMapOfStringInt(const std::map<std::string,int>& mymap) -{ - if (mymap.size()==0) - return std::string(" NONE\n"); - std::ostringstream oss; - for (std::map<std::string,int>::const_iterator i=mymap.begin(); i!=mymap.end(); ++i) - oss << " -> [" << (*i).first << "]=" << (*i).second << std::endl; - return oss.str(); -} - -std::string MEDPARTITIONER::ReprMapOfStringVectorOfString(const std::map< std::string,std::vector<std::string> >& mymap) -{ - if (mymap.size()==0) - return std::string(" NONE\n"); - std::ostringstream oss; - for (std::map< std::string,std::vector<std::string> >::const_iterator i=mymap.begin(); i!=mymap.end(); ++i) - oss << " -> [" << (*i).first << "]=" << std::endl << ReprVectorOfString((*i).second) << std::endl; - return oss.str(); -} - -std::string MEDPARTITIONER::ReprFieldDescriptions(const std::vector<std::string>& vec, const std::string separator) -{ - if (vec.size()==0) - return std::string(" NONE\n"); - std::ostringstream oss; - for (std::vector<std::string>::const_iterator i=vec.begin(); i!=vec.end(); ++i) - { - oss << " ->"; - oss << ReprVectorOfString(DeserializeToVectorOfString(*i), separator) << std::endl; - } - return oss.str(); -} - -/*! - * a string "hello" gives a string " 5/hello/" - * serialized_FromVectorOfString_string+SerializeFromString("toto") is - * equivalent to vector<string>.push_back("toto") on serialized_FromVectorOfString_string - */ -std::string MEDPARTITIONER::SerializeFromString(const std::string& s) -{ - std::ostringstream oss; - oss << std::setw(5) << s.size() << "/" << s << "/"; - return oss.str(); -} - -/*! - * a vector of string gives a string - */ -std::string MEDPARTITIONER::SerializeFromVectorOfString(const std::vector<std::string>& vec) -{ - std::ostringstream oss; - for (std::vector<std::string>::const_iterator i=vec.begin(); i!=vec.end(); ++i) - oss<< std::setw(5) << (*i).size() << "/" << *i << "/"; - return oss.str(); -} - -/*! - * a string gives a vector of string - */ -std::vector<std::string> MEDPARTITIONER::DeserializeToVectorOfString(const std::string& str) -{ - std::vector<std::string> res; - std::size_t pos=0; - std::size_t posmax=str.size(); - if (posmax==0) - return res; //empty vector - std::size_t length; - while (pos < posmax-6) //setw(5)+" " - { - std::istringstream iss(str.substr(pos,5)); - iss >> length; - if ((str[pos+5]!='/') || (str[pos+6+length]!='/')) - { - std::cerr << "Error on string '" << str << "'" << std::endl;; - throw INTERP_KERNEL::Exception("Error on string"); - } - res.push_back(str.substr(pos+6,length)); - pos=pos+6+length+1; - } - return res; -} - -std::string MEDPARTITIONER::EraseTagSerialized(const std::string& fromStr, const std::string& tag) -{ - std::vector<std::string> vec=DeserializeToVectorOfString(fromStr); - std::vector<std::string> res; - for (std::size_t i=0; i<vec.size(); i++) - { - if (vec[i].find(tag)==std::string::npos) - res.push_back(vec[i]); - } - return MEDPARTITIONER::SerializeFromVectorOfString(res); -} - -/*! - * elements first and second of map give one elements in result vector of string - * converting formatted the int second as firsts characters ending at first slash - */ -std::vector<std::string> MEDPARTITIONER::VectorizeFromMapOfStringInt(const std::map<std::string,int>& mymap) -{ - std::vector<std::string> res; - for (std::map<std::string,int>::const_iterator i=mymap.begin(); i!=mymap.end(); ++i) - { - std::ostringstream oss; - oss << (*i).second << "/" << (*i).first; - res.push_back(oss.str()); - } - return res; -} - -/* - * if existing identicals (first,second) in vector no problem, else Exception - */ -std::map<std::string,int> MEDPARTITIONER::DevectorizeToMapOfStringInt(const std::vector<std::string>& vec) -{ - std::map<std::string,int> res; - for (std::vector<std::string>::const_iterator i=vec.begin(); i!=vec.end(); ++i) - { - std::size_t pos=0; - std::size_t posmax=(*i).size(); - std::size_t found=(*i).find('/'); //first slash - if ((found==std::string::npos) || (found<1)) - throw INTERP_KERNEL::Exception("Error aIntNumber/anyString is expected"); - int second; - std::istringstream iss((*i).substr(pos,found)); - iss >> second; - std::string first=(*i).substr(pos+found+1,posmax-found); - std::map<std::string,int>::iterator it=res.find(first); - if (it!=res.end()) - if ((*it).second!=second) - throw INTERP_KERNEL::Exception("Error not the same map value"); - res[first]=second; - } - return res; -} - -/*! - * elements first and second of map give one elements in result vector of string - * adding key map and length of second vector as first string in each serialized vector - * one serialized vector per key map - */ -std::vector<std::string> MEDPARTITIONER::VectorizeFromMapOfStringVectorOfString(const std::map< std::string,std::vector<std::string> >& mymap) -{ - std::vector<std::string> res; - for (std::map< std::string,std::vector<std::string> >::const_iterator i=mymap.begin(); i!=mymap.end(); ++i) - { - std::vector<std::string> vs=(*i).second; //a vector of string; - std::ostringstream oss; - oss << "Keymap/" << (*i).first << "/" << (*i).second.size(); - vs.insert(vs.begin(), oss.str()); - res.push_back(SerializeFromVectorOfString(vs)); - } - return res; -} - -/*! - * if existing identicals keymap in vector no problem - * duplicates in second vector - */ -std::map< std::string,std::vector<std::string> > MEDPARTITIONER::DevectorizeToMapOfStringVectorOfString(const std::vector<std::string>& vec) -{ - std::map< std::string,std::vector<std::string> > res; - for (std::vector<std::string>::const_iterator i=vec.begin(); i!=vec.end(); ++i) - { - std::vector<std::string> vs=DeserializeToVectorOfString(*i); - - std::string enTete=vs[0]; - std::size_t posmax=enTete.size(); - std::size_t foundKey=enTete.find("Keymap/"); - std::size_t foundSizeVector=enTete.find_last_of('/'); - if ((foundKey==std::string::npos) || (foundKey!=0) || ((foundKey+7)>=foundSizeVector)) - throw INTERP_KERNEL::Exception("Error Keymap/anyString/aIntNumber is expected"); - int sizeVector; - std::istringstream iss(enTete.substr(foundSizeVector+1,posmax-foundSizeVector)); - iss >> sizeVector; - std::string keymap=enTete.substr(foundKey+7,foundSizeVector-foundKey-7); - for (int ii=1; ii<=sizeVector; ii++) - res[keymap].push_back(vs[ii]); //add unconditionnaly,so merge duplicates in second vector - } - return res; -} - -/*! - * shit for unique and unique_copy for the duplicate CONSECUTIVE elements - * I do not want to sort - */ -std::vector<std::string> MEDPARTITIONER::SelectTagsInVectorOfString(const std::vector<std::string>& vec, const std::string tag) -{ - std::vector<std::string> res; - if (vec.size()==0) - return res; - for (std::vector<std::string>::const_iterator i=vec.begin(); i!=vec.end(); ++i) - { - if ((*i).find(tag)!=std::string::npos) res.push_back(*i); - } - return res; -} - -/*! - * - */ -std::vector<std::string> MEDPARTITIONER::DeleteDuplicatesInVectorOfString(const std::vector<std::string>& vec) -{ - std::vector<std::string> res; - if (vec.size()==0) return res; - //shit for unique and unique_copy for the duplicate CONSECUTIVE elements - //I do not want to sort - for (std::vector<std::string>::const_iterator i=vec.begin(); i!=vec.end(); ++i) - { - bool found=false; - for (std::vector<std::string>::const_iterator j=res.begin(); j!=res.end(); ++j) - { - if ((*i).compare(*j)==0) - { - found=true; - break; - } - } - if (!found) res.push_back(*i); - } - return res; -} - -std::map< std::string,std::vector<std::string> > MEDPARTITIONER::DeleteDuplicatesInMapOfStringVectorOfString(const std::map< std::string,std::vector<std::string> >& mymap) -{ - std::map< std::string,std::vector<std::string> > res; - for (std::map< std::string,std::vector<std::string> >::const_iterator i=mymap.begin(); i!=mymap.end(); ++i) - res[(*i).first]=DeleteDuplicatesInVectorOfString((*i).second); - return res; -} - -//void MEDPARTITIONER::sendRecvVectorOfString(const std::vector<string>& vec, const int source, const int target) -//TODO -std::string MEDPARTITIONER::Cle1ToStr(const std::string& s, const int inew) -{ - std::ostringstream oss; - oss << s << " " << inew; - return oss.str(); -} - -void MEDPARTITIONER::Cle1ToData(const std::string& key, std::string& s, int& inew) -{ - std::size_t posmax=key.size(); - std::size_t found=key.find(' '); - if ((found==std::string::npos) || (found<1)) - throw INTERP_KERNEL::Exception("Error 'aStringWithoutWhitespace aInt' is expected"); - s=key.substr(0,found); - std::istringstream iss(key.substr(found,posmax-found)); - iss >> inew; -} - -std::string MEDPARTITIONER::Cle2ToStr(const std::string& s, const int inew, const int iold) -{ - std::ostringstream oss; - oss << s << " " << inew << " " << iold; - return oss.str(); -} - -void MEDPARTITIONER::Cle2ToData(const std::string& key, std::string& s, int& inew, int& iold) -{ - std::size_t posmax=key.size(); - std::size_t found=key.find(' '); - if ((found==std::string::npos) || (found<1)) - throw INTERP_KERNEL::Exception("Error 'aStringWithoutWhitespace aInt aInt' is expected"); - s=key.substr(0,found); - std::istringstream iss(key.substr(found,posmax-found)); - iss >> inew >> iold; -} - -std::string MEDPARTITIONER::ExtractFromDescription(const std::string& description,const std::string& tag) -{ - std::size_t found=description.find(tag); - if ((found==std::string::npos) || (found<1)) - { - std::cerr << "ERROR : not found '" << tag << "' in '"<< description << "'\n"; - throw INTERP_KERNEL::Exception("Error ExtractFromDescription"); - } - std::size_t beg=found; - std::size_t end=beg; - if (description[found-1]!='/') - { - //find without '/'... and pray looking for first whitespace - //something like 'idomain=0 fileName=tmp.med meshName=...' - end=description.size(); - beg+=tag.length(); - std::string res=description.substr(beg,end-beg); - found=res.find(' '); - if (found==std::string::npos) - found=res.length(); - res=res.substr(0,found); - return res; - } - std::size_t lg=StrToInt(description.substr(found-6,found)); - beg+=tag.length(); - return description.substr(beg,lg-tag.length()); -} - -void MEDPARTITIONER::FieldDescriptionToData(const std::string& description, - int& idomain, std::string& fileName, std::string& meshName, std::string& fieldName, int& typeField, int& DT, int& IT) -{ - idomain=StrToInt(ExtractFromDescription(description,"idomain=")); - fileName=ExtractFromDescription(description,"fileName="); - meshName=ExtractFromDescription(description,"meshName="); - fieldName=ExtractFromDescription(description,"fieldName="); - typeField=StrToInt(ExtractFromDescription(description,"typeField=")); - DT=StrToInt(ExtractFromDescription(description,"DT=")); - IT=StrToInt(ExtractFromDescription(description,"IT=")); -} - -void MEDPARTITIONER::FieldShortDescriptionToData(const std::string& description, - std::string& fieldName, int& typeField, int& entity, int& DT, int& IT) -{ - fieldName=ExtractFromDescription(description,"fieldName="); - typeField=StrToInt(ExtractFromDescription(description,"typeField=")); - entity=StrToInt(ExtractFromDescription(description,"entity=")); - DT=StrToInt(ExtractFromDescription(description,"DT=")); - IT=StrToInt(ExtractFromDescription(description,"IT=")); -} - -ParaMEDMEM::DataArrayInt *MEDPARTITIONER::CreateDataArrayIntFromVector(const std::vector<int>& v) -{ - ParaMEDMEM::DataArrayInt* p=ParaMEDMEM::DataArrayInt::New(); - p->alloc(v.size(),1); - std::copy(v.begin(),v.end(),p->getPointer()); - return p; -} - -ParaMEDMEM::DataArrayInt *MEDPARTITIONER::CreateDataArrayIntFromVector(const std::vector<int>& v,const int nbComponents) -{ - ParaMEDMEM::DataArrayInt* p=ParaMEDMEM::DataArrayInt::New(); - if (v.size()%nbComponents!=0) - throw INTERP_KERNEL::Exception("Problem size modulo nbComponents != 0"); - p->alloc(v.size()/nbComponents,nbComponents); - std::copy(v.begin(),v.end(),p->getPointer()); - return p; -} - -ParaMEDMEM::DataArrayDouble* MEDPARTITIONER::CreateDataArrayDoubleFromVector(const std::vector<double>& v) -{ - ParaMEDMEM::DataArrayDouble* p=ParaMEDMEM::DataArrayDouble::New(); - p->alloc(v.size(),1); - std::copy(v.begin(),v.end(),p->getPointer()); - return p; -} - -/*! - */ -std::vector<std::string> MEDPARTITIONER::BrowseFieldDouble(const ParaMEDMEM::MEDCouplingFieldDouble* fd) -{ - std::vector<std::string> res; - if (fd->getArray()) - { - int nb=fd->getArray()->getNumberOfComponents(); - res.push_back("nbComponents="); res.back()+=IntToStr(nb); - for (int i=0; i<nb; i++) - { - res.push_back("componentInfo"); - res.back()+=IntToStr(i)+"="+fd->getArray()->getInfoOnComponent(i); - } - } - else - { - res.push_back("nbComponents=0"); //unknown - } - return res; -} - -/*! - * quick almost human readable information on all fields in a .med file - */ -std::vector<std::string> MEDPARTITIONER::BrowseAllFields(const std::string& myfile) -{ - std::vector<std::string> res; - std::vector<std::string> meshNames=MEDLoader::GetMeshNames(myfile); - - for (std::size_t i=0; i<meshNames.size(); i++) - { - std::vector<std::string> fieldNames= - MEDLoader::GetAllFieldNamesOnMesh(myfile,meshNames[i]); - for (std::size_t j = 0; j < fieldNames.size(); j++) - { - std::vector< ParaMEDMEM::TypeOfField > typeFields= - MEDLoader::GetTypesOfField(myfile, meshNames[i], fieldNames[j]); - for (std::size_t k = 0; k < typeFields.size(); k++) - { - std::vector< std::pair< int, int > > its= - MEDLoader::GetFieldIterations(typeFields[k], myfile, meshNames[i], fieldNames[j]); - if (MyGlobals::_Is0verbose>100) - std::cout<< "fieldName " << fieldNames[j] << " typeField " << typeFields[k] << " its.size() " << its.size() << std::endl; - for (std::size_t m = 0; m < its.size(); m++) - { - std::vector<std::string> resi; - resi.push_back("fileName="); resi.back()+=myfile; - resi.push_back("meshName="); resi.back()+=meshNames[i]; - resi.push_back("fieldName="); resi.back()+=fieldNames[j]; - resi.push_back("typeField="); resi.back()+=IntToStr((int)typeFields[k]); - resi.push_back("DT="); resi.back()+=IntToStr((int)its[m].first); - resi.push_back("IT="); resi.back()+=IntToStr((int)its[m].second); - res.push_back(SerializeFromVectorOfString(resi)); - } - } - } - } - return res; -} - -std::vector<std::string> MEDPARTITIONER::GetInfosOfField(const char *fileName, const char *meshName, const int idomain) -{ - const int lggeom=10; - const med_geometry_type GEOMTYPE[lggeom]={ //MED_N_CELL_FIXED_GEO] = { - //MED_POINT1, - //MED_SEG2, - //MED_SEG3, - //MED_SEG4, - //MED_TRIA3, - //MED_QUAD4, - //MED_TRIA6, - //MED_TRIA7, - //MED_QUAD8, - //MED_QUAD9, - MED_TETRA4, - MED_PYRA5, - MED_PENTA6, - MED_HEXA8, - MED_OCTA12, - MED_TETRA10, - MED_PYRA13, - MED_PENTA15, - MED_HEXA20, - MED_HEXA27, - //MED_POLYGON, - //MED_POLYHEDRON - }; - - const char * const GEOMTYPENAME[lggeom]={ - //"MED_POINT1", - //"MED_SEG2", - //"MED_SEG3", - //"MED_SEG4", - //"MED_TRIA3", - //"MED_QUAD4", - //"MED_TRIA6", - //"MED_TRIA7", - //"MED_QUAD8", - //"MED_QUAD9", - "MED_TETRA4", - "MED_PYRA5", - "MED_PENTA6", - "MED_HEXA8", - "MED_OCTA12", - "MED_TETRA10", - "MED_PYRA13", - "MED_PENTA15", - "MED_HEXA20", - "MED_HEXA27", - //"MED_POLYGONE", - //"MED_POLYEDRE", - }; - - - const int lgentity=3; - const med_entity_type ENTITYTYPE[lgentity]={ //MED_N_ENTITY_TYPES+2]={ - //MED_UNDEF_ENTITY_TYPE, - MED_CELL, - //MED_DESCENDING_FACE, - //MED_DESCENDING_EDGE, - MED_NODE, - MED_NODE_ELEMENT, - //MED_STRUCT_ELEMENT, - //MED_UNDEF_ENTITY_TYPE - }; - - const char * const ENTITYTYPENAME[lgentity]={ //MED_N_ENTITY_TYPES+2]={ - //"MED_UNDEF_ENTITY_TYPE", - "MED_CELL", - //"MED_FACE", - //"MED_ARETE", - "MED_NODE", - "MED_NODE_ELEMENT", - //"MED_STRUCT_ELEMENT", - //"MED_UNDEF_ENTITY_TYPE" - }; - - std::vector<std::string> res; - med_idt fid=MEDfileOpen(fileName,MED_ACC_RDONLY); - med_int nbFields=MEDnField(fid); - if (MyGlobals::_Verbose>20) - std::cout << "on filename " << fileName << " nbOfField " << nbFields << std::endl; - // - med_field_type typcha; - med_int numdt=0,numo=0; - med_float dt=0.0; - char *maa_ass=MEDLoaderBase::buildEmptyString(MED_NAME_SIZE); - char *nomcha=MEDLoaderBase::buildEmptyString(MED_NAME_SIZE); - med_bool localmesh; - // - for(int i=1; i<=nbFields; i++) - { - med_int ncomp=MEDfieldnComponent(fid,i); - INTERP_KERNEL::AutoPtr<char> comp=new char[ncomp*MED_SNAME_SIZE+1]; - INTERP_KERNEL::AutoPtr<char> unit=new char[ncomp*MED_SNAME_SIZE+1]; - INTERP_KERNEL::AutoPtr<char> dt_unit=new char[MED_LNAME_SIZE+1]; - med_int nbPdt; - MEDfieldInfo(fid,i,nomcha,maa_ass,&localmesh,&typcha,comp,unit,dt_unit,&nbPdt); - std::string curFieldName=MEDLoaderBase::buildStringFromFortran(nomcha,MED_NAME_SIZE+1); - std::string curMeshName=MEDLoaderBase::buildStringFromFortran(maa_ass,MED_NAME_SIZE+1); - for (int k=1; k<=nbPdt; k++) - { - MEDfieldComputingStepInfo(fid,nomcha,k,&numdt,&numo,&dt); - if (MyGlobals::_Verbose>20) - std::cout<< "on filename " << fileName << " field " << i << " fieldName " << curFieldName << " meshName " << curMeshName << - " typ " << typcha << " nbComponent " << ncomp << " nbPdt " << nbPdt << " noPdt " << k << - " ndt " << numdt << " nor " << numo << " dt " << dt << std::endl; - for (int ie=0; ie<lgentity; ie++) - { - for (int j=0; j<lggeom; j++) - { - int profilesize=0,nbi=0; - med_entity_type enttype=ENTITYTYPE[ie]; - //enttype=MED_NODE;enttype=MED_CELL;enttype=MED_NODE_ELEMENT; - char pflname[MED_NAME_SIZE+1]=""; - char locname[MED_NAME_SIZE+1]=""; - med_int nbofprofile=MEDfieldnProfile(fid,nomcha,numdt,numo,enttype,GEOMTYPE[j],pflname,locname); - int profileit=1; - if (enttype==MED_NODE) - { - med_geometry_type mygeomtype=MED_UNDEF_ENTITY_TYPE; - med_int nbOfVal=MEDfieldnValueWithProfile(fid,nomcha,numdt,numo,enttype,mygeomtype,profileit, - MED_COMPACT_PFLMODE,pflname,&profilesize,locname,&nbi); - if (nbOfVal>0) - { - if (MyGlobals::_Verbose>20) - std::cout << "on filename " << fileName << " entity " << enttype << " nbOfVal with " << - nbofprofile << " profile(s) for geomType (AUCUN) nbOfVal " << - nbOfVal << " profilName '" << pflname << "' profileSize " << profilesize << " nbPtGauss " << nbi << std::endl; - std::vector<std::string> resi; - resi.push_back("idomain="); resi.back()+=IntToStr(idomain); - resi.push_back("fileName="); resi.back()+=fileName; - resi.push_back("meshName="); resi.back()+=curMeshName; - resi.push_back("fieldName="); resi.back()+=curFieldName; - resi.push_back("typeField="); resi.back()+=IntToStr((int)ParaMEDMEM::ON_NODES); - resi.push_back("typeData="); resi.back()+=IntToStr((int)typcha); //6 for double? - resi.push_back("nbComponent="); resi.back()+=IntToStr((int)ncomp); - resi.push_back("DT="); resi.back()+=IntToStr((int)numdt); - resi.push_back("IT="); resi.back()+=IntToStr((int)numo); - resi.push_back("time="); resi.back()+=DoubleToStr(dt); - resi.push_back("entity="); resi.back()+=IntToStr((int)enttype); - resi.push_back("entityName="); resi.back()+=ENTITYTYPENAME[ie]; - resi.push_back("nbOfVal="); resi.back()+=IntToStr((int)nbOfVal); - resi.push_back("profilName="); resi.back()+=pflname; - resi.push_back("profileSize="); resi.back()+=IntToStr((int)profilesize); - resi.push_back("nbPtGauss="); resi.back()+=IntToStr((int)nbi); - res.push_back(SerializeFromVectorOfString(resi)); - } - break; //on nodes no need to scute all geomtype - } - else - { - med_geometry_type mygeomtype=GEOMTYPE[j]; - med_int nbOfVal=MEDfieldnValueWithProfile(fid,nomcha,numdt,numo,enttype,mygeomtype,profileit, - MED_COMPACT_PFLMODE,pflname,&profilesize,locname,&nbi); - if (nbOfVal>0) - { - if (MyGlobals::_Verbose>20) - std::cout << "on filename " << fileName << " entity " << enttype << " nbOfVal with " << - nbofprofile << " profile(s) for geomType " << - GEOMTYPE[j] << " " << GEOMTYPENAME[j] << " nbOfVal " << - nbOfVal << " profilName '" << pflname << "' profileSize " << profilesize << " nbPtGauss " << nbi << std::endl; - int typeField=-1; //unknown - if (enttype==MED_CELL) - typeField=ParaMEDMEM::ON_CELLS; - if (enttype==MED_NODE_ELEMENT) - typeField=ParaMEDMEM::ON_GAUSS_NE; - //if (enttype==??) typeField=ON_GAUSS_PT; - std::vector<std::string> resi; - resi.push_back("idomain="); resi.back()+=IntToStr(idomain); - resi.push_back("fileName="); resi.back()+=fileName; - resi.push_back("meshName="); resi.back()+=curMeshName; - resi.push_back("fieldName="); resi.back()+=curFieldName; - resi.push_back("typeField="); resi.back()+=IntToStr((int)typeField); - resi.push_back("typeData="); resi.back()+=IntToStr((int)typcha); //6 for double? - resi.push_back("nbComponent="); resi.back()+=IntToStr((int)ncomp); - resi.push_back("DT="); resi.back()+=IntToStr((int)numdt); - resi.push_back("IT="); resi.back()+=IntToStr((int)numo); - resi.push_back("time="); resi.back()+=DoubleToStr(dt); - resi.push_back("entity="); resi.back()+=IntToStr((int)enttype); - resi.push_back("entityName="); resi.back()+=ENTITYTYPENAME[ie]; - resi.push_back("geomType="); resi.back()+=IntToStr((int)GEOMTYPE[j]); - resi.push_back("geomTypeName="); resi.back()+=GEOMTYPENAME[j]; - resi.push_back("nbOfVal="); resi.back()+=IntToStr((int)nbOfVal); - resi.push_back("profilName="); resi.back()+=pflname; - resi.push_back("profileSize="); resi.back()+=IntToStr((int)profilesize); - resi.push_back("nbPtGauss="); resi.back()+=IntToStr((int)nbi); - if (typeField==(-1)) - { - std::cout << "WARNING : unknown typeField for entity type " << enttype << std::endl << - SerializeFromVectorOfString(resi) << std::endl; - continue; //do not register push_back - } - res.push_back(SerializeFromVectorOfString(resi)); - } - } - } - } - } - } - delete [] maa_ass; - delete [] nomcha; - MEDfileClose(fid); - if (MyGlobals::_Verbose>10) - std::cout << "detected fields:\n" << ReprVectorOfString(res) << std::endl; - return res; -} - -/*! - * quick almost human readable information on all fields on a mesh in a .med file - */ -std::vector<std::string> MEDPARTITIONER::BrowseAllFieldsOnMesh(const std::string& myfile, const std::string& mymesh, const int idomain) -{ - std::vector<std::string> res=GetInfosOfField(myfile.c_str(),mymesh.c_str(),idomain); - return res; -} - -/*! - * create empty MEDCouplingUMesh* dim 3 - */ -ParaMEDMEM::MEDCouplingUMesh* MEDPARTITIONER::CreateEmptyMEDCouplingUMesh() -{ - ParaMEDMEM::MEDCouplingUMesh* umesh=ParaMEDMEM::MEDCouplingUMesh::New(); - umesh->setMeshDimension(3); - umesh->allocateCells(0); - umesh->finishInsertingCells(); - ParaMEDMEM::DataArrayDouble *myCoords=ParaMEDMEM::DataArrayDouble::New(); - myCoords->alloc(0,3); - umesh->setCoords(myCoords); - umesh->setName("EMPTY"); - myCoords->decrRef(); - umesh->checkCoherency(); - return umesh; -} - -namespace MEDPARTITIONER -{ - BBTreeOfDim::BBTreeOfDim( int dim, - const double* bbs, - int* elems, - int level, - int nbelems, - double epsilon) - { - switch ( dim ) - { - case 3: - _tree=new BBTree<3> (bbs,elems,level,nbelems,epsilon); - _PgetElementsAroundPoint = & BBTreeOfDim::_getElementsAroundPoint< 3 >; - _PgetIntersectingElems = & BBTreeOfDim::_getIntersectingElems< 3 >; - break; - case 2: - _tree=new BBTree<2> (bbs,elems,level,nbelems,epsilon); - _PgetElementsAroundPoint = & BBTreeOfDim::_getElementsAroundPoint< 2 >; - _PgetIntersectingElems = & BBTreeOfDim::_getIntersectingElems< 2 >; - break; - case 1: - _tree=new BBTree<1> (bbs,elems,level,nbelems,epsilon); - _PgetElementsAroundPoint = & BBTreeOfDim::_getElementsAroundPoint< 1 >; - _PgetIntersectingElems = & BBTreeOfDim::_getIntersectingElems< 1 >; - break; - default: - _tree=0; - throw INTERP_KERNEL::Exception("BBTreeOfDim(): wrong space dimension"); - } - } - - BBTreeOfDim::~BBTreeOfDim() - { - delete (BBTree<3>*)_tree; - } - - void BBTreeOfDim::getElementsAroundPoint( const double* coordsPtr, - std::vector<int>& elems ) const - { - BBTreeOfDim* me = (BBTreeOfDim*) this; - (me->*_PgetElementsAroundPoint) ( coordsPtr, elems ); - } - void BBTreeOfDim::getIntersectingElems(const double* bb, - std::vector<int>& elems) const - { - BBTreeOfDim* me = (BBTreeOfDim*) this; - (me->*_PgetIntersectingElems) ( bb, elems ); - } -} diff --git a/src/MEDPartitioner/MEDPARTITIONER_Utils.hxx b/src/MEDPartitioner/MEDPARTITIONER_Utils.hxx deleted file mode 100644 index 64fc0c2b9..000000000 --- a/src/MEDPartitioner/MEDPARTITIONER_Utils.hxx +++ /dev/null @@ -1,178 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// - -#ifndef __MEDPARTITIONER_UTILS_HXX__ -#define __MEDPARTITIONER_UTILS_HXX__ - -#include "MEDPARTITIONER.hxx" - -#include "MEDCouplingUMesh.hxx" -#include "BBTree.txx" - -#include <string> -#include <vector> -#include <map> - -//# define LOCALIZED(message) #message , __FILE__ , __FUNCTION__ , __LINE__ - -namespace MEDPARTITIONER -{ - MEDPARTITIONER_EXPORT std::string Trim(const std::string& s,const std::string& drop); - MEDPARTITIONER_EXPORT std::string IntToStr(const int i); - MEDPARTITIONER_EXPORT std::string DoubleToStr(const double i); - MEDPARTITIONER_EXPORT int StrToInt(const std::string& s); - MEDPARTITIONER_EXPORT double StrToDouble(const std::string& s); - MEDPARTITIONER_EXPORT bool TestArg(const char *arg, const char *argExpected, std::string& argValue); - MEDPARTITIONER_EXPORT std::vector<int> CreateRandomSize(const int size); - MEDPARTITIONER_EXPORT void RandomizeAdj(int* xadj, int* adjncy, std::vector<int>& ran, std::vector<int>& vx, std::vector<int>& va); - MEDPARTITIONER_EXPORT void TestRandomize(); - - MEDPARTITIONER_EXPORT std::string ReprVectorOfString(const std::vector<std::string>& vec); - MEDPARTITIONER_EXPORT std::string ReprVectorOfString(const std::vector<std::string>& vec, const std::string separator); - MEDPARTITIONER_EXPORT std::string ReprMapOfStringInt(const std::map<std::string,int>& mymap); - MEDPARTITIONER_EXPORT std::string ReprMapOfStringVectorOfString(const std::map< std::string,std::vector<std::string> >& mymap); - MEDPARTITIONER_EXPORT std::string ReprFieldDescriptions(const std::vector<std::string>& vec,const std::string separator); - - MEDPARTITIONER_EXPORT std::string SerializeFromString(const std::string& s); - MEDPARTITIONER_EXPORT std::string SerializeFromVectorOfString(const std::vector<std::string>& vec); - MEDPARTITIONER_EXPORT std::vector<std::string> DeserializeToVectorOfString(const std::string& str); - MEDPARTITIONER_EXPORT std::string EraseTagSerialized(const std::string& fromStr, const std::string& tag); - - MEDPARTITIONER_EXPORT std::vector<std::string> VectorizeFromMapOfStringInt(const std::map<std::string,int>& mymap); - MEDPARTITIONER_EXPORT std::map<std::string,int> DevectorizeToMapOfStringInt(const std::vector<std::string>& vec); - - MEDPARTITIONER_EXPORT std::vector<std::string> VectorizeFromMapOfStringVectorOfString(const std::map< std::string,std::vector<std::string> >& mymap); - MEDPARTITIONER_EXPORT std::map< std::string,std::vector<std::string> > DevectorizeToMapOfStringVectorOfString(const std::vector<std::string>& vec); - - MEDPARTITIONER_EXPORT std::vector<std::string> SelectTagsInVectorOfString(const std::vector<std::string>& vec, const std::string tag); - MEDPARTITIONER_EXPORT std::vector<std::string> DeleteDuplicatesInVectorOfString(const std::vector<std::string>& vec); - MEDPARTITIONER_EXPORT std::map< std::string,std::vector<std::string> > DeleteDuplicatesInMapOfStringVectorOfString(const std::map< std::string,std::vector<std::string> >& mymap); - - MEDPARTITIONER_EXPORT std::string Cle1ToStr(const std::string& s, const int inew); - MEDPARTITIONER_EXPORT void Cle1ToData(const std::string& cle, std::string& s, int& inew); - - MEDPARTITIONER_EXPORT std::string Cle2ToStr(const std::string& s,const int inew,const int iold); - MEDPARTITIONER_EXPORT void Cle2ToData(const std::string& cle, std::string& s, int& inew, int& iold); - - MEDPARTITIONER_EXPORT std::string ExtractFromDescription(const std::string& description,const std::string& tag); - MEDPARTITIONER_EXPORT void FieldDescriptionToData(const std::string& description, - int& idomain, std::string& fileName, std::string& meshName, std::string& fieldName, - int& typeField, int& DT, int& IT); - MEDPARTITIONER_EXPORT void FieldShortDescriptionToData(const std::string& description, - std::string& fieldName, int& typeField, int& entity, int& DT, int& IT); - - ParaMEDMEM::DataArrayInt *CreateDataArrayIntFromVector(const std::vector<int>& v); - ParaMEDMEM::DataArrayInt *CreateDataArrayIntFromVector(const std::vector<int>& v, const int nbComponents); - ParaMEDMEM::DataArrayDouble *CreateDataArrayDoubleFromVector(const std::vector<double>& v); - - ParaMEDMEM::MEDCouplingUMesh *CreateEmptyMEDCouplingUMesh(); - - std::vector<std::string> BrowseFieldDouble(const ParaMEDMEM::MEDCouplingFieldDouble* fd); - std::vector<std::string> BrowseAllFields(const std::string& myfile); - std::vector<std::string> BrowseAllFieldsOnMesh(const std::string& myfile, const std::string& mymesh, const int idomain); - std::vector<std::string> GetInfosOfField(const char *fileName, const char *meshName, const int idomain ); - -#ifdef HAVE_MPI - //not adviced, interblocking, use sendAndReceive - //void SendVectorOfString(const std::vector<std::string>& vec, const int target); - //std::vector<std::string> RecvVectorOfString(const int source); - //TODO void sendRecvVectorOfString(const std::vector<std::string>& vec, const int source, const int target); - MEDPARTITIONER_EXPORT std::vector<std::string> SendAndReceiveVectorOfString(const std::vector<std::string>& vec, const int source, const int target); - MEDPARTITIONER_EXPORT std::vector<std::string> AllgathervVectorOfString(const std::vector<std::string>& vec); - - void SendDoubleVec(const std::vector<double>& vec, const int target); - std::vector<double> *RecvDoubleVec(const int source); - void RecvDoubleVec(std::vector<double>& vec, const int source); - - void SendIntVec(const std::vector<int>& vec, const int target); - std::vector<int>* RecvIntVec(int source); - void RecvIntVec(std::vector<int>& vec, const int source); - - void SendDataArrayInt(const ParaMEDMEM::DataArrayInt* da, const int target); - ParaMEDMEM::DataArrayInt *RecvDataArrayInt(const int source); - void SendDataArrayDouble(const ParaMEDMEM::DataArrayDouble* da, const int target); - ParaMEDMEM::DataArrayDouble *RecvDataArrayDouble(const int source); - - void TestVectorOfStringMpi(); - void TestMapOfStringIntMpi(); - void TestMapOfStringVectorOfStringMpi(); - void TestDataArrayMpi(); - void TestPersistantMpi0To1(int taille, int nb); - void TestPersistantMpiRing(int taille, int nb); - void TestPersistantMpiRingOnCommSplit(int taille, int nb); -#endif - - class MEDPARTITIONER_EXPORT MyGlobals - { - public : - static int _Verbose; //0 to 1000 over 200 is debug - static int _Rank; - static int _World_Size; - static int _Randomize; - static int _Atomize; - static int _Creates_Boundary_Faces; - static int _Create_Joints; - static int _Is0verbose; //trace cout if rank 0 and verbose - static std::vector<std::string> _File_Names; //on [iold] - static std::vector<std::string> _Mesh_Names; //on [iold] - static std::vector<std::string> _Field_Descriptions; - /*! used for descriptions of components of fields for example...*/ - static std::vector<std::string> _General_Informations; - }; - - - - /*! - * \brief Class encapsulating BBTree of dimension given at construction and - * providing all features of BBTree - */ - class BBTreeOfDim - { - void * _tree; - void (BBTreeOfDim::*_PgetElementsAroundPoint)( const double* coordsPtr, - std::vector<int>& elems ) const; - void (BBTreeOfDim::*_PgetIntersectingElems)( const double* bb, - std::vector<int>& elems ) const; - - template< int dim> - void _getElementsAroundPoint( const double* coordsPtr, - std::vector<int>& elems ) const - { - ((BBTree<dim,int>*)_tree)->getElementsAroundPoint( coordsPtr, elems ); - } - template< int dim> - void _getIntersectingElems(const double* bb, - std::vector<int>& elems) const - { - ((BBTree<dim,int>*)_tree)->getIntersectingElems( bb, elems ); - } - public: - - BBTreeOfDim( int dim, - const double* bbs, - int* elems, - int level, - int nbelems, - double epsilon=1e-12); - ~BBTreeOfDim(); - void getElementsAroundPoint(const double* coordsPtr, std::vector<int>& elems ) const; - void getIntersectingElems (const double* bb, std::vector<int>& elems) const; - }; -} -#endif diff --git a/src/MEDPartitioner/MEDPARTITIONER_UtilsPara.cxx b/src/MEDPartitioner/MEDPARTITIONER_UtilsPara.cxx deleted file mode 100644 index 12b5d6cf5..000000000 --- a/src/MEDPartitioner/MEDPARTITIONER_UtilsPara.cxx +++ /dev/null @@ -1,732 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// - -#include "MEDPARTITIONER_Utils.hxx" - -#include "MEDLoader.hxx" -#include "MEDLoaderBase.hxx" -#include "MEDFileUtilities.hxx" -#include "CellModel.hxx" -#include "MEDCouplingUMesh.hxx" -#include "MEDCouplingFieldDouble.hxx" -#include "InterpKernelException.hxx" -#include "MEDCouplingAutoRefCountObjectPtr.hxx" -#include "InterpKernelAutoPtr.hxx" - -#include <fstream> -#include <iostream> -#include <iomanip> -#include <sstream> -#include <string> - -#ifdef HAVE_MPI -#include <mpi.h> -#endif - -using namespace MEDPARTITIONER; - -/*! - * not optimized but suffisant - * return empty vector if i am not target - */ -std::vector<std::string> MEDPARTITIONER::SendAndReceiveVectorOfString(const std::vector<std::string>& vec, const int source, const int target) -{ - int rank=MyGlobals::_Rank; - - MPI_Status status; - int tag = 111001; - if (rank == source) - { - std::string str=SerializeFromVectorOfString(vec); - int size=str.length(); - MPI_Send( &size, 1, MPI_INT, target, tag, MPI_COMM_WORLD ); - MPI_Send( (void*)str.data(), str.length(), MPI_CHAR, target, tag+100, MPI_COMM_WORLD ); - } - - int recSize=0; - if (rank == target) - { - MPI_Recv(&recSize, 1, MPI_INT, source, tag, MPI_COMM_WORLD, &status); - std::string recData(recSize,'x'); - MPI_Recv((void*)recData.data(), recSize, MPI_CHAR, source, tag+100, MPI_COMM_WORLD, &status); - return DeserializeToVectorOfString(recData); //not empty one for target proc - } - std::vector<std::string> res; - return res; //empty one for other proc -} - -/*! - * strings NO need all same size!!!! - */ -std::vector<std::string> MEDPARTITIONER::AllgathervVectorOfString(const std::vector<std::string>& vec) -{ - if (MyGlobals::_World_Size==1) //nothing to do - return vec; - - int world_size=MyGlobals::_World_Size; - std::string str=SerializeFromVectorOfString(vec); - - std::vector<int> indexes(world_size); - int size=str.length(); - MPI_Allgather(&size, 1, MPI_INT, - &indexes[0], 1, MPI_INT, MPI_COMM_WORLD); - - //calcul of displacement - std::vector< int > disp(1,0); - for (int i=0; i<world_size; i++) disp.push_back( disp.back() + indexes[i] ); - - std::string recData(disp.back(),'x'); - MPI_Allgatherv((void*)str.data(), str.length(), MPI_CHAR, - (void*)recData.data(), &indexes[0], &disp[0], MPI_CHAR, - MPI_COMM_WORLD); - - //really extraordinary verbose for debug - std::vector<std::string> deserial=DeserializeToVectorOfString(recData); - if (MyGlobals::_Verbose>1000) - { - std::cout << "proc "<<MyGlobals::_Rank<<" : receive '" << recData << "'" << std::endl; - std::cout << "deserialize is : a vector of size " << deserial.size() << std::endl; - std::cout << ReprVectorOfString(deserial) << std::endl; - } - return deserial; -} - -/*! - Sends content of \a vec to processor \a target. To be used with \a RecvDoubleVec method. - \param vec vector to be sent - \param target processor id of the target -*/ -void MEDPARTITIONER::SendDoubleVec(const std::vector<double>& vec, const int target) -{ - int tag = 111002; - int size=vec.size(); - if (MyGlobals::_Verbose>1000) - std::cout << "proc " << MyGlobals::_Rank << " : --> SendDoubleVec " << size << std::endl; -#ifdef HAVE_MPI - MPI_Send(&size, 1, MPI_INT, target, tag, MPI_COMM_WORLD); - MPI_Send(const_cast<double*>(&vec[0]), size, MPI_DOUBLE, target, tag+100, MPI_COMM_WORLD); -#endif -} - -/*! Receives messages from proc \a source to fill vector<int> vec. - To be used with \a SendDoubleVec method. - - \param vec vector that is filled - \param source processor id of the incoming messages -*/ -std::vector<double>* MEDPARTITIONER::RecvDoubleVec(const int source) -{ - int tag = 111002; - int size; -#ifdef HAVE_MPI - MPI_Status status; - MPI_Recv(&size, 1, MPI_INT, source, tag, MPI_COMM_WORLD, &status); - if (MyGlobals::_Verbose>1000) - std::cout << "proc " << MyGlobals::_Rank << " : <-- RecvDoubleVec " << size << std::endl; - std::vector<double>* vec=new std::vector<double>; - vec->resize(size); - MPI_Recv(&vec[0], size, MPI_DOUBLE, source, tag+100, MPI_COMM_WORLD, &status); -#endif - return vec; -} - -void MEDPARTITIONER::RecvDoubleVec(std::vector<double>& vec, const int source) -{ - int tag = 111002; - int size; -#ifdef HAVE_MPI - MPI_Status status; - MPI_Recv(&size, 1, MPI_INT, source, tag, MPI_COMM_WORLD, &status); - if (MyGlobals::_Verbose>1000) - std::cout<< "proc " << MyGlobals::_Rank << " : <-- RecvDoubleVec " << size << std::endl;; - vec.resize(size); - MPI_Recv(&vec[0], size, MPI_DOUBLE, source, tag+100, MPI_COMM_WORLD, &status); -#endif -} -/*! - Sends content of \a vec to processor \a target. To be used with \a RecvIntVec method. - \param vec vector to be sent - \param target processor id of the target -*/ -void MEDPARTITIONER::SendIntVec(const std::vector<int>& vec, const int target) -{ - int tag = 111003; - int size=vec.size(); - if (MyGlobals::_Verbose>1000) - std::cout << "proc " << MyGlobals::_Rank << " : --> SendIntVec " << size << std::endl; -#ifdef HAVE_MPI - MPI_Send(&size, 1, MPI_INT, target, tag, MPI_COMM_WORLD); - MPI_Send(const_cast<int*>(&vec[0]), size,MPI_INT, target, tag+100, MPI_COMM_WORLD); -#endif -} - -/*! Receives messages from proc \a source to fill vector<int> vec. - To be used with \a SendIntVec method. - \param vec vector that is filled - \param source processor id of the incoming messages -*/ -std::vector<int> *MEDPARTITIONER::RecvIntVec(const int source) -{ - int tag = 111003; - int size; -#ifdef HAVE_MPI - MPI_Status status; - MPI_Recv(&size, 1, MPI_INT, source, tag, MPI_COMM_WORLD, &status); - if (MyGlobals::_Verbose>1000) - std::cout << "proc " << MyGlobals::_Rank << " : <-- RecvIntVec " << size << std::endl; - std::vector<int> *vec=new std::vector<int>; - vec->resize(size); - MPI_Recv(&vec[0], size, MPI_INT, source, tag+100, MPI_COMM_WORLD, &status); -#endif - return vec; -} - -void MEDPARTITIONER::RecvIntVec(std::vector<int>& vec, const int source) -{ - int tag = 111003; - int size; -#ifdef HAVE_MPI - MPI_Status status; - MPI_Recv(&size, 1, MPI_INT, source, tag, MPI_COMM_WORLD, &status); - if (MyGlobals::_Verbose>1000) - std::cout << "proc " << MyGlobals::_Rank << " : <-- RecvIntVec " << size << std::endl; - vec.resize(size); - MPI_Recv(&vec[0], size, MPI_INT, source, tag+100, MPI_COMM_WORLD,&status); -#endif -} - -/*! - Sends content of \a dataArrayInt to processor \a target. - To be used with \a RecvDataArrayInt method. - \param da dataArray to be sent - \param target processor id of the target -*/ -void MEDPARTITIONER::SendDataArrayInt(const ParaMEDMEM::DataArrayInt *da, const int target) -{ - if (da==0) - throw INTERP_KERNEL::Exception("Problem send DataArrayInt* NULL"); - int tag = 111004; - int size[3]; - size[0]=da->getNbOfElems(); - size[1]=da->getNumberOfTuples(); - size[2]=da->getNumberOfComponents(); - if (MyGlobals::_Verbose>1000) - std::cout << "proc " << MyGlobals::_Rank << " : --> SendDataArrayInt " << size[0] << std::endl; -#ifdef HAVE_MPI - MPI_Send(&size, 3, MPI_INT, target, tag, MPI_COMM_WORLD); - const int *p=da->getConstPointer(); - MPI_Send(const_cast<int*>(&p[0]), size[0] ,MPI_INT, target, tag+100, MPI_COMM_WORLD); -#endif -} - -/*! Receives messages from proc \a source to fill dataArrayInt da. - To be used with \a SendIntVec method. - \param da dataArrayInt that is filled - \param source processor id of the incoming messages -*/ -ParaMEDMEM::DataArrayInt *MEDPARTITIONER::RecvDataArrayInt(const int source) -{ - int tag = 111004; - int size[3]; -#ifdef HAVE_MPI - MPI_Status status; - MPI_Recv(size, 3, MPI_INT, source, tag, MPI_COMM_WORLD, &status); - if (MyGlobals::_Verbose>1000) - std::cout << "proc " << MyGlobals::_Rank << " : <-- RecvDataArrayInt " << size[0] << std::endl; - if (size[0]!=(size[1]*size[2])) - throw INTERP_KERNEL::Exception("Problem in RecvDataArrayInt incoherent sizes"); - ParaMEDMEM::DataArrayInt* da=ParaMEDMEM::DataArrayInt::New(); - da->alloc(size[1],size[2]); - int *p=da->getPointer(); - MPI_Recv(const_cast<int*>(&p[0]), size[0], MPI_INT, source, tag+100, MPI_COMM_WORLD, &status); -#endif - return da; -} - -/*! - Sends content of \a dataArrayInt to processor \a target. - To be used with \a RecvDataArrayDouble method. - \param da dataArray to be sent - \param target processor id of the target -*/ -void MEDPARTITIONER::SendDataArrayDouble(const ParaMEDMEM::DataArrayDouble *da, const int target) -{ - if (da==0) - throw INTERP_KERNEL::Exception("Problem send DataArrayDouble* NULL"); - int tag = 111005; - int size[3]; - size[0]=da->getNbOfElems(); - size[1]=da->getNumberOfTuples(); - size[2]=da->getNumberOfComponents(); - if (MyGlobals::_Verbose>1000) - std::cout << "proc " << MyGlobals::_Rank << " : --> SendDataArrayDouble " << size[0] << std::endl; -#ifdef HAVE_MPI - MPI_Send(&size, 3, MPI_INT, target, tag, MPI_COMM_WORLD); - const double *p=da->getConstPointer(); - MPI_Send(const_cast<double*>(&p[0]), size[0] ,MPI_DOUBLE, target, tag+100, MPI_COMM_WORLD); -#endif -} - -/*! Receives messages from proc \a source to fill dataArrayDouble da. - To be used with \a SendDoubleVec method. - \param da dataArrayDouble that is filled - \param source processor id of the incoming messages -*/ -ParaMEDMEM::DataArrayDouble* MEDPARTITIONER::RecvDataArrayDouble(const int source) -{ - int tag = 111005; - int size[3]; -#ifdef HAVE_MPI - MPI_Status status; - MPI_Recv(size, 3, MPI_INT, source, tag, MPI_COMM_WORLD, &status); - if (MyGlobals::_Verbose>1000) - std::cout << "proc " << MyGlobals::_Rank << " : <-- RecvDataArrayDouble " << size[0] << std::endl; - if (size[0]!=(size[1]*size[2])) - throw INTERP_KERNEL::Exception("Problem in RecvDataArrayDouble incoherent sizes"); - ParaMEDMEM::DataArrayDouble* da=ParaMEDMEM::DataArrayDouble::New(); - da->alloc(size[1],size[2]); - double *p=da->getPointer(); - MPI_Recv(const_cast<double*>(&p[0]), size[0], MPI_DOUBLE, source, tag+100, MPI_COMM_WORLD, &status); -#endif - return da; -} - -void MEDPARTITIONER::TestVectorOfStringMpi() -{ - int rank=MyGlobals::_Rank; - int world_size=MyGlobals::_World_Size; - std::vector<std::string> myVector; - std::ostringstream oss; - oss << "hello from " << std::setw(5) << rank << " " << std::string(rank+1,'n') << - " next is an empty one"; - myVector.push_back(oss.str()); - myVector.push_back(""); - myVector.push_back("next is an singleton"); - myVector.push_back("1"); - - if (rank==0) - { - std::string s0=SerializeFromVectorOfString(myVector); - std::vector<std::string> res=DeserializeToVectorOfString(s0); - if (res.size()!=myVector.size()) - throw INTERP_KERNEL::Exception("Problem in (de)serialise VectorOfString incoherent sizes"); - for (std::size_t i=0; i<myVector.size(); i++) - if (res[i]!=myVector[i]) - throw INTERP_KERNEL::Exception("Problem in (de)serialise VectorOfString incoherent elements"); - } - - for (int i=0; i<world_size; i++) - { - for (int j=0; j<world_size; j++) - { - std::vector<std::string> res=SendAndReceiveVectorOfString(myVector, i, j); - if ((rank==j) && MyGlobals::_Verbose>20) - std::cout << "proc " << rank << " : receive \n" << ReprVectorOfString(res) << std::endl; - if (rank==j) - { - if (res.size()!=myVector.size()) - throw INTERP_KERNEL::Exception("Problem in SendAndReceiveVectorOfString incoherent sizes"); - for (std::size_t ii=1; ii<myVector.size(); ii++) //first is different - if (res[i]!=myVector[ii]) - throw INTERP_KERNEL::Exception("Problem in SendAndReceiveVectorOfString incoherent elements"); - } - else - { - if (res.size()!=0) - throw INTERP_KERNEL::Exception("Problem in SendAndReceiveVectorOfString size have to be 0"); - } - } - } - std::vector<std::string> res=AllgathervVectorOfString(myVector); - //sometimes for test - res=AllgathervVectorOfString(myVector); - res=AllgathervVectorOfString(myVector); - if (rank==0 && MyGlobals::_Verbose>20) - std::cout << "proc " << rank << " : receive \n" << ReprVectorOfString(res) << std::endl; - if (res.size()!=myVector.size()*world_size) - throw INTERP_KERNEL::Exception("Problem in AllgathervVectorOfString incoherent sizes"); - int jj=-1; - for (int j=0; j<world_size; j++) - { - for (int i=0; i<(int)myVector.size(); i++) - { - jj=jj+1; - if (i==0) - continue; //first is different - if (res[jj]!=myVector[i]) - throw INTERP_KERNEL::Exception("Problem in AllgathervVectorOfString incoherent elements"); - } - } - if (MyGlobals::_Verbose) - std::cout << "proc " << rank << " : OK TestVectorOfStringMpi END" << std::endl; -} - -void MEDPARTITIONER::TestMapOfStringIntMpi() -{ - int rank=MyGlobals::_Rank; - std::map<std::string,int> myMap; - myMap["one"]=1; - myMap["two"]=22; //a bug - myMap["three"]=3; - myMap["two"]=2; //last speaking override - - if (rank==0) - { - std::vector<std::string> v2=VectorizeFromMapOfStringInt(myMap); - std::map<std::string,int> m3=DevectorizeToMapOfStringInt(v2); - if (ReprMapOfStringInt(m3)!=ReprMapOfStringInt(myMap)) - throw INTERP_KERNEL::Exception("Problem in (de)vectorize MapOfStringInt"); - } - - std::vector<std::string> v2=AllgathervVectorOfString(VectorizeFromMapOfStringInt(myMap)); - if (rank==0 && MyGlobals::_Verbose>20) - { - std::cout << "v2 is : a vector of size " << v2.size() << std::endl; - std::cout << ReprVectorOfString(v2) << std::endl; - std::map<std::string,int> m2=DevectorizeToMapOfStringInt(v2); - std::cout << "m2 is : a map of size " << m2.size() << std::endl; - std::cout << ReprMapOfStringInt(m2) << std::endl; - } - if (MyGlobals::_Verbose) - std::cout << "proc " << rank << " : OK TestMapOfStringIntMpi END" << std::endl; -} - -void MEDPARTITIONER::TestMapOfStringVectorOfStringMpi() -{ - int rank=MyGlobals::_Rank; - std::vector<std::string> myVector; - std::ostringstream oss; - oss << "hello from " << std::setw(5) << MyGlobals::_Rank << " " << std::string(rank+1,'n') << " next is an empty one"; - myVector.push_back(oss.str()); - myVector.push_back(""); - myVector.push_back("next is an singleton"); - myVector.push_back("1"); - - if (rank==0) - { - std::map< std::string,std::vector<std::string> > m2; - m2["first key"]=myVector; - m2["second key"]=myVector; - std::vector<std::string> v2=VectorizeFromMapOfStringVectorOfString(m2); - std::map< std::string,std::vector<std::string> > m3=DevectorizeToMapOfStringVectorOfString(v2); - if (rank==0 && MyGlobals::_Verbose>20) - std::cout << "m2 is : a MapOfStringVectorOfString of size " << m2.size() << std::endl; - std::cout << ReprMapOfStringVectorOfString(m2) << std::endl; - std::cout << "v2 is : a vector of size " << v2.size() << std::endl; - std::cout << ReprVectorOfString(v2) << std::endl; - std::cout << "m3 is : a map of size "<<m3.size() << std::endl; - std::cout << ReprMapOfStringVectorOfString(m3) << std::endl; - if (ReprMapOfStringVectorOfString(m3)!=ReprMapOfStringVectorOfString(m2)) - throw INTERP_KERNEL::Exception("Problem in (de)vectorize MapOfStringVectorOfString"); - } - - std::map< std::string,std::vector<std::string> > m4; - m4["1rst key"]=myVector; - m4["2snd key"]=myVector; - std::vector<std::string> v4=AllgathervVectorOfString(VectorizeFromMapOfStringVectorOfString(m4)); - if (rank==0 && MyGlobals::_Verbose>20) - { - std::map< std::string,std::vector<std::string> > m5=DevectorizeToMapOfStringVectorOfString(v4); - std::map< std::string,std::vector<std::string> > m6=DeleteDuplicatesInMapOfStringVectorOfString(m5); - std::cout<< "m5 is : a map of size "<<m5.size() << std::endl; - std::cout<< ReprMapOfStringVectorOfString(m5) << std::endl; - std::cout<< "m6 is : a map from m5 with deleteDuplicates of size " << m6.size() << std::endl; - std::cout<< ReprMapOfStringVectorOfString(m6) << std::endl; - } - if (MyGlobals::_Verbose) - std::cout<<"proc " << rank << " : OK TestMapOfStringVectorOfStringMpi END" << std::endl; -} - -void MEDPARTITIONER::TestDataArrayMpi() -{ - int rank=MyGlobals::_Rank; - //int - { - ParaMEDMEM::DataArrayInt* send=ParaMEDMEM::DataArrayInt::New(); - ParaMEDMEM::DataArrayInt* recv=0; - int nbOfTuples=5; - int numberOfComponents=3; - send->alloc(nbOfTuples,numberOfComponents); - std::vector<int> vals; - for (int j=0; j<nbOfTuples; j++) - for (int i=0; i<numberOfComponents; i++) vals.push_back((j+1)*10+i+1); - std::copy(vals.begin(),vals.end(),send->getPointer()); - if (rank==0) - SendDataArrayInt(send, 1); - if (rank==1) - recv=RecvDataArrayInt(0); - if (rank==1 && MyGlobals::_Verbose>20) - { - std::cout << send->repr() << std::endl; - std::cout << recv->repr() << std::endl; - } - if (rank==1) - { - if (send->repr()!=recv->repr()) - throw INTERP_KERNEL::Exception("Problem in send&recv DataArrayInt"); - } - send->decrRef(); - if (rank==1) - recv->decrRef(); - } - //double - { - ParaMEDMEM::DataArrayDouble* send=ParaMEDMEM::DataArrayDouble::New(); - ParaMEDMEM::DataArrayDouble* recv=0; - int nbOfTuples=5; - int numberOfComponents=3; - send->alloc(nbOfTuples,numberOfComponents); - std::vector<double> vals; - for (int j=0; j<nbOfTuples; j++) - for (int i=0; i<numberOfComponents; i++) vals.push_back(double(j+1)+double(i+1)/10); - std::copy(vals.begin(),vals.end(),send->getPointer()); - if (rank==0) SendDataArrayDouble(send, 1); - if (rank==1) recv=RecvDataArrayDouble(0); - if (rank==1 && MyGlobals::_Verbose>20) - { - std::cout << send->repr() << std::endl; - std::cout << recv->repr() << std::endl; - } - if (rank==1) - { - if (send->repr()!=recv->repr()) - throw INTERP_KERNEL::Exception("Problem in send&recv DataArrayDouble"); - } - send->decrRef(); - if (rank==1) recv->decrRef(); - } - - if (MyGlobals::_Verbose) - std::cout << "proc " << rank << " : OK TestDataArrayMpi END" << std::endl; -} - -void MEDPARTITIONER::TestPersistantMpi0To1(int taille, int nb) -{ - double temps_debut=MPI_Wtime(); - int rank=MyGlobals::_Rank; - std::vector<int> x, y; - int tag=111111; - MPI_Request requete0, requete1; - MPI_Status statut; - int ok=0; - std::string res; - if (rank==0) - { - x.resize(taille); - MPI_Ssend_init(&x[0], taille, MPI_INT, 1, tag, MPI_COMM_WORLD , &requete0); - for(int k=0; k<nb; k++) - { - for (int i=0; i<taille; ++i) x[i]=k; - //Envoi d’un gros message --> cela peut prendre du temps - MPI_Start(&requete0); - //Traitement sequentiel independant de "x" - //... - MPI_Wait(&requete0, &statut); - //Traitement sequentiel impliquant une modification de "x" en memoire - //x=... - } - MPI_Request_free(&requete0); - } - else if (rank == 1) - { - y.resize(taille); - MPI_Recv_init(&y[0], taille, MPI_INT, 0, tag, MPI_COMM_WORLD , &requete1); - for(int k=0; k<nb; k++) - { - //Pre-traitement sequentiel - //... - for (int i=0; i<taille; ++i) y[i]=(-1); - //Reception du gros message --> cela peut prendre du temps - MPI_Start(&requete1); - //Traitement sequentiel independant de "y" - //... - MPI_Wait(&requete1, &statut); - //Traitement sequentiel dependant de "y" - //...=f(y) - int nbb=0; - for (int i=0; i<taille; ++i) - if (y[i]==k) - nbb++; - if (nbb==taille) - ok++; - if (MyGlobals::_Verbose>9) - { - res="0K"; - if (nbb!=taille) - res="KO"; - std::cout << res << k << " "; - } - } - res="0K"; - if (ok!=nb) - res="BAD"; - if (MyGlobals::_Verbose>1) - std::cout << "result " << res << " time(sec) " << MPI_Wtime()-temps_debut << std::endl; - MPI_Request_free(&requete1); - } - //end_time=(MPI_WTIME()-start_time); -} - -void MEDPARTITIONER::TestPersistantMpiRing(int taille, int nb) -{ - double temps_debut=MPI_Wtime(); - int befo, next, rank, wsize, tagbefo, tagnext; - rank=MyGlobals::_Rank; - wsize=MyGlobals::_World_Size; - befo=rank-1; if (befo<0) befo=wsize-1; - next=rank+1; if (next>=wsize) next=0; - std::vector<int> x, y; - tagbefo=111111+befo; - tagnext=111111+rank; - MPI_Request requete0, requete1; - MPI_Status statut1, statut2; - int ok=0; - std::string res; - //cout<<"ini|"<<rank<<'|'<<befo<<'|'<<next<<' '; - { - x.resize(taille); - y.resize(taille); - MPI_Ssend_init(&x[0], taille, MPI_INT, next, tagnext, MPI_COMM_WORLD , &requete0); - MPI_Recv_init(&y[0], taille, MPI_INT, befo, tagbefo, MPI_COMM_WORLD , &requete1); - for(int k=0; k<nb; k++) - { - for (int i=0; i<taille; ++i) x[i]=k+rank; - //Envoi d’un gros message --> cela peut prendre du temps - MPI_Start(&requete0); - //Reception du gros message --> cela peut prendre du temps - for (int i=0; i<taille; ++i) y[i]=(-1); - MPI_Start(&requete1); - //Traitement sequentiel independant de "x" - //... - //Traitement sequentiel independant de "y" - //... - MPI_Wait(&requete1, &statut1); - //Traitement sequentiel dependant de "y" - //...=f(y) - int nbb=0; - for (int i=0; i<taille; ++i) - if (y[i]==k+befo) - nbb++; - if (nbb==taille) - ok++; - if (MyGlobals::_Verbose>9) - { - res="0K"+IntToStr(rank); - if (nbb!=taille) - res="KO"+IntToStr(rank); - std::cout << res << k << " "; - } - MPI_Wait(&requete0, &statut2); - //Traitement sequentiel impliquant une modification de "x" en memoire - //x=... - } - res="0K"; if (ok!=nb) res="MAUVAIS"; - temps_debut=MPI_Wtime()-temps_debut; - MPI_Request_free(&requete1); - MPI_Request_free(&requete0); - } - //end_time=(MPI_WTIME()-start_time); - if (MyGlobals::_Verbose>1) - std::cout << "result on proc " << rank << " " << res << " time(sec) " << temps_debut << std::endl; -} - -void MEDPARTITIONER::TestPersistantMpiRingOnCommSplit(int size, int nb) -{ - double temps_debut=MPI_Wtime(); - int rank=MyGlobals::_Rank; - MPI_Comm newcomm; - int color=1; - int rankMax=4; - if (rank>=rankMax) - color=MPI_UNDEFINED; - //MPI_Comm_dup (MPI_COMM_WORLD, &newcomm) ; - MPI_Comm_split(MPI_COMM_WORLD, color, rank, &newcomm); - - int befo, next, wsize, tagbefo, tagnext; - wsize=rankMax; - if (wsize>MyGlobals::_World_Size) - wsize=MyGlobals::_World_Size; - befo=rank-1; - if (befo<0) - befo=wsize-1; - next=rank+1; - if (next>=wsize) - next=0; - std::vector<int> x, y; - tagbefo=111111+befo; - tagnext=111111+rank; - MPI_Request requete0, requete1; - MPI_Status statut1, statut2; - int ok=0; - std::string res; - - if (color==1) - { - x.resize(size); - y.resize(size); - MPI_Ssend_init(&x[0], size, MPI_INT, next, tagnext, newcomm , &requete0); - MPI_Recv_init(&y[0], size, MPI_INT, befo, tagbefo, newcomm , &requete1); - for(int k=0; k<nb; k++) - { - for (int i=0; i<size; ++i) - x[i]=k+rank; - //Send of big message --> time consuming - MPI_Start(&requete0); - //Reception of big message --> time consuming - for (int i=0; i<size; ++i) - y[i]=-1; - MPI_Start(&requete1); - //Traitement sequentiel independant de "x" - //... - //Traitement sequentiel independant de "y" - //... - //cout<<"dsr|"<<rank<<' '; - MPI_Wait(&requete1, &statut1); - //Traitement sequentiel dependant de "y" - //...=f(y) - int nbb=0; - for (int i=0; i<size; ++i) - if (y[i]==k+befo) - nbb++; - if (nbb==size) - ok++; - if (MyGlobals::_Verbose>9) - { - res="0K"+IntToStr(rank); - if (nbb!=size) - res="KO"+IntToStr(rank); - std::cout << res << k << " "; - } - MPI_Wait(&requete0, &statut2); - //Traitement sequentiel impliquant une modification de "x" en memoire - //x=... - } - res="0K"; - if (ok!=nb) - res="MAUVAIS"; - temps_debut=MPI_Wtime()-temps_debut; - MPI_Request_free(&requete1); - MPI_Request_free(&requete0); - } - //MPI_Barrier(MPI_COMM_WORLD); - if (color==1) - MPI_Comm_free(&newcomm); - if (MyGlobals::_Verbose>1) - std::cout << "resultat proc " << rank <<" " << res << " time(sec) " << temps_debut << std::endl; -} diff --git a/src/MEDPartitioner/MEDPARTITIONER_metis.c b/src/MEDPartitioner/MEDPARTITIONER_metis.c deleted file mode 100644 index f67c84932..000000000 --- a/src/MEDPartitioner/MEDPARTITIONER_metis.c +++ /dev/null @@ -1,81 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// - -// Creation of this C code is forced by the following. -// -// In case if Metis is a part of Parmetis V3, extern "C" {#include "metis.h"} causes -// inclusion of C++ code of MPI via parmetis.h <- mpi.h <- mpicxx.h -// that breaks compilation. To workaround this problem we create a wrapping C -// function, inclusion of whose declaration causes no problem. - -#include "MEDPARTITIONER_metis.h" - -#if defined(MED_ENABLE_METIS) & !defined(MED_ENABLE_PARMETIS) - #ifndef MED_ENABLE_METIS_V5 - #include "defs.h" - #endif // MED_ENABLE_METIS_V5 - #include "metis.h" - #ifdef MED_ENABLE_METIS_V5 - #define idxtype idx_t - #endif // MED_ENABLE_METIS_V5 -#else - typedef int idxtype; -#endif // defined(MED_ENABLE_METIS) & !defined(MED_ENABLE_PARMETIS) - -void MEDPARTITIONER_METIS_PartGraphRecursive(int *nvtxs, idxtype *xadj, idxtype *adjncy, idxtype *vwgt, - idxtype *adjwgt, int *wgtflag, int *numflag, int *nparts, - int *options, int *edgecut, idxtype *part) -{ -#if defined(MED_ENABLE_METIS) - #ifndef MED_ENABLE_METIS_V5 - METIS_PartGraphRecursive(nvtxs, xadj, adjncy, vwgt, - adjwgt, wgtflag, numflag, nparts, - options, edgecut, part); - #else - int ncon=1; - options[METIS_OPTION_NCUTS]=1; - options[METIS_OPTION_NITER]=1; - options[METIS_OPTION_UFACTOR]=1; - METIS_PartGraphRecursive(nvtxs, &ncon, xadj, adjncy, vwgt, 0 /* vsize*/, - adjwgt, nparts,/* tpwgts*/ 0,/* ubvec */ 0, - options, edgecut, part); - #endif -#endif -} - -void MEDPARTITIONER_METIS_PartGraphKway(int *nvtxs, idxtype *xadj, idxtype *adjncy, idxtype *vwgt, - idxtype *adjwgt, int *wgtflag, int *numflag, int *nparts, - int *options, int *edgecut, idxtype *part) -{ -#if defined(MED_ENABLE_METIS) - #ifndef MED_ENABLE_METIS_V5 - METIS_PartGraphKway(nvtxs, xadj, adjncy, vwgt, - adjwgt, wgtflag, numflag, nparts, - options, edgecut, part); - #else - int ncon=1; - options[METIS_OPTION_NCUTS]=1; - options[METIS_OPTION_NITER]=1; - options[METIS_OPTION_UFACTOR]=1; - METIS_PartGraphKway(nvtxs, &ncon, xadj, adjncy, vwgt, 0 /* vsize*/, - adjwgt, nparts, 0 , 0 /* ubvec */, - options, edgecut, part); - #endif -#endif -} diff --git a/src/MEDPartitioner/MEDPARTITIONER_metis.h b/src/MEDPartitioner/MEDPARTITIONER_metis.h deleted file mode 100644 index eadfd7d50..000000000 --- a/src/MEDPartitioner/MEDPARTITIONER_metis.h +++ /dev/null @@ -1,30 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// - -// Creation of this C code is forced by the following. -// -// In case if Metis is a part of Parmetis V3, extern "C" {#include "metis.h"} causes -// inclusion of C++ code of MPI via parmetis.h <- mpi.h <- mpicxx.h -// that breaks compilation. To workaround this problem we create a wrapping C -// function, inclusion of whose declaration causes no problem. - - -void MEDPARTITIONER_METIS_PartGraphRecursive(int *, int *, int *, int *, int *, int *, int *, int *, int *, int *, int *); - -void MEDPARTITIONER_METIS_PartGraphKway(int *, int *, int *, int *, int *, int *, int *, int *, int *, int *, int *); diff --git a/src/MEDPartitioner/Test/CMakeLists.txt b/src/MEDPartitioner/Test/CMakeLists.txt deleted file mode 100644 index 6eb440e21..000000000 --- a/src/MEDPartitioner/Test/CMakeLists.txt +++ /dev/null @@ -1,65 +0,0 @@ -# Copyright (C) 2012-2015 CEA/DEN, EDF 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, 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 -# 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_DEFINITIONS(${BOOST_DEFINITIONS} ${CPPUNIT_DEFINITIONS}) - -INCLUDE_DIRECTORIES( - ${CPPUNIT_INCLUDE_DIRS} - ${CMAKE_CURRENT_SOURCE_DIR}/.. - ${CMAKE_CURRENT_SOURCE_DIR}/../../INTERP_KERNELTest # for BasicMainTest.hxx - ) - -SET(MEDPARTITIONERTest_HEADERS_HXX - MEDPARTITIONERTest.hxx - ) - -SET(MEDPARTITIONERTest_SOURCES - MEDPARTITIONERTest.cxx - ) - -SET(MEDPARTITIONERTest_LDFLAGS medpartitionercpp ${CPPUNIT_LIBRARIES}) - -IF(SALOME_USE_MPI) - IF(SALOME_MED_PARTITIONER_PARMETIS) - SET(MEDPARTITIONERTest_SOURCES ${MEDPARTITIONERTest_SOURCES} MEDPARTITIONERTestPara.cxx) - ENDIF(SALOME_MED_PARTITIONER_PARMETIS) -ENDIF(SALOME_USE_MPI) - -ADD_LIBRARY(MEDPARTITIONERTest SHARED ${MEDPARTITIONERTest_SOURCES}) -TARGET_LINK_LIBRARIES(MEDPARTITIONERTest ${MEDPARTITIONERTest_LDFLAGS}) -INSTALL(TARGETS MEDPARTITIONERTest DESTINATION ${SALOME_INSTALL_LIBS}) - -ADD_EXECUTABLE(TestMEDPARTITIONER TestMEDPARTITIONER.cxx) -TARGET_LINK_LIBRARIES(TestMEDPARTITIONER MEDPARTITIONERTest) -INSTALL(TARGETS TestMEDPARTITIONER DESTINATION ${SALOME_INSTALL_BINS}) - -INSTALL(FILES ${MEDPARTITIONERTest_HEADERS_HXX} DESTINATION ${SALOME_INSTALL_HEADERS}) - -SALOME_GENERATE_TESTS_ENVIRONMENT(tests_env) -ADD_TEST(TestMEDPARTITIONER TestMEDPARTITIONER) -SET_TESTS_PROPERTIES(TestMEDPARTITIONER PROPERTIES ENVIRONMENT "${tests_env}") - -# Application tests - -SET(TEST_INSTALL_DIRECTORY ${SALOME_INSTALL_SCRIPT_SCRIPTS}/test/MEDCoupling/MEDPartitioner) -INSTALL(TARGETS MEDPARTITIONERTest TestMEDPARTITIONER DESTINATION ${TEST_INSTALL_DIRECTORY}) - -INSTALL(FILES CTestTestfileInstall.cmake - DESTINATION ${TEST_INSTALL_DIRECTORY} - RENAME CTestTestfile.cmake) diff --git a/src/MEDPartitioner/Test/CTestTestfileInstall.cmake b/src/MEDPartitioner/Test/CTestTestfileInstall.cmake deleted file mode 100644 index 4605fa005..000000000 --- a/src/MEDPartitioner/Test/CTestTestfileInstall.cmake +++ /dev/null @@ -1,21 +0,0 @@ -# Copyright (C) 2015 CEA/DEN, EDF 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, 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 -# 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_TEST(TestMEDPARTITIONER TestMEDPARTITIONER) -SET_TESTS_PROPERTIES(TestMEDPARTITIONER PROPERTIES LABELS "${COMPONENT_NAME}") diff --git a/src/MEDPartitioner/Test/MEDPARTITIONERTest.cxx b/src/MEDPartitioner/Test/MEDPARTITIONERTest.cxx deleted file mode 100644 index 5144d40d3..000000000 --- a/src/MEDPartitioner/Test/MEDPARTITIONERTest.cxx +++ /dev/null @@ -1,1506 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// - -#include "MEDPARTITIONERTest.hxx" - -#include "MEDPARTITIONER_MeshCollection.hxx" -#include "MEDPARTITIONER_ParallelTopology.hxx" -#include "MEDPARTITIONER_ParaDomainSelector.hxx" -#include "MEDPARTITIONER_Utils.hxx" - -#include "CellModel.hxx" -#include "MEDFileMesh.hxx" -#include "MEDLoader.hxx" -#include "MEDLoaderBase.hxx" -#include "MEDCouplingUMesh.hxx" -#include "MEDCouplingExtrudedMesh.hxx" -#include "MEDCouplingFieldDouble.hxx" -#include "MEDCouplingMemArray.hxx" -#include "MEDCouplingMultiFields.hxx" - -#include <cppunit/TestAssert.h> - -#include <sstream> -#include <cmath> -#include <list> -#include <stdexcept> -#include <cstdlib> -#include <vector> - -#ifdef HAVE_MPI -#include <mpi.h> -#endif - -using namespace std; -using namespace ParaMEDMEM; -using namespace MEDPARTITIONER; - -void MEDPARTITIONERTest::setSize(int ni, int nj, int nk) -{ - this->_ni=ni; //nb of hexa9 - this->_nj=nj; - this->_nk=nk; - this->_ntot=_ni*_nj*_nk; - string ijk=IntToStr(ni)+"x"+IntToStr(nj)+"x"+IntToStr(nk); - this->_file_name="tmp_testMesh_"+ijk+".med"; - this->_file_name_with_faces="tmp_testMeshWithFaces_"+ijk+".med"; - string ij=IntToStr(ni)+"x"+IntToStr(nj); - this->_file_name2="tmp_testMesh_"+ij+".med"; - this->_mesh_name="testMesh"; -} - -void MEDPARTITIONERTest::setSmallSize() -{ - setSize(2,3,5); //nb of hexa9 -} - -void MEDPARTITIONERTest::setMedianSize() -{ - setSize(20,30,50); //nb of hexa9 -} - -void MEDPARTITIONERTest::setbigSize() -{ - setSize(200,300,500); //nb of hexa9 -} - -std::string MEDPARTITIONERTest::getPartitionerExe() const -{ - std::string execName; - if ( getenv("top_builddir")) // make distcheck - { - execName = getenv("top_builddir"); - execName += "/src/MEDPartitioner/medpartitioner"; - } - else if ( getenv("MED_ROOT_DIR") ) - { - execName=getenv("MED_ROOT_DIR"); //.../INSTALL/MED - execName+="/bin/salome/medpartitioner"; - } - else - { - CPPUNIT_FAIL("Can't find medpartitioner, neither MED_ROOT_DIR nor top_builddir is set"); - } - return execName; -} - -// ============================================================================ -/*! - * Set up the environment called at every CPPUNIT_TEST () - */ -// ============================================================================ -void MEDPARTITIONERTest::setUp() -{ - this->_verbose=0; -#if defined(HAVE_MPI) - if (MyGlobals::_Rank==-1) //do once only - { - MPI_Init(0,0); - MPI_Comm_size(MPI_COMM_WORLD, &MyGlobals::_World_Size); - MPI_Comm_rank(MPI_COMM_WORLD, &MyGlobals::_Rank); - } -#else - //sequential : no MPI - MyGlobals::_World_Size=1; - MyGlobals::_Rank=0; -#endif - - if (_verbose>10) - { -#if defined(HAVE_MPI) - cout<<"\ndefined(HAVE_MPI)"<<endl; -#else - cout<<"\nNOT defined(HAVE_MPI)"<<endl; -#endif -#if defined(MED_ENABLE_PARMETIS) - cout<<"defined(MED_ENABLE_PARMETIS)"<<endl; -#else - cout<<"NOT defined(MED_ENABLE_PARMETIS)"<<endl; -#endif -#if defined(MED_ENABLE_METIS) - cout<<"defined(MED_ENABLE_METIS)"<<endl; -#else - cout<<"NOT defined(MED_ENABLE_METIS)"<<endl; -#endif -#if defined(MED_ENABLE_SCOTCH) - cout<<"defined(MED_ENABLE_SCOTCH)"<<endl; -#else - cout<<"NOT defined(MED_ENABLE_SCOTCH)"<<endl; -#endif - } -} - -// ============================================================================ -/*! - * - delete - */ -// ============================================================================ -void MEDPARTITIONERTest::tearDown() -{ -} - -ParaMEDMEM::MEDCouplingUMesh * MEDPARTITIONERTest::buildCUBE3DMesh() -//only hexa8 -{ - vector<int> conn; - vector<double> coor; - for (int k=0; k<=_nk; k++) - for (int j=0; j<=_nj; j++) - for (int i=0; i<=_ni; i++) - { - coor.push_back(i+.1); - coor.push_back(j+.2); - coor.push_back(k+.3); - } - int ii; - for (int k=0; k<_nk; k++) - for (int j=0; j<_nj; j++) - for (int i=0; i<_ni; i++) - { - ii=i + j*(_ni+1) + k*(_ni+1)*(_nj+1); - conn.push_back(ii); - conn.push_back(ii+1); - ii=ii + _ni + 2 ; - conn.push_back(ii); - conn.push_back(ii-1); - - ii=i + j*(_ni+1) + (k+1)*(_ni+1)*(_nj+1); - conn.push_back(ii); - conn.push_back(ii+1); - ii=ii + _ni + 2 ; - conn.push_back(ii); - conn.push_back(ii-1); - } - - /* - if (_verbose) //only for debug - { - cout<< "\nnb coor " << (_ni+1)*(_nj+1)*(_nk+1)*3 << " " << coor.size() << endl; - for (int i=0; i<(int)coor.size(); i++) - cout << coor[i] << " "; - cout << endl; - cout << "\nnb conn " << (_ni)*(_nj)*(_nk)*8 << " " << conn.size() << endl; - for (int i=0; i<(int)conn.size(); i=i+8) - { - for (int j=0; j<8; j++) - cout << conn[i+j] << " "; - cout << endl; - } - cout << endl; - } - */ - - MEDCouplingUMesh *mesh=MEDCouplingUMesh::New(); - mesh->setMeshDimension(3); - int nbc=conn.size()/8; //nb of cells - int nbv=coor.size()/3; //nb of vertices - mesh->allocateCells(nbc); - for(int i=0; i<nbc; i++) - { - int onehexa[8]; - std::copy(conn.begin()+i*8,conn.begin()+(i+1)*8,onehexa); - if (false) //(_verbose) - { - for (int j=0; j<8; j++) cout<<onehexa[j]<<" "; - cout<<endl; - } - mesh->insertNextCell(INTERP_KERNEL::NORM_HEXA8,8,onehexa); - } - mesh->finishInsertingCells(); - DataArrayDouble *myCoords=DataArrayDouble::New(); - myCoords->alloc(nbv,3); - std::copy(coor.begin(),coor.end(),myCoords->getPointer()); - mesh->setCoords(myCoords); - mesh->setName(_mesh_name.c_str()); - myCoords->decrRef(); - mesh->checkCoherency(); - return mesh; -} - -ParaMEDMEM::MEDCouplingUMesh * MEDPARTITIONERTest::buildCARRE3DMesh() -//only quad4 in oblique (k=j) -{ - vector<int> conn; - vector<double> coor; - for (int j=0; j<=_nj; j++) - for (int i=0; i<=_ni; i++) - { - int k=j; - coor.push_back(i+.1); - coor.push_back(j+.2); - coor.push_back(k+.3); - } - int ii; - int k=0; - for (int j=0; j<_nj; j++) - for (int i=0; i<_ni; i++) - { - ii=i + j*(_ni+1) + k*(_ni+1)*(_nj+1); - conn.push_back(ii); - conn.push_back(ii+1); - ii=ii + _ni + 2 ; - conn.push_back(ii); - conn.push_back(ii-1); - } - - if (false) //(_verbose) - { - cout<<"\nnb coor "<<(_ni+1)*(_nj+1)*3<<" "<<coor.size()<<endl; - for (int i=0; i<(int)coor.size(); i++) - cout << coor[i] << " "; - cout<<endl; - cout<<"\nnb conn "<<(_ni)*(_nj)*4<<" "<<conn.size()<<endl; - for (int i=0; i<(int)conn.size(); i=i+4) - { - for (int j=0; j<4; j++) cout<<conn[i+j]<<" "; - cout<<endl; - } - cout<<endl; - } - - MEDCouplingUMesh *mesh=MEDCouplingUMesh::New(); - mesh->setMeshDimension(2); - int nbc=conn.size()/4; //nb of cells - int nbv=coor.size()/3; //nb of vertices - mesh->allocateCells(nbc); - for(int i=0; i<nbc; i++) - { - int onequa[4]; - std::copy(conn.begin()+i*4,conn.begin()+(i+1)*4,onequa); - if (false) //(_verbose) - { - for (int j=0; j<4; j++) cout<<onequa[j]<<" "; - cout<<endl; - } - mesh->insertNextCell(INTERP_KERNEL::NORM_QUAD4,4,onequa); - } - mesh->finishInsertingCells(); - DataArrayDouble *myCoords=DataArrayDouble::New(); - myCoords->alloc(nbv,3); - std::copy(coor.begin(),coor.end(),myCoords->getPointer()); - mesh->setCoords(myCoords); - mesh->setName(_mesh_name.c_str()); - myCoords->decrRef(); - mesh->checkCoherency(); - return mesh; -} - -ParaMEDMEM::MEDCouplingUMesh * MEDPARTITIONERTest::buildFACE3DMesh() -//only quad4 on a global face of the CUBE3D (k=0) -{ - vector<int> conn; - vector<double> coor; - for (int j=0; j<=_nj; j++) - for (int i=0; i<=_ni; i++) - { - int k=0; - coor.push_back(i+.1); - coor.push_back(j+.2); - coor.push_back(k+.3); - } - int ii; - int k=0; - for (int j=0; j<_nj; j++) - for (int i=0; i<_ni; i++) - { - ii=i + j*(_ni+1) + k*(_ni+1)*(_nj+1); - conn.push_back(ii); - conn.push_back(ii+1); - ii=ii + _ni + 2 ; - conn.push_back(ii); - conn.push_back(ii-1); - } - - if (false) //(_verbose) - { - cout<<"\nnb coor "<<(_ni+1)*(_nj+1)*3<<" "<<coor.size()<<endl; - for (int i=0; i<(int)coor.size(); i++) - cout << coor[i] << " "; - cout<<endl; - cout<<"\nnb conn "<<(_ni)*(_nj)*4<<" "<<conn.size()<<endl; - for (int i=0; i<(int)conn.size(); i=i+4) - { - for (int j=0; j<4; j++) - cout << conn[i+j] << " "; - cout << endl; - } - cout << endl; - } - - MEDCouplingUMesh *mesh=MEDCouplingUMesh::New(); - mesh->setMeshDimension(2); - int nbc=conn.size()/4; //nb of cells - int nbv=coor.size()/3; //nb of vertices - mesh->allocateCells(nbc); - for(int i=0; i<nbc; i++) - { - int onequa[4]; - std::copy(conn.begin()+i*4,conn.begin()+(i+1)*4,onequa); - if (false) //(_verbose) - { - for (int j=0; j<4; j++) cout<<onequa[j]<<" "; - cout<<endl; - } - mesh->insertNextCell(INTERP_KERNEL::NORM_QUAD4,4,onequa); - } - mesh->finishInsertingCells(); - DataArrayDouble *myCoords=DataArrayDouble::New(); - myCoords->alloc(nbv,3); - std::copy(coor.begin(),coor.end(),myCoords->getPointer()); - mesh->setCoords(myCoords); - mesh->setName(_mesh_name.c_str()); - myCoords->decrRef(); - mesh->checkCoherency(); - return mesh; -} - -MEDCouplingFieldDouble * MEDPARTITIONERTest::buildVecFieldOnCells(string myfileName) -{ - //int ni=2,nj=3,nk=5; //nb of hexa9 - vector<double> field; - for (int k=0; k<_nk; k++) - for (int j=0; j<_nj; j++) - for (int i=0; i<_ni; i++) - { - field.push_back(i+.1); - field.push_back(j+.2); - field.push_back(k+.3); - } - - MEDCouplingUMesh *mesh=MEDLoader::ReadUMeshFromFile(myfileName.c_str(),_mesh_name.c_str(),0); - int nbOfCells=mesh->getNumberOfCells(); - MEDCouplingFieldDouble *f1=MEDCouplingFieldDouble::New(ON_CELLS,ONE_TIME); - f1->setName("VectorFieldOnCells"); - f1->setDescription("DescriptionOfFieldOnCells"); //not saved in file? - f1->setMesh(mesh); - DataArrayDouble *myField=DataArrayDouble::New(); - myField->alloc(nbOfCells,3); - std::copy(field.begin(),field.end(),myField->getPointer()); - f1->setArray(myField); - myField->setInfoOnComponent(0,"vx"); - myField->setInfoOnComponent(1,"vy"); - myField->setInfoOnComponent(2,"vz"); - myField->decrRef(); - f1->setTime(2.,0,1); - f1->checkCoherency(); - mesh->decrRef(); - return f1; -} - -MEDCouplingFieldDouble * MEDPARTITIONERTest::buildVecFieldOnNodes() -{ - //int ni=2,nj=3,nk=5; //nb of hexa9 - vector<double> field; - for (int k=0; k<=_nk; k++) - for (int j=0; j<=_nj; j++) - for (int i=0; i<=_ni; i++) - { - field.push_back(i+.1); - field.push_back(j+.2); - field.push_back(k+.3); - } - - MEDCouplingUMesh *mesh=MEDLoader::ReadUMeshFromFile(_file_name.c_str(),_mesh_name.c_str(),0); - int nbOfNodes=mesh->getNumberOfNodes(); - MEDCouplingFieldDouble *f1=MEDCouplingFieldDouble::New(ON_NODES,ONE_TIME); - f1->setName("VectorFieldOnNodes"); - f1->setDescription("DescriptionOfFieldOnNodes"); //not saved in file? - f1->setMesh(mesh); - DataArrayDouble *myField=DataArrayDouble::New(); - myField->alloc(nbOfNodes,3); - std::copy(field.begin(),field.end(),myField->getPointer()); - f1->setArray(myField); - myField->setInfoOnComponent(0,"vx"); - myField->setInfoOnComponent(1,"vy"); - myField->setInfoOnComponent(2,"vz"); - myField->decrRef(); - f1->setTime(2.,0,1); - f1->checkCoherency(); - mesh->decrRef(); - return f1; -} - - -void MEDPARTITIONERTest::createTestMeshWithoutField() -{ - { - MEDCouplingUMesh * mesh = buildCUBE3DMesh(); - MEDLoader::WriteUMesh(_file_name.c_str(),mesh,true); - if (_verbose) cout<<endl<<_file_name<<" created"<<endl; - if (_ntot<1000000) //too long - { - MEDCouplingUMesh *mesh_rw=MEDLoader::ReadUMeshFromFile(_file_name.c_str(),mesh->getName().c_str(),0); - if (_verbose) cout<<_file_name<<" reread"<<endl; - CPPUNIT_ASSERT(mesh->isEqual(mesh_rw,1e-12)); - mesh_rw->decrRef(); - } - mesh->decrRef(); - } - - { - vector<const ParaMEDMEM::MEDCouplingUMesh*> meshes; - MEDCouplingUMesh * mesh1 = buildCUBE3DMesh(); - MEDCouplingUMesh * mesh2 = buildFACE3DMesh(); - mesh1->setName("testMesh"); - mesh2->setName("theFaces"); - mesh2->tryToShareSameCoordsPermute(*mesh1, 1e-9); - mesh2->checkCoherency(); - mesh1->checkCoherency(); - meshes.push_back(mesh1); - meshes.push_back(mesh2); - MEDLoader::WriteUMeshes(_file_name_with_faces.c_str(), meshes, true); - - ParaMEDMEM::MEDFileUMesh* mfm=ParaMEDMEM::MEDFileUMesh::New(_file_name_with_faces.c_str(), mesh1->getName().c_str()); - DataArrayInt* FacesFam=DataArrayInt::New(); - FacesFam->alloc(mfm->getSizeAtLevel(-1),1); - FacesFam->fillWithValue(-1); - DataArrayInt* CellsFam=DataArrayInt::New(); - CellsFam->alloc(mfm->getSizeAtLevel(0),1); - CellsFam->fillWithValue(1); - mfm->setFamilyFieldArr(-1,FacesFam); - mfm->setFamilyFieldArr(0,CellsFam); - map<string,int> theFamilies; - theFamilies["FAMILLE_ZERO"]=0; - theFamilies["FamilyFaces"]=-1; - theFamilies["FamilyCells"]=1; - map<string, vector<string> > theGroups; - theGroups["GroupFaces"].push_back("FamilyFaces"); - theGroups["GroupCells"].push_back("FamilyCells"); - mfm->setFamilyInfo(theFamilies); - mfm->setGroupInfo(theGroups); - mfm->write(_file_name_with_faces.c_str(),0); - FacesFam->decrRef(); - CellsFam->decrRef(); - - /*ce truc marche pas! - ParaMEDMEM::MEDFileUMesh* mfm=ParaMEDMEM::MEDFileUMesh::New(_file_name_with_faces.c_str(), mesh1->getName()); - vector<const ParaMEDMEM::MEDCouplingUMesh*> ms; - ms.push_back(mesh2); - mfm->setGroupsFromScratch(-1, ms); - mfm->write(_file_name_with_faces.c_str(),0); - */ - - if (_verbose) cout<<endl<<_file_name_with_faces<<" created"<<endl; - if (_ntot<1000000) //too long - { - MEDCouplingUMesh *mesh_rw=MEDLoader::ReadUMeshFromFile(_file_name_with_faces.c_str(),mesh1->getName().c_str(),0); - if (_verbose) cout<<_file_name_with_faces<<" reread"<<endl; - CPPUNIT_ASSERT(mesh1->isEqual(mesh_rw,1e-12)); - mesh_rw->decrRef(); - } - mesh1->decrRef(); - mesh2->decrRef(); - mfm->decrRef(); - } - - { - MEDCouplingUMesh * mesh = buildCARRE3DMesh(); - MEDLoader::WriteUMesh(_file_name2.c_str(),mesh,true); - if (_verbose) cout<<endl<<_file_name2<<" created"<<endl; - MEDCouplingUMesh *mesh_rw=MEDLoader::ReadUMeshFromFile(_file_name2.c_str(),mesh->getName().c_str(),0); - if (_verbose) cout<<_file_name2<<" reread"<<endl; - CPPUNIT_ASSERT(mesh->isEqual(mesh_rw,1e-12)); - mesh_rw->decrRef(); - mesh->decrRef(); - } -} - -/* -create a set of nbx*nby*nbz files mesh of ni*ny*nz cells -*/ -void MEDPARTITIONERTest::createHugeTestMesh(int ni, int nj, int nk, int nbx, int nby, int nbz, int nbTarget) -{ - setSize(ni,nj,nk); - _nb_target_huge=nbTarget; - MEDCouplingUMesh * mesh = buildCUBE3DMesh(); - //int nbx=1, nby=1, nbz=2; - std::vector< double > cooDep,cooFin; - mesh->getCoordinatesOfNode(0, cooDep); - mesh->getCoordinatesOfNode(mesh->getNumberOfNodes()-1, cooFin); - //cout<<endl<<cooDep[0]<<" "<<cooDep[1]<<" "<<cooDep[2]<<endl; - //cout<<cooFin[0]<<" "<<cooFin[1]<<" "<<cooFin[2]<<endl; - - string tagXml="\ -<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n \ -<root>\n \ - <version maj=\"2\" min=\"3\" ver=\"1\"/>\n \ - <description what=\"\" when=\"YYMMDDHHmm\"/>\n \ - <content>\n \ - <mesh name=\"testMesh\"/>\n \ - </content>\n \ - <splitting>\n \ - <subdomain number=\"$subdomainNumber\"/>\n \ - <global_numbering present=\"no\"/>\n \ - </splitting>\n \ - <files>\n$tagSubfile \ - </files>\n \ - <mapping>\n$tagMesh \ - </mapping>\n \ -</root>\n"; - - string tagSubfiles, tagSubfile="\ - <subfile id=\"$xyz\">\n \ - <name>$fileName</name>\n \ - <machine>localhost</machine>\n \ - </subfile>\n"; - string tagMeshes, tagMesh="\ - <mesh name=\"testMesh\">\n \ - <chunk subdomain=\"$xyz\">\n \ - <name>testMesh</name>\n \ - </chunk>\n \ - </mesh>\n"; - - int xyz=1; - string sxyz; - DataArrayDouble* coordsInit=mesh->getCoords()->deepCpy(); - double* ptrInit=coordsInit->getPointer(); - double deltax=cooFin[0]-cooDep[0]; - double deltay=cooFin[1]-cooDep[1]; - double deltaz=cooFin[2]-cooDep[2]; - - double dz=0.; - for (int z=0; z<nbz; z++) - { - double dy=0.; - for (int y=0; y<nby; y++) - { - double dx=0.; - for (int x=0; x<nbx; x++) - { - string fileName; - sxyz=IntToStr(xyz); - fileName="tmp_testMeshHuge_"+IntToStr(_ni)+"x"+IntToStr(_nj)+"x"+IntToStr(_nk)+"_"+sxyz+".med"; - - DataArrayDouble* coords=mesh->getCoords(); - //int nbOfComp=coords->getNumberOfComponents(); //be 3D - int nbOfTuple=coords->getNumberOfTuples(); - double* ptr=coords->getPointer(); - double* ptrini=ptrInit; - for (int i=0; i<nbOfTuple; i++) - { - *ptr=(*ptrini)+dx; ptr++; ptrini++; //be 3D - *ptr=(*ptrini)+dy; ptr++; ptrini++; - *ptr=(*ptrini)+dz; ptr++; ptrini++; - } - - MEDLoader::WriteUMesh(fileName.c_str(),mesh,true); - - tagSubfiles+=tagSubfile; - tagSubfiles.replace(tagSubfiles.find("$xyz"),4,sxyz); - tagSubfiles.replace(tagSubfiles.find("$fileName"),9,fileName); - - tagMeshes+=tagMesh; - tagMeshes.replace(tagMeshes.find("$xyz"),4,sxyz); - xyz++; - dx+=deltax; - } - dy+=deltay; - } - dz+=deltaz; - } - coordsInit->decrRef(); - - tagXml.replace(tagXml.find("$subdomainNumber"),16,sxyz); - tagXml.replace(tagXml.find("$tagSubfile"),11,tagSubfiles); - tagXml.replace(tagXml.find("$tagMesh"),8,tagMeshes); - - string nameFileXml; - _file_name_huge_xml="tmp_testMeshHuge_"+IntToStr(_ni)+"x"+IntToStr(_nj)+"x"+IntToStr(_nk)+"_"+sxyz+".xml"; - std::ofstream f(_file_name_huge_xml.c_str()); - f<<tagXml; - f.close(); - //cout<<"\n"<<tagXml<<endl; - if (_verbose) - cout<<endl<<nameFileXml<<" created"<<endl; - mesh->decrRef(); -} - -void MEDPARTITIONERTest::createTestMeshWithVecFieldOnCells() -{ - { - string name=_file_name; - MEDCouplingFieldDouble *f1=buildVecFieldOnCells(name); - name.replace(name.find(".med"),4,"_WithVecFieldOnCells.med"); - MEDLoader::WriteField(name.c_str(),f1,true); - f1->setTime(3.,1,1); //time,it,order - f1->applyFunc("x/2."); - MEDLoader::WriteField(name.c_str(),f1,false); - if (_verbose) cout<<endl<<name<<" created"<<endl; - if (_ntot<1000000) //too long - { - MEDCouplingFieldDouble *f2=MEDLoader::ReadFieldCell(name.c_str(),f1->getMesh()->getName().c_str(),0,f1->getName().c_str(),0,1); - //DataArrayDouble *res=f2->getArray(); - if (_verbose) cout<<name<<" reread"<<endl; - //CPPUNIT_ASSERT(f1->isEqual(f2,1e-12,1e-12)); - f2->decrRef(); - } - f1->decrRef(); - } - { - string name=_file_name; - MEDCouplingFieldDouble *f1=buildVecFieldOnCells(name); - name.replace(name.find(".med"),4,"_WithVecFieldOnGaussNe.med"); - MEDCouplingFieldDouble *f3=MEDCouplingFieldDouble::New(ON_GAUSS_NE,ONE_TIME); - f3->setMesh(f1->getMesh()); - //cout<<"\nNumberOfMeshPlacesExpected "<<f3->getNumberOfMeshPlacesExpected()<<" " - // /*<<getNumberOfTuples(f1->getMesh())<<" "*/ - // <<f3->getMesh()->getNumberOfNodes()<<" " - // <<f3->getMesh()->getNumberOfCells()<<endl; - f3->setName("MyFieldOnGaussNE"); - f3->setDescription("MyDescriptionNE"); - DataArrayDouble *array=DataArrayDouble::New(); - //int nb=f1->getMesh()->getNumberOfNodes(); - - /*8 pt de gauss by cell - int nb=f3->getMesh()->getNumberOfCells()*8; - array->alloc(nb,2); - double *ptr=array->getPointer(); - for (int i=0; i<nb*2; i=i+2) {ptr[i]=(double)(i/8) ; ptr[i]=2.*(double)(i/8);} - */ - - //more nbptgauss=8 by default needs set MEDCouplingFieldDiscretizationPerCell - //theory: (may be) http://www.code-aster.org/V2/doc/v9/fr/man_r/r3/r3.06.03.pdf - int nbptgauss=8; //nb pt de gauss by cell - int nbcell=f3->getMesh()->getNumberOfCells(); - int nb=nbcell*nbptgauss; - int nbcomp=2; - array->alloc(nb,nbcomp); - double *ptr=array->getPointer(); - int ii=0; - for (int i=0; i<nbcell; i++) - for (int j=0; j<nbptgauss; j++) - for (int k=0; k<nbcomp; k++) - { - //123.4 for 12th cell,3rd component, 4th gausspoint - ptr[ii]=(double)((i+1)*10+(k+1))+((double)(j+1))/10.; - ii++; - } - array->setInfoOnComponent(0,"vGx"); - array->setInfoOnComponent(1,"vGy"); - f3->setTime(4.,5,6); - f3->setArray(array); - array->decrRef(); - MEDLoader::WriteField(name.c_str(),f3,true); - if (_verbose) cout<<endl<<name<<" created"<<endl; - f3->checkCoherency(); - f1->decrRef(); - if (_ntot<1000000) //too long - { - MEDCouplingFieldDouble* f4=MEDLoader::ReadField(ON_GAUSS_NE, - name.c_str(), f3->getMesh()->getName().c_str(), 0, "MyFieldOnGaussNE", 5, 6); - if (_verbose) cout<<"MyFieldOnGaussNE reread"<<endl; - f4->decrRef(); - } - f3->decrRef(); - } - { - string name=_file_name_with_faces; - MEDCouplingFieldDouble *f1=buildVecFieldOnCells(name); - name.replace(name.find(".med"),4,"_WithVecFieldOnCells.med"); - MEDLoader::WriteField(name.c_str(),f1,true); - if (_verbose) cout<<endl<<name<<" created"<<endl; - if (_ntot<1000000) //too long - { - MEDCouplingFieldDouble *f2=MEDLoader::ReadFieldCell(name.c_str(),f1->getMesh()->getName().c_str(),0,f1->getName().c_str(),0,1); - if (_verbose) cout<<name<<" reread"<<endl; - //CPPUNIT_ASSERT(f1->isEqual(f2,1e-12,1e-12)); assertion failed!! - f2->decrRef(); - } - f1->decrRef(); - } -} - -void MEDPARTITIONERTest::createTestMeshWithVecFieldOnNodes() -{ - MEDCouplingFieldDouble *f1=buildVecFieldOnNodes(); - string name=_file_name; - name.replace(name.find(".med"),4,"_WithVecFieldOnNodes.med"); - MEDLoader::WriteField(name.c_str(),f1,true); - if (_verbose) cout<<endl<<name<<" created"<<endl; - if (_ntot<1000000) //too long - { - MEDCouplingFieldDouble *f2=MEDLoader::ReadFieldNode(name.c_str(),f1->getMesh()->getName().c_str(),0,f1->getName().c_str(),0,1); - if (_verbose) cout<<name<<" reread"<<endl; - //CPPUNIT_ASSERT(f1->isEqual(f2,1e-12,1e-12)); assertion failed!! - f2->decrRef(); - } - f1->decrRef(); -} - -void MEDPARTITIONERTest::verifyTestMeshWithVecFieldOnNodes() -{ - string name=_file_name; - name.replace(name.find(".med"),4,"_WithVecFieldOnNodes.med"); - MEDCouplingUMesh * m=MEDLoader::ReadUMeshFromFile(name.c_str(),_mesh_name.c_str(),0); - std::set<INTERP_KERNEL::NormalizedCellType> types(m->getAllGeoTypes()); - if (_verbose) - { - cout<<"\n types in "<<name<<" : "; - //for (std::set<INTERP_KERNEL::NormalizedCellType>::iterator t=types.begin(); t!=types.end(); ++t) cout<<" "<<*t; - for (std::set<INTERP_KERNEL::NormalizedCellType>::const_iterator t=types.begin(); t!=types.end(); ++t) - { - //INTERP_KERNEL::CellModel essai=INTERP_KERNEL::CellModel::GetCellModel(*t); - cout<<" "<<(INTERP_KERNEL::CellModel::GetCellModel(*t)).getRepr(); - } - cout<<endl; - } - m->decrRef(); - - MEDFileUMesh * mf = MEDFileUMesh::New(_file_name.c_str(),_mesh_name.c_str(),-1,-1); - vector<int> lev; - lev=mf->getNonEmptyLevels(); - if (_verbose) - { - cout<<" levels in "<<name<<" : "; - for (vector<int>::iterator l=lev.begin(); l!=lev.end(); ++l) cout<<" "<<*l; - cout<<endl; - } - mf->decrRef(); -} - -void MEDPARTITIONERTest::createTestMeshes() -{ - createTestMeshWithoutField(); - createTestMeshWithVecFieldOnCells(); - createTestMeshWithVecFieldOnNodes(); -} - -void MEDPARTITIONERTest::deleteTestMeshes() -{ - string cmd="rm *tmp_testMesh*"; - if (_verbose) cout<<endl<<cmd<<endl; - system(cmd.c_str()); //may be not if debug -} - -void MEDPARTITIONERTest::testMeshCollectionSingle() -{ - setSmallSize(); - createTestMeshes(); - MyGlobals::_World_Size=1; - MyGlobals::_Rank=0; - string fileName=_file_name_with_faces; - MEDPARTITIONER::ParaDomainSelector parallelizer(false); - MEDPARTITIONER::MeshCollection collection(fileName,parallelizer); - CPPUNIT_ASSERT(collection.isParallelMode()); - CPPUNIT_ASSERT_EQUAL(3, collection.getMeshDimension()); - CPPUNIT_ASSERT(collection.getName()=="testMesh"); - CPPUNIT_ASSERT_EQUAL(1,collection.getNbOfLocalMeshes()); - CPPUNIT_ASSERT_EQUAL(1,collection.getNbOfGlobalMeshes()); - CPPUNIT_ASSERT_EQUAL(_ni*_nj*_nk,collection.getNbOfLocalCells()); - CPPUNIT_ASSERT_EQUAL(_ni*_nj,collection.getNbOfLocalFaces()); -} - -void MEDPARTITIONERTest::testMeshCollectionXml() -{ - setSmallSize(); - createHugeTestMesh(_ni, _nj, _nk, 2, 2, 2, 32); //xml but not so huge - string fileName=_file_name_huge_xml; - MEDPARTITIONER::ParaDomainSelector parallelizer(false); - MEDPARTITIONER::MeshCollection collection(fileName,parallelizer); - CPPUNIT_ASSERT(collection.isParallelMode()); - CPPUNIT_ASSERT_EQUAL(3, collection.getMeshDimension()); - CPPUNIT_ASSERT(collection.getName()=="testMesh"); - CPPUNIT_ASSERT_EQUAL(8,collection.getNbOfLocalMeshes()); - CPPUNIT_ASSERT_EQUAL(8,collection.getNbOfGlobalMeshes()); - CPPUNIT_ASSERT_EQUAL(_ni*_nj*_nk*8,collection.getNbOfLocalCells()); - CPPUNIT_ASSERT_EQUAL(0,collection.getNbOfLocalFaces()); -} - - -//#################for metis - - - -#if defined(MED_ENABLE_METIS) -void MEDPARTITIONERTest::testMeshCollectionSinglePartitionMetis() -{ - setSmallSize(); - createTestMeshes(); - //MyGlobals::_Verbose=500; - string fileName=_file_name_with_faces; - int ndomains=2; - bool split_family=false; - bool empty_groups=false; - MEDPARTITIONER::ParaDomainSelector parallelizer(false); - MEDPARTITIONER::MeshCollection collection(fileName,parallelizer); - - MEDPARTITIONER::ParallelTopology* aPT = (MEDPARTITIONER::ParallelTopology*) collection.getTopology(); - aPT->setGlobalNumerotationDefault(collection.getParaDomainSelector()); - //Creating the graph and partitioning it - auto_ptr< MEDPARTITIONER::Topology > new_topo; - new_topo.reset( collection.createPartition(ndomains,MEDPARTITIONER::Graph::METIS) ); - //Creating a new mesh collection from the partitioning - MEDPARTITIONER::MeshCollection new_collection(collection,new_topo.get(),split_family,empty_groups); - - //example to create files - //MyGlobals::_General_Informations.clear(); - //MyGlobals::_General_Informations.push_back(SerializeFromString("finalMeshName=Merge")); - //if (MyGlobals::_Verbose>100) cout << "generalInformations : \n"<<ReprVectorOfString(MyGlobals::_General_Informations); - //new_collection.write("ttmp") - - CPPUNIT_ASSERT(new_collection.isParallelMode()); - CPPUNIT_ASSERT_EQUAL(3, new_collection.getMeshDimension()); - CPPUNIT_ASSERT(new_collection.getName()==collection.getName()); - CPPUNIT_ASSERT_EQUAL(ndomains,new_collection.getNbOfLocalMeshes()); - CPPUNIT_ASSERT_EQUAL(ndomains,new_collection.getNbOfGlobalMeshes()); - CPPUNIT_ASSERT_EQUAL(collection.getNbOfLocalCells(),new_collection.getNbOfLocalCells()); - CPPUNIT_ASSERT_EQUAL(collection.getNbOfLocalFaces(),new_collection.getNbOfLocalFaces()); -} - -void MEDPARTITIONERTest::testMeshCollectionComplexPartitionMetis() -{ - setSmallSize(); - createHugeTestMesh(_ni, _nj, _nk, 2, 2, 2, 32); //xml on 2*2*2 meshes but not so huge - string fileName=_file_name_huge_xml; - bool split_family=false; - bool empty_groups=false; - MEDPARTITIONER::ParaDomainSelector parallelizer(false); - MEDPARTITIONER::MeshCollection collection(fileName,parallelizer); - - MEDPARTITIONER::ParallelTopology* aPT = (MEDPARTITIONER::ParallelTopology*) collection.getTopology(); - aPT->setGlobalNumerotationDefault(collection.getParaDomainSelector()); - - for (int ndomains=2 ; ndomains<=16 ; ndomains++) - { - //Creating the graph and partitioning it - auto_ptr< MEDPARTITIONER::Topology > new_topo; - new_topo.reset( collection.createPartition(ndomains,MEDPARTITIONER::Graph::METIS) ); - //Creating a new mesh collection from the partitioning - MEDPARTITIONER::MeshCollection new_collection(collection,new_topo.get(),split_family,empty_groups); - - CPPUNIT_ASSERT_EQUAL(ndomains,new_collection.getNbOfLocalMeshes()); - CPPUNIT_ASSERT_EQUAL(ndomains,new_collection.getNbOfGlobalMeshes()); - CPPUNIT_ASSERT_EQUAL(collection.getNbOfLocalCells(),new_collection.getNbOfLocalCells()); - CPPUNIT_ASSERT_EQUAL(collection.getNbOfLocalFaces(),new_collection.getNbOfLocalFaces()); - } -} - -void MEDPARTITIONERTest::testMetisSmallSize() -{ - //#if !defined(HAVE_MPI) - setSmallSize(); - createTestMeshes(); - std::string MetisOrScotch("metis"); - launchMetisOrScotchMedpartitionerOnTestMeshes(MetisOrScotch); - verifyMetisOrScotchMedpartitionerOnSmallSizeForMesh(MetisOrScotch); - verifyMetisOrScotchMedpartitionerOnSmallSizeForFieldOnCells(MetisOrScotch); - verifyMetisOrScotchMedpartitionerOnSmallSizeForFieldOnGaussNe(MetisOrScotch); - //#endif -} -#endif - - -//#################for scotch - - -#if defined(MED_ENABLE_SCOTCH) -void MEDPARTITIONERTest::testMeshCollectionSinglePartitionScotch() -{ - setSmallSize(); - createTestMeshes(); - //MyGlobals::_Verbose=500; - string fileName=_file_name_with_faces; - int ndomains=2; - bool split_family=false; - bool empty_groups=false; - MEDPARTITIONER::ParaDomainSelector parallelizer(false); - MEDPARTITIONER::MeshCollection collection(fileName,parallelizer); - - MEDPARTITIONER::ParallelTopology* aPT = (MEDPARTITIONER::ParallelTopology*) collection.getTopology(); - aPT->setGlobalNumerotationDefault(collection.getParaDomainSelector()); - //Creating the graph and partitioning it - auto_ptr< MEDPARTITIONER::Topology > new_topo; - new_topo.reset( collection.createPartition(ndomains,MEDPARTITIONER::Graph::SCOTCH) ); - //Creating a new mesh collection from the partitioning - MEDPARTITIONER::MeshCollection new_collection(collection,new_topo.get(),split_family,empty_groups); - - //example to create files - //MyGlobals::_General_Informations.clear(); - //MyGlobals::_General_Informations.push_back(SerializeFromString("finalMeshName=Merge")); - //if (MyGlobals::_Verbose>100) cout << "generalInformations : \n"<<ReprVectorOfString(MyGlobals::_General_Informations); - //new_collection.write("ttmp") - - CPPUNIT_ASSERT(new_collection.isParallelMode()); - CPPUNIT_ASSERT_EQUAL(3, new_collection.getMeshDimension()); - CPPUNIT_ASSERT(new_collection.getName()==collection.getName()); - CPPUNIT_ASSERT_EQUAL(ndomains,new_collection.getNbOfLocalMeshes()); - CPPUNIT_ASSERT_EQUAL(ndomains,new_collection.getNbOfGlobalMeshes()); - CPPUNIT_ASSERT_EQUAL(collection.getNbOfLocalCells(),new_collection.getNbOfLocalCells()); - CPPUNIT_ASSERT_EQUAL(collection.getNbOfLocalFaces(),new_collection.getNbOfLocalFaces()); -} - -void MEDPARTITIONERTest::testMeshCollectionComplexPartitionScotch() -{ - setSmallSize(); - createHugeTestMesh(_ni, _nj, _nk, 2, 2, 2, 32); //xml on 2*2*2 meshes but not so huge - string fileName=_file_name_huge_xml; - bool split_family=false; - bool empty_groups=false; - MEDPARTITIONER::ParaDomainSelector parallelizer(false); - MEDPARTITIONER::MeshCollection collection(fileName,parallelizer); - - MEDPARTITIONER::ParallelTopology* aPT = (MEDPARTITIONER::ParallelTopology*) collection.getTopology(); - aPT->setGlobalNumerotationDefault(collection.getParaDomainSelector()); - - for (int ndomains=2 ; ndomains<=16 ; ndomains++) - { - //Creating the graph and partitioning it - auto_ptr< MEDPARTITIONER::Topology > new_topo; - new_topo.reset( collection.createPartition(ndomains,MEDPARTITIONER::Graph::SCOTCH) ); - //Creating a new mesh collection from the partitioning - MEDPARTITIONER::MeshCollection new_collection(collection,new_topo.get(),split_family,empty_groups); - - CPPUNIT_ASSERT_EQUAL(ndomains,new_collection.getNbOfLocalMeshes()); - CPPUNIT_ASSERT_EQUAL(ndomains,new_collection.getNbOfGlobalMeshes()); - CPPUNIT_ASSERT_EQUAL(collection.getNbOfLocalCells(),new_collection.getNbOfLocalCells()); - CPPUNIT_ASSERT_EQUAL(collection.getNbOfLocalFaces(),new_collection.getNbOfLocalFaces()); - } -} - -void MEDPARTITIONERTest::testScotchSmallSize() -{ - //#if !defined(HAVE_MPI) - setSmallSize(); - createTestMeshes(); - std::string MetisOrScotch("scotch"); - launchMetisOrScotchMedpartitionerOnTestMeshes(MetisOrScotch); - verifyMetisOrScotchMedpartitionerOnSmallSizeForMesh(MetisOrScotch); - verifyMetisOrScotchMedpartitionerOnSmallSizeForFieldOnCells(MetisOrScotch); - verifyMetisOrScotchMedpartitionerOnSmallSizeForFieldOnGaussNe(MetisOrScotch); - //#endif -} -#endif - -void MEDPARTITIONERTest::launchMetisOrScotchMedpartitionerOnTestMeshes(std::string MetisOrScotch) -{ - int res; - string cmd,execName,sourceName,targetName; - - execName=getPartitionerExe(); - - cmd="which "+execName+" 2>/dev/null 1>/dev/null"; //no trace - res=system(cmd.c_str()); - CPPUNIT_ASSERT_EQUAL_MESSAGE(execName + " - INVALID PATH TO medpartitioner", 0, res); - - cmd=execName+" --ndomains=2 --split-method="+MetisOrScotch; //on same proc - sourceName=_file_name; - targetName=_file_name; - targetName.replace(targetName.find(".med"),4,"_partitionedTo2_"); - cmd+=" --input-file="+sourceName+" --output-file="+targetName+" --verbose="+IntToStr(_verbose); - if (_verbose) cout<<endl<<cmd<<endl; - res=system(cmd.c_str()); - CPPUNIT_ASSERT_EQUAL(0, res); - - cmd=execName+" --ndomains=5 --split-method="+MetisOrScotch; //on less proc - sourceName=_file_name; - targetName=_file_name; - targetName.replace(targetName.find(".med"),4,"_partitionedTo5_"); - cmd+=" --input-file="+sourceName+" --output-file="+targetName+" --verbose="+IntToStr(_verbose); - if (_verbose) cout<<endl<<cmd<<endl; - res=system(cmd.c_str()); - CPPUNIT_ASSERT_EQUAL(0, res); - - cmd=execName+" --ndomains=1 --split-method="+MetisOrScotch; //on 1 proc - sourceName=targetName+".xml"; - targetName=_file_name; - targetName.replace(targetName.find(".med"),4,"_remergedFrom5_"); - cmd+=" --input-file="+sourceName+" --output-file="+targetName+" --verbose="+IntToStr(_verbose); - if (_verbose) cout<<endl<<cmd<<endl; - res=system(cmd.c_str()); - CPPUNIT_ASSERT_EQUAL(0, res); - - cmd=execName+" --ndomains=1 --split-method="+MetisOrScotch; //on more proc - //sourceName=targetName+".xml"; - targetName=_file_name; - targetName.replace(targetName.find(".med"),4,"_remergedFrom5_"); - cmd+=" --input-file="+sourceName+" --output-file="+targetName+" --verbose="+IntToStr(_verbose); - if (_verbose) cout<<endl<<cmd<<endl; - res=system(cmd.c_str()); - CPPUNIT_ASSERT_EQUAL(0, res); -} - -void MEDPARTITIONERTest::verifyMetisOrScotchMedpartitionerOnSmallSizeForMesh(std::string MetisOrScotch) -{ - int res; - string fileName,cmd,execName,sourceName,targetName,input; - execName=getPartitionerExe(); - fileName=_file_name_with_faces; - - ParaMEDMEM::MEDFileUMesh* initialMesh=ParaMEDMEM::MEDFileUMesh::New(fileName.c_str(),_mesh_name.c_str()); - ParaMEDMEM::MEDCouplingUMesh* cellMesh=initialMesh->getLevel0Mesh(false); - ParaMEDMEM::MEDCouplingUMesh* faceMesh=initialMesh->getLevelM1Mesh(false); - - cmd=execName+" --ndomains=5 --split-method="+MetisOrScotch; //on same proc - sourceName=fileName; - targetName=fileName; - targetName.replace(targetName.find(".med"),4,"_partitionedTo5_"); - cmd+=" --input-file="+sourceName+" --output-file="+targetName+" --verbose="+IntToStr(_verbose); - if (_verbose) cout<<endl<<cmd<<endl; - res=system(cmd.c_str()); - CPPUNIT_ASSERT_EQUAL(0, res); - input=targetName+".xml"; - - MEDPARTITIONER::ParaDomainSelector parallelizer(false); - MEDPARTITIONER::MeshCollection collection(input,parallelizer); - CPPUNIT_ASSERT_EQUAL(3, collection.getMeshDimension()); - std::vector<ParaMEDMEM::MEDCouplingUMesh*>cellMeshes=collection.getMesh(); - CPPUNIT_ASSERT_EQUAL(5, (int) cellMeshes.size()); - int nbcells=0; - for (std::size_t i = 0; i < cellMeshes.size(); i++) - nbcells+=cellMeshes[i]->getNumberOfCells(); - CPPUNIT_ASSERT_EQUAL(cellMesh->getNumberOfCells(), nbcells); - - std::vector<ParaMEDMEM::MEDCouplingUMesh*>faceMeshes=collection.getFaceMesh(); - CPPUNIT_ASSERT_EQUAL(5, (int) faceMeshes.size()); - int nbfaces=0; - for (std::size_t i=0; i < faceMeshes.size(); i++) - nbfaces+=faceMeshes[i]->getNumberOfCells(); - CPPUNIT_ASSERT_EQUAL(faceMesh->getNumberOfCells(), nbfaces); - - //merge split meshes and test equality - cmd=execName+" --ndomains=1 --split-method="+MetisOrScotch; //on same proc - sourceName=targetName+".xml"; - targetName=fileName; - targetName.replace(targetName.find(".med"),4,"_remergedFrom5_"); - cmd+=" --input-file="+sourceName+" --output-file="+targetName+" --verbose="+IntToStr(_verbose); - if (_verbose) cout<<endl<<cmd<<endl; - res=system(cmd.c_str()); - CPPUNIT_ASSERT_EQUAL(0, res); - - string refusedName=targetName+"1.med"; - ParaMEDMEM::MEDFileUMesh* refusedMesh=ParaMEDMEM::MEDFileUMesh::New(refusedName.c_str(),_mesh_name.c_str()); - ParaMEDMEM::MEDCouplingUMesh* refusedCellMesh=refusedMesh->getLevel0Mesh(false); - ParaMEDMEM::MEDCouplingUMesh* refusedFaceMesh=refusedMesh->getLevelM1Mesh(false); - - CPPUNIT_ASSERT_EQUAL(cellMesh->getNumberOfCells(), refusedCellMesh->getNumberOfCells()); - CPPUNIT_ASSERT_EQUAL(faceMesh->getNumberOfCells(), refusedFaceMesh->getNumberOfCells()); - - /*not the good job - ParaMEDMEM::MEDCouplingMesh* mergeCell=cellMesh->mergeMyselfWith(refusedCellMesh); - CPPUNIT_ASSERT_EQUAL(cellMesh->getNumberOfCells(), mergeCell->getNumberOfCells()); - - ParaMEDMEM::MEDCouplingMesh* mergeFace=faceMesh->mergeMyselfWith(refusedFaceMesh); - CPPUNIT_ASSERT_EQUAL(faceMesh->getNumberOfCells(), mergeFace->getNumberOfCells()); - - CPPUNIT_ASSERT(faceMesh->isEqual(refusedFaceMesh,1e-12)); - */ - - std::vector<const MEDCouplingUMesh *> meshes; - std::vector<DataArrayInt *> corr; - meshes.push_back(cellMesh); - refusedCellMesh->tryToShareSameCoordsPermute(*cellMesh, 1e-9); - meshes.push_back(refusedCellMesh); - MEDCouplingUMesh* fusedCell=MEDCouplingUMesh::FuseUMeshesOnSameCoords(meshes,0,corr); - CPPUNIT_ASSERT_EQUAL(cellMesh->getNumberOfCells(), fusedCell->getNumberOfCells()); - - meshes.resize(0); - for (std::size_t i = 0; i < corr.size(); i++) - corr[i]->decrRef(); - corr.resize(0); - meshes.push_back(faceMesh); - refusedFaceMesh->tryToShareSameCoordsPermute(*faceMesh, 1e-9); - meshes.push_back(refusedFaceMesh); - MEDCouplingUMesh* fusedFace=MEDCouplingUMesh::FuseUMeshesOnSameCoords(meshes,0,corr); - CPPUNIT_ASSERT_EQUAL(faceMesh->getNumberOfCells(), fusedFace->getNumberOfCells()); - - for (std::size_t i = 0; i < corr.size(); i++) - corr[i]->decrRef(); - fusedFace->decrRef(); - refusedFaceMesh->decrRef(); - faceMesh->decrRef(); - fusedCell->decrRef(); - refusedCellMesh->decrRef(); - refusedMesh->decrRef(); - cellMesh->decrRef(); - initialMesh->decrRef(); - //done in ~collection - //for (int i = 0; i < faceMeshes.size(); i++) faceMeshes[i]->decrRef(); - //for (int i = 0; i < cellMeshes.size(); i++) cellMeshes[i]->decrRef(); -} - -void MEDPARTITIONERTest::verifyMetisOrScotchMedpartitionerOnSmallSizeForFieldOnCells(std::string MetisOrScotch) -{ - int res; - string fileName,cmd,execName,sourceName,targetName,input; - execName=getPartitionerExe(); - fileName=_file_name; - fileName.replace(fileName.find(".med"),4,"_WithVecFieldOnCells.med"); - - ParaMEDMEM::MEDFileUMesh* initialMesh=ParaMEDMEM::MEDFileUMesh::New(fileName.c_str(),_mesh_name.c_str()); - ParaMEDMEM::MEDCouplingUMesh* cellMesh=initialMesh->getLevel0Mesh(false); - - cmd=execName+" --ndomains=5 --split-method="+MetisOrScotch; //on same proc - sourceName=fileName; - targetName=fileName; - targetName.replace(targetName.find(".med"),4,"_partitionedTo5_"); - cmd+=" --input-file="+sourceName+" --output-file="+targetName+" --verbose="+IntToStr(_verbose); - if (_verbose) cout<<endl<<cmd<<endl; - res=system(cmd.c_str()); - CPPUNIT_ASSERT_EQUAL(0, res); - input=targetName+".xml"; - - //merge split meshes and test equality - cmd=execName+" --ndomains=1 --split-method="+MetisOrScotch; //on same proc - sourceName=targetName+".xml"; - targetName=fileName; - targetName.replace(targetName.find(".med"),4,"_remergedFrom5_"); - cmd+=" --input-file="+sourceName+" --output-file="+targetName+" --verbose="+IntToStr(_verbose); - if (_verbose) cout<<endl<<cmd<<endl; - res=system(cmd.c_str()); - CPPUNIT_ASSERT_EQUAL(0, res); - - string refusedName=targetName+"1.med"; - ParaMEDMEM::MEDFileUMesh* refusedMesh=ParaMEDMEM::MEDFileUMesh::New(refusedName.c_str(),_mesh_name.c_str()); - ParaMEDMEM::MEDCouplingUMesh* refusedCellMesh=refusedMesh->getLevel0Mesh(false); - - CPPUNIT_ASSERT_EQUAL(cellMesh->getNumberOfCells(), refusedCellMesh->getNumberOfCells()); - - std::vector<const MEDCouplingUMesh *> meshes; - std::vector<DataArrayInt *> corr; - meshes.push_back(cellMesh); - refusedCellMesh->tryToShareSameCoordsPermute(*cellMesh, 1e-9); - meshes.push_back(refusedCellMesh); - MEDCouplingUMesh* fusedCell=MEDCouplingUMesh::FuseUMeshesOnSameCoords(meshes,0,corr); - CPPUNIT_ASSERT_EQUAL(cellMesh->getNumberOfCells(), fusedCell->getNumberOfCells()); - - MEDCouplingFieldDouble* field1=MEDLoader::ReadFieldCell(fileName.c_str(),initialMesh->getName().c_str(),0,"VectorFieldOnCells",0,1); - MEDCouplingFieldDouble* field2=MEDLoader::ReadFieldCell(refusedName.c_str(),refusedCellMesh->getName().c_str(),0,"VectorFieldOnCells",0,1); - - int nbcells=corr[1]->getNumberOfTuples(); - CPPUNIT_ASSERT_EQUAL(cellMesh->getNumberOfCells(), nbcells); - //use corr to test equality of field - DataArrayDouble* f1=field1->getArray(); - DataArrayDouble* f2=field2->getArray(); - if (_verbose>300) - { - cout<<"\nf1 : "<<f1->reprZip(); - cout<<"\nf2 : "<<f2->reprZip(); //field2->advancedRepradvancedRepr(); - for (std::size_t i = 0; i < corr.size(); i++) - cout << "\ncorr " << i << " : " << corr[i]->reprZip(); - - } - int nbequal=0; - int nbcomp=field1->getNumberOfComponents(); - double* p1=f1->getPointer(); - double* p2=f2->getPointer(); - int* pc=corr[1]->getPointer(); - for (int i = 0; i < nbcells; i++) - { - int i1=pc[i]*nbcomp; - int i2=i*nbcomp; - for (int j = 0; j < nbcomp; j++) - { - if (p1[i1+j]==p2[i2+j]) nbequal++; - //cout<<" "<<p1[i1+j]<<"="<<p2[i2+j]; - } - } - CPPUNIT_ASSERT_EQUAL(nbcells*nbcomp, nbequal); - - for (std::size_t i = 0; i < corr.size(); i++) - corr[i]->decrRef(); - field1->decrRef(); - field2->decrRef(); - fusedCell->decrRef(); - refusedMesh->decrRef(); - refusedCellMesh->decrRef(); - cellMesh->decrRef(); - initialMesh->decrRef(); -} - -void MEDPARTITIONERTest::verifyMetisOrScotchMedpartitionerOnSmallSizeForFieldOnGaussNe(std::string MetisOrScotch) -{ - int res; - string fileName,cmd,execName,sourceName,targetName,input; - execName=getPartitionerExe(); - fileName=_file_name; - fileName.replace(fileName.find(".med"),4,"_WithVecFieldOnGaussNe.med"); - - ParaMEDMEM::MEDFileUMesh* initialMesh=ParaMEDMEM::MEDFileUMesh::New(fileName.c_str(),_mesh_name.c_str()); - ParaMEDMEM::MEDCouplingUMesh* cellMesh=initialMesh->getLevel0Mesh(false); - - cmd=execName+" --ndomains=5 --split-method="+MetisOrScotch; //on same proc - sourceName=fileName; - targetName=fileName; - targetName.replace(targetName.find(".med"),4,"_partitionedTo5_"); - cmd+=" --input-file="+sourceName+" --output-file="+targetName+" --verbose="+IntToStr(_verbose); - if (_verbose) cout<<endl<<cmd<<endl; - res=system(cmd.c_str()); - CPPUNIT_ASSERT_EQUAL(0, res); - input=targetName+".xml"; - - //merge split meshes and test equality - cmd=execName+" --ndomains=1 --split-method="+MetisOrScotch; //on same proc - sourceName=targetName+".xml"; - targetName=fileName; - targetName.replace(targetName.find(".med"),4,"_remergedFrom5_"); - cmd+=" --input-file="+sourceName+" --output-file="+targetName+" --verbose="+IntToStr(_verbose); - if (_verbose) cout<<endl<<cmd<<endl; - res=system(cmd.c_str()); - CPPUNIT_ASSERT_EQUAL(0, res); - - string refusedName=targetName+"1.med"; - ParaMEDMEM::MEDFileUMesh* refusedMesh=ParaMEDMEM::MEDFileUMesh::New(refusedName.c_str(),_mesh_name.c_str()); - ParaMEDMEM::MEDCouplingUMesh* refusedCellMesh=refusedMesh->getLevel0Mesh(false); - - CPPUNIT_ASSERT_EQUAL(cellMesh->getNumberOfCells(), refusedCellMesh->getNumberOfCells()); - - std::vector<const MEDCouplingUMesh *> meshes; - std::vector<DataArrayInt *> corr; - meshes.push_back(cellMesh); - refusedCellMesh->tryToShareSameCoordsPermute(*cellMesh, 1e-9); - meshes.push_back(refusedCellMesh); - MEDCouplingUMesh* fusedCell=MEDCouplingUMesh::FuseUMeshesOnSameCoords(meshes,0,corr); - CPPUNIT_ASSERT_EQUAL(cellMesh->getNumberOfCells(), fusedCell->getNumberOfCells()); - - MEDCouplingFieldDouble* field1=MEDLoader::ReadField(ON_GAUSS_NE,fileName.c_str(),initialMesh->getName().c_str(),0,"MyFieldOnGaussNE",5,6); - MEDCouplingFieldDouble* field2=MEDLoader::ReadField(ON_GAUSS_NE,refusedName.c_str(),refusedCellMesh->getName().c_str(),0,"MyFieldOnGaussNE",5,6); - - int nbcells=corr[1]->getNumberOfTuples(); - CPPUNIT_ASSERT_EQUAL(cellMesh->getNumberOfCells(), nbcells); - //use corr to test equality of field - DataArrayDouble* f1=field1->getArray(); - DataArrayDouble* f2=field2->getArray(); - if (_verbose>300) - { - cout << "\nf1 : " << f1->reprZip(); //123.4 for 12th cell,3rd component, 4th gausspoint - cout << "\nf2 : " << f2->reprZip(); //field2->advancedRepradvancedRepr(); - for (std::size_t i = 0; i < corr.size(); i++) - cout << "\ncorr " << i << " : " << corr[i]->reprZip(); - - } - int nbequal=0; - int nbptgauss=8; - int nbcomp=field1->getNumberOfComponents(); - double* p1=f1->getPointer(); - double* p2=f2->getPointer(); - int* pc=corr[1]->getPointer(); - for (int i = 0; i < nbcells; i++) - { - int i1=pc[i]*nbcomp*nbptgauss; - int i2=i*nbcomp*nbptgauss; - for (int j = 0; j < nbcomp*nbptgauss; j++) - { - if (p1[i1+j]==p2[i2+j]) nbequal++; - //cout<<" "<<p1[i1+j]<<"="<<p2[i2+j]; - } - } - CPPUNIT_ASSERT_EQUAL(nbcells*nbcomp*nbptgauss, nbequal); - - for (std::size_t i = 0; i < corr.size(); i++) - corr[i]->decrRef(); - field1->decrRef(); - field2->decrRef(); - fusedCell->decrRef(); - refusedMesh->decrRef(); - refusedCellMesh->decrRef(); - cellMesh->decrRef(); - initialMesh->decrRef(); -} - -//================================================================================ -/*! - * \brief Test for 0021756: [CEA 602] MEDPartitioner improvements - */ -//================================================================================ - -void MEDPARTITIONERTest::testCreateBoundaryFaces2D() -{ - // Fixed complains are: - // - 2D is not available - // - groups and family handling is bugged (probably due to bug in the handling - // of arrayTo in castIntField()) - // - creates boundary faces option is not handled - - // Create a 2D mesh in a file - - const char fileName[] = "tmp_testCreateBoundaryFaces2D.med"; - - const int idFam1 = 3, idFam2 = 2; - int nbFam1, nbFam2, nbc; - { - const int nbX = 20, nbY = 15; - vector<int> conn; - vector<double> coor; - for (int j=0; j<=nbY; j++) - for (int i=0; i<=nbX; i++) - { - coor.push_back(i+.1); - coor.push_back(j+.2); - } - int ii; - for (int j=0; j<nbY; j++) - for (int i=0; i<nbX; i++) - { - ii=i + j*(nbX+1); - conn.push_back(ii); - conn.push_back(ii+1); - ii=ii + nbX + 2 ; - conn.push_back(ii); - conn.push_back(ii-1); - } - MEDCouplingUMesh *mesh=MEDCouplingUMesh::New(); - mesh->setMeshDimension(2); - - nbc=conn.size()/4; //nb of cells - mesh->allocateCells(nbc); - int* pConn = &conn[0]; - for(int i=0; i<nbc; i++, pConn+=4) - mesh->insertNextCell(INTERP_KERNEL::NORM_QUAD4,4,pConn); - mesh->finishInsertingCells(); - - int nbv=coor.size()/2; //nb of vertices - DataArrayDouble *myCoords=DataArrayDouble::New(); - myCoords->useArray( &coor[0], /*ownership=*/false, CPP_DEALLOC, nbv, 2 ); - mesh->setCoords(myCoords); - mesh->setName("FacesIn2D"); - myCoords->decrRef(); - mesh->checkCoherency(); - - // groups of cells - DataArrayInt* cellsFam=DataArrayInt::New(); - cellsFam->alloc(nbc,1); - nbFam1 = nbc/3, nbFam2 = nbc/2; - int iE = 0; - for ( int i = 0; i < nbFam1; ++i ) cellsFam->getPointer()[ iE++ ] = idFam1; - for ( int i = 0; i < nbFam2; ++i ) cellsFam->getPointer()[ iE++ ] = idFam2; - for ( ; iE < nbc; ) cellsFam->getPointer()[ iE++ ] = 0; - map<string,int> theFamilies; - theFamilies["FAMILLE_ZERO"]=0; - theFamilies["Family1" ]=idFam1; - theFamilies["Family2" ]=idFam2; - map<string, vector<string> > theGroups; - theGroups["Group1"].push_back("Family1"); - theGroups["Group2"].push_back("Family2"); - - // write mesh - MEDFileUMesh * fileMesh = MEDFileUMesh::New(); - fileMesh->setMeshAtLevel(0, mesh); - fileMesh->setFamilyInfo(theFamilies); - fileMesh->setGroupInfo(theGroups); - fileMesh->setFamilyFieldArr(0, cellsFam); - fileMesh->write(fileName,2); - - cellsFam->decrRef(); - mesh ->decrRef(); - fileMesh->decrRef(); - - } // mesh creation - - // Partition the mesh into 4 parts - - const int ndomains = 4; - ParaDomainSelector parallelizer(false); - MeshCollection collection(fileName,parallelizer); - ParallelTopology* aPT = (ParallelTopology*) collection.getTopology(); - aPT->setGlobalNumerotationDefault(collection.getParaDomainSelector()); - - std::auto_ptr< Topology > new_topo; -#if defined(MED_ENABLE_METIS) || defined(MED_ENABLE_PARMETIS) - new_topo.reset( collection.createPartition(ndomains,Graph::METIS) ); -#endif -#if defined(MED_ENABLE_SCOTCH) - if ( !new_topo.get() ) - new_topo.reset( collection.createPartition(ndomains,Graph::SCOTCH) ); -#endif - if ( !new_topo.get() ) - return; - - // Check that "2D is available" - - const char xmlName[] = "tmp_testCreateBoundaryFaces2D"; - { - MyGlobals::_Creates_Boundary_Faces = true; - MeshCollection new_collection(collection,new_topo.get()); - - CPPUNIT_ASSERT_EQUAL(ndomains,new_collection.getNbOfLocalMeshes()); - CPPUNIT_ASSERT_EQUAL(ndomains,new_collection.getNbOfGlobalMeshes()); - CPPUNIT_ASSERT_EQUAL(collection.getNbOfLocalCells(),new_collection.getNbOfLocalCells()); - CPPUNIT_ASSERT_EQUAL(0,collection.getNbOfLocalFaces()); - CPPUNIT_ASSERT (new_collection.getNbOfLocalFaces() > 0 ); - - MyGlobals::_General_Informations.clear(); - MyGlobals::_General_Informations.push_back(SerializeFromString("finalMeshName=2D")); - new_collection.write( xmlName ); - } - - // Check that "groups and family handling is NOT bugged" - - MeshCollection new_collection(std::string(xmlName)+".xml"); - std::map< int, int > famId2nb; // count total nb of cells in divided families - std::map< int, int >::iterator id2nn; - { - const std::vector<ParaMEDMEM::DataArrayInt*>& famIdsVec = new_collection.getCellFamilyIds(); - for ( size_t i = 0; i < famIdsVec.size(); ++i ) - { - ParaMEDMEM::DataArrayInt* famIdsArr = famIdsVec[i]; - for ( int j = famIdsArr->getNbOfElems()-1; j >= 0; --j ) - { - id2nn = famId2nb.insert( make_pair( famIdsArr->getPointer()[j], 0 )).first; - id2nn->second++; - } - } - } - CPPUNIT_ASSERT_EQUAL( 3, (int) famId2nb.size() ); // 3 fams/groups in all - CPPUNIT_ASSERT_EQUAL( 1, (int) famId2nb.count( 0 )); - CPPUNIT_ASSERT_EQUAL( 1, (int) famId2nb.count( idFam1 )); - CPPUNIT_ASSERT_EQUAL( 1, (int) famId2nb.count( idFam2 )); - CPPUNIT_ASSERT_EQUAL( nbFam1, famId2nb[ idFam1 ]); - CPPUNIT_ASSERT_EQUAL( nbFam2, famId2nb[ idFam2 ]); - CPPUNIT_ASSERT_EQUAL( nbc - nbFam1 - nbFam2, famId2nb[ 0 ]); - - // Check that "creates boundary faces option is handled" - - famId2nb.clear(); - const std::vector<ParaMEDMEM::DataArrayInt*>& famIdsVec = new_collection.getFaceFamilyIds(); - for ( size_t i = 0; i < famIdsVec.size(); ++i ) - { - ParaMEDMEM::DataArrayInt* famIdsArr = famIdsVec[i]; - for ( int j = famIdsArr->getNbOfElems()-1; j >= 0; --j ) - { - id2nn = famId2nb.insert( make_pair( famIdsArr->getPointer()[j], 0 )).first; - id2nn->second++; - } - } - - CPPUNIT_ASSERT( !famId2nb.empty() ); - - // for each "JOINT_n_p_..." group there must be "JOINT_p_n_..." group - // of the same size - std::map<std::string,int>& famName2id = new_collection.getFamilyInfo(); - std::map<std::string,int>::iterator na2id = famName2id.begin(), na2id2; - std::set< int > okFamIds; - okFamIds.insert(0); - for ( ; na2id != famName2id.end(); ++na2id ) - { - if ( okFamIds.count( na2id->second ) || na2id->first[0] != 'J') - continue; - na2id2 = na2id; - bool groupOK = false; - while ( !groupOK && ++na2id2 != famName2id.end() ) - groupOK = ( na2id2->first.find_first_not_of( na2id->first ) == std::string::npos ); - - CPPUNIT_ASSERT( groupOK ); - CPPUNIT_ASSERT( na2id->second != na2id2->second); - CPPUNIT_ASSERT_EQUAL( 1, (int) famId2nb.count( na2id2->second )); - CPPUNIT_ASSERT_EQUAL( 1, (int) famId2nb.count( na2id->second )); - CPPUNIT_ASSERT_EQUAL( (int) famId2nb[ na2id2->second ], - (int) famId2nb[ na2id->second ]); - okFamIds.insert( na2id2->second ); - } -} diff --git a/src/MEDPartitioner/Test/MEDPARTITIONERTest.hxx b/src/MEDPartitioner/Test/MEDPARTITIONERTest.hxx deleted file mode 100644 index 5e437cb32..000000000 --- a/src/MEDPartitioner/Test/MEDPARTITIONERTest.hxx +++ /dev/null @@ -1,142 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 -// 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 __MEDPARTITIONERTEST_HXX__ -#define __MEDPARTITIONERTEST_HXX__ - -#ifdef WIN32 -# if defined MEDPARTITIONERTEST_EXPORTS || defined MEDPARTITIONERTest_EXPORTS -# define MEDPARTITIONERTEST_EXPORT __declspec( dllexport ) -# else -# define MEDPARTITIONERTEST_EXPORT __declspec( dllimport ) -# endif -#else -# define MEDPARTITIONERTEST_EXPORT -#endif - - -#include <cppunit/extensions/HelperMacros.h> - -#include <set> -#include <string> -#include <iostream> - -#include "MEDCouplingUMesh.hxx" -#include "MEDCouplingExtrudedMesh.hxx" -#include "MEDCouplingFieldDouble.hxx" - -class MEDPARTITIONERTEST_EXPORT MEDPARTITIONERTest : public CppUnit::TestFixture -{ - CPPUNIT_TEST_SUITE( MEDPARTITIONERTest ); - CPPUNIT_TEST( testMeshCollectionSingle ); - CPPUNIT_TEST( testMeshCollectionXml ); -#if defined(MED_ENABLE_METIS) - CPPUNIT_TEST( testMeshCollectionSinglePartitionMetis ); - CPPUNIT_TEST( testMeshCollectionComplexPartitionMetis ); - CPPUNIT_TEST( testMetisSmallSize ); -#endif -#if defined(MED_ENABLE_SCOTCH) - CPPUNIT_TEST( testMeshCollectionSinglePartitionScotch ); - CPPUNIT_TEST( testMeshCollectionComplexPartitionScotch ); - CPPUNIT_TEST( testScotchSmallSize ); -#endif - -#if defined(HAVE_MPI) -#if defined(MED_ENABLE_PARMETIS) - //test with mpi on system - CPPUNIT_TEST( testMpirunSmallSize ); - CPPUNIT_TEST( testMpirunMedianSize ); - CPPUNIT_TEST( testMpirunHugeSize ); -#endif -#endif - - CPPUNIT_TEST( testCreateBoundaryFaces2D ); // imp 0021756 - - //CPPUNIT_TEST( deleteTestMeshes ); - CPPUNIT_TEST_SUITE_END(); - -public: - - //global use - int _ni; //nb of hexa9 - int _nj; - int _nk; - int _ntot; - std::string _file_name; //initial test mesh file med CUBE3D - std::string _file_name_with_faces; //initial test mesh file med CUBE3D plus a set of faces - std::string _file_name2; //initial test mesh file med CARRE3D - std::string _file_name_huge_xml; - int _nb_target_huge; - std::string _mesh_name; //initial test mesh file med - int _verbose; - - //for utils - void setSize(int ni, int nj, int nk); - void setSmallSize(); - void setMedianSize(); - void setbigSize(); - std::string getPartitionerExe() const; - ParaMEDMEM::MEDCouplingUMesh * buildCUBE3DMesh(); - ParaMEDMEM::MEDCouplingUMesh * buildFACE3DMesh(); - ParaMEDMEM::MEDCouplingUMesh * buildCARRE3DMesh(); - ParaMEDMEM::MEDCouplingFieldDouble * buildVecFieldOnCells(std::string myfileName); - ParaMEDMEM::MEDCouplingFieldDouble * buildVecFieldOnNodes(); - void createTestMeshWithoutField(); - void createTestMeshWithVecFieldOnCells(); - void createTestMeshWithVecFieldOnNodes(); - void verifyTestMeshWithVecFieldOnNodes(); - void verifyMetisOrScotchMedpartitionerOnSmallSizeForMesh(std::string MetisOrScotch); - void verifyMetisOrScotchMedpartitionerOnSmallSizeForFieldOnCells(std::string MetisOrScotch); - void verifyMetisOrScotchMedpartitionerOnSmallSizeForFieldOnGaussNe(std::string MetisOrScotch); - void verifyMedpartitionerOnSmallSizeForMesh(); - void verifyMedpartitionerOnSmallSizeForFieldOnCells(); - void verifyMedpartitionerOnSmallSizeForFieldOnGaussNe(); - void createTestMeshes(); - void createHugeTestMesh(int ni, int nj, int nk, int nbx, int nby, int nbz, int nbTarget); - void launchMetisOrScotchMedpartitionerOnTestMeshes(std::string MetisOrScotch); - void launchMedpartitionerOnTestMeshes(); - void launchMedpartitionerOnHugeTestMeshes(); - void deleteTestMeshes(); - - //for CPPUNIT_TEST - void setUp(); - void tearDown(); - void testMeshCollectionSingle(); - void testMeshCollectionXml(); -#if defined(MED_ENABLE_METIS) - void testMeshCollectionSinglePartitionMetis(); - void testMeshCollectionComplexPartitionMetis(); - void testMetisSmallSize(); -#endif -#if defined(MED_ENABLE_SCOTCH) - void testMeshCollectionSinglePartitionScotch(); - void testMeshCollectionComplexPartitionScotch(); - void testScotchSmallSize(); -#endif - -#if defined(HAVE_MPI) - void testMpirunSmallSize(); - void testMpirunMedianSize(); - void testMpirunHugeSize(); -#endif - - void testCreateBoundaryFaces2D(); -}; - -#endif diff --git a/src/MEDPartitioner/Test/MEDPARTITIONERTestPara.cxx b/src/MEDPartitioner/Test/MEDPARTITIONERTestPara.cxx deleted file mode 100644 index 5daaa525d..000000000 --- a/src/MEDPartitioner/Test/MEDPARTITIONERTestPara.cxx +++ /dev/null @@ -1,435 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// - -#include "MEDPARTITIONERTest.hxx" - -#include "MEDPARTITIONER_MeshCollection.hxx" -#include "MEDPARTITIONER_ParallelTopology.hxx" -#include "MEDPARTITIONER_ParaDomainSelector.hxx" -#include "MEDPARTITIONER_Utils.hxx" - -#include "CellModel.hxx" -#include "MEDFileMesh.hxx" -#include "MEDLoader.hxx" -#include "MEDLoaderBase.hxx" -#include "MEDCouplingUMesh.hxx" -#include "MEDCouplingExtrudedMesh.hxx" -#include "MEDCouplingFieldDouble.hxx" -#include "MEDCouplingMemArray.hxx" -#include "MEDCouplingMultiFields.hxx" - -#include <cppunit/TestAssert.h> - -#include <sstream> -#include <cmath> -#include <list> -#include <stdexcept> -#include <cstdlib> -#include <vector> - -#include <mpi.h> - -using namespace std; -using namespace ParaMEDMEM; -using namespace MEDPARTITIONER; - -#if defined(HAVE_MPI) -void MEDPARTITIONERTest::verifyMedpartitionerOnSmallSizeForMesh() -{ - int res; - string fileName,cmd,execName,sourceName,targetName,input; - execName=getenv("MED_ROOT_DIR"); //.../INSTALL/MED - execName+="/bin/salome/medpartitioner_para"; - fileName=_file_name_with_faces; - - ParaMEDMEM::MEDFileUMesh* initialMesh=ParaMEDMEM::MEDFileUMesh::New(fileName.c_str(),_mesh_name.c_str()); - ParaMEDMEM::MEDCouplingUMesh* cellMesh=initialMesh->getLevel0Mesh(false); - ParaMEDMEM::MEDCouplingUMesh* faceMesh=initialMesh->getLevelM1Mesh(false); - - cmd="mpirun -np 5 "+execName+" --ndomains=5 --split-method=metis"; //on same proc - sourceName=fileName; - targetName=fileName; - targetName.replace(targetName.find(".med"),4,"_partitionedTo5_"); - cmd+=" --input-file="+sourceName+" --output-file="+targetName+" --verbose="+IntToStr(_verbose); - if (_verbose) cout<<endl<<cmd<<endl; - res=system(cmd.c_str()); - CPPUNIT_ASSERT_EQUAL(0, res); - input=targetName+".xml"; - - MEDPARTITIONER::ParaDomainSelector parallelizer(false); - MEDPARTITIONER::MeshCollection collection(input,parallelizer); - CPPUNIT_ASSERT_EQUAL(3, collection.getMeshDimension()); - std::vector<ParaMEDMEM::MEDCouplingUMesh*>cellMeshes=collection.getMesh(); - CPPUNIT_ASSERT_EQUAL(5, (int) cellMeshes.size()); - int nbcells=0; - for (std::size_t i = 0; i < cellMeshes.size(); i++) - nbcells+=cellMeshes[i]->getNumberOfCells(); - CPPUNIT_ASSERT_EQUAL(cellMesh->getNumberOfCells(), nbcells); - - std::vector<ParaMEDMEM::MEDCouplingUMesh*>faceMeshes=collection.getFaceMesh(); - CPPUNIT_ASSERT_EQUAL(5, (int) faceMeshes.size()); - int nbfaces=0; - for (std::size_t i=0; i < faceMeshes.size(); i++) - nbfaces+=faceMeshes[i]->getNumberOfCells(); - CPPUNIT_ASSERT_EQUAL(faceMesh->getNumberOfCells(), nbfaces); - - //merge split meshes and test equality - cmd="mpirun -np 1 "+execName+" --ndomains=1 --split-method=metis"; //on same proc - sourceName=targetName+".xml"; - targetName=fileName; - targetName.replace(targetName.find(".med"),4,"_remergedFrom5_"); - cmd+=" --input-file="+sourceName+" --output-file="+targetName+" --verbose="+IntToStr(_verbose); - if (_verbose) cout<<endl<<cmd<<endl; - res=system(cmd.c_str()); - CPPUNIT_ASSERT_EQUAL(0, res); - - string refusedName=targetName+"1.med"; - ParaMEDMEM::MEDFileUMesh* refusedMesh=ParaMEDMEM::MEDFileUMesh::New(refusedName.c_str(),_mesh_name.c_str()); - ParaMEDMEM::MEDCouplingUMesh* refusedCellMesh=refusedMesh->getLevel0Mesh(false); - ParaMEDMEM::MEDCouplingUMesh* refusedFaceMesh=refusedMesh->getLevelM1Mesh(false); - - CPPUNIT_ASSERT_EQUAL(cellMesh->getNumberOfCells(), refusedCellMesh->getNumberOfCells()); - CPPUNIT_ASSERT_EQUAL(faceMesh->getNumberOfCells(), refusedFaceMesh->getNumberOfCells()); - - /*not the good job - ParaMEDMEM::MEDCouplingMesh* mergeCell=cellMesh->mergeMyselfWith(refusedCellMesh); - CPPUNIT_ASSERT_EQUAL(cellMesh->getNumberOfCells(), mergeCell->getNumberOfCells()); - - ParaMEDMEM::MEDCouplingMesh* mergeFace=faceMesh->mergeMyselfWith(refusedFaceMesh); - CPPUNIT_ASSERT_EQUAL(faceMesh->getNumberOfCells(), mergeFace->getNumberOfCells()); - - CPPUNIT_ASSERT(faceMesh->isEqual(refusedFaceMesh,1e-12)); - */ - - std::vector<const MEDCouplingUMesh *> meshes; - std::vector<DataArrayInt *> corr; - meshes.push_back(cellMesh); - refusedCellMesh->tryToShareSameCoordsPermute(*cellMesh, 1e-9); - meshes.push_back(refusedCellMesh); - MEDCouplingUMesh* fusedCell=MEDCouplingUMesh::FuseUMeshesOnSameCoords(meshes,0,corr); - CPPUNIT_ASSERT_EQUAL(cellMesh->getNumberOfCells(), fusedCell->getNumberOfCells()); - - meshes.resize(0); - for (std::size_t i = 0; i < corr.size(); i++) - corr[i]->decrRef(); - corr.resize(0); - meshes.push_back(faceMesh); - refusedFaceMesh->tryToShareSameCoordsPermute(*faceMesh, 1e-9); - meshes.push_back(refusedFaceMesh); - MEDCouplingUMesh* fusedFace=MEDCouplingUMesh::FuseUMeshesOnSameCoords(meshes,0,corr); - CPPUNIT_ASSERT_EQUAL(faceMesh->getNumberOfCells(), fusedFace->getNumberOfCells()); - - for (std::size_t i = 0; i < corr.size(); i++) - corr[i]->decrRef(); - fusedFace->decrRef(); - refusedFaceMesh->decrRef(); - faceMesh->decrRef(); - fusedCell->decrRef(); - refusedCellMesh->decrRef(); - cellMesh->decrRef(); - //done in ~collection - //for (int i = 0; i < faceMeshes.size(); i++) faceMeshes[i]->decrRef(); - //for (int i = 0; i < cellMeshes.size(); i++) cellMeshes[i]->decrRef(); -} - -void MEDPARTITIONERTest::verifyMedpartitionerOnSmallSizeForFieldOnCells() -{ - int res; - string fileName,cmd,execName,sourceName,targetName,input; - execName=getenv("MED_ROOT_DIR"); //.../INSTALL/MED - execName+="/bin/salome/medpartitioner_para"; - fileName=_file_name; - fileName.replace(fileName.find(".med"),4,"_WithVecFieldOnCells.med"); - - ParaMEDMEM::MEDFileUMesh* initialMesh=ParaMEDMEM::MEDFileUMesh::New(fileName.c_str(),_mesh_name.c_str()); - ParaMEDMEM::MEDCouplingUMesh* cellMesh=initialMesh->getLevel0Mesh(false); - - cmd="mpirun -np 5 "+execName+" --ndomains=5 --split-method=metis"; //on same proc - sourceName=fileName; - targetName=fileName; - targetName.replace(targetName.find(".med"),4,"_partitionedTo5_"); - cmd+=" --input-file="+sourceName+" --output-file="+targetName+" --verbose="+IntToStr(_verbose); - if (_verbose) cout<<endl<<cmd<<endl; - res=system(cmd.c_str()); - CPPUNIT_ASSERT_EQUAL(0, res); - input=targetName+".xml"; - - //merge split meshes and test equality - cmd="mpirun -np 1 "+execName+" --ndomains=1 --split-method=metis"; //on same proc - sourceName=targetName+".xml"; - targetName=fileName; - targetName.replace(targetName.find(".med"),4,"_remergedFrom5_"); - cmd+=" --input-file="+sourceName+" --output-file="+targetName+" --verbose="+IntToStr(_verbose); - if (_verbose) cout<<endl<<cmd<<endl; - res=system(cmd.c_str()); - CPPUNIT_ASSERT_EQUAL(0, res); - - string refusedName=targetName+"1.med"; - ParaMEDMEM::MEDFileUMesh* refusedMesh=ParaMEDMEM::MEDFileUMesh::New(refusedName.c_str(),_mesh_name.c_str()); - ParaMEDMEM::MEDCouplingUMesh* refusedCellMesh=refusedMesh->getLevel0Mesh(false); - - CPPUNIT_ASSERT_EQUAL(cellMesh->getNumberOfCells(), refusedCellMesh->getNumberOfCells()); - - std::vector<const MEDCouplingUMesh *> meshes; - std::vector<DataArrayInt *> corr; - meshes.push_back(cellMesh); - refusedCellMesh->tryToShareSameCoordsPermute(*cellMesh, 1e-9); - meshes.push_back(refusedCellMesh); - MEDCouplingUMesh* fusedCell=MEDCouplingUMesh::FuseUMeshesOnSameCoords(meshes,0,corr); - CPPUNIT_ASSERT_EQUAL(cellMesh->getNumberOfCells(), fusedCell->getNumberOfCells()); - - MEDCouplingFieldDouble* field1=MEDLoader::ReadFieldCell(fileName.c_str(),initialMesh->getName().c_str(),0,"VectorFieldOnCells",0,1); - MEDCouplingFieldDouble* field2=MEDLoader::ReadFieldCell(refusedName.c_str(),refusedCellMesh->getName().c_str(),0,"VectorFieldOnCells",0,1); - - int nbcells=corr[1]->getNumberOfTuples(); - CPPUNIT_ASSERT_EQUAL(cellMesh->getNumberOfCells(), nbcells); - //use corr to test equality of field - DataArrayDouble* f1=field1->getArray(); - DataArrayDouble* f2=field2->getArray(); - if (_verbose>300) - { - cout<<"\nf1 : "<<f1->reprZip(); - cout<<"\nf2 : "<<f2->reprZip(); //field2->advancedRepradvancedRepr(); - for (std::size_t i = 0; i < corr.size(); i++) - cout << "\ncorr " << i << " : " << corr[i]->reprZip(); - - } - int nbequal=0; - int nbcomp=field1->getNumberOfComponents(); - double* p1=f1->getPointer(); - double* p2=f2->getPointer(); - int* pc=corr[1]->getPointer(); - for (int i = 0; i < nbcells; i++) - { - int i1=pc[i]*nbcomp; - int i2=i*nbcomp; - for (int j = 0; j < nbcomp; j++) - { - if (p1[i1+j]==p2[i2+j]) nbequal++; - //cout<<" "<<p1[i1+j]<<"="<<p2[i2+j]; - } - } - CPPUNIT_ASSERT_EQUAL(nbcells*nbcomp, nbequal); - - for (std::size_t i = 0; i < corr.size(); i++) - corr[i]->decrRef(); - field1->decrRef(); - field2->decrRef(); - fusedCell->decrRef(); - refusedCellMesh->decrRef(); - cellMesh->decrRef(); -} - -void MEDPARTITIONERTest::verifyMedpartitionerOnSmallSizeForFieldOnGaussNe() -{ - int res; - string fileName,cmd,execName,sourceName,targetName,input; - execName=getenv("MED_ROOT_DIR"); //.../INSTALL/MED - execName+="/bin/salome/medpartitioner_para"; - fileName=_file_name; - fileName.replace(fileName.find(".med"),4,"_WithVecFieldOnGaussNe.med"); - - ParaMEDMEM::MEDFileUMesh* initialMesh=ParaMEDMEM::MEDFileUMesh::New(fileName.c_str(),_mesh_name.c_str()); - ParaMEDMEM::MEDCouplingUMesh* cellMesh=initialMesh->getLevel0Mesh(false); - - cmd="mpirun -np 5 "+execName+" --ndomains=5 --split-method=metis"; //on same proc - sourceName=fileName; - targetName=fileName; - targetName.replace(targetName.find(".med"),4,"_partitionedTo5_"); - cmd+=" --input-file="+sourceName+" --output-file="+targetName+" --verbose="+IntToStr(_verbose); - if (_verbose) cout<<endl<<cmd<<endl; - res=system(cmd.c_str()); - CPPUNIT_ASSERT_EQUAL(0, res); - input=targetName+".xml"; - - //merge split meshes and test equality - cmd="mpirun -np 1 "+execName+" --ndomains=1 --split-method=metis"; //on same proc - sourceName=targetName+".xml"; - targetName=fileName; - targetName.replace(targetName.find(".med"),4,"_remergedFrom5_"); - cmd+=" --input-file="+sourceName+" --output-file="+targetName+" --verbose="+IntToStr(_verbose); - if (_verbose) cout<<endl<<cmd<<endl; - res=system(cmd.c_str()); - CPPUNIT_ASSERT_EQUAL(0, res); - - string refusedName=targetName+"1.med"; - ParaMEDMEM::MEDFileUMesh* refusedMesh=ParaMEDMEM::MEDFileUMesh::New(refusedName.c_str(),_mesh_name.c_str()); - ParaMEDMEM::MEDCouplingUMesh* refusedCellMesh=refusedMesh->getLevel0Mesh(false); - - CPPUNIT_ASSERT_EQUAL(cellMesh->getNumberOfCells(), refusedCellMesh->getNumberOfCells()); - - std::vector<const MEDCouplingUMesh *> meshes; - std::vector<DataArrayInt *> corr; - meshes.push_back(cellMesh); - refusedCellMesh->tryToShareSameCoordsPermute(*cellMesh, 1e-9); - meshes.push_back(refusedCellMesh); - MEDCouplingUMesh* fusedCell=MEDCouplingUMesh::FuseUMeshesOnSameCoords(meshes,0,corr); - CPPUNIT_ASSERT_EQUAL(cellMesh->getNumberOfCells(), fusedCell->getNumberOfCells()); - - MEDCouplingFieldDouble* field1=MEDLoader::ReadField(ON_GAUSS_NE,fileName.c_str(),initialMesh->getName().c_str(),0,"MyFieldOnGaussNE",5,6); - MEDCouplingFieldDouble* field2=MEDLoader::ReadField(ON_GAUSS_NE,refusedName.c_str(),refusedCellMesh->getName().c_str(),0,"MyFieldOnGaussNE",5,6); - - int nbcells=corr[1]->getNumberOfTuples(); - CPPUNIT_ASSERT_EQUAL(cellMesh->getNumberOfCells(), nbcells); - //use corr to test equality of field - DataArrayDouble* f1=field1->getArray(); - DataArrayDouble* f2=field2->getArray(); - if (_verbose>300) - { - cout << "\nf1 : " << f1->reprZip(); //123.4 for 12th cell,3rd component, 4th gausspoint - cout << "\nf2 : " << f2->reprZip(); //field2->advancedRepradvancedRepr(); - for (std::size_t i = 0; i < corr.size(); i++) - cout << "\ncorr " << i << " : " << corr[i]->reprZip(); - - } - int nbequal=0; - int nbptgauss=8; - int nbcomp=field1->getNumberOfComponents(); - double* p1=f1->getPointer(); - double* p2=f2->getPointer(); - int* pc=corr[1]->getPointer(); - for (int i = 0; i < nbcells; i++) - { - int i1=pc[i]*nbcomp*nbptgauss; - int i2=i*nbcomp*nbptgauss; - for (int j = 0; j < nbcomp*nbptgauss; j++) - { - if (p1[i1+j]==p2[i2+j]) nbequal++; - //cout<<" "<<p1[i1+j]<<"="<<p2[i2+j]; - } - } - CPPUNIT_ASSERT_EQUAL(nbcells*nbcomp*nbptgauss, nbequal); - - for (std::size_t i = 0; i < corr.size(); i++) - corr[i]->decrRef(); - field1->decrRef(); - field2->decrRef(); - fusedCell->decrRef(); - refusedCellMesh->decrRef(); - cellMesh->decrRef(); -} - -void MEDPARTITIONERTest::launchMedpartitionerOnTestMeshes() -{ - - /* examples - export INFI=/home/vb144235/resources/blade.med - //no need export MESH=Fuse_1 - export INFI=tmp_testMeshxxx.med - //no need export MESH=testMesh - mpirun -np 2 medpartitioner_para --input-file=$INFI --output-file=ttmp1_ --ndomains=4 - mpirun -np 5 medpartitioner_para --input-file=ttmp1_.xml --output-file=ttmp2_ --ndomains=5 - mpirun -np 2 valgrind medpartitioner_para --input-file=tmp_testMesh_20x30x50.med --output-file=ttmp1petit_ --ndomains=4 --dump-cpu-memory --verbose=111 - */ - int res; - string cmd,execName,sourceName,targetName; - - res=system("which mpirun 2>/dev/null 1>/dev/null"); //no trace - CPPUNIT_ASSERT_EQUAL(0, res); - - execName=getenv("MED_ROOT_DIR"); //.../INSTALL/MED - execName+="/bin/salome/medpartitioner_para"; - - cmd="which "+execName+" 2>/dev/null 1>/dev/null"; //no trace - res=system(cmd.c_str()); - CPPUNIT_ASSERT_EQUAL(0, res); - - cmd="mpirun -np 2 "+execName+" --ndomains=2 --split-method=metis"; //on same proc - sourceName=_file_name; - targetName=_file_name; - targetName.replace(targetName.find(".med"),4,"_partitionedTo2_"); - cmd+=" --input-file="+sourceName+" --output-file="+targetName+" --verbose="+IntToStr(_verbose); - if (_verbose) cout<<endl<<cmd<<endl; - res=system(cmd.c_str()); - CPPUNIT_ASSERT_EQUAL(0, res); - - cmd="mpirun -np 3 "+execName+" --ndomains=5 --split-method=metis"; //on less proc - sourceName=_file_name; - targetName=_file_name; - targetName.replace(targetName.find(".med"),4,"_partitionedTo5_"); - cmd+=" --input-file="+sourceName+" --output-file="+targetName+" --verbose="+IntToStr(_verbose); - if (_verbose) cout<<endl<<cmd<<endl; - res=system(cmd.c_str()); - CPPUNIT_ASSERT_EQUAL(0, res); - - cmd="mpirun -np 1 "+execName+" --ndomains=1 --split-method=metis"; //on 1 proc - sourceName=targetName+".xml"; - targetName=_file_name; - targetName.replace(targetName.find(".med"),4,"_remergedFrom5_"); - cmd+=" --input-file="+sourceName+" --output-file="+targetName+" --verbose="+IntToStr(_verbose); - if (_verbose) cout<<endl<<cmd<<endl; - res=system(cmd.c_str()); - CPPUNIT_ASSERT_EQUAL(0, res); - - cmd="mpirun -np 8 "+execName+" --ndomains=1 --split-method=metis"; //on more proc - //sourceName=targetName+".xml"; - targetName=_file_name; - targetName.replace(targetName.find(".med"),4,"_remergedFrom5_"); - cmd+=" --input-file="+sourceName+" --output-file="+targetName+" --verbose="+IntToStr(_verbose); - if (_verbose) cout<<endl<<cmd<<endl; - res=system(cmd.c_str()); - CPPUNIT_ASSERT_EQUAL(0, res); -} - -void MEDPARTITIONERTest::launchMedpartitionerOnHugeTestMeshes() -{ - int res=0; - string cmd,execName,sourceName,targetName; - execName=getenv("MED_ROOT_DIR"); //.../INSTALL/MED - execName+="/bin/salome/medpartitioner_para"; - - string snbTarget=IntToStr(_nb_target_huge); - cmd="mpirun -np "+snbTarget+" "+execName+" --ndomains="+snbTarget+" --split-method=metis"; //on same proc - sourceName=_file_name_huge_xml; - targetName=_file_name_huge_xml; - string tmp="_partitionedTo"+snbTarget+"_"; - targetName.replace(targetName.find(".xml"),4,tmp); - cmd+=" --input-file="+sourceName+" --output-file="+targetName+" --verbose="+IntToStr(_verbose); - if (_verbose) cout<<endl<<cmd<<endl; - res=system(cmd.c_str()); - CPPUNIT_ASSERT_EQUAL(0, res); -} - -void MEDPARTITIONERTest::testMpirunSmallSize() -{ - setSmallSize(); - createTestMeshes(); - launchMedpartitionerOnTestMeshes(); - verifyMedpartitionerOnSmallSizeForMesh(); - verifyMedpartitionerOnSmallSizeForFieldOnCells(); - verifyMedpartitionerOnSmallSizeForFieldOnGaussNe(); -} - -void MEDPARTITIONERTest::testMpirunMedianSize() -{ - setMedianSize(); - createTestMeshes(); - launchMedpartitionerOnTestMeshes(); -} - -void MEDPARTITIONERTest::testMpirunHugeSize() -{ - //setBigSize(); //may be a lot for now - setMedianSize(); - //create a set of nbx*nby*nbz files mesh of ni*ny*nz cells - //_verbose=1; - createHugeTestMesh(_ni, _nj, _nk, 2, 2, 2, 32); //it is now to know how far we are going to test - launchMedpartitionerOnHugeTestMeshes(); -} -#endif diff --git a/src/MEDPartitioner/Test/TestMEDPARTITIONER.cxx b/src/MEDPartitioner/Test/TestMEDPARTITIONER.cxx deleted file mode 100644 index a46dd0a4a..000000000 --- a/src/MEDPartitioner/Test/TestMEDPARTITIONER.cxx +++ /dev/null @@ -1,27 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// - -//include all MEDPARTITIONER Test -#include "MEDPARTITIONERTest.hxx" - -//Registers the fixture into the 'registry' -CPPUNIT_TEST_SUITE_REGISTRATION( MEDPARTITIONERTest ); - -//generic Main program from KERNEL_SRC/src/Basics/Test -#include "BasicMainTest.hxx" diff --git a/src/MEDPartitioner/medpartitioner.cxx b/src/MEDPartitioner/medpartitioner.cxx deleted file mode 100644 index 48b90a7d4..000000000 --- a/src/MEDPartitioner/medpartitioner.cxx +++ /dev/null @@ -1,310 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 -// 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 -// - -/* - examples of launch - export verb=1 - medpartitioner --input-file=blade.med --output-file=ttmp1_ --ndomains=2 --dump-cpu-memory --verbose=$verb - medpartitioner --input-file=medpartitioner_blade.xml --output-file=ttmp1_ --ndomains=2 --dump-cpu-memory --verbose=$verb - medpartitioner --input-file=ttmp1_.xml --output-file=tttmp1_ --ndomains=4 --dump-cpu-memory --verbose=$verb -*/ - -/* -#include "MEDPARTITIONER_Graph.hxx" -#include "MEDPARTITIONER_Topology.hxx" -#include "MEDPARTITIONER_ParaDomainSelector.hxx" -#include "MEDPARTITIONER_MeshCollection.hxx" -#include "MEDPARTITIONER_Utils.hxx" -*/ - -#include "MEDPARTITIONER_MeshCollection.hxx" -#include "MEDPARTITIONER_ParallelTopology.hxx" -#include "MEDPARTITIONER_ParaDomainSelector.hxx" -#include "MEDPARTITIONER_Utils.hxx" - -#include <string> -#include <fstream> -#include <cstring> -#include <cstdlib> -#include <iostream> - -using namespace std; -using namespace MEDPARTITIONER; - -int main(int argc, char** argv) -{ -#if !defined(MED_ENABLE_METIS) && !defined(MED_ENABLE_SCOTCH) - std::cout << "Sorry, no one split method is available. Please, compile with METIS or SCOTCH." << std::endl; - return 1; -#else - - // Defining options - // by parsing the command line - - bool split_family=false; - bool empty_groups=false; - bool mesure_memory=false; - bool filter_face=true; - - string input; - string output; - string meshname; - string library="metis"; //default - int ndomains; - int help=0; - - //sequential : no MPI - MyGlobals::_World_Size=1; - MyGlobals::_Rank=0; - MyGlobals::_Creates_Boundary_Faces=0; - MyGlobals::_Create_Joints=0; - - // Primitive parsing of command-line options - string desc ("Available options of medpartitioner V1.0:\n" - "\t--help : produces this help message\n" - "\t--verbose : echoes arguments\n" - "\t--input-file=<string> : name of the input .med file or .xml master file\n" - "\t--output-file=<string> : name of the resulting file (without extension)\n" - "\t--ndomains=<number> : number of subdomains in the output file, default is 1\n" -#if defined(MED_ENABLE_METIS) && defined(MED_ENABLE_SCOTCH) - //user can choose! - "\t--split-method=<string> : name of the splitting library (metis/scotch), default is metis\n" -#endif - "\t--creates-boundary-faces : creates boundary faces mesh in the output files\n" - "\t--creates-joints : creates joints in the output files\n" - "\t--dump-cpu-memory : dumps passed CPU time and maximal increase of used memory\n" - ); - - if (argc<=1) help=1; - string value; - for (int i = 1; i < argc; i++) - { - if (strlen(argv[i]) < 3) - { - cerr << "bad argument : "<< argv[i] << endl; - return 1; - } - - if (TestArg(argv[i],"--verbose",value)) - { - MyGlobals::_Verbose=1; - if (value!="") MyGlobals::_Verbose = atoi(value.c_str()); - } - else if (TestArg(argv[i],"--help",value)) help=1; -// else if (TestArg(argv[i],"--test",value)) test=1; - else if (TestArg(argv[i],"--input-file",value)) input=value; - else if (TestArg(argv[i],"--output-file",value)) output=value; - else if (TestArg(argv[i],"--split-method",value)) library=value; - else if (TestArg(argv[i],"--ndomains",value)) ndomains=atoi(value.c_str()); - else if (TestArg(argv[i],"--creates-boundary-faces",value)) MyGlobals::_Creates_Boundary_Faces=1; - else if (TestArg(argv[i],"--create-joints",value)) MyGlobals::_Create_Joints=1; - else if (TestArg(argv[i],"--dump-cpu-memory",value)) mesure_memory=true; - else - { - cerr << "unknown argument : "<< argv[i] << endl; - return 1; - } - } - - MyGlobals::_Is0verbose=MyGlobals::_Verbose; - -//no choice -#if defined(MED_ENABLE_METIS) && !defined(MED_ENABLE_SCOTCH) - library = "metis"; -#endif -#if !defined(MED_ENABLE_METIS) && defined(MED_ENABLE_SCOTCH) - library = "scotch"; -#endif -//user choice -#if defined(MED_ENABLE_METIS) && defined(MED_ENABLE_SCOTCH) - if ((library!="metis") && (library!="scotch")) - { - cerr << "split-method only available : metis, scotch" << endl; - return 1; - } -#endif - - if (help==1) - { - cout<<desc<<"\n"; - return 0; - } - - if (MyGlobals::_Is0verbose) - { - cout << "medpartitioner V1.0 :" << endl; - cout << " input-file = " << input << endl; - cout << " output-file = " << output << endl; - cout << " split-method = " << library << endl; - cout << " ndomains = " << ndomains << endl; - cout << " creates_boundary_faces = " << MyGlobals::_Creates_Boundary_Faces << endl; - cout << " create-joints = " << MyGlobals::_Create_Joints<< endl; - cout << " dump-cpu-memory = " << mesure_memory<< endl; - cout << " verbose = " << MyGlobals::_Verbose << endl; - } - //testing whether it is possible to write a file at the specified location - if (MyGlobals::_Rank==0) - { - string outputtest = output + ".testioms."; - ofstream testfile (outputtest.c_str()); - if (testfile.fail()) - { - cerr << "output-file directory does not exist or is in read-only access" << endl; - return 1; - } - //deletes test file - remove(outputtest.c_str()); - } - - // Beginning of the computation - - // Loading the mesh collection - if (MyGlobals::_Is0verbose) cout << "Reading input files "<<endl; - - try - { - /*MEDPARTITIONER::ParaDomainSelector parallelizer(mesure_memory); - MEDPARTITIONER::MeshCollection collection(input,parallelizer); - MEDPARTITIONER::ParallelTopology* aPT = (MEDPARTITIONER::ParallelTopology*) collection.getTopology(); - aPT->setGlobalNumerotationDefault(collection.getParaDomainSelector()); - //int nbfiles=MyGlobals::_fileMedNames->size(); //nb domains - //to have unique valid fields names/pointers/descriptions for partitionning - collection.prepareFieldDescriptions(); - //int nbfields=collection.getFieldDescriptions().size(); //on all domains - //cout<<ReprVectorOfString(collection.getFieldDescriptions()); - - if (MyGlobals::_Is0verbose) - { - cout<<"fileNames :"<<endl - <<ReprVectorOfString(MyGlobals::_File_Names); - cout<<"fieldDescriptions :"<<endl - <<ReprFieldDescriptions(collection.getFieldDescriptions()," "); //cvwat07 - cout<<"familyInfo :\n" - <<ReprMapOfStringInt(collection.getFamilyInfo())<<endl; - cout<<"groupInfo :\n" - <<ReprMapOfStringVectorOfString(collection.getGroupInfo())<<endl; - }*/ - MEDPARTITIONER::ParaDomainSelector parallelizer(mesure_memory); - MEDPARTITIONER::MeshCollection collection(input,parallelizer); - MEDPARTITIONER::ParallelTopology* aPT = (MEDPARTITIONER::ParallelTopology*) collection.getTopology(); - aPT->setGlobalNumerotationDefault(collection.getParaDomainSelector()); - //to have unique valid fields names/pointers/descriptions for partitionning - collection.prepareFieldDescriptions(); - - //MEDPARTITIONER::MeshCollection collection(input); - - //Creating the graph and partitioning it - if (MyGlobals::_Is0verbose) cout << "Computing partition with " << library << endl; - - auto_ptr< MEDPARTITIONER::Topology > new_topo; - if (library == "metis") - new_topo.reset( collection.createPartition(ndomains,MEDPARTITIONER::Graph::METIS)); - else - new_topo.reset( collection.createPartition(ndomains,MEDPARTITIONER::Graph::SCOTCH)); - parallelizer.evaluateMemory(); - - //Creating a new mesh collection from the partitioning - if (MyGlobals::_Is0verbose) cout << "Creating new meshes"<< endl; - MEDPARTITIONER::MeshCollection new_collection(collection,new_topo.get(),split_family,empty_groups); - - if (filter_face) new_collection.filterFaceOnCell(); - - //to get infos on all procs - - //see meshName - vector<string> finalInformations; - vector<string> r1,r2; - //r1=AllgathervVectorOfString(MyGlobals::_General_Informations); - r1=MyGlobals::_General_Informations; - //if (MyGlobals::_Is0verbose>1000) cout << "generalInformations : \n"<<ReprVectorOfString(r1); - r2=SelectTagsInVectorOfString(r1,"ioldDomain="); - r2=SelectTagsInVectorOfString(r2,"meshName="); - if (r2.size()==(collection.getMesh()).size()) - { - for (std::size_t i=0; i<r2.size(); i++) - r2[i]=EraseTagSerialized(r2[i],"ioldDomain="); - r2=DeleteDuplicatesInVectorOfString(r2); - if (r2.size()==1) - { - string finalMesh="finalMeshName="+ExtractFromDescription(r2[0], "meshName="); - finalInformations.push_back(SerializeFromString(finalMesh)); - } - } - if (finalInformations.size()==0) - { - if (MyGlobals::_Rank==0) - cerr<<"Problem on final meshName : set at 'Merge'"<<endl; - finalInformations.push_back(SerializeFromString("finalMeshName=Merge")); - } - - //see field info nbComponents & componentInfo (if fields present) - r2=SelectTagsInVectorOfString(r1,"fieldName="); - r2=SelectTagsInVectorOfString(r2,"nbComponents="); - //may be yes? or not? - for (std::size_t i=0; i<r2.size(); i++) - r2[i]=EraseTagSerialized(r2[i],"ioldFieldDouble="); - r2=DeleteDuplicatesInVectorOfString(r2); - for (std::size_t i=0; i<r2.size(); i++) - finalInformations.push_back(r2[i]); - - MyGlobals::_General_Informations=finalInformations; - if (MyGlobals::_Is0verbose) - cout << "generalInformations : \n"<<ReprVectorOfString(finalInformations); - - //new_collection.setSubdomainBoundaryCreates(creates_boundary_faces); - if (MyGlobals::_Is0verbose) cout << "Writing "<<ndomains<<" output files "<<output<<"xx.med"<<" and "<<output<<".xml"<<endl; - new_collection.write(output); - - /*if ( mesure_memory ) - if ( parallelizer.isOnDifferentHosts() || MyGlobals::_Rank==0 ) - { - cout << "Elapsed time = " << parallelizer.getPassedTime() - << ", max memory usage = " << parallelizer.evaluateMemory() << " KB" - << endl; - }*/ - - if (MyGlobals::_Is0verbose>0) cout<<"OK END"<< endl; - return 0; - } - catch(const char *mess) - { - cerr<<mess<<endl; - fflush(stderr); - return 1; - } - catch(INTERP_KERNEL::Exception& e) - { - cerr<<"INTERP_KERNEL_Exception : "<<e.what()<<endl; - fflush(stderr); - return 1; - } - catch(std::exception& e) - { - cerr<<"std_Exception : "<<e.what()<<endl; - fflush(stderr); - return 1; - } - catch(...) - { - cerr<<"an unknown type exception error was occured"<<endl; - fflush(stderr); - return 1; - } -#endif -} diff --git a/src/MEDPartitioner/medpartitioner_para.cxx b/src/MEDPartitioner/medpartitioner_para.cxx deleted file mode 100644 index 60c3295d2..000000000 --- a/src/MEDPartitioner/medpartitioner_para.cxx +++ /dev/null @@ -1,353 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 -// 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 -// - -/* - examples of launch - rm ttmp* tttmp* - export verb=11 - mpirun -np 2 medpartitioner_para --input-file=blade.med --output-file=ttmp1_ --ndomains=2 --dump-cpu-memory --verbose=$verb - mpirun -np 5 medpartitioner_para --input-file=blade.med --output-file=ttmp1_ --ndomains=2 --dump-cpu-memory --verbose=$verb - mpirun -np 4 medpartitioner_para --input-file=ttmp1_.xml --output-file=tttmp1_ --ndomains=4 --verbose=$verb - - mpirun -np 2 medpartitioner_para --ndomains=2 --input-file=tmp_testMesh_20x30x50.med --output-file=ttmp2_ --verbose=$verb - mpirun -np 2 medpartitioner_para --ndomains=2 --input-file=ttmp2_.xml --output-file=ttmp3_ --verbose=$verb - - mpirun -np 2 medpartitioner_para --ndomains=2 --input-file=tmp_testMeshWithFaces_20x30x50.med --output-file=ttmp2_ --verbose=$verb - mpirun -np 2 medpartitioner_para --ndomains=2 --input-file=ttmp2_.xml --output-file=ttmp3_ --verbose=$verb - - mpirun -np 2 medpartitioner_para --ndomains=2 --input-file=tmp_testMesh_20x30x50_WithVecFieldOnCells.med --output-file=ttmp2_ --verbose=$verb - mpirun -np 2 medpartitioner_para --ndomains=2 --input-file=tmp_testMesh_20x30x50_WithVecFieldOnNodes.med --output-file=ttmp2_ --verbose=$verb - mpirun -np 2 medpartitioner_para --ndomains=2 --input-file=ttmp2_.xml --output-file=ttmp3_ --verbose=$verb - - mpirun -np 4 medpartitioner_para --ndomains=4 --input-file=tmp_testMeshHuge_20x30x50_6.xml --output-file=ttmp3_ --verbose=1 -*/ - - -#include "MEDPARTITIONER_MeshCollection.hxx" -#include "MEDPARTITIONER_ParallelTopology.hxx" -#include "MEDPARTITIONER_ParaDomainSelector.hxx" -#include "MEDPARTITIONER_Utils.hxx" - -#include "MEDLoader.hxx" - -#include <fstream> -#include <iostream> -#include <iomanip> -#include <sstream> -#include <string> -#include <cstring> - -#ifdef HAVE_MPI -#include <mpi.h> -#endif - -using namespace std; -using namespace MEDPARTITIONER; - -int main(int argc, char** argv) -{ -#if !defined(MED_ENABLE_PARMETIS) - cout << "Sorry, no one split method is available. Please, compile with ParMETIS."<<endl; - return 1; -#else - - // Defining options - // by parsing the command line - - bool split_family=false; - bool empty_groups=false; - bool mesure_memory=false; - bool filter_face=true; - - string input; - string output; - string meshname; - string library="metis"; //default - int ndomains; - int help=0; - int test=0; - MPI_Init(&argc,&argv); - MPI_Comm_size(MPI_COMM_WORLD, &MyGlobals::_World_Size); - MPI_Comm_rank(MPI_COMM_WORLD, &MyGlobals::_Rank); - - //cout<<"proc "<<MyGlobals::_Rank<<" of "<<MyGlobals::_World_Size<<endl; //for debug - //TestVectorOfStringMpi(); //cvw - //TestRandomize(); - - //Primitive parsing of command-line options - string desc ("Available options of medpartitioner_para V1.0.3:\n" - "\t--help : produces this help message\n" - "\t--verbose : echoes arguments\n" - "\t--input-file=<string> : name of the input .med file or .xml master file\n" - "\t--output-file=<string> : name of the resulting file (without extension)\n" - "\t--ndomains=<number> : number of subdomains in the output file, default is 1\n" -#if defined(MED_ENABLE_PARMETIS) -// || defined(MED_ENABLE_PTSCOTCH) -//user can choose! (not yet) - "\t--split-method=<string> : name of the splitting library (metis/scotch), default is metis\n" -#endif - "\t--creates-boundary-faces : creates boundary faces mesh in the output files\n" - "\t--dump-cpu-memory : dumps passed CPU time and maximal increase of used memory\n" - //"\t--randomize=<number> : random seed for other partitionning (only on one proc)\n" - //"\t--atomize : do the opposite of a good partitionner (only on one proc)\n" - ); - - if (argc<=1) help=1; - string value; - for (int i = 1; i < argc; i++) - { - if (strlen(argv[i]) < 3) - { - if (MyGlobals::_Rank==0) cerr << "bad argument : "<< argv[i] << endl; - MPI_Finalize(); return 1; - } - - if (TestArg(argv[i],"--verbose",value)) - { - MyGlobals::_Verbose=1; - if (value!="") MyGlobals::_Verbose = atoi(value.c_str()); - } - else if (TestArg(argv[i],"--help",value)) help=1; - else if (TestArg(argv[i],"--test",value)) test=1; - else if (TestArg(argv[i],"--input-file",value)) input=value; - else if (TestArg(argv[i],"--output-file",value)) output=value; - else if (TestArg(argv[i],"--split-method",value)) library=value; - else if (TestArg(argv[i],"--ndomains",value)) ndomains=atoi(value.c_str()); - else if (TestArg(argv[i],"--randomize",value)) MyGlobals::_Randomize=atoi(value.c_str()); - else if (TestArg(argv[i],"--atomize",value)) MyGlobals::_Atomize=atoi(value.c_str()); - else if (TestArg(argv[i],"--creates-boundary-faces",value)) MyGlobals::_Creates_Boundary_Faces=1; - else if (TestArg(argv[i],"--dump-cpu-memory",value)) mesure_memory=true; - else - { - if (MyGlobals::_Rank==0) cerr << "unknown argument : "<< argv[i] << endl; - MPI_Finalize(); return 1; - } - } - - - if (MyGlobals::_Randomize!=0 && MyGlobals::_World_Size!=1) - { - if (MyGlobals::_Rank==0) cerr << "randomize only available on 1 proc (mpirun -np 1)" << endl; - MyGlobals::_Randomize=0; - } - -//no choice -#if defined(MED_ENABLE_PARMETIS) && !defined(MED_ENABLE_SCOTCH) - library = "metis"; -#endif -#if !defined(MED_ENABLE_PARMETIS) && defined(MED_ENABLE_SCOTCH) - library = "scotch"; -#endif -//user choice -#if defined(MED_ENABLE_PARMETIS) && defined(MED_ENABLE_SCOTCH) - if ((library!="metis") && (library!="scotch")) - { - if (MyGlobals::_Rank==0) cerr << "split-method only available : metis, scotch" << endl; - MPI_Finalize(); return 1; - } -#endif - - if (help==1) - { - if (MyGlobals::_Rank==0) cout<<desc<<"\n"; - MPI_Finalize(); return 0; - } - - MyGlobals::_Is0verbose=0; - if (MyGlobals::_Rank==0) MyGlobals::_Is0verbose=MyGlobals::_Verbose; - //MyGlobals::_Is0verbose=((MyGlobals::_Rank==0) && MyGlobals::_Verbose); - if (test==1) //only for debugger - { - if (MyGlobals::_Is0verbose>0) cout<<"tests on "<<MyGlobals::_Atomize<<" "<<ndomains<<endl; - //TestPersistantMpi0To1(MyGlobals::_Atomize, ndomains); - //TestPersistantMpiRing(MyGlobals::_Atomize, ndomains); - TestPersistantMpiRingOnCommSplit(MyGlobals::_Atomize, ndomains); - //MPI_Barrier(MPI_COMM_WORLD); - MPI_Finalize(); - return 0; - TestVectorOfStringMpi(); - TestMapOfStringIntMpi(); - TestMapOfStringVectorOfStringMpi(); - TestDataArrayMpi(); - MPI_Finalize(); - return 1; - } - - if (MyGlobals::_Is0verbose) - { - cout << "medpartitioner_para V1.0 :" << endl; - cout << " input-file = " << input << endl; - cout << " output-file = " << output << endl; - cout << " split-method = " << library << endl; - cout << " ndomains = " << ndomains << endl; - cout << " creates_boundary_faces = " << MyGlobals::_Creates_Boundary_Faces << endl; - cout << " dump-cpu-memory = " << mesure_memory<< endl; - cout << " verbose = " << MyGlobals::_Verbose << endl; - } - //testing whether it is possible to write a file at the specified location - if (MyGlobals::_Rank==0) - { - string outputtest = output + ".testioms."; - ofstream testfile (outputtest.c_str()); - if (testfile.fail()) - { - cerr << "output-file directory does not exist or is in read-only access" << endl; - MPI_Finalize(); return 1; - } - //deletes test file - remove(outputtest.c_str()); - } - - // Beginning of the computation - - // Loading the mesh collection - if (MyGlobals::_Is0verbose) cout << "Reading input files "<<endl; - - try - { - MEDPARTITIONER::ParaDomainSelector parallelizer(mesure_memory); - MEDPARTITIONER::MeshCollection collection(input,parallelizer); - MEDPARTITIONER::ParallelTopology* aPT = (MEDPARTITIONER::ParallelTopology*) collection.getTopology(); - aPT->setGlobalNumerotationDefault(collection.getParaDomainSelector()); - //int nbfiles=MyGlobals::_fileMedNames->size(); //nb domains - //to have unique valid fields names/pointers/descriptions for partitionning - collection.prepareFieldDescriptions(); - //int nbfields=collection.getFieldDescriptions().size(); //on all domains - //cout<<ReprVectorOfString(collection.getFieldDescriptions()); - - if (MyGlobals::_Is0verbose) - { - cout<<"fileNames :"<<endl - <<ReprVectorOfString(MyGlobals::_File_Names); - cout<<"fieldDescriptions :"<<endl - <<ReprFieldDescriptions(collection.getFieldDescriptions()," "); - cout<<"familyInfo :\n" - <<ReprMapOfStringInt(collection.getFamilyInfo())<<endl; - cout<<"groupInfo :\n" - <<ReprMapOfStringVectorOfString(collection.getGroupInfo())<<endl; - } - - //Creating the graph and partitioning it - if (MyGlobals::_Is0verbose) cout << "Computing partition "<< endl; - - auto_ptr< MEDPARTITIONER::Topology > new_topo; - if (library == "metis") - new_topo.reset( collection.createPartition(ndomains,MEDPARTITIONER::Graph::METIS)); - else - new_topo.reset( collection.createPartition(ndomains,MEDPARTITIONER::Graph::SCOTCH)); - parallelizer.evaluateMemory(); - - //Creating a new mesh collection from the partitioning - if (MyGlobals::_Is0verbose) cout << "Creating new meshes"<< endl; - MEDPARTITIONER::MeshCollection new_collection(collection,new_topo.get(),split_family,empty_groups); - //cout<<"proc "<<MyGlobals::_Rank<<" : new_collection done"<<endl; - parallelizer.evaluateMemory(); - - //if (!xml_output_master) new_collection.setDriverType(MEDPARTITIONER::MedAscii); - if (filter_face) new_collection.filterFaceOnCell(); - - //to get infos on all procs - - //see meshName - vector<string> finalInformations; - vector<string> r1,r2; - r1=AllgathervVectorOfString(MyGlobals::_General_Informations); - //if (MyGlobals::_Is0verbose>1000) cout << "generalInformations : \n"<<ReprVectorOfString(r1); - r2=SelectTagsInVectorOfString(r1,"ioldDomain="); - r2=SelectTagsInVectorOfString(r2,"meshName="); - if (r2.size()==(collection.getMesh()).size()) - { - for (std::size_t i=0; i<r2.size(); i++) - r2[i]=EraseTagSerialized(r2[i],"ioldDomain="); - r2=DeleteDuplicatesInVectorOfString(r2); - if (r2.size()==1) - { - string finalMesh="finalMeshName="+ExtractFromDescription(r2[0], "meshName="); - finalInformations.push_back(SerializeFromString(finalMesh)); - } - } - if (finalInformations.size()==0) - { - if (MyGlobals::_Rank==0) - cerr<<"Problem on final meshName : set at 'Merge'"<<endl; - finalInformations.push_back(SerializeFromString("finalMeshName=Merge")); - } - - //see field info nbComponents & componentInfo (if fields present) - r2=SelectTagsInVectorOfString(r1,"fieldName="); - r2=SelectTagsInVectorOfString(r2,"nbComponents="); - //may be yes? or not? - for (std::size_t i=0; i<r2.size(); i++) - r2[i]=EraseTagSerialized(r2[i],"ioldFieldDouble="); - r2=DeleteDuplicatesInVectorOfString(r2); - for (std::size_t i=0; i<r2.size(); i++) - finalInformations.push_back(r2[i]); - - MyGlobals::_General_Informations=finalInformations; - if (MyGlobals::_Is0verbose) - cout << "generalInformations : \n"<<ReprVectorOfString(finalInformations); - - //new_collection.setSubdomainBoundaryCreates(creates_boundary_faces); - if (MyGlobals::_Is0verbose) cout << "Writing "<<ndomains<<" output files "<<output<<"xx.med"<<" and "<<output<<".xml"<<endl; - new_collection.write(output); - - if ( mesure_memory ) - if ( parallelizer.isOnDifferentHosts() || MyGlobals::_Rank==0 ) - { - cout << "Elapsed time = " << parallelizer.getPassedTime() - << ", max memory usage = " << parallelizer.evaluateMemory() << " KB" - << endl; - } - if(MyGlobals::_World_Size>1) - MPI_Barrier(MPI_COMM_WORLD); - if (MyGlobals::_Is0verbose>0) cout<<"OK END"<< endl; - MPI_Finalize(); - return 0; - } - catch(const char *mess) - { - cerr<<"proc "<<MyGlobals::_Rank<<" : "<<mess<<endl; - fflush(stderr); - MPI_Finalize(); - return 1; - } - catch(INTERP_KERNEL::Exception& e) - { - cerr<<"proc "<<MyGlobals::_Rank<<" : INTERP_KERNEL_Exception : "<<e.what()<<endl; - fflush(stderr); - MPI_Finalize(); - return 1; - } - catch(std::exception& e) - { - cerr<<"proc "<<MyGlobals::_Rank<<" : std_Exception : "<<e.what()<<endl; - fflush(stderr); - MPI_Finalize(); - return 1; - } - catch(...) - { - cerr<<"proc "<<MyGlobals::_Rank<<" : an unknown type exception error was occured"<<endl; - fflush(stderr); - MPI_Finalize(); - return 1; - } -#endif -} - diff --git a/src/MEDPartitioner_Swig/CMakeLists.txt b/src/MEDPartitioner_Swig/CMakeLists.txt deleted file mode 100644 index f203e7295..000000000 --- a/src/MEDPartitioner_Swig/CMakeLists.txt +++ /dev/null @@ -1,77 +0,0 @@ -# Copyright (C) 2012-2015 CEA/DEN, EDF 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, 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 -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -# -# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -# - -INCLUDE(${SWIG_USE_FILE}) - -ADD_DEFINITIONS(${PYTHON_DEFINITIONS} ${HDF5_DEFINITIONS} ${MEDFILE_DEFINITIONS} ) - -SET_SOURCE_FILES_PROPERTIES(MEDPartitioner.i PROPERTIES CPLUSPLUS ON) -SET_SOURCE_FILES_PROPERTIES(MEDPartitioner.i PROPERTIES SWIG_DEFINITIONS "-shadow") -SET(SWIG_MODULE_MEDPartitioner_EXTRA_FLAGS "${SWIG_EXTRA_FLAGS_FOR_NUMPYANDSCIPY};-DWITHOUT_AUTOFIELD") - -SET (MEDPartitioner_SWIG_DPYS_FILES - MEDPartitionerCommon.i) - -INCLUDE_DIRECTORIES( - ${PYTHON_INCLUDE_DIRS} - ${PTHREAD_INCLUDE_DIR} # pthread dependancy due to python2.7 library - ${CMAKE_CURRENT_SOURCE_DIR} - ${CMAKE_CURRENT_BINARY_DIR} - ${HDF5_INCLUDE_DIRS} - ${MEDFILE_INCLUDE_DIRS} - ${CMAKE_CURRENT_SOURCE_DIR}/../MEDPartitioner - ${CMAKE_CURRENT_SOURCE_DIR}/../MEDCoupling_Swig - ${CMAKE_CURRENT_SOURCE_DIR}/../MEDCoupling - ${CMAKE_CURRENT_SOURCE_DIR}/../MEDLoader - ${CMAKE_CURRENT_SOURCE_DIR}/../MEDLoader/Swig - ${CMAKE_CURRENT_SOURCE_DIR}/../INTERP_KERNEL - ${CMAKE_CURRENT_SOURCE_DIR}/../INTERP_KERNEL/Bases - ${CMAKE_CURRENT_SOURCE_DIR}/../INTERP_KERNEL/Geometric2D - ${CMAKE_CURRENT_SOURCE_DIR}/../INTERP_KERNEL/ExprEval - ${CMAKE_CURRENT_SOURCE_DIR}/../INTERP_KERNEL/GaussPoints - ) - -SWIG_ADD_MODULE(MEDPartitioner python MEDPartitioner.i) -SWIG_LINK_LIBRARIES(MEDPartitioner ${PYTHON_LIBRARIES} ${PLATFORM_LIBS} medpartitionercpp) - -IF(WIN32) - SET_TARGET_PROPERTIES(_MEDPartitioner PROPERTIES DEBUG_OUTPUT_NAME _MEDPartitioner_d) -ENDIF(WIN32) -INSTALL(TARGETS ${SWIG_MODULE_MEDPartitioner_REAL_NAME} DESTINATION ${SALOME_INSTALL_PYTHON}) - -SET(PYFILES_TO_INSTALL ${CMAKE_CURRENT_BINARY_DIR}/MEDPartitioner.py) -SALOME_INSTALL_SCRIPTS("${PYFILES_TO_INSTALL}" ${SALOME_INSTALL_SCRIPT_PYTHON}) - -INSTALL(FILES MEDPartitioner.i MEDPartitionerCommon.i DESTINATION ${SALOME_INSTALL_HEADERS}) -INSTALL(FILES MEDPartitionerTest.py DESTINATION ${SALOME_INSTALL_SCRIPT_PYTHON}) - -SALOME_GENERATE_TESTS_ENVIRONMENT(tests_env) -ADD_TEST(MEDPartitionerTest ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/MEDPartitionerTest.py) -SET_TESTS_PROPERTIES(MEDPartitionerTest PROPERTIES ENVIRONMENT "${tests_env}") - -# Application tests - -SET(TEST_INSTALL_DIRECTORY ${SALOME_INSTALL_SCRIPT_SCRIPTS}/test/MEDCoupling/MEDPartitioner_Swig) -INSTALL(FILES MEDPartitionerTest.py DESTINATION ${TEST_INSTALL_DIRECTORY}) - -INSTALL(FILES CTestTestfileInstall.cmake - DESTINATION ${TEST_INSTALL_DIRECTORY} - RENAME CTestTestfile.cmake) - - diff --git a/src/MEDPartitioner_Swig/CTestTestfileInstall.cmake b/src/MEDPartitioner_Swig/CTestTestfileInstall.cmake deleted file mode 100644 index 2100e6bf0..000000000 --- a/src/MEDPartitioner_Swig/CTestTestfileInstall.cmake +++ /dev/null @@ -1,21 +0,0 @@ -# Copyright (C) 2015 CEA/DEN, EDF 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, 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 -# 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_TEST(MEDPartitionerTest python MEDPartitionerTest.py) -SET_TESTS_PROPERTIES(MEDPartitionerTest PROPERTIES LABELS "${COMPONENT_NAME}") diff --git a/src/MEDPartitioner_Swig/MEDPartitioner.i b/src/MEDPartitioner_Swig/MEDPartitioner.i deleted file mode 100644 index 13f6d9ca9..000000000 --- a/src/MEDPartitioner_Swig/MEDPartitioner.i +++ /dev/null @@ -1,140 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// - -%include "MEDPartitionerCommon.i" - - -// %pythoncode %{ -// def ParaMEDMEMDataArrayDoublenew(cls,*args): -// import _MEDPartitioner -// return _MEDPartitioner.DataArrayDouble____new___(cls,args) -// def ParaMEDMEMDataArrayDoubleIadd(self,*args): -// import _MEDPartitioner -// return _MEDPartitioner.DataArrayDouble____iadd___(self, self, *args) -// def ParaMEDMEMDataArrayDoubleIsub(self,*args): -// import _MEDPartitioner -// return _MEDPartitioner.DataArrayDouble____isub___(self, self, *args) -// def ParaMEDMEMDataArrayDoubleImul(self,*args): -// import _MEDPartitioner -// return _MEDPartitioner.DataArrayDouble____imul___(self, self, *args) -// def ParaMEDMEMDataArrayDoubleIdiv(self,*args): -// import _MEDPartitioner -// return _MEDPartitioner.DataArrayDouble____idiv___(self, self, *args) -// def ParaMEDMEMDataArrayDoubleIpow(self,*args): -// import _MEDPartitioner -// return _MEDPartitioner.DataArrayDouble____ipow___(self, self, *args) -// def ParaMEDMEMDataArrayIntnew(cls,*args): -// import _MEDPartitioner -// return _MEDPartitioner.DataArrayInt____new___(cls,args) -// def ParaMEDMEMDataArrayIntIadd(self,*args): -// import _MEDPartitioner -// return _MEDPartitioner.DataArrayInt____iadd___(self, self, *args) -// def ParaMEDMEMDataArrayIntIsub(self,*args): -// import _MEDPartitioner -// return _MEDPartitioner.DataArrayInt____isub___(self, self, *args) -// def ParaMEDMEMDataArrayIntImul(self,*args): -// import _MEDPartitioner -// return _MEDPartitioner.DataArrayInt____imul___(self, self, *args) -// def ParaMEDMEMDataArrayIntIdiv(self,*args): -// import _MEDPartitioner -// return _MEDPartitioner.DataArrayInt____idiv___(self, self, *args) -// def ParaMEDMEMDataArrayIntImod(self,*args): -// import _MEDPartitioner -// return _MEDPartitioner.DataArrayInt____imod___(self, self, *args) -// def ParaMEDMEMDataArrayIntIpow(self,*args): -// import _MEDPartitioner -// return _MEDPartitioner.DataArrayInt____ipow___(self, self, *args) -// def ParaMEDMEMDataArrayDoubleTupleIadd(self,*args): -// import _MEDPartitioner -// return _MEDPartitioner.DataArrayDoubleTuple____iadd___(self, self, *args) -// def ParaMEDMEMDataArrayDoubleTupleIsub(self,*args): -// import _MEDPartitioner -// return _MEDPartitioner.DataArrayDoubleTuple____isub___(self, self, *args) -// def ParaMEDMEMDataArrayDoubleTupleImul(self,*args): -// import _MEDPartitioner -// return _MEDPartitioner.DataArrayDoubleTuple____imul___(self, self, *args) -// def ParaMEDMEMDataArrayDoubleTupleIdiv(self,*args): -// import _MEDPartitioner -// return _MEDPartitioner.DataArrayDoubleTuple____idiv___(self, self, *args) -// def ParaMEDMEMDataArrayIntTupleIadd(self,*args): -// import _MEDPartitioner -// return _MEDPartitioner.DataArrayIntTuple____iadd___(self, self, *args) -// def ParaMEDMEMDataArrayIntTupleIsub(self,*args): -// import _MEDPartitioner -// return _MEDPartitioner.DataArrayIntTuple____isub___(self, self, *args) -// def ParaMEDMEMDataArrayIntTupleImul(self,*args): -// import _MEDPartitioner -// return _MEDPartitioner.DataArrayIntTuple____imul___(self, self, *args) -// def ParaMEDMEMDataArrayIntTupleIdiv(self,*args): -// import _MEDPartitioner -// return _MEDPartitioner.DataArrayIntTuple____idiv___(self, self, *args) -// def ParaMEDMEMDataArrayIntTupleImod(self,*args): -// import _MEDPartitioner -// return _MEDPartitioner.DataArrayIntTuple____imod___(self, self, *args) -// %} - - -// %pythoncode %{ -// DataArrayDouble.__new__=classmethod(ParaMEDMEMDataArrayDoublenew) -// DataArrayDouble.__iadd__=ParaMEDMEMDataArrayDoubleIadd -// DataArrayDouble.__isub__=ParaMEDMEMDataArrayDoubleIsub -// DataArrayDouble.__imul__=ParaMEDMEMDataArrayDoubleImul -// DataArrayDouble.__idiv__=ParaMEDMEMDataArrayDoubleIdiv -// DataArrayDouble.__ipow__=ParaMEDMEMDataArrayDoubleIpow - -// DataArrayInt.__new__=classmethod(ParaMEDMEMDataArrayIntnew) -// DataArrayInt.__iadd__=ParaMEDMEMDataArrayIntIadd -// DataArrayInt.__isub__=ParaMEDMEMDataArrayIntIsub -// DataArrayInt.__imul__=ParaMEDMEMDataArrayIntImul -// DataArrayInt.__idiv__=ParaMEDMEMDataArrayIntIdiv -// DataArrayInt.__imod__=ParaMEDMEMDataArrayIntImod -// DataArrayInt.__ipow__=ParaMEDMEMDataArrayIntIpow - -// DataArrayDoubleTuple.__iadd__=ParaMEDMEMDataArrayDoubleTupleIadd -// DataArrayDoubleTuple.__isub__=ParaMEDMEMDataArrayDoubleTupleIsub -// DataArrayDoubleTuple.__imul__=ParaMEDMEMDataArrayDoubleTupleImul -// DataArrayDoubleTuple.__idiv__=ParaMEDMEMDataArrayDoubleTupleIdiv - -// DataArrayIntTuple.__iadd__=ParaMEDMEMDataArrayIntTupleIadd -// DataArrayIntTuple.__isub__=ParaMEDMEMDataArrayIntTupleIsub -// DataArrayIntTuple.__imul__=ParaMEDMEMDataArrayIntTupleImul -// DataArrayIntTuple.__idiv__=ParaMEDMEMDataArrayIntTupleIdiv -// DataArrayIntTuple.__imod__=ParaMEDMEMDataArrayIntTupleImod - -// del ParaMEDMEMDataArrayDoublenew -// del ParaMEDMEMDataArrayDoubleIadd -// del ParaMEDMEMDataArrayDoubleIsub -// del ParaMEDMEMDataArrayDoubleImul -// del ParaMEDMEMDataArrayDoubleIdiv -// del ParaMEDMEMDataArrayIntnew -// del ParaMEDMEMDataArrayIntIadd -// del ParaMEDMEMDataArrayIntIsub -// del ParaMEDMEMDataArrayIntImul -// del ParaMEDMEMDataArrayIntIdiv -// del ParaMEDMEMDataArrayIntImod -// del ParaMEDMEMDataArrayDoubleTupleIadd -// del ParaMEDMEMDataArrayDoubleTupleIsub -// del ParaMEDMEMDataArrayDoubleTupleImul -// del ParaMEDMEMDataArrayDoubleTupleIdiv -// del ParaMEDMEMDataArrayIntTupleIadd -// del ParaMEDMEMDataArrayIntTupleIsub -// del ParaMEDMEMDataArrayIntTupleImul -// del ParaMEDMEMDataArrayIntTupleIdiv -// del ParaMEDMEMDataArrayIntTupleImod -// %} diff --git a/src/MEDPartitioner_Swig/MEDPartitionerCommon.i b/src/MEDPartitioner_Swig/MEDPartitionerCommon.i deleted file mode 100644 index 93a390a81..000000000 --- a/src/MEDPartitioner_Swig/MEDPartitionerCommon.i +++ /dev/null @@ -1,70 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 -// 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 -// - -%module MEDPartitioner - -%include std_string.i - -%{ -#include "MEDFileData.hxx" - -#include "MEDPARTITIONER_MEDPartitioner.hxx" -#include "MEDPARTITIONER.hxx" -#include "MEDPARTITIONER_Graph.hxx" - -using namespace ParaMEDMEM; -using namespace INTERP_KERNEL; -using namespace MEDPARTITIONER; -%} - -%feature("autodoc", "1"); -%feature("docstring"); - -%newobject MEDPARTITIONER::MEDPartitioner::New; -%newobject MEDPARTITIONER::MEDPartitioner::Graph; -%newobject MEDPARTITIONER::MEDPartitioner::getMEDFileData; -%feature("unref") ParaMEDMEM::MEDFileData "$this->decrRef();" - -%nodefaultctor; - -%rename (InterpKernelException) INTERP_KERNEL::Exception; - -namespace MEDPARTITIONER -{ - class Graph - { - public: - virtual void partGraph(int ndomain, const std::string& options_string="", ParaDomainSelector *sel=0) throw(INTERP_KERNEL::Exception); - const ParaMEDMEM::MEDCouplingSkyLineArray *getGraph() const; - const ParaMEDMEM::MEDCouplingSkyLineArray *getPartition() const; - int nbVertices() const; - }; - - class MEDPartitioner - { - public: - MEDPartitioner(const std::string& filename, int ndomains=1, const std::string& library="metis",bool creates_boundary_faces=false, bool create_joints=false, bool mesure_memory=false) throw(INTERP_KERNEL::Exception); - MEDPartitioner(const ParaMEDMEM::MEDFileData* fileData, int ndomains=1, const std::string& library="metis",bool creates_boundary_faces=false, bool create_joints=false, bool mesure_memory=false) throw(INTERP_KERNEL::Exception); - MEDPartitioner(const ParaMEDMEM::MEDFileData* fileData, Graph* graph, bool creates_boundary_faces=false, bool create_joints=false, bool mesure_memory=false) throw(INTERP_KERNEL::Exception); - static MEDPARTITIONER::Graph* Graph(ParaMEDMEM::MEDCouplingSkyLineArray* graph, Graph::splitter_type split=Graph::METIS, int* edgeweight=0) throw(INTERP_KERNEL::Exception); - ParaMEDMEM::MEDFileData* getMEDFileData() throw(INTERP_KERNEL::Exception); - void write(const std::string& filename) throw(INTERP_KERNEL::Exception); - }; -} - diff --git a/src/MEDPartitioner_Swig/MEDPartitionerTest.py b/src/MEDPartitioner_Swig/MEDPartitionerTest.py deleted file mode 100644 index 8ad3c3064..000000000 --- a/src/MEDPartitioner_Swig/MEDPartitionerTest.py +++ /dev/null @@ -1,100 +0,0 @@ -# Copyright (C) 2012-2015 CEA/DEN, EDF 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, 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 -# 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 -# - -from MEDPartitioner import * -from MEDLoader import * -import unittest -from MEDLoaderDataForTest import MEDLoaderDataForTest - -class MEDPartitionerTest(unittest.TestCase): - def testPartition(self): - fname="PyPartitionTest.med" - data=MEDLoaderDataForTest.buildACompleteMEDDataStructureWithFieldsOnCells_1() - data.write(fname,2) - part_file=MEDPartitioner(fname,2) - part_data=MEDPartitioner(data,2) - part_file.write("splitted_PyPartitionTest_1") - part_data.write("splitted_PyPartitionTest_2") - part_file_xml=MEDPartitioner("splitted_PyPartitionTest_1.xml") - part_data_xml=MEDPartitioner("splitted_PyPartitionTest_2.xml") - data1=part_file_xml.getMEDFileData() - data2=part_data_xml.getMEDFileData() - m1d=data1.getMeshes().getMeshAtPos(0) - m2d=data2.getMeshes().getMeshAtPos(0) - self.assertTrue(m1d.isEqual(m2d,1e-12)) - pass - def testPartitionGraph(self): - data=MEDLoaderDataForTest.buildACompleteMEDDataStructureWithFieldsOnCells_1() - m=data.getMeshes().getMeshAtPos(0) - graph=MEDPartitioner.Graph(m.getLevel0Mesh().generateGraph()) - graph.partGraph(2) - tool=MEDPartitioner(data,graph) - data2=tool.getMEDFileData() - self.assertEqual( 2, data2.getMeshes().getNumberOfMeshes() ) - pass - def testPartitionWithJoints(self): - # cartesian mesh 4x4 - arr=DataArrayDouble(5) ; arr.iota() - c=MEDCouplingCMesh() ; c.setCoords(arr,arr) - m=c.buildUnstructured() - m.setName("mesh") - mm=MEDFileUMesh() - mm.setMeshAtLevel(0,m) - ms=MEDFileMeshes() ; ms.pushMesh(mm) - data=MEDFileData() - data.setMeshes(ms) - part_file=MEDPartitioner(data,4,"metis",True,True,True) - data_file=part_file.getMEDFileData() - meshes=data_file.getMeshes() - self.assertEqual( 4, meshes.getNumberOfMeshes()) - self.assertEqual( 3, meshes.getMeshAtPos(0).getJoints().getNumberOfJoints()) - self.assertEqual( 3, meshes.getMeshAtPos(1).getJoints().getNumberOfJoints()) - self.assertEqual( 3, meshes.getMeshAtPos(2).getJoints().getNumberOfJoints()) - self.assertEqual( 3, meshes.getMeshAtPos(3).getJoints().getNumberOfJoints()) - joints=meshes.getMeshAtPos(0).getJoints() - self.assertEqual( 1, joints.getJointAtPos(0).getDomainNumber(), 1) - self.assertEqual( 2, joints.getJointAtPos(1).getDomainNumber(), 2) - self.assertEqual( 3, joints.getJointAtPos(2).getDomainNumber(), 3) - self.assertEqual( 2, joints.getJointAtPos(0).getStepAtPos(0).getNumberOfCorrespondences()) - self.assertEqual( 2, joints.getJointAtPos(1).getStepAtPos(0).getNumberOfCorrespondences()) - self.assertEqual( 1, joints.getJointAtPos(2).getStepAtPos(0).getNumberOfCorrespondences()) - found=0 - for ii in xrange(joints.getJointAtPos(0).getStepAtPos(0).getNumberOfCorrespondences()): - correspond=joints.getJointAtPos(0).getStepAtPos(0).getCorrespondenceAtPos(ii) - if correspond.getCorrespondence().isEqual(DataArrayInt([1,3,2,4])): - found+=1 - self.assertEqual(NORM_QUAD4, correspond.getLocalGeometryType()) - self.assertEqual(NORM_QUAD4, correspond.getRemoteGeometryType()) - pass - pass - self.assertEqual(1,found) - pass - def testPartitionPartGraph(self): - arr=DataArrayDouble(5) ; arr.iota() - c=MEDCouplingCMesh() ; c.setCoords(arr,arr) - m=c.buildUnstructured() - part=MEDPartitioner.Graph(m.generateGraph()) - part.partGraph(2) - a=part.getGraph() - p=part.getPartition() - self.assertTrue(isinstance(a,MEDCouplingSkyLineArray)) - self.assertTrue(isinstance(p,MEDCouplingSkyLineArray)) - self.assertTrue(part.nbVertices() > 0 ) - pass -unittest.main() diff --git a/src/RENUMBER/CMakeLists.txt b/src/RENUMBER/CMakeLists.txt deleted file mode 100644 index 47eb9639a..000000000 --- a/src/RENUMBER/CMakeLists.txt +++ /dev/null @@ -1,96 +0,0 @@ -# Copyright (C) 2012-2015 CEA/DEN, EDF 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, 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 -# 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_DEFINITIONS(${HDF5_DEFINITIONS} ${BOOST_DEFINITIONS} ${MEDFILE_DEFINITIONS}) - -IF(Boost_FOUND) - ADD_DEFINITIONS("-DENABLE_BOOST") -ENDIF(Boost_FOUND) - -# Include directories -INCLUDE_DIRECTORIES( - ${MEDFILE_INCLUDE_DIRS} - ${HDF5_INCLUDE_DIRS} - ${CMAKE_CURRENT_SOURCE_DIR}/../MEDLoader - ${CMAKE_CURRENT_SOURCE_DIR}/../MEDCoupling - ${CMAKE_CURRENT_SOURCE_DIR}/../INTERP_KERNEL - ${CMAKE_CURRENT_SOURCE_DIR}/../INTERP_KERNEL/Bases - ${CMAKE_CURRENT_SOURCE_DIR}/../INTERP_KERNEL/Geometric2D - ${CMAKE_CURRENT_SOURCE_DIR}/../INTERP_KERNEL/ExprEval - ${CMAKE_CURRENT_SOURCE_DIR}/../INTERP_KERNEL/GaussPoints - ) - -IF(SALOME_USE_MPI) - ADD_DEFINITIONS(${MPI_DEFINITIONS}) - INCLUDE_DIRECTORIES(${MPI_INCLUDE_DIRS}) -ENDIF(SALOME_USE_MPI) - -SET(renumbercpp_HEADERS_HXX - RENUMBER_Renumbering.hxx - RenumberingFactory.hxx - RENUMBERDefines.hxx - ) - -SET(renumbercpp_SOURCES - RENUMBER_Renumbering.cxx - RenumberingFactory.cxx - ) - -SET(renumber_SOURCES - renumbering.cxx - ) - -SET(renumbercpp_LDFLAGS medloader) - -IF(PARMETIS_FOUND) - INCLUDE_DIRECTORIES(${PARMETIS_INCLUDE_DIRS}) -ENDIF(PARMETIS_FOUND) - -IF(METIS_FOUND) - INCLUDE_DIRECTORIES(${METIS_INCLUDE_DIRS}) - - SET(renumbercpp_SOURCES ${renumbercpp_SOURCES} RENUMBER_METISRenumbering.cxx) - SET(renumbercpp_HEADERS_HXX ${renumbercpp_HEADERS_HXX} RENUMBER_METISRenumbering.hxx) - SET(renumbercpp_LDFLAGS ${renumbercpp_LDFLAGS} ${METIS_LIBRARIES}) - SET(renumber_DEFINITIONS "${renumber_DEFINITIONS} ${METIS_DEFINITIONS}") -ENDIF(METIS_FOUND) - -IF(Boost_FOUND) - INCLUDE_DIRECTORIES(${Boost_INCLUDE_DIRS}) - - SET(renumbercpp_SOURCES ${renumbercpp_SOURCES} RENUMBER_BOOSTRenumbering.cxx) - SET(renumbercpp_HEADERS_HXX ${renumbercpp_HEADERS_HXX} RENUMBER_BOOSTRenumbering.hxx) - SET(renumbercpp_LDFLAGS ${renumbercpp_LDFLAGS} ${BOOST_LIBRARIES}) -ENDIF(Boost_FOUND) - -IF(SALOME_USE_MPI) - SET(renumbercpp_LDFLAGS ${renumbercpp_LDFLAGS} ${MPI_LIBRARIES}) -ENDIF(SALOME_USE_MPI) - -ADD_EXECUTABLE(renumber ${renumber_SOURCES}) -SET_TARGET_PROPERTIES(renumber PROPERTIES COMPILE_FLAGS "${renumber_DEFINITIONS}") -TARGET_LINK_LIBRARIES(renumber renumbercpp) -INSTALL(TARGETS renumber DESTINATION ${SALOME_INSTALL_BINS}) - -ADD_LIBRARY(renumbercpp SHARED ${renumbercpp_SOURCES}) -SET_TARGET_PROPERTIES(renumbercpp PROPERTIES COMPILE_FLAGS "${renumber_DEFINITIONS}") -TARGET_LINK_LIBRARIES(renumbercpp ${renumbercpp_LDFLAGS}) -INSTALL(TARGETS renumbercpp DESTINATION ${SALOME_INSTALL_LIBS}) - -INSTALL(FILES ${renumbercpp_HEADERS_HXX} DESTINATION ${SALOME_INSTALL_HEADERS}) diff --git a/src/RENUMBER/RENUMBERDefines.hxx b/src/RENUMBER/RENUMBERDefines.hxx deleted file mode 100755 index 144284283..000000000 --- a/src/RENUMBER/RENUMBERDefines.hxx +++ /dev/null @@ -1,34 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 -// 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 __RENUMBERDEFINES_HXX__ -#define __RENUMBERDEFINES_HXX__ - -//export symbols -#ifdef WIN32 -# if defined RENUMBERCPP_EXPORTS || defined renumbercpp_EXPORTS -# define RENUMBER_EXPORT __declspec(dllexport) -# else -# define RENUMBER_EXPORT __declspec(dllimport) -# endif -#else -# define RENUMBER_EXPORT -#endif - -#endif // __RENUMBERDEFINES_HXX__ diff --git a/src/RENUMBER/RENUMBER_BOOSTRenumbering.cxx b/src/RENUMBER/RENUMBER_BOOSTRenumbering.cxx deleted file mode 100644 index 8b0f45885..000000000 --- a/src/RENUMBER/RENUMBER_BOOSTRenumbering.cxx +++ /dev/null @@ -1,55 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// - -#include "RENUMBER_BOOSTRenumbering.hxx" - -#include "MEDCouplingMemArray.hxx" -#include "MEDCouplingAutoRefCountObjectPtr.hxx" - -#include <boost/config.hpp> -#include <boost/graph/adjacency_list.hpp> -#include <boost/graph/cuthill_mckee_ordering.hpp> -#include <boost/graph/properties.hpp> -#include <boost/graph/bandwidth.hpp> - -void BOOSTRenumbering::renumber(const int *graph, const int *index_graph, int nbCell, ParaMEDMEM::DataArrayInt *&iperm, ParaMEDMEM::DataArrayInt *&perm) -{ - ParaMEDMEM::MEDCouplingAutoRefCountObjectPtr<ParaMEDMEM::DataArrayInt> out0(ParaMEDMEM::DataArrayInt::New()),out1(ParaMEDMEM::DataArrayInt::New()); - out0->alloc(nbCell,1); out1->alloc(nbCell,1); - out0->fillWithZero(); out1->fillWithZero(); - // - typedef boost::adjacency_list<boost::vecS, boost::vecS, boost::undirectedS, - boost::property<boost::vertex_color_t, boost::default_color_type, - boost::property<boost::vertex_degree_t,int> > > Graph; - typedef boost::graph_traits<Graph>::vertex_descriptor Vertex; - typedef boost::graph_traits<Graph>::vertices_size_type size_type; - Graph G(nbCell); - for (int i=0;i<nbCell;++i) - for (int j=index_graph[i];j<index_graph[i+1];++j) - add_edge(i,graph[j],G); - boost::property_map<Graph, boost::vertex_index_t>::type - index_map = boost::get(boost::vertex_index, G); - boost::cuthill_mckee_ordering(G, out0->getPointer(), boost::get(boost::vertex_color, G), - boost::make_degree_map(G)); - int *out0Ptr(out0->getPointer()),*out1Ptr(out1->getPointer()); - for(int c=0;c!=nbCell;++c) - out1Ptr[index_map[out0Ptr[nbCell-c-1]]]=c; - out0->reverse(); - iperm=out0.retn(); perm=out1.retn(); -} diff --git a/src/RENUMBER/RENUMBER_BOOSTRenumbering.hxx b/src/RENUMBER/RENUMBER_BOOSTRenumbering.hxx deleted file mode 100644 index 31e7d1eba..000000000 --- a/src/RENUMBER/RENUMBER_BOOSTRenumbering.hxx +++ /dev/null @@ -1,32 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 -// 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 __BOOSTRENUMBERING_HXX__ -#define __BOOSTRENUMBERING_HXX__ - -#include "RENUMBERDefines.hxx" -#include "RENUMBER_Renumbering.hxx" - -class RENUMBER_EXPORT BOOSTRenumbering:public Renumbering -{ -public: - void renumber(const int *graph, const int *index_graph, int nbCell, ParaMEDMEM::DataArrayInt *&iperm, ParaMEDMEM::DataArrayInt *&perm); -}; - -#endif /*BOOSTRENUMBERING_HXX_*/ diff --git a/src/RENUMBER/RENUMBER_METISRenumbering.cxx b/src/RENUMBER/RENUMBER_METISRenumbering.cxx deleted file mode 100644 index 66820b686..000000000 --- a/src/RENUMBER/RENUMBER_METISRenumbering.cxx +++ /dev/null @@ -1,45 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 -// 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 -// - -#ifdef MED_ENABLE_PARMETIS -// include parmetis.h even if it is not needed here -// to avoid inclusion of c++ definitions within extern "C" -// from metis.h from parmetis.h from mpi.h(openmpi) from mpicxx.h -#include <parmetis.h> -#endif -extern "C" -{ -#include "metis.h" -} - -#include "MEDCouplingMemArray.hxx" -#include "MEDCouplingAutoRefCountObjectPtr.hxx" - -#include "RENUMBER_METISRenumbering.hxx" - -void METISRenumbering::renumber(const int *graph, const int *index_graph, int nbCell, ParaMEDMEM::DataArrayInt *&iperm, ParaMEDMEM::DataArrayInt *&perm) -{ - ParaMEDMEM::MEDCouplingAutoRefCountObjectPtr<ParaMEDMEM::DataArrayInt> out0(ParaMEDMEM::DataArrayInt::New()),out1(ParaMEDMEM::DataArrayInt::New()); - out0->alloc(nbCell,1); out1->alloc(nbCell,1); - out0->fillWithZero(); out1->fillWithZero(); - int num_flag=1; - int options=0; - METIS_NodeND(&nbCell,(int*)index_graph,(int*)graph,&num_flag,&options,out0->getPointer(),out1->getPointer()); - iperm=out0.retn(); perm=out1.retn(); -} diff --git a/src/RENUMBER/RENUMBER_METISRenumbering.hxx b/src/RENUMBER/RENUMBER_METISRenumbering.hxx deleted file mode 100644 index ca20175eb..000000000 --- a/src/RENUMBER/RENUMBER_METISRenumbering.hxx +++ /dev/null @@ -1,32 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 -// 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 __METISRENUMBERING_HXX__ -#define __METISRENUMBERING_HXX__ - -#include "RENUMBERDefines.hxx" -#include "RENUMBER_Renumbering.hxx" - -class RENUMBER_EXPORT METISRenumbering:public Renumbering -{ -public: - virtual void renumber(const int *graph, const int *index_graph, int nb_cell, ParaMEDMEM::DataArrayInt *&iperm, ParaMEDMEM::DataArrayInt *&perm); -}; - -#endif /*METISRENUMBERING_HXX_*/ diff --git a/src/RENUMBER/RENUMBER_Renumbering.cxx b/src/RENUMBER/RENUMBER_Renumbering.cxx deleted file mode 100644 index 84fa3bfae..000000000 --- a/src/RENUMBER/RENUMBER_Renumbering.cxx +++ /dev/null @@ -1,19 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 -// 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 -// - diff --git a/src/RENUMBER/RENUMBER_Renumbering.hxx b/src/RENUMBER/RENUMBER_Renumbering.hxx deleted file mode 100644 index 6c21ee45c..000000000 --- a/src/RENUMBER/RENUMBER_Renumbering.hxx +++ /dev/null @@ -1,37 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 -// 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 RENUMBERING_HXX_ -#define RENUMBERING_HXX_ -#include "RENUMBERDefines.hxx" -#include <vector> - -namespace ParaMEDMEM -{ - class DataArrayInt; -} - -class RENUMBER_EXPORT Renumbering -{ -public: - virtual void renumber(const int *graph, const int *index_graph, int nbCell, ParaMEDMEM::DataArrayInt *&iperm, ParaMEDMEM::DataArrayInt *&perm) = 0; - virtual ~Renumbering() { } -}; - -#endif /*RENUMBERING_HXX_*/ diff --git a/src/RENUMBER/RenumberingFactory.cxx b/src/RENUMBER/RenumberingFactory.cxx deleted file mode 100644 index 50cb5d146..000000000 --- a/src/RENUMBER/RenumberingFactory.cxx +++ /dev/null @@ -1,83 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// - -#include "RenumberingFactory.hxx" -#include "RENUMBER_Renumbering.hxx" -#ifdef MED_ENABLE_METIS -#include "RENUMBER_METISRenumbering.hxx" -#endif -#ifdef ENABLE_BOOST -#include "RENUMBER_BOOSTRenumbering.hxx" -#endif - -#include <iostream> - -using namespace std; - -namespace MED_RENUMBER -{ - Renumbering* RenumberingFactory(const string &s) - { -#ifdef MED_ENABLE_METIS -#ifdef ENABLE_BOOST - if (s=="METIS") - { - return new METISRenumbering; - } - else if(s=="BOOST") - { - return new BOOSTRenumbering; - } - else - { - std::cerr << "The method has to be METIS or BOOST" << std::endl; - return 0; - } -#endif -#ifndef ENABLE_BOOST - if (s=="METIS") - { - return new METISRenumbering; - } - else - { - std::cerr << "The method has to be METIS!" << std::endl; - return 0; - } -#endif -#endif -#ifndef MED_ENABLE_METIS -#ifdef ENABLE_BOOST - if (s=="BOOST") - { - return new BOOSTRenumbering; - } - else - { - std::cerr << "The method has to be BOOST!" << std::endl; - return 0; - } -#endif -#ifndef ENABLE_BOOST - std::cerr << "Error, no method compiled" << std::endl; - return 0; -#endif -#endif - } -} diff --git a/src/RENUMBER/RenumberingFactory.hxx b/src/RENUMBER/RenumberingFactory.hxx deleted file mode 100644 index 0ba3d5578..000000000 --- a/src/RENUMBER/RenumberingFactory.hxx +++ /dev/null @@ -1,33 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 -// 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 __RENUMBERINGFACTORY_HXX__ -#define __RENUMBERINGFACTORY_HXX__ - -#include "RENUMBERDefines.hxx" -#include "RENUMBER_Renumbering.hxx" - -#include <string> - -namespace MED_RENUMBER -{ - RENUMBER_EXPORT Renumbering* RenumberingFactory(const std::string& s); -} - -#endif /*RENUMBERINGFACTORY_HXX_*/ diff --git a/src/RENUMBER/renumbering.cxx b/src/RENUMBER/renumbering.cxx deleted file mode 100644 index 1fd4e3b73..000000000 --- a/src/RENUMBER/renumbering.cxx +++ /dev/null @@ -1,128 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// - -#include "MEDFileData.hxx" -#include "MEDFileMesh.hxx" -#include "MEDFileField.hxx" - -#include "MEDCouplingUMesh.hxx" - -#include "RenumberingFactory.hxx" - -#include <time.h> -#include <string> -#include <cstdlib> -#include <fstream> -#include <iostream> - -using namespace std; -using namespace ParaMEDMEM; -using namespace MED_RENUMBER; - -int main(int argc, char** argv) -{ - double t_begin,t_read_st,t_compute_graph,t_family,t_field; - t_begin=clock(); - if (argc <5) - { - cerr << "Usage : " << argv[0] - << " filename_in meshname method[BOOST/METIS] filename_out" << endl << endl; - return -1; - } - string filename_in = argv[1]; - string meshname = argv[2]; - string type_renum = argv[3]; - string filename_out = argv[4]; - - if(type_renum!="METIS" && type_renum!="BOOST") - { - cout << "The method has to be METIS or BOOST!" << endl; - return -1; - } - // Reading file structure - cout << "Reading : " << flush; - MEDCouplingAutoRefCountObjectPtr<MEDFileData> fd(MEDFileData::New(filename_in)); - MEDFileMesh *m=fd->getMeshes()->getMeshWithName(meshname); - MEDFileUMesh *mc=dynamic_cast<MEDFileUMesh *>(m); - if(!mc) - { - std::ostringstream oss; oss << "In file \"" << filename_in << "\" the mesh name \"" << meshname<< "\" exists but is not unstructured !"; - throw INTERP_KERNEL::Exception(oss.str().c_str()); - } - t_read_st=clock(); - cout << (t_read_st-t_begin)/(double) CLOCKS_PER_SEC << "s" << endl << flush; - // Reading mesh - MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> workMesh=mc->getMeshAtLevel(0); - std::vector<int> code=workMesh->getDistributionOfTypes(); - cout << "Building the graph : " << flush; - DataArrayInt *neighb=0,*neighbI=0; - workMesh->computeNeighborsOfCells(neighb,neighbI); - MEDCouplingAutoRefCountObjectPtr<DataArrayInt> neighbSafe(neighb),neighbISafe(neighbI),ipermSafe,permSafe; - const int *graph=neighbSafe->begin(); - const int *graph_index=neighbISafe->begin(); - // Compute permutation iperm->new2old perm->old2new - DataArrayInt *iperm(0),*perm(0); - Renumbering *renumb=RenumberingFactory(type_renum); - renumb->renumber(graph,graph_index,workMesh->getNumberOfCells(),iperm,perm); - ipermSafe=iperm; permSafe=perm; - delete renumb; - ipermSafe=0;//erase new2old, we are using only old 2 new - t_compute_graph=clock(); - cout << " : " << (t_compute_graph-t_read_st)/(double) CLOCKS_PER_SEC << "s" << endl; - cout.flush(); - // Connectivity - cout << "Reordering connectivity & families and writing : " << flush; - workMesh->renumberCells(perm->begin(),false); - mc->setMeshAtLevel(0,workMesh); - const DataArrayInt *famField=mc->getFamilyFieldAtLevel(0); - if(famField) - { - MEDCouplingAutoRefCountObjectPtr<DataArrayInt> famField2=famField->renumber(perm->begin()); - mc->setFamilyFieldArr(0,famField2); - } - mc->write(filename_out,2); - t_family=clock(); - cout << " : " << (t_family-t_compute_graph)/(double) CLOCKS_PER_SEC << "s" << endl << flush; - // Fields - cout << "Reordering fields and writing : " << flush; - MEDFileFields *fs=fd->getFields(); - if(fs) - { - for(int i=0;i<fs->getNumberOfFields();i++) - { - MEDFileFieldMultiTS *fmts=dynamic_cast<MEDFileFieldMultiTS *>(fs->getFieldAtPos(i)); - if(!fmts) continue; - if(fmts->getMeshName()==meshname) - { - for(int j=0;j<fmts->getNumberOfTS();j++) - { - MEDFileField1TS *f1ts=dynamic_cast<MEDFileField1TS*>(fmts->getTimeStepAtPos(j)); - if(!f1ts) continue; - DataArrayDouble *arr=f1ts->getUndergroundDataArray(); - arr->renumberInPlace(perm->begin()); - } - } - } - fs->write(filename_out,0); - //fs->renumberEntitiesLyingOnMesh(meshname,code,code,o2n); bugged - } - t_field=clock(); - cout << " : " << (t_field-t_family)/(double) CLOCKS_PER_SEC << "s" << endl << flush; - return 0; -} diff --git a/src/RENUMBER/testRenumbering.py b/src/RENUMBER/testRenumbering.py deleted file mode 100755 index c18ba6795..000000000 --- a/src/RENUMBER/testRenumbering.py +++ /dev/null @@ -1,210 +0,0 @@ -#!/usr/bin/env python -# -*- coding: iso-8859-1 -*- -# Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 -# 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 -# - -from MEDLoader import * -import os -import sys -import unittest - -class RenumberingTest(unittest.TestCase): - def testBoost2D(self): - filename="Test2D.med" - meshname="Mesh_1" - method="BOOST" - string_to_execute=self.dir_renumber+" "+self.dir_mesh+"/"+filename+" "+meshname+" "+method+" "+self.dir_mesh+"/out_"+filename - os.system(string_to_execute) - mm=MEDFileMesh.New(self.dir_mesh+"/out_"+filename,meshname) - m=mm.getMeshAtLevel(0) - ff=MEDFileField1TS(self.dir_mesh+"/out_"+filename,"Test field") - field_ini=DataArrayDouble([(2,3),(12,13),(14,15),(4,5),(6,7),(8,9),(16,17),(0,1),(10,11)]) - ff.getFieldOnMeshAtLevel(ON_CELLS,0,mm) - f=ff.getFieldOnMeshAtLevel(ON_CELLS,0,mm) - field=f.getArray().isEqual(field_ini,1e-15) - connectivite=[4,1,5,12,10,4,10,12,13,11,4,5,4,14,12,4,11,13,9,3,4,12,14,15,13,4,4,0,6,14,4,13,15,8,9,4,14,6,7,15,4,15,7,2,8] - connectivite_index=[0,5,10,15,20,25,30,35,40,45] - Boost2D=m.getNodalConnectivity().getValues()==connectivite and m.getNodalConnectivityIndex().getValues()==connectivite_index and field - self.assertTrue(Boost2D) - os.remove(self.dir_mesh+"/out_"+filename) - pass - - def tessMetis2D(self):#not activated yet - filename="Test2D.med" - meshname="Mesh_1" - method="METIS" - string_to_execute=self.dir_renumber+" "+self.dir_mesh+"/"+filename+" "+meshname+" "+method+" "+self.dir_mesh+"/out_"+filename - os.system(string_to_execute) - m = MESH(MED_DRIVER,self.dir_mesh+"/out_"+filename,meshname) - nbcell2dmetis=m.getNumberOfElements(MED_CELL,MED_ALL_ELEMENTS) - connectivite=[12,14,10,4,2,6,13,11,11,13,14,12,16,8,3,9,5,1,7,15,15,7,8,16,14,16,9,10,6,5,15,13,13,15,16,14] - connectivite_index=[1,5,9,13,17,21,25,29,33,37] - conn=m.getConnectivity(MED_NODAL,MED_CELL,MED_QUAD4) - conn_index=m.getConnectivityIndex(MED_NODAL,MED_CELL); - conn2dmetis=(list(conn)==connectivite) - conn_index2dmetis=(list(conn_index)==connectivite_index) - Metis2D=conn2dmetis and conn_index2dmetis and (nbcell2dmetis==9) - self.assertTrue(Metis2D) - os.remove(self.dir_mesh+"/out_"+filename) - pass - - def testBoost2DPolygon(self): - filename="Test2Dpoly.med" - meshname="Mesh_1" - method="BOOST" - string_to_execute=self.dir_renumber+" "+self.dir_mesh+"/"+filename+" "+meshname+" "+method+" "+self.dir_mesh+"/out_"+filename - os.system(string_to_execute) - mm=MEDFileMesh.New(self.dir_mesh+"/out_"+filename,meshname) - m=mm.getMeshAtLevel(0) - nbcell2dpolyboost=m.getNumberOfCells() - connectivite=[5,1,4,8,9,5,10,9,8,11,5,4,5,7,8,5,3,10,11,15,5,11,8,7,12,5,5,0,6,7,5,15,11,12,14,5,12,7,6,13,5,14,12,13,2] - connectivite_index=[0,5,10,15,20,25,30,35,40,45] - conn=m.getNodalConnectivity().getValues() - conn_index=m.getNodalConnectivityIndex().getValues() - conn2dpolyboost=(list(conn)==connectivite) - conn_index2dpolyboost=(list(conn_index)==connectivite_index) - PolyBoost2D=conn2dpolyboost and conn_index2dpolyboost and (nbcell2dpolyboost==9) - self.assertTrue(PolyBoost2D) - os.remove(self.dir_mesh+"/out_"+filename) - pass - - def tessMetis2DPolygon(self):#not activated yet - filename="Test2Dpoly.med" - meshname="Mesh_1" - method="METIS" - string_to_execute=self.dir_renumber+" "+self.dir_mesh+"/"+filename+" "+meshname+" "+method+" "+self.dir_mesh+"/out_"+filename - os.system(string_to_execute) - m = MESH(MED_DRIVER,self.dir_mesh+"/out_"+filename,meshname) - nbcell2dpolymetis=m.getNumberOfElements(MED_CELL,MED_ALL_ELEMENTS) - connectivite=[6,1,7,8,2,5,9,10,5,6,8,9,15,13,14,3,4,11,12,16,16,12,13,15,11,10,9,12,12,9,8,13,13,8,7,14] - connectivite_index=[1,5,9,13,17,21,25,29,33,37] - conn=m.getConnectivity(MED_NODAL,MED_CELL,MED_POLYGON) - conn_index=m.getConnectivityIndex(MED_NODAL,MED_CELL) - conn2dpolymetis=(list(conn)==connectivite) - conn_index2dpolymetis=(list(conn_index)==connectivite_index) - PolyMetis2D=conn2dpolymetis and conn_index2dpolymetis and (nbcell2dpolymetis==9) - self.assertTrue(PolyMetis2D) - os.remove(self.dir_mesh+"/out_"+filename) - pass - - def testBoost3D(self): - filename="Test3D.med" - meshname="Mesh_1" - method="BOOST" - string_to_execute=self.dir_renumber+" "+self.dir_mesh+"/"+filename+" "+meshname+" "+method+" "+self.dir_mesh+"/out_"+filename - os.system(string_to_execute) - mm=MEDFileMesh.New(self.dir_mesh+"/out_"+filename,meshname) - m=mm.getMeshAtLevel(0) - nbcell3dboost=m.getNumberOfCells() - connectivite=[18,22,12,4,17,26,21,13,25,18,16,5,12,22,24,15,21,26,18,26,21,13,25,23,14,6,19,18,8,22,17,0,20,26,25,9,18,24,15,21,26,18,7,14,23,18,1,16,22,8,11,24,26,20,18,20,26,25,9,10,23,19,2,18,11,24,26,20,3,18,23,10] - connectivite_index=[0,9,18,27,36,45,54,63,72] - conn=m.getNodalConnectivity().getValues() - conn_index=m.getNodalConnectivityIndex().getValues() - conn3dboost=(list(conn)==connectivite) - conn_index3dboost=(list(conn_index)==connectivite_index) - Boost3D=conn3dboost and conn_index3dboost and (nbcell3dboost==8) - self.assertTrue(Boost3D) - os.remove(self.dir_mesh+"/out_"+filename) - pass - - def tessMetis3D(self):#not activated yet - filename="Test3D.med" - meshname="Mesh_1" - method="METIS" - string_to_execute=self.dir_renumber+" "+self.dir_mesh+"/"+filename+" "+meshname+" "+method+" "+self.dir_mesh+"/out_"+filename - os.system(string_to_execute) - m = MESH(MED_DRIVER,self.dir_mesh+"/out_"+filename,meshname) - nbcell3dmetis=m.getNumberOfElements(MED_CELL,MED_ALL_ELEMENTS) - connectivite=[12,25,27,21,4,19,24,11,27,22,14,26,24,15,7,20,17,6,13,23,25,16,22,27,9,23,18,1,21,27,26,10,23,13,5,18,27,22,14,26,25,16,22,27,19,8,15,24,2,17,23,9,12,25,27,21,21,27,26,10,11,24,20,3] - connectivite_index=[1,9,17,25,33,41,49,57,65] - conn=m.getConnectivity(MED_NODAL,MED_CELL,MED_HEXA8) - conn_index=m.getConnectivityIndex(MED_NODAL,MED_CELL); - conn3dmetis=(list(conn)==connectivite) - conn_index3dmetis=(list(conn_index)==connectivite_index) - Metis3D=conn3dmetis&conn_index3dmetis&(nbcell3dmetis==8) - self.assertTrue(Metis3D) - os.remove(self.dir_mesh+"/out_"+filename) - pass - - def testBoost3DPoly(self): - filename="Test3Dpoly.med" - meshname="Mesh_1" - method="BOOST" - string_to_execute=self.dir_renumber+" "+self.dir_mesh+"/"+filename+" "+meshname+" "+method+" "+self.dir_mesh+"/out_"+filename - os.system(string_to_execute) - mm=MEDFileMesh.New(self.dir_mesh+"/out_"+filename,meshname) - m=mm.getMeshAtLevel(0) - nbcell3dpolyboost=m.getNumberOfCells() - connectivite=[31,22,12,4,17,-1,26,25,13,21,-1,22,26,21,12,-1,12,21,13,4,-1,4,13,25,17,-1,17,25,26,22,31,16,5,12,22,-1,24,26,21,15,-1,16,24,15,5,-1,5,15,21,12,-1,12,21,26,22,-1,22,26,24,16,31,26,21,13,25,-1,23,19,6,14,-1,26,23,14,21,-1,21,14,6,13,-1,13,6,19,25,-1,25,19,23,26,31,8,22,17,0,-1,20,9,25,26,-1,8,20,26,22,-1,22,26,25,17,-1,17,25,9,0,-1,0,9,20,8,31,24,15,21,26,-1,18,23,14,7,-1,24,18,7,15,-1,15,7,14,21,-1,21,14,23,26,-1,26,23,18,24,31,1,16,22,8,-1,11,20,26,24,-1,1,11,24,16,-1,16,24,26,22,-1,22,26,20,8,-1,8,20,11,1,31,20,26,25,9,-1,10,2,19,23,-1,20,10,23,26,-1,26,23,19,25,-1,25,19,2,9,-1,9,2,10,20,31,11,24,26,20,-1,3,10,23,18,-1,11,3,18,24,-1,24,18,23,26,-1,26,23,10,20,-1,20,10,3,11] - connectivite_index=[0,30,60,90,120,150,180,210,240] - conn=m.getNodalConnectivity().getValues() - conn_index=m.getNodalConnectivityIndex().getValues() - conn3dpolyboost=(connectivite==list(conn)) - conn_index3dpolyboost=(connectivite_index==list(conn_index)) - PolyBoost3D=(conn3dpolyboost and conn_index3dpolyboost and (nbcell3dpolyboost==8)) - self.assertTrue(PolyBoost3D) - os.remove(self.dir_mesh+"/out_"+filename) - pass - - def tessBoost3DPoly(self):#not activated yet - filename="Test3Dpoly.med" - meshname="Mesh_1" - method="METIS" - string_to_execute=self.dir_renumber+" "+self.dir_mesh+"/"+filename+" "+meshname+" "+method+" "+self.dir_mesh+"/out_"+filename - os.system(string_to_execute) - m = MESH(MED_DRIVER,self.dir_mesh+"/out_"+filename,meshname) - nbcell3dpolymetis=m.getNumberOfElements(MED_CELL,MED_ALL_ELEMENTS) - connectivite=[12,25,27,21,-1,4,11,24,19,-1,12,4,19,25,-1,25,19,24,27,-1,27,24,11,21,-1,21,11,4,12, - 27,22,14,26,-1,24,20,7,15,-1,27,24,15,22,-1,22,15,7,14,-1,14,7,20,26,-1,26,20,24,27, - 17,6,13,23,-1,25,27,22,16,-1,17,25,16,6,-1,6,16,22,13,-1,13,22,27,23,-1,23,27,25,17, - 9,23,18,1,-1,21,10,26,27,-1,9,21,27,23,-1,23,27,26,18,-1,18,26,10,1,-1,1,10,21,9, - 23,13,5,18,-1,27,26,14,22,-1,23,27,22,13,-1,13,22,14,5,-1,5,14,26,18,-1,18,26,27,23, - 25,16,22,27,-1,19,24,15,8,-1,25,19,8,16,-1,16,8,15,22,-1,22,15,24,27,-1,27,24,19,25, - 2,17,23,9,-1,12,21,27,25,-1,2,12,25,17,-1,17,25,27,23,-1,23,27,21,9,-1,9,21,12,2, - 21,27,26,10,-1,11,3,20,24,-1,21,11,24,27,-1,27,24,20,26,-1,26,20,3,10,-1,10,3,11,21] - connectivite_index=[1, 30, 59, 88, 117, 146, 175, 204, 233] - conn=m.getConnectivity(MED_NODAL,MED_CELL,MED_POLYHEDRA) - conn_index=m.getConnectivityIndex(MED_NODAL,MED_CELL); - conn3dpolymetis=(list(conn)==connectivite) - conn_index3dpolymetis=(list(conn_index)==connectivite_index) - PolyMetis3D=(conn3dpolymetis and conn_index3dpolymetis and (nbcell3dpolymetis==8)) - self.assertTrue(PolyMetis3D) - os.remove(self.dir_mesh+"/out_"+filename) - pass - - def setUp(self): - srcdir = os.getenv("srcdir") - med_root = os.getenv("MED_ROOT_DIR") - if srcdir: - # make test is being performed - self.dir_renumber="./renumber" - self.dir_mesh = os.path.join( srcdir, "../../resources") - elif med_root: - # hope renumber has been already installed - self.dir_renumber=os.path.join( med_root, "bin/salome/renumber") - self.dir_mesh = os.path.join( med_root, "share/salome/resources/med") - else: - # initial version - self.dir_renumber="../../../MED_INSTALL/bin/salome/renumber" - self.dir_mesh="../../resources" - pass - pass - pass - -unittest.main() diff --git a/src/RENUMBER_Swig/CMakeLists.txt b/src/RENUMBER_Swig/CMakeLists.txt deleted file mode 100644 index c4c5943d1..000000000 --- a/src/RENUMBER_Swig/CMakeLists.txt +++ /dev/null @@ -1,79 +0,0 @@ -# Copyright (C) 2012-2015 CEA/DEN, EDF 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, 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 -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public -# License along with this library; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -# -# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -# - -INCLUDE(${SWIG_USE_FILE}) - -ADD_DEFINITIONS(${PYTHON_DEFINITIONS}) - -SET_SOURCE_FILES_PROPERTIES(MEDRenumber.i PROPERTIES CPLUSPLUS ON) -SET_SOURCE_FILES_PROPERTIES(MEDRenumber.i PROPERTIES SWIG_DEFINITIONS "-shadow") -SET(SWIG_MODULE_MEDRenumber_EXTRA_FLAGS "${SWIG_EXTRA_FLAGS_FOR_NUMPYANDSCIPY};-DWITHOUT_AUTOFIELD") - -IF(Boost_FOUND) - SET(SWIG_MODULE_MEDRenumber_EXTRA_FLAGS -DHAS_BOOST ${SWIG_MODULE_MEDRenumber_EXTRA_FLAGS}) -ENDIF(Boost_FOUND) - -IF(METIS_FOUND) - SET(SWIG_MODULE_MEDRenumber_EXTRA_FLAGS -DHAS_METIS ${SWIG_MODULE_MEDRenumber_EXTRA_FLAGS}) -ENDIF(METIS_FOUND) - -SET (MEDRenumber_SWIG_DPYS_FILES - MEDRenumberCommon.i) - -INCLUDE_DIRECTORIES( - ${PYTHON_INCLUDE_DIRS} - ${PTHREAD_INCLUDE_DIR} # pthread dependancy due to python2.7 library - ${CMAKE_CURRENT_SOURCE_DIR} - ${CMAKE_CURRENT_BINARY_DIR} - ${CMAKE_CURRENT_SOURCE_DIR}/../RENUMBER - ${CMAKE_CURRENT_SOURCE_DIR}/../MEDCoupling_Swig - ${CMAKE_CURRENT_SOURCE_DIR}/../MEDCoupling - ${CMAKE_CURRENT_SOURCE_DIR}/../INTERP_KERNEL - ${CMAKE_CURRENT_SOURCE_DIR}/../INTERP_KERNEL/Bases - ${CMAKE_CURRENT_SOURCE_DIR}/../INTERP_KERNEL/Geometric2D - ${CMAKE_CURRENT_SOURCE_DIR}/../INTERP_KERNEL/ExprEval - ${CMAKE_CURRENT_SOURCE_DIR}/../INTERP_KERNEL/GaussPoints - ) - -SWIG_ADD_MODULE(MEDRenumber python MEDRenumber.i) -SWIG_LINK_LIBRARIES(MEDRenumber ${PYTHON_LIBRARIES} ${PLATFORM_LIBS} renumbercpp) - -IF(WIN32) - SET_TARGET_PROPERTIES(_MEDRenumber PROPERTIES DEBUG_OUTPUT_NAME _MEDRenumber_d) -ENDIF(WIN32) -INSTALL(TARGETS ${SWIG_MODULE_MEDRenumber_REAL_NAME} DESTINATION ${SALOME_INSTALL_PYTHON}) - -SET(PYFILES_TO_INSTALL ${CMAKE_CURRENT_BINARY_DIR}/MEDRenumber.py) -SALOME_INSTALL_SCRIPTS("${PYFILES_TO_INSTALL}" ${SALOME_INSTALL_SCRIPT_PYTHON}) - -INSTALL(FILES MEDRenumber.i MEDRenumberCommon.i DESTINATION ${SALOME_INSTALL_HEADERS}) -INSTALL(FILES MEDRenumberTest.py DESTINATION ${SALOME_INSTALL_SCRIPT_PYTHON}) - -SALOME_GENERATE_TESTS_ENVIRONMENT(tests_env) -ADD_TEST(MEDRenumberTest ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/MEDRenumberTest.py) -SET_TESTS_PROPERTIES(MEDRenumberTest PROPERTIES ENVIRONMENT "${tests_env}") - -# Application tests - -SET(TEST_INSTALL_DIRECTORY ${SALOME_INSTALL_SCRIPT_SCRIPTS}/test/MEDCoupling/RENUMBER_Swig) -INSTALL(FILES MEDRenumberTest.py DESTINATION ${TEST_INSTALL_DIRECTORY}) - -INSTALL(FILES CTestTestfileInstall.cmake - DESTINATION ${TEST_INSTALL_DIRECTORY} - RENAME CTestTestfile.cmake) diff --git a/src/RENUMBER_Swig/CTestTestfileInstall.cmake b/src/RENUMBER_Swig/CTestTestfileInstall.cmake deleted file mode 100644 index aeaaf7124..000000000 --- a/src/RENUMBER_Swig/CTestTestfileInstall.cmake +++ /dev/null @@ -1,21 +0,0 @@ -# Copyright (C) 2015 CEA/DEN, EDF 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, 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 -# 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_TEST(MEDRenumberTest python MEDRenumberTest.py) -SET_TESTS_PROPERTIES(MEDRenumberTest PROPERTIES LABELS "${COMPONENT_NAME}") diff --git a/src/RENUMBER_Swig/MEDRenumber.i b/src/RENUMBER_Swig/MEDRenumber.i deleted file mode 100644 index 9ba28d274..000000000 --- a/src/RENUMBER_Swig/MEDRenumber.i +++ /dev/null @@ -1,141 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// - -%include "MEDRenumberCommon.i" - -%pythoncode %{ -def ParaMEDMEMDataArrayDoublenew(cls,*args): - import _MEDRenumber - return _MEDRenumber.DataArrayDouble____new___(cls,args) -def ParaMEDMEMDataArrayDoubleIadd(self,*args): - import _MEDRenumber - return _MEDRenumber.DataArrayDouble____iadd___(self, self, *args) -def ParaMEDMEMDataArrayDoubleIsub(self,*args): - import _MEDRenumber - return _MEDRenumber.DataArrayDouble____isub___(self, self, *args) -def ParaMEDMEMDataArrayDoubleImul(self,*args): - import _MEDRenumber - return _MEDRenumber.DataArrayDouble____imul___(self, self, *args) -def ParaMEDMEMDataArrayDoubleIdiv(self,*args): - import _MEDRenumber - return _MEDRenumber.DataArrayDouble____idiv___(self, self, *args) -def ParaMEDMEMDataArrayDoubleIpow(self,*args): - import _MEDRenumber - return _MEDRenumber.DataArrayDouble____ipow___(self, self, *args) -def ParaMEDMEMDataArrayIntnew(cls,*args): - import _MEDRenumber - return _MEDRenumber.DataArrayInt____new___(cls,args) -def ParaMEDMEMDataArrayIntIadd(self,*args): - import _MEDRenumber - return _MEDRenumber.DataArrayInt____iadd___(self, self, *args) -def ParaMEDMEMDataArrayIntIsub(self,*args): - import _MEDRenumber - return _MEDRenumber.DataArrayInt____isub___(self, self, *args) -def ParaMEDMEMDataArrayIntImul(self,*args): - import _MEDRenumber - return _MEDRenumber.DataArrayInt____imul___(self, self, *args) -def ParaMEDMEMDataArrayIntIdiv(self,*args): - import _MEDRenumber - return _MEDRenumber.DataArrayInt____idiv___(self, self, *args) -def ParaMEDMEMDataArrayIntImod(self,*args): - import _MEDRenumber - return _MEDRenumber.DataArrayInt____imod___(self, self, *args) -def ParaMEDMEMDataArrayIntIpow(self,*args): - import _MEDRenumber - return _MEDRenumber.DataArrayInt____ipow___(self, self, *args) -def ParaMEDMEMDataArrayDoubleTupleIadd(self,*args): - import _MEDRenumber - return _MEDRenumber.DataArrayDoubleTuple____iadd___(self, self, *args) -def ParaMEDMEMDataArrayDoubleTupleIsub(self,*args): - import _MEDRenumber - return _MEDRenumber.DataArrayDoubleTuple____isub___(self, self, *args) -def ParaMEDMEMDataArrayDoubleTupleImul(self,*args): - import _MEDRenumber - return _MEDRenumber.DataArrayDoubleTuple____imul___(self, self, *args) -def ParaMEDMEMDataArrayDoubleTupleIdiv(self,*args): - import _MEDRenumber - return _MEDRenumber.DataArrayDoubleTuple____idiv___(self, self, *args) -def ParaMEDMEMDataArrayIntTupleIadd(self,*args): - import _MEDRenumber - return _MEDRenumber.DataArrayIntTuple____iadd___(self, self, *args) -def ParaMEDMEMDataArrayIntTupleIsub(self,*args): - import _MEDRenumber - return _MEDRenumber.DataArrayIntTuple____isub___(self, self, *args) -def ParaMEDMEMDataArrayIntTupleImul(self,*args): - import _MEDRenumber - return _MEDRenumber.DataArrayIntTuple____imul___(self, self, *args) -def ParaMEDMEMDataArrayIntTupleIdiv(self,*args): - import _MEDRenumber - return _MEDRenumber.DataArrayIntTuple____idiv___(self, self, *args) -def ParaMEDMEMDataArrayIntTupleImod(self,*args): - import _MEDRenumber - return _MEDRenumber.DataArrayIntTuple____imod___(self, self, *args) -%} - - -%pythoncode %{ -InterpKernelException.__reduce__=INTERPKERNELExceptionReduce -DataArrayDouble.__new__=classmethod(ParaMEDMEMDataArrayDoublenew) -DataArrayDouble.__iadd__=ParaMEDMEMDataArrayDoubleIadd -DataArrayDouble.__isub__=ParaMEDMEMDataArrayDoubleIsub -DataArrayDouble.__imul__=ParaMEDMEMDataArrayDoubleImul -DataArrayDouble.__idiv__=ParaMEDMEMDataArrayDoubleIdiv -DataArrayDouble.__ipow__=ParaMEDMEMDataArrayDoubleIpow - -DataArrayInt.__new__=classmethod(ParaMEDMEMDataArrayIntnew) -DataArrayInt.__iadd__=ParaMEDMEMDataArrayIntIadd -DataArrayInt.__isub__=ParaMEDMEMDataArrayIntIsub -DataArrayInt.__imul__=ParaMEDMEMDataArrayIntImul -DataArrayInt.__idiv__=ParaMEDMEMDataArrayIntIdiv -DataArrayInt.__imod__=ParaMEDMEMDataArrayIntImod -DataArrayInt.__ipow__=ParaMEDMEMDataArrayIntIpow - -DataArrayDoubleTuple.__iadd__=ParaMEDMEMDataArrayDoubleTupleIadd -DataArrayDoubleTuple.__isub__=ParaMEDMEMDataArrayDoubleTupleIsub -DataArrayDoubleTuple.__imul__=ParaMEDMEMDataArrayDoubleTupleImul -DataArrayDoubleTuple.__idiv__=ParaMEDMEMDataArrayDoubleTupleIdiv - -DataArrayIntTuple.__iadd__=ParaMEDMEMDataArrayIntTupleIadd -DataArrayIntTuple.__isub__=ParaMEDMEMDataArrayIntTupleIsub -DataArrayIntTuple.__imul__=ParaMEDMEMDataArrayIntTupleImul -DataArrayIntTuple.__idiv__=ParaMEDMEMDataArrayIntTupleIdiv -DataArrayIntTuple.__imod__=ParaMEDMEMDataArrayIntTupleImod - -del INTERPKERNELExceptionReduce -del ParaMEDMEMDataArrayDoublenew -del ParaMEDMEMDataArrayDoubleIadd -del ParaMEDMEMDataArrayDoubleIsub -del ParaMEDMEMDataArrayDoubleImul -del ParaMEDMEMDataArrayDoubleIdiv -del ParaMEDMEMDataArrayIntnew -del ParaMEDMEMDataArrayIntIadd -del ParaMEDMEMDataArrayIntIsub -del ParaMEDMEMDataArrayIntImul -del ParaMEDMEMDataArrayIntIdiv -del ParaMEDMEMDataArrayIntImod -del ParaMEDMEMDataArrayDoubleTupleIadd -del ParaMEDMEMDataArrayDoubleTupleIsub -del ParaMEDMEMDataArrayDoubleTupleImul -del ParaMEDMEMDataArrayDoubleTupleIdiv -del ParaMEDMEMDataArrayIntTupleIadd -del ParaMEDMEMDataArrayIntTupleIsub -del ParaMEDMEMDataArrayIntTupleImul -del ParaMEDMEMDataArrayIntTupleIdiv -del ParaMEDMEMDataArrayIntTupleImod -%} diff --git a/src/RENUMBER_Swig/MEDRenumberCommon.i b/src/RENUMBER_Swig/MEDRenumberCommon.i deleted file mode 100644 index 85f5d7e7c..000000000 --- a/src/RENUMBER_Swig/MEDRenumberCommon.i +++ /dev/null @@ -1,107 +0,0 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 -// 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) - -%module MEDRenumber - -%include std_vector.i -%include std_string.i - -%{ -#include "MEDCouplingMemArray.hxx" -#include "MEDCouplingAutoRefCountObjectPtr.hxx" -#include "MEDCouplingDataArrayTypemaps.i" - -#include "RenumberingFactory.hxx" -#include "RENUMBER_Renumbering.hxx" - -using namespace ParaMEDMEM; -using namespace INTERP_KERNEL; - using namespace MED_RENUMBER; -%} - -%template(ivec) std::vector<int>; -%template(dvec) std::vector<double>; -%template(svec) std::vector<std::string>; - -#ifdef WITH_NUMPY -%init %{ import_array(); %} -#endif - -%feature("autodoc", "1"); -%feature("docstring"); - -%newobject MED_RENUMBER::RenumberingFactory; - -%nodefaultctor; - -%rename (InterpKernelException) INTERP_KERNEL::Exception; - -%include "MEDCouplingRefCountObject.i" -%include "MEDCouplingMemArray.i" - -class Renumbering -{ -public: - %extend - { - virtual PyObject *renumber(const ParaMEDMEM::DataArrayInt *graph, const ParaMEDMEM::DataArrayInt *index_graph) throw(INTERP_KERNEL::Exception) - { - if(!graph || !index_graph) - throw INTERP_KERNEL::Exception("wrap of Renumbering::renumber : One of the input arrays is NULL !"); - if(!graph->isAllocated() || !index_graph->isAllocated()) - throw INTERP_KERNEL::Exception("wrap of Renumbering::renumber : One of the input arrays is not allocated !"); - ParaMEDMEM::DataArrayInt *out0(0),*out1(0); - self->renumber(graph->begin(),index_graph->begin(),index_graph->getNumberOfTuples()-1,out0,out1); - PyObject *ret=PyTuple_New(2); - PyTuple_SetItem(ret,0,SWIG_NewPointerObj(SWIG_as_voidptr(out0),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 )); - PyTuple_SetItem(ret,1,SWIG_NewPointerObj(SWIG_as_voidptr(out1),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 )); - return ret; - } - } - virtual ~Renumbering(); -}; - -namespace MED_RENUMBER -{ - Renumbering *RenumberingFactory(const std::string& s) throw(INTERP_KERNEL::Exception); -} - -%inline -{ - std::vector<std::string> RenumberAvailableMethods()throw(INTERP_KERNEL::Exception) - { - std::vector<std::string> ret; -#ifdef HAS_BOOST - ret.push_back(std::string("BOOST")); -#endif -#ifdef HAS_METIS - ret.push_back(std::string("METIS")); -#endif - return ret; - } -} - -%pythoncode %{ -import os -__filename=os.environ.get('PYTHONSTARTUP') -if __filename and os.path.isfile(__filename): - execfile(__filename) - pass -%} diff --git a/src/RENUMBER_Swig/MEDRenumberTest.py b/src/RENUMBER_Swig/MEDRenumberTest.py deleted file mode 100644 index 15199faa0..000000000 --- a/src/RENUMBER_Swig/MEDRenumberTest.py +++ /dev/null @@ -1,41 +0,0 @@ -# Copyright (C) 2012-2015 CEA/DEN, EDF 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, 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 -# 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 -# - -from MEDRenumber import * -import unittest - -class MEDRenumberTest(unittest.TestCase): - - @unittest.skipUnless("BOOST" in RenumberAvailableMethods(),"requires BOOST prerequisite !") - def test1(self): - from MEDCoupling import MEDCouplingCMesh - ren=RenumberingFactory("BOOST") - arr=DataArrayDouble(10) ; arr.iota() - c=MEDCouplingCMesh() ; c.setCoords(arr,arr) - m=c.buildUnstructured() - a,b=m.computeNeighborsOfCells() - n2o,o2n=ren.renumber(a,b) - self.assertTrue(o2n.isEqual(DataArrayInt([0,2,5,9,14,20,27,35,44,1,4,8,13,19,26,34,43,52,3,7,12,18,25,33,42,51,59,6,11,17,24,32,41,50,58,65,10,16,23,31,40,49,57,64,70,15,22,30,39,48,56,63,69,74,21,29,38,47,55,62,68,73,77,28,37,46,54,61,67,72,76,79,36,45,53,60,66,71,75,78,80]))) - pass - - def setUp(self): - pass - pass - -unittest.main() diff --git a/src/medtool/CMakeLists.txt b/src/medtool/CMakeLists.txt new file mode 100644 index 000000000..4bbaae984 --- /dev/null +++ b/src/medtool/CMakeLists.txt @@ -0,0 +1,359 @@ +# Copyright (C) 2015 CEA/DEN, EDF 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, 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 +# 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 +# + +CMAKE_MINIMUM_REQUIRED(VERSION 2.8.2 FATAL_ERROR) +#INCLUDE(CMakeDependentOption) +PROJECT(MEDtool C CXX) + +# Ensure a proper linker behavior: +CMAKE_POLICY(SET CMP0003 NEW) + +# Versioning +# =========== +# Project name, upper case +STRING(TOUPPER ${PROJECT_NAME} PROJECT_NAME_UC) + +SET(${PROJECT_NAME_UC}_MAJOR_VERSION 1) +SET(${PROJECT_NAME_UC}_MINOR_VERSION 0) +SET(${PROJECT_NAME_UC}_PATCH_VERSION 0) +SET(${PROJECT_NAME_UC}_VERSION + ${${PROJECT_NAME_UC}_MAJOR_VERSION}.${${PROJECT_NAME_UC}_MINOR_VERSION}.${${PROJECT_NAME_UC}_PATCH_VERSION}) +SET(${PROJECT_NAME_UC}_VERSION_DEV 1) + +# Our own set of macros: +LIST(APPEND CMAKE_MODULE_PATH "${PROJECT_SOURCE_DIR}/cmake_files") +INCLUDE(MEDtoolMacros) + +# Platform setup +# ============== +#INCLUDE(SalomeSetupPlatform) + +# +# User options +# ============ +INCLUDE(CMakeDependentOption) +OPTION(SALOME_MED_MICROMED "Build MED without MED file dependancy." OFF) +OPTION(SALOME_MED_ENABLE_PYTHON "Build PYTHON bindings." ON) +OPTION(SALOME_MED_ENABLE_PARTITIONER "Build MEDPartitioner." ON) +OPTION(SALOME_MED_ENABLE_RENUMBER "Build Renumber." ON) +OPTION(SALOME_MED_WITH_FILE_EXAMPLES "Install examples of files containing meshes and fields of different formats." ON) +OPTION(SALOME_USE_MPI "(Use MPI containers) - For MED this triggers the build of ParaMEDMEM." OFF) +OPTION(SALOME_BUILD_TESTS "Build MED tests." ON) +OPTION(SALOME_BUILD_DOC "Build MED doc." ON) +CMAKE_DEPENDENT_OPTION(SALOME_MED_PARTITIONER_METIS "Enable metis graph library in MEDPartitioner." ON "SALOME_MED_ENABLE_PARTITIONER" OFF) +CMAKE_DEPENDENT_OPTION(SALOME_MED_PARTITIONER_SCOTCH "Enable scotch graph library in MEDPartitioner." ON "SALOME_MED_ENABLE_PARTITIONER;NOT SALOME_USE_MPI" OFF) +CMAKE_DEPENDENT_OPTION(SALOME_MED_PARTITIONER_PARMETIS "Enable parmetis graph library in MEDPartitioner." ON "SALOME_MED_ENABLE_PARTITIONER;SALOME_USE_MPI" OFF) +IF(WIN32) + CMAKE_DEPENDENT_OPTION(SALOME_MED_MEDLOADER_USE_XDR "Enable use of XDR for SauvReader." ON "NOT SALOME_MED_MICROMED" OFF) +ENDIF(WIN32) + +# +# Set list of prerequisites +# ========================= + +LIST(APPEND CMAKE_MODULE_PATH "${PROJECT_SOURCE_DIR}/cmake_files") + +IF(NOT SALOME_MED_MICROMED) + #FIND_PACKAGE(SalomeHDF5 REQUIRED) + #FIND_PACKAGE(SalomeMEDFile REQUIRED) + FIND_PACKAGE(HDF5 REQUIRED) + FIND_PACKAGE(MEDFile REQUIRED) + # XDR stuff + IF(NOT WIN32) + #FIND_PACKAGE(SalomeXDR REQUIRED) + FIND_PACKAGE(XDR REQUIRED) + ELSE(NOT WIN32) + IF(SALOME_MED_MEDLOADER_USE_XDR) + FIND_PACKAGE(SalomeXDR REQUIRED) + ENDIF(SALOME_MED_MEDLOADER_USE_XDR) + ENDIF(NOT WIN32) + # End of XDR Stuff + IF(SALOME_MED_ENABLE_PARTITIONER) + #FIND_PACKAGE(SalomeLibXml2) + #SALOME_LOG_OPTIONAL_PACKAGE(LibXml2 SALOME_MED_ENABLE_PARTITIONER) + IF(DEFINED ENV{LIBXML2_ROOT_DIR}) + SET(CMAKE_PREFIX_PATH "$ENV{LIBXML2_ROOT_DIR}") + ENDIF() + FIND_PACKAGE(LibXml2) + MESSAGE("LIBXML2_FOUND: ${LIBXML2_FOUND}") + MESSAGE("LIBXML2_INCLUDE_DIR: ${LIBXML2_INCLUDE_DIR}") + MESSAGE("LIBXML2_LIBRARIES: ${LIBXML2_LIBRARIES}") + MESSAGE("LIBXML2_DEFINITIONS: ${LIBXML2_DEFINITIONS}") + MESSAGE("LIBXML2_XMLLINT_EXECUTABLE: ${LIBXML2_XMLLINT_EXECUTABLE}") + MESSAGE("LIBXML2_VERSION_STRING: ${LIBXML2_VERSION_STRING}") + + IF(SALOME_MED_PARTITIONER_METIS) + #FIND_PACKAGE(SalomeMetis) + #SALOME_LOG_OPTIONAL_PACKAGE(Metis SALOME_MED_PARTITIONER_METIS) + FIND_PACKAGE(Metis) + ADD_DEFINITIONS("-DMED_ENABLE_METIS") + ENDIF(SALOME_MED_PARTITIONER_METIS) + IF(SALOME_MED_PARTITIONER_SCOTCH) + #FIND_PACKAGE(SalomeScotch) + #SALOME_LOG_OPTIONAL_PACKAGE(Scotch SALOME_MED_PARTITIONER_SCOTCH) + FIND_PACKAGE(Scotch) + ADD_DEFINITIONS("-DMED_ENABLE_SCOTCH") + ENDIF(SALOME_MED_PARTITIONER_SCOTCH) + ENDIF(SALOME_MED_ENABLE_PARTITIONER) +ENDIF(NOT SALOME_MED_MICROMED) + +ENABLE_TESTING() # let it outsite because even if SALOME_BUILD_TESTS is OFF, python tests that not need additional compilation can be run. + +IF(SALOME_BUILD_TESTS) + #FIND_PACKAGE(SalomeCppUnit) + #SALOME_LOG_OPTIONAL_PACKAGE(CppUnit SALOME_BUILD_TESTS) + FIND_PACKAGE(CppUnit) +ENDIF(SALOME_BUILD_TESTS) + +IF(SALOME_USE_MPI) + FIND_PACKAGE(SalomeMPI REQUIRED) + ADD_DEFINITIONS("-DHAVE_MPI") + IF(SALOME_MED_PARTITIONER_PARMETIS) + FIND_PACKAGE(SalomeParMetis) + SALOME_LOG_OPTIONAL_PACKAGE(ParMetis SALOME_MED_PARTITIONER_PARMETIS) + ADD_DEFINITIONS("-DMED_ENABLE_PARMETIS") + ENDIF(SALOME_MED_PARTITIONER_PARMETIS) +ENDIF(SALOME_USE_MPI) + +IF(SALOME_MED_ENABLE_RENUMBER) + #FIND_PACKAGE(SalomeBoost) + #SALOME_LOG_OPTIONAL_PACKAGE(Boost SALOME_MED_ENABLE_RENUMBER) + IF(DEFINED ENV{BOOST_ROOT_DIR}) + SET(CMAKE_PREFIX_PATH "$ENV{BOOST_ROOT_DIR}") + ENDIF() + SET(Boost_USE_STATIC_LIBS OFF) + SET(Boost_USE_MULTITHREADED ON) + SET(Boost_USE_STATIC_RUNTIME OFF) + SET(Boost_NO_BOOST_CMAKE ON) + SET(SalomeBoost_FIND_COMPONENTS filesystem regex signals system thread date_time chrono) + FIND_PACKAGE(Boost) +ENDIF(SALOME_MED_ENABLE_RENUMBER) + +IF(SALOME_BUILD_DOC) + #FIND_PACKAGE(SalomeDoxygen) + #FIND_PACKAGE(SalomeGraphviz) + #FIND_PACKAGE(SalomeSphinx) + #SALOME_LOG_OPTIONAL_PACKAGE(Doxygen SALOME_BUILD_DOC) + #SALOME_LOG_OPTIONAL_PACKAGE(Graphviz SALOME_BUILD_DOC) + #SALOME_LOG_OPTIONAL_PACKAGE(Sphinx SALOME_BUILD_DOC) + FIND_PACKAGE(Doxygen) + IF(DEFINED ENV{GRAPHVIZ_ROOT_DIR}) + SET(CMAKE_PREFIX_PATH "$ENV{GRAPHVIZ_ROOT_DIR}") + ENDIF() + FIND_PACKAGE(Graphviz) + FIND_PACKAGE(Sphinx) +ENDIF(SALOME_BUILD_DOC) + +IF(SALOME_MED_ENABLE_PYTHON) + #FIND_PACKAGE(SalomePython) + #FIND_PACKAGE(SalomeSWIG) + #SALOME_LOG_OPTIONAL_PACKAGE(Python SALOME_MED_ENABLE_PYTHON) + #SALOME_LOG_OPTIONAL_PACKAGE(SWIG SALOME_MED_ENABLE_PYTHON) + FIND_PACKAGE(PythonInterp) + GET_FILENAME_COMPONENT(_python_dir "${PYTHON_EXECUTABLE}" PATH) + GET_FILENAME_COMPONENT(CMAKE_INCLUDE_PATH "${_python_dir}/../include/python${PYTHON_VERSION_MAJOR}.${PYTHON_VERSION_MINOR}" ABSOLUTE) + GET_FILENAME_COMPONENT(CMAKE_LIBRARY_PATH "${_python_dir}/../lib" ABSOLUTE) + SET(PythonLibs_FIND_VERSION "${PYTHON_VERSION}") + FIND_PACKAGE(PythonLibs) + + FIND_PACKAGE(SWIG) + # Set the extra flags for SWIG for numpy and scipy + SET(SWIG_EXTRA_FLAGS_FOR_NUMPYANDSCIPY) + IF(NUMPY_FOUND) + SET(SWIG_EXTRA_FLAGS_FOR_NUMPYANDSCIPY "-DWITH_NUMPY") + ENDIF(NUMPY_FOUND) + IF(SCIPY_FOUND) + SET(SWIG_EXTRA_FLAGS_FOR_NUMPYANDSCIPY "${SWIG_EXTRA_FLAGS_FOR_NUMPYANDSCIPY};-DWITH_SCIPY") + ENDIF(SCIPY_FOUND) +ENDIF(SALOME_MED_ENABLE_PYTHON) + +# Detection report +#SALOME_PACKAGE_REPORT_AND_CHECK() + +# Directories +# +# Directories have to be given after prerequisites (to be able to use +# Python version string for example). +# =========== +SET(MEDTOOL_INSTALL_BINS bin CACHE PATH "Install path: MEDtool binaries") +SET(MEDTOOL_INSTALL_LIBS lib CACHE PATH "Install path: MEDtool libs") +SET(MEDTOOL_INSTALL_HEADERS include CACHE PATH "Install path: MEDtool headers") +SET(MEDTOOL_INSTALL_SCRIPT_SCRIPTS ${MEDTOOL_INSTALL_BINS} CACHE PATH "Install path: MEDtool scripts") +SET(MEDTOOL_INSTALL_TESTS tests CACHE PATH "Install path: MEDtool tests") +# SET(SALOME_INSTALL_SCRIPT_DATA ${SALOME_INSTALL_BINS} CACHE PATH +# "Install path: SALOME script data") +SET(MEDTOOL_INSTALL_SCRIPT_PYTHON ${MEDTOOL_INSTALL_BINS} CACHE PATH "Install path: MEDtool Python scripts") +# SET(SALOME_INSTALL_APPLISKEL_SCRIPTS ${SALOME_INSTALL_BINS}/appliskel CACHE PATH +# "Install path: SALOME application skeleton - scripts") +# SET(SALOME_INSTALL_APPLISKEL_PYTHON ${SALOME_INSTALL_BINS}/appliskel CACHE PATH +# "Install path: SALOME application skeleton - Python") +# SET(SALOME_INSTALL_CMAKE salome_adm/cmake_files CACHE PATH "Install path: SALOME CMake files") +# SET(SALOME_INSTALL_CMAKE_LOCAL adm_local/cmake_files CACHE PATH +# "Install path: local SALOME CMake files") + +IF(SALOME_MED_ENABLE_PYTHON) + SET(_pydir lib/python${PYTHON_VERSION_MAJOR}.${PYTHON_VERSION_MINOR}/site-packages) + SET(MEDTOOL_INSTALL_PYTHON ${_pydir} CACHE PATH "Install path: MEDtool Python stuff") + SET(MEDTOOL_INSTALL_PYTHON_SHARED ${MEDTOOL_INSTALL_PYTHON}/shared_modules CACHE PATH + "Install path: MEDtool Python shared modules") +ENDIF(SALOME_MED_ENABLE_PYTHON) + +SET(MEDTOOL_INSTALL_RES share/resources CACHE PATH "Install path: MEDTOOL resources") +SET(MEDTOOL_INSTALL_DOC share/doc CACHE PATH "Install path: MEDTOOL documentation") + +# Med specific: + +SET(MEDTOOL_INSTALL_RES_DATA "${MEDTOOL_INSTALL_RES}/med" CACHE PATH "Install path: MEDTOOL specific data") +#SET(SALOME_MED_INSTALL_RES_SCRIPTS "${SALOME_INSTALL_RES}/med" CACHE PATH "Install path: SALOME MED specific scripts") + +#MARK_AS_ADVANCED(SALOME_INSTALL_BINS SALOME_INSTALL_LIBS SALOME_INSTALL_IDLS SALOME_INSTALL_HEADERS) +#MARK_AS_ADVANCED(SALOME_INSTALL_SCRIPT_SCRIPTS SALOME_INSTALL_SCRIPT_DATA SALOME_INSTALL_SCRIPT_PYTHON) +#MARK_AS_ADVANCED(SALOME_INSTALL_APPLISKEL_SCRIPTS SALOME_INSTALL_APPLISKEL_PYTHON SALOME_INSTALL_CMAKE SALOME_INSTALL_CMAKE_LOCAL SALOME_INSTALL_RES) +#MARK_AS_ADVANCED(SALOME_INSTALL_PYTHON SALOME_INSTALL_PYTHON_SHARED SALOME_MED_INSTALL_RES_DATA SALOME_MED_INSTALL_RES_SCRIPTS SALOME_INSTALL_DOC) + +# Header configuration +# ==================== +MEDTOOL_XVERSION(${PROJECT_NAME}) +#SALOME_CONFIGURE_FILE(MED_version.h.in MED_version.h INSTALL ${SALOME_INSTALL_HEADERS}) +#SALOME_CONFIGURE_FILE(VERSION.in VERSION INSTALL ${SALOME_INSTALL_BINS}) +CONFIGURE_FILE(${CMAKE_CURRENT_SOURCE_DIR}/MEDtool_version.h.in ${CMAKE_CURRENT_BINARY_DIR}/MEDtool_version.h) +INSTALL(FILES ${CMAKE_CURRENT_BINARY_DIR}/MEDtool_version.h DESTINATION ${MEDTOOL_INSTALL_HEADERS}) + +# Accumulate environment variables for MED module +#SALOME_ACCUMULATE_ENVIRONMENT(PYTHONPATH NOCHECK ${CMAKE_INSTALL_PREFIX}/${SALOME_INSTALL_BINS} +# ${CMAKE_INSTALL_PREFIX}/${SALOME_INSTALL_PYTHON}) +#SALOME_ACCUMULATE_ENVIRONMENT(LD_LIBRARY_PATH NOCHECK ${CMAKE_INSTALL_PREFIX}/${SALOME_INSTALL_LIBS}) + + +# Sources +# ======== +IF(WIN32) + ADD_DEFINITIONS("-D_USE_MATH_DEFINES") +ENDIF(WIN32) + +ADD_SUBDIRECTORY(src) +#ADD_SUBDIRECTORY(adm_local) + +IF(SALOME_BUILD_DOC) + ADD_SUBDIRECTORY(doc) +ENDIF(SALOME_BUILD_DOC) + +#ADD_SUBDIRECTORY(adm_local_without_kernel) + +IF(NOT SALOME_MED_MICROMED) + IF(SALOME_MED_WITH_FILE_EXAMPLES) + ADD_SUBDIRECTORY(resources) + ENDIF(SALOME_MED_WITH_FILE_EXAMPLES) +ENDIF(NOT SALOME_MED_MICROMED) + +# Configuration export +# ==================== + +# List of targets in this project we want to make visible to the rest of the world. +# They all have to be INSTALL'd with the option "EXPORT ${PROJECT_NAME}TargetGroup" +SET(_${PROJECT_NAME}_exposed_targets + interpkernel medcoupling medcouplingremapper) + +IF(NOT SALOME_MED_MICROMED) + LIST(APPEND _${PROJECT_NAME}_exposed_targets medloader) + IF(SALOME_MED_ENABLE_RENUMBER) + LIST(APPEND _${PROJECT_NAME}_exposed_targets renumbercpp) + ENDIF() + IF(SALOME_MED_ENABLE_PARTITIONER) + LIST(APPEND _${PROJECT_NAME}_exposed_targets medpartitionercpp) + IF(SALOME_BUILD_TESTS) + LIST(APPEND _${PROJECT_NAME}_exposed_targets MEDPARTITIONERTest) + ENDIF() + ENDIF() + IF(SALOME_BUILD_TESTS) + LIST(APPEND _${PROJECT_NAME}_exposed_targets InterpKernelTest) + ENDIF() +ENDIF() + +IF(SALOME_USE_MPI) + LIST(APPEND _${PROJECT_NAME}_exposed_targets paramedmem) + IF(NOT SALOME_MED_MICROMED) + LIST(APPEND _${PROJECT_NAME}_exposed_targets paramedloader) + ENDIF() + IF(SALOME_BUILD_TESTS) + IF(NOT SALOME_MED_MICROMED) + LIST(APPEND _${PROJECT_NAME}_exposed_targets ParaMEDMEMTest) + ENDIF() + ENDIF() +ENDIF() + +# Add all targets to the build-tree export set + +EXPORT(TARGETS ${_${PROJECT_NAME}_exposed_targets} + FILE ${PROJECT_BINARY_DIR}/${PROJECT_NAME}Targets.cmake) + +# Create the configuration files: +# - in the build tree: + +# Ensure the variables are always defined for the configure (even if empty): +# SET(KERNEL_ROOT_DIR "${KERNEL_ROOT_DIR}") +# SET(GUI_ROOT_DIR "${GUI_ROOT_DIR}") +# SET(MEDFILE_ROOT_DIR "${MEDFILE_ROOT_DIR}") +# SET(MPI_ROOT_DIR "${MPI_ROOT_DIR}") +# SET(HDF5_ROOT_DIR "${HDF5_ROOT_DIR}") +# SET(OMNIORB_ROOT_DIR "${OMNIORB_ROOT_DIR}") +# SET(PTHREAD_ROOT_DIR "${PTHREAD_ROOT_DIR}") +# SET(BOOST_ROOT_DIR "${BOOST_ROOT_DIR}") +# SET(SWIG_ROOT_DIR "${SWIG_ROOT_DIR}") +# SET(PYTHON_ROOT_DIR "${PYTHON_ROOT_DIR}") +# SET(CPPUNIT_ROOT_DIR "${CPPUNIT_ROOT_DIR}") +# SET(GRAPHVIZ_ROOT_DIR "${GRAPHVIZ_ROOT_DIR}") +# SET(DOXYGEN_ROOT_DIR "${DOXYGEN_ROOT_DIR}") +# SET(SPHINX_ROOT_DIR "${SPHINX_ROOT_DIR}") + +# SET(METIS_ROOT_DIR "${METIS_ROOT_DIR}") +# SET(PARMETIS_ROOT_DIR "${PARMETIS_ROOT_DIR}") +# SET(SCOTCH_ROOT_DIR "${SCOTCH_ROOT_DIR}") +# SET(XDR_ROOT_DIR "${XDR_ROOT_DIR}") + +# - in the install tree: +# Get the relative path of the include directory so +# we can register it in the generated configuration files: +SET(CONF_INCLUDE_DIRS "${CMAKE_INSTALL_PREFIX}/${INSTALL_INCLUDE_DIR}") + +# Build variables that will be expanded when configuring Salome<MODULE>Config.cmake: +# SALOME_CONFIGURE_PREPARE(Metis ParMetis Scotch XDR CAS Qt4 CppUnit Graphviz Doxygen Sphinx MPI omniORB +# PThread Boost libXml2 Python HDF5 MEDFile) + +# INCLUDE(CMakePackageConfigHelpers) +# CONFIGURE_PACKAGE_CONFIG_FILE(${PROJECT_NAME}Config.cmake.in +# ${PROJECT_BINARY_DIR}/to_install/${PROJECT_NAME}Config.cmake +# INSTALL_DESTINATION "${SALOME_INSTALL_CMAKE}_LOCAL" +# PATH_VARS CONF_INCLUDE_DIRS SALOME_INSTALL_CMAKE_LOCAL CMAKE_INSTALL_PREFIX +# KERNEL_ROOT_DIR GUI_ROOT_DIR MEDFILE_ROOT_DIR MPI_ROOT_DIR +# HDF5_ROOT_DIR OMNIORB_ROOT_DIR PTHREAD_ROOT_DIR BOOST_ROOT_DIR +# SWIG_ROOT_DIR PYTHON_ROOT_DIR CPPUNIT_ROOT_DIR GRAPHVIZ_ROOT_DIR DOXYGEN_ROOT_DIR +# SPHINX_ROOT_DIR METIS_ROOT_DIR PARMETIS_ROOT_DIR SCOTCH_ROOT_DIR XDR_ROOT_DIR) + +#WRITE_BASIC_PACKAGE_VERSION_FILE(${PROJECT_BINARY_DIR}/${PROJECT_NAME}ConfigVersion.cmake +# VERSION ${${PROJECT_NAME_UC}_VERSION} +# COMPATIBILITY AnyNewerVersion) + +# Install the CMake configuration files: +# INSTALL(FILES +# "${PROJECT_BINARY_DIR}/to_install/${PROJECT_NAME}Config.cmake" +# "${PROJECT_BINARY_DIR}/${PROJECT_NAME}ConfigVersion.cmake" +# DESTINATION "${SALOME_INSTALL_CMAKE_LOCAL}") + +# Install the export set for use with the install-tree +#INSTALL(EXPORT ${PROJECT_NAME}TargetGroup DESTINATION "${SALOME_INSTALL_CMAKE_LOCAL}" +# FILE ${PROJECT_NAME}Targets.cmake) diff --git a/src/medtool/MEDtool_version.h.in b/src/medtool/MEDtool_version.h.in new file mode 100644 index 000000000..701912571 --- /dev/null +++ b/src/medtool/MEDtool_version.h.in @@ -0,0 +1,44 @@ +// Copyright (C) 2015 CEA/DEN, EDF R&D, OPEN CASCADE +// +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, 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 +// 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 +// + +#if !defined(__MEDTOOL_VERSION_H__) +#define __MEDTOOL_VERSION_H__ + +/*! + Specify version of MEDtool, as follows + + MEDTOOL_VERSION_MAJOR : (integer) number identifying major version + MEDTOOL_VERSION_MINOR : (integer) number identifying minor version + MEDTOOL_VERSION_MAINTENANCE : (integer) number identifying maintenance version + MEDTOOL_VERSION_STR : (string) complete version number "major.minor.maintenance" + MEDTOOL_VERSION : (hex) complete version number (major << 16) + (minor << 8) + maintenance + MEDTOOL_DEVELOPMENT : (integer) indicates development version when set to 1 +*/ + +#define MEDTOOL_VERSION_MAJOR @MEDTOOL_MAJOR_VERSION@ +#define MEDTOOL_VERSION_MINOR @MEDTOOL_MINOR_VERSION@ +#define MEDTOOL_VERSION_MAINTENANCE @MEDTOOL_PATCH_VERSION@ +#define MEDTOOL_VERSION_STR "@MEDTOOL_VERSION@" +#define MEDTOOL_VERSION @MEDTOOL_XVERSION@ +#define MEDTOOL_DEVELOPMENT @MEDTOOL_VERSION_DEV@ + +#endif // __MEDTOOL_VERSION_H__ diff --git a/src/medtool/cmake_files/FindCppUnit.cmake b/src/medtool/cmake_files/FindCppUnit.cmake new file mode 100644 index 000000000..7e68e5645 --- /dev/null +++ b/src/medtool/cmake_files/FindCppUnit.cmake @@ -0,0 +1,95 @@ +# - Find CppUnit +# Sets the following variables: +# CPPUNIT_INCLUDE_DIRS - path to the CppUnit include directory +# CPPUNIT_LIBRARIES - path to the CppUnit libraries to be linked against +# CPPUNIT_DEFINITIONS - specific CppUnit definitions to be added +# +# The header cppunit/extensions/HelperMacros.h is looked for. +# The following libraries are searched +# cppunit_dll, or cppunitd_dll (Windows) +# cppunit (Linux) +# + +######################################################################### +# Copyright (C) 2007-2015 CEA/DEN, EDF R&D, OPEN CASCADE +# +# Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +# CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, 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 +# 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 +# + +IF(NOT CppUnit_FIND_QUIETLY) + MESSAGE(STATUS "Looking for CppUnit ...") +ENDIF() + +# Headers +SET(CPPUNIT_ROOT_DIR $ENV{CPPUNIT_ROOT_DIR} CACHE PATH "Path to the CPPUNIT.") +IF(CPPUNIT_ROOT_DIR) + LIST(APPEND CMAKE_INCLUDE_PATH "${CPPUNIT_ROOT_DIR}/include") + LIST(APPEND CMAKE_PROGRAM_PATH "${CPPUNIT_ROOT_DIR}/bin") +ENDIF(CPPUNIT_ROOT_DIR) + +SET(CPPUNIT_INCLUDE_TO_FIND cppunit/extensions/HelperMacros.h) +FIND_PATH(CPPUNIT_INCLUDE_DIRS ${CPPUNIT_INCLUDE_TO_FIND}) + +# Libraries +IF(WIN32) + IF(CMAKE_BUILD_TYPE STREQUAL Debug) + FIND_LIBRARY(CPPUNIT_LIBRARIES cppunitd_dll) + ELSE(CMAKE_BUILD_TYPE STREQUAL Debug) + FIND_LIBRARY(CPPUNIT_LIBRARIES cppunit_dll) + ENDIF(CMAKE_BUILD_TYPE STREQUAL Debug) +ELSE(WIN32) + FIND_PROGRAM(CPPUNIT_CONFIG_BIN cppunit-config) + IF(NOT CPPUNIT_CONFIG_BIN) + MESSAGE(FATAL_ERROR "Error in CPPUNIT detection ! cppunit-config executable not found !") + ENDIF(NOT CPPUNIT_CONFIG_BIN) + EXECUTE_PROCESS(COMMAND ${CPPUNIT_CONFIG_BIN} --libs OUTPUT_VARIABLE CPPUNIT_LDFLAGS) + STRING(STRIP ${CPPUNIT_LDFLAGS} CPPUNIT_LDFLAGS) + STRING(REPLACE " " ";" LDFLAGS_LIST ${CPPUNIT_LDFLAGS}) + FOREACH(LDFLAG ${LDFLAGS_LIST}) + STRING(REGEX MATCH "^-L.*" LIBDIR "${LDFLAG}") + STRING(REGEX MATCH "^-l.*" LIB "${LDFLAG}") + IF(LIBDIR) + STRING(REGEX REPLACE "^-L" "" LIBDIR ${LIBDIR}) + LIST(APPEND CMAKE_LIBRARY_PATH ${LIBDIR}) + ELSEIF(LIB) + STRING(REGEX REPLACE "^-l" "" LIB ${LIB}) + LIST(APPEND LIBS ${LIB}) + ELSE() + MESSAGE(FATAL_ERROR "Unrecognized token \"${LDFLAG}\" in the output of cppunit-config --libs") + ENDIF() + ENDFOREACH(LDFLAG ${LDFLAGS_LIST}) + FOREACH(LIB ${LIBS}) + FIND_LIBRARY(CPPUNIT_SUBLIB_${LIB} ${LIB}) + IF(NOT CPPUNIT_SUBLIB_${LIB}) + MESSAGE(FATAL_ERROR "Error in CPPUNIT detection! Fail to locate the needed library ${LIB}!") + ENDIF(NOT CPPUNIT_SUBLIB_${LIB}) + LIST(APPEND CPPUNIT_LIBRARIES ${CPPUNIT_SUBLIB_${LIB}}) + ENDFOREACH(LIB ${LIBS}) +# MESSAGE("**** ${CPPUNIT_LIBRARIES}") +ENDIF(WIN32) + +# Global variables +SET(CPPUNIT_DEFINITIONS) +IF(WIN32) + SET(CPPUNIT_DEFINITIONS -DCPPUNIT_DLL) +ENDIF(WIN32) + +INCLUDE(FindPackageHandleStandardArgs) +FIND_PACKAGE_HANDLE_STANDARD_ARGS(CppUnit REQUIRED_VARS CPPUNIT_INCLUDE_DIRS CPPUNIT_LIBRARIES) diff --git a/src/medtool/cmake_files/FindGraphviz.cmake b/src/medtool/cmake_files/FindGraphviz.cmake new file mode 100644 index 000000000..be92feb5f --- /dev/null +++ b/src/medtool/cmake_files/FindGraphviz.cmake @@ -0,0 +1,71 @@ +# - Graphviz detection +# +# Output variables: GRAPHVIZ_EXECUTABLE - where is executable 'dot' takes place. +# GRAPHVIZ_INCLUDE_DIRS - where to find headers. +# GRAPHVIZ_LIBRARIES - where to get libraries. +# GRAPHVIZ_VERSION - Graphviz version +# GRAPHVIZ_DEFINITIONS - Graphviz definitions +# GRAPHVIZ_FOUND - True if Graphviz was found. +# +########################################################################### +# Copyright (C) 2007-2015 CEA/DEN, EDF R&D, OPEN CASCADE +# +# Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +# CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, 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 +# 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 +# + +FIND_PROGRAM(GRAPHVIZ_EXECUTABLE dot) + +FIND_PATH(GRAPHVIZ_INCLUDE_DIR NAMES graphviz/cgraph.h) +SET(GRAPHVIZ_INCLUDE_DIRS ${GRAPHVIZ_INCLUDE_DIR} ${GRAPHVIZ_INCLUDE_DIR}/graphviz) + +FIND_LIBRARY(GRAPHVIZ_cdt_LIBRARY NAMES cdt PATH_SUFFIXES bin) +FIND_LIBRARY(GRAPHVIZ_graph_LIBRARY NAMES cgraph PATH_SUFFIXES bin) +FIND_LIBRARY(GRAPHVIZ_gvc_LIBRARY NAMES gvc PATH_SUFFIXES bin) +FIND_LIBRARY(GRAPHVIZ_pathplan_LIBRARY NAMES pathplan PATH_SUFFIXES bin) + +SET(GRAPHVIZ_LIBRARIES + ${GRAPHVIZ_cdt_LIBRARY} + ${GRAPHVIZ_graph_LIBRARY} + ${GRAPHVIZ_gvc_LIBRARY} + ${GRAPHVIZ_pathplan_LIBRARY} + ) + +IF(GRAPHVIZ_EXECUTABLE) + EXECUTE_PROCESS(COMMAND ${GRAPHVIZ_EXECUTABLE} "-V" ERROR_VARIABLE GRAPHVIZ_VERSION ERROR_STRIP_TRAILING_WHITESPACE) + STRING(REGEX REPLACE ".* ([0-9.]+) .*" "\\1" GRAPHVIZ_VERSION "${GRAPHVIZ_VERSION}") +ENDIF() + +SET(GRAPHVIZ_DEFINITIONS) +IF("${GRAPHVIZ_VERSION}" VERSION_LESS "2.36.0") + SET(GRAPHVIZ_DEFINITIONS -DWITH_CGRAPH) +ENDIF() + +## Don't detect cgraph on Windows +#IF(NOT WIN32) +# FIND_LIBRARY(GRAPHVIZ_cgraph_LIBRARY NAMES cgraph PATH_SUFFIXES bin) +# SET(GRAPHVIZ_LIBRARIES ${GRAPHVIZ_cgraph_LIBRARY}) +#ENDIF() + +# Handle the standard arguments of the find_package() command: +INCLUDE(FindPackageHandleStandardArgs) +FIND_PACKAGE_HANDLE_STANDARD_ARGS(Graphviz REQUIRED_VARS + GRAPHVIZ_EXECUTABLE + GRAPHVIZ_LIBRARIES + GRAPHVIZ_INCLUDE_DIRS) diff --git a/src/medtool/cmake_files/FindMEDFile.cmake b/src/medtool/cmake_files/FindMEDFile.cmake new file mode 100644 index 000000000..82b8eee53 --- /dev/null +++ b/src/medtool/cmake_files/FindMEDFile.cmake @@ -0,0 +1,54 @@ +# - Find MED file installation +# +# The following variable are set: +# MEDFILE_INCLUDE_DIRS +# MEDFILE_LIBRARIES +# MEDFILE_C_LIBRARIES +# MEDFILE_F_LIBRARIES +# +# The CMake (or environment) variable MEDFILE_ROOT_DIR can be set to +# guide the detection and indicate a root directory to look into. +# +############################################################################ +# Copyright (C) 2007-2015 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, 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 +# 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 +# + +# ------ + +MESSAGE(STATUS "Check for medfile ...") + +# ------ + +SET(MEDFILE_ROOT_DIR $ENV{MEDFILE_ROOT_DIR} CACHE PATH "Path to the MEDFile.") +IF(MEDFILE_ROOT_DIR) + LIST(APPEND CMAKE_PREFIX_PATH "${MEDFILE_ROOT_DIR}") +ENDIF(MEDFILE_ROOT_DIR) + +FIND_PATH(MEDFILE_INCLUDE_DIRS med.h) +#FIND_PROGRAM(MDUMP mdump) +FIND_LIBRARY(MEDFILE_C_LIBRARIES NAMES medC) +FIND_LIBRARY(MEDFILE_F_LIBRARIES NAMES med) +IF(MEDFILE_F_LIBRARIES) + SET(MEDFILE_LIBRARIES ${MEDFILE_C_LIBRARIES} ${MEDFILE_F_LIBRARIES}) +ELSE(MEDFILE_F_LIBRARIES) + SET(MEDFILE_LIBRARIES ${MEDFILE_C_LIBRARIES}) +ENDIF(MEDFILE_F_LIBRARIES) + +INCLUDE(FindPackageHandleStandardArgs) +FIND_PACKAGE_HANDLE_STANDARD_ARGS(MEDFile REQUIRED_VARS MEDFILE_INCLUDE_DIRS MEDFILE_LIBRARIES) diff --git a/src/medtool/cmake_files/FindMetis.cmake b/src/medtool/cmake_files/FindMetis.cmake new file mode 100644 index 000000000..5173cba6d --- /dev/null +++ b/src/medtool/cmake_files/FindMetis.cmake @@ -0,0 +1,50 @@ +# Copyright (C) 2007-2015 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, 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 +# 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 +# + +# ------ + +MESSAGE(STATUS "Check for metis ...") + +SET(METIS_ROOT_DIR $ENV{METIS_ROOT_DIR} CACHE PATH "Path to the METIS.") +IF(METIS_ROOT_DIR) + LIST(APPEND CMAKE_LIBRARY_PATH "${METIS_ROOT_DIR}") + LIST(APPEND CMAKE_LIBRARY_PATH "${METIS_ROOT_DIR}/lib") + LIST(APPEND CMAKE_INCLUDE_PATH "${METIS_ROOT_DIR}/Lib") + LIST(APPEND CMAKE_INCLUDE_PATH "${METIS_ROOT_DIR}/include") +ENDIF(METIS_ROOT_DIR) + +FIND_LIBRARY(METIS_LIBRARIES metis) +FIND_PATH(METIS_INCLUDE_DIRS metis.h) + +INCLUDE(FindPackageHandleStandardArgs) +FIND_PACKAGE_HANDLE_STANDARD_ARGS(Metis REQUIRED_VARS METIS_INCLUDE_DIRS METIS_LIBRARIES) +FILE(READ ${METIS_INCLUDE_DIRS}/metis.h metis_h_content) +STRING(REPLACE "\n" ";" list_metis_h_content ${metis_h_content}) +FOREACH(ln ${list_metis_h_content}) + IF("${ln}" MATCHES "^#define METIS_VER_MAJOR") + STRING(REPLACE "#define METIS_VER_MAJOR" "" metis_major_version "${ln}") + STRING(STRIP "${metis_major_version}" metis_major_version) + ENDIF("${ln}" MATCHES "^#define METIS_VER_MAJOR") +ENDFOREACH(ln ${list_metis_h_content}) +IF(metis_major_version STREQUAL 5) + SET(MEDTOOL_METIS_V5 1) + MESSAGE(STATUS "Metis maj version 5 detected.") +ELSE(metis_major_version STREQUAL 5) + MESSAGE(STATUS "Metis maj version 4 detected.") +ENDIF(metis_major_version STREQUAL 5) diff --git a/src/medtool/cmake_files/FindScotch.cmake b/src/medtool/cmake_files/FindScotch.cmake new file mode 100644 index 000000000..b63d30dcb --- /dev/null +++ b/src/medtool/cmake_files/FindScotch.cmake @@ -0,0 +1,35 @@ +# Copyright (C) 2007-2015 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, 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 +# 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 +# + +# ------ + +MESSAGE(STATUS "Check for scotch ...") + +SET(SCOTCH_ROOT_DIR $ENV{SCOTCH_ROOT_DIR} CACHE PATH "Path to the SCOTCH.") +IF(SCOTCH_ROOT_DIR) + LIST(APPEND CMAKE_PREFIX_PATH "${SCOTCH_ROOT_DIR}") +ENDIF(SCOTCH_ROOT_DIR) + +FIND_LIBRARY(SCOTCH_LIBRARIES scotch) +FIND_LIBRARY(SCOTCH_ERR_LIBRARIES scotcherr) +SET(SCOTCH_LIBRARIES ${SCOTCH_LIBRARIES} ${SCOTCH_ERR_LIBRARIES}) +FIND_PATH(SCOTCH_INCLUDE_DIRS scotch.h PATH_SUFFIXES "/scotch") + +INCLUDE(FindPackageHandleStandardArgs) +FIND_PACKAGE_HANDLE_STANDARD_ARGS(Scotch REQUIRED_VARS SCOTCH_INCLUDE_DIRS SCOTCH_LIBRARIES) diff --git a/src/medtool/cmake_files/FindSphinx.cmake b/src/medtool/cmake_files/FindSphinx.cmake new file mode 100644 index 000000000..94cc2ae05 --- /dev/null +++ b/src/medtool/cmake_files/FindSphinx.cmake @@ -0,0 +1,43 @@ +# - Sphinx detection +# +# Output variables: +# SPHINX_EXECUTABLE - path to the Sphinx executable +# SPHINX_PYTHONPATH - path to the Sphinx Python modules +# +########################################################################### +# Copyright (C) 2007-2015 CEA/DEN, EDF R&D, OPEN CASCADE +# +# Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +# CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, 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 +# 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 +# + +FIND_PROGRAM(SPHINX_EXECUTABLE sphinx-build PATH_SUFFIXES Scripts) +FIND_PROGRAM(SPHINX_APIDOC_EXECUTABLE sphinx-apidoc PATH_SUFFIXES Scripts) + +# Get root dir locally, going up two levels from the exec: +GET_FILENAME_COMPONENT(_tmp_ROOT_DIR "${SPHINX_EXECUTABLE}" PATH) +GET_FILENAME_COMPONENT(_tmp_ROOT_DIR "${_tmp_ROOT_DIR}" PATH) +IF(WIN32) + SET(SPHINX_PYTHONPATH "${_tmp_ROOT_DIR}/lib/site-packages") +ELSE() + SET(SPHINX_PYTHONPATH "${_tmp_ROOT_DIR}/lib/python${PYTHON_VERSION_MAJOR}.${PYTHON_VERSION_MINOR}/site-packages") +ENDIF() +# Handle the standard arguments of the find_package() command: +INCLUDE(FindPackageHandleStandardArgs) +FIND_PACKAGE_HANDLE_STANDARD_ARGS(Sphinx REQUIRED_VARS SPHINX_EXECUTABLE SPHINX_APIDOC_EXECUTABLE) diff --git a/src/medtool/cmake_files/FindXDR.cmake b/src/medtool/cmake_files/FindXDR.cmake new file mode 100644 index 000000000..c0eaf86e1 --- /dev/null +++ b/src/medtool/cmake_files/FindXDR.cmake @@ -0,0 +1,38 @@ +# Copyright (C) 2007-2015 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, 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 +# 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 +# + +MESSAGE(STATUS "Check for XDR ...") + +FIND_PATH(XDR_INCLUDE_DIRS rpc/xdr.h) +SET(XDR_DEFINITIONS "-DHAS_XDR") + +IF(WIN32) + FIND_LIBRARY(XDR_LIBRARIES xdr) # To get the .lib file from XDR + FIND_PATH(XDR_INCLUDE_DIRS2 stdint.h PATH_SUFFIXES src/msvc) # To get the stdint.h from XDR (needed by types.h) + IF(XDR_INCLUDE_DIRS) + IF(XDR_INCLUDE_DIRS2) + LIST(APPEND XDR_INCLUDE_DIRS "${XDR_INCLUDE_DIRS2}") + ELSE() + SET(XDR_INCLUDE_DIRS "${XDR_INCLUDE_DIRS2}") # Make the detection fail + ENDIF() + ENDIF() +ENDIF(WIN32) + +INCLUDE(FindPackageHandleStandardArgs) +FIND_PACKAGE_HANDLE_STANDARD_ARGS(XDR REQUIRED_VARS XDR_INCLUDE_DIRS) diff --git a/src/medtool/cmake_files/MEDtoolMacros.cmake b/src/medtool/cmake_files/MEDtoolMacros.cmake new file mode 100644 index 000000000..ee476091f --- /dev/null +++ b/src/medtool/cmake_files/MEDtoolMacros.cmake @@ -0,0 +1,60 @@ +# Copyright (C) 2015 CEA/DEN, EDF 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, 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 +# 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 +# + +#################################################################### +# _TOHEXA() +# Convert a number (smaller than 16) into hexadecimal representation +# with a leading 0. +MACRO(_TOHEXA num result) + SET(_hexa_map a b c d e f) + IF(${num} LESS 10) + SET(${result} "0${num}") + ELSE() + MATH(EXPR _res "${num}-10" ) + LIST(GET _hexa_map ${_res} _out) + SET(${result} "0${_out}") + ENDIF() +ENDMACRO(_TOHEXA) + +#################################################################### +# MEDTOOL_XVERSION() +# +# Computes hexadecimal version of MEDTOOL package +# +# USAGE: MEDTOOL_XVERSION(package) +# +# ARGUMENTS: +# +# package: IN: MEDTOOL package name +# +# The macro reads MEDTOOL package version from PACKAGE_VERSION variable +# (note package name are uppercase); +# hexadecimal version value in form 0xAABBCC (where AA, BB and CC are +# major, minor and maintenance components of package version in +# hexadecimal form) is put to the PACKAGE_XVERSION variable +MACRO(MEDTOOL_XVERSION pkg) + STRING(TOUPPER ${pkg} _pkg_UC) + IF(${_pkg_UC}_VERSION) + SET(_major) + SET(_minor) + SET(_patch) + _TOHEXA(${${_pkg_UC}_MAJOR_VERSION} _major) + _TOHEXA(${${_pkg_UC}_MINOR_VERSION} _minor) + _TOHEXA(${${_pkg_UC}_PATCH_VERSION} _patch) + SET(${_pkg_UC}_XVERSION "0x${_major}${_minor}${_patch}") + ENDIF() +ENDMACRO(MEDTOOL_XVERSION) diff --git a/src/medtool/resources/CMakeLists.txt b/src/medtool/resources/CMakeLists.txt new file mode 100644 index 000000000..6d185dc17 --- /dev/null +++ b/src/medtool/resources/CMakeLists.txt @@ -0,0 +1,235 @@ +# Copyright (C) 2012-2015 CEA/DEN, EDF 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, 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 +# 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(MED_RESOURCES_FILES + #boitenew.cnc + #boitenew.inp + #boitenew.xyz + #Case1.cnc + #Case1.inp + #Case1.xyz + #cube.cnc + #cube.inp + #cube.xyz + #test3.cnc + #test3.inp + #test3.xyz + #titi.cnc + #titi.inp + #titi.xyz + #carre_en_quad4.med + #carre_en_quad4_seg2.med + #cas_defaut_domaine_fluide.med + #ChampsDarcy.med + #cube_hexa8.med + #cube_hexa8_quad4.med + #darcy_1.1_res.med + #darcy_1.3_resCASTEM.med + #darcy_1.3_resPORFLOW.med + #darcy_1.3_resTRACES.med + #darcy2_Castem_EFMH.med + #darcy2_Castem_qua_EFMH.med + #darcy2_Castem_qua_VF.med + #Darcy3_3D_H_10x10x10_2.med + #Darcy3_3D_H_10x10x10.sauve + #dx200_dy1_avec_2couches.sauve + #elle_2D_QT_10x10.sauve + #elle_2D_QT_2x2.sauve + #elle_2D_QT_40x40.sauve + #elle_2D_QT_4x4.sauve + #elle_3D_HPr_10x10x10_2.med + #elle_3D_HPr_10x10x10.sauve + #elle_3D_HPr_2x2x2_2.med + #elle_3D_HPr_2x2x2.sauve + #elle_3D_HPr_4x4x4_2.med + #elle_3D_HPr_4x4x4.sauve + #extendedtransport53_triangles.med + #geomMesh_nomorereadable21.med + #geomMesh22.med + #H_CastCast_EFMH_I129_COUPLEX1.med + #H_CastCast_VF_I129_COUPLEX1.med + #H_CastCast_VF_Se79_COUPLEX1.med + #H_CastPorf_I129_COUPLEX1.med + #H_CastPorf_Se79_COUPLEX1.med + #H_PorfCast_EFMH_I129_COUPLEX1.med + #H_PorfCast_EFMH_Se79_COUPLEX1.med + #H_PorfPorf_I129_COUPLEX1.med + #H_Traces_I129_COUPLEX1.med + #H_Traces_Se79_COUPLEX1.med + # inclusion_2d_raf.sauve + # inclusion_2d.sauve + # mail_ktest1-3-hexa.sauve + # mail_ktest1-3-tetra.sauve + # mail_ktest3-1.sauve + # mail_ktest3-2.sauve + # maill.00.med + # maill.00_nofield.med + # maill.00_nomesh.med + # maill.00_without_seg2.med + # maill.0.med + # maillage_5_5_5.med + # maillage_andra2_100elts.sauve + # maillage_cas2_2d.sauve + # maillage_cas4_234elts.sauve + # maillage_CHEMVAL_100elts.sauve + # maillage_CHEMVAL_40elts.sauve + # maillage_chemvalIV_cas1_100elts.sauve + # maillage_chemvalIV_cas1_40elts.med + # maillage_chemvalIV_cas1_40elts.sauve + # maillage_UniSegFam.med + # mail_test1-1-qua.sauve + # mail_test1-1-tri.sauve + # mail_test1-2-qua.sauve + # mail_test1-2-tri.sauve + # mail-test1-4-1.sauve + # mail-test1-4-2.sauve + # mesh_nomorereadable21.med + # mesh.med + # Mistrat.med + #Old_ChampsDarcy.med + #Old_darcy_1.1_res.med + #Old_darcy_1.3_resCASTEM.med + #Old_darcy_1.3_resPORFLOW.med + #Old_darcy_1.3_resTRACES.med + #Old_darcy2_Castem_EFMH.med + #Old_darcy2_Castem_qua_EFMH.med + #Old_darcy2_Castem_qua_VF.med + #Old_H_CastCast_EFMH_I129_COUPLEX1.med + #Old_H_CastCast_VF_I129_COUPLEX1.med + #Old_H_CastCast_VF_Se79_COUPLEX1.med + #Old_H_CastPorf_I129_COUPLEX1.med + #Old_H_CastPorf_Se79_COUPLEX1.med + #Old_H_PorfCast_EFMH_I129_COUPLEX1.med + #Old_H_PorfCast_EFMH_Se79_COUPLEX1.med + #Old_H_PorfPorf_I129_COUPLEX1.med + #Old_H_PorfPorf_Se79_COUPLEX1.med + #Old_H_Traces_I129_COUPLEX1.med + #Old_H_Traces_Se79_COUPLEX1.med + #Old_maillage_chemvalIV_cas1_40elts.med + #pointe_nomorereadable21.med + pointe.med + #poly3D.med + #polyedres.med + #polygones.med + #recoll_bord.med + #test19.med + # test_2D.med + # trio_2D.med + # TimeStamps.med + # zzzz121b.med + # zzzz121b_without_tr6.med + # UnitTetra.med + # GeneralTetra.med + # NudgedSimpler.med + # NudgedTetra.med + # CornerTetra.med + # SimpleIncludedTetra.med + # SimpleIncludingTetra.med + Test2D.med + Test2Dpoly.med + Test3D.med + Test3Dpoly.med + #UnitTetraDegenT.med + # DegenEdgeXY.med + # DegenFaceXYZ.med + # DegenTranslatedInPlane.med + # ComplexIncludedTetra.med + # ComplexIncludingTetra.med + # HalfstripOnly.med + # HalfstripOnly2.med + #SimpleHalfstripOnly.med + #GenTetra1.med + #GenTetra2.med + #TrickyTetra1.med + LargeUnitTetra.med + # LargeInconsistentTetra.med + # DividedUnitTetraSimpler.med + # DividedUnitTetra.med + # NudgedDividedUnitTetra.med + # NudgedDividedUnitTetraSimpler.med + # DividedGenTetra1.med + # DividedGenTetra2.med + # Box1.med + # Box2.med + # Box3.med + # Box1Moderate.med + # Box2Moderate.med + # BoxModSmall1.med + # BoxModSmall2.med + # BoxEvenSmaller1.med + # TinyBox.med + # BoxHexa1.med + # BoxHexa2.med + # MovedHexaBox1.med + # MovedHexaBox2.med + # BoxTetra2.med + square1.med + # square1_split + # square1_split1.med + # square1_split2.med + # square1_split3.med + square2.med + # square2_split + # square2_split1.med + # square2_split2.med + # testStructCart3D.med + # Mesh3D_10_2d1.med + # Mesh3D_10_2d2.med + # Mesh3D_11.med + Pol1.fig + Pol2.fig + Pol3.fig + Pol4.fig + # blow5_ascii.case + # blow5_ascii.geo + # blow5_ascii_cd_displacement + # blow5_ascii_cd_thickness + # blow5_ascii_pd_displacement + # blow5_ascii_pd_thickness + #test_2D.sauve + #allPillesTest.sauv + #BDC-714.sauv + #portico_3subs.sauv + agitateur.med + ) + +# IF(MED_ENABLE_GUI) +# FILE(GLOB MED_RESOURCES_PNG "${CMAKE_CURRENT_SOURCE_DIR}/*.png") +# SET(MED_RESOURCES_FILES +# ${MED_RESOURCES_FILES} +# ModuleMed.png +# Data.png +# Infos.png +# Structure.png +# explore_med_file.png +# field_selection.png +# med_mesh.png +# med_field.png +# mesh_selection.png +# ) +# ENDIF(MED_ENABLE_GUI) + +INSTALL(FILES ${MED_RESOURCES_FILES} DESTINATION ${MEDTOOL_INSTALL_RES_DATA}) + +#MESSAGE(STATUS "Creation of ${CMAKE_CURRENT_BINARY_DIR}/MEDCatalog.xml") +#CONFIGURE_FILE(${CMAKE_CURRENT_SOURCE_DIR}/MEDCatalog.xml.in ${CMAKE_CURRENT_BINARY_DIR}/MEDCatalog.xml @ONLY) +#MESSAGE(STATUS "Creation of ${CMAKE_CURRENT_BINARY_DIR}/SalomeApp.xml") +#CONFIGURE_FILE(${CMAKE_CURRENT_SOURCE_DIR}/SalomeApp.xml.in ${CMAKE_CURRENT_BINARY_DIR}/SalomeApp.xml @ONLY) + +#INSTALL(FILES ${CMAKE_CURRENT_BINARY_DIR}/MEDCatalog.xml ${CMAKE_CURRENT_BINARY_DIR}/SalomeApp.xml DESTINATION ${SALOME_MED_INSTALL_RES_DATA}) diff --git a/src/medtool/resources/LargeUnitTetra.med b/src/medtool/resources/LargeUnitTetra.med new file mode 100644 index 000000000..99ad8003b Binary files /dev/null and b/src/medtool/resources/LargeUnitTetra.med differ diff --git a/src/medtool/resources/Pol1.fig b/src/medtool/resources/Pol1.fig new file mode 100644 index 000000000..cee7eb792 --- /dev/null +++ b/src/medtool/resources/Pol1.fig @@ -0,0 +1,15 @@ +#FIG 3.2 Produced by xfig version 3.2.5-alpha5 +Landscape +Center +Metric +Letter +100.00 +Single +-2 +1200 2 +5 1 0 1 0 7 50 -1 -1 0.000 0 1 0 0 2700.000 4800.000 3600 6000 4200 4800 3600 3600 +5 1 0 1 0 7 50 -1 -1 0.000 0 1 0 0 5400.000 1200.000 3600 3600 5400 4200 7200 3600 +5 1 0 1 0 7 50 -1 -1 0.000 0 0 0 0 5100.000 6300.000 7200 3600 7800 4200 8400 5400 +5 1 0 1 0 7 50 -1 -1 0.000 0 1 0 0 8400.000 6000.000 8400 5400 7800 6000 8400 6600 +5 1 0 1 0 7 50 -1 -1 0.000 0 1 0 0 9128.571 9642.857 8400 6600 6600 7800 6000 9600 +5 1 0 1 0 7 50 -1 -1 0.000 0 1 0 0 2820.000 9120.000 6000 9600 5400 7200 3600 6000 diff --git a/src/medtool/resources/Pol2.fig b/src/medtool/resources/Pol2.fig new file mode 100644 index 000000000..4778e6735 --- /dev/null +++ b/src/medtool/resources/Pol2.fig @@ -0,0 +1,13 @@ +#FIG 3.2 Produced by xfig version 3.2.5-alpha5 +Landscape +Center +Inches +Letter +100.00 +Single +-2 +1200 2 +5 1 0 1 0 7 50 -1 -1 0.000 0 0 0 0 13000.000 7200.000 6600 9000 6600 5400 8400 2400 +5 1 0 1 0 7 50 -1 -1 0.000 0 1 0 0 10500.000 -900.000 8400 2400 10800 3000 12600 2400 +5 1 0 1 0 7 50 -1 -1 0.000 0 1 0 0 16242.857 6471.429 12600 2400 10800 6000 11400 9000 +5 1 0 1 0 7 50 -1 -1 0.000 0 0 0 0 9000.000 13500.000 6600 9000 9000 8400 11400 9000 diff --git a/src/medtool/resources/Pol3.fig b/src/medtool/resources/Pol3.fig new file mode 100644 index 000000000..4bad14493 --- /dev/null +++ b/src/medtool/resources/Pol3.fig @@ -0,0 +1,11 @@ +#FIG 3.2 Produced by xfig version 3.2.5-alpha5 +Landscape +Center +Inches +Letter +100.00 +Single +-2 +1200 2 +2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 2 +3000 7200 6600 3600 diff --git a/src/medtool/resources/Pol4.fig b/src/medtool/resources/Pol4.fig new file mode 100644 index 000000000..1c6cd7924 --- /dev/null +++ b/src/medtool/resources/Pol4.fig @@ -0,0 +1,10 @@ +#FIG 3.2 Produced by xfig version 3.2.5-alpha5 +Landscape +Center +Inches +Letter +100.00 +Single +-2 +1200 2 +5 1 0 1 0 7 50 -1 -1 0.000 0 0 0 0 4800.000 4837.500 4200 7200 4800 2400 5400 7200 diff --git a/src/medtool/resources/Test2D.med b/src/medtool/resources/Test2D.med new file mode 100644 index 000000000..8f651af39 Binary files /dev/null and b/src/medtool/resources/Test2D.med differ diff --git a/src/medtool/resources/Test2Dpoly.med b/src/medtool/resources/Test2Dpoly.med new file mode 100644 index 000000000..7d56fed90 Binary files /dev/null and b/src/medtool/resources/Test2Dpoly.med differ diff --git a/src/medtool/resources/Test3D.med b/src/medtool/resources/Test3D.med new file mode 100644 index 000000000..48eccd7a6 Binary files /dev/null and b/src/medtool/resources/Test3D.med differ diff --git a/src/medtool/resources/Test3Dpoly.med b/src/medtool/resources/Test3Dpoly.med new file mode 100644 index 000000000..621709411 Binary files /dev/null and b/src/medtool/resources/Test3Dpoly.med differ diff --git a/src/medtool/resources/agitateur.med b/src/medtool/resources/agitateur.med new file mode 100644 index 000000000..73c62e127 Binary files /dev/null and b/src/medtool/resources/agitateur.med differ diff --git a/src/medtool/resources/pointe.med b/src/medtool/resources/pointe.med new file mode 100644 index 000000000..73844dfa6 Binary files /dev/null and b/src/medtool/resources/pointe.med differ diff --git a/src/medtool/resources/square1.med b/src/medtool/resources/square1.med new file mode 100644 index 000000000..3fd7c4111 Binary files /dev/null and b/src/medtool/resources/square1.med differ diff --git a/src/medtool/resources/square2.med b/src/medtool/resources/square2.med new file mode 100644 index 000000000..9b9d0a40e Binary files /dev/null and b/src/medtool/resources/square2.med differ diff --git a/src/medtool/src/CMakeLists.txt b/src/medtool/src/CMakeLists.txt new file mode 100644 index 000000000..725c1e0db --- /dev/null +++ b/src/medtool/src/CMakeLists.txt @@ -0,0 +1,68 @@ +# Copyright (C) 2015 CEA/DEN, EDF 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, 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 +# 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 +# + +SET(MED_ENABLE_MICROMED ${SALOME_MED_MICROMED}) + +ADD_SUBDIRECTORY(INTERP_KERNEL) +IF(SALOME_BUILD_TESTS) + ADD_SUBDIRECTORY(INTERP_KERNELTest) +ENDIF(SALOME_BUILD_TESTS) +ADD_SUBDIRECTORY(MEDCoupling) + +IF(SALOME_MED_ENABLE_PYTHON) + ADD_SUBDIRECTORY(MEDCoupling_Swig) +ENDIF(SALOME_MED_ENABLE_PYTHON) + +IF(NOT SALOME_MED_MICROMED) + ADD_SUBDIRECTORY(MEDLoader) + IF(SALOME_MED_ENABLE_RENUMBER) + ADD_SUBDIRECTORY(RENUMBER) + IF(SALOME_MED_ENABLE_PYTHON) + ADD_SUBDIRECTORY(RENUMBER_Swig) + ENDIF(SALOME_MED_ENABLE_PYTHON) + ENDIF(SALOME_MED_ENABLE_RENUMBER) + IF(SALOME_MED_ENABLE_PARTITIONER) + ADD_SUBDIRECTORY(MEDPartitioner) + IF(SALOME_MED_ENABLE_PYTHON) + ADD_SUBDIRECTORY(MEDPartitioner_Swig) + ENDIF(SALOME_MED_ENABLE_PYTHON) + ENDIF(SALOME_MED_ENABLE_PARTITIONER) +ENDIF(NOT SALOME_MED_MICROMED) + +IF(SALOME_USE_MPI) + ADD_SUBDIRECTORY(ParaMEDMEM) + IF(NOT SALOME_MED_MICROMED) + ADD_SUBDIRECTORY(ParaMEDLoader) + ENDIF(NOT SALOME_MED_MICROMED) + IF(SALOME_MED_ENABLE_PYTHON) + ADD_SUBDIRECTORY(ParaMEDMEM_Swig) + ENDIF(SALOME_MED_ENABLE_PYTHON) + IF(SALOME_BUILD_TESTS) + IF(NOT SALOME_MED_MICROMED) + ADD_SUBDIRECTORY(ParaMEDMEMTest) + ENDIF(NOT SALOME_MED_MICROMED) + ENDIF(SALOME_BUILD_TESTS) +ENDIF(SALOME_USE_MPI) + +# Application tests +INSTALL(FILES CTestTestfileInstall.cmake + DESTINATION ${MEDTOOL_INSTALL_TESTS} + RENAME CTestTestfile.cmake) + +INSTALL(FILES CTestTestfileInstallMEDCoupling.cmake + DESTINATION ${MEDTOOL_INSTALL_TESTS}/MEDCoupling + RENAME CTestTestfile.cmake) diff --git a/src/medtool/src/CTestTestfileInstall.cmake b/src/medtool/src/CTestTestfileInstall.cmake new file mode 100644 index 000000000..e9b04a1f6 --- /dev/null +++ b/src/medtool/src/CTestTestfileInstall.cmake @@ -0,0 +1,20 @@ +# Copyright (C) 2015 CEA/DEN, EDF 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, 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 +# 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 +# + +SUBDIRS(MEDCoupling) diff --git a/src/medtool/src/CTestTestfileInstallMEDCoupling.cmake b/src/medtool/src/CTestTestfileInstallMEDCoupling.cmake new file mode 100644 index 000000000..b1a8785b6 --- /dev/null +++ b/src/medtool/src/CTestTestfileInstallMEDCoupling.cmake @@ -0,0 +1,31 @@ +# Copyright (C) 2015 CEA/DEN, EDF 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, 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 +# 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(COMPONENT_NAME MEDCOUPLING) + +#SUBDIRS(INTERP_KERNELTest) +SUBDIRS(MEDCoupling) +#SUBDIRS(MEDCoupling_Swig) +#SUBDIRS(MEDLoader) +#SUBDIRS(MEDLoader/Swig) +#SUBDIRS(MEDPartitioner) +#SUBDIRS(ParaMEDMEM_Swig) +#SUBDIRS(ParaMEDMEMTest) +#SUBDIRS(MEDPartitioner_Swig) +#SUBDIRS(RENUMBER_Swig) diff --git a/src/medtool/src/INTERP_KERNEL/BBTree.txx b/src/medtool/src/INTERP_KERNEL/BBTree.txx new file mode 100644 index 000000000..5694fa4bc --- /dev/null +++ b/src/medtool/src/INTERP_KERNEL/BBTree.txx @@ -0,0 +1,281 @@ +// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 +// 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 __BBTREE_TXX__ +#define __BBTREE_TXX__ + +#include <vector> +#include <algorithm> + +#include <iostream> +#include <limits> +#include <cmath> + +template <int dim, class ConnType = int> +class BBTree +{ + +private: + BBTree* _left; + BBTree* _right; + int _level; + double _max_left; + double _min_right; + const double *_bb; + typename std::vector<ConnType> _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 bbs pointer to the [xmin1 xmax1 ymin1 ymax1 xmin2 xmax2 ...] array containing the bounding boxes that are to be indexed. + \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. 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 + int nbelems=... + double* bbs= new double[2*2*nbelems]; + // filling bbs ... + ... + BBTree<2> tree = new BBTree<2>(elems,0,0,nbelems,1e-12); + \endcode + */ + + 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) + { + _terminal=true; + + } + double* nodes=new double [nbelems]; + _elems.resize(nbelems); + for (ConnType i=0; i<nbelems; i++) + { + ConnType elem; + if (elems!=0) + elem= elems[i]; + else + elem=i; + + _elems[i]=elem; + nodes[i]=bbs[elem*dim*2+(level%dim)*2]; + } + if (_terminal) { delete[] nodes; return;} + + std::nth_element<double*>(nodes, nodes+nbelems/2, nodes+nbelems); + double median = *(nodes+nbelems/2); + delete[] nodes; + // std:: cout << *median <<std::endl; + + std::vector<ConnType> new_elems_left; + std::vector<ConnType> new_elems_right; + + new_elems_left.reserve(nbelems/2+1); + new_elems_right.reserve(nbelems/2+1); + double max_left = -std::numeric_limits<double>::max(); + double min_right= std::numeric_limits<double>::max(); + for (int i=0; i<nbelems;i++) + { + int elem; + if (elems!=0) + elem= elems[i]; + else + elem=i; + double max=bbs[elem*dim*2+(level%dim)*2+1]; + double min = bbs[elem*dim*2+(level%dim)*2]; + + if (min>median) + { + new_elems_right.push_back(elem); + if (min<min_right) min_right = min; + } + else + + { + new_elems_left.push_back(elem); + if (max>max_left) max_left = max; + } + + + } + _max_left=max_left+std::abs(_epsilon); + _min_right=min_right-std::abs(_epsilon); + ConnType *tmp; + tmp=0; + if(!new_elems_left.empty()) + tmp=&(new_elems_left[0]); + _left=new BBTree(bbs, tmp, level+1, (int)new_elems_left.size(),_epsilon); + tmp=0; + if(!new_elems_right.empty()) + tmp=&(new_elems_right[0]); + _right=new BBTree(bbs, tmp, level+1, (int)new_elems_right.size(),_epsilon); + + } + + + + ~BBTree() + { + if (_left!=0) delete _left; + if (_right!=0) delete _right; + + } + + + /*! returns in \a elems the list of elements potentially intersecting the bounding box pointed to by \a bb + + \param bb pointer to query bounding box + \param elems list of elements (given in 0-indexing that is to say in \b C \b mode) intersecting the bounding box + */ + + void getIntersectingElems(const double* bb, std::vector<ConnType>& elems) const + { + // terminal node : return list of elements intersecting bb + if (_terminal) + { + for (int i=0; i<_nbelems; i++) + { + const double* const bb_ptr=_bb+_elems[i]*2*dim; + bool intersects = true; + for (int idim=0; idim<dim; idim++) + { + if (bb_ptr[idim*2]-bb[idim*2+1]>-_epsilon|| bb_ptr[idim*2+1]-bb[idim*2]<_epsilon) + intersects=false; + } + if (intersects) + { + elems.push_back(_elems[i]); + } + } + return; + } + + //non terminal node + double min = bb[(_level%dim)*2]; + double max = bb[(_level%dim)*2+1]; + if (max < _min_right) + { + _left->getIntersectingElems(bb, elems); + return; + } + if (min> _max_left) + { + _right->getIntersectingElems(bb,elems); + return; + } + _left->getIntersectingElems(bb,elems); + _right->getIntersectingElems(bb,elems); + } + + /*! + * This method is very close to getIntersectingElems except that it returns number of elems instead of elems themselves. + */ + int getNbOfIntersectingElems(const double* bb) + { + // terminal node : return list of elements intersecting bb + int ret(0); + if (_terminal) + { + for (int i=0; i<_nbelems; i++) + { + const double* const bb_ptr=_bb+_elems[i]*2*dim; + bool intersects = true; + for (int idim=0; idim<dim; idim++) + { + if (bb_ptr[idim*2]-bb[idim*2+1]>-_epsilon|| bb_ptr[idim*2+1]-bb[idim*2]<_epsilon) + intersects=false; + } + if (intersects) + ret++; + } + return ret; + } + //non terminal node + double min = bb[(_level%dim)*2]; + double max = bb[(_level%dim)*2+1]; + if (max < _min_right) + return _left->getNbOfIntersectingElems(bb); + if (min> _max_left) + return _right->getNbOfIntersectingElems(bb); + return _left->getNbOfIntersectingElems(bb)+_right->getNbOfIntersectingElems(bb); + } + + + /*! returns in \a elems the list of elements potentially containing the point pointed to by \a xx + \param xx pointer to query point coords + \param elems list of elements (given in 0-indexing) intersecting the bounding box + */ + + void getElementsAroundPoint(const double* xx, std::vector<ConnType>& elems) const + { + // terminal node : return list of elements intersecting bb + if (_terminal) + { + for (ConnType i=0; i<_nbelems; i++) + { + const double* const bb_ptr=_bb+_elems[i]*2*dim; + bool intersects = true; + for (int idim=0; idim<dim; idim++) + { + if (bb_ptr[idim*2]-xx[idim]>_epsilon|| bb_ptr[idim*2+1]-xx[idim]<-_epsilon) + intersects=false; + } + if (intersects) + { + elems.push_back(_elems[i]); + } + } + return; + } + + //non terminal node + if (xx[_level%dim] < _min_right) + { + _left->getElementsAroundPoint(xx, elems); + return; + } + if (xx[_level%dim]> _max_left) + { + _right->getElementsAroundPoint(xx,elems); + return; + } + _left->getElementsAroundPoint(xx,elems); + _right->getElementsAroundPoint(xx,elems); + } + + + + int size() + { + if (_terminal) return _nbelems; + return _left->size()+_right->size(); + } +}; +#endif diff --git a/src/medtool/src/INTERP_KERNEL/BBTreeDst.txx b/src/medtool/src/INTERP_KERNEL/BBTreeDst.txx new file mode 100644 index 000000000..a5cbfb43d --- /dev/null +++ b/src/medtool/src/INTERP_KERNEL/BBTreeDst.txx @@ -0,0 +1,217 @@ +// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 +// 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 <vector> +#include <algorithm> + +#include <iostream> +#include <limits> +#include <cmath> + +template <int dim> +class BBTreeDst +{ +private: + BBTreeDst* _left; + BBTreeDst* _right; + int _level; + double _max_left; + double _min_right; + const double *_bb; + std::vector<int> _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<nbelems; i++) + _elems[i]=elems?elems[i]:i; + if(_terminal) + { + fillBBoxTerminal(bbs); + return ; + } + double *nodes=new double[nbelems]; + for (int i=0; i<nbelems; i++) + nodes[i]=bbs[_elems[i]*dim*2+(level%dim)*2]; + std::nth_element<double*>(nodes, nodes+nbelems/2, nodes+nbelems); + double median = *(nodes+nbelems/2); + delete [] nodes; + std::vector<int> new_elems_left; + std::vector<int> new_elems_right; + + new_elems_left.reserve(nbelems/2+1); + new_elems_right.reserve(nbelems/2+1); + double max_left = -std::numeric_limits<double>::max(); + double min_right= std::numeric_limits<double>::max(); + for(int i=0; i<nbelems;i++) + { + int elem; + if (elems!=0) + elem= elems[i]; + else + elem=i; + double max=bbs[elem*dim*2+(level%dim)*2+1]; + double min = bbs[elem*dim*2+(level%dim)*2]; + + if (min>median) + { + new_elems_right.push_back(elem); + if (min<min_right) min_right = min; + } + else + { + new_elems_left.push_back(elem); + if (max>max_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<int>& elems) const + { + if(_terminal) + { + for(int i=0; i<_nbelems; i++) + { + if(GetMinDistanceFromBBoxToPt(_bb+_elems[i]*2*dim,pt)<minOfMaxDstsSq) + elems.push_back(_elems[i]); + } + } + else + { + double minOfMaxDsts=sqrt(minOfMaxDstsSq); + if(_min_right-pt[_level%dim]>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<dim;j++) + { + _terminal[2*j]=std::numeric_limits<double>::max(); + _terminal[2*j+1]=-std::numeric_limits<double>::max(); + } + for(int i=0;i<_nbelems;i++) + { + for(int j=0;j<dim;j++) + { + _terminal[2*j]=std::min(_terminal[2*j],bbs[2*dim*_elems[i]+2*j]); + _terminal[2*j+1]=std::max(_terminal[2*j+1],bbs[2*dim*_elems[i]+2*j+1]); + } + } + } + + static double GetMaxDistanceFromBBoxToPt(const double *bbox, const double *pt) + { + if(bbox[0]<=bbox[1]) + { + double zeRes=0.; + for (int idim=0; idim<dim; idim++) + { + double val1=pt[idim]-bbox[idim*2],val2=pt[idim]-bbox[idim*2+1]; + double x=std::max(fabs(val1),fabs(val2)); + zeRes+=x*x; + } + return zeRes; + } + else//min>max -> no cells in this + return std::numeric_limits<double>::max(); + + } + + static double GetMinDistanceFromBBoxToPt(const double *bbox, const double *pt) + { + if(bbox[0]<=bbox[1]) + { + double zeRes=0.; + for (int idim=0; idim<dim; idim++) + { + double val1=pt[idim]-bbox[idim*2],val2=pt[idim]-bbox[idim*2+1]; + char pos=(( (0.<val1)-(val1<0.) )+( (0.<val2)-(val2<0.) ))/2;// sign(val) = (0.<val)-(val<0.) + if(pos!=0) + { + double x=pos==1?val2:val1; + zeRes+=x*x; + } + } + return zeRes; + } + else//min>max -> no cells in this + return std::numeric_limits<double>::max(); + } +}; + +#endif diff --git a/src/medtool/src/INTERP_KERNEL/BBTreePts.txx b/src/medtool/src/INTERP_KERNEL/BBTreePts.txx new file mode 100644 index 000000000..6c4378a79 --- /dev/null +++ b/src/medtool/src/INTERP_KERNEL/BBTreePts.txx @@ -0,0 +1,222 @@ +// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 +// 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 <vector> +#include <algorithm> + +#include <iostream> +#include <limits> +#include <cmath> + +template <int dim, class ConnType = int> +class BBTreePts +{ + +private: + BBTreePts* _left; + BBTreePts* _right; + int _level; + double _max_left; + double _min_right; + const double *_pts; + typename std::vector<ConnType> _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<nbelems;i++) + { + ConnType elem; + if (elems!=0) + elem= elems[i]; + else + elem=i; + + _elems[i]=elem; + nodes[i]=pts[elem*dim+(level%dim)]; + } + if(_terminal) { delete[] nodes; return; } + // + std::nth_element<double*>(nodes, nodes+nbelems/2, nodes+nbelems); + double median=*(nodes+nbelems/2); + delete [] nodes; + std::vector<ConnType> 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<double>::max(); + double min_right= std::numeric_limits<double>::max(); + for(int i=0;i<nbelems;i++) + { + int elem; + if(elems!=0) + elem= elems[i]; + else + elem=i; + double mx=pts[elem*dim+(level%dim)]; + if(mx>median) + { + new_elems_right.push_back(elem); + if(mx<min_right) min_right=mx; + } + else + { + new_elems_left.push_back(elem); + if(mx>max_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<double>::max(); + for(ConnType i=0;i<_nbelems;i++) + { + const double* const bb_ptr=_pts+_elems[i]*dim; + double tmp=0.; + for(int idim=0;idim<dim;idim++) + tmp+=(bb_ptr[idim]-xx[idim])*(bb_ptr[idim]-xx[idim]); + if(tmp<threshold) + { + if(tmp<ret) + { ret=tmp; elem=_elems[i]; } + } + } + return ret; + } + //non terminal node + double s=sqrt(threshold*dim); + if(xx[_level%dim]+s<_min_right) + return _left->getElementsAroundPoint2(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<retr) + { elem=eleml; return retl; } + else + { elem=elemr; return retr; } + } + + /*! returns in \a elems the list of elements potentially containing the point pointed to by \a xx + * ** Infinite norm is used here not norm 2 ! *** + * + * \param xx pointer to query point coords + * \param elems list of elements (given in 0-indexing) intersecting the bounding box + * \sa BBTreePts::getElementsAroundPoint2 + */ + void getElementsAroundPoint(const double* xx, std::vector<ConnType>& 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;idim<dim;idim++) + intersects=intersects && (std::abs(bb_ptr[idim]-xx[idim])<=_epsilon); + if(intersects) + elems.push_back(_elems[i]); + } + return; + } + //non terminal node + if(xx[_level%dim]<_min_right) + { + _left->getElementsAroundPoint(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/medtool/src/INTERP_KERNEL/Barycentric3DIntersectorP1P1.hxx b/src/medtool/src/INTERP_KERNEL/Barycentric3DIntersectorP1P1.hxx new file mode 100644 index 000000000..33746d4c4 --- /dev/null +++ b/src/medtool/src/INTERP_KERNEL/Barycentric3DIntersectorP1P1.hxx @@ -0,0 +1,46 @@ +// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 +// 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 __BARYCENTRIC3DINTERSECTORP1P1_HXX__ +#define __BARYCENTRIC3DINTERSECTORP1P1_HXX__ + +#include "Intersector3DP1P1.hxx" +#include "NormalizedUnstructuredMesh.hxx" + +namespace INTERP_KERNEL +{ + template<class MyMeshType, class MyMatrix> + class Barycentric3DIntersectorP1P1 : public Intersector3DP1P1<MyMeshType,MyMatrix> + { + public: + static const int SPACEDIM=MyMeshType::MY_SPACEDIM; + static const int MESHDIM=MyMeshType::MY_MESHDIM; + typedef typename MyMeshType::MyConnType ConnType; + static const NumberingPolicy numPol=MyMeshType::My_numPol; + public: + Barycentric3DIntersectorP1P1(const MyMeshType& targetMesh, const MyMeshType& srcMesh, double precision); + ~Barycentric3DIntersectorP1P1(); + void intersectCells(ConnType targetCell, const std::vector<ConnType>& srcCells, MyMatrix& res); + protected: + double _precision; + }; +} + +#endif diff --git a/src/medtool/src/INTERP_KERNEL/Barycentric3DIntersectorP1P1.txx b/src/medtool/src/INTERP_KERNEL/Barycentric3DIntersectorP1P1.txx new file mode 100644 index 000000000..7009c7c36 --- /dev/null +++ b/src/medtool/src/INTERP_KERNEL/Barycentric3DIntersectorP1P1.txx @@ -0,0 +1,98 @@ +// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 +// 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 __BARYCENTRIC3DINTERSECTORP1P1_TXX__ +#define __BARYCENTRIC3DINTERSECTORP1P1_TXX__ + +#include "Barycentric3DIntersectorP1P1.hxx" +#include "Intersector3DP1P1.txx" +#include "MeshUtils.hxx" + +namespace INTERP_KERNEL +{ + + /** + * Constructor creating object from target cell global number + * + * @param targetMesh mesh containing the target elements + * @param srcMesh mesh containing the source elements + * @param policy splitting policy to be used + */ + template<class MyMeshType, class MyMatrix> + Barycentric3DIntersectorP1P1<MyMeshType,MyMatrix>::Barycentric3DIntersectorP1P1(const MyMeshType& targetMesh, const MyMeshType& srcMesh, double precision): + Intersector3DP1P1<MyMeshType,MyMatrix>(targetMesh,srcMesh),_precision(precision) + { + } + + template<class MyMeshType, class MyMatrix> + Barycentric3DIntersectorP1P1<MyMeshType,MyMatrix>::~Barycentric3DIntersectorP1P1() + { + } + + /** + * @param targetCell in C mode. + * @param srcCells in C mode. + */ + template<class MyMeshType, class MyMatrix> + void Barycentric3DIntersectorP1P1<MyMeshType,MyMatrix>::intersectCells(ConnType targetCell, const std::vector<ConnType>& srcCells, MyMatrix& res) + { + std::vector<double> CoordsT; + const ConnType *startOfCellNodeConnT=Intersector3DP1P1<MyMeshType,MyMatrix>::getStartConnOfTargetCell(targetCell); + Intersector3DP1P1<MyMeshType,MyMatrix>::getRealTargetCoordinates(OTT<ConnType,numPol>::indFC(targetCell),CoordsT); + int nbOfNodesT=CoordsT.size()/SPACEDIM; + const double *coordsS=Intersector3DP1P1<MyMeshType,MyMatrix>::_src_mesh.getCoordinatesPtr(); + for(int nodeIdT=0;nodeIdT<nbOfNodesT;nodeIdT++) + { + typename MyMatrix::value_type& resRow=res[OTT<ConnType,numPol>::ind2C(startOfCellNodeConnT[nodeIdT])]; + if(!resRow.empty()) + continue; + for(typename std::vector<ConnType>::const_iterator iterCellS=srcCells.begin();iterCellS!=srcCells.end();iterCellS++) + { + NormalizedCellType tS=Intersector3DP1P1<MyMeshType,MyMatrix>::_src_mesh.getTypeOfElement(OTT<ConnType,numPol>::indFC(*iterCellS)); + if(tS!=NORM_TETRA4) + throw INTERP_KERNEL::Exception("Invalid source cell detected for meshdim==3. Only TETRA4 supported !"); + const CellModel& cmTypeS=CellModel::GetCellModel(tS); + // + std::vector<ConnType> connOfCurCellS; + Intersector3DP1P1<MyMeshType,MyMatrix>::getConnOfSourceCell(OTT<ConnType,numPol>::indFC(*iterCellS),connOfCurCellS); + if( PointLocatorAlgos<MyMeshType>::isElementContainsPointAlg3D(&CoordsT[nodeIdT*SPACEDIM],&connOfCurCellS[0],connOfCurCellS.size(),coordsS,cmTypeS,_precision) ) + { + double resLoc[4]; + std::vector<double> localCoordsS; + Intersector3DP1P1<MyMeshType,MyMatrix>::getRealSourceCoordinates(OTT<ConnType,numPol>::indFC(*iterCellS),localCoordsS); + std::vector<const double*> eap(4); + eap[0]=&localCoordsS[0]; eap[1]=&localCoordsS[3]; eap[2]=&localCoordsS[6]; eap[3]=&localCoordsS[9]; + barycentric_coords(eap,&CoordsT[nodeIdT*SPACEDIM],resLoc); + const ConnType *startOfCellNodeConnS=Intersector3DP1P1<MyMeshType,MyMatrix>::getStartConnOfSourceCell(*iterCellS); + for(int nodeIdS=0;nodeIdS<4;nodeIdS++) + { + if(fabs(resLoc[nodeIdS])>_precision) + { + ConnType curNodeSInCmode=OTT<ConnType,numPol>::coo2C(startOfCellNodeConnS[nodeIdS]); + resRow.insert(std::make_pair(OTT<ConnType,numPol>::indFC(curNodeSInCmode),resLoc[nodeIdS])); + } + } + } + } + } + } +} + +#endif diff --git a/src/medtool/src/INTERP_KERNEL/Bases/InterpKernelAutoPtr.hxx b/src/medtool/src/INTERP_KERNEL/Bases/InterpKernelAutoPtr.hxx new file mode 100644 index 000000000..1e28d1e61 --- /dev/null +++ b/src/medtool/src/INTERP_KERNEL/Bases/InterpKernelAutoPtr.hxx @@ -0,0 +1,84 @@ +// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 +// 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 __INTERPKERNELAUTOPTR_HXX__ +#define __INTERPKERNELAUTOPTR_HXX__ + +namespace INTERP_KERNEL +{ + template<class T> + class AutoPtr + { + public: + AutoPtr(T *ptr=0):_ptr(ptr) { } + ~AutoPtr() { destroyPtr(); } + AutoPtr &operator=(T *ptr) { if(_ptr!=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() { delete [] _ptr; } + private: + T *_ptr; + }; + + template<class T> + class AutoCppPtr + { + public: + AutoCppPtr(T *ptr=0):_ptr(ptr) { } + ~AutoCppPtr() { destroyPtr(); } + AutoCppPtr &operator=(T *ptr) { if(_ptr!=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() { delete _ptr; } + private: + T *_ptr; + }; + + template<class T> + class AutoCPtr + { + public: + AutoCPtr(T *ptr=0):_ptr(ptr) { } + ~AutoCPtr() { destroyPtr(); } + AutoCPtr &operator=(T *ptr) { if(_ptr!=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/medtool/src/INTERP_KERNEL/Bases/InterpKernelException.cxx b/src/medtool/src/INTERP_KERNEL/Bases/InterpKernelException.cxx new file mode 100644 index 000000000..dae549346 --- /dev/null +++ b/src/medtool/src/INTERP_KERNEL/Bases/InterpKernelException.cxx @@ -0,0 +1,38 @@ +// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 +// 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 "InterpKernelException.hxx" + +INTERP_KERNEL::Exception::Exception(const char *reason):_reason(reason) +{ +} + +INTERP_KERNEL::Exception::Exception(const char *reason, const char *file, int line):_reason(reason) +{ +} + +INTERP_KERNEL::Exception::~Exception() throw () +{ +} + +const char *INTERP_KERNEL::Exception::what() const throw() +{ + return _reason.c_str(); +} diff --git a/src/medtool/src/INTERP_KERNEL/Bases/InterpKernelException.hxx b/src/medtool/src/INTERP_KERNEL/Bases/InterpKernelException.hxx new file mode 100644 index 000000000..86fe0cc96 --- /dev/null +++ b/src/medtool/src/INTERP_KERNEL/Bases/InterpKernelException.hxx @@ -0,0 +1,43 @@ +// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 +// 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 __INTERPKERNELEXCEPTION_HXX__ +#define __INTERPKERNELEXCEPTION_HXX__ + +#include "INTERPKERNELDefines.hxx" + +#include <string> +#include <exception> + +namespace INTERP_KERNEL +{ + class Exception : public std::exception + { + public: + INTERPKERNEL_EXPORT Exception(const char *reason); + INTERPKERNEL_EXPORT Exception(const char *reason, const char *file, int line); + INTERPKERNEL_EXPORT ~Exception() throw (); + INTERPKERNEL_EXPORT const char *what() const throw(); + protected: + std::string _reason; + }; +} + +#endif diff --git a/src/medtool/src/INTERP_KERNEL/Bases/InterpKernelHashFun.hxx b/src/medtool/src/INTERP_KERNEL/Bases/InterpKernelHashFun.hxx new file mode 100644 index 000000000..3fcc84ee6 --- /dev/null +++ b/src/medtool/src/INTERP_KERNEL/Bases/InterpKernelHashFun.hxx @@ -0,0 +1,146 @@ +// Copyright (C) 2001-2015 CEA/DEN, EDF 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, 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 +// 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 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 General Public License for more details. + +// Under Section 7 of GPL version 3, you are granted additional +// permissions described in the GCC Runtime Library Exception, version +// 3.1, as published by the Free Software Foundation. + +// You should have received a copy of the GNU General Public License and +// a copy of the GCC Runtime Library Exception along with this program; +// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see +// <http://www.gnu.org/licenses/>. + +/* + * Copyright (c) 1996-1998 + * Silicon Graphics Computer Systems, Inc. + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Silicon Graphics makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + * + * + * Copyright (c) 1994 + * Hewlett-Packard Company + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Hewlett-Packard Company makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + * + */ +#ifndef __INTERPKERNELHASHFUN_HXX__ +#define __INTERPKERNELHASHFUN_HXX__ + +#include <cstddef> + +namespace INTERP_KERNEL +{ + template<class _Key> + struct hash { }; + + inline std::size_t __stl_hash_string(const char* __s) + { + unsigned long __h = 0; + for ( ; *__s; ++__s) + __h = 5 * __h + *__s; + return std::size_t(__h); + } + + template<> + struct hash<char*> + { + std::size_t operator()(const char* __s) const + { return __stl_hash_string(__s); } + }; + + template<> + struct hash<const char*> + { + std::size_t operator()(const char* __s) const + { return __stl_hash_string(__s); } + }; + + template<> + struct hash<char> + { + std::size_t operator()(char __x) const { return __x; } + }; + + template<> + struct hash<unsigned char> + { + std::size_t operator()(unsigned char __x) const { return __x; } + }; + + template<> + struct hash<signed char> + { + std::size_t operator()(unsigned char __x) const { return __x; } + }; + + template<> + struct hash<short> + { + std::size_t operator()(short __x) const { return __x; } + }; + + template<> + struct hash<unsigned short> + { + std::size_t operator()(unsigned short __x) const { return __x; } + }; + + template<> + struct hash<int> + { + std::size_t operator()(int __x) const { return __x; } + }; + + template<> + struct hash<unsigned int> + { + std::size_t operator()(unsigned int __x) const { return __x; } + }; + + template<> + struct hash<long> + { + std::size_t operator()(long __x) const { return __x; } + }; + + template<> + struct hash<unsigned long> + { + std::size_t operator()(unsigned long __x) const { return __x; } + }; +} + +#endif diff --git a/src/medtool/src/INTERP_KERNEL/Bases/InterpKernelHashMap.hxx b/src/medtool/src/INTERP_KERNEL/Bases/InterpKernelHashMap.hxx new file mode 100644 index 000000000..f4ff608b0 --- /dev/null +++ b/src/medtool/src/INTERP_KERNEL/Bases/InterpKernelHashMap.hxx @@ -0,0 +1,414 @@ +// Copyright (C) 2001-2015 CEA/DEN, EDF 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, 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 +// 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 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 General Public License for more details. + +// Under Section 7 of GPL version 3, you are granted additional +// permissions described in the GCC Runtime Library Exception, version +// 3.1, as published by the Free Software Foundation. + +// You should have received a copy of the GNU General Public License and +// a copy of the GCC Runtime Library Exception along with this program; +// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see +// <http://www.gnu.org/licenses/>. + +/* + * Copyright (c) 1996 + * Silicon Graphics Computer Systems, Inc. + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Silicon Graphics makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + * + * + * Copyright (c) 1994 + * Hewlett-Packard Company + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Hewlett-Packard Company makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + * + */ +#ifndef __INTERPKERNELHASHMAP__ +#define __INTERPKERNELHASHMAP__ + +#include "InterpKernelStlExt.hxx" +#include "InterpKernelHashTable.hxx" + +namespace INTERP_KERNEL +{ + template<class _Key, class _Tp, class _HashFn = hash<_Key>, + class _EqualKey = std::equal_to<_Key>, class _Alloc = std::allocator<_Tp> > + class HashMap + { + private: + typedef hashtable<std::pair<const _Key, _Tp>,_Key, _HashFn, + STLEXT::Select1st<std::pair<const _Key, _Tp> >, + _EqualKey, _Alloc> _Ht; + + _Ht _M_ht; + + public: + typedef typename _Ht::key_type key_type; + typedef _Tp data_type; + typedef _Tp mapped_type; + typedef typename _Ht::value_type value_type; + typedef typename _Ht::hasher hasher; + typedef typename _Ht::key_equal key_equal; + + typedef typename _Ht::size_type size_type; + typedef typename _Ht::difference_type difference_type; + typedef typename _Ht::pointer pointer; + typedef typename _Ht::const_pointer const_pointer; + typedef typename _Ht::reference reference; + typedef typename _Ht::const_reference const_reference; + + typedef typename _Ht::iterator iterator; + typedef typename _Ht::const_iterator const_iterator; + + typedef typename _Ht::allocator_type allocator_type; + + hasher hash_funct() const { return _M_ht.hash_funct(); } + + key_equal key_eq() const { return _M_ht.key_eq(); } + + allocator_type get_allocator() const { return _M_ht.get_allocator(); } + + HashMap() : _M_ht(100, hasher(), key_equal(), allocator_type()) {} + + explicit HashMap(size_type __n) : _M_ht(__n, hasher(), key_equal(), allocator_type()) {} + + HashMap(size_type __n, const hasher& __hf) : _M_ht(__n, __hf, key_equal(), allocator_type()) {} + + HashMap(size_type __n, const hasher& __hf, const key_equal& __eql, + const allocator_type& __a = allocator_type()) : _M_ht(__n, __hf, __eql, __a) {} + + template<class _InputIterator> + HashMap(_InputIterator __f, _InputIterator __l) : _M_ht(100, hasher(), key_equal(), allocator_type()) + { _M_ht.insert_unique(__f, __l); } + + template<class _InputIterator> + HashMap(_InputIterator __f, _InputIterator __l, size_type __n) : _M_ht(__n, hasher(), key_equal(), allocator_type()) + { _M_ht.insert_unique(__f, __l); } + + template<class _InputIterator> + HashMap(_InputIterator __f, _InputIterator __l, size_type __n, const hasher& __hf) + : _M_ht(__n, __hf, key_equal(), allocator_type()) + { _M_ht.insert_unique(__f, __l); } + + template<class _InputIterator> + HashMap(_InputIterator __f, _InputIterator __l, size_type __n, + const hasher& __hf, const key_equal& __eql, + const allocator_type& __a = allocator_type()) : _M_ht(__n, __hf, __eql, __a) + { _M_ht.insert_unique(__f, __l); } + + size_type size() const { return _M_ht.size(); } + + size_type max_size() const { return _M_ht.max_size(); } + + bool empty() const { return _M_ht.empty(); } + + void swap(HashMap& __hs) { _M_ht.swap(__hs._M_ht); } + + template<class _K1, class _T1, class _HF, class _EqK, class _Al> + friend bool operator== (const HashMap<_K1, _T1, _HF, _EqK, _Al>&, + const HashMap<_K1, _T1, _HF, _EqK, _Al>&); + + iterator begin() { return _M_ht.begin(); } + + iterator end() { return _M_ht.end(); } + + const_iterator begin() const { return _M_ht.begin(); } + + const_iterator end() const { return _M_ht.end(); } + + std::pair<iterator, bool> insert(const value_type& __obj) { return _M_ht.insert_unique(__obj); } + + template<class _InputIterator> + void insert(_InputIterator __f, _InputIterator __l) { _M_ht.insert_unique(__f, __l); } + + std::pair<iterator, bool> + insert_noresize(const value_type& __obj) { return _M_ht.insert_unique_noresize(__obj); } + + iterator find(const key_type& __key) { return _M_ht.find(__key); } + + const_iterator find(const key_type& __key) const { return _M_ht.find(__key); } + + _Tp& operator[](const key_type& __key) { return _M_ht.find_or_insert(value_type(__key, _Tp())).second; } + + size_type count(const key_type& __key) const { return _M_ht.count(__key); } + + std::pair<iterator, iterator> equal_range(const key_type& __key) { return _M_ht.equal_range(__key); } + + std::pair<const_iterator, const_iterator> equal_range(const key_type& __key) const { return _M_ht.equal_range(__key); } + + size_type erase(const key_type& __key) { return _M_ht.erase(__key); } + + void erase(iterator __it) { _M_ht.erase(__it); } + + void erase(iterator __f, iterator __l) { _M_ht.erase(__f, __l); } + + void clear() { _M_ht.clear(); } + + void resize(size_type __hint) { _M_ht.resize(__hint); } + + size_type bucket_count() const { return _M_ht.bucket_count(); } + + size_type max_bucket_count() const { return _M_ht.max_bucket_count(); } + + size_type elems_in_bucket(size_type __n) const { return _M_ht.elems_in_bucket(__n); } + }; + + template<class _Key, class _Tp, class _HashFn, class _EqlKey, class _Alloc> + inline bool operator==(const HashMap<_Key, _Tp, _HashFn, _EqlKey, _Alloc>& __hm1, + const HashMap<_Key, _Tp, _HashFn, _EqlKey, _Alloc>& __hm2) + { return __hm1._M_ht == __hm2._M_ht; } + + template<class _Key, class _Tp, class _HashFn, class _EqlKey, class _Alloc> + inline bool operator!=(const HashMap<_Key, _Tp, _HashFn, _EqlKey, _Alloc>& __hm1, + const HashMap<_Key, _Tp, _HashFn, _EqlKey, _Alloc>& __hm2) + { return !(__hm1 == __hm2); } + + template<class _Key, class _Tp, class _HashFn, class _EqlKey, class _Alloc> + inline void swap(HashMap<_Key, _Tp, _HashFn, _EqlKey, _Alloc>& __hm1, + HashMap<_Key, _Tp, _HashFn, _EqlKey, _Alloc>& __hm2) + { __hm1.swap(__hm2); } + + template<class _Key, class _Tp, + class _HashFn = hash<_Key>, + class _EqualKey = std::equal_to<_Key>, + class _Alloc = std::allocator<_Tp> > + class HashMultiMap + { + private: + typedef hashtable<std::pair<const _Key, _Tp>, _Key, _HashFn, + STLEXT::Select1st<std::pair<const _Key, _Tp> >, _EqualKey, _Alloc> + _Ht; + _Ht _M_ht; + public: + typedef typename _Ht::key_type key_type; + typedef _Tp data_type; + typedef _Tp mapped_type; + typedef typename _Ht::value_type value_type; + typedef typename _Ht::hasher hasher; + typedef typename _Ht::key_equal key_equal; + + typedef typename _Ht::size_type size_type; + typedef typename _Ht::difference_type difference_type; + typedef typename _Ht::pointer pointer; + typedef typename _Ht::const_pointer const_pointer; + typedef typename _Ht::reference reference; + typedef typename _Ht::const_reference const_reference; + + typedef typename _Ht::iterator iterator; + typedef typename _Ht::const_iterator const_iterator; + + typedef typename _Ht::allocator_type allocator_type; + + hasher hash_funct() const { return _M_ht.hash_funct(); } + + key_equal key_eq() const { return _M_ht.key_eq(); } + + allocator_type get_allocator() const { return _M_ht.get_allocator(); } + + HashMultiMap() : _M_ht(100, hasher(), key_equal(), allocator_type()) { } + + explicit HashMultiMap(size_type __n) : _M_ht(__n, hasher(), key_equal(), allocator_type()) {} + + HashMultiMap(size_type __n, const hasher& __hf) : _M_ht(__n, __hf, key_equal(), allocator_type()) {} + + HashMultiMap(size_type __n, const hasher& __hf, const key_equal& __eql, + const allocator_type& __a = allocator_type()) : _M_ht(__n, __hf, __eql, __a) {} + + template<class _InputIterator> + HashMultiMap(_InputIterator __f, _InputIterator __l) : _M_ht(100, hasher(), key_equal(), allocator_type()) + { _M_ht.insert_equal(__f, __l); } + + template<class _InputIterator> + HashMultiMap(_InputIterator __f, _InputIterator __l, size_type __n) : _M_ht(__n, hasher(), key_equal(), allocator_type()) + { _M_ht.insert_equal(__f, __l); } + + template<class _InputIterator> + HashMultiMap(_InputIterator __f, _InputIterator __l, size_type __n, const hasher& __hf) + : _M_ht(__n, __hf, key_equal(), allocator_type()) + { _M_ht.insert_equal(__f, __l); } + + template<class _InputIterator> + HashMultiMap(_InputIterator __f, _InputIterator __l, size_type __n, + const hasher& __hf, const key_equal& __eql, + const allocator_type& __a = allocator_type()) + : _M_ht(__n, __hf, __eql, __a) + { _M_ht.insert_equal(__f, __l); } + + size_type size() const { return _M_ht.size(); } + + size_type max_size() const { return _M_ht.max_size(); } + + bool empty() const { return _M_ht.empty(); } + + void swap(HashMultiMap& __hs) { _M_ht.swap(__hs._M_ht); } + + template<class _K1, class _T1, class _HF, class _EqK, class _Al> + friend bool operator==(const HashMultiMap<_K1, _T1, _HF, _EqK, _Al>&, + const HashMultiMap<_K1, _T1, _HF, _EqK, _Al>&); + + iterator begin() { return _M_ht.begin(); } + + iterator end() { return _M_ht.end(); } + + const_iterator begin() const { return _M_ht.begin(); } + + const_iterator end() const { return _M_ht.end(); } + + iterator insert(const value_type& __obj) { return _M_ht.insert_equal(__obj); } + + template<class _InputIterator> + void insert(_InputIterator __f, _InputIterator __l) { _M_ht.insert_equal(__f,__l); } + + iterator insert_noresize(const value_type& __obj) { return _M_ht.insert_equal_noresize(__obj); } + + iterator find(const key_type& __key) { return _M_ht.find(__key); } + + const_iterator find(const key_type& __key) const { return _M_ht.find(__key); } + + size_type count(const key_type& __key) const { return _M_ht.count(__key); } + + std::pair<iterator, iterator> equal_range(const key_type& __key) { return _M_ht.equal_range(__key); } + + std::pair<const_iterator, const_iterator> equal_range(const key_type& __key) const { return _M_ht.equal_range(__key); } + + size_type erase(const key_type& __key) { return _M_ht.erase(__key); } + + void erase(iterator __it) { _M_ht.erase(__it); } + + void erase(iterator __f, iterator __l) { _M_ht.erase(__f, __l); } + + void clear() { _M_ht.clear(); } + + void resize(size_type __hint) { _M_ht.resize(__hint); } + + size_type bucket_count() const { return _M_ht.bucket_count(); } + + size_type max_bucket_count() const { return _M_ht.max_bucket_count(); } + + size_type elems_in_bucket(size_type __n) const { return _M_ht.elems_in_bucket(__n); } + }; + + template<class _Key, class _Tp, class _HF, class _EqKey, class _Alloc> + inline bool operator==(const HashMultiMap<_Key, _Tp, _HF, _EqKey, _Alloc>& __hm1, + const HashMultiMap<_Key, _Tp, _HF, _EqKey, _Alloc>& __hm2) + { return __hm1._M_ht == __hm2._M_ht; } + + template<class _Key, class _Tp, class _HF, class _EqKey, class _Alloc> + inline bool operator!=(const HashMultiMap<_Key, _Tp, _HF, _EqKey, _Alloc>& __hm1, + const HashMultiMap<_Key, _Tp, _HF, _EqKey, _Alloc>& __hm2) + { return !(__hm1 == __hm2); } + + template<class _Key, class _Tp, class _HashFn, class _EqlKey, class _Alloc> + inline void swap(HashMultiMap<_Key, _Tp, _HashFn, _EqlKey, _Alloc>& __hm1, + HashMultiMap<_Key, _Tp, _HashFn, _EqlKey, _Alloc>& __hm2) + { __hm1.swap(__hm2); } + +} + +namespace std +{ + // Specialization of insert_iterator so that it will work for HashMap + // and HashMultiMap. + template<class _Key, class _Tp, class _HashFn, class _EqKey, class _Alloc> + class insert_iterator<INTERP_KERNEL::HashMap<_Key, _Tp, _HashFn, + _EqKey, _Alloc> > + { + protected: + typedef INTERP_KERNEL::HashMap<_Key, _Tp, _HashFn, _EqKey, _Alloc> + _Container; + _Container* container; + public: + typedef _Container container_type; + typedef output_iterator_tag iterator_category; + typedef void value_type; + typedef void difference_type; + typedef void pointer; + typedef void reference; + + insert_iterator(_Container& __x) : container(&__x) {} + + insert_iterator(_Container& __x, typename _Container::iterator) : container(&__x) {} + + insert_iterator<_Container>& operator=(const typename _Container::value_type& __value__) + { + container->insert(__value__); + return *this; + } + + insert_iterator<_Container>& operator*() { return *this; } + + insert_iterator<_Container>& operator++() { return *this; } + + insert_iterator<_Container>& operator++(int) { return *this; } + }; + + template<class _Key, class _Tp, class _HashFn, class _EqKey, class _Alloc> + class insert_iterator<INTERP_KERNEL::HashMultiMap<_Key, _Tp, _HashFn, + _EqKey, _Alloc> > + { + protected: + typedef INTERP_KERNEL::HashMultiMap<_Key, _Tp, _HashFn, _EqKey, _Alloc> + _Container; + _Container* container; + typename _Container::iterator iter; + + public: + typedef _Container container_type; + typedef output_iterator_tag iterator_category; + typedef void value_type; + typedef void difference_type; + typedef void pointer; + typedef void reference; + + insert_iterator(_Container& __x) : container(&__x) {} + + insert_iterator(_Container& __x, typename _Container::iterator) : container(&__x) {} + + insert_iterator<_Container>& operator=(const typename _Container::value_type& __value__) + { + container->insert(__value__); + return *this; + } + + insert_iterator<_Container>& operator*() { return *this; } + + insert_iterator<_Container>& operator++() { return *this; } + + insert_iterator<_Container>& operator++(int) { return *this; } + }; +} + +#endif diff --git a/src/medtool/src/INTERP_KERNEL/Bases/InterpKernelHashTable.hxx b/src/medtool/src/INTERP_KERNEL/Bases/InterpKernelHashTable.hxx new file mode 100644 index 000000000..6caa116b9 --- /dev/null +++ b/src/medtool/src/INTERP_KERNEL/Bases/InterpKernelHashTable.hxx @@ -0,0 +1,1005 @@ +// Copyright (C) 2001-2015 CEA/DEN, EDF 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, 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 +// 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 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 General Public License for more details. + +// Under Section 7 of GPL version 3, you are granted additional +// permissions described in the GCC Runtime Library Exception, version +// 3.1, as published by the Free Software Foundation. + +// You should have received a copy of the GNU General Public License and +// a copy of the GCC Runtime Library Exception along with this program; +// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see +// <http://www.gnu.org/licenses/>. + +/* + * Copyright (c) 1996,1997 + * Silicon Graphics Computer Systems, Inc. + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Silicon Graphics makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + * + * + * Copyright (c) 1994 + * Hewlett-Packard Company + * + * Permission to use, copy, modify, distribute and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appear in all copies and + * that both that copyright notice and this permission notice appear + * in supporting documentation. Hewlett-Packard Company makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + * + */ +#ifndef __INTERPKERNELHASHTABLE_HXX__ +#define __INTERPKERNELHASHTABLE_HXX__ + +#include "InterpKernelStlExt.hxx" +#include "InterpKernelHashFun.hxx" + +#include <vector> +#include <iterator> +#include <algorithm> +#include <functional> + +namespace INTERP_KERNEL +{ + template<class _Val> + struct _Hashtable_node + { + _Hashtable_node* _M_next; + _Val _M_val; + }; + + template<class _Val, class _Key, class _HashFcn, class _ExtractKey, + class _EqualKey, class _Alloc = std::allocator<_Val> > + class hashtable; + + template<class _Val, class _Key, class _HashFcn, + class _ExtractKey, class _EqualKey, class _Alloc> + struct _Hashtable_iterator; + + template<class _Val, class _Key, class _HashFcn, + class _ExtractKey, class _EqualKey, class _Alloc> + struct _Hashtable_const_iterator; + + template<class _Val, class _Key, class _HashFcn, + class _ExtractKey, class _EqualKey, class _Alloc> + struct _Hashtable_iterator + { + typedef hashtable<_Val, _Key, _HashFcn, _ExtractKey, _EqualKey, _Alloc> + _Hashtable; + typedef _Hashtable_iterator<_Val, _Key, _HashFcn, + _ExtractKey, _EqualKey, _Alloc> + iterator; + typedef _Hashtable_const_iterator<_Val, _Key, _HashFcn, + _ExtractKey, _EqualKey, _Alloc> + const_iterator; + typedef _Hashtable_node<_Val> _Node; + typedef std::forward_iterator_tag iterator_category; + typedef _Val value_type; + typedef std::ptrdiff_t difference_type; + typedef std::size_t size_type; + typedef _Val& reference; + typedef _Val* pointer; + + _Node* _M_cur; + _Hashtable* _M_ht; + + _Hashtable_iterator(_Node* __n, _Hashtable* __tab) + : _M_cur(__n), _M_ht(__tab) { } + + _Hashtable_iterator() { } + + reference + operator*() const + { return _M_cur->_M_val; } + + pointer + operator->() const + { return &(operator*()); } + + iterator& + operator++(); + + iterator + operator++(int); + + bool + operator==(const iterator& __it) const + { return _M_cur == __it._M_cur; } + + bool + operator!=(const iterator& __it) const + { return _M_cur != __it._M_cur; } + }; + + template<class _Val, class _Key, class _HashFcn, + class _ExtractKey, class _EqualKey, class _Alloc> + struct _Hashtable_const_iterator + { + typedef hashtable<_Val, _Key, _HashFcn, _ExtractKey, _EqualKey, _Alloc> + _Hashtable; + typedef _Hashtable_iterator<_Val,_Key,_HashFcn, + _ExtractKey,_EqualKey,_Alloc> + iterator; + typedef _Hashtable_const_iterator<_Val, _Key, _HashFcn, + _ExtractKey, _EqualKey, _Alloc> + const_iterator; + typedef _Hashtable_node<_Val> _Node; + + typedef std::forward_iterator_tag iterator_category; + typedef _Val value_type; + typedef std::ptrdiff_t difference_type; + typedef std::size_t size_type; + typedef const _Val& reference; + typedef const _Val* pointer; + + const _Node* _M_cur; + const _Hashtable* _M_ht; + + _Hashtable_const_iterator(const _Node* __n, const _Hashtable* __tab) + : _M_cur(__n), _M_ht(__tab) { } + + _Hashtable_const_iterator() { } + + _Hashtable_const_iterator(const iterator& __it) + : _M_cur(__it._M_cur), _M_ht(__it._M_ht) { } + + reference operator*() const { return _M_cur->_M_val; } + + pointer operator->() const { return &(operator*()); } + + const_iterator& operator++(); + + const_iterator operator++(int); + + bool operator==(const const_iterator& __it) const { return _M_cur == __it._M_cur; } + + bool operator!=(const const_iterator& __it) const { return _M_cur != __it._M_cur; } + }; + + // Note: assumes long is at least 32 bits. + enum { _S_num_primes = 28 }; + + static const unsigned long __stl_prime_list[_S_num_primes] = + { + 53ul, 97ul, 193ul, 389ul, 769ul, + 1543ul, 3079ul, 6151ul, 12289ul, 24593ul, + 49157ul, 98317ul, 196613ul, 393241ul, 786433ul, + 1572869ul, 3145739ul, 6291469ul, 12582917ul, 25165843ul, + 50331653ul, 100663319ul, 201326611ul, 402653189ul, 805306457ul, + 1610612741ul, 3221225473ul, 4294967291ul + }; + + inline unsigned long + __stl_next_prime(unsigned long __n) + { + const unsigned long* __first = __stl_prime_list; + const unsigned long* __last = __stl_prime_list + (int)_S_num_primes; + const unsigned long* pos = std::lower_bound(__first, __last, __n); + return pos == __last ? *(__last - 1) : *pos; + } + + // Forward declaration of operator==. + template<class _Val, class _Key, class _HF, class _Ex, + class _Eq, class _All> + class hashtable; + + template<class _Val, class _Key, class _HF, class _Ex, + class _Eq, class _All> + bool operator==(const hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>& __ht1, + const hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>& __ht2); + + // Hashtables handle allocators a bit differently than other + // containers do. If we're using standard-conforming allocators, then + // a hashtable unconditionally has a member variable to hold its + // allocator, even if it so happens that all instances of the + // allocator type are identical. This is because, for hashtables, + // this extra storage is negligible. Additionally, a base class + // wouldn't serve any other purposes; it wouldn't, for example, + // simplify the exception-handling code. + template<class _Val, class _Key, class _HashFcn, + class _ExtractKey, class _EqualKey, class _Alloc> + class hashtable + { + public: + typedef _Key key_type; + typedef _Val value_type; + typedef _HashFcn hasher; + typedef _EqualKey key_equal; + + typedef std::size_t size_type; + typedef std::ptrdiff_t difference_type; + typedef value_type* pointer; + typedef const value_type* const_pointer; + typedef value_type& reference; + typedef const value_type& const_reference; + + hasher hash_funct() const { return _M_hash; } + + key_equal key_eq() const { return _M_equals; } + + private: + typedef _Hashtable_node<_Val> _Node; + + public: + typedef typename _Alloc::template rebind<value_type>::other allocator_type; + allocator_type get_allocator() const { return _M_node_allocator; } + + private: + typedef typename _Alloc::template rebind<_Node>::other _Node_Alloc; + typedef typename _Alloc::template rebind<_Node*>::other _Nodeptr_Alloc; + typedef std::vector<_Node*, _Nodeptr_Alloc> _Vector_type; + + _Node_Alloc _M_node_allocator; + + _Node *_M_get_node() { return _M_node_allocator.allocate(1); } + + void _M_put_node(_Node* __p) { _M_node_allocator.deallocate(__p, 1); } + + private: + hasher _M_hash; + key_equal _M_equals; + _ExtractKey _M_get_key; + _Vector_type _M_buckets; + size_type _M_num_elements; + + public: + typedef _Hashtable_iterator<_Val, _Key, _HashFcn, _ExtractKey, + _EqualKey, _Alloc> + iterator; + typedef _Hashtable_const_iterator<_Val, _Key, _HashFcn, _ExtractKey, + _EqualKey, _Alloc> + const_iterator; + + friend struct + _Hashtable_iterator<_Val, _Key, _HashFcn, _ExtractKey, _EqualKey, _Alloc>; + + friend struct + _Hashtable_const_iterator<_Val, _Key, _HashFcn, _ExtractKey, + _EqualKey, _Alloc>; + + public: + hashtable(size_type __n, const _HashFcn& __hf, + const _EqualKey& __eql, const _ExtractKey& __ext, + const allocator_type& __a = allocator_type()) + : _M_node_allocator(__a), _M_hash(__hf), _M_equals(__eql), + _M_get_key(__ext), _M_buckets(__a), _M_num_elements(0) + { _M_initialize_buckets(__n); } + + hashtable(size_type __n, const _HashFcn& __hf, + const _EqualKey& __eql, + const allocator_type& __a = allocator_type()) + : _M_node_allocator(__a), _M_hash(__hf), _M_equals(__eql), + _M_get_key(_ExtractKey()), _M_buckets(__a), _M_num_elements(0) + { _M_initialize_buckets(__n); } + + hashtable(const hashtable& __ht) + : _M_node_allocator(__ht.get_allocator()), _M_hash(__ht._M_hash), + _M_equals(__ht._M_equals), _M_get_key(__ht._M_get_key), + _M_buckets(__ht.get_allocator()), _M_num_elements(0) + { _M_copy_from(__ht); } + + hashtable& operator= (const hashtable& __ht) + { + if (&__ht != this) + { + clear(); + _M_hash = __ht._M_hash; + _M_equals = __ht._M_equals; + _M_get_key = __ht._M_get_key; + _M_copy_from(__ht); + } + return *this; + } + + ~hashtable() + { clear(); } + + size_type size() const { return _M_num_elements; } + + size_type max_size() const { return size_type(-1); } + + bool empty() const { return size() == 0; } + + void swap(hashtable& __ht) + { + std::swap(_M_hash, __ht._M_hash); + std::swap(_M_equals, __ht._M_equals); + std::swap(_M_get_key, __ht._M_get_key); + _M_buckets.swap(__ht._M_buckets); + std::swap(_M_num_elements, __ht._M_num_elements); + } + + iterator begin() + { + for (size_type __n = 0; __n < _M_buckets.size(); ++__n) + if (_M_buckets[__n]) + return iterator(_M_buckets[__n], this); + return end(); + } + + iterator end() { return iterator(0, this); } + + const_iterator begin() const + { + for (size_type __n = 0; __n < _M_buckets.size(); ++__n) + if (_M_buckets[__n]) + return const_iterator(_M_buckets[__n], this); + return end(); + } + + const_iterator end() const { return const_iterator(0, this); } + + template<class _Vl, class _Ky, class _HF, class _Ex, class _Eq, class _Al> + friend bool operator==(const hashtable<_Vl, _Ky, _HF, _Ex, _Eq, _Al>&, + const hashtable<_Vl, _Ky, _HF, _Ex, _Eq, _Al>&); + + public: + size_type bucket_count() const { return _M_buckets.size(); } + + size_type max_bucket_count() const { return __stl_prime_list[(int)_S_num_primes - 1]; } + + size_type elems_in_bucket(size_type __bucket) const + { + size_type __result = 0; + for (_Node* __n = _M_buckets[__bucket]; __n; __n = __n->_M_next) + __result += 1; + return __result; + } + + std::pair<iterator, bool> insert_unique(const value_type& __obj) + { + resize(_M_num_elements + 1); + return insert_unique_noresize(__obj); + } + + iterator insert_equal(const value_type& __obj) + { + resize(_M_num_elements + 1); + return insert_equal_noresize(__obj); + } + + std::pair<iterator, bool> insert_unique_noresize(const value_type& __obj); + + iterator insert_equal_noresize(const value_type& __obj); + + template<class _InputIterator> + void insert_unique(_InputIterator __f, _InputIterator __l) + { insert_unique(__f, __l, __iterator_category(__f)); } + + template<class _InputIterator> + void insert_equal(_InputIterator __f, _InputIterator __l) + { insert_equal(__f, __l, __iterator_category(__f)); } + + template<class _InputIterator> + void insert_unique(_InputIterator __f, _InputIterator __l, + std::input_iterator_tag) + { + for ( ; __f != __l; ++__f) + insert_unique(*__f); + } + + template<class _InputIterator> + void insert_equal(_InputIterator __f, _InputIterator __l, + std::input_iterator_tag) + { + for ( ; __f != __l; ++__f) + insert_equal(*__f); + } + + template<class _ForwardIterator> + void insert_unique(_ForwardIterator __f, _ForwardIterator __l, + std::forward_iterator_tag) + { + size_type __n = std::distance(__f, __l); + resize(_M_num_elements + __n); + for ( ; __n > 0; --__n, ++__f) + insert_unique_noresize(*__f); + } + + template<class _ForwardIterator> + void + insert_equal(_ForwardIterator __f, _ForwardIterator __l, + std::forward_iterator_tag) + { + size_type __n = std::distance(__f, __l); + resize(_M_num_elements + __n); + for ( ; __n > 0; --__n, ++__f) + insert_equal_noresize(*__f); + } + + reference find_or_insert(const value_type& __obj); + + iterator find(const key_type& __key) + { + size_type __n = _M_bkt_num_key(__key); + _Node* __first; + for (__first = _M_buckets[__n]; + __first && !_M_equals(_M_get_key(__first->_M_val), __key); + __first = __first->_M_next) + { } + return iterator(__first, this); + } + + const_iterator find(const key_type& __key) const + { + size_type __n = _M_bkt_num_key(__key); + const _Node* __first; + for (__first = _M_buckets[__n]; + __first && !_M_equals(_M_get_key(__first->_M_val), __key); + __first = __first->_M_next) + { } + return const_iterator(__first, this); + } + + size_type count(const key_type& __key) const + { + const size_type __n = _M_bkt_num_key(__key); + size_type __result = 0; + for (const _Node* __cur = _M_buckets[__n]; __cur; + __cur = __cur->_M_next) + if (_M_equals(_M_get_key(__cur->_M_val), __key)) + ++__result; + return __result; + } + + std::pair<iterator, iterator> equal_range(const key_type& __key); + + std::pair<const_iterator, const_iterator> equal_range(const key_type& __key) const; + + size_type erase(const key_type& __key); + + void erase(const iterator& __it); + + void erase(iterator __first, iterator __last); + + void erase(const const_iterator& __it); + + void erase(const_iterator __first, const_iterator __last); + + void resize(size_type __num_elements_hint); + + void clear(); + + private: + size_type _M_next_size(size_type __n) const { return __stl_next_prime(__n); } + + void _M_initialize_buckets(size_type __n) + { + const size_type __n_buckets = _M_next_size(__n); + _M_buckets.reserve(__n_buckets); + _M_buckets.insert(_M_buckets.end(), __n_buckets, (_Node*) 0); + _M_num_elements = 0; + } + + size_type _M_bkt_num_key(const key_type& __key) const + { return _M_bkt_num_key(__key, _M_buckets.size()); } + + size_type _M_bkt_num(const value_type& __obj) const + { return _M_bkt_num_key(_M_get_key(__obj)); } + + size_type _M_bkt_num_key(const key_type& __key, std::size_t __n) const + { return _M_hash(__key) % __n; } + + size_type _M_bkt_num(const value_type& __obj, std::size_t __n) const + { return _M_bkt_num_key(_M_get_key(__obj), __n); } + + _Node* _M_new_node(const value_type& __obj) + { + _Node* __n = _M_get_node(); + __n->_M_next = 0; + try + { + this->get_allocator().construct(&__n->_M_val, __obj); + return __n; + } + catch(...) + { + _M_put_node(__n); + throw; + } + } + + void _M_delete_node(_Node* __n) + { + this->get_allocator().destroy(&__n->_M_val); + _M_put_node(__n); + } + + void _M_erase_bucket(const size_type __n, _Node* __first, _Node* __last); + + void _M_erase_bucket(const size_type __n, _Node* __last); + + void _M_copy_from(const hashtable& __ht); + }; + + template<class _Val, class _Key, class _HF, class _ExK, class _EqK, class _All> + _Hashtable_iterator<_Val, _Key, _HF, _ExK, _EqK, _All>& + _Hashtable_iterator<_Val, _Key, _HF, _ExK, _EqK, _All>:: + operator++() + { + const _Node* __old = _M_cur; + _M_cur = _M_cur->_M_next; + if (!_M_cur) + { + size_type __bucket = _M_ht->_M_bkt_num(__old->_M_val); + while (!_M_cur && ++__bucket < _M_ht->_M_buckets.size()) + _M_cur = _M_ht->_M_buckets[__bucket]; + } + return *this; + } + + template<class _Val, class _Key, class _HF, class _ExK, class _EqK, class _All> + inline _Hashtable_iterator<_Val, _Key, _HF, _ExK, _EqK, _All> + _Hashtable_iterator<_Val, _Key, _HF, _ExK, _EqK, _All>:: + operator++(int) + { + iterator __tmp = *this; + ++*this; + return __tmp; + } + + template<class _Val, class _Key, class _HF, class _ExK, class _EqK, class _All> + _Hashtable_const_iterator<_Val, _Key, _HF, _ExK, _EqK, _All>& + _Hashtable_const_iterator<_Val, _Key, _HF, _ExK, _EqK, _All>:: + operator++() + { + const _Node* __old = _M_cur; + _M_cur = _M_cur->_M_next; + if (!_M_cur) + { + size_type __bucket = _M_ht->_M_bkt_num(__old->_M_val); + while (!_M_cur && ++__bucket < _M_ht->_M_buckets.size()) + _M_cur = _M_ht->_M_buckets[__bucket]; + } + return *this; + } + + template<class _Val, class _Key, class _HF, class _ExK, class _EqK, + class _All> + inline _Hashtable_const_iterator<_Val, _Key, _HF, _ExK, _EqK, _All> + _Hashtable_const_iterator<_Val, _Key, _HF, _ExK, _EqK, _All>:: + operator++(int) + { + const_iterator __tmp = *this; + ++*this; + return __tmp; + } + + template<class _Val, class _Key, class _HF, class _Ex, class _Eq, class _All> + bool operator==(const hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>& __ht1, + const hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>& __ht2) + { + typedef typename hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>::_Node _Node; + + if (__ht1._M_buckets.size() != __ht2._M_buckets.size()) + return false; + + for (std::size_t __n = 0; __n < __ht1._M_buckets.size(); ++__n) + { + _Node* __cur1 = __ht1._M_buckets[__n]; + _Node* __cur2 = __ht2._M_buckets[__n]; + // Check same length of lists + for (; __cur1 && __cur2; + __cur1 = __cur1->_M_next, __cur2 = __cur2->_M_next) + { } + if (__cur1 || __cur2) + return false; + // Now check one's elements are in the other + for (__cur1 = __ht1._M_buckets[__n] ; __cur1; + __cur1 = __cur1->_M_next) + { + bool _found__cur1 = false; + for (__cur2 = __ht2._M_buckets[__n]; + __cur2; __cur2 = __cur2->_M_next) + { + if (__cur1->_M_val == __cur2->_M_val) + { + _found__cur1 = true; + break; + } + } + if (!_found__cur1) + return false; + } + } + return true; + } + + template<class _Val, class _Key, class _HF, class _Ex, class _Eq, class _All> + inline bool operator!=(const hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>& __ht1, + const hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>& __ht2) + { return !(__ht1 == __ht2); } + + template<class _Val, class _Key, class _HF, class _Extract, class _EqKey, class _All> + inline void swap(hashtable<_Val, _Key, _HF, _Extract, _EqKey, _All>& __ht1, + hashtable<_Val, _Key, _HF, _Extract, _EqKey, _All>& __ht2) + { __ht1.swap(__ht2); } + + template<class _Val, class _Key, class _HF, class _Ex, class _Eq, class _All> + std::pair<typename hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>::iterator, bool> + hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>:: + insert_unique_noresize(const value_type& __obj) + { + const size_type __n = _M_bkt_num(__obj); + _Node* __first = _M_buckets[__n]; + + for (_Node* __cur = __first; __cur; __cur = __cur->_M_next) + if (_M_equals(_M_get_key(__cur->_M_val), _M_get_key(__obj))) + return std::pair<iterator, bool>(iterator(__cur, this), false); + + _Node* __tmp = _M_new_node(__obj); + __tmp->_M_next = __first; + _M_buckets[__n] = __tmp; + ++_M_num_elements; + return std::pair<iterator, bool>(iterator(__tmp, this), true); + } + + template<class _Val, class _Key, class _HF, class _Ex, class _Eq, class _All> + typename hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>::iterator + hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>:: + insert_equal_noresize(const value_type& __obj) + { + const size_type __n = _M_bkt_num(__obj); + _Node* __first = _M_buckets[__n]; + + for (_Node* __cur = __first; __cur; __cur = __cur->_M_next) + if (_M_equals(_M_get_key(__cur->_M_val), _M_get_key(__obj))) + { + _Node* __tmp = _M_new_node(__obj); + __tmp->_M_next = __cur->_M_next; + __cur->_M_next = __tmp; + ++_M_num_elements; + return iterator(__tmp, this); + } + + _Node* __tmp = _M_new_node(__obj); + __tmp->_M_next = __first; + _M_buckets[__n] = __tmp; + ++_M_num_elements; + return iterator(__tmp, this); + } + + template<class _Val, class _Key, class _HF, class _Ex, class _Eq, class _All> + typename hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>::reference + hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>:: + find_or_insert(const value_type& __obj) + { + resize(_M_num_elements + 1); + + size_type __n = _M_bkt_num(__obj); + _Node* __first = _M_buckets[__n]; + + for (_Node* __cur = __first; __cur; __cur = __cur->_M_next) + if (_M_equals(_M_get_key(__cur->_M_val), _M_get_key(__obj))) + return __cur->_M_val; + + _Node* __tmp = _M_new_node(__obj); + __tmp->_M_next = __first; + _M_buckets[__n] = __tmp; + ++_M_num_elements; + return __tmp->_M_val; + } + + template<class _Val, class _Key, class _HF, class _Ex, class _Eq, class _All> + std::pair<typename hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>::iterator, + typename hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>::iterator> + hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>::equal_range(const key_type& __key) + { + typedef std::pair<iterator, iterator> _Pii; + const size_type __n = _M_bkt_num_key(__key); + + for (_Node* __first = _M_buckets[__n]; __first; + __first = __first->_M_next) + if (_M_equals(_M_get_key(__first->_M_val), __key)) + { + for (_Node* __cur = __first->_M_next; __cur; + __cur = __cur->_M_next) + if (!_M_equals(_M_get_key(__cur->_M_val), __key)) + return _Pii(iterator(__first, this), iterator(__cur, this)); + for (size_type __m = __n + 1; __m < _M_buckets.size(); ++__m) + if (_M_buckets[__m]) + return _Pii(iterator(__first, this), + iterator(_M_buckets[__m], this)); + return _Pii(iterator(__first, this), end()); + } + return _Pii(end(), end()); + } + + template<class _Val, class _Key, class _HF, class _Ex, class _Eq, class _All> + std::pair<typename hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>::const_iterator, + typename hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>::const_iterator> + hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>::equal_range(const key_type& __key) const + { + typedef std::pair<const_iterator, const_iterator> _Pii; + const size_type __n = _M_bkt_num_key(__key); + + for (const _Node* __first = _M_buckets[__n]; __first; + __first = __first->_M_next) + { + if (_M_equals(_M_get_key(__first->_M_val), __key)) + { + for (const _Node* __cur = __first->_M_next; __cur; + __cur = __cur->_M_next) + if (!_M_equals(_M_get_key(__cur->_M_val), __key)) + return _Pii(const_iterator(__first, this), + const_iterator(__cur, this)); + for (size_type __m = __n + 1; __m < _M_buckets.size(); ++__m) + if (_M_buckets[__m]) + return _Pii(const_iterator(__first, this), + const_iterator(_M_buckets[__m], this)); + return _Pii(const_iterator(__first, this), end()); + } + } + return _Pii(end(), end()); + } + + template<class _Val, class _Key, class _HF, class _Ex, class _Eq, class _All> + typename hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>::size_type + hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>::erase(const key_type& __key) + { + const size_type __n = _M_bkt_num_key(__key); + _Node* __first = _M_buckets[__n]; + size_type __erased = 0; + + if (__first) + { + _Node* __cur = __first; + _Node* __next = __cur->_M_next; + while (__next) + { + if (_M_equals(_M_get_key(__next->_M_val), __key)) + { + __cur->_M_next = __next->_M_next; + _M_delete_node(__next); + __next = __cur->_M_next; + ++__erased; + --_M_num_elements; + } + else + { + __cur = __next; + __next = __cur->_M_next; + } + } + if (_M_equals(_M_get_key(__first->_M_val), __key)) + { + _M_buckets[__n] = __first->_M_next; + _M_delete_node(__first); + ++__erased; + --_M_num_elements; + } + } + return __erased; + } + + template<class _Val, class _Key, class _HF, class _Ex, class _Eq, class _All> + void hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>::erase(const iterator& __it) + { + _Node* __p = __it._M_cur; + if (__p) + { + const size_type __n = _M_bkt_num(__p->_M_val); + _Node* __cur = _M_buckets[__n]; + if (__cur == __p) + { + _M_buckets[__n] = __cur->_M_next; + _M_delete_node(__cur); + --_M_num_elements; + } + else + { + _Node* __next = __cur->_M_next; + while (__next) + { + if (__next == __p) + { + __cur->_M_next = __next->_M_next; + _M_delete_node(__next); + --_M_num_elements; + break; + } + else + { + __cur = __next; + __next = __cur->_M_next; + } + } + } + } + } + + template<class _Val, class _Key, class _HF, class _Ex, class _Eq, class _All> + void hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>::erase(iterator __first, iterator __last) + { + size_type __f_bucket = __first._M_cur ? _M_bkt_num(__first._M_cur->_M_val) : _M_buckets.size(); + + size_type __l_bucket = __last._M_cur ? _M_bkt_num(__last._M_cur->_M_val) : _M_buckets.size(); + + if (__first._M_cur == __last._M_cur) + return; + else if (__f_bucket == __l_bucket) + _M_erase_bucket(__f_bucket, __first._M_cur, __last._M_cur); + else + { + _M_erase_bucket(__f_bucket, __first._M_cur, 0); + for (size_type __n = __f_bucket + 1; __n < __l_bucket; ++__n) + _M_erase_bucket(__n, 0); + if (__l_bucket != _M_buckets.size()) + _M_erase_bucket(__l_bucket, __last._M_cur); + } + } + + template<class _Val, class _Key, class _HF, class _Ex, class _Eq, class _All> + inline void + hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>:: + erase(const_iterator __first, const_iterator __last) + { + erase(iterator(const_cast<_Node*>(__first._M_cur), + const_cast<hashtable*>(__first._M_ht)), + iterator(const_cast<_Node*>(__last._M_cur), + const_cast<hashtable*>(__last._M_ht))); + } + + template<class _Val, class _Key, class _HF, class _Ex, class _Eq, class _All> + inline void hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>::erase(const const_iterator& __it) + { erase(iterator(const_cast<_Node*>(__it._M_cur), const_cast<hashtable*>(__it._M_ht))); } + + template<class _Val, class _Key, class _HF, class _Ex, class _Eq, class _All> + void hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>::resize(size_type __num_elements_hint) + { + const size_type __old_n = _M_buckets.size(); + if (__num_elements_hint > __old_n) + { + const size_type __n = _M_next_size(__num_elements_hint); + if (__n > __old_n) + { + _Vector_type __tmp(__n, (_Node*)(0), _M_buckets.get_allocator()); + try + { + for (size_type __bucket = 0; __bucket < __old_n; ++__bucket) + { + _Node* __first = _M_buckets[__bucket]; + while (__first) + { + size_type __new_bucket = _M_bkt_num(__first->_M_val,__n); + _M_buckets[__bucket] = __first->_M_next; + __first->_M_next = __tmp[__new_bucket]; + __tmp[__new_bucket] = __first; + __first = _M_buckets[__bucket]; + } + } + _M_buckets.swap(__tmp); + } + catch(...) + { + for (size_type __bucket = 0; __bucket < __tmp.size();++__bucket) + { + while (__tmp[__bucket]) + { + _Node* __next = __tmp[__bucket]->_M_next; + _M_delete_node(__tmp[__bucket]); + __tmp[__bucket] = __next; + } + } + throw; + } + } + } + } + + template<class _Val, class _Key, class _HF, class _Ex, class _Eq, class _All> + void hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>::_M_erase_bucket(const size_type __n, _Node* __first, _Node* __last) + { + _Node* __cur = _M_buckets[__n]; + if (__cur == __first) + _M_erase_bucket(__n, __last); + else + { + _Node* __next; + for (__next = __cur->_M_next; + __next != __first; + __cur = __next, __next = __cur->_M_next) + ; + while (__next != __last) + { + __cur->_M_next = __next->_M_next; + _M_delete_node(__next); + __next = __cur->_M_next; + --_M_num_elements; + } + } + } + + template<class _Val, class _Key, class _HF, class _Ex, class _Eq, class _All> + void hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>::_M_erase_bucket(const size_type __n, _Node* __last) + { + _Node* __cur = _M_buckets[__n]; + while (__cur != __last) + { + _Node* __next = __cur->_M_next; + _M_delete_node(__cur); + __cur = __next; + _M_buckets[__n] = __cur; + --_M_num_elements; + } + } + + template<class _Val, class _Key, class _HF, class _Ex, class _Eq, class _All> + void hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>::clear() + { + for (size_type __i = 0; __i < _M_buckets.size(); ++__i) + { + _Node* __cur = _M_buckets[__i]; + while (__cur != 0) + { + _Node* __next = __cur->_M_next; + _M_delete_node(__cur); + __cur = __next; + } + _M_buckets[__i] = 0; + } + _M_num_elements = 0; + } + + template<class _Val, class _Key, class _HF, class _Ex, class _Eq, class _All> + void hashtable<_Val, _Key, _HF, _Ex, _Eq, _All>::_M_copy_from(const hashtable& __ht) + { + _M_buckets.clear(); + _M_buckets.reserve(__ht._M_buckets.size()); + _M_buckets.insert(_M_buckets.end(), __ht._M_buckets.size(), (_Node*) 0); + try + { + for (size_type __i = 0; __i < __ht._M_buckets.size(); ++__i) { + const _Node* __cur = __ht._M_buckets[__i]; + if (__cur) + { + _Node* __local_copy = _M_new_node(__cur->_M_val); + _M_buckets[__i] = __local_copy; + for (_Node* __next = __cur->_M_next; + __next; + __cur = __next, __next = __cur->_M_next) + { + __local_copy->_M_next = _M_new_node(__next->_M_val); + __local_copy = __local_copy->_M_next; + } + } + } + _M_num_elements = __ht._M_num_elements; + } + catch(...) + { + clear(); + throw; + } + } +} + +#endif diff --git a/src/medtool/src/INTERP_KERNEL/Bases/InterpKernelStlExt.hxx b/src/medtool/src/INTERP_KERNEL/Bases/InterpKernelStlExt.hxx new file mode 100644 index 000000000..162cc7871 --- /dev/null +++ b/src/medtool/src/INTERP_KERNEL/Bases/InterpKernelStlExt.hxx @@ -0,0 +1,43 @@ +// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 +// 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 __INTERPKERNELSTLEXT_HXX__ +#define __INTERPKERNELSTLEXT_HXX__ + +#include <functional> + +namespace INTERP_KERNEL +{ + namespace STLEXT + { + template<typename _Pair> + struct Select1st : public std::unary_function<_Pair, typename _Pair::first_type> + { + typename _Pair::first_type& operator()(_Pair& __x) const { return __x.first; } + const typename _Pair::first_type&operator()(const _Pair& __x) const { return __x.first; } + }; + + template<typename _T1, typename _T2> + inline void Construct(_T1* __p, const _T2& __value__) { ::new(static_cast<void*>(__p)) _T1(__value__); } + + template<typename _Tp> inline void Destroy(_Tp* __pointer) { __pointer->~_Tp(); } + } +} + +#endif diff --git a/src/medtool/src/INTERP_KERNEL/Bases/NormalizedGeometricTypes b/src/medtool/src/INTERP_KERNEL/Bases/NormalizedGeometricTypes new file mode 100644 index 000000000..b02d2cb72 --- /dev/null +++ b/src/medtool/src/INTERP_KERNEL/Bases/NormalizedGeometricTypes @@ -0,0 +1,70 @@ +// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 +// 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 __NORMALIZEDGEOMETRICTYPES__ +#define __NORMALIZEDGEOMETRICTYPES__ + +namespace INTERP_KERNEL +{ + typedef enum + { + NORM_POINT1 = 0, + NORM_SEG2 = 1, + NORM_SEG3 = 2, + NORM_SEG4 = 10, + NORM_POLYL = 33, + NORM_TRI3 = 3, + NORM_QUAD4 = 4, + NORM_POLYGON = 5, + NORM_TRI6 = 6, + NORM_TRI7 = 7, + NORM_QUAD8 = 8, + NORM_QUAD9 = 9, + NORM_QPOLYG = 32, + // + NORM_TETRA4 = 14, + NORM_PYRA5 = 15, + NORM_PENTA6 = 16, + NORM_HEXA8 = 18, + NORM_TETRA10 = 20, + NORM_HEXGP12 = 22, + NORM_PYRA13 = 23, + NORM_PENTA15 = 25, + NORM_HEXA20 = 30, + NORM_HEXA27 = 27, + NORM_POLYHED = 31, + NORM_ERROR = 40, + 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. + * + * The images below illustrates the policies in their respective order. + * + * \image html tetra_simplexize_5_6.jpg + * \image html tetra_simplexize_24_48.jpg + */ + typedef enum { PLANAR_FACE_5 = 5, PLANAR_FACE_6 = 6, GENERAL_24 = 24, GENERAL_48 = 48 } SplittingPolicy; +} + +#endif diff --git a/src/medtool/src/INTERP_KERNEL/Bases/NormalizedUnstructuredMesh.hxx b/src/medtool/src/INTERP_KERNEL/Bases/NormalizedUnstructuredMesh.hxx new file mode 100644 index 000000000..26732f94b --- /dev/null +++ b/src/medtool/src/INTERP_KERNEL/Bases/NormalizedUnstructuredMesh.hxx @@ -0,0 +1,35 @@ +// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 +// 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 __NORMALIZEDUNSTRUCTUREDMESH_HXX__ +#define __NORMALIZEDUNSTRUCTUREDMESH_HXX__ + +#include "NormalizedGeometricTypes" + +namespace INTERP_KERNEL +{ + typedef enum + { + ALL_C_MODE , + ALL_FORTRAN_MODE + } NumberingPolicy; +} + +#endif diff --git a/src/medtool/src/INTERP_KERNEL/BoundingBox.cxx b/src/medtool/src/INTERP_KERNEL/BoundingBox.cxx new file mode 100644 index 000000000..de2748b7a --- /dev/null +++ b/src/medtool/src/INTERP_KERNEL/BoundingBox.cxx @@ -0,0 +1,165 @@ +// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// + +#include "BoundingBox.hxx" + +#include <iostream> +#include <algorithm> +#include <cassert> + +namespace INTERP_KERNEL +{ + + /** + * Constructor creating box from an array of the points corresponding + * to the vertices of the element. + * Each point is represented by an array of three doubles. + * + * @param pts array of points + * @param numPts number of vertices + * + */ + BoundingBox::BoundingBox(const double** pts, const unsigned numPts) + :_coords(new double[6]) + { + assert(numPts > 1); + + // initialize with first two points + const double* pt1 = pts[0]; + const double* pt2 = pts[1]; + + for(BoxCoord c = XMIN ; c <= ZMIN ; c = BoxCoord(c + 1)) + { + _coords[c] = std::min(pt1[c], pt2[c]); + _coords[c + 3] = std::max(pt1[c], pt2[c]); + } + + for(unsigned i = 2 ; i < numPts ; ++i) + { + updateWithPoint(pts[i]); + } + + assert(isValid()); + } + + /** + * Constructor creating box from union of two boxes, resulting in a box that encloses both of them + * + * @param box1 the first box + * @param box2 the second box + */ + BoundingBox::BoundingBox(const BoundingBox& box1, const BoundingBox& box2) + : _coords(new double[6]) + { + assert(_coords != 0); + + for(BoxCoord c = XMIN ; c <= ZMIN ; c = BoxCoord(c + 1)) + { + _coords[c] = std::min(box1._coords[c], box2._coords[c]); + _coords[c + 3] = std::max(box1._coords[c + 3], box2._coords[c + 3]); + } + + assert(isValid()); + } + + /** + * Destructor + * + */ + BoundingBox::~BoundingBox() + { + delete[] _coords; + } + + /** + * Determines if the intersection with a given box is empty + * + * @param box BoundingBox with which intersection is tested + * @return true if intersection between boxes is empty, false if not + */ + bool BoundingBox::isDisjointWith(const BoundingBox& box) const + { + for(BoxCoord c = XMIN ; c <= ZMIN ; c = BoxCoord(c + 1)) + { + const double otherMinCoord = box.getCoordinate(c); + const double otherMaxCoord = box.getCoordinate(BoxCoord(c + 3)); + + // boxes are disjoint if there exists a direction in which the + // minimum coordinate of one is greater than the maximum coordinate of the other + + // more stable version ? + // const double tol = 1.0e-2*_coords[c]; + // if(_coords[c] > otherMaxCoord + tol + // || _coords[c + 3] < otherMinCoord - tol) + + + if(_coords[c] > otherMaxCoord + || _coords[c + 3] < otherMinCoord) + + { + return true; + } + + } + return false; + } + + + + /** + * Updates the bounding box to include a given point + * + * @param pt point to be included + * + */ + void BoundingBox::updateWithPoint(const double* pt) + { + for(BoxCoord c = XMIN ; c <= ZMIN ; c = BoxCoord(c + 1)) + { + const double ptVal = pt[c]; + + // update min and max coordinates + _coords[c] = std::min(_coords[c], ptVal); + _coords[c + 3] = std::max(_coords[c + 3], ptVal); + + } + } + + /** + * Checks if the box is valid, which it is if its minimum coordinates are + * smaller than its maximum coordinates in all directions. + * + * @return true if the box is valid, false if not + */ + bool BoundingBox::isValid() const + { + bool valid = true; + for(BoxCoord c = XMIN ; c < ZMIN ; c = BoxCoord(c + 1)) + { + if(_coords[c] > _coords[c + 3]) + { + std::cout << "+++ Error in BoundingBox |: coordinate " << c << " is invalid : " + <<_coords[c] << " > " << _coords[c+3] << std::endl; + valid = false; + } + } + return valid; + } + +} diff --git a/src/medtool/src/INTERP_KERNEL/BoundingBox.hxx b/src/medtool/src/INTERP_KERNEL/BoundingBox.hxx new file mode 100644 index 000000000..02c2ce9a1 --- /dev/null +++ b/src/medtool/src/INTERP_KERNEL/BoundingBox.hxx @@ -0,0 +1,110 @@ +// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 +// 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 __BOUNDINGBOX_HXX__ +#define __BOUNDINGBOX_HXX__ + +#include "INTERPKERNELDefines.hxx" +#include <iostream> + +namespace INTERP_KERNEL +{ + + /** + * \brief Class representing the bounding box of a number of points. + * + */ + class INTERPKERNEL_EXPORT BoundingBox + { + public: + + /// Enumeration representing the six coordinates that define the bounding box + enum BoxCoord { XMIN = 0, YMIN = 1, ZMIN = 2, XMAX = 3, YMAX = 4, ZMAX = 5 }; + + BoundingBox(const double** pts, const unsigned numPts); + + BoundingBox(const BoundingBox& box1, const BoundingBox& box2); + + ~BoundingBox(); + + bool isDisjointWith(const BoundingBox& box) const; + + inline void setCoordinate(const BoxCoord coord, double value); + + inline double getCoordinate(const BoxCoord coord) const; + + void updateWithPoint(const double* pt); + + inline void dumpCoords() const; + + private: + + bool isValid() const; + + /// disallow copying + BoundingBox(const BoundingBox& box); + + /// disallow assignment + BoundingBox& operator=(const BoundingBox& box); + + /// Vector containing the coordinates of the box + /// interlaced in the order XMIN, YMIN, ZMIN, XMAX, YMAX, ZMAX + double* _coords; + + }; + + /** + * Sets a coordinate of the box to a given value. + * + * @param coord coordinate to set + * @param value new value for coordinate + * + */ + inline void BoundingBox::setCoordinate(const BoxCoord coord, double value) + { + _coords[coord] = value; + } + + /** + * Gets a coordinate of the box + * + * @param coord coordinate to get + * @return value of coordinate + * + */ + inline double BoundingBox::getCoordinate(const BoxCoord coord) const + { + return _coords[coord]; + } + + /** + * Prints the coordinates of the box to std::cout + * + */ + inline void BoundingBox::dumpCoords() const + { + std::cout << "[xmin, xmax] = [" << _coords[XMIN] << ", " << _coords[XMAX] << "]" << " | "; + std::cout << "[ymin, ymax] = [" << _coords[YMIN] << ", " << _coords[YMAX] << "]" << " | "; + std::cout << "[zmin, zmax] = [" << _coords[ZMIN] << ", " << _coords[ZMAX] << "]"; + std::cout << std::endl; + } + +} + +#endif diff --git a/src/medtool/src/INTERP_KERNEL/BoxSplittingOptions.cxx b/src/medtool/src/INTERP_KERNEL/BoxSplittingOptions.cxx new file mode 100644 index 000000000..a23a6b7e3 --- /dev/null +++ b/src/medtool/src/INTERP_KERNEL/BoxSplittingOptions.cxx @@ -0,0 +1,47 @@ +// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 +// 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 + +#include "BoxSplittingOptions.hxx" + +#include <sstream> + +const double INTERP_KERNEL::BoxSplittingOptions::DFT_EFFICIENCY_GOAL=0.5; + +const double INTERP_KERNEL::BoxSplittingOptions::DFT_EFFICIENCY_THRESHOLD=0.7; + +void INTERP_KERNEL::BoxSplittingOptions::init() +{ + _efficiency_goal=DFT_EFFICIENCY_GOAL; + _efficiency_threshold=DFT_EFFICIENCY_THRESHOLD; + _min_patch_length=DFT_MIN_PATCH_LENGTH; + _max_patch_length=DFT_MAX_PATCH_LENGTH; + _max_nb_cells_in_patch=DFT_MAX_PATCH_MEASURE; +} + +std::string INTERP_KERNEL::BoxSplittingOptions::printOptions() const +{ + std::ostringstream oss; + oss << "Efficiency goal: " << 100*_efficiency_goal << "%" << std::endl; + oss << "Efficiency threshold: " << 100*_efficiency_threshold << "%" << std::endl; + oss << "Min. patch side length: " << _min_patch_length << std::endl; + oss << "Max. patch side length: " << _max_patch_length << std::endl; + oss << "Max. patch measure: " << _max_nb_cells_in_patch << std::endl; + return oss.str(); +} diff --git a/src/medtool/src/INTERP_KERNEL/BoxSplittingOptions.hxx b/src/medtool/src/INTERP_KERNEL/BoxSplittingOptions.hxx new file mode 100644 index 000000000..0834430ef --- /dev/null +++ b/src/medtool/src/INTERP_KERNEL/BoxSplittingOptions.hxx @@ -0,0 +1,68 @@ +// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 +// 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 + +#ifndef __BOXSPLITTINGOPTIONS_HXX__ +#define __BOXSPLITTINGOPTIONS_HXX__ + +#include "INTERPKERNELDefines.hxx" + +#include <string> + +namespace INTERP_KERNEL +{ + /*! + * \class BoxSplittingOptions + * Class defining the options for box splitting used for AMR algorithm like creation of patches following a criterion. + */ + class INTERPKERNEL_EXPORT BoxSplittingOptions + { + private: + double _efficiency_goal; + double _efficiency_threshold; + int _min_patch_length; + int _max_patch_length; + int _max_nb_cells_in_patch; + public: + BoxSplittingOptions() { init(); } + void init(); + double getEfficiencyGoal() const { return _efficiency_goal; } + void setEfficiencyGoal(double efficiency) { _efficiency_goal=efficiency; } + double getEfficiencyThreshold() const { return _efficiency_threshold; } + void setEfficiencyThreshold(double efficiencyThreshold) { _efficiency_threshold=efficiencyThreshold; } + int getMinimumPatchLength() const { return _min_patch_length; } + void setMinimumPatchLength(int minPatchLength) { _min_patch_length=minPatchLength; } + int getMaximumPatchLength() const { return _max_patch_length; } + void setMaximumPatchLength(int maxNbCellPatch) { _max_patch_length=maxNbCellPatch; } + int getMaximumNbOfCellsInPatch() const { return _max_nb_cells_in_patch; } + void setMaximumNbOfCellsInPatch(int maxNbCellsInPatch) { _max_nb_cells_in_patch=maxNbCellsInPatch; } + void copyOptions(const BoxSplittingOptions & other) { *this=other; } + std::string printOptions() const; + private: + static const int DFT_MIN_PATCH_LENGTH=1; + static const int DFT_MAX_PATCH_LENGTH=2147483647; + static const int DFT_MAX_PATCH_MEASURE=2147483647; + static const double DFT_EFFICIENCY_GOAL; + static const double DFT_EFFICIENCY_THRESHOLD; + public: + static const char PRECISION_STR[]; + }; +} + +#endif diff --git a/src/medtool/src/INTERP_KERNEL/CMakeLists.txt b/src/medtool/src/INTERP_KERNEL/CMakeLists.txt new file mode 100644 index 000000000..0afa489f5 --- /dev/null +++ b/src/medtool/src/INTERP_KERNEL/CMakeLists.txt @@ -0,0 +1,88 @@ +# Copyright (C) 2012-2015 CEA/DEN, EDF 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, 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 +# 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) + +SET(interpkernel_SOURCES + TransformedTriangle.cxx + TransformedTriangleIntersect.cxx + TransformedTriangleMath.cxx + BoundingBox.cxx + TranslationRotationMatrix.cxx + TetraAffineTransform.cxx + CellModel.cxx + DiameterCalculator.cxx + UnitTetraIntersectionBary.cxx + InterpolationOptions.cxx + BoxSplittingOptions.cxx + DirectedBoundingBox.cxx + Interpolation2DCurve.cxx + Interpolation3DSurf.cxx + Interpolation3D.cxx + Interpolation3D2D.cxx + MeshElement.cxx + InterpKernelMeshQuality.cxx + InterpKernelCellSimplify.cxx + InterpKernelMatrixTools.cxx + VolSurfUser.cxx + SplitterTetra.cxx + Bases/InterpKernelException.cxx + Geometric2D/InterpKernelGeo2DAbstractEdge.cxx + Geometric2D/InterpKernelGeo2DBounds.cxx + Geometric2D/InterpKernelGeo2DPrecision.cxx + Geometric2D/InterpKernelGeo2DComposedEdge.cxx + Geometric2D/InterpKernelGeo2DEdgeArcCircle.cxx + Geometric2D/InterpKernelGeo2DEdge.cxx + Geometric2D/InterpKernelGeo2DEdgeInfLin.cxx + Geometric2D/InterpKernelGeo2DEdgeLin.cxx + Geometric2D/InterpKernelGeo2DElementaryEdge.cxx + Geometric2D/InterpKernelGeo2DNode.cxx + Geometric2D/InterpKernelGeo2DQuadraticPolygon.cxx + ExprEval/InterpKernelExprParser.cxx + ExprEval/InterpKernelFunction.cxx + ExprEval/InterpKernelUnit.cxx + ExprEval/InterpKernelValue.cxx + ExprEval/InterpKernelAsmX86.cxx + GaussPoints/InterpKernelGaussCoords.cxx + ) + +INCLUDE_DIRECTORIES( + ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_CURRENT_SOURCE_DIR}/Bases + ${CMAKE_CURRENT_SOURCE_DIR}/Geometric2D + ${CMAKE_CURRENT_SOURCE_DIR}/ExprEval + ${CMAKE_CURRENT_SOURCE_DIR}/GaussPoints + ) + +SET(PLATFORM_MMAP) +IF(NOT WIN32) + SET(PLATFORM_MMAP "-D_POSIX_MAPPED_FILES") +ENDIF(NOT WIN32) + +ADD_LIBRARY(interpkernel SHARED ${interpkernel_SOURCES}) +SET_TARGET_PROPERTIES(interpkernel PROPERTIES COMPILE_FLAGS "${PLATFORM_MMAP}") +TARGET_LINK_LIBRARIES(interpkernel ${PLATFORM_LIBS}) +INSTALL(TARGETS interpkernel EXPORT ${PROJECT_NAME}TargetGroup DESTINATION ${MEDTOOL_INSTALL_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} Bases/NormalizedGeometricTypes DESTINATION ${MEDTOOL_INSTALL_HEADERS}) + +# Will be used for SWIG dependencies: +SET (interpkernel_HEADERS_HXX PARENT_SCOPE) +SET (interpkernel_HEADERS_TXX PARENT_SCOPE) diff --git a/src/medtool/src/INTERP_KERNEL/CellModel.cxx b/src/medtool/src/INTERP_KERNEL/CellModel.cxx new file mode 100644 index 000000000..d3e364196 --- /dev/null +++ b/src/medtool/src/INTERP_KERNEL/CellModel.cxx @@ -0,0 +1,889 @@ +// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 +// 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 "CellModel.hxx" + +#include "InterpKernelException.hxx" +#include "DiameterCalculator.hxx" + +#include <algorithm> +#include <sstream> +#include <vector> +#include <limits> + +namespace INTERP_KERNEL +{ + const char *CellModel::CELL_TYPES_REPR[]={"NORM_POINT1", "NORM_SEG2", "NORM_SEG3", "NORM_TRI3", "NORM_QUAD4",// 0->4 + "NORM_POLYGON", "NORM_TRI6", "NORM_TRI7" , "NORM_QUAD8", "NORM_QUAD9",//5->9 + "NORM_SEG4", "", "", "", "NORM_TETRA4",//10->14 + "NORM_PYRA5", "NORM_PENTA6", "", "NORM_HEXA8", "",//15->19 + "NORM_TETRA10", "", "NORM_HEXGP12", "NORM_PYRA13", "",//20->24 + "NORM_PENTA15", "", "NORM_HEXA27", "", "",//25->29 + "NORM_HEXA20", "NORM_POLYHED", "NORM_QPOLYG", "NORM_POLYL", "",//30->34 + "", "", "", "", "",//35->39 + "NORM_ERROR"}; + + std::map<NormalizedCellType,CellModel> CellModel::_map_of_unique_instance; + + const CellModel& CellModel::GetCellModel(NormalizedCellType type) + { + if(_map_of_unique_instance.empty()) + buildUniqueInstance(); + const std::map<NormalizedCellType,CellModel>::iterator iter=_map_of_unique_instance.find(type); + if(iter==_map_of_unique_instance.end()) + { + std::ostringstream stream; stream << "no cellmodel for normalized type " << type; + throw Exception(stream.str().c_str()); + } + return (*iter).second; + } + + const char *CellModel::getRepr() const + { + return CELL_TYPES_REPR[(int)_type]; + } + + /*! + * This method is compatible with all types including dynamic one. + */ + bool CellModel::isCompatibleWith(NormalizedCellType type) const + { + if(_type==type) + return true; + const CellModel& other=GetCellModel(type); + if(_dim!=other.getDimension()) + return false; + bool b1=isQuadratic(); + bool b2=other.isQuadratic(); + if((b1 && !b2) || (!b1 && b2)) + return false; + b1=isDynamic(); + b2=other.isDynamic(); + return b1 || b2; + } + + void CellModel::buildUniqueInstance() + { + _map_of_unique_instance.insert(std::make_pair(NORM_POINT1,CellModel(NORM_POINT1))); + _map_of_unique_instance.insert(std::make_pair(NORM_SEG2,CellModel(NORM_SEG2))); + _map_of_unique_instance.insert(std::make_pair(NORM_SEG3,CellModel(NORM_SEG3))); + _map_of_unique_instance.insert(std::make_pair(NORM_SEG4,CellModel(NORM_SEG4))); + _map_of_unique_instance.insert(std::make_pair(NORM_TRI3,CellModel(NORM_TRI3))); + _map_of_unique_instance.insert(std::make_pair(NORM_QUAD4,CellModel(NORM_QUAD4))); + _map_of_unique_instance.insert(std::make_pair(NORM_TRI6,CellModel(NORM_TRI6))); + _map_of_unique_instance.insert(std::make_pair(NORM_TRI7,CellModel(NORM_TRI7))); + _map_of_unique_instance.insert(std::make_pair(NORM_QUAD8,CellModel(NORM_QUAD8))); + _map_of_unique_instance.insert(std::make_pair(NORM_QUAD9,CellModel(NORM_QUAD9))); + _map_of_unique_instance.insert(std::make_pair(NORM_TETRA4,CellModel(NORM_TETRA4))); + _map_of_unique_instance.insert(std::make_pair(NORM_HEXA8,CellModel(NORM_HEXA8))); + _map_of_unique_instance.insert(std::make_pair(NORM_PYRA5,CellModel(NORM_PYRA5))); + _map_of_unique_instance.insert(std::make_pair(NORM_PENTA6,CellModel(NORM_PENTA6))); + _map_of_unique_instance.insert(std::make_pair(NORM_TETRA10,CellModel(NORM_TETRA10))); + _map_of_unique_instance.insert(std::make_pair(NORM_HEXGP12,CellModel(NORM_HEXGP12))); + _map_of_unique_instance.insert(std::make_pair(NORM_PYRA13,CellModel(NORM_PYRA13))); + _map_of_unique_instance.insert(std::make_pair(NORM_PENTA15,CellModel(NORM_PENTA15))); + _map_of_unique_instance.insert(std::make_pair(NORM_HEXA20,CellModel(NORM_HEXA20))); + _map_of_unique_instance.insert(std::make_pair(NORM_HEXA27,CellModel(NORM_HEXA27))); + _map_of_unique_instance.insert(std::make_pair(NORM_POLYGON,CellModel(NORM_POLYGON))); + _map_of_unique_instance.insert(std::make_pair(NORM_POLYHED,CellModel(NORM_POLYHED))); + _map_of_unique_instance.insert(std::make_pair(NORM_QPOLYG,CellModel(NORM_QPOLYG))); + _map_of_unique_instance.insert(std::make_pair(NORM_POLYL,CellModel(NORM_POLYL))); + _map_of_unique_instance.insert(std::make_pair(NORM_ERROR,CellModel(NORM_ERROR))); + } + + CellModel::CellModel(NormalizedCellType type):_type(type) + { + _is_extruded=false; + _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<unsigned>::max(); + switch(type) + { + case NORM_POINT1: + { + _nb_of_pts=1; _nb_of_sons=0; _dim=0; _extruded_type=NORM_SEG2; _is_simplex=true; + } + break; + case NORM_SEG2: + { + _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; + } + break; + case NORM_SEG3: + { + _nb_of_pts=3; _nb_of_sons=3; _dim=1; _extruded_type=NORM_QUAD8; _linear_type=NORM_SEG2; _quadratic=true; _is_simplex=false; + _sons_type[0]=NORM_POINT1; _sons_type[1]=NORM_POINT1; _sons_type[2]=NORM_POINT1; + _sons_con[0][0]=0; _nb_of_sons_con[0]=1; + _sons_con[1][0]=1; _nb_of_sons_con[1]=1; + _sons_con[2][0]=2; _nb_of_sons_con[2]=1; + } + break; + case NORM_SEG4: + { + _nb_of_pts=4; _nb_of_sons=4; _dim=1; _linear_type=NORM_SEG2; _quadratic=true; _is_simplex=false; // no _extruded_type because no cubic 2D cell + _sons_type[0]=NORM_POINT1; _sons_type[1]=NORM_POINT1; _sons_type[2]=NORM_POINT1; _sons_type[3]=NORM_POINT1; + _sons_con[0][0]=0; _nb_of_sons_con[0]=1; + _sons_con[1][0]=1; _nb_of_sons_con[1]=1; + _sons_con[2][0]=2; _nb_of_sons_con[2]=1; + _sons_con[3][0]=3; _nb_of_sons_con[3]=1; + } + break; + case NORM_TETRA4: + { + _nb_of_pts=4; _nb_of_sons=4; _dim=3; _quadratic_type=NORM_TETRA10; _is_simplex=true; + _sons_type[0]=NORM_TRI3; _sons_type[1]=NORM_TRI3; _sons_type[2]=NORM_TRI3; _sons_type[3]=NORM_TRI3; + _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]=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; _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; + _sons_con[2][0]=0; _sons_con[2][1]=4; _sons_con[2][2]=5; _sons_con[2][3]=1; _nb_of_sons_con[2]=4; + _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; _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; + _sons_con[2][0]=2; _sons_con[2][1]=3; _nb_of_sons_con[2]=2; + _sons_con[3][0]=3; _sons_con[3][1]=0; _nb_of_sons_con[3]=2; _extruded_type=NORM_HEXA8; + } + break; + case NORM_TRI3: + { + _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; + _sons_con[2][0]=2; _sons_con[2][1]=0; _nb_of_sons_con[2]=2; _extruded_type=NORM_PENTA6; + } + break; + case NORM_TRI6: + { + _nb_of_pts=6; _nb_of_sons=3; _dim=2; _linear_type=NORM_TRI3; _is_simplex=false; + _sons_type[0]=NORM_SEG3; _sons_type[1]=NORM_SEG3; _sons_type[2]=NORM_SEG3; + _sons_con[0][0]=0; _sons_con[0][1]=1; _sons_con[0][2]=3; _nb_of_sons_con[0]=3; + _sons_con[1][0]=1; _sons_con[1][1]=2; _sons_con[1][2]=4; _nb_of_sons_con[1]=3; + _sons_con[2][0]=2; _sons_con[2][1]=0; _sons_con[2][2]=5; _nb_of_sons_con[2]=3; _quadratic=true; _extruded_type=NORM_PENTA15; + } + break; + case NORM_TRI7: + { + _nb_of_pts=7; _nb_of_sons=3; _dim=2; _linear_type=NORM_TRI3; _is_simplex=false; + _sons_type[0]=NORM_SEG3; _sons_type[1]=NORM_SEG3; _sons_type[2]=NORM_SEG3; + _sons_con[0][0]=0; _sons_con[0][1]=1; _sons_con[0][2]=3; _nb_of_sons_con[0]=3; + _sons_con[1][0]=1; _sons_con[1][1]=2; _sons_con[1][2]=4; _nb_of_sons_con[1]=3; + _sons_con[2][0]=2; _sons_con[2][1]=0; _sons_con[2][2]=5; _nb_of_sons_con[2]=3; _quadratic=true; //no extruded type because no penta20 + } + break; + case NORM_QUAD8: + { + _nb_of_pts=8; _nb_of_sons=4; _dim=2; _linear_type=NORM_QUAD4; _is_simplex=false; + _sons_type[0]=NORM_SEG3; _sons_type[1]=NORM_SEG3; _sons_type[2]=NORM_SEG3; _sons_type[3]=NORM_SEG3; + _sons_con[0][0]=0; _sons_con[0][1]=1; _sons_con[0][2]=4; _nb_of_sons_con[0]=3; + _sons_con[1][0]=1; _sons_con[1][1]=2; _sons_con[1][2]=5; _nb_of_sons_con[1]=3; + _sons_con[2][0]=2; _sons_con[2][1]=3; _sons_con[2][2]=6; _nb_of_sons_con[2]=3; + _sons_con[3][0]=3; _sons_con[3][1]=0; _sons_con[3][2]=7; _nb_of_sons_con[3]=3; _quadratic=true; _extruded_type=NORM_HEXA20; + } + break; + case NORM_QUAD9: + { + _nb_of_pts=9; _nb_of_sons=4; _dim=2; _linear_type=NORM_QUAD4; _is_simplex=false; + _sons_type[0]=NORM_SEG3; _sons_type[1]=NORM_SEG3; _sons_type[2]=NORM_SEG3; _sons_type[3]=NORM_SEG3; + _sons_con[0][0]=0; _sons_con[0][1]=1; _sons_con[0][2]=4; _nb_of_sons_con[0]=3; + _sons_con[1][0]=1; _sons_con[1][1]=2; _sons_con[1][2]=5; _nb_of_sons_con[1]=3; + _sons_con[2][0]=2; _sons_con[2][1]=3; _sons_con[2][2]=6; _nb_of_sons_con[2]=3; + _sons_con[3][0]=3; _sons_con[3][1]=0; _sons_con[3][2]=7; _nb_of_sons_con[3]=3; _quadratic=true; _extruded_type=NORM_HEXA27; + } + break; + case NORM_PYRA5: + { + _nb_of_pts=5; _nb_of_sons=5; _dim=3; _quadratic_type=NORM_PYRA13; _is_simplex=false; + _sons_type[0]=NORM_QUAD4; _sons_type[1]=NORM_TRI3; _sons_type[2]=NORM_TRI3; _sons_type[3]=NORM_TRI3; _sons_type[4]=NORM_TRI3; + _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]=0; _sons_con[1][1]=4; _sons_con[1][2]=1; _nb_of_sons_con[1]=3; + _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; _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: + { + _nb_of_pts=10; _nb_of_sons=4; _dim=3; _linear_type=NORM_TETRA4; _is_simplex=false; + _sons_type[0]=NORM_TRI6; _sons_type[1]=NORM_TRI6; _sons_type[2]=NORM_TRI6; _sons_type[3]=NORM_TRI6; + _sons_con[0][0]=0; _sons_con[0][1]=1; _sons_con[0][2]=2; _sons_con[0][3]=4; _sons_con[0][4]=5; _sons_con[0][5]=6; _nb_of_sons_con[0]=6; + _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: + { + _nb_of_pts=12; _nb_of_sons=8; _dim=3; _is_simplex=false; _is_extruded=true; + _sons_type[0]=NORM_POLYGON; _sons_type[1]=NORM_POLYGON; _sons_type[2]=NORM_QUAD4; _sons_type[3]=NORM_QUAD4; _sons_type[4]=NORM_QUAD4; _sons_type[5]=NORM_QUAD4; + _sons_type[6]=NORM_QUAD4; _sons_type[7]=NORM_QUAD4; + _sons_con[0][0]=0; _sons_con[0][1]=1; _sons_con[0][2]=2; _sons_con[0][3]=3; _sons_con[0][4]=4; _sons_con[0][5]=5; _nb_of_sons_con[0]=6; + _sons_con[1][0]=6; _sons_con[1][1]=11; _sons_con[1][2]=10; _sons_con[1][3]=9; _sons_con[1][4]=8; _sons_con[1][5]=7; _nb_of_sons_con[1]=6; + _sons_con[2][0]=0; _sons_con[2][1]=6; _sons_con[2][2]=7; _sons_con[2][3]=1; _nb_of_sons_con[2]=4; + _sons_con[3][0]=1; _sons_con[3][1]=7; _sons_con[3][2]=8; _sons_con[3][3]=2; _nb_of_sons_con[3]=4; + _sons_con[4][0]=2; _sons_con[4][1]=8; _sons_con[4][2]=9; _sons_con[4][3]=3; _nb_of_sons_con[4]=4; + _sons_con[5][0]=3; _sons_con[5][1]=9; _sons_con[5][2]=10; _sons_con[5][3]=4; _nb_of_sons_con[5]=4; + _sons_con[6][0]=4; _sons_con[6][1]=10; _sons_con[6][2]=11; _sons_con[6][3]=5; _nb_of_sons_con[6]=4; + _sons_con[7][0]=5; _sons_con[7][1]=11; _sons_con[7][2]=6; _sons_con[7][3]=0; _nb_of_sons_con[7]=4; + } + break; + case NORM_PYRA13: + { + _nb_of_pts=13; _nb_of_sons=5; _dim=3; _linear_type=NORM_PYRA5; _is_simplex=false; + _sons_type[0]=NORM_QUAD8; _sons_type[1]=NORM_TRI6; _sons_type[2]=NORM_TRI6; _sons_type[3]=NORM_TRI6; _sons_type[4]=NORM_TRI6; + _sons_con[0][0]=0; _sons_con[0][1]=1; _sons_con[0][2]=2; _sons_con[0][3]=3; _sons_con[0][4]=5; _sons_con[0][5]=6; _sons_con[0][6]=7; _sons_con[0][7]=8; _nb_of_sons_con[0]=8; + _sons_con[1][0]=0; _sons_con[1][1]=4; _sons_con[1][2]=1; _sons_con[1][3]=9; _sons_con[1][4]=10; _sons_con[1][5]=5; _nb_of_sons_con[1]=6; + _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: + { + _nb_of_pts=15; _nb_of_sons=5; _dim=3; _linear_type=NORM_PENTA6; _is_simplex=false; + _sons_type[0]=NORM_TRI6; _sons_type[1]=NORM_TRI6; _sons_type[2]=NORM_QUAD8; _sons_type[3]=NORM_QUAD8; _sons_type[4]=NORM_QUAD8; + _sons_con[0][0]=0; _sons_con[0][1]=1; _sons_con[0][2]=2; _sons_con[0][3]=6; _sons_con[0][4]=7; _sons_con[0][5]=8; _nb_of_sons_con[0]=6; + _sons_con[1][0]=3; _sons_con[1][1]=5; _sons_con[1][2]=4; _sons_con[1][3]=11; _sons_con[1][4]=10; _sons_con[1][5]=9; _nb_of_sons_con[1]=6; + _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: + { + _nb_of_pts=20; _nb_of_sons=6; _dim=3; _linear_type=NORM_HEXA8; _is_simplex=false; + _sons_type[0]=NORM_QUAD8; _sons_type[1]=NORM_QUAD8; _sons_type[2]=NORM_QUAD8; _sons_type[3]=NORM_QUAD8; _sons_type[4]=NORM_QUAD8; _sons_type[5]=NORM_QUAD8; + _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][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: + { + _nb_of_pts=27; _nb_of_sons=6; _dim=3; _linear_type=NORM_HEXA8; _is_simplex=false; + _sons_type[0]=NORM_QUAD9; _sons_type[1]=NORM_QUAD9; _sons_type[2]=NORM_QUAD9; _sons_type[3]=NORM_QUAD9; _sons_type[4]=NORM_QUAD9; _sons_type[5]=NORM_QUAD9; + _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][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; _quadratic_type=NORM_QPOLYG; + } + break; + case NORM_POLYHED: + { + _nb_of_pts=0; _nb_of_sons=0; _dim=3; _dyn=true; _is_simplex=false; + } + break; + case NORM_QPOLYG: + { + _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: + { + _nb_of_pts=0; _nb_of_sons=0; _dim=1; _dyn=true; _extruded_type=NORM_POLYGON; _is_simplex=false; + } + break; + case NORM_ERROR: + { + _nb_of_pts=std::numeric_limits<unsigned>::max(); _nb_of_sons=std::numeric_limits<unsigned>::max(); _dim=std::numeric_limits<unsigned>::max(); + } + break; + } + } + + /*! + * Equivalent to getNumberOfSons except that this method deals with dynamic type. + */ + unsigned CellModel::getNumberOfSons2(const int *conn, int lgth) const + { + if(!isDynamic()) + return getNumberOfSons(); + if(_dim==2) + { + if(_type==NORM_POLYGON) + return lgth; + else + return lgth/2; + } + else if(_dim==1) + return lgth;//NORM_POLYL + else + 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. + */ + NormalizedCellType CellModel::getSonType2(unsigned sonId) const + { + if(!isDynamic()) + return getSonType(sonId); + if(_dim==2) + { + if(_type==NORM_POLYGON) + return NORM_SEG2; + else + return NORM_SEG3; + } + else if(_dim==1) + return NORM_ERROR;//NORM_POLYL + //polyedron + return NORM_POLYGON; + } + + /*! + * \b WARNING this method do not manage correctly types that return true at the call of isDynamic. Use fillSonCellNodalConnectivity2 instead. + */ + unsigned CellModel::fillSonCellNodalConnectivity(int sonId, const int *nodalConn, int *sonNodalConn) const + { + unsigned nbOfTurnLoop=_nb_of_sons_con[sonId]; + const unsigned *sonConn=_sons_con[sonId]; + for(unsigned i=0;i<nbOfTurnLoop;i++) + sonNodalConn[i]=nodalConn[sonConn[i]]; + return nbOfTurnLoop; + } + + unsigned CellModel::fillSonCellNodalConnectivity2(int sonId, const int *nodalConn, int lgth, int *sonNodalConn, NormalizedCellType& typeOfSon) const + { + typeOfSon=getSonType2(sonId); + if(!isDynamic()) + return fillSonCellNodalConnectivity(sonId,nodalConn,sonNodalConn); + else + { + if(_dim==2)//polygon + { + if(_type==NORM_POLYGON) + { + sonNodalConn[0]=nodalConn[sonId]; + sonNodalConn[1]=nodalConn[(sonId+1)%lgth]; + return 2; + } + else + { + sonNodalConn[0]=nodalConn[sonId]; + sonNodalConn[1]=nodalConn[(sonId+1)%(lgth/2)]; + sonNodalConn[2]=nodalConn[sonId+(lgth/2)]; + return 3; + } + } + else if(_dim==3) + {//polyedron + const int *where=nodalConn; + for(int i=0;i<sonId;i++) + { + where=std::find(where,nodalConn+lgth,-1); + where++; + } + const int *where2=std::find(where,nodalConn+lgth,-1); + std::copy(where,where2,sonNodalConn); + return where2-where; + } + else + 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 !"); + } + + void CellModel::changeOrientationOf2D(int *nodalConn, unsigned int sz) const + { + if(sz<1) + return ; + if(!isQuadratic()) + { + std::vector<int> tmp(sz-1); + std::copy(nodalConn+1,nodalConn+sz,tmp.rbegin()); + std::copy(tmp.begin(),tmp.end(),nodalConn+1); + } + else + { + unsigned int sz2(sz/2); + std::vector<int> tmp0(sz2-1),tmp1(sz2); + std::copy(nodalConn+1,nodalConn+sz2,tmp0.rbegin()); + std::copy(nodalConn+sz2,nodalConn+sz,tmp1.rbegin()); + std::copy(tmp0.begin(),tmp0.end(),nodalConn+1); + std::copy(tmp1.begin(),tmp1.end(),nodalConn+sz2); + } + } + + void CellModel::changeOrientationOf1D(int *nodalConn, unsigned int sz) const + { + if(!isDynamic()) + { + if(sz==2 || sz==3) + { + std::swap(nodalConn[0],nodalConn[1]); + return ; + } + else if(sz==4) + { + std::swap(nodalConn[0],nodalConn[1]); + std::swap(nodalConn[2],nodalConn[3]); + } + else + throw Exception("CellModel::changeOrientationOf1D : unrecognized 1D cell type !"); + } + else + { + std::vector<int> tmp(sz-1); + std::copy(nodalConn+1,nodalConn+sz,tmp.rbegin()); + std::copy(tmp.begin(),tmp.end(),nodalConn+1); + } + } + + //================================================================================ + /*! + * \brief Return number of nodes in sonId-th son of a Dynamic() cell + */ + //================================================================================ + + unsigned CellModel::getNumberOfNodesConstituentTheSon2(unsigned sonId, const int *nodalConn, int lgth) const + { + if(!isDynamic()) + return getNumberOfNodesConstituentTheSon(sonId); + + if(_dim==2)//polygon + { + if(_type==NORM_POLYGON) + return 2; + else + return 3; + } + else if(_dim==3) + {//polyedron + const int *where=nodalConn; + for(unsigned int i=0;i<sonId;i++) + { + where=std::find(where,nodalConn+lgth,-1); + where++; + } + const int *where2=std::find(where,nodalConn+lgth,-1); + return where2-where; + } + else + throw INTERP_KERNEL::Exception("CellModel::getNumberOfNodesConstituentTheSon2 : no sons on NORM_POLYL !"); + } + + /*! + * This method retrieves if cell1 represented by 'conn1' and cell2 represented by 'conn2' + * are equivalent by a permutation or not. This method expects to work on 1D or 2D (only mesh dimension where it is possible to have a spaceDim) strictly higher than meshDim. + * If not an exception will be thrown. + * @return True if two cells have same orientation, false if not. + */ + bool CellModel::getOrientationStatus(unsigned lgth, const int *conn1, const int *conn2) const + { + if(_dim!=1 && _dim!=2) + throw INTERP_KERNEL::Exception("CellModel::getOrientationStatus : invalid dimension ! Must be 1 or 2 !"); + if(!_quadratic) + { + std::vector<int> tmp(2*lgth); + std::vector<int>::iterator it=std::copy(conn1,conn1+lgth,tmp.begin()); + std::copy(conn1,conn1+lgth,it); + it=std::search(tmp.begin(),tmp.end(),conn2,conn2+lgth); + if(it==tmp.begin()) + return true; + if(it!=tmp.end()) + return _dim!=1; + std::vector<int>::reverse_iterator it2=std::search(tmp.rbegin(),tmp.rend(),conn2,conn2+lgth); + if(it2!=tmp.rend()) + return false; + throw INTERP_KERNEL::Exception("CellModel::getOrientationStatus : Request of orientation status of non equal connectively cells !"); + } + else + { + if(_dim!=1) + { + std::vector<int> tmp(lgth); + std::vector<int>::iterator it=std::copy(conn1,conn1+lgth/2,tmp.begin()); + std::copy(conn1,conn1+lgth/2,it); + it=std::search(tmp.begin(),tmp.end(),conn2,conn2+lgth/2); + int d=std::distance(tmp.begin(),it); + if(it==tmp.end()) + return false; + it=std::copy(conn1+lgth/2,conn1+lgth,tmp.begin()); + std::copy(conn1+lgth/2,conn1+lgth,it); + it=std::search(tmp.begin(),tmp.end(),conn2,conn2+lgth); + if(it==tmp.end()) + return false; + int d2=std::distance(tmp.begin(),it); + return d==d2; + } + else + { + int p=(lgth+1)/2; + std::vector<int> tmp(2*p); + std::vector<int>::iterator it=std::copy(conn1,conn1+p,tmp.begin()); + std::copy(conn1,conn1+p,it); + it=std::search(tmp.begin(),tmp.end(),conn2,conn2+p); + int d=std::distance(tmp.begin(),it); + if(it==tmp.end()) + return false; + tmp.resize(2*p-2); + it=std::copy(conn1+p,conn1+lgth,tmp.begin()); + std::copy(conn1+p,conn1+lgth,it); + it=std::search(tmp.begin(),tmp.end(),conn2+p,conn2+lgth); + if(it==tmp.end()) + return false; + int d2=std::distance(tmp.begin(),it); + return d==d2; + } + } + } + + DiameterCalculator *CellModel::buildInstanceOfDiameterCalulator(int spaceDim) const + { + switch(_type) + { + case NORM_TRI3: + { + switch(spaceDim) + { + case 2: + return new DiameterCalulatorTRI3S2; + case 3: + return new DiameterCalulatorTRI3S3; + default: + throw Exception("CellModel::buildInstanceOfDiameterCalulator : For TRI3 only space dimension 2 and 3 implemented !"); + } + break; + } + case NORM_QUAD4: + { + switch(spaceDim) + { + case 2: + return new DiameterCalulatorQUAD4S2; + case 3: + return new DiameterCalulatorQUAD4S3; + default: + throw Exception("CellModel::buildInstanceOfDiameterCalulator : For QUAD4 only space dimension 2 and 3 implemented !"); + } + break; + } + case NORM_TRI6: + { + switch(spaceDim) + { + case 2: + return new DiameterCalulatorTRI6S2; + case 3: + return new DiameterCalulatorTRI6S3; + default: + throw Exception("CellModel::buildInstanceOfDiameterCalulator : For TRI6 only space dimension 2 and 3 implemented !"); + } + break; + } + case NORM_TRI7: + { + switch(spaceDim) + { + case 2: + return new DiameterCalulatorTRI7S2; + case 3: + return new DiameterCalulatorTRI7S3; + default: + throw Exception("CellModel::buildInstanceOfDiameterCalulator : For TRI7 only space dimension 2 and 3 implemented !"); + } + break; + } + case NORM_QUAD8: + { + switch(spaceDim) + { + case 2: + return new DiameterCalulatorQUAD8S2; + case 3: + return new DiameterCalulatorQUAD8S3; + default: + throw Exception("CellModel::buildInstanceOfDiameterCalulator : For QUAD8 only space dimension 2 and 3 implemented !"); + } + break; + } + case NORM_QUAD9: + { + switch(spaceDim) + { + case 2: + return new DiameterCalulatorQUAD9S2; + case 3: + return new DiameterCalulatorQUAD9S3; + default: + throw Exception("CellModel::buildInstanceOfDiameterCalulator : For QUAD9 only space dimension 2 and 3 implemented !"); + } + break; + } + case NORM_TETRA4: + { + if(spaceDim==3) + return new DiameterCalulatorTETRA4; + else + throw Exception("CellModel::buildInstanceOfDiameterCalulator : For TETRA4 space dimension 3 expected !"); + } + case NORM_TETRA10: + { + if(spaceDim==3) + return new DiameterCalulatorTETRA10; + else + throw Exception("CellModel::buildInstanceOfDiameterCalulator : For TETRA10 space dimension 3 expected !"); + } + case NORM_HEXA8: + { + if(spaceDim==3) + return new DiameterCalulatorHEXA8; + else + throw Exception("CellModel::buildInstanceOfDiameterCalulator : For HEXA8 space dimension 3 expected !"); + } + case NORM_HEXA20: + { + if(spaceDim==3) + return new DiameterCalulatorHEXA20; + else + throw Exception("CellModel::buildInstanceOfDiameterCalulator : For HEXA20 space dimension 3 expected !"); + } + case NORM_HEXA27: + { + if(spaceDim==3) + return new DiameterCalulatorHEXA27; + else + throw Exception("CellModel::buildInstanceOfDiameterCalulator : For HEXA27 space dimension 3 expected !"); + } + case NORM_PENTA6: + { + if(spaceDim==3) + return new DiameterCalulatorPENTA6; + else + throw Exception("CellModel::buildInstanceOfDiameterCalulator : For PENTA6 space dimension 3 expected !"); + } + case NORM_PENTA15: + { + if(spaceDim==3) + return new DiameterCalulatorPENTA15; + else + throw Exception("CellModel::buildInstanceOfDiameterCalulator : For PENTA15 space dimension 3 expected !"); + } + case NORM_PYRA5: + { + if(spaceDim==3) + return new DiameterCalulatorPYRA5; + else + throw Exception("CellModel::buildInstanceOfDiameterCalulator : For PYRA5 space dimension 3 expected !"); + } + case NORM_PYRA13: + { + if(spaceDim==3) + return new DiameterCalulatorPYRA13; + else + throw Exception("CellModel::buildInstanceOfDiameterCalulator : For PYRA13 space dimension 3 expected !"); + } + default: + throw Exception("CellModel::buildInstanceOfDiameterCalulator : implemented only for TRI3, QUAD4, TETRA4, HEXA8, PENTA6, PYRA5 !"); + } + } +} diff --git a/src/medtool/src/INTERP_KERNEL/CellModel.hxx b/src/medtool/src/INTERP_KERNEL/CellModel.hxx new file mode 100644 index 000000000..d1b5e1d95 --- /dev/null +++ b/src/medtool/src/INTERP_KERNEL/CellModel.hxx @@ -0,0 +1,104 @@ +// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 +// 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 __CELLMODEL_INTERP_KERNEL_HXX__ +#define __CELLMODEL_INTERP_KERNEL_HXX__ + +#include "INTERPKERNELDefines.hxx" + +#include "NormalizedUnstructuredMesh.hxx" + +#include <map> + +namespace INTERP_KERNEL +{ + class DiameterCalculator; + + /*! + * This class descibes all static elements (different from polygons and polyhedron) 3D, 2D and 1D. + */ + class CellModel + { + 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(); + public: + INTERPKERNEL_EXPORT static const CellModel& GetCellModel(NormalizedCellType type); + INTERPKERNEL_EXPORT NormalizedCellType getEnum() const { return _type; } + INTERPKERNEL_EXPORT const char *getRepr() const; + INTERPKERNEL_EXPORT bool isExtruded() const { return _is_extruded; } + INTERPKERNEL_EXPORT bool isDynamic() const { return _dyn; } + INTERPKERNEL_EXPORT bool isQuadratic() const { return _quadratic; } + INTERPKERNEL_EXPORT unsigned getDimension() const { return _dim; } + INTERPKERNEL_EXPORT bool isCompatibleWith(NormalizedCellType type) const; + INTERPKERNEL_EXPORT bool isSimplex() const { return _is_simplex; } + //! sonId is in C format. + INTERPKERNEL_EXPORT const unsigned *getNodesConstituentTheSon(unsigned sonId) const { return _sons_con[sonId]; } + INTERPKERNEL_EXPORT bool getOrientationStatus(unsigned lgth, const int *conn1, const int *conn2) const; + 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; + INTERPKERNEL_EXPORT void changeOrientationOf2D(int *nodalConn, unsigned int sz) const; + INTERPKERNEL_EXPORT void changeOrientationOf1D(int *nodalConn, unsigned int sz) const; + INTERPKERNEL_EXPORT DiameterCalculator *buildInstanceOfDiameterCalulator(int spaceDim) const; + private: + bool _dyn; + bool _quadratic; + bool _is_simplex; + bool _is_extruded; + 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<NormalizedCellType,CellModel> _map_of_unique_instance; + static const char *CELL_TYPES_REPR[]; + }; +} + +#endif diff --git a/src/medtool/src/INTERP_KERNEL/ConvexIntersector.hxx b/src/medtool/src/INTERP_KERNEL/ConvexIntersector.hxx new file mode 100644 index 000000000..53966f530 --- /dev/null +++ b/src/medtool/src/INTERP_KERNEL/ConvexIntersector.hxx @@ -0,0 +1,54 @@ +// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 +// 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 __CONVEXINTERSECTOR_HXX__ +#define __CONVEXINTERSECTOR_HXX__ + +#include "PlanarIntersectorP0P0.hxx" +#include "PlanarIntersectorP0P1.hxx" +#include "PlanarIntersectorP1P0.hxx" +#include "PlanarIntersectorP1P1.hxx" +#include "PlanarIntersectorP1P0Bary.hxx" +#include "PlanarIntersectorP0P1Bary.hxx" + +namespace INTERP_KERNEL +{ + template<class MyMeshType, class MyMatrix, template <class MeshType, class TheMatrix, class ThisIntersector> class InterpType > + class ConvexIntersector : public InterpType<MyMeshType,MyMatrix,ConvexIntersector<MyMeshType,MyMatrix,InterpType> > + { + public: + static const int SPACEDIM=MyMeshType::MY_SPACEDIM; + static const int MESHDIM=MyMeshType::MY_MESHDIM; + typedef typename MyMeshType::MyConnType ConnType; + static const NumberingPolicy numPol=MyMeshType::My_numPol; + public: + ConvexIntersector(const MyMeshType& meshT, const MyMeshType& meshS, + double dimCaracteristic, double precision, double md3DSurf, double minDot3DSurf, double medianPlane, + bool doRotate, int orientation, int printLevel); + double intersectGeometry(ConnType icellT, ConnType icellS, ConnType nbNodesT, ConnType nbNodesS); + double intersectGeometryWithQuadrangle(const double *quadrangle, const std::vector<double>& sourceCoords, bool isSourceQuad); + double intersectGeometryGeneral(const std::vector<double>& targetCoords, const std::vector<double>& sourceCoords); + double intersectGeoBary(const std::vector<double>& targetCell, bool targetCellQuadratic, const double *sourceCell, std::vector<double>& res); + private : + double _epsilon; + }; +} + +#endif diff --git a/src/medtool/src/INTERP_KERNEL/ConvexIntersector.txx b/src/medtool/src/INTERP_KERNEL/ConvexIntersector.txx new file mode 100644 index 000000000..9ab59b197 --- /dev/null +++ b/src/medtool/src/INTERP_KERNEL/ConvexIntersector.txx @@ -0,0 +1,195 @@ +// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 +// 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 __CONVEXINTERSECTOR_TXX__ +#define __CONVEXINTERSECTOR_TXX__ + +#include "ConvexIntersector.hxx" +#include "PlanarIntersectorP0P0.txx" +#include "PlanarIntersectorP0P1.txx" +#include "PlanarIntersectorP1P0.txx" +#include "PlanarIntersectorP1P1.txx" +#include "PlanarIntersectorP1P0Bary.txx" +#include "PlanarIntersectorP0P1Bary.txx" + +#include "PolygonAlgorithms.txx" + +#include <iostream> + +#define CONVINTERSECTOR_TEMPLATE template<class MyMeshType, class MyMatrix, template <class MeshType, class TheMatrix, class ThisIntersector> class InterpType> +#define CONVEX_INTERSECTOR_ ConvexIntersector<MyMeshType,MyMatrix,InterpType> + +namespace INTERP_KERNEL +{ + CONVINTERSECTOR_TEMPLATE + CONVEX_INTERSECTOR_::ConvexIntersector(const MyMeshType& meshT, const MyMeshType& meshS, + double dimCaracteristic, double precision, double md3DSurf, double minDot3DSurf, + double medianPlane, bool doRotate , int oriantation, int printLevel) + :InterpType<MyMeshType,MyMatrix,CONVEX_INTERSECTOR_ >(meshT,meshS,dimCaracteristic, precision, md3DSurf, minDot3DSurf, medianPlane, doRotate, oriantation, printLevel), + _epsilon(precision*dimCaracteristic) + { + if(PlanarIntersector<MyMeshType,MyMatrix>::_print_level >= 1) + { + std::cout << " - intersection type = convex " << std::endl; + if(SPACEDIM==3){ + if(PlanarIntersector<MyMeshType,MyMatrix>::_do_rotate) std::cout << " _do_rotate = true" << std::endl; + else std::cout << " _do_rotate = false" << std::endl; + } + } + } + + CONVINTERSECTOR_TEMPLATE + double CONVEX_INTERSECTOR_::intersectGeometry(ConnType icellT, ConnType icellS, + ConnType nbNodesT, ConnType nbNodesS) + { + double result = 0; + int orientation = 1; + + /*** Obtain the coordinates of T and S ***/ + std::vector<double> CoordsT; + std::vector<double> CoordsS; + PlanarIntersector<MyMeshType,MyMatrix>::getRealCoordinates(icellT,icellS,nbNodesT,nbNodesS,CoordsT,CoordsS,orientation); + /*** Compute the intersection area ***/ + INTERP_KERNEL::PolygonAlgorithms<SPACEDIM> P(_epsilon, PlanarIntersector<MyMeshType,MyMatrix>::_precision); + std::deque<double> inter = P.intersectConvexPolygons(&CoordsT[0], &CoordsS[0], + CoordsT.size()/SPACEDIM, CoordsS.size()/SPACEDIM); + double area[SPACEDIM]; + int nb_inter =((int)inter.size())/SPACEDIM; + for(int i = 1; i<nb_inter-1; i++) + { + INTERP_KERNEL::crossprod<SPACEDIM>(&inter[0],&inter[SPACEDIM*i],&inter[SPACEDIM*(i+1)],area); + result +=0.5*norm<SPACEDIM>(area); + } + + //DEBUG prints + if(PlanarIntersector<MyMeshType,MyMatrix>::_print_level >= 3) + { + std::cout << std::endl << "Number of nodes of the intersection = "<< nb_inter << std::endl; + for(int i=0; i< nb_inter; i++) + {for (int idim=0; idim<SPACEDIM; idim++) std::cout << inter[SPACEDIM*i+idim]<< " "; std::cout << std::endl;} + std::cout << std::endl <<"Intersection area = " << result << std::endl; + } + + return orientation*result; + } + + CONVINTERSECTOR_TEMPLATE + double CONVEX_INTERSECTOR_::intersectGeometryWithQuadrangle(const double * quadrangle, + const std::vector<double>& sourceCoords, + bool isSourceQuad) + { + double result = 0; + int nbOfNodesS=sourceCoords.size()/SPACEDIM; + + /*** Compute the intersection area ***/ + INTERP_KERNEL::PolygonAlgorithms<SPACEDIM> P(_epsilon, PlanarIntersector<MyMeshType,MyMatrix>::_precision); + std::deque<double> inter = P.intersectConvexPolygons(quadrangle, &sourceCoords[0], + 4, nbOfNodesS); + double area[SPACEDIM]; + int nb_inter =((int)inter.size())/SPACEDIM; + for(int i = 1; i<nb_inter-1; i++) + { + INTERP_KERNEL::crossprod<SPACEDIM>(&inter[0],&inter[SPACEDIM*i],&inter[SPACEDIM*(i+1)],area); + result +=0.5*norm<SPACEDIM>(area); + } + + //DEBUG prints + if(PlanarIntersector<MyMeshType,MyMatrix>::_print_level >= 3) + { + std::cout << std::endl << "Number of nodes of the intersection = "<< nb_inter << std::endl; + for(int i=0; i< nb_inter; i++) + {for (int idim=0; idim<SPACEDIM; idim++) std::cout << inter[SPACEDIM*i+idim]<< " "; std::cout << std::endl;} + std::cout << std::endl <<"Intersection area = " << result << std::endl; + } + + return result; + } + + CONVINTERSECTOR_TEMPLATE + double CONVEX_INTERSECTOR_::intersectGeometryGeneral(const std::vector<double>& targetCoords, + const std::vector<double>& sourceCoords) + { + double result = 0; + int nbOfNodesS=sourceCoords.size()/SPACEDIM; + int nbOfNodesT=targetCoords.size()/SPACEDIM; + /*** Compute the intersection area ***/ + INTERP_KERNEL::PolygonAlgorithms<SPACEDIM> P(_epsilon, PlanarIntersector<MyMeshType,MyMatrix>::_precision); + std::deque<double> inter = P.intersectConvexPolygons(&targetCoords[0], &sourceCoords[0], + nbOfNodesT, nbOfNodesS); + double area[SPACEDIM]; + int nb_inter =((int)inter.size())/SPACEDIM; + for(int i = 1; i<nb_inter-1; i++) + { + INTERP_KERNEL::crossprod<SPACEDIM>(&inter[0],&inter[SPACEDIM*i],&inter[SPACEDIM*(i+1)],area); + result +=0.5*norm<SPACEDIM>(area); + } + return result; + } + + //================================================================================ + /*! + * \brief Intersect a triangle and a polygon for P1P0 barycentric algorithm + * \param targetCell - list of coordinates of target polygon in full interlace + * \param targetCellQuadratic - specifies if target polygon is quadratic or not + * \param sourceTria - list of coordinates of source triangle + * \param res - coefficients a,b and c associated to nodes of sourceTria + */ + //================================================================================ + + CONVINTERSECTOR_TEMPLATE + double CONVEX_INTERSECTOR_::intersectGeoBary(const std::vector<double>& targetCell, + bool targetCellQuadratic, + const double * sourceTria, + std::vector<double>& res) + { + double area = 0; + double barycenter[SPACEDIM] = {0., 0.}; + int nbOfNodesT=targetCell.size()/SPACEDIM; + + /*** Compute the intersection area ***/ + INTERP_KERNEL::PolygonAlgorithms<SPACEDIM> P(_epsilon, PlanarIntersector<MyMeshType,MyMatrix>::_precision); + std::deque<double> inter = P.intersectConvexPolygons(sourceTria, &targetCell[0], 3, nbOfNodesT); + double cross[SPACEDIM]; + int nb_inter =((int)inter.size())/SPACEDIM; + for(int i = 1; i<nb_inter-1; i++) + { + INTERP_KERNEL::crossprod<SPACEDIM>(&inter[0],&inter[SPACEDIM*i],&inter[SPACEDIM*(i+1)],cross); + area += 0.5*norm<SPACEDIM>(cross); + barycenter[0] += inter[SPACEDIM*i]; + barycenter[1] += inter[SPACEDIM*i+1]; + } + if ( area > std::numeric_limits<double>::min() ) + { + barycenter[0] = ( barycenter[0] + inter[0] + inter[SPACEDIM*(nb_inter-1)] ) / nb_inter; + barycenter[1] = ( barycenter[1] + inter[1] + inter[SPACEDIM*(nb_inter-1)+1]) / nb_inter; + res.resize(3); + barycentric_coords<2>( sourceTria, &barycenter[0], &res[0]); + res[0] *= area; + res[1] *= area; + res[2] *= area; + } + else + { + area = 0; + } + return area; + } +} + +#endif diff --git a/src/medtool/src/INTERP_KERNEL/CurveIntersector.hxx b/src/medtool/src/INTERP_KERNEL/CurveIntersector.hxx new file mode 100644 index 000000000..e1c3e69ce --- /dev/null +++ b/src/medtool/src/INTERP_KERNEL/CurveIntersector.hxx @@ -0,0 +1,79 @@ +// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 +// 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 __CURVEINTERSECTOR_HXX__ +#define __CURVEINTERSECTOR_HXX__ + +#include "TargetIntersector.hxx" +#include "NormalizedUnstructuredMesh.hxx" + +namespace INTERP_KERNEL +{ + template<class MyMeshType, class MyMatrix> + class CurveIntersector : public TargetIntersector<MyMeshType,MyMatrix> + { + public: + static const int SPACEDIM=MyMeshType::MY_SPACEDIM; + static const int MESHDIM=MyMeshType::MY_MESHDIM; + typedef typename MyMeshType::MyConnType ConnType; + static const NumberingPolicy numPol=MyMeshType::My_numPol; + public: + CurveIntersector(const MyMeshType& meshT, const MyMeshType& meshS, + double precision, double adjustmentEpsAbs, double medianLine, int printLevel); + virtual ~CurveIntersector(); + void createBoundingBoxes(const MyMeshType& mesh, std::vector<double>& bbox); + void adjustBoundingBoxes(std::vector<double>& bbox, double adjustmentEpsAbs); + static void getElemBB(double* bb, const MyMeshType& mesh, ConnType iP, ConnType nb_nodes); + static bool ComputeBaryCoordsOf(double startOfSeg, double endOfSeg, double pt, double& startPos, double& endPos); + protected : + bool projectionThis(const double *coordsT, const double *coordsS, double& xs0, double& xs1, double& xt0, double& xt1) const; + bool getRealTargetCoordinates(ConnType icellT, std::vector<double>& coordsT) const; + typename MyMeshType::MyConnType getNodeIdOfTargetCellAt(ConnType icellT, ConnType nodeIdInCellT) const; + bool getRealSourceCoordinates(ConnType icellS, std::vector<double>& coordsS) const; + typename MyMeshType::MyConnType getNodeIdOfSourceCellAt(ConnType icellT, ConnType nodeIdInCellT) const; + double intersectSegments(const double *coordsT, const double *coordsS) const; + double intersectSegmentsInternal(const double *coordsT, const double *coordsS, double& xs0, double& xs1, double& xt0, double& xt1) const; + + struct TDualSegment + { + std::vector<double> _coords; + int _nodeId; // in mesh mode + }; + static void getDualSegments(ConnType icell, + const MyMeshType& mesh, + std::vector<TDualSegment>& segments); + + protected: + const ConnType *_connectT; + const ConnType *_connectS; + const double *_coordsT; + const double *_coordsS; + const ConnType *_connIndexT; + const ConnType *_connIndexS; + const MyMeshType& _meshT; + const MyMeshType& _meshS; + double _tolerance; + double _precision; + double _median_line; + int _print_level; + }; +} + +#endif diff --git a/src/medtool/src/INTERP_KERNEL/CurveIntersector.txx b/src/medtool/src/INTERP_KERNEL/CurveIntersector.txx new file mode 100644 index 000000000..c311605f7 --- /dev/null +++ b/src/medtool/src/INTERP_KERNEL/CurveIntersector.txx @@ -0,0 +1,430 @@ +// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 +// 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 __CURVEINTERSECTOR_TXX__ +#define __CURVEINTERSECTOR_TXX__ + +#include "CurveIntersector.hxx" +#include "InterpolationUtils.hxx" + +#include <limits> + +namespace INTERP_KERNEL +{ + template<class MyMeshType, class MyMatrix> + CurveIntersector<MyMeshType,MyMatrix> + ::CurveIntersector(const MyMeshType& meshT, const MyMeshType& meshS, + double precision, double tolerance, double medianLine, int printLevel): + _meshT(meshT), + _meshS(meshS), + _tolerance(tolerance), + _precision(precision), + _median_line(medianLine), + _print_level(printLevel) + { + if ( SPACEDIM != 1 && SPACEDIM != 2 ) + throw Exception("CurveIntersector(): space dimension of mesh must be 1 or 2"); + if ( MESHDIM != 1 ) + throw Exception("CurveIntersector(): mesh dimension must be 1"); + + _connectT = meshT.getConnectivityPtr(); + _connectS = meshS.getConnectivityPtr(); + _connIndexT = meshT.getConnectivityIndexPtr(); + _connIndexS = meshS.getConnectivityIndexPtr(); + _coordsT = meshT.getCoordinatesPtr(); + _coordsS = meshS.getCoordinatesPtr(); + } + + template<class MyMeshType, class MyMatrix> + CurveIntersector<MyMeshType,MyMatrix>::~CurveIntersector() + { + } + + //================================================================================ + /*! + \brief creates the bounding boxes for all the cells of mesh \a mesh + + \param mesh structure pointing to the mesh + \param bbox vector containing the bounding boxes + */ + //================================================================================ + + template<class MyMeshType, class MyMatrix> + void CurveIntersector<MyMeshType,MyMatrix>::createBoundingBoxes (const MyMeshType& mesh, + std::vector<double>& bbox) + { + long nbelems = mesh.getNumberOfElements(); + bbox.resize(2*SPACEDIM* nbelems); + const double* coords = mesh.getCoordinatesPtr(); + const ConnType* conn = mesh.getConnectivityPtr(); + const ConnType* conn_index = mesh.getConnectivityIndexPtr(); + int ibox=0; + for(long icell=0; icell<nbelems; icell++) + { + int nb_nodes_per_elem = conn_index[icell+1]-conn_index[icell]; + //initializing bounding box limits + for(int idim=0; idim<SPACEDIM; idim++) + { + bbox[2*SPACEDIM*ibox+2*idim] = std::numeric_limits<double>::max(); + bbox[2*SPACEDIM*ibox+2*idim+1] = -std::numeric_limits<double>::max(); + } + //updating the bounding box with each node of the element + for (int j=0; j<nb_nodes_per_elem; j++) + { + const double* coord_node = coords + + SPACEDIM*OTT<ConnType,numPol> + ::coo2C(conn[OTT<ConnType,numPol>::conn2C(conn_index[icell]+j)]); + for(int idim=0; idim<SPACEDIM; idim++) + { + double x = *(coord_node+idim); + bbox[ibox*2*SPACEDIM + 2*idim] = + ( bbox[ibox*2*SPACEDIM + 2*idim] < x ) ? bbox[ibox*2*SPACEDIM + 2*idim] : x; + bbox[ibox*2*SPACEDIM + 2*idim+1] = + ( bbox[ibox*2*SPACEDIM + 2*idim+1] > x ) ? bbox[ibox*2*SPACEDIM + 2*idim+1] : x; + } + } + ibox++; + } + } + + /*! + Computes the bouding box of a given element. iP in numPol mode. + */ + template<class MyMeshType, class MyMatrix> + void CurveIntersector<MyMeshType,MyMatrix>::getElemBB (double* bb, + const MyMeshType& mesh, + ConnType iP, + ConnType nb_nodes) + { + const double* coords = mesh.getCoordinatesPtr(); + const ConnType* conn_index = mesh.getConnectivityIndexPtr(); + const ConnType* conn = mesh.getConnectivityPtr(); + //initializing bounding box limits + for(int idim=0; idim<SPACEDIM; idim++) + { + bb[2*idim ] = std::numeric_limits<double>::max(); + bb[2*idim+1] = -std::numeric_limits<double>::max(); + } + + for (ConnType i=0; i<nb_nodes; i++) + { + //MN: iP= cell index, not node index, use of connectivity array ? + const double* coord_node = coords + + SPACEDIM*(OTT<ConnType,numPol>::coo2C(conn[OTT<ConnType,numPol>::conn2C(conn_index[OTT<ConnType,numPol>::ind2C(iP)]+i)])); + for(int idim=0; idim<SPACEDIM; idim++) + { + double x = *(coord_node+idim); + bb[2*idim ] = (x<bb[2*idim ]) ? x : bb[2*idim ]; + bb[2*idim+1] = (x>bb[2*idim+1]) ? x : bb[2*idim+1]; + } + } + } + + /*! + * \param [in] startOfSeg - input coming from intersectSegments or intersectSegmentsInternal + * \param [in] endOfSeg - input coming from intersectSegments or intersectSegmentsInternal. Assume that endOfSeg>startOfSeg. + * \param [in] pt - position of point that the method computes the bary coords for. + */ + template<class MyMeshType, class MyMatrix> + bool CurveIntersector<MyMeshType,MyMatrix>::ComputeBaryCoordsOf(double startOfSeg, double endOfSeg, double pt, double& startPos, double& endPos) + { + double deno(endOfSeg-startOfSeg); + startPos=(endOfSeg-pt)/deno; + endPos=1.-startPos; + return startPos>=0. && endPos>=0.; + } + + /*! Readjusts a set of bounding boxes so that they are extended + in all dimensions for avoiding missing interesting intersections + + \param bbox vector containing the bounding boxes + */ + template<class MyMeshType, class MyMatrix> + void CurveIntersector<MyMeshType,MyMatrix>::adjustBoundingBoxes (std::vector<double>& bbox, + double adjustmentEpsAbs) + { + long size = bbox.size()/(2*SPACEDIM); + for (int i=0; i<size; i++) + { + for(int idim=0; idim<SPACEDIM; idim++) + { + bbox[i*2*SPACEDIM+2*idim ] -= adjustmentEpsAbs; + bbox[i*2*SPACEDIM+2*idim+1] += adjustmentEpsAbs; + } + } + } + + /*! + * @param icellT id in target mesh in format of MyMeshType. + * @param coordsT output val that stores coordinates of the target cell + * automatically resized to the right length. + * @return true if segment is quadratic and in this case coordinates of medium node + * are placed in the middle of coordsT + */ + template<class MyMeshType, class MyMatrix> + bool CurveIntersector<MyMeshType,MyMatrix>::getRealTargetCoordinates(ConnType icellT, std::vector<double>& coordsT) const + { + int nbNodesT(_connIndexT[OTT<ConnType,numPol>::ind2C(icellT)+1] - _connIndexT[OTT<ConnType,numPol>::ind2C(icellT)]); + coordsT.resize(SPACEDIM*nbNodesT); + for (ConnType iT=0; iT<nbNodesT; iT++) + { + for(int idim=0; idim<SPACEDIM; idim++) + { + coordsT[SPACEDIM*iT+idim] = + _coordsT[SPACEDIM*OTT<ConnType,numPol>::coo2C(_connectT[OTT<ConnType,numPol>::conn2C(_connIndexT[OTT<ConnType,numPol>::ind2C(icellT)]+iT)])+idim]; + } + } + if ( nbNodesT > 2 ) + { + for(int idim=0; idim<SPACEDIM; idim++) + std::swap( coordsT[SPACEDIM*1+idim], coordsT[SPACEDIM*2+idim]); + return true; + } + return false; + } + + template<class MyMeshType, class MyMatrix> + typename MyMeshType::MyConnType CurveIntersector<MyMeshType,MyMatrix>::getNodeIdOfTargetCellAt(ConnType icellT, ConnType nodeIdInCellT) const + { + int nbNodesT(_connIndexT[OTT<ConnType,numPol>::ind2C(icellT)+1] - _connIndexT[OTT<ConnType,numPol>::ind2C(icellT)]); + if(nodeIdInCellT>=0 && nodeIdInCellT<nbNodesT) + return OTT<ConnType,numPol>::coo2C(_connectT[OTT<ConnType,numPol>::conn2C(_connIndexT[OTT<ConnType,numPol>::ind2C(icellT)]+nodeIdInCellT)]); + else + throw Exception("getNodeIdOfTargetCellAt : error in nodeId in cell"); + } + + /*! + * @param icellS id in source mesh in format of MyMeshType. + * @param coordsS output val that stores coordinates of the source cell automatically resized to the right length. + * @return true if segment is quadratic and in this case coordinates of medium node + * are placed in the middle of coordsS + */ + template<class MyMeshType, class MyMatrix> + bool CurveIntersector<MyMeshType,MyMatrix>::getRealSourceCoordinates(ConnType icellS, std::vector<double>& coordsS) const + { + int nbNodesS = _connIndexS[OTT<ConnType,numPol>::ind2C(icellS)+1] - _connIndexS[OTT<ConnType,numPol>::ind2C(icellS)]; + coordsS.resize(SPACEDIM*nbNodesS); + for(ConnType iS=0; iS<nbNodesS; iS++) + { + for(int idim=0; idim<SPACEDIM; idim++) + { + coordsS[SPACEDIM*iS+idim] = + _coordsS[SPACEDIM*OTT<ConnType,numPol>::coo2C(_connectS[OTT<ConnType,numPol>::conn2C(_connIndexS[OTT<ConnType,numPol>::ind2C(icellS)]+iS)])+idim]; + } + } + if ( nbNodesS > 2 ) + { + for(int idim=0; idim<SPACEDIM; idim++) + std::swap( coordsS[SPACEDIM*1+idim], coordsS[SPACEDIM*2+idim]); + return true; + } + return false; + } + + template<class MyMeshType, class MyMatrix> + typename MyMeshType::MyConnType CurveIntersector<MyMeshType,MyMatrix>::getNodeIdOfSourceCellAt(ConnType icellS, ConnType nodeIdInCellS) const + { + int nbNodesS(_connIndexS[OTT<ConnType,numPol>::ind2C(icellS)+1] - _connIndexS[OTT<ConnType,numPol>::ind2C(icellS)]); + if(nodeIdInCellS>=0 && nodeIdInCellS<nbNodesS) + return OTT<ConnType,numPol>::coo2C(_connectS[OTT<ConnType,numPol>::conn2C(_connIndexS[OTT<ConnType,numPol>::ind2C(icellS)]+nodeIdInCellS)]); + else + throw Exception("getNodeIdOfSourceCellAt : error in nodeId in cell"); + } + + /*! + * \brief Return dual segments of given segment + * \param icell - given segment in C mode + * \param mesh - mesh + * \param segments - dual segments + */ + template<class MyMeshType, class MyMatrix> + void CurveIntersector<MyMeshType,MyMatrix>::getDualSegments(ConnType icell, + const MyMeshType& mesh, + std::vector<TDualSegment>& segments) + { + // get coordinates of cell nodes + int nbNodes; + std::vector<double> ncoords; + std::vector<int> nodeIds; + { + const ConnType *connect = mesh.getConnectivityPtr(); + const ConnType *connIndex = mesh.getConnectivityIndexPtr(); + const double *coords = mesh.getCoordinatesPtr(); + + nbNodes = connIndex[icell+1] - connIndex[icell]; + + ncoords.resize(SPACEDIM*nbNodes); + nodeIds.resize(nbNodes); + + for(int i=0; i<nbNodes; i++) + for(int idim=0; idim<SPACEDIM; idim++) + { + nodeIds[i] = connect[OTT<ConnType,numPol>::conn2C(connIndex[OTT<ConnType,numPol>::ind2C(icell)]+i)]; + ncoords[SPACEDIM*i+idim] = coords[SPACEDIM*OTT<ConnType,numPol>::coo2C(nodeIds[i])+idim]; + } + if ( nbNodes > 2 ) // quadratic segment, put medium node in the middle + { + for(int idim=0; idim<SPACEDIM; idim++) + std::swap( ncoords[SPACEDIM*1+idim], ncoords[SPACEDIM*2+idim]); + std::swap( nodeIds[1], nodeIds[2] ); + } + } + + // fill segments + segments.clear(); + segments.reserve( 2*nbNodes ); + for(int i=0; i<nbNodes-1; i++) + { + segments.push_back(TDualSegment()); + TDualSegment& seg1 = segments.back(); + segments.push_back(TDualSegment()); + TDualSegment& seg2 = segments.back(); + + seg1._nodeId = nodeIds[i]; + seg2._nodeId = nodeIds[i+1]; + + seg1._coords.resize( SPACEDIM * 2 ); + seg2._coords.resize( SPACEDIM * 2 ); + + for(int idim=0; idim<SPACEDIM; idim++) + { + double c1 = ncoords[SPACEDIM*i+idim]; + double c2 = ncoords[SPACEDIM*(i+1)+idim]; + double m = 0.5 * ( c1 + c2 ); + seg1._coords[ idim ] = c1; + seg1._coords[ SPACEDIM + idim ] = m; + seg2._coords[ idim ] = m; + seg2._coords[ SPACEDIM + idim ] = c2; + } + } + } + + template<class MyMeshType, class MyMatrix> + bool CurveIntersector<MyMeshType,MyMatrix>::projectionThis(const double *coordsT, const double *coordsS, + double& xs0, double& xs1, double& xt0, double& xt1) const + { + xt0 = coordsT[0]; xt1 = coordsT[1]; + xs0 = coordsS[0]; xs1 = coordsS[1]; + if ( SPACEDIM == 2 ) + { + // Pass 2D->1D + + enum { X=0, Y }; + + // check if two segments overlap in 2D within tolerance + + const double* t0 = coordsT; + const double* t1 = coordsT + 2; + double t01[2] = { t1[X]-t0[X], t1[Y]-t0[Y] }; // tgt segment direction + double tSize = sqrt( t01[X]*t01[X] + t01[Y]*t01[Y] ); // tgt segment size + if ( tSize < _precision ) + return false; // degenerated segment + t01[X] /= tSize, t01[Y] /= tSize; // normalize t01 + + const double* s0 = coordsS; + const double* s1 = coordsS + 2; + double t0s0[2] = { s0[X]-t0[X], s0[Y]-t0[Y] }; + double t0s1[2] = { s1[X]-t0[X], s1[Y]-t0[Y] }; + double nt01_x_t0s0 = t0s0[X] * t01[Y] - t0s0[Y] * t01[X]; // t0s0 dot norm of t01 + double nt01_x_t0s1 = t0s1[X] * t01[Y] - t0s1[Y] * t01[X]; // t0s1 dot norm of t01 + double dist_ts0 = fabs( nt01_x_t0s0 ); // dist from tgt seg to s0 + double dist_ts1 = fabs( nt01_x_t0s1 ); // dist from tgt seg to s1 + bool s0_out_of_tol = ( dist_ts0 > _tolerance ); + bool s1_out_of_tol = ( dist_ts1 > _tolerance ); + if ( nt01_x_t0s0 * nt01_x_t0s1 > 0 && ( s0_out_of_tol || s1_out_of_tol )) + return false; // tgt segment is to far from src segment + + double S0[2] = { s0[X], s0[Y] }; + double S1[2] = { s1[X], s1[Y] }; + if ( s0_out_of_tol ) // put s0 within tolerance + { + double t = _tolerance * nt01_x_t0s0 / dist_ts0; // signed tolerance + double r = ( nt01_x_t0s0 - t ) / ( nt01_x_t0s0 - nt01_x_t0s1 ); + S0[X] = s0[X] * ( 1.-r ) + s1[X] * r; + S0[Y] = s0[Y] * ( 1.-r ) + s1[Y] * r; + } + if ( s1_out_of_tol ) // put s1 within tolerance + { + double t = _tolerance * nt01_x_t0s1 / dist_ts1; // signed tolerance + double r = ( nt01_x_t0s1 - t ) / ( nt01_x_t0s1 - nt01_x_t0s0 ); + S1[X] = s1[X] * ( 1.-r ) + s0[X] * r; + S1[Y] = s1[Y] * ( 1.-r ) + s0[Y] * r; + } + + // project tgt and src segments to median line + + double s01[2] = { S1[X]-S0[X], S1[Y]-S0[Y] }; // src segment direction + double sSize = sqrt( s01[X]*s01[X] + s01[Y]*s01[Y] ); // src segment size + if ( sSize < _precision ) + return false; // degenerated segment + s01[X] /= sSize, s01[Y] /= sSize; // normalize s01 + + // make t01 and s01 codirected + double t01_x_s01 = t01[X] * s01[X] + t01[Y] * s01[Y]; // t01 dot s01 + if ( t01_x_s01 < 0 ) + s01[X] = -s01[X], s01[Y] = -s01[Y]; + + double medianDir[2] = { + t01[X] * ( 1.-_median_line) + s01[X] * _median_line, + t01[Y] * ( 1.-_median_line) + s01[Y] * _median_line + }; + double medianSize = sqrt( medianDir[X]*medianDir[X] + medianDir[Y]*medianDir[Y] ); + if ( medianSize < std::numeric_limits<double>::min() ) + return false; // strange... + medianDir[X] /= medianSize, medianDir[Y] /= medianSize; + + xt0 = t0[X] * medianDir[X] + t0[Y] * medianDir[Y]; + xt1 = t1[X] * medianDir[X] + t1[Y] * medianDir[Y]; + xs0 = S0[X] * medianDir[X] + S0[Y] * medianDir[Y]; + xs1 = S1[X] * medianDir[X] + S1[Y] * medianDir[Y]; + + } // if ( SPACEDIM == 2 ) + return true; + } + + /*! + * \brief Return length of intersection of two segments + */ + template<class MyMeshType, class MyMatrix> + double CurveIntersector<MyMeshType,MyMatrix>::intersectSegmentsInternal(const double *coordsT, const double *coordsS, double& xs0, double& xs1, double& xt0, double& xt1) const + { + if(!projectionThis(coordsT,coordsS,xs0,xs1,xt0,xt1)) + return 0.; + + if ( xt0 > xt1 ) std::swap( xt0, xt1 ); + if ( xs0 > xs1 ) std::swap( xs0, xs1 ); + + double x0 = std::max( xt0, xs0 ); + double x1 = std::min( xt1, xs1 ); + return ( x0 < x1 ) ? ( x1 - x0 ) : 0.; + } + + /*! + * \brief Return length of intersection of two segments + */ + template<class MyMeshType, class MyMatrix> + double CurveIntersector<MyMeshType,MyMatrix>::intersectSegments(const double *coordsT, const double *coordsS) const + { + double xs0,xs1,xt0,xt1; + return intersectSegmentsInternal(coordsT,coordsS,xs0,xs1,xt0,xt1); + } + +} + +#endif diff --git a/src/medtool/src/INTERP_KERNEL/CurveIntersectorP0P0.hxx b/src/medtool/src/INTERP_KERNEL/CurveIntersectorP0P0.hxx new file mode 100644 index 000000000..eabf428f6 --- /dev/null +++ b/src/medtool/src/INTERP_KERNEL/CurveIntersectorP0P0.hxx @@ -0,0 +1,48 @@ +// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 +// 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 __CURVEINTERSECTORP0P0_HXX__ +#define __CURVEINTERSECTORP0P0_HXX__ + +#include "CurveIntersector.hxx" + +namespace INTERP_KERNEL +{ + template<class MyMeshType, class MyMatrix> + class CurveIntersectorP0P0 : public CurveIntersector<MyMeshType,MyMatrix> + { + public: + static const int SPACEDIM=MyMeshType::MY_SPACEDIM; + static const int MESHDIM=MyMeshType::MY_MESHDIM; + typedef typename MyMeshType::MyConnType ConnType; + static const NumberingPolicy numPol=MyMeshType::My_numPol; + + CurveIntersectorP0P0(const MyMeshType& meshT, const MyMeshType& meshS, + double precision, double tolerance, + double medianLine, int printLevel); + public: + int getNumberOfRowsOfResMatrix() const; + int getNumberOfColsOfResMatrix() const; + void intersectCells(ConnType icellT, + const std::vector<ConnType>& icellsS, MyMatrix& res); + }; +} + +#endif diff --git a/src/medtool/src/INTERP_KERNEL/CurveIntersectorP0P0.txx b/src/medtool/src/INTERP_KERNEL/CurveIntersectorP0P0.txx new file mode 100644 index 000000000..61c7fd60b --- /dev/null +++ b/src/medtool/src/INTERP_KERNEL/CurveIntersectorP0P0.txx @@ -0,0 +1,79 @@ +// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 +// 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 __CURVEINTERSECTORP0P0_TXX__ +#define __CURVEINTERSECTORP0P0_TXX__ + +#include "CurveIntersectorP0P0.hxx" +#include "CurveIntersector.txx" + +#define BASE_INTERSECTOR CurveIntersector<MyMeshType,MyMatrix> + +namespace INTERP_KERNEL +{ + template<class MyMeshType, class MyMatrix> + CurveIntersectorP0P0<MyMeshType,MyMatrix> + ::CurveIntersectorP0P0(const MyMeshType& meshT, const MyMeshType& meshS, + double precision, double tolerance, + double medianLine, int printLevel): + BASE_INTERSECTOR(meshT, meshS, precision, tolerance, medianLine, printLevel) + { + } + + template<class MyMeshType, class MyMatrix> + int CurveIntersectorP0P0<MyMeshType,MyMatrix> + ::getNumberOfRowsOfResMatrix() const + { + return BASE_INTERSECTOR::_meshT.getNumberOfElements(); + } + + template<class MyMeshType, class MyMatrix> + int CurveIntersectorP0P0<MyMeshType,MyMatrix> + ::getNumberOfColsOfResMatrix() const + { + return BASE_INTERSECTOR::_meshS.getNumberOfElements(); + } + + template<class MyMeshType, class MyMatrix> + void CurveIntersectorP0P0<MyMeshType,MyMatrix> + ::intersectCells(ConnType icellT, const std::vector<ConnType>& icellsS, MyMatrix& res) + { + typename MyMatrix::value_type& resRow = res[icellT]; + std::vector<double> coordsT; + int t, nbSegT = 1 + BASE_INTERSECTOR::getRealTargetCoordinates(icellT,coordsT); + for ( t = 0; t < nbSegT; ++t ) + for(typename std::vector<ConnType>::const_iterator + iter=icellsS.begin(); iter!=icellsS.end(); iter++) + { + int iS = *iter; + std::vector<double> coordsS; + int s, nbSegS = 1 + BASE_INTERSECTOR::getRealSourceCoordinates(iS,coordsS); + for ( s = 0; s < nbSegS; ++s ) + { + double surf = BASE_INTERSECTOR::intersectSegments(&coordsT[0] + t*SPACEDIM, + &coordsS[0] + s*SPACEDIM); + if(surf!=0.) + resRow.insert(std::make_pair(OTT<ConnType,numPol>::indFC(iS),surf)); + } + } + } +} +#undef BASE_INTERSECTOR + +#endif diff --git a/src/medtool/src/INTERP_KERNEL/CurveIntersectorP0P1.hxx b/src/medtool/src/INTERP_KERNEL/CurveIntersectorP0P1.hxx new file mode 100644 index 000000000..e8469d0f1 --- /dev/null +++ b/src/medtool/src/INTERP_KERNEL/CurveIntersectorP0P1.hxx @@ -0,0 +1,48 @@ +// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 +// 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 __CURVEINTERSECTORP0P1_HXX__ +#define __CURVEINTERSECTORP0P1_HXX__ + +#include "CurveIntersector.hxx" + +namespace INTERP_KERNEL +{ + template<class MyMeshType, class MyMatrix> + class CurveIntersectorP0P1 : public CurveIntersector<MyMeshType,MyMatrix> + { + public: + static const int SPACEDIM=MyMeshType::MY_SPACEDIM; + static const int MESHDIM=MyMeshType::MY_MESHDIM; + typedef typename MyMeshType::MyConnType ConnType; + static const NumberingPolicy numPol=MyMeshType::My_numPol; + + CurveIntersectorP0P1(const MyMeshType& meshT, const MyMeshType& meshS, + double precision, double tolerance, + double medianLine, int printLevel); + public: + void intersectCells(ConnType icellT, + const std::vector<ConnType>& icellsS, MyMatrix& res); + int getNumberOfRowsOfResMatrix() const; + int getNumberOfColsOfResMatrix() const; + }; +} + +#endif diff --git a/src/medtool/src/INTERP_KERNEL/CurveIntersectorP0P1.txx b/src/medtool/src/INTERP_KERNEL/CurveIntersectorP0P1.txx new file mode 100644 index 000000000..a12e41142 --- /dev/null +++ b/src/medtool/src/INTERP_KERNEL/CurveIntersectorP0P1.txx @@ -0,0 +1,97 @@ +// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 +// 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 __CurveIntersectorP0P1_TXX__ +#define __CurveIntersectorP0P1_TXX__ + +#include "CurveIntersectorP0P1.hxx" +#include "CurveIntersector.txx" + +#define BASE_INTERSECTOR CurveIntersector<MyMeshType,MyMatrix> + +namespace INTERP_KERNEL +{ + template<class MyMeshType, class MyMatrix> + CurveIntersectorP0P1<MyMeshType,MyMatrix> + ::CurveIntersectorP0P1(const MyMeshType& meshT, const MyMeshType& meshS, + double precision, double tolerance, + double medianLine, int printLevel): + BASE_INTERSECTOR(meshT, meshS, precision, tolerance, medianLine, printLevel) + { + } + + template<class MyMeshType, class MyMatrix> + int CurveIntersectorP0P1<MyMeshType,MyMatrix> + ::getNumberOfRowsOfResMatrix() const + { + return BASE_INTERSECTOR::_meshT.getNumberOfNodes(); + } + + template<class MyMeshType, class MyMatrix> + int CurveIntersectorP0P1<MyMeshType,MyMatrix> + ::getNumberOfColsOfResMatrix() const + { + return BASE_INTERSECTOR::_meshS.getNumberOfElements(); + } + + //================================================================================ + /*! + * \brief Project from segments to nodes + */ + //================================================================================ + + template<class MyMeshType, class MyMatrix> + void CurveIntersectorP0P1<MyMeshType,MyMatrix> + ::intersectCells(ConnType icellT, const std::vector<ConnType>& icellsS, MyMatrix& res) + { + std::vector<typename BASE_INTERSECTOR::TDualSegment> segmentsT; + BASE_INTERSECTOR::getDualSegments( icellT, BASE_INTERSECTOR::_meshT, segmentsT); + for ( int t = 0; t < (int)segmentsT.size(); ++t ) + { + typename MyMatrix::value_type& resRow = res[ OTT<ConnType,numPol>::ind2C( segmentsT[t]._nodeId )]; + for(typename std::vector<ConnType>::const_iterator + iter=icellsS.begin(); iter!=icellsS.end(); iter++) + { + int iS = *iter; + std::vector<double> coordsS; + int s, nbSegS = 1 + BASE_INTERSECTOR::getRealSourceCoordinates(iS,coordsS); + for ( s = 0; s < nbSegS; ++s ) + { + double surf = BASE_INTERSECTOR::intersectSegments(&segmentsT[t]._coords[0], + &coordsS[0] + s*SPACEDIM); + if(surf!=0.) + { + typename MyMatrix::value_type::const_iterator iterRes=resRow.find(OTT<ConnType,numPol>::indFC(iS)); + if(iterRes==resRow.end()) + resRow.insert(std::make_pair(OTT<ConnType,numPol>::indFC(iS),surf)); + else + { + surf+=(*iterRes).second; + resRow.erase(OTT<ConnType,numPol>::indFC(iS)); + resRow.insert(std::make_pair(OTT<ConnType,numPol>::indFC(iS),surf)); + } + } + } + } + } + } +} +#undef BASE_INTERSECTOR + +#endif diff --git a/src/medtool/src/INTERP_KERNEL/CurveIntersectorP1P0.hxx b/src/medtool/src/INTERP_KERNEL/CurveIntersectorP1P0.hxx new file mode 100644 index 000000000..f2d78c200 --- /dev/null +++ b/src/medtool/src/INTERP_KERNEL/CurveIntersectorP1P0.hxx @@ -0,0 +1,46 @@ +// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 +// 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 __CURVEINTERSECTORP1P0_HXX__ +#define __CURVEINTERSECTORP1P0_HXX__ + +#include "CurveIntersector.hxx" + +namespace INTERP_KERNEL +{ + template<class MyMeshType, class MyMatrix> + class CurveIntersectorP1P0 : public CurveIntersector<MyMeshType,MyMatrix> + { + public: + static const int SPACEDIM=MyMeshType::MY_SPACEDIM; + static const int MESHDIM=MyMeshType::MY_MESHDIM; + typedef typename MyMeshType::MyConnType ConnType; + static const NumberingPolicy numPol=MyMeshType::My_numPol; + + CurveIntersectorP1P0(const MyMeshType& meshT, const MyMeshType& meshS, + double precision, double tolerance, double medianLine, int printLevel); + public: + void intersectCells(ConnType icellT, const std::vector<ConnType>& icellsS, MyMatrix& res); + int getNumberOfRowsOfResMatrix() const; + int getNumberOfColsOfResMatrix() const; + }; +} + +#endif diff --git a/src/medtool/src/INTERP_KERNEL/CurveIntersectorP1P0.txx b/src/medtool/src/INTERP_KERNEL/CurveIntersectorP1P0.txx new file mode 100644 index 000000000..7125fc8b3 --- /dev/null +++ b/src/medtool/src/INTERP_KERNEL/CurveIntersectorP1P0.txx @@ -0,0 +1,97 @@ +// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 +// 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 __CurveIntersectorP1P0_TXX__ +#define __CurveIntersectorP1P0_TXX__ + +#include "CurveIntersectorP1P0.hxx" +#include "CurveIntersector.txx" + +#define BASE_INTERSECTOR CurveIntersector<MyMeshType,MyMatrix> + +namespace INTERP_KERNEL +{ + template<class MyMeshType, class MyMatrix> + CurveIntersectorP1P0<MyMeshType,MyMatrix> + ::CurveIntersectorP1P0(const MyMeshType& meshT, const MyMeshType& meshS, + double precision, double tolerance, + double medianLine, int printLevel): + BASE_INTERSECTOR (meshT, meshS, precision, tolerance, medianLine, printLevel) + { + } + + template<class MyMeshType, class MyMatrix> + int CurveIntersectorP1P0<MyMeshType,MyMatrix> + ::getNumberOfRowsOfResMatrix() const + { + return BASE_INTERSECTOR::_meshT.getNumberOfElements(); + } + + template<class MyMeshType, class MyMatrix> + int CurveIntersectorP1P0<MyMeshType,MyMatrix> + ::getNumberOfColsOfResMatrix() const + { + return BASE_INTERSECTOR::_meshS.getNumberOfNodes(); + } + + //================================================================================ + /*! + * \brief Project from source nodes to target segments + */ + //================================================================================ + + template<class MyMeshType, class MyMatrix> + void CurveIntersectorP1P0<MyMeshType,MyMatrix> + ::intersectCells(ConnType icellT, const std::vector<ConnType>& icellsS, MyMatrix& res) + { + typename MyMatrix::value_type& resRow = res[ icellT ]; + std::vector<typename BASE_INTERSECTOR::TDualSegment> segmentsS; + std::vector<double> coordsT; + int t, nbSegT = 1 + BASE_INTERSECTOR::getRealTargetCoordinates(icellT,coordsT); + for ( t = 0; t < nbSegT; ++t ) + for(typename std::vector<ConnType>::const_iterator + iter=icellsS.begin(); iter!=icellsS.end(); iter++) + { + int iS = *iter; + BASE_INTERSECTOR::getDualSegments( OTT<ConnType,numPol>::ind2C(iS), + BASE_INTERSECTOR::_meshS, segmentsS); + for ( int s = 0; s < (int)segmentsS.size(); ++s ) + { + double surf = BASE_INTERSECTOR::intersectSegments(&segmentsS[s]._coords[0], + &coordsT[0] + t*SPACEDIM); + if(surf!=0.) + { + int nS = segmentsS[s]._nodeId; + typename MyMatrix::value_type::const_iterator iterRes=resRow.find(nS); + if(iterRes==resRow.end()) + resRow.insert(std::make_pair(nS,surf)); + else + { + surf+=(*iterRes).second; + resRow.erase(nS); + resRow.insert(std::make_pair(nS,surf)); + } + } + } + } + } +} +#undef BASE_INTERSECTOR + +#endif diff --git a/src/medtool/src/INTERP_KERNEL/CurveIntersectorP1P1.hxx b/src/medtool/src/INTERP_KERNEL/CurveIntersectorP1P1.hxx new file mode 100644 index 000000000..34678e712 --- /dev/null +++ b/src/medtool/src/INTERP_KERNEL/CurveIntersectorP1P1.hxx @@ -0,0 +1,48 @@ +// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 +// 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 __CURVEINTERSECTORP1P1_HXX__ +#define __CURVEINTERSECTORP1P1_HXX__ + +#include "CurveIntersector.hxx" + +namespace INTERP_KERNEL +{ + template<class MyMeshType, class MyMatrix> + class CurveIntersectorP1P1 : public CurveIntersector<MyMeshType,MyMatrix> + { + public: + static const int SPACEDIM=MyMeshType::MY_SPACEDIM; + static const int MESHDIM=MyMeshType::MY_MESHDIM; + typedef typename MyMeshType::MyConnType ConnType; + static const NumberingPolicy numPol=MyMeshType::My_numPol; + + CurveIntersectorP1P1(const MyMeshType& meshT, const MyMeshType& meshS, + double precision, double tolerance, + double medianLine, int printLevel); + public: + void intersectCells(ConnType icellT, + const std::vector<ConnType>& icellsS, MyMatrix& res); + int getNumberOfRowsOfResMatrix() const; + int getNumberOfColsOfResMatrix() const; + }; +} + +#endif diff --git a/src/medtool/src/INTERP_KERNEL/CurveIntersectorP1P1.txx b/src/medtool/src/INTERP_KERNEL/CurveIntersectorP1P1.txx new file mode 100644 index 000000000..266c87083 --- /dev/null +++ b/src/medtool/src/INTERP_KERNEL/CurveIntersectorP1P1.txx @@ -0,0 +1,92 @@ +// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 +// 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 __CurveIntersectorP1P1_TXX__ +#define __CurveIntersectorP1P1_TXX__ + +#include "CurveIntersectorP1P1.hxx" +#include "CurveIntersector.txx" + +#define BASE_INTERSECTOR CurveIntersector<MyMeshType,MyMatrix> + +namespace INTERP_KERNEL +{ + template<class MyMeshType, class MyMatrix> + CurveIntersectorP1P1<MyMeshType,MyMatrix> + ::CurveIntersectorP1P1(const MyMeshType& meshT, const MyMeshType& meshS, + double precision, double tolerance, + double medianLine, int printLevel): + BASE_INTERSECTOR (meshT, meshS, precision, tolerance, medianLine, printLevel) + { + } + + template<class MyMeshType, class MyMatrix> + int CurveIntersectorP1P1<MyMeshType,MyMatrix> + ::getNumberOfRowsOfResMatrix() const + { + return BASE_INTERSECTOR::_meshT.getNumberOfNodes(); + } + + template<class MyMeshType, class MyMatrix> + int CurveIntersectorP1P1<MyMeshType,MyMatrix> + ::getNumberOfColsOfResMatrix() const + { + return BASE_INTERSECTOR::_meshS.getNumberOfNodes(); + } + + template<class MyMeshType, class MyMatrix> + void CurveIntersectorP1P1<MyMeshType,MyMatrix> + ::intersectCells(ConnType icellT, const std::vector<ConnType>& icellsS, MyMatrix& res) + { + std::vector<typename BASE_INTERSECTOR::TDualSegment> segmentsT, segmentsS; + BASE_INTERSECTOR::getDualSegments( icellT, BASE_INTERSECTOR::_meshT, segmentsT); + for ( int t = 0; t < (int)segmentsT.size(); ++t ) + { + typename MyMatrix::value_type& resRow = res[ OTT<ConnType,numPol>::ind2C( segmentsT[t]._nodeId )]; + for(typename std::vector<ConnType>::const_iterator + iter=icellsS.begin(); iter!=icellsS.end(); iter++) + { + int iS = *iter; + BASE_INTERSECTOR::getDualSegments( OTT<ConnType,numPol>::ind2C(iS), + BASE_INTERSECTOR::_meshS, segmentsS); + for ( int s = 0; s < (int)segmentsS.size(); ++s ) + { + double surf = BASE_INTERSECTOR::intersectSegments(&segmentsT[t]._coords[0], + &segmentsS[s]._coords[0]); + if(surf!=0.) + { + int nS = segmentsS[s]._nodeId; + typename MyMatrix::value_type::const_iterator iterRes=resRow.find(nS); + if(iterRes==resRow.end()) + resRow.insert(std::make_pair(nS,surf)); + else + { + surf+=(*iterRes).second; + resRow.erase(nS); + resRow.insert(std::make_pair(nS,surf)); + } + } + } + } + } + } +} +#undef BASE_INTERSECTOR + +#endif diff --git a/src/medtool/src/INTERP_KERNEL/CurveIntersectorP1P1PL.hxx b/src/medtool/src/INTERP_KERNEL/CurveIntersectorP1P1PL.hxx new file mode 100644 index 000000000..d9bab059b --- /dev/null +++ b/src/medtool/src/INTERP_KERNEL/CurveIntersectorP1P1PL.hxx @@ -0,0 +1,50 @@ +// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 +// 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 (EDF R&D) + +#ifndef __CURVEINTERSECTORP1P1PL_HXX__ +#define __CURVEINTERSECTORP1P1PL_HXX__ + +#include "CurveIntersector.hxx" + +namespace INTERP_KERNEL +{ + template<class MyMeshType, class MyMatrix> + class CurveIntersectorP1P1PL : public CurveIntersector<MyMeshType,MyMatrix> + { + public: + static const int SPACEDIM=MyMeshType::MY_SPACEDIM; + static const int MESHDIM=MyMeshType::MY_MESHDIM; + typedef typename MyMeshType::MyConnType ConnType; + static const NumberingPolicy numPol=MyMeshType::My_numPol; + + CurveIntersectorP1P1PL(const MyMeshType& meshT, const MyMeshType& meshS, + double precision, double tolerance, + double medianLine, int printLevel); + public: + void intersectCells(ConnType icellT, const std::vector<ConnType>& icellsS, MyMatrix& res); + int getNumberOfRowsOfResMatrix() const; + int getNumberOfColsOfResMatrix() const; + private: + static void AppendValueInMatrix(MyMatrix& res, ConnType nodeIdT, ConnType nodeIdS0, double val0, ConnType nodeIdS1, double val1); + static void AppendValueInMatrix2(typename MyMatrix::value_type& resRow, ConnType nodeIdS0, double val0); + }; +} + +#endif diff --git a/src/medtool/src/INTERP_KERNEL/CurveIntersectorP1P1PL.txx b/src/medtool/src/INTERP_KERNEL/CurveIntersectorP1P1PL.txx new file mode 100644 index 000000000..02b09eb91 --- /dev/null +++ b/src/medtool/src/INTERP_KERNEL/CurveIntersectorP1P1PL.txx @@ -0,0 +1,112 @@ +// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 +// 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 (EDF R&D) + +#ifndef __CURVEINTERSECTORP1P1PL_TXX__ +#define __CURVEINTERSECTORP1P1PL_TXX__ + +#include "CurveIntersectorP1P1PL.hxx" +#include "CurveIntersector.txx" + +#include <cassert> + +namespace INTERP_KERNEL +{ + template<class MyMeshType, class MyMatrix> + CurveIntersectorP1P1PL<MyMeshType,MyMatrix>::CurveIntersectorP1P1PL(const MyMeshType& meshT, const MyMeshType& meshS, double precision, double tolerance, double medianLine, int printLevel):CurveIntersector<MyMeshType,MyMatrix>(meshT, meshS, precision, tolerance, medianLine, printLevel) + { + } + + template<class MyMeshType, class MyMatrix> + int CurveIntersectorP1P1PL<MyMeshType,MyMatrix>::getNumberOfRowsOfResMatrix() const + { + return CurveIntersector<MyMeshType,MyMatrix>::_meshT.getNumberOfNodes(); + } + + template<class MyMeshType, class MyMatrix> + int CurveIntersectorP1P1PL<MyMeshType,MyMatrix>::getNumberOfColsOfResMatrix() const + { + return CurveIntersector<MyMeshType,MyMatrix>::_meshS.getNumberOfNodes(); + } + + template<class MyMeshType, class MyMatrix> + void CurveIntersectorP1P1PL<MyMeshType,MyMatrix>::AppendValueInMatrix2(typename MyMatrix::value_type& resRow, ConnType nodeIdS0, double val0) + { + typename MyMatrix::value_type::const_iterator iterRes(resRow.find(OTT<ConnType,numPol>::indFC(nodeIdS0))); + if(iterRes==resRow.end()) + { + resRow.insert(std::make_pair(OTT<ConnType,numPol>::indFC(nodeIdS0),val0)); + } + else + { + double val((*iterRes).second+val0); + resRow.erase(OTT<ConnType,numPol>::indFC(nodeIdS0)); + resRow.insert(std::make_pair(OTT<ConnType,numPol>::indFC(nodeIdS0),val)); + } + } + + template<class MyMeshType, class MyMatrix> + void CurveIntersectorP1P1PL<MyMeshType,MyMatrix>::AppendValueInMatrix(MyMatrix& res, ConnType nodeIdT, ConnType nodeIdS0, double val0, ConnType nodeIdS1, double val1) + { + typename MyMatrix::value_type& resRow(res[nodeIdT]); + AppendValueInMatrix2(resRow,nodeIdS0,val0); + AppendValueInMatrix2(resRow,nodeIdS1,val1); + } + + template<class MyMeshType, class MyMatrix> + void CurveIntersectorP1P1PL<MyMeshType,MyMatrix>::intersectCells(ConnType icellT, const std::vector<ConnType>& icellsS, MyMatrix& res) + { + std::vector<double> coordsT; + if(CurveIntersector<MyMeshType,MyMatrix>::getRealTargetCoordinates(icellT,coordsT)) + throw INTERP_KERNEL::Exception("Invalid target cell detected for meshdim==1. Only SEG2 supported !"); + assert(coordsT.size()/SPACEDIM==2); + for(typename std::vector<ConnType>::const_iterator iter=icellsS.begin();iter!=icellsS.end();iter++) + { + std::vector<double> coordsS; + if(CurveIntersector<MyMeshType,MyMatrix>::getRealSourceCoordinates(*iter,coordsS)) + throw INTERP_KERNEL::Exception("Invalid source cell detected for meshdim==1. Only SEG2 supported !"); + assert(coordsS.size()/SPACEDIM==2); + double xs0,xs1,xt0,xt1; + double lgth(CurveIntersector<MyMeshType,MyMatrix>::intersectSegmentsInternal(&coordsT[0],&coordsS[0],xs0,xs1,xt0,xt1)); + ConnType nodeIdS0(CurveIntersector<MyMeshType,MyMatrix>::getNodeIdOfSourceCellAt(*iter,0)); + ConnType nodeIdS1(CurveIntersector<MyMeshType,MyMatrix>::getNodeIdOfSourceCellAt(*iter,1)); + if(lgth>0.) + { + double a,b; + // for first + ConnType nodeIdT0(CurveIntersector<MyMeshType,MyMatrix>::getNodeIdOfTargetCellAt(icellT,0)); + if(CurveIntersector<MyMeshType,MyMatrix>::ComputeBaryCoordsOf(xs0,xs1,xt0,a,b)) + { + a*=lgth; b*=lgth; + AppendValueInMatrix(res,nodeIdT0,nodeIdS0,a,nodeIdS1,b); + } + // + ConnType nodeIdT1(CurveIntersector<MyMeshType,MyMatrix>::getNodeIdOfTargetCellAt(icellT,1)); + typename MyMatrix::value_type& resRow1=res[nodeIdT1]; + if(CurveIntersector<MyMeshType,MyMatrix>::ComputeBaryCoordsOf(xs0,xs1,xt1,a,b)) + { + a*=lgth; b*=lgth; + AppendValueInMatrix(res,nodeIdT1,nodeIdS0,a,nodeIdS1,b); + } + } + } + } +} + +#endif diff --git a/src/medtool/src/INTERP_KERNEL/DiameterCalculator.cxx b/src/medtool/src/INTERP_KERNEL/DiameterCalculator.cxx new file mode 100644 index 000000000..b89d66383 --- /dev/null +++ b/src/medtool/src/INTERP_KERNEL/DiameterCalculator.cxx @@ -0,0 +1,745 @@ +// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 +// 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 (EDF R&D) + +#include "DiameterCalculator.hxx" +#include "InterpKernelException.hxx" +#include "CellModel.hxx" + +#include <algorithm> +#include <sstream> +#include <cmath> + +using namespace INTERP_KERNEL; + +NormalizedCellType DiameterCalulatorTRI3S2::TYPE=NORM_TRI3; + +NormalizedCellType DiameterCalulatorTRI3S3::TYPE=NORM_TRI3; + +NormalizedCellType DiameterCalulatorTRI6S2::TYPE=NORM_TRI6; + +NormalizedCellType DiameterCalulatorTRI6S3::TYPE=NORM_TRI6; + +NormalizedCellType DiameterCalulatorTRI7S2::TYPE=NORM_TRI7; + +NormalizedCellType DiameterCalulatorTRI7S3::TYPE=NORM_TRI7; + +NormalizedCellType DiameterCalulatorQUAD4S2::TYPE=NORM_QUAD4; + +NormalizedCellType DiameterCalulatorQUAD4S3::TYPE=NORM_QUAD4; + +NormalizedCellType DiameterCalulatorQUAD8S2::TYPE=NORM_QUAD8; + +NormalizedCellType DiameterCalulatorQUAD8S3::TYPE=NORM_QUAD8; + +NormalizedCellType DiameterCalulatorQUAD9S2::TYPE=NORM_QUAD9; + +NormalizedCellType DiameterCalulatorQUAD9S3::TYPE=NORM_QUAD9; + +NormalizedCellType DiameterCalulatorTETRA4::TYPE=NORM_TETRA4; + +NormalizedCellType DiameterCalulatorTETRA10::TYPE=NORM_TETRA10; + +NormalizedCellType DiameterCalulatorHEXA8::TYPE=NORM_HEXA8; + +NormalizedCellType DiameterCalulatorHEXA20::TYPE=NORM_HEXA20; + +NormalizedCellType DiameterCalulatorHEXA27::TYPE=NORM_HEXA27; + +NormalizedCellType DiameterCalulatorPENTA6::TYPE=NORM_PENTA6; + +NormalizedCellType DiameterCalulatorPENTA15::TYPE=NORM_PENTA15; + +NormalizedCellType DiameterCalulatorPYRA5::TYPE=NORM_PYRA5; + +NormalizedCellType DiameterCalulatorPYRA13::TYPE=NORM_PYRA13; + +inline double SqNormV2(const double tab[2]) +{ + return tab[0]*tab[0]+tab[1]*tab[1]; +} + +inline void DiffV2(const double a[2], const double b[2], double c[2]) +{ + c[0]=a[0]-b[0]; + c[1]=a[1]-b[1]; +} + +inline double SqNormV3(const double tab[3]) +{ + return tab[0]*tab[0]+tab[1]*tab[1]+tab[2]*tab[2]; +} + +inline void DiffV3(const double a[3], const double b[3], double c[3]) +{ + c[0]=a[0]-b[0]; + c[1]=a[1]-b[1]; + c[2]=a[2]-b[2]; +} + +template<class Evaluator> +void ComputeForListOfCellIdsUMeshFrmt(const int *bgIds, const int *endIds, const int *indPtr, const int *connPtr, const double *coordsPtr, double *resPtr) +{ + Evaluator evtor; + NormalizedCellType ct(Evaluator::TYPE); + int cti((int) ct); + for(const int *it=bgIds;it!=endIds;it++) + { + int offset(indPtr[*it]); + if(connPtr[offset]==cti) + resPtr[*it]=evtor.ComputeForOneCellInternal(connPtr+offset+1,connPtr+indPtr[(*it)+1],coordsPtr); + else + { + std::ostringstream oss; oss << "DiameterCalculator::computeForListOfCellIdsUMeshFrmt : invalid nodal connectivity format at cell # " << *it << " !"; + throw Exception(oss.str().c_str()); + } + } +} + +template<class Evaluator> +void ComputeForRangeOfCellIdsUMeshFrmt(int bgId, int endId, const int *indPtr, const int *connPtr, const double *coordsPtr, double *resPtr) +{ + Evaluator evtor; + NormalizedCellType ct(Evaluator::TYPE); + int cti((int) ct); + for(int it=bgId;it<endId;it++) + { + int offset(indPtr[it]); + if(connPtr[offset]==cti) + resPtr[it]=evtor.ComputeForOneCellInternal(connPtr+offset+1,connPtr+indPtr[it+1],coordsPtr); + else + { + std::ostringstream oss; oss << "DiameterCalculator::computeForListOfCellIdsUMeshFrmt : invalid nodal connectivity format at cell # " << it << " !"; + throw Exception(oss.str().c_str()); + } + } +} + +template<class Evaluator> +void ComputeFor1SGTUMeshFrmt(int nbOfCells, const int *connPtr, const double *coordsPtr, double *resPtr) +{ + Evaluator evtor; + NormalizedCellType ct(Evaluator::TYPE); + const CellModel& cm(CellModel::GetCellModel(ct)); + unsigned nbNodes(cm.getNumberOfNodes()); + const int *ptr(connPtr); + for(int i=0;i<nbOfCells;i++,ptr+=nbNodes,resPtr++) + *resPtr=evtor.ComputeForOneCellInternal(ptr,ptr+nbNodes,coordsPtr); +} + +//================================================================= + +double DiameterCalulatorTRI3S2::ComputeForOneCellInternal(const int *bg, const int *endd, const double *coordsPtr) +{ + if(std::distance(bg,endd)==3) + { + const double *a(coordsPtr+2*bg[0]),*b(coordsPtr+2*bg[1]),*c(coordsPtr+2*bg[2]); + double l0[2],l1[2],l2[2]; + DiffV2(a,b,l0); + DiffV2(a,c,l1); + DiffV2(b,c,l2); + double res(std::max(SqNormV2(l0),SqNormV2(l1))); + res=std::max(res,SqNormV2(l2)); + return std::sqrt(res); + } + else + throw Exception("DiameterCalulatorTRI3S2::ComputeForOneCellInternal : input connectivity must be of size 3 !"); +} + +void DiameterCalulatorTRI3S2::computeForListOfCellIdsUMeshFrmt(const int *bgIds, const int *endIds, const int *indPtr, const int *connPtr, const double *coordsPtr, double *resPtr) const +{ + ComputeForListOfCellIdsUMeshFrmt<DiameterCalulatorTRI3S2>(bgIds,endIds,indPtr,connPtr,coordsPtr,resPtr); +} + +void DiameterCalulatorTRI3S2::computeForRangeOfCellIdsUMeshFrmt(int bgId, int endId, const int *indPtr, const int *connPtr, const double *coordsPtr, double *resPtr) const +{ + ComputeForRangeOfCellIdsUMeshFrmt<DiameterCalulatorTRI3S2>(bgId,endId,indPtr,connPtr,coordsPtr,resPtr); +} + +void DiameterCalulatorTRI3S2::computeFor1SGTUMeshFrmt(int nbOfCells, const int *connPtr, const double *coordsPtr, double *resPtr) const +{ + ComputeFor1SGTUMeshFrmt<DiameterCalulatorTRI3S2>(nbOfCells,connPtr,coordsPtr,resPtr); +} + +//================================================================= + +double DiameterCalulatorTRI3S3::ComputeForOneCellInternal(const int *bg, const int *endd, const double *coordsPtr) +{ + if(std::distance(bg,endd)==3) + { + const double *a(coordsPtr+3*bg[0]),*b(coordsPtr+3*bg[1]),*c(coordsPtr+3*bg[2]); + double l0[3],l1[3],l2[3]; + DiffV3(a,b,l0); + DiffV3(a,c,l1); + DiffV3(b,c,l2); + double res(std::max(SqNormV3(l0),SqNormV3(l1))); + res=std::max(res,SqNormV3(l2)); + return std::sqrt(res); + } + else + throw Exception("DiameterCalulatorTRI3S2::ComputeForOneCellInternal : input connectivity must be of size 3 !"); +} + +void DiameterCalulatorTRI3S3::computeForListOfCellIdsUMeshFrmt(const int *bgIds, const int *endIds, const int *indPtr, const int *connPtr, const double *coordsPtr, double *resPtr) const +{ + ComputeForListOfCellIdsUMeshFrmt<DiameterCalulatorTRI3S3>(bgIds,endIds,indPtr,connPtr,coordsPtr,resPtr); +} + +void DiameterCalulatorTRI3S3::computeForRangeOfCellIdsUMeshFrmt(int bgId, int endId, const int *indPtr, const int *connPtr, const double *coordsPtr, double *resPtr) const +{ + ComputeForRangeOfCellIdsUMeshFrmt<DiameterCalulatorTRI3S3>(bgId,endId,indPtr,connPtr,coordsPtr,resPtr); +} + +void DiameterCalulatorTRI3S3::computeFor1SGTUMeshFrmt(int nbOfCells, const int *connPtr, const double *coordsPtr, double *resPtr) const +{ + ComputeFor1SGTUMeshFrmt<DiameterCalulatorTRI3S3>(nbOfCells,connPtr,coordsPtr,resPtr); +} + +//================================================================= + +double DiameterCalulatorTRI6S2::ComputeForOneCellInternal(const int *bg, const int *endd, const double *coordsPtr) +{ + if(std::distance(bg,endd)==6) + return DiameterCalulatorTRI3S2::ComputeForOneCellInternal(bg,bg+3,coordsPtr); + else + throw Exception("DiameterCalulatorTRI6S2::ComputeForOneCellInternal : input connectivity must be of size 6 !"); +} + +void DiameterCalulatorTRI6S2::computeForListOfCellIdsUMeshFrmt(const int *bgIds, const int *endIds, const int *indPtr, const int *connPtr, const double *coordsPtr, double *resPtr) const +{ + ComputeForListOfCellIdsUMeshFrmt<DiameterCalulatorTRI6S2>(bgIds,endIds,indPtr,connPtr,coordsPtr,resPtr); +} + +void DiameterCalulatorTRI6S2::computeForRangeOfCellIdsUMeshFrmt(int bgId, int endId, const int *indPtr, const int *connPtr, const double *coordsPtr, double *resPtr) const +{ + ComputeForRangeOfCellIdsUMeshFrmt<DiameterCalulatorTRI6S2>(bgId,endId,indPtr,connPtr,coordsPtr,resPtr); +} + +void DiameterCalulatorTRI6S2::computeFor1SGTUMeshFrmt(int nbOfCells, const int *connPtr, const double *coordsPtr, double *resPtr) const +{ + ComputeFor1SGTUMeshFrmt<DiameterCalulatorTRI6S2>(nbOfCells,connPtr,coordsPtr,resPtr); +} + +//================================================================= + +double DiameterCalulatorTRI6S3::ComputeForOneCellInternal(const int *bg, const int *endd, const double *coordsPtr) +{ + if(std::distance(bg,endd)==6) + return DiameterCalulatorTRI3S3::ComputeForOneCellInternal(bg,bg+3,coordsPtr); + else + throw Exception("DiameterCalulatorTRI6S3::ComputeForOneCellInternal : input connectivity must be of size 6 !"); +} + +void DiameterCalulatorTRI6S3::computeForListOfCellIdsUMeshFrmt(const int *bgIds, const int *endIds, const int *indPtr, const int *connPtr, const double *coordsPtr, double *resPtr) const +{ + ComputeForListOfCellIdsUMeshFrmt<DiameterCalulatorTRI6S3>(bgIds,endIds,indPtr,connPtr,coordsPtr,resPtr); +} + +void DiameterCalulatorTRI6S3::computeForRangeOfCellIdsUMeshFrmt(int bgId, int endId, const int *indPtr, const int *connPtr, const double *coordsPtr, double *resPtr) const +{ + ComputeForRangeOfCellIdsUMeshFrmt<DiameterCalulatorTRI6S3>(bgId,endId,indPtr,connPtr,coordsPtr,resPtr); +} + +void DiameterCalulatorTRI6S3::computeFor1SGTUMeshFrmt(int nbOfCells, const int *connPtr, const double *coordsPtr, double *resPtr) const +{ + ComputeFor1SGTUMeshFrmt<DiameterCalulatorTRI6S3>(nbOfCells,connPtr,coordsPtr,resPtr); +} + +//================================================================= + +double DiameterCalulatorTRI7S2::ComputeForOneCellInternal(const int *bg, const int *endd, const double *coordsPtr) +{ + if(std::distance(bg,endd)==7) + return DiameterCalulatorTRI3S2::ComputeForOneCellInternal(bg,bg+3,coordsPtr); + else + throw Exception("DiameterCalulatorTRI7S2::ComputeForOneCellInternal : input connectivity must be of size 7 !"); +} + +void DiameterCalulatorTRI7S2::computeForListOfCellIdsUMeshFrmt(const int *bgIds, const int *endIds, const int *indPtr, const int *connPtr, const double *coordsPtr, double *resPtr) const +{ + ComputeForListOfCellIdsUMeshFrmt<DiameterCalulatorTRI7S2>(bgIds,endIds,indPtr,connPtr,coordsPtr,resPtr); +} + +void DiameterCalulatorTRI7S2::computeForRangeOfCellIdsUMeshFrmt(int bgId, int endId, const int *indPtr, const int *connPtr, const double *coordsPtr, double *resPtr) const +{ + ComputeForRangeOfCellIdsUMeshFrmt<DiameterCalulatorTRI7S2>(bgId,endId,indPtr,connPtr,coordsPtr,resPtr); +} + +void DiameterCalulatorTRI7S2::computeFor1SGTUMeshFrmt(int nbOfCells, const int *connPtr, const double *coordsPtr, double *resPtr) const +{ + ComputeFor1SGTUMeshFrmt<DiameterCalulatorTRI7S2>(nbOfCells,connPtr,coordsPtr,resPtr); +} + +//================================================================= + +double DiameterCalulatorTRI7S3::ComputeForOneCellInternal(const int *bg, const int *endd, const double *coordsPtr) +{ + if(std::distance(bg,endd)==7) + return DiameterCalulatorTRI3S3::ComputeForOneCellInternal(bg,bg+3,coordsPtr); + else + throw Exception("DiameterCalulatorTRI7S3::ComputeForOneCellInternal : input connectivity must be of size 7 !"); +} + +void DiameterCalulatorTRI7S3::computeForListOfCellIdsUMeshFrmt(const int *bgIds, const int *endIds, const int *indPtr, const int *connPtr, const double *coordsPtr, double *resPtr) const +{ + ComputeForListOfCellIdsUMeshFrmt<DiameterCalulatorTRI7S3>(bgIds,endIds,indPtr,connPtr,coordsPtr,resPtr); +} + +void DiameterCalulatorTRI7S3::computeForRangeOfCellIdsUMeshFrmt(int bgId, int endId, const int *indPtr, const int *connPtr, const double *coordsPtr, double *resPtr) const +{ + ComputeForRangeOfCellIdsUMeshFrmt<DiameterCalulatorTRI7S3>(bgId,endId,indPtr,connPtr,coordsPtr,resPtr); +} + +void DiameterCalulatorTRI7S3::computeFor1SGTUMeshFrmt(int nbOfCells, const int *connPtr, const double *coordsPtr, double *resPtr) const +{ + ComputeFor1SGTUMeshFrmt<DiameterCalulatorTRI7S3>(nbOfCells,connPtr,coordsPtr,resPtr); +} + +//================================================================= + +double DiameterCalulatorQUAD4S2::ComputeForOneCellInternal(const int *bg, const int *endd, const double *coordsPtr) +{ + if(std::distance(bg,endd)==4) + { + const double *a(coordsPtr+2*bg[0]),*b(coordsPtr+2*bg[1]),*c(coordsPtr+2*bg[2]),*d(coordsPtr+2*bg[3]); + double l0[2],l1[2]; + DiffV2(a,c,l0); + DiffV2(b,d,l1); + return std::sqrt(std::max(SqNormV2(l0),SqNormV2(l1))); + } + else + throw Exception("DiameterCalulatorQUAD4S2::ComputeForOneCellInternal : input connectivity must be of size 4 !"); +} + +void DiameterCalulatorQUAD4S2::computeForListOfCellIdsUMeshFrmt(const int *bgIds, const int *endIds, const int *indPtr, const int *connPtr, const double *coordsPtr, double *resPtr) const +{ + ComputeForListOfCellIdsUMeshFrmt<DiameterCalulatorQUAD4S2>(bgIds,endIds,indPtr,connPtr,coordsPtr,resPtr); +} + +void DiameterCalulatorQUAD4S2::computeForRangeOfCellIdsUMeshFrmt(int bgId, int endId, const int *indPtr, const int *connPtr, const double *coordsPtr, double *resPtr) const +{ + ComputeForRangeOfCellIdsUMeshFrmt<DiameterCalulatorQUAD4S2>(bgId,endId,indPtr,connPtr,coordsPtr,resPtr); +} + +void DiameterCalulatorQUAD4S2::computeFor1SGTUMeshFrmt(int nbOfCells, const int *connPtr, const double *coordsPtr, double *resPtr) const +{ + ComputeFor1SGTUMeshFrmt<DiameterCalulatorQUAD4S2>(nbOfCells,connPtr,coordsPtr,resPtr); +} + +//================================================================= + +double DiameterCalulatorQUAD4S3::ComputeForOneCellInternal(const int *bg, const int *endd, const double *coordsPtr) +{ + if(std::distance(bg,endd)==4) + { + const double *a(coordsPtr+3*bg[0]),*b(coordsPtr+3*bg[1]),*c(coordsPtr+3*bg[2]),*d(coordsPtr+3*bg[3]); + double l0[3],l1[3]; + DiffV3(a,c,l0); + DiffV3(b,d,l1); + return std::sqrt(std::max(SqNormV3(l0),SqNormV3(l1))); + } + else + throw Exception("DiameterCalulatorQUAD4S3::ComputeForOneCellInternal : input connectivity must be of size 4 !"); +} + +void DiameterCalulatorQUAD4S3::computeForListOfCellIdsUMeshFrmt(const int *bgIds, const int *endIds, const int *indPtr, const int *connPtr, const double *coordsPtr, double *resPtr) const +{ + ComputeForListOfCellIdsUMeshFrmt<DiameterCalulatorQUAD4S3>(bgIds,endIds,indPtr,connPtr,coordsPtr,resPtr); +} + +void DiameterCalulatorQUAD4S3::computeForRangeOfCellIdsUMeshFrmt(int bgId, int endId, const int *indPtr, const int *connPtr, const double *coordsPtr, double *resPtr) const +{ + ComputeForRangeOfCellIdsUMeshFrmt<DiameterCalulatorQUAD4S3>(bgId,endId,indPtr,connPtr,coordsPtr,resPtr); +} + +void DiameterCalulatorQUAD4S3::computeFor1SGTUMeshFrmt(int nbOfCells, const int *connPtr, const double *coordsPtr, double *resPtr) const +{ + ComputeFor1SGTUMeshFrmt<DiameterCalulatorQUAD4S3>(nbOfCells,connPtr,coordsPtr,resPtr); +} + +//================================================================= + +double DiameterCalulatorQUAD8S2::ComputeForOneCellInternal(const int *bg, const int *endd, const double *coordsPtr) +{ + if(std::distance(bg,endd)==8) + return DiameterCalulatorQUAD4S2::ComputeForOneCellInternal(bg,bg+4,coordsPtr); + else + throw Exception("DiameterCalulatorQUAD8S2::ComputeForOneCellInternal : input connectivity must be of size 8 !"); +} + +void DiameterCalulatorQUAD8S2::computeForListOfCellIdsUMeshFrmt(const int *bgIds, const int *endIds, const int *indPtr, const int *connPtr, const double *coordsPtr, double *resPtr) const +{ + ComputeForListOfCellIdsUMeshFrmt<DiameterCalulatorQUAD8S2>(bgIds,endIds,indPtr,connPtr,coordsPtr,resPtr); +} + +void DiameterCalulatorQUAD8S2::computeForRangeOfCellIdsUMeshFrmt(int bgId, int endId, const int *indPtr, const int *connPtr, const double *coordsPtr, double *resPtr) const +{ + ComputeForRangeOfCellIdsUMeshFrmt<DiameterCalulatorQUAD8S2>(bgId,endId,indPtr,connPtr,coordsPtr,resPtr); +} + +void DiameterCalulatorQUAD8S2::computeFor1SGTUMeshFrmt(int nbOfCells, const int *connPtr, const double *coordsPtr, double *resPtr) const +{ + ComputeFor1SGTUMeshFrmt<DiameterCalulatorQUAD8S2>(nbOfCells,connPtr,coordsPtr,resPtr); +} + +//================================================================= + +double DiameterCalulatorQUAD8S3::ComputeForOneCellInternal(const int *bg, const int *endd, const double *coordsPtr) +{ + if(std::distance(bg,endd)==8) + return DiameterCalulatorQUAD4S3::ComputeForOneCellInternal(bg,bg+4,coordsPtr); + else + throw Exception("DiameterCalulatorQUAD8S3::ComputeForOneCellInternal : input connectivity must be of size 8 !"); +} + +void DiameterCalulatorQUAD8S3::computeForListOfCellIdsUMeshFrmt(const int *bgIds, const int *endIds, const int *indPtr, const int *connPtr, const double *coordsPtr, double *resPtr) const +{ + ComputeForListOfCellIdsUMeshFrmt<DiameterCalulatorQUAD8S3>(bgIds,endIds,indPtr,connPtr,coordsPtr,resPtr); +} + +void DiameterCalulatorQUAD8S3::computeForRangeOfCellIdsUMeshFrmt(int bgId, int endId, const int *indPtr, const int *connPtr, const double *coordsPtr, double *resPtr) const +{ + ComputeForRangeOfCellIdsUMeshFrmt<DiameterCalulatorQUAD8S3>(bgId,endId,indPtr,connPtr,coordsPtr,resPtr); +} + +void DiameterCalulatorQUAD8S3::computeFor1SGTUMeshFrmt(int nbOfCells, const int *connPtr, const double *coordsPtr, double *resPtr) const +{ + ComputeFor1SGTUMeshFrmt<DiameterCalulatorQUAD8S3>(nbOfCells,connPtr,coordsPtr,resPtr); +} + +//================================================================= + +double DiameterCalulatorQUAD9S2::ComputeForOneCellInternal(const int *bg, const int *endd, const double *coordsPtr) +{ + if(std::distance(bg,endd)==9) + return DiameterCalulatorQUAD4S2::ComputeForOneCellInternal(bg,bg+4,coordsPtr); + else + throw Exception("DiameterCalulatorQUAD9S2::ComputeForOneCellInternal : input connectivity must be of size 9 !"); +} + +void DiameterCalulatorQUAD9S2::computeForListOfCellIdsUMeshFrmt(const int *bgIds, const int *endIds, const int *indPtr, const int *connPtr, const double *coordsPtr, double *resPtr) const +{ + ComputeForListOfCellIdsUMeshFrmt<DiameterCalulatorQUAD9S2>(bgIds,endIds,indPtr,connPtr,coordsPtr,resPtr); +} + +void DiameterCalulatorQUAD9S2::computeForRangeOfCellIdsUMeshFrmt(int bgId, int endId, const int *indPtr, const int *connPtr, const double *coordsPtr, double *resPtr) const +{ + ComputeForRangeOfCellIdsUMeshFrmt<DiameterCalulatorQUAD9S2>(bgId,endId,indPtr,connPtr,coordsPtr,resPtr); +} + +void DiameterCalulatorQUAD9S2::computeFor1SGTUMeshFrmt(int nbOfCells, const int *connPtr, const double *coordsPtr, double *resPtr) const +{ + ComputeFor1SGTUMeshFrmt<DiameterCalulatorQUAD9S2>(nbOfCells,connPtr,coordsPtr,resPtr); +} + +//================================================================= + +double DiameterCalulatorQUAD9S3::ComputeForOneCellInternal(const int *bg, const int *endd, const double *coordsPtr) +{ + if(std::distance(bg,endd)==9) + return DiameterCalulatorQUAD4S3::ComputeForOneCellInternal(bg,bg+4,coordsPtr); + else + throw Exception("DiameterCalulatorQUAD8S3::ComputeForOneCellInternal : input connectivity must be of size 9 !"); +} + +void DiameterCalulatorQUAD9S3::computeForListOfCellIdsUMeshFrmt(const int *bgIds, const int *endIds, const int *indPtr, const int *connPtr, const double *coordsPtr, double *resPtr) const +{ + ComputeForListOfCellIdsUMeshFrmt<DiameterCalulatorQUAD9S3>(bgIds,endIds,indPtr,connPtr,coordsPtr,resPtr); +} + +void DiameterCalulatorQUAD9S3::computeForRangeOfCellIdsUMeshFrmt(int bgId, int endId, const int *indPtr, const int *connPtr, const double *coordsPtr, double *resPtr) const +{ + ComputeForRangeOfCellIdsUMeshFrmt<DiameterCalulatorQUAD9S3>(bgId,endId,indPtr,connPtr,coordsPtr,resPtr); +} + +void DiameterCalulatorQUAD9S3::computeFor1SGTUMeshFrmt(int nbOfCells, const int *connPtr, const double *coordsPtr, double *resPtr) const +{ + ComputeFor1SGTUMeshFrmt<DiameterCalulatorQUAD9S3>(nbOfCells,connPtr,coordsPtr,resPtr); +} + +//================================================================= + +double DiameterCalulatorTETRA4::ComputeForOneCellInternal(const int *bg, const int *endd, const double *coordsPtr) +{ + if(std::distance(bg,endd)==4) + { + const double *a(coordsPtr+3*bg[0]),*b(coordsPtr+3*bg[1]),*c(coordsPtr+3*bg[2]),*d(coordsPtr+3*bg[3]); + double l0[3],l1[3],l2[3],l3[3],l4[3],l5[3]; + DiffV3(a,b,l0); + DiffV3(a,c,l1); + DiffV3(b,c,l2); + DiffV3(a,d,l3); + DiffV3(b,d,l4); + DiffV3(c,d,l5); + double tmp[6]; + tmp[0]=SqNormV3(l0); tmp[1]=SqNormV3(l1); tmp[2]=SqNormV3(l2); tmp[3]=SqNormV3(l3); tmp[4]=SqNormV3(l4); tmp[5]=SqNormV3(l5); + return std::sqrt(*std::max_element(tmp,tmp+6)); + } + else + throw Exception("DiameterCalulatorTETRA4::ComputeForOneCellInternal : input connectivity must be of size 4 !"); +} + +void DiameterCalulatorTETRA4::computeForListOfCellIdsUMeshFrmt(const int *bgIds, const int *endIds, const int *indPtr, const int *connPtr, const double *coordsPtr, double *resPtr) const +{ + ComputeForListOfCellIdsUMeshFrmt<DiameterCalulatorTETRA4>(bgIds,endIds,indPtr,connPtr,coordsPtr,resPtr); +} + +void DiameterCalulatorTETRA4::computeForRangeOfCellIdsUMeshFrmt(int bgId, int endId, const int *indPtr, const int *connPtr, const double *coordsPtr, double *resPtr) const +{ + ComputeForRangeOfCellIdsUMeshFrmt<DiameterCalulatorTETRA4>(bgId,endId,indPtr,connPtr,coordsPtr,resPtr); +} + +void DiameterCalulatorTETRA4::computeFor1SGTUMeshFrmt(int nbOfCells, const int *connPtr, const double *coordsPtr, double *resPtr) const +{ + ComputeFor1SGTUMeshFrmt<DiameterCalulatorTETRA4>(nbOfCells,connPtr,coordsPtr,resPtr); +} + +//================================================================= + +double DiameterCalulatorTETRA10::ComputeForOneCellInternal(const int *bg, const int *endd, const double *coordsPtr) +{ + if(std::distance(bg,endd)==10) + return DiameterCalulatorTETRA4::ComputeForOneCellInternal(bg,bg+4,coordsPtr); + else + throw Exception("DiameterCalulatorTETRA10::ComputeForOneCellInternal : input connectivity must be of size 10 !"); +} + +void DiameterCalulatorTETRA10::computeForListOfCellIdsUMeshFrmt(const int *bgIds, const int *endIds, const int *indPtr, const int *connPtr, const double *coordsPtr, double *resPtr) const +{ + ComputeForListOfCellIdsUMeshFrmt<DiameterCalulatorTETRA10>(bgIds,endIds,indPtr,connPtr,coordsPtr,resPtr); +} + +void DiameterCalulatorTETRA10::computeForRangeOfCellIdsUMeshFrmt(int bgId, int endId, const int *indPtr, const int *connPtr, const double *coordsPtr, double *resPtr) const +{ + ComputeForRangeOfCellIdsUMeshFrmt<DiameterCalulatorTETRA10>(bgId,endId,indPtr,connPtr,coordsPtr,resPtr); +} + +void DiameterCalulatorTETRA10::computeFor1SGTUMeshFrmt(int nbOfCells, const int *connPtr, const double *coordsPtr, double *resPtr) const +{ + ComputeFor1SGTUMeshFrmt<DiameterCalulatorTETRA10>(nbOfCells,connPtr,coordsPtr,resPtr); +} + +//================================================================= + +double DiameterCalulatorHEXA8::ComputeForOneCellInternal(const int *bg, const int *endd, const double *coordsPtr) +{ + if(std::distance(bg,endd)==8) + { + const double *p0(coordsPtr+3*bg[0]),*p1(coordsPtr+3*bg[1]),*p2(coordsPtr+3*bg[2]),*p3(coordsPtr+3*bg[3]),*p4(coordsPtr+3*bg[4]),*p5(coordsPtr+3*bg[5]),*p6(coordsPtr+3*bg[6]),*p7(coordsPtr+3*bg[7]); + double l0[3],l1[3],l2[3],l3[3]; + DiffV3(p0,p6,l0); + DiffV3(p1,p7,l1); + DiffV3(p2,p4,l2); + DiffV3(p3,p5,l3); + double tmp[4]; + tmp[0]=SqNormV3(l0); tmp[1]=SqNormV3(l1); tmp[2]=SqNormV3(l2); tmp[3]=SqNormV3(l3); + return std::sqrt(*std::max_element(tmp,tmp+4)); + } + else + throw Exception("DiameterCalulatorHEXA8::ComputeForOneCellInternal : input connectivity must be of size 8 !"); +} + +void DiameterCalulatorHEXA8::computeForListOfCellIdsUMeshFrmt(const int *bgIds, const int *endIds, const int *indPtr, const int *connPtr, const double *coordsPtr, double *resPtr) const +{ + ComputeForListOfCellIdsUMeshFrmt<DiameterCalulatorHEXA8>(bgIds,endIds,indPtr,connPtr,coordsPtr,resPtr); +} + +void DiameterCalulatorHEXA8::computeForRangeOfCellIdsUMeshFrmt(int bgId, int endId, const int *indPtr, const int *connPtr, const double *coordsPtr, double *resPtr) const +{ + ComputeForRangeOfCellIdsUMeshFrmt<DiameterCalulatorHEXA8>(bgId,endId,indPtr,connPtr,coordsPtr,resPtr); +} + +void DiameterCalulatorHEXA8::computeFor1SGTUMeshFrmt(int nbOfCells, const int *connPtr, const double *coordsPtr, double *resPtr) const +{ + ComputeFor1SGTUMeshFrmt<DiameterCalulatorHEXA8>(nbOfCells,connPtr,coordsPtr,resPtr); +} + +//================================================================= + +double DiameterCalulatorHEXA20::ComputeForOneCellInternal(const int *bg, const int *endd, const double *coordsPtr) +{ + if(std::distance(bg,endd)==20) + return DiameterCalulatorHEXA8::ComputeForOneCellInternal(bg,bg+8,coordsPtr); + else + throw Exception("DiameterCalulatorHEXA20::ComputeForOneCellInternal : input connectivity must be of size 20 !"); +} + +void DiameterCalulatorHEXA20::computeForListOfCellIdsUMeshFrmt(const int *bgIds, const int *endIds, const int *indPtr, const int *connPtr, const double *coordsPtr, double *resPtr) const +{ + ComputeForListOfCellIdsUMeshFrmt<DiameterCalulatorHEXA20>(bgIds,endIds,indPtr,connPtr,coordsPtr,resPtr); +} + +void DiameterCalulatorHEXA20::computeForRangeOfCellIdsUMeshFrmt(int bgId, int endId, const int *indPtr, const int *connPtr, const double *coordsPtr, double *resPtr) const +{ + ComputeForRangeOfCellIdsUMeshFrmt<DiameterCalulatorHEXA20>(bgId,endId,indPtr,connPtr,coordsPtr,resPtr); +} + +void DiameterCalulatorHEXA20::computeFor1SGTUMeshFrmt(int nbOfCells, const int *connPtr, const double *coordsPtr, double *resPtr) const +{ + ComputeFor1SGTUMeshFrmt<DiameterCalulatorHEXA20>(nbOfCells,connPtr,coordsPtr,resPtr); +} + +//================================================================= + +double DiameterCalulatorHEXA27::ComputeForOneCellInternal(const int *bg, const int *endd, const double *coordsPtr) +{ + if(std::distance(bg,endd)==27) + return DiameterCalulatorHEXA8::ComputeForOneCellInternal(bg,bg+8,coordsPtr); + else + throw Exception("DiameterCalulatorHEXA27::ComputeForOneCellInternal : input connectivity must be of size 27 !"); +} + +void DiameterCalulatorHEXA27::computeForListOfCellIdsUMeshFrmt(const int *bgIds, const int *endIds, const int *indPtr, const int *connPtr, const double *coordsPtr, double *resPtr) const +{ + ComputeForListOfCellIdsUMeshFrmt<DiameterCalulatorHEXA27>(bgIds,endIds,indPtr,connPtr,coordsPtr,resPtr); +} + +void DiameterCalulatorHEXA27::computeForRangeOfCellIdsUMeshFrmt(int bgId, int endId, const int *indPtr, const int *connPtr, const double *coordsPtr, double *resPtr) const +{ + ComputeForRangeOfCellIdsUMeshFrmt<DiameterCalulatorHEXA27>(bgId,endId,indPtr,connPtr,coordsPtr,resPtr); +} + +void DiameterCalulatorHEXA27::computeFor1SGTUMeshFrmt(int nbOfCells, const int *connPtr, const double *coordsPtr, double *resPtr) const +{ + ComputeFor1SGTUMeshFrmt<DiameterCalulatorHEXA27>(nbOfCells,connPtr,coordsPtr,resPtr); +} + +//================================================================= + +double DiameterCalulatorPENTA6::ComputeForOneCellInternal(const int *bg, const int *endd, const double *coordsPtr) +{ + if(std::distance(bg,endd)==6) + { + const double *p0(coordsPtr+3*bg[0]),*p1(coordsPtr+3*bg[1]),*p2(coordsPtr+3*bg[2]),*p3(coordsPtr+3*bg[3]),*p4(coordsPtr+3*bg[4]),*p5(coordsPtr+3*bg[5]); + double l0[3],l1[3],l2[3],l3[3],l4[3],l5[3]; + DiffV3(p0,p4,l0); + DiffV3(p1,p3,l1); + DiffV3(p1,p5,l2); + DiffV3(p2,p4,l3); + DiffV3(p0,p5,l4); + DiffV3(p2,p3,l5); + double tmp[6]; + tmp[0]=SqNormV3(l0); tmp[1]=SqNormV3(l1); tmp[2]=SqNormV3(l2); tmp[3]=SqNormV3(l3); tmp[4]=SqNormV3(l4); tmp[5]=SqNormV3(l5); + return std::sqrt(*std::max_element(tmp,tmp+6)); + } + else + throw Exception("DiameterCalulatorPENTA6::ComputeForOneCellInternal : input connectivity must be of size 6 !"); +} + +void DiameterCalulatorPENTA6::computeForListOfCellIdsUMeshFrmt(const int *bgIds, const int *endIds, const int *indPtr, const int *connPtr, const double *coordsPtr, double *resPtr) const +{ + ComputeForListOfCellIdsUMeshFrmt<DiameterCalulatorPENTA6>(bgIds,endIds,indPtr,connPtr,coordsPtr,resPtr); +} + +void DiameterCalulatorPENTA6::computeForRangeOfCellIdsUMeshFrmt(int bgId, int endId, const int *indPtr, const int *connPtr, const double *coordsPtr, double *resPtr) const +{ + ComputeForRangeOfCellIdsUMeshFrmt<DiameterCalulatorPENTA6>(bgId,endId,indPtr,connPtr,coordsPtr,resPtr); +} + +void DiameterCalulatorPENTA6::computeFor1SGTUMeshFrmt(int nbOfCells, const int *connPtr, const double *coordsPtr, double *resPtr) const +{ + ComputeFor1SGTUMeshFrmt<DiameterCalulatorPENTA6>(nbOfCells,connPtr,coordsPtr,resPtr); +} + +//================================================================= + +double DiameterCalulatorPENTA15::ComputeForOneCellInternal(const int *bg, const int *endd, const double *coordsPtr) +{ + if(std::distance(bg,endd)==15) + return DiameterCalulatorPENTA6::ComputeForOneCellInternal(bg,bg+6,coordsPtr); + else + throw Exception("DiameterCalulatorPENTA15::ComputeForOneCellInternal : input connectivity must be of size 15 !"); +} + +void DiameterCalulatorPENTA15::computeForListOfCellIdsUMeshFrmt(const int *bgIds, const int *endIds, const int *indPtr, const int *connPtr, const double *coordsPtr, double *resPtr) const +{ + ComputeForListOfCellIdsUMeshFrmt<DiameterCalulatorPENTA15>(bgIds,endIds,indPtr,connPtr,coordsPtr,resPtr); +} + +void DiameterCalulatorPENTA15::computeForRangeOfCellIdsUMeshFrmt(int bgId, int endId, const int *indPtr, const int *connPtr, const double *coordsPtr, double *resPtr) const +{ + ComputeForRangeOfCellIdsUMeshFrmt<DiameterCalulatorPENTA15>(bgId,endId,indPtr,connPtr,coordsPtr,resPtr); +} + +void DiameterCalulatorPENTA15::computeFor1SGTUMeshFrmt(int nbOfCells, const int *connPtr, const double *coordsPtr, double *resPtr) const +{ + ComputeFor1SGTUMeshFrmt<DiameterCalulatorPENTA15>(nbOfCells,connPtr,coordsPtr,resPtr); +} + +//================================================================= + +double DiameterCalulatorPYRA5::ComputeForOneCellInternal(const int *bg, const int *endd, const double *coordsPtr) +{ + if(std::distance(bg,endd)==5) + { + const double *p0(coordsPtr+3*bg[0]),*p1(coordsPtr+3*bg[1]),*p2(coordsPtr+3*bg[2]),*p3(coordsPtr+3*bg[3]),*p4(coordsPtr+3*bg[4]); + double l0[3],l1[3],l2[3],l3[3],l4[3],l5[3]; + DiffV3(p0,p2,l0); + DiffV3(p1,p3,l1); + DiffV3(p0,p4,l2); + DiffV3(p1,p4,l3); + DiffV3(p2,p4,l4); + DiffV3(p3,p4,l5); + double tmp[6]; + tmp[0]=SqNormV3(l0); tmp[1]=SqNormV3(l1); tmp[2]=SqNormV3(l2); tmp[3]=SqNormV3(l3); tmp[4]=SqNormV3(l4); tmp[5]=SqNormV3(l5); + return std::sqrt(*std::max_element(tmp,tmp+6)); + } + else + throw Exception("DiameterCalulatorPYRA5::ComputeForOneCellInternal : input connectivity must be of size 5 !"); +} + +void DiameterCalulatorPYRA5::computeForListOfCellIdsUMeshFrmt(const int *bgIds, const int *endIds, const int *indPtr, const int *connPtr, const double *coordsPtr, double *resPtr) const +{ + ComputeForListOfCellIdsUMeshFrmt<DiameterCalulatorPYRA5>(bgIds,endIds,indPtr,connPtr,coordsPtr,resPtr); +} + +void DiameterCalulatorPYRA5::computeForRangeOfCellIdsUMeshFrmt(int bgId, int endId, const int *indPtr, const int *connPtr, const double *coordsPtr, double *resPtr) const +{ + ComputeForRangeOfCellIdsUMeshFrmt<DiameterCalulatorPYRA5>(bgId,endId,indPtr,connPtr,coordsPtr,resPtr); +} + +void DiameterCalulatorPYRA5::computeFor1SGTUMeshFrmt(int nbOfCells, const int *connPtr, const double *coordsPtr, double *resPtr) const +{ + ComputeFor1SGTUMeshFrmt<DiameterCalulatorPYRA5>(nbOfCells,connPtr,coordsPtr,resPtr); +} + +//================================================================= + +double DiameterCalulatorPYRA13::ComputeForOneCellInternal(const int *bg, const int *endd, const double *coordsPtr) +{ + if(std::distance(bg,endd)==13) + return DiameterCalulatorPYRA5::ComputeForOneCellInternal(bg,bg+5,coordsPtr); + else + throw Exception("DiameterCalulatorPYRA13::ComputeForOneCellInternal : input connectivity must be of size 13 !"); +} + +void DiameterCalulatorPYRA13::computeForListOfCellIdsUMeshFrmt(const int *bgIds, const int *endIds, const int *indPtr, const int *connPtr, const double *coordsPtr, double *resPtr) const +{ + ComputeForListOfCellIdsUMeshFrmt<DiameterCalulatorPYRA13>(bgIds,endIds,indPtr,connPtr,coordsPtr,resPtr); +} + +void DiameterCalulatorPYRA13::computeForRangeOfCellIdsUMeshFrmt(int bgId, int endId, const int *indPtr, const int *connPtr, const double *coordsPtr, double *resPtr) const +{ + ComputeForRangeOfCellIdsUMeshFrmt<DiameterCalulatorPYRA13>(bgId,endId,indPtr,connPtr,coordsPtr,resPtr); +} + +void DiameterCalulatorPYRA13::computeFor1SGTUMeshFrmt(int nbOfCells, const int *connPtr, const double *coordsPtr, double *resPtr) const +{ + ComputeFor1SGTUMeshFrmt<DiameterCalulatorPYRA13>(nbOfCells,connPtr,coordsPtr,resPtr); +} diff --git a/src/medtool/src/INTERP_KERNEL/DiameterCalculator.hxx b/src/medtool/src/INTERP_KERNEL/DiameterCalculator.hxx new file mode 100644 index 000000000..a2a0a19f1 --- /dev/null +++ b/src/medtool/src/INTERP_KERNEL/DiameterCalculator.hxx @@ -0,0 +1,315 @@ +// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 +// 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 (EDF R&D) + +#ifndef __DIAMETERCALCULATOR_HXX__ +#define __DIAMETERCALCULATOR_HXX__ + +#include "INTERPKERNELDefines.hxx" + +#include "NormalizedGeometricTypes" + +namespace INTERP_KERNEL +{ + class DiameterCalculator + { + public: + INTERPKERNEL_EXPORT virtual ~DiameterCalculator() { } + INTERPKERNEL_EXPORT virtual NormalizedCellType getType() const = 0; + INTERPKERNEL_EXPORT virtual double computeForOneCell(const int *bg, const int *endd, const double *coordsPtr) const = 0; + INTERPKERNEL_EXPORT virtual void computeForListOfCellIdsUMeshFrmt(const int *bgIds, const int *endIds, const int *indPtr, const int *connPtr, const double *coordsPtr, double *resPtr) const = 0; + INTERPKERNEL_EXPORT virtual void computeForRangeOfCellIdsUMeshFrmt(int bgId, int endId, const int *indPtr, const int *connPtr, const double *coordsPtr, double *resPtr) const = 0; + INTERPKERNEL_EXPORT virtual void computeFor1SGTUMeshFrmt(int nbOfCells, const int *connPtr, const double *coordsPtr, double *resPtr) const = 0; + }; + + class DiameterCalulatorTRI3S2 : public DiameterCalculator + { + public: + NormalizedCellType getType() const { return TYPE; } + double computeForOneCell(const int *bg, const int *endd, const double *coordsPtr) const { return ComputeForOneCellInternal(bg,endd,coordsPtr); } + static double ComputeForOneCellInternal(const int *bg, const int *endd, const double *coordsPtr); + void computeForListOfCellIdsUMeshFrmt(const int *bgIds, const int *endIds, const int *indPtr, const int *connPtr, const double *coordsPtr, double *resPtr) const; + void computeForRangeOfCellIdsUMeshFrmt(int bgId, int endId, const int *indPtr, const int *connPtr, const double *coordsPtr, double *resPtr) const; + void computeFor1SGTUMeshFrmt(int nbOfCells, const int *connPtr, const double *coordsPtr, double *resPtr) const; + public: + static NormalizedCellType TYPE; + }; + + class DiameterCalulatorTRI3S3 : public DiameterCalculator + { + public: + NormalizedCellType getType() const { return TYPE; } + double computeForOneCell(const int *bg, const int *endd, const double *coordsPtr) const { return ComputeForOneCellInternal(bg,endd,coordsPtr); } + static double ComputeForOneCellInternal(const int *bg, const int *endd, const double *coordsPtr); + void computeForListOfCellIdsUMeshFrmt(const int *bgIds, const int *endIds, const int *indPtr, const int *connPtr, const double *coordsPtr, double *resPtr) const; + void computeForRangeOfCellIdsUMeshFrmt(int bgId, int endId, const int *indPtr, const int *connPtr, const double *coordsPtr, double *resPtr) const; + void computeFor1SGTUMeshFrmt(int nbOfCells, const int *connPtr, const double *coordsPtr, double *resPtr) const; + public: + static NormalizedCellType TYPE; + }; + + class DiameterCalulatorTRI6S2 : public DiameterCalculator + { + public: + NormalizedCellType getType() const { return TYPE; } + double computeForOneCell(const int *bg, const int *endd, const double *coordsPtr) const { return ComputeForOneCellInternal(bg,endd,coordsPtr); } + static double ComputeForOneCellInternal(const int *bg, const int *endd, const double *coordsPtr); + void computeForListOfCellIdsUMeshFrmt(const int *bgIds, const int *endIds, const int *indPtr, const int *connPtr, const double *coordsPtr, double *resPtr) const; + void computeForRangeOfCellIdsUMeshFrmt(int bgId, int endId, const int *indPtr, const int *connPtr, const double *coordsPtr, double *resPtr) const; + void computeFor1SGTUMeshFrmt(int nbOfCells, const int *connPtr, const double *coordsPtr, double *resPtr) const; + public: + static NormalizedCellType TYPE; + }; + + class DiameterCalulatorTRI6S3 : public DiameterCalculator + { + public: + NormalizedCellType getType() const { return TYPE; } + double computeForOneCell(const int *bg, const int *endd, const double *coordsPtr) const { return ComputeForOneCellInternal(bg,endd,coordsPtr); } + static double ComputeForOneCellInternal(const int *bg, const int *endd, const double *coordsPtr); + void computeForListOfCellIdsUMeshFrmt(const int *bgIds, const int *endIds, const int *indPtr, const int *connPtr, const double *coordsPtr, double *resPtr) const; + void computeForRangeOfCellIdsUMeshFrmt(int bgId, int endId, const int *indPtr, const int *connPtr, const double *coordsPtr, double *resPtr) const; + void computeFor1SGTUMeshFrmt(int nbOfCells, const int *connPtr, const double *coordsPtr, double *resPtr) const; + public: + static NormalizedCellType TYPE; + }; + + class DiameterCalulatorTRI7S2 : public DiameterCalculator + { + public: + NormalizedCellType getType() const { return TYPE; } + double computeForOneCell(const int *bg, const int *endd, const double *coordsPtr) const { return ComputeForOneCellInternal(bg,endd,coordsPtr); } + static double ComputeForOneCellInternal(const int *bg, const int *endd, const double *coordsPtr); + void computeForListOfCellIdsUMeshFrmt(const int *bgIds, const int *endIds, const int *indPtr, const int *connPtr, const double *coordsPtr, double *resPtr) const; + void computeForRangeOfCellIdsUMeshFrmt(int bgId, int endId, const int *indPtr, const int *connPtr, const double *coordsPtr, double *resPtr) const; + void computeFor1SGTUMeshFrmt(int nbOfCells, const int *connPtr, const double *coordsPtr, double *resPtr) const; + public: + static NormalizedCellType TYPE; + }; + + class DiameterCalulatorTRI7S3 : public DiameterCalculator + { + public: + NormalizedCellType getType() const { return TYPE; } + double computeForOneCell(const int *bg, const int *endd, const double *coordsPtr) const { return ComputeForOneCellInternal(bg,endd,coordsPtr); } + static double ComputeForOneCellInternal(const int *bg, const int *endd, const double *coordsPtr); + void computeForListOfCellIdsUMeshFrmt(const int *bgIds, const int *endIds, const int *indPtr, const int *connPtr, const double *coordsPtr, double *resPtr) const; + void computeForRangeOfCellIdsUMeshFrmt(int bgId, int endId, const int *indPtr, const int *connPtr, const double *coordsPtr, double *resPtr) const; + void computeFor1SGTUMeshFrmt(int nbOfCells, const int *connPtr, const double *coordsPtr, double *resPtr) const; + public: + static NormalizedCellType TYPE; + }; + + class DiameterCalulatorQUAD4S2 : public DiameterCalculator + { + public: + NormalizedCellType getType() const { return TYPE; } + double computeForOneCell(const int *bg, const int *endd, const double *coordsPtr) const { return ComputeForOneCellInternal(bg,endd,coordsPtr); } + static double ComputeForOneCellInternal(const int *bg, const int *endd, const double *coordsPtr); + void computeForListOfCellIdsUMeshFrmt(const int *bgIds, const int *endIds, const int *indPtr, const int *connPtr, const double *coordsPtr, double *resPtr) const; + void computeForRangeOfCellIdsUMeshFrmt(int bgId, int endId, const int *indPtr, const int *connPtr, const double *coordsPtr, double *resPtr) const; + void computeFor1SGTUMeshFrmt(int nbOfCells, const int *connPtr, const double *coordsPtr, double *resPtr) const; + public: + static NormalizedCellType TYPE; + }; + + class DiameterCalulatorQUAD4S3 : public DiameterCalculator + { + public: + NormalizedCellType getType() const { return TYPE; } + double computeForOneCell(const int *bg, const int *endd, const double *coordsPtr) const { return ComputeForOneCellInternal(bg,endd,coordsPtr); } + static double ComputeForOneCellInternal(const int *bg, const int *endd, const double *coordsPtr); + void computeForListOfCellIdsUMeshFrmt(const int *bgIds, const int *endIds, const int *indPtr, const int *connPtr, const double *coordsPtr, double *resPtr) const; + void computeForRangeOfCellIdsUMeshFrmt(int bgId, int endId, const int *indPtr, const int *connPtr, const double *coordsPtr, double *resPtr) const; + void computeFor1SGTUMeshFrmt(int nbOfCells, const int *connPtr, const double *coordsPtr, double *resPtr) const; + public: + static NormalizedCellType TYPE; + }; + + class DiameterCalulatorQUAD8S2 : public DiameterCalculator + { + public: + NormalizedCellType getType() const { return TYPE; } + double computeForOneCell(const int *bg, const int *endd, const double *coordsPtr) const { return ComputeForOneCellInternal(bg,endd,coordsPtr); } + static double ComputeForOneCellInternal(const int *bg, const int *endd, const double *coordsPtr); + void computeForListOfCellIdsUMeshFrmt(const int *bgIds, const int *endIds, const int *indPtr, const int *connPtr, const double *coordsPtr, double *resPtr) const; + void computeForRangeOfCellIdsUMeshFrmt(int bgId, int endId, const int *indPtr, const int *connPtr, const double *coordsPtr, double *resPtr) const; + void computeFor1SGTUMeshFrmt(int nbOfCells, const int *connPtr, const double *coordsPtr, double *resPtr) const; + public: + static NormalizedCellType TYPE; + }; + + class DiameterCalulatorQUAD8S3 : public DiameterCalculator + { + public: + NormalizedCellType getType() const { return TYPE; } + double computeForOneCell(const int *bg, const int *endd, const double *coordsPtr) const { return ComputeForOneCellInternal(bg,endd,coordsPtr); } + static double ComputeForOneCellInternal(const int *bg, const int *endd, const double *coordsPtr); + void computeForListOfCellIdsUMeshFrmt(const int *bgIds, const int *endIds, const int *indPtr, const int *connPtr, const double *coordsPtr, double *resPtr) const; + void computeForRangeOfCellIdsUMeshFrmt(int bgId, int endId, const int *indPtr, const int *connPtr, const double *coordsPtr, double *resPtr) const; + void computeFor1SGTUMeshFrmt(int nbOfCells, const int *connPtr, const double *coordsPtr, double *resPtr) const; + public: + static NormalizedCellType TYPE; + }; + + class DiameterCalulatorQUAD9S2 : public DiameterCalculator + { + public: + NormalizedCellType getType() const { return TYPE; } + double computeForOneCell(const int *bg, const int *endd, const double *coordsPtr) const { return ComputeForOneCellInternal(bg,endd,coordsPtr); } + static double ComputeForOneCellInternal(const int *bg, const int *endd, const double *coordsPtr); + void computeForListOfCellIdsUMeshFrmt(const int *bgIds, const int *endIds, const int *indPtr, const int *connPtr, const double *coordsPtr, double *resPtr) const; + void computeForRangeOfCellIdsUMeshFrmt(int bgId, int endId, const int *indPtr, const int *connPtr, const double *coordsPtr, double *resPtr) const; + void computeFor1SGTUMeshFrmt(int nbOfCells, const int *connPtr, const double *coordsPtr, double *resPtr) const; + public: + static NormalizedCellType TYPE; + }; + + class DiameterCalulatorQUAD9S3 : public DiameterCalculator + { + public: + NormalizedCellType getType() const { return TYPE; } + double computeForOneCell(const int *bg, const int *endd, const double *coordsPtr) const { return ComputeForOneCellInternal(bg,endd,coordsPtr); } + static double ComputeForOneCellInternal(const int *bg, const int *endd, const double *coordsPtr); + void computeForListOfCellIdsUMeshFrmt(const int *bgIds, const int *endIds, const int *indPtr, const int *connPtr, const double *coordsPtr, double *resPtr) const; + void computeForRangeOfCellIdsUMeshFrmt(int bgId, int endId, const int *indPtr, const int *connPtr, const double *coordsPtr, double *resPtr) const; + void computeFor1SGTUMeshFrmt(int nbOfCells, const int *connPtr, const double *coordsPtr, double *resPtr) const; + public: + static NormalizedCellType TYPE; + }; + + class DiameterCalulatorTETRA4 : public DiameterCalculator + { + public: + NormalizedCellType getType() const { return TYPE; } + double computeForOneCell(const int *bg, const int *endd, const double *coordsPtr) const { return ComputeForOneCellInternal(bg,endd,coordsPtr); } + static double ComputeForOneCellInternal(const int *bg, const int *endd, const double *coordsPtr); + void computeForListOfCellIdsUMeshFrmt(const int *bgIds, const int *endIds, const int *indPtr, const int *connPtr, const double *coordsPtr, double *resPtr) const; + void computeForRangeOfCellIdsUMeshFrmt(int bgId, int endId, const int *indPtr, const int *connPtr, const double *coordsPtr, double *resPtr) const; + void computeFor1SGTUMeshFrmt(int nbOfCells, const int *connPtr, const double *coordsPtr, double *resPtr) const; + public: + static NormalizedCellType TYPE; + }; + + class DiameterCalulatorTETRA10 : public DiameterCalculator + { + public: + NormalizedCellType getType() const { return TYPE; } + double computeForOneCell(const int *bg, const int *endd, const double *coordsPtr) const { return ComputeForOneCellInternal(bg,endd,coordsPtr); } + static double ComputeForOneCellInternal(const int *bg, const int *endd, const double *coordsPtr); + void computeForListOfCellIdsUMeshFrmt(const int *bgIds, const int *endIds, const int *indPtr, const int *connPtr, const double *coordsPtr, double *resPtr) const; + void computeForRangeOfCellIdsUMeshFrmt(int bgId, int endId, const int *indPtr, const int *connPtr, const double *coordsPtr, double *resPtr) const; + void computeFor1SGTUMeshFrmt(int nbOfCells, const int *connPtr, const double *coordsPtr, double *resPtr) const; + public: + static NormalizedCellType TYPE; + }; + + class DiameterCalulatorHEXA8 : public DiameterCalculator + { + public: + NormalizedCellType getType() const { return TYPE; } + double computeForOneCell(const int *bg, const int *endd, const double *coordsPtr) const { return ComputeForOneCellInternal(bg,endd,coordsPtr); } + static double ComputeForOneCellInternal(const int *bg, const int *endd, const double *coordsPtr); + void computeForListOfCellIdsUMeshFrmt(const int *bgIds, const int *endIds, const int *indPtr, const int *connPtr, const double *coordsPtr, double *resPtr) const; + void computeForRangeOfCellIdsUMeshFrmt(int bgId, int endId, const int *indPtr, const int *connPtr, const double *coordsPtr, double *resPtr) const; + void computeFor1SGTUMeshFrmt(int nbOfCells, const int *connPtr, const double *coordsPtr, double *resPtr) const; + public: + static NormalizedCellType TYPE; + }; + + class DiameterCalulatorHEXA20 : public DiameterCalculator + { + public: + NormalizedCellType getType() const { return TYPE; } + double computeForOneCell(const int *bg, const int *endd, const double *coordsPtr) const { return ComputeForOneCellInternal(bg,endd,coordsPtr); } + static double ComputeForOneCellInternal(const int *bg, const int *endd, const double *coordsPtr); + void computeForListOfCellIdsUMeshFrmt(const int *bgIds, const int *endIds, const int *indPtr, const int *connPtr, const double *coordsPtr, double *resPtr) const; + void computeForRangeOfCellIdsUMeshFrmt(int bgId, int endId, const int *indPtr, const int *connPtr, const double *coordsPtr, double *resPtr) const; + void computeFor1SGTUMeshFrmt(int nbOfCells, const int *connPtr, const double *coordsPtr, double *resPtr) const; + public: + static NormalizedCellType TYPE; + }; + + class DiameterCalulatorHEXA27 : public DiameterCalculator + { + public: + NormalizedCellType getType() const { return TYPE; } + double computeForOneCell(const int *bg, const int *endd, const double *coordsPtr) const { return ComputeForOneCellInternal(bg,endd,coordsPtr); } + static double ComputeForOneCellInternal(const int *bg, const int *endd, const double *coordsPtr); + void computeForListOfCellIdsUMeshFrmt(const int *bgIds, const int *endIds, const int *indPtr, const int *connPtr, const double *coordsPtr, double *resPtr) const; + void computeForRangeOfCellIdsUMeshFrmt(int bgId, int endId, const int *indPtr, const int *connPtr, const double *coordsPtr, double *resPtr) const; + void computeFor1SGTUMeshFrmt(int nbOfCells, const int *connPtr, const double *coordsPtr, double *resPtr) const; + public: + static NormalizedCellType TYPE; + }; + + class DiameterCalulatorPENTA6 : public DiameterCalculator + { + public: + NormalizedCellType getType() const { return TYPE; } + double computeForOneCell(const int *bg, const int *endd, const double *coordsPtr) const { return ComputeForOneCellInternal(bg,endd,coordsPtr); } + static double ComputeForOneCellInternal(const int *bg, const int *endd, const double *coordsPtr); + void computeForListOfCellIdsUMeshFrmt(const int *bgIds, const int *endIds, const int *indPtr, const int *connPtr, const double *coordsPtr, double *resPtr) const; + void computeForRangeOfCellIdsUMeshFrmt(int bgId, int endId, const int *indPtr, const int *connPtr, const double *coordsPtr, double *resPtr) const; + void computeFor1SGTUMeshFrmt(int nbOfCells, const int *connPtr, const double *coordsPtr, double *resPtr) const; + public: + static NormalizedCellType TYPE; + }; + + class DiameterCalulatorPENTA15 : public DiameterCalculator + { + public: + NormalizedCellType getType() const { return TYPE; } + double computeForOneCell(const int *bg, const int *endd, const double *coordsPtr) const { return ComputeForOneCellInternal(bg,endd,coordsPtr); } + static double ComputeForOneCellInternal(const int *bg, const int *endd, const double *coordsPtr); + void computeForListOfCellIdsUMeshFrmt(const int *bgIds, const int *endIds, const int *indPtr, const int *connPtr, const double *coordsPtr, double *resPtr) const; + void computeForRangeOfCellIdsUMeshFrmt(int bgId, int endId, const int *indPtr, const int *connPtr, const double *coordsPtr, double *resPtr) const; + void computeFor1SGTUMeshFrmt(int nbOfCells, const int *connPtr, const double *coordsPtr, double *resPtr) const; + public: + static NormalizedCellType TYPE; + }; + + class DiameterCalulatorPYRA5 : public DiameterCalculator + { + public: + NormalizedCellType getType() const { return TYPE; } + double computeForOneCell(const int *bg, const int *endd, const double *coordsPtr) const { return ComputeForOneCellInternal(bg,endd,coordsPtr); } + static double ComputeForOneCellInternal(const int *bg, const int *endd, const double *coordsPtr); + void computeForListOfCellIdsUMeshFrmt(const int *bgIds, const int *endIds, const int *indPtr, const int *connPtr, const double *coordsPtr, double *resPtr) const; + void computeForRangeOfCellIdsUMeshFrmt(int bgId, int endId, const int *indPtr, const int *connPtr, const double *coordsPtr, double *resPtr) const; + void computeFor1SGTUMeshFrmt(int nbOfCells, const int *connPtr, const double *coordsPtr, double *resPtr) const; + public: + static NormalizedCellType TYPE; + }; + + class DiameterCalulatorPYRA13 : public DiameterCalculator + { + public: + NormalizedCellType getType() const { return TYPE; } + double computeForOneCell(const int *bg, const int *endd, const double *coordsPtr) const { return ComputeForOneCellInternal(bg,endd,coordsPtr); } + static double ComputeForOneCellInternal(const int *bg, const int *endd, const double *coordsPtr); + void computeForListOfCellIdsUMeshFrmt(const int *bgIds, const int *endIds, const int *indPtr, const int *connPtr, const double *coordsPtr, double *resPtr) const; + void computeForRangeOfCellIdsUMeshFrmt(int bgId, int endId, const int *indPtr, const int *connPtr, const double *coordsPtr, double *resPtr) const; + void computeFor1SGTUMeshFrmt(int nbOfCells, const int *connPtr, const double *coordsPtr, double *resPtr) const; + public: + static NormalizedCellType TYPE; + }; +} + +#endif diff --git a/src/medtool/src/INTERP_KERNEL/DirectedBoundingBox.cxx b/src/medtool/src/INTERP_KERNEL/DirectedBoundingBox.cxx new file mode 100644 index 000000000..113a905f1 --- /dev/null +++ b/src/medtool/src/INTERP_KERNEL/DirectedBoundingBox.cxx @@ -0,0 +1,757 @@ +// Copyright (C) 2009-2015 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, 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 +// 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 +// +// File : DirectedBoundingBox.cxx +// Created : Mon Apr 12 14:41:22 2010 +// Author : Edward AGAPOV (eap) + +#include "DirectedBoundingBox.hxx" + +#include "InterpolationUtils.hxx" + +#define __TENSOR(i,j) tensor[(i)*_dim+(j)] +#define __AXIS(i) (&_axes[(i)*_dim]) +#define __MIN(i) _minmax[i*2] +#define __MAX(i) _minmax[i*2+1] +#define __MYID (long(this)%10000) +#define __DMP(msg) \ + // cout << msg << endl + +using namespace std; + +namespace +{ + //================================================================================ + /*! + * \brief Add point coordinates to inertia tensor in 3D space + */ + //================================================================================ + + inline void addPointToInertiaTensor3D(const double* coord, + const double* gc, + vector<double>& tensor) + { + // we fill the upper triangle of tensor only + const int _dim = 3; + double x = coord[0] - gc[0], y = coord[1] - gc[1], z = coord[2] - gc[2]; + __TENSOR(0,0) += y*y + z*z; + __TENSOR(1,1) += x*x + z*z; + __TENSOR(2,2) += x*x + y*y; + __TENSOR(0,1) -= x*y; + __TENSOR(0,2) -= x*z; + __TENSOR(1,2) -= y*z; + } + //================================================================================ + /*! + * \brief Add point coordinates to inertia tensor in 2D space + */ + //================================================================================ + + inline void addPointToInertiaTensor2D(const double* coord, + const double* gc, + vector<double>& tensor) + { + // we fill the upper triangle of tensor only + const int _dim = 2; + double x = coord[0] - gc[0], y = coord[1] - gc[1]; + __TENSOR(0,0) += y*y; + __TENSOR(1,1) += x*x; + __TENSOR(0,1) -= x*y; + } + + //================================================================================ + /*! + * \brief Find eigenvectors of tensor using Jacobi's method + */ + //================================================================================ + + bool JacobiEigenvectorsSearch( const int _dim, vector<double>& tensor, vector<double>& _axes) + { + if ( _dim == 3 ) + { + __DMP( "Tensor : {" + << "{ "<<__TENSOR(0,0) << ", "<<__TENSOR(0,1) << ", "<<__TENSOR(0,2) << "} " + << "{ "<<__TENSOR(1,0) << ", "<<__TENSOR(1,1) << ", "<<__TENSOR(1,2) << "} " + << "{ "<<__TENSOR(2,0) << ", "<<__TENSOR(2,1) << ", "<<__TENSOR(2,2) << "}} "); + } + else + { + __DMP( "Tensor : {" + << "{ "<<__TENSOR(0,0) << ", "<<__TENSOR(0,1) << "} " + << "{ "<<__TENSOR(1,0) << ", "<<__TENSOR(1,1) << "}} "); + } + + const int maxRot = 5*_dim*_dim; // limit on number of rotations + const double tol = 1e-9; + + // set _axes to identity + int i,j; + for ( i = 0; i < _dim; ++i ) + for ( j = 0; j < _dim; ++j ) + __AXIS(i)[j] = ( i==j ? 1. : 0 ); + + bool solved = false; + for ( int iRot = 0; iRot < maxRot; ++ iRot ) + { + // find max off-diagonal element of the tensor + int k = 0, l = 0; + double max = 0.; + for ( i = 0; i < _dim-1; ++i ) + for ( j = i+1; j < _dim; ++j ) + if ( fabs( __TENSOR(i,j)) > max ) + max = fabs( __TENSOR(i,j) ), k = i, l = j; + solved = ( max < tol ); + if ( solved ) + break; + + // Rotate to make __TENSOR(k,l) == 0 + + double diff = __TENSOR(l,l) - __TENSOR(k,k); + double t; // tangent of rotation angle + if ( fabs(__TENSOR(k,l)) < abs(diff)*1.0e-36) + { + t = __TENSOR(k,l)/diff; + } + else + { + double phi = diff/(2.0*__TENSOR(k,l)); + t = 1.0/(abs(phi) + sqrt(phi*phi + 1.0)); + if ( phi < 0.0) t = -t; + } + double c = 1.0/sqrt(t*t + 1.0); // cosine of rotation angle + double s = t*c; // sine of rotation angle + double tau = s/(1.0 + c); + __TENSOR(k,k) -= t*__TENSOR(k,l); + __TENSOR(l,l) += t*__TENSOR(k,l); + __TENSOR(k,l) = 0.0; + +#define __ROTATE(T,r1,c1,r2,c2) \ +{ \ +int i1 = r1*_dim+c1, i2 = r2*_dim+c2; \ +double t1 = T[i1], t2 = T[i2]; \ +T[i1] -= s * ( t2 + tau * t1);\ +T[i2] += s * ( t1 - tau * t2);\ +} + for ( i = 0; i < k; ++i ) // Case of i < k + __ROTATE(tensor, i,k,i,l); + + for ( i = k+1; i < l; ++i ) // Case of k < i < l + __ROTATE(tensor, k,i,i,l); + + for ( i = l + 1; i < _dim; ++i ) // Case of i > l + __ROTATE(tensor, k,i,l,i); + + for ( i = 0; i < _dim; ++i ) // Update transformation matrix + __ROTATE(_axes, i,k,i,l); + } + + __DMP( "Solved = " << solved ); + if ( _dim == 3 ) { + __DMP( " Eigen " << __TENSOR(0,0)<<", "<<__TENSOR(1,1)<<", "<<__TENSOR(2,2) ); + for ( int ii=0; ii <3; ++ii ) + __DMP( ii << ": " << __AXIS(ii)[0] << ", " << __AXIS(ii)[1] << ", " << __AXIS(ii)[2] ); + } + else { + __DMP( " Eigen " << __TENSOR(0,0) << ", " << __TENSOR(1,1) ); + for ( int ii=0; ii <2; ++ii ) + __DMP( ii << ": " << __AXIS(ii)[0] << ", " << __AXIS(ii)[1] ); + } + + return solved; + } + + //================================================================================ + /*! + * \brief Return true if two minmaxes do not intersect + */ + //================================================================================ + + inline bool isMinMaxOut(const double* minmax1, + const double* minmax2, + int dim) + { + for ( int i = 0; i < dim; ++i ) + { + if ( minmax1[i*2] > minmax2[i*2+1] || + minmax1[i*2+1] < minmax2[i*2] ) + return true; + } + return false; + } + +} // noname namespace + +namespace INTERP_KERNEL +{ + + //================================================================================ + /*! + * \brief Creates empty box intended to further initalization via setData() + */ + //================================================================================ + + DirectedBoundingBox::DirectedBoundingBox():_dim(0) + { + } + + //================================================================================ + /*! + * \brief Creates bounding box of a mesh + * \param pts - coordinates of points in full interlace + * \param numPts - number of points in the mesh + * \param dim - space dimension + */ + //================================================================================ + + DirectedBoundingBox::DirectedBoundingBox(const double* pts, + const unsigned numPts, + const unsigned dim) + : _dim(dim), _axes(dim*dim), _minmax(2*dim) + { + // init box extremities + for ( unsigned i = 0; i < _dim; ++i ) + _minmax[1+i*2] = -numeric_limits<double>::max(), + _minmax[i*2] = numeric_limits<double>::max(); + + if ( numPts < 1 ) return; + + __DMP( "DirectedBoundingBox " << __MYID ); + + const double* coord = pts; + const double* coordEnd = coord + numPts * dim; + + // compute gravity center of points + double gc[3] = {0,0,0}; + if ( dim > 1 ) + { + for ( coord = pts; coord < coordEnd; ) + for ( int i = 0; i < (int)dim; ++i ) + gc[i] += *coord++; + for ( int j = 0; j < (int)dim; ++j ) + gc[j] /= numPts; + + } + + // compute axes and box extremities + vector<double> tensor( dim * dim, 0.); + switch ( dim ) + { + case 3: + for ( coord = pts; coord < coordEnd; coord += dim ) + addPointToInertiaTensor3D( coord, gc, tensor ); + + //computeAxes3D(tensor); + JacobiEigenvectorsSearch(_dim, tensor, _axes); + + for ( coord = pts; coord < coordEnd; coord += dim ) + addPointToBox( coord ); + + break; + + case 2: + for ( coord = pts; coord < coordEnd; coord += dim ) + addPointToInertiaTensor2D( coord, gc, tensor ); + + //computeAxes2D(tensor); + JacobiEigenvectorsSearch(_dim, tensor, _axes); + + for ( coord = pts; coord < coordEnd; coord += dim ) + addPointToBox( coord ); + + break; + + default: + for ( coord = pts; coord < coordEnd; coord += dim ) + { + if ( *coord < _minmax[0] ) _minmax[0] = *coord; + if ( *coord > _minmax[1] ) _minmax[1] = *coord; + } + } + } + + //================================================================================ + /*! + * \brief Creates bounding box of an element + * \param pts - coordinates of points of element + * \param numPts - number of points in the element + * \param dim - space dimension + */ + //================================================================================ + + DirectedBoundingBox::DirectedBoundingBox(const double** pts, + const unsigned numPts, + const unsigned dim) + : _dim(dim), _axes(dim*dim), _minmax(2*dim) + { + // init box extremities + for ( unsigned i = 0; i < _dim; ++i ) + _minmax[1+i*2] = -numeric_limits<double>::max(), + _minmax[i*2] = numeric_limits<double>::max(); + + if ( numPts < 1 ) return; + + __DMP( "DirectedBoundingBox " << __MYID ); + + // compute gravity center of points + double gc[3] = {0,0,0}; + if ( dim > 1 ) + { + for ( unsigned i = 0; i < numPts; ++i ) + for ( int j = 0; j < (int)dim; ++j ) + gc[j] += pts[i][j]; + for ( int j = 0; j < (int)dim; ++j ) + gc[j] /= numPts; + } + + // compute axes and box extremities + vector<double> tensor( dim * dim, 0.); + switch ( dim ) + { + case 3: + for ( unsigned i = 0; i < numPts; ++i ) + addPointToInertiaTensor3D( pts[i], gc, tensor ); + + //computeAxes3D(tensor); + JacobiEigenvectorsSearch(_dim, tensor, _axes); + + for ( unsigned i = 0; i < numPts; ++i ) + addPointToBox( pts[i] ); + + break; + case 2: + for ( unsigned i = 0; i < numPts; ++i ) + addPointToInertiaTensor2D( pts[i], gc, tensor ); + + //computeAxes2D(tensor); + JacobiEigenvectorsSearch(_dim, tensor, _axes); + + for ( unsigned i = 0; i < numPts; ++i ) + addPointToBox( pts[i] ); + + break; + default: + for ( unsigned i = 0; i < numPts; ++i ) + { + if ( pts[i][0] < _minmax[0] ) _minmax[0] = pts[i][0]; + if ( pts[i][0] > _minmax[1] ) _minmax[1] = pts[i][0]; + } + _axes[0] = 1.0; + } + } + + //================================================================================ + /*! + * \brief Compute eigenvectors of inertia tensor + */ + //================================================================================ + + // void DirectedBoundingBox::computeAxes3D(const std::vector<double>& tensor) +// { +// // compute principal moments of inertia which are eigenvalues of the tensor +// double eig[3]; +// { +// // coefficients of polynomial equation det(tensor-eig*I) = 0 +// double a = -1; +// double b = __TENSOR(0,0)+__TENSOR(1,1)+__TENSOR(2,2); +// double c = +// __TENSOR(0,1)*__TENSOR(0,1) + +// __TENSOR(0,2)*__TENSOR(0,2) + +// __TENSOR(1,2)*__TENSOR(1,2) - +// __TENSOR(0,0)*__TENSOR(1,1) - +// __TENSOR(0,0)*__TENSOR(2,2) - +// __TENSOR(1,1)*__TENSOR(2,2); +// double d = +// __TENSOR(0,0)*__TENSOR(1,1)*__TENSOR(2,2) - +// __TENSOR(0,0)*__TENSOR(1,2)*__TENSOR(1,2) - +// __TENSOR(1,1)*__TENSOR(0,2)*__TENSOR(0,2) - +// __TENSOR(2,2)*__TENSOR(0,1)*__TENSOR(0,1) + +// __TENSOR(0,1)*__TENSOR(0,2)*__TENSOR(1,2)*2; + +// // find eigenvalues which are roots of characteristic polynomial +// double x = (3*c/a - b*b/(a*a))/3; +// double y = (2*b*b*b/(a*a*a) - 9*b*c/(a*a) + 27*d/a)/27; +// double z = y*y/4 + x*x*x/27; + +// double i = sqrt(y*y/4 - z) + 1e-300; +// double j = -pow(i,1/3.); +// double y2 = -y/(2*i); +// if ( y2 > 1.0) y2 = 1.; else if ( y2 < -1.0) y2 = -1.; +// double k = acos(y2); +// double m = cos(k/3); +// double n = sqrt(3)*sin(k/3); +// double p = -b/(3*a); + +// eig[0] = -2*j*m + p; +// eig[1] = j *(m + n) + p; +// eig[2] = j *(m - n) + p; +// } +// // compute eigenvector of the tensor at each eigenvalue +// // by solving system [tensor-eig*I]*[axis] = 0 +// bool ok = true; +// __DMP( "Tensor : {" +// << "{ "<<__TENSOR(0,0) << ", "<<__TENSOR(0,1) << ", "<<__TENSOR(0,2) << "} " +// << "{ "<<__TENSOR(1,0) << ", "<<__TENSOR(1,1) << ", "<<__TENSOR(1,2) << "} " +// << "{ "<<__TENSOR(2,0) << ", "<<__TENSOR(2,1) << ", "<<__TENSOR(2,2) << "}} "); +// for ( int i = 0; i < 3 && ok; ++i ) // loop on 3 eigenvalues +// { +// // [tensor-eig*I] +// double T[3][3]= +// {{ __TENSOR(0,0)-eig[i],__TENSOR(0,1), __TENSOR(0,2), }, +// { __TENSOR(0,1), __TENSOR(1,1)-eig[i],__TENSOR(1,2), }, +// { __TENSOR(0,2), __TENSOR(1,2), __TENSOR(2,2)-eig[i]}}; +// // The determinant of T is zero, so that the equations are not linearly independent. +// // Therefore, we assign an arbitrary value (1.) to i-th component of eigenvector +// // and use two of the equations to compute the other two components +// double M[2][3], sol[2]; +// for ( int j = 0, c = 0; j < 3; ++j ) +// if ( i == j ) +// M[0][2] = -T[0][j], M[1][2] = -T[1][j]; +// else +// M[0][c] = T[0][j], M[1][c] = T[1][j], c++; + +// ok = solveSystemOfEquations<2>( M, sol ); + +// double* eigenVec = __AXIS(i); +// for ( int j = 0, c = 0; j < 3; ++j ) +// eigenVec[j] = ( i == j ) ? 1. : sol[c++]; + +// // normilize +// double size = sqrt(eigenVec[0]*eigenVec[0] + +// eigenVec[1]*eigenVec[1] + +// eigenVec[2]*eigenVec[2] ); +// if ((ok = (size > numeric_limits<double>::min() ))) +// { +// eigenVec[0] /= size; +// eigenVec[1] /= size; +// eigenVec[2] /= size; +// } +// } +// if ( !ok ) +// { +// __DMP( " solve3EquationSystem() - KO " ); +// _axes = vector<double>( _dim*_dim, 0); +// __AXIS(0)[0] = __AXIS(1)[1] = __AXIS(2)[2] = 1.; +// } +// __DMP( " Eigen " << eig[0] << ", " << eig[1] << ", " << eig[2] ); +// for ( int i=0; i <3; ++i ) +// __DMP( i << ": " << __AXIS(i)[0] << ", " << __AXIS(i)[1] << ", " << __AXIS(i)[2] ); + +// double* a0 = __AXIS(0), *a1 = __AXIS(1); +// double cross[3] = { a0[1]*a1[2]-a1[1]*a0[2], +// a0[2]*a1[0]-a1[2]*a0[0], +// a0[0]*a1[1]-a1[0]*a0[1] }; +// __DMP( " Cross a1^a2 " << cross[0] << ", " << cross[1] << ", " << cross[2] ); +// } + + //================================================================================ + /*! + * \brief Compute eigenvectors of inertia tensor + */ + //================================================================================ + + // void DirectedBoundingBox::computeAxes2D(const std::vector<double>& tensor) +// { +// // compute principal moments of inertia which are eigenvalues of the tensor +// // by solving square equation det(tensor-eig*I) +// double X = (__TENSOR(0,0)+__TENSOR(1,1))/2; +// double Y = sqrt(4*__TENSOR(0,1)*__TENSOR(0,1) + +// (__TENSOR(0,0)-__TENSOR(1,1)) * (__TENSOR(0,0)-__TENSOR(1,1)))/2; +// double eig[2] = +// { +// X + Y, +// X - Y +// }; +// // compute eigenvector of the tensor at each eigenvalue +// // by solving system [tensor-eig*I]*[axis] = 0 +// bool ok = true; +// for ( int i = 0; i < 2 && ok; ++i ) +// { +// // [tensor-eig*I] +// double T[2][2]= +// {{ __TENSOR(0,0)-eig[i],__TENSOR(0,1) }, +// { __TENSOR(0,1), __TENSOR(1,1)-eig[i] }}; + +// // The determinant of T is zero, so that the equations are not linearly independent. +// // Therefore, we assign an arbitrary value (1.) to i-th component of eigenvector +// // and use one equation to compute the other component +// double* eigenVec = __AXIS(i); +// eigenVec[i] = 1.; +// int j = 1-i; +// if ((ok = ( fabs( T[j][j] ) > numeric_limits<double>::min() ))) +// eigenVec[j] = -T[j][i] / T[j][j]; +// } +// if ( !ok ) +// { +// _axes = vector<double>( _dim*_dim, 0); +// __AXIS(0)[0] = __AXIS(1)[1] = 1.; +// } +// } + + //================================================================================ + /*! + * \brief Convert point coordinates into local coordinate system of the box + */ + //================================================================================ + + void DirectedBoundingBox::toLocalCS(const double* p, double* pLoc) const + { + switch ( _dim ) + { + case 3: + pLoc[0] = dotprod<3>( p, __AXIS(0)); + pLoc[1] = dotprod<3>( p, __AXIS(1)); + pLoc[2] = dotprod<3>( p, __AXIS(2)); + break; + case 2: + pLoc[0] = dotprod<2>( p, __AXIS(0)); + pLoc[1] = dotprod<2>( p, __AXIS(1)); + break; + default: + pLoc[0] = p[0]; + } + } + + //================================================================================ + /*! + * \brief Convert point coordinates from local coordinate system of the box to global CS + */ + //================================================================================ + + void DirectedBoundingBox::fromLocalCS(const double* p, double* pGlob) const + { + switch ( _dim ) + { + case 3: + pGlob[0] = p[0] * __AXIS(0)[0] + p[1] * __AXIS(1)[0] + p[2] * __AXIS(2)[0]; + pGlob[1] = p[0] * __AXIS(0)[1] + p[1] * __AXIS(1)[1] + p[2] * __AXIS(2)[1]; + pGlob[2] = p[0] * __AXIS(0)[2] + p[1] * __AXIS(1)[2] + p[2] * __AXIS(2)[2]; + break; + case 2: + pGlob[0] = p[0] * __AXIS(0)[0] + p[1] * __AXIS(1)[0]; + pGlob[1] = p[0] * __AXIS(0)[1] + p[1] * __AXIS(1)[1]; + break; + default: + pGlob[0] = p[0]; + } + } + + //================================================================================ + /*! + * \brief Enlarge box size by given value + */ + //================================================================================ + + void DirectedBoundingBox::enlarge(const double tol) + { + for ( unsigned i = 0; i < _dim; ++i ) + __MIN(i) -= tol, __MAX(i) += tol; + } + + //================================================================================ + /*! + * \brief Return coordinates of corners of bounding box + */ + //================================================================================ + + void DirectedBoundingBox::getCorners(std::vector<double>& corners, + const double* minmax) const + { + int iC, nbCorners = 1; + for ( int i=0;i<(int)_dim;++i ) nbCorners *= 2; + corners.resize( nbCorners * _dim ); + // each coordinate is filled with either min or max, nbSwap is number of corners + // after which min and max swap + int nbSwap = nbCorners/2; + for ( unsigned i = 0; i < _dim; ++i ) + { + iC = 0; + while ( iC < nbCorners ) + { + for (int j = 0; j < nbSwap; ++j, ++iC ) corners[iC*_dim+i] = minmax[i*2]; + for (int j = 0; j < nbSwap; ++j, ++iC ) corners[iC*_dim+i] = minmax[i*2+1]; + } + nbSwap /= 2; + } + } + + //================================================================================ + /*! + * \brief Test if this box intersects with the other + * \retval bool - true if there is no intersection + */ + //================================================================================ + + bool DirectedBoundingBox::isDisjointWith(const DirectedBoundingBox& box) const + { + if ( _dim < 1 || box._dim < 1 ) return false; // empty box includes all + if ( _dim == 1 ) + return isMinMaxOut( &box._minmax[0], &this->_minmax[0], _dim ); + + // boxes are disjoined if their minmaxes in local CS of either of boxes do not intersect + for ( int isThisCS = 0; isThisCS < 2; ++isThisCS ) + { + const DirectedBoundingBox* axisBox = isThisCS ? this : &box; + const DirectedBoundingBox* cornerBox = isThisCS ? &box : this; + + // find minmax of cornerBox in the CS of axisBox + + DirectedBoundingBox mmBox((double*)0,0,_dim); //!< empty box with CS == axisBox->_axes + mmBox._axes = axisBox->_axes; + + vector<double> corners; + getCorners( corners, &cornerBox->_minmax[0] ); + + double globCorner[3]; + for ( int iC = 0, nC = corners.size()/_dim; iC < nC; ++iC) + { + cornerBox->fromLocalCS( &corners[iC*_dim], globCorner ); + mmBox.addPointToBox( globCorner ); + } + if ( isMinMaxOut( &mmBox._minmax[0], &axisBox->_minmax[0], _dim )) + return true; + } + return false; + } + + //================================================================================ + /*! + * \brief Test if this box intersects with an non-directed box + * \retval bool - true if there is no intersection + */ + //================================================================================ + + bool DirectedBoundingBox::isDisjointWith(const double* box) const + { + if ( _dim < 1 ) return false; // empty box includes all + if ( _dim == 1 ) + return isMinMaxOut( &_minmax[0], box, _dim ); + + // boxes are disjoined if their minmaxes in local CS of either of boxes do not intersect + + // compare minmaxes in locals CS of this directed box + { + vector<double> cornersOther; + getCorners( cornersOther, box ); + DirectedBoundingBox mmBox((double*)0,0,_dim); //!< empty box with CS == this->_axes + mmBox._axes = this->_axes; + for ( int iC = 0, nC = cornersOther.size()/_dim; iC < nC; ++iC) + mmBox.addPointToBox( &cornersOther[iC*_dim] ); + + if ( isMinMaxOut( &mmBox._minmax[0], &this->_minmax[0], _dim )) + return true; + } + + // compare minmaxes in global CS + { + vector<double> cornersThis; + getCorners( cornersThis, &_minmax[0] ); + DirectedBoundingBox mmBox((double*)0,0,_dim); //!< initailized _minmax + double globCorner[3]; + for ( int iC = 0, nC = cornersThis.size()/_dim; iC < nC; ++iC) + { + fromLocalCS( &cornersThis[iC*_dim], globCorner ); + for ( int i = 0; i < (int)_dim; ++i ) + { + if ( globCorner[i] < mmBox._minmax[i*2] ) mmBox._minmax[i*2] = globCorner[i]; + if ( globCorner[i] > mmBox._minmax[i*2+1] ) mmBox._minmax[i*2+1] = globCorner[i]; + } + } + if ( isMinMaxOut( &mmBox._minmax[0], box, _dim )) + return true; + } + return false; + } + + //================================================================================ + /*! + * \brief Return true if given point is out of this box + */ + //================================================================================ + + bool DirectedBoundingBox::isOut(const double* point) const + { + if ( _dim < 1 ) return false; // empty box includes all + + double pLoc[3]; + toLocalCS( point, pLoc ); + bool out = isLocalOut( pLoc ); +#ifdef _DEBUG_ + switch (_dim) + { + case 3: + __DMP(__MYID<<": "<<point[0]<<", "<<point[1]<<", "<<point[2]<<" "<<(out?"OUT":"IN"));break; + case 2: + __DMP(__MYID<<": "<<point[0]<<", "<<point[1]<<" "<<(out?"OUT":"IN"));break; + case 1: + __DMP(__MYID<<": "<<point[0]<<" "<<(out?"OUT":"IN"));break; + } +#endif + return out; + } + + //================================================================================ + /*! + * \brief Return array of internal data + */ + //================================================================================ + + vector<double> DirectedBoundingBox::getData() const + { + vector<double> data(1, _dim); + if ( _dim > 0 ) + { + data.insert( data.end(), &_axes[0], &_axes[0] + _axes.size()); + data.insert( data.end(), &_minmax[0], &_minmax[0] + _minmax.size()); + } + if ( data.size() < (unsigned)dataSize( _dim )) + data.resize( dataSize( _dim ), 0 ); + return data; + } + + //================================================================================ + /*! + * \brief Initializes self with data retrieved via getData() + */ + //================================================================================ + + void DirectedBoundingBox::setData(const double* data) + { + _dim = unsigned( *data++ ); + if ( _dim > 0 ) + { + _axes.assign( data, data+_dim*_dim ); data += _dim*_dim; + _minmax.assign( data, data+2*_dim ); + } + else + { + _axes.clear(); + _minmax.clear(); + } + } + + //================================================================================ + /*! + * \brief Return size of internal data returned by getData() depending on space dim + */ + //================================================================================ + + int DirectedBoundingBox::dataSize(int dim) + { + return 1 + dim*dim + 2*dim; // : _dim + _axes + _minmax + } +} diff --git a/src/medtool/src/INTERP_KERNEL/DirectedBoundingBox.hxx b/src/medtool/src/INTERP_KERNEL/DirectedBoundingBox.hxx new file mode 100644 index 000000000..50501cd17 --- /dev/null +++ b/src/medtool/src/INTERP_KERNEL/DirectedBoundingBox.hxx @@ -0,0 +1,119 @@ +// Copyright (C) 2009-2015 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, 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 +// 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 __DIRECTEDBOUNDINGBOX_HXX__ +#define __DIRECTEDBOUNDINGBOX_HXX__ + +#include "INTERPKERNELDefines.hxx" + +#include <vector> + +namespace INTERP_KERNEL +{ + + /** + * \brief Class representing the bounding box of a number of points + * with box axes parallel to principal axes of inertia of points + */ + class DirectedBoundingBox + { + public: + + INTERPKERNEL_EXPORT DirectedBoundingBox(); + + INTERPKERNEL_EXPORT DirectedBoundingBox(const double* pts, const unsigned numPts, const unsigned dim); + + INTERPKERNEL_EXPORT DirectedBoundingBox(const double** pts, const unsigned numPts, const unsigned dim); + + //~DirectedBoundingBox(); + + INTERPKERNEL_EXPORT void enlarge(const double tol); + + INTERPKERNEL_EXPORT bool isDisjointWith(const DirectedBoundingBox& box) const; + + INTERPKERNEL_EXPORT bool isDisjointWith(const double* box) const; + + INTERPKERNEL_EXPORT bool isOut(const double* point) const; + + + // return internal data + INTERPKERNEL_EXPORT std::vector<double> getData() const; + + // initialize with data returned by getData() + INTERPKERNEL_EXPORT void setData(const double* data); + + // return size of internal data + INTERPKERNEL_EXPORT static int dataSize(int dim); + + private: + + //void computeAxes3D(const std::vector<double>& tensor); + + //void computeAxes2D(const std::vector<double>& tensor); + + inline void addPointToBox(const double* coord); + + void toLocalCS(const double* p, double* pLoc) const; + + void fromLocalCS(const double* p, double* pGlob) const; + + inline bool isLocalOut(const double* pLoc) const; + + void getCorners(std::vector<double>& corners, const double* minmax) const; + + unsigned _dim; + + std::vector<double> _axes; //!< principal axes of inertia in full interlace + std::vector<double> _minmax; //!< pairs of min an max coordinates along the axes + + }; + + //================================================================================ + /*! + * \brief Test point in local CS against box extremities + * + */ + //================================================================================ + + inline bool DirectedBoundingBox::isLocalOut(const double* pLoc) const + { + for ( int i = 0; i < (int)_dim; ++i ) + if ( pLoc[i] < _minmax[i*2] || pLoc[i] > _minmax[i*2+1] ) + return true; + return false; + } + + //================================================================================ + /*! + * \brief Update box extremities + */ + //================================================================================ + + inline void DirectedBoundingBox::addPointToBox(const double* coord) + { + for ( int i = 0; i < (int)_dim; ++i ) + { + double c = 0; + for ( int j = 0; j < (int)_dim; ++j ) c += coord[j]*_axes[i*_dim+j]; + if ( c < _minmax[i*2] ) _minmax[i*2] = c; + if ( c > _minmax[i*2+1] ) _minmax[i*2+1] = c; + } + } +} +#endif diff --git a/src/medtool/src/INTERP_KERNEL/ExprEval/InterpKernelAsmX86.cxx b/src/medtool/src/INTERP_KERNEL/ExprEval/InterpKernelAsmX86.cxx new file mode 100644 index 000000000..aaeeabf14 --- /dev/null +++ b/src/medtool/src/INTERP_KERNEL/ExprEval/InterpKernelAsmX86.cxx @@ -0,0 +1,495 @@ +// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 +// 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 "InterpKernelAsmX86.hxx" + +#include <cstring> +#include <sstream> +#include <algorithm> + +#ifdef _POSIX_MAPPED_FILES +#include <sys/mman.h> +#else +#ifdef WIN32 +#include <windows.h> +#endif +#endif + +const char *INTERP_KERNEL::AsmX86::OPS[NB_OF_OPS]={"mov","push","pop","fld","faddp","fsubp","fmulp","fdivp","fcos","fsin","fabs","fchs","fsqrt","sub","add","ret","leave","movsd","fst"}; + +std::vector<char> INTERP_KERNEL::AsmX86::convertIntoMachineLangage(const std::vector<std::string>& asmb) const +{ + std::vector<char> ret; + for(std::vector<std::string>::const_iterator iter=asmb.begin();iter!=asmb.end();iter++) + convertOneInstructionInML(*iter,ret); + return ret; +} + +char *INTERP_KERNEL::AsmX86::copyToExecMemZone(const std::vector<char>& ml, unsigned& offset) const +{ + char *ret=0; + int lgth=ml.size(); +#ifdef _POSIX_MAPPED_FILES + ret=(char *)mmap(0,lgth,PROT_EXEC | PROT_WRITE,MAP_ANONYMOUS | MAP_PRIVATE,-1,0); +#else +#ifdef WIN32 + HANDLE h=CreateFileMapping(INVALID_HANDLE_VALUE,NULL,PAGE_EXECUTE_READWRITE,0,lgth,NULL); + ret=(char *)MapViewOfFile(h,FILE_MAP_EXECUTE | FILE_MAP_READ | FILE_MAP_WRITE,0,0,lgth); +#endif +#endif + if(ret) + std::copy(ml.begin(),ml.end(),ret); + return ret; +} + +void INTERP_KERNEL::AsmX86::convertOneInstructionInML(const std::string& inst, std::vector<char>& ml) const +{ + std::string::size_type pos=inst.find_first_of(' '); + std::string op; + std::string param; + if(pos!=std::string::npos) + { + op=inst.substr(0,pos); + param=inst.substr(pos+1); + } + else + op=inst; + int id=0; + for(const char **it=OPS;it!=OPS+NB_OF_OPS;it++,id++) + { + std::string tmp(*it); + if(op==tmp) + break; + } + switch(id) + { + case 0: + convertMov(param,ml); + break; + case 1: + convertPush(param,ml); + break; + case 2: + convertPop(param,ml); + break; + case 3: + convertFld(param,ml); + break; + case 4: + convertFaddp(param,ml); + break; + case 5: + convertFsubp(param,ml); + break; + case 6: + convertFmulp(param,ml); + break; + case 7: + convertFdivp(param,ml); + break; + case 8: + convertFcos(param,ml); + break; + case 9: + convertFsin(param,ml); + break; + case 10: + convertFabs(param,ml); + break; + case 11: + convertFchs(param,ml); + break; + case 12: + convertFsqrt(param,ml); + break; + case 13: + convertSub(param,ml); + break; + case 14: + convertAdd(param,ml); + break; + case 15: + convertRet(param,ml); + break; + case 16: + convertLeave(param,ml); + break; + case 17: + convertMovsd(param,ml); + break; + case 18: + convertFst(param,ml); + break; + default: + { + std::ostringstream oss; oss << "Unrecognized op : " << op << " in assembly line : " << inst; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + } +} + +#include <iostream> + +void INTERP_KERNEL::AsmX86::convertMov(const std::string& inst, std::vector<char>& ml) +{ + const char ASM1[]="ebp,esp"; + const unsigned char ML1[2]={0x89,0xe5}; + if(inst==ASM1) + { + ml.insert(ml.end(),ML1,ML1+sizeof(ML1)); + return ; + } + const char ASM2[]="rbp,rsp"; + const unsigned char ML2[3]={0x48,0x89,0xe5}; + if(inst==ASM2) + { + ml.insert(ml.end(),ML2,ML2+sizeof(ML2)); + return ; + } + std::string::size_type pos=inst.find_first_of(' '); + if(pos==std::string::npos) + { + std::ostringstream oss; oss << "not recognized instruction mov : " << inst; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + std::string inst2=inst.substr(pos+1); + pos=inst2.find_first_of(','); + if(pos==std::string::npos) + { + std::ostringstream oss; oss << "not recognized instruction mov : " << inst; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + std::string inst3=inst2.substr(0,pos); + std::string inst4=inst2.substr(pos+1); + convertMovToEsp(inst3,inst4,ml); +} + +void INTERP_KERNEL::AsmX86::convertMovToEsp(const std::string& inst1, const std::string& inst2, std::vector<char>& ml) +{ + if(inst1[0]!='[' || inst1[inst1.length()-1]!=']') + throw INTERP_KERNEL::Exception("not recognized convertMovToEsp exp !"); + std::string inst1bis=inst1.substr(1,inst1.length()-2); + const char ASM1[]="esp"; + const unsigned char ML1[3]={0xc7,0x04,0x24}; + if(inst1bis==ASM1) + {//mov dword [esp],0x3ff3c0ca + ml.insert(ml.end(),ML1,ML1+sizeof(ML1)); + appendAddress(inst2,4,ml); + return ; + } + if(inst1bis.substr(0,3)==ASM1) + { + if(inst1bis[3]=='+') + {//mov dword [esp+4],0x3ff3c0ca + const unsigned char ML2[3]={0xc7,0x44,0x24}; + ml.insert(ml.end(),ML2,ML2+sizeof(ML2)); + std::string::size_type pos=inst1bis.find_first_of(']'); + std::string inst1_1=inst1bis.substr(4,pos-4-1); + appendAddress(inst1_1,1,ml); + appendAddress(inst2,4,ml); + return; + } + else + throw INTERP_KERNEL::Exception("Not recognized exp : mov [esp@..],..."); + } + const char ASM3[]="rsp"; + const unsigned char ML3[3]={0xc7,0x04,0x24}; + if(inst1bis==ASM3) + {//mov dword [rsp],0x3ff3c0ca + ml.insert(ml.end(),ML3,ML3+sizeof(ML3)); + appendAddress(inst2,4,ml); + return ; + } + if(inst1bis.substr(0,3)==ASM3) + { + if(inst1bis[3]=='+') + {//mov dword [rsp+4],0x3ff3c0ca + const unsigned char ML2[3]={0xc7,0x44,0x24}; + ml.insert(ml.end(),ML2,ML2+sizeof(ML2)); + std::string::size_type pos=inst1bis.find_first_of(']'); + std::string inst1_1=inst1bis.substr(4,pos-4-1); + appendAddress(inst1_1,1,ml); + appendAddress(inst2,4,ml); + return; + } + else + throw INTERP_KERNEL::Exception("Not recognized exp : mov [esp@..],..."); + } + throw INTERP_KERNEL::Exception("Not recognized exp : mov"); +} + +void INTERP_KERNEL::AsmX86::convertPush(const std::string& inst, std::vector<char>& ml) +{ + std::string::size_type pos=inst.find_first_of(' '); + std::string inst2=inst.substr(pos+1); + const char ASM1[]="ebp"; + const unsigned char ML1[1]={0x55}; + if(inst2==ASM1) + {//push ebp + ml.insert(ml.end(),ML1,ML1+sizeof(ML1)); + return ; + } + const char ASM2[]="ebx"; + const unsigned char ML2[1]={0x53}; + if(inst2==ASM2) + {//push ebx + ml.insert(ml.end(),ML2,ML2+sizeof(ML2)); + return ; + } + const char ASM3[]="rbp"; + const unsigned char ML3[1]={0x55}; + if(inst2==ASM3) + {//push rbp + ml.insert(ml.end(),ML3,ML3+sizeof(ML3)); + return ; + } + throw INTERP_KERNEL::Exception("Unrecognized push instruction"); +} + +void INTERP_KERNEL::AsmX86::convertPop(const std::string& inst, std::vector<char>& ml) +{ + std::string::size_type pos=inst.find_first_of(' '); + std::string inst2=inst.substr(pos+1); + const char ASM1[]="ebp"; + const unsigned char ML1[1]={0x5d}; + if(inst2==ASM1) + {//push ebp + ml.insert(ml.end(),ML1,ML1+sizeof(ML1)); + return ; + } + const char ASM2[]="ebx"; + const unsigned char ML2[1]={0x5b}; + if(inst2==ASM2) + {//push ebx + ml.insert(ml.end(),ML2,ML2+sizeof(ML2)); + return ; + } + throw INTERP_KERNEL::Exception("Unrecognized pop instruction"); +} + +void INTERP_KERNEL::AsmX86::convertFld(const std::string& inst, std::vector<char>& ml) +{ + std::string::size_type pos=inst.find_first_of(' '); + std::string params=inst.substr(pos+1); + std::string params2=params.substr(1,params.length()-2); + if(params2.substr(0,3)=="esp") + { + const unsigned char ML1[3]={0xdd,0x04,0x24}; + if(params2.length()==3) + {//fld qword [esp] + ml.insert(ml.end(),ML1,ML1+sizeof(ML1)); + return ; + } + pos=params2.find_first_of('+'); + if(pos!=std::string::npos) + {//fld qword [esp+@] + ml.insert(ml.end(),ML1,ML1+sizeof(ML1)); + std::string params3=params2.substr(pos+1); + appendAddress(params3,1,ml); + return ; + } + throw INTERP_KERNEL::Exception("Unrecognized fld esp..."); + } + if(params2.substr(0,3)=="ebp") + { + const unsigned char ML2[2]={0xdd,0x45}; + if(params2.length()==3) + {//fld qword [ebp] + ml.insert(ml.end(),ML2,ML2+sizeof(ML2)); + ml.push_back(0); + return ; + } + pos=params2.find_first_of('+'); + if(pos!=std::string::npos) + {//fld qword [esp+@] + ml.insert(ml.end(),ML2,ML2+sizeof(ML2)); + std::string params3=params2.substr(pos+1); + appendAddress(params3,1,ml); + return ; + } + throw INTERP_KERNEL::Exception("Unrecognized fld ebp..."); + } + if(params2.substr(0,3)=="rsp") + { + const unsigned char ML2[3]={0xdd,0x04,0x24}; + ml.insert(ml.end(),ML2,ML2+sizeof(ML2));// to improve ! no fully managed ! + return ; + } + throw INTERP_KERNEL::Exception("Unrecognized fld instruction"); +} + +void INTERP_KERNEL::AsmX86::convertFaddp(const std::string& inst, std::vector<char>& ml) +{ + const unsigned char ML1[2]={0xde,0xc1}; + ml.insert(ml.end(),ML1,ML1+sizeof(ML1)); +} + +void INTERP_KERNEL::AsmX86::convertFsubp(const std::string& inst, std::vector<char>& ml) +{ + const unsigned char ML1[2]={0xde,0xe9}; + ml.insert(ml.end(),ML1,ML1+sizeof(ML1)); +} + +void INTERP_KERNEL::AsmX86::convertFmulp(const std::string& inst, std::vector<char>& ml) +{ + const unsigned char ML1[2]={0xde,0xc9}; + ml.insert(ml.end(),ML1,ML1+sizeof(ML1)); +} + +void INTERP_KERNEL::AsmX86::convertFdivp(const std::string& inst, std::vector<char>& ml) +{ + const unsigned char ML1[2]={0xde,0xf9}; + ml.insert(ml.end(),ML1,ML1+sizeof(ML1)); +} + +void INTERP_KERNEL::AsmX86::convertFcos(const std::string& inst, std::vector<char>& ml) +{ + const unsigned char ML[2]={0xd9,0xff}; + ml.insert(ml.end(),ML,ML+sizeof(ML)); +} + +void INTERP_KERNEL::AsmX86::convertFsin(const std::string& inst, std::vector<char>& ml) +{ + const unsigned char ML[2]={0xd9,0xfe}; + ml.insert(ml.end(),ML,ML+sizeof(ML)); +} + +void INTERP_KERNEL::AsmX86::convertFabs(const std::string& inst, std::vector<char>& ml) +{ + const unsigned char ML[2]={0xd9,0xe1}; + ml.insert(ml.end(),ML,ML+sizeof(ML)); +} + +void INTERP_KERNEL::AsmX86::convertFchs(const std::string& inst, std::vector<char>& ml) +{ + const unsigned char ML[2]={0xd9,0xe0}; + ml.insert(ml.end(),ML,ML+sizeof(ML)); +} + +void INTERP_KERNEL::AsmX86::convertFsqrt(const std::string& inst, std::vector<char>& ml) +{ + const unsigned char ML[2]={0xd9,0xfa}; + ml.insert(ml.end(),ML,ML+sizeof(ML)); +} + +void INTERP_KERNEL::AsmX86::convertSub(const std::string& inst, std::vector<char>& ml) +{ + if(inst.substr(0,4)=="esp,") + { + const unsigned char ML[2]={0x81,0xec}; + ml.insert(ml.end(),ML,ML+sizeof(ML)); + std::string inst2=inst.substr(4); + appendAddress(inst2,4,ml); + return; + } + if(inst.substr(0,4)=="rsp,") + { + const unsigned char ML[4]={0x48,0x83,0xec,0x08}; + ml.insert(ml.end(),ML,ML+sizeof(ML)); // to improve 8 statically put (last of element of ML) !!!! + return; + } + throw INTERP_KERNEL::Exception("Not recognized sub instruction."); +} + +void INTERP_KERNEL::AsmX86::convertAdd(const std::string& inst, std::vector<char>& ml) +{ + if(inst.substr(0,4)=="esp,") + { + const unsigned char ML[2]={0x81,0xc4}; + ml.insert(ml.end(),ML,ML+sizeof(ML)); + std::string inst2=inst.substr(4); + appendAddress(inst2,4,ml); + return; + } + if(inst.substr(0,4)=="rsp,") + { + const unsigned char ML[4]={0x48,0x83,0xc4,0x08}; + ml.insert(ml.end(),ML,ML+sizeof(ML)); // to improve 8 statically put (last of element of ML) !!!! + return; + } + throw INTERP_KERNEL::Exception("Not recognized add instruction."); +} + +void INTERP_KERNEL::AsmX86::convertRet(const std::string& inst, std::vector<char>& ml) +{ + const unsigned char ML[1]={0xc3}; + ml.insert(ml.end(),ML,ML+sizeof(ML)); +} + +void INTERP_KERNEL::AsmX86::convertLeave(const std::string& inst, std::vector<char>& ml) +{ + const unsigned char ML[1]={0xc9}; + ml.insert(ml.end(),ML,ML+sizeof(ML)); +} + +void INTERP_KERNEL::AsmX86::convertMovsd(const std::string& inst, std::vector<char>& ml) +{ + const char ASM1[]="[rsp],xmm0"; + const unsigned char ML1[5]={0xf2,0x0f,0x11,0x04,0x24}; + if(inst==ASM1) + { + ml.insert(ml.end(),ML1,ML1+sizeof(ML1)); + return ; + } + const char ASM2[]="xmm0,[rsp]"; + const unsigned char ML2[5]={0xf2,0x0f,0x10,0x04,0x24}; + if(inst==ASM2) + { + ml.insert(ml.end(),ML2,ML2+sizeof(ML2)); + return ; + } + std::ostringstream oss; oss << "not recognized instruction movsd : " << inst; + throw INTERP_KERNEL::Exception(oss.str().c_str()); +} + +void INTERP_KERNEL::AsmX86::convertFst(const std::string& inst, std::vector<char>& ml) +{ + const char ASM1[]="qword [rsp]"; + const unsigned char ML1[3]={0xdd,0x14,0x24}; + if(inst==ASM1) + { + ml.insert(ml.end(),ML1,ML1+sizeof(ML1)); + return ; + } + std::ostringstream oss; oss << "not recognized instruction fst : " << inst; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + //tony +} + + +void INTERP_KERNEL::AsmX86::appendAddress(const std::string& addr, int nbOfByte, std::vector<char>& ml) +{ + int i,j; + char v; + std::istringstream iss(addr); + if(addr.length()>2) + { + if(addr[0]=='0' && addr[1]=='x') + iss >> std::hex; + } + iss >> i; + for(int k=0;k<nbOfByte;k++) + { + j=i&255; + v=j; + ml.push_back(v); + i>>=8; + } +} diff --git a/src/medtool/src/INTERP_KERNEL/ExprEval/InterpKernelAsmX86.hxx b/src/medtool/src/INTERP_KERNEL/ExprEval/InterpKernelAsmX86.hxx new file mode 100644 index 000000000..7620686a2 --- /dev/null +++ b/src/medtool/src/INTERP_KERNEL/ExprEval/InterpKernelAsmX86.hxx @@ -0,0 +1,68 @@ +// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 +// 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 __INTERPKERNELASMX86_HXX__ +#define __INTERPKERNELASMX86_HXX__ + +#include "INTERPKERNELDefines.hxx" +#include "InterpKernelException.hxx" + +#include <vector> +#include <string> + +namespace INTERP_KERNEL +{ + class AsmX86 + { + public: + std::vector<char> convertIntoMachineLangage(const std::vector<std::string>& asmb) const; + char *copyToExecMemZone(const std::vector<char>& ml, unsigned& offset) const; + private: + void convertOneInstructionInML(const std::string& inst, std::vector<char>& ml) const; + private: + static void convertMov(const std::string& inst, std::vector<char>& ml); + static void convertPush(const std::string& inst, std::vector<char>& ml); + static void convertPop(const std::string& inst, std::vector<char>& ml); + static void convertFld(const std::string& inst, std::vector<char>& ml); + static void convertFaddp(const std::string& inst, std::vector<char>& ml); + static void convertFsubp(const std::string& inst, std::vector<char>& ml); + static void convertFmulp(const std::string& inst, std::vector<char>& ml); + static void convertFdivp(const std::string& inst, std::vector<char>& ml); + static void convertFcos(const std::string& inst, std::vector<char>& ml); + static void convertFsin(const std::string& inst, std::vector<char>& ml); + static void convertFabs(const std::string& inst, std::vector<char>& ml); + static void convertFchs(const std::string& inst, std::vector<char>& ml); + static void convertFsqrt(const std::string& inst, std::vector<char>& ml); + static void convertSub(const std::string& inst, std::vector<char>& ml); + static void convertAdd(const std::string& inst, std::vector<char>& ml); + static void convertRet(const std::string& inst, std::vector<char>& ml); + static void convertLeave(const std::string& inst, std::vector<char>& ml); + static void convertMovsd(const std::string& inst, std::vector<char>& ml); + static void convertFst(const std::string& inst, std::vector<char>& ml); + // + static void convertMovToEsp(const std::string& inst1, const std::string& inst2, std::vector<char>& ml); + static void appendAddress(const std::string& addr, int nbOfByte, std::vector<char>& ml); + private: + static const int NB_OF_OPS=19; + static const char *OPS[NB_OF_OPS]; + }; +} + +#endif diff --git a/src/medtool/src/INTERP_KERNEL/ExprEval/InterpKernelExprParser.cxx b/src/medtool/src/INTERP_KERNEL/ExprEval/InterpKernelExprParser.cxx new file mode 100644 index 000000000..e1cce1a91 --- /dev/null +++ b/src/medtool/src/INTERP_KERNEL/ExprEval/InterpKernelExprParser.cxx @@ -0,0 +1,1201 @@ +// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 +// 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 "InterpKernelExprParser.hxx" +#include "InterpKernelValue.hxx" +#include "InterpKernelAsmX86.hxx" +#include "InterpKernelAutoPtr.hxx" + +#include <cctype> +#include <sstream> +#include <limits> +#include <vector> +#include <iterator> +#include <iostream> +#include <algorithm> + +using namespace INTERP_KERNEL; + +const char LeafExprVar::END_OF_RECOGNIZED_VAR[]="Vec"; + +const char ExprParser::WHITE_SPACES[]=" \n"; + +const char ExprParser::EXPR_PARSE_ERR_MSG[]="Invalid expression detected : "; + +LeafExpr *LeafExpr::buildInstanceFrom(const std::string& expr) +{ + std::istringstream stream; + stream.str(expr); + double val; + stream >> val; + if(!stream.fail()) + if(stream.eof()) + return new LeafExprVal(val); + else + { + std::ostringstream errMsg; + char MSGTYP6[]="Error following expression is not consedered as a double value : "; + errMsg << MSGTYP6 << expr; + throw INTERP_KERNEL::Exception(errMsg.str().c_str()); + } + else + return new LeafExprVar(expr); +} + +LeafExpr::~LeafExpr() +{ +} + +LeafExprVal::LeafExprVal(double value):_value(value) +{ +} + +LeafExprVal::~LeafExprVal() +{ +} + +void LeafExprVal::fillValue(Value *val) const +{ + val->setDouble(_value); +} + +void LeafExprVal::replaceValues(const std::vector<double>& valuesInExpr) +{ + int pos=(int)_value; + int lgth=(int)valuesInExpr.size(); + if(pos>=lgth || pos<0) + throw INTERP_KERNEL::Exception("LeafExprVal::replaceValues : Big Problem detected ! Send expression to Salome support with expression !"); + _value=valuesInExpr[pos]; +} + +LeafExprVal *LeafExprVal::deepCpy() const +{ + return new LeafExprVal(*this); +} + +LeafExprVar::LeafExprVar(const std::string& var):_fast_pos(-1),_var_name(var),_val(0) +{ +} + +void LeafExprVar::fillValue(Value *val) const +{ + if(_val) + val->setDouble(_val[_fast_pos]); + else + val->setVarname(_fast_pos,_var_name); + +} + +void LeafExprVar::prepareExprEvaluation(const std::vector<std::string>& vars, int nbOfCompo, int targetNbOfCompo) const +{ + std::vector<std::string>::const_iterator iter=std::find(vars.begin(),vars.end(),_var_name); + if(iter==vars.end()) + { + if(!isRecognizedKeyVar(_var_name,_fast_pos)) + { + std::ostringstream oss; oss << "Var : " << _var_name << " not in : "; + std::copy(vars.begin(),vars.end(),std::ostream_iterator<std::string>(oss,", ")); + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + else + { + int relPos=-7-_fast_pos; + if(relPos>=targetNbOfCompo) + { + std::ostringstream oss; oss << "LeafExprVar::prepareExprEvaluation : Found recognized unitary vector \"" << _var_name << "\" which implies that component #" << relPos; + oss << " exists, but it is not the case component id should be in [0," << targetNbOfCompo << ") !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + else + return; + } + } + _fast_pos=(int)std::distance(vars.begin(),iter); + if(_fast_pos>=nbOfCompo) + { + std::ostringstream oss; oss << "LeafExprVar::prepareExprEvaluation : Found var \"" << _var_name << "\" on place " << _fast_pos << " whereas only must be in [0," << nbOfCompo << ") !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } +} + +/*! + * \param [in] vars - the sorted list of vars + * \param [in] nbOfCompo - the size of the input tuples (it is used to scan if no problem occurs) + * \param [in] targetNbOfCompo - the size of the output tuple (it is used to check that no problem occurs) + * \param [in] refPos - is an integer in [0,targetNbOfCompo), that tell the id of \a this. It is for multi interpreters. + * \sa evaluateDouble + */ +void LeafExprVar::prepareExprEvaluationDouble(const std::vector<std::string>& vars, int nbOfCompo, int targetNbOfCompo, int refPos, const double *ptOfInputStart, const double *ptOfInputEnd) const +{ + if((int)vars.size()!=std::distance(ptOfInputStart,ptOfInputEnd)) + throw INTERP_KERNEL::Exception("LeafExprVar::prepareExprEvaluationDouble : size of input vector must be equal to the input vector !"); + prepareExprEvaluation(vars,nbOfCompo,targetNbOfCompo); + _ref_pos=refPos; + _val=ptOfInputStart; +} + +void LeafExprVar::prepareExprEvaluationVec() const +{ + if(!isRecognizedKeyVar(_var_name,_fast_pos)) + _fast_pos=-2; +} + +bool LeafExprVar::isRecognizedKeyVar(const std::string& var, int& pos) +{ + if(var.length()!=sizeof(END_OF_RECOGNIZED_VAR)) + return false; + std::string end=var.substr(1); + if(end!=END_OF_RECOGNIZED_VAR) + return false; + char first=var[0]; + if(first<'I' || first>'Z') + return false; + pos=-7-(first-'I'); + return true; +} + +LeafExprVar *LeafExprVar::deepCpy() const +{ + return new LeafExprVar(*this); +} + +/*! + * Nothing to do it is not a bug. + */ +void LeafExprVar::replaceValues(const std::vector<double>& valuesInExpr) +{ +} + +LeafExprVar::~LeafExprVar() +{ +} + +void ExprParserOfEval::clearSortedMemory() +{ + delete _leaf; + for(std::vector<ExprParserOfEval>::iterator it=_sub_parts.begin();it!=_sub_parts.end();it++) + (*it).clearSortedMemory(); + for(std::vector<Function *>::iterator it=_funcs.begin();it!=_funcs.end();it++) + delete *it; +} + +void ExprParserOfEval::sortMemory() +{ + for(std::vector<ExprParserOfEval>::iterator it=_sub_parts.begin();it!=_sub_parts.end();it++) + (*it).sortMemory(); + if(_leaf) + _leaf=_leaf->deepCpy(); + for(std::vector<Function *>::iterator it=_funcs.begin();it!=_funcs.end();it++) + if(*it) + *it=(*it)->deepCpy(); +} + +ExprParser::ExprParser(const std::string& expr, ExprParser *father):_father(father),_is_parsed(false),_leaf(0),_is_parsing_ok(false),_expr(expr) +{ + _expr=deleteWhiteSpaces(_expr); +} + +//! For \b NOT null terminated strings coming from FORTRAN. +ExprParser::ExprParser(const char *expr, int lgth, ExprParser *father):_father(father),_is_parsed(false),_leaf(0),_is_parsing_ok(false) +{ + _expr=buildStringFromFortran(expr,lgth); + _expr=deleteWhiteSpaces(_expr); +} + +ExprParser::~ExprParser() +{ + delete _leaf; + _for_eval.clearSortedMemory(); + releaseFunctions(); +} + +std::size_t ExprParser::FindCorrespondingOpenBracket(const std::string& expr, std::size_t posOfCloseBracket) +{ + int level=0; + for(std::size_t iter=0;iter<posOfCloseBracket;iter++) + { + std::size_t iter2=posOfCloseBracket-1-iter; + if(expr[iter2]==')') + level++; + else if(expr[iter2]=='(') + { + if(level==0) + return iter2; + else + level--; + } + } + return std::string::npos; +} + +std::string ExprParser::buildStringFromFortran(const char *expr, int lgth) +{ + std::string ret(expr,lgth); + std::string whiteSpaces(WHITE_SPACES); + std::size_t found=ret.find_last_not_of(whiteSpaces); + if (found!=std::string::npos) + ret.erase(found+1); + else + ret.clear();//ret is all whitespace + return ret; +} + +std::string ExprParser::deleteWhiteSpaces(const std::string& expr) +{ + std::string ret(expr); + std::string whiteSpaces(WHITE_SPACES); + std::size_t where1=0,where2=0; + while(where2!=std::string::npos && where1!=std::string::npos) + { + where1=ret.find_first_of(whiteSpaces.c_str(),where1,whiteSpaces.length()); + if(where1!=std::string::npos) + { + where2=ret.find_first_not_of(whiteSpaces,where1); + if(where2!=std::string::npos) + ret.erase(ret.begin()+where1,ret.begin()+where2); + else + ret.erase(ret.begin()+where1,ret.end()); + } + } + return ret; +} + +void ExprParser::parse() +{ + _is_parsed=true; + _is_parsing_ok=false; + _sub_expr.clear(); + releaseFunctions(); + if(!_expr.empty()) + { + std::string tmp(_expr); + std::vector<double> valuesInExpr; + fillValuesInExpr(valuesInExpr); + checkBracketsParity(); + if(!simplify()) + parseDeeper(); + replaceValues(valuesInExpr); + _expr=tmp; + } + reverseThis(); + _is_parsing_ok=true; +} + +double ExprParser::evaluate() const +{ + AutoCppPtr<Value> gen(new ValueDouble); + AutoCppPtr<ValueDouble> res(static_cast<ValueDouble *>(evaluateLowLev(gen))); + return res->getData(); +} + +DecompositionInUnitBase ExprParser::evaluateUnit() const +{ + Value *gen=new ValueUnit; + ValueUnit *res=0; + try + { + res=(ValueUnit *)evaluateLowLev(gen); + } + catch(INTERP_KERNEL::Exception& e) + { + delete gen; + throw e; + } + delete gen; + DecompositionInUnitBase ret=res->getData(); + delete res; + return ret; +} + +void ExprParser::evaluateExpr(int szOfOutParam, const double *inParam, double *outParam) const +{ + AutoCppPtr<Value> gen(new ValueDoubleExpr(szOfOutParam,inParam)); + AutoCppPtr<ValueDoubleExpr> res(static_cast<ValueDoubleExpr *>(evaluateLowLev(gen))); + std::copy(res->getData(),res->getData()+szOfOutParam,outParam); +} + +void ExprParser::prepareExprEvaluation(const std::vector<std::string>& vars, int nbOfCompo, int targetNbOfCompo) const +{ + if(_leaf) + { + LeafExprVar *leafC=dynamic_cast<LeafExprVar *>(_leaf); + if(leafC) + leafC->prepareExprEvaluation(vars,nbOfCompo,targetNbOfCompo); + } + else + for(std::vector<ExprParser>::const_iterator iter=_sub_expr.begin();iter!=_sub_expr.end();iter++) + (*iter).prepareExprEvaluation(vars,nbOfCompo,targetNbOfCompo); +} + +/*! + * \param [in] vars - the sorted list of vars + * \param [in] nbOfCompo - the size of the input tuples (it is used to scan if no problem occurs) + * \param [in] targetNbOfCompo - the size of the output tuple (it is used to check that no problem occurs) + * \param [in] refPos - is an integer in [0,targetNbOfCompo), that tell the id of \a this. It is for multi interpreters. + * \sa evaluateDouble + */ +void ExprParser::prepareExprEvaluationDouble(const std::vector<std::string>& vars, int nbOfCompo, int targetNbOfCompo, int refPos, const double *ptOfInputStart, const double *ptOfInputEnd) const +{ + if((int)vars.size()!=std::distance(ptOfInputStart,ptOfInputEnd)) + throw INTERP_KERNEL::Exception("ExprParser::prepareExprEvaluationDouble : size of input vector must be equal to the input vector !"); + if(_leaf) + { + LeafExprVar *leafC=dynamic_cast<LeafExprVar *>(_leaf); + if(leafC) + leafC->prepareExprEvaluationDouble(vars,nbOfCompo,targetNbOfCompo,refPos,ptOfInputStart,ptOfInputEnd); + } + else + for(std::vector<ExprParser>::const_iterator iter=_sub_expr.begin();iter!=_sub_expr.end();iter++) + (*iter).prepareExprEvaluationDouble(vars,nbOfCompo,targetNbOfCompo,refPos,ptOfInputStart,ptOfInputEnd); +} + +void ExprParser::prepareFastEvaluator() const +{ + _for_eval.clearSortedMemory(); + _for_eval=convertMeTo(); + _for_eval.sortMemory(); +} + +/*! + * \sa prepareExprEvaluationDouble + */ +double ExprParser::evaluateDouble() const +{ + checkForEvaluation(); + std::vector<double> stackOfVal; + evaluateDoubleInternal(stackOfVal); + return stackOfVal.back(); +} + +void ExprParser::checkForEvaluation() const +{ + if(!_is_parsing_ok) + throw INTERP_KERNEL::Exception("checkForEvaluation : Parsing fails ! Invalid expression !"); + if(_sub_expr.empty() && !_leaf) + throw INTERP_KERNEL::Exception("checkForEvaluation : Empty expression !"); +} + +void ExprParser::prepareExprEvaluationVec() const +{ + std::set<std::string> trueVars; + getTrueSetOfVars(trueVars); + if(trueVars.size()>1) + { + std::ostringstream oss; oss << "For this type of evaluation only one not keyword variable authorized : "; + oss << "having " << trueVars.size() << " : "; + std::copy(trueVars.begin(),trueVars.end(),std::ostream_iterator<std::string>(oss," ")); oss << " !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + prepareExprEvaluationVecLowLev(); +} + +void ExprParser::prepareExprEvaluationVecLowLev() const +{ + if(_leaf) + { + LeafExprVar *leafC=dynamic_cast<LeafExprVar *>(_leaf); + if(leafC) + leafC->prepareExprEvaluationVec(); + } + else + for(std::vector<ExprParser>::const_iterator iter=_sub_expr.begin();iter!=_sub_expr.end();iter++) + (*iter).prepareExprEvaluationVecLowLev(); +} + +Value *ExprParser::evaluateLowLev(Value *valGen) const +{ + checkForEvaluation(); + std::vector<Value *> stackOfVal; + try + { + if(_leaf) + { + Value *ret=valGen->newInstance(); + try + { + _leaf->fillValue(ret); + } + catch(INTERP_KERNEL::Exception& e) + { + delete ret; + throw e; + } + stackOfVal.resize(1); + stackOfVal[0]=ret; + } + else + { + stackOfVal.resize(_sub_expr.size()); + std::vector<Value *>::iterator iter2=stackOfVal.begin(); + for(std::vector<ExprParser>::const_iterator iter=_sub_expr.begin();iter!=_sub_expr.end();iter++,iter2++) + *iter2=(*iter).evaluateLowLev(valGen); + } + for(std::vector<Function *>::const_iterator iter3=_func_btw_sub_expr.begin();iter3!=_func_btw_sub_expr.end();iter3++) + (*iter3)->operate(stackOfVal); + } + catch(INTERP_KERNEL::Exception& e) + { + for(std::vector<Value *>::iterator iter4=stackOfVal.begin();iter4!=stackOfVal.end();iter4++) + delete *iter4; + throw e; + } + return stackOfVal.back(); +} + +void ExprParser::reverseThis() +{ + if(_leaf) + return ; + for(std::vector<ExprParser>::iterator iter=_sub_expr.begin();iter!=_sub_expr.end();iter++) + (*iter).reverseThis(); + AutoPtr<char> buf(new char[sizeof(ExprParser)]); + char *loc(reinterpret_cast<char *>(&_sub_expr[0])),*bufPtr(buf); + std::size_t sz(_sub_expr.size()); + std::size_t nbOfTurn(sz/2); + for(std::size_t i=0;i<nbOfTurn;i++) + { + std::copy(loc+i*sizeof(ExprParser),loc+(i+1)*sizeof(ExprParser),bufPtr); + std::copy(loc+(sz-i-1)*sizeof(ExprParser),loc+(sz-i)*sizeof(ExprParser),loc+i*sizeof(ExprParser)); + std::copy(bufPtr,bufPtr+sizeof(ExprParser),loc+(sz-i-1)*sizeof(ExprParser)); + } +} + +ExprParserOfEval ExprParser::convertMeTo() const +{ + std::size_t sz(_sub_expr.size()); + std::vector<ExprParserOfEval> subExpr(sz); + for(std::size_t i=0;i<sz;i++) + subExpr[i]=_sub_expr[i].convertMeTo(); + return ExprParserOfEval(_leaf,subExpr,_func_btw_sub_expr); +} + +void ExprParser::getSetOfVars(std::set<std::string>& vars) const +{ + if(_leaf) + { + LeafExprVar *leafC=dynamic_cast<LeafExprVar *>(_leaf); + if(leafC) + vars.insert(leafC->getVar()); + } + else + for(std::vector<ExprParser>::const_iterator iter=_sub_expr.begin();iter!=_sub_expr.end();iter++) + (*iter).getSetOfVars(vars); +} + +void ExprParser::getTrueSetOfVars(std::set<std::string>& trueVars) const +{ + std::set<std::string> vars; + getSetOfVars(vars); + trueVars.clear(); + for(std::set<std::string>::const_iterator iter=vars.begin();iter!=vars.end();iter++) + { + int tmp; + if(!LeafExprVar::isRecognizedKeyVar(*iter,tmp)) + trueVars.insert(*iter); + } +} + +void ExprParser::parseDeeper() +{ + for(std::vector<ExprParser>::iterator iter=_sub_expr.begin();iter!=_sub_expr.end();iter++) + if(!(*iter).simplify()) + (*iter).parseDeeper(); +} + +/*! + * This method has the responsability to see if this->_expr can be seen as a unary function of something. + * Something defined as the contain of highest level barckets. + * Typically '(3*x+2)' and 'cos(4*l+p*n)' will be intercepted by this method whereas '3*x+2' not...etc.. + */ +void ExprParser::parseUnaryFunc() +{ + if(_expr[_expr.length()-1]!=')') + return ; + //at this level of code _expr + std::size_t pos1=_expr.find_first_of('('); + std::size_t pos4=FindCorrespondingOpenBracket(_expr,_expr.length()-1); + if(pos4!=pos1) + return ; + std::string funcName=_expr.substr(0,pos1); + std::size_t pos2=funcName.find_first_of("+-*/^><",0,7); + std::size_t pos3=funcName.find_first_not_of("+-*/^><",0,7); + if(pos2!=std::string::npos && pos3!=std::string::npos) + return ;//Bracket group is not alone, can't conclude not recursively. + std::string newExp2=_expr.substr(pos1+1,_expr.length()-pos1-2); + std::size_t nbOfParamsInFunc=std::count(newExp2.begin(),newExp2.end(),',')+1; + if(pos3!=std::string::npos) + _func_btw_sub_expr.push_back(FunctionsFactory::buildFuncFromString(funcName.c_str(),(int)nbOfParamsInFunc)); + else + { + std::size_t lgth=funcName.length(); + char tmp[2]; tmp[1]='\0'; + for(std::size_t i=0;i<lgth;i++) + { + tmp[0]=funcName[i]; + _func_btw_sub_expr.push_back(FunctionsFactory::buildFuncFromString(tmp,(int)nbOfParamsInFunc)); + } + } + std::size_t pos6=0; + for(std::size_t i=0;i<nbOfParamsInFunc;i++) + { + std::size_t pos5=newExp2.find_first_of(',',pos6); + std::size_t len=std::string::npos; + if(pos5!=std::string::npos) + len=pos5-pos6; + std::string newExp3=newExp2.substr(pos6,len); + _sub_expr.push_back(ExprParser(newExp3.c_str(),this)); + pos6=pos5+1; + } + _is_parsing_ok=true; +} + +/*! + * This method has the responsability to see if this->_expr is interpretable without any recursion. + * \return true if no recursion needed, false if this->_expr is too complex to be interpreted at this level. + * \throw exception if this->_expr is simple enough to try to interprate this and this expression contains an error. + */ +bool ExprParser::tryToInterpALeaf() +{ + std::size_t pos=_expr.find_first_not_of("+-",0,2); + std::string minimizedExpr=_expr.substr(pos); + std::size_t pos2=minimizedExpr.find_first_of("+-*/^()<>",0,9); + if(pos2!=std::string::npos) + return false; + delete _leaf; + _leaf=LeafExpr::buildInstanceFrom(minimizedExpr); + int nbOfNegs=0; + for(std::size_t i=0;i<pos;i++) + if(_expr[i]=='-') + nbOfNegs++; + if(nbOfNegs%2) + _func_btw_sub_expr.push_back(FunctionsFactory::buildUnaryFuncFromString("-")); + _is_parsing_ok=true; + return true; +} + +void ExprParser::parseForCmp() +{ + std::string::const_iterator iter; + int curLevel=0; + std::string curPart; + bool isParsingSucceed=false; + for(iter=_expr.begin();iter!=_expr.end();iter++) + { + switch(*iter) + { + case '>': + case '<': + { + isParsingSucceed=true; + if(!curPart.empty()) + { + _sub_expr.push_back(ExprParser(curPart.c_str(),this)); + curPart.clear(); + _func_btw_sub_expr.push_back(FunctionsFactory::buildBinaryFuncFromString(*iter)); + } + else + { + std::ostringstream errMsg; + char MSGTYP1[]="Error non unary function for '"; + errMsg << EXPR_PARSE_ERR_MSG << MSGTYP1 << *iter << "'"; + std::string tmp=_expr.substr(iter-_expr.begin()); + LocateError(errMsg,tmp,0); + throw INTERP_KERNEL::Exception(errMsg.str().c_str()); + } + break; + } + case '(': + curLevel++; + curPart+=*iter; + break; + case ')': + curLevel--; + curPart+=*iter; + break; + default: + curPart+=*iter; + } + } + if(isParsingSucceed) + { + if(!curPart.empty()) + { + _sub_expr.push_back(ExprParser(curPart.c_str(),this)); + _is_parsing_ok=true; + } + else + { + std::ostringstream errMsg; + char MSGTYP4[]="Error following expression finished by > / < without right part."; + errMsg << EXPR_PARSE_ERR_MSG << MSGTYP4 << _expr; + throw INTERP_KERNEL::Exception(errMsg.str().c_str()); + } + } +} + +void ExprParser::parseForAddMin() +{ + std::string::const_iterator iter; + int curLevel=0; + std::string curPart; + bool isParsingSucceed=false; + for(iter=_expr.begin();iter!=_expr.end();iter++) + { + switch(*iter) + { + case '+': + case '-': + if(curLevel!=0) + curPart+=*iter; + else + { + if(!curPart.empty()) + { + std::string::reverse_iterator accessor=curPart.rbegin(); + if(*accessor!='*' && *accessor!='/' && *accessor!='^') + { + isParsingSucceed=true; + _sub_expr.push_back(ExprParser(curPart.c_str(),this)); + curPart.clear(); + _func_btw_sub_expr.push_back(FunctionsFactory::buildBinaryFuncFromString(*iter)); + } + else + curPart+=*iter; + } + else + curPart+=*iter; + } + break; + case '(': + curLevel++; + curPart+=*iter; + break; + case ')': + curLevel--; + curPart+=*iter; + break; + default: + curPart+=*iter; + } + } + if(isParsingSucceed) + { + if(!curPart.empty()) + { + _sub_expr.push_back(ExprParser(curPart.c_str(),this)); + _is_parsing_ok=true; + } + else + { + std::ostringstream errMsg; + char MSGTYP4[]="Error following expression finished by +/- without right part."; + errMsg << EXPR_PARSE_ERR_MSG << MSGTYP4 << _expr; + throw INTERP_KERNEL::Exception(errMsg.str().c_str()); + } + } +} + +void ExprParser::parseForMulDiv() +{ + std::string::const_iterator iter; + int curLevel=0; + std::string curPart; + bool isParsingSucceed=false; + for(iter=_expr.begin();iter!=_expr.end();iter++) + { + switch(*iter) + { + case '/': + case '*': + if(curLevel!=0) + curPart+=*iter; + else + { + isParsingSucceed=true; + if(!curPart.empty()) + { + _sub_expr.push_back(ExprParser(curPart.c_str(),this)); + curPart.clear(); + _func_btw_sub_expr.push_back(FunctionsFactory::buildBinaryFuncFromString(*iter)); + } + else + { + std::ostringstream errMsg; + char MSGTYP1[]="Error non unary function for '"; + errMsg << EXPR_PARSE_ERR_MSG << MSGTYP1 << *iter << "'"; + std::string tmp=_expr.substr(iter-_expr.begin()); + LocateError(errMsg,tmp,0); + throw INTERP_KERNEL::Exception(errMsg.str().c_str()); + } + } + break; + case '(': + curLevel++; + curPart+=*iter; + break; + case ')': + curLevel--; + curPart+=*iter; + break; + default: + curPart+=*iter; + } + } + if(isParsingSucceed) + { + if(!curPart.empty()) + { + _sub_expr.push_back(ExprParser(curPart.c_str(),this)); + _is_parsing_ok=true; + } + else + { + std::ostringstream errMsg; + char MSGTYP5[]="Error following expression finished by *// without right part."; + errMsg << EXPR_PARSE_ERR_MSG << MSGTYP5 << _expr; + throw INTERP_KERNEL::Exception(errMsg.str().c_str()); + } + } +} + +void ExprParser::parseForPow() +{ + std::string::const_iterator iter; + int curLevel=0; + std::string curPart; + bool isParsingSucceed=false; + for(iter=_expr.begin();iter!=_expr.end();iter++) + { + switch(*iter) + { + case '^': + if(curLevel!=0) + curPart+=*iter; + else + if(!curPart.empty()) + { + isParsingSucceed=true; + _sub_expr.push_back(ExprParser(curPart.c_str(),this)); + curPart.clear(); + _func_btw_sub_expr.push_back(FunctionsFactory::buildBinaryFuncFromString(*iter)); + } + else + { + std::ostringstream errMsg; + char MSGTYP1[]="Error non unary function for '"; + errMsg << EXPR_PARSE_ERR_MSG << MSGTYP1 << *iter << "'"; + std::string tmp=_expr.substr(iter-_expr.begin()); + LocateError(errMsg,tmp,0);curPart+=*iter; + throw INTERP_KERNEL::Exception(errMsg.str().c_str()); + } + break; + case '(': + curLevel++; + curPart+=*iter; + break; + case ')': + curLevel--; + curPart+=*iter; + break; + default: + curPart+=*iter; + } + } + if(isParsingSucceed) + { + if(!curPart.empty()) + { + _sub_expr.push_back(ExprParser(curPart.c_str(),this)); + _is_parsing_ok=true; + } + else + { + std::ostringstream errMsg; + char MSGTYP6[]="Error following expression finished by ^ without right part."; + errMsg << EXPR_PARSE_ERR_MSG << MSGTYP6 << _expr; + throw INTERP_KERNEL::Exception(errMsg.str().c_str()); + } + } +} + +void ExprParser::releaseFunctions() +{ + for(std::vector<Function *>::iterator iter=_func_btw_sub_expr.begin();iter!=_func_btw_sub_expr.end();iter++) + delete *iter; + _func_btw_sub_expr.clear(); +} + +/*! + * This method parse this->_expr at the current level. + * This method first try to see if this->_expr is a leaf, if not it try a unary function of something (see INTERP_KERNEL::ExprParser::parseUnaryFunc method) + * If true is returned, no deeper parsing needed, if false is returned for a full parsing of this->_expr INTERP_KERNEL::ExprParser::parseDeeper call needed. + */ +bool ExprParser::simplify() +{ + if(tryToInterpALeaf()) + return true; + parseUnaryFunc(); + if(!_is_parsing_ok) + { + parseForCmp(); + if(!_is_parsing_ok) + { + parseForAddMin(); + if(!_is_parsing_ok) + { + parseForMulDiv(); + if(!_is_parsing_ok) + parseForPow(); + } + } + } + if(!_is_parsing_ok) + { + std::ostringstream errMsg; + char MSGTYP3[]="Error in interpreting : "; + errMsg << EXPR_PARSE_ERR_MSG << MSGTYP3 << _expr; + LocateError(errMsg,_expr,0); + throw INTERP_KERNEL::Exception(errMsg.str().c_str()); + } + return false; +} + +void ExprParser::checkBracketsParity() const +{ + std::string::const_iterator iter; + int curLevel=0; + for(iter=_expr.begin();iter!=_expr.end();iter++) + { + if(*iter=='(') + curLevel++; + else if(*iter==')') + { + if(curLevel==0) + { + std::ostringstream errMsg; + char MSGTYP1[]="Error in brackets : closing brackets ')' before openning '('"; + errMsg << EXPR_PARSE_ERR_MSG << MSGTYP1; + LocateError(errMsg,_expr,(int)std::distance(_expr.begin(),iter)); + throw INTERP_KERNEL::Exception(errMsg.str().c_str()); + } + curLevel--; + } + } + if(curLevel!=0) + { + std::ostringstream errMsg; + char MSGTYP2[]="Error in brackets : not finally closed expr."; + errMsg << EXPR_PARSE_ERR_MSG << MSGTYP2; + throw INTERP_KERNEL::Exception(errMsg.str().c_str()); + } +} + +/*! + * This method substitutes part in [bg,end) in expr by the content of (str(id)) and returns the double value representation in expr[bg,end). + * If double representation is invalid an exception is thrown. + * This method returns a delta that is the delta to operate to pos in expr after substitution. + */ +double ExprParser::ReplaceAndTraduce(std::string& expr, int id, std::size_t bg, std::size_t end, int& delta) +{ + static const char MSG[]="Interal error : A string expected to be a float is not one ! Bug to signal !"; + std::istringstream stream; + std::ostringstream oss; + std::size_t end2=end!=std::string::npos?end-bg:end; + std::string tmp=expr.substr(bg,end2); + stream.str(tmp); + double ret=std::numeric_limits<double>::max(); + stream >> ret; + if(stream.fail()) + throw INTERP_KERNEL::Exception(MSG); + if(!stream.eof()) + throw INTERP_KERNEL::Exception(MSG); + oss << id; + std::string tmp2(oss.str()); + std::size_t l1=tmp.length(); + delta=(int)tmp2.length()-(int)l1; + expr.replace(bg,l1,tmp2); + return ret; +} + +/*! + * This method makes the assumption that _expr has no white space. + * This method scans _expr finding in greedy mode the following pattern : + * {0..9}+{.}?{0..9}*{{eE}{-}?{0..9}+}? + */ +void ExprParser::fillValuesInExpr(std::vector<double>& valuesInExpr) +{ + const char FIGURES[]="0123456789"; + const std::string other("+-*^/(<>,"); + std::size_t lgth=_expr.length(); + int id=0,delta; + for(std::size_t pos=0;pos!=std::string::npos;id++) + { + std::size_t pos2=_expr.find_first_of(FIGURES,pos,10); + if(pos2==std::string::npos) + break; + if(pos2>0) + {//treat case of "x*log10(x)" -> "10" should NOT be intercepted by this + if(other.find_first_of(_expr[pos2-1])==std::string::npos) + { + pos=_expr.find_first_not_of(FIGURES,pos2,10); + id--; + continue; + } + if(_expr[pos2-1]==')') + { + pos=_expr.find_first_not_of(FIGURES,pos2,10); + std::ostringstream oss; oss << "Problem on parsing : Number \"" << _expr.substr(pos2,pos!=std::string::npos?pos2-pos:std::string::npos); + oss << "\" is right after close parenthesis... ')'"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + } + std::size_t pos3=_expr.find_first_not_of(FIGURES,pos2,10); + if(pos3==std::string::npos) + {//"x+1223442320" + valuesInExpr.push_back(ReplaceAndTraduce(_expr,id,pos2,std::string::npos,delta)); + break; + } + if(_expr[pos3]=='.') + pos3++; + if(pos3<lgth) + { + std::size_t pos4=_expr.find_first_not_of(FIGURES,pos3,10); + if(pos4==std::string::npos) + {//"x+1223334.223" + valuesInExpr.push_back(ReplaceAndTraduce(_expr,id,pos2,std::string::npos,delta)); + break; + } + else + { + if(_expr[pos4]!='e' && _expr[pos4]!='E') + {//"x+1223334.223+x" + valuesInExpr.push_back(ReplaceAndTraduce(_expr,id,pos2,pos4,delta)); + pos=pos4+delta; + continue; + } + else + { + if(++pos4<lgth) + { + if(_expr[pos4]=='+' || _expr[pos4]=='-') + pos4++; + if(pos4>=lgth) + {//"x+1223334.223e+" or "1223334.223E-" + std::ostringstream oss; oss << "Invalid expr : float number at the end of expr is invalid lacking number after exponential and sign ! -> \"" << _expr.substr(pos2) << "\""; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + std::size_t pos5=_expr.find_first_not_of(FIGURES,pos4,10); + if(pos4==pos5) + {//"x+1223334.223e+x" or "1223334.223E-y" + std::ostringstream oss; oss << "Invalid expr : float number in expr is invalid lacking number after exponential ! -> \"" << _expr.substr(pos2,pos4-pos2) << "\""; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + //OK, normal case + valuesInExpr.push_back(ReplaceAndTraduce(_expr,id,pos2,pos5,delta)); + pos=pos5+delta; + continue; + } + else//"x+1223334.223e" + { + std::ostringstream oss; oss << "Invalid expr : float number at the end of expr is invalid lacking number after exponential ! " << _expr.substr(pos2); + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + } + } + } + else + {//"x+1223334." + valuesInExpr.push_back(ReplaceAndTraduce(_expr,id,pos2,std::string::npos,delta)); + break; + } + } +} + +void ExprParser::replaceValues(const std::vector<double>& valuesInExpr) +{ + if(_leaf) + _leaf->replaceValues(valuesInExpr); + else + { + for(std::vector<ExprParser>::iterator iter=_sub_expr.begin();iter!=_sub_expr.end();iter++) + (*iter).replaceValues(valuesInExpr); + } +} + +void ExprParser::LocateError(std::ostream& stringToDisp, const std::string& srcOfErr, int posOfErr) +{ + stringToDisp << "Position is " << posOfErr << " of string : \"" << srcOfErr << "\"" << std::endl; +} + +char *ExprParser::compileX86() const +{ + std::vector<std::string> ass; + //need in stack + ass.push_back("push ebp"); + ass.push_back("mov ebp,esp"); + compileX86LowLev(ass); + ass.push_back("pop ebp"); + ass.push_back("ret"); + std::cout << std::endl; + for(std::vector<std::string>::const_iterator iter=ass.begin();iter!=ass.end();iter++) + std::cout << " " << *iter << std::endl; + AsmX86 asmb; + std::vector<char> output=asmb.convertIntoMachineLangage(ass); + for(std::vector<char>::const_iterator iter=output.begin();iter!=output.end();iter++) + std::cout << std::hex << (int)((unsigned char)(*iter)) << " "; + std::cout << std::endl; + unsigned offset; + return asmb.copyToExecMemZone(output,offset); +} + +char *ExprParser::compileX86_64() const +{ + std::vector<std::string> ass; + //need in stack + ass.push_back("push rbp"); + ass.push_back("mov rbp,rsp"); + compileX86_64LowLev(ass); + ass.push_back("sub rsp,8"); + ass.push_back("fst qword [rsp]"); + ass.push_back("movsd xmm0,[rsp]"); + ass.push_back("add rsp,8"); + ass.push_back("leave"); + ass.push_back("ret"); + std::cout << std::endl; + for(std::vector<std::string>::const_iterator iter=ass.begin();iter!=ass.end();iter++) + std::cout << " " << *iter << std::endl; + AsmX86 asmb; + std::vector<char> output=asmb.convertIntoMachineLangage(ass); + for(std::vector<char>::const_iterator iter=output.begin();iter!=output.end();iter++) + std::cout << std::hex << (int)((unsigned char)(*iter)) << " "; + std::cout << std::endl; + unsigned offset; + return asmb.copyToExecMemZone(output,offset); +} + +void ExprParser::compileX86LowLev(std::vector<std::string>& ass) const +{ + if(_leaf) + _leaf->compileX86(ass); + else + { + for(std::vector<ExprParser>::const_iterator iter=_sub_expr.begin();iter!=_sub_expr.end();iter++) + (*iter).compileX86LowLev(ass); + } + for(std::vector<Function *>::const_iterator iter2=_func_btw_sub_expr.begin();iter2!=_func_btw_sub_expr.end();iter2++) + (*iter2)->operateX86(ass); +} + +void ExprParser::compileX86_64LowLev(std::vector<std::string>& ass) const +{ + if(_leaf) + _leaf->compileX86_64(ass); + else + { + for(std::vector<ExprParser>::const_iterator iter=_sub_expr.begin();iter!=_sub_expr.end();iter++) + (*iter).compileX86_64LowLev(ass); + } + for(std::vector<Function *>::const_iterator iter2=_func_btw_sub_expr.begin();iter2!=_func_btw_sub_expr.end();iter2++) + (*iter2)->operateX86(ass); +} + +double LeafExprVal::getDoubleValue() const +{ + return _value; +} + +void LeafExprVal::compileX86(std::vector<std::string>& ass) const +{ + ass.push_back("sub esp,8"); + const int *b=reinterpret_cast<const int *>(&_value),*c=reinterpret_cast<const int *>(&_value); + c++; + std::ostringstream oss; + oss << std::hex; + oss << "mov dword [esp+4],0x" << *c; + ass.push_back(oss.str()); + oss.str(""); + oss << "mov dword [esp],0x" << *b; + ass.push_back(oss.str()); + ass.push_back("fld qword [esp]"); + ass.push_back("add esp,8"); +} + +void LeafExprVal::compileX86_64(std::vector<std::string>& ass) const +{ + ass.push_back("sub rsp,8"); + const int *b=reinterpret_cast<const int *>(&_value),*c=reinterpret_cast<const int *>(&_value); + c++; + std::ostringstream oss; + oss << std::hex; + oss << "mov dword [rsp+4],0x" << *c; + ass.push_back(oss.str()); + oss.str(""); + oss << "mov dword [rsp],0x" << *b; + ass.push_back(oss.str()); + ass.push_back("fld qword [rsp]"); + ass.push_back("add rsp,8"); +} + +double LeafExprVar::getDoubleValue() const +{ + if(_fast_pos>=0) + return _val[_fast_pos]; + else + { + int pos(-7-_fast_pos); + return pos==_ref_pos?1.:0.; + } +} + +void LeafExprVar::compileX86(std::vector<std::string>& ass) const +{ + ass.push_back("fld qword [ebp+8]"); +} + +void LeafExprVar::compileX86_64(std::vector<std::string>& ass) const +{ + ass.push_back("sub rsp,8"); + ass.push_back("movsd [rsp],xmm0"); + ass.push_back("fld qword [rsp]"); + ass.push_back("add rsp,8"); +} + +int ExprParser::getStackSizeToPlayX86(const ExprParser *asker) const +{ + if(asker) + { + int sz=_father->getStackSizeToPlayX86(this); + int i=0; + for(std::vector<ExprParser>::const_reverse_iterator iter=_sub_expr.rbegin();iter!=_sub_expr.rend();iter++,i++) + { + const ExprParser& obj=(*iter); + const ExprParser *pt=&obj; + if(pt==asker) + return sz-i; + } + throw INTERP_KERNEL::Exception("error getStackSizeToPlayX86 an object ExprParser called as father, whereas it is not one !"); + } + else + { + if(!_father) + return MAX_X86_FP_ST; + return _father->getStackSizeToPlayX86(this); + } +} diff --git a/src/medtool/src/INTERP_KERNEL/ExprEval/InterpKernelExprParser.hxx b/src/medtool/src/INTERP_KERNEL/ExprEval/InterpKernelExprParser.hxx new file mode 100644 index 000000000..0b1642a14 --- /dev/null +++ b/src/medtool/src/INTERP_KERNEL/ExprEval/InterpKernelExprParser.hxx @@ -0,0 +1,192 @@ +// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 +// 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 __INTERPKERNELEXPRPARSER_HXX__ +#define __INTERPKERNELEXPRPARSER_HXX__ + +#include "INTERPKERNELDefines.hxx" +#include "InterpKernelUnit.hxx" +#include "InterpKernelException.hxx" +#include "InterpKernelFunction.hxx" + +#include <string> +#include <list> +#include <map> +#include <set> + +namespace INTERP_KERNEL +{ + class ValueDouble; + + class LeafExpr + { + public: + INTERPKERNEL_EXPORT virtual ~LeafExpr(); + INTERPKERNEL_EXPORT virtual double getDoubleValue() const = 0; + INTERPKERNEL_EXPORT virtual void fillValue(Value *val) const = 0; + INTERPKERNEL_EXPORT virtual void compileX86(std::vector<std::string>& ass) const = 0; + INTERPKERNEL_EXPORT virtual void compileX86_64(std::vector<std::string>& ass) const = 0; + INTERPKERNEL_EXPORT virtual void replaceValues(const std::vector<double>& valuesInExpr) = 0; + INTERPKERNEL_EXPORT virtual LeafExpr *deepCpy() const = 0; + INTERPKERNEL_EXPORT static LeafExpr *buildInstanceFrom(const std::string& expr); + }; + + class LeafExprVal : public LeafExpr + { + public: + INTERPKERNEL_EXPORT LeafExprVal(double value); + INTERPKERNEL_EXPORT ~LeafExprVal(); + INTERPKERNEL_EXPORT double getDoubleValue() const; + INTERPKERNEL_EXPORT void compileX86(std::vector<std::string>& ass) const; + INTERPKERNEL_EXPORT void compileX86_64(std::vector<std::string>& ass) const; + INTERPKERNEL_EXPORT void fillValue(Value *val) const; + INTERPKERNEL_EXPORT void replaceValues(const std::vector<double>& valuesInExpr); + INTERPKERNEL_EXPORT LeafExprVal *deepCpy() const; + private: + double _value; + }; + + class LeafExprVar : public LeafExpr + { + public: + INTERPKERNEL_EXPORT LeafExprVar(const LeafExprVar& other):_fast_pos(other._fast_pos),_ref_pos(other._ref_pos),_var_name(other._var_name),_val(other._val) { } + INTERPKERNEL_EXPORT LeafExprVar(const std::string& var); + INTERPKERNEL_EXPORT ~LeafExprVar(); + INTERPKERNEL_EXPORT double getDoubleValue() const; + INTERPKERNEL_EXPORT void compileX86(std::vector<std::string>& ass) const; + INTERPKERNEL_EXPORT void compileX86_64(std::vector<std::string>& ass) const; + INTERPKERNEL_EXPORT void fillValue(Value *val) const; + INTERPKERNEL_EXPORT std::string getVar() const { return _var_name; } + INTERPKERNEL_EXPORT void prepareExprEvaluation(const std::vector<std::string>& vars, int nbOfCompo, int targetNbOfCompo) const; + INTERPKERNEL_EXPORT void prepareExprEvaluationDouble(const std::vector<std::string>& vars, int nbOfCompo, int targetNbOfCompo, int refPos, const double *ptOfInputStart, const double *ptOfInputEnd) const; + INTERPKERNEL_EXPORT void prepareExprEvaluationVec() const; + INTERPKERNEL_EXPORT void replaceValues(const std::vector<double>& valuesInExpr); + INTERPKERNEL_EXPORT static bool isRecognizedKeyVar(const std::string& var, int& pos); + INTERPKERNEL_EXPORT LeafExprVar *deepCpy() const; + public: + static const char END_OF_RECOGNIZED_VAR[]; + private: + mutable int _fast_pos; + mutable int _ref_pos; + std::string _var_name; + mutable const double *_val; + }; + + class ExprParserOfEval + { + public: + ExprParserOfEval():_leaf(0) { } + ExprParserOfEval(LeafExpr *leaf, const std::vector<ExprParserOfEval>& subParts, const std::vector<Function *>& funcs):_leaf(leaf),_sub_parts(subParts),_funcs(funcs) { } + void evaluateDoubleInternal(std::vector<double>& stck) const + { + if(_leaf) + stck.push_back(_leaf->getDoubleValue()); + else + for(std::vector<ExprParserOfEval>::const_iterator iter=_sub_parts.begin();iter!=_sub_parts.end();iter++) + (*iter).evaluateDoubleInternal(stck); + for(std::vector<Function *>::const_iterator iter3=_funcs.begin();iter3!=_funcs.end();iter3++) + (*iter3)->operateStackOfDouble(stck); + } + void evaluateDoubleInternalSafe(std::vector<double>& stck) const + { + if(_leaf) + stck.push_back(_leaf->getDoubleValue()); + else + for(std::vector<ExprParserOfEval>::const_iterator iter=_sub_parts.begin();iter!=_sub_parts.end();iter++) + (*iter).evaluateDoubleInternalSafe(stck); + for(std::vector<Function *>::const_iterator iter3=_funcs.begin();iter3!=_funcs.end();iter3++) + (*iter3)->operateStackOfDoubleSafe(stck); + } + void clearSortedMemory(); + void sortMemory(); + private: + LeafExpr *_leaf; + std::vector<ExprParserOfEval> _sub_parts; + std::vector<Function *> _funcs; + }; + + class ExprParser + { + public: + INTERPKERNEL_EXPORT ExprParser(const std::string& expr, ExprParser *father=0); + INTERPKERNEL_EXPORT ExprParser(const char *expr, int lgth, ExprParser *father=0); + INTERPKERNEL_EXPORT ~ExprParser(); + INTERPKERNEL_EXPORT void parse(); + INTERPKERNEL_EXPORT bool isParsingSuccessfull() const { return _is_parsing_ok; } + INTERPKERNEL_EXPORT double evaluate() const; + INTERPKERNEL_EXPORT DecompositionInUnitBase evaluateUnit() const; + INTERPKERNEL_EXPORT void prepareExprEvaluation(const std::vector<std::string>& vars, int nbOfCompo, int targetNbOfCompo) const; + INTERPKERNEL_EXPORT void prepareExprEvaluationDouble(const std::vector<std::string>& vars, int nbOfCompo, int targetNbOfCompo, int refPos, const double *ptOfInputStart, const double *ptOfInputEnd) const; + INTERPKERNEL_EXPORT void prepareFastEvaluator() const; + INTERPKERNEL_EXPORT void prepareExprEvaluationVec() const; + INTERPKERNEL_EXPORT double evaluateDouble() const; + INTERPKERNEL_EXPORT void evaluateDoubleInternal(std::vector<double>& stck) const { _for_eval.evaluateDoubleInternal(stck); } + INTERPKERNEL_EXPORT void evaluateDoubleInternalSafe(std::vector<double>& stck) const { _for_eval.evaluateDoubleInternalSafe(stck); } + INTERPKERNEL_EXPORT void checkForEvaluation() const; + INTERPKERNEL_EXPORT void evaluateExpr(int szOfOutParam, const double *inParam, double *outParam) const; + INTERPKERNEL_EXPORT void getSetOfVars(std::set<std::string>& vars) const; + INTERPKERNEL_EXPORT void getTrueSetOfVars(std::set<std::string>& vars) const; + // + INTERPKERNEL_EXPORT char *compileX86() const; + INTERPKERNEL_EXPORT char *compileX86_64() const; + INTERPKERNEL_EXPORT void compileX86LowLev(std::vector<std::string>& ass) const; + INTERPKERNEL_EXPORT void compileX86_64LowLev(std::vector<std::string>& ass) const; + INTERPKERNEL_EXPORT int getStackSizeToPlayX86(const ExprParser *asker) const; + // + INTERPKERNEL_EXPORT static std::string buildStringFromFortran(const char *expr, int lgth); + INTERPKERNEL_EXPORT static std::string deleteWhiteSpaces(const std::string& expr); + private: + Value *evaluateLowLev(Value *valGen) const; + void reverseThis(); + ExprParserOfEval convertMeTo() const; + private: + void prepareExprEvaluationVecLowLev() const; + bool tryToInterpALeaf(); + void parseUnaryFunc(); + void parseForCmp(); + void parseForAddMin(); + void parseForMulDiv(); + void parseForPow(); + void parseDeeper(); + bool simplify(); + void releaseFunctions(); + void checkBracketsParity() const; + void fillValuesInExpr(std::vector<double>& valuesInExpr); + void replaceValues(const std::vector<double>& valuesInExpr); + static double ReplaceAndTraduce(std::string& expr, int id, std::size_t bg, std::size_t end, int& delta); + static std::size_t FindCorrespondingOpenBracket(const std::string& expr, std::size_t posOfCloseBracket); + static void LocateError(std::ostream& stringToDisp, const std::string& srcOfErr, int posOfErr); + private: + ExprParser *_father; + bool _is_parsed; + LeafExpr *_leaf; + bool _is_parsing_ok; + std::string _expr; + mutable ExprParserOfEval _for_eval; + std::vector<ExprParser> _sub_expr; + std::vector<Function *> _func_btw_sub_expr; + private: + static const int MAX_X86_FP_ST=8; + static const char WHITE_SPACES[]; + static const char EXPR_PARSE_ERR_MSG[]; + }; +} + +#endif diff --git a/src/medtool/src/INTERP_KERNEL/ExprEval/InterpKernelFunction.cxx b/src/medtool/src/INTERP_KERNEL/ExprEval/InterpKernelFunction.cxx new file mode 100644 index 000000000..5af091240 --- /dev/null +++ b/src/medtool/src/INTERP_KERNEL/ExprEval/InterpKernelFunction.cxx @@ -0,0 +1,1292 @@ +// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 +// 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 "InterpKernelFunction.hxx" +#include "InterpKernelValue.hxx" + +#include <cmath> +#include <limits> + +using namespace INTERP_KERNEL; + +const char IdentityFunction::REPR[]="Id"; + +const char PositiveFunction::REPR[]="+"; + +const char NegateFunction::REPR[]="-"; + +const char CosFunction::REPR[]="cos"; + +const char SinFunction::REPR[]="sin"; + +const char TanFunction::REPR[]="tan"; + +const char ACosFunction::REPR[]="acos"; + +const char ASinFunction::REPR[]="asin"; + +const char ATanFunction::REPR[]="atan"; + +const char CoshFunction::REPR[]="cosh"; + +const char SinhFunction::REPR[]="sinh"; + +const char TanhFunction::REPR[]="tanh"; + +const char SqrtFunction::REPR[]="sqrt"; + +const char AbsFunction::REPR[]="abs"; + +const char PlusFunction::REPR[]="+"; + +const char MinusFunction::REPR[]="-"; + +const char MultFunction::REPR[]="*"; + +const char DivFunction::REPR[]="/"; + +const char PowFunction::REPR[]="^"; + +const char ExpFunction::REPR[]="exp"; + +const char LnFunction::REPR[]="ln"; + +const char LogFunction::REPR[]="log"; + +const char Log10Function::REPR[]="log10"; + +const char MaxFunction::REPR[]="max"; + +const char MinFunction::REPR[]="min"; + +const char GreaterThanFunction::REPR[]=">"; + +const char LowerThanFunction::REPR[]="<"; + +const char IfFunction::REPR[]="if"; + +Function *FunctionsFactory::buildFuncFromString(const char *type, int nbOfParams) +{ + switch(nbOfParams) + { + case 1: + return buildUnaryFuncFromString(type); + case 2: + return buildBinaryFuncFromString(type); + case 3: + return buildTernaryFuncFromString(type); + default: + throw INTERP_KERNEL::Exception("Invalid number of params detected : limited to 2 !"); + } +} + +Function *FunctionsFactory::buildUnaryFuncFromString(const char *type) +{ + std::string tmp(type); + if(tmp.empty()) + return new IdentityFunction; + if(tmp==CosFunction::REPR) + return new CosFunction; + if(tmp==SinFunction::REPR) + return new SinFunction; + if(tmp==TanFunction::REPR) + return new TanFunction; + if(tmp==ACosFunction::REPR) + return new ACosFunction; + if(tmp==ASinFunction::REPR) + return new ASinFunction; + if(tmp==ATanFunction::REPR) + return new ATanFunction; + if(tmp==CoshFunction::REPR) + return new CoshFunction; + if(tmp==SinhFunction::REPR) + return new SinhFunction; + if(tmp==TanhFunction::REPR) + return new TanhFunction; + if(tmp==SqrtFunction::REPR) + return new SqrtFunction; + if(tmp==AbsFunction::REPR) + return new AbsFunction; + if(tmp==PositiveFunction::REPR) + return new PositiveFunction; + if(tmp==NegateFunction::REPR) + return new NegateFunction; + if(tmp==ExpFunction::REPR) + return new ExpFunction; + if(tmp==LnFunction::REPR) + return new LnFunction; + if(tmp==LogFunction::REPR) + return new LogFunction; + if(tmp==Log10Function::REPR) + return new Log10Function; + // + std::string msg("Invalid unary function detected : \""); + msg+=type; msg+="\""; + throw INTERP_KERNEL::Exception(msg.c_str()); +} + +Function *FunctionsFactory::buildBinaryFuncFromString(const char *type) +{ + std::string tmp(type); + if(tmp==PositiveFunction::REPR) + return new PlusFunction; + if(tmp==NegateFunction::REPR) + return new MinusFunction; + if(tmp==MultFunction::REPR) + return new MultFunction; + if(tmp==DivFunction::REPR) + return new DivFunction; + if(tmp==PowFunction::REPR) + return new PowFunction; + if(tmp==MaxFunction::REPR) + return new MaxFunction; + if(tmp==MinFunction::REPR) + return new MinFunction; + if(tmp==GreaterThanFunction::REPR) + return new GreaterThanFunction; + if(tmp==LowerThanFunction::REPR) + return new LowerThanFunction; + std::string msg("Invalid binary function detected : \""); + msg+=type; msg+="\""; + throw INTERP_KERNEL::Exception(msg.c_str()); +} + +Function *FunctionsFactory::buildTernaryFuncFromString(const char *type) +{ + std::string tmp(type); + if(tmp==IfFunction::REPR) + return new IfFunction(); + std::string msg("Invalid ternary function detected : \""); + msg+=type; msg+="\""; + throw INTERP_KERNEL::Exception(msg.c_str()); +} + +Function *FunctionsFactory::buildBinaryFuncFromString(char type) +{ + char tmp[2]; tmp[0]=type; tmp[1]='\0'; + return buildBinaryFuncFromString(tmp); +} + +Function::~Function() +{ +} + +IdentityFunction::~IdentityFunction() +{ +} + +void IdentityFunction::operate(std::vector<Value *>& stck) const +{ +} + +void IdentityFunction::operateX86(std::vector<std::string>& asmb) const +{ +} + +void IdentityFunction::operateStackOfDouble(std::vector<double>& stck) const +{ +} + +const char *IdentityFunction::getRepr() const +{ + return REPR; +} + +bool IdentityFunction::isACall() const +{ + return false; +} + +PositiveFunction::~PositiveFunction() +{ +} + +int UnaryFunction::getNbInputParams() const +{ + return 1; +} + +void PositiveFunction::operate(std::vector<Value *>& stck) const +{ +} + +void PositiveFunction::operateX86(std::vector<std::string>& asmb) const +{ +} + +void PositiveFunction::operateStackOfDouble(std::vector<double>& stck) const +{ +} + +const char *PositiveFunction::getRepr() const +{ + return REPR; +} + +bool PositiveFunction::isACall() const +{ + return false; +} + +NegateFunction::~NegateFunction() +{ +} + +void NegateFunction::operate(std::vector<Value *>& stck) const +{ + Value *val=stck.back(); + val->negate(); +} + +void NegateFunction::operateX86(std::vector<std::string>& asmb) const +{ + asmb.push_back("fchs"); +} + +void NegateFunction::operateStackOfDouble(std::vector<double>& stck) const +{ + double v(stck.back()); + stck.back()=-v; +} + +const char *NegateFunction::getRepr() const +{ + return REPR; +} + +bool NegateFunction::isACall() const +{ + return false; +} + +CosFunction::~CosFunction() +{ +} + +void CosFunction::operate(std::vector<Value *>& stck) const +{ + Value *val=stck.back(); + val->cos(); +} + +void CosFunction::operateX86(std::vector<std::string>& asmb) const +{ + asmb.push_back("fcos"); +} + +void CosFunction::operateStackOfDouble(std::vector<double>& stck) const +{ + double v(stck.back()); + stck.back()=cos(v); +} + +const char *CosFunction::getRepr() const +{ + return REPR; +} + +bool CosFunction::isACall() const +{ + return true; +} + +SinFunction::~SinFunction() +{ +} + +void SinFunction::operate(std::vector<Value *>& stck) const +{ + Value *val=stck.back(); + val->sin(); +} + +void SinFunction::operateX86(std::vector<std::string>& asmb) const +{ + asmb.push_back("fsin"); +} + +void SinFunction::operateStackOfDouble(std::vector<double>& stck) const +{ + double v(stck.back()); + stck.back()=sin(v); +} + +const char *SinFunction::getRepr() const +{ + return REPR; +} + +bool SinFunction::isACall() const +{ + return true; +} + +TanFunction::~TanFunction() +{ +} + +void TanFunction::operate(std::vector<Value *>& stck) const +{ + Value *val=stck.back(); + val->tan(); +} + +void TanFunction::operateX86(std::vector<std::string>& asmb) const +{ + throw INTERP_KERNEL::Exception("Assembly Not implemented yet !"); +} + +void TanFunction::operateStackOfDouble(std::vector<double>& stck) const +{ + double v(stck.back()); + stck.back()=tan(v); +} + +const char *TanFunction::getRepr() const +{ + return REPR; +} + +bool TanFunction::isACall() const +{ + return true; +} + +ACosFunction::~ACosFunction() +{ +} + +void ACosFunction::operate(std::vector<Value *>& stck) const +{ + Value *val=stck.back(); + val->acos(); +} + +void ACosFunction::operateX86(std::vector<std::string>& asmb) const +{ + throw INTERP_KERNEL::Exception("Assembly Not implemented yet !"); +} + +void ACosFunction::operateStackOfDouble(std::vector<double>& stck) const +{ + double v(stck.back()); + stck.back()=acos(v); +} + +void ACosFunction::operateStackOfDoubleSafe(std::vector<double>& stck) const +{ + double v(stck.back()); + if(fabs(v)>1.) + throw INTERP_KERNEL::Exception("acos on a value which absolute is > 1 !"); + stck.back()=acos(v); +} + +const char *ACosFunction::getRepr() const +{ + return REPR; +} + +bool ACosFunction::isACall() const +{ + return true; +} + +ASinFunction::~ASinFunction() +{ +} + +void ASinFunction::operate(std::vector<Value *>& stck) const +{ + Value *val=stck.back(); + val->asin(); +} + +void ASinFunction::operateX86(std::vector<std::string>& asmb) const +{ + throw INTERP_KERNEL::Exception("Assembly Not implemented yet !"); +} + +void ASinFunction::operateStackOfDouble(std::vector<double>& stck) const +{ + double v(stck.back()); + stck.back()=asin(v); +} + +void ASinFunction::operateStackOfDoubleSafe(std::vector<double>& stck) const +{ + double v(stck.back()); + if(fabs(v)>1.) + throw INTERP_KERNEL::Exception("asin on a value which absolute is > 1 !"); + stck.back()=asin(v); +} + +const char *ASinFunction::getRepr() const +{ + return REPR; +} + +bool ASinFunction::isACall() const +{ + return true; +} + +ATanFunction::~ATanFunction() +{ +} + +void ATanFunction::operate(std::vector<Value *>& stck) const +{ + Value *val=stck.back(); + val->atan(); +} + +void ATanFunction::operateX86(std::vector<std::string>& asmb) const +{ + throw INTERP_KERNEL::Exception("Assembly Not implemented yet !"); +} + +void ATanFunction::operateStackOfDouble(std::vector<double>& stck) const +{ + double v(stck.back()); + stck.back()=atan(v); +} + +const char *ATanFunction::getRepr() const +{ + return REPR; +} + +bool ATanFunction::isACall() const +{ + return true; +} + +CoshFunction::~CoshFunction() +{ +} + +void CoshFunction::operate(std::vector<Value *>& stck) const +{ + Value *val=stck.back(); + val->cosh(); +} + +void CoshFunction::operateX86(std::vector<std::string>& asmb) const +{ + throw INTERP_KERNEL::Exception("Assembly Not implemented yet !"); +} + +void CoshFunction::operateStackOfDouble(std::vector<double>& stck) const +{ + double v(stck.back()); + stck.back()=cosh(v); +} + +const char *CoshFunction::getRepr() const +{ + return REPR; +} + +bool CoshFunction::isACall() const +{ + return true; +} + +SinhFunction::~SinhFunction() +{ +} + +void SinhFunction::operate(std::vector<Value *>& stck) const +{ + Value *val=stck.back(); + val->sinh(); +} + +void SinhFunction::operateX86(std::vector<std::string>& asmb) const +{ + throw INTERP_KERNEL::Exception("Assembly Not implemented yet !"); +} + +void SinhFunction::operateStackOfDouble(std::vector<double>& stck) const +{ + double v(stck.back()); + stck.back()=sinh(v); +} + +const char *SinhFunction::getRepr() const +{ + return REPR; +} + +bool SinhFunction::isACall() const +{ + return true; +} + +TanhFunction::~TanhFunction() +{ +} + +void TanhFunction::operate(std::vector<Value *>& stck) const +{ + Value *val=stck.back(); + val->tanh(); +} + +void TanhFunction::operateX86(std::vector<std::string>& asmb) const +{ + throw INTERP_KERNEL::Exception("Assembly Not implemented yet !"); +} + +void TanhFunction::operateStackOfDouble(std::vector<double>& stck) const +{ + double v(stck.back()); + stck.back()=tanh(v); +} + +const char *TanhFunction::getRepr() const +{ + return REPR; +} + +bool TanhFunction::isACall() const +{ + return true; +} + +SqrtFunction::~SqrtFunction() +{ +} + +void SqrtFunction::operate(std::vector<Value *>& stck) const +{ + Value *val=stck.back(); + val->sqrt(); +} + +void SqrtFunction::operateX86(std::vector<std::string>& asmb) const +{ + asmb.push_back("fsqrt"); +} + +void SqrtFunction::operateStackOfDouble(std::vector<double>& stck) const +{ + double v(stck.back()); + stck.back()=sqrt(v); +} + +void SqrtFunction::operateStackOfDoubleSafe(std::vector<double>& stck) const +{ + double v(stck.back()); + if(v<0.) + throw INTERP_KERNEL::Exception("sqrt on a value < 0. !"); + stck.back()=sqrt(v); +} + +const char *SqrtFunction::getRepr() const +{ + return REPR; +} + +bool SqrtFunction::isACall() const +{ + return true; +} + +AbsFunction::~AbsFunction() +{ +} + +void AbsFunction::operate(std::vector<Value *>& stck) const +{ + Value *val=stck.back(); + val->abs(); +} + +void AbsFunction::operateX86(std::vector<std::string>& asmb) const +{ + asmb.push_back("fabs"); +} + +void AbsFunction::operateStackOfDouble(std::vector<double>& stck) const +{ + double v(stck.back()); + stck.back()=fabs(v); +} + +const char *AbsFunction::getRepr() const +{ + return REPR; +} + +bool AbsFunction::isACall() const +{ + return false; +} + +void ExpFunction::operate(std::vector<Value *>& stck) const +{ + Value *val=stck.back(); + val->exp(); +} + +void ExpFunction::operateX86(std::vector<std::string>& asmb) const +{ + throw INTERP_KERNEL::Exception("Assembly Not implemented yet !"); +} + +void ExpFunction::operateStackOfDouble(std::vector<double>& stck) const +{ + double v(stck.back()); + stck.back()=std::exp(v); +} + +const char *ExpFunction::getRepr() const +{ + return REPR; +} + +bool ExpFunction::isACall() const +{ + return true; +} + +LnFunction::~LnFunction() +{ +} + +void LnFunction::operate(std::vector<Value *>& stck) const +{ + Value *val=stck.back(); + val->ln(); +} + +void LnFunction::operateX86(std::vector<std::string>& asmb) const +{ + throw INTERP_KERNEL::Exception("Assembly Not implemented yet !"); +} + +void LnFunction::operateStackOfDouble(std::vector<double>& stck) const +{ + double v(stck.back()); + stck.back()=std::log(v); +} + +void LnFunction::operateStackOfDoubleSafe(std::vector<double>& stck) const +{ + double v(stck.back()); + if(v<0.) + throw INTERP_KERNEL::Exception("ln on a value < 0. !"); + stck.back()=std::log(v); +} + +const char *LnFunction::getRepr() const +{ + return REPR; +} + +bool LnFunction::isACall() const +{ + return true; +} + +LogFunction::~LogFunction() +{ +} + +void LogFunction::operate(std::vector<Value *>& stck) const +{ + Value *val=stck.back(); + val->ln(); +} + +void LogFunction::operateX86(std::vector<std::string>& asmb) const +{ + throw INTERP_KERNEL::Exception("Assembly for log Not implemented yet !"); +} + +void LogFunction::operateStackOfDouble(std::vector<double>& stck) const +{ + double v(stck.back()); + stck.back()=std::log(v); +} + +void LogFunction::operateStackOfDoubleSafe(std::vector<double>& stck) const +{ + double v(stck.back()); + if(v<0.) + throw INTERP_KERNEL::Exception("log on a value < 0. !"); + stck.back()=std::log(v); +} + +const char *LogFunction::getRepr() const +{ + return REPR; +} + +bool LogFunction::isACall() const +{ + return true; +} + +Log10Function::~Log10Function() +{ +} + +void Log10Function::operate(std::vector<Value *>& stck) const +{ + Value *val=stck.back(); + val->log10(); +} + +void Log10Function::operateX86(std::vector<std::string>& asmb) const +{ + throw INTERP_KERNEL::Exception("Assembly for log Not implemented yet !"); +} + +void Log10Function::operateStackOfDouble(std::vector<double>& stck) const +{ + double v(stck.back()); + stck.back()=std::log10(v); +} + +void Log10Function::operateStackOfDoubleSafe(std::vector<double>& stck) const +{ + double v(stck.back()); + if(v<0.) + throw INTERP_KERNEL::Exception("log10 on a value < 0. !"); + stck.back()=std::log10(v); +} + +const char *Log10Function::getRepr() const +{ + return REPR; +} + +bool Log10Function::isACall() const +{ + return true; +} + +int BinaryFunction::getNbInputParams() const +{ + return 2; +} + +PlusFunction::~PlusFunction() +{ +} + +void PlusFunction::operate(std::vector<Value *>& stck) const +{ + Value *val1=stck.back(); + stck.pop_back(); + Value *& val2=stck.back(); + Value *val3; + try + { + val3=val1->plus(val2); + } + catch(INTERP_KERNEL::Exception& e) + { + delete val1; + throw e; + } + delete val1; + delete val2; + val2=val3; +} + +void PlusFunction::operateX86(std::vector<std::string>& asmb) const +{ + asmb.push_back("faddp st1"); +} + +void PlusFunction::operateStackOfDouble(std::vector<double>& stck) const +{ + double a(stck.back()); + stck.pop_back(); + stck.back()=a+stck.back(); +} + +const char *PlusFunction::getRepr() const +{ + return REPR; +} + +bool PlusFunction::isACall() const +{ + return false; +} + +MinusFunction::~MinusFunction() +{ +} + +void MinusFunction::operate(std::vector<Value *>& stck) const +{ + Value *val1=stck.back(); + stck.pop_back(); + Value *& val2=stck.back(); + Value *val3; + try + { + val3=val1->minus(val2); + } + catch(INTERP_KERNEL::Exception& e) + { + delete val1; + throw e; + } + delete val1; + delete val2; + val2=val3; +} + +void MinusFunction::operateX86(std::vector<std::string>& asmb) const +{ + asmb.push_back("fsubp st1"); +} + +void MinusFunction::operateStackOfDouble(std::vector<double>& stck) const +{ + double a(stck.back()); + stck.pop_back(); + stck.back()=a-stck.back(); +} + +const char *MinusFunction::getRepr() const +{ + return REPR; +} + +bool MinusFunction::isACall() const +{ + return false; +} + +MultFunction::~MultFunction() +{ +} + +void MultFunction::operate(std::vector<Value *>& stck) const +{ + Value *val1=stck.back(); + stck.pop_back(); + Value *& val2=stck.back(); + Value *val3=val1->mult(val2); + delete val1; + delete val2; + val2=val3; +} + +void MultFunction::operateX86(std::vector<std::string>& asmb) const +{ + asmb.push_back("fmulp st1"); +} + +void MultFunction::operateStackOfDouble(std::vector<double>& stck) const +{ + double a(stck.back()); + stck.pop_back(); + stck.back()=a*stck.back(); +} + +const char *MultFunction::getRepr() const +{ + return REPR; +} + +bool MultFunction::isACall() const +{ + return false; +} + +DivFunction::~DivFunction() +{ +} + +void DivFunction::operate(std::vector<Value *>& stck) const +{ + Value *val1=stck.back(); + stck.pop_back(); + Value *& val2=stck.back(); + Value *val3; + try + { + val3=val1->div(val2); + } + catch(INTERP_KERNEL::Exception& e) + { + delete val1; + throw e; + } + delete val1; + delete val2; + val2=val3; +} + +void DivFunction::operateX86(std::vector<std::string>& asmb) const +{ + asmb.push_back("fdivp st1"); +} + +void DivFunction::operateStackOfDouble(std::vector<double>& stck) const +{ + double a(stck.back()); + stck.pop_back(); + stck.back()=a/stck.back(); +} + +void DivFunction::operateStackOfDoubleSafe(std::vector<double>& stck) const +{ + double a(stck.back()); + stck.pop_back(); + if(stck.back()==0.) + throw INTERP_KERNEL::Exception("division by 0. !"); + stck.back()=a/stck.back(); +} + +const char *DivFunction::getRepr() const +{ + return REPR; +} + +bool DivFunction::isACall() const +{ + return false; +} + +PowFunction::~PowFunction() +{ +} + +void PowFunction::operate(std::vector<Value *>& stck) const +{ + Value *val1=stck.back(); + stck.pop_back(); + Value *& val2=stck.back(); + Value *val3; + try + { + val3=val1->pow(val2); + } + catch(INTERP_KERNEL::Exception& e) + { + delete val1; + throw e; + } + delete val1; + delete val2; + val2=val3; +} + +void PowFunction::operateX86(std::vector<std::string>& asmb) const +{ + throw INTERP_KERNEL::Exception("Assembly Not implemented yet !"); +} + +void PowFunction::operateStackOfDouble(std::vector<double>& stck) const +{ + double a(stck.back()); + stck.pop_back(); + stck.back()=std::pow(a,stck.back()); +} + +void PowFunction::operateStackOfDoubleSafe(std::vector<double>& stck) const +{ + double a(stck.back()); + stck.pop_back(); + double b(stck.back()); + if(a<0.) + throw INTERP_KERNEL::Exception("pow with val < 0. !"); + stck.back()=std::pow(a,b); +} + +const char *PowFunction::getRepr() const +{ + return REPR; +} + +bool PowFunction::isACall() const +{ + return true; +} + +ExpFunction::~ExpFunction() +{ +} + +MaxFunction::~MaxFunction() +{ +} + +void MaxFunction::operate(std::vector<Value *>& stck) const +{ + Value *val1=stck.back(); + stck.pop_back(); + Value *& val2=stck.back(); + Value *val3; + try + { + val3=val1->max(val2); + } + catch(INTERP_KERNEL::Exception& e) + { + delete val1; + throw e; + } + delete val1; + delete val2; + val2=val3; +} + +void MaxFunction::operateX86(std::vector<std::string>& asmb) const +{ + throw INTERP_KERNEL::Exception("Assembly Not implemented yet !"); +} + +void MaxFunction::operateStackOfDouble(std::vector<double>& stck) const +{ + double a(stck.back()); + stck.pop_back(); + stck.back()=std::max(stck.back(),a); +} + +const char *MaxFunction::getRepr() const +{ + return REPR; +} + +bool MaxFunction::isACall() const +{ + return false; +} + +MinFunction::~MinFunction() +{ +} + +void MinFunction::operate(std::vector<Value *>& stck) const +{ + Value *val1=stck.back(); + stck.pop_back(); + Value *& val2=stck.back(); + Value *val3; + try + { + val3=val1->min(val2); + } + catch(INTERP_KERNEL::Exception& e) + { + delete val1; + throw e; + } + delete val1; + delete val2; + val2=val3; +} + +void MinFunction::operateX86(std::vector<std::string>& asmb) const +{ + throw INTERP_KERNEL::Exception("Assembly Not implemented yet !"); +} + +void MinFunction::operateStackOfDouble(std::vector<double>& stck) const +{ + double a(stck.back()); + stck.pop_back(); + stck.back()=std::min(stck.back(),a); +} + +const char *MinFunction::getRepr() const +{ + return REPR; +} + +bool MinFunction::isACall() const +{ + return false; +} + +GreaterThanFunction::~GreaterThanFunction() +{ +} + +void GreaterThanFunction::operate(std::vector<Value *>& stck) const +{ + Value *val1=stck.back(); + stck.pop_back(); + Value *& val2=stck.back(); + Value *val3; + try + { + val3=val1->greaterThan(val2); + } + catch(INTERP_KERNEL::Exception& e) + { + delete val1; + throw e; + } + delete val1; + delete val2; + val2=val3; +} + +void GreaterThanFunction::operateX86(std::vector<std::string>& asmb) const +{ + throw INTERP_KERNEL::Exception("Assembly Not implemented yet !"); +} + +void GreaterThanFunction::operateStackOfDouble(std::vector<double>& stck) const +{ + double a(stck.back()); + stck.pop_back(); + double b(stck.back()); + stck.back()=a>b?std::numeric_limits<double>::max():-std::numeric_limits<double>::max(); +} + +const char *GreaterThanFunction::getRepr() const +{ + return REPR; +} + +bool GreaterThanFunction::isACall() const +{ + return false; +} + +LowerThanFunction::~LowerThanFunction() +{ +} + +void LowerThanFunction::operate(std::vector<Value *>& stck) const +{ + Value *val1=stck.back(); + stck.pop_back(); + Value *& val2=stck.back(); + Value *val3; + try + { + val3=val1->lowerThan(val2); + } + catch(INTERP_KERNEL::Exception& e) + { + delete val1; + throw e; + } + delete val1; + delete val2; + val2=val3; +} + +void LowerThanFunction::operateX86(std::vector<std::string>& asmb) const +{ + throw INTERP_KERNEL::Exception("Assembly Not implemented yet !"); +} + +void LowerThanFunction::operateStackOfDouble(std::vector<double>& stck) const +{ + double a(stck.back()); + stck.pop_back(); + double b(stck.back()); + stck.back()=a<b?std::numeric_limits<double>::max():-std::numeric_limits<double>::max(); +} + +const char *LowerThanFunction::getRepr() const +{ + return REPR; +} + +bool LowerThanFunction::isACall() const +{ + return false; +} + +int TernaryFunction::getNbInputParams() const +{ + return 3; +} + +IfFunction::~IfFunction() +{ +} + +void IfFunction::operate(std::vector<Value *>& stck) const +{ + Value *val1=stck.back(); + stck.pop_back(); + Value *val2=stck.back(); + stck.pop_back(); + Value *&val3=stck.back(); + Value *val4; + try + { + val4=val1->ifFunc(val2,val3); + } + catch(INTERP_KERNEL::Exception& e) + { + delete val1; + delete val2; + throw e; + } + delete val1; + delete val2; + delete val3; + val3=val4; +} + +void IfFunction::operateX86(std::vector<std::string>& asmb) const +{ + throw INTERP_KERNEL::Exception("Assembly Not implemented yet !"); +} + +void IfFunction::operateStackOfDouble(std::vector<double>& stck) const +{ + double cond(stck.back()); + stck.pop_back(); + double the(stck.back()); + stck.pop_back(); + if(cond==std::numeric_limits<double>::max()) + stck.back()=the; +} + +void IfFunction::operateStackOfDoubleSafe(std::vector<double>& stck) const +{ + double cond(stck.back()); + stck.pop_back(); + double the(stck.back()); + stck.pop_back(); + if(cond!=std::numeric_limits<double>::max() && cond!=-std::numeric_limits<double>::max()) + throw INTERP_KERNEL::Exception("ifFunc : first parameter of ternary func is NOT a consequence of a boolean op !"); + if(cond==std::numeric_limits<double>::max()) + stck.back()=the; +} + +const char *IfFunction::getRepr() const +{ + return REPR; +} + +bool IfFunction::isACall() const +{ + return false; +} + diff --git a/src/medtool/src/INTERP_KERNEL/ExprEval/InterpKernelFunction.hxx b/src/medtool/src/INTERP_KERNEL/ExprEval/InterpKernelFunction.hxx new file mode 100644 index 000000000..8f5cf489e --- /dev/null +++ b/src/medtool/src/INTERP_KERNEL/ExprEval/InterpKernelFunction.hxx @@ -0,0 +1,479 @@ +// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 +// 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 __INTERPKERNELFUNCTION_HXX__ +#define __INTERPKERNELFUNCTION_HXX__ + +#include "INTERPKERNELDefines.hxx" +#include "InterpKernelException.hxx" + +#include <vector> + +namespace INTERP_KERNEL +{ + class Value; + class Function; + + class INTERPKERNEL_EXPORT FunctionsFactory + { + public: + static Function *buildFuncFromString(const char *type, int nbOfParams); + static Function *buildUnaryFuncFromString(const char *type); + //static Function *buildUnaryFuncFromString(char type); + static Function *buildBinaryFuncFromString(const char *type); + static Function *buildBinaryFuncFromString(char type); + static Function *buildTernaryFuncFromString(const char *type); + }; + + class INTERPKERNEL_EXPORT Function + { + public: + virtual ~Function(); + virtual int getNbInputParams() const = 0; + virtual void operate(std::vector<Value *>& stck) const = 0; + virtual void operateX86(std::vector<std::string>& asmb) const = 0; + virtual void operateStackOfDouble(std::vector<double>& stck) const = 0; + virtual void operateStackOfDoubleSafe(std::vector<double>& stck) const { operateStackOfDouble(stck); } + virtual const char *getRepr() const = 0; + virtual bool isACall() const = 0; + virtual Function *deepCpy() const = 0; + }; + + class INTERPKERNEL_EXPORT UnaryFunction : public Function + { + public: + int getNbInputParams() const; + }; + + class INTERPKERNEL_EXPORT IdentityFunction : public UnaryFunction + { + public: + ~IdentityFunction(); + void operate(std::vector<Value *>& stck) const; + void operateX86(std::vector<std::string>& asmb) const; + void operateStackOfDouble(std::vector<double>& stck) const; + const char *getRepr() const; + bool isACall() const; + IdentityFunction *deepCpy() const { return new IdentityFunction; } + public: + static const char REPR[]; + }; + + class INTERPKERNEL_EXPORT PositiveFunction : public UnaryFunction + { + public: + ~PositiveFunction(); + void operate(std::vector<Value *>& stck) const; + void operateX86(std::vector<std::string>& asmb) const; + void operateStackOfDouble(std::vector<double>& stck) const; + const char *getRepr() const; + bool isACall() const; + PositiveFunction *deepCpy() const { return new PositiveFunction; } + public: + static const char REPR[]; + }; + + class INTERPKERNEL_EXPORT NegateFunction : public UnaryFunction + { + public: + ~NegateFunction(); + void operate(std::vector<Value *>& stck) const; + void operateX86(std::vector<std::string>& asmb) const; + void operateStackOfDouble(std::vector<double>& stck) const; + const char *getRepr() const; + bool isACall() const; + NegateFunction *deepCpy() const { return new NegateFunction; } + public: + static const char REPR[]; + }; + + class INTERPKERNEL_EXPORT CosFunction : public UnaryFunction + { + public: + ~CosFunction(); + void operate(std::vector<Value *>& stck) const; + void operateX86(std::vector<std::string>& asmb) const; + void operateStackOfDouble(std::vector<double>& stck) const; + const char *getRepr() const; + bool isACall() const; + CosFunction *deepCpy() const { return new CosFunction; } + public: + static const char REPR[]; + }; + + class INTERPKERNEL_EXPORT SinFunction : public UnaryFunction + { + public: + ~SinFunction(); + void operate(std::vector<Value *>& stck) const; + void operateX86(std::vector<std::string>& asmb) const; + void operateStackOfDouble(std::vector<double>& stck) const; + const char *getRepr() const; + bool isACall() const; + SinFunction *deepCpy() const { return new SinFunction; } + public: + static const char REPR[]; + }; + + class INTERPKERNEL_EXPORT TanFunction : public UnaryFunction + { + public: + ~TanFunction(); + void operate(std::vector<Value *>& stck) const; + void operateX86(std::vector<std::string>& asmb) const; + void operateStackOfDouble(std::vector<double>& stck) const; + const char *getRepr() const; + bool isACall() const; + TanFunction *deepCpy() const { return new TanFunction; } + public: + static const char REPR[]; + }; + + class INTERPKERNEL_EXPORT ACosFunction : public UnaryFunction + { + public: + ~ACosFunction(); + void operate(std::vector<Value *>& stck) const; + void operateX86(std::vector<std::string>& asmb) const; + void operateStackOfDouble(std::vector<double>& stck) const; + void operateStackOfDoubleSafe(std::vector<double>& stck) const; + const char *getRepr() const; + bool isACall() const; + ACosFunction *deepCpy() const { return new ACosFunction; } + public: + static const char REPR[]; + }; + + class INTERPKERNEL_EXPORT ASinFunction : public UnaryFunction + { + public: + ~ASinFunction(); + void operate(std::vector<Value *>& stck) const; + void operateX86(std::vector<std::string>& asmb) const; + void operateStackOfDouble(std::vector<double>& stck) const; + void operateStackOfDoubleSafe(std::vector<double>& stck) const; + const char *getRepr() const; + bool isACall() const; + ASinFunction *deepCpy() const { return new ASinFunction; } + public: + static const char REPR[]; + }; + + class INTERPKERNEL_EXPORT ATanFunction : public UnaryFunction + { + public: + ~ATanFunction(); + void operate(std::vector<Value *>& stck) const; + void operateX86(std::vector<std::string>& asmb) const; + void operateStackOfDouble(std::vector<double>& stck) const; + const char *getRepr() const; + bool isACall() const; + ATanFunction *deepCpy() const { return new ATanFunction; } + public: + static const char REPR[]; + }; + + class INTERPKERNEL_EXPORT CoshFunction : public UnaryFunction + { + public: + ~CoshFunction(); + void operate(std::vector<Value *>& stck) const; + void operateX86(std::vector<std::string>& asmb) const; + void operateStackOfDouble(std::vector<double>& stck) const; + const char *getRepr() const; + bool isACall() const; + CoshFunction *deepCpy() const { return new CoshFunction; } + public: + static const char REPR[]; + }; + + class INTERPKERNEL_EXPORT SinhFunction : public UnaryFunction + { + public: + ~SinhFunction(); + void operate(std::vector<Value *>& stck) const; + void operateX86(std::vector<std::string>& asmb) const; + void operateStackOfDouble(std::vector<double>& stck) const; + const char *getRepr() const; + bool isACall() const; + SinhFunction *deepCpy() const { return new SinhFunction; } + public: + static const char REPR[]; + }; + + class INTERPKERNEL_EXPORT TanhFunction : public UnaryFunction + { + public: + ~TanhFunction(); + void operate(std::vector<Value *>& stck) const; + void operateX86(std::vector<std::string>& asmb) const; + void operateStackOfDouble(std::vector<double>& stck) const; + const char *getRepr() const; + bool isACall() const; + TanhFunction *deepCpy() const { return new TanhFunction; } + public: + static const char REPR[]; + }; + + class INTERPKERNEL_EXPORT SqrtFunction : public UnaryFunction + { + public: + ~SqrtFunction(); + void operateX86(std::vector<std::string>& asmb) const; + void operate(std::vector<Value *>& stck) const; + void operateStackOfDouble(std::vector<double>& stck) const; + void operateStackOfDoubleSafe(std::vector<double>& stck) const; + const char *getRepr() const; + bool isACall() const; + SqrtFunction *deepCpy() const { return new SqrtFunction; } + public: + static const char REPR[]; + }; + + class INTERPKERNEL_EXPORT AbsFunction : public UnaryFunction + { + public: + ~AbsFunction(); + void operate(std::vector<Value *>& stck) const; + void operateX86(std::vector<std::string>& asmb) const; + void operateStackOfDouble(std::vector<double>& stck) const; + const char *getRepr() const; + bool isACall() const; + AbsFunction *deepCpy() const { return new AbsFunction; } + public: + static const char REPR[]; + }; + + class INTERPKERNEL_EXPORT ExpFunction : public UnaryFunction + { + public: + ~ExpFunction(); + void operate(std::vector<Value *>& stck) const; + void operateX86(std::vector<std::string>& asmb) const; + void operateStackOfDouble(std::vector<double>& stck) const; + const char *getRepr() const; + bool isACall() const; + ExpFunction *deepCpy() const { return new ExpFunction; } + public: + static const char REPR[]; + }; + + class INTERPKERNEL_EXPORT LnFunction : public UnaryFunction + { + public: + ~LnFunction(); + void operate(std::vector<Value *>& stck) const; + void operateX86(std::vector<std::string>& asmb) const; + void operateStackOfDouble(std::vector<double>& stck) const; + void operateStackOfDoubleSafe(std::vector<double>& stck) const; + const char *getRepr() const; + bool isACall() const; + LnFunction *deepCpy() const { return new LnFunction; } + public: + static const char REPR[]; + }; + + class INTERPKERNEL_EXPORT LogFunction : public UnaryFunction + { + public: + ~LogFunction(); + void operate(std::vector<Value *>& stck) const; + void operateX86(std::vector<std::string>& asmb) const; + void operateStackOfDouble(std::vector<double>& stck) const; + void operateStackOfDoubleSafe(std::vector<double>& stck) const; + const char *getRepr() const; + bool isACall() const; + LogFunction *deepCpy() const { return new LogFunction; } + public: + static const char REPR[]; + }; + + class INTERPKERNEL_EXPORT Log10Function : public UnaryFunction + { + public: + ~Log10Function(); + void operate(std::vector<Value *>& stck) const; + void operateX86(std::vector<std::string>& asmb) const; + void operateStackOfDouble(std::vector<double>& stck) const; + void operateStackOfDoubleSafe(std::vector<double>& stck) const; + const char *getRepr() const; + bool isACall() const; + Log10Function *deepCpy() const { return new Log10Function; } + public: + static const char REPR[]; + }; + + class INTERPKERNEL_EXPORT BinaryFunction : public Function + { + public: + int getNbInputParams() const; + }; + + class PlusFunction : public BinaryFunction + { + public: + ~PlusFunction(); + void operate(std::vector<Value *>& stck) const; + void operateX86(std::vector<std::string>& asmb) const; + void operateStackOfDouble(std::vector<double>& stck) const; + const char *getRepr() const; + bool isACall() const; + PlusFunction *deepCpy() const { return new PlusFunction; } + public: + static const char REPR[]; + }; + + class INTERPKERNEL_EXPORT MinusFunction : public BinaryFunction + { + public: + ~MinusFunction(); + void operate(std::vector<Value *>& stck) const; + void operateX86(std::vector<std::string>& asmb) const; + void operateStackOfDouble(std::vector<double>& stck) const; + const char *getRepr() const; + bool isACall() const; + MinusFunction *deepCpy() const { return new MinusFunction; } + public: + static const char REPR[]; + }; + + class INTERPKERNEL_EXPORT MultFunction : public BinaryFunction + { + public: + ~MultFunction(); + void operate(std::vector<Value *>& stck) const; + void operateX86(std::vector<std::string>& asmb) const; + void operateStackOfDouble(std::vector<double>& stck) const; + const char *getRepr() const; + bool isACall() const; + MultFunction *deepCpy() const { return new MultFunction; } + public: + static const char REPR[]; + }; + + class INTERPKERNEL_EXPORT DivFunction : public BinaryFunction + { + public: + ~DivFunction(); + void operate(std::vector<Value *>& stck) const; + void operateX86(std::vector<std::string>& asmb) const; + void operateStackOfDouble(std::vector<double>& stck) const; + void operateStackOfDoubleSafe(std::vector<double>& stck) const; + const char *getRepr() const; + bool isACall() const; + DivFunction *deepCpy() const { return new DivFunction; } + public: + static const char REPR[]; + }; + + class INTERPKERNEL_EXPORT PowFunction : public BinaryFunction + { + public: + ~PowFunction(); + void operate(std::vector<Value *>& stck) const; + void operateX86(std::vector<std::string>& asmb) const; + void operateStackOfDouble(std::vector<double>& stck) const; + void operateStackOfDoubleSafe(std::vector<double>& stck) const; + const char *getRepr() const; + bool isACall() const; + PowFunction *deepCpy() const { return new PowFunction; } + public: + static const char REPR[]; + }; + + class INTERPKERNEL_EXPORT MaxFunction : public BinaryFunction + { + public: + ~MaxFunction(); + void operate(std::vector<Value *>& stck) const; + void operateX86(std::vector<std::string>& asmb) const; + void operateStackOfDouble(std::vector<double>& stck) const; + const char *getRepr() const; + bool isACall() const; + MaxFunction *deepCpy() const { return new MaxFunction; } + public: + static const char REPR[]; + }; + + class INTERPKERNEL_EXPORT MinFunction : public BinaryFunction + { + public: + ~MinFunction(); + void operate(std::vector<Value *>& stck) const; + void operateX86(std::vector<std::string>& asmb) const; + void operateStackOfDouble(std::vector<double>& stck) const; + const char *getRepr() const; + bool isACall() const; + MinFunction *deepCpy() const { return new MinFunction; } + public: + static const char REPR[]; + }; + + class INTERPKERNEL_EXPORT GreaterThanFunction : public BinaryFunction + { + public: + ~GreaterThanFunction(); + void operate(std::vector<Value *>& stck) const; + void operateX86(std::vector<std::string>& asmb) const; + void operateStackOfDouble(std::vector<double>& stck) const; + const char *getRepr() const; + bool isACall() const; + GreaterThanFunction *deepCpy() const { return new GreaterThanFunction; } + public: + static const char REPR[]; + }; + + class INTERPKERNEL_EXPORT LowerThanFunction : public BinaryFunction + { + public: + ~LowerThanFunction(); + void operate(std::vector<Value *>& stck) const; + void operateX86(std::vector<std::string>& asmb) const; + void operateStackOfDouble(std::vector<double>& stck) const; + const char *getRepr() const; + bool isACall() const; + LowerThanFunction *deepCpy() const { return new LowerThanFunction; } + public: + static const char REPR[]; + }; + + class INTERPKERNEL_EXPORT TernaryFunction : public Function + { + public: + int getNbInputParams() const; + }; + + class INTERPKERNEL_EXPORT IfFunction : public TernaryFunction + { + public: + ~IfFunction(); + void operate(std::vector<Value *>& stck) const; + void operateX86(std::vector<std::string>& asmb) const; + void operateStackOfDouble(std::vector<double>& stck) const; + void operateStackOfDoubleSafe(std::vector<double>& stck) const; + const char *getRepr() const; + bool isACall() const; + IfFunction *deepCpy() const { return new IfFunction; } + public: + static const char REPR[]; + }; +} + +#endif diff --git a/src/medtool/src/INTERP_KERNEL/ExprEval/InterpKernelUnit.cxx b/src/medtool/src/INTERP_KERNEL/ExprEval/InterpKernelUnit.cxx new file mode 100644 index 000000000..44e08f49f --- /dev/null +++ b/src/medtool/src/INTERP_KERNEL/ExprEval/InterpKernelUnit.cxx @@ -0,0 +1,372 @@ +// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 +// 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 "InterpKernelUnit.hxx" +#include "InterpKernelExprParser.hxx" + +#include <cmath> +#include <sstream> +#include <iomanip> +#include <limits> + +using namespace INTERP_KERNEL; + +UnitDataBase UnitDataBase::_uniqueMapForExpr; + +static const char InterpKernelMuAscii[2]={-0x4B,0x0}; + +static const char InterpKernelMuUnicode[3]={-0x3E,-0x4B,0x0}; + +const char *UnitDataBase::PREF_POW10[NB_OF_PREF_POW10]={"y","z","a","f","p","n",InterpKernelMuAscii,InterpKernelMuUnicode,"u","m","c","d", + "da","h","k","M","G","T","P","E","Z","Y"}; + +const double UnitDataBase::POW10[NB_OF_PREF_POW10]={1e-24,1e-21,1e-18,1e-15,1e-12,1e-9,1e-6,1e-6,1e-6,1e-3,1e-2,1e-1, + 1e1,1e2,1e3,1e6,1e9,1e12,1e15,1e18,1e21,1e24}; + +static const char InterpKernelDegreeCAscii[3]={-0x50,0x43,0x0}; + +static const char InterpKernelDegreeCUnicode[4]={-0x3E,-0x50,0x43,0x0}; + +static const char InterpKernelDegreeCUnicodeWin[3]={-0x08,0x43,0x0}; + +const char *UnitDataBase::UNITS_RECOGN[NB_OF_UNITS_RECOGN]={"g","m","s","A","K", + "W","J","Hz","V","h","min","t","N","dyn", + "eV","Pa","atm","bar",InterpKernelDegreeCAscii,"C","ohm","F","S", + "T","H","P","St",InterpKernelDegreeCUnicode,InterpKernelDegreeCUnicodeWin}; + +const short UnitDataBase::PROJ_IN_BASE[NB_OF_UNITS_RECOGN][SIZE_OF_UNIT_BASE]= + { + {1,0,0,0,0},//g + {0,1,0,0,0},//m + {0,0,1,0,0},//s + {0,0,0,1,0},//A + {0,0,0,0,1},//K + {1,2,-3,0,0},//W + {1,2,-2,0,0},//J + {0,0,-1,0,0},//Hz + {1,2,-3,-1,0},//V + {0,0,1,0,0},//h + {0,0,1,0,0},//min + {1,0,0,0,0},//t + {1,1,-2,0,0},//N + {1,1,-2,0,0},//dyn + {1,2,-2,0,0},//eV + {1,-1,-2,0,0},//Pa + {1,-1,-2,0,0},//atm + {1,-1,-2,0,0},//bar + {0,0,0,0,1},//degree C + {0,0,1,1,0},//C + {1,2,-3,-2,0},//ohm + {-1,-2,4,2,0},//F + {-1,-2,3,2,0},//S + {1,0,-2,-1,0},//T + {1,2,-2,-2,0},//H + {1,-1,-1,0,0},//P + {0,2,-1,0,0},//St + {0,0,0,0,1},//degree C + {0,0,0,0,1}//degree C + }; + +const double UnitDataBase::MUL_COEFF[NB_OF_UNITS_RECOGN]= + { 1.,1.,1.,1.,1., + 1000.,1000.,1.,1000.,3600.,3600.,1e6,1000.,1e-2, + 1.60217733e-16,1000.,1.01325e8,1e8,1.,1.,1000.,1e-3, + 1000.,1000.,100.,1.,1.,1.,1.}; + +const double UnitDataBase::ADD_COEFF[NB_OF_UNITS_RECOGN]= + { 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 273.15, 0., 0., 0., 0., 0., 0., 0., 0., 273.15 ,273.15}; + +UnitDataBase::UnitDataBase() +{ + for(int i=0;i<NB_OF_PREF_POW10;i++) + _prefix_pow_10[PREF_POW10[i]]=POW10[i]; + for(int i=0;i<NB_OF_UNITS_RECOGN;i++) + { + _units_semantic[UNITS_RECOGN[i]]=PROJ_IN_BASE[i]; + _units_mul[UNITS_RECOGN[i]]=MUL_COEFF[i]; + _units_add[UNITS_RECOGN[i]]=ADD_COEFF[i]; + } +} + +const short *UnitDataBase::getInfoForUnit(const std::string& unit, double& addFact, double& mFact) const +{ + std::size_t lgth=unit.length(); + std::string work,work2; + const short *ret=0; + for(std::size_t i=0;i<lgth && !ret;i++) + { + work=unit.substr(i); + std::map<std::string,const short *>::const_iterator iter=_units_semantic.find(work); + if(iter!=_units_semantic.end()) + { + ret=(*iter).second; + std::map<std::string,double>::const_iterator iter2=_units_add.find(work); + addFact=(*iter2).second; + std::map<std::string,double>::const_iterator iter3=_units_mul.find(work); + mFact=(*iter3).second; + work2=unit.substr(0,i); + } + } + if(!ret) + { + std::ostringstream os; + os << "Unit : " << unit << " not recognized !"; + throw INTERP_KERNEL::Exception(os.str().c_str()); + } + if(!work2.empty()) + { + std::map<std::string,double>::const_iterator iter4=_prefix_pow_10.find(work2); + if(iter4==_prefix_pow_10.end()) + { + std::ostringstream os; + os << "Unit : " << unit << " not fully recognized : \"" << work << "\" detected as core unit and \""; + os << work2 << "\" not recognized prefix !"; + throw INTERP_KERNEL::Exception(os.str().c_str()); + } + addFact=0.; + mFact*=(*iter4).second; + } + return ret; +} + +DecompositionInUnitBase::DecompositionInUnitBase():_add_to_base(0.),_mult_fact_to_base(1.) +{ + _value[0]=0; + _value[1]=0; + _value[2]=0; + _value[3]=0; + _value[4]=0; +} + +void DecompositionInUnitBase::setInfo(const short *vals, double addFact, double mFact) +{ + _add_to_base=addFact; + _mult_fact_to_base=mFact; + _value[0]=vals[0]; + _value[1]=vals[1]; + _value[2]=vals[2]; + _value[3]=vals[3]; + _value[4]=vals[4]; +} + +bool DecompositionInUnitBase::operator==(const DecompositionInUnitBase& other) const +{ + return _value[0]==other._value[0] && _value[1]==other._value[1] && _value[2]==other._value[2] && _value[3]==other._value[3] && _value[4]==other._value[4]; +} + +void DecompositionInUnitBase::getTranslationParams(const DecompositionInUnitBase& other, double& mul, double& add) const +{ + if((*this)==other) + { + mul=_mult_fact_to_base/other._mult_fact_to_base; + add=_add_to_base/other._mult_fact_to_base-other._add_to_base; + } + else + { + mul=std::numeric_limits<double>::max(); + add=std::numeric_limits<double>::max(); + } +} + +bool DecompositionInUnitBase::isEqual(short mass, short lgth, short time, short intensity, short temp, double add, double mult) +{ + bool ret1=mass==_value[0]; + bool ret2=lgth==_value[1]; + bool ret3=time==_value[2]; + bool ret4=intensity==_value[3]; + bool ret5=temp==_value[4]; + bool ret6=areDoubleEquals(add,_add_to_base); + bool ret7=areDoubleEquals(mult,_mult_fact_to_base); + return ret1 && ret2 && ret3 && ret4 && ret5 && ret6 && ret7; +} + +void DecompositionInUnitBase::negate() +{ + _mult_fact_to_base=-_mult_fact_to_base; +} + +bool DecompositionInUnitBase::isAdimensional() const +{ + return _value[0]==0 && _value[1]==0 && _value[2]==0 && _value[3]==0 && _value[4]==0; +} + +bool DecompositionInUnitBase::isUnitary() const +{ + return areDoubleEquals(_add_to_base,0.) && areDoubleEquals(_mult_fact_to_base,1.); +} + +void DecompositionInUnitBase::tryToConvertInUnit(double val) +{ + int valI=(int)val; + if((val-(double)valI)!=0.) + { + std::ostringstream os; + os << "Double value " << val << " can't be considered as integer. Not admitable for units !"; + throw INTERP_KERNEL::Exception(os.str().c_str()); + } + _value[0]=0; + _value[1]=0; + _value[2]=0; + _value[3]=0; + _value[4]=0; + _add_to_base=0; + _mult_fact_to_base=valI; +} + +DecompositionInUnitBase &DecompositionInUnitBase::operator*(const DecompositionInUnitBase& other) +{ + _value[0]+=other._value[0]; _value[1]+=other._value[1]; _value[2]+=other._value[2]; _value[3]+=other._value[3]; _value[4]+=other._value[4]; + _mult_fact_to_base*=other._mult_fact_to_base; + _add_to_base=0.; + return *this; +} + +DecompositionInUnitBase &DecompositionInUnitBase::operator/(const DecompositionInUnitBase& other) +{ + _value[0]-=other._value[0]; _value[1]-=other._value[1]; _value[2]-=other._value[2]; _value[3]-=other._value[3]; _value[4]-=other._value[4]; + _mult_fact_to_base/=other._mult_fact_to_base; + _add_to_base=0.; + return *this; +} + +DecompositionInUnitBase &DecompositionInUnitBase::operator^(const DecompositionInUnitBase& other) +{ + if(!other.isAdimensional()) + throw INTERP_KERNEL::Exception("Trying to execute operator ^ with a second member not adimensionnal"); + int exp=couldItBeConsideredAsInt(other._mult_fact_to_base); + _value[0]*=exp; _value[1]*=exp; _value[2]*=exp; _value[3]*=exp; _value[4]*=exp; + _mult_fact_to_base=powInt(_mult_fact_to_base,exp); + _add_to_base=0.; + return *this; +} + +void DecompositionInUnitBase::dealWithAddFactor(const DecompositionInUnitBase& other) +{ + if(!areDoubleEquals(_add_to_base,0.)) + if(other.isAdimensional()) + if(areDoubleEquals(other._mult_fact_to_base,1.)) + return ; + if(!other.areDoubleEquals(_add_to_base,0.)) + if(isAdimensional()) + if(areDoubleEquals(_mult_fact_to_base,1.)) + return ; + _add_to_base=0.; +} + +double DecompositionInUnitBase::powInt(double val, int exp) +{ + double work=1.; + if(exp==0) + return 1.; + if(exp>0) + for(int i=0;i<exp;i++) + work*=val; + else + { + int tmp=-exp; + for(int i=0;i<tmp;i++) + work*=1/val; + } + return work; +} + +bool DecompositionInUnitBase::areDoubleEquals(double a, double b) +{ + if(a==0. || b==0.) + return a==b; + double ref=std::max(a,b); + return fabs((a-b)/ref)<1e-7; +} + +int DecompositionInUnitBase::couldItBeConsideredAsInt(double val) +{ + int ret=(int)val; + double valT=(double) ret; + if(valT==val) + return ret; + else + { + std::ostringstream stream; stream << "Invalid double number " << std::setprecision(16) << val << " can's be considered for ^ operation on unit."; + throw INTERP_KERNEL::Exception(stream.str().c_str()); + } +} + +Unit::Unit(const char *reprC, bool tryToInterp):_coarse_repr(reprC), + _is_interpreted(false), + _is_interpretation_ok(false) +{ + if(tryToInterp) + tryToInterprate(); +} + +Unit::Unit(const char *reprFortran, int sizeOfRepr, bool tryToInterp):_coarse_repr(ExprParser::buildStringFromFortran(reprFortran,sizeOfRepr)), + _is_interpreted(false), + _is_interpretation_ok(false) +{ +} + +void Unit::tryToInterprate() const +{ + if(!_is_interpreted) + { + _is_interpreted=true; + _is_interpretation_ok=false; + try + { + ExprParser expr(_coarse_repr.c_str()); + expr.parse(); + _decomp_in_base=expr.evaluateUnit(); + _is_interpretation_ok=true; + } + catch(INTERP_KERNEL::Exception&) { } + } +} + +bool Unit::isInterpretationOK() const +{ + return _is_interpretation_ok; +} + +bool Unit::isCompatibleWith(const Unit& other) const +{ + tryToInterprate(); + other.tryToInterprate(); + if(_is_interpretation_ok && other._is_interpretation_ok) + return _decomp_in_base==other._decomp_in_base; + else + return false; +} + +double Unit::convert(const Unit& target, double sourceVal) const +{ + if(isCompatibleWith(target)) + { + double mult,add; + _decomp_in_base.getTranslationParams(target._decomp_in_base,mult,add); + return mult*sourceVal+add; + } + else + return std::numeric_limits<double>::max(); +} + +std::string Unit::getCoarseRepr() const +{ + return _coarse_repr; +} diff --git a/src/medtool/src/INTERP_KERNEL/ExprEval/InterpKernelUnit.hxx b/src/medtool/src/INTERP_KERNEL/ExprEval/InterpKernelUnit.hxx new file mode 100644 index 000000000..4af8759b5 --- /dev/null +++ b/src/medtool/src/INTERP_KERNEL/ExprEval/InterpKernelUnit.hxx @@ -0,0 +1,117 @@ +// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 +// 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 __INTERPKERNELUNIT_HXX__ +#define __INTERPKERNELUNIT_HXX__ + +#include "INTERPKERNELDefines.hxx" +#include "InterpKernelException.hxx" + +#include <map> +#include <sstream> + +namespace INTERP_KERNEL +{ + class UnitDataBase + { + public: + INTERPKERNEL_EXPORT UnitDataBase(); + INTERPKERNEL_EXPORT const short *getInfoForUnit(const std::string& unit, double& addFact, double& mFact) const; + INTERPKERNEL_EXPORT static UnitDataBase _uniqueMapForExpr; + INTERPKERNEL_EXPORT static const int SIZE_OF_UNIT_BASE=5; + private: + std::map<std::string,double> _prefix_pow_10; + std::map<std::string,const short *> _units_semantic; + std::map<std::string,double> _units_mul; + std::map<std::string,double> _units_add; + private: + static const int NB_OF_PREF_POW10=22; + static const char *PREF_POW10[NB_OF_PREF_POW10]; + static const double POW10[NB_OF_PREF_POW10]; + static const int NB_OF_UNITS_RECOGN=29; + static const char *UNITS_RECOGN[NB_OF_UNITS_RECOGN]; + static const short PROJ_IN_BASE[NB_OF_UNITS_RECOGN][SIZE_OF_UNIT_BASE]; + static const double MUL_COEFF[NB_OF_UNITS_RECOGN]; + static const double ADD_COEFF[NB_OF_UNITS_RECOGN]; + }; + + class DecompositionInUnitBase + { + public: + INTERPKERNEL_EXPORT DecompositionInUnitBase(); + INTERPKERNEL_EXPORT void setInfo(const short *vals, double addFact, double mFact); + INTERPKERNEL_EXPORT short operator[](int i) const { return _value[i]; } + INTERPKERNEL_EXPORT bool operator==(const DecompositionInUnitBase& other) const; + INTERPKERNEL_EXPORT void getTranslationParams(const DecompositionInUnitBase& other, double& mul, double& add) const; + INTERPKERNEL_EXPORT bool isEqual(short mass, short lgth, short time, short intensity, short temp, + double add, double mult); + INTERPKERNEL_EXPORT bool isUnitary() const; + //! \b WARNING no test is done on the fact that unit is adimensionnal. + INTERPKERNEL_EXPORT void negate(); + INTERPKERNEL_EXPORT bool isAdimensional() const; + INTERPKERNEL_EXPORT void tryToConvertInUnit(double val); + INTERPKERNEL_EXPORT DecompositionInUnitBase &operator*(const DecompositionInUnitBase& other); + INTERPKERNEL_EXPORT DecompositionInUnitBase &operator/(const DecompositionInUnitBase& other); + INTERPKERNEL_EXPORT DecompositionInUnitBase &operator^(const DecompositionInUnitBase& other); + private: + void dealWithAddFactor(const DecompositionInUnitBase& other); + static int couldItBeConsideredAsInt(double val); + static bool areDoubleEquals(double a, double b); + static double powInt(double val, int exp); + private: + short _value[UnitDataBase::SIZE_OF_UNIT_BASE]; + double _add_to_base; + double _mult_fact_to_base; + }; + + /*! + * This class deals with units. + * This class has two main responsabilities : + * - interprete units by giving simply their representation in string type. + * - performing operations on these units. + * + * All the possible units are represented with a unique tuple with 5 elements + * representing the unique decomposition of a unit in the following base. + * + * dimension 0 stands for mass in g (\b NOT kg to simplify parsing). + * dimension 1 stands for length in m. + * dimension 2 stands for time in s. + * dimension 3 stands for elec intensity A. + * dimension 4 stands for temperature in K. + */ + class Unit + { + public: + INTERPKERNEL_EXPORT Unit(const char *reprC, bool tryToInterp=true); + INTERPKERNEL_EXPORT Unit(const char *reprFortran, int sizeOfRepr, bool tryToInterp=true); + INTERPKERNEL_EXPORT void tryToInterprate() const; + INTERPKERNEL_EXPORT bool isInterpretationOK() const; + INTERPKERNEL_EXPORT bool isCompatibleWith(const Unit& other) const; + INTERPKERNEL_EXPORT double convert(const Unit& target, double sourceVal) const; + INTERPKERNEL_EXPORT std::string getCoarseRepr() const; + private: + std::string _coarse_repr; + mutable bool _is_interpreted; + mutable bool _is_interpretation_ok; + mutable DecompositionInUnitBase _decomp_in_base; + }; +} + +#endif diff --git a/src/medtool/src/INTERP_KERNEL/ExprEval/InterpKernelValue.cxx b/src/medtool/src/INTERP_KERNEL/ExprEval/InterpKernelValue.cxx new file mode 100644 index 000000000..3006fc941 --- /dev/null +++ b/src/medtool/src/INTERP_KERNEL/ExprEval/InterpKernelValue.cxx @@ -0,0 +1,641 @@ +// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 +// 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 "InterpKernelValue.hxx" +#include "InterpKernelFunction.hxx" + +#include <cmath> +#include <limits> +#include <algorithm> + +using namespace INTERP_KERNEL; + +ValueDouble::ValueDouble():_data(std::numeric_limits<double>::max()) +{ +} + +Value *ValueDouble::newInstance() const +{ + return new ValueDouble; +} + +ValueDouble::ValueDouble(double val):_data(val) +{ +} + +void ValueDouble::setDouble(double val) +{ + _data=val; +} + +void ValueDouble::setVarname(int fastPos, const std::string& var) +{ + std::string msg("Error var : "); msg+=var; msg+=" not numeric : use another expression evaluator !"; + throw INTERP_KERNEL::Exception(msg.c_str()); +} + +void ValueDouble::positive() +{ +} + +void ValueDouble::negate() +{ + _data=-_data; +} + +void ValueDouble::sqrt() +{ + _data=std::sqrt(_data); +} + +void ValueDouble::cos() +{ + _data=std::cos(_data); +} + +void ValueDouble::sin() +{ + _data=std::sin(_data); +} + +void ValueDouble::tan() +{ + _data=std::tan(_data); +} + +void ValueDouble::acos() +{ + _data=std::acos(_data); +} + +void ValueDouble::asin() +{ + _data=std::asin(_data); +} + +void ValueDouble::atan() +{ + _data=std::atan(_data); +} + +void ValueDouble::cosh() +{ + _data=std::cosh(_data); +} + +void ValueDouble::sinh() +{ + _data=std::sinh(_data); +} + +void ValueDouble::tanh() +{ + _data=std::tanh(_data); +} + +void ValueDouble::abs() +{ + if(_data<0.) + _data=-_data; +} + +void ValueDouble::exp() +{ + _data=std::exp(_data); +} + +void ValueDouble::ln() +{ + _data=std::log(_data); +} + +void ValueDouble::log10() +{ + _data=std::log10(_data); +} + +Value *ValueDouble::plus(const Value *other) const +{ + const ValueDouble *valC=checkSameType(other); + return new ValueDouble(_data+valC->_data); +} + +Value *ValueDouble::minus(const Value *other) const +{ + const ValueDouble *valC=checkSameType(other); + return new ValueDouble(_data-valC->_data); +} + +Value *ValueDouble::mult(const Value *other) const +{ + const ValueDouble *valC=checkSameType(other); + return new ValueDouble(_data*valC->_data); +} + +Value *ValueDouble::div(const Value *other) const +{ + const ValueDouble *valC=checkSameType(other); + return new ValueDouble(_data/valC->_data); +} + +Value *ValueDouble::pow(const Value *other) const +{ + const ValueDouble *valC=checkSameType(other); + return new ValueDouble(std::pow(_data,valC->_data)); +} + +Value *ValueDouble::max(const Value *other) const +{ + const ValueDouble *valC=checkSameType(other); + return new ValueDouble(std::max(_data,valC->_data)); +} + +Value *ValueDouble::min(const Value *other) const +{ + const ValueDouble *valC=checkSameType(other); + return new ValueDouble(std::min(_data,valC->_data)); +} + +Value *ValueDouble::greaterThan(const Value *other) const +{ + const ValueDouble *valC=checkSameType(other); + return new ValueDouble(_data>valC->_data?std::numeric_limits<double>::max():-std::numeric_limits<double>::max()); +} + +Value *ValueDouble::lowerThan(const Value *other) const +{ + const ValueDouble *valC=checkSameType(other); + return new ValueDouble(_data<valC->_data?std::numeric_limits<double>::max():-std::numeric_limits<double>::max()); +} + +Value *ValueDouble::ifFunc(const Value *the, const Value *els) const +{ + const ValueDouble *theC=checkSameType(the); + const ValueDouble *elsC=checkSameType(els); + if(_data==std::numeric_limits<double>::max()) + return new ValueDouble(theC->_data); + if(_data==-std::numeric_limits<double>::max()) + return new ValueDouble(elsC->_data); + throw INTERP_KERNEL::Exception("ValueDouble::ifFunc : The fist element of ternary function if is not a binary op !"); +} + +const ValueDouble *ValueDouble::checkSameType(const Value *val) +{ + const ValueDouble *valC=dynamic_cast<const ValueDouble *>(val); + if(!valC) + throw INTERP_KERNEL::Exception("Trying to operate on non homogeneous Values (double with other type) !"); + return valC; +} + +ValueUnit::ValueUnit() +{ +} + +Value *ValueUnit::newInstance() const +{ + return new ValueUnit; +} + +ValueUnit::ValueUnit(const DecompositionInUnitBase& unit):_data(unit) +{ +} + +void ValueUnit::setDouble(double val) +{ + _data.tryToConvertInUnit(val); +} + +void ValueUnit::setVarname(int fastPos, const std::string& var) +{ + double add,mul; + const short *projInBase=UnitDataBase::_uniqueMapForExpr.getInfoForUnit(var,add,mul); + _data.setInfo(projInBase,add,mul); +} + +void ValueUnit::positive() +{ + unsupportedOp(PositiveFunction::REPR); +} + +void ValueUnit::negate() +{ + _data.negate(); +} + +void ValueUnit::sqrt() +{ + unsupportedOp(SqrtFunction::REPR); +} + +void ValueUnit::cos() +{ + unsupportedOp(CosFunction::REPR); +} + +void ValueUnit::sin() +{ + unsupportedOp(SinFunction::REPR); +} + +void ValueUnit::tan() +{ + unsupportedOp(TanFunction::REPR); +} + +void ValueUnit::acos() +{ + unsupportedOp(ACosFunction::REPR); +} + +void ValueUnit::asin() +{ + unsupportedOp(ASinFunction::REPR); +} + +void ValueUnit::atan() +{ + unsupportedOp(ATanFunction::REPR); +} + +void ValueUnit::cosh() +{ + unsupportedOp(CoshFunction::REPR); +} + +void ValueUnit::sinh() +{ + unsupportedOp(SinhFunction::REPR); +} + +void ValueUnit::tanh() +{ + unsupportedOp(TanhFunction::REPR); +} + +void ValueUnit::abs() +{ + unsupportedOp(AbsFunction::REPR); +} + +void ValueUnit::exp() +{ + unsupportedOp(ExpFunction::REPR); +} + +void ValueUnit::ln() +{ + unsupportedOp(LnFunction::REPR); +} + +void ValueUnit::log10() +{ + unsupportedOp(Log10Function::REPR); +} + +Value *ValueUnit::plus(const Value *other) const +{ + unsupportedOp(PlusFunction::REPR); + return 0; +} + +Value *ValueUnit::minus(const Value *other) const +{ + unsupportedOp(MinusFunction::REPR); + return 0; +} + +Value *ValueUnit::greaterThan(const Value *other) const +{ + unsupportedOp(GreaterThanFunction::REPR); + return 0; +} + +Value *ValueUnit::lowerThan(const Value *other) const +{ + unsupportedOp(LowerThanFunction::REPR); + return 0; +} + +Value *ValueUnit::ifFunc(const Value *the, const Value *els) const +{ + unsupportedOp(IfFunction::REPR); + return 0; +} + +Value *ValueUnit::mult(const Value *other) const +{ + const ValueUnit *valC=checkSameType(other); + DecompositionInUnitBase tmp=_data; + tmp*valC->getData(); + return new ValueUnit(tmp); +} + +Value *ValueUnit::div(const Value *other) const +{ + const ValueUnit *valC=checkSameType(other); + DecompositionInUnitBase tmp=_data; + tmp/valC->getData(); + return new ValueUnit(tmp); +} + +Value *ValueUnit::pow(const Value *other) const +{ + const ValueUnit *valC=checkSameType(other); + DecompositionInUnitBase tmp=_data; + tmp^valC->getData(); + return new ValueUnit(tmp); +} + +Value *ValueUnit::max(const Value *other) const +{ + unsupportedOp(MaxFunction::REPR); + return 0; +} + +Value *ValueUnit::min(const Value *other) const +{ + unsupportedOp(MinFunction::REPR); + return 0; +} + +const ValueUnit *ValueUnit::checkSameType(const Value *val) +{ + const ValueUnit *valC=dynamic_cast<const ValueUnit *>(val); + if(!valC) + throw INTERP_KERNEL::Exception("Trying to operate on non homogeneous Values (Units with other type) !"); + return valC; +} + +void ValueUnit::unsupportedOp(const char *type) +{ + const char msg[]="Unsupported operation for units :"; + std::string msgStr(msg); + msgStr+=type; + throw INTERP_KERNEL::Exception(msgStr.c_str()); +} + +ValueDoubleExpr::ValueDoubleExpr(int szDestData, const double *srcData):_sz_dest_data(szDestData),_dest_data(new double[_sz_dest_data]),_src_data(srcData) +{ +} + +ValueDoubleExpr::~ValueDoubleExpr() +{ + delete [] _dest_data; +} + +Value *ValueDoubleExpr::newInstance() const +{ + return new ValueDoubleExpr(_sz_dest_data,_src_data); +} + +void ValueDoubleExpr::setDouble(double val) +{ + std::fill(_dest_data,_dest_data+_sz_dest_data,val); +} + +void ValueDoubleExpr::setVarname(int fastPos, const std::string& var) +{ + if(fastPos==-2) + std::copy(_src_data,_src_data+_sz_dest_data,_dest_data); + else if(fastPos>-2) + std::fill(_dest_data,_dest_data+_sz_dest_data,_src_data[fastPos]); + else + { + std::fill(_dest_data,_dest_data+_sz_dest_data,0.); + _dest_data[-7-fastPos]=1.; + } +} + +void ValueDoubleExpr::positive() +{ +} + +void ValueDoubleExpr::negate() +{ + std::transform(_dest_data,_dest_data+_sz_dest_data,_dest_data,std::negate<double>()); +} + +void ValueDoubleExpr::sqrt() +{ + double *it=std::find_if(_dest_data,_dest_data+_sz_dest_data,std::bind2nd(std::less<double>(),0.)); + if(it!=_dest_data+_sz_dest_data) + throw INTERP_KERNEL::Exception("Trying to apply sqrt on < 0. value !"); + std::transform(_dest_data,_dest_data+_sz_dest_data,_dest_data,std::ptr_fun<double,double>(std::sqrt)); +} + +void ValueDoubleExpr::cos() +{ + std::transform(_dest_data,_dest_data+_sz_dest_data,_dest_data,std::ptr_fun<double,double>(std::cos)); +} + +void ValueDoubleExpr::sin() +{ + std::transform(_dest_data,_dest_data+_sz_dest_data,_dest_data,std::ptr_fun<double,double>(std::sin)); +} + +void ValueDoubleExpr::tan() +{ + std::transform(_dest_data,_dest_data+_sz_dest_data,_dest_data,std::ptr_fun<double,double>(std::tan)); +} + +void ValueDoubleExpr::acos() +{ + double *it=std::find_if(_dest_data,_dest_data+_sz_dest_data,std::bind2nd(std::less<double>(),-1.)); + if(it!=_dest_data+_sz_dest_data) + throw INTERP_KERNEL::Exception("Trying to apply acos on < 1. value !"); + it=std::find_if(_dest_data,_dest_data+_sz_dest_data,std::bind2nd(std::greater<double>(),1.)); + if(it!=_dest_data+_sz_dest_data) + throw INTERP_KERNEL::Exception("Trying to apply acos on > 1. value !"); + std::transform(_dest_data,_dest_data+_sz_dest_data,_dest_data,std::ptr_fun<double,double>(std::acos)); +} + +void ValueDoubleExpr::asin() +{ + double *it=std::find_if(_dest_data,_dest_data+_sz_dest_data,std::bind2nd(std::less<double>(),-1.)); + if(it!=_dest_data+_sz_dest_data) + throw INTERP_KERNEL::Exception("Trying to apply asin on < 1. value !"); + it=std::find_if(_dest_data,_dest_data+_sz_dest_data,std::bind2nd(std::greater<double>(),1.)); + if(it!=_dest_data+_sz_dest_data) + throw INTERP_KERNEL::Exception("Trying to apply asin on > 1. value !"); + std::transform(_dest_data,_dest_data+_sz_dest_data,_dest_data,std::ptr_fun<double,double>(std::asin)); +} + +void ValueDoubleExpr::atan() +{ + std::transform(_dest_data,_dest_data+_sz_dest_data,_dest_data,std::ptr_fun<double,double>(std::atan)); +} + +void ValueDoubleExpr::cosh() +{ + std::transform(_dest_data,_dest_data+_sz_dest_data,_dest_data,std::ptr_fun<double,double>(std::cosh)); +} + +void ValueDoubleExpr::sinh() +{ + std::transform(_dest_data,_dest_data+_sz_dest_data,_dest_data,std::ptr_fun<double,double>(std::sinh)); +} + +void ValueDoubleExpr::tanh() +{ + std::transform(_dest_data,_dest_data+_sz_dest_data,_dest_data,std::ptr_fun<double,double>(std::tanh)); +} + +void ValueDoubleExpr::abs() +{ + std::transform(_dest_data,_dest_data+_sz_dest_data,_dest_data,std::ptr_fun<double,double>(fabs)); +} + +void ValueDoubleExpr::exp() +{ + std::transform(_dest_data,_dest_data+_sz_dest_data,_dest_data,std::ptr_fun<double,double>(std::exp)); +} + +void ValueDoubleExpr::ln() +{ + double *it=std::find_if(_dest_data,_dest_data+_sz_dest_data,std::bind2nd(std::less_equal<double>(),0.)); + if(it!=_dest_data+_sz_dest_data) + throw INTERP_KERNEL::Exception("Trying to apply neperian/natural log on <= 0. value !"); + std::transform(_dest_data,_dest_data+_sz_dest_data,_dest_data,std::ptr_fun<double,double>(std::log)); +} + +void ValueDoubleExpr::log10() +{ + double *it=std::find_if(_dest_data,_dest_data+_sz_dest_data,std::bind2nd(std::less_equal<double>(),0.)); + if(it!=_dest_data+_sz_dest_data) + throw INTERP_KERNEL::Exception("Trying to apply log10 on <= 0. value !"); + std::transform(_dest_data,_dest_data+_sz_dest_data,_dest_data,std::ptr_fun<double,double>(std::log10)); +} + +Value *ValueDoubleExpr::plus(const Value *other) const +{ + const ValueDoubleExpr *otherC=static_cast<const ValueDoubleExpr *>(other); + ValueDoubleExpr *ret=new ValueDoubleExpr(_sz_dest_data,_src_data); + std::transform(_dest_data,_dest_data+_sz_dest_data,otherC->getData(),ret->getData(),std::plus<double>()); + return ret; +} + +Value *ValueDoubleExpr::minus(const Value *other) const +{ + const ValueDoubleExpr *otherC=static_cast<const ValueDoubleExpr *>(other); + ValueDoubleExpr *ret=new ValueDoubleExpr(_sz_dest_data,_src_data); + std::transform(_dest_data,_dest_data+_sz_dest_data,otherC->getData(),ret->getData(),std::minus<double>()); + return ret; +} + +Value *ValueDoubleExpr::mult(const Value *other) const +{ + const ValueDoubleExpr *otherC=static_cast<const ValueDoubleExpr *>(other); + ValueDoubleExpr *ret=new ValueDoubleExpr(_sz_dest_data,_src_data); + std::transform(_dest_data,_dest_data+_sz_dest_data,otherC->getData(),ret->getData(),std::multiplies<double>()); + return ret; +} + +Value *ValueDoubleExpr::div(const Value *other) const +{ + const ValueDoubleExpr *otherC=static_cast<const ValueDoubleExpr *>(other); + double *it=std::find(otherC->getData(),otherC->getData()+_sz_dest_data,0.); + if(it!=otherC->getData()+_sz_dest_data) + throw INTERP_KERNEL::Exception("Trying to operate division by 0. !"); + ValueDoubleExpr *ret=new ValueDoubleExpr(_sz_dest_data,_src_data); + std::transform(_dest_data,_dest_data+_sz_dest_data,otherC->getData(),ret->getData(),std::divides<double>()); + return ret; +} + +Value *ValueDoubleExpr::pow(const Value *other) const +{ + const ValueDoubleExpr *otherC=static_cast<const ValueDoubleExpr *>(other); + double p=otherC->getData()[0]; + double *it=std::find_if(_dest_data,_dest_data+_sz_dest_data,std::bind2nd(std::less<double>(),0.)); + if(it!=_dest_data+_sz_dest_data) + throw INTERP_KERNEL::Exception("Trying to operate pow(a,b) with a<0. !"); + ValueDoubleExpr *ret=new ValueDoubleExpr(_sz_dest_data,_src_data); + std::transform(_dest_data,_dest_data+_sz_dest_data,ret->getData(),std::bind2nd(std::ptr_fun<double,double,double>(std::pow),p)); + return ret; +} + +Value *ValueDoubleExpr::max(const Value *other) const +{ + const ValueDoubleExpr *otherC=static_cast<const ValueDoubleExpr *>(other); + ValueDoubleExpr *ret=new ValueDoubleExpr(_sz_dest_data,_src_data); + std::transform(_dest_data,_dest_data+_sz_dest_data,otherC->getData(),ret->getData(),std::ptr_fun<const double&, const double&, const double& >(std::max)); + return ret; +} + +Value *ValueDoubleExpr::min(const Value *other) const +{ + const ValueDoubleExpr *otherC=static_cast<const ValueDoubleExpr *>(other); + ValueDoubleExpr *ret=new ValueDoubleExpr(_sz_dest_data,_src_data); + std::transform(_dest_data,_dest_data+_sz_dest_data,otherC->getData(),ret->getData(),std::ptr_fun<const double&, const double&, const double& >(std::min)); + return ret; +} + +Value *ValueDoubleExpr::greaterThan(const Value *other) const +{ + const ValueDoubleExpr *otherC=static_cast<const ValueDoubleExpr *>(other); + ValueDoubleExpr *ret=new ValueDoubleExpr(_sz_dest_data,_src_data); + for(int i=0;i<_sz_dest_data;i++) + if(_dest_data[i]<=otherC->getData()[i]) + { + std::fill(ret->getData(),ret->getData()+_sz_dest_data,-std::numeric_limits<double>::max()); + return ret; + } + std::fill(ret->getData(),ret->getData()+_sz_dest_data,std::numeric_limits<double>::max()); + return ret; +} + +Value *ValueDoubleExpr::lowerThan(const Value *other) const +{ + const ValueDoubleExpr *otherC=static_cast<const ValueDoubleExpr *>(other); + ValueDoubleExpr *ret=new ValueDoubleExpr(_sz_dest_data,_src_data); + for(int i=0;i<_sz_dest_data;i++) + if(_dest_data[i]>=otherC->getData()[i]) + { + std::fill(ret->getData(),ret->getData()+_sz_dest_data,-std::numeric_limits<double>::max()); + return ret; + } + std::fill(ret->getData(),ret->getData()+_sz_dest_data,std::numeric_limits<double>::max()); + return ret; +} + +Value *ValueDoubleExpr::ifFunc(const Value *the, const Value *els) const +{ + const ValueDoubleExpr *theC=static_cast<const ValueDoubleExpr *>(the); + const ValueDoubleExpr *elsC=static_cast<const ValueDoubleExpr *>(els); + ValueDoubleExpr *ret=new ValueDoubleExpr(_sz_dest_data,_src_data); + bool okmax=true; + bool okmin=true; + for(int i=0;i<_sz_dest_data && (okmax || okmin);i++) + { + okmax=_dest_data[i]==std::numeric_limits<double>::max(); + okmin=_dest_data[i]==-std::numeric_limits<double>::max(); + } + if(okmax || okmin) + { + if(okmax) + std::copy(theC->getData(),theC->getData()+_sz_dest_data,ret->getData()); + else + std::copy(elsC->getData(),elsC->getData()+_sz_dest_data,ret->getData()); + return ret; + } + else + { + throw INTERP_KERNEL::Exception("ValueDoubleExpr::ifFunc : first parameter of ternary func is NOT a consequence of a boolean op !"); + } +} diff --git a/src/medtool/src/INTERP_KERNEL/ExprEval/InterpKernelValue.hxx b/src/medtool/src/INTERP_KERNEL/ExprEval/InterpKernelValue.hxx new file mode 100644 index 000000000..ecc6d1118 --- /dev/null +++ b/src/medtool/src/INTERP_KERNEL/ExprEval/InterpKernelValue.hxx @@ -0,0 +1,202 @@ +// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 +// 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 __INTERPKERNELVALUE_HXX__ +#define __INTERPKERNELVALUE_HXX__ + +#include "INTERPKERNELDefines.hxx" +#include "InterpKernelException.hxx" +#include "InterpKernelUnit.hxx" + +namespace INTERP_KERNEL +{ + class INTERPKERNEL_EXPORT Value + { + public: + virtual Value *newInstance() const = 0; + virtual ~Value() { } + virtual void setDouble(double val) = 0; + virtual void setVarname(int fastPos, const std::string& var) = 0; + //unary + virtual void positive() = 0; + virtual void negate() = 0; + virtual void sqrt() = 0; + virtual void cos() = 0; + virtual void sin() = 0; + virtual void tan() = 0; + virtual void acos() = 0; + virtual void asin() = 0; + virtual void atan() = 0; + virtual void cosh() = 0; + virtual void sinh() = 0; + virtual void tanh() = 0; + virtual void abs() = 0; + virtual void exp() = 0; + virtual void ln() = 0; + virtual void log10() = 0; + //binary + virtual Value *plus(const Value *other) const = 0; + virtual Value *minus(const Value *other) const = 0; + virtual Value *mult(const Value *other) const = 0; + virtual Value *div(const Value *other) const = 0; + virtual Value *pow(const Value *other) const = 0; + virtual Value *max(const Value *other) const = 0; + virtual Value *min(const Value *other) const = 0; + virtual Value *greaterThan(const Value *other) const = 0; + virtual Value *lowerThan(const Value *other) const = 0; + //ternary + virtual Value *ifFunc(const Value *the, const Value *els) const = 0; + }; + + class INTERPKERNEL_EXPORT ValueDouble : public Value + { + public: + ValueDouble(); + Value *newInstance() const; + void setDouble(double val); + void setVarname(int fastPos, const std::string& var); + // + double getData() const { return _data; } + void positive(); + void negate(); + void sqrt(); + void cos(); + void sin(); + void tan(); + void acos(); + void asin(); + void atan(); + void cosh(); + void sinh(); + void tanh(); + void abs(); + void exp(); + void ln(); + void log10(); + // + Value *plus(const Value *other) const; + Value *minus(const Value *other) const; + Value *mult(const Value *other) const; + Value *div(const Value *other) const; + Value *pow(const Value *other) const; + Value *max(const Value *other) const; + Value *min(const Value *other) const; + Value *greaterThan(const Value *other) const; + Value *lowerThan(const Value *other) const; + // + Value *ifFunc(const Value *the, const Value *els) const; + private: + ValueDouble(double val); + static const ValueDouble *checkSameType(const Value *val); + private: + double _data; + }; + + class ValueUnit : public Value + { + public: + INTERPKERNEL_EXPORT ValueUnit(); + INTERPKERNEL_EXPORT Value *newInstance() const; + INTERPKERNEL_EXPORT void setDouble(double val); + INTERPKERNEL_EXPORT void setVarname(int fastPos, const std::string& var); + // + INTERPKERNEL_EXPORT DecompositionInUnitBase getData() const { return _data; } + INTERPKERNEL_EXPORT void positive(); + INTERPKERNEL_EXPORT void negate(); + INTERPKERNEL_EXPORT void sqrt(); + INTERPKERNEL_EXPORT void cos(); + INTERPKERNEL_EXPORT void sin(); + INTERPKERNEL_EXPORT void tan(); + INTERPKERNEL_EXPORT void acos(); + INTERPKERNEL_EXPORT void asin(); + INTERPKERNEL_EXPORT void atan(); + INTERPKERNEL_EXPORT void cosh(); + INTERPKERNEL_EXPORT void sinh(); + INTERPKERNEL_EXPORT void tanh(); + INTERPKERNEL_EXPORT void abs(); + INTERPKERNEL_EXPORT void exp(); + INTERPKERNEL_EXPORT void ln(); + INTERPKERNEL_EXPORT void log10(); + // + INTERPKERNEL_EXPORT Value *plus(const Value *other) const; + INTERPKERNEL_EXPORT Value *minus(const Value *other) const; + INTERPKERNEL_EXPORT Value *mult(const Value *other) const; + INTERPKERNEL_EXPORT Value *div(const Value *other) const; + INTERPKERNEL_EXPORT Value *pow(const Value *other) const; + INTERPKERNEL_EXPORT Value *max(const Value *other) const; + INTERPKERNEL_EXPORT Value *min(const Value *other) const; + INTERPKERNEL_EXPORT Value *greaterThan(const Value *other) const; + INTERPKERNEL_EXPORT Value *lowerThan(const Value *other) const; + // + INTERPKERNEL_EXPORT Value *ifFunc(const Value *the, const Value *els) const; + private: + ValueUnit(const DecompositionInUnitBase& unit); + static void unsupportedOp(const char *type); + static const ValueUnit *checkSameType(const Value *val); + private: + DecompositionInUnitBase _data; + }; + + class INTERPKERNEL_EXPORT ValueDoubleExpr : public Value + { + public: + ValueDoubleExpr(int szDestData, const double *srcData); + ~ValueDoubleExpr(); + double *getData() const { return _dest_data; } + Value *newInstance() const; + void setDouble(double val); + void setVarname(int fastPos, const std::string& var); + // + void positive(); + void negate(); + void sqrt(); + void cos(); + void sin(); + void tan(); + void acos(); + void asin(); + void atan(); + void cosh(); + void sinh(); + void tanh(); + void abs(); + void exp(); + void ln(); + void log10(); + // + Value *plus(const Value *other) const; + Value *minus(const Value *other) const; + Value *mult(const Value *other) const; + Value *div(const Value *other) const; + Value *pow(const Value *other) const; + Value *max(const Value *other) const; + Value *min(const Value *other) const; + Value *greaterThan(const Value *other) const; + Value *lowerThan(const Value *other) const; + // + Value *ifFunc(const Value *the, const Value *els) const; + private: + int _sz_dest_data; + double *_dest_data; + const double *_src_data; + }; +} + +#endif diff --git a/src/medtool/src/INTERP_KERNEL/GaussPoints/InterpKernelGaussCoords.cxx b/src/medtool/src/INTERP_KERNEL/GaussPoints/InterpKernelGaussCoords.cxx new file mode 100644 index 000000000..618e9e8b8 --- /dev/null +++ b/src/medtool/src/INTERP_KERNEL/GaussPoints/InterpKernelGaussCoords.cxx @@ -0,0 +1,2823 @@ +// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 +// 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 +// + +//Local includes +#include "InterpKernelGaussCoords.hxx" +#include "CellModel.hxx" + +//STL includes +#include <math.h> +#include <algorithm> +#include <sstream> + +using namespace INTERP_KERNEL; + +//Define common part of the code in the MACRO +//--------------------------------------------------------------- +#define LOCAL_COORD_MACRO_BEGIN \ + _my_local_reference_coord.resize( _my_local_ref_dim*_my_local_nb_ref ); \ + for( int refId = 0; refId < _my_local_nb_ref; refId++ ) \ + { \ + double* coords = &_my_local_reference_coord[ refId*_my_local_ref_dim ]; \ + switch(refId) \ + { + +//--------------------------------------------------------------- +#define LOCAL_COORD_MACRO_END \ + } \ +} + +//--------------------------------------------------------------- +#define SHAPE_FUN_MACRO_BEGIN \ + for( int gaussId = 0 ; gaussId < _my_nb_gauss ; gaussId++ ) \ + { \ + double* funValue = &_my_function_value[ gaussId * _my_nb_ref ]; \ + const double* gc = &_my_gauss_coord[ gaussId * getGaussCoordDim() ]; + +//--------------------------------------------------------------- +#define SHAPE_FUN_MACRO_END \ + } + +#define CHECK_MACRO \ + if( ! aSatify ) \ + { \ + std::ostringstream stream; \ + stream << "Error in the gauss localization for the cell with type "; \ + stream << cellModel.getRepr(); \ + stream << " !!!"; \ + throw INTERP_KERNEL::Exception(stream.str().c_str()); \ + } + + +//--------------------------------------------------------------- +static bool IsEqual(double theLeft, double theRight) +{ + static double EPS = 1.0E-3; + if(fabs(theLeft) + fabs(theRight) > EPS) + return fabs(theLeft-theRight)/(fabs(theLeft)+fabs(theRight)) < EPS; + return true; +} + + +//////////////////////////////////////////////////////////////////////////////////////////////// +// GAUSS INFO CLASS // +//////////////////////////////////////////////////////////////////////////////////////////////// + +/*! + * Constructor of the GaussInfo + */ +GaussInfo::GaussInfo( NormalizedCellType theGeometry, + const DataVector& theGaussCoord, + int theNbGauss, + const DataVector& theReferenceCoord, + int theNbRef ) : + _my_geometry(theGeometry), + _my_nb_gauss(theNbGauss), + _my_gauss_coord(theGaussCoord), + _my_nb_ref(theNbRef), + _my_reference_coord(theReferenceCoord) +{ + + //Allocate shape function values + _my_function_value.resize( _my_nb_gauss * _my_nb_ref ); +} + +/*! + * Destructor + */ +GaussInfo::~GaussInfo() +{ +} + +/*! + * Return dimension of the gauss coordinates + */ +int GaussInfo::getGaussCoordDim() const +{ + if( _my_nb_gauss ) + { + return _my_gauss_coord.size()/_my_nb_gauss; + } + else + { + return 0; + } +} + +/*! + * Return dimension of the reference coordinates + */ +int GaussInfo::getReferenceCoordDim() const +{ + if( _my_nb_ref ) + { + return _my_reference_coord.size()/_my_nb_ref; + } + else + { + return 0; + } +} + +/*! + * Return type of the cell. + */ +NormalizedCellType GaussInfo::getCellType() const +{ + return _my_geometry; +} + +/*! + * Return Nb of the gauss points. + */ +int GaussInfo::getNbGauss() const +{ + return _my_nb_gauss; +} + +/*! + * Return Nb of the reference coordinates. + */ +int GaussInfo::getNbRef() const +{ + return _my_nb_ref; +} + +/*! + * Check coordinates + */ +bool GaussInfo::isSatisfy() +{ + + bool anIsSatisfy = ((_my_local_nb_ref == _my_nb_ref) && (_my_local_ref_dim == getReferenceCoordDim())); + //Check coordinates + if(anIsSatisfy) + { + for( int refId = 0; refId < _my_local_nb_ref; refId++ ) + { + double* refCoord = &_my_reference_coord[ refId*_my_local_ref_dim ]; + double* localRefCoord = &_my_local_reference_coord[ refId*_my_local_ref_dim ]; + bool anIsEqual = false; + for( int dimId = 0; dimId < _my_local_ref_dim; dimId++ ) + { + anIsEqual = IsEqual( localRefCoord[dimId], refCoord[dimId]); + if(!anIsEqual ) + { + return false; + } + } + } + } + return anIsSatisfy; +} + +std::vector<double> GaussInfo::NormalizeCoordinatesIfNecessary(NormalizedCellType ct, int inputDim, const std::vector<double>& inputArray) +{ + std::size_t sz(inputArray.size()),dim((std::size_t)inputDim); + if(dim==0) + throw INTERP_KERNEL::Exception("GaussInfo::NormalizeCoordinatesIfNecessary : invalid dimension ! Must be !=0 !"); + if(sz%dim!=0) + throw INTERP_KERNEL::Exception("GaussInfo::NormalizeCoordinatesIfNecessary : invalid input array ! Inconsistent with the given dimension !"); + const CellModel& cm(CellModel::GetCellModel(ct)); + std::size_t baseDim((std::size_t)cm.getDimension()); + if(baseDim==dim) + return inputArray; + std::size_t nbOfItems(sz/dim); + std::vector<double> ret(nbOfItems*baseDim); + if(baseDim>dim) + { + for(std::size_t i=0;i<nbOfItems;i++) + { + std::size_t j=0; + for(;j<dim;j++) + ret[i*baseDim+j]=inputArray[i*dim+j]; + for(;j<baseDim;j++) + ret[i*baseDim+j]=0.; + } + } + else + { + for(std::size_t i=0;i<nbOfItems;i++) + { + std::size_t j=0; + for(;j<baseDim;j++) + ret[i*baseDim+j]=inputArray[i*dim+j]; + } + } + return ret; +} + +typedef void (*MapToShapeFunction)(GaussInfo& obj); + +/*! + * Initialize the internal vectors + */ +void GaussInfo::initLocalInfo() +{ + bool aSatify = false; + const CellModel& cellModel(CellModel::GetCellModel(_my_geometry)); + switch( _my_geometry ) + { + case NORM_POINT1: + _my_local_ref_dim = 0; + _my_local_nb_ref = 1; + point1Init(); + aSatify = isSatisfy(); + CHECK_MACRO; + break; + + case NORM_SEG2: + _my_local_ref_dim = 1; + _my_local_nb_ref = 2; + seg2Init(); + aSatify = isSatisfy(); + CHECK_MACRO; + break; + + case NORM_SEG3: + _my_local_ref_dim = 1; + _my_local_nb_ref = 3; + seg3Init(); + aSatify = isSatisfy(); + CHECK_MACRO; + break; + + case NORM_TRI3: + _my_local_ref_dim = 2; + _my_local_nb_ref = 3; + tria3aInit(); + aSatify = isSatisfy(); + + if(!aSatify) + { + tria3bInit(); + aSatify = isSatisfy(); + CHECK_MACRO; + } + break; + + case NORM_TRI6: + _my_local_ref_dim = 2; + _my_local_nb_ref = 6; + tria6aInit(); + aSatify = isSatisfy(); + if(!aSatify) + { + tria6bInit(); + aSatify = isSatisfy(); + CHECK_MACRO; + } + break; + + case NORM_TRI7: + _my_local_ref_dim = 2; + _my_local_nb_ref = 7; + tria7aInit(); + aSatify = isSatisfy(); + CHECK_MACRO; + break; + + case NORM_QUAD4: + { + _my_local_ref_dim = 2; + _my_local_nb_ref = 4; + MapToShapeFunction QUAD4PTR[]={Quad4aInit,Quad4bInit,Quad4cInit,Quad4DegSeg2Init}; + std::size_t NB_OF_QUAD4PTR(sizeof(QUAD4PTR)/sizeof(MapToShapeFunction)); + for(std::size_t i=0;i<NB_OF_QUAD4PTR && !aSatify;i++) + { + (QUAD4PTR[i])(*this); + aSatify = isSatisfy(); + } + CHECK_MACRO; + break; + } + break; + + case NORM_QUAD8: + _my_local_ref_dim = 2; + _my_local_nb_ref = 8; + quad8aInit(); + aSatify = isSatisfy(); + + if(!aSatify) + { + quad8bInit(); + aSatify = isSatisfy(); + CHECK_MACRO; + } + break; + + case NORM_QUAD9: + _my_local_ref_dim = 2; + _my_local_nb_ref = 9; + quad9aInit(); + aSatify = isSatisfy(); + CHECK_MACRO; + break; + + case NORM_TETRA4: + _my_local_ref_dim = 3; + _my_local_nb_ref = 4; + tetra4aInit(); + aSatify = isSatisfy(); + + if(!aSatify) + { + tetra4bInit(); + aSatify = isSatisfy(); + CHECK_MACRO; + } + break; + + case NORM_TETRA10: + _my_local_ref_dim = 3; + _my_local_nb_ref = 10; + tetra10aInit(); + aSatify = isSatisfy(); + + if(!aSatify) + { + tetra10bInit(); + aSatify = isSatisfy(); + CHECK_MACRO; + } + break; + + case NORM_PYRA5: + _my_local_ref_dim = 3; + _my_local_nb_ref = 5; + pyra5aInit(); + aSatify = isSatisfy(); + + if(!aSatify) + { + pyra5bInit(); + aSatify = isSatisfy(); + CHECK_MACRO; + } + break; + + case NORM_PYRA13: + _my_local_ref_dim = 3; + _my_local_nb_ref = 13; + pyra13aInit(); + aSatify = isSatisfy(); + + if(!aSatify) + { + pyra13bInit(); + aSatify = isSatisfy(); + CHECK_MACRO; + } + break; + + case NORM_PENTA6: + { + _my_local_ref_dim = 3; + _my_local_nb_ref = 6; + MapToShapeFunction PENTA6PTR[]={Penta6aInit,Penta6bInit,Penta6DegTria3aInit,Penta6DegTria3bInit}; + std::size_t NB_OF_PENTA6PTR(sizeof(PENTA6PTR)/sizeof(MapToShapeFunction)); + for(std::size_t i=0;i<NB_OF_PENTA6PTR && !aSatify;i++) + { + (PENTA6PTR[i])(*this); + aSatify = isSatisfy(); + } + CHECK_MACRO; + break; + } + + + _my_local_ref_dim = 3; + _my_local_nb_ref = 6; + penta6aInit(); + aSatify = isSatisfy(); + + if(!aSatify) + { + penta6bInit(); + aSatify = isSatisfy(); + CHECK_MACRO; + } + break; + + case NORM_PENTA15: + { + _my_local_ref_dim = 3; + _my_local_nb_ref = 15; + MapToShapeFunction PENTA15PTR[]={Penta15aInit,Penta15bInit}; + std::size_t NB_OF_PENTA15PTR(sizeof(PENTA15PTR)/sizeof(MapToShapeFunction)); + for(std::size_t i=0;i<NB_OF_PENTA15PTR && !aSatify;i++) + { + (PENTA15PTR[i])(*this); + aSatify = isSatisfy(); + } + CHECK_MACRO; + break; + } + + case NORM_HEXA8: + { + _my_local_ref_dim = 3; + _my_local_nb_ref = 8; + MapToShapeFunction HEXA8PTR[]={Hexa8aInit,Hexa8bInit,Hexa8DegQuad4aInit,Hexa8DegQuad4bInit,Hexa8DegQuad4cInit}; + std::size_t NB_OF_HEXA8PTR(sizeof(HEXA8PTR)/sizeof(MapToShapeFunction)); + for(std::size_t i=0;i<NB_OF_HEXA8PTR && !aSatify;i++) + { + (HEXA8PTR[i])(*this); + aSatify = isSatisfy(); + } + CHECK_MACRO; + break; + } + + case NORM_HEXA20: + _my_local_ref_dim = 3; + _my_local_nb_ref = 20; + hexa20aInit(); + aSatify = isSatisfy(); + + if(!aSatify) + { + hexa20bInit(); + aSatify = isSatisfy(); + CHECK_MACRO; + } + break; + + case NORM_HEXA27: + _my_local_ref_dim = 3; + _my_local_nb_ref = 27; + hexa27aInit(); + aSatify = isSatisfy(); + CHECK_MACRO + break; + + default: + throw INTERP_KERNEL::Exception("Not managed cell type !"); + break; + } +} + +/** + * Return shape function value by node id + */ +const double* GaussInfo::getFunctionValues( const int theGaussId ) const +{ + return &_my_function_value[ _my_nb_ref*theGaussId ]; +} + +void GaussInfo::point1Init() +{ + double *funValue(&_my_function_value[0]); + funValue[0] = 1. ; +} + +/*! + * Init Segment 2 Reference coordinates ans Shape function. + */ +void GaussInfo::seg2Init() +{ + LOCAL_COORD_MACRO_BEGIN; + case 0: + coords[0] = -1.0; + break; + case 1: + coords[0] = 1.0; + break; + LOCAL_COORD_MACRO_END; + + SHAPE_FUN_MACRO_BEGIN; + funValue[0] = 0.5*(1.0 - gc[0]); + funValue[1] = 0.5*(1.0 + gc[0]); + SHAPE_FUN_MACRO_END; +} + +/*! + * Init Segment 3 Reference coordinates ans Shape function. + */ +void GaussInfo::seg3Init() +{ + LOCAL_COORD_MACRO_BEGIN; + case 0: + coords[0] = -1.0; + break; + case 1: + coords[0] = 1.0; + break; + case 2: + coords[0] = 0.0; + break; + LOCAL_COORD_MACRO_END; + + SHAPE_FUN_MACRO_BEGIN; + funValue[0] = -0.5*(1.0 - gc[0])*gc[0]; + funValue[1] = 0.5*(1.0 + gc[0])*gc[0]; + funValue[2] = (1.0 + gc[0])*(1.0 - gc[0]); + SHAPE_FUN_MACRO_END; +} + +/*! + * Init Triangle Reference coordinates ans Shape function. + * Case A. + */ +void GaussInfo::tria3aInit() +{ + LOCAL_COORD_MACRO_BEGIN; + case 0: + coords[0] = -1.0; + coords[1] = 1.0; + break; + case 1: + coords[0] = -1.0; + coords[1] = -1.0; + break; + case 2: + coords[0] = 1.0; + coords[1] = -1.0; + break; + LOCAL_COORD_MACRO_END; + + SHAPE_FUN_MACRO_BEGIN; + funValue[0] = 0.5*(1.0 + gc[1]); + funValue[1] = -0.5*(gc[0] + gc[1]); + funValue[2] = 0.5*(1.0 + gc[0]); + SHAPE_FUN_MACRO_END; +} + +/*! + * Init Triangle Reference coordinates ans Shape function. + * Case B. + */ +void GaussInfo::tria3bInit() +{ + LOCAL_COORD_MACRO_BEGIN; + case 0: + coords[0] = 0.0; + coords[1] = 0.0; + break; + case 1: + coords[0] = 1.0; + coords[1] = 0.0; + break; + case 2: + coords[0] = 0.0; + coords[1] = 1.0; + break; + LOCAL_COORD_MACRO_END; + + SHAPE_FUN_MACRO_BEGIN; + funValue[0] = 1.0 - gc[0] - gc[1]; + funValue[1] = gc[0]; + funValue[2] = gc[1]; + SHAPE_FUN_MACRO_END; +} + +/*! + * Init Quadratic Triangle Reference coordinates ans Shape function. + * Case A. + */ +void GaussInfo::tria6aInit() +{ + LOCAL_COORD_MACRO_BEGIN; + case 0: + coords[0] = -1.0; + coords[1] = 1.0; + break; + case 1: + coords[0] = -1.0; + coords[1] = -1.0; + break; + case 2: + coords[0] = 1.0; + coords[1] = -1.0; + break; + case 3: + coords[0] = -1.0; + coords[1] = 1.0; + break; + case 4: + coords[0] = 0.0; + coords[1] = -1.0; + break; + case 5: + coords[0] = 0.0; + coords[1] = 0.0; + break; + LOCAL_COORD_MACRO_END; + + SHAPE_FUN_MACRO_BEGIN; + funValue[0] = 0.5*(1.0 + gc[1])*gc[1]; + funValue[1] = 0.5*(gc[0] + gc[1])*(gc[0] + gc[1] + 1); + funValue[2] = 0.5*(1.0 + gc[0])*gc[0]; + funValue[3] = -1.0*(1.0 + gc[1])*(gc[0] + gc[1]); + funValue[4] = -1.0*(1.0 + gc[0])*(gc[0] + gc[1]); + funValue[5] = (1.0 + gc[1])*(1.0 + gc[1]); + SHAPE_FUN_MACRO_END; +} + +/*! + * Init Quadratic Triangle Reference coordinates ans Shape function. + * Case B. + */ +void GaussInfo::tria6bInit() +{ + LOCAL_COORD_MACRO_BEGIN; + case 0: + coords[0] = 0.0; + coords[1] = 0.0; + break; + + case 1: + coords[0] = 1.0; + coords[1] = 0.0; + break; + + case 2: + coords[0] = 0.0; + coords[1] = 1.0; + break; + + case 3: + coords[0] = 0.5; + coords[1] = 0.0; + break; + + case 4: + coords[0] = 0.5; + coords[1] = 0.5; + break; + + case 5: + coords[0] = 0.0; + coords[1] = 0.5; + break; + + LOCAL_COORD_MACRO_END; + + SHAPE_FUN_MACRO_BEGIN; + funValue[0] = (1.0 - gc[0] - gc[1])*(1.0 - 2.0*gc[0] - 2.0*gc[1]); + funValue[1] = gc[0]*(2.0*gc[0] - 1.0); + funValue[2] = gc[1]*(2.0*gc[1] - 1.0); + funValue[3] = 4.0*gc[0]*(1.0 - gc[0] - gc[1]); + funValue[4] = 4.0*gc[0]*gc[1]; + funValue[5] = 4.0*gc[1]*(1.0 - gc[0] - gc[1]); + SHAPE_FUN_MACRO_END; +} + +void GaussInfo::tria7aInit() +{ + LOCAL_COORD_MACRO_BEGIN; + case 0: + coords[0] = 0.0; + coords[1] = 0.0; + break; + case 1: + coords[0] = 1.0; + coords[1] = 0.0; + break; + case 2: + coords[0] = 0.0; + coords[1] = 1.0; + break; + case 3: + coords[0] = 0.5; + coords[1] = 0.0; + break; + case 4: + coords[0] = 0.5; + coords[1] = 0.5; + break; + case 5: + coords[0] = 0.0; + coords[1] = 0.5; + break; + case 6: + coords[0] = 0.3333333333333333; + coords[1] = 0.3333333333333333; + break; + + LOCAL_COORD_MACRO_END; + + SHAPE_FUN_MACRO_BEGIN; + funValue[0]=1-3*(gc[0]+gc[1])+2*(gc[0]*gc[0]+gc[1]*gc[1])+7*gc[0]*gc[1]-3*gc[0]*gc[1]*(gc[0]+gc[1]); + funValue[1]=gc[0]*(-1+2*gc[0]+3*gc[1]-3*gc[1]*(gc[0]+gc[1])); + funValue[2]=gc[1]*(-1.+3.*gc[0]+2.*gc[1]-3.*gc[0]*(gc[0]+gc[1])); + funValue[3]=4*gc[0]*(1-gc[0]-4*gc[1]+3*gc[1]*(gc[0]+gc[1])); + funValue[4]=4*gc[0]*gc[1]*(-2+3*(gc[0]+gc[1])); + funValue[5]=4*gc[1]*(1-4*gc[0]-gc[1]+3*gc[0]*(gc[0]+gc[1])); + funValue[6]=27*gc[0]*gc[1]*(1-gc[0]-gc[1]); + SHAPE_FUN_MACRO_END; +} + +/*! + * Init Quadrangle Reference coordinates ans Shape function. + * Case A. + */ +void GaussInfo::quad4aInit() +{ + LOCAL_COORD_MACRO_BEGIN; + case 0: + coords[0] = -1.0; + coords[1] = 1.0; + break; + case 1: + coords[0] = -1.0; + coords[1] = -1.0; + break; + case 2: + coords[0] = 1.0; + coords[1] = -1.0; + break; + case 3: + coords[0] = 1.0; + coords[1] = 1.0; + break; + + LOCAL_COORD_MACRO_END; + + SHAPE_FUN_MACRO_BEGIN; + funValue[0] = 0.25*(1.0 + gc[1])*(1.0 - gc[0]); + funValue[1] = 0.25*(1.0 - gc[1])*(1.0 - gc[0]); + funValue[2] = 0.25*(1.0 - gc[1])*(1.0 + gc[0]); + funValue[3] = 0.25*(1.0 + gc[0])*(1.0 + gc[1]); + SHAPE_FUN_MACRO_END; +} + +/*! + * Init Quadrangle Reference coordinates ans Shape function. + * Case B. + */ +void GaussInfo::quad4bInit() +{ + LOCAL_COORD_MACRO_BEGIN; + case 0: + coords[0] = -1.0; + coords[1] = -1.0; + break; + case 1: + coords[0] = 1.0; + coords[1] = -1.0; + break; + case 2: + coords[0] = 1.0; + coords[1] = 1.0; + break; + case 3: + coords[0] = -1.0; + coords[1] = 1.0; + break; + + LOCAL_COORD_MACRO_END; + + SHAPE_FUN_MACRO_BEGIN; + funValue[0] = 0.25*(1.0 - gc[0])*(1.0 - gc[1]); + funValue[1] = 0.25*(1.0 + gc[0])*(1.0 - gc[1]); + funValue[2] = 0.25*(1.0 + gc[0])*(1.0 + gc[1]); + funValue[3] = 0.25*(1.0 - gc[0])*(1.0 + gc[1]); + SHAPE_FUN_MACRO_END; +} + +void GaussInfo::quad4cInit() +{ + LOCAL_COORD_MACRO_BEGIN; + case 0: + coords[0] = -1.0; + coords[1] = -1.0; + break; + case 1: + coords[0] = -1.0; + coords[1] = 1.0; + break; + case 2: + coords[0] = 1.0; + coords[1] = 1.0; + break; + case 3: + coords[0] = 1.0; + coords[1] = -1.0; + break; + + LOCAL_COORD_MACRO_END; + + SHAPE_FUN_MACRO_BEGIN; + funValue[0] = 0.25*(1.0 - gc[0])*(1.0 - gc[1]); + funValue[1] = 0.25*(1.0 - gc[0])*(1.0 + gc[1]); + funValue[2] = 0.25*(1.0 + gc[0])*(1.0 + gc[1]); + funValue[3] = 0.25*(1.0 + gc[0])*(1.0 - gc[1]); + SHAPE_FUN_MACRO_END; +} + +/*! + * This shapefunc map is same as degenerated seg2Init + */ +void GaussInfo::quad4DegSeg2Init() +{ + LOCAL_COORD_MACRO_BEGIN; + case 0: + coords[0] = -1.0; + coords[1] = 0.0; + break; + case 1: + coords[0] = 1.0; + coords[1] = 0.0; + break; + case 2: + coords[0] = 0.0; + coords[1] = 0.0; + break; + case 3: + coords[0] = 0.0; + coords[1] = 0.0; + break; + LOCAL_COORD_MACRO_END; + + SHAPE_FUN_MACRO_BEGIN; + funValue[0] = 0.5*(1.0 - gc[0]); + funValue[1] = 0.5*(1.0 + gc[0]); + funValue[2] = 0.; + funValue[3] = 0.; + SHAPE_FUN_MACRO_END; +} + +/*! + * Init Quadratic Quadrangle Reference coordinates ans Shape function. + * Case A. + */ +void GaussInfo::quad8aInit() +{ + LOCAL_COORD_MACRO_BEGIN; + case 0: + coords[0] = -1.0; + coords[1] = 1.0; + break; + case 1: + coords[0] = -1.0; + coords[1] = -1.0; + break; + case 2: + coords[0] = 1.0; + coords[1] = -1.0; + break; + case 3: + coords[0] = 1.0; + coords[1] = 1.0; + break; + case 4: + coords[0] = -1.0; + coords[1] = 0.0; + break; + case 5: + coords[0] = 0.0; + coords[1] = -1.0; + break; + case 6: + coords[0] = 1.0; + coords[1] = 0.0; + break; + case 7: + coords[0] = 0.0; + coords[1] = 1.0; + break; + LOCAL_COORD_MACRO_END; + + SHAPE_FUN_MACRO_BEGIN; + funValue[0] = 0.25*(1.0 + gc[1])*(1.0 - gc[0])*(gc[1] - gc[0] - 1.0); + funValue[1] = 0.25*(1.0 - gc[1])*(1.0 - gc[0])*(-gc[1] - gc[0] - 1.0); + funValue[2] = 0.25*(1.0 - gc[1])*(1.0 + gc[0])*(-gc[1] + gc[0] - 1.0); + funValue[3] = 0.25*(1.0 + gc[1])*(1.0 + gc[0])*(gc[1] + gc[0] - 1.0); + funValue[4] = 0.5*(1.0 - gc[0])*(1.0 - gc[1])*(1.0 + gc[1]); + funValue[5] = 0.5*(1.0 - gc[1])*(1.0 - gc[0])*(1.0 + gc[0]); + funValue[6] = 0.5*(1.0 + gc[0])*(1.0 - gc[1])*(1.0 + gc[1]); + funValue[7] = 0.5*(1.0 + gc[1])*(1.0 - gc[0])*(1.0 + gc[0]); + SHAPE_FUN_MACRO_END; +} + +/*! + * Init Quadratic Quadrangle Reference coordinates ans Shape function. + * Case B. + */ +void GaussInfo::quad8bInit() +{ + LOCAL_COORD_MACRO_BEGIN; + case 0: + coords[0] = -1.0; + coords[1] = -1.0; + break; + case 1: + coords[0] = 1.0; + coords[1] = -1.0; + break; + case 2: + coords[0] = 1.0; + coords[1] = 1.0; + break; + case 3: + coords[0] = -1.0; + coords[1] = 1.0; + break; + case 4: + coords[0] = 0.0; + coords[1] = -1.0; + break; + case 5: + coords[0] = 1.0; + coords[1] = 0.0; + break; + case 6: + coords[0] = 0.0; + coords[1] = 1.0; + break; + case 7: + coords[0] = -1.0; + coords[1] = 0.0; + break; + LOCAL_COORD_MACRO_END; + + SHAPE_FUN_MACRO_BEGIN; + funValue[0] = 0.25*(1.0 - gc[0])*(1.0 - gc[1])*(-1.0 - gc[0] - gc[1]); + funValue[1] = 0.25*(1.0 + gc[0])*(1.0 - gc[1])*(-1.0 + gc[0] - gc[1]); + funValue[2] = 0.25*(1.0 + gc[0])*(1.0 + gc[1])*(-1.0 + gc[0] + gc[1]); + funValue[3] = 0.25*(1.0 - gc[0])*(1.0 + gc[1])*(-1.0 - gc[0] + gc[1]); + funValue[4] = 0.5*(1.0 - gc[0]*gc[0])*(1.0 - gc[1]); + funValue[5] = 0.5*(1.0 - gc[1]*gc[1])*(1.0 + gc[0]); + funValue[6] = 0.5*(1.0 - gc[0]*gc[0])*(1.0 + gc[1]); + funValue[7] = 0.5*(1.0 - gc[1]*gc[1])*(1.0 - gc[0]); + SHAPE_FUN_MACRO_END; +} + +void GaussInfo::quad9aInit() +{ + LOCAL_COORD_MACRO_BEGIN; + case 0: + coords[0] = -1.0; + coords[1] = -1.0; + break; + case 1: + coords[0] = 1.0; + coords[1] = -1.0; + break; + case 2: + coords[0] = 1.0; + coords[1] = 1.0; + break; + case 3: + coords[0] = -1.0; + coords[1] = 1.0; + break; + case 4: + coords[0] = 0.0; + coords[1] = -1.0; + break; + case 5: + coords[0] = 1.0; + coords[1] = 0.0; + break; + case 6: + coords[0] = 0.0; + coords[1] = 1.0; + break; + case 7: + coords[0] = -1.0; + coords[1] = 0.0; + break; + case 8: + coords[0] = 0.0; + coords[1] = 0.0; + break; + LOCAL_COORD_MACRO_END; + + SHAPE_FUN_MACRO_BEGIN; + funValue[0] = 0.25*gc[0]*gc[1]*(gc[0]-1.)*(gc[1]-1.); + funValue[1] = 0.25*gc[0]*gc[1]*(gc[0]+1.)*(gc[1]-1.); + funValue[2] = 0.25*gc[0]*gc[1]*(gc[0]+1.)*(gc[1]+1.); + funValue[3] = 0.25*gc[0]*gc[1]*(gc[0]-1.)*(gc[1]+1.); + funValue[4] = 0.5*(1.-gc[0]*gc[0])*gc[1]*(gc[1]-1.); + funValue[5] = 0.5*gc[0]*(gc[0]+1.)*(1.-gc[1]*gc[1]); + funValue[6] = 0.5*(1.-gc[0]*gc[0])*gc[1]*(gc[1]+1.); + funValue[7] = 0.5*gc[0]*(gc[0]-1.)*(1.-gc[1]*gc[1]); + funValue[8] = (1.-gc[0]*gc[0])*(1.-gc[1]*gc[1]); + SHAPE_FUN_MACRO_END; +} + +/*! + * Init Tetrahedron Reference coordinates ans Shape function. + * Case A. + */ +void GaussInfo::tetra4aInit() +{ + LOCAL_COORD_MACRO_BEGIN; + case 0: + coords[0] = 0.0; + coords[1] = 1.0; + coords[2] = 0.0; + break; + case 1: + coords[0] = 0.0; + coords[1] = 0.0; + coords[2] = 1.0; + break; + case 2: + coords[0] = 0.0; + coords[1] = 0.0; + coords[2] = 0.0; + break; + case 3: + coords[0] = 1.0; + coords[1] = 0.0; + coords[2] = 0.0; + break; + LOCAL_COORD_MACRO_END; + + SHAPE_FUN_MACRO_BEGIN; + funValue[0] = gc[1]; + funValue[1] = gc[2]; + funValue[2] = 1.0 - gc[0] - gc[1] - gc[2]; + funValue[3] = gc[0]; + SHAPE_FUN_MACRO_END; +} + +/*! + * Init Tetrahedron Reference coordinates ans Shape function. + * Case B. + */ +void GaussInfo::tetra4bInit() +{ + LOCAL_COORD_MACRO_BEGIN; + case 0: + coords[0] = 0.0; + coords[1] = 1.0; + coords[2] = 0.0; + break; + case 2: + coords[0] = 0.0; + coords[1] = 0.0; + coords[2] = 1.0; + break; + case 1: + coords[0] = 0.0; + coords[1] = 0.0; + coords[2] = 0.0; + break; + case 3: + coords[0] = 1.0; + coords[1] = 0.0; + coords[2] = 0.0; + break; + LOCAL_COORD_MACRO_END; + + SHAPE_FUN_MACRO_BEGIN; + funValue[0] = gc[1]; + funValue[2] = gc[2]; + funValue[1] = 1.0 - gc[0] - gc[1] - gc[2]; + funValue[3] = gc[0]; + SHAPE_FUN_MACRO_END; + +} + +/*! + * Init Quadratic Tetrahedron Reference coordinates ans Shape function. + * Case A. + */ +void GaussInfo::tetra10aInit() +{ + LOCAL_COORD_MACRO_BEGIN; + case 0: + coords[0] = 0.0; + coords[1] = 1.0; + coords[2] = 0.0; + break; + case 1: + coords[0] = 0.0; + coords[1] = 0.0; + coords[2] = 1.0; + break; + case 2: + coords[0] = 0.0; + coords[1] = 0.0; + coords[2] = 0.0; + break; + case 3: + coords[0] = 1.0; + coords[1] = 0.0; + coords[2] = 0.0; + break; + case 4: + coords[0] = 0.0; + coords[1] = 0.5; + coords[2] = 0.5; + break; + case 5: + coords[0] = 0.0; + coords[1] = 0.0; + coords[2] = 0.5; + break; + case 6: + coords[0] = 0.0; + coords[1] = 0.5; + coords[2] = 0.0; + break; + case 7: + coords[0] = 0.5; + coords[1] = 0.5; + coords[2] = 0.0; + break; + case 8: + coords[0] = 0.5; + coords[1] = 0.0; + coords[2] = 0.5; + break; + case 9: + coords[0] = 0.5; + coords[1] = 0.0; + coords[2] = 0.0; + break; + LOCAL_COORD_MACRO_END; + + SHAPE_FUN_MACRO_BEGIN; + funValue[0] = gc[1]*(2.0*gc[1] - 1.0); + funValue[1] = gc[2]*(2.0*gc[2] - 1.0); + funValue[2] = (1.0 - gc[0] - gc[1] - gc[2])*(1.0 - 2.0*gc[0] - 2.0*gc[1] - 2.0*gc[2]); + funValue[3] = gc[0]*(2.0*gc[0] - 1.0); + funValue[4] = 4.0*gc[1]*gc[2]; + funValue[5] = 4.0*gc[2]*(1.0 - gc[0] - gc[1] - gc[2]); + funValue[6] = 4.0*gc[1]*(1.0 - gc[0] - gc[1] - gc[2]); + funValue[7] = 4.0*gc[0]*gc[1]; + funValue[8] = 4.0*gc[0]*gc[2]; + funValue[9] = 4.0*gc[0]*(1.0 - gc[0] - gc[1] - gc[2]); + SHAPE_FUN_MACRO_END; +} + +/*! + * Init Quadratic Tetrahedron Reference coordinates ans Shape function. + * Case B. + */ +void GaussInfo::tetra10bInit() +{ + LOCAL_COORD_MACRO_BEGIN; + case 0: + coords[0] = 0.0; + coords[1] = 1.0; + coords[2] = 0.0; + break; + case 2: + coords[0] = 0.0; + coords[1] = 0.0; + coords[2] = 1.0; + break; + case 1: + coords[0] = 0.0; + coords[1] = 0.0; + coords[2] = 0.0; + break; + case 3: + coords[0] = 1.0; + coords[1] = 0.0; + coords[2] = 0.0; + break; + case 6: + coords[0] = 0.0; + coords[1] = 0.5; + coords[2] = 0.5; + break; + case 5: + coords[0] = 0.0; + coords[1] = 0.0; + coords[2] = 0.5; + break; + case 4: + coords[0] = 0.0; + coords[1] = 0.5; + coords[2] = 0.0; + break; + case 7: + coords[0] = 0.5; + coords[1] = 0.5; + coords[2] = 0.0; + break; + case 9: + coords[0] = 0.5; + coords[1] = 0.0; + coords[2] = 0.5; + break; + case 8: + coords[0] = 0.5; + coords[1] = 0.0; + coords[2] = 0.0; + break; + LOCAL_COORD_MACRO_END; + + SHAPE_FUN_MACRO_BEGIN; + funValue[0] = gc[1]*(2.0*gc[1] - 1.0); + funValue[2] = gc[2]*(2.0*gc[2] - 1.0); + funValue[1] = (1.0 - gc[0] - gc[1] - gc[2])*(1.0 - 2.0*gc[0] - 2.0*gc[1] - 2.0*gc[2]); + funValue[3] = gc[0]*(2.0*gc[0] - 1.0); + funValue[6] = 4.0*gc[1]*gc[2]; + funValue[5] = 4.0*gc[2]*(1.0 - gc[0] - gc[1] - gc[2]); + funValue[4] = 4.0*gc[1]*(1.0 - gc[0] - gc[1] - gc[2]); + funValue[7] = 4.0*gc[0]*gc[1]; + funValue[9] = 4.0*gc[0]*gc[2]; + funValue[8] = 4.0*gc[0]*(1.0 - gc[0] - gc[1] - gc[2]); + SHAPE_FUN_MACRO_END; +} + +/*! + * Init Pyramid Reference coordinates ans Shape function. + * Case A. + */ +void GaussInfo::pyra5aInit() +{ + LOCAL_COORD_MACRO_BEGIN; + case 0: + coords[0] = 1.0; + coords[1] = 0.0; + coords[2] = 0.0; + break; + case 1: + coords[0] = 0.0; + coords[1] = 1.0; + coords[2] = 0.0; + break; + case 2: + coords[0] = -1.0; + coords[1] = 0.0; + coords[2] = 0.0; + break; + case 3: + coords[0] = 0.0; + coords[1] = -1.0; + coords[2] = 0.0; + break; + case 4: + coords[0] = 0.0; + coords[1] = 0.0; + coords[2] = 1.0; + break; + LOCAL_COORD_MACRO_END; + + SHAPE_FUN_MACRO_BEGIN; + funValue[0] = 0.25*(-gc[0] + gc[1] - 1.0)*(-gc[0] - gc[1] - 1.0)*(1.0 - gc[2]); + funValue[1] = 0.25*(-gc[0] - gc[1] - 1.0)*(+gc[0] - gc[1] - 1.0)*(1.0 - gc[2]); + funValue[2] = 0.25*(+gc[0] + gc[1] - 1.0)*(+gc[0] - gc[1] - 1.0)*(1.0 - gc[2]); + funValue[3] = 0.25*(+gc[0] + gc[1] - 1.0)*(-gc[0] + gc[1] - 1.0)*(1.0 - gc[2]); + funValue[4] = gc[2]; + SHAPE_FUN_MACRO_END; +} +/*! + * Init Pyramid Reference coordinates ans Shape function. + * Case B. + */ +void GaussInfo::pyra5bInit() +{ + LOCAL_COORD_MACRO_BEGIN; + case 0: + coords[0] = 1.0; + coords[1] = 0.0; + coords[2] = 0.0; + break; + case 3: + coords[0] = 0.0; + coords[1] = 1.0; + coords[2] = 0.0; + break; + case 2: + coords[0] = -1.0; + coords[1] = 0.0; + coords[2] = 0.0; + break; + case 1: + coords[0] = 0.0; + coords[1] = -1.0; + coords[2] = 0.0; + break; + case 4: + coords[0] = 0.0; + coords[1] = 0.0; + coords[2] = 1.0; + break; + LOCAL_COORD_MACRO_END; + + SHAPE_FUN_MACRO_BEGIN; + funValue[0] = 0.25*(-gc[0] + gc[1] - 1.0)*(-gc[0] - gc[1] - 1.0)*(1.0 - gc[2]); + funValue[3] = 0.25*(-gc[0] - gc[1] - 1.0)*(+gc[0] - gc[1] - 1.0)*(1.0 - gc[2]); + funValue[2] = 0.25*(+gc[0] + gc[1] - 1.0)*(+gc[0] - gc[1] - 1.0)*(1.0 - gc[2]); + funValue[1] = 0.25*(+gc[0] + gc[1] - 1.0)*(-gc[0] + gc[1] - 1.0)*(1.0 - gc[2]); + funValue[4] = gc[2]; + SHAPE_FUN_MACRO_END; +} + +/*! + * Init Quadratic Pyramid Reference coordinates ans Shape function. + * Case A. + */ +void GaussInfo::pyra13aInit() +{ + LOCAL_COORD_MACRO_BEGIN; + case 0: + coords[0] = 1.0; + coords[1] = 0.0; + coords[2] = 0.0; + break; + case 1: + coords[0] = 0.0; + coords[1] = 1.0; + coords[2] = 0.0; + break; + case 2: + coords[0] = -1.0; + coords[1] = 0.0; + coords[2] = 0.0; + break; + case 3: + coords[0] = 0.0; + coords[1] = -1.0; + coords[2] = 0.0; + break; + case 4: + coords[0] = 0.0; + coords[1] = 0.0; + coords[2] = 1.0; + break; + + case 5: + coords[0] = 0.5; + coords[1] = 0.5; + coords[2] = 0.0; + break; + case 6: + coords[0] = -0.5; + coords[1] = 0.5; + coords[2] = 0.0; + break; + case 7: + coords[0] = -0.5; + coords[1] = -0.5; + coords[2] = 0.0; + break; + case 8: + coords[0] = 0.5; + coords[1] = -0.5; + coords[2] = 0.0; + break; + case 9: + coords[0] = 0.5; + coords[1] = 0.0; + coords[2] = 0.5; + break; + case 10: + coords[0] = 0.0; + coords[1] = 0.5; + coords[2] = 0.5; + break; + case 11: + coords[0] = -0.5; + coords[1] = 0.0; + coords[2] = 0.5; + break; + case 12: + coords[0] = 0.0; + coords[1] = -0.5; + coords[2] = 0.5; + break; + LOCAL_COORD_MACRO_END; + + SHAPE_FUN_MACRO_BEGIN; + funValue[0] = 0.5*(-gc[0] + gc[1] + gc[2] - 1.0)*(-gc[0] - gc[1] + gc[2] - 1.0)* + (gc[0] - 0.5)/(1.0 - gc[2]); + funValue[1] = 0.5*(-gc[0] - gc[1] + gc[2] - 1.0)*(+gc[0] - gc[1] + gc[2] - 1.0)* + (gc[1] - 0.5)/(1.0 - gc[2]); + funValue[2] = 0.5*(+gc[0] - gc[1] + gc[2] - 1.0)*(+gc[0] + gc[1] + gc[2] - 1.0)* + (-gc[0] - 0.5)/(1.0 - gc[2]); + funValue[3] = 0.5*(+gc[0] + gc[1] + gc[2] - 1.0)*(-gc[0] + gc[1] + gc[2] - 1.0)* + (-gc[1] - 0.5)/(1.0 - gc[2]); + + funValue[4] = 2.0*gc[2]*(gc[2] - 0.5); + + funValue[5] = 0.5*(-gc[0] + gc[1] + gc[2] - 1.0)*(-gc[0] - gc[1] + gc[2] - 1.0)* + (gc[0] - gc[1] + gc[2] - 1.0)/(1.0 - gc[2]); + funValue[6] = 0.5*(-gc[0] - gc[1] + gc[2] - 1.0)*(gc[0] - gc[1] + gc[2] - 1.0)* + (gc[0] + gc[1] + gc[2] - 1.0)/(1.0 - gc[2]); + funValue[7] = 0.5*(gc[0] - gc[1] + gc[2] - 1.0)*(gc[0] + gc[1] + gc[2] - 1.0)* + (-gc[0] + gc[1] + gc[2] - 1.0)/(1.0 - gc[2]); + funValue[8] = 0.5*(gc[0] + gc[1] + gc[2] - 1.0)*(-gc[0] + gc[1] + gc[2] - 1.0)* + (-gc[0] - gc[1] + gc[2] - 1.0)/(1.0 - gc[2]); + + funValue[9] = 0.5*gc[2]*(-gc[0] + gc[1] + gc[2] - 1.0)*(-gc[0] - gc[1] + gc[2] - 1.0)/ + (1.0 - gc[2]); + funValue[10] = 0.5*gc[2]*(-gc[0] - gc[1] + gc[2] - 1.0)*(gc[0] - gc[1] + gc[2] - 1.0)/ + (1.0 - gc[2]); + funValue[11] = 0.5*gc[2]*(gc[0] - gc[1] + gc[2] - 1.0)*(gc[0] + gc[1] + gc[2] - 1.0)/ + (1.0 - gc[2]); + funValue[12] = 0.5*gc[2]*(gc[0] + gc[1] + gc[2] - 1.0)*(-gc[0] + gc[1] + gc[2] - 1.0)/ + (1.0 - gc[2]); + SHAPE_FUN_MACRO_END; +} + +/*! + * Init Quadratic Pyramid Reference coordinates ans Shape function. + * Case B. + */ +void GaussInfo::pyra13bInit() +{ + LOCAL_COORD_MACRO_BEGIN; + case 0: + coords[0] = 1.0; + coords[1] = 0.0; + coords[2] = 0.0; + break; + case 1: + coords[0] = 0.0; + coords[1] = -1.0; + coords[2] = 0.0; + break; + case 2: + coords[0] = -1.0; + coords[1] = 0.0; + coords[2] = 0.0; + break; + case 3: + coords[0] = 0.0; + coords[1] = 1.0; + coords[2] = 0.0; + break; + case 4: + coords[0] = 0.0; + coords[1] = 0.0; + coords[2] = 1.0; + break; + case 5: + coords[0] = 0.5; + coords[1] = -0.5; + coords[2] = 0.0; + break; + case 6: + coords[0] = -0.5; + coords[1] = -0.5; + coords[2] = 0.0; + break; + case 7: + coords[0] = -0.5; + coords[1] = 0.5; + coords[2] = 0.0; + break; + case 8: + coords[0] = 0.5; + coords[1] = 0.5; + coords[2] = 0.0; + break; + case 9: + coords[0] = 0.5; + coords[1] = 0.0; + coords[2] = 0.5; + break; + case 10: + coords[0] = 0.0; + coords[1] = -0.5; + coords[2] = 0.5; + break; + case 11: + coords[0] = -0.5; + coords[1] = 0.0; + coords[2] = 0.5; + break; + case 12: + coords[0] = 0.0; + coords[1] = 0.5; + coords[2] = 0.5; + break; + LOCAL_COORD_MACRO_END; + + SHAPE_FUN_MACRO_BEGIN; + funValue[0] =0.5*(-gc[0]+gc[1]+gc[2]-1.0)*(-gc[0]-gc[1]+gc[2]-1.0)*(gc[0]-0.5)/(1.0-gc[2]); + funValue[1] =0.5*(+gc[0]+gc[1]+gc[2]-1.0)*(-gc[0]+gc[1]+gc[2]-1.0)*(-gc[1]-0.5)/(1.0-gc[2]); + funValue[2] =0.5*(+gc[0]-gc[1]+gc[2]-1.0)*(+gc[0]+gc[1]+gc[2]-1.0)*(-gc[0]-0.5)/(1.0-gc[2]); + funValue[3] =0.5*(-gc[0]-gc[1]+gc[2]-1.0)*(+gc[0]-gc[1]+gc[2]-1.0)*(gc[1]-0.5)/(1.0-gc[2]); + + funValue[4] =2.*gc[2]*(gc[2]-0.5); + + funValue[5] =-0.5*(gc[0]+gc[1]+gc[2]-1.0)*(-gc[0]+gc[1]+gc[2]-1.0)*(-gc[0]-gc[1]+gc[2]-1.0)/(1.0-gc[2]); + funValue[6] =-0.5*(gc[0]-gc[1]+gc[2]-1.0)*(gc[0]+gc[1]+gc[2]-1.0)*(-gc[0]+gc[1]+gc[2]-1.0)/(1.0-gc[2]); + funValue[7] =-0.5*(-gc[0]-gc[1]+gc[2]-1.0)*(gc[0]-gc[1]+gc[2]-1.0)*(gc[0]+gc[1]+gc[2]-1.0)/(1.0-gc[2]); + funValue[8] =-0.5*(-gc[0]+gc[1]+gc[2]-1.0)*(-gc[0]-gc[1]+gc[2]-1.0)*(gc[0]-gc[1]+gc[2]-1.0)/(1.0-gc[2]); + + funValue[9] =gc[2]*(-gc[0]+gc[1]+gc[2]-1.0)*(-gc[0]-gc[1]+gc[2]-1.0)/(1.0-gc[2]); + funValue[10]=gc[2]*(gc[0]+gc[1]+gc[2]-1.0)*(-gc[0]+gc[1]+gc[2]-1.0)/(1.0-gc[2]); + funValue[11]=gc[2]*(gc[0]-gc[1]+gc[2]-1.0)*(gc[0]+gc[1]+gc[2]-1.0)/(1.0-gc[2]); + funValue[12]=gc[2]*(-gc[0]-gc[1]+gc[2]-1.0)*(gc[0]-gc[1]+gc[2]-1.0)/(1.0-gc[2]); + + SHAPE_FUN_MACRO_END; +} + + +/*! + * Init Pentahedron Reference coordinates and Shape function. + * Case A. + */ +void GaussInfo::penta6aInit() +{ + LOCAL_COORD_MACRO_BEGIN; + case 0: + coords[0] = -1.0; + coords[1] = 1.0; + coords[2] = 0.0; + break; + case 1: + coords[0] = -1.0; + coords[1] = -0.0; + coords[2] = 1.0; + break; + case 2: + coords[0] = -1.0; + coords[1] = 0.0; + coords[2] = 0.0; + break; + case 3: + coords[0] = 1.0; + coords[1] = 1.0; + coords[2] = 0.0; + break; + case 4: + coords[0] = 1.0; + coords[1] = 0.0; + coords[2] = 1.0; + break; + case 5: + coords[0] = 1.0; + coords[1] = 0.0; + coords[2] = 0.0; + break; + LOCAL_COORD_MACRO_END; + + SHAPE_FUN_MACRO_BEGIN; + funValue[0] = 0.5*gc[1]*(1.0 - gc[0]); + funValue[1] = 0.5*gc[2]*(1.0 - gc[0]); + funValue[2] = 0.5*(1.0 - gc[1] - gc[2])*(1.0 - gc[0]); + + funValue[3] = 0.5*gc[1]*(gc[0] + 1.0); + funValue[4] = 0.5*gc[2]*(gc[0] + 1.0); + funValue[5] = 0.5*(1.0 - gc[1] - gc[2])*(1.0 + gc[0]); + SHAPE_FUN_MACRO_END; +} + +/*! + * Init Pentahedron Reference coordinates and Shape function. + * Case B. + */ +void GaussInfo::penta6bInit() +{ + LOCAL_COORD_MACRO_BEGIN; + case 0: + coords[0] = -1.0; + coords[1] = 1.0; + coords[2] = 0.0; + break; + case 2: + coords[0] = -1.0; + coords[1] = -0.0; + coords[2] = 1.0; + break; + case 1: + coords[0] = -1.0; + coords[1] = 0.0; + coords[2] = 0.0; + break; + case 3: + coords[0] = 1.0; + coords[1] = 1.0; + coords[2] = 0.0; + break; + case 5: + coords[0] = 1.0; + coords[1] = 0.0; + coords[2] = 1.0; + break; + case 4: + coords[0] = 1.0; + coords[1] = 0.0; + coords[2] = 0.0; + break; + LOCAL_COORD_MACRO_END; + + SHAPE_FUN_MACRO_BEGIN; + funValue[0] = 0.5*gc[1]*(1.0 - gc[0]); + funValue[2] = 0.5*gc[2]*(1.0 - gc[0]); + funValue[1] = 0.5*(1.0 - gc[1] - gc[2])*(1.0 - gc[0]); + funValue[3] = 0.5*gc[1]*(gc[0] + 1.0); + funValue[5] = 0.5*gc[2]*(gc[0] + 1.0); + funValue[4] = 0.5*(1.0 - gc[1] - gc[2])*(1.0 + gc[0]); + SHAPE_FUN_MACRO_END; +} + +/*! + * This shapefunc map is same as degenerated tria3aInit + */ +void GaussInfo::penta6DegTria3aInit() +{ + LOCAL_COORD_MACRO_BEGIN; + case 0: + coords[0] = -1.0; + coords[1] = 1.0; + coords[2] = 0.0; + break; + case 1: + coords[0] = -1.0; + coords[1] = -1.0; + coords[2] = 0.0; + break; + case 2: + coords[0] = 1.0; + coords[1] = -1.0; + coords[2] = 0.0; + break; + case 3: + coords[0] = 0.0; + coords[1] = 0.0; + coords[2] = 0.0; + break; + case 4: + coords[0] = 0.0; + coords[1] = 0.0; + coords[2] = 0.0; + break; + case 5: + coords[0] = 0.0; + coords[1] = 0.0; + coords[2] = 0.0; + break; + LOCAL_COORD_MACRO_END; + + SHAPE_FUN_MACRO_BEGIN; + funValue[0] = 0.5*(1.0 + gc[1]); + funValue[1] = -0.5*(gc[0] + gc[1]); + funValue[2] = 0.5*(1.0 + gc[0]); + funValue[3] = 0.; + funValue[4] = 0.; + funValue[5] = 0.; + SHAPE_FUN_MACRO_END; +} + +/*! + * This shapefunc map is same as degenerated tria3bInit + */ +void GaussInfo::penta6DegTria3bInit() +{ + LOCAL_COORD_MACRO_BEGIN; + case 0: + coords[0] = 0.0; + coords[1] = 0.0; + coords[2] = 0.0; + break; + case 1: + coords[0] = 1.0; + coords[1] = 0.0; + coords[2] = 0.0; + break; + case 2: + coords[0] = 0.0; + coords[1] = 1.0; + coords[2] = 0.0; + break; + case 3: + coords[0] = 0.0; + coords[1] = 0.0; + coords[2] = 0.0; + break; + case 4: + coords[0] = 0.0; + coords[1] = 0.0; + coords[2] = 0.0; + break; + case 5: + coords[0] = 0.0; + coords[1] = 0.0; + coords[2] = 0.0; + break; + LOCAL_COORD_MACRO_END; + + SHAPE_FUN_MACRO_BEGIN; + funValue[0] = 1.0 - gc[0] - gc[1]; + funValue[1] = gc[0]; + funValue[2] = gc[1]; + funValue[3] = 0.; + funValue[4] = 0.; + funValue[5] = 0.; + SHAPE_FUN_MACRO_END; +} + +/*! + * Init Pentahedron Reference coordinates and Shape function. + * Case A. + */ +void GaussInfo::penta15aInit() +{ + LOCAL_COORD_MACRO_BEGIN; + case 0: + coords[0] = -1.0; + coords[1] = 1.0; + coords[2] = 0.0; + break; + case 1: + coords[0] = -1.0; + coords[1] = -0.0; + coords[2] = 1.0; + break; + case 2: + coords[0] = -1.0; + coords[1] = 0.0; + coords[2] = 0.0; + break; + case 3: + coords[0] = 1.0; + coords[1] = 1.0; + coords[2] = 0.0; + break; + case 4: + coords[0] = 1.0; + coords[1] = 0.0; + coords[2] = 1.0; + break; + case 5: + coords[0] = 1.0; + coords[1] = 0.0; + coords[2] = 0.0; + break; + + case 6: + coords[0] = -1.0; + coords[1] = 0.5; + coords[2] = 0.5; + break; + case 7: + coords[0] = -1.0; + coords[1] = 0.0; + coords[2] = 0.5; + break; + case 8: + coords[0] = -1.0; + coords[1] = 0.5; + coords[2] = 0.0; + break; + case 9: + coords[0] = 0.0; + coords[1] = 1.0; + coords[2] = 0.0; + break; + case 10: + coords[0] = 0.0; + coords[1] = 0.0; + coords[2] = 1.0; + break; + case 11: + coords[0] = 0.0; + coords[1] = 0.0; + coords[2] = 0.0; + break; + case 12: + coords[0] = 1.0; + coords[1] = 0.5; + coords[2] = 0.5; + break; + case 13: + coords[0] = 1.0; + coords[1] = 0.0; + coords[2] = 0.5; + break; + case 14: + coords[0] = 1.0; + coords[1] = 0.5; + coords[2] = 0.0; + break; + LOCAL_COORD_MACRO_END; + + SHAPE_FUN_MACRO_BEGIN; + funValue[0] = 0.5*gc[1]*(1.0 - gc[0])*(2.0*gc[1] - 2.0 - gc[0]); + funValue[1] = 0.5*gc[2]*(1.0 - gc[0])*(2.0*gc[2] - 2.0 - gc[0]); + funValue[2] = 0.5*(gc[0] - 1.0)*(1.0 - gc[1] - gc[2])*(gc[0] + 2.0*gc[1] + 2.0*gc[2]); + + funValue[3] = 0.5*gc[1]*(1.0 + gc[0])*(2.0*gc[1] - 2.0 + gc[0]); + funValue[4] = 0.5*gc[2]*(1.0 + gc[0])*(2.0*gc[2] - 2.0 + gc[0]); + funValue[5] = 0.5*(-gc[0] - 1.0)*(1.0 - gc[1] - gc[2])*(-gc[0] + 2.0*gc[1] + 2.0*gc[2]); + + funValue[6] = 2.0*gc[1]*gc[2]*(1.0 - gc[0]); + funValue[7] = 2.0*gc[2]*(1.0 - gc[1] - gc[2])*(1.0 - gc[0]); + funValue[8] = 2.0*gc[1]*(1.0 - gc[1] - gc[2])*(1.0 - gc[0]); + + funValue[9] = gc[1]*(1.0 - gc[0]*gc[0]); + funValue[10] = gc[2]*(1.0 - gc[0]*gc[0]); + funValue[11] = (1.0 - gc[1] - gc[2])*(1.0 - gc[0]*gc[0]); + + funValue[12] = 2.0*gc[1]*gc[2]*(1.0 + gc[0]); + funValue[13] = 2.0*gc[2]*(1.0 - gc[1] - gc[2])*(1.0 + gc[0]); + funValue[14] = 2.0*gc[1]*(1.0 - gc[1] - gc[2])*(1.0 + gc[0]); + SHAPE_FUN_MACRO_END; +} + +/*! + * Init Qaudratic Pentahedron Reference coordinates and Shape function. + * Case B. + */ +void GaussInfo::penta15bInit() +{ + LOCAL_COORD_MACRO_BEGIN; + case 0: + coords[0] = -1.0; + coords[1] = 1.0; + coords[2] = 0.0; + break; + case 2: + coords[0] = -1.0; + coords[1] = -0.0; + coords[2] = 1.0; + break; + case 1: + coords[0] = -1.0; + coords[1] = 0.0; + coords[2] = 0.0; + break; + case 3: + coords[0] = 1.0; + coords[1] = 1.0; + coords[2] = 0.0; + break; + case 5: + coords[0] = 1.0; + coords[1] = 0.0; + coords[2] = 1.0; + break; + case 4: + coords[0] = 1.0; + coords[1] = 0.0; + coords[2] = 0.0; + break; + + case 8: + coords[0] = -1.0; + coords[1] = 0.5; + coords[2] = 0.5; + break; + case 7: + coords[0] = -1.0; + coords[1] = 0.0; + coords[2] = 0.5; + break; + case 6: + coords[0] = -1.0; + coords[1] = 0.5; + coords[2] = 0.0; + break; + case 12: + coords[0] = 0.0; + coords[1] = 1.0; + coords[2] = 0.0; + break; + case 14: + coords[0] = 0.0; + coords[1] = 0.0; + coords[2] = 1.0; + break; + case 13: + coords[0] = 0.0; + coords[1] = 0.0; + coords[2] = 0.0; + break; + case 11: + coords[0] = 1.0; + coords[1] = 0.5; + coords[2] = 0.5; + break; + case 10: + coords[0] = 1.0; + coords[1] = 0.0; + coords[2] = 0.5; + break; + case 9: + coords[0] = 1.0; + coords[1] = 0.5; + coords[2] = 0.0; + break; + LOCAL_COORD_MACRO_END; + + SHAPE_FUN_MACRO_BEGIN; + funValue[0] = 0.5*gc[1]*(1.0 - gc[0])*(2.0*gc[1] - 2.0 - gc[0]); + funValue[2] = 0.5*gc[2]*(1.0 - gc[0])*(2.0*gc[2] - 2.0 - gc[0]); + funValue[1] = 0.5*(gc[0] - 1.0)*(1.0 - gc[1] - gc[2])*(gc[0] + 2.0*gc[1] + 2.0*gc[2]); + + funValue[3] = 0.5*gc[1]*(1.0 + gc[0])*(2.0*gc[1] - 2.0 + gc[0]); + funValue[5] = 0.5*gc[2]*(1.0 + gc[0])*(2.0*gc[2] - 2.0 + gc[0]); + funValue[4] = 0.5*(-gc[0] - 1.0)*(1.0 - gc[1] - gc[2])*(-gc[0] + 2.0*gc[1] + 2.0*gc[2]); + + funValue[8] = 2.0*gc[1]*gc[2]*(1.0 - gc[0]); + funValue[7] = 2.0*gc[2]*(1.0 - gc[1] - gc[2])*(1.0 - gc[0]); + funValue[6] = 2.0*gc[1]*(1.0 - gc[1] - gc[2])*(1.0 - gc[0]); + + funValue[12] = gc[1]*(1.0 - gc[0]*gc[0]); + funValue[14] = gc[2]*(1.0 - gc[0]*gc[0]); + funValue[13] = (1.0 - gc[1] - gc[2])*(1.0 - gc[0]*gc[0]); + + funValue[11] = 2.0*gc[1]*gc[2]*(1.0 + gc[0]); + funValue[10] = 2.0*gc[2]*(1.0 - gc[1] - gc[2])*(1.0 + gc[0]); + funValue[9] = 2.0*gc[1]*(1.0 - gc[1] - gc[2])*(1.0 + gc[0]); + SHAPE_FUN_MACRO_END; +} + +/*! + * Init Hehahedron Reference coordinates and Shape function. + * Case A. + */ +void GaussInfo::hexa8aInit() +{ + LOCAL_COORD_MACRO_BEGIN; + case 0: + coords[0] = -1.0; + coords[1] = -1.0; + coords[2] = -1.0; + break; + case 1: + coords[0] = 1.0; + coords[1] = -1.0; + coords[2] = -1.0; + break; + case 2: + coords[0] = 1.0; + coords[1] = 1.0; + coords[2] = -1.0; + break; + case 3: + coords[0] = -1.0; + coords[1] = 1.0; + coords[2] = -1.0; + break; + case 4: + coords[0] = -1.0; + coords[1] = -1.0; + coords[2] = 1.0; + break; + case 5: + coords[0] = 1.0; + coords[1] = -1.0; + coords[2] = 1.0; + break; + case 6: + coords[0] = 1.0; + coords[1] = 1.0; + coords[2] = 1.0; + break; + case 7: + coords[0] = -1.0; + coords[1] = 1.0; + coords[2] = 1.0; + break; + LOCAL_COORD_MACRO_END; + + SHAPE_FUN_MACRO_BEGIN; + funValue[0] = 0.125*(1.0 - gc[0])*(1.0 - gc[1])*(1.0 - gc[2]); + funValue[1] = 0.125*(1.0 + gc[0])*(1.0 - gc[1])*(1.0 - gc[2]); + funValue[2] = 0.125*(1.0 + gc[0])*(1.0 + gc[1])*(1.0 - gc[2]); + funValue[3] = 0.125*(1.0 - gc[0])*(1.0 + gc[1])*(1.0 - gc[2]); + + funValue[4] = 0.125*(1.0 - gc[0])*(1.0 - gc[1])*(1.0 + gc[2]); + funValue[5] = 0.125*(1.0 + gc[0])*(1.0 - gc[1])*(1.0 + gc[2]); + funValue[6] = 0.125*(1.0 + gc[0])*(1.0 + gc[1])*(1.0 + gc[2]); + funValue[7] = 0.125*(1.0 - gc[0])*(1.0 + gc[1])*(1.0 + gc[2]); + SHAPE_FUN_MACRO_END; +} + +/*! + * Init Hehahedron Reference coordinates and Shape function. + * Case B. + */ +void GaussInfo::hexa8bInit() +{ + LOCAL_COORD_MACRO_BEGIN; + case 0: + coords[0] = -1.0; + coords[1] = -1.0; + coords[2] = -1.0; + break; + case 3: + coords[0] = 1.0; + coords[1] = -1.0; + coords[2] = -1.0; + break; + case 2: + coords[0] = 1.0; + coords[1] = 1.0; + coords[2] = -1.0; + break; + case 1: + coords[0] = -1.0; + coords[1] = 1.0; + coords[2] = -1.0; + break; + case 4: + coords[0] = -1.0; + coords[1] = -1.0; + coords[2] = 1.0; + break; + case 7: + coords[0] = 1.0; + coords[1] = -1.0; + coords[2] = 1.0; + break; + case 6: + coords[0] = 1.0; + coords[1] = 1.0; + coords[2] = 1.0; + break; + case 5: + coords[0] = -1.0; + coords[1] = 1.0; + coords[2] = 1.0; + break; + LOCAL_COORD_MACRO_END; + + SHAPE_FUN_MACRO_BEGIN; + funValue[0] = 0.125*(1.0 - gc[0])*(1.0 - gc[1])*(1.0 - gc[2]); + funValue[3] = 0.125*(1.0 + gc[0])*(1.0 - gc[1])*(1.0 - gc[2]); + funValue[2] = 0.125*(1.0 + gc[0])*(1.0 + gc[1])*(1.0 - gc[2]); + funValue[1] = 0.125*(1.0 - gc[0])*(1.0 + gc[1])*(1.0 - gc[2]); + + funValue[4] = 0.125*(1.0 - gc[0])*(1.0 - gc[1])*(1.0 + gc[2]); + funValue[7] = 0.125*(1.0 + gc[0])*(1.0 - gc[1])*(1.0 + gc[2]); + funValue[6] = 0.125*(1.0 + gc[0])*(1.0 + gc[1])*(1.0 + gc[2]); + funValue[5] = 0.125*(1.0 - gc[0])*(1.0 + gc[1])*(1.0 + gc[2]); + SHAPE_FUN_MACRO_END; +} + +/*! + * This shapefunc map is same as degenerated quad4bInit + */ +void GaussInfo::hexa8DegQuad4aInit() +{ + LOCAL_COORD_MACRO_BEGIN; + case 0: + coords[0] = -1.0; + coords[1] = 1.0; + coords[2] = 0.0; + break; + case 1: + coords[0] = -1.0; + coords[1] = -1.0; + coords[2] = 0.0; + break; + case 2: + coords[0] = 1.0; + coords[1] = -1.0; + coords[2] = 0.0; + break; + case 3: + coords[0] = 1.0; + coords[1] = 1.0; + coords[2] = 0.0; + break; + case 4: + coords[0] = 0.0; + coords[1] = 0.0; + coords[2] = 0.0; + break; + case 5: + coords[0] = 0.0; + coords[1] = 0.0; + coords[2] = 0.0; + break; + case 6: + coords[0] = 0.0; + coords[1] = 0.0; + coords[2] = 0.0; + break; + case 7: + coords[0] = 0.0; + coords[1] = 0.0; + coords[2] = 0.0; + break; + LOCAL_COORD_MACRO_END; + + SHAPE_FUN_MACRO_BEGIN; + funValue[0] = 0.25*(1.0 + gc[1])*(1.0 - gc[0]); + funValue[1] = 0.25*(1.0 - gc[1])*(1.0 - gc[0]); + funValue[2] = 0.25*(1.0 - gc[1])*(1.0 + gc[0]); + funValue[3] = 0.25*(1.0 + gc[0])*(1.0 + gc[1]); + funValue[4] = 0.; + funValue[5] = 0.; + funValue[6] = 0.; + funValue[7] = 0.; + SHAPE_FUN_MACRO_END; +} + +/*! + * This shapefunc map is same as degenerated quad4bInit + */ +void GaussInfo::hexa8DegQuad4bInit() +{ + LOCAL_COORD_MACRO_BEGIN; + case 0: + coords[0] = -1.0; + coords[1] = -1.0; + coords[2] = 0.0; + break; + case 1: + coords[0] = 1.0; + coords[1] = -1.0; + coords[2] = 0.0; + break; + case 2: + coords[0] = 1.0; + coords[1] = 1.0; + coords[2] = 0.0; + break; + case 3: + coords[0] = -1.0; + coords[1] = 1.0; + coords[2] = 0.0; + break; + case 4: + coords[0] = 0.0; + coords[1] = 0.0; + coords[2] = 0.0; + break; + case 5: + coords[0] = 0.0; + coords[1] = 0.0; + coords[2] = 0.0; + break; + case 6: + coords[0] = 0.0; + coords[1] = 0.0; + coords[2] = 0.0; + break; + case 7: + coords[0] = 0.0; + coords[1] = 0.0; + coords[2] = 0.0; + break; + LOCAL_COORD_MACRO_END; + + SHAPE_FUN_MACRO_BEGIN; + funValue[0] = 0.25*(1.0 - gc[0])*(1.0 - gc[1]); + funValue[1] = 0.25*(1.0 + gc[0])*(1.0 - gc[1]); + funValue[2] = 0.25*(1.0 + gc[0])*(1.0 + gc[1]); + funValue[3] = 0.25*(1.0 - gc[0])*(1.0 + gc[1]); + funValue[4] = 0.; + funValue[5] = 0.; + funValue[6] = 0.; + funValue[7] = 0.; + SHAPE_FUN_MACRO_END; +} + +/*! + * This shapefunc map is same as degenerated quad4cInit + */ +void GaussInfo::hexa8DegQuad4cInit() +{ + LOCAL_COORD_MACRO_BEGIN; + case 0: + coords[0] = -1.0; + coords[1] = -1.0; + coords[2] = 0.0; + break; + case 1: + coords[0] = -1.0; + coords[1] = 1.0; + coords[2] = 0.0; + break; + case 2: + coords[0] = 1.0; + coords[1] = 1.0; + coords[2] = 0.0; + break; + case 3: + coords[0] = 1.0; + coords[1] = -1.0; + coords[2] = 0.0; + break; + case 4: + coords[0] = 0.0; + coords[1] = 0.0; + coords[2] = 0.0; + break; + case 5: + coords[0] = 0.0; + coords[1] = 0.0; + coords[2] = 0.0; + break; + case 6: + coords[0] = 0.0; + coords[1] = 0.0; + coords[2] = 0.0; + break; + case 7: + coords[0] = 0.0; + coords[1] = 0.0; + coords[2] = 0.0; + break; + + LOCAL_COORD_MACRO_END; + + SHAPE_FUN_MACRO_BEGIN; + funValue[0] = 0.25*(1.0 - gc[0])*(1.0 - gc[1]); + funValue[1] = 0.25*(1.0 - gc[0])*(1.0 + gc[1]); + funValue[2] = 0.25*(1.0 + gc[0])*(1.0 + gc[1]); + funValue[3] = 0.25*(1.0 + gc[0])*(1.0 - gc[1]); + funValue[4] = 0. ; + funValue[5] = 0. ; + funValue[6] = 0. ; + funValue[7] = 0. ; + SHAPE_FUN_MACRO_END; +} + +/*! + * Init Qaudratic Hehahedron Reference coordinates and Shape function. + * Case A. + */ +void GaussInfo::hexa20aInit() +{ + LOCAL_COORD_MACRO_BEGIN; + case 0: + coords[0] = -1.0; + coords[1] = -1.0; + coords[2] = -1.0; + break; + case 1: + coords[0] = 1.0; + coords[1] = -1.0; + coords[2] = -1.0; + break; + case 2: + coords[0] = 1.0; + coords[1] = 1.0; + coords[2] = -1.0; + break; + case 3: + coords[0] = -1.0; + coords[1] = 1.0; + coords[2] = -1.0; + break; + case 4: + coords[0] = -1.0; + coords[1] = -1.0; + coords[2] = 1.0; + break; + case 5: + coords[0] = 1.0; + coords[1] = -1.0; + coords[2] = 1.0; + break; + case 6: + coords[0] = 1.0; + coords[1] = 1.0; + coords[2] = 1.0; + break; + case 7: + coords[0] = -1.0; + coords[1] = 1.0; + coords[2] = 1.0; + break; + + case 8: + coords[0] = 0.0; + coords[1] = -1.0; + coords[2] = -1.0; + break; + case 9: + coords[0] = 1.0; + coords[1] = 0.0; + coords[2] = -1.0; + break; + case 10: + coords[0] = 0.0; + coords[1] = 1.0; + coords[2] = -1.0; + break; + case 11: + coords[0] = -1.0; + coords[1] = 0.0; + coords[2] = -1.0; + break; + case 12: + coords[0] = -1.0; + coords[1] = -1.0; + coords[2] = 0.0; + break; + case 13: + coords[0] = 1.0; + coords[1] = -1.0; + coords[2] = 0.0; + break; + case 14: + coords[0] = 1.0; + coords[1] = 1.0; + coords[2] = 0.0; + break; + case 15: + coords[0] = -1.0; + coords[1] = 1.0; + coords[2] = 0.0; + break; + case 16: + coords[0] = 0.0; + coords[1] = -1.0; + coords[2] = 1.0; + break; + case 17: + coords[0] = 1.0; + coords[1] = 0.0; + coords[2] = 1.0; + break; + case 18: + coords[0] = 0.0; + coords[1] = 1.0; + coords[2] = 1.0; + break; + case 19: + coords[0] = -1.0; + coords[1] = 0.0; + coords[2] = 1.0; + break; + LOCAL_COORD_MACRO_END; + + SHAPE_FUN_MACRO_BEGIN; + funValue[0] = 0.125*(1.0 - gc[0])*(1.0 - gc[1])*(1.0 - gc[2])* + (-2.0 - gc[0] - gc[1] - gc[2]); + funValue[1] = 0.125*(1.0 + gc[0])*(1.0 - gc[1])*(1.0 - gc[2])* + (-2.0 + gc[0] - gc[1] - gc[2]); + funValue[2] = 0.125*(1.0 + gc[0])*(1.0 + gc[1])*(1.0 - gc[2])* + (-2.0 + gc[0] + gc[1] - gc[2]); + funValue[3] = 0.125*(1.0 - gc[0])*(1.0 + gc[1])*(1.0 - gc[2])* + (-2.0 - gc[0] + gc[1] - gc[2]); + funValue[4] = 0.125*(1.0 - gc[0])*(1.0 - gc[1])*(1.0 + gc[2])* + (-2.0 - gc[0] - gc[1] + gc[2]); + funValue[5] = 0.125*(1.0 + gc[0])*(1.0 - gc[1])*(1.0 + gc[2])* + (-2.0 + gc[0] - gc[1] + gc[2]); + funValue[6] = 0.125*(1.0 + gc[0])*(1.0 + gc[1])*(1.0 + gc[2])* + (-2.0 + gc[0] + gc[1] + gc[2]); + funValue[7] = 0.125*(1.0 - gc[0])*(1.0 + gc[1])*(1.0 + gc[2])* + (-2.0 - gc[0] + gc[1] + gc[2]); + + funValue[8] = 0.25*(1.0 - gc[0]*gc[0])*(1.0 - gc[1])*(1.0 - gc[2]); + funValue[9] = 0.25*(1.0 - gc[1]*gc[1])*(1.0 + gc[0])*(1.0 - gc[2]); + funValue[10] = 0.25*(1.0 - gc[0]*gc[0])*(1.0 + gc[1])*(1.0 - gc[2]); + funValue[11] = 0.25*(1.0 - gc[1]*gc[1])*(1.0 - gc[0])*(1.0 - gc[2]); + funValue[12] = 0.25*(1.0 - gc[2]*gc[2])*(1.0 - gc[0])*(1.0 - gc[1]); + funValue[13] = 0.25*(1.0 - gc[2]*gc[2])*(1.0 + gc[0])*(1.0 - gc[1]); + funValue[14] = 0.25*(1.0 - gc[2]*gc[2])*(1.0 + gc[0])*(1.0 + gc[1]); + funValue[15] = 0.25*(1.0 - gc[2]*gc[2])*(1.0 - gc[0])*(1.0 + gc[1]); + funValue[16] = 0.25*(1.0 - gc[0]*gc[0])*(1.0 - gc[1])*(1.0 + gc[2]); + funValue[17] = 0.25*(1.0 - gc[1]*gc[1])*(1.0 + gc[0])*(1.0 + gc[2]); + funValue[18] = 0.25*(1.0 - gc[0]*gc[0])*(1.0 + gc[1])*(1.0 + gc[2]); + funValue[19] = 0.25*(1.0 - gc[1]*gc[1])*(1.0 - gc[0])*(1.0 + gc[2]); + SHAPE_FUN_MACRO_END; +} + +/*! + * Init Qaudratic Hehahedron Reference coordinates and Shape function. + * Case B. + */ +void GaussInfo::hexa20bInit() +{ + LOCAL_COORD_MACRO_BEGIN; + case 0: + coords[0] = -1.0; + coords[1] = -1.0; + coords[2] = -1.0; + break; + case 3: + coords[0] = 1.0; + coords[1] = -1.0; + coords[2] = -1.0; + break; + case 2: + coords[0] = 1.0; + coords[1] = 1.0; + coords[2] = -1.0; + break; + case 1: + coords[0] = -1.0; + coords[1] = 1.0; + coords[2] = -1.0; + break; + case 4: + coords[0] = -1.0; + coords[1] = -1.0; + coords[2] = 1.0; + break; + case 7: + coords[0] = 1.0; + coords[1] = -1.0; + coords[2] = 1.0; + break; + case 6: + coords[0] = 1.0; + coords[1] = 1.0; + coords[2] = 1.0; + break; + case 5: + coords[0] = -1.0; + coords[1] = 1.0; + coords[2] = 1.0; + break; + + case 11: + coords[0] = 0.0; + coords[1] = -1.0; + coords[2] = -1.0; + break; + case 10: + coords[0] = 1.0; + coords[1] = 0.0; + coords[2] = -1.0; + break; + case 9: + coords[0] = 0.0; + coords[1] = 1.0; + coords[2] = -1.0; + break; + case 8: + coords[0] = -1.0; + coords[1] = 0.0; + coords[2] = -1.0; + break; + case 16: + coords[0] = -1.0; + coords[1] = -1.0; + coords[2] = 0.0; + break; + case 19: + coords[0] = 1.0; + coords[1] = -1.0; + coords[2] = 0.0; + break; + case 18: + coords[0] = 1.0; + coords[1] = 1.0; + coords[2] = 0.0; + break; + case 17: + coords[0] = -1.0; + coords[1] = 1.0; + coords[2] = 0.0; + break; + case 15: + coords[0] = 0.0; + coords[1] = -1.0; + coords[2] = 1.0; + break; + case 14: + coords[0] = 1.0; + coords[1] = 0.0; + coords[2] = 1.0; + break; + case 13: + coords[0] = 0.0; + coords[1] = 1.0; + coords[2] = 1.0; + break; + case 12: + coords[0] = -1.0; + coords[1] = 0.0; + coords[2] = 1.0; + break; + LOCAL_COORD_MACRO_END; + + SHAPE_FUN_MACRO_BEGIN; + + funValue[0] = 0.125*(1.0 - gc[0])*(1.0 - gc[1])*(1.0 - gc[2])* + (-2.0 - gc[0] - gc[1] - gc[2]); + funValue[3] = 0.125*(1.0 + gc[0])*(1.0 - gc[1])*(1.0 - gc[2])* + (-2.0 + gc[0] - gc[1] - gc[2]); + funValue[2] = 0.125*(1.0 + gc[0])*(1.0 + gc[1])*(1.0 - gc[2])* + (-2.0 + gc[0] + gc[1] - gc[2]); + funValue[1] = 0.125*(1.0 - gc[0])*(1.0 + gc[1])*(1.0 - gc[2])* + (-2.0 - gc[0] + gc[1] - gc[2]); + funValue[4] = 0.125*(1.0 - gc[0])*(1.0 - gc[1])*(1.0 + gc[2])* + (-2.0 - gc[0] - gc[1] + gc[2]); + funValue[7] = 0.125*(1.0 + gc[0])*(1.0 - gc[1])*(1.0 + gc[2])* + (-2.0 + gc[0] - gc[1] + gc[2]); + funValue[6] = 0.125*(1.0 + gc[0])*(1.0 + gc[1])*(1.0 + gc[2])* + (-2.0 + gc[0] + gc[1] + gc[2]); + funValue[5] = 0.125*(1.0 - gc[0])*(1.0 + gc[1])*(1.0 + gc[2])* + (-2.0 - gc[0] + gc[1] + gc[2]); + + funValue[11] = 0.25*(1.0 - gc[0]*gc[0])*(1.0 - gc[1])*(1.0 - gc[2]); + funValue[10] = 0.25*(1.0 - gc[1]*gc[1])*(1.0 + gc[0])*(1.0 - gc[2]); + funValue[9] = 0.25*(1.0 - gc[0]*gc[0])*(1.0 + gc[1])*(1.0 - gc[2]); + funValue[8] = 0.25*(1.0 - gc[1]*gc[1])*(1.0 - gc[0])*(1.0 - gc[2]); + funValue[16] = 0.25*(1.0 - gc[2]*gc[2])*(1.0 - gc[0])*(1.0 - gc[1]); + funValue[19] = 0.25*(1.0 - gc[2]*gc[2])*(1.0 + gc[0])*(1.0 - gc[1]); + funValue[18] = 0.25*(1.0 - gc[2]*gc[2])*(1.0 + gc[0])*(1.0 + gc[1]); + funValue[17] = 0.25*(1.0 - gc[2]*gc[2])*(1.0 - gc[0])*(1.0 + gc[1]); + funValue[15] = 0.25*(1.0 - gc[0]*gc[0])*(1.0 - gc[1])*(1.0 + gc[2]); + funValue[14] = 0.25*(1.0 - gc[1]*gc[1])*(1.0 + gc[0])*(1.0 + gc[2]); + funValue[13] = 0.25*(1.0 - gc[0]*gc[0])*(1.0 + gc[1])*(1.0 + gc[2]); + funValue[12] = 0.25*(1.0 - gc[1]*gc[1])*(1.0 - gc[0])*(1.0 + gc[2]); + SHAPE_FUN_MACRO_END; +} + +void GaussInfo::hexa27aInit() +{ + LOCAL_COORD_MACRO_BEGIN; + case 0: + coords[0] = -1.0; + coords[1] = -1.0; + coords[2] = -1.0; + break; + case 1: + coords[0] = -1.0; + coords[1] = 1.0; + coords[2] = -1.0; + break; + case 2: + coords[0] = 1.0; + coords[1] = 1.0; + coords[2] = -1.0; + break; + case 3: + coords[0] = 1.0; + coords[1] = -1.0; + coords[2] = -1.0; + break; + case 4: + coords[0] = -1.0; + coords[1] = -1.0; + coords[2] = 1.0; + break; + case 5: + coords[0] = -1.0; + coords[1] = 1.0; + coords[2] = 1.0; + break; + case 6: + coords[0] = 1.0; + coords[1] = 1.0; + coords[2] = 1.0; + break; + case 7: + coords[0] = 1.0; + coords[1] = -1.0; + coords[2] = 1.0; + break; + case 8: + coords[0] = -1.0; + coords[1] = 0.0; + coords[2] = -1.0; + break; + case 9: + coords[0] = 0.0; + coords[1] = 1.0; + coords[2] = -1.0; + break; + case 10: + coords[0] = 1.0; + coords[1] = 0.0; + coords[2] = -1.0; + break; + case 11: + coords[0] = 0.0; + coords[1] = -1.0; + coords[2] = -1.0; + break; + case 12: + coords[0] = -1.0; + coords[1] = 0.0; + coords[2] = 1.0; + break; + case 13: + coords[0] = 0.0; + coords[1] = 1.0; + coords[2] = 1.0; + break; + case 14: + coords[0] = 1.0; + coords[1] = 0.0; + coords[2] = 1.0; + break; + case 15: + coords[0] = 0.0; + coords[1] = -1.0; + coords[2] = 1.0; + break; + case 16: + coords[0] = -1.0; + coords[1] = -1.0; + coords[2] = 0.0; + break; + case 17: + coords[0] = -1.0; + coords[1] = 1.0; + coords[2] = 0.0; + break; + case 18: + coords[0] = 1.0; + coords[1] = 1.0; + coords[2] = 0.0; + break; + case 19: + coords[0] = 1.0; + coords[1] = -1.0; + coords[2] = 0.0; + break; + case 20: + coords[0] = 0.0; + coords[1] = 0.0; + coords[2] = -1.0; + break; + case 21: + coords[0] = -1.0; + coords[1] = 0.0; + coords[2] = 0.0; + break; + case 22: + coords[0] = 0.0; + coords[1] = 1.0; + coords[2] = 0.0; + break; + case 23: + coords[0] = 1.0; + coords[1] = 0.0; + coords[2] = 0.0; + break; + case 24: + coords[0] = 0.0; + coords[1] = -1.0; + coords[2] = 0.0; + break; + case 25: + coords[0] = 0.0; + coords[1] = 0.0; + coords[2] = 1.0; + break; + case 26: + coords[0] = 0.0; + coords[1] = 0.0; + coords[2] = 0.0; + break; + LOCAL_COORD_MACRO_END; + + SHAPE_FUN_MACRO_BEGIN; + + funValue[0] =0.125*gc[0]*(gc[0]-1.)*gc[1]*(gc[1]-1.)*gc[2]*(gc[2]-1.); + funValue[1] =0.125*gc[0]*(gc[0]-1.)*gc[1]*(gc[1]+1.)*gc[2]*(gc[2]-1.); + funValue[2] =0.125*gc[0]*(gc[0]+1.)*gc[1]*(gc[1]+1.)*gc[2]*(gc[2]-1.); + funValue[3] =0.125*gc[0]*(gc[0]+1.)*gc[1]*(gc[1]-1.)*gc[2]*(gc[2]-1.); + funValue[4] =0.125*gc[0]*(gc[0]-1.)*gc[1]*(gc[1]-1.)*gc[2]*(gc[2]+1.); + funValue[5] =0.125*gc[0]*(gc[0]-1.)*gc[1]*(gc[1]+1.)*gc[2]*(gc[2]+1.); + funValue[6] =0.125*gc[0]*(gc[0]+1.)*gc[1]*(gc[1]+1.)*gc[2]*(gc[2]+1.); + funValue[7] =0.125*gc[0]*(gc[0]+1.)*gc[1]*(gc[1]-1.)*gc[2]*(gc[2]+1.); + funValue[8] =0.25*gc[0]*(gc[0]-1.)*(1.-gc[1]*gc[1])*gc[2]*(gc[2]-1.); + funValue[9] =0.25*(1.-gc[0]*gc[0])*gc[1]*(gc[1]+1.)*gc[2]*(gc[2]-1.); + funValue[10]=0.25*gc[0]*(gc[0]+1.)*(1.-gc[1]*gc[1])*gc[2]*(gc[2]-1.); + funValue[11]=0.25*(1.-gc[0]*gc[0])*gc[1]*(gc[1]-1.)*gc[2]*(gc[2]-1.); + funValue[12]=0.25*gc[0]*(gc[0]-1.)*(1.-gc[1]*gc[1])*gc[2]*(gc[2]+1.); + funValue[13]=0.25*(1.-gc[0]*gc[0])*gc[1]*(gc[1]+1.)*gc[2]*(gc[2]+1.); + funValue[14]=0.25*gc[0]*(gc[0]+1.)*(1.-gc[1]*gc[1])*gc[2]*(gc[2]+1.); + funValue[15]=0.25*(1.-gc[0]*gc[0])*gc[1]*(gc[1]-1.)*gc[2]*(gc[2]+1.); + funValue[16]=0.25*gc[0]*(gc[0]-1.)*gc[1]*(gc[1]-1.)*(1.-gc[2]*gc[2]); + funValue[17]=0.25*gc[0]*(gc[0]-1.)*gc[1]*(gc[1]+1.)*(1.-gc[2]*gc[2]); + funValue[18]=0.25*gc[0]*(gc[0]+1.)*gc[1]*(gc[1]+1.)*(1.-gc[2]*gc[2]); + funValue[19]=0.25*gc[0]*(gc[0]+1.)*gc[1]*(gc[1]-1.)*(1.-gc[2]*gc[2]); + funValue[20]=0.5*(1.-gc[0]*gc[0])*(1.-gc[1]*gc[1])*gc[2]*(gc[2]-1.); + funValue[21]=0.5*gc[0]*(gc[0]-1.)*(1.-gc[1]*gc[1])*(1.-gc[2]*gc[2]); + funValue[22]=0.5*(1.-gc[0]*gc[0])*gc[1]*(gc[1]+1.)*(1.-gc[2]*gc[2]); + funValue[23]=0.5*gc[0]*(gc[0]+1.)*(1.-gc[1]*gc[1])*(1.-gc[2]*gc[2]); + funValue[24]=0.5*(1.-gc[0]*gc[0])*gc[1]*(gc[1]-1.)*(1.-gc[2]*gc[2]); + funValue[25]=0.5*(1.-gc[0]*gc[0])*(1.-gc[1]*gc[1])*gc[2]*(gc[2]+1.); + funValue[26]=(1.-gc[0]*gc[0])*(1.-gc[1]*gc[1])*(1.-gc[2]*gc[2]); + + SHAPE_FUN_MACRO_END; +} + +//////////////////////////////////////////////////////////////////////////////////////////////// +// GAUSS COORD CLASS // +//////////////////////////////////////////////////////////////////////////////////////////////// +/*! + * Constructor + */ +GaussCoords::GaussCoords() +{ +} + +/*! + * Destructor + */ +GaussCoords::~GaussCoords() +{ + GaussInfoVector::iterator it = _my_gauss_info.begin(); + for( ; it != _my_gauss_info.end(); it++ ) + { + if((*it) != NULL) + delete (*it); + } +} + +/*! + * Add Gauss localization info + */ +void GaussCoords::addGaussInfo( NormalizedCellType theGeometry, + int coordDim, + const double* theGaussCoord, + int theNbGauss, + const double* theReferenceCoord, + int theNbRef) +{ + GaussInfoVector::iterator it = _my_gauss_info.begin(); + for( ; it != _my_gauss_info.end(); it++ ) + { + if( (*it)->getCellType() == theGeometry ) + { + break; + } + } + + DataVector aGaussCoord; + for(int i = 0 ; i < theNbGauss*coordDim; i++ ) + aGaussCoord.push_back(theGaussCoord[i]); + + DataVector aReferenceCoord; + for(int i = 0 ; i < theNbRef*coordDim; i++ ) + aReferenceCoord.push_back(theReferenceCoord[i]); + + + GaussInfo* info = new GaussInfo( theGeometry, aGaussCoord, theNbGauss, aReferenceCoord, theNbRef); + info->initLocalInfo(); + + //If info with cell type doesn't exist add it + if( it == _my_gauss_info.end() ) + { + _my_gauss_info.push_back(info); + + // If information exists, update it + } + else + { + int index = std::distance(_my_gauss_info.begin(),it); + delete (*it); + _my_gauss_info[index] = info; + } +} + + +/*! + * Calculate gauss points coordinates + */ +double* GaussCoords::calculateCoords( NormalizedCellType theGeometry, + const double *theNodeCoords, + const int theSpaceDim, + const int *theIndex) +{ + const GaussInfo *info = getInfoGivenCellType(theGeometry); + int nbCoords = theSpaceDim * info->getNbGauss(); + double *aCoords = new double[nbCoords]; + calculateCoordsAlg(info,theNodeCoords,theSpaceDim,theIndex,aCoords); + return aCoords; +} + + +void GaussCoords::calculateCoords( NormalizedCellType theGeometry, const double *theNodeCoords, const int theSpaceDim, const int *theIndex, double *result) +{ + const GaussInfo *info = getInfoGivenCellType(theGeometry); + calculateCoordsAlg(info,theNodeCoords,theSpaceDim,theIndex,result); +} + +void GaussCoords::calculateCoordsAlg(const GaussInfo *info, const double* theNodeCoords, const int theSpaceDim, const int *theIndex, double *result) +{ + int aConn = info->getNbRef(); + + int nbCoords = theSpaceDim * info->getNbGauss(); + std::fill(result,result+nbCoords,0.); + + for( int gaussId = 0; gaussId < info->getNbGauss(); gaussId++ ) + { + double *coord=result+gaussId*theSpaceDim; + const double *function=info->getFunctionValues(gaussId); + for ( int connId = 0; connId < aConn ; connId++ ) + { + const double* nodeCoord = theNodeCoords + (theIndex[connId]*theSpaceDim); + for( int dimId = 0; dimId < theSpaceDim; dimId++ ) + coord[dimId] += nodeCoord[dimId]*function[connId]; + } + } +} + +const GaussInfo *GaussCoords::getInfoGivenCellType(NormalizedCellType cellType) +{ + GaussInfoVector::const_iterator it = _my_gauss_info.begin(); + //Try to find gauss localization info + for( ; it != _my_gauss_info.end() ; it++ ) + if( (*it)->getCellType()==cellType) + return (*it); + throw INTERP_KERNEL::Exception("Can't find gauss localization information !"); +} diff --git a/src/medtool/src/INTERP_KERNEL/GaussPoints/InterpKernelGaussCoords.hxx b/src/medtool/src/INTERP_KERNEL/GaussPoints/InterpKernelGaussCoords.hxx new file mode 100644 index 000000000..12c706e82 --- /dev/null +++ b/src/medtool/src/INTERP_KERNEL/GaussPoints/InterpKernelGaussCoords.hxx @@ -0,0 +1,189 @@ +// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 +// 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 __INTERPKERNELGAUSSCOORDS_HXX__ +#define __INTERPKERNELGAUSSCOORDS_HXX__ + +#include "INTERPKERNELDefines.hxx" +#include "NormalizedUnstructuredMesh.hxx" +#include "InterpKernelException.hxx" + +#include <vector> + +namespace INTERP_KERNEL +{ + typedef std::vector<double> DataVector; + typedef std::vector<int> IndexVector; + + //Class to store Gauss Points information + class GaussInfo + { + public: + INTERPKERNEL_EXPORT GaussInfo( NormalizedCellType theGeometry, + const DataVector& theGaussCoord, + int theNbGauss, + const DataVector& theReferenceCoord, + int theNbRef + ); + INTERPKERNEL_EXPORT ~GaussInfo(); + + INTERPKERNEL_EXPORT NormalizedCellType getCellType() const; + + INTERPKERNEL_EXPORT int getGaussCoordDim() const; + INTERPKERNEL_EXPORT int getReferenceCoordDim() const; + + INTERPKERNEL_EXPORT int getNbGauss() const; + INTERPKERNEL_EXPORT int getNbRef() const; + + INTERPKERNEL_EXPORT const double* getFunctionValues( const int theGaussId ) const; + + INTERPKERNEL_EXPORT void initLocalInfo(); + + INTERPKERNEL_EXPORT static std::vector<double> NormalizeCoordinatesIfNecessary(NormalizedCellType ct, int inputDim, const std::vector<double>& inputArray); + + protected: + + bool isSatisfy(); + + void point1Init(); + + //1D + void seg2Init(); + void seg3Init(); + + //2D + void tria3aInit(); + void tria3bInit(); + void tria6aInit(); + void tria6bInit(); + void tria7aInit(); + + void quad4aInit(); + static void Quad4aInit(GaussInfo& obj) { obj.quad4aInit(); } + void quad4bInit(); + static void Quad4bInit(GaussInfo& obj) { obj.quad4bInit(); } + void quad4cInit(); + static void Quad4cInit(GaussInfo& obj) { obj.quad4cInit(); } + void quad4DegSeg2Init(); + static void Quad4DegSeg2Init(GaussInfo& obj) { obj.quad4DegSeg2Init(); } + void quad8aInit(); + void quad8bInit(); + void quad9aInit(); + + //3D + void tetra4aInit(); + void tetra4bInit(); + void tetra10aInit(); + void tetra10bInit(); + + void pyra5aInit(); + void pyra5bInit(); + void pyra13aInit(); + void pyra13bInit(); + + void penta6aInit(); + static void Penta6aInit(GaussInfo& obj) { obj.penta6aInit(); } + void penta6bInit(); + static void Penta6bInit(GaussInfo& obj) { obj.penta6bInit(); } + void penta6DegTria3aInit(); + static void Penta6DegTria3aInit(GaussInfo& obj) { obj.penta6DegTria3aInit(); } + void penta6DegTria3bInit(); + static void Penta6DegTria3bInit(GaussInfo& obj) { obj.penta6DegTria3bInit(); } + + void penta15aInit(); + static void Penta15aInit(GaussInfo& obj) { obj.penta15aInit(); } + void penta15bInit(); + static void Penta15bInit(GaussInfo& obj) { obj.penta15bInit(); } + + void hexa8aInit(); + static void Hexa8aInit(GaussInfo& obj) { obj.hexa8aInit(); } + void hexa8bInit(); + static void Hexa8bInit(GaussInfo& obj) { obj.hexa8bInit(); } + void hexa8DegQuad4aInit(); + static void Hexa8DegQuad4aInit(GaussInfo& obj) { obj.hexa8DegQuad4aInit(); } + void hexa8DegQuad4bInit(); + static void Hexa8DegQuad4bInit(GaussInfo& obj) { obj.hexa8DegQuad4bInit(); } + void hexa8DegQuad4cInit(); + static void Hexa8DegQuad4cInit(GaussInfo& obj) { obj.hexa8DegQuad4cInit(); } + void hexa20aInit(); + void hexa20bInit(); + void hexa27aInit(); + + private: + //INFORMATION from MEDMEM + NormalizedCellType _my_geometry; //Cell type + + int _my_nb_gauss; //Nb of the gauss points for element + DataVector _my_gauss_coord; //Gauss coordinates + + int _my_nb_ref; //Nb of the nodes for element: + //NORM_SEG2 - 2 + //NORM_SEG3 - 3 + //NORM_TRI3 - 3 + //............. + + DataVector _my_reference_coord; //Reference coordinates + + //LOCAL INFORMATION + DataVector _my_local_reference_coord; //Vector to store reference coordinates + int _my_local_ref_dim; //Dimension of the local reference coordinates: + // (x) - 1D case + // (x, y) - 2D case + // (x, y, z) - 3D case + int _my_local_nb_ref; //Nb of the local reference coordinates + + DataVector _my_function_value; //Shape Function values + }; + + + //Class for calculation of the coordinates of the gauss points + class GaussCoords + { + public: + + INTERPKERNEL_EXPORT GaussCoords(); + INTERPKERNEL_EXPORT ~GaussCoords(); + + INTERPKERNEL_EXPORT void addGaussInfo( NormalizedCellType theGeometry, + int coordDim, + const double* theGaussCoord, + int theNbGauss, + const double* theReferenceCoord, + int theNbRef); + + INTERPKERNEL_EXPORT double* calculateCoords( NormalizedCellType theGeometry, + const double* theNodeCoords, + const int theSpaceDim, + const int* theIndex); + + INTERPKERNEL_EXPORT void calculateCoords( NormalizedCellType theGeometry, + const double* theNodeCoords, + const int theSpaceDim, + const int* theIndex, + double *result); + private: + const GaussInfo *getInfoGivenCellType(NormalizedCellType cellType); + void calculateCoordsAlg(const GaussInfo *info, const double* theNodeCoords, const int theSpaceDim, const int *theIndex, + double *result); + private: + typedef std::vector<GaussInfo*> GaussInfoVector; + GaussInfoVector _my_gauss_info; + }; +} +#endif //INTERPKERNELGAUSSCOORDS diff --git a/src/medtool/src/INTERP_KERNEL/GenMathFormulae.hxx b/src/medtool/src/INTERP_KERNEL/GenMathFormulae.hxx new file mode 100644 index 000000000..a53aacfca --- /dev/null +++ b/src/medtool/src/INTERP_KERNEL/GenMathFormulae.hxx @@ -0,0 +1,96 @@ +// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 +// 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 __GENMATHFORMULAE_HXX__ +#define __GENMATHFORMULAE_HXX__ + +#include "InterpKernelException.hxx" + +#include <cmath> + +namespace INTERP_KERNEL +{ + /*! + * This method computes eigenvalues of a 3x3 symetric matrix stored with 6 values in 'matrix'. The convension chosen for 'matrix' is described here: + * matrix[0]=m_xx, matrix[1]=m_yy, matrix[2]=m_zz, + * matrix[3]=m_xy, matrix[4]=m_yz, matrix[5]=m_xz + * This method returns the 3 eigenvalues in 'eigenVals'. + */ + void computeEigenValues6(const double *matrix, double *eigenVals) + { + double tr=(matrix[0]+matrix[1]+matrix[2])/3.; + double K[6]={matrix[0]-tr,matrix[1]-tr,matrix[2]-tr,matrix[3],matrix[4],matrix[5]}; + double q=(K[0]*K[1]*K[2]+2.*K[4]*K[5]*K[3]-K[0]*K[4]*K[4]-K[2]*K[3]*K[3]-K[1]*K[5]*K[5])/2.; + double p=K[0]*K[0]+K[1]*K[1]+K[2]*K[2]+2*(K[3]*K[3]+K[4]*K[4]+K[5]*K[5]); + p/=6.; + double sqp=sqrt(p); + double tmp=p*sqp; + double phi; + if(fabs(q)<=fabs(tmp)) + phi=1./3.*acos(q/tmp); + else + phi=0.; + if(phi<0.) + phi+=M_PI/3.; + eigenVals[0]=tr+2.*sqp*cos(phi); + eigenVals[1]=tr-sqp*(cos(phi)+sqrt(3.)*sin(phi)); + eigenVals[2]=tr-sqp*(cos(phi)-sqrt(3.)*sin(phi)); + } + + /*! + * This method computes one eigenvector of a 3x3 symetric matrix stored with 6 values in 'matrix'. The convension chosen for 'matrix' is described here: + * matrix[0]=m_xx, matrix[1]=m_yy, matrix[2]=m_zz, + * matrix[3]=m_xy, matrix[4]=m_yz, matrix[5]=m_xz + * This method returns the eigenvector of the corresponding eigenvalue in 'eigenVal'. The returned eigenValue is normalized. + */ + void computeEigenVectorForEigenValue6(const double *matrix, double eigenVal, double eps, double *eigenVector) + { + //if(fabs(eigenVal)>eps) + { + const double m9[9]={matrix[0]-eigenVal,matrix[3],matrix[5],matrix[3],matrix[1]-eigenVal,matrix[4],matrix[5],matrix[4],matrix[2]-eigenVal}; + for(int i=0;i<3;i++) + { + double w[9]={m9[0+3*i],m9[1+3*i],m9[2+3*i],m9[0+(3*(i+1))%6],m9[1+(3*(i+1))%6],m9[2+(3*(i+1))%6],1.,1.,1.}; + double det=w[0]*w[4]*w[8]+w[1]*w[5]*w[6]+w[2]*w[3]*w[7]-w[0]*w[5]*w[7]-w[1]*w[3]*w[8]-w[2]*w[4]*w[6]; + if(fabs(det)>eps) + { + eigenVector[0]=(w[1]*w[5]-w[4]*w[2])/det; + eigenVector[1]=(w[2]*w[3]-w[0]*w[5])/det; + eigenVector[2]=(w[0]*w[4]-w[1]*w[3])/det; + double norm=sqrt(eigenVector[0]*eigenVector[0]+eigenVector[1]*eigenVector[1]+eigenVector[2]*eigenVector[2]); + eigenVector[0]/=norm; + eigenVector[1]/=norm; + eigenVector[2]/=norm; + return; + } + } + } + //else + { + eigenVector[0]=0.; + eigenVector[1]=0.; + eigenVector[2]=0.; + return; + } + //throw INTERP_KERNEL::Exception("computeEigenVector : Do not succed in finding eigen vector !"); + } +} + +#endif diff --git a/src/medtool/src/INTERP_KERNEL/Geometric2D/InterpKernelGeo2DAbstractEdge.cxx b/src/medtool/src/INTERP_KERNEL/Geometric2D/InterpKernelGeo2DAbstractEdge.cxx new file mode 100644 index 000000000..af84365f3 --- /dev/null +++ b/src/medtool/src/INTERP_KERNEL/Geometric2D/InterpKernelGeo2DAbstractEdge.cxx @@ -0,0 +1,118 @@ +// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 +// 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 "InterpKernelGeo2DAbstractEdge.hxx" +#include "InterpKernelGeo2DComposedEdge.hxx" +#include "InterpKernelGeo2DElementaryEdge.hxx" + +using namespace INTERP_KERNEL; + +IteratorOnComposedEdge::IteratorOnComposedEdge():_list_handle(0) +{ +} + +IteratorOnComposedEdge::IteratorOnComposedEdge(ComposedEdge *compEdges):_list_handle(compEdges->getListBehind()) +{ + first(); +} + +void IteratorOnComposedEdge::operator=(const IteratorOnComposedEdge& other) +{ + _deep_it=other._deep_it; + _list_handle=other._list_handle; +} + +void IteratorOnComposedEdge::last() +{ + _deep_it=_list_handle->end(); + _deep_it--; +} + +void IteratorOnComposedEdge::nextLoop() +{ + _deep_it++; + if(_deep_it==_list_handle->end()) + first(); +} + +void IteratorOnComposedEdge::previousLoop() +{ + if(_deep_it!=_list_handle->begin()) + _deep_it--; + else + last(); +} + +bool IteratorOnComposedEdge::goToNextInOn(bool direction, int& i, int nbMax) +{ + TypeOfEdgeLocInPolygon loc=current()->getLoc(); + if(direction) + { + while(loc==FULL_OUT_1 && i<nbMax) + { + nextLoop(); i++; + loc=current()->getLoc(); + } + if(i==nbMax) + return false; + return true; + } + else + { + while(loc==FULL_OUT_1 && i<nbMax) + { + previousLoop(); i++; + loc=current()->getLoc(); + } + if(i==nbMax) + return false; + while(loc!=FULL_OUT_1 && i<nbMax) + { + previousLoop(); i++; + loc=current()->getLoc(); + } + nextLoop(); i--; + return true; + } +} + +void IteratorOnComposedEdge::assignMySelfToAllElems(ComposedEdge *elems) +{ + std::list<ElementaryEdge *> *myList=elems->getListBehind(); + for(std::list<ElementaryEdge *>::iterator iter=myList->begin();iter!=myList->end();iter++) + (*iter)->getIterator()=(*this); +} + +void IteratorOnComposedEdge::insertElemEdges(ComposedEdge *elems, bool changeMySelf) +{ + std::list<ElementaryEdge *> *myListToInsert=elems->getListBehind(); + std::list<ElementaryEdge *>::iterator iter=myListToInsert->begin(); + *_deep_it=*iter; + _deep_it++; + iter++; + int sizeOfMyList=myListToInsert->size(); + _list_handle->insert(_deep_it,iter,myListToInsert->end()); + if(!changeMySelf) + { + for(int i=0;i<sizeOfMyList;i++) + _deep_it--; + } +} + diff --git a/src/medtool/src/INTERP_KERNEL/Geometric2D/InterpKernelGeo2DAbstractEdge.hxx b/src/medtool/src/INTERP_KERNEL/Geometric2D/InterpKernelGeo2DAbstractEdge.hxx new file mode 100644 index 000000000..897687a18 --- /dev/null +++ b/src/medtool/src/INTERP_KERNEL/Geometric2D/InterpKernelGeo2DAbstractEdge.hxx @@ -0,0 +1,68 @@ +// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 +// 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 __INTERPKERNELGEO2DABSTRACTEDGE_HXX__ +#define __INTERPKERNELGEO2DABSTRACTEDGE_HXX__ + +#include "INTERPKERNELDefines.hxx" + +#include <set> +#include <list> +#include <fstream> + +namespace INTERP_KERNEL +{ + class Edge; + class Node; + class Bounds; + + class ComposedEdge; + class ElementaryEdge; + + /*! + * Asumption is done with this iterator that we iterate on a container containing more than one edge. + */ + class IteratorOnComposedEdge + { + friend class ComposedEdge; + friend class ElementaryEdge; + friend class QuadraticPolygon; + public: + INTERPKERNEL_EXPORT IteratorOnComposedEdge(); + INTERPKERNEL_EXPORT IteratorOnComposedEdge(ComposedEdge *compEdges); + INTERPKERNEL_EXPORT bool isValid() const { return _list_handle!=0; } + INTERPKERNEL_EXPORT void operator=(const IteratorOnComposedEdge& other); + INTERPKERNEL_EXPORT void first() { _deep_it=_list_handle->begin(); } + INTERPKERNEL_EXPORT void next() { _deep_it++; } + INTERPKERNEL_EXPORT void last(); + INTERPKERNEL_EXPORT void nextLoop(); + INTERPKERNEL_EXPORT void previousLoop(); + INTERPKERNEL_EXPORT bool finished() const { return _deep_it==_list_handle->end(); } + INTERPKERNEL_EXPORT bool goToNextInOn(bool direction, int& i, int nbMax); + INTERPKERNEL_EXPORT ElementaryEdge *current() { return *_deep_it; } + INTERPKERNEL_EXPORT void assignMySelfToAllElems(ComposedEdge *elems); + INTERPKERNEL_EXPORT void insertElemEdges(ComposedEdge *elems, bool changeMySelf); + private: + std::list<ElementaryEdge *>::iterator _deep_it; + std::list<ElementaryEdge *>* _list_handle; + }; +} + +#endif diff --git a/src/medtool/src/INTERP_KERNEL/Geometric2D/InterpKernelGeo2DBounds.cxx b/src/medtool/src/INTERP_KERNEL/Geometric2D/InterpKernelGeo2DBounds.cxx new file mode 100644 index 000000000..72e4dec32 --- /dev/null +++ b/src/medtool/src/INTERP_KERNEL/Geometric2D/InterpKernelGeo2DBounds.cxx @@ -0,0 +1,212 @@ +// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 +// 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 "InterpKernelGeo2DBounds.hxx" +#include "InterpKernelException.hxx" +#include "InterpKernelGeo2DEdgeArcCircle.hxx" +#include "InterpKernelGeo2DNode.hxx" + +using namespace INTERP_KERNEL; + +const double& Bounds::operator[](int i) const +{ + switch(i) + { + case 0: + return _x_min; + case 1: + return _x_max; + case 2: + return _y_min; + case 3: + return _y_max; + } + throw Exception("internal error occurs !"); +} + +double &Bounds::operator[](int i) +{ + switch(i) + { + case 0: + return _x_min; + case 1: + return _x_max; + case 2: + return _y_min; + case 3: + return _y_max; + } + throw Exception("internal error occurs !"); +} + +double Bounds::getDiagonal() const +{ + double a=_x_max-_x_min; + double b=_y_max-_y_min; + return sqrt(a*a+b*b); +} + +/*! + * See Node::applySimilarity to see signification of params. + */ +void Bounds::applySimilarity(double xBary, double yBary, double dimChar) +{ + _x_min=(_x_min-xBary)/dimChar; + _x_max=(_x_max-xBary)/dimChar; + _y_min=(_y_min-yBary)/dimChar; + _y_max=(_y_max-yBary)/dimChar; +} + +/*! + * See Node::unApplySimilarity to see signification of params. + */ +void Bounds::unApplySimilarity(double xBary, double yBary, double dimChar) +{ + _x_min=_x_min*dimChar+xBary; + _x_max=_x_max*dimChar+xBary; + _y_min=_y_min*dimChar+yBary; + _y_max=_y_max*dimChar+yBary; +} + +void Bounds::getBarycenter(double& xBary, double& yBary) const +{ + xBary=(_x_min+_x_max)/2.; + yBary=(_y_max+_y_min)/2.; +} + +void Bounds::prepareForAggregation() +{ + _x_min=1e200; _x_max=-1e200; _y_min=1e200; _y_max=-1e200; +} + +/*! + * Given an arc defined by 'center', 'radius' and 'intrcptArcDelta' in radian, returns (by outputs intrcptArcAngle0 and intrcptArcDelta) + * the intercepted angle of 'this' from 'center' point of view. + * If diagonal of 'this' is the same order of 2*radius, intrcptArcAngle0 and intrcptArcDelta remains unchanged. + * @param center IN parameter. + * @param radius IN parameter. + * @param [out] intrcptArcAngle0 OUT parameter. + * @param [out] intrcptArcDelta OUT parameter. + */ +void Bounds::getInterceptedArc(const double *center, double radius, double& intrcptArcAngle0, double& intrcptArcDelta) const +{ + double diag=getDiagonal(); + if(diag<2.*radius) + { + double v1[2],v2[2],w1[2],w2[2]; + v1[0]=_x_min-center[0]; v1[1]=_y_max-center[1]; v2[0]=_x_max-center[0]; v2[1]=_y_min-center[1]; + w1[0]=v1[0]; w1[1]=_y_min-center[1]; w2[0]=v2[0]; w2[1]=_y_max-center[1]; + double delta1=EdgeArcCircle::SafeAsin(v1[0]*v2[1]-v1[1]*v2[0]); + double delta2=EdgeArcCircle::SafeAsin(w1[0]*w2[1]-w1[1]*w2[0]); + double tmp; + if(fabs(delta1)>fabs(delta2)) + { + intrcptArcDelta=delta1; + intrcptArcAngle0=EdgeArcCircle::GetAbsoluteAngle(v1,tmp); + } + else + { + intrcptArcDelta=delta2; + intrcptArcAngle0=EdgeArcCircle::GetAbsoluteAngle(w1,tmp); + } + } +} + +double Bounds::fitXForXFigD(double val, int res) const +{ + double delta=std::max(_x_max-_x_min,_y_max-_y_min)/2.; + double ret=val-(_x_max+_x_min)/2.+delta; + delta=11.1375*res/(2.*delta); + return ret*delta; +} + +double Bounds::fitYForXFigD(double val, int res) const +{ + double delta=std::max(_x_max-_x_min,_y_max-_y_min)/2.; + double ret=(_y_max+_y_min)/2.-val+delta; + delta=11.1375*res/(2.*delta); + return ret*delta; +} + +Bounds *Bounds::nearlyAmIIntersectingWith(const Bounds& other) const +{ + if( (other._x_min > _x_max+QUADRATIC_PLANAR::_precision) || (other._x_max < _x_min-QUADRATIC_PLANAR::_precision) || (other._y_min > _y_max+QUADRATIC_PLANAR::_precision) + || (other._y_max < _y_min-QUADRATIC_PLANAR::_precision) ) + return 0; + if( (other._x_min >= _x_max ) || (other._x_max <= _x_min) || (other._y_min >= _y_max) || (other._y_max <= _y_min) ) + { + return new Bounds(std::max(_x_min-QUADRATIC_PLANAR::_precision,other._x_min), + std::min(_x_max+QUADRATIC_PLANAR::_precision,other._x_max), + std::max(_y_min-QUADRATIC_PLANAR::_precision,other._y_min), + std::min(_y_max+QUADRATIC_PLANAR::_precision,other._y_max));//In approx cases. + } + else + return new Bounds(std::max(_x_min,other._x_min),std::min(_x_max,other._x_max),std::max(_y_min,other._y_min),std::min(_y_max,other._y_max)); +} + +Bounds *Bounds::amIIntersectingWith(const Bounds& other) const +{ + if( (other._x_min > _x_max) || (other._x_max < _x_min) || (other._y_min > _y_max) || (other._y_max < _y_min) ) + return 0; + return new Bounds(std::max(_x_min,other._x_min),std::min(_x_max,other._x_max),std::max(_y_min,other._y_min),std::min(_y_max,other._y_max)); +} + +Position Bounds::where(double x, double y) const +{ + if((x>=_x_min && x<=_x_max) && (y>=_y_min && y<=_y_max)) + return IN; + else + return OUT; +} + +Position Bounds::nearlyWhere(double x, double y) const +{ + bool thinX=Node::areDoubleEquals(_x_min,_x_max); + bool thinY=Node::areDoubleEquals(_y_min,_y_max); + if(!thinX) + { + if((Node::areDoubleEquals(x,_x_min) || Node::areDoubleEquals(x,_x_max)) && ((y<_y_max+QUADRATIC_PLANAR::_precision) && (y>_y_min-QUADRATIC_PLANAR::_precision))) + return ON_BOUNDARY_POS; + } + else + if(!Node::areDoubleEquals(_x_min,x) && !Node::areDoubleEquals(_x_max,x)) + return OUT; + if(!thinY) + { + if((Node::areDoubleEquals(y,_y_min) || Node::areDoubleEquals(y,_y_max)) && ((x<_x_max+QUADRATIC_PLANAR::_precision) && (x>_x_min-QUADRATIC_PLANAR::_precision))) + return ON_BOUNDARY_POS; + } + else + if(!Node::areDoubleEquals(_y_min,y) && !Node::areDoubleEquals(_y_max,y)) + return OUT; + if(thinX && thinY) + return ON_BOUNDARY_POS; + if((x>=_x_min && x<=_x_max) && (y>=_y_min && y<=_y_max)) + return IN; + else + return OUT; +} + +void Bounds::aggregate(const Bounds& other) +{ + _x_min=std::min(_x_min,other._x_min); _x_max=std::max(_x_max,other._x_max); + _y_min=std::min(_y_min,other._y_min); _y_max=std::max(_y_max,other._y_max); +} diff --git a/src/medtool/src/INTERP_KERNEL/Geometric2D/InterpKernelGeo2DBounds.hxx b/src/medtool/src/INTERP_KERNEL/Geometric2D/InterpKernelGeo2DBounds.hxx new file mode 100644 index 000000000..914391a9f --- /dev/null +++ b/src/medtool/src/INTERP_KERNEL/Geometric2D/InterpKernelGeo2DBounds.hxx @@ -0,0 +1,80 @@ +// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 +// 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 __INTERPKERNELGEO2DBOUNDS_HXX__ +#define __INTERPKERNELGEO2DBOUNDS_HXX__ + +#include "INTERPKERNELDefines.hxx" + +#include <algorithm> + +namespace INTERP_KERNEL +{ + /*! + * Relative LOC + */ + typedef enum + { + IN = 0, + OUT = 1, + ON_BOUNDARY_POS = 2, + ON_BOUNDARY_NEG = 3 + } Position; + + class INTERPKERNEL_EXPORT Bounds + { + public: + Bounds():_x_min(0.),_x_max(0.),_y_min(0.),_y_max(0.) { } + double &operator[](int i); + const double& operator[](int i) const; + double getXMin() const { return _x_min; } + double getXMax() const { return _x_max; } + double getYMin() const { return _y_min; } + double getYMax() const { return _y_max; } + double getDiagonal() const; + void getBarycenter(double& xBary, double& yBary) const; + void applySimilarity(double xBary, double yBary, double dimChar); + void unApplySimilarity(double xBary, double yBary, double dimChar); + Bounds& operator=(const Bounds& other) { _x_min=other._x_min; _x_max=other._x_max; _y_min=other._y_min; _y_max=other._y_max; return *this; } + Bounds(double xMin, double xMax, double yMin, double yMax):_x_min(xMin),_x_max(xMax),_y_min(yMin),_y_max(yMax) { } + void setValues(double xMin, double xMax, double yMin, double yMax) { _x_min=xMin; _x_max=xMax; _y_min=yMin; _y_max=yMax; } + void prepareForAggregation(); + void getInterceptedArc(const double *center, double radius, double& intrcptArcAngle0, double& intrcptArcDelta) const; + int fitXForXFig(double val, int res) const { return (int)fitXForXFigD(val,res); } + int fitYForXFig(double val, int res) const { return (int)fitYForXFigD(val,res); } + double fitXForXFigD(double val, int res) const; + double fitYForXFigD(double val, int res) const; + Bounds *nearlyAmIIntersectingWith(const Bounds& other) const; + Bounds *amIIntersectingWith(const Bounds& other) const; + //! No approximations. + Position where(double x, double y) const; + //! Idem where method but with approximations. + Position nearlyWhere(double x, double y) const; + void aggregate(const Bounds& other); + double getCaracteristicDim() const { return std::max(_x_max-_x_min,_y_max-_y_min); } + protected: + double _x_min; + double _x_max; + double _y_min; + double _y_max; + }; +} + +#endif diff --git a/src/medtool/src/INTERP_KERNEL/Geometric2D/InterpKernelGeo2DComposedEdge.cxx b/src/medtool/src/INTERP_KERNEL/Geometric2D/InterpKernelGeo2DComposedEdge.cxx new file mode 100644 index 000000000..9c310bbca --- /dev/null +++ b/src/medtool/src/INTERP_KERNEL/Geometric2D/InterpKernelGeo2DComposedEdge.cxx @@ -0,0 +1,672 @@ +// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 +// 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 "InterpKernelGeo2DComposedEdge.hxx" +#include "InterpKernelGeo2DElementaryEdge.hxx" +#include "InterpKernelGeo2DEdgeArcCircle.hxx" +#include "InterpKernelGeo2DEdgeInfLin.hxx" +#include "InterpKernelException.hxx" + +#include <algorithm> +#include <memory> +#include <iterator> +#include <set> + +using namespace INTERP_KERNEL; + +ComposedEdge::ComposedEdge(const ComposedEdge& other) +{ + for(std::list<ElementaryEdge *>::const_iterator iter=other._sub_edges.begin();iter!=other._sub_edges.end();iter++) + _sub_edges.push_back((*iter)->clone()); +} + +ComposedEdge::~ComposedEdge() +{ + clearAll(_sub_edges.begin()); +} + +void ComposedEdge::setValueAt(int i, Edge *e, bool direction) +{ + std::list<ElementaryEdge*>::iterator it=_sub_edges.begin(); + for(int j=0;j<i;j++) + it++; + delete *it; + *it=new ElementaryEdge(e,direction); +} + +/*! \cond HIDDEN_ITEMS */ +struct AbsEdgeCmp +{ + AbsEdgeCmp(ElementaryEdge *b):_b1(b) { } + bool operator()(ElementaryEdge *a) { return a->getPtr()==_b1->getPtr();} + + ElementaryEdge *_b1; +}; +/*! \endcond */ + +double ComposedEdge::getCommonLengthWith(const ComposedEdge& other) const +{ + double ret=0.; + for(std::list<ElementaryEdge *>::const_iterator iter=_sub_edges.begin();iter!=_sub_edges.end();iter++) + { + if(find_if(other._sub_edges.begin(),other._sub_edges.end(),AbsEdgeCmp(*iter))!=other._sub_edges.end()) + { + const ElementaryEdge *tmp=static_cast<const ElementaryEdge *>(*iter); + ret+=tmp->getCurveLength(); + } + } + return ret; +} + +void ComposedEdge::clear() +{ + clearAll(_sub_edges.begin()); + _sub_edges.clear(); +} + +void ComposedEdge::pushBack(Edge *edge, bool direction) +{ + _sub_edges.push_back(new ElementaryEdge(edge,direction)); +} + +void ComposedEdge::pushBack(ElementaryEdge *elem) +{ + _sub_edges.push_back(elem); +} + +void ComposedEdge::pushBack(ComposedEdge *elem) +{ + std::list<ElementaryEdge *> *elemsOfElem=elem->getListBehind(); + _sub_edges.insert(_sub_edges.end(),elemsOfElem->begin(),elemsOfElem->end()); +} + +ElementaryEdge *ComposedEdge::operator[](int i) const +{ + std::list<ElementaryEdge *>::const_iterator iter=_sub_edges.begin(); + for(int ii=0;ii<i;ii++) + iter++; + return *iter; +} + +void ComposedEdge::reverse() +{ + _sub_edges.reverse(); + for(std::list<ElementaryEdge *>::iterator iter=_sub_edges.begin();iter!=_sub_edges.end();iter++) + (*iter)->reverse(); +} + +bool ComposedEdge::presenceOfOn() const +{ + bool ret=false; + for(std::list<ElementaryEdge *>::const_iterator iter=_sub_edges.begin();iter!=_sub_edges.end() && !ret;iter++) + ret=((*iter)->getLoc()==FULL_ON_1); + return ret; +} + +bool ComposedEdge::presenceOfQuadraticEdge() const +{ + bool ret=false; + for(std::list<ElementaryEdge *>::const_iterator iter=_sub_edges.begin();iter!=_sub_edges.end() && !ret;iter++) + { + Edge *e=(*iter)->getPtr(); + if(e) + ret=dynamic_cast<EdgeArcCircle*>(e)!=0; + } + return ret; +} + +void ComposedEdge::initLocations() const +{ + for(std::list<ElementaryEdge *>::const_iterator iter=_sub_edges.begin();iter!=_sub_edges.end();iter++) + (*iter)->initLocations(); +} + +/** + * Reset the status of all edges (OUT, IN, ON) because they were potentially assigned + * by the previous candidate processing. + */ +void ComposedEdge::InitLocationsWithOther(const ComposedEdge& first, const ComposedEdge& other) +{ + std::set<Edge *> s1,s2; + for(std::list<ElementaryEdge *>::const_iterator it1=first._sub_edges.begin();it1!=first._sub_edges.end();it1++) + s1.insert((*it1)->getPtr()); + for(std::list<ElementaryEdge *>::const_iterator it2=other._sub_edges.begin();it2!=other._sub_edges.end();it2++) + s2.insert((*it2)->getPtr()); + first.initLocations(); + other.initLocations(); + std::vector<Edge *> s3; + std::set_intersection(s1.begin(),s1.end(),s2.begin(),s2.end(),std::back_insert_iterator< std::vector<Edge *> >(s3)); + for(std::vector<Edge *>::const_iterator it3=s3.begin();it3!=s3.end();it3++) + (*it3)->declareOn(); +} + +ComposedEdge *ComposedEdge::clone() const +{ + return new ComposedEdge(*this); +} + +bool ComposedEdge::isNodeIn(Node *n) const +{ + bool ret=false; + for(std::list<ElementaryEdge *>::const_iterator iter=_sub_edges.begin();iter!=_sub_edges.end() && !ret;iter++) + ret=(*iter)->isNodeIn(n); + return ret; +} + +/*! + * This method computes the area of 'this'. + * By definition : + * \f[ + * Area=\int_{Polygon} dS + * \f] + * Thanks to Green's theorem we have. + * \f[ + * \int_{Polygon} x \cdot dS=\sum_{0 \leq i < nb of edges} -\int_{Edge_{i}}ydx=\sum_{0 \leq i < nb of edges} AreaOfZone_{Edge_{i}} + * \f] + * Where \f$ AreaOfZone_{i} \f$ is computed virtually by INTERP_KERNEL::Edge::getAreaOfZone with following formula : + * \f[ + * AreaOfZone_{i}=\int_{Edge_{i}} -ydx + * \f] + */ +double ComposedEdge::getArea() const +{ + double ret=0.; + for(std::list<ElementaryEdge *>::const_iterator iter=_sub_edges.begin();iter!=_sub_edges.end();iter++) + ret+=(*iter)->getAreaOfZone(); + return ret; +} + +double ComposedEdge::getPerimeter() const +{ + double ret=0.; + for(std::list<ElementaryEdge *>::const_iterator iter=_sub_edges.begin();iter!=_sub_edges.end();iter++) + ret+=(*iter)->getCurveLength(); + return ret; +} + +double ComposedEdge::getHydraulicDiameter() const +{ + return 4*fabs(getArea())/getPerimeter(); +} + +/*! + * This method computes barycenter of 'this' by returning xG in bary[0] and yG in bary[1]. + * By definition : + * \f[ + * Area \cdot x_{G}=\int_{Polygon} x \cdot dS + * \f] + * \f[ + * Area \cdot y_{G}=\int_{Polygon} y \cdot dS + * \f] + * Thanks to Green's theorem we have. + * \f[ + * \int_{Polygon} x \cdot dS=\sum_{0 \leq i < nb of edges} -\int_{Edge_{i}}yxdx + * \f] + * \f[ + * \int_{Polygon} y \cdot dS=\sum_{0 \leq i < nb of edges} -\int_{Edge_{i}}\frac{y^{2}}{2}dx + * \f] + * Area is computed using the same principle than described in INTERP_KERNEL::ComposedEdge::getArea method. + * \f$ -\int_{Edge_{i}}yxdx \f$ and \f$ -\int_{Edge_{i}}\frac{y^{2}}{2}dx \f$ are computed virtually with INTERP_KERNEL::Edge::getBarycenterOfZone. + */ +void ComposedEdge::getBarycenter(double *bary) const +{ + bary[0]=0.; + bary[1]=0.; + double area=0.; + for(std::list<ElementaryEdge *>::const_iterator iter=_sub_edges.begin();iter!=_sub_edges.end();iter++) + { + (*iter)->getBarycenterOfZone(bary); + area+=(*iter)->getAreaOfZone(); + } + bary[0]/=area; + bary[1]/=area; +} + +/*! + * Idem ComposedEdge::getBarycenter except that the special case where _sub_edges==1 is dealt here. + */ +void ComposedEdge::getBarycenterGeneral(double *bary) const +{ + if(_sub_edges.empty()) + throw INTERP_KERNEL::Exception("ComposedEdge::getBarycenterGeneral called on an empty polygon !"); + if(_sub_edges.size()>2) + return getBarycenter(bary); + double w; + _sub_edges.back()->getBarycenter(bary,w); +} + +double ComposedEdge::normalizeMe(double& xBary, double& yBary) +{ + Bounds b; + b.prepareForAggregation(); + fillBounds(b); + double dimChar=b.getCaracteristicDim(); + b.getBarycenter(xBary,yBary); + applyGlobalSimilarity(xBary,yBary,dimChar); + return dimChar; +} + +double ComposedEdge::normalize(ComposedEdge *other, double& xBary, double& yBary) +{ + Bounds b; + b.prepareForAggregation(); + fillBounds(b); + other->fillBounds(b); + double dimChar=b.getCaracteristicDim(); + b.getBarycenter(xBary,yBary); + applyGlobalSimilarity(xBary,yBary,dimChar); + other->applyGlobalSimilarity(xBary,yBary,dimChar); + return dimChar; +} + +/*! + * This method operates the opposite operation than ComposedEdge::applyGlobalSimilarity. + */ +void ComposedEdge::unApplyGlobalSimilarityExt(ComposedEdge& other, double xBary, double yBary, double fact) +{ + initNodeHitStatus(); + other.initNodeHitStatus(); + unApplySimilarityOnMyNodes(xBary,yBary,fact); + other.unApplySimilarityOnMyNodesIfNotAlreadyHit(xBary,yBary,fact); + initEdgeHitStatus(); + other.initEdgeHitStatus(); + unApplySimilarityOnMyEdges(xBary,yBary,fact); + other.unApplySimilarityOnMyEdgesIfNotAlreadyHit(xBary,yBary,fact); +} + +double ComposedEdge::normalizeExt(ComposedEdge *other, double& xBary, double& yBary) +{ + Bounds b; + b.prepareForAggregation(); + fillBounds(b); + other->fillBounds(b); + double dimChar=b.getCaracteristicDim(); + b.getBarycenter(xBary,yBary); + applyGlobalSimilarity2(other,xBary,yBary,dimChar); + return dimChar; +} + +void ComposedEdge::dumpInXfigFile(std::ostream& stream, int resolution, const Bounds& box) const +{ + stream.precision(10); + for(std::list<ElementaryEdge *>::const_iterator iter=_sub_edges.begin();iter!=_sub_edges.end();iter++) + (*iter)->dumpInXfigFile(stream,resolution,box); +} + +Node *ComposedEdge::getEndNode() const +{ + return _sub_edges.back()->getEndNode(); +} + +Node *ComposedEdge::getStartNode() const +{ + return _sub_edges.front()->getStartNode(); +} + +bool ComposedEdge::changeEndNodeWith(Node *node) const +{ + return _sub_edges.back()->changeEndNodeWith(node); +} + +bool ComposedEdge::changeStartNodeWith(Node *node) const +{ + return _sub_edges.front()->changeStartNodeWith(node); +} + +void ComposedEdge::fillBounds(Bounds& output) const +{ + for(std::list<ElementaryEdge *>::const_iterator iter=_sub_edges.begin();iter!=_sub_edges.end();iter++) + (*iter)->fillBounds(output); +} + +/*! + * \b WARNING : applies similarity \b ONLY on edges without any change on Nodes. To perform a global similarity call applyGlobalSimilarity. + */ +void ComposedEdge::applySimilarity(double xBary, double yBary, double dimChar) +{ + for(std::list<ElementaryEdge *>::iterator iter=_sub_edges.begin();iter!=_sub_edges.end();iter++) + (*iter)->applySimilarity(xBary,yBary,dimChar); +} + +/*! + * Perform Similarity transformation on all elements of this Nodes and Edges. + */ +void ComposedEdge::applyGlobalSimilarity(double xBary, double yBary, double dimChar) +{ + std::set<Node *> allNodes; + getAllNodes(allNodes); + for(std::set<Node *>::iterator iter=allNodes.begin();iter!=allNodes.end();iter++) + (*iter)->applySimilarity(xBary,yBary,dimChar); + for(std::list<ElementaryEdge *>::iterator iter=_sub_edges.begin();iter!=_sub_edges.end();iter++) + (*iter)->applySimilarity(xBary,yBary,dimChar); +} + +/*! + * Perform Similarity transformation on all elements of this Nodes and Edges on 'this' and 'other'. + * Nodes can be shared between 'this' and 'other'. + */ +void ComposedEdge::applyGlobalSimilarity2(ComposedEdge *other, double xBary, double yBary, double dimChar) +{ + initNodeHitStatus(); + other->initNodeHitStatus(); + applySimilarityOnMyNodes(xBary,yBary,dimChar); + other->applySimilarityOnMyNodesIfNotAlreadyHit(xBary,yBary,dimChar); + initEdgeHitStatus(); + other->initEdgeHitStatus(); + applySimilarityOnMyEdges(xBary,yBary,dimChar); + other->applySimilarityOnMyEdgesIfNotAlreadyHit(xBary,yBary,dimChar); +} + +/*! + * This method append to param 'partConsidered' the part of length of subedges IN or ON. + * @param partConsidered INOUT param. + */ +void ComposedEdge::dispatchPerimeter(double& partConsidered) const +{ + for(std::list<ElementaryEdge *>::const_iterator iter=_sub_edges.begin();iter!=_sub_edges.end();iter++) + { + TypeOfEdgeLocInPolygon loc=(*iter)->getLoc(); + if(loc==FULL_IN_1 || loc==FULL_ON_1) + partConsidered+=(*iter)->getCurveLength(); + } +} + +/*! + * Idem dispatchPerimeterExcl except that when a subedge is declared as ON this subedge is counted in commonPart. + */ +void ComposedEdge::dispatchPerimeterExcl(double& partConsidered, double& commonPart) const +{ + for(std::list<ElementaryEdge *>::const_iterator iter=_sub_edges.begin();iter!=_sub_edges.end();iter++) + { + TypeOfEdgeLocInPolygon loc=(*iter)->getLoc(); + if(loc==FULL_IN_1) + partConsidered+=(*iter)->getCurveLength(); + if(loc==FULL_ON_1) + commonPart+=(*iter)->getCurveLength(); + } +} + +void ComposedEdge::getAllNodes(std::set<Node *>& output) const +{ + std::list<ElementaryEdge *>::const_iterator iter=_sub_edges.begin(); + for(;iter!=_sub_edges.end();iter++) + (*iter)->getAllNodes(output); +} + +void ComposedEdge::initNodeHitStatus() const +{ + for(std::list<ElementaryEdge *>::const_iterator iter=_sub_edges.begin();iter!=_sub_edges.end();iter++) + { + (*iter)->getStartNode()->initHitStatus(); + (*iter)->getEndNode()->initHitStatus(); + } +} + +void ComposedEdge::applySimilarityOnMyNodes(double xBary, double yBary, double dimChar) const +{ + for(std::list<ElementaryEdge *>::const_iterator iter=_sub_edges.begin();iter!=_sub_edges.end();iter++) + { + (*iter)->getStartNode()->hitMeAlone(xBary,yBary,dimChar); + (*iter)->getEndNode()->hitMeAlone(xBary,yBary,dimChar); + } +} + +void ComposedEdge::unApplySimilarityOnMyNodes(double xBary, double yBary, double dimChar) const +{ + for(std::list<ElementaryEdge *>::const_iterator iter=_sub_edges.begin();iter!=_sub_edges.end();iter++) + { + (*iter)->getStartNode()->unHitMeAlone(xBary,yBary,dimChar); + (*iter)->getEndNode()->unHitMeAlone(xBary,yBary,dimChar); + } +} + +void ComposedEdge::applySimilarityOnMyNodesIfNotAlreadyHit(double xBary, double yBary, double dimChar) const +{ + for(std::list<ElementaryEdge *>::const_iterator iter=_sub_edges.begin();iter!=_sub_edges.end();iter++) + { + (*iter)->getStartNode()->hitMeAfter(xBary,yBary,dimChar); + (*iter)->getEndNode()->hitMeAfter(xBary,yBary,dimChar); + } +} + +void ComposedEdge::unApplySimilarityOnMyNodesIfNotAlreadyHit(double xBary, double yBary, double dimChar) const +{ + for(std::list<ElementaryEdge *>::const_iterator iter=_sub_edges.begin();iter!=_sub_edges.end();iter++) + { + (*iter)->getStartNode()->unHitMeAfter(xBary,yBary,dimChar); + (*iter)->getEndNode()->unHitMeAfter(xBary,yBary,dimChar); + } +} + +void ComposedEdge::initEdgeHitStatus() const +{ + for(std::list<ElementaryEdge *>::const_iterator iter=_sub_edges.begin();iter!=_sub_edges.end();iter++) + (*iter)->getPtr()->initHitStatus(); +} + +void ComposedEdge::applySimilarityOnMyEdges(double xBary, double yBary, double dimChar) const +{ + for(std::list<ElementaryEdge *>::const_iterator iter=_sub_edges.begin();iter!=_sub_edges.end();iter++) + (*iter)->getPtr()->hitMeAlone(xBary,yBary,dimChar); +} + +void ComposedEdge::unApplySimilarityOnMyEdges(double xBary, double yBary, double dimChar) const +{ + for(std::list<ElementaryEdge *>::const_iterator iter=_sub_edges.begin();iter!=_sub_edges.end();iter++) + (*iter)->getPtr()->unHitMeAlone(xBary,yBary,dimChar); +} + +void ComposedEdge::applySimilarityOnMyEdgesIfNotAlreadyHit(double xBary, double yBary, double dimChar) const +{ + for(std::list<ElementaryEdge *>::const_iterator iter=_sub_edges.begin();iter!=_sub_edges.end();iter++) + (*iter)->getPtr()->hitMeAfter(xBary,yBary,dimChar); +} + +void ComposedEdge::unApplySimilarityOnMyEdgesIfNotAlreadyHit(double xBary, double yBary, double dimChar) const +{ + for(std::list<ElementaryEdge *>::const_iterator iter=_sub_edges.begin();iter!=_sub_edges.end();iter++) + (*iter)->getPtr()->unHitMeAfter(xBary,yBary,dimChar); +} + +void ComposedEdge::getBarycenter(double *bary, double& weigh) const +{ + weigh=0.; bary[0]=0.; bary[1]=0.; + double tmp1,tmp2[2]; + for(std::list<ElementaryEdge *>::const_iterator iter=_sub_edges.begin();iter!=_sub_edges.end();iter++) + { + (*iter)->getBarycenter(tmp2,tmp1); + weigh+=tmp1; + bary[0]+=tmp1*tmp2[0]; + bary[1]+=tmp1*tmp2[1]; + } + bary[0]/=weigh; + bary[1]/=weigh; +} + +/*! + * This method makes the hypothesis that \a nodeToTest can be either IN or OUT. + * + * \sa ComposedEdge::isInOrOut2 + */ +bool ComposedEdge::isInOrOut(Node *nodeToTest) const +{ + Bounds b; b.prepareForAggregation(); + fillBounds(b); + if(b.nearlyWhere((*nodeToTest)[0],(*nodeToTest)[1])==OUT) + return false; + std::set< IntersectElement > inOutSwitch; + double ref(isInOrOutAlg(nodeToTest,inOutSwitch)); + bool ret(false); + for(std::set< IntersectElement >::iterator iter4=inOutSwitch.begin();iter4!=inOutSwitch.end();iter4++) + { + if((*iter4).getVal1()<ref) + { + if((*iter4).getNodeOnly()->getLoc()==ON_1) + ret=!ret; + } + else + break; + } + return ret; +} + +/*! + * This method is close to ComposedEdge::isInOrOut behaviour except that here EPSILON is taken into account to detect if it is IN or OUT. + * If \a nodeToTest is close to an edge in \a this, true will be returned even if it is outside informatically from \a this. + * + * \sa ComposedEdge::isInOrOut + */ +bool ComposedEdge::isInOrOut2(Node *nodeToTest) const +{ + std::set< IntersectElement > inOutSwitch; + double ref(isInOrOutAlg(nodeToTest,inOutSwitch)); + bool ret(false); + for(std::set< IntersectElement >::iterator iter4=inOutSwitch.begin();iter4!=inOutSwitch.end();iter4++) + { + double val((*iter4).getVal1()); + if(fabs(val-ref)>=QUADRATIC_PLANAR::_precision) + { + if(val<ref) + { + if((*iter4).getNodeOnly()->getLoc()==ON_1) + ret=!ret; + } + else + break; + } + else + return true; + } + return ret; +} + +double ComposedEdge::isInOrOutAlg(Node *nodeToTest, std::set< IntersectElement >& inOutSwitch) const +{ + // searching for e1 + std::set<Node *> nodes; + getAllNodes(nodes); + std::set<double> radialDistributionOfNodes; + std::set<Node *>::const_iterator iter; + for(iter=nodes.begin();iter!=nodes.end();iter++) + radialDistributionOfNodes.insert(nodeToTest->getSlope(*(*iter))); + std::vector<double> radialDistrib(radialDistributionOfNodes.begin(),radialDistributionOfNodes.end()); + radialDistributionOfNodes.clear(); + std::vector<double> radialDistrib2(radialDistrib.size()); + copy(radialDistrib.begin()+1,radialDistrib.end(),radialDistrib2.begin()); + radialDistrib2.back()=M_PI+radialDistrib.front(); + std::vector<double> radialDistrib3(radialDistrib.size()); + std::transform(radialDistrib2.begin(),radialDistrib2.end(),radialDistrib.begin(),radialDistrib3.begin(),std::minus<double>()); + std::vector<double>::iterator iter3=max_element(radialDistrib3.begin(),radialDistrib3.end()); + int i=iter3-radialDistrib3.begin(); + // ok for e1 - Let's go. + EdgeInfLin *e1=new EdgeInfLin(nodeToTest,radialDistrib[i]+radialDistrib3[i]/2.); + double ref=e1->getCharactValue(*nodeToTest); + for(std::list<ElementaryEdge *>::const_iterator iter4=_sub_edges.begin();iter4!=_sub_edges.end();iter4++) + { + ElementaryEdge *val=(*iter4); + if(val) + { + Edge *e=val->getPtr(); + std::auto_ptr<EdgeIntersector> intersc(Edge::BuildIntersectorWith(e1,e)); + bool obviousNoIntersection,areOverlapped; + intersc->areOverlappedOrOnlyColinears(0,obviousNoIntersection,areOverlapped); // first parameter never used + if(obviousNoIntersection) + { + continue; + } + if(!areOverlapped) + { + std::list< IntersectElement > listOfIntesc=intersc->getIntersectionsCharacteristicVal(); + for(std::list< IntersectElement >::iterator iter2=listOfIntesc.begin();iter2!=listOfIntesc.end();iter2++) + if((*iter2).isIncludedByBoth()) + inOutSwitch.insert(*iter2); + } + //if overlapped we can forget + } + else + throw Exception("Invalid use of ComposedEdge::isInOrOutAlg : only one level supported !"); + } + e1->decrRef(); + return ref; +} + +/*bool ComposedEdge::isInOrOut(Node *aNodeOn, Node *nodeToTest) const +{ + + EdgeInfLin *e1=new EdgeInfLin(aNodeOn,nodeToTest); + double ref=e1->getCharactValue(*nodeToTest); + set< IntersectElement > inOutSwitch; + for(vector<AbstractEdge *>::const_iterator iter=_sub_edges.begin();iter!=_sub_edges.end();iter++) + { + ElementaryEdge *val=dynamic_cast<ElementaryEdge *>(*iter); + if(val) + { + Edge *e=val->getPtr(); + auto_ptr<Intersector> intersc(Edge::buildIntersectorWith(e1,e)); + bool obviousNoIntersection,areOverlapped; + intersc->areOverlappedOrOnlyColinears(0,obviousNoIntersection,areOverlapped); + if(obviousNoIntersection) + { + continue; + } + if(!areOverlapped) + { + list< IntersectElement > listOfIntesc=intersc->getIntersectionsCharacteristicVal(); + for(list< IntersectElement >::iterator iter2=listOfIntesc.begin();iter2!=listOfIntesc.end();iter2++) + if((*iter2).isIncludedByBoth()) + inOutSwitch.insert(*iter2); + } + //if overlapped we can forget + } + else + throw Exception("Invalid use of ComposedEdge::isInOrOut : only one level supported !"); + } + e1->decrRef(); + bool ret=false; + for(set< IntersectElement >::iterator iter=inOutSwitch.begin();iter!=inOutSwitch.end();iter++) + { + if((*iter).getVal1()<ref) + { + if((*iter).getNodeOnly()->getLoc()==ON_1) + ret=!ret; + } + else + break; + } + return ret; +}*/ + +bool ComposedEdge::getDirection() const +{ + throw Exception("ComposedEdge::getDirection : no sense"); +} + +bool ComposedEdge::intresincEqCoarse(const Edge *other) const +{ + if(_sub_edges.size()!=1) + return false; + return _sub_edges.front()->intresincEqCoarse(other); +} + +void ComposedEdge::clearAll(std::list<ElementaryEdge *>::iterator startToDel) +{ + for(std::list<ElementaryEdge *>::iterator iter=startToDel;iter!=_sub_edges.end();iter++) + delete (*iter); +} diff --git a/src/medtool/src/INTERP_KERNEL/Geometric2D/InterpKernelGeo2DComposedEdge.hxx b/src/medtool/src/INTERP_KERNEL/Geometric2D/InterpKernelGeo2DComposedEdge.hxx new file mode 100644 index 000000000..f4c56fbac --- /dev/null +++ b/src/medtool/src/INTERP_KERNEL/Geometric2D/InterpKernelGeo2DComposedEdge.hxx @@ -0,0 +1,124 @@ +// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 +// 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 __INTERPKERNELGEO2DCOMPOSEDNODE_HXX__ +#define __INTERPKERNELGEO2DCOMPOSEDNODE_HXX__ + +#include "INTERPKERNELDefines.hxx" +#include "InterpKernelGeo2DEdge.hxx" + +#include <set> +#include <list> +#include <vector> +#include <ostream> + +namespace INTERP_KERNEL +{ + class Node; + class Edge; + class Bounds; + class ElementaryEdge; + class IteratorOnComposedEdge; + + /** + * A set of quadratic or linear edges, described mainly by their connectivity + * The set is assumed to be connected, but not necessarily closed (i.e. not necessarily forming a closed polygon). + * Some methods however requires a closed form. + */ + class ComposedEdge + { + friend class IteratorOnComposedEdge; + public: + INTERPKERNEL_EXPORT ComposedEdge() { } + INTERPKERNEL_EXPORT ComposedEdge(const ComposedEdge& other); + INTERPKERNEL_EXPORT ComposedEdge(int sz):_sub_edges(sz) { } + INTERPKERNEL_EXPORT static void Delete(ComposedEdge *pt) { delete pt; } + INTERPKERNEL_EXPORT static void SoftDelete(ComposedEdge *pt) { pt->_sub_edges.clear(); delete pt; } + INTERPKERNEL_EXPORT void reverse(); + INTERPKERNEL_EXPORT int recursiveSize() const { return (int)_sub_edges.size(); } + INTERPKERNEL_EXPORT bool presenceOfOn() const; + INTERPKERNEL_EXPORT bool presenceOfQuadraticEdge() const; + INTERPKERNEL_EXPORT void initLocations() const; + INTERPKERNEL_EXPORT static void InitLocationsWithOther(const ComposedEdge& first, const ComposedEdge& other); + INTERPKERNEL_EXPORT ComposedEdge *clone() const; + INTERPKERNEL_EXPORT bool isNodeIn(Node *n) const; + INTERPKERNEL_EXPORT double getArea() const; + INTERPKERNEL_EXPORT double getPerimeter() const; + INTERPKERNEL_EXPORT double getHydraulicDiameter() const; + INTERPKERNEL_EXPORT void getBarycenter(double *bary) const; + INTERPKERNEL_EXPORT void getBarycenterGeneral(double *bary) const; + INTERPKERNEL_EXPORT double normalizeMe(double& xBary, double& yBary); + INTERPKERNEL_EXPORT double normalize(ComposedEdge *other, double& xBary, double& yBary); + INTERPKERNEL_EXPORT double normalizeExt(ComposedEdge *other, double& xBary, double& yBary); + INTERPKERNEL_EXPORT void unApplyGlobalSimilarityExt(ComposedEdge& other, double xBary, double yBary, double fact); + INTERPKERNEL_EXPORT void fillBounds(Bounds& output) const; + INTERPKERNEL_EXPORT void applySimilarity(double xBary, double yBary, double dimChar); + INTERPKERNEL_EXPORT void applyGlobalSimilarity(double xBary, double yBary, double dimChar); + INTERPKERNEL_EXPORT void applyGlobalSimilarity2(ComposedEdge *other, double xBary, double yBary, double dimChar); + INTERPKERNEL_EXPORT void dispatchPerimeter(double& partConsidered) const; + INTERPKERNEL_EXPORT void dispatchPerimeterExcl(double& partConsidered, double& commonPart) const; + INTERPKERNEL_EXPORT double dispatchPerimeterAdv(const ComposedEdge& father, std::vector<double>& result) const; + INTERPKERNEL_EXPORT void getAllNodes(std::set<Node *>& output) const; + INTERPKERNEL_EXPORT void initNodeHitStatus() const; + INTERPKERNEL_EXPORT void applySimilarityOnMyNodes(double xBary, double yBary, double dimChar) const; + INTERPKERNEL_EXPORT void unApplySimilarityOnMyNodes(double xBary, double yBary, double dimChar) const; + INTERPKERNEL_EXPORT void applySimilarityOnMyNodesIfNotAlreadyHit(double xBary, double yBary, double dimChar) const; + INTERPKERNEL_EXPORT void unApplySimilarityOnMyNodesIfNotAlreadyHit(double xBary, double yBary, double dimChar) const; + INTERPKERNEL_EXPORT void initEdgeHitStatus() const; + INTERPKERNEL_EXPORT void applySimilarityOnMyEdges(double xBary, double yBary, double dimChar) const; + INTERPKERNEL_EXPORT void unApplySimilarityOnMyEdges(double xBary, double yBary, double dimChar) const; + INTERPKERNEL_EXPORT void applySimilarityOnMyEdgesIfNotAlreadyHit(double xBary, double yBary, double dimChar) const; + INTERPKERNEL_EXPORT void unApplySimilarityOnMyEdgesIfNotAlreadyHit(double xBary, double yBary, double dimChar) const; + INTERPKERNEL_EXPORT void getBarycenter(double *bary, double& weigh) const; + INTERPKERNEL_EXPORT bool completed() const { return getEndNode()==getStartNode(); } + INTERPKERNEL_EXPORT void setValueAt(int i, Edge *e, bool direction=true); + INTERPKERNEL_EXPORT double getCommonLengthWith(const ComposedEdge& other) const; + INTERPKERNEL_EXPORT void clear(); + INTERPKERNEL_EXPORT bool empty() const { return _sub_edges.empty(); } + INTERPKERNEL_EXPORT ElementaryEdge *front() const { return _sub_edges.front(); } + INTERPKERNEL_EXPORT ElementaryEdge *back() const { return _sub_edges.back(); } + INTERPKERNEL_EXPORT void resize(int i) { _sub_edges.resize(i); } + INTERPKERNEL_EXPORT void pushBack(Edge *edge, bool direction=true); + INTERPKERNEL_EXPORT void pushBack(ElementaryEdge *elem); + INTERPKERNEL_EXPORT void pushBack(ComposedEdge *elem); + INTERPKERNEL_EXPORT int size() const { return (int)_sub_edges.size(); } + INTERPKERNEL_EXPORT ElementaryEdge *operator[](int i) const; + INTERPKERNEL_EXPORT Node *getEndNode() const; + INTERPKERNEL_EXPORT Node *getStartNode() const; + INTERPKERNEL_EXPORT bool changeEndNodeWith(Node *node) const; + INTERPKERNEL_EXPORT bool changeStartNodeWith(Node *node) const; + INTERPKERNEL_EXPORT void dumpInXfigFile(std::ostream& stream, int resolution, const Bounds& box) const; + INTERPKERNEL_EXPORT bool isInOrOut(Node *nodeToTest) const; + INTERPKERNEL_EXPORT bool isInOrOut2(Node *nodeToTest) const; + INTERPKERNEL_EXPORT bool getDirection() const; + INTERPKERNEL_EXPORT bool intresincEqCoarse(const Edge *other) const; + private: + std::list<ElementaryEdge *>* getListBehind() { return &_sub_edges; } + double isInOrOutAlg(Node *nodeToTest, std::set< IntersectElement >& inOutSwitch) const; + protected: + ~ComposedEdge(); + private: + void clearAll(std::list<ElementaryEdge *>::iterator startToDel); + protected: + std::list<ElementaryEdge *> _sub_edges; + }; +} + +#endif diff --git a/src/medtool/src/INTERP_KERNEL/Geometric2D/InterpKernelGeo2DEdge.cxx b/src/medtool/src/INTERP_KERNEL/Geometric2D/InterpKernelGeo2DEdge.cxx new file mode 100644 index 000000000..166252287 --- /dev/null +++ b/src/medtool/src/INTERP_KERNEL/Geometric2D/InterpKernelGeo2DEdge.cxx @@ -0,0 +1,1032 @@ +// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 +// 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 "InterpKernelGeo2DEdge.hxx" +#include "InterpKernelGeo2DEdgeLin.hxx" +#include "InterpKernelGeo2DEdgeInfLin.hxx" +//#include "EdgeParabol.hxx" +#include "InterpKernelGeo2DEdgeArcCircle.hxx" +#include "InterpKernelGeo2DComposedEdge.hxx" +#include "InterpKernelException.hxx" + +#include <algorithm> + +using namespace INTERP_KERNEL; + +MergePoints::MergePoints():_ass1Start1(0),_ass1End1(0),_ass1Start2(0),_ass1End2(0), + _ass2Start1(0),_ass2End1(0),_ass2Start2(0),_ass2End2(0) +{ +} + +void MergePoints::start1Replaced() +{ + unsigned nbOfAsso=getNumberOfAssociations(); + if(nbOfAsso==0) + _ass1Start1=1; + else + _ass2Start1=1; +} + +void MergePoints::end1Replaced() +{ + unsigned nbOfAsso=getNumberOfAssociations(); + if(nbOfAsso==0) + _ass1End1=1; + else + _ass2End1=1; +} + +void MergePoints::start1OnStart2() +{ + unsigned nbOfAsso=getNumberOfAssociations(); + if(nbOfAsso==0) + { + _ass1Start1=1; + _ass1Start2=1; + } + else + { + _ass2Start1=1; + _ass2Start2=1; + } +} + +void MergePoints::start1OnEnd2() +{ + unsigned nbOfAsso=getNumberOfAssociations(); + if(nbOfAsso==0) + { + _ass1Start1=1; + _ass1End2=1; + } + else + { + _ass2Start1=1; + _ass2End2=1; + } +} + +void MergePoints::end1OnStart2() +{ + unsigned nbOfAsso=getNumberOfAssociations(); + if(nbOfAsso==0) + { + _ass1End1=1; + _ass1Start2=1; + } + else + { + _ass2End1=1; + _ass2Start2=1; + } +} + +void MergePoints::end1OnEnd2() +{ + unsigned nbOfAsso=getNumberOfAssociations(); + if(nbOfAsso==0) + { + _ass1End1=1; + _ass1End2=1; + } + else + { + _ass2End1=1; + _ass2End2=1; + } +} + +bool MergePoints::isStart1(unsigned rk) const +{ + if(rk==0) + return _ass1Start1; + else + return _ass2Start1; +} + +bool MergePoints::isEnd1(unsigned rk) const +{ + if(rk==0) + return _ass1End1; + else + return _ass2End1; +} + +bool MergePoints::isStart2(unsigned rk) const +{ + if(rk==0) + return _ass1Start2; + else + return _ass2Start2; +} + +bool MergePoints::isEnd2(unsigned rk) const +{ + if(rk==0) + return _ass1End2; + else + return _ass2End2; +} + +void MergePoints::clear() +{ + _ass1Start1=0;_ass1End1=0;_ass1Start2=0;_ass1End2=0; + _ass2Start1=0;_ass2End1=0;_ass2Start2=0;_ass2End2=0; +} + +unsigned MergePoints::getNumberOfAssociations() const +{ + unsigned ret=0; + unsigned subTot=_ass1Start1+_ass1End1+_ass1Start2+_ass1End2; + if(subTot!=0) + ret++; + subTot=_ass2Start1+_ass2End1+_ass2Start2+_ass2End2; + if(subTot!=0) + ret++; + return ret; +} + +void MergePoints::PushInMap(int key, int value, std::map<int,int>& mergedNodes) +{ + if(key!=-1 && value!=-1) + mergedNodes[key]=value; +} + +void MergePoints::updateMergedNodes(int e1Start, int e1End, int e2Start, int e2End, std::map<int,int>& mergedNodes) +{ + unsigned subTot(_ass1Start1+_ass1End1+_ass1Start2+_ass1End2); + if(subTot!=0) + { + if(_ass1Start1 && _ass1Start2) + PushInMap(e2Start,e1Start,mergedNodes); + if(_ass1Start1 && _ass1End2) + PushInMap(e2End,e1Start,mergedNodes); + if(_ass1End1 && _ass1Start2) + PushInMap(e2Start,e1End,mergedNodes); + if(_ass1End1 && _ass1End2) + PushInMap(e2End,e1End,mergedNodes); + } + subTot=_ass2Start1+_ass2End1+_ass2Start2+_ass2End2; + if(subTot!=0) + { + if(_ass2Start1 && _ass2Start2) + PushInMap(e2Start,e1Start,mergedNodes); + if(_ass2Start1 && _ass2End2) + PushInMap(e2End,e1Start,mergedNodes); + if(_ass2End1 && _ass2Start2) + PushInMap(e2Start,e1End,mergedNodes); + if(_ass2End1 && _ass2End2) + PushInMap(e2End,e1End,mergedNodes); + } +} + +IntersectElement::IntersectElement(double val1, double val2, bool start1, bool end1, bool start2, bool end2, Node *node + , const Edge& e1, const Edge& e2, bool keepOrder):_1S(keepOrder?start1:start2), + _1E(keepOrder?end1:end2), + _2S(keepOrder?start2:start1), + _2E(keepOrder?end2:end1), + _chararct_val_for_e1(keepOrder?val1:val2), + _chararct_val_for_e2(keepOrder?val2:val1), + _node(node),_loc_of_node(node->getLoc()),_e1(keepOrder?e1:e2), + _e2(keepOrder?e2:e1) +{ +} + +IntersectElement::IntersectElement(const IntersectElement& other):_1S(other._1S),_1E(other._1E),_2S(other._2S),_2E(other._2E), + _chararct_val_for_e1(other._chararct_val_for_e1), + _chararct_val_for_e2(other._chararct_val_for_e2),_node(other._node), + _loc_of_node(other._loc_of_node),_e1(other._e1), _e2(other._e2) +{ + if(_node) + _node->incrRef(); +} + +IntersectElement& IntersectElement::operator=(const IntersectElement& other) +{ + _1S=other._1S;_1E=other._1E; _2S=other._2S; _2E=other._2E; + _chararct_val_for_e1=other._chararct_val_for_e1; + _chararct_val_for_e2=other._chararct_val_for_e2; + setNode(other._node); + return *this; +} + +bool IntersectElement::operator<(const IntersectElement& other) const +{ + return _e1.isLower(_chararct_val_for_e1,other._chararct_val_for_e1); +} + +IntersectElement::~IntersectElement() +{ + if(_node) + _node->decrRef(); +} + +/*! + * Returns 0 or 1. + */ +bool IntersectElement::isOnMergedExtremity() const +{ + if( (_1S && _2S) || (_1S && _2E) || (_1E && _2S) || (_1E && _2E) ) + return true; + return false; +} + +/*! + * To call if isOnMergedExtremity returned true. + */ +void IntersectElement::performMerging(MergePoints& commonNode) const +{ + if(_1S && _2S) + { + if(_e1.changeStartNodeWith(_e2.getStartNode())) + { + _e2.getStartNode()->declareOnLim(); + commonNode.start1OnStart2(); + } + } + else if(_1S && _2E) + { + if(_e1.changeStartNodeWith(_e2.getEndNode())) + { + _e2.getEndNode()->declareOnLim(); + commonNode.start1OnEnd2(); + } + } + else if(_1E && _2S) + { + if(_e1.changeEndNodeWith(_e2.getStartNode())) + { + _e2.getStartNode()->declareOnLim(); + commonNode.end1OnStart2(); + } + } + else if(_1E && _2E) + { + if(_e1.changeEndNodeWith(_e2.getEndNode())) + { + _e2.getEndNode()->declareOnLim(); + commonNode.end1OnEnd2(); + } + } +} + +/*! + * This methode is const because 'node' is supposed to be equal geomitrically to _node. + */ +void IntersectElement::setNode(Node *node) const +{ + if(node!=_node) + { + if(_node) + ((Node *)_node)->decrRef(); + (const_cast<IntersectElement *>(this))->_node=node; + if(_node) + _node->incrRef(); + } +} + +bool IntersectElement::isLowerOnOther(const IntersectElement& other) const +{ + return _e2.isLower(_chararct_val_for_e2,other._chararct_val_for_e2); +} + +unsigned IntersectElement::isOnExtrForAnEdgeAndInForOtherEdge() const +{ + if(( _1S && !(_2S || _2E) ) || ( _1E && !(_2S || _2E) )) + { + if(_1S && !(_2S || _2E)) + setNode(_e1.getStartNode()); + else + setNode(_e1.getEndNode()); + if(_e2.isIn(_chararct_val_for_e2)) + return LIMIT_ON; + return LIMIT_ALONE; + } + if(( _2S && !(_1S || _1E) ) || ( _2E && !(_1S || _1E))) + { + if(_2S && !(_1S || _1E)) + setNode(_e2.getStartNode()); + else + setNode(_e2.getEndNode()); + if(_e1.isIn(_chararct_val_for_e1)) + return LIMIT_ON; + return LIMIT_ALONE; + } + return NO_LIMIT; +} + +bool IntersectElement::isIncludedByBoth() const +{ + return _e1.isIn(_chararct_val_for_e1) && _e2.isIn(_chararct_val_for_e2); +} + +bool EdgeIntersector::intersect(const Bounds *whereToFind, std::vector<Node *>& newNodes, bool& order, MergePoints& commonNode) +{ + std::list< IntersectElement > listOfIntesc=getIntersectionsCharacteristicVal(); + std::list< IntersectElement >::iterator iter; + for(iter=listOfIntesc.begin();iter!=listOfIntesc.end();) + { + if((*iter).isOnMergedExtremity()) + { + (*iter).performMerging(commonNode); + iter=listOfIntesc.erase(iter); + continue; + } + unsigned tmp=(*iter).isOnExtrForAnEdgeAndInForOtherEdge(); + if(tmp==IntersectElement::LIMIT_ALONE) + { + iter=listOfIntesc.erase(iter); + continue; + } + else if(tmp==IntersectElement::LIMIT_ON) + { + (*iter).attachLoc(); + iter++; + continue; + } + if(!(*iter).isIncludedByBoth()) + { + iter=listOfIntesc.erase(iter); + continue; + } + (*iter).attachLoc(); + iter++; + } + if(listOfIntesc.size()==0) + return false; + if(listOfIntesc.size()==1) + { + order=true;//useless + newNodes.push_back(listOfIntesc.front().getNodeAndReleaseIt()); + } + else + { + std::vector<IntersectElement> vecOfIntesc(listOfIntesc.begin(),listOfIntesc.end()); + listOfIntesc.clear(); + sort(vecOfIntesc.begin(),vecOfIntesc.end()); + for(std::vector<IntersectElement>::iterator iterV=vecOfIntesc.begin();iterV!=vecOfIntesc.end();iterV++) + newNodes.push_back((*iterV).getNodeAndReleaseIt()); + order=vecOfIntesc.front().isLowerOnOther(vecOfIntesc.back()); + } + return true; +} + +/*! + * Locates 'node' regarding edge this->_e1. If node is located close to (with distant lt epsilon) start or end point of _e1, + * 'node' takes its place. In this case 'obvious' is set to true and 'commonNode' stores information of merge point and finally 'where' is set. + * Furthermore 'node' is declared as ON LIMIT to indicate in locating process that an absolute location computation will have to be done. + * If 'node' is not close to start or end point of _e1, 'obvious' is set to false and 'commonNode' and 'where' are let unchanged. + */ +void EdgeIntersector::obviousCaseForCurvAbscisse(Node *node, TypeOfLocInEdge& where, MergePoints& commonNode, bool& obvious) const +{ + obvious=true; + if(node->isEqual(*_e1.getStartNode())) + { + where=START; + if(_e1.changeStartNodeWith(node)) + { + commonNode.start1Replaced(); + node->declareOnLim(); + } + return ; + } + if(node->isEqual(*_e1.getEndNode())) + { + where=END; + if(_e1.changeEndNodeWith(node)) + { + commonNode.end1Replaced(); + node->declareOnLim(); + } + return ; + } + obvious=false; +} + +Edge::Edge(double sX, double sY, double eX, double eY):_cnt(1),_loc(FULL_UNKNOWN),_start(new Node(sX,sY)),_end(new Node(eX,eY)) +{ +} + +Edge::~Edge() +{ + _start->decrRef(); + if(_end) + _end->decrRef(); +} + +bool Edge::decrRef() +{ + bool ret=(--_cnt==0); + if(ret) + delete this; + return ret; +} + +void Edge::declareOn() const +{ + if(_loc==FULL_UNKNOWN) + { + _loc=FULL_ON_1; + _start->declareOn(); + _end->declareOn(); + } +} + +void Edge::declareIn() const +{ + if(_loc==FULL_UNKNOWN) + { + _loc=FULL_IN_1; + _start->declareIn(); + _end->declareIn(); + } +} + +void Edge::declareOut() const +{ + if(_loc==FULL_UNKNOWN) + { + _loc=FULL_OUT_1; + _start->declareOut(); + _end->declareOut(); + } +} + +void Edge::fillXfigStreamForLoc(std::ostream& stream) const +{ + switch(_loc) + { + case FULL_IN_1: + stream << '2';//Green + break; + case FULL_OUT_1: + stream << '1';//Bleue + break; + case FULL_ON_1: + stream << '4';//Red + break; + default: + stream << '0'; + } +} + +bool Edge::changeStartNodeWith(Node *otherStartNode) const +{ + if(_start==otherStartNode) + return true; + if(_start->isEqual(*otherStartNode)) + { + ((const_cast<Edge *>(this))->_start)->decrRef();//un-const cast Ok thanks to 2 lines above. + ((const_cast<Edge *>(this))->_start)=otherStartNode; + _start->incrRef(); + return true; + } + return false; +} + +bool Edge::changeStartNodeWithAndKeepTrack(Node *otherStartNode, std::vector<Node *>& track) const +{ + if(_start==otherStartNode) + return true; + if(_start->isEqualAndKeepTrack(*otherStartNode,track)) + { + ((const_cast<Edge *>(this))->_start)->decrRef();//un-const cast Ok thanks to 2 lines above. + ((const_cast<Edge *>(this))->_start)=otherStartNode; + otherStartNode->incrRef(); + return true; + } + return false; +} + +bool Edge::changeEndNodeWith(Node *otherEndNode) const +{ + if(_end==otherEndNode) + return true; + if(_end->isEqual(*otherEndNode)) + { + ((const_cast<Edge *>(this))->_end)->decrRef(); + ((const_cast<Edge *>(this))->_end)=otherEndNode; + _end->incrRef(); + return true; + } + return false; +} + +bool Edge::changeEndNodeWithAndKeepTrack(Node *otherEndNode, std::vector<Node *>& track) const +{ + if(_end==otherEndNode) + return true; + if(_end->isEqualAndKeepTrack(*otherEndNode,track)) + { + ((const_cast<Edge *>(this))->_end)->decrRef(); + ((const_cast<Edge *>(this))->_end)=otherEndNode; + otherEndNode->incrRef(); + return true; + } + return false; +} + +/*! + * Precondition : 'start' and 'end' are lying on the same curve than 'this'. + * Add in vec the sub edge lying on this. + * If 'start' is equal (by pointer) to '_end' and 'end' is equal to '_end' too nothing is added. + * If 'start' is equal (by pointer) to '_start' and 'end' is equal to '_start' too nothing is added. + * If 'start' is equal (by pointer) to '_start' and 'end' is equal to '_end' this is added in vec. + */ +void Edge::addSubEdgeInVector(Node *start, Node *end, ComposedEdge& vec) const +{ + if((start==_start && end==_start) || (start==_end && end==_end)) + return ; + if(start==_start && end==_end) + { + incrRef(); + vec.pushBack(const_cast<Edge *>(this)); + return ; + } + vec.pushBack(buildEdgeLyingOnMe(start,end,true)); +} + +/*! + * Retrieves a vector 'vectOutput' that is normal to 'this'. 'vectOutput' is normalized. + */ +void Edge::getNormalVector(double *vectOutput) const +{ + std::copy((const double *)(*_end),(const double *)(*_end)+2,vectOutput); + std::transform(vectOutput,vectOutput+2,(const double *)(*_start),vectOutput,std::minus<double>()); + double norm=1./Node::norm(vectOutput); + std::transform(vectOutput,vectOutput+2,vectOutput,bind2nd(std::multiplies<double>(),norm)); + double tmp=vectOutput[0]; + vectOutput[0]=vectOutput[1]; + 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); +} + +Edge *Edge::BuildFromXfigLine(std::istream& str) +{ + unsigned char type; + str >> type; + if(type=='2') + return new EdgeLin(str); + else if(type=='5') + return new EdgeArcCircle(str); + else + { + std::cerr << "Unknown line found..."; + return 0; + } +} + +/*! + * \param other The Edge with which we are going to intersect. + * \param commonNode Output. The common nodes found during operation of intersecting. + * \param outVal1 Output filled in case true is returned. It specifies the new or not new edges by which 'this' is replaced after intersecting op. + * \param outVal2 Output filled in case true is returned. It specifies the new or not new edges by which 'other' is replaced after intersecting op. + * return true if the intersection between this. + */ +bool Edge::intersectWith(const Edge *other, MergePoints& commonNode, + ComposedEdge& outVal1, ComposedEdge& outVal2) const +{ + bool ret=true; + Bounds *merge=_bounds.nearlyAmIIntersectingWith(other->getBounds()); + if(!merge) + return false; + delete merge; + merge=0; + EdgeIntersector *intersector=BuildIntersectorWith(this,other); + ret=Intersect(this,other,intersector,merge,commonNode,outVal1,outVal2); + delete intersector; + return ret; +} + +bool Edge::IntersectOverlapped(const Edge *f1, const Edge *f2, EdgeIntersector *intersector, MergePoints& commonNode, + ComposedEdge& outValForF1, ComposedEdge& outValForF2) +{ + bool rev=intersector->haveTheySameDirection(); + Node *f2Start=f2->getNode(rev?START:END); + Node *f2End=f2->getNode(rev?END:START); + TypeOfLocInEdge place1, place2; + intersector->getPlacements(f2Start,f2End,place1,place2,commonNode); + int codeForIntersectionCase=CombineCodes(place1,place2); + return SplitOverlappedEdges(f1,f2,f2Start,f2End,rev,codeForIntersectionCase,outValForF1,outValForF2); +} + +/*! + * Perform 1D linear interpolation. Warning distrib1 and distrib2 are expected to be in ascending mode. + */ +void Edge::Interpolate1DLin(const std::vector<double>& distrib1, const std::vector<double>& distrib2, std::map<int, std::map<int,double> >& result) +{ + int nbOfV1=distrib1.size()-1; + int nbOfV2=distrib2.size()-1; + Node *n1=new Node(0.,0.); Node *n3=new Node(0.,0.); + Node *n2=new Node(0.,0.); Node *n4=new Node(0.,0.); + MergePoints commonNode; + for(int i=0;i<nbOfV1;i++) + { + std::vector<double>::const_iterator iter=find_if(distrib2.begin()+1,distrib2.end(),bind2nd(std::greater_equal<double>(),distrib1[i])); + if(iter!=distrib2.end()) + { + for(int j=(iter-1)-distrib2.begin();j<nbOfV2;j++) + { + if(distrib2[j]<=distrib1[i+1]) + { + EdgeLin *e1=new EdgeLin(n1,n2); EdgeLin *e2=new EdgeLin(n3,n4); + n1->setNewCoords(distrib1[i],0.); n2->setNewCoords(distrib1[i+1],0.); + n3->setNewCoords(distrib2[j],0.); n4->setNewCoords(distrib2[j+1],0.); + ComposedEdge *f1=new ComposedEdge; + ComposedEdge *f2=new ComposedEdge; + SegSegIntersector inters(*e1,*e2); + bool b1,b2; + inters.areOverlappedOrOnlyColinears(0,b1,b2); + if(IntersectOverlapped(e1,e2,&inters,commonNode,*f1,*f2)) + { + result[i][j]=f1->getCommonLengthWith(*f2)/e1->getCurveLength(); + } + ComposedEdge::Delete(f1); ComposedEdge::Delete(f2); + e1->decrRef(); e2->decrRef(); + } + } + } + } + n1->decrRef(); n2->decrRef(); n3->decrRef(); n4->decrRef(); +} + +EdgeIntersector *Edge::BuildIntersectorWith(const Edge *e1, const Edge *e2) +{ + EdgeIntersector *ret=0; + const EdgeLin *tmp1=0; + const EdgeArcCircle *tmp2=0; + unsigned char type1=e1->getTypeOfFunc(); + e1->dynCastFunction(tmp1,tmp2); + unsigned char type2=e2->getTypeOfFunc(); + e2->dynCastFunction(tmp1,tmp2); + type1|=type2; + switch(type1) + { + case 1:// Intersection seg/seg + ret=new SegSegIntersector((const EdgeLin &)(*e1),(const EdgeLin &)(*e2)); + break; + case 5:// Intersection seg/arc of circle + ret=new ArcCSegIntersector(*tmp2,*tmp1,tmp2==e1); + break; + case 4:// Intersection arc/arc of circle + ret=new ArcCArcCIntersector((const EdgeArcCircle &)(*e1),(const EdgeArcCircle &)(*e2)); + break; + default: + //Should never happen + throw Exception("A non managed association of edge has been detected. Go work for intersection computation implementation."); + } + return ret; +} + +/*! + * See Node::applySimilarity to see signification of params. + */ +void Edge::applySimilarity(double xBary, double yBary, double dimChar) +{ + _bounds.applySimilarity(xBary,yBary,dimChar); +} + +void Edge::unApplySimilarity(double xBary, double yBary, double dimChar) +{ + _bounds.unApplySimilarity(xBary,yBary,dimChar); +} + +void Edge::getMiddleOfPointsOriented(const double *p1, const double *p2, double *mid) const +{ + return getMiddleOfPoints(p1, p2, mid); +} + +bool Edge::Intersect(const Edge *f1, const Edge *f2, EdgeIntersector *intersector, const Bounds *whereToFind, MergePoints& commonNode, + ComposedEdge& outValForF1, ComposedEdge& outValForF2) +{ + bool obviousNoIntersection; + bool areOverlapped; + intersector->areOverlappedOrOnlyColinears(whereToFind,obviousNoIntersection,areOverlapped); + if(areOverlapped) + return IntersectOverlapped(f1,f2,intersector,commonNode,outValForF1,outValForF2); + if(obviousNoIntersection) + return false; + std::vector<Node *> newNodes; + bool order; + if(intersector->intersect(whereToFind,newNodes,order,commonNode)) + { + if(newNodes.empty()) + throw Exception("Internal error occured - error in intersector implementation!");// This case should never happen + std::vector<Node *>::iterator iter=newNodes.begin(); + std::vector<Node *>::reverse_iterator iterR=newNodes.rbegin(); + f1->addSubEdgeInVector(f1->getStartNode(),*iter,outValForF1); + f2->addSubEdgeInVector(f2->getStartNode(),order?*iter:*iterR,outValForF2); + for(std::vector<Node *>::iterator iter2=newNodes.begin();iter2!=newNodes.end();iter2++,iterR++) + { + if((iter2+1)==newNodes.end()) + { + f1->addSubEdgeInVector(*iter2,f1->getEndNode(),outValForF1); + (*iter2)->decrRef(); + f2->addSubEdgeInVector(order?*iter2:*iterR,f2->getEndNode(),outValForF2); + } + else + { + f1->addSubEdgeInVector(*iter2,*(iter2+1),outValForF1); + (*iter2)->decrRef(); + f2->addSubEdgeInVector(order?*iter2:*iterR,order?*(iter2+1):*(iterR+1),outValForF2); + } + } + return true; + } + else//no intersection inside whereToFind + return false; +} + +int Edge::CombineCodes(TypeOfLocInEdge code1, TypeOfLocInEdge code2) +{ + int ret=(int)code1; + ret*=OFFSET_FOR_TYPEOFLOCINEDGE; + ret+=(int)code2; + return ret; +} + +/*! + * This method splits e1 and e2 into pieces as much sharable as possible. The precondition to the call of this method + * is that e1 and e2 have been declared as overlapped by corresponding intersector built from e1 and e2 type. + * + * @param nS start node of e2 with the SAME DIRECTION as e1. The pointer nS should be equal to start node of e2 or to its end node. + * @param nE end node of e2 with the SAME DIRECTION as e1. The pointer nE should be equal to start node of e2 or to its end node. + * @param direction is param that specifies if e2 and e1 have same directions (true) or opposed (false). + * @param code is the code returned by method Edge::combineCodes. + */ +bool Edge::SplitOverlappedEdges(const Edge *e1, const Edge *e2, Node *nS, Node *nE, bool direction, int code, + ComposedEdge& outVal1, ComposedEdge& outVal2) +{ + Edge *tmp; + switch(code) + { + case OUT_BEFORE*OFFSET_FOR_TYPEOFLOCINEDGE+START: // OUT_BEFORE - START + case OUT_BEFORE*OFFSET_FOR_TYPEOFLOCINEDGE+OUT_BEFORE: // OUT_BEFORE - OUT_BEFORE + case OUT_AFTER*OFFSET_FOR_TYPEOFLOCINEDGE+OUT_AFTER: // OUT_AFTER - OUT_AFTER + case END*OFFSET_FOR_TYPEOFLOCINEDGE+OUT_AFTER: // END - OUT_AFTER + case END*OFFSET_FOR_TYPEOFLOCINEDGE+START: // END - START + return false; + case INSIDE*OFFSET_FOR_TYPEOFLOCINEDGE+OUT_AFTER: // INSIDE - OUT_AFTER + outVal1.pushBack(e1->buildEdgeLyingOnMe(e1->getStartNode(),nS,true)); + tmp=e1->buildEdgeLyingOnMe(nS,e1->getEndNode()); tmp->incrRef(); + outVal1.pushBack(tmp); + outVal2.resize(2); + outVal2.setValueAt(direction?0:1,tmp,direction); tmp->declareOn(); + outVal2.setValueAt(direction?1:0,e1->buildEdgeLyingOnMe(e1->getEndNode(),nE,direction)); + return true; + case INSIDE*OFFSET_FOR_TYPEOFLOCINEDGE+INSIDE: // INSIDE - INSIDE + { + if(!e2->isIn(e2->getCharactValue(*(e1->getStartNode())))) + { + e2->incrRef(); e2->incrRef(); + outVal1.resize(3); + outVal1.setValueAt(0,e1->buildEdgeLyingOnMe(e1->getStartNode(),nS)); + outVal1.setValueAt(1,const_cast<Edge*>(e2),direction); + outVal1.setValueAt(2,e1->buildEdgeLyingOnMe(nE,e1->getEndNode())); + outVal2.pushBack(const_cast<Edge*>(e2)); e2->declareOn(); + return true; + } + else + { + outVal1.resize(3); + outVal2.resize(3); + tmp=e1->buildEdgeLyingOnMe(e1->getStartNode(),nE); tmp->incrRef(); tmp->declareOn(); + outVal1.setValueAt(0,tmp,true); outVal2.setValueAt(direction?2:0,tmp,direction); + outVal1.setValueAt(1,e1->buildEdgeLyingOnMe(nE,nS)); + tmp=e1->buildEdgeLyingOnMe(nS,e1->getEndNode()); tmp->incrRef(); tmp->declareOn(); + outVal1.setValueAt(2,tmp,true); outVal2.setValueAt(direction?0:2,tmp,direction); + tmp=e1->buildEdgeLyingOnMe(e1->getEndNode(),e1->getStartNode()); + outVal2.setValueAt(1,tmp,direction); + return true; + } + } + case OUT_BEFORE*OFFSET_FOR_TYPEOFLOCINEDGE+INSIDE: // OUT_BEFORE - INSIDE + { + tmp=e1->buildEdgeLyingOnMe(e1->getStartNode(),nE); tmp->incrRef(); + outVal1.pushBack(tmp); + outVal1.pushBack(e1->buildEdgeLyingOnMe(nE,e1->getEndNode())); + outVal2.resize(2); + outVal2.setValueAt(direction?0:1,e1->buildEdgeLyingOnMe(nS,e1->getStartNode(),direction)); + outVal2.setValueAt(direction?1:0,tmp,direction); tmp->declareOn(); + return true; + } + case OUT_BEFORE*OFFSET_FOR_TYPEOFLOCINEDGE+OUT_AFTER: // OUT_BEFORE - OUT_AFTER + { + e1->incrRef(); e1->incrRef(); + outVal1.pushBack(const_cast<Edge*>(e1)); + outVal2.resize(3); + outVal2.setValueAt(direction?0:2,e1->buildEdgeLyingOnMe(nS,e1->getStartNode(),direction)); + outVal2.setValueAt(1,const_cast<Edge*>(e1),direction); e1->declareOn(); + outVal2.setValueAt(direction?2:0,e1->buildEdgeLyingOnMe(e1->getEndNode(),nE,direction)); + return true; + } + case START*OFFSET_FOR_TYPEOFLOCINEDGE+END: // START - END + { + e1->incrRef(); e1->incrRef(); + outVal1.pushBack(const_cast<Edge*>(e1)); + outVal2.pushBack(const_cast<Edge*>(e1),direction); e1->declareOn(); + return true; + } + case START*OFFSET_FOR_TYPEOFLOCINEDGE+OUT_AFTER: // START - OUT_AFTER + { + e1->incrRef(); e1->incrRef(); + outVal1.pushBack(const_cast<Edge*>(e1)); + outVal2.resize(2); + outVal2.setValueAt(direction?0:1,const_cast<Edge*>(e1),direction); e1->declareOn(); + outVal2.setValueAt(direction?1:0,e1->buildEdgeLyingOnMe(e1->getEndNode(),nE,direction)); + return true; + } + case INSIDE*OFFSET_FOR_TYPEOFLOCINEDGE+END: // INSIDE - END + { + e2->incrRef(); e2->incrRef(); + outVal1.pushBack(e1->buildEdgeLyingOnMe(e1->getStartNode(),nS,true)); + outVal1.pushBack(const_cast<Edge*>(e2),direction); + outVal2.pushBack(const_cast<Edge*>(e2)); e2->declareOn(); + return true; + } + case OUT_BEFORE*OFFSET_FOR_TYPEOFLOCINEDGE+END: // OUT_BEFORE - END + { + e1->incrRef(); e1->incrRef(); + outVal1.pushBack(const_cast<Edge*>(e1)); + outVal2.resize(2); + outVal2.setValueAt(direction?0:1,e1->buildEdgeLyingOnMe(nS,e1->getStartNode(),direction)); + outVal2.setValueAt(direction?1:0,const_cast<Edge*>(e1),direction); e1->declareOn(); + return true; + } + case START*OFFSET_FOR_TYPEOFLOCINEDGE+INSIDE: // START - INSIDE + { + e2->incrRef(); e2->incrRef(); + outVal1.pushBack(const_cast<Edge*>(e2),direction); + outVal1.pushBack(e1->buildEdgeLyingOnMe(nE,e1->getEndNode())); + outVal2.pushBack(const_cast<Edge*>(e2)); e2->declareOn(); + return true; + } + case INSIDE*OFFSET_FOR_TYPEOFLOCINEDGE+START: // INSIDE - START + { + outVal1.resize(2); + outVal2.resize(2); + tmp=e1->buildEdgeLyingOnMe(nS,e1->getEndNode()); tmp->incrRef(); tmp->declareOn(); + outVal1.setValueAt(0,e1->buildEdgeLyingOnMe(e1->getStartNode(),nS)); + outVal1.setValueAt(1,tmp); + outVal2.setValueAt(direction?0:1,tmp,direction); + outVal2.setValueAt(direction?1:0,e1->buildEdgeLyingOnMe(e1->getEndNode(),nE,direction)); + return true; + } + case END*OFFSET_FOR_TYPEOFLOCINEDGE+INSIDE: // END - INSIDE + { + outVal1.resize(2); + outVal2.resize(2); + tmp=e1->buildEdgeLyingOnMe(e1->getStartNode(),nE); tmp->incrRef(); tmp->declareOn(); + outVal1.setValueAt(0,tmp); + outVal1.setValueAt(1,e1->buildEdgeLyingOnMe(nE,e1->getEndNode())); + outVal2.setValueAt(direction?0:1,e1->buildEdgeLyingOnMe(e1->getEndNode(),e1->getStartNode(),direction)); + outVal2.setValueAt(direction?1:0,tmp,direction); + return true; + } + default: + throw Exception("Unexpected situation of overlapping edges : internal error occurs ! "); + } +} + +bool Edge::isEqual(const Edge& other) const +{ + return _start->isEqual(*other._start) && _end->isEqual(*other._end); +} + +inline bool eqpair(const std::pair<double,Node *>& p1, const std::pair<double,Node *>& p2) +{ + return fabs(p1.first-p2.first)<QUADRATIC_PLANAR::_precision; +} + +/** + * This method takes in input nodes in \a subNodes (using \a coo) + * + * \param [in,out] subNodes to be sorted + * \return true if a reordering was necessary false if not. + */ +bool Edge::sortSubNodesAbs(const double *coo, std::vector<int>& subNodes) +{ + Bounds b; + b.prepareForAggregation(); + b.aggregate(getBounds()); + double xBary,yBary; + double dimChar(b.getCaracteristicDim()); + b.getBarycenter(xBary,yBary); + applySimilarity(xBary,yBary,dimChar); + _start->applySimilarity(xBary,yBary,dimChar); + _end->applySimilarity(xBary,yBary,dimChar); + // + std::size_t sz(subNodes.size()),i(0); + std::vector< std::pair<double,Node *> > an2(sz); + std::map<Node *, int> m; + for(std::vector<int>::const_iterator it=subNodes.begin();it!=subNodes.end();it++,i++) + { + Node *n(new Node(coo[2*(*it)],coo[2*(*it)+1])); + n->applySimilarity(xBary,yBary,dimChar); + m[n]=*it; + an2[i]=std::pair<double,Node *>(getCharactValueBtw0And1(*n),n); + } + std::sort(an2.begin(),an2.end()); + // + bool ret(false); + for(i=0;i<sz;i++) + { + int id(m[an2[i].second]); + if(id!=subNodes[i]) + { subNodes[i]=id; ret=true; } + } + // + for(std::map<INTERP_KERNEL::Node *,int>::const_iterator it2=m.begin();it2!=m.end();it2++) + (*it2).first->decrRef(); + return ret; +} + +/** + * Sort nodes so that they all lie consecutively on the edge that has been cut. + */ +void Edge::sortIdsAbs(const std::vector<INTERP_KERNEL::Node *>& addNodes, const std::map<INTERP_KERNEL::Node *, int>& mapp1, + const std::map<INTERP_KERNEL::Node *, int>& mapp2, std::vector<int>& edgesThis) +{ + Bounds b; + b.prepareForAggregation(); + b.aggregate(getBounds()); + double xBary,yBary; + double dimChar=b.getCaracteristicDim(); + b.getBarycenter(xBary,yBary); + for(std::vector<Node *>::const_iterator iter=addNodes.begin();iter!=addNodes.end();iter++) + (*iter)->applySimilarity(xBary,yBary,dimChar); + applySimilarity(xBary,yBary,dimChar); + _start->applySimilarity(xBary,yBary,dimChar); + _end->applySimilarity(xBary,yBary,dimChar); + std::size_t sz=addNodes.size(); + std::vector< std::pair<double,Node *> > an2(sz); + for(std::size_t i=0;i<sz;i++) + an2[i]=std::pair<double,Node *>(getCharactValueBtw0And1(*addNodes[i]),addNodes[i]); + std::sort(an2.begin(),an2.end()); + int startId=(*mapp1.find(_start)).second; + int endId=(*mapp1.find(_end)).second; + std::vector<int> tmpp; + std::vector< std::pair<double,Node *> >::const_iterator itend=std::unique(an2.begin(),an2.end(),eqpair); + for(std::vector< std::pair<double,Node *> >::const_iterator it=an2.begin();it!=itend;it++) + { + int idd=(*mapp2.find((*it).second)).second; + if((*it).first<QUADRATIC_PLANAR::_precision) + { + startId=idd; + continue; + } + if((*it).first>1-QUADRATIC_PLANAR::_precision) + { + endId=idd; + continue; + } + tmpp.push_back(idd); + } + std::vector<int> tmpp2(tmpp.size()+2); + tmpp2[0]=startId; + std::copy(tmpp.begin(),tmpp.end(),tmpp2.begin()+1); + tmpp2[tmpp.size()+1]=endId; + std::vector<int>::iterator itt=std::unique(tmpp2.begin(),tmpp2.end()); + tmpp2.resize(std::distance(tmpp2.begin(),itt)); + int nbOfEdges=tmpp2.size()-1; + for(int i=0;i<nbOfEdges;i++) + { + edgesThis.push_back(tmpp2[i]); + edgesThis.push_back(tmpp2[i+1]); + } +} diff --git a/src/medtool/src/INTERP_KERNEL/Geometric2D/InterpKernelGeo2DEdge.hxx b/src/medtool/src/INTERP_KERNEL/Geometric2D/InterpKernelGeo2DEdge.hxx new file mode 100644 index 000000000..006fb2565 --- /dev/null +++ b/src/medtool/src/INTERP_KERNEL/Geometric2D/InterpKernelGeo2DEdge.hxx @@ -0,0 +1,310 @@ +// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 +// 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 __INTERPKERNELGEO2DEDGE_HXX__ +#define __INTERPKERNELGEO2DEDGE_HXX__ + +#include "INTERPKERNELDefines.hxx" +#include "InterpKernelException.hxx" +#include "InterpKernelGeo2DBounds.hxx" +#include "InterpKernelGeo2DNode.hxx" + +#include <iostream> +#include <vector> +#include <list> +#include <map> + +namespace INTERP_KERNEL +{ + typedef enum + { + SEG = 1, + ARC_CIRCLE = 4, + ARC_PARABOL = 8 + } TypeOfFunction; + + typedef enum + { + CIRCLE = 0 , + PARABOL = 1 + } TypeOfMod4QuadEdge; + + typedef enum + { + START = 5, + END = 1, + INSIDE = 2, + OUT_BEFORE = 3, + OUT_AFTER = 4 + } TypeOfLocInEdge; //see Edge::OFFSET_FOR_TYPEOFLOCINEDGE + + typedef enum + { + FULL_IN_1 = 1, + FULL_ON_1 = 4, + FULL_OUT_1 = 2, + FULL_UNKNOWN = 3 + } TypeOfEdgeLocInPolygon; + + class INTERPKERNEL_EXPORT MergePoints + { + public: + MergePoints(); + + //methods called during intersection edge-edge + void start1Replaced(); + void end1Replaced(); + void start1OnStart2(); + void start1OnEnd2(); + void end1OnStart2(); + void end1OnEnd2(); + //methods to be called during aggregation + bool isStart1(unsigned rk) const; + bool isEnd1(unsigned rk) const; + bool isStart2(unsigned rk) const; + bool isEnd2(unsigned rk) const; + void clear(); + unsigned getNumberOfAssociations() const; + void updateMergedNodes(int e1Start, int e1End, int e2Start, int e2End, std::map<int,int>& mergedNodes); + private: + static void PushInMap(int key, int value, std::map<int,int>& mergedNodes); + private: + unsigned _ass1Start1 : 1; + unsigned _ass1End1 : 1; + unsigned _ass1Start2 : 1; + unsigned _ass1End2 : 1; + unsigned _ass2Start1 : 1; + unsigned _ass2End1 : 1; + unsigned _ass2Start2 : 1; + unsigned _ass2End2 : 1; + }; + + class Edge; + class ComposedEdge; + /*! + * This class is in charge to store an intersection point as result of \b non oververlapping edge intersection. + * This class manages the cases when intersect element is one of the extrimities of edge1 and/or edge2. + */ + class INTERPKERNEL_EXPORT IntersectElement + { + public: + IntersectElement(double val1, double val2, bool start1, bool end1, bool start2, bool end2, Node *node, const Edge& e1, const Edge& e2, bool keepOrder); + IntersectElement(const IntersectElement& other); + //! The sort operator is done on the edge 1 \b not edge 2. + bool operator<(const IntersectElement& other) const; + IntersectElement& operator=(const IntersectElement& other); + double getVal1() const { return _chararct_val_for_e1; } + double getVal2() const { return _chararct_val_for_e2; } + //! idem operator< method except that the orientation is done on edge 2 \b not edge 1. + bool isLowerOnOther(const IntersectElement& other) const; + unsigned isOnExtrForAnEdgeAndInForOtherEdge() const; + void attachLoc() { _node->setLoc(_loc_of_node); } + bool isOnMergedExtremity() const; + bool isIncludedByBoth() const; + void setNode(Node *node) const; + void performMerging(MergePoints& commonNode) const; + Node *getNodeOnly() const { return _node; } + Node *getNodeAndReleaseIt() { Node *tmp=_node; _node=0; return tmp; } + ~IntersectElement(); + private: + bool _1S; + bool _1E; + bool _2S; + bool _2E; + double _chararct_val_for_e1; + double _chararct_val_for_e2; + Node *_node; + TypeOfLocInPolygon _loc_of_node; + const Edge& _e1; + const Edge& _e2; + public: + static const unsigned LIMIT_ALONE = 22; + static const unsigned LIMIT_ON = 73; + static const unsigned NO_LIMIT = 19; + }; + + /*! + * This abstract interface specifies all the methods to be overloaded of all possibilities edge-intersection. + */ + class INTERPKERNEL_EXPORT EdgeIntersector + { + protected: + //! All non symetric methods are relative to 'e1'. + EdgeIntersector(const Edge& e1, const Edge& e2):_e1(e1),_e2(e2) { } + public: + virtual ~EdgeIntersector() { } + virtual bool keepOrder() const = 0; + virtual bool areColinears() const = 0; + //!to call only if 'areOverlapped' have been set to true when areOverlappedOrOnlyColinears was called + virtual bool haveTheySameDirection() const = 0; + //!to call only if 'areOverlapped' have been set to true when areOverlappedOrOnlyColinears was called + virtual void getPlacements(Node *start, Node *end, TypeOfLocInEdge& whereStart, TypeOfLocInEdge& whereEnd, MergePoints& commonNode) const = 0; + //! When true is returned, newNodes should contains at least 1 element. All merging nodes betw _e1 and _e2 extremities must be done. + bool intersect(const Bounds *whereToFind, std::vector<Node *>& newNodes, bool& order, MergePoints& commonNode); + //! Should be called only once per association. + virtual void areOverlappedOrOnlyColinears(const Bounds *whereToFind, bool& obviousNoIntersection, bool& areOverlapped) = 0; + //! The size of returned vector is equal to number of potential intersections point. The values are so that their are interpretable by virtual Edge::isIn method. + virtual std::list< IntersectElement > getIntersectionsCharacteristicVal() const = 0; + protected: + void obviousCaseForCurvAbscisse(Node *node, TypeOfLocInEdge& where, MergePoints& commonNode, bool& obvious) const; + protected: + const Edge& _e1; + const Edge& _e2; + }; + + class INTERPKERNEL_EXPORT SameTypeEdgeIntersector : public EdgeIntersector + { + protected: + SameTypeEdgeIntersector(const Edge& e1, const Edge& e2):EdgeIntersector(e1,e2) { } + bool keepOrder() const { return true; } + }; + + class INTERPKERNEL_EXPORT CrossTypeEdgeIntersector : public EdgeIntersector + { + protected: + CrossTypeEdgeIntersector(const Edge& e1, const Edge& e2, bool reverse):EdgeIntersector(e1,e2),_reverse(reverse) { } + bool keepOrder() const { return _reverse; } + bool haveTheySameDirection() const { throw Exception("Cross type intersector is not supposed to deal with overlapped in cross type."); } + const Edge *myE1() { if(_reverse) return &_e1; else return &_e2; } + const Edge *myE2() { if(_reverse) return &_e2; else return &_e1; } + protected: + //! boolean to inform intersector that unsymetrics treatments reverse of e1 and e2 should be done. + bool _reverse; + }; + + class EdgeLin; + class EdgeInfLin; + class EdgeArcCircle; + + /*! + * Deal with an oriented edge of a polygon. + * An Edge is defined with a start node, an end node and an equation of 1D curve. + * All other attributes are mutable because they don't impact these 3 invariant attributes. + * To be exact start and end nodes can change (address) but their location remain + * the same (at precision). + */ + class INTERPKERNEL_EXPORT Edge + { + public: + Edge(Node *start, Node *end, bool direction=true):_cnt(1),_loc(FULL_UNKNOWN) { if(direction) { _start=start; _end=end; } else { _start=end; _end=start; } _start->incrRef(); _end->incrRef(); } + Edge(double sX, double sY, double eX, double eY); + TypeOfEdgeLocInPolygon getLoc() const { return _loc; } + void incrRef() const { _cnt++; } + bool decrRef(); + void initLocs() const { _loc=FULL_UNKNOWN; _start->initLocs(); _end->initLocs(); } + void declareOn() const; + void declareIn() const; + void declareOut() const; + void initHitStatus() const { _hit=false; } + bool getHitStatus() const { return _hit; } + void hitMeAlone(double xBary, double yBary, double dimChar) { _hit=true; applySimilarity(xBary,yBary,dimChar); } + void unHitMeAlone(double xBary, double yBary, double dimChar) { _hit=true; unApplySimilarity(xBary,yBary,dimChar); } + void hitMeAfter(double xBary, double yBary, double dimChar) { if(!_hit) hitMeAlone(xBary,yBary,dimChar); } + void unHitMeAfter(double xBary, double yBary, double dimChar) { if(!_hit) unHitMeAlone(xBary,yBary,dimChar); } + const Bounds& getBounds() const { return _bounds; } + void fillXfigStreamForLoc(std::ostream& stream) const; + Node *getNode(TypeOfLocInEdge where) const { if(where==START) return _start; else if(where==END) return _end; else return 0; } + Node *getStartNode() const { return _start; } + Node *getEndNode() const { return _end; } + void setEndNodeWithoutChange(Node *newEnd); + void setStartNodeWithoutChange(Node *newStart); + bool changeStartNodeWith(Node *otherStartNode) const; + bool changeStartNodeWithAndKeepTrack(Node *otherStartNode, std::vector<Node *>& track) const; + bool changeEndNodeWith(Node *otherEndNode) const; + bool changeEndNodeWithAndKeepTrack(Node *otherEndNode, std::vector<Node *>& track) const; + void addSubEdgeInVector(Node *start, Node *end, ComposedEdge& vec) const; + void getNormalVector(double *vectOutput) const; + static EdgeIntersector *BuildIntersectorWith(const Edge *e1, const Edge *e2); + static Edge *BuildFromXfigLine(std::istream& str); + static Edge *BuildEdgeFrom(Node *start, Node *end); + template<TypeOfMod4QuadEdge type> + 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; + //! apply a similiraty transformation on 'this' + virtual void applySimilarity(double xBary, double yBary, double dimChar); + //! apply the inverse similiraty transformation on 'this' + virtual void unApplySimilarity(double xBary, double yBary, double dimChar); + //! return the length of arc. Value is always > 0. ! + virtual double getCurveLength() const = 0; + virtual void getBarycenter(double *bary) const = 0; + virtual void getBarycenterOfZone(double *bary) const = 0; + //! return the middle of two points + virtual void getMiddleOfPoints(const double *p1, const double *p2, double *mid) const = 0; + //! return the middle of two points respecting the orientation defined by this (relevant for arc of circle). By default same as getMiddleOfPoints() + virtual void getMiddleOfPointsOriented(const double *p1, const double *p2, double *mid) const; + //! Retrieves a point that is owning to this, well placed for IN/OUT detection of this. Typically midlle of this is returned. + virtual Node *buildRepresentantOfMySelf() const = 0; + //! Given a magnitude specified by sub-type returns if in or not. See getCharactValue method. + virtual bool isIn(double characterVal) const = 0; + //! With the same magnitude as defined in 'isIn' method perform a compararison. Precondition : val1 and val2 are different and exactly INSIDE this. + virtual bool isLower(double val1, double val2) const = 0; + //! node is expected to lay on 'this'. It returns a characteristic magnitude usable by isIn method. + virtual double getCharactValue(const Node& node) const = 0; + //! node is expected to lay on 'this'. It returns a characteristic magnitude between 0 and 1. + virtual double getCharactValueBtw0And1(const Node& node) const = 0; + //! retrieves the distance to this : The min distance from pt and any point of this. + virtual double getDistanceToPoint(const double *pt) const = 0; + //! return if node with coords 'coordOfNode' is on this (with precision). + virtual bool isNodeLyingOn(const double *coordOfNode) const = 0; + virtual TypeOfFunction getTypeOfFunc() const = 0; + virtual void dynCastFunction(const EdgeLin * &seg, + const EdgeArcCircle * &arcSeg) const = 0; + bool intersectWith(const Edge *other, MergePoints& commonNode, + ComposedEdge& outVal1, ComposedEdge& outVal2) const; + static bool IntersectOverlapped(const Edge *f1, const Edge *f2, EdgeIntersector *intersector, MergePoints& commonNode, + ComposedEdge& outValForF1, ComposedEdge& outValForF2); + static void Interpolate1DLin(const std::vector<double>& distrib1, const std::vector<double>& distrib2, + std::map<int, std::map<int,double> >& result); + virtual void dumpInXfigFile(std::ostream& stream, bool direction, int resolution, const Bounds& box) const = 0; + bool isEqual(const Edge& other) const; + public: + bool sortSubNodesAbs(const double *coo, std::vector<int>& subNodes); + void sortIdsAbs(const std::vector<INTERP_KERNEL::Node *>& addNodes, const std::map<INTERP_KERNEL::Node *, int>& mapp1, const std::map<INTERP_KERNEL::Node *, int>& mapp2, std::vector<int>& edgesThis); + virtual void fillGlobalInfoAbs(bool direction, const std::map<INTERP_KERNEL::Node *,int>& mapThis, const std::map<INTERP_KERNEL::Node *,int>& mapOther, int offset1, int offset2, double fact, double baryX, double baryY, + std::vector<int>& edgesThis, std::vector<double>& addCoo, std::map<INTERP_KERNEL::Node *,int> mapAddCoo) const = 0; + virtual void fillGlobalInfoAbs2(const std::map<INTERP_KERNEL::Node *,int>& mapThis, const std::map<INTERP_KERNEL::Node *,int>& mapOther, int offset1, int offset2, double fact, double baryX, double baryY, + std::vector<int>& edgesOther, std::vector<double>& addCoo, std::map<INTERP_KERNEL::Node *,int>& mapAddCoo) const = 0; + virtual Edge *buildEdgeLyingOnMe(Node *start, Node *end, bool direction=true) const = 0; + protected: + Edge():_cnt(1),_loc(FULL_UNKNOWN),_start(0),_end(0) { } + virtual ~Edge(); + static int CombineCodes(TypeOfLocInEdge code1, TypeOfLocInEdge code2); + static bool Intersect(const Edge *f1, const Edge *f2, EdgeIntersector *intersector, const Bounds *whereToFind, MergePoints& commonNode, + ComposedEdge& outValForF1, ComposedEdge& outValForF2); + //! The code 'code' is built by method combineCodes + static bool SplitOverlappedEdges(const Edge *e1, const Edge *e2, Node *nS, Node *nE, bool direction, int code, + ComposedEdge& outVal1, ComposedEdge& outVal2); + protected: + mutable bool _hit; + mutable unsigned char _cnt; + mutable TypeOfEdgeLocInPolygon _loc; + Bounds _bounds; + Node *_start; + Node *_end; + protected: + //In relation with max possible value of TypeOfLocInEdge. + static const int OFFSET_FOR_TYPEOFLOCINEDGE = 8; + }; +} + +#endif diff --git a/src/medtool/src/INTERP_KERNEL/Geometric2D/InterpKernelGeo2DEdge.txx b/src/medtool/src/INTERP_KERNEL/Geometric2D/InterpKernelGeo2DEdge.txx new file mode 100644 index 000000000..c76b18134 --- /dev/null +++ b/src/medtool/src/INTERP_KERNEL/Geometric2D/InterpKernelGeo2DEdge.txx @@ -0,0 +1,31 @@ +// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 +// 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 __INTERPKERNELGEO2DEDGE_TXX__ +#define __INTERPKERNELGEO2DEDGE_TXX__ + +#include "InterpKernelGeo2DEdgeArcCircle.hxx" + +template<INTERP_KERNEL::TypeOfMod4QuadEdge type> +INTERP_KERNEL::Edge *INTERP_KERNEL::Edge::BuildEdgeFrom(Node *start, Node *middle, Node *end) +{ + return new INTERP_KERNEL::EdgeArcCircle(start,middle,end); +} + +#endif diff --git a/src/medtool/src/INTERP_KERNEL/Geometric2D/InterpKernelGeo2DEdgeArcCircle.cxx b/src/medtool/src/INTERP_KERNEL/Geometric2D/InterpKernelGeo2DEdgeArcCircle.cxx new file mode 100644 index 000000000..491ff1578 --- /dev/null +++ b/src/medtool/src/INTERP_KERNEL/Geometric2D/InterpKernelGeo2DEdgeArcCircle.cxx @@ -0,0 +1,841 @@ +// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 +// 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 "InterpKernelGeo2DEdgeArcCircle.hxx" +#include "InterpKernelGeo2DEdgeLin.hxx" +#include "InterpKernelException.hxx" +#include "InterpKernelGeo2DNode.hxx" +#include "NormalizedUnstructuredMesh.hxx" + +#include <sstream> +#include <algorithm> + +using namespace INTERP_KERNEL; + +ArcCArcCIntersector::ArcCArcCIntersector(const EdgeArcCircle& e1, const EdgeArcCircle& e2):SameTypeEdgeIntersector(e1,e2),_dist(0.) +{ +} + +bool ArcCArcCIntersector::haveTheySameDirection() const +{ + return (getE1().getAngle()>0. && getE2().getAngle()>0.) || (getE1().getAngle()<0. && getE2().getAngle()<0.); +} + +bool ArcCArcCIntersector::areColinears() const +{ + double radiusL,radiusB; + double centerL[2],centerB[2]; + double tmp,cst; + return internalAreColinears(getE1(),getE2(),tmp,cst,radiusL,centerL,radiusB,centerB); +} + +/*! + * Precondition 'start' and 'end' are on the same curve than this. + */ +void ArcCArcCIntersector::getPlacements(Node *start, Node *end, TypeOfLocInEdge& whereStart, TypeOfLocInEdge& whereEnd, MergePoints& commonNode) const +{ + bool obvious1,obvious2; + obviousCaseForCurvAbscisse(start,whereStart,commonNode,obvious1); + obviousCaseForCurvAbscisse(end,whereEnd,commonNode,obvious2); + if(obvious1 && obvious2) + return ; + double angleInRadStart=getAngle(start); + double angleInRadEnd=getAngle(end); + if(obvious1 || obvious2) + { + if(obvious1) + { + if(EdgeArcCircle::IsIn2Pi(getE1().getAngle0(),getE1().getAngle(),angleInRadEnd)) + whereEnd=INSIDE; + else + whereEnd=OUT_AFTER; + return ; + } + else + { + if(EdgeArcCircle::IsIn2Pi(getE1().getAngle0(),getE1().getAngle(),angleInRadStart)) + whereStart=INSIDE; + else + whereStart=OUT_BEFORE; + return ; + } + } + if(EdgeArcCircle::IsIn2Pi(getE1().getAngle0(),getE1().getAngle(),angleInRadStart)) + { + whereStart=INSIDE; + if(EdgeArcCircle::IsIn2Pi(getE1().getAngle0(),getE1().getAngle(),angleInRadEnd)) + whereEnd=INSIDE; + else + whereEnd=OUT_AFTER; + } + else + {//we are out in start. + if(EdgeArcCircle::IsIn2Pi(getE1().getAngle0(),getE1().getAngle(),angleInRadEnd)) + { + whereStart=OUT_BEFORE; + whereEnd=INSIDE; + } + else + { + if(EdgeArcCircle::IsIn2Pi(getE2().getAngle0(),getE2().getAngle(),getE1().getAngle0())) + {//_e2 contains stictly _e1 + whereStart=OUT_BEFORE; + whereEnd=OUT_AFTER; + } + else + {//_e2 is outside from _e1 + whereStart=OUT_BEFORE; + whereEnd=OUT_BEFORE; + } + } + } +} + +/*! + * Return angle between ]-Pi;Pi[ + */ +double ArcCArcCIntersector::getAngle(Node *node) const +{ + return EdgeArcCircle::GetAbsoluteAngleOfNormalizedVect(((*node)[0]-getE1().getCenter()[0])/getE1().getRadius(),((*node)[1]-getE1().getCenter()[1])/getE1().getRadius()); +} + +bool ArcCArcCIntersector::internalAreColinears(const EdgeArcCircle& a1, const EdgeArcCircle& a2, double& distBetweenCenters, double& cst, + double& radiusL, double centerL[2], double& radiusB, double centerB[2]) +{ + double lgth1=fabs(a1.getAngle()*a1.getRadius()); + double lgth2=fabs(a2.getAngle()*a2.getRadius()); + if(lgth1<lgth2) + {//a1 is the little one ('L') and a2 the big one ('B') + a1.getCenter(centerL); radiusL=a1.getRadius(); + a2.getCenter(centerB); radiusB=a2.getRadius(); + } + else + { + a2.getCenter(centerL); radiusL=a2.getRadius(); + a1.getCenter(centerB); radiusB=a1.getRadius(); + } + // dividing from the begining by radiusB^2 to keep precision + distBetweenCenters=Node::distanceBtw2PtSq(centerL,centerB); + cst=distBetweenCenters/(radiusB*radiusB); + cst+=radiusL*radiusL/(radiusB*radiusB); + return Node::areDoubleEqualsWP(cst,1.,2.); +} + +bool ArcCArcCIntersector::areArcsOverlapped(const EdgeArcCircle& a1, const EdgeArcCircle& a2) +{ + double radiusL,radiusB; + double centerL[2],centerB[2]; + double tmp(0.),cst(0.); + if(!internalAreColinears(a1,a2,tmp,cst,radiusL,centerL,radiusB,centerB)) + return false; + // + double angle0L,angleL; + Bounds *merge=a1.getBounds().nearlyAmIIntersectingWith(a2.getBounds()); + merge->getInterceptedArc(centerL,radiusL,angle0L,angleL); + delete merge; + // + tmp=sqrt(tmp); + if(Node::areDoubleEqualsWP(tmp,0.,1/(10*std::max(radiusL,radiusB)))) + return Node::areDoubleEquals(radiusL,radiusB); + double phi=EdgeArcCircle::GetAbsoluteAngleOfNormalizedVect((centerL[0]-centerB[0])/tmp,(centerL[1]-centerB[1])/tmp); + double cst2=2*radiusL*tmp/(radiusB*radiusB); + double cmpContainer[4]; + int sizeOfCmpContainer=2; + cmpContainer[0]=cst+cst2*cos(phi-angle0L); + cmpContainer[1]=cst+cst2*cos(phi-angle0L+angleL); + double a=EdgeArcCircle::NormalizeAngle(phi-angle0L); + if(EdgeArcCircle::IsIn2Pi(angle0L,angleL,a)) + cmpContainer[sizeOfCmpContainer++]=cst+cst2; + a=EdgeArcCircle::NormalizeAngle(phi-angle0L+M_PI); + if(EdgeArcCircle::IsIn2Pi(angle0L,angleL,a)) + cmpContainer[sizeOfCmpContainer++]=cst-cst2; + a=*std::max_element(cmpContainer,cmpContainer+sizeOfCmpContainer); + return Node::areDoubleEqualsWP(a,1.,2.); +} + +void ArcCArcCIntersector::areOverlappedOrOnlyColinears(const Bounds *whereToFind, bool& obviousNoIntersection, bool& areOverlapped) +{ + _dist=Node::distanceBtw2Pt(getE1().getCenter(),getE2().getCenter()); + double radius1=getE1().getRadius(); double radius2=getE2().getRadius(); + if(_dist>radius1+radius2+QUADRATIC_PLANAR::_precision || _dist+std::min(radius1,radius2)+QUADRATIC_PLANAR::_precision<std::max(radius1,radius2)) + { + obviousNoIntersection=true; + areOverlapped=false; + return ; + } + if(areArcsOverlapped(getE1(),getE2()))//(Node::areDoubleEquals(_dist,0.) && Node::areDoubleEquals(radius1,radius2)) + { + obviousNoIntersection=false; + areOverlapped=true; + } + else + { + obviousNoIntersection=false; + areOverlapped=false; + } +} + +std::list< IntersectElement > ArcCArcCIntersector::getIntersectionsCharacteristicVal() const +{ + std::list< IntersectElement > ret; + const double *center1=getE1().getCenter(); + const double *center2=getE2().getCenter(); + double radius1=getE1().getRadius(); double radius2=getE2().getRadius(); + double d1_1=(_dist*_dist-radius2*radius2+radius1*radius1)/(2.*_dist); + double u[2];//u is normalized vector from center1 to center2. + u[0]=(center2[0]-center1[0])/_dist; u[1]=(center2[1]-center1[1])/_dist; + double d1_1y=EdgeArcCircle::SafeSqrt(radius1*radius1-d1_1*d1_1); + double angleE1=EdgeArcCircle::NormalizeAngle(getE1().getAngle0()+getE1().getAngle()); + double angleE2=EdgeArcCircle::NormalizeAngle(getE2().getAngle0()+getE2().getAngle()); + if(!Node::areDoubleEquals(d1_1y,0)) + { + //2 intersections + double v1[2],v2[2]; + v1[0]=u[0]*d1_1-u[1]*d1_1y; v1[1]=u[1]*d1_1+u[0]*d1_1y; + v2[0]=u[0]*d1_1+u[1]*d1_1y; v2[1]=u[1]*d1_1-u[0]*d1_1y; + Node *node1=new Node(center1[0]+v1[0],center1[1]+v1[1]); node1->declareOn(); + Node *node2=new Node(center1[0]+v2[0],center1[1]+v2[1]); node2->declareOn(); + double angle1_1=EdgeArcCircle::GetAbsoluteAngleOfNormalizedVect(v1[0]/radius1,v1[1]/radius1); + double angle2_1=EdgeArcCircle::GetAbsoluteAngleOfNormalizedVect(v2[0]/radius1,v2[1]/radius1); + double v3[2],v4[2]; + v3[0]=center1[0]-center2[0]+v1[0]; v3[1]=center1[1]-center2[1]+v1[1]; + v4[0]=center1[0]-center2[0]+v2[0]; v4[1]=center1[1]-center2[1]+v2[1]; + double angle1_2=EdgeArcCircle::GetAbsoluteAngleOfNormalizedVect(v3[0]/radius2,v3[1]/radius2); + double angle2_2=EdgeArcCircle::GetAbsoluteAngleOfNormalizedVect(v4[0]/radius2,v4[1]/radius2); + // + bool e1_1S=Node::areDoubleEqualsWP(angle1_1,getE1().getAngle0(),radius1); + bool e1_1E=Node::areDoubleEqualsWP(angle1_1,angleE1,radius1); + bool e1_2S=Node::areDoubleEqualsWP(angle1_2,getE2().getAngle0(),radius1); + bool e1_2E=Node::areDoubleEqualsWP(angle1_2,angleE2,radius1); + // + bool e2_1S=Node::areDoubleEqualsWP(angle2_1,getE1().getAngle0(),radius2); + bool e2_1E=Node::areDoubleEqualsWP(angle2_1,angleE1,radius2); + bool e2_2S=Node::areDoubleEqualsWP(angle2_2,getE2().getAngle0(),radius2); + bool e2_2E=Node::areDoubleEqualsWP(angle2_2,angleE2,radius2); + ret.push_back(IntersectElement(angle1_1,angle1_2,e1_1S,e1_1E,e1_2S,e1_2E,node1,_e1,_e2,keepOrder())); + ret.push_back(IntersectElement(angle2_1,angle2_2,e2_1S,e2_1E,e2_2S,e2_2E,node2,_e1,_e2,keepOrder())); + } + else + { + //tangent intersection + double v1[2],v2[2]; + v1[0]=d1_1*u[0]; v1[1]=d1_1*u[1]; + v2[0]=center1[0]-center2[0]+v1[0]; v2[1]=center1[1]-center2[1]+v1[1]; + double angle0_1=EdgeArcCircle::GetAbsoluteAngleOfNormalizedVect(v1[0]/radius1,v1[1]/radius1); + double angle0_2=EdgeArcCircle::GetAbsoluteAngleOfNormalizedVect(v2[0]/radius2,v2[1]/radius2); + bool e0_1S=Node::areDoubleEqualsWP(angle0_1,getE1().getAngle0(),radius1); + bool e0_1E=Node::areDoubleEqualsWP(angle0_1,angleE1,radius1); + bool e0_2S=Node::areDoubleEqualsWP(angle0_2,getE2().getAngle0(),radius2); + bool e0_2E=Node::areDoubleEqualsWP(angle0_2,angleE2,radius2); + Node *node=new Node(center1[0]+d1_1*u[0],center1[1]+d1_1*u[1]); node->declareOnTangent(); + ret.push_back(IntersectElement(angle0_1,angle0_2,e0_1S,e0_1E,e0_2S,e0_2E,node,_e1,_e2,keepOrder())); + } + return ret; +} +/*double angle0_2; + double signDeltaAngle2; + double d1_2; + if(u[1]<0.) + angle0_1=-angle0_1; + if(d1_1>=0.) + { + if(_dist>radius1) + { + angle0_2=angle0_1+M_PI; + signDeltaAngle2=-1.; + } + else + { + angle0_2=angle0_1; + signDeltaAngle2=1.; + } + } + else + { + angle0_1+=M_PI; + angle0_2=angle0_1; + signDeltaAngle2=1.; + } + angle0_1=NormalizeAngle(angle0_1); + angle0_2=NormalizeAngle(angle0_2); + double angleE1=NormalizeAngle(getE1().getAngle0()+getE1().getAngle()); + double angleE2=NormalizeAngle(getE2().getAngle0()+getE2().getAngle()); + if(!(Node::areDoubleEquals(d1_1,radius1) || Node::areDoubleEquals(d1_1,-radius1)) ) + { + //2 intersections + double deltaAngle1=EdgeArcCircle::SafeAcos(fabs(d1_1)/radius1); //owns to 0;Pi/2 by construction + double deltaAngle2=EdgeArcCircle::SafeAcos(fabs(d1_2)/radius2); //owns to 0;Pi/2 by construction + double angle1_1=NormalizeAngle(angle0_1+deltaAngle1);// Intersection 1 seen for _e1 + double angle2_1=NormalizeAngle(angle0_1-deltaAngle1);// Intersection 2 seen for _e1 + double angle1_2=NormalizeAngle(angle0_2+signDeltaAngle2*deltaAngle2);// Intersection 1 seen for _e2 + double angle2_2=NormalizeAngle(angle0_2-signDeltaAngle2*deltaAngle2);// Intersection 2 seen for _e2 + // + bool e1_1S=Node::areDoubleEqualsWP(angle1_1,getE1().getAngle0(),radius1); + bool e1_1E=Node::areDoubleEqualsWP(angle1_1,angleE1,radius1); + bool e1_2S=Node::areDoubleEqualsWP(angle1_2,getE2().getAngle0(),radius1); + bool e1_2E=Node::areDoubleEqualsWP(angle1_2,angleE2,radius1); + // + bool e2_1S=Node::areDoubleEqualsWP(angle2_1,getE1().getAngle0(),radius2); + bool e2_1E=Node::areDoubleEqualsWP(angle2_1,angleE1,radius2); + bool e2_2S=Node::areDoubleEqualsWP(angle2_2,getE2().getAngle0(),radius2); + bool e2_2E=Node::areDoubleEqualsWP(angle2_2,angleE2,radius2); + Node *node1=new Node(center1[0]+radius1*cos(angle1_1),center1[0]+radius1*sin(angle1_1)); node1->declareOn(); + Node *node2=new Node(center1[0]+radius1*cos(angle2_1),center1[0]+radius1*sin(angle2_1)); node2->declareOn(); + ret.push_back(IntersectElement(angle1_1,angle1_2,e1_1S,e1_1E,e1_2S,e1_2E,node1,_e1,_e2,keepOrder())); + ret.push_back(IntersectElement(angle2_1,angle2_2,e2_1S,e2_1E,e2_2S,e2_2E,node2,_e1,_e2,keepOrder())); + } + else + //tangent intersection + { + bool e0_1S=Node::areDoubleEqualsWP(angle0_1,getE1().getAngle0(),radius1); + bool e0_1E=Node::areDoubleEqualsWP(angle0_1,angleE1,radius1); + bool e0_2S=Node::areDoubleEqualsWP(angle0_2,getE2().getAngle0(),radius2); + bool e0_2E=Node::areDoubleEqualsWP(angle0_2,angleE2,radius2); + Node *node=new Node(center1[0]+radius1*cos(angle0_1),center1[0]+radius1*sin(angle0_1)); node->declareOnTangent(); + ret.push_back(IntersectElement(angle0_1,angle0_2,e0_1S,e0_1E,e0_2S,e0_2E,node,_e1,_e2,keepOrder())); + } + return ret;*/ + +ArcCSegIntersector::ArcCSegIntersector(const EdgeArcCircle& e1, const EdgeLin& e2, bool reverse):CrossTypeEdgeIntersector(e1,e2,reverse) +{ +} + +void ArcCSegIntersector::areOverlappedOrOnlyColinears(const Bounds *whereToFind, bool& obviousNoIntersection, bool& areOverlapped) +{ + areOverlapped=false;//No overlapping by construction + const double *center=getE1().getCenter(); + _dx=(*(_e2.getEndNode()))[0]-(*(_e2.getStartNode()))[0]; + _dy=(*(_e2.getEndNode()))[1]-(*(_e2.getStartNode()))[1]; + _drSq=_dx*_dx+_dy*_dy; + _cross= + ((*(_e2.getStartNode()))[0]-center[0])*((*(_e2.getEndNode()))[1]-center[1])- + ((*(_e2.getStartNode()))[1]-center[1])*((*(_e2.getEndNode()))[0]-center[0]); + _determinant=getE1().getRadius()*getE1().getRadius()/_drSq-_cross*_cross/(_drSq*_drSq); + if(_determinant>-2*QUADRATIC_PLANAR::_precision)//QUADRATIC_PLANAR::_precision*QUADRATIC_PLANAR::_precision*_drSq*_drSq/(2.*_dx*_dx)) + obviousNoIntersection=false; + else + obviousNoIntersection=true; +} + +/*! + * By construction, no chance that an arc of circle and line to be colinear. + */ +bool ArcCSegIntersector::areColinears() const +{ + return false; +} + +void ArcCSegIntersector::getPlacements(Node *start, Node *end, TypeOfLocInEdge& whereStart, TypeOfLocInEdge& whereEnd, MergePoints& commonNode) const +{ + throw Exception("Internal error. Should never been called : no overlapping possible between arc of circle and a segment."); +} + +std::list< IntersectElement > ArcCSegIntersector::getIntersectionsCharacteristicVal() const +{ + std::list< IntersectElement > ret; + const double *center=getE1().getCenter(); + if(!(fabs(_determinant)<(2.*QUADRATIC_PLANAR::_precision)))//QUADRATIC_PLANAR::_precision*QUADRATIC_PLANAR::_precision*_drSq*_drSq/(2.*_dx*_dx)) + { + double determinant=EdgeArcCircle::SafeSqrt(_determinant); + double x1=(_cross*_dy/_drSq+Node::sign(_dy)*_dx*determinant)+center[0]; + double y1=(-_cross*_dx/_drSq+fabs(_dy)*determinant)+center[1]; + Node *intersect1=new Node(x1,y1); intersect1->declareOn(); + bool i1_1S=_e1.getStartNode()->isEqual(*intersect1); + bool i1_1E=_e1.getEndNode()->isEqual(*intersect1); + bool i1_2S=_e2.getStartNode()->isEqual(*intersect1); + bool i1_2E=_e2.getEndNode()->isEqual(*intersect1); + ret.push_back(IntersectElement(getE1().getCharactValue(*intersect1),getE2().getCharactValue(*intersect1),i1_1S,i1_1E,i1_2S,i1_2E,intersect1,_e1,_e2,keepOrder())); + // + double x2=(_cross*_dy/_drSq-Node::sign(_dy)*_dx*determinant)+center[0]; + double y2=(-_cross*_dx/_drSq-fabs(_dy)*determinant)+center[1]; + Node *intersect2=new Node(x2,y2); intersect2->declareOn(); + bool i2_1S=_e1.getStartNode()->isEqual(*intersect2); + bool i2_1E=_e1.getEndNode()->isEqual(*intersect2); + bool i2_2S=_e2.getStartNode()->isEqual(*intersect2); + bool i2_2E=_e2.getEndNode()->isEqual(*intersect2); + ret.push_back(IntersectElement(getE1().getCharactValue(*intersect2),getE2().getCharactValue(*intersect2),i2_1S,i2_1E,i2_2S,i2_2E,intersect2,_e1,_e2,keepOrder())); + } + else//tangent intersection + { + double x=(_cross*_dy)/_drSq+center[0]; + double y=(-_cross*_dx)/_drSq+center[1]; + Node *intersect3=new Node(x,y); intersect3->declareOnTangent(); + bool i_1S=_e1.getStartNode()->isEqual(*intersect3); + bool i_1E=_e1.getEndNode()->isEqual(*intersect3); + bool i_2S=_e2.getStartNode()->isEqual(*intersect3); + bool i_2E=_e2.getEndNode()->isEqual(*intersect3); + ret.push_back(IntersectElement(_e1.getCharactValue(*intersect3),_e2.getCharactValue(*intersect3),i_1S,i_1E,i_2S,i_2E,intersect3,_e1,_e2,keepOrder())); + } + return ret; +} + +EdgeArcCircle::EdgeArcCircle(std::istream& lineInXfig) +{ + const unsigned NB_OF_SKIP_FIELDS=15; + std::string tmpS; + for(unsigned i=0;i<NB_OF_SKIP_FIELDS;i++) + lineInXfig >> tmpS; + _start=new Node(lineInXfig); + Node *middle=new Node(lineInXfig); + _end=new Node(lineInXfig); + GetArcOfCirclePassingThru(*_start,*middle,*_end,_center,_radius,_angle,_angle0); + middle->decrRef(); + updateBounds(); +} + +EdgeArcCircle::EdgeArcCircle(Node *start, Node *middle, Node *end, bool direction):Edge(start,end, direction) +{ + GetArcOfCirclePassingThru(*_start,*middle,*_end,_center,_radius,_angle,_angle0); + updateBounds(); +} + +EdgeArcCircle::EdgeArcCircle(double sX, double sY, double mX, double mY, double eX, double eY):Edge(sX,sY,eX,eY) +{ + double middle[2]; middle[0]=mX; middle[1]=mY; + GetArcOfCirclePassingThru(*_start,middle,*_end,_center,_radius,_angle,_angle0); + updateBounds(); +} + +/*! + * @param angle0 in ]-Pi;Pi[ + * @param deltaAngle in ]-2.*Pi;2.*Pi[ + */ +EdgeArcCircle::EdgeArcCircle(Node *start, Node *end, const double *center, double radius, double angle0, double deltaAngle, bool direction):Edge(start,end,direction),_angle(deltaAngle), + _angle0(angle0),_radius(radius) +{ + _center[0]=center[0]; + _center[1]=center[1]; + updateBounds(); +} + +void EdgeArcCircle::changeMiddle(Node *newMiddle) +{ + GetArcOfCirclePassingThru(*_start,*newMiddle,*_end,_center,_radius,_angle,_angle0); + updateBounds(); +} + +Edge *EdgeArcCircle::buildEdgeLyingOnMe(Node *start, Node *end, bool direction) const +{ + double sx=((*start)[0]-_center[0])/_radius; + double sy=((*start)[1]-_center[1])/_radius; + double ex=((*end)[0]-_center[0])/_radius; + double ey=((*end)[1]-_center[1])/_radius; + double angle0=GetAbsoluteAngleOfNormalizedVect(direction?sx:ex,direction?sy:ey); + double deltaAngle=GetAbsoluteAngleOfNormalizedVect(sx*ex+sy*ey,sx*ey-sy*ex); + if(deltaAngle>0. && _angle<0.) + deltaAngle-=2.*M_PI; + else if(deltaAngle<0. && _angle>0.) + deltaAngle+=2.*M_PI; + deltaAngle=direction?deltaAngle:-deltaAngle; + return new EdgeArcCircle(start,end,_center,_radius,angle0,deltaAngle,direction); +} + +void EdgeArcCircle::applySimilarity(double xBary, double yBary, double dimChar) +{ + Edge::applySimilarity(xBary,yBary,dimChar); + _radius/=dimChar; + _center[0]=(_center[0]-xBary)/dimChar; + _center[1]=(_center[1]-yBary)/dimChar; +} + +void EdgeArcCircle::unApplySimilarity(double xBary, double yBary, double dimChar) +{ + Edge::unApplySimilarity(xBary,yBary,dimChar); + _radius*=dimChar; + _center[0]=_center[0]*dimChar+xBary; + _center[1]=_center[1]*dimChar+yBary; +} + +/*! + * 'eps' is expected to be > 0. + * 'conn' is of size 3. conn[0] is start id, conn[1] is end id and conn[2] is middle id. + * 'offset' is typically the number of nodes already existing in global 2D curve mesh. Additionnal coords 'addCoo' ids will be put after the already existing. + */ +void EdgeArcCircle::tesselate(const int *conn, int offset, double eps, std::vector<int>& newConn, std::vector<double>& addCoo) const +{ + newConn.push_back(INTERP_KERNEL::NORM_POLYL); + int nbOfSubDiv=(int)(fabs(_angle)/eps); + if(nbOfSubDiv<=2) + { + newConn.push_back(conn[0]); newConn.push_back(conn[2]); newConn.push_back(conn[1]); + return ; + } + double signOfAngle=_angle>0.?1.:-1.; + int offset2=offset+((int)addCoo.size())/2; + newConn.push_back(conn[0]); + for(int i=1;i<nbOfSubDiv;i++,offset2++) + { + double angle=_angle0+i*eps*signOfAngle; + newConn.push_back(offset2); + addCoo.push_back(_center[0]+_radius*cos(angle)); addCoo.push_back(_center[1]+_radius*sin(angle)); + } + newConn.push_back(conn[1]); +} + +EdgeArcCircle *EdgeArcCircle::BuildFromNodes(Node *start, Node *middle, Node *end) +{ + EdgeLin *e1,*e2; + e1=new EdgeLin(start,middle); + e2=new EdgeLin(middle,end); + SegSegIntersector inters(*e1,*e2); + bool colinearity=inters.areColinears(); + delete e1; delete e2; + if(colinearity) + { + start->decrRef(); middle->decrRef(); end->decrRef(); + return 0; + } + else + { + EdgeArcCircle *ret=new EdgeArcCircle(start,middle,end); + start->decrRef(); middle->decrRef(); end->decrRef(); + return ret; + } +} + +/*! + * Given an \b NON normalized vector 'vect', returns its norm 'normVect' and its + * angle in ]-Pi,Pi] relative to Ox axe. + */ +double EdgeArcCircle::GetAbsoluteAngle(const double *vect, double& normVect) +{ + normVect=Node::norm(vect); + return GetAbsoluteAngleOfNormalizedVect(vect[0]/normVect,vect[1]/normVect); +} + +/*! + * Given a \b normalized vector defined by (ux,uy) returns its angle in ]-Pi;Pi]. + * So before using this method ux*ux+uy*uy should as much as possible close to 1. + * This methods is quite time consuming in order to keep as much as possible precision. + * It is NOT ALWAYS possible to do that only in one call of acos. Sometimes call to asin is necessary + * due to imperfection of acos near 0. and Pi (cos x ~ 1-x*x/2.) + */ +double EdgeArcCircle::GetAbsoluteAngleOfNormalizedVect(double ux, double uy) +{ + return atan2(uy, ux); +} + +void EdgeArcCircle::GetArcOfCirclePassingThru(const double *start, const double *middle, const double *end, + double *center, double& radius, double& angleInRad, double& angleInRad0) +{ + double delta=(middle[0]-start[0])*(end[1]-middle[1])-(end[0]-middle[0])*(middle[1]-start[1]); + double b1=(middle[1]*middle[1]+middle[0]*middle[0]-start[0]*start[0]-start[1]*start[1])/2; + double b2=(end[1]*end[1]+end[0]*end[0]-middle[0]*middle[0]-middle[1]*middle[1])/2; + center[0]=((end[1]-middle[1])*b1+(start[1]-middle[1])*b2)/delta; + center[1]=((middle[0]-end[0])*b1+(middle[0]-start[0])*b2)/delta; + radius=SafeSqrt((start[0]-center[0])*(start[0]-center[0])+(start[1]-center[1])*(start[1]-center[1])); + angleInRad0=GetAbsoluteAngleOfNormalizedVect((start[0]-center[0])/radius,(start[1]-center[1])/radius); + double angleInRadM=GetAbsoluteAngleOfNormalizedVect((middle[0]-center[0])/radius,(middle[1]-center[1])/radius); + angleInRad=GetAbsoluteAngleOfNormalizedVect(((start[0]-center[0])*(end[0]-center[0])+(start[1]-center[1])*(end[1]-center[1]))/(radius*radius), + ((start[0]-center[0])*(end[1]-center[1])-(start[1]-center[1])*(end[0]-center[0]))/(radius*radius)); + if(IsAngleNotIn(angleInRad0,angleInRad,angleInRadM)) + angleInRad=angleInRad<0?2*M_PI+angleInRad:angleInRad-2*M_PI; +} + +void EdgeArcCircle::dumpInXfigFile(std::ostream& stream, bool direction, int resolution, const Bounds& box) const +{ + stream << "5 1 0 1 "; + fillXfigStreamForLoc(stream); + stream << " 7 50 -1 -1 0.000 0 "; + if( (direction && (-_angle)>=0) || (!direction && (-_angle)<0)) + stream << '0';//'0' + else + stream << '1';//'1' + stream << " 1 0 "; + stream << box.fitXForXFigD(_center[0],resolution) << " " << box.fitYForXFigD(_center[1],resolution) << " "; + direction?_start->dumpInXfigFile(stream,resolution,box):_end->dumpInXfigFile(stream,resolution,box); + Node *middle=buildRepresentantOfMySelf(); + middle->dumpInXfigFile(stream,resolution,box); + middle->decrRef(); + direction?_end->dumpInXfigFile(stream,resolution,box):_start->dumpInXfigFile(stream,resolution,box); + stream << std::endl << "1 1 2.00 120.00 180.00" << std::endl; +} + +void EdgeArcCircle::update(Node *m) +{ + GetArcOfCirclePassingThru(*_start,*m,*_end,_center,_radius,_angle,_angle0); + updateBounds(); +} + +/*! + * This methods computes : + * \f[ + * \int_{Current Edge} -ydx + * \f] + */ +double EdgeArcCircle::getAreaOfZone() const +{ + return -_radius*_radius*(sin(_angle)-_angle)/2.+((*_start)[0]-(*_end)[0])*((*_start)[1]+(*_end)[1])/2.; +} + +double EdgeArcCircle::getCurveLength() const +{ + return fabs(_angle*_radius); +} + +void EdgeArcCircle::getBarycenter(double *bary) const +{ + bary[0]=_center[0]+_radius*cos(_angle0+_angle/2.); + bary[1]=_center[1]+_radius*sin(_angle0+_angle/2.); +} + +/*! + * \f[ + * bary[0]=\int_{Current Edge} -yxdx + * \f] + * \f[ + * bary[1]=\int_{Current Edge} -\frac{y^{2}}{2}dx + * \f] + * To compute these 2 expressions in this class we have : + * \f[ + * x=x_{0}+Radius \cdot cos(\theta) + * \f] + * \f[ + * y=y_{0}+Radius \cdot sin(\theta) + * \f] + * \f[ + * dx=-Radius \cdot sin(\theta) \cdot d\theta + * \f] + */ +void EdgeArcCircle::getBarycenterOfZone(double *bary) const +{ + double x0=_center[0]; + double y0=_center[1]; + double angle1=_angle0+_angle; + double tmp1=sin(angle1); + double tmp0=sin(_angle0); + double tmp2=_radius*_radius*_radius; + double tmp3=cos(angle1); + double tmp4=cos(_angle0); + bary[0]=_radius*x0*y0*(tmp4-tmp3)+_radius*_radius*(y0*(cos(2*_angle0)-cos(2*angle1))/4.+ + x0*(_angle/2.+(sin(2.*_angle0)-sin(2.*angle1))/4.)) + +tmp2*(tmp1*tmp1*tmp1-tmp0*tmp0*tmp0)/3.; + bary[1]=y0*y0*_radius*(tmp4-tmp3)/2.+_radius*_radius*y0*(_angle/2.+(sin(2.*_angle0)-sin(2.*angle1))/4.) + +tmp2*(tmp4-tmp3+(tmp3*tmp3*tmp3-tmp4*tmp4*tmp4)/3.)/2.; +} + +/** + * Compute the "middle" of two points on the arc of circle. + * The order (p1,p2) or (p2,p1) doesn't matter. p1 and p2 have to be localized on the edge defined by this. + * \param[out] mid the point located half-way between p1 and p2 on the arc defined by this. + * \sa getMiddleOfPointsOriented() a generalisation working also when p1 and p2 are not on the arc. + */ +void EdgeArcCircle::getMiddleOfPoints(const double *p1, const double *p2, double *mid) const +{ + double dx1((p1[0]-_center[0])/_radius),dy1((p1[1]-_center[1])/_radius),dx2((p2[0]-_center[0])/_radius),dy2((p2[1]-_center[1])/_radius); + double angle1(GetAbsoluteAngleOfNormalizedVect(dx1,dy1)),angle2(GetAbsoluteAngleOfNormalizedVect(dx2,dy2)); + // + double myDelta1(angle1-_angle0),myDelta2(angle2-_angle0); + if(_angle>0.) + { myDelta1=myDelta1>-QUADRATIC_PLANAR::_precision?myDelta1:myDelta1+2.*M_PI; myDelta2=myDelta2>-QUADRATIC_PLANAR::_precision?myDelta2:myDelta2+2.*M_PI; } + else + { myDelta1=myDelta1<QUADRATIC_PLANAR::_precision?myDelta1:myDelta1-2.*M_PI; myDelta2=myDelta2<QUADRATIC_PLANAR::_precision?myDelta2:myDelta2-2.*M_PI; } + //// + mid[0]=_center[0]+_radius*cos(_angle0+(myDelta1+myDelta2)/2.); + mid[1]=_center[1]+_radius*sin(_angle0+(myDelta1+myDelta2)/2.); +} + +/** + * Compute the "middle" of two points on the arc of circle. + * Walk on the circle from p1 to p2 using the rotation direction indicated by this->_angle (i.e. by the orientation of the arc). + * This function is sensitive to the ordering of p1 and p2. + * \param[out] mid the point located half-way between p1 and p2 + * \sa getMiddleOfPoints() to be used when the order of p1 and p2 is not relevant. + */ +void EdgeArcCircle::getMiddleOfPointsOriented(const double *p1, const double *p2, double *mid) const +{ + double dx1((p1[0]-_center[0])/_radius),dy1((p1[1]-_center[1])/_radius),dx2((p2[0]-_center[0])/_radius),dy2((p2[1]-_center[1])/_radius); + double angle1(GetAbsoluteAngleOfNormalizedVect(dx1,dy1)),angle2(GetAbsoluteAngleOfNormalizedVect(dx2,dy2)); + + if (angle1 <= 0.0) + angle1 += 2.*M_PI; + if (angle2 <= 0.0) + angle2 += 2.*M_PI; + + double avg; + if((_angle>0. && angle1 <= angle2) || (_angle<=0. && angle1 >= angle2)) + avg = (angle1+angle2)/2.; + else + avg = (angle1+angle2)/2. - M_PI; + + mid[0]=_center[0]+_radius*cos(avg); + mid[1]=_center[1]+_radius*sin(avg); +} + + +/*! + * Characteristic value used is angle in ]_Pi;Pi[ from axe 0x. + */ +bool EdgeArcCircle::isIn(double characterVal) const +{ + return IsIn2Pi(_angle0,_angle,characterVal); +} + +Node *EdgeArcCircle::buildRepresentantOfMySelf() const +{ + return new Node(_center[0]+_radius*cos(_angle0+_angle/2.),_center[1]+_radius*sin(_angle0+_angle/2.)); +} + +/*! + * Characteristic value used is angle in ]_Pi;Pi[ from axe 0x. + * 'val1' and 'val2' have been detected previously as owning to this. + */ +bool EdgeArcCircle::isLower(double val1, double val2) const +{ + double myDelta1=val1-_angle0; + double myDelta2=val2-_angle0; + if(_angle>0.) + { + myDelta1=myDelta1>-(_radius*QUADRATIC_PLANAR::_precision)?myDelta1:myDelta1+2.*M_PI;//in some cases val1 or val2 are so close to angle0 that myDelta is close to 0. but negative. + myDelta2=myDelta2>-(_radius*QUADRATIC_PLANAR::_precision)?myDelta2:myDelta2+2.*M_PI; + return myDelta1<myDelta2; + } + else + { + myDelta1=myDelta1<(_radius*QUADRATIC_PLANAR::_precision)?myDelta1:myDelta1-2.*M_PI; + myDelta2=myDelta2<(_radius*QUADRATIC_PLANAR::_precision)?myDelta2:myDelta2-2.*M_PI; + return myDelta2<myDelta1; + } +} + +/*! + * For Arc circle the caract value is angle with Ox between -Pi and Pi. + */ +double EdgeArcCircle::getCharactValue(const Node& node) const +{ + double dx=(node[0]-_center[0])/_radius; + double dy=(node[1]-_center[1])/_radius; + return GetAbsoluteAngleOfNormalizedVect(dx,dy); +} + +double EdgeArcCircle::getCharactValueBtw0And1(const Node& node) const +{ + double dx=(node[0]-_center[0])/_radius; + double dy=(node[1]-_center[1])/_radius; + double angle=GetAbsoluteAngleOfNormalizedVect(dx,dy); + // + double myDelta=angle-_angle0; + if(_angle>0.) + myDelta=myDelta>=0.?myDelta:myDelta+2.*M_PI; + else + myDelta=myDelta<=0.?myDelta:myDelta-2.*M_PI; + return myDelta/_angle; +} + +double EdgeArcCircle::getDistanceToPoint(const double *pt) const +{ + double angle=Node::computeAngle(_center,pt); + if(IsIn2Pi(_angle0,_angle,angle)) + return fabs(Node::distanceBtw2Pt(_center,pt)-_radius); + else + { + double dist1=Node::distanceBtw2Pt(*_start,pt); + double dist2=Node::distanceBtw2Pt(*_end,pt); + return std::min(dist1,dist2); + } +} + +bool EdgeArcCircle::isNodeLyingOn(const double *coordOfNode) const +{ + double dist=Node::distanceBtw2Pt(_center,coordOfNode); + if(Node::areDoubleEquals(dist,_radius)) + { + double angle=Node::computeAngle(_center,coordOfNode); + return IsIn2Pi(_angle0,_angle,angle); + } + else + return false; +} + +/*! + * Idem IsAngleNotIn except that here 'start' in ]-Pi;Pi[ and delta in ]-2*Pi;2Pi[. + * @param angleIn in ]-Pi;Pi[. + */ +bool EdgeArcCircle::IsIn2Pi(double start, double delta, double angleIn) +{ + double myDelta=angleIn-start; + if(delta>0.) + { + myDelta=myDelta>=0.?myDelta:myDelta+2.*M_PI; + return myDelta>0. && myDelta<delta; + } + else + { + myDelta=myDelta<=0.?myDelta:myDelta-2.*M_PI; + return myDelta<0. && myDelta>delta; + } +} + +/*! + * Given the arc 'a' defined by 'start' angle and a 'delta' [-Pi;Pi] states for the angle 'angleIn' [-Pi;Pi] if it owns or not 'a'. + */ +bool EdgeArcCircle::IsAngleNotIn(double start, double delta, double angleIn) +{ + double tmp=start; + if(tmp<0.) + tmp+=2*M_PI; + double tmp2=angleIn; + if(tmp2<0.) + tmp2+=2*M_PI; + if(tmp+delta>=2.*M_PI) + return (tmp2<tmp) && (tmp2>tmp+delta-2*M_PI); + else if(tmp+delta>=0.) + return (tmp2<std::min(tmp,tmp+delta) || tmp2>std::max(tmp,tmp+delta)); + else + return (tmp2>tmp) && (tmp2<(tmp+delta+2.*M_PI)); +} + +void EdgeArcCircle::updateBounds() +{ + _bounds.setValues(std::min((*_start)[0],(*_end)[0]),std::max((*_start)[0],(*_end)[0]),std::min((*_start)[1],(*_end)[1]),std::max((*_start)[1],(*_end)[1])); + if(IsIn2Pi(_angle0,_angle,M_PI/2)) + _bounds[3]=_center[1]+_radius; + if(IsIn2Pi(_angle0,_angle,-M_PI/2)) + _bounds[2]=_center[1]-_radius; + if(IsIn2Pi(_angle0,_angle,0.)) + _bounds[1]=_center[0]+_radius; + if(IsIn2Pi(_angle0,_angle,M_PI)) + _bounds[0]=_center[0]-_radius; +} + +void EdgeArcCircle::fillGlobalInfoAbs(bool direction, const std::map<INTERP_KERNEL::Node *,int>& mapThis, const std::map<INTERP_KERNEL::Node *,int>& mapOther, int offset1, int offset2, double fact, double baryX, double baryY, + std::vector<int>& edgesThis, std::vector<double>& addCoo, std::map<INTERP_KERNEL::Node *,int> mapAddCoo) const +{ + int tmp[2]; + _start->fillGlobalInfoAbs(mapThis,mapOther,offset1,offset2,fact,baryX,baryY,addCoo,mapAddCoo,tmp); + _end->fillGlobalInfoAbs(mapThis,mapOther,offset1,offset2,fact,baryX,baryY,addCoo,mapAddCoo,tmp+1); + if(direction) + { + edgesThis.push_back(tmp[0]); + edgesThis.push_back(tmp[1]); + } + else + { + edgesThis.push_back(tmp[1]); + edgesThis.push_back(tmp[0]); + } +} + +void EdgeArcCircle::fillGlobalInfoAbs2(const std::map<INTERP_KERNEL::Node *,int>& mapThis, const std::map<INTERP_KERNEL::Node *,int>& mapOther, int offset1, int offset2, double fact, double baryX, double baryY, + std::vector<int>& edgesOther, std::vector<double>& addCoo, std::map<INTERP_KERNEL::Node *,int>& mapAddCoo) const +{ + _start->fillGlobalInfoAbs2(mapThis,mapOther,offset1,offset2,fact,baryX,baryY,addCoo,mapAddCoo,edgesOther); + _end->fillGlobalInfoAbs2(mapThis,mapOther,offset1,offset2,fact,baryX,baryY,addCoo,mapAddCoo,edgesOther); +} diff --git a/src/medtool/src/INTERP_KERNEL/Geometric2D/InterpKernelGeo2DEdgeArcCircle.hxx b/src/medtool/src/INTERP_KERNEL/Geometric2D/InterpKernelGeo2DEdgeArcCircle.hxx new file mode 100644 index 000000000..382077bc4 --- /dev/null +++ b/src/medtool/src/INTERP_KERNEL/Geometric2D/InterpKernelGeo2DEdgeArcCircle.hxx @@ -0,0 +1,138 @@ +// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 +// 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 __INTERPKERNELGEO2DEDGEARCCIRCLE_HXX__ +#define __INTERPKERNELGEO2DEDGEARCCIRCLE_HXX__ + +#include "INTERPKERNELDefines.hxx" +#include "InterpKernelGeo2DEdge.hxx" + +namespace INTERP_KERNEL +{ + class INTERPKERNEL_EXPORT ArcCArcCIntersector : public SameTypeEdgeIntersector + { + public: + ArcCArcCIntersector(const EdgeArcCircle& e1, const EdgeArcCircle& e2); + bool haveTheySameDirection() const; + bool areColinears() const; + void getPlacements(Node *start, Node *end, TypeOfLocInEdge& whereStart, TypeOfLocInEdge& whereEnd, MergePoints& commonNode) const; + void areOverlappedOrOnlyColinears(const Bounds *whereToFind, bool& obviousNoIntersection, bool& areOverlapped); + std::list< IntersectElement > getIntersectionsCharacteristicVal() const; + private: + //! return angle in ]-Pi;Pi[ - 'node' must be on curve of '_e1' + double getAngle(Node *node) const; + static bool internalAreColinears(const EdgeArcCircle& a1, const EdgeArcCircle& a2, double& distBetweenCenters, double& cst, double& radiusL, double centerL[2], double& raduisB, double centerB[2]); + static bool areArcsOverlapped(const EdgeArcCircle& a1, const EdgeArcCircle& a2); + private: + const EdgeArcCircle& getE1() const { return (const EdgeArcCircle&)_e1; } + const EdgeArcCircle& getE2() const { return (const EdgeArcCircle&)_e2; } + private: + double _dist; + }; + + class INTERPKERNEL_EXPORT ArcCSegIntersector : public CrossTypeEdgeIntersector + { + public: + ArcCSegIntersector(const EdgeArcCircle& e1, const EdgeLin& e2, bool reverse=true); + //virtual overloading + bool areColinears() const; + void getPlacements(Node *start, Node *end, TypeOfLocInEdge& whereStart, TypeOfLocInEdge& whereEnd, MergePoints& commonNode) const; + void areOverlappedOrOnlyColinears(const Bounds *whereToFind, bool& obviousNoIntersection, bool& areOverlapped); + std::list< IntersectElement > getIntersectionsCharacteristicVal() const; + private: + const EdgeArcCircle& getE1() const { return (const EdgeArcCircle&)_e1; } + const EdgeLin& getE2() const { return (const EdgeLin&)_e2; } + private: + double _dx; + double _dy; + double _drSq; + double _cross; + double _determinant; + }; + + class INTERPKERNEL_EXPORT EdgeArcCircle : public Edge + { + public: + EdgeArcCircle(std::istream& lineInXfig); + EdgeArcCircle(Node *start, Node *middle, Node *end, bool direction = true); + EdgeArcCircle(double sX, double sY, double mX, double mY, double eX, double eY); + EdgeArcCircle(Node *start, Node *end, const double *center, double radius, double angle0, double deltaAngle, bool direction=true); + //! for tests + void changeMiddle(Node *newMiddle); + void dumpInXfigFile(std::ostream& stream, bool direction, int resolution, const Bounds& box) const; + void update(Node *m); + double getAreaOfZone() const; + double getCurveLength() const; + void getBarycenter(double *bary) const; + void getBarycenterOfZone(double *bary) const; + void getMiddleOfPoints(const double *p1, const double *p2, double *mid) const; + void getMiddleOfPointsOriented(const double *p1, const double *p2, double *mid) const; + bool isIn(double characterVal) const; + Node *buildRepresentantOfMySelf() const; + bool isLower(double val1, double val2) const; + double getCharactValue(const Node& node) const; + double getCharactValueBtw0And1(const Node& node) const; + double getDistanceToPoint(const double *pt) const; + bool isNodeLyingOn(const double *coordOfNode) const; + TypeOfFunction getTypeOfFunc() const { return ARC_CIRCLE; } + void dynCastFunction(const EdgeLin * &seg, + const EdgeArcCircle * &arcSeg) const { arcSeg=this; } + const double *getCenter() const { return _center; } + void getCenter(double *center) const { center[0]=_center[0]; center[1]=_center[1]; } + bool doIHaveSameDirectionAs(const Edge& other) const { return false; } + void applySimilarity(double xBary, double yBary, double dimChar); + void unApplySimilarity(double xBary, double yBary, double dimChar); + double getAngle0() const { return _angle0; } + double getRadius() const { return _radius; } + double getAngle() const { return _angle; } + void tesselate(const int *conn, int offset, double eps, std::vector<int>& newConn, std::vector<double>& addCoo) const; + static EdgeArcCircle *BuildFromNodes(Node *start, Node *middle, Node *end); + static double GetAbsoluteAngle(const double *vect, double& normVect); + static double GetAbsoluteAngleOfNormalizedVect(double ux, double uy); + static void GetArcOfCirclePassingThru(const double *start, const double *middle, const double *end, + double *center, double& radius, double& angleInRad, double& angleInRad0); + //! To avoid in aggressive optimizations nan. + static double SafeSqrt(double val) { double ret=std::max(val,0.); return sqrt(ret); } + static double SafeAcos(double cosAngle) { double ret=std::min(cosAngle,1.); ret=std::max(ret,-1.); return acos(ret); } + static double SafeAsin(double sinAngle) { double ret=std::min(sinAngle,1.); ret=std::max(ret,-1.); return asin(ret); } + //! @param start and @param angleIn in ]-Pi;Pi] and @param delta in ]-2*Pi,2*Pi[ + static bool IsIn2Pi(double start, double delta, double angleIn); + //! 'delta' 'start' in ]-Pi;Pi[ + static bool IsAngleNotIn(double start, double delta, double angleIn); + //! for an angle 'angle' in ]-3*Pi;3*Pi[ returns angle in ]-Pi;Pi[ + static double NormalizeAngle(double angle) { if(angle>M_PI) return angle-2.*M_PI; if(angle<-M_PI) return angle+2.*M_PI; return angle; } + protected: + void updateBounds(); + Edge *buildEdgeLyingOnMe(Node *start, Node *end, bool direction=true) const; + void fillGlobalInfoAbs(bool direction, const std::map<INTERP_KERNEL::Node *,int>& mapThis, const std::map<INTERP_KERNEL::Node *,int>& mapOther, int offset1, int offset2, double fact, double baryX, double baryY, + std::vector<int>& edgesThis, std::vector<double>& addCoo, std::map<INTERP_KERNEL::Node *,int> mapAddCoo) const; + void fillGlobalInfoAbs2(const std::map<INTERP_KERNEL::Node *,int>& mapThis, const std::map<INTERP_KERNEL::Node *,int>& mapOther, int offset1, int offset2, double fact, double baryX, double baryY, + std::vector<int>& edgesOther, std::vector<double>& addCoo, std::map<INTERP_KERNEL::Node *,int>& mapAddCoo) const; + protected: + //!Value between -2Pi and 2Pi + double _angle; + //!Value between -Pi and Pi + double _angle0; + double _radius; + double _center[2]; + }; +} + +#endif diff --git a/src/medtool/src/INTERP_KERNEL/Geometric2D/InterpKernelGeo2DEdgeInfLin.cxx b/src/medtool/src/INTERP_KERNEL/Geometric2D/InterpKernelGeo2DEdgeInfLin.cxx new file mode 100644 index 000000000..9f669194d --- /dev/null +++ b/src/medtool/src/INTERP_KERNEL/Geometric2D/InterpKernelGeo2DEdgeInfLin.cxx @@ -0,0 +1,30 @@ +// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 +// 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 "InterpKernelGeo2DEdgeInfLin.hxx" + +using namespace INTERP_KERNEL; + +EdgeInfLin::EdgeInfLin(Node *pointPassingThrough, double slope) +{ + _start=pointPassingThrough; + _start->incrRef(); + _end=new Node((*_start)[0]+cos(slope),(*_start)[1]+sin(slope)); +} diff --git a/src/medtool/src/INTERP_KERNEL/Geometric2D/InterpKernelGeo2DEdgeInfLin.hxx b/src/medtool/src/INTERP_KERNEL/Geometric2D/InterpKernelGeo2DEdgeInfLin.hxx new file mode 100644 index 000000000..c4942765f --- /dev/null +++ b/src/medtool/src/INTERP_KERNEL/Geometric2D/InterpKernelGeo2DEdgeInfLin.hxx @@ -0,0 +1,41 @@ +// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 +// 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 __INTERPKERNELGEO2DEDGEINFLIN_HXX__ +#define __INTERPKERNELGEO2DEDGEINFLIN_HXX__ + +#include "InterpKernelGeo2DEdgeLin.hxx" + +namespace INTERP_KERNEL +{ + class EdgeInfLin : public EdgeLin + { + public: + EdgeInfLin(Node *start, Node *end):EdgeLin(start,end,true) { } + EdgeInfLin(Node *pointPassingThrough, double slope); + bool isIn(double characterVal) const { return true; } + void dynCastFunction(const EdgeLin * &seg, + const EdgeArcCircle * &arcSeg) const { seg=this; } + protected: + ~EdgeInfLin() { } + }; +} + +#endif diff --git a/src/medtool/src/INTERP_KERNEL/Geometric2D/InterpKernelGeo2DEdgeLin.cxx b/src/medtool/src/INTERP_KERNEL/Geometric2D/InterpKernelGeo2DEdgeLin.cxx new file mode 100644 index 000000000..0ea63b722 --- /dev/null +++ b/src/medtool/src/INTERP_KERNEL/Geometric2D/InterpKernelGeo2DEdgeLin.cxx @@ -0,0 +1,335 @@ +// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 +// 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 "InterpKernelGeo2DEdgeLin.hxx" +#include "InterpKernelGeo2DNode.hxx" +#include "InterpKernelException.hxx" +#include "NormalizedUnstructuredMesh.hxx" + +using namespace INTERP_KERNEL; + +namespace INTERP_KERNEL +{ + extern const unsigned MAX_SIZE_OF_LINE_XFIG_FILE=1024; +} + +SegSegIntersector::SegSegIntersector(const EdgeLin& e1, const EdgeLin& e2):SameTypeEdgeIntersector(e1,e2) +{ + _matrix[0]=(*(e2.getStartNode()))[0]-(*(e2.getEndNode()))[0]; + _matrix[1]=(*(e1.getEndNode()))[0]-(*(e1.getStartNode()))[0]; + _matrix[2]=(*(e2.getStartNode()))[1]-(*(e2.getEndNode()))[1]; + _matrix[3]=(*(e1.getEndNode()))[1]-(*(e1.getStartNode()))[1]; + _col[0]=_matrix[3]*(*(e1.getStartNode()))[0]-_matrix[1]*(*(e1.getStartNode()))[1]; + _col[1]=-_matrix[2]*(*(e2.getStartNode()))[0]+_matrix[0]*(*(e2.getStartNode()))[1]; + //Little trick to avoid problems if 'e1' and 'e2' are colinears and along Ox or Oy axes. + if(fabs(_matrix[3])>fabs(_matrix[1])) + _ind=0; + else + _ind=1; +} + +/*! + * Must be called when 'this' and 'other' have been detected to be at least colinear. Typically they are overlapped. + * Must be called after call of areOverlappedOrOnlyColinears. + */ +bool SegSegIntersector::haveTheySameDirection() const +{ + return (_matrix[3]*_matrix[1]+_matrix[2]*_matrix[0])>0.; + //return (_matrix[_ind?1:0]>0. && _matrix[_ind?3:2]>0.) || (_matrix[_ind?1:0]<0. && _matrix[_ind?3:2]<0.); +} + +/*! + * Precondition start and end must be so that there predecessor was in the same direction than 'e1' + */ +void SegSegIntersector::getPlacements(Node *start, Node *end, TypeOfLocInEdge& whereStart, TypeOfLocInEdge& whereEnd, MergePoints& commonNode) const +{ + getCurveAbscisse(start,whereStart,commonNode); + getCurveAbscisse(end,whereEnd,commonNode); +} + +void SegSegIntersector::getCurveAbscisse(Node *node, TypeOfLocInEdge& where, MergePoints& commonNode) const +{ + bool obvious; + obviousCaseForCurvAbscisse(node,where,commonNode,obvious); + if(obvious) + return ; + double ret=((*node)[!_ind]-(*_e1.getStartNode())[!_ind])/((*_e1.getEndNode())[!_ind]-(*_e1.getStartNode())[!_ind]); + if(ret>0. && ret <1.) + where=INSIDE; + else if(ret<0.) + where=OUT_BEFORE; + else + where=OUT_AFTER; +} + +/*! + * areColinears method should be called before with a returned colinearity equal to false to avoid bad news. + */ +std::list< IntersectElement > SegSegIntersector::getIntersectionsCharacteristicVal() const +{ + std::list< IntersectElement > ret; + double x=_matrix[0]*_col[0]+_matrix[1]*_col[1]; + double y=_matrix[2]*_col[0]+_matrix[3]*_col[1]; + //Only one intersect point possible + Node *node=new Node(x,y); + node->declareOn(); + bool i_1S=_e1.getStartNode()->isEqual(*node); + bool i_1E=_e1.getEndNode()->isEqual(*node); + bool i_2S=_e2.getStartNode()->isEqual(*node); + bool i_2E=_e2.getEndNode()->isEqual(*node); + ret.push_back(IntersectElement(_e1.getCharactValue(*node), + _e2.getCharactValue(*node), + i_1S,i_1E,i_2S,i_2E,node,_e1,_e2,keepOrder())); + return ret; +} + +/*! + * retrieves if segs are colinears. + * WARNING !!! Contrary to areOverlappedOrOnlyColinears method, this method use an + * another precision to detect colinearity ! + */ +bool SegSegIntersector::areColinears() const +{ + double determinant=_matrix[0]*_matrix[3]-_matrix[1]*_matrix[2]; + return fabs(determinant)<QUADRATIC_PLANAR::_arc_detection_precision; +} + +/*! + * Should be called \b once ! non const method. + * \param whereToFind specifies the box where final seek should be done. Essentially it is used for caracteristic reason. + * \param colinearity returns if regarding QUADRATIC_PLANAR::_precision ; e1 and e2 are colinears + * If true 'this' is modified ! So this method be called once above all if true is returned for this parameter. + * \param areOverlapped if colinearity if true, this parameter looks if e1 and e2 are overlapped. + */ +void SegSegIntersector::areOverlappedOrOnlyColinears(const Bounds *whereToFind, bool& colinearity, bool& areOverlapped) +{ + double determinant=_matrix[0]*_matrix[3]-_matrix[1]*_matrix[2]; + if(fabs(determinant)>2.*QUADRATIC_PLANAR::_precision)//2*_precision due to max of offset on _start and _end + { + colinearity=false; areOverlapped=false; + _matrix[0]/=determinant; _matrix[1]/=determinant; _matrix[2]/=determinant; _matrix[3]/=determinant; + } + else + { + colinearity=true; + //retrieving initial matrix + double tmp=_matrix[0]; _matrix[0]=_matrix[3]; _matrix[3]=tmp; + _matrix[1]=-_matrix[1]; _matrix[2]=-_matrix[2]; + // + double deno=sqrt(_matrix[0]*_matrix[0]+_matrix[1]*_matrix[1]); + double x=(*(_e1.getStartNode()))[0]-(*(_e2.getStartNode()))[0]; + double y=(*(_e1.getStartNode()))[1]-(*(_e2.getStartNode()))[1]; + areOverlapped=fabs((_matrix[1]*y+_matrix[0]*x)/deno)<QUADRATIC_PLANAR::_precision; + } +} + +EdgeLin::EdgeLin(std::istream& lineInXfig) +{ + char currentLine[MAX_SIZE_OF_LINE_XFIG_FILE]; + lineInXfig.getline(currentLine,MAX_SIZE_OF_LINE_XFIG_FILE); + _start=new Node(lineInXfig); + _end=new Node(lineInXfig); + updateBounds(); +} + +EdgeLin::EdgeLin(Node *start, Node *end, bool direction):Edge(start,end,direction) +{ + updateBounds(); +} + +EdgeLin::EdgeLin(double sX, double sY, double eX, double eY):Edge(sX,sY,eX,eY) +{ + updateBounds(); +} + +EdgeLin::~EdgeLin() +{ +} + +/*! + * Characteristic for edges is relative position btw 0.;1. + */ +bool EdgeLin::isIn(double characterVal) const +{ + return characterVal>0. && characterVal<1.; +} + +Node *EdgeLin::buildRepresentantOfMySelf() const +{ + return new Node(((*(_start))[0]+(*(_end))[0])/2.,((*(_start))[1]+(*(_end))[1])/2.); +} + +double EdgeLin::getCharactValue(const Node& node) const +{ + return getCharactValueEng(node); +} + +double EdgeLin::getCharactValueBtw0And1(const Node& node) const +{ + return getCharactValueEng(node); +} + +double EdgeLin::getDistanceToPoint(const double *pt) const +{ + double loc=getCharactValueEng(pt); + if(loc>0. && loc<1.) + { + double tmp[2]; + tmp[0]=(*_start)[0]*(1-loc)+loc*(*_end)[0]; + tmp[1]=(*_start)[1]*(1-loc)+loc*(*_end)[1]; + return Node::distanceBtw2Pt(pt,tmp); + } + else + { + double dist1=Node::distanceBtw2Pt(*_start,pt); + double dist2=Node::distanceBtw2Pt(*_end,pt); + return std::min(dist1,dist2); + } +} + +bool EdgeLin::isNodeLyingOn(const double *coordOfNode) const +{ + double dBase=sqrt(_start->distanceWithSq(*_end)); + double d1=Node::distanceBtw2Pt(*_start,coordOfNode); + d1+=Node::distanceBtw2Pt(*_end,coordOfNode); + return Node::areDoubleEquals(dBase,d1); +} + +void EdgeLin::dumpInXfigFile(std::ostream& stream, bool direction, int resolution, const Bounds& box) const +{ + stream << "2 1 0 1 "; + fillXfigStreamForLoc(stream); + stream << " 7 50 -1 -1 0.000 0 0 -1 1 0 2" << std::endl << "1 1 1.00 60.00 120.00" << std::endl; + direction?_start->dumpInXfigFile(stream,resolution,box):_end->dumpInXfigFile(stream,resolution,box); + direction?_end->dumpInXfigFile(stream,resolution,box):_start->dumpInXfigFile(stream,resolution,box); + stream << std::endl; +} + +void EdgeLin::update(Node *m) +{ + updateBounds(); +} + +double EdgeLin::getNormSq() const +{ + return _start->distanceWithSq(*_end); +} + +/*! + * This methods computes : + * \f[ + * \int_{Current Edge} -ydx + * \f] + */ +double EdgeLin::getAreaOfZone() const +{ + return ((*_start)[0]-(*_end)[0])*((*_start)[1]+(*_end)[1])/2.; +} + +void EdgeLin::getBarycenter(double *bary) const +{ + bary[0]=((*_start)[0]+(*_end)[0])/2.; + bary[1]=((*_start)[1]+(*_end)[1])/2.; +} + +/*! + * \f[ + * bary[0]=\int_{Current Edge} -yxdx + * \f] + * \f[ + * bary[1]=\int_{Current Edge} -\frac{y^{2}}{2}dx + * \f] + * To compute these 2 expressions in this class we have : + * \f[ + * y=y_{1}+\frac{y_{2}-y_{1}}{x_{2}-x_{1}}(x-x_{1}) + * \f] + */ +void EdgeLin::getBarycenterOfZone(double *bary) const +{ + double x1=(*_start)[0]; + double y1=(*_start)[1]; + double x2=(*_end)[0]; + double y2=(*_end)[1]; + bary[0]=(x1-x2)*(y1*(2.*x1+x2)+y2*(2.*x2+x1))/6.; + //bary[0]+=(y1-y2)*(x2*x2/3.-(x1*x2+x1*x1)/6.)+y1*(x1*x1-x2*x2)/2.; + //bary[0]+=(y1-y2)*((x2*x2+x1*x2+x1*x1)/3.-(x2+x1)*x1/2.)+y1*(x1*x1-x2*x2)/2.; + bary[1]=(x1-x2)*(y1*(y1+y2)+y2*y2)/6.; +} + +/*! + * Here \a this is not used (contrary to EdgeArcCircle class). + */ +void EdgeLin::getMiddleOfPoints(const double *p1, const double *p2, double *mid) const +{ + mid[0]=(p1[0]+p2[0])/2.; + mid[1]=(p1[1]+p2[1])/2.; +} + +double EdgeLin::getCurveLength() const +{ + double x=(*_start)[0]-(*_end)[0]; + double y=(*_start)[1]-(*_end)[1]; + return sqrt(x*x+y*y); +} + +Edge *EdgeLin::buildEdgeLyingOnMe(Node *start, Node *end, bool direction) const +{ + return new EdgeLin(start,end,direction); +} + +/*! + * No precision should be introduced here. Just think as if precision was perfect. + */ +void EdgeLin::updateBounds() +{ + _bounds.setValues(std::min((*_start)[0],(*_end)[0]),std::max((*_start)[0],(*_end)[0]),std::min((*_start)[1],(*_end)[1]),std::max((*_start)[1],(*_end)[1])); +} + +double EdgeLin::getCharactValueEng(const double *node) const +{ + double car1_1x=node[0]-(*(_start))[0]; double car1_2x=(*(_end))[0]-(*(_start))[0]; + double car1_1y=node[1]-(*(_start))[1]; double car1_2y=(*(_end))[1]-(*(_start))[1]; + return (car1_1x*car1_2x+car1_1y*car1_2y)/(car1_2x*car1_2x+car1_2y*car1_2y); +} + +void EdgeLin::fillGlobalInfoAbs(bool direction, const std::map<INTERP_KERNEL::Node *,int>& mapThis, const std::map<INTERP_KERNEL::Node *,int>& mapOther, int offset1, int offset2, double fact, double baryX, double baryY, + std::vector<int>& edgesThis, std::vector<double>& addCoo, std::map<INTERP_KERNEL::Node *,int> mapAddCoo) const +{ + int tmp[2]; + _start->fillGlobalInfoAbs(mapThis,mapOther,offset1,offset2,fact,baryX,baryY,addCoo,mapAddCoo,tmp); + _end->fillGlobalInfoAbs(mapThis,mapOther,offset1,offset2,fact,baryX,baryY,addCoo,mapAddCoo,tmp+1); + if(direction) + { + edgesThis.push_back(tmp[0]); + edgesThis.push_back(tmp[1]); + } + else + { + edgesThis.push_back(tmp[1]); + edgesThis.push_back(tmp[0]); + } +} + +void EdgeLin::fillGlobalInfoAbs2(const std::map<INTERP_KERNEL::Node *,int>& mapThis, const std::map<INTERP_KERNEL::Node *,int>& mapOther, int offset1, int offset2, double fact, double baryX, double baryY, + std::vector<int>& edgesOther, std::vector<double>& addCoo, std::map<INTERP_KERNEL::Node *,int>& mapAddCoo) const +{ + _start->fillGlobalInfoAbs2(mapThis,mapOther,offset1,offset2,fact,baryX,baryY,addCoo,mapAddCoo,edgesOther); + _end->fillGlobalInfoAbs2(mapThis,mapOther,offset1,offset2,fact,baryX,baryY,addCoo,mapAddCoo,edgesOther); +} diff --git a/src/medtool/src/INTERP_KERNEL/Geometric2D/InterpKernelGeo2DEdgeLin.hxx b/src/medtool/src/INTERP_KERNEL/Geometric2D/InterpKernelGeo2DEdgeLin.hxx new file mode 100644 index 000000000..fad4ada11 --- /dev/null +++ b/src/medtool/src/INTERP_KERNEL/Geometric2D/InterpKernelGeo2DEdgeLin.hxx @@ -0,0 +1,87 @@ +// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 +// 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 __INTERPKERNELGEO2DEDGELIN_HXX__ +#define __INTERPKERNELGEO2DEDGELIN_HXX__ + +#include "INTERPKERNELDefines.hxx" +#include "InterpKernelGeo2DEdge.hxx" + +namespace INTERP_KERNEL +{ + class INTERPKERNEL_EXPORT SegSegIntersector : SameTypeEdgeIntersector + { + friend class Edge; + public: + SegSegIntersector(const EdgeLin& e1, const EdgeLin& e2); + bool areColinears() const; + bool haveTheySameDirection() const; + void getPlacements(Node *start, Node *end, TypeOfLocInEdge& whereStart, TypeOfLocInEdge& whereEnd, MergePoints& commonNode) const; + void areOverlappedOrOnlyColinears(const Bounds *whereToFind, bool& obviousNoIntersection, bool& areOverlapped); + std::list< IntersectElement > getIntersectionsCharacteristicVal() const; + private: + void getCurveAbscisse(Node *node, TypeOfLocInEdge& where, MergePoints& commonNode) const; + private: + //! index on which all single index op will be performed. Filled in case colinearity is equal to true. + int _ind; + double _col[2]; + double _matrix[4];//SPACEDIM*SPACEDIM + }; + + class INTERPKERNEL_EXPORT EdgeLin : public Edge + { + friend class SegSegIntersector; + public: + EdgeLin(std::istream& lineInXfig); + EdgeLin(Node *start, Node *end, bool direction=true); + EdgeLin(double sX, double sY, double eX, double eY); + ~EdgeLin(); + TypeOfFunction getTypeOfFunc() const { return SEG; } + void dumpInXfigFile(std::ostream& stream, bool direction, int resolution, const Bounds& box) const; + void update(Node *m); + double getNormSq() const; + double getAreaOfZone() const; + double getCurveLength() const; + void getBarycenter(double *bary) const; + void getBarycenterOfZone(double *bary) const; + void getMiddleOfPoints(const double *p1, const double *p2, double *mid) const; + bool isIn(double characterVal) const; + Node *buildRepresentantOfMySelf() const; + double getCharactValue(const Node& node) const; + double getCharactValueBtw0And1(const Node& node) const; + double getDistanceToPoint(const double *pt) const; + bool isNodeLyingOn(const double *coordOfNode) const; + bool isLower(double val1, double val2) const { return val1<val2; } + double getCharactValueEng(const double *node) const; + bool doIHaveSameDirectionAs(const Edge& other) const; + void dynCastFunction(const EdgeLin * &seg, + const EdgeArcCircle * &arcSeg) const { seg=this; } + protected: + EdgeLin() { } + void updateBounds(); + Edge *buildEdgeLyingOnMe(Node *start, Node *end, bool direction) const; + void fillGlobalInfoAbs(bool direction, const std::map<INTERP_KERNEL::Node *,int>& mapThis, const std::map<INTERP_KERNEL::Node *,int>& mapOther, int offset1, int offset2, double fact, double baryX, double baryY, + std::vector<int>& edgesThis, std::vector<double>& addCoo, std::map<INTERP_KERNEL::Node *,int> mapAddCoo) const; + void fillGlobalInfoAbs2(const std::map<INTERP_KERNEL::Node *,int>& mapThis, const std::map<INTERP_KERNEL::Node *,int>& mapOther, int offset1, int offset2, double fact, double baryX, double baryY, + std::vector<int>& edgesOther, std::vector<double>& addCoo, std::map<INTERP_KERNEL::Node *,int>& mapAddCoo) const; + }; +} + +#endif diff --git a/src/medtool/src/INTERP_KERNEL/Geometric2D/InterpKernelGeo2DElementaryEdge.cxx b/src/medtool/src/INTERP_KERNEL/Geometric2D/InterpKernelGeo2DElementaryEdge.cxx new file mode 100644 index 000000000..04089b219 --- /dev/null +++ b/src/medtool/src/INTERP_KERNEL/Geometric2D/InterpKernelGeo2DElementaryEdge.cxx @@ -0,0 +1,232 @@ +// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 +// 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 "InterpKernelGeo2DElementaryEdge.hxx" +#include "InterpKernelException.hxx" +#include "InterpKernelGeo2DEdge.hxx" +#include "InterpKernelGeo2DComposedEdge.hxx" + +using namespace INTERP_KERNEL; + +ElementaryEdge::ElementaryEdge(const ElementaryEdge& other):_direction(other._direction),_ptr(other._ptr) +{ + _ptr->incrRef(); +} + +ElementaryEdge::~ElementaryEdge() +{ + if(_ptr) + _ptr->decrRef(); +} + +bool ElementaryEdge::isNodeIn(Node *n) const +{ + return _ptr->getStartNode()==n || _ptr->getEndNode()==n; +} + +/*! + * \b WARNING contrary to INTERP_KERNEL::Edge::getBarycenterOfZone method called, + * this one is cumulative. + */ +void ElementaryEdge::getBarycenterOfZone(double *bary) const +{ + double tmp[2]; + _ptr->getBarycenterOfZone(tmp); + if(_direction) + { + bary[0]+=tmp[0]; + bary[1]+=tmp[1]; + } + else + { + bary[0]-=tmp[0]; + bary[1]-=tmp[1]; + } +} + +void ElementaryEdge::fillBounds(Bounds& output) const +{ + output.aggregate(_ptr->getBounds()); +} + +void ElementaryEdge::getAllNodes(std::set<Node *>& output) const +{ + output.insert(_ptr->getStartNode()); + output.insert(_ptr->getEndNode()); +} + +void ElementaryEdge::getBarycenter(double *bary, double& weigh) const +{ + _ptr->getBarycenter(bary); + weigh=_ptr->getCurveLength(); +} + +ElementaryEdge *ElementaryEdge::clone() const +{ + return new ElementaryEdge(*this); +} + +void ElementaryEdge::initLocations() const +{ + _ptr->initLocs(); +} + +/*! + * WARNING use this method if and only if this is so that it is completely in/out/on of @param pol. + */ +TypeOfEdgeLocInPolygon ElementaryEdge::locateFullyMySelf(const ComposedEdge& pol, TypeOfEdgeLocInPolygon precEdgeLoc) const +{ + if(getLoc()!=FULL_UNKNOWN) + return getLoc(); + //obvious cases + if(precEdgeLoc==FULL_IN_1) + { + if(getStartNode()->getLoc()==ON_1) + { + declareOut(); + return getLoc(); + } + else if(getStartNode()->getLoc()==IN_1 || getStartNode()->getLoc()==ON_TANG_1) + { + declareIn(); + return getLoc(); + } + } + if(precEdgeLoc==FULL_OUT_1) + { + if(getStartNode()->getLoc()==ON_1) + { + declareIn(); + return getLoc(); + } + else if(getStartNode()->getLoc()==IN_1 || getStartNode()->getLoc()==ON_TANG_1) + { + declareOut(); + return getLoc(); + } + } + if(getStartNode()->getLoc()==IN_1 || getEndNode()->getLoc()==IN_1) + { + declareIn(); + return getLoc(); + } + if(getStartNode()->getLoc()==OUT_1 || getEndNode()->getLoc()==OUT_1) + { + declareOut(); + return getLoc(); + } + //a seek is requested + return locateFullyMySelfAbsolute(pol); +} + +TypeOfEdgeLocInPolygon ElementaryEdge::locateFullyMySelfAbsolute(const ComposedEdge& pol) const +{ + Node *node=_ptr->buildRepresentantOfMySelf(); // build barycenter used to detect if the edge is IN or OUT + if(pol.isInOrOut(node)) + declareIn(); + else + declareOut(); + node->decrRef(); + return getLoc(); +} + +Node *ElementaryEdge::getEndNode() const +{ + if(_direction) + return _ptr->getEndNode(); + else return _ptr->getStartNode(); +} + +Node *ElementaryEdge::getStartNode() const +{ + if(_direction) + return _ptr->getStartNode(); + else + return _ptr->getEndNode(); +} + +bool ElementaryEdge::changeEndNodeWith(Node *node) const +{ + if(_direction) + return _ptr->changeEndNodeWith(node); + else + return _ptr->changeStartNodeWith(node); +} + +bool ElementaryEdge::changeStartNodeWith(Node *node) const +{ + if(_direction) + return _ptr->changeStartNodeWith(node); + else + return _ptr->changeEndNodeWith(node); +} + +void ElementaryEdge::dumpInXfigFile(std::ostream& stream, int resolution, const Bounds& box) const +{ + _ptr->dumpInXfigFile(stream,_direction,resolution,box); +} + +bool ElementaryEdge::intresicEqual(const ElementaryEdge *other) const +{ + return _ptr==other->_ptr; +} + +bool ElementaryEdge::intresicEqualDirSensitive(const ElementaryEdge *other) const +{ + return ( _direction==other->_direction ) && (_ptr==other->_ptr); +} + +bool ElementaryEdge::intresincEqCoarse(const Edge *other) const +{ + return _ptr==other; +} + +bool ElementaryEdge::isEqual(const ElementaryEdge& other) const +{ + return _ptr->isEqual(*other._ptr); +} + +/*! + * Called by QuadraticPolygon::splitAbs method. + */ +void ElementaryEdge::fillGlobalInfoAbs(const std::map<INTERP_KERNEL::Node *,int>& mapThis, const std::map<INTERP_KERNEL::Node *,int>& mapOther, int offset1, int offset2, double fact, double baryX, double baryY, + std::vector<int>& edgesThis, std::vector<double>& addCoo, std::map<INTERP_KERNEL::Node *,int> mapAddCoo) const +{ + _ptr->fillGlobalInfoAbs(_direction,mapThis,mapOther,offset1,offset2,fact,baryX,baryY,edgesThis,addCoo,mapAddCoo); +} + +/*! + * Called by QuadraticPolygon::splitAbs method. Close to ElementaryEdge::fillGlobalInfoAbs method expect that here edgesOther (that replace edgesThis) is here an in/out parameter that only contains nodes + * unsorted because the "other" mesh is not subdivided yet. + */ +void ElementaryEdge::fillGlobalInfoAbs2(const std::map<INTERP_KERNEL::Node *,int>& mapThis, const std::map<INTERP_KERNEL::Node *,int>& mapOther, int offset1, int offset2, double fact, double baryX, double baryY, + std::vector<int>& edgesOther, std::vector<double>& addCoo, std::map<INTERP_KERNEL::Node *,int>& mapAddCoo) const +{ + _ptr->fillGlobalInfoAbs2(mapThis,mapOther,offset1,offset2,fact,baryX,baryY,edgesOther,addCoo,mapAddCoo); +} + +/*! + * This method builds from a \a start node, an \a end node and a direction a new ElementaryEdge. + */ +ElementaryEdge *ElementaryEdge::BuildEdgeFromStartEndDir(bool direction, INTERP_KERNEL::Node *start, INTERP_KERNEL::Node *end) +{ + Edge *ptr=Edge::BuildEdgeFrom(start,end); + return new ElementaryEdge(ptr,direction); +} diff --git a/src/medtool/src/INTERP_KERNEL/Geometric2D/InterpKernelGeo2DElementaryEdge.hxx b/src/medtool/src/INTERP_KERNEL/Geometric2D/InterpKernelGeo2DElementaryEdge.hxx new file mode 100644 index 000000000..1c3cdefa9 --- /dev/null +++ b/src/medtool/src/INTERP_KERNEL/Geometric2D/InterpKernelGeo2DElementaryEdge.hxx @@ -0,0 +1,83 @@ +// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 +// 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 __INTERPKERNELGEO2DELEMENTARYEDGE_HXX__ +#define __INTERPKERNELGEO2DELEMENTARYEDGE_HXX__ + +#include "INTERPKERNELDefines.hxx" +#include "InterpKernelException.hxx" +#include "InterpKernelGeo2DAbstractEdge.hxx" +#include "InterpKernelGeo2DEdge.hxx" + +namespace INTERP_KERNEL +{ + class ElementaryEdge + { + public: + INTERPKERNEL_EXPORT ElementaryEdge(Edge *ptr, bool direction):_direction(direction),_ptr(ptr) { } + INTERPKERNEL_EXPORT ElementaryEdge(const ElementaryEdge& other); + INTERPKERNEL_EXPORT ~ElementaryEdge(); + INTERPKERNEL_EXPORT bool isThereStartPoint() const { return _iterator.isValid(); } + INTERPKERNEL_EXPORT IteratorOnComposedEdge& getIterator() { return _iterator; } + INTERPKERNEL_EXPORT bool completed() const { return false; } + INTERPKERNEL_EXPORT void declareOn() const { _ptr->declareOn(); } + INTERPKERNEL_EXPORT void declareIn() const { _ptr->declareIn(); } + INTERPKERNEL_EXPORT void declareOut() const { _ptr->declareOut(); } + INTERPKERNEL_EXPORT TypeOfEdgeLocInPolygon getLoc() const { return _ptr->getLoc(); } + INTERPKERNEL_EXPORT Edge *getPtr() const { return _ptr; } + INTERPKERNEL_EXPORT void reverse() { _direction=(!_direction); } + INTERPKERNEL_EXPORT bool isNodeIn(Node *n) const; + INTERPKERNEL_EXPORT double getAreaOfZone() const { double ret=_ptr->getAreaOfZone(); return _direction?ret:-ret; } + INTERPKERNEL_EXPORT void getBarycenterOfZone(double *bary) const; + INTERPKERNEL_EXPORT void fillBounds(Bounds& output) const; + INTERPKERNEL_EXPORT void applySimilarity(double xBary, double yBary, double dimChar) { _ptr->applySimilarity(xBary,yBary,dimChar); } + INTERPKERNEL_EXPORT void unApplySimilarity(double xBary, double yBary, double dimChar) { _ptr->unApplySimilarity(xBary,yBary,dimChar); } + INTERPKERNEL_EXPORT void getAllNodes(std::set<Node *>& output) const; + INTERPKERNEL_EXPORT void getBarycenter(double *bary, double& weigh) const; + INTERPKERNEL_EXPORT ElementaryEdge *clone() const; + INTERPKERNEL_EXPORT void initLocations() const; + INTERPKERNEL_EXPORT int size() const; + INTERPKERNEL_EXPORT TypeOfEdgeLocInPolygon locateFullyMySelfAbsolute(const ComposedEdge& pol) const; + INTERPKERNEL_EXPORT TypeOfEdgeLocInPolygon locateFullyMySelf(const ComposedEdge& pol, TypeOfEdgeLocInPolygon precEdgeLoc) const; + INTERPKERNEL_EXPORT Node *getEndNode() const; + INTERPKERNEL_EXPORT Node *getStartNode() const; + INTERPKERNEL_EXPORT double getCurveLength() const { return _ptr->getCurveLength(); } + INTERPKERNEL_EXPORT bool changeEndNodeWith(Node *node) const; + INTERPKERNEL_EXPORT bool changeStartNodeWith(Node *node) const; + INTERPKERNEL_EXPORT bool intresicEqual(const ElementaryEdge *other) const; + INTERPKERNEL_EXPORT bool intresicEqualDirSensitive(const ElementaryEdge *other) const; + INTERPKERNEL_EXPORT void dumpInXfigFile(std::ostream& stream, int resolution, const Bounds& box) const; + INTERPKERNEL_EXPORT bool getDirection() const { return _direction; } + INTERPKERNEL_EXPORT bool intresincEqCoarse(const Edge *other) const; + INTERPKERNEL_EXPORT bool isEqual(const ElementaryEdge& other) const; + public: + INTERPKERNEL_EXPORT void fillGlobalInfoAbs(const std::map<INTERP_KERNEL::Node *,int>& mapThis, const std::map<INTERP_KERNEL::Node *,int>& mapOther, int offset1, int offset2, double fact, double baryX, double baryY, + std::vector<int>& edgesThis, std::vector<double>& addCoo, std::map<INTERP_KERNEL::Node *,int> mapAddCoo) const; + INTERPKERNEL_EXPORT void fillGlobalInfoAbs2(const std::map<INTERP_KERNEL::Node *,int>& mapThis, const std::map<INTERP_KERNEL::Node *,int>& mapOther, int offset1, int offset2, double fact, double baryX, double baryY, + std::vector<int>& edgesOther, std::vector<double>& addCoo, std::map<INTERP_KERNEL::Node *,int>& mapAddCoo) const; + INTERPKERNEL_EXPORT static ElementaryEdge *BuildEdgeFromStartEndDir(bool direction, INTERP_KERNEL::Node *start, INTERP_KERNEL::Node *end); + private: + bool _direction; + Edge *_ptr; + IteratorOnComposedEdge _iterator; + }; +} + +#endif diff --git a/src/medtool/src/INTERP_KERNEL/Geometric2D/InterpKernelGeo2DNode.cxx b/src/medtool/src/INTERP_KERNEL/Geometric2D/InterpKernelGeo2DNode.cxx new file mode 100644 index 000000000..72072b9c2 --- /dev/null +++ b/src/medtool/src/INTERP_KERNEL/Geometric2D/InterpKernelGeo2DNode.cxx @@ -0,0 +1,198 @@ +// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 +// 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 "InterpKernelGeo2DNode.hxx" +#include "InterpKernelGeo2DEdgeArcCircle.hxx" + +using namespace INTERP_KERNEL; + +Node::Node(double x, double y):_cnt(1),_loc(UNKNOWN) +{ + _coords[0]=x; _coords[1]=y; +} + +Node::Node(const double *coords):_cnt(1),_loc(UNKNOWN) +{ + _coords[0]=coords[0]; + _coords[1]=coords[1]; +} + +Node::Node(std::istream& stream):_cnt(1),_loc(UNKNOWN) +{ + int tmp; + stream >> tmp; + _coords[0]=((double) tmp)/1e4; + stream >> tmp; + _coords[1]=((double) tmp)/1e4; +} + +Node::~Node() +{ +} + +bool Node::decrRef() +{ + bool ret=(--_cnt==0); + if(ret) + delete this; + return ret; +} + +bool Node::isEqual(const Node& other) const +{ + const unsigned SPACEDIM=2; + bool ret=true; + for(unsigned i=0;i<SPACEDIM;i++) + ret&=areDoubleEquals((*this)[i],other[i]); + return ret; +} + +double Node::getSlope(const Node& other) const +{ + return computeSlope(*this, other); +} + +/*! + * Convenient method. Equivalent to isEqual method. In case of true is returned, '&other' is + * added in 'track' container. + */ +bool Node::isEqualAndKeepTrack(const Node& other, std::vector<Node *>& track) const +{ + bool ret=isEqual(other); + if(ret) + track.push_back(const_cast<Node *>(&other)); + return ret; +} + +void Node::dumpInXfigFile(std::ostream& stream, int resolution, const Bounds& box) const +{ + stream << box.fitXForXFig(_coords[0],resolution) << " " << box.fitYForXFig(_coords[1],resolution) << " "; +} + +double Node::distanceWithSq(const Node& other) const +{ + return (_coords[0]-other._coords[0])*(_coords[0]-other._coords[0])+(_coords[1]-other._coords[1])*(_coords[1]-other._coords[1]); +} + +/*! + * WARNING different from 'computeAngle' method ! The returned value are not in the same interval ! + * Here in [0; Pi). Typically this method returns the same value by exchanging pt1 and pt2. + * Use in process of detection of a point in or not in polygon. + */ +double Node::computeSlope(const double *pt1, const double *pt2) +{ + double x=pt2[0]-pt1[0]; + double y=pt2[1]-pt1[1]; + double norm=sqrt(x*x+y*y); + double ret=EdgeArcCircle::SafeAcos(fabs(x)/norm); + if( (x>=0. && y>=0.) || (x<0. && y<0.) ) + return ret; + else + return M_PI-ret; +} + +/*! + * WARNING different from 'computeSlope' method. Here angle in -Pi;Pi is returned. + * This method is anti-symetric. + */ +double Node::computeAngle(const double *pt1, const double *pt2) +{ + double x=pt2[0]-pt1[0]; + double y=pt2[1]-pt1[1]; + double norm=sqrt(x*x+y*y); + return EdgeArcCircle::GetAbsoluteAngleOfNormalizedVect(x/norm,y/norm); +} + +/*! + * apply a Similarity transformation on this. + * @param xBary is the opposite of the X translation to do. + * @param yBary is the opposite of the Y translation to do. + * @param dimChar is the reduction factor. + */ +void Node::applySimilarity(double xBary, double yBary, double dimChar) +{ + _coords[0]=(_coords[0]-xBary)/dimChar; + _coords[1]=(_coords[1]-yBary)/dimChar; +} + +/*! + * apply the reverse Similarity transformation on this. + * This method is the opposite of Node::applySimilarity method to retrieve the initial state. + * @param xBary is the opposite of the X translation to do. + * @param yBary is the opposite of the Y translation to do. + * @param dimChar is the reduction factor. + */ +void Node::unApplySimilarity(double xBary, double yBary, double dimChar) +{ + _coords[0]=_coords[0]*dimChar+xBary; + _coords[1]=_coords[1]*dimChar+yBary; +} + +/*! + * Called by QuadraticPolygon::splitAbs method. + */ +void Node::fillGlobalInfoAbs(const std::map<INTERP_KERNEL::Node *,int>& mapThis, const std::map<INTERP_KERNEL::Node *,int>& mapOther, int offset1, int offset2, double fact, double baryX, double baryY, + std::vector<double>& addCoo, std::map<INTERP_KERNEL::Node *,int>& mapAddCoo, int *nodeId) const +{ + std::map<INTERP_KERNEL::Node *,int>::const_iterator it=mapThis.find(const_cast<Node *>(this)); + if(it!=mapThis.end()) + { + *nodeId=(*it).second; + return; + } + it=mapOther.find(const_cast<Node *>(this)); + if(it!=mapOther.end()) + { + *nodeId=(*it).second+offset1; + return; + } + it=mapAddCoo.find(const_cast<Node *>(this)); + if(it!=mapAddCoo.end()) + { + *nodeId=(*it).second; + return; + } + int id=(int)addCoo.size()/2; + addCoo.push_back(fact*_coords[0]+baryX); + addCoo.push_back(fact*_coords[1]+baryY); + *nodeId=offset2+id; + mapAddCoo[const_cast<Node *>(this)]=offset2+id; +} + +/*! + * Called by QuadraticPolygon::splitAbs method. + */ +void Node::fillGlobalInfoAbs2(const std::map<INTERP_KERNEL::Node *,int>& mapThis, const std::map<INTERP_KERNEL::Node *,int>& mapOther, int offset1, int offset2, double fact, double baryX, double baryY, + std::vector<double>& addCoo, std::map<INTERP_KERNEL::Node *,int>& mapAddCoo, std::vector<int>& pointsOther) const +{ + int tmp; + std::size_t sz1=addCoo.size(); + fillGlobalInfoAbs(mapThis,mapOther,offset1,offset2,fact,baryX,baryY,addCoo,mapAddCoo,&tmp); + if(sz1!=addCoo.size()) + { + pointsOther.push_back(tmp); + return ; + } + std::vector<int>::const_iterator it=std::find(pointsOther.begin(),pointsOther.end(),tmp); + if(it!=pointsOther.end()) + return ; + if(tmp<offset1) + pointsOther.push_back(tmp); +} diff --git a/src/medtool/src/INTERP_KERNEL/Geometric2D/InterpKernelGeo2DNode.hxx b/src/medtool/src/INTERP_KERNEL/Geometric2D/InterpKernelGeo2DNode.hxx new file mode 100644 index 000000000..0ea54cc1c --- /dev/null +++ b/src/medtool/src/INTERP_KERNEL/Geometric2D/InterpKernelGeo2DNode.hxx @@ -0,0 +1,111 @@ +// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 +// 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 __INTERPKERNELGEO2DNODE_HXX__ +#define __INTERPKERNELGEO2DNODE_HXX__ + +#include "InterpKernelGeo2DPrecision.hxx" +#include "INTERPKERNELDefines.hxx" + +#include <map> +#include <cmath> +#include <vector> +#include <iostream> + +namespace INTERP_KERNEL +{ + typedef enum + { + IN_1 = 7, + ON_1 = 8, + ON_LIM_1 = 12, + ON_TANG_1 = 9, + OUT_1 = 10, + UNKNOWN = 11 + } TypeOfLocInPolygon; + + class Bounds; + + /*! + * Representation of a 2D point, and potentially its location relative to a polygon. + * As nodes can be shared between edges it is handled with ref counting. + */ + class INTERPKERNEL_EXPORT Node + { + public: + Node(double x, double y); + Node(const double *coords); + Node(std::istream& stream); + void incrRef() const { _cnt++; } + bool decrRef(); + void initHitStatus() const { _hit=0; } + char getHitStatus() const { return _hit; } + void hitMeAlone(double xBary, double yBary, double dimChar) { if(_hit==0) { _hit=1; applySimilarity(xBary,yBary,dimChar); } } + void unHitMeAlone(double xBary, double yBary, double dimChar) { if(_hit==0) { _hit=1; unApplySimilarity(xBary,yBary,dimChar); } } + void hitMeAfter(double xBary, double yBary, double dimChar) { if(_hit==0) { hitMeAlone(xBary,yBary,dimChar); _hit=2; } else if(_hit==1) declareOn(); } + void unHitMeAfter(double xBary, double yBary, double dimChar) { if(_hit==0) { unHitMeAlone(xBary,yBary,dimChar); _hit=2; } } + void initLocs() const { _loc=UNKNOWN; } + void setLoc(TypeOfLocInPolygon loc) const { _loc=loc; } + TypeOfLocInPolygon getLoc() const { return _loc; } + void declareIn() const { if(_loc==UNKNOWN) _loc=IN_1; } + void declareOn() const { if(_loc==UNKNOWN) _loc=ON_1; } + void declareOnLim() const { if(_loc==UNKNOWN || _loc==ON_1) _loc=ON_LIM_1; } + void declareOut() { if(_loc==UNKNOWN) _loc=OUT_1; } + void declareOnTangent() { _loc=ON_TANG_1; } + operator const double*() const { return _coords; } + bool isEqual(const Node& other) const; + //returns an angle in -Pi/2;Pi/2. + double getSlope(const Node& other) const; + bool isEqualAndKeepTrack(const Node& other, std::vector<Node *>& track) const; + void dumpInXfigFile(std::ostream& stream, int resolution, const Bounds& box) const; + double distanceWithSq(const Node& other) const; + double operator[](int i) const { return _coords[i]; } + //! use with caution + void setNewCoords(double x, double y) { _coords[0]=x; _coords[1]=y; } + //returns an angle in -Pi/2;Pi/2. + static double computeSlope(const double *pt1, const double *pt2); + //returns an angle in -Pi;Pi + static double computeAngle(const double *pt1, const double *pt2); + void applySimilarity(double xBary, double yBary, double dimChar); + void unApplySimilarity(double xBary, double yBary, double dimChar); + static double dot(const double *vect1, const double *vect2) { return vect1[0]*vect2[0]+vect1[1]*vect2[1]; } + static double sign(double val) { if(val>=0) return 1.; else return -1.; } + static double norm(const double *vect) { return sqrt(vect[0]*vect[0]+vect[1]*vect[1]); } + static bool areDoubleEquals(double a, double b) { return fabs(a-b) < QUADRATIC_PLANAR::_precision; } + //! idem areDoubleEquals except that precision of comparison is modified. + static bool areDoubleEqualsWP(double a, double b, double k) { return fabs(a-b) < k*QUADRATIC_PLANAR::_precision; } + static double distanceBtw2Pt(const double *a, const double *b) { return sqrt((a[0]-b[0])*(a[0]-b[0])+(a[1]-b[1])*(a[1]-b[1])); } + static double distanceBtw2PtSq(const double *a, const double *b) { return (a[0]-b[0])*(a[0]-b[0])+(a[1]-b[1])*(a[1]-b[1]); } + // + void fillGlobalInfoAbs(const std::map<INTERP_KERNEL::Node *,int>& mapThis, const std::map<INTERP_KERNEL::Node *,int>& mapOther, int offset1, int offset2, double fact, double baryX, double baryY, + std::vector<double>& addCoo, std::map<INTERP_KERNEL::Node *,int>& mapAddCoo, int *nodeId) const; + void fillGlobalInfoAbs2(const std::map<INTERP_KERNEL::Node *,int>& mapThis, const std::map<INTERP_KERNEL::Node *,int>& mapOther, int offset1, int offset2, double fact, double baryX, double baryY, + std::vector<double>& addCoo, std::map<INTERP_KERNEL::Node *,int>& mapAddCoo, std::vector<int>& pointsOther) const; + protected: + ~Node(); + protected: + mutable char _hit; + mutable unsigned char _cnt; + mutable TypeOfLocInPolygon _loc; + double _coords[2]; + }; +} + +#endif diff --git a/src/medtool/src/INTERP_KERNEL/Geometric2D/InterpKernelGeo2DPrecision.cxx b/src/medtool/src/INTERP_KERNEL/Geometric2D/InterpKernelGeo2DPrecision.cxx new file mode 100644 index 000000000..14666d9d9 --- /dev/null +++ b/src/medtool/src/INTERP_KERNEL/Geometric2D/InterpKernelGeo2DPrecision.cxx @@ -0,0 +1,35 @@ +// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 +// 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 "InterpKernelGeo2DPrecision.hxx" + +double INTERP_KERNEL::QUADRATIC_PLANAR::_precision=1e-14; + +double INTERP_KERNEL::QUADRATIC_PLANAR::_arc_detection_precision=1e-14; + +void INTERP_KERNEL::QUADRATIC_PLANAR::setPrecision(double precision) +{ + INTERP_KERNEL::QUADRATIC_PLANAR::_precision=precision; +} + +void INTERP_KERNEL::QUADRATIC_PLANAR::setArcDetectionPrecision(double precision) +{ + INTERP_KERNEL::QUADRATIC_PLANAR::_arc_detection_precision=precision; +} diff --git a/src/medtool/src/INTERP_KERNEL/Geometric2D/InterpKernelGeo2DPrecision.hxx b/src/medtool/src/INTERP_KERNEL/Geometric2D/InterpKernelGeo2DPrecision.hxx new file mode 100644 index 000000000..4d494abce --- /dev/null +++ b/src/medtool/src/INTERP_KERNEL/Geometric2D/InterpKernelGeo2DPrecision.hxx @@ -0,0 +1,38 @@ +// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 +// 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 __INTERPKERNELGEO2DPRECISION_HXX__ +#define __INTERPKERNELGEO2DPRECISION_HXX__ + +#include "INTERPKERNELDefines.hxx" + +namespace INTERP_KERNEL +{ + class INTERPKERNEL_EXPORT QUADRATIC_PLANAR + { + public: + static double _precision; + static double _arc_detection_precision; + static void setPrecision(double precision); + static void setArcDetectionPrecision(double precision); + }; +} + +#endif diff --git a/src/medtool/src/INTERP_KERNEL/Geometric2D/InterpKernelGeo2DQuadraticPolygon.cxx b/src/medtool/src/INTERP_KERNEL/Geometric2D/InterpKernelGeo2DQuadraticPolygon.cxx new file mode 100644 index 000000000..caed9530b --- /dev/null +++ b/src/medtool/src/INTERP_KERNEL/Geometric2D/InterpKernelGeo2DQuadraticPolygon.cxx @@ -0,0 +1,1286 @@ +// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 +// 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 "InterpKernelGeo2DQuadraticPolygon.hxx" +#include "InterpKernelGeo2DElementaryEdge.hxx" +#include "InterpKernelGeo2DEdgeArcCircle.hxx" +#include "InterpKernelGeo2DAbstractEdge.hxx" +#include "InterpKernelGeo2DEdgeLin.hxx" +#include "InterpKernelGeo2DBounds.hxx" +#include "InterpKernelGeo2DEdge.txx" + +#include "NormalizedUnstructuredMesh.hxx" + +#include <fstream> +#include <sstream> +#include <iomanip> +#include <cstring> +#include <limits> + +using namespace INTERP_KERNEL; + +namespace INTERP_KERNEL +{ + const unsigned MAX_SIZE_OF_LINE_XFIG_FILE=1024; +} + +QuadraticPolygon::QuadraticPolygon(const char *file) +{ + char currentLine[MAX_SIZE_OF_LINE_XFIG_FILE]; + std::ifstream stream(file); + stream.exceptions(std::ios_base::eofbit); + try + { + do + stream.getline(currentLine,MAX_SIZE_OF_LINE_XFIG_FILE); + while(strcmp(currentLine,"1200 2")!=0); + do + { + Edge *newEdge=Edge::BuildFromXfigLine(stream); + if(!empty()) + newEdge->changeStartNodeWith(back()->getEndNode()); + pushBack(newEdge); + } + while(1); + } + catch(std::ifstream::failure&) + { + } + front()->changeStartNodeWith(back()->getEndNode()); +} + +QuadraticPolygon::~QuadraticPolygon() +{ +} + +QuadraticPolygon *QuadraticPolygon::BuildLinearPolygon(std::vector<Node *>& nodes) +{ + QuadraticPolygon *ret(new QuadraticPolygon); + std::size_t size=nodes.size(); + for(std::size_t i=0;i<size;i++) + { + ret->pushBack(new EdgeLin(nodes[i],nodes[(i+1)%size])); + nodes[i]->decrRef(); + } + return ret; +} + +QuadraticPolygon *QuadraticPolygon::BuildArcCirclePolygon(std::vector<Node *>& nodes) +{ + QuadraticPolygon *ret(new QuadraticPolygon); + std::size_t size=nodes.size(); + for(std::size_t i=0;i<size/2;i++) + + { + EdgeLin *e1,*e2; + e1=new EdgeLin(nodes[i],nodes[i+size/2]); + e2=new EdgeLin(nodes[i+size/2],nodes[(i+1)%(size/2)]); + SegSegIntersector inters(*e1,*e2); + bool colinearity=inters.areColinears(); + delete e1; delete e2; + if(colinearity) + ret->pushBack(new EdgeLin(nodes[i],nodes[(i+1)%(size/2)])); + else + ret->pushBack(new EdgeArcCircle(nodes[i],nodes[i+size/2],nodes[(i+1)%(size/2)])); + nodes[i]->decrRef(); nodes[i+size/2]->decrRef(); + } + return ret; +} + +Edge *QuadraticPolygon::BuildLinearEdge(std::vector<Node *>& nodes) +{ + if(nodes.size()!=2) + throw INTERP_KERNEL::Exception("QuadraticPolygon::BuildLinearEdge : input vector is expected to be of size 2 !"); + Edge *ret(new EdgeLin(nodes[0],nodes[1])); + nodes[0]->decrRef(); nodes[1]->decrRef(); + return ret; +} + +Edge *QuadraticPolygon::BuildArcCircleEdge(std::vector<Node *>& nodes) +{ + if(nodes.size()!=3) + throw INTERP_KERNEL::Exception("QuadraticPolygon::BuildArcCircleEdge : input vector is expected to be of size 3 !"); + EdgeLin *e1(new EdgeLin(nodes[0],nodes[2])),*e2(new EdgeLin(nodes[2],nodes[1])); + SegSegIntersector inters(*e1,*e2); + bool colinearity=inters.areColinears(); + delete e1; delete e2; + Edge *ret(0); + if(colinearity) + ret=new EdgeLin(nodes[0],nodes[1]); + else + ret=new EdgeArcCircle(nodes[0],nodes[2],nodes[1]); + nodes[0]->decrRef(); nodes[1]->decrRef(); nodes[2]->decrRef(); + return ret; +} + +void QuadraticPolygon::BuildDbgFile(const std::vector<Node *>& nodes, const char *fileName) +{ + std::ofstream file(fileName); + file << std::setprecision(16); + file << " double coords[]=" << std::endl << " { "; + for(std::vector<Node *>::const_iterator iter=nodes.begin();iter!=nodes.end();iter++) + { + if(iter!=nodes.begin()) + file << "," << std::endl << " "; + file << (*(*iter))[0] << ", " << (*(*iter))[1]; + } + file << "};" << std::endl; +} + +void QuadraticPolygon::closeMe() const +{ + if(!front()->changeStartNodeWith(back()->getEndNode())) + throw(Exception("big error: not closed polygon...")); +} + +void QuadraticPolygon::circularPermute() +{ + if(_sub_edges.size()>1) + { + ElementaryEdge *first=_sub_edges.front(); + _sub_edges.pop_front(); + _sub_edges.push_back(first); + } +} + +bool QuadraticPolygon::isButterflyAbs() +{ + INTERP_KERNEL::Bounds b; + double xBary,yBary; + b.prepareForAggregation(); + fillBounds(b); + double dimChar=b.getCaracteristicDim(); + b.getBarycenter(xBary,yBary); + applyGlobalSimilarity(xBary,yBary,dimChar); + // + return isButterfly(); +} + +bool QuadraticPolygon::isButterfly() const +{ + for(std::list<ElementaryEdge *>::const_iterator it=_sub_edges.begin();it!=_sub_edges.end();it++) + { + Edge *e1=(*it)->getPtr(); + std::list<ElementaryEdge *>::const_iterator it2=it; + it2++; + for(;it2!=_sub_edges.end();it2++) + { + MergePoints commonNode; + ComposedEdge *outVal1=new ComposedEdge; + ComposedEdge *outVal2=new ComposedEdge; + Edge *e2=(*it2)->getPtr(); + if(e1->intersectWith(e2,commonNode,*outVal1,*outVal2)) + { + Delete(outVal1); + Delete(outVal2); + return true; + } + Delete(outVal1); + Delete(outVal2); + } + } + return false; +} + +void QuadraticPolygon::dumpInXfigFileWithOther(const ComposedEdge& other, const char *fileName) const +{ + std::ofstream file(fileName); + const int resolution=1200; + Bounds box; + box.prepareForAggregation(); + fillBounds(box); + other.fillBounds(box); + dumpInXfigFile(file,resolution,box); + other.ComposedEdge::dumpInXfigFile(file,resolution,box); +} + +void QuadraticPolygon::dumpInXfigFile(const char *fileName) const +{ + std::ofstream file(fileName); + const int resolution=1200; + Bounds box; + box.prepareForAggregation(); + fillBounds(box); + dumpInXfigFile(file,resolution,box); +} + +void QuadraticPolygon::dumpInXfigFile(std::ostream& stream, int resolution, const Bounds& box) const +{ + stream << "#FIG 3.2 Produced by xfig version 3.2.5-alpha5" << std::endl; + stream << "Landscape" << std::endl; + stream << "Center" << std::endl; + stream << "Metric" << std::endl; + stream << "Letter" << std::endl; + stream << "100.00" << std::endl; + stream << "Single" << std::endl; + stream << "-2" << std::endl; + stream << resolution << " 2" << std::endl; + ComposedEdge::dumpInXfigFile(stream,resolution,box); +} + +/*! + * Warning contrary to intersectWith method this method is \b NOT const. 'this' and 'other' are modified after call of this method. + */ +double QuadraticPolygon::intersectWithAbs(QuadraticPolygon& other) +{ + double ret=0.,xBaryBB,yBaryBB; + double fact=normalize(&other,xBaryBB,yBaryBB); + std::vector<QuadraticPolygon *> polygs=intersectMySelfWith(other); + for(std::vector<QuadraticPolygon *>::iterator iter=polygs.begin();iter!=polygs.end();iter++) + { + ret+=fabs((*iter)->getArea()); + delete *iter; + } + return ret*fact*fact; +} + +/*! + * This method splits 'this' with 'other' into smaller pieces localizable. 'mapThis' is a map that gives the correspondance + * between nodes contained in 'this' and node ids in a global mesh. + * In the same way, 'mapOther' gives the correspondance between nodes contained in 'other' and node ids in a + * global mesh from wich 'other' is extracted. + * This method has 1 out paramater : 'edgesThis', After the call of this method, it contains the nodal connectivity (including type) + * of 'this' into globlal "this mesh". + * This method has 2 in/out parameters : 'subDivOther' and 'addCoo'.'otherEdgeIds' is useful to put values in + * 'edgesThis', 'subDivOther' and 'addCoo'. + * Size of 'otherEdgeIds' has to be equal to number of ElementaryEdges in 'other'. No check of that will be done. + * The term 'abs' in the name recalls that we normalize the mesh (spatially) so that node coordinates fit into [0;1]. + * @param offset1 is the number of nodes contained in global mesh from which 'this' is extracted. + * @param offset2 is the sum of nodes contained in global mesh from which 'this' is extracted and 'other' is extracted. + * @param edgesInOtherColinearWithThis will be appended at the end of the vector with colinear edge ids of other (if any) + * @param otherEdgeIds is a vector with the same size than other before calling this method. It gives in the same order + * the cell id in global other mesh. + */ +void QuadraticPolygon::splitAbs(QuadraticPolygon& other, + const std::map<INTERP_KERNEL::Node *,int>& mapThis, const std::map<INTERP_KERNEL::Node *,int>& mapOther, + int offset1, int offset2 , + const std::vector<int>& otherEdgeIds, + std::vector<int>& edgesThis, int cellIdThis, + std::vector< std::vector<int> >& edgesInOtherColinearWithThis, std::vector< std::vector<int> >& subDivOther, + std::vector<double>& addCoo, std::map<int,int>& mergedNodes) +{ + double xBaryBB, yBaryBB; + double fact=normalizeExt(&other, xBaryBB, yBaryBB); + // + IteratorOnComposedEdge it1(this),it3(&other); + MergePoints merge; + ComposedEdge *c1=new ComposedEdge; + ComposedEdge *c2=new ComposedEdge; + int i=0; + std::map<INTERP_KERNEL::Node *,int> mapAddCoo; + for(it3.first();!it3.finished();it3.next(),i++)//iteration over 'other' _sub_edges + { + QuadraticPolygon otherTmp; + ElementaryEdge* curE3=it3.current(); + otherTmp.pushBack(new ElementaryEdge(curE3->getPtr(),curE3->getDirection())); curE3->getPtr()->incrRef(); + IteratorOnComposedEdge it2(&otherTmp); + for(it2.first();!it2.finished();it2.next())//iteration on subedges of 'other->_sub_edge' + { + ElementaryEdge* curE2=it2.current(); + if(!curE2->isThereStartPoint()) + it1.first(); + else + it1=curE2->getIterator(); + for(;!it1.finished();)//iteration over 'this' _sub_edges + { + ElementaryEdge* curE1=it1.current(); + merge.clear(); + // + std::map<INTERP_KERNEL::Node *,int>::const_iterator thisStart(mapThis.find(curE1->getStartNode())),thisEnd(mapThis.find(curE1->getEndNode())),otherStart(mapOther.find(curE2->getStartNode())),otherEnd(mapOther.find(curE2->getEndNode())); + int thisStart2(thisStart==mapThis.end()?-1:(*thisStart).second),thisEnd2(thisEnd==mapThis.end()?-1:(*thisEnd).second),otherStart2(otherStart==mapOther.end()?-1:(*otherStart).second+offset1),otherEnd2(otherEnd==mapOther.end()?-1:(*otherEnd).second+offset1); + // + if(curE1->getPtr()->intersectWith(curE2->getPtr(),merge,*c1,*c2)) + { + if(!curE1->getDirection()) c1->reverse(); + if(!curE2->getDirection()) c2->reverse(); + UpdateNeighbours(merge,it1,it2,c1,c2); + //Substitution of simple edge by sub-edges. + delete curE1; // <-- destroying simple edge coming from pol1 + delete curE2; // <-- destroying simple edge coming from pol2 + it1.insertElemEdges(c1,true);// <-- 2nd param is true to go next. + it2.insertElemEdges(c2,false);// <-- 2nd param is false to avoid to go next. + curE2=it2.current(); + // + it1.assignMySelfToAllElems(c2);//To avoid that others + SoftDelete(c1); + SoftDelete(c2); + c1=new ComposedEdge; + c2=new ComposedEdge; + } + else + { + UpdateNeighbours(merge,it1,it2,curE1,curE2); + it1.next(); + } + merge.updateMergedNodes(thisStart2,thisEnd2,otherStart2,otherEnd2,mergedNodes); + } + } + if(otherTmp.presenceOfOn()) + edgesInOtherColinearWithThis[otherEdgeIds[i]].push_back(cellIdThis); + if(otherTmp._sub_edges.size()>1) + { + for(std::list<ElementaryEdge *>::const_iterator it=otherTmp._sub_edges.begin();it!=otherTmp._sub_edges.end();it++) + (*it)->fillGlobalInfoAbs2(mapThis,mapOther,offset1,offset2,/**/fact,xBaryBB,yBaryBB,/**/subDivOther[otherEdgeIds[i]],addCoo,mapAddCoo); + } + } + Delete(c1); + Delete(c2); + // + for(std::list<ElementaryEdge *>::const_iterator it=_sub_edges.begin();it!=_sub_edges.end();it++) + (*it)->fillGlobalInfoAbs(mapThis,mapOther,offset1,offset2,/**/fact,xBaryBB,yBaryBB,/**/edgesThis,addCoo,mapAddCoo); + // +} + +/*! + * This method builds 'this' from its descending conn stored in crude mode (MEDCoupling). + * Descending conn is in FORTRAN relative mode in order to give the + * orientation of edge (see buildDescendingConnectivity2() method). + * See appendEdgeFromCrudeDataArray() for params description. + */ +void QuadraticPolygon::buildFromCrudeDataArray(const std::map<int,INTERP_KERNEL::Node *>& mapp, bool isQuad, const int *nodalBg, const double *coords, + const int *descBg, const int *descEnd, const std::vector<std::vector<int> >& intersectEdges) +{ + std::size_t nbOfSeg=std::distance(descBg,descEnd); + for(std::size_t i=0;i<nbOfSeg;i++) + { + appendEdgeFromCrudeDataArray(i,mapp,isQuad,nodalBg,coords,descBg,descEnd,intersectEdges); + } +} + +void QuadraticPolygon::appendEdgeFromCrudeDataArray(std::size_t edgePos, const std::map<int,INTERP_KERNEL::Node *>& mapp, bool isQuad, + const int *nodalBg, const double *coords, + const int *descBg, const int *descEnd, const std::vector<std::vector<int> >& intersectEdges) +{ + if(!isQuad) + { + bool direct=descBg[edgePos]>0; + int edgeId=abs(descBg[edgePos])-1; // back to C indexing mode + const std::vector<int>& subEdge=intersectEdges[edgeId]; + std::size_t nbOfSubEdges=subEdge.size()/2; + for(std::size_t j=0;j<nbOfSubEdges;j++) + appendSubEdgeFromCrudeDataArray(0,j,direct,edgeId,subEdge,mapp); + } + else + { + std::size_t nbOfSeg=std::distance(descBg,descEnd); + const double *st=coords+2*(nodalBg[edgePos]); + INTERP_KERNEL::Node *st0=new INTERP_KERNEL::Node(st[0],st[1]); + const double *endd=coords+2*(nodalBg[(edgePos+1)%nbOfSeg]); + INTERP_KERNEL::Node *endd0=new INTERP_KERNEL::Node(endd[0],endd[1]); + const double *middle=coords+2*(nodalBg[edgePos+nbOfSeg]); + INTERP_KERNEL::Node *middle0=new INTERP_KERNEL::Node(middle[0],middle[1]); + EdgeLin *e1,*e2; + e1=new EdgeLin(st0,middle0); + e2=new EdgeLin(middle0,endd0); + SegSegIntersector inters(*e1,*e2); + bool colinearity=inters.areColinears(); + delete e1; delete e2; + // + bool direct=descBg[edgePos]>0; + int edgeId=abs(descBg[edgePos])-1; + const std::vector<int>& subEdge=intersectEdges[edgeId]; + std::size_t nbOfSubEdges=subEdge.size()/2; + if(colinearity) + { + for(std::size_t j=0;j<nbOfSubEdges;j++) + appendSubEdgeFromCrudeDataArray(0,j,direct,edgeId,subEdge,mapp); + } + else + { + Edge *e=new EdgeArcCircle(st0,middle0,endd0,true); + for(std::size_t j=0;j<nbOfSubEdges;j++) + appendSubEdgeFromCrudeDataArray(e,j,direct,edgeId,subEdge,mapp); + e->decrRef(); + } + st0->decrRef(); endd0->decrRef(); middle0->decrRef(); + } +} + +void QuadraticPolygon::appendSubEdgeFromCrudeDataArray(Edge *baseEdge, std::size_t j, bool direct, int edgeId, const std::vector<int>& subEdge, const std::map<int,INTERP_KERNEL::Node *>& mapp) +{ + std::size_t nbOfSubEdges=subEdge.size()/2; + if(!baseEdge) + {//it is not a quadratic subedge + Node *start=(*mapp.find(direct?subEdge[2*j]:subEdge[2*nbOfSubEdges-2*j-1])).second; + Node *end=(*mapp.find(direct?subEdge[2*j+1]:subEdge[2*nbOfSubEdges-2*j-2])).second; + ElementaryEdge *e=ElementaryEdge::BuildEdgeFromStartEndDir(true,start,end); + pushBack(e); + } + else + {//it is a quadratic subedge + Node *start=(*mapp.find(direct?subEdge[2*j]:subEdge[2*nbOfSubEdges-2*j-1])).second; + Node *end=(*mapp.find(direct?subEdge[2*j+1]:subEdge[2*nbOfSubEdges-2*j-2])).second; + Edge *ee=baseEdge->buildEdgeLyingOnMe(start,end); + ElementaryEdge *eee=new ElementaryEdge(ee,true); + pushBack(eee); + } +} + +/*! + * This method builds from descending conn of a quadratic polygon stored in crude mode (MEDCoupling). Descending conn is in FORTRAN relative mode in order to give the + * orientation of edge. + */ +void QuadraticPolygon::buildFromCrudeDataArray2(const std::map<int,INTERP_KERNEL::Node *>& mapp, bool isQuad, const int *nodalBg, const double *coords, const int *descBg, const int *descEnd, const std::vector<std::vector<int> >& intersectEdges, + const INTERP_KERNEL::QuadraticPolygon& pol1, const int *descBg1, const int *descEnd1, const std::vector<std::vector<int> >& intersectEdges1, + const std::vector< std::vector<int> >& colinear1, + std::map<int,std::vector<INTERP_KERNEL::ElementaryEdge *> >& alreadyExistingIn2) +{ + std::size_t nbOfSeg=std::distance(descBg,descEnd); + for(std::size_t i=0;i<nbOfSeg;i++)//loop over all edges of pol2 + { + bool direct=descBg[i]>0; + int edgeId=abs(descBg[i])-1;//current edge id of pol2 + std::map<int,std::vector<INTERP_KERNEL::ElementaryEdge *> >::const_iterator it1=alreadyExistingIn2.find(descBg[i]),it2=alreadyExistingIn2.find(-descBg[i]); + if(it1!=alreadyExistingIn2.end() || it2!=alreadyExistingIn2.end()) + { + bool sameDir=(it1!=alreadyExistingIn2.end()); + const std::vector<INTERP_KERNEL::ElementaryEdge *>& edgesAlreadyBuilt=sameDir?(*it1).second:(*it2).second; + if(sameDir) + { + for(std::vector<INTERP_KERNEL::ElementaryEdge *>::const_iterator it3=edgesAlreadyBuilt.begin();it3!=edgesAlreadyBuilt.end();it3++) + { + Edge *ee=(*it3)->getPtr(); ee->incrRef(); + pushBack(new ElementaryEdge(ee,(*it3)->getDirection())); + } + } + else + { + for(std::vector<INTERP_KERNEL::ElementaryEdge *>::const_reverse_iterator it4=edgesAlreadyBuilt.rbegin();it4!=edgesAlreadyBuilt.rend();it4++) + { + Edge *ee=(*it4)->getPtr(); ee->incrRef(); + pushBack(new ElementaryEdge(ee,!(*it4)->getDirection())); + } + } + continue; + } + bool directos=colinear1[edgeId].empty(); + std::vector<std::pair<int,std::pair<bool,int> > > idIns1; + int offset1=0; + if(!directos) + {// if the current edge of pol2 has one or more colinear edges part into pol1 + const std::vector<int>& c=colinear1[edgeId]; + std::size_t nbOfEdgesIn1=std::distance(descBg1,descEnd1); + for(std::size_t j=0;j<nbOfEdgesIn1;j++) + { + int edgeId1=abs(descBg1[j])-1; + if(std::find(c.begin(),c.end(),edgeId1)!=c.end()) + { + idIns1.push_back(std::pair<int,std::pair<bool,int> >(edgeId1,std::pair<bool,int>(descBg1[j]>0,offset1)));// it exists an edge into pol1 given by tuple (idIn1,direct1) that is colinear at edge 'edgeId' in pol2 + //std::pair<edgeId1); direct1=descBg1[j]>0; + } + offset1+=intersectEdges1[edgeId1].size()/2;//offset1 is used to find the INTERP_KERNEL::Edge * instance into pol1 that will be part of edge into pol2 + } + directos=idIns1.empty(); + } + if(directos) + {//no subpart of edge 'edgeId' of pol2 is in pol1 so let's operate the same thing that QuadraticPolygon::buildFromCrudeDataArray method + std::size_t oldSz=_sub_edges.size(); + appendEdgeFromCrudeDataArray(i,mapp,isQuad,nodalBg,coords,descBg,descEnd,intersectEdges); + std::size_t newSz=_sub_edges.size(); + std::size_t zeSz=newSz-oldSz; + alreadyExistingIn2[descBg[i]].resize(zeSz); + std::list<ElementaryEdge *>::const_reverse_iterator it5=_sub_edges.rbegin(); + for(std::size_t p=0;p<zeSz;p++,it5++) + alreadyExistingIn2[descBg[i]][zeSz-p-1]=*it5; + } + else + {//there is subpart of edge 'edgeId' of pol2 inside pol1 + const std::vector<int>& subEdge=intersectEdges[edgeId]; + std::size_t nbOfSubEdges=subEdge.size()/2; + for(std::size_t j=0;j<nbOfSubEdges;j++) + { + int idBg=direct?subEdge[2*j]:subEdge[2*nbOfSubEdges-2*j-1]; + int idEnd=direct?subEdge[2*j+1]:subEdge[2*nbOfSubEdges-2*j-2]; + bool direction11,found=false; + bool direct1;//store if needed the direction in 1 + int offset2; + std::size_t nbOfSubEdges1; + for(std::vector<std::pair<int,std::pair<bool,int> > >::const_iterator it=idIns1.begin();it!=idIns1.end() && !found;it++) + { + int idIn1=(*it).first;//store if needed the cell id in 1 + direct1=(*it).second.first; + offset1=(*it).second.second; + const std::vector<int>& subEdge1PossiblyAlreadyIn1=intersectEdges1[idIn1]; + nbOfSubEdges1=subEdge1PossiblyAlreadyIn1.size()/2; + offset2=0; + for(std::size_t k=0;k<nbOfSubEdges1 && !found;k++) + {//perform a loop on all subedges of pol1 that includes edge 'edgeId' of pol2. For the moment we iterate only on subedges of ['idIn1']... To improve + if(subEdge1PossiblyAlreadyIn1[2*k]==idBg && subEdge1PossiblyAlreadyIn1[2*k+1]==idEnd) + { direction11=true; found=true; } + else if(subEdge1PossiblyAlreadyIn1[2*k]==idEnd && subEdge1PossiblyAlreadyIn1[2*k+1]==idBg) + { direction11=false; found=true; } + else + offset2++; + } + } + if(!found) + {//the current subedge of edge 'edgeId' of pol2 is not a part of the colinear edge 'idIn1' of pol1 -> build new Edge instance + //appendEdgeFromCrudeDataArray(j,mapp,isQuad,nodalBg,coords,descBg,descEnd,intersectEdges); + Node *start=(*mapp.find(idBg)).second; + Node *end=(*mapp.find(idEnd)).second; + ElementaryEdge *e=ElementaryEdge::BuildEdgeFromStartEndDir(true,start,end); + pushBack(e); + alreadyExistingIn2[descBg[i]].push_back(e); + } + else + {//the current subedge of edge 'edgeId' of pol2 is part of the colinear edge 'idIn1' of pol1 -> reuse Edge instance of pol1 + ElementaryEdge *e=pol1[offset1+(direct1?offset2:nbOfSubEdges1-offset2-1)]; + Edge *ee=e->getPtr(); + ee->incrRef(); + ElementaryEdge *e2=new ElementaryEdge(ee,!(direct1^direction11)); + pushBack(e2); + alreadyExistingIn2[descBg[i]].push_back(e2); + } + } + } + } +} + +/*! + * Method expected to be called on pol2. Every params not suffixed by numbered are supposed to refer to pol2 (this). + * Method to find edges that are ON. + */ +void QuadraticPolygon::updateLocOfEdgeFromCrudeDataArray2(const int *descBg, const int *descEnd, const std::vector<std::vector<int> >& intersectEdges, + const INTERP_KERNEL::QuadraticPolygon& pol1, const int *descBg1, const int *descEnd1, + const std::vector<std::vector<int> >& intersectEdges1, const std::vector< std::vector<int> >& colinear1) const +{ + std::size_t nbOfSeg=std::distance(descBg,descEnd); + for(std::size_t i=0;i<nbOfSeg;i++)//loop over all edges of pol2 + { + bool direct=descBg[i]>0; + int edgeId=abs(descBg[i])-1;//current edge id of pol2 + const std::vector<int>& c=colinear1[edgeId]; + if(c.empty()) + continue; + const std::vector<int>& subEdge=intersectEdges[edgeId]; + std::size_t nbOfSubEdges=subEdge.size()/2; + // + std::size_t nbOfEdgesIn1=std::distance(descBg1,descEnd1); + int offset1=0; + for(std::size_t j=0;j<nbOfEdgesIn1;j++) + { + int edgeId1=abs(descBg1[j])-1; + if(std::find(c.begin(),c.end(),edgeId1)!=c.end()) + { + for(std::size_t k=0;k<nbOfSubEdges;k++) + { + int idBg=direct?subEdge[2*k]:subEdge[2*nbOfSubEdges-2*k-1]; + int idEnd=direct?subEdge[2*k+1]:subEdge[2*nbOfSubEdges-2*k-2]; + int idIn1=edgeId1; + bool direct1=descBg1[j]>0; + const std::vector<int>& subEdge1PossiblyAlreadyIn1=intersectEdges1[idIn1]; + std::size_t nbOfSubEdges1=subEdge1PossiblyAlreadyIn1.size()/2; + int offset2=0; + bool found=false; + for(std::size_t kk=0;kk<nbOfSubEdges1 && !found;kk++) + { + found=(subEdge1PossiblyAlreadyIn1[2*kk]==idBg && subEdge1PossiblyAlreadyIn1[2*kk+1]==idEnd) || (subEdge1PossiblyAlreadyIn1[2*kk]==idEnd && subEdge1PossiblyAlreadyIn1[2*kk+1]==idBg); + if(!found) + offset2++; + } + if(found) + { + ElementaryEdge *e=pol1[offset1+(direct1?offset2:nbOfSubEdges1-offset2-1)]; + e->getPtr()->declareOn(); + } + } + } + offset1+=intersectEdges1[edgeId1].size()/2;//offset1 is used to find the INTERP_KERNEL::Edge * instance into pol1 that will be part of edge into pol2 + } + } +} + +void QuadraticPolygon::appendCrudeData(const std::map<INTERP_KERNEL::Node *,int>& mapp, double xBary, double yBary, double fact, int offset, std::vector<double>& addCoordsQuadratic, std::vector<int>& conn, std::vector<int>& connI) const +{ + int nbOfNodesInPg=0; + bool presenceOfQuadratic=presenceOfQuadraticEdge(); + conn.push_back(presenceOfQuadratic?NORM_QPOLYG:NORM_POLYGON); + for(std::list<ElementaryEdge *>::const_iterator it=_sub_edges.begin();it!=_sub_edges.end();it++) + { + Node *tmp=0; + tmp=(*it)->getStartNode(); + std::map<INTERP_KERNEL::Node *,int>::const_iterator it1=mapp.find(tmp); + conn.push_back((*it1).second); + nbOfNodesInPg++; + } + if(presenceOfQuadratic) + { + int j=0; + int off=offset+((int)addCoordsQuadratic.size())/2; + for(std::list<ElementaryEdge *>::const_iterator it=_sub_edges.begin();it!=_sub_edges.end();it++,j++,nbOfNodesInPg++) + { + INTERP_KERNEL::Node *node=(*it)->getPtr()->buildRepresentantOfMySelf(); + node->unApplySimilarity(xBary,yBary,fact); + addCoordsQuadratic.push_back((*node)[0]); + addCoordsQuadratic.push_back((*node)[1]); + conn.push_back(off+j); + node->decrRef(); + } + } + connI.push_back(connI.back()+nbOfNodesInPg+1); +} + +/*! + * This method make the hypothesis that \a this and \a other are split at the minimum into edges that are fully IN, OUT or ON. + * This method returns newly created polygons in \a conn and \a connI and the corresponding ids ( \a idThis, \a idOther) are stored respectively into \a nbThis and \a nbOther. + * @param [in,out] edgesThis, parameter that keep informed the caller about the edges in this not shared by the result of intersection of \a this with \a other + * @param [in,out] edgesBoundaryOther, parameter that stores all edges in result of intersection that are not + */ +void QuadraticPolygon::buildPartitionsAbs(QuadraticPolygon& other, std::set<INTERP_KERNEL::Edge *>& edgesThis, std::set<INTERP_KERNEL::Edge *>& edgesBoundaryOther, const std::map<INTERP_KERNEL::Node *,int>& mapp, int idThis, int idOther, int offset, std::vector<double>& addCoordsQuadratic, std::vector<int>& conn, std::vector<int>& connI, std::vector<int>& nbThis, std::vector<int>& nbOther) +{ + double xBaryBB, yBaryBB; + double fact=normalizeExt(&other, xBaryBB, yBaryBB); + //Locate \a this relative to \a other (edges of \a this, aka \a pol1 are marked as IN or OUT) + other.performLocatingOperationSlow(*this); // without any assumption + std::vector<QuadraticPolygon *> res=buildIntersectionPolygons(other,*this); + for(std::vector<QuadraticPolygon *>::iterator it=res.begin();it!=res.end();it++) + { + (*it)->appendCrudeData(mapp,xBaryBB,yBaryBB,fact,offset,addCoordsQuadratic,conn,connI); + INTERP_KERNEL::IteratorOnComposedEdge it1(*it); + for(it1.first();!it1.finished();it1.next()) + { + Edge *e=it1.current()->getPtr(); + if(edgesThis.find(e)!=edgesThis.end()) + edgesThis.erase(e); + else + { + if(edgesBoundaryOther.find(e)!=edgesBoundaryOther.end()) + edgesBoundaryOther.erase(e); + else + edgesBoundaryOther.insert(e); + } + } + nbThis.push_back(idThis); + nbOther.push_back(idOther); + delete *it; + } + unApplyGlobalSimilarityExt(other,xBaryBB,yBaryBB,fact); +} + +/*! + * Warning This method is \b NOT const. 'this' and 'other' are modified after call of this method. + * 'other' is a QuadraticPolygon of \b non closed edges. + */ +double QuadraticPolygon::intersectWithAbs1D(QuadraticPolygon& other, bool& isColinear) +{ + double ret = 0., xBaryBB, yBaryBB; + double fact = normalize(&other, xBaryBB, yBaryBB); + + QuadraticPolygon cpyOfThis(*this); + QuadraticPolygon cpyOfOther(other); + int nbOfSplits = 0; + SplitPolygonsEachOther(cpyOfThis, cpyOfOther, nbOfSplits); + //At this point cpyOfThis and cpyOfOther have been splited at maximum edge so that in/out can been done. + performLocatingOperation(cpyOfOther); + isColinear = false; + for(std::list<ElementaryEdge *>::const_iterator it=cpyOfOther._sub_edges.begin();it!=cpyOfOther._sub_edges.end();it++) + { + switch((*it)->getLoc()) + { + case FULL_IN_1: + { + ret += fabs((*it)->getPtr()->getCurveLength()); + break; + } + case FULL_ON_1: + { + isColinear=true; + ret += fabs((*it)->getPtr()->getCurveLength()); + break; + } + default: + { + } + } + } + return ret * fact; +} + +/*! + * Warning contrary to intersectWith method this method is \b NOT const. 'this' and 'other' are modified after call of this method. + */ +double QuadraticPolygon::intersectWithAbs(QuadraticPolygon& other, double* barycenter) +{ + double ret=0.,bary[2],area,xBaryBB,yBaryBB; + barycenter[0] = barycenter[1] = 0.; + double fact=normalize(&other,xBaryBB,yBaryBB); + std::vector<QuadraticPolygon *> polygs=intersectMySelfWith(other); + for(std::vector<QuadraticPolygon *>::iterator iter=polygs.begin();iter!=polygs.end();iter++) + { + area=fabs((*iter)->getArea()); + (*iter)->getBarycenter(bary); + delete *iter; + ret+=area; + barycenter[0] += bary[0]*area; + barycenter[1] += bary[1]*area; + } + if ( ret > std::numeric_limits<double>::min() ) + { + barycenter[0]=barycenter[0]/ret*fact+xBaryBB; + barycenter[1]=barycenter[1]/ret*fact+yBaryBB; + + } + return ret*fact*fact; +} + +/*! + * \b WARNING this method is const and other is const too. \b BUT location of Edges in 'this' and 'other' are nevertheless modified. + * This is possible because loc attribute in Edge class is mutable. + * This implies that if 'this' or/and 'other' are reused for intersect* method initLocations has to be called on each of this/them. + */ +double QuadraticPolygon::intersectWith(const QuadraticPolygon& other) const +{ + double ret=0.; + std::vector<QuadraticPolygon *> polygs=intersectMySelfWith(other); + for(std::vector<QuadraticPolygon *>::iterator iter=polygs.begin();iter!=polygs.end();iter++) + { + ret+=fabs((*iter)->getArea()); + delete *iter; + } + return ret; +} + +/*! + * \b WARNING this method is const and other is const too. \b BUT location of Edges in 'this' and 'other' are nevertheless modified. + * This is possible because loc attribute in Edge class is mutable. + * This implies that if 'this' or/and 'other' are reused for intersect* method initLocations has to be called on each of this/them. + */ +double QuadraticPolygon::intersectWith(const QuadraticPolygon& other, double* barycenter) const +{ + double ret=0., bary[2]; + barycenter[0] = barycenter[1] = 0.; + std::vector<QuadraticPolygon *> polygs=intersectMySelfWith(other); + for(std::vector<QuadraticPolygon *>::iterator iter=polygs.begin();iter!=polygs.end();iter++) + { + double area = fabs((*iter)->getArea()); + (*iter)->getBarycenter(bary); + delete *iter; + ret+=area; + barycenter[0] += bary[0]*area; + barycenter[1] += bary[1]*area; + } + if ( ret > std::numeric_limits<double>::min() ) + { + barycenter[0] /= ret; + barycenter[1] /= ret; + } + return ret; +} + +/*! + * \b WARNING this method is const and other is const too. \b BUT location of Edges in 'this' and 'other' are nevertheless modified. + * This is possible because loc attribute in Edge class is mutable. + * This implies that if 'this' or/and 'other' are reused for intersect* method initLocations has to be called on each of this/them. + */ +void QuadraticPolygon::intersectForPerimeter(const QuadraticPolygon& other, double& perimeterThisPart, double& perimeterOtherPart, double& perimeterCommonPart) const +{ + perimeterThisPart=0.; perimeterOtherPart=0.; perimeterCommonPart=0.; + QuadraticPolygon cpyOfThis(*this); + QuadraticPolygon cpyOfOther(other); int nbOfSplits=0; + SplitPolygonsEachOther(cpyOfThis,cpyOfOther,nbOfSplits); + performLocatingOperation(cpyOfOther); + other.performLocatingOperation(cpyOfThis); + cpyOfThis.dispatchPerimeterExcl(perimeterThisPart,perimeterCommonPart); + cpyOfOther.dispatchPerimeterExcl(perimeterOtherPart,perimeterCommonPart); + perimeterCommonPart/=2.; +} + +/*! + * \b WARNING this method is const and other is const too. \b BUT location of Edges in 'this' and 'other' are nevertheless modified. + * This is possible because loc attribute in Edge class is mutable. + * This implies that if 'this' or/and 'other' are reused for intersect* method initLocations has to be called on each of this/them. + * + * polThis.size()==this->size() and polOther.size()==other.size(). + * For each ElementaryEdge of 'this', the corresponding contribution in resulting polygon is in 'polThis'. + * For each ElementaryEdge of 'other', the corresponding contribution in resulting polygon is in 'polOther'. + * As consequence common part are counted twice (in polThis \b and in polOther). + */ +void QuadraticPolygon::intersectForPerimeterAdvanced(const QuadraticPolygon& other, std::vector< double >& polThis, std::vector< double >& polOther) const +{ + polThis.resize(size()); + polOther.resize(other.size()); + IteratorOnComposedEdge it1(const_cast<QuadraticPolygon *>(this)); + int edgeId=0; + for(it1.first();!it1.finished();it1.next(),edgeId++) + { + ElementaryEdge* curE1=it1.current(); + QuadraticPolygon cpyOfOther(other); + QuadraticPolygon tmp; + tmp.pushBack(curE1->clone()); + int tmp2; + SplitPolygonsEachOther(tmp,cpyOfOther,tmp2); + other.performLocatingOperation(tmp); + tmp.dispatchPerimeter(polThis[edgeId]); + } + // + IteratorOnComposedEdge it2(const_cast<QuadraticPolygon *>(&other)); + edgeId=0; + for(it2.first();!it2.finished();it2.next(),edgeId++) + { + ElementaryEdge* curE2=it2.current(); + QuadraticPolygon cpyOfThis(*this); + QuadraticPolygon tmp; + tmp.pushBack(curE2->clone()); + int tmp2; + SplitPolygonsEachOther(tmp,cpyOfThis,tmp2); + performLocatingOperation(tmp); + tmp.dispatchPerimeter(polOther[edgeId]); + } +} + + +/*! + * numberOfCreatedPointsPerEdge is resized to the number of edges of 'this'. + * This method returns in ordered maner the number of newly created points per edge. + * This method performs a split process between 'this' and 'other' that gives the result PThis. + * Then for each edges of 'this' this method counts how many edges in Pthis have the same id. + */ +void QuadraticPolygon::intersectForPoint(const QuadraticPolygon& other, std::vector< int >& numberOfCreatedPointsPerEdge) const +{ + numberOfCreatedPointsPerEdge.resize(size()); + IteratorOnComposedEdge it1(const_cast<QuadraticPolygon *>(this)); + int edgeId=0; + for(it1.first();!it1.finished();it1.next(),edgeId++) + { + ElementaryEdge* curE1=it1.current(); + QuadraticPolygon cpyOfOther(other); + QuadraticPolygon tmp; + tmp.pushBack(curE1->clone()); + int tmp2; + SplitPolygonsEachOther(tmp,cpyOfOther,tmp2); + numberOfCreatedPointsPerEdge[edgeId]=tmp.recursiveSize()-1; + } +} + +/*! + * \b WARNING this method is const and other is const too. \b BUT location of Edges in 'this' and 'other' are nevertheless modified. + * This is possible because loc attribute in Edge class is mutable. + * This implies that if 'this' or/and 'other' are reused for intersect* method initLocations has to be called on each of this/them. + */ +std::vector<QuadraticPolygon *> QuadraticPolygon::intersectMySelfWith(const QuadraticPolygon& other) const +{ + QuadraticPolygon cpyOfThis(*this); + QuadraticPolygon cpyOfOther(other); int nbOfSplits=0; + SplitPolygonsEachOther(cpyOfThis,cpyOfOther,nbOfSplits); + //At this point cpyOfThis and cpyOfOther have been splited at maximum edge so that in/out can been done. + performLocatingOperation(cpyOfOther); + return other.buildIntersectionPolygons(cpyOfThis,cpyOfOther); +} + +/*! + * This method is typically the first step of boolean operations between pol1 and pol2. + * This method perform the minimal splitting so that at the end each edges constituting pol1 are fully either IN or OUT or ON. + * @param pol1 IN/OUT param that is equal to 'this' when called. + */ +void QuadraticPolygon::SplitPolygonsEachOther(QuadraticPolygon& pol1, QuadraticPolygon& pol2, int& nbOfSplits) +{ + IteratorOnComposedEdge it1(&pol1),it2(&pol2); + MergePoints merge; + ComposedEdge *c1=new ComposedEdge; + ComposedEdge *c2=new ComposedEdge; + for(it2.first();!it2.finished();it2.next()) + { + ElementaryEdge* curE2=it2.current(); + if(!curE2->isThereStartPoint()) + it1.first(); + else + it1=curE2->getIterator(); + for(;!it1.finished();) + { + + ElementaryEdge* curE1=it1.current(); + merge.clear(); nbOfSplits++; + if(curE1->getPtr()->intersectWith(curE2->getPtr(),merge,*c1,*c2)) + { + if(!curE1->getDirection()) c1->reverse(); + if(!curE2->getDirection()) c2->reverse(); + UpdateNeighbours(merge,it1,it2,c1,c2); + //Substitution of simple edge by sub-edges. + delete curE1; // <-- destroying simple edge coming from pol1 + delete curE2; // <-- destroying simple edge coming from pol2 + it1.insertElemEdges(c1,true);// <-- 2nd param is true to go next. + it2.insertElemEdges(c2,false);// <-- 2nd param is false to avoid to go next. + curE2=it2.current(); + // + it1.assignMySelfToAllElems(c2);//To avoid that others + SoftDelete(c1); + SoftDelete(c2); + c1=new ComposedEdge; + c2=new ComposedEdge; + } + else + { + UpdateNeighbours(merge,it1,it2,curE1,curE2); + it1.next(); + } + } + } + Delete(c1); + Delete(c2); +} + +void QuadraticPolygon::performLocatingOperation(QuadraticPolygon& pol1) const +{ + IteratorOnComposedEdge it(&pol1); + TypeOfEdgeLocInPolygon loc=FULL_ON_1; + for(it.first();!it.finished();it.next()) + { + ElementaryEdge *cur=it.current(); + loc=cur->locateFullyMySelf(*this,loc);//*this=pol2=other + } +} + +void QuadraticPolygon::performLocatingOperationSlow(QuadraticPolygon& pol2) const +{ + IteratorOnComposedEdge it(&pol2); + for(it.first();!it.finished();it.next()) + { + ElementaryEdge *cur=it.current(); + cur->locateFullyMySelfAbsolute(*this); + } +} + +/*! + * Given 2 polygons \a pol1 and \a pol2 (localized) the resulting polygons are returned. + * + * this : pol2 simplified. + * @param [in] pol1 pol1 split. + * @param [in] pol2 pol2 split. + */ +std::vector<QuadraticPolygon *> QuadraticPolygon::buildIntersectionPolygons(const QuadraticPolygon& pol1, const QuadraticPolygon& pol2) const +{ + std::vector<QuadraticPolygon *> ret; + std::list<QuadraticPolygon *> pol2Zip=pol2.zipConsecutiveInSegments(); + if(!pol2Zip.empty()) + ClosePolygons(pol2Zip,pol1,*this,ret); + else + {//borders of pol2 do not cross pol1,and pol2 borders are outside of pol1. That is to say, either pol2 and pol1 + //do not overlap or pol1 is fully inside pol2. So in the first case no intersection, in the other case + //the intersection is pol1. + ElementaryEdge *e1FromPol1=pol1[0]; + TypeOfEdgeLocInPolygon loc=FULL_ON_1; + loc=e1FromPol1->locateFullyMySelf(*this,loc); + if(loc==FULL_IN_1) + ret.push_back(new QuadraticPolygon(pol1)); + } + return ret; +} + +/*! + * Returns parts of potentially non closed-polygons. Each returned polygons are not mergeable. + * this : pol2 split and locallized. + */ +std::list<QuadraticPolygon *> QuadraticPolygon::zipConsecutiveInSegments() const +{ + std::list<QuadraticPolygon *> ret; + IteratorOnComposedEdge it(const_cast<QuadraticPolygon *>(this)); + int nbOfTurns=recursiveSize(); + int i=0; + if(!it.goToNextInOn(false,i,nbOfTurns)) + return ret; + i=0; + // + while(i<nbOfTurns) + { + QuadraticPolygon *tmp1=new QuadraticPolygon; + TypeOfEdgeLocInPolygon loc=it.current()->getLoc(); + while(loc!=FULL_OUT_1 && i<nbOfTurns) + { + ElementaryEdge *tmp3=it.current()->clone(); + tmp1->pushBack(tmp3); + it.nextLoop(); i++; + loc=it.current()->getLoc(); + } + if(tmp1->empty()) + { + delete tmp1; + continue; + } + ret.push_back(tmp1); + it.goToNextInOn(true,i,nbOfTurns); + } + return ret; +} + +/*! + * @param [in] pol2zip is a list of set of edges (=an opened polygon) coming from split polygon 2. + * @param [in] pol1 is split pol1. + * @param [in] pol2 should be considered as pol2Simplified. + * @param [out] results the resulting \b CLOSED polygons. + */ +void QuadraticPolygon::ClosePolygons(std::list<QuadraticPolygon *>& pol2Zip, const QuadraticPolygon& pol1, const QuadraticPolygon& pol2, + std::vector<QuadraticPolygon *>& results) +{ + bool directionKnownInPol1=false; + bool directionInPol1; + for(std::list<QuadraticPolygon *>::iterator iter=pol2Zip.begin();iter!=pol2Zip.end();) + { + if((*iter)->completed()) + { + results.push_back(*iter); + directionKnownInPol1=false; + iter=pol2Zip.erase(iter); + continue; + } + if(!directionKnownInPol1) + { + if(!(*iter)->haveIAChanceToBeCompletedBy(pol1,pol2,directionInPol1)) + { delete *iter; iter=pol2Zip.erase(iter); continue; } + else + directionKnownInPol1=true; + } + std::list<QuadraticPolygon *>::iterator iter2=iter; iter2++; + std::list<QuadraticPolygon *>::iterator iter3=(*iter)->fillAsMuchAsPossibleWith(pol1,iter2,pol2Zip.end(),directionInPol1); + if(iter3!=pol2Zip.end()) + { + (*iter)->pushBack(*iter3); + SoftDelete(*iter3); + pol2Zip.erase(iter3); + } + } +} + +/*! + * 'this' is expected to be set of edges (not closed) of pol2 split. + */ +bool QuadraticPolygon::haveIAChanceToBeCompletedBy(const QuadraticPolygon& pol1Splitted,const QuadraticPolygon& pol2NotSplitted, bool& direction) +{ + IteratorOnComposedEdge it(const_cast<QuadraticPolygon *>(&pol1Splitted)); + bool found=false; + Node *n=getEndNode(); + ElementaryEdge *cur=it.current(); + for(it.first();!it.finished() && !found;) + { + cur=it.current(); + found=(cur->getStartNode()==n); + if(!found) + it.next(); + } + if(!found) + throw Exception("Internal error: polygons incompatible with each others. Should never happen!"); + //Ok we found correspondance between this and pol1. Searching for right direction to close polygon. + ElementaryEdge *e=_sub_edges.back(); + if(e->getLoc()==FULL_ON_1) + { + if(e->getPtr()==cur->getPtr()) + { + direction=false; + it.previousLoop(); + cur=it.current(); + Node *repr=cur->getPtr()->buildRepresentantOfMySelf(); + bool ret=pol2NotSplitted.isInOrOut(repr); + repr->decrRef(); + return ret; + } + else + { + direction=true; + Node *repr=cur->getPtr()->buildRepresentantOfMySelf(); + bool ret=pol2NotSplitted.isInOrOut(repr); + repr->decrRef(); + return ret; + } + } + else + direction=cur->locateFullyMySelfAbsolute(pol2NotSplitted)==FULL_IN_1; + return true; +} + +/*! + * This method fills as much as possible \a this (a sub-part of pol2 split) with edges of \a pol1Splitted. + */ +std::list<QuadraticPolygon *>::iterator QuadraticPolygon::fillAsMuchAsPossibleWith(const QuadraticPolygon& pol1Splitted, + std::list<QuadraticPolygon *>::iterator iStart, + std::list<QuadraticPolygon *>::iterator iEnd, + bool direction) +{ + IteratorOnComposedEdge it(const_cast<QuadraticPolygon *>(&pol1Splitted)); + bool found=false; + Node *n=getEndNode(); + ElementaryEdge *cur; + for(it.first();!it.finished() && !found;) + { + cur=it.current(); + found=(cur->getStartNode()==n); + if(!found) + it.next(); + } + if(!direction) + it.previousLoop(); + Node *nodeToTest; + int szMax(pol1Splitted.size()+1),ii(0);// here a protection against agressive users of IntersectMeshes of invalid input meshes + std::list<QuadraticPolygon *>::iterator ret; + do + { + cur=it.current(); + ElementaryEdge *tmp=cur->clone(); + if(!direction) + tmp->reverse(); + pushBack(tmp); + nodeToTest=tmp->getEndNode(); + direction?it.nextLoop():it.previousLoop(); + ret=CheckInList(nodeToTest,iStart,iEnd); + if(completed()) + return iEnd; + ii++; + } + while(ret==iEnd && ii<szMax); + if(ii==szMax)// here a protection against agressive users of IntersectMeshes of invalid input meshes + throw INTERP_KERNEL::Exception("QuadraticPolygon::fillAsMuchAsPossibleWith : Something is invalid with input polygons !"); + return ret; +} + +std::list<QuadraticPolygon *>::iterator QuadraticPolygon::CheckInList(Node *n, std::list<QuadraticPolygon *>::iterator iStart, + std::list<QuadraticPolygon *>::iterator iEnd) +{ + for(std::list<QuadraticPolygon *>::iterator iter=iStart;iter!=iEnd;iter++) + if((*iter)->isNodeIn(n)) + return iter; + return iEnd; +} + +void QuadraticPolygon::ComputeResidual(const QuadraticPolygon& pol1, const std::set<Edge *>& notUsedInPol1, const std::set<Edge *>& edgesInPol2OnBoundary, const std::map<INTERP_KERNEL::Node *,int>& mapp, int offset, int idThis, + std::vector<double>& addCoordsQuadratic, std::vector<int>& conn, std::vector<int>& connI, std::vector<int>& nb1, std::vector<int>& nb2) +{ + pol1.initLocations(); + for(std::set<Edge *>::const_iterator it9=notUsedInPol1.begin();it9!=notUsedInPol1.end();it9++) + { (*it9)->initLocs(); (*it9)->declareOn(); } + for(std::set<Edge *>::const_iterator itA=edgesInPol2OnBoundary.begin();itA!=edgesInPol2OnBoundary.end();itA++) + { (*itA)->initLocs(); (*itA)->declareIn(); } + //// + std::set<Edge *> notUsedInPol1L(notUsedInPol1); + IteratorOnComposedEdge it(const_cast<QuadraticPolygon *>(&pol1)); + int sz=pol1.size(); + std::list<QuadraticPolygon *> pol1Zip; + if(pol1.size()==(int)notUsedInPol1.size() && edgesInPol2OnBoundary.empty()) + { + pol1.appendCrudeData(mapp,0.,0.,1.,offset,addCoordsQuadratic,conn,connI); nb1.push_back(idThis); nb2.push_back(-1); + return ; + } + while(!notUsedInPol1L.empty()) + { + for(int i=0;i<sz && (it.current()->getStartNode()->getLoc()!=IN_1 || it.current()->getLoc()!=FULL_ON_1);i++) + it.nextLoop(); + if(it.current()->getStartNode()->getLoc()!=IN_1 || it.current()->getLoc()!=FULL_ON_1) + throw INTERP_KERNEL::Exception("Presence of a target polygon fully included in source polygon ! The partition of this leads to a non simply connex cell (with hole) ! Impossible ! Such resulting cell cannot be stored in MED cell format !"); + QuadraticPolygon *tmp1=new QuadraticPolygon; + do + { + Edge *ee=it.current()->getPtr(); + if(ee->getLoc()==FULL_ON_1) + { + ee->incrRef(); notUsedInPol1L.erase(ee); + tmp1->pushBack(new ElementaryEdge(ee,it.current()->getDirection())); + } + it.nextLoop(); + } + while(it.current()->getStartNode()->getLoc()!=IN_1 && !notUsedInPol1L.empty()); + pol1Zip.push_back(tmp1); + } + //// + std::list<QuadraticPolygon *> retPolsUnderContruction; + std::list<Edge *> edgesInPol2OnBoundaryL(edgesInPol2OnBoundary.begin(),edgesInPol2OnBoundary.end()); + std::map<QuadraticPolygon *, std::list<QuadraticPolygon *> > pol1ZipConsumed; + std::size_t maxNbOfTurn=edgesInPol2OnBoundaryL.size(),nbOfTurn=0,iiMNT=0; + for(std::list<QuadraticPolygon *>::const_iterator itMNT=pol1Zip.begin();itMNT!=pol1Zip.end();itMNT++,iiMNT++) + nbOfTurn+=(*itMNT)->size(); + maxNbOfTurn=maxNbOfTurn*nbOfTurn; maxNbOfTurn*=maxNbOfTurn; + nbOfTurn=0; + while(nbOfTurn<maxNbOfTurn && ((!pol1Zip.empty() || !edgesInPol2OnBoundaryL.empty()))) + { + for(std::list<QuadraticPolygon *>::iterator it1=retPolsUnderContruction.begin();it1!=retPolsUnderContruction.end();) + { + if((*it1)->getStartNode()==(*it1)->getEndNode()) + { + it1++; + continue; + } + Node *curN=(*it1)->getEndNode(); + bool smthHappened=false; + for(std::list<Edge *>::iterator it2=edgesInPol2OnBoundaryL.begin();it2!=edgesInPol2OnBoundaryL.end();) + { + if(curN==(*it2)->getStartNode()) + { (*it2)->incrRef(); (*it1)->pushBack(new ElementaryEdge(*it2,true)); curN=(*it2)->getEndNode(); smthHappened=true; it2=edgesInPol2OnBoundaryL.erase(it2); } + else if(curN==(*it2)->getEndNode()) + { (*it2)->incrRef(); (*it1)->pushBack(new ElementaryEdge(*it2,false)); curN=(*it2)->getStartNode(); smthHappened=true; it2=edgesInPol2OnBoundaryL.erase(it2); } + else + it2++; + } + if(smthHappened) + { + for(std::list<QuadraticPolygon *>::iterator it3=pol1Zip.begin();it3!=pol1Zip.end();) + { + if(curN==(*it3)->getStartNode()) + { + for(std::list<ElementaryEdge *>::const_iterator it4=(*it3)->_sub_edges.begin();it4!=(*it3)->_sub_edges.end();it4++) + { (*it4)->getPtr()->incrRef(); bool dir=(*it4)->getDirection(); (*it1)->pushBack(new ElementaryEdge((*it4)->getPtr(),dir)); } + smthHappened=true; + pol1ZipConsumed[*it1].push_back(*it3); + curN=(*it3)->getEndNode(); + it3=pol1Zip.erase(it3); + } + else + it3++; + } + } + if(!smthHappened) + { + for(std::list<ElementaryEdge *>::const_iterator it5=(*it1)->_sub_edges.begin();it5!=(*it1)->_sub_edges.end();it5++) + { + Edge *ee=(*it5)->getPtr(); + if(edgesInPol2OnBoundary.find(ee)!=edgesInPol2OnBoundary.end()) + edgesInPol2OnBoundaryL.push_back(ee); + } + for(std::list<QuadraticPolygon *>::iterator it6=pol1ZipConsumed[*it1].begin();it6!=pol1ZipConsumed[*it1].end();it6++) + pol1Zip.push_front(*it6); + pol1ZipConsumed.erase(*it1); + delete *it1; + it1=retPolsUnderContruction.erase(it1); + } + } + if(!pol1Zip.empty()) + { + QuadraticPolygon *tmp=new QuadraticPolygon; + QuadraticPolygon *first=*(pol1Zip.begin()); + for(std::list<ElementaryEdge *>::const_iterator it4=first->_sub_edges.begin();it4!=first->_sub_edges.end();it4++) + { (*it4)->getPtr()->incrRef(); bool dir=(*it4)->getDirection(); tmp->pushBack(new ElementaryEdge((*it4)->getPtr(),dir)); } + pol1ZipConsumed[tmp].push_back(first); + 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<QuadraticPolygon *>::iterator it1=retPolsUnderContruction.begin();it1!=retPolsUnderContruction.end();it1++) + { + if((*it1)->getStartNode()==(*it1)->getEndNode()) + { + (*it1)->appendCrudeData(mapp,0.,0.,1.,offset,addCoordsQuadratic,conn,connI); nb1.push_back(idThis); nb2.push_back(-1); + for(std::list<QuadraticPolygon *>::iterator it6=pol1ZipConsumed[*it1].begin();it6!=pol1ZipConsumed[*it1].end();it6++) + delete *it6; + delete *it1; + } + } +} diff --git a/src/medtool/src/INTERP_KERNEL/Geometric2D/InterpKernelGeo2DQuadraticPolygon.hxx b/src/medtool/src/INTERP_KERNEL/Geometric2D/InterpKernelGeo2DQuadraticPolygon.hxx new file mode 100644 index 000000000..ee9ca5bc0 --- /dev/null +++ b/src/medtool/src/INTERP_KERNEL/Geometric2D/InterpKernelGeo2DQuadraticPolygon.hxx @@ -0,0 +1,126 @@ +// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 +// 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 __INTERPKERNELGEO2DQUADRATICPOLYGON_HXX__ +#define __INTERPKERNELGEO2DQUADRATICPOLYGON_HXX__ + +#include "INTERPKERNELDefines.hxx" + +#include "InterpKernelGeo2DComposedEdge.hxx" +#include "InterpKernelGeo2DAbstractEdge.hxx" +#include "InterpKernelGeo2DElementaryEdge.hxx" + +#include <list> +#include <vector> + +namespace INTERP_KERNEL +{ + class Edge; + class MergePoints; + + /** + * A set of quadratic or linear edges, not necessarily connected to form a closed polygon. + * Some methods however requires a closed form. + * Class ComposedEdge focuses more on connectivity aspect. + */ + class QuadraticPolygon : public ComposedEdge + { + public: + INTERPKERNEL_EXPORT QuadraticPolygon() { } + INTERPKERNEL_EXPORT QuadraticPolygon(const QuadraticPolygon& other):ComposedEdge(other) { } + INTERPKERNEL_EXPORT QuadraticPolygon(const char *fileName); + INTERPKERNEL_EXPORT static QuadraticPolygon *BuildLinearPolygon(std::vector<Node *>& nodes); + INTERPKERNEL_EXPORT static QuadraticPolygon *BuildArcCirclePolygon(std::vector<Node *>& nodes); + INTERPKERNEL_EXPORT static Edge *BuildLinearEdge(std::vector<Node *>& nodes); + INTERPKERNEL_EXPORT static Edge *BuildArcCircleEdge(std::vector<Node *>& nodes); + INTERPKERNEL_EXPORT static void BuildDbgFile(const std::vector<Node *>& nodes, const char *fileName); + INTERPKERNEL_EXPORT ~QuadraticPolygon(); + INTERPKERNEL_EXPORT void closeMe() const; + INTERPKERNEL_EXPORT void circularPermute(); + INTERPKERNEL_EXPORT bool isButterflyAbs(); + INTERPKERNEL_EXPORT bool isButterfly() const; + INTERPKERNEL_EXPORT void dumpInXfigFile(const char *fileName) const; + INTERPKERNEL_EXPORT void dumpInXfigFileWithOther(const ComposedEdge& other, const char *fileName) const; + //! Before intersecting as intersectWith a normalization is done. + INTERPKERNEL_EXPORT double intersectWithAbs(QuadraticPolygon& other); + INTERPKERNEL_EXPORT double intersectWithAbs1D(QuadraticPolygon& other, bool& isColinear); + //! Before intersecting as intersectWith a normalization is done. + INTERPKERNEL_EXPORT double intersectWithAbs(QuadraticPolygon& other, double* barycenter); + INTERPKERNEL_EXPORT void splitAbs(QuadraticPolygon& other, const std::map<INTERP_KERNEL::Node *,int>& mapThis, const std::map<INTERP_KERNEL::Node *,int>& mapOther, int offset1, int offset2, const std::vector<int>& otherEdgeIds, + std::vector<int>& edgesThis, int cellIdThis, std::vector< std::vector<int> >& edgesInOtherColinearWithThis, std::vector< std::vector<int> >& subDivOther, std::vector<double>& addCoo, std::map<int,int>& mergedNodes); + INTERPKERNEL_EXPORT void buildFromCrudeDataArray(const std::map<int,INTERP_KERNEL::Node *>& mapp, bool isQuad, const int *nodalBg, const double *coords, + const int *descBg, const int *descEnd, const std::vector<std::vector<int> >& intersectEdges); + INTERPKERNEL_EXPORT void buildFromCrudeDataArray2(const std::map<int,INTERP_KERNEL::Node *>& mapp, bool isQuad, const int *nodalBg, const double *coords, const int *descBg, const int *descEnd, const std::vector<std::vector<int> >& intersectEdges, + const INTERP_KERNEL::QuadraticPolygon& pol1, const int *descBg1, const int *descEnd1, const std::vector<std::vector<int> >& intersectEdges1, + const std::vector< std::vector<int> >& colinear1, + std::map<int,std::vector<INTERP_KERNEL::ElementaryEdge *> >& alreadyExistingIn2); + INTERPKERNEL_EXPORT void updateLocOfEdgeFromCrudeDataArray2(const int *descBg, const int *descEnd, const std::vector<std::vector<int> >& intersectEdges, const INTERP_KERNEL::QuadraticPolygon& pol1, const int *descBg1, const int *descEnd1, const std::vector<std::vector<int> >& intersectEdges1, const std::vector< std::vector<int> >& colinear1) const; + INTERPKERNEL_EXPORT void appendEdgeFromCrudeDataArray(std::size_t edgeId, const std::map<int,INTERP_KERNEL::Node *>& mapp, bool isQuad, const int *nodalBg, const double *coords, + const int *descBg, const int *descEnd, const std::vector<std::vector<int> >& intersectEdges); + INTERPKERNEL_EXPORT void appendSubEdgeFromCrudeDataArray(Edge *baseEdge, std::size_t j, bool direct, int edgeId, const std::vector<int>& subEdge, const std::map<int,INTERP_KERNEL::Node *>& mapp); + INTERPKERNEL_EXPORT void appendCrudeData(const std::map<INTERP_KERNEL::Node *,int>& mapp, double xBary, double yBary, double fact, int offset, std::vector<double>& addCoordsQuadratic, std::vector<int>& conn, std::vector<int>& connI) const; + INTERPKERNEL_EXPORT void buildPartitionsAbs(QuadraticPolygon& other, std::set<INTERP_KERNEL::Edge *>& edgesThis, std::set<INTERP_KERNEL::Edge *>& edgesBoundaryOther, const std::map<INTERP_KERNEL::Node *,int>& mapp, int idThis, int idOther, int offset, + std::vector<double>& addCoordsQuadratic, std::vector<int>& conn, std::vector<int>& connI, std::vector<int>& nb1, std::vector<int>& nb2); + // + INTERPKERNEL_EXPORT double intersectWith(const QuadraticPolygon& other) const; + INTERPKERNEL_EXPORT double intersectWith(const QuadraticPolygon& other, double* barycenter) const; + INTERPKERNEL_EXPORT std::vector<QuadraticPolygon *> intersectMySelfWith(const QuadraticPolygon& other) const; + INTERPKERNEL_EXPORT void intersectForPerimeter(const QuadraticPolygon& other, double& perimeterThisPart, double& perimeterOtherPart, double& perimeterCommonPart) const; + INTERPKERNEL_EXPORT void intersectForPerimeterAdvanced(const QuadraticPolygon& other, std::vector< double >& polThis, std::vector< double >& polOther) const; + INTERPKERNEL_EXPORT void intersectForPoint(const QuadraticPolygon& other, std::vector< int >& numberOfCreatedPointsPerEdge) const; + public://Only public for tests reasons + INTERPKERNEL_EXPORT void performLocatingOperation(QuadraticPolygon& pol2) const; + INTERPKERNEL_EXPORT void performLocatingOperationSlow(QuadraticPolygon& pol2) const; + INTERPKERNEL_EXPORT static void SplitPolygonsEachOther(QuadraticPolygon& pol1, QuadraticPolygon& pol2, int& nbOfSplits); + INTERPKERNEL_EXPORT std::vector<QuadraticPolygon *> buildIntersectionPolygons(const QuadraticPolygon& pol1, const QuadraticPolygon& pol2) const; + INTERPKERNEL_EXPORT bool haveIAChanceToBeCompletedBy(const QuadraticPolygon& pol1Splitted, const QuadraticPolygon& pol2NotSplitted, bool& direction); + INTERPKERNEL_EXPORT static void ComputeResidual(const QuadraticPolygon& pol1, const std::set<Edge *>& notUsedInPol1, const std::set<Edge *>& edgesInPol2OnBoundary, const std::map<INTERP_KERNEL::Node *,int>& mapp, int offset, int idThis, + std::vector<double>& addCoordsQuadratic, std::vector<int>& conn, std::vector<int>& connI, std::vector<int>& nb1, std::vector<int>& nb2); + protected: + std::list<QuadraticPolygon *> zipConsecutiveInSegments() const; + void dumpInXfigFile(std::ostream& stream, int resolution, const Bounds& box) const; + static void ClosePolygons(std::list<QuadraticPolygon *>& pol2Zip, const QuadraticPolygon& pol1, const QuadraticPolygon& pol2, std::vector<QuadraticPolygon *>& results); + template<class EDGES> + static void UpdateNeighbours(const MergePoints& merger, IteratorOnComposedEdge it1, IteratorOnComposedEdge it2, + const EDGES *e1, const EDGES *e2); + std::list<QuadraticPolygon *>::iterator fillAsMuchAsPossibleWith(const QuadraticPolygon& pol1Splitted, + std::list<QuadraticPolygon *>::iterator iStart, + std::list<QuadraticPolygon *>::iterator iEnd, + bool direction); + static std::list<QuadraticPolygon *>::iterator CheckInList(Node *n, std::list<QuadraticPolygon *>::iterator iStart, + std::list<QuadraticPolygon *>::iterator iEnd); + }; +} + +namespace INTERP_KERNEL +{ + template<class EDGES> + void QuadraticPolygon::UpdateNeighbours(const MergePoints& merger, IteratorOnComposedEdge it1, IteratorOnComposedEdge it2, + const EDGES *e1, const EDGES *e2) + { + it1.previousLoop(); it2.previousLoop(); + ElementaryEdge *curE1=it1.current(); ElementaryEdge *curE2=it2.current(); + curE1->changeEndNodeWith(e1->getStartNode()); curE2->changeEndNodeWith(e2->getStartNode()); + it1.nextLoop(); it1.nextLoop(); it2.nextLoop(); it2.nextLoop(); + curE1->changeStartNodeWith(e1->getEndNode()); curE2->changeStartNodeWith(e2->getEndNode()); + } +} + +#endif diff --git a/src/medtool/src/INTERP_KERNEL/Geometric2DIntersector.hxx b/src/medtool/src/INTERP_KERNEL/Geometric2DIntersector.hxx new file mode 100644 index 000000000..1de6c446f --- /dev/null +++ b/src/medtool/src/INTERP_KERNEL/Geometric2DIntersector.hxx @@ -0,0 +1,60 @@ +// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 +// 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 __GEOMETRIC2DINTERSECTOR_HXX__ +#define __GEOMETRIC2DINTERSECTOR_HXX__ + +#include "PlanarIntersectorP0P0.hxx" +#include "PlanarIntersectorP0P1.hxx" +#include "PlanarIntersectorP1P0.hxx" +#include "PlanarIntersectorP1P1.hxx" +#include "PlanarIntersectorP1P0Bary.hxx" +#include "PlanarIntersectorP0P1Bary.hxx" + +namespace INTERP_KERNEL +{ + class QuadraticPolygon; + + template<class MyMeshType, class MyMatrix, template <class MeshType, class TheMatrix, class ThisIntersector> class InterpType> + class Geometric2DIntersector : public InterpType<MyMeshType,MyMatrix,Geometric2DIntersector<MyMeshType,MyMatrix,InterpType> > + { + public: + static const int SPACEDIM=MyMeshType::MY_SPACEDIM; + static const int MESHDIM=MyMeshType::MY_MESHDIM; + typedef typename MyMeshType::MyConnType ConnType; + static const NumberingPolicy numPol=MyMeshType::My_numPol; + public: + Geometric2DIntersector(const MyMeshType& meshT, const MyMeshType& meshS, + double dimCaracteristic, double md3DSurf, double minDot3DSurf, double medianPlane, double precision, int orientation); + double intersectGeometry(ConnType icellT, ConnType icellS, ConnType nbNodesT, ConnType nbNodesS); + double intersectGeometry1D(ConnType icellT, ConnType icellS, ConnType nbNodesT, ConnType nbNodesS, + bool& isColinear); + double intersectGeometryWithQuadrangle(const double *quadrangle, const std::vector<double>& sourceCoords, bool isSourceQuad); + double intersectGeometryGeneral(const std::vector<double>& targetCoords, const std::vector<double>& sourceCoords); + double intersectGeoBary(const std::vector<double>& targetCell, bool targetCellQuadratic, const double *sourceCell, std::vector<double>& res); + private: + QuadraticPolygon *buildPolygonFrom(const std::vector<double>& coords, NormalizedCellType type); + QuadraticPolygon *buildPolygonOfOneEdgeFrom(const std::vector<double>& coords, NormalizedCellType type); + QuadraticPolygon *buildPolygonAFrom(ConnType cell, int nbOfPoints, NormalizedCellType type); + QuadraticPolygon *buildPolygonBFrom(ConnType cell, int nbOfPoints, NormalizedCellType type); + }; +} + +#endif diff --git a/src/medtool/src/INTERP_KERNEL/Geometric2DIntersector.txx b/src/medtool/src/INTERP_KERNEL/Geometric2DIntersector.txx new file mode 100644 index 000000000..81998de5e --- /dev/null +++ b/src/medtool/src/INTERP_KERNEL/Geometric2DIntersector.txx @@ -0,0 +1,250 @@ +// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 +// 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 __GEOMETRIC2DINTERSECTOR_TXX__ +#define __GEOMETRIC2DINTERSECTOR_TXX__ + +#include "Geometric2DIntersector.hxx" +#include "PlanarIntersectorP0P0.txx" +#include "Planar2D1DIntersectorP0P0.txx" +#include "PlanarIntersectorP0P1.txx" +#include "PlanarIntersectorP1P0.txx" +#include "PlanarIntersectorP1P1.txx" +#include "PlanarIntersectorP1P0Bary.txx" +#include "PlanarIntersectorP0P1Bary.txx" +#include "CellModel.hxx" + +#include "InterpKernelGeo2DQuadraticPolygon.hxx" +#include "InterpKernelGeo2DEdgeArcCircle.hxx" +#include "InterpKernelGeo2DEdgeLin.hxx" +#include "InterpKernelGeo2DNode.hxx" + +#define GEO2D_INTERSECTOR Geometric2DIntersector<MyMeshType,MyMatrix,InterpType> +#define INTERSECTOR_TEMPLATE template<class MyMeshType, class MyMatrix, template <class MeshType, class TheMatrix, class ThisIntersector> class InterpType> + +namespace INTERP_KERNEL +{ + INTERSECTOR_TEMPLATE + GEO2D_INTERSECTOR::Geometric2DIntersector(const MyMeshType& meshT, const MyMeshType& meshS, + double dimCaracteristic, double md3DSurf, double minDot3DSurf, double medianPlane, + double precision, int orientation): + InterpType<MyMeshType,MyMatrix,GEO2D_INTERSECTOR >(meshT,meshS,dimCaracteristic, precision, md3DSurf, minDot3DSurf, medianPlane, true, orientation, 0) + { + QUADRATIC_PLANAR::_precision=precision; + } + + INTERSECTOR_TEMPLATE + double GEO2D_INTERSECTOR::intersectGeometry(ConnType icellT, ConnType icellS, + ConnType nbNodesT, ConnType nbNodesS) + { + int orientation = 1; + std::vector<double> CoordsT; + std::vector<double> CoordsS; + PlanarIntersector<MyMeshType,MyMatrix>::getRealCoordinates(icellT,icellS,nbNodesT,nbNodesS,CoordsT,CoordsS,orientation); + NormalizedCellType tT=PlanarIntersector<MyMeshType,MyMatrix>::_meshT.getTypeOfElement(icellT); + NormalizedCellType tS=PlanarIntersector<MyMeshType,MyMatrix>::_meshS.getTypeOfElement(icellS); + QuadraticPolygon *p1=buildPolygonFrom(CoordsT,tT); + QuadraticPolygon *p2=buildPolygonFrom(CoordsS,tS); + double ret=p1->intersectWithAbs(*p2); + delete p1; delete p2; + return orientation*ret; + } + + INTERSECTOR_TEMPLATE + double GEO2D_INTERSECTOR::intersectGeometry1D(ConnType icellT, ConnType icellS, + ConnType nbNodesT, ConnType nbNodesS, + bool& isColinear) + { + int orientation = 1; + std::vector<double> CoordsT; + std::vector<double> CoordsS; + PlanarIntersector<MyMeshType,MyMatrix>::getRealCoordinates(icellT,icellS,nbNodesT,nbNodesS,CoordsT,CoordsS,orientation); + NormalizedCellType tT=PlanarIntersector<MyMeshType,MyMatrix>::_meshT.getTypeOfElement(icellT); + NormalizedCellType tS=PlanarIntersector<MyMeshType,MyMatrix>::_meshS.getTypeOfElement(icellS); + QuadraticPolygon *p1=buildPolygonFrom(CoordsT,tT); + QuadraticPolygon *p2=buildPolygonOfOneEdgeFrom(CoordsS,tS); + double ret=p1->intersectWithAbs1D(*p2, isColinear); + delete p1; delete p2; + return orientation*ret; + } + + INTERSECTOR_TEMPLATE + double GEO2D_INTERSECTOR::intersectGeometryWithQuadrangle(const double * quadrangle, + const std::vector<double>& sourceCoords, + bool isSourceQuad) + { + std::vector<Node *> nodes(4); + nodes[0]=new Node(quadrangle[0],quadrangle[1]); + nodes[1]=new Node(quadrangle[SPACEDIM],quadrangle[SPACEDIM+1]); + nodes[2]=new Node(quadrangle[2*SPACEDIM],quadrangle[2*SPACEDIM+1]); + nodes[3]=new Node(quadrangle[3*SPACEDIM],quadrangle[3*SPACEDIM+1]); + int nbOfSourceNodes=sourceCoords.size()/SPACEDIM; + std::vector<Node *> nodes2(nbOfSourceNodes); + for(int i=0;i<nbOfSourceNodes;i++) + nodes2[i]=new Node(sourceCoords[i*SPACEDIM],sourceCoords[i*SPACEDIM+1]); + QuadraticPolygon *p1=QuadraticPolygon::BuildLinearPolygon(nodes); + QuadraticPolygon *p2; + if(!isSourceQuad) + p2=QuadraticPolygon::BuildLinearPolygon(nodes2); + else + p2=QuadraticPolygon::BuildArcCirclePolygon(nodes2); + double ret=p1->intersectWithAbs(*p2); + delete p1; delete p2; + return ret; + } + + INTERSECTOR_TEMPLATE + double GEO2D_INTERSECTOR::intersectGeometryGeneral(const std::vector<double>& targetCoords, + const std::vector<double>& sourceCoords) + { + int nbOfTargetNodes=targetCoords.size()/SPACEDIM; + std::vector<Node *> nodes(nbOfTargetNodes); + for(int i=0;i<nbOfTargetNodes;i++) + nodes[i]=new Node(targetCoords[i*SPACEDIM],targetCoords[i*SPACEDIM+1]); + int nbOfSourceNodes=sourceCoords.size()/SPACEDIM; + std::vector<Node *> nodes2(nbOfSourceNodes); + for(int i=0;i<nbOfSourceNodes;i++) + nodes2[i]=new Node(sourceCoords[i*SPACEDIM],sourceCoords[i*SPACEDIM+1]); + QuadraticPolygon *p1=QuadraticPolygon::BuildLinearPolygon(nodes); + QuadraticPolygon *p2=QuadraticPolygon::BuildLinearPolygon(nodes2); + double ret=p1->intersectWithAbs(*p2); + delete p1; delete p2; + return ret; + } + + //================================================================================ + /*! + * \brief Intersect a triangle and a polygon for P1P0 barycentric algorithm + * \param targetCell - list of coordinates of target polygon in full interlace + * \param targetCellQuadratic - specifies if target polygon is quadratic or not + * \param sourceTria - list of coordinates of source triangle + * \param res - coefficients a,b and c associated to nodes of sourceTria + */ + //================================================================================ + + INTERSECTOR_TEMPLATE + double GEO2D_INTERSECTOR::intersectGeoBary(const std::vector<double>& targetCell, + bool targetCellQuadratic, + const double * sourceTria, + std::vector<double>& res) + { + std::vector<Node *> nodes(3); + nodes[0]=new Node(sourceTria[0*SPACEDIM],sourceTria[0*SPACEDIM+1]); + nodes[1]=new Node(sourceTria[1*SPACEDIM],sourceTria[1*SPACEDIM+1]); + nodes[2]=new Node(sourceTria[2*SPACEDIM],sourceTria[2*SPACEDIM+1]); + int nbOfTargetNodes=targetCell.size()/SPACEDIM; + std::vector<Node *> nodes2(nbOfTargetNodes); + for(int i=0;i<nbOfTargetNodes;i++) + nodes2[i]=new Node(targetCell[i*SPACEDIM],targetCell[i*SPACEDIM+1]); + QuadraticPolygon *p1=QuadraticPolygon::BuildLinearPolygon(nodes); + QuadraticPolygon *p2; + if(!targetCellQuadratic) + p2=QuadraticPolygon::BuildLinearPolygon(nodes2); + else + p2=QuadraticPolygon::BuildArcCirclePolygon(nodes2); + double barycenter[2]; + double ret=p1->intersectWithAbs(*p2,barycenter); + delete p1; delete p2; + if ( ret > std::numeric_limits<double>::min() ) + { + std::vector<const double* > sourceCell(3); + sourceCell[0] = &sourceTria[0]; + sourceCell[1] = &sourceTria[SPACEDIM]; + sourceCell[2] = &sourceTria[SPACEDIM*2]; + res.resize(3); + barycentric_coords( sourceCell, barycenter, &res[0]); + res[0] *= ret; + res[1] *= ret; + res[2] *= ret; + } + else + { + ret = 0; + } + return ret; + } + + INTERSECTOR_TEMPLATE + QuadraticPolygon *GEO2D_INTERSECTOR::buildPolygonFrom(const std::vector<double>& coords, NormalizedCellType type) + { + int nbNodes=coords.size()/SPACEDIM; + std::vector<Node *> nodes(nbNodes); + for(int i=0;i<nbNodes;i++) + nodes[i]=new Node(coords[i*SPACEDIM],coords[i*SPACEDIM+1]); + if(!CellModel::GetCellModel(type).isQuadratic()) + return QuadraticPolygon::BuildLinearPolygon(nodes); + else + return QuadraticPolygon::BuildArcCirclePolygon(nodes); + } + + INTERSECTOR_TEMPLATE + QuadraticPolygon *GEO2D_INTERSECTOR::buildPolygonOfOneEdgeFrom(const std::vector<double>& coords, NormalizedCellType type) + { + if(type==NORM_SEG2) + { + Node *node0=new Node(coords[0],coords[1]); + Node *node1=new Node(coords[SPACEDIM],coords[SPACEDIM+1]); + QuadraticPolygon *ret=new QuadraticPolygon; + ret->pushBack(new EdgeLin(node0,node1)); + node0->decrRef(); node1->decrRef(); + return ret; + } + else if(type==NORM_SEG3) + { + Node *nodeBg=new Node(coords[0],coords[1]); + Node *nodeEnd=new Node(coords[SPACEDIM],coords[SPACEDIM+1]); + Node *nodeMiddle=new Node(coords[2*SPACEDIM],coords[2*SPACEDIM+1]); + QuadraticPolygon *ret=new QuadraticPolygon; + ret->pushBack(new EdgeArcCircle(nodeBg,nodeMiddle,nodeEnd)); + nodeBg->decrRef(); nodeEnd->decrRef(); nodeMiddle->decrRef(); + return ret; + } + else + throw INTERP_KERNEL::Exception("buildPolygonOfOneEdgeFrom : trying to build such non close QuadraticPolygon with 1D type !"); + } + + INTERSECTOR_TEMPLATE + QuadraticPolygon *GEO2D_INTERSECTOR::buildPolygonAFrom(ConnType cell, int nbOfPoints, NormalizedCellType type) + { + const ConnType *startOfCellNodeConn=PlanarIntersector<MyMeshType,MyMatrix>::_connectT+OTT<ConnType,numPol>::conn2C(PlanarIntersector<MyMeshType,MyMatrix>::_connIndexT[OTT<ConnType,numPol>::ind2C(cell)]); + std::vector<Node *> nodes(nbOfPoints); + for(int i=0;i<nbOfPoints;i++) + nodes[i]=new Node(PlanarIntersector<MyMeshType,MyMatrix>::_coordsT+OTT<ConnType,numPol>::coo2C(startOfCellNodeConn[i])*SPACEDIM); + if(CellModel::GetCellModel(type).isQuadratic()) + return QuadraticPolygon::BuildLinearPolygon(nodes); + else + return QuadraticPolygon::BuildArcCirclePolygon(nodes); + } + + INTERSECTOR_TEMPLATE + QuadraticPolygon *GEO2D_INTERSECTOR::buildPolygonBFrom(ConnType cell, int nbOfPoints, NormalizedCellType type) + { + const ConnType *startOfCellNodeConn=PlanarIntersector<MyMeshType,MyMatrix>::_connectS+OTT<ConnType,numPol>::conn2C(PlanarIntersector<MyMeshType,MyMatrix>::_connIndexS[OTT<ConnType,numPol>::ind2C(cell)]); + std::vector<Node *> nodes(nbOfPoints); + for(int i=0;i<nbOfPoints;i++) + nodes[i]=new Node(PlanarIntersector<MyMeshType,MyMatrix>::_coordsS+OTT<ConnType,numPol>::coo2C(startOfCellNodeConn[i])*SPACEDIM); + const CellModel& cm=CellModel::GetCellModel(type); + if(!cm.isQuadratic()) + return QuadraticPolygon::BuildLinearPolygon(nodes); + else + return QuadraticPolygon::BuildArcCirclePolygon(nodes); + } +} + +#endif diff --git a/src/medtool/src/INTERP_KERNEL/INTERPKERNELDefines.hxx b/src/medtool/src/INTERP_KERNEL/INTERPKERNELDefines.hxx new file mode 100644 index 000000000..45a3e9afc --- /dev/null +++ b/src/medtool/src/INTERP_KERNEL/INTERPKERNELDefines.hxx @@ -0,0 +1,34 @@ +// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 +// 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 __INTERPKERNELDEFINES_HXX__ +#define __INTERPKERNELDEFINES_HXX__ + +//export symbols +#ifdef WIN32 +# if defined INTERPKERNEL_EXPORTS || defined interpkernel_EXPORTS +# define INTERPKERNEL_EXPORT __declspec(dllexport) +# else +# define INTERPKERNEL_EXPORT __declspec(dllimport) +# endif +#else +# define INTERPKERNEL_EXPORT +#endif + +#endif diff --git a/src/medtool/src/INTERP_KERNEL/IntegralUniformIntersector.hxx b/src/medtool/src/INTERP_KERNEL/IntegralUniformIntersector.hxx new file mode 100644 index 000000000..171fa99be --- /dev/null +++ b/src/medtool/src/INTERP_KERNEL/IntegralUniformIntersector.hxx @@ -0,0 +1,72 @@ +// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 +// 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 __INTEGRALUNIFORMINTERSECTOR_HXX__ +#define __INTEGRALUNIFORMINTERSECTOR_HXX__ + +#include "TargetIntersector.hxx" + +#include <cmath> + +namespace INTERP_KERNEL +{ + template<class MyMeshType, class MyMatrix> + class IntegralUniformIntersector : public TargetIntersector<MyMeshType,MyMatrix> + { + public: + typedef typename MyMeshType::MyConnType ConnType; + public: + IntegralUniformIntersector(const MyMeshType& mesh, bool isAbs); + double performNormalization(double val) const { if(_is_abs) return fabs(val); else return val; } + void setFromTo(bool val) { _from_to=val; } + void putValueIn(ConnType i, double val, MyMatrix& res) const; + protected: + const MyMeshType& _mesh; + //! if false means fromIntegralUniform if true means toIntegralUniform + bool _from_to; + bool _is_abs; + }; + + template<class MyMeshType, class MyMatrix> + class IntegralUniformIntersectorP0 : public IntegralUniformIntersector<MyMeshType,MyMatrix> + { + public: + typedef typename MyMeshType::MyConnType ConnType; + public: + IntegralUniformIntersectorP0(const MyMeshType& mesh, bool isAbs); + int getNumberOfRowsOfResMatrix() const; + int getNumberOfColsOfResMatrix() const; + void intersectCells(ConnType targetCell, const std::vector<ConnType>& srcCells, MyMatrix& res); + }; + + template<class MyMeshType, class MyMatrix> + class IntegralUniformIntersectorP1 : public IntegralUniformIntersector<MyMeshType,MyMatrix> + { + public: + typedef typename MyMeshType::MyConnType ConnType; + public: + IntegralUniformIntersectorP1(const MyMeshType& mesh, bool isAbs); + int getNumberOfRowsOfResMatrix() const; + int getNumberOfColsOfResMatrix() const; + void intersectCells(ConnType targetCell, const std::vector<ConnType>& srcCells, MyMatrix& res); + }; +} + +#endif diff --git a/src/medtool/src/INTERP_KERNEL/IntegralUniformIntersector.txx b/src/medtool/src/INTERP_KERNEL/IntegralUniformIntersector.txx new file mode 100644 index 000000000..279776323 --- /dev/null +++ b/src/medtool/src/INTERP_KERNEL/IntegralUniformIntersector.txx @@ -0,0 +1,156 @@ +// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 +// 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 __INTEGRALUNIFORMINTERSECTOR_TXX__ +#define __INTEGRALUNIFORMINTERSECTOR_TXX__ + +#include "IntegralUniformIntersector.hxx" +#include "VolSurfUser.txx" + +namespace INTERP_KERNEL +{ + template<class MyMeshType, class MyMatrix> + IntegralUniformIntersector<MyMeshType,MyMatrix>::IntegralUniformIntersector(const MyMeshType& mesh, bool isAbs):_mesh(mesh),_from_to(false),_is_abs(isAbs) + { + } + + template<class MyMeshType, class MyMatrix> + void IntegralUniformIntersector<MyMeshType,MyMatrix>::putValueIn(ConnType iInCMode, double val1, MyMatrix& res) const + { + static const NumberingPolicy numPol=MyMeshType::My_numPol; + double val=performNormalization(val1); + if(_from_to) + { + typename MyMatrix::value_type& resRow=res[0]; + typename MyMatrix::value_type::const_iterator iterRes=resRow.find(OTT<ConnType,numPol>::indFC(iInCMode)); + if(iterRes==resRow.end()) + resRow.insert(std::make_pair(OTT<ConnType,numPol>::indFC(iInCMode),val)); + else + { + double val2=(*iterRes).second+val; + resRow.erase(OTT<ConnType,numPol>::indFC(iInCMode)); + resRow.insert(std::make_pair(OTT<ConnType,numPol>::indFC(iInCMode),val2)); + } + } + else + { + typename MyMatrix::value_type& resRow=res[iInCMode]; + typename MyMatrix::value_type::const_iterator iterRes=resRow.find(OTT<ConnType,numPol>::indFC(0)); + if(iterRes==resRow.end()) + resRow.insert(std::make_pair(OTT<ConnType,numPol>::indFC(0),val)); + else + { + double val2=(*iterRes).second+val; + resRow.erase(OTT<ConnType,numPol>::indFC(0)); + resRow.insert(std::make_pair(OTT<ConnType,numPol>::indFC(0),val2)); + } + } + } + + template<class MyMeshType, class MyMatrix> + IntegralUniformIntersectorP0<MyMeshType,MyMatrix>::IntegralUniformIntersectorP0(const MyMeshType& mesh, bool isAbs):IntegralUniformIntersector<MyMeshType,MyMatrix>(mesh,isAbs) + { + } + + template<class MyMeshType, class MyMatrix> + int IntegralUniformIntersectorP0<MyMeshType,MyMatrix>::getNumberOfRowsOfResMatrix() const + { + if(IntegralUniformIntersector<MyMeshType,MyMatrix>::_from_to) + return 1; + else + return IntegralUniformIntersector<MyMeshType,MyMatrix>::_mesh.getNumberOfElements(); + } + + template<class MyMeshType, class MyMatrix> + int IntegralUniformIntersectorP0<MyMeshType,MyMatrix>::getNumberOfColsOfResMatrix() const + { + if(IntegralUniformIntersector<MyMeshType,MyMatrix>::_from_to) + return IntegralUniformIntersector<MyMeshType,MyMatrix>::_mesh.getNumberOfElements(); + else + return 1; + } + + template<class MyMeshType, class MyMatrix> + void IntegralUniformIntersectorP0<MyMeshType,MyMatrix>::intersectCells(ConnType targetCell, const std::vector<ConnType>& srcCells, MyMatrix& res) + { + static const NumberingPolicy numPol=MyMeshType::My_numPol; + res.resize(getNumberOfRowsOfResMatrix()); + unsigned long nbelem=IntegralUniformIntersector<MyMeshType,MyMatrix>::_mesh.getNumberOfElements(); + const ConnType *connIndx=IntegralUniformIntersector<MyMeshType,MyMatrix>::_mesh.getConnectivityIndexPtr(); + const ConnType *conn=IntegralUniformIntersector<MyMeshType,MyMatrix>::_mesh.getConnectivityPtr(); + const double *coords=IntegralUniformIntersector<MyMeshType,MyMatrix>::_mesh.getCoordinatesPtr(); + for(unsigned long i=0;i<nbelem;i++) + { + INTERP_KERNEL::NormalizedCellType t=IntegralUniformIntersector<MyMeshType,MyMatrix>::_mesh.getTypeOfElement(OTT<ConnType,numPol>::indFC(i)); + double val=computeVolSurfOfCell<ConnType,numPol,MyMeshType::MY_SPACEDIM>(t,conn+OTT<ConnType,numPol>::ind2C(connIndx[i]),connIndx[i+1]-connIndx[i],coords); + IntegralUniformIntersector<MyMeshType,MyMatrix>::putValueIn(i,val,res); + } + } + + template<class MyMeshType, class MyMatrix> + IntegralUniformIntersectorP1<MyMeshType,MyMatrix>::IntegralUniformIntersectorP1(const MyMeshType& mesh, bool isAbs):IntegralUniformIntersector<MyMeshType,MyMatrix>(mesh,isAbs) + { + } + + template<class MyMeshType, class MyMatrix> + int IntegralUniformIntersectorP1<MyMeshType,MyMatrix>::getNumberOfRowsOfResMatrix() const + { + if(IntegralUniformIntersector<MyMeshType,MyMatrix>::_from_to) + return 1; + else + return IntegralUniformIntersector<MyMeshType,MyMatrix>::_mesh.getNumberOfNodes(); + } + + template<class MyMeshType, class MyMatrix> + int IntegralUniformIntersectorP1<MyMeshType,MyMatrix>::getNumberOfColsOfResMatrix() const + { + if(IntegralUniformIntersector<MyMeshType,MyMatrix>::_from_to) + return IntegralUniformIntersector<MyMeshType,MyMatrix>::_mesh.getNumberOfNodes(); + else + return 1; + } + + template<class MyMeshType, class MyMatrix> + void IntegralUniformIntersectorP1<MyMeshType,MyMatrix>::intersectCells(ConnType targetCell, const std::vector<ConnType>& srcCells, MyMatrix& res) + { + static const NumberingPolicy numPol=MyMeshType::My_numPol; + res.resize(getNumberOfRowsOfResMatrix()); + unsigned long nbelem=IntegralUniformIntersector<MyMeshType,MyMatrix>::_mesh.getNumberOfElements(); + const ConnType *connIndx=IntegralUniformIntersector<MyMeshType,MyMatrix>::_mesh.getConnectivityIndexPtr(); + const ConnType *conn=IntegralUniformIntersector<MyMeshType,MyMatrix>::_mesh.getConnectivityPtr(); + const double *coords=IntegralUniformIntersector<MyMeshType,MyMatrix>::_mesh.getCoordinatesPtr(); + for(unsigned long i=0;i<nbelem;i++) + { + INTERP_KERNEL::NormalizedCellType t=IntegralUniformIntersector<MyMeshType,MyMatrix>::_mesh.getTypeOfElement(OTT<ConnType,numPol>::indFC(i)); + int lgth=connIndx[i+1]-connIndx[i]; + const ConnType *locConn=conn+OTT<ConnType,numPol>::ind2C(connIndx[i]); + double val=computeVolSurfOfCell<ConnType,numPol,MyMeshType::MY_SPACEDIM>(t,locConn,lgth,coords); + if(t==NORM_TRI3) + val/=3.; + else if(t==NORM_TETRA4) + val/=4.; + else + throw INTERP_KERNEL::Exception("Invalid cell type detected : must be TRI3 or TETRA4 ! "); + for(int j=0;j<lgth;j++) + IntegralUniformIntersector<MyMeshType,MyMatrix>::putValueIn(OTT<ConnType,numPol>::coo2C(locConn[j]),val,res); + } + } +} + +#endif diff --git a/src/medtool/src/INTERP_KERNEL/InterpKernelCellSimplify.cxx b/src/medtool/src/INTERP_KERNEL/InterpKernelCellSimplify.cxx new file mode 100644 index 000000000..dd985b501 --- /dev/null +++ b/src/medtool/src/INTERP_KERNEL/InterpKernelCellSimplify.cxx @@ -0,0 +1,511 @@ +// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 +// 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 "InterpKernelCellSimplify.hxx" +#include "CellModel.hxx" + +#include <algorithm> +#include <iterator> +#include <sstream> +#include <numeric> +#include <cstring> +#include <limits> +#include <vector> +#include <list> +#include <set> + +using namespace INTERP_KERNEL; + +/*! + * This method takes as input a cell with type 'type' and whose connectivity is defined by (conn,lgth) + * It retrieves the same cell with a potentially different type (in return) whose connectivity is defined by (retConn,retLgth) + * \b WARNING for optimization reason the arrays 'retConn' and 'conn' can overlapped ! + */ +INTERP_KERNEL::NormalizedCellType CellSimplify::simplifyDegeneratedCell(INTERP_KERNEL::NormalizedCellType type, const int *conn, int lgth, int *retConn, int& retLgth) +{ + const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(type); + std::set<int> c(conn,conn+lgth); + c.erase(-1); + bool isObviousNonDegeneratedCell=((int)c.size()==lgth); + if(cm.isQuadratic() || isObviousNonDegeneratedCell) + {//quadratic do nothing for the moment. + retLgth=lgth; + int *tmp=new int[lgth];//no direct std::copy ! overlapping of conn and retConn ! + std::copy(conn,conn+lgth,tmp); + std::copy(tmp,tmp+lgth,retConn); + delete [] tmp; + return type; + } + if(cm.getDimension()==2) + { + int *tmp=new int[lgth]; + tmp[0]=conn[0]; + int newPos=1; + for(int i=1;i<lgth;i++) + if(std::find(tmp,tmp+newPos,conn[i])==tmp+newPos) + tmp[newPos++]=conn[i]; + INTERP_KERNEL::NormalizedCellType ret=tryToUnPoly2D(cm.isQuadratic(),tmp,newPos,retConn,retLgth); + delete [] tmp; + return ret; + } + if(cm.getDimension()==3) + { + int nbOfFaces,lgthOfPolyhConn; + int *zipFullReprOfPolyh=getFullPolyh3DCell(type,conn,lgth,nbOfFaces,lgthOfPolyhConn); + INTERP_KERNEL::NormalizedCellType ret=tryToUnPoly3D(zipFullReprOfPolyh,nbOfFaces,lgthOfPolyhConn,retConn,retLgth); + delete [] zipFullReprOfPolyh; + return ret; + } + throw INTERP_KERNEL::Exception("CellSimplify::simplifyDegeneratedCell : works only with 2D and 3D cell !"); +} + + +/*! + * This static method tries to unpolygonize a cell whose connectivity is given by 'conn' and 'lgth'. + * Contrary to INTERP_KERNEL::CellSimplify::simplifyDegeneratedCell method 'conn' and 'retConn' do not overlap. + */ +INTERP_KERNEL::NormalizedCellType CellSimplify::tryToUnPoly2D(bool isQuad, const int *conn, int lgth, int *retConn, int& retLgth) +{ + retLgth=lgth; + std::copy(conn,conn+lgth,retConn); + if(!isQuad) + { + switch(lgth) + { + case 3: + return INTERP_KERNEL::NORM_TRI3; + case 4: + return INTERP_KERNEL::NORM_QUAD4; + default: + return INTERP_KERNEL::NORM_POLYGON; + } + } + else + { + switch(lgth) + { + case 6: + return INTERP_KERNEL::NORM_TRI6; + case 8: + return INTERP_KERNEL::NORM_QUAD8; + default: + return INTERP_KERNEL::NORM_QPOLYG; + } + } +} + +/*! + * This method takes as input a 3D linear cell and put its representation in returned array. Warning the returned array has to be deallocated. + * The length of the returned array is specified by out parameter + * The format of output array is the following : + * 1,2,3,-1,3,4,2,-1,3,4,1,-1,1,2,4,NORM_TRI3,NORM_TRI3,NORM_TRI3 (faces type at the end of classical polyhedron nodal description) + */ +int *CellSimplify::getFullPolyh3DCell(INTERP_KERNEL::NormalizedCellType type, const int *conn, int lgth, + int& retNbOfFaces, int& retLgth) +{ + const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(type); + unsigned nbOfFaces=cm.getNumberOfSons2(conn,lgth); + int *tmp=new int[nbOfFaces*(lgth+1)]; + int *work=tmp; + std::vector<int> faces; + for(unsigned j=0;j<nbOfFaces;j++) + { + INTERP_KERNEL::NormalizedCellType type2; + unsigned offset=cm.fillSonCellNodalConnectivity2(j,conn,lgth,work,type2); + // + int *tmp2=new int[offset]; + tmp2[0]=work[0]; + int newPos=1; + for(unsigned k=1;k<offset;k++) + if(std::find(tmp2,tmp2+newPos,work[k])==tmp2+newPos) + tmp2[newPos++]=work[k]; + if(newPos<3) + { + delete [] tmp2; + continue; + } + int tmp3; + faces.push_back(tryToUnPoly2D(CellModel::GetCellModel(type2).isQuadratic(),tmp2,newPos,work,tmp3)); + delete [] tmp2; + // + work+=newPos; + *work++=-1; + } + std::copy(faces.begin(),faces.end(),--work); + retNbOfFaces=(int)faces.size(); + retLgth=(int)std::distance(tmp,work); + return tmp; +} + +/*! + * This static method tries to unpolygonize a cell whose connectivity is given by 'conn' (format is the same as specified in + * method INTERP_KERNEL::CellSimplify::getFullPolyh3DCell ) and 'lgth'+'nbOfFaces'. + * Contrary to INTERP_KERNEL::CellSimplify::simplifyDegeneratedCell method 'conn' and 'retConn' do not overlap. + */ +INTERP_KERNEL::NormalizedCellType CellSimplify::tryToUnPoly3D(const int *conn, int nbOfFaces, int lgth, int *retConn, int& retLgth) +{ + std::set<int> nodes(conn,conn+lgth); + nodes.erase(-1); + int nbOfNodes=(int)nodes.size(); + int magicNumber=100*nbOfNodes+nbOfFaces; + switch(magicNumber) + { + case 806: + return tryToUnPolyHex8(conn,nbOfFaces,lgth,retConn,retLgth); + case 1208: + return tryToUnPolyHexp12(conn,nbOfFaces,lgth,retConn,retLgth); + case 605: + return tryToUnPolyPenta6(conn,nbOfFaces,lgth,retConn,retLgth); + case 505: + return tryToUnPolyPyra5(conn,nbOfFaces,lgth,retConn,retLgth); + case 404: + return tryToUnPolyTetra4(conn,nbOfFaces,lgth,retConn,retLgth); + default: + retLgth=lgth; + std::copy(conn,conn+lgth,retConn); + return INTERP_KERNEL::NORM_POLYHED; + } +} + +bool CellSimplify::orientOppositeFace(const int *baseFace, int *retConn, const int *sideFace, int lgthBaseFace) +{ + std::vector<int> tmp2; + std::set<int> bases(baseFace,baseFace+lgthBaseFace); + std::set<int> sides(sideFace,sideFace+4); + std::set_intersection(bases.begin(),bases.end(),sides.begin(),sides.end(),std::back_insert_iterator< std::vector<int> >(tmp2)); + if(tmp2.size()!=2) + return false; + std::vector< std::pair<int,int> > baseEdges(lgthBaseFace); + std::vector< std::pair<int,int> > oppEdges(lgthBaseFace); + std::vector< std::pair<int,int> > sideEdges(4); + for(int i=0;i<lgthBaseFace;i++) + { + baseEdges[i]=std::pair<int,int>(baseFace[i],baseFace[(i+1)%lgthBaseFace]); + oppEdges[i]=std::pair<int,int>(retConn[i],retConn[(i+1)%lgthBaseFace]); + } + for(int i=0;i<4;i++) + sideEdges[i]=std::pair<int,int>(sideFace[i],sideFace[(i+1)%4]); + std::vector< std::pair<int,int> > tmp; + std::set< std::pair<int,int> > baseEdgesS(baseEdges.begin(),baseEdges.end()); + std::set< std::pair<int,int> > sideEdgesS(sideEdges.begin(),sideEdges.end()); + std::set_intersection(baseEdgesS.begin(),baseEdgesS.end(),sideEdgesS.begin(),sideEdgesS.end(),std::back_insert_iterator< std::vector< std::pair<int,int> > >(tmp)); + if(tmp.empty()) + { + //reverse sideFace + for(int i=0;i<4;i++) + { + std::pair<int,int> p=sideEdges[i]; + std::pair<int,int> r(p.second,p.first); + sideEdges[i]=r; + } + //end reverse sideFace + std::set< std::pair<int,int> > baseEdgesS2(baseEdges.begin(),baseEdges.end()); + std::set< std::pair<int,int> > sideEdgesS2(sideEdges.begin(),sideEdges.end()); + std::set_intersection(baseEdgesS2.begin(),baseEdgesS2.end(),sideEdgesS2.begin(),sideEdgesS2.end(),std::back_insert_iterator< std::vector< std::pair<int,int> > >(tmp)); + if(tmp.empty()) + return false; + } + if(tmp.size()!=1) + return false; + bool found=false; + std::pair<int,int> pInOpp; + for(int i=0;i<4 && !found;i++) + {//finding the pair(edge) in sideFace that do not include any node of tmp[0] edge + found=(tmp[0].first!=sideEdges[i].first && tmp[0].first!=sideEdges[i].second && + tmp[0].second!=sideEdges[i].first && tmp[0].second!=sideEdges[i].second); + if(found) + {//found ! reverse it + pInOpp.first=sideEdges[i].second; + pInOpp.second=sideEdges[i].first; + } + } + if(!found) + return false; + int pos=(int)std::distance(baseEdges.begin(),std::find(baseEdges.begin(),baseEdges.end(),tmp[0])); + std::vector< std::pair<int,int> >::iterator it=std::find(oppEdges.begin(),oppEdges.end(),pInOpp); + if(it==oppEdges.end())//the opposite edge of side face is not found opposite face ... maybe problem of orientation of polyhedron + return false; + int pos2=(int)std::distance(oppEdges.begin(),it); + int offset=pos-pos2; + if(offset<0) + offset+=lgthBaseFace; + //this is the end copy the result + int *tmp3=new int[lgthBaseFace]; + for(int i=0;i<lgthBaseFace;i++) + tmp3[(offset+i)%lgthBaseFace]=oppEdges[i].first; + std::copy(tmp3,tmp3+lgthBaseFace,retConn); + delete [] tmp3; + return true; +} + +bool CellSimplify::isWellOriented(const int *baseFace, int *retConn, const int *sideFace, int lgthBaseFace) +{ + return true; +} + +/*! + * This method is trying to permute the connectivity of 'oppFace' face so that the k_th node of 'baseFace' is associated to the + * k_th node in retConnOfOppFace. Excluded faces 'baseFace' and 'oppFace' all the other faces in 'conn' must be QUAD4 faces. + * If the arragement process succeeds true is returned and retConnOfOppFace is filled. + */ +bool CellSimplify::tryToArrangeOppositeFace(const int *conn, int lgth, int lgthBaseFace, const int *baseFace, const int *oppFace, int nbOfFaces, int *retConnOfOppFace) +{ + retConnOfOppFace[0]=oppFace[0]; + for(int j=1;j<lgthBaseFace;j++) + retConnOfOppFace[j]=oppFace[lgthBaseFace-j]; + const int *curFace=conn; + int sideFace=0; + bool ret=true; + for(int i=0;i<nbOfFaces && ret;i++) + { + if(curFace!=baseFace && curFace!=oppFace) + { + if(sideFace==0) + ret=orientOppositeFace(baseFace,retConnOfOppFace,curFace,lgthBaseFace); + else + ret=isWellOriented(baseFace,retConnOfOppFace,curFace,lgthBaseFace); + sideFace++; + } + curFace=std::find(curFace,conn+lgth,-1); + curFace++; + } + return ret; +} + +/*! + * Cell with 'conn' connectivity has been detected as a good candidate. Full check of this. If yes NORM_HEXA8 is returned. + * This method is only callable if in 'conn' there is 8 nodes and 6 faces. + * If fails a POLYHED is returned. + */ +INTERP_KERNEL::NormalizedCellType CellSimplify::tryToUnPolyHex8(const int *conn, int nbOfFaces, int lgth, int *retConn, int& retLgth) +{ + if(std::find_if(conn+lgth,conn+lgth+nbOfFaces,std::bind2nd(std::not_equal_to<int>(),(int)INTERP_KERNEL::NORM_QUAD4))==conn+lgth+nbOfFaces) + {//6 faces are QUAD4. + int oppositeFace=-1; + std::set<int> conn1(conn,conn+4); + for(int i=1;i<6 && oppositeFace<0;i++) + { + std::vector<int> tmp; + std::set<int> conn2(conn+5*i,conn+5*i+4); + std::set_intersection(conn1.begin(),conn1.end(),conn2.begin(),conn2.end(),std::back_insert_iterator< std::vector<int> >(tmp)); + if(tmp.empty()) + oppositeFace=i; + } + if(oppositeFace>=1) + {//oppositeFace of face#0 found. + int tmp2[4]; + if(tryToArrangeOppositeFace(conn,lgth,4,conn,conn+5*oppositeFace,6,tmp2)) + { + std::copy(conn,conn+4,retConn); + std::copy(tmp2,tmp2+4,retConn+4); + retLgth=8; + return INTERP_KERNEL::NORM_HEXA8; + } + } + } + retLgth=lgth; + std::copy(conn,conn+lgth,retConn); + return INTERP_KERNEL::NORM_POLYHED; +} + +INTERP_KERNEL::NormalizedCellType CellSimplify::tryToUnPolyHexp12(const int *conn, int nbOfFaces, int lgth, int *retConn, int& retLgth) +{ + std::size_t nbOfHexagon=std::count(conn+lgth,conn+lgth+nbOfFaces,(int)INTERP_KERNEL::NORM_POLYGON); + std::size_t nbOfQuad=std::count(conn+lgth,conn+lgth+nbOfFaces,(int)INTERP_KERNEL::NORM_QUAD4); + if(nbOfQuad==6 && nbOfHexagon==2) + { + const int *hexag0=std::find(conn+lgth,conn+lgth+nbOfFaces,(int)INTERP_KERNEL::NORM_POLYGON); + std::size_t hexg0Id=std::distance(conn+lgth,hexag0); + const int *hexag1=std::find(hexag0+1,conn+lgth+nbOfFaces,(int)INTERP_KERNEL::NORM_POLYGON); + std::size_t hexg1Id=std::distance(conn+lgth,hexag1); + const int *connHexag0=conn+5*hexg0Id; + std::size_t lgthH0=std::distance(connHexag0,std::find(connHexag0,conn+lgth,-1)); + if(lgthH0==6) + { + const int *connHexag1=conn+5*hexg0Id+7+(hexg1Id-hexg0Id-1)*5; + std::size_t lgthH1=std::distance(connHexag1,std::find(connHexag1,conn+lgth,-1)); + if(lgthH1==6) + { + std::vector<int> tmp; + std::set<int> conn1(connHexag0,connHexag0+6); + std::set<int> conn2(connHexag1,connHexag1+6); + std::set_intersection(conn1.begin(),conn1.end(),conn2.begin(),conn2.end(),std::back_insert_iterator< std::vector<int> >(tmp)); + if(tmp.empty()) + { + int tmp2[6]; + if(tryToArrangeOppositeFace(conn,lgth,6,connHexag0,connHexag1,8,tmp2)) + { + std::copy(connHexag0,connHexag0+6,retConn); + std::copy(tmp2,tmp2+6,retConn+6); + retLgth=12; + return INTERP_KERNEL::NORM_HEXGP12; + } + } + } + } + } + retLgth=lgth; + std::copy(conn,conn+lgth,retConn); + return INTERP_KERNEL::NORM_POLYHED; +} + +/*! + * Cell with 'conn' connectivity has been detected as a good candidate. Full check of this. If yes NORM_PENTA6 is returned. + * If fails a POLYHED is returned. + */ +INTERP_KERNEL::NormalizedCellType CellSimplify::tryToUnPolyPenta6(const int *conn, int nbOfFaces, int lgth, int *retConn, int& retLgth) +{ + std::size_t nbOfTriFace=std::count(conn+lgth,conn+lgth+nbOfFaces,(int)INTERP_KERNEL::NORM_TRI3); + std::size_t nbOfQuadFace=std::count(conn+lgth,conn+lgth+nbOfFaces,(int)INTERP_KERNEL::NORM_QUAD4); + if(nbOfTriFace==2 && nbOfQuadFace==3) + { + std::size_t tri3_0=std::distance(conn+lgth,std::find(conn+lgth,conn+lgth+nbOfFaces,(int)INTERP_KERNEL::NORM_TRI3)); + std::size_t tri3_1=std::distance(conn+lgth,std::find(conn+lgth+tri3_0+1,conn+lgth+nbOfFaces,(int)INTERP_KERNEL::NORM_TRI3)); + const int *tri_0=0,*tri_1=0; + const int *w=conn; + for(std::size_t i=0;i<5;i++) + { + if(i==tri3_0) + tri_0=w; + if(i==tri3_1) + tri_1=w; + w=std::find(w,conn+lgth,-1); + w++; + } + std::vector<int> tmp; + std::set<int> conn1(tri_0,tri_0+3); + std::set<int> conn2(tri_1,tri_1+3); + std::set_intersection(conn1.begin(),conn1.end(),conn2.begin(),conn2.end(),std::back_insert_iterator< std::vector<int> >(tmp)); + if(tmp.empty()) + { + int tmp2[3]; + if(tryToArrangeOppositeFace(conn,lgth,3,tri_0,tri_1,5,tmp2)) + { + std::copy(tri_0,tri_0+3,retConn); + std::copy(tmp2,tmp2+3,retConn+3); + retLgth=6; + return INTERP_KERNEL::NORM_PENTA6; + } + } + } + retLgth=lgth; + std::copy(conn,conn+lgth,retConn); + return INTERP_KERNEL::NORM_POLYHED; +} + +/*! + * Cell with 'conn' connectivity has been detected as a good candidate. Full check of this. If yes NORM_PYRA5 is returned. + * If fails a POLYHED is returned. + */ +INTERP_KERNEL::NormalizedCellType CellSimplify::tryToUnPolyPyra5(const int *conn, int nbOfFaces, int lgth, int *retConn, int& retLgth) +{ + std::size_t nbOfTriFace=std::count(conn+lgth,conn+lgth+nbOfFaces,(int)INTERP_KERNEL::NORM_TRI3); + std::size_t nbOfQuadFace=std::count(conn+lgth,conn+lgth+nbOfFaces,(int)INTERP_KERNEL::NORM_QUAD4); + if(nbOfTriFace==4 && nbOfQuadFace==1) + { + std::size_t quad4_pos=std::distance(conn+lgth,std::find(conn+lgth,conn+lgth+nbOfFaces,(int)INTERP_KERNEL::NORM_QUAD4)); + const int *quad4=0; + const int *w=conn; + for(std::size_t i=0;i<5 && quad4==0;i++) + { + if(i==quad4_pos) + quad4=w; + w=std::find(w,conn+lgth,-1); + w++; + } + std::set<int> quad4S(quad4,quad4+4); + w=conn; + bool ok=true; + int point=-1; + for(std::size_t i=0;i<5 && ok;i++) + { + if(i!=quad4_pos) + { + std::vector<int> tmp; + std::set<int> conn2(w,w+3); + std::set_intersection(conn2.begin(),conn2.end(),quad4S.begin(),quad4S.end(),std::back_insert_iterator< std::vector<int> >(tmp)); + ok=tmp.size()==2; + tmp.clear(); + std::set_difference(conn2.begin(),conn2.end(),quad4S.begin(),quad4S.end(),std::back_insert_iterator< std::vector<int> >(tmp)); + ok=ok && tmp.size()==1; + if(ok) + { + if(point>=0) + ok=point==tmp[0]; + else + point=tmp[0]; + } + } + w=std::find(w,conn+lgth,-1); + w++; + } + if(ok && point>=0) + { + std::copy(quad4,quad4+4,retConn); + retConn[4]=point; + retLgth=5; + return INTERP_KERNEL::NORM_PYRA5; + } + } + retLgth=lgth; + std::copy(conn,conn+lgth,retConn); + return INTERP_KERNEL::NORM_POLYHED; +} + +/*! + * Cell with 'conn' connectivity has been detected as a good candidate. Full check of this. If yes NORM_TETRA4 is returned. + * If fails a POLYHED is returned. + */ +INTERP_KERNEL::NormalizedCellType CellSimplify::tryToUnPolyTetra4(const int *conn, int nbOfFaces, int lgth, int *retConn, int& retLgth) +{ + if(std::find_if(conn+lgth,conn+lgth+nbOfFaces,std::bind2nd(std::not_equal_to<int>(),(int)INTERP_KERNEL::NORM_TRI3))==conn+lgth+nbOfFaces) + { + std::set<int> tribase(conn,conn+3); + int point=-1; + bool ok=true; + for(int i=1;i<4 && ok;i++) + { + std::vector<int> tmp; + std::set<int> conn2(conn+i*4,conn+4*i+3); + std::set_intersection(conn2.begin(),conn2.end(),tribase.begin(),tribase.end(),std::back_insert_iterator< std::vector<int> >(tmp)); + ok=tmp.size()==2; + tmp.clear(); + std::set_difference(conn2.begin(),conn2.end(),tribase.begin(),tribase.end(),std::back_insert_iterator< std::vector<int> >(tmp)); + ok=ok && tmp.size()==1; + if(ok) + { + if(point>=0) + ok=point==tmp[0]; + else + point=tmp[0]; + } + } + if(ok && point>=0) + { + std::copy(conn,conn+3,retConn); + retConn[3]=point; + retLgth=4; + return INTERP_KERNEL::NORM_TETRA4; + } + } + retLgth=lgth; + std::copy(conn,conn+lgth,retConn); + return INTERP_KERNEL::NORM_POLYHED; +} diff --git a/src/medtool/src/INTERP_KERNEL/InterpKernelCellSimplify.hxx b/src/medtool/src/INTERP_KERNEL/InterpKernelCellSimplify.hxx new file mode 100644 index 000000000..94d3163c1 --- /dev/null +++ b/src/medtool/src/INTERP_KERNEL/InterpKernelCellSimplify.hxx @@ -0,0 +1,49 @@ +// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 +// 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 __INTERPKERNELCELLSIMPLIFY_HXX__ +#define __INTERPKERNELCELLSIMPLIFY_HXX__ + +#include "INTERPKERNELDefines.hxx" +#include "NormalizedUnstructuredMesh.hxx" +#include "InterpKernelException.hxx" + +namespace INTERP_KERNEL +{ + class INTERPKERNEL_EXPORT CellSimplify + { + public: + static INTERP_KERNEL::NormalizedCellType simplifyDegeneratedCell(INTERP_KERNEL::NormalizedCellType type, const int *conn, int lgth, int *retConn, int& retLgth); + static int *getFullPolyh3DCell(INTERP_KERNEL::NormalizedCellType type, const int *conn, int lgth, + int& retNbOfFaces, int& retLgth); + static INTERP_KERNEL::NormalizedCellType tryToUnPoly2D(bool isQuad, const int *conn, int lgth, int *retConn, int& retLgth); + static INTERP_KERNEL::NormalizedCellType tryToUnPoly3D(const int *conn, int nbOfFaces, int lgth, int *retConn, int& retLgth); + static INTERP_KERNEL::NormalizedCellType tryToUnPolyHex8(const int *conn, int nbOfFaces, int lgth, int *retConn, int& retLgth); + static INTERP_KERNEL::NormalizedCellType tryToUnPolyHexp12(const int *conn, int nbOfFaces, int lgth, int *retConn, int& retLgth); + static INTERP_KERNEL::NormalizedCellType tryToUnPolyPenta6(const int *conn, int nbOfFaces, int lgth, int *retConn, int& retLgth); + static INTERP_KERNEL::NormalizedCellType tryToUnPolyPyra5(const int *conn, int nbOfFaces, int lgth, int *retConn, int& retLgth); + static INTERP_KERNEL::NormalizedCellType tryToUnPolyTetra4(const int *conn, int nbOfFaces, int lgth, int *retConn, int& retLgth); + static bool tryToArrangeOppositeFace(const int *conn, int lgth, int lgthBaseFace, const int *baseFace, const int *oppFaceId, int nbOfFaces, int *retConnOfOppFace); + static bool isWellOriented(const int *baseFace, int *retConn, const int *sideFace, int lgthBaseFace); + static bool orientOppositeFace(const int *baseFace, int *retConn, const int *sideFace, int lgthBaseFace); + }; +} + +#endif diff --git a/src/medtool/src/INTERP_KERNEL/InterpKernelMatrix.hxx b/src/medtool/src/INTERP_KERNEL/InterpKernelMatrix.hxx new file mode 100755 index 000000000..6a65f8b81 --- /dev/null +++ b/src/medtool/src/INTERP_KERNEL/InterpKernelMatrix.hxx @@ -0,0 +1,439 @@ +// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 +// 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 __INTERPKERNELMATRIX_HXX_ +#define __INTERPKERNELMATRIX_HXX__ + +#include "InterpolationUtils.hxx" + +#include <vector> +#include <iostream> +#include <ostream> +#include <istream> +#include <map> + +namespace INTERP_KERNEL +{ + template<class T, NumberingPolicy type> + class Matrix; + + template<class U, NumberingPolicy type> + std::ostream& operator<<(std::ostream& in, const Matrix<U,type>& m); + template<class U, NumberingPolicy type> + std::istream& operator>>(std::istream& in, Matrix<U,type>& m); + + template<class T, NumberingPolicy type=ALL_C_MODE> + class Matrix + { + + class KeyComparator + { + public: + KeyComparator(int val):_val(val) { } + bool operator()(const typename std::pair<int,T>& val) { return val.first==_val; } + protected: + int _val; + }; + + class Row : public std::vector< std::pair<int,T> > + { + public: + Row():std::vector< std::pair<int,T> >(){}; + Row (const Row& row) + { + this->resize(row.size()); + for (int i=0; i<this->size(); i++) + (*this)[i]=row[i]; + } + Row& operator= (const Row& row) + { + this->resize(row.size()); + for (int i=0; i<this->size(); i++) + (*this)[i]=row[i]; + return *this; + } + typename std::vector< std::pair<int,T> >::const_iterator find(int elem) const + { + return std::find_if(std::vector< std::pair<int,T> >::begin(),std::vector< std::pair<int,T> >::end(),KeyComparator(elem)); + } + + void erase(int elem) { std::vector< std::pair<int,T> >::erase(std::find_if(std::vector< std::pair<int,T> >::begin(),std::vector< std::pair<int,T> >::end(),KeyComparator(elem))); } + + void insert(const std::pair<int,T>& myPair) { vector<std::pair<int,T> >::push_back(myPair); } + }; + + private: + unsigned int _nb_rows; + T* _coeffs; + unsigned int* _cols; + std::vector<unsigned int> _ncols_offset; + std::vector< Row > _auxiliary_matrix; + friend std::ostream& operator<<<>(std::ostream& in, const Matrix<T,type>& m); + friend std::istream& operator>><>(std::istream& in, Matrix<T,type>& m); + bool _is_configured; + public: + typedef Row value_type; + public: + Matrix():_coeffs(0), _cols(0), _nb_rows(0), _is_configured(false) + { } + Matrix(int nbrows):_coeffs(0), _cols(0), _is_configured(false) + { _nb_rows=nbrows; } + Matrix(std::vector<std::map<int,T> > & matrix) : + _coeffs(0), _cols(0), _is_configured(false) + { + _nb_rows=matrix.size(); + _auxiliary_matrix.resize(_nb_rows); + for (int i=0; i<_nb_rows; i++) + { + typename std::map<int,T>::iterator it; + for (it=matrix[i].begin(); it != matrix[i].end(); it++) + _auxiliary_matrix[i].push_back(*it);//MN: pq push_back plutot que simple affectation? + } + } + /*!Copy constructor + */ + Matrix(const Matrix & m) + { + _is_configured=m._is_configured; + _nb_rows=m._nb_rows; + _auxiliary_matrix=m._auxiliary_matrix; + _ncols_offset=m._ncols_offset; + if (_is_configured) + { + int size=_ncols_offset[_nb_rows]; + _coeffs = new double[size]; + _cols = new unsigned int[size]; + memcpy(_coeffs, m._coeffs, size*sizeof(double)); + memcpy(_cols, m._cols, size*sizeof(int)); + } + } + + ~Matrix() + { + delete[] _coeffs; + delete[] _cols; + } + + Matrix& operator=(const Matrix& m) + { + _is_configured=m._is_configured; + _nb_rows=m._nb_rows; + _auxiliary_matrix=m._auxiliary_matrix; + _ncols_offset=m._ncols_offset; + if (_is_configured) + { + int size=_ncols_offset[_nb_rows]; + _coeffs = new double[size]; + _cols = new unsigned int[size]; + memcpy(_coeffs, m._coeffs, size*sizeof(double)); + memcpy(_cols, m._cols, size*sizeof(int)); + } + return this; + } + + /*! declares a method that specifies the number of rows */ + void resize(unsigned int nbrows) + { + _nb_rows=nbrows; + _auxiliary_matrix.resize(nbrows); + } + + /*! sets (i,j) coefficient to \a value */ + void setIJ(int irow, int icol, T value) + { + if (_is_configured) + throw Exception("filling a configured matrix"); + if (_auxiliary_matrix.empty()) + _auxiliary_matrix.resize(_nb_rows); + + for (unsigned int i=0; i< _auxiliary_matrix[OTT<int,type>::ind2C(irow)].size(); i++) + if (_auxiliary_matrix[OTT<int,type>::ind2C(irow)][i].first == icol) + { + _auxiliary_matrix[OTT<int,type>::ind2C(irow)][i].second = value; + return; + } + _auxiliary_matrix[OTT<int,type>::ind2C(irow)].push_back(std::make_pair(icol, value)); + } + + /*! + Matrix multiplies vector \a input and stores the result in + vector \a output. + The vector pointed by \a input must be dimensioned + to the number of columns while the vector pointed by output must be + dimensioned to the number of rows. + */ + void multiply(const T* const input, T* const output) + { + if (!_is_configured) + configure(); + + for (int i=0; i< _nb_rows; i++) + { + output[i]=0.; + for (unsigned int j=_ncols_offset[i]; j< _ncols_offset[i+1]; j++) + { + int icol = _cols[j]; + output[i]+=input[icol]*_coeffs[j]; + } + } + } + + /*! + Matrix multiplies vector \a input and stores the result in + vector \a output. + input and output are supposed to represent the same field + discretised on two different on meshes. + nb_comp is the number of components of the fields input and output + The vector pointed by \a input must be dimensioned + to the number of columns times nb_comp while the vector pointed by output must be + dimensioned to the number of rows times nb_comp. + */ + void multiply(const T* const input, T* const output, int nb_comp) + { + if (!_is_configured) + configure(); + + for (int i=0; i< _nb_rows; i++) + { + for(int comp = 0; comp < nb_comp; comp++) + output[i*nb_comp+comp]=0.; + for (unsigned int j=_ncols_offset[i]; j< _ncols_offset[i+1]; j++) + { + int icol = _cols[j]; + for(int comp = 0; comp < nb_comp; comp++) + output[i*nb_comp+comp]+=input[icol*nb_comp+comp]*_coeffs[j]; + } + } + } + /*! + Transpose-multiplies vector \a input and stores the result in + vector \a output. + nb_cols is the number of columns of the matrix, (it is not an attribute of the class) + The vector pointed by \a input must be dimensioned + to the number of lines _nb_rows while the vector pointed by output must be + dimensioned to the number of columns nb_cols. + */ + void transposeMultiply(const T* const input, T* const output, int nb_cols) + { + if (!_is_configured) + configure(); + + for (int icol=0; icol< nb_cols; icol++) + output[icol]=0.; + for (int i=0; i< _nb_rows; i++) + { + for (unsigned int j=_ncols_offset[i]; j< _ncols_offset[i+1]; j++) + { + int icol = _cols[j]; + output[icol]+=input[i]*_coeffs[j]; + } + } + } + /*! + Transpose-multiplies vector \a input and stores the result in + vector \a output. + input and output are supposed to represent the same field + discretised on two different on meshes. + nb_comp is the number of components of the fields input and output + nb_cols is the number of columns of the matrix, (it is not an attribute of the class) + The vector pointed by \a input must be dimensioned + to _nb_rows*nb_comp while the vector pointed by output must be + dimensioned to nb_cols*nb_comp. + */ + void transposeMultiply(const T* const input, T* const output, int nb_cols, int nb_comp) + { + if (!_is_configured) + configure(); + + for (int icol=0; icol< nb_cols; icol++) + for(int comp = 0; comp < nb_comp; comp++) + output[icol*nb_comp+comp]=0.; + + for (int i=0; i< _nb_rows; i++) + { + for (unsigned int j=_ncols_offset[i]; j< _ncols_offset[i+1]; j++) + { + int icol = _cols[j]; + for(int comp = 0; comp < nb_comp; comp++) + output[icol*nb_comp+comp]+=input[i*nb_comp+comp]*_coeffs[j]; + } + } + } + /* + Sums the coefficients of each column of the matrix + nb_cols is the number of columns of the matrix, (it is not an attribute of the class) + The vector output must be dimensioned to nb_cols + */ + void colSum(std::vector< T >& output, int nb_cols) + { + if (!_is_configured) + configure(); + for (int icol=0; icol< nb_cols; icol++) + output[icol]=0.; + for (int i=0; i< _nb_rows; i++) + { + for (unsigned int j=_ncols_offset[i]; j< _ncols_offset[i+1]; j++) + { + int icol = _cols[j]; + output[icol]+=_coeffs[j]; + } + } + } + + /* + Sums the coefficients of each row of the matrix + The vector output must be dimensioned to _nb_rows + */ + void rowSum(std::vector< T >& output) + { + if (!_is_configured) + configure(); + for (int i=0; i< _nb_rows; i++) + { + output[i]=0; + for (unsigned int j=_ncols_offset[i]; j< _ncols_offset[i+1]; j++) + output[i]+=_coeffs[j]; + } + } + + /*! This operation freezes the profile of the matrix + and puts it under a CSR form so that it becomes + efficient both in terms of memory occupation and + in terms of multiplication */ + + void configure() + { + _ncols_offset.resize(_nb_rows+1); + _ncols_offset[0]=0; + for (unsigned int i=0; i<_nb_rows; i++) + _ncols_offset[i+1]=_ncols_offset[i]+_auxiliary_matrix[i].size(); + int nbcoeffs= _ncols_offset[_nb_rows]; + _cols=new unsigned int[nbcoeffs]; + _coeffs=new T[nbcoeffs]; + unsigned int* cols_ptr=_cols; + T* coeffs_ptr=_coeffs; + for (unsigned int i=0; i<_nb_rows; i++) + { + for (unsigned int j=0; j<_auxiliary_matrix[i].size(); j++) + { + *cols_ptr++ = OTT<int,type>::ind2C(_auxiliary_matrix[i][j].first); + *coeffs_ptr++ = _auxiliary_matrix[i][j].second; + } + } + _auxiliary_matrix.clear(); + _is_configured=true; + } + + /*! + * 0 <= irow < n + */ + Row &operator [] (unsigned int irow) + { + return _auxiliary_matrix[irow]; + } + + int getNbRows() + { + return _nb_rows; + } + + }; + + /*! output to an ascii file + only nonzero elements are written + - the first line contains the indexing (0 or 1) + - the second line contains the number of rows. + - for each row, a line contains: + - the number of nonzero coeffs + - and for each coeff : icol, value + + for instance, matrix + | 1.0 0.0 0.5 | + | 0.0 1.0 0.0 | + | 0.2 0.0 1.0 | + will be displayed in 0-indexing as + 0 + 3 + 2 0 1.0 2 0.5 + 1 1 1.0 + 2 0 0.2 2 1.0 + */ + + template<class T, NumberingPolicy type> + std::ostream& operator<<(std::ostream& out, const Matrix<T, type>& m) + { + if (m._is_configured) + { + out << OTT<unsigned int,type>::indFC(0) <<std::endl; + out << m._nb_rows<<std::endl; + for (unsigned int i=0; i<m._nb_rows; i++) + { + out << m._ncols_offset[i+1]-m._ncols_offset[i]; + for (unsigned int j=m._ncols_offset[i]; j<m._ncols_offset[i+1]; j++) + out <<"\t"<< OTT<unsigned int,type>::indFC(m._cols[j]) <<"\t"<<m._coeffs[j]; + out<<std::endl; + } + } + else + { + out << OTT<unsigned int,type>::indFC(0) <<"\n"; + out << m._nb_rows <<"\n"; + for (unsigned int i=0; i<m._nb_rows; i++) + { + out<< m._auxiliary_matrix[i].size(); + for (unsigned int j=0; j<m._auxiliary_matrix[i].size(); j++) + out << "\t" <<m._auxiliary_matrix[i][j].first <<"\t" + <<m._auxiliary_matrix[i][j].second; + out <<"\n"; + } + } + return out; + } + + template<class T, NumberingPolicy type> + std::istream& operator>>(std::istream& in, Matrix<T,type>& m) + { + int index_base_test; + in >> index_base_test; + if (index_base_test!=OTT<unsigned int,type>::indFC(0)) + { + std::cerr << "file index is "<<index_base_test<<std::endl; + throw Exception("incompatible indexing reading matrix"); + } + in >> m._nb_rows; + m._auxiliary_matrix.resize(m._nb_rows); + for (unsigned int i=0; i<m._nb_rows; i++) + { + unsigned int ncols; + in >> ncols; + m._auxiliary_matrix[i].resize(ncols); + double value; + unsigned int col; + for (unsigned int j=0; j<ncols; j++) + { + in>>col; + in>>value; + m._auxiliary_matrix[i].push_back(std::make_pair(col, value)); + } + } + return in; + } +} + +#endif diff --git a/src/medtool/src/INTERP_KERNEL/InterpKernelMatrixTools.cxx b/src/medtool/src/INTERP_KERNEL/InterpKernelMatrixTools.cxx new file mode 100644 index 000000000..59cfecaa3 --- /dev/null +++ b/src/medtool/src/INTERP_KERNEL/InterpKernelMatrixTools.cxx @@ -0,0 +1,425 @@ +// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 +// 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 "InterpKernelMatrixTools.hxx" +#include "InterpKernelException.hxx" +#include "InterpKernelAutoPtr.hxx" + +#include <sstream> +#include <algorithm> + +namespace INTERP_KERNEL +{ + /* + * Computes the dot product of two vectors. + * This routine uses unrolled loops for increments equal to one. + * + * Reference: + * + * Jack Dongarra, Jim Bunch, Cleve Moler, Pete Stewart, + * LINPACK User's Guide, + * SIAM, 1979, + * ISBN13: 978-0-898711-72-1, + * LC: QA214.L56. + * + * Charles Lawson, Richard Hanson, David Kincaid, Fred Krogh, + * Basic Linear Algebra Subprograms for Fortran Usage, + * Algorithm 539, + * ACM Transactions on Mathematical Software, + * Volume 5, Number 3, September 1979, pages 308-323. + * + * \param [in] n the number of entries in the vectors. + * \param [in] dx the first vector. + * \param [in] incx the increment between successive entries in \a dx. + * \param [in] dy the second vector. + * \param [in] incy the increment between successive entries in \a dy. + * \return the sum of the product of the corresponding entries of \a dx and \a dy. + */ + double ddot(int n, const double *dx, int incx, const double *dy, int incy) + { + double dtemp=0.0; + int i,ix,iy,m; + if(n<=0) + return dtemp; + // Code for unequal increments or equal increments not equal to 1. + if(incx!=1 || incy!=1) + { + if (incx>=0) + ix=0; + else + ix=(-n+1)*incx; + + if(incy>=0) + iy=0; + else + iy=(-n+1)*incy; + for(i=0;i<n;i++,ix+=incx,iy+=incy) + dtemp+=dx[ix]*dy[iy]; + } + //Code for both increments equal to 1. + else + { + m=n%5; + for(i=0;i<m;i++) + dtemp+=dx[i]*dy[i]; + for (i=m;i<n;i+=5) + dtemp+=dx[i]*dy[i]+dx[i+1]*dy[i+1]+dx[i+2]*dy[i+2]+dx[i+3]*dy[i+3]+dx[i+4]*dy[i+4]; + } + return dtemp; + } + + + void dscal(int n, double sa, double *x, int incx) + { + int i,ix,m; + + if(n<=0) { } + else if(incx==1) + { + m=n%5; + for(i=0;i<m;i++ ) + x[i]=sa*x[i]; + + for(i=m;i<n;i+=5) + { + x[i] =sa*x[i]; + x[i+1]=sa*x[i+1]; + x[i+2]=sa*x[i+2]; + x[i+3]=sa*x[i+3]; + x[i+4]=sa*x[i+4]; + } + } + else + { + if(0<=incx) + ix=0; + else + ix=(-n+1)*incx; + + for(i=0;i<n;i++,ix+=incx) + x[ix]=sa*x[ix]; + } + } + + void daxpy(int n, double da, const double *dx, int incx, double *dy, int incy) + { + int i,ix,iy,m; + if (n<=0) + return; + if (da==0.0) + return; + // Code for unequal increments or equal increments not equal to 1. + if(incx!=1 || incy!=1) + { + if(0<=incx) + ix=0; + else + ix=(-n+1)*incx; + + if(0<=incy) + iy=0; + else + iy=(-n+1)*incy; + + for(i=0;i<n;i++,ix+=incx,iy+=incy) + dy[iy]=dy[iy]+da*dx[ix]; + } + // Code for both increments equal to 1. + else + { + m=n%4; + for (i=0;i<m;i++) + dy[i]=dy[i]+da*dx[i]; + for(i=m;i<n;i+=4) + { + dy[i ]=dy[i ]+da*dx[i ]; + dy[i+1]=dy[i+1]+da*dx[i+1]; + dy[i+2]=dy[i+2]+da*dx[i+2]; + dy[i+3]=dy[i+3]+da*dx[i+3]; + } + } + } + + double r8_abs(double x) + { + if(x>=0.0) + return x; + else + return -x; + } + + void dswap(int n, double *x, int incx, double *y, int incy) + { + int i,ix,iy,m; + double temp; + + if(n<=0) { } + else if(incx==1 && incy==1) + { + m=n%3; + for(i=0;i<m;i++) + { temp=x[i]; x[i]=y[i]; y[i]=temp; } + for(i=m;i<n;i+=3) + { + temp=x[i]; x[i]=y[i]; y[i]=temp; + temp=x[i+1]; x[i+1]=y[i+1]; y[i+1]=temp; + temp=x[i+2]; x[i+2]=y[i+2]; y[i+2]=temp; + } + } + else + { + if(0<=incx) + ix=0; + else + ix=(-n+1)*incx; + if(0<=incy) + iy=0; + else + iy=(-n+1)*incy; + for(i=0;i<n;i++,ix+=incx,iy+=incy) + { + temp=x[ix]; x[ix]=y[iy]; + } + } + } + + /* + * Finds the index of the vector element of maximum absolute value. + * \warning This index is a 1-based index, not a 0-based index ! + * + * Reference: + * Jack Dongarra, Jim Bunch, Cleve Moler, Pete Stewart, + * LINPACK User's Guide, + * SIAM, 1979, + * ISBN13: 978-0-898711-72-1, + * LC: QA214.L56. + * + * Charles Lawson, Richard Hanson, David Kincaid, Fred Krogh, + * Basic Linear Algebra Subprograms for Fortran Usage, + * Algorithm 539, + * ACM Transactions on Mathematical Software, + * Volume 5, Number 3, September 1979, pages 308-323. + * + * \param [in] n the number of entries in the vector. + * \param [in] dx the vector to be examined. + * \param [in] incx the increment between successive entries of SX. + * \return the index of the element of maximum absolute value (in C convention). + */ + int idamax(int n, const double *dx, int incx) + { + double dmax; + int i,ix,value; + value=-1; + if ( n < 1 || incx <= 0 ) + return value; + value=0; + if(n==1) + return value; + if(incx==1) + { + dmax=r8_abs(dx[0]); + for(i=1;i<n;i++) + { + if(dmax<r8_abs(dx[i])) + { + value=i; + dmax=r8_abs(dx[i]); + } + } + } + else + { + ix=0; + dmax=r8_abs(dx[0]); + ix+=incx; + for(i=1;i<n;i++) + { + if(dmax<r8_abs(dx[ix])) + { + value=i; + dmax=r8_abs(dx[ix]); + } + ix+=incx; + } + } + return value; + } + + + /* + * Purpose: + * + * factors a real general matrix. + * + * Reference: + * + * Jack Dongarra, Cleve Moler, Jim Bunch and Pete Stewart, + * LINPACK User's Guide, + * SIAM, (Society for Industrial and Applied Mathematics), + * 3600 University City Science Center, + * Philadelphia, PA, 19104-2688. + * ISBN 0-89871-172-X + * + * Parameters: + * + * \param [in,out] a a matrix of size LDA*N. On intput, the matrix to be factored. + * On output, an upper triangular matrix and the multipliers used to obtain + * it. The factorization can be written A=L*U, where L is a product of + * permutation and unit lower triangular matrices, and U is upper triangular. + * + * \param [in] lda the leading dimension of \a a. + * \param [in] n the order of the matrix \a a. + * \param [out] ipvt the pivot indices of size \a n. + * \return the singularity indicator. + * - 0, normal value. + * - K, if U(K-1,K-1) == 0. This is not an error condition for this subroutine, + * but it does indicate that DGESL or DGEDI will divide by zero if called. + */ + int dgefa(double *a, int lda, int n, int *ipvt) + { + int info=0; + int l; + double t; + // Gaussian elimination with partial pivoting. + for(int k=0;k<n-1;k++) + { + // Find L=pivot index. + l=idamax(n-k-1,a+k+k*lda,1)+k; + ipvt[k]=l; + // Zero pivot implies this column already triangularized. + if(a[l+k*lda]==0.0) + { + info=k+1; + continue; + } + //Interchange if necessary. + if(l!=k) + { + t=a[l+k*lda]; + a[l+k*lda]=a[k+k*lda]; + a[k+k*lda]=t; + } + // Compute multipliers. + t=-1.0/a[k+k*lda]; + dscal(n-k-1,t,a+k+1+k*lda,1); + // Row elimination with column indexing. + for(int j=k+1;j<n;j++) + { + t=a[l+j*lda]; + if(l!=k-1) + { + a[l+j*lda]=a[k+j*lda]; + a[k+j*lda]=t; + } + daxpy(n-k-1,t,a+k+1+k*lda,1,a+k+1+j*lda,1); + } + } + ipvt[n-1]=n-1; + if(a[n-1+(n-1)*lda]==0.0) + info=n; + return info; + } + + /* + * - Purpose: computes inverse (job=1) of a matrix factored by dgefa. + * + * - Discussion: A division by zero will occur if the input factor contains + * a zero on the diagonal. It will not occur if the subroutines are called correctly + * and dgfa has set info to 0. + * + * Reference: + * + * Jack Dongarra, Cleve Moler, Jim Bunch and Pete Stewart, + * LINPACK User's Guide, + * SIAM, (Society for Industrial and Applied Mathematics), + * 3600 University City Science Center, + * Philadelphia, PA, 19104-2688. + * ISBN 0-89871-172-X + * + * Parameters: + * + * \param [in,out] a matrix of size lda*n, on input, the LU factor information, as output of dgfa. On output, the inverse matrix. + * \param [in] lda, the leading dimension of the array \a a. + * \param [in] n, the order of the matrix \a a. + * \param [in] ipvt, the pivot vector from dgfa. + * \param [in,out] work a work array of size at least equal to \a n. + */ + void dgedi(double *a, int lda, int n, const int *ipvt, double *work) + { + double t; + for(int k=0;k<n;k++) + { + a[k+k*lda]=1.0/a[k+k*lda]; + t=-a[k+k*lda]; + dscal(k,t,a+0+k*lda,1); + for(int j=k+1;j<n;j++) + { + t=a[k+j*lda]; + a[k+j*lda]=0.0; + daxpy(k+1,t,a+0+k*lda,1,a+0+j*lda,1); + } + } + // Form inverse(U) * inverse(L). + for(int k=n-2;k>=0;k--) + { + for(int i=k+1;i<n;i++) + { + work[i]=a[i+k*lda]; + a[i+k*lda]=0.0; + } + + for(int j=k+1;j<n;j++) + { + t=work[j]; + daxpy(n,t,a+0+j*lda,1,a+0+k*lda,1); + } + int l=ipvt[k]; + if(l!=k-1) + dswap(n,a+0+k*lda,1,a+0+l*lda,1); + } + } + + void matrixProduct(const double *A, int n1, int p1, const double *B, int n2, int p2, double *C) + { + if(p1!=n2) + { + std::ostringstream oss; oss << "matrixProduct : the size of input matrix are not coherent the nb of cols of input matrix #0 is " << p1 << " whereas the number of rows of input matrix #1 is " << n2 << " !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + for(int i=0;i<n1;i++) + { + for(int j=0;j<p2;j++) + { + C[i*p2+j] = 0.; + for(int k=0;k<p1;k++) + C[i*p2+j]+=A[i*p1+k]*B[k*p2+j]; + } + } + } + + void inverseMatrix(const double *A, int n, double *iA) + { + INTERP_KERNEL::AutoPtr<int> ipvt=new int[n]; + INTERP_KERNEL::AutoPtr<double> work=new double[n*n]; + std::copy(A,A+n*n,iA); + dgefa(iA,n,n,ipvt); + dgedi(iA,n,n,ipvt,work); + } +} diff --git a/src/medtool/src/INTERP_KERNEL/InterpKernelMatrixTools.hxx b/src/medtool/src/INTERP_KERNEL/InterpKernelMatrixTools.hxx new file mode 100644 index 000000000..95fb28f23 --- /dev/null +++ b/src/medtool/src/INTERP_KERNEL/InterpKernelMatrixTools.hxx @@ -0,0 +1,33 @@ +// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 +// 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 __INTERPKERNELMATRIXTOOLS_HXX__ +#define __INTERPKERNELMATRIXTOOLS_HXX__ + +#include "INTERPKERNELDefines.hxx" + +namespace INTERP_KERNEL +{ + void INTERPKERNEL_EXPORT matrixProduct(const double *A, int n1, int p1, const double *B, int n2, int p2, double *C); + void INTERPKERNEL_EXPORT inverseMatrix(const double *A, int n, double *iA); + void INTERPKERNEL_EXPORT daxpy(int n, double da, const double *dx, int incx, double *dy, int incy); +} + +#endif diff --git a/src/medtool/src/INTERP_KERNEL/InterpKernelMeshQuality.cxx b/src/medtool/src/INTERP_KERNEL/InterpKernelMeshQuality.cxx new file mode 100644 index 000000000..f09c0ff26 --- /dev/null +++ b/src/medtool/src/INTERP_KERNEL/InterpKernelMeshQuality.cxx @@ -0,0 +1,210 @@ +// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 +// 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 "InterpKernelMeshQuality.hxx" + +#include <cmath> +#include <limits> +#include <numeric> +#include <algorithm> + +double INTERP_KERNEL::quadSkew(const double *coo) +{ + double pa0[3]={ + coo[3]+coo[6]-coo[0]-coo[9], + coo[4]+coo[7]-coo[1]-coo[10], + coo[5]+coo[8]-coo[2]-coo[11] + }; + double pa1[3]={ + coo[6]+coo[9]-coo[0]-coo[3], + coo[7]+coo[10]-coo[1]-coo[4], + coo[8]+coo[11]-coo[2]-coo[5], + }; + double l0=sqrt(pa0[0]*pa0[0]+pa0[1]*pa0[1]+pa0[2]*pa0[2]); + double l1=sqrt(pa1[0]*pa1[0]+pa1[1]*pa1[1]+pa1[2]*pa1[2]); + if(l0<1.e-15) + return 0.; + if(l1<1.e-15) + return 0.; + pa0[0]/=l0; pa0[1]/=l0; pa0[2]/=l0; + pa1[0]/=l1; pa1[1]/=l1; pa1[2]/=l1; + return pa0[0]*pa1[0]+pa0[1]*pa1[1]+pa0[2]*pa1[2]; +} + +double INTERP_KERNEL::quadEdgeRatio(const double *coo) +{ + double a2=(coo[3]-coo[0])*(coo[3]-coo[0])+(coo[4]-coo[1])*(coo[4]-coo[1])+(coo[5]-coo[2])*(coo[5]-coo[2]); + double b2=(coo[6]-coo[3])*(coo[6]-coo[3])+(coo[7]-coo[4])*(coo[7]-coo[4])+(coo[8]-coo[5])*(coo[8]-coo[5]); + double c2=(coo[9]-coo[6])*(coo[9]-coo[6])+(coo[10]-coo[7])*(coo[10]-coo[7])+(coo[11]-coo[8])*(coo[11]-coo[8]); + double d2=(coo[0]-coo[9])*(coo[0]-coo[9])+(coo[1]-coo[10])*(coo[1]-coo[10])+(coo[2]-coo[11])*(coo[2]-coo[11]); + double mab=a2<b2?a2:b2; + double Mab=a2<b2?b2:a2; + double mcd=c2<d2?c2:d2; + double Mcd=c2<d2?d2:c2; + double m2=mab<mcd?mab:mcd; + double M2=Mab>Mcd?Mab:Mcd; + if(m2>1.e-15) + return sqrt(M2/m2); + else + return std::numeric_limits<double>::max(); +} + +double INTERP_KERNEL::quadAspectRatio(const double *coo) +{ + double a=sqrt((coo[3]-coo[0])*(coo[3]-coo[0])+(coo[4]-coo[1])*(coo[4]-coo[1])+(coo[5]-coo[2])*(coo[5]-coo[2])); + double b=sqrt((coo[6]-coo[3])*(coo[6]-coo[3])+(coo[7]-coo[4])*(coo[7]-coo[4])+(coo[8]-coo[5])*(coo[8]-coo[5])); + double c=sqrt((coo[9]-coo[6])*(coo[9]-coo[6])+(coo[10]-coo[7])*(coo[10]-coo[7])+(coo[11]-coo[8])*(coo[11]-coo[8])); + double d=sqrt((coo[0]-coo[9])*(coo[0]-coo[9])+(coo[1]-coo[10])*(coo[1]-coo[10])+(coo[2]-coo[11])*(coo[2]-coo[11])); + double ma=a>b?a:b; + double mb=c>d?c:d; + double hm=ma>mb?ma:mb; + double ab[3]={(coo[4]-coo[1])*(coo[8]-coo[5])-(coo[7]-coo[4])*(coo[5]-coo[2]), + (coo[5]-coo[2])*(coo[6]-coo[3])-(coo[3]-coo[0])*(coo[8]-coo[5]), + (coo[3]-coo[0])*(coo[7]-coo[4])-(coo[4]-coo[1])*(coo[6]-coo[3])}; + double cd[3]={(coo[10]-coo[7])*(coo[2]-coo[11])-(coo[1]-coo[10])*(coo[11]-coo[8]), + (coo[11]-coo[8])*(coo[0]-coo[9])-(coo[9]-coo[6])*(coo[2]-coo[11]), + (coo[9]-coo[6])*(coo[1]-coo[10])-(coo[10]-coo[7])*(coo[0]-coo[9])}; + double e=sqrt(ab[0]*ab[0]+ab[1]*ab[1]+ab[2]*ab[2])+sqrt(cd[0]*cd[0]+cd[1]*cd[1]+cd[2]*cd[2]); + if(d>1e-15) + return 0.5*(a+b+c+d)*hm/e; + else + return std::numeric_limits<double>::max(); +} + +double INTERP_KERNEL::quadWarp(const double *coo) +{ + double e0[3]={coo[3]-coo[0],coo[4]-coo[1],coo[5]-coo[2]}; + double e1[3]={coo[6]-coo[3],coo[7]-coo[4],coo[8]-coo[5]}; + double e2[3]={coo[9]-coo[6],coo[10]-coo[7],coo[11]-coo[8]}; + double e3[3]={coo[0]-coo[9],coo[1]-coo[10],coo[2]-coo[11]}; + + double n0[3]={e3[1]*e0[2]-e3[2]*e0[1],e3[2]*e0[0]-e3[0]*e0[2],e3[0]*e0[1]-e3[1]*e0[0]}; + double n1[3]={e0[1]*e1[2]-e0[2]*e1[1],e0[2]*e1[0]-e0[0]*e1[2],e0[0]*e1[1]-e0[1]*e1[0]}; + double n2[3]={e1[1]*e2[2]-e1[2]*e2[1],e1[2]*e2[0]-e1[0]*e2[2],e1[0]*e2[1]-e1[1]*e2[0]}; + double n3[3]={e2[1]*e3[2]-e2[2]*e3[1],e2[2]*e3[0]-e2[0]*e3[2],e2[0]*e3[1]-e2[1]*e3[0]}; + + double l0=sqrt(n0[0]*n0[0]+n0[1]*n0[1]+n0[2]*n0[2]); + double l1=sqrt(n1[0]*n1[0]+n1[1]*n1[1]+n1[2]*n1[2]); + double l2=sqrt(n2[0]*n2[0]+n2[1]*n2[1]+n2[2]*n2[2]); + double l3=sqrt(n3[0]*n3[0]+n3[1]*n3[1]+n3[2]*n3[2]); + + if(l0<1.e-15 || l1<1.e-15 || l2<1.e-15 || l3<1e-15) + return std::numeric_limits<double>::min(); + + double warp=std::min(n0[0]/l0*n2[0]/l2+n0[1]/l0*n2[1]/l2+n0[2]/l0*n2[2]/l2,n1[0]/l1*n3[0]/l3+n1[1]/l1*n3[1]/l3+n1[2]/l1*n3[2]/l3); + return warp*warp*warp; +} + +double INTERP_KERNEL::triEdgeRatio(const double *coo) +{ + double a2=(coo[3]-coo[0])*(coo[3]-coo[0])+(coo[4]-coo[1])*(coo[4]-coo[1])+(coo[5]-coo[2])*(coo[5]-coo[2]); + double b2=(coo[6]-coo[3])*(coo[6]-coo[3])+(coo[7]-coo[4])*(coo[7]-coo[4])+(coo[8]-coo[5])*(coo[8]-coo[5]); + double c2=(coo[0]-coo[6])*(coo[0]-coo[6])+(coo[1]-coo[7])*(coo[1]-coo[7])+(coo[2]-coo[8])*(coo[2]-coo[8]); + double mab=a2<b2?a2:b2; + double Mab=a2<b2?b2:a2; + double m2=c2>mab?mab:c2; + double M2=c2>Mab?c2:Mab; + if(m2>1.e-15) + return sqrt(M2/m2); + else + return std::numeric_limits<double>::max(); +} + +double INTERP_KERNEL::triAspectRatio(const double *coo) +{ + double a=sqrt((coo[3]-coo[0])*(coo[3]-coo[0])+(coo[4]-coo[1])*(coo[4]-coo[1])+(coo[5]-coo[2])*(coo[5]-coo[2])); + double b=sqrt((coo[6]-coo[3])*(coo[6]-coo[3])+(coo[7]-coo[4])*(coo[7]-coo[4])+(coo[8]-coo[5])*(coo[8]-coo[5])); + double c=sqrt((coo[0]-coo[6])*(coo[0]-coo[6])+(coo[1]-coo[7])*(coo[1]-coo[7])+(coo[2]-coo[8])*(coo[2]-coo[8])); + + double hm=a>b?a:b; + hm=hm>c?hm:c; + + double ab[3]={(coo[4]-coo[1])*(coo[8]-coo[5])-(coo[7]-coo[4])*(coo[5]-coo[2]), + (coo[5]-coo[2])*(coo[6]-coo[3])-(coo[3]-coo[0])*(coo[8]-coo[5]), + (coo[3]-coo[0])*(coo[7]-coo[4])-(coo[4]-coo[1])*(coo[6]-coo[3])}; + double d=sqrt(ab[0]*ab[0]+ab[1]*ab[1]+ab[2]*ab[2]); + static const double normalizeCoeff=sqrt(3.)/6.; + if(d>1.e-15) + return normalizeCoeff*hm*(a+b+c)/d; + else + return std::numeric_limits<double>::max(); +} + +double INTERP_KERNEL::tetraEdgeRatio(const double *coo) +{ + double a[3]={coo[3]-coo[0],coo[4]-coo[1],coo[5]-coo[2]}; + double b[3]={coo[6]-coo[3],coo[7]-coo[4],coo[8]-coo[5]}; + double c[3]={coo[0]-coo[6],coo[1]-coo[7],coo[2]-coo[8]}; + double d[3]={coo[9]-coo[0],coo[10]-coo[1],coo[11]-coo[2]}; + double e[3]={coo[9]-coo[3],coo[10]-coo[4],coo[11]-coo[5]}; + double f[3]={coo[9]-coo[6],coo[10]-coo[7],coo[11]-coo[8]}; + + double l2[6]= + {a[0]*a[0]+a[1]*a[1]+a[2]*a[2], + b[0]*b[0]+b[1]*b[1]+b[2]*b[2], + c[0]*c[0]+c[1]*c[1]+c[2]*c[2], + d[0]*d[0]+d[1]*d[1]+d[2]*d[2], + e[0]*e[0]+e[1]*e[1]+e[2]*e[2], + f[0]*f[0]+f[1]*f[1]+f[2]*f[2]}; + + double M2=*std::max_element(l2,l2+6); + double m2=*std::min_element(l2,l2+6); + if(m2>1e-15) + return sqrt(M2/m2); + else + return std::numeric_limits<double>::max(); +} + +double INTERP_KERNEL::tetraAspectRatio(const double *coo) +{ + static const double normalizeCoeff=sqrt(6.)/12.; + double ab[3]={coo[3]-coo[0],coo[4]-coo[1],coo[5]-coo[2]}; + double ac[3]={coo[6]-coo[0],coo[7]-coo[1],coo[8]-coo[2]}; + double ad[3]={coo[9]-coo[0],coo[10]-coo[1],coo[11]-coo[2]}; + double detTet=(ab[0]*(ac[1]*ad[2]-ac[2]*ad[1]))+(ab[1]*(ac[2]*ad[0]-ac[0]*ad[2]))+(ab[2]*(ac[0]*ad[1]-ac[1]*ad[0])); + //if(detTet<1.e-15) + // return std::numeric_limits<double>::max(); + double bc[3]={coo[6]-coo[3],coo[7]-coo[4],coo[8]-coo[5]}; + double bd[3]={coo[9]-coo[3],coo[10]-coo[4],coo[11]-coo[5]}; + double cd[3]={coo[9]-coo[6],coo[10]-coo[7],coo[11]-coo[8]}; + + double ab2=ab[0]*ab[0]+ab[1]*ab[1]+ab[2]*ab[2]; + double bc2=bc[0]*bc[0]+bc[1]*bc[1]+bc[2]*bc[2]; + double ac2=ac[0]*ac[0]+ac[1]*ac[1]+ac[2]*ac[2]; + double ad2=ad[0]*ad[0]+ad[1]*ad[1]+ad[2]*ad[2]; + double bd2=bd[0]*bd[0]+bd[1]*bd[1]+bd[2]*bd[2]; + double cd2=cd[0]*cd[0]+cd[1]*cd[1]+cd[2]*cd[2]; + + double A=ab2>bc2?ab2:bc2; + double B=ac2>ad2?ac2:ad2; + double C=bd2>cd2?bd2:cd2; + double D=A>B?A:B; + double hm=D>C?sqrt(D):sqrt(C); + + bd[0]=ab[1]*bc[2]-ab[2]*bc[1]; bd[1]=ab[2]*bc[0]-ab[0]*bc[2]; bd[2]=ab[0]*bc[1]-ab[1]*bc[0]; + A=sqrt(bd[0]*bd[0]+bd[1]*bd[1]+bd[2]*bd[2]); + bd[0]=ab[1]*ad[2]-ab[2]*ad[1]; bd[1]=ab[2]*ad[0]-ab[0]*ad[2]; bd[2]=ab[0]*ad[1]-ab[1]*ad[0]; + B=sqrt(bd[0]*bd[0]+bd[1]*bd[1]+bd[2]*bd[2]); + bd[0]=ac[1]*ad[2]-ac[2]*ad[1]; bd[1]=ac[2]*ad[0]-ac[0]*ad[2]; bd[2]=ac[0]*ad[1]-ac[1]*ad[0]; + C=sqrt(bd[0]*bd[0]+bd[1]*bd[1]+bd[2]*bd[2]); + bd[0]=bc[1]*cd[2]-bc[2]*cd[1]; bd[1]=bc[2]*cd[0]-bc[0]*cd[2]; bd[2]=bc[0]*cd[1]-bc[1]*cd[0]; + D=sqrt(bd[0]*bd[0]+bd[1]*bd[1]+bd[2]*bd[2]); + return normalizeCoeff*hm*(A+B+C+D)/fabs(detTet); +} diff --git a/src/medtool/src/INTERP_KERNEL/InterpKernelMeshQuality.hxx b/src/medtool/src/INTERP_KERNEL/InterpKernelMeshQuality.hxx new file mode 100644 index 000000000..88afc15d9 --- /dev/null +++ b/src/medtool/src/INTERP_KERNEL/InterpKernelMeshQuality.hxx @@ -0,0 +1,38 @@ +// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 +// 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 __INTERPKERNELMESHQUALITY_HXX_ +#define __INTERPKERNELMESHQUALITY_HXX__ + +#include "INTERPKERNELDefines.hxx" + +namespace INTERP_KERNEL +{ + INTERPKERNEL_EXPORT double quadSkew(const double *coo); + INTERPKERNEL_EXPORT double quadEdgeRatio(const double *coo); + INTERPKERNEL_EXPORT double quadAspectRatio(const double *coo); + INTERPKERNEL_EXPORT double quadWarp(const double *coo); + INTERPKERNEL_EXPORT double triEdgeRatio(const double *coo); + INTERPKERNEL_EXPORT double triAspectRatio(const double *coo); + INTERPKERNEL_EXPORT double tetraEdgeRatio(const double *coo); + INTERPKERNEL_EXPORT double tetraAspectRatio(const double *coo); +} + +#endif diff --git a/src/medtool/src/INTERP_KERNEL/InterpKernelUtilities.hxx b/src/medtool/src/INTERP_KERNEL/InterpKernelUtilities.hxx new file mode 100644 index 000000000..44ee02ab1 --- /dev/null +++ b/src/medtool/src/INTERP_KERNEL/InterpKernelUtilities.hxx @@ -0,0 +1,38 @@ +// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 +// 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 __INTERPKERNELUTILITIES_HXX__ +#define __INTERPKERNELUTILITIES_HXX__ + +//! DON'T INCLUDE THIS FILE IN .h NOR IN .hxx FILES !!!!!!!!! +#ifdef _DEBUG_ +# define MESSAGE(chain) {HERE ; cerr << chain << endl ;} +#else +# define MESSAGE(chain) +#endif + +#ifdef _DEBUG_ +# define HERE {cout<<flush ; cerr << "- Trace " << __FILE__ << " [" << __LINE__ << "] : " << flush ;} +#else +# define HERE +#endif + +#define LOCALIZED(message) static_cast<const char *> (message) , __FILE__ , __LINE__ + +#endif diff --git a/src/medtool/src/INTERP_KERNEL/Interpolation.hxx b/src/medtool/src/INTERP_KERNEL/Interpolation.hxx new file mode 100644 index 000000000..16415593b --- /dev/null +++ b/src/medtool/src/INTERP_KERNEL/Interpolation.hxx @@ -0,0 +1,56 @@ +// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 +// 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 __INTERPOLATION_HXX__ +#define __INTERPOLATION_HXX__ + +#include "INTERPKERNELDefines.hxx" +#include "InterpolationOptions.hxx" +#include "InterpKernelException.hxx" + +#include <string> + +namespace INTERP_KERNEL +{ + template<class TrueMainInterpolator> + class Interpolation : public InterpolationOptions + { + public: + Interpolation() { } + Interpolation(const InterpolationOptions& io) :InterpolationOptions(io){} + //interpolation of two triangular meshes. + template<class MatrixType, class MyMeshType> + int interpolateMeshes(const MyMeshType& meshS, const MyMeshType& meshT, MatrixType& result) + { return asLeaf().interpolateMeshes(meshS,meshT,result); } + template<class MyMeshType, class MatrixType> + int fromIntegralUniform(const MyMeshType& meshT, MatrixType& result, const std::string& method) { return fromToIntegralUniform(false,meshT,result,method); } + template<class MyMeshType, class MatrixType> + int toIntegralUniform(const MyMeshType& meshS, MatrixType& result, const std::string& method) { return fromToIntegralUniform(true,meshS,result,method); } + template<class MyMeshType> + static double CalculateCharacteristicSizeOfMeshes(const MyMeshType& myMeshS, const MyMeshType& myMeshT, const int printLevel); + protected: + template<class MyMeshType, class MatrixType> + int fromToIntegralUniform(bool fromTo, const MyMeshType& mesh, MatrixType& result, const std::string& method); + protected: + TrueMainInterpolator& asLeaf() { return static_cast<TrueMainInterpolator&>(*this); } + }; +} + +#endif diff --git a/src/medtool/src/INTERP_KERNEL/Interpolation.txx b/src/medtool/src/INTERP_KERNEL/Interpolation.txx new file mode 100644 index 000000000..65a9fb4d3 --- /dev/null +++ b/src/medtool/src/INTERP_KERNEL/Interpolation.txx @@ -0,0 +1,97 @@ +// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 +// 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 __INTERPOLATION_TXX__ +#define __INTERPOLATION_TXX__ + +#include "Interpolation.hxx" +#include "IntegralUniformIntersector.hxx" +#include "IntegralUniformIntersector.txx" +#include "VectorUtils.hxx" + +namespace INTERP_KERNEL +{ + template<class TrueMainInterpolator> + template<class MyMeshType, class MatrixType> + int Interpolation<TrueMainInterpolator>::fromToIntegralUniform(bool fromTo, const MyMeshType& mesh, MatrixType& result, const std::string& method) + { + typedef typename MyMeshType::MyConnType ConnType; + int ret=-1; + if(method=="P0") + { + IntegralUniformIntersectorP0<MyMeshType,MatrixType> intersector(mesh,InterpolationOptions::getMeasureAbsStatus()); + intersector.setFromTo(fromTo); + std::vector<ConnType> tmp; + intersector.intersectCells(0,tmp,result); + ret=intersector.getNumberOfColsOfResMatrix(); + } + else if(method=="P1") + { + IntegralUniformIntersectorP1<MyMeshType,MatrixType> intersector(mesh,InterpolationOptions::getMeasureAbsStatus()); + intersector.setFromTo(fromTo); + std::vector<ConnType> tmp; + intersector.intersectCells(0,tmp,result); + ret=intersector.getNumberOfColsOfResMatrix(); + } + else + throw INTERP_KERNEL::Exception("Invalid method specified in fromIntegralUniform : must be in { \"P0\", \"P1\"}"); + return ret; + } + + template<class TrueMainInterpolator> + template<class MyMeshType> + double Interpolation<TrueMainInterpolator>::CalculateCharacteristicSizeOfMeshes(const MyMeshType& myMeshS, const MyMeshType& myMeshT, const int printLevel) + { + static const int SPACEDIM=MyMeshType::MY_SPACEDIM; + + long nbMailleS=myMeshS.getNumberOfElements(); + long nbMailleT=myMeshT.getNumberOfElements(); + + /**************************************************/ + /* Search the characteristic size of the meshes */ + /**************************************************/ + + double BoxS[2*SPACEDIM]; myMeshS.getBoundingBox(BoxS); + double BoxT[2*SPACEDIM]; myMeshT.getBoundingBox(BoxT); + double diagonalS,dimCaracteristicS=std::numeric_limits<double>::max(); + if(nbMailleS!=0) + { + diagonalS=getDistanceBtw2Pts<SPACEDIM>(BoxS+SPACEDIM,BoxS); + dimCaracteristicS=diagonalS/nbMailleS; + } + double diagonalT,dimCaracteristicT=std::numeric_limits<double>::max(); + if(nbMailleT!=0) + { + diagonalT=getDistanceBtw2Pts<SPACEDIM>(BoxT+SPACEDIM,BoxT); + dimCaracteristicT=diagonalT/nbMailleT; + } + if (printLevel>=1) + { + std::cout << " - Characteristic size of the source mesh : " << dimCaracteristicS << std::endl; + std::cout << " - Characteristic size of the target mesh: " << dimCaracteristicT << std::endl; + } + + return std::min(dimCaracteristicS, dimCaracteristicT); + + } + +} + +#endif + diff --git a/src/medtool/src/INTERP_KERNEL/Interpolation1D.hxx b/src/medtool/src/INTERP_KERNEL/Interpolation1D.hxx new file mode 100755 index 000000000..351cb4296 --- /dev/null +++ b/src/medtool/src/INTERP_KERNEL/Interpolation1D.hxx @@ -0,0 +1,36 @@ +// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 +// 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 __INTERPOLATION1D_HXX__ +#define __INTERPOLATION1D_HXX__ + +#include "InterpolationCurve.hxx" + +namespace INTERP_KERNEL +{ + class Interpolation1D : public InterpolationCurve<Interpolation1D> + { + public: + Interpolation1D() { } + Interpolation1D(const InterpolationOptions& io):InterpolationCurve<Interpolation1D>(io) {} + }; +} + +#endif diff --git a/src/medtool/src/INTERP_KERNEL/Interpolation1D.txx b/src/medtool/src/INTERP_KERNEL/Interpolation1D.txx new file mode 100644 index 000000000..dcc4f77ff --- /dev/null +++ b/src/medtool/src/INTERP_KERNEL/Interpolation1D.txx @@ -0,0 +1,27 @@ +// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 +// 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 __INTERPOLATION1D_TXX__ +#define __INTERPOLATION1D_TXX__ + +#include "Interpolation1D.hxx" + +#include "InterpolationCurve.txx" + +#endif diff --git a/src/medtool/src/INTERP_KERNEL/Interpolation2D.hxx b/src/medtool/src/INTERP_KERNEL/Interpolation2D.hxx new file mode 100755 index 000000000..82a8980b3 --- /dev/null +++ b/src/medtool/src/INTERP_KERNEL/Interpolation2D.hxx @@ -0,0 +1,41 @@ +// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 +// 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 __INTERPOLATION2D_HXX__ +#define __INTERPOLATION2D_HXX__ + +#include "InterpolationPlanar.hxx" + +namespace INTERP_KERNEL +{ + class Interpolation2D : public InterpolationPlanar<Interpolation2D> + { + public: + Interpolation2D() { } + Interpolation2D(const InterpolationOptions& io):InterpolationPlanar<Interpolation2D>(io) { } + public: + bool doRotate() const { return false; } + double medianPlane() const { return 0.; } + template<class MyMeshType, class MyMatrixRow> + void performAdjustmentOfBB(PlanarIntersector<MyMeshType,MyMatrixRow>* intersector, std::vector<double>& bbox) const { } + }; +} + +#endif diff --git a/src/medtool/src/INTERP_KERNEL/Interpolation2D.txx b/src/medtool/src/INTERP_KERNEL/Interpolation2D.txx new file mode 100644 index 000000000..fa871e5b9 --- /dev/null +++ b/src/medtool/src/INTERP_KERNEL/Interpolation2D.txx @@ -0,0 +1,27 @@ +// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 +// 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 __INTERPOLATION2D_TXX__ +#define __INTERPOLATION2D_TXX__ + +#include "Interpolation2D.hxx" + +#include "InterpolationPlanar.txx" + +#endif diff --git a/src/medtool/src/INTERP_KERNEL/Interpolation2D1D.hxx b/src/medtool/src/INTERP_KERNEL/Interpolation2D1D.hxx new file mode 100644 index 000000000..2ef88f89c --- /dev/null +++ b/src/medtool/src/INTERP_KERNEL/Interpolation2D1D.hxx @@ -0,0 +1,63 @@ +// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 +// 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 __INTERPOLATION2D1D_HXX__ +#define __INTERPOLATION2D1D_HXX__ + +#include "Interpolation.hxx" +#include "Planar2D1DIntersectorP0P0.hxx" +#include "NormalizedUnstructuredMesh.hxx" +#include "InterpolationOptions.hxx" + +namespace INTERP_KERNEL +{ + /*! + * Contrary to its name this class deals with 1D mesh in source and 2D mesh in target. + * The meshdim of 'MyMeshType' in input is ignored that's why 'meshS' and 'meshT' + * have the same type. + * '_duplicate_faces' attribute stores duplicated faces in the following format. + * The key of '_duplicate_faces' represents the 1D cellId that is shared by + * more than one 2D target cell, and the value of '_duplicate_faces' + * the 2D target cells. The size of the value of '_duplicate_faces' is more than or equal to 2. + */ + class Interpolation2D1D : public Interpolation<Interpolation2D1D> + { + public: + typedef std::map<int,std::set<int> > DuplicateFacesType; + + Interpolation2D1D() { setOrientation(2); } + Interpolation2D1D(const InterpolationOptions& io):Interpolation<Interpolation2D1D>(io) { } + public: + + // Main function to interpolate triangular and quadratic meshes + template<class MyMeshType, class MatrixType> + int interpolateMeshes(const MyMeshType& meshS, const MyMeshType& meshT, MatrixType& result, const std::string& method); + DuplicateFacesType retrieveDuplicateFaces() const + { + return _duplicate_faces; + } + private: + DuplicateFacesType _duplicate_faces; + private: + double _dim_caracteristic; + }; +} + +#endif diff --git a/src/medtool/src/INTERP_KERNEL/Interpolation2D1D.txx b/src/medtool/src/INTERP_KERNEL/Interpolation2D1D.txx new file mode 100644 index 000000000..482a88250 --- /dev/null +++ b/src/medtool/src/INTERP_KERNEL/Interpolation2D1D.txx @@ -0,0 +1,157 @@ +// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 +// 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 __INTERPOLATION2D1D_TXX__ +#define __INTERPOLATION2D1D_TXX__ + +#include "Interpolation2D1D.hxx" + +namespace INTERP_KERNEL +{ + + /** \brief Main function to interpolate triangular or quadrangular meshes. + \details The algorithm proceeds in two steps: first a filtering process reduces the number of pairs of elements for which the + * calculation must be carried out by eliminating pairs that do not intersect based on their bounding boxes. Then, the + * volume of intersection is calculated by an object of type IntersectorPlanar for the remaining pairs, and entered into the + * intersection matrix. + * + * The matrix is partially sparse : it is a vector of maps of integer - double pairs. + * The length of the vector is equal to the number of target elements - for each target element there is a map, regardless + * of whether the element intersects any source elements or not. But in the maps there are only entries for those source elements + * which have a non-zero intersection volume with the target element. The vector has indices running from + * 0 to (#target elements - 1), meaning that the map for target element i is stored at index i - 1. In the maps, however, + * the indexing is more natural : the intersection volume of the target element i with source element j is found at matrix[i-1][j]. + * + + * @param myMeshS Planar source mesh + * @Param myMeshT Planar target mesh + * @return vector containing for each element i of the source mesh, a map giving for each element j + * of the target mesh which i intersects, the area of the intersection + * + */ + template<class MyMeshType, class MatrixType> + int Interpolation2D1D::interpolateMeshes(const MyMeshType& myMeshS, const MyMeshType& myMeshT, MatrixType& result, const std::string& method) + { + static const int SPACEDIM=MyMeshType::MY_SPACEDIM; + typedef typename MyMeshType::MyConnType ConnType; + static const NumberingPolicy numPol=MyMeshType::My_numPol; + + long global_start =clock(); + int counter=0; + /***********************************************************/ + /* Check both meshes are made of triangles and quadrangles */ + /***********************************************************/ + + long nbMailleS=myMeshS.getNumberOfElements(); + + /**************************************************/ + /* Search the characteristic size of the meshes */ + /**************************************************/ + + int printLevel = InterpolationOptions::getPrintLevel(); + _dim_caracteristic = CalculateCharacteristicSizeOfMeshes(myMeshS, myMeshT, printLevel); + if (printLevel>=1) + { + std::cout << "Interpolation2D1D::computation of the intersections" << std::endl; + } + + PlanarIntersector<MyMeshType,MatrixType>* intersector=0; + std::string meth = InterpolationOptions::filterInterpolationMethod(method); + if(meth=="P0P0") + { + switch (InterpolationOptions::getIntersectionType()) + { + case Geometric2D: + intersector=new Geometric2DIntersector<MyMeshType,MatrixType,Planar2D1DIntersectorP0P0>(myMeshT, myMeshS, _dim_caracteristic, + InterpolationOptions::getMaxDistance3DSurfIntersect(), + InterpolationOptions::getMinDotBtwPlane3DSurfIntersect(), + InterpolationOptions::getMedianPlane(), + InterpolationOptions::getPrecision(), + InterpolationOptions::getOrientation()); + break; + default: + throw INTERP_KERNEL::Exception("Invalid intersection type ! Must be : Geometric2D"); + } + } + else + throw INTERP_KERNEL::Exception("Invalid method specified or intersection type ! Must be : \"P0P0\""); + + /****************************************************************/ + /* Create a search tree based on the bounding boxes */ + /* Instanciate the intersector and initialise the result vector */ + /****************************************************************/ + + long start_filtering=clock(); + + std::vector<double> bbox; + intersector->createBoundingBoxes(myMeshS,bbox); // create the bounding boxes + const double *bboxPtr=0; + if(nbMailleS>0) + bboxPtr=&bbox[0]; + BBTree<SPACEDIM,ConnType> my_tree(bboxPtr, 0, 0,nbMailleS, -getPrecision());//creating the search structure + + long end_filtering=clock(); + + result.resize(intersector->getNumberOfRowsOfResMatrix());//on initialise. + + /****************************************************/ + /* Loop on the target cells - core of the algorithm */ + /****************************************************/ + long start_intersection=clock(); + long nbelem_type=myMeshT.getNumberOfElements(); + const ConnType *connIndxT=myMeshT.getConnectivityIndexPtr(); + for(int iT=0; iT<nbelem_type; iT++) + { + int nb_nodesT=connIndxT[iT+1]-connIndxT[iT]; + std::vector<int> intersecting_elems; + double bb[2*SPACEDIM]; + intersector->getElemBB(bb,myMeshT,OTT<ConnType,numPol>::indFC(iT),nb_nodesT); + my_tree.getIntersectingElems(bb, intersecting_elems); + intersector->intersectCells(iT,intersecting_elems,result); + counter+=intersecting_elems.size(); + intersecting_elems.clear(); + } + int ret=intersector->getNumberOfColsOfResMatrix(); + + const DuplicateFacesType& intersectFaces = *intersector->getIntersectFaces(); + DuplicateFacesType::const_iterator iter; + for (iter = intersectFaces.begin(); iter != intersectFaces.end(); ++iter) + { + if (iter->second.size() > 1) + { + _duplicate_faces.insert(std::make_pair(iter->first, iter->second)); + } + } + + delete intersector; + + if (InterpolationOptions::getPrintLevel() >=1) + { + long end_intersection=clock(); + std::cout << "Filtering time= " << end_filtering-start_filtering << std::endl; + std::cout << "Intersection time= " << end_intersection-start_intersection << std::endl; + long global_end =clock(); + std::cout << "Number of computed intersections = " << counter << std::endl; + std::cout << "Global time= " << global_end - global_start << std::endl; + } + return ret; + } + +} +#endif diff --git a/src/medtool/src/INTERP_KERNEL/Interpolation2DCurve.cxx b/src/medtool/src/INTERP_KERNEL/Interpolation2DCurve.cxx new file mode 100644 index 000000000..0db047975 --- /dev/null +++ b/src/medtool/src/INTERP_KERNEL/Interpolation2DCurve.cxx @@ -0,0 +1,60 @@ +// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 +// 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 "Interpolation2DCurve.hxx" +#include "InterpolationCurve.txx" + +namespace INTERP_KERNEL +{ + Interpolation2DCurve::Interpolation2DCurve() + { + // to have non-zero default thickness of target element + InterpolationOptions::setBoundingBoxAdjustmentAbs( InterpolationOptions::getPrecision() ); + } + + Interpolation2DCurve::Interpolation2DCurve + (const InterpolationOptions& io):InterpolationCurve<Interpolation2DCurve>(io) + { + // to have non-zero default thickness of target element + InterpolationOptions::setBoundingBoxAdjustmentAbs( InterpolationOptions::getPrecision() ); + } + + /** + * \brief Function used to set the options for the intersection calculation + * \details The following options can be modified: + * -# Precision: Level of precision of the computations. + * - Values: positive real number. + * - Default: 1.0E-12. + * -# Tolerance: Thickness of target element. + * - Values: positive real number. + * - Default: 1.0E-12. + * -# Median line: Position of the median line where both segments will be projected. + * - Values: real number between 0.0 and 1.0. + * - Default: 0.5 + */ + void Interpolation2DCurve::setOptions (double precision, + double tolerance, + double medianLine) + { + InterpolationOptions::setPrecision(precision); + InterpolationOptions::setBoundingBoxAdjustmentAbs(tolerance); + InterpolationOptions::setMedianPlane(medianLine); + } +} diff --git a/src/medtool/src/INTERP_KERNEL/Interpolation2DCurve.hxx b/src/medtool/src/INTERP_KERNEL/Interpolation2DCurve.hxx new file mode 100644 index 000000000..d0348bebe --- /dev/null +++ b/src/medtool/src/INTERP_KERNEL/Interpolation2DCurve.hxx @@ -0,0 +1,39 @@ +// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 +// 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 __INTERPOLATION2DCURVE_HXX__ +#define __INTERPOLATION2DCURVE_HXX__ + +#include "InterpolationCurve.hxx" +#include "InterpolationOptions.hxx" + +namespace INTERP_KERNEL +{ + class INTERPKERNEL_EXPORT Interpolation2DCurve : public InterpolationCurve<Interpolation2DCurve> + { + public: + Interpolation2DCurve(); + Interpolation2DCurve(const InterpolationOptions& io); + // geometric precision, intersection tolerance, coice of the median line, + void setOptions(double precision, double tolerance, double medianLine); + }; +} + +#endif diff --git a/src/medtool/src/INTERP_KERNEL/Interpolation3D.cxx b/src/medtool/src/INTERP_KERNEL/Interpolation3D.cxx new file mode 100644 index 000000000..16bd09cc0 --- /dev/null +++ b/src/medtool/src/INTERP_KERNEL/Interpolation3D.cxx @@ -0,0 +1,41 @@ +// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 +// 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 "Interpolation3D.hxx" +#include "Interpolation3D.txx" + +namespace INTERP_KERNEL +{ + /** + * \class Interpolation3D + * \brief Class used to calculate the volumes of intersection between the elements of two 3D meshes. + * + */ + /** + * Default constructor + * + */ + Interpolation3D::Interpolation3D() + { + } + Interpolation3D::Interpolation3D(const InterpolationOptions& io):Interpolation<Interpolation3D>(io) + { + } +} diff --git a/src/medtool/src/INTERP_KERNEL/Interpolation3D.hxx b/src/medtool/src/INTERP_KERNEL/Interpolation3D.hxx new file mode 100644 index 000000000..828c63c76 --- /dev/null +++ b/src/medtool/src/INTERP_KERNEL/Interpolation3D.hxx @@ -0,0 +1,43 @@ +// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 +// 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 __INTERPOLATION3D_HXX__ +#define __INTERPOLATION3D_HXX__ + +#include "INTERPKERNELDefines.hxx" +#include "Interpolation.hxx" +#include "NormalizedUnstructuredMesh.hxx" +#include "InterpolationOptions.hxx" + +namespace INTERP_KERNEL +{ + class INTERPKERNEL_EXPORT Interpolation3D : public Interpolation<Interpolation3D> + { + public: + Interpolation3D(); + Interpolation3D(const InterpolationOptions& io); + template<class MyMeshType, class MatrixType> + int interpolateMeshes(const MyMeshType& srcMesh, const MyMeshType& targetMesh, MatrixType& result, const std::string& method); + private: + SplittingPolicy _splitting_policy; + }; +} + +#endif diff --git a/src/medtool/src/INTERP_KERNEL/Interpolation3D.txx b/src/medtool/src/INTERP_KERNEL/Interpolation3D.txx new file mode 100644 index 000000000..bc68b525c --- /dev/null +++ b/src/medtool/src/INTERP_KERNEL/Interpolation3D.txx @@ -0,0 +1,370 @@ +// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 +// 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 __INTERPOLATION3D_TXX__ +#define __INTERPOLATION3D_TXX__ + +#include "Interpolation3D.hxx" +#include "Interpolation.txx" +#include "MeshElement.txx" +#include "TransformedTriangle.hxx" +#include "PolyhedronIntersectorP0P0.txx" +#include "PointLocator3DIntersectorP0P0.txx" +#include "PolyhedronIntersectorP0P1.txx" +#include "PointLocator3DIntersectorP0P1.txx" +#include "PolyhedronIntersectorP1P0.txx" +#include "PolyhedronIntersectorP1P0Bary.txx" +#include "PointLocator3DIntersectorP1P0.txx" +#include "PolyhedronIntersectorP1P1.txx" +#include "PointLocator3DIntersectorP1P1.txx" +#include "Barycentric3DIntersectorP1P1.txx" +#include "Log.hxx" +// If defined, use recursion to traverse the binary search tree, else use the BBTree class +//#define USE_RECURSIVE_BBOX_FILTER + +#ifdef USE_RECURSIVE_BBOX_FILTER +#include "MeshRegion.txx" +#include "RegionNode.hxx" +#include <stack> + +#else // use BBTree class + +#include "BBTree.txx" + +#endif + +namespace INTERP_KERNEL +{ + /** + * Calculates the matrix of volumes of intersection between the elements of srcMesh and the elements of targetMesh. + * The calculation is done in two steps. First a filtering process reduces the number of pairs of elements for which the + * calculation must be carried out by eliminating pairs that do not intersect based on their bounding boxes. Then, the + * volume of intersection is calculated by an object of type Intersector3D for the remaining pairs, and entered into the + * intersection matrix. + * + * The matrix is partially sparse : it is a vector of maps of integer - double pairs. + * It can also be an INTERP_KERNEL::Matrix object. + * The length of the vector is equal to the number of target elements - for each target element there is a map, regardless + * of whether the element intersects any source elements or not. But in the maps there are only entries for those source elements + * which have a non-zero intersection volume with the target element. The vector has indices running from + * 0 to (nb target elements - 1), meaning that the map for target element i is stored at index i - 1. In the maps, however, + * the indexing is more natural : the intersection volume of the target element i with source element j is found at matrix[i-1][j]. + * + + * @param srcMesh 3-dimensional source mesh + * @param targetMesh 3-dimesional target mesh, containing only tetraedra + * @param result matrix in which the result is stored + * + */ + template<class MyMeshType, class MatrixType> + int Interpolation3D::interpolateMeshes(const MyMeshType& srcMesh, const MyMeshType& targetMesh, MatrixType& result, const std::string& method) + { + typedef typename MyMeshType::MyConnType ConnType; + // create MeshElement objects corresponding to each element of the two meshes + const unsigned long numSrcElems = srcMesh.getNumberOfElements(); + const unsigned long numTargetElems = targetMesh.getNumberOfElements(); + + LOG(2, "Source mesh has " << numSrcElems << " elements and target mesh has " << numTargetElems << " elements "); + + std::vector<MeshElement<ConnType>*> srcElems(numSrcElems); + std::vector<MeshElement<ConnType>*> targetElems(numTargetElems); + + std::map<MeshElement<ConnType>*, int> indices; + + for(unsigned long i = 0 ; i < numSrcElems ; ++i) + srcElems[i] = new MeshElement<ConnType>(i, srcMesh); + + for(unsigned long i = 0 ; i < numTargetElems ; ++i) + targetElems[i] = new MeshElement<ConnType>(i, targetMesh); + + Intersector3D<MyMeshType,MatrixType>* intersector=0; + std::string methC = InterpolationOptions::filterInterpolationMethod(method); + if(methC=="P0P0") + { + switch(InterpolationOptions::getIntersectionType()) + { + case Triangulation: + intersector=new PolyhedronIntersectorP0P0<MyMeshType,MatrixType>(targetMesh, srcMesh, getSplittingPolicy()); + break; + case PointLocator: + intersector=new PointLocator3DIntersectorP0P0<MyMeshType,MatrixType>(targetMesh, srcMesh, getPrecision()); + break; + default: + throw INTERP_KERNEL::Exception("Invalid 3D intersection type for P0P0 interp specified : must be Triangle or PointLocator."); + } + } + else if(methC=="P0P1") + { + switch(InterpolationOptions::getIntersectionType()) + { + case Triangulation: + intersector=new PolyhedronIntersectorP0P1<MyMeshType,MatrixType>(targetMesh, srcMesh, getSplittingPolicy()); + break; + case PointLocator: + intersector=new PointLocator3DIntersectorP0P1<MyMeshType,MatrixType>(targetMesh, srcMesh, getPrecision()); + break; + default: + throw INTERP_KERNEL::Exception("Invalid 3D intersection type for P0P1 interp specified : must be Triangle or PointLocator."); + } + } + else if(methC=="P1P0") + { + switch(InterpolationOptions::getIntersectionType()) + { + case Triangulation: + intersector=new PolyhedronIntersectorP1P0<MyMeshType,MatrixType>(targetMesh, srcMesh, getSplittingPolicy()); + break; + case PointLocator: + intersector=new PointLocator3DIntersectorP1P0<MyMeshType,MatrixType>(targetMesh, srcMesh, getPrecision()); + break; + case Barycentric: + intersector=new PolyhedronIntersectorP1P0Bary<MyMeshType,MatrixType>(targetMesh, srcMesh, getSplittingPolicy()); + break; + default: + throw INTERP_KERNEL::Exception("Invalid 3D intersection type for P1P0 interp specified : must be Triangle, PointLocator or Barycentric."); + } + } + else if(methC=="P1P1") + { + switch(InterpolationOptions::getIntersectionType()) + { + case Triangulation: + intersector=new PolyhedronIntersectorP1P1<MyMeshType,MatrixType>(targetMesh, srcMesh, getSplittingPolicy()); + break; + case PointLocator: + intersector=new PointLocator3DIntersectorP1P1<MyMeshType,MatrixType>(targetMesh, srcMesh, getPrecision()); + break; + case Barycentric: + intersector=new Barycentric3DIntersectorP1P1<MyMeshType,MatrixType>(targetMesh, srcMesh, getPrecision()); + break; + default: + throw INTERP_KERNEL::Exception("Invalid 3D intersection type for P1P1 interp specified : must be Triangle or PointLocator."); + } + } + else + throw Exception("Invalid method choosed must be in \"P0P0\", \"P0P1\", \"P1P0\" or \"P1P1\"."); + // create empty maps for all source elements + result.resize(intersector->getNumberOfRowsOfResMatrix()); + +#ifdef USE_RECURSIVE_BBOX_FILTER + + /* + * Performs a depth-first search over srcMesh, using bounding boxes to recursively eliminate the elements of targetMesh + * which cannot intersect smaller and smaller regions of srcMesh. At each level, each region is divided in two, forming + * a binary search tree with leaves consisting of only one element of the source mesh together with the elements of the + * target mesh that can intersect it. The recursion is implemented with a stack of RegionNodes, each one containing a + * source region and a target region. Each region has an associated bounding box and a vector of pointers to the elements + * that belong to it. Each MeshElement contains a bounding box and the global number of the corresponding element in the mesh. + */ + + // create initial RegionNode and fill up its source region with all the source mesh elements and + // its target region with all the target mesh elements whose bounding box + // intersects that of the source region + + RegionNode<ConnType>* firstNode = new RegionNode<ConnType>(); + + MeshRegion<ConnType>& srcRegion = firstNode->getSrcRegion(); + + for(unsigned long i = 0 ; i < numSrcElems ; ++i) + { + srcRegion.addElement(srcElems[i], srcMesh); + } + + MeshRegion<ConnType>& targetRegion = firstNode->getTargetRegion(); + + for(unsigned long i = 0 ; i < numTargetElems ; ++i) + { + if(!srcRegion.isDisjointWithElementBoundingBox( *(targetElems[i]) )) + { + targetRegion.addElement(targetElems[i], targetMesh); + } + } + + // Using a stack, descend recursively, creating at each step two new RegionNodes having as source region the left and + // right part of the source region of the current node (created using MeshRegion::split()) and as target region all the + // elements of the target mesh whose bounding box intersects the corresponding part + // Continue until the source region contains only one element, at which point the intersection volumes are + // calculated with all the remaining target mesh elements and stored in the matrix if they are non-zero. + + std::stack< RegionNode<ConnType>* > nodes; + nodes.push(firstNode); + + while(!nodes.empty()) + { + RegionNode<ConnType>* currNode = nodes.top(); + nodes.pop(); + LOG(4, "Popping node "); + + if(currNode->getTargetRegion().getNumberOfElements() == 1) + { + // calculate volumes + LOG(4, " - One element"); + + MeshElement<ConnType>* targetElement = *(currNode->getTargetRegion().getBeginElements()); + std::vector<ConnType> intersectElems; + for(typename std::vector< MeshElement<ConnType>* >::const_iterator iter = currNode->getSrcRegion().getBeginElements();iter != currNode->getSrcRegion().getEndElements();++iter) + intersectElems.push_back((*iter)->getIndex()); + intersector->intersectCells(targetElement->getIndex(),intersectElems,result); + } + else // recursion + { + + LOG(4, " - Recursion"); + + RegionNode<ConnType>* leftNode = new RegionNode<ConnType>(); + RegionNode<ConnType>* rightNode = new RegionNode<ConnType>(); + + // split current source region + //} decide on axis + static BoundingBox::BoxCoord axis = BoundingBox::XMAX; + + currNode->getTargetRegion().split(leftNode->getTargetRegion(), rightNode->getTargetRegion(), axis, targetMesh); + + LOG(5, "After split, left target region has " << leftNode->getTargetRegion().getNumberOfElements() + << " elements and right target region has " << rightNode->getTargetRegion().getNumberOfElements() + << " elements"); + + // ugly hack to avoid problem with enum which does not start at 0 + // I guess I ought to implement ++ for it instead ... + // Anyway, it basically chooses the next axis, cyclically + axis = (axis != BoundingBox::ZMAX) ? static_cast<BoundingBox::BoxCoord>(axis + 1) : BoundingBox::XMAX; + + // add source elements of current node that overlap the target regions of the new nodes + LOG(5, " -- Adding source elements"); + int numLeftElements = 0; + int numRightElements = 0; + for(typename std::vector<MeshElement<ConnType>*>::const_iterator iter = currNode->getSrcRegion().getBeginElements() ; + iter != currNode->getSrcRegion().getEndElements() ; ++iter) + { + LOG(6, " --- New target node"); + + if(!leftNode->getTargetRegion().isDisjointWithElementBoundingBox(**iter)) + { + leftNode->getSrcRegion().addElement(*iter, srcMesh); + ++numLeftElements; + } + + if(!rightNode->getTargetRegion().isDisjointWithElementBoundingBox(**iter)) + { + rightNode->getSrcRegion().addElement(*iter, srcMesh); + ++numRightElements; + } + + } + + LOG(5, "Left src region has " << numLeftElements << " elements and right src region has " + << numRightElements << " elements"); + + // push new nodes on stack + if(numLeftElements != 0) + { + nodes.push(leftNode); + } + else + { + delete leftNode; + } + + if(numRightElements != 0) + { + nodes.push(rightNode); + } + else + { + delete rightNode; + } + } + + // all nodes are deleted here + delete currNode; + + LOG(4, "Next iteration. Nodes left : " << nodes.size()); + } + +#else // Use BBTree + + // create BBTree structure + // - get bounding boxes + double* bboxes = new double[6 * numSrcElems]; + int* srcElemIdx = new int[numSrcElems]; + for(unsigned long i = 0; i < numSrcElems ; ++i) + { + // get source bboxes in right order + const BoundingBox* box = srcElems[i]->getBoundingBox(); + bboxes[6*i+0] = box->getCoordinate(BoundingBox::XMIN); + bboxes[6*i+1] = box->getCoordinate(BoundingBox::XMAX); + bboxes[6*i+2] = box->getCoordinate(BoundingBox::YMIN); + bboxes[6*i+3] = box->getCoordinate(BoundingBox::YMAX); + bboxes[6*i+4] = box->getCoordinate(BoundingBox::ZMIN); + bboxes[6*i+5] = box->getCoordinate(BoundingBox::ZMAX); + + // source indices have to begin with zero for BBox, I think + srcElemIdx[i] = srcElems[i]->getIndex(); + } + + BBTree<3,ConnType> tree(bboxes, srcElemIdx, 0, numSrcElems); + + // for each target element, get source elements with which to calculate intersection + // - calculate intersection by calling intersectCells + for(unsigned long i = 0; i < numTargetElems; ++i) + { + const BoundingBox* box = targetElems[i]->getBoundingBox(); + const int targetIdx = targetElems[i]->getIndex(); + + // get target bbox in right order + double targetBox[6]; + targetBox[0] = box->getCoordinate(BoundingBox::XMIN); + targetBox[1] = box->getCoordinate(BoundingBox::XMAX); + targetBox[2] = box->getCoordinate(BoundingBox::YMIN); + targetBox[3] = box->getCoordinate(BoundingBox::YMAX); + targetBox[4] = box->getCoordinate(BoundingBox::ZMIN); + targetBox[5] = box->getCoordinate(BoundingBox::ZMAX); + + std::vector<ConnType> intersectElems; + + tree.getIntersectingElems(targetBox, intersectElems); + + if ( !intersectElems.empty() ) + intersector->intersectCells(targetIdx,intersectElems,result); + } + + delete [] bboxes; + delete [] srcElemIdx; + +#endif + // free allocated memory + int ret=intersector->getNumberOfColsOfResMatrix(); + + delete intersector; + + for(unsigned long i = 0 ; i < numSrcElems ; ++i) + { + delete srcElems[i]; + } + for(unsigned long i = 0 ; i < numTargetElems ; ++i) + { + delete targetElems[i]; + } + return ret; + + } +} + +#endif diff --git a/src/medtool/src/INTERP_KERNEL/Interpolation3D2D.cxx b/src/medtool/src/INTERP_KERNEL/Interpolation3D2D.cxx new file mode 100644 index 000000000..4e8cee7f7 --- /dev/null +++ b/src/medtool/src/INTERP_KERNEL/Interpolation3D2D.cxx @@ -0,0 +1,34 @@ +// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// + +#include "Interpolation3D2D.hxx" + +namespace INTERP_KERNEL +{ + /** + * Default constructor + * + */ + Interpolation3D2D::Interpolation3D2D() + { + } + Interpolation3D2D::Interpolation3D2D(const InterpolationOptions& io):Interpolation<Interpolation3D2D>(io) + { + } +} diff --git a/src/medtool/src/INTERP_KERNEL/Interpolation3D2D.hxx b/src/medtool/src/INTERP_KERNEL/Interpolation3D2D.hxx new file mode 100644 index 000000000..761c37f34 --- /dev/null +++ b/src/medtool/src/INTERP_KERNEL/Interpolation3D2D.hxx @@ -0,0 +1,61 @@ +// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 +// 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 __INTERPOLATION3D2D_HXX__ +#define __INTERPOLATION3D2D_HXX__ + +#include <set> +#include <map> + +#include "INTERPKERNELDefines.hxx" +#include "Interpolation.hxx" +#include "NormalizedUnstructuredMesh.hxx" +#include "InterpolationOptions.hxx" + +namespace INTERP_KERNEL +{ + /*! + * Contrary to its name this class deals with 2D mesh in source and 3D mesh in target. + * The meshdim of 'MyMeshType' in input is ignored that's why 'meshS' and 'meshT' + * have the same type. + * '_duplicate_faces' attribute stores duplicated faces in the following format. + * The key of '_duplicate_faces' represents the 2D cellId that is shared by + * more than one 3D target cell, and the value of '_duplicate_faces' + * the 3D target cells. The size of the value of '_duplicate_faces' is more than or equal to 2. + */ + class Interpolation3D2D : public Interpolation<Interpolation3D2D> + { + public: + typedef std::map<int,std::set<int> > DuplicateFacesType; + + INTERPKERNEL_EXPORT Interpolation3D2D(); + INTERPKERNEL_EXPORT Interpolation3D2D(const InterpolationOptions& io); + template<class MyMeshType, class MyMatrixType> + int interpolateMeshes(const MyMeshType& srcMesh, + const MyMeshType& targetMesh, + MyMatrixType& matrix, + const std::string& method); + INTERPKERNEL_EXPORT DuplicateFacesType retrieveDuplicateFaces() const { return _duplicate_faces; } + private: + SplittingPolicy _splitting_policy; + DuplicateFacesType _duplicate_faces; + }; +} + +#endif diff --git a/src/medtool/src/INTERP_KERNEL/Interpolation3D2D.txx b/src/medtool/src/INTERP_KERNEL/Interpolation3D2D.txx new file mode 100644 index 000000000..674317e1a --- /dev/null +++ b/src/medtool/src/INTERP_KERNEL/Interpolation3D2D.txx @@ -0,0 +1,190 @@ +// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 +// 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 __INTERPOLATION3D2D_TXX__ +#define __INTERPOLATION3D2D_TXX__ + +#include "Interpolation3D2D.hxx" +#include "Interpolation.txx" +#include "MeshElement.txx" +#include "TransformedTriangle.hxx" +#include "Polyhedron3D2DIntersectorP0P0.txx" +#include "PointLocator3DIntersectorP0P0.txx" +#include "PolyhedronIntersectorP0P1.txx" +#include "PointLocator3DIntersectorP0P1.txx" +#include "PolyhedronIntersectorP1P0.txx" +#include "PolyhedronIntersectorP1P0Bary.txx" +#include "PointLocator3DIntersectorP1P0.txx" +#include "PolyhedronIntersectorP1P1.txx" +#include "PointLocator3DIntersectorP1P1.txx" +#include "Log.hxx" + +#include "BBTree.txx" + +namespace INTERP_KERNEL +{ + /** + * Calculates the matrix of volumes of intersection between the elements of srcMesh and the elements of targetMesh. + * The calculation is done in two steps. First a filtering process reduces the number of pairs of elements for which the + * calculation must be carried out by eliminating pairs that do not intersect based on their bounding boxes. Then, the + * volume of intersection is calculated by an object of type Intersector3D for the remaining pairs, and entered into the + * intersection matrix. + * + * The matrix is partially sparse : it is a vector of maps of integer - double pairs. + * It can also be an INTERP_KERNEL::Matrix object. + * The length of the vector is equal to the number of target elements - for each target element there is a map, regardless + * of whether the element intersects any source elements or not. But in the maps there are only entries for those source elements + * which have a non-zero intersection volume with the target element. The vector has indices running from + * 0 to (nb target elements - 1), meaning that the map for target element i is stored at index i - 1. In the maps, however, + * the indexing is more natural : the intersection volume of the target element i with source element j is found at matrix[i-1][j]. + * + + * @param srcMesh 3-dimensional source mesh + * @param targetMesh 3-dimesional target mesh, containing only tetraedra + * @param matrix matrix in which the result is stored + * + */ + template<class MyMeshType, class MyMatrixType> + int Interpolation3D2D::interpolateMeshes(const MyMeshType& srcMesh, + const MyMeshType& targetMesh, + MyMatrixType& matrix, + const std::string& method) + { + typedef typename MyMeshType::MyConnType ConnType; + // create MeshElement objects corresponding to each element of the two meshes + const unsigned long numSrcElems = srcMesh.getNumberOfElements(); + const unsigned long numTargetElems = targetMesh.getNumberOfElements(); + + LOG(2, "Source mesh has " << numSrcElems << " elements and target mesh has " << numTargetElems << " elements "); + + std::vector<MeshElement<ConnType>*> srcElems(numSrcElems); + std::vector<MeshElement<ConnType>*> targetElems(numTargetElems); + + std::map<MeshElement<ConnType>*, int> indices; + DuplicateFacesType intersectFaces; + + for(unsigned long i = 0 ; i < numSrcElems ; ++i) + srcElems[i] = new MeshElement<ConnType>(i, srcMesh); + + for(unsigned long i = 0 ; i < numTargetElems ; ++i) + targetElems[i] = new MeshElement<ConnType>(i, targetMesh); + + Intersector3D<MyMeshType,MyMatrixType>* intersector=0; + std::string methC = InterpolationOptions::filterInterpolationMethod(method); + const double dimCaracteristic = CalculateCharacteristicSizeOfMeshes(srcMesh, targetMesh, InterpolationOptions::getPrintLevel()); + if(methC=="P0P0") + { + switch(InterpolationOptions::getIntersectionType()) + { + case Triangulation: + intersector=new Polyhedron3D2DIntersectorP0P0<MyMeshType,MyMatrixType>(targetMesh, + srcMesh, + dimCaracteristic, + getPrecision(), + intersectFaces, + getSplittingPolicy()); + break; + case PointLocator: + intersector=new PointLocator3DIntersectorP0P0<MyMeshType,MyMatrixType>(targetMesh,srcMesh,getPrecision()); + break; + default: + throw INTERP_KERNEL::Exception("Invalid 3D to 2D intersection type for P0P0 interp specified : must be Triangulation or PointLocator."); + } + } + else + throw Exception("Invalid method choosed must be in \"P0P0\"."); + // create empty maps for all source elements + matrix.resize(intersector->getNumberOfRowsOfResMatrix()); + + // create BBTree structure + // - get bounding boxes + double* bboxes = new double[6 * numSrcElems]; + int* srcElemIdx = new int[numSrcElems]; + for(unsigned long i = 0; i < numSrcElems ; ++i) + { + // get source bboxes in right order + const BoundingBox* box = srcElems[i]->getBoundingBox(); + bboxes[6*i+0] = box->getCoordinate(BoundingBox::XMIN); + bboxes[6*i+1] = box->getCoordinate(BoundingBox::XMAX); + bboxes[6*i+2] = box->getCoordinate(BoundingBox::YMIN); + bboxes[6*i+3] = box->getCoordinate(BoundingBox::YMAX); + bboxes[6*i+4] = box->getCoordinate(BoundingBox::ZMIN); + bboxes[6*i+5] = box->getCoordinate(BoundingBox::ZMAX); + + // source indices have to begin with zero for BBox, I think + srcElemIdx[i] = srcElems[i]->getIndex(); + } + + BBTree<3,ConnType> tree(bboxes, srcElemIdx, 0, numSrcElems, 0.); + + // for each target element, get source elements with which to calculate intersection + // - calculate intersection by calling intersectCells + for(unsigned long i = 0; i < numTargetElems; ++i) + { + const BoundingBox* box = targetElems[i]->getBoundingBox(); + const int targetIdx = targetElems[i]->getIndex(); + + // get target bbox in right order + double targetBox[6]; + targetBox[0] = box->getCoordinate(BoundingBox::XMIN); + targetBox[1] = box->getCoordinate(BoundingBox::XMAX); + targetBox[2] = box->getCoordinate(BoundingBox::YMIN); + targetBox[3] = box->getCoordinate(BoundingBox::YMAX); + targetBox[4] = box->getCoordinate(BoundingBox::ZMIN); + targetBox[5] = box->getCoordinate(BoundingBox::ZMAX); + + std::vector<ConnType> intersectElems; + + tree.getIntersectingElems(targetBox, intersectElems); + + if ( !intersectElems.empty() ) + intersector->intersectCells(targetIdx, intersectElems, matrix); + + } + + delete [] bboxes; + delete [] srcElemIdx; + + DuplicateFacesType::iterator iter; + for (iter = intersectFaces.begin(); iter != intersectFaces.end(); ++iter) + { + if (iter->second.size() > 1) + { + _duplicate_faces.insert(std::make_pair(iter->first, iter->second)); + } + } + + // free allocated memory + int ret=intersector->getNumberOfColsOfResMatrix(); + + delete intersector; + + for(unsigned long i = 0 ; i < numSrcElems ; ++i) + { + delete srcElems[i]; + } + for(unsigned long i = 0 ; i < numTargetElems ; ++i) + { + delete targetElems[i]; + } + return ret; + + } +} + +#endif diff --git a/src/medtool/src/INTERP_KERNEL/Interpolation3DSurf.cxx b/src/medtool/src/INTERP_KERNEL/Interpolation3DSurf.cxx new file mode 100644 index 000000000..708d11a37 --- /dev/null +++ b/src/medtool/src/INTERP_KERNEL/Interpolation3DSurf.cxx @@ -0,0 +1,61 @@ +// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 +// 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 "Interpolation3DSurf.hxx" +#include "InterpolationPlanar.txx" + +namespace INTERP_KERNEL +{ + Interpolation3DSurf::Interpolation3DSurf() + { + } + + Interpolation3DSurf::Interpolation3DSurf(const InterpolationOptions& io):InterpolationPlanar<Interpolation3DSurf>(io) + { + } + + + /** + \brief Function used to set the options for the intersection calculation + \details The following options can be modified: + -# intersectionType: the type of algorithm to be used in the computation of the cell-cell intersections. + - Values: Triangle, Convex. + - Default: Triangle. + -# medianPlan: Position of the median plane where both cells will be projected + - Values: between 0 and 1. + - Default: 0.5. + -# doRotat: rotate the coordinate system such that the target cell is in the Oxy plane. + - Values: true (necessarilly if Intersection_type=Triangle), false. + - Default: true (as default Intersection_type=Triangle) + -# precision: Level of precision of the computations is precision times the characteristic size of the mesh. + - Values: positive real number. + - Default: 1.0E-12. + -# printLevel: Level of verboseness during the computations. + - Values: interger between 0 and 3. + - Default: 0. + */ + void Interpolation3DSurf::setOptions(double precision, int printLevel, double medianPlan, + IntersectionType intersectionType, bool doRotat, int orientation) + { + InterpolationPlanar<Interpolation3DSurf>::setOptions(precision,printLevel,intersectionType, orientation); + InterpolationPlanar<Interpolation3DSurf>::setDoRotate(doRotat); + InterpolationPlanar<Interpolation3DSurf>::setMedianPlane(medianPlan); + } +} diff --git a/src/medtool/src/INTERP_KERNEL/Interpolation3DSurf.hxx b/src/medtool/src/INTERP_KERNEL/Interpolation3DSurf.hxx new file mode 100644 index 000000000..fda0fdd61 --- /dev/null +++ b/src/medtool/src/INTERP_KERNEL/Interpolation3DSurf.hxx @@ -0,0 +1,44 @@ +// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 +// 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 __INTERPOLATION3DSURF_HXX__ +#define __INTERPOLATION3DSURF_HXX__ + +#include "InterpolationPlanar.txx" +#include "INTERPKERNELDefines.hxx" +#include "InterpolationOptions.hxx" + +namespace INTERP_KERNEL +{ + class INTERPKERNEL_EXPORT Interpolation3DSurf : public InterpolationPlanar<Interpolation3DSurf> + { + public: + Interpolation3DSurf(); + Interpolation3DSurf(const InterpolationOptions& io); + void setOptions(double precision, int printLevel, double medianPlane, + IntersectionType intersectionType, bool doRotate, int orientation=0); + public: + template<class MyMeshType, class MyMatrixRow> + void performAdjustmentOfBB(PlanarIntersector<MyMeshType,MyMatrixRow>* intersector, std::vector<double>& bbox) const + { intersector->adjustBoundingBoxes(bbox,InterpolationPlanar<Interpolation3DSurf>::getBoundingBoxAdjustment(),InterpolationPlanar<Interpolation3DSurf>::getBoundingBoxAdjustmentAbs()); } + }; +} + +#endif diff --git a/src/medtool/src/INTERP_KERNEL/InterpolationCC.hxx b/src/medtool/src/INTERP_KERNEL/InterpolationCC.hxx new file mode 100644 index 000000000..62f844b06 --- /dev/null +++ b/src/medtool/src/INTERP_KERNEL/InterpolationCC.hxx @@ -0,0 +1,51 @@ +// Copyright (C) 2009-2015 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, 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 +// 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 +// + +// File : InterpolationCC.hxx +// Created : Fri Aug 14 11:33:17 2009 +// Author : Edward AGAPOV (eap) +// +#ifndef __InterpolationCC_HXX__ +#define __InterpolationCC_HXX__ + +#include "Interpolation.hxx" + +namespace INTERP_KERNEL +{ + /*! + * \brief Interpolator of cartesian/cartesian meshes + */ + class InterpolationCC : public Interpolation<InterpolationCC> + { +// static const int SPACEDIM=MyMeshType::MY_SPACEDIM; +// static const int MESHDIM=MyMeshType::MY_MESHDIM; +// typedef typename MyMeshType::MyConnType ConnType; +// static const NumberingPolicy numPol=MyMeshType::My_numPol; + public: + InterpolationCC(); + InterpolationCC(const InterpolationOptions& io); + template<class MyMeshType, class MatrixType> + int interpolateMeshes(const MyMeshType& srcMesh, const MyMeshType& targetMesh, MatrixType& result, const char *method); + + private: + }; +} + + +#endif diff --git a/src/medtool/src/INTERP_KERNEL/InterpolationCC.txx b/src/medtool/src/INTERP_KERNEL/InterpolationCC.txx new file mode 100644 index 000000000..ea75faced --- /dev/null +++ b/src/medtool/src/INTERP_KERNEL/InterpolationCC.txx @@ -0,0 +1,252 @@ +// Copyright (C) 2009-2015 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, 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 +// 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 +// +// File : InterpolationCC.txx +// Created : Fri Aug 14 11:39:27 2009 +// Author : Edward AGAPOV (eap) +// + +#include "InterpolationCC.hxx" +#include "InterpolationUtils.hxx" + +// convert index "From Mesh Index" +#define _FMI(i) OTT<typename MyMeshType::MyConnType,MyMeshType::My_numPol>::ind2C((i)) +// convert index "To Mesh Index" +#define _TMI(i) OTT<typename MyMeshType::MyConnType,MyMeshType::My_numPol>::indFC((i)) + +namespace INTERP_KERNEL +{ + //================================================================================ + /*! + * \brief Constructor does nothing + */ + //================================================================================ + InterpolationCC::InterpolationCC() + { + } + + InterpolationCC::InterpolationCC(const InterpolationOptions& io):Interpolation<InterpolationCC>(io) + { + } + + //================================================================================ + /*! + * \brief An 1D intersection result + */ + //================================================================================ + + struct Interference + { + int _src_index; // source cell index along an axis + int _tgt_index; // target cell index along an axis + double _length; // interference length + Interference(int is = -1, int it = -1, double l = 0):_src_index(is),_tgt_index(it),_length(l){} + }; + + //================================================================================ + /*! + * \brief Fills the matrix by precomputed cell interferences along axes + * \param inter_of_axis - cell/cell interferences along each axis + * \param result - matrix to fill in + * \param src_nb_cells[] - nb of cells along each of axes in the source mesh + * \param tgt_nb_cells[] - nb of cells along each of axes in the target mesh + * \param src_i_cell - source cell number accumulated by previous axes + * \param tgt_i_cell - target cell number accumulated by previous axes + * \param src_prev_area - factor by which this axis icreases cell number + * \param tgt_prev_area - factor by which this axis icreases cell number + * \param axis - the axis to treat + * \param prev_value - intersection size computed by previous axes + */ + //================================================================================ + + template <class MyMeshType, class MatrixType, int dim> + void fillMatrix(const std::list< Interference > inter_of_axis[dim], + MatrixType& result, + const int src_nb_cells[dim], + const int tgt_nb_cells[dim], + const int src_i_cell = 0, + const int tgt_i_cell = 0, + const int src_prev_area = 1, + const int tgt_prev_area = 1, + const int axis = 0, + const double prev_value = 1.0) + { + typedef std::list < Interference >::const_iterator TIntIterator; + + if ( axis + 1 == dim ) + { + for ( TIntIterator i = inter_of_axis[axis].begin(); i != inter_of_axis[axis].end(); ++i ) + { + double value = i->_length * prev_value; + int src_i = i->_src_index * src_prev_area + src_i_cell; + int tgt_i = i->_tgt_index * tgt_prev_area + tgt_i_cell; + + result[ tgt_i ].insert( std::make_pair( _TMI( src_i ), value )); + } + } + else + { + int src_prev_area_next = src_prev_area * src_nb_cells[ axis ]; + int tgt_prev_area_next = tgt_prev_area * tgt_nb_cells[ axis ]; + + for ( TIntIterator i = inter_of_axis[axis].begin(); i != inter_of_axis[axis].end(); ++i ) + { + double value = i->_length * prev_value; + int src_i = i->_src_index * src_prev_area + src_i_cell; + int tgt_i = i->_tgt_index * tgt_prev_area + tgt_i_cell; + + // call for the next axis + fillMatrix<MyMeshType, MatrixType, dim>(inter_of_axis, result, + src_nb_cells, tgt_nb_cells, src_i, tgt_i, + src_prev_area_next, tgt_prev_area_next, + axis+1, value ); + } + } + } + + //================================================================================ + /*! + * \brief Calculates the matrix of volumes of intersection between the elements of + * src_mesh and the elements of targetMesh + * \param src_mesh - source mesh + * \param tgt_mesh - target mesh + * \param result - matrix in which the result is stored + * \param method - interpolation method, not used as only "P0P0" is implemented so far + * + * The matrix is partially sparse : it is a vector of maps of integer - double pairs. + * It can also be an INTERP_KERNEL::Matrix object. + * The length of the vector is equal to the number of target elements - for each target + * element there is a map, regardless of whether the element intersects any source + * elements or not. But in the maps there are only entries for those source elements + * which have a non-zero intersection volume with the target element. The vector has + * indices running from 0 to (nb target elements - 1), meaning that the map for target + * element i is stored at index i - 1. In the maps, however, the indexing is more natural: + * the intersection volume of the target element i with source element j is found at matrix[i-1][j] + */ + //================================================================================ + + template<class MyMeshType, class MatrixType> + int InterpolationCC::interpolateMeshes(const MyMeshType& src_mesh, + const MyMeshType& tgt_mesh, + MatrixType& result, + const char * method) + { + if ( std::string("P0P0") != method ) + throw Exception("Only P0P0 method is implemented so far"); + + // create empty maps for all target elements + result.resize( tgt_mesh.getNumberOfElements() ); + + const int ret = src_mesh.getNumberOfElements(); + + const double eps = getPrecision(); + const int dim = MyMeshType::MY_MESHDIM; + //const NumberingPolicy numPol = MyMeshType::My_numPol; + + const double* src_coords[ dim ]; + const double* tgt_coords[ dim ]; + int src_nb_cells[ dim ]; + int tgt_nb_cells[ dim ]; + for ( int j = 0; j < dim; ++j ) + { + src_coords[ j ] = src_mesh.getCoordsAlongAxis( _TMI( j )); + tgt_coords[ j ] = tgt_mesh.getCoordsAlongAxis( _TMI( j )); + src_nb_cells[ j ] = src_mesh.nbCellsAlongAxis( _TMI( j )); + tgt_nb_cells[ j ] = tgt_mesh.nbCellsAlongAxis( _TMI( j )); + } + + // ============================================ + // Calculate cell interferences along the axes + // ============================================ + + std::list < Interference > interferences[ dim ]; + + for ( int j = 0; j < dim; ++j ) // loop on axes of castesian space + { + std::list < Interference >& axis_interferences = interferences[j]; + + int it = 0, is = 0; + double x1t, x2t, x1s, x2s; // left and right ordinates of target and source cells + + // look for the first interference + // -------------------------------- + bool intersection = false; + while ( !intersection && it < tgt_nb_cells[j] && is < src_nb_cells[j] ) + { + x1s = src_coords[ j ][ is ]; + x2t = tgt_coords[ j ][ it+1 ]; + if ( x2t < x1s+eps ) + { + it++; // source lays on the right of target + continue; + } + x1t = tgt_coords[ j ][ it ]; + x2s = src_coords[ j ][ is+1 ]; + if ( x2s < x1t+eps ) + { + is++; // source lays on the left of target + continue; + } + intersection = true; + } + if ( !intersection ) return ret; // no intersections + + // get all interferences + // ---------------------- + while ( intersection ) + { + x1s = src_coords[ j ][ is ]; + x1t = tgt_coords[ j ][ it ]; + x2t = tgt_coords[ j ][ it+1 ]; + x2s = src_coords[ j ][ is+1 ]; + + double x1 = std::max( x1s ,x1t ); + double x2 = std::min( x2s ,x2t ); + axis_interferences.push_back( Interference( is, it, x2 - x1 )); + + // to the next target and/or source cell + double diff2 = x2s - x2t; + if ( diff2 > -eps ) + intersection = ( ++it < tgt_nb_cells[j] ); + if ( diff2 < eps ) + intersection = ( ++is < src_nb_cells[j] && intersection); + } + } + + // ================ + // Fill the matrix + // ================ + + switch ( dim ) + { + case 3: + fillMatrix<MyMeshType,MatrixType,3>( interferences, result, src_nb_cells,tgt_nb_cells ); + break; + + case 2: + fillMatrix<MyMeshType,MatrixType,2>( interferences, result, src_nb_cells,tgt_nb_cells ); + break; + + case 1: + fillMatrix<MyMeshType,MatrixType,1>( interferences, result, src_nb_cells,tgt_nb_cells ); + break; + } + + return ret; + } +} diff --git a/src/medtool/src/INTERP_KERNEL/InterpolationCU.hxx b/src/medtool/src/INTERP_KERNEL/InterpolationCU.hxx new file mode 100644 index 000000000..1b9589777 --- /dev/null +++ b/src/medtool/src/INTERP_KERNEL/InterpolationCU.hxx @@ -0,0 +1,47 @@ +// Copyright (C) 2009-2015 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, 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 +// 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 +// + +// File : InterpolationCU.hxx +// Created : Mon Dec 14 16:52:53 2009 +// Author : Edward AGAPOV (eap) +// +#ifndef __InterpolationCU_HXX__ +#define __InterpolationCU_HXX__ + +#include "Interpolation.hxx" +#include "NormalizedUnstructuredMesh.hxx" + +namespace INTERP_KERNEL +{ + class InterpolationCU : public Interpolation< InterpolationCU > + { + public: + InterpolationCU(); + InterpolationCU(const InterpolationOptions & io); + + template<class MyCMeshType, class MyUMeshType, class MatrixType> + int interpolateMeshes(const MyCMeshType& meshS, const MyUMeshType& meshT, MatrixType& result, const char *method); + + template<class MyUMeshType, class MyCMeshType, class MatrixType> + int interpolateMeshesRev(const MyUMeshType& meshS, const MyCMeshType& meshT, MatrixType& result, const char *method); + + }; +} + +#endif diff --git a/src/medtool/src/INTERP_KERNEL/InterpolationCU.txx b/src/medtool/src/INTERP_KERNEL/InterpolationCU.txx new file mode 100644 index 000000000..51b30bfbd --- /dev/null +++ b/src/medtool/src/INTERP_KERNEL/InterpolationCU.txx @@ -0,0 +1,236 @@ +// Copyright (C) 2009-2015 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, 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 +// 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 +// +// File : InterpolationCU.txx +// Created : Mon Dec 14 17:30:25 2009 +// Author : Edward AGAPOV (eap) + +#ifndef __InterpolationCU_TXX__ +#define __InterpolationCU_TXX__ + +#include "InterpolationCU.hxx" + +#include "Interpolation.txx" +#include "IntersectorCU1D.txx" +#include "IntersectorCU2D.txx" +#include "IntersectorCU3D.txx" + +#include <map> + +// // convert index "From Mesh Index" +#define _FMIU(i) OTT<typename MyUMeshType::MyConnType,MyUMeshType::My_numPol>::ind2C((i)) +#define _FMIC(i) OTT<typename MyCMeshType::MyConnType,MyCMeshType::My_numPol>::ind2C((i)) +// convert index "To Mesh Index" +#define _TMIU(i) OTT<typename MyUMeshType::MyConnType,MyUMeshType::My_numPol>::indFC((i)) +#define _TMIC(i) OTT<typename MyCMeshType::MyConnType,MyCMeshType::My_numPol>::indFC((i)) +// convert coord "From Mesh Coord" +#define _FMCOO(i) OTT<typename MyUMeshType::MyConnType,MyUMeshType::My_numPol>::coo2C((i)) +// convert connectivity "From Mesh Connectivity" +#define _FMCON(i) OTT<typename MyUMeshType::MyConnType,MyUMeshType::My_numPol>::conn2C((i)) + +namespace INTERP_KERNEL +{ + /** + * \defgroup InterpolationCU InterpolationCU + * \class InterpolationCU + * \brief Class used to calculate the volumes of intersection between the elements of a cartesian and an unstructured meshes. + * + */ + //================================================================================ + /** + * Default constructor + * + */ + //================================================================================ + + InterpolationCU::InterpolationCU() + { + } + + InterpolationCU::InterpolationCU(const InterpolationOptions & io) + :Interpolation<InterpolationCU>(io) + { + } + + //================================================================================ + /** + * Calculates the matrix of volumes of intersection between the elements of srcMesh and the elements of targetMesh. + * The calculation is done in two steps. First a filtering process reduces the number of pairs of elements for which the + * calculation must be carried out by eliminating pairs that do not intersect based on their bounding boxes. Then, the + * volume of intersection is calculated for the remaining pairs, and entered into the + * intersection matrix. + * + * The matrix is partially sparse : it is a vector of maps of integer - double pairs. + * It can also be an INTERP_KERNEL::Matrix object. + * The length of the vector is equal to the number of target elements - for each target element there is a map, regardless + * of whether the element intersects any source elements or not. But in the maps there are only entries for those source elements + * which have a non-zero intersection volume with the target element. The vector has indices running from + * 0 to (nb target elements - 1), meaning that the map for target element i is stored at index i - 1. In the maps, however, + * the indexing is more natural : the intersection volume of the target element i with source element j is found at matrix[i-1][j]. + * + + * @param srcMesh cartesian source mesh + * @param targetMesh unstructured target mesh + * @param result matrix in which the result is stored + * @param method interpolation method + */ + //================================================================================ + + template<class MyCMeshType, class MyUMeshType, class MatrixType> + int InterpolationCU::interpolateMeshes(const MyCMeshType& src_mesh, + const MyUMeshType& tgt_mesh, + MatrixType& result, + const char * method) + { + typedef typename MyCMeshType::MyConnType CConnType; + + if ( std::string("P0P0") != method ) + throw Exception("Only P0P0 method is implemented so far"); + if ( MyCMeshType::MY_SPACEDIM != MyUMeshType::MY_SPACEDIM || + MyCMeshType::MY_SPACEDIM != MyUMeshType::MY_MESHDIM ) + throw Exception("InterpolationCU::interpolateMeshes(): dimension of meshes must be same"); + + const double eps = getPrecision(); + const int dim = MyCMeshType::MY_SPACEDIM; + + TargetIntersector<MyCMeshType, MatrixType>* intersector = 0; + switch( dim ) + { + case 1: intersector = new IntersectorCU1D<MyCMeshType, MyUMeshType, MatrixType>( src_mesh, tgt_mesh ); break; + case 2: intersector = new IntersectorCU2D<MyCMeshType, MyUMeshType, MatrixType>( src_mesh, tgt_mesh ); break; + case 3: intersector = new IntersectorCU3D<MyCMeshType, MyUMeshType, MatrixType>( src_mesh, tgt_mesh, getSplittingPolicy() ); break; + } + // create empty maps for all target elements + result.resize( intersector->getNumberOfRowsOfResMatrix() ); + const int ret = intersector->getNumberOfColsOfResMatrix(); + + const double* src_coords[ dim ]; + int src_nb_coords[ dim ]; + std::map< double, int> src_coord_to_index[ dim ]; + for ( int j = 0; j < dim; ++j ) + { + src_coords [j] = src_mesh.getCoordsAlongAxis( _TMIC( j )); + src_nb_coords[j] = src_mesh.nbCellsAlongAxis ( _TMIC( j )) + 1; + for (int i = 0; i < src_nb_coords[j]; ++i ) + src_coord_to_index[j].insert( std::make_pair( src_coords[j][i], i )); + } + + const unsigned long tgtu_nb_cells = tgt_mesh.getNumberOfElements(); + + IntersectorCU<MyCMeshType, MyUMeshType, MatrixType> bbHelper(src_mesh, tgt_mesh); + double bb[2*dim]; + + // loop on unstructured tgt cells + + for(unsigned int iT=0; iT<tgtu_nb_cells; iT++) + { + result[ iT ].clear(); + + // get bounding box of target cell + bbHelper.getUElemBB( bb, _TMIU(iT)); + + bool doItersect = true; + for ( int j = 0; j < dim && doItersect; ++j ) + doItersect = + bb[j*2] < src_coords[j][ src_nb_coords[j]-1 ] - eps && + bb[j*2+1] > src_coords[j][0] + eps; + if ( !doItersect ) + continue; // no intersection + + // find structured src cells intersecting iT cell + std::vector< std::vector< CConnType > > structIndices(1); + std::map< double, int>::iterator coo_ind; + for ( int j = 0; j < dim; ++j ) + { + coo_ind = src_coord_to_index[j].lower_bound( bb[2*j+1] - eps ); + if ( coo_ind == src_coord_to_index[j].end() ) + --coo_ind; + int max_i = coo_ind->second; + + coo_ind = src_coord_to_index[j].upper_bound( bb[2*j ] + eps ); + if ( coo_ind != src_coord_to_index[j].begin() ) + --coo_ind; + int min_i = coo_ind->second; + + std::vector< std::vector< CConnType > > newStructIndices; + for ( unsigned int iInd = 0; iInd < structIndices.size(); ++iInd ) + { + for ( int i = min_i; i < max_i; ++i ) + { + std::vector< CConnType > index = structIndices[iInd]; + index.push_back( i ); + newStructIndices.push_back( index ); + } + } + structIndices.swap( newStructIndices ); + } + + // perform intersection + + for ( unsigned int iInd = 0; iInd < structIndices.size(); ++iInd ) + intersector->intersectCells( iT, structIndices[iInd], result ); + } + delete intersector; + return ret; + } + + //================================================================================ + /** + * Calculates the matrix of volumes of intersection between the elements of srcMesh and the elements of targetMesh. + * The calculation is done in two steps. First a filtering process reduces the number of pairs of elements for which the + * calculation must be carried out by eliminating pairs that do not intersect based on their bounding boxes. Then, the + * volume of intersection is calculated for the remaining pairs, and entered into the + * intersection matrix. + * + * The matrix is partially sparse : it is a vector of maps of integer - double pairs. + * It can also be an INTERP_KERNEL::Matrix object. + * The length of the vector is equal to the number of target elements - for each target element there is a map, regardless + * of whether the element intersects any source elements or not. But in the maps there are only entries for those source elements + * which have a non-zero intersection volume with the target element. The vector has indices running from + * 0 to (nb target elements - 1), meaning that the map for target element i is stored at index i - 1. In the maps, however, + * the indexing is more natural : the intersection volume of the target element i with source element j is found at matrix[i-1][j]. + * + + * @param srcMesh 2-dimesional unstructured target mesh + * @param targetMesh 2-dimensional cartesian source mesh + * @param result matrix in which the result is stored + * @param method interpolation method + */ + //================================================================================ + + template<class MyUMeshType, class MyCMeshType, class MatrixType> + int InterpolationCU::interpolateMeshesRev(const MyUMeshType& meshS, const MyCMeshType& meshT, MatrixType& result, const char *method) + { + MatrixType revResult; + int sizeT = interpolateMeshes( meshT, meshS, revResult, method ); + int sizeS = revResult.size(); + result.resize( sizeT ); + + for ( int iS = 0; iS < sizeS; ++iS ) + { + typename MatrixType::value_type & row = revResult[iS]; + typename MatrixType::value_type::iterator iT_surf = row.begin(); + for ( ; iT_surf != row.end(); ++iT_surf ) + result[ iT_surf->first ][ iS ] = iT_surf->second; + } + return sizeS; + } + +} + +#endif diff --git a/src/medtool/src/INTERP_KERNEL/InterpolationCurve.hxx b/src/medtool/src/INTERP_KERNEL/InterpolationCurve.hxx new file mode 100644 index 000000000..5bdc1a9d5 --- /dev/null +++ b/src/medtool/src/INTERP_KERNEL/InterpolationCurve.hxx @@ -0,0 +1,44 @@ +// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 +// 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 __INTERPOLATIONCURVE_HXX__ +#define __INTERPOLATIONCURVE_HXX__ + +#include "Interpolation.hxx" +#include "InterpolationOptions.hxx" + +namespace INTERP_KERNEL +{ + template<class RealCurve> + class InterpolationCurve : public Interpolation< InterpolationCurve<RealCurve> > + { + public: + InterpolationCurve(); + InterpolationCurve(const InterpolationOptions & io); + + // Main function to interpolate + template<class MyMeshType, class MatrixType> + int interpolateMeshes(const MyMeshType& meshS, const MyMeshType& meshT, + MatrixType& result, const std::string& method); + + }; +} + +#endif diff --git a/src/medtool/src/INTERP_KERNEL/InterpolationCurve.txx b/src/medtool/src/INTERP_KERNEL/InterpolationCurve.txx new file mode 100644 index 000000000..239370a61 --- /dev/null +++ b/src/medtool/src/INTERP_KERNEL/InterpolationCurve.txx @@ -0,0 +1,216 @@ +// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 +// 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 __INTERPOLATIONCURVE_TXX__ +#define __INTERPOLATIONCURVE_TXX__ + +#include "InterpolationCurve.hxx" +#include "InterpolationOptions.hxx" +#include "CurveIntersectorP0P0.txx" +#include "CurveIntersectorP1P0.txx" +#include "CurveIntersectorP0P1.txx" +#include "CurveIntersectorP1P1.txx" +#include "CurveIntersectorP1P1PL.txx" +#include "BBTree.txx" + +#include <time.h> + +namespace INTERP_KERNEL +{ + /** + * \defgroup interpolationCurve InterpolationCurve + * + * \class InterpolationCurve + * \brief Class used to compute the coefficients of the interpolation matrix between + * two local meshes in two dimensions. + */ + template<class RealCurve> + InterpolationCurve<RealCurve>::InterpolationCurve() + { + } + + template<class RealCurve> + InterpolationCurve<RealCurve>::InterpolationCurve (const InterpolationOptions& io) + :Interpolation< InterpolationCurve<RealCurve> >(io) + { + } + + /** \brief Main function to interpolate 1D meshes. + \details The algorithm proceeds in two steps: first a filtering process reduces the number of pairs of elements for which the + * calculation must be carried out by eliminating pairs that do not intersect based on their bounding boxes. Then, the + * volume of intersection is calculated by an object of type IntersectorPlanar for the remaining pairs, and entered into the + * intersection matrix. + * + * The matrix is partially sparse : it is a vector of maps of integer - double pairs. + * The length of the vector is equal to the number of target elements - for each target element there is a map, regardless + * of whether the element intersects any source elements or not. But in the maps there are only entries for those source elements + * which have a non-zero intersection volume with the target element. The vector has indices running from + * 0 to (#target elements - 1), meaning that the map for target element i is stored at index i - 1. In the maps, however, + * the indexing is more natural : the intersection volume of the target element i with source element j is found at matrix[i-1][j]. + * + + * @param myMeshS Planar source mesh + * @Param myMeshT Planar target mesh + * @return vector containing for each element i of the source mesh, a map giving for each element j + * of the target mesh which i intersects, the area of the intersection + * + */ + template<class RealCurve> + template<class MyMeshType, class MatrixType> + int InterpolationCurve<RealCurve>::interpolateMeshes (const MyMeshType& myMeshS, + const MyMeshType& myMeshT, + MatrixType& result, + const std::string& method) + { + static const int SPACEDIM=MyMeshType::MY_SPACEDIM; + typedef typename MyMeshType::MyConnType ConnType; + static const NumberingPolicy numPol = MyMeshType::My_numPol; + + long global_start = clock(); + int counter=0; + + long nbMailleS = myMeshS.getNumberOfElements(); + long nbMailleT = myMeshT.getNumberOfElements(); + + CurveIntersector<MyMeshType,MatrixType>* intersector=0; + if(method=="P0P0") + { + switch (InterpolationOptions::getIntersectionType()) + { + case Triangulation: + { + intersector = new CurveIntersectorP0P0<MyMeshType,MatrixType>(myMeshT, myMeshS, + InterpolationOptions::getPrecision(), + InterpolationOptions::getBoundingBoxAdjustmentAbs(), + InterpolationOptions::getMedianPlane(), + InterpolationOptions::getPrintLevel()); + break; + } + default: + throw INTERP_KERNEL::Exception("For P0P0 in 1D or 2D curve only Triangulation supported for the moment !"); + } + } + else if(method=="P0P1") + { + switch (InterpolationOptions::getIntersectionType()) + { + case Triangulation: + { + intersector = new CurveIntersectorP0P1<MyMeshType,MatrixType>(myMeshT, myMeshS, + InterpolationOptions::getPrecision(), + InterpolationOptions::getBoundingBoxAdjustmentAbs(), + InterpolationOptions::getMedianPlane(), + InterpolationOptions::getPrintLevel()); + break; + } + default: + throw INTERP_KERNEL::Exception("For P0P1 in 1D or 2D curve only Triangulation supported for the moment !"); + } + } + else if(method=="P1P0") + { + switch (InterpolationOptions::getIntersectionType()) + { + case Triangulation: + { + intersector = new CurveIntersectorP1P0<MyMeshType,MatrixType>(myMeshT, myMeshS, + InterpolationOptions::getPrecision(), + InterpolationOptions::getBoundingBoxAdjustmentAbs(), + InterpolationOptions::getMedianPlane(), + InterpolationOptions::getPrintLevel()); + break; + } + default: + throw INTERP_KERNEL::Exception("For P1P0 in 1D or 2D curve only Triangulation supported for the moment !"); + } + } + else if(method=="P1P1") + { + switch (InterpolationOptions::getIntersectionType()) + { + case Triangulation: + intersector = new CurveIntersectorP1P1<MyMeshType,MatrixType> + (myMeshT, myMeshS, + InterpolationOptions::getPrecision(), + InterpolationOptions::getBoundingBoxAdjustmentAbs(), + InterpolationOptions::getMedianPlane(), + InterpolationOptions::getPrintLevel()); + break; + case PointLocator: + intersector = new CurveIntersectorP1P1PL<MyMeshType,MatrixType> + (myMeshT, myMeshS, + InterpolationOptions::getPrecision(), + InterpolationOptions::getBoundingBoxAdjustmentAbs(), + InterpolationOptions::getMedianPlane(), + InterpolationOptions::getPrintLevel()); + break; + default: + throw INTERP_KERNEL::Exception("For P1P1 in 1D or 2D curve only Triangulation and PointLocator supported !"); + } + } + else + throw INTERP_KERNEL::Exception("Invalid method specified ! Must be in : \"P0P0\" \"P0P1\" \"P1P0\" or \"P1P1\""); + /****************************************************************/ + /* Create a search tree based on the bounding boxes */ + /* Instanciate the intersector and initialise the result vector */ + /****************************************************************/ + + long start_filtering=clock(); + + std::vector<double> bbox; + intersector->createBoundingBoxes(myMeshS,bbox); // create the bounding boxes + intersector->adjustBoundingBoxes(bbox, InterpolationOptions::getBoundingBoxAdjustmentAbs()); + BBTree<SPACEDIM,ConnType> my_tree(&bbox[0], 0, 0, nbMailleS);//creating the search structure + + long end_filtering = clock(); + + result.resize(intersector->getNumberOfRowsOfResMatrix());//on initialise. + + /****************************************************/ + /* Loop on the target cells - core of the algorithm */ + /****************************************************/ + long start_intersection = clock(); + const ConnType *connIndxT = myMeshT.getConnectivityIndexPtr(); + for(int iT=0; iT<nbMailleT; iT++) + { + int nb_nodesT = connIndxT[iT+1] - connIndxT[iT]; + std::vector<int> intersecting_elems; + double bb[2*SPACEDIM]; + intersector->getElemBB(bb,myMeshT,OTT<ConnType,numPol>::indFC(iT),nb_nodesT); + my_tree.getIntersectingElems(bb, intersecting_elems); + intersector->intersectCells(iT,intersecting_elems,result); + counter += intersecting_elems.size(); + } + int ret = intersector->getNumberOfColsOfResMatrix(); + delete intersector; + + if (InterpolationOptions::getPrintLevel() >= 1) + { + long end_intersection=clock(); + std::cout << "Filtering time= " << end_filtering-start_filtering << std::endl; + std::cout << "Intersection time= " << end_intersection-start_intersection << std::endl; + long global_end =clock(); + std::cout << "Number of computed intersections = " << counter << std::endl; + std::cout << "Global time= " << global_end - global_start << std::endl; + } + return ret; + } +} + +#endif diff --git a/src/medtool/src/INTERP_KERNEL/InterpolationOptions.cxx b/src/medtool/src/INTERP_KERNEL/InterpolationOptions.cxx new file mode 100644 index 000000000..ae1c14e10 --- /dev/null +++ b/src/medtool/src/INTERP_KERNEL/InterpolationOptions.cxx @@ -0,0 +1,333 @@ +// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 +// 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 "InterpolationOptions.hxx" +#include "InterpKernelGeo2DPrecision.hxx" +#include "InterpKernelException.hxx" + +#include <sstream> + +const double INTERP_KERNEL::InterpolationOptions::DFT_MEDIAN_PLANE=0.5; + +const double INTERP_KERNEL::InterpolationOptions::DFT_SURF3D_ADJ_EPS=1.e-4; + +const double INTERP_KERNEL::InterpolationOptions::DFT_MAX_DIST_3DSURF_INTERSECT=-1.; + +const double INTERP_KERNEL::InterpolationOptions::DFT_MIN_DOT_BTW_3DSURF_INTERSECT=-1.; + +const char INTERP_KERNEL::InterpolationOptions::PRECISION_STR[]="Precision"; + +const char INTERP_KERNEL::InterpolationOptions::ARC_DETECTION_PRECISION_STR[]="ArcDetectionPrecision"; + +const char INTERP_KERNEL::InterpolationOptions::MEDIANE_PLANE_STR[]="MedianPlane"; + +const char INTERP_KERNEL::InterpolationOptions::BOUNDING_BOX_ADJ_STR[]="BoundingBoxAdjustment"; + +const char INTERP_KERNEL::InterpolationOptions::BOUNDING_BOX_ADJ_ABS_STR[]="BoundingBoxAdjustmentAbs"; + +const char INTERP_KERNEL::InterpolationOptions::MAX_DISTANCE_3DSURF_INSECT_STR[]="MaxDistance3DSurfIntersect"; + +const char INTERP_KERNEL::InterpolationOptions::MIN_DOT_BTW_3DSURF_INSECT_STR[]="MinDotBetween3DSurfIntersect"; + +const char INTERP_KERNEL::InterpolationOptions::PRINT_LEV_STR[]="PrintLevel"; + +const char INTERP_KERNEL::InterpolationOptions::DO_ROTATE_STR[]="DoRotate"; + +const char INTERP_KERNEL::InterpolationOptions::ORIENTATION_STR[]="Orientation"; + +const char INTERP_KERNEL::InterpolationOptions::MEASURE_ABS_STR[]="MeasureAbs"; + +const char INTERP_KERNEL::InterpolationOptions::INTERSEC_TYPE_STR[]="IntersectionType"; + +const char INTERP_KERNEL::InterpolationOptions::SPLITTING_POLICY_STR[]="SplittingPolicy"; + +const char INTERP_KERNEL::InterpolationOptions::TRIANGULATION_INTERSECT2D_STR[]="Triangulation"; + +const char INTERP_KERNEL::InterpolationOptions::CONVEX_INTERSECT2D_STR[]="Convex"; + +const char INTERP_KERNEL::InterpolationOptions::GEOMETRIC_INTERSECT2D_STR[]="Geometric2D"; + +const char INTERP_KERNEL::InterpolationOptions::POINTLOCATOR_INTERSECT_STR[]="PointLocator"; + +const char INTERP_KERNEL::InterpolationOptions::BARYCENTRIC_INTERSECT_STR[]="Barycentric"; + +const char INTERP_KERNEL::InterpolationOptions::BARYCENTRICGEO2D_INTERSECT_STR[]="BarycentricGeo2D"; + +const char INTERP_KERNEL::InterpolationOptions::PLANAR_SPLIT_FACE_5_STR[]="PLANAR_FACE_5"; + +const char INTERP_KERNEL::InterpolationOptions::PLANAR_SPLIT_FACE_6_STR[]="PLANAR_FACE_6"; + +const char INTERP_KERNEL::InterpolationOptions::GENERAL_SPLIT_24_STR[]="GENERAL_24"; + +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; + _min_dot_btw_3Dsurf_intersect=DFT_MIN_DOT_BTW_3DSURF_INTERSECT; + _orientation=0; + _measure_abs=true; + _splitting_policy=PLANAR_FACE_5; +} + +double INTERP_KERNEL::InterpolationOptions::getArcDetectionPrecision() const +{ + return INTERP_KERNEL::QUADRATIC_PLANAR::_arc_detection_precision; +} + +void INTERP_KERNEL::InterpolationOptions::setArcDetectionPrecision(double p) +{ + INTERP_KERNEL::QUADRATIC_PLANAR::_arc_detection_precision=p; +} + +std::string INTERP_KERNEL::InterpolationOptions::getIntersectionTypeRepr() const +{ + if(_intersection_type==INTERP_KERNEL::Triangulation) + return std::string(TRIANGULATION_INTERSECT2D_STR); + else if(_intersection_type==INTERP_KERNEL::Convex) + return std::string(CONVEX_INTERSECT2D_STR); + else if(_intersection_type==INTERP_KERNEL::Geometric2D) + return std::string(GEOMETRIC_INTERSECT2D_STR); + else if(_intersection_type==INTERP_KERNEL::PointLocator) + return std::string(POINTLOCATOR_INTERSECT_STR); + else if(_intersection_type==INTERP_KERNEL::Barycentric) + return std::string(BARYCENTRIC_INTERSECT_STR); + else if(_intersection_type==INTERP_KERNEL::BarycentricGeo2D) + return std::string(BARYCENTRICGEO2D_INTERSECT_STR); + else + return std::string("UNKNOWN_INTERSECT_TYPE"); +} + +bool INTERP_KERNEL::InterpolationOptions::setOptionDouble(const std::string& key, double value) +{ + if(key==PRECISION_STR) + { + setPrecision(value); + return true; + } + if(key==ARC_DETECTION_PRECISION_STR) + { + setArcDetectionPrecision(value); + return true; + } + else if(key==MEDIANE_PLANE_STR) + { + setMedianPlane(value); + return true; + } + else if(key==BOUNDING_BOX_ADJ_STR) + { + setBoundingBoxAdjustment(value); + return true; + } + else if(key==BOUNDING_BOX_ADJ_ABS_STR) + { + setBoundingBoxAdjustmentAbs(value); + return true; + } + else if(key==MAX_DISTANCE_3DSURF_INSECT_STR) + { + setMaxDistance3DSurfIntersect(value); + return true; + } + else if(key==MIN_DOT_BTW_3DSURF_INSECT_STR) + { + setMinDotBtwPlane3DSurfIntersect(value); + return true; + } + else + return false; +} + +bool INTERP_KERNEL::InterpolationOptions::setOptionInt(const std::string& key, int value) +{ + if(key==PRINT_LEV_STR) + { + setPrintLevel(value); + return true; + } + else if(key==DO_ROTATE_STR) + { + setDoRotate(value != 0); + return true; + } + else if(key==ORIENTATION_STR) + { + setOrientation(value); + return true; + } + else if(key==MEASURE_ABS_STR) + { + bool valBool=(value!=0); + setMeasureAbsStatus(valBool); + return true; + } + else + return false; +} + +bool INTERP_KERNEL::InterpolationOptions::setOptionString(const std::string& key, const std::string& value) +{ + if(key==INTERSEC_TYPE_STR) + { + if(value==TRIANGULATION_INTERSECT2D_STR) + { + setIntersectionType(INTERP_KERNEL::Triangulation); + return true; + } + else if(value==CONVEX_INTERSECT2D_STR) + { + setIntersectionType(INTERP_KERNEL::Convex); + return true; + } + else if(value==GEOMETRIC_INTERSECT2D_STR) + { + setIntersectionType(INTERP_KERNEL::Geometric2D); + return true; + } + else if(value==POINTLOCATOR_INTERSECT_STR) + { + setIntersectionType(INTERP_KERNEL::PointLocator); + return true; + } + else if(value==BARYCENTRIC_INTERSECT_STR) + { + setIntersectionType(INTERP_KERNEL::Barycentric); + return true; + } + else if(value==BARYCENTRICGEO2D_INTERSECT_STR) + { + setIntersectionType(INTERP_KERNEL::BarycentricGeo2D); + return true; + } + } + else if(key==SPLITTING_POLICY_STR) + { + if(value==PLANAR_SPLIT_FACE_5_STR) + { + setSplittingPolicy(INTERP_KERNEL::PLANAR_FACE_5); + return true; + } + else if(value==PLANAR_SPLIT_FACE_6_STR) + { + setSplittingPolicy(INTERP_KERNEL::PLANAR_FACE_6); + return true; + } + else if(value==GENERAL_SPLIT_24_STR) + { + setSplittingPolicy(INTERP_KERNEL::GENERAL_24); + return true; + } + else if(value==GENERAL_SPLIT_48_STR) + { + setSplittingPolicy(INTERP_KERNEL::GENERAL_48); + return true; + } + else + return false; + } + return false; +} + +std::string INTERP_KERNEL::InterpolationOptions::getSplittingPolicyRepr() const +{ + if(_splitting_policy==INTERP_KERNEL::PLANAR_FACE_5) + return std::string(PLANAR_SPLIT_FACE_5_STR); + else if(_splitting_policy==INTERP_KERNEL::PLANAR_FACE_6) + return std::string(PLANAR_SPLIT_FACE_6_STR); + else if(_splitting_policy==INTERP_KERNEL::GENERAL_24) + return std::string(GENERAL_SPLIT_24_STR); + else if(_splitting_policy==INTERP_KERNEL::GENERAL_48) + return std::string(GENERAL_SPLIT_48_STR); + else + return std::string("UNKNOWN_SPLITTING_POLICY"); +} + +std::string INTERP_KERNEL::InterpolationOptions::filterInterpolationMethod(const std::string& meth) const +{ + return std::string(meth); +} + +bool INTERP_KERNEL::InterpolationOptions::setInterpolationOptions(long print_level, + std::string intersection_type, + double precision, + double median_plane, + bool do_rotate, + double bounding_box_adjustment, + double bounding_box_adjustment_abs, + double max_distance_for_3Dsurf_intersect, + long orientation, + bool measure_abs, + std::string splitting_policy) +{ + _print_level=print_level; + _precision=precision; + _median_plane=median_plane; + _do_rotate=do_rotate; + _bounding_box_adjustment=bounding_box_adjustment; + _bounding_box_adjustment_abs=bounding_box_adjustment_abs; + _max_distance_for_3Dsurf_intersect=max_distance_for_3Dsurf_intersect; + _orientation=orientation; + _measure_abs=measure_abs; + return(setOptionString(INTERSEC_TYPE_STR,intersection_type) && setOptionString(SPLITTING_POLICY_STR,splitting_policy)); +} + +std::string INTERP_KERNEL::InterpolationOptions::printOptions() const +{ + std::ostringstream oss; oss.precision(15); oss << "Interpolation Options ******" << std::endl; + oss << "Print level : " << _print_level << std::endl; + oss << "Intersection type : " << getIntersectionTypeRepr() << std::endl; + oss << "Precision : " << _precision << std::endl; + oss << "Arc Detection Precision : " << getArcDetectionPrecision() << std::endl; + oss << "Median plane : " << _median_plane << std::endl; + oss << "Do Rotate status : " << std::boolalpha << _do_rotate << std::endl; + oss << "Bounding box adj : " << _bounding_box_adjustment << std::endl; + oss << "Bounding box adj abs : " << _bounding_box_adjustment_abs << std::endl; + oss << "Max distance for 3DSurf intersect : " << _max_distance_for_3Dsurf_intersect << std::endl; + oss << "Min dot between plane for 3DSurf intersect : " << _min_dot_btw_3Dsurf_intersect << std::endl; + oss << "Orientation : " << _orientation << std::endl; + oss << "Measure abs : " << _measure_abs << std::endl; + oss << "Splitting policy : " << getSplittingPolicyRepr() << std::endl; + oss << "****************************" << std::endl; + return oss.str(); +} + +void INTERP_KERNEL::InterpolationOptions::CheckAndSplitInterpolationMethod(const std::string& method, std::string& srcMeth, std::string& trgMeth) +{ + const int NB_OF_METH_MANAGED=4; + const char *METH_MANAGED[NB_OF_METH_MANAGED]={"P0P0","P0P1","P1P0","P1P1"}; + bool found=false; + for(int i=0;i<NB_OF_METH_MANAGED && !found;i++) + found=(method==METH_MANAGED[i]); + if(!found) + { + 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=method.substr(0,2); + trgMeth=method.substr(2); +} diff --git a/src/medtool/src/INTERP_KERNEL/InterpolationOptions.hxx b/src/medtool/src/INTERP_KERNEL/InterpolationOptions.hxx new file mode 100644 index 000000000..61fc7141b --- /dev/null +++ b/src/medtool/src/INTERP_KERNEL/InterpolationOptions.hxx @@ -0,0 +1,154 @@ +// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 +// 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 __INTERPOLATIONOPTIONS_HXX__ +#define __INTERPOLATIONOPTIONS_HXX__ + +#include "INTERPKERNELDefines.hxx" +#include "NormalizedUnstructuredMesh.hxx" + +#include <string> + +namespace INTERP_KERNEL +{ + typedef enum { Triangulation, Convex, Geometric2D, PointLocator, Barycentric, BarycentricGeo2D } IntersectionType; + + /*! + * \class InterpolationOptions + * Class defining the options for all interpolation algorithms. + * + * List of options, possible values and default values can be found on this page: + * \ref InterpKerIntersectors + */ + class INTERPKERNEL_EXPORT InterpolationOptions + { + private: + int _print_level ; + IntersectionType _intersection_type; + double _precision; + double _median_plane ; + bool _do_rotate ; + //! this measure is relative to the caracteristic dimension + double _bounding_box_adjustment ; + //! this measure is absolute \b not relative to the cell size + double _bounding_box_adjustment_abs ; + double _max_distance_for_3Dsurf_intersect; + double _min_dot_btw_3Dsurf_intersect; + int _orientation ; + bool _measure_abs; + SplittingPolicy _splitting_policy ; + public: + InterpolationOptions() { init(); } + int getPrintLevel() const { return _print_level; } + void setPrintLevel(int pl) { _print_level=pl; } + + IntersectionType getIntersectionType() const { return _intersection_type; } + void setIntersectionType(IntersectionType it) { _intersection_type=it; } + std::string getIntersectionTypeRepr() const; + + double getPrecision() const { return _precision; } + void setPrecision(double p) { _precision=p; } + + double getArcDetectionPrecision() const; + void setArcDetectionPrecision(double p); + + double getMedianPlane() const { return _median_plane; } + void setMedianPlane(double mp) { _median_plane=mp; } + + bool getDoRotate() const { return _do_rotate; } + void setDoRotate( bool dr) { _do_rotate = dr; } + + double getBoundingBoxAdjustment() const { return _bounding_box_adjustment; } + void setBoundingBoxAdjustment(double bba) { _bounding_box_adjustment=bba; } + + double getBoundingBoxAdjustmentAbs() const { return _bounding_box_adjustment_abs; } + void setBoundingBoxAdjustmentAbs(double bba) { _bounding_box_adjustment_abs=bba; } + + double getMaxDistance3DSurfIntersect() const { return _max_distance_for_3Dsurf_intersect; } + void setMaxDistance3DSurfIntersect(double bba) { _max_distance_for_3Dsurf_intersect=bba; } + + double getMinDotBtwPlane3DSurfIntersect() const { return _min_dot_btw_3Dsurf_intersect; } + void setMinDotBtwPlane3DSurfIntersect(double v) { _min_dot_btw_3Dsurf_intersect=v; } + + int getOrientation() const { return _orientation; } + void setOrientation(int o) { _orientation=o; } + + bool getMeasureAbsStatus() const { return _measure_abs; } + void setMeasureAbsStatus(bool newStatus) { _measure_abs=newStatus; } + + SplittingPolicy getSplittingPolicy() const { return _splitting_policy; } + void setSplittingPolicy(SplittingPolicy sp) { _splitting_policy=sp; } + std::string getSplittingPolicyRepr() const; + + std::string filterInterpolationMethod(const std::string& meth) const; + + void init(); + + bool setInterpolationOptions(long print_level, + std::string intersection_type, + double precision, + double median_plane, + bool do_rotate, + double bounding_box_adjustment, + double bounding_box_adjustment_abs, + double max_distance_for_3Dsurf_intersect, + long orientation, + bool measure_abs, + std::string splitting_policy); + void copyOptions(const InterpolationOptions & other) { *this = other; } + bool setOptionDouble(const std::string& key, double value); + bool setOptionInt(const std::string& key, int value); + bool setOptionString(const std::string& key, const std::string& value); + std::string printOptions() const; + public: + static void CheckAndSplitInterpolationMethod(const std::string& method, std::string& srcMeth, std::string& trgMeth); + private: + static const double DFT_MEDIAN_PLANE; + static const double DFT_SURF3D_ADJ_EPS; + static const double DFT_MAX_DIST_3DSURF_INTERSECT; + static const double DFT_MIN_DOT_BTW_3DSURF_INTERSECT; + public: + static const char PRECISION_STR[]; + static const char ARC_DETECTION_PRECISION_STR[]; + static const char MEDIANE_PLANE_STR[]; + static const char BOUNDING_BOX_ADJ_STR[]; + static const char BOUNDING_BOX_ADJ_ABS_STR[]; + static const char MAX_DISTANCE_3DSURF_INSECT_STR[]; + static const char MIN_DOT_BTW_3DSURF_INSECT_STR[]; + static const char PRINT_LEV_STR[]; + static const char DO_ROTATE_STR[]; + static const char ORIENTATION_STR[]; + static const char MEASURE_ABS_STR[]; + static const char INTERSEC_TYPE_STR[]; + static const char SPLITTING_POLICY_STR[]; + static const char TRIANGULATION_INTERSECT2D_STR[]; + static const char CONVEX_INTERSECT2D_STR[]; + static const char GEOMETRIC_INTERSECT2D_STR[]; + static const char POINTLOCATOR_INTERSECT_STR[]; + static const char BARYCENTRIC_INTERSECT_STR[]; + static const char BARYCENTRICGEO2D_INTERSECT_STR[]; + static const char PLANAR_SPLIT_FACE_5_STR[]; + static const char PLANAR_SPLIT_FACE_6_STR[]; + static const char GENERAL_SPLIT_24_STR[]; + static const char GENERAL_SPLIT_48_STR[]; + }; + +} +#endif diff --git a/src/medtool/src/INTERP_KERNEL/InterpolationPlanar.hxx b/src/medtool/src/INTERP_KERNEL/InterpolationPlanar.hxx new file mode 100755 index 000000000..1505c46e4 --- /dev/null +++ b/src/medtool/src/INTERP_KERNEL/InterpolationPlanar.hxx @@ -0,0 +1,59 @@ +// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 +// 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 __INTERPOLATIONPLANAR_HXX__ +#define __INTERPOLATIONPLANAR_HXX__ + +#include "Interpolation.hxx" +#include "PlanarIntersector.hxx" +#include "NormalizedUnstructuredMesh.hxx" +#include "InterpolationOptions.hxx" + +namespace INTERP_KERNEL +{ + template<class RealPlanar> + class InterpolationPlanar : public Interpolation< InterpolationPlanar<RealPlanar> > + { + private: + double _dim_caracteristic; + public: + InterpolationPlanar(); + InterpolationPlanar(const InterpolationOptions & io); + + // geometric precision, debug print level, coice of the median plane, intersection etc ... + void setOptions(double precision, int printLevel, + IntersectionType intersectionType, int orientation=0); + + // Main function to interpolate triangular and quadratic meshes + template<class MyMeshType, class MatrixType> + int interpolateMeshes(const MyMeshType& meshS, const MyMeshType& meshT, MatrixType& result, const std::string& method); + public: + bool doRotate() const { return asLeafInterpPlanar().doRotate(); } + double medianPlane() const { return asLeafInterpPlanar().medianPlane(); } + template<class MyMeshType, class MyMatrixRow> + void performAdjustmentOfBB(PlanarIntersector<MyMeshType,MyMatrixRow>* intersector, std::vector<double>& bbox) const + { return asLeafInterpPlanar().performAdjustmentOfBB(intersector,bbox); } + protected: + RealPlanar& asLeafInterpPlanar() { return static_cast<RealPlanar&>(*this); } + const RealPlanar& asLeafInterpPlanar() const { return static_cast< const RealPlanar& >(*this); } + }; +} + +#endif diff --git a/src/medtool/src/INTERP_KERNEL/InterpolationPlanar.txx b/src/medtool/src/INTERP_KERNEL/InterpolationPlanar.txx new file mode 100644 index 000000000..d7a1fea20 --- /dev/null +++ b/src/medtool/src/INTERP_KERNEL/InterpolationPlanar.txx @@ -0,0 +1,417 @@ +// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 +// 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 __INTERPOLATIONPLANAR_TXX__ +#define __INTERPOLATIONPLANAR_TXX__ + +#include "InterpolationPlanar.hxx" +#include "Interpolation.txx" +#include "InterpolationOptions.hxx" +#include "PlanarIntersector.hxx" +#include "PlanarIntersector.txx" +#include "TriangulationIntersector.hxx" +#include "TriangulationIntersector.txx" +#include "ConvexIntersector.hxx" +#include "ConvexIntersector.txx" +#include "Geometric2DIntersector.hxx" +#include "Geometric2DIntersector.txx" +#include "PointLocator2DIntersector.hxx" +#include "PointLocator2DIntersector.txx" +#include "PlanarIntersectorP0P1PL.hxx" +#include "PlanarIntersectorP0P1PL.txx" +#include "PlanarIntersectorP1P0PL.hxx" +#include "PlanarIntersectorP1P0PL.txx" +#include "PlanarIntersectorP1P1PL.hxx" +#include "PlanarIntersectorP1P1PL.txx" +#include "VectorUtils.hxx" +#include "BBTree.txx" + +#include <limits> +#include <time.h> + +namespace INTERP_KERNEL +{ + /** + * \defgroup interpolationPlanar InterpolationPlanar + * + * \class InterpolationPlanar + * \brief Class used to compute the coefficients of the interpolation matrix between + * two local meshes in two dimensions. Meshes can contain mixed triangular and quadrangular elements. + */ + template<class RealPlanar> + InterpolationPlanar<RealPlanar>::InterpolationPlanar():_dim_caracteristic(1) + + { + } + + template<class RealPlanar> + InterpolationPlanar<RealPlanar>::InterpolationPlanar(const InterpolationOptions& io):Interpolation< InterpolationPlanar<RealPlanar> >(io),_dim_caracteristic(1) + + { + } + + /** + * \brief Function used to set the options for the intersection calculation + * \details The following options can be modified: + * -# Intersection_type: the type of algorithm to be used in the computation of the cell-cell intersections. + * - Values: Triangle, Convex. + * - Default: Triangle. + * -# Precision: Level of precision of the computations is precision times the characteristic size of the mesh. + * - Values: positive real number. + * - Default: 1.0E-12. + * -# PrintLevel: Level of verboseness during the computations. + * - Values: interger between 0 and 3. + * - Default: 0. + */ + template<class RealPlanar> + void InterpolationPlanar<RealPlanar>::setOptions(double precision, int printLevel, IntersectionType intersectionType, int orientation) + { + InterpolationOptions::setPrecision(precision); + InterpolationOptions::setPrintLevel(printLevel); + InterpolationOptions::setIntersectionType(intersectionType); + InterpolationOptions::setOrientation(orientation); + } + + + /** \brief Main function to interpolate triangular or quadrangular meshes. + \details The algorithm proceeds in two steps: first a filtering process reduces the number of pairs of elements for which the + * calculation must be carried out by eliminating pairs that do not intersect based on their bounding boxes. Then, the + * volume of intersection is calculated by an object of type IntersectorPlanar for the remaining pairs, and entered into the + * intersection matrix. + * + * The matrix is partially sparse : it is a vector of maps of integer - double pairs. + * The length of the vector is equal to the number of target elements - for each target element there is a map, regardless + * of whether the element intersects any source elements or not. But in the maps there are only entries for those source elements + * which have a non-zero intersection volume with the target element. The vector has indices running from + * 0 to (#target elements - 1), meaning that the map for target element i is stored at index i - 1. In the maps, however, + * the indexing is more natural : the intersection volume of the target element i with source element j is found at matrix[i-1][j]. + * + + * @param myMeshS Planar source mesh + * @Param myMeshT Planar target mesh + * @return vector containing for each element i of the source mesh, a map giving for each element j + * of the target mesh which i intersects, the area of the intersection + * + */ + template<class RealPlanar> + template<class MyMeshType, class MatrixType> + int InterpolationPlanar<RealPlanar>::interpolateMeshes(const MyMeshType& myMeshS, const MyMeshType& myMeshT, MatrixType& result, const std::string& method) + { + static const int SPACEDIM=MyMeshType::MY_SPACEDIM; + typedef typename MyMeshType::MyConnType ConnType; + static const NumberingPolicy numPol=MyMeshType::My_numPol; + + long global_start =clock(); + int counter=0; + /***********************************************************/ + /* Check both meshes are made of triangles and quadrangles */ + /***********************************************************/ + + long nbMailleS=myMeshS.getNumberOfElements(); + long nbMailleT=myMeshT.getNumberOfElements(); + + /**************************************************/ + /* Search the characteristic size of the meshes */ + /**************************************************/ + + double BoxS[2*SPACEDIM]; myMeshS.getBoundingBox(BoxS); + double BoxT[2*SPACEDIM]; myMeshT.getBoundingBox(BoxT); + double diagonalS,dimCaracteristicS=std::numeric_limits<double>::max(); + if(nbMailleS!=0) + { + diagonalS=getDistanceBtw2Pts<SPACEDIM>(BoxS+SPACEDIM,BoxS); + dimCaracteristicS=diagonalS/nbMailleS; + } + double diagonalT,dimCaracteristicT=std::numeric_limits<double>::max(); + if(nbMailleT!=0) + { + diagonalT=getDistanceBtw2Pts<SPACEDIM>(BoxT+SPACEDIM,BoxT); + dimCaracteristicT=diagonalT/nbMailleT; + } + + _dim_caracteristic=std::min(dimCaracteristicS, dimCaracteristicT); + if (InterpolationOptions::getPrintLevel()>=1) + { + std::cout << " - Characteristic size of the source mesh : " << dimCaracteristicS << std::endl; + std::cout << " - Characteristic size of the target mesh: " << dimCaracteristicT << std::endl; + std::cout << "InterpolationPlanar::computation of the intersections" << std::endl; + } + + PlanarIntersector<MyMeshType,MatrixType>* intersector=0; + std::string meth = InterpolationOptions::filterInterpolationMethod(method); + if(meth=="P0P0") + { + switch (InterpolationOptions::getIntersectionType()) + { + case Triangulation: + intersector=new TriangulationIntersector<MyMeshType,MatrixType,PlanarIntersectorP0P0>(myMeshT,myMeshS,_dim_caracteristic, + InterpolationOptions::getPrecision(), + InterpolationOptions::getMaxDistance3DSurfIntersect(), + InterpolationOptions::getMinDotBtwPlane3DSurfIntersect(), + InterpolationOptions::getMedianPlane(), + InterpolationOptions::getOrientation(), + InterpolationOptions::getPrintLevel()); + break; + case Convex: + intersector=new ConvexIntersector<MyMeshType,MatrixType,PlanarIntersectorP0P0>(myMeshT,myMeshS,_dim_caracteristic, + InterpolationOptions::getPrecision(), + InterpolationOptions::getMaxDistance3DSurfIntersect(), + InterpolationOptions::getMinDotBtwPlane3DSurfIntersect(), + InterpolationOptions::getMedianPlane(), + InterpolationOptions::getDoRotate(), + InterpolationOptions::getOrientation(), + InterpolationOptions::getPrintLevel()); + break; + case Geometric2D: + intersector=new Geometric2DIntersector<MyMeshType,MatrixType,PlanarIntersectorP0P0>(myMeshT, myMeshS, _dim_caracteristic, + InterpolationOptions::getMaxDistance3DSurfIntersect(), + InterpolationOptions::getMinDotBtwPlane3DSurfIntersect(), + InterpolationOptions::getMedianPlane(), + InterpolationOptions::getPrecision(), + InterpolationOptions::getOrientation()); + break; + case PointLocator: + intersector=new PointLocator2DIntersector<MyMeshType,MatrixType,PlanarIntersectorP0P0>(myMeshT, myMeshS, _dim_caracteristic, + InterpolationOptions::getMaxDistance3DSurfIntersect(), + InterpolationOptions::getMinDotBtwPlane3DSurfIntersect(), + InterpolationOptions::getMedianPlane(), + InterpolationOptions::getPrecision(), + InterpolationOptions::getOrientation()); + break; + default: + throw INTERP_KERNEL::Exception("For P0P0 planar interpolation possibities are : Triangulation, Convex, Geometric2D, PointLocator !"); + } + } + else if(meth=="P0P1") + { + switch (InterpolationOptions::getIntersectionType()) + { + case Triangulation: + intersector=new TriangulationIntersector<MyMeshType,MatrixType,PlanarIntersectorP0P1>(myMeshT,myMeshS,_dim_caracteristic, + InterpolationOptions::getPrecision(), + InterpolationOptions::getMaxDistance3DSurfIntersect(), + InterpolationOptions::getMinDotBtwPlane3DSurfIntersect(), + InterpolationOptions::getMedianPlane(), + InterpolationOptions::getOrientation(), + InterpolationOptions::getPrintLevel()); + break; + case Convex: + intersector=new ConvexIntersector<MyMeshType,MatrixType,PlanarIntersectorP0P1>(myMeshT,myMeshS,_dim_caracteristic, + InterpolationOptions::getPrecision(), + InterpolationOptions::getMaxDistance3DSurfIntersect(), + InterpolationOptions::getMinDotBtwPlane3DSurfIntersect(), + InterpolationOptions::getMedianPlane(), + InterpolationOptions::getDoRotate(), + InterpolationOptions::getOrientation(), + InterpolationOptions::getPrintLevel()); + break; + case Geometric2D: + intersector=new Geometric2DIntersector<MyMeshType,MatrixType,PlanarIntersectorP0P1>(myMeshT, myMeshS, _dim_caracteristic, + InterpolationOptions::getMaxDistance3DSurfIntersect(), + InterpolationOptions::getMinDotBtwPlane3DSurfIntersect(), + InterpolationOptions::getMedianPlane(), + InterpolationOptions::getPrecision(), + InterpolationOptions::getOrientation()); + break; + case PointLocator: + intersector=new PlanarIntersectorP0P1PL<MyMeshType,MatrixType>(myMeshT, myMeshS, _dim_caracteristic, + InterpolationOptions::getMaxDistance3DSurfIntersect(), + InterpolationOptions::getMinDotBtwPlane3DSurfIntersect(), + InterpolationOptions::getMedianPlane(), + InterpolationOptions::getPrecision(), + InterpolationOptions::getOrientation()); + break; + case Barycentric: + intersector=new TriangulationIntersector<MyMeshType,MatrixType,PlanarIntersectorP0P1Bary>(myMeshT,myMeshS,_dim_caracteristic, + InterpolationOptions::getPrecision(), + InterpolationOptions::getMaxDistance3DSurfIntersect(), + InterpolationOptions::getMinDotBtwPlane3DSurfIntersect(), + InterpolationOptions::getMedianPlane(), + InterpolationOptions::getOrientation(), + InterpolationOptions::getPrintLevel()); + break; + case BarycentricGeo2D: + intersector=new Geometric2DIntersector<MyMeshType,MatrixType,PlanarIntersectorP0P1Bary>(myMeshT, myMeshS, _dim_caracteristic, + InterpolationOptions::getMaxDistance3DSurfIntersect(), + InterpolationOptions::getMinDotBtwPlane3DSurfIntersect(), + InterpolationOptions::getMedianPlane(), + InterpolationOptions::getPrecision(), + InterpolationOptions::getOrientation()); + break; + default: + throw INTERP_KERNEL::Exception("For P0P1 planar interpolation possibities are : Triangulation, Convex, Geometric2D, PointLocator, Barycentric, BarycentricGeo2D !"); + } + } + else if(meth=="P1P0") + { + switch (InterpolationOptions::getIntersectionType()) + { + case Triangulation: + intersector=new TriangulationIntersector<MyMeshType,MatrixType,PlanarIntersectorP1P0>(myMeshT,myMeshS,_dim_caracteristic, + InterpolationOptions::getPrecision(), + InterpolationOptions::getMaxDistance3DSurfIntersect(), + InterpolationOptions::getMinDotBtwPlane3DSurfIntersect(), + InterpolationOptions::getMedianPlane(), + InterpolationOptions::getOrientation(), + InterpolationOptions::getPrintLevel()); + break; + case Convex: + intersector=new ConvexIntersector<MyMeshType,MatrixType,PlanarIntersectorP1P0>(myMeshT,myMeshS,_dim_caracteristic, + InterpolationOptions::getPrecision(), + InterpolationOptions::getMaxDistance3DSurfIntersect(), + InterpolationOptions::getMinDotBtwPlane3DSurfIntersect(), + InterpolationOptions::getMedianPlane(), + InterpolationOptions::getDoRotate(), + InterpolationOptions::getOrientation(), + InterpolationOptions::getPrintLevel()); + break; + case Geometric2D: + intersector=new Geometric2DIntersector<MyMeshType,MatrixType,PlanarIntersectorP1P0>(myMeshT, myMeshS, _dim_caracteristic, + InterpolationOptions::getMaxDistance3DSurfIntersect(), + InterpolationOptions::getMinDotBtwPlane3DSurfIntersect(), + InterpolationOptions::getMedianPlane(), + InterpolationOptions::getPrecision(), + InterpolationOptions::getOrientation()); + break; + case PointLocator: + intersector=new PlanarIntersectorP1P0PL<MyMeshType,MatrixType>(myMeshT, myMeshS, _dim_caracteristic, + InterpolationOptions::getMaxDistance3DSurfIntersect(), + InterpolationOptions::getMinDotBtwPlane3DSurfIntersect(), + InterpolationOptions::getMedianPlane(), + InterpolationOptions::getPrecision(), + InterpolationOptions::getOrientation()); + break; + case Barycentric: + intersector=new TriangulationIntersector<MyMeshType,MatrixType,PlanarIntersectorP1P0Bary>(myMeshT,myMeshS,_dim_caracteristic, + InterpolationOptions::getPrecision(), + InterpolationOptions::getMaxDistance3DSurfIntersect(), + InterpolationOptions::getMinDotBtwPlane3DSurfIntersect(), + InterpolationOptions::getMedianPlane(), + InterpolationOptions::getOrientation(), + InterpolationOptions::getPrintLevel()); + break; + case BarycentricGeo2D: + intersector=new Geometric2DIntersector<MyMeshType,MatrixType,PlanarIntersectorP1P0Bary>(myMeshT, myMeshS, _dim_caracteristic, + InterpolationOptions::getMaxDistance3DSurfIntersect(), + InterpolationOptions::getMinDotBtwPlane3DSurfIntersect(), + InterpolationOptions::getMedianPlane(), + InterpolationOptions::getPrecision(), + InterpolationOptions::getOrientation()); + break; + } + } + else if(meth=="P1P1") + { + switch (InterpolationOptions::getIntersectionType()) + { + case Triangulation: + intersector=new TriangulationIntersector<MyMeshType,MatrixType,PlanarIntersectorP1P1>(myMeshT,myMeshS,_dim_caracteristic, + InterpolationOptions::getPrecision(), + InterpolationOptions::getMaxDistance3DSurfIntersect(), + InterpolationOptions::getMinDotBtwPlane3DSurfIntersect(), + InterpolationOptions::getMedianPlane(), + InterpolationOptions::getOrientation(), + InterpolationOptions::getPrintLevel()); + break; + case Convex: + intersector=new ConvexIntersector<MyMeshType,MatrixType,PlanarIntersectorP1P1>(myMeshT,myMeshS,_dim_caracteristic, + InterpolationOptions::getPrecision(), + InterpolationOptions::getMaxDistance3DSurfIntersect(), + InterpolationOptions::getMinDotBtwPlane3DSurfIntersect(), + InterpolationOptions::getMedianPlane(), + InterpolationOptions::getDoRotate(), + InterpolationOptions::getOrientation(), + InterpolationOptions::getPrintLevel()); + break; + case Geometric2D: + intersector=new Geometric2DIntersector<MyMeshType,MatrixType,PlanarIntersectorP1P1>(myMeshT, myMeshS, _dim_caracteristic, + InterpolationOptions::getMaxDistance3DSurfIntersect(), + InterpolationOptions::getMinDotBtwPlane3DSurfIntersect(), + InterpolationOptions::getMedianPlane(), + InterpolationOptions::getPrecision(), + InterpolationOptions::getOrientation()); + break; + case PointLocator: + intersector=new PlanarIntersectorP1P1PL<MyMeshType,MatrixType>(myMeshT, myMeshS, _dim_caracteristic, + InterpolationOptions::getMaxDistance3DSurfIntersect(), + InterpolationOptions::getMinDotBtwPlane3DSurfIntersect(), + InterpolationOptions::getMedianPlane(), + InterpolationOptions::getPrecision(), + InterpolationOptions::getOrientation()); + break; + default: + throw INTERP_KERNEL::Exception("For P1P1 planar interpolation possibities are : Triangulation, Convex, Geometric2D, PointLocator !"); + } + } + else + throw INTERP_KERNEL::Exception("Invalid method specified or intersection type ! Must be in : \"P0P0\" \"P0P1\" \"P1P0\" or \"P1P1\""); + /****************************************************************/ + /* Create a search tree based on the bounding boxes */ + /* Instanciate the intersector and initialise the result vector */ + /****************************************************************/ + + long start_filtering=clock(); + + std::vector<double> bbox; + intersector->createBoundingBoxes(myMeshS,bbox); // create the bounding boxes + performAdjustmentOfBB(intersector,bbox); + const double *bboxPtr=0; + if(nbMailleS>0) + bboxPtr=&bbox[0]; + BBTree<SPACEDIM,ConnType> my_tree(bboxPtr, 0, 0,nbMailleS);//creating the search structure + + long end_filtering=clock(); + + result.resize(intersector->getNumberOfRowsOfResMatrix());//on initialise. + + /****************************************************/ + /* Loop on the target cells - core of the algorithm */ + /****************************************************/ + long start_intersection=clock(); + long nbelem_type=myMeshT.getNumberOfElements(); + const ConnType *connIndxT=myMeshT.getConnectivityIndexPtr(); + for(int iT=0; iT<nbelem_type; iT++) + { + int nb_nodesT=connIndxT[iT+1]-connIndxT[iT]; + std::vector<int> intersecting_elems; + double bb[2*SPACEDIM]; + intersector->getElemBB(bb,myMeshT,OTT<ConnType,numPol>::indFC(iT),nb_nodesT); + my_tree.getIntersectingElems(bb, intersecting_elems); + intersector->intersectCells(iT,intersecting_elems,result); + counter+=intersecting_elems.size(); + intersecting_elems.clear(); + } + int ret=intersector->getNumberOfColsOfResMatrix(); + delete intersector; + + if (InterpolationOptions::getPrintLevel() >=1) + { + long end_intersection=clock(); + std::cout << "Filtering time= " << end_filtering-start_filtering << std::endl; + std::cout << "Intersection time= " << end_intersection-start_intersection << std::endl; + long global_end =clock(); + std::cout << "Number of computed intersections = " << counter << std::endl; + std::cout << "Global time= " << global_end - global_start << std::endl; + } + return ret; + } +} + +#endif diff --git a/src/medtool/src/INTERP_KERNEL/InterpolationUtils.hxx b/src/medtool/src/INTERP_KERNEL/InterpolationUtils.hxx new file mode 100644 index 000000000..dd3ffef94 --- /dev/null +++ b/src/medtool/src/INTERP_KERNEL/InterpolationUtils.hxx @@ -0,0 +1,1110 @@ +// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 +// 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 __INTERPOLATIONUTILS_HXX__ +#define __INTERPOLATIONUTILS_HXX__ + +#include "INTERPKERNELDefines.hxx" +#include "InterpKernelException.hxx" + +#include "NormalizedUnstructuredMesh.hxx" + +#include <deque> +#include <map> +#include <cmath> +#include <string> +#include <vector> +#include <algorithm> +#include <iostream> +#include <limits> +#include <functional> + +namespace INTERP_KERNEL +{ + template<class ConnType, NumberingPolicy numPol> + class OTT//OffsetToolTrait + { + }; + + template<class ConnType> + class OTT<ConnType,ALL_C_MODE> + { + public: + static ConnType indFC(ConnType i) { return i; } + static ConnType ind2C(ConnType i) { return i; } + static ConnType conn2C(ConnType i) { return i; } + static ConnType coo2C(ConnType i) { return i; } + }; + + template<class ConnType> + class OTT<ConnType,ALL_FORTRAN_MODE> + { + public: + static ConnType indFC(ConnType i) { return i+1; } + static ConnType ind2C(ConnType i) { return i-1; } + static ConnType conn2C(ConnType i) { return i-1; } + static ConnType coo2C(ConnType i) { return i-1; } + }; + + /*_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ */ + /* calcul la surface d'un triangle */ + /*_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ */ + + inline double Surf_Tri(const double* P_1,const double* P_2,const double* P_3) + { + double A=(P_3[1]-P_1[1])*(P_2[0]-P_1[0])-(P_2[1]-P_1[1])*(P_3[0]-P_1[0]); + double Surface = 0.5*fabs(A); + return Surface; + } + + /*_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ */ + /* fonction qui calcul le determinant */ + /* de deux vecteur(cf doc CGAL). */ + /*_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _*/ + + //fonction qui calcul le determinant des vecteurs: P3P1 et P3P2 + //(cf doc CGAL). + + inline double mon_determinant(const double* P_1, + const double* P_2, + const double* P_3) + { + double mon_det=(P_1[0]-P_3[0])*(P_2[1]-P_3[1])-(P_2[0]-P_3[0])*(P_1[1]-P_3[1]); + return mon_det; + } + + /*_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _*/ + //calcul la norme du vecteur P1P2 + + inline double norme_vecteur(const double* P_1,const double* P_2) + { + double X=P_1[0]-P_2[0]; + double Y=P_1[1]-P_2[1]; + double norme=sqrt(X*X+Y*Y); + return norme; + } + + /*_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ */ + /* calcul le cos et le sin de l'angle P1P2,P1P3 */ + /*_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ */ + + inline std::vector<double> calcul_cos_et_sin(const double* P_1, + const double* P_2, + const double* P_3) + { + + std::vector<double> Vect; + double P1_P2=norme_vecteur(P_1,P_2); + double P2_P3=norme_vecteur(P_2,P_3); + double P3_P1=norme_vecteur(P_3,P_1); + + double N=P1_P2*P1_P2+P3_P1*P3_P1-P2_P3*P2_P3; + double D=2.0*P1_P2*P3_P1; + double COS=N/D; + if (COS>1.0) COS=1.0; + if (COS<-1.0) COS=-1.0; + Vect.push_back(COS); + double V=mon_determinant(P_2,P_3,P_1); + double D_1=P1_P2*P3_P1; + double SIN=V/D_1; + if (SIN>1.0) SIN=1.0; + if (SIN<-1.0) SIN=-1.0; + Vect.push_back(SIN); + + return Vect; + + } + + /*! + * This method builds a quadrangle built with the first point of 'triIn' the barycenter of two edges starting or ending with + * the first point of 'triIn' and the barycenter of 'triIn'. + * + * @param triIn is a 6 doubles array in full interlace mode, that represents a triangle. + * @param quadOut is a 8 doubles array filled after the following call. + */ + template<int SPACEDIM> + inline void fillDualCellOfTri(const double *triIn, double *quadOut) + { + //1st point + std::copy(triIn,triIn+SPACEDIM,quadOut); + double tmp[SPACEDIM]; + std::transform(triIn,triIn+SPACEDIM,triIn+SPACEDIM,tmp,std::plus<double>()); + //2nd point + std::transform(tmp,tmp+SPACEDIM,quadOut+SPACEDIM,std::bind2nd(std::multiplies<double>(),0.5)); + std::transform(tmp,tmp+SPACEDIM,triIn+2*SPACEDIM,tmp,std::plus<double>()); + //3rd point + std::transform(tmp,tmp+SPACEDIM,quadOut+2*SPACEDIM,std::bind2nd(std::multiplies<double>(),1/3.)); + //4th point + std::transform(triIn,triIn+SPACEDIM,triIn+2*SPACEDIM,tmp,std::plus<double>()); + std::transform(tmp,tmp+SPACEDIM,quadOut+3*SPACEDIM,std::bind2nd(std::multiplies<double>(),0.5)); + } + + /*! + * This method builds a potentially non-convex polygon cell built with the first point of 'triIn' the barycenter of two edges starting or ending with + * the first point of 'triIn' and the barycenter of 'triIn'. + * + * @param triIn is a 6 doubles array in full interlace mode, that represents a triangle. + * @param quadOut is a 8 doubles array filled after the following call. + */ + template<int SPACEDIM> + inline void fillDualCellOfPolyg(const double *polygIn, int nPtsPolygonIn, double *polygOut) + { + //1st point + std::copy(polygIn,polygIn+SPACEDIM,polygOut); + std::transform(polygIn,polygIn+SPACEDIM,polygIn+SPACEDIM,polygOut+SPACEDIM,std::plus<double>()); + //2nd point + std::transform(polygOut+SPACEDIM,polygOut+2*SPACEDIM,polygOut+SPACEDIM,std::bind2nd(std::multiplies<double>(),0.5)); + double tmp[SPACEDIM]; + // + for(int i=0;i<nPtsPolygonIn-2;i++) + { + std::transform(polygIn,polygIn+SPACEDIM,polygIn+(i+2)*SPACEDIM,tmp,std::plus<double>()); + std::transform(tmp,tmp+SPACEDIM,polygOut+(2*i+3)*SPACEDIM,std::bind2nd(std::multiplies<double>(),0.5)); + std::transform(polygIn+(i+1)*SPACEDIM,polygIn+(i+2)*SPACEDIM,tmp,tmp,std::plus<double>()); + std::transform(tmp,tmp+SPACEDIM,polygOut+(2*i+2)*SPACEDIM,std::bind2nd(std::multiplies<double>(),1./3.)); + } + } + + /*_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ */ + /* calcul les coordonnees du barycentre d'un polygone */ + /* le vecteur en entree est constitue des coordonnees */ + /* des sommets du polygone */ + /*_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ */ + + inline std::vector<double> bary_poly(const std::vector<double>& V) + { + std::vector<double> Bary; + long taille=V.size(); + double x=0; + double y=0; + + for(long i=0;i<taille/2;i++) + { + x=x+V[2*i]; + y=y+V[2*i+1]; + } + double A=2*x/((double)taille); + double B=2*y/((double)taille); + Bary.push_back(A);//taille vecteur=2*nb de points. + Bary.push_back(B); + + + return Bary; + } + + /*! + * Given 6 coeffs of a Tria6 returns the corresponding value of a given pos + */ + inline double computeTria6RefBase(const double *coeffs, const double *pos) + { + return coeffs[0]+coeffs[1]*pos[0]+coeffs[2]*pos[1]+coeffs[3]*pos[0]*pos[0]+coeffs[4]*pos[0]*pos[1]+coeffs[5]*pos[1]*pos[1]; + } + + /*! + * Given xsi,eta in refCoo (length==2) return 6 coeffs in weightedPos. + */ + inline void computeWeightedCoeffsInTria6FromRefBase(const double *refCoo, double *weightedPos) + { + weightedPos[0]=(1.-refCoo[0]-refCoo[1])*(1.-2*refCoo[0]-2.*refCoo[1]); + weightedPos[1]=refCoo[0]*(2.*refCoo[0]-1.); + weightedPos[2]=refCoo[1]*(2.*refCoo[1]-1.); + weightedPos[3]=4.*refCoo[0]*(1.-refCoo[0]-refCoo[1]); + weightedPos[4]=4.*refCoo[0]*refCoo[1]; + weightedPos[5]=4.*refCoo[1]*(1.-refCoo[0]-refCoo[1]); + } + + /*! + * Given 10 coeffs of a Tetra10 returns the corresponding value of a given pos + */ + inline double computeTetra10RefBase(const double *coeffs, const double *pos) + { + return coeffs[0]+coeffs[1]*pos[0]+coeffs[2]*pos[1]+coeffs[3]*pos[2]+ + coeffs[4]*pos[0]*pos[0]+coeffs[5]*pos[0]*pos[1]+coeffs[6]*pos[0]*pos[2]+ + coeffs[7]*pos[1]*pos[1]+coeffs[8]*pos[1]*pos[2]+coeffs[9]*pos[2]*pos[2]; + } + + /*! + * Given xsi,eta,z in refCoo (length==3) return 10 coeffs in weightedPos. + */ + inline void computeWeightedCoeffsInTetra10FromRefBase(const double *refCoo, double *weightedPos) + { + //http://www.cadfamily.com/download/CAE/ABAQUS/The%20Finite%20Element%20Method%20-%20A%20practical%20course%20abaqus.pdf page 217 + //L1=1-refCoo[0]-refCoo[1]-refCoo[2] + //L2=refCoo[0] L3=refCoo[1] L4=refCoo[2] + weightedPos[0]=(-2.*(refCoo[0]+refCoo[1]+refCoo[2])+1)*(1-refCoo[0]-refCoo[1]-refCoo[2]);//(2*L1-1)*L1 + weightedPos[1]=(2.*refCoo[0]-1.)*refCoo[0];//(2*L2-1)*L2 + weightedPos[2]=(2.*refCoo[1]-1.)*refCoo[1];//(2*L3-1)*L3 + weightedPos[3]=(2.*refCoo[2]-1.)*refCoo[2];//(2*L4-1)*L4 + weightedPos[4]=4.*(1-refCoo[0]-refCoo[1]-refCoo[2])*refCoo[0];//4*L1*L2 + weightedPos[5]=4.*refCoo[0]*refCoo[1];//4*L2*L3 + weightedPos[6]=4.*(1-refCoo[0]-refCoo[1]-refCoo[2])*refCoo[1];//4*L1*L3 + weightedPos[7]=4.*(1-refCoo[0]-refCoo[1]-refCoo[2])*refCoo[2];//4*L1*L4 + weightedPos[8]=4.*refCoo[0]*refCoo[2];//4*L2*L4 + weightedPos[9]=4.*refCoo[1]*refCoo[2];//4*L3*L4 + } + + /*! + * \brief Solve system equation in matrix form using Gaussian elimination algorithm + * \param M - N x N+1 matrix + * \param sol - vector of N solutions + * \retval bool - true if succeeded + */ + template<unsigned nbRow> + bool solveSystemOfEquations(double M[nbRow][nbRow+1], double* sol) + { + const int nbCol=nbRow+1; + + // make upper triangular matrix (forward elimination) + + int iR[nbRow];// = { 0, 1, 2 }; + for ( int i = 0; i < (int) nbRow; ++i ) + iR[i] = i; + for ( int i = 0; i < (int)(nbRow-1); ++i ) // nullify nbRow-1 rows + { + // swap rows to have max value of i-th column in i-th row + double max = std::fabs( M[ iR[i] ][i] ); + for ( int r = i+1; r < (int)nbRow; ++r ) + { + double m = std::fabs( M[ iR[r] ][i] ); + if ( m > max ) + { + max = m; + std::swap( iR[r], iR[i] ); + } + } + if ( max < std::numeric_limits<double>::min() ) + { + //sol[0]=1; sol[1]=sol[2]=sol[3]=0; + return false; // no solution + } + // make 0 below M[i][i] (actually we do not modify i-th column) + double* tUpRow = M[ iR[i] ]; + for ( int r = i+1; r < (int)nbRow; ++r ) + { + double* mRow = M[ iR[r] ]; + double coef = mRow[ i ] / tUpRow[ i ]; + for ( int c = i+1; c < nbCol; ++c ) + mRow[ c ] -= tUpRow[ c ] * coef; + } + } + double* mRow = M[ iR[nbRow-1] ]; + if ( std::fabs( mRow[ nbRow-1 ] ) < std::numeric_limits<double>::min() ) + { + //sol[0]=1; sol[1]=sol[2]=sol[3]=0; + return false; // no solution + } + mRow[ nbRow ] /= mRow[ nbRow-1 ]; + + // calculate solution (back substitution) + + sol[ nbRow-1 ] = mRow[ nbRow ]; + + for ( int i = nbRow-2; i+1; --i ) + { + mRow = M[ iR[i] ]; + sol[ i ] = mRow[ nbRow ]; + for ( int j = nbRow-1; j > i; --j ) + sol[ i ] -= sol[j]*mRow[ j ]; + sol[ i ] /= mRow[ i ]; + } + + return true; + } + + + /*! + * \brief Solve system equation in matrix form using Gaussian elimination algorithm + * \param M - N x N+NB_OF_VARS matrix + * \param sol - vector of N solutions + * \retval bool - true if succeeded + */ + template<unsigned SZ, unsigned NB_OF_RES> + bool solveSystemOfEquations2(const double *matrix, double *solutions, double eps) + { + unsigned k,j; + int nr,n,m,np; + double s,g; + int mb; + // + double B[SZ*(SZ+NB_OF_RES)]; + std::copy(matrix,matrix+SZ*(SZ+NB_OF_RES),B); + // + nr=SZ+NB_OF_RES; + for(k=0;k<SZ;k++) + { + np=nr*k+k; + if(fabs(B[np])<eps) + { + n=k; + do + { + n++; + if(fabs(B[nr*k+n])>eps) + {/* Rows permutation */ + for(m=0;m<nr;m++) + std::swap(B[nr*k+m],B[nr*n+m]); + } + } + while (n<(int)SZ); + } + s=B[np];//s is the Pivot + std::transform(B+k*nr,B+(k+1)*nr,B+k*nr,std::bind2nd(std::divides<double>(),s)); + for(j=0;j<SZ;j++) + { + if(j!=k) + { + g=B[j*nr+k]; + for(mb=k;mb<nr;mb++) + B[j*nr+mb]-=B[k*nr+mb]*g; + } + } + } + for(j=0;j<NB_OF_RES;j++) + for(k=0;k<SZ;k++) + solutions[j*SZ+k]=B[nr*k+SZ+j]; + // + return true; + } + + /*_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _*/ + /* Calculate barycentric coordinates of a 2D point p */ + /* with respect to the triangle verices. */ + /* triaCoords are in full interlace */ + /*_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _*/ + + template<int SPACEDIM> + inline void barycentric_coords(const double* triaCoords, const double* p, double* bc) + { + // matrix 2x2 + double + T11 = triaCoords[0]-triaCoords[2*SPACEDIM], T12 = triaCoords[SPACEDIM]-triaCoords[2*SPACEDIM], + T21 = triaCoords[1]-triaCoords[2*SPACEDIM+1], T22 = triaCoords[SPACEDIM+1]-triaCoords[2*SPACEDIM+1]; + // matrix determinant + double Tdet = T11*T22 - T12*T21; + if ( fabs( Tdet ) < std::numeric_limits<double>::min() ) { + bc[0]=1; bc[1]=0; bc[2]=0; + return; + } + // matrix inverse + double t11 = T22, t12 = -T12, t21 = -T21, t22 = T11; + // vector + double r11 = p[0]-triaCoords[2*SPACEDIM], r12 = p[1]-triaCoords[2*SPACEDIM+1]; + // barycentric coordinates: mutiply matrix by vector + bc[0] = (t11 * r11 + t12 * r12)/Tdet; + bc[1] = (t21 * r11 + t22 * r12)/Tdet; + bc[2] = 1. - bc[0] - bc[1]; + } + + /*! + * Calculate barycentric coordinates of a point p with respect to triangle or tetra verices. + * This method makes 2 assumptions : + * - this is a simplex + * - spacedim == meshdim. For TRI3 and TRI6 spaceDim is expected to be equal to 2 and for TETRA4 spaceDim is expected to be equal to 3. + * If not the case (3D surf for example) a previous projection should be done before. + */ + inline void barycentric_coords(const std::vector<const double*>& n, const double *p, double *bc) + { + enum { _X, _Y, _Z }; + switch(n.size()) + { + case 2: + {// SEG 2 + double delta=n[0][0]-n[1][0]; + bc[0]=fabs((*p-n[1][0])/delta); + bc[1]=fabs((*p-n[0][0])/delta); + break; + } + case 3: + { // TRIA3 + // matrix 2x2 + double + T11 = n[0][_X]-n[2][_X], T12 = n[1][_X]-n[2][_X], + T21 = n[0][_Y]-n[2][_Y], T22 = n[1][_Y]-n[2][_Y]; + // matrix determinant + double Tdet = T11*T22 - T12*T21; + if ( (std::fabs( Tdet) ) < (std::numeric_limits<double>::min()) ) + { + bc[0]=1; bc[1]=bc[2]=0; // no solution + return; + } + // matrix inverse + double t11 = T22, t12 = -T12, t21 = -T21, t22 = T11; + // vector + double r11 = p[_X]-n[2][_X], r12 = p[_Y]-n[2][_Y]; + // barycentric coordinates: mutiply matrix by vector + bc[0] = (t11 * r11 + t12 * r12)/Tdet; + bc[1] = (t21 * r11 + t22 * r12)/Tdet; + bc[2] = 1. - bc[0] - bc[1]; + break; + } + case 4: + { // TETRA4 + // Find bc by solving system of 3 equations using Gaussian elimination algorithm + // bc1*( x1 - x4 ) + bc2*( x2 - x4 ) + bc3*( x3 - x4 ) = px - x4 + // bc1*( y1 - y4 ) + bc2*( y2 - y4 ) + bc3*( y3 - y4 ) = px - y4 + // bc1*( z1 - z4 ) + bc2*( z2 - z4 ) + bc3*( z3 - z4 ) = px - z4 + + double T[3][4]= + {{ n[0][_X]-n[3][_X], n[1][_X]-n[3][_X], n[2][_X]-n[3][_X], p[_X]-n[3][_X] }, + { n[0][_Y]-n[3][_Y], n[1][_Y]-n[3][_Y], n[2][_Y]-n[3][_Y], p[_Y]-n[3][_Y] }, + { n[0][_Z]-n[3][_Z], n[1][_Z]-n[3][_Z], n[2][_Z]-n[3][_Z], p[_Z]-n[3][_Z] }}; + + if ( !solveSystemOfEquations<3>( T, bc ) ) + bc[0]=1., bc[1] = bc[2] = bc[3] = 0; + else + bc[ 3 ] = 1. - bc[0] - bc[1] - bc[2]; + break; + } + case 6: + { + // TRIA6 + double matrix2[48]={1., 0., 0., 0., 0., 0., 0., 0., + 1., 0., 0., 0., 0., 0., 1., 0., + 1., 0., 0., 0., 0., 0., 0., 1., + 1., 0., 0., 0., 0., 0., 0.5, 0., + 1., 0., 0., 0., 0., 0., 0.5, 0.5, + 1., 0., 0., 0., 0., 0., 0.,0.5}; + for(int i=0;i<6;i++) + { + matrix2[8*i+1]=n[i][0]; + matrix2[8*i+2]=n[i][1]; + matrix2[8*i+3]=n[i][0]*n[i][0]; + matrix2[8*i+4]=n[i][0]*n[i][1]; + matrix2[8*i+5]=n[i][1]*n[i][1]; + } + double res[12]; + solveSystemOfEquations2<6,2>(matrix2,res,std::numeric_limits<double>::min()); + double refCoo[2]; + refCoo[0]=computeTria6RefBase(res,p); + refCoo[1]=computeTria6RefBase(res+6,p); + computeWeightedCoeffsInTria6FromRefBase(refCoo,bc); + break; + } + case 10: + {//TETRA10 + double matrix2[130]={1., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., + 1., 0., 0., 0., 0., 0., 0., 0., 0., 0., 1., 0., 0., + 1., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 1., 0., + 1., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 1., + 1., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.5, 0., 0., + 1., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.5, 0.5, 0., + 1., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.,0.5, 0., + 1., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.5, + 1., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.5, 0., 0.5, + 1., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.5, 0.5}; + for(int i=0;i<10;i++) + { + matrix2[13*i+1]=n[i][0]; + matrix2[13*i+2]=n[i][1]; + matrix2[13*i+3]=n[i][2]; + matrix2[13*i+4]=n[i][0]*n[i][0]; + matrix2[13*i+5]=n[i][0]*n[i][1]; + matrix2[13*i+6]=n[i][0]*n[i][2]; + matrix2[13*i+7]=n[i][1]*n[i][1]; + matrix2[13*i+8]=n[i][1]*n[i][2]; + matrix2[13*i+9]=n[i][2]*n[i][2]; + } + double res[30]; + solveSystemOfEquations2<10,3>(matrix2,res,std::numeric_limits<double>::min()); + double refCoo[3]; + refCoo[0]=computeTetra10RefBase(res,p); + refCoo[1]=computeTetra10RefBase(res+10,p); + refCoo[2]=computeTetra10RefBase(res+20,p); + computeWeightedCoeffsInTetra10FromRefBase(refCoo,bc); + break; + } + default: + throw INTERP_KERNEL::Exception("INTERP_KERNEL::barycentric_coords : unrecognized simplex !"); + } + } + + /*_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ */ + /* calcul la surface d'un polygone. */ + /*_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ */ + + inline double Surf_Poly(const std::vector<double>& Poly) + { + + double Surface=0; + for(unsigned long i=0; i<(Poly.size())/2-2; i++) + { + double Surf=Surf_Tri( &Poly[0],&Poly[2*(i+1)],&Poly[2*(i+2)] ); + Surface=Surface + Surf ; + } + return Surface ; + } + + /*_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ */ + /* fonction qui teste si un point est dans une maille */ + /* point: P_0 */ + /* P_1, P_2, P_3 sommet des mailles */ + /*_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ */ + + inline bool point_dans_triangle(const double* P_0,const double* P_1, + const double* P_2,const double* P_3, + double eps) + { + + bool A=false; + double det_1=mon_determinant(P_1,P_3,P_0); + double det_2=mon_determinant(P_3,P_2,P_0); + double det_3=mon_determinant(P_2,P_1,P_0); + if( (det_1>=-eps && det_2>=-eps && det_3>=-eps) || (det_1<=eps && det_2<=eps && det_3<=eps) ) + { + A=true; + } + + return A; + } + + /*_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ */ + /*fonction pour verifier qu'un point n'a pas deja ete considerer dans */ + /* le vecteur et le rajouter au vecteur sinon. */ + /*_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ */ + + inline void verif_point_dans_vect(const double* P, std::vector<double>& V, double absolute_precision ) + { + long taille=V.size(); + bool isPresent=false; + for(long i=0;i<taille/2;i++) + { + if (sqrt(((P[0]-V[2*i])*(P[0]-V[2*i])+(P[1]-V[2*i+1])*(P[1]-V[2*i+1])))<absolute_precision) + isPresent=true; + + } + if(!isPresent) + { + + V.push_back(P[0]); + V.push_back(P[1]); + } + } + + /*_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ */ + /* fonction qui rajoute les sommet du triangle P dans le vecteur V */ + /* si ceux-ci sont compris dans le triangle S et ne sont pas deja dans */ + /* V. */ + /*sommets de P: P_1, P_2, P_3 */ + /*sommets de S: P_4, P_5, P_6 */ + /*_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ */ + + inline void rajou_sommet_triangl(const double* P_1,const double* P_2,const double* P_3, + const double* P_4,const double* P_5,const double* P_6, + std::vector<double>& V, double dim_caracteristic, double precision) + { + + double absolute_precision = precision*dim_caracteristic; + bool A_1=INTERP_KERNEL::point_dans_triangle(P_1,P_4,P_5,P_6,absolute_precision); + if(A_1) + verif_point_dans_vect(P_1,V,absolute_precision); + bool A_2=INTERP_KERNEL::point_dans_triangle(P_2,P_4,P_5,P_6,absolute_precision); + if(A_2) + verif_point_dans_vect(P_2,V,absolute_precision); + bool A_3=INTERP_KERNEL::point_dans_triangle(P_3,P_4,P_5,P_6,absolute_precision); + if(A_3) + verif_point_dans_vect(P_3,V,absolute_precision); + } + + + /*_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _*/ + /* calcul de l'intersection de deux segments: segments P1P2 avec P3P4 */ + /* . Si l'intersection est non nulle et si celle-ci n'est */ + /* n'est pas deja contenue dans Vect on la rajoute a Vect */ + /*_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _*/ + + inline void inters_de_segment(const double * P_1,const double * P_2, + const double * P_3,const double * P_4, + std::vector<double>& Vect, + double dim_caracteristic, double precision) + { + // calcul du determinant de P_1P_2 et P_3P_4. + double det=(P_2[0]-P_1[0])*(P_4[1]-P_3[1])-(P_4[0]-P_3[0])*(P_2[1]-P_1[1]); + + double absolute_precision = dim_caracteristic*precision; + if(fabs(det)>absolute_precision) + { + double k_1=-((P_3[1]-P_4[1])*(P_3[0]-P_1[0])+(P_4[0]-P_3[0])*(P_3[1]-P_1[1]))/det; + + if (k_1 >= -absolute_precision && k_1 <= 1+absolute_precision) + //if( k_1 >= -precision && k_1 <= 1+precision) + { + double k_2= ((P_1[1]-P_2[1])*(P_1[0]-P_3[0])+(P_2[0]-P_1[0])*(P_1[1]-P_3[1]))/det; + + if (k_2 >= -absolute_precision && k_2 <= 1+absolute_precision) + //if( k_2 >= -precision && k_2 <= 1+precision) + { + double P_0[2]; + P_0[0]=P_1[0]+k_1*(P_2[0]-P_1[0]); + P_0[1]=P_1[1]+k_1*(P_2[1]-P_1[1]); + verif_point_dans_vect(P_0,Vect,absolute_precision); + } + } + } + } + + + + /*_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _*/ + /* calcul l'intersection de deux triangles */ + /* P_1, P_2, P_3: sommets du premier triangle */ + /* P_4, P_5, P_6: sommets du deuxi�me triangle */ + /*_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _*/ + + inline void intersec_de_triangle(const double* P_1,const double* P_2, const double* P_3, + const double* P_4,const double* P_5,const double* P_6, + std::vector<double>& Vect, double dim_caracteristic, double precision) + { + inters_de_segment(P_1,P_2,P_4,P_5,Vect, dim_caracteristic, precision); + inters_de_segment(P_1,P_2,P_5,P_6,Vect, dim_caracteristic, precision); + inters_de_segment(P_1,P_2,P_6,P_4,Vect, dim_caracteristic, precision); + inters_de_segment(P_2,P_3,P_4,P_5,Vect, dim_caracteristic, precision); + inters_de_segment(P_2,P_3,P_5,P_6,Vect, dim_caracteristic, precision); + inters_de_segment(P_2,P_3,P_6,P_4,Vect, dim_caracteristic, precision); + inters_de_segment(P_3,P_1,P_4,P_5,Vect, dim_caracteristic, precision); + inters_de_segment(P_3,P_1,P_5,P_6,Vect, dim_caracteristic, precision); + inters_de_segment(P_3,P_1,P_6,P_4,Vect, dim_caracteristic, precision); + rajou_sommet_triangl(P_1,P_2,P_3,P_4,P_5,P_6,Vect, dim_caracteristic, precision); + rajou_sommet_triangl(P_4,P_5,P_6,P_1,P_2,P_3,Vect, dim_caracteristic, precision); + } + + /*_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _*/ + /* fonction pour verifier qu'un node maille n'a pas deja ete considerer */ + /* dans le vecteur et le rajouter au vecteur sinon. */ + /*_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _*/ + + inline void verif_maill_dans_vect(int Num, std::vector<int>& V) + { + long taille=V.size(); + int A=0; + for(long i=0;i<taille;i++) + { + if(Num==V[i]) + { + A=1; + break; + } + } + if(A==0) + {V.push_back(Num); } + } + + /*! Function that compares two angles from the values of the pairs (sin,cos)*/ + /*! Angles are considered in [0, 2Pi] bt are not computed explicitely */ + class AngleLess + { + public: + bool operator()(std::pair<double,double>theta1, std::pair<double,double> theta2) + { + double norm1 = sqrt(theta1.first*theta1.first +theta1.second*theta1.second); + double norm2 = sqrt(theta2.first*theta2.first +theta2.second*theta2.second); + + double epsilon = 1.e-12; + + if( norm1 < epsilon || norm2 < epsilon ) + std::cout << "Warning InterpolationUtils.hxx: AngleLess : Vector with zero norm, cannot define the angle !!!! " << std::endl; + + return theta1.second*(norm2 + theta2.first) < theta2.second*(norm1 + theta1.first); + + } + }; + + + /*_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ */ + /* fonction pour reconstituer un polygone convexe a partir */ + /* d'un nuage de point. */ + /*_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ */ + + inline std::vector<double> reconstruct_polygon(const std::vector<double>& V) + { + + int taille((int)V.size()); + + //VB : why 6 ? + + if(taille<=6) + {return V;} + else + { + double *COS=new double[taille/2]; + double *SIN=new double[taille/2]; + //double *angle=new double[taille/2]; + std::vector<double> Bary=bary_poly(V); + COS[0]=1.0; + SIN[0]=0.0; + //angle[0]=0.0; + for(int i=0; i<taille/2-1;i++) + { + std::vector<double> Trigo=calcul_cos_et_sin(&Bary[0],&V[0],&V[2*(i+1)]); + COS[i+1]=Trigo[0]; + SIN[i+1]=Trigo[1]; + //if(SIN[i+1]>=0) + // {angle[i+1]=atan2(SIN[i+1],COS[i+1]);} + // else + // {angle[i+1]=-atan2(SIN[i+1],COS[i+1]);} + } + + //ensuite on ordonne les angles. + std::vector<double> Pt_ordonne; + Pt_ordonne.reserve(taille); + // std::multimap<double,int> Ordre; + std::multimap<std::pair<double,double>,int, AngleLess> CosSin; + for(int i=0;i<taille/2;i++) + { + // Ordre.insert(std::make_pair(angle[i],i)); + CosSin.insert(std::make_pair(std::make_pair(SIN[i],COS[i]),i)); + } + // std::multimap <double,int>::iterator mi; + std::multimap<std::pair<double,double>,int, AngleLess>::iterator micossin; + // for(mi=Ordre.begin();mi!=Ordre.end();mi++) + // { + // int j=(*mi).second; + // Pt_ordonne.push_back(V[2*j]); + // Pt_ordonne.push_back(V[2*j+1]); + // } + for(micossin=CosSin.begin();micossin!=CosSin.end();micossin++) + { + int j=(*micossin).second; + Pt_ordonne.push_back(V[2*j]); + Pt_ordonne.push_back(V[2*j+1]); + } + delete [] COS; + delete [] SIN; + // delete [] angle; + return Pt_ordonne; + } + } + + template<int DIM, NumberingPolicy numPol, class MyMeshType> + inline void getElemBB(double* bb, const double *coordsOfMesh, int iP, int nb_nodes) + { + bb[0]=std::numeric_limits<double>::max(); + bb[1]=-std::numeric_limits<double>::max(); + bb[2]=std::numeric_limits<double>::max(); + bb[3]=-std::numeric_limits<double>::max(); + bb[4]=std::numeric_limits<double>::max(); + bb[5]=-std::numeric_limits<double>::max(); + + for (int i=0; i<nb_nodes; i++) + { + double x = coordsOfMesh[3*(iP+i)]; + double y = coordsOfMesh[3*(iP+i)+1]; + double z = coordsOfMesh[3*(iP+i)+2]; + bb[0]=(x<bb[0])?x:bb[0]; + bb[1]=(x>bb[1])?x:bb[1]; + bb[2]=(y<bb[2])?y:bb[2]; + bb[3]=(y>bb[3])?y:bb[3]; + bb[4]=(z<bb[4])?z:bb[4]; + bb[5]=(z>bb[5])?z:bb[5]; + } + } + + /*_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _*/ + /* Computes the dot product of a and b */ + /*_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _*/ + template<int dim> + inline double dotprod( const double * a, const double * b) + { + double result=0; + for(int idim = 0; idim < dim ; idim++) result += a[idim]*b[idim]; + return result; + } + /*_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _*/ + /* Computes the norm of vector v */ + /*_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _*/ + template<int dim> + inline double norm(const double * v) + { + double result =0; + for(int idim =0; idim<dim; idim++) result+=v[idim]*v[idim]; + return sqrt(result); + } + /*_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _*/ + /* Computes the square norm of vector a-b */ + /*_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _*/ + template<int dim> + inline double distance2( const double * a, const double * b) + { + double result =0; + for(int idim =0; idim<dim; idim++) result+=(a[idim]-b[idim])*(a[idim]-b[idim]); + return result; + } + template<class T, int dim> + inline double distance2( T * a, int inda, T * b, int indb) + { + double result =0; + for(int idim =0; idim<dim; idim++) result += ((*a)[inda+idim] - (*b)[indb+idim])* ((*a)[inda+idim] - (*b)[indb+idim]); + return result; + } + /*_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _*/ + /* Computes the determinant of a and b */ + /*_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _*/ + inline double determinant ( double * a, double * b) + { + return a[0]*b[1]-a[1]*b[0]; + } + inline double determinant ( double * a, double * b, double * c) + { + return a[0]*determinant(b+1,c+1)-b[0]*determinant(a+1,c+1)+c[0]*determinant(a+1,b+1); + } + + /*_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _*/ + /* Computes the cross product of AB and AC */ + /*_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _*/ + + template<int dim> inline void crossprod( const double * A, const double * B, const double * C, double * V); + + template<> inline + void crossprod<2>( const double * A, const double * B, const double * C, double * V) + { + double AB[2]; + double AC[2]; + for(int idim =0; idim<2; idim++) AB[idim] = B[idim]-A[idim];//B-A + for(int idim =0; idim<2; idim++) AC[idim] = C[idim]-A[idim];//C-A; + + V[0]=determinant(AB,AC); + V[1]=0; + } + template<> inline + void crossprod<3>( const double * A, const double * B, const double * C, double * V) + { + double AB[3]; + double AC[3]; + for(int idim =0; idim<3; idim++) AB[idim] = B[idim]-A[idim];//B-A + for(int idim =0; idim<3; idim++) AC[idim] = C[idim]-A[idim];//C-A; + + V[0]=AB[1]*AC[2]-AB[2]*AC[1]; + V[1]=-AB[0]*AC[2]+AB[2]*AC[0]; + V[2]=AB[0]*AC[1]-AB[1]*AC[0]; + } + template<> inline + void crossprod<1>( const double * /*A*/, const double * /*B*/, const double * /*C*/, double * /*V*/) + { + // just to be able to compile + } + + /*_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _*/ + /* Checks wether point A is inside the quadrangle BCDE */ + /*_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _*/ + + template<int dim> inline double check_inside(const double* A,const double* B,const double* C,const double* D, + const double* E,double* ABC, double* ADE) + { + crossprod<dim>(A,B,C,ABC); + crossprod<dim>(A,D,E,ADE); + return dotprod<dim>(ABC,ADE); + } + + + /*_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _*/ + /* Computes the geometric angle (in [0,Pi]) between two non zero vectors AB and AC */ + /*_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _*/ + template<int dim> inline double angle(const double * A, const double * B, const double * C, double * n) + { + double AB[dim]; + double AC[dim]; + double orthAB[dim]; + + for(int idim =0; idim<dim; idim++) AB[idim] = B[idim]-A[idim];//B-A; + for(int idim =0; idim<dim; idim++) AC[idim] = C[idim]-A[idim];//C-A; + + double normAB= norm<dim>(AB); + for(int idim =0; idim<dim; idim++) AB[idim]/=normAB; + + double normAC= norm<dim>(AC); + double AB_dot_AC=dotprod<dim>(AB,AC); + for(int idim =0; idim<dim; idim++) orthAB[idim] = AC[idim]-AB_dot_AC*AB[idim]; + + double denom= normAC+AB_dot_AC; + double numer=norm<dim>(orthAB); + + return 2*atan2(numer,denom); + } + + /*_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _*/ + /* Tells whether the frame constituted of vectors AB, AC and n is direct */ + /*_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _*/ + template<int dim> inline double direct_frame(const double * A, const double * B, const double * C, double * n); + template<> inline + double direct_frame<2>(const double * A, const double * B, const double * C, double * n) + { + double AB[2]; + double AC[2]; + for(int idim =0; idim<2; idim++) AB[idim] = B[idim]-A[idim];//B-A; + for(int idim =0; idim<2; idim++) AC[idim] = C[idim]-A[idim];//C-A; + + return determinant(AB,AC)*n[0]; + } + template<> inline + double direct_frame<3>(const double * A, const double * B, const double * C, double * n) + { + double AB[3]; + double AC[3]; + for(int idim =0; idim<3; idim++) AB[idim] = B[idim]-A[idim];//B-A; + for(int idim =0; idim<3; idim++) AC[idim] = C[idim]-A[idim];//C-A; + + return determinant(AB,AC,n)>0; + } + + /*_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _*/ + /* calcul l'intersection de deux polygones COPLANAIRES */ + /* en dimension DIM (2 ou 3). Si DIM=3 l'algorithme ne considere*/ + /* que les deux premieres coordonnees de chaque point */ + /*_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _*/ + template<int DIM> inline void intersec_de_polygone(const double * Coords_A, const double * Coords_B, + int nb_NodesA, int nb_NodesB, + std::vector<double>& inter, + double dim_caracteristic, double precision) + { + for(int i_A = 1; i_A<nb_NodesA-1; i_A++) + { + for(int i_B = 1; i_B<nb_NodesB-1; i_B++) + { + INTERP_KERNEL::intersec_de_triangle(&Coords_A[0],&Coords_A[DIM*i_A],&Coords_A[DIM*(i_A+1)], + &Coords_B[0],&Coords_B[DIM*i_B],&Coords_B[DIM*(i_B+1)], + inter, dim_caracteristic, precision); + } + } + int nb_inter=((int)inter.size())/DIM; + if(nb_inter >3) inter=INTERP_KERNEL::reconstruct_polygon(inter); + } + + /*_ _ _ _ _ _ _ _ _ + *_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ + * fonctions qui calcule l'aire d'un polygone en dimension 2 ou 3 + *_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ */ + template<int DIM> inline double polygon_area(std::vector<double>& inter) + { + double result=0.; + double area[DIM]; + + for(int i = 1; i<(int)inter.size()/DIM-1; i++) + { + INTERP_KERNEL::crossprod<DIM>(&inter[0],&inter[DIM*i],&inter[DIM*(i+1)],area); + result +=0.5*norm<DIM>(area); + } + return result; + } + + template<int DIM> inline double polygon_area(std::deque<double>& inter) + { + double result=0.; + double area[DIM]; + + for(int i = 1; i<(int)inter.size()/DIM-1; i++) + { + INTERP_KERNEL::crossprod<DIM>(&inter[0],&inter[DIM*i],&inter[DIM*(i+1)],area); + result +=0.5*norm<DIM>(area); + } + return result; + } + + /*! Computes the triple product (XA^XB).XC (in 3D)*/ + inline double triple_product(const double* A, const double*B, const double*C, const double*X) + { + double XA[3]; + XA[0]=A[0]-X[0]; + XA[1]=A[1]-X[1]; + XA[2]=A[2]-X[2]; + double XB[3]; + XB[0]=B[0]-X[0]; + XB[1]=B[1]-X[1]; + XB[2]=B[2]-X[2]; + double XC[3]; + XC[0]=C[0]-X[0]; + XC[1]=C[1]-X[1]; + XC[2]=C[2]-X[2]; + + return + (XA[1]*XB[2]-XA[2]*XB[1])*XC[0]+ + (XA[2]*XB[0]-XA[0]*XB[2])*XC[1]+ + (XA[0]*XB[1]-XA[1]*XB[0])*XC[2]; + } + + /*! Subroutine of checkEqualPolygins that tests if two list of nodes (not necessarily distincts) describe the same polygon, assuming they share a comon point.*/ + /*! Indexes istart1 and istart2 designate two points P1 in L1 and P2 in L2 that have identical coordinates. Generally called with istart1=0.*/ + /*! Integer sign ( 1 or -1) indicate the direction used in going all over L2. */ + template<class T, int dim> + bool checkEqualPolygonsOneDirection(T * L1, T * L2, int size1, int size2, int istart1, int istart2, double epsilon, int sign) + { + int i1 = istart1; + int i2 = istart2; + int i1next = ( i1 + 1 ) % size1; + int i2next = ( i2 + sign +size2) % size2; + + while(true) + { + while( i1next!=istart1 && distance2<T,dim>(L1,i1*dim, L1,i1next*dim) < epsilon ) i1next = ( i1next + 1 ) % size1; + while( i2next!=istart2 && distance2<T,dim>(L2,i2*dim, L2,i2next*dim) < epsilon ) i2next = ( i2next + sign +size2 ) % size2; + + if(i1next == istart1) + { + if(i2next == istart2) + return true; + else return false; + } + else + if(i2next == istart2) + return false; + else + { + if(distance2<T,dim>(L1,i1next*dim, L2,i2next*dim) > epsilon ) + return false; + else + { + i1 = i1next; + i2 = i2next; + i1next = ( i1 + 1 ) % size1; + i2next = ( i2 + sign + size2 ) % size2; + } + } + } + } + + /*! Tests if two list of nodes (not necessarily distincts) describe the same polygon.*/ + /*! Existence of multiple points in the list is considered.*/ + template<class T, int dim> + bool checkEqualPolygons(T * L1, T * L2, double epsilon) + { + if(L1==NULL || L2==NULL) + { + std::cout << "Warning InterpolationUtils.hxx:checkEqualPolygonsPointer: Null pointer " << std::endl; + throw(Exception("big error: not closed polygon...")); + } + + int size1 = (*L1).size()/dim; + int size2 = (*L2).size()/dim; + int istart1 = 0; + int istart2 = 0; + + while( istart2 < size2 && distance2<T,dim>(L1,istart1*dim, L2,istart2*dim) > epsilon ) istart2++; + + if(istart2 == size2) + { + return (size1 == 0) && (size2 == 0); + } + else + return checkEqualPolygonsOneDirection<T,dim>( L1, L2, size1, size2, istart1, istart2, epsilon, 1) + || checkEqualPolygonsOneDirection<T,dim>( L1, L2, size1, size2, istart1, istart2, epsilon, -1); + + } +} + + +#endif diff --git a/src/medtool/src/INTERP_KERNEL/Intersector3D.hxx b/src/medtool/src/INTERP_KERNEL/Intersector3D.hxx new file mode 100644 index 000000000..c9b74ffe7 --- /dev/null +++ b/src/medtool/src/INTERP_KERNEL/Intersector3D.hxx @@ -0,0 +1,49 @@ +// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 +// 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 __INTERSECTOR3D_HXX__ +#define __INTERSECTOR3D_HXX__ + +#include "TargetIntersector.hxx" + +namespace INTERP_KERNEL +{ + template<class MyMeshType, class MyMatrix> + class Intersector3D : public TargetIntersector<MyMeshType,MyMatrix> + { + public: + static const int SPACEDIM=MyMeshType::MY_SPACEDIM; + static const int MESHDIM=MyMeshType::MY_MESHDIM; + typedef typename MyMeshType::MyConnType ConnType; + static const NumberingPolicy numPol=MyMeshType::My_numPol; + public: + Intersector3D(const MyMeshType& targetMesh, const MyMeshType& srcMesh); + void getRealTargetCoordinates(ConnType icellT, std::vector<double>& coordsT) const; + void getRealSourceCoordinates(ConnType icellT, std::vector<double>& coordsT) const; + const ConnType *getStartConnOfTargetCell(ConnType icellT) const; + const ConnType *getStartConnOfSourceCell(ConnType icellS) const; + void getConnOfSourceCell(ConnType icellS, typename std::vector<ConnType>& res) const; + protected: + const MyMeshType& _target_mesh; + const MyMeshType& _src_mesh; + }; +} + +#endif diff --git a/src/medtool/src/INTERP_KERNEL/Intersector3D.txx b/src/medtool/src/INTERP_KERNEL/Intersector3D.txx new file mode 100644 index 000000000..92ff0a56a --- /dev/null +++ b/src/medtool/src/INTERP_KERNEL/Intersector3D.txx @@ -0,0 +1,107 @@ +// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 +// 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 __INTERSECTOR3D_TXX__ +#define __INTERSECTOR3D_TXX__ + +#include "Intersector3D.hxx" + +#include <algorithm> + +namespace INTERP_KERNEL +{ + template<class MyMeshType, class MyMatrix> + Intersector3D<MyMeshType,MyMatrix>::Intersector3D(const MyMeshType& targetMesh, const MyMeshType& srcMesh):_target_mesh(targetMesh),_src_mesh(srcMesh) + { + } + + /*! + * @param icellT in format of MyMeshType. + */ + template<class MyMeshType, class MyMatrix> + void Intersector3D<MyMeshType,MyMatrix>::getRealTargetCoordinates(ConnType icellT, std::vector<double>& coordsT) const + { + int nbNodesT=_target_mesh.getNumberOfNodesOfElement(icellT); + coordsT.resize(SPACEDIM*nbNodesT); + std::vector<double>::iterator iter=coordsT.begin(); + for (ConnType iT=0; iT<nbNodesT; iT++) + { + const double *coordsCur=getCoordsOfNode(iT,icellT,_target_mesh); + iter=std::copy(coordsCur,coordsCur+SPACEDIM,iter); + } + } + + /*! + * @param icellT in format of MyMeshType. + */ + template<class MyMeshType, class MyMatrix> + void Intersector3D<MyMeshType,MyMatrix>::getRealSourceCoordinates(ConnType icellS, std::vector<double>& coordsS) const + { + int nbNodesS=_src_mesh.getNumberOfNodesOfElement(icellS); + coordsS.resize(SPACEDIM*nbNodesS); + std::vector<double>::iterator iter=coordsS.begin(); + for (ConnType iS=0; iS<nbNodesS; iS++) + { + const double *coordsCur=getCoordsOfNode(iS,icellS,_src_mesh); + iter=std::copy(coordsCur,coordsCur+SPACEDIM,iter); + } + } + + /*! + * @param icellT in C format. + * @return is in format of MyMeshType + */ + template<class MyMeshType, class MyMatrix> + const typename MyMeshType::MyConnType *Intersector3D<MyMeshType,MyMatrix>::getStartConnOfTargetCell(ConnType icellT) const + { + const ConnType *myConectT=_target_mesh.getConnectivityPtr(); + const ConnType *myConIndexT=_target_mesh.getConnectivityIndexPtr(); + return myConectT+OTT<ConnType,numPol>::conn2C(myConIndexT[icellT]); + } + + /*! + * @param icellT in C format. + * @return is in format of MyMeshType + */ + template<class MyMeshType, class MyMatrix> + const typename MyMeshType::MyConnType *Intersector3D<MyMeshType,MyMatrix>::getStartConnOfSourceCell(ConnType icellS) const + { + const ConnType *myConectS=_src_mesh.getConnectivityPtr(); + const ConnType *myConIndexS=_src_mesh.getConnectivityIndexPtr(); + return myConectS+OTT<ConnType,numPol>::conn2C(myConIndexS[icellS]); + } + + /*! + * @param icellS in format of MyMeshType. + * @param res ; out param in format of MyMeshType. + */ + template<class MyMeshType, class MyMatrix> + void Intersector3D<MyMeshType,MyMatrix>::getConnOfSourceCell(ConnType icellS, typename std::vector<ConnType>& res) const + { + const ConnType *myConectS=_src_mesh.getConnectivityPtr(); + const ConnType *myConIndexS=_src_mesh.getConnectivityIndexPtr(); + ConnType start=myConIndexS[OTT<ConnType,numPol>::ind2C(icellS)]; + ConnType end=myConIndexS[OTT<ConnType,numPol>::ind2C(icellS)+1]; + int nbNodesS=end-start; + res.resize(nbNodesS); + std::copy(myConectS+OTT<ConnType,numPol>::conn2C(start),myConectS+OTT<ConnType,numPol>::conn2C(end),res.begin()); + } +} + +#endif diff --git a/src/medtool/src/INTERP_KERNEL/Intersector3DP0P0.hxx b/src/medtool/src/INTERP_KERNEL/Intersector3DP0P0.hxx new file mode 100644 index 000000000..ede6b02ae --- /dev/null +++ b/src/medtool/src/INTERP_KERNEL/Intersector3DP0P0.hxx @@ -0,0 +1,38 @@ +// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 +// 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 __INTERSECTOR3DP0P0_HXX__ +#define __INTERSECTOR3DP0P0_HXX__ + +#include "Intersector3D.hxx" + +namespace INTERP_KERNEL +{ + template<class MyMeshType, class MyMatrix> + class Intersector3DP0P0 : public Intersector3D<MyMeshType,MyMatrix> + { + public: + Intersector3DP0P0(const MyMeshType& targetMesh, const MyMeshType& srcMesh); + int getNumberOfRowsOfResMatrix() const; + int getNumberOfColsOfResMatrix() const; + }; +} + +#endif diff --git a/src/medtool/src/INTERP_KERNEL/Intersector3DP0P0.txx b/src/medtool/src/INTERP_KERNEL/Intersector3DP0P0.txx new file mode 100644 index 000000000..86f1a17d5 --- /dev/null +++ b/src/medtool/src/INTERP_KERNEL/Intersector3DP0P0.txx @@ -0,0 +1,46 @@ +// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 +// 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 __INTERSECTOR3DP0P0_TXX__ +#define __INTERSECTOR3DP0P0_TXX__ + +#include "Intersector3DP0P0.hxx" +#include "Intersector3D.txx" + +namespace INTERP_KERNEL +{ + template<class MyMeshType, class MyMatrix> + Intersector3DP0P0<MyMeshType,MyMatrix>::Intersector3DP0P0(const MyMeshType& targetMesh, const MyMeshType& srcMesh):Intersector3D<MyMeshType,MyMatrix>(targetMesh,srcMesh) + { + } + + template<class MyMeshType, class MyMatrix> + int Intersector3DP0P0<MyMeshType,MyMatrix>::getNumberOfRowsOfResMatrix() const + { + return Intersector3D<MyMeshType,MyMatrix>::_target_mesh.getNumberOfElements(); + } + + template<class MyMeshType, class MyMatrix> + int Intersector3DP0P0<MyMeshType,MyMatrix>::getNumberOfColsOfResMatrix() const + { + return Intersector3D<MyMeshType,MyMatrix>::_src_mesh.getNumberOfElements(); + } +} + +#endif diff --git a/src/medtool/src/INTERP_KERNEL/Intersector3DP0P1.hxx b/src/medtool/src/INTERP_KERNEL/Intersector3DP0P1.hxx new file mode 100644 index 000000000..8ba8b6cc4 --- /dev/null +++ b/src/medtool/src/INTERP_KERNEL/Intersector3DP0P1.hxx @@ -0,0 +1,38 @@ +// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 +// 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 __INTERSECTOR3DP0P1_HXX__ +#define __INTERSECTOR3DP0P1_HXX__ + +#include "Intersector3D.hxx" + +namespace INTERP_KERNEL +{ + template<class MyMeshType, class MyMatrix> + class Intersector3DP0P1 : public Intersector3D<MyMeshType,MyMatrix> + { + public: + Intersector3DP0P1(const MyMeshType& targetMesh, const MyMeshType& srcMesh); + int getNumberOfRowsOfResMatrix() const; + int getNumberOfColsOfResMatrix() const; + }; +} + +#endif diff --git a/src/medtool/src/INTERP_KERNEL/Intersector3DP0P1.txx b/src/medtool/src/INTERP_KERNEL/Intersector3DP0P1.txx new file mode 100644 index 000000000..cd44920ce --- /dev/null +++ b/src/medtool/src/INTERP_KERNEL/Intersector3DP0P1.txx @@ -0,0 +1,46 @@ +// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 +// 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 __INTERSECTOR3DP0P1_TXX__ +#define __INTERSECTOR3DP0P1_TXX__ + +#include "Intersector3DP0P1.hxx" +#include "Intersector3D.txx" + +namespace INTERP_KERNEL +{ + template<class MyMeshType, class MyMatrix> + Intersector3DP0P1<MyMeshType,MyMatrix>::Intersector3DP0P1(const MyMeshType& targetMesh, const MyMeshType& srcMesh):Intersector3D<MyMeshType,MyMatrix>(targetMesh,srcMesh) + { + } + + template<class MyMeshType, class MyMatrix> + int Intersector3DP0P1<MyMeshType,MyMatrix>::getNumberOfRowsOfResMatrix() const + { + return Intersector3D<MyMeshType,MyMatrix>::_target_mesh.getNumberOfNodes(); + } + + template<class MyMeshType, class MyMatrix> + int Intersector3DP0P1<MyMeshType,MyMatrix>::getNumberOfColsOfResMatrix() const + { + return Intersector3D<MyMeshType,MyMatrix>::_src_mesh.getNumberOfElements(); + } +} + +#endif diff --git a/src/medtool/src/INTERP_KERNEL/Intersector3DP1P0.hxx b/src/medtool/src/INTERP_KERNEL/Intersector3DP1P0.hxx new file mode 100644 index 000000000..8ba6bf53c --- /dev/null +++ b/src/medtool/src/INTERP_KERNEL/Intersector3DP1P0.hxx @@ -0,0 +1,38 @@ +// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 +// 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 __INTERSECTOR3DP1P0_HXX__ +#define __INTERSECTOR3DP1P0_HXX__ + +#include "Intersector3D.hxx" + +namespace INTERP_KERNEL +{ + template<class MyMeshType, class MyMatrix> + class Intersector3DP1P0 : public Intersector3D<MyMeshType,MyMatrix> + { + public: + Intersector3DP1P0(const MyMeshType& targetMesh, const MyMeshType& srcMesh); + int getNumberOfRowsOfResMatrix() const; + int getNumberOfColsOfResMatrix() const; + }; +} + +#endif diff --git a/src/medtool/src/INTERP_KERNEL/Intersector3DP1P0.txx b/src/medtool/src/INTERP_KERNEL/Intersector3DP1P0.txx new file mode 100644 index 000000000..9db664d67 --- /dev/null +++ b/src/medtool/src/INTERP_KERNEL/Intersector3DP1P0.txx @@ -0,0 +1,46 @@ +// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 +// 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 __INTERSECTOR3DP1P0_TXX__ +#define __INTERSECTOR3DP1P0_TXX__ + +#include "Intersector3DP1P0.hxx" +#include "Intersector3D.txx" + +namespace INTERP_KERNEL +{ + template<class MyMeshType, class MyMatrix> + Intersector3DP1P0<MyMeshType,MyMatrix>::Intersector3DP1P0(const MyMeshType& targetMesh, const MyMeshType& srcMesh):Intersector3D<MyMeshType,MyMatrix>(targetMesh,srcMesh) + { + } + + template<class MyMeshType, class MyMatrix> + int Intersector3DP1P0<MyMeshType,MyMatrix>::getNumberOfRowsOfResMatrix() const + { + return Intersector3D<MyMeshType,MyMatrix>::_target_mesh.getNumberOfElements(); + } + + template<class MyMeshType, class MyMatrix> + int Intersector3DP1P0<MyMeshType,MyMatrix>::getNumberOfColsOfResMatrix() const + { + return Intersector3D<MyMeshType,MyMatrix>::_src_mesh.getNumberOfNodes(); + } +} + +#endif diff --git a/src/medtool/src/INTERP_KERNEL/Intersector3DP1P0Bary.hxx b/src/medtool/src/INTERP_KERNEL/Intersector3DP1P0Bary.hxx new file mode 100644 index 000000000..8b69793dc --- /dev/null +++ b/src/medtool/src/INTERP_KERNEL/Intersector3DP1P0Bary.hxx @@ -0,0 +1,38 @@ +// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 +// 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 __Intersector3DP1P0Bary_HXX__ +#define __Intersector3DP1P0Bary_HXX__ + +#include "Intersector3D.hxx" + +namespace INTERP_KERNEL +{ + template<class MyMeshType, class MyMatrix> + class Intersector3DP1P0Bary : public Intersector3D<MyMeshType,MyMatrix> + { + public: + Intersector3DP1P0Bary(const MyMeshType& targetMesh, const MyMeshType& srcMesh); + int getNumberOfRowsOfResMatrix() const; + int getNumberOfColsOfResMatrix() const; + }; +} + +#endif diff --git a/src/medtool/src/INTERP_KERNEL/Intersector3DP1P0Bary.txx b/src/medtool/src/INTERP_KERNEL/Intersector3DP1P0Bary.txx new file mode 100644 index 000000000..31e7f2401 --- /dev/null +++ b/src/medtool/src/INTERP_KERNEL/Intersector3DP1P0Bary.txx @@ -0,0 +1,46 @@ +// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 +// 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 __Intersector3DP1P0Bary_TXX__ +#define __Intersector3DP1P0Bary_TXX__ + +#include "Intersector3DP1P0Bary.hxx" +#include "Intersector3D.txx" + +namespace INTERP_KERNEL +{ + template<class MyMeshType, class MyMatrix> + Intersector3DP1P0Bary<MyMeshType,MyMatrix>::Intersector3DP1P0Bary(const MyMeshType& targetMesh, const MyMeshType& srcMesh):Intersector3D<MyMeshType,MyMatrix>(targetMesh,srcMesh) + { + } + + template<class MyMeshType, class MyMatrix> + int Intersector3DP1P0Bary<MyMeshType,MyMatrix>::getNumberOfRowsOfResMatrix() const + { + return Intersector3D<MyMeshType,MyMatrix>::_target_mesh.getNumberOfElements(); + } + + template<class MyMeshType, class MyMatrix> + int Intersector3DP1P0Bary<MyMeshType,MyMatrix>::getNumberOfColsOfResMatrix() const + { + return Intersector3D<MyMeshType,MyMatrix>::_src_mesh.getNumberOfNodes(); + } +} + +#endif diff --git a/src/medtool/src/INTERP_KERNEL/Intersector3DP1P1.hxx b/src/medtool/src/INTERP_KERNEL/Intersector3DP1P1.hxx new file mode 100644 index 000000000..ff5977fa7 --- /dev/null +++ b/src/medtool/src/INTERP_KERNEL/Intersector3DP1P1.hxx @@ -0,0 +1,38 @@ +// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 +// 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 __Intersector3DP1P1_HXX__ +#define __Intersector3DP1P1_HXX__ + +#include "Intersector3D.hxx" + +namespace INTERP_KERNEL +{ + template<class MyMeshType, class MyMatrix> + class Intersector3DP1P1 : public Intersector3D<MyMeshType,MyMatrix> + { + public: + Intersector3DP1P1(const MyMeshType& targetMesh, const MyMeshType& srcMesh); + int getNumberOfRowsOfResMatrix() const; + int getNumberOfColsOfResMatrix() const; + }; +} + +#endif diff --git a/src/medtool/src/INTERP_KERNEL/Intersector3DP1P1.txx b/src/medtool/src/INTERP_KERNEL/Intersector3DP1P1.txx new file mode 100644 index 000000000..a8aea3824 --- /dev/null +++ b/src/medtool/src/INTERP_KERNEL/Intersector3DP1P1.txx @@ -0,0 +1,46 @@ +// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 +// 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 __Intersector3DP1P1_TXX__ +#define __Intersector3DP1P1_TXX__ + +#include "Intersector3DP1P1.hxx" +#include "Intersector3D.txx" + +namespace INTERP_KERNEL +{ + template<class MyMeshType, class MyMatrix> + Intersector3DP1P1<MyMeshType,MyMatrix>::Intersector3DP1P1(const MyMeshType& targetMesh, const MyMeshType& srcMesh):Intersector3D<MyMeshType,MyMatrix>(targetMesh,srcMesh) + { + } + + template<class MyMeshType, class MyMatrix> + int Intersector3DP1P1<MyMeshType,MyMatrix>::getNumberOfRowsOfResMatrix() const + { + return Intersector3D<MyMeshType,MyMatrix>::_target_mesh.getNumberOfNodes(); + } + + template<class MyMeshType, class MyMatrix> + int Intersector3DP1P1<MyMeshType,MyMatrix>::getNumberOfColsOfResMatrix() const + { + return Intersector3D<MyMeshType,MyMatrix>::_src_mesh.getNumberOfNodes(); + } +} + +#endif diff --git a/src/medtool/src/INTERP_KERNEL/IntersectorCU.hxx b/src/medtool/src/INTERP_KERNEL/IntersectorCU.hxx new file mode 100644 index 000000000..3bd09d120 --- /dev/null +++ b/src/medtool/src/INTERP_KERNEL/IntersectorCU.hxx @@ -0,0 +1,78 @@ +// Copyright (C) 2009-2015 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, 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 +// 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 +// +// File : IntersectorCU.hxx +// Created : Thu Dec 17 12:30:17 2009 +// Author : Edward AGAPOV (eap) +// + +#ifndef __IntersectorCU_HXX__ +#define __IntersectorCU_HXX__ + +#include "TargetIntersector.hxx" +#include "NormalizedUnstructuredMesh.hxx" + +namespace INTERP_KERNEL +{ + template<class MyCMeshType, class MyUMeshType, class MyMatrix> class _StabIntersector; + + template<class MyCMeshType, class MyUMeshType, class MyMatrix, class ConcreteIntersector=_StabIntersector<MyCMeshType,MyUMeshType,MyMatrix> > + class IntersectorCU : public TargetIntersector<MyCMeshType,MyMatrix> + { + public: + static const int SPACEDIM=MyCMeshType::MY_SPACEDIM; + static const int MESHDIM=MyCMeshType::MY_MESHDIM; + typedef typename MyUMeshType::MyConnType UConnType; + typedef typename MyCMeshType::MyConnType CConnType; + public: + //! \addtogroup InterpKerGrpIntCU @{ + IntersectorCU(const MyCMeshType& meshS, const MyUMeshType& meshT); + //! @} + virtual ~IntersectorCU(); + void getUElemBB(double* bb, UConnType iP); + void getUCoordinates(UConnType icell, std::vector<double>& coords); + + int getNumberOfRowsOfResMatrix() const; + int getNumberOfColsOfResMatrix() const; + void intersectCells(CConnType icellU, const std::vector<CConnType>& icellC, MyMatrix& res); + double intersectGeometry(CConnType icellT, const std::vector<CConnType>& icellC) { return asLeaf().intersectGeometry(icellT,icellC); } + protected: + ConcreteIntersector& asLeaf() { return static_cast<ConcreteIntersector&>(*this); } + + protected: + const UConnType *_connectU; + const UConnType *_connIndexU; + const double * _coordsU; + const MyUMeshType& _meshU; + + const double * _coordsC[SPACEDIM]; + int _nbCellsC[SPACEDIM]; + const MyCMeshType& _meshC; + }; + + // class to enable usage of IntersectorCU not for intersection but for access to data it encapsulates + template<class MyCMeshType, class MyUMeshType, class MyMatrix> + class _StabIntersector: public IntersectorCU<MyCMeshType, MyUMeshType, MyMatrix, _StabIntersector<MyCMeshType, MyUMeshType, MyMatrix> > + { + public: + _StabIntersector(const MyCMeshType& meshS, const MyUMeshType& meshT) : IntersectorCU<MyCMeshType, MyUMeshType, MyMatrix, _StabIntersector<MyCMeshType, MyUMeshType, MyMatrix> >(meshS, meshT) {} + double intersectGeometry(typename MyUMeshType::MyConnType icellT, const std::vector<typename MyCMeshType::MyConnType>& icellC) { throw Exception("You must provide an intersector as the 4-th template argument of IntersectorCU"); return 0; } + }; +} + +#endif diff --git a/src/medtool/src/INTERP_KERNEL/IntersectorCU.txx b/src/medtool/src/INTERP_KERNEL/IntersectorCU.txx new file mode 100644 index 000000000..b6111f732 --- /dev/null +++ b/src/medtool/src/INTERP_KERNEL/IntersectorCU.txx @@ -0,0 +1,163 @@ +// Copyright (C) 2009-2015 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, 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 +// 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 +// +// File : IntersectorCU.txx +// Created : Thu Dec 17 12:30:17 2009 +// Author : Edward AGAPOV (eap) +// +#ifndef __IntersectorCU_TXX__ +#define __IntersectorCU_TXX__ + +#include "IntersectorCU.hxx" + +// convert index "From Mesh Index" +#define _FMIU(i) OTT<typename MyUMeshType::MyConnType,MyUMeshType::My_numPol>::ind2C((i)) +#define _FMIC(i) OTT<typename MyCMeshType::MyConnType,MyCMeshType::My_numPol>::ind2C((i)) +// convert index "To Mesh Index" +#define _TMIU(i) OTT<typename MyUMeshType::MyConnType,MyUMeshType::My_numPol>::indFC((i)) +#define _TMIC(i) OTT<typename MyCMeshType::MyConnType,MyCMeshType::My_numPol>::indFC((i)) +// convert coord "From Mesh Coord" +#define _FMCOO(i) OTT<typename MyUMeshType::MyConnType,MyUMeshType::My_numPol>::coo2C((i)) +// convert connectivity "From Mesh Connectivity" +#define _FMCON(i) OTT<typename MyUMeshType::MyConnType,MyUMeshType::My_numPol>::conn2C((i)) + + +#define _CU_TEMPLATE \ +template<class MyCMeshType, class MyUMeshType, class MyMatrix, class ConcreteIntersector> +#define _INTERSECTOR_CU_ \ +IntersectorCU<MyCMeshType, MyUMeshType, MyMatrix, ConcreteIntersector> + +namespace INTERP_KERNEL +{ + //================================================================================ + /*! + * \brief Constructor + */ + //================================================================================ + + _CU_TEMPLATE + _INTERSECTOR_CU_::IntersectorCU(const MyCMeshType& meshS, const MyUMeshType& meshT): + _meshU(meshT), _meshC(meshS) + { + _connectU =meshT.getConnectivityPtr(); + _connIndexU=meshT.getConnectivityIndexPtr(); + _coordsU =meshT.getCoordinatesPtr(); + + for ( int j = 0; j < SPACEDIM; ++j ) + { + _coordsC [ j ] = _meshC.getCoordsAlongAxis( _TMIC( j )); + _nbCellsC[ j ] = _meshC.nbCellsAlongAxis ( _TMIC( j )); + } + } + + //================================================================================ + /*! + * \brief Destructor + */ + //================================================================================ + + _CU_TEMPLATE + _INTERSECTOR_CU_::~IntersectorCU() + { + } + + //================================================================================ + /*! + * \brief Return bounding box of an unstructured element + */ + //================================================================================ + + _CU_TEMPLATE + void _INTERSECTOR_CU_::getUElemBB(double* bb, UConnType icell) + { + //initializing bounding box limits + for(int idim=0; idim<SPACEDIM; idim++) + { + bb[2*idim ] = std::numeric_limits<double>::max(); + bb[2*idim+1] = -std::numeric_limits<double>::max(); + } + + UConnType nb_nodes = _connIndexU[icell+1] - _connIndexU[icell]; + for (UConnType i=0; i<nb_nodes; i++) + { + //const double* coord_node=_coordsU+SPACEDIM*(OTT<ConnType,numPol>::coo2C(conn[OTT<ConnType,numPol>::conn2C(conn_index[OTT<ConnType,numPol>::ind2C(iP)]+i)])); + const double* coord_node=_coordsU+SPACEDIM*(_FMCOO( _connectU[_FMCON (_connIndexU[_FMIU(icell)]+i)])); + for(int idim=0; idim<SPACEDIM; idim++) + { + double x = *(coord_node+idim); + bb[2*idim ] = (x<bb[2*idim ])?x:bb[2*idim ]; + bb[2*idim+1] = (x>bb[2*idim+1])?x:bb[2*idim+1]; + } + } + } + + //================================================================================ + /*! + * \brief Return coordinates of nodes of an unstructured element + */ + //================================================================================ + + _CU_TEMPLATE + void _INTERSECTOR_CU_::getUCoordinates(UConnType icell, std::vector<double>& coords) + { + UConnType nb_nodes = _connIndexU[icell+1] - _connIndexU[icell]; + coords.resize( SPACEDIM * nb_nodes ); + for (UConnType i=0; i<nb_nodes; i++) + for(int j=0; j<SPACEDIM; j++) + coords[SPACEDIM*i+j]=_coordsU[SPACEDIM*_FMCOO( _connectU[_FMCON (_connIndexU[_FMIU(icell)]+i)])+j]; + } + + _CU_TEMPLATE + int _INTERSECTOR_CU_::getNumberOfRowsOfResMatrix() const + { + return _meshU.getNumberOfElements(); + } + _CU_TEMPLATE + int _INTERSECTOR_CU_::getNumberOfColsOfResMatrix() const + { + return _meshC.getNumberOfElements(); + } + + //================================================================================ + /*! + * \brief Intersects unstructured target cell with structured source cell given by + * its indices + * \param icellU - index of an unstructured element + * \param icellC - i,j,k of a structured element + * \param res - matrix to fill in + */ + //================================================================================ + + _CU_TEMPLATE + void _INTERSECTOR_CU_::intersectCells(CConnType icellU, + const std::vector<CConnType>& icellC, + MyMatrix& res) + { + double v = intersectGeometry(icellU, icellC); + + CConnType iC = icellC[0], area = _nbCellsC[0]; + for ( int j = 1; j < SPACEDIM; ++j ) + { + iC += icellC[j] * area; + area *= _nbCellsC[j]; + } + res[ icellU ][ iC ] = v; + } +} + +#endif diff --git a/src/medtool/src/INTERP_KERNEL/IntersectorCU1D.hxx b/src/medtool/src/INTERP_KERNEL/IntersectorCU1D.hxx new file mode 100644 index 000000000..b22d4e5ab --- /dev/null +++ b/src/medtool/src/INTERP_KERNEL/IntersectorCU1D.hxx @@ -0,0 +1,47 @@ +// Copyright (C) 2009-2015 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, 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 +// 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 +// + +// File : IntersectorCU1D.hxx +// Created : Thu Dec 17 14:10:00 2009 +// Author : Edward AGAPOV (eap) +// +#ifndef __IntersectorCU1D_HXX__ +#define __IntersectorCU1D_HXX__ + +#include "IntersectorCU.hxx" + +namespace INTERP_KERNEL +{ + template<class MyCMeshType, class MyUMeshType, class MyMatrix > + class IntersectorCU1D : public IntersectorCU<MyCMeshType,MyUMeshType,MyMatrix,IntersectorCU1D<MyCMeshType,MyUMeshType,MyMatrix> > + { + public: + typedef typename MyUMeshType::MyConnType UConnType; + typedef typename MyCMeshType::MyConnType CConnType; + public: + IntersectorCU1D(const MyCMeshType& meshS, const MyUMeshType& meshT); + ~IntersectorCU1D(); + double intersectGeometry(UConnType icellT, const std::vector<CConnType>& icellC); + + private: + }; +} + + +#endif diff --git a/src/medtool/src/INTERP_KERNEL/IntersectorCU1D.txx b/src/medtool/src/INTERP_KERNEL/IntersectorCU1D.txx new file mode 100644 index 000000000..832d7b3c1 --- /dev/null +++ b/src/medtool/src/INTERP_KERNEL/IntersectorCU1D.txx @@ -0,0 +1,82 @@ +// Copyright (C) 2009-2015 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, 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 +// 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 +// +// File : IntersectorCU1D.txx +// Created : Thu Dec 17 14:17:49 2009 +// Author : Edward AGAPOV (eap) + +#ifndef __IntersectorCU1D_TXX__ +#define __IntersectorCU1D_TXX__ + +#include "IntersectorCU1D.hxx" +#include "IntersectorCU.txx" + +#define IntersectorCU1D_TEMPLATE template<class MyCMeshType, class MyUMeshType, class MyMatrix> +#define INTERSECTOR_CU1D IntersectorCU1D<MyCMeshType,MyUMeshType,MyMatrix > +#define _INTER_CU IntersectorCU <MyCMeshType,MyUMeshType,MyMatrix,IntersectorCU1D<MyCMeshType,MyUMeshType,MyMatrix> > + +namespace INTERP_KERNEL +{ + //================================================================================ + /*! + * \brief intersector of the unstructured mesh and the cartesian mesh in 1D + */ + //================================================================================ + + IntersectorCU1D_TEMPLATE + INTERSECTOR_CU1D::IntersectorCU1D(const MyCMeshType& meshS, + const MyUMeshType& meshT): + _INTER_CU( meshS, meshT ) + { + if ( MyCMeshType::MY_SPACEDIM != 1 || MyCMeshType::MY_MESHDIM != 1 || + MyUMeshType::MY_SPACEDIM != 1 || MyUMeshType::MY_MESHDIM != 1 ) + throw Exception("IntersectorCU1D(): Invalid mesh dimension, it must be 1"); + } + + //================================================================================ + /*! + * \brief destructor + */ + //================================================================================ + + IntersectorCU1D_TEMPLATE + INTERSECTOR_CU1D::~IntersectorCU1D() + { + } + + //================================================================================ + /*! + * \brief Calculate length of intersection of an unstructured cell and a cartesian one. + * The cartesian cell is given by its [i,j,k] indices + */ + //================================================================================ + + IntersectorCU1D_TEMPLATE + double INTERSECTOR_CU1D::intersectGeometry(UConnType icellT, + const std::vector<CConnType>& icellS) + { + std::vector<double> coordsU; + _INTER_CU::getUCoordinates(icellT, coordsU); + + const double* coordsC = & _INTER_CU::_coordsC[0][ _FMIC(icellS[0]) ]; + + double res = std::min( coordsU[1], coordsC[1] ) - std::max( coordsU[0], coordsC[0] ); + return res; + } +} +#endif diff --git a/src/medtool/src/INTERP_KERNEL/IntersectorCU2D.hxx b/src/medtool/src/INTERP_KERNEL/IntersectorCU2D.hxx new file mode 100644 index 000000000..e034028fa --- /dev/null +++ b/src/medtool/src/INTERP_KERNEL/IntersectorCU2D.hxx @@ -0,0 +1,47 @@ +// Copyright (C) 2009-2015 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, 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 +// 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 +// + +// File : IntersectorCU2D.hxx +// Created : Thu Dec 17 14:10:00 2009 +// Author : Edward AGAPOV (eap) +// +#ifndef __IntersectorCU2D_HXX__ +#define __IntersectorCU2D_HXX__ + +#include "IntersectorCU.hxx" + +namespace INTERP_KERNEL +{ + template<class MyCMeshType, class MyUMeshType, class MyMatrix > + class IntersectorCU2D : public IntersectorCU<MyCMeshType,MyUMeshType,MyMatrix,IntersectorCU2D<MyCMeshType,MyUMeshType,MyMatrix> > + { + public: + typedef typename MyUMeshType::MyConnType UConnType; + typedef typename MyCMeshType::MyConnType CConnType; + public: + IntersectorCU2D(const MyCMeshType& meshS, const MyUMeshType& meshT); + double intersectGeometry(UConnType icellT, const std::vector<CConnType>& icellC); + + private: + TriangulationIntersector<MyUMeshType,MyMatrix,PlanarIntersectorP0P0> _intersector; + }; +} + + +#endif diff --git a/src/medtool/src/INTERP_KERNEL/IntersectorCU2D.txx b/src/medtool/src/INTERP_KERNEL/IntersectorCU2D.txx new file mode 100644 index 000000000..df7c7efb7 --- /dev/null +++ b/src/medtool/src/INTERP_KERNEL/IntersectorCU2D.txx @@ -0,0 +1,76 @@ +// Copyright (C) 2009-2015 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, 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 +// 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 +// +// File : IntersectorCU2D.txx +// Created : Thu Dec 17 14:17:49 2009 +// Author : Edward AGAPOV (eap) + +#ifndef __IntersectorCU2D_TXX__ +#define __IntersectorCU2D_TXX__ + +#include "IntersectorCU2D.hxx" +#include "IntersectorCU.txx" + +#define IntersectorCU2D_TEMPLATE template<class MyCMeshType, class MyUMeshType, class MyMatrix> +#define INTERSECTOR_CU2D IntersectorCU2D<MyCMeshType, MyUMeshType, MyMatrix > +#define INTER_CU IntersectorCU<MyCMeshType,MyUMeshType,MyMatrix,IntersectorCU2D<MyCMeshType,MyUMeshType,MyMatrix> > + + +namespace INTERP_KERNEL +{ + IntersectorCU2D_TEMPLATE + INTERSECTOR_CU2D::IntersectorCU2D(const MyCMeshType& meshS, + const MyUMeshType& meshT): + IntersectorCU<MyCMeshType, MyUMeshType, MyMatrix, IntersectorCU2D<MyCMeshType,MyUMeshType,MyMatrix> >( meshS, meshT ), + _intersector(meshT, meshT, 0,0,0,0,0,0,0 ) + { + if ( MyCMeshType::MY_SPACEDIM != 2 || MyCMeshType::MY_MESHDIM != 2 || + MyUMeshType::MY_SPACEDIM != 2 || MyUMeshType::MY_MESHDIM != 2 ) + throw Exception("IntersectorCU2D(): Invalid mesh dimension, it must be 2"); + } + + + //================================================================================ + /*! + * \brief Calculate area of intersection of an unstructured cell and a cartesian one. + * The cartesian cell is given by its [i,j] indices + */ + //================================================================================ + + IntersectorCU2D_TEMPLATE + double INTERSECTOR_CU2D::intersectGeometry(UConnType icellT, + const std::vector<CConnType>& icellS) + { + std::vector<double> uCoords; + this->getUCoordinates( icellT, uCoords ); + + NormalizedCellType tT = INTER_CU::_meshU.getTypeOfElement( _TMIU(icellT)); + bool is_tgt_quad = CellModel::GetCellModel(tT).isQuadratic(); + + double quad[8] = { INTER_CU::_coordsC[0][icellS[0]], INTER_CU::_coordsC[1][icellS[1]], + INTER_CU::_coordsC[0][icellS[0]+1], INTER_CU::_coordsC[1][icellS[1]], + INTER_CU::_coordsC[0][icellS[0]+1], INTER_CU::_coordsC[1][icellS[1]+1], + INTER_CU::_coordsC[0][icellS[0]], INTER_CU::_coordsC[1][icellS[1]+1] }; + + double surf = _intersector.intersectGeometryWithQuadrangle( quad, + uCoords, + is_tgt_quad); + return surf; + } +} +#endif diff --git a/src/medtool/src/INTERP_KERNEL/IntersectorCU3D.hxx b/src/medtool/src/INTERP_KERNEL/IntersectorCU3D.hxx new file mode 100644 index 000000000..32abb3d0c --- /dev/null +++ b/src/medtool/src/INTERP_KERNEL/IntersectorCU3D.hxx @@ -0,0 +1,55 @@ +// Copyright (C) 2009-2015 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, 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 +// 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 +// + +// File : IntersectorCU3D.hxx +// Created : Thu Dec 17 14:10:00 2009 +// Author : Edward AGAPOV (eap) +// +#ifndef __IntersectorCU3D_HXX__ +#define __IntersectorCU3D_HXX__ + +#include "IntersectorCU.hxx" +#include "SplitterTetra.hxx" + +namespace INTERP_KERNEL +{ + class _Cartesian3D2UnstructHexMesh; + + template<class MyCMeshType, class MyUMeshType, class MyMatrix > + class IntersectorCU3D : public IntersectorCU<MyCMeshType,MyUMeshType,MyMatrix,IntersectorCU3D<MyCMeshType,MyUMeshType,MyMatrix> > + { + public: + typedef typename MyUMeshType::MyConnType UConnType; + typedef typename MyCMeshType::MyConnType CConnType; + public: + IntersectorCU3D(const MyCMeshType& meshS, const MyUMeshType& meshT, SplittingPolicy splitting_policy); + ~IntersectorCU3D(); + double intersectGeometry(UConnType icellT, const std::vector<CConnType>& icellC); + + private: + + typedef SplitterTetra2<MyUMeshType, _Cartesian3D2UnstructHexMesh > TSplitter; + typedef SplitterTetra <_Cartesian3D2UnstructHexMesh > TTetra; + _Cartesian3D2UnstructHexMesh* _uHexMesh; + TSplitter* _split; + }; +} + + +#endif diff --git a/src/medtool/src/INTERP_KERNEL/IntersectorCU3D.txx b/src/medtool/src/INTERP_KERNEL/IntersectorCU3D.txx new file mode 100644 index 000000000..c271120f0 --- /dev/null +++ b/src/medtool/src/INTERP_KERNEL/IntersectorCU3D.txx @@ -0,0 +1,156 @@ +// Copyright (C) 2009-2015 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, 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 +// 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 +// +// File : IntersectorCU3D.txx +// Created : Thu Dec 17 14:17:49 2009 +// Author : Edward AGAPOV (eap) + +#ifndef __IntersectorCU3D_TXX__ +#define __IntersectorCU3D_TXX__ + +#include "IntersectorCU3D.hxx" +#include "IntersectorCU.txx" +#include "SplitterTetra.txx" + +#define IntersectorCU3D_TEMPLATE template<class MyCMeshType, class MyUMeshType, class MyMatrix> +#define INTERSECTOR_CU3D IntersectorCU3D<MyCMeshType,MyUMeshType,MyMatrix > +#define _INTERSECTOR_CU IntersectorCU <MyCMeshType,MyUMeshType,MyMatrix,IntersectorCU3D<MyCMeshType,MyUMeshType,MyMatrix> > + +namespace INTERP_KERNEL +{ + //================================================================================ + /*! + * \brief Unstructured hexahedral mesh derived from cartesian 3D mesh. + * Mesh contains one HEXA8 element + */ + //================================================================================ + + class _Cartesian3D2UnstructHexMesh + { + public: + static const int MY_SPACEDIM=3; + static const int MY_MESHDIM=3; + typedef int MyConnType; + static const NumberingPolicy My_numPol=ALL_C_MODE; + + _Cartesian3D2UnstructHexMesh(const double * coords[3]): _coordsC(coords) {} + void setHexa(int I, int J, int K) // indices in C mode + { + double* pCoord = _coordsU; + for ( int k = K; k < K+2; ++k ) + for ( int j = J; j < J+2; ++j ) + for ( int i = I; i < I+2; ++i ) + { + *pCoord++ = _coordsC[0][i]; + *pCoord++ = _coordsC[1][j]; + *pCoord++ = _coordsC[2][k]; + } + } + const int *getConnectivityPtr() const + { + static int conn[] = { 1,0,2,3,5,4,6,7 }; + return conn; + } + const int *getConnectivityIndexPtr() const + { + static int conInd[] = { 0,8 }; + return conInd; + } + void getBoundingBox(double *boundingBox) const + { + boundingBox[BoundingBox::XMIN] = _coordsU[0]; + boundingBox[BoundingBox::XMAX] = _coordsU[0+1*MY_SPACEDIM]; + boundingBox[BoundingBox::YMIN] = _coordsU[1]; + boundingBox[BoundingBox::YMAX] = _coordsU[1+2*MY_SPACEDIM]; + boundingBox[BoundingBox::ZMIN] = _coordsU[2]; + boundingBox[BoundingBox::ZMAX] = _coordsU[2+4*MY_SPACEDIM]; + } + NormalizedCellType getTypeOfElement(int eltId) const { return NORM_HEXA8; } + unsigned char getNumberOfNodesOfElement(int eltId) const { return 8; } + unsigned long getNumberOfElements() const { return 1; } + unsigned long getNumberOfNodes() const { return 8; } + const double *getCoordinatesPtr() const { return _coordsU; } + void releaseTempArrays() {} + private: + const double** _coordsC; + double _coordsU[3*8]; + }; + + //================================================================================ + /*! + * \brief intersector of the unstructured mesh and the cartesian mesh in 3D + */ + //================================================================================ + + IntersectorCU3D_TEMPLATE + INTERSECTOR_CU3D::IntersectorCU3D(const MyCMeshType& meshS, + const MyUMeshType& meshT, + SplittingPolicy splitting_policy): + _INTERSECTOR_CU( meshS, meshT ) + { + if ( MyCMeshType::MY_SPACEDIM != 3 || MyCMeshType::MY_MESHDIM != 3 || + MyUMeshType::MY_SPACEDIM != 3 || MyUMeshType::MY_MESHDIM != 3 ) + throw Exception("IntersectorCU3D(): Invalid mesh dimension, it must be 3"); + + _uHexMesh = new _Cartesian3D2UnstructHexMesh( _INTERSECTOR_CU::_coordsC ); + _split = new TSplitter( meshT, *_uHexMesh, splitting_policy ); + } + + //================================================================================ + /*! + * \brief destructor + */ + //================================================================================ + + IntersectorCU3D_TEMPLATE + INTERSECTOR_CU3D::~IntersectorCU3D() + { + delete _uHexMesh; _uHexMesh=0; + delete _split; _split=0; + } + + //================================================================================ + /*! + * \brief Calculate volume of intersection of an unstructured cell and a cartesian one. + * The cartesian cell is given by its [i,j,k] indices + */ + //================================================================================ + + IntersectorCU3D_TEMPLATE + double INTERSECTOR_CU3D::intersectGeometry(UConnType icellT, + const std::vector<CConnType>& icellS) + { + // split an unstructured cell into tetra + std::vector< TTetra* > tetra; + UConnType nb_nodes = + _INTERSECTOR_CU::_connIndexU[icellT+1] - _INTERSECTOR_CU::_connIndexU[icellT]; + _split->releaseArrays(); + _split->splitTargetCell( icellT, nb_nodes, tetra); + + // intersect a cartesian 3d cell with tetra + _uHexMesh->setHexa( _FMIC(icellS[0]),_FMIC(icellS[1]),_FMIC(icellS[2])); // set cell at i,j,k + double res = 0; + for ( unsigned int t = 0; t < tetra.size(); ++t ) + { + res += tetra[t]->intersectSourceCell( 0 ); + delete tetra[t]; + } + return res; + } +} +#endif diff --git a/src/medtool/src/INTERP_KERNEL/Log.hxx b/src/medtool/src/INTERP_KERNEL/Log.hxx new file mode 100644 index 000000000..3f0e35157 --- /dev/null +++ b/src/medtool/src/INTERP_KERNEL/Log.hxx @@ -0,0 +1,66 @@ +// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 +// 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 _LOG_H_ +#define _LOG_H_ + +/** + * \file Log.hxx + * \brief Simple pre-processor logging utility. + * + * Replaces LOG( lvl, x ) with "if(lvl <= LOG_LEVEL) std::cout << x << std::endl" when logging is active + * (LOG_LEVEL > 0 is defined). x is the level at which the message should be logged - if it is smaller or equal to + * LOG_LEVEL (which can be defined at compile-time for each file by passing option -DLOG_LEVEL=x to gcc) + * than the message is logged. + * + * + * + */ + +/// define LOG_LEVEL here if it is not already defined +#ifndef LOG_LEVEL +#define LOG_LEVEL 0 +#endif + +#if LOG_LEVEL > 0 + +#include <iostream> + +/// write message msg to std::cout if x <= LOG_LEVEL +#define LOG(x, msg) if(x <= LOG_LEVEL) std::cout << msg << std::endl; +#define LOG3( x , msg1 , msg2 ) if(x <= LOG_LEVEL) std::cout << msg1, msg2 << std::endl; + +#else + +#define LOG( x , msg ) +#define LOG3( x , msg1 , msg2 ) + +#endif + + + + + + + + + + + +#endif diff --git a/src/medtool/src/INTERP_KERNEL/MeshElement.cxx b/src/medtool/src/INTERP_KERNEL/MeshElement.cxx new file mode 100644 index 000000000..696d30b18 --- /dev/null +++ b/src/medtool/src/INTERP_KERNEL/MeshElement.cxx @@ -0,0 +1,37 @@ +// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// + +#include "MeshElement.hxx" + +namespace INTERP_KERNEL +{ + ///////////////////////////////////////////////////////////////////// + /// ElementBBoxOrder ///////////// + ///////////////////////////////////////////////////////////////////// + /** + * Constructor + * + * @param coord BoundingBox coordinate (XMIN, XMAX, etc) on which to base the ordering + */ + ElementBBoxOrder::ElementBBoxOrder(BoundingBox::BoxCoord coord) + : _coord(coord) + { + } +} + diff --git a/src/medtool/src/INTERP_KERNEL/MeshElement.hxx b/src/medtool/src/INTERP_KERNEL/MeshElement.hxx new file mode 100644 index 000000000..3fb6ab652 --- /dev/null +++ b/src/medtool/src/INTERP_KERNEL/MeshElement.hxx @@ -0,0 +1,87 @@ +// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 +// 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 __MESHELEMENT_HXX__ +#define __MESHELEMENT_HXX__ + +#include "BoundingBox.hxx" + +namespace INTERP_KERNEL +{ + + /** + * \brief Class representing a single element of a mesh together with its bounding box. + * It gives access to the element's global number, type and bounding box and allows + * easy bounding box intersection tests between MeshElements and collections of MeshElement (MeshRegions) + */ + template<class ConnType> + class MeshElement + { + + public: + template<class MyMeshType> + MeshElement(const ConnType index, const MyMeshType& mesh); + + ~MeshElement(); + + ConnType getIndex() const { return _index; } + + unsigned char getNumberOfNodes() const { return _number; } + + const BoundingBox* getBoundingBox() const { return _box; } + + private: + /// disallow copying + MeshElement(const MeshElement& elem); + + /// disallow assignment + MeshElement& operator=(const MeshElement& elem); + + /// global number of the element + const ConnType _index; + + const unsigned char _number; + + /// bounding box of the element - does not change after having been initialised + BoundingBox* _box; + }; + + /** + * \brief Class defining an order for MeshElements based on their bounding boxes. + * The order defined between two elements is that between a given coordinate of + * their bounding boxes. For instance, if the order is based on YMIN, an element whose boxes + * has a smaller YMIN is sorted before one with a larger YMIN. + * + */ + class ElementBBoxOrder + { + public : + + ElementBBoxOrder(BoundingBox::BoxCoord coord); + template<class ConnType> + bool operator()(MeshElement<ConnType>* elem1, MeshElement<ConnType>* elem2); + + private : + /// BoundingBox coordinate (XMIN, XMAX, etc) on which to base the ordering + BoundingBox::BoxCoord _coord; + }; + +} + +#endif diff --git a/src/medtool/src/INTERP_KERNEL/MeshElement.txx b/src/medtool/src/INTERP_KERNEL/MeshElement.txx new file mode 100644 index 000000000..0da39e0a0 --- /dev/null +++ b/src/medtool/src/INTERP_KERNEL/MeshElement.txx @@ -0,0 +1,95 @@ +// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 +// 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 __MESHELEMENT_TXX__ +#define __MESHELEMENT_TXX__ + +#include "MeshElement.hxx" + +#include "TetraAffineTransform.hxx" +#include "TransformedTriangle.hxx" +#include "MeshUtils.hxx" +#include "BoundingBox.hxx" +#include <assert.h> + +namespace INTERP_KERNEL +{ + + /** + * Constructor + * + * @param index global number of element in the mesh in C mode. + * @param mesh mesh that the element belongs to + */ + template<class ConnType> + template<class MyMeshType> + MeshElement<ConnType>::MeshElement(const ConnType index, const MyMeshType& mesh) + : _index(index), _number(mesh.getNumberOfNodesOfElement(OTT<typename MyMeshType::MyConnType,MyMeshType::My_numPol>::indFC(index))), _box(0) + { + const double**vertices = new const double*[_number]; + + for(unsigned char i = 0 ; i < _number ; ++i) + vertices[i] = getCoordsOfNode(i , OTT<typename MyMeshType::MyConnType,MyMeshType::My_numPol>::indFC(index), mesh); + + // create bounding box + _box = new BoundingBox(vertices,_number); + delete [] vertices; + } + + /** + * Destructor + * + */ + template<class ConnType> + MeshElement<ConnType>::~MeshElement() + { + delete _box; + } + + + + ///////////////////////////////////////////////////////////////////// + /// ElementBBoxOrder ///////////// + ///////////////////////////////////////////////////////////////////// + + /** + * Comparison operator based on the bounding boxes of the elements + * + * @return true if the coordinate _coord of the bounding box of elem1 is + * strictly smaller than that of the bounding box of elem2 + */ + template<class ConnType> + bool ElementBBoxOrder::operator()( MeshElement<ConnType>* elem1, MeshElement<ConnType>* elem2) + { + const BoundingBox* box1 = elem1->getBoundingBox(); + const BoundingBox* box2 = elem2->getBoundingBox(); + + assert(elem1 != 0); + assert(elem2 != 0); + assert(box1 != 0); + assert(box2 != 0); + + const double coord1 = box1->getCoordinate(_coord); + const double coord2 = box2->getCoordinate(_coord); + + return coord1 < coord2; + } + +} + +#endif diff --git a/src/medtool/src/INTERP_KERNEL/MeshRegion.hxx b/src/medtool/src/INTERP_KERNEL/MeshRegion.hxx new file mode 100644 index 000000000..6baf33e34 --- /dev/null +++ b/src/medtool/src/INTERP_KERNEL/MeshRegion.hxx @@ -0,0 +1,93 @@ +// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 +// 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 __MESHREGION_HXX__ +#define __MESHREGION_HXX__ + +#include "MeshElement.hxx" +#include "BoundingBox.hxx" +#include "NormalizedUnstructuredMesh.hxx" + +#include <vector> + +namespace INTERP_KERNEL +{ + /** + * \brief Class representing a set of elements in a mesh together with their bounding box. + * It permits to split itself in two, which is used in the depth-first search filtering process. + * + */ + template<class ConnType> + class MeshRegion + { + public: + + MeshRegion(); + + ~MeshRegion(); + + template<class MyMeshType> + void addElement(MeshElement<ConnType>* const element, const MyMeshType& mesh); + + template<class MyMeshType> + void split(MeshRegion<ConnType>& region1, MeshRegion<ConnType>& region2, BoundingBox::BoxCoord coord, const MyMeshType& mesh); + + bool isDisjointWithElementBoundingBox(const MeshElement<ConnType>& elem) const; + /** + * Accessor to beginning of elements vector + * + * @return constant iterator pointing at the beginning of the vector or elements + */ + typename std::vector< MeshElement<ConnType>* >::const_iterator getBeginElements() const { return _elements.begin(); } + + /** + * Accessor to end of elements vector + * + * @return constant iterator pointing at the end of the vector or elements + */ + typename std::vector< MeshElement<ConnType>* >::const_iterator getEndElements() const { return _elements.end(); } + + /** + * Gives information on how many elements are contained in the region. + * + * @return the number of elements contained in the region + */ + unsigned getNumberOfElements() const { return _elements.size(); } + + private: + + /// disallow copying + MeshRegion(const MeshRegion& m); + + /// disallow assignment + MeshRegion<ConnType>& operator=(const MeshRegion<ConnType>& m); + + /// Vector of pointers to contained MeshElements. + /// NB : these pointers are not owned by the region object, and are thus + /// neither allocated or liberated in this class. The elements must therefore be allocated and liberated outside the class. + std::vector< MeshElement<ConnType>* > _elements; + + /// BoundingBox containing all the nodes of all the elements in the region. + BoundingBox* _box; + + }; + +} + +#endif diff --git a/src/medtool/src/INTERP_KERNEL/MeshRegion.txx b/src/medtool/src/INTERP_KERNEL/MeshRegion.txx new file mode 100644 index 000000000..6183b9b7c --- /dev/null +++ b/src/medtool/src/INTERP_KERNEL/MeshRegion.txx @@ -0,0 +1,153 @@ +// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 +// 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 __MESHREGION_TXX__ +#define __MESHREGION_TXX__ + +#include "MeshRegion.hxx" + +#include "MeshElement.txx" +#include "MeshUtils.hxx" + +namespace INTERP_KERNEL +{ + + /** + * Default constructor + * + */ + template<class ConnType> + MeshRegion<ConnType>::MeshRegion():_box(0) + { + } + + /** + * Destructor + * + */ + template<class ConnType> + MeshRegion<ConnType>::~MeshRegion() + { + delete _box; + } + + /** + * Adds an element to the region, updating the bounding box. If the bounding box does not yet + * exist, it is created here. This creation is delayed to make it possible to have empty MeshRegions + * + * @param element pointer to element to add to region + * @param mesh mesh to which element belongs + * + */ + template<class ConnType> + template<class MyMeshType> + void MeshRegion<ConnType>::addElement(MeshElement<ConnType>* const element, const MyMeshType& mesh) + { + _elements.push_back(element); + + const unsigned char numNodes = element->getNumberOfNodes(); + const ConnType elemIdx = element->getIndex(); + + if(_box == 0) + { + const double** pts = new const double*[numNodes]; + + // get coordinates of the nodes of the element + for(unsigned char i = 0 ; i < numNodes ; ++i) + { + pts[i] = getCoordsOfNode(i, OTT<typename MyMeshType::MyConnType,MyMeshType::My_numPol>::indFC(elemIdx), mesh); + } + + _box = new BoundingBox(pts, numNodes); + delete [] pts; + + } else { + + for(unsigned char i = 0 ; i < numNodes ; ++i) + { + const double* pt = getCoordsOfNode(i, OTT<typename MyMeshType::MyConnType,MyMeshType::My_numPol>::indFC(elemIdx), mesh); + _box->updateWithPoint(pt); + } + } + } + + /** + * Splits the region in two along the given axis, copying the elements with bounding boxes whose maximum + * coordinate along the axis are smaller than the middle of the bounding box of this region in region1. The + * rest of the elements are copied to region2. + * + * @param region1 region in which to store one half of this region + * @param region2 region in which to store the other of this region + * @param coord coordinate of BoundingBox to use when splitting the region + * @param mesh mesh to which region belongs + * + */ + template<class ConnType> + template<class MyMeshType> + void MeshRegion<ConnType>::split(MeshRegion<ConnType>& region1, MeshRegion<ConnType>& region2, BoundingBox::BoxCoord coord, const MyMeshType& mesh) + { + // create ordering + ElementBBoxOrder cmp(coord); + + // sort elements by their bounding boxes + std::sort(_elements.begin(), _elements.end(), cmp); + + // put the first half of the elements in region1 and the + // rest in region2 + typename std::vector< MeshElement<ConnType> *>::const_iterator iter = _elements.begin(); + int elemCount = 0; + + while(elemCount < static_cast<int>(_elements.size() / 2)) + { + region1.addElement(*iter, mesh); + ++iter; + ++elemCount; + } + + while(iter != _elements.end()) + { + region2.addElement(*iter, mesh); + ++iter; + } + } + + /** + * Determines if a given element can intersect the elements of this region by + * testing whether the bounding box of the region intersects the bounding box of the element. + * Note that the test is only true in one direction : if the bounding boxes are disjoint, the + * element cannot intersect any of the elements in the region, but if they are not disjoint, the + * element may or may not do so. + * + * @param elem Element with which to test for disjoint-ness + * @return true if the bounding box of the element is disjoint with the bounding box of the region, false otherwise + */ + template<class ConnType> + bool MeshRegion<ConnType>::isDisjointWithElementBoundingBox(const MeshElement<ConnType>& elem) const + { + const BoundingBox* elemBox = elem.getBoundingBox(); + + assert(_box != 0); + assert(elemBox != 0); + + return _box->isDisjointWith(*elemBox); + } + + +} + +#endif diff --git a/src/medtool/src/INTERP_KERNEL/MeshUtils.hxx b/src/medtool/src/INTERP_KERNEL/MeshUtils.hxx new file mode 100644 index 000000000..6f751d134 --- /dev/null +++ b/src/medtool/src/INTERP_KERNEL/MeshUtils.hxx @@ -0,0 +1,114 @@ +// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 +// 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 __MESHUTILS_HXX__ +#define __MESHUTILS_HXX__ + +#include "InterpolationUtils.hxx" + +namespace INTERP_KERNEL +{ + /** + * Returns the global number of the node of an element. + * + * @param node the node for which the global number is sought (ALWAYS in C mode) + * @param element an element of the mesh (in numPol policy) + * @param mesh a mesh + * @return the node's global number so that (its coordinates in the coordinates array are at [SPACEDIM*globalNumber, SPACEDIM*globalNumber + SPACEDIM] + */ + template<class MyMeshType> + inline typename MyMeshType::MyConnType getGlobalNumberOfNode(typename MyMeshType::MyConnType node, typename MyMeshType::MyConnType element, const MyMeshType& mesh) + { + typedef typename MyMeshType::MyConnType ConnType; + const NumberingPolicy numPol=MyMeshType::My_numPol; + const ConnType elemIdx=OTT<ConnType,numPol>::conn2C(mesh.getConnectivityIndexPtr()[OTT<ConnType,numPol>::ind2C(element)]); + if(mesh.getTypeOfElement(element)!=INTERP_KERNEL::NORM_POLYHED) + return OTT<ConnType,numPol>::coo2C(mesh.getConnectivityPtr()[elemIdx + node]); + else + { + const ConnType *startNodalConnOfElem=mesh.getConnectivityPtr()+elemIdx; + ConnType ptr=0,ret=0; + while(startNodalConnOfElem[ret]==-1 || ptr!=node) + { + ret++; + if(startNodalConnOfElem[ret]!=-1) + ptr++; + } + return OTT<ConnType,numPol>::coo2C(startNodalConnOfElem[ret]); + } + } + + /** + * Returns the coordinates of a node of an element + * + * @param node the node for which the coordinates are sought. In C mode. + * @param element an element of the mesh. In mesh policy. + * @param mesh a mesh + * @return pointer to an array of 3 doubles containing the coordinates of the node + */ + template<class MyMeshType> + inline const double* getCoordsOfNode(typename MyMeshType::MyConnType node, typename MyMeshType::MyConnType element, const MyMeshType& mesh) + { + typedef typename MyMeshType::MyConnType ConnType; + const ConnType connIdx = getGlobalNumberOfNode(node, element, mesh); + const double *ret=mesh.getCoordinatesPtr()+MyMeshType::MY_SPACEDIM*connIdx; + return ret; + } + + /** + * Returns the coordinates of a node of an element + * + * @param node the node for which the coordinates are sought. In C mode. + * @param element an element of the mesh. In mesh policy. + * @param mesh a mesh + * @param nodeId globale nodeId in whole mesh point of view in C mode. + * @return pointer to an array of 3 doubles containing the coordinates of the node + */ + template<class MyMeshType> + inline const double* getCoordsOfNode2(typename MyMeshType::MyConnType node, typename MyMeshType::MyConnType element, const MyMeshType& mesh, typename MyMeshType::MyConnType& nodeId) + { + nodeId= getGlobalNumberOfNode(node, element, mesh); + return mesh.getCoordinatesPtr()+MyMeshType::MY_SPACEDIM*nodeId; + } + + /** + * Returns the barycentric coordinates of a point within a triangle or tetrahedron + * + * @param point the point for which the barycentric coordinates are sought + * @param element an element of the mesh + * @param mesh a mesh + * @param barycentricCoords an array of 3 doubles containing the coordinates of the node + */ + template<class MyMeshType, int NB_NODES> + inline void getBarycentricCoordinates(const double* point, + typename MyMeshType::MyConnType element, + const MyMeshType& mesh, + double* barycentricCoords) + { + std::vector<const double*> nodes( NB_NODES ); + for ( int node = 0; node < NB_NODES; ++node ) + { + nodes[ node ] = getCoordsOfNode( node, element, mesh ); + } + barycentric_coords( nodes, point, barycentricCoords ); + } + +} + +#endif diff --git a/src/medtool/src/INTERP_KERNEL/Planar2D1DIntersectorP0P0.hxx b/src/medtool/src/INTERP_KERNEL/Planar2D1DIntersectorP0P0.hxx new file mode 100644 index 000000000..4356a1c21 --- /dev/null +++ b/src/medtool/src/INTERP_KERNEL/Planar2D1DIntersectorP0P0.hxx @@ -0,0 +1,60 @@ +// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 +// 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 __PLANAR2D1DINTERSECTORP0P0_HXX__ +#define __PLANAR2D1DINTERSECTORP0P0_HXX__ + +#include "PlanarIntersector.hxx" + +namespace INTERP_KERNEL +{ + template<class MyMeshType, class MyMatrix, class ConcreteP0P0Intersector> + class Planar2D1DIntersectorP0P0 : public PlanarIntersector<MyMeshType,MyMatrix> + { + public: + static const int SPACEDIM=MyMeshType::MY_SPACEDIM; + static const int MESHDIM=MyMeshType::MY_MESHDIM; + typedef typename MyMeshType::MyConnType ConnType; + static const NumberingPolicy numPol=MyMeshType::My_numPol; + protected: + Planar2D1DIntersectorP0P0(const MyMeshType& meshT, const MyMeshType& meshS, + double dimCaracteristic, double precision, double md3DSurf, double minDot3DSurf, double medianPlane, bool doRotate, int orientation, int printLevel); + public: + int getNumberOfRowsOfResMatrix() const; + int getNumberOfColsOfResMatrix() const; + const typename PlanarIntersector<MyMeshType,MyMatrix>::DuplicateFacesType* getIntersectFaces() const + { + return &_intersect_faces; + } + void intersectCells(ConnType icellT, const std::vector<ConnType>& icellsS, MyMatrix& res); + /*! + * Contrary to intersectCells method here icellS and icellT are \b not in \b C mode but in mode of MyMeshType. + */ + double intersectGeometry1D(ConnType icellT, ConnType icellS, ConnType nbNodesT, ConnType nbNodesS, + bool& isColinear) + { return asLeaf().intersectGeometry1D(icellT,icellS,nbNodesT,nbNodesS, isColinear); } + protected: + ConcreteP0P0Intersector& asLeaf() { return static_cast<ConcreteP0P0Intersector&>(*this); } + private: + typename PlanarIntersector<MyMeshType,MyMatrix>::DuplicateFacesType _intersect_faces; + }; +} + +#endif diff --git a/src/medtool/src/INTERP_KERNEL/Planar2D1DIntersectorP0P0.txx b/src/medtool/src/INTERP_KERNEL/Planar2D1DIntersectorP0P0.txx new file mode 100644 index 000000000..848a8f592 --- /dev/null +++ b/src/medtool/src/INTERP_KERNEL/Planar2D1DIntersectorP0P0.txx @@ -0,0 +1,81 @@ +// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 +// 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 __PLANAR2D1DINTERSECTORP0P0_TXX__ +#define __PLANAR2D1DINTERSECTORP0P0_TXX__ + +#include "Planar2D1DIntersectorP0P0.hxx" + +namespace INTERP_KERNEL +{ + template<class MyMeshType, class MyMatrix, class ConcreteP0P0Intersector> + Planar2D1DIntersectorP0P0<MyMeshType,MyMatrix,ConcreteP0P0Intersector>::Planar2D1DIntersectorP0P0(const MyMeshType& meshT, const MyMeshType& meshS, + double dimCaracteristic, double precision, double md3DSurf, double minDot3DSurf, double medianPlane, + bool doRotate, int orientation, int printLevel): + PlanarIntersector<MyMeshType,MyMatrix>(meshT,meshS,dimCaracteristic,precision,md3DSurf,minDot3DSurf,medianPlane,doRotate,orientation,printLevel) + { + } + + template<class MyMeshType, class MyMatrix, class ConcreteP0P0Intersector> + int Planar2D1DIntersectorP0P0<MyMeshType,MyMatrix,ConcreteP0P0Intersector>::getNumberOfRowsOfResMatrix() const + { + return PlanarIntersector<MyMeshType,MyMatrix>::_meshT.getNumberOfElements(); + } + + template<class MyMeshType, class MyMatrix, class ConcreteP0P0Intersector> + int Planar2D1DIntersectorP0P0<MyMeshType,MyMatrix,ConcreteP0P0Intersector>::getNumberOfColsOfResMatrix() const + { + return PlanarIntersector<MyMeshType,MyMatrix>::_meshS.getNumberOfElements(); + } + + template<class MyMeshType, class MyMatrix, class ConcreteP0P0Intersector> + void Planar2D1DIntersectorP0P0<MyMeshType,MyMatrix,ConcreteP0P0Intersector>::intersectCells(ConnType icellT, const std::vector<ConnType>& icellsS, MyMatrix& res) + { + int nbNodesT=PlanarIntersector<MyMeshType,MyMatrix>::_connIndexT[icellT+1]-PlanarIntersector<MyMeshType,MyMatrix>::_connIndexT[icellT]; + typename MyMatrix::value_type& resRow=res[icellT]; + for(typename std::vector<ConnType>::const_iterator iter=icellsS.begin();iter!=icellsS.end();iter++) + { + int iS=*iter; + int nbNodesS=PlanarIntersector<MyMeshType,MyMatrix>::_connIndexS[iS+1]-PlanarIntersector<MyMeshType,MyMatrix>::_connIndexS[iS]; + bool isColinear = false; + double surf=intersectGeometry1D(OTT<ConnType,numPol>::indFC(icellT),OTT<ConnType,numPol>::indFC(iS), + nbNodesT,nbNodesS, isColinear); + surf=PlanarIntersector<MyMeshType,MyMatrix>::getValueRegardingOption(surf); + if(surf!=0.) + resRow.insert(std::make_pair(OTT<ConnType,numPol>::indFC(iS),surf)); + + if (isColinear) + { + typename PlanarIntersector<MyMeshType,MyMatrix>::DuplicateFacesType::iterator intersectFacesIter = _intersect_faces.find(iS); + if (intersectFacesIter != _intersect_faces.end()) + { + intersectFacesIter->second.insert(icellT); + } + else + { + std::set<int> targetCellSet; + targetCellSet.insert(icellT); + _intersect_faces.insert(std::make_pair(iS, targetCellSet)); + } + } + } + } +} + +#endif diff --git a/src/medtool/src/INTERP_KERNEL/PlanarIntersector.hxx b/src/medtool/src/INTERP_KERNEL/PlanarIntersector.hxx new file mode 100644 index 000000000..b0662104c --- /dev/null +++ b/src/medtool/src/INTERP_KERNEL/PlanarIntersector.hxx @@ -0,0 +1,85 @@ +// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 +// 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 __PLANARINTERSECTOR_HXX__ +#define __PLANARINTERSECTOR_HXX__ + +#include "TargetIntersector.hxx" +#include "NormalizedUnstructuredMesh.hxx" + +#include <map> +#include <set> + +namespace INTERP_KERNEL +{ + class TranslationRotationMatrix; + + template<class MyMeshType, class MyMatrix> + class PlanarIntersector : public TargetIntersector<MyMeshType,MyMatrix> + { + public: + static const int SPACEDIM=MyMeshType::MY_SPACEDIM; + static const int MESHDIM=MyMeshType::MY_MESHDIM; + typedef typename MyMeshType::MyConnType ConnType; + static const NumberingPolicy numPol=MyMeshType::My_numPol; + typedef typename std::map<int,std::set<int> > DuplicateFacesType; + public: + PlanarIntersector(const MyMeshType& meshT, const MyMeshType& meshS, double dimCaracteristic, double precision, double md3DSurf, double minDot3DSurf, double medianPlane, bool doRotate, int orientation, int printLevel); + virtual ~PlanarIntersector(); + void createBoundingBoxes(const MyMeshType& mesh, std::vector<double>& bbox); + void adjustBoundingBoxes(std::vector<double>& bbox, double surf3DAdjustmentEps, double surf3DAdjustmentEpsAbs); + inline void getElemBB(double* bb, const MyMeshType& mesh, ConnType iP, ConnType nb_nodes); + static int Projection(double *Coords_A, double *Coords_B, + int nb_NodesA, int nb_NodesB, double epsilon, double md3DSurf, double minDot3DSurf, double median_plane, bool do_rotate); + virtual const DuplicateFacesType* getIntersectFaces() const + { + return NULL; + } + protected : + int projectionThis(double *Coords_A, double *Coords_B, int nb_NodesA, int nb_NodesB); + void getRealTargetCoordinates(ConnType icellT, std::vector<double>& coordsT); + void getRealSourceCoordinates(ConnType icellS, std::vector<double>& coordsS); + void getRealTargetCoordinatesPermute(ConnType icellT, int offset, std::vector<double>& coordsT); + void getRealSourceCoordinatesPermute(ConnType icellS, int offset, std::vector<double>& coordsS); + void getRealCoordinates(ConnType icellT, ConnType icellS, ConnType nbNodesT, ConnType nbNodesS, std::vector<double>& coordsT, std::vector<double>& coordsS, int& orientation); + double getValueRegardingOption(double val) const; + static void rotate3DTriangle( double* PP1, double*PP2, double*PP3, + TranslationRotationMatrix& rotation_matrix); + protected: + const ConnType *_connectT; + const ConnType *_connectS; + const double *_coordsT; + const double *_coordsS; + const ConnType *_connIndexT; + const ConnType *_connIndexS; + const MyMeshType& _meshT; + const MyMeshType& _meshS; + double _dim_caracteristic; + double _max_distance_3Dsurf_intersect; + double _min_dot_btw_3Dsurf_intersect; + double _precision; + double _median_plane; + bool _do_rotate; + int _orientation; + int _print_level; + }; +} + +#endif diff --git a/src/medtool/src/INTERP_KERNEL/PlanarIntersector.txx b/src/medtool/src/INTERP_KERNEL/PlanarIntersector.txx new file mode 100644 index 000000000..ebaf24cb0 --- /dev/null +++ b/src/medtool/src/INTERP_KERNEL/PlanarIntersector.txx @@ -0,0 +1,447 @@ +// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 +// 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 __PLANARINTERSECTOR_TXX__ +#define __PLANARINTERSECTOR_TXX__ + +#include "PlanarIntersector.hxx" +#include "InterpolationUtils.hxx" +#include "TranslationRotationMatrix.hxx" + +#include <iostream> +#include <limits> + +namespace INTERP_KERNEL +{ + template<class MyMeshType, class MyMatrix> + PlanarIntersector<MyMeshType,MyMatrix>::PlanarIntersector(const MyMeshType& meshT, const MyMeshType& meshS, double dimCaracteristic, double precision, double md3DSurf, double minDot3DSurf, double medianPlane, bool doRotate, int orientation, int printLevel): + _meshT(meshT),_meshS(meshS), + _dim_caracteristic(dimCaracteristic),_max_distance_3Dsurf_intersect(md3DSurf),_min_dot_btw_3Dsurf_intersect(minDot3DSurf),_precision(precision),_median_plane(medianPlane), + _do_rotate(doRotate),_orientation(orientation),_print_level(printLevel) + { + _connectT=meshT.getConnectivityPtr(); + _connectS=meshS.getConnectivityPtr(); + _connIndexT=meshT.getConnectivityIndexPtr(); + _connIndexS=meshS.getConnectivityIndexPtr(); + _coordsT=meshT.getCoordinatesPtr(); + _coordsS=meshS.getCoordinatesPtr(); + } + + template<class MyMeshType, class MyMatrix> + PlanarIntersector<MyMeshType,MyMatrix>::~PlanarIntersector() + { + } + + /*! + \brief creates the bounding boxes for all the cells of mesh \a mesh + + The method accepts mixed meshes (containing triangles and quadrangles). + The vector returned is of dimension 6*nb_elems with bounding boxes stored as xmin1, xmax1, ymin1, ymax1, zmin1, zmax1, xmin2, xmax2, ymin2,... + The returned pointer must be deleted by the calling code. + + \param mesh structure pointing to the mesh + \param bbox vector containing the bounding boxes + */ + template<class MyMeshType, class MyMatrix> + void PlanarIntersector<MyMeshType,MyMatrix>::createBoundingBoxes(const MyMeshType& mesh, std::vector<double>& bbox) + { + /* We build the segment tree for locating possible matching intersections*/ + long nbelems = mesh.getNumberOfElements(); + bbox.resize(2*SPACEDIM* nbelems); + const double* coords = mesh.getCoordinatesPtr(); + const ConnType* conn = mesh.getConnectivityPtr(); + const ConnType* conn_index = mesh.getConnectivityIndexPtr(); + int ibox=0; + for(long icell=0; icell<nbelems; icell++) + { + int nb_nodes_per_elem =conn_index[icell+1]-conn_index[icell]; + //initializing bounding box limits + for(int idim=0; idim<SPACEDIM; idim++) + { + bbox[2*SPACEDIM*ibox+2*idim] = std::numeric_limits<double>::max(); + bbox[2*SPACEDIM*ibox+2*idim+1] = -std::numeric_limits<double>::max(); + } + //updating the bounding box with each node of the element + for (int j=0; j<nb_nodes_per_elem; j++) + { + const double* coord_node=coords+SPACEDIM*OTT<ConnType,numPol>::coo2C(conn[OTT<ConnType,numPol>::conn2C(conn_index[icell]+j)]); + for(int idim=0; idim<SPACEDIM; idim++) + { + double x=*(coord_node+idim); + bbox[ibox*2*SPACEDIM + 2*idim] = (bbox[ibox*2*SPACEDIM + 2*idim] <x)?bbox[ibox*2*SPACEDIM + 2*idim ]:x; + bbox[ibox*2*SPACEDIM + 2*idim+1] = (bbox[ibox*2*SPACEDIM + 2*idim+1]>x)?bbox[ibox*2*SPACEDIM + 2*idim+1]:x; + } + } + ibox++; + } + } + + /*! + Computes the bouding box of a given element. iP in numPol mode. + */ + template<class MyMeshType, class MyMatrix> + void PlanarIntersector<MyMeshType,MyMatrix>::getElemBB(double* bb, const MyMeshType& mesh, ConnType iP, ConnType nb_nodes) + { + const double* coords = mesh.getCoordinatesPtr(); + const ConnType* conn_index = mesh.getConnectivityIndexPtr(); + const ConnType* conn = mesh.getConnectivityPtr(); + //initializing bounding box limits + for(int idim=0; idim<SPACEDIM; idim++) + { + bb[2*idim ] = std::numeric_limits<double>::max(); + bb[2*idim+1] = -std::numeric_limits<double>::max(); + } + + for (ConnType i=0; i<nb_nodes; i++) + { + //MN: iP= cell index, not node index, use of connectivity array ? + const double* coord_node=coords+SPACEDIM*(OTT<ConnType,numPol>::coo2C(conn[OTT<ConnType,numPol>::conn2C(conn_index[OTT<ConnType,numPol>::ind2C(iP)]+i)])); + for(int idim=0; idim<SPACEDIM; idim++) + { + double x = *(coord_node+idim); + //double y = *(mesh.getCoordinates(MED_FULL_INTERLACE)+3*(iP+i)+1); + bb[2*idim ] = (x<bb[2*idim ])?x:bb[2*idim ]; + bb[2*idim+1] = (x>bb[2*idim+1])?x:bb[2*idim+1]; + } + } + } + + /*! Readjusts a set of bounding boxes so that they are extended + in all dimensions for avoiding missing interesting intersections + + \param bbox vector containing the bounding boxes + */ + template<class MyMeshType, class MyMatrix> + void PlanarIntersector<MyMeshType,MyMatrix>::adjustBoundingBoxes(std::vector<double>& bbox, double surf3DAdjustmentEps, double surf3DAdjustmentEpsAbs) + { + /* We build the segment tree for locating possible matching intersections*/ + + long size = bbox.size()/(2*SPACEDIM); + for (int i=0; i<size; i++) + { + double max=- std::numeric_limits<double>::max(); + for(int idim=0; idim<SPACEDIM; idim++) + { + double Dx=bbox[i*2*SPACEDIM+1+2*idim]-bbox[i*2*SPACEDIM+2*idim]; + max=(max<Dx)?Dx:max; + } + for(int idim=0; idim<SPACEDIM; idim++) + { + bbox[i*2*SPACEDIM+2*idim ] -= surf3DAdjustmentEps*max+surf3DAdjustmentEpsAbs; + bbox[i*2*SPACEDIM+2*idim+1] += surf3DAdjustmentEps*max+surf3DAdjustmentEpsAbs; + } + } + } + + /*! + * @param icellT id in target mesh in format of MyMeshType. + * @param coordsT output val that stores coordinates of the target cell automatically resized to the right length. + */ + template<class MyMeshType, class MyMatrix> + void PlanarIntersector<MyMeshType,MyMatrix>::getRealTargetCoordinates(ConnType icellT, std::vector<double>& coordsT) + { + int nbNodesT=_connIndexT[OTT<ConnType,numPol>::ind2C(icellT)+1]-_connIndexT[OTT<ConnType,numPol>::ind2C(icellT)]; + coordsT.resize(SPACEDIM*nbNodesT); + for (ConnType iT=0; iT<nbNodesT; iT++) + for(int idim=0; idim<SPACEDIM; idim++) + coordsT[SPACEDIM*iT+idim]=_coordsT[SPACEDIM*OTT<ConnType,numPol>::coo2C(_connectT[OTT<ConnType,numPol>::conn2C(_connIndexT[OTT<ConnType,numPol>::ind2C(icellT)]+iT)])+idim]; + } + + /*! + * @param icellS id in source mesh in format of MyMeshType. + * @param coordsS output val that stores coordinates of the source cell automatically resized to the right length. + */ + template<class MyMeshType, class MyMatrix> + void PlanarIntersector<MyMeshType,MyMatrix>::getRealSourceCoordinates(ConnType icellS, std::vector<double>& coordsS) + { + int nbNodesS=_connIndexS[OTT<ConnType,numPol>::ind2C(icellS)+1]-_connIndexS[OTT<ConnType,numPol>::ind2C(icellS)]; + coordsS.resize(SPACEDIM*nbNodesS); + for (ConnType iS=0; iS<nbNodesS; iS++) + for(int idim=0; idim<SPACEDIM; idim++) + coordsS[SPACEDIM*iS+idim]=_coordsS[SPACEDIM*OTT<ConnType,numPol>::coo2C(_connectS[OTT<ConnType,numPol>::conn2C(_connIndexS[OTT<ConnType,numPol>::ind2C(icellS)]+iS)])+idim]; + } + + /*! + * @param icellT id in target mesh in format of MyMeshType. + * @param offset is a value in C format that indicates the number of circular permutation. + * @param coordsT output val that stores coordinates of the target cell automatically resized to the right length. + */ + template<class MyMeshType, class MyMatrix> + void PlanarIntersector<MyMeshType,MyMatrix>::getRealTargetCoordinatesPermute(ConnType icellT, int offset, std::vector<double>& coordsT) + { + int nbNodesT=_connIndexT[OTT<ConnType,numPol>::ind2C(icellT)+1]-_connIndexT[OTT<ConnType,numPol>::ind2C(icellT)]; + coordsT.resize(SPACEDIM*nbNodesT); + for (ConnType iTTmp=0; iTTmp<nbNodesT; iTTmp++) + { + ConnType iT=(iTTmp+offset)%nbNodesT; + for(int idim=0; idim<SPACEDIM; idim++) + coordsT[SPACEDIM*iTTmp+idim]=_coordsT[SPACEDIM*OTT<ConnType,numPol>::coo2C(_connectT[OTT<ConnType,numPol>::conn2C(_connIndexT[OTT<ConnType,numPol>::ind2C(icellT)]+iT)])+idim]; + } + } + + /*! + * @param icellS id in source mesh in format of MyMeshType. + * @param offset is a value in C format that indicates the number of circular permutation. + * @param coordsS output val that stores coordinates of the source cell automatically resized to the right length. + */ + template<class MyMeshType, class MyMatrix> + void PlanarIntersector<MyMeshType,MyMatrix>::getRealSourceCoordinatesPermute(ConnType icellS, int offset, std::vector<double>& coordsS) + { + int nbNodesS=_connIndexS[OTT<ConnType,numPol>::ind2C(icellS)+1]-_connIndexS[OTT<ConnType,numPol>::ind2C(icellS)]; + coordsS.resize(SPACEDIM*nbNodesS); + for (ConnType iSTmp=0; iSTmp<nbNodesS; iSTmp++) + { + ConnType iS=(iSTmp+offset)%nbNodesS; + for(int idim=0; idim<SPACEDIM; idim++) + coordsS[SPACEDIM*iSTmp+idim]=_coordsS[SPACEDIM*OTT<ConnType,numPol>::coo2C(_connectS[OTT<ConnType,numPol>::conn2C(_connIndexS[OTT<ConnType,numPol>::ind2C(icellS)]+iS)])+idim]; + } + } + + /*! + * @param icellT id in target mesh in format of MyMeshType. + * @param icellS id in source mesh in format of MyMeshType. + * @param nbNodesT nb of nodes of the target cell. + * @param nbNodesS nb of nodes of the source cell. + * @param coordsT output val that stores coordinates of the target cell automatically resized to the right length. + * @param coordsS output val that stores coordinates of the source cell automatically resized to the right length. + * @param orientation is an output value too, only set if SPACEDIM==3. + */ + template<class MyMeshType, class MyMatrix> + void PlanarIntersector<MyMeshType,MyMatrix>::getRealCoordinates(ConnType icellT, ConnType icellS, ConnType nbNodesT, ConnType nbNodesS, std::vector<double>& coordsT, std::vector<double>& coordsS, int& orientation) + { + coordsT.resize(SPACEDIM*nbNodesT); + coordsS.resize(SPACEDIM*nbNodesS); + for (int idim=0; idim<SPACEDIM; idim++) + { + for (ConnType iT=0; iT<nbNodesT; iT++) + coordsT[SPACEDIM*iT+idim] = _coordsT[SPACEDIM*OTT<ConnType,numPol>::coo2C(_connectT[OTT<ConnType,numPol>::conn2C(_connIndexT[OTT<ConnType,numPol>::ind2C(icellT)]+iT)])+idim]; + for (ConnType iS=0; iS<nbNodesS; iS++) + coordsS[SPACEDIM*iS+idim] = _coordsS[SPACEDIM*OTT<ConnType,numPol>::coo2C(_connectS[OTT<ConnType,numPol>::conn2C(_connIndexS[OTT<ConnType,numPol>::ind2C(icellS)]+iS)])+idim]; + } + + //project cells T and S on the median plane and rotate the median plane + if(SPACEDIM==3) + orientation = projectionThis(&coordsT[0], &coordsS[0], nbNodesT, nbNodesS); + + //DEBUG PRINTS + if(_print_level >= 3) + { + std::cout << std::endl << "Cell coordinates (possibly after projection)" << std::endl; + std::cout << std::endl << "icellT= " << icellT << ", nb nodes T= " << nbNodesT << std::endl; + for(int iT =0; iT< nbNodesT; iT++) + {for (int idim=0; idim<SPACEDIM; idim++) std::cout << coordsT[SPACEDIM*iT+idim] << " "; std::cout << std::endl;} + std::cout << std::endl << "icellS= " << icellS << ", nb nodes S= " << nbNodesS << std::endl; + for(int iS =0; iS< nbNodesS; iS++) + {for (int idim=0; idim<SPACEDIM; idim++) std::cout << coordsS[SPACEDIM*iS+idim]<< " "; std::cout << std::endl; } + } + } + + /*! + * Filtering out zero surfaces and badly oriented surfaces + * _orientation = -1,0,1,2 + * -1 : the intersection is taken into account if target and cells have different orientation + * 0 : the intersection is always taken into account + * 1 : the intersection is taken into account if target and cells have the same orientation + * 2 : the absolute value of intersection is always taken into account + */ + template<class MyMeshType, class MyMatrix> + double PlanarIntersector<MyMeshType,MyMatrix>::getValueRegardingOption(double val) const + { + if(_orientation==0) + return val; + if(_orientation==2) + return fabs(val); + if (( val > 0.0 && _orientation==1) || ( val < 0.0 && _orientation==-1 )) + return _orientation*val; + return 0.; + } + + template<class MyMeshType, class MyMatrix> + int PlanarIntersector<MyMeshType,MyMatrix>::projectionThis(double *Coords_A, double *Coords_B, int nb_NodesA, int nb_NodesB) + { + return Projection(Coords_A,Coords_B,nb_NodesA,nb_NodesB,_dim_caracteristic*_precision,_max_distance_3Dsurf_intersect,_min_dot_btw_3Dsurf_intersect,_median_plane,_do_rotate); + } + + template<class MyMeshType, class MyMatrix> + int PlanarIntersector<MyMeshType,MyMatrix>::Projection(double *Coords_A, double *Coords_B, + int nb_NodesA, int nb_NodesB, double epsilon, double md3DSurf, double minDot3DSurf, double median_plane, bool do_rotate) + { + double normal_A[3]={0,0,0}; + double normal_B[3]={0,0,0}; + double linear_comb[3]; + double proj; + bool same_orientation; + + //Find the normal to cells A and B + int i_A1(1); + while(i_A1<nb_NodesA && distance2<SPACEDIM>(Coords_A,&Coords_A[SPACEDIM*i_A1])< epsilon) + i_A1++; + int i_A2(i_A1+1); + crossprod<SPACEDIM>(Coords_A, &Coords_A[SPACEDIM*i_A1], &Coords_A[SPACEDIM*i_A2],normal_A); + double normA(sqrt(dotprod<SPACEDIM>(normal_A,normal_A))); + while(i_A2<nb_NodesA && normA < epsilon) + { + crossprod<SPACEDIM>(Coords_A, &Coords_A[SPACEDIM*i_A1], &Coords_A[SPACEDIM*i_A2],normal_A); + i_A2++; + normA = sqrt(dotprod<SPACEDIM>(normal_A,normal_A)); + + } + int i_B1(1); + while(i_B1<nb_NodesB && distance2<SPACEDIM>(Coords_B,Coords_B+SPACEDIM*i_B1)< epsilon) + i_B1++; + int i_B2(i_B1+1); + crossprod<SPACEDIM>(Coords_B, Coords_B+SPACEDIM*i_B1, Coords_B+SPACEDIM*i_B2,normal_B); + double normB(sqrt(dotprod<SPACEDIM>(normal_B,normal_B))); + while(i_B2<nb_NodesB && normB < epsilon) + { + crossprod<SPACEDIM>(Coords_B, Coords_B+SPACEDIM*i_B1, Coords_B+SPACEDIM*i_B2,normal_B); + i_B2++; + normB = sqrt(dotprod<SPACEDIM>(normal_B,normal_B)); + } + + //fabien option + if(md3DSurf>0.) + { + double coords_GA[3]; + for(int i=0;i<3;i++) + { + coords_GA[i]=0.; + for (int j=0;j<nb_NodesA;j++) + coords_GA[i]+=Coords_A[3*j+i]; + coords_GA[i]/=nb_NodesA; + } + double G1[3],G2[3],G3[3]; + for(int i=0;i<3;i++) + { + G1[i]=Coords_B[i]-coords_GA[i]; + G2[i]=Coords_B[i+3]-coords_GA[i]; + G3[i]=Coords_B[i+6]-coords_GA[i]; + } + double prodvect[3]; + prodvect[0]=G1[1]*G2[2]-G1[2]*G2[1]; + prodvect[1]=G1[2]*G2[0]-G1[0]*G2[2]; + prodvect[2]=G1[0]*G2[1]-G1[1]*G2[0]; + double prodscal=prodvect[0]*G3[0]+prodvect[1]*G3[1]+prodvect[2]*G3[2]; + if(fabs(prodscal)>md3DSurf) + return 0; + } + if(i_A2<nb_NodesA && i_B2<nb_NodesB) + { + //Build the normal of the median plane + + double dotProd(dotprod<SPACEDIM>(normal_A,normal_B)/(normA*normB)); + + if(fabs(dotProd)<minDot3DSurf) + return 0; + + same_orientation=(dotProd>=0); + + if(!same_orientation) + for(int idim =0; idim< SPACEDIM; idim++) + normal_A[idim] *=-1; + + double normBB(sqrt(dotprod<SPACEDIM>(normal_B,normal_B))); + + for(int idim =0; idim< SPACEDIM; idim++) + linear_comb[idim] = median_plane*normal_A[idim]/normA + (1-median_plane)*normal_B[idim]/normBB; + double norm= sqrt(dotprod<SPACEDIM>(linear_comb,linear_comb)); + + //Necessarily: norm>epsilon, no need to check + for(int idim =0; idim< SPACEDIM; idim++) + linear_comb[idim]/=norm; + + //Project the nodes of A and B on the median plane + for(int i_A=0; i_A<nb_NodesA; i_A++) + { + proj = dotprod<SPACEDIM>(&Coords_A[SPACEDIM*i_A],linear_comb); + for(int idim =0; idim< SPACEDIM; idim++) + Coords_A[SPACEDIM*i_A+idim] -= proj*linear_comb[idim]; + } + for(int i_B=0; i_B<nb_NodesB; i_B++) + { + proj = dotprod<SPACEDIM>(Coords_B+SPACEDIM*i_B,linear_comb); + for(int idim =0; idim< SPACEDIM; idim++) + Coords_B[SPACEDIM*i_B+idim] -= proj*linear_comb[idim]; + } + + //Buid the matrix sending A into the Oxy plane and apply it to A and B + if(do_rotate) + { + TranslationRotationMatrix rotation; + //rotate3DTriangle(Coords_A, &Coords_A[SPACEDIM*i_A1], &Coords_A[SPACEDIM*i_A2], rotation); + rotate3DTriangle(Coords_B, Coords_B+SPACEDIM*i_B1, Coords_B+SPACEDIM*i_B2, rotation); + for (int i=0; i<nb_NodesA; i++) + rotation.transform_vector(Coords_A+SPACEDIM*i); + for (int i=0; i<nb_NodesB; i++) + rotation.transform_vector(Coords_B+SPACEDIM*i); + } + return same_orientation?1:-1; + } + else + { + std::cout << " Degenerated cell " << "epsilon = " << epsilon << std::endl; + std::cout << " i_A1= " << i_A1 << " i_A2= " << i_A2 << std::endl; + std::cout << " distance2<SPACEDIM>(Coords_A,&Coords_A[i_A1])= " << distance2<SPACEDIM>(Coords_A,&Coords_A[i_A1]) << std::endl; + std::cout << "abs(normal_A) = " << fabs(normal_A[0]) << " ; " <<fabs( normal_A[1]) << " ; " << fabs(normal_A[2]) << std::endl; + std::cout << " i_B1= " << i_B1 << " i_B2= " << i_B2 << std::endl; + std::cout << " distance2<SPACEDIM>(&Coords_B[0],&Coords_B[i_B1])= " << distance2<SPACEDIM>(Coords_B,Coords_B+i_B1) << std::endl; + std::cout << "normal_B = " << normal_B[0] << " ; " << normal_B[1] << " ; " << normal_B[2] << std::endl; + return 1; + } + } + + template<class MyMeshType, class MyMatrix> + void PlanarIntersector<MyMeshType,MyMatrix>::rotate3DTriangle(double* PP1, double*PP2, double*PP3, + TranslationRotationMatrix& rotation_matrix) + { + //initializes + rotation_matrix.translate(PP1); + + double P2w[3]; + double P3w[3]; + P2w[0]=PP2[0]; P2w[1]=PP2[1];P2w[2]=PP2[2]; + P3w[0]=PP3[0]; P3w[1]=PP3[1];P3w[2]=PP3[2]; + + // translating to set P1 at the origin + for (int i=0; i<3; i++) + { + P2w[i]-=PP1[i]; + P3w[i]-=PP1[i]; + } + + // rotating to set P2 on the Oxy plane + TranslationRotationMatrix A; + A.rotate_x(P2w); + A.rotate_vector(P3w); + rotation_matrix.multiply(A); + + //rotating to set P2 on the Ox axis + TranslationRotationMatrix B; + B.rotate_z(P2w); + B.rotate_vector(P3w); + rotation_matrix.multiply(B); + + //rotating to set P3 on the Oxy plane + TranslationRotationMatrix C; + C.rotate_x(P3w); + rotation_matrix.multiply(C); + } +} + +#endif diff --git a/src/medtool/src/INTERP_KERNEL/PlanarIntersectorP0P0.hxx b/src/medtool/src/INTERP_KERNEL/PlanarIntersectorP0P0.hxx new file mode 100644 index 000000000..c20275ec6 --- /dev/null +++ b/src/medtool/src/INTERP_KERNEL/PlanarIntersectorP0P0.hxx @@ -0,0 +1,51 @@ +// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 +// 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 __PLANARINTERSECTORP0P0_HXX__ +#define __PLANARINTERSECTORP0P0_HXX__ + +#include "PlanarIntersector.hxx" + +namespace INTERP_KERNEL +{ + template<class MyMeshType, class MyMatrix, class ConcreteP0P0Intersector> + class PlanarIntersectorP0P0 : public PlanarIntersector<MyMeshType,MyMatrix> + { + public: + static const int SPACEDIM=MyMeshType::MY_SPACEDIM; + static const int MESHDIM=MyMeshType::MY_MESHDIM; + typedef typename MyMeshType::MyConnType ConnType; + static const NumberingPolicy numPol=MyMeshType::My_numPol; + protected: + PlanarIntersectorP0P0(const MyMeshType& meshT, const MyMeshType& meshS, double dimCaracteristic, double precision, double md3DSurf, double minDot3DSurf, double medianPlane, bool doRotate, int orientation, int printLevel); + public: + int getNumberOfRowsOfResMatrix() const; + int getNumberOfColsOfResMatrix() const; + void intersectCells(ConnType icellT, const std::vector<ConnType>& icellsS, MyMatrix& res); + /*! + * Contrary to intersectCells method here icellS and icellT are \b not in \b C mode but in mode of MyMeshType. + */ + double intersectGeometry(ConnType icellT, ConnType icellS, ConnType nbNodesT, ConnType nbNodesS) { return asLeaf().intersectGeometry(icellT,icellS,nbNodesT,nbNodesS); } + protected: + ConcreteP0P0Intersector& asLeaf() { return static_cast<ConcreteP0P0Intersector&>(*this); } + }; +} + +#endif diff --git a/src/medtool/src/INTERP_KERNEL/PlanarIntersectorP0P0.txx b/src/medtool/src/INTERP_KERNEL/PlanarIntersectorP0P0.txx new file mode 100644 index 000000000..35e44ee80 --- /dev/null +++ b/src/medtool/src/INTERP_KERNEL/PlanarIntersectorP0P0.txx @@ -0,0 +1,64 @@ +// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 +// 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 __PLANARINTERSECTORP0P0_TXX__ +#define __PLANARINTERSECTORP0P0_TXX__ + +#include "PlanarIntersectorP0P0.hxx" + +namespace INTERP_KERNEL +{ + template<class MyMeshType, class MyMatrix, class ConcreteP0P0Intersector> + PlanarIntersectorP0P0<MyMeshType,MyMatrix,ConcreteP0P0Intersector>::PlanarIntersectorP0P0(const MyMeshType& meshT, const MyMeshType& meshS, + double dimCaracteristic, double precision, double md3DSurf, double minDot3DSurf, double medianPlane, + bool doRotate, int orientation, int printLevel): + PlanarIntersector<MyMeshType,MyMatrix>(meshT,meshS,dimCaracteristic,precision,md3DSurf,minDot3DSurf,medianPlane,doRotate,orientation,printLevel) + { + } + + template<class MyMeshType, class MyMatrix, class ConcreteP0P0Intersector> + int PlanarIntersectorP0P0<MyMeshType,MyMatrix,ConcreteP0P0Intersector>::getNumberOfRowsOfResMatrix() const + { + return PlanarIntersector<MyMeshType,MyMatrix>::_meshT.getNumberOfElements(); + } + + template<class MyMeshType, class MyMatrix, class ConcreteP0P0Intersector> + int PlanarIntersectorP0P0<MyMeshType,MyMatrix,ConcreteP0P0Intersector>::getNumberOfColsOfResMatrix() const + { + return PlanarIntersector<MyMeshType,MyMatrix>::_meshS.getNumberOfElements(); + } + + template<class MyMeshType, class MyMatrix, class ConcreteP0P0Intersector> + void PlanarIntersectorP0P0<MyMeshType,MyMatrix,ConcreteP0P0Intersector>::intersectCells(ConnType icellT, const std::vector<ConnType>& icellsS, MyMatrix& res) + { + int nbNodesT=PlanarIntersector<MyMeshType,MyMatrix>::_connIndexT[icellT+1]-PlanarIntersector<MyMeshType,MyMatrix>::_connIndexT[icellT]; + typename MyMatrix::value_type& resRow=res[icellT]; + for(typename std::vector<ConnType>::const_iterator iter=icellsS.begin();iter!=icellsS.end();iter++) + { + int iS=*iter; + int nbNodesS=PlanarIntersector<MyMeshType,MyMatrix>::_connIndexS[iS+1]-PlanarIntersector<MyMeshType,MyMatrix>::_connIndexS[iS]; + double surf=intersectGeometry(OTT<ConnType,numPol>::indFC(icellT),OTT<ConnType,numPol>::indFC(iS),nbNodesT,nbNodesS); + surf=PlanarIntersector<MyMeshType,MyMatrix>::getValueRegardingOption(surf); + if(surf!=0.) + resRow.insert(std::make_pair(OTT<ConnType,numPol>::indFC(iS),surf)); + } + } +} + +#endif diff --git a/src/medtool/src/INTERP_KERNEL/PlanarIntersectorP0P1.hxx b/src/medtool/src/INTERP_KERNEL/PlanarIntersectorP0P1.hxx new file mode 100644 index 000000000..bedddac9d --- /dev/null +++ b/src/medtool/src/INTERP_KERNEL/PlanarIntersectorP0P1.hxx @@ -0,0 +1,51 @@ +// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 +// 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 __PLANARINTERSECTORP0P1_HXX__ +#define __PLANARINTERSECTORP0P1_HXX__ + +#include "PlanarIntersector.hxx" + +namespace INTERP_KERNEL +{ + template<class MyMeshType, class MyMatrix, class ConcreteP0P1Intersector> + class PlanarIntersectorP0P1 : public PlanarIntersector<MyMeshType,MyMatrix> + { + public: + static const int SPACEDIM=MyMeshType::MY_SPACEDIM; + static const int MESHDIM=MyMeshType::MY_MESHDIM; + typedef typename MyMeshType::MyConnType ConnType; + static const NumberingPolicy numPol=MyMeshType::My_numPol; + protected: + PlanarIntersectorP0P1(const MyMeshType& meshT, const MyMeshType& meshS, double dimCaracteristic, double precision, double md3DSurf, double minDot3DSurf, double medianPlane, bool doRotate, int orientation, int printLevel); + public: + void intersectCells(ConnType icellT, const std::vector<ConnType>& icellsS, MyMatrix& res); + int getNumberOfRowsOfResMatrix() const; + int getNumberOfColsOfResMatrix() const; + /*! + * Contrary to intersectCells method here icellS and icellT are \b not in \b C mode but in mode of MyMeshType. + */ + double intersectGeometryWithQuadrangle(const double *quadrangle, const std::vector<double>& sourceCoords, bool isSourceQuad) { return asLeaf().intersectGeometryWithQuadrangle(quadrangle,sourceCoords,isSourceQuad); } + protected: + ConcreteP0P1Intersector& asLeaf() { return static_cast<ConcreteP0P1Intersector&>(*this); } + }; +} + +#endif diff --git a/src/medtool/src/INTERP_KERNEL/PlanarIntersectorP0P1.txx b/src/medtool/src/INTERP_KERNEL/PlanarIntersectorP0P1.txx new file mode 100644 index 000000000..427b14b98 --- /dev/null +++ b/src/medtool/src/INTERP_KERNEL/PlanarIntersectorP0P1.txx @@ -0,0 +1,104 @@ +// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 +// 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 __PLANARINTERSECTORP0P1_TXX__ +#define __PLANARINTERSECTORP0P1_TXX__ + +#include "PlanarIntersectorP0P1.hxx" +#include "InterpolationUtils.hxx" +#include "CellModel.hxx" + +namespace INTERP_KERNEL +{ + template<class MyMeshType, class MyMatrix, class ConcreteP0P1Intersector> + PlanarIntersectorP0P1<MyMeshType,MyMatrix,ConcreteP0P1Intersector>::PlanarIntersectorP0P1(const MyMeshType& meshT, const MyMeshType& meshS, + double dimCaracteristic, double precision, double md3DSurf, double minDot3DSurf, double medianPlane, + bool doRotate, int orientation, int printLevel): + PlanarIntersector<MyMeshType,MyMatrix>(meshT,meshS,dimCaracteristic,precision,md3DSurf,minDot3DSurf,medianPlane,doRotate,orientation,printLevel) + { + } + + template<class MyMeshType, class MyMatrix, class ConcreteP0P1Intersector> + int PlanarIntersectorP0P1<MyMeshType,MyMatrix,ConcreteP0P1Intersector>::getNumberOfRowsOfResMatrix() const + { + return PlanarIntersector<MyMeshType,MyMatrix>::_meshT.getNumberOfNodes(); + } + + template<class MyMeshType, class MyMatrix, class ConcreteP0P1Intersector> + int PlanarIntersectorP0P1<MyMeshType,MyMatrix,ConcreteP0P1Intersector>::getNumberOfColsOfResMatrix() const + { + return PlanarIntersector<MyMeshType,MyMatrix>::_meshS.getNumberOfElements(); + } + + /*! + * This methods split on the fly, into triangles in order to compute dual mesh of target cell (with icellT id in target mesh in C mode). + */ + template<class MyMeshType, class MyMatrix, class ConcreteP0P1Intersector> + void PlanarIntersectorP0P1<MyMeshType,MyMatrix,ConcreteP0P1Intersector>::intersectCells(ConnType icellT, const std::vector<ConnType>& icellsS, MyMatrix& res) + { + int nbNodesT=PlanarIntersector<MyMeshType,MyMatrix>::_connIndexT[icellT+1]-PlanarIntersector<MyMeshType,MyMatrix>::_connIndexT[icellT]; + double triangle[9]; + double quadrangle[12]; + std::vector<double> sourceCellCoords; + int orientation=1; + const ConnType *startOfCellNodeConn=PlanarIntersector<MyMeshType,MyMatrix>::_connectT+OTT<ConnType,numPol>::conn2C(PlanarIntersector<MyMeshType,MyMatrix>::_connIndexT[icellT]); + for(int nodeIdT=0;nodeIdT<nbNodesT;nodeIdT++) + { + ConnType curNodeTInCmode=OTT<ConnType,numPol>::coo2C(startOfCellNodeConn[nodeIdT]); + std::copy(PlanarIntersector<MyMeshType,MyMatrix>::_coordsT+curNodeTInCmode*SPACEDIM, + PlanarIntersector<MyMeshType,MyMatrix>::_coordsT+curNodeTInCmode*SPACEDIM+SPACEDIM,triangle); + typename MyMatrix::value_type& resRow=res[curNodeTInCmode]; + for(typename std::vector<ConnType>::const_iterator iter=icellsS.begin();iter!=icellsS.end();iter++) + { + int iS=*iter; + PlanarIntersector<MyMeshType,MyMatrix>::getRealSourceCoordinates(OTT<ConnType,numPol>::indFC(iS),sourceCellCoords); + for(int subTriT=1;subTriT<=nbNodesT-2;subTriT++) + { + std::copy(PlanarIntersector<MyMeshType,MyMatrix>::_coordsT+OTT<ConnType,numPol>::coo2C(startOfCellNodeConn[(nodeIdT+subTriT)%nbNodesT])*SPACEDIM, + PlanarIntersector<MyMeshType,MyMatrix>::_coordsT+OTT<ConnType,numPol>::coo2C(startOfCellNodeConn[(nodeIdT+subTriT)%nbNodesT])*SPACEDIM+SPACEDIM, + triangle+SPACEDIM); + std::copy(PlanarIntersector<MyMeshType,MyMatrix>::_coordsT+OTT<ConnType,numPol>::coo2C(startOfCellNodeConn[(nodeIdT+subTriT+1)%nbNodesT])*SPACEDIM, + PlanarIntersector<MyMeshType,MyMatrix>::_coordsT+OTT<ConnType,numPol>::coo2C(startOfCellNodeConn[(nodeIdT+subTriT+1)%nbNodesT])*SPACEDIM+SPACEDIM, + triangle+2*SPACEDIM); + fillDualCellOfTri<SPACEDIM>(triangle,quadrangle); + std::vector<double> sourceCellCoordsTmp(sourceCellCoords); + if(SPACEDIM==3) + orientation=PlanarIntersector<MyMeshType,MyMatrix>::projectionThis(&sourceCellCoordsTmp[0],quadrangle,sourceCellCoords.size()/SPACEDIM,4); + NormalizedCellType tS=PlanarIntersector<MyMeshType,MyMatrix>::_meshS.getTypeOfElement(OTT<ConnType,numPol>::indFC(iS)); + double surf=orientation*intersectGeometryWithQuadrangle(quadrangle,sourceCellCoordsTmp,CellModel::GetCellModel(tS).isQuadratic()); + surf=PlanarIntersector<MyMeshType,MyMatrix>::getValueRegardingOption(surf); + if(surf!=0.) + { + typename MyMatrix::value_type::const_iterator iterRes=resRow.find(OTT<ConnType,numPol>::indFC(iS)); + if(iterRes==resRow.end()) + resRow.insert(std::make_pair(OTT<ConnType,numPol>::indFC(iS),surf)); + else + { + double val=(*iterRes).second+surf; + resRow.erase(OTT<ConnType,numPol>::indFC(iS)); + resRow.insert(std::make_pair(OTT<ConnType,numPol>::indFC(iS),val)); + } + } + } + } + } + } +} + +#endif diff --git a/src/medtool/src/INTERP_KERNEL/PlanarIntersectorP0P1Bary.hxx b/src/medtool/src/INTERP_KERNEL/PlanarIntersectorP0P1Bary.hxx new file mode 100644 index 000000000..b4380b164 --- /dev/null +++ b/src/medtool/src/INTERP_KERNEL/PlanarIntersectorP0P1Bary.hxx @@ -0,0 +1,55 @@ +// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 +// 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 __PlanarIntersectorP0P1Bary_HXX__ +#define __PlanarIntersectorP0P1Bary_HXX__ + +#include "PlanarIntersector.hxx" + +namespace INTERP_KERNEL +{ + template<class MyMeshType, class MyMatrix, class ConcreteP0P1Intersector> + class PlanarIntersectorP0P1Bary : public PlanarIntersector<MyMeshType,MyMatrix> + { + public: + static const int SPACEDIM=MyMeshType::MY_SPACEDIM; + static const int MESHDIM=MyMeshType::MY_MESHDIM; + typedef typename MyMeshType::MyConnType ConnType; + static const NumberingPolicy numPol=MyMeshType::My_numPol; + protected: + PlanarIntersectorP0P1Bary(const MyMeshType& meshT, const MyMeshType& meshS, double dimCaracteristic, double precision, double md3DSurf, double minDot3DSurf, double medianPlane, bool doRotate, int orientation, int printLevel); + public: + void intersectCells(ConnType icellT, const std::vector<ConnType>& icellsS, MyMatrix& res); + int getNumberOfRowsOfResMatrix() const; + int getNumberOfColsOfResMatrix() const; + /*! + * Contrary to intersectCells method here icellS and icellT are \b not in \b C mode but in mode of MyMeshType. + */ + double intersectGeoBary(const std::vector<double>& sourceCell, + bool sourceCellQuadratic, + const double * targetTria, + std::vector<double>& res) + { return asLeaf().intersectGeoBary(sourceCell,sourceCellQuadratic,targetTria,res); } + protected: + ConcreteP0P1Intersector& asLeaf() { return static_cast<ConcreteP0P1Intersector&>(*this); } + }; +} + +#endif diff --git a/src/medtool/src/INTERP_KERNEL/PlanarIntersectorP0P1Bary.txx b/src/medtool/src/INTERP_KERNEL/PlanarIntersectorP0P1Bary.txx new file mode 100644 index 000000000..66c34174a --- /dev/null +++ b/src/medtool/src/INTERP_KERNEL/PlanarIntersectorP0P1Bary.txx @@ -0,0 +1,115 @@ +// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 +// 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 __PlanarIntersectorP0P1Bary_TXX__ +#define __PlanarIntersectorP0P1Bary_TXX__ + +#include "PlanarIntersectorP0P1Bary.hxx" +#include "InterpolationUtils.hxx" + +namespace INTERP_KERNEL +{ + template<class MyMeshType, class MyMatrix, class ConcreteP0P1Intersector> + PlanarIntersectorP0P1Bary<MyMeshType,MyMatrix,ConcreteP0P1Intersector>::PlanarIntersectorP0P1Bary(const MyMeshType& meshT, const MyMeshType& meshS, + double dimCaracteristic, double precision, + double md3DSurf, double minDot3DSurf, double medianPlane, + bool doRotate, int orientation, int printLevel): + PlanarIntersector<MyMeshType,MyMatrix>(meshT,meshS,dimCaracteristic,precision,md3DSurf,minDot3DSurf, + medianPlane,doRotate,orientation,printLevel) + { + // SPEC: + // "Limitation. For the P0P1 barycentric improvement only triangle target cells in 2D and + // tetrahedrons in 3D will be supported by interpolators. If a non + // triangle/tetrahedron source cell is detected an INTERP_KERNEL::Exception should be thrown." + + // Check types of source elements here rather than in intersectCells() since a wrong type can be + // found late after a long time of calculation. + + const unsigned long numTrgElems = meshT.getNumberOfElements(); + for(unsigned long i = 0 ; i < numTrgElems ; ++i) + if ( meshT.getTypeOfElement( OTT<ConnType,numPol>::indFC( i )) != NORM_TRI3 ) + throw INTERP_KERNEL::Exception("P0P1 barycentric algorithm works only with triangular target meshes"); + } + + template<class MyMeshType, class MyMatrix, class ConcreteP0P1Intersector> + int PlanarIntersectorP0P1Bary<MyMeshType,MyMatrix,ConcreteP0P1Intersector>::getNumberOfRowsOfResMatrix() const + { + return PlanarIntersector<MyMeshType,MyMatrix>::_meshT.getNumberOfNodes(); + } + + template<class MyMeshType, class MyMatrix, class ConcreteP0P1Intersector> + int PlanarIntersectorP0P1Bary<MyMeshType,MyMatrix,ConcreteP0P1Intersector>::getNumberOfColsOfResMatrix() const + { + return PlanarIntersector<MyMeshType,MyMatrix>::_meshS.getNumberOfElements(); + } + + /*! + * This method computes a value per each node of each source triangle for target. + */ + template<class MyMeshType, class MyMatrix, class ConcreteP0P1Intersector> + void PlanarIntersectorP0P1Bary<MyMeshType,MyMatrix,ConcreteP0P1Intersector>::intersectCells(ConnType icellT, const std::vector<ConnType>& icellsS, MyMatrix& res) + { + int orientation=1; + std::vector<double> trgTriaCoords,trgTriaCoordsTmp; + // target cell data + PlanarIntersector<MyMeshType,MyMatrix>::getRealTargetCoordinates(OTT<ConnType,numPol>::indFC(icellT),trgTriaCoords); + std::vector<double> *tgtCoords(&trgTriaCoords); + const ConnType *startOfCellNodeConn=PlanarIntersector<MyMeshType,MyMatrix>::_connectT+OTT<ConnType,numPol>::conn2C(PlanarIntersector<MyMeshType,MyMatrix>::_connIndexT[icellT]); + // treat each source cells + for(typename std::vector<ConnType>::const_iterator iter=icellsS.begin();iter!=icellsS.end();iter++) + { + std::vector<double> srcCellCoords,srcCellCoordsTmp,nodeCeffs; + int iS=*iter; + NormalizedCellType tS=PlanarIntersector<MyMeshType,MyMatrix>::_meshS.getTypeOfElement(OTT<ConnType,numPol>::indFC(iS)); + bool isSourceQuad=CellModel::GetCellModel(tS).isQuadratic(); + PlanarIntersector<MyMeshType,MyMatrix>::getRealSourceCoordinates(OTT<ConnType,numPol>::indFC(iS),srcCellCoords); + std::vector<double> *srcCoords(&srcCellCoords); + int srcNbNodes = srcCellCoords.size()/SPACEDIM; + if(SPACEDIM==3) + { + srcCellCoordsTmp=srcCellCoords; + trgTriaCoordsTmp=trgTriaCoords; + srcCoords=&srcCellCoordsTmp; + tgtCoords=&trgTriaCoordsTmp; + orientation=PlanarIntersector<MyMeshType,MyMatrix>::projectionThis(&trgTriaCoordsTmp[0],&srcCellCoordsTmp[0], + 3,srcNbNodes); + } + //double surf=orientation*intersectGeometryWithQuadrangle(quadrangle,targetCellCoordsTmp,isTargetQuad); + double surf=orientation*intersectGeoBary(*srcCoords,isSourceQuad,&((*tgtCoords)[0]),nodeCeffs); + surf=PlanarIntersector<MyMeshType,MyMatrix>::getValueRegardingOption(surf); + if(surf!=0.) + { + for(int nodeIdT=0;nodeIdT<3;nodeIdT++) + { + ConnType curNodeT=startOfCellNodeConn[nodeIdT]; + typename MyMatrix::value_type& resRow=res[curNodeT]; + typename MyMatrix::value_type::const_iterator iterRes=resRow.find(*iter); + if(iterRes!=resRow.end()) + { + nodeCeffs[*iter] += iterRes->second; + resRow.erase(*iter); + } + resRow.insert(std::make_pair(*iter,nodeCeffs[nodeIdT])); + } + } + } + } +} +#endif diff --git a/src/medtool/src/INTERP_KERNEL/PlanarIntersectorP0P1PL.hxx b/src/medtool/src/INTERP_KERNEL/PlanarIntersectorP0P1PL.hxx new file mode 100644 index 000000000..d04e2da59 --- /dev/null +++ b/src/medtool/src/INTERP_KERNEL/PlanarIntersectorP0P1PL.hxx @@ -0,0 +1,44 @@ +// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 +// 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 __PLANARINTERSECTORP0P1PL_HXX__ +#define __PLANARINTERSECTORP0P1PL_HXX__ + +#include "PlanarIntersector.hxx" + +namespace INTERP_KERNEL +{ + template<class MyMeshType, class MyMatrix> + class PlanarIntersectorP0P1PL : public PlanarIntersector<MyMeshType,MyMatrix> + { + public: + static const int SPACEDIM=MyMeshType::MY_SPACEDIM; + static const int MESHDIM=MyMeshType::MY_MESHDIM; + typedef typename MyMeshType::MyConnType ConnType; + static const NumberingPolicy numPol=MyMeshType::My_numPol; + public: + PlanarIntersectorP0P1PL(const MyMeshType& meshT, const MyMeshType& meshS, double dimCaracteristic, double md3DSurf, double minDot3DSurf, double medianPlane, double precision, int orientation); + void intersectCells(ConnType icellT, const std::vector<ConnType>& icellsS, MyMatrix& res); + int getNumberOfRowsOfResMatrix() const; + int getNumberOfColsOfResMatrix() const; + }; +} + +#endif diff --git a/src/medtool/src/INTERP_KERNEL/PlanarIntersectorP0P1PL.txx b/src/medtool/src/INTERP_KERNEL/PlanarIntersectorP0P1PL.txx new file mode 100644 index 000000000..abb6cd8c5 --- /dev/null +++ b/src/medtool/src/INTERP_KERNEL/PlanarIntersectorP0P1PL.txx @@ -0,0 +1,84 @@ +// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 +// 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 __PLANARINTERSECTORP0P1PL_TXX__ +#define __PLANARINTERSECTORP0P1PL_TXX__ + +#include "PlanarIntersectorP0P1PL.hxx" +#include "PlanarIntersector.txx" +#include "CellModel.hxx" + +#include "PointLocatorAlgos.txx" + +namespace INTERP_KERNEL +{ + template<class MyMeshType, class MyMatrix> + PlanarIntersectorP0P1PL<MyMeshType,MyMatrix>::PlanarIntersectorP0P1PL(const MyMeshType& meshT, const MyMeshType& meshS, + double dimCaracteristic, double md3DSurf, double minDot3DSurf, + double medianPlane, double precision, int orientation): + PlanarIntersector<MyMeshType,MyMatrix>(meshT,meshS,dimCaracteristic,precision,md3DSurf,minDot3DSurf,medianPlane,true,orientation,0) + { + } + + template<class MyMeshType, class MyMatrix> + void PlanarIntersectorP0P1PL<MyMeshType,MyMatrix>::intersectCells(ConnType icellT, const std::vector<ConnType>& icellsS, MyMatrix& res) + { + std::vector< std::vector<double> > coordsOfSources(icellsS.size()); + int ii=0; + for(typename std::vector<ConnType>::const_iterator iter=icellsS.begin();iter!=icellsS.end();iter++,ii++) + PlanarIntersector<MyMeshType,MyMatrix>::getRealSourceCoordinates(OTT<ConnType,numPol>::indFC(*iter),coordsOfSources[ii]); + const ConnType *startOfCellNodeConnT=PlanarIntersector<MyMeshType,MyMatrix>::_connectT+OTT<ConnType,numPol>::conn2C(PlanarIntersector<MyMeshType,MyMatrix>::_connIndexT[icellT]); + std::vector<double> coordsTarget; + PlanarIntersector<MyMeshType,MyMatrix>::getRealTargetCoordinates(OTT<ConnType,numPol>::indFC(icellT),coordsTarget); + int nbNodesT=coordsTarget.size()/SPACEDIM; + ii=0; + for(typename std::vector<ConnType>::const_iterator iter2=icellsS.begin();iter2!=icellsS.end();iter2++,ii++) + { + std::vector<double> tmpSource(coordsOfSources[ii]); + std::vector<double> tmpTarget(coordsTarget); + if(SPACEDIM==3) + PlanarIntersector<MyMeshType,MyMatrix>::projectionThis(&tmpSource[0],&tmpTarget[0],tmpSource.size()/SPACEDIM,nbNodesT); + for(int nodeIdT=0;nodeIdT<nbNodesT;nodeIdT++) + { + if(PointLocatorAlgos<MyMeshType>::isElementContainsPointAlg2D(&tmpTarget[0]+nodeIdT*SPACEDIM,&tmpSource[0],tmpSource.size()/SPACEDIM,PlanarIntersector<MyMeshType,MyMatrix>::_precision)) + { + ConnType curNodeTInCmode=OTT<ConnType,numPol>::coo2C(startOfCellNodeConnT[nodeIdT]); + typename MyMatrix::value_type& resRow=res[curNodeTInCmode]; + typename MyMatrix::value_type::const_iterator iterRes=resRow.find(OTT<ConnType,numPol>::indFC(*iter2)); + if(iterRes==resRow.end()) + resRow.insert(std::make_pair(OTT<ConnType,numPol>::indFC(*iter2),1.)); + } + } + } + } + + template<class MyMeshType, class MyMatrix> + int PlanarIntersectorP0P1PL<MyMeshType,MyMatrix>::getNumberOfRowsOfResMatrix() const + { + return PlanarIntersector<MyMeshType,MyMatrix>::_meshT.getNumberOfNodes(); + } + + template<class MyMeshType, class MyMatrix> + int PlanarIntersectorP0P1PL<MyMeshType,MyMatrix>::getNumberOfColsOfResMatrix() const + { + return PlanarIntersector<MyMeshType,MyMatrix>::_meshS.getNumberOfElements(); + } +} + +#endif diff --git a/src/medtool/src/INTERP_KERNEL/PlanarIntersectorP1P0.hxx b/src/medtool/src/INTERP_KERNEL/PlanarIntersectorP1P0.hxx new file mode 100644 index 000000000..f351143a4 --- /dev/null +++ b/src/medtool/src/INTERP_KERNEL/PlanarIntersectorP1P0.hxx @@ -0,0 +1,51 @@ +// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 +// 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 __PLANARINTERSECTORP1P0_HXX__ +#define __PLANARINTERSECTORP1P0_HXX__ + +#include "PlanarIntersector.hxx" + +namespace INTERP_KERNEL +{ + template<class MyMeshType, class MyMatrix, class ConcreteP1P0Intersector> + class PlanarIntersectorP1P0 : public PlanarIntersector<MyMeshType,MyMatrix> + { + public: + static const int SPACEDIM=MyMeshType::MY_SPACEDIM; + static const int MESHDIM=MyMeshType::MY_MESHDIM; + typedef typename MyMeshType::MyConnType ConnType; + static const NumberingPolicy numPol=MyMeshType::My_numPol; + protected: + PlanarIntersectorP1P0(const MyMeshType& meshT, const MyMeshType& meshS, double dimCaracteristic, double precision, double md3DSurf, double minDot3DSurf, double medianPlane, bool doRotate, int orientation, int printLevel); + public: + void intersectCells(ConnType icellT, const std::vector<ConnType>& icellsS, MyMatrix& res); + int getNumberOfRowsOfResMatrix() const; + int getNumberOfColsOfResMatrix() const; + /*! + * Contrary to intersectCells method here icellS and icellT are \b not in \b C mode but in mode of MyMeshType. + */ + double intersectGeometryWithQuadrangle(const double *quadrangle, const std::vector<double>& sourceCoords, bool isSourceQuad) { return asLeaf().intersectGeometryWithQuadrangle(quadrangle,sourceCoords,isSourceQuad); } + protected: + ConcreteP1P0Intersector& asLeaf() { return static_cast<ConcreteP1P0Intersector&>(*this); } + }; +} + +#endif diff --git a/src/medtool/src/INTERP_KERNEL/PlanarIntersectorP1P0.txx b/src/medtool/src/INTERP_KERNEL/PlanarIntersectorP1P0.txx new file mode 100644 index 000000000..60617aee6 --- /dev/null +++ b/src/medtool/src/INTERP_KERNEL/PlanarIntersectorP1P0.txx @@ -0,0 +1,104 @@ +// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 +// 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 __PLANARINTERSECTORP1P0_TXX__ +#define __PLANARINTERSECTORP1P0_TXX__ + +#include "PlanarIntersectorP1P0.hxx" +#include "InterpolationUtils.hxx" + +namespace INTERP_KERNEL +{ + template<class MyMeshType, class MyMatrix, class ConcreteP1P0Intersector> + PlanarIntersectorP1P0<MyMeshType,MyMatrix,ConcreteP1P0Intersector>::PlanarIntersectorP1P0(const MyMeshType& meshT, const MyMeshType& meshS, + double dimCaracteristic, double precision, double md3DSurf, double minDot3DSurf, double medianPlane, + bool doRotate, int orientation, int printLevel): + PlanarIntersector<MyMeshType,MyMatrix>(meshT,meshS,dimCaracteristic,precision,md3DSurf,minDot3DSurf,medianPlane,doRotate,orientation,printLevel) + { + } + + template<class MyMeshType, class MyMatrix, class ConcreteP1P0Intersector> + int PlanarIntersectorP1P0<MyMeshType,MyMatrix,ConcreteP1P0Intersector>::getNumberOfRowsOfResMatrix() const + { + return PlanarIntersector<MyMeshType,MyMatrix>::_meshT.getNumberOfElements(); + } + + template<class MyMeshType, class MyMatrix, class ConcreteP1P0Intersector> + int PlanarIntersectorP1P0<MyMeshType,MyMatrix,ConcreteP1P0Intersector>::getNumberOfColsOfResMatrix() const + { + return PlanarIntersector<MyMeshType,MyMatrix>::_meshS.getNumberOfNodes(); + } + + /*! + * This methods split on the fly, into triangles in order to compute dual mesh of target cell (with icellT id in target mesh in C mode). + */ + template<class MyMeshType, class MyMatrix, class ConcreteP1P0Intersector> + void PlanarIntersectorP1P0<MyMeshType,MyMatrix,ConcreteP1P0Intersector>::intersectCells(ConnType icellT, const std::vector<ConnType>& icellsS, MyMatrix& res) + { + double triangle[9]; + double quadrangle[12]; + std::vector<double> targetCellCoords; + int orientation=1; + PlanarIntersector<MyMeshType,MyMatrix>::getRealTargetCoordinates(OTT<ConnType,numPol>::indFC(icellT),targetCellCoords); + NormalizedCellType tT=PlanarIntersector<MyMeshType,MyMatrix>::_meshT.getTypeOfElement(OTT<ConnType,numPol>::indFC(icellT)); + bool isTargetQuad=CellModel::GetCellModel(tT).isQuadratic(); + typename MyMatrix::value_type& resRow=res[icellT]; + for(typename std::vector<ConnType>::const_iterator iter=icellsS.begin();iter!=icellsS.end();iter++) + { + int iS=*iter; + int nbNodesS=PlanarIntersector<MyMeshType,MyMatrix>::_connIndexS[iS+1]-PlanarIntersector<MyMeshType,MyMatrix>::_connIndexS[iS]; + const ConnType *startOfCellNodeConn=PlanarIntersector<MyMeshType,MyMatrix>::_connectS+OTT<ConnType,numPol>::conn2C(PlanarIntersector<MyMeshType,MyMatrix>::_connIndexS[iS]); + for(int nodeIdS=0;nodeIdS<nbNodesS;nodeIdS++) + { + ConnType curNodeSInCmode=OTT<ConnType,numPol>::coo2C(startOfCellNodeConn[nodeIdS]); + std::copy(PlanarIntersector<MyMeshType,MyMatrix>::_coordsS+curNodeSInCmode*SPACEDIM, + PlanarIntersector<MyMeshType,MyMatrix>::_coordsS+curNodeSInCmode*SPACEDIM+SPACEDIM,triangle); + for(int subTriS=1;subTriS<=nbNodesS-2;subTriS++) + { + std::copy(PlanarIntersector<MyMeshType,MyMatrix>::_coordsS+OTT<ConnType,numPol>::coo2C(startOfCellNodeConn[(nodeIdS+subTriS)%nbNodesS])*SPACEDIM, + PlanarIntersector<MyMeshType,MyMatrix>::_coordsS+OTT<ConnType,numPol>::coo2C(startOfCellNodeConn[(nodeIdS+subTriS)%nbNodesS])*SPACEDIM+SPACEDIM, + triangle+SPACEDIM); + std::copy(PlanarIntersector<MyMeshType,MyMatrix>::_coordsS+OTT<ConnType,numPol>::coo2C(startOfCellNodeConn[(nodeIdS+subTriS+1)%nbNodesS])*SPACEDIM, + PlanarIntersector<MyMeshType,MyMatrix>::_coordsS+OTT<ConnType,numPol>::coo2C(startOfCellNodeConn[(nodeIdS+subTriS+1)%nbNodesS])*SPACEDIM+SPACEDIM, + triangle+2*SPACEDIM); + fillDualCellOfTri<SPACEDIM>(triangle,quadrangle); + std::vector<double> targetCellCoordsTmp(targetCellCoords); + if(SPACEDIM==3) + orientation=PlanarIntersector<MyMeshType,MyMatrix>::projectionThis(&targetCellCoordsTmp[0],quadrangle,targetCellCoords.size()/SPACEDIM,4); + double surf=orientation*intersectGeometryWithQuadrangle(quadrangle,targetCellCoordsTmp,isTargetQuad); + surf=PlanarIntersector<MyMeshType,MyMatrix>::getValueRegardingOption(surf); + if(surf!=0.) + { + typename MyMatrix::value_type::const_iterator iterRes=resRow.find(OTT<ConnType,numPol>::indFC(curNodeSInCmode)); + if(iterRes==resRow.end()) + resRow.insert(std::make_pair(OTT<ConnType,numPol>::indFC(curNodeSInCmode),surf)); + else + { + double val=(*iterRes).second+surf; + resRow.erase(OTT<ConnType,numPol>::indFC(curNodeSInCmode)); + resRow.insert(std::make_pair(OTT<ConnType,numPol>::indFC(curNodeSInCmode),val)); + } + } + } + } + } + } +} + +#endif diff --git a/src/medtool/src/INTERP_KERNEL/PlanarIntersectorP1P0Bary.hxx b/src/medtool/src/INTERP_KERNEL/PlanarIntersectorP1P0Bary.hxx new file mode 100644 index 000000000..ede9dc76f --- /dev/null +++ b/src/medtool/src/INTERP_KERNEL/PlanarIntersectorP1P0Bary.hxx @@ -0,0 +1,55 @@ +// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 +// 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 __PlanarIntersectorP1P0Bary_HXX__ +#define __PlanarIntersectorP1P0Bary_HXX__ + +#include "PlanarIntersector.hxx" + +namespace INTERP_KERNEL +{ + template<class MyMeshType, class MyMatrix, class ConcreteP1P0Intersector> + class PlanarIntersectorP1P0Bary : public PlanarIntersector<MyMeshType,MyMatrix> + { + public: + static const int SPACEDIM=MyMeshType::MY_SPACEDIM; + static const int MESHDIM=MyMeshType::MY_MESHDIM; + typedef typename MyMeshType::MyConnType ConnType; + static const NumberingPolicy numPol=MyMeshType::My_numPol; + protected: + PlanarIntersectorP1P0Bary(const MyMeshType& meshT, const MyMeshType& meshS, double dimCaracteristic, double precision, double md3DSurf, double minDot3DSurf, double medianPlane, bool doRotate, int orientation, int printLevel); + public: + void intersectCells(ConnType icellT, const std::vector<ConnType>& icellsS, MyMatrix& res); + int getNumberOfRowsOfResMatrix() const; + int getNumberOfColsOfResMatrix() const; + /*! + * Contrary to intersectCells method here icellS and icellT are \b not in \b C mode but in mode of MyMeshType. + */ + double intersectGeoBary(const std::vector<double>& targetCell, + bool targetCellQuadratic, + const double * sourceTria, + std::vector<double>& res) + { return asLeaf().intersectGeoBary(targetCell,targetCellQuadratic,sourceTria,res); } + protected: + ConcreteP1P0Intersector& asLeaf() { return static_cast<ConcreteP1P0Intersector&>(*this); } + }; +} + +#endif diff --git a/src/medtool/src/INTERP_KERNEL/PlanarIntersectorP1P0Bary.txx b/src/medtool/src/INTERP_KERNEL/PlanarIntersectorP1P0Bary.txx new file mode 100644 index 000000000..ae0b94f51 --- /dev/null +++ b/src/medtool/src/INTERP_KERNEL/PlanarIntersectorP1P0Bary.txx @@ -0,0 +1,118 @@ +// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 +// 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 __PlanarIntersectorP1P0Bary_TXX__ +#define __PlanarIntersectorP1P0Bary_TXX__ + +#include "PlanarIntersectorP1P0Bary.hxx" +#include "InterpolationUtils.hxx" + +#define PLAN_INTERSECTOR PlanarIntersectorP1P0Bary<MyMeshType,MyMatrix,ConcreteP1P0Intersector> +#define PLAN_INTER_TEMPLATE template<class MyMeshType, class MyMatrix, class ConcreteP1P0Intersector> + +namespace INTERP_KERNEL +{ + PLAN_INTER_TEMPLATE + PLAN_INTERSECTOR::PlanarIntersectorP1P0Bary(const MyMeshType& meshT, const MyMeshType& meshS, + double dimCaracteristic, double precision, + double md3DSurf, double minDot3DSurf, double medianPlane, + bool doRotate, int orientation, int printLevel): + PlanarIntersector<MyMeshType,MyMatrix>(meshT,meshS,dimCaracteristic,precision,md3DSurf,minDot3DSurf, + medianPlane,doRotate,orientation,printLevel) + { + // SPEC: + // "Limitation. For the P1P0 barycentric improvement only triangle source cells in 2D and + // tetrahedrons in 3D will be supported by interpolators. If a non + // triangle/tetrahedron source cell is detected an INTERP_KERNEL::Exception should be thrown." + + // Check types of source elements here rather than in intersectCells() since a wrong type can be + // found late after a long time of calculation. + + const unsigned long numSrcElems = meshS.getNumberOfElements(); + for(unsigned long i = 0 ; i < numSrcElems ; ++i) + if ( meshS.getTypeOfElement( OTT<ConnType,numPol>::indFC( i )) != NORM_TRI3 ) + throw INTERP_KERNEL::Exception("P1P0 barycentric algorithm works only with triangular source meshes"); + } + + PLAN_INTER_TEMPLATE + int PLAN_INTERSECTOR::getNumberOfRowsOfResMatrix() const + { + return PlanarIntersector<MyMeshType,MyMatrix>::_meshT.getNumberOfElements(); + } + + PLAN_INTER_TEMPLATE + int PLAN_INTERSECTOR::getNumberOfColsOfResMatrix() const + { + return PlanarIntersector<MyMeshType,MyMatrix>::_meshS.getNumberOfNodes(); + } + + /*! + * This method computes a value per each node of each source triangle for target. + */ + PLAN_INTER_TEMPLATE + void PLAN_INTERSECTOR::intersectCells(ConnType icellT, + const std::vector<ConnType>& icellsS, + MyMatrix& res) + { + int orientation=1; + std::vector<double> srcTriaCoords, tgtCellCoords, tgtCellCoordsTmp, nodeCeffs; + + // target cell data + PlanarIntersector<MyMeshType,MyMatrix>::getRealTargetCoordinates(OTT<ConnType,numPol>::indFC(icellT),tgtCellCoords); + std::vector<double> * tgtCoords = & tgtCellCoords; + int tgtNbNodes = tgtCellCoords.size()/SPACEDIM; + NormalizedCellType tT=PlanarIntersector<MyMeshType,MyMatrix>::_meshT.getTypeOfElement(OTT<ConnType,numPol>::indFC(icellT)); + bool isTargetQuad=CellModel::GetCellModel(tT).isQuadratic(); + + typename MyMatrix::value_type& resRow=res[icellT]; + + // treat each source triangle + for(typename std::vector<ConnType>::const_iterator iter=icellsS.begin();iter!=icellsS.end();iter++) + { + int iS=*iter; + PlanarIntersector<MyMeshType,MyMatrix>::getRealSourceCoordinates(OTT<ConnType,numPol>::indFC(iS),srcTriaCoords); + const ConnType *startOfCellNodeConn=PlanarIntersector<MyMeshType,MyMatrix>::_connectS+OTT<ConnType,numPol>::conn2C(PlanarIntersector<MyMeshType,MyMatrix>::_connIndexS[iS]); + if(SPACEDIM==3) + { + tgtCellCoordsTmp = tgtCellCoords; + tgtCoords = & tgtCellCoordsTmp; + orientation=PlanarIntersector<MyMeshType,MyMatrix>::projectionThis(&tgtCellCoordsTmp[0], &srcTriaCoords[0], + tgtNbNodes, 3); + } + //double surf=orientation*intersectGeometryWithQuadrangle(quadrangle,targetCellCoordsTmp,isTargetQuad); + double surf=orientation*intersectGeoBary( *tgtCoords, isTargetQuad, &srcTriaCoords[0], nodeCeffs ); + surf=PlanarIntersector<MyMeshType,MyMatrix>::getValueRegardingOption(surf); + if(surf!=0.) + { + for(int nodeIdS=0;nodeIdS<3;nodeIdS++) + { + ConnType curNodeS=startOfCellNodeConn[nodeIdS]; + typename MyMatrix::value_type::const_iterator iterRes=resRow.find(curNodeS); + if(iterRes!=resRow.end()) + { + nodeCeffs[nodeIdS] += iterRes->second; + resRow.erase( curNodeS ); + } + resRow.insert(std::make_pair(curNodeS,nodeCeffs[nodeIdS])); + } + } + } + } +} +#endif diff --git a/src/medtool/src/INTERP_KERNEL/PlanarIntersectorP1P0PL.hxx b/src/medtool/src/INTERP_KERNEL/PlanarIntersectorP1P0PL.hxx new file mode 100644 index 000000000..47e9121cb --- /dev/null +++ b/src/medtool/src/INTERP_KERNEL/PlanarIntersectorP1P0PL.hxx @@ -0,0 +1,44 @@ +// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 +// 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 __PLANARINTERSECTORP1P0PL_HXX__ +#define __PLANARINTERSECTORP1P0PL_HXX__ + +#include "PlanarIntersector.hxx" + +namespace INTERP_KERNEL +{ + template<class MyMeshType, class MyMatrix> + class PlanarIntersectorP1P0PL : public PlanarIntersector<MyMeshType,MyMatrix> + { + public: + static const int SPACEDIM=MyMeshType::MY_SPACEDIM; + static const int MESHDIM=MyMeshType::MY_MESHDIM; + typedef typename MyMeshType::MyConnType ConnType; + static const NumberingPolicy numPol=MyMeshType::My_numPol; + public: + PlanarIntersectorP1P0PL(const MyMeshType& meshT, const MyMeshType& meshS, double dimCaracteristic, double md3DSurf, double minDot3DSurf, double medianPlane, double precision, int orientation); + void intersectCells(ConnType icellT, const std::vector<ConnType>& icellsS, MyMatrix& res); + int getNumberOfRowsOfResMatrix() const; + int getNumberOfColsOfResMatrix() const; + }; +} + +#endif diff --git a/src/medtool/src/INTERP_KERNEL/PlanarIntersectorP1P0PL.txx b/src/medtool/src/INTERP_KERNEL/PlanarIntersectorP1P0PL.txx new file mode 100644 index 000000000..c86fa2c50 --- /dev/null +++ b/src/medtool/src/INTERP_KERNEL/PlanarIntersectorP1P0PL.txx @@ -0,0 +1,108 @@ +// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 +// 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 __PLANARINTERSECTORP1P0PL_TXX__ +#define __PLANARINTERSECTORP1P0PL_TXX__ + +#include "PlanarIntersectorP1P0PL.hxx" +#include "PlanarIntersector.txx" +#include "CellModel.hxx" + +#include "PointLocatorAlgos.txx" +#include "InterpKernelGeo2DQuadraticPolygon.hxx" +#include "MeshUtils.hxx" + +namespace INTERP_KERNEL +{ + template<class MyMeshType, class MyMatrix> + PlanarIntersectorP1P0PL<MyMeshType,MyMatrix>::PlanarIntersectorP1P0PL(const MyMeshType& meshT, const MyMeshType& meshS, + double dimCaracteristic, double md3DSurf, double minDot3DSurf, + double medianPlane, double precision, int orientation): + PlanarIntersector<MyMeshType,MyMatrix>(meshT,meshS,dimCaracteristic,precision,md3DSurf,minDot3DSurf,medianPlane,true,orientation,0) + { + } + + template<class MyMeshType, class MyMatrix> + void PlanarIntersectorP1P0PL<MyMeshType,MyMatrix>::intersectCells(ConnType icellT, const std::vector<ConnType>& icellsS, MyMatrix& res) + { + std::vector<double> CoordsT; + typename MyMatrix::value_type& resRow=res[icellT]; + PlanarIntersector<MyMeshType,MyMatrix>::getRealTargetCoordinates(OTT<ConnType,numPol>::indFC(icellT),CoordsT); + double baryT[SPACEDIM]; + double baryTTmp[SPACEDIM]; + calculateBarycenterDyn2<SPACEDIM>(&CoordsT[0],CoordsT.size()/SPACEDIM,baryT); + for(typename std::vector<ConnType>::const_iterator iter=icellsS.begin();iter!=icellsS.end();iter++) + { + NormalizedCellType tS=PlanarIntersector<MyMeshType,MyMatrix>::_meshS.getTypeOfElement(OTT<ConnType,numPol>::indFC(*iter)); + if(tS!=NORM_TRI3) + throw INTERP_KERNEL::Exception("Invalid source cell detected for meshdim==2. Only TRI3 supported !"); + std::vector<double> CoordsS; + PlanarIntersector<MyMeshType,MyMatrix>::getRealSourceCoordinates(OTT<ConnType,numPol>::indFC(*iter),CoordsS); + if(SPACEDIM==2) + { + std::copy(baryT,baryT+SPACEDIM,baryTTmp); + } + else + { + double littleTargetCell[9]; + std::copy(baryT,baryT+SPACEDIM,littleTargetCell); + std::copy(CoordsT.begin(),CoordsT.begin()+3,littleTargetCell+3); + std::copy(CoordsT.begin()+3,CoordsT.begin()+6,littleTargetCell+6); + PlanarIntersector<MyMeshType,MyMatrix>::projectionThis(&CoordsS[0],littleTargetCell,3,3); + std::copy(littleTargetCell,littleTargetCell+3,baryTTmp); + } + if(PointLocatorAlgos<MyMeshType>::isElementContainsPointAlg2D(baryTTmp,&CoordsS[0],3,PlanarIntersector<MyMeshType,MyMatrix>::_precision)) + { + double resLoc[3]; + barycentric_coords<SPACEDIM>(&CoordsS[0],baryTTmp,resLoc); + const ConnType *startOfCellNodeConnS=PlanarIntersector<MyMeshType,MyMatrix>::_connectS+OTT<ConnType,numPol>::conn2C(PlanarIntersector<MyMeshType,MyMatrix>::_connIndexS[*iter]); + for(int nodeIdS=0;nodeIdS<3;nodeIdS++) + { + if(fabs(resLoc[nodeIdS])>PlanarIntersector<MyMeshType,MyMatrix>::_precision) + { + ConnType curNodeSInCmode=OTT<ConnType,numPol>::coo2C(startOfCellNodeConnS[nodeIdS]); + typename MyMatrix::value_type::const_iterator iterRes=resRow.find(OTT<ConnType,numPol>::indFC(curNodeSInCmode)); + if(iterRes==resRow.end()) + resRow.insert(std::make_pair(OTT<ConnType,numPol>::indFC(curNodeSInCmode),resLoc[nodeIdS])); + else + { + double val=(*iterRes).second+resLoc[nodeIdS]; + resRow.erase(OTT<ConnType,numPol>::indFC(curNodeSInCmode)); + resRow.insert(std::make_pair(OTT<ConnType,numPol>::indFC(curNodeSInCmode),val)); + } + } + } + } + } + } + + template<class MyMeshType, class MyMatrix> + int PlanarIntersectorP1P0PL<MyMeshType,MyMatrix>::getNumberOfRowsOfResMatrix() const + { + return PlanarIntersector<MyMeshType,MyMatrix>::_meshT.getNumberOfElements(); + } + + template<class MyMeshType, class MyMatrix> + int PlanarIntersectorP1P0PL<MyMeshType,MyMatrix>::getNumberOfColsOfResMatrix() const + { + return PlanarIntersector<MyMeshType,MyMatrix>::_meshS.getNumberOfNodes(); + } +} + +#endif diff --git a/src/medtool/src/INTERP_KERNEL/PlanarIntersectorP1P1.hxx b/src/medtool/src/INTERP_KERNEL/PlanarIntersectorP1P1.hxx new file mode 100644 index 000000000..6c8cb310a --- /dev/null +++ b/src/medtool/src/INTERP_KERNEL/PlanarIntersectorP1P1.hxx @@ -0,0 +1,49 @@ +// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 +// 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 __PLANARINTERSECTORP1P1_HXX__ +#define __PLANARINTERSECTORP1P1_HXX__ + +#include "PlanarIntersector.hxx" + +namespace INTERP_KERNEL +{ + template<class MyMeshType, class MyMatrix, class ConcreteP1P1Intersector> + class PlanarIntersectorP1P1 : public PlanarIntersector<MyMeshType,MyMatrix> + { + public: + static const int SPACEDIM=MyMeshType::MY_SPACEDIM; + static const int MESHDIM=MyMeshType::MY_MESHDIM; + typedef typename MyMeshType::MyConnType ConnType; + static const NumberingPolicy numPol=MyMeshType::My_numPol; + protected: + PlanarIntersectorP1P1(const MyMeshType& meshT, const MyMeshType& meshS, double dimCaracteristic, double precision, double md3DSurf, double minDot3DSurf, double medianPlane, bool doRotate, int orientation, int printLevel); + public: + void intersectCells(ConnType icellT, const std::vector<ConnType>& icellsS, MyMatrix& res); + int getNumberOfRowsOfResMatrix() const; + int getNumberOfColsOfResMatrix() const; + + double intersectGeometryGeneral(const std::vector<double>& targetCoords, const std::vector<double>& sourceCoords) { return asLeaf().intersectGeometryGeneral(targetCoords,sourceCoords); } + protected: + ConcreteP1P1Intersector& asLeaf() { return static_cast<ConcreteP1P1Intersector&>(*this); } + }; +} + +#endif diff --git a/src/medtool/src/INTERP_KERNEL/PlanarIntersectorP1P1.txx b/src/medtool/src/INTERP_KERNEL/PlanarIntersectorP1P1.txx new file mode 100644 index 000000000..af1914139 --- /dev/null +++ b/src/medtool/src/INTERP_KERNEL/PlanarIntersectorP1P1.txx @@ -0,0 +1,102 @@ +// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 +// 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 __PLANARINTERSECTORP1P1_TXX__ +#define __PLANARINTERSECTORP1P1_TXX__ + +#include "PlanarIntersectorP1P1.hxx" +#include "InterpolationUtils.hxx" +#include "CellModel.hxx" + +namespace INTERP_KERNEL +{ + template<class MyMeshType, class MyMatrix, class ConcreteP1P1Intersector> + PlanarIntersectorP1P1<MyMeshType,MyMatrix,ConcreteP1P1Intersector>::PlanarIntersectorP1P1(const MyMeshType& meshT, const MyMeshType& meshS, + double dimCaracteristic, double precision, double md3DSurf, double minDot3DSurf, double medianPlane, + bool doRotate, int orientation, int printLevel): + PlanarIntersector<MyMeshType,MyMatrix>(meshT,meshS,dimCaracteristic,precision,md3DSurf,minDot3DSurf,medianPlane,doRotate,orientation,printLevel) + { + } + + template<class MyMeshType, class MyMatrix, class ConcreteP1P1Intersector> + int PlanarIntersectorP1P1<MyMeshType,MyMatrix,ConcreteP1P1Intersector>::getNumberOfRowsOfResMatrix() const + { + return PlanarIntersector<MyMeshType,MyMatrix>::_meshT.getNumberOfNodes(); + } + + template<class MyMeshType, class MyMatrix, class ConcreteP1P1Intersector> + int PlanarIntersectorP1P1<MyMeshType,MyMatrix,ConcreteP1P1Intersector>::getNumberOfColsOfResMatrix() const + { + return PlanarIntersector<MyMeshType,MyMatrix>::_meshS.getNumberOfNodes(); + } + + /*! + * This methods split on the fly, into triangles in order to compute dual mesh of target cell (with icellT id in target mesh in C mode). + */ + template<class MyMeshType, class MyMatrix, class ConcreteP1P1Intersector> + void PlanarIntersectorP1P1<MyMeshType,MyMatrix,ConcreteP1P1Intersector>::intersectCells(ConnType icellT, const std::vector<ConnType>& icellsS, MyMatrix& res) + { + int nbNodesT=PlanarIntersector<MyMeshType,MyMatrix>::_connIndexT[icellT+1]-PlanarIntersector<MyMeshType,MyMatrix>::_connIndexT[icellT]; + int orientation=1; + const ConnType *startOfCellNodeConn=PlanarIntersector<MyMeshType,MyMatrix>::_connectT+OTT<ConnType,numPol>::conn2C(PlanarIntersector<MyMeshType,MyMatrix>::_connIndexT[icellT]); + std::vector<double> polygT; + PlanarIntersector<MyMeshType,MyMatrix>::getRealTargetCoordinates(OTT<ConnType,numPol>::indFC(icellT),polygT); + for(int nodeIdT=0;nodeIdT<nbNodesT;nodeIdT++) + { + ConnType curNodeTInCmode=OTT<ConnType,numPol>::coo2C(startOfCellNodeConn[nodeIdT]); + PlanarIntersector<MyMeshType,MyMatrix>::getRealTargetCoordinatesPermute(OTT<ConnType,numPol>::indFC(icellT),nodeIdT,polygT); + std::vector<double> polygDualT(SPACEDIM*2*(nbNodesT-1)); + fillDualCellOfPolyg<SPACEDIM>(&polygT[0],polygT.size()/SPACEDIM,&polygDualT[0]); + typename MyMatrix::value_type& resRow=res[curNodeTInCmode]; + for(typename std::vector<ConnType>::const_iterator iter=icellsS.begin();iter!=icellsS.end();iter++) + { + int iS=*iter; + int nbNodesS=PlanarIntersector<MyMeshType,MyMatrix>::_connIndexS[iS+1]-PlanarIntersector<MyMeshType,MyMatrix>::_connIndexS[iS]; + const ConnType *startOfCellNodeConnS=PlanarIntersector<MyMeshType,MyMatrix>::_connectS+OTT<ConnType,numPol>::conn2C(PlanarIntersector<MyMeshType,MyMatrix>::_connIndexS[iS]); + for(int nodeIdS=0;nodeIdS<nbNodesS;nodeIdS++) + { + ConnType curNodeSInCmode=OTT<ConnType,numPol>::coo2C(startOfCellNodeConnS[nodeIdS]); + std::vector<double> polygS; + PlanarIntersector<MyMeshType,MyMatrix>::getRealSourceCoordinatesPermute(OTT<ConnType,numPol>::indFC(iS),nodeIdS,polygS); + std::vector<double> polygDualS(SPACEDIM*2*(nbNodesS-1)); + fillDualCellOfPolyg<SPACEDIM>(&polygS[0],polygS.size()/SPACEDIM,&polygDualS[0]); + std::vector<double> polygDualTTmp(polygDualT); + if(SPACEDIM==3) + orientation=PlanarIntersector<MyMeshType,MyMatrix>::projectionThis(&polygDualS[0],&polygDualTTmp[0],polygDualS.size()/SPACEDIM,polygDualT.size()/SPACEDIM); + double surf=orientation*intersectGeometryGeneral(polygDualTTmp,polygDualS); + surf=PlanarIntersector<MyMeshType,MyMatrix>::getValueRegardingOption(surf); + if(surf!=0.) + { + typename MyMatrix::value_type::const_iterator iterRes=resRow.find(OTT<ConnType,numPol>::indFC(curNodeSInCmode)); + if(iterRes==resRow.end()) + resRow.insert(std::make_pair(OTT<ConnType,numPol>::indFC(curNodeSInCmode),surf)); + else + { + double val=(*iterRes).second+surf; + resRow.erase(OTT<ConnType,numPol>::indFC(curNodeSInCmode)); + resRow.insert(std::make_pair(OTT<ConnType,numPol>::indFC(curNodeSInCmode),val)); + } + } + } + } + } + } +} + +#endif diff --git a/src/medtool/src/INTERP_KERNEL/PlanarIntersectorP1P1PL.hxx b/src/medtool/src/INTERP_KERNEL/PlanarIntersectorP1P1PL.hxx new file mode 100644 index 000000000..226d89e32 --- /dev/null +++ b/src/medtool/src/INTERP_KERNEL/PlanarIntersectorP1P1PL.hxx @@ -0,0 +1,44 @@ +// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 +// 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 __PLANARINTERSECTORP1P1PL_HXX__ +#define __PLANARINTERSECTORP1P1PL_HXX__ + +#include "PlanarIntersector.hxx" + +namespace INTERP_KERNEL +{ + template<class MyMeshType, class MyMatrix> + class PlanarIntersectorP1P1PL : public PlanarIntersector<MyMeshType,MyMatrix> + { + public: + static const int SPACEDIM=MyMeshType::MY_SPACEDIM; + static const int MESHDIM=MyMeshType::MY_MESHDIM; + typedef typename MyMeshType::MyConnType ConnType; + static const NumberingPolicy numPol=MyMeshType::My_numPol; + public: + PlanarIntersectorP1P1PL(const MyMeshType& meshT, const MyMeshType& meshS, double dimCaracteristic, double md3DSurf, double minDot3DSurf, double medianPlane, double precision, int orientation); + void intersectCells(ConnType icellT, const std::vector<ConnType>& icellsS, MyMatrix& res); + int getNumberOfRowsOfResMatrix() const; + int getNumberOfColsOfResMatrix() const; + }; +} + +#endif diff --git a/src/medtool/src/INTERP_KERNEL/PlanarIntersectorP1P1PL.txx b/src/medtool/src/INTERP_KERNEL/PlanarIntersectorP1P1PL.txx new file mode 100644 index 000000000..aa36f5cfe --- /dev/null +++ b/src/medtool/src/INTERP_KERNEL/PlanarIntersectorP1P1PL.txx @@ -0,0 +1,99 @@ +// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 +// 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 __PLANARINTERSECTORP1P1PL_TXX__ +#define __PLANARINTERSECTORP1P1PL_TXX__ + +#include "PlanarIntersectorP1P1PL.hxx" +#include "PlanarIntersector.txx" +#include "CellModel.hxx" + +#include "PointLocatorAlgos.txx" +#include "MeshUtils.hxx" + +namespace INTERP_KERNEL +{ + template<class MyMeshType, class MyMatrix> + PlanarIntersectorP1P1PL<MyMeshType,MyMatrix>::PlanarIntersectorP1P1PL(const MyMeshType& meshT, const MyMeshType& meshS, + double dimCaracteristic, double md3DSurf, double minDot3DSurf, + double medianPlane, double precision, int orientation): + PlanarIntersector<MyMeshType,MyMatrix>(meshT,meshS,dimCaracteristic,precision,md3DSurf,minDot3DSurf,medianPlane,true,orientation,0) + { + } + + template<class MyMeshType, class MyMatrix> + void PlanarIntersectorP1P1PL<MyMeshType,MyMatrix>::intersectCells(ConnType icellT, const std::vector<ConnType>& icellsS, MyMatrix& res) + { + std::vector<double> CoordsT; + PlanarIntersector<MyMeshType,MyMatrix>::getRealTargetCoordinates(OTT<ConnType,numPol>::indFC(icellT),CoordsT); + int nbOfNodesT=CoordsT.size()/SPACEDIM; + for(typename std::vector<ConnType>::const_iterator iter=icellsS.begin();iter!=icellsS.end();iter++) + { + NormalizedCellType tS=PlanarIntersector<MyMeshType,MyMatrix>::_meshS.getTypeOfElement(OTT<ConnType,numPol>::indFC(*iter)); + if(tS!=NORM_TRI3) + throw INTERP_KERNEL::Exception("Invalid source cell detected for meshdim==2. Only TRI3 supported !"); + std::vector<double> CoordsS; + PlanarIntersector<MyMeshType,MyMatrix>::getRealSourceCoordinates(OTT<ConnType,numPol>::indFC(*iter),CoordsS); + std::vector<double> CoordsTTmp(CoordsT); + if(SPACEDIM==3) + PlanarIntersector<MyMeshType,MyMatrix>::projectionThis(&CoordsS[0],&CoordsTTmp[0],CoordsS.size()/SPACEDIM,nbOfNodesT); + const ConnType *startOfCellNodeConnT=PlanarIntersector<MyMeshType,MyMatrix>::_connectT+OTT<ConnType,numPol>::conn2C(PlanarIntersector<MyMeshType,MyMatrix>::_connIndexT[icellT]); + for(int nodeIdT=0;nodeIdT<nbOfNodesT;nodeIdT++) + { + typename MyMatrix::value_type& resRow=res[OTT<ConnType,numPol>::ind2C(startOfCellNodeConnT[nodeIdT])]; + if( PointLocatorAlgos<MyMeshType>::isElementContainsPointAlg2D(&CoordsTTmp[nodeIdT*SPACEDIM],&CoordsS[0],3,PlanarIntersector<MyMeshType,MyMatrix>::_precision) ) + { + double resLoc[3]; + barycentric_coords<SPACEDIM>(&CoordsS[0],&CoordsTTmp[nodeIdT*SPACEDIM],resLoc); + const ConnType *startOfCellNodeConnS=PlanarIntersector<MyMeshType,MyMatrix>::_connectS+OTT<ConnType,numPol>::conn2C(PlanarIntersector<MyMeshType,MyMatrix>::_connIndexS[*iter]); + for(int nodeIdS=0;nodeIdS<3;nodeIdS++) + { + if(fabs(resLoc[nodeIdS])>PlanarIntersector<MyMeshType,MyMatrix>::_precision) + { + ConnType curNodeSInCmode=OTT<ConnType,numPol>::coo2C(startOfCellNodeConnS[nodeIdS]); + typename MyMatrix::value_type::const_iterator iterRes=resRow.find(OTT<ConnType,numPol>::indFC(curNodeSInCmode)); + if(iterRes==resRow.end()) + resRow.insert(std::make_pair(OTT<ConnType,numPol>::indFC(curNodeSInCmode),resLoc[nodeIdS])); + else + { + double val=(*iterRes).second+resLoc[nodeIdS]; + resRow.erase(OTT<ConnType,numPol>::indFC(curNodeSInCmode)); + resRow.insert(std::make_pair(OTT<ConnType,numPol>::indFC(curNodeSInCmode),val)); + } + } + } + } + } + } + } + + template<class MyMeshType, class MyMatrix> + int PlanarIntersectorP1P1PL<MyMeshType,MyMatrix>::getNumberOfRowsOfResMatrix() const + { + return PlanarIntersector<MyMeshType,MyMatrix>::_meshT.getNumberOfNodes(); + } + + template<class MyMeshType, class MyMatrix> + int PlanarIntersectorP1P1PL<MyMeshType,MyMatrix>::getNumberOfColsOfResMatrix() const + { + return PlanarIntersector<MyMeshType,MyMatrix>::_meshS.getNumberOfNodes(); + } +} + +#endif diff --git a/src/medtool/src/INTERP_KERNEL/PointLocator2DIntersector.hxx b/src/medtool/src/INTERP_KERNEL/PointLocator2DIntersector.hxx new file mode 100644 index 000000000..51251c3ec --- /dev/null +++ b/src/medtool/src/INTERP_KERNEL/PointLocator2DIntersector.hxx @@ -0,0 +1,56 @@ +// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 +// 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 __POINTLOCATORINTERSECTOR_HXX__ +#define __POINTLOCATORINTERSECTOR_HXX__ + +#include "PlanarIntersectorP0P0.hxx" +#include "PlanarIntersectorP0P1.hxx" +#include "PlanarIntersectorP1P0.hxx" +#include "PlanarIntersectorP1P1.hxx" +#include "PlanarIntersectorP1P0Bary.hxx" + +namespace INTERP_KERNEL +{ + class QuadraticPolygon; + + template<class MyMeshType, class MyMatrix, template <class MeshType, class TheMatrix, class ThisIntersector> class InterpType> + class PointLocator2DIntersector : public InterpType<MyMeshType,MyMatrix,PointLocator2DIntersector<MyMeshType,MyMatrix,InterpType> > + { + public: + static const int SPACEDIM=MyMeshType::MY_SPACEDIM; + static const int MESHDIM=MyMeshType::MY_MESHDIM; + typedef typename MyMeshType::MyConnType ConnType; + static const NumberingPolicy numPol=MyMeshType::My_numPol; + public: + PointLocator2DIntersector(const MyMeshType& meshT, const MyMeshType& meshS, + double dimCaracteristic, double md3DSurf, double minDot3DSurf, double medianPlane, double precision, int orientation); + double intersectGeometry(ConnType icellT, ConnType icellS, ConnType nbNodesT, ConnType nbNodesS); + double intersectGeometryWithQuadrangle(const double *quadrangle, const std::vector<double>& sourceCoords, bool isSourceQuad); + double intersectGeometryGeneral(const std::vector<double>& targetCoords, const std::vector<double>& sourceCoords); + double intersectGeoBary(const std::vector<double>& targetCell, bool targetCellQuadratic, const double *sourceCell, std::vector<double>& res); + private: + QuadraticPolygon *buildPolygonFrom(const std::vector<double>& coords, NormalizedCellType type); + QuadraticPolygon *buildPolygonAFrom(ConnType cell, int nbOfPoints, NormalizedCellType type); + QuadraticPolygon *buildPolygonBFrom(ConnType cell, int nbOfPoints, NormalizedCellType type); + }; +} + +#endif diff --git a/src/medtool/src/INTERP_KERNEL/PointLocator2DIntersector.txx b/src/medtool/src/INTERP_KERNEL/PointLocator2DIntersector.txx new file mode 100644 index 000000000..0f83435c6 --- /dev/null +++ b/src/medtool/src/INTERP_KERNEL/PointLocator2DIntersector.txx @@ -0,0 +1,165 @@ +// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 +// 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 __POINTLOCATORINTERSECTOR_TXX__ +#define __POINTLOCATORINTERSECTOR_TXX__ + +#include "PointLocator2DIntersector.hxx" +#include "PlanarIntersectorP0P0.txx" +#include "PlanarIntersectorP0P1.txx" +#include "PlanarIntersectorP1P0.txx" +#include "PlanarIntersectorP1P1.txx" +#include "PlanarIntersectorP1P0Bary.txx" +#include "CellModel.hxx" + +#include "InterpKernelGeo2DQuadraticPolygon.hxx" +#include "PointLocatorAlgos.txx" + +#define PTLOC2D_INTERSECTOR PointLocator2DIntersector<MyMeshType,MyMatrix,InterpType> +#define INTERSECTOR_TEMPLATE template<class MyMeshType, class MyMatrix, template <class MeshType, class TheMatrix, class ThisIntersector> class InterpType> + +namespace INTERP_KERNEL +{ + INTERSECTOR_TEMPLATE + PTLOC2D_INTERSECTOR::PointLocator2DIntersector(const MyMeshType& meshT, const MyMeshType& meshS, + double dimCaracteristic, double md3DSurf, double minDot3DSurf, double medianPlane, + double precision, int orientation): + InterpType<MyMeshType,MyMatrix,PTLOC2D_INTERSECTOR >(meshT,meshS,dimCaracteristic, precision, md3DSurf, minDot3DSurf, medianPlane, true, orientation, 0) + { + } + + INTERSECTOR_TEMPLATE + double PTLOC2D_INTERSECTOR::intersectGeometry(ConnType icellT, ConnType icellS, + ConnType nbNodesT, ConnType nbNodesS) + { + int orientation = 1; + std::vector<double> CoordsT; + std::vector<double> CoordsS; + PlanarIntersector<MyMeshType,MyMatrix>::getRealCoordinates(icellT,icellS,nbNodesT,nbNodesS,CoordsT,CoordsS,orientation); + NormalizedCellType tT=PlanarIntersector<MyMeshType,MyMatrix>::_meshT.getTypeOfElement(icellT); + QuadraticPolygon *pT=buildPolygonFrom(CoordsT,tT); + double baryT[SPACEDIM]; + pT->getBarycenterGeneral(baryT); + delete pT; + if(PointLocatorAlgos<MyMeshType>::isElementContainsPointAlg2D(baryT,&CoordsS[0],nbNodesS,InterpType<MyMeshType,MyMatrix,PTLOC2D_INTERSECTOR >::_precision)) + return 1.; + return 0.; + } + + INTERSECTOR_TEMPLATE + double PTLOC2D_INTERSECTOR::intersectGeometryWithQuadrangle(const double * quadrangle, + const std::vector<double>& sourceCoords, + bool isSourceQuad) + { + int nbOfSourceNodes=sourceCoords.size()/SPACEDIM; + std::vector<Node *> nodes2(nbOfSourceNodes); + for(int i=0;i<nbOfSourceNodes;i++) + nodes2[i]=new Node(sourceCoords[i*SPACEDIM],sourceCoords[i*SPACEDIM+1]); + QuadraticPolygon *p2; + if(!isSourceQuad) + p2=QuadraticPolygon::BuildLinearPolygon(nodes2); + else + p2=QuadraticPolygon::BuildArcCirclePolygon(nodes2); + double bary[SPACEDIM]; + p2->getBarycenter(bary); + delete p2; + if( PointLocatorAlgos<MyMeshType>::isElementContainsPointAlg2D(bary,quadrangle,4) ) + return 1.; + return 0.; + } + + INTERSECTOR_TEMPLATE + double PTLOC2D_INTERSECTOR::intersectGeometryGeneral(const std::vector<double>& targetCoords, + const std::vector<double>& sourceCoords) + { + int nbOfTargetNodes=targetCoords.size()/SPACEDIM; + int nbOfSourceNodes=sourceCoords.size()/SPACEDIM; + std::vector<Node *> nodes2(nbOfSourceNodes); + for(int i=0;i<nbOfSourceNodes;i++) + nodes2[i]=new Node(sourceCoords[i*SPACEDIM],sourceCoords[i*SPACEDIM+1]); + QuadraticPolygon *p=QuadraticPolygon::BuildLinearPolygon(nodes2); + double bary[SPACEDIM]; + p->getBarycenterGeneral(bary); + delete p; + if( PointLocatorAlgos<MyMeshType>::isElementContainsPointAlg2D(bary,&targetCoords[0],nbOfTargetNodes) ) + return 1.; + return 0.; + } + + //================================================================================ + /*! + * \brief Intersect a triangle and a polygon for P1P0 barycentric algorithm + * \param targetCell - list of coordinates of target polygon in full interlace + * \param targetCellQuadratic - specifies if target polygon is quadratic or not + * \param sourceTria - list of coordinates of source triangle + * \param res - coefficients a,b and c associated to nodes of sourceTria + */ + //================================================================================ + + INTERSECTOR_TEMPLATE + double PTLOC2D_INTERSECTOR::intersectGeoBary(const std::vector<double>& targetCell, + bool targetCellQuadratic, + const double * sourceTria, + std::vector<double>& res) + { + throw INTERP_KERNEL::Exception("intersectGeoBary incompatible with PointLocator. Desactivate P1P0Bary to avoid the problem"); + return 0.; + } + + INTERSECTOR_TEMPLATE + QuadraticPolygon *PTLOC2D_INTERSECTOR::buildPolygonFrom(const std::vector<double>& coords, NormalizedCellType type) + { + int nbNodes=coords.size()/SPACEDIM; + std::vector<Node *> nodes(nbNodes); + for(int i=0;i<nbNodes;i++) + nodes[i]=new Node(coords[i*SPACEDIM],coords[i*SPACEDIM+1]); + if(!CellModel::GetCellModel(type).isQuadratic()) + return QuadraticPolygon::BuildLinearPolygon(nodes); + else + return QuadraticPolygon::BuildArcCirclePolygon(nodes); + } + + INTERSECTOR_TEMPLATE + QuadraticPolygon *PTLOC2D_INTERSECTOR::buildPolygonAFrom(ConnType cell, int nbOfPoints, NormalizedCellType type) + { + const ConnType *startOfCellNodeConn=PlanarIntersector<MyMeshType,MyMatrix>::_connectT+OTT<ConnType,numPol>::conn2C(PlanarIntersector<MyMeshType,MyMatrix>::_connIndexT[OTT<ConnType,numPol>::ind2C(cell)]); + std::vector<Node *> nodes(nbOfPoints); + for(int i=0;i<nbOfPoints;i++) + nodes[i]=new Node(PlanarIntersector<MyMeshType,MyMatrix>::_coordsT+OTT<ConnType,numPol>::coo2C(startOfCellNodeConn[i])*SPACEDIM); + if(CellModel::GetCellModel(type).isQuadratic()) + return QuadraticPolygon::BuildLinearPolygon(nodes); + else + return QuadraticPolygon::BuildArcCirclePolygon(nodes); + } + + INTERSECTOR_TEMPLATE + QuadraticPolygon *PTLOC2D_INTERSECTOR::buildPolygonBFrom(ConnType cell, int nbOfPoints, NormalizedCellType type) + { + const ConnType *startOfCellNodeConn=PlanarIntersector<MyMeshType,MyMatrix>::_connectS+OTT<ConnType,numPol>::conn2C(PlanarIntersector<MyMeshType,MyMatrix>::_connIndexS[OTT<ConnType,numPol>::ind2C(cell)]); + std::vector<Node *> nodes(nbOfPoints); + for(int i=0;i<nbOfPoints;i++) + nodes[i]=new Node(PlanarIntersector<MyMeshType,MyMatrix>::_coordsS+OTT<ConnType,numPol>::coo2C(startOfCellNodeConn[i])*SPACEDIM); + if(type!=NORM_TRI6 && type!=NORM_QUAD8) + return QuadraticPolygon::BuildLinearPolygon(nodes); + else + return QuadraticPolygon::BuildArcCirclePolygon(nodes); + } +} + +#endif diff --git a/src/medtool/src/INTERP_KERNEL/PointLocator3DIntersectorP0P0.hxx b/src/medtool/src/INTERP_KERNEL/PointLocator3DIntersectorP0P0.hxx new file mode 100644 index 000000000..54b46415d --- /dev/null +++ b/src/medtool/src/INTERP_KERNEL/PointLocator3DIntersectorP0P0.hxx @@ -0,0 +1,46 @@ +// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 +// 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 __POINTLOCATOR3DINTERSECTORP0P0_HXX__ +#define __POINTLOCATOR3DINTERSECTORP0P0_HXX__ + +#include "Intersector3DP0P0.hxx" +#include "NormalizedUnstructuredMesh.hxx" + +namespace INTERP_KERNEL +{ + template<class MyMeshType, class MyMatrix> + class PointLocator3DIntersectorP0P0 : public Intersector3DP0P0<MyMeshType,MyMatrix> + { + public: + static const int SPACEDIM=MyMeshType::MY_SPACEDIM; + static const int MESHDIM=MyMeshType::MY_MESHDIM; + typedef typename MyMeshType::MyConnType ConnType; + static const NumberingPolicy numPol=MyMeshType::My_numPol; + public: + PointLocator3DIntersectorP0P0(const MyMeshType& targetMesh, const MyMeshType& srcMesh, double precision); + ~PointLocator3DIntersectorP0P0(); + void intersectCells(ConnType targetCell, const std::vector<ConnType>& srcCells, MyMatrix& res); + protected: + double _precision; + }; +} + +#endif diff --git a/src/medtool/src/INTERP_KERNEL/PointLocator3DIntersectorP0P0.txx b/src/medtool/src/INTERP_KERNEL/PointLocator3DIntersectorP0P0.txx new file mode 100644 index 000000000..197e644dd --- /dev/null +++ b/src/medtool/src/INTERP_KERNEL/PointLocator3DIntersectorP0P0.txx @@ -0,0 +1,78 @@ +// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 +// 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 __POINTLOCATOR3DINTERSECTORP0P0_TXX__ +#define __POINTLOCATOR3DINTERSECTORP0P0_TXX__ + +#include "PointLocator3DIntersectorP0P0.hxx" +#include "Intersector3DP0P0.txx" +#include "MeshUtils.hxx" + +#include "SplitterTetra.txx" +#include "PointLocatorAlgos.txx" + +namespace INTERP_KERNEL +{ + + /** + * @param targetMesh mesh containing the target elements + * @param srcMesh mesh containing the source elements + * @param policy splitting policy to be used + */ + template<class MyMeshType, class MyMatrix> + PointLocator3DIntersectorP0P0<MyMeshType,MyMatrix>::PointLocator3DIntersectorP0P0(const MyMeshType& targetMesh, const MyMeshType& srcMesh, double precision): + Intersector3DP0P0<MyMeshType,MyMatrix>(targetMesh,srcMesh),_precision(precision) + { + } + + template<class MyMeshType, class MyMatrix> + PointLocator3DIntersectorP0P0<MyMeshType,MyMatrix>::~PointLocator3DIntersectorP0P0() + { + } + + /** + * + * @param targetCell in C mode. + * @param srcCells in C mode. + * + */ + template<class MyMeshType, class MyMatrix> + void PointLocator3DIntersectorP0P0<MyMeshType,MyMatrix>::intersectCells(ConnType targetCell, const std::vector<ConnType>& srcCells, MyMatrix& res) + { + std::vector<double> CoordsT; + Intersector3DP0P0<MyMeshType,MyMatrix>::getRealTargetCoordinates(OTT<ConnType,numPol>::indFC(targetCell),CoordsT); + double bary[SPACEDIM]; + calculateBarycenterDyn2<SPACEDIM>(&CoordsT[0],CoordsT.size()/SPACEDIM,bary); + typename MyMatrix::value_type& resRow=res[targetCell]; + const double *coordsS=Intersector3DP0P0<MyMeshType,MyMatrix>::_src_mesh.getCoordinatesPtr(); + for(typename std::vector<ConnType>::const_iterator iterCellS=srcCells.begin();iterCellS!=srcCells.end();iterCellS++) + { + NormalizedCellType tS=Intersector3DP0P0<MyMeshType,MyMatrix>::_src_mesh.getTypeOfElement(OTT<ConnType,numPol>::indFC(*iterCellS)); + const CellModel& cmTypeS=CellModel::GetCellModel(tS); + std::vector<ConnType> connOfCurCellS; + Intersector3DP0P0<MyMeshType,MyMatrix>::getConnOfSourceCell(OTT<ConnType,numPol>::indFC(*iterCellS),connOfCurCellS); + if(PointLocatorAlgos<MyMeshType>::isElementContainsPointAlg3D(bary,&connOfCurCellS[0],connOfCurCellS.size(),coordsS,cmTypeS,_precision)) + { + resRow.insert(std::make_pair(OTT<ConnType,numPol>::indFC(*iterCellS),1)); + } + } + } +} + +#endif diff --git a/src/medtool/src/INTERP_KERNEL/PointLocator3DIntersectorP0P1.hxx b/src/medtool/src/INTERP_KERNEL/PointLocator3DIntersectorP0P1.hxx new file mode 100644 index 000000000..a7eb4fc19 --- /dev/null +++ b/src/medtool/src/INTERP_KERNEL/PointLocator3DIntersectorP0P1.hxx @@ -0,0 +1,46 @@ +// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 +// 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 __POINTLOCATOR3DINTERSECTORP0P1_HXX__ +#define __POINTLOCATOR3DINTERSECTORP0P1_HXX__ + +#include "Intersector3DP0P1.hxx" +#include "NormalizedUnstructuredMesh.hxx" + +namespace INTERP_KERNEL +{ + template<class MyMeshType, class MyMatrix> + class PointLocator3DIntersectorP0P1 : public Intersector3DP0P1<MyMeshType,MyMatrix> + { + public: + static const int SPACEDIM=MyMeshType::MY_SPACEDIM; + static const int MESHDIM=MyMeshType::MY_MESHDIM; + typedef typename MyMeshType::MyConnType ConnType; + static const NumberingPolicy numPol=MyMeshType::My_numPol; + public: + PointLocator3DIntersectorP0P1(const MyMeshType& targetMesh, const MyMeshType& srcMesh, double precision); + ~PointLocator3DIntersectorP0P1(); + void intersectCells(ConnType targetCell, const std::vector<ConnType>& srcCells, MyMatrix& res); + protected: + double _precision; + }; +} + +#endif diff --git a/src/medtool/src/INTERP_KERNEL/PointLocator3DIntersectorP0P1.txx b/src/medtool/src/INTERP_KERNEL/PointLocator3DIntersectorP0P1.txx new file mode 100644 index 000000000..0b0e68eeb --- /dev/null +++ b/src/medtool/src/INTERP_KERNEL/PointLocator3DIntersectorP0P1.txx @@ -0,0 +1,81 @@ +// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 +// 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 __POINTLOCATOR3DINTERSECTORP0P1_TXX__ +#define __POINTLOCATOR3DINTERSECTORP0P1_TXX__ + +#include "PointLocator3DIntersectorP0P1.hxx" +#include "Intersector3DP0P1.txx" +#include "MeshUtils.hxx" + +namespace INTERP_KERNEL +{ + + /** + * @param targetMesh mesh containing the target elements + * @param srcMesh mesh containing the source elements + * @param policy splitting policy to be used + */ + template<class MyMeshType, class MyMatrix> + PointLocator3DIntersectorP0P1<MyMeshType,MyMatrix>::PointLocator3DIntersectorP0P1(const MyMeshType& targetMesh, const MyMeshType& srcMesh, double precision): + Intersector3DP0P1<MyMeshType,MyMatrix>(targetMesh,srcMesh),_precision(precision) + { + } + + template<class MyMeshType, class MyMatrix> + PointLocator3DIntersectorP0P1<MyMeshType,MyMatrix>::~PointLocator3DIntersectorP0P1() + { + } + + /** + * + * @param targetCell in C mode. + * @param srcCells in C mode. + * + */ + template<class MyMeshType, class MyMatrix> + void PointLocator3DIntersectorP0P1<MyMeshType,MyMatrix>::intersectCells(ConnType targetCell, const std::vector<ConnType>& srcCells, MyMatrix& res) + { + std::vector<double> coordsTarget; + Intersector3DP0P1<MyMeshType,MyMatrix>::getRealTargetCoordinates(OTT<ConnType,numPol>::indFC(targetCell),coordsTarget); + int nbNodesT=coordsTarget.size()/SPACEDIM; + const double *coordsS=Intersector3DP0P1<MyMeshType,MyMatrix>::_src_mesh.getCoordinatesPtr(); + const ConnType *startOfCellNodeConnT=Intersector3DP0P1<MyMeshType,MyMatrix>::getStartConnOfTargetCell(targetCell); + for(typename std::vector<ConnType>::const_iterator iterCellS=srcCells.begin();iterCellS!=srcCells.end();iterCellS++) + { + NormalizedCellType tS=Intersector3DP0P1<MyMeshType,MyMatrix>::_src_mesh.getTypeOfElement(OTT<ConnType,numPol>::indFC(*iterCellS)); + const CellModel& cmTypeS=CellModel::GetCellModel(tS); + std::vector<ConnType> connOfCurCellS; + Intersector3DP0P1<MyMeshType,MyMatrix>::getConnOfSourceCell(OTT<ConnType,numPol>::indFC(*iterCellS),connOfCurCellS); + for(int nodeIdT=0;nodeIdT<nbNodesT;nodeIdT++) + { + if(PointLocatorAlgos<MyMeshType>::isElementContainsPointAlg3D(&coordsTarget[nodeIdT*SPACEDIM],&connOfCurCellS[0],connOfCurCellS.size(),coordsS,cmTypeS,_precision)) + { + ConnType curNodeTInCmode=OTT<ConnType,numPol>::coo2C(startOfCellNodeConnT[nodeIdT]); + typename MyMatrix::value_type& resRow=res[curNodeTInCmode]; + typename MyMatrix::value_type::const_iterator iterRes=resRow.find(OTT<ConnType,numPol>::indFC(*iterCellS)); + if(iterRes==resRow.end()) + resRow.insert(std::make_pair(OTT<ConnType,numPol>::indFC(*iterCellS),1.)); + } + } + } + } +} + +#endif diff --git a/src/medtool/src/INTERP_KERNEL/PointLocator3DIntersectorP1P0.hxx b/src/medtool/src/INTERP_KERNEL/PointLocator3DIntersectorP1P0.hxx new file mode 100644 index 000000000..012dc28c2 --- /dev/null +++ b/src/medtool/src/INTERP_KERNEL/PointLocator3DIntersectorP1P0.hxx @@ -0,0 +1,46 @@ +// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 +// 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 __POINTLOCATOR3DINTERSECTORP1P0_HXX__ +#define __POINTLOCATOR3DINTERSECTORP1P0_HXX__ + +#include "Intersector3DP1P0.hxx" +#include "NormalizedUnstructuredMesh.hxx" + +namespace INTERP_KERNEL +{ + template<class MyMeshType, class MyMatrix> + class PointLocator3DIntersectorP1P0 : public Intersector3DP1P0<MyMeshType,MyMatrix> + { + public: + static const int SPACEDIM=MyMeshType::MY_SPACEDIM; + static const int MESHDIM=MyMeshType::MY_MESHDIM; + typedef typename MyMeshType::MyConnType ConnType; + static const NumberingPolicy numPol=MyMeshType::My_numPol; + public: + PointLocator3DIntersectorP1P0(const MyMeshType& targetMesh, const MyMeshType& srcMesh, double precision); + ~PointLocator3DIntersectorP1P0(); + void intersectCells(ConnType targetCell, const std::vector<ConnType>& srcCells, MyMatrix& res); + protected: + double _precision; + }; +} + +#endif diff --git a/src/medtool/src/INTERP_KERNEL/PointLocator3DIntersectorP1P0.txx b/src/medtool/src/INTERP_KERNEL/PointLocator3DIntersectorP1P0.txx new file mode 100644 index 000000000..e611b8bee --- /dev/null +++ b/src/medtool/src/INTERP_KERNEL/PointLocator3DIntersectorP1P0.txx @@ -0,0 +1,99 @@ +// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 +// 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 __POINTLOCATOR3DINTERSECTORP1P0_TXX__ +#define __POINTLOCATOR3DINTERSECTORP1P0_TXX__ + +#include "PointLocator3DIntersectorP1P0.hxx" +#include "Intersector3DP1P0.txx" +#include "MeshUtils.hxx" + +namespace INTERP_KERNEL +{ + /** + * @param targetMesh mesh containing the target elements + * @param srcMesh mesh containing the source elements + * @param policy splitting policy to be used + * + * WARNING : in _split attribute, sourceMesh and targetMesh are switched in order to fit intersectCells feature. + */ + template<class MyMeshType, class MyMatrix> + PointLocator3DIntersectorP1P0<MyMeshType,MyMatrix>::PointLocator3DIntersectorP1P0(const MyMeshType& targetMesh, const MyMeshType& srcMesh, double precision):Intersector3DP1P0<MyMeshType,MyMatrix>(targetMesh,srcMesh),_precision(precision) + { + } + + template<class MyMeshType, class MyMatrix> + PointLocator3DIntersectorP1P0<MyMeshType,MyMatrix>::~PointLocator3DIntersectorP1P0() + { + } + + /** + * @param targetCell in C mode. + * @param srcCells in C mode. + * + * WARNING : for all methods on _split object source and target are switched ! + */ + template<class MyMeshType, class MyMatrix> + void PointLocator3DIntersectorP1P0<MyMeshType,MyMatrix>::intersectCells(ConnType targetCell, const std::vector<ConnType>& srcCells, MyMatrix& res) + { + std::vector<double> CoordsT; + typename MyMatrix::value_type& resRow=res[targetCell]; + const double *coordsS=Intersector3DP1P0<MyMeshType,MyMatrix>::_src_mesh.getCoordinatesPtr(); + Intersector3DP1P0<MyMeshType,MyMatrix>::getRealTargetCoordinates(OTT<ConnType,numPol>::indFC(targetCell),CoordsT); + double baryT[SPACEDIM]; + calculateBarycenterDyn2<SPACEDIM>(&CoordsT[0],CoordsT.size()/SPACEDIM,baryT); + for(typename std::vector<ConnType>::const_iterator iterCellS=srcCells.begin();iterCellS!=srcCells.end();iterCellS++) + { + NormalizedCellType tS=Intersector3DP1P0<MyMeshType,MyMatrix>::_src_mesh.getTypeOfElement(OTT<ConnType,numPol>::indFC(*iterCellS)); + if(tS!=NORM_TETRA4) + throw INTERP_KERNEL::Exception("Invalid source cell detected for meshdim==3. Only TETRA4 supported !"); + const CellModel& cmTypeS=CellModel::GetCellModel(tS); + std::vector<ConnType> connOfCurCellS; + Intersector3DP1P0<MyMeshType,MyMatrix>::getConnOfSourceCell(OTT<ConnType,numPol>::indFC(*iterCellS),connOfCurCellS); + if( PointLocatorAlgos<MyMeshType>::isElementContainsPointAlg3D(baryT,&connOfCurCellS[0],connOfCurCellS.size(),coordsS,cmTypeS,_precision) ) + { + double resLoc[4]; + std::vector<double> srcCell; + Intersector3DP1P0<MyMeshType,MyMatrix>::getRealSourceCoordinates(OTT<ConnType,numPol>::indFC(*iterCellS),srcCell); + std::vector<const double*> eap(4); + eap[0]=&srcCell[0]; eap[1]=&srcCell[3]; eap[2]=&srcCell[6]; eap[3]=&srcCell[9]; + barycentric_coords(eap,baryT,resLoc); + const ConnType *startOfCellNodeConn=Intersector3DP1P0<MyMeshType,MyMatrix>::getStartConnOfSourceCell(*iterCellS); + for(int nodeIdS=0;nodeIdS<4;nodeIdS++) + { + if(fabs(resLoc[nodeIdS])>_precision) + { + ConnType curNodeSInCmode=OTT<ConnType,numPol>::coo2C(startOfCellNodeConn[nodeIdS]); + typename MyMatrix::value_type::const_iterator iterRes=resRow.find(OTT<ConnType,numPol>::indFC(curNodeSInCmode)); + if(iterRes==resRow.end()) + resRow.insert(std::make_pair(OTT<ConnType,numPol>::indFC(curNodeSInCmode),resLoc[nodeIdS])); + else + { + double val=(*iterRes).second+resLoc[nodeIdS]; + resRow.erase(OTT<ConnType,numPol>::indFC(curNodeSInCmode)); + resRow.insert(std::make_pair(OTT<ConnType,numPol>::indFC(curNodeSInCmode),val)); + } + } + } + } + } + } +} + +#endif diff --git a/src/medtool/src/INTERP_KERNEL/PointLocator3DIntersectorP1P1.hxx b/src/medtool/src/INTERP_KERNEL/PointLocator3DIntersectorP1P1.hxx new file mode 100644 index 000000000..6eb18993f --- /dev/null +++ b/src/medtool/src/INTERP_KERNEL/PointLocator3DIntersectorP1P1.hxx @@ -0,0 +1,46 @@ +// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 +// 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 __POINTLOCATOR3DINTERSECTORP1P1_HXX__ +#define __POINTLOCATOR3DINTERSECTORP1P1_HXX__ + +#include "Intersector3DP1P1.hxx" +#include "NormalizedUnstructuredMesh.hxx" + +namespace INTERP_KERNEL +{ + template<class MyMeshType, class MyMatrix> + class PointLocator3DIntersectorP1P1 : public Intersector3DP1P1<MyMeshType,MyMatrix> + { + public: + static const int SPACEDIM=MyMeshType::MY_SPACEDIM; + static const int MESHDIM=MyMeshType::MY_MESHDIM; + typedef typename MyMeshType::MyConnType ConnType; + static const NumberingPolicy numPol=MyMeshType::My_numPol; + public: + PointLocator3DIntersectorP1P1(const MyMeshType& targetMesh, const MyMeshType& srcMesh, double precision); + ~PointLocator3DIntersectorP1P1(); + void intersectCells(ConnType targetCell, const std::vector<ConnType>& srcCells, MyMatrix& res); + protected: + double _precision; + }; +} + +#endif diff --git a/src/medtool/src/INTERP_KERNEL/PointLocator3DIntersectorP1P1.txx b/src/medtool/src/INTERP_KERNEL/PointLocator3DIntersectorP1P1.txx new file mode 100644 index 000000000..ddc9c41b8 --- /dev/null +++ b/src/medtool/src/INTERP_KERNEL/PointLocator3DIntersectorP1P1.txx @@ -0,0 +1,102 @@ +// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 +// 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 __POINTLOCATOR3DINTERSECTORP1P1_TXX__ +#define __POINTLOCATOR3DINTERSECTORP1P1_TXX__ + +#include "PointLocator3DIntersectorP1P1.hxx" +#include "Intersector3DP1P1.txx" +#include "MeshUtils.hxx" + +namespace INTERP_KERNEL +{ + + /** + * Constructor creating object from target cell global number + * + * @param targetMesh mesh containing the target elements + * @param srcMesh mesh containing the source elements + * @param policy splitting policy to be used + */ + template<class MyMeshType, class MyMatrix> + PointLocator3DIntersectorP1P1<MyMeshType,MyMatrix>::PointLocator3DIntersectorP1P1(const MyMeshType& targetMesh, const MyMeshType& srcMesh, double precision): + Intersector3DP1P1<MyMeshType,MyMatrix>(targetMesh,srcMesh),_precision(precision) + { + } + + template<class MyMeshType, class MyMatrix> + PointLocator3DIntersectorP1P1<MyMeshType,MyMatrix>::~PointLocator3DIntersectorP1P1() + { + } + + /** + * @param targetCell in C mode. + * @param srcCells in C mode. + */ + template<class MyMeshType, class MyMatrix> + void PointLocator3DIntersectorP1P1<MyMeshType,MyMatrix>::intersectCells(ConnType targetCell, const std::vector<ConnType>& srcCells, MyMatrix& res) + { + std::vector<double> CoordsT; + Intersector3DP1P1<MyMeshType,MyMatrix>::getRealTargetCoordinates(OTT<ConnType,numPol>::indFC(targetCell),CoordsT); + int nbOfNodesT=CoordsT.size()/SPACEDIM; + const double *coordsS=Intersector3DP1P1<MyMeshType,MyMatrix>::_src_mesh.getCoordinatesPtr(); + for(typename std::vector<ConnType>::const_iterator iterCellS=srcCells.begin();iterCellS!=srcCells.end();iterCellS++) + { + NormalizedCellType tS=Intersector3DP1P1<MyMeshType,MyMatrix>::_src_mesh.getTypeOfElement(OTT<ConnType,numPol>::indFC(*iterCellS)); + if(tS!=NORM_TETRA4) + throw INTERP_KERNEL::Exception("Invalid source cell detected for meshdim==3. Only TETRA4 supported !"); + const CellModel& cmTypeS=CellModel::GetCellModel(tS); + const ConnType *startOfCellNodeConnT=Intersector3DP1P1<MyMeshType,MyMatrix>::getStartConnOfTargetCell(targetCell); + for(int nodeIdT=0;nodeIdT<nbOfNodesT;nodeIdT++) + { + typename MyMatrix::value_type& resRow=res[OTT<ConnType,numPol>::ind2C(startOfCellNodeConnT[nodeIdT])]; + std::vector<ConnType> connOfCurCellS; + Intersector3DP1P1<MyMeshType,MyMatrix>::getConnOfSourceCell(OTT<ConnType,numPol>::indFC(*iterCellS),connOfCurCellS); + if( PointLocatorAlgos<MyMeshType>::isElementContainsPointAlg3D(&CoordsT[nodeIdT*SPACEDIM],&connOfCurCellS[0],connOfCurCellS.size(),coordsS,cmTypeS,_precision) ) + { + double resLoc[4]; + std::vector<double> localCoordsS; + Intersector3DP1P1<MyMeshType,MyMatrix>::getRealSourceCoordinates(OTT<ConnType,numPol>::indFC(*iterCellS),localCoordsS); + std::vector<const double*> eap(4); + eap[0]=&localCoordsS[0]; eap[1]=&localCoordsS[3]; eap[2]=&localCoordsS[6]; eap[3]=&localCoordsS[9]; + barycentric_coords(eap,&CoordsT[nodeIdT*SPACEDIM],resLoc); + const ConnType *startOfCellNodeConnS=Intersector3DP1P1<MyMeshType,MyMatrix>::getStartConnOfSourceCell(*iterCellS); + for(int nodeIdS=0;nodeIdS<4;nodeIdS++) + { + if(fabs(resLoc[nodeIdS])>_precision) + { + ConnType curNodeSInCmode=OTT<ConnType,numPol>::coo2C(startOfCellNodeConnS[nodeIdS]); + typename MyMatrix::value_type::const_iterator iterRes=resRow.find(OTT<ConnType,numPol>::indFC(curNodeSInCmode)); + if(iterRes==resRow.end()) + resRow.insert(std::make_pair(OTT<ConnType,numPol>::indFC(curNodeSInCmode),resLoc[nodeIdS])); + else + { + double val=(*iterRes).second+resLoc[nodeIdS]; + resRow.erase(OTT<ConnType,numPol>::indFC(curNodeSInCmode)); + resRow.insert(std::make_pair(OTT<ConnType,numPol>::indFC(curNodeSInCmode),val)); + } + } + } + } + } + } + } +} + +#endif diff --git a/src/medtool/src/INTERP_KERNEL/PointLocatorAlgos.txx b/src/medtool/src/INTERP_KERNEL/PointLocatorAlgos.txx new file mode 100644 index 000000000..8a59aed65 --- /dev/null +++ b/src/medtool/src/INTERP_KERNEL/PointLocatorAlgos.txx @@ -0,0 +1,326 @@ +// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 +// 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 __POINTLOCATORALGOS_TXX__ +#define __POINTLOCATORALGOS_TXX__ + +#include "InterpolationUtils.hxx" +#include "CellModel.hxx" +#include "BBTree.txx" + +#include <list> +#include <set> +#include <limits> + +namespace INTERP_KERNEL +{ + class GenericPointLocatorAlgos + { + public: + virtual ~GenericPointLocatorAlgos() { } + virtual std::list<int> locates(const double* x, double eps) = 0; + }; + + template<class MyMeshType> + class PointLocatorAlgos: public GenericPointLocatorAlgos + { + private : + double* _bb; + BBTree<MyMeshType::MY_SPACEDIM,typename MyMeshType::MyConnType>* _tree; + const MyMeshType& _mesh; + public: + PointLocatorAlgos(const MyMeshType& mesh):_mesh(mesh) + { + typedef typename MyMeshType::MyConnType ConnType; + const int SPACEDIM=MyMeshType::MY_SPACEDIM; + const NumberingPolicy numPol=MyMeshType::My_numPol; + int nelem = _mesh.getNumberOfElements(); + _bb = new double[SPACEDIM*2*nelem]; + const ConnType* conn = _mesh.getConnectivityPtr(); + const ConnType* conn_index = _mesh.getConnectivityIndexPtr(); + const double* coords=_mesh.getCoordinatesPtr(); + for (int i=0; i<nelem; i++) + { + for (int idim=0; idim<SPACEDIM; idim++) + { + _bb[2*(i*SPACEDIM+idim)]=std::numeric_limits<double>::max(); + _bb[2*(i*SPACEDIM+idim)+1]=-std::numeric_limits<double>::max(); + } + for (int index= conn_index[i]; index < conn_index[i+1];index++) + { + //coordelem points to the coordinates of the current node of the i-th element + const double* coordelem = coords+OTT<ConnType,numPol>::ind2C(conn[OTT<ConnType,numPol>::ind2C(index)])*SPACEDIM; + + //the bounding box is updated by checking wheher the node is at the min/max in exach dimension + for (int idim=0; idim<SPACEDIM;idim++) + { + _bb[2*(i*SPACEDIM+idim)]=(coordelem[idim]<_bb[2*(i*SPACEDIM+idim)])?coordelem[idim]:_bb[2*(i*SPACEDIM+idim)]; + _bb[2*(i*SPACEDIM+idim)+1]=(coordelem[idim]>_bb[2*(i*SPACEDIM+idim)+1])?coordelem[idim]:_bb[2*(i*SPACEDIM+idim)+1]; + } + } + } + _tree=new BBTree<SPACEDIM,typename MyMeshType::MyConnType>(_bb,0,0,nelem); + } + + ~PointLocatorAlgos() + { + delete[] _bb; + delete _tree; + } + + //returns the list of elements that contains + //the point pointed to by x + std::list<typename MyMeshType::MyConnType> locates(const double* x, double eps) + { + typedef typename MyMeshType::MyConnType ConnType; + const NumberingPolicy numPol=MyMeshType::My_numPol; + std::vector<ConnType> candidates; + _tree->getElementsAroundPoint(x,candidates); + std::list<ConnType> retlist; + for(unsigned int i=0; i< candidates.size(); i++) + { + int ielem=candidates[i]; + if (elementContainsPoint(ielem,x,eps)) + retlist.push_back(OTT<ConnType,numPol>::indFC(ielem)); + } + return retlist; + } + + static bool isElementContainsPointAlg2D(const double *ptToTest, const double *cellPts, int nbEdges, double eps) + { + /* with dimension 2, it suffices to check all the edges + and see if the sign of double products from the point + is always the same. + C + / \ + / \ + Xo / \ + A-------B + + here XA^XC and XC^XB have different signs*/ + const int SPACEDIM=MyMeshType::MY_SPACEDIM; + int* sign = new int[nbEdges]; + for (int iedge=0; iedge<nbEdges; iedge++) + { + const double* A=cellPts+SPACEDIM*iedge; + const double* B=cellPts+SPACEDIM*((iedge+1)%nbEdges); + double a=mon_determinant(ptToTest, A, B); + if(a<-eps) + sign[iedge]=-1; + else if(a>eps) + sign[iedge]=1; + else + sign[iedge]=0; + } + bool ret=decideFromSign(sign, nbEdges); + delete [] sign; + return ret; + } + + static bool isElementContainsPointAlg3D(const double *ptToTest, const typename MyMeshType::MyConnType *conn_elem, int conn_elem_sz, const double *coords, const CellModel& cmType, double eps) + { + const int SPACEDIM=MyMeshType::MY_SPACEDIM; + typedef typename MyMeshType::MyConnType ConnType; + const NumberingPolicy numPol=MyMeshType::My_numPol; + + int nbfaces = cmType.getNumberOfSons2(conn_elem,conn_elem_sz); + int *sign = new int[nbfaces]; + int *connOfSon = new int[conn_elem_sz]; + for (int iface=0; iface<nbfaces; iface++) + { + NormalizedCellType typeOfSon; + cmType.fillSonCellNodalConnectivity2(iface,conn_elem,conn_elem_sz,connOfSon,typeOfSon); + const double* AA=coords+SPACEDIM*(OTT<ConnType,numPol>::coo2C(connOfSon[0])); + const double* BB=coords+SPACEDIM*(OTT<ConnType,numPol>::coo2C(connOfSon[1])); + const double* CC=coords+SPACEDIM*(OTT<ConnType,numPol>::coo2C(connOfSon[2])); + double Vol=triple_product(AA,BB,CC,ptToTest); + if (Vol<-eps) + sign[iface]=-1; + else if (Vol>eps) + sign[iface]=1; + else + sign[iface]=0; + } + bool ret=decideFromSign(sign, nbfaces); + delete [] sign; + delete [] connOfSon; + return ret; + } + + static bool isElementContainsPoint(const double *ptToTest, NormalizedCellType type, const double *coords, const typename MyMeshType::MyConnType *conn_elem, int conn_elem_sz, double eps) + { + const int SPACEDIM=MyMeshType::MY_SPACEDIM; + typedef typename MyMeshType::MyConnType ConnType; + const NumberingPolicy numPol=MyMeshType::My_numPol; + + const CellModel& cmType=CellModel::GetCellModel(type); + // + if (SPACEDIM==2) + { + int nbEdges=cmType.getNumberOfSons(); + double *pts = new double[nbEdges*SPACEDIM]; + for (int iedge=0; iedge<nbEdges; iedge++) + { + const double* a=coords+SPACEDIM*(OTT<ConnType,numPol>::ind2C(conn_elem[iedge])); + std::copy(a,a+SPACEDIM,pts+iedge*SPACEDIM); + } + bool ret=isElementContainsPointAlg2D(ptToTest,pts,nbEdges,eps); + delete [] pts; + return ret; + } + + if (SPACEDIM==3) + { + return isElementContainsPointAlg3D(ptToTest,conn_elem,conn_elem_sz,coords,cmType,eps); + } + + if(SPACEDIM==1) + { + double p1=coords[(OTT<ConnType,numPol>::ind2C(conn_elem[0]))]; + double p2=coords[(OTT<ConnType,numPol>::ind2C(conn_elem[1]))]; + double delta=fabs(p1-p2)+eps; + double val=*ptToTest-std::min(p1,p2); + return val>-eps && val<delta; + } + throw INTERP_KERNEL::Exception("Invalid spacedim detected ! Managed spaceDim are 2 and 3 !"); + } + + bool elementContainsPoint(typename MyMeshType::MyConnType i, const double* x, double eps) + { + //as i is extracted from the BBTRee, it is already in C numbering + //it is not necessary to convert it from F to C + typedef typename MyMeshType::MyConnType ConnType; + const NumberingPolicy numPol=MyMeshType::My_numPol; + + const double* coords= _mesh.getCoordinatesPtr(); + const ConnType* conn=_mesh.getConnectivityPtr(); + const ConnType* conn_index= _mesh.getConnectivityIndexPtr(); + const ConnType* conn_elem=conn+OTT<ConnType,numPol>::ind2C(conn_index[i]); + int conn_elem_sz=conn_index[i+1]-conn_index[i]; + NormalizedCellType type=_mesh.getTypeOfElement(OTT<ConnType,numPol>::indFC(i)); + return isElementContainsPoint(x,type,coords,conn_elem,conn_elem_sz,eps); + } + + static bool decideFromSign(const int* sign, int nbelem) + { + int min_sign = 1; + int max_sign = -1; + for (int i=0; i<nbelem;i++) + { + min_sign=(sign[i]<min_sign)?sign[i]:min_sign; + max_sign=(sign[i]>max_sign)?sign[i]:max_sign; + } + return (min_sign!=-1 || max_sign!=1); + } + }; + + template<class MyMeshType> + class PointLocatorInSimplex : public PointLocatorAlgos<MyMeshType> + { + const MyMeshType& _mesh; + public: + PointLocatorInSimplex(const MyMeshType& mesh) + :PointLocatorAlgos<MyMeshType>(mesh),_mesh(mesh) + { + } + + //================================================================================ + /*! + * \brief Returns nodes composing the simplex the point x is in + */ + //================================================================================ + + virtual std::list<int> locates(const double* x, double eps) + { + typedef typename MyMeshType::MyConnType ConnType; + const NumberingPolicy numPol=MyMeshType::My_numPol; + + std::list<int> simplexNodes; + std::list<int> candidates = PointLocatorAlgos<MyMeshType>::locates(x,eps); + std::list<int>::iterator eIt = candidates.begin(); + for ( ; eIt != candidates.end(); ++eIt ) + { + const int i = OTT<ConnType,numPol>::ind2C( *eIt ); + const double* coords= _mesh.getCoordinatesPtr(); + const ConnType* conn=_mesh.getConnectivityPtr(); + const ConnType* conn_index= _mesh.getConnectivityIndexPtr(); + const ConnType* conn_elem=conn+OTT<ConnType,numPol>::ind2C(conn_index[i]); + int conn_elem_sz=conn_index[i+1]-conn_index[i]; + NormalizedCellType type=_mesh.getTypeOfElement(OTT<ConnType,numPol>::indFC(i)); + CellModel cell = CellModel::GetCellModel(type); + + if ( cell.isQuadratic() ) + throw Exception("P2 not implemented yet"); + + if ( cell.isSimplex()) + { + for ( int n = 0; n < conn_elem_sz; ++n ) + simplexNodes.push_back( conn_elem[ n ]); + } + else + { + NormalizedCellType simlexType = cell.getDimension()==3 ? NORM_TETRA4 : NORM_TRI3; + std::vector<int> sonNodes; + NormalizedCellType sonType; + const unsigned nbSons = cell.getNumberOfSons2( conn_elem, conn_elem_sz ); + for ( unsigned s = 0; s < nbSons; ++s ) + { + sonNodes.resize( cell.getNumberOfNodesConstituentTheSon2( s, conn_elem, conn_elem_sz )); + cell.fillSonCellNodalConnectivity2( s, conn_elem, conn_elem_sz, &sonNodes[0], sonType ); + std::set<int> sonNodesSet( sonNodes.begin(), sonNodes.end() ); + + std::set< std::set< ConnType > > checkedSonSimplex; + for ( unsigned sn = 0; sn < sonNodes.size(); ++sn ) + { + std::vector< ConnType > simplexConn( cell.getDimension() + 1 ); + unsigned n; + for ( n = 0; n < cell.getDimension()-1; ++n ) + simplexConn[n] = sonNodes[ (sn+n) % sonNodes.size() ]; + + for ( unsigned n2 = 0; n2 < sonNodes.size()-cell.getDimension()+1; ++n2 ) + { + simplexConn[n] = sonNodes[ (sn+n+n2) % sonNodes.size() ]; + std::set< ConnType > sonSimplex( simplexConn.begin(), --simplexConn.end()); + if ( checkedSonSimplex.insert( sonSimplex ).second ) + { + for ( unsigned cn = 0; cn < conn_elem_sz; ++cn ) + if ( !sonNodesSet.count( conn_elem[cn] )) + { + simplexConn.back() = conn_elem[cn]; + if ( this->isElementContainsPoint( x, simlexType, coords, + &simplexConn[0], simplexConn.size(), eps )) + { + simplexNodes.insert( simplexNodes.end(), + simplexConn.begin(), simplexConn.end()); + return simplexNodes; + } + } + } + } + } + } + } + } + return simplexNodes; + } + + }; +} + +#endif diff --git a/src/medtool/src/INTERP_KERNEL/PolygonAlgorithms.hxx b/src/medtool/src/INTERP_KERNEL/PolygonAlgorithms.hxx new file mode 100644 index 000000000..bbb49362a --- /dev/null +++ b/src/medtool/src/INTERP_KERNEL/PolygonAlgorithms.hxx @@ -0,0 +1,94 @@ +// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 +// 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 __POLYGONALGORITHMS_HXX__ +#define __POLYGONALGORITHMS_HXX__ + +#include <vector> +#include <deque> +#include <map> + +namespace INTERP_KERNEL +{ + template<int DIM> + class VertexLess + { + public: + bool operator()(const double * P_1, const double * P_2) + { + for(int idim=0; idim<DIM; idim++) + { + if(P_1[idim] < P_2[idim] ) return true; + else if( P_1[idim] > P_2[idim]) return false; + } + return false; + } + }; + + template<int DIM> + class PolygonAlgorithms + { + public: + PolygonAlgorithms(double epsilon, double precision); + std::deque<double> intersectConvexPolygons(const double* P_1,const double* P_2, int N1, int N2); + + //Not yet tested + int convexDecomposition(const double * P, int N, std::vector< std::map< int,int > >& components, + std::vector< int >& components_index, const double epsilon); + private: + void defineIndices(int& i_loc, int& i_next, int& i_prev, + const double *& Poly1, const double *& Poly2, + int& j1, int& j1_glob, int& j2, int& j2_glob, + int& j3, int& j3_glob, int& j4, int& j4_glob, + int& i_glob, int& i_next_glob, int& i_prev_glob, + const double * P_1, const double * P_2, + int N1, int N2, int sign); + void addCrossings( const double * A, const double * B, int i , int i_next, + const double * C, const double * D, int j1, int j2, + const double * E, const double * F, int j3, int j4, + const double * G); + void addCrossing0(const double * A, const double * B, int i, int i_next, + const double * C, const double * D, int j, int j_next); + void addCrossing( double * ABCD, std::pair< int,int > i_i_next, std::pair< int,int > j_j_next); + void addNewVertex( int i, int i_glob, int i_next_glob, int i_prev_glob, const double * P); + bool intersectSegmentSegment(const double * A, const double * B, const double * C, + const double * D, const double * E, double * V); + + + //Not yet tested + void convexDecomposition(const double* P, int N, double* n, std::vector< int > subP, int NsubP, + std::vector< std::map< int,int > >& components, std::vector< int >& components_index, + int& Ncomp, int sign, const double epsilon); + void convHull(const double *P, int N, double * n, std::map< int,int >& subP, + std::map< int,int >& not_in_hull, int& NsubP, const double epsilon); + private: + std::deque< double > _Inter;/* vertices of the intersection P1^P2 */ + std::vector< std::pair< int,int > > _End_segments; /* segments containing inter final edges */ + /* status list of segments (ending point, starting point) intersected by the sweeping line */ + /* and a boolean true if the ending point is in the intersection */ + std::multimap< int, std::pair< int,bool> > _Status; + bool _is_in_intersection; + bool _terminus; + double _vdouble[DIM]; + double _epsilon; + double _precision; + }; +} + +#endif diff --git a/src/medtool/src/INTERP_KERNEL/PolygonAlgorithms.txx b/src/medtool/src/INTERP_KERNEL/PolygonAlgorithms.txx new file mode 100644 index 000000000..cda3f5b1f --- /dev/null +++ b/src/medtool/src/INTERP_KERNEL/PolygonAlgorithms.txx @@ -0,0 +1,824 @@ +// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 +// 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 __POLYGONALGORITHMS_TXX__ +#define __POLYGONALGORITHMS_TXX__ + +#include "PolygonAlgorithms.hxx" +#include "InterpolationUtils.hxx" +#include <list> +#include <map> +#include <iostream> + +namespace INTERP_KERNEL +{ + template<int DIM> + PolygonAlgorithms<DIM>::PolygonAlgorithms(double epsilon, double precision)//: (0) + { + _is_in_intersection = false; + _epsilon = epsilon; + _precision = precision; + } + /*************************************************************/ + /* Computes the 3D intersection between two COPLANAR */ + /* Segments [A,B] and [C,D], stores the result in V. */ + /* If A belongs to [CD] then the vertex E (preceeding A) */ + /* is used to decide if the crossing is real. If A coincides */ + /* with C or D, a special treatment is performed */ + /*************************************************************/ + template<int DIM> + bool PolygonAlgorithms<DIM>::intersectSegmentSegment(const double * A, const double * B, const double * C, + const double * D, const double * E, double * V) + { + double AB[DIM], DC[DIM], AC[DIM], det, t1, t2, inv_det; + + /******* Initialisation of the linear system t1*AB+t2*DC=AC ***********/ + for(int idim=0;idim<DIM;idim++) + { + AB[idim] = B[idim]-A[idim];//B-A + DC[idim] = C[idim]-D[idim];//C-D + AC[idim] = C[idim]-A[idim];//C-A + } + + /******* Resolution of the linear system t1*AB+t2*DC=AC ***********/ + det = determinant(AB,DC);//determinant of the first two coordinates + if(fabs(det) >_epsilon) + { + inv_det = 1/det; + t1 = determinant(AC,DC)*inv_det;//solves the linear system t1*AB+t2*DC=AC + t2 = determinant(AB,AC)*inv_det;//solves the linear system t1*AB+t2*DC=AC + } + else + { + switch(DIM) + { + case 2: + { + if(distance2<DIM>(A,D)<_epsilon) + crossprod<DIM>(A,C,E,_vdouble);//store the crossprod between vectors AC and AE (E=vertex preceding A) + return false;//case of paralell segments + } + case 3://beware AB and CD may belong to a vertical plane + det = determinant(&AB[1],&DC[1]);//determinant of the last two coefficients + if(fabs(det) > _epsilon) + { + inv_det = 1/det; + t1=(AC[1]*DC[DIM-1]-AC[DIM-1]*DC[1])*inv_det; + t2=(AB[1]*AC[DIM-1]-AB[DIM-1]*AC[1])*inv_det; + } + else //beware AB and CD may belong to a plane y = constant + { + det = AB[0]*DC[DIM-1]-AB[DIM-1]*DC[0]; + if(fabs(det) > _epsilon) + { + inv_det = 1/det; + t1=(AC[0]*DC[DIM-1]-AC[DIM-1]*DC[0])*inv_det; + t2=(AB[0]*AC[DIM-1]-AB[DIM-1]*AC[0])*inv_det; + } + else + { + if(distance2<DIM>(A,D)<_epsilon) + crossprod<DIM>(A,C,E,_vdouble);//store the crossprod between vectors AC and AE (E=vertex preceding A) + return false;//case of paralell segments + } + } + } + } + + if(t1>_precision && t1<1-_precision) + { + if( t2>_precision && t2<1-_precision) + { + for(int idim=0;idim<DIM;idim++) V[idim]=t1*AB[idim] + A[idim]; + return true; + } + } + else if(fabs(t1) <= _precision) + { + if( t2>_precision && t2<1-_precision)//vertex on an edge + { + double V12[DIM]; + double V34[DIM]; + crossprod<DIM>(A,D,B,V12); + crossprod<DIM>(A,D,E,V34); + double same_side =dotprod<DIM>(V12, V34); + if( same_side < -_epsilon ) // <= epsilon or 0 ?//crossing + { + for(int idim=0;idim<DIM;idim++) V[idim]=A[idim]; + return true; + } + else if( same_side > _epsilon ) _terminus= !_is_in_intersection;//reflexion + else //separation of overlaping edges + { + if(_Inter.empty() ) _terminus=true; + else if(!_is_in_intersection) + { + for(int idim=0;idim<DIM;idim++) V[idim]=A[idim]; + return true; + } + } + } + else if(fabs(t2-1) <= _precision)//vertex on a vertex (A=D), first run + crossprod<DIM>(A,C,E,_vdouble);//store the angle between vectors AC and AE (E=vertex preceding A) + else if(fabs(t2) <= _precision)//vertex on a vertex (A=C), second run + { + double Vdoublebis[DIM]; + //crossprod<DIM>(A,C,E,_vdouble); + crossprod<DIM>(A,B,D,Vdoublebis); + double in_between =dotprod<DIM>(Vdoublebis,_vdouble); + if(in_between>_epsilon)//crossing + { + for(int idim=0;idim<DIM;idim++) V[idim]=A[idim]; + return true; + } + else if(fabs(in_between)<=_epsilon && dotprod<DIM>(Vdoublebis,Vdoublebis) > _epsilon) + //ie _vdouble=0, separation of overlaping edges at a double point + { + //crossprod<DIM>(A,E,B,_vdouble); + if(dotprod<DIM>(_vdouble,Vdoublebis) >=_epsilon )//crossing + { + if(_Inter.empty()) _terminus=true; + else if(!_is_in_intersection) + { + for(int idim=0;idim<DIM;idim++) V[idim]=A[idim]; + return true; + } + } + } + } + } + return false; + } + + /*************************************************************/ + /* adds vertex i to the list inter and updates _End_segments */ + /* i is the local index of the current vertex */ + /*************************************************************/ + template<int DIM> + inline void PolygonAlgorithms<DIM>::addNewVertex( int i, int i_glob, int i_next_glob, int i_prev_glob, + const double * P) + { + /* Question:Should we add vertex i to the front or back ? */ + if( _End_segments[1].second == i_glob) + { + for(int idim=0;idim<DIM;idim++) _Inter.push_back(P[DIM*i+idim]); + _End_segments[1] = std::make_pair(i_glob, i_next_glob); + } + else + { + for(int idim=DIM-1;idim>-1;idim--) _Inter.push_front(P[DIM*i+idim]); + _End_segments[0] = std::make_pair(i_glob, i_next_glob); + } + } + + /************************************************************/ + /* adds a crossing between two segments starting at i and j */ + /* to the double ended list inter in the correct order */ + /* according to endsegments, updates _End_segments */ + /************************************************************/ + template<int DIM> + inline void PolygonAlgorithms<DIM>::addCrossing( double * ABCD, std::pair< int,int > i_i_next, + std::pair< int,int > j_j_next) + { + if(!_Inter.empty() ) + { + if(_End_segments[0] ==i_i_next) + { + for(int idim=DIM-1;idim>=0;idim--) _Inter.push_front(ABCD[idim]); + _terminus= (_End_segments[1]== j_j_next); + _End_segments[0] = j_j_next; + } + else + { + if( _End_segments[0]== j_j_next) + { + for(int idim=DIM-1;idim>=0;idim--) _Inter.push_front(ABCD[idim]); + _terminus= (_End_segments[1]== i_i_next); + _End_segments[0] = i_i_next; + } + else + { + for(int idim=0;idim<DIM;idim++) _Inter.push_back(ABCD[idim]); + _End_segments[1] = (_End_segments[1]== i_i_next) ? j_j_next : i_i_next; + } + } + } + else + { + for(int i=0;i<DIM;i++) _Inter.push_back(ABCD[i]); + _End_segments.push_back(i_i_next); + _End_segments.push_back(j_j_next); + } + } + + /*******************************************************/ + /* checks the possible crossing between segments [A,B] */ + /* (with end-point global indices i and i_next) */ + /* and [C,D] (end-point global indices j and j_next). */ + /* If no intersection is detected, checks whether B is */ + /* inside the quadrangle AEDC. */ + /* Updates the lists inter and _End_segments */ + /*******************************************************/ + + template<int DIM> + void PolygonAlgorithms<DIM>::addCrossing0(const double * A, const double * B, int i, int i_next, + const double * C, const double * D, int j, int j_next) + { + double ABCD[DIM]; + if(intersectSegmentSegment(A,B,C,D,ABCD, ABCD)) + //fifth and sixth arguments are useless here + { + /* Updating _End_segments */ + std::pair< int,int > i_i_next = std::make_pair(i, i_next); + std::pair< int,int > j_j_next = std::make_pair(j, j_next); + if( _End_segments[0] == i_i_next) + { + for(int idim=DIM-1;idim>-1;idim--) _Inter.push_front(ABCD[idim]); + _End_segments[0] = j_j_next; + } + else + { + for(int idim=0;idim<DIM;idim++) _Inter.push_back(ABCD[idim]); + _End_segments[1] = j_j_next; + _terminus = _End_segments[0]== j_j_next; + } + + /* Updating _Status */ + _Status.insert(make_pair(i_next,std::make_pair(i, false))); + std::multimap< int, std::pair< int,bool> >::iterator mi =_Status.find(j_next); + ((* mi).second).second= !((* mi).second).second; + } + else _Status.insert(std::make_pair(i_next,std::make_pair(i,true))); + } + + /*******************************************************/ + /* adds the possible crossings between segments [A,B] (with end-point global indices i and i_next) */ + /*and segments [C,D] and [E,F] to the list inter and updates _End_segments */ + /* In cases of ambiguity, the vertex G is used to decide wether the crossing should be accepted */ + /*******************************************************/ + template<int DIM> + inline void PolygonAlgorithms<DIM>::addCrossings( const double * A, const double * B, int i , int i_next, + const double * C, const double * D, int j1, int j2, + const double * E, const double * F, int j3, int j4, + const double * G) + { + double ABCD[DIM]; + double ABEF[DIM]; + std::multimap< int, std::pair< int,bool> >::iterator mi; + + if(intersectSegmentSegment(A,B,C,D,G,ABCD)) + { + if(intersectSegmentSegment(A,B,E,F,G,ABEF)) + { + VertexLess<DIM> vl; + if (vl(ABCD,ABEF)) + { + addCrossing(ABCD, std::make_pair(i, i_next), std::make_pair(j1, j2)); + addCrossing(ABEF, std::make_pair(i, i_next), std::make_pair(j3, j4)); + } + else + { + addCrossing(ABEF, std::make_pair(i, i_next), std::make_pair(j3, j4)); + addCrossing(ABCD, std::make_pair(i, i_next), std::make_pair(j1, j2)); + } + _Status.insert(std::make_pair(i_next,std::make_pair(i, _is_in_intersection))); + mi=_Status.find(j2); + ((* mi).second).second= !((* mi).second).second; + mi=_Status.find(j4); + ((* mi).second).second= !((* mi).second).second; + } + else + { + addCrossing(ABCD, std::make_pair( i, i_next), std::make_pair(j1,j2)); + _Status.insert(std::make_pair(i_next,std::make_pair(i, !_is_in_intersection))); + mi=_Status.find(j2); + ((* mi).second).second= !((* mi).second).second; + } + } + else + { + if(intersectSegmentSegment(A,B,E,F,G, ABEF)) + { + addCrossing(ABEF, std::make_pair( i, i_next), std::make_pair( j3, j4)); + _Status.insert(std::make_pair(i_next,std::make_pair(i, !_is_in_intersection))); + mi=_Status.find(j4); + ((* mi).second).second= !((* mi).second).second; + } + else _Status.insert(std::make_pair(i_next,std::make_pair(i, _is_in_intersection))); + } + } + + + /* define various indices required in the function intersect_conv_polygon */ + /* vertices from the both polygons are supposed to be present in the status */ + template<int DIM> + inline void PolygonAlgorithms<DIM>::defineIndices(int& i_loc, int& i_next, int& i_prev, + const double *& Poly1, const double *& Poly2, + int& j1, int& j1_glob, int& j2, int& j2_glob, + int& j3, int& j3_glob, int& j4, int& j4_glob, + int& i_glob, int& i_next_glob, int& i_prev_glob, + const double * P_1, const double * P_2, + int N1, int N2, int sign) + { + int N0, shift; + if(i_glob < N1) + { + N0 = N1; + shift = 0; + Poly1 = P_1; + Poly2 = P_2; + + std::multimap< int, std::pair< int,bool> >::reverse_iterator mi1=_Status.rbegin(); + j1_glob=((*mi1).second).first; + j1=j1_glob-N1; + j2_glob=(*mi1).first; + j2=j2_glob-N1; + mi1++; + j3_glob=((*mi1).second).first; + j3=j3_glob-N1; + j4_glob=(*mi1).first; + j4=j4_glob-N1; + } + else + { + N0 = N2; + shift = N1; + Poly1 = P_2; + Poly2 = P_1; + + std::multimap< int, std::pair< int,bool> >::iterator mi2= _Status.begin(); + j1_glob=((*mi2).second).first; + j1=j1_glob; + j2_glob=(*mi2).first; + j2=j2_glob; + mi2++; + j3_glob=((*mi2).second).first; + j3=j3_glob; + j4_glob=(*mi2).first; + j4=j4_glob; + } + i_loc = i_glob-shift; + i_next = (i_next_glob-shift+N0)%N0;//end-point of segment starting at i + i_prev = (i_prev_glob-shift+N0)%N0; + i_next_glob = i_next+shift; + i_prev_glob = i_prev+shift; + //warning: sign is either 1 or -1; + //To do: test and remove from Convex_intersecor.cxx + // while(distance2<DIM>(&Poly1[DIM*i_loc],&Poly1[DIM*i_next])< _epsilon && i_next != i_loc) + // i_next =(i_next+sign+N0)%N0; + // while(distance2<DIM>(&Poly1[DIM*i_loc],&Poly1[DIM*i_prev])< _epsilon && i_prev != i_loc) + // i_prev =(i_prev+sign+N0)%N0; + } + /*******************************************************/ + /* computes the vertices of the intersection of two COPLANAR */ + /* simple (no dble points)convex polygons using line sweep algorithm */ + /* P1 and P2 contain the 3D coordinates of the successive vertices */ + /*******************************************************/ + template<int DIM> + std::deque< double > PolygonAlgorithms<DIM>::intersectConvexPolygons(const double* P_1,const double* P_2, + int N1, int N2) + { + int i_loc, i_glob, j1, j1_glob, j2,j2_glob, j3, j3_glob, j4,j4_glob, + i_prev, i_prev_glob, i_next, i_next_glob, nb_prev, sign, idim; + const double * Poly1, * Poly2; + bool four_neighbours=false; + _terminus = N1 < 3 || N2<3; + + /* list of future events ordered according to their coordinates (x,y,z) (lexicographical order) */ + std::multimap< const double *, int, VertexLess<DIM> > mmap_events; + typename std::list< std::pair< const double *, int > >::iterator mi1,mi2; + + std::multimap< int, std::pair< int,bool> >::iterator mi; + + /********** Initalisation of events with P1 and P2 vertices ************/ + for(i_loc=0;i_loc<N1;i_loc++) + mmap_events.insert(std::make_pair(&P_1[DIM*i_loc],i_loc)); + for(i_loc=0;i_loc<N2;i_loc++) + mmap_events.insert(std::make_pair(&P_2[DIM*i_loc],i_loc+N1)); + + std::list< std::pair< const double *, int > > events(mmap_events.begin(),mmap_events.end()); + + if(!_terminus) + { + /******** Treatment of the first vertex ********/ + mi1=events.begin(); + i_glob = (* mi1).second; + bool which_start = i_glob < N1; + if(i_glob < N1){ i_next_glob = (i_glob +1)%N1; i_prev_glob = (i_glob -1+N1)%N1;} + else{ i_next_glob = (i_glob-N1+1)%N2 + N1;i_prev_glob = (i_glob-N1-1+N2)%N2 + N1;} + _Status.insert(std::make_pair(i_next_glob,std::make_pair(i_glob, false))); + _Status.insert(std::make_pair(i_prev_glob,std::make_pair(i_glob, false))); + mi1++; + //std::cout<< "nb_prev= "<< 0 << " i_glob= " << i_glob << std::endl; + + /******* Loop until the second polygon is reached *******/ + while( !four_neighbours) + { + i_glob=(* mi1).second;//global index of vertex i + nb_prev = _Status.count(i_glob);//counts the number of segments ending at i + + //std::cout<< "nb_prev= "<< nb_prev << " i_glob= " << i_glob << std::endl; + switch (nb_prev) + { + case 1 : + mi=_Status.find(i_glob);// pointer to the segment ending at i + i_prev_glob = ((*mi).second).first;//starting point of the segment ending at i + i_next= (i_prev_glob - i_glob > 0) == (abs(i_prev_glob - i_glob) == 1) ? i_glob - 1 : i_glob + 1; + if(i_glob < N1) i_next_glob = (i_next +N1)%N1; + else i_next_glob = (i_next-N1+N2)%N2 + N1; + _Status.erase(mi); + _Status.insert(std::make_pair(i_next_glob,std::make_pair(i_glob, false))); + mi1++; + break; + case 2 : + return _Inter; + case 0 : + if( (i_glob < N1) != which_start) + { + mi2=mi1; + mi2++; + /* detection of double points */ + if(distance2<DIM>((* mi1).first, (*mi2).first) > _epsilon) + four_neighbours = true; + else /* Rare pothological case: */ + { + const std::pair< const double *, int > next_pt= *mi2; + events.erase(mi2); + mi1=events.insert(mi1,next_pt); + } + } + break; + default: + throw Exception("intersectConvexPolygon: sequence of nodes does not describe a simple polygon (1)"); + } + } + /******** Loop until a terminal point or crossing is reached ************/ + while( !_terminus) + { + //std::cout<< "nb_prev= "<< nb_prev<< " nb_inter= " << _Inter.size()/DIM << std::endl; + switch (nb_prev) + { + case 1 : + mi=_Status.find(i_glob);// pointer to the segment ending at i + i_prev_glob = ((*mi).second).first;//starting point of the segment ending at i + sign = (i_prev_glob - i_glob > 0) == (abs(i_prev_glob - i_glob) == 1) ? - 1 : + 1; + i_next_glob = i_glob+sign; + _is_in_intersection = ((*mi).second).second;//boolean that tells if i is in the intersection + _Status.erase(mi); + defineIndices(i_loc,i_next,i_prev, Poly1,Poly2, + j1,j1_glob,j2,j2_glob,j3,j3_glob,j4,j4_glob, + i_glob,i_next_glob,i_prev_glob, P_1,P_2, N1, N2, sign); + if( _is_in_intersection ) addNewVertex(i_loc, i_glob, i_next_glob, i_prev_glob, Poly1); + addCrossings(&Poly1[DIM*i_loc], &Poly1[DIM*i_next], i_glob, i_next_glob, + &Poly2[DIM*j1] , &Poly2[DIM*j2] , j1_glob,j2_glob, + &Poly2[DIM*j3] , &Poly2[DIM*j4] , j3_glob,j4_glob, &Poly1[DIM*i_prev]); + break; + case 2 : + if(!_Inter.empty()) + { + if(i_glob < N1) for(idim=0;idim<DIM;idim++) _Inter.push_back(P_1[DIM*i_glob+idim]); + else for(idim=0;idim<DIM;idim++) _Inter.push_back(P_2[DIM*(i_glob-N1)+idim]); + } + return _Inter; + case 0 ://To do if possible : remove this case from here + if(_Inter.empty() && (i_glob < N1) != which_start){ + i_next_glob = i_glob+1; + i_prev_glob = i_glob-1; + defineIndices(i_loc,i_next,i_prev, Poly1,Poly2, + j1,j1_glob,j2,j2_glob,j3,j3_glob,j4,j4_glob, + i_glob,i_next_glob,i_prev_glob, P_1,P_2, N1, N2, 1); + double V12[DIM], V34[DIM]; + double inside = check_inside<DIM>(&Poly1[DIM*i_loc],&Poly2[DIM*j1],&Poly2[DIM*j2], + &Poly2[DIM*j3], &Poly2[DIM*j4],V12, V34); + _is_in_intersection=( inside < _epsilon ); // <= epsilon or 0 ? + + if(fabs(inside) > _epsilon)//vertex clearly inside or outside + { + //std::cout<<"coucou1" << std::endl; + if( _is_in_intersection) + { + for(int iidim=0;iidim<DIM;iidim++) + _Inter.push_back(Poly1[DIM*i_loc+iidim]); + _End_segments.push_back(std::make_pair(i_glob,i_next_glob)); + _End_segments.push_back(std::make_pair(i_glob,i_prev_glob)); + } + addCrossings(&Poly1[DIM*i_loc], &Poly1[DIM*i_next], i_glob, i_next_glob, + &Poly2[DIM*j1] , &Poly2[DIM*j2] , j1_glob,j2_glob, + &Poly2[DIM*j3] , &Poly2[DIM*j4] , j3_glob,j4_glob, &Poly1[DIM*i_prev]); + addCrossings(&Poly1[DIM*i_loc], &Poly1[DIM*i_prev], i_glob, i_prev_glob, + &Poly2[DIM*j1] , &Poly2[DIM*j2] , j1_glob,j2_glob, + &Poly2[DIM*j3] , &Poly2[DIM*j4] , j3_glob,j4_glob, &Poly1[DIM*i_next]); + } + else //vertex on an edge + { + //std::cout<<"coucou2" << std::endl; + bool is_inside_next, is_inside_prev; + double Vnext[DIM], Vprev[DIM]; + for(idim=0;idim<DIM;idim++) _Inter.push_back(Poly1[DIM*i_loc+idim]); + + if(dotprod<DIM>(V34,V34) > _epsilon)//vertex i on edge (j1,j2), not on (j3,j4) + { + crossprod<DIM>(&Poly1[DIM*i_loc], &Poly2[DIM*j2], &Poly1[DIM*i_next],Vnext); + crossprod<DIM>(&Poly1[DIM*i_loc], &Poly2[DIM*j2], &Poly1[DIM*i_prev],Vprev); + is_inside_next= (dotprod<DIM>(Vnext,V34)<0); + is_inside_prev= (dotprod<DIM>(Vprev,V34)<0); + + if(!(is_inside_next || is_inside_prev)) return std::deque< double >(); + + if(is_inside_next) + { + _End_segments.push_back(std::make_pair(i_glob,i_next_glob)); + addCrossing0(&Poly1[DIM*i_loc], &Poly1[DIM*i_next], i_glob, i_next_glob, + &Poly2[DIM*j3] , &Poly2[DIM*j4] , j3_glob,j4_glob); + } + else + { + _End_segments.push_back(std::make_pair(j1_glob,j2_glob)); + _Status.insert(std::make_pair(i_next_glob,std::make_pair(i_glob, false))); + mi=_Status.find(j2_glob); + ((* mi).second).second= !((* mi).second).second; + } + if(is_inside_prev) + { + _End_segments.push_back(std::make_pair(i_glob,i_prev_glob)); + addCrossing0(&Poly1[DIM*i_loc], &Poly1[DIM*i_prev], i_glob, i_prev_glob, + &Poly2[DIM*j3] , &Poly2[DIM*j4] , j3_glob,j4_glob); + } + else + { + _End_segments.push_back(std::make_pair(j1_glob,j2_glob)); + _Status.insert(std::make_pair(i_prev_glob,std::make_pair(i_glob, false))); + mi=_Status.find(j2_glob); + ((* mi).second).second= !((* mi).second).second; + } + } + else if(dotprod<DIM>(V12,V12) > _epsilon)//vertex i on a edge (j3,j4), not on (j1,j2) + { + crossprod<DIM>(&Poly1[DIM*i_loc], &Poly2[DIM*j4], &Poly1[DIM*i_next],Vnext); + crossprod<DIM>(&Poly1[DIM*i_loc], &Poly2[DIM*j4], &Poly1[DIM*i_prev],Vprev); + is_inside_next= dotprod<DIM>(Vnext,V12)<0; + is_inside_prev= dotprod<DIM>(Vprev,V12)<0; + + if(!(is_inside_next || is_inside_prev)) return std::deque< double >(); + + if(is_inside_next) + { + _End_segments.push_back(std::make_pair(i_glob,i_next_glob)); + addCrossing0(&Poly1[DIM*i_loc], &Poly1[DIM*i_next], i_glob, i_next_glob, + &Poly2[DIM*j1] , &Poly2[DIM*j2] , j1_glob,j2_glob); + } + else + { + _End_segments.push_back(std::make_pair(j3_glob,j4_glob)); + _Status.insert(std::make_pair(i_next_glob,std::make_pair(i_glob, false))); + mi=_Status.find(j4_glob); + ((* mi).second).second= ! ((* mi).second).second; + } + if(is_inside_prev) + { + _End_segments.push_back(std::make_pair(i_glob,i_prev_glob)); + addCrossing0(&Poly1[DIM*i_loc], &Poly1[DIM*i_prev], i_glob, i_prev_glob, + &Poly2[DIM*j1] , &Poly2[DIM*j2] , j1_glob,j2_glob); + } + else + { + _End_segments.push_back(std::make_pair(j3_glob,j4_glob)); + _Status.insert(std::make_pair(i_prev_glob,std::make_pair(i_glob, false))); + mi=_Status.find(j4_glob); + ((* mi).second).second= !((* mi).second).second; + } + } + else //vertices i, j1 and j3 share the same coordinates + { + crossprod<DIM>(&Poly1[DIM*i_loc], &Poly2[DIM*j2], &Poly1[DIM*i_next],Vnext); + crossprod<DIM>(&Poly1[DIM*i_loc], &Poly2[DIM*j2], &Poly1[DIM*i_prev],Vprev); + crossprod<DIM>(&Poly1[DIM*i_loc], &Poly2[DIM*j4], &Poly1[DIM*i_next],V12); + crossprod<DIM>(&Poly1[DIM*i_loc], &Poly2[DIM*j4], &Poly1[DIM*i_prev],V34); + + double inside_next= dotprod<DIM>(Vnext,V12); + double inside_prev= dotprod<DIM>(Vprev,V34); + double inside_j2 = dotprod<DIM>(Vnext,Vprev); + double inside_j4 = dotprod<DIM>(V12,V34); + + std::map<double, std::pair<int,int> > which_is_inside; + which_is_inside[inside_next] = std::make_pair(i_glob,i_next_glob); + which_is_inside[inside_prev] = std::make_pair(i_glob,i_prev_glob); + which_is_inside[inside_j2] = std::make_pair(j1_glob,j2_glob); + which_is_inside[inside_j4] = std::make_pair(j3_glob,j4_glob); + + std::map<double, std::pair<int,int> >::iterator min = which_is_inside.begin(); + std::map<double, std::pair<int,int> >::iterator minext = min; + minext++; + std::map<double, std::pair<int,int> >::reverse_iterator max = which_is_inside.rbegin(); + std::multimap< int, std::pair< int,bool> >::iterator j2_in_status = _Status.find(((*min).second).second); + std::multimap< int, std::pair< int,bool> >::iterator j4_in_status = _Status.find(((*minext).second).second); + + if((*min).first < -_epsilon) //there is someone clearly inside + { + _End_segments.push_back( (*min).second ); + _End_segments.push_back((* minext).second); + if(j2_in_status != _Status.end()) + ((*j2_in_status).second).second = ! ((*j2_in_status).second).second; + if(j4_in_status != _Status.end()) + ((*j4_in_status).second).second = ! ((*j4_in_status).second).second; + is_inside_next = ((*min).second).second == i_next_glob || ((*minext).second).second == i_next_glob; + is_inside_prev = ((*min).second).second == i_prev_glob || ((*minext).second).second == i_prev_glob; + } + else + if(fabs((*min).first) <= _epsilon) //nobody is clearly inside but two segments are superposed + { + if(fabs((*max).first) > _epsilon) + return std::deque< double >(); + else //all four segments are superposed + { + _End_segments.push_back(std::make_pair(i_glob,i_next_glob)); + _End_segments.push_back(std::make_pair(i_glob,i_prev_glob)); + is_inside_next= true; + is_inside_prev= true; + } + } + else //there is nobody inside + return std::deque< double >(); + + _Status.insert(std::make_pair(i_prev_glob,std::make_pair(i_glob,is_inside_prev))); + _Status.insert(std::make_pair(i_next_glob,std::make_pair(i_glob,is_inside_next))); + } + } + } + break; + default: + std::cout << "Problem: nbprev= " << nb_prev << " ; i_glob = " << i_glob << std::endl; + throw Exception("intersectConvexPolygon: sequence of nodes does not describe a simple polygon (2)"); + } + mi1++; + i_glob=(* mi1).second;//global index of vertex i + nb_prev = _Status.count(i_glob); + } + } + return _Inter; + } + + /**************************************************************************/ + /* computes the convex hull of a polygon subP which is a sub polygon of P */ + /* P is the array of coordinates, subP is a map containing initially the indices of a subpolygon of P */ + /* in the end, subP contains only the elements belonging to the convex hull, and not_in_hull the others */ + /**************************************************************************/ + template<int DIM> + inline void PolygonAlgorithms<DIM>::convHull(const double *P, int N, double * normal, + std::map< int,int >& subP, std::map< int,int >& not_in_hull, + int& NsubP, const double epsilon) + { + if(NsubP>3) + { + std::map< int,int >::iterator mi_prev = subP.begin(); + std::map< int,int >::iterator mi = mi_prev; + mi++; + std::map< int,int >::iterator mi_next = mi; + mi_next++; + double directframe=0.; + + /* Check if the polygon subP is positively oriented */ + std::map< int,int >::iterator mi1=mi; + while(mi1 != subP.end() && distance2<DIM>(&P[DIM*(*subP.begin()).second],&P[DIM*(*mi1).second])< epsilon) + mi1++; + std::map< int,int >::iterator mi2=mi1; + while(mi2 != subP.end() && fabs(directframe)<epsilon) + { + directframe =direct_frame<DIM>(&P[DIM* (*mi1).second], + &P[DIM* (*subP.begin()).second], + &P[DIM* (*mi2).second], normal); + mi2++; + } + if(directframe < 0) for(int idim=0; idim< DIM; idim++) normal[idim] *= -1; + + /* Core of the algorithm */ + while(mi_next != subP.end()) + { + directframe = direct_frame<DIM>(&P[DIM* (*mi).second], + &P[DIM* (*mi_prev).second], + &P[DIM* (*mi_next).second], normal); + if(directframe > -epsilon){ + mi ++; + mi_prev++; + mi_next++; + } + else + { + not_in_hull.insert(*mi); + subP.erase(mi); + NsubP--; + mi--; + } + } + directframe = direct_frame<DIM>(&P[DIM*(*mi).second], + &P[DIM*(*mi_prev).second], + &P[DIM*(*subP.begin()).second], normal); + if(directframe < -epsilon) + { + not_in_hull.insert(*mi); + subP.erase(mi); + NsubP--; + } + } + } + + template<int DIM> + void PolygonAlgorithms<DIM>::convexDecomposition(const double * P, int N, double *normal, std::vector< int > subP, int NsubP, + std::vector< std::map< int,int > >& components, std::vector< int >& components_index, + int& Ncomp, int sign, const double epsilon) + { + int i; + std::map< int, int > hull; + std::map< int, int > not_in_hull; + std::map< int, int >::iterator mi, mj; + std::vector< int > reflex_region; + int Nreflex; + int i_xmax=0; + const double * xmax=&P[DIM*subP[0]]; + /* checking an extremal point of subP */ + for(i=0; i<NsubP; i++) + { + if(&P[DIM*subP[i]]> xmax) + { + i_xmax=i; + xmax=&P[DIM*subP[i]]; + } + } + /* renumbering of SubP elements for the convex hull*/ + for(i=0; i<NsubP; i++) hull.insert(hull.end(),std::make_pair(i,subP[(i+i_xmax)%NsubP])); + /* compute the convex hull */ + convHull(P, N, normal, hull, not_in_hull, NsubP,epsilon); + /* convex hull is the next component */ + components.push_back(hull); + components_index.push_back(sign*NsubP); + Ncomp++; + /* searching for reflex regions */ + for(mi=not_in_hull.begin(); mi!=not_in_hull.end(); mi++) + { + reflex_region.clear(); + reflex_region.push_back(hull[(*mi).first-1]); + reflex_region.push_back( (*mi).second ); + Nreflex=2; + mj=mi; + mj++; + while((mj != not_in_hull.end()) && ((*mj).first == (*mi).first+1)) + { + reflex_region.push_back((*mj).second); + Nreflex++; + mi++; + mj++; + } + reflex_region.push_back(hull[(*mi).first+1]); + Nreflex++; + convexDecomposition( P, N,normal, reflex_region, Nreflex, components, components_index, Ncomp, -sign, epsilon); + } + } + + /**************************************************************************/ + /* decomposes a non convex polygon P with N vertices contained in a plane */ + /* into a sequence of convex polygons */ + /* the input vectors 'components' and 'components_index' should be empty */ + /* returns the number of convex components */ + /* if P is composed of a single point, then an empty polygon is returned */ + /**************************************************************************/ + template<int DIM> + int PolygonAlgorithms<DIM>::convexDecomposition(const double * P, int N, std::vector< std::map< int,int > >& components, + std::vector< int >& components_index, const double epsilon) + { + int Ncomp=0; + std::vector< int > subP(N); + double normal[3]={0,0,0}; + + for(int i = 0; i<N; i++) subP[i]=i; + + //Build the normal of polygon P + int i1=1; + while(i1<N && distance2<DIM>(&P[0],&P[i1])< epsilon) i1++; + int i2=i1+1; + while(i2<N && fabs(dotprod<DIM>(normal,normal))<epsilon) + { + crossprod<DIM>(&P[i1], &P[0], &P[i2],normal); + i2++; + } + + convexDecomposition(P, N, normal, subP, N, components, components_index, Ncomp, 1, epsilon); + return Ncomp; + } +} + +#endif diff --git a/src/medtool/src/INTERP_KERNEL/Polyhedron3D2DIntersectorP0P0.hxx b/src/medtool/src/INTERP_KERNEL/Polyhedron3D2DIntersectorP0P0.hxx new file mode 100644 index 000000000..6c5a2d1f9 --- /dev/null +++ b/src/medtool/src/INTERP_KERNEL/Polyhedron3D2DIntersectorP0P0.hxx @@ -0,0 +1,79 @@ +// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 +// 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 __POLYHEDRON3D2DINTERSECTORP0P0_HXX__ +#define __POLYHEDRON3D2DINTERSECTORP0P0_HXX__ + +#include "Intersector3DP0P0.hxx" +#include "SplitterTetra.hxx" +#include "NormalizedUnstructuredMesh.hxx" + +namespace INTERP_KERNEL +{ + + + /** + * \brief Class responsible for calculating intersection between a hexahedron target element and + * the source elements. + * + */ + template<class MyMeshType, class MyMatrixType> + class Polyhedron3D2DIntersectorP0P0 : public Intersector3DP0P0<MyMeshType,MyMatrixType> + { + typedef typename std::map<int,std::set<int> > DuplicateFacesType; + + public: + static const int SPACEDIM=MyMeshType::MY_SPACEDIM; + static const int MESHDIM=MyMeshType::MY_MESHDIM; + typedef typename MyMeshType::MyConnType ConnType; + static const NumberingPolicy numPol=MyMeshType::My_numPol; + + public: + + Polyhedron3D2DIntersectorP0P0(const MyMeshType& targetMesh, + const MyMeshType& srcMesh, + const double dimCaracteristic, + const double precision, + DuplicateFacesType& intersectFaces, + SplittingPolicy policy = PLANAR_FACE_5); + + ~Polyhedron3D2DIntersectorP0P0(); + + void intersectCells(ConnType targetCell, + const std::vector<ConnType>& srcCells, + MyMatrixType& matrix); + + private: + void releaseArrays(); + private: + /// pointers to the SplitterTetra objects representing the tetrahedra + /// that result from the splitting of the hexahedron target cell + std::vector< SplitterTetra<MyMeshType>* > _tetra; + + SplitterTetra2<MyMeshType> _split; + + double _dim_caracteristic; + double _precision; + + DuplicateFacesType& _intersect_faces; + + }; +} + +#endif diff --git a/src/medtool/src/INTERP_KERNEL/Polyhedron3D2DIntersectorP0P0.txx b/src/medtool/src/INTERP_KERNEL/Polyhedron3D2DIntersectorP0P0.txx new file mode 100644 index 000000000..85d58450b --- /dev/null +++ b/src/medtool/src/INTERP_KERNEL/Polyhedron3D2DIntersectorP0P0.txx @@ -0,0 +1,169 @@ +// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 +// 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 __POLYHEDRON3D2DINTERSECTORP0P0_TXX__ +#define __POLYHEDRON3D2DINTERSECTORP0P0_TXX__ + +#include "Polyhedron3D2DIntersectorP0P0.hxx" +#include "Intersector3DP0P0.txx" +#include "MeshUtils.hxx" + +#include "SplitterTetra.txx" + +namespace INTERP_KERNEL +{ + + /** + * Constructor creating object from target cell global number + * The constructor first calculates the necessary nodes, + * (depending on the splitting policy) and then splits the hexahedron into + * tetrahedra, placing these in the internal vector _tetra. + * + * @param targetMesh mesh containing the target elements + * @param srcMesh mesh containing the source elements + * @param policy splitting policy to be used + */ + template<class MyMeshType, class MyMatrixType> + Polyhedron3D2DIntersectorP0P0<MyMeshType,MyMatrixType>::Polyhedron3D2DIntersectorP0P0(const MyMeshType& targetMesh, + const MyMeshType& srcMesh, + const double dimCaracteristic, + const double precision, + DuplicateFacesType& intersectFaces, + SplittingPolicy policy) + : Intersector3DP0P0<MyMeshType,MyMatrixType>(targetMesh,srcMesh), + _split(targetMesh,srcMesh,policy), + _dim_caracteristic(dimCaracteristic), + _precision(precision), + _intersect_faces(intersectFaces) + { + } + + /** + * Destructor. + * Liberates the SplitterTetra objects and potential sub-node points that have been allocated. + * + */ + template<class MyMeshType, class MyMatrixType> + Polyhedron3D2DIntersectorP0P0<MyMeshType,MyMatrixType>::~Polyhedron3D2DIntersectorP0P0() + { + releaseArrays(); + } + + template<class MyMeshType, class MyMatrixType> + void Polyhedron3D2DIntersectorP0P0<MyMeshType,MyMatrixType>::releaseArrays() + { + for(typename std::vector< SplitterTetra<MyMeshType>* >::iterator iter = _tetra.begin(); iter != _tetra.end(); ++iter) + delete *iter; + _split.releaseArrays(); + _tetra.clear(); + } + + /** + * Calculates the volume of intersection of an element in the source mesh and the target element + * represented by the object. + * The calculation is performed by calling the corresponding method for + * each SplitterTetra object created by the splitting. + * + * @param targetCell in C mode. + * @param srcCells in C mode. + */ + template<class MyMeshType, class MyMatrixType> + void Polyhedron3D2DIntersectorP0P0<MyMeshType,MyMatrixType>::intersectCells(ConnType targetCell, + const std::vector<ConnType>& srcCells, + MyMatrixType& matrix) + { + int nbOfNodesT=Intersector3D<MyMeshType,MyMatrixType>::_target_mesh.getNumberOfNodesOfElement(OTT<ConnType,numPol>::indFC(targetCell)); + releaseArrays(); + _split.splitTargetCell(targetCell,nbOfNodesT,_tetra); + + for(typename std::vector<ConnType>::const_iterator iterCellS=srcCells.begin();iterCellS!=srcCells.end();iterCellS++) + { + double surface = 0.; + std::multiset<TriangleFaceKey> listOfTetraFacesTreated; + std::set<TriangleFaceKey> listOfTetraFacesColinear; + + // calculate the coordinates of the nodes + typename MyMeshType::MyConnType cellSrc = *iterCellS; + int cellSrcIdx = OTT<ConnType,numPol>::indFC(cellSrc); + NormalizedCellType normCellType=Intersector3D<MyMeshType,MyMatrixType>::_src_mesh.getTypeOfElement(cellSrcIdx); + const CellModel& cellModelCell=CellModel::GetCellModel(normCellType); + const MyMeshType& src_mesh = Intersector3D<MyMeshType,MyMatrixType>::_src_mesh; + unsigned nbOfNodes4Type=cellModelCell.isDynamic() ? src_mesh.getNumberOfNodesOfElement(cellSrcIdx) : cellModelCell.getNumberOfNodes(); + int *polyNodes=new int[nbOfNodes4Type]; + double **polyCoords = new double*[nbOfNodes4Type]; + for(int i = 0;i<(int)nbOfNodes4Type;++i) + { + // we could store mapping local -> global numbers too, but not sure it is worth it + const int globalNodeNum = getGlobalNumberOfNode(i, OTT<ConnType,numPol>::indFC(*iterCellS), src_mesh); + polyNodes[i] = globalNodeNum; + polyCoords[i] = const_cast<double*>(src_mesh.getCoordinatesPtr()+MyMeshType::MY_SPACEDIM*globalNodeNum); + } + + for(typename std::vector<SplitterTetra<MyMeshType>*>::iterator iter = _tetra.begin(); iter != _tetra.end(); ++iter) + surface += (*iter)->intersectSourceFace(normCellType, + nbOfNodes4Type, + polyNodes, + polyCoords, + _dim_caracteristic, + _precision, + listOfTetraFacesTreated, + listOfTetraFacesColinear); + + if(surface!=0.) + { + + matrix[targetCell].insert(std::make_pair(cellSrcIdx, surface)); + + bool isSrcFaceColinearWithFaceOfTetraTargetCell = false; + std::set<TriangleFaceKey>::iterator iter; + for (iter = listOfTetraFacesColinear.begin(); iter != listOfTetraFacesColinear.end(); ++iter) + { + if (listOfTetraFacesTreated.count(*iter) != 1) + { + isSrcFaceColinearWithFaceOfTetraTargetCell = false; + break; + } + else + { + isSrcFaceColinearWithFaceOfTetraTargetCell = true; + } + } + + if (isSrcFaceColinearWithFaceOfTetraTargetCell) + { + DuplicateFacesType::iterator intersectFacesIter = _intersect_faces.find(cellSrcIdx); + if (intersectFacesIter != _intersect_faces.end()) + { + intersectFacesIter->second.insert(targetCell); + } + else + { + std::set<int> targetCellSet; + targetCellSet.insert(targetCell); + _intersect_faces.insert(std::make_pair(cellSrcIdx, targetCellSet)); + } + } + } + delete [] polyNodes; + delete [] polyCoords; + } + _split.releaseArrays(); + } +} + +#endif diff --git a/src/medtool/src/INTERP_KERNEL/PolyhedronIntersectorP0P0.hxx b/src/medtool/src/INTERP_KERNEL/PolyhedronIntersectorP0P0.hxx new file mode 100644 index 000000000..35193ec13 --- /dev/null +++ b/src/medtool/src/INTERP_KERNEL/PolyhedronIntersectorP0P0.hxx @@ -0,0 +1,65 @@ +// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 +// 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 __POLYHEDRONINTERSECTORP0P0_HXX__ +#define __POLYHEDRONINTERSECTORP0P0_HXX__ + +#include "Intersector3DP0P0.hxx" +#include "SplitterTetra.hxx" +#include "NormalizedUnstructuredMesh.hxx" + +namespace INTERP_KERNEL +{ + + + /** + * \brief Class responsible for calculating intersection between a hexahedron target element and + * the source elements. + * + */ + template<class MyMeshType, class MyMatrix> + class PolyhedronIntersectorP0P0 : public Intersector3DP0P0<MyMeshType,MyMatrix> + { + public: + static const int SPACEDIM=MyMeshType::MY_SPACEDIM; + static const int MESHDIM=MyMeshType::MY_MESHDIM; + typedef typename MyMeshType::MyConnType ConnType; + static const NumberingPolicy numPol=MyMeshType::My_numPol; + public: + + PolyhedronIntersectorP0P0(const MyMeshType& targetMesh, const MyMeshType& srcMesh, SplittingPolicy policy = PLANAR_FACE_5); + + ~PolyhedronIntersectorP0P0(); + + void intersectCells(ConnType targetCell, const std::vector<ConnType>& srcCells, MyMatrix& res); + + private: + void releaseArrays(); + private: + /// pointers to the SplitterTetra objects representing the tetrahedra + /// that result from the splitting of the hexahedron target cell + std::vector< SplitterTetra<MyMeshType>* > _tetra; + + SplitterTetra2<MyMeshType> _split; + + }; +} + +#endif diff --git a/src/medtool/src/INTERP_KERNEL/PolyhedronIntersectorP0P0.txx b/src/medtool/src/INTERP_KERNEL/PolyhedronIntersectorP0P0.txx new file mode 100644 index 000000000..6ed792171 --- /dev/null +++ b/src/medtool/src/INTERP_KERNEL/PolyhedronIntersectorP0P0.txx @@ -0,0 +1,97 @@ +// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 +// 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 __POLYHEDRONINTERSECTORP0P0_TXX__ +#define __POLYHEDRONINTERSECTORP0P0_TXX__ + +#include "PolyhedronIntersectorP0P0.hxx" +#include "Intersector3DP0P0.txx" +#include "MeshUtils.hxx" + +#include "SplitterTetra.txx" + +namespace INTERP_KERNEL +{ + + /** + * Constructor creating object from target cell global number + * The constructor first calculates the necessary nodes, + * (depending on the splitting policy) and then splits the hexahedron into + * tetrahedra, placing these in the internal vector _tetra. + * + * @param targetMesh mesh containing the target elements + * @param srcMesh mesh containing the source elements + * @param policy splitting policy to be used + */ + template<class MyMeshType, class MyMatrix> + PolyhedronIntersectorP0P0<MyMeshType,MyMatrix>::PolyhedronIntersectorP0P0(const MyMeshType& targetMesh, const MyMeshType& srcMesh, SplittingPolicy policy):Intersector3DP0P0<MyMeshType,MyMatrix>(targetMesh,srcMesh),_split(targetMesh,srcMesh,policy) + { + } + + /** + * Destructor. + * Liberates the SplitterTetra objects and potential sub-node points that have been allocated. + * + */ + template<class MyMeshType, class MyMatrix> + PolyhedronIntersectorP0P0<MyMeshType,MyMatrix>::~PolyhedronIntersectorP0P0() + { + releaseArrays(); + } + + template<class MyMeshType, class MyMatrix> + void PolyhedronIntersectorP0P0<MyMeshType,MyMatrix>::releaseArrays() + { + for(typename std::vector< SplitterTetra<MyMeshType>* >::iterator iter = _tetra.begin(); iter != _tetra.end(); ++iter) + delete *iter; + _split.releaseArrays(); + _tetra.clear(); + } + + /** + * Calculates the volume of intersection of an element in the source mesh and the target element + * represented by the object. + * The calculation is performed by calling the corresponding method for + * each SplitterTetra object created by the splitting. + * + * @param targetCell in C mode. + * @param srcCells in C mode. + * + */ + template<class MyMeshType, class MyMatrix> + void PolyhedronIntersectorP0P0<MyMeshType,MyMatrix>::intersectCells(ConnType targetCell, const std::vector<ConnType>& srcCells, MyMatrix& res) + { + releaseArrays(); + _split.splitTargetCell2(targetCell,_tetra); + for(typename std::vector<ConnType>::const_iterator iterCellS=srcCells.begin();iterCellS!=srcCells.end();iterCellS++) + { + double volume = 0.; + for(typename std::vector<SplitterTetra<MyMeshType>*>::iterator iter = _tetra.begin(); iter != _tetra.end(); ++iter) + { + volume += (*iter)->intersectSourceCell(*iterCellS); + (*iter)->clearVolumesCache(); + } + if(volume!=0.) + res[targetCell].insert(std::make_pair(OTT<ConnType,numPol>::indFC(*iterCellS), volume)); + } + _split.releaseArrays(); + } +} + +#endif diff --git a/src/medtool/src/INTERP_KERNEL/PolyhedronIntersectorP0P1.hxx b/src/medtool/src/INTERP_KERNEL/PolyhedronIntersectorP0P1.hxx new file mode 100644 index 000000000..2bf2ec0b3 --- /dev/null +++ b/src/medtool/src/INTERP_KERNEL/PolyhedronIntersectorP0P1.hxx @@ -0,0 +1,65 @@ +// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 +// 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 __POLYHEDRONINTERSECTORP0P1_HXX__ +#define __POLYHEDRONINTERSECTORP0P1_HXX__ + +#include "Intersector3DP0P1.hxx" +#include "SplitterTetra.hxx" +#include "NormalizedUnstructuredMesh.hxx" + +namespace INTERP_KERNEL +{ + + + /** + * \brief Class responsible for calculating intersection between a hexahedron target element and + * the source elements. + * + */ + template<class MyMeshType, class MyMatrix> + class PolyhedronIntersectorP0P1 : public Intersector3DP0P1<MyMeshType,MyMatrix> + { + public: + static const int SPACEDIM=MyMeshType::MY_SPACEDIM; + static const int MESHDIM=MyMeshType::MY_MESHDIM; + typedef typename MyMeshType::MyConnType ConnType; + static const NumberingPolicy numPol=MyMeshType::My_numPol; + public: + + PolyhedronIntersectorP0P1(const MyMeshType& targetMesh, const MyMeshType& srcMesh, SplittingPolicy policy = PLANAR_FACE_5); + + ~PolyhedronIntersectorP0P1(); + + void intersectCells(ConnType targetCell, const std::vector<ConnType>& srcCells, MyMatrix& res); + + private: + void releaseArrays(); + private: + /// pointers to the SplitterTetra objects representing the tetrahedra + /// that result from the splitting of the hexahedron target cell + std::vector< SplitterTetra<MyMeshType>* > _tetra; + + SplitterTetra2<MyMeshType> _split; + + }; +} + +#endif diff --git a/src/medtool/src/INTERP_KERNEL/PolyhedronIntersectorP0P1.txx b/src/medtool/src/INTERP_KERNEL/PolyhedronIntersectorP0P1.txx new file mode 100644 index 000000000..43839bb45 --- /dev/null +++ b/src/medtool/src/INTERP_KERNEL/PolyhedronIntersectorP0P1.txx @@ -0,0 +1,118 @@ +// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 +// 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 __POLYHEDRONINTERSECTORP0P1_TXX__ +#define __POLYHEDRONINTERSECTORP0P1_TXX__ + +#include "PolyhedronIntersectorP0P1.hxx" +#include "Intersector3DP0P1.txx" +#include "MeshUtils.hxx" + +#include "SplitterTetra.txx" + +namespace INTERP_KERNEL +{ + + /** + * Constructor creating object from target cell global number + * The constructor first calculates the necessary nodes, + * (depending on the splitting policy) and then splits the hexahedron into + * tetrahedra, placing these in the internal vector _tetra. + * + * @param targetMesh mesh containing the target elements + * @param srcMesh mesh containing the source elements + * @param policy splitting policy to be used + */ + template<class MyMeshType, class MyMatrix> + PolyhedronIntersectorP0P1<MyMeshType,MyMatrix>::PolyhedronIntersectorP0P1(const MyMeshType& targetMesh, const MyMeshType& srcMesh, SplittingPolicy policy):Intersector3DP0P1<MyMeshType,MyMatrix>(targetMesh,srcMesh),_split(targetMesh,srcMesh,policy) + { + } + + /** + * Destructor. + * Liberates the SplitterTetra objects and potential sub-node points that have been allocated. + * + */ + template<class MyMeshType, class MyMatrix> + PolyhedronIntersectorP0P1<MyMeshType,MyMatrix>::~PolyhedronIntersectorP0P1() + { + releaseArrays(); + } + + template<class MyMeshType, class MyMatrix> + void PolyhedronIntersectorP0P1<MyMeshType,MyMatrix>::releaseArrays() + { + for(typename std::vector< SplitterTetra<MyMeshType>* >::iterator iter = _tetra.begin(); iter != _tetra.end(); ++iter) + delete *iter; + _split.releaseArrays(); + _tetra.clear(); + } + + /** + * Calculates the volume of intersection of an element in the source mesh and the target element + * represented by the object. + * The calculation is performed by calling the corresponding method for + * each SplitterTetra object created by the splitting. + * + * @param targetCell in C mode. + * @param srcCells in C mode. + * + */ + template<class MyMeshType, class MyMatrix> + void PolyhedronIntersectorP0P1<MyMeshType,MyMatrix>::intersectCells(ConnType targetCell, const std::vector<ConnType>& srcCells, MyMatrix& res) + { + SplitterTetra<MyMeshType>* subTetras[24]; + releaseArrays(); + _split.splitTargetCell2(targetCell,_tetra); + for(typename std::vector<ConnType>::const_iterator iterCellS=srcCells.begin();iterCellS!=srcCells.end();iterCellS++) + { + for(typename std::vector<SplitterTetra<MyMeshType>*>::iterator iter = _tetra.begin(); iter != _tetra.end(); ++iter) + { + (*iter)->splitIntoDualCells(subTetras); + for(int i=0;i<24;i++) + { + SplitterTetra<MyMeshType> *tmp=subTetras[i]; + double volume = tmp->intersectSourceCell(*iterCellS); + if(volume!=0.) + { + int targetNodeId(tmp->getId(0)); + if(targetNodeId<0) + { + std::ostringstream oss; oss << "PolyhedronIntersectorP0P1::intersectCells : On target cell #" << targetCell << " the splitting into tetra4 leads to the creation of an additional point that interacts with source cell Id #" << *iterCellS << " !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + typename MyMatrix::value_type& resRow=res[targetNodeId]; + typename MyMatrix::value_type::const_iterator iterRes=resRow.find(OTT<ConnType,numPol>::indFC(*iterCellS)); + if(iterRes==resRow.end()) + resRow.insert(std::make_pair(OTT<ConnType,numPol>::indFC(*iterCellS),volume)); + else + { + double val=(*iterRes).second+volume; + resRow.erase(OTT<ConnType,numPol>::indFC(*iterCellS)); + resRow.insert(std::make_pair(OTT<ConnType,numPol>::indFC(*iterCellS),val)); + } + } + delete tmp; + } + } + } + } +} + +#endif diff --git a/src/medtool/src/INTERP_KERNEL/PolyhedronIntersectorP1P0.hxx b/src/medtool/src/INTERP_KERNEL/PolyhedronIntersectorP1P0.hxx new file mode 100644 index 000000000..4c9cb248a --- /dev/null +++ b/src/medtool/src/INTERP_KERNEL/PolyhedronIntersectorP1P0.hxx @@ -0,0 +1,65 @@ +// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 +// 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 __POLYHEDRONINTERSECTORP1P0_HXX__ +#define __POLYHEDRONINTERSECTORP1P0_HXX__ + +#include "Intersector3DP1P0.hxx" +#include "SplitterTetra.hxx" +#include "NormalizedUnstructuredMesh.hxx" + +namespace INTERP_KERNEL +{ + + + /** + * \brief Class responsible for calculating intersection between a hexahedron target element and + * the source elements. + * + */ + template<class MyMeshType, class MyMatrix> + class PolyhedronIntersectorP1P0 : public Intersector3DP1P0<MyMeshType,MyMatrix> + { + public: + static const int SPACEDIM=MyMeshType::MY_SPACEDIM; + static const int MESHDIM=MyMeshType::MY_MESHDIM; + typedef typename MyMeshType::MyConnType ConnType; + static const NumberingPolicy numPol=MyMeshType::My_numPol; + public: + + PolyhedronIntersectorP1P0(const MyMeshType& targetMesh, const MyMeshType& srcMesh, SplittingPolicy policy = PLANAR_FACE_5); + + ~PolyhedronIntersectorP1P0(); + + void intersectCells(ConnType targetCell, const std::vector<ConnType>& srcCells, MyMatrix& res); + + private: + void releaseArrays(); + private: + /// pointers to the SplitterTetra objects representing the tetrahedra + /// that result from the splitting of the hexahedron target cell + std::vector< SplitterTetra<MyMeshType>* > _tetra; + + SplitterTetra2<MyMeshType> _split; + + }; +} + +#endif diff --git a/src/medtool/src/INTERP_KERNEL/PolyhedronIntersectorP1P0.txx b/src/medtool/src/INTERP_KERNEL/PolyhedronIntersectorP1P0.txx new file mode 100644 index 000000000..350f33252 --- /dev/null +++ b/src/medtool/src/INTERP_KERNEL/PolyhedronIntersectorP1P0.txx @@ -0,0 +1,117 @@ +// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 +// 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 __POLYHEDRONINTERSECTORP1P0_TXX__ +#define __POLYHEDRONINTERSECTORP1P0_TXX__ + +#include "PolyhedronIntersectorP1P0.hxx" +#include "Intersector3DP1P0.txx" +#include "MeshUtils.hxx" + +#include "SplitterTetra.txx" + +namespace INTERP_KERNEL +{ + + /** + * Constructor creating object from target cell global number + * The constructor first calculates the necessary nodes, + * (depending on the splitting policy) and then splits the hexahedron into + * tetrahedra, placing these in the internal vector _tetra. + * + * @param targetMesh mesh containing the target elements + * @param srcMesh mesh containing the source elements + * @param policy splitting policy to be used + * + * WARNING : in _split attribute, sourceMesh and targetMesh are switched in order to fit intersectCells feature. + */ + template<class MyMeshType, class MyMatrix> + PolyhedronIntersectorP1P0<MyMeshType,MyMatrix>::PolyhedronIntersectorP1P0(const MyMeshType& targetMesh, const MyMeshType& srcMesh, SplittingPolicy policy):Intersector3DP1P0<MyMeshType,MyMatrix>(targetMesh,srcMesh),_split(srcMesh,targetMesh,policy) + { + } + + /** + * Destructor. + * Liberates the SplitterTetra objects and potential sub-node points that have been allocated. + * + */ + template<class MyMeshType, class MyMatrix> + PolyhedronIntersectorP1P0<MyMeshType,MyMatrix>::~PolyhedronIntersectorP1P0() + { + releaseArrays(); + } + + template<class MyMeshType, class MyMatrix> + void PolyhedronIntersectorP1P0<MyMeshType,MyMatrix>::releaseArrays() + { + for(typename std::vector< SplitterTetra<MyMeshType>* >::iterator iter = _tetra.begin(); iter != _tetra.end(); ++iter) + delete *iter; + _split.releaseArrays(); + _tetra.clear(); + } + + /** + * Calculates the volume of intersection of an element in the source mesh and the target element + * represented by the object. + * The calculation is performed by calling the corresponding method for + * each SplitterTetra object created by the splitting. + * + * @param targetCell in C mode. + * @param srcCells in C mode. + * + * WARNING : for all methods on _split object source and target are switched ! + */ + template<class MyMeshType, class MyMatrix> + void PolyhedronIntersectorP1P0<MyMeshType,MyMatrix>::intersectCells(ConnType targetCell, const std::vector<ConnType>& srcCells, MyMatrix& res) + { + SplitterTetra<MyMeshType>* subTetras[24]; + typename MyMatrix::value_type& resRow=res[targetCell]; + for(typename std::vector<ConnType>::const_iterator iterCellS=srcCells.begin();iterCellS!=srcCells.end();iterCellS++) + { + releaseArrays(); + int nbOfNodesS=Intersector3D<MyMeshType,MyMatrix>::_src_mesh.getNumberOfNodesOfElement(OTT<ConnType,numPol>::indFC(*iterCellS)); + _split.splitTargetCell(*iterCellS,nbOfNodesS,_tetra); + for(typename std::vector<SplitterTetra<MyMeshType>*>::iterator iter = _tetra.begin(); iter != _tetra.end(); ++iter) + { + (*iter)->splitIntoDualCells(subTetras); + for(int i=0;i<24;i++) + { + SplitterTetra<MyMeshType> *tmp=subTetras[i]; + double volume = tmp->intersectSourceCell(targetCell); + ConnType sourceNode=tmp->getId(0); + if(volume!=0.) + { + typename MyMatrix::value_type::const_iterator iterRes=resRow.find(OTT<ConnType,numPol>::indFC(sourceNode)); + if(iterRes==resRow.end()) + resRow.insert(std::make_pair(OTT<ConnType,numPol>::indFC(sourceNode),volume)); + else + { + double val=(*iterRes).second+volume; + resRow.erase(OTT<ConnType,numPol>::indFC(sourceNode)); + resRow.insert(std::make_pair(OTT<ConnType,numPol>::indFC(sourceNode),val)); + } + } + delete tmp; + } + } + } + } +} + +#endif diff --git a/src/medtool/src/INTERP_KERNEL/PolyhedronIntersectorP1P0Bary.hxx b/src/medtool/src/INTERP_KERNEL/PolyhedronIntersectorP1P0Bary.hxx new file mode 100644 index 000000000..9dabe51fe --- /dev/null +++ b/src/medtool/src/INTERP_KERNEL/PolyhedronIntersectorP1P0Bary.hxx @@ -0,0 +1,65 @@ +// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 +// 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 __PolyhedronIntersectorP1P0Bary_HXX__ +#define __PolyhedronIntersectorP1P0Bary_HXX__ + +#include "Intersector3DP1P0Bary.hxx" +#include "SplitterTetra.hxx" +#include "NormalizedUnstructuredMesh.hxx" + +namespace INTERP_KERNEL +{ + + + /** + * \brief Class responsible for calculating intersection between a hexahedron target element and + * the source elements. + * + */ + template<class MyMeshType, class MyMatrix> + class PolyhedronIntersectorP1P0Bary : public Intersector3DP1P0Bary<MyMeshType,MyMatrix> + { + public: + static const int SPACEDIM=MyMeshType::MY_SPACEDIM; + static const int MESHDIM=MyMeshType::MY_MESHDIM; + typedef typename MyMeshType::MyConnType ConnType; + static const NumberingPolicy numPol=MyMeshType::My_numPol; + public: + + PolyhedronIntersectorP1P0Bary(const MyMeshType& targetMesh, const MyMeshType& srcMesh, SplittingPolicy policy = PLANAR_FACE_5); + + ~PolyhedronIntersectorP1P0Bary(); + + void intersectCells(ConnType targetCell, const std::vector<ConnType>& srcCells, MyMatrix& res); + + private: + void releaseArrays(); + private: + /// pointers to the SplitterTetra objects representing the tetrahedra + /// that result from the splitting of the hexahedron target cell + std::vector< SplitterTetra<MyMeshType>* > _tetra; + + SplitterTetra2<MyMeshType> _split; + + }; +} + +#endif diff --git a/src/medtool/src/INTERP_KERNEL/PolyhedronIntersectorP1P0Bary.txx b/src/medtool/src/INTERP_KERNEL/PolyhedronIntersectorP1P0Bary.txx new file mode 100644 index 000000000..6136b5ee9 --- /dev/null +++ b/src/medtool/src/INTERP_KERNEL/PolyhedronIntersectorP1P0Bary.txx @@ -0,0 +1,154 @@ +// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 +// 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 __PolyhedronIntersectorP1P0Bary_TXX__ +#define __PolyhedronIntersectorP1P0Bary_TXX__ + +#include "PolyhedronIntersectorP1P0Bary.hxx" +#include "Intersector3DP1P0Bary.txx" +#include "MeshUtils.hxx" + +#include "SplitterTetra.txx" + +namespace INTERP_KERNEL +{ + + /** + * Constructor creating object from target cell global number + * The constructor first calculates the necessary nodes, + * (depending on the splitting policy) and then splits the hexahedron into + * tetrahedra, placing these in the internal vector _tetra. + * + * @param targetMesh mesh containing the target elements + * @param srcMesh mesh containing the source elements + * @param policy splitting policy to be used + * + * WARNING : in _split attribute, sourceMesh and targetMesh are switched in order to fit intersectCells feature. + */ + template<class MyMeshType, class MyMatrix> + PolyhedronIntersectorP1P0Bary<MyMeshType,MyMatrix>::PolyhedronIntersectorP1P0Bary(const MyMeshType& targetMesh, + const MyMeshType& srcMesh, + SplittingPolicy policy) + :Intersector3DP1P0Bary<MyMeshType,MyMatrix>(targetMesh,srcMesh),_split(targetMesh,srcMesh,policy) + { + // SPEC: + // "Limitation. For the P1P0 barycentric improvement only triangle source cells in 2D and + // tetrahedrons in 3D will be supported by interpolators. If a non + // triangle/tetrahedron source cell is detected an INTERP_KERNEL::Exception should be thrown." + + // Check types of source elements here rather than in intersectCells() since a wrong type can be + // found late after a long time of calculation. + + const unsigned long numSrcElems = srcMesh.getNumberOfElements(); + for(unsigned long i = 0 ; i < numSrcElems ; ++i) + if ( srcMesh.getTypeOfElement( OTT<ConnType,numPol>::indFC(i) ) != NORM_TETRA4 ) + throw INTERP_KERNEL::Exception("P1P0 barycentric algorithm works only with tetrahedral source meshes"); + } + + /** + * Destructor. + * Liberates the SplitterTetra objects and potential sub-node points that have been allocated. + * + */ + template<class MyMeshType, class MyMatrix> + PolyhedronIntersectorP1P0Bary<MyMeshType,MyMatrix>::~PolyhedronIntersectorP1P0Bary() + { + releaseArrays(); + } + + template<class MyMeshType, class MyMatrix> + void PolyhedronIntersectorP1P0Bary<MyMeshType,MyMatrix>::releaseArrays() + { + for(typename std::vector< SplitterTetra<MyMeshType>* >::iterator iter = _tetra.begin(); iter != _tetra.end(); ++iter) + delete *iter; + _split.releaseArrays(); + _tetra.clear(); + } + + //================================================================================ + /*! + * \brief This method computes a value per each node of source cell for each target cell. + * \param srcCell - a source tetrahedron + * \param tgtCells - target elements + * \param res - matrix to fill in + */ + //================================================================================ + + template<class MyMeshType, class MyMatrix> + void PolyhedronIntersectorP1P0Bary<MyMeshType,MyMatrix>::intersectCells(ConnType tgtCell, + const std::vector<ConnType>& srcCells, + MyMatrix& res) + { + typename MyMatrix::value_type& resRow=res[tgtCell]; + + int nbOfNodesT=Intersector3D<MyMeshType,MyMatrix>::_target_mesh.getNumberOfNodesOfElement(OTT<ConnType,numPol>::indFC(tgtCell)); + releaseArrays(); + _split.splitTargetCell(tgtCell,nbOfNodesT,_tetra); + + for(typename std::vector<ConnType>::const_iterator iterCellS=srcCells.begin();iterCellS!=srcCells.end();iterCellS++) + { + // intersect a source tetrahedron with each target tetrahedron: get intersection volume and barycenter + double baryCentre[SPACEDIM], total_baryCentre[3] = { 0., 0., 0.}; + double interVolume = 0; + for(typename std::vector<SplitterTetra<MyMeshType>*>::iterator iterTetraT = _tetra.begin(); iterTetraT != _tetra.end(); ++iterTetraT) + { + SplitterTetra<MyMeshType> *tmp=*iterTetraT; + tmp->clearVolumesCache(); + double volume = tmp->intersectSourceCell(*iterCellS, baryCentre); + if ( volume > 0 ) + { + interVolume += volume; + for ( int i = 0; i < SPACEDIM; ++i ) + total_baryCentre[i] += baryCentre[i]*volume; + } + } + if(interVolume!=0) + { + for ( int i = 0; i < SPACEDIM; ++i ) + total_baryCentre[i] /= interVolume; + + // coordinates of the source tetrahedron + std::vector<const double*> srcCellCoords(4); + for ( int n = 0; n < 4; ++n ) + srcCellCoords[ n ] = getCoordsOfNode( n, *iterCellS, Intersector3D<MyMeshType,MyMatrix>::_src_mesh ); + + // compute barycentric coordinates + double baryCoords[4]; + barycentric_coords( srcCellCoords, total_baryCentre, baryCoords); + + // store coeffs of each node of the source tetrahedron + const ConnType *srcCellNodes=Intersector3D<MyMeshType,MyMatrix>::_src_mesh.getConnectivityPtr()+OTT<ConnType,numPol>::conn2C(Intersector3D<MyMeshType,MyMatrix>::_src_mesh.getConnectivityIndexPtr()[*iterCellS]); + for ( int n = 0; n < 4; ++n ) + { + double val = baryCoords[n] * interVolume; + ConnType curNodeS = srcCellNodes[n]; + typename MyMatrix::value_type::const_iterator iterRes=resRow.find(curNodeS); + if(iterRes!=resRow.end()) + { + val += iterRes->second; + resRow.erase( curNodeS ); + } + resRow.insert(std::make_pair(curNodeS,val)); + } + } + } + } +} + +#endif diff --git a/src/medtool/src/INTERP_KERNEL/PolyhedronIntersectorP1P1.hxx b/src/medtool/src/INTERP_KERNEL/PolyhedronIntersectorP1P1.hxx new file mode 100644 index 000000000..002a173ca --- /dev/null +++ b/src/medtool/src/INTERP_KERNEL/PolyhedronIntersectorP1P1.hxx @@ -0,0 +1,56 @@ +// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 +// 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 __PolyhedronIntersectorP1P1_HXX__ +#define __PolyhedronIntersectorP1P1_HXX__ + +#include "Intersector3DP1P1.hxx" +#include "SplitterTetra.hxx" +#include "NormalizedUnstructuredMesh.hxx" + +namespace INTERP_KERNEL +{ + + + /** + * \brief Class responsible for calculating intersection between a hexahedron target element and + * the source elements. + * + */ + template<class MyMeshType, class MyMatrix> + class PolyhedronIntersectorP1P1 : public Intersector3DP1P1<MyMeshType,MyMatrix> + { + public: + static const int SPACEDIM=MyMeshType::MY_SPACEDIM; + static const int MESHDIM=MyMeshType::MY_MESHDIM; + typedef typename MyMeshType::MyConnType ConnType; + static const NumberingPolicy numPol=MyMeshType::My_numPol; + public: + + PolyhedronIntersectorP1P1(const MyMeshType& targetMesh, const MyMeshType& srcMesh, SplittingPolicy policy = PLANAR_FACE_5); + + ~PolyhedronIntersectorP1P1(); + + void intersectCells(ConnType targetCell, const std::vector<ConnType>& srcCells, MyMatrix& res); + + }; +} + +#endif diff --git a/src/medtool/src/INTERP_KERNEL/PolyhedronIntersectorP1P1.txx b/src/medtool/src/INTERP_KERNEL/PolyhedronIntersectorP1P1.txx new file mode 100644 index 000000000..f26320187 --- /dev/null +++ b/src/medtool/src/INTERP_KERNEL/PolyhedronIntersectorP1P1.txx @@ -0,0 +1,134 @@ +// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 +// 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 __PolyhedronIntersectorP1P1_TXX__ +#define __PolyhedronIntersectorP1P1_TXX__ + +#include "PolyhedronIntersectorP1P1.hxx" +#include "Intersector3DP1P1.txx" +#include "MeshUtils.hxx" + +#include "SplitterTetra.txx" + +namespace INTERP_KERNEL +{ + + /** + * Constructor creating object from target cell global number + * + * @param targetMesh mesh containing the target elements + * @param srcMesh mesh containing the source elements + * @param policy splitting policy to be used + */ + template<class MyMeshType, class MyMatrix> + PolyhedronIntersectorP1P1<MyMeshType,MyMatrix>::PolyhedronIntersectorP1P1(const MyMeshType& targetMesh, const MyMeshType& srcMesh, SplittingPolicy policy):Intersector3DP1P1<MyMeshType,MyMatrix>(targetMesh,srcMesh) + { + // SPEC: + // "Limitation. Concerning P1P1 3D improvement only tetrahedron will be supported. + // If another type than tetrahedron is detected an INTERP_KERNEL::Exception should be thrown" + + // Check types of elements here rather than in intersectCells() since a wrong type can be + // found late after a long time of calculation. + + const unsigned long numSrcElems = srcMesh.getNumberOfElements(); + for(unsigned long i = 0 ; i < numSrcElems ; ++i) + if ( srcMesh.getTypeOfElement( OTT<ConnType,numPol>::indFC( i )) != NORM_TETRA4 ) + throw INTERP_KERNEL::Exception("P1P1 3D algorithm works only with tetrahedral meshes"); + + const unsigned long numTgtElems = targetMesh.getNumberOfElements(); + for(unsigned long i = 0 ; i < numTgtElems ; ++i) + if ( targetMesh.getTypeOfElement( OTT<ConnType,numPol>::indFC( i )) != NORM_TETRA4 ) + throw INTERP_KERNEL::Exception("P1P1 3D algorithm works only with tetrahedral meshes"); + } + + /** + * Destructor. + */ + template<class MyMeshType, class MyMatrix> + PolyhedronIntersectorP1P1<MyMeshType,MyMatrix>::~PolyhedronIntersectorP1P1() + { + } + + /** + * Calculates the volume of intersection of an element in the source mesh and the target element + * represented by the object. + * + * @param targetCell in C mode. + * @param srcCells in C mode. + */ + template<class MyMeshType, class MyMatrix> + void PolyhedronIntersectorP1P1<MyMeshType,MyMatrix>::intersectCells(ConnType targetCell, const std::vector<ConnType>& srcCells, MyMatrix& res) + { +#ifdef _DEBUG_ + UnitTetraIntersectionBary b; b.init(); +#endif + // split the targetCell into dual cells + std::pair< int, std::vector<double> > subTetraNodes[24]; // a node of sub tetra and its coordinates + const double* nodes[4]; int conn[4]; + for(int node = 0; node < 4 ; ++node) + nodes[node]=getCoordsOfNode2(node, OTT<ConnType,numPol>::indFC(targetCell), + Intersector3D<MyMeshType,MyMatrix>::_target_mesh,conn[node]); + SplitterTetra<MyMeshType> tgtTetra(Intersector3D<MyMeshType,MyMatrix>::_src_mesh, nodes, conn); + for (int i=0; i<24; i++) + { + subTetraNodes[i].second.resize(12); + tgtTetra.splitMySelfForDual(&subTetraNodes[i].second[0],i,subTetraNodes[i].first); + } + // intersect each source tetrahedron with each of target dual cells + SplitterTetra<MyMeshType>* subTetrasS[24]; + for(typename std::vector<ConnType>::const_iterator iterCellS=srcCells.begin();iterCellS!=srcCells.end();iterCellS++) + { + // split a source cell into dual cells + for(int node = 0; node < 4 ; ++node) + nodes[node]=getCoordsOfNode2(node, OTT<ConnType,numPol>::indFC(*iterCellS), + Intersector3D<MyMeshType,MyMatrix>::_src_mesh,conn[node]); + + SplitterTetra<MyMeshType> srcTetra(Intersector3D<MyMeshType,MyMatrix>::_target_mesh, nodes, conn); + srcTetra.splitIntoDualCells(subTetrasS); + + // intersect each target subTetra with each source one + for(int i=0;i<24;i++) + { + SplitterTetra<MyMeshType> *tmp=subTetrasS[i]; + ConnType sourceNode=OTT<ConnType,numPol>::indFC(tmp->getId(0)); + for(int j=0;j<24;j++) + { + const double* tetraNodes12 = &subTetraNodes[j].second[0]; + const double* tetraNodesT[4]={ tetraNodes12, tetraNodes12+3, tetraNodes12+6, tetraNodes12+9 }; + double volume = tmp->intersectTetra( tetraNodesT ); + if(volume!=0.) + { + ConnType tgtNode=subTetraNodes[j].first; + typename MyMatrix::value_type& resRow = res[tgtNode]; + typename MyMatrix::value_type::const_iterator iterRes=resRow.find( sourceNode ); + if(iterRes!=resRow.end()) + { + volume += (*iterRes).second; + resRow.erase(sourceNode); + } + resRow.insert(std::make_pair(sourceNode,volume)); + } + } + delete tmp; + } + } + } +} + +#endif diff --git a/src/medtool/src/INTERP_KERNEL/RegionNode.hxx b/src/medtool/src/INTERP_KERNEL/RegionNode.hxx new file mode 100644 index 000000000..c7aaf7532 --- /dev/null +++ b/src/medtool/src/INTERP_KERNEL/RegionNode.hxx @@ -0,0 +1,68 @@ +// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 +// 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 __REGIONNODE_HXX__ +#define __REGIONNODE_HXX__ + +#include "MeshRegion.hxx" + +namespace INTERP_KERNEL +{ + + /** + * \brief Class containing a tuplet of a source region and a target region. + * This is used as the object to put on the stack in the depth-first search + * in the bounding-box filtering process. + */ + template<class ConnType> + class RegionNode + { + public: + + RegionNode() { } + + ~RegionNode() { } + + /** + * Accessor to source region + * + * @return reference to source region + */ + MeshRegion<ConnType>& getSrcRegion() { return _srcRegion; } + + /** + * Accessor to target region + * + * @return reference to target region + */ + MeshRegion<ConnType>& getTargetRegion() { return _targetRegion; } + + private: + + /// source region + MeshRegion<ConnType> _srcRegion; + + /// target region + MeshRegion<ConnType> _targetRegion; + + }; + +} + +#endif diff --git a/src/medtool/src/INTERP_KERNEL/SplitterTetra.cxx b/src/medtool/src/INTERP_KERNEL/SplitterTetra.cxx new file mode 100644 index 000000000..06dbb101e --- /dev/null +++ b/src/medtool/src/INTERP_KERNEL/SplitterTetra.cxx @@ -0,0 +1,217 @@ +// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 +// 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 "SplitterTetra.hxx" + +namespace INTERP_KERNEL +{ + + void SplitHexa8IntoTetras(SplittingPolicy policy, const int *nodalConnBg, const int *nodalConnEnd, const double *coords, + std::vector<int>& tetrasNodalConn, std::vector<double>& addCoords) + { + if(std::distance(nodalConnBg,nodalConnEnd)!=8) + throw INTERP_KERNEL::Exception("SplitHexa8IntoTetras : input hexa do not have 8 nodes !"); + switch(policy) + { + case PLANAR_FACE_5: + { + tetrasNodalConn.resize(20); + int *conn(&tetrasNodalConn[0]); + conn[0]=nodalConnBg[SPLIT_NODES_5_WO[0]]; conn[1]=nodalConnBg[SPLIT_NODES_5_WO[1]]; conn[2]=nodalConnBg[SPLIT_NODES_5_WO[2]]; conn[3]=nodalConnBg[SPLIT_NODES_5_WO[3]]; + conn[4]=nodalConnBg[SPLIT_NODES_5_WO[4]]; conn[5]=nodalConnBg[SPLIT_NODES_5_WO[5]]; conn[6]=nodalConnBg[SPLIT_NODES_5_WO[6]]; conn[7]=nodalConnBg[SPLIT_NODES_5_WO[7]]; + conn[8]=nodalConnBg[SPLIT_NODES_5_WO[8]]; conn[9]=nodalConnBg[SPLIT_NODES_5_WO[9]]; conn[10]=nodalConnBg[SPLIT_NODES_5_WO[10]]; conn[11]=nodalConnBg[SPLIT_NODES_5_WO[11]]; + conn[12]=nodalConnBg[SPLIT_NODES_5_WO[12]]; conn[13]=nodalConnBg[SPLIT_NODES_5_WO[13]]; conn[14]=nodalConnBg[SPLIT_NODES_5_WO[14]]; conn[15]=nodalConnBg[SPLIT_NODES_5_WO[15]]; + conn[16]=nodalConnBg[SPLIT_NODES_5_WO[16]]; conn[17]=nodalConnBg[SPLIT_NODES_5_WO[17]]; conn[18]=nodalConnBg[SPLIT_NODES_5_WO[18]]; conn[19]=nodalConnBg[SPLIT_NODES_5_WO[19]]; + return ; + } + case PLANAR_FACE_6: + { + tetrasNodalConn.resize(24); + int *conn(&tetrasNodalConn[0]); + conn[0]=nodalConnBg[SPLIT_NODES_6_WO[0]]; conn[1]=nodalConnBg[SPLIT_NODES_6_WO[1]]; conn[2]=nodalConnBg[SPLIT_NODES_6_WO[2]]; conn[3]=nodalConnBg[SPLIT_NODES_6_WO[3]]; + conn[4]=nodalConnBg[SPLIT_NODES_6_WO[4]]; conn[5]=nodalConnBg[SPLIT_NODES_6_WO[5]]; conn[6]=nodalConnBg[SPLIT_NODES_6_WO[6]]; conn[7]=nodalConnBg[SPLIT_NODES_6_WO[7]]; + conn[8]=nodalConnBg[SPLIT_NODES_6_WO[8]]; conn[9]=nodalConnBg[SPLIT_NODES_6_WO[9]]; conn[10]=nodalConnBg[SPLIT_NODES_6_WO[10]]; conn[11]=nodalConnBg[SPLIT_NODES_6_WO[11]]; + conn[12]=nodalConnBg[SPLIT_NODES_6_WO[12]]; conn[13]=nodalConnBg[SPLIT_NODES_6_WO[13]]; conn[14]=nodalConnBg[SPLIT_NODES_6_WO[14]]; conn[15]=nodalConnBg[SPLIT_NODES_6_WO[15]]; + conn[16]=nodalConnBg[SPLIT_NODES_6_WO[16]]; conn[17]=nodalConnBg[SPLIT_NODES_6_WO[17]]; conn[18]=nodalConnBg[SPLIT_NODES_6_WO[18]]; conn[19]=nodalConnBg[SPLIT_NODES_6_WO[19]]; + conn[20]=nodalConnBg[SPLIT_NODES_6_WO[20]]; conn[21]=nodalConnBg[SPLIT_NODES_6_WO[21]]; conn[22]=nodalConnBg[SPLIT_NODES_6_WO[22]]; conn[23]=nodalConnBg[SPLIT_NODES_6_WO[23]]; + return ; + } + case GENERAL_24: + { + addCoords.resize(7*3); + tetrasNodalConn.resize(24*4); + int *conn(&tetrasNodalConn[0]); + double *tmp(&addCoords[18]); + tmp[0]=0.; tmp[1]=0.; tmp[2]=0.; + double *tmp2(&addCoords[0]); + for(int i=0;i<6;i++,tmp2+=3) + { + tmp2[0]=0.; tmp2[1]=0.; tmp2[2]=0.; + for(int j=0;j<4;j++,conn+=4) + { + int tmp3(nodalConnBg[GENERAL_24_SUB_NODES_WO[4*i+j]]); + tmp2[0]+=coords[3*tmp3+0]; + tmp2[1]+=coords[3*tmp3+1]; + tmp2[2]+=coords[3*tmp3+2]; + conn[0]=tmp3; + conn[1]=nodalConnBg[GENERAL_24_SUB_NODES_WO[4*i+(j+1)%4]]; + conn[2]=-(i+1); conn[3]=-7; + } + tmp2[0]/=4.; tmp2[1]/=4.; tmp2[2]/=4.; + tmp[0]+=tmp2[0]; tmp[1]+=tmp2[1]; tmp[2]+=tmp2[2]; + } + tmp[0]/=6.; tmp[1]/=6.; tmp[2]/=6.; + return ; + } + case GENERAL_48: + { + addCoords.resize(19*3); + tetrasNodalConn.resize(48*4); + double *tmp2(&addCoords[0]),*tmp(&addCoords[0]); + for(int i=0;i<12;i++,tmp2+=3) + { + tmp2[0]=(coords[3*nodalConnBg[GENERAL_48_SUB_NODES[2*i]]+0]+coords[3*nodalConnBg[GENERAL_48_SUB_NODES[2*i+1]]+0])/2.; + tmp2[1]=(coords[3*nodalConnBg[GENERAL_48_SUB_NODES[2*i]]+1]+coords[3*nodalConnBg[GENERAL_48_SUB_NODES[2*i+1]]+1])/2.; + tmp2[2]=(coords[3*nodalConnBg[GENERAL_48_SUB_NODES[2*i]]+2]+coords[3*nodalConnBg[GENERAL_48_SUB_NODES[2*i+1]]+2])/2.; + } + for(int i=0;i<7;i++,tmp2+=3) + { + tmp2[0]=(tmp[3*(GENERAL_48_SUB_NODES[2*i+24]-8)+0]+tmp[3*(GENERAL_48_SUB_NODES[2*i+25]-8)+0])/2.; + tmp2[1]=(tmp[3*(GENERAL_48_SUB_NODES[2*i+24]-8)+1]+tmp[3*(GENERAL_48_SUB_NODES[2*i+25]-8)+1])/2.; + tmp2[2]=(tmp[3*(GENERAL_48_SUB_NODES[2*i+24]-8)+2]+tmp[3*(GENERAL_48_SUB_NODES[2*i+25]-8)+2])/2.; + } + int *conn(&tetrasNodalConn[0]); + std::vector<double> dummy; + for(int i=0;i<8;i++) + { + std::vector<int> c; + SplitHexa8IntoTetras(PLANAR_FACE_6,GENERAL_48_SUBZONES_2+i*8,GENERAL_48_SUBZONES_2+(i+1)*8,coords,c,dummy); + int *conn2(&c[0]); + for(int j=0;j<6;j++,conn+=4,conn2+=4) + { + conn[0]=conn2[0]>=0?nodalConnBg[conn2[0]]:conn2[0]; + conn[1]=conn2[1]>=0?nodalConnBg[conn2[1]]:conn2[1]; + conn[2]=conn2[2]>=0?nodalConnBg[conn2[2]]:conn2[2]; + conn[3]=conn2[3]>=0?nodalConnBg[conn2[3]]:conn2[3]; + } + } + return ; + } + default: + throw INTERP_KERNEL::Exception("SplitHexa8IntoTetras : invalid input policy ! Should be in [PLANAR_FACE_5,PLANAR_FACE_6,GENERAL_24,GENERAL_48] !"); + } + } + + void SplitIntoTetras(SplittingPolicy policy, NormalizedCellType gt, const int *nodalConnBg, const int *nodalConnEnd, const double *coords, + std::vector<int>& tetrasNodalConn, std::vector<double>& addCoords) + { + switch(gt) + { + case NORM_TETRA4: + { + std::size_t sz(std::distance(nodalConnBg,nodalConnEnd)); + if(sz!=4) + throw INTERP_KERNEL::Exception("SplitIntoTetras : input tetra do not have 4 nodes !"); + tetrasNodalConn.insert(tetrasNodalConn.end(),nodalConnBg,nodalConnEnd); + return ; + } + case NORM_HEXA8: + { + SplitHexa8IntoTetras(policy,nodalConnBg,nodalConnEnd,coords,tetrasNodalConn,addCoords); + return ; + } + case NORM_PYRA5: + { + std::size_t sz(std::distance(nodalConnBg,nodalConnEnd)); + if(sz!=5) + throw INTERP_KERNEL::Exception("SplitIntoTetras : input pyra5 do not have 5 nodes !"); + tetrasNodalConn.resize(8); + int *conn(&tetrasNodalConn[0]); + conn[0]=nodalConnBg[0]; conn[1]=nodalConnBg[1]; conn[2]=nodalConnBg[2]; conn[3]=nodalConnBg[4]; + conn[4]=nodalConnBg[0]; conn[5]=nodalConnBg[2]; conn[6]=nodalConnBg[3]; conn[7]=nodalConnBg[4]; + return ; + } + case NORM_PENTA6: + { + std::size_t sz(std::distance(nodalConnBg,nodalConnEnd)); + if(sz!=6) + throw INTERP_KERNEL::Exception("SplitIntoTetras : input penta6 do not have 6 nodes !"); + tetrasNodalConn.resize(12); + int *conn(&tetrasNodalConn[0]); + conn[0]=nodalConnBg[0]; conn[1]=nodalConnBg[1]; conn[2]=nodalConnBg[2]; conn[3]=nodalConnBg[3]; + conn[4]=nodalConnBg[3]; conn[5]=nodalConnBg[5]; conn[6]=nodalConnBg[4]; conn[7]=nodalConnBg[2]; + conn[8]=nodalConnBg[4]; conn[9]=nodalConnBg[2]; conn[10]=nodalConnBg[1]; conn[11]=nodalConnBg[3]; + return ; + } + case NORM_HEXGP12: + { + std::size_t sz(std::distance(nodalConnBg,nodalConnEnd)); + if(sz!=12) + throw INTERP_KERNEL::Exception("SplitIntoTetras : input octa12 (hexagone prism) do not have 12 nodes !"); + tetrasNodalConn.resize(48); + int *conn(&tetrasNodalConn[0]); + conn[0]=nodalConnBg[0]; conn[1]=nodalConnBg[1]; conn[2]=nodalConnBg[5]; conn[3]=nodalConnBg[6]; + conn[4]=nodalConnBg[6]; conn[5]=nodalConnBg[11]; conn[6]=nodalConnBg[7]; conn[7]=nodalConnBg[5]; + conn[8]=nodalConnBg[7]; conn[9]=nodalConnBg[5]; conn[10]=nodalConnBg[1]; conn[11]=nodalConnBg[6]; + // + conn[12]=nodalConnBg[1]; conn[13]=nodalConnBg[4]; conn[14]=nodalConnBg[5]; conn[15]=nodalConnBg[7]; + conn[16]=nodalConnBg[7]; conn[17]=nodalConnBg[11]; conn[18]=nodalConnBg[10]; conn[19]=nodalConnBg[5]; + conn[20]=nodalConnBg[10]; conn[21]=nodalConnBg[5]; conn[22]=nodalConnBg[4]; conn[23]=nodalConnBg[7]; + // + conn[24]=nodalConnBg[1]; conn[25]=nodalConnBg[2]; conn[26]=nodalConnBg[4]; conn[27]=nodalConnBg[7]; + conn[28]=nodalConnBg[7]; conn[29]=nodalConnBg[10]; conn[30]=nodalConnBg[8]; conn[31]=nodalConnBg[4]; + conn[32]=nodalConnBg[8]; conn[33]=nodalConnBg[4]; conn[34]=nodalConnBg[2]; conn[35]=nodalConnBg[7]; + // + conn[36]=nodalConnBg[2]; conn[37]=nodalConnBg[3]; conn[38]=nodalConnBg[4]; conn[39]=nodalConnBg[8]; + conn[40]=nodalConnBg[8]; conn[41]=nodalConnBg[10]; conn[42]=nodalConnBg[9]; conn[43]=nodalConnBg[4]; + conn[44]=nodalConnBg[9]; conn[45]=nodalConnBg[4]; conn[46]=nodalConnBg[3]; conn[47]=nodalConnBg[8]; + return ; + } + case NORM_POLYHED: + { + std::size_t nbOfFaces(std::count(nodalConnBg,nodalConnEnd,-1)+1); + std::size_t nbOfTetra(std::distance(nodalConnBg,nodalConnEnd)-nbOfFaces+1); + addCoords.resize((nbOfFaces+1)*3); + tetrasNodalConn.resize(nbOfTetra*4); + int *conn(&tetrasNodalConn[0]); + const int *work(nodalConnBg); + double *tmp(&addCoords[0]),*tmp2(&addCoords[3*nbOfFaces]); + tmp2[0]=0.; tmp2[1]=0.; tmp2[2]=0.; + for(std::size_t i=0;i<nbOfFaces;i++,tmp+=3) + { + tmp[0]=0.; tmp[1]=0.; tmp[2]=0.; + std::size_t nbOfNodesOfFace(std::distance(work,std::find(work,nodalConnEnd,-1))); + for(std::size_t j=0;j<nbOfNodesOfFace;j++,conn+=4) + { + conn[0]=work[j]; conn[1]=work[(j+1)%nbOfNodesOfFace]; conn[2]=-((int)i+1); conn[3]=-((int)nbOfFaces+1); + tmp[0]+=coords[3*work[j]+0]; tmp[1]+=coords[3*work[j]+1]; tmp[2]+=coords[3*work[j]+2]; + } + tmp[0]/=(int)nbOfNodesOfFace; tmp[1]/=(int)nbOfNodesOfFace; tmp[2]/=(int)nbOfNodesOfFace; + tmp2[0]+=tmp[0]; tmp2[1]+=tmp[1]; tmp2[2]+=tmp[2]; + work+=nbOfNodesOfFace+1; + } + tmp2[0]/=(int)nbOfFaces; tmp2[1]/=(int)nbOfFaces; tmp2[2]/=(int)nbOfFaces; + return ; + } + default: + throw INTERP_KERNEL::Exception("SplitIntoTetras : not managed such Geometric type ! Available geometric types are all 3D linear cells !"); + } + } +} diff --git a/src/medtool/src/INTERP_KERNEL/SplitterTetra.hxx b/src/medtool/src/INTERP_KERNEL/SplitterTetra.hxx new file mode 100644 index 000000000..5d242a5e5 --- /dev/null +++ b/src/medtool/src/INTERP_KERNEL/SplitterTetra.hxx @@ -0,0 +1,627 @@ +// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 +// 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 __SPLITTERTETRA_HXX__ +#define __SPLITTERTETRA_HXX__ + +#include "INTERPKERNELDefines.hxx" +#include "TransformedTriangle.hxx" +#include "TetraAffineTransform.hxx" +#include "InterpolationOptions.hxx" +#include "InterpKernelException.hxx" +#include "InterpKernelHashMap.hxx" +#include "VectorUtils.hxx" + +#include <functional> +#include <vector> +#include <cassert> +#include <map> +#include <set> + +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 GENERAL_24_SUB_NODES_WO[28] = + { + 0,4,5,1,// sub-node 8 (face) + 0,1,2,3,// sub-node 9 (face) + 0,3,7,4,// sub-node 10 (face) + 1,5,6,2,// sub-node 11 (face) + 4,7,6,5,// sub-node 12 (face) + 2,6,7,3,// 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 + }; + + // Each sub-node is the barycenter of two other nodes. + // For the edges, these lie on the original mesh. + // For the faces, these are the edge sub-nodes. + // For the cell these are two face sub-nodes. + static const int GENERAL_48_SUB_NODES[38] = + { + 0,1, // sub-node 8 (edge) + 0,4, // sub-node 9 (edge) + 1,5, // sub-node 10 (edge) + 4,5, // sub-node 11 (edge) + 0,3, // sub-node 12 (edge) + 1,2, // sub-node 13 (edge) + 4,7, // sub-node 14 (edge) + 5,6, // sub-node 15 (edge) + 2,3, // sub-node 16 (edge) + 3,7, // sub-node 17 (edge) + 2,6, // sub-node 18 (edge) + 6,7, // sub-node 19 (edge) + 8,11, // sub-node 20 (face) + 12,13, // sub-node 21 (face) + 9,17, // sub-node 22 (face) + 10,18, // sub-node 23 (face) + 14,15, // sub-node 24 (face) + 16,19, // sub-node 25 (face) + 20,25 // sub-node 26 (cell) + }; + + // Define 8 hexahedral subzones as in Grandy, p449 + // the values correspond to the nodes that correspond to nodes 1,2,3,4,5,6,7,8 in the subcell + // For the correspondance of the nodes, see the GENERAL_48_SUB_NODES table in calculateSubNodes + static const int GENERAL_48_SUBZONES[64] = + { + 0,8,21,12,9,20,26,22, + 8,1,13,21,20,10,23,26, + 12,21,16,3,22,26,25,17, + 21,13,2,16,26,23,18,25, + 9,20,26,22,4,11,24,14, + 20,10,23,26,11,5,15,24, + 22,26,25,17,14,24,19,7, + 26,23,18,25,24,15,6,19 + }; + + static const int GENERAL_48_SUBZONES_2[64] = + { + 0,-1,-14,-5,-2,-13,-19,-15, + -1,1,-6,-14,-13,-3,-16,-19, + -5,-14,-9,3,-15,-19,-18,-10, + -14,-6,2,-9,-19,-16,-11,-18, + -2,-13,-19,-15,4,-4,-17,-7, + -13,-3,-16,-19,-4,5,-8,-17, + -15,-19,-18,-10,-7,-17,-12,7, + -19,-16,-11,-18,-17,-8,6,-12}; + + void SplitHexa8IntoTetras(SplittingPolicy policy, const int *nodalConnBg, const int *nodalConnEnd, const double *coords, + std::vector<int>& tetrasNodalConn, std::vector<double>& addCoords); + + INTERPKERNEL_EXPORT void SplitIntoTetras(SplittingPolicy policy, NormalizedCellType gt, const int *nodalConnBg, const int *nodalConnEnd, const double *coords, + std::vector<int>& tetrasNodalConn, std::vector<double>& addCoords); + + /** + * \brief Class representing a triangular face, used as key in caching hash map in SplitterTetra. + * + */ + class TriangleFaceKey + { + public: + + /** + * Constructor + * Sorts the given nodes (so that the order in which they are passed does not matter) and + * calculates a hash value for the key. + * + * @param node1 global number of the first node of the face + * @param node2 global number of the second node of the face + * @param node3 global number of the third node of the face + */ + TriangleFaceKey(int node1, int node2, int node3) + { + Sort3Ints(_nodes, node1, node2, node3); + _hashVal = ( _nodes[0] + _nodes[1] + _nodes[2] ) % 29; + } + + /** + * Equality comparison operator. + * Compares this TriangleFaceKey object to another and determines if they represent the same face. + * + * @param key TriangleFaceKey with which to compare + * @return true if key has the same three nodes as this object, false if not + */ + bool operator==(const TriangleFaceKey& key) const + { + return _nodes[0] == key._nodes[0] && _nodes[1] == key._nodes[1] && _nodes[2] == key._nodes[2]; + } + + /** + * Less than operator. + * + * @param key TriangleFaceKey with which to compare + * @return true if this object has the three nodes less than the nodes of the key object, false if not + */ + bool operator<(const TriangleFaceKey& key) const + { + for (int i = 0; i < 3; ++i) + { + if (_nodes[i] < key._nodes[i]) + { + return true; + } + else if (_nodes[i] > key._nodes[i]) + { + return false; + } + } + return false; + } + + /** + * Returns a hash value for the object, based on its three nodes. + * This value is not unique for each face. + * + * @return a hash value for the object + */ + int hashVal() const + { + return _hashVal; + } + + inline static void Sort3Ints(int* sorted, int node1, int node2, int node3); + + private: + /// global numbers of the three nodes, sorted in ascending order + int _nodes[3]; + + /// hash value for the object, calculated in the constructor + int _hashVal; + }; + + /** + * Method to sort three integers in ascending order + * + * @param sorted int[3] array in which to store the result + * @param x1 first integer + * @param x2 second integer + * @param x3 third integer + */ + inline void TriangleFaceKey::Sort3Ints(int* sorted, int x1, int x2, int x3) + { + if(x1 < x2) + { + if(x1 < x3) + { + // x1 is min + sorted[0] = x1; + sorted[1] = x2 < x3 ? x2 : x3; + sorted[2] = x2 < x3 ? x3 : x2; + } + else + { + // x3, x1, x2 + sorted[0] = x3; + sorted[1] = x1; + sorted[2] = x2; + } + } + else // x2 < x1 + { + if(x2 < x3) + { + // x2 is min + sorted[0] = x2; + sorted[1] = x1 < x3 ? x1 : x3; + sorted[2] = x1 < x3 ? x3 : x1; + } + else + { + // x3, x2, x1 + sorted[0] = x3; + sorted[1] = x2; + sorted[2] = x1; + } + } + } + + /** + * \brief Template specialization of INTERP_KERNEL::hash<T> function object for use with a + * with TriangleFaceKey as key class. + * + */ + template<> class hash<INTERP_KERNEL::TriangleFaceKey> + { + public: + /** + * Operator() that returns the precalculated hashvalue of a TriangleFaceKey object. + * + * @param key a TriangleFaceKey object + * @return an integer hash value for key + */ + int operator()(const INTERP_KERNEL::TriangleFaceKey& key) const + { + return key.hashVal(); + } + }; +} + +namespace INTERP_KERNEL +{ + /** + * \brief Class calculating the volume of intersection between a tetrahedral target element and + * source elements with triangular or quadratilateral faces. + * + */ + template<class MyMeshType> + class SplitterTetra + { + public: + + SplitterTetra(const MyMeshType& srcMesh, const double** tetraCorners, const typename MyMeshType::MyConnType *nodesId); + + SplitterTetra(const MyMeshType& srcMesh, const double tetraCorners[12], const int *conn = 0); + + ~SplitterTetra(); + + double intersectSourceCell(typename MyMeshType::MyConnType srcCell, double* baryCentre=0); + double intersectSourceFace(const NormalizedCellType polyType, + const int polyNodesNbr, + const int *const polyNodes, + const double *const *const polyCoords, + const double dimCaracteristic, + const double precision, + std::multiset<TriangleFaceKey>& listOfTetraFacesTreated, + std::set<TriangleFaceKey>& listOfTetraFacesColinear); + + double intersectTetra(const double** tetraCorners); + + typename MyMeshType::MyConnType getId(int id) { return _conn[id]; } + + void splitIntoDualCells(SplitterTetra<MyMeshType> **output); + + void splitMySelfForDual(double* output, int i, typename MyMeshType::MyConnType& nodeId); + + void clearVolumesCache(); + + private: + inline static void CheckIsOutside(const double* pt, bool* isOutside, const double errTol = DEFAULT_ABS_TOL); + inline static void CheckIsStrictlyOutside(const double* pt, bool* isStrictlyOutside, const double errTol = DEFAULT_ABS_TOL); + inline void calculateNode(typename MyMeshType::MyConnType globalNodeNum); + inline void calculateNode2(typename MyMeshType::MyConnType globalNodeNum, const double* node); + inline void calculateVolume(TransformedTriangle& tri, const TriangleFaceKey& key); + inline void calculateSurface(TransformedTriangle& tri, const TriangleFaceKey& key); + + static inline bool IsFacesCoplanar(const double *const planeNormal, const double planeConstant, + const double *const *const coordsFace, const double precision); + static inline double CalculateIntersectionSurfaceOfCoplanarTriangles(const double *const planeNormal, + const double planeConstant, + const double *const p1, const double *const p2, const double *const p3, + const double *const p4, const double *const p5, const double *const p6, + const double dimCaracteristic, const double precision); + + /// disallow copying + SplitterTetra(const SplitterTetra& t); + + /// disallow assignment + SplitterTetra& operator=(const SplitterTetra& t); + + // member variables + /// affine transform associated with this target element + TetraAffineTransform* _t; + + /// HashMap relating node numbers to transformed nodes, used for caching + HashMap< int , double* > _nodes; + + /// HashMap relating triangular faces to calculated volume contributions, used for caching + HashMap< TriangleFaceKey, double > _volumes; + + /// reference to the source mesh + const MyMeshType& _src_mesh; + + // node id of the first node in target mesh in C mode. + typename MyMeshType::MyConnType _conn[4]; + + double _coords[12]; + + /// Smallest volume of the intersecting elements in the transformed space that will be returned as non-zero. + /// Since the scale is always the same in the transformed space (the target tetrahedron is unitary), this number is independent of the scale of the meshes. + static const double SPARSE_TRUNCATION_LIMIT; + }; + + /** + * Function used to filter out elements by checking if they belong to one of the halfspaces + * x <= 0, x >= 1, y <= 0, y >= 1, z <= 0, z >= 1, (indexed 0 - 7). The function updates an array of boolean variables + * which indicates whether the points that have already been checked are all in a halfspace. For each halfspace, + * the corresponding array element will be true if and only if it was true when the method was called and pt lies in the halfspace. + * + * @param pt double[3] containing the coordiantes of a transformed point + * @param isOutside bool[8] which indicate the results of earlier checks. + */ + template<class MyMeshType> + inline void SplitterTetra<MyMeshType>::CheckIsOutside(const double* pt, bool* isOutside, const double errTol) + { + isOutside[0] = isOutside[0] && (pt[0] < errTol); + isOutside[1] = isOutside[1] && (pt[0] > (1.0-errTol) ); + isOutside[2] = isOutside[2] && (pt[1] < errTol); + isOutside[3] = isOutside[3] && (pt[1] > (1.0-errTol)); + isOutside[4] = isOutside[4] && (pt[2] < errTol); + isOutside[5] = isOutside[5] && (pt[2] > (1.0-errTol)); + isOutside[6] = isOutside[6] && (1.0 - pt[0] - pt[1] - pt[2] < errTol); + isOutside[7] = isOutside[7] && (1.0 - pt[0] - pt[1] - pt[2] > (1.0-errTol) ); + } + + template<class MyMeshType> + inline void SplitterTetra<MyMeshType>::CheckIsStrictlyOutside(const double* pt, bool* isStrictlyOutside, const double errTol) + { + isStrictlyOutside[0] = isStrictlyOutside[0] && (pt[0] < -errTol); + isStrictlyOutside[1] = isStrictlyOutside[1] && (pt[0] > (1.0 + errTol)); + isStrictlyOutside[2] = isStrictlyOutside[2] && (pt[1] < -errTol); + isStrictlyOutside[3] = isStrictlyOutside[3] && (pt[1] > (1.0 + errTol)); + isStrictlyOutside[4] = isStrictlyOutside[4] && (pt[2] < -errTol); + isStrictlyOutside[5] = isStrictlyOutside[5] && (pt[2] > (1.0 + errTol)); + isStrictlyOutside[6] = isStrictlyOutside[6] && (1.0 - pt[0] - pt[1] - pt[2] < -errTol); + isStrictlyOutside[7] = isStrictlyOutside[7] && (1.0 - pt[0] - pt[1] - pt[2] > (1.0 + errTol)); + } + + /** + * Calculates the transformed node with a given global node number. + * Gets the coordinates for the node in _src_mesh with the given global number and applies TetraAffineTransform + * _t to it. Stores the result in the cache _nodes. The non-existance of the node in _nodes should be verified before + * calling. + * + * @param globalNodeNum global node number of the node in the mesh _src_mesh + * + */ + template<class MyMeshType> + inline void SplitterTetra<MyMeshType>::calculateNode(typename MyMeshType::MyConnType globalNodeNum) + { + const double* node = _src_mesh.getCoordinatesPtr()+MyMeshType::MY_SPACEDIM*globalNodeNum; + double* transformedNode = new double[MyMeshType::MY_SPACEDIM]; + assert(transformedNode != 0); + _t->apply(transformedNode, node); + _nodes[globalNodeNum] = transformedNode; + } + + + /** + * Calculates the transformed node with a given global node number. + * Applies TetraAffineTransform * _t to it. + * Stores the result in the cache _nodes. The non-existence of the node in _nodes should be verified before * calling. + * The only difference with the previous method calculateNode is that the coordinates of the node are passed in arguments + * and are not recalculated in order to optimize the method. + * + * @param globalNodeNum global node number of the node in the mesh _src_mesh + * + */ + template<class MyMeshType> + inline void SplitterTetra<MyMeshType>::calculateNode2(typename MyMeshType::MyConnType globalNodeNum, const double* node) + { + double* transformedNode = new double[MyMeshType::MY_SPACEDIM]; + assert(transformedNode != 0); + _t->apply(transformedNode, node); + _nodes[globalNodeNum] = transformedNode; + } + + /** + * Calculates the volume contribution from the given TransformedTriangle and stores it with the given key in . + * Calls TransformedTriangle::calculateIntersectionVolume to perform the calculation. + * + * @param tri triangle for which to calculate the volume contribution + * @param key key associated with the face + */ + template<class MyMeshType> + inline void SplitterTetra<MyMeshType>::calculateVolume(TransformedTriangle& tri, const TriangleFaceKey& key) + { + const double vol = tri.calculateIntersectionVolume(); + _volumes.insert(std::make_pair(key, vol)); + } + + /** + * Calculates the surface contribution from the given TransformedTriangle and stores it with the given key in. + * Calls TransformedTriangle::calculateIntersectionSurface to perform the calculation. + * + * @param tri triangle for which to calculate the surface contribution + * @param key key associated with the face + */ + template<class MyMeshType> + inline void SplitterTetra<MyMeshType>::calculateSurface(TransformedTriangle& tri, const TriangleFaceKey& key) + { + const double surf = tri.calculateIntersectionSurface(_t); + _volumes.insert(std::make_pair(key, surf)); + } + + template<class MyMeshTypeT, class MyMeshTypeS=MyMeshTypeT> + class SplitterTetra2 + { + public: + SplitterTetra2(const MyMeshTypeT& targetMesh, const MyMeshTypeS& srcMesh, SplittingPolicy policy); + ~SplitterTetra2(); + void releaseArrays(); + void splitTargetCell2(typename MyMeshTypeT::MyConnType targetCell, typename std::vector< SplitterTetra<MyMeshTypeS>* >& tetra); + void splitTargetCell(typename MyMeshTypeT::MyConnType targetCell, typename MyMeshTypeT::MyConnType nbOfNodesT, + typename std::vector< SplitterTetra<MyMeshTypeS>* >& tetra);//to suppress + void fiveSplit(const int* const subZone, typename std::vector< SplitterTetra<MyMeshTypeS>* >& tetra);//to suppress + void sixSplit(const int* const subZone, typename std::vector< SplitterTetra<MyMeshTypeS>* >& tetra);//to suppress + void calculateGeneral24Tetra(typename std::vector< SplitterTetra<MyMeshTypeS>* >& tetra);//to suppress + void calculateGeneral48Tetra(typename std::vector< SplitterTetra<MyMeshTypeS>* >& tetra);//to suppress + void splitPyram5(typename std::vector< SplitterTetra<MyMeshTypeS>* >& tetra);//to suppress + void splitConvex(typename MyMeshTypeT::MyConnType targetCell,//to suppress + typename std::vector< SplitterTetra<MyMeshTypeS>* >& tetra);//to suppress + void calculateSubNodes(const MyMeshTypeT& targetMesh, typename MyMeshTypeT::MyConnType targetCell);//to suppress + inline const double* getCoordsOfSubNode(typename MyMeshTypeT::MyConnType node);//to suppress + inline const double* getCoordsOfSubNode2(typename MyMeshTypeT::MyConnType node, typename MyMeshTypeT::MyConnType& nodeId);//to suppress + //template<int n> + inline void calcBarycenter(int n, double* barycenter, const typename MyMeshTypeT::MyConnType* pts);//to suppress + private: + const MyMeshTypeT& _target_mesh; + const MyMeshTypeS& _src_mesh; + SplittingPolicy _splitting_pol; + /// vector of pointers to double[3] containing the coordinates of the + /// (sub) - nodes of split target cell + std::vector<const double*> _nodes; + std::vector<typename MyMeshTypeT::MyConnType> _node_ids; + }; + + /** + * Calculates the barycenter of n (sub) - nodes + * + * @param n number of nodes for which to calculate barycenter + * @param barycenter pointer to double[3] array in which to store the result + * @param pts pointer to int[n] array containing the (sub)-nodes for which to calculate the barycenter + */ + template<class MyMeshTypeT, class MyMeshTypeS> + //template<int n> + inline void SplitterTetra2<MyMeshTypeT, MyMeshTypeS>::calcBarycenter(int n, double* barycenter, const typename MyMeshTypeT::MyConnType* pts) + { + barycenter[0] = barycenter[1] = barycenter[2] = 0.0; + for(int i = 0; i < n ; ++i) + { + const double* pt = getCoordsOfSubNode(pts[i]); + barycenter[0] += pt[0]; + barycenter[1] += pt[1]; + barycenter[2] += pt[2]; + } + + barycenter[0] /= n; + barycenter[1] /= n; + barycenter[2] /= n; + } + + /** + * Accessor to the coordinates of a given (sub)-node + * + * @param node local number of the (sub)-node 0,..,7 are the elements nodes, sub-nodes are numbered from 8,.. + * @return pointer to double[3] containing the coordinates of the nodes + */ + template<class MyMeshTypeT, class MyMeshTypeS> + inline const double* SplitterTetra2<MyMeshTypeT, MyMeshTypeS>::getCoordsOfSubNode(typename MyMeshTypeT::MyConnType node) + { + // replace "at()" with [] for unsafe but faster access + return _nodes.at(node); + } + + /** + * Accessor to the coordinates of a given (sub)-node + * + * @param node local number of the (sub)-node 0,..,7 are the elements nodes, sub-nodes are numbered from 8,.. + * @param nodeId is an output that is node id in target whole mesh in C mode. + * @return pointer to double[3] containing the coordinates of the nodes + */ + template<class MyMeshTypeT, class MyMeshTypeS> + const double* SplitterTetra2<MyMeshTypeT, MyMeshTypeS>::getCoordsOfSubNode2(typename MyMeshTypeT::MyConnType node, typename MyMeshTypeT::MyConnType& nodeId) + { + const double *ret=_nodes.at(node); + if(node<8) + nodeId=_node_ids[node]; + else + nodeId=-1; + return ret; + } +} + +#endif diff --git a/src/medtool/src/INTERP_KERNEL/SplitterTetra.txx b/src/medtool/src/INTERP_KERNEL/SplitterTetra.txx new file mode 100644 index 000000000..226a6264c --- /dev/null +++ b/src/medtool/src/INTERP_KERNEL/SplitterTetra.txx @@ -0,0 +1,1319 @@ +// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 +// 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 __SPLITTERTETRA_TXX__ +#define __SPLITTERTETRA_TXX__ + +#include "SplitterTetra.hxx" + +#include "TetraAffineTransform.hxx" +#include "TransformedTriangle.hxx" +#include "MeshUtils.hxx" +#include "VectorUtils.hxx" +#include "CellModel.hxx" +#include "Log.hxx" +#include "UnitTetraIntersectionBary.hxx" +#include "VolSurfFormulae.hxx" + +#include <cmath> +#include <cassert> +#include <string> +#include <sstream> +#include <vector> + +namespace INTERP_KERNEL +{ + template<class MyMeshType> + const double SplitterTetra<MyMeshType>::SPARSE_TRUNCATION_LIMIT=1.0e-14; + + /*! + * output is expected to be allocated with 24*sizeof(void*) in order to store the 24 tetras. + * These tetras have to be deallocated. + */ + template<class MyMeshType> + void SplitterTetra<MyMeshType>::splitIntoDualCells(SplitterTetra<MyMeshType> **output) + { + double tmp[12]; + const double *tmp2[4]={tmp,tmp+3,tmp+6,tmp+9}; + typename MyMeshType::MyConnType conn[4]={-1,-1,-1,-1}; + for(int i=0;i<24;i++) + { + splitMySelfForDual(tmp,i,conn[0]); + output[i]=new SplitterTetra<MyMeshType>(_src_mesh,tmp2,conn); + } + } + + /** + * SplitterTetra class computes for a list of cell ids of a given mesh \a srcMesh (badly named) the intersection with a + * single TETRA4 cell given by \a tetraCorners (of length 4) and \a nodesId (of length 4 too). \a nodedIds is given only to establish + * if a partial computation of a triangle has already been performed (to increase performance). + * + * The \a srcMesh can contain polyhedron cells. + * + * + * Constructor creating object from the four corners of the tetrahedron. + * + * @param srcMesh mesh containing the source elements + * @param tetraCorners array of four pointers to double[3] arrays containing the coordinates of the + * corners of the tetrahedron + */ + template<class MyMeshType> + SplitterTetra<MyMeshType>::SplitterTetra(const MyMeshType& srcMesh, const double** tetraCorners, const typename MyMeshType::MyConnType *nodesId) + : _t(0), _src_mesh(srcMesh) + { + std::copy(nodesId,nodesId+4,_conn); + _coords[0]=tetraCorners[0][0]; _coords[1]=tetraCorners[0][1]; _coords[2]=tetraCorners[0][2]; + _coords[3]=tetraCorners[1][0]; _coords[4]=tetraCorners[1][1]; _coords[5]=tetraCorners[1][2]; + _coords[6]=tetraCorners[2][0]; _coords[7]=tetraCorners[2][1]; _coords[8]=tetraCorners[2][2]; + _coords[9]=tetraCorners[3][0]; _coords[10]=tetraCorners[3][1]; _coords[11]=tetraCorners[3][2]; + // create the affine transform + _t=new TetraAffineTransform(_coords); + } + + /** + * SplitterTetra class computes for a list of cell ids of a given mesh \a srcMesh (badly named) the intersection with a + * single TETRA4 cell given by \a tetraCorners (of length 4) and \a nodesId (of length 4 too). \a nodedIds is given only to establish + * if a partial computation of a triangle has already been performed (to increase performance). + * + * The \a srcMesh can contain polyhedron cells. + * + * + * Constructor creating object from the four corners of the tetrahedron. + * + * \param [in] srcMesh mesh containing the source elements + * \param [in] tetraCorners array 4*3 doubles containing corners of input tetrahedron (P0X,P0Y,P0Y,P1X,P1Y,P1Z,P2X,P2Y,P2Z,P3X,P3Y,P3Z). + */ + template<class MyMeshType> + SplitterTetra<MyMeshType>::SplitterTetra(const MyMeshType& srcMesh, const double tetraCorners[12], const int *conn): _t(0),_src_mesh(srcMesh) + { + if(!conn) + { _conn[0]=0; _conn[1]=1; _conn[2]=2; _conn[3]=3; } + else + { _conn[0]=conn[0]; _conn[1]=conn[1]; _conn[2]=conn[2]; _conn[3]=conn[3]; } + _coords[0]=tetraCorners[0]; _coords[1]=tetraCorners[1]; _coords[2]=tetraCorners[2]; _coords[3]=tetraCorners[3]; _coords[4]=tetraCorners[4]; _coords[5]=tetraCorners[5]; + _coords[6]=tetraCorners[6]; _coords[7]=tetraCorners[7]; _coords[8]=tetraCorners[8]; _coords[9]=tetraCorners[9]; _coords[10]=tetraCorners[10]; _coords[11]=tetraCorners[11]; + // create the affine transform + _t=new TetraAffineTransform(_coords); + } + + /** + * Destructor + * + * Deletes _t and the coordinates (double[3] vectors) in _nodes + * + */ + template<class MyMeshType> + SplitterTetra<MyMeshType>::~SplitterTetra() + { + delete _t; + for(HashMap< int, double* >::iterator iter = _nodes.begin(); iter != _nodes.end() ; ++iter) + delete[] iter->second; + } + + /*! + * \Forget already calculated triangles, which is crucial for calculation of barycenter of intersection + */ + template<class MyMeshType> + void SplitterTetra<MyMeshType>::clearVolumesCache() + { + _volumes.clear(); + } + + /*! + * This method destroys the 4 pointers pointed by tetraCorners[0],tetraCorners[1],tetraCorners[2] and tetraCorners[3] + * @param i is in 0..23 included. + * @param output is expected to be sized of 12 in order to. + */ + template<class MyMeshType> + void SplitterTetra<MyMeshType>::splitMySelfForDual(double* output, int i, typename MyMeshType::MyConnType& nodeId) + { + double *tmp[4]; + int offset=i/6; + nodeId=_conn[offset]; + tmp[0]=_coords+3*offset; tmp[1]=_coords+((offset+1)%4)*3; tmp[2]=_coords+((offset+2)%4)*3; tmp[3]=_coords+((offset+3)%4)*3; + int caseToTreat=i%6; + int case1=caseToTreat/2; + int case2=caseToTreat%2; + const int tab[3][2]={{1,2},{3,2},{1,3}}; + const int *curTab=tab[case1]; + double pt0[3]; pt0[0]=(tmp[curTab[case2]][0]+tmp[0][0])/2.; pt0[1]=(tmp[curTab[case2]][1]+tmp[0][1])/2.; pt0[2]=(tmp[curTab[case2]][2]+tmp[0][2])/2.; + double pt1[3]; pt1[0]=(tmp[0][0]+tmp[curTab[0]][0]+tmp[curTab[1]][0])/3.; pt1[1]=(tmp[0][1]+tmp[curTab[0]][1]+tmp[curTab[1]][1])/3.; pt1[2]=(tmp[0][2]+tmp[curTab[0]][2]+tmp[curTab[1]][2])/3.; + double pt2[3]; pt2[0]=(tmp[0][0]+tmp[1][0]+tmp[2][0]+tmp[3][0])/4.; pt2[1]=(tmp[0][1]+tmp[1][1]+tmp[2][1]+tmp[3][1])/4.; pt2[2]=(tmp[0][2]+tmp[1][2]+tmp[2][2]+tmp[3][2])/4.; + std::copy(pt1,pt1+3,output+case2*3); + std::copy(pt0,pt0+3,output+(abs(case2-1))*3); + std::copy(pt2,pt2+3,output+2*3); + std::copy(tmp[0],tmp[0]+3,output+3*3); + } + + /** + * Calculates the volume of intersection of an element in the source mesh and the target element. + * It first calculates the transformation that takes the target tetrahedron into the unit tetrahedron. After that, the + * faces of the source element are triangulated and the calculated transformation is applied + * to each triangle. The algorithm of Grandy, implemented in INTERP_KERNEL::TransformedTriangle is used + * to calculate the contribution to the volume from each triangle. The volume returned is the sum of these contributions + * divided by the determinant of the transformation. + * + * The class will cache the intermediary calculations of transformed nodes of source cells and volumes associated + * with triangulated faces to avoid having to recalculate these. + * + * @param element global number of the source element in C mode. + */ + template<class MyMeshType> + double SplitterTetra<MyMeshType>::intersectSourceCell(typename MyMeshType::MyConnType element, + double* baryCentre) + { + typedef typename MyMeshType::MyConnType ConnType; + const NumberingPolicy numPol=MyMeshType::My_numPol; + //{ could be done on outside? + // check if we have planar tetra element + if(_t->determinant() == 0.0) + { + // tetra is planar + LOG(2, "Planar tetra -- volume 0"); + return 0.0; + } + + // get type of cell + NormalizedCellType normCellType=_src_mesh.getTypeOfElement(OTT<ConnType,numPol>::indFC(element)); + const CellModel& cellModelCell=CellModel::GetCellModel(normCellType); + unsigned nbOfNodes4Type=cellModelCell.isDynamic() ? _src_mesh.getNumberOfNodesOfElement(OTT<ConnType,numPol>::indFC(element)) : cellModelCell.getNumberOfNodes(); + // halfspace filtering + bool isOutside[8] = {true, true, true, true, true, true, true, true}; + bool isTargetOutside = false; + + // calculate the coordinates of the nodes + int *cellNodes=new int[nbOfNodes4Type]; + for(int i = 0;i<(int)nbOfNodes4Type;++i) + { + // we could store mapping local -> global numbers too, but not sure it is worth it + const int globalNodeNum = getGlobalNumberOfNode(i, OTT<ConnType,numPol>::indFC(element), _src_mesh); + cellNodes[i]=globalNodeNum; + if(_nodes.find(globalNodeNum) == _nodes.end()) + { + //for(HashMap< int , double* >::iterator iter3=_nodes.begin();iter3!=_nodes.end();iter3++) + // std::cout << (*iter3).first << " "; + //std::cout << std::endl << "*** " << globalNodeNum << std::endl; + calculateNode(globalNodeNum); + } + CheckIsOutside(_nodes[globalNodeNum], isOutside); + } + + // halfspace filtering check + // NB : might not be beneficial for caching of triangles + for(int i = 0; i < 8; ++i) + { + if(isOutside[i]) + { + isTargetOutside = true; + } + } + + double totalVolume = 0.0; + + if(!isTargetOutside) + { + /// calculator of intersection barycentre + UnitTetraIntersectionBary baryCalculator( _t->determinant() < 0.); + + // get nb of sons of a cell + const ConnType* rawCellConn = _src_mesh.getConnectivityPtr() + OTT<ConnType,numPol>::conn2C( _src_mesh.getConnectivityIndexPtr()[ element ]); + const int rawNbCellNodes = _src_mesh.getConnectivityIndexPtr()[ element+1 ] - _src_mesh.getConnectivityIndexPtr()[ element ]; + unsigned nbOfSons = cellModelCell.getNumberOfSons2(rawCellConn, rawNbCellNodes); + + for(unsigned ii = 0 ; ii < nbOfSons; ++ii) + { + // get sons connectivity + NormalizedCellType faceType; + int *faceNodes, nbFaceNodes=-1; + if ( cellModelCell.isDynamic() ) + { + faceNodes=new int[nbOfNodes4Type]; + nbFaceNodes = cellModelCell.fillSonCellNodalConnectivity2(ii,rawCellConn,rawNbCellNodes,faceNodes,faceType); + for ( int i = 0; i < nbFaceNodes; ++i ) + faceNodes[i] = OTT<ConnType,numPol>::coo2C(faceNodes[i]); + } + else + { + faceType = cellModelCell.getSonType(ii); + const CellModel& faceModel=CellModel::GetCellModel(faceType); + assert(faceModel.getDimension() == 2); + faceNodes=new int[faceModel.getNumberOfNodes()]; + cellModelCell.fillSonCellNodalConnectivity(ii,cellNodes,faceNodes); + } + // intersect a son with the unit tetra + switch(faceType) + { + case NORM_TRI3: + { + // create the face key + TriangleFaceKey key = TriangleFaceKey(faceNodes[0], faceNodes[1], faceNodes[2]); + + // calculate the triangle if needed + if(_volumes.find(key) == _volumes.end()) + { + TransformedTriangle tri(_nodes[faceNodes[0]], _nodes[faceNodes[1]], _nodes[faceNodes[2]]); + calculateVolume(tri, key); + totalVolume += _volumes[key]; + if ( baryCentre ) + baryCalculator.addSide( tri ); + } else { + // count negative as face has reversed orientation + totalVolume -= _volumes[key]; + } + } + break; + + case NORM_QUAD4: + + // simple triangulation of faces along a diagonal : + // + // 2 ------ 3 + // | / | + // | / | + // | / | + // | / | + // | / | + // | / | + // 1 ------ 4 + // + //? not sure if this always works + { + // calculate the triangles if needed + + // local nodes 1, 2, 3 + TriangleFaceKey key1 = TriangleFaceKey(faceNodes[0], faceNodes[1], faceNodes[2]); + if(_volumes.find(key1) == _volumes.end()) + { + TransformedTriangle tri(_nodes[faceNodes[0]], _nodes[faceNodes[1]], _nodes[faceNodes[2]]); + calculateVolume(tri, key1); + totalVolume += _volumes[key1]; + } else { + // count negative as face has reversed orientation + totalVolume -= _volumes[key1]; + } + + // local nodes 1, 3, 4 + TriangleFaceKey key2 = TriangleFaceKey(faceNodes[0], faceNodes[2], faceNodes[3]); + if(_volumes.find(key2) == _volumes.end()) + { + TransformedTriangle tri(_nodes[faceNodes[0]], _nodes[faceNodes[2]], _nodes[faceNodes[3]]); + calculateVolume(tri, key2); + totalVolume += _volumes[key2]; + } + else + { + // count negative as face has reversed orientation + totalVolume -= _volumes[key2]; + } + } + break; + + case NORM_POLYGON: + { + int nbTria = nbFaceNodes - 2; // split polygon into nbTria triangles + for ( int iTri = 0; iTri < nbTria; ++iTri ) + { + TriangleFaceKey key = TriangleFaceKey(faceNodes[0], faceNodes[1+iTri], faceNodes[2+iTri]); + if(_volumes.find(key) == _volumes.end()) + { + TransformedTriangle tri(_nodes[faceNodes[0]], _nodes[faceNodes[1+iTri]], _nodes[faceNodes[2+iTri]]); + calculateVolume(tri, key); + totalVolume += _volumes[key]; + } + else + { + totalVolume -= _volumes[key]; + } + } + } + break; + + default: + std::cout << "+++ Error : Only elements with triangular and quadratilateral faces are supported at the moment." << std::endl; + assert(false); + } + delete [] faceNodes; + } + + if ( baryCentre ) { + baryCalculator.getBary( baryCentre ); + _t->reverseApply( baryCentre, baryCentre ); + } + } + delete [] cellNodes; + // reset if it is very small to keep the matrix sparse + // is this a good idea? + if(epsilonEqual(totalVolume, 0.0, SPARSE_TRUNCATION_LIMIT)) + { + totalVolume = 0.0; + } + + LOG(2, "Volume = " << totalVolume << ", det= " << _t->determinant()); + + // NB : fault in article, Grandy, [8] : it is the determinant of the inverse transformation + // that should be used (which is equivalent to dividing by the determinant) + return std::fabs(1.0 / _t->determinant() * totalVolume) ; + } + + /** + * Calculates the intersection surface of two coplanar triangles. + * + * @param palneNormal normal of the plane for the first triangle + * @param planeConstant constant of the equation of the plane for the first triangle + * @param p1 coordinates of the first node of the first triangle + * @param p2 coordinates of the second node of the first triangle + * @param p3 coordinates of the third node of the first triangle + * @param p4 coordinates of the first node of the second triangle + * @param p5 coordinates of the second node of the second triangle + * @param p6 coordinates of the third node of the second triangle + * @param dimCaracteristic characteristic size of the meshes containing the triangles + * @param precision precision for double float data used for comparison + */ + template<class MyMeshType> + double SplitterTetra<MyMeshType>::CalculateIntersectionSurfaceOfCoplanarTriangles(const double *const planeNormal, + const double planeConstant, + const double *const p1, const double *const p2, const double *const p3, + const double *const p4, const double *const p5, const double *const p6, + const double dimCaracteristic, const double precision) + { + typedef typename MyMeshType::MyConnType ConnType; + typedef double Vect2[2]; + typedef double Triangle2[3][2]; + + const double *const tri0[3] = {p1, p2, p3}; + const double *const tri1[3] = {p4, p5, p6}; + + // Plane of the first triangle defined by the normal of the triangle and the constant + // Project triangles onto coordinate plane most aligned with plane normal + int maxNormal = 0; + double fmax = std::abs(planeNormal[0]); + double absMax = std::abs(planeNormal[1]); + if (absMax > fmax) + { + maxNormal = 1; + fmax = absMax; + } + absMax = std::abs(planeNormal[2]); + if (absMax > fmax) + { + maxNormal = 2; + } + + Triangle2 projTri0, projTri1; + int i; + + if (maxNormal == 0) + { + // Project onto yz-plane. + for (i = 0; i < 3; ++i) + { + projTri0[i][0] = tri0[i][1]; + projTri0[i][1] = tri0[i][2]; + projTri1[i][0] = tri1[i][1]; + projTri1[i][1] = tri1[i][2]; + } + } + else if (maxNormal == 1) + { + // Project onto xz-plane. + for (i = 0; i < 3; ++i) + { + projTri0[i][0] = tri0[i][0]; + projTri0[i][1] = tri0[i][2]; + projTri1[i][0] = tri1[i][0]; + projTri1[i][1] = tri1[i][2]; + } + } + else + { + // Project onto xy-plane. + for (i = 0; i < 3; ++i) + { + projTri0[i][0] = tri0[i][0]; + projTri0[i][1] = tri0[i][1]; + projTri1[i][0] = tri1[i][0]; + projTri1[i][1] = tri1[i][1]; + } + } + + // 2D triangle intersection routines require counterclockwise ordering. + Vect2 save; + Vect2 edge0; + Vect2 edge1; + for (int ii = 0; ii < 2; ++ii) + { + edge0[ii] = projTri0[1][ii] - projTri0[0][ii]; + edge1[ii] = projTri0[2][ii] - projTri0[0][ii]; + } + if ((edge0[0] * edge1[1] - edge0[1] * edge1[0]) < (double) 0.) + { + // Triangle is clockwise, reorder it. + for (int ii = 0; ii < 2; ++ii) + { + save[ii] = projTri0[1][ii]; + projTri0[1][ii] = projTri0[2][ii]; + projTri0[2][ii] = save[ii]; + } + } + + for (int ii = 0; ii < 2; ++ii) + { + edge0[ii] = projTri1[1][ii] - projTri1[0][ii]; + edge1[ii] = projTri1[2][ii] - projTri1[0][ii]; + } + if ((edge0[0] * edge1[1] - edge0[1] * edge1[0]) < (double) 0.) + { + // Triangle is clockwise, reorder it. + for (int ii = 0; ii < 2; ++ii) + { + save[ii] = projTri1[1][ii]; + projTri1[1][ii] = projTri1[2][ii]; + projTri1[2][ii] = save[ii]; + } + } + + std::vector<double> inter2; + intersec_de_triangle(projTri0[0], projTri0[1], projTri0[2], + projTri1[0], projTri1[1], projTri1[2], + inter2, + dimCaracteristic, precision); + ConnType nb_inter=((ConnType)inter2.size())/2; + double surface = 0.; + if(nb_inter >3) inter2=reconstruct_polygon(inter2); + if (nb_inter > 0) + { + std::vector<double> inter3; + inter3.resize(3 * nb_inter); + // Map 2D intersections back to the 3D triangle space. + if (maxNormal == 0) + { + double invNX = ((double) 1.) / planeNormal[0]; + for (i = 0; i < nb_inter; i++) + { + inter3[3 * i + 1] = inter2[2 * i]; + inter3[3 * i + 2] = inter2[2 * i + 1]; + inter3[3 * i] = invNX * (planeConstant - planeNormal[1] * inter3[3 * i + 1] - planeNormal[2] * inter3[3 * i + 2]); + } + } + else if (maxNormal == 1) + { + double invNY = ((double) 1.) / planeNormal[1]; + for (i = 0; i < nb_inter; i++) + { + inter3[3 * i] = inter2[2 * i]; + inter3[3 * i + 2] = inter2[2 * i + 1]; + inter3[3 * i + 1] = invNY * (planeConstant - planeNormal[0] * inter3[3 * i] - planeNormal[2] * inter3[3 * i + 2]); + } + } + else + { + double invNZ = ((double) 1.) / planeNormal[2]; + for (i = 0; i < nb_inter; i++) + { + inter3[3 * i] = inter2[2 * i]; + inter3[3 * i + 1] = inter2[2 * i + 1]; + inter3[3 * i + 2] = invNZ * (planeConstant - planeNormal[0] * inter3[3 * i] - planeNormal[1] * inter3[3 * i + 1]); + } + } + surface = polygon_area<3>(inter3); + } + return surface; + } + + /** + * Determine if a face is coplanar with a triangle. + * The first face is characterized by the equation of her plane + * + * @param palneNormal normal of the plane for the first triangle + * @param planeConstant constant of the equation of the plane for the first triangle + * @param coordsFace coordinates of the triangle face + * @param precision precision for double float data used for comparison + */ + template<class MyMeshType> + bool SplitterTetra<MyMeshType>::IsFacesCoplanar(const double *const planeNormal, + const double planeConstant, + const double *const *const coordsFace, + const double precision) + { + // Compute the signed distances of triangle vertices to the plane. Use an epsilon-thick plane test. + // For faces not left + int counter = 0; + for (int i = 0; i < 3; ++i) + { + const double distance = dot(planeNormal, coordsFace[i]) - planeConstant; + if (epsilonEqual(distance, precision)) + { + counter++; + } + } + return counter == 3; + } + + /** + * Calculates the surface of intersection of a polygon face in the source mesh and a cell of the target mesh. + * It first calculates the transformation that takes the target tetrahedron into the unit tetrahedron. After that, the + * faces of the source element are triangulated and the calculated transformation is applied + * to each triangle. + * The algorithm is based on the algorithm of Grandy used in intersectSourceCell to compute + * the volume of intersection of two cell elements. + * The case with a source face colinear to one of the face of tetrahedrons is taking into account: + * the contribution of the face must not be counted two times. + * + * The class will cache the intermediary calculations of transformed nodes of source faces and surfaces associated + * with triangulated faces to avoid having to recalculate these. + * + * @param polyType type of the polygon source face + * @param polyNodesNbr number of the nodes of the polygon source face + * @param polyNodes numbers of the nodes of the polygon source face + * @param polyCoords coordinates of the nodes of the polygon source face + * @param dimCaracteristic characteristic size of the meshes containing the triangles + * @param precision precision for double float data used for comparison + * @param listOfTetraFacesTreated list of tetra faces treated + * @param listOfTetraFacesColinear list of tetra faces colinear with the polygon source faces + */ + template<class MyMeshType> + double SplitterTetra<MyMeshType>::intersectSourceFace(const NormalizedCellType polyType, + const int polyNodesNbr, + const int *const polyNodes, + const double *const *const polyCoords, + const double dimCaracteristic, + const double precision, + std::multiset<TriangleFaceKey>& listOfTetraFacesTreated, + std::set<TriangleFaceKey>& listOfTetraFacesColinear) + { + double totalSurface = 0.0; + + // check if we have planar tetra element + if(_t->determinant() == 0.0) + { + // tetra is planar + LOG(2, "Planar tetra -- volume 0"); + return 0.0; + } + + // halfspace filtering + bool isOutside[8] = {true, true, true, true, true, true, true, true}; + bool isStrictlyOutside[8] = {true, true, true, true, true, true, true, true}; + bool isTargetStrictlyOutside = false; + bool isTargetOutside = false; + + // calculate the coordinates of the nodes + for(int i = 0;i<(int)polyNodesNbr;++i) + { + const int globalNodeNum = polyNodes[i]; + if(_nodes.find(globalNodeNum) == _nodes.end()) + { + calculateNode2(globalNodeNum, polyCoords[i]); + } + + CheckIsStrictlyOutside(_nodes[globalNodeNum], isStrictlyOutside, precision); + CheckIsOutside(_nodes[globalNodeNum], isOutside, precision); + } + + // halfspace filtering check + // NB : might not be beneficial for caching of triangles + for(int i = 0; i < 8; ++i) + { + if(isStrictlyOutside[i]) + { + isTargetStrictlyOutside = true; + break; + } + else if (isOutside[i]) + { + isTargetOutside = true; + } + } + + if (!isTargetStrictlyOutside) + { + + if (isTargetOutside) + { + // Faces are parallel + const int tetraFacesNodesConn[4][3] = { + { 0, 1, 2 }, + { 0, 2, 3 }, + { 0, 3, 1 }, + { 1, 2, 3 } }; + double planeNormal[3]; + for (int iTetraFace = 0; iTetraFace < 4; ++iTetraFace) + { + const int * const tetraFaceNodesConn = tetraFacesNodesConn[iTetraFace]; + TriangleFaceKey key = TriangleFaceKey(_conn[tetraFaceNodesConn[0]], + _conn[tetraFaceNodesConn[1]], + _conn[tetraFaceNodesConn[2]]); + if (listOfTetraFacesTreated.find(key) == listOfTetraFacesTreated.end()) + { + const double * const coordsTetraTriNode1 = _coords + tetraFaceNodesConn[0] * MyMeshType::MY_SPACEDIM; + const double * const coordsTetraTriNode2 = _coords + tetraFaceNodesConn[1] * MyMeshType::MY_SPACEDIM; + const double * const coordsTetraTriNode3 = _coords + tetraFaceNodesConn[2] * MyMeshType::MY_SPACEDIM; + calculateNormalForTria(coordsTetraTriNode1, coordsTetraTriNode2, coordsTetraTriNode3, planeNormal); + const double normOfTetraTriNormal = norm(planeNormal); + if (epsilonEqual(normOfTetraTriNormal, 0.)) + { + for (int i = 0; i < 3; ++i) + { + planeNormal[i] = 0.; + } + } + else + { + const double invNormOfTetraTriNormal = 1. / normOfTetraTriNormal; + for (int i = 0; i < 3; ++i) + { + planeNormal[i] *= invNormOfTetraTriNormal; + } + } + double planeConstant = dot(planeNormal, coordsTetraTriNode1); + if (IsFacesCoplanar(planeNormal, planeConstant, polyCoords, precision)) + { + int nbrPolyTri = polyNodesNbr - 2; // split polygon into nbrPolyTri triangles + for (int iTri = 0; iTri < nbrPolyTri; ++iTri) + { + double volume = CalculateIntersectionSurfaceOfCoplanarTriangles(planeNormal, + planeConstant, + polyCoords[0], + polyCoords[1 + iTri], + polyCoords[2 + iTri], + coordsTetraTriNode1, + coordsTetraTriNode2, + coordsTetraTriNode3, + dimCaracteristic, + precision); + if (!epsilonEqual(volume, 0.)) + { + totalSurface += volume; + listOfTetraFacesColinear.insert(key); + } + } + } + } + listOfTetraFacesTreated.insert(key); + } + } + else + { + // intersect a son with the unit tetra + switch (polyType) + { + case NORM_TRI3: + { + // create the face key + TriangleFaceKey key = TriangleFaceKey(polyNodes[0], polyNodes[1], polyNodes[2]); + + // calculate the triangle if needed + if (_volumes.find(key) == _volumes.end()) + { + TransformedTriangle tri(_nodes[polyNodes[0]], _nodes[polyNodes[1]], _nodes[polyNodes[2]]); + calculateSurface(tri, key); + totalSurface += _volumes[key]; + } + else + { + // count negative as face has reversed orientation + totalSurface -= _volumes[key]; + } + } + break; + + case NORM_QUAD4: + + // simple triangulation of faces along a diagonal : + // + // 2 ------ 3 + // | / | + // | / | + // | / | + // | / | + // | / | + // | / | + // 1 ------ 4 + // + //? not sure if this always works + { + // calculate the triangles if needed + + // local nodes 1, 2, 3 + TriangleFaceKey key1 = TriangleFaceKey(polyNodes[0], polyNodes[1], polyNodes[2]); + if (_volumes.find(key1) == _volumes.end()) + { + TransformedTriangle tri(_nodes[polyNodes[0]], _nodes[polyNodes[1]], _nodes[polyNodes[2]]); + calculateSurface(tri, key1); + totalSurface += _volumes[key1]; + } + else + { + // count negative as face has reversed orientation + totalSurface -= _volumes[key1]; + } + + // local nodes 1, 3, 4 + TriangleFaceKey key2 = TriangleFaceKey(polyNodes[0], polyNodes[2], polyNodes[3]); + if (_volumes.find(key2) == _volumes.end()) + { + TransformedTriangle tri(_nodes[polyNodes[0]], _nodes[polyNodes[2]], _nodes[polyNodes[3]]); + calculateSurface(tri, key2); + totalSurface += _volumes[key2]; + } + else + { + // count negative as face has reversed orientation + totalSurface -= _volumes[key2]; + } + } + break; + + case NORM_POLYGON: + { + int nbrPolyTri = polyNodesNbr - 2; // split polygon into nbrPolyTri triangles + for (int iTri = 0; iTri < nbrPolyTri; ++iTri) + { + TriangleFaceKey key = TriangleFaceKey(polyNodes[0], polyNodes[1 + iTri], polyNodes[2 + iTri]); + if (_volumes.find(key) == _volumes.end()) + { + TransformedTriangle tri(_nodes[polyNodes[0]], _nodes[polyNodes[1 + iTri]], + _nodes[polyNodes[2 + iTri]]); + calculateSurface(tri, key); + totalSurface += _volumes[key]; + } + else + { + totalSurface -= _volumes[key]; + } + } + } + break; + + default: + std::cout + << "+++ Error : Only elements with triangular and quadratilateral faces are supported at the moment." + << std::endl; + assert(false); + } + + } + } + + // reset if it is very small to keep the matrix sparse + // is this a good idea? + if(epsilonEqual(totalSurface, 0.0, SPARSE_TRUNCATION_LIMIT)) + { + totalSurface = 0.0; + } + + LOG(2, "Volume = " << totalSurface << ", det= " << _t->determinant()); + + return totalSurface; + } + + /** + * Calculates the volume of intersection of this tetrahedron with another one. + */ + template<class MyMeshType> + double SplitterTetra<MyMeshType>::intersectTetra(const double** tetraCorners) + { + //{ could be done on outside? + // check if we have planar tetra element + if(_t->determinant() == 0.0) + { + // tetra is planar + LOG(2, "Planar tetra -- volume 0"); + return 0.0; + } + + const unsigned nbOfNodes4Type=4; + // halfspace filtering + bool isOutside[8] = {true, true, true, true, true, true, true, true}; + bool isTargetOutside = false; + + // calculate the transformed coordinates of the nodes + double nodes[nbOfNodes4Type][3]; + for(int i = 0;i<(int)nbOfNodes4Type;++i) + { + _t->apply(nodes[i], tetraCorners[i]); + CheckIsOutside(nodes[i], isOutside); + } + + // halfspace filtering check + // NB : might not be beneficial for caching of triangles + for(int i = 0; i < 8; ++i) + { + if(isOutside[i]) + { + isTargetOutside = true; + } + } + + double totalVolume = 0.0; + + if(!isTargetOutside) + { + const CellModel& cellModelCell=CellModel::GetCellModel(NORM_TETRA4); + int cellNodes[4] = { 0, 1, 2, 3 }, faceNodes[3]; + + for(unsigned ii = 0 ; ii < 4 ; ++ii) + { + cellModelCell.fillSonCellNodalConnectivity(ii,cellNodes,faceNodes); + + TransformedTriangle tri(nodes[faceNodes[0]], nodes[faceNodes[1]], nodes[faceNodes[2]]); + double vol = tri.calculateIntersectionVolume(); + totalVolume += vol; + } + + // reset if it is very small to keep the matrix sparse + // is this a good idea? + if(epsilonEqual(totalVolume, 0.0, SPARSE_TRUNCATION_LIMIT)) + { + totalVolume = 0.0; + } + } + LOG(2, "Volume = " << totalVolume << ", det= " << _t->determinant()); + + // NB : fault in article, Grandy, [8] : it is the determinant of the inverse transformation + // that should be used (which is equivalent to dividing by the determinant) + return std::fabs(1.0 / _t->determinant() * totalVolume) ; + } + + //////////////////////////////////////////////////////// + + template<class MyMeshTypeT, class MyMeshTypeS> + SplitterTetra2<MyMeshTypeT, MyMeshTypeS>::SplitterTetra2(const MyMeshTypeT& targetMesh, const MyMeshTypeS& srcMesh, SplittingPolicy policy) + :_target_mesh(targetMesh),_src_mesh(srcMesh),_splitting_pol(policy) + { + } + + template<class MyMeshTypeT, class MyMeshTypeS> + SplitterTetra2<MyMeshTypeT, MyMeshTypeS>::~SplitterTetra2() + { + releaseArrays(); + } + + template<class MyMeshTypeT, class MyMeshTypeS> + void SplitterTetra2<MyMeshTypeT, MyMeshTypeS>::releaseArrays() + { + // free potential sub-mesh nodes that have been allocated + typename MyMeshTypeT::MyConnType nbOfNodesT = _node_ids.size();// Issue 0020634. + if((int)_nodes.size()>=/*8*/nbOfNodesT) + { + std::vector<const double*>::iterator iter = _nodes.begin() + /*8*/nbOfNodesT; + while(iter != _nodes.end()) + { + delete[] *iter; + ++iter; + } + } + _nodes.clear(); + } + + /*! + * \param [in] targetCell in C mode. + * \param [out] tetra is the output result tetra containers. + */ + template<class MyMeshTypeT, class MyMeshTypeS> + void SplitterTetra2<MyMeshTypeT, MyMeshTypeS>::splitTargetCell2(typename MyMeshTypeT::MyConnType targetCell, typename std::vector< SplitterTetra<MyMeshTypeS>* >& tetra) + { + const int *refConn(_target_mesh.getConnectivityPtr()); + const int *cellConn(refConn+_target_mesh.getConnectivityIndexPtr()[targetCell]); + INTERP_KERNEL::NormalizedCellType gt(_target_mesh.getTypeOfElement(targetCell)); + std::vector<int> tetrasNodalConn; + std::vector<double> addCoords; + const double *coords(_target_mesh.getCoordinatesPtr()); + SplitIntoTetras(_splitting_pol,gt,cellConn,refConn+_target_mesh.getConnectivityIndexPtr()[targetCell+1],coords,tetrasNodalConn,addCoords); + std::size_t nbTetras(tetrasNodalConn.size()/4); tetra.resize(nbTetras); + double tmp[12]; + int tmp2[4]; + for(std::size_t i=0;i<nbTetras;i++) + { + for(int j=0;j<4;j++) + { + int cellId(tetrasNodalConn[4*i+j]); + tmp2[j]=cellId; + if(cellId>=0) + { + tmp[j*3+0]=coords[3*cellId+0]; + tmp[j*3+1]=coords[3*cellId+1]; + tmp[j*3+2]=coords[3*cellId+2]; + } + else + { + tmp[j*3+0]=addCoords[3*(-cellId-1)+0]; + tmp[j*3+1]=addCoords[3*(-cellId-1)+1]; + tmp[j*3+2]=addCoords[3*(-cellId-1)+2]; + } + } + tetra[i]=new SplitterTetra<MyMeshTypeS>(_src_mesh,tmp,tmp2); + } + } + + /*! + * @param targetCell in C mode. + * @param tetra is the output result tetra containers. + */ + template<class MyMeshTypeT, class MyMeshTypeS> + void SplitterTetra2<MyMeshTypeT, MyMeshTypeS>::splitTargetCell(typename MyMeshTypeT::MyConnType targetCell, + typename MyMeshTypeT::MyConnType nbOfNodesT, + typename std::vector< SplitterTetra<MyMeshTypeS>* >& tetra) + { + typedef typename MyMeshTypeT::MyConnType ConnType; + const NumberingPolicy numPol=MyMeshTypeT::My_numPol; + const int numTetra = static_cast<int>(_splitting_pol); + if(nbOfNodesT==4) + { + _nodes.resize(8); + _node_ids.resize(8); + tetra.reserve(1); + const double *nodes[4]; + int conn[4]; + for(int node = 0; node < 4 ; ++node) + { + nodes[node]=getCoordsOfNode2(node, OTT<ConnType,numPol>::indFC(targetCell),_target_mesh,conn[node]); + } + std::copy(conn,conn+4,_node_ids.begin()); + SplitterTetra<MyMeshTypeS>* t = new SplitterTetra<MyMeshTypeS>(_src_mesh, nodes,conn); + tetra.push_back(t); + return ; + } + // Issue 0020634. To pass nbOfNodesT to calculateSubNodes (don't want to add an arg) + _node_ids.resize(nbOfNodesT); + + // pre-calculate nodes + calculateSubNodes(_target_mesh, OTT<ConnType,numPol>::indFC(targetCell)); + + tetra.reserve(numTetra); + _nodes.reserve(30); // we never have more than this + + switch ( nbOfNodesT ) + { + case 8: + { + switch(_splitting_pol) + { + case PLANAR_FACE_5: + { + const int subZone[8] = { 0, 1, 2, 3, 4, 5, 6, 7 }; + fiveSplit(subZone,tetra); + } + break; + + case PLANAR_FACE_6: + { + const int subZone[8] = { 0, 1, 2, 3, 4, 5, 6, 7 }; + sixSplit(subZone,tetra); + } + break; + + case GENERAL_24: + { + calculateGeneral24Tetra(tetra); + } + break; + + case GENERAL_48: + { + calculateGeneral48Tetra(tetra); + } + break; + default: + assert(false); + } + break; + } + case 5: + { + splitPyram5(tetra); + break; + } + default: + { + splitConvex(targetCell, tetra); + } + } + } + + /** + * Splits the hexahedron into five tetrahedra. + * This method adds five SplitterTetra objects to the vector tetra. + * + * @param subZone the local node numbers corresponding to the hexahedron corners - these are mapped onto {0,..,7}. Providing this allows the + * splitting to be reused on the subzones of the GENERAL_* types of splitting + */ + template<class MyMeshTypeT, class MyMeshTypeS> + void SplitterTetra2<MyMeshTypeT, MyMeshTypeS>::fiveSplit(const int* const subZone, typename std::vector< SplitterTetra<MyMeshTypeS>* >& tetra) + { + // create tetrahedra + for(int i = 0; i < 5; ++i) + { + const double* nodes[4]; + int conn[4]; + for(int j = 0; j < 4; ++j) + { + conn[j] = subZone[ SPLIT_NODES_5[4*i+j] ]; + nodes[j] = getCoordsOfSubNode(conn[j]); + } + SplitterTetra<MyMeshTypeS>* t = new SplitterTetra<MyMeshTypeS>(_src_mesh, nodes,conn); + tetra.push_back(t); + } + } + + /** + * Splits the hexahedron into six tetrahedra. + * This method adds six SplitterTetra objects to the vector tetra. + * + * @param subZone the local node numbers corresponding to the hexahedron corners - these are mapped onto {0,..,7}. Providing this allows the + * splitting to be reused on the subzones of the GENERAL_* types of splitting + */ + template<class MyMeshTypeT, class MyMeshTypeS> + void SplitterTetra2<MyMeshTypeT, MyMeshTypeS>::sixSplit(const int* const subZone, typename std::vector< SplitterTetra<MyMeshTypeS>* >& tetra) + { + for(int i = 0; i < 6; ++i) + { + const double* nodes[4]; + int conn[4]; + for(int j = 0; j < 4; ++j) + { + conn[j] = subZone[SPLIT_NODES_6[4*i+j]]; + nodes[j] = getCoordsOfSubNode(conn[j]); + } + SplitterTetra<MyMeshTypeS>* t = new SplitterTetra<MyMeshTypeS>(_src_mesh, nodes,conn); + tetra.push_back(t); + } + } + + /** + * Splits the hexahedron into 24 tetrahedra. + * The splitting is done by combining the barycenter of the tetrahedron, the barycenter of each face + * and the nodes of each edge of the face. This creates 6 faces * 4 edges / face = 24 tetrahedra. + * The submesh nodes introduced are the barycenters of the faces and the barycenter of the cell. + * + */ + template<class MyMeshTypeT, class MyMeshTypeS> + void SplitterTetra2<MyMeshTypeT, MyMeshTypeS>::calculateGeneral24Tetra(typename std::vector< SplitterTetra<MyMeshTypeS>* >& tetra) + { + // 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 + + // nodes to use for tetrahedron + const double* nodes[4]; + int conn[4]; + // get the cell center + conn[0] = 14; + nodes[0] = getCoordsOfSubNode(conn[0]); + + for(int faceCenterNode = 8; faceCenterNode < 14; ++faceCenterNode) + { + // get the face center + conn[1] = faceCenterNode; + nodes[1] = getCoordsOfSubNode(conn[1]); + for(int j = 0; j < 4; ++j) + { + const int row = 4*(faceCenterNode - 8) + j; + 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]); + + SplitterTetra<MyMeshTypeS>* t = new SplitterTetra<MyMeshTypeS>(_src_mesh, nodes, conn); + tetra.push_back(t); + } + } + } + + + /** + * Splits the hexahedron into 48 tetrahedra. + * The splitting is done by introducing the midpoints of all the edges + * and the barycenter of the element as submesh nodes. The 8 hexahedral subzones thus defined + * are then split into 6 tetrahedra each, as in Grandy, p. 449. The division of the subzones + * is done by calling sixSplit(). + * + */ + template<class MyMeshTypeT, class MyMeshTypeS> + void SplitterTetra2<MyMeshTypeT, MyMeshTypeS>::calculateGeneral48Tetra(typename std::vector< SplitterTetra<MyMeshTypeS>* >& tetra) + { + for(int i = 0; i < 8; ++i) + { + sixSplit(GENERAL_48_SUBZONES+8*i,tetra); + } + } + + /** + * Splits the NORM_PYRA5 into 2 tetrahedra. + */ + template<class MyMeshTypeT, class MyMeshTypeS> + void SplitterTetra2<MyMeshTypeT, MyMeshTypeS>::splitPyram5(typename std::vector< SplitterTetra<MyMeshTypeS>* >& tetra) + { + static const int SPLIT_PYPA5[2][4] = + { + { + 0, 1, 2, 4 + }, + { + 0, 2, 3, 4 + } + }; + + // create tetrahedra + const double* nodes[4]; + int conn[4]; + for(int i = 0; i < 2; ++i) + { + for(int j = 0; j < 4; ++j) + nodes[j] = getCoordsOfSubNode2(SPLIT_PYPA5[i][j],conn[j]); + SplitterTetra<MyMeshTypeS>* t = new SplitterTetra<MyMeshTypeS>(_src_mesh, nodes,conn); + tetra.push_back(t); + } + } + + /** + * Splits a convex cell into tetrahedra. + */ + template<class MyMeshTypeT, class MyMeshTypeS> + void SplitterTetra2<MyMeshTypeT, MyMeshTypeS>::splitConvex(typename MyMeshTypeT::MyConnType targetCell, + typename std::vector< SplitterTetra<MyMeshTypeS>* >& tetra) + { + // Each face of a cell is split into triangles and + // each of triangles and a cell barycenter form a tetrahedron. + + typedef typename MyMeshTypeT::MyConnType ConnType; + const NumberingPolicy numPol=MyMeshTypeT::My_numPol; + + // get type of cell and nb of cell nodes + NormalizedCellType normCellType=_target_mesh.getTypeOfElement(OTT<ConnType,numPol>::indFC(targetCell)); + const CellModel& cellModelCell=CellModel::GetCellModel(normCellType); + unsigned nbOfCellNodes=cellModelCell.isDynamic() ? _target_mesh.getNumberOfNodesOfElement(OTT<ConnType,numPol>::indFC(targetCell)) : cellModelCell.getNumberOfNodes(); + + // get nb of cell sons (faces) + const ConnType* rawCellConn = _target_mesh.getConnectivityPtr() + OTT<ConnType,numPol>::conn2C( _target_mesh.getConnectivityIndexPtr()[ targetCell ]); + const int rawNbCellNodes = _target_mesh.getConnectivityIndexPtr()[ targetCell+1 ] - _target_mesh.getConnectivityIndexPtr()[ targetCell ]; + unsigned nbOfSons = cellModelCell.getNumberOfSons2(rawCellConn, rawNbCellNodes); + + // indices of nodes of a son + static std::vector<int> allNodeIndices; // == 0,1,2,...,nbOfCellNodes-1 + while ( allNodeIndices.size() < nbOfCellNodes ) + allNodeIndices.push_back( allNodeIndices.size() ); + std::vector<int> classicFaceNodes(4); + if(cellModelCell.isQuadratic()) + throw INTERP_KERNEL::Exception("SplitterTetra2::splitConvex : quadratic 3D cells are not implemented yet !"); + int* faceNodes = cellModelCell.isDynamic() ? &allNodeIndices[0] : &classicFaceNodes[0]; + + // nodes of tetrahedron + int conn[4]; + const double* nodes[4]; + nodes[3] = getCoordsOfSubNode2( nbOfCellNodes,conn[3]); // barycenter + + for(unsigned ii = 0 ; ii < nbOfSons; ++ii) + { + // get indices of son's nodes: it's just next portion of allNodeIndices for polyhedron + // and some of allNodeIndices accodring to cell model for a classsic cell + unsigned nbFaceNodes = cellModelCell.getNumberOfNodesConstituentTheSon2(ii, rawCellConn, rawNbCellNodes); + if ( normCellType != NORM_POLYHED ) + cellModelCell.fillSonCellNodalConnectivity(ii,&allNodeIndices[0],faceNodes); + + int nbTetra = nbFaceNodes - 2; // split polygon into nbTetra triangles + + // create tetrahedra + for(int i = 0; i < nbTetra; ++i) + { + nodes[0] = getCoordsOfSubNode2( faceNodes[0], conn[0]); + nodes[1] = getCoordsOfSubNode2( faceNodes[1+i],conn[1]); + nodes[2] = getCoordsOfSubNode2( faceNodes[2+i],conn[2]); + SplitterTetra<MyMeshTypeS>* t = new SplitterTetra<MyMeshTypeS>(_src_mesh, nodes,conn); + tetra.push_back(t); + } + + if ( normCellType == NORM_POLYHED ) + faceNodes += nbFaceNodes; // go to the next face + } + } + + /** + * Precalculates all the nodes. + * Retrieves the mesh nodes and allocates the necessary sub-mesh + * nodes according to the splitting policy used. + * This method is meant to be called once by the constructor. + * + * @param targetMesh the target mesh + * @param targetCell the global number of the cell that the object represents, in targetMesh mode. + * @param policy the splitting policy of the object + * + */ + template<class MyMeshTypeT, class MyMeshTypeS> + void SplitterTetra2<MyMeshTypeT, MyMeshTypeS>::calculateSubNodes(const MyMeshTypeT& targetMesh, typename MyMeshTypeT::MyConnType targetCell) + { + // retrieve real mesh nodes + + typename MyMeshTypeT::MyConnType nbOfNodesT = _node_ids.size();// Issue 0020634. _node_ids.resize(8); + for(int node = 0; node < nbOfNodesT ; ++node) + { + // calculate only normal nodes + _nodes.push_back(getCoordsOfNode2(node, targetCell, targetMesh,_node_ids[node])); + } + + switch ( nbOfNodesT ) + { + case 8: + + // create sub-mesh nodes if needed + switch(_splitting_pol) + { + case GENERAL_24: + { + for(int i = 0; i < 7; ++i) + { + double* barycenter = new double[3]; + calcBarycenter(4, barycenter, &GENERAL_24_SUB_NODES[4*i]); + _nodes.push_back(barycenter); + } + } + break; + + case GENERAL_48: + { + for(int i = 0; i < 19; ++i) + { + double* barycenter = new double[3]; + calcBarycenter(2, barycenter, &GENERAL_48_SUB_NODES[2*i]); + _nodes.push_back(barycenter); + } + } + break; + + default: + break; + } + + case 5: // NORM_PYRA5 + break; + + default: // convex 3d cell + { + // add barycenter of a cell + std::vector<int> allIndices(nbOfNodesT); + for ( int i = 0; i < nbOfNodesT; ++i ) allIndices[i] = i; + double* barycenter = new double[3]; + calcBarycenter(nbOfNodesT, barycenter, &allIndices[0]); + _nodes.push_back(barycenter); + } + } + + } +} + +#endif diff --git a/src/medtool/src/INTERP_KERNEL/TargetIntersector.hxx b/src/medtool/src/INTERP_KERNEL/TargetIntersector.hxx new file mode 100644 index 000000000..e79d1e747 --- /dev/null +++ b/src/medtool/src/INTERP_KERNEL/TargetIntersector.hxx @@ -0,0 +1,55 @@ +// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 +// 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 __TARGETINTERSECTOR__HXX__ +#define __TARGETINTERSECTOR__HXX__ + +#include "INTERPKERNELDefines.hxx" + +#include <vector> + +namespace INTERP_KERNEL +{ + /** + * \brief Abstract base class of Intersector classes. + * These classes represent a target element and calculate its intersection + * with the source elements. + */ + template<class MyMeshType, class MyMatrix> + class TargetIntersector + { + public: + typedef typename MyMeshType::MyConnType ConnType; + public: + /*! + * Tool for cell intersection, result is always positive. + * @param icellT id of cell in target mesh in \b C \b mode. + * @param icellsS ids of cells in source mesh in \b C \b mode. + * @param res is an IN/OUT parameter that represents the icellTth row in final matrix, fed with at most icellsS elements. + */ + virtual void intersectCells(ConnType targetCell, const std::vector<ConnType>& srcCells, MyMatrix& res) = 0; + + virtual int getNumberOfRowsOfResMatrix() const = 0; + virtual int getNumberOfColsOfResMatrix() const = 0; + virtual ~TargetIntersector() { } + }; +} + +#endif diff --git a/src/medtool/src/INTERP_KERNEL/TetraAffineTransform.cxx b/src/medtool/src/INTERP_KERNEL/TetraAffineTransform.cxx new file mode 100644 index 000000000..f01b160d6 --- /dev/null +++ b/src/medtool/src/INTERP_KERNEL/TetraAffineTransform.cxx @@ -0,0 +1,393 @@ +// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// + +#include "TetraAffineTransform.hxx" +#include "VectorUtils.hxx" + +#include <cmath> +#include <cstring> +#include <iostream> + +#include "Log.hxx" + +namespace INTERP_KERNEL +{ + ///////////////////////////////////////////////////////////////////////////////////////// + /// PUBLIC INTERFACE METHODS ////////////// + ///////////////////////////////////////////////////////////////////////////////////////// + + /** + * Constructor + * Create the TetraAffineTransform object from the tetrahedron + * with corners specified in pts. If the tetrahedron is degenerate or almost degenerate, + * construction succeeds, but the determinant of the transform is set to 0. + * + * @param pts a 4x3 matrix containing 4 points (P0X,P0Y,P0Z,P1X,P1Y,P1Z,...) of 3 coordinates each + */ + TetraAffineTransform::TetraAffineTransform(const double *pts) + { + + LOG(2,"Creating transform from tetraeder : "); + + // three last points -> linear transform + for(int i = 0; i < 3 ; ++i) + { + for(int j = 0 ; j < 3 ; ++j) + { + // NB we insert columns, not rows + _linear_transform[3*j + i] = pts[(i+1)*3+j] - pts[j]; + } + } + + // remember _linear_transform for the reverse transformation + memcpy( _back_linear_transform, _linear_transform, 9*sizeof(double)); + memcpy( _back_translation, pts, 3*sizeof(double)); + + calculateDeterminant(); + + LOG(3, "determinant before inverse = " << _determinant); + + // check that tetra is non-planar -> determinant is not zero + // otherwise set _determinant to zero to signal caller that transformation did not work + if(epsilonEqual(_determinant, 0.0)) + { + _determinant = 0.0; + return; + } + + // we need the inverse transform + invertLinearTransform(); + + // first point -> translation + // calculate here because translation takes place in "transformed space", + // or in other words b = -A*O where A is the linear transform + // and O is the position vector of the point that is mapped onto the origin + for(int i = 0 ; i < 3 ; ++i) + { + _translation[i] = -(_linear_transform[3*i]*pts[0] + _linear_transform[3*i+1]*pts[1] + _linear_transform[3*i+2]*pts[2]) ; + } + + // precalculate determinant (again after inversion of transform) + calculateDeterminant(); + +#ifdef INVERSION_SELF_CHECK + // debugging : check that applying the inversed transform to the original points + // gives us the unit tetrahedron + LOG(4, "transform determinant is " << _determinant); + LOG(4, "*Self-check : Applying transformation to original points ... "); + for(int i = 0; i < 4 ; ++i) + { + double v[3]; + apply(v, pts+3*i); + LOG(4, vToStr(v)) + for(int j = 0; j < 3; ++j) + { + assert(epsilonEqual(v[j], (3*i+j == 3 || 3*i+j == 7 || 3*i+j == 11 ) ? 1.0 : 0.0)); + } + } + + LOG(4, " ok"); +#endif + } + + /** + * Calculates the transform of point srcPt and stores the result in destPt. + * If destPt == srcPt, then srcPt is overwritten safely. + * + * + * @param destPt double[3] in which to store the transformed point + * @param srcPt double[3] containing coordinates of points to be transformed + * + */ + void TetraAffineTransform::apply(double* destPt, const double* srcPt) const + { + double* dest = destPt; + + // are we self-allocating ? + const bool selfAllocation = (destPt == srcPt); + + if(selfAllocation) + { + // alloc temporary memory + dest = new double[3]; + + LOG(6, "Info : Self-affectation in TetraAffineTransform::apply"); + } + + for(int i = 0 ; i < 3 ; ++i) + { + // matrix - vector multiplication + dest[i] = _linear_transform[3*i] * srcPt[0] + _linear_transform[3*i + 1] * srcPt[1] + _linear_transform[3*i + 2] * srcPt[2]; + + // translation + dest[i] += _translation[i]; + } + + if(selfAllocation) + { + // copy result back to destPt + for(int i = 0 ; i < 3 ; ++i) + { + destPt[i] = dest[i]; + } + delete[] dest; + } + } + + /** + * Calculates the reverse transform of point srcPt and stores the result in destPt. + * If destPt == srcPt, then srcPt is overwritten safely. + * + * @param destPt double[3] in which to store the transformed point + * @param srcPt double[3] containing coordinates of points to be transformed + */ + void TetraAffineTransform::reverseApply(double* destPt, const double* srcPt) const + { + double* dest = destPt; + + // are we self-allocating ? + const bool selfAllocation = (destPt == srcPt); + + if(selfAllocation) + { + // alloc temporary memory + dest = new double[3]; + + LOG(6, "Info : Self-affectation in TetraAffineTransform::reverseApply"); + } + + for(int i = 0 ; i < 3 ; ++i) + { + // matrix - vector multiplication + dest[i] = _back_linear_transform[3*i] * srcPt[0] + _back_linear_transform[3*i + 1] * srcPt[1] + _back_linear_transform[3*i + 2] * srcPt[2]; + + // translation + dest[i] += _back_translation[i]; + } + + if(selfAllocation) + { + // copy result back to destPt + for(int i = 0 ; i < 3 ; ++i) + { + destPt[i] = dest[i]; + } + delete[] dest; + } + } + + /** + * Returns the determinant of the linear part A of the transform. + * + * @return determinant of the transform + * + */ + double TetraAffineTransform::determinant() const + { + return _determinant; + } + + /** + * Outputs to std::cout the matrix A and the vector b + * of the transform Ax + b + * + */ + void TetraAffineTransform::dump() const + { + std::cout << "A = " << std::endl << "["; + for(int i = 0; i < 3; ++i) + { + std::cout << _linear_transform[3*i] << ", " << _linear_transform[3*i + 1] << ", " << _linear_transform[3*i + 2]; + if(i != 2 ) std::cout << std::endl; + } + std::cout << "]" << std::endl; + + std::cout << "b = " << "[" << _translation[0] << ", " << _translation[1] << ", " << _translation[2] << "]" << std::endl; + } + + ///////////////////////////////////////////////////////////////////////////////////////// + /// PRIVATE METHODS ////////////// + ///////////////////////////////////////////////////////////////////////////////////////// + + /** + * Calculates the inverse of the matrix A, stored in _linear_transform + * by LU-factorization and substitution + * + */ + void TetraAffineTransform::invertLinearTransform() + { + //{ we copy the matrix for the lu-factorization + // maybe inefficient + double lu[9]; + for(int i = 0 ; i < 9; ++i) + { + lu[i] = _linear_transform[i]; + } + + // calculate LU factorization + int idx[3]; + factorizeLU(lu, idx); + + // calculate inverse by forward and backward substitution + // store in _linear_transform + // NB _linear_transform cannot be overwritten with lu in the loop + for(int i = 0 ; i < 3 ; ++i) + { + // form standard base vector i + const double b[3] = + { + double ( int(i == 0) ), + double ( int(i == 1) ), + double ( int(i == 2) ), + }; + + LOG(6, "b = [" << b[0] << ", " << b[1] << ", " << b[2] << "]"); + + double y[3]; + forwardSubstitution(y, lu, b, idx); + + double x[3]; + backwardSubstitution(x, lu, y, idx); + + // copy to _linear_transform matrix + // NB : this is a column operation, so we cannot + // do this directly when we calculate x + for(int j = 0 ; j < 3 ; j++) + { + _linear_transform[3*j + i] = x[idx[j]]; + } + } + } + + /** + * Updates the member _determinant of the matrix A of the transformation. + * + */ + void TetraAffineTransform::calculateDeterminant() + { + const double subDet[3] = + { + _linear_transform[4] * _linear_transform[8] - _linear_transform[5] * _linear_transform[7], + _linear_transform[3] * _linear_transform[8] - _linear_transform[5] * _linear_transform[6], + _linear_transform[3] * _linear_transform[7] - _linear_transform[4] * _linear_transform[6] + }; + + _determinant = _linear_transform[0] * subDet[0] - _linear_transform[1] * subDet[1] + _linear_transform[2] * subDet[2]; + } + + + ///////////////////////////////////////////////// + /// Auxiliary methods for inverse calculation /// + ///////////////////////////////////////////////// + + + /** + * Calculates the LU-factorization of the matrix A (_linear_transform) + * and stores it in lu. Since partial pivoting is used, there are + * row swaps. This is represented by the index permutation vector idx : to access element + * (i,j) of lu, use lu[3*idx[i] + j] + * + * @param lu double[9] in which to store LU-factorization + * @param idx int[3] in which to store row permutation vector + */ + void TetraAffineTransform::factorizeLU(double* lu, int* idx) const + { + // 3 x 3 LU factorization + // initialise idx + for(int i = 0 ; i < 3 ; ++i) + { + idx[i] = i; + } + + for(int k = 0; k < 2 ; ++k) + { + + // find pivot + int i = k; + double max = std::fabs(lu[3*idx[k] + k]); + int row = i; + while(i < 3) + { + if(std::fabs(lu[3*idx[i] + k]) > max) + { + max = fabs(lu[3*idx[i] + k]); + row = i; + } + ++i; + } + + // swap rows in index vector + int tmp = idx[k]; + idx[k] = idx[row]; + idx[row] = tmp; + + // calculate row + for(int j = k + 1 ; j < 3 ; ++j) + { + // l_jk = u_jk / u_kk + lu[3*idx[j] + k] /= lu[3*idx[k] + k]; + for(int s = k + 1; s < 3 ; ++s) + { + // case s = k will always become zero, and then be replaced by + // the l-value + // there's no need to calculate this explicitly + + // u_js = u_js - l_jk * u_ks + lu[3*idx[j] + s] -= lu[3*idx[j] + k] * lu[3*idx[k] + s] ; + } + } + } + } + + /** + * Solves the system Lx = b, where L is lower unit-triangular (ones on the diagonal) + * + * @param x double[3] in which the solution is stored + * @param lu double[9] containing the LU-factorization + * @param b double[3] containing the right-hand side + * @param idx int[3] containing the permutation vector associated with lu + * + */ + void TetraAffineTransform::forwardSubstitution(double* x, const double* lu, const double* b, const int* idx) const + { + // divisions are not carried out explicitly because lu does not store + // the diagonal values of L, which are all 1 + // Compare with backwardSubstitution() + x[idx[0]] = ( b[idx[0]] ); // / lu[3*idx[0]] + x[idx[1]] = ( b[idx[1]] - lu[3*idx[1]] * x[idx[0]] ); // / lu[3*idx[1] + 1]; + x[idx[2]] = ( b[idx[2]] - lu[3*idx[2]] * x[idx[0]] - lu[3*idx[2] + 1] * x[idx[1]] ); // / lu[3*idx[2] + 2]; + } + + /** + * Solves the system Ux = b, where U is upper-triangular + * + * @param x double[3] in which the solution is stored + * @param lu double[9] containing the LU-factorization + * @param b double[3] containing the right-hand side + * @param idx int[3] containing the permutation vector associated with lu + * + */ + void TetraAffineTransform::backwardSubstitution(double* x, const double* lu, const double* b, const int* idx) const + { + x[idx[2]] = ( b[idx[2]] ) / lu[3*idx[2] + 2]; + x[idx[1]] = ( b[idx[1]] - lu[3*idx[1] + 2] * x[idx[2]] ) / lu[3*idx[1] + 1]; + x[idx[0]] = ( b[idx[0]] - lu[3*idx[0] + 1] * x[idx[1]] - lu[3*idx[0] + 2] * x[idx[2]] ) / lu[3*idx[0]]; + } + +} diff --git a/src/medtool/src/INTERP_KERNEL/TetraAffineTransform.hxx b/src/medtool/src/INTERP_KERNEL/TetraAffineTransform.hxx new file mode 100644 index 000000000..fcdb152db --- /dev/null +++ b/src/medtool/src/INTERP_KERNEL/TetraAffineTransform.hxx @@ -0,0 +1,81 @@ +// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 +// 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 __TETRA_AFFINE_TRANSFORM_HXX__ +#define __TETRA_AFFINE_TRANSFORM_HXX__ + +#include "INTERPKERNELDefines.hxx" + +#undef INVERSION_SELF_CHECK // debugging : check that calculated inverse is correct + +namespace INTERP_KERNEL +{ + /** + * \brief Class representing an affine transformation x -> Ax + b that transforms a given tetrahedron + * into the unit tetrahedron. + * + */ + class INTERPKERNEL_EXPORT TetraAffineTransform + { + + public: + TetraAffineTransform(const double *pts); + + void apply(double* destPt, const double* srcPt) const; + + void reverseApply(double* destPt, const double* srcPt) const; + + double determinant() const; + + void dump() const; + + private: + + void invertLinearTransform(); + + void calculateDeterminant(); + + void factorizeLU(double* lu, int* idx) const; + + void forwardSubstitution(double* x, const double* lu, const double* b, const int* idx) const; + + void backwardSubstitution(double* x, const double* lu, const double* b, const int* idx) const; + + // The affine transformation Ax + b is represented with _linear_transformation containing the elements of + // A in row-first ordering and _translation containing the elements of b + + /// 3x3 matrix A in affine transform x -> Ax + b + double _linear_transform[9]; + + /// 3x1 vector b in affine transform x -> Ax + b + double _translation[3]; + + /// The determinant of the matrix A is calculated at the construction of the object and cached. + double _determinant; + + /// 3x3 matrix AT is transposed A matrix used for y -> ATy - c transformation + double _back_linear_transform[9]; + + /// 3x1 vector c in affine transform y -> ATy - c + double _back_translation[3]; + + }; +} + +#endif diff --git a/src/medtool/src/INTERP_KERNEL/TransformedTriangle.cxx b/src/medtool/src/INTERP_KERNEL/TransformedTriangle.cxx new file mode 100644 index 000000000..8b735cb46 --- /dev/null +++ b/src/medtool/src/INTERP_KERNEL/TransformedTriangle.cxx @@ -0,0 +1,842 @@ +// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// + +#include "TransformedTriangle.hxx" +#include "VectorUtils.hxx" +#include "TetraAffineTransform.hxx" +#include <iostream> +#include <fstream> +#include <cassert> +#include <algorithm> +#include <functional> +#include <iterator> +#include <math.h> +#include <vector> + +namespace INTERP_KERNEL +{ + + /** + * \brief Class representing a circular order of a set of points around their barycenter. + * It is used with the STL sort() algorithm to sort the point of the two polygons + * + */ + class ProjectedCentralCircularSortOrder + { + public: + + /// Enumeration of different planes to project on when calculating order + enum CoordType { XY, XZ, YZ }; + + /** + * Constructor + * + * @param barycenter double[3] containing the barycenter of the points to be compared + * @param type plane to project on when comparing. The comparison will not work if all the points are in a plane perpendicular + * to the plane being projected on + */ + ProjectedCentralCircularSortOrder(const double* barycenter, const CoordType type) + : _aIdx((type == YZ) ? 1 : 0), + _bIdx((type == XY) ? 1 : 2), + _a(barycenter[_aIdx]), + _b(barycenter[_bIdx]) + { + } + + /** + * Comparison operator. + * Compares the relative position between two points in their ordering around the barycenter. + * + * @param pt1 a double[3] representing a point + * @param pt2 a double[3] representing a point + * @return true if the angle of the difference vector between pt1 and the barycenter is greater than that + * of the difference vector between pt2 and the barycenter. + */ + bool operator()(const double* pt1, const double* pt2) + { + // calculate angles with the axis + const double ang1 = atan2(pt1[_aIdx] - _a, pt1[_bIdx] - _b); + const double ang2 = atan2(pt2[_aIdx] - _a, pt2[_bIdx] - _b); + + return ang1 > ang2; + } + + private: + /// index corresponding to first coordinate of plane on which points are projected + const int _aIdx; + + /// index corresponding to second coordinate of plane on which points are projected + const int _bIdx; + + /// value of first projected coordinate of the barycenter + const double _a; + + /// value of second projected coordinate of the barycenter + const double _b; + }; + + // ---------------------------------------------------------------------------------- + // TransformedTriangle PUBLIC + // ---------------------------------------------------------------------------------- + + /** + * Constructor + * + * The coordinates are copied to the internal member variables + * + * @param p array of three doubles containing coordinates of P + * @param q array of three doubles containing coordinates of Q + * @param r array of three doubles containing coordinates of R + */ + TransformedTriangle::TransformedTriangle(double* p, double* q, double* r) + : _is_double_products_calculated(false), _is_triple_products_calculated(false), _volume(0) + { + + for(int i = 0 ; i < 3 ; ++i) + { + // xyz coordinates + _coords[5*P + i] = p[i]; + _coords[5*Q + i] = q[i]; + _coords[5*R + i] = r[i]; + } + + // h coordinate + + _coords[5*P + 3] = 1 - p[0] - p[1] - p[2]; + _coords[5*Q + 3] = 1 - q[0] - q[1] - q[2]; + _coords[5*R + 3] = 1 - r[0] - r[1] - r[2]; + + // H coordinate + _coords[5*P + 4] = 1 - p[0] - p[1]; + _coords[5*Q + 4] = 1 - q[0] - q[1]; + _coords[5*R + 4] = 1 - r[0] - r[1]; + + resetNearZeroCoordinates(); + + // initialise rest of data + preCalculateDoubleProducts(); + + preCalculateTriangleSurroundsEdge(); + + preCalculateTripleProducts(); + + } + + /** + * Destructor + * + * Deallocates the memory used to store the points of the polygons. + * This memory is allocated in calculateIntersectionAndProjectionPolygons(). + */ + TransformedTriangle::~TransformedTriangle() + { + // delete elements of polygons + for(std::vector<double*>::iterator it = _polygonA.begin() ; it != _polygonA.end() ; ++it) + { + delete[] *it; + } + for(std::vector<double*>::iterator it = _polygonB.begin() ; it != _polygonB.end() ; ++it) + { + delete[] *it; + } + } + + /** + * Calculates the volume of intersection between the triangle and the + * unit tetrahedron. + * + * @return volume of intersection of this triangle with unit tetrahedron, + * as described in Grandy + * + */ + double TransformedTriangle::calculateIntersectionVolume() + { + // check first that we are not below z - plane + if(isTriangleBelowTetraeder()) + { + LOG(2, " --- Triangle is below tetraeder - V = 0.0"); + return 0.0; + } + + // get the sign of the volume - equal to the sign of the z-component of the normal + // of the triangle, u_x * v_y - u_y * v_x, where u = q - p and v = r - p + // if it is zero, the triangle is perpendicular to the z - plane and so the volume is zero +// const double uv_xy[4] = +// { +// _coords[5*Q] - _coords[5*P], _coords[5*Q + 1] - _coords[5*P + 1], // u_x, u_y +// _coords[5*R] - _coords[5*P], _coords[5*R + 1] - _coords[5*P + 1] // v_x, v_y +// }; + +// double sign = uv_xy[0] * uv_xy[3] - uv_xy[1] * uv_xy[2]; + int sign = isTriangleInclinedToFacet( OXY ); + + if(sign == 0 ) + { + LOG(2, " --- Triangle is perpendicular to z-plane - V = 0.0"); + return _volume = 0.0; + } + + + // normalize sign + //sign = sign > 0.0 ? 1.0 : -1.0; + + LOG(2, "-- Calculating intersection polygons ... "); + calculateIntersectionAndProjectionPolygons(); + + double barycenter[3]; + + // calculate volume under A + double volA = 0.0; + if(_polygonA.size() > 2) + { + LOG(2, "---- Treating polygon A ... "); + calculatePolygonBarycenter(A, barycenter); + sortIntersectionPolygon(A, barycenter); + volA = calculateVolumeUnderPolygon(A, barycenter); + LOG(2, "Volume is " << sign * volA); + } + + double volB = 0.0; + // if triangle is not in h = 0 plane, calculate volume under B + if(_polygonB.size() > 2 && !isTriangleInPlaneOfFacet(XYZ)) + { + LOG(2, "---- Treating polygon B ... "); + + calculatePolygonBarycenter(B, barycenter); + sortIntersectionPolygon(B, barycenter); + volB = calculateVolumeUnderPolygon(B, barycenter); + LOG(2, "Volume is " << sign * volB); + } + + LOG(2, "volA + volB = " << sign * (volA + volB) << std::endl << "***********"); + + return _volume = sign * (volA + volB); + + } + + /** + * Calculates the volume of intersection between the triangle and the + * unit tetrahedron. + * + * @return volume of intersection of this triangle with unit tetrahedron, + * as described in Grandy + * + */ + double TransformedTriangle::calculateIntersectionSurface(TetraAffineTransform* tat) + { + // check first that we are not below z - plane + if(isTriangleBelowTetraeder()) + { + LOG(2, " --- Triangle is below tetraeder - V = 0.0"); + return 0.0; + } + + LOG(2, "-- Calculating intersection polygon ... "); + calculateIntersectionPolygon(); + + _volume = 0.; + if(_polygonA.size() > 2) { + double barycenter[3]; + calculatePolygonBarycenter(A, barycenter); + sortIntersectionPolygon(A, barycenter); + const std::size_t nbPoints = _polygonA.size(); + for(std::size_t i = 0 ; i < nbPoints ; ++i) + tat->reverseApply(_polygonA[i], _polygonA[i]); + _volume = calculateSurfacePolygon(); + } + + return _volume; + } + + // ---------------------------------------------------------------------------------- + // TransformedTriangle PRIVATE + // ---------------------------------------------------------------------------------- + + /** + * Calculates the intersection polygons A and B, performing the intersection tests + * and storing the corresponding points in the vectors _polygonA and _polygonB. + * + * @post _polygonA contains the intersection polygon A and _polygonB contains the + * intersection polygon B. + * + */ + void TransformedTriangle::calculateIntersectionAndProjectionPolygons() + { + assert(_polygonA.size() == 0); + assert(_polygonB.size() == 0); + // avoid reallocations in push_back() by pre-allocating enough memory + // we should never have more than 20 points + _polygonA.reserve(20); + _polygonB.reserve(20); + // -- surface intersections + // surface - edge + for(TetraEdge edge = OX ; edge <= ZX ; edge = TetraEdge(edge + 1)) + { + if(testSurfaceEdgeIntersection(edge)) + { + double* ptA = new double[3]; + calcIntersectionPtSurfaceEdge(edge, ptA); + _polygonA.push_back(ptA); + LOG(3,"Surface-edge : " << vToStr(ptA) << " added to A "); + if(edge >= XY) + { + double* ptB = new double[3]; + copyVector3(ptA, ptB); + _polygonB.push_back(ptB); + LOG(3,"Surface-edge : " << vToStr(ptB) << " added to B "); + } + + } + } + + // surface - ray + for(TetraCorner corner = X ; corner < NO_TET_CORNER ; corner = TetraCorner(corner + 1)) + { + if(testSurfaceRayIntersection(corner)) + { + double* ptB = new double[3]; + copyVector3(&COORDS_TET_CORNER[3 * corner], ptB); + _polygonB.push_back(ptB); + LOG(3,"Surface-ray : " << vToStr(ptB) << " added to B"); + } + } + + // -- segment intersections + for(TriSegment seg = PQ ; seg < NO_TRI_SEGMENT ; seg = TriSegment(seg + 1)) + { + + bool isZero[NO_DP]; + + // check beforehand which double-products are zero + for(DoubleProduct dp = C_YZ; dp < NO_DP; dp = DoubleProduct(dp + 1)) + { + isZero[dp] = (calcStableC(seg, dp) == 0.0); + } + + // segment - facet + for(TetraFacet facet = OYZ ; facet < NO_TET_FACET ; facet = TetraFacet(facet + 1)) + { + // is this test worth it? + const bool doTest = + !isZero[DP_FOR_SEG_FACET_INTERSECTION[3*facet]] && + !isZero[DP_FOR_SEG_FACET_INTERSECTION[3*facet + 1]] && + !isZero[DP_FOR_SEG_FACET_INTERSECTION[3*facet + 2]]; + + if(doTest && testSegmentFacetIntersection(seg, facet)) + { + double* ptA = new double[3]; + calcIntersectionPtSegmentFacet(seg, facet, ptA); + _polygonA.push_back(ptA); + LOG(3,"Segment-facet : " << vToStr(ptA) << " added to A"); + if(facet == XYZ) + { + double* ptB = new double[3]; + copyVector3(ptA, ptB); + _polygonB.push_back(ptB); + LOG(3,"Segment-facet : " << vToStr(ptB) << " added to B"); + } + + } + } + + // segment - edge + for(TetraEdge edge = OX ; edge <= ZX ; edge = TetraEdge(edge + 1)) + { + const DoubleProduct edge_dp = DoubleProduct(edge); + + if(isZero[edge_dp] && testSegmentEdgeIntersection(seg, edge)) + { + double* ptA = new double[3]; + calcIntersectionPtSegmentEdge(seg, edge, ptA); + _polygonA.push_back(ptA); + LOG(3,"Segment-edge : " << vToStr(ptA) << " added to A"); + if(edge >= XY) + { + double* ptB = new double[3]; + copyVector3(ptA, ptB); + _polygonB.push_back(ptB); + } + } + } + + // segment - corner + for(TetraCorner corner = O ; corner < NO_TET_CORNER ; corner = TetraCorner(corner + 1)) + { + const bool doTest = + isZero[DoubleProduct( EDGES_FOR_CORNER[3*corner] )] && + isZero[DoubleProduct( EDGES_FOR_CORNER[3*corner+1] )] && + isZero[DoubleProduct( EDGES_FOR_CORNER[3*corner+2] )]; + + if(doTest && testSegmentCornerIntersection(seg, corner)) + { + double* ptA = new double[3]; + copyVector3(&COORDS_TET_CORNER[3 * corner], ptA); + _polygonA.push_back(ptA); + LOG(3,"Segment-corner : " << vToStr(ptA) << " added to A"); + if(corner != O) + { + double* ptB = new double[3]; + _polygonB.push_back(ptB); + copyVector3(&COORDS_TET_CORNER[3 * corner], ptB); + LOG(3,"Segment-corner : " << vToStr(ptB) << " added to B"); + } + } + } + + // segment - ray + for(TetraCorner corner = X ; corner < NO_TET_CORNER ; corner = TetraCorner(corner + 1)) + { + if(isZero[DP_SEGMENT_RAY_INTERSECTION[7*(corner-1)]] && testSegmentRayIntersection(seg, corner)) + { + double* ptB = new double[3]; + copyVector3(&COORDS_TET_CORNER[3 * corner], ptB); + _polygonB.push_back(ptB); + LOG(3,"Segment-ray : " << vToStr(ptB) << " added to B"); + } + } + + // segment - halfstrip + for(TetraEdge edge = XY ; edge <= ZX ; edge = TetraEdge(edge + 1)) + { + +#if 0 + const int edgeIdx = int(edge) - 3; // offset since we only care for edges XY - ZX + const bool doTest = + !isZero[DP_FOR_HALFSTRIP_INTERSECTION[4*edgeIdx]] && + !isZero[DP_FOR_HALFSTRIP_INTERSECTION[4*edgeIdx+1]]; + + + if(doTest && testSegmentHalfstripIntersection(seg, edge)) +#endif + if(testSegmentHalfstripIntersection(seg, edge)) + { + double* ptB = new double[3]; + calcIntersectionPtSegmentHalfstrip(seg, edge, ptB); + _polygonB.push_back(ptB); + LOG(3,"Segment-halfstrip : " << vToStr(ptB) << " added to B"); + } + } + } + + // inclusion tests + for(TriCorner corner = P ; corner < NO_TRI_CORNER ; corner = TriCorner(corner + 1)) + { + // { XYZ - inclusion only possible if in Tetrahedron? + // tetrahedron + if(testCornerInTetrahedron(corner)) + { + double* ptA = new double[3]; + copyVector3(&_coords[5*corner], ptA); + _polygonA.push_back(ptA); + LOG(3,"Inclusion tetrahedron : " << vToStr(ptA) << " added to A"); + } + + // XYZ - plane + if(testCornerOnXYZFacet(corner)) + { + double* ptB = new double[3]; + copyVector3(&_coords[5*corner], ptB); + _polygonB.push_back(ptB); + LOG(3,"Inclusion XYZ-plane : " << vToStr(ptB) << " added to B"); + } + + // projection on XYZ - facet + if(testCornerAboveXYZFacet(corner)) + { + double* ptB = new double[3]; + copyVector3(&_coords[5*corner], ptB); + ptB[2] = 1 - ptB[0] - ptB[1]; + assert(epsilonEqual(ptB[0]+ptB[1]+ptB[2] - 1, 0.0)); + _polygonB.push_back(ptB); + LOG(3,"Projection XYZ-plane : " << vToStr(ptB) << " added to B"); + } + + } + + } + + /** + * Calculates the intersection polygon A, performing the intersection tests + * and storing the corresponding point in the vector _polygonA. + * + * @post _polygonA contains the intersection polygon A. + * + */ + void TransformedTriangle::calculateIntersectionPolygon() + { + assert(_polygonA.size() == 0); + // avoid reallocations in push_back() by pre-allocating enough memory + // we should never have more than 20 points + _polygonA.reserve(20); + // -- surface intersections + // surface - edge + for(TetraEdge edge = OX ; edge <= ZX ; edge = TetraEdge(edge + 1)) + { + if(testSurfaceEdgeIntersection(edge)) + { + double* ptA = new double[3]; + calcIntersectionPtSurfaceEdge(edge, ptA); + _polygonA.push_back(ptA); + LOG(3,"Surface-edge : " << vToStr(ptA) << " added to A "); + } + } + + // -- segment intersections + for(TriSegment seg = PQ ; seg < NO_TRI_SEGMENT ; seg = TriSegment(seg + 1)) + { + + bool isZero[NO_DP]; + + // check beforehand which double-products are zero + for(DoubleProduct dp = C_YZ; dp < NO_DP; dp = DoubleProduct(dp + 1)) + { + isZero[dp] = (calcStableC(seg, dp) == 0.0); + } + + // segment - facet + for(TetraFacet facet = OYZ ; facet < NO_TET_FACET ; facet = TetraFacet(facet + 1)) + { + // is this test worth it? + const bool doTest = + !isZero[DP_FOR_SEG_FACET_INTERSECTION[3*facet]] && + !isZero[DP_FOR_SEG_FACET_INTERSECTION[3*facet + 1]] && + !isZero[DP_FOR_SEG_FACET_INTERSECTION[3*facet + 2]]; + + if(doTest && testSegmentFacetIntersection(seg, facet)) + { + double* ptA = new double[3]; + calcIntersectionPtSegmentFacet(seg, facet, ptA); + _polygonA.push_back(ptA); + LOG(3,"Segment-facet : " << vToStr(ptA) << " added to A"); + } + } + + // segment - edge + for(TetraEdge edge = OX ; edge <= ZX ; edge = TetraEdge(edge + 1)) + { + const DoubleProduct edge_dp = DoubleProduct(edge); + + if(isZero[edge_dp] && testSegmentEdgeIntersection(seg, edge)) + { + double* ptA = new double[3]; + calcIntersectionPtSegmentEdge(seg, edge, ptA); + _polygonA.push_back(ptA); + LOG(3,"Segment-edge : " << vToStr(ptA) << " added to A"); + } + } + + // segment - corner + for(TetraCorner corner = O ; corner < NO_TET_CORNER ; corner = TetraCorner(corner + 1)) + { + const bool doTest = + isZero[DoubleProduct( EDGES_FOR_CORNER[3*corner] )] && + isZero[DoubleProduct( EDGES_FOR_CORNER[3*corner+1] )] && + isZero[DoubleProduct( EDGES_FOR_CORNER[3*corner+2] )]; + + if(doTest && testSegmentCornerIntersection(seg, corner)) + { + double* ptA = new double[3]; + copyVector3(&COORDS_TET_CORNER[3 * corner], ptA); + _polygonA.push_back(ptA); + LOG(3,"Segment-corner : " << vToStr(ptA) << " added to A"); + } + } + + } + + // inclusion tests + for(TriCorner corner = P ; corner < NO_TRI_CORNER ; corner = TriCorner(corner + 1)) + { + // { XYZ - inclusion only possible if in Tetrahedron? + // tetrahedron + if(testCornerInTetrahedron(corner)) + { + double* ptA = new double[3]; + copyVector3(&_coords[5*corner], ptA); + _polygonA.push_back(ptA); + LOG(3,"Inclusion tetrahedron : " << vToStr(ptA) << " added to A"); + } + + } + + } + + + /** + * Returns the surface of polygon A. + * + * @return the surface of polygon A. + */ + double TransformedTriangle::calculateSurfacePolygon() + { + const std::size_t nbPoints = _polygonA.size(); + double pdt[3]; + double sum[3] = {0., 0., 0.}; + + for(std::size_t i = 0 ; i < nbPoints ; ++i) + { + const double *const ptCurr = _polygonA[i]; // pt "i" + const double *const ptNext = _polygonA[(i + 1) % nbPoints]; // pt "i+1" (pt nbPoints == pt 0) + + cross(ptCurr, ptNext, pdt); + add(pdt, sum); + } + + const double surface = norm(sum) * 0.5; + LOG(2,"Surface is " << surface); + return surface; + } + + /** + * Calculates the barycenters of the given intersection polygon. + * + * @pre the intersection polygons have been calculated with calculateIntersectionAndProjectionPolygons() + * + * @param poly one of the two intersection polygons + * @param barycenter array of three doubles where barycenter is stored + * + */ + void TransformedTriangle::calculatePolygonBarycenter(const IntersectionPolygon poly, double* barycenter) + { + LOG(3,"--- Calculating polygon barycenter"); + + // get the polygon points + std::vector<double*>& polygon = (poly == A) ? _polygonA : _polygonB; + + // calculate barycenter + const std::size_t m = polygon.size(); + + for(int j = 0 ; j < 3 ; ++j) + { + barycenter[j] = 0.0; + } + + if(m != 0) + { + for(std::size_t i = 0 ; i < m ; ++i) + { + const double* pt = polygon[i]; + for(int j = 0 ; j < 3 ; ++j) + { + barycenter[j] += pt[j] / double(m); + } + } + } + LOG(3,"Barycenter is " << vToStr(barycenter)); + } + + /** + * Sorts the given intersection polygon in circular order around its barycenter. + * @pre the intersection polygons have been calculated with calculateIntersectionAndProjectionPolygons() + * @post the vertices in _polygonA and _polygonB are sorted in circular order around their + * respective barycenters + * + * @param poly one of the two intersection polygons + * @param barycenter array of three doubles with the coordinates of the barycenter + * + */ + void TransformedTriangle::sortIntersectionPolygon(const IntersectionPolygon poly, const double* barycenter) + { + LOG(3,"--- Sorting polygon ..."); + + using INTERP_KERNEL::ProjectedCentralCircularSortOrder; + typedef ProjectedCentralCircularSortOrder SortOrder; // change is only necessary here and in constructor + typedef SortOrder::CoordType CoordType; + + // get the polygon points + std::vector<double*>& polygon = (poly == A) ? _polygonA : _polygonB; + + if(polygon.size() == 0) + return; + + // determine type of sorting + CoordType type = SortOrder::XY; + if(poly == A && !isTriangleInclinedToFacet( OXY )) // B is on h = 0 plane -> ok + { + // NB : the following test is never true if we have eliminated the + // triangles parallel to x == 0 and y == 0 in calculateIntersectionVolume(). + // We keep the test here anyway, to avoid interdependency. + + // is triangle inclined to x == 0 ? + if(isTriangleInclinedToFacet(OZX)) + { + type = SortOrder::XZ; + } + else //if(isTriangleParallelToFacet(OYZ)) + { + type = SortOrder::YZ; + } + } + + // create order object + SortOrder order(barycenter, type); + + // sort vector with this object + // NB : do not change place of first object, with respect to which the order + // is defined + sort((polygon.begin()), polygon.end(), order); + + LOG(3,"Sorted polygon is "); + for(size_t i = 0 ; i < polygon.size() ; ++i) + { + LOG(3,vToStr(polygon[i])); + } + + } + + /** + * Calculates the volume between the given polygon and the z = 0 plane. + * + * @pre the intersection polygones have been calculated with calculateIntersectionAndProjectionPolygons(), + * and they have been sorted in circular order with sortIntersectionPolygons(void) + * + * @param poly one of the two intersection polygons + * @param barycenter array of three doubles with the coordinates of the barycenter + * @return the volume between the polygon and the z = 0 plane + * + */ + double TransformedTriangle::calculateVolumeUnderPolygon(IntersectionPolygon poly, const double* barycenter) + { + LOG(2,"--- Calculating volume under polygon"); + + // get the polygon points + std::vector<double*>& polygon = (poly == A) ? _polygonA : _polygonB; + + double vol = 0.0; + const std::size_t m = polygon.size(); + + for(std::size_t i = 0 ; i < m ; ++i) + { + const double* ptCurr = polygon[i]; // pt "i" + const double* ptNext = polygon[(i + 1) % m]; // pt "i+1" (pt m == pt 0) + + const double factor1 = ptCurr[2] + ptNext[2] + barycenter[2]; + const double factor2 = + ptCurr[0]*(ptNext[1] - barycenter[1]) + + ptNext[0]*(barycenter[1] - ptCurr[1]) + + barycenter[0]*(ptCurr[1] - ptNext[1]); + vol += (factor1 * factor2) / 6.0; + } + + LOG(2,"Abs. Volume is " << vol); + return vol; + } + + + //////////////////////////////////////////////////////////////////////////////////// + // Detection of (very) degenerate cases ///////////// + //////////////////////////////////////////////////////////////////////////////////// + + /** + * Checks if the triangle lies in the plane of a given facet + * + * @param facet one of the facets of the tetrahedron + * @return true if PQR lies in the plane of the facet, false if not + */ + bool TransformedTriangle::isTriangleInPlaneOfFacet(const TetraFacet facet) const + { + + // coordinate to check + const int coord = static_cast<int>(facet); + + for(TriCorner c = P ; c < NO_TRI_CORNER ; c = TriCorner(c + 1)) + { + if(_coords[5*c + coord] != 0.0) + { + return false; + } + } + + return true; + } + + /** + * Checks if the triangle is parallel to the given facet + * + * @param facet one of the facets of the unit tetrahedron + * @return true if triangle is parallel to facet, false if not + */ + bool TransformedTriangle::isTriangleParallelToFacet(const TetraFacet facet) const + { + // coordinate to check + const int coord = static_cast<int>(facet); + return (_coords[5*P + coord] == _coords[5*Q + coord]) && (_coords[5*P + coord] == _coords[5*R + coord]); + } + + /** + * Checks if the triangle is not perpedicular to the given facet + * + * @param facet one of the facets of the unit tetrahedron + * @return zero if the triangle is perpendicular to the facet, + * else 1 or -1 depending on the sign of cross product of facet edges + */ + int TransformedTriangle::isTriangleInclinedToFacet(const TetraFacet facet) const + { + // coordinate to check + const int coord = static_cast<int>(facet); + const int ind1 = ( coord+1 ) % 3, ind2 = ( coord+2 ) % 3; + const double uv_xy[4] = + { + // u_x, u_y + _coords[5*Q+ind1] - _coords[5*P+ind1], _coords[5*Q+ind2] - _coords[5*P+ind2], + // v_x, v_y + _coords[5*R+ind1] - _coords[5*P+ind1], _coords[5*R+ind2] - _coords[5*P+ind2] + }; + + double sign = uv_xy[0] * uv_xy[3] - uv_xy[1] * uv_xy[2]; + if(epsilonEqual(sign, 0.)) + { + sign = 0.; + } + return (sign < 0.) ? -1 : (sign > 0.) ? 1 : 0; + } + + /** + * Determines whether the triangle is below the z-plane. + * + * @return true if the z-coordinate of the three corners of the triangle are all less than 0, false otherwise. + */ + bool TransformedTriangle::isTriangleBelowTetraeder() const + { + for(TriCorner c = P ; c < NO_TRI_CORNER ; c = TriCorner(c + 1)) + { + // check z-coords for all points + if(_coords[5*c + 2] >= 0.0) + { + return false; + } + } + return true; + } + + /** + * Prints the coordinates of the triangle to std::cout + * + */ + void TransformedTriangle::dumpCoords() const + { + std::cout << "Coords : "; + for(int i = 0 ; i < 3; ++i) + { + std::cout << vToStr(&_coords[5*i]) << ","; + } + std::cout << std::endl; + } + + } // NAMESPACE diff --git a/src/medtool/src/INTERP_KERNEL/TransformedTriangle.hxx b/src/medtool/src/INTERP_KERNEL/TransformedTriangle.hxx new file mode 100644 index 000000000..51433c9d2 --- /dev/null +++ b/src/medtool/src/INTERP_KERNEL/TransformedTriangle.hxx @@ -0,0 +1,389 @@ +// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 +// 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 __TRANSFORMED_TRIANGLE_HXX__ +#define __TRANSFORMED_TRIANGLE_HXX__ + +#include "INTERPKERNELDefines.hxx" + +#include <vector> + +// Levels : +// 1 - overview of algorithm + volume result +// 2 - algorithm detail +// 3 - intersection polygon results detail +// 4 - intersection polygon search detail +// higher -> misc. gory details of calculation + +#include "Log.hxx" + +#ifdef WIN32 +#pragma warning(disable:4251) +#endif + +namespace INTERP_TEST +{ + class TransformedTriangleTest; + class TransformedTriangleIntersectTest; +} + + +namespace INTERP_KERNEL +{ + class TetraAffineTransform; + + /** \class TransformedTriangle + * \brief Class representing one of the faces of the triangulated source polyhedron after having been transformed + * with the affine transform that takes the target tetrahedron to the unit tetrahedron. It contains the + * logic for calculating the volume of intersection between the triangle and the unit tetrahedron. + * + * \see TransformedTriangle.hxx + * + * Reference : J. Grandy, "Conservative Remapping and Region Overlays by Intersecting Arbitrary Polyhedra", + * Journal of Computational Physics (1999) + * + */ + + /** \file TransformedTriangle.hxx + * + * OVERVIEW of how the class works : (details can be found in the documentation of each method) + * + * Constructor : + * The constructor takes as arguments three pointers to double[3] vectors holding the transformed + * coordinates of the corners of the triangle. It copies their coordinates and then proceeds to pre-calculating certain + * entities used in the intersection calculation : the double products, triple products and the values of the function E + * (Grandy, [53]). + * + * calculateIntersectionVolume() : + * This is the only method in the public interface. It calculates the volume under the intersection polygons + * between the triangle and the unit tetrahedron, as described in Grandy, pp. 435-447. It does this by first calculating the + * intersection polygons A and B, with the method calculateIntersectionPolygons(). It then calculates the barycenter of each + * polygon in calculatePolygonBarycenter(), and sorts their points in a circular order around the barycenter in + * sortIntersecionPolygon(). The sorting is done with STL sort, using the order defined in the class + * ProjectedCentralCircularSortOrder. The volume under each polygon is then calculated with calculateVolumeUnderPolygon(), which + * implements formula [34] in Grandy. + * + * calculateIntersectionPolygons() : + * This method goes through all the possible ways in which the triangle can intersect the tetrahedron and tests for these + * types of intersections in accordance with the formulas described in Grandy. These tests are implemented in the test* - methods. + * The formulas in the article are stated for one case each only, while the calculation must take into account all cases. + * To this end, a number of tables, implemented as static const arrays of different types, are used. The tables + * mainly contain values of the different enumeration types described at the beginning of the class interface. For example, + * the formula Grandy gives for the segment-halfstrip intersection tests ([30]) is for use with the halfstrip above the zx edge. + * For the other two halfstrips (above the xy and yz edges), other double products are used, which + * are stored in the table DP_FOR_HALFSTRIP_INTERSECTION. This allows us to treat + * all the edges equally, avoiding switch() - statements. It is the careful choice of order of the enumeration types that makes this + * possible. Notably, there is a correspondance between the TetraEdge type and the DoubleProduct type (see Grandy, table III) that + * is used throughout the code, permitting statements such as DoubleProduct(some_edge) to work. + * When an intersection point has been detected it is calculated with a corresponding calc* - method in the cases where it + * is not known directly. It is then added to the polygon A and/or B as necessary. + * + * OPTIMIZE : + * If OPTIMIZE is defined, a large number of methods will be prefixed with inline and some optimizations concerning the tests + * with zero double products will be used. + */ + class INTERPKERNEL_EXPORT TransformedTriangle + { + + + public: + + friend class INTERP_TEST::TransformedTriangleTest; + friend class INTERP_TEST::TransformedTriangleIntersectTest; + /* + * Enumerations representing the different geometric elements of the unit tetrahedron + * and the triangle. The end element, NO_* gives the number of elements in the enumeration + * and can be used as end element in loops. + */ + + /// Corners of tetrahedron + enum TetraCorner { O = 0, X, Y, Z, NO_TET_CORNER }; + + /// Edges of tetrahedron + enum TetraEdge { OX = 0, OY, OZ, XY, YZ, ZX, H01, H10, NO_TET_EDGE }; + + /// Facets (faces) of tetrahedron + enum TetraFacet { OYZ = 0, OZX, OXY, XYZ, NO_TET_FACET }; + + /// Corners of triangle + enum TriCorner { P = 0, Q, R, NO_TRI_CORNER }; + + /// Segments (edges) of triangle + enum TriSegment { PQ = 0, QR, RP, NO_TRI_SEGMENT }; + + /// Intersection polygons + enum IntersectionPolygon{ A = 0, B, NO_INTERSECTION_POLYGONS }; + + /// Double products + /// NB : order corresponds to TetraEdges (Grandy, table III) + enum DoubleProduct { C_YZ = 0, C_ZX, C_XY, C_ZH, C_XH, C_YH, C_01, C_10, NO_DP }; + + TransformedTriangle(double* p, double* q, double* r); + ~TransformedTriangle(); + + double calculateIntersectionVolume(); + double calculateIntersectionSurface(TetraAffineTransform* tat); + + void dumpCoords() const; + + // Queries of member values used by UnitTetraIntersectionBary + + const double* getCorner(TriCorner corner) const { return _coords + 5*corner; } + + const std::vector<double*>& getPolygonA() const { return _polygonA; } + + double getVolume() const { return _volume; } + + protected: + + TransformedTriangle() { } + + // ---------------------------------------------------------------------------------- + // High-level methods called directly by calculateIntersectionVolume() + // ---------------------------------------------------------------------------------- + void calculateIntersectionAndProjectionPolygons(); + + void calculatePolygonBarycenter(const IntersectionPolygon poly, double* barycenter); + + void sortIntersectionPolygon(const IntersectionPolygon poly, const double* barycenter); + + double calculateVolumeUnderPolygon(IntersectionPolygon poly, const double* barycenter); + + // ---------------------------------------------------------------------------------- + // High-level methods called directly by calculateIntersectionSurface() + // ---------------------------------------------------------------------------------- + void calculateIntersectionPolygon(); + + double calculateSurfacePolygon(); + + // ---------------------------------------------------------------------------------- + // Detection of degenerate triangles + // ---------------------------------------------------------------------------------- + + bool isTriangleInPlaneOfFacet(const TetraFacet facet) const; + + bool isTriangleParallelToFacet(const TetraFacet facet) const; + + int isTriangleInclinedToFacet(const TetraFacet facet) const; + + bool isTriangleBelowTetraeder() const; + + // ---------------------------------------------------------------------------------- + // Intersection test methods and intersection point calculations + // ---------------------------------------------------------------------------------- + + inline bool testSurfaceEdgeIntersection(const TetraEdge edge) const; + + void calcIntersectionPtSurfaceEdge(const TetraEdge edge, double* pt) const; + + inline bool testSegmentFacetIntersection(const TriSegment seg, const TetraFacet facet) const; + + void calcIntersectionPtSegmentFacet(const TriSegment seg, const TetraFacet facet, double* pt) const; + + bool testSegmentEdgeIntersection(const TriSegment seg, const TetraEdge edge) const; + + void calcIntersectionPtSegmentEdge(const TriSegment seg, const TetraEdge edge, double* pt) const ; + + bool testSegmentCornerIntersection(const TriSegment seg, const TetraCorner corner) const ; + + inline bool testSurfaceRayIntersection(const TetraCorner corner) const; + + bool testSegmentHalfstripIntersection(const TriSegment seg, const TetraEdge edg); + + void calcIntersectionPtSegmentHalfstrip(const TriSegment seg, const TetraEdge edge, double* pt) const; + + bool testSegmentRayIntersection(const TriSegment seg, const TetraCorner corner) const; + + inline bool testCornerInTetrahedron(const TriCorner corner) const; + + inline bool testCornerOnXYZFacet(const TriCorner corner) const; + + inline bool testCornerAboveXYZFacet(const TriCorner corner) const; + + // ---------------------------------------------------------------------------------- + // Utility methods used in intersection tests + // ---------------------------------------------------------------------------------- + + bool testTriangleSurroundsEdge(const TetraEdge edge) const; + + inline bool testEdgeIntersectsTriangle(const TetraEdge edge) const; + + inline bool testFacetSurroundsSegment(const TriSegment seg, const TetraFacet facet) const; + + inline bool testSegmentIntersectsFacet(const TriSegment seg, const TetraFacet facet) const; + + bool testSegmentIntersectsHPlane(const TriSegment seg) const; + + bool testSurfaceAboveCorner(const TetraCorner corner) const; + + bool testTriangleSurroundsRay(const TetraCorner corner) const; + + // ---------------------------------------------------------------------------------- + // Double and triple product calculations + // ---------------------------------------------------------------------------------- + + void resetNearZeroCoordinates(); + + bool areDoubleProductsConsistent(const TriSegment seg) const; + + void preCalculateDoubleProducts(void); + + inline void resetDoubleProducts(const TriSegment seg, const TetraCorner corner); + + double calculateDistanceCornerSegment(const TetraCorner corner, const TriSegment seg) const; + + void preCalculateTripleProducts(void); + + double calculateAngleEdgeTriangle(const TetraEdge edge) const; + + inline double calcStableC(const TriSegment seg, const DoubleProduct dp) const; + + inline double calcStableT(const TetraCorner corner) const; + + inline double calcUnstableC(const TriSegment seg, const DoubleProduct dp) const; + + double calcTByDevelopingRow(const TetraCorner corner, const int row = 1, const bool project = false) const; + + // ---------------------------------------------------------------------------------- + // Member variables + // ---------------------------------------------------------------------------------- + protected: + + /// Array holding the coordinates of the triangle's three corners + /// order : + /// [ p_x, p_y, p_z, p_h, p_H, q_x, q_y, q_z, q_h, q_H, r_x, r_y, r_z, r_h, r_H ] + double _coords[15]; + + /// Flag showing whether the double products have been calculated yet + bool _is_double_products_calculated; + + /// Flag showing whether the triple products have been calculated yet + bool _is_triple_products_calculated; + + /// Array containing the 24 double products. + /// order : c^PQ_YZ, ... ,cPQ_10, ... c^QR_YZ, ... c^RP_YZ + /// following order in enumeration DoubleProduct + double _doubleProducts[24]; + + /// Array containing the 4 triple products. + /// order : t_O, t_X, t_Y, t_Z + double _tripleProducts[4]; + + /// Vector holding the points of the intersection polygon A. + /// these points are allocated in calculateIntersectionPolygons() and liberated in the destructor + std::vector<double*> _polygonA; + + /// Vector holding the points of the intersection polygon B. + /// These points are allocated in calculateIntersectionPolygons() and liberated in the destructor + std::vector<double*> _polygonB; + + /// Array holding the coordinates of the barycenter of the polygon A + /// This point is calculated in calculatePolygonBarycenter + double _barycenterA[3]; + + /// Array holding the coordinates of the barycenter of the polygon B + /// This point is calculated in calculatePolygonBarycenter + //double _barycenterB[3]; + + /// Array of flags indicating which of the four triple products have been correctly calculated. + /// Used for asserts in debug mode + bool _validTP[4]; + + /// calculated volume for use of UnitTetraIntersectionBary + double _volume; + + /** + * Calls TransformedTriangle::testTriangleSurroundsEdge for edges OX to ZX and stores the result in + * member variable array_triangleSurroundsEdgeCache. + * + */ + void preCalculateTriangleSurroundsEdge(); + + /// Array holding results of the test testTriangleSurroundsEdge() for all the edges. + /// These are calculated in preCalculateTriangleSurroundsEdge(). + bool _triangleSurroundsEdgeCache[NO_TET_EDGE]; + + // ---------------------------------------------------------------------------------- + // Constants + // ---------------------------------------------------------------------------------- + + // offsets : 0 -> x, 1 -> y, 2 -> z, 3 -> h, 4 -> H + // corresponds to order of double products in DoubleProduct + // so that offset[C_*] gives the right coordinate + static const int DP_OFFSET_1[8]; + static const int DP_OFFSET_2[8]; + + // the coordinates used in the expansion of triple products by a given row + // in constellation (corner, row-1) + // (0,1,2,3) <=> (x,y,z,h) + static const int COORDINATE_FOR_DETERMINANT_EXPANSION[12]; + + // contains the edge of the double product used when + // expanding the triple product determinant associated with each corner + // by a given row + static const DoubleProduct DP_FOR_DETERMINANT_EXPANSION[12]; + + // values used to decide how imprecise the double products + // should be to set them to 0.0 + static const long double MACH_EPS; // machine epsilon + static const long double MULT_PREC_F; // precision of multiplications (Grandy : f) + static const long double THRESHOLD_F; // threshold for zeroing (Grandy : F/f) + + static const double TRIPLE_PRODUCT_ANGLE_THRESHOLD; + + // correspondance facet - double product + // Grandy, table IV + static const DoubleProduct DP_FOR_SEG_FACET_INTERSECTION[12]; + + // signs associated with entries in DP_FOR_SEGMENT_FACET_INTERSECTION + static const double SIGN_FOR_SEG_FACET_INTERSECTION[12]; + + // coordinates of corners of tetrahedron + static const double COORDS_TET_CORNER[12]; + + // indices to use in tables DP_FOR_SEG_FACET_INTERSECTION and SIGN_FOR_SEG_FACET_INTERSECTION + // for the calculation of the coordinates (x,y,z) of the intersection points + // for Segment-Facet and Segment-Edge intersections + static const int DP_INDEX[12]; + + // correspondance edge - corners + static const TetraCorner CORNERS_FOR_EDGE[12]; + + // correspondance edge - facets + // facets shared by each edge + static const TetraFacet FACET_FOR_EDGE[12]; + + // correspondance edge - corners + static const TetraEdge EDGES_FOR_CORNER[12]; + + // double products used in segment-halfstrip test + static const DoubleProduct DP_FOR_HALFSTRIP_INTERSECTION[12]; + + // double products used in segment - ray test + static const DoubleProduct DP_SEGMENT_RAY_INTERSECTION[21]; + + }; + + // include definitions of inline methods + +#include "TransformedTriangleInline.hxx" +} + + +#endif diff --git a/src/medtool/src/INTERP_KERNEL/TransformedTriangleInline.hxx b/src/medtool/src/INTERP_KERNEL/TransformedTriangleInline.hxx new file mode 100644 index 000000000..3f473ec75 --- /dev/null +++ b/src/medtool/src/INTERP_KERNEL/TransformedTriangleInline.hxx @@ -0,0 +1,284 @@ +// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 +// 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 __TRANSFORMEDTRIANGLEINLINE_HXX__ +#define __TRANSFORMEDTRIANGLEINLINE_HXX__ + +// This file contains inline versions of some of the methods in the TransformedTriangle*.cxx files. +// It replaces those methods if OPTIMIZE is defined. +// NB : most of these methods have documentation in their corresponding .cxx - file. + +// ---------------------------------------------------------------------------------- +// Optimization methods. These are only defined and used if OPTIMIZE is defined. +// ----------------------------------------------------------------------------------- + + +inline void TransformedTriangle::preCalculateTriangleSurroundsEdge() +{ + for(TetraEdge edge = OX ; edge <= ZX ; edge = TetraEdge(edge + 1)) + { + _triangleSurroundsEdgeCache[edge] = testTriangleSurroundsEdge(edge); + } +} + + +// ---------------------------------------------------------------------------------- +// TransformedTriangle_math.cxx +// ---------------------------------------------------------------------------------- + +inline void TransformedTriangle::resetDoubleProducts(const TriSegment seg, const TetraCorner corner) +{ + // set the three corresponding double products to 0.0 + static const DoubleProduct DOUBLE_PRODUCTS[12] = + { + C_YZ, C_ZX, C_XY, // O + C_YZ, C_ZH, C_YH, // X + C_ZX, C_ZH, C_XH, // Y + C_XY, C_YH, C_XH // Z + }; + + for(int i = 0 ; i < 3 ; ++i) { + const DoubleProduct dp = DOUBLE_PRODUCTS[3*corner + i]; + + LOG(6, std::endl << "resetting inconsistent dp :" << dp << " for corner " << corner); + _doubleProducts[8*seg + dp] = 0.0; + }; +} + +inline double TransformedTriangle::calcStableC(const TriSegment seg, const DoubleProduct dp) const +{ + return _doubleProducts[8*seg + dp]; +} + +inline double TransformedTriangle::calcStableT(const TetraCorner corner) const +{ + // assert(_isTripleProductsCalculated); + // assert(_validTP[corner]); + return _tripleProducts[corner]; +} + +inline double TransformedTriangle::calcUnstableC(const TriSegment seg, const DoubleProduct dp) const +{ + + // find the points of the triangle + // 0 -> P, 1 -> Q, 2 -> R + const int pt1 = seg; + const int pt2 = (seg + 1) % 3; + + // find offsets + const int off1 = DP_OFFSET_1[dp]; + const int off2 = DP_OFFSET_2[dp]; + + return _coords[5*pt1 + off1] * _coords[5*pt2 + off2] - _coords[5*pt1 + off2] * _coords[5*pt2 + off1]; +} + +// ---------------------------------------------------------------------------------- +// TransformedTriangle_intersect.cxx +// ---------------------------------------------------------------------------------- +inline bool TransformedTriangle::testSurfaceEdgeIntersection(const TetraEdge edge) const +{ + return _triangleSurroundsEdgeCache[edge] && testEdgeIntersectsTriangle(edge); +} + +inline bool TransformedTriangle::testSegmentFacetIntersection(const TriSegment seg, const TetraFacet facet) const +{ + return testFacetSurroundsSegment(seg, facet) && testSegmentIntersectsFacet(seg, facet); +} + +inline bool TransformedTriangle::testSurfaceRayIntersection(const TetraCorner corner) const +{ + return testTriangleSurroundsRay( corner ) && testSurfaceAboveCorner( corner ); +} + +inline bool TransformedTriangle::testCornerInTetrahedron(const TriCorner corner) const +{ + const double pt[4] = + { + _coords[5*corner], // x + _coords[5*corner + 1], // y + _coords[5*corner + 2], // z + _coords[5*corner + 3] // z + }; + + for(int i = 0 ; i < 4 ; ++i) + { + if(pt[i] < 0.0 || pt[i] > 1.0) + { + return false; + } + } + return true; +} + +inline bool TransformedTriangle::testCornerOnXYZFacet(const TriCorner corner) const +{ +#if 0 + const double pt[4] = + { + _coords[5*corner], // x + _coords[5*corner + 1], // y + _coords[5*corner + 2], // z + _coords[5*corner + 3] // h + }; +#endif + const double* pt = &_coords[5*corner]; + + if(pt[3] != 0.0) + { + return false; + } + + for(int i = 0 ; i < 3 ; ++i) + { + if(pt[i] < 0.0 || pt[i] > 1.0) + { + return false; + } + } + return true; +} + +inline bool TransformedTriangle::testCornerAboveXYZFacet(const TriCorner corner) const +{ + const double x = _coords[5*corner]; + const double y = _coords[5*corner + 1]; + const double h = _coords[5*corner + 3]; + const double H = _coords[5*corner + 4]; + + return h < 0.0 && H >= 0.0 && x >= 0.0 && y >= 0.0; + +} + +inline bool TransformedTriangle::testEdgeIntersectsTriangle(const TetraEdge edge) const +{ + + // assert(edge < H01); + + // correspondance edge - triple products + // for edges OX, ..., ZX (Grandy, table III) + static const TetraCorner TRIPLE_PRODUCTS[12] = + { + X, O, // OX + Y, O, // OY + Z, O, // OZ + X, Y, // XY + Y, Z, // YZ + Z, X, // ZX + }; + + // Grandy, [16] + const double t1 = calcStableT(TRIPLE_PRODUCTS[2*edge]); + const double t2 = calcStableT(TRIPLE_PRODUCTS[2*edge + 1]); + + //? should equality with zero use epsilon? + LOG(5, "testEdgeIntersectsTriangle : t1 = " << t1 << " t2 = " << t2 ); + return (t1*t2 <= 0.0) && (t1 - t2 != 0.0); +} + +inline bool TransformedTriangle::testFacetSurroundsSegment(const TriSegment seg, const TetraFacet facet) const +{ +#if 0 + const double signs[3] = + { + SIGN_FOR_SEG_FACET_INTERSECTION[3*facet], + SIGN_FOR_SEG_FACET_INTERSECTION[3*facet + 1], + SIGN_FOR_SEG_FACET_INTERSECTION[3*facet + 2] + }; +#endif + + const double* signs = &SIGN_FOR_SEG_FACET_INTERSECTION[3*facet]; + const double c1 = signs[0]*calcStableC(seg, DP_FOR_SEG_FACET_INTERSECTION[3*facet]); + const double c2 = signs[1]*calcStableC(seg, DP_FOR_SEG_FACET_INTERSECTION[3*facet + 1]); + const double c3 = signs[2]*calcStableC(seg, DP_FOR_SEG_FACET_INTERSECTION[3*facet + 2]); + + return (c1*c3 > 0.0) && (c2*c3 > 0.0); +} + +inline bool TransformedTriangle::testSegmentIntersectsFacet(const TriSegment seg, const TetraFacet facet) const +{ + // use correspondance facet a = 0 <=> offset for coordinate a in _coords + // and also correspondance segment AB => corner A + const double coord1 = _coords[5*seg + facet]; + const double coord2 = _coords[5*( (seg + 1) % 3) + facet]; + + //? should we use epsilon-equality here in second test? + LOG(5, "coord1 : " << coord1 << " coord2 : " << coord2 ); + + return (coord1*coord2 <= 0.0) && (coord1 != coord2); +} + +inline bool TransformedTriangle::testSegmentIntersectsHPlane(const TriSegment seg) const +{ + // get the H - coordinates + const double coord1 = _coords[5*seg + 4]; + const double coord2 = _coords[5*( (seg + 1) % 3) + 4]; + //? should we use epsilon-equality here in second test? + LOG(5, "coord1 : " << coord1 << " coord2 : " << coord2 ); + + return (coord1*coord2 <= 0.0) && (coord1 != coord2); +} + +inline bool TransformedTriangle::testSurfaceAboveCorner(const TetraCorner corner) const +{ + // ? There seems to be an error in Grandy -> it should be C_XY instead of C_YZ in [28]. + // ? I haven't really figured out why, but it seems to work. + const double normal = calcStableC(PQ, C_XY) + calcStableC(QR, C_XY) + calcStableC(RP, C_XY); + + LOG(6, "surface above corner " << corner << " : " << "n = " << normal << ", t = [" << calcTByDevelopingRow(corner, 1, false) << ", " << calcTByDevelopingRow(corner, 2, false) << ", " << calcTByDevelopingRow(corner, 3, false) ); + LOG(6, "] - stable : " << calcStableT(corner) ); + + //? we don't care here if the triple product is "invalid", that is, the triangle does not surround one of the + // edges going out from the corner (Grandy [53]) + if(!_validTP[corner]) + { + return ( calcTByDevelopingRow(corner, 1, false) * normal ) >= 0.0; + } + else + { + return ( calcStableT(corner) * normal ) >= 0.0; + } +} + +inline bool TransformedTriangle::testTriangleSurroundsRay(const TetraCorner corner) const +{ + // assert(corner == X || corner == Y || corner == Z); + + // double products to use for the possible corners + static const DoubleProduct DP_FOR_RAY_INTERSECTION[4] = + { + DoubleProduct(0), // O - only here to fill out and make indices match + C_10, // X + C_01, // Y + C_XY // Z + }; + + const DoubleProduct dp = DP_FOR_RAY_INTERSECTION[corner]; + + const double cPQ = calcStableC(PQ, dp); + const double cQR = calcStableC(QR, dp); + const double cRP = calcStableC(RP, dp); + + //? NB here we have no correction for precision - is this good? + // Our authority Grandy says nothing + LOG(5, "dp in triSurrRay for corner " << corner << " = [" << cPQ << ", " << cQR << ", " << cRP << "]" ); + + return ( cPQ*cQR > 0.0 ) && ( cPQ*cRP > 0.0 ); + +} +#endif diff --git a/src/medtool/src/INTERP_KERNEL/TransformedTriangleIntersect.cxx b/src/medtool/src/INTERP_KERNEL/TransformedTriangleIntersect.cxx new file mode 100644 index 000000000..fa4c8a535 --- /dev/null +++ b/src/medtool/src/INTERP_KERNEL/TransformedTriangleIntersect.cxx @@ -0,0 +1,586 @@ +// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// + +#include "TransformedTriangle.hxx" +#include <iostream> +#include <fstream> +#include <cassert> +#include <cmath> +#include "VectorUtils.hxx" + +namespace INTERP_KERNEL +{ + + // ---------------------------------------------------------------------------------- + // Correspondance tables describing all the variations of formulas. + // ---------------------------------------------------------------------------------- + + /// \brief Correspondance between facets and double products. + /// + /// This table encodes Grandy, table IV. Use 3*facet + {0,1,2} as index + const TransformedTriangle::DoubleProduct TransformedTriangle::DP_FOR_SEG_FACET_INTERSECTION[12] = + { + C_XH, C_XY, C_ZX, // OYZ + C_YH, C_YZ, C_XY, // OZX + C_ZH, C_ZX, C_YZ, // OXY + C_XH, C_YH, C_ZH // XYZ + }; + + /// \brief Signs associated with entries in DP_FOR_SEGMENT_FACET_INTERSECTION. + /// + /// This table encodes Grandy, table IV. Use 3*facet + {0,1,2} as index + const double TransformedTriangle::SIGN_FOR_SEG_FACET_INTERSECTION[12] = + { + 1.0, 1.0, -1.0, + 1.0, 1.0, -1.0, + 1.0, 1.0, -1.0, + 1.0, 1.0, 1.0 + }; + + /// \brief Coordinates of corners of tetrahedron. + /// + /// Use 3*Corner + coordinate as index + const double TransformedTriangle::COORDS_TET_CORNER[12] = + { + 0.0, 0.0, 0.0, + 1.0, 0.0, 0.0, + 0.0, 1.0, 0.0, + 0.0, 0.0, 1.0 + }; + + /// \brief Indices to use in tables DP_FOR_SEG_FACET_INTERSECTION and SIGN_FOR_SEG_FACET_INTERSECTION + /// for the calculation of the coordinates (x,y,z) of the intersection points + /// for Segment-Facet and Segment-Edge intersections. + /// + /// Use 3*facet + coordinate as index. -1 indicates that the coordinate is 0. + const int TransformedTriangle::DP_INDEX[12] = + { + // x, y, z + -1, 1, 2, // OYZ + 5, -1, 4, // OZX + 7, 8, -1, // OXY + 9, 10, 11 // XYZ + }; + + /// \brief Correspondance edge - corners. + /// + /// Gives the two corners associated with each edge + /// Use 2*edge + {0, 1} as index + const TransformedTriangle::TetraCorner TransformedTriangle::CORNERS_FOR_EDGE[12] = + { + O, X, // OX + O, Y, // OY + O, Z, // OZ + X, Y, // XY + Y, Z, // YZ + Z, X // ZX + }; + + /// \brief Correspondance edge - facets. + /// + /// Gives the two facets shared by and edge. Use 2*facet + {0, 1} as index + const TransformedTriangle::TetraFacet TransformedTriangle::FACET_FOR_EDGE[12] = + { + OXY, OZX, // OX + OXY, OYZ, // OY + OZX, OYZ, // OZ + OXY, XYZ, // XY + OYZ, XYZ, // YZ + OZX, XYZ // ZX + }; + + /// \brief Correspondance corners - edges. + /// + /// Gives edges meeting at a given corner. Use 3*corner + {0,1,2} as index + const TransformedTriangle::TetraEdge TransformedTriangle::EDGES_FOR_CORNER[12] = + { + OX, OY, OZ, // O + OX, XY, ZX, // X + OY, XY, YZ, // Y + OZ, ZX, YZ // Z + }; + + /// \brief Double products to use in halfstrip intersection tests. + /// + /// Use 4*(offset_edge) + {0,1,2,3} as index. offset_edge = edge - 3 (so that XY -> 0, YZ -> 1, ZX -> 2) + /// Entries with offset 0 and 1 are for the first condition (positive product) + /// and those with offset 2 and 3 are for the second condition (negative product). + const TransformedTriangle::DoubleProduct TransformedTriangle::DP_FOR_HALFSTRIP_INTERSECTION[12] = + { + C_10, C_01, C_ZH, C_10, // XY + C_01, C_XY, C_XH, C_01, // YZ + C_XY, C_10, C_YH, C_XY // ZX + }; + + /// \brief Double products to use in segment-ray test. + /// + /// Use 7*corner_offset + {0,1,2,3,4,5,6} as index. corner_offset = corner - 1 (so that X -> 0, Y-> 1, Z->2) + /// Entries with offset 0 are for first condition (zero double product) and the rest are for condition 3 (in the same + /// order as in the article) + const TransformedTriangle::DoubleProduct TransformedTriangle::DP_SEGMENT_RAY_INTERSECTION[21] = + { + C_10, C_YH, C_ZH, C_01, C_XY, C_YH, C_XY, // X + C_01, C_XH, C_ZH, C_XY, C_10, C_ZH, C_10, // Y + C_XY, C_YH, C_XH, C_10, C_01, C_XH, C_01 // Z + }; + + /** + * Calculates the point of intersection between the given edge of the tetrahedron and the + * triangle PQR. (Grandy, eq [22]) + * + * @pre testSurfaceEdgeIntersection(edge) returns true + * @param edge edge of tetrahedron + * @param pt array of three doubles in which to store the coordinates of the intersection point + */ + void TransformedTriangle::calcIntersectionPtSurfaceEdge(const TetraEdge edge, double* pt) const + { + assert(edge < H01); + + // barycentric interpolation between points A and B + // : (x,y,z)* = (1-alpha)*A + alpha*B where + // alpha = t_A / (t_A - t_B) + + const TetraCorner corners[2] = + { + CORNERS_FOR_EDGE[2*edge], + CORNERS_FOR_EDGE[2*edge + 1] + }; + + // calculate alpha + const double tA = calcStableT(corners[0]); + const double tB = calcStableT(corners[1]); + const double alpha = tA / (tA - tB); + + // calculate point + LOG(4, "corner A = " << corners[0] << " corner B = " << corners[1] ); + LOG(4, "tA = " << tA << " tB = " << tB << " alpha= " << alpha ); + for(int i = 0; i < 3; ++i) + { + + pt[i] = (1 - alpha) * COORDS_TET_CORNER[3*corners[0] + i] + + alpha * COORDS_TET_CORNER[3*corners[1] + i]; +#if 0 + pt[i] = (1 - alpha) * getCoordinateForTetCorner<corners[0], i>() + + alpha * getCoordinateForTetCorner<corners[0], i>(); +#endif + LOG(6, pt[i] ); + assert(pt[i] >= 0.0); + assert(pt[i] <= 1.0); + } + } + + /** + * Calculates the point of intersection between the given segment of the triangle + * and the given facet of the tetrahedron. (Grandy, eq. [23]) + * + * @pre testSurfaceEdgeIntersection(seg, facet) returns true + * + * @param seg segment of the triangle + * @param facet facet of the tetrahedron + * @param pt array of three doubles in which to store the coordinates of the intersection point + */ + void TransformedTriangle::calcIntersectionPtSegmentFacet(const TriSegment seg, const TetraFacet facet, double* pt) const + { + // calculate s + double s = 0.0; + for(int i = 0; i < 3; ++i) + { + const DoubleProduct dp = DP_FOR_SEG_FACET_INTERSECTION[3*facet + i]; + const double sign = SIGN_FOR_SEG_FACET_INTERSECTION[3*facet + i]; + s -= sign * calcStableC(seg, dp); + } + + assert(s != 0.0); + + // calculate coordinates of intersection point + for(int i = 0 ; i < 3; ++i) + { + const int dpIdx = DP_INDEX[3*facet + i]; + + if(dpIdx < 0) + { + pt[i] = 0.0; + } + else + { + const DoubleProduct dp = DP_FOR_SEG_FACET_INTERSECTION[dpIdx]; + const double sign = SIGN_FOR_SEG_FACET_INTERSECTION[dpIdx]; + pt[i] = -( sign * calcStableC(seg, dp) ) / s; + + LOG(4, "SegmentFacetIntPtCalc : pt[" << i << "] = " << pt[i] ); + LOG(4, "c(" << seg << ", " << dp << ") = " << sign * calcStableC(seg, dp) ); + assert(pt[i] >= 0.0); + assert(pt[i] <= 1.0); + } + } + + } + + /** + * Tests if the given segment of the triangle intersects the given edge of the tetrahedron (Grandy, eq. [20] + * If the OPTIMIZE is defined, it does not do the test the double product that should be zero. + * @param seg segment of the triangle + * @param edge edge of tetrahedron + * @return true if the segment intersects the edge + */ + bool TransformedTriangle::testSegmentEdgeIntersection(const TriSegment seg, const TetraEdge edge) const + { + { + // check condition that the double products for one of the two + // facets adjacent to the edge has a positive product + bool isFacetCondVerified = false; + TetraFacet facet[2]; + for(int i = 0 ; i < 2 ; ++i) + { + facet[i] = FACET_FOR_EDGE[2*edge + i]; + + // find the two c-values -> the two for the other edges of the facet + int idx1 = 0 ; + int idx2 = 1; + DoubleProduct dp1 = DP_FOR_SEG_FACET_INTERSECTION[3*facet[i] + idx1]; + DoubleProduct dp2 = DP_FOR_SEG_FACET_INTERSECTION[3*facet[i] + idx2]; + + if(dp1 == DoubleProduct( edge )) + { + idx1 = 2; + dp1 = DP_FOR_SEG_FACET_INTERSECTION[3*facet[i] + idx1]; + } + else if(dp2 == DoubleProduct( edge )) + { + idx2 = 2; + dp2 = DP_FOR_SEG_FACET_INTERSECTION[3*facet[i] + idx2]; + } + + const double c1 = SIGN_FOR_SEG_FACET_INTERSECTION[3*facet[i] + idx1]*calcStableC(seg, dp1); + const double c2 = SIGN_FOR_SEG_FACET_INTERSECTION[3*facet[i] + idx2]*calcStableC(seg, dp2); + + //isFacetCondVerified = isFacetCondVerified || c1*c2 > 0.0; + if(c1*c2 > 0.0) + { + isFacetCondVerified = true; + } + } + + if(!isFacetCondVerified) + { + return false; + } + else + { + return testSegmentIntersectsFacet(seg, facet[0]) || testSegmentIntersectsFacet(seg, facet[1]); + } + } + } + + /** + * Calculates the point of intersection between the given segment of the triangle + * and the given edge of the tetrahedron. (Grandy, eq. [25]) + * + * @pre testSegmentEdgeIntersection(seg, edge) returns true + * + * @param seg segment of the triangle + * @param edge edge of the tetrahedron + * @param pt array of three doubles in which to store the coordinates of the intersection point + */ + void TransformedTriangle::calcIntersectionPtSegmentEdge(const TriSegment seg, const TetraEdge edge, double* pt) const + { + assert(edge < H01); + + // get the two facets associated with the edge + static const TetraFacet FACETS_FOR_EDGE[12] = + { + OXY, OZX, // OX + OXY, OYZ, // OY + OZX, OYZ, // OZ + OXY, XYZ, // XY + OYZ, XYZ, // YZ + OZX, XYZ // ZX + }; + + const TetraFacet facets[2] = + { + FACETS_FOR_EDGE[2*edge], + FACETS_FOR_EDGE[2*edge + 1] + }; + + // calculate s for the two edges + double s[2]; + for(int i = 0; i < 2; ++i) + { + s[i] = 0.0; + for(int j = 0; j < 3; ++j) + { + const DoubleProduct dp = DP_FOR_SEG_FACET_INTERSECTION[3*facets[i] + j]; + const double sign = SIGN_FOR_SEG_FACET_INTERSECTION[3*facets[i] + j]; + s[i] += sign * calcStableC(seg, dp); + } + } + + // calculate denominator + const double denominator = s[0]*s[0] + s[1]*s[1]; + + // calculate intersection point + for(int i = 0; i < 3; ++i) + { + // calculate double product values for the two faces + double c[2]; + for(int j = 0 ; j < 2; ++j) + { + const int dpIdx = DP_INDEX[3*facets[j] + i]; + const DoubleProduct dp = DP_FOR_SEG_FACET_INTERSECTION[dpIdx]; + const double sign = SIGN_FOR_SEG_FACET_INTERSECTION[dpIdx]; + c[j] = dpIdx < 0.0 ? 0.0 : sign * calcStableC(seg, dp); + } + + // pt[i] = (c1*s1 + c2*s2) / (s1^2 + s2^2) + + pt[i] = (c[0] * s[0] + c[1] * s[1]) / denominator; + + // strange bug with -O2 enabled : assertion fails when we don't have the following + // trace - line + //std::cout << "pt[i] = " << pt[i] << std::endl; + //assert(pt[i] >= 0.0); // check we are in tetraeder + //assert(pt[i] <= 1.0); + + } + } + + + /** + * Tests if the given segment of the triangle intersects the given corner of the tetrahedron. + * (Grandy, eq. [21]). If OPTIMIZE is defined, the double products that should be zero are not verified. + * + * @param seg segment of the triangle + * @param corner corner of the tetrahedron + * @return true if the segment intersects the corner + */ + bool TransformedTriangle::testSegmentCornerIntersection(const TriSegment seg, const TetraCorner corner) const + { + + + // facets meeting at a given corner + static const TetraFacet FACETS_FOR_CORNER[12] = + { + OXY, OYZ, OZX, // O + OZX, OXY, XYZ, // X + OYZ, XYZ, OXY, // Y + OZX, XYZ, OYZ // Z + }; + + // check segment intersect a facet + for(int i = 0 ; i < 3 ; ++i) + { + const TetraFacet facet = FACETS_FOR_CORNER[3*corner + i]; + if(testSegmentIntersectsFacet(seg, facet)) + { + return true; + } + } + + return false; + } + + /** + * Tests if the given segment of the triangle intersects the half-strip above the + * given edge of the h = 0 plane. (Grandy, eq. [30]) + * + * @param seg segment of the triangle + * @param edge edge of the h = 0 plane of the tetrahedron (XY, YZ, ZX) + * @return true if the upwards ray from the corner intersects the triangle. + */ + bool TransformedTriangle::testSegmentHalfstripIntersection(const TriSegment seg, const TetraEdge edge) + { + // get right index here to avoid "filling out" array + const int edgeIndex = static_cast<int>(edge) - 3; + + // double products used in test + // products 1 and 2 for each edge -> first condition in Grandy [30] + // products 3 and 4 for each edge -> third condition + // NB : some uncertainty whether these last are correct + // DP_FOR_HALFSTRIP_INTERSECTION + + // facets to use in second condition (S_m) + static const TetraFacet FACET_FOR_HALFSTRIP_INTERSECTION[3] = + { + NO_TET_FACET, // XY -> special case : test with plane H = 0 + OYZ, // YZ + OZX // ZX + }; + + const double cVals[4] = + { + calcStableC(seg, DP_FOR_HALFSTRIP_INTERSECTION[4*edgeIndex]), + calcStableC(seg, DP_FOR_HALFSTRIP_INTERSECTION[4*edgeIndex + 1]), + calcStableC(seg, DP_FOR_HALFSTRIP_INTERSECTION[4*edgeIndex + 2]), + calcStableC(seg, DP_FOR_HALFSTRIP_INTERSECTION[4*edgeIndex + 3]) + }; + + const TetraFacet facet = FACET_FOR_HALFSTRIP_INTERSECTION[edgeIndex]; + + + // special case : facet H = 0 + const bool cond2 = (facet == NO_TET_FACET) ? testSegmentIntersectsHPlane(seg) : testSegmentIntersectsFacet(seg, facet); + LOG(4, "Halfstrip tests (" << seg << ", " << edge << ") : " << (cVals[0]*cVals[1] < 0.0) << ", " << cond2 << ", " << (cVals[2]*cVals[3] > 0.0) ); + LOG(4, "c2 = " << cVals[2] << ", c3 = " << cVals[3] ); + + return (cVals[0]*cVals[1] < 0.0) && cond2 && (cVals[2]*cVals[3] > 0.0); + } + + /** + * Calculates the point of intersection between the given segment of the triangle + * and the halfstrip above the given edge of the tetrahedron. (Grandy, eq. [31]) + * + * @pre testSegmentHalfstripIntersection(seg, edge) returns true + * + * @param seg segment of the triangle + * @param edge edge of the tetrahedron defining the halfstrip + * @param pt array of three doubles in which to store the coordinates of the intersection point + */ + void TransformedTriangle::calcIntersectionPtSegmentHalfstrip(const TriSegment seg, const TetraEdge edge, double* pt) const + { + assert(edge > OZ); + assert(edge < H01); + + // get right index here to avoid "filling out" array + const int edgeIndex = static_cast<int>(edge) - 3; + assert(edgeIndex >= 0); + assert(edgeIndex < 3); + + // Barycentric interpolation on the edge + // for edge AB : (x,y,z)* = (1-alpha) * A + alpha * B + // where alpha = cB / (cB - cA) + + const double cA = calcStableC(seg, DP_FOR_HALFSTRIP_INTERSECTION[4*edgeIndex]); + const double cB = calcStableC(seg, DP_FOR_HALFSTRIP_INTERSECTION[4*edgeIndex + 1]); + assert(cA != cB); + + const double alpha = cA / (cA - cB); + + for(int i = 0; i < 3; ++i) + { + const TetraCorner corners[2] = + { + CORNERS_FOR_EDGE[2*edge], + CORNERS_FOR_EDGE[2*edge + 1] + }; + + const double cornerCoords[2] = + { + COORDS_TET_CORNER[3*corners[0] + i], + COORDS_TET_CORNER[3*corners[1] + i] + }; + + pt[i] = (1 - alpha) * cornerCoords[0] + alpha * cornerCoords[1]; + LOG(6, pt[i] ); + assert(pt[i] >= 0.0); + assert(pt[i] <= 1.0); + } + assert(epsilonEqualRelative(pt[0] + pt[1] + pt[2], 1.0)); + } + + /** + * Tests if the given segment of triangle PQR intersects the ray pointing + * in the upwards z - direction from the given corner of the tetrahedron. (Grandy eq. [29]) + * If OPTIMIZE is defined, the double product that should be zero is not verified. + * + * @param seg segment of the triangle PQR + * @param corner corner of the tetrahedron on the h = 0 facet (X, Y, or Z) + * @return true if the upwards ray from the corner intersects the segment. + */ + bool TransformedTriangle::testSegmentRayIntersection(const TriSegment seg, const TetraCorner corner) const + { + assert(corner == X || corner == Y || corner == Z); + LOG(4, "Testing seg - ray intersection for seg = " << seg << ", corner = " << corner ); + + // readjust index since O is not used + const int cornerIdx = static_cast<int>(corner) - 1; + + // facets to use + //? not sure this is correct + static const TetraFacet FIRST_FACET_SEGMENT_RAY_INTERSECTION[3] = + { + OZX, // X + OYZ, // Y + OZX, // Z + }; + + // cond 2 + const bool cond21 = testSegmentIntersectsFacet(seg, FIRST_FACET_SEGMENT_RAY_INTERSECTION[cornerIdx]); + const bool cond22 = (corner == Z) ? testSegmentIntersectsFacet(seg, OYZ) : testSegmentIntersectsHPlane(seg); + + if(!(cond21 || cond22)) + { + LOG(4, "SR fails at cond 2 : cond21 = " << cond21 << ", cond22 = " << cond22 ); + return false; + } + + // cond 3 + const double cVals[6] = + { + calcStableC(seg, DP_SEGMENT_RAY_INTERSECTION[7*cornerIdx + 1]), + calcStableC(seg, DP_SEGMENT_RAY_INTERSECTION[7*cornerIdx + 2]), + calcStableC(seg, DP_SEGMENT_RAY_INTERSECTION[7*cornerIdx + 3]), + calcStableC(seg, DP_SEGMENT_RAY_INTERSECTION[7*cornerIdx + 4]), + calcStableC(seg, DP_SEGMENT_RAY_INTERSECTION[7*cornerIdx + 5]), + calcStableC(seg, DP_SEGMENT_RAY_INTERSECTION[7*cornerIdx + 6]), + }; + + // cond. 3 + if(( (cVals[0] + cVals[1])*(cVals[2] - cVals[3]) - cVals[4]*cVals[5] ) >= 0.0) + { + LOG(4, "SR fails at cond 3 : " << (cVals[0] + cVals[1])*(cVals[2] - cVals[3]) - cVals[4]*cVals[5] ); + } + return ( (cVals[0] + cVals[1])*(cVals[2] - cVals[3]) - cVals[4]*cVals[5] ) < 0.0; + + } + + // ///////////////////////////////////////////////////////////////////////////////// + // Utility methods used in intersection tests /////////////// + // ///////////////////////////////////////////////////////////////////////////////// + /** + * Tests if the triangle PQR surrounds the axis on which the + * given edge of the tetrahedron lies. + * + * @param edge edge of tetrahedron + * @return true if PQR surrounds edge, false if not (see Grandy, eq. [53]) + */ + bool TransformedTriangle::testTriangleSurroundsEdge(const TetraEdge edge) const + { + // NB DoubleProduct enum corresponds to TetraEdge enum according to Grandy, table III + // so we can use the edge directly + + const double cPQ = calcStableC(PQ, DoubleProduct(edge)); + const double cQR = calcStableC(QR, DoubleProduct(edge)); + const double cRP = calcStableC(RP, DoubleProduct(edge)); + + LOG(5, "TriangleSurroundsEdge : edge = " << edge << " c = [" << cPQ << ", " << cQR << ", " << cRP << "]" ); + + // if two or more c-values are zero we disallow x-edge intersection + // Grandy, p.446 + const int numZeros = (cPQ == 0.0 ? 1 : 0) + (cQR == 0.0 ? 1 : 0) + (cRP == 0.0 ? 1 : 0); + + if(numZeros >= 2 ) + { + LOG(5, "TriangleSurroundsEdge test fails due to too many 0 dp" ); + } + + return (cPQ*cQR >= 0.0) && (cQR*cRP >= 0.0) && (cRP*cPQ >= 0.0) && numZeros < 2; + } + +} // NAMESPACE diff --git a/src/medtool/src/INTERP_KERNEL/TransformedTriangleMath.cxx b/src/medtool/src/INTERP_KERNEL/TransformedTriangleMath.cxx new file mode 100644 index 000000000..b61edc1cd --- /dev/null +++ b/src/medtool/src/INTERP_KERNEL/TransformedTriangleMath.cxx @@ -0,0 +1,503 @@ +// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// + +#include "TransformedTriangle.hxx" +#include <iostream> +#include <fstream> +#include <cassert> +#include <cmath> +#include <limits> +#include <map> +#include <utility> + +#include "VectorUtils.hxx" + +namespace INTERP_KERNEL +{ + + // ---------------------------------------------------------------------------------- + // Tables + // ---------------------------------------------------------------------------------- + + /// Table with first coordinate (a) used to calculate double product c^pq_ab = p_a * q_b - p_b * q_a (index to be used : DoubleProduct) + const int TransformedTriangle::DP_OFFSET_1[8] = {1, 2, 0, 2, 0, 1, 4, 1}; + + /// Table with second coordinate (b) used to calculate double product c^pq_ab = p_a * q_b - p_b * q_a (index to be used : DoubleProduct) + const int TransformedTriangle::DP_OFFSET_2[8] = {2, 0, 1, 3, 3, 3, 0, 4}; + + /// Coordinates used to calculate triple products by the expanding one of the three rows of the determinant (index to be used : 3*Corner + row) + const int TransformedTriangle::COORDINATE_FOR_DETERMINANT_EXPANSION[12] = + { + // row 1, 2, 3 + 0, 1, 2, // O + 3, 1, 2, // X + 0, 3, 2, // Y + 0, 1, 3 // Z + }; + + /// Double products used to calculate triple products by expanding one of the three rows of the determinant (index to be used : 3*Corner + row) + const TransformedTriangle::DoubleProduct TransformedTriangle::DP_FOR_DETERMINANT_EXPANSION[12] = + { + // row 1, 2, 3 + C_YZ, C_ZX, C_XY, // O + C_YZ, C_ZH, C_YH, // X + C_ZH, C_ZX, C_XH, // Y + C_YH, C_XH, C_XY // Z + }; + + /// The machine epsilon, used in precision corrections + const long double TransformedTriangle::MACH_EPS = std::numeric_limits<double>::epsilon(); + + /// 4.0 * the machine epsilon, represents the precision of multiplication when performing corrections corrections ( f in Grandy ) + const long double TransformedTriangle::MULT_PREC_F = 4.0 * TransformedTriangle::MACH_EPS; + + /// Threshold for resetting double and triple products to zero; ( F / f in Grandy ) + const long double TransformedTriangle::THRESHOLD_F = 500.0; + + /// Threshold for what is considered a small enough angle to warrant correction of triple products by Grandy, [57] + const double TransformedTriangle::TRIPLE_PRODUCT_ANGLE_THRESHOLD = 0.1; + + + // after transformation to the U-space, coordinates are inaccurate + // small variations around zero should not be taken into account + void TransformedTriangle::resetNearZeroCoordinates() + { + for (int i=0; i<15; i++) + if (fabs(_coords[i])<TransformedTriangle::MACH_EPS*20.0) _coords[i]=0.0; + } + + // ---------------------------------------------------------------------------------- + // Double and triple product calculations + // ---------------------------------------------------------------------------------- + + /** + * Pre-calculates all double products for this triangle, and stores + * them internally. This method makes compensation for precision errors, + * and it is thus the "stable" double products that are stored. + * + */ + void TransformedTriangle::preCalculateDoubleProducts(void) + { + if(_is_double_products_calculated) + return; + + // -- calculate all unstable double products -- store in _doubleProducts + for(TriSegment seg = PQ ; seg <= RP ; seg = TriSegment(seg + 1)) + { + for(DoubleProduct dp = C_YZ ; dp <= C_10 ; dp = DoubleProduct(dp + 1)) + _doubleProducts[8*seg + dp] = calcUnstableC(seg, dp); + } + + std::map<double, TetraCorner> distances; + + // -- (1) for each segment : check that double products satisfy Grandy, [46] + // -- and make corrections if not + for(TriSegment seg = PQ ; seg <= RP ; seg = TriSegment(seg + 1)) + { + if(!areDoubleProductsConsistent(seg)) + { + LOG(4, "inconsistent! "); + for(TetraCorner corner = O ; corner <= Z ; corner = TetraCorner(corner + 1)) + { + // calculate distance corner - segment axis + const double dist = calculateDistanceCornerSegment(corner, seg); + distances.insert( std::make_pair( dist, corner ) ); + } + + // first element -> minimum distance + const TetraCorner minCorner = distances.begin()->second; + resetDoubleProducts(seg, minCorner); + distances.clear(); + } + } + + // -- (2) check that each double product statisfies Grandy, [47], else set to 0 + for(TriSegment seg = PQ ; seg <= RP ; seg = TriSegment(seg + 1)) + { + for(DoubleProduct dp = C_YZ ; dp <= C_10 ; dp = DoubleProduct(dp + 1)) + { + // find the points of the triangle + // 0 -> P, 1 -> Q, 2 -> R + const int pt1 = seg; + const int pt2 = (seg + 1) % 3; + + // find offsets + const int off1 = DP_OFFSET_1[dp]; + const int off2 = DP_OFFSET_2[dp]; + + const double term1 = _coords[5*pt1 + off1] * _coords[5*pt2 + off2]; + const double term2 = _coords[5*pt1 + off2] * _coords[5*pt2 + off1]; + + const long double delta = MULT_PREC_F * ( std::fabs(term1) + std::fabs(term2) ); + + if( epsilonEqual(_doubleProducts[8*seg + dp], 0.0, THRESHOLD_F * delta)) + { + // debug output +#if LOG_LEVEL >= 5 + if(_doubleProducts[8*seg + dp] != 0.0) + { + LOG(5, "Double product for (seg,dp) = (" << seg << ", " << dp << ") = " ); + LOG(5, std::fabs(_doubleProducts[8*seg + dp]) << " is imprecise, reset to 0.0" ); + } +#endif + + + _doubleProducts[8*seg + dp] = 0.0; + + } + } + } + + _is_double_products_calculated = true; + } + + /** + * Checks if the double products for a given segment are consistent, as defined by + * Grandy, [46]. + * + * @param seg Segment for which to check consistency of double products + * @return true if the double products are consistent, false if not + */ + bool TransformedTriangle::areDoubleProductsConsistent(const TriSegment seg) const + { + const double term1 = _doubleProducts[8*seg + C_YZ] * _doubleProducts[8*seg + C_XH]; + const double term2 = _doubleProducts[8*seg + C_ZX] * _doubleProducts[8*seg + C_YH]; + const double term3 = _doubleProducts[8*seg + C_XY] * _doubleProducts[8*seg + C_ZH]; + + LOG(2, "for seg " << seg << " consistency " << term1 + term2 + term3 ); + LOG(2, "term1 :" << term1 << " term2 :" << term2 << " term3: " << term3 ); + + const int num_zero = (term1 == 0.0 ? 1 : 0) + (term2 == 0.0 ? 1 : 0) + (term3 == 0.0 ? 1 : 0); + const int num_neg = (term1 < 0.0 ? 1 : 0) + (term2 < 0.0 ? 1 : 0) + (term3 < 0.0 ? 1 : 0); + const int num_pos = (term1 > 0.0 ? 1 : 0) + (term2 > 0.0 ? 1 : 0) + (term3 > 0.0 ? 1 : 0); + + assert( num_zero + num_neg + num_pos == 3 ); + + // calculated geometry is inconsistent if we have one of the following cases + // * one term zero and the other two of the same sign + // * two terms zero + // * all terms positive + // * all terms negative + if(((num_zero == 1 && num_neg != 1) || num_zero == 2 || (num_neg == 0 && num_zero != 3) || num_neg == 3 )) + { + LOG(4, "inconsistent dp found" ); + } + return !((num_zero == 1 && num_neg != 1) || num_zero == 2 || (num_neg == 0 && num_zero != 3) || num_neg == 3 ); + + } + + /** + * Calculate the shortest distance between a tetrahedron corner and a triangle segment. + * + * @param corner corner of the tetrahedron + * @param seg segment of the triangle + * @return shortest distance from the corner to the segment + */ + double TransformedTriangle::calculateDistanceCornerSegment(const TetraCorner corner, const TriSegment seg) const + { + // NB uses fact that TriSegment <=> TriCorner that is first point of segment (PQ <=> P) + const TriCorner ptP_idx = TriCorner(seg); + const TriCorner ptQ_idx = TriCorner( (seg + 1) % 3); + + const double ptP[3] = { _coords[5*ptP_idx], _coords[5*ptP_idx + 1], _coords[5*ptP_idx + 2] }; + const double ptQ[3] = { _coords[5*ptQ_idx], _coords[5*ptQ_idx + 1], _coords[5*ptQ_idx + 2] }; + + // coordinates of corner + const double ptTetCorner[3] = + { + COORDS_TET_CORNER[3*corner ], + COORDS_TET_CORNER[3*corner + 1], + COORDS_TET_CORNER[3*corner + 2] + }; + + // dist^2 = ( PQ x CP )^2 / |PQ|^2 where C is the corner point + + // difference vectors + const double diffPQ[3] = { ptQ[0] - ptP[0], ptQ[1] - ptP[1], ptQ[2] - ptP[2] }; + const double diffCornerP[3] = { ptP[0] - ptTetCorner[0], ptP[1] - ptTetCorner[1], ptP[2] - ptTetCorner[2] }; + + // cross product of difference vectors + double crossProd[3]; + cross(diffPQ, diffCornerP, crossProd); + + const double cross_squared = dot(crossProd, crossProd); + const double norm_diffPQ_squared = dot(diffPQ, diffPQ); + + assert(norm_diffPQ_squared != 0.0); + + return cross_squared / norm_diffPQ_squared; + } + + /** + * Pre-calculates all triple products for the tetrahedron with respect to + * this triangle, and stores them internally. This method takes into account + * the problem of errors due to cancellation. + * + */ + void TransformedTriangle::preCalculateTripleProducts(void) + { + if(_is_triple_products_calculated) + { + return; + } + + // find edge / row to use -> that whose edge makes the smallest angle to the triangle + // use a map to find the minimum + std::map<double, int> anglesForRows; + + LOG(4, "Precalculating triple products" ); + for(TetraCorner corner = O ; corner <= Z ; corner = TetraCorner(corner + 1)) + { + LOG(6, "- Triple product for corner " << corner ); + + for(int row = 1 ; row < 4 ; ++row) + { + const DoubleProduct dp = DP_FOR_DETERMINANT_EXPANSION[3*corner + (row - 1)]; + + // get edge by using correspondance between Double Product and Edge + TetraEdge edge = TetraEdge(dp); + + // use edge only if it is surrounded by the surface + if( _triangleSurroundsEdgeCache[edge] ) + { + // -- calculate angle between edge and PQR + const double angle = calculateAngleEdgeTriangle(edge); + anglesForRows.insert(std::make_pair(angle, row)); + } + } + + if(anglesForRows.size() != 0) // we have found a good row + { + const double minAngle = anglesForRows.begin()->first; + const int minRow = anglesForRows.begin()->second; + + if(minAngle < TRIPLE_PRODUCT_ANGLE_THRESHOLD) + { + _tripleProducts[corner] = calcTByDevelopingRow(corner, minRow, true); + } + else + { + _tripleProducts[corner] = calcTByDevelopingRow(corner, minRow, false); + } + _validTP[corner] = true; + } + else + { + // this value will not be used + // we set it to whatever + LOG(6, "Triple product not calculated for corner " << corner ); + _tripleProducts[corner] = -3.14159265; + _validTP[corner] = false; + + } + anglesForRows.clear(); + + } + + _is_triple_products_calculated = true; + } + + /** + * Calculates the angle between an edge of the tetrahedron and the triangle + * + * @param edge edge of the tetrahedron + * @return angle between triangle and edge + */ + double TransformedTriangle::calculateAngleEdgeTriangle(const TetraEdge edge) const + { + // find normal to PQR - cross PQ and PR + const double pq[3] = + { + _coords[5*Q] - _coords[5*P], + _coords[5*Q + 1] - _coords[5*P + 1], + _coords[5*Q + 2] - _coords[5*P + 2] + }; + + const double pr[3] = + { + _coords[5*R] - _coords[5*P], + _coords[5*R + 1] - _coords[5*P + 1], + _coords[5*R + 2] - _coords[5*P + 2] + }; + + double normal[3]; + + cross(pq, pr, normal); + + static const double EDGE_VECTORS[18] = + { + 1.0, 0.0, 0.0, // OX + 0.0, 1.0, 0.0, // OY + 0.0, 0.0, 1.0, // OZ + -1.0, 1.0, 0.0, // XY + 0.0,-1.0, 1.0, // YZ + 1.0, 0.0,-1.0 // ZX + }; + + const double edgeVec[3] = { + EDGE_VECTORS[3*edge], + EDGE_VECTORS[3*edge + 1], + EDGE_VECTORS[3*edge + 2], + }; + + //return angleBetweenVectors(normal, edgeVec); + + const double lenNormal = norm(normal); + const double lenEdgeVec = norm(edgeVec); + const double dotProd = dot(normal, edgeVec); + + //? is this more stable? -> no subtraction + // return asin( dotProd / ( lenNormal * lenEdgeVec ) ) + 3.141592625358979 / 2.0; + double tmp=dotProd / ( lenNormal * lenEdgeVec ); + tmp=std::max(tmp,-1.); + tmp=std::min(tmp,1.); + return atan(1.0)*4.0 - acos(tmp); + + } + + /** + * Calculates triple product associated with the given corner of tetrahedron, developing + * the determinant by the given row. The triple product gives the signed volume of + * the tetrahedron between this corner and the triangle PQR. If the flag project is true, + * one coordinate is projected out in order to eliminate errors in the intersection point + * calculation due to cancellation. + * + * @pre double products have already been calculated + * @param corner corner for which the triple product is calculated + * @param row row (1 <= row <= 3) used to calculate the determinant + * @param project indicates whether or not to perform projection as inidicated in Grandy, p.446 + * @return triple product associated with corner (see Grandy, [50]-[52]) + */ + double TransformedTriangle::calcTByDevelopingRow(const TetraCorner corner, const int row, const bool project) const + { + + // OVERVIEW OF CALCULATION + // --- sign before the determinant + // the sign used depends on the sign in front of the triple product (Grandy, [15]), + // and the convention used in the definition of the double products + + // the sign in front of the determinant gives the following schema for the three terms (I): + // corner/row 1 2 3 + // O (sign:+) + - + + // X (sign:-) - + - + // Y (sign:-) - + - + // Z (sign:-) - + - + + // the 2x2 determinants are the following (C_AB <=> A_p*B_q - B_p*A_q, etc) + // corner/row 1 2 3 + // O (sign:+) C_YZ C_XZ C_XY + // X (sign:-) C_YZ C_HZ C_HY + // Y (sign:-) C_HZ C_XZ C_XH + // Z (sign:-) C_YH C_XH C_XY + + // these are represented in DP_FOR_DETERMINANT_EXPANSION, + // except for the fact that certain double products are inversed (C_AB <-> C_BA) + + // comparing with the DOUBLE_PRODUCTS and using the fact that C_AB = -C_BA + // we deduce the following schema (II) : + // corner/row 1 2 3 + // O (sign:+) + - + + // X (sign:-) + - - + // Y (sign:-) - - + + // Z (sign:-) + + + + + // comparing the two schemas (I) and (II) gives us the following matrix of signs, + // putting 1 when the signs in (I) and (II) are equal and -1 when they are different : + + static const int SIGNS[12] = + { + 1, 1, 1, + -1,-1, 1, + 1,-1,-1, + -1, 1,-1 + }; + + // find the offsets of the rows of the determinant + const int offset = COORDINATE_FOR_DETERMINANT_EXPANSION[3 * corner + (row - 1)]; + + const DoubleProduct dp = DP_FOR_DETERMINANT_EXPANSION[3 * corner + (row - 1)]; + + const int sign = SIGNS[3 * corner + (row - 1)]; + + const double cQR = calcStableC(QR, dp); + const double cRP = calcStableC(RP, dp); + const double cPQ = calcStableC(PQ, dp); + + double alpha = 0.0; + + // coordinate to use for projection (Grandy, [57]) with edges + // OX, OY, OZ, XY, YZ, ZX in order : + // (y, z, x, h, h, h) + // for the first three we could also use {2, 0, 1} + static const int PROJECTION_COORDS[6] = { 1, 2, 0, 3, 3, 3 } ; + + const int coord = PROJECTION_COORDS[ dp ]; + + // coordinate values for P, Q and R + const double coordValues[3] = { _coords[5*P + coord], _coords[5*Q + coord], _coords[5*R + coord] }; + + if(project) + { + // products coordinate values with corresponding double product + const double coordDPProd[3] = { coordValues[0] * cQR, coordValues[1] * cRP, coordValues[2] * cPQ }; + + const double sumDPProd = coordDPProd[0] + coordDPProd[1] + coordDPProd[2]; + const double sumDPProdSq = dot(coordDPProd, coordDPProd); + + // alpha = sumDPProd / sumDPProdSq; + alpha = (sumDPProdSq != 0.0) ? sumDPProd / sumDPProdSq : 0.0; + } + + const double cQRbar = cQR * (1.0 - alpha * coordValues[0] * cQR); + const double cRPbar = cRP * (1.0 - alpha * coordValues[1] * cRP); + const double cPQbar = cPQ * (1.0 - alpha * coordValues[2] * cPQ); + + // check sign of barred products - should not change + // assert(cQRbar * cQR >= 0.0); + //assert(cRPbar * cRP >= 0.0); + //assert(cPQbar * cPQ >= 0.0); + + const double p_term = _coords[5*P + offset] * cQRbar; + const double q_term = _coords[5*Q + offset] * cRPbar; + const double r_term = _coords[5*R + offset] * cPQbar; + + // check that we are not so close to zero that numerical errors could take over, + // otherwise reset to zero (cf Grandy, p. 446) +#ifdef FIXED_DELTA + const double delta = FIXED_DELTA; +#else + const long double delta = MULT_PREC_F * (std::fabs(p_term) + std::fabs(q_term) + std::fabs(r_term)); +#endif + + if( epsilonEqual( p_term + q_term + r_term, 0.0, THRESHOLD_F * delta) ) + { + LOG(4, "Reset imprecise triple product for corner " << corner << " to zero" ); + return 0.0; + } + else + { + // NB : using plus also for the middle term compensates for a double product + // which is inversely ordered + LOG(6, "Triple product for corner " << corner << ", row " << row << " = " << sign*( p_term + q_term + r_term ) ); + return sign*( p_term + q_term + r_term ); + } + + } + +} diff --git a/src/medtool/src/INTERP_KERNEL/TranslationRotationMatrix.cxx b/src/medtool/src/INTERP_KERNEL/TranslationRotationMatrix.cxx new file mode 100644 index 000000000..345df1096 --- /dev/null +++ b/src/medtool/src/INTERP_KERNEL/TranslationRotationMatrix.cxx @@ -0,0 +1,22 @@ +// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// + +#include "TranslationRotationMatrix.hxx" + +const double INTERP_KERNEL::TranslationRotationMatrix::EPS=1e-12; diff --git a/src/medtool/src/INTERP_KERNEL/TranslationRotationMatrix.hxx b/src/medtool/src/INTERP_KERNEL/TranslationRotationMatrix.hxx new file mode 100644 index 000000000..a0e4a0ebc --- /dev/null +++ b/src/medtool/src/INTERP_KERNEL/TranslationRotationMatrix.hxx @@ -0,0 +1,132 @@ +// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 +// 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 __TRANSLATIONROTATIONMATRIX_HXX__ +#define __TRANSLATIONROTATIONMATRIX_HXX__ + +#include "INTERPKERNELDefines.hxx" + +#include <cmath> + +namespace INTERP_KERNEL +{ + class INTERPKERNEL_EXPORT TranslationRotationMatrix + { + + public: + + TranslationRotationMatrix() + { + unsigned i; + for(i=0;i<TRANSL_SIZE;i++) + _translation_coeffs[i]=0.; + for(i=0;i<ROT_SIZE;i++) + _rotation_coeffs[i]=i%4?0.:1.; + } + + void multiply(const TranslationRotationMatrix& A) + { + TranslationRotationMatrix result; + //setting output matrix to zero + for (int i=0; i<3; i++) + result._rotation_coeffs[i*4]=0.0; + //multiplying + for (int i=0; i<3;i++) + for (int j=0; j<3; j++) + for (int k=0; k<3; k++) + result._rotation_coeffs[j+i*3]+=A._rotation_coeffs[3*i+k]*_rotation_coeffs[j+k*3]; + + for (int i=0;i<9; i++) + _rotation_coeffs[i]=result._rotation_coeffs[i]; + } + + void rotate_vector(double* P) + { + double temp[3]={0.0, 0.0, 0.0}; + + for (int i=0; i<3;i++) + for (int j=0; j<3; j++) + temp[i] +=_rotation_coeffs[3*i+j]*P[j]; + + P[0]=temp[0];P[1]=temp[1];P[2]=temp[2]; + } + + void transform_vector(double*P) + { + P[0]+=_translation_coeffs[0]; + P[1]+=_translation_coeffs[1]; + P[2]+=_translation_coeffs[2]; + rotate_vector(P); + } + + void translate(const double* P) + { + _translation_coeffs[0]=P[0]; + _translation_coeffs[1]=P[1]; + _translation_coeffs[2]=P[2]; + } + + void rotate_x (double* P) + { + _rotation_coeffs[0]=1.0; + double r_sqr = P[1]*P[1]+P[2]*P[2]; + if (r_sqr < EPS) + {_rotation_coeffs[4]=1.0; _rotation_coeffs[8]=1.0; return;} + double r = sqrt(r_sqr); + double cos =P[1]/r; + double sin =P[2]/r; + + _rotation_coeffs[4]=cos; + _rotation_coeffs[5]=sin; + _rotation_coeffs[7]=-sin; + _rotation_coeffs[8]=cos; + + + rotate_vector(P); + } + + void rotate_z (double* P) + { + _rotation_coeffs[8]=1.0; + double r_sqr = P[0]*P[0]+P[1]*P[1]; + if (r_sqr < EPS) + {_rotation_coeffs[4]=1.0; _rotation_coeffs[0]=1.0; return;} + double r = sqrt(r_sqr); + double cos =P[0]/r; + double sin =P[1]/r; + + _rotation_coeffs[0]=cos; + _rotation_coeffs[1]=sin; + _rotation_coeffs[3]=-sin; + _rotation_coeffs[4]=cos; + + rotate_vector(P); + } + + + private: + static const double EPS; + static const unsigned ROT_SIZE=9; + static const unsigned TRANSL_SIZE=3; + double _rotation_coeffs[ROT_SIZE]; + double _translation_coeffs[TRANSL_SIZE]; + }; +} + +#endif diff --git a/src/medtool/src/INTERP_KERNEL/TriangulationIntersector.hxx b/src/medtool/src/INTERP_KERNEL/TriangulationIntersector.hxx new file mode 100644 index 000000000..27eb54b1a --- /dev/null +++ b/src/medtool/src/INTERP_KERNEL/TriangulationIntersector.hxx @@ -0,0 +1,51 @@ +// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 +// 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 __TRIANGULATIONINTERSECTOR_HXX__ +#define __TRIANGULATIONINTERSECTOR_HXX__ + +#include "PlanarIntersectorP0P0.hxx" +#include "PlanarIntersectorP0P1.hxx" +#include "PlanarIntersectorP1P0.hxx" +#include "PlanarIntersectorP1P1.hxx" +#include "PlanarIntersectorP1P0Bary.hxx" + +namespace INTERP_KERNEL +{ + template<class MyMeshType, class MyMatrix, template <class MeshType, class TheMatrix, class ThisIntersector> class InterpType > + class TriangulationIntersector : public InterpType<MyMeshType,MyMatrix,TriangulationIntersector<MyMeshType,MyMatrix,InterpType> > + { + public: + static const int SPACEDIM=MyMeshType::MY_SPACEDIM; + static const int MESHDIM=MyMeshType::MY_MESHDIM; + typedef typename MyMeshType::MyConnType ConnType; + static const NumberingPolicy numPol=MyMeshType::My_numPol; + public: + TriangulationIntersector(const MyMeshType& meshT, const MyMeshType& meshS, + double dimCaracteristic, double precision, double md3DSurf, double minDot3DSurf, double medianPlane, int orientation, int printLevel); + double intersectGeometry(ConnType icellT, ConnType icellS, ConnType nbNodesT, ConnType nbNodesS); + double intersectGeometryWithQuadrangle(const double *quadrangle, const std::vector<double>& sourceCoords, bool isSourceQuad); + double intersectGeometryGeneral(const std::vector<double>& targetCoords, const std::vector<double>& sourceCoords); + double intersectGeoBary(const std::vector<double>& targetCell, bool targetCellQuadratic, const double *sourceCell, std::vector<double>& res); + + }; +} + +#endif diff --git a/src/medtool/src/INTERP_KERNEL/TriangulationIntersector.txx b/src/medtool/src/INTERP_KERNEL/TriangulationIntersector.txx new file mode 100644 index 000000000..a7a080b28 --- /dev/null +++ b/src/medtool/src/INTERP_KERNEL/TriangulationIntersector.txx @@ -0,0 +1,236 @@ +// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 +// 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 __TRIANGULATIONINTERSECTOR_TXX__ +#define __TRIANGULATIONINTERSECTOR_TXX__ + +#include "TriangulationIntersector.hxx" +#include "PlanarIntersectorP0P0.txx" +#include "PlanarIntersectorP0P1.txx" +#include "PlanarIntersectorP1P0.txx" +#include "PlanarIntersectorP1P0Bary.txx" + +#include "InterpolationUtils.hxx" +#include "PlanarIntersector.hxx" + +#include <iostream> + +#define TRI_INTERSECTOR TriangulationIntersector<MyMeshType,MyMatrix,InterpType> +#define TRI_INTER_TEMPLATE template<class MyMeshType, class MyMatrix, \ + template <class MeshType, class TheMatrix, class ThisIntersector> class InterpType> + +namespace INTERP_KERNEL +{ + TRI_INTER_TEMPLATE + TRI_INTERSECTOR::TriangulationIntersector(const MyMeshType& meshT, const MyMeshType& meshS, + double DimCaracteristic, double Precision, double md3DSurf, double minDot3DSurf, + double MedianPlane, int orientation, int PrintLevel) + :InterpType<MyMeshType,MyMatrix,TRI_INTERSECTOR >(meshT,meshS,DimCaracteristic, Precision, md3DSurf, minDot3DSurf, + MedianPlane, true, orientation, PrintLevel) + { + if(PlanarIntersector<MyMeshType,MyMatrix>::_print_level >= 1) + { + std::cout << " - intersection type = triangles " << std::endl; + if(SPACEDIM==3) std::cout << "_do_rotate = true"<< std::endl; + } + } + + TRI_INTER_TEMPLATE + double TRI_INTERSECTOR::intersectGeometry(ConnType icellT, ConnType icellS, + ConnType nbNodesT, ConnType nbNodesS) + { + double result = 0.; + int orientation = 1; + + //Obtain the coordinates of T and S + std::vector<double> CoordsT; + std::vector<double> CoordsS; + PlanarIntersector<MyMeshType,MyMatrix>::getRealCoordinates(icellT,icellS,nbNodesT,nbNodesS,CoordsT,CoordsS,orientation); + //Compute the intersection area + double area[SPACEDIM]; + for(ConnType iT = 1; iT<nbNodesT-1; iT++) + { + for(ConnType iS = 1; iS<nbNodesS-1; iS++) + { + std::vector<double> inter; + INTERP_KERNEL::intersec_de_triangle(&CoordsT[0],&CoordsT[SPACEDIM*iT],&CoordsT[SPACEDIM*(iT+1)], + &CoordsS[0],&CoordsS[SPACEDIM*iS],&CoordsS[SPACEDIM*(iS+1)], + inter, PlanarIntersector<MyMeshType,MyMatrix>::_dim_caracteristic, + PlanarIntersector<MyMeshType,MyMatrix>::_precision); + ConnType nb_inter=((ConnType)inter.size())/2; + if(nb_inter >3) inter=reconstruct_polygon(inter); + for(ConnType i = 1; i<nb_inter-1; i++) + { + INTERP_KERNEL::crossprod<2>(&inter[0],&inter[2*i],&inter[2*(i+1)],area); + result +=0.5*fabs(area[0]); + } + //DEBUG prints + if(PlanarIntersector<MyMeshType,MyMatrix>::_print_level >= 3) + { + std::cout << std::endl << "Number of nodes of the intersection = "<< nb_inter << std::endl; + for(ConnType i=0; i< nb_inter; i++) + {for (int idim=0; idim<2; idim++) std::cout << inter[2*i+idim] << " "; std::cout << std::endl; } + } + } + } + + //DEBUG PRINTS + if(PlanarIntersector<MyMeshType,MyMatrix>::_print_level >= 3) + std::cout << std::endl <<"Intersection area = " << result << std::endl; + + return orientation*result; + } + + TRI_INTER_TEMPLATE + double TRI_INTERSECTOR::intersectGeometryWithQuadrangle(const double * quadrangle, + const std::vector<double>& sourceCoords, + bool isSourceQuad) + { + double result = 0.; + ConnType nbNodesS=sourceCoords.size()/SPACEDIM; + //Compute the intersection area + double area[SPACEDIM]; + for(ConnType iT = 1; iT<3; iT++) + { + for(ConnType iS = 1; iS<nbNodesS-1; iS++) + { + std::vector<double> inter; + INTERP_KERNEL::intersec_de_triangle(quadrangle,&quadrangle[SPACEDIM*iT],&quadrangle[SPACEDIM*(iT+1)], + &sourceCoords[0],&sourceCoords[SPACEDIM*iS],&sourceCoords[SPACEDIM*(iS+1)], + inter, PlanarIntersector<MyMeshType,MyMatrix>::_dim_caracteristic, + PlanarIntersector<MyMeshType,MyMatrix>::_precision); + ConnType nb_inter=((ConnType)inter.size())/2; + if(nb_inter >3) inter=reconstruct_polygon(inter); + for(ConnType i = 1; i<nb_inter-1; i++) + { + INTERP_KERNEL::crossprod<2>(&inter[0],&inter[2*i],&inter[2*(i+1)],area); + result +=0.5*fabs(area[0]); + } + //DEBUG prints + if(PlanarIntersector<MyMeshType,MyMatrix>::_print_level >= 3) + { + std::cout << std::endl << "Number of nodes of the intersection = "<< nb_inter << std::endl; + for(ConnType i=0; i< nb_inter; i++) + {for (int idim=0; idim<2; idim++) std::cout << inter[2*i+idim] << " "; std::cout << std::endl; } + } + } + } + + //DEBUG PRINTS + if(PlanarIntersector<MyMeshType,MyMatrix>::_print_level >= 3) + std::cout << std::endl <<"Intersection area = " << result << std::endl; + + return result; + } + + TRI_INTER_TEMPLATE + double TRI_INTERSECTOR::intersectGeometryGeneral(const std::vector<double>& targetCoords, + const std::vector<double>& sourceCoords) + { + double result = 0.; + ConnType nbNodesS=sourceCoords.size()/SPACEDIM; + ConnType nbNodesT=targetCoords.size()/SPACEDIM; + //Compute the intersection area + double area[SPACEDIM]; + for(ConnType iT = 1; iT<nbNodesT-1; iT++) + { + for(ConnType iS = 1; iS<nbNodesS-1; iS++) + { + std::vector<double> inter; + INTERP_KERNEL::intersec_de_triangle(&targetCoords[0],&targetCoords[SPACEDIM*iT],&targetCoords[SPACEDIM*(iT+1)], + &sourceCoords[0],&sourceCoords[SPACEDIM*iS],&sourceCoords[SPACEDIM*(iS+1)], + inter, PlanarIntersector<MyMeshType,MyMatrix>::_dim_caracteristic, + PlanarIntersector<MyMeshType,MyMatrix>::_precision); + ConnType nb_inter=((ConnType)inter.size())/2; + if(nb_inter >3) inter=reconstruct_polygon(inter); + for(ConnType i = 1; i<nb_inter-1; i++) + { + INTERP_KERNEL::crossprod<2>(&inter[0],&inter[2*i],&inter[2*(i+1)],area); + result +=0.5*fabs(area[0]); + } + } + } + return result; + } + + //================================================================================ + /*! + * \brief Intersect a triangle and a polygon for P1P0 barycentric algorithm + * \param targetCell - list of coordinates of target polygon in full interlace + * \param targetCellQuadratic - specifies if target polygon is quadratic or not + * \param sourceTria - list of coordinates of source triangle + * \param res - coefficients a,b and c associated to nodes of sourceTria + */ + //================================================================================ + + TRI_INTER_TEMPLATE + double TRI_INTERSECTOR::intersectGeoBary(const std::vector<double>& targetCell, + bool targetCellQuadratic, + const double * sourceTria, + std::vector<double>& res) + { + std::vector<const double* > sourceCell(3); + sourceCell[0] = &sourceTria[0]; + sourceCell[1] = &sourceTria[SPACEDIM]; + sourceCell[2] = &sourceTria[SPACEDIM*2]; + + //Compute the intersection area + double inter_area[SPACEDIM], total_area = 0.; + double total_barycenter[SPACEDIM]={0.,0.}; + + const ConnType nbNodesT=targetCell.size()/SPACEDIM; + for(ConnType iT = 1; iT<nbNodesT-1; iT++) + { + std::vector<double> inter; + INTERP_KERNEL::intersec_de_triangle(&targetCell[0],&targetCell[SPACEDIM*iT],&targetCell[SPACEDIM*(iT+1)], + sourceCell[0], sourceCell[1], sourceCell[2], + inter, PlanarIntersector<MyMeshType,MyMatrix>::_dim_caracteristic, + PlanarIntersector<MyMeshType,MyMatrix>::_precision); + ConnType nb_inter=((ConnType)inter.size())/2; + if(nb_inter >3) inter=reconstruct_polygon(inter); + for(ConnType i = 1; i<nb_inter-1; i++) + { + INTERP_KERNEL::crossprod<2>(&inter[0],&inter[2*i],&inter[2*(i+1)],inter_area); + inter_area[0] = 0.5 * fabs( inter_area[0] ); + total_area += inter_area[0]; + std::vector<double> inter_bary=INTERP_KERNEL::bary_poly(inter); + total_barycenter[0] += inter_area[0] * inter_bary[0]; + total_barycenter[1] += inter_area[0] * inter_bary[1]; + } + } + if ( total_area > std::numeric_limits<double>::min() ) + { + total_barycenter[0] /= total_area; + total_barycenter[1] /= total_area; + res.resize(3); + barycentric_coords( sourceCell, &total_barycenter[0], &res[0]); + res[0] *= total_area; + res[1] *= total_area; + res[2] *= total_area; + } + else + { + total_area = 0; + } + return total_area; + } + +} + +#endif diff --git a/src/medtool/src/INTERP_KERNEL/UnitTetraIntersectionBary.cxx b/src/medtool/src/INTERP_KERNEL/UnitTetraIntersectionBary.cxx new file mode 100644 index 000000000..4cd663089 --- /dev/null +++ b/src/medtool/src/INTERP_KERNEL/UnitTetraIntersectionBary.cxx @@ -0,0 +1,755 @@ +// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 +// 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 +// + +// File : UnitTetraIntersectionBary.cxx +// Created : Tue Dec 9 16:48:49 2008 +// Author : Edward AGAPOV (eap) +// +#include "UnitTetraIntersectionBary.hxx" + +#include "VectorUtils.hxx" +#include "InterpolationUtils.hxx" +#include "VolSurfFormulae.hxx" + +#define NB_TETRA_SIDES 4 +#define NB_TETRA_NODES 4 + +//#define DMP_UNITTETRAINTERSECTIONBARY + + +namespace INTERP_KERNEL +{ + enum { _X=0, _Y, _Z }; + + inline bool samePoint( const double* p1, const double* p2 ) + { + return ( epsilonEqual( p1[0], p2[0]) && + epsilonEqual( p1[1], p2[1]) && + epsilonEqual( p1[2], p2[2])); + } + + //================================================================================ + /*! + * \brief Creates a ready-to-use tool + */ + //================================================================================ + + UnitTetraIntersectionBary::UnitTetraIntersectionBary(bool isTetraInversed) + :TransformedTriangle(),_int_volume(0),_isTetraInversed( isTetraInversed ) + { + //init(); + } + //================================================================================ + /*! + * \brief Initializes fields + */ + //================================================================================ + + void UnitTetraIntersectionBary::init(bool isTetraInversed) + { + _int_volume = 0; + _isTetraInversed = isTetraInversed; + _faces.clear(); + _polyNormals.clear(); + } + + //================================================================================ + /*! + * \brief Stores a part of triangle common with the unit tetrahedron + * \param triangle - triangle side of other cell + */ + //================================================================================ + + void UnitTetraIntersectionBary::addSide(const TransformedTriangle& triangle) + { + _int_volume += triangle.getVolume(); + + double triNormal[3], polyNormal[3]; + crossprod<3>( triangle.getCorner(P),triangle.getCorner(Q),triangle.getCorner(R), triNormal); + + const std::vector<double*> * pPolygonA = &triangle.getPolygonA(); + if ( pPolygonA->size() < 3 ) + { + if ( !epsilonEqual( triNormal[_Z], 0 )) + return; // not vertical triangle does not intersect the unit tetra + + // Vertical triangle. Use inherited methods of TransformedTriangle to + // calculate intesection polygon + *((TransformedTriangle*)this) = triangle; // copy triangle fields + _polygonA.clear(); + _polygonB.clear(); + calculateIntersectionAndProjectionPolygons(); + if (this->_polygonA.size() < 3) + return; + calculatePolygonBarycenter(A, _barycenterA); + sortIntersectionPolygon(A, _barycenterA); + pPolygonA = & _polygonA; + } + + // check if polygon orientation is same as the one of triangle + std::vector<double*>::const_iterator p = pPolygonA->begin(), pEnd = pPolygonA->end(); +#ifdef DMP_UNITTETRAINTERSECTIONBARY + std::cout.precision(18); + std::cout << "**** int polygon() " << std::endl; + while ( p != pEnd ) + { + double* pp = *p++; + std::cout << pEnd - p << ": ( " << pp[0] << ", " << pp[1] << ", " << pp[2] << " )" << std::endl; + } + p = pPolygonA->begin(); +#endif + double* p1 = *p++; + double* p2 = *p; + while ( samePoint( p1, p2 ) && ++p != pEnd ) + p2 = *p; + if ( p == pEnd ) + { +#ifdef DMP_UNITTETRAINTERSECTIONBARY + std::cout << "All points equal" << std::endl; +#endif + clearPolygons(); + return; + } + double* p3 = *p; + while (( samePoint( p2, p3 ) || samePoint( p1, p3 )) && ++p != pEnd ) + p3 = *p; + if ( p == pEnd ) + { +#ifdef DMP_UNITTETRAINTERSECTIONBARY + std::cout << "Only two points differ" << std::endl; +#endif + clearPolygons(); + return ; + } + crossprod<3>( p1, p2, p3, polyNormal ); + bool reverse = ( dotprod<3>( triNormal, polyNormal ) < 0.0 ); + if (_isTetraInversed) reverse = !reverse; + + // store polygon + _faces.push_back( std::vector< double* > () ); + std::vector< double* >& faceCorner = _faces.back(); + faceCorner.resize( pPolygonA->size()/* + 1*/ ); + + int i = 0; + if ( reverse ) + { + std::vector<double*>::const_reverse_iterator polyF = pPolygonA->rbegin(), polyEnd; + for ( polyEnd = pPolygonA->rend(); polyF != polyEnd; ++i, ++polyF ) + if ( i==0 || !samePoint( *polyF, faceCorner[i-1] )) + copyVector3( *polyF, faceCorner[i] = new double[3] ); + else + --i; + polyNormal[0] *= -1.; + polyNormal[1] *= -1.; + polyNormal[2] *= -1.; + } + else + { + std::vector<double*>::const_iterator polyF = pPolygonA->begin(), polyEnd; + for ( polyEnd = pPolygonA->end(); polyF != polyEnd; ++i, ++polyF ) + if ( i==0 || !samePoint( *polyF, faceCorner[i-1] )) + copyVector3( *polyF, faceCorner[i] = new double[3] ); + else + --i; + } + if ( i < 3 ) + { + clearPolygons(); // free memory of _polygonA + _polygonA = faceCorner; + _faces.pop_back(); + } + else + { + if ( i < (int)pPolygonA->size() ) + faceCorner.resize( i ); + + if ( _polyNormals.empty() ) + _polyNormals.reserve(4); + _polyNormals.push_back( std::vector< double >( polyNormal, polyNormal+3 )); + } + +#ifdef DMP_UNITTETRAINTERSECTIONBARY + std::cout << "**** addSide() " << _faces.size() << std::endl; + for ( int i = 0; i < faceCorner.size(); ++i ) + { + double* p = faceCorner[i]; + std::cout << i << ": ( " << p[0] << ", " << p[1] << ", " << p[2] << " )" << std::endl; + } + std::cout << "NORM: ( " << _polyNormals.back()[0] << ", " << _polyNormals.back()[1] << ", " << _polyNormals.back()[2] << " )" << std::endl; +#endif + clearPolygons(); + } + + //================================================================================ + /*! + * \brief Computes and returns coordinates of barycentre + */ + //================================================================================ + + bool UnitTetraIntersectionBary::getBary(double* baryCenter) + { + baryCenter[0] = baryCenter[1] = baryCenter[2] = -1.0; + if ( addSideFaces() < NB_TETRA_SIDES ) + { + // tetra is not intersected + if ( fabs(_int_volume) > 1e-10 ) + { + // tetra is fully inside the other cell + baryCenter[0] = baryCenter[1] = baryCenter[2] = 0.25; + _int_volume = 0.16666666666666666; + return true; + } + return false; + } + // Algo: + // - pick up one point P among the summits of the polyhedron + // - for each face of the polyhedron which does not contain the point : + // - compute the barycenter of the volume obtained by forming the "pyramid" with + // the face as a base and point P as a summit + // - compute the volume of the "pyramid" + // - Add up all barycenter positions weighting them with the volumes. + + baryCenter[0] = baryCenter[1] = baryCenter[2] = 0.; + + std::list< std::vector< double* > >::iterator f = _faces.begin(), fEnd = _faces.end(); + double * PP = f->at(0); + + for ( ++f; f != fEnd; ++f ) + { + std::vector< double* >& polygon = *f; + if ( polygon.empty() ) + continue; + + bool pBelongsToPoly = false; + std::vector<double*>::iterator v = polygon.begin(), vEnd = polygon.end(); + for ( ; !pBelongsToPoly && v != vEnd; ++v ) + pBelongsToPoly = samePoint( PP, *v ); + if ( pBelongsToPoly ) + continue; + + // Compute the barycenter of the volume. Barycenter of pyramid is on line + // ( barycenter of polygon -> PP ) with 1/4 of pyramid height from polygon. + + double bary[] = { 0, 0, 0 }; + + // base polygon bary + for ( v = polygon.begin(); v != vEnd ; ++v ) + { + double* p = *v; + bary[0] += p[0]; + bary[1] += p[1]; + bary[2] += p[2]; + } + bary[0] /= (int)polygon.size(); + bary[1] /= (int)polygon.size(); + bary[2] /= (int)polygon.size(); + + // pyramid volume + double vol = 0; + for ( int i = 0; i < (int)polygon.size(); ++i ) + { + double* p1 = polygon[i]; + double* p2 = polygon[(i+1)%polygon.size()]; + vol += std::fabs( calculateVolumeForTetra( p1, p2, bary, PP )); + } + + // put bary on the line ( barycenter of polygon -> PP ) and multiply by volume + baryCenter[0] += ( bary[0] * 0.75 + PP[0] * 0.25 ) * vol; + baryCenter[1] += ( bary[1] * 0.75 + PP[1] * 0.25 ) * vol; + baryCenter[2] += ( bary[2] * 0.75 + PP[2] * 0.25 ) * vol; + } + if ( _int_volume < 0. ) + _int_volume = -_int_volume; + baryCenter[0] /= _int_volume; + baryCenter[1] /= _int_volume; + baryCenter[2] /= _int_volume; + +#ifdef DMP_UNITTETRAINTERSECTIONBARY + std::cout.precision(5); + std::cout << "**** Barycenter " << baryCenter[0] <<", "<< baryCenter[1] <<", "<< baryCenter[2] + << "\t **** Volume " << _int_volume << std::endl; + std::cout << "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~" << std::endl; +#endif + return true; + } + + //================================================================================ + /*! + * \brief Add faces of the intersection polyhedron formed on faces of the + * unit tetrahedron by sides of already added faces + * \retval int - number of faces of intersection polyhedron + */ + //================================================================================ + + int UnitTetraIntersectionBary::addSideFaces() + { + int nbPolyhedraFaces = 0; + + if ( _faces.empty() ) + return nbPolyhedraFaces; + + // ------------------------------------------- + // Detect polygons laying on sides of a tetra + // ------------------------------------------- + + bool sideAdded[NB_TETRA_SIDES] = { false, false, false, false }; + int nbAddedSides = 0; + std::list< std::vector< double* > >::iterator f = _faces.begin(), fEnd = _faces.end(); + for ( ; f != fEnd; ++f ) + { + std::vector< double* >& polygon = *f; + double coordSum[3] = {0,0,0}; + for ( int i = 0; i < (int)polygon.size(); ++i ) + { + double* p = polygon[i]; + coordSum[0] += p[0]; + coordSum[1] += p[1]; + coordSum[2] += p[2]; + } + for ( int j = 0; j < 3 && !sideAdded[j]; ++j ) + { + if ( epsilonEqual( coordSum[j], 0.0 )) + sideAdded[j] = ++nbAddedSides != 0 ; + } + if ( !sideAdded[3] && + ( epsilonEqual( (coordSum[0]+coordSum[1]+coordSum[2]) / (int)polygon.size(), 1. ))) + sideAdded[3] = ++nbAddedSides != 0 ; + } + if ( nbAddedSides == NB_TETRA_SIDES ) + return nbAddedSides; + + // --------------------------------------------------------------------------------- + // Add segments of already added polygons to future polygonal faces on sides of tetra + // --------------------------------------------------------------------------------- + + std::size_t nbIntersectPolygs = _faces.size(); + + std::vector< double* > * sideFaces[ 4 ]; // future polygons on sides of tetra + for ( int i = 0; i < NB_TETRA_SIDES; ++i ) + { + sideFaces[ i ]=0; + if ( !sideAdded[ i ] ) + { + _faces.push_back( std::vector< double* > () ); + sideFaces[ i ] = &_faces.back(); + } + } + f = _faces.begin(), fEnd = _faces.end(); + for ( std::size_t iF = 0; iF < nbIntersectPolygs; ++f, ++iF ) // loop on added intersection polygons + { + std::vector< double* >& polygon = *f; + for ( std::size_t i = 0; i < polygon.size(); ++i ) + { + // segment ends + double* p1 = polygon[i]; + double* p2 = polygon[(i+1)%polygon.size()]; + bool p1OnSide, p2OnSide;//, onZeroSide = false; + for ( int j = 0; j < 3; ++j ) + { + if ( !sideFaces[ j ] ) + continue; + p1OnSide = epsilonEqual( p1[j], 0. ); + p2OnSide = epsilonEqual( p2[j], 0. ); + if ( p1OnSide && p2OnSide ) + { + // segment p1-p2 is on j-th orthogonal side of tetra + sideFaces[j]->push_back( new double[3] ); + copyVector3( p1, sideFaces[j]->back() ); + sideFaces[j]->push_back( new double[3] ); + copyVector3( p2, sideFaces[j]->back() ); + //break; + } + } + // check if the segment p1-p2 is on the inclined side + if ( sideFaces[3] && + epsilonEqual( p1[_X] + p1[_Y] + p1[_Z], 1.0 ) && + epsilonEqual( p2[_X] + p2[_Y] + p2[_Z], 1.0 )) + { + sideFaces[3]->push_back( new double[3] ); + copyVector3( p1, sideFaces[3]->back() ); + sideFaces[3]->push_back( new double[3] ); + copyVector3( p2, sideFaces[3]->back() ); + } + } + } +#ifdef DMP_UNITTETRAINTERSECTIONBARY + std::cout << "**** after Add segments to sides " << std::endl; + for ( int i = 0; i < NB_TETRA_SIDES; ++i ) + { + std::cout << "\t Side " << i << std::endl; + if ( !sideFaces[i] ) + { + std::cout << "\t cut by triagle" << std::endl; + } + else + { + std::vector< double* >& sideFace = *sideFaces[i]; + for ( int i = 0; i < sideFace.size(); ++i ) + { + double* p = sideFace[i]; + std::cout << "\t" << i << ": ( " << p[0] << ", " << p[1] << ", " << p[2] << " )" << std::endl; + } + } + } +#endif + + // --------------------------------------------------------------------------- + // Make closed polygons on tetra sides by adding not cut off corners of tetra + // --------------------------------------------------------------------------- + + double origin[3] = { 0,0,0 }; + + // find corners of tetra cut off by triangles of other tetra + // --------------------------------------------------------- + + // corners are coded like this: index = 1*X + 2*Y + 3*Z + // (0,0,0) -> index == 0; (0,0,1) -> index == 3 + int cutOffCorners[NB_TETRA_NODES] = { false, false, false, false }; + int passedCorners[NB_TETRA_NODES] = { false, false, false, false }; + + // find cutOffCorners by normals of intersection polygons + int nbCutOffCorners = 0; + for ( int ic = 0; ic < NB_TETRA_NODES; ++ic ) + { + f = _faces.begin(), fEnd = _faces.end(); + for ( std::size_t iF = 0; iF < nbIntersectPolygs; ++f, ++iF ) // loop on added intersection polygons + { + std::vector< double* >& polygon = *f; + + double corner2Poly[3] = { polygon[0][0], polygon[0][1], polygon[0][2] }; + if ( ic ) corner2Poly[ ic-1 ] -= 1.0; + + // _polyNormals are outside of a tetrahedron + double dot = dotprod<3>( corner2Poly, &_polyNormals[iF][0] ); + if ( dot < -DEFAULT_ABS_TOL*DEFAULT_ABS_TOL ) + { +#ifdef DMP_UNITTETRAINTERSECTIONBARY + std::cout << "side " << iF+1 << ": cut " << ic << std::endl; +#endif + cutOffCorners[ ic ] = true; + nbCutOffCorners++; + break; + } + } + } + + for ( int i = 0; i < 3; ++i ) // loop on orthogonal faces of the unit tetra + { + if ( !sideFaces[i] ) continue; + std::vector< double* >& sideFace = *sideFaces[i]; + + std::size_t nbPoints = sideFace.size(); + if ( nbPoints == 0 ) + continue; // not intersected face at all - no cut off corners can be detected + + int ind1 = (i+1)%3, ind2 = (i+2)%3; // indices of coords on i-th tetra side + + int nbCutOnSide = 0; + bool isSegmentOnEdge=false; + for ( std::size_t ip = 0; ip < nbPoints; ++ip ) + { + std::size_t isSegmentEnd = ( ip % 2 ); + + double* p = sideFace[ ip ]; + double* p2 = isSegmentEnd ? 0 : sideFace[ip+1]; + + if ( !isSegmentEnd ) + isSegmentOnEdge = false; // initialize + + int cutOffIndex = -1, passThIndex = -1;// no cut off neither pass through + int pCut[] = { 0,0,0 }, pPass[] = { 0,0,0 }; + + if ( epsilonEqual( p[ind1], 0.)) + { + // point is on orthogonal edge + if ( !isSegmentEnd && epsilonEqual( p2[ind1], 0. )) + isSegmentOnEdge = true; + + if ( !isSegmentOnEdge ) + { // segment ends are on different edges + pCut[ind2] = (int)isSegmentEnd; // believe that cutting triangles are well oriented + cutOffIndex = pCut[0] + 2*pCut[1] + 3*pCut[2]; + } + if ( epsilonEqual( p[ind2], 0.) || epsilonEqual( p[ind2], 1.)) + { + pPass[ind2] = ( p[ind2] < 0.5 ) ? 0 : 1; + passThIndex = pPass[0] + 2*pPass[1] + 3*pPass[2]; + } + } + else if ( epsilonEqual( p[ind2], 0.)) + { + // point is on orthogonal edge + if ( !isSegmentEnd && epsilonEqual( p2[ind2], 0. )) + isSegmentOnEdge = true; + if ( !isSegmentEnd ) + {// segment ends are on different edges + pCut[ind1] = 1-(int)isSegmentEnd; + cutOffIndex = pCut[0] + 2*pCut[1] + 3*pCut[2]; + } + if ( epsilonEqual( p[ind1], 0.) || epsilonEqual( p[ind1], 1.)) + { + pPass[ind1] = ( p[ind1] < 0.5 ) ? 0 : 1; + passThIndex = pPass[0] + 2*pPass[1] + 3*pPass[2]; + } + } + else if ( epsilonEqual(p[ind1] + p[ind2], 1.0 )) + { + // point is on inclined edge + if ( !isSegmentEnd && epsilonEqual(p2[ind1] + p2[ind2], 1.0 )) + isSegmentOnEdge = true; + if ( !isSegmentOnEdge ) + { //segment ends are on different edges + pCut[ind1] = (int)isSegmentEnd; + pCut[ind2] = 1-(int)isSegmentEnd; + cutOffIndex = pCut[0] + 2*pCut[1] + 3*pCut[2]; + } + } + else + { + continue; + } + // remember cut off and passed through points + if ( passThIndex >= 0 ) + { + passedCorners[ passThIndex ] = true; + if ( cutOffCorners[ passThIndex ] ) + { + nbCutOffCorners--; + cutOffCorners[ passThIndex ] = false; +#ifdef DMP_UNITTETRAINTERSECTIONBARY + std::cout << "PASS THROUGH " << passThIndex << std::endl; +#endif + } + } + if ( cutOffIndex >= 0 ) + { + nbCutOnSide++; + if ( !passedCorners[ cutOffIndex ] && !cutOffCorners[ cutOffIndex ] ) + { + nbCutOffCorners++; + cutOffCorners[ cutOffIndex ] = true; + } + } + } // loop on points on a unit tetra side + + if ( nbCutOnSide == 0 && nbPoints <= 2 ) + continue; // one segment laying on edge at most + + if ( nbCutOffCorners == NB_TETRA_NODES ) + break; // all tetra corners are cut off + + if ( /*nbCutOnSide <= 2 &&*/ nbPoints >= 6 ) + { + // at least 3 segments - all corners of a side are cut off + for (int cutIndex = 0; cutIndex < NB_TETRA_NODES; ++cutIndex ) + if ( cutIndex != i+1 && !passedCorners[ cutIndex ] && !cutOffCorners[ cutIndex ]) + cutOffCorners[ cutIndex ] = ++nbCutOffCorners != 0 ; + } + + } + // loop on orthogonal faces of tetra + + // check if all corners are cut off on the inclined tetra side + if ( sideFaces[ XYZ ] && sideFaces[ XYZ ]->size() >= 6 ) + { + for (int cutIndex = 1; cutIndex < NB_TETRA_NODES; ++cutIndex ) + if ( !passedCorners[ cutIndex ] && !cutOffCorners[ cutIndex ]) + cutOffCorners[ cutIndex ] = ++nbCutOffCorners != 0 ; + } + + // Add to faces on tetra sides the corners not cut off by segments of intersection polygons + // ---------------------------------------------------------------------------------- + if ( nbCutOffCorners > 0 ) + { + for ( int i = 0; i < NB_TETRA_SIDES; ++i ) + { + if ( !sideFaces[ i ] ) continue; + std::vector< double* >& sideFace = *sideFaces[i]; + + int excludeCorner = (i + 1) % NB_TETRA_NODES; + for ( int ic = 0; ic < NB_TETRA_NODES; ++ic ) + { + if ( !cutOffCorners[ ic ] && ic != excludeCorner ) + { + sideFace.push_back( new double[3] ); + copyVector3( origin, sideFace.back() ); + if ( ic ) + sideFace.back()[ ic-1 ] = 1.0; + } + } + } + } + +#ifdef DMP_UNITTETRAINTERSECTIONBARY + std::cout << "**** after Add corners to sides " << std::endl; + for ( int i = 0; i < NB_TETRA_SIDES; ++i ) + { + std::cout << "\t Side " << i << std::endl; + if ( !sideFaces[i] ) { + std::cout << "\t cut by triagle" << std::endl; + } + else + { + std::vector< double* >& sideFace = *sideFaces[i]; + for ( int i = 0; i < sideFace.size(); ++i ) + { + double* p = sideFace[i]; + std::cout << "\t" << i << ": ( " << p[0] << ", " << p[1] << ", " << p[2] << " )" << std::endl; + } + } + } + std::cout << "Cut off corners: "; + if ( nbCutOffCorners == 0 ) + std::cout << "NO"; + else + for ( int ic = 0; ic < NB_TETRA_NODES; ++ic ) + std::cout << cutOffCorners[ ic ]; + std::cout << std::endl; +#endif + // ------------------------------------------------------------------------ + // Sort corners of filled up faces on tetra sides and exclude equal points + // ------------------------------------------------------------------------ + + std::size_t iF = 0; + for ( f = _faces.begin(); f != fEnd; ++f, ++iF ) + { + std::vector< double* >& face = *f; + if ( face.size() >= 3 ) + { + clearPolygons(); // free memory of _polygonA + _polygonA = face; + face.clear(); + face.reserve( _polygonA.size() ); + if ( iF >= nbIntersectPolygs ) + { // sort points of side faces + calculatePolygonBarycenter( A, _barycenterA ); + setTriangleOnSide( (int)(iF-nbIntersectPolygs) ); + sortIntersectionPolygon( A, _barycenterA ); + } + // exclude equal points + std::vector< double* >::iterator v = _polygonA.begin(), vEnd = _polygonA.end(); + face.push_back( *v ); + *v = 0; + for ( ++v; v != vEnd; ++v ) + { + double* pPrev = face.back(); + double* p = *v; + if ( !samePoint( p, pPrev )) + { + face.push_back( p ); + *v = 0; + } + } + } + if ( face.size() < 3 ) + { // size could decrease + clearPolygons(); // free memory of _polygonA + _polygonA = face; + face.clear(); + } + else + { + nbPolyhedraFaces++; + } + } +#ifdef DMP_UNITTETRAINTERSECTIONBARY + std::cout << "**** after HEALING all faces " << std::endl; + for (iF=0, f = _faces.begin(); f != fEnd; ++f, ++iF ) + { + std::cout << "\t Side " << iF << std::endl; + std::vector< double* >& sideFace = *f; + for ( int i = 0; i < sideFace.size(); ++i ) + { + double* p = sideFace[i]; + std::cout << "\t" << i << ": ( " << p[0] << ", " << p[1] << ", " << p[2] << " )" << std::endl; + } + } +#endif + return nbPolyhedraFaces; + } + + //================================================================================ + /*! + * \brief set corners of inherited TransformedTriangle as corners of i-th side of + * the Unit tetra. It is necessary to sort points of faces on sides of the unit + * tetrahedron using sortIntersectionPolygon(A) + */ + //================================================================================ + + void UnitTetraIntersectionBary::setTriangleOnSide(int iSide) + { + if ( iSide >= 3 ) + iSide = 0; + for(int i = 0 ; i < 3 ; ++i) + { + _coords[5*i] = _coords[5*i + 1] = _coords[5*i + 2] = 0.; + if ( i != iSide ) + _coords[5*i + i] = 1.; + } + } + + //================================================================================ + /*! + * \brief Free memory of polygons + */ + //================================================================================ + + void UnitTetraIntersectionBary::clearPolygons(bool andFaces) + { + for(std::vector<double*>::iterator it = _polygonA.begin() ; it != _polygonA.end() ; ++it) + { delete[] *it; + *it = 0; + } + for(std::vector<double*>::iterator it = _polygonB.begin() ; it != _polygonB.end() ; ++it) + { + delete[] *it; + *it = 0; + } + + _polygonA.clear(); + _polygonB.clear(); + + if ( andFaces ) + { + std::list< std::vector< double* > >::iterator f = this->_faces.begin(), fEnd = this->_faces.end(); + for ( ; f != fEnd; ++f ) + { + std::vector< double* >& polygon = *f; + for(std::vector<double*>::iterator it = polygon.begin() ; it != polygon.end() ; ++it) + { + delete[] *it; + *it = 0; + } + } + this->_faces.clear(); + } + } + + //================================================================================ + /*! + * \brief Destructor clears coordinates of faces + */ + //================================================================================ + + UnitTetraIntersectionBary::~UnitTetraIntersectionBary() + { + clearPolygons(/*andFaces=*/true ); + } + +} diff --git a/src/medtool/src/INTERP_KERNEL/UnitTetraIntersectionBary.hxx b/src/medtool/src/INTERP_KERNEL/UnitTetraIntersectionBary.hxx new file mode 100644 index 000000000..c1446832d --- /dev/null +++ b/src/medtool/src/INTERP_KERNEL/UnitTetraIntersectionBary.hxx @@ -0,0 +1,81 @@ +// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 +// 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 +// + +// File : UnitTetraIntersectionBary.hxx +// Created : Tue Dec 9 16:06:33 2008 +// Author : Edward AGAPOV (eap) +// +#ifndef __UNITTETRAINTERSECTIONBARY_HXX__ +#define __UNITTETRAINTERSECTIONBARY_HXX__ + +#include "TransformedTriangle.hxx" +#include "INTERPKERNELDefines.hxx" + +#include <vector> +#include <list> + +namespace INTERP_KERNEL +{ + class UnitTetraIntersectionBary : protected TransformedTriangle + { + public: + INTERPKERNEL_EXPORT UnitTetraIntersectionBary(bool isTetraInversed=false); + + INTERPKERNEL_EXPORT void init(bool isTetraInversed=false); + /*! + * \brief Stores a part of triangle common with the unit tetrahedron + * \param triangle - triangle side of other cell, whose calculateIntersectionVolume() + * must have already been called + */ + INTERPKERNEL_EXPORT void addSide(const TransformedTriangle& triangle); + + /*! + * \brief Computes and return coordinates of barycentre + */ + INTERPKERNEL_EXPORT bool getBary(double* baryCenter); + + /*! + * \brief Returns volume of intersection + * \retval double - + */ + INTERPKERNEL_EXPORT inline double getVolume() const { return _int_volume; } + + INTERPKERNEL_EXPORT virtual ~UnitTetraIntersectionBary(); + + private: + + int addSideFaces(); + + void setTriangleOnSide(int i); + + void clearPolygons(bool andFaces=false); + + /// volume of intersection + double _int_volume; + + /// faces of intersection polyhedron + std::list< std::vector< double* > > _faces; + std::vector< std::vector< double > > _polyNormals; + + bool _isTetraInversed; + }; + +} + +#endif diff --git a/src/medtool/src/INTERP_KERNEL/VTKNormalizedUnstructuredMesh.hxx b/src/medtool/src/INTERP_KERNEL/VTKNormalizedUnstructuredMesh.hxx new file mode 100644 index 000000000..678ab55db --- /dev/null +++ b/src/medtool/src/INTERP_KERNEL/VTKNormalizedUnstructuredMesh.hxx @@ -0,0 +1,56 @@ +// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 +// 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 __VTKNORMALIZEDUNSTRUCTUREDMESH_HXX__ +#define __VTKNORMALIZEDUNSTRUCTUREDMESH_HXX__ + +#include "NormalizedUnstructuredMesh.hxx" + +#include "vtkType.h" + +class vtkUnstructuredGrid; + +template<int MESHDIM> +class INTERPKERNEL_EXPORT VTKNormalizedUnstructuredMesh +{ +public: + static const int MY_SPACEDIM=3; + static const int MY_MESHDIM=MESHDIM; + typedef vtkIdType MyConnType; + static const INTERP_KERNEL::NumberingPolicy My_numPol=INTERP_KERNEL::ALL_C_MODE; +public: + VTKNormalizedUnstructuredMesh(vtkUnstructuredGrid *mesh); + ~VTKNormalizedUnstructuredMesh(); + void getBoundingBox(double *boundingBox) const; + NormalizedCellType getTypeOfElement(vtkIdType eltId) const; + unsigned long getNumberOfElements() const; + unsigned long getNumberOfNodes() const; + const vtkIdType *getConnectivityPtr() const; + const double *getCoordinatesPtr() const; + const vtkIdType *getConnectivityIndexPtr() const; + void releaseTempArrays(); +protected: + void putinMEDFormat() const; +protected: + vtkUnstructuredGrid *_mesh_in_vtk_mode; + mutable vtkIdType *_tmp_index_array; +}; + +#endif diff --git a/src/medtool/src/INTERP_KERNEL/VTKNormalizedUnstructuredMesh.txx b/src/medtool/src/INTERP_KERNEL/VTKNormalizedUnstructuredMesh.txx new file mode 100644 index 000000000..96482ff7e --- /dev/null +++ b/src/medtool/src/INTERP_KERNEL/VTKNormalizedUnstructuredMesh.txx @@ -0,0 +1,133 @@ +// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 +// 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 __VTKNORMALIZEDUNSTRUCTUREDMESH_TXX__ +#define __VTKNORMALIZEDUNSTRUCTUREDMESH_TXX__ + +#include "VTKNormalizedUnstructuredMesh.hxx" + +#include "vtkUnstructuredGrid.h" +#include "vtkCellArray.h" +#include "vtkPoints.h" + +template<int MESHDIM> +VTKNormalizedUnstructuredMesh<MESHDIM>::VTKNormalizedUnstructuredMesh(vtkUnstructuredGrid *mesh):_mesh_in_vtk_mode(mesh), + _tmp_index_array(0) +{ +} + +template<int MESHDIM> +VTKNormalizedUnstructuredMesh<MESHDIM>::~VTKNormalizedUnstructuredMesh() +{ + _mesh_in_vtk_mode->Delete(); + releaseTempArrays(); +} + +template<int MESHDIM> +void VTKNormalizedUnstructuredMesh<MESHDIM>::getBoundingBox(double *boundingBox) const +{ + double tmp[6]; + _mesh_in_vtk_mode->GetBounds(tmp); + for(unsigned i=0;i<3;i++) + { + boundingBox[i]=tmp[2*i]; + boundingBox[3+i]=tmp[2*i+1]; + } +} + +template<int MESHDIM> +NormalizedCellType VTKNormalizedUnstructuredMesh<MESHDIM>::getTypeOfElement(vtkIdType eltId) const +{ + int cellType=_mesh_in_vtk_mode->GetCellType(eltId); + int convTab[30]={0,0,0,0,0,(int)NORM_TRI3,0,(int)NORM_POLYGON,0,(int)NORM_QUAD4,(int)NORM_TETRA4,0,(int)NORM_HEXA8 + 0,(int)NORM_PYRA5,0,0,0,(int)NORM_TRI6,(int)NORM_QUAD8,}; +} + +template<int MESHDIM> +unsigned long VTKNormalizedUnstructuredMesh<MESHDIM>::getNumberOfElements() const +{ + return _mesh_in_vtk_mode->GetNumberOfCells(); +} + +template<int MESHDIM> +unsigned long VTKNormalizedUnstructuredMesh<MESHDIM>::getNumberOfNodes() const +{ + return _mesh_in_vtk_mode->GetNumberOfPoints(); +} + +template<int MESHDIM> +const vtkIdType *VTKNormalizedUnstructuredMesh<MESHDIM>::getConnectivityPtr() const +{ + vtkIdType *ret=_mesh_in_vtk_mode->GetCells()->GetPointer(); + if(_tmp_index_array) + return ret; + else + { + putinMEDFormat(); + return ret; + } +} + +template<int MESHDIM> +const double *VTKNormalizedUnstructuredMesh<MESHDIM>::getCoordinatesPtr() const +{ + return (const double *)_mesh_in_vtk_mode->GetPoints()->GetVoidPointer(0); +} + +template<int MESHDIM> +const vtkIdType *VTKNormalizedUnstructuredMesh<MESHDIM>::getConnectivityIndexPtr() const +{ + if(_tmp_index_array) + return _tmp_index_array; + else + { + putinMEDFormat(); + return _tmp_index_array; + } +} + +template<int MESHDIM> +void VTKNormalizedUnstructuredMesh<MESHDIM>::putinMEDFormat() const +{ + long nbOfElem=getNumberOfElements(); + _tmp_index_array=new vtkIdType[nbOfElem+1]; + _tmp_index_array[0]=0; + vtkIdType *coarseConn=_mesh_in_vtk_mode->GetCells()->GetPointer(); + long ptInCC=0; + vtkIdType *finalConn=coarseConn; + for(long i=0;i<nbOfElem;i++) + { + vtkIdType cellLgth=coarseConn[ptInCC]; + for(vtkIdType j=0;j<cellLgth;j++) + *finalConn++=coarseConn[ptInCC+j+1]; + _tmp_index_array[i+1]=_tmp_index_array[i]+cellLgth; + ptInCC+=cellLgth+1; + } + int gh=0; + gh++; +} + +template<int MESHDIM> +void VTKNormalizedUnstructuredMesh<MESHDIM>::releaseTempArrays() +{ + delete [] _tmp_index_array; + _tmp_index_array=0; +} + +#endif diff --git a/src/medtool/src/INTERP_KERNEL/VectorUtils.hxx b/src/medtool/src/INTERP_KERNEL/VectorUtils.hxx new file mode 100644 index 000000000..21d69803a --- /dev/null +++ b/src/medtool/src/INTERP_KERNEL/VectorUtils.hxx @@ -0,0 +1,175 @@ +// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 +// 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 __VECTORUTILS_HXX__ +#define __VECTORUTILS_HXX__ + +#include <sstream> +#include <numeric> +#include <string> +#include <cmath> +#include <map> + +namespace INTERP_KERNEL +{ + /// Precision used for tests of 3D part of INTERP_KERNEL + const double VOL_PREC = 1.0e-6; + + /// Default relative tolerance in epsilonEqualRelative + const double DEFAULT_REL_TOL = 1.0e-6; + + /// Default absolute tolerance in epsilonEqual and epsilonEqualRelative + const double DEFAULT_ABS_TOL = 5.0e-12; + + /** + * @param a first point. Should point on a array of size at least equal to SPACEDIM. + * @param b second point. Should point on a array of size at least equal to SPACEDIM. + */ + template<int SPACEDIM> + inline double getDistanceBtw2Pts(const double *a, const double *b) + { + double ret2=0.; + for(int i=0;i<SPACEDIM;i++) + ret2+=(a[i]-b[i])*(a[i]-b[i]); + return sqrt(ret2); + } + + // ------------------------------------------------------------------- + // Math operations for vectors represented by double[3] - arrays + // ------------------------------------------------------------------- + + /** + * Copies a double[3] vector from src to dest + * + * @param src source vector + * @param dest destination vector + * + */ + inline void copyVector3(const double* src, double* dest) + { + for(int i = 0 ; i < 3 ; ++i) + dest[i] = src[i]; + } + + /** + * Creates a string representation of a double[3] vector + * + * @param pt a 3-vector + * @return a string of the form [x, y, z] + */ + inline const std::string vToStr(const double* pt) + { + std::stringstream ss(std::ios::out); + ss << "[" << pt[0] << ", " << pt[1] << ", " << pt[2] << "]"; + return ss.str(); + } + + /** + * Adds a double[3] - vector to another one. + * + * @param v vector v + * @param res vector in which to store the result res + v. + */ + inline void add(const double* v, double* res) + { + res[0] += v[0]; + res[1] += v[1]; + res[2] += v[2]; + } + + /** + * Calculates the cross product of two double[3] - vectors. + * + * @param v1 vector v1 + * @param v2 vector v2 + * @param res vector in which to store the result v1 x v2. It should not be one of v1 and v2. + */ + inline void cross(const double* v1, const double* v2,double* res) + { + res[0] = v1[1]*v2[2] - v1[2]*v2[1]; + res[1] = v1[2]*v2[0] - v1[0]*v2[2]; + res[2] = v1[0]*v2[1] - v1[1]*v2[0]; + } + + /** + * Calculates the dot product of two double[3] - vectors + * + * @param v1 vector v1 + * @param v2 vector v2 + * @return dot (scalar) product v1.v2 + */ + inline double dot(const double* v1, const double* v2) + { + return v1[0]*v2[0] + v1[1]*v2[1] + v1[2]*v2[2]; + } + + /** + * Calculates norm of a double[3] vector + * + * @param v a vector v + * @return euclidean norm of v + */ + inline double norm(const double* v) + { + return sqrt(dot(v,v)); + } + + /** + * Compares doubles using an absolute tolerance + * This is suitable mainly for comparisons with 0.0 + * + * @param x first value + * @param y second value + * @param errTol maximum allowed absolute difference that is to be treated as equality + * @return true if |x - y| < errTol, false otherwise + */ + inline bool epsilonEqual(const double x, const double y, const double errTol = DEFAULT_ABS_TOL) + { + return y < x ? x - y < errTol : y - x < errTol; + // return std::fabs(x - y) < errTol; + } + + /** + * Compares doubles using a relative tolerance + * This is suitable mainly for comparing larger values to each other. Before performing the relative test, + * an absolute test is performed to guard from problems when comparing to 0.0 + * + * @param x first value + * @param y second value + * @param relTol maximum allowed relative difference that is to be treated as equality + * @param absTol maximum allowed absolute difference that is to be treated as equality + * @return true if |x - y| <= absTol or |x - y|/max(|x|,|y|) <= relTol, false otherwise + */ + inline bool epsilonEqualRelative(const double x, const double y, const double relTol = DEFAULT_REL_TOL, const double absTol = DEFAULT_ABS_TOL) + { + // necessary for comparing values close to zero + // in order to avoid division by very small numbers + if(std::fabs(x - y) < absTol) + { + return true; + } + + const double relError = std::fabs((x - y) / std::max(std::fabs(x), std::fabs(y))); + + return relError < relTol; + } + +} + +#endif diff --git a/src/medtool/src/INTERP_KERNEL/VolSurfFormulae.hxx b/src/medtool/src/INTERP_KERNEL/VolSurfFormulae.hxx new file mode 100644 index 000000000..5562de5a3 --- /dev/null +++ b/src/medtool/src/INTERP_KERNEL/VolSurfFormulae.hxx @@ -0,0 +1,835 @@ +// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 +// 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 __VOLSURFFORMULAE_HXX__ +#define __VOLSURFFORMULAE_HXX__ + +#include "InterpolationUtils.hxx" +#include "InterpKernelException.hxx" +#include "InterpKernelGeo2DEdgeLin.hxx" +#include "InterpKernelGeo2DEdgeArcCircle.hxx" +#include "InterpKernelGeo2DQuadraticPolygon.hxx" + +#include <sstream> +#include <cmath> + +namespace INTERP_KERNEL +{ + inline void calculateBarycenterDyn(const double **pts, int nbPts, + int dim, double *bary); + + inline double calculateAreaForPolyg(const double **coords, int nbOfPtsInPolygs, + int spaceDim); + + + inline double calculateAreaForQPolyg(const double **coords, int nbOfPtsInPolygs, + int spaceDim); + + inline double calculateLgthForSeg2(const double *p1, const double *p2, int spaceDim) + { + if(spaceDim==1) + return *p2-*p1; + else + { + double ret=0; + for(int i=0;i<spaceDim;i++) + ret+=(p2[i]-p1[i])*(p2[i]-p1[i]); + 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 + // =========================== + inline double calculateAreaForTria(const double *p1, const double *p2, + const double *p3, int spaceDim) + { + double area ; + + if ( spaceDim == 2 ) + { + area = -((p2[0]-p1[0])*(p3[1]-p1[1]) - (p3[0]-p1[0])*(p2[1]-p1[1]))/2.0; + } + else + { + area = sqrt(((p2[1]-p1[1])*(p3[2]-p1[2]) - (p3[1]-p1[1])*(p2[2]-p1[2]))* + ((p2[1]-p1[1])*(p3[2]-p1[2]) - (p3[1]-p1[1])*(p2[2]-p1[2])) + + + ((p3[0]-p1[0])*(p2[2]-p1[2]) - (p2[0]-p1[0])*(p3[2]-p1[2]))* + ((p3[0]-p1[0])*(p2[2]-p1[2]) - (p2[0]-p1[0])*(p3[2]-p1[2])) + + + ((p2[0]-p1[0])*(p3[1]-p1[1]) - (p3[0]-p1[0])*(p2[1]-p1[1]))* + ((p2[0]-p1[0])*(p3[1]-p1[1]) - (p3[0]-p1[0])*(p2[1]-p1[1])))/2.0; + } + + return area ; + } + + // ============================= + // Calculate Area for quadrangle + // ============================= + inline double calculateAreaForQuad(const double *p1, const double *p2, + const double *p3, const double *p4, + int spaceDim) + { + double area ; + + if (spaceDim==2) + { + double a1 = (p2[0]-p1[0])/4.0, a2 = (p2[1]-p1[1])/4.0; + double b1 = (p3[0]-p4[0])/4.0, b2 = (p3[1]-p4[1])/4.0; + double c1 = (p3[0]-p2[0])/4.0, c2 = (p3[1]-p2[1])/4.0; + double d1 = (p4[0]-p1[0])/4.0, d2 = (p4[1]-p1[1])/4.0; + + area = - 4.0*( b1*c2 - c1*b2 + a1*c2 - c1*a2 + + b1*d2 - d1*b2 + a1*d2 - d1*a2); + } + else + { + area = (sqrt(((p2[1]-p1[1])*(p4[2]-p1[2]) - (p4[1]-p1[1])*(p2[2]-p1[2]))* + ((p2[1]-p1[1])*(p4[2]-p1[2]) - (p4[1]-p1[1])*(p2[2]-p1[2])) + + ((p4[0]-p1[0])*(p2[2]-p1[2]) - (p2[0]-p1[0])*(p4[2]-p1[2]))* + ((p4[0]-p1[0])*(p2[2]-p1[2]) - (p2[0]-p1[0])*(p4[2]-p1[2])) + + ((p2[0]-p1[0])*(p4[1]-p1[1]) - (p4[0]-p1[0])*(p2[1]-p1[1]))* + ((p2[0]-p1[0])*(p4[1]-p1[1]) - (p4[0]-p1[0])*(p2[1]-p1[1]))) + + + sqrt(((p4[1]-p3[1])*(p2[2]-p3[2]) - (p2[1]-p3[1])*(p4[2]-p3[2]))* + ((p4[1]-p3[1])*(p2[2]-p3[2]) - (p2[1]-p3[1])*(p4[2]-p3[2])) + + ((p2[0]-p3[0])*(p4[2]-p3[2]) - (p4[0]-p3[0])*(p2[2]-p3[2]))* + ((p2[0]-p3[0])*(p4[2]-p3[2]) - (p4[0]-p3[0])*(p2[2]-p3[2])) + + ((p4[0]-p3[0])*(p2[1]-p3[1]) - (p2[0]-p3[0])*(p4[1]-p3[1]))* + ((p4[0]-p3[0])*(p2[1]-p3[1]) - (p2[0]-p3[0])*(p4[1]-p3[1]))) + )/2.0; + } + + return area ; + } + + // ==================================== + // Calculate Normal Vector for Triangle + // ==================================== + inline void calculateNormalForTria(const double *p1, const double *p2, + const double *p3, double *normal) + { + normal[0] = ((p2[1]-p1[1])*(p3[2]-p1[2]) - (p3[1]-p1[1])*(p2[2]-p1[2]))/2.0; + normal[1] = ((p3[0]-p1[0])*(p2[2]-p1[2]) - (p2[0]-p1[0])*(p3[2]-p1[2]))/2.0; + normal[2] = ((p2[0]-p1[0])*(p3[1]-p1[1]) - (p3[0]-p1[0])*(p2[1]-p1[1]))/2.0; + } + + // ====================================== + // Calculate Normal Vector for Quadrangle + // ====================================== + inline void calculateNormalForQuad(const double *p1, const double *p2, + const double *p3, const double *p4, + double *normal) + { + double xnormal1 = (p2[1]-p1[1])*(p4[2]-p1[2]) - (p4[1]-p1[1])*(p2[2]-p1[2]); + double xnormal2 = (p4[0]-p1[0])*(p2[2]-p1[2]) - (p2[0]-p1[0])*(p4[2]-p1[2]); + double xnormal3 = (p2[0]-p1[0])*(p4[1]-p1[1]) - (p4[0]-p1[0])*(p2[1]-p1[1]); + double xarea = sqrt(xnormal1*xnormal1 + xnormal2*xnormal2 + xnormal3*xnormal3); + xnormal1 = xnormal1/xarea; + xnormal2 = xnormal2/xarea; + xnormal3 = xnormal3/xarea; + xarea = calculateAreaForQuad(p1,p2,p3,p4,3); + normal[0] = xnormal1*xarea ; + normal[1] = xnormal2*xarea ; + normal[2] = xnormal3*xarea ; + } + + // =================================== + // Calculate Normal Vector for Polygon + // =================================== + inline void calculateNormalForPolyg(const double **coords, int nbOfPtsInPolygs, + double *normal) + { + double coordOfBary[3]; + + calculateBarycenterDyn(coords,nbOfPtsInPolygs,3,coordOfBary); + double xnormal1 = (coords[0][1]-coords[1][1]) * (coordOfBary[2]-coords[1][2]) + - (coords[0][2]-coords[1][2]) * (coordOfBary[1]-coords[1][1]); + + double xnormal2 = (coords[0][2]-coords[1][2]) * (coordOfBary[0]-coords[1][0]) + - (coords[0][0]-coords[1][0]) * (coordOfBary[2]-coords[1][2]); + + double xnormal3 = (coords[0][0]-coords[1][0]) * (coordOfBary[1]-coords[1][1]) + - (coords[0][1]-coords[1][1]) * (coordOfBary[0]-coords[1][0]); + + double xarea=sqrt(xnormal1*xnormal1 + xnormal2*xnormal2 + xnormal3*xnormal3); + + if ( xarea < 1.e-6 ) + { + //std::string diagnosis"Can not calculate normal - polygon is singular"; + throw std::exception(); + } + + xnormal1 = -xnormal1/xarea; + xnormal2 = -xnormal2/xarea; + xnormal3 = -xnormal3/xarea; + xarea = calculateAreaForPolyg(coords,nbOfPtsInPolygs,3); + normal[0] = xnormal1*xarea ; + normal[1] = xnormal2*xarea ; + normal[2] = xnormal3*xarea ; + } + + // ========================== + // Calculate Area for Polygon + // ========================== + inline double calculateAreaForPolyg(const double **coords, int nbOfPtsInPolygs, + int spaceDim) + { + double ret=0.; + double coordOfBary[3]; + + calculateBarycenterDyn(coords,nbOfPtsInPolygs,spaceDim,coordOfBary); + for ( int i=0; i<nbOfPtsInPolygs; i++ ) + { + double tmp = calculateAreaForTria(coords[i],coords[(i+1)%nbOfPtsInPolygs], + coordOfBary,spaceDim); + ret+=tmp; + } + return ret; + } + + double calculateAreaForQPolyg(const double **coords, int nbOfPtsInPolygs, int spaceDim) + { + + if(nbOfPtsInPolygs%2==0) + { + if(spaceDim==2) + { + std::vector<Node *> nodes(nbOfPtsInPolygs); + for(int i=0;i<nbOfPtsInPolygs;i++) + nodes[i]=new Node(coords[i][0],coords[i][1]); + QuadraticPolygon *pol=QuadraticPolygon::BuildArcCirclePolygon(nodes); + double ret=pol->getArea(); + delete pol; + return -ret; + } + else + return calculateAreaForPolyg(coords,nbOfPtsInPolygs/2,spaceDim); + } + else + { + std::ostringstream oss; oss << "INTERP_KERNEL::calculateAreaForQPolyg : nb of points in quadratic polygon is " << nbOfPtsInPolygs << " should be even !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + } + + // ========================== + // Calculate Volume for Tetra + // ========================== + inline double calculateVolumeForTetra(const double *p1, const double *p2, + const double *p3, const double *p4) + { + return ( (p3[0]-p1[0])*( (p2[1]-p1[1])*(p4[2]-p1[2]) + - (p2[2]-p1[2])*(p4[1]-p1[1]) ) + - (p2[0]-p1[0])*( (p3[1]-p1[1])*(p4[2]-p1[2]) + - (p3[2]-p1[2])*(p4[1]-p1[1]) ) + + (p4[0]-p1[0])*( (p3[1]-p1[1])*(p2[2]-p1[2]) + - (p3[2]-p1[2])*(p2[1]-p1[1]) ) + ) / 6.0 ; + } + + // ========================= + // Calculate Volume for Pyra + // ========================= + inline double calculateVolumeForPyra(const double *p1, const double *p2, + const double *p3, const double *p4, + const double *p5) + { + return ( ((p3[0]-p1[0])*( (p2[1]-p1[1])*(p5[2]-p1[2]) + - (p2[2]-p1[2])*(p5[1]-p1[1]) ) + -(p2[0]-p1[0])*( (p3[1]-p1[1])*(p5[2]-p1[2]) + - (p3[2]-p1[2])*(p5[1]-p1[1]) ) + +(p5[0]-p1[0])*( (p3[1]-p1[1])*(p2[2]-p1[2]) + - (p3[2]-p1[2])*(p2[1]-p1[1]) )) + + + ((p4[0]-p1[0])*( (p3[1]-p1[1])*(p5[2]-p1[2]) + - (p3[2]-p1[2])*(p5[1]-p1[1]) ) + -(p3[0]-p1[0])*( (p4[1]-p1[1])*(p5[2]-p1[2]) + - (p4[2]-p1[2])*(p5[1]-p1[1])) + +(p5[0]-p1[0])*( (p4[1]-p1[1])*(p3[2]-p1[2]) + - (p4[2]-p1[2])*(p3[1]-p1[1]) )) + ) / 6.0 ; + } + + // ========================== + // Calculate Volume for Penta + // ========================== + inline double calculateVolumeForPenta(const double *p1, const double *p2, + const double *p3, const double *p4, + const double *p5, const double *p6) + { + double a1 = (p2[0]-p3[0])/2.0, a2 = (p2[1]-p3[1])/2.0, a3 = (p2[2]-p3[2])/2.0; + double b1 = (p5[0]-p6[0])/2.0, b2 = (p5[1]-p6[1])/2.0, b3 = (p5[2]-p6[2])/2.0; + double c1 = (p4[0]-p1[0])/2.0, c2 = (p4[1]-p1[1])/2.0, c3 = (p4[2]-p1[2])/2.0; + double d1 = (p5[0]-p2[0])/2.0, d2 = (p5[1]-p2[1])/2.0, d3 = (p5[2]-p2[2])/2.0; + double e1 = (p6[0]-p3[0])/2.0, e2 = (p6[1]-p3[1])/2.0, e3 = (p6[2]-p3[2])/2.0; + double f1 = (p1[0]-p3[0])/2.0, f2 = (p1[1]-p3[1])/2.0, f3 = (p1[2]-p3[2])/2.0; + double h1 = (p4[0]-p6[0])/2.0, h2 = (p4[1]-p6[1])/2.0, h3 = (p4[2]-p6[2])/2.0; + + double A = a1*c2*f3 - a1*c3*f2 - a2*c1*f3 + a2*c3*f1 + a3*c1*f2 - a3*c2*f1; + double B = b1*c2*h3 - b1*c3*h2 - b2*c1*h3 + b2*c3*h1 + b3*c1*h2 - b3*c2*h1; + double C = (a1*c2*h3 + b1*c2*f3) - (a1*c3*h2 + b1*c3*f2) + - (a2*c1*h3 + b2*c1*f3) + (a2*c3*h1 + b2*c3*f1) + + (a3*c1*h2 + b3*c1*f2) - (a3*c2*h1 + b3*c2*f1); + double D = a1*d2*f3 - a1*d3*f2 - a2*d1*f3 + a2*d3*f1 + a3*d1*f2 - a3*d2*f1; + double E = b1*d2*h3 - b1*d3*h2 - b2*d1*h3 + b2*d3*h1 + b3*d1*h2 - b3*d2*h1; + double F = (a1*d2*h3 + b1*d2*f3) - (a1*d3*h2 + b1*d3*f2) + - (a2*d1*h3 + b2*d1*f3) + (a2*d3*h1 + b2*d3*f1) + + (a3*d1*h2 + b3*d1*f2) - (a3*d2*h1 + b3*d2*f1); + double G = a1*e2*f3 - a1*e3*f2 - a2*e1*f3 + a2*e3*f1 + a3*e1*f2 - a3*e2*f1; + double H = b1*e2*h3 - b1*e3*h2 - b2*e1*h3 + b2*e3*h1 + b3*e1*h2 - b3*e2*h1; + double P = (a1*e2*h3 + b1*e2*f3) - (a1*e3*h2 + b1*e3*f2) + - (a2*e1*h3 + b2*e1*f3) + (a2*e3*h1 + b2*e3*f1) + + (a3*e1*h2 + b3*e1*f2) - (a3*e2*h1 + b3*e2*f1); + + return (-2.0*(2.0*(A + B + D + E + G + H) + C + F + P)/9.0); + } + + // ========================= + // Calculate Volume for Hexa + // ========================= + inline double calculateVolumeForHexa(const double *pt1, const double *pt2, + const double *pt3, const double *pt4, + const double *pt5, const double *pt6, + const double *pt7, const double *pt8) + { + double a1=(pt3[0]-pt4[0])/8.0, a2=(pt3[1]-pt4[1])/8.0, a3=(pt3[2]-pt4[2])/8.0; + double b1=(pt2[0]-pt1[0])/8.0, b2=(pt2[1]-pt1[1])/8.0, b3=(pt2[2]-pt1[2])/8.0; + double c1=(pt7[0]-pt8[0])/8.0, c2=(pt7[1]-pt8[1])/8.0, c3=(pt7[2]-pt8[2])/8.0; + double d1=(pt6[0]-pt5[0])/8.0, d2=(pt6[1]-pt5[1])/8.0, d3=(pt6[2]-pt5[2])/8.0; + double e1=(pt3[0]-pt2[0])/8.0, e2=(pt3[1]-pt2[1])/8.0, e3=(pt3[2]-pt2[2])/8.0; + double f1=(pt4[0]-pt1[0])/8.0, f2=(pt4[1]-pt1[1])/8.0, f3=(pt4[2]-pt1[2])/8.0; + double h1=(pt7[0]-pt6[0])/8.0, h2=(pt7[1]-pt6[1])/8.0, h3=(pt7[2]-pt6[2])/8.0; + double p1=(pt8[0]-pt5[0])/8.0, p2=(pt8[1]-pt5[1])/8.0, p3=(pt8[2]-pt5[2])/8.0; + double q1=(pt3[0]-pt7[0])/8.0, q2=(pt3[1]-pt7[1])/8.0, q3=(pt3[2]-pt7[2])/8.0; + double r1=(pt4[0]-pt8[0])/8.0, r2=(pt4[1]-pt8[1])/8.0, r3=(pt4[2]-pt8[2])/8.0; + double s1=(pt2[0]-pt6[0])/8.0, s2=(pt2[1]-pt6[1])/8.0, s3=(pt2[2]-pt6[2])/8.0; + double t1=(pt1[0]-pt5[0])/8.0, t2=(pt1[1]-pt5[1])/8.0, t3=(pt1[2]-pt5[2])/8.0; + + double A = a1*e2*q3 - a1*e3*q2 - a2*e1*q3 + a2*e3*q1 + a3*e1*q2 - a3*e2*q1; + double B = c1*h2*q3 - c1*h3*q2 - c2*h1*q3 + c2*h3*q1 + c3*h1*q2 - c3*h2*q1; + double C = (a1*h2 + c1*e2)*q3 - (a1*h3 + c1*e3)*q2 + - (a2*h1 + c2*e1)*q3 + (a2*h3 + c2*e3)*q1 + + (a3*h1 + c3*e1)*q2 - (a3*h2 + c3*e2)*q1; + double D = b1*e2*s3 - b1*e3*s2 - b2*e1*s3 + b2*e3*s1 + b3*e1*s2 - b3*e2*s1; + double E = d1*h2*s3 - d1*h3*s2 - d2*h1*s3 + d2*h3*s1 + d3*h1*s2 - d3*h2*s1; + double F = (b1*h2 + d1*e2)*s3 - (b1*h3 + d1*e3)*s2 + - (b2*h1 + d2*e1)*s3 + (b2*h3 + d2*e3)*s1 + + (b3*h1 + d3*e1)*s2 - (b3*h2 + d3*e2)*s1; + double G = (a1*e2*s3 + b1*e2*q3) - (a1*e3*s2 + b1*e3*q2) + - (a2*e1*s3 + b2*e1*q3) + (a2*e3*s1 + b2*e3*q1) + + (a3*e1*s2 + b3*e1*q2) - (a3*e2*s1 + b3*e2*q1); + double H = (c1*h2*s3 + d1*h2*q3) - (c1*h3*s2 + d1*h3*q2) + - (c2*h1*s3 + d2*h1*q3) + (c2*h3*s1 + d2*h3*q1) + + (c3*h1*s2 + d3*h1*q2) - (c3*h2*s1 + d3*h2*q1); + double I = ((a1*h2 + c1*e2)*s3 + (b1*h2 + d1*e2)*q3) + - ((a1*h3 + c1*e3)*s2 + (b1*h3 + d1*e3)*q2) + - ((a2*h1 + c2*e1)*s3 + (b2*h1 + d2*e1)*q3) + + ((a2*h3 + c2*e3)*s1 + (b2*h3 + d2*e3)*q1) + + ((a3*h1 + c3*e1)*s2 + (b3*h1 + d3*e1)*q2) + - ((a3*h2 + c3*e2)*s1 + (b3*h2 + d3*e2)*q1); + double J = a1*f2*r3 - a1*f3*r2 - a2*f1*r3 + a2*f3*r1 + a3*f1*r2 - a3*f2*r1; + double K = c1*p2*r3 - c1*p3*r2 - c2*p1*r3 + c2*p3*r1 + c3*p1*r2 - c3*p2*r1; + double L = (a1*p2 + c1*f2)*r3 - (a1*p3 + c1*f3)*r2 + - (a2*p1 + c2*f1)*r3 + (a2*p3 + c2*f3)*r1 + + (a3*p1 + c3*f1)*r2 - (a3*p2 + c3*f2)*r1; + double M = b1*f2*t3 - b1*f3*t2 - b2*f1*t3 + b2*f3*t1 + b3*f1*t2 - b3*f2*t1; + double N = d1*p2*t3 - d1*p3*t2 - d2*p1*t3 + d2*p3*t1 + d3*p1*t2 - d3*p2*t1; + double O = (b1*p2 + d1*f2)*t3 - (b1*p3 + d1*f3)*t2 + - (b2*p1 + d2*f1)*t3 + (b2*p3 + d2*f3)*t1 + + (b3*p1 + d3*f1)*t2 - (b3*p2 + d3*f2)*t1; + double P = (a1*f2*t3 + b1*f2*r3) - (a1*f3*t2 + b1*f3*r2) + - (a2*f1*t3 + b2*f1*r3) + (a2*f3*t1 + b2*f3*r1) + + (a3*f1*t2 + b3*f1*r2) - (a3*f2*t1 + b3*f2*r1); + double Q = (c1*p2*t3 + d1*p2*r3) - (c1*p3*t2 + d1*p3*r2) + - (c2*p1*t3 + d2*p1*r3) + (c2*p3*t1 + d2*p3*r1) + + (c3*p1*t2 + d3*p1*r2) - (c3*p2*t1 + d3*p2*r1); + double R = ((a1*p2 + c1*f2)*t3 + (b1*p2 + d1*f2)*r3) + - ((a1*p3 + c1*f3)*t2 + (b1*p3 + d1*f3)*r2) + - ((a2*p1 + c2*f1)*t3 + (b2*p1 + d2*f1)*r3) + + ((a2*p3 + c2*f3)*t1 + (b2*p3 + d2*f3)*r1) + + ((a3*p1 + c3*f1)*t2 + (b3*p1 + d3*f1)*r2) + - ((a3*p2 + c3*f2)*t1 + (b3*p2 + d3*f2)*r1); + double S = (a1*e2*r3 + a1*f2*q3) - (a1*e3*r2 + a1*f3*q2) + - (a2*e1*r3 + a2*f1*q3) + (a2*e3*r1 + a2*f3*q1) + + (a3*e1*r2 + a3*f1*q2) - (a3*e2*r1 + a3*f2*q1); + double T = (c1*h2*r3 + c1*p2*q3) - (c1*h3*r2 + c1*p3*q2) + - (c2*h1*r3 + c2*p1*q3) + (c2*h3*r1 + c2*p3*q1) + + (c3*h1*r2 + c3*p1*q2) - (c3*h2*r1 + c3*p2*q1); + double U = ((a1*h2 + c1*e2)*r3 + (a1*p2 + c1*f2)*q3) + - ((a1*h3 + c1*e3)*r2 + (a1*p3 + c1*f3)*q2) + - ((a2*h1 + c2*e1)*r3 + (a2*p1 + c2*f1)*q3) + + ((a2*h3 + c2*e3)*r1 + (a2*p3 + c2*f3)*q1) + + ((a3*h1 + c3*e1)*r2 + (a3*p1 + c3*f1)*q2) + - ((a3*h2 + c3*e2)*r1 + (a3*p2 + c3*f2)*q1); + double V = (b1*e2*t3 + b1*f2*s3) - (b1*e3*t2 + b1*f3*s2) + - (b2*e1*t3 + b2*f1*s3) + (b2*e3*t1 + b2*f3*s1) + + (b3*e1*t2 + b3*f1*s2) - (b3*e2*t1 + b3*f2*s1); + double W = (d1*h2*t3 + d1*p2*s3) - (d1*h3*t2 + d1*p3*s2) + - (d2*h1*t3 + d2*p1*s3) + (d2*h3*t1 + d2*p3*s1) + + (d3*h1*t2 + d3*p1*s2) - (d3*h2*t1 + d3*p2*s1); + double X = ((b1*h2 + d1*e2)*t3 + (b1*p2 + d1*f2)*s3) + - ((b1*h3 + d1*e3)*t2 + (b1*p3 + d1*f3)*s2) + - ((b2*h1 + d2*e1)*t3 + (b2*p1 + d2*f1)*s3) + + ((b2*h3 + d2*e3)*t1 + (b2*p3 + d2*f3)*s1) + + ((b3*h1 + d3*e1)*t2 + (b3*p1 + d3*f1)*s2) + - ((b3*h2 + d3*e2)*t1 + (b3*p2 + d3*f2)*s1); + double Y = (a1*e2*t3 + a1*f2*s3 + b1*e2*r3 + b1*f2*q3) + - (a1*e3*t2 + a1*f3*s2 + b1*e3*r2 + b1*f3*q2) + - (a2*e1*t3 + a2*f1*s3 + b2*e1*r3 + b2*f1*q3) + + (a2*e3*t1 + a2*f3*s1 + b2*e3*r1 + b2*f3*q1) + + (a3*e1*t2 + a3*f1*s2 + b3*e1*r2 + b3*f1*q2) + - (a3*e2*t1 + a3*f2*s1 + b3*e2*r1 + b3*f2*q1); + double Z = (c1*h2*t3 + c1*p2*s3 + d1*h2*r3 + d1*p2*q3) + - (c1*h3*t2 + c1*p3*s2 + d1*h3*r2 + d1*p3*q2) + - (c2*h1*t3 + c2*p1*s3 + d2*h1*r3 + d2*p1*q3) + + (c2*h3*t1 + c2*p3*s1 + d2*h3*r1 + d2*p3*q1) + + (c3*h1*t2 + c3*p1*s2 + d3*h1*r2 + d3*p1*q2) + - (c3*h2*t1 + c3*p2*s1 + d3*h2*r1 + d3*p2*q1); + double AA = ((a1*h2 + c1*e2)*t3 + (a1*p2 + c1*f2)*s3 + +(b1*h2 + d1*e2)*r3 + (b1*p2 + d1*f2)*q3) + - ((a1*h3 + c1*e3)*t2 + (a1*p3 + c1*f3)*s2 + +(b1*h3 + d1*e3)*r2 + (b1*p3 + d1*f3)*q2) + - ((a2*h1 + c2*e1)*t3 + (a2*p1 + c2*f1)*s3 + +(b2*h1 + d2*e1)*r3 + (b2*p1 + d2*f1)*q3) + + ((a2*h3 + c2*e3)*t1 + (a2*p3 + c2*f3)*s1 + +(b2*h3 + d2*e3)*r1 + (b2*p3 + d2*f3)*q1) + + ((a3*h1 + c3*e1)*t2 + (a3*p1 + c3*f1)*s2 + +(b3*h1 + d3*e1)*r2 + (b3*p1 + d3*f1)*q2) + - ((a3*h2 + c3*e2)*t1 + (a3*p2 + c3*f2)*s1 + + (b3*h2 + d3*e2)*r1 + (b3*p2 + d3*f2)*q1); + + return 64.0*( 8.0*(A + B + D + E + J + K + M + N) + + 4.0*(C + F + G + H + L + O + P + Q + S + T + V + W) + + 2.0*(I + R + U + X + Y + Z) + AA ) / 27.0 ; + } + + // ========================================================================================================================= + // Calculate Volume for Generic Polyedron, even not convex one, WARNING !!! The polyedron's faces must be correctly ordered + // ========================================================================================================================= + inline double calculateVolumeForPolyh(const double ***pts, + const int *nbOfNodesPerFaces, + int nbOfFaces, + const double *bary) + { + double volume=0.; + + for ( int i=0; i<nbOfFaces; i++ ) + { + double normal[3]; + double vecForAlt[3]; + + calculateNormalForPolyg(pts[i],nbOfNodesPerFaces[i],normal); + vecForAlt[0]=bary[0]-pts[i][0][0]; + vecForAlt[1]=bary[1]-pts[i][0][1]; + vecForAlt[2]=bary[2]-pts[i][0][2]; + volume+=vecForAlt[0]*normal[0]+vecForAlt[1]*normal[1]+vecForAlt[2]*normal[2]; + } + return -volume/3.; + } + + /*! + * Calculate Volume for Generic Polyedron, even not convex one, WARNING !!! The polyedron's faces must be correctly ordered. + * 2nd API avoiding to create double** arrays. The returned value could be negative if polyhedrons faces are not oriented with normal outside of the + * polyhedron + */ + template<class ConnType, NumberingPolicy numPol> + inline double calculateVolumeForPolyh2(const ConnType *connec, int lgth, const double *coords) + { + std::size_t nbOfFaces=std::count(connec,connec+lgth,-1)+1; + double volume=0.; + const int *work=connec; + for(std::size_t iFace=0;iFace<nbOfFaces;iFace++) + { + const int *work2=std::find(work+1,connec+lgth,-1); + std::size_t nbOfNodesOfCurFace=std::distance(work,work2); + double areaVector[3]={0.,0.,0.}; + for(std::size_t ptId=0;ptId<nbOfNodesOfCurFace;ptId++) + { + const double *pti=coords+3*OTT<ConnType,numPol>::coo2C(work[ptId]); + const double *pti1=coords+3*OTT<ConnType,numPol>::coo2C(work[(ptId+1)%nbOfNodesOfCurFace]); + areaVector[0]+=pti[1]*pti1[2]-pti[2]*pti1[1]; + areaVector[1]+=pti[2]*pti1[0]-pti[0]*pti1[2]; + areaVector[2]+=pti[0]*pti1[1]-pti[1]*pti1[0]; + } + const double *pt=coords+3*work[0]; + volume+=pt[0]*areaVector[0]+pt[1]*areaVector[1]+pt[2]*areaVector[2]; + work=work2+1; + } + return volume/6.; + } + + /*! + * This method returns the area oriented vector of a polygon. This method is useful for normal computation without + * any troubles if several edges are colinears. + * @param res must be of size at least 3 to store the result. + */ + template<class ConnType, NumberingPolicy numPol> + inline void areaVectorOfPolygon(const ConnType *connec, int lgth, const double *coords, double *res) + { + res[0]=0.; res[1]=0.; res[2]=0.; + for(int ptId=0;ptId<lgth;ptId++) + { + const double *pti=coords+3*OTT<ConnType,numPol>::coo2C(connec[ptId]); + const double *pti1=coords+3*OTT<ConnType,numPol>::coo2C(connec[(ptId+1)%lgth]); + res[0]+=pti[1]*pti1[2]-pti[2]*pti1[1]; + res[1]+=pti[2]*pti1[0]-pti[0]*pti1[2]; + res[2]+=pti[0]*pti1[1]-pti[1]*pti1[0]; + } + } + + template<class ConnType, NumberingPolicy numPol> + inline void computePolygonBarycenter3D(const ConnType *connec, int lgth, const double *coords, double *res) + { + double area[3]; + areaVectorOfPolygon<ConnType,numPol>(connec,lgth,coords,area); + double norm=sqrt(area[0]*area[0]+area[1]*area[1]+area[2]*area[2]); + if(norm>std::numeric_limits<double>::min()) + { + area[0]/=norm; area[1]/=norm; area[2]/=norm; + res[0]=0.; res[1]=0.; res[2]=0.; + for(int i=1;i<lgth-1;i++) + { + double v[3]; + double tmpArea[3]; + v[0]=(coords[3*OTT<ConnType,numPol>::coo2C(connec[0])]+ + coords[3*OTT<ConnType,numPol>::coo2C(connec[i])]+ + coords[3*OTT<ConnType,numPol>::coo2C(connec[i+1])])/3.; + v[1]=(coords[3*OTT<ConnType,numPol>::coo2C(connec[0])+1]+ + coords[3*OTT<ConnType,numPol>::coo2C(connec[i])+1]+ + coords[3*OTT<ConnType,numPol>::coo2C(connec[i+1])+1])/3.; + v[2]=(coords[3*OTT<ConnType,numPol>::coo2C(connec[0])+2]+ + coords[3*OTT<ConnType,numPol>::coo2C(connec[i])+2]+ + coords[3*OTT<ConnType,numPol>::coo2C(connec[i+1])+2])/3.; + ConnType tmpConn[3]={connec[0],connec[i],connec[i+1]}; + areaVectorOfPolygon<ConnType,numPol>(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<lgth;i++) + { + v[0]=coords[3*OTT<ConnType,numPol>::coo2C(connec[(i+1)%lgth])]-coords[3*OTT<ConnType,numPol>::coo2C(connec[i])]; + v[1]=coords[3*OTT<ConnType,numPol>::coo2C(connec[(i+1)%lgth])+1]-coords[3*OTT<ConnType,numPol>::coo2C(connec[i])+1]; + v[2]=coords[3*OTT<ConnType,numPol>::coo2C(connec[(i+1)%lgth])+2]-coords[3*OTT<ConnType,numPol>::coo2C(connec[i])+2]; + double norm2=sqrt(v[0]*v[0]+v[1]*v[1]+v[2]*v[2]); + res[0]+=(coords[3*OTT<ConnType,numPol>::coo2C(connec[(i+1)%lgth])]+coords[3*OTT<ConnType,numPol>::coo2C(connec[i])])/2.*norm2; + res[1]+=(coords[3*OTT<ConnType,numPol>::coo2C(connec[(i+1)%lgth])+1]+coords[3*OTT<ConnType,numPol>::coo2C(connec[i])+1])/2.*norm2; + res[2]+=(coords[3*OTT<ConnType,numPol>::coo2C(connec[(i+1)%lgth])+2]+coords[3*OTT<ConnType,numPol>::coo2C(connec[i])+2])/2.*norm2; + norm+=norm2; + } + if(norm>std::numeric_limits<double>::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<lgth;i++) + { + res[0]+=coords[3*OTT<ConnType,numPol>::coo2C(connec[i])]; + res[1]+=coords[3*OTT<ConnType,numPol>::coo2C(connec[i])+1]; + res[2]+=coords[3*OTT<ConnType,numPol>::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))+ + 4.*C*(A*(2*u1*v1+u2*v1+u1*v2+2.*u2*v2)+B*(v1*v1+v1*v2+v2*v2))+A*B*(u1*(3.*v1*v1+2.*v1*v2+v2*v2)+u2*(v1*v1+2.*v1*v2+3.*v2*v2)))/24.; + } + + template<class ConnType, NumberingPolicy numPol> + inline void barycenterOfPolyhedron(const ConnType *connec, int lgth, const double *coords, double *res) + { + std::size_t nbOfFaces=std::count(connec,connec+lgth,-1)+1; + res[0]=0.; res[1]=0.; res[2]=0.; + const int *work=connec; + for(std::size_t i=0;i<nbOfFaces;i++) + { + const int *work2=std::find(work+1,connec+lgth,-1); + int nbOfNodesOfCurFace=(int)std::distance(work,work2); + // projection to (u,v) of each faces of polyh to compute integral(x^2/2) on each faces. + double normal[3]; + areaVectorOfPolygon<ConnType,numPol>(work,nbOfNodesOfCurFace,coords,normal); + double normOfNormal=sqrt(normal[0]*normal[0]+normal[1]*normal[1]+normal[2]*normal[2]); + if(normOfNormal<std::numeric_limits<double>::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]); + double c=normal[2]; + if(fabs(s)>1e-12) + { + u[0]/=std::abs(s); u[1]/=std::abs(s); + } + else + { u[0]=1.; u[1]=0.; } + //C : high in plane of polyhedron face : always constant + double w=normal[0]*coords[3*OTT<ConnType,numPol>::coo2C(work[0])]+ + normal[1]*coords[3*OTT<ConnType,numPol>::coo2C(work[0])+1]+ + normal[2]*coords[3*OTT<ConnType,numPol>::coo2C(work[0])+2]; + // A,B,D,F,G,H,L,M,N coeffs of rotation matrix defined by (u,c,s) + double A=u[0]*u[0]*(1-c)+c; + double B=u[0]*u[1]*(1-c); + double D=u[1]*s; + double F=B; + double G=u[1]*u[1]*(1-c)+c; + double H=-u[0]*s; + double L=-u[1]*s; + double M=u[0]*s; + double N=c; + double CX=-w*D; + double CY=-w*H; + double CZ=-w*N; + for(int j=0;j<nbOfNodesOfCurFace;j++) + { + const double *p1=coords+3*OTT<ConnType,numPol>::coo2C(work[j]); + const double *p2=coords+3*OTT<ConnType,numPol>::coo2C(work[(j+1)%nbOfNodesOfCurFace]); + double u1=A*p1[0]+B*p1[1]+D*p1[2]; + double u2=A*p2[0]+B*p2[1]+D*p2[2]; + double v1=F*p1[0]+G*p1[1]+H*p1[2]; + double v2=F*p2[0]+G*p2[1]+H*p2[2]; + // + double gx=integrationOverA3DLine(u1,v1,u2,v2,A,B,CX); + double gy=integrationOverA3DLine(u1,v1,u2,v2,F,G,CY); + double gz=integrationOverA3DLine(u1,v1,u2,v2,L,M,CZ); + res[0]+=gx*normal[0]; + res[1]+=gy*normal[1]; + res[2]+=gz*normal[2]; + } + work=work2+1; + } + double vol=calculateVolumeForPolyh2<ConnType,numPol>(connec,lgth,coords); + if(fabs(vol)>std::numeric_limits<double>::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<nbOfFaces;i++) + { + const int *work2=std::find(work+1,connec+lgth,-1); + int nbOfNodesOfCurFace=(int)std::distance(work,work2); + double normal[3]; + areaVectorOfPolygon<ConnType,numPol>(work,nbOfNodesOfCurFace,coords,normal); + double normOfNormal=sqrt(normal[0]*normal[0]+normal[1]*normal[1]+normal[2]*normal[2]); + if(normOfNormal<std::numeric_limits<double>::min()) + continue; + sum+=normOfNormal; + double tmpBary[3]; + computePolygonBarycenter3D<ConnType,numPol>(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; + } + } + + // ============================================================================================================================================ + // Calculate Volume for NON Generic Polyedron. Only polydrons with bary included in pts is supported by this method. Result is always positive. + // ============================================================================================================================================ + inline double calculateVolumeForPolyhAbs(const double ***pts, + const int *nbOfNodesPerFaces, + int nbOfFaces, + const double *bary) + { + double volume=0.; + + for ( int i=0; i<nbOfFaces; i++ ) + { + double normal[3]; + double vecForAlt[3]; + + calculateNormalForPolyg(pts[i],nbOfNodesPerFaces[i],normal); + vecForAlt[0]=bary[0]-pts[i][0][0]; + vecForAlt[1]=bary[1]-pts[i][0][1]; + vecForAlt[2]=bary[2]-pts[i][0][2]; + volume+=fabs(vecForAlt[0]*normal[0]+vecForAlt[1]*normal[1]+vecForAlt[2]*normal[2]); + } + return volume/3.; + } + + template<int N> + inline double addComponentsOfVec(const double **pts, int rk) + { + return pts[N-1][rk]+addComponentsOfVec<N-1>(pts,rk); + } + + template<> + inline double addComponentsOfVec<1>(const double **pts, int rk) + { + return pts[0][rk]; + } + + template<int N, int DIM> + inline void calculateBarycenter(const double **pts, double *bary) + { + bary[DIM-1]=addComponentsOfVec<N>(pts,DIM-1)/N; + calculateBarycenter<N,DIM-1>(pts,bary); + } + + template<> + inline void calculateBarycenter<2,0>(const double ** /*pts*/, double * /*bary*/) + { + } + + template<> + inline void calculateBarycenter<3,0>(const double ** /*pts*/, double * /*bary*/) + { + } + + template<> + inline void calculateBarycenter<4,0>(const double ** /*pts*/, double * /*bary*/) + { + } + + template<> + inline void calculateBarycenter<5,0>(const double ** /*pts*/, double * /*bary*/) + { + } + + template<> + inline void calculateBarycenter<6,0>(const double ** /*pts*/, double * /*bary*/) + { + } + + template<> + inline void calculateBarycenter<7,0>(const double ** /*pts*/, double * /*bary*/) + { + } + + template<> + inline void calculateBarycenter<8,0>(const double ** /*pts*/, double * /*bary*/) + { + } + + inline void calculateBarycenterDyn(const double **pts, int nbPts, + int dim, double *bary) + { + for(int i=0;i<dim;i++) + { + double temp=0.; + for(int j=0;j<nbPts;j++) + { + temp+=pts[j][i]; + } + bary[i]=temp/nbPts; + } + } + + template<int SPACEDIM> + inline void calculateBarycenterDyn2(const double *pts, int nbPts, double *bary) + { + for(int i=0;i<SPACEDIM;i++) + { + double temp=0.; + for(int j=0;j<nbPts;j++) + { + temp+=pts[j*SPACEDIM+i]; + } + bary[i]=temp/nbPts; + } + } + + inline void computePolygonBarycenter2DEngine(double **coords, int lgth, double *res) + { + double area=0.; + res[0]=0.; res[1]=0.; + for(int i=0;i<lgth;i++) + { + double cp=coords[i][0]*coords[(i+1)%lgth][1]-coords[i][1]*coords[(i+1)%lgth][0]; + area+=cp; + 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<class ConnType, NumberingPolicy numPol> + inline void computePolygonBarycenter2D(const ConnType *connec, int lgth, const double *coords, double *res) + { + double **coords2=new double *[lgth]; + for(int i=0;i<lgth;i++) + coords2[i]=const_cast<double *>(coords+2*OTT<ConnType,numPol>::coo2C(connec[i])); + computePolygonBarycenter2DEngine(coords2,lgth,res); + delete [] coords2; + } + + inline void computeQPolygonBarycenter2D(double **coords, int nbOfPtsInPolygs, int spaceDim, double *res) + { + if(nbOfPtsInPolygs%2==0) + { + if(spaceDim==2) + { + std::vector<Node *> nodes(nbOfPtsInPolygs); + for(int i=0;i<nbOfPtsInPolygs;i++) + nodes[i]=new Node(coords[i][0],coords[i][1]); + QuadraticPolygon *pol=QuadraticPolygon::BuildArcCirclePolygon(nodes); + pol->getBarycenter(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()); + } + } +} + +#endif diff --git a/src/medtool/src/INTERP_KERNEL/VolSurfUser.cxx b/src/medtool/src/INTERP_KERNEL/VolSurfUser.cxx new file mode 100644 index 000000000..dcbf7b6f4 --- /dev/null +++ b/src/medtool/src/INTERP_KERNEL/VolSurfUser.cxx @@ -0,0 +1,137 @@ +// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 +// 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 <cmath> +#include <limits> +#include <algorithm> +#include <functional> + +namespace INTERP_KERNEL +{ + double SquareDistanceFromPtToSegInSpaceDim2(const double *pt, const double *pt0Seg2, const double *pt1Seg2, std::size_t &nbOfHint) + { + 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<double>::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) + { + double matrix[12]; + if(!ComputeRotTranslationMatrixToPut3PointsOnOXY(pt0Tri3,pt1Tri3,pt2Tri3,matrix)) + return std::numeric_limits<double>::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<double>::max(); + std::size_t nbOfHint=0; + if(xy[0]>0. && xy[0]<xy1[0]) + { ret=std::min(ret,z*z+xy[1]*xy[1]); nbOfHint++; } //distance pt to edge [pt0Tri3,pt1Tri3] + double tmp=SquareDistanceFromPtToSegInSpaceDim2(xy,xy1,xy2,nbOfHint); //distance pt to edge [pt1Tri3,pt2Tri3] + ret=std::min(ret,z*z+tmp); + tmp=SquareDistanceFromPtToSegInSpaceDim2(xy,xy2,xy0,nbOfHint);//distance pt to edge [pt2Tri3,pt0Tri3] + ret=std::min(ret,z*z+tmp); + if(nbOfHint==3) + ret=std::min(ret,z*z); + return sqrt(ret); + } + + double DistanceFromPtToPolygonInSpaceDim3(const double *pt, const int *connOfPolygonBg, const int *connOfPolygonEnd, const double *coords) + { + std::size_t nbOfEdges=std::distance(connOfPolygonBg,connOfPolygonEnd); + if(nbOfEdges<3) + throw INTERP_KERNEL::Exception("DistanceFromPtToPolygonInSpaceDim3 : trying to compute a distance to a polygon containing less than 3 edges !"); + double baryOfNodes[3]={0.,0.,0.}; + for(std::size_t i=0;i<nbOfEdges;i++) + { baryOfNodes[0]+=coords[3*connOfPolygonBg[i]]; baryOfNodes[1]+=coords[3*connOfPolygonBg[i]+1]; baryOfNodes[2]+=coords[3*connOfPolygonBg[i]+2]; } + std::transform(baryOfNodes,baryOfNodes+3,baryOfNodes,std::bind2nd(std::multiplies<double>(),1./((double)nbOfEdges))); + double matrix[12]; + if(!ComputeRotTranslationMatrixToPut3PointsOnOXY(coords+3*connOfPolygonBg[0],coords+3*connOfPolygonBg[1],baryOfNodes,matrix)) + return std::numeric_limits<double>::max(); + INTERP_KERNEL::AutoPtr<double> 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<nbOfEdges;i++) + { + ptXY[2*i]=matrix[0]*coords[3*connOfPolygonBg[i]]+matrix[1]*coords[3*connOfPolygonBg[i]+1]+matrix[2]*coords[3*connOfPolygonBg[i]+2]+matrix[3]; + ptXY[2*i+1]=matrix[4]*coords[3*connOfPolygonBg[i]]+matrix[5]*coords[3*connOfPolygonBg[i]+1]+matrix[6]*coords[3*connOfPolygonBg[i]+2]+matrix[7]; + } + double xy[2]={matrix[0]*pt[0]+matrix[1]*pt[1]+matrix[2]*pt[2]+matrix[3],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<double>::max(); + std::size_t nbOfHint=0; + for(std::size_t i=0;i<nbOfEdges;i++) + { + double tmp=SquareDistanceFromPtToSegInSpaceDim2(xy,((double *)ptXY)+2*i,((double *)ptXY)+2*((i+1)%nbOfEdges),nbOfHint); + ret=std::min(ret,z*z+tmp); + } + if(nbOfHint==nbOfEdges) + ret=std::min(ret,z*z); + return sqrt(ret); + } + + /*! + * \param [out] matrix contain a dense matrix of size 12 with 3 rows containing each 4 colums. This matrix is the reduction of 4x4 matrix but the last + * line containing [0,0,0,1] is omitted. + */ + bool ComputeRotTranslationMatrixToPut3PointsOnOXY(const double *p0, const double *p1, const double *p2, double *matrix) + { + double norm=sqrt((p1[0]-p0[0])*(p1[0]-p0[0])+(p1[1]-p0[1])*(p1[1]-p0[1])+(p1[2]-p0[2])*(p1[2]-p0[2])); + double c=(p1[0]-p0[0])/norm; + double s=sqrt(1-c*c); + double y=p1[2]-p0[2],z=p0[1]-p1[1]; + norm=sqrt(y*y+z*z); + if(norm!=0.) + { y/=norm; z/=norm; } + double r0[9]={c,-z*s,y*s, + z*s,y*y*(1-c)+c,y*z*(1-c), + -y*s,z*y*(1-c),z*z*(1-c)+c}; + // 2nd rotation matrix + double x=p2[0]-p0[0]; + y=p2[1]-p0[1]; z=p2[2]-p0[2]; + double y1=x*r0[3]+y*r0[4]+z*r0[5],z1=x*r0[6]+y*r0[7]+z*r0[8]; + c=y1/sqrt(y1*y1+z1*z1); + s=sqrt(1.-c*c); + // + std::copy(r0,r0+3,matrix); + matrix[4]=c*r0[3]-s*r0[6]; matrix[5]=c*r0[4]-s*r0[7]; matrix[6]=c*r0[5]-s*r0[8]; + matrix[8]=s*r0[3]+c*r0[6]; matrix[9]=s*r0[4]+c*r0[7]; matrix[10]=s*r0[5]+c*r0[8]; + matrix[3]=-p0[0]*matrix[0]-p0[1]*matrix[1]-p0[2]*matrix[2]; + matrix[7]=-p0[0]*matrix[4]-p0[1]*matrix[5]-p0[2]*matrix[6]; + matrix[11]=-p0[0]*matrix[8]-p0[1]*matrix[9]-p0[2]*matrix[10]; + return true; + } +} + diff --git a/src/medtool/src/INTERP_KERNEL/VolSurfUser.hxx b/src/medtool/src/INTERP_KERNEL/VolSurfUser.hxx new file mode 100644 index 000000000..de1f82fa1 --- /dev/null +++ b/src/medtool/src/INTERP_KERNEL/VolSurfUser.hxx @@ -0,0 +1,51 @@ +// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 +// 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 __VOLSURFUSER_HXX__ +#define __VOLSURFUSER_HXX__ + +#include "INTERPKERNELDefines.hxx" +#include "InterpKernelException.hxx" +#include "NormalizedUnstructuredMesh.hxx" + +namespace INTERP_KERNEL +{ + template<class ConnType, NumberingPolicy numPolConn, int SPACEDIM> + double computeVolSurfOfCell(NormalizedCellType type, const ConnType *connec, int lgth, const double *coords); + + template<class ConnType, NumberingPolicy numPolConn> + double computeVolSurfOfCell2(NormalizedCellType type, const ConnType *connec, int lgth, const double *coords, int spaceDim); + + template<class ConnType, NumberingPolicy numPolConn, int SPACEDIM> + void computeBarycenter(NormalizedCellType type, const ConnType *connec, int lgth, const double *coords, double *res); + + template<class ConnType, NumberingPolicy numPolConn> + void computeBarycenter2(NormalizedCellType type, const ConnType *connec, int lgth, const double *coords, int spaceDim, double *res); + + double INTERPKERNEL_EXPORT SquareDistanceFromPtToSegInSpaceDim2(const double *pt, const double *pt0Seg2, const double *pt1Seg2, std::size_t &nbOfHint); + + double INTERPKERNEL_EXPORT DistanceFromPtToTriInSpaceDim3(const double *pt, const double *pt0Tri3, const double *pt1Tri3, const double *pt2Tri3); + + double INTERPKERNEL_EXPORT DistanceFromPtToPolygonInSpaceDim3(const double *pt, const int *connOfPolygonBg, const int *connOfPolygonEnd, const double *coords); + + bool ComputeRotTranslationMatrixToPut3PointsOnOXY(const double *pt0Tri3, const double *pt1Tri3, const double *pt2Tri3, double *matrix); +} + +#endif diff --git a/src/medtool/src/INTERP_KERNEL/VolSurfUser.txx b/src/medtool/src/INTERP_KERNEL/VolSurfUser.txx new file mode 100644 index 000000000..c3f1aa4b0 --- /dev/null +++ b/src/medtool/src/INTERP_KERNEL/VolSurfUser.txx @@ -0,0 +1,438 @@ +// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 +// 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 __VOLSURFUSER_TXX__ +#define __VOLSURFUSER_TXX__ + +#include "VolSurfUser.hxx" +#include "VolSurfFormulae.hxx" +#include "InterpolationUtils.hxx" + +#include <algorithm> + +namespace INTERP_KERNEL +{ + template<class ConnType, NumberingPolicy numPol, int SPACEDIM> + double computeVolSurfOfCell(NormalizedCellType type, const ConnType *connec, int lgth, const double *coords) + { + switch(type) + { + case INTERP_KERNEL::NORM_SEG2 : + case INTERP_KERNEL::NORM_SEG4 : + { + int N1 = OTT<ConnType,numPol>::coo2C(connec[0]); + int N2 = OTT<ConnType,numPol>::coo2C(connec[1]); + return INTERP_KERNEL::calculateLgthForSeg2(coords+(SPACEDIM*N1),coords+(SPACEDIM*N2),SPACEDIM); + } + case INTERP_KERNEL::NORM_SEG3 : + { + int beginNode = OTT<ConnType,numPol>::coo2C(connec[0]); + int endNode = OTT<ConnType,numPol>::coo2C(connec[1]); + int middleNode = OTT<ConnType,numPol>::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<ConnType,numPol>::coo2C(connec[0]); + int N2 = OTT<ConnType,numPol>::coo2C(connec[1]); + int N3 = OTT<ConnType,numPol>::coo2C(connec[2]); + + return INTERP_KERNEL::calculateAreaForTria(coords+(SPACEDIM*N1), + coords+(SPACEDIM*N2), + coords+(SPACEDIM*N3), + SPACEDIM); + } + break; + + case INTERP_KERNEL::NORM_TRI6 : + case INTERP_KERNEL::NORM_TRI7 : + { + const double *pts[6]; + pts[0] = coords+SPACEDIM*OTT<ConnType,numPol>::coo2C(connec[0]); + pts[1] = coords+SPACEDIM*OTT<ConnType,numPol>::coo2C(connec[1]); + pts[2] = coords+SPACEDIM*OTT<ConnType,numPol>::coo2C(connec[2]); + pts[3] = coords+SPACEDIM*OTT<ConnType,numPol>::coo2C(connec[3]); + pts[4] = coords+SPACEDIM*OTT<ConnType,numPol>::coo2C(connec[4]); + pts[5] = coords+SPACEDIM*OTT<ConnType,numPol>::coo2C(connec[5]); + return INTERP_KERNEL::calculateAreaForQPolyg(pts,6,SPACEDIM); + } + break; + case INTERP_KERNEL::NORM_QUAD4 : + { + int N1 = OTT<ConnType,numPol>::coo2C(connec[0]); + int N2 = OTT<ConnType,numPol>::coo2C(connec[1]); + int N3 = OTT<ConnType,numPol>::coo2C(connec[2]); + int N4 = OTT<ConnType,numPol>::coo2C(connec[3]); + + return INTERP_KERNEL::calculateAreaForQuad(coords+SPACEDIM*N1, + coords+SPACEDIM*N2, + coords+SPACEDIM*N3, + coords+SPACEDIM*N4, + SPACEDIM); + } + break; + case INTERP_KERNEL::NORM_QUAD8 : + case INTERP_KERNEL::NORM_QUAD9 : + { + const double *pts[8]; + pts[0] = coords+SPACEDIM*OTT<ConnType,numPol>::coo2C(connec[0]); + pts[1] = coords+SPACEDIM*OTT<ConnType,numPol>::coo2C(connec[1]); + pts[2] = coords+SPACEDIM*OTT<ConnType,numPol>::coo2C(connec[2]); + pts[3] = coords+SPACEDIM*OTT<ConnType,numPol>::coo2C(connec[3]); + pts[4] = coords+SPACEDIM*OTT<ConnType,numPol>::coo2C(connec[4]); + pts[5] = coords+SPACEDIM*OTT<ConnType,numPol>::coo2C(connec[5]); + pts[6] = coords+SPACEDIM*OTT<ConnType,numPol>::coo2C(connec[6]); + pts[7] = coords+SPACEDIM*OTT<ConnType,numPol>::coo2C(connec[7]); + return INTERP_KERNEL::calculateAreaForQPolyg(pts,8,SPACEDIM); + } + break; + case INTERP_KERNEL::NORM_POLYGON : + { + const double **pts=new const double *[lgth]; + for(int inod=0;inod<lgth;inod++) + pts[inod] = coords+SPACEDIM*OTT<ConnType,numPol>::coo2C(connec[inod]); + double val=INTERP_KERNEL::calculateAreaForPolyg(pts,lgth,SPACEDIM); + delete [] pts; + return val; + } + break; + case INTERP_KERNEL::NORM_QPOLYG : + { + const double **pts=new const double *[lgth]; + for(int inod=0;inod<lgth;inod++) + pts[inod] = coords+SPACEDIM*OTT<ConnType,numPol>::coo2C(connec[inod]); + double val=INTERP_KERNEL::calculateAreaForQPolyg(pts,lgth,SPACEDIM); + delete [] pts; + return val; + } + break; + case INTERP_KERNEL::NORM_TETRA4 : + case INTERP_KERNEL::NORM_TETRA10 : + { + int N1 = OTT<ConnType,numPol>::coo2C(connec[0]); + int N2 = OTT<ConnType,numPol>::coo2C(connec[1]); + int N3 = OTT<ConnType,numPol>::coo2C(connec[2]); + int N4 = OTT<ConnType,numPol>::coo2C(connec[3]); + + return INTERP_KERNEL::calculateVolumeForTetra(coords+SPACEDIM*N1, + coords+SPACEDIM*N2, + coords+SPACEDIM*N3, + coords+SPACEDIM*N4); + } + break; + + case INTERP_KERNEL::NORM_PYRA5 : + case INTERP_KERNEL::NORM_PYRA13 : + { + int N1 = OTT<ConnType,numPol>::coo2C(connec[0]); + int N2 = OTT<ConnType,numPol>::coo2C(connec[1]); + int N3 = OTT<ConnType,numPol>::coo2C(connec[2]); + int N4 = OTT<ConnType,numPol>::coo2C(connec[3]); + int N5 = OTT<ConnType,numPol>::coo2C(connec[4]); + + return INTERP_KERNEL::calculateVolumeForPyra(coords+SPACEDIM*N1, + coords+SPACEDIM*N2, + coords+SPACEDIM*N3, + coords+SPACEDIM*N4, + coords+SPACEDIM*N5); + } + break; + + case INTERP_KERNEL::NORM_PENTA6 : + case INTERP_KERNEL::NORM_PENTA15 : + { + int N1 = OTT<ConnType,numPol>::coo2C(connec[0]); + int N2 = OTT<ConnType,numPol>::coo2C(connec[1]); + int N3 = OTT<ConnType,numPol>::coo2C(connec[2]); + int N4 = OTT<ConnType,numPol>::coo2C(connec[3]); + int N5 = OTT<ConnType,numPol>::coo2C(connec[4]); + int N6 = OTT<ConnType,numPol>::coo2C(connec[5]); + + return INTERP_KERNEL::calculateVolumeForPenta(coords+SPACEDIM*N1, + coords+SPACEDIM*N2, + coords+SPACEDIM*N3, + coords+SPACEDIM*N4, + coords+SPACEDIM*N5, + coords+SPACEDIM*N6); + } + break; + + case INTERP_KERNEL::NORM_HEXA8 : + case INTERP_KERNEL::NORM_HEXA20 : + case INTERP_KERNEL::NORM_HEXA27 : + { + int N1 = OTT<ConnType,numPol>::coo2C(connec[0]); + int N2 = OTT<ConnType,numPol>::coo2C(connec[1]); + int N3 = OTT<ConnType,numPol>::coo2C(connec[2]); + int N4 = OTT<ConnType,numPol>::coo2C(connec[3]); + int N5 = OTT<ConnType,numPol>::coo2C(connec[4]); + int N6 = OTT<ConnType,numPol>::coo2C(connec[5]); + int N7 = OTT<ConnType,numPol>::coo2C(connec[6]); + int N8 = OTT<ConnType,numPol>::coo2C(connec[7]); + + return INTERP_KERNEL::calculateVolumeForHexa(coords+SPACEDIM*N1, + coords+SPACEDIM*N2, + coords+SPACEDIM*N3, + coords+SPACEDIM*N4, + coords+SPACEDIM*N5, + coords+SPACEDIM*N6, + coords+SPACEDIM*N7, + coords+SPACEDIM*N8); + } + break; + case INTERP_KERNEL::NORM_HEXGP12: + { + const int connecHexa12[43]={ + OTT<ConnType,numPol>::coo2C(connec[0]),OTT<ConnType,numPol>::coo2C(connec[1]),OTT<ConnType,numPol>::coo2C(connec[2]),OTT<ConnType,numPol>::coo2C(connec[3]),OTT<ConnType,numPol>::coo2C(connec[4]),OTT<ConnType,numPol>::coo2C(connec[5]),-1, + OTT<ConnType,numPol>::coo2C(connec[6]),OTT<ConnType,numPol>::coo2C(connec[11]),OTT<ConnType,numPol>::coo2C(connec[10]),OTT<ConnType,numPol>::coo2C(connec[9]),OTT<ConnType,numPol>::coo2C(connec[8]),OTT<ConnType,numPol>::coo2C(connec[7]),-1, + OTT<ConnType,numPol>::coo2C(connec[0]),OTT<ConnType,numPol>::coo2C(connec[6]),OTT<ConnType,numPol>::coo2C(connec[7]),OTT<ConnType,numPol>::coo2C(connec[1]),-1, + OTT<ConnType,numPol>::coo2C(connec[1]),OTT<ConnType,numPol>::coo2C(connec[7]),OTT<ConnType,numPol>::coo2C(connec[8]),OTT<ConnType,numPol>::coo2C(connec[2]),-1, + OTT<ConnType,numPol>::coo2C(connec[2]),OTT<ConnType,numPol>::coo2C(connec[8]),OTT<ConnType,numPol>::coo2C(connec[9]),OTT<ConnType,numPol>::coo2C(connec[3]),-1, + OTT<ConnType,numPol>::coo2C(connec[3]),OTT<ConnType,numPol>::coo2C(connec[9]),OTT<ConnType,numPol>::coo2C(connec[10]),OTT<ConnType,numPol>::coo2C(connec[4]),-1, + OTT<ConnType,numPol>::coo2C(connec[4]),OTT<ConnType,numPol>::coo2C(connec[10]),OTT<ConnType,numPol>::coo2C(connec[11]),OTT<ConnType,numPol>::coo2C(connec[5]),-1, + OTT<ConnType,numPol>::coo2C(connec[5]),OTT<ConnType,numPol>::coo2C(connec[11]),OTT<ConnType,numPol>::coo2C(connec[6]),OTT<ConnType,numPol>::coo2C(connec[0])}; + return calculateVolumeForPolyh2<ConnType,numPol>(connecHexa12,43,coords); + } + case INTERP_KERNEL::NORM_POLYHED : + { + return calculateVolumeForPolyh2<ConnType,numPol>(connec,lgth,coords); + } + break; + default: + throw INTERP_KERNEL::Exception("Not recognized cell type to get Length/Area/Volume on it !"); + } + } + + template<class ConnType, NumberingPolicy numPolConn> + double computeVolSurfOfCell2(NormalizedCellType type, const ConnType *connec, int lgth, const double *coords, int spaceDim) + { + if(spaceDim==3) + return computeVolSurfOfCell<ConnType,numPolConn,3>(type,connec,lgth,coords); + if(spaceDim==2) + return computeVolSurfOfCell<ConnType,numPolConn,2>(type,connec,lgth,coords); + if(spaceDim==1) + return computeVolSurfOfCell<ConnType,numPolConn,1>(type,connec,lgth,coords); + throw INTERP_KERNEL::Exception("Invalid spaceDim specified : must be 1, 2 or 3"); + } + + + template<class ConnType, NumberingPolicy numPol,int SPACEDIM> + void computeBarycenter(NormalizedCellType type, const ConnType *connec, int lgth, const double *coords, double *res) + { + switch(type) + { + case NORM_SEG2: + case NORM_SEG4: + { + std::copy(coords+SPACEDIM*OTT<ConnType,numPol>::coo2C(connec[0]), + coords+SPACEDIM*OTT<ConnType,numPol>::coo2C(connec[0]+1),res); + std::transform(res,res+SPACEDIM,coords+SPACEDIM*OTT<ConnType,numPol>::coo2C(connec[1]),res,std::plus<double>()); + std::transform(res,res+SPACEDIM,res,std::bind2nd(std::multiplies<double>(),0.5)); + break; + } + case NORM_SEG3: + { + if(SPACEDIM==2) + { + Edge *ed=Edge::BuildEdgeFrom3Points(coords+2*OTT<ConnType,numPol>::coo2C(connec[0]),coords+2*OTT<ConnType,numPol>::coo2C(connec[2]),coords+2*OTT<ConnType,numPol>::coo2C(connec[1])); + ed->getBarycenter(res); + ed->decrRef(); + } + else if(SPACEDIM==1) + { + *res=(coords[OTT<ConnType,numPol>::coo2C(connec[0])]+coords[OTT<ConnType,numPol>::coo2C(connec[1])])/2.; + } + else if(SPACEDIM==3) + { + std::copy(coords+SPACEDIM*OTT<ConnType,numPol>::coo2C(connec[0]), + coords+SPACEDIM*OTT<ConnType,numPol>::coo2C(connec[0]+1),res); + std::transform(res,res+SPACEDIM,coords+SPACEDIM*OTT<ConnType,numPol>::coo2C(connec[1]),res,std::plus<double>()); + std::transform(res,res+SPACEDIM,res,std::bind2nd(std::multiplies<double>(),0.5)); + } + else + throw INTERP_KERNEL::Exception("computeBarycenter for SEG3 only SPACEDIM 1,2 or 3 supported !"); + break; + } + case NORM_TRI3: + case NORM_TRI7: + { + std::copy(coords+SPACEDIM*OTT<ConnType,numPol>::coo2C(connec[0]), + coords+SPACEDIM*OTT<ConnType,numPol>::coo2C(connec[0]+1),res); + std::transform(res,res+SPACEDIM,coords+SPACEDIM*OTT<ConnType,numPol>::coo2C(connec[1]),res,std::plus<double>()); + std::transform(res,res+SPACEDIM,coords+SPACEDIM*OTT<ConnType,numPol>::coo2C(connec[2]),res,std::plus<double>()); + std::transform(res,res+SPACEDIM,res,std::bind2nd(std::multiplies<double>(),1./3.)); + break; + } + case NORM_TRI6: + { + if(SPACEDIM==2) + { + double *pts[6]; + pts[0] = const_cast<double *>(coords+SPACEDIM*OTT<ConnType,numPol>::coo2C(connec[0])); + pts[1] = const_cast<double *>(coords+SPACEDIM*OTT<ConnType,numPol>::coo2C(connec[1])); + pts[2] = const_cast<double *>(coords+SPACEDIM*OTT<ConnType,numPol>::coo2C(connec[2])); + pts[3] = const_cast<double *>(coords+SPACEDIM*OTT<ConnType,numPol>::coo2C(connec[3])); + pts[4] = const_cast<double *>(coords+SPACEDIM*OTT<ConnType,numPol>::coo2C(connec[4])); + pts[5] = const_cast<double *>(coords+SPACEDIM*OTT<ConnType,numPol>::coo2C(connec[5])); + computeQPolygonBarycenter2D(pts,6,2,res); + } + else if(SPACEDIM==3) + computePolygonBarycenter3D<ConnType,numPol>(connec,lgth/2,coords,res); + else + throw INTERP_KERNEL::Exception("Impossible spacedim linked to cell 2D Cell !"); + break; + } + case NORM_QUAD4: + case NORM_POLYGON: + { + if(SPACEDIM==2) + computePolygonBarycenter2D<ConnType,numPol>(connec,lgth,coords,res); + else if(SPACEDIM==3) + computePolygonBarycenter3D<ConnType,numPol>(connec,lgth,coords,res); + else + throw INTERP_KERNEL::Exception("Impossible spacedim linked to cell 2D Cell !"); + break; + } + case NORM_QUAD8: + { + if(SPACEDIM==2) + { + double *pts[8]; + pts[0] = const_cast<double *>(coords+SPACEDIM*OTT<ConnType,numPol>::coo2C(connec[0])); + pts[1] = const_cast<double *>(coords+SPACEDIM*OTT<ConnType,numPol>::coo2C(connec[1])); + pts[2] = const_cast<double *>(coords+SPACEDIM*OTT<ConnType,numPol>::coo2C(connec[2])); + pts[3] = const_cast<double *>(coords+SPACEDIM*OTT<ConnType,numPol>::coo2C(connec[3])); + pts[4] = const_cast<double *>(coords+SPACEDIM*OTT<ConnType,numPol>::coo2C(connec[4])); + pts[5] = const_cast<double *>(coords+SPACEDIM*OTT<ConnType,numPol>::coo2C(connec[5])); + pts[6] = const_cast<double *>(coords+SPACEDIM*OTT<ConnType,numPol>::coo2C(connec[6])); + pts[7] = const_cast<double *>(coords+SPACEDIM*OTT<ConnType,numPol>::coo2C(connec[7])); + computeQPolygonBarycenter2D(pts,8,2,res); + } + else if(SPACEDIM==3) + computePolygonBarycenter3D<ConnType,numPol>(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<lgth;i++) + pts[i]=const_cast<double *>(coords+2*OTT<ConnType,numPol>::coo2C(connec[i])); + computeQPolygonBarycenter2D(pts,lgth,2,res); + delete [] pts; + } + else if(SPACEDIM==3) + computePolygonBarycenter3D<ConnType,numPol>(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<ConnType,numPol>::coo2C(connec[0])]; + res[1]=coords[3*OTT<ConnType,numPol>::coo2C(connec[0])+1]; + res[2]=coords[3*OTT<ConnType,numPol>::coo2C(connec[0])+2]; + res[0]+=coords[3*OTT<ConnType,numPol>::coo2C(connec[1])]; + res[1]+=coords[3*OTT<ConnType,numPol>::coo2C(connec[1])+1]; + res[2]+=coords[3*OTT<ConnType,numPol>::coo2C(connec[1])+2]; + res[0]+=coords[3*OTT<ConnType,numPol>::coo2C(connec[2])]; + res[1]+=coords[3*OTT<ConnType,numPol>::coo2C(connec[2])+1]; + res[2]+=coords[3*OTT<ConnType,numPol>::coo2C(connec[2])+2]; + res[0]+=coords[3*OTT<ConnType,numPol>::coo2C(connec[3])]; + res[1]+=coords[3*OTT<ConnType,numPol>::coo2C(connec[3])+1]; + res[2]+=coords[3*OTT<ConnType,numPol>::coo2C(connec[3])+2]; + res[0]*=0.25; res[1]*=0.25; res[2]*=0.25; + break; + } + case NORM_PYRA5: + { + double tmp[3]; + computePolygonBarycenter3D<ConnType,numPol>(connec,lgth-1,coords,tmp); + res[0]=(coords[3*OTT<ConnType,numPol>::coo2C(connec[4])]+3.*tmp[0])/4.; + res[1]=(coords[3*OTT<ConnType,numPol>::coo2C(connec[4])+1]+3.*tmp[1])/4.; + res[2]=(coords[3*OTT<ConnType,numPol>::coo2C(connec[4])+2]+3.*tmp[2])/4.; + break; + } + case NORM_HEXA8: + { + const int conn[29]={ + OTT<ConnType,numPol>::coo2C(connec[0]),OTT<ConnType,numPol>::coo2C(connec[1]),OTT<ConnType,numPol>::coo2C(connec[2]),OTT<ConnType,numPol>::coo2C(connec[3]),-1, + OTT<ConnType,numPol>::coo2C(connec[4]),OTT<ConnType,numPol>::coo2C(connec[7]),OTT<ConnType,numPol>::coo2C(connec[6]),OTT<ConnType,numPol>::coo2C(connec[5]),-1, + OTT<ConnType,numPol>::coo2C(connec[0]),OTT<ConnType,numPol>::coo2C(connec[3]),OTT<ConnType,numPol>::coo2C(connec[7]),OTT<ConnType,numPol>::coo2C(connec[4]),-1, + OTT<ConnType,numPol>::coo2C(connec[3]),OTT<ConnType,numPol>::coo2C(connec[2]),OTT<ConnType,numPol>::coo2C(connec[6]),OTT<ConnType,numPol>::coo2C(connec[7]),-1, + OTT<ConnType,numPol>::coo2C(connec[2]),OTT<ConnType,numPol>::coo2C(connec[1]),OTT<ConnType,numPol>::coo2C(connec[5]),OTT<ConnType,numPol>::coo2C(connec[6]),-1, + OTT<ConnType,numPol>::coo2C(connec[0]),OTT<ConnType,numPol>::coo2C(connec[4]),OTT<ConnType,numPol>::coo2C(connec[5]),OTT<ConnType,numPol>::coo2C(connec[1]), + }; + barycenterOfPolyhedron<ConnType,numPol>(conn,29,coords,res); + break; + } + case NORM_PENTA6: + { + const int conn[22]={ + OTT<ConnType,numPol>::coo2C(connec[0]),OTT<ConnType,numPol>::coo2C(connec[1]),OTT<ConnType,numPol>::coo2C(connec[2]),-1, + OTT<ConnType,numPol>::coo2C(connec[3]),OTT<ConnType,numPol>::coo2C(connec[5]),OTT<ConnType,numPol>::coo2C(connec[4]),-1, + OTT<ConnType,numPol>::coo2C(connec[0]),OTT<ConnType,numPol>::coo2C(connec[2]),OTT<ConnType,numPol>::coo2C(connec[5]),OTT<ConnType,numPol>::coo2C(connec[3]),-1, + OTT<ConnType,numPol>::coo2C(connec[2]),OTT<ConnType,numPol>::coo2C(connec[1]),OTT<ConnType,numPol>::coo2C(connec[4]),OTT<ConnType,numPol>::coo2C(connec[5]),-1, + OTT<ConnType,numPol>::coo2C(connec[1]),OTT<ConnType,numPol>::coo2C(connec[0]),OTT<ConnType,numPol>::coo2C(connec[3]),OTT<ConnType,numPol>::coo2C(connec[4]) + }; + barycenterOfPolyhedron<ConnType,numPol>(conn,22,coords,res); + break; + } + case INTERP_KERNEL::NORM_HEXGP12: + { + const int connecHexa12[43]={ + OTT<ConnType,numPol>::coo2C(connec[0]),OTT<ConnType,numPol>::coo2C(connec[1]),OTT<ConnType,numPol>::coo2C(connec[2]),OTT<ConnType,numPol>::coo2C(connec[3]),OTT<ConnType,numPol>::coo2C(connec[4]),OTT<ConnType,numPol>::coo2C(connec[5]),-1, + OTT<ConnType,numPol>::coo2C(connec[6]),OTT<ConnType,numPol>::coo2C(connec[11]),OTT<ConnType,numPol>::coo2C(connec[10]),OTT<ConnType,numPol>::coo2C(connec[9]),OTT<ConnType,numPol>::coo2C(connec[8]),OTT<ConnType,numPol>::coo2C(connec[7]),-1, + OTT<ConnType,numPol>::coo2C(connec[0]),OTT<ConnType,numPol>::coo2C(connec[6]),OTT<ConnType,numPol>::coo2C(connec[7]),OTT<ConnType,numPol>::coo2C(connec[1]),-1, + OTT<ConnType,numPol>::coo2C(connec[1]),OTT<ConnType,numPol>::coo2C(connec[7]),OTT<ConnType,numPol>::coo2C(connec[8]),OTT<ConnType,numPol>::coo2C(connec[2]),-1, + OTT<ConnType,numPol>::coo2C(connec[2]),OTT<ConnType,numPol>::coo2C(connec[8]),OTT<ConnType,numPol>::coo2C(connec[9]),OTT<ConnType,numPol>::coo2C(connec[3]),-1, + OTT<ConnType,numPol>::coo2C(connec[3]),OTT<ConnType,numPol>::coo2C(connec[9]),OTT<ConnType,numPol>::coo2C(connec[10]),OTT<ConnType,numPol>::coo2C(connec[4]),-1, + OTT<ConnType,numPol>::coo2C(connec[4]),OTT<ConnType,numPol>::coo2C(connec[10]),OTT<ConnType,numPol>::coo2C(connec[11]),OTT<ConnType,numPol>::coo2C(connec[5]),-1, + OTT<ConnType,numPol>::coo2C(connec[5]),OTT<ConnType,numPol>::coo2C(connec[11]),OTT<ConnType,numPol>::coo2C(connec[6]),OTT<ConnType,numPol>::coo2C(connec[0])}; + barycenterOfPolyhedron<ConnType,numPol>(connecHexa12,43,coords,res); + break; + } + case NORM_POLYHED: + { + barycenterOfPolyhedron<ConnType,numPol>(connec,lgth,coords,res); + break; + } + default: + throw INTERP_KERNEL::Exception("Not recognized cell type to get Barycenter on it !"); + } + } + + template<class ConnType, NumberingPolicy numPolConn> + void computeBarycenter2(NormalizedCellType type, const ConnType *connec, int lgth, const double *coords, int spaceDim, double *res) + { + if(spaceDim==3) + return computeBarycenter<ConnType,numPolConn,3>(type,connec,lgth,coords,res); + if(spaceDim==2) + return computeBarycenter<ConnType,numPolConn,2>(type,connec,lgth,coords,res); + if(spaceDim==1) + return computeBarycenter<ConnType,numPolConn,1>(type,connec,lgth,coords,res); + throw INTERP_KERNEL::Exception("Invalid spaceDim specified for compute barycenter : must be 1, 2 or 3"); + } +} + +#endif diff --git a/src/medtool/src/INTERP_KERNELTest/BBTreeTest.cxx b/src/medtool/src/INTERP_KERNELTest/BBTreeTest.cxx new file mode 100644 index 000000000..a4420571a --- /dev/null +++ b/src/medtool/src/INTERP_KERNELTest/BBTreeTest.cxx @@ -0,0 +1,307 @@ +// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// + +#include "BBTreeTest.hxx" +#include <iostream> +#include <vector> +#include "DirectedBoundingBox.hxx" + +namespace INTERP_TEST +{ + + + void BBTreeTest::setUp() + { + } + + + void BBTreeTest::tearDown() + { + } + + /** + * Test that creates a tree in 2D and check that + * the results are correct in three + * cases : + * a non matching search + * a standard case + * a bbox overlapping the bboxes of the tree + */ + void BBTreeTest::test_BBTree() { + //bbox tree creation + const int N=10; + double* bbox=new double[4*N*N]; + for (int i=0; i<N; i++) + for (int j=0; j<N; j++) + { + bbox[4*(i*N+j)]=i; + bbox[4*(i*N+j)+1]=i+1; + bbox[4*(i*N+j)+2]=j; + bbox[4*(i*N+j)+3]=j+1; + } + BBTree<2> tree(bbox,0,0,N*N); + std::vector <int> elems; + + //box outside the tree + double bbox1[4]={-2.0, -1.0, 0.0, 1.0}; + tree.getIntersectingElems(bbox1,elems); + CPPUNIT_ASSERT_EQUAL(0,(int)elems.size()); + elems.clear(); + + //box intersecting 4 tree elems + double bbox2[4]={2.5, 3.5, 0.5, 1.5}; + tree.getIntersectingElems(bbox2,elems); + CPPUNIT_ASSERT_EQUAL(4,(int)elems.size()); + elems.clear(); + + //box exactly superimposed to two tree elems + double bbox3[4]={5.0,6.0,7.0,9.0}; + tree.getIntersectingElems(bbox3,elems); + CPPUNIT_ASSERT_EQUAL(2,(int)elems.size()); + elems.clear(); + + double xx[2]={1.0,1.0}; + tree.getElementsAroundPoint(xx,elems); + CPPUNIT_ASSERT_EQUAL(4,(int)elems.size()); + + delete[] bbox; + } + + void BBTreeTest::test_DirectedBB_3D() + { + // a rectangle 1x2 extruded along vector (10,0,10) + const int nbP = 8, dim = 3; + double coords[nbP*dim] = + { + 0,0,0, 2,0,0, 2,1,0, 0,1,0, + 10,0,10, 12,0,10, 12,1,10, 10,1,10 + }; + INTERP_KERNEL::DirectedBoundingBox bb( coords, nbP, dim); + bb.enlarge( 1e-12 ); + + // corners of extrusion are IN + for ( int i = 0; i < nbP*dim; i+=dim ) + CPPUNIT_ASSERT( !bb.isOut( coords + i )); + + // points near corners of extrusion are OUT + double p[nbP*dim] = + { + 0,0,3, 6,0,3, 5,1,2, 0,1,2, + 8,0,9, 11,0,8, 11,0.5,8, 8,0.5,9 + }; + for ( int i = 0; i < nbP*dim; i+=dim ) + CPPUNIT_ASSERT( bb.isOut( p + i )); + + // the extrusions shifted by 3 in XOY plane are OUT + double shifted_X[nbP*dim] = + { + 3,0,0, 5,0,0, 5,1,0, 3,1,0, + 13,0,10, 15,0,10, 15,1,10, 13,1,10 + }; + double shifted_x[nbP*dim] = + { + -3,0,0, -1,0,0, -1,1,0, -3,1,0, + 7,0,10, 9,0,10, 9,1,10, 7,1,10 + }; + double shifted_Y[nbP*dim] = + { + 0,3,0, 2,3,0, 2,4,0, 0,4,0, + 10,3,10, 12,3,10, 12,4,10, 10,4,10 + }; + double shifted_y[nbP*dim] = + { + 0,-3,0, 2,-3,0, 2,-2,0, 0,-2,0, + 10,-3,10, 12,-3,10, 12,-2,10, 10,-2,10 + }; + INTERP_KERNEL::DirectedBoundingBox shiftedBB_x( shifted_x, nbP, dim); + INTERP_KERNEL::DirectedBoundingBox shiftedBB_X( shifted_X, nbP, dim); + INTERP_KERNEL::DirectedBoundingBox shiftedBB_y( shifted_y, nbP, dim); + INTERP_KERNEL::DirectedBoundingBox shiftedBB_Y( shifted_Y, nbP, dim); + + CPPUNIT_ASSERT( bb.isDisjointWith( shiftedBB_x )); + CPPUNIT_ASSERT( bb.isDisjointWith( shiftedBB_X )); + CPPUNIT_ASSERT( bb.isDisjointWith( shiftedBB_y )); + CPPUNIT_ASSERT( bb.isDisjointWith( shiftedBB_Y )); + + // intersecting box is IN + double inters_coords[nbP*dim] = + { + 0,0,0, 2,0,0, 2,1,0, 0,1,0, + 0,0,2, 2,0,2, 2,1,2, 0,1,2 + }; + INTERP_KERNEL::DirectedBoundingBox ibb( inters_coords, nbP, dim); + CPPUNIT_ASSERT( !bb.isDisjointWith( ibb )); + + // overlapping non-directed BB + double overlappingBB[2*dim] = + { + 5,6, 0, 1, -5,4 + }; + CPPUNIT_ASSERT( !bb.isDisjointWith( overlappingBB )); + + // non-overlapping non-directed BB + double nonoverlappingBB_1[2*dim] = + { + 5,6, 0,1, -5,2 + }; + CPPUNIT_ASSERT( bb.isDisjointWith( nonoverlappingBB_1 )); + double nonoverlappingBB_2[2*dim] = + { + 5,6, 0,1, 7,20 + }; + CPPUNIT_ASSERT( bb.isDisjointWith( nonoverlappingBB_2 )); + } + + void BBTreeTest::test_DirectedBB_2D() + { + // a segment of length 2 extruded along vector (10,10) + const int nbP = 4, dim = 2; + double coords[nbP*dim] = + { + 0,0, 2,0, + 10,10, 12,10, + }; + INTERP_KERNEL::DirectedBoundingBox bb( coords, nbP, dim); + bb.enlarge( 1e-12 ); + + // corners of extrusion are IN + for ( int i = 0; i < nbP*dim; i+=dim ) + CPPUNIT_ASSERT( !bb.isOut( coords + i )); + + // points near corners of extrusion are OUT + double p[nbP*dim] = + { + 1,2, 4,1, + 11,8, 8,9, + }; + for ( int i = 0; i < nbP*dim; i+=dim ) + CPPUNIT_ASSERT( bb.isOut( p + i )); + + // the extrusions shifted by 3 along OX are OUT + double shifted_X[nbP*dim] = + { + 3,0, 5,0, + 13,10, 15,10, + }; + double shifted_x[nbP*dim] = + { + -3,0, -1,0, + 7,10, 9,10, + }; + INTERP_KERNEL::DirectedBoundingBox shiftedBB_x( shifted_x, nbP, dim); + INTERP_KERNEL::DirectedBoundingBox shiftedBB_X( shifted_X, nbP, dim); + + CPPUNIT_ASSERT( bb.isDisjointWith( shiftedBB_x )); + CPPUNIT_ASSERT( bb.isDisjointWith( shiftedBB_X )); + + // intersecting box is IN + double inters_coords[nbP*dim] = + { + 0,0, 2,0, + 0,2, 2,2 + }; + INTERP_KERNEL::DirectedBoundingBox ibb( inters_coords, nbP, dim); + CPPUNIT_ASSERT( !bb.isDisjointWith( ibb )); + + // overlapping non-directed BB + double overlappingBB[2*dim] = + { + 5,6, -5,4 + }; + CPPUNIT_ASSERT( !bb.isDisjointWith( overlappingBB )); + + // non-overlapping non-directed BB + double nonoverlappingBB_1[2*dim] = + { + 5,6, -5,2 + }; + CPPUNIT_ASSERT( bb.isDisjointWith( nonoverlappingBB_1 )); + double nonoverlappingBB_2[2*dim] = + { + 5,6, 7,20 + }; + CPPUNIT_ASSERT( bb.isDisjointWith( nonoverlappingBB_2 )); + } + + void BBTreeTest::test_DirectedBB_1D() + { + const int nbP = 2, dim = 1; + double coords[nbP*dim] = + { + 0, 10 + }; + INTERP_KERNEL::DirectedBoundingBox bb( coords, nbP, dim); + bb.enlarge( 1e-12 ); + + // coords are IN + for ( int i = 0; i < nbP*dim; i+=dim ) + CPPUNIT_ASSERT( !bb.isOut( coords + i )); + + // points near ends are OUT + double p[nbP*dim] = + { + -0.0001, 10.1 + }; + for ( int i = 0; i < nbP*dim; i+=dim ) + CPPUNIT_ASSERT( bb.isOut( p + i )); + + // shifted boxes are OUT + double shifted_X[nbP*dim] = + { + 10.1, 11 + }; + double shifted_x[nbP*dim] = + { + -3.0, -0.001 + }; + INTERP_KERNEL::DirectedBoundingBox shiftedBB_x( shifted_x, nbP, dim); + INTERP_KERNEL::DirectedBoundingBox shiftedBB_X( shifted_X, nbP, dim); + + CPPUNIT_ASSERT( bb.isDisjointWith( shiftedBB_x )); + CPPUNIT_ASSERT( bb.isDisjointWith( shiftedBB_X )); + + // intersecting box is IN + double inters_coords[nbP*dim] = + { + -2,2 + }; + INTERP_KERNEL::DirectedBoundingBox ibb( inters_coords, nbP, dim); + CPPUNIT_ASSERT( !bb.isDisjointWith( ibb )); + + // overlapping non-directed BB + double overlappingBB[2*dim] = + { + -5,4 + }; + CPPUNIT_ASSERT( !bb.isDisjointWith( overlappingBB )); + + // non-overlapping non-directed BB + double nonoverlappingBB_1[2*dim] = + { + -5,-2 + }; + CPPUNIT_ASSERT( bb.isDisjointWith( nonoverlappingBB_1 )); + double nonoverlappingBB_2[2*dim] = + { + 11,16 + }; + CPPUNIT_ASSERT( bb.isDisjointWith( nonoverlappingBB_2 )); + } + +} diff --git a/src/medtool/src/INTERP_KERNELTest/BBTreeTest.hxx b/src/medtool/src/INTERP_KERNELTest/BBTreeTest.hxx new file mode 100644 index 000000000..89f98835e --- /dev/null +++ b/src/medtool/src/INTERP_KERNELTest/BBTreeTest.hxx @@ -0,0 +1,66 @@ +// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 +// 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 __TU_BB_TREE_HXX__ +#define __TU_BB_TREE_HXX__ + +#include <cppunit/extensions/HelperMacros.h> + +#include "InterpKernelTestExport.hxx" +#include "BBTree.txx" + +namespace INTERP_TEST +{ + + /** + * \brief Test suite testing some of the low level methods of TransformedTriangle. + * + */ + class INTERPKERNELTEST_EXPORT BBTreeTest : public CppUnit::TestFixture + { + + CPPUNIT_TEST_SUITE( BBTreeTest ); + CPPUNIT_TEST( test_BBTree ); + CPPUNIT_TEST( test_DirectedBB_1D ); + CPPUNIT_TEST( test_DirectedBB_2D ); + CPPUNIT_TEST( test_DirectedBB_3D ); + CPPUNIT_TEST_SUITE_END(); + + + public: + void setUp(); + + void tearDown(); + + // tests + void test_BBTree(); + void test_DirectedBB_1D(); + void test_DirectedBB_2D(); + void test_DirectedBB_3D(); + + }; + + + + +} + + + +#endif diff --git a/src/medtool/src/INTERP_KERNELTest/BasicMainTest.hxx b/src/medtool/src/INTERP_KERNELTest/BasicMainTest.hxx new file mode 100644 index 000000000..e1a78e6c9 --- /dev/null +++ b/src/medtool/src/INTERP_KERNELTest/BasicMainTest.hxx @@ -0,0 +1,96 @@ +// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 +// 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 _BASICMAINTEST_HXX_ +#define _BASICMAINTEST_HXX_ + +#include <cppunit/CompilerOutputter.h> +#include <cppunit/TestResult.h> +#include <cppunit/TestResultCollector.h> +#include <cppunit/TextTestProgressListener.h> +#include <cppunit/BriefTestProgressListener.h> +#include <cppunit/extensions/TestFactoryRegistry.h> +#include <cppunit/TestRunner.h> +#include <stdexcept> + +#include <iostream> +#include <fstream> + +#ifndef WIN32 +#include <fpu_control.h> +#endif + +// ============================================================================ +/*! + * Main program source for Unit Tests with cppunit package does not depend + * on actual tests, so we use the same for all partial unit tests. + */ +// ============================================================================ + +int main(int argc, char* argv[]) +{ +#ifndef WIN32 + fpu_control_t cw = _FPU_DEFAULT & ~(_FPU_MASK_IM | _FPU_MASK_ZM | _FPU_MASK_OM); + _FPU_SETCW(cw); +#endif + // --- Create the event manager and test controller + CPPUNIT_NS::TestResult controller; + + // --- Add a listener that colllects test result + CPPUNIT_NS::TestResultCollector result; + controller.addListener( &result ); + + // --- Add a listener that print dots as test run. +#ifdef WIN32 + CPPUNIT_NS::TextTestProgressListener progress; +#else + CPPUNIT_NS::BriefTestProgressListener progress; +#endif + controller.addListener( &progress ); + + // --- Get the top level suite from the registry + + CPPUNIT_NS::Test *suite = + CPPUNIT_NS::TestFactoryRegistry::getRegistry().makeTest(); + + // --- Adds the test to the list of test to run + + CPPUNIT_NS::TestRunner runner; + runner.addTest( suite ); + runner.run( controller); + + // --- Print test in a compiler compatible format. + + std::ofstream testFile; + testFile.open("UnitTestsResult", std::ios::out | std::ios::trunc); + //CPPUNIT_NS::CompilerOutputter outputter( &result, std::cerr ); + CPPUNIT_NS::CompilerOutputter outputter( &result, testFile ); + outputter.write(); + + // --- Run the tests. + + bool wasSucessful = result.wasSuccessful(); + testFile.close(); + + // --- Return error code 1 if the one of test failed. + + return wasSucessful ? 0 : 1; +} + +#endif diff --git a/src/medtool/src/INTERP_KERNELTest/CMakeLists.txt b/src/medtool/src/INTERP_KERNELTest/CMakeLists.txt new file mode 100644 index 000000000..af3ddab5f --- /dev/null +++ b/src/medtool/src/INTERP_KERNELTest/CMakeLists.txt @@ -0,0 +1,102 @@ +# Copyright (C) 2012-2015 CEA/DEN, EDF 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, 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 +# 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) + +ADD_DEFINITIONS(${HDF5_DEFINITIONS} ${MEDFILE_DEFINITIONS} ${XDR_DEFINITIONS} ${CPPUNIT_DEFINITIONS}) + +INCLUDE_DIRECTORIES( + ${CPPUNIT_INCLUDE_DIRS} + ${HDF5_INCLUDE_DIRS} + ${MEDFILE_INCLUDE_DIRS} + ${XDR_INCLUDE_DIRS} + ${CMAKE_CURRENT_SOURCE_DIR}/../MEDLoader + ${CMAKE_CURRENT_SOURCE_DIR}/../MEDCoupling + ${CMAKE_CURRENT_SOURCE_DIR}/../INTERP_KERNEL + ${CMAKE_CURRENT_SOURCE_DIR}/../INTERP_KERNEL/Bases + ${CMAKE_CURRENT_SOURCE_DIR}/../INTERP_KERNEL/ExprEval + ${CMAKE_CURRENT_SOURCE_DIR}/../INTERP_KERNEL/GaussPoints + ${CMAKE_CURRENT_SOURCE_DIR}/../INTERP_KERNEL/Geometric2D + ) + +SET(InterpKernelTest_SOURCES + BBTreeTest.cxx + CppUnitTest.cxx + ExprEvalInterpTest.cxx + QuadraticPlanarInterpTest.cxx + QuadraticPlanarInterpTest2.cxx + QuadraticPlanarInterpTest3.cxx + QuadraticPlanarInterpTest4.cxx + QuadraticPlanarInterpTest5.cxx + SingleElementPlanarTests.cxx + TransformedTriangleIntersectTest.cxx + TransformedTriangleTest.cxx + UnitTetra3D2DIntersectionTest.cxx + UnitTetraIntersectionBaryTest.cxx + TestInterpKernelUtils.cxx + ThreeDSurfProjectionTest.cxx +) + +SET(TestINTERP_KERNEL_SOURCES + TestInterpKernel.cxx + ) + +SET(PerfTest_SOURCES + PerfTest.cxx + ) + +IF(NOT MED_ENABLE_MICROMED) + SET(InterpKernelTest_SOURCES + ${InterpKernelTest_SOURCES} + InterpolationOptionsTest.cxx + MEDMeshMaker.cxx + ) + + SET(PerfTest_SOURCES + PerfTest.cxx + ) + ADD_EXECUTABLE(PerfTest ${PerfTest_SOURCES}) + TARGET_LINK_LIBRARIES(PerfTest InterpKernelTest ${CPPUNIT_LIBRARIES} ${PLATFORM_LIBS}) + INSTALL(TARGETS PerfTest DESTINATION ${MEDTOOL_INSTALL_BINS}) +ENDIF(NOT MED_ENABLE_MICROMED) + +ADD_LIBRARY(InterpKernelTest SHARED ${InterpKernelTest_SOURCES}) + +SET(InterpKernelTest_LIBS medcoupling interpkernel ${CPPUNIT_LIBRARIES}) +IF(NOT MED_ENABLE_MICROMED) + SET(InterpKernelTest_LIBS medloader ${InterpKernelTest_LIBS}) +ENDIF(NOT MED_ENABLE_MICROMED) +TARGET_LINK_LIBRARIES(InterpKernelTest ${InterpKernelTest_LIBS}) + +ADD_EXECUTABLE(TestINTERP_KERNEL ${TestINTERP_KERNEL_SOURCES}) +TARGET_LINK_LIBRARIES(TestINTERP_KERNEL InterpKernelTest ${CPPUNIT_LIBRARIES} ${PLATFORM_LIBS}) +ADD_TEST(TestINTERP_KERNEL TestINTERP_KERNEL) +#SALOME_GENERATE_TESTS_ENVIRONMENT(tests_env) +SET_TESTS_PROPERTIES(TestINTERP_KERNEL PROPERTIES ENVIRONMENT "${tests_env}") + +INSTALL(TARGETS TestINTERP_KERNEL DESTINATION ${MEDTOOL_INSTALL_BINS}) +INSTALL(TARGETS InterpKernelTest DESTINATION ${MEDTOOL_INSTALL_LIBS}) + +# Application tests + +SET(TEST_INSTALL_DIRECTORY ${MEDTOOL_INSTALL_TESTS}/MEDCoupling/INTERP_KERNELTest) +INSTALL(TARGETS TestINTERP_KERNEL InterpKernelTest DESTINATION ${TEST_INSTALL_DIRECTORY}) + +INSTALL(FILES CTestTestfileInstall.cmake + DESTINATION ${TEST_INSTALL_DIRECTORY} + RENAME CTestTestfile.cmake) diff --git a/src/medtool/src/INTERP_KERNELTest/CTestTestfileInstall.cmake b/src/medtool/src/INTERP_KERNELTest/CTestTestfileInstall.cmake new file mode 100644 index 000000000..1152205af --- /dev/null +++ b/src/medtool/src/INTERP_KERNELTest/CTestTestfileInstall.cmake @@ -0,0 +1,21 @@ +# Copyright (C) 2015 CEA/DEN, EDF 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, 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 +# 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_TEST(TestINTERP_KERNEL TestINTERP_KERNEL) +SET_TESTS_PROPERTIES(TestINTERP_KERNEL PROPERTIES LABELS "${COMPONENT_NAME}") diff --git a/src/medtool/src/INTERP_KERNELTest/CppUnitTest.cxx b/src/medtool/src/INTERP_KERNELTest/CppUnitTest.cxx new file mode 100644 index 000000000..18cbc1531 --- /dev/null +++ b/src/medtool/src/INTERP_KERNELTest/CppUnitTest.cxx @@ -0,0 +1,20 @@ +// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// + +#include "CppUnitTest.hxx" diff --git a/src/medtool/src/INTERP_KERNELTest/CppUnitTest.hxx b/src/medtool/src/INTERP_KERNELTest/CppUnitTest.hxx new file mode 100644 index 000000000..14f16c78d --- /dev/null +++ b/src/medtool/src/INTERP_KERNELTest/CppUnitTest.hxx @@ -0,0 +1,87 @@ +// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 +// 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 __TU_TEST_CPPUNIT_HXX__ +#define __TU_TEST_CPPUNIT_HXX__ + +#include <cppunit/extensions/HelperMacros.h> + +#include "InterpKernelTestExport.hxx" + +/** + * \brief Class tested by TestBogusClass : not very useful + */ +class INTERPKERNELTEST_EXPORT BogusClass { + friend class TestBogusClass; + +public: + BogusClass(double _x) : x(_x) {;} + + double getX() { return x; } + +private: + double x; +}; + +/** + * \brief Class used to figure out CppUnit : not very useful + * + */ +class INTERPKERNELTEST_EXPORT TestBogusClass : public CppUnit::TestFixture +{ + + CPPUNIT_TEST_SUITE( TestBogusClass ); + CPPUNIT_TEST( test1 ); + CPPUNIT_TEST( test2 ); + CPPUNIT_TEST_SUITE_END(); + +public: + void setUp() { + obj = new BogusClass(3.14); + } + + void tearDown() { + delete obj; + } + + void test1() { + // test something + CPPUNIT_ASSERT(obj->x == 3.14); + CPPUNIT_ASSERT(obj->getX() == obj->x); + } + + void test2() { + // test something else + obj->x += 2.6; + CPPUNIT_ASSERT(obj->getX() > 3.14); + } + +private: + BogusClass* obj; + +}; + + + + + + + + +#endif diff --git a/src/medtool/src/INTERP_KERNELTest/ExprEvalInterpTest.cxx b/src/medtool/src/INTERP_KERNELTest/ExprEvalInterpTest.cxx new file mode 100644 index 000000000..c5753d73e --- /dev/null +++ b/src/medtool/src/INTERP_KERNELTest/ExprEvalInterpTest.cxx @@ -0,0 +1,696 @@ +// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 +// 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 "ExprEvalInterpTest.hxx" +#include "InterpKernelExprParser.hxx" + +#include <limits> +#include <iterator> + +using namespace INTERP_TEST; + +void ExprEvalInterpTest::testBuildStringFromFortran() +{ + char toto1[]="123456 "; + char result[]="123456"; + std::string titi; + titi=INTERP_KERNEL::ExprParser::buildStringFromFortran(toto1,8); + CPPUNIT_ASSERT_EQUAL(6,(int)titi.length()); + CPPUNIT_ASSERT(titi==result); + // + char toto2[]=" 23456 "; + char result2[]=" 23456"; + titi=INTERP_KERNEL::ExprParser::buildStringFromFortran(toto2,8); + CPPUNIT_ASSERT(titi==result2); + CPPUNIT_ASSERT_EQUAL(6,(int)titi.length()); + // + char toto3[]=" 3456 "; + char result3[]=" 3456"; + titi=INTERP_KERNEL::ExprParser::buildStringFromFortran(toto3,8); + CPPUNIT_ASSERT(titi==result3); + CPPUNIT_ASSERT_EQUAL(6,(int)titi.length()); + // + char toto4[]=" "; + titi=INTERP_KERNEL::ExprParser::buildStringFromFortran(toto4,8); + CPPUNIT_ASSERT_EQUAL(0,(int)titi.length()); + // + char toto5[]=" 345677"; + titi=INTERP_KERNEL::ExprParser::buildStringFromFortran(toto5,8); + CPPUNIT_ASSERT(titi==toto5); + CPPUNIT_ASSERT_EQUAL(8,(int)titi.length()); +} + +void ExprEvalInterpTest::testDeleteWhiteSpaces() +{ + char toto[]=" jkhjkh ooooppp l "; + char result[]="jkhjkhoooopppl"; + std::string totoS(toto); + std::string totoR=INTERP_KERNEL::ExprParser::deleteWhiteSpaces(totoS); + CPPUNIT_ASSERT(totoR==result); + CPPUNIT_ASSERT_EQUAL(14,(int)totoR.length()); + // + char toto2[]=" jkhjkh ooooppp l "; + totoS=toto2; + totoR=INTERP_KERNEL::ExprParser::deleteWhiteSpaces(totoS); + CPPUNIT_ASSERT(totoR==result); + CPPUNIT_ASSERT_EQUAL(14,(int)totoR.length()); + // + char toto3[]=" jkhjkh oooo pppl "; + totoS=toto3; + totoR=INTERP_KERNEL::ExprParser::deleteWhiteSpaces(totoS); + CPPUNIT_ASSERT(totoR==result); + CPPUNIT_ASSERT_EQUAL(14,(int)totoR.length()); + // + char toto4[]=" jkhjkh oooo pppl"; + totoS=toto4; + totoR=INTERP_KERNEL::ExprParser::deleteWhiteSpaces(totoS); + CPPUNIT_ASSERT(totoR==result); + CPPUNIT_ASSERT_EQUAL(14,(int)totoR.length()); + // + char toto5[]="jkhjkh oooo pppl"; + totoS=toto5; + totoR=INTERP_KERNEL::ExprParser::deleteWhiteSpaces(totoS); + CPPUNIT_ASSERT(totoR==result); + CPPUNIT_ASSERT_EQUAL(14,(int)totoR.length()); + // + totoS=result; + totoR=INTERP_KERNEL::ExprParser::deleteWhiteSpaces(totoS); + CPPUNIT_ASSERT(totoR==result); + CPPUNIT_ASSERT_EQUAL(14,(int)totoR.length()); + // + char toto6[]="j k h j k h o o o o p p p l"; + totoS=toto6; + totoR=INTERP_KERNEL::ExprParser::deleteWhiteSpaces(totoS); + CPPUNIT_ASSERT(totoR==result); + CPPUNIT_ASSERT_EQUAL(14,(int)totoR.length()); + // + char toto7[]="j k h j k h o o o o p pp l"; + totoS=toto7; + totoR=INTERP_KERNEL::ExprParser::deleteWhiteSpaces(totoS); + CPPUNIT_ASSERT(totoR==result); + CPPUNIT_ASSERT_EQUAL(14,(int)totoR.length()); + // + char toto8[]=" "; + totoS=toto8; + totoR=INTERP_KERNEL::ExprParser::deleteWhiteSpaces(totoS); + CPPUNIT_ASSERT(totoR.empty()); + // + char toto9[]=""; + totoS=toto9; + totoR=INTERP_KERNEL::ExprParser::deleteWhiteSpaces(totoS); + CPPUNIT_ASSERT(totoR.empty()); + // + char toto10[]="j\n k \nh\nj \n\n k\nh \n o \no\n o\n o \np\n\npp \n\n l"; + totoS=toto10; + totoR=INTERP_KERNEL::ExprParser::deleteWhiteSpaces(totoS); + CPPUNIT_ASSERT(totoR==result); + CPPUNIT_ASSERT_EQUAL(14,(int)totoR.length()); +} + +void ExprEvalInterpTest::testInterpreter0() +{ + INTERP_KERNEL::ExprParser expr1("3*-2"); + expr1.parse(); + CPPUNIT_ASSERT_DOUBLES_EQUAL(-6.,expr1.evaluate(),1e-15); + INTERP_KERNEL::ExprParser expr2("-2.3"); + expr2.parse(); + CPPUNIT_ASSERT_DOUBLES_EQUAL(-2.3,expr2.evaluate(),1e-15); + INTERP_KERNEL::ExprParser expr3("--2.3"); + expr3.parse(); + CPPUNIT_ASSERT_DOUBLES_EQUAL(2.3,expr3.evaluate(),1e-15); + INTERP_KERNEL::ExprParser expr4("-++2.3"); + expr4.parse(); + CPPUNIT_ASSERT_DOUBLES_EQUAL(-2.3,expr4.evaluate(),1e-15); + INTERP_KERNEL::ExprParser expr5("+2.3"); + expr5.parse(); + CPPUNIT_ASSERT_DOUBLES_EQUAL(2.3,expr5.evaluate(),1e-15); + INTERP_KERNEL::ExprParser expr6("3^-1"); + expr6.parse(); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.33333333333333333,expr6.evaluate(),1e-15); +} + +void ExprEvalInterpTest::testInterpreter1() +{ + INTERP_KERNEL::ExprParser expr1("3+2*5"); + expr1.parse(); + CPPUNIT_ASSERT_DOUBLES_EQUAL(13.,expr1.evaluate(),1e-14); + INTERP_KERNEL::ExprParser expr2("3+2^3*5"); + expr2.parse(); + CPPUNIT_ASSERT_DOUBLES_EQUAL(43.,expr2.evaluate(),1e-14); + INTERP_KERNEL::ExprParser expr3("3+2^(2*5)"); + expr3.parse(); + CPPUNIT_ASSERT_DOUBLES_EQUAL(1027.,expr3.evaluate(),1e-14); + INTERP_KERNEL::ExprParser expr4("(3.2+4.3)*(1.3+2.3*7.8)"); + expr4.parse(); + CPPUNIT_ASSERT_DOUBLES_EQUAL(144.3,expr4.evaluate(),1e-10); + INTERP_KERNEL::ExprParser expr5("(3.2+4.3)*cos(1.3+2.3*7.8)"); + expr5.parse(); + CPPUNIT_ASSERT_DOUBLES_EQUAL(6.9355510138337619,expr5.evaluate(),1e-14); + INTERP_KERNEL::ExprParser expr6("3+2-4-7+4.3"); + expr6.parse(); + CPPUNIT_ASSERT_DOUBLES_EQUAL(-1.7,expr6.evaluate(),1e-14); + INTERP_KERNEL::ExprParser expr7("3.2*4.5/3.3/2.2"); + expr7.parse(); + CPPUNIT_ASSERT_DOUBLES_EQUAL(1.9834710743801653,expr7.evaluate(),1e-14); + INTERP_KERNEL::ExprParser expr8("3.2*4.5/3.3/2.2"); + expr8.parse(); + CPPUNIT_ASSERT_DOUBLES_EQUAL(1.9834710743801653,expr8.evaluate(),1e-14); + INTERP_KERNEL::ExprParser expr9("(((1.23456789)))"); + expr9.parse(); + CPPUNIT_ASSERT_DOUBLES_EQUAL(1.23456789,expr9.evaluate(),1e-14); + INTERP_KERNEL::ExprParser expr10("3.2*((2*5.2+6.)+(1.2*1.2+3.))"); + expr10.parse(); + CPPUNIT_ASSERT_DOUBLES_EQUAL(66.688,expr10.evaluate(),1e-13); + INTERP_KERNEL::ExprParser expr11("((3.2*(((2*5.2+6.)+(1.2*1.2+3.)))))"); + expr11.parse(); + CPPUNIT_ASSERT_DOUBLES_EQUAL(66.688,expr11.evaluate(),1e-13); + INTERP_KERNEL::ExprParser expr12("((3.2*(cos((2*5.2+6.)+(1.2*1.2+3.)))))"); + expr12.parse(); + CPPUNIT_ASSERT_DOUBLES_EQUAL(-1.3038041398761016,expr12.evaluate(),1e-14); + INTERP_KERNEL::ExprParser expr13("((3.2*(sin((2*5.2+6.)+(1.2*1.2+3.)))))"); + expr13.parse(); + CPPUNIT_ASSERT_DOUBLES_EQUAL(2.9223440531261784,expr13.evaluate(),1e-14); + INTERP_KERNEL::ExprParser expr14("((3.2*(tan((2*5.2+6.)+(1.2*1.2+3.)))))"); + expr14.parse(); + CPPUNIT_ASSERT_DOUBLES_EQUAL(-7.1724737512280257,expr14.evaluate(),1e-14); + INTERP_KERNEL::ExprParser expr15("((3.2*(sqrt((2*5.2+6.)+(1.2*1.2+3.)))))"); + expr15.parse(); + CPPUNIT_ASSERT_DOUBLES_EQUAL(14.608271629457059,expr15.evaluate(),1e-13); + INTERP_KERNEL::ExprParser expr16("-((3.2*(sqrt((2*5.2+6.)+(1.2*1.2+3.)))))"); + expr16.parse(); + CPPUNIT_ASSERT_DOUBLES_EQUAL(-14.608271629457059,expr16.evaluate(),1e-13); + INTERP_KERNEL::ExprParser expr17("(-(3.2*(sqrt((2*5.2+6.)+(1.2*1.2+3.)))))"); + expr17.parse(); + CPPUNIT_ASSERT_DOUBLES_EQUAL(-14.608271629457059,expr17.evaluate(),1e-13); + INTERP_KERNEL::ExprParser expr18("((-3.2*(sqrt((2*5.2+6.)+(1.2*1.2+3.)))))"); + expr18.parse(); + CPPUNIT_ASSERT_DOUBLES_EQUAL(-14.608271629457059,expr18.evaluate(),1e-13); + INTERP_KERNEL::ExprParser expr19("((3.2*(exp((6.+2*5.2)+(1.2*1.2+3.)))))"); + expr19.parse(); + CPPUNIT_ASSERT_DOUBLES_EQUAL(3596226038.1784945,expr19.evaluate(),1e-6); + INTERP_KERNEL::ExprParser expr20("((3.2*(ln((2*5.2+6.)+(1.2*1.2+3.)))))"); + expr20.parse(); + CPPUNIT_ASSERT_DOUBLES_EQUAL(9.7179974940325309,expr20.evaluate(),1e-14); + INTERP_KERNEL::ExprParser expr21("max(3.2,4.5)"); + expr21.parse(); + CPPUNIT_ASSERT_DOUBLES_EQUAL(4.5,expr21.evaluate(),1e-14); + INTERP_KERNEL::ExprParser expr22("3.*max(((3.2*(ln((2*5.2+6.)+(1.2*1.2+3.))))),((3.2*(exp((6.+2*5.2)+(1.2*1.2+3.))))))"); + expr22.parse(); + CPPUNIT_ASSERT_DOUBLES_EQUAL(10788678114.535484,expr22.evaluate(),1e-5); + INTERP_KERNEL::ExprParser expr23("min(3.2,4.5)"); + expr23.parse(); + CPPUNIT_ASSERT_DOUBLES_EQUAL(3.2,expr23.evaluate(),1e-14); +} + +void ExprEvalInterpTest::testInterpreter2() +{ + INTERP_KERNEL::ExprParser expr1("3.5*x+x*x*x/(2+x)+2*5*y"); + expr1.parse(); + std::set<std::string> res,expected; + expr1.getSetOfVars(res); + CPPUNIT_ASSERT_EQUAL(2,(int)res.size()); + expected.insert("x"); expected.insert("y"); + CPPUNIT_ASSERT(std::equal(res.begin(),res.end(),expected.begin())); + double xyValue[2]={1.,3.}; + double res1; + std::vector<std::string> vars; vars.push_back("x"); vars.push_back("y"); + expr1.prepareExprEvaluation(vars,2,1); + expr1.evaluateExpr(1,xyValue,&res1); + CPPUNIT_ASSERT_DOUBLES_EQUAL(33.833333333333336,res1,1e-13); + xyValue[0]=-2.; + CPPUNIT_ASSERT_THROW(expr1.evaluateExpr(1,xyValue,&res1),INTERP_KERNEL::Exception); + double res2[2]; + xyValue[0]=1.; + expr1.evaluateExpr(2,xyValue,res2); + CPPUNIT_ASSERT_DOUBLES_EQUAL(33.833333333333336,res2[0],1e-13); + CPPUNIT_ASSERT_DOUBLES_EQUAL(33.833333333333336,res2[1],1e-13); + INTERP_KERNEL::ExprParser expr2("3.5*tan(2.3*x)*IVec+(cos(1.2+y/x)*JVec)"); + expr2.parse(); + res.clear(); expected.clear(); + expr2.getSetOfVars(res); + CPPUNIT_ASSERT_EQUAL(4,(int)res.size()); + expected.insert("x"); expected.insert("y"); expected.insert("IVec"); expected.insert("JVec"); + CPPUNIT_ASSERT(std::equal(res.begin(),res.end(),expected.begin())); + expr2.prepareExprEvaluation(vars,2,2); + expr2.evaluateExpr(2,xyValue,res2); + CPPUNIT_ASSERT_DOUBLES_EQUAL(-3.9172477460694637,res2[0],1e-14); + CPPUNIT_ASSERT_DOUBLES_EQUAL(-0.49026082134069943,res2[1],1e-14); + INTERP_KERNEL::ExprParser expr3("3.5*u+u^2.4+2."); + expr3.parse(); + expr3.prepareExprEvaluationVec(); + expr3.evaluateExpr(2,xyValue,res2); + CPPUNIT_ASSERT_DOUBLES_EQUAL(6.5,res2[0],1e-14); + CPPUNIT_ASSERT_DOUBLES_EQUAL(26.466610165238237,res2[1],1e-14); + INTERP_KERNEL::ExprParser expr4("3.5*v+u^2.4+2."); + expr4.parse(); + CPPUNIT_ASSERT_THROW(expr4.prepareExprEvaluationVec(),INTERP_KERNEL::Exception); +} + +void ExprEvalInterpTest::testInterpreterUnit0() +{ + INTERP_KERNEL::ExprParser expr1("kg"); + expr1.parse(); + INTERP_KERNEL::DecompositionInUnitBase unit=expr1.evaluateUnit(); + CPPUNIT_ASSERT(unit.isEqual(1,0,0,0,0,0.,1000.)); + INTERP_KERNEL::ExprParser expr2("kgT"); + expr2.parse(); + CPPUNIT_ASSERT_THROW(expr2.evaluateUnit(),INTERP_KERNEL::Exception); + INTERP_KERNEL::ExprParser expr3("g"); + expr3.parse(); + unit=expr3.evaluateUnit(); + CPPUNIT_ASSERT(unit.isEqual(1,0,0,0,0,0.,1.)); + INTERP_KERNEL::ExprParser expr4("g*m"); + expr4.parse(); + unit=expr4.evaluateUnit(); + CPPUNIT_ASSERT(unit.isEqual(1,1,0,0,0,0.,1.)); + INTERP_KERNEL::ExprParser expr5("g*m/K"); + expr5.parse(); + unit=expr5.evaluateUnit(); + CPPUNIT_ASSERT(unit.isEqual(1,1,0,0,-1,0.,1.)); + INTERP_KERNEL::ExprParser expr6("g*m/K^2"); + expr6.parse(); + unit=expr6.evaluateUnit(); + CPPUNIT_ASSERT(unit.isEqual(1,1,0,0,-2,0.,1.)); + INTERP_KERNEL::ExprParser expr7("g/K^2*m"); + expr7.parse(); + unit=expr7.evaluateUnit(); + CPPUNIT_ASSERT(unit.isEqual(1,1,0,0,-2,0.,1.)); + INTERP_KERNEL::ExprParser expr8("g/(K^2*m)"); + expr8.parse(); + unit=expr8.evaluateUnit(); + CPPUNIT_ASSERT(unit.isEqual(1,-1,0,0,-2,0.,1.)); + INTERP_KERNEL::ExprParser expr9("km/h"); + expr9.parse(); + unit=expr9.evaluateUnit(); + CPPUNIT_ASSERT(unit.isEqual(0,1,-1,0,0,0.,0.27777777777777779)); + INTERP_KERNEL::ExprParser expr10("m/s"); + expr10.parse(); + unit=expr10.evaluateUnit(); + CPPUNIT_ASSERT(unit.isEqual(0,1,-1,0,0,0.,1.)); + INTERP_KERNEL::ExprParser expr11("m+s"); + expr11.parse(); + CPPUNIT_ASSERT_THROW(expr11.evaluateUnit(),INTERP_KERNEL::Exception); + INTERP_KERNEL::ExprParser expr12("m-m"); + expr12.parse(); + CPPUNIT_ASSERT_THROW(expr12.evaluateUnit(),INTERP_KERNEL::Exception); + const char expr13C[3]={-0x50,0x43,0x0}; + INTERP_KERNEL::ExprParser expr13(expr13C); + expr13.parse(); + unit=expr13.evaluateUnit(); + CPPUNIT_ASSERT(unit.isEqual(0,0,0,0,1,273.15,1.)); + const char expr14C[4]={-0x3E,-0x50,0x43,0x0}; + INTERP_KERNEL::ExprParser expr14(expr14C); + expr14.parse(); + unit=expr14.evaluateUnit(); + CPPUNIT_ASSERT(unit.isEqual(0,0,0,0,1,273.15,1.)); + INTERP_KERNEL::ExprParser expr15("kN/kg"); + expr15.parse(); + unit=expr15.evaluateUnit(); + CPPUNIT_ASSERT(unit.isEqual(0,1,-2,0,0,0.,1000.)); + INTERP_KERNEL::ExprParser expr16("cm"); + expr16.parse(); + unit=expr16.evaluateUnit(); + CPPUNIT_ASSERT(unit.isEqual(0,1,0,0,0,0.,0.01)); + INTERP_KERNEL::ExprParser expr17("m"); + expr17.parse(); + unit=expr17.evaluateUnit(); + CPPUNIT_ASSERT(unit.isEqual(0,1,0,0,0,0.,1)); + const char expr18C[3]={-0x08,0x43,0x0}; + INTERP_KERNEL::ExprParser expr18(expr18C); + expr18.parse(); + unit=expr18.evaluateUnit(); + CPPUNIT_ASSERT(unit.isEqual(0,0,0,0,1,273.15,1.)); + const char expr19C[6]={-0x50,0x43,0x2F,-0x50,0x43,0x0}; + INTERP_KERNEL::ExprParser expr19(expr19C); + expr19.parse(); + unit=expr19.evaluateUnit(); + CPPUNIT_ASSERT(unit.isEqual(0,0,0,0,0,0.,1.)); + const char expr20C[9]={-0x50,0x43,0x2A,-0x50,0x43,0x2F,-0x50,0x43,0x0}; + INTERP_KERNEL::ExprParser expr20(expr20C); + expr20.parse(); + unit=expr20.evaluateUnit(); + CPPUNIT_ASSERT(unit.isEqual(0,0,0,0,1,0.,1.)); +} + +void ExprEvalInterpTest::testInterpreterUnit1() +{ + INTERP_KERNEL::Unit unit1("m/s"); + INTERP_KERNEL::Unit unit2("km/h"); + CPPUNIT_ASSERT(unit1.isCompatibleWith(unit2) && unit2.isCompatibleWith(unit1)); + CPPUNIT_ASSERT_DOUBLES_EQUAL(360,unit1.convert(unit2,100.),1e-10); + INTERP_KERNEL::Unit unit3("J/s"); + INTERP_KERNEL::Unit unit4("kW"); + CPPUNIT_ASSERT(unit3.isCompatibleWith(unit4) && unit4.isCompatibleWith(unit3)); + CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,unit3.convert(unit4,1000.),1e-10); + CPPUNIT_ASSERT(unit4.getCoarseRepr()=="kW"); + INTERP_KERNEL::Unit unit5("kpT"); + CPPUNIT_ASSERT(!unit5.isInterpretationOK()); + CPPUNIT_ASSERT(unit5.getCoarseRepr()=="kpT"); + INTERP_KERNEL::Unit unit6("m*kpT"); + CPPUNIT_ASSERT(!unit6.isInterpretationOK()); + INTERP_KERNEL::Unit unit7("m*s^-1"); + CPPUNIT_ASSERT(unit7.isCompatibleWith(unit2) && unit2.isCompatibleWith(unit7)); + CPPUNIT_ASSERT_DOUBLES_EQUAL(360,unit7.convert(unit2,100.),1e-10); + const char unit8C[3]={-0x50,0x43,0x0}; + INTERP_KERNEL::Unit unit8(unit8C); + INTERP_KERNEL::Unit unit9("K"); + CPPUNIT_ASSERT(unit9.isCompatibleWith(unit8) && unit8.isCompatibleWith(unit9)); + CPPUNIT_ASSERT_DOUBLES_EQUAL(335.15,unit8.convert(unit9,62.),1e-10); + CPPUNIT_ASSERT_DOUBLES_EQUAL(-16.37,unit9.convert(unit8,256.78),1e-10); + INTERP_KERNEL::Unit unit10("m"); + INTERP_KERNEL::Unit unit11("cm"); + CPPUNIT_ASSERT(unit10.isCompatibleWith(unit11) && unit11.isCompatibleWith(unit10)); + CPPUNIT_ASSERT_DOUBLES_EQUAL(6200.,unit10.convert(unit11,62.),1e-8); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.62,unit11.convert(unit10,62.),1e-15); + INTERP_KERNEL::Unit unit12("m-m"); + CPPUNIT_ASSERT(!unit12.isInterpretationOK()); +} + +void ExprEvalInterpTest::testInterpreter3() +{ + std::set<std::string> res; + double input[3]; + double res2[3]; + INTERP_KERNEL::ExprParser expr1("2.3+x>5."); + expr1.parse(); + expr1.getSetOfVars(res); + CPPUNIT_ASSERT_EQUAL(1,(int)res.size()); + CPPUNIT_ASSERT(*(res.begin())=="x"); + expr1.prepareExprEvaluationVec(); + input[0]=0.; + expr1.evaluateExpr(1,input,res2); + CPPUNIT_ASSERT(-std::numeric_limits<double>::max()==res2[0]); + input[0]=2.8; + expr1.evaluateExpr(1,input,res2); + CPPUNIT_ASSERT(std::numeric_limits<double>::max()==res2[0]); + input[0]=2.6; + expr1.evaluateExpr(1,input,res2); + CPPUNIT_ASSERT(-std::numeric_limits<double>::max()==res2[0]); + // + INTERP_KERNEL::ExprParser expr2("2.3+x<5."); + expr2.parse(); + res.clear(); + expr2.getSetOfVars(res); + CPPUNIT_ASSERT_EQUAL(1,(int)res.size()); + CPPUNIT_ASSERT(*(res.begin())=="x"); + expr2.prepareExprEvaluationVec(); + input[0]=0.; + expr2.evaluateExpr(1,input,res2); + CPPUNIT_ASSERT(std::numeric_limits<double>::max()==res2[0]); + input[0]=2.8; + expr2.evaluateExpr(1,input,res2); + CPPUNIT_ASSERT(-std::numeric_limits<double>::max()==res2[0]); + input[0]=2.6; + expr2.evaluateExpr(1,input,res2); + CPPUNIT_ASSERT(std::numeric_limits<double>::max()==res2[0]); + // + INTERP_KERNEL::ExprParser expr3("if(2.3+x<5.,2+3*x,3+x/2)"); + expr3.parse(); + res.clear(); + expr3.getSetOfVars(res); + CPPUNIT_ASSERT_EQUAL(1,(int)res.size()); + CPPUNIT_ASSERT(*(res.begin())=="x"); + expr3.prepareExprEvaluationVec(); + input[0]=0.; + expr3.evaluateExpr(1,input,res2); + CPPUNIT_ASSERT_DOUBLES_EQUAL(2.,res2[0],1e-12); + input[0]=2.8; + expr3.evaluateExpr(1,input,res2); + CPPUNIT_ASSERT_DOUBLES_EQUAL(4.4,res2[0],1e-12); + input[0]=2.6; + expr3.evaluateExpr(1,input,res2); + CPPUNIT_ASSERT_DOUBLES_EQUAL(9.8,res2[0],1e-12); + // + INTERP_KERNEL::ExprParser expr4("if(x>1000,2*x,x/3)"); + expr4.parse(); + res.clear(); + expr4.getSetOfVars(res); + CPPUNIT_ASSERT_EQUAL(1,(int)res.size()); + CPPUNIT_ASSERT(*(res.begin())=="x"); + expr4.prepareExprEvaluationVec(); + input[0]=2.7; + expr4.evaluateExpr(1,input,res2); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.9,res2[0],1e-12); + input[0]=999.; + expr4.evaluateExpr(1,input,res2); + CPPUNIT_ASSERT_DOUBLES_EQUAL(333.,res2[0],1e-12); + input[0]=1002.; + expr4.evaluateExpr(1,input,res2); + CPPUNIT_ASSERT_DOUBLES_EQUAL(2004.,res2[0],1e-12); + // + INTERP_KERNEL::ExprParser expr5("4.4*x*log10(x)*10"); + expr5.parse(); + res.clear(); + expr5.getSetOfVars(res); + CPPUNIT_ASSERT_EQUAL(1,(int)res.size()); + CPPUNIT_ASSERT(*(res.begin())=="x"); + expr5.prepareExprEvaluationVec(); + input[0]=273.15; + expr5.evaluateExpr(1,input,res2); + CPPUNIT_ASSERT_DOUBLES_EQUAL(29282.131520617437,res2[0],1e-9); + input[0]=0.; + CPPUNIT_ASSERT_THROW(expr5.evaluateExpr(1,input,res2),INTERP_KERNEL::Exception); +} + +/*! + * Bug detected by Marc concerning expressions with blanks. + */ +void ExprEvalInterpTest::testInterpreter4() +{ + INTERP_KERNEL::ExprParser expr("2*x + 1"); + double vals[3]={0.1,0.2,0.3}; + std::vector<std::string> varsV(3); + varsV[0] = "x"; + varsV[1] = "y"; + varsV[2] = "z"; + expr.parse(); + expr.prepareExprEvaluation(varsV,3,1); + double result; + expr.evaluateExpr(1,vals, &result); + CPPUNIT_ASSERT_DOUBLES_EQUAL(1.2,result,1e-12); +} + +/*! + * Allowing scientific format for floats. + */ +void ExprEvalInterpTest::testInterpreter5() +{ + std::set<std::string> res; + double input[3]; + double res2[3]; + INTERP_KERNEL::ExprParser expr1("1.85e-3*x"); + expr1.parse(); + expr1.getSetOfVars(res); + CPPUNIT_ASSERT_EQUAL(1,(int)res.size()); + CPPUNIT_ASSERT(*(res.begin())=="x"); + input[0]=56.7; + expr1.prepareExprEvaluationVec(); + expr1.evaluateExpr(1,input,res2); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.104895,res2[0],1e-12); + input[0]=-65.7; + expr1.evaluateExpr(1,input,res2); + CPPUNIT_ASSERT_DOUBLES_EQUAL(-0.121545,res2[0],1e-12); + // + INTERP_KERNEL::ExprParser expr2("x*1.85e-3"); + expr2.parse(); + expr2.getSetOfVars(res); + CPPUNIT_ASSERT_EQUAL(1,(int)res.size()); + CPPUNIT_ASSERT(*(res.begin())=="x"); + input[0]=56.7; + expr2.prepareExprEvaluationVec(); + expr2.evaluateExpr(1,input,res2); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.104895,res2[0],1e-12); + input[0]=-65.7; + expr2.evaluateExpr(1,input,res2); + CPPUNIT_ASSERT_DOUBLES_EQUAL(-0.121545,res2[0],1e-12); + // + INTERP_KERNEL::ExprParser expr3("2.6E+1+x*1.85e-3"); + expr3.parse(); + expr3.getSetOfVars(res); + CPPUNIT_ASSERT_EQUAL(1,(int)res.size()); + CPPUNIT_ASSERT(*(res.begin())=="x"); + input[0]=56.7; + expr3.prepareExprEvaluationVec(); + expr3.evaluateExpr(1,input,res2); + CPPUNIT_ASSERT_DOUBLES_EQUAL(26.104895,res2[0],1e-12); + input[0]=-65.7; + expr3.evaluateExpr(1,input,res2); + CPPUNIT_ASSERT_DOUBLES_EQUAL(25.878455,res2[0],1e-12); + // + INTERP_KERNEL::ExprParser expr4("3.*max(((3.2e+1*(ln((2*5.2E-02+6.)+(1.2E-001*1.2E+2+3e-4))))),((3.2E-2*(exp((6e-1+2*5.2e-2)+(1.2E001*1.2+3.))))))"); + expr4.parse(); + CPPUNIT_ASSERT_DOUBLES_EQUAL(6994207.8359543988,expr4.evaluate(),1e-5); +} + +/*! + * Test focusing on fast evaluator. + */ +void ExprEvalInterpTest::testInterpreter6() +{ + std::vector<double> stackOfVal; + // + stackOfVal.clear(); + INTERP_KERNEL::ExprParser expr1("1.-2./3."); + expr1.parse(); + expr1.prepareFastEvaluator(); + expr1.evaluateDoubleInternal(stackOfVal); + CPPUNIT_ASSERT_EQUAL(1,(int)stackOfVal.size()); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.33333333333333333,stackOfVal.back(),1e-14); + // + stackOfVal.clear(); + INTERP_KERNEL::ExprParser expr2("1.-2.^3."); + expr2.parse(); + expr2.prepareFastEvaluator(); + expr2.evaluateDoubleInternal(stackOfVal); + CPPUNIT_ASSERT_EQUAL(1,(int)stackOfVal.size()); + CPPUNIT_ASSERT_DOUBLES_EQUAL(-7.,stackOfVal.back(),1e-14); + // + stackOfVal.clear(); + INTERP_KERNEL::ExprParser expr3("(7.-2.)^3."); + expr3.parse(); + expr3.prepareFastEvaluator(); + expr3.evaluateDoubleInternal(stackOfVal); + CPPUNIT_ASSERT_EQUAL(1,(int)stackOfVal.size()); + CPPUNIT_ASSERT_DOUBLES_EQUAL(125.,stackOfVal.back(),1e-12); + // now playing with one parameter - calling several times + stackOfVal.clear(); + INTERP_KERNEL::ExprParser expr4("1.2/(7.-2.*cos(x/3))"); + expr4.parse(); + expr4.prepareFastEvaluator(); + double z; + expr4.prepareExprEvaluationDouble(std::vector<std::string>(1,"x"),1,1,0,&z,&z+1); + expr4.prepareFastEvaluator(); + z=0.77; + expr4.evaluateDoubleInternal(stackOfVal); + CPPUNIT_ASSERT_EQUAL(1,(int)stackOfVal.size()); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.23689586281558844,stackOfVal.back(),1e-12); + stackOfVal.pop_back(); + z=0.55; + expr4.evaluateDoubleInternal(stackOfVal); + CPPUNIT_ASSERT_EQUAL(1,(int)stackOfVal.size()); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.2384018932069258,stackOfVal.back(),1e-12); + // + stackOfVal.clear(); + INTERP_KERNEL::ExprParser expr5("x-2*cos(y/3.)"); + expr5.parse(); + expr5.prepareFastEvaluator(); + double *aa(new double[2]); + std::vector<std::string> vv(2); vv[0]="x"; vv[1]="y"; + expr5.prepareExprEvaluationDouble(vv,2,1,0,aa,aa+2); + expr5.prepareFastEvaluator(); + aa[0]=0.3; aa[1]=0.5; + expr5.evaluateDoubleInternal(stackOfVal); + CPPUNIT_ASSERT_EQUAL(1,(int)stackOfVal.size()); + CPPUNIT_ASSERT_DOUBLES_EQUAL(-1.67228646312585,stackOfVal.back(),1e-14); + stackOfVal.pop_back(); + aa[0]=0.5; aa[1]=0.3; + expr5.evaluateDoubleInternal(stackOfVal); + CPPUNIT_ASSERT_EQUAL(1,(int)stackOfVal.size()); + CPPUNIT_ASSERT_DOUBLES_EQUAL(-1.4900083305560516,stackOfVal.back(),1e-14); + stackOfVal.pop_back(); + delete [] aa; + // + stackOfVal.clear(); + INTERP_KERNEL::ExprParser expr6("x*IVec-2*cos(y/3.)*JVec"); + expr6.parse(); + aa=new double[2]; + vv.resize(2); vv[0]="x"; vv[1]="y"; + expr6.prepareExprEvaluationDouble(vv,2,2,0,aa,aa+2);//emulate 1st interpreter + expr6.prepareFastEvaluator(); + aa[0]=0.3; aa[1]=0.5; + expr6.evaluateDoubleInternal(stackOfVal); + CPPUNIT_ASSERT_EQUAL(1,(int)stackOfVal.size()); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.3,stackOfVal.back(),1e-14); + stackOfVal.pop_back(); + expr6.prepareExprEvaluationDouble(vv,2,2,1,aa,aa+2);//emulate 2nd interpreter + expr6.prepareFastEvaluator(); + expr6.evaluateDoubleInternal(stackOfVal); + CPPUNIT_ASSERT_EQUAL(1,(int)stackOfVal.size()); + CPPUNIT_ASSERT_DOUBLES_EQUAL(-1.97228646312585,stackOfVal.back(),1e-14); + stackOfVal.pop_back(); + delete [] aa; + // + stackOfVal.clear(); + INTERP_KERNEL::ExprParser expr7("if(x>3.,-6,7.)"); + expr7.parse(); + expr7.prepareExprEvaluationDouble(std::vector<std::string>(1,"x"),1,1,0,&z,&z+1); + expr7.prepareFastEvaluator(); + z=3.1; + expr7.evaluateDoubleInternal(stackOfVal); + CPPUNIT_ASSERT_EQUAL(1,(int)stackOfVal.size()); + CPPUNIT_ASSERT_DOUBLES_EQUAL(-6.,stackOfVal.back(),1e-14); + stackOfVal.pop_back(); + z=2.8; + expr7.evaluateDoubleInternal(stackOfVal); + CPPUNIT_ASSERT_EQUAL(1,(int)stackOfVal.size()); + CPPUNIT_ASSERT_DOUBLES_EQUAL(7.,stackOfVal.back(),1e-14); + stackOfVal.pop_back(); + // + stackOfVal.clear(); + INTERP_KERNEL::ExprParser expr8("if(x<3.,-6,7.)"); + expr8.parse(); + expr8.prepareExprEvaluationDouble(std::vector<std::string>(1,"x"),1,1,0,&z,&z+1); + expr8.prepareFastEvaluator(); + z=3.1; + expr8.evaluateDoubleInternal(stackOfVal); + CPPUNIT_ASSERT_EQUAL(1,(int)stackOfVal.size()); + CPPUNIT_ASSERT_DOUBLES_EQUAL(7.,stackOfVal.back(),1e-14); + stackOfVal.pop_back(); + z=2.8; + expr8.evaluateDoubleInternal(stackOfVal); + CPPUNIT_ASSERT_EQUAL(1,(int)stackOfVal.size()); + CPPUNIT_ASSERT_DOUBLES_EQUAL(-6.,stackOfVal.back(),1e-14); + stackOfVal.pop_back(); + // + stackOfVal.clear(); + INTERP_KERNEL::ExprParser expr9("x*x/2");//this test is very important to test for iso priority with more than one + expr9.parse(); + expr9.prepareExprEvaluationDouble(std::vector<std::string>(1,"x"),1,1,0,&z,&z+1); + expr9.prepareFastEvaluator(); + z=3.; + expr9.evaluateDoubleInternal(stackOfVal); + CPPUNIT_ASSERT_EQUAL(1,(int)stackOfVal.size()); + CPPUNIT_ASSERT_DOUBLES_EQUAL(4.5,stackOfVal.back(),1e-14); + stackOfVal.pop_back(); + // + stackOfVal.clear(); + INTERP_KERNEL::ExprParser expr10("2./3./4./5."); + expr10.parse(); + expr10.prepareFastEvaluator(); + expr10.evaluateDoubleInternal(stackOfVal); + CPPUNIT_ASSERT_EQUAL(1,(int)stackOfVal.size()); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.03333333333333333,stackOfVal.back(),1e-13); + // + stackOfVal.clear(); + INTERP_KERNEL::ExprParser expr11("2./3./4.*5."); + expr11.parse(); + expr11.prepareFastEvaluator(); + expr11.evaluateDoubleInternal(stackOfVal); + CPPUNIT_ASSERT_EQUAL(1,(int)stackOfVal.size()); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.83333333333333333,stackOfVal.back(),1e-14); + // + stackOfVal.clear(); + INTERP_KERNEL::ExprParser expr12("2./3.*4.*5."); + expr12.parse(); + expr12.prepareFastEvaluator(); + expr12.evaluateDoubleInternal(stackOfVal); + CPPUNIT_ASSERT_EQUAL(1,(int)stackOfVal.size()); + CPPUNIT_ASSERT_DOUBLES_EQUAL(13.333333333333333,stackOfVal.back(),1e-14); +} diff --git a/src/medtool/src/INTERP_KERNELTest/ExprEvalInterpTest.hxx b/src/medtool/src/INTERP_KERNELTest/ExprEvalInterpTest.hxx new file mode 100644 index 000000000..5d5bd0ef8 --- /dev/null +++ b/src/medtool/src/INTERP_KERNELTest/ExprEvalInterpTest.hxx @@ -0,0 +1,63 @@ +// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 +// 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 _EXPREVALINTERPTEST_HXX_ +#define _EXPREVALINTERPTEST_HXX_ + +#include <cppunit/extensions/HelperMacros.h> + +#include "InterpKernelTestExport.hxx" + +namespace INTERP_TEST +{ + class INTERPKERNELTEST_EXPORT ExprEvalInterpTest : public CppUnit::TestFixture + { + CPPUNIT_TEST_SUITE( ExprEvalInterpTest ); + CPPUNIT_TEST( testBuildStringFromFortran ); + CPPUNIT_TEST( testDeleteWhiteSpaces ); + CPPUNIT_TEST( testInterpreter0 ); + CPPUNIT_TEST( testInterpreter1 ); + CPPUNIT_TEST( testInterpreter2 ); + CPPUNIT_TEST( testInterpreterUnit0 ); + CPPUNIT_TEST( testInterpreterUnit1 ); + CPPUNIT_TEST( testInterpreter3 ); + CPPUNIT_TEST( testInterpreter4 ); + CPPUNIT_TEST( testInterpreter5 ); + CPPUNIT_TEST( testInterpreter6 ); + CPPUNIT_TEST_SUITE_END(); + public: + void setUp() { } + void tearDown() { } + void cleanUp() { } + void testBuildStringFromFortran(); + void testDeleteWhiteSpaces(); + void testInterpreter0(); + void testInterpreter1(); + void testInterpreter2(); + void testInterpreter3(); + void testInterpreter4(); + void testInterpreter5(); + void testInterpreter6(); + void testInterpreterUnit0(); + void testInterpreterUnit1(); + }; +} + +#endif diff --git a/src/medtool/src/INTERP_KERNELTest/HexaTests.hxx b/src/medtool/src/INTERP_KERNELTest/HexaTests.hxx new file mode 100644 index 000000000..3edcbd326 --- /dev/null +++ b/src/medtool/src/INTERP_KERNELTest/HexaTests.hxx @@ -0,0 +1,76 @@ +// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 +// 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 __HEXA_TESTS_HXX_ +#define __HEXA_TESTS_HXX_ + +#include "InterpolationTestSuite.hxx" + +namespace INTERP_TEST +{ + /** + * \brief Class performing intersection tests on meshes with hexahedral elements. + * + */ + class HexaTests : public InterpolationTestSuite<3,3> + { + CPPUNIT_TEST_SUITE( HexaTests ); + + CPPUNIT_TEST( simpleHexaBox ); + //VB : slightly inaccurate so that it triggers a failure of the test + // should be investigated in the future + // CPPUNIT_TEST( reflexiveHexaBox ); + CPPUNIT_TEST( hexaBoxes ); + CPPUNIT_TEST( hexaBoxesMoved ); + + CPPUNIT_TEST_SUITE_END(); + + public: + + /// Intersection between two boxes, aligned with the axes.One has 60 hexahedral elements and the other has 39 tetrahedral elements + /// \brief Status : pass + void simpleHexaBox() + { + _testTools->intersectMeshes("BoxHexa1", "BoxTetra2", 65250, 1.0e-5); + } + + /// Intersection of a box with 60 hexahedral elements with itself + /// \brief Status : pass + void reflexiveHexaBox() + { + _testTools->intersectMeshes("BoxHexa1", "BoxHexa1", 204000); + } + + /// Intersection between two boxes, aligned with the axes.Both have hexahedral elements : one 36, the other 60 + /// \brief Status : pass + void hexaBoxes() + { + _testTools->intersectMeshes("BoxHexa1", "BoxHexa2", 65250); + } + + /// Intersection between two boxes in general position with hexahedral elements. One has 200 elements and the other 420. + /// \brief Status : fails - reason unknown. The matrix does not fulfil the transpose requirement : that W_AB = W_BA^T + void hexaBoxesMoved() + { + _testTools->intersectMeshes("MovedHexaBox1", "MovedHexaBox2", 65250); + } + + }; +} +#endif diff --git a/src/medtool/src/INTERP_KERNELTest/InterpKernelTestExport.hxx b/src/medtool/src/INTERP_KERNELTest/InterpKernelTestExport.hxx new file mode 100644 index 000000000..f34c58fe4 --- /dev/null +++ b/src/medtool/src/INTERP_KERNELTest/InterpKernelTestExport.hxx @@ -0,0 +1,33 @@ +// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 +// 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 _INTERPKERNELTESTEXPORT_HXX_ +#define _INTERPKERNELTESTEXPORT_HXX_ + +#ifdef WIN32 +# if defined InterpKernelTest_EXPORTS +# define INTERPKERNELTEST_EXPORT __declspec( dllexport ) +# else +# define INTERPKERNELTEST_EXPORT __declspec( dllimport ) +# endif +#else +# define INTERPKERNELTEST_EXPORT +#endif + +#endif diff --git a/src/medtool/src/INTERP_KERNELTest/Interpolation3DTest.cxx b/src/medtool/src/INTERP_KERNELTest/Interpolation3DTest.cxx new file mode 100644 index 000000000..db32ed895 --- /dev/null +++ b/src/medtool/src/INTERP_KERNELTest/Interpolation3DTest.cxx @@ -0,0 +1,344 @@ +// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// + +#include "Interpolation3DTest.hxx" + +#include "MEDFileMesh.hxx" +#include "MEDCouplingUMesh.hxx" +#include "MEDCouplingFieldDouble.hxx" + +#include <map> +#include <cmath> +#include <vector> +#include <iostream> +#include <algorithm> + +#include "VectorUtils.hxx" + +// levels : +// 1 - titles and volume results +// 2 - symmetry / diagonal results and intersection matrix output +// 3 - empty +// 4 - empty +// 5 - misc +#include "Log.hxx" + + +//#define VOL_PREC 1.0e-6 + +using namespace ParaMEDMEM; +using namespace INTERP_KERNEL; + +double Interpolation3DTest::sumRow(const IntersectionMatrix& m, int i) const +{ + double vol = 0.0; + for(IntersectionMatrix::const_iterator iter = m.begin() ; iter != m.end() ; ++iter) + { + if(iter->count(i) != 0.0) + { + std::map<int, double>::const_iterator iter2 = iter->find(i); + vol += iter2->second; + } + } + return vol; +} + +double Interpolation3DTest::sumCol(const IntersectionMatrix& m, int i) const +{ + double vol = 0.0; + const std::map<int, double>& col = m[i]; + for(std::map<int, double>::const_iterator iter = col.begin() ; iter != col.end() ; ++iter) + { + vol += std::fabs(iter->second); + } + return vol; +} + + +void Interpolation3DTest::getVolumes(ParaMEDMEM::MEDCouplingUMesh& mesh, double *tab) const +{ + MEDCouplingAutoRefCountObjectPtr<MEDCouplingFieldDouble> vol=mesh->getMeasureField(true); + std::copy(vol->getArray()->begin(),vol->getArray()->end(),tab); +} + +double Interpolation3DTest::sumVolume(const IntersectionMatrix& m) const +{ + + std::vector<double> volumes; + for(IntersectionMatrix::const_iterator iter = m.begin() ; iter != m.end() ; ++iter) + { + for(std::map<int, double>::const_iterator iter2 = iter->begin() ; iter2 != iter->end() ; ++iter2) + { + volumes.push_back(iter2->second); + // vol += std::abs(iter2->second); + } + } + + // sum in ascending order to avoid rounding errors + + sort(volumes.begin(), volumes.end()); + const double vol = accumulate(volumes.begin(), volumes.end(), 0.0); + + return vol; +} + +bool Interpolation3DTest::testVolumes(const IntersectionMatrix& m, MEDCouplingUMesh& sMesh, MEDCouplingUMesh& tMesh) const +{ + bool ok = true; + + // source elements + double* sVol = new double[sMesh.getNumberOfCells()]; + getVolumes(sMesh, sVol); + + for(int i = 0; i < sMesh.getNumberOfCells(); ++i) + { + const double sum_row = sumRow(m, i+1); + if(!epsilonEqualRelative(sum_row, sVol[i], VOL_PREC)) + { + LOG(1, "Source volume inconsistent : vol of cell " << i << " = " << sVol[i] << " but the row sum is " << sum_row ); + ok = false; + } + LOG(1, "diff = " <<sum_row - sVol[i] ); + } + + // target elements + double* tVol = new double[tMesh.getNumberOfCells()]; + getVolumes(tMesh, tVol); + for(int i = 0; i < tMesh.getNumberOfCells(); ++i) + { + const double sum_col = sumCol(m, i); + if(!epsilonEqualRelative(sum_col, tVol[i], VOL_PREC)) + { + LOG(1, "Target volume inconsistent : vol of cell " << i << " = " << tVol[i] << " but the col sum is " << sum_col); + ok = false; + } + LOG(1, "diff = " <<sum_col - tVol[i] ); + } + delete[] sVol; + delete[] tVol; + + return ok; +} + +bool Interpolation3DTest::areCompatitable(const IntersectionMatrix& m1, const IntersectionMatrix& m2) const +{ + bool compatitable = true; + int i = 0; + for(IntersectionMatrix::const_iterator iter = m1.begin() ; iter != m1.end() ; ++iter) + { + for(std::map<int, double>::const_iterator iter2 = iter->begin() ; iter2 != iter->end() ; ++iter2) + { + int j = iter2->first; + if(m2.at(j-1).count(i+1) == 0) + { + if(!epsilonEqual(iter2->second, 0.0, VOL_PREC)) + { + LOG(2, "V1( " << i << ", " << j << ") exists, but V2( " << j - 1 << ", " << i + 1 << ") " << " does not " ); + LOG(2, "(" << i << ", " << j << ") fails"); + compatitable = false; + } + } + } + ++i; + } + if(!compatitable) + { + LOG(1, "*** matrices are not compatitable"); + } + return compatitable; +} + +bool Interpolation3DTest::testSymmetric(const IntersectionMatrix& m1, const IntersectionMatrix& m2) const +{ + + int i = 0; + bool isSymmetric = true; + + LOG(1, "Checking symmetry src - target" ); + isSymmetric = isSymmetric & areCompatitable(m1, m2) ; + LOG(1, "Checking symmetry target - src" ); + isSymmetric = isSymmetric & areCompatitable(m2, m1); + + for(IntersectionMatrix::const_iterator iter = m1.begin() ; iter != m1.end() ; ++iter) + { + for(std::map<int, double>::const_iterator iter2 = iter->begin() ; iter2 != iter->end() ; ++iter2) + { + int j = iter2->first; + const double v1 = iter2->second; + //if(m2[j - 1].count(i+1) > 0) + // { + std::map<int, double> theMap = m2.at(j-1); + const double v2 = theMap[i + 1]; + if(v1 != v2) + { + LOG(2, "V1( " << i << ", " << j << ") = " << v1 << " which is different from V2( " << j - 1 << ", " << i + 1 << ") = " << v2 << " | diff = " << v1 - v2 ); + if(!epsilonEqualRelative(v1, v2, VOL_PREC)) + { + LOG(2, "(" << i << ", " << j << ") fails"); + isSymmetric = false; + } + } + } + ++i; + } + if(!isSymmetric) + { + LOG(1, "*** matrices are not symmetric"); + } + return isSymmetric; +} + +bool Interpolation3DTest::testDiagonal(const IntersectionMatrix& m) const +{ + LOG(1, "Checking if matrix is diagonal" ); + int i = 1; + bool isDiagonal = true; + for(IntersectionMatrix::const_iterator iter = m.begin() ; iter != m.end() ; ++iter) + { + for(std::map<int, double>::const_iterator iter2 = iter->begin() ; iter2 != iter->end() ; ++iter2) + { + int j = iter2->first; + const double vol = iter2->second; + if(vol != 0.0 && (i != j)) + { + LOG(2, "V( " << i - 1 << ", " << j << ") = " << vol << " which is not zero" ); + if(!epsilonEqual(vol, 0.0, VOL_PREC)) + { + LOG(2, "(" << i << ", " << j << ") fails"); + isDiagonal = false; + } + } + } + ++i; + } + if(!isDiagonal) + { + LOG(1, "*** matrix is not diagonal"); + } + return isDiagonal; +} + +void Interpolation3DTest::dumpIntersectionMatrix(const IntersectionMatrix& m) const +{ + int i = 0; + std::cout << "Intersection matrix is " << std::endl; + for(IntersectionMatrix::const_iterator iter = m.begin() ; iter != m.end() ; ++iter) + { + for(std::map<int, double>::const_iterator iter2 = iter->begin() ; iter2 != iter->end() ; ++iter2) + { + + std::cout << "V(" << i << ", " << iter2->first << ") = " << iter2->second << std::endl; + + } + ++i; + } + std::cout << "Sum of volumes = " << sumVolume(m) << std::endl; +} + +void Interpolation3DTest::setUp() +{ + interpolator = new Interpolation3D(); +} + +void Interpolation3DTest::tearDown() +{ + delete interpolator; +} + +void Interpolation3DTest::calcIntersectionMatrix(const char* mesh1path, const char* mesh1, const char* mesh2path, const char* mesh2, IntersectionMatrix& m) const +{ + const string dataBaseDir = getenv("MED_ROOT_DIR"); + const string dataDir = dataBaseDir + "/share/salome/resources/med/"; + + LOG(1, std::endl << "=== -> intersecting src = " << mesh1 << ", target = " << mesh2 ); + + LOG(5, "Loading " << mesh1 << " from " << mesh1path); + MESH sMesh(MED_DRIVER, dataDir+mesh1path, mesh1); + + LOG(5, "Loading " << mesh2 << " from " << mesh2path); + MESH tMesh(MED_DRIVER, dataDir+mesh2path, mesh2); + + m = interpolator->interpolateMeshes(sMesh, tMesh); + + // if reflexive, check volumes + if(strcmp(mesh1path,mesh2path) == 0) + { + const bool row_and_col_sums_ok = testVolumes(m, sMesh, tMesh); + CPPUNIT_ASSERT_EQUAL_MESSAGE("Row or column sums incorrect", true, row_and_col_sums_ok); + } + + LOG(1, "Intersection calculation done. " << std::endl ); + +} + +void Interpolation3DTest::intersectMeshes(const char* mesh1path, const char* mesh1, const char* mesh2path, const char* mesh2, const double correctVol, const double prec, bool doubleTest) const +{ + LOG(1, std::endl << std::endl << "=============================" ); + + using std::string; + const string path1 = string(mesh1path) + string(mesh1); + const string path2 = string(mesh2path) + string(mesh2); + + const bool isTestReflexive = (path1.compare(path2) == 0); + + IntersectionMatrix matrix1; + calcIntersectionMatrix(mesh1path, mesh1, mesh2path, mesh2, matrix1); + +#if LOG_LEVEL >= 2 + dumpIntersectionMatrix(matrix1); +#endif + + std::cout.precision(16); + + const double vol1 = sumVolume(matrix1); + + if(!doubleTest) + { + LOG(1, "vol = " << vol1 <<" correctVol = " << correctVol ); + CPPUNIT_ASSERT_DOUBLES_EQUAL(correctVol, vol1, prec * std::max(correctVol, vol1)); + + if(isTestReflexive) + { + CPPUNIT_ASSERT_EQUAL_MESSAGE("Reflexive test failed", true, testDiagonal(matrix1)); + } + } + else + { + + IntersectionMatrix matrix2; + calcIntersectionMatrix(mesh2path, mesh2, mesh1path, mesh1, matrix2); + +#if LOG_LEVEL >= 2 + dumpIntersectionMatrix(matrix2); +#endif + + const double vol2 = sumVolume(matrix2); + + LOG(1, "vol1 = " << vol1 << ", vol2 = " << vol2 << ", correctVol = " << correctVol ); + + CPPUNIT_ASSERT_DOUBLES_EQUAL(correctVol, vol1, prec * std::max(vol1, correctVol)); + CPPUNIT_ASSERT_DOUBLES_EQUAL(correctVol, vol2, prec * std::max(vol2, correctVol)); + CPPUNIT_ASSERT_DOUBLES_EQUAL(vol1, vol2, prec * std::max(vol1, vol2)); + CPPUNIT_ASSERT_EQUAL_MESSAGE("Symmetry test failed", true, testSymmetric(matrix1, matrix2)); + } + +} + + + diff --git a/src/medtool/src/INTERP_KERNELTest/Interpolation3DTest.hxx b/src/medtool/src/INTERP_KERNELTest/Interpolation3DTest.hxx new file mode 100644 index 000000000..6680f94e9 --- /dev/null +++ b/src/medtool/src/INTERP_KERNELTest/Interpolation3DTest.hxx @@ -0,0 +1,49 @@ +// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 +// 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 __TU_INTERPOLATION_3D_TEST_HXX__ +#define __TU_INTERPOLATION_3D_TEST_HXX__ + +#include <cppunit/extensions/HelperMacros.h> +#include "Interpolation3D.hxx" + +#define ERR_TOL 1.0e-8 + +/// \brief OBSOLETE - renamed Interpolation3DTestSuite +class Interpolation3DTest : public CppUnit::TestFixture +{ + +public: + void setUp() + { + _testTools = new MeshTestToolkit(); + } + + void tearDown() + { + delete _testTools; + } + +protected: + + MeshToolkit* _testTools; + +}; + +#endif diff --git a/src/medtool/src/INTERP_KERNELTest/InterpolationOptionsTest.cxx b/src/medtool/src/INTERP_KERNELTest/InterpolationOptionsTest.cxx new file mode 100644 index 000000000..9bc5c7406 --- /dev/null +++ b/src/medtool/src/INTERP_KERNELTest/InterpolationOptionsTest.cxx @@ -0,0 +1,90 @@ +// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// + +#include "MEDFileMesh.hxx" +#include "MEDCouplingFieldDouble.hxx" + +#include "InterpolationOptionsTest.hxx" +#include "MEDCouplingNormalizedUnstructuredMesh.txx" +#include "Interpolation2D.txx" +#include "TestInterpKernelUtils.hxx" + +#include <iostream> +#include <vector> + +using namespace ParaMEDMEM; + +namespace INTERP_TEST +{ + void InterpolationOptionsTest::setUp() + { + } + + + void InterpolationOptionsTest::tearDown() + { + } + + /** + * Test that creates a tree in 2D and check that + * the results are correct in three + * cases : + * a non matching search + * a standard case + * a bbox overlapping the bboxes of the tree + */ + void InterpolationOptionsTest::test_InterpolationOptions() + { + std::string sourcename=INTERP_TEST::getResourceFile("square1.med"); + MEDFileUMesh *source_mesh=MEDFileUMesh::New(sourcename.c_str(),"Mesh_2"); + + std::string targetname=INTERP_TEST::getResourceFile("square2.med"); + MEDFileUMesh *target_mesh=MEDFileUMesh::New(targetname.c_str(),"Mesh_3"); + + MEDCouplingUMesh *source_mesh_mc=source_mesh->getMeshAtLevel(0); + MEDCouplingFieldDouble *source_field=MEDCouplingFieldDouble::New(ON_CELLS); + source_field->setMesh(source_mesh_mc); source_mesh_mc->decrRef(); + DataArrayDouble *arr=DataArrayDouble::New(); arr->alloc(source_mesh_mc->getNumberOfCells(),1); + source_field->setArray(arr); arr->decrRef(); + double *value=arr->getPointer(); + for(int i=0; i<source_mesh_mc->getNumberOfCells(); i++) + value[i]=1.0; + MEDCouplingUMesh *target_mesh_mc=target_mesh->getMeshAtLevel(0); + MEDCouplingFieldDouble *target_field=MEDCouplingFieldDouble::New(ON_CELLS); + target_field->setMesh(target_mesh_mc); target_mesh_mc->decrRef(); + arr=DataArrayDouble::New(); arr->alloc(target_mesh_mc->getNumberOfCells(),1); + target_field->setArray(arr); arr->decrRef(); + double* targetvalue=arr->getPointer(); + for(int i=0; i<target_mesh_mc->getNumberOfCells(); i++) + targetvalue[i]=0.0; + // Ok at this point we have our mesh in MED-Memory format. + // Go to wrap med_source_mesh and med_target_mesh. + MEDCouplingNormalizedUnstructuredMesh<2,2> wrap_source_mesh(source_mesh_mc); + MEDCouplingNormalizedUnstructuredMesh<2,2> wrap_target_mesh(target_mesh_mc); + // Go for interpolation... + INTERP_KERNEL::Interpolation2D myInterpolator; + //optionnal call to parametrize your interpolation. First precision, tracelevel, intersector wanted. + myInterpolator.setPrecision(1e-7); + myInterpolator.setPrintLevel(1); + source_mesh->decrRef(); + source_field->decrRef(); + target_field->decrRef(); + target_mesh->decrRef(); + } +} diff --git a/src/medtool/src/INTERP_KERNELTest/InterpolationOptionsTest.hxx b/src/medtool/src/INTERP_KERNELTest/InterpolationOptionsTest.hxx new file mode 100644 index 000000000..d97856a59 --- /dev/null +++ b/src/medtool/src/INTERP_KERNELTest/InterpolationOptionsTest.hxx @@ -0,0 +1,62 @@ +// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 +// 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 __TU_INTERPOLATIONOPTIONS_HXX__ +#define __TU_INTERPOLATIONOPTIONS_HXX__ + +#include <cppunit/extensions/HelperMacros.h> + +#include "InterpKernelTestExport.hxx" +#include "InterpolationOptions.hxx" + +namespace INTERP_TEST +{ + + /** + * \brief Test suite testing some of the low level methods of TransformedTriangle. + * + */ + class INTERPKERNELTEST_EXPORT InterpolationOptionsTest : public CppUnit::TestFixture + { + + CPPUNIT_TEST_SUITE( InterpolationOptionsTest ); + CPPUNIT_TEST( test_InterpolationOptions ); + CPPUNIT_TEST_SUITE_END(); + + + public: + void setUp(); + + void tearDown(); + + // tests + void test_InterpolationOptions(); + + private: + + }; + + + + +} + + + +#endif diff --git a/src/medtool/src/INTERP_KERNELTest/InterpolationPlanarTestSuite.hxx b/src/medtool/src/INTERP_KERNELTest/InterpolationPlanarTestSuite.hxx new file mode 100644 index 000000000..6d9c84f9e --- /dev/null +++ b/src/medtool/src/INTERP_KERNELTest/InterpolationPlanarTestSuite.hxx @@ -0,0 +1,127 @@ +// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 +// 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 __TU_INTERPOLATION_PLANAR_TEST_SUITE_HXX__ +#define __TU_INTERPOLATION_PLANAR_TEST_SUITE_HXX__ + +#include <cppunit/extensions/HelperMacros.h> +#include <deque> +#include <cmath> +#include <iostream> + +namespace INTERP_TEST +{ + + /** + * \brief Base class for planar mesh intersection test suites. + * + */ + class InterpolationPlanarTestSuite : public CppUnit::TestFixture + { + + public: + double _Epsilon; + double _Precision; + + /** + * Sets up the test suite. + * + */ + void setUp() + { + _Epsilon = 1.e-6; + _Precision = 1.e-6; + } + void tearDown() {} + + // bool checkDequesEqual(std::deque< double > deque1, std::deque< double > deque2, double epsilon); + // bool checkVectorsEqual(std::vector< double > Vect1, std::vector< double > Vect2, double epsilon); + // void dequePrintOut(std::deque< double > deque1); + // void vectPrintOut(std::vector< double > vect); + // void tabPrintOut( const double * tab, int size); + + bool checkDequesEqual(std::deque< double > deque1, + std::deque< double > deque2, double epsilon) + { + int size1 = deque1.size(); + int size2 = deque2.size(); + bool are_equal = size1 == size2; + + if(are_equal) + for(int i = 0; i < size1 && are_equal; i++) + are_equal = fabs(deque1[i] - deque2[i]) < epsilon; + + return are_equal; + } + bool checkVectorsEqual(std::vector< double > vect1, + std::vector< double > vect2, double epsilon) + { + int size1 = vect1.size(); + int size2 = vect2.size(); + bool are_equal = size1 == size2; + + if(are_equal) + for(int i = 0; i < size1 && are_equal; i++) + are_equal = fabs(vect1[i] - vect2[i]) < epsilon; + + return are_equal; + } + void dequePrintOut(std::deque< double > deque1) + { + for(int i = 0; i< (int)deque1.size(); i++) + { + std::cerr << deque1[i] << " "; + } + std::cerr<< std::endl; + } + void vectPrintOut(std::vector< double > vect) + { + for(int i = 0; i< (int)vect.size(); i++) + { + std::cerr << vect[i] << " "; + } + std::cerr<< std::endl; + } + void tabPrintOut( const double * tab,int size) + { + for(int i = 0; i< size; i++) + { + std::cerr << tab[i] << " "; + } + std::cerr<< std::endl; + } + + /** + * Cleans up after the test suite. + * Liberates the MeshTestToolkit object used by the tests. + */ + // void tearDown() + // { + // delete _testTools; + // } + + + + // protected: + // /// MeshTestToolkit object to which the tests are delegated + // MeshTestToolkit* _testTools; + + }; +} +#endif diff --git a/src/medtool/src/INTERP_KERNELTest/InterpolationTestSuite.hxx b/src/medtool/src/INTERP_KERNELTest/InterpolationTestSuite.hxx new file mode 100644 index 000000000..9c4ec7a7b --- /dev/null +++ b/src/medtool/src/INTERP_KERNELTest/InterpolationTestSuite.hxx @@ -0,0 +1,66 @@ +// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 +// 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 __TU_INTERPOLATION_TEST_SUITE_HXX__ +#define __TU_INTERPOLATION_TEST_SUITE_HXX__ + +#include "MeshTestToolkit.txx" + +#include <cppunit/extensions/HelperMacros.h> + +namespace INTERP_TEST +{ + + /** + * \brief Base class for mesh intersection test suites. + * + */ + template<int SPACEDIM, int MESHDIM> + class InterpolationTestSuite : public CppUnit::TestFixture + { + + public: + /** + * Sets up the test suite. + * Creates the MeshTestToolkit object used by the tests. + * + */ + void setUp() + { + _testTools = new MeshTestToolkit<SPACEDIM,MESHDIM>(); + } + + /** + * Cleans up after the test suite. + * Liberates the MeshTestToolkit object used by the tests. + */ + void tearDown() + { + delete _testTools; + } + + + + protected: + /// MeshTestToolkit object to which the tests are delegated + MeshTestToolkit<SPACEDIM,MESHDIM>* _testTools; + + }; +} +#endif diff --git a/src/medtool/src/INTERP_KERNELTest/MEDMeshMaker.cxx b/src/medtool/src/INTERP_KERNELTest/MEDMeshMaker.cxx new file mode 100644 index 000000000..f0538b113 --- /dev/null +++ b/src/medtool/src/INTERP_KERNELTest/MEDMeshMaker.cxx @@ -0,0 +1,48 @@ +// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// + +#include "MEDCouplingAutoRefCountObjectPtr.hxx" +#include "MEDCouplingCMesh.hxx" + +#include "MEDMeshMaker.hxx" + +using namespace ParaMEDMEM; + +ParaMEDMEM::MEDCouplingUMesh *MEDMeshMaker(int dim, int nbedge) +{ + MEDCouplingAutoRefCountObjectPtr<MEDCouplingCMesh> c=MEDCouplingCMesh::New(); + MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> arr=DataArrayDouble::New(); + arr->alloc(nbedge+1,1); arr->iota(0.); arr->applyLin(1./double(nbedge),0.); + switch(dim) + { + case 2: + { + c->setCoords(arr,arr); + break; + } + case 3: + { + c->setCoords(arr,arr,arr); + break; + } + default: + throw INTERP_KERNEL::Exception("MEDMeshMaker : only dim 2 or 3 supported !"); + } + return c->buildUnstructured(); +} diff --git a/src/medtool/src/INTERP_KERNELTest/MEDMeshMaker.hxx b/src/medtool/src/INTERP_KERNELTest/MEDMeshMaker.hxx new file mode 100644 index 000000000..44bcdf19b --- /dev/null +++ b/src/medtool/src/INTERP_KERNELTest/MEDMeshMaker.hxx @@ -0,0 +1,22 @@ +// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// + +#include "MEDCouplingUMesh.hxx" + +ParaMEDMEM::MEDCouplingUMesh *MEDMeshMaker(int dim, int nbedge); diff --git a/src/medtool/src/INTERP_KERNELTest/MeshTestToolkit.hxx b/src/medtool/src/INTERP_KERNELTest/MeshTestToolkit.hxx new file mode 100644 index 000000000..0144c9d0f --- /dev/null +++ b/src/medtool/src/INTERP_KERNELTest/MeshTestToolkit.hxx @@ -0,0 +1,90 @@ +// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 +// 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 __TU_MESH_TEST_TOOLKIT_HXX__ +#define __TU_MESH_TEST_TOOLKIT_HXX__ + +#include "Interpolation3D.hxx" +#include "Interpolation3D.txx" +#include "InterpolationPlanar.hxx" + +#include <vector> +#include <map> + +#define ERR_TOL 1.0e-8 + +typedef std::vector<std::map<int,double> > IntersectionMatrix; + +namespace INTERP_KERNEL +{ + class Interpolation3D; +} + + +namespace ParaMEDMEM +{ + class MEDCouplingUMesh; +} + +namespace INTERP_TEST +{ + /** + * \brief Class providing services for mesh intersection tests. + * + */ + template<int SPACEDIM, int MESHDIM> + class MeshTestToolkit + { + + public: + double _precision; + INTERP_KERNEL::IntersectionType _intersectionType;//Used only in the case MESHDIM==2 (planar intersections) + + MeshTestToolkit():_precision(1.e-6),_intersectionType(INTERP_KERNEL::Triangulation) {} + + ~MeshTestToolkit() {} + + void intersectMeshes(const char* mesh1, const char* mesh2, const double correctVol, const double prec = 1.0e-5, bool doubleTest = true) const; + + // 1.0e-5 here is due to limited precision of "correct" volumes calculated in Salome + void intersectMeshes(const char* mesh1path, const char* mesh1, const char* mesh2path, const char* mesh2, const double correctVol, const double prec = 1.0e-5, bool doubleTest = true) const; + + void dumpIntersectionMatrix(const IntersectionMatrix& m) const; + + double sumRow(const IntersectionMatrix& m, int i) const; + + double sumCol(const IntersectionMatrix& m, int i) const; + + void getVolumes(ParaMEDMEM::MEDCouplingUMesh& mesh, double* tab) const; + + bool testVolumes(const IntersectionMatrix& m, ParaMEDMEM::MEDCouplingUMesh& sMesh, ParaMEDMEM::MEDCouplingUMesh& tMesh) const; + + double sumVolume(const IntersectionMatrix& m) const; + + bool areCompatitable( const IntersectionMatrix& m1, const IntersectionMatrix& m2) const; + + bool testTranspose(const IntersectionMatrix& m1, const IntersectionMatrix& m2) const; + + bool testDiagonal(const IntersectionMatrix& m) const; + + void calcIntersectionMatrix(const char* mesh1path, const char* mesh1, const char* mesh2path, const char* mesh2, IntersectionMatrix& m) const; + + }; +} +#endif diff --git a/src/medtool/src/INTERP_KERNELTest/MeshTestToolkit.txx b/src/medtool/src/INTERP_KERNELTest/MeshTestToolkit.txx new file mode 100644 index 000000000..9096963ce --- /dev/null +++ b/src/medtool/src/INTERP_KERNELTest/MeshTestToolkit.txx @@ -0,0 +1,483 @@ +// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// +#include "TestInterpKernelUtils.hxx" + +#include "MeshTestToolkit.hxx" + +#include "MEDFileMesh.hxx" + +#include "MEDCouplingNormalizedUnstructuredMesh.hxx" +#include "MEDCouplingNormalizedUnstructuredMesh.txx" +#include "MEDCouplingFieldDouble.hxx" + +#include "Interpolation3DSurf.hxx" +#include "Interpolation2D.txx" +#include "Interpolation3D.txx" + +#include <map> +#include <cmath> +#include <vector> +#include <cstring> +#include <iostream> +#include <algorithm> + + +// levels : +// 1 - titles and volume results +// 2 - symmetry / diagonal results and intersection matrix output +// 3 - empty +// 4 - empty +// 5 - misc +#include "Log.hxx" + +#include <cppunit/extensions/HelperMacros.h> + +//#define VOL_PREC 1.0e-6 +using namespace ParaMEDMEM; +using namespace INTERP_KERNEL; + +namespace INTERP_TEST +{ + /** + * Calculates the sum of a row of an intersection matrix + * + * @param m an intersection matrix + * @param i the index of the row (1 <= i <= no. rows) + * @return the sum of the values of row i + * + */ + template <int SPACEDIM, int MESHDIM> + double MeshTestToolkit<SPACEDIM,MESHDIM>::sumRow(const IntersectionMatrix& m, int i) const + { + double vol = 0.0; + for(IntersectionMatrix::const_iterator iter = m.begin() ; iter != m.end() ; ++iter) + { + if(iter->count(i) != 0.0) + { + std::map<int, double>::const_iterator iter2 = iter->find(i); + vol += fabs(iter2->second); + } + } + return vol; + } + + /** + * Calculates the sum of a column of an intersection matrix + * + * @param m an intersection matrix + * @param i the index of the column (0 <= i <= no. rows - 1) + * @return the sum of the values of column i + * + */ + template <int SPACEDIM, int MESHDIM> + double MeshTestToolkit<SPACEDIM,MESHDIM>::sumCol(const IntersectionMatrix& m, int i) const + { + double vol = 0.0; + const std::map<int, double>& col = m[i]; + for(std::map<int, double>::const_iterator iter = col.begin() ; iter != col.end() ; ++iter) + { + vol += fabs(iter->second); + } + return vol; + } + + /** + * Gets the volumes of the elements in a mesh. + * + * @param mesh the mesh + * @param tab pointer to double[no. elements of mesh] array in which to store the volumes + */ + template <int SPACEDIM, int MESHDIM> + void MeshTestToolkit<SPACEDIM,MESHDIM>::getVolumes(ParaMEDMEM::MEDCouplingUMesh& mesh, double *tab) const + { + MEDCouplingAutoRefCountObjectPtr<MEDCouplingFieldDouble> vol=mesh.getMeasureField(true); + std::copy(vol->getArray()->begin(),vol->getArray()->end(),tab); + } + + /** + * Sums all the elements (volumes) of an intersection matrix + * + * @param m the intersection matrix + * @return the sum of the elements of m + */ + + template <int SPACEDIM, int MESHDIM> + double MeshTestToolkit<SPACEDIM,MESHDIM>::sumVolume(const IntersectionMatrix& m) const + { + std::vector<double> volumes; + for(IntersectionMatrix::const_iterator iter = m.begin() ; iter != m.end() ; ++iter) + { + for(std::map<int, double>::const_iterator iter2 = iter->begin() ; iter2 != iter->end() ; ++iter2) + { + volumes.push_back(fabs(iter2->second)); + } + } + + // sum in ascending order to avoid rounding errors + + sort(volumes.begin(), volumes.end()); + const double vol = accumulate(volumes.begin(), volumes.end(), 0.0); + + return vol; + } + + /** + * Verifies if for a given intersection matrix the sum of each row is equal to the volumes + * of the corresponding source elements and the sum of each column is equal to the volumes + * of the corresponding target elements. This will be true as long as the meshes correspond + * to the same geometry. The equalities are in the "epsilon-sense", making sure the relative + * error is small enough. + * + * @param m the intersection matrix + * @param sMesh the source mesh + * @param tMesh the target mesh + * @return true if the condition is verified, false if not. + */ + template <int SPACEDIM, int MESHDIM> + bool MeshTestToolkit<SPACEDIM,MESHDIM>::testVolumes(const IntersectionMatrix& m, ParaMEDMEM::MEDCouplingUMesh& sMesh, ParaMEDMEM::MEDCouplingUMesh& tMesh) const + { + bool ok = true; + + // source elements + double* sVol = new double[sMesh.getNumberOfCells()]; + getVolumes(sMesh, sVol); + + for(int i = 0; i < sMesh.getNumberOfCells(); ++i) + { + const double sum_row = sumRow(m, i); + if(!epsilonEqualRelative(sum_row, fabs(sVol[i]), _precision)) + { + LOG(1, "Source volume inconsistent : vol of cell " << i << " = " << sVol[i] << " but the row sum is " << sum_row ); + ok = false; + } + LOG(1, "diff = " <<sum_row - sVol[i] ); + } + + // target elements + double* tVol = new double[tMesh.getNumberOfCells()]; + getVolumes(tMesh, tVol); + for(int i = 0; i < tMesh.getNumberOfCells(); ++i) + { + const double sum_col = sumCol(m, i); + if(!epsilonEqualRelative(sum_col,fabs(tVol[i]), _precision)) + { + LOG(1, "Target volume inconsistent : vol of cell " << i << " = " << tVol[i] << " but the col sum is " << sum_col); + ok = false; + } + LOG(1, "diff = " <<sum_col - tVol[i] ); + } + delete[] sVol; + delete[] tVol; + + return ok; + } + + /** + * Verifies that two intersection matrices have the necessary elements to be able to be each others' transposes. + * + * @param m1 the first intersection matrix + * @param m2 the second intersection matrix + * + * @return true if for each element (i,j) of m1, the element (j,i) exists in m2, false if not. + */ + template <int SPACEDIM, int MESHDIM> + bool MeshTestToolkit<SPACEDIM,MESHDIM>::areCompatitable(const IntersectionMatrix& m1, const IntersectionMatrix& m2) const + { + bool compatitable = true; + int i = 0; + for(IntersectionMatrix::const_iterator iter = m1.begin() ; iter != m1.end() ; ++iter) + { + for(std::map<int, double>::const_iterator iter2 = iter->begin() ; iter2 != iter->end() ; ++iter2) + { + int j = iter2->first; + if(m2.at(j).count(i) == 0) + { + if(!epsilonEqual(iter2->second, 0.0, _precision)) + { + LOG(2, "V1( " << i << ", " << j << ") exists, but V2( " << j << ", " << i << ") " << " does not " ); + LOG(2, "(" << i << ", " << j << ") fails"); + compatitable = false; + } + } + } + ++i; + } + if(!compatitable) + { + LOG(1, "*** matrices are not compatitable"); + } + return compatitable; + } + + /** + * Tests if two intersection matrices are each others' transposes. + * + * @param m1 the first intersection matrix + * @param m2 the second intersection matrix + * @return true if m1 = m2^T, false if not. + */ + template <int SPACEDIM, int MESHDIM> + bool MeshTestToolkit<SPACEDIM,MESHDIM>::testTranspose(const IntersectionMatrix& m1, const IntersectionMatrix& m2) const + { + int i = 0; + bool isSymmetric = true; + + LOG(1, "Checking symmetry src - target" ); + isSymmetric = isSymmetric & areCompatitable(m1, m2) ; + LOG(1, "Checking symmetry target - src" ); + isSymmetric = isSymmetric & areCompatitable(m2, m1); + + for(IntersectionMatrix::const_iterator iter = m1.begin() ; iter != m1.end() ; ++iter) + { + for(std::map<int, double>::const_iterator iter2 = iter->begin() ; iter2 != iter->end() ; ++iter2) + { + int j = iter2->first; + const double v1 = fabs(iter2->second); + //if(m2[j - 1].count(i+1) > 0) + // { + std::map<int, double> theMap = m2.at(j); + const double v2 = fabs(theMap[i]); + if(v1 != v2) + { + LOG(2, "V1( " << i << ", " << j << ") = " << v1 << " which is different from V2( " << j << ", " << i << ") = " << v2 << " | diff = " << v1 - v2 ); + if(!epsilonEqualRelative(v1, v2, _precision)) + { + LOG(2, "(" << i << ", " << j << ") fails"); + isSymmetric = false; + } + } + } + ++i; + } + if(!isSymmetric) + { + LOG(1, "*** matrices are not symmetric"); + } + return isSymmetric; + } + + /** + * Tests if an intersection matrix is diagonal. + * + * @param m the intersection matrix + * @return true if m is diagonal; false if not + * + */ + template <int SPACEDIM, int MESHDIM> + bool MeshTestToolkit<SPACEDIM,MESHDIM>::testDiagonal(const IntersectionMatrix& m) const + { + LOG(1, "Checking if matrix is diagonal" ); + int i = 0; + bool isDiagonal = true; + for(IntersectionMatrix::const_iterator iter = m.begin() ; iter != m.end() ; ++iter) + { + for(std::map<int, double>::const_iterator iter2 = iter->begin() ; iter2 != iter->end() ; ++iter2) + { + int j = iter2->first; + const double vol = iter2->second; + if(vol != 0.0 && (i != j)) + { + LOG(2, "V( " << i << ", " << j << ") = " << vol << " which is not zero" ); + if(!epsilonEqual(vol, 0.0, _precision)) + { + LOG(2, "(" << i << ", " << j << ") fails"); + isDiagonal = false; + } + } + } + ++i; + } + if(!isDiagonal) + { + LOG(1, "*** matrix is not diagonal"); + } + return isDiagonal; + } + + /** + * Outputs the intersection matrix as a list of all its elements to std::cout. + * + * @param m the intersection matrix to output + */ + template <int SPACEDIM, int MESHDIM> + void MeshTestToolkit<SPACEDIM,MESHDIM>::dumpIntersectionMatrix(const IntersectionMatrix& m) const + { + int i = 0; + std::cout << "Intersection matrix is " << std::endl; + for(IntersectionMatrix::const_iterator iter = m.begin() ; iter != m.end() ; ++iter) + { + for(std::map<int, double>::const_iterator iter2 = iter->begin() ; iter2 != iter->end() ; ++iter2) + { + std::cout << "V(" << i << ", " << iter2->first << ") = " << iter2->second << std::endl; + } + ++i; + } + std::cout << "Sum of volumes = " << sumVolume(m) << std::endl; + } + + /** + * Calculates the intersection matrix for two meshes. + * If the source and target meshes are the same, a CppUnit assertion raised if testVolumes() returns false. + * + * @param mesh1path the path to the file containing the source mesh, relative to {$MED_ROOT_DIR}/share/salome/resources/med/ + * @param mesh1 the name of the source mesh + * @param mesh2path the path to the file containing the target mesh, relative to {$MED_ROOT_DIR}/share/salome/resources/med/ + * @param mesh2 the name of the target mesh + * @param m intersection matrix in which to store the result of the intersection + */ + template <int SPACEDIM, int MESHDIM> + void MeshTestToolkit<SPACEDIM,MESHDIM>::calcIntersectionMatrix(const char* mesh1path, const char* mesh1, const char* mesh2path, const char* mesh2, IntersectionMatrix& m) const + { + LOG(1, std::endl << "=== -> intersecting src = " << mesh1path << ", target = " << mesh2path ); + + LOG(5, "Loading " << mesh1 << " from " << mesh1path); + MEDCouplingAutoRefCountObjectPtr<MEDFileUMesh> sMeshML=MEDFileUMesh::New(INTERP_TEST::getResourceFile(mesh1path).c_str(),mesh1); + MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> sMesh=sMeshML->getMeshAtLevel(0); + + LOG(5, "Loading " << mesh2 << " from " << mesh2path); + MEDCouplingAutoRefCountObjectPtr<MEDFileUMesh> tMeshML=MEDFileUMesh::New(INTERP_TEST::getResourceFile(mesh2path).c_str(),mesh2); + MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> tMesh=tMeshML->getMeshAtLevel(0); + + MEDCouplingNormalizedUnstructuredMesh<SPACEDIM,MESHDIM> sMesh_wrapper(sMesh); + MEDCouplingNormalizedUnstructuredMesh<SPACEDIM,MESHDIM> tMesh_wrapper(tMesh); + + if (SPACEDIM==2 && MESHDIM==2) + { + Interpolation2D interpolator; + interpolator.setOptions(_precision, LOG_LEVEL, _intersectionType,1); + interpolator.interpolateMeshes(sMesh_wrapper, tMesh_wrapper,m,"P0P0"); + } + else if (SPACEDIM==3 && MESHDIM==2) + { + Interpolation3DSurf interpolator; + interpolator.setOptions(_precision,LOG_LEVEL, 0.5,_intersectionType,false,1); + interpolator.interpolateMeshes(sMesh_wrapper, tMesh_wrapper,m,"P0P0"); + } + else if (SPACEDIM==3 && MESHDIM==3) + { + Interpolation3D interpolator; + interpolator.interpolateMeshes(sMesh_wrapper, tMesh_wrapper,m,"P0P0"); + } + else + { + throw INTERP_KERNEL::Exception("Wrong dimensions"); + } + // if reflexive, check volumes + if(strcmp(mesh1path,mesh2path) == 0) + { + const bool row_and_col_sums_ok = testVolumes(m, *sMesh, *tMesh); + CPPUNIT_ASSERT_EQUAL_MESSAGE("Row or column sums incorrect", true, row_and_col_sums_ok); + const bool is_diagonal =testDiagonal(m); + CPPUNIT_ASSERT_EQUAL_MESSAGE("Self intersection matrix is not diagonal", true, is_diagonal); + } + + LOG(1, "Intersection calculation done. " << std::endl ); + } + + /** + * Tests the intersection algorithm for two meshes. + * Depending on the nature of the meshes, different tests will be performed. The sum of the elements will + * be compared to the given total volume of the intersection in all cases. If the two meshes are the same, then + * it will be confirmed that the intersection matrix is diagonal, otherwise the intersection matrices will be + * calculated once which each mesh as source mesh, and it will be verified that the they are each others' transpose. + * + * @param mesh1path the path to the file containing the source mesh, relative to {$MED_ROOT_DIR}/share/salome/resources/med/ + * @param mesh1 the name of the source mesh + * @param mesh2path the path to the file containing the target mesh, relative to {$MED_ROOT_DIR}/share/salome/resources/med/ + * @param mesh2 the name of the target mesh + * @param correctVol the total volume of the intersection of the two meshes + * @param prec maximum relative error to be tolerated in volume comparisions + * @param doubleTest if false, only the test with mesh 1 as the source mesh and mesh 2 as the target mesh will be performed + * + */ + template <int SPACEDIM, int MESHDIM> + void MeshTestToolkit<SPACEDIM,MESHDIM>::intersectMeshes(const char* mesh1path, const char* mesh1, const char* mesh2path, const char* mesh2, const double correctVol, const double prec, bool doubleTest) const + { + LOG(1, std::endl << std::endl << "=============================" ); + + using std::string; + const string path1 = string(mesh1path) + string(mesh1); + const string path2 = string(mesh2path) + string(mesh2); + + const bool isTestReflexive = (path1.compare(path2) == 0); + + IntersectionMatrix matrix1; + calcIntersectionMatrix(mesh1path, mesh1, mesh2path, mesh2, matrix1); + +#if LOG_LEVEL >= 2 + dumpIntersectionMatrix(matrix1); +#endif + + std::cout.precision(16); + + const double vol1 = sumVolume(matrix1); + + if(!doubleTest) + { + LOG(1, "vol = " << vol1 <<" correctVol = " << correctVol ); + CPPUNIT_ASSERT_DOUBLES_EQUAL(correctVol, vol1, prec * std::max(correctVol, vol1)); + + if(isTestReflexive) + { + CPPUNIT_ASSERT_EQUAL_MESSAGE("Reflexive test failed", true, testDiagonal(matrix1)); + } + } + else + { + IntersectionMatrix matrix2; + calcIntersectionMatrix(mesh2path, mesh2, mesh1path, mesh1, matrix2); + +#if LOG_LEVEL >= 2 + dumpIntersectionMatrix(matrix2); +#endif + + const double vol2 = sumVolume(matrix2); + + LOG(1, "vol1 = " << vol1 << ", vol2 = " << vol2 << ", correctVol = " << correctVol ); + + CPPUNIT_ASSERT_EQUAL_MESSAGE("Symmetry test failed", true, testTranspose(matrix1, matrix2)); + CPPUNIT_ASSERT_DOUBLES_EQUAL(correctVol, vol1, prec * std::max(vol1, correctVol)); + CPPUNIT_ASSERT_DOUBLES_EQUAL(correctVol, vol2, prec * std::max(vol2, correctVol)); + CPPUNIT_ASSERT_DOUBLES_EQUAL(vol1, vol2, prec * std::max(vol1, vol2)); + } + } + + /** + * Utility method used to facilitate the call to intersect meshes. + * It calls intersectMeshes, using "mesh1.med" as file name for the mesh with name "mesh1" and + * "mesh2.med" as file name for the mesh with name "mesh2". The rest of the arguments are passed + * along as they are. + * + * @param mesh1 the name of the source mesh + * @param mesh2 the name of the target mesh + * @param correctVol the total volume of the intersection of the two meshes + * @param prec maximum relative error to be tolerated in volume comparisions + * @param doubleTest if false, only the test with mesh 1 as the source mesh and mesh 2 as the target mesh will be performed + * + */ + template <int SPACEDIM, int MESHDIM> + void MeshTestToolkit<SPACEDIM,MESHDIM>::intersectMeshes(const char* mesh1, const char* mesh2, const double correctVol, const double prec, bool doubleTest) const + { + const std::string path1 = std::string(mesh1) + std::string(".med"); + std::cout << "here :" << path1 << std::endl; + const std::string path2 = std::string(mesh2) + std::string(".med"); + + intersectMeshes(path1.c_str(), mesh1, path2.c_str(), mesh2, correctVol, prec, doubleTest); + } +} diff --git a/src/medtool/src/INTERP_KERNELTest/MultiElement2DTests.hxx b/src/medtool/src/INTERP_KERNELTest/MultiElement2DTests.hxx new file mode 100644 index 000000000..12d3036ef --- /dev/null +++ b/src/medtool/src/INTERP_KERNELTest/MultiElement2DTests.hxx @@ -0,0 +1,63 @@ +// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 +// 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 __MULTI_ELEMENT_2D_TESTS_HXX_ +#define __MULTI_ELEMENT_2D_TESTS_HXX_ + +#include "InterpolationTestSuite.hxx" + +namespace INTERP_TEST +{ + /** + * \brief Class testing algorithm by intersecting meshes of several + * polygonal elements - up to a few thousand. This serves to check the + * filtering methods and the matrix assemblage, as well as verifying + * that computation errors do not become unmanageable. It uses mehes of + * different geometries : triangle, quadrilateral. + * + */ + class MultiElement2DTests : public InterpolationTestSuite<2,2> + { + CPPUNIT_TEST_SUITE( MultiElement2DTests ); + + CPPUNIT_TEST(SymetryTranspose2DTest); + CPPUNIT_TEST(SelfIntersection2DTest); + + CPPUNIT_TEST_SUITE_END(); + + public: + void SymetryTranspose2DTest() + { + _testTools->_intersectionType=INTERP_KERNEL::Triangulation; + _testTools->intersectMeshes("square1.med", "Mesh_2","square2.med","Mesh_3", 10000.); + _testTools->_intersectionType=INTERP_KERNEL::Convex; + _testTools->intersectMeshes("square1.med", "Mesh_2","square2.med","Mesh_3", 10000.); + } + void SelfIntersection2DTest() + { + IntersectionMatrix m; + _testTools->_intersectionType=INTERP_KERNEL::Triangulation; + _testTools->calcIntersectionMatrix("square1.med", "Mesh_2","square1.med","Mesh_2", m); + //_testTools->_intersectionType=INTERP_KERNEL::Convex;// valgrind complains ! + //_testTools->calcIntersectionMatrix("square1.med", "Mesh_2","square1.med","Mesh_2", m); + } + }; +} + +#endif diff --git a/src/medtool/src/INTERP_KERNELTest/MultiElement3DSurfTests.hxx b/src/medtool/src/INTERP_KERNELTest/MultiElement3DSurfTests.hxx new file mode 100644 index 000000000..6308c046c --- /dev/null +++ b/src/medtool/src/INTERP_KERNELTest/MultiElement3DSurfTests.hxx @@ -0,0 +1,63 @@ +// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 +// 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 __MULTI_ELEMENT_3DSurf_TESTS_HXX_ +#define __MULTI_ELEMENT_3DSurf_TESTS_HXX_ + +#include "InterpolationTestSuite.hxx" + +namespace INTERP_TEST +{ + /** + * \brief Class testing algorithm by intersecting meshes of several + * polygonal elements - up to a few thousand. This serves to check the + * filtering methods and the matrix assemblage, as well as verifying + * that computation errors do not become unmanageable. It uses mehes of + * different geometries : triangle, quadrilateral. + * + */ + class MultiElement2DTests : public InterpolationTestSuite<3,2> + { + CPPUNIT_TEST_SUITE( MultiElement3DSurfTests ); + + CPPUNIT_TEST(SymetryTranspose3DSurfTest); + CPPUNIT_TEST(SelfIntersection3DSurfTest); + + CPPUNIT_TEST_SUITE_END(); + + public: + void SymetryTranspose3DSurfTest() + { + _testTools->_intersectionType=INTERP_KERNEL::Triangulation; + _testTools->intersectMeshes("square1.med", "Mesh_2","square2.med","Mesh_3", 10000.); + _testTools->_intersectionType=INTERP_KERNEL::Convex; + _testTools->intersectMeshes("square1.med", "Mesh_2","square2.med","Mesh_3", 10000.); + } + void SelfIntersection3DSurfTest() + { + IntersectionMatrix m; + _testTools->_intersectionType=INTERP_KERNEL::Triangulation; + _testTools->calcIntersectionMatrix("square1.med", "Mesh_2","square1.med","Mesh_2", m); + _testTools->_intersectionType=INTERP_KERNEL::Convex; + _testTools->calcIntersectionMatrix("square1.med", "Mesh_2","square1.med","Mesh_2", m); + } + }; +} + +#endif diff --git a/src/medtool/src/INTERP_KERNELTest/MultiElementTetraTests.hxx b/src/medtool/src/INTERP_KERNELTest/MultiElementTetraTests.hxx new file mode 100644 index 000000000..d901eb332 --- /dev/null +++ b/src/medtool/src/INTERP_KERNELTest/MultiElementTetraTests.hxx @@ -0,0 +1,159 @@ +// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 +// 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 __MULTI_ELEMENT_TETRA_TESTS_HXX_ +#define __MULTI_ELEMENT_TETRA_TESTS_HXX_ + +#include "InterpolationTestSuite.hxx" + +namespace INTERP_TEST +{ + /** + * \brief Class testing algorithm by intersecting meshes of several + * elements (all tetrahedra) - up to a few thousand. This serves to check the + * filtering methods and the matrix assemblage, as well as verifying + * that computation errors do not become unmanageable. It uses mehes of + * different geometries : tetrahedra, boxes and cylinders. + * + */ + class MultiElementTetraTests : public InterpolationTestSuite<3,3> + { + CPPUNIT_TEST_SUITE( MultiElementTetraTests ); + + CPPUNIT_TEST( tetraComplexIncluded ); + CPPUNIT_TEST( dividedUnitTetraSimplerReflexive ); + CPPUNIT_TEST( dividedUnitTetraReflexive ); + CPPUNIT_TEST( nudgedDividedUnitTetraSimpler ); + CPPUNIT_TEST( nudgedDividedUnitTetra ); + CPPUNIT_TEST( dividedGenTetra ); + CPPUNIT_TEST( tinyBoxReflexive ); + CPPUNIT_TEST( moderateBoxEvenSmallerReflexive ); + CPPUNIT_TEST( moderateBoxSmallReflexive ); + CPPUNIT_TEST( boxReflexive ); + CPPUNIT_TEST( boxReflexiveModerate ); + CPPUNIT_TEST( tetraBoxes ); + CPPUNIT_TEST( moderateBoxesSmaller ); + CPPUNIT_TEST( moderateBoxes ); + + CPPUNIT_TEST_SUITE_END(); + + public: + + /// Tetrahedron situated totally inside another + /// \brief Status : pass + void tetraComplexIncluded() + { + _testTools->intersectMeshes("ComplexIncludedTetra", "ComplexIncludingTetra", 17.0156); + } + + /// Unit tetrahedron divided in 4 elements intersecting itself. + /// \brief Status : pass + void dividedUnitTetraSimplerReflexive() + { + _testTools->intersectMeshes("DividedUnitTetraSimpler", "DividedUnitTetraSimpler", 0.1666667); + } + + /// Unit tetrahedron divided in 14 elements intersecting itself. + /// \brief Status : pass + void dividedUnitTetraReflexive() + { + _testTools->intersectMeshes("DividedUnitTetra", "DividedUnitTetra", 0.1666667); + } + + /// Unit tetrahedron divided in 4 elements intersecting slightly displaced version of itself. + /// \brief Status : pass + void nudgedDividedUnitTetraSimpler() + { + _testTools->intersectMeshes("NudgedDividedUnitTetraSimpler", "DividedUnitTetraSimpler", 0.150191); + } + + /// Unit tetrahedron divided in 14 elements intersecting slightly displaced version of itself. + /// \brief Status : pass + void nudgedDividedUnitTetra() + { + _testTools->intersectMeshes("NudgedDividedUnitTetra", "DividedUnitTetra", 0.150191); + } + + /// Two intersecting tetrahedra in general position, one with 23 elements, the other with 643 elements + /// \brief Status : pass + void dividedGenTetra() + { + _testTools->intersectMeshes("DividedGenTetra1", "DividedGenTetra2", 0.546329); + } + + /// Large box in general position with 12 elements intersecting itself + /// \brief Status : pass + void tinyBoxReflexive() + { + _testTools->intersectMeshes("TinyBox", "TinyBox", 979200); + } + + /// Small box in general position with 33 elements intersecting itself + /// \brief Status : pass + void boxReflexive() + { + _testTools->intersectMeshes("Box3", "Box3", 13.9954); + } + + /// Box in general position with 67 elements intersecting itself + /// \brief Status : pass + void moderateBoxEvenSmallerReflexive() + { + _testTools->intersectMeshes("BoxEvenSmaller1", "BoxEvenSmaller1", 1.44018e6); + } + + /// Box in general position with 544 elements intersecting itself + /// \brief Status : pass + void moderateBoxSmallReflexive() + { + _testTools->intersectMeshes("BoxModSmall1", "BoxModSmall1", 1.44018e6); + } + + /// Large box in general position with 2943 elements intersecting itself + /// \brief Status : pass + void boxReflexiveModerate() + { + _testTools->intersectMeshes("Box1Moderate", "Box1Moderate", 1.0e6); + } + + /// Two intersecting boxes in general position with 12 and 18 elements + /// \brief Status : pass + void tetraBoxes() + { + _testTools->intersectMeshes("Box1", "Box2", 124.197); + } + + /// Two intersecting boxes in general position with 430 and 544 elements + /// \brief Status : pass + void moderateBoxesSmaller() + { + _testTools->intersectMeshes("BoxModSmall1", "BoxModSmall2", 321853); + } + + /// Two intersecting boxes in general position with 2943 and 3068 elements + /// \brief Status : pass + void moderateBoxes() + { + _testTools->intersectMeshes("Box1Moderate", "Box2Moderate", 376856); + } + + }; +} + +#endif diff --git a/src/medtool/src/INTERP_KERNELTest/PerfTest.cxx b/src/medtool/src/INTERP_KERNELTest/PerfTest.cxx new file mode 100644 index 000000000..85d67be1a --- /dev/null +++ b/src/medtool/src/INTERP_KERNELTest/PerfTest.cxx @@ -0,0 +1,155 @@ +// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// + +#include "Interpolation3D.hxx" +#include "Interpolation3D.txx" +#include "MeshTestToolkit.txx" +#include "Log.hxx" +#include "VectorUtils.hxx" +#include "TestInterpKernelUtils.hxx" + +#include "MEDCouplingNormalizedUnstructuredMesh.hxx" + +#include <cassert> +#include <string> + +/** + * \file PerfTest.cxx + * Test program which takes two meshes and calculates their intersection matrix. + * + * USAGE : PerfTest mesh1 mesh2 + * where mesh1 and mesh2 are the names of two meshes located in + * the files mesh1.med, mesh2.med in {$MED_ROOT_DIR}/share/salome/resources/med/ + * + */ + +namespace INTERP_TEST +{ + /** + * \brief Specialization of MeshTestToolkit for the purposes of performance testing. + * + */ + class PerfTestToolkit : public MeshTestToolkit<3,3> + { + + public: + + /** + * Calculates the intersection matrix for two meshes. + * Outputs the names of the meshes intersected, the number of elements in each mesh, + * the number of matrix elements and the number of non-zero matrix elements, etc. + * These values help to determine how well the filtering algorithm is working. + * + * @param mesh1path the path to the file containing the source mesh, relative to {$MED_ROOT_DIR}/share/salome/resources/med/ + * @param mesh1 the name of the source mesh + * @param mesh2path the path to the file containing the target mesh, relative to {$MED_ROOT_DIR}/share/salome/resources/med/ + * @param mesh2 the name of the target mesh + * @param m intersection matrix in which to store the result of the intersection + */ + void calcIntersectionMatrix(const char* mesh1path, const char* mesh1, const char* mesh2path, const char* mesh2, IntersectionMatrix& m) + { + LOG(1, std::endl << "=== -> intersecting src = " << mesh1 << ", target = " << mesh2 ); + + LOG(5, "Loading " << mesh1 << " from " << mesh1path); + MEDCouplingAutoRefCountObjectPtr<MEDFileUMesh> sMeshML=MEDFileUMesh::New(INTERP_TEST::getResourceFile(mesh1path).c_str(),mesh1); + MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> sMesh=sMeshML->getMeshAtLevel(0); + + + LOG(5, "Loading " << mesh2 << " from " << mesh2path); + MEDCouplingAutoRefCountObjectPtr<MEDFileUMesh> tMeshML=MEDFileUMesh::New(INTERP_TEST::getResourceFile(mesh2path).c_str(),mesh2); + MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> tMesh=tMeshML->getMeshAtLevel(0); + + MEDCouplingNormalizedUnstructuredMesh<3,3> sMesh_wrapper(sMesh); + MEDCouplingNormalizedUnstructuredMesh<3,3> tMesh_wrapper(tMesh); + + Interpolation3D interpolator; + interpolator.interpolateMeshes(sMesh_wrapper, tMesh_wrapper,m,"P0P0"); + + std::pair<int, int> eff = countNumberOfMatrixEntries(m); + LOG(1, eff.first << " of " << numTargetElems * numSrcElems << " intersections calculated : ratio = " + << double(eff.first) / double(numTargetElems * numSrcElems)); + LOG(1, eff.second << " non-zero elements of " << eff.first << " total : filter efficiency = " + << double(eff.second) / double(eff.first)); + + LOG(1, "Intersection calculation done. " << std::endl ); + + } + + /** + * Counts the number of elements in an intersection matrix, and the number of these which are non-zero. + * + * @param m the intersection matrix + * @return pair<int, int> containing as its first element the number of elements in m and as its second element the + * number these which are non-zero + */ + std::pair<int,int> countNumberOfMatrixEntries(const IntersectionMatrix& m) + { + + int numElems = 0; + int numNonZero = 0; + for(IntersectionMatrix::const_iterator iter = m.begin() ; iter != m.end() ; ++iter) + { + numElems += iter->size(); + for(std::map<int, double>::const_iterator iter2 = iter->begin() ; iter2 != iter->end() ; ++iter2) + { + if(!INTERP_KERNEL::epsilonEqual(iter2->second, 0.0, VOL_PREC)) + { + ++numNonZero; + } + } + } + return std::make_pair(numElems, numNonZero); + } + + }; +} + +/** + * Main method of the program. + * Intersects the meshes and outputs some information about the calculation as well as the + * intersection matrix on std::cout. + * + * @param argc number of arguments given to the program (should be 3, the user giving 2 mesh names) + * @param argv vector to the arguments as strings. + */ +int main(int argc, char** argv) +{ + using INTERP_TEST::PerfTestToolkit; + + assert(argc == 3); + + // load meshes + const std::string mesh1 = argv[1]; + const std::string mesh2 = argv[2]; + + const std::string mesh1path = mesh1 + ".med"; + const std::string mesh2path = mesh2 + ".med"; + + IntersectionMatrix m; + + PerfTestToolkit testTools; + + testTools.calcIntersectionMatrix(mesh1path.c_str(), mesh1.c_str(), mesh2path.c_str(), mesh2.c_str(), m); + + testTools.dumpIntersectionMatrix(m); + + return 0; + +} + diff --git a/src/medtool/src/INTERP_KERNELTest/QuadraticPlanarInterpTest.cxx b/src/medtool/src/INTERP_KERNELTest/QuadraticPlanarInterpTest.cxx new file mode 100644 index 000000000..3a1f8a46a --- /dev/null +++ b/src/medtool/src/INTERP_KERNELTest/QuadraticPlanarInterpTest.cxx @@ -0,0 +1,1023 @@ +// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 +// 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 "QuadraticPlanarInterpTest.hxx" +#include "InterpKernelGeo2DQuadraticPolygon.hxx" +#include "InterpKernelGeo2DEdgeArcCircle.hxx" +#include "InterpKernelGeo2DElementaryEdge.hxx" +#include "InterpKernelGeo2DComposedEdge.hxx" +#include "InterpKernelGeo2DEdgeLin.hxx" +#include "TestInterpKernelUtils.hxx" + +#include <sstream> +#include <iostream> + +using namespace INTERP_KERNEL; + +namespace INTERP_TEST +{ + +static const double ADMISSIBLE_ERROR = 1.e-14; + +void QuadraticPlanarInterpTest::setUp() +{ +} + +void QuadraticPlanarInterpTest::tearDown() +{ +} + +void QuadraticPlanarInterpTest::cleanUp() +{ +} + +void QuadraticPlanarInterpTest::ReadWriteInXfigElementary() +{ + //Testing bounds calculation. For Seg2 + std::istringstream stream("2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 2\n3200 3400 4500 4700"); + EdgeLin *e1=new EdgeLin(stream); + Bounds bound=e1->getBounds(); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.32,bound[0],ADMISSIBLE_ERROR); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.45,bound[1],ADMISSIBLE_ERROR); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.34,bound[2],ADMISSIBLE_ERROR); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.47,bound[3],ADMISSIBLE_ERROR); + e1->decrRef(); + std::istringstream stream2("2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 2\n4500 4700 3200 3400"); + e1=new EdgeLin(stream2); + bound=e1->getBounds(); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.32,bound[0],ADMISSIBLE_ERROR); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.45,bound[1],ADMISSIBLE_ERROR); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.34,bound[2],ADMISSIBLE_ERROR); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.47,bound[3],ADMISSIBLE_ERROR); + e1->decrRef(); + //Testing bounds calculation For Arc of circle. + +} + +void QuadraticPlanarInterpTest::ReadWriteInXfigGlobal() +{ + QuadraticPolygon pol1(INTERP_TEST::getResourceFile("Pol1.fig").c_str()); + pol1.dumpInXfigFile("Pol1_gen.fig"); + QuadraticPolygon pol2(INTERP_TEST::getResourceFile("Pol2.fig").c_str()); + pol2.dumpInXfigFile("Pol2_gen.fig"); + QuadraticPolygon pol3(INTERP_TEST::getResourceFile("Pol3.fig").c_str()); + pol3.dumpInXfigFile("Pol3_gen.fig"); + QuadraticPolygon pol4(INTERP_TEST::getResourceFile("Pol4.fig").c_str()); + CPPUNIT_ASSERT_EQUAL(1,pol4.size()); + ElementaryEdge *edge1=dynamic_cast<ElementaryEdge *>(pol4[0]); + CPPUNIT_ASSERT(edge1); + Edge *edge2=edge1->getPtr(); + EdgeArcCircle *edge=dynamic_cast<EdgeArcCircle *>(edge2); + CPPUNIT_ASSERT(edge); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.24375,edge->getRadius(),ADMISSIBLE_ERROR); + CPPUNIT_ASSERT_DOUBLES_EQUAL(5.7857653289925404,edge->getAngle(),ADMISSIBLE_ERROR); + double center[2]; + edge->getCenter(center); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.48,center[0],ADMISSIBLE_ERROR); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.48375,center[1],ADMISSIBLE_ERROR); + const double *start=*edge->getStartNode(); + Node *n1=new Node(start[0]+2*(center[0]-start[0]),start[1]+2*(center[1]-start[1])); + edge->changeMiddle(n1); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.24375,edge->getRadius(),ADMISSIBLE_ERROR); + CPPUNIT_ASSERT_DOUBLES_EQUAL(5.7857653289925404,edge->getAngle(),ADMISSIBLE_ERROR); + n1->decrRef(); + n1=new Node(center[0],center[1]+0.24375); + edge->changeMiddle(n1); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.24375,edge->getRadius(),ADMISSIBLE_ERROR); + CPPUNIT_ASSERT_DOUBLES_EQUAL(-0.49741997818704586,edge->getAngle(),ADMISSIBLE_ERROR);//5.7857653289925404 + 2*PI + n1->decrRef(); + //A half circle. + EdgeArcCircle *e=new EdgeArcCircle(0.84,0.54,0.78,0.6,0.84,0.66); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.06,e->getRadius(),ADMISSIBLE_ERROR); + CPPUNIT_ASSERT_DOUBLES_EQUAL(-3.1415925921507317,e->getAngle(),1e-5); + e->decrRef(); + e=new EdgeArcCircle(0.84,0.54,0.9,0.6,0.84,0.66); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.06,e->getRadius(),ADMISSIBLE_ERROR); + CPPUNIT_ASSERT_DOUBLES_EQUAL(3.1415925921507317,e->getAngle(),1e-5); + e->decrRef(); +} + +void QuadraticPlanarInterpTest::BasicGeometricTools() +{ + Node *n1=new Node(1.,1.); + Node *n2=new Node(4.,2.); + EdgeLin *e1=new EdgeLin(n1,n2); + double tmp[2]; + e1->getNormalVector(tmp); + CPPUNIT_ASSERT_DOUBLES_EQUAL(-0.94868329805051377,tmp[1],ADMISSIBLE_ERROR); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.31622776601683794,tmp[0],ADMISSIBLE_ERROR); + e1->decrRef(); + n1->decrRef(); n2->decrRef(); + n1=new Node(1.,1.); + n2=new Node(0.,4.); + e1=new EdgeLin(n1,n2); + double tmp2[2]; + e1->getNormalVector(tmp2); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.,Node::dot(tmp,tmp2),1e-10); + tmp[0]=0.5; tmp[1]=2.5; + CPPUNIT_ASSERT(e1->isNodeLyingOn(tmp)); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.,e1->getDistanceToPoint(tmp),1e-12); + tmp[1]=2.55; CPPUNIT_ASSERT(!e1->isNodeLyingOn(tmp)); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.0158113883008418,e1->getDistanceToPoint(tmp),1e-12); + tmp[0]=0.; tmp[1]=5.; + CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,e1->getDistanceToPoint(tmp),1e-12); + EdgeArcCircle *e=new EdgeArcCircle(4.,3.,0.,5.,-5.,0.); + tmp[0]=-4.; tmp[1]=3.; + CPPUNIT_ASSERT(e->isNodeLyingOn(tmp)); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.,e->getDistanceToPoint(tmp),1e-12); + tmp[1]=3.1; CPPUNIT_ASSERT(!e->isNodeLyingOn(tmp)); + CPPUNIT_ASSERT_DOUBLES_EQUAL(6.0632371551998077e-2,e->getDistanceToPoint(tmp),1e-12); + tmp[0]=-4.; tmp[1]=-3.; + CPPUNIT_ASSERT(!e->isNodeLyingOn(tmp)); + CPPUNIT_ASSERT_DOUBLES_EQUAL(3.1622776601683795,e->getDistanceToPoint(tmp),1e-12); + e->decrRef(); + e1->decrRef(); + n1->decrRef(); n2->decrRef(); +} + +void QuadraticPlanarInterpTest::IntersectionBasics() +{ + //Testing intersection of Bounds. + std::istringstream stream1("2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 2\n3200 3400 4500 4800"); + EdgeLin *e1=new EdgeLin(stream1); + std::istringstream stream2("2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 2\n3200 3400 4500 4800"); + EdgeLin *e2=new EdgeLin(stream2); + Bounds *bound=e1->getBounds().amIIntersectingWith(e2->getBounds()); CPPUNIT_ASSERT(bound); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.32,(*bound)[0],ADMISSIBLE_ERROR); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.45,(*bound)[1],ADMISSIBLE_ERROR); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.34,(*bound)[2],ADMISSIBLE_ERROR); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.48,(*bound)[3],ADMISSIBLE_ERROR); + delete bound; + e2->decrRef(); e1->decrRef(); + // + std::istringstream stream3("2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 2\n3000 7200 6000 3700"); + EdgeLin *e3=new EdgeLin(stream3); + std::istringstream stream4("2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 2\n4800 6600 7200 4200"); + EdgeLin *e4=new EdgeLin(stream4); + bound=e3->getBounds().amIIntersectingWith(e4->getBounds()); CPPUNIT_ASSERT(bound); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.48,(*bound)[0],ADMISSIBLE_ERROR); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.6,(*bound)[1],ADMISSIBLE_ERROR); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.42,(*bound)[2],ADMISSIBLE_ERROR); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.66,(*bound)[3],ADMISSIBLE_ERROR); + delete bound; + e3->decrRef(); e4->decrRef(); +} + +void QuadraticPlanarInterpTest::EdgeLinUnitary() +{ + EdgeLin *e1=new EdgeLin(0.5,0.5,3.7,4.1); + Node *n=new Node(2.1,2.3); + CPPUNIT_ASSERT_DOUBLES_EQUAL(e1->getCharactValue(*n),0.5,1e-8); + n->decrRef(); + n=new Node(3.7,4.1); + CPPUNIT_ASSERT_DOUBLES_EQUAL(e1->getCharactValue(*n),1.,1e-8); + n->decrRef(); + n=new Node(0.5,0.5); + CPPUNIT_ASSERT_DOUBLES_EQUAL(e1->getCharactValue(*n),0.,1e-8); + n->decrRef(); + n=new Node(-1.1,-1.3); + CPPUNIT_ASSERT_DOUBLES_EQUAL(e1->getCharactValue(*n),-0.5,1e-8); + n->decrRef(); + n=new Node(5.3,5.9); + CPPUNIT_ASSERT_DOUBLES_EQUAL(e1->getCharactValue(*n),1.5,1e-8); + n->decrRef(); e1->decrRef(); +} + +/*! + * Here two things are tested. + * 1 ) One the overlapping calculation capability of edge/edge intersector. + * 2 ) Then the capability to handle the case where 2 segs (whatever their type) are overlapped. + * All the configuration of full or part overlapping have been tested. + */ +void QuadraticPlanarInterpTest::IntersectionEdgeOverlapUnitarySegSeg() +{ + ComposedEdge& v1=*(new ComposedEdge); + ComposedEdge& v2=*(new ComposedEdge); + MergePoints v3; + //Testing merge of geometric equals seg2. + Edge *e1=new EdgeLin(0.5,0.5,1.,1.); Edge *e2=new EdgeLin(0.5,0.5,1.,1.); + CPPUNIT_ASSERT(e1->intersectWith(e2,v3,v1,v2)); + CPPUNIT_ASSERT_EQUAL(2,(int)v3.getNumberOfAssociations()); + CPPUNIT_ASSERT_EQUAL(1,(int)v1.size()); CPPUNIT_ASSERT_EQUAL(1,(int)v2.size()); + CPPUNIT_ASSERT(v1[0]->intresincEqCoarse(e1) && v1[0]->getDirection()); CPPUNIT_ASSERT(v2[0]->intresincEqCoarse(e1) && v2[0]->getDirection()); + v1.clear(); v2.clear(); v3.clear(); + // - testing by adding some noise + e1->decrRef(); e1=new EdgeLin(0.5+5.e-15,0.5-5.e-15,1.,1.+7.e-15); + CPPUNIT_ASSERT(e1->intersectWith(e2,v3,v1,v2)); + CPPUNIT_ASSERT_EQUAL(2,(int)v3.getNumberOfAssociations()); + CPPUNIT_ASSERT_EQUAL(1,(int)v1.size()); CPPUNIT_ASSERT_EQUAL(1,(int)v2.size()); + CPPUNIT_ASSERT(v1[0]->intresincEqCoarse(e1) && v1[0]->getDirection()); CPPUNIT_ASSERT(v2[0]->intresincEqCoarse(e1) && v2[0]->getDirection()); + e2->decrRef(); e1->decrRef(); + v1.clear(); v2.clear(); v3.clear(); + //Testing merge of geometric equals seg2 but now with opposite direction + e1=new EdgeLin(0.5,0.5,0.7,0.7); e2=new EdgeLin(0.7+6.e-15,0.7-2.e-15,0.5+3.e-15,0.5-4.e-15); + CPPUNIT_ASSERT(e1->intersectWith(e2,v3,v1,v2)); + CPPUNIT_ASSERT_EQUAL(2,(int)v3.getNumberOfAssociations()); + CPPUNIT_ASSERT_EQUAL(1,(int)v1.size()); CPPUNIT_ASSERT_EQUAL(1,(int)v2.size()); + CPPUNIT_ASSERT(v1[0]->intresincEqCoarse(e1) && v1[0]->getDirection()); CPPUNIT_ASSERT(v2[0]->intresincEqCoarse(e1) && !v2[0]->getDirection());//compared 8 lines above !v2[0]->getDirection() + e2->decrRef(); e1->decrRef(); + v1.clear(); v2.clear(); v3.clear(); + //Test 0 + //Test 1 - OUT_AFTER - OUT_AFTER | same dir. - 0° + e1=new EdgeLin(0.,0.,1.,0.); e2=new EdgeLin(1.5,0.,2.,0.); + CPPUNIT_ASSERT(!e1->intersectWith(e2,v3,v1,v2)); + CPPUNIT_ASSERT_EQUAL(0,(int)v3.getNumberOfAssociations()); + CPPUNIT_ASSERT_EQUAL(0,(int)v1.size()); + CPPUNIT_ASSERT_EQUAL(0,(int)v2.size()); + e2->decrRef(); e1->decrRef(); + v1.clear(); v2.clear(); v3.clear(); + //Test 2 - INSIDE - OUT_AFTER | same dir. - 0° + e1=new EdgeLin(0.,0.,1.,0.); e2=new EdgeLin(0.5,0.,1.5,0.); + CPPUNIT_ASSERT(e1->intersectWith(e2,v3,v1,v2)); + CPPUNIT_ASSERT_EQUAL(0,(int)v3.getNumberOfAssociations()); + CPPUNIT_ASSERT_EQUAL(2,(int)v1.size()); + CPPUNIT_ASSERT_EQUAL(2,(int)v2.size()); + CPPUNIT_ASSERT(v1[1]->intresicEqualDirSensitive(v2[0])); + CPPUNIT_ASSERT(v1[0]->getEndNode()==v1[1]->getStartNode()); CPPUNIT_ASSERT(e1->getStartNode()==v1[0]->getStartNode()); CPPUNIT_ASSERT(e1->getEndNode()==v1[1]->getEndNode()); + CPPUNIT_ASSERT(v2[0]->getEndNode()==v2[1]->getStartNode()); CPPUNIT_ASSERT(e2->getStartNode()==v2[0]->getStartNode()); CPPUNIT_ASSERT(e2->getEndNode()==v2[1]->getEndNode()); + CPPUNIT_ASSERT(e1->getStartNode()==v1.front()->getStartNode() && e1->getEndNode()==v1.back()->getEndNode()); + CPPUNIT_ASSERT(e2->getStartNode()==v2.front()->getStartNode() && e2->getEndNode()==v2.back()->getEndNode()); + e2->decrRef(); e1->decrRef(); + v1.clear(); v2.clear(); v3.clear(); + //Test 2 - INSIDE - OUT_AFTER | same dir. - 90° + e1=new EdgeLin(0.,0.,0.,1.); e2=new EdgeLin(0.,0.5,0.,1.5); + CPPUNIT_ASSERT(e1->intersectWith(e2,v3,v1,v2)); + CPPUNIT_ASSERT_EQUAL(0,(int)v3.getNumberOfAssociations()); + CPPUNIT_ASSERT_EQUAL(2,(int)v1.size()); + CPPUNIT_ASSERT_EQUAL(2,(int)v2.size()); + CPPUNIT_ASSERT(v1[1]->intresicEqualDirSensitive(v2[0])); + CPPUNIT_ASSERT(v1[0]->getEndNode()==v1[1]->getStartNode()); CPPUNIT_ASSERT(e1->getStartNode()==v1[0]->getStartNode()); CPPUNIT_ASSERT(e1->getEndNode()==v1[1]->getEndNode()); + CPPUNIT_ASSERT(v2[0]->getEndNode()==v2[1]->getStartNode()); CPPUNIT_ASSERT(e2->getStartNode()==v2[0]->getStartNode()); CPPUNIT_ASSERT(e2->getEndNode()==v2[1]->getEndNode()); + CPPUNIT_ASSERT(e1->getStartNode()==v1.front()->getStartNode() && e1->getEndNode()==v1.back()->getEndNode()); + CPPUNIT_ASSERT(e2->getStartNode()==v2.front()->getStartNode() && e2->getEndNode()==v2.back()->getEndNode()); + e2->decrRef(); e1->decrRef(); + v1.clear(); v2.clear(); v3.clear(); + //Test 2 - INSIDE - OUT_AFTER | same dir. - 45° + e1=new EdgeLin(0.,0.,1.,1.); e2=new EdgeLin(0.5,0.5,1.5,1.5); + CPPUNIT_ASSERT(e1->intersectWith(e2,v3,v1,v2)); + CPPUNIT_ASSERT_EQUAL(0,(int)v3.getNumberOfAssociations()); + CPPUNIT_ASSERT_EQUAL(2,(int)v1.size()); + CPPUNIT_ASSERT_EQUAL(2,(int)v2.size()); + CPPUNIT_ASSERT(v1[1]->intresicEqualDirSensitive(v2[0])); + CPPUNIT_ASSERT(v1[0]->getEndNode()==v1[1]->getStartNode()); CPPUNIT_ASSERT(e1->getStartNode()==v1[0]->getStartNode()); CPPUNIT_ASSERT(e1->getEndNode()==v1[1]->getEndNode()); + CPPUNIT_ASSERT(v2[0]->getEndNode()==v2[1]->getStartNode()); CPPUNIT_ASSERT(e2->getStartNode()==v2[0]->getStartNode()); CPPUNIT_ASSERT(e2->getEndNode()==v2[1]->getEndNode()); + e2->decrRef(); e1->decrRef(); + v1.clear(); v2.clear(); v3.clear(); + //Test 2 - INSIDE - OUT_AFTER | opp. dir. - 45° + e1=new EdgeLin(0.,0.,1.,1.); e2=new EdgeLin(1.5,1.5,0.5,0.5); + CPPUNIT_ASSERT(e1->intersectWith(e2,v3,v1,v2)); + CPPUNIT_ASSERT_EQUAL(0,(int)v3.getNumberOfAssociations()); + CPPUNIT_ASSERT_EQUAL(2,(int)v1.size()); + CPPUNIT_ASSERT_EQUAL(2,(int)v2.size()); + CPPUNIT_ASSERT(!v1[1]->intresicEqualDirSensitive(v2[1]) && v1[1]->intresicEqual(v2[1])); + CPPUNIT_ASSERT(v1[0]->getEndNode()==v1[1]->getStartNode()); CPPUNIT_ASSERT(e1->getStartNode()==v1[0]->getStartNode()); CPPUNIT_ASSERT(e1->getEndNode()==v1[1]->getEndNode()); + CPPUNIT_ASSERT(v2[0]->getEndNode()==v2[1]->getStartNode()); CPPUNIT_ASSERT(e2->getStartNode()==v2[0]->getStartNode()); CPPUNIT_ASSERT(e2->getEndNode()==v2[1]->getEndNode()); + CPPUNIT_ASSERT(e1->getStartNode()==v1.front()->getStartNode() && e1->getEndNode()==v1.back()->getEndNode()); + CPPUNIT_ASSERT(e2->getStartNode()==v2.front()->getStartNode() && e2->getEndNode()==v2.back()->getEndNode()); + e2->decrRef(); e1->decrRef(); + v1.clear(); v2.clear(); v3.clear(); + //Test 3 - INSIDE - INSIDE | same dir. - 0° + e1=new EdgeLin(0.,0.,1.,0.); e2=new EdgeLin(0.25,0.,0.75,0.); + CPPUNIT_ASSERT(e1->intersectWith(e2,v3,v1,v2)); + CPPUNIT_ASSERT_EQUAL(0,(int)v3.getNumberOfAssociations()); + CPPUNIT_ASSERT_EQUAL(3,(int)v1.size()); + CPPUNIT_ASSERT_EQUAL(1,(int)v2.size()); + CPPUNIT_ASSERT(v1[1]->intresincEqCoarse(e2) && v1[1]->getDirection()); + CPPUNIT_ASSERT(v1[0]->getEndNode()==v1[1]->getStartNode()); CPPUNIT_ASSERT(v1[1]->getEndNode()==v1[2]->getStartNode()); + CPPUNIT_ASSERT(v1[0]->getStartNode()== e1->getStartNode()); CPPUNIT_ASSERT(v1[2]->getEndNode()== e1->getEndNode()); + CPPUNIT_ASSERT(v1[0]->getEndNode()==e2->getStartNode()); CPPUNIT_ASSERT(v1[1]->getEndNode()==e2->getEndNode()); + CPPUNIT_ASSERT(e1->getStartNode()==v1.front()->getStartNode() && e1->getEndNode()==v1.back()->getEndNode()); + CPPUNIT_ASSERT(e2->getStartNode()==v2.front()->getStartNode() && e2->getEndNode()==v2.back()->getEndNode()); + e2->decrRef(); e1->decrRef(); + v1.clear(); v2.clear(); v3.clear(); + //Test 3 - INSIDE - INSIDE | same dir. - 90° + e1=new EdgeLin(0.,0.,0.,1.); e2=new EdgeLin(0.,0.25,0.,0.75); + CPPUNIT_ASSERT(e1->intersectWith(e2,v3,v1,v2)); + CPPUNIT_ASSERT_EQUAL(0,(int)v3.getNumberOfAssociations()); + CPPUNIT_ASSERT_EQUAL(3,(int)v1.size()); + CPPUNIT_ASSERT_EQUAL(1,(int)v2.size()); + CPPUNIT_ASSERT(v1[1]->intresincEqCoarse(e2) && v1[1]->getDirection()); + CPPUNIT_ASSERT(v1[0]->getEndNode()==v1[1]->getStartNode()); CPPUNIT_ASSERT(v1[1]->getEndNode()==v1[2]->getStartNode()); + CPPUNIT_ASSERT(v1[0]->getStartNode()== e1->getStartNode()); CPPUNIT_ASSERT(v1[2]->getEndNode()== e1->getEndNode()); + CPPUNIT_ASSERT(v1[0]->getEndNode()==e2->getStartNode()); CPPUNIT_ASSERT(v1[1]->getEndNode()==e2->getEndNode()); + CPPUNIT_ASSERT(e1->getStartNode()==v1.front()->getStartNode() && e1->getEndNode()==v1.back()->getEndNode()); + CPPUNIT_ASSERT(e2->getStartNode()==v2.front()->getStartNode() && e2->getEndNode()==v2.back()->getEndNode()); + e2->decrRef(); e1->decrRef(); + v1.clear(); v2.clear(); v3.clear(); + //Test 3 - INSIDE - INSIDE | same dir. - 45° + e1=new EdgeLin(0.,0.,1.,1.); e2=new EdgeLin(0.25,0.25,0.75,0.75); + CPPUNIT_ASSERT(e1->intersectWith(e2,v3,v1,v2)); + CPPUNIT_ASSERT_EQUAL(0,(int)v3.getNumberOfAssociations()); + CPPUNIT_ASSERT_EQUAL(3,(int)v1.size()); + CPPUNIT_ASSERT_EQUAL(1,(int)v2.size()); + CPPUNIT_ASSERT(v1[1]->intresincEqCoarse(e2) && v1[1]->getDirection()); + CPPUNIT_ASSERT(v1[0]->getEndNode()==v1[1]->getStartNode()); CPPUNIT_ASSERT(v1[1]->getEndNode()==v1[2]->getStartNode()); + CPPUNIT_ASSERT(v1[0]->getStartNode()== e1->getStartNode()); CPPUNIT_ASSERT(v1[2]->getEndNode()== e1->getEndNode()); + CPPUNIT_ASSERT(v1[0]->getEndNode()==e2->getStartNode()); CPPUNIT_ASSERT(v1[1]->getEndNode()==e2->getEndNode()); + CPPUNIT_ASSERT(e1->getStartNode()==v1.front()->getStartNode() && e1->getEndNode()==v1.back()->getEndNode()); + CPPUNIT_ASSERT(e2->getStartNode()==v2.front()->getStartNode() && e2->getEndNode()==v2.back()->getEndNode()); + e2->decrRef(); e1->decrRef(); + v1.clear(); v2.clear(); v3.clear(); + //Test 3 - INSIDE - INSIDE | opp dir. - 45° + e1=new EdgeLin(0.,0.,1.,1.); e2=new EdgeLin(0.75,0.75,0.25,0.25); + CPPUNIT_ASSERT(e1->intersectWith(e2,v3,v1,v2)); + CPPUNIT_ASSERT_EQUAL(0,(int)v3.getNumberOfAssociations()); + CPPUNIT_ASSERT_EQUAL(3,(int)v1.size()); + CPPUNIT_ASSERT_EQUAL(1,(int)v2.size()); + CPPUNIT_ASSERT(v1[1]->intresincEqCoarse(e2) && !v1[1]->getDirection()); + CPPUNIT_ASSERT(v1[0]->getEndNode()==v1[1]->getStartNode()); CPPUNIT_ASSERT(v1[1]->getEndNode()==v1[2]->getStartNode()); + CPPUNIT_ASSERT(v1[0]->getStartNode()== e1->getStartNode()); CPPUNIT_ASSERT(v1[2]->getEndNode()== e1->getEndNode()); + CPPUNIT_ASSERT(v1[0]->getEndNode()==e2->getEndNode()); CPPUNIT_ASSERT(v1[1]->getEndNode()==e2->getStartNode()); + CPPUNIT_ASSERT(e1->getStartNode()==v1.front()->getStartNode() && e1->getEndNode()==v1.back()->getEndNode()); + CPPUNIT_ASSERT(e2->getStartNode()==v2.front()->getStartNode() && e2->getEndNode()==v2.back()->getEndNode()); + e2->decrRef(); e1->decrRef(); + v1.clear(); v2.clear(); v3.clear(); + //Test 3bis - INSIDE - INSIDE - Bis | opp dir. + double center[2]={0.,0.}; + double radius=1.; + e1=buildArcOfCircle(center,radius,-M_PI,0); e2=buildArcOfCircle(center,radius,-2*M_PI/3.+2*M_PI,-M_PI/3.); + CPPUNIT_ASSERT_DOUBLES_EQUAL(M_PI,e1->getCurveLength(),1e-12); CPPUNIT_ASSERT_DOUBLES_EQUAL(5.*M_PI/3.,e2->getCurveLength(),1e-12);// To check that in the previous line +2.M_PI has done its job. + CPPUNIT_ASSERT(e1->intersectWith(e2,v3,v1,v2)); + CPPUNIT_ASSERT_EQUAL(0,(int)v3.getNumberOfAssociations()); + CPPUNIT_ASSERT_EQUAL(3,(int)v1.size()); + CPPUNIT_ASSERT_EQUAL(3,(int)v2.size()); + CPPUNIT_ASSERT(v1[0]->intresincEqCoarse(v2[0]->getPtr())); CPPUNIT_ASSERT(v1[0]->getDirection()); CPPUNIT_ASSERT(!v2[0]->getDirection()); + CPPUNIT_ASSERT(v1[2]->intresincEqCoarse(v2[2]->getPtr())); CPPUNIT_ASSERT(v1[2]->getDirection()); CPPUNIT_ASSERT(!v2[2]->getDirection()); + CPPUNIT_ASSERT_DOUBLES_EQUAL(M_PI,v2[1]->getCurveLength(),1.e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(M_PI/3.,v1[1]->getCurveLength(),1.e-12); + CPPUNIT_ASSERT(v2[1]->getStartNode()==e1->getStartNode()); + CPPUNIT_ASSERT(v2[1]->getEndNode()==e1->getEndNode()); + CPPUNIT_ASSERT(v1[0]->getStartNode()==e1->getStartNode()); + CPPUNIT_ASSERT(v1[0]->getEndNode()==e2->getStartNode()); + CPPUNIT_ASSERT(v1[1]->getStartNode()==e2->getStartNode()); + CPPUNIT_ASSERT(v1[1]->getEndNode()==e2->getEndNode()); + e2->decrRef(); e1->decrRef(); + v1.clear(); v2.clear(); v3.clear(); + //Test 3bis - INSIDE - INSIDE - Bis | same dir. + e1=buildArcOfCircle(center,radius,-M_PI,0); e2=buildArcOfCircle(center,radius,-M_PI/3.,-2*M_PI/3.+2*M_PI); + CPPUNIT_ASSERT_DOUBLES_EQUAL(M_PI,e1->getCurveLength(),1e-12); CPPUNIT_ASSERT_DOUBLES_EQUAL(5.*M_PI/3.,e2->getCurveLength(),1e-12);// To check that in the previous line +2.M_PI has done its job. + CPPUNIT_ASSERT(e1->intersectWith(e2,v3,v1,v2)); + CPPUNIT_ASSERT_EQUAL(0,(int)v3.getNumberOfAssociations()); + CPPUNIT_ASSERT_EQUAL(3,(int)v1.size()); + CPPUNIT_ASSERT_EQUAL(3,(int)v2.size()); + CPPUNIT_ASSERT(v1[0]->intresincEqCoarse(v2[2]->getPtr())); CPPUNIT_ASSERT(v1[0]->getDirection()); CPPUNIT_ASSERT(v2[2]->getDirection()); + CPPUNIT_ASSERT(v1[2]->intresincEqCoarse(v2[0]->getPtr())); CPPUNIT_ASSERT(v1[2]->getDirection()); CPPUNIT_ASSERT(v2[0]->getDirection()); + CPPUNIT_ASSERT_DOUBLES_EQUAL(M_PI,v2[1]->getCurveLength(),1.e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(M_PI/3.,v1[1]->getCurveLength(),1.e-12); + CPPUNIT_ASSERT(v2[1]->getStartNode()==e1->getEndNode()); + CPPUNIT_ASSERT(v2[1]->getEndNode()==e1->getStartNode()); + CPPUNIT_ASSERT(v1[0]->getStartNode()==e1->getStartNode()); + CPPUNIT_ASSERT(v1[0]->getEndNode()==e2->getEndNode()); + CPPUNIT_ASSERT(v1[1]->getStartNode()==e2->getEndNode()); + CPPUNIT_ASSERT(v1[1]->getEndNode()==e2->getStartNode()); + e2->decrRef(); e1->decrRef(); + v1.clear(); v2.clear(); v3.clear(); + //Test 3bis - INSIDE - INSIDE - Bis | opp dir. | e1<->e2 to test symetry + e1=buildArcOfCircle(center,radius,-M_PI,0); e2=buildArcOfCircle(center,radius,-2*M_PI/3.+2*M_PI,-M_PI/3.); + CPPUNIT_ASSERT_DOUBLES_EQUAL(M_PI,e1->getCurveLength(),1e-12); CPPUNIT_ASSERT_DOUBLES_EQUAL(5.*M_PI/3.,e2->getCurveLength(),1e-12);// To check that in the previous line +2.M_PI has done its job. + CPPUNIT_ASSERT(e2->intersectWith(e1,v3,v2,v1)); + CPPUNIT_ASSERT_EQUAL(0,(int)v3.getNumberOfAssociations()); + CPPUNIT_ASSERT_EQUAL(3,(int)v1.size()); + CPPUNIT_ASSERT_EQUAL(3,(int)v2.size()); + CPPUNIT_ASSERT(v1[0]->intresincEqCoarse(v2[0]->getPtr())); CPPUNIT_ASSERT(!v1[0]->getDirection()); CPPUNIT_ASSERT(v2[0]->getDirection()); + CPPUNIT_ASSERT(v1[2]->intresincEqCoarse(v2[2]->getPtr())); CPPUNIT_ASSERT(!v1[2]->getDirection()); CPPUNIT_ASSERT(v2[2]->getDirection()); + CPPUNIT_ASSERT_DOUBLES_EQUAL(M_PI,v2[1]->getCurveLength(),1.e-5); // << not maximal precision because node switching + CPPUNIT_ASSERT_DOUBLES_EQUAL(M_PI/3.,v1[1]->getCurveLength(),1.e-12); + CPPUNIT_ASSERT(v2[1]->getStartNode()==e1->getStartNode()); + CPPUNIT_ASSERT(v2[1]->getEndNode()==e1->getEndNode()); + CPPUNIT_ASSERT(v1[0]->getStartNode()==e1->getStartNode()); + CPPUNIT_ASSERT(v1[0]->getEndNode()==e2->getStartNode()); + CPPUNIT_ASSERT(v1[1]->getStartNode()==e2->getStartNode()); + CPPUNIT_ASSERT(v1[1]->getEndNode()==e2->getEndNode()); + e2->decrRef(); e1->decrRef(); + v1.clear(); v2.clear(); v3.clear(); + //Test 3bis - INSIDE - INSIDE - Bis | same dir. | e1<->e2 to test symetry + e1=buildArcOfCircle(center,radius,-M_PI,0); e2=buildArcOfCircle(center,radius,-M_PI/3.,-2*M_PI/3.+2*M_PI); + CPPUNIT_ASSERT_DOUBLES_EQUAL(M_PI,e1->getCurveLength(),1e-12); CPPUNIT_ASSERT_DOUBLES_EQUAL(5.*M_PI/3.,e2->getCurveLength(),1e-12);// To check that in the previous line +2.M_PI has done its job. + CPPUNIT_ASSERT(e2->intersectWith(e1,v3,v2,v1)); + CPPUNIT_ASSERT_EQUAL(0,(int)v3.getNumberOfAssociations()); + CPPUNIT_ASSERT_EQUAL(3,(int)v1.size()); + CPPUNIT_ASSERT_EQUAL(3,(int)v2.size()); + CPPUNIT_ASSERT(v1[0]->intresincEqCoarse(v2[2]->getPtr())); CPPUNIT_ASSERT(v1[0]->getDirection()); CPPUNIT_ASSERT(v2[2]->getDirection()); + CPPUNIT_ASSERT(v1[2]->intresincEqCoarse(v2[0]->getPtr())); CPPUNIT_ASSERT(v1[2]->getDirection()); CPPUNIT_ASSERT(v2[0]->getDirection()); + CPPUNIT_ASSERT_DOUBLES_EQUAL(M_PI,v2[1]->getCurveLength(),1.e-5); // << not maximal precision because node switching + CPPUNIT_ASSERT_DOUBLES_EQUAL(M_PI/3.,v1[1]->getCurveLength(),1.e-12); + CPPUNIT_ASSERT(v2[1]->getStartNode()==e1->getEndNode()); + CPPUNIT_ASSERT(v2[1]->getEndNode()==e1->getStartNode()); + CPPUNIT_ASSERT(v1[0]->getStartNode()==e1->getStartNode()); + CPPUNIT_ASSERT(v1[0]->getEndNode()==e2->getEndNode()); + CPPUNIT_ASSERT(v1[1]->getStartNode()==e2->getEndNode()); + CPPUNIT_ASSERT(v1[1]->getEndNode()==e2->getStartNode()); + e2->decrRef(); e1->decrRef(); + v1.clear(); v2.clear(); v3.clear(); + //Test 4 - OUT_BEFORE - OUT_BEFORE | same dir. - 0 ° + e1=new EdgeLin(0.,0.,1.,0.); e2=new EdgeLin(-1.,0.,-0.5,0.); + CPPUNIT_ASSERT(!e1->intersectWith(e2,v3,v1,v2)); + CPPUNIT_ASSERT_EQUAL(0,(int)v3.getNumberOfAssociations()); + CPPUNIT_ASSERT_EQUAL(0,(int)v1.size()); + CPPUNIT_ASSERT_EQUAL(0,(int)v2.size()); + e2->decrRef(); e1->decrRef(); + v1.clear(); v2.clear(); v3.clear(); + //Test 5 - OUT_BEFORE - INSIDE | same dir. - 0° + e1=new EdgeLin(0.,0.,1.,0.); e2=new EdgeLin(-0.5,0.,0.5,0.); + CPPUNIT_ASSERT(e1->intersectWith(e2,v3,v1,v2)); + CPPUNIT_ASSERT_EQUAL(0,(int)v3.getNumberOfAssociations()); + CPPUNIT_ASSERT_EQUAL(2,(int)v1.size()); + CPPUNIT_ASSERT_EQUAL(2,(int)v2.size()); + CPPUNIT_ASSERT(v1[0]->intresicEqualDirSensitive(v2[1])); + CPPUNIT_ASSERT(v1[0]->getEndNode()==v1[1]->getStartNode()); CPPUNIT_ASSERT(v2[0]->getEndNode()==v2[1]->getStartNode()); + CPPUNIT_ASSERT(e1->getStartNode()==v1.front()->getStartNode() && e1->getEndNode()==v1.back()->getEndNode()); + CPPUNIT_ASSERT(e2->getStartNode()==v2.front()->getStartNode() && e2->getEndNode()==v2.back()->getEndNode()); + e2->decrRef(); e1->decrRef(); + v1.clear(); v2.clear(); v3.clear(); + //Test 5 - OUT_BEFORE - INSIDE | same dir. - 90° + e1=new EdgeLin(0.,0.,0.,1.); e2=new EdgeLin(0,-0.5,0.,0.5); + CPPUNIT_ASSERT(e1->intersectWith(e2,v3,v1,v2)); + CPPUNIT_ASSERT_EQUAL(0,(int)v3.getNumberOfAssociations()); + CPPUNIT_ASSERT_EQUAL(2,(int)v1.size()); + CPPUNIT_ASSERT_EQUAL(2,(int)v2.size()); + CPPUNIT_ASSERT(v1[0]->intresicEqualDirSensitive(v2[1])); + CPPUNIT_ASSERT(v1[0]->getEndNode()==v1[1]->getStartNode()); CPPUNIT_ASSERT(v2[0]->getEndNode()==v2[1]->getStartNode()); + CPPUNIT_ASSERT(e1->getStartNode()==v1.front()->getStartNode() && e1->getEndNode()==v1.back()->getEndNode()); + CPPUNIT_ASSERT(e2->getStartNode()==v2.front()->getStartNode() && e2->getEndNode()==v2.back()->getEndNode()); + e2->decrRef(); e1->decrRef(); + v1.clear(); v2.clear(); v3.clear(); + //Test 5 - OUT_BEFORE - INSIDE | same dir. - 45° + e1=new EdgeLin(0.,0.,1.,1.); e2=new EdgeLin(-0.5,-0.5,0.5,0.5); + CPPUNIT_ASSERT(e1->intersectWith(e2,v3,v1,v2)); + CPPUNIT_ASSERT_EQUAL(0,(int)v3.getNumberOfAssociations()); + CPPUNIT_ASSERT_EQUAL(2,(int)v1.size()); + CPPUNIT_ASSERT_EQUAL(2,(int)v2.size()); + CPPUNIT_ASSERT(v1[0]->intresicEqualDirSensitive(v2[1])); + CPPUNIT_ASSERT(v1[0]->getEndNode()==v1[1]->getStartNode()); CPPUNIT_ASSERT(v2[0]->getEndNode()==v2[1]->getStartNode()); + CPPUNIT_ASSERT(e1->getStartNode()==v1.front()->getStartNode() && e1->getEndNode()==v1.back()->getEndNode()); + CPPUNIT_ASSERT(e2->getStartNode()==v2.front()->getStartNode() && e2->getEndNode()==v2.back()->getEndNode()); + e2->decrRef(); e1->decrRef(); + v1.clear(); v2.clear(); v3.clear(); + //Test 5 - OUT_BEFORE - INSIDE | opp dir. - 45° + e1=new EdgeLin(0.,0.,1.,1.); e2=new EdgeLin(0.5,0.5,-0.5,-0.5); + CPPUNIT_ASSERT(e1->intersectWith(e2,v3,v1,v2)); + CPPUNIT_ASSERT_EQUAL(0,(int)v3.getNumberOfAssociations()); + CPPUNIT_ASSERT_EQUAL(2,(int)v1.size()); + CPPUNIT_ASSERT_EQUAL(2,(int)v2.size()); + CPPUNIT_ASSERT(!v1[0]->intresicEqualDirSensitive(v2[0]) && v1[0]->intresicEqual(v2[0]) ); + CPPUNIT_ASSERT(v1[0]->getEndNode()==v1[1]->getStartNode()); CPPUNIT_ASSERT(v2[0]->getEndNode()==v2[1]->getStartNode()); + CPPUNIT_ASSERT(e1->getStartNode()==v1.front()->getStartNode() && e1->getEndNode()==v1.back()->getEndNode()); + CPPUNIT_ASSERT(e2->getStartNode()==v2.front()->getStartNode() && e2->getEndNode()==v2.back()->getEndNode()); + e2->decrRef(); e1->decrRef(); + v1.clear(); v2.clear(); v3.clear(); + //Test 6 - OUT_BEFORE - OUT_AFTER | same dir. - 0° + e1=new EdgeLin(0.,0.,1.,0.); e2=new EdgeLin(-0.5,0.,1.5,0.); + CPPUNIT_ASSERT(e1->intersectWith(e2,v3,v1,v2)); + CPPUNIT_ASSERT_EQUAL(0,(int)v3.getNumberOfAssociations()); + CPPUNIT_ASSERT_EQUAL(1,(int)v1.size()); + CPPUNIT_ASSERT_EQUAL(3,(int)v2.size()); + CPPUNIT_ASSERT(v1[0]->intresincEqCoarse(e1) && v1[0]->getDirection()); + CPPUNIT_ASSERT(v2[1]->intresincEqCoarse(e1) && v2[1]->getDirection()); + CPPUNIT_ASSERT(v2[0]->getEndNode()==v2[1]->getStartNode() && v2[1]->getEndNode()==v2[2]->getStartNode()); + CPPUNIT_ASSERT(e1->getStartNode()==v1.front()->getStartNode() && e1->getEndNode()==v1.back()->getEndNode()); + CPPUNIT_ASSERT(e2->getStartNode()==v2.front()->getStartNode() && e2->getEndNode()==v2.back()->getEndNode()); + e2->decrRef(); e1->decrRef(); + v1.clear(); v2.clear(); v3.clear(); + //Test 6 - OUT_BEFORE - OUT_AFTER | same dir. - 90° + e1=new EdgeLin(0.,0.,0.,1.); e2=new EdgeLin(0.,-0.5,0.,1.5); + CPPUNIT_ASSERT(e1->intersectWith(e2,v3,v1,v2)); + CPPUNIT_ASSERT_EQUAL(0,(int)v3.getNumberOfAssociations()); + CPPUNIT_ASSERT_EQUAL(1,(int)v1.size()); + CPPUNIT_ASSERT_EQUAL(3,(int)v2.size()); + CPPUNIT_ASSERT(v1[0]->intresincEqCoarse(e1) && v1[0]->getDirection()); + CPPUNIT_ASSERT(v2[1]->intresincEqCoarse(e1) && v2[1]->getDirection()); + CPPUNIT_ASSERT(v2[0]->getEndNode()==v2[1]->getStartNode() && v2[1]->getEndNode()==v2[2]->getStartNode()); + CPPUNIT_ASSERT(e1->getStartNode()==v1.front()->getStartNode() && e1->getEndNode()==v1.back()->getEndNode()); + CPPUNIT_ASSERT(e2->getStartNode()==v2.front()->getStartNode() && e2->getEndNode()==v2.back()->getEndNode()); + e2->decrRef(); e1->decrRef(); + v1.clear(); v2.clear(); v3.clear(); + //Test 6 - OUT_BEFORE - OUT_AFTER | same dir. - 45° + e1=new EdgeLin(0.,0.,1.,1.); e2=new EdgeLin(-0.5,-0.5,1.5,1.5); + CPPUNIT_ASSERT(e1->intersectWith(e2,v3,v1,v2)); + CPPUNIT_ASSERT_EQUAL(0,(int)v3.getNumberOfAssociations()); + CPPUNIT_ASSERT_EQUAL(1,(int)v1.size()); + CPPUNIT_ASSERT_EQUAL(3,(int)v2.size()); + CPPUNIT_ASSERT(v1[0]->intresincEqCoarse(e1) && v1[0]->getDirection()); + CPPUNIT_ASSERT(v2[1]->intresincEqCoarse(e1) && v2[1]->getDirection()); + CPPUNIT_ASSERT(v2[0]->getEndNode()==v2[1]->getStartNode() && v2[1]->getEndNode()==v2[2]->getStartNode()); + CPPUNIT_ASSERT(e1->getStartNode()==v1.front()->getStartNode() && e1->getEndNode()==v1.back()->getEndNode()); + CPPUNIT_ASSERT(e2->getStartNode()==v2.front()->getStartNode() && e2->getEndNode()==v2.back()->getEndNode()); + e2->decrRef(); e1->decrRef(); + v1.clear(); v2.clear(); v3.clear(); + //Test 6 - OUT_BEFORE - OUT_AFTER | opp dir. - 45° + e1=new EdgeLin(0.,0.,1.,1.); e2=new EdgeLin(1.5,1.5,-0.5,-0.5); + CPPUNIT_ASSERT(e1->intersectWith(e2,v3,v1,v2)); + CPPUNIT_ASSERT_EQUAL(0,(int)v3.getNumberOfAssociations()); + CPPUNIT_ASSERT_EQUAL(1,(int)v1.size()); + CPPUNIT_ASSERT_EQUAL(3,(int)v2.size()); + CPPUNIT_ASSERT(v1[0]->intresincEqCoarse(e1) && v1[0]->getDirection()); + CPPUNIT_ASSERT(v2[1]->intresincEqCoarse(e1) && !v2[1]->getDirection()); + CPPUNIT_ASSERT(v2[0]->getEndNode()==v2[1]->getStartNode() && v2[1]->getEndNode()==v2[2]->getStartNode()); + CPPUNIT_ASSERT(e1->getStartNode()==v1.front()->getStartNode() && e1->getEndNode()==v1.back()->getEndNode()); + CPPUNIT_ASSERT(e2->getStartNode()==v2.front()->getStartNode() && e2->getEndNode()==v2.back()->getEndNode()); + e2->decrRef(); e1->decrRef(); + v1.clear(); v2.clear(); v3.clear(); + //Test 7 - END - OUT_AFTER | same dir. - 0° + e1=new EdgeLin(0.,0.,1.,0.); e2=new EdgeLin(1.,0.,1.5,0.); + CPPUNIT_ASSERT(!e1->intersectWith(e2,v3,v1,v2)); + CPPUNIT_ASSERT_EQUAL(1,(int)v3.getNumberOfAssociations()); + CPPUNIT_ASSERT_EQUAL(0,(int)v1.size()); + CPPUNIT_ASSERT_EQUAL(0,(int)v2.size()); + e2->decrRef(); e1->decrRef(); + v1.clear(); v2.clear(); v3.clear(); + //Test 7 - END - OUT_AFTER | opp dir. - 0° + e1=new EdgeLin(0.,0.,1.,0.); e2=new EdgeLin(1.5,0.,1.,0.); + CPPUNIT_ASSERT(!e1->intersectWith(e2,v3,v1,v2)); + CPPUNIT_ASSERT_EQUAL(1,(int)v3.getNumberOfAssociations()); + CPPUNIT_ASSERT_EQUAL(0,(int)v1.size()); + CPPUNIT_ASSERT_EQUAL(0,(int)v2.size()); + CPPUNIT_ASSERT(e1->getEndNode()==e2->getEndNode()); + e2->decrRef(); e1->decrRef(); + v1.clear(); v2.clear(); v3.clear(); + //Test 8 - START - END | same dir. - 0° + e1=new EdgeLin(0.,0.,0.7,0.); e2=new EdgeLin(0.,0.,0.7,0.); + CPPUNIT_ASSERT(e1->intersectWith(e2,v3,v1,v2)); + CPPUNIT_ASSERT_EQUAL(2,(int)v3.getNumberOfAssociations()); + CPPUNIT_ASSERT_EQUAL(1,(int)v1.size()); + CPPUNIT_ASSERT_EQUAL(1,(int)v2.size()); + CPPUNIT_ASSERT(v1[0]->intresincEqCoarse(e1) && v1[0]->getDirection()); CPPUNIT_ASSERT(v2[0]->intresincEqCoarse(e1) && v2[0]->getDirection()); + CPPUNIT_ASSERT(e1->getStartNode()==e2->getStartNode()); CPPUNIT_ASSERT(e1->getEndNode()==e2->getEndNode()); + CPPUNIT_ASSERT(e1->getStartNode()==v1.front()->getStartNode() && e1->getEndNode()==v1.back()->getEndNode()); + CPPUNIT_ASSERT(e2->getStartNode()==v2.front()->getStartNode() && e2->getEndNode()==v2.back()->getEndNode()); + e2->decrRef(); e1->decrRef(); + v1.clear(); v2.clear(); v3.clear(); + //Test 8 - START - END | same dir. - 90° + e1=new EdgeLin(0.,0.,0.,0.7); e2=new EdgeLin(0.,0.,0.,0.7); + CPPUNIT_ASSERT(e1->intersectWith(e2,v3,v1,v2)); + CPPUNIT_ASSERT_EQUAL(2,(int)v3.getNumberOfAssociations()); + CPPUNIT_ASSERT_EQUAL(1,(int)v1.size()); + CPPUNIT_ASSERT_EQUAL(1,(int)v2.size()); + CPPUNIT_ASSERT(v1[0]->intresincEqCoarse(e1) && v1[0]->getDirection()); CPPUNIT_ASSERT(v2[0]->intresincEqCoarse(e1) && v2[0]->getDirection()); + CPPUNIT_ASSERT(e1->getStartNode()==e2->getStartNode()); CPPUNIT_ASSERT(e1->getEndNode()==e2->getEndNode()); + CPPUNIT_ASSERT(e1->getStartNode()==v1.front()->getStartNode() && e1->getEndNode()==v1.back()->getEndNode()); + CPPUNIT_ASSERT(e2->getStartNode()==v2.front()->getStartNode() && e2->getEndNode()==v2.back()->getEndNode()); + e2->decrRef(); e1->decrRef(); + v1.clear(); v2.clear(); v3.clear(); + //Test 8 - START - END | same dir. - 45° + e1=new EdgeLin(0.,0.,0.7,0.7); e2=new EdgeLin(0.,0.,0.7,0.7); + CPPUNIT_ASSERT(e1->intersectWith(e2,v3,v1,v2)); + CPPUNIT_ASSERT_EQUAL(2,(int)v3.getNumberOfAssociations()); + CPPUNIT_ASSERT_EQUAL(1,(int)v1.size()); + CPPUNIT_ASSERT_EQUAL(1,(int)v2.size()); + CPPUNIT_ASSERT(v1[0]->intresincEqCoarse(e1) && v1[0]->getDirection()); CPPUNIT_ASSERT(v2[0]->intresincEqCoarse(e1) && v2[0]->getDirection()); + CPPUNIT_ASSERT(e1->getStartNode()==e2->getStartNode()); CPPUNIT_ASSERT(e1->getEndNode()==e2->getEndNode()); + CPPUNIT_ASSERT(e1->getStartNode()==v1.front()->getStartNode() && e1->getEndNode()==v1.back()->getEndNode()); + CPPUNIT_ASSERT(e2->getStartNode()==v2.front()->getStartNode() && e2->getEndNode()==v2.back()->getEndNode()); + e2->decrRef(); e1->decrRef(); + v1.clear(); v2.clear(); v3.clear(); + //Test 8 - START - END | opp. dir. - 45° + e1=new EdgeLin(0.,0.,0.7,0.7); e2=new EdgeLin(0.7,0.7,0.,0.); + CPPUNIT_ASSERT(e1->intersectWith(e2,v3,v1,v2)); + CPPUNIT_ASSERT_EQUAL(2,(int)v3.getNumberOfAssociations()); + CPPUNIT_ASSERT_EQUAL(1,(int)v1.size()); + CPPUNIT_ASSERT_EQUAL(1,(int)v2.size()); + CPPUNIT_ASSERT(v1[0]->intresincEqCoarse(e1) && v1[0]->getDirection()); CPPUNIT_ASSERT(v2[0]->intresincEqCoarse(e1) && !v2[0]->getDirection()); + CPPUNIT_ASSERT(e1->getStartNode()==e2->getEndNode()); CPPUNIT_ASSERT(e1->getEndNode()==e2->getStartNode()); + CPPUNIT_ASSERT(e1->getStartNode()==v1.front()->getStartNode() && e1->getEndNode()==v1.back()->getEndNode()); + CPPUNIT_ASSERT(e2->getStartNode()==v2.front()->getStartNode() && e2->getEndNode()==v2.back()->getEndNode()); + e2->decrRef(); e1->decrRef(); + v1.clear(); v2.clear(); v3.clear(); + //Test 9 - OUT_BEFORE - START | same dir. + e1=new EdgeLin(0.,0.,1.,0.); e2=new EdgeLin(-0.5,0.,0.,0.); + CPPUNIT_ASSERT(!e1->intersectWith(e2,v3,v1,v2)); + CPPUNIT_ASSERT_EQUAL(1,(int)v3.getNumberOfAssociations()); + CPPUNIT_ASSERT_EQUAL(0,(int)v1.size()); + CPPUNIT_ASSERT_EQUAL(0,(int)v2.size()); + CPPUNIT_ASSERT(e2->getEndNode()==e1->getStartNode()); + e2->decrRef(); e1->decrRef(); + v1.clear(); v2.clear(); v3.clear(); + //Test 10 - START - OUT_AFTER | same dir. - 0° + e1=new EdgeLin(0.,0.,0.7,0.); e2=new EdgeLin(0.,0.,1.,0.); + CPPUNIT_ASSERT(e1->intersectWith(e2,v3,v1,v2)); + CPPUNIT_ASSERT_EQUAL(1,(int)v3.getNumberOfAssociations()); + CPPUNIT_ASSERT_EQUAL(1,(int)v1.size()); + CPPUNIT_ASSERT_EQUAL(2,(int)v2.size()); + CPPUNIT_ASSERT(v1[0]->intresincEqCoarse(e1) && v1[0]->getDirection()); CPPUNIT_ASSERT(v2[0]->intresincEqCoarse(e1) && v2[0]->getDirection()); + CPPUNIT_ASSERT(e1->getStartNode()==v1[0]->getStartNode()); CPPUNIT_ASSERT(e1->getStartNode()==e2->getStartNode()); CPPUNIT_ASSERT(v2[1]->getEndNode()==e2->getEndNode()); + CPPUNIT_ASSERT(v2[0]->getEndNode()==v2[1]->getStartNode()); + CPPUNIT_ASSERT(e1->getStartNode()==v1.front()->getStartNode() && e1->getEndNode()==v1.back()->getEndNode()); + CPPUNIT_ASSERT(e2->getStartNode()==v2.front()->getStartNode() && e2->getEndNode()==v2.back()->getEndNode()); + e2->decrRef(); e1->decrRef(); + v1.clear(); v2.clear(); v3.clear(); + //Test 10 - START - OUT_AFTER | same dir. - 90° + e1=new EdgeLin(0.,0.,0.,0.7); e2=new EdgeLin(0.,0.,0.,1.); + CPPUNIT_ASSERT(e1->intersectWith(e2,v3,v1,v2)); + CPPUNIT_ASSERT_EQUAL(1,(int)v3.getNumberOfAssociations()); + CPPUNIT_ASSERT_EQUAL(1,(int)v1.size()); + CPPUNIT_ASSERT_EQUAL(2,(int)v2.size()); + CPPUNIT_ASSERT(v1[0]->intresincEqCoarse(e1) && v1[0]->getDirection()); CPPUNIT_ASSERT(v2[0]->intresincEqCoarse(e1) && v2[0]->getDirection()); + CPPUNIT_ASSERT(e1->getStartNode()==v1[0]->getStartNode()); CPPUNIT_ASSERT(e1->getStartNode()==e2->getStartNode()); CPPUNIT_ASSERT(v2[1]->getEndNode()==e2->getEndNode()); + CPPUNIT_ASSERT(v2[0]->getEndNode()==v2[1]->getStartNode()); + CPPUNIT_ASSERT(e1->getStartNode()==v1.front()->getStartNode() && e1->getEndNode()==v1.back()->getEndNode()); + CPPUNIT_ASSERT(e2->getStartNode()==v2.front()->getStartNode() && e2->getEndNode()==v2.back()->getEndNode()); + e2->decrRef(); e1->decrRef(); + v1.clear(); v2.clear(); v3.clear(); + //Test 10 - START - OUT_AFTER | same dir. - 45° + e1=new EdgeLin(0.,0.,0.7,0.7); e2=new EdgeLin(0.,0.,1.,1.); + CPPUNIT_ASSERT(e1->intersectWith(e2,v3,v1,v2)); + CPPUNIT_ASSERT_EQUAL(1,(int)v3.getNumberOfAssociations()); + CPPUNIT_ASSERT_EQUAL(1,(int)v1.size()); + CPPUNIT_ASSERT_EQUAL(2,(int)v2.size()); + CPPUNIT_ASSERT(v1[0]->intresincEqCoarse(e1) && v1[0]->getDirection()); CPPUNIT_ASSERT(v2[0]->intresincEqCoarse(e1) && v2[0]->getDirection()); + CPPUNIT_ASSERT(e1->getStartNode()==v1[0]->getStartNode()); CPPUNIT_ASSERT(e1->getStartNode()==e2->getStartNode()); CPPUNIT_ASSERT(v2[1]->getEndNode()==e2->getEndNode()); + CPPUNIT_ASSERT(v2[0]->getEndNode()==v2[1]->getStartNode()); + CPPUNIT_ASSERT(e1->getStartNode()==v1.front()->getStartNode() && e1->getEndNode()==v1.back()->getEndNode()); + CPPUNIT_ASSERT(e2->getStartNode()==v2.front()->getStartNode() && e2->getEndNode()==v2.back()->getEndNode()); + e2->decrRef(); e1->decrRef(); + v1.clear(); v2.clear(); v3.clear(); + //Test 10 - START - OUT_AFTER | opp dir. - 45° + e1=new EdgeLin(0.,0.,0.7,0.7); e2=new EdgeLin(1.,1.,0.,0.); + CPPUNIT_ASSERT(e1->intersectWith(e2,v3,v1,v2)); + CPPUNIT_ASSERT_EQUAL(1,(int)v3.getNumberOfAssociations()); + CPPUNIT_ASSERT_EQUAL(1,(int)v1.size()); + CPPUNIT_ASSERT_EQUAL(2,(int)v2.size()); + CPPUNIT_ASSERT(v1[0]->intresincEqCoarse(e1) && v1[0]->getDirection()); CPPUNIT_ASSERT(v2[1]->intresincEqCoarse(e1) && !v2[1]->getDirection()); + CPPUNIT_ASSERT(e1->getStartNode()==v1[0]->getStartNode()); CPPUNIT_ASSERT(e1->getStartNode()==e2->getEndNode()); CPPUNIT_ASSERT(v2[1]->getEndNode()==e2->getEndNode()); + CPPUNIT_ASSERT(v2[0]->getEndNode()==v2[1]->getStartNode()); + CPPUNIT_ASSERT(e1->getStartNode()==v1.front()->getStartNode() && e1->getEndNode()==v1.back()->getEndNode()); + CPPUNIT_ASSERT(e2->getStartNode()==v2.front()->getStartNode() && e2->getEndNode()==v2.back()->getEndNode()); + e2->decrRef(); e1->decrRef(); + v1.clear(); v2.clear(); v3.clear(); + //Test 11 - INSIDE - END | same dir. - 0° + e1=new EdgeLin(0.,0.,1.,0.); e2=new EdgeLin(0.7,0.,1.,0.); + CPPUNIT_ASSERT(e1->intersectWith(e2,v3,v1,v2)); + CPPUNIT_ASSERT_EQUAL(1,(int)v3.getNumberOfAssociations()); + CPPUNIT_ASSERT_EQUAL(2,(int)v1.size()); + CPPUNIT_ASSERT_EQUAL(1,(int)v2.size()); + CPPUNIT_ASSERT(v1[1]->intresincEqCoarse(e2) && v1[1]->getDirection()); CPPUNIT_ASSERT(v2[0]->intresincEqCoarse(e2) && v2[0]->getDirection()); + CPPUNIT_ASSERT(e1->getStartNode()==v1[0]->getStartNode()); CPPUNIT_ASSERT(e1->getEndNode()==v1[1]->getEndNode()); CPPUNIT_ASSERT(e1->getEndNode()==e2->getEndNode()); + CPPUNIT_ASSERT(v1[0]->getEndNode()==v1[1]->getStartNode()); + CPPUNIT_ASSERT(e1->getStartNode()==v1.front()->getStartNode() && e1->getEndNode()==v1.back()->getEndNode()); + CPPUNIT_ASSERT(e2->getStartNode()==v2.front()->getStartNode() && e2->getEndNode()==v2.back()->getEndNode()); + e2->decrRef(); e1->decrRef(); + v1.clear(); v2.clear(); v3.clear(); + //Test 11 - INSIDE - END | same dir. - 90° + e1=new EdgeLin(0.,0.,0.,1.); e2=new EdgeLin(0.,0.7,0.,1.); + CPPUNIT_ASSERT(e1->intersectWith(e2,v3,v1,v2)); + CPPUNIT_ASSERT_EQUAL(1,(int)v3.getNumberOfAssociations()); + CPPUNIT_ASSERT_EQUAL(2,(int)v1.size()); + CPPUNIT_ASSERT_EQUAL(1,(int)v2.size()); + CPPUNIT_ASSERT(v1[1]->intresincEqCoarse(e2) && v1[1]->getDirection()); CPPUNIT_ASSERT(v2[0]->intresincEqCoarse(e2) && v2[0]->getDirection()); + CPPUNIT_ASSERT(e1->getStartNode()==v1[0]->getStartNode()); CPPUNIT_ASSERT(e1->getEndNode()==v1[1]->getEndNode()); CPPUNIT_ASSERT(e1->getEndNode()==e2->getEndNode()); + CPPUNIT_ASSERT(v1[0]->getEndNode()==v1[1]->getStartNode()); + CPPUNIT_ASSERT(e1->getStartNode()==v1.front()->getStartNode() && e1->getEndNode()==v1.back()->getEndNode()); + CPPUNIT_ASSERT(e2->getStartNode()==v2.front()->getStartNode() && e2->getEndNode()==v2.back()->getEndNode()); + e2->decrRef(); e1->decrRef(); + v1.clear(); v2.clear(); v3.clear(); + //Test 11 - INSIDE - END | same dir. - 45° + e1=new EdgeLin(0.,0.,1.,1.); e2=new EdgeLin(0.7,0.7,1.,1.); + CPPUNIT_ASSERT(e1->intersectWith(e2,v3,v1,v2)); + CPPUNIT_ASSERT_EQUAL(1,(int)v3.getNumberOfAssociations()); + CPPUNIT_ASSERT_EQUAL(2,(int)v1.size()); + CPPUNIT_ASSERT_EQUAL(1,(int)v2.size()); + CPPUNIT_ASSERT(v1[1]->intresincEqCoarse(e2) && v1[1]->getDirection()); CPPUNIT_ASSERT(v2[0]->intresincEqCoarse(e2) && v2[0]->getDirection()); + CPPUNIT_ASSERT(e1->getStartNode()==v1[0]->getStartNode()); CPPUNIT_ASSERT(e1->getEndNode()==v1[1]->getEndNode()); CPPUNIT_ASSERT(e1->getEndNode()==e2->getEndNode()); + CPPUNIT_ASSERT(v1[0]->getEndNode()==v1[1]->getStartNode()); + CPPUNIT_ASSERT(e1->getStartNode()==v1.front()->getStartNode() && e1->getEndNode()==v1.back()->getEndNode()); + CPPUNIT_ASSERT(e2->getStartNode()==v2.front()->getStartNode() && e2->getEndNode()==v2.back()->getEndNode()); + e2->decrRef(); e1->decrRef(); + v1.clear(); v2.clear(); v3.clear(); + //Test 11 - INSIDE - END | opp dir. - 45° + e1=new EdgeLin(0.,0.,1.,1.); e2=new EdgeLin(1.,1.,0.7,0.7); + CPPUNIT_ASSERT(e1->intersectWith(e2,v3,v1,v2)); + CPPUNIT_ASSERT_EQUAL(1,(int)v3.getNumberOfAssociations()); + CPPUNIT_ASSERT_EQUAL(2,(int)v1.size()); + CPPUNIT_ASSERT_EQUAL(1,(int)v2.size()); + CPPUNIT_ASSERT(e1->getStartNode()==v1[0]->getStartNode()); CPPUNIT_ASSERT(e1->getEndNode()==v1[1]->getEndNode()); CPPUNIT_ASSERT(e1->getEndNode()==e2->getStartNode()); + CPPUNIT_ASSERT(v1[1]->intresincEqCoarse(e2) && !v1[1]->getDirection()); CPPUNIT_ASSERT(v2[0]->intresincEqCoarse(e2) && v2[0]->getDirection()); + CPPUNIT_ASSERT(v1[0]->getEndNode()==v1[1]->getStartNode()); + CPPUNIT_ASSERT(e1->getStartNode()==v1.front()->getStartNode() && e1->getEndNode()==v1.back()->getEndNode()); + CPPUNIT_ASSERT(e2->getStartNode()==v2.front()->getStartNode() && e2->getEndNode()==v2.back()->getEndNode()); + e2->decrRef(); e1->decrRef(); + v1.clear(); v2.clear(); v3.clear(); + //Test 12 - OUT_BEFORE - END | same dir. - 0° + e1=new EdgeLin(0.,0.,1.,0.); e2=new EdgeLin(-0.5,0.,1.,0.); + CPPUNIT_ASSERT(e1->intersectWith(e2,v3,v1,v2)); + CPPUNIT_ASSERT_EQUAL(1,(int)v3.getNumberOfAssociations()); + CPPUNIT_ASSERT_EQUAL(1,(int)v1.size()); + CPPUNIT_ASSERT_EQUAL(2,(int)v2.size()); + CPPUNIT_ASSERT(v1[0]->intresincEqCoarse(e1) && v1[0]->getDirection()); CPPUNIT_ASSERT(v2[1]->intresincEqCoarse(e1) && v2[1]->getDirection()); + CPPUNIT_ASSERT(e2->getStartNode()==v2[0]->getStartNode()); CPPUNIT_ASSERT(e1->getEndNode()==e2->getEndNode()); CPPUNIT_ASSERT(e2->getEndNode()==v2[1]->getEndNode()); + CPPUNIT_ASSERT(v2[0]->getEndNode()==v2[1]->getStartNode()); + CPPUNIT_ASSERT(e1->getStartNode()==v1.front()->getStartNode() && e1->getEndNode()==v1.back()->getEndNode()); + CPPUNIT_ASSERT(e2->getStartNode()==v2.front()->getStartNode() && e2->getEndNode()==v2.back()->getEndNode()); + e2->decrRef(); e1->decrRef(); + v1.clear(); v2.clear(); v3.clear(); + //Test 12 - OUT_BEFORE - END | same dir. - 90° + e1=new EdgeLin(0.,0.,0.,1.); e2=new EdgeLin(0.,-0.5,0.,1.); + CPPUNIT_ASSERT(e1->intersectWith(e2,v3,v1,v2)); + CPPUNIT_ASSERT_EQUAL(1,(int)v3.getNumberOfAssociations()); + CPPUNIT_ASSERT_EQUAL(1,(int)v1.size()); + CPPUNIT_ASSERT_EQUAL(2,(int)v2.size()); + CPPUNIT_ASSERT(v1[0]->intresincEqCoarse(e1) && v1[0]->getDirection()); CPPUNIT_ASSERT(v2[1]->intresincEqCoarse(e1) && v2[1]->getDirection()); + CPPUNIT_ASSERT(e2->getStartNode()==v2[0]->getStartNode()); CPPUNIT_ASSERT(e1->getEndNode()==e2->getEndNode()); CPPUNIT_ASSERT(e2->getEndNode()==v2[1]->getEndNode()); + CPPUNIT_ASSERT(v2[0]->getEndNode()==v2[1]->getStartNode()); + CPPUNIT_ASSERT(e1->getStartNode()==v1.front()->getStartNode() && e1->getEndNode()==v1.back()->getEndNode()); + CPPUNIT_ASSERT(e2->getStartNode()==v2.front()->getStartNode() && e2->getEndNode()==v2.back()->getEndNode()); + e2->decrRef(); e1->decrRef(); + v1.clear(); v2.clear(); v3.clear(); + //Test 12 - OUT_BEFORE - END | same dir. - 45° + e1=new EdgeLin(0.,0.,1.,1.); e2=new EdgeLin(-0.5,-0.5,1.,1.); + CPPUNIT_ASSERT(e1->intersectWith(e2,v3,v1,v2)); + CPPUNIT_ASSERT_EQUAL(1,(int)v3.getNumberOfAssociations()); + CPPUNIT_ASSERT_EQUAL(1,(int)v1.size()); + CPPUNIT_ASSERT_EQUAL(2,(int)v2.size()); + CPPUNIT_ASSERT(v1[0]->intresincEqCoarse(e1) && v1[0]->getDirection()); CPPUNIT_ASSERT(v2[1]->intresincEqCoarse(e1) && v2[1]->getDirection()); + CPPUNIT_ASSERT(e2->getStartNode()==v2[0]->getStartNode()); CPPUNIT_ASSERT(e1->getEndNode()==e2->getEndNode()); CPPUNIT_ASSERT(e2->getEndNode()==v2[1]->getEndNode()); + CPPUNIT_ASSERT(v2[0]->getEndNode()==v2[1]->getStartNode()); + CPPUNIT_ASSERT(e1->getStartNode()==v1.front()->getStartNode() && e1->getEndNode()==v1.back()->getEndNode()); + CPPUNIT_ASSERT(e2->getStartNode()==v2.front()->getStartNode() && e2->getEndNode()==v2.back()->getEndNode()); + e2->decrRef(); e1->decrRef(); + v1.clear(); v2.clear(); v3.clear(); + //Test 12 - OUT_BEFORE - END | opp dir. - 45° + e1=new EdgeLin(0.,0.,1.,1.); e2=new EdgeLin(1.,1.,-0.5,-0.5); + CPPUNIT_ASSERT(e1->intersectWith(e2,v3,v1,v2)); + CPPUNIT_ASSERT_EQUAL(1,(int)v3.getNumberOfAssociations()); + CPPUNIT_ASSERT_EQUAL(1,(int)v1.size()); + CPPUNIT_ASSERT_EQUAL(2,(int)v2.size()); + CPPUNIT_ASSERT(v1[0]->intresincEqCoarse(e1) && v1[0]->getDirection()); CPPUNIT_ASSERT(v2[0]->intresincEqCoarse(e1) && !v2[0]->getDirection()); + CPPUNIT_ASSERT(e2->getStartNode()==v2[0]->getStartNode()); CPPUNIT_ASSERT(e1->getEndNode()==e2->getStartNode()); CPPUNIT_ASSERT(e2->getEndNode()==v2[1]->getEndNode()); + CPPUNIT_ASSERT(v2[0]->getEndNode()==v2[1]->getStartNode()); + CPPUNIT_ASSERT(e1->getStartNode()==v1.front()->getStartNode() && e1->getEndNode()==v1.back()->getEndNode()); + CPPUNIT_ASSERT(e2->getStartNode()==v2.front()->getStartNode() && e2->getEndNode()==v2.back()->getEndNode()); + e2->decrRef(); e1->decrRef(); + v1.clear(); v2.clear(); v3.clear(); + //Test 13 - START - INSIDE | same dir. - 0° + e1=new EdgeLin(0.,0.,1.,0.); e2=new EdgeLin(0.,0.,0.5,0.); + CPPUNIT_ASSERT(e1->intersectWith(e2,v3,v1,v2)); + CPPUNIT_ASSERT_EQUAL(1,(int)v3.getNumberOfAssociations()); + CPPUNIT_ASSERT_EQUAL(2,(int)v1.size()); + CPPUNIT_ASSERT_EQUAL(1,(int)v2.size()); + CPPUNIT_ASSERT(v1[0]->intresincEqCoarse(e2) && v1[0]->getDirection()); CPPUNIT_ASSERT(v2[0]->intresincEqCoarse(e2) && v2[0]->getDirection()); + CPPUNIT_ASSERT(e2->getStartNode()==v1[0]->getStartNode()); CPPUNIT_ASSERT(e1->getStartNode()==e2->getStartNode()); CPPUNIT_ASSERT(e1->getEndNode()==v1[1]->getEndNode()); + CPPUNIT_ASSERT(v1[0]->getEndNode()==v1[1]->getStartNode()); + CPPUNIT_ASSERT(e1->getStartNode()==v1.front()->getStartNode() && e1->getEndNode()==v1.back()->getEndNode()); + CPPUNIT_ASSERT(e2->getStartNode()==v2.front()->getStartNode() && e2->getEndNode()==v2.back()->getEndNode()); + e2->decrRef(); e1->decrRef(); + v1.clear(); v2.clear(); v3.clear(); + //Test 13 - START - INSIDE | same dir. - 90° + e1=new EdgeLin(0.,0.,0.,1.); e2=new EdgeLin(0.,0.,0.,0.5); + CPPUNIT_ASSERT(e1->intersectWith(e2,v3,v1,v2)); + CPPUNIT_ASSERT_EQUAL(1,(int)v3.getNumberOfAssociations()); + CPPUNIT_ASSERT_EQUAL(2,(int)v1.size()); + CPPUNIT_ASSERT_EQUAL(1,(int)v2.size()); + CPPUNIT_ASSERT(v1[0]->intresincEqCoarse(e2) && v1[0]->getDirection()); CPPUNIT_ASSERT(v2[0]->intresincEqCoarse(e2) && v2[0]->getDirection()); + CPPUNIT_ASSERT(e2->getStartNode()==v1[0]->getStartNode()); CPPUNIT_ASSERT(e1->getStartNode()==e2->getStartNode()); CPPUNIT_ASSERT(e1->getEndNode()==v1[1]->getEndNode()); + CPPUNIT_ASSERT(v1[0]->getEndNode()==v1[1]->getStartNode()); + CPPUNIT_ASSERT(e1->getStartNode()==v1.front()->getStartNode() && e1->getEndNode()==v1.back()->getEndNode()); + CPPUNIT_ASSERT(e2->getStartNode()==v2.front()->getStartNode() && e2->getEndNode()==v2.back()->getEndNode()); + e2->decrRef(); e1->decrRef(); + v1.clear(); v2.clear(); v3.clear(); + //Test 13 - START - INSIDE | same dir. - 45° + e1=new EdgeLin(0.,0.,1.,1.); e2=new EdgeLin(0.,0.,0.5,0.5); + CPPUNIT_ASSERT(e1->intersectWith(e2,v3,v1,v2)); + CPPUNIT_ASSERT_EQUAL(1,(int)v3.getNumberOfAssociations()); + CPPUNIT_ASSERT_EQUAL(2,(int)v1.size()); + CPPUNIT_ASSERT_EQUAL(1,(int)v2.size()); + CPPUNIT_ASSERT(v1[0]->intresincEqCoarse(e2) && v1[0]->getDirection()); CPPUNIT_ASSERT(v2[0]->intresincEqCoarse(e2) && v2[0]->getDirection()); + CPPUNIT_ASSERT(e2->getStartNode()==v1[0]->getStartNode()); CPPUNIT_ASSERT(e1->getStartNode()==e2->getStartNode()); CPPUNIT_ASSERT(e1->getEndNode()==v1[1]->getEndNode()); + CPPUNIT_ASSERT(v1[0]->getEndNode()==v1[1]->getStartNode()); + CPPUNIT_ASSERT(e1->getStartNode()==v1.front()->getStartNode() && e1->getEndNode()==v1.back()->getEndNode()); + CPPUNIT_ASSERT(e2->getStartNode()==v2.front()->getStartNode() && e2->getEndNode()==v2.back()->getEndNode()); + e2->decrRef(); e1->decrRef(); + v1.clear(); v2.clear(); v3.clear(); + //Test 13 - START - INSIDE | opp dir. - 45° + e1=new EdgeLin(0.,0.,1.,1.); e2=new EdgeLin(0.5,0.5,0.,0.); + CPPUNIT_ASSERT(e1->intersectWith(e2,v3,v1,v2)); + CPPUNIT_ASSERT_EQUAL(1,(int)v3.getNumberOfAssociations()); + CPPUNIT_ASSERT_EQUAL(2,(int)v1.size()); + CPPUNIT_ASSERT_EQUAL(1,(int)v2.size()); + CPPUNIT_ASSERT(v1[0]->intresincEqCoarse(e2) && !v1[0]->getDirection()); CPPUNIT_ASSERT(v2[0]->intresincEqCoarse(e2) && v2[0]->getDirection()); + CPPUNIT_ASSERT(e2->getEndNode()==v1[0]->getStartNode()); CPPUNIT_ASSERT(e1->getStartNode()==e2->getEndNode()); CPPUNIT_ASSERT(e1->getEndNode()==v1[1]->getEndNode()); + CPPUNIT_ASSERT(v1[0]->getEndNode()==v1[1]->getStartNode()); + CPPUNIT_ASSERT(e1->getStartNode()==v1.front()->getStartNode() && e1->getEndNode()==v1.back()->getEndNode()); + CPPUNIT_ASSERT(e2->getStartNode()==v2.front()->getStartNode() && e2->getEndNode()==v2.back()->getEndNode()); + e2->decrRef(); e1->decrRef(); + v1.clear(); v2.clear(); v3.clear(); + //Test 14 - INSIDE - START | same dir. + e1=buildArcOfCircle(center,radius,-M_PI,2.*M_PI); e2=buildArcOfCircle(center,radius,M_PI/3.,-M_PI); + CPPUNIT_ASSERT_DOUBLES_EQUAL(M_PI,e1->getCurveLength(),1e-12); CPPUNIT_ASSERT_DOUBLES_EQUAL(4.*M_PI/3.,e2->getCurveLength(),1e-12); + CPPUNIT_ASSERT(e1->intersectWith(e2,v3,v1,v2)); + CPPUNIT_ASSERT_EQUAL(1,(int)v3.getNumberOfAssociations()); + CPPUNIT_ASSERT_EQUAL(2,(int)v1.size()); + CPPUNIT_ASSERT_EQUAL(2,(int)v2.size()); + CPPUNIT_ASSERT(v1[1]->intresicEqual(v2[0])); + CPPUNIT_ASSERT(v2[1]->getEndNode()==e1->getStartNode()); + CPPUNIT_ASSERT(v1[0]->getStartNode()==e1->getStartNode()); + CPPUNIT_ASSERT(v1[1]->getEndNode()==e1->getEndNode()); + CPPUNIT_ASSERT(v2[1]->getStartNode()==e1->getEndNode()); + CPPUNIT_ASSERT_DOUBLES_EQUAL(2*M_PI/3.,v1[0]->getCurveLength(),1.e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(M_PI/3.,v2[0]->getCurveLength(),1.e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(M_PI,v2[1]->getCurveLength(),1.e-12); + e2->decrRef(); e1->decrRef(); + v1.clear(); v2.clear(); v3.clear(); + //Test 14 - INSIDE - START | opp dir. + e1=buildArcOfCircle(center,radius,-M_PI,2.*M_PI); e2=buildArcOfCircle(center,radius,-M_PI,M_PI/3.); + CPPUNIT_ASSERT_DOUBLES_EQUAL(M_PI,e1->getCurveLength(),1e-12); CPPUNIT_ASSERT_DOUBLES_EQUAL(4.*M_PI/3.,e2->getCurveLength(),1e-12); + CPPUNIT_ASSERT(e1->intersectWith(e2,v3,v1,v2)); + CPPUNIT_ASSERT_EQUAL(1,(int)v3.getNumberOfAssociations()); + CPPUNIT_ASSERT_EQUAL(2,(int)v1.size()); + CPPUNIT_ASSERT_EQUAL(2,(int)v2.size()); + CPPUNIT_ASSERT(v1[1]->intresincEqCoarse(v2[1]->getPtr()) && !v2[1]->getDirection() && v1[1]->getDirection()); + CPPUNIT_ASSERT(v2[0]->getStartNode()==e1->getStartNode()); + CPPUNIT_ASSERT(v1[0]->getStartNode()==e1->getStartNode()); + CPPUNIT_ASSERT(v1[1]->getEndNode()==e1->getEndNode()); + CPPUNIT_ASSERT(v2[1]->getStartNode()==e1->getEndNode()); + CPPUNIT_ASSERT(v2[0]->getEndNode()==e1->getEndNode()); + CPPUNIT_ASSERT_DOUBLES_EQUAL(2*M_PI/3.,v1[0]->getCurveLength(),1.e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(M_PI/3.,v2[1]->getCurveLength(),1.e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(M_PI,v2[0]->getCurveLength(),1.e-12); + e2->decrRef(); e1->decrRef(); + v1.clear(); v2.clear(); v3.clear(); + //Test 15 - END - INSIDE | same dir. + e1=buildArcOfCircle(center,radius,-M_PI,2.*M_PI); e2=buildArcOfCircle(center,radius,0.,-4.*M_PI/3); + CPPUNIT_ASSERT_DOUBLES_EQUAL(M_PI,e1->getCurveLength(),1e-12); CPPUNIT_ASSERT_DOUBLES_EQUAL(4.*M_PI/3.,e2->getCurveLength(),1e-12); + CPPUNIT_ASSERT(e1->intersectWith(e2,v3,v1,v2)); + CPPUNIT_ASSERT_EQUAL(1,(int)v3.getNumberOfAssociations()); + CPPUNIT_ASSERT_EQUAL(2,(int)v1.size()); + CPPUNIT_ASSERT_EQUAL(2,(int)v2.size()); + CPPUNIT_ASSERT(v1[0]->intresicEqual(v2[1])); + CPPUNIT_ASSERT(v2[0]->getEndNode()==e1->getStartNode()); + CPPUNIT_ASSERT(v1[0]->getStartNode()==e1->getStartNode()); + CPPUNIT_ASSERT(v1[1]->getEndNode()==e1->getEndNode()); + CPPUNIT_ASSERT(v2[0]->getStartNode()==e1->getEndNode()); + CPPUNIT_ASSERT_DOUBLES_EQUAL(M_PI/3.,v1[0]->getCurveLength(),1.e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(M_PI,v2[0]->getCurveLength(),1.e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(2.*M_PI/3.,v1[1]->getCurveLength(),1.e-12); + e2->decrRef(); e1->decrRef(); + v1.clear(); v2.clear(); v3.clear(); + //Test 15 - END - INSIDE | opp dir. + e1=buildArcOfCircle(center,radius,-M_PI,2.*M_PI); e2=buildArcOfCircle(center,radius,-4.*M_PI/3,0.); + CPPUNIT_ASSERT_DOUBLES_EQUAL(M_PI,e1->getCurveLength(),1e-12); CPPUNIT_ASSERT_DOUBLES_EQUAL(4.*M_PI/3.,e2->getCurveLength(),1e-12); + CPPUNIT_ASSERT(e1->intersectWith(e2,v3,v1,v2)); + CPPUNIT_ASSERT_EQUAL(1,(int)v3.getNumberOfAssociations()); + CPPUNIT_ASSERT_EQUAL(2,(int)v1.size()); + CPPUNIT_ASSERT_EQUAL(2,(int)v2.size()); + CPPUNIT_ASSERT(v1[0]->intresincEqCoarse(v2[0]->getPtr()) && !v2[0]->getDirection() && v1[0]->getDirection()); + CPPUNIT_ASSERT(v2[0]->getEndNode()==e1->getStartNode()); + CPPUNIT_ASSERT(v1[0]->getStartNode()==e1->getStartNode()); + CPPUNIT_ASSERT(v1[1]->getEndNode()==e1->getEndNode()); + CPPUNIT_ASSERT(v2[1]->getEndNode()==e1->getEndNode()); + CPPUNIT_ASSERT_DOUBLES_EQUAL(M_PI/3.,v1[0]->getCurveLength(),1.e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(M_PI,v2[1]->getCurveLength(),1.e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(2.*M_PI/3.,v1[1]->getCurveLength(),1.e-12); + e2->decrRef(); e1->decrRef(); + v1.clear(); v2.clear(); v3.clear(); + // + ComposedEdge::Delete(&v1); + ComposedEdge::Delete(&v2); +} + +/*! + * Here there is test of cases where between 2 edges intersects only in points not on edge. + */ +void QuadraticPlanarInterpTest::IntersectionPointOnlyUnitarySegSeg() +{ + // 0° - classical + EdgeLin *e1=new EdgeLin(0.,0.,1.,0.); + EdgeLin *e2=new EdgeLin(0.3,0.3,0.5,-0.3); + ComposedEdge& v1=*(new ComposedEdge); + ComposedEdge& v2=*(new ComposedEdge); MergePoints v3; + CPPUNIT_ASSERT(e1->intersectWith(e2,v3,v1,v2)); + CPPUNIT_ASSERT_EQUAL(0,(int)v3.getNumberOfAssociations()); + CPPUNIT_ASSERT_EQUAL(2,(int)v1.size()); + CPPUNIT_ASSERT_EQUAL(2,(int)v2.size()); + CPPUNIT_ASSERT(v1[0]->getEndNode()==v1[1]->getStartNode()); CPPUNIT_ASSERT(v2[0]->getEndNode()==v2[1]->getStartNode()); + CPPUNIT_ASSERT(e1->getStartNode()==v1.front()->getStartNode() && e1->getEndNode()==v1.back()->getEndNode()); + CPPUNIT_ASSERT(e2->getStartNode()==v2.front()->getStartNode() && e2->getEndNode()==v2.back()->getEndNode()); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.4,(*v1[0]->getEndNode())[0],ADMISSIBLE_ERROR); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.,(*v1[0]->getEndNode())[1],ADMISSIBLE_ERROR); + e2->decrRef(); e1->decrRef(); + v1.clear(); v2.clear(); v3.clear(); + // 90° - classical + e1=new EdgeLin(0.,0.,0.,1.); + e2=new EdgeLin(-0.3,0.3,0.3,0.5); + CPPUNIT_ASSERT(e1->intersectWith(e2,v3,v1,v2)); + CPPUNIT_ASSERT_EQUAL(0,(int)v3.getNumberOfAssociations()); + CPPUNIT_ASSERT_EQUAL(2,(int)v1.size()); + CPPUNIT_ASSERT_EQUAL(2,(int)v2.size()); + CPPUNIT_ASSERT(v1[0]->getEndNode()==v1[1]->getStartNode()); CPPUNIT_ASSERT(v2[0]->getEndNode()==v2[1]->getStartNode()); + CPPUNIT_ASSERT(e1->getStartNode()==v1.front()->getStartNode() && e1->getEndNode()==v1.back()->getEndNode()); + CPPUNIT_ASSERT(e2->getStartNode()==v2.front()->getStartNode() && e2->getEndNode()==v2.back()->getEndNode()); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.,(*v1[0]->getEndNode())[0],ADMISSIBLE_ERROR); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.4,(*v1[0]->getEndNode())[1],ADMISSIBLE_ERROR); + e2->decrRef(); e1->decrRef(); + v1.clear(); v2.clear(); v3.clear(); + //Test 1 - 0° + e1=new EdgeLin(0.,0.,1.,0.); e2=new EdgeLin(0.,0.,0.,1.); + CPPUNIT_ASSERT(!e1->intersectWith(e2,v3,v1,v2)); + CPPUNIT_ASSERT_EQUAL(1,(int)v3.getNumberOfAssociations()); + CPPUNIT_ASSERT(v3.isStart1(0)); CPPUNIT_ASSERT(v3.isStart2(0)); + e2->decrRef(); e1->decrRef(); + v1.clear(); v2.clear(); v3.clear(); + //Test 1 - 90° + e1=new EdgeLin(0.,0.,0.,1.); e2=new EdgeLin(0.,0.,1.,0.); + CPPUNIT_ASSERT(!e1->intersectWith(e2,v3,v1,v2)); + CPPUNIT_ASSERT_EQUAL(1,(int)v3.getNumberOfAssociations()); + CPPUNIT_ASSERT(v3.isStart1(0)); CPPUNIT_ASSERT(v3.isStart2(0)); + e2->decrRef(); e1->decrRef(); + v1.clear(); v2.clear(); v3.clear(); + //Test 1 - 45° + e1=new EdgeLin(0.,0.,1.,1.); e2=new EdgeLin(0.,0.,1.,-1.); + CPPUNIT_ASSERT(!e1->intersectWith(e2,v3,v1,v2)); + CPPUNIT_ASSERT_EQUAL(1,(int)v3.getNumberOfAssociations()); + CPPUNIT_ASSERT(v3.isStart1(0)); CPPUNIT_ASSERT(v3.isStart2(0)); + e2->decrRef(); e1->decrRef(); + v1.clear(); v2.clear(); v3.clear(); + //Test 2 + e1=new EdgeLin(0.,0.,1.,0.); e2=new EdgeLin(1.,1.,1.,0.); + CPPUNIT_ASSERT(!e1->intersectWith(e2,v3,v1,v2)); + CPPUNIT_ASSERT_EQUAL(1,(int)v3.getNumberOfAssociations()); + CPPUNIT_ASSERT(v3.isEnd1(0)); CPPUNIT_ASSERT(v3.isEnd2(0)); + e2->decrRef(); e1->decrRef(); + v1.clear(); v2.clear(); v3.clear(); + //Test 3 + e1=new EdgeLin(0.,0.,1.,0.); e2=new EdgeLin(1.,0.,1.,1.); + CPPUNIT_ASSERT(!e1->intersectWith(e2,v3,v1,v2)); + CPPUNIT_ASSERT_EQUAL(1,(int)v3.getNumberOfAssociations()); + CPPUNIT_ASSERT(v3.isEnd1(0)); CPPUNIT_ASSERT(v3.isStart2(0)); + e2->decrRef(); e1->decrRef(); + v1.clear(); v2.clear(); v3.clear(); + //Test 4 + e1=new EdgeLin(0.,0.,1.,1.); e2=new EdgeLin(1.,-1.,0.,0.); + CPPUNIT_ASSERT(!e1->intersectWith(e2,v3,v1,v2)); + CPPUNIT_ASSERT_EQUAL(1,(int)v3.getNumberOfAssociations()); + CPPUNIT_ASSERT(v3.isStart1(0)); CPPUNIT_ASSERT(v3.isEnd2(0)); + e2->decrRef(); e1->decrRef(); + v1.clear(); v2.clear(); v3.clear(); + //Intersection extremity of one edge and inside of other edge. 2 End. + e1=new EdgeLin(0.,0.,1.,0.); + e2=new EdgeLin(0.5,1.,0.5,0.); + CPPUNIT_ASSERT(e1->intersectWith(e2,v3,v1,v2)); + CPPUNIT_ASSERT_EQUAL(2,(int)v1.size()); + CPPUNIT_ASSERT_EQUAL(1,(int)v2.size()); + CPPUNIT_ASSERT_EQUAL(0,(int)v3.getNumberOfAssociations()); + CPPUNIT_ASSERT(v2[0]->intresincEqCoarse(e2) && v2[0]->getDirection()); + CPPUNIT_ASSERT(v1[0]->getStartNode()==e1->getStartNode() && v1[0]->getEndNode()==e2->getEndNode() && v1[1]->getStartNode()==e2->getEndNode() && v1[1]->getEndNode()==e1->getEndNode()); + CPPUNIT_ASSERT(v1[0]->getDirection() && v1[1]->getDirection()); + e2->decrRef(); e1->decrRef(); + v1.clear(); v2.clear(); v3.clear(); + //Intersection extremity of one edge and inside of other edge. 2 Start. + e1=new EdgeLin(0.,0.,1.,0.); + e2=new EdgeLin(0.5,0.,0.5,1.); + CPPUNIT_ASSERT(e1->intersectWith(e2,v3,v1,v2)); + CPPUNIT_ASSERT_EQUAL(2,(int)v1.size()); + CPPUNIT_ASSERT_EQUAL(1,(int)v2.size()); + CPPUNIT_ASSERT_EQUAL(0,(int)v3.getNumberOfAssociations()); + CPPUNIT_ASSERT(v2[0]->intresincEqCoarse(e2) && v2[0]->getDirection()); + CPPUNIT_ASSERT(v1[0]->getStartNode()==e1->getStartNode() && v1[0]->getEndNode()==e2->getStartNode() && v1[1]->getStartNode()==e2->getStartNode() && v1[1]->getEndNode()==e1->getEndNode()); + CPPUNIT_ASSERT(v1[0]->getDirection() && v1[1]->getDirection()); + e2->decrRef(); e1->decrRef(); + v1.clear(); v2.clear(); v3.clear(); + //Intersection extremity of one edge and inside of other edge. 1 Start. + e1=new EdgeLin(0.5,0.,0.5,1.); + e2=new EdgeLin(0.,0.,1.,0.); + CPPUNIT_ASSERT(e1->intersectWith(e2,v3,v1,v2)); + CPPUNIT_ASSERT_EQUAL(1,(int)v1.size()); + CPPUNIT_ASSERT_EQUAL(2,(int)v2.size()); + CPPUNIT_ASSERT_EQUAL(0,(int)v3.getNumberOfAssociations()); + CPPUNIT_ASSERT(v1[0]->intresincEqCoarse(e1) && v1[0]->getDirection()); + CPPUNIT_ASSERT(v2[0]->getStartNode()==e2->getStartNode() && v2[0]->getEndNode()==e1->getStartNode() && v2[1]->getStartNode()==e1->getStartNode() && v2[1]->getEndNode()==e2->getEndNode()); + CPPUNIT_ASSERT(v2[0]->getDirection() && v2[1]->getDirection()); + e2->decrRef(); e1->decrRef(); + v1.clear(); v2.clear(); v3.clear(); + //Intersection extremity of one edge and inside of other edge. 1 End. + e1=new EdgeLin(0.5,1.,0.5,0.); + e2=new EdgeLin(0.,0.,1.,0.); + CPPUNIT_ASSERT(e1->intersectWith(e2,v3,v1,v2)); + CPPUNIT_ASSERT_EQUAL(1,(int)v1.size()); + CPPUNIT_ASSERT_EQUAL(2,(int)v2.size()); + CPPUNIT_ASSERT_EQUAL(0,(int)v3.getNumberOfAssociations()); + CPPUNIT_ASSERT(v1[0]->intresincEqCoarse(e1) && v1[0]->getDirection()); + CPPUNIT_ASSERT(v2[0]->getStartNode()==e2->getStartNode() && v2[0]->getEndNode()==e1->getEndNode() && v2[1]->getStartNode()==e1->getEndNode() && v2[1]->getEndNode()==e2->getEndNode()); + CPPUNIT_ASSERT(v2[0]->getDirection() && v2[1]->getDirection()); + e2->decrRef(); e1->decrRef(); + v1.clear(); v2.clear(); v3.clear(); + ComposedEdge::Delete(&v2); + ComposedEdge::Delete(&v1); +} + +} diff --git a/src/medtool/src/INTERP_KERNELTest/QuadraticPlanarInterpTest.hxx b/src/medtool/src/INTERP_KERNELTest/QuadraticPlanarInterpTest.hxx new file mode 100644 index 000000000..991e47b28 --- /dev/null +++ b/src/medtool/src/INTERP_KERNELTest/QuadraticPlanarInterpTest.hxx @@ -0,0 +1,214 @@ +// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 +// 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 _QUADRATICPLANARINTERPTEST_HXX_ +#define _QUADRATICPLANARINTERPTEST_HXX_ + +#include <cppunit/extensions/HelperMacros.h> + +#include "InterpKernelTestExport.hxx" +#include "InterpKernelGeo2DEdgeArcCircle.hxx" +#include "InterpKernelGeo2DQuadraticPolygon.hxx" + +namespace INTERP_TEST +{ + class INTERPKERNELTEST_EXPORT QuadraticPlanarInterpTest : public CppUnit::TestFixture + { + CPPUNIT_TEST_SUITE( QuadraticPlanarInterpTest ); + CPPUNIT_TEST( ReadWriteInXfigElementary ); + CPPUNIT_TEST( ReadWriteInXfigGlobal ); + CPPUNIT_TEST( BasicGeometricTools ); + CPPUNIT_TEST( IntersectionBasics ); + CPPUNIT_TEST( EdgeLinUnitary ); + CPPUNIT_TEST( IntersectionEdgeOverlapUnitarySegSeg ); + CPPUNIT_TEST( IntersectionPointOnlyUnitarySegSeg ); + CPPUNIT_TEST( IntersectArcCircleBase ); + CPPUNIT_TEST( IntersectArcCircleFull ); + CPPUNIT_TEST( IntersectArcCircleSegumentBase ); + CPPUNIT_TEST( checkInOutDetection ); + CPPUNIT_TEST( checkAssemblingBases1 ); + CPPUNIT_TEST( checkAssemblingBases2 ); + CPPUNIT_TEST( checkPolygonsIntersection1 ); + CPPUNIT_TEST( checkPolygonsIntersection2 ); + CPPUNIT_TEST( checkAreasCalculations ); + CPPUNIT_TEST( checkBarycenterCalculations ); + CPPUNIT_TEST( checkHighLevelFunctionTest1 ); + CPPUNIT_TEST( check1DInterpLin ); + CPPUNIT_TEST( checkEpsilonCoherency1 ); + CPPUNIT_TEST( checkNonRegression1 ); + CPPUNIT_TEST( checkNonRegression2 ); + CPPUNIT_TEST( checkNonRegression3 ); + CPPUNIT_TEST( checkNonRegression4 ); + CPPUNIT_TEST( checkNonRegression5 ); + CPPUNIT_TEST( checkNonRegression6 ); + CPPUNIT_TEST( checkNonRegression7 ); + CPPUNIT_TEST( checkNonRegression8 ); + CPPUNIT_TEST( checkNonRegression9 ); + CPPUNIT_TEST( checkNonRegression10 ); + CPPUNIT_TEST( checkNonRegression11 ); + CPPUNIT_TEST( checkNonRegression12 ); + CPPUNIT_TEST ( checkNonRegression13 ); + CPPUNIT_TEST ( checkNonRegression14 ); + CPPUNIT_TEST ( checkNonRegression15 ); + CPPUNIT_TEST ( checkNonRegression16 ); + CPPUNIT_TEST ( checkNonRegression17 ); + // + CPPUNIT_TEST ( checkNonRegressionOmar0000 ); + CPPUNIT_TEST ( checkNonRegressionOmar0001 ); + CPPUNIT_TEST ( checkNonRegressionOmar0002 ); + CPPUNIT_TEST ( checkNonRegressionOmar0003 ); + CPPUNIT_TEST ( checkNonRegressionOmar0004 ); + CPPUNIT_TEST ( checkNonRegressionOmar0005 ); + CPPUNIT_TEST ( checkNonRegressionOmar0006 ); + CPPUNIT_TEST ( checkNonRegressionOmar0007 ); + CPPUNIT_TEST ( checkNonRegressionOmar0008 ); + CPPUNIT_TEST ( checkNonRegressionOmar0009 ); + CPPUNIT_TEST ( checkNonRegressionOmar0010 ); + CPPUNIT_TEST ( checkNonRegressionOmar0011 ); + CPPUNIT_TEST ( checkNonRegressionOmar2511 ); + CPPUNIT_TEST ( checkNonRegressionOmar0012 ); + CPPUNIT_TEST ( checkNonRegressionOmar0013 ); + CPPUNIT_TEST ( checkNonRegressionOmar0014 ); + CPPUNIT_TEST ( checkNonRegressionOmar0015 ); + CPPUNIT_TEST ( checkNonRegressionOmar0016 ); + CPPUNIT_TEST ( checkNonRegressionOmar0017 ); + CPPUNIT_TEST ( checkNonRegressionOmar0018 ); + CPPUNIT_TEST ( checkNonRegressionOmar0019 ); + CPPUNIT_TEST ( checkNonRegressionOmar0020 ); + CPPUNIT_TEST ( checkNonRegressionOmar0021 ); + CPPUNIT_TEST ( checkNonRegressionOmar0022 ); + CPPUNIT_TEST ( checkNonRegressionOmar0023 ); + CPPUNIT_TEST ( checkNonRegressionOmar0024 ); + CPPUNIT_TEST ( checkNonRegressionOmar2524 ); + CPPUNIT_TEST ( checkNonRegressionOmar0025 ); + CPPUNIT_TEST ( checkNonRegressionOmar0026 ); + CPPUNIT_TEST ( checkNonRegressionOmar0027 ); + CPPUNIT_TEST ( checkNonRegressionOmar0028 ); + CPPUNIT_TEST ( checkNonRegressionOmar0029 ); + CPPUNIT_TEST ( checkNonRegressionOmar0030 ); + // + CPPUNIT_TEST( checkNormalize ); + CPPUNIT_TEST( checkMakePartitionAbs1 ); + // + CPPUNIT_TEST( checkIsInOrOut ); + CPPUNIT_TEST( checkGetMiddleOfPoints ); + CPPUNIT_TEST( checkGetMiddleOfPointsOriented ); + CPPUNIT_TEST_SUITE_END(); + public: + void setUp(); + void tearDown(); + void cleanUp(); + // + void ReadWriteInXfigElementary(); + void ReadWriteInXfigGlobal(); + void BasicGeometricTools(); + void IntersectionBasics(); + void EdgeLinUnitary(); + void IntersectionEdgeOverlapUnitarySegSeg(); + void IntersectionPointOnlyUnitarySegSeg(); + // + void IntersectArcCircleBase(); + void IntersectArcCircleFull(); + void IntersectArcCircleSegumentBase(); + // + void checkInOutDetection(); + // + void checkAssemblingBases1(); + void checkAssemblingBases2(); + // + void checkPolygonsIntersection1(); + void checkPolygonsIntersection2(); + void checkAreasCalculations(); + void checkBarycenterCalculations(); + // + void checkHighLevelFunctionTest1(); + // + void check1DInterpLin(); + // + void checkEpsilonCoherency1(); + // + void checkNonRegression1(); + void checkNonRegression2(); + void checkNonRegression3(); + void checkNonRegression4(); + void checkNonRegression5(); + void checkNonRegression6(); + void checkNonRegression7(); + void checkNonRegression8(); + void checkNonRegression9(); + void checkNonRegression10(); + void checkNonRegression11(); + void checkNonRegression12(); + void checkNonRegression13(); + void checkNonRegression14(); + void checkNonRegression15(); + void checkNonRegression16(); + void checkNonRegression17(); + // + void checkNonRegressionOmar0000(); + void checkNonRegressionOmar0001(); + void checkNonRegressionOmar0002(); + void checkNonRegressionOmar0003(); + void checkNonRegressionOmar0004(); + void checkNonRegressionOmar0005(); + void checkNonRegressionOmar0006(); + void checkNonRegressionOmar0007(); + void checkNonRegressionOmar0008(); + void checkNonRegressionOmar0009(); + void checkNonRegressionOmar0010(); + void checkNonRegressionOmar0011(); + void checkNonRegressionOmar2511(); + void checkNonRegressionOmar0012(); + void checkNonRegressionOmar0013(); + void checkNonRegressionOmar0014(); + void checkNonRegressionOmar0015(); + void checkNonRegressionOmar0016(); + void checkNonRegressionOmar0017(); + void checkNonRegressionOmar0018(); + void checkNonRegressionOmar0019(); + void checkNonRegressionOmar0020(); + void checkNonRegressionOmar0021(); + void checkNonRegressionOmar0022(); + void checkNonRegressionOmar0023(); + void checkNonRegressionOmar0024(); + void checkNonRegressionOmar2524(); + void checkNonRegressionOmar0025(); + void checkNonRegressionOmar0026(); + void checkNonRegressionOmar0027(); + void checkNonRegressionOmar0028(); + void checkNonRegressionOmar0029(); + void checkNonRegressionOmar0030(); + // + void checkNormalize(); + void checkMakePartitionAbs1(); + // From Adrien: + void checkIsInOrOut(); + void checkGetMiddleOfPoints(); + void checkGetMiddleOfPointsOriented(); + + private: + INTERP_KERNEL::QuadraticPolygon *buildQuadraticPolygonCoarseInfo(const double *coords, const int *conn, int lgth); + INTERP_KERNEL::EdgeArcCircle *buildArcOfCircle(const double *center, double radius, double alphaStart, double alphaEnd); + double btw2NodesAndACenter(const INTERP_KERNEL::Node& n1, const INTERP_KERNEL::Node& n2, const double *center); + void checkBasicsOfPolygons(INTERP_KERNEL::QuadraticPolygon& pol1, INTERP_KERNEL::QuadraticPolygon& pol2, bool checkDirection); + }; +} + +#endif diff --git a/src/medtool/src/INTERP_KERNELTest/QuadraticPlanarInterpTest2.cxx b/src/medtool/src/INTERP_KERNELTest/QuadraticPlanarInterpTest2.cxx new file mode 100644 index 000000000..a41827b15 --- /dev/null +++ b/src/medtool/src/INTERP_KERNELTest/QuadraticPlanarInterpTest2.cxx @@ -0,0 +1,675 @@ +// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 +// 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 "QuadraticPlanarInterpTest.hxx" +#include "InterpKernelGeo2DQuadraticPolygon.hxx" +#include "InterpKernelGeo2DEdgeArcCircle.hxx" +#include "InterpKernelGeo2DEdgeLin.hxx" + +#include <cmath> +#include <sstream> +#include <iostream> + +using namespace INTERP_KERNEL; + +namespace INTERP_TEST +{ + +static const double ADMISSIBLE_ERROR = 1.e-14; + +void QuadraticPlanarInterpTest::IntersectArcCircleBase() +{ + double center[2]={0.5,0.5}; + double radius=0.3; + EdgeArcCircle *e1=buildArcOfCircle(center,radius,M_PI/4.,M_PI/3.); + CPPUNIT_ASSERT_DOUBLES_EQUAL(e1->getBounds()[0],center[0]+radius*cos(M_PI/3),ADMISSIBLE_ERROR); + CPPUNIT_ASSERT_DOUBLES_EQUAL(e1->getBounds()[1],center[0]+radius*cos(M_PI/4),ADMISSIBLE_ERROR); + CPPUNIT_ASSERT_DOUBLES_EQUAL(e1->getBounds()[2],center[1]+radius*sin(M_PI/4),ADMISSIBLE_ERROR); + CPPUNIT_ASSERT_DOUBLES_EQUAL(e1->getBounds()[3],center[1]+radius*sin(M_PI/3),ADMISSIBLE_ERROR); + e1->decrRef(); + // + e1=buildArcOfCircle(center,radius,M_PI/3.,M_PI/2.); + CPPUNIT_ASSERT_DOUBLES_EQUAL(e1->getBounds()[0],center[0]+radius*cos(M_PI/2),ADMISSIBLE_ERROR); + CPPUNIT_ASSERT_DOUBLES_EQUAL(e1->getBounds()[1],center[0]+radius*cos(M_PI/3),ADMISSIBLE_ERROR); + CPPUNIT_ASSERT_DOUBLES_EQUAL(e1->getBounds()[2],center[1]+radius*sin(M_PI/3),ADMISSIBLE_ERROR); + CPPUNIT_ASSERT_DOUBLES_EQUAL(e1->getBounds()[3],center[1]+radius*sin(M_PI/2),ADMISSIBLE_ERROR); + e1->decrRef(); + // + e1=buildArcOfCircle(center,radius,M_PI/3.,3.*M_PI/4.); + CPPUNIT_ASSERT_DOUBLES_EQUAL(e1->getBounds()[0],center[0]+radius*cos(3*M_PI/4),ADMISSIBLE_ERROR); + CPPUNIT_ASSERT_DOUBLES_EQUAL(e1->getBounds()[1],center[0]+radius*cos(M_PI/3),ADMISSIBLE_ERROR); + CPPUNIT_ASSERT_DOUBLES_EQUAL(e1->getBounds()[2],center[1]+radius*sin(3*M_PI/4),ADMISSIBLE_ERROR); + CPPUNIT_ASSERT_DOUBLES_EQUAL(e1->getBounds()[3],center[1]+radius*sin(M_PI/2),ADMISSIBLE_ERROR);//<< + e1->decrRef(); + // + e1=buildArcOfCircle(center,radius,3*M_PI/4,7*M_PI/8); + CPPUNIT_ASSERT_DOUBLES_EQUAL(e1->getBounds()[0],center[0]+radius*cos(7*M_PI/8),ADMISSIBLE_ERROR); + CPPUNIT_ASSERT_DOUBLES_EQUAL(e1->getBounds()[1],center[0]+radius*cos(3*M_PI/4),ADMISSIBLE_ERROR); + CPPUNIT_ASSERT_DOUBLES_EQUAL(e1->getBounds()[2],center[1]+radius*sin(7*M_PI/8),ADMISSIBLE_ERROR); + CPPUNIT_ASSERT_DOUBLES_EQUAL(e1->getBounds()[3],center[1]+radius*sin(3*M_PI/4),ADMISSIBLE_ERROR); + e1->decrRef(); + // + e1=buildArcOfCircle(center,radius,7.*M_PI/8.,9.*M_PI/8.); + CPPUNIT_ASSERT_DOUBLES_EQUAL(e1->getBounds()[0],center[0]+radius*cos(M_PI),ADMISSIBLE_ERROR);//<< + CPPUNIT_ASSERT_DOUBLES_EQUAL(e1->getBounds()[1],center[0]+radius*cos(7*M_PI/8),ADMISSIBLE_ERROR); + CPPUNIT_ASSERT_DOUBLES_EQUAL(e1->getBounds()[2],center[1]+radius*sin(9*M_PI/8),ADMISSIBLE_ERROR); + CPPUNIT_ASSERT_DOUBLES_EQUAL(e1->getBounds()[3],center[1]+radius*sin(7*M_PI/8),ADMISSIBLE_ERROR); + e1->decrRef(); + // + e1=buildArcOfCircle(center,radius,9.*M_PI/8.,11.*M_PI/8.); + CPPUNIT_ASSERT_DOUBLES_EQUAL(e1->getBounds()[0],center[0]+radius*cos(9*M_PI/8),ADMISSIBLE_ERROR); + CPPUNIT_ASSERT_DOUBLES_EQUAL(e1->getBounds()[1],center[0]+radius*cos(11*M_PI/8),ADMISSIBLE_ERROR); + CPPUNIT_ASSERT_DOUBLES_EQUAL(e1->getBounds()[2],center[1]+radius*sin(11*M_PI/8),ADMISSIBLE_ERROR); + CPPUNIT_ASSERT_DOUBLES_EQUAL(e1->getBounds()[3],center[1]+radius*sin(9*M_PI/8),ADMISSIBLE_ERROR); + e1->decrRef(); + // + e1=buildArcOfCircle(center,radius,11.*M_PI/8.,7.*M_PI/4.); + CPPUNIT_ASSERT_DOUBLES_EQUAL(e1->getBounds()[0],center[0]+radius*cos(11*M_PI/8),ADMISSIBLE_ERROR); + CPPUNIT_ASSERT_DOUBLES_EQUAL(e1->getBounds()[1],center[0]+radius*cos(7*M_PI/4),ADMISSIBLE_ERROR); + CPPUNIT_ASSERT_DOUBLES_EQUAL(e1->getBounds()[2],center[1]+radius*sin(3*M_PI/2),ADMISSIBLE_ERROR);//<< + CPPUNIT_ASSERT_DOUBLES_EQUAL(e1->getBounds()[3],center[1]+radius*sin(7*M_PI/4),ADMISSIBLE_ERROR); + e1->decrRef(); + // + e1=buildArcOfCircle(center,radius,7.*M_PI/4.,15.*M_PI/8.); + CPPUNIT_ASSERT_DOUBLES_EQUAL(e1->getBounds()[0],center[0]+radius*cos(7*M_PI/4),ADMISSIBLE_ERROR); + CPPUNIT_ASSERT_DOUBLES_EQUAL(e1->getBounds()[1],center[0]+radius*cos(15*M_PI/8),ADMISSIBLE_ERROR); + CPPUNIT_ASSERT_DOUBLES_EQUAL(e1->getBounds()[2],center[1]+radius*sin(7*M_PI/4),ADMISSIBLE_ERROR); + CPPUNIT_ASSERT_DOUBLES_EQUAL(e1->getBounds()[3],center[1]+radius*sin(15*M_PI/8),ADMISSIBLE_ERROR); + e1->decrRef(); + // + e1=buildArcOfCircle(center,radius,-M_PI/8.,M_PI/4.); + CPPUNIT_ASSERT_DOUBLES_EQUAL(e1->getBounds()[0],center[0]+radius*cos(M_PI/4),ADMISSIBLE_ERROR); + CPPUNIT_ASSERT_DOUBLES_EQUAL(e1->getBounds()[1],center[0]+radius*cos(0.),ADMISSIBLE_ERROR); //<< + CPPUNIT_ASSERT_DOUBLES_EQUAL(e1->getBounds()[2],center[1]+radius*sin(15*M_PI/8),ADMISSIBLE_ERROR); + CPPUNIT_ASSERT_DOUBLES_EQUAL(e1->getBounds()[3],center[1]+radius*sin(M_PI/4),ADMISSIBLE_ERROR); + e1->decrRef(); + // + // ArcCArcCIntersector + // + TypeOfLocInEdge where1,where2; + std::vector<Node *> v4; + MergePoints v3; + EdgeArcCircle *e2; + ArcCArcCIntersector *intersector=0; + for(unsigned k=0;k<8;k++) + { + e1=buildArcOfCircle(center,radius,M_PI/4.+k*M_PI/4.,M_PI/3.+k*M_PI/4.); + e2=buildArcOfCircle(center,radius,M_PI/4.+k*M_PI/4.,M_PI/3.+k*M_PI/4.); + intersector=new ArcCArcCIntersector(*e1,*e2); + intersector->getPlacements(e2->getStartNode(),e2->getEndNode(),where1,where2,v3); + CPPUNIT_ASSERT(where1==START && where2==END); + delete intersector; v3.clear(); e2->decrRef(); + // + e2=buildArcOfCircle(center,radius,7*M_PI/24.+k*M_PI/4.,M_PI/3.+k*M_PI/4.); + intersector=new ArcCArcCIntersector(*e1,*e2); + intersector->getPlacements(e2->getStartNode(),e2->getEndNode(),where1,where2,v3); + CPPUNIT_ASSERT(where1==INSIDE && where2==END); + delete intersector; v3.clear(); e2->decrRef(); + // + e2=buildArcOfCircle(center,radius,M_PI/4.+k*M_PI/4.,7*M_PI/24.+k*M_PI/4.); + intersector=new ArcCArcCIntersector(*e1,*e2); + intersector->getPlacements(e2->getStartNode(),e2->getEndNode(),where1,where2,v3); + CPPUNIT_ASSERT(where1==START && where2==INSIDE); + delete intersector; v3.clear(); e2->decrRef(); + // + e2=buildArcOfCircle(center,radius,13.*M_PI/48.+k*M_PI/4.,15*M_PI/48.+k*M_PI/4.); + intersector=new ArcCArcCIntersector(*e1,*e2); + intersector->getPlacements(e2->getStartNode(),e2->getEndNode(),where1,where2,v3); + CPPUNIT_ASSERT(where1==INSIDE && where2==INSIDE); + delete intersector; v3.clear(); e2->decrRef(); + // + e2=buildArcOfCircle(center,radius,-M_PI/4.+k*M_PI/4.,M_PI/6.+k*M_PI/4.); + intersector=new ArcCArcCIntersector(*e1,*e2); + intersector->getPlacements(e2->getStartNode(),e2->getEndNode(),where1,where2,v3); + CPPUNIT_ASSERT(where1==OUT_BEFORE && where2==OUT_BEFORE); + delete intersector; v3.clear(); e2->decrRef(); + // + e2=buildArcOfCircle(center,radius,0+k*M_PI/4.,5*M_PI/6.+k*M_PI/4.); + intersector=new ArcCArcCIntersector(*e1,*e2); + intersector->getPlacements(e2->getStartNode(),e2->getEndNode(),where1,where2,v3); + CPPUNIT_ASSERT(where1==OUT_BEFORE && where2==OUT_AFTER); + delete intersector; v3.clear(); e2->decrRef(); + e1->decrRef(); + } + // Ok now let's see intersection only. 2 intersections R1 > R2 ; dist(circle1,circle2)>R1; Opposite order. + for(unsigned k=0;k<8;k++) + { + center[0]=0.; center[1]=0.; + double center2[2]; center2[0]=3.8*cos(k*M_PI/4.); center2[1]=3.8*sin(k*M_PI/4.); + e1=buildArcOfCircle(center,3.,(k-1)*M_PI/4.,(k+1)*M_PI/4.); + e2=buildArcOfCircle(center2,1.,M_PI+(k-1)*M_PI/4.,M_PI+(k+1)*M_PI/4.); + intersector=new ArcCArcCIntersector(*e1,*e2); + bool order; + bool obvious,areOverlapped; + intersector->areOverlappedOrOnlyColinears(0,obvious,areOverlapped); + CPPUNIT_ASSERT(!obvious && !areOverlapped); + CPPUNIT_ASSERT(intersector->intersect(0,v4,order,v3)); CPPUNIT_ASSERT(!order); + CPPUNIT_ASSERT_EQUAL(2,(int)v4.size()); CPPUNIT_ASSERT_EQUAL(0,(int)v3.getNumberOfAssociations()); + CPPUNIT_ASSERT_DOUBLES_EQUAL(e1->getRadius(),Node::distanceBtw2Pt(e1->getCenter(),(*(v4[0]))),ADMISSIBLE_ERROR); + CPPUNIT_ASSERT_DOUBLES_EQUAL(e2->getRadius(),Node::distanceBtw2Pt(e2->getCenter(),(*(v4[0]))),ADMISSIBLE_ERROR); + CPPUNIT_ASSERT_DOUBLES_EQUAL(e1->getRadius(),Node::distanceBtw2Pt(e1->getCenter(),(*(v4[1]))),ADMISSIBLE_ERROR); + CPPUNIT_ASSERT_DOUBLES_EQUAL(e2->getRadius(),Node::distanceBtw2Pt(e2->getCenter(),(*(v4[1]))),ADMISSIBLE_ERROR); + CPPUNIT_ASSERT(!v4[0]->isEqual(*v4[1])); + CPPUNIT_ASSERT_DOUBLES_EQUAL(btw2NodesAndACenter(*v4[0],*v4[1],e1->getCenter()),0.35587863972199624,1e-10); + for(std::vector<Node *>::iterator iter=v4.begin();iter!=v4.end();iter++) + (*iter)->decrRef(); + v4.clear(); v3.clear(); + delete intersector; e2->decrRef(); e1->decrRef(); + } + // Ok now let's see intersection only. 2 intersections R1 > R2 ; dist(circle1,circle2)>R1; Same order. + for(unsigned k=0;k<7;k++) + { + center[0]=0.; center[1]=0.; + double center2[2]; center2[0]=3.8*cos(k*M_PI/4.); center2[1]=3.8*sin(k*M_PI/4.); + e1=buildArcOfCircle(center,3.,(k-1)*M_PI/4.,(k+1)*M_PI/4.); + e2=buildArcOfCircle(center2,1.,M_PI+(k+1)*M_PI/4.,M_PI+(k-1)*M_PI/4.); + intersector=new ArcCArcCIntersector(*e1,*e2); + bool order; + bool obvious,areOverlapped; + intersector->areOverlappedOrOnlyColinears(0,obvious,areOverlapped); + CPPUNIT_ASSERT(!obvious && !areOverlapped); + CPPUNIT_ASSERT(intersector->intersect(0,v4,order,v3)); CPPUNIT_ASSERT(order); + CPPUNIT_ASSERT_EQUAL(2,(int)v4.size()); CPPUNIT_ASSERT_EQUAL(0,(int)v3.getNumberOfAssociations()); + CPPUNIT_ASSERT_DOUBLES_EQUAL(e1->getRadius(),Node::distanceBtw2Pt(e1->getCenter(),(*(v4[0]))),ADMISSIBLE_ERROR); + CPPUNIT_ASSERT_DOUBLES_EQUAL(e2->getRadius(),Node::distanceBtw2Pt(e2->getCenter(),(*(v4[0]))),ADMISSIBLE_ERROR); + CPPUNIT_ASSERT_DOUBLES_EQUAL(e1->getRadius(),Node::distanceBtw2Pt(e1->getCenter(),(*(v4[1]))),ADMISSIBLE_ERROR); + CPPUNIT_ASSERT_DOUBLES_EQUAL(e2->getRadius(),Node::distanceBtw2Pt(e2->getCenter(),(*(v4[1]))),ADMISSIBLE_ERROR); + CPPUNIT_ASSERT(!v4[0]->isEqual(*v4[1])); + CPPUNIT_ASSERT_DOUBLES_EQUAL(btw2NodesAndACenter(*v4[0],*v4[1],e1->getCenter()),0.35587863972199624,1e-10); + for(std::vector<Node *>::iterator iter=v4.begin();iter!=v4.end();iter++) + (*iter)->decrRef(); + v4.clear(); v3.clear(); + delete intersector; e2->decrRef(); e1->decrRef(); + } + // 2 intersections R1>R2 ; dist(circle1,circle2)<R1; Same order. + for(unsigned k=0;k<8;k++) + { + center[0]=0.; center[1]=0.; + double center2[2]; center2[0]=2.8*cos(k*M_PI/4.); center2[1]=2.8*sin(k*M_PI/4.); + e1=buildArcOfCircle(center,3.,(k-1)*M_PI/4.,(k+1)*M_PI/4.); + e2=buildArcOfCircle(center2,1.,(k)*M_PI/4.-M_PI/2.,(k)*M_PI/4.+M_PI/2.); + intersector=new ArcCArcCIntersector(*e1,*e2); + bool order; + bool obvious,areOverlapped; + intersector->areOverlappedOrOnlyColinears(0,obvious,areOverlapped); + CPPUNIT_ASSERT(!obvious && !areOverlapped); + CPPUNIT_ASSERT(intersector->intersect(0,v4,order,v3)); CPPUNIT_ASSERT(order); + CPPUNIT_ASSERT_EQUAL(2,(int)v4.size()); CPPUNIT_ASSERT_EQUAL(0,(int)v3.getNumberOfAssociations()); + CPPUNIT_ASSERT_DOUBLES_EQUAL(e1->getRadius(),Node::distanceBtw2Pt(e1->getCenter(),(*(v4[0]))),ADMISSIBLE_ERROR); + CPPUNIT_ASSERT_DOUBLES_EQUAL(e2->getRadius(),Node::distanceBtw2Pt(e2->getCenter(),(*(v4[0]))),ADMISSIBLE_ERROR); + CPPUNIT_ASSERT_DOUBLES_EQUAL(e1->getRadius(),Node::distanceBtw2Pt(e1->getCenter(),(*(v4[1]))),ADMISSIBLE_ERROR); + CPPUNIT_ASSERT_DOUBLES_EQUAL(e2->getRadius(),Node::distanceBtw2Pt(e2->getCenter(),(*(v4[1]))),ADMISSIBLE_ERROR); + CPPUNIT_ASSERT(!v4[0]->isEqual(*v4[1])); + CPPUNIT_ASSERT_DOUBLES_EQUAL(btw2NodesAndACenter(*v4[0],*v4[1],e1->getCenter()),0.6793851523346941,1e-10); + for(std::vector<Node *>::iterator iter=v4.begin();iter!=v4.end();iter++) + (*iter)->decrRef(); + v4.clear(); v3.clear(); + delete intersector; e2->decrRef(); e1->decrRef(); + } + // 2 intersections R1>R2 ; dist(circle1,circle2)<R1; Opp order. + for(unsigned k=0;k<8;k++) + { + center[0]=0.; center[1]=0.; + double center2[2]; center2[0]=2.8*cos(k*M_PI/4.); center2[1]=2.8*sin(k*M_PI/4.); + e1=buildArcOfCircle(center,3.,(k-1)*M_PI/4.,(k+1)*M_PI/4.); + e2=buildArcOfCircle(center2,1.,(k)*M_PI/4.+M_PI/2.,(k)*M_PI/4.-M_PI/2.); + intersector=new ArcCArcCIntersector(*e1,*e2); + bool order; + bool obvious,areOverlapped; + intersector->areOverlappedOrOnlyColinears(0,obvious,areOverlapped); + CPPUNIT_ASSERT(!obvious && !areOverlapped); + CPPUNIT_ASSERT(intersector->intersect(0,v4,order,v3)); CPPUNIT_ASSERT(!order); + CPPUNIT_ASSERT_EQUAL(2,(int)v4.size()); CPPUNIT_ASSERT_EQUAL(0,(int)v3.getNumberOfAssociations()); + CPPUNIT_ASSERT_DOUBLES_EQUAL(e1->getRadius(),Node::distanceBtw2Pt(e1->getCenter(),(*(v4[0]))),ADMISSIBLE_ERROR); + CPPUNIT_ASSERT_DOUBLES_EQUAL(e2->getRadius(),Node::distanceBtw2Pt(e2->getCenter(),(*(v4[0]))),ADMISSIBLE_ERROR); + CPPUNIT_ASSERT_DOUBLES_EQUAL(e1->getRadius(),Node::distanceBtw2Pt(e1->getCenter(),(*(v4[1]))),ADMISSIBLE_ERROR); + CPPUNIT_ASSERT_DOUBLES_EQUAL(e2->getRadius(),Node::distanceBtw2Pt(e2->getCenter(),(*(v4[1]))),ADMISSIBLE_ERROR); + CPPUNIT_ASSERT(!v4[0]->isEqual(*v4[1])); + CPPUNIT_ASSERT_DOUBLES_EQUAL(btw2NodesAndACenter(*v4[0],*v4[1],e1->getCenter()),0.6793851523346941,1e-10); + for(std::vector<Node *>::iterator iter=v4.begin();iter!=v4.end();iter++) + (*iter)->decrRef(); + v4.clear(); v3.clear(); + delete intersector; e2->decrRef(); e1->decrRef(); + } + // Ok now let's see intersection only. 2 intersections R1 < R2 ; dist(circle1,circle2)>R2; Opposite order. + for(unsigned k=0;k<1;k++) + { + double center2[2]; center[0]=0.; center[1]=0.; + center2[0]=3.8*cos(k*M_PI/4.); center2[1]=3.8*sin(k*M_PI/4.); + e1=buildArcOfCircle(center,1.,(k-1)*M_PI/4.,(k+1)*M_PI/4.); + e2=buildArcOfCircle(center2,3.,M_PI+(k-1)*M_PI/4.,M_PI+(k+1)*M_PI/4.); + intersector=new ArcCArcCIntersector(*e1,*e2); + bool order; + bool obvious,areOverlapped; + intersector->areOverlappedOrOnlyColinears(0,obvious,areOverlapped); + CPPUNIT_ASSERT(!obvious && !areOverlapped); + CPPUNIT_ASSERT(intersector->intersect(0,v4,order,v3)); CPPUNIT_ASSERT(!order); + CPPUNIT_ASSERT_EQUAL(2,(int)v4.size()); CPPUNIT_ASSERT_EQUAL(0,(int)v3.getNumberOfAssociations()); + CPPUNIT_ASSERT_DOUBLES_EQUAL(e1->getRadius(),Node::distanceBtw2Pt(e1->getCenter(),(*(v4[0]))),ADMISSIBLE_ERROR); + CPPUNIT_ASSERT_DOUBLES_EQUAL(e2->getRadius(),Node::distanceBtw2Pt(e2->getCenter(),(*(v4[0]))),ADMISSIBLE_ERROR); + CPPUNIT_ASSERT_DOUBLES_EQUAL(e1->getRadius(),Node::distanceBtw2Pt(e1->getCenter(),(*(v4[1]))),ADMISSIBLE_ERROR); + CPPUNIT_ASSERT_DOUBLES_EQUAL(e2->getRadius(),Node::distanceBtw2Pt(e2->getCenter(),(*(v4[1]))),ADMISSIBLE_ERROR); + CPPUNIT_ASSERT(!v4[0]->isEqual(*v4[1])); + CPPUNIT_ASSERT_DOUBLES_EQUAL(1.1195732971845034,btw2NodesAndACenter(*v4[0],*v4[1],e1->getCenter()),1e-10); + for(std::vector<Node *>::iterator iter=v4.begin();iter!=v4.end();iter++) + (*iter)->decrRef(); + v4.clear(); v3.clear(); + delete intersector; e2->decrRef(); e1->decrRef(); + } + // Ok now let's see intersection only. 2 intersections R1 < R2 ; dist(circle1,circle2)>R2; same order. + for(unsigned k=0;k<8;k++) + { + double center2[2]; center[0]=0.; center[1]=0.; + center2[0]=3.8*cos(k*M_PI/4.); center2[1]=3.8*sin(k*M_PI/4.); + e1=buildArcOfCircle(center,1.,(k+1)*M_PI/4.,(k-1)*M_PI/4.); + e2=buildArcOfCircle(center2,3.,M_PI+(k-1)*M_PI/4.,M_PI+(k+1)*M_PI/4.); + intersector=new ArcCArcCIntersector(*e1,*e2); + bool order; + bool obvious,areOverlapped; + intersector->areOverlappedOrOnlyColinears(0,obvious,areOverlapped); + CPPUNIT_ASSERT(!obvious && !areOverlapped); + CPPUNIT_ASSERT(intersector->intersect(0,v4,order,v3)); CPPUNIT_ASSERT(order); + CPPUNIT_ASSERT_EQUAL(2,(int)v4.size()); CPPUNIT_ASSERT_EQUAL(0,(int)v3.getNumberOfAssociations()); + CPPUNIT_ASSERT_DOUBLES_EQUAL(e1->getRadius(),Node::distanceBtw2Pt(e1->getCenter(),(*(v4[0]))),ADMISSIBLE_ERROR); + CPPUNIT_ASSERT_DOUBLES_EQUAL(e2->getRadius(),Node::distanceBtw2Pt(e2->getCenter(),(*(v4[0]))),ADMISSIBLE_ERROR); + CPPUNIT_ASSERT_DOUBLES_EQUAL(e1->getRadius(),Node::distanceBtw2Pt(e1->getCenter(),(*(v4[1]))),ADMISSIBLE_ERROR); + CPPUNIT_ASSERT_DOUBLES_EQUAL(e2->getRadius(),Node::distanceBtw2Pt(e2->getCenter(),(*(v4[1]))),ADMISSIBLE_ERROR); + CPPUNIT_ASSERT(!v4[0]->isEqual(*v4[1])); + CPPUNIT_ASSERT_DOUBLES_EQUAL(-1.1195732971845034,btw2NodesAndACenter(*v4[0],*v4[1],e1->getCenter()),1e-10); + for(std::vector<Node *>::iterator iter=v4.begin();iter!=v4.end();iter++) + (*iter)->decrRef(); + v4.clear(); v3.clear(); + delete intersector; e2->decrRef(); e1->decrRef(); + } + // Ok now let's see intersection only. 2 intersections R1 < R2 ; dist(circle1,circle2)<R2; same order. + for(unsigned k=0;k<8;k++) + { + double center2[2]; center[0]=0.; center[1]=0.; + center2[0]=-2.8*cos(k*M_PI/4.); center2[1]=-2.8*sin(k*M_PI/4.); + e1=buildArcOfCircle(center,1.,(k)*M_PI/4.+M_PI/2.,(k)*M_PI/4.-M_PI/2.); + e2=buildArcOfCircle(center2,3.,(k+1)*M_PI/4.,(k-1)*M_PI/4.); + intersector=new ArcCArcCIntersector(*e1,*e2); + bool order; + bool obvious,areOverlapped; + intersector->areOverlappedOrOnlyColinears(0,obvious,areOverlapped); + CPPUNIT_ASSERT(!obvious && !areOverlapped); + CPPUNIT_ASSERT(intersector->intersect(0,v4,order,v3)); CPPUNIT_ASSERT(order); + CPPUNIT_ASSERT_EQUAL(2,(int)v4.size()); CPPUNIT_ASSERT_EQUAL(0,(int)v3.getNumberOfAssociations()); + CPPUNIT_ASSERT_DOUBLES_EQUAL(e1->getRadius(),Node::distanceBtw2Pt(e1->getCenter(),(*(v4[0]))),ADMISSIBLE_ERROR); + CPPUNIT_ASSERT_DOUBLES_EQUAL(e2->getRadius(),Node::distanceBtw2Pt(e2->getCenter(),(*(v4[0]))),ADMISSIBLE_ERROR); + CPPUNIT_ASSERT_DOUBLES_EQUAL(e1->getRadius(),Node::distanceBtw2Pt(e1->getCenter(),(*(v4[1]))),ADMISSIBLE_ERROR); + CPPUNIT_ASSERT_DOUBLES_EQUAL(e2->getRadius(),Node::distanceBtw2Pt(e2->getCenter(),(*(v4[1]))),ADMISSIBLE_ERROR); + CPPUNIT_ASSERT(!v4[0]->isEqual(*v4[1])); + CPPUNIT_ASSERT_DOUBLES_EQUAL(-3.0844420190512074,btw2NodesAndACenter(*v4[0],*v4[1],e1->getCenter()),1e-10); + for(std::vector<Node *>::iterator iter=v4.begin();iter!=v4.end();iter++) + (*iter)->decrRef(); + v4.clear(); v3.clear(); + delete intersector; e2->decrRef(); e1->decrRef(); + } + // Ok now let's see intersection only. 2 intersections R1 < R2 ; dist(circle1,circle2)<R2; opp. order. + for(unsigned k=0;k<8;k++) + { + double center2[2]; center[0]=0.; center[1]=0.; + center2[0]=-2.8*cos(k*M_PI/4.); center2[1]=-2.8*sin(k*M_PI/4.); + e1=buildArcOfCircle(center,1.,(k)*M_PI/4.+M_PI/2.,(k)*M_PI/4.-M_PI/2.); + e2=buildArcOfCircle(center2,3.,(k-1)*M_PI/4.,(k+1)*M_PI/4.); + intersector=new ArcCArcCIntersector(*e1,*e2); + bool order; + bool obvious,areOverlapped; + intersector->areOverlappedOrOnlyColinears(0,obvious,areOverlapped); + CPPUNIT_ASSERT(!obvious && !areOverlapped); + CPPUNIT_ASSERT(intersector->intersect(0,v4,order,v3)); CPPUNIT_ASSERT(!order); + CPPUNIT_ASSERT_EQUAL(2,(int)v4.size()); CPPUNIT_ASSERT_EQUAL(0,(int)v3.getNumberOfAssociations()); + CPPUNIT_ASSERT_DOUBLES_EQUAL(e1->getRadius(),Node::distanceBtw2Pt(e1->getCenter(),(*(v4[0]))),ADMISSIBLE_ERROR); + CPPUNIT_ASSERT_DOUBLES_EQUAL(e2->getRadius(),Node::distanceBtw2Pt(e2->getCenter(),(*(v4[0]))),ADMISSIBLE_ERROR); + CPPUNIT_ASSERT_DOUBLES_EQUAL(e1->getRadius(),Node::distanceBtw2Pt(e1->getCenter(),(*(v4[1]))),ADMISSIBLE_ERROR); + CPPUNIT_ASSERT_DOUBLES_EQUAL(e2->getRadius(),Node::distanceBtw2Pt(e2->getCenter(),(*(v4[1]))),ADMISSIBLE_ERROR); + CPPUNIT_ASSERT(!v4[0]->isEqual(*v4[1])); + CPPUNIT_ASSERT_DOUBLES_EQUAL(-3.0844420190512074,btw2NodesAndACenter(*v4[0],*v4[1],e1->getCenter()),1e-10); + for(std::vector<Node *>::iterator iter=v4.begin();iter!=v4.end();iter++) + (*iter)->decrRef(); + v4.clear(); v3.clear(); + delete intersector; e2->decrRef(); e1->decrRef(); + } + // Tangent intersection + QUADRATIC_PLANAR::setPrecision(1e-5); + for(unsigned k=0;k<8;k++) + { + double center2[2]; center[0]=0.; center[1]=0.; + center2[0]=4.*cos(k*M_PI/4.); center2[1]=4.*sin(k*M_PI/4.); + e1=buildArcOfCircle(center,1.,(k+1)*M_PI/4.,(k-1)*M_PI/4.); + e2=buildArcOfCircle(center2,3.,M_PI+(k-1)*M_PI/4.,M_PI+(k+1)*M_PI/4.); + intersector=new ArcCArcCIntersector(*e1,*e2); + bool order; + bool obvious,areOverlapped; + intersector->areOverlappedOrOnlyColinears(0,obvious,areOverlapped); + CPPUNIT_ASSERT(!obvious && !areOverlapped); + CPPUNIT_ASSERT(intersector->intersect(0,v4,order,v3)); CPPUNIT_ASSERT(order); // order has no sence here because v4.size() expected to 1 but for valgrind serenity test. + CPPUNIT_ASSERT_EQUAL(1,(int)v4.size()); CPPUNIT_ASSERT_EQUAL(0,(int)v3.getNumberOfAssociations()); + CPPUNIT_ASSERT_DOUBLES_EQUAL(e1->getRadius(),Node::distanceBtw2Pt(e1->getCenter(),(*(v4[0]))),ADMISSIBLE_ERROR); + CPPUNIT_ASSERT_DOUBLES_EQUAL(e2->getRadius(),Node::distanceBtw2Pt(e2->getCenter(),(*(v4[0]))),ADMISSIBLE_ERROR); + for(std::vector<Node *>::iterator iter=v4.begin();iter!=v4.end();iter++) + (*iter)->decrRef(); + v4.clear(); v4.clear(); + delete intersector; e2->decrRef(); e1->decrRef(); + } + QUADRATIC_PLANAR::setPrecision(1e-14); + // Extremities # 1 + for(unsigned k=0;k<8;k++) + { + center[0]=0.; center[1]=0.; + double center2[2]; center2[0]=3.8*cos(k*M_PI/4.); center2[1]=3.8*sin(k*M_PI/4.); + e1=buildArcOfCircle(center,3.,k*M_PI/4.-0.17793931986099812,k*M_PI/4.+0.17793931986099812); + e2=buildArcOfCircle(center2,1.,M_PI+k*M_PI/4.-0.55978664859225125,M_PI+k*M_PI/4.+0.55978664859225125); + intersector=new ArcCArcCIntersector(*e1,*e2); + bool order; + bool obvious,areOverlapped; + intersector->areOverlappedOrOnlyColinears(0,obvious,areOverlapped); + CPPUNIT_ASSERT(!obvious && !areOverlapped); + CPPUNIT_ASSERT(!intersector->intersect(0,v4,order,v3)); CPPUNIT_ASSERT_EQUAL(0,(int)v4.size()); CPPUNIT_ASSERT_EQUAL(2,(int)v3.getNumberOfAssociations()); + CPPUNIT_ASSERT(e1->getStartNode()==e2->getEndNode()); CPPUNIT_ASSERT(e2->getStartNode()==e1->getEndNode()); + v4.clear(); v3.clear(); + delete intersector; e2->decrRef(); e1->decrRef(); + } + for(unsigned k=0;k<8;k++) + { + center[0]=0.; center[1]=0.; + double center2[2]; center2[0]=3.8*cos(k*M_PI/4.); center2[1]=3.8*sin(k*M_PI/4.); + e1=buildArcOfCircle(center,3.,k*M_PI/4.-0.17793931986099812,k*M_PI/4.+0.17793931986099812); + e2=buildArcOfCircle(center2,1.,M_PI+k*M_PI/4.+0.55978664859225125,M_PI+k*M_PI/4.-0.55978664859225125); + intersector=new ArcCArcCIntersector(*e1,*e2); + bool order; + bool obvious,areOverlapped; + intersector->areOverlappedOrOnlyColinears(0,obvious,areOverlapped); + CPPUNIT_ASSERT(!obvious && !areOverlapped); + CPPUNIT_ASSERT(!intersector->intersect(0,v4,order,v3)); CPPUNIT_ASSERT_EQUAL(0,(int)v4.size()); CPPUNIT_ASSERT_EQUAL(2,(int)v3.getNumberOfAssociations()); + CPPUNIT_ASSERT(e1->getStartNode()==e2->getStartNode()); CPPUNIT_ASSERT(e2->getEndNode()==e1->getEndNode()); + v4.clear(); v3.clear(); + delete intersector; e2->decrRef(); e1->decrRef(); + } + // Extremities # 2 + for(unsigned k=0;k<8;k++) + { + center[0]=0.; center[1]=0.; + double center2[2]; center2[0]=3.8*cos(k*M_PI/4.); center2[1]=3.8*sin(k*M_PI/4.); + e1=buildArcOfCircle(center,3.,k*M_PI/4.-0.17793931986099812,k*M_PI/4.+0.17793931986099812); + e2=buildArcOfCircle(center2,1.,M_PI+k*M_PI/4.+0.55978664859225125,M_PI+k*M_PI/4.-0.7); + intersector=new ArcCArcCIntersector(*e1,*e2); + bool order; + bool obvious,areOverlapped; + intersector->areOverlappedOrOnlyColinears(0,obvious,areOverlapped); + CPPUNIT_ASSERT(!obvious && !areOverlapped); + CPPUNIT_ASSERT(intersector->intersect(0,v4,order,v3)); + CPPUNIT_ASSERT(order); CPPUNIT_ASSERT_EQUAL(1,(int)v4.size()); CPPUNIT_ASSERT_EQUAL(1,(int)v3.getNumberOfAssociations()); + CPPUNIT_ASSERT(e1->getStartNode()==e2->getStartNode()); CPPUNIT_ASSERT(e1->getEndNode()==v4[0]); + v4[0]->decrRef(); + v4.clear(); v3.clear(); + delete intersector; e2->decrRef(); e1->decrRef(); + } + // Extremities # 3 + for(unsigned k=0;k<8;k++) + { + center[0]=0.; center[1]=0.; + double center2[2]; center2[0]=3.8*cos(k*M_PI/4.); center2[1]=3.8*sin(k*M_PI/4.); + e1=buildArcOfCircle(center,3.,k*M_PI/4.-0.17793931986099812,k*M_PI/4.+0.17793931986099812); + e2=buildArcOfCircle(center2,1.,M_PI+k*M_PI/4.+0.7,M_PI+k*M_PI/4.-0.7); + intersector=new ArcCArcCIntersector(*e1,*e2); + bool order; + bool obvious,areOverlapped; + intersector->areOverlappedOrOnlyColinears(0,obvious,areOverlapped); + CPPUNIT_ASSERT(!obvious && !areOverlapped); + CPPUNIT_ASSERT(intersector->intersect(0,v4,order,v3)); CPPUNIT_ASSERT(order); CPPUNIT_ASSERT_EQUAL(2,(int)v4.size()); CPPUNIT_ASSERT_EQUAL(0,(int)v3.getNumberOfAssociations()); + CPPUNIT_ASSERT(e1->getStartNode()==v4[0]); CPPUNIT_ASSERT(e1->getEndNode()==v4[1]); + v4[0]->decrRef(); v4[1]->decrRef(); + v4.clear(); v3.clear(); + delete intersector; e2->decrRef(); e1->decrRef(); + } + // Extremities # 4 + for(unsigned k=0;k<8;k++) + { + center[0]=0.; center[1]=0.; + double center2[2]; center2[0]=3.8*cos(k*M_PI/4.); center2[1]=3.8*sin(k*M_PI/4.); + Node *nodeS=new Node(center[0]+3.*cos(k*M_PI/4.-0.17793931986099812),center[1]+3.*sin(k*M_PI/4.-0.17793931986099812)); + Node *nodeE=new Node(center[0]+3.*cos(k*M_PI/4.),center[1]+3.*sin(k*M_PI/4.)); + double angle=k*M_PI/4.-0.17793931986099812; + angle=angle>M_PI?angle-2.*M_PI:angle; + e1=new EdgeArcCircle(nodeS,nodeE,//Problem of precision 1e-14 to easily reached. + center,3.,angle,0.17793931986099812); + nodeS->decrRef(); nodeE->decrRef(); + e2=buildArcOfCircle(center2,1.,M_PI+k*M_PI/4.+0.7,M_PI+k*M_PI/4.-0.7); + intersector=new ArcCArcCIntersector(*e1,*e2); + bool order; + bool obvious,areOverlapped; + intersector->areOverlappedOrOnlyColinears(0,obvious,areOverlapped); + CPPUNIT_ASSERT(!obvious && !areOverlapped); + CPPUNIT_ASSERT(intersector->intersect(0,v4,order,v3)); CPPUNIT_ASSERT(order); CPPUNIT_ASSERT_EQUAL(1,(int)v4.size()); CPPUNIT_ASSERT_EQUAL(0,(int)v3.getNumberOfAssociations()); + CPPUNIT_ASSERT(e1->getStartNode()==v4[0]); + v4[0]->decrRef(); + v4.clear(); v3.clear(); + delete intersector; e2->decrRef(); e1->decrRef(); + } + //Extremities # 5 + for(unsigned k=0;k<8;k++) + { + center[0]=0.; center[1]=0.; + double center2[2]; center2[0]=3.8*cos(k*M_PI/4.); center2[1]=3.8*sin(k*M_PI/4.); + Node *nodeS=new Node(center[0]+3.*cos(k*M_PI/4.-0.17793931986099812),center[1]+3.*sin(k*M_PI/4.-0.17793931986099812)); + Node *nodeE=new Node(center[0]+3.*cos(k*M_PI/4.)+0.5,center[1]+3.*sin(k*M_PI/4.)); + double angle=k*M_PI/4.-0.17793931986099812; + angle=angle>M_PI?angle-2.*M_PI:angle; + e1=new EdgeArcCircle(nodeS,nodeE,//Problem of precision 1e-14 to easily reached. + center,3.,angle,0.67793931986099812); + nodeS->decrRef(); nodeE->decrRef(); + e2=buildArcOfCircle(center2,1.,M_PI+k*M_PI/4.+0.7,M_PI+k*M_PI/4.-0.7); + intersector=new ArcCArcCIntersector(*e1,*e2); + bool order; + bool obvious,areOverlapped; + intersector->areOverlappedOrOnlyColinears(0,obvious,areOverlapped); + CPPUNIT_ASSERT(!obvious && !areOverlapped); + CPPUNIT_ASSERT(intersector->intersect(0,v4,order,v3)); CPPUNIT_ASSERT(order); CPPUNIT_ASSERT_EQUAL(2,(int)v4.size()); CPPUNIT_ASSERT_EQUAL(0,(int)v3.getNumberOfAssociations()); + CPPUNIT_ASSERT(e1->getStartNode()==v4[0]); + v4[0]->decrRef(); v4[1]->decrRef(); + v4.clear(); v3.clear(); + delete intersector; e2->decrRef(); e1->decrRef(); + } +} + +void QuadraticPlanarInterpTest::IntersectArcCircleFull() +{ + double center1[2]; center1[0]=0.; center1[1]=0.; double radius1=3.; + double center2[2]; center2[0]=0.75; center2[1]=-2.6; double radius2=1.; + EdgeArcCircle *e1=buildArcOfCircle(center1,radius1,-M_PI/3.,4.*M_PI/3.); + EdgeArcCircle *e2=buildArcOfCircle(center2,radius2,0.,M_PI/2.); + MergePoints commonNode; + QuadraticPolygon pol1; QuadraticPolygon pol2; + QuadraticPolygon pol3; QuadraticPolygon pol4; + pol3.pushBack(e1); pol4.pushBack(e2); + CPPUNIT_ASSERT_DOUBLES_EQUAL(15.707963267948966,pol3.getPerimeter(),1e-6); + CPPUNIT_ASSERT_DOUBLES_EQUAL(1.5707963267949,pol4.getPerimeter(),1e-6); + CPPUNIT_ASSERT_DOUBLES_EQUAL(19.6648305849,pol3.getArea(),1e-6); + CPPUNIT_ASSERT_DOUBLES_EQUAL(-1.8146018366,pol4.getArea(),1e-6); + CPPUNIT_ASSERT(e1->intersectWith(e2,commonNode,pol1,pol2)); + CPPUNIT_ASSERT_EQUAL(2,pol1.size()); + CPPUNIT_ASSERT_EQUAL(2,pol2.size()); + CPPUNIT_ASSERT_DOUBLES_EQUAL(19.6648305849,pol1.getArea(),1e-6); + CPPUNIT_ASSERT_DOUBLES_EQUAL(-1.8146018366,pol2.getArea(),1e-6); + CPPUNIT_ASSERT_DOUBLES_EQUAL(15.707963267948966,pol1.getPerimeter(),1e-6); + CPPUNIT_ASSERT_DOUBLES_EQUAL(1.5707963267949,pol2.getPerimeter(),1e-6); + // + e1=buildArcOfCircle(center1,radius1,-2*M_PI/3.,-7.*M_PI/3.); + e2=buildArcOfCircle(center2,radius2,0.,M_PI/2.); + commonNode.clear(); + QuadraticPolygon pol5; QuadraticPolygon pol6; + QuadraticPolygon pol7; QuadraticPolygon pol8; + pol7.pushBack(e1); pol8.pushBack(e2); + CPPUNIT_ASSERT_DOUBLES_EQUAL(15.707963267948966,pol7.getPerimeter(),1e-6); + CPPUNIT_ASSERT_DOUBLES_EQUAL(1.5707963267949,pol8.getPerimeter(),1e-6); + CPPUNIT_ASSERT_DOUBLES_EQUAL(-19.6648305849,pol7.getArea(),1e-6); + CPPUNIT_ASSERT_DOUBLES_EQUAL(-1.8146018366,pol8.getArea(),1e-6); + CPPUNIT_ASSERT(e1->intersectWith(e2,commonNode,pol5,pol6)); + CPPUNIT_ASSERT_EQUAL(2,pol5.size()); + CPPUNIT_ASSERT_EQUAL(2,pol6.size()); + CPPUNIT_ASSERT_DOUBLES_EQUAL(-19.6648305849,pol5.getArea(),1e-6); + CPPUNIT_ASSERT_DOUBLES_EQUAL(-1.8146018366,pol6.getArea(),1e-6); + CPPUNIT_ASSERT_DOUBLES_EQUAL(15.707963267948966,pol5.getPerimeter(),1e-6); + CPPUNIT_ASSERT_DOUBLES_EQUAL(1.5707963267949,pol6.getPerimeter(),1e-6); + // + center2[0]=3.5; center2[1]=0.; + e1=buildArcOfCircle(center1,radius1,-2*M_PI/3.,-7.*M_PI/3.); + e2=buildArcOfCircle(center2,radius2,M_PI/2.,3*M_PI/2.); + commonNode.clear(); + QuadraticPolygon pol9; QuadraticPolygon pol10; + QuadraticPolygon pol11; QuadraticPolygon pol12; + pol11.pushBack(e1); pol12.pushBack(e2); + CPPUNIT_ASSERT_DOUBLES_EQUAL(15.707963267948966,pol11.getPerimeter(),1e-6); + CPPUNIT_ASSERT_DOUBLES_EQUAL(3.1415926535897931,pol12.getPerimeter(),1e-6); + CPPUNIT_ASSERT_DOUBLES_EQUAL(-19.6648305849,pol11.getArea(),1e-6); + CPPUNIT_ASSERT_DOUBLES_EQUAL(1.5707963267949,pol12.getArea(),1e-6); + CPPUNIT_ASSERT(e1->intersectWith(e2,commonNode,pol9,pol10)); + CPPUNIT_ASSERT_EQUAL(3,pol9.size()); + CPPUNIT_ASSERT_EQUAL(3,pol10.size()); + CPPUNIT_ASSERT_DOUBLES_EQUAL(15.707963267948966,pol9.getPerimeter(),1e-6); + CPPUNIT_ASSERT_DOUBLES_EQUAL(3.1415926535897931,pol10.getPerimeter(),1e-6); + CPPUNIT_ASSERT_DOUBLES_EQUAL(-19.6648305849,pol9.getArea(),1e-6); + CPPUNIT_ASSERT_DOUBLES_EQUAL(1.5707963267949,pol10.getArea(),1e-6); + // + center2[0]=0.; center2[1]=0.; radius2=radius1; + e1=buildArcOfCircle(center1,radius1,-2*M_PI/3.,-7.*M_PI/3.); + e2=buildArcOfCircle(center2,radius2,M_PI/3.,2*M_PI/3.); + commonNode.clear(); + QuadraticPolygon pol13; QuadraticPolygon pol14; + QuadraticPolygon pol15; QuadraticPolygon pol16; + pol15.pushBack(e1); pol16.pushBack(e2); + CPPUNIT_ASSERT_DOUBLES_EQUAL(15.707963267948966,pol15.getPerimeter(),1e-6); + CPPUNIT_ASSERT_DOUBLES_EQUAL(3.1415926535897931,pol16.getPerimeter(),1e-6); + CPPUNIT_ASSERT_DOUBLES_EQUAL(-19.6648305849,pol15.getArea(),1e-6); + CPPUNIT_ASSERT_DOUBLES_EQUAL(8.6095032974147,pol16.getArea(),1e-6); + CPPUNIT_ASSERT(e1->intersectWith(e2,commonNode,pol13,pol14)); + CPPUNIT_ASSERT_EQUAL(3,pol13.size()); + CPPUNIT_ASSERT_EQUAL(1,pol14.size()); + CPPUNIT_ASSERT_DOUBLES_EQUAL(15.707963267948966,pol13.getPerimeter(),1e-6); + CPPUNIT_ASSERT_DOUBLES_EQUAL(-19.6648305849,pol13.getArea(),1e-6); + CPPUNIT_ASSERT_DOUBLES_EQUAL(3.1415926535897931,pol14.getPerimeter(),1e-6); + CPPUNIT_ASSERT_DOUBLES_EQUAL(8.6095032974147,pol14.getArea(),1e-6); + // + e1=buildArcOfCircle(center1,radius1,-2*M_PI/3.,-7.*M_PI/3.); + e2=buildArcOfCircle(center2,radius2,2*M_PI/3.,M_PI/3.); + commonNode.clear(); + QuadraticPolygon pol17; QuadraticPolygon pol18; + QuadraticPolygon pol19; QuadraticPolygon pol20; + pol19.pushBack(e1); pol20.pushBack(e2); + CPPUNIT_ASSERT_DOUBLES_EQUAL(15.707963267948966,pol19.getPerimeter(),1e-6); + CPPUNIT_ASSERT_DOUBLES_EQUAL(3.1415926535897931,pol20.getPerimeter(),1e-6); + CPPUNIT_ASSERT_DOUBLES_EQUAL(-19.6648305849,pol19.getArea(),1e-6); + CPPUNIT_ASSERT_DOUBLES_EQUAL(-8.6095032974147,pol20.getArea(),1e-6); + CPPUNIT_ASSERT(e1->intersectWith(e2,commonNode,pol17,pol18)); + CPPUNIT_ASSERT_EQUAL(3,pol17.size()); + CPPUNIT_ASSERT_EQUAL(1,pol18.size()); + CPPUNIT_ASSERT_DOUBLES_EQUAL(15.707963267948966,pol17.getPerimeter(),1e-6); + CPPUNIT_ASSERT_DOUBLES_EQUAL(-19.6648305849,pol17.getArea(),1e-6); + CPPUNIT_ASSERT_DOUBLES_EQUAL(3.1415926535897931,pol18.getPerimeter(),1e-6); + CPPUNIT_ASSERT_DOUBLES_EQUAL(-8.6095032974147,pol18.getArea(),1e-6); + //no intersection #1 + center2[0]=4.277; center2[1]=-4.277; + e1=buildArcOfCircle(center1,radius1,-2*M_PI/3.,-7.*M_PI/3.); + e2=buildArcOfCircle(center2,radius2,M_PI/4.,5*M_PI/4.); + QuadraticPolygon polTemp1; QuadraticPolygon polTemp2; + CPPUNIT_ASSERT(!e1->intersectWith(e2,commonNode,polTemp1,polTemp2)); + e1->decrRef(); e2->decrRef(); + //no intersection #2 + center2[0]=1.; center2[1]=-1.; radius2=0.2; + e1=buildArcOfCircle(center1,radius1,-2*M_PI/3.,-7.*M_PI/3.); + e2=buildArcOfCircle(center2,radius2,M_PI/4.,5*M_PI/4.); + CPPUNIT_ASSERT(!e1->intersectWith(e2,commonNode,polTemp1,polTemp2)); + e1->decrRef(); e2->decrRef(); +} + +void QuadraticPlanarInterpTest::IntersectArcCircleSegumentBase() +{ + double center[2]={2.,2.}; + EdgeArcCircle *e1=buildArcOfCircle(center,2.3,M_PI/4.,5.*M_PI/4.); + EdgeLin *e2=new EdgeLin(-1.3,1.,3.,5.3); + EdgeIntersector *intersector=new ArcCSegIntersector(*e1,*e2); + bool order; + bool obvious,areOverlapped; + intersector->areOverlappedOrOnlyColinears(0,obvious,areOverlapped); + CPPUNIT_ASSERT(!obvious && !areOverlapped); + std::vector<Node *> v4; + MergePoints v3; + CPPUNIT_ASSERT(intersector->intersect(0,v4,order,v3)); CPPUNIT_ASSERT(!order); CPPUNIT_ASSERT_EQUAL(2,(int)v4.size()); CPPUNIT_ASSERT_EQUAL(0,(int)v3.getNumberOfAssociations()); + CPPUNIT_ASSERT_DOUBLES_EQUAL(2.,(*v4[0])[0],1e-10); CPPUNIT_ASSERT_DOUBLES_EQUAL(4.3,(*v4[0])[1],1e-10); + CPPUNIT_ASSERT_DOUBLES_EQUAL(-0.3,(*v4[1])[0],1e-10); CPPUNIT_ASSERT_DOUBLES_EQUAL(2.,(*v4[1])[1],1e-10); + v4[0]->decrRef(); v4[1]->decrRef(); e2->decrRef(); v3.clear(); v4.clear(); delete intersector; + // + e2=new EdgeLin(3.,5.3,-1.3,1.); + intersector=new ArcCSegIntersector(*e1,*e2); + intersector->areOverlappedOrOnlyColinears(0,obvious,areOverlapped); CPPUNIT_ASSERT(!obvious && !areOverlapped); + CPPUNIT_ASSERT(intersector->intersect(0,v4,order,v3)); CPPUNIT_ASSERT(order); CPPUNIT_ASSERT_EQUAL(2,(int)v4.size()); CPPUNIT_ASSERT_EQUAL(0,(int)v3.getNumberOfAssociations()); + CPPUNIT_ASSERT_DOUBLES_EQUAL(2.,(*v4[0])[0],1e-10); CPPUNIT_ASSERT_DOUBLES_EQUAL(4.3,(*v4[0])[1],1e-10); + CPPUNIT_ASSERT_DOUBLES_EQUAL(-0.3,(*v4[1])[0],1e-10); CPPUNIT_ASSERT_DOUBLES_EQUAL(2.,(*v4[1])[1],1e-10); + v4[0]->decrRef(); v4[1]->decrRef(); e2->decrRef(); v3.clear(); v4.clear(); delete intersector; + // tangent intersection + e2=new EdgeLin(-1.,4.3,3.,4.3); + intersector=new ArcCSegIntersector(*e1,*e2); + intersector->areOverlappedOrOnlyColinears(0,obvious,areOverlapped); CPPUNIT_ASSERT(!obvious && !areOverlapped); + CPPUNIT_ASSERT(intersector->intersect(0,v4,order,v3)); CPPUNIT_ASSERT(order); CPPUNIT_ASSERT_EQUAL(1,(int)v4.size()); CPPUNIT_ASSERT_EQUAL(0,(int)v3.getNumberOfAssociations()); + CPPUNIT_ASSERT_DOUBLES_EQUAL(2.,(*v4[0])[0],1e-10); CPPUNIT_ASSERT_DOUBLES_EQUAL(4.3,(*v4[0])[1],1e-10); + v4[0]->decrRef(); e2->decrRef(); v3.clear(); delete intersector; + // no intersection + e2=new EdgeLin(-2.,-2.,-1.,-3.); + intersector=new ArcCSegIntersector(*e1,*e2); + intersector->areOverlappedOrOnlyColinears(0,obvious,areOverlapped); CPPUNIT_ASSERT(obvious && !areOverlapped); + e2->decrRef(); v3.clear(); delete intersector; + // + e1->decrRef(); +} + +QuadraticPolygon *QuadraticPlanarInterpTest::buildQuadraticPolygonCoarseInfo(const double *coords, const int *conn, int lgth) +{ + std::vector<INTERP_KERNEL::Node *> nodes; + for(int i=0;i<lgth;i++) + nodes.push_back(new INTERP_KERNEL::Node(coords[2*conn[i]],coords[2*conn[i]+1])); + return INTERP_KERNEL::QuadraticPolygon::BuildArcCirclePolygon(nodes); +} + +EdgeArcCircle *QuadraticPlanarInterpTest::buildArcOfCircle(const double *center, double radius, double alphaStart, double alphaEnd) +{ + double alphaM=(alphaStart+alphaEnd)/2; + return new EdgeArcCircle(center[0]+cos(alphaStart)*radius,center[1]+sin(alphaStart)*radius, + center[0]+cos(alphaM)*radius,center[1]+sin(alphaM)*radius, + center[0]+cos(alphaEnd)*radius,center[1]+sin(alphaEnd)*radius); +} + +double QuadraticPlanarInterpTest::btw2NodesAndACenter(const Node& n1, const Node& n2, const double *center) +{ + const double *n1Pt=n1; + const double *n2Pt=n2; + double tmp1[2],tmp2[2]; + tmp1[0]=n1Pt[0]-center[0]; tmp1[1]=n1Pt[1]-center[1]; + tmp2[0]=n2Pt[0]-center[0]; tmp2[1]=n2Pt[1]-center[1]; + double distTmp1=sqrt(tmp1[0]*tmp1[0]+tmp1[1]*tmp1[1]); + double distTmp2=sqrt(tmp2[0]*tmp2[0]+tmp2[1]*tmp2[1]); + double ret=acos((tmp1[0]*tmp2[0]+tmp1[1]*tmp2[1])/(distTmp1*distTmp2)); + if(tmp1[0]*tmp2[1]-tmp1[1]*tmp2[0]<0) + ret=-ret; + return ret; +} + +} diff --git a/src/medtool/src/INTERP_KERNELTest/QuadraticPlanarInterpTest3.cxx b/src/medtool/src/INTERP_KERNELTest/QuadraticPlanarInterpTest3.cxx new file mode 100644 index 000000000..5b6bb3ad2 --- /dev/null +++ b/src/medtool/src/INTERP_KERNELTest/QuadraticPlanarInterpTest3.cxx @@ -0,0 +1,327 @@ +// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 +// 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 "QuadraticPlanarInterpTest.hxx" +#include "InterpKernelGeo2DQuadraticPolygon.hxx" +#include "InterpKernelGeo2DElementaryEdge.hxx" +#include "InterpKernelGeo2DEdgeArcCircle.hxx" +#include "InterpKernelGeo2DEdgeLin.hxx" + +#include <cmath> +#include <sstream> +#include <iostream> + +using namespace INTERP_KERNEL; + +namespace INTERP_TEST +{ + +void QuadraticPlanarInterpTest::checkInOutDetection() +{ + Node *n1=new Node(0.,0.); + Node *n2=new Node(1.,0.); + Node *n3=new Node(0.5,1.); + EdgeLin *e1=new EdgeLin(n1,n2); + EdgeLin *e2=new EdgeLin(n2,n3); + EdgeLin *e3=new EdgeLin(n3,n1); + ComposedEdge *tri=new ComposedEdge; + tri->pushBack(e1); tri->pushBack(e2); tri->pushBack(e3); + // + Node *where=new Node(0.4,0.1); + CPPUNIT_ASSERT(tri->isInOrOut(where)); where->decrRef(); + where=new Node(-0.1,1.); + CPPUNIT_ASSERT(!tri->isInOrOut(where)); where->decrRef(); + where=new Node(0.6,-0.1); + CPPUNIT_ASSERT(!tri->isInOrOut(where)); where->decrRef(); + //Clean-up + n1->decrRef(); n2->decrRef(); n3->decrRef(); + ComposedEdge::Delete(tri); +} + +/*! + * Check Iterators mechanism. + */ +void QuadraticPlanarInterpTest::checkAssemblingBases1() +{ + Node *n1=new Node(0.,0.); + Node *n2=new Node(0.1,0.); EdgeLin *e1_2=new EdgeLin(n1,n2); + Node *n3=new Node(0.2,0.); EdgeLin *e2_3=new EdgeLin(n2,n3); + Node *n4=new Node(0.3,0.); EdgeLin *e3_4=new EdgeLin(n3,n4); + Node *n5=new Node(0.4,0.); EdgeLin *e4_5=new EdgeLin(n4,n5); + Node *n6=new Node(0.5,0.); EdgeLin *e5_6=new EdgeLin(n5,n6); + Node *n7=new Node(0.6,0.); EdgeLin *e6_7=new EdgeLin(n6,n7); + Node *n8=new Node(0.7,0.); EdgeLin *e7_8=new EdgeLin(n7,n8); + Node *n9=new Node(0.8,0.); EdgeLin *e8_9=new EdgeLin(n8,n9); + Node *n10=new Node(0.9,0.); EdgeLin *e9_10=new EdgeLin(n9,n10); + Node *n11=new Node(1.,0.); EdgeLin *e10_11=new EdgeLin(n10,n11); + Node *n12=new Node(0.5,1.); EdgeLin *e11_12=new EdgeLin(n11,n12); + EdgeLin *e12_1=new EdgeLin(n12,n1); + //Only one level + e1_2->incrRef(); e2_3->incrRef(); e3_4->incrRef(); e4_5->incrRef(); e5_6->incrRef(); e6_7->incrRef(); + e7_8->incrRef(); e8_9->incrRef(); e9_10->incrRef(); e10_11->incrRef(); e11_12->incrRef(); e12_1->incrRef(); + ComposedEdge *c=new ComposedEdge; + c->pushBack(e1_2); c->pushBack(e2_3); c->pushBack(e3_4); c->pushBack(e4_5); c->pushBack(e5_6); c->pushBack(e6_7); + c->pushBack(e7_8); c->pushBack(e8_9); c->pushBack(e9_10); c->pushBack(e10_11); c->pushBack(e11_12); c->pushBack(e12_1); + CPPUNIT_ASSERT_EQUAL(12,c->recursiveSize()); + IteratorOnComposedEdge it(c); + CPPUNIT_ASSERT(it.current()->getPtr()==e1_2); CPPUNIT_ASSERT(!it.finished()); + it.next(); CPPUNIT_ASSERT(it.current()->getPtr()==e2_3); CPPUNIT_ASSERT(!it.finished()); + it.next(); it.next(); CPPUNIT_ASSERT(it.current()->getPtr()==e4_5); CPPUNIT_ASSERT(!it.finished()); + it.previousLoop(); CPPUNIT_ASSERT(it.current()->getPtr()==e3_4); CPPUNIT_ASSERT(!it.finished()); + it.previousLoop(); CPPUNIT_ASSERT(it.current()->getPtr()==e2_3); CPPUNIT_ASSERT(!it.finished()); + it.previousLoop(); CPPUNIT_ASSERT(it.current()->getPtr()==e1_2); CPPUNIT_ASSERT(!it.finished()); + it.previousLoop(); CPPUNIT_ASSERT(it.current()->getPtr()==e12_1); CPPUNIT_ASSERT(!it.finished()); + it.next(); CPPUNIT_ASSERT(it.finished()); + it.first(); CPPUNIT_ASSERT(it.current()->getPtr()==e1_2); CPPUNIT_ASSERT(!it.finished()); + it.previousLoop(); CPPUNIT_ASSERT(it.current()->getPtr()==e12_1); CPPUNIT_ASSERT(!it.finished()); + it.nextLoop(); CPPUNIT_ASSERT(it.current()->getPtr()==e1_2); CPPUNIT_ASSERT(!it.finished()); + it.last(); CPPUNIT_ASSERT(it.current()->getPtr()==e12_1); CPPUNIT_ASSERT(!it.finished()); + //Multi-Level + ComposedEdge::Delete(c); + //(e1_2, (e2_3,(e3_4, e4_5, e5_6, e6_7, (e7_8, e8_9 ), ( e9_10 , e10_11 ), e11_12 ),e12_1 ) ) + e1_2->incrRef(); e2_3->incrRef(); e3_4->incrRef(); e4_5->incrRef(); e5_6->incrRef(); e6_7->incrRef(); + e7_8->incrRef(); e8_9->incrRef(); e9_10->incrRef(); e10_11->incrRef(); e11_12->incrRef(); e12_1->incrRef(); + ComposedEdge *c2_2_4=new ComposedEdge; c2_2_4->pushBack(e7_8); c2_2_4->pushBack(e8_9); + ComposedEdge *c2_2_5=new ComposedEdge; c2_2_5->pushBack(e9_10); c2_2_5->pushBack(e10_11); + ComposedEdge *c2_2=new ComposedEdge; c2_2->pushBack(e3_4); c2_2->pushBack(e4_5); c2_2->pushBack(e5_6); c2_2->pushBack(e6_7); c2_2->pushBack(c2_2_4); c2_2->pushBack(c2_2_5); c2_2->pushBack(e11_12); + ComposedEdge *c2=new ComposedEdge; c2->pushBack(e2_3); c2->pushBack(c2_2); c2->pushBack(e12_1); + c=new ComposedEdge; c->pushBack(e1_2); c->pushBack(c2); CPPUNIT_ASSERT_EQUAL(12,c->recursiveSize()); + IteratorOnComposedEdge it2(c); + CPPUNIT_ASSERT(it2.current()->getPtr()==e1_2); + it2.next(); CPPUNIT_ASSERT(it2.current()->getPtr()==e2_3); CPPUNIT_ASSERT(!it2.finished()); + it2.next(); CPPUNIT_ASSERT(it2.current()->getPtr()==e3_4); CPPUNIT_ASSERT(!it2.finished()); + it2.next(); CPPUNIT_ASSERT(it2.current()->getPtr()==e4_5); CPPUNIT_ASSERT(!it2.finished()); + it2.previousLoop(); CPPUNIT_ASSERT(it2.current()->getPtr()==e3_4); CPPUNIT_ASSERT(!it2.finished()); + it2.previousLoop(); CPPUNIT_ASSERT(it2.current()->getPtr()==e2_3); CPPUNIT_ASSERT(!it2.finished()); + it2.previousLoop(); CPPUNIT_ASSERT(it2.current()->getPtr()==e1_2); CPPUNIT_ASSERT(!it2.finished()); + it2.previousLoop(); CPPUNIT_ASSERT(it2.current()->getPtr()==e12_1); CPPUNIT_ASSERT(!it2.finished()); + it2.next(); CPPUNIT_ASSERT(it2.finished()); + it2.first(); CPPUNIT_ASSERT(it2.current()->getPtr()==e1_2); CPPUNIT_ASSERT(!it2.finished()); + it2.previousLoop(); CPPUNIT_ASSERT(it2.current()->getPtr()==e12_1); CPPUNIT_ASSERT(!it2.finished()); + it2.nextLoop(); CPPUNIT_ASSERT(it2.current()->getPtr()==e1_2); CPPUNIT_ASSERT(!it2.finished()); + it2.last(); CPPUNIT_ASSERT(it2.current()->getPtr()==e12_1); CPPUNIT_ASSERT(!it2.finished()); + it2.first(); CPPUNIT_ASSERT(it2.current()->getPtr()==e1_2); CPPUNIT_ASSERT(!it2.finished()); + it2.nextLoop(); CPPUNIT_ASSERT(it2.current()->getPtr()==e2_3); CPPUNIT_ASSERT(!it2.finished()); + it2.nextLoop(); CPPUNIT_ASSERT(it2.current()->getPtr()==e3_4); CPPUNIT_ASSERT(!it2.finished()); + it2.nextLoop(); CPPUNIT_ASSERT(it2.current()->getPtr()==e4_5); CPPUNIT_ASSERT(!it2.finished()); + // substitutions. + /*it2.first(); CPPUNIT_ASSERT(it2.current()->getPtr()==e1_2); CPPUNIT_ASSERT(!it2.finished()); + ElementaryEdge *&tmp=it2.current(); CPPUNIT_ASSERT(it2.current()->getPtr()==e1_2); CPPUNIT_ASSERT(!it2.finished()); + ComposedEdge *c1=new ComposedEdge; Node *n1_bis=new Node(0.,0.05); EdgeLin *e1_1bis=new EdgeLin(n1,n1_bis); EdgeLin *e1bis_2=new EdgeLin(n1_bis,n2); e1_1bis->incrRef(); e1bis_2->incrRef(); + c1->pushBack(e1_1bis); c1->pushBack(e1bis_2); delete tmp; tmp=(ElementaryEdge *)c1; CPPUNIT_ASSERT_EQUAL(13,c->recursiveSize()); + CPPUNIT_ASSERT(it2.current()->getPtr()==e1_1bis); CPPUNIT_ASSERT(!it2.finished());// here testing capability of Iterator.'current' method to deal with change of hierarchy. + it2.next(); CPPUNIT_ASSERT(it2.current()->getPtr()==e1bis_2); CPPUNIT_ASSERT(!it2.finished()); + it2.next(); CPPUNIT_ASSERT(it2.current()->getPtr()==e2_3); CPPUNIT_ASSERT(!it2.finished()); + it2.previousLoop(); CPPUNIT_ASSERT(it2.current()->getPtr()==e1bis_2); CPPUNIT_ASSERT(!it2.finished()); + it2.previousLoop(); CPPUNIT_ASSERT(it2.current()->getPtr()==e1_1bis); CPPUNIT_ASSERT(!it2.finished()); + it2.previousLoop(); CPPUNIT_ASSERT(it2.current()->getPtr()==e12_1); CPPUNIT_ASSERT(!it2.finished()); + it2.previousLoop(); CPPUNIT_ASSERT(it2.current()->getPtr()==e11_12); CPPUNIT_ASSERT(!it2.finished()); + it2.previousLoop(); CPPUNIT_ASSERT(it2.current()->getPtr()==e10_11); CPPUNIT_ASSERT(!it2.finished()); + it2.previousLoop(); CPPUNIT_ASSERT(it2.current()->getPtr()==e9_10); CPPUNIT_ASSERT(!it2.finished()); + it2.previousLoop(); CPPUNIT_ASSERT(it2.current()->getPtr()==e8_9); CPPUNIT_ASSERT(!it2.finished()); + it2.previousLoop(); CPPUNIT_ASSERT(it2.current()->getPtr()==e7_8); CPPUNIT_ASSERT(!it2.finished()); + it2.previousLoop(); CPPUNIT_ASSERT(it2.current()->getPtr()==e6_7); CPPUNIT_ASSERT(!it2.finished()); + it2.previousLoop(); CPPUNIT_ASSERT(it2.current()->getPtr()==e5_6); CPPUNIT_ASSERT(!it2.finished()); + it2.previousLoop(); CPPUNIT_ASSERT(it2.current()->getPtr()==e4_5); CPPUNIT_ASSERT(!it2.finished()); + it2.previousLoop(); CPPUNIT_ASSERT(it2.current()->getPtr()==e3_4); CPPUNIT_ASSERT(!it2.finished()); + it2.previousLoop(); CPPUNIT_ASSERT(it2.current()->getPtr()==e2_3); CPPUNIT_ASSERT(!it2.finished()); + it2.previousLoop(); CPPUNIT_ASSERT(it2.current()->getPtr()==e1bis_2); CPPUNIT_ASSERT(!it2.finished()); + it2.previousLoop(); CPPUNIT_ASSERT(it2.current()->getPtr()==e1_1bis); CPPUNIT_ASSERT(!it2.finished()); + it2.previousLoop(); CPPUNIT_ASSERT(it2.current()->getPtr()==e12_1); CPPUNIT_ASSERT(!it2.finished()); + //go forward + it2.nextLoop(); CPPUNIT_ASSERT(it2.current()->getPtr()==e1_1bis); CPPUNIT_ASSERT(!it2.finished()); + it2.nextLoop(); CPPUNIT_ASSERT(it2.current()->getPtr()==e1bis_2); CPPUNIT_ASSERT(!it2.finished()); + it2.nextLoop(); CPPUNIT_ASSERT(it2.current()->getPtr()==e2_3); CPPUNIT_ASSERT(!it2.finished()); + it2.nextLoop(); CPPUNIT_ASSERT(it2.current()->getPtr()==e3_4); CPPUNIT_ASSERT(!it2.finished()); + it2.nextLoop(); CPPUNIT_ASSERT(it2.current()->getPtr()==e4_5); CPPUNIT_ASSERT(!it2.finished()); + it2.nextLoop(); CPPUNIT_ASSERT(it2.current()->getPtr()==e5_6); CPPUNIT_ASSERT(!it2.finished()); + it2.nextLoop(); CPPUNIT_ASSERT(it2.current()->getPtr()==e6_7); CPPUNIT_ASSERT(!it2.finished()); + it2.nextLoop(); CPPUNIT_ASSERT(it2.current()->getPtr()==e7_8); CPPUNIT_ASSERT(!it2.finished()); + it2.nextLoop(); CPPUNIT_ASSERT(it2.current()->getPtr()==e8_9); CPPUNIT_ASSERT(!it2.finished()); + it2.nextLoop(); CPPUNIT_ASSERT(it2.current()->getPtr()==e9_10); CPPUNIT_ASSERT(!it2.finished()); + it2.nextLoop(); CPPUNIT_ASSERT(it2.current()->getPtr()==e10_11); CPPUNIT_ASSERT(!it2.finished()); + it2.nextLoop(); CPPUNIT_ASSERT(it2.current()->getPtr()==e11_12); CPPUNIT_ASSERT(!it2.finished()); + it2.nextLoop(); CPPUNIT_ASSERT(it2.current()->getPtr()==e12_1); CPPUNIT_ASSERT(!it2.finished()); + it2.nextLoop(); CPPUNIT_ASSERT(it2.current()->getPtr()==e1_1bis); CPPUNIT_ASSERT(!it2.finished());*/ + ComposedEdge::SoftDelete(c2_2_4); + ComposedEdge::SoftDelete(c2_2_5); + ComposedEdge::SoftDelete(c2_2); + ComposedEdge::SoftDelete(c2); + ComposedEdge::Delete(c); + //clean-up + //e1_1bis->decrRef(); e1bis_2->decrRef(); + e1_2->decrRef(); e2_3->decrRef(); e3_4->decrRef(); e4_5->decrRef(); e5_6->decrRef(); e6_7->decrRef(); + e7_8->decrRef(); e8_9->decrRef(); e9_10->decrRef(); e10_11->decrRef(); e11_12->decrRef(); e12_1->decrRef(); + //n1_bis->decrRef(); + n1->decrRef(); n2->decrRef(); n3->decrRef(); n4->decrRef(); n5->decrRef(); n6->decrRef(); + n7->decrRef(); n8->decrRef(); n9->decrRef(); n10->decrRef(); n11->decrRef(); n12->decrRef(); +} + +/*! + * Check splitting of 2 polygons. After this operation, all ElementaryEdge are either in/out/on. + */ +void QuadraticPlanarInterpTest::checkAssemblingBases2() +{ + //The "most" basic test1 + Node *n1=new Node(0.,0.); Node *n4=new Node(0.,-0.3); + Node *n2=new Node(1.,0.); Node *n5=new Node(1.,-0.3); + Node *n3=new Node(0.5,1.); Node *n6=new Node(0.5,0.7); + EdgeLin *e1_2=new EdgeLin(n1,n2); EdgeLin *e4_5=new EdgeLin(n4,n5); + EdgeLin *e2_3=new EdgeLin(n2,n3); EdgeLin *e5_6=new EdgeLin(n5,n6); + EdgeLin *e3_1=new EdgeLin(n3,n1); EdgeLin *e6_4=new EdgeLin(n6,n4); + // + e1_2->incrRef(); e2_3->incrRef(); e3_1->incrRef(); e4_5->incrRef(); e5_6->incrRef(); e6_4->incrRef(); + QuadraticPolygon pol1; pol1.pushBack(e1_2); pol1.pushBack(e2_3); pol1.pushBack(e3_1); + QuadraticPolygon pol2; pol2.pushBack(e4_5); pol2.pushBack(e5_6); pol2.pushBack(e6_4); + QuadraticPolygon cpyPol1(pol1); int nbOfSplits=0; + cpyPol1.SplitPolygonsEachOther(pol1,pol2,nbOfSplits); + CPPUNIT_ASSERT_EQUAL(5,pol1.recursiveSize()); + CPPUNIT_ASSERT_EQUAL(5,pol2.recursiveSize());CPPUNIT_ASSERT_EQUAL(15,nbOfSplits); + checkBasicsOfPolygons(pol1,pol2,true); + CPPUNIT_ASSERT(pol2[1]->getEndNode()==pol1[1]->getEndNode()); + CPPUNIT_ASSERT(pol2[1]->getEndNode()->getLoc()==ON_1); + CPPUNIT_ASSERT(pol2[3]->getEndNode()==pol1[0]->getEndNode()); + CPPUNIT_ASSERT(pol2[3]->getEndNode()->getLoc()==ON_1); + cpyPol1.performLocatingOperation(pol2); + ElementaryEdge *tmp=dynamic_cast<ElementaryEdge *>(pol2[0]); CPPUNIT_ASSERT(tmp); CPPUNIT_ASSERT(tmp->getPtr()==e4_5); + CPPUNIT_ASSERT(tmp->getLoc()==FULL_OUT_1); + CPPUNIT_ASSERT(tmp->getLoc()==FULL_OUT_1); + tmp=dynamic_cast<ElementaryEdge *>(pol2[1]); CPPUNIT_ASSERT(tmp); + CPPUNIT_ASSERT(tmp->getLoc()==FULL_OUT_1); + tmp=dynamic_cast<ElementaryEdge *>(pol2[2]); CPPUNIT_ASSERT(tmp); + CPPUNIT_ASSERT(tmp->getLoc()==FULL_IN_1); + tmp=dynamic_cast<ElementaryEdge *>(pol2[3]); CPPUNIT_ASSERT(tmp); + CPPUNIT_ASSERT(tmp->getLoc()==FULL_IN_1); + tmp=dynamic_cast<ElementaryEdge *>(pol2[4]); CPPUNIT_ASSERT(tmp); + CPPUNIT_ASSERT(tmp->getLoc()==FULL_OUT_1); + //clean-up for test1 + e1_2->decrRef(); e2_3->decrRef(); e3_1->decrRef(); e4_5->decrRef(); e5_6->decrRef(); e6_4->decrRef(); + n1->decrRef(); n2->decrRef(); n3->decrRef(); n4->decrRef(); n5->decrRef(); n6->decrRef(); + + //Deeper test some extremities of pol2 are on edges of pol1. + + n1=new Node(0.,0.); n4=new Node(1.5,-0.5); + n2=new Node(1.,0.); n5=new Node(0.5,0.); + n3=new Node(0.5,1.); n6=new Node(0.75,0.5); Node *n7=new Node(2.,0.5); + e1_2=new EdgeLin(n1,n2); e2_3=new EdgeLin(n2,n3); e3_1=new EdgeLin(n3,n1); + EdgeLin *e5_4=new EdgeLin(n5,n4); EdgeLin *e4_7=new EdgeLin(n4,n7); EdgeLin *e7_6=new EdgeLin(n7,n6); EdgeLin *e6_5=new EdgeLin(n6,n5); + // + e1_2->incrRef(); e2_3->incrRef(); e3_1->incrRef(); e5_4->incrRef(); e4_7->incrRef(); e7_6->incrRef(); e6_5->incrRef(); + QuadraticPolygon pol3; pol3.pushBack(e1_2); pol3.pushBack(e2_3); pol3.pushBack(e3_1); + QuadraticPolygon pol4; pol4.pushBack(e5_4); pol4.pushBack(e4_7); pol4.pushBack(e7_6); pol4.pushBack(e6_5); + QuadraticPolygon cpyPol3(pol3); nbOfSplits=0; + cpyPol3.SplitPolygonsEachOther(pol3,pol4,nbOfSplits); + CPPUNIT_ASSERT_EQUAL(5,pol3.recursiveSize()); + CPPUNIT_ASSERT_EQUAL(4,pol4.recursiveSize());CPPUNIT_ASSERT_EQUAL(16,nbOfSplits); + checkBasicsOfPolygons(pol3,pol4,true); + CPPUNIT_ASSERT(pol4[0]->getStartNode()==pol3[0]->getEndNode()); CPPUNIT_ASSERT(pol4[0]->getStartNode()==n5); + CPPUNIT_ASSERT(n5->getLoc()==ON_LIM_1); + CPPUNIT_ASSERT(pol4[2]->getEndNode()==pol3[2]->getEndNode()); CPPUNIT_ASSERT(pol4[2]->getEndNode()==n6); + CPPUNIT_ASSERT(n6->getLoc()==ON_LIM_1); + cpyPol3.performLocatingOperation(pol4); + tmp=dynamic_cast<ElementaryEdge *>(pol4[1]); CPPUNIT_ASSERT(tmp); CPPUNIT_ASSERT(tmp->getPtr()==e4_7); + CPPUNIT_ASSERT(tmp->getLoc()==FULL_OUT_1); + tmp=dynamic_cast<ElementaryEdge *>(pol4[3]); CPPUNIT_ASSERT(tmp); CPPUNIT_ASSERT(tmp->getPtr()==e6_5); + tmp=dynamic_cast<ElementaryEdge *>(pol4[0]); CPPUNIT_ASSERT(tmp); CPPUNIT_ASSERT(tmp->getPtr()==e5_4); + CPPUNIT_ASSERT(tmp->getLoc()==FULL_OUT_1); + tmp=dynamic_cast<ElementaryEdge *>(pol4[2]); CPPUNIT_ASSERT(tmp); CPPUNIT_ASSERT(tmp->getPtr()==e7_6); + CPPUNIT_ASSERT(tmp->getLoc()==FULL_OUT_1); + tmp=dynamic_cast<ElementaryEdge *>(pol4[3]); CPPUNIT_ASSERT(tmp); CPPUNIT_ASSERT(tmp->getPtr()==e6_5); + CPPUNIT_ASSERT(tmp->getLoc()==FULL_IN_1); + //clean-up for test2 + e1_2->decrRef(); e2_3->decrRef(); e3_1->decrRef(); e5_4->decrRef(); e4_7->decrRef(); e7_6->decrRef(); e6_5->decrRef(); + n1->decrRef(); n2->decrRef(); n3->decrRef(); n4->decrRef(); n5->decrRef(); n6->decrRef(); n7->decrRef(); + + //Test with one edge of pol2 is included in pol1. + + n1=new Node(0.,0.); n4=new Node(-0.5,0.); + n2=new Node(1.,0.); n5=new Node(0.,-1.); + n3=new Node(0.5,1.); n6=new Node(0.5,0.); + e1_2=new EdgeLin(n1,n2); e2_3=new EdgeLin(n2,n3); e3_1=new EdgeLin(n3,n1); + e4_5=new EdgeLin(n4,n5); e5_6=new EdgeLin(n5,n6); e6_4=new EdgeLin(n6,n4); + e1_2->incrRef(); e2_3->incrRef(); e3_1->incrRef(); e4_5->incrRef(); e5_6->incrRef(); e6_4->incrRef(); + QuadraticPolygon pol5; pol5.pushBack(e1_2); pol5.pushBack(e2_3); pol5.pushBack(e3_1); + QuadraticPolygon pol6; pol6.pushBack(e4_5); pol6.pushBack(e5_6); pol6.pushBack(e6_4); + QuadraticPolygon cpyPol5(pol5); nbOfSplits=0; + cpyPol5.SplitPolygonsEachOther(pol5,pol6,nbOfSplits); + CPPUNIT_ASSERT_EQUAL(4,pol5.recursiveSize()); + CPPUNIT_ASSERT_EQUAL(4,pol6.recursiveSize()); CPPUNIT_ASSERT_EQUAL(13,nbOfSplits); + checkBasicsOfPolygons(pol5,pol6,false); + CPPUNIT_ASSERT(pol6[2]->getStartNode()==pol5[0]->getEndNode()); CPPUNIT_ASSERT(pol6[2]->getStartNode()==n6); + CPPUNIT_ASSERT(n6->getLoc()==ON_LIM_1); + CPPUNIT_ASSERT(pol6[2]->getEndNode()==pol5[0]->getStartNode()); CPPUNIT_ASSERT(pol5[0]->getStartNode()==n1); + CPPUNIT_ASSERT(n1->getLoc()==ON_LIM_1); + cpyPol5.performLocatingOperation(pol6); + tmp=dynamic_cast<ElementaryEdge *>(pol6[0]); CPPUNIT_ASSERT(tmp); CPPUNIT_ASSERT(tmp->getPtr()==e4_5); + CPPUNIT_ASSERT(tmp->getLoc()==FULL_OUT_1); + tmp=dynamic_cast<ElementaryEdge *>(pol6[1]); CPPUNIT_ASSERT(tmp); CPPUNIT_ASSERT(tmp->getPtr()==e5_6); + CPPUNIT_ASSERT(tmp->getLoc()==FULL_OUT_1); + tmp=dynamic_cast<ElementaryEdge *>(pol6[2]); CPPUNIT_ASSERT(tmp); + CPPUNIT_ASSERT(tmp->getLoc()==FULL_ON_1); + tmp=dynamic_cast<ElementaryEdge *>(pol6[3]); CPPUNIT_ASSERT(tmp); + CPPUNIT_ASSERT(tmp->getLoc()==FULL_OUT_1); + //clean-up test3 + e1_2->decrRef(); e2_3->decrRef(); e3_1->decrRef(); e4_5->decrRef(); e5_6->decrRef(); e6_4->decrRef(); + n1->decrRef(); n2->decrRef(); n3->decrRef(); n4->decrRef(); n5->decrRef(); n6->decrRef(); + + //Test of full overlapped polygons. + + n1=new Node(0.,0.); n4=new Node(0.,0.); + n2=new Node(1.,0.); n5=new Node(1.,0.); + n3=new Node(0.5,1.); n6=new Node(0.5,1.); + e1_2=new EdgeLin(n1,n2); e2_3=new EdgeLin(n2,n3); e3_1=new EdgeLin(n3,n1); + e4_5=new EdgeLin(n4,n5); e5_6=new EdgeLin(n5,n6); e6_4=new EdgeLin(n6,n4); + e1_2->incrRef(); e2_3->incrRef(); e3_1->incrRef(); e4_5->incrRef(); e5_6->incrRef(); e6_4->incrRef(); + QuadraticPolygon pol7; pol7.pushBack(e1_2); pol7.pushBack(e2_3); pol7.pushBack(e3_1); + QuadraticPolygon pol8; pol8.pushBack(e4_5); pol8.pushBack(e5_6); pol8.pushBack(e6_4); + QuadraticPolygon cpyPol7(pol7); nbOfSplits=0; + cpyPol7.SplitPolygonsEachOther(pol7,pol8,nbOfSplits); + tmp=dynamic_cast<ElementaryEdge *>(pol8[0]); CPPUNIT_ASSERT(tmp); CPPUNIT_ASSERT(tmp->getPtr()==e1_2); + CPPUNIT_ASSERT(tmp->getLoc()==FULL_ON_1); + tmp=dynamic_cast<ElementaryEdge *>(pol8[1]); CPPUNIT_ASSERT(tmp); CPPUNIT_ASSERT(tmp->getPtr()==e2_3); + CPPUNIT_ASSERT(tmp->getLoc()==FULL_ON_1); + tmp=dynamic_cast<ElementaryEdge *>(pol8[2]); CPPUNIT_ASSERT(tmp); CPPUNIT_ASSERT(tmp->getPtr()==e3_1); + CPPUNIT_ASSERT(tmp->getLoc()==FULL_ON_1); + //clean-up test4 + e1_2->decrRef(); e2_3->decrRef(); e3_1->decrRef(); e4_5->decrRef(); e5_6->decrRef(); e6_4->decrRef(); + n1->decrRef(); n2->decrRef(); n3->decrRef(); n4->decrRef(); n5->decrRef(); n6->decrRef(); +} + +void QuadraticPlanarInterpTest::checkBasicsOfPolygons(QuadraticPolygon& pol1, QuadraticPolygon& pol2, bool checkDirection) +{ + IteratorOnComposedEdge it1(&pol1),it2(&pol2); it1.previousLoop(); it2.previousLoop(); + Node *nIter1=it1.current()->getEndNode(); Node *nIter2=it2.current()->getEndNode(); + for(it2.first();!it2.finished();it2.next()) + { + CPPUNIT_ASSERT(nIter2==it2.current()->getStartNode()); + if(checkDirection) + CPPUNIT_ASSERT(it2.current()->getDirection()); + nIter2=it2.current()->getEndNode(); + } + for(it1.first();!it1.finished();it1.next()) + { + CPPUNIT_ASSERT(nIter1==it1.current()->getStartNode()); + if(checkDirection) + CPPUNIT_ASSERT(it1.current()->getDirection()); + nIter1=it1.current()->getEndNode(); + } +} + +} diff --git a/src/medtool/src/INTERP_KERNELTest/QuadraticPlanarInterpTest4.cxx b/src/medtool/src/INTERP_KERNELTest/QuadraticPlanarInterpTest4.cxx new file mode 100644 index 000000000..c9c34bd27 --- /dev/null +++ b/src/medtool/src/INTERP_KERNELTest/QuadraticPlanarInterpTest4.cxx @@ -0,0 +1,1685 @@ +// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 +// 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 "QuadraticPlanarInterpTest.hxx" +#include "InterpKernelGeo2DQuadraticPolygon.hxx" +#include "InterpKernelGeo2DElementaryEdge.hxx" +#include "InterpKernelGeo2DEdgeArcCircle.hxx" +#include "InterpKernelGeo2DEdgeLin.hxx" + +#include <cmath> +#include <sstream> +#include <iostream> +#include <iterator> + +using namespace INTERP_KERNEL; + +namespace INTERP_TEST +{ + +void QuadraticPlanarInterpTest::checkPolygonsIntersection1() +{ + //The "most" basic test1 + Node *n1=new Node(0.,0.); Node *n4=new Node(0.,-0.3); + Node *n2=new Node(1.,0.); Node *n5=new Node(1.,-0.3); + Node *n3=new Node(0.5,1.); Node *n6=new Node(0.5,0.7); + EdgeLin *e1_2=new EdgeLin(n1,n2); EdgeLin *e4_5=new EdgeLin(n4,n5); + EdgeLin *e2_3=new EdgeLin(n2,n3); EdgeLin *e5_6=new EdgeLin(n5,n6); + EdgeLin *e3_1=new EdgeLin(n3,n1); EdgeLin *e6_4=new EdgeLin(n6,n4); + // + std::vector<QuadraticPolygon *> result; + for(int k=0;k<2;k++) + for(int i=0;i<3;i++) + { + for(int j=0;j<1;j++) + { + e1_2->incrRef(); e2_3->incrRef(); e3_1->incrRef(); e4_5->incrRef(); e5_6->incrRef(); e6_4->incrRef(); + QuadraticPolygon pol1; pol1.circularPermute(); pol1.pushBack(e1_2); pol1.pushBack(e2_3); pol1.pushBack(e3_1); + for(int i1=0;i1<i;i1++) pol1.circularPermute(); if(k==1) pol1.reverse(); + QuadraticPolygon pol2; pol2.pushBack(e4_5); pol2.pushBack(e5_6); pol2.pushBack(e6_4); + for(int j1=0;j1<j;j1++) pol2.circularPermute(); + result=pol1.intersectMySelfWith(pol2); + CPPUNIT_ASSERT_EQUAL(1,(int)result.size()); checkBasicsOfPolygons(*result[0],*result[0],false); + CPPUNIT_ASSERT_EQUAL(3,result[0]->recursiveSize()); + double tmp1=0.,tmp2=0.,tmp3=0.; + pol1.intersectForPerimeter(pol2,tmp1,tmp2,tmp3); + std::vector<double> v1,v2; + std::vector<int> v3; + pol1.intersectForPerimeterAdvanced(pol2,v1,v2);//no common edge + pol1.intersectForPoint(pol2,v3); + CPPUNIT_ASSERT_EQUAL(3,(int)v1.size()); + CPPUNIT_ASSERT_EQUAL(3,(int)v2.size()); + CPPUNIT_ASSERT_EQUAL(3,(int)v3.size()); + if(k==0) + { + CPPUNIT_ASSERT_EQUAL(2,v3[(3-i)%3]); + CPPUNIT_ASSERT_EQUAL(0,v3[(4-i)%3]); + CPPUNIT_ASSERT_EQUAL(0,v3[(5-i)%3]); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.7,v1[(3-i)%3],1.e-14); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.,v1[(4-i)%3],1.e-14); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.,v1[(5-i)%3],1.e-14); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.,v2[0],1.e-14); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.78262379212492639,v2[1],1.e-14); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.78262379212492639,v2[2],1.e-14); + } + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.7,tmp1,1.e-14); + CPPUNIT_ASSERT_DOUBLES_EQUAL(1.5652475842498528,tmp2,1.e-14); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.,tmp3,1.e-14);//no common edge + delete result[0]; + } + } + //clean-up for test1 + e1_2->decrRef(); e2_3->decrRef(); e3_1->decrRef(); e4_5->decrRef(); e5_6->decrRef(); e6_4->decrRef(); + n1->decrRef(); n2->decrRef(); n3->decrRef(); n4->decrRef(); n5->decrRef(); n6->decrRef(); + + //Deeper test some extremities of pol2 are on edges of pol1. + + n1=new Node(0.,0.); n4=new Node(1.5,-0.5); + n2=new Node(1.,0.); n5=new Node(0.5,0.); + n3=new Node(0.5,1.); n6=new Node(0.75,0.5); Node *n7=new Node(2.,0.5); + e1_2=new EdgeLin(n1,n2); e2_3=new EdgeLin(n2,n3); e3_1=new EdgeLin(n3,n1); + EdgeLin *e5_4=new EdgeLin(n5,n4); EdgeLin *e4_7=new EdgeLin(n4,n7); EdgeLin *e7_6=new EdgeLin(n7,n6); EdgeLin *e6_5=new EdgeLin(n6,n5); + // + for(int k=0;k<2;k++) + for(int i=0;i<3;i++) + { + for(int j=0;j<4;j++) + { + e1_2->incrRef(); e2_3->incrRef(); e3_1->incrRef(); e5_4->incrRef(); e4_7->incrRef(); e7_6->incrRef(); e6_5->incrRef(); + QuadraticPolygon pol3; pol3.pushBack(e1_2); pol3.pushBack(e2_3); pol3.pushBack(e3_1); + for(int i1=0;i1<i;i1++) pol3.circularPermute(); if(k==1) pol3.reverse(); + QuadraticPolygon pol4; pol4.pushBack(e5_4); pol4.pushBack(e4_7); pol4.pushBack(e7_6); pol4.pushBack(e6_5); + for(int j1=0;j1<j;j1++) pol4.circularPermute(); + result=pol3.intersectMySelfWith(pol4); + CPPUNIT_ASSERT_EQUAL(1,(int)result.size()); checkBasicsOfPolygons(*result[0],*result[0],false); + CPPUNIT_ASSERT_EQUAL(3,result[0]->recursiveSize()); + delete result[0]; + } + } + //clean-up for test2 + e1_2->decrRef(); e2_3->decrRef(); e3_1->decrRef(); e5_4->decrRef(); e4_7->decrRef(); e7_6->decrRef(); e6_5->decrRef(); + n1->decrRef(); n2->decrRef(); n3->decrRef(); n4->decrRef(); n5->decrRef(); n6->decrRef(); n7->decrRef(); + + //Test with one edge of pol2 is included in pol1. + + n1=new Node(0.,0.); n4=new Node(-0.5,0.); + n2=new Node(1.,0.); n5=new Node(0.,-1.); + n3=new Node(0.5,1.); n6=new Node(0.5,0.); + e1_2=new EdgeLin(n1,n2); e2_3=new EdgeLin(n2,n3); e3_1=new EdgeLin(n3,n1); + e4_5=new EdgeLin(n4,n5); e5_6=new EdgeLin(n5,n6); e6_4=new EdgeLin(n6,n4); + for(int k=0;k<2;k++) + for(int i=0;i<3;i++) + { + for(int j=0;j<3;j++) + { + e1_2->incrRef(); e2_3->incrRef(); e3_1->incrRef(); e4_5->incrRef(); e5_6->incrRef(); e6_4->incrRef(); + QuadraticPolygon pol5; pol5.pushBack(e1_2); pol5.pushBack(e2_3); pol5.pushBack(e3_1); + for(int i1=0;i1<i;i1++) pol5.circularPermute(); if(k==1) pol5.reverse(); + QuadraticPolygon pol6; pol6.pushBack(e4_5); pol6.pushBack(e5_6); pol6.pushBack(e6_4); + for(int j1=0;j1<j;j1++) pol6.circularPermute(); + result=pol5.intersectMySelfWith(pol6); + CPPUNIT_ASSERT_EQUAL(0,(int)result.size()); + } + } + //clean-up test3 + e1_2->decrRef(); e2_3->decrRef(); e3_1->decrRef(); e4_5->decrRef(); e5_6->decrRef(); e6_4->decrRef(); + n1->decrRef(); n2->decrRef(); n3->decrRef(); n4->decrRef(); n5->decrRef(); n6->decrRef(); + + //Test of full overlapped polygons. + + n1=new Node(0.,0.); n4=new Node(0.,0.); + n2=new Node(1.,0.); n5=new Node(1.,0.); + n3=new Node(0.5,1.); n6=new Node(0.5,1.); + e1_2=new EdgeLin(n1,n2); e2_3=new EdgeLin(n2,n3); e3_1=new EdgeLin(n3,n1); + e4_5=new EdgeLin(n4,n5); e5_6=new EdgeLin(n5,n6); e6_4=new EdgeLin(n6,n4); + for(int k=0;k<2;k++) + for(int i=0;i<3;i++) + { + for(int j=0;j<3;j++) + { + e1_2->incrRef(); e2_3->incrRef(); e3_1->incrRef(); e4_5->incrRef(); e5_6->incrRef(); e6_4->incrRef(); + QuadraticPolygon pol7; pol7.pushBack(e1_2); pol7.pushBack(e2_3); pol7.pushBack(e3_1); + for(int i1=0;i1<i;i1++) pol7.circularPermute(); if(k==1) pol7.reverse(); + QuadraticPolygon pol8; pol8.pushBack(e4_5); pol8.pushBack(e5_6); pol8.pushBack(e6_4); + for(int j1=0;j1<j;j1++) pol8.circularPermute(); + result=pol7.intersectMySelfWith(pol8); + CPPUNIT_ASSERT_EQUAL(1,(int)result.size()); checkBasicsOfPolygons(*result[0],*result[0],false); + CPPUNIT_ASSERT_EQUAL(3,result[0]->recursiveSize()); + delete result[0]; + double tmp1=0.,tmp2=0.,tmp3=0.; + pol7.intersectForPerimeter(pol8,tmp1,tmp2,tmp3); + std::vector<double> v1,v2; + pol7.intersectForPerimeterAdvanced(pol8,v1,v2);//only common edges. + CPPUNIT_ASSERT_DOUBLES_EQUAL(3.2360679774997898,v1[0]+v1[1]+v1[2],1.e-14); + CPPUNIT_ASSERT_DOUBLES_EQUAL(3.2360679774997898,v2[0]+v2[1]+v2[2],1.e-14); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.,tmp1,1.e-14); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.,tmp2,1.e-14); + CPPUNIT_ASSERT_DOUBLES_EQUAL(3.2360679774997898,tmp3,1.e-14); + } + } + //clean-up test4 + e1_2->decrRef(); e2_3->decrRef(); e3_1->decrRef(); e4_5->decrRef(); e5_6->decrRef(); e6_4->decrRef(); + n1->decrRef(); n2->decrRef(); n3->decrRef(); n4->decrRef(); n5->decrRef(); n6->decrRef(); + + //Test of closing process + + n1=new Node(0.,0.); n4=new Node(0.539,-0.266); + n2=new Node(1.,0.); n5=new Node(1.039,0.6); + n3=new Node(0.5,1.); n6=new Node(-0.077,0.667); + e1_2=new EdgeLin(n1,n2); e2_3=new EdgeLin(n2,n3); e3_1=new EdgeLin(n3,n1); + e4_5=new EdgeLin(n4,n5); e5_6=new EdgeLin(n5,n6); e6_4=new EdgeLin(n6,n4); + for(int k=0;k<2;k++) + for(int i=0;i<3;i++) + { + for(int j=0;j<3;j++) + { + e1_2->incrRef(); e2_3->incrRef(); e3_1->incrRef(); e4_5->incrRef(); e5_6->incrRef(); e6_4->incrRef(); + QuadraticPolygon pol9; pol9.pushBack(e1_2); pol9.pushBack(e2_3); pol9.pushBack(e3_1); + for(int i1=0;i1<i;i1++) pol9.circularPermute(); if(k==1) pol9.reverse(); + QuadraticPolygon pol10; pol10.pushBack(e5_6); pol10.pushBack(e6_4); pol10.pushBack(e4_5); + for(int j1=0;j1<j;j1++) pol10.circularPermute(); + result=pol9.intersectMySelfWith(pol10); + CPPUNIT_ASSERT_EQUAL(1,(int)result.size()); checkBasicsOfPolygons(*result[0],*result[0],false); + CPPUNIT_ASSERT_EQUAL(6,result[0]->recursiveSize()); + delete result[0]; + } + } + //clean-up test5 + e1_2->decrRef(); e2_3->decrRef(); e3_1->decrRef(); e4_5->decrRef(); e5_6->decrRef(); e6_4->decrRef(); + n1->decrRef(); n2->decrRef(); n3->decrRef(); n4->decrRef(); n5->decrRef(); n6->decrRef(); + + // Full in case + + n1=new Node(0.,0.); n4=new Node(0.3,0.1); + n2=new Node(1.,0.); n5=new Node(0.7,0.1); + n3=new Node(0.5,1.); n6=new Node(0.5,0.7); + e1_2=new EdgeLin(n1,n2); e2_3=new EdgeLin(n2,n3); e3_1=new EdgeLin(n3,n1); + e4_5=new EdgeLin(n4,n5); e5_6=new EdgeLin(n5,n6); e6_4=new EdgeLin(n6,n4); + for(int k=0;k<2;k++) + for(int i=0;i<3;i++) + { + for(int j=0;j<3;j++) + { + e1_2->incrRef(); e2_3->incrRef(); e3_1->incrRef(); e4_5->incrRef(); e5_6->incrRef(); e6_4->incrRef(); + QuadraticPolygon pol11; pol11.pushBack(e1_2); pol11.pushBack(e2_3); pol11.pushBack(e3_1); + for(int i1=0;i1<i;i1++) pol11.circularPermute(); if(k==1) pol11.reverse(); + QuadraticPolygon pol12; pol12.pushBack(e5_6); pol12.pushBack(e6_4); pol12.pushBack(e4_5); + for(int j1=0;j1<j;j1++) pol12.circularPermute(); + result=pol11.intersectMySelfWith(pol12); + CPPUNIT_ASSERT_EQUAL(1,(int)result.size()); checkBasicsOfPolygons(*result[0],*result[0],false); + CPPUNIT_ASSERT_EQUAL(3,result[0]->recursiveSize()); + delete result[0]; + } + } + //clean-up test6 + e1_2->decrRef(); e2_3->decrRef(); e3_1->decrRef(); e4_5->decrRef(); e5_6->decrRef(); e6_4->decrRef(); + n1->decrRef(); n2->decrRef(); n3->decrRef(); n4->decrRef(); n5->decrRef(); n6->decrRef(); + + // Full out case + + n1=new Node(0.,0.); n4=new Node(-2,0.); + n2=new Node(1.,0.); n5=new Node(-1.,0.); + n3=new Node(0.5,1.); n6=new Node(-1.5,1.); + e1_2=new EdgeLin(n1,n2); e2_3=new EdgeLin(n2,n3); e3_1=new EdgeLin(n3,n1); + e4_5=new EdgeLin(n4,n5); e5_6=new EdgeLin(n5,n6); e6_4=new EdgeLin(n6,n4); + for(int k=0;k<2;k++) + for(int i=0;i<3;i++) + { + for(int j=0;j<3;j++) + { + e1_2->incrRef(); e2_3->incrRef(); e3_1->incrRef(); e4_5->incrRef(); e5_6->incrRef(); e6_4->incrRef(); + QuadraticPolygon pol13; pol13.pushBack(e1_2); pol13.pushBack(e2_3); pol13.pushBack(e3_1); + for(int i1=0;i1<i;i1++) pol13.circularPermute(); if(k==1) pol13.reverse(); + QuadraticPolygon pol14; pol14.pushBack(e5_6); pol14.pushBack(e6_4); pol14.pushBack(e4_5); + for(int j1=0;j1<j;j1++) pol14.circularPermute(); + result=pol13.intersectMySelfWith(pol14); + CPPUNIT_ASSERT_EQUAL(0,(int)result.size()); + } + } + //clean-up test7 + e1_2->decrRef(); e2_3->decrRef(); e3_1->decrRef(); e4_5->decrRef(); e5_6->decrRef(); e6_4->decrRef(); + n1->decrRef(); n2->decrRef(); n3->decrRef(); n4->decrRef(); n5->decrRef(); n6->decrRef(); + + //Multi polygons + + n1=new Node(0.,0.); + n2=new Node(1.,0.); + n3=new Node(1.,1.); + n4=new Node(0.,1.); + // + n5=new Node(0.2,0.7); + n6=new Node(0.4,0.7); + n7=new Node(0.4,1.3); + Node *n8=new Node(0.6,1.3); + Node *n9=new Node(0.6,0.7); + Node *n10=new Node(0.9,0.7); + Node *n11=new Node(0.9,2.); + Node *n12=new Node(0.2,2.); + // + e1_2=new EdgeLin(n1,n2); e2_3=new EdgeLin(n2,n3); Edge *e3_4=new EdgeLin(n3,n4); Edge *e4_1=new EdgeLin(n4,n1); + e5_6=new EdgeLin(n5,n6); Edge *e6_7=new EdgeLin(n6,n7); Edge *e7_8=new EdgeLin(n7,n8); Edge *e8_9=new EdgeLin(n8,n9); Edge *e9_10=new EdgeLin(n9,n10); Edge *e10_11=new EdgeLin(n10,n11); + Edge *e11_12=new EdgeLin(n11,n12); Edge *e12_1=new EdgeLin(n12,n5); + // + for(int k=0;k<2;k++) + for(int i=0;i<4;i++) + { + for(int j=0;j<8;j++) + { + e1_2->incrRef(); e2_3->incrRef(); e3_4->incrRef(); e4_1->incrRef(); e5_6->incrRef(); e6_7->incrRef(); e7_8->incrRef(); e8_9->incrRef(); e9_10->incrRef(); e10_11->incrRef(); e11_12->incrRef(); e12_1->incrRef(); + QuadraticPolygon pol15; pol15.pushBack(e1_2); pol15.pushBack(e2_3); pol15.pushBack(e3_4); pol15.pushBack(e4_1); + for(int i1=0;i1<i;i1++) pol15.circularPermute(); if(k==1) pol15.reverse(); + QuadraticPolygon pol16; pol16.pushBack(e5_6); pol16.pushBack(e6_7); pol16.pushBack(e7_8); pol16.pushBack(e8_9); pol16.pushBack(e9_10); pol16.pushBack(e10_11); pol16.pushBack(e11_12); pol16.pushBack(e12_1); + for(int j1=0;j1<j;j1++) pol16.circularPermute(); + result=pol15.intersectMySelfWith(pol16); + CPPUNIT_ASSERT_EQUAL(2,(int)result.size()); + checkBasicsOfPolygons(*result[0],*result[1],false); + CPPUNIT_ASSERT_EQUAL(4,result[0]->recursiveSize()); CPPUNIT_ASSERT_EQUAL(4,result[1]->recursiveSize()); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.15,result[0]->getArea()+result[1]->getArea(),1e-10); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.03,fabs(result[0]->getArea()-result[1]->getArea()),1e-10); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.15,pol15.intersectWith(pol16),1e-10); + delete result[0]; delete result[1]; + } + } + //clean-up test8 + e1_2->decrRef(); e2_3->decrRef(); e3_4->decrRef(); e4_1->decrRef(); e5_6->decrRef(); e6_7->decrRef(); e7_8->decrRef(); e8_9->decrRef(); e9_10->decrRef(); e10_11->decrRef(); e11_12->decrRef(); e12_1->decrRef(); + n1->decrRef(); n2->decrRef(); n3->decrRef(); n4->decrRef(); n5->decrRef(); n6->decrRef(); n7->decrRef(); n8->decrRef(); n9->decrRef(); n10->decrRef(); n11->decrRef(); n12->decrRef(); +} + +/*! + * Testing case where a polygon pol1 is included in an onother polygon pol2. + */ +void QuadraticPlanarInterpTest::checkPolygonsIntersection2() +{ + Node *n1=new Node(0.,0.); Node *n4=new Node(0.2,0.2); + Node *n2=new Node(1.,0.); Node *n5=new Node(0.8,0.2); + Node *n3=new Node(0.5,1.); Node *n6=new Node(0.5,0.8); + Edge *e1_2=new EdgeLin(n1,n2); Edge *e4_5=new EdgeLin(n4,n5); + Edge *e2_3=new EdgeLin(n2,n3); Edge *e5_6=new EdgeLin(n5,n6); + Edge *e3_1=new EdgeLin(n3,n1); Edge *e6_4=new EdgeLin(n6,n4); + // + QuadraticPolygon pol1; pol1.pushBack(e1_2); pol1.pushBack(e2_3); pol1.pushBack(e3_1); + QuadraticPolygon pol2; pol2.pushBack(e4_5); pol2.pushBack(e5_6); pol2.pushBack(e6_4); + std::vector<QuadraticPolygon *> result=pol1.intersectMySelfWith(pol2); + CPPUNIT_ASSERT_EQUAL(1,(int)result.size()); + CPPUNIT_ASSERT_EQUAL(3,result[0]->recursiveSize()); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.18,result[0]->getArea(),1e-10); + delete result[0]; + result.clear(); + pol1.initLocations(); + pol2.initLocations(); + result=pol2.intersectMySelfWith(pol1); + CPPUNIT_ASSERT_EQUAL(1,(int)result.size()); + CPPUNIT_ASSERT_EQUAL(3,result[0]->recursiveSize()); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.18,result[0]->getArea(),1e-10); + delete result[0]; + //clean-up + n1->decrRef(); n2->decrRef(); n3->decrRef(); n4->decrRef(); n5->decrRef(); n6->decrRef(); +} + +void QuadraticPlanarInterpTest::checkAreasCalculations() +{ + Node *n1=new Node(0.,0.); + Node *n2=new Node(1.,0.); + Node *n3=new Node(0.5,1.); + Edge *e1_2=new EdgeLin(n1,n2); + Edge *e2_3=new EdgeLin(n2,n3); + Edge *e3_1=new EdgeLin(n3,n1); + // + e1_2->incrRef(); e2_3->incrRef(); e3_1->incrRef(); + QuadraticPolygon pol1; pol1.pushBack(e1_2); pol1.pushBack(e2_3); pol1.pushBack(e3_1); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.5,pol1.getArea(),1e-10); + CPPUNIT_ASSERT_DOUBLES_EQUAL(3.2360679774997898,pol1.getPerimeter(),1e-10); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.61803398874989479,pol1.getHydraulicDiameter(),1e-10); + pol1.reverse(); + CPPUNIT_ASSERT_DOUBLES_EQUAL(-0.5,pol1.getArea(),1e-10); + CPPUNIT_ASSERT_DOUBLES_EQUAL(3.2360679774997898,pol1.getPerimeter(),1e-10); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.61803398874989479,pol1.getHydraulicDiameter(),1e-10); + //clean-up + e1_2->decrRef(); e2_3->decrRef(); e3_1->decrRef(); + n1->decrRef(); n2->decrRef(); n3->decrRef(); + + //case 2 + + n1=new Node(0.,0.); + n2=new Node(1.,0.); + Node *n3m=new Node(1.5,0.5); + n3=new Node(1.,1.); + Node *n4=new Node(0.,1.); + e1_2=new EdgeLin(n1,n2); + e2_3=new EdgeArcCircle(n2,n3m,n3); + Edge *e3_4=new EdgeLin(n3,n4); + Edge *e4_1=new EdgeLin(n4,n1); + // + for(int k=0;k<8;k++) + { + n2->setNewCoords(cos(k*M_PI/4),sin(k*M_PI/4)); + n3->setNewCoords(sqrt(2.)*cos((k+1)*M_PI/4),sqrt(2.)*sin((k+1)*M_PI/4)); + n3m->setNewCoords(1.5811388300841898*cos(0.3217505543966423+k*M_PI/4),1.5811388300841898*sin(0.3217505543966423+k*M_PI/4)); + n4->setNewCoords(cos(k*M_PI/4+M_PI/2),sin(k*M_PI/4+M_PI/2)); + e1_2->update(n3m); e2_3->update(n3m); e3_4->update(n3m); e4_1->update(n3m); + e1_2->incrRef(); e2_3->incrRef(); e3_4->incrRef(); e4_1->incrRef(); + QuadraticPolygon pol2; pol2.pushBack(e1_2); pol2.pushBack(e2_3); pol2.pushBack(e3_4); pol2.pushBack(e4_1); + CPPUNIT_ASSERT_DOUBLES_EQUAL(1.3926990816987241,pol2.getArea(),1e-6); + CPPUNIT_ASSERT_DOUBLES_EQUAL(4.5707963267948966,pol2.getPerimeter(),1e-6); + pol2.reverse(); + CPPUNIT_ASSERT_DOUBLES_EQUAL(-1.3926990816987241,pol2.getArea(),1e-6); + CPPUNIT_ASSERT_DOUBLES_EQUAL(4.5707963267948966,pol2.getPerimeter(),1e-6); + } + //clean-up case2 + e1_2->decrRef(); e2_3->decrRef(); e3_4->decrRef(); e4_1->decrRef(); + n1->decrRef(); n2->decrRef(); n3->decrRef(); n3m->decrRef(); n4->decrRef(); + + //case 3 + + const double radius1=0.7; + const double radius2=0.9; + n1=new Node(1.+radius1*cos(-2.*M_PI/3.),1.+radius1*sin(-2.*M_PI/3.)); + n2=new Node(1.+radius1*cos(-M_PI/3.),1.+radius1*sin(-M_PI/3.)); + Node *n2m=new Node(1.+radius1*cos(M_PI/2.),1.+radius1*sin(M_PI/2.)); + n3=new Node(1.+radius2*cos(-M_PI/3.),1.+radius2*sin(-M_PI/3.)); + n3m=new Node(1.+radius2*cos(M_PI/2.),1.+radius2*sin(M_PI/2.)); + n4=new Node(1.+radius2*cos(-2.*M_PI/3.),1.+radius2*sin(-2.*M_PI/3.)); + e1_2=new EdgeArcCircle(n1,n2m,n2); + e2_3=new EdgeLin(n2,n3); + e3_4=new EdgeArcCircle(n3,n3m,n4); + e4_1=new EdgeLin(n4,n1); + // + e1_2->incrRef(); e2_3->incrRef(); e3_4->incrRef(); e4_1->incrRef(); + QuadraticPolygon pol3; pol3.pushBack(e1_2); pol3.pushBack(e2_3); pol3.pushBack(e3_4); pol3.pushBack(e4_1); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.83775804095727857,pol3.getArea(),1e-10); + CPPUNIT_ASSERT_DOUBLES_EQUAL(8.7775804095727832,pol3.getPerimeter(),1e-10); + pol3.reverse(); + CPPUNIT_ASSERT_DOUBLES_EQUAL(-0.83775804095727857,pol3.getArea(),1e-10); + CPPUNIT_ASSERT_DOUBLES_EQUAL(8.7775804095727832,pol3.getPerimeter(),1e-10); + //clean-up case3 + e1_2->decrRef(); e2_3->decrRef(); e3_4->decrRef(); e4_1->decrRef(); + n1->decrRef(); n2->decrRef(); n2m->decrRef(); n3->decrRef(); n3m->decrRef(); n4->decrRef(); +} + +void QuadraticPlanarInterpTest::checkBarycenterCalculations() +{ + Node *n1=new Node(3.,7.); + Node *n2=new Node(5.,7.); + Node *n3=new Node(4.,8.); + Edge *e1_2=new EdgeLin(n1,n2); + Edge *e2_3=new EdgeLin(n2,n3); + Edge *e3_1=new EdgeLin(n3,n1); + // + double bary[2]; + e1_2->incrRef(); e2_3->incrRef(); e3_1->incrRef(); + QuadraticPolygon pol1; pol1.pushBack(e1_2); pol1.pushBack(e2_3); pol1.pushBack(e3_1); + bary[0]=0.; bary[1]=0.; + e1_2->getBarycenterOfZone(bary); + CPPUNIT_ASSERT_DOUBLES_EQUAL(-56.,bary[0],1.e-10); + bary[0]=0.; bary[1]=0.; + e2_3->getBarycenterOfZone(bary); + CPPUNIT_ASSERT_DOUBLES_EQUAL(33.66666666666667,bary[0],1.e-10); + CPPUNIT_ASSERT_DOUBLES_EQUAL(28.16666666666667,bary[1],1.e-10); + bary[0]=0.; bary[1]=0.; + e3_1->getBarycenterOfZone(bary); + CPPUNIT_ASSERT_DOUBLES_EQUAL(26.333333333333336,bary[0],1.e-10); + CPPUNIT_ASSERT_DOUBLES_EQUAL(28.1666666666667,bary[1],1.e-10); + CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,pol1.getArea(),1e-10); + pol1.getBarycenter(bary); + CPPUNIT_ASSERT_DOUBLES_EQUAL(4.,bary[0],1.e-10); + CPPUNIT_ASSERT_DOUBLES_EQUAL(7.333333333333333,bary[1],1.e-10); + // + e1_2->incrRef(); e2_3->incrRef(); e3_1->incrRef(); + QuadraticPolygon pol4; pol4.pushBack(e3_1,false); pol4.pushBack(e2_3,false); pol4.pushBack(e1_2,false); + CPPUNIT_ASSERT_DOUBLES_EQUAL(-1.,pol4.getArea(),1e-10); + pol4.getBarycenter(bary); + CPPUNIT_ASSERT_DOUBLES_EQUAL(4.,bary[0],1.e-10); + CPPUNIT_ASSERT_DOUBLES_EQUAL(7.333333333333333,bary[1],1.e-10); + //clean-up + e1_2->decrRef(); e2_3->decrRef(); e3_1->decrRef(); + n1->decrRef(); n2->decrRef(); n3->decrRef(); + //Inverting polygon + n1=new Node(3.,7.); + n2=new Node(5.,7.); + n3=new Node(4.,8.); + e1_2=new EdgeLin(n1,n3); + e2_3=new EdgeLin(n3,n2); + e3_1=new EdgeLin(n2,n1); + e1_2->incrRef(); e2_3->incrRef(); e3_1->incrRef(); + QuadraticPolygon pol3; pol3.pushBack(e1_2); pol3.pushBack(e2_3); pol3.pushBack(e3_1); + bary[0]=0.; bary[1]=0.; + pol3.getBarycenter(bary); + CPPUNIT_ASSERT_DOUBLES_EQUAL(-1.,pol3.getArea(),1e-10); + CPPUNIT_ASSERT_DOUBLES_EQUAL(4.,bary[0],1.e-10); + CPPUNIT_ASSERT_DOUBLES_EQUAL(7.333333333333333,bary[1],1.e-10); + //clean-up + e1_2->decrRef(); e2_3->decrRef(); e3_1->decrRef(); + n1->decrRef(); n2->decrRef(); n3->decrRef(); + // + double center[2]={3.,7.}; + e1_2=buildArcOfCircle(center,4.,M_PI/3.,4.*M_PI/3.); + bary[0]=0.; bary[1]=0.; + e1_2->getBarycenterOfZone(bary); + CPPUNIT_ASSERT_DOUBLES_EQUAL(131.685410765053,bary[0],1.e-10); + CPPUNIT_ASSERT_DOUBLES_EQUAL(303.262521934362,bary[1],1.e-10); + n1=new Node(0.99999999999999822,3.5358983848622465); + n2=new Node(5.,10.4641016151377544); + Edge *e2_1=new EdgeLin(n1,n2); + // + e1_2->incrRef(); e2_1->incrRef(); + QuadraticPolygon pol2; pol2.pushBack(e1_2); pol2.pushBack(e2_1); + pol2.getBarycenter(bary); + CPPUNIT_ASSERT_DOUBLES_EQUAL(25.132741228718345,pol2.getArea(),1e-10); + //4*radius/(3.*pi) + CPPUNIT_ASSERT_DOUBLES_EQUAL(1.5297896122085546,bary[0],1.e-10); + CPPUNIT_ASSERT_DOUBLES_EQUAL(7.8488263631567756,bary[1],1.e-10); + //clean-up + e1_2->decrRef(); e2_1->decrRef(); + n1->decrRef(); n2->decrRef(); +} + +/*! + * Testing user interface high level function. + */ +void QuadraticPlanarInterpTest::checkHighLevelFunctionTest1() +{ + QUADRATIC_PLANAR::setPrecision(1e-12); + QUADRATIC_PLANAR::setArcDetectionPrecision(1e-9); + double coords[]={ + 8.8334591186000004, 5.0999999999999996, + 7.1014083111000001, 6.0999999999999996, + 7.8334591186000004, 6.8320508074999999, + 7.9674337149000003, 5.5999999999999996, + 7.4192455562999999, 6.5142135623000001, + 8.3334591186000004, 5.9660254036999998 + }; + std::vector<Node *> nodes; + nodes.push_back(new Node(coords)); + nodes.push_back(new Node(coords+2)); + nodes.push_back(new Node(coords+4)); + nodes.push_back(new Node(coords+6)); + nodes.push_back(new Node(coords+8)); + nodes.push_back(new Node(coords+10)); + QuadraticPolygon *pol=QuadraticPolygon::BuildArcCirclePolygon(nodes); + CPPUNIT_ASSERT_DOUBLES_EQUAL(-1.04719755,pol->getArea(),1e-5); + CPPUNIT_ASSERT_EQUAL(3,pol->size()); + ElementaryEdge *e0=dynamic_cast<ElementaryEdge *>((*pol)[0]); + ElementaryEdge *e1=dynamic_cast<ElementaryEdge *>((*pol)[1]); + ElementaryEdge *e2=dynamic_cast<ElementaryEdge *>((*pol)[0]); + CPPUNIT_ASSERT(e0); CPPUNIT_ASSERT(e1); CPPUNIT_ASSERT(e2); + CPPUNIT_ASSERT(dynamic_cast<EdgeLin *>(e0->getPtr()));//<- testing detection of colinearity + CPPUNIT_ASSERT(dynamic_cast<EdgeArcCircle *>(e1->getPtr())); + CPPUNIT_ASSERT(dynamic_cast<EdgeLin *>(e2->getPtr()));//<- testing detection of colinearity + nodes.clear(); + delete pol; + nodes.push_back(new Node(coords)); + nodes.push_back(new Node(coords+4)); + nodes.push_back(new Node(coords+2)); + nodes.push_back(new Node(coords+10)); + nodes.push_back(new Node(coords+8)); + nodes.push_back(new Node(coords+6)); + pol=QuadraticPolygon::BuildArcCirclePolygon(nodes); + CPPUNIT_ASSERT_DOUBLES_EQUAL(1.04719755,pol->getArea(),1e-5); + CPPUNIT_ASSERT_EQUAL(3,pol->size()); + e0=dynamic_cast<ElementaryEdge *>((*pol)[0]); + e1=dynamic_cast<ElementaryEdge *>((*pol)[1]); + e2=dynamic_cast<ElementaryEdge *>((*pol)[0]); + CPPUNIT_ASSERT(e0); CPPUNIT_ASSERT(e1); CPPUNIT_ASSERT(e2); + CPPUNIT_ASSERT(dynamic_cast<EdgeLin *>(e0->getPtr()));//<- testing detection of colinearity + CPPUNIT_ASSERT(dynamic_cast<EdgeArcCircle *>(e1->getPtr())); + CPPUNIT_ASSERT(dynamic_cast<EdgeLin *>(e2->getPtr()));//<- testing detection of colinearity + delete pol; + const double coords2[]={ + 0.,0., + 1.5,0., + 1.5,1., + 0.,1. + }; + nodes.clear(); + nodes.push_back(new Node(coords2)); + nodes.push_back(new Node(coords2+2)); + nodes.push_back(new Node(coords2+4)); + nodes.push_back(new Node(coords2+6)); + pol=QuadraticPolygon::BuildLinearPolygon(nodes); + CPPUNIT_ASSERT_DOUBLES_EQUAL(1.5,pol->getArea(),1e-12); + double tmp[2],tmp2; + pol->getBarycenter(tmp,tmp2); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.75,tmp[0],1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.5,tmp[1],1e-12); + delete pol; + const double coords3[]={ + 1.0999999999000001, -1.9052558882999999, + 1.9052558881999999, -1.0999999999000001, + 1.7320508075000001, -0.99999999989999999, + 0.99999999989999999, -1.7320508075000001, + 1.5556349186, -1.5556349185, + 1.8186533478, -1.0499999999, + 1.4142135623000001, -1.4142135623000001, + 1.0499999999, -1.8186533479 + }; + nodes.clear(); + nodes.push_back(new Node(coords3)); + nodes.push_back(new Node(coords3+2)); + nodes.push_back(new Node(coords3+4)); + nodes.push_back(new Node(coords3+6)); + nodes.push_back(new Node(coords3+8)); + nodes.push_back(new Node(coords3+10)); + nodes.push_back(new Node(coords3+12)); + nodes.push_back(new Node(coords3+14)); + pol=QuadraticPolygon::BuildArcCirclePolygon(nodes); + pol->getBarycenter(tmp,tmp2); + delete pol; + QUADRATIC_PLANAR::setPrecision(1e-14); +} + +void QuadraticPlanarInterpTest::check1DInterpLin() +{ + QUADRATIC_PLANAR::setPrecision(1e-7); + QUADRATIC_PLANAR::setArcDetectionPrecision(1e-9); + const int NB_OF_CELL_AXIAL_1=30; + static const double Z_VALS_1[NB_OF_CELL_AXIAL_1+1]= + { -0.1550 , -0.1356, -0.1162, -0.0969, -0.0775 ,-0.0581, -0.0387, -0.0194, 0.0000 , 0.0500, + 0.1000 , 0.1500 , 0.2000 , 0.2500, 0.3000, 0.3500, 0.4000, 0.4500, 0.5000, 0.5500, + 0.6000, 0.6500, 0.7000, 0.7194, 0.7388, 0.7581, 0.7775, 0.7969, 0.8163, 0.8356, + 0.8550}; + std::vector<double> zLev1(Z_VALS_1,Z_VALS_1+NB_OF_CELL_AXIAL_1+1); + + const int NB_OF_CELL_AXIAL_2=46; + static const double Z_VALS_2[NB_OF_CELL_AXIAL_2+1]= + { -0.3050 ,-0.2863,-0.2675,-0.2488,-0.2300,-0.2113,-0.1925,-0.1738,-0.1550,-0.1356 + , -0.1162,-0.0969,-0.0775,-0.0581,-0.0387,-0.0194,0.0000, 0.0500, 0.1 ,0.15 + , 0.20, 0.25, 0.30, 0.350 ,0.40 ,0.450 ,0.500 , 0.550, 0.600 ,0.650 ,0.700 + , 0.7194 ,0.7388 ,0.7581 ,0.7775 ,0.7969 ,0.8163 ,0.8356, 0.8550 + , 0.8738 ,0.8925 ,0.9113 ,0.9300 ,0.9488 ,0.9675 ,0.9863, 1.0050}; + std::vector<double> zLev2(Z_VALS_2,Z_VALS_2+NB_OF_CELL_AXIAL_2+1); + std::map<int,std::map<int,double> > m; + Edge::Interpolate1DLin(zLev1,zLev2,m); + CPPUNIT_ASSERT_EQUAL(30,(int)m.size()); + double ret=0; + for(int i=0;i<30;i++) + { + CPPUNIT_ASSERT_EQUAL(1,(int)m[i].size()); + CPPUNIT_ASSERT(m[i][8+i] > 0.15); + ret+=m[i][8+i]; + } + CPPUNIT_ASSERT_DOUBLES_EQUAL(ret,30.,1e-12); + // + m.clear(); + const int NB_OF_CELL_AXIAL_3=13; + static const double Z_VALS_3[NB_OF_CELL_AXIAL_3+1]={ + 0.,0.01,0.05,0.10,0.15,0.20,0.25,0.30, + 0.35,0.40,0.45,0.50,0.55,0.60 }; + std::vector<double> zLev3(Z_VALS_3,Z_VALS_3+NB_OF_CELL_AXIAL_3+1); + Edge::Interpolate1DLin(zLev3,zLev1,m); + CPPUNIT_ASSERT_EQUAL(13,(int)m.size()); + CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,m[0][8],1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,m[1][8],1e-12); + for(int i=0;i<11;i++) + { + CPPUNIT_ASSERT_EQUAL(1,(int)m[i+2].size()); + CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,m[i+2][i+9],1e-12); + } + QUADRATIC_PLANAR::setPrecision(1e-14); +} + +/*! + * This test looks if intersectors are in coherency. + */ +void QuadraticPlanarInterpTest::checkEpsilonCoherency1() +{ + INTERP_KERNEL::QUADRATIC_PLANAR::setPrecision(1e-12); + INTERP_KERNEL::QUADRATIC_PLANAR::setArcDetectionPrecision(1e-5); + + const double pol1[]={ + -2.1083388455000001, 1.2172499999999999, + -1.7320508075000001, 1, + -1.9201948265, 1.108625 + }; + + const double pol2[]={ + -2.2379999998, 0, + -1.9381648534, 1.1189999998, + -2.1617419990000002, 0.57923702298000002, + -1.9381648534, 1.1189999998, + -1.9909924031999999, 1.1494999999, + -1.9645786283, 1.1342499998 + }; + // + Node *n1=new Node(pol1[0],pol1[1]); + Node *n2=new Node(pol1[2],pol1[3]); + Node *n3; + // + Edge *e1=new EdgeLin(n1,n2); n1->decrRef(); n2->decrRef(); + n1=new Node(pol2[0],pol2[1]); + n2=new Node(pol2[4],pol2[5]); + n3=new Node(pol2[2],pol2[3]); + Edge *e2=new EdgeArcCircle(n1,n2,n3); n1->decrRef(); n2->decrRef(); n3->decrRef(); + e2->decrRef(); + e1->decrRef(); +} + +/*! + * Tests to avoid regressions : Basic one. + */ +void QuadraticPlanarInterpTest::checkNonRegression1() +{ + const double coords1[]= + { + 16.1732057215, -25.110999999800001, + 16.02555485246479, -25.340997988918762 + }; + Node *nS1=new Node(coords1); + Node *nE1=new Node(coords1+2); + const double radius1=2.902; + const double angleS1=-0.49999999950907054; const double angleL1=-0.0942156629996692; + const double center1[2]={13.66, -23.66}; + EdgeArcCircle *e1=new EdgeArcCircle(nS1,nE1,center1,radius1,angleS1,angleL1); + // + const double coords2[]= + { + 16.041579804000001, -25.350249998999999, + 16.367740958999999, -24.132999999999999 + }; + Node *nS2=new Node(coords2); + Node *nE2=new Node(coords2+2); + const double radius2=2.4345; + const double angleS2=-0.523598776190207; const double angleL2=0.5235987755846041; + const double center2[]={ 13.933240960547204, -24.132999998525658 }; + EdgeArcCircle *e2=new EdgeArcCircle(nS2,nE2,center2,radius2,angleS2,angleL2); + MergePoints merge; + QuadraticPolygon c1,c2; + e1->intersectWith(e2,merge,c1,c2); + CPPUNIT_ASSERT_EQUAL(2,c1.size()); CPPUNIT_ASSERT_EQUAL(2,c2.size()); + CPPUNIT_ASSERT_DOUBLES_EQUAL(e1->getCurveLength(),c1.getPerimeter(),1e-5); + //clean-up + nS1->decrRef(); nE1->decrRef(); nS2->decrRef(); nE2->decrRef(); e1->decrRef(); e2->decrRef(); +} + +void QuadraticPlanarInterpTest::checkNonRegression2() +{ + QUADRATIC_PLANAR::setPrecision(1e-12); + QUADRATIC_PLANAR::setArcDetectionPrecision(1e-9); + double coords1[]= + { + 15.141499999899999, -26.226033271399999, + 16.226033271199999, -25.141499999800001, + 16.1732057215, -25.110999999800001, + 15.110999999899999, -26.1732057217, + 15.755157392699999, -25.755157392499999, + 16.199619496299999, -25.126249999799999, + 15.7120238788, -25.712023879099998, + 15.126249999899999, -26.199619496499999 + }; + double coords2[]= + { + 15.933240959000001, -24.132999999999999, + 15.665291765999999, -25.132999998999999, + 16.041579804000001, -25.350249998999999, + 16.367740958999999, -24.132999999999999, + 15.865092611, -24.650638091000001, + 15.853435785, -25.241624998999999, + 16.284787383000001, -24.763094964, + 16.150490958999999, -24.132999999999999 + }; + std::vector<Node *> nodes1; + nodes1.push_back(new Node(coords1)); + nodes1.push_back(new Node(coords1+2)); + nodes1.push_back(new Node(coords1+4)); + nodes1.push_back(new Node(coords1+6)); + nodes1.push_back(new Node(coords1+8)); + nodes1.push_back(new Node(coords1+10)); + nodes1.push_back(new Node(coords1+12)); + nodes1.push_back(new Node(coords1+14)); + QuadraticPolygon *pol1=QuadraticPolygon::BuildArcCirclePolygon(nodes1); + std::vector<Node *> nodes2; + nodes2.push_back(new Node(coords2)); + nodes2.push_back(new Node(coords2+2)); + nodes2.push_back(new Node(coords2+4)); + nodes2.push_back(new Node(coords2+6)); + nodes2.push_back(new Node(coords2+8)); + nodes2.push_back(new Node(coords2+10)); + nodes2.push_back(new Node(coords2+12)); + nodes2.push_back(new Node(coords2+14)); + QuadraticPolygon *pol2=QuadraticPolygon::BuildArcCirclePolygon(nodes2); + std::vector<QuadraticPolygon *> v=pol1->intersectMySelfWith(*pol2); + CPPUNIT_ASSERT_EQUAL(1,(int)v.size()); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.00173945,v[0]->getArea(),1e-7); + delete v[0]; + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.00173945,pol1->intersectWith(*pol2),1e-7); + delete pol1; + delete pol2; +} + +/*! + * Tests to avoid regressions : Basic one. + */ +void QuadraticPlanarInterpTest::checkNonRegression3() +{ + const double coords1[]= + { + 10.962340811000001, -22.417749999000002, + 12.217990959, -21.162099852000001 + }; + Node *nS1=new Node(coords1); + Node *nE1=new Node(coords1+2); + const double radius1=3.4304999897666599; + const double angleS1=2.6179938783536514; const double angleL1=-0.52359877711901204; + const double center1[2]={13.933240950441375, -24.132999992807399}; + EdgeArcCircle *e1=new EdgeArcCircle(nS1,nE1,center1,radius1,angleS1,angleL1); + // + const double coords2[]= + { + 11.1467942784, -22.2090000002, + 11.0939667286, -22.178500000099998 + }; + Node *nS2=new Node(coords2); + Node *nE2=new Node(coords2+2); + EdgeLin *e2=new EdgeLin(nS2,nE2); + MergePoints merge; + QuadraticPolygon c1,c2; + CPPUNIT_ASSERT(e1->intersectWith(e2,merge,c1,c2)); + CPPUNIT_ASSERT_EQUAL(2,c1.size()); + CPPUNIT_ASSERT_EQUAL(2,c2.size()); + ElementaryEdge *tmp1=dynamic_cast<ElementaryEdge *>(c1.front()); CPPUNIT_ASSERT(tmp1); + EdgeArcCircle *tmp2=dynamic_cast<EdgeArcCircle *>(tmp1->getPtr()); CPPUNIT_ASSERT(tmp2); + CPPUNIT_ASSERT_DOUBLES_EQUAL(2.6179938783536514,tmp2->getAngle0(),1e-14); + //clean-up + nS1->decrRef(); nE1->decrRef(); nS2->decrRef(); nE2->decrRef(); e1->decrRef(); e2->decrRef(); +} + +void QuadraticPlanarInterpTest::checkNonRegression4() +{ + QUADRATIC_PLANAR::setPrecision(1e-12); + QUADRATIC_PLANAR::setArcDetectionPrecision(1e-9); + double coords1[]= + { + 10.962340811000001, -22.417749999000002, + 12.217990959, -21.162099852000001, + 12.051990958999999, -20.874579418, + 10.674820377, -22.251749999000001, + 11.507511146000001, -21.707270185999999, + 12.134990959, -21.018339635, + 11.272751694, -21.472510735, + 10.818580594, -22.334749999 + }; + + double coords2[]= + { + 10.758000000199999, -23.66, + 11.1467942784, -22.2090000002, + 11.0939667286, -22.178500000099998, + 10.696999999999999, -23.66, + 10.856883252299999, -22.908907131159999, + 11.1203805035, -22.1937500001, + 10.797961776699999, -22.893119169449999, + 10.727500000099999, -23.66 + }; + std::vector<Node *> nodes1; + nodes1.push_back(new Node(coords1)); + nodes1.push_back(new Node(coords1+2)); + nodes1.push_back(new Node(coords1+4)); + nodes1.push_back(new Node(coords1+6)); + nodes1.push_back(new Node(coords1+8)); + nodes1.push_back(new Node(coords1+10)); + nodes1.push_back(new Node(coords1+12)); + nodes1.push_back(new Node(coords1+14)); + QuadraticPolygon *pol1=QuadraticPolygon::BuildArcCirclePolygon(nodes1); + std::vector<Node *> nodes2; + nodes2.push_back(new Node(coords2)); + nodes2.push_back(new Node(coords2+2)); + nodes2.push_back(new Node(coords2+4)); + nodes2.push_back(new Node(coords2+6)); + nodes2.push_back(new Node(coords2+8)); + nodes2.push_back(new Node(coords2+10)); + nodes2.push_back(new Node(coords2+12)); + nodes2.push_back(new Node(coords2+14)); + QuadraticPolygon *pol2=QuadraticPolygon::BuildArcCirclePolygon(nodes2); + std::vector<QuadraticPolygon *> v=pol1->intersectMySelfWith(*pol2); + CPPUNIT_ASSERT_EQUAL(1,(int)v.size()); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.00164773941455998,v[0]->getArea(),1e-7); + delete v[0]; + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.00164773941455998,pol1->intersectWith(*pol2),1e-7); + delete pol1; + delete pol2; +} + +void QuadraticPlanarInterpTest::checkNonRegression5() +{ + INTERP_KERNEL::QUADRATIC_PLANAR::setPrecision(1e-12); + INTERP_KERNEL::QUADRATIC_PLANAR::setArcDetectionPrecision(1e-5); + double coords1[]= + { + -1.7320508075000001, 1, + -1, 1.7320508075000001 , + -1.2172499999999999, 2.1083388455000001, + -2.1083388455000001, 1.2172499999999999, + -1.4142135623000001, 1.4142135623000001, + -1.108625, 1.9201948265, + -1.7214514588000001, 1.7214514588000001, + -1.9201948265, 1.108625}; + + double coords2[]= + { + -2.2379999998, 0, + -1.9381648534, 1.1189999998, + -1.9909924031999999, 1.1494999999, + -2.2989999998999999, 0, + -2.1617419990000002, 0.57923702298000002, + -1.9645786283, 1.1342499998, + -2.2206634745999998, 0.59502498461999997, + -2.2684999997999999, 0}; + //Edge1_of_pol2 inter Edge4_of_pol1 = {-1.9381648533711939, 1.1189999998498941} + //Edge4_of_pol1 _angle = -0.523598775922546, _angle0 = -3.1415926535897931, _radius = 2.2379999983074721, _center = {-1.4925279436059493e-09, 1.3300635705141101e-10}} + std::vector<Node *> nodes1; + nodes1.push_back(new Node(coords1)); + nodes1.push_back(new Node(coords1+2)); + nodes1.push_back(new Node(coords1+4)); + nodes1.push_back(new Node(coords1+6)); + nodes1.push_back(new Node(coords1+8)); + nodes1.push_back(new Node(coords1+10)); + nodes1.push_back(new Node(coords1+12)); + nodes1.push_back(new Node(coords1+14)); + QuadraticPolygon *pol1=QuadraticPolygon::BuildArcCirclePolygon(nodes1); + std::vector<Node *> nodes2; + nodes2.push_back(new Node(coords2)); + nodes2.push_back(new Node(coords2+2)); + nodes2.push_back(new Node(coords2+4)); + nodes2.push_back(new Node(coords2+6)); + nodes2.push_back(new Node(coords2+8)); + nodes2.push_back(new Node(coords2+10)); + nodes2.push_back(new Node(coords2+12)); + nodes2.push_back(new Node(coords2+14)); + QuadraticPolygon *pol2=QuadraticPolygon::BuildArcCirclePolygon(nodes2); + std::vector<QuadraticPolygon *> v=pol1->intersectMySelfWith(*pol2); + CPPUNIT_ASSERT_EQUAL(0,(int)v.size()); + //CPPUNIT_ASSERT_DOUBLES_EQUAL(0.00164773941455998,v[0]->getArea(),1e-7); + //delete v[0]; + //CPPUNIT_ASSERT_DOUBLES_EQUAL(0.00164773941455998,pol1->intersectWith(*pol2),1e-7); + delete pol1; + delete pol2; +} + +void QuadraticPlanarInterpTest::checkNonRegression6() +{ + QUADRATIC_PLANAR::setPrecision(1e-12); + QUADRATIC_PLANAR::setArcDetectionPrecision(1e-5); + double coords1[]= + { + 10.962340811000001, -22.417749999000002, + 12.217990959, -21.162099852000001, + 12.051990958999999, -20.874579418, + 10.674820377, -22.251749999000001, + 11.507511146000001, -21.707270185999999, + 12.134990959, -21.018339635, + 11.272751694, -21.472510735, + 10.818580594, -22.334749999 + }; + double coords2[]= + { 10.426, -23.66, + 10.859273844199999, -22.043000000100001, + 10.806446294799999, -22.012500000199999, + 10.3650000002, -23.66, + 10.536195877799999, -22.822979208099998, + 10.832860069499999, -22.027750000200001, + 10.477274402499999, -22.80719124657, + 10.3955000001, -23.66}; + std::vector<Node *> nodes1; + nodes1.push_back(new Node(coords1)); + nodes1.push_back(new Node(coords1+2)); + nodes1.push_back(new Node(coords1+4)); + nodes1.push_back(new Node(coords1+6)); + nodes1.push_back(new Node(coords1+8)); + nodes1.push_back(new Node(coords1+10)); + nodes1.push_back(new Node(coords1+12)); + nodes1.push_back(new Node(coords1+14)); + QuadraticPolygon *pol1=QuadraticPolygon::BuildArcCirclePolygon(nodes1); + std::vector<Node *> nodes2; + nodes2.push_back(new Node(coords2)); + nodes2.push_back(new Node(coords2+2)); + nodes2.push_back(new Node(coords2+4)); + nodes2.push_back(new Node(coords2+6)); + nodes2.push_back(new Node(coords2+8)); + nodes2.push_back(new Node(coords2+10)); + nodes2.push_back(new Node(coords2+12)); + nodes2.push_back(new Node(coords2+14)); + QuadraticPolygon *pol2=QuadraticPolygon::BuildArcCirclePolygon(nodes2); + std::vector<QuadraticPolygon *> v=pol1->intersectMySelfWith(*pol2); + CPPUNIT_ASSERT_EQUAL(1,(int)v.size()); + CPPUNIT_ASSERT_DOUBLES_EQUAL(v[0]->getArea(),0.0150659,1e-7); + delete v[0]; + delete pol1; + delete pol2; +} + +void QuadraticPlanarInterpTest::checkNonRegression7() +{ + QUADRATIC_PLANAR::setPrecision(1e-5); + QUADRATIC_PLANAR::setArcDetectionPrecision(1e-5); + double coords1[]= + { + -2., 0, + -1.7320508075000001, 1, + -2.1083388455000001, 1.2172499999999999, + -2.4344999999999999, 0, + -1.9318516525603098, 0.51763809027157182, + -1.9201948265, 1.108625, + -2.3515464241024469, 0.63009496529570408, + -2.2172499999999999, 0 + }; + double coords2[]= + { -2.3369999999000002, 0, + -2.0239013684999998, 1.1684999999000001, + -2.1927763221999998, 1.2659999998, + -2.5319999998, 0, + -2.2573686559260442, 0.60486010843437632, + -2.1083388453499996, 1.2172499998499999, + -2.445724191994314, 0.65532982205982326, + -2.4344999998499999, 0 }; + std::vector<Node *> nodes1; + nodes1.push_back(new Node(coords1)); + nodes1.push_back(new Node(coords1+2)); + nodes1.push_back(new Node(coords1+4)); + nodes1.push_back(new Node(coords1+6)); + nodes1.push_back(new Node(coords1+8)); + nodes1.push_back(new Node(coords1+10)); + nodes1.push_back(new Node(coords1+12)); + nodes1.push_back(new Node(coords1+14)); + QuadraticPolygon *pol1=QuadraticPolygon::BuildArcCirclePolygon(nodes1); + std::vector<Node *> nodes2; + nodes2.push_back(new Node(coords2)); + nodes2.push_back(new Node(coords2+2)); + nodes2.push_back(new Node(coords2+4)); + nodes2.push_back(new Node(coords2+6)); + nodes2.push_back(new Node(coords2+8)); + nodes2.push_back(new Node(coords2+10)); + nodes2.push_back(new Node(coords2+12)); + nodes2.push_back(new Node(coords2+14)); + QuadraticPolygon *pol2=QuadraticPolygon::BuildArcCirclePolygon(nodes2); + std::vector<QuadraticPolygon *> v=pol1->intersectMySelfWith(*pol2); + CPPUNIT_ASSERT_EQUAL(1,(int)v.size()); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.121795,v[0]->getArea(),1.e-6); + delete v[0]; + delete pol1; + delete pol2; +} + +void QuadraticPlanarInterpTest::checkNonRegression8() +{ + QUADRATIC_PLANAR::setPrecision(1e-3); + QUADRATIC_PLANAR::setArcDetectionPrecision(1e-5); + double coords1[]= + { + -13.933240959000001, -28.559499999, + -16.146490959000001, -27.966461449000001, + -16.383240958999998, -28.376524478, + -13.933240959000001, -29.032999999000001, + -15.078903461873765, -28.408670669106311, + -16.264865958999998, -28.1714929635, + -15.201454280317435, -28.866036547696734, + -13.933240959000001, -28.796249999 }; + double coords2[]= + { -16.382999999950002, -28.376524478457149, + -13.933000000014729, -29.03299999982551, + -13.93300000006697, -28.793999999915993, + -16.263500000000001, -28.169544407039268, + -15.201213320921273, -28.866036548734634, + -13.933000000040851, -28.913499999870751, + -15.139355569325469, -28.635180276305853, + -16.323249999975001, -28.273034442748209 }; + std::vector<Node *> nodes1; + nodes1.push_back(new Node(coords1)); + nodes1.push_back(new Node(coords1+2)); + nodes1.push_back(new Node(coords1+4)); + nodes1.push_back(new Node(coords1+6)); + nodes1.push_back(new Node(coords1+8)); + nodes1.push_back(new Node(coords1+10)); + nodes1.push_back(new Node(coords1+12)); + nodes1.push_back(new Node(coords1+14)); + QuadraticPolygon *pol1=QuadraticPolygon::BuildArcCirclePolygon(nodes1); + std::vector<Node *> nodes2; + nodes2.push_back(new Node(coords2)); + nodes2.push_back(new Node(coords2+2)); + nodes2.push_back(new Node(coords2+4)); + nodes2.push_back(new Node(coords2+6)); + nodes2.push_back(new Node(coords2+8)); + nodes2.push_back(new Node(coords2+10)); + nodes2.push_back(new Node(coords2+12)); + nodes2.push_back(new Node(coords2+14)); + QuadraticPolygon *pol2=QuadraticPolygon::BuildArcCirclePolygon(nodes2); + std::vector<QuadraticPolygon *> v=pol1->intersectMySelfWith(*pol2); + CPPUNIT_ASSERT_EQUAL(1,(int)v.size()); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.598232,v[0]->getArea(),1.e-6); + delete v[0]; + delete pol1; + delete pol2; +} + +void QuadraticPlanarInterpTest::checkNonRegression9() +{ + QUADRATIC_PLANAR::setPrecision(1e-7); + QUADRATIC_PLANAR::setArcDetectionPrecision(1e-8); + double coords1[]= + { + -0.04476229252902969, -0.085118027765365603, + -0.046952683430894329, -0.085704941238358354, + -0.046952683430894329, -0.088063823748058725, + -0.043582851274179504, -0.087160879944491371, + -0.045818853668170414, -0.085555669718918592, + -0.046952683430894329, -0.086884382493208526, + -0.045208329947517549, -0.087834175256748526, + -0.044172571901604597, -0.086139453854928494 }; + + double coords2[]= + { -0.05065868681155701, -0.087744551996665671, + -0.046951871439587615, -0.088737790182236015, + -0.046951871439683469, -0.088063823751059062, + -0.050321703596054014, -0.087160879946116557, + -0.0488706602695924, -0.08848517684025306, + -0.046951871439635542, -0.088400806966647538, + -0.048696224921445964, -0.087834175258503858, + -0.050490195203805516, -0.087452715971391121}; + + std::vector<Node *> nodes1; + nodes1.push_back(new Node(coords1)); + nodes1.push_back(new Node(coords1+2)); + nodes1.push_back(new Node(coords1+4)); + nodes1.push_back(new Node(coords1+6)); + nodes1.push_back(new Node(coords1+8)); + nodes1.push_back(new Node(coords1+10)); + nodes1.push_back(new Node(coords1+12)); + nodes1.push_back(new Node(coords1+14)); + QuadraticPolygon *pol1=QuadraticPolygon::BuildArcCirclePolygon(nodes1); + std::vector<Node *> nodes2; + nodes2.push_back(new Node(coords2)); + nodes2.push_back(new Node(coords2+2)); + nodes2.push_back(new Node(coords2+4)); + nodes2.push_back(new Node(coords2+6)); + nodes2.push_back(new Node(coords2+8)); + nodes2.push_back(new Node(coords2+10)); + nodes2.push_back(new Node(coords2+12)); + nodes2.push_back(new Node(coords2+14)); + QuadraticPolygon *pol2=QuadraticPolygon::BuildArcCirclePolygon(nodes2); + std::vector<QuadraticPolygon *> v=pol1->intersectMySelfWith(*pol2); + CPPUNIT_ASSERT_EQUAL(0,(int)v.size()); + delete pol1; + delete pol2; +} + +void QuadraticPlanarInterpTest::checkNonRegression10() +{ + INTERP_KERNEL::QUADRATIC_PLANAR::setPrecision(1e-7); + INTERP_KERNEL::QUADRATIC_PLANAR::setArcDetectionPrecision(1e-7); + double coords1[]= + { -0.002269581957210453, -0.09851030343724453, + -0.004268022334182935, -0.1059685844580936, + -0.002777851483521377, -0.1023709937816271}; + double coords2[]= + { -0.004114727297178323, -0.1049870239624718, + -0.003544545103522544, -0.1053162188055505}; + Node *n1_1=new Node(coords1); + Node *n2_1=new Node(coords1+2); + Node *n3_1=new Node(coords1+4); + Node *n1_2=new Node(coords2); + Node *n2_2=new Node(coords2+2); + EdgeArcCircle *e1=new EdgeArcCircle(n1_1,n3_1,n2_1); + EdgeLin *e2=new EdgeLin(n1_2,n2_2); + MergePoints merge; + ComposedEdge *c1=new ComposedEdge; + ComposedEdge *c2=new ComposedEdge; + CPPUNIT_ASSERT(e1->intersectWith(e2,merge,*c1,*c2)); + CPPUNIT_ASSERT_EQUAL(2,c1->size()); + CPPUNIT_ASSERT_EQUAL(2,c2->size()); + ComposedEdge::Delete(c1); ComposedEdge::Delete(c2); + n1_1->decrRef(); n2_1->decrRef(); n3_1->decrRef(); + n1_2->decrRef(); n2_2->decrRef(); + e1->decrRef(); e2->decrRef(); +} + +void QuadraticPlanarInterpTest::checkNonRegression11() +{ + INTERP_KERNEL::QUADRATIC_PLANAR::setPrecision(1e-7); + INTERP_KERNEL::QUADRATIC_PLANAR::setArcDetectionPrecision(1e-7); + double coords1[]= + { -0.002269581957210453, -0.09851030343724453, + -0.004268022334182935, -0.1059685844580936, + -0.002886178753789801, -0.1067663922211958, + -0.0006739664310059821, -0.09851030343724453, + -0.002777851483521377, -0.1023709937816271, + -0.003577100543986368, -0.1063674883396447, + -0.001236605237717319, -0.1027839694676665, + -0.001471774194108217, -0.09851030343724453}; + double coords2[]= + { -0.003544545103522544, -0.1053162188055505, + -0.001941023322604723, -0.09851030343724451, + -0.002598140593501099, -0.09851030343724451, + -0.004114727297178323, -0.1049870239624718, + -0.002347317802266182, -0.1020064358043286, + -0.002269581958052911, -0.09851030343724451, + -0.002982346712452072, -0.1018362598405457, + -0.003829636200350435, -0.1051516213840111}; + + std::vector<Node *> nodes1; + nodes1.push_back(new Node(coords1)); + nodes1.push_back(new Node(coords1+2)); + nodes1.push_back(new Node(coords1+4)); + nodes1.push_back(new Node(coords1+6)); + nodes1.push_back(new Node(coords1+8)); + nodes1.push_back(new Node(coords1+10)); + nodes1.push_back(new Node(coords1+12)); + nodes1.push_back(new Node(coords1+14)); + QuadraticPolygon *pol1=QuadraticPolygon::BuildArcCirclePolygon(nodes1); + std::vector<Node *> nodes2; + nodes2.push_back(new Node(coords2)); + nodes2.push_back(new Node(coords2+2)); + nodes2.push_back(new Node(coords2+4)); + nodes2.push_back(new Node(coords2+6)); + nodes2.push_back(new Node(coords2+8)); + nodes2.push_back(new Node(coords2+10)); + nodes2.push_back(new Node(coords2+12)); + nodes2.push_back(new Node(coords2+14)); + QuadraticPolygon *pol2=QuadraticPolygon::BuildArcCirclePolygon(nodes2); + std::vector<QuadraticPolygon *> v=pol1->intersectMySelfWith(*pol2); + CPPUNIT_ASSERT_EQUAL(1,(int)v.size()); + CPPUNIT_ASSERT_DOUBLES_EQUAL(2.28973e-06,v[0]->getArea(),1.e-11); + delete v[0]; + delete pol1; + delete pol2; +} + +void QuadraticPlanarInterpTest::checkNonRegression12() +{ + INTERP_KERNEL::QUADRATIC_PLANAR::setPrecision(1e-6); + INTERP_KERNEL::QUADRATIC_PLANAR::setArcDetectionPrecision(1e-7); + double coords1[]= + { -0.5032251558760915, -0.8716087994449138, + -0.4695268343089433, -0.8806382374805872, + -0.4695268343089433, -0.8570494123835835, + -0.4914307433275896, -0.8511802776536561, + -0.4869703691141082, -0.8783417525751493, + -0.4695268343089433, -0.8688438249320853, + -0.480865131947653, -0.8555566971861125, + -0.4973279496018406, -0.8613945385492849}; + + double coords2[]= + { -0.5065868681155701, -0.8774455199666568, + -0.4695187143958762, -0.8873779018223601, + -0.4695187143968347, -0.8806382375105907, + -0.5032170359605401, -0.8716087994611657, + -0.488706602695924, -0.8848517684025307, + -0.4695187143963554, -0.8840080696664754, + -0.4869622492144596, -0.8783417525850385, + -0.5049019520380551, -0.8745271597139112}; + + std::vector<Node *> nodes1; + nodes1.push_back(new Node(coords1)); + nodes1.push_back(new Node(coords1+2)); + nodes1.push_back(new Node(coords1+4)); + nodes1.push_back(new Node(coords1+6)); + nodes1.push_back(new Node(coords1+8)); + nodes1.push_back(new Node(coords1+10)); + nodes1.push_back(new Node(coords1+12)); + nodes1.push_back(new Node(coords1+14)); + QuadraticPolygon *pol1=QuadraticPolygon::BuildArcCirclePolygon(nodes1); + std::vector<Node *> nodes2; + nodes2.push_back(new Node(coords2)); + nodes2.push_back(new Node(coords2+2)); + nodes2.push_back(new Node(coords2+4)); + nodes2.push_back(new Node(coords2+6)); + nodes2.push_back(new Node(coords2+8)); + nodes2.push_back(new Node(coords2+10)); + nodes2.push_back(new Node(coords2+12)); + nodes2.push_back(new Node(coords2+14)); + QuadraticPolygon *pol2=QuadraticPolygon::BuildArcCirclePolygon(nodes2); + std::vector<QuadraticPolygon *> v=pol1->intersectMySelfWith(*pol2); + CPPUNIT_ASSERT_EQUAL(1,(int)v.size()); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.,v[0]->getArea(),1.e-6); + delete v[0]; + delete pol1; + delete pol2; +} + +void QuadraticPlanarInterpTest::checkNonRegression13() +{ + INTERP_KERNEL::QUADRATIC_PLANAR::setPrecision(1e-7); + INTERP_KERNEL::QUADRATIC_PLANAR::setArcDetectionPrecision(1e-6); + + double coords_1[194]={ + 0, 0, 0.304375, -7.454791178893722e-17, 0.2152256265236553, -0.2152256265236555, -5.591093384170291e-17, -0.304375, + -0.2152256265236555, -0.2152256265236554, -0.304375, 3.727395589446861e-17, -0.2152256265236554, 0.2152256265236554, 1.86369779472343e-17, 0.304375, + 0.2152256265236554, 0.2152256265236554, 0.60875, -1.490958235778744e-16, 0.5624116654162459, -0.2329585394522483, 0.4304512530473107, -0.4304512530473109, + 0.2329585394522485, -0.5624116654162458, -1.118218676834058e-16, -0.60875, -0.2329585394522482, -0.5624116654162459, -0.4304512530473109, -0.4304512530473108, + -0.5624116654162459, -0.2329585394522483, -0.60875, 7.454791178893722e-17, -0.5624116654162458, 0.2329585394522485, -0.4304512530473108, 0.4304512530473109, + -0.2329585394522484, 0.5624116654162458, 3.727395589446861e-17, 0.60875, 0.2329585394522485, 0.5624116654162458, 0.4304512530473109, 0.4304512530473108, + 0.5624116654162458, 0.2329585394522484, 0.913125, -2.236437353668116e-16, 0.645676879570966, -0.6456768795709663, -1.677328015251087e-16, -0.913125, + -0.6456768795709663, -0.6456768795709661, -0.913125, 1.118218676834058e-16, -0.6456768795709661, 0.6456768795709662, 5.591093384170291e-17, 0.913125, + 0.6456768795709662, 0.6456768795709661, 1.2175, -2.981916471557489e-16, 1.124823330832492, -0.4659170789044966, 0.8609025060946214, -0.8609025060946218, + 0.4659170789044971, -1.124823330832492, -2.236437353668116e-16, -1.2175, -0.4659170789044965, -1.124823330832492, -0.8609025060946218, -0.8609025060946216, + -1.124823330832492, -0.4659170789044967, -1.2175, 1.490958235778744e-16, -1.124823330832492, 0.465917078904497, -0.8609025060946216, 0.8609025060946217, + -0.4659170789044967, 1.124823330832492, 7.454791178893722e-17, 1.2175, 0.4659170789044969, 1.124823330832492, 0.8609025060946217, 0.8609025060946216, + 1.124823330832492, 0.4659170789044968, 1.521875, -3.727395589446861e-16, 1.076128132618277, -1.076128132618277, -2.795546692085146e-16, -1.521875, + -1.076128132618277, -1.076128132618277, -1.521875, 1.86369779472343e-16, -1.076128132618277, 1.076128132618277, 9.318488973617152e-17, 1.521875, + 1.076128132618277, 1.076128132618277, 1.82625, -4.472874707336233e-16, 1.687234996248738, -0.6988756183567448, 1.291353759141932, -1.291353759141933, + 0.6988756183567456, -1.687234996248737, -3.354656030502175e-16, -1.82625, -0.6988756183567447, -1.687234996248738, -1.291353759141933, -1.291353759141932, + -1.687234996248738, -0.6988756183567449, -1.82625, 2.236437353668116e-16, -1.687234996248737, 0.6988756183567454, -1.291353759141932, 1.291353759141932, + -0.6988756183567451, 1.687234996248737, 1.118218676834058e-16, 1.82625, 0.6988756183567453, 1.687234996248737, 1.291353759141932, 1.291353759141932, + 1.687234996248737, 0.6988756183567452, 2.130625, -5.218353825225606e-16, 1.506579385665588, -1.506579385665588, -3.913765368919204e-16, -2.130625, + -1.506579385665588, -1.506579385665588, -2.130625, 2.609176912612803e-16, -1.506579385665588, 1.506579385665588, 1.304588456306401e-16, 2.130625, + 1.506579385665588, 1.506579385665588, 2.435, -5.963832943114977e-16, 2.249646661664984, -0.9318341578089931, 1.721805012189243, -1.721805012189244, + 0.9318341578089941, -2.249646661664983, -4.472874707336233e-16, -2.435, -0.9318341578089929, -2.249646661664984, -1.721805012189244, -1.721805012189243, + -2.249646661664984, -0.9318341578089934, -2.435, 2.981916471557489e-16, -2.249646661664983, 0.9318341578089939, -1.721805012189243, 1.721805012189243, + -0.9318341578089935, 2.249646661664983, 1.490958235778744e-16, 2.435, 0.9318341578089938, 2.249646661664983, 1.721805012189243, 1.721805012189243, + 2.249646661664983, 0.9318341578089936 }; + + int tab6_1[48]={ + 0, 9, 11, 1, 10, 2, 0, 11, 13, 2, 12, 3, 0, 13, 15, 3, 14, 4, 0, 15, + 17, 4, 16, 5, 0, 17, 19, 5, 18, 6, 0, 19, 21, 6, 20, 7, 0, 21, 23, 7, + 22, 8, 0, 23, 9, 8, 24, 1 }; + + int tab8_1[192]={ + 9, 33, 35, 11, 25, 34, 26, 10, 11, 35, 37, 13, 26, 36, 27, 12, 13, 37, 39, 15, + 27, 38, 28, 14, 15, 39, 41, 17, 28, 40, 29, 16, 17, 41, 43, 19, 29, 42, 30, 18, + 19, 43, 45, 21, 30, 44, 31, 20, 21, 45, 47, 23, 31, 46, 32, 22, 23, 47, 33, 9, + 32, 48, 25, 24, 33, 57, 59, 35, 49, 58, 50, 34, 35, 59, 61, 37, 50, 60, 51, 36, + 37, 61, 63, 39, 51, 62, 52, 38, 39, 63, 65, 41, 52, 64, 53, 40, 41, 65, 67, 43, + 53, 66, 54, 42, 43, 67, 69, 45, 54, 68, 55, 44, 45, 69, 71, 47, 55, 70, 56, 46, + 47, 71, 57, 33, 56, 72, 49, 48, 57, 81, 83, 59, 73, 82, 74, 58, 59, 83, 85, 61, + 74, 84, 75, 60, 61, 85, 87, 63, 75, 86, 76, 62, 63, 87, 89, 65, 76, 88, 77, 64, + 65, 89, 91, 67, 77, 90, 78, 66, 67, 91, 93, 69, 78, 92, 79, 68, 69, 93, 95, 71, + 79, 94, 80, 70, 71, 95, 81, 57, 80, 96, 73, 72 }; + + double coords_2[20]={ + 0.5159941860137611, 0, 0, -0.5159941860137611, -0.5159941860137611, 0, 0, 0.5159941860137611, + 0.6684941860137611, 0, 0, -0.6684941860137611, -0.6684941860137611, 0, 0, 0.6684941860137611, + 0.5922441860137611, 0, -0.5922441860137611, 0 }; + + int tab8_2[16]={ + 0, 4, 6, 2, 8, 5, 9, 1, 2, 6, 4, 0, 9, 7, 8, 3 }; + + double perimeterFromPol1,perimeterFromPol2,perimeterFromPol1AndPol2; + + const int *work1=tab6_1; + for(int i=0;i<8;i++,work1+=6) + { + QuadraticPolygon *pol1=buildQuadraticPolygonCoarseInfo(coords_1,work1,6); + const int *work2=tab8_2; + for(int j=0;j<2;j++,work2+=8) + { + QuadraticPolygon *pol2=buildQuadraticPolygonCoarseInfo(coords_2,work2,8); + //std::vector<int> tmp; + //pol1->intersectForPoint(*pol2,tmp); + pol1->intersectForPerimeter(*pol2,perimeterFromPol1,perimeterFromPol2,perimeterFromPol1AndPol2); + //pol1->intersectMySelfWith(*pol2); + delete pol2; + } + delete pol1; + } + work1=tab8_1; + for(int i=0;i<24;i++,work1+=8) + { + QuadraticPolygon *pol1=buildQuadraticPolygonCoarseInfo(coords_1,work1,8); + const int *work2=tab8_2; + for(int j=0;j<2;j++,work2+=8) + { + + QuadraticPolygon *pol2=buildQuadraticPolygonCoarseInfo(coords_2,work2,8); + //std::vector<int> tmp; + //pol1->intersectForPoint(*pol2,tmp); + pol1->intersectForPerimeter(*pol2,perimeterFromPol1,perimeterFromPol2,perimeterFromPol1AndPol2); + delete pol2; + } + delete pol1; + } +} + +/*! + Some overlapping cases for intersectForPoint. +*/ +void QuadraticPlanarInterpTest::checkNonRegression14() +{ + INTERP_KERNEL::QUADRATIC_PLANAR::setPrecision(1e-7); + INTERP_KERNEL::QUADRATIC_PLANAR::setArcDetectionPrecision(1e-6); + + double coords[72]={ + 1.,0.,1.3,0.,-1.3,0.,-1.,0.,1.15,0.,0.,1.3,-1.15,0.,0.,1., + -0.91923881554251186,-0.91923881554251186,-0.91923881554251186,0.91923881554251186,-1.0606601717798214,1.0606601717798214,-1.0606601717798214,-1.0606601717798214,-1.5,0., + -0.98994949366116658,-0.98994949366116658,-0.98994949366116658,0.98994949366116658, + 0.91923881554251186,0.91923881554251186,1.0606601717798214,1.0606601717798214,0.98994949366116658,0.98994949366116658, 0., 1.5, + -0.83562389259250125,0.99585777605467141, -0.65, 1.1258330249197703, -1.2216004070216808, 0.44462618632336953, -1.1258330249197703, 0.65, + -0.74564936725635955, 1.0648976575756897, -1.6770646146510724, 1.4072242996141826, -1.1782001231476449, 0.54940374026290939, -1.5873847317707279, 0.74020965686300877, + -1.1782001231476449, 0.54940374026290939, -1.0648976575756894, 0.74564936725635977, -1.2950531075192693, -0.11330246557195534, -1.2950531075192693, 0.11330246557195565, + -1.1258330249197703, 0.65, -2.1146554070041046, 0.56662020857685746, -1.6918048488667423, 0.45331774300490169, + 0.,-1.3,0.,-1.5 + }; + int tab[48]={ + 0,1,2,3,4,5,6,7, + 8,9,10,11,2,14,12,13, + 9,15,16,10,5,17,18,14, + 9,15,16,10,34,17,35,14, + 19,20,21,22,23,24,25,26, + 27,28,29,30,31,32,2,33 + }; + QuadraticPolygon *pol1,*pol2; + std::vector<int> goalOfTest; + // + pol1=buildQuadraticPolygonCoarseInfo(coords,tab,8); + // Level 1 + pol2=buildQuadraticPolygonCoarseInfo(coords,tab+8,8); + pol1->intersectForPoint(*pol2,goalOfTest); + const int res1[4]={0,1,0,0}; + CPPUNIT_ASSERT_EQUAL(4,(int)goalOfTest.size()); + CPPUNIT_ASSERT(equal(goalOfTest.begin(),goalOfTest.end(),res1)); + delete pol2; + // Level 2 + pol2=buildQuadraticPolygonCoarseInfo(coords,tab+16,8); + pol1->intersectForPoint(*pol2,goalOfTest); + const int res2[4]={0,2,0,0}; + CPPUNIT_ASSERT_EQUAL(4,(int)goalOfTest.size()); + CPPUNIT_ASSERT(equal(goalOfTest.begin(),goalOfTest.end(),res2)); + delete pol2; + //Level 2 bis + pol2=buildQuadraticPolygonCoarseInfo(coords,tab+24,8); + pol1->intersectForPoint(*pol2,goalOfTest); + const int res2Bis[4]={0,2,0,0}; + CPPUNIT_ASSERT_EQUAL(4,(int)goalOfTest.size()); + CPPUNIT_ASSERT(equal(goalOfTest.begin(),goalOfTest.end(),res2Bis)); + delete pol2; + // Level 3 + pol2=buildQuadraticPolygonCoarseInfo(coords,tab+40,8); + pol1->intersectForPoint(*pol2,goalOfTest); + const int res3[4]={0,3,0,0}; + CPPUNIT_ASSERT_EQUAL(4,(int)goalOfTest.size()); + CPPUNIT_ASSERT(equal(goalOfTest.begin(),goalOfTest.end(),res3)); + delete pol2; + // Level 4 + pol2=buildQuadraticPolygonCoarseInfo(coords,tab+32,8); + pol1->intersectForPoint(*pol2,goalOfTest); + const int res4[4]={0,4,0,0}; + CPPUNIT_ASSERT_EQUAL(4,(int)goalOfTest.size()); + CPPUNIT_ASSERT(equal(goalOfTest.begin(),goalOfTest.end(),res4)); + delete pol2; + // + delete pol1; +} + +/*! + * This test is one of the most complicated intersection configuration. + */ +void QuadraticPlanarInterpTest::checkNonRegression15() +{ + INTERP_KERNEL::QUADRATIC_PLANAR::setPrecision(1e-7); + INTERP_KERNEL::QUADRATIC_PLANAR::setArcDetectionPrecision(1e-6); + + double coords[72]={ + 1.,0.,1.3,0.,-1.3,0.,-1.,0.,1.15,0.,0.,1.3,-1.15,0.,0.,1., + -0.91923881554251186,-0.91923881554251186,-0.91923881554251186,0.91923881554251186,-1.0606601717798214,1.0606601717798214,-1.0606601717798214,-1.0606601717798214,-1.5,0., + -0.98994949366116658,-0.98994949366116658,-0.98994949366116658,0.98994949366116658, + 0.91923881554251186,0.91923881554251186,1.0606601717798214,1.0606601717798214,0.98994949366116658,0.98994949366116658, 0., 1.5, + -0.83562389259250125,0.99585777605467141, -0.65, 1.1258330249197703, -1.2216004070216808, 0.44462618632336953, -1.1258330249197703, 0.65, + -0.74564936725635955, 1.0648976575756897, -1.6770646146510724, 1.4072242996141826, -1.1782001231476449, 0.54940374026290939, -1.5873847317707279, 0.74020965686300877, + -1.1782001231476449, 0.54940374026290939, -1.0648976575756894, 0.74564936725635977, -1.2950531075192693, -0.11330246557195534, -1.2950531075192693, 0.11330246557195565, + -1.1258330249197703, 0.65, -2.1146554070041046, 0.56662020857685746, -1.6918048488667423, 0.45331774300490169, + 0.,-1.3,0.,-1.5 + }; + + int tab[24]={ + 0,1,2,3,4,5,6,7, + 9,15,16,10,7,17,5,14, + 9,10,16,15,14,5,17,7 + }; + + const double RefLgth=3.88995883524451; + const double RefArea=0.383185168001075; + // + QuadraticPolygon *pol1,*pol2; + //pol1 and pol2 in same orientation + pol1=buildQuadraticPolygonCoarseInfo(coords,tab,8); + pol2=buildQuadraticPolygonCoarseInfo(coords,tab+8,8); + std::vector<QuadraticPolygon *> res=pol1->intersectMySelfWith(*pol2); + CPPUNIT_ASSERT_EQUAL(1,(int)res.size()); + CPPUNIT_ASSERT_EQUAL(4,res[0]->recursiveSize()); + CPPUNIT_ASSERT_DOUBLES_EQUAL(RefLgth,res[0]->getPerimeter(),1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(RefArea,res[0]->getArea(),1e-12); + delete res[0]; + //pol1 and pol2 in same orientation but inversing intersection call pol1<->pol2 + res=pol2->intersectMySelfWith(*pol1); + CPPUNIT_ASSERT_EQUAL(1,(int)res.size()); + CPPUNIT_ASSERT_EQUAL(4,res[0]->recursiveSize()); + CPPUNIT_ASSERT_DOUBLES_EQUAL(RefLgth,res[0]->getPerimeter(),1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(RefArea,res[0]->getArea(),1e-12); + delete res[0]; + delete pol2; + //pol1 and pol2 in opposite orientation + pol2=buildQuadraticPolygonCoarseInfo(coords,tab+16,8); + res=pol1->intersectMySelfWith(*pol2); + CPPUNIT_ASSERT_EQUAL(1,(int)res.size()); + CPPUNIT_ASSERT_EQUAL(4,res[0]->recursiveSize()); + CPPUNIT_ASSERT_DOUBLES_EQUAL(RefLgth,res[0]->getPerimeter(),1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(-RefArea,res[0]->getArea(),1e-12); + delete res[0]; + //pol1 and pol2 in opposite orientation but inversing intersection call pol1<->pol2 + res=pol2->intersectMySelfWith(*pol1); + CPPUNIT_ASSERT_EQUAL(1,(int)res.size()); + CPPUNIT_ASSERT_EQUAL(4,res[0]->recursiveSize()); + CPPUNIT_ASSERT_DOUBLES_EQUAL(RefLgth,res[0]->getPerimeter(),1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(RefArea,res[0]->getArea(),1e-12); + delete res[0]; + delete pol2; + // + delete pol1; +} + +class DoubleEqual +{ +public: + DoubleEqual(double eps):_eps(eps) { } + bool operator()(double x, double y) { return fabs(x-y)<_eps; } +private: + double _eps; +}; + +/*! + * This test is to see the reuse of a polygon in intersect* methods. initLocation needed ... + */ +void QuadraticPlanarInterpTest::checkNonRegression16() +{ + INTERP_KERNEL::QUADRATIC_PLANAR::setPrecision(1e-7); + INTERP_KERNEL::QUADRATIC_PLANAR::setArcDetectionPrecision(1e-7); + double coords1[194]={ + 0, 0, 0.304375, 0, 0.2152256265236554, 0.2152256265236554, 1.86369779472343e-17, 0.304375, + -0.2152256265236554, 0.2152256265236554, -0.304375, 3.727395589446861e-17, -0.2152256265236555, -0.2152256265236554, -5.591093384170291e-17, -0.304375, + 0.2152256265236553, -0.2152256265236555, 0.60875, 0, 0.5624116654162458, 0.2329585394522484, 0.4304512530473109, 0.4304512530473108, + 0.2329585394522485, 0.5624116654162458, 3.727395589446861e-17, 0.60875, -0.2329585394522484, 0.5624116654162458, -0.4304512530473108, 0.4304512530473109, + -0.5624116654162458, 0.2329585394522485, -0.60875, 7.454791178893722e-17, -0.5624116654162459, -0.2329585394522483, -0.4304512530473109, -0.4304512530473108, + -0.2329585394522482, -0.5624116654162459, -1.118218676834058e-16, -0.60875, 0.2329585394522485, -0.5624116654162458, 0.4304512530473107, -0.4304512530473109, + 0.5624116654162459, -0.2329585394522483, 0.913125, 0, 0.6456768795709662, 0.6456768795709661, 5.591093384170291e-17, 0.913125, + -0.6456768795709661, 0.6456768795709662, -0.913125, 1.118218676834058e-16, -0.6456768795709663, -0.6456768795709661, -1.677328015251087e-16, -0.913125, + 0.645676879570966, -0.6456768795709663, 1.2175, 0, 1.124823330832492, 0.4659170789044968, 0.8609025060946217, 0.8609025060946216, + 0.4659170789044969, 1.124823330832492, 7.454791178893722e-17, 1.2175, -0.4659170789044967, 1.124823330832492, -0.8609025060946216, 0.8609025060946217, + -1.124823330832492, 0.465917078904497, -1.2175, 1.490958235778744e-16, -1.124823330832492, -0.4659170789044967, -0.8609025060946218, -0.8609025060946216, + -0.4659170789044965, -1.124823330832492, -2.236437353668116e-16, -1.2175, 0.4659170789044971, -1.124823330832492, 0.8609025060946214, -0.8609025060946218, + 1.124823330832492, -0.4659170789044966, 1.521875, 0, 1.076128132618277, 1.076128132618277, 9.318488973617152e-17, 1.521875, + -1.076128132618277, 1.076128132618277, -1.521875, 1.86369779472343e-16, -1.076128132618277, -1.076128132618277, -2.795546692085146e-16, -1.521875, + 1.076128132618277, -1.076128132618277, 1.82625, 0, 1.687234996248737, 0.6988756183567452, 1.291353759141932, 1.291353759141932, + 0.6988756183567453, 1.687234996248737, 1.118218676834058e-16, 1.82625, -0.6988756183567451, 1.687234996248737, -1.291353759141932, 1.291353759141932, + -1.687234996248737, 0.6988756183567454, -1.82625, 2.236437353668116e-16, -1.687234996248738, -0.6988756183567449, -1.291353759141933, -1.291353759141932, + -0.6988756183567447, -1.687234996248738, -3.354656030502175e-16, -1.82625, 0.6988756183567456, -1.687234996248737, 1.291353759141932, -1.291353759141933, + 1.687234996248738, -0.6988756183567448, 2.130625, 0, 1.506579385665588, 1.506579385665588, 1.304588456306401e-16, 2.130625, + -1.506579385665588, 1.506579385665588, -2.130625, 2.609176912612803e-16, -1.506579385665588, -1.506579385665588, -3.913765368919204e-16, -2.130625, + 1.506579385665588, -1.506579385665588, 2.435, 0, 2.249646661664983, 0.9318341578089936, 1.721805012189243, 1.721805012189243, + 0.9318341578089938, 2.249646661664983, 1.490958235778744e-16, 2.435, -0.9318341578089935, 2.249646661664983, -1.721805012189243, 1.721805012189243, + -2.249646661664983, 0.9318341578089939, -2.435, 2.981916471557489e-16, -2.249646661664984, -0.9318341578089934, -1.721805012189244, -1.721805012189243, + -0.9318341578089929, -2.249646661664984, -4.472874707336233e-16, -2.435, 0.9318341578089941, -2.249646661664983, 1.721805012189243, -1.721805012189244, + 2.249646661664984, -0.9318341578089931, }; + + int tab1_8[192]={ + 11, 35, 33, 9, 26, 34, 25, 10, 13, 37, 35, 11, 27, 36, 26, 12, 15, 39, 37, 13, + 28, 38, 27, 14, 17, 41, 39, 15, 29, 40, 28, 16, 19, 43, 41, 17, 30, 42, 29, 18, + 21, 45, 43, 19, 31, 44, 30, 20, 23, 47, 45, 21, 32, 46, 31, 22, 9, 33, 47, 23, + 25, 48, 32, 24, 35, 59, 57, 33, 50, 58, 49, 34, 37, 61, 59, 35, 51, 60, 50, 36, + 39, 63, 61, 37, 52, 62, 51, 38, 41, 65, 63, 39, 53, 64, 52, 40, 43, 67, 65, 41, + 54, 66, 53, 42, 45, 69, 67, 43, 55, 68, 54, 44, 47, 71, 69, 45, 56, 70, 55, 46, + 33, 57, 71, 47, 49, 72, 56, 48, 59, 83, 81, 57, 74, 82, 73, 58, 61, 85, 83, 59, + 75, 84, 74, 60, 63, 87, 85, 61, 76, 86, 75, 62, 65, 89, 87, 63, 77, 88, 76, 64, + 67, 91, 89, 65, 78, 90, 77, 66, 69, 93, 91, 67, 79, 92, 78, 68, 71, 95, 93, 69, + 80, 94, 79, 70, 57, 81, 95, 71, 73, 96, 80, 72, }; + + double coords2[20]={ + 2.435, 0, 0, -2.435, -2.435, 0, 0, 2.435, + 2.6925, 0, 0, -2.6925, -2.6925, 0, 0, 2.6925, + 2.56375, 0, -2.56375, 0, }; + + int tab2_8[16]={ 0, 4, 6, 2, 8, 5, 9, 1, 2, 6, 4, 0, 9, 7, 8, 3 }; + + QuadraticPolygon *pol1,*pol2; + //pol1 and pol2 in same orientation + std::vector<double> test1,test2; + for(int ii=0;ii<24;ii++) + { + pol1=buildQuadraticPolygonCoarseInfo(coords1,tab1_8+8*ii,8); + for(int jj=0;jj<2;jj++) + { + pol2=buildQuadraticPolygonCoarseInfo(coords2,tab2_8+jj*8,8); + // + std::vector<double> v1,v2; + pol1->initLocations(); + pol1->intersectForPerimeterAdvanced(*pol2,v1,v2); + if(ii==16 && jj==1) + test1=v1; + if(ii==20 && jj==1) + test2=v1; + delete pol2; + } + delete pol1; + } + const double test1_res[4]={0.,1.9124445278727873,0.,0.}; + CPPUNIT_ASSERT(std::equal(test1.begin(),test1.end(),test1_res,DoubleEqual(1e-10))); + const double test2_res[4]={0.,0.,0.,0.}; + CPPUNIT_ASSERT(std::equal(test2.begin(),test2.end(),test2_res,DoubleEqual(1e-10))); +} + +/*! + * This test checks overlapped intersections END-INSIDE and INSIDE-START with same and opposite orientation. + */ +void QuadraticPlanarInterpTest::checkNonRegression17() +{ + INTERP_KERNEL::QUADRATIC_PLANAR::setPrecision(1e-7); + INTERP_KERNEL::QUADRATIC_PLANAR::setArcDetectionPrecision(1e-7); + double coords[16]={ + -1., 0., 1., 0. , 1.5, 0., -1.5, 0., + 0. , 1., 1.25, 0., 0., 1.5, -1.25, 0.}; + + double coords2[16]={ + 0.70710678118654757, 0.70710678118654757, -1., 0., -1.25, 0., 0.88388347648318444, 0.88388347648318444, + 0., -1., -1.125, 0., 0., -1.25, 0.79549512883486606, 0.79549512883486606 }; + + double coords3[16]={ + 0.70710678118654757, 0.70710678118654757, 0.88388347648318444, 0.88388347648318444, -1.25, 0., -1., 0., + 0.79549512883486606, 0.79549512883486606, 0., -1.25, -1.125, 0., 0., -1. }; + + int tab8[8]={ + 0, 1, 2, 3, 4, 5, 6, 7 }; + QuadraticPolygon *pol1=buildQuadraticPolygonCoarseInfo(coords,tab8,8); + QuadraticPolygon *pol2=buildQuadraticPolygonCoarseInfo(coords2,tab8,8); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.22089323345553233,pol1->intersectWith(*pol2),1.e-13); + delete pol1; + delete pol2; + pol1=buildQuadraticPolygonCoarseInfo(coords,tab8,8); + pol2=buildQuadraticPolygonCoarseInfo(coords2,tab8,8); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.22089323345553233,pol2->intersectWith(*pol1),1.e-13); + delete pol1; + delete pol2; + pol1=buildQuadraticPolygonCoarseInfo(coords,tab8,8); + pol2=buildQuadraticPolygonCoarseInfo(coords3,tab8,8); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.22089323345553233,pol1->intersectWith(*pol2),1.e-13); + delete pol1; + delete pol2; + pol1=buildQuadraticPolygonCoarseInfo(coords,tab8,8); + pol2=buildQuadraticPolygonCoarseInfo(coords3,tab8,8); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.22089323345553233,pol2->intersectWith(*pol1),1.e-13); + delete pol1; + delete pol2; +} + +void QuadraticPlanarInterpTest::checkNormalize() +{ + INTERP_KERNEL::QUADRATIC_PLANAR::setPrecision(1e-14); + Node *n1=new Node(0.,0.); Node *n4=new Node(0.,-3.); + Node *n2=new Node(10.,0.); Node *n5=new Node(10.,-3.); + Node *n3=new Node(5.,10.); Node *n6=new Node(5.,7.); + EdgeLin *e1_2=new EdgeLin(n1,n2); EdgeLin *e4_5=new EdgeLin(n4,n5); + EdgeLin *e2_3=new EdgeLin(n2,n3); EdgeLin *e5_6=new EdgeLin(n5,n6); + EdgeLin *e3_1=new EdgeLin(n3,n1); EdgeLin *e6_4=new EdgeLin(n6,n4); + // + QuadraticPolygon pol1; pol1.pushBack(e1_2); pol1.pushBack(e2_3); pol1.pushBack(e3_1); + QuadraticPolygon pol2; pol2.pushBack(e4_5); pol2.pushBack(e5_6); pol2.pushBack(e6_4); + n1->decrRef(); n2->decrRef(); n3->decrRef(); n4->decrRef(); n5->decrRef(); n6->decrRef(); + double area1Start=pol1.getArea(); + double xb,yb; + double fact=pol1.normalize(&pol2,xb,yb); + double area1End=pol1.getArea(); + CPPUNIT_ASSERT_DOUBLES_EQUAL(area1Start,area1End*fact*fact,1e-14); + CPPUNIT_ASSERT_DOUBLES_EQUAL(13.,fact,1.e-14); + double area=pol1.intersectWith(pol2); + CPPUNIT_ASSERT_DOUBLES_EQUAL(24.5,area*fact*fact,1e-14); + // + n1=new Node(0.,0.); n4=new Node(0.,-3.); + n2=new Node(10.,0.); n5=new Node(10.,-3.); + n3=new Node(5.,10.); n6=new Node(5.,7.); + e1_2=new EdgeLin(n1,n2); e4_5=new EdgeLin(n4,n5); + e2_3=new EdgeLin(n2,n3); e5_6=new EdgeLin(n5,n6); + e3_1=new EdgeLin(n3,n1); e6_4=new EdgeLin(n6,n4); + QuadraticPolygon pol3; pol3.pushBack(e1_2); pol3.pushBack(e2_3); pol3.pushBack(e3_1); + QuadraticPolygon pol4; pol4.pushBack(e4_5); pol4.pushBack(e5_6); pol4.pushBack(e6_4); + n1->decrRef(); n2->decrRef(); n3->decrRef(); n4->decrRef(); n5->decrRef(); n6->decrRef(); + CPPUNIT_ASSERT_DOUBLES_EQUAL(24.5,pol3.intersectWithAbs(pol4),1.e-14); + // Ok testing EdgeArcCircle update. + double center[2]={5.,5.}; + double radius=300.; + EdgeArcCircle *e1=buildArcOfCircle(center,radius,M_PI/4.,M_PI/3.); + const Bounds& b=e1->getBounds(); + double x,y,fact2; + fact2=b.getCaracteristicDim(); + b.getBarycenter(x,y); + CPPUNIT_ASSERT_DOUBLES_EQUAL(78.539816339744817,e1->getCurveLength(),1e-13); + CPPUNIT_ASSERT_DOUBLES_EQUAL(15106.061037591669,e1->getAreaOfZone(),1e-10); + e1->getStartNode()->applySimilarity(x,y,fact2); + e1->getEndNode()->applySimilarity(x,y,fact2); + e1->applySimilarity(x,y,fact2); + CPPUNIT_ASSERT_DOUBLES_EQUAL(62.132034355964237,fact2,1e-13); + CPPUNIT_ASSERT_DOUBLES_EQUAL(1.2640792652913602,e1->getCurveLength(),1e-14); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.034741420428165526,e1->getAreaOfZone(),1e-13); + e1->decrRef(); +} + +void QuadraticPlanarInterpTest::checkMakePartitionAbs1() +{ + INTERP_KERNEL::QUADRATIC_PLANAR::setPrecision(1e-14); + Node *n0=new Node(0.,0.); Node *n4=new Node(0.5,0.25); + Node *n1=new Node(0.,0.5); Node *n5=new Node(0.3,1.2); + Node *n2=new Node(1.,0.5); Node *n6=new Node(1.1,1.3); + Node *n3=new Node(1.,0.); Node *n7=new Node(-0.1,0.9); + EdgeLin *e0_1=new EdgeLin(n0,n1); + EdgeLin *e1_2=new EdgeLin(n1,n2); EdgeLin *e4_5=new EdgeLin(n4,n5); + EdgeLin *e2_3=new EdgeLin(n2,n3); EdgeLin *e5_6=new EdgeLin(n5,n6); + EdgeLin *e3_0=new EdgeLin(n3,n0); EdgeLin *e6_4=new EdgeLin(n6,n4); + EdgeLin *e4_7=new EdgeLin(n4,n7); EdgeLin *e7_5=new EdgeLin(n7,n5); + QuadraticPolygon pol1; pol1.pushBack(e0_1); pol1.pushBack(e1_2); pol1.pushBack(e2_3); pol1.pushBack(e3_0); + QuadraticPolygon pol2; pol2.pushBack(e4_5); pol2.pushBack(e5_6); pol2.pushBack(e6_4); + pol2.pushBack(e7_5); e4_5->incrRef(); pol2.pushBack(new ElementaryEdge(e4_5,false)); pol2.pushBack(e4_7); + n0->decrRef(); n1->decrRef(); n2->decrRef(); n3->decrRef(); n4->decrRef(); n5->decrRef(); n6->decrRef(); n7->decrRef(); + pol1.dumpInXfigFileWithOther(pol2,"tony.fig"); +} + +} diff --git a/src/medtool/src/INTERP_KERNELTest/QuadraticPlanarInterpTest5.cxx b/src/medtool/src/INTERP_KERNELTest/QuadraticPlanarInterpTest5.cxx new file mode 100644 index 000000000..615969ffb --- /dev/null +++ b/src/medtool/src/INTERP_KERNELTest/QuadraticPlanarInterpTest5.cxx @@ -0,0 +1,1286 @@ +// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 +// 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 "QuadraticPlanarInterpTest.hxx" +#include "InterpKernelGeo2DQuadraticPolygon.hxx" +#include "InterpKernelGeo2DElementaryEdge.hxx" +#include "InterpKernelGeo2DEdgeArcCircle.hxx" +#include "InterpKernelGeo2DEdgeLin.hxx" + +#include <cmath> +#include <sstream> +#include <iostream> +#include <iterator> + +using namespace INTERP_KERNEL; + +namespace INTERP_TEST +{ + +class DoubleEqual +{ +public: + DoubleEqual(double eps):_eps(eps) { } + bool operator()(double x, double y) { return fabs(x-y)<_eps; } +private: + double _eps; +}; + +void QuadraticPlanarInterpTest::checkNonRegressionOmar0000() +{ + INTERP_KERNEL::QUADRATIC_PLANAR::setPrecision(1e-7); + INTERP_KERNEL::QUADRATIC_PLANAR::setArcDetectionPrecision(1e-7); + double coords[16]={ + -0.383022221559489, 0.3213938048432697, -0.5745333323392334, 0.4820907072649046, 0.5745333323392335, 0.4820907072649044, 0.383022221559489, 0.3213938048432696, + -0.4787777769493612, 0.4017422560540872, 4.592273826833915e-17, 0.75, 0.4787777769493612, 0.401742256054087, 3.061515884555943e-17, 0.5 }; + + double coords2[16]={ + -0.383022221559489, -0.1786061951567303, -0.5745333323392334, -0.01790929273509539, 0.5745333323392335, -0.01790929273509556, 0.383022221559489, -0.1786061951567304, + -0.4787777769493612, -0.0982577439459128, 4.592273826833915e-17, 0.25, 0.4787777769493612, -0.09825774394591297, 3.061515884555943e-17, 0 }; + + int tab8[8]={ + 0, 1, 2, 3, 4, 5, 6, 7 }; + QuadraticPolygon *pol1=buildQuadraticPolygonCoarseInfo(coords,tab8,8); + QuadraticPolygon *pol2=buildQuadraticPolygonCoarseInfo(coords2,tab8,8); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.,pol1->intersectWith(*pol2),1.e-13); + delete pol1; + delete pol2; + pol1=buildQuadraticPolygonCoarseInfo(coords,tab8,8); + pol2=buildQuadraticPolygonCoarseInfo(coords2,tab8,8); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.,pol2->intersectWith(*pol1),1.e-13); + delete pol1; + delete pol2; +} + +void QuadraticPlanarInterpTest::checkNonRegressionOmar0001() +{ + INTERP_KERNEL::QUADRATIC_PLANAR::setPrecision(1e-7); + INTERP_KERNEL::QUADRATIC_PLANAR::setArcDetectionPrecision(1e-7); + double coords[16]={ + -0.383022221559489, 0.3213938048432697, -0.5745333323392334, 0.4820907072649046, 0.5745333323392335, 0.4820907072649044, 0.383022221559489, 0.3213938048432696, + -0.4787777769493612, 0.4017422560540872, 4.592273826833915e-17, 0.75, 0.4787777769493612, 0.401742256054087, 3.061515884555943e-17, 0.5 }; + + double coords2[16]={ + -0.383022221559489, 0.3213938048432697, -0.5745333323392334, 0.4820907072649046, 0.5745333323392335, 0.4820907072649044, 0.383022221559489, 0.3213938048432696, + -0.4787777769493612, 0.4017422560540872, 4.592273826833915e-17, 0.75, 0.4787777769493612, 0.401742256054087, 3.061515884555943e-17, 0.5 }; + + int tab8[8]={ + 0, 1, 2, 3, 4, 5, 6, 7 }; + QuadraticPolygon *pol1=buildQuadraticPolygonCoarseInfo(coords,tab8,8); + QuadraticPolygon *pol2=buildQuadraticPolygonCoarseInfo(coords2,tab8,8); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.272708,pol1->intersectWith(*pol2),1.e-6); + delete pol1; + delete pol2; + pol1=buildQuadraticPolygonCoarseInfo(coords,tab8,8); + pol2=buildQuadraticPolygonCoarseInfo(coords2,tab8,8); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.272708,pol2->intersectWith(*pol1),1.e-6); + delete pol1; + delete pol2; +} + +void QuadraticPlanarInterpTest::checkNonRegressionOmar0002() +{ + INTERP_KERNEL::QUADRATIC_PLANAR::setPrecision(1e-7); + INTERP_KERNEL::QUADRATIC_PLANAR::setArcDetectionPrecision(1e-7); + double coords[16]={ + -0.383022221559489, 0.3213938048432697, -0.5745333323392334, 0.4820907072649046, 0.5745333323392335, 0.4820907072649044, 0.383022221559489, 0.3213938048432696, + -0.4787777769493612, 0.4017422560540872, 4.592273826833915e-17, 0.75, 0.4787777769493612, 0.401742256054087, 3.061515884555943e-17, 0.5 }; + + double coords2[16]={ + -0.4979288880273356, 0.4178119462962507, -0.6128355544951823, 0.5142300877492316, 0.6128355544951825, 0.5142300877492314, 0.4979288880273357, 0.4178119462962505, + -0.555382221261259, 0.4660210170227412, 4.898425415289509e-17, 0.8, 0.5553822212612591, 0.466021017022741, 3.979970649922726e-17, 0.65 }; + + int tab8[8]={ + 0, 1, 2, 3, 4, 5, 6, 7 }; + QuadraticPolygon *pol1=buildQuadraticPolygonCoarseInfo(coords,tab8,8); + QuadraticPolygon *pol2=buildQuadraticPolygonCoarseInfo(coords2,tab8,8); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.122173,pol1->intersectWith(*pol2),1.e-6); + delete pol1; + delete pol2; + pol1=buildQuadraticPolygonCoarseInfo(coords,tab8,8); + pol2=buildQuadraticPolygonCoarseInfo(coords2,tab8,8); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.122173,pol2->intersectWith(*pol1),1.e-6); + delete pol1; + delete pol2; +} + +void QuadraticPlanarInterpTest::checkNonRegressionOmar0003() +{ + INTERP_KERNEL::QUADRATIC_PLANAR::setPrecision(1e-7); + INTERP_KERNEL::QUADRATIC_PLANAR::setArcDetectionPrecision(1e-7); + double coords[16]={ + -0.3535533905932737, 0.3535533905932738, -0.5303300858899106, 0.5303300858899107, 0.5303300858899107, 0.5303300858899106, 0.3535533905932738, 0.3535533905932737, + -0.4419417382415922, 0.4419417382415922, 4.592273826833915e-17, 0.75, 0.4419417382415922, 0.4419417382415922, 3.061515884555943e-17, 0.5 }; + + double coords2[16]={ + -0.4979288880273356, 0.4178119462962507, -0.6128355544951823, 0.5142300877492316, 0.6128355544951825, 0.5142300877492314, 0.4979288880273357, 0.4178119462962505, + -0.555382221261259, 0.4660210170227412, 4.898425415289509e-17, 0.8, 0.5553822212612591, 0.466021017022741, 3.979970649922726e-17, 0.65 }; + + int tab8[8]={ + 0, 1, 2, 3, 4, 5, 6, 7 }; + QuadraticPolygon *pol1=buildQuadraticPolygonCoarseInfo(coords,tab8,8); + QuadraticPolygon *pol2=buildQuadraticPolygonCoarseInfo(coords2,tab8,8); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.109956,pol1->intersectWith(*pol2),1.e-6); + delete pol1; + delete pol2; + pol1=buildQuadraticPolygonCoarseInfo(coords,tab8,8); + pol2=buildQuadraticPolygonCoarseInfo(coords2,tab8,8); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.109956,pol2->intersectWith(*pol1),1.e-6); + delete pol1; + delete pol2; +} + +void QuadraticPlanarInterpTest::checkNonRegressionOmar0004() +{ + INTERP_KERNEL::QUADRATIC_PLANAR::setPrecision(1e-7); + INTERP_KERNEL::QUADRATIC_PLANAR::setArcDetectionPrecision(1e-7); + double coords[16]={ + -0.4596194077712559, 0.4596194077712559, -0.5303300858899106, 0.5303300858899107, 0.5303300858899107, 0.5303300858899106, 0.4596194077712559, 0.4596194077712559, + -0.4949747468305832, 0.4949747468305833, 4.592273826833915e-17, 0.75, 0.4949747468305833, 0.4949747468305832, 3.979970649922726e-17, 0.65 }; + + double coords2[16]={ + -0.383022221559489, 0.3213938048432697, -0.6128355544951823, 0.5142300877492316, 0.6128355544951825, 0.5142300877492314, 0.383022221559489, 0.3213938048432696, + -0.4979288880273356, 0.4178119462962507, 4.898425415289509e-17, 0.8, 0.4979288880273357, 0.4178119462962505, 3.061515884555943e-17, 0.5 }; + + int tab8[8]={ + 0, 1, 2, 3, 4, 5, 6, 7 }; + QuadraticPolygon *pol1=buildQuadraticPolygonCoarseInfo(coords,tab8,8); + QuadraticPolygon *pol2=buildQuadraticPolygonCoarseInfo(coords2,tab8,8); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.109956,pol1->intersectWith(*pol2),1.e-6); + delete pol1; + delete pol2; + pol1=buildQuadraticPolygonCoarseInfo(coords,tab8,8); + pol2=buildQuadraticPolygonCoarseInfo(coords2,tab8,8); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.109956,pol2->intersectWith(*pol1),1.e-6); + delete pol1; + delete pol2; +} + +void QuadraticPlanarInterpTest::checkNonRegressionOmar0005() +{ + INTERP_KERNEL::QUADRATIC_PLANAR::setPrecision(1e-7); + INTERP_KERNEL::QUADRATIC_PLANAR::setArcDetectionPrecision(1e-7); + double coords[16]={ + -0.383022221559489, 0.3213938048432697, -0.6128355544951823, 0.5142300877492316, 0.6128355544951825, 0.5142300877492314, 0.383022221559489, 0.3213938048432696, + -0.4979288880273356, 0.4178119462962507, 4.898425415289509e-17, 0.8, 0.4979288880273357, 0.4178119462962505, 3.061515884555943e-17, 0.5 }; + + double coords2[16]={ + -0.4596194077712559, 0.4596194077712559, -0.5303300858899106, 0.5303300858899107, 0.5303300858899107, 0.5303300858899106, 0.4596194077712559, 0.4596194077712559, + -0.4949747468305832, 0.4949747468305833, 4.592273826833915e-17, 0.75, 0.4949747468305833, 0.4949747468305832, 3.979970649922726e-17, 0.65 }; + + int tab8[8]={ + 0, 1, 2, 3, 4, 5, 6, 7 }; + QuadraticPolygon *pol1=buildQuadraticPolygonCoarseInfo(coords,tab8,8); + QuadraticPolygon *pol2=buildQuadraticPolygonCoarseInfo(coords2,tab8,8); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.109956,pol1->intersectWith(*pol2),1.e-6); + delete pol1; + delete pol2; + pol1=buildQuadraticPolygonCoarseInfo(coords,tab8,8); + pol2=buildQuadraticPolygonCoarseInfo(coords2,tab8,8); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.109956,pol2->intersectWith(*pol1),1.e-6); + delete pol1; + delete pol2; +} + +void QuadraticPlanarInterpTest::checkNonRegressionOmar0006() +{ + INTERP_KERNEL::QUADRATIC_PLANAR::setPrecision(1e-7); + INTERP_KERNEL::QUADRATIC_PLANAR::setArcDetectionPrecision(1e-7); + double coords[16]={ + -0.383022221559489, 0.3213938048432697, -0.5362311101832845, 0.4499513267805776, 0.5362311101832846, 0.4499513267805774, 0.383022221559489, 0.3213938048432696, + -0.4596266658713867, 0.3856725658119237, 4.28612223837832e-17, 0.7, 0.4596266658713868, 0.3856725658119236, 3.061515884555943e-17, 0.5 }; + + double coords2[16]={ + -0.1811733315717646, 0.6761480784023478, -0.2070552360820167, 0.7727406610312547, 0.2070552360820166, 0.7727406610312547, 0.1811733315717645, 0.6761480784023478, + -0.1941142838268906, 0.7244443697168013, 4.898425415289509e-17, 0.8, 0.1941142838268906, 0.7244443697168013, 4.28612223837832e-17, 0.7 }; + + int tab8[8]={ + 0, 1, 2, 3, 4, 5, 6, 7 }; + QuadraticPolygon *pol1=buildQuadraticPolygonCoarseInfo(coords,tab8,8); + QuadraticPolygon *pol2=buildQuadraticPolygonCoarseInfo(coords2,tab8,8); + std::vector<double> val1,val2; + pol1->intersectForPerimeterAdvanced(*pol2,val1,val2); + double test1_res[4]={0.,0.366519,0.,0.}; + double test2_res[4]={0.,0.,0.,0.366519}; + CPPUNIT_ASSERT(std::equal(val1.begin(),val1.end(),test1_res,DoubleEqual(1e-6))); + CPPUNIT_ASSERT(std::equal(val2.begin(),val2.end(),test2_res,DoubleEqual(1e-6))); + delete pol1; + delete pol2; +} + +void QuadraticPlanarInterpTest::checkNonRegressionOmar0007() +{ + INTERP_KERNEL::QUADRATIC_PLANAR::setPrecision(1e-7); + INTERP_KERNEL::QUADRATIC_PLANAR::setArcDetectionPrecision(1e-7); + double coords[16]={ + -0.383022221559489, 0.3213938048432697, -0.5362311101832845, 0.4499513267805776, 0.5362311101832846, 0.4499513267805774, 0.383022221559489, 0.3213938048432696, + -0.4596266658713867, 0.3856725658119237, 4.28612223837832e-17, 0.7, 0.4596266658713868, 0.3856725658119236, 3.061515884555943e-17, 0.5 }; + + double coords2[16]={ + -0.4499513267805775, 0.5362311101832846, -0.5142300877492315, 0.6128355544951825, -0.1389185421335442, 0.7878462024097664, -0.1215537243668512, 0.6893654271085455, + -0.4820907072649045, 0.5745333323392335, -0.3380946093925595, 0.7250462296293201, -0.1302361332501977, 0.738605814759156, -0.2958327832184895, 0.634415450925655 }; + + int tab8[8]={ + 0, 1, 2, 3, 4, 5, 6, 7 }; + QuadraticPolygon *pol1=buildQuadraticPolygonCoarseInfo(coords,tab8,8); + QuadraticPolygon *pol2=buildQuadraticPolygonCoarseInfo(coords2,tab8,8); + std::vector<double> val1,val2; + pol1->intersectForPerimeterAdvanced(*pol2,val1,val2); + double test1_res[4]={0.,0.366519,0.,0.}; + double test2_res[4]={0.,0.,0.,0.366519}; + CPPUNIT_ASSERT(std::equal(val1.begin(),val1.end(),test1_res,DoubleEqual(1e-6))); + CPPUNIT_ASSERT(std::equal(val2.begin(),val2.end(),test2_res,DoubleEqual(1e-6))); + delete pol1; + delete pol2; +} + +void QuadraticPlanarInterpTest::checkNonRegressionOmar0008() +{ + INTERP_KERNEL::QUADRATIC_PLANAR::setPrecision(1e-7); + INTERP_KERNEL::QUADRATIC_PLANAR::setArcDetectionPrecision(1e-7); + double coords[16]={ + -0.383022221559489, 0.3213938048432697, -0.5362311101832845, 0.4499513267805776, 0.5362311101832846, 0.4499513267805774, 0.383022221559489, 0.3213938048432696, + -0.4596266658713867, 0.3856725658119237, 4.28612223837832e-17, 0.7, 0.4596266658713868, 0.3856725658119236, 3.061515884555943e-17, 0.5 }; + + double coords2[16]={ + -0.6344154509256549, 0.2958327832184896, -0.72504622962932, 0.3380946093925596, -0.4588611490808367, 0.6553216354311937, -0.401503505445732, 0.5734064310022944, + -0.6797308402774874, 0.3169636963055246, -0.6128355544951823, 0.5142300877492316, -0.4301823272632844, 0.614364033216744, -0.5362311101832845, 0.4499513267805776 }; + + int tab8[8]={ + 0, 1, 2, 3, 4, 5, 6, 7 }; + QuadraticPolygon *pol1=buildQuadraticPolygonCoarseInfo(coords,tab8,8); + QuadraticPolygon *pol2=buildQuadraticPolygonCoarseInfo(coords2,tab8,8); + std::vector<double> val1,val2; + pol1->intersectForPerimeterAdvanced(*pol2,val1,val2); + double test1_res[4]={0.,0.18326,0.,0.}; + double test2_res[4]={0.,0.,0.,0.18326}; + CPPUNIT_ASSERT(std::equal(val1.begin(),val1.end(),test1_res,DoubleEqual(1e-5))); + CPPUNIT_ASSERT(std::equal(val2.begin(),val2.end(),test2_res,DoubleEqual(1e-5))); + delete pol1; + delete pol2; +} + +void QuadraticPlanarInterpTest::checkNonRegressionOmar0009() +{ + INTERP_KERNEL::QUADRATIC_PLANAR::setPrecision(1e-7); + INTERP_KERNEL::QUADRATIC_PLANAR::setArcDetectionPrecision(1e-7); + double coords[16]={ + -0.3863703305156274, -0.1035276180410081, -0.4829629131445342, -0.1294095225512602, 0.4829629131445342, -0.1294095225512604, 0.3863703305156274, -0.1035276180410083, + -0.4346666218300808, -0.1164685702961342, 1.416374613080751e-16, 0.5, 0.4346666218300808, -0.1164685702961343, 1.133099690464601e-16, 0.4 }; + double coords2[16]={ + 0.5, -1.224606353822377e-16, 0.6, -1.469527624586853e-16, -0.6, 7.347638122934263e-17, -0.5, 6.123031769111886e-17, + 0.55, -1.347066989204615e-16, -1.102145718440139e-16, -0.6, -0.55, 6.735334946023075e-17, -9.184547653667829e-17, -0.5 }; + + int tab8[8]={ + 0, 1, 2, 3, 4, 5, 6, 7 }; + QuadraticPolygon *pol1=buildQuadraticPolygonCoarseInfo(coords,tab8,8); + QuadraticPolygon *pol2=buildQuadraticPolygonCoarseInfo(coords2,tab8,8); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.,pol1->intersectWith(*pol2),1.e-13); + delete pol1; + delete pol2; + pol1=buildQuadraticPolygonCoarseInfo(coords,tab8,8); + pol2=buildQuadraticPolygonCoarseInfo(coords2,tab8,8); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.,pol2->intersectWith(*pol1),1.e-13); + delete pol1; + delete pol2; +} + +void QuadraticPlanarInterpTest::checkNonRegressionOmar0010() +{ + INTERP_KERNEL::QUADRATIC_PLANAR::setPrecision(1e-7); + INTERP_KERNEL::QUADRATIC_PLANAR::setArcDetectionPrecision(1e-7); + double coords[16]={ + -0.3863703305156274, -0.1035276180410081, -0.4829629131445342, -0.1294095225512602, 0.4829629131445342, -0.1294095225512604, 0.3863703305156274, -0.1035276180410083, +-0.4346666218300808, -0.1164685702961342, 1.416374613080751e-16, 0.5, 0.4346666218300808, -0.1164685702961343, 1.133099690464601e-16, 0.4 }; + double coords2[16]={ + 0.4346666218300808, -0.1164685702961343, 0.579555495773441, -0.1552914270615124, -0.579555495773441, -0.1552914270615122, -0.4346666218300808, -0.1164685702961342, +0.5071110588017609, -0.1358799986788234, -1.102145718440139e-16, -0.6, -0.507111058801761, -0.1358799986788232, -8.266092888301047e-17, -0.45 }; + + int tab8[8]={ + 0, 1, 2, 3, 4, 5, 6, 7 }; + QuadraticPolygon *pol1=buildQuadraticPolygonCoarseInfo(coords,tab8,8); + QuadraticPolygon *pol2=buildQuadraticPolygonCoarseInfo(coords2,tab8,8); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.,pol1->intersectWith(*pol2),1.e-13); + delete pol1; + delete pol2; + pol1=buildQuadraticPolygonCoarseInfo(coords,tab8,8); + pol2=buildQuadraticPolygonCoarseInfo(coords2,tab8,8); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.,pol2->intersectWith(*pol1),1.e-13); + delete pol1; + delete pol2; +} + +void QuadraticPlanarInterpTest::checkNonRegressionOmar0011() +{ + INTERP_KERNEL::QUADRATIC_PLANAR::setPrecision(1e-7); + INTERP_KERNEL::QUADRATIC_PLANAR::setArcDetectionPrecision(1e-7); + double coords[16]={ + -0.3863703305156274, -0.1035276180410081, -0.4829629131445342, -0.1294095225512602, 0.4829629131445342, -0.1294095225512604, 0.3863703305156274, -0.1035276180410083, +-0.4346666218300808, -0.1164685702961342, 1.416374613080751e-16, 0.5, 0.4346666218300808, -0.1164685702961343, 1.133099690464601e-16, 0.4 }; + double coords2[16]={ + 0.4829629131445342, -0.1294095225512603, 0.579555495773441, -0.1552914270615124, -0.579555495773441, -0.1552914270615122, -0.4829629131445342, -0.1294095225512602, +0.5312592044589877, -0.1423504748063864, -1.102145718440139e-16, -0.6, -0.5312592044589877, -0.1423504748063862, -9.184547653667829e-17, -0.5 }; + + int tab8[8]={ + 0, 1, 2, 3, 4, 5, 6, 7 }; + QuadraticPolygon *pol1=buildQuadraticPolygonCoarseInfo(coords,tab8,8); + QuadraticPolygon *pol2=buildQuadraticPolygonCoarseInfo(coords2,tab8,8); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.,pol1->intersectWith(*pol2),1.e-13); + double val1,val2,val3; + pol1->intersectForPerimeter(*pol2,val1,val2,val3); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.,val1,1.e-13); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.,val2,1.e-13); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.,val3,1.e-13); + std::vector<double> val4,val5; + pol1->intersectForPerimeterAdvanced(*pol2,val4,val5); + double test1_res[4]={0.,0.,0.,0.}; + CPPUNIT_ASSERT(std::equal(val4.begin(),val4.end(),test1_res,DoubleEqual(1e-13))); + CPPUNIT_ASSERT(std::equal(val5.begin(),val5.end(),test1_res,DoubleEqual(1e-13))); + delete pol1; + delete pol2; + pol1=buildQuadraticPolygonCoarseInfo(coords,tab8,8); + pol2=buildQuadraticPolygonCoarseInfo(coords2,tab8,8); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.,pol2->intersectWith(*pol1),1.e-13); + pol1->intersectForPerimeter(*pol2,val1,val2,val3); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.,val1,1.e-13); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.,val2,1.e-13); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.,val3,1.e-13); + val4.clear(); val5.clear(); + pol1->intersectForPerimeterAdvanced(*pol2,val4,val5); + CPPUNIT_ASSERT(std::equal(val4.begin(),val4.end(),test1_res,DoubleEqual(1e-13))); + CPPUNIT_ASSERT(std::equal(val5.begin(),val5.end(),test1_res,DoubleEqual(1e-13))); + delete pol1; + delete pol2; +} + +void QuadraticPlanarInterpTest::checkNonRegressionOmar2511() +{ + INTERP_KERNEL::QUADRATIC_PLANAR::setPrecision(1e-7); + INTERP_KERNEL::QUADRATIC_PLANAR::setArcDetectionPrecision(1e-7); + double coords[16]={ + -0.3863703305156274, -0.1035276180410081, -0.4829629131445342, -0.1294095225512602, 0.4829629131445342, -0.1294095225512604, 0.3863703305156274, -0.1035276180410083, + -0.4346666218300808, -0.1164685702961342, 1.416374613080751e-16, 0.5, 0.4346666218300808, -0.1164685702961343, 1.133099690464601e-16, 0.4, }; + + double coords2[16]={ + 0.579555495773441, -0.1552914270615124, -0.579555495773441, -0.1552914270615122, -0.4829629131445342, -0.1294095225512602, 0.4829629131445342, -0.1294095225512603, + -1.102145718440139e-16, -0.6, -0.5312592044589877, -0.1423504748063862, -9.184547653667829e-17, -0.5, 0.5312592044589877, -0.1423504748063864, }; + + int tab8[8]={ + 0, 1, 2, 3, 4, 5, 6, 7 }; + QuadraticPolygon *pol1=buildQuadraticPolygonCoarseInfo(coords,tab8,8); + QuadraticPolygon *pol2=buildQuadraticPolygonCoarseInfo(coords2,tab8,8); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.,pol1->intersectWith(*pol2),1.e-13); + double val1,val2,val3; + pol1->intersectForPerimeter(*pol2,val1,val2,val3); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.,val1,1.e-13); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.,val2,1.e-13); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.,val3,1.e-13); + std::vector<double> val4,val5; + pol1->intersectForPerimeterAdvanced(*pol2,val4,val5); + double test1_res[4]={0.,0.,0.,0.}; + CPPUNIT_ASSERT(std::equal(val4.begin(),val4.end(),test1_res,DoubleEqual(1e-13))); + CPPUNIT_ASSERT(std::equal(val5.begin(),val5.end(),test1_res,DoubleEqual(1e-13))); + delete pol1; + delete pol2; + pol1=buildQuadraticPolygonCoarseInfo(coords,tab8,8); + pol2=buildQuadraticPolygonCoarseInfo(coords2,tab8,8); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.,pol2->intersectWith(*pol1),1.e-13); + pol1->intersectForPerimeter(*pol2,val1,val2,val3); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.,val1,1.e-13); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.,val2,1.e-13); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.,val3,1.e-13); + val4.clear(); val5.clear(); + pol1->intersectForPerimeterAdvanced(*pol2,val4,val5); + CPPUNIT_ASSERT(std::equal(val4.begin(),val4.end(),test1_res,DoubleEqual(1e-13))); + CPPUNIT_ASSERT(std::equal(val5.begin(),val5.end(),test1_res,DoubleEqual(1e-13))); + delete pol1; + delete pol2; +} + +void QuadraticPlanarInterpTest::checkNonRegressionOmar0012() +{ + INTERP_KERNEL::QUADRATIC_PLANAR::setPrecision(1e-7); + INTERP_KERNEL::QUADRATIC_PLANAR::setArcDetectionPrecision(1e-7); + double coords[16]={ + -1, 1.224606353822377e-16, -1.6, 1.959370166115804e-16, 9.796850830579018e-17, 1.6, 6.123031769111886e-17, 1, + -1.3, 1.591988259969091e-16, -1.131370849898476, 1.131370849898476, 7.959941299845453e-17, 1.3, -0.7071067811865475, 0.7071067811865476 }; + + double coords2[16]={ + 6.123031769111886e-18, 1.85, 1.224606353822377e-17, 1.95, 1.224606353822377e-17, 1.55, 6.123031769111886e-18, 1.65, + 9.18454765366783e-18, 1.9, 0.2, 1.75, 9.18454765366783e-18, 1.6, 0.1, 1.75 }; + + int tab8[8]={ + 0, 1, 2, 3, 4, 5, 6, 7 }; + QuadraticPolygon *pol1=buildQuadraticPolygonCoarseInfo(coords,tab8,8); + QuadraticPolygon *pol2=buildQuadraticPolygonCoarseInfo(coords2,tab8,8); + std::vector<double> val1,val2; + pol1->intersectForPerimeterAdvanced(*pol2,val1,val2); + double test1_res[4]={0.,0.,0.05,0.}; + double test2_res[4]={0.,0.,0.05,0.}; + CPPUNIT_ASSERT(std::equal(val1.begin(),val1.end(),test1_res,DoubleEqual(1e-13))); + CPPUNIT_ASSERT(std::equal(val2.begin(),val2.end(),test2_res,DoubleEqual(1e-13))); + delete pol1; + delete pol2; + std::vector<int> val3; + pol1=buildQuadraticPolygonCoarseInfo(coords,tab8,8); + pol2=buildQuadraticPolygonCoarseInfo(coords2,tab8,8); + pol1->intersectForPoint(*pol2,val3); + int test3_res[4]={0,0,1,0}; + CPPUNIT_ASSERT(std::equal(val3.begin(),val3.end(),test3_res)); + delete pol1; + delete pol2; +} + +void QuadraticPlanarInterpTest::checkNonRegressionOmar0013() +{ + INTERP_KERNEL::QUADRATIC_PLANAR::setPrecision(1e-7); + INTERP_KERNEL::QUADRATIC_PLANAR::setArcDetectionPrecision(1e-7); + double coords[16]={ + -1, 1.224606353822377e-16, -1.6, 1.959370166115804e-16, 9.796850830579018e-17, 1.6, 6.123031769111886e-17, 1, + -1.3, 1.591988259969091e-16, -1.131370849898476, 1.131370849898476, 7.959941299845453e-17, 1.3, -0.7071067811865475, 0.7071067811865476 }; + + double coords2[16]={ + 6.123031769111886e-18, 1.7, 1.224606353822377e-17, 1.8, 1.224606353822377e-17, 1.4, 6.123031769111886e-18, 1.5, + 9.18454765366783e-18, 1.75, 0.2, 1.6, 9.18454765366783e-18, 1.45, 0.1, 1.6 }; + + int tab8[8]={ + 0, 1, 2, 3, 4, 5, 6, 7 }; + QuadraticPolygon *pol1=buildQuadraticPolygonCoarseInfo(coords,tab8,8); + QuadraticPolygon *pol2=buildQuadraticPolygonCoarseInfo(coords2,tab8,8); + std::vector<double> val1,val2; + pol1->intersectForPerimeterAdvanced(*pol2,val1,val2); + double test1_res[4]={0.,0.,0.1,0.}; + double test2_res[4]={0.,0.,0.1,0.}; + CPPUNIT_ASSERT(std::equal(val1.begin(),val1.end(),test1_res,DoubleEqual(1e-13))); + CPPUNIT_ASSERT(std::equal(val2.begin(),val2.end(),test2_res,DoubleEqual(1e-13))); + delete pol1; + delete pol2; + std::vector<int> val3; + pol1=buildQuadraticPolygonCoarseInfo(coords,tab8,8); + pol2=buildQuadraticPolygonCoarseInfo(coords2,tab8,8); + pol1->intersectForPoint(*pol2,val3); + int test3_res[4]={0,0,2,0}; + CPPUNIT_ASSERT(std::equal(val3.begin(),val3.end(),test3_res)); + delete pol1; + delete pol2; +} + +void QuadraticPlanarInterpTest::checkNonRegressionOmar0014() +{ + INTERP_KERNEL::QUADRATIC_PLANAR::setPrecision(1e-7); + INTERP_KERNEL::QUADRATIC_PLANAR::setArcDetectionPrecision(1e-7); + double coords[16]={ + -1, 1.224606353822377e-16, -1.6, 1.959370166115804e-16, 9.796850830579018e-17, 1.6, 6.123031769111886e-17, 1, +-1.3, 1.591988259969091e-16, -1.131370849898476, 1.131370849898476, 7.959941299845453e-17, 1.3, -0.7071067811865475, 0.7071067811865476 }; + double coords2[16]={ + 6.123031769111886e-18, 1.55, 1.224606353822377e-17, 1.65, 1.224606353822377e-17, 1.25, 6.123031769111886e-18, 1.35, +9.18454765366783e-18, 1.6, 0.2, 1.45, 9.18454765366783e-18, 1.3, 0.1, 1.45 }; + + int tab8[8]={ + 0, 1, 2, 3, 4, 5, 6, 7 }; + QuadraticPolygon *pol1=buildQuadraticPolygonCoarseInfo(coords,tab8,8); + QuadraticPolygon *pol2=buildQuadraticPolygonCoarseInfo(coords2,tab8,8); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.,pol1->intersectWith(*pol2),1.e-13); + delete pol1; + delete pol2; + pol1=buildQuadraticPolygonCoarseInfo(coords,tab8,8); + pol2=buildQuadraticPolygonCoarseInfo(coords2,tab8,8); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.,pol2->intersectWith(*pol1),1.e-13); + delete pol1; + delete pol2; + // + pol1=buildQuadraticPolygonCoarseInfo(coords,tab8,8); + pol2=buildQuadraticPolygonCoarseInfo(coords2,tab8,8); + std::vector<double> val1,val2; + pol1->intersectForPerimeterAdvanced(*pol2,val1,val2); + double test1_res[4]={0.,0.,0.15,0.}; + double test2_res[4]={0.05,0.,0.1,0.}; + CPPUNIT_ASSERT(std::equal(val1.begin(),val1.end(),test1_res,DoubleEqual(1e-13))); + CPPUNIT_ASSERT(std::equal(val2.begin(),val2.end(),test2_res,DoubleEqual(1e-13))); + delete pol1; + delete pol2; + std::vector<int> val3; + pol1=buildQuadraticPolygonCoarseInfo(coords,tab8,8); + pol2=buildQuadraticPolygonCoarseInfo(coords2,tab8,8); + pol1->intersectForPoint(*pol2,val3); + int test3_res[4]={0,0,3,0}; + CPPUNIT_ASSERT(std::equal(val3.begin(),val3.end(),test3_res)); + delete pol1; + delete pol2; +} + +void QuadraticPlanarInterpTest::checkNonRegressionOmar0015() +{ + INTERP_KERNEL::QUADRATIC_PLANAR::setPrecision(1e-7); + INTERP_KERNEL::QUADRATIC_PLANAR::setArcDetectionPrecision(1e-7); + double coords[16]={ + -1, 1.224606353822377e-16, -1.6, 1.959370166115804e-16, 9.796850830579018e-17, 1.6, 6.123031769111886e-17, 1, +-1.3, 1.591988259969091e-16, -1.131370849898476, 1.131370849898476, 7.959941299845453e-17, 1.3, -0.7071067811865475, 0.7071067811865476 }; + double coords2[16]={ + 6.123031769111886e-18, 1.4, 1.224606353822377e-17, 1.5, 1.224606353822377e-17, 1.1, 6.123031769111886e-18, 1.2, +9.18454765366783e-18, 1.45, 0.2, 1.3, 9.18454765366783e-18, 1.15, 0.1, 1.3 }; + + int tab8[8]={ + 0, 1, 2, 3, 4, 5, 6, 7 }; + QuadraticPolygon *pol1=buildQuadraticPolygonCoarseInfo(coords,tab8,8); + QuadraticPolygon *pol2=buildQuadraticPolygonCoarseInfo(coords2,tab8,8); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.,pol1->intersectWith(*pol2),1.e-13); + delete pol1; + delete pol2; + pol1=buildQuadraticPolygonCoarseInfo(coords,tab8,8); + pol2=buildQuadraticPolygonCoarseInfo(coords2,tab8,8); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.,pol2->intersectWith(*pol1),1.e-13); + delete pol1; + delete pol2; + // + pol1=buildQuadraticPolygonCoarseInfo(coords,tab8,8); + pol2=buildQuadraticPolygonCoarseInfo(coords2,tab8,8); + std::vector<double> val1,val2; + pol1->intersectForPerimeterAdvanced(*pol2,val1,val2); + double test1_res[4]={0.,0.,0.2,0.}; + double test2_res[4]={0.1,0.,0.1,0.}; + CPPUNIT_ASSERT(std::equal(val1.begin(),val1.end(),test1_res,DoubleEqual(1e-13))); + CPPUNIT_ASSERT(std::equal(val2.begin(),val2.end(),test2_res,DoubleEqual(1e-13))); + delete pol1; + delete pol2; + std::vector<int> val3; + pol1=buildQuadraticPolygonCoarseInfo(coords,tab8,8); + pol2=buildQuadraticPolygonCoarseInfo(coords2,tab8,8); + pol1->intersectForPoint(*pol2,val3); + int test3_res[4]={0,0,4,0}; + CPPUNIT_ASSERT(std::equal(val3.begin(),val3.end(),test3_res)); + delete pol1; + delete pol2; +} + +void QuadraticPlanarInterpTest::checkNonRegressionOmar0016() +{ + INTERP_KERNEL::QUADRATIC_PLANAR::setPrecision(1e-7); + INTERP_KERNEL::QUADRATIC_PLANAR::setArcDetectionPrecision(1e-7); + double coords[16]={ + -1, 1.224606353822377e-16, -1.6, 1.959370166115804e-16, 9.796850830579018e-17, 1.6, 6.123031769111886e-17, 1, +-1.3, 1.591988259969091e-16, -1.131370849898476, 1.131370849898476, 7.959941299845453e-17, 1.3, -0.7071067811865475, 0.7071067811865476 }; + double coords2[16]={ + 6.123031769111886e-18, 1.25, 1.224606353822377e-17, 1.35, 1.224606353822377e-17, 0.95, 6.123031769111886e-18, 1.05, +9.18454765366783e-18, 1.3, 0.2, 1.15, 9.18454765366783e-18, 0.9999999999999999, 0.1, 1.15 }; + + int tab8[8]={ + 0, 1, 2, 3, 4, 5, 6, 7 }; + QuadraticPolygon *pol1=buildQuadraticPolygonCoarseInfo(coords,tab8,8); + QuadraticPolygon *pol2=buildQuadraticPolygonCoarseInfo(coords2,tab8,8); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.,pol1->intersectWith(*pol2),1.e-13); + delete pol1; + delete pol2; + pol1=buildQuadraticPolygonCoarseInfo(coords,tab8,8); + pol2=buildQuadraticPolygonCoarseInfo(coords2,tab8,8); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.,pol2->intersectWith(*pol1),1.e-13); + delete pol1; + delete pol2; + // + pol1=buildQuadraticPolygonCoarseInfo(coords,tab8,8); + pol2=buildQuadraticPolygonCoarseInfo(coords2,tab8,8); + std::vector<double> val1,val2; + pol1->intersectForPerimeterAdvanced(*pol2,val1,val2); + double test1_res[4]={0.,0.,0.15,0.}; + double test2_res[4]={0.1,0.,0.05,0.}; + CPPUNIT_ASSERT(std::equal(val1.begin(),val1.end(),test1_res,DoubleEqual(1e-13))); + CPPUNIT_ASSERT(std::equal(val2.begin(),val2.end(),test2_res,DoubleEqual(1e-13))); + delete pol1; + delete pol2; + std::vector<int> val3; + pol1=buildQuadraticPolygonCoarseInfo(coords,tab8,8); + pol2=buildQuadraticPolygonCoarseInfo(coords2,tab8,8); + pol1->intersectForPoint(*pol2,val3); + int test3_res[4]={0,0,3,0}; + CPPUNIT_ASSERT(std::equal(val3.begin(),val3.end(),test3_res)); + delete pol1; + delete pol2; +} + +void QuadraticPlanarInterpTest::checkNonRegressionOmar0017() +{ + INTERP_KERNEL::QUADRATIC_PLANAR::setPrecision(1e-7); + INTERP_KERNEL::QUADRATIC_PLANAR::setArcDetectionPrecision(1e-7); + double coords[16]={ + -1, 1.224606353822377e-16, -1.6, 1.959370166115804e-16, 9.796850830579018e-17, 1.6, 6.123031769111886e-17, 1, + -1.3, 1.591988259969091e-16, -1.131370849898476, 1.131370849898476, 7.959941299845453e-17, 1.3, -0.7071067811865475, 0.7071067811865476 }; + + double coords2[16]={ + 6.123031769111886e-18, 1.1, 1.224606353822377e-17, 1.2, 1.224606353822377e-17, 0.8, 6.123031769111886e-18, 0.9, + 9.18454765366783e-18, 1.15, 0.2, 1, 9.18454765366783e-18, 0.85, 0.1, 1 }; + + int tab8[8]={ + 0, 1, 2, 3, 4, 5, 6, 7 }; + QuadraticPolygon *pol1=buildQuadraticPolygonCoarseInfo(coords,tab8,8); + QuadraticPolygon *pol2=buildQuadraticPolygonCoarseInfo(coords2,tab8,8); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.,pol1->intersectWith(*pol2),1.e-13); + delete pol1; + delete pol2; + pol1=buildQuadraticPolygonCoarseInfo(coords,tab8,8); + pol2=buildQuadraticPolygonCoarseInfo(coords2,tab8,8); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.,pol2->intersectWith(*pol1),1.e-13); + delete pol1; + delete pol2; + // + pol1=buildQuadraticPolygonCoarseInfo(coords,tab8,8); + pol2=buildQuadraticPolygonCoarseInfo(coords2,tab8,8); + std::vector<double> val1,val2; + pol1->intersectForPerimeterAdvanced(*pol2,val1,val2); + double test1_res[4]={0.,0.,0.1,0.}; + double test2_res[4]={0.1,0.,0.,0.}; + CPPUNIT_ASSERT(std::equal(val1.begin(),val1.end(),test1_res,DoubleEqual(1e-13))); + CPPUNIT_ASSERT(std::equal(val2.begin(),val2.end(),test2_res,DoubleEqual(1e-13))); + delete pol1; + delete pol2; + std::vector<int> val3; + pol1=buildQuadraticPolygonCoarseInfo(coords,tab8,8); + pol2=buildQuadraticPolygonCoarseInfo(coords2,tab8,8); + pol1->intersectForPoint(*pol2,val3); + int test3_res[4]={0,0,2,0}; + CPPUNIT_ASSERT(std::equal(val3.begin(),val3.end(),test3_res)); + delete pol1; + delete pol2; +} + +void QuadraticPlanarInterpTest::checkNonRegressionOmar0018() +{ + INTERP_KERNEL::QUADRATIC_PLANAR::setPrecision(1e-7); + INTERP_KERNEL::QUADRATIC_PLANAR::setArcDetectionPrecision(1e-7); + double coords[16]={ + -1, 1.224606353822377e-16, -1.6, 1.959370166115804e-16, 9.796850830579018e-17, 1.6, 6.123031769111886e-17, 1, + -1.3, 1.591988259969091e-16, -1.131370849898476, 1.131370849898476, 7.959941299845453e-17, 1.3, -0.7071067811865475, 0.7071067811865476 }; + + double coords2[16]={ + 6.123031769111886e-18, 0.95, 1.224606353822377e-17, 1.05, 1.224606353822377e-17, 0.6499999999999999, 6.123031769111886e-18, 0.75, + 9.18454765366783e-18, 1, 0.2, 0.85, 9.18454765366783e-18, 0.7, 0.1, 0.85 }; + + int tab8[8]={ + 0, 1, 2, 3, 4, 5, 6, 7 }; + QuadraticPolygon *pol1=buildQuadraticPolygonCoarseInfo(coords,tab8,8); + QuadraticPolygon *pol2=buildQuadraticPolygonCoarseInfo(coords2,tab8,8); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.,pol1->intersectWith(*pol2),1.e-13); + delete pol1; + delete pol2; + pol1=buildQuadraticPolygonCoarseInfo(coords,tab8,8); + pol2=buildQuadraticPolygonCoarseInfo(coords2,tab8,8); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.,pol2->intersectWith(*pol1),1.e-13); + delete pol1; + delete pol2; + // + pol1=buildQuadraticPolygonCoarseInfo(coords,tab8,8); + pol2=buildQuadraticPolygonCoarseInfo(coords2,tab8,8); + std::vector<double> val1,val2; + pol1->intersectForPerimeterAdvanced(*pol2,val1,val2); + double test1_res[4]={0.,0.,0.05,0.}; + double test2_res[4]={0.05,0.,0.,0.}; + CPPUNIT_ASSERT(std::equal(val1.begin(),val1.end(),test1_res,DoubleEqual(1e-13))); + CPPUNIT_ASSERT(std::equal(val2.begin(),val2.end(),test2_res,DoubleEqual(1e-13))); + delete pol1; + delete pol2; + std::vector<int> val3; + pol1=buildQuadraticPolygonCoarseInfo(coords,tab8,8); + pol2=buildQuadraticPolygonCoarseInfo(coords2,tab8,8); + pol1->intersectForPoint(*pol2,val3); + int test3_res[4]={0,0,1,0}; + CPPUNIT_ASSERT(std::equal(val3.begin(),val3.end(),test3_res)); + delete pol1; + delete pol2; +} + +void QuadraticPlanarInterpTest::checkNonRegressionOmar0019() +{ + INTERP_KERNEL::QUADRATIC_PLANAR::setPrecision(1e-7); + INTERP_KERNEL::QUADRATIC_PLANAR::setArcDetectionPrecision(1e-7); + double coords[16]={ + -0.5, 6.123031769111886e-17, -0.8, 9.796850830579018e-17, 0.8, 0, 0.5, 0, + -0.65, 7.959941299845453e-17, 4.898425415289509e-17, 0.8, 0.65, 0, 3.061515884555943e-17, 0.5 }; + + double coords2[16]={ + 0.9500000000000001, 1.836909530733566e-17, 0.8, 3.673819061467131e-17, 1.4, 0, 1.25, 0, + 0.8750000000000001, 2.755364296100349e-17, 1.1, 0.3, 1.325, 0, 1.1, 0.15 }; + + int tab8[8]={ + 0, 1, 2, 3, 4, 5, 6, 7 }; + QuadraticPolygon *pol1=buildQuadraticPolygonCoarseInfo(coords,tab8,8); + QuadraticPolygon *pol2=buildQuadraticPolygonCoarseInfo(coords2,tab8,8); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.,pol1->intersectWith(*pol2),1.e-13); + delete pol1; + delete pol2; + pol1=buildQuadraticPolygonCoarseInfo(coords,tab8,8); + pol2=buildQuadraticPolygonCoarseInfo(coords2,tab8,8); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.,pol2->intersectWith(*pol1),1.e-13); + delete pol1; + delete pol2; +} + +void QuadraticPlanarInterpTest::checkNonRegressionOmar0020() +{ + INTERP_KERNEL::QUADRATIC_PLANAR::setPrecision(1e-7); + INTERP_KERNEL::QUADRATIC_PLANAR::setArcDetectionPrecision(1e-7); + double coords[16]={ + -0.5, 6.123031769111886e-17, -0.8, 9.796850830579018e-17, 0.8, 0, 0.5, 0, + -0.65, 7.959941299845453e-17, 4.898425415289509e-17, 0.8, 0.65, 0, 3.061515884555943e-17, 0.5 }; + + double coords2[16]={ + 0.05000000000000002, 1.836909530733566e-17, -0.09999999999999998, 3.673819061467131e-17, 0.5, 0, 0.35, 0, + -0.02499999999999997, 2.755364296100349e-17, 0.2, 0.3, 0.425, 0, 0.2, 0.15 }; + + int tab8[8]={ + 0, 1, 2, 3, 4, 5, 6, 7 }; + QuadraticPolygon *pol1=buildQuadraticPolygonCoarseInfo(coords,tab8,8); + QuadraticPolygon *pol2=buildQuadraticPolygonCoarseInfo(coords2,tab8,8); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.,pol1->intersectWith(*pol2),1.e-13); + delete pol1; + delete pol2; + pol1=buildQuadraticPolygonCoarseInfo(coords,tab8,8); + pol2=buildQuadraticPolygonCoarseInfo(coords2,tab8,8); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.,pol2->intersectWith(*pol1),1.e-13); + delete pol1; + delete pol2; + // + pol1=buildQuadraticPolygonCoarseInfo(coords,tab8,8); + pol2=buildQuadraticPolygonCoarseInfo(coords2,tab8,8); + std::vector<double> val1,val2; + pol1->intersectForPerimeterAdvanced(*pol2,val1,val2); + double test1_res[4]={0.,0.,0.,0.}; + double test2_res[4]={0.,0.,0.,0.}; + CPPUNIT_ASSERT(std::equal(val1.begin(),val1.end(),test1_res,DoubleEqual(1e-6))); + CPPUNIT_ASSERT(std::equal(val2.begin(),val2.end(),test2_res,DoubleEqual(1e-6))); + delete pol1; + delete pol2; + std::vector<int> val3; + pol1=buildQuadraticPolygonCoarseInfo(coords,tab8,8); + pol2=buildQuadraticPolygonCoarseInfo(coords2,tab8,8); + pol1->intersectForPoint(*pol2,val3); + int test3_res[4]={0,0,0,0}; + CPPUNIT_ASSERT(std::equal(val3.begin(),val3.end(),test3_res)); + delete pol1; + delete pol2; +} + +void QuadraticPlanarInterpTest::checkNonRegressionOmar0021() +{ + INTERP_KERNEL::QUADRATIC_PLANAR::setPrecision(1e-7); + INTERP_KERNEL::QUADRATIC_PLANAR::setArcDetectionPrecision(1e-7); + double coords[16]={ + -0.5, 6.123031769111886e-17, -0.8, 9.796850830579018e-17, 0.8, 0, 0.5, 0, + -0.65, 7.959941299845453e-17, 4.898425415289509e-17, 0.8, 0.65, 0, 3.061515884555943e-17, 0.5 }; + + double coords2[16]={ + -1, -0.07999999999999999, -1.15, -0.07999999999999996, -0.55, -0.08, -0.7, -0.08, + -1.075, -0.07999999999999997, -0.85, 0.22, -0.625, -0.08, -0.85, 0.06999999999999999 }; + + int tab8[8]={ + 0, 1, 2, 3, 4, 5, 6, 7 }; + QuadraticPolygon *pol1=buildQuadraticPolygonCoarseInfo(coords,tab8,8); + QuadraticPolygon *pol2=buildQuadraticPolygonCoarseInfo(coords2,tab8,8); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.0311485,pol1->intersectWith(*pol2),1.e-7); + delete pol1; + delete pol2; + pol1=buildQuadraticPolygonCoarseInfo(coords,tab8,8); + pol2=buildQuadraticPolygonCoarseInfo(coords2,tab8,8); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.0311485,pol2->intersectWith(*pol1),1.e-7); + delete pol1; + delete pol2; + // + pol1=buildQuadraticPolygonCoarseInfo(coords,tab8,8); + pol2=buildQuadraticPolygonCoarseInfo(coords2,tab8,8); + std::vector<double> val1,val2; + pol1->intersectForPerimeterAdvanced(*pol2,val1,val2); + double test1_res[4]={0.162251,0.151523,0.,0.}; + double test2_res[4]={0.,0.311383,0.,0.0978193}; + CPPUNIT_ASSERT(std::equal(val1.begin(),val1.end(),test1_res,DoubleEqual(1e-6))); + CPPUNIT_ASSERT(std::equal(val2.begin(),val2.end(),test2_res,DoubleEqual(1e-6))); + delete pol1; + delete pol2; + std::vector<int> val3; + pol1=buildQuadraticPolygonCoarseInfo(coords,tab8,8); + pol2=buildQuadraticPolygonCoarseInfo(coords2,tab8,8); + pol1->intersectForPoint(*pol2,val3); + int test3_res[4]={2,2,0,0}; + CPPUNIT_ASSERT(std::equal(val3.begin(),val3.end(),test3_res)); + delete pol1; + delete pol2; +} +void QuadraticPlanarInterpTest::checkNonRegressionOmar0022() +{ + INTERP_KERNEL::QUADRATIC_PLANAR::setPrecision(1e-7); + INTERP_KERNEL::QUADRATIC_PLANAR::setArcDetectionPrecision(1e-7); + double coords[16]={ + -0.5, 6.123031769111886e-17, -0.8, 9.796850830579018e-17, 0.8, 0, 0.5, 0, + -0.65, 7.959941299845453e-17, 4.898425415289509e-17, 0.8, 0.65, 0, 3.061515884555943e-17, 0.5 }; + + double coords2[16]={ + 0.15, -0.07999999999999999, 0, -0.07999999999999996, 0.6, -0.08, 0.45, -0.08, + 0.07500000000000001, -0.07999999999999997, 0.3, 0.22, 0.5249999999999999, -0.08, 0.3, 0.06999999999999999 }; + + int tab8[8]={ + 0, 1, 2, 3, 4, 5, 6, 7 }; + QuadraticPolygon *pol1=buildQuadraticPolygonCoarseInfo(coords,tab8,8); + QuadraticPolygon *pol2=buildQuadraticPolygonCoarseInfo(coords2,tab8,8); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.00902229,pol1->intersectWith(*pol2),1.e-8); + delete pol1; + delete pol2; + pol1=buildQuadraticPolygonCoarseInfo(coords,tab8,8); + pol2=buildQuadraticPolygonCoarseInfo(coords2,tab8,8); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.00902229,pol2->intersectWith(*pol1),1.e-8); + delete pol1; + delete pol2; +} + +void QuadraticPlanarInterpTest::checkNonRegressionOmar0023() +{ + INTERP_KERNEL::QUADRATIC_PLANAR::setPrecision(1e-7); + INTERP_KERNEL::QUADRATIC_PLANAR::setArcDetectionPrecision(1e-7); + double coords[16]={ + -0.5, 6.123031769111886e-17, -0.8, 9.796850830579018e-17, 0.8, 0, 0.5, 0, + -0.65, 7.959941299845453e-17, 4.898425415289509e-17, 0.8, 0.65, 0, 3.061515884555943e-17, 0.5, }; + + double coords2[16]={ + 0.4156854249492381, 0.5656854249492381, 0.2656854249492381, 0.5656854249492381, 0.8656854249492381, 0.5656854249492381, 0.7156854249492381, 0.5656854249492381, + 0.3406854249492381, 0.5656854249492381, 0.5656854249492381, 0.8656854249492381, 0.7906854249492381, 0.5656854249492381, 0.5656854249492381, 0.7156854249492381 }; + + int tab8[8]={ + 0, 1, 2, 3, 4, 5, 6, 7 }; + QuadraticPolygon *pol1=buildQuadraticPolygonCoarseInfo(coords,tab8,8); + QuadraticPolygon *pol2=buildQuadraticPolygonCoarseInfo(coords2,tab8,8); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.0215659,pol1->intersectWith(*pol2),1.e-7); + delete pol1; + delete pol2; + pol1=buildQuadraticPolygonCoarseInfo(coords,tab8,8); + pol2=buildQuadraticPolygonCoarseInfo(coords2,tab8,8); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.0215659,pol2->intersectWith(*pol1),1.e-7); + delete pol1; + delete pol2; +} + +void QuadraticPlanarInterpTest::checkNonRegressionOmar0024() +{ + INTERP_KERNEL::QUADRATIC_PLANAR::setPrecision(1e-7); + INTERP_KERNEL::QUADRATIC_PLANAR::setArcDetectionPrecision(1e-7); + double coords[16]={ + -0.5, 6.123031769111886e-17, -0.8, 9.796850830579018e-17, 0.8, 0, 0.5, 0, +-0.65, 7.959941299845453e-17, 4.898425415289509e-17, 0.8, 0.65, 0, 3.061515884555943e-17, 0.5 }; + double coords2[16]={ + 0.5656854249492381, 0.5656854249492381, 0.4156854249492382, 0.5656854249492381, 1.015685424949238, 0.5656854249492381, 0.8656854249492382, 0.5656854249492381, +0.4906854249492382, 0.5656854249492381, 0.7156854249492381, 0.8656854249492381, 0.9406854249492381, 0.5656854249492381, 0.7156854249492381, 0.7156854249492381 }; + + int tab8[8]={ + 0, 1, 2, 3, 4, 5, 6, 7 }; + QuadraticPolygon *pol1=buildQuadraticPolygonCoarseInfo(coords,tab8,8); + QuadraticPolygon *pol2=buildQuadraticPolygonCoarseInfo(coords2,tab8,8); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.00877657,pol1->intersectWith(*pol2),1.e-8); + delete pol1; + delete pol2; + pol1=buildQuadraticPolygonCoarseInfo(coords,tab8,8); + pol2=buildQuadraticPolygonCoarseInfo(coords2,tab8,8); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.00877657,pol2->intersectWith(*pol1),1.e-8); + delete pol1; + delete pol2; +} + +void QuadraticPlanarInterpTest::checkNonRegressionOmar2524() +{ + INTERP_KERNEL::QUADRATIC_PLANAR::setPrecision(1e-7); + INTERP_KERNEL::QUADRATIC_PLANAR::setArcDetectionPrecision(1e-7); + double coords[16]={ + -0.5, 6.123031769111886e-17, -0.8, 9.796850830579018e-17, 0.8, 0, 0.5, 0, +-0.65, 7.959941299845453e-17, 4.898425415289509e-17, 0.8, 0.65, 0, 3.061515884555943e-17, 0.5 }; + double coords2[16]={ + 0.4156854249492382, 0.5656854249492381, 1.015685424949238, 0.5656854249492381, 0.8656854249492382, 0.5656854249492381, 0.5656854249492381, 0.5656854249492381, +0.7156854249492381, 0.8656854249492381, 0.9406854249492381, 0.5656854249492381, 0.7156854249492381, 0.7156854249492381, 0.4906854249492382, 0.5656854249492381 }; + + int tab8[8]={ + 0, 1, 2, 3, 4, 5, 6, 7 }; + QuadraticPolygon *pol1=buildQuadraticPolygonCoarseInfo(coords,tab8,8); + QuadraticPolygon *pol2=buildQuadraticPolygonCoarseInfo(coords2,tab8,8); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.00877657,pol1->intersectWith(*pol2),1.e-8); + delete pol1; + delete pol2; + pol1=buildQuadraticPolygonCoarseInfo(coords,tab8,8); + pol2=buildQuadraticPolygonCoarseInfo(coords2,tab8,8); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.00877657,pol2->intersectWith(*pol1),1.e-8); + delete pol1; + delete pol2; +} + +void QuadraticPlanarInterpTest::checkNonRegressionOmar0025() +{ + INTERP_KERNEL::QUADRATIC_PLANAR::setPrecision(1e-7); + INTERP_KERNEL::QUADRATIC_PLANAR::setArcDetectionPrecision(1e-7); + double coords[16]={ + -0.5, 6.123031769111886e-17, -0.8, 9.796850830579018e-17, 0.8, 0, 0.5, 0, + -0.65, 7.959941299845453e-17, 4.898425415289509e-17, 0.8, 0.65, 0, 3.061515884555943e-17, 0.5 }; + + double coords2[16]={ + 0.715685424949238, 0.5656854249492381, 0.565685424949238, 0.5656854249492381, 1.165685424949238, 0.5656854249492381, 1.015685424949238, 0.5656854249492381, + 0.6406854249492381, 0.5656854249492381, 0.8656854249492381, 0.8656854249492381, 1.090685424949238, 0.5656854249492381, 0.8656854249492381, 0.7156854249492381 }; + + int tab8[8]={ + 0, 1, 2, 3, 4, 5, 6, 7 }; + QuadraticPolygon *pol1=buildQuadraticPolygonCoarseInfo(coords,tab8,8); + QuadraticPolygon *pol2=buildQuadraticPolygonCoarseInfo(coords2,tab8,8); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.,pol1->intersectWith(*pol2),1.e-13); + delete pol1; + delete pol2; + pol1=buildQuadraticPolygonCoarseInfo(coords,tab8,8); + pol2=buildQuadraticPolygonCoarseInfo(coords2,tab8,8); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.,pol2->intersectWith(*pol1),1.e-13); + delete pol1; + delete pol2; + // + std::vector<int> val3; + pol1=buildQuadraticPolygonCoarseInfo(coords,tab8,8); + pol2=buildQuadraticPolygonCoarseInfo(coords2,tab8,8); + pol1->intersectForPoint(*pol2,val3); + int test3_res[4]={0,1,0,0}; + CPPUNIT_ASSERT(std::equal(val3.begin(),val3.end(),test3_res)); + delete pol1; + delete pol2; +} + +void QuadraticPlanarInterpTest::checkNonRegressionOmar0026() +{ + INTERP_KERNEL::QUADRATIC_PLANAR::setPrecision(1e-7); + INTERP_KERNEL::QUADRATIC_PLANAR::setArcDetectionPrecision(1e-7); + double coords[16]={ + -0.4, 4.898425415289509e-17, -0.75, 9.184547653667829e-17, 0.75, 0, 0.4, 0, + -0.575, 7.041486534478669e-17, 4.592273826833915e-17, 0.75, 0.575, 0, 2.449212707644755e-17, 0.4 }; + + double coords2[16]={ + 0.1, 0.95, 0.2, 0.95, -0.2, 0.95, -0.1, 0.95, + 0.15, 0.95, 1.224606353822377e-17, 0.75, -0.15, 0.95, 6.123031769111886e-18, 0.85 }; + + int tab8[8]={ + 0, 1, 2, 3, 4, 5, 6, 7 }; + QuadraticPolygon *pol1=buildQuadraticPolygonCoarseInfo(coords,tab8,8); + QuadraticPolygon *pol2=buildQuadraticPolygonCoarseInfo(coords2,tab8,8); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.,pol1->intersectWith(*pol2),1.e-13); + delete pol1; + delete pol2; + pol1=buildQuadraticPolygonCoarseInfo(coords,tab8,8); + pol2=buildQuadraticPolygonCoarseInfo(coords2,tab8,8); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.,pol2->intersectWith(*pol1),1.e-13); + delete pol1; + delete pol2; + // + std::vector<int> val3; + pol1=buildQuadraticPolygonCoarseInfo(coords,tab8,8); + pol2=buildQuadraticPolygonCoarseInfo(coords2,tab8,8); + pol1->intersectForPoint(*pol2,val3); + int test3_res[4]={0,1,0,0}; + CPPUNIT_ASSERT(std::equal(val3.begin(),val3.end(),test3_res)); + delete pol1; + delete pol2; +} + +void QuadraticPlanarInterpTest::checkNonRegressionOmar0027() +{ + INTERP_KERNEL::QUADRATIC_PLANAR::setPrecision(1e-7); + INTERP_KERNEL::QUADRATIC_PLANAR::setArcDetectionPrecision(1e-7); + double coords[16]={ + -0.4, 4.898425415289509e-17, -0.75, 9.184547653667829e-17, 0.75, 0, 0.4, 0, + -0.575, 7.041486534478669e-17, 4.592273826833915e-17, 0.75, 0.575, 0, 2.449212707644755e-17, 0.4 }; + + double coords2[16]={ + -0.1, 0.7, -0.2, 0.7, 0.2, 0.7, 0.1, 0.7, + -0.15, 0.7, 1.224606353822377e-17, 0.8999999999999999, 0.15, 0.7, 6.123031769111886e-18, 0.7999999999999999 }; + + int tab8[8]={ + 0, 1, 2, 3, 4, 5, 6, 7 }; + QuadraticPolygon *pol1=buildQuadraticPolygonCoarseInfo(coords,tab8,8); + QuadraticPolygon *pol2=buildQuadraticPolygonCoarseInfo(coords2,tab8,8); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.00712309,pol1->intersectWith(*pol2),1.e-8); + delete pol1; + delete pol2; + pol1=buildQuadraticPolygonCoarseInfo(coords,tab8,8); + pol2=buildQuadraticPolygonCoarseInfo(coords2,tab8,8); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.00712309,pol2->intersectWith(*pol1),1.e-8); + delete pol1; + delete pol2; + // + pol1=buildQuadraticPolygonCoarseInfo(coords,tab8,8); + pol2=buildQuadraticPolygonCoarseInfo(coords2,tab8,8); + std::vector<double> val1,val2; + pol1->intersectForPerimeterAdvanced(*pol2,val1,val2); + double test1_res[4]={0.,0.222704,0.,0.}; + double test2_res[4]={0.1,0.0465335,0.1,0.092554}; + CPPUNIT_ASSERT(std::equal(val1.begin(),val1.end(),test1_res,DoubleEqual(1e-6))); + CPPUNIT_ASSERT(std::equal(val2.begin(),val2.end(),test2_res,DoubleEqual(1e-6))); + delete pol1; + delete pol2; + std::vector<int> val3; + pol1=buildQuadraticPolygonCoarseInfo(coords,tab8,8); + pol2=buildQuadraticPolygonCoarseInfo(coords2,tab8,8); + pol1->intersectForPoint(*pol2,val3); + int test3_res[4]={0,4,0,0}; + CPPUNIT_ASSERT(std::equal(val3.begin(),val3.end(),test3_res)); + delete pol1; + delete pol2; +} + +void QuadraticPlanarInterpTest::checkNonRegressionOmar0028() +{ + INTERP_KERNEL::QUADRATIC_PLANAR::setPrecision(1e-7); + INTERP_KERNEL::QUADRATIC_PLANAR::setArcDetectionPrecision(1e-7); + double coords[16]={ + -0.4, 4.898425415289509e-17, -0.75, 9.184547653667829e-17, 0.75, 0, 0.4, 0, + -0.575, 7.041486534478669e-17, 4.592273826833915e-17, 0.75, 0.575, 0, 2.449212707644755e-17, 0.4 }; + + double coords2[16]={ + -0.07071067811865477, 0.4792893218813453, -0.1414213562373095, 0.4085786437626905, 0.1414213562373095, 0.6914213562373095, 0.07071067811865477, 0.6207106781186548, + -0.1060660171779822, 0.4439339828220179, -0.1414213562373095, 0.6914213562373096, 0.1060660171779822, 0.6560660171779822, -0.07071067811865475, 0.6207106781186548 }; + + int tab8[8]={ + 0, 1, 2, 3, 4, 5, 6, 7 }; + QuadraticPolygon *pol1=buildQuadraticPolygonCoarseInfo(coords,tab8,8); + QuadraticPolygon *pol2=buildQuadraticPolygonCoarseInfo(coords2,tab8,8); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.0471239,pol1->intersectWith(*pol2),1.e-7); + delete pol1; + delete pol2; + pol1=buildQuadraticPolygonCoarseInfo(coords,tab8,8); + pol2=buildQuadraticPolygonCoarseInfo(coords2,tab8,8); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.0471239,pol2->intersectWith(*pol1),1.e-7); + delete pol1; + delete pol2; + // + pol1=buildQuadraticPolygonCoarseInfo(coords,tab8,8); + pol2=buildQuadraticPolygonCoarseInfo(coords2,tab8,8); + std::vector<double> val1,val2; + pol1->intersectForPerimeterAdvanced(*pol2,val1,val2); + double test1_res[4]={0.,0.,0.,0.}; + double test2_res[4]={0.1,0.628319,0.1,0.314159}; + CPPUNIT_ASSERT(std::equal(val1.begin(),val1.end(),test1_res,DoubleEqual(1e-6))); + CPPUNIT_ASSERT(std::equal(val2.begin(),val2.end(),test2_res,DoubleEqual(1e-6))); + delete pol1; + delete pol2; + std::vector<int> val3; + pol1=buildQuadraticPolygonCoarseInfo(coords,tab8,8); + pol2=buildQuadraticPolygonCoarseInfo(coords2,tab8,8); + pol1->intersectForPoint(*pol2,val3); + int test3_res[4]={0,1,0,0}; + CPPUNIT_ASSERT(std::equal(val3.begin(),val3.end(),test3_res)); + delete pol1; + delete pol2; +} + +void QuadraticPlanarInterpTest::checkNonRegressionOmar0029() +{ + INTERP_KERNEL::QUADRATIC_PLANAR::setPrecision(1e-7); + INTERP_KERNEL::QUADRATIC_PLANAR::setArcDetectionPrecision(1e-7); + double coords[16]={ + -0.4, 4.898425415289509e-17, -0.75, 9.184547653667829e-17, 0.75, 0, 0.4, 0, + -0.575, 7.041486534478669e-17, 4.592273826833915e-17, 0.75, 0.575, 0, 2.449212707644755e-17, 0.4 }; + + double coords2[16]={ + -0.07071067811865477, 0.1292893218813453, -0.1414213562373095, 0.05857864376269051, 0.1414213562373095, 0.3414213562373095, 0.07071067811865477, 0.2707106781186548, + -0.1060660171779822, 0.09393398282201787, -0.1414213562373095, 0.3414213562373095, 0.1060660171779822, 0.3060660171779822, -0.07071067811865475, 0.2707106781186548 }; + + int tab8[8]={ + 0, 1, 2, 3, 4, 5, 6, 7 }; + QuadraticPolygon *pol1=buildQuadraticPolygonCoarseInfo(coords,tab8,8); + QuadraticPolygon *pol2=buildQuadraticPolygonCoarseInfo(coords2,tab8,8); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.,pol1->intersectWith(*pol2),1.e-13); + delete pol1; + delete pol2; + pol1=buildQuadraticPolygonCoarseInfo(coords,tab8,8); + pol2=buildQuadraticPolygonCoarseInfo(coords2,tab8,8); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.,pol2->intersectWith(*pol1),1.e-13); + delete pol1; + delete pol2; + // + pol1=buildQuadraticPolygonCoarseInfo(coords,tab8,8); + pol2=buildQuadraticPolygonCoarseInfo(coords2,tab8,8); + std::vector<double> val1,val2; + pol1->intersectForPerimeterAdvanced(*pol2,val1,val2); + double test1_res[4]={0.,0.,0.,0.}; + double test2_res[4]={0.,0.,0.,0.}; + CPPUNIT_ASSERT(std::equal(val1.begin(),val1.end(),test1_res,DoubleEqual(1e-13))); + CPPUNIT_ASSERT(std::equal(val2.begin(),val2.end(),test2_res,DoubleEqual(1e-13))); + delete pol1; + delete pol2; + std::vector<int> val3; + pol1=buildQuadraticPolygonCoarseInfo(coords,tab8,8); + pol2=buildQuadraticPolygonCoarseInfo(coords2,tab8,8); + pol1->intersectForPoint(*pol2,val3); + int test3_res[4]={0,0,0,1}; + CPPUNIT_ASSERT(std::equal(val3.begin(),val3.end(),test3_res)); + delete pol1; + delete pol2; +} + +void QuadraticPlanarInterpTest::checkNonRegressionOmar0030() +{ + INTERP_KERNEL::QUADRATIC_PLANAR::setPrecision(1e-7); + INTERP_KERNEL::QUADRATIC_PLANAR::setArcDetectionPrecision(1e-7); + double coords[16]={ + -0.4, 4.898425415289509e-17, -0.75, 9.184547653667829e-17, 0.75, 0, 0.4, 0, + -0.575, 7.041486534478669e-17, 4.592273826833915e-17, 0.75, 0.575, 0, 2.449212707644755e-17, 0.4 }; + + double coords2[16]={ + -0.4889087296526012, 0.3889087296526012, -0.5889087296526012, 0.3889087296526012, -0.1889087296526012, 0.3889087296526012, -0.2889087296526012, 0.3889087296526012, + -0.5389087296526012, 0.3889087296526012, -0.3889087296526012, 0.5889087296526012, -0.2389087296526012, 0.3889087296526012, -0.3889087296526012, 0.4889087296526012 }; + + int tab8[8]={ + 0, 1, 2, 3, 4, 5, 6, 7 }; + QuadraticPolygon *pol1=buildQuadraticPolygonCoarseInfo(coords,tab8,8); + QuadraticPolygon *pol2=buildQuadraticPolygonCoarseInfo(coords2,tab8,8); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.0471239,pol1->intersectWith(*pol2),1.e-7); + delete pol1; + delete pol2; + pol1=buildQuadraticPolygonCoarseInfo(coords,tab8,8); + pol2=buildQuadraticPolygonCoarseInfo(coords2,tab8,8); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.0471239,pol2->intersectWith(*pol1),1.e-7); + delete pol1; + delete pol2; + // + pol1=buildQuadraticPolygonCoarseInfo(coords,tab8,8); + pol2=buildQuadraticPolygonCoarseInfo(coords2,tab8,8); + std::vector<double> val1,val2; + pol1->intersectForPerimeterAdvanced(*pol2,val1,val2); + double test1_res[4]={0.,0.,0.,0.}; + double test2_res[4]={0.1,0.628319,0.1,0.314159}; + CPPUNIT_ASSERT(std::equal(val1.begin(),val1.end(),test1_res,DoubleEqual(1e-6))); + CPPUNIT_ASSERT(std::equal(val2.begin(),val2.end(),test2_res,DoubleEqual(1e-6))); + delete pol1; + delete pol2; + std::vector<int> val3; + pol1=buildQuadraticPolygonCoarseInfo(coords,tab8,8); + pol2=buildQuadraticPolygonCoarseInfo(coords2,tab8,8); + pol1->intersectForPoint(*pol2,val3); + int test3_res[4]={0,1,0,0}; + CPPUNIT_ASSERT(std::equal(val3.begin(),val3.end(),test3_res)); + delete pol1; + delete pol2; +} + +void QuadraticPlanarInterpTest::checkIsInOrOut() +{ + double coords[8]={ 0.30662641093707971, -0.47819928619088981, + -0.47819928619088964, 0.30662641093707987, + 0.0, 0.0, + 0.4, 0.4 + }; + coords[4] = (coords[0] + coords[2]) / 2.0; + coords[5] = (coords[1] + coords[3]) / 2.0; + + int tab4[4]={ 0, 1, 2, 3}; + QuadraticPolygon *pol1=buildQuadraticPolygonCoarseInfo(coords,tab4,4); + Node * n = new Node(0.3175267678416348, -0.4890996430954449); + + CPPUNIT_ASSERT(! pol1->isInOrOut(n)); // node should be out + n->decrRef(); + delete pol1; +} + +void QuadraticPlanarInterpTest::checkGetMiddleOfPoints() +{ + { // from testIntersect2DMeshWith1DLine6() + double p1[] = {0.51641754716735844, 2.0}; + double p2[] = {0.0, 1.0}; + double e_center[] = {-0.71, 2.0}; + double mid[] = {0.0,0.0}; // out + double mide[] = {0.0,0.0}; // expected + + Node * start = new Node(0.,0.); Node * end = new Node(0.,0.); // unused + // start, end, center_x, center_y, radius, angle0, angle + EdgeArcCircle e(start, end, e_center, 1.2264175471673588, -0.9533904350433241, 0.95339043504332388); + + e.getMiddleOfPoints(p1, p2, mid); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.37969180470645592, mid[0], 1.e-7); + CPPUNIT_ASSERT_DOUBLES_EQUAL(1.4372640310451197, mid[1], 1.e-7); + + e.getMiddleOfPoints(p2, p1, mid); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.37969180470645592, mid[0], 1.e-7); + CPPUNIT_ASSERT_DOUBLES_EQUAL(1.4372640310451197, mid[1], 1.e-7); + + start->decrRef(); end->decrRef(); + } + { // from testSwig2Intersect2DMeshWith1DLine11() + double p1[] = {-1., 0.23453685964236054}; + double p2[] = {-0.23453685964235979, 1.0}; + double e_center[] = {-4.85, 4.85}; + double mid[] = {0.0,0.0}; // out + + Node * start = new Node(0.,0.); Node * end = new Node(0.,0.); // unused + // start, end, center_x, center_y, radius, angle0, angle + EdgeArcCircle e(start, end, e_center, 6.0104076400856474, -0.69522150912422953, -0.18035330854643861); + + e.getMiddleOfPoints(p1, p2, mid); + CPPUNIT_ASSERT_DOUBLES_EQUAL(-0.6, mid[0], 1.e-7); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.6, mid[1], 1.e-7); + + e.getMiddleOfPoints(p2, p1, mid); + CPPUNIT_ASSERT_DOUBLES_EQUAL(-0.6, mid[0], 1.e-7); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.6, mid[1], 1.e-7); + + start->decrRef(); end->decrRef(); + } + { // from testSwig2Intersect2DMeshWith1DLine11() + double p1[] = {-0.1303327636866019, -1.0}; + double p2[] = {-1.0, -0.1303327636866019}; + double e_center[] = {-1.9833333333333298, -1.9833333333333298}; + double mid[] = {0.0,0.0}; // out + + Node * start = new Node(0.,0.); Node * end = new Node(0.,0.); // unused + // start, end, center_x, center_y, radius, angle0, angle + EdgeArcCircle e(start, end, e_center, 2.0977501175200861, 1.0829141821052615, -0.59503203741562627); + + e.getMiddleOfPoints(p1, p2, mid); + CPPUNIT_ASSERT_DOUBLES_EQUAL(-0.5, mid[0], 1.e-7); + CPPUNIT_ASSERT_DOUBLES_EQUAL(-0.5, mid[1], 1.e-7); + + e.getMiddleOfPoints(p2, p1, mid); + CPPUNIT_ASSERT_DOUBLES_EQUAL(-0.5, mid[0], 1.e-7); + CPPUNIT_ASSERT_DOUBLES_EQUAL(-0.5, mid[1], 1.e-7); + + start->decrRef(); end->decrRef(); + } +} + +void QuadraticPlanarInterpTest::checkGetMiddleOfPointsOriented() +{ + { // from testSwig2Colinearize2D3() + double p1[] = {-0.70710678118654746, 0.70710678118654757}; + double p2[] = {-0.70710678118654768, -0.70710678118654746}; + double e_center[] = {0., 0.}; + double mid[] = {0.0,0.0}; // out + + Node * start = new Node(0.,0.); Node * end = new Node(0.,0.); // unused + // start, end, center_x, center_y, radius, angle0, angle + EdgeArcCircle e(start, end, e_center, 1.0, -0.7853981633974485, -1.5707963267948966); + + e.getMiddleOfPointsOriented(p1, p2, mid); + CPPUNIT_ASSERT_DOUBLES_EQUAL(1., mid[0], 1.e-7); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0., mid[1], 1.e-7); + + e.getMiddleOfPoints(p1, p2, mid); + CPPUNIT_ASSERT_DOUBLES_EQUAL(-1., mid[0], 1.e-7); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0., mid[1], 1.e-7); + + e.getMiddleOfPointsOriented(p2, p1, mid); + CPPUNIT_ASSERT_DOUBLES_EQUAL(-1., mid[0], 1.e-7); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0., mid[1], 1.e-7); + + start->decrRef(); end->decrRef(); + } +} + +} diff --git a/src/medtool/src/INTERP_KERNELTest/SingleElementPlanarTests.cxx b/src/medtool/src/INTERP_KERNELTest/SingleElementPlanarTests.cxx new file mode 100644 index 000000000..185b9accd --- /dev/null +++ b/src/medtool/src/INTERP_KERNELTest/SingleElementPlanarTests.cxx @@ -0,0 +1,1053 @@ +// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// + +#include "SingleElementPlanarTests.hxx" +#include "InterpolationUtils.hxx" +#include "PolygonAlgorithms.hxx" +#include "PolygonAlgorithms.txx" +#include "InterpolationPlanarTestSuite.hxx" +#include <deque> + +using namespace INTERP_KERNEL; + +namespace INTERP_TEST +{ + const double _Epsilon = 1.e-12; + const double _Precision = 1.e-12; + const double _losange1[8] = { 1,0, 0,1, -1,0, 0,-1 }; + const double _losange2[8] = { 2,0, 1,1, 0,0, 1,-1 }; + const double _losange3[8] = {2.5,0.5,1.5,1.5,0.5,0.5,1.5,-0.5 }; + const double _square1[8] = { -1,-1, -1,1, 1,1, 1,-1}; + const double _square2[8] = {1,-0.25,0,-0.25,0,0.25,1,0.25 }; + const double _losange4[8] = { 3,0, 2,1, 1,0, 2,-1 }; + const double _losange5[8] = { 1.5,0, 0,1.5,-1.5,0, 0,-1.5 }; + const double _losange6[12]= { 2,0, 1,1, 0.5,0.5,0,0, 0.5,-0.5, 1,-1 }; + const double _losange7[10]= { 1,0, 0,1, -1,0, 0,-1, 0.5,-0.5 }; + const double _square3[10] = { -1,-1, -1,1, 0.5,1, 1,1, 1,-1, }; + const double _square4[8] = {-0.5,-1,-0.5,1,1.5,1,1.5,-1 }; + const double _square5[10] = { -1,-1, -1,1, 0,1, 1,1, 1,-1 }; + const double _losange8[8] = { 0,1, 1,-1, 0,-1.5,-0.5,-1 }; + const double _losange9[8] = {0.5,0, 0,1, -1.5,0, 0,-1 }; + const double _hexagon1[12]= { -2,0, -1,-1, 1,-1, 2,0, 1,1, -1,1 }; + const double _hexagon2[12]= {-1.5,0.5,-1,-1, 1,-1, 2,1, 1,1, -1,1 }; + const double _hexagon3[12]= { -2,2, -1,1, 1,1, 2,2, 1,3, -1,3 }; + const double _square6[8] = { -1,1, -1,3, 0.5,3,0.5,1 }; + const double _losange10[8]= { 0,-1, 1,-2, 0,-3, -1,-2 }; + const double _triangle1[6]= {0.5,0, 1,1, 0,1 }; + const double _triangle2[6]= { 0,0.5, 0,-0.5,1.5,0 }; + const double _triangle3[9]= {-1,2,0, 1,2,0, 0,2,1 }; + const double _triangle4[9]= {1./2,2,0, 1, 2, 1, 1, 2, 0.5 }; + const double _parallel1[8] = {-1,0, -0.5,1, 0.5,1, 0,0}; + const double _parallel2[8]= {-0.5,1, 0,0, 1.,0, 0.5,1 }; + const double _parallel3[8]= {-0.5,-1, 0,0, 1,0, 0.5,-1}; + const double _triangle5[6]= { 0,0, 0,0.5, 0.5,0.5 }; + const double _triangle6[6]= { 1./3,1./3, 1./3,2./3, 2./3,2./3 }; + const double _triangle7[6]= {0.5,2, 1,1, 0,1 }; + const double _triangle8[6]= {22.4601,35.2129, 13.9921,34.693, 18.2853,26.2812 }; + const double _triangle9[6]= {13.9921,34.693, 22.4601,35.2129, 18.2785,42.3869 }; + const double _triangle10[6]= {84.8575,98.2042, 80,100, 82.2601,95.7202}; + const double _triangle11[6]= {80,100, 76.6659,91.9804, 85.3912,92.5061 }; + + // Two diamonds intersecting without degeneracy (two distinct crossing points) + // /\ /\ + // / \/ \ + // / /\ \ + // / / \ \ + // \ \ / / + // \ \/ / + // \ /\ / + // \/ \/ + + + // \brief Status : pass + void SingleElementPlanarTests::diamondsBasic() + { + INTERP_KERNEL::PolygonAlgorithms<2> intersector (_Epsilon, _Precision);; + std::deque< double > actual_result = intersector.intersectConvexPolygons(_losange1,_losange2,4,4); + std::deque< double > expected_result; + + expected_result.push_back(0.5);expected_result.push_back(-0.5); + expected_result.push_back(0);expected_result.push_back(0); + expected_result.push_back(0.5);expected_result.push_back(0.5); + expected_result.push_back(1);expected_result.push_back(0); + + CPPUNIT_ASSERT_MESSAGE("Basic diamond crossing test failed (CONVEX)", + (INTERP_KERNEL::checkEqualPolygons<std::deque<double>,2>(&actual_result, &expected_result, _Epsilon))); + } + + void SingleElementPlanarTests::diamondsBasic_Triangulation() + { + std::vector< double > actual_result; + INTERP_KERNEL::intersec_de_polygone<2>(_losange1,_losange2,4,4,actual_result,_Epsilon/_Precision, _Precision ); + + std::vector< double > expected_result; + expected_result.push_back(1);expected_result.push_back(0); + expected_result.push_back(0.5);expected_result.push_back(0.5); + expected_result.push_back(0);expected_result.push_back(0); + expected_result.push_back(0.5);expected_result.push_back(-0.5); + + CPPUNIT_ASSERT_MESSAGE("Basic diamond crossing test failed (TRIANGULATION)", + (INTERP_KERNEL::checkEqualPolygons<std::vector<double>,2>(&actual_result, &expected_result, _Epsilon))); + } + + + // Two diamonds with overlapping edges in an exclusion configuration + // /\ + // / \ + // /\ / \ + // / \/ \ + // / \ / + // / \ / + // \ /\ / + // \ / \/ + // \ / + // \/ + // \brief Status : pass + void SingleElementPlanarTests::tangentDiamonds() + { + INTERP_KERNEL::PolygonAlgorithms<2> intersector (_Epsilon, _Precision);; + std::deque< double > actual_result = intersector.intersectConvexPolygons(_losange1,_losange3,4,4); + std::deque< double > expected_result; + + CPPUNIT_ASSERT_MESSAGE("Diamond exclusion tangency test failed (CONVEX)", + (INTERP_KERNEL::checkEqualPolygons<std::deque<double>,2>(&actual_result, &expected_result, _Epsilon))); + } + void SingleElementPlanarTests::tangentDiamonds_Triangulation() + { + std::vector< double > actual_result; + INTERP_KERNEL::intersec_de_polygone<2>(_losange1,_losange3,4,4,actual_result,_Epsilon/_Precision, _Precision ); + + std::vector< double > expected_result; + expected_result.push_back(0.5);expected_result.push_back(0.5); + expected_result.push_back(1);expected_result.push_back(0); + + CPPUNIT_ASSERT_MESSAGE("Diamond exclusion tangency test failed (TRIANGULATION)", + (INTERP_KERNEL::checkEqualPolygons<std::vector<double>,2>(&actual_result, &expected_result, _Epsilon))); + } + + // Two tangent squares with overlapping edges, in an inclusion configuration + // _____________ + // | | + // | _______| + // | | | + // | |_______| + // | | + // |_____________| + + // \brief Status : pass + void SingleElementPlanarTests::tangentSquares() + { + INTERP_KERNEL::PolygonAlgorithms<2> intersector (_Epsilon, _Precision);; + std::deque< double > actual_result = intersector.intersectConvexPolygons(_square1,_square2,4,4); + std::deque< double > expected_result; + + expected_result.push_back(0.);expected_result.push_back(0.25); + expected_result.push_back(0.);expected_result.push_back(-0.25); + expected_result.push_back(1.);expected_result.push_back(-0.25); + expected_result.push_back(1.);expected_result.push_back(0.25); + + CPPUNIT_ASSERT_MESSAGE("Squares inclusion tangency test failed (CONVEX)", + (INTERP_KERNEL::checkEqualPolygons<std::deque<double>,2>(&actual_result, &expected_result, _Epsilon))); + } + void SingleElementPlanarTests::tangentSquares_Triangulation() + { + std::vector< double > actual_result; + INTERP_KERNEL::intersec_de_polygone<2>(_square1,_square2,4,4,actual_result,_Epsilon/_Precision, _Precision ); + + std::vector< double > expected_result; + + expected_result.push_back(1.);expected_result.push_back(0.25); + expected_result.push_back(0.25);expected_result.push_back(0.25); + expected_result.push_back(1./6);expected_result.push_back(1./6); + expected_result.push_back(0.);expected_result.push_back(0.25); + expected_result.push_back(0.);expected_result.push_back(0.); + expected_result.push_back(0.);expected_result.push_back(-0.25); + expected_result.push_back(1.);expected_result.push_back(-0.25); + + CPPUNIT_ASSERT_MESSAGE("Squares inclusion tangency test failed (TRIANGULATION)", + (INTERP_KERNEL::checkEqualPolygons<std::vector<double>,2>(&actual_result, &expected_result, _Epsilon))); + } + + // Two diamonds sharing a vertex in an exclusion configuration + // /\ /\ + // / \ / \ + // / \ / \ + // / \/ \ + // \ /\ / + // \ / \ / + // \ / \ / + // \/ \/ + + + // \brief Status : pass + void SingleElementPlanarTests::diamondsSharingVertex1() + { + INTERP_KERNEL::PolygonAlgorithms<2> intersector (_Epsilon, _Precision);; + std::deque< double > actual_result = intersector.intersectConvexPolygons(_losange1,_losange4,4,4); + std::deque< double > expected_result; + + CPPUNIT_ASSERT_MESSAGE("Diamond sharing (1) vertex test failed (CONVEX)", + (INTERP_KERNEL::checkEqualPolygons<std::deque<double>,2>(&actual_result, &expected_result, _Epsilon))); + } + void SingleElementPlanarTests::diamondsSharingVertex1_Triangulation() + { + std::vector< double > actual_result; + INTERP_KERNEL::intersec_de_polygone<2>(_losange1,_losange4,4,4,actual_result,_Epsilon/_Precision, _Precision ); + + std::vector< double > expected_result; + expected_result.push_back(1.);expected_result.push_back(0.); + + CPPUNIT_ASSERT_MESSAGE("Diamonds sharing (1) vertex test failed (TRIANGULATION)", + (INTERP_KERNEL::checkEqualPolygons<std::vector<double>,2>(&actual_result, &expected_result, _Epsilon))); + } + + // Two identical squares + // _____________ + // | | + // | | + // | | + // | | + // | | + // |_____________| + + // \brief Status : pass + void SingleElementPlanarTests::identicalSquares() + { + INTERP_KERNEL::PolygonAlgorithms<2> intersector (_Epsilon, _Precision);; + /* + ////////////////// TEST DESACTIVATED by A. GEAY because memory fault : + // conditional jump INTERP_KERNEL::PolygonAlgorithms<2>::intersectConvexPolygons(double const*, double const*, int, int) (PolygonAlgorithms.txx:629) + std::deque< double > actual_result = intersector.intersectConvexPolygons(_square1,_square1,4,4); + std::deque< double > expected_result; + + expected_result.push_back(-1.);expected_result.push_back(1.); + expected_result.push_back(-1.);expected_result.push_back(-1.); + expected_result.push_back(1.);expected_result.push_back(-1.); + expected_result.push_back(1.);expected_result.push_back(1.); + + CPPUNIT_ASSERT_MESSAGE("Identical squares test failed (CONVEX)", + (INTERP_KERNEL::checkEqualPolygons<std::deque<double>,2>(&actual_result, &expected_result, _Epsilon))); + */ + } + void SingleElementPlanarTests::identicalSquares_Triangulation() + { + std::vector< double > actual_result; + INTERP_KERNEL::intersec_de_polygone<2>(_square1,_square1,4,4,actual_result,_Epsilon/_Precision, _Precision ); + + std::vector< double > expected_result; + + expected_result.push_back(1.);expected_result.push_back(1.); + expected_result.push_back(-1.);expected_result.push_back(1.); + expected_result.push_back(-1.);expected_result.push_back(-1.); + expected_result.push_back(1.);expected_result.push_back(-1.); + + CPPUNIT_ASSERT_MESSAGE("Identical squares test failed (TRIANGULATION)", + (INTERP_KERNEL::checkEqualPolygons<std::vector<double>,2>(&actual_result, &expected_result, _Epsilon))); + } + // Square and diamond intersecting with no degeneracy + // /\ + // / \ + // / \ + // __/______\__ + // | / \ | + // |/ \| + // / \ + // /| |\ + // \| |/ + // \ / + // |\ /| + // |_\________/_| + // \ / + // \ / + // \ / + // \/ + // \brief Status : pass + void SingleElementPlanarTests::squareAndDiamondBasic() + { + INTERP_KERNEL::PolygonAlgorithms<2> intersector (_Epsilon, _Precision);; + std::deque< double > actual_result = intersector.intersectConvexPolygons(_square1,_losange5,4,4); + std::deque< double > expected_result; + + expected_result.push_back(1.);expected_result.push_back(0.5); + expected_result.push_back(0.5);expected_result.push_back(1.); + expected_result.push_back(-0.5);expected_result.push_back(1.); + expected_result.push_back(-1.);expected_result.push_back(0.5); + expected_result.push_back(-1.);expected_result.push_back(-0.5); + expected_result.push_back(-0.5);expected_result.push_back(-1.); + expected_result.push_back(0.5);expected_result.push_back(-1.); + expected_result.push_back(1.);expected_result.push_back(-0.5); + + CPPUNIT_ASSERT_MESSAGE("Square and diamond basic test failed (CONVEX)", + (INTERP_KERNEL::checkEqualPolygons<std::deque<double>,2>(&actual_result, &expected_result, _Epsilon))); + } + void SingleElementPlanarTests::squareAndDiamondBasic_Triangulation() + { + std::vector< double > actual_result; + INTERP_KERNEL::intersec_de_polygone<2>(_square1,_losange5,4,4,actual_result,_Epsilon/_Precision, _Precision ); + + std::vector< double > expected_result; + + expected_result.push_back(1.);expected_result.push_back(0.); + expected_result.push_back(1.);expected_result.push_back(0.5); + expected_result.push_back(0.75);expected_result.push_back(0.75); + expected_result.push_back(0.5);expected_result.push_back(1.); + expected_result.push_back(0.);expected_result.push_back(0.); + expected_result.push_back(-0.5);expected_result.push_back(1.); + expected_result.push_back(-1.);expected_result.push_back(0.5); + expected_result.push_back(-1.);expected_result.push_back(0.); + expected_result.push_back(-1.);expected_result.push_back(-0.5); + expected_result.push_back(-0.75);expected_result.push_back(-0.75); + expected_result.push_back(-0.5);expected_result.push_back(-1.); + expected_result.push_back(0.5);expected_result.push_back(-1.); + expected_result.push_back(1.);expected_result.push_back(-0.5); + + + // EAP: different place of (0,0) point on 32 and 64-bits platforms + // we comment it for the sake of "make check" to pass + //CPPUNIT_ASSERT_MESSAGE("Square and diamond basic test failed (TRIANGULATION), maybe not significant (0,0) should be removed", + //(INTERP_KERNEL::checkEqualPolygons<vector<double>,2>(&actual_result, &expected_result, _Epsilon))); + } + // square and diamond intersecting at four degenerated pointss + // ______ + // | /\ | + // | / \ | + // |/ \| + // |\ /| + // | \ / | + // |__\/__| + // \brief Status : pass + + void SingleElementPlanarTests::squareAndDiamondCritical() + { + INTERP_KERNEL::PolygonAlgorithms<2> intersector (_Epsilon, _Precision);; + std::deque< double > actual_result = intersector.intersectConvexPolygons(_square1,_losange1,4,4); + std::deque< double > expected_result; + + expected_result.push_back(0.);expected_result.push_back(-1.); + expected_result.push_back(-1.);expected_result.push_back(0.); + expected_result.push_back(0.);expected_result.push_back(1.); + expected_result.push_back(1.);expected_result.push_back(0.); + + CPPUNIT_ASSERT_MESSAGE("Square and diamond critical tangency test failed (CONVEX)", + (INTERP_KERNEL::checkEqualPolygons<std::deque<double>,2>(&actual_result, &expected_result, _Epsilon))); + } + void SingleElementPlanarTests::squareAndDiamondCritical_Triangulation() + { + std::vector< double > actual_result; + INTERP_KERNEL::intersec_de_polygone<2>(_square1,_losange1,4,4,actual_result,_Epsilon/_Precision, _Precision ); + + std::vector< double > expected_result; + + expected_result.push_back(0.5);expected_result.push_back(0.5); + expected_result.push_back(0.);expected_result.push_back(1.); + expected_result.push_back(0);expected_result.push_back(0); + expected_result.push_back(-1.);expected_result.push_back(0.); + expected_result.push_back(-0.5);expected_result.push_back(-0.5); + expected_result.push_back(0.);expected_result.push_back(-1.); + expected_result.push_back(1.);expected_result.push_back(0.); + + // 0020208: Unit Test of MED failed +// CPPUNIT_ASSERT_MESSAGE("Square and diamond basic test failed (TRIANGULATION) maybe not significant (0,0) should be removed", +// (INTERP_KERNEL::checkEqualPolygons<vector<double>,2>(&actual_result, &expected_result, _Epsilon))); + } + // Two diamonds intersecting at one vertex on edge and one double vertex + // /\ /\ + // / \ / \ + // / ¤ \ + // / / \ \ + // \ \ / / + // \ * / + // \ / \ / + // \/ \/ + + + // \brief Status : pass + void SingleElementPlanarTests::diamondsCritical() + { + + INTERP_KERNEL::PolygonAlgorithms<2> intersector (_Epsilon, _Precision);; + std::deque< double > actual_result = intersector.intersectConvexPolygons(_losange6,_losange7,6,5); + std::deque< double > expected_result; + + expected_result.push_back(0.5);expected_result.push_back(-0.5); + expected_result.push_back(0.5);expected_result.push_back(-0.5); + expected_result.push_back(0);expected_result.push_back(0); + expected_result.push_back(0.5);expected_result.push_back(0.5); + expected_result.push_back(0.5);expected_result.push_back(0.5); + expected_result.push_back(1);expected_result.push_back(0); + + CPPUNIT_ASSERT_MESSAGE("Basic diamond crossing test failed (CONVEX)", + (INTERP_KERNEL::checkEqualPolygons<std::deque<double>,2>(&actual_result, &expected_result, _Epsilon))); + } + void SingleElementPlanarTests::diamondsCritical_Triangulation() + { + std::vector< double > actual_result; + INTERP_KERNEL::intersec_de_polygone<2>(_losange6,_losange7,6,5,actual_result,_Epsilon/_Precision, _Precision ); + + std::vector< double > expected_result; + + expected_result.push_back(1);expected_result.push_back(0); + expected_result.push_back(0.5);expected_result.push_back(0.5); + expected_result.push_back(0);expected_result.push_back(0); + expected_result.push_back(0.5);expected_result.push_back(-0.5); + + CPPUNIT_ASSERT_MESSAGE("Basic diamond crossing test failed (TRIANGULATION)", + (INTERP_KERNEL::checkEqualPolygons<std::vector<double>,2>(&actual_result, &expected_result, _Epsilon))); + } + + // Two tangent squares with starting and ending vertices on edges + // _____ ___.___ ______ + // | | | | + // | | | | + // | | | | + // | | | | + // | | | | + // |_____|_______|______| + + // \brief Status : pass + void SingleElementPlanarTests::quadranglesCritical() + { + INTERP_KERNEL::PolygonAlgorithms<2> intersector (_Epsilon, _Precision);; + std::deque< double > actual_result = intersector.intersectConvexPolygons(_square4,_square3,4,5); + std::deque< double > expected_result; + + expected_result.push_back(-0.5);expected_result.push_back(1.); + expected_result.push_back(-0.5);expected_result.push_back(-1.); + expected_result.push_back(1.);expected_result.push_back(-1.); + expected_result.push_back(1.);expected_result.push_back(1.); + + CPPUNIT_ASSERT_MESSAGE("Critical quadrangles with tangency test failed (CONVEX)", + (INTERP_KERNEL::checkEqualPolygons<std::deque<double>,2>(&actual_result, &expected_result, _Epsilon))); + } + void SingleElementPlanarTests::quadranglesCritical_Triangulation() + { + std::vector< double > actual_result; + INTERP_KERNEL::intersec_de_polygone<2>(_square4,_square3,4,5,actual_result,_Epsilon/_Precision, _Precision ); + + std::vector< double > expected_result; + + expected_result.push_back(1.);expected_result.push_back(-1.); + expected_result.push_back(1.);expected_result.push_back(0.5); + expected_result.push_back(1.);expected_result.push_back(1.); + expected_result.push_back(0.5);expected_result.push_back(1.); + expected_result.push_back(-0.5);expected_result.push_back(1.); + expected_result.push_back(-0.5);expected_result.push_back(-1./3); + expected_result.push_back(-0.5);expected_result.push_back(-0.5); + expected_result.push_back(-0.5);expected_result.push_back(-1.); + + CPPUNIT_ASSERT_MESSAGE("Critical quadrangles with tangency test failed (TRIANGULATION)", + (INTERP_KERNEL::checkEqualPolygons<std::vector<double>,2>(&actual_result, &expected_result, _Epsilon))); + } + + + // square and diamond crossing and tangency at double vertices, starting vertex on edge + // _____.____ + // | / \ | + // | / \ | + // | / \ | + // |_/_______\| + // \ / + // \ / + // \ / + // \ / + // \brief Status : pass + void SingleElementPlanarTests::quadrangleAndDiamondCritical() + { + INTERP_KERNEL::PolygonAlgorithms<2> intersector (_Epsilon, _Precision);; + std::deque< double > actual_result = intersector.intersectConvexPolygons(_square5,_losange8,5,4); + std::deque< double > expected_result; + + expected_result.push_back(0.);expected_result.push_back(1.); + expected_result.push_back(-0.5);expected_result.push_back(-1.); + expected_result.push_back(1.);expected_result.push_back(-1.); + expected_result.push_back(1.);expected_result.push_back(-1.); + + CPPUNIT_ASSERT_MESSAGE("Square and diamond critical tangency test failed (CONVEX)", + (INTERP_KERNEL::checkEqualPolygons<std::deque<double>,2>(&actual_result, &expected_result, _Epsilon))); + } + void SingleElementPlanarTests::quadrangleAndDiamondCritical_Triangulation() + { + std::vector< double > actual_result; + INTERP_KERNEL::intersec_de_polygone<2>(_square5,_losange8,5,4,actual_result,_Epsilon/_Precision, _Precision ); + + std::vector< double > expected_result; + + expected_result.push_back(1.);expected_result.push_back(-1.); + expected_result.push_back(1./3);expected_result.push_back(1./3); + expected_result.push_back(0.);expected_result.push_back(1.); + expected_result.push_back(0.);expected_result.push_back(0.); + expected_result.push_back(-1./3);expected_result.push_back(-1./3); + expected_result.push_back(-0.5);expected_result.push_back(-1.); + expected_result.push_back(0.);expected_result.push_back(-1.); + + CPPUNIT_ASSERT_MESSAGE("Square and diamond critical tangency test failed (TRIANGULATION)", + (INTERP_KERNEL::checkEqualPolygons<std::vector<double>,2>(&actual_result, &expected_result, _Epsilon))); + } // square and diamond intersecting at four degenerated pointss + // + // ²/²\ + // ² / ² \ + // ² / ² \ + // ² \ ² / + // ² \ ² / + // ²\²/ + // \brief Status : pass + + void SingleElementPlanarTests::diamondsCritical2() + { + INTERP_KERNEL::PolygonAlgorithms<2> intersector (_Epsilon, _Precision);; + std::deque< double > actual_result = intersector.intersectConvexPolygons(_losange1,_losange9,4,4); + std::deque< double > expected_result; + + expected_result.push_back(0.);expected_result.push_back(-1.); + expected_result.push_back(0.);expected_result.push_back(-1.); + expected_result.push_back(-1.);expected_result.push_back(0.); + expected_result.push_back(0.);expected_result.push_back(1.); + expected_result.push_back(0.);expected_result.push_back(1.); + expected_result.push_back(0.5);expected_result.push_back(0.); + + CPPUNIT_ASSERT_MESSAGE("Diamonds with crossing at double vertex test failed (CONVEX)", + (INTERP_KERNEL::checkEqualPolygons<std::deque<double>,2>(&actual_result, &expected_result, _Epsilon))); + } + void SingleElementPlanarTests::diamondsCritical2_Triangulation() + { + std::vector< double > actual_result; + INTERP_KERNEL::intersec_de_polygone<2>(_losange1,_losange9,4,4,actual_result,_Epsilon/_Precision, _Precision ); + + std::vector< double > expected_result; + + expected_result.push_back(0.);expected_result.push_back(-1.); + expected_result.push_back(0.5);expected_result.push_back(0.); + expected_result.push_back(0.);expected_result.push_back(1.); + expected_result.push_back(-1.);expected_result.push_back(0.); + + CPPUNIT_ASSERT_MESSAGE("Diamonds with crossing at double vertex test failed (TRIANGULATION)", + (INTERP_KERNEL::checkEqualPolygons<std::vector<double>,2>(&actual_result, &expected_result, _Epsilon))); + } + + // Two tangent hexagons with double vertices and a critical starting vertex on edge + // _________ + // / \²²² + // ² \² + // / \ + // / ² ² \ + // \ / + // \ ² ² / + // \ / + // \²_______²/ + + + // \brief Status : pass + void SingleElementPlanarTests::hexagonsCritical1() + { + + INTERP_KERNEL::PolygonAlgorithms<2> intersector (_Epsilon, _Precision);; + std::deque< double > actual_result = intersector.intersectConvexPolygons(_hexagon1,_hexagon2,6,6); + std::deque< double > expected_result; + + expected_result.push_back(5./3);expected_result.push_back(1./3); + expected_result.push_back(1.);expected_result.push_back(-1.); + expected_result.push_back(-1.);expected_result.push_back(-1.); + expected_result.push_back(-1.5);expected_result.push_back(0.5); + expected_result.push_back(-1.);expected_result.push_back(1.); + expected_result.push_back(1.);expected_result.push_back(1.); + + CPPUNIT_ASSERT_MESSAGE("First hexagon critical crossing test failed (CONVEX)", + (INTERP_KERNEL::checkEqualPolygons<std::deque<double>,2>(&actual_result, &expected_result, _Epsilon))); + } + void SingleElementPlanarTests::hexagonsCritical1_Triangulation() + { + std::vector< double > actual_result; + INTERP_KERNEL::intersec_de_polygone<2>(_hexagon1,_hexagon2,6,6,actual_result,_Epsilon/_Precision, _Precision ); + + std::vector< double > expected_result; + + expected_result.push_back(-1.);expected_result.push_back(1.); + expected_result.push_back(-1.5);expected_result.push_back(0.5); + expected_result.push_back(-8./7);expected_result.push_back(2./7); + expected_result.push_back(-1.4);expected_result.push_back(0.2); + expected_result.push_back(-4./3);expected_result.push_back(0.); + expected_result.push_back(-2./3);expected_result.push_back(0.); + expected_result.push_back(-1.25);expected_result.push_back(-0.25); + expected_result.push_back(-1.);expected_result.push_back(-1.); + expected_result.push_back(1.);expected_result.push_back(-1.); + expected_result.push_back(1.5);expected_result.push_back(0.); + expected_result.push_back(5./3);expected_result.push_back(1./3); + expected_result.push_back(1.125);expected_result.push_back(0.875); + expected_result.push_back(1.);expected_result.push_back(1.); + expected_result.push_back(0.25);expected_result.push_back(0.75); + + CPPUNIT_ASSERT_MESSAGE("First hexagon critical crossing test failed (TRIANGULATION)", + (INTERP_KERNEL::checkEqualPolygons<std::vector<double>,2>(&actual_result, &expected_result, _Epsilon))); + } + + // Two tangent hexagons with double vertices and a critical starting vertex on edge + // _______ + // / \ + // / \ + // \ / + // \_______/ + // / \ + // / \ + // \ / + // \_______/ + + + // \brief Status : pass + void SingleElementPlanarTests::hexagonsCritical2() + { + INTERP_KERNEL::PolygonAlgorithms<2> intersector (_Epsilon, _Precision);; + std::deque< double > actual_result = intersector.intersectConvexPolygons(_hexagon1,_hexagon3,6,6); + std::deque< double > expected_result; + + CPPUNIT_ASSERT_MESSAGE("Second hexagon critical crossing test failed (CONVEX)", + (INTERP_KERNEL::checkEqualPolygons<std::deque<double>,2>(&actual_result, &expected_result, _Epsilon))); + } + void SingleElementPlanarTests::hexagonsCritical2_Triangulation() + { + std::vector< double > actual_result; + INTERP_KERNEL::intersec_de_polygone<2>(_hexagon1,_hexagon3,6,6,actual_result,_Epsilon/_Precision, _Precision ); + + std::vector< double > expected_result; + expected_result.push_back(1.);expected_result.push_back(1.); + expected_result.push_back(-1.);expected_result.push_back(1.); + + CPPUNIT_ASSERT_MESSAGE("Second hexagon critical crossing test failed (TRIANGULATION)", + (INTERP_KERNEL::checkEqualPolygons<std::vector<double>,2>(&actual_result, &expected_result, _Epsilon))); + } + + // Square and quadrilateron with outer tangency + // ________ + // | | + // | | + // | | + // |________|___ + // | | + // | | + // | | + // | | + // | | + // |____________| + + // \brief Status : pass + void SingleElementPlanarTests::squareAndQuadrangleCritical() + { + INTERP_KERNEL::PolygonAlgorithms<2> intersector (_Epsilon, _Precision);; + std::deque< double > actual_result = intersector.intersectConvexPolygons(_square1,_square6,4,4); + std::deque< double > expected_result; + + CPPUNIT_ASSERT_MESSAGE("Identical squares test failed (CONVEX)", (INTERP_KERNEL::checkEqualPolygons<std::deque<double>,2>(&actual_result, &expected_result, _Epsilon))); + } + void SingleElementPlanarTests::squareAndQuadrangleCritical_Triangulation() + { + std::vector< double > actual_result; + INTERP_KERNEL::intersec_de_polygone<2>(_square1,_square6,4,4,actual_result,_Epsilon/_Precision, _Precision ); + + std::vector< double > expected_result; + expected_result.push_back(-1.);expected_result.push_back(1.); + expected_result.push_back(0.5);expected_result.push_back(1.); + + CPPUNIT_ASSERT_MESSAGE("Identical squares test failed (TRIANGULATION)", + (INTERP_KERNEL::checkEqualPolygons<std::vector<double>,2>(&actual_result, &expected_result, _Epsilon))); + } + // Two diamonds sharing a vertex in an exclusion configuration + // /\ + // / \ + // / \ + // / \ + // \ / + // \ / + // \ / + // \/ + // /\ + // / \ + // / \ + // / \ + // \ / + // \ / + // \ / + // \/ + + + // \brief Status : pass + void SingleElementPlanarTests:: diamondsSharingVertex2() + { + INTERP_KERNEL::PolygonAlgorithms<2> intersector (_Epsilon, _Precision);; + std::deque< double > actual_result = intersector.intersectConvexPolygons(_losange1,_losange10,4,4); + std::deque< double > expected_result; + + CPPUNIT_ASSERT_MESSAGE("Diamond sharing vertex (2) test failed (CONVEX)", + (INTERP_KERNEL::checkEqualPolygons<std::deque<double>,2>(&actual_result, &expected_result, _Epsilon))); + } + void SingleElementPlanarTests:: diamondsSharingVertex2_Triangulation() + { + std::vector< double > actual_result; + INTERP_KERNEL::intersec_de_polygone<2>(_losange1,_losange10,4,4,actual_result,_Epsilon/_Precision, _Precision ); + + std::vector< double > expected_result; + expected_result.push_back(0.);expected_result.push_back(-1.); + + CPPUNIT_ASSERT_MESSAGE("Diamond sharing vertex (2) test failed (TRIANGULATION)", + (INTERP_KERNEL::checkEqualPolygons<std::vector<double>,2>(&actual_result, &expected_result, _Epsilon))); + } + + // Triangle and diamond with a critical crossing at double starting vertex + // ____ + // /|\ / + // / | \/ + // / | /\ + // / |/ \ + // \ / + // \ / + // \ / + // \ / + + // \brief Status : pass + void SingleElementPlanarTests:: triangleAndDiamondCritical() + { + INTERP_KERNEL::PolygonAlgorithms<2> intersector (_Epsilon, _Precision);; + std::deque< double > actual_result = intersector.intersectConvexPolygons(_losange1,_triangle1,4,3); + std::deque< double > expected_result; + + expected_result.push_back(2./3);expected_result.push_back(1./3); + expected_result.push_back(0.5);expected_result.push_back(0.); + expected_result.push_back(0.);expected_result.push_back(1.); + + CPPUNIT_ASSERT_MESSAGE("Triangle and diamonds critical test failed (CONVEX)", + (INTERP_KERNEL::checkEqualPolygons<std::deque<double>,2>(&actual_result, &expected_result, _Epsilon))); + } + void SingleElementPlanarTests:: triangleAndDiamondCritical_Triangulation() + { + std::vector< double > actual_result; + INTERP_KERNEL::intersec_de_polygone<2>(_losange1,_triangle1,4,3,actual_result,_Epsilon/_Precision, _Precision ); + + std::vector< double > expected_result; + + expected_result.push_back(2./3);expected_result.push_back(1./3); + expected_result.push_back(0.);expected_result.push_back(1.); + expected_result.push_back(0.5);expected_result.push_back(0.); + + CPPUNIT_ASSERT_MESSAGE("Triangle and diamonds critical test failed (TRIANGULATION)", + (INTERP_KERNEL::checkEqualPolygons<std::vector<double>,2>(&actual_result, &expected_result, _Epsilon))); + } + + // Basic triangle and square intersection (two distinct points) + // __________ + // | | + // | |\ | + // | | \| + // | | \ + // | | |\ + // | | |/ + // | | / + // | | /| + // | |/ | + // |__________| + + // \brief Status : pass + void SingleElementPlanarTests::triangleAndSquareBasic() + { + INTERP_KERNEL::PolygonAlgorithms<2> intersector (_Epsilon, _Precision);; + std::deque< double > actual_result = intersector.intersectConvexPolygons(_square1,_triangle2,4,3); + std::deque< double > expected_result; + + expected_result.push_back(1.);expected_result.push_back(1./6); + expected_result.push_back(1.);expected_result.push_back(-1./6); + expected_result.push_back(0.);expected_result.push_back(-0.5); + expected_result.push_back(0.);expected_result.push_back(0.5); + + CPPUNIT_ASSERT_MESSAGE("Identical squares test failed (CONVEX)", + (INTERP_KERNEL::checkEqualPolygons<std::deque<double>,2>(&actual_result, &expected_result, _Epsilon))); + } + + void SingleElementPlanarTests::triangleAndSquareBasic_Triangulation() + { + std::vector< double > actual_result; + INTERP_KERNEL::intersec_de_polygone<2>(_square1,_triangle2,4,3,actual_result,_Epsilon/_Precision, _Precision ); + + std::vector< double > expected_result; + + expected_result.push_back(1.);expected_result.push_back(1./6); + expected_result.push_back(0.375);expected_result.push_back(0.375); + expected_result.push_back(0.);expected_result.push_back(0.5); + expected_result.push_back(0.);expected_result.push_back(0.); + expected_result.push_back(0.);expected_result.push_back(-0.5); + expected_result.push_back(1.);expected_result.push_back(-1./6); + + CPPUNIT_ASSERT_MESSAGE("Identical squares test failed (TRIANGULATION)", + (INTERP_KERNEL::checkEqualPolygons<std::vector<double>,2>(&actual_result, &expected_result, _Epsilon))); + } + // Two triangles with a starting vertex on edge + + // /\ ²²²² + // / ² ² + // / ² ² + // /__²___\ + + // \brief Status : pass + void SingleElementPlanarTests::trianglesCritical() + { + INTERP_KERNEL::PolygonAlgorithms<3> intersector (_Epsilon, _Precision);; + std::deque< double > actual_result = intersector.intersectConvexPolygons(_triangle3,_triangle4,3,3); + std::deque< double > expected_result; + + expected_result.push_back(2./3);expected_result.push_back(2.);expected_result.push_back(1./3); + expected_result.push_back(0.5);expected_result.push_back(2.);expected_result.push_back(0.); + expected_result.push_back(0.75);expected_result.push_back(2.);expected_result.push_back(0.25); + + CPPUNIT_ASSERT_MESSAGE("Triangles critical test failed (CONVEX)", + (INTERP_KERNEL::checkEqualPolygons<std::deque<double>,3>(&actual_result, &expected_result, _Epsilon))); + } + void SingleElementPlanarTests::trianglesCritical_Triangulation() + { + std::vector< double > actual_result; + double _triangle3rotated[6],_triangle4rotated[6]; + for (int i=0; i<3; i++)_triangle3rotated[2*i] = _triangle3[3*i]; + for (int i=0; i<3; i++)_triangle3rotated[2*i+1] = _triangle3[3*i+2]; + for (int i=0; i<3; i++)_triangle4rotated[2*i] = _triangle4[3*i]; + for (int i=0; i<3; i++)_triangle4rotated[2*i+1] = _triangle4[3*i+2]; + + INTERP_KERNEL::intersec_de_polygone<2>(_triangle3rotated,_triangle4rotated,3,3,actual_result,_Epsilon/_Precision, _Precision ); + + std::vector< double > expected_result; + + expected_result.push_back(0.5);expected_result.push_back(0.); + expected_result.push_back(2./3);expected_result.push_back(1./3); + expected_result.push_back(0.75);expected_result.push_back(0.25); + + CPPUNIT_ASSERT_MESSAGE("Triangles critical test failed (TRIANGULATION)", + (INTERP_KERNEL::checkEqualPolygons<std::vector<double>,2>(&actual_result, &expected_result, _Epsilon))); + } + + // Two tangent paralellograms intersecting at 3 double vertices (one being a starting vertex) + // _______ + // /\ /\ + // / \ / \ + // / \ / \ + // /______\/______\ + + + // \brief Status : pass + void SingleElementPlanarTests::paralellogramsCritical1() + { + INTERP_KERNEL::PolygonAlgorithms<2> intersector (_Epsilon, _Precision);; + std::deque< double > actual_result = intersector.intersectConvexPolygons(_parallel1,_parallel2,4,4); + std::deque< double > expected_result; + + expected_result.push_back(0.);expected_result.push_back(0.); + expected_result.push_back(0.);expected_result.push_back(0.); + expected_result.push_back(-0.5);expected_result.push_back(1.); + expected_result.push_back(0.5);expected_result.push_back(1.); + + CPPUNIT_ASSERT_MESSAGE("Paralellogram tangency test (1) failed (CONVEX)", + (INTERP_KERNEL::checkEqualPolygons<std::deque<double>,2>(&actual_result, &expected_result, _Epsilon))); + } + void SingleElementPlanarTests::paralellogramsCritical1_Triangulation() + { + std::vector< double > actual_result; + INTERP_KERNEL::intersec_de_polygone<2>(_parallel1,_parallel2,4,4,actual_result,_Epsilon/_Precision, _Precision ); + + std::vector< double > expected_result; + + expected_result.push_back(0.25);expected_result.push_back(0.5); + expected_result.push_back(0.5);expected_result.push_back(1.); + expected_result.push_back(0.);expected_result.push_back(2./3); + expected_result.push_back(-0.5);expected_result.push_back(1.); + expected_result.push_back(-0.25);expected_result.push_back(0.5); + expected_result.push_back(0.);expected_result.push_back(0.); + + CPPUNIT_ASSERT_MESSAGE("Paralellogram tangency test (1) failed (TRIANGULATION)", + (INTERP_KERNEL::checkEqualPolygons<std::vector<double>,2>(&actual_result, &expected_result, _Epsilon))); + } + + // Two paralellograms sharing a vertex in an exclusion configuration + // ________ + // / / + // / / + // / / + // /_______/_______ + // / / + // / / + // / / + // /_______/ + + + // \brief Status : pass + void SingleElementPlanarTests::paralellogramsCritical2() + { + INTERP_KERNEL::PolygonAlgorithms<2> intersector (_Epsilon, _Precision);; + std::deque< double > actual_result = intersector.intersectConvexPolygons(_parallel1,_parallel3,4,4); + std::deque< double > expected_result; + + CPPUNIT_ASSERT_MESSAGE("Paralellogram tangency test failed (CONVEX)", + (INTERP_KERNEL::checkEqualPolygons<std::deque<double>,2>(&actual_result, &expected_result, _Epsilon))); + } + void SingleElementPlanarTests::paralellogramsCritical2_Triangulation() + { + std::vector< double > actual_result; + INTERP_KERNEL::intersec_de_polygone<2>(_parallel1,_parallel3,4,4,actual_result,_Epsilon/_Precision, _Precision ); + + std::vector< double > expected_result; + + expected_result.push_back(0.);expected_result.push_back(0.); + + CPPUNIT_ASSERT_MESSAGE("Paralellogram tangency test failed (TRIANGULATION)", + (INTERP_KERNEL::checkEqualPolygons<std::vector<double>,2>(&actual_result, &expected_result, _Epsilon))); + } + + // Two triangles in a tangency configuration with a starting vertex on edge + + // _____ + // | / + // __|___/ + // | | / + // | | / + // | |/ + // | / + // | / + // |/ + + // \brief Status : pass + void SingleElementPlanarTests::trianglesTangencyCritical() + { + INTERP_KERNEL::PolygonAlgorithms<2> intersector (_Epsilon, _Precision);; + std::deque< double > actual_result = intersector.intersectConvexPolygons(_triangle5,_triangle6,3,3); + std::deque< double > expected_result; + + expected_result.push_back(1./3);expected_result.push_back(1./2); + expected_result.push_back(1./3);expected_result.push_back(1./3); + expected_result.push_back(1./2);expected_result.push_back(1./2); + + CPPUNIT_ASSERT_MESSAGE("Triangles tangency critical test failed (CONVEX)", + (INTERP_KERNEL::checkEqualPolygons<std::deque<double>,2>(&actual_result, &expected_result, _Epsilon))); + } + void SingleElementPlanarTests::trianglesTangencyCritical_Triangulation() + { + std::vector< double > actual_result; + INTERP_KERNEL::intersec_de_polygone<2>(_triangle5,_triangle6,3,3,actual_result,_Epsilon/_Precision, _Precision ); + + std::vector< double > expected_result; + + expected_result.push_back(1./3);expected_result.push_back(1./2); + expected_result.push_back(1./2);expected_result.push_back(1./2); + expected_result.push_back(1./3);expected_result.push_back(1./3); + + CPPUNIT_ASSERT_MESSAGE("Triangles tangency critical test failed (TRIANGULATION)", + (INTERP_KERNEL::checkEqualPolygons<std::vector<double>,2>(&actual_result, &expected_result, _Epsilon))); + } + + // Two triangles with double starting point in an outer tangency configuration + // /\ + // / \ + // / \ + // /______\ + // \ / + // \ / + // \ / + // \/ + + + // \brief Status : pass + void SingleElementPlanarTests::trianglesTangencyCritical2() + { + INTERP_KERNEL::PolygonAlgorithms<2> intersector (_Epsilon, _Precision);; + std::deque< double > actual_result = intersector.intersectConvexPolygons(_triangle1,_triangle7,3,3); + std::deque< double > expected_result; + + // if(!checkDequesEqual(actual_result,expected_result, _Epsilon)) + // { + // std::cerr<< "CPP_UNIT expected result= " << std::endl; + // dequePrintOut(expected_result); + // std::cerr<< "CPP_UNIT actual result= " << std::endl; + // dequePrintOut(actual_result); + // } + + CPPUNIT_ASSERT_MESSAGE("Triangles tangency critical (2) test failed (CONVEX)", + (INTERP_KERNEL::checkEqualPolygons<std::deque<double>,2>(&actual_result, &expected_result, _Epsilon))); + } + void SingleElementPlanarTests::trianglesTangencyCritical2_Triangulation() + { + std::vector< double > actual_result; + INTERP_KERNEL::intersec_de_polygone<2>(_triangle1,_triangle7,3,3,actual_result,_Epsilon/_Precision, _Precision ); + + std::vector< double > expected_result; + expected_result.push_back(1.);expected_result.push_back(1.); + expected_result.push_back(0.);expected_result.push_back(1.); + + // if(!checkVectorsEqual(actual_result,expected_result, _Epsilon)) + // { + // cerr<< "CPP_UNIT expected result= " << endl; + // vectPrintOut(expected_result); + // cerr<< "CPP_UNIT actual result= " << endl; + // vectPrintOut(actual_result); + // } + + CPPUNIT_ASSERT_MESSAGE("Triangles tangency critical (2) test failed (TRIANGULATION)", + (INTERP_KERNEL::checkEqualPolygons<std::vector<double>,2>(&actual_result, &expected_result, _Epsilon))); + } + // \brief Status : pass + void SingleElementPlanarTests::trianglesTangencyCritical3() + { + INTERP_KERNEL::PolygonAlgorithms<2> intersector (_Epsilon, _Precision);; + std::deque< double > actual_result = intersector.intersectConvexPolygons(_triangle8,_triangle9,3,3); + std::deque< double > expected_result; + + CPPUNIT_ASSERT_MESSAGE("Triangles tangency critical (3) test failed (CONVEX)", + (INTERP_KERNEL::checkEqualPolygons<std::deque<double>,2>(&actual_result, &expected_result, _Epsilon))); + } + void SingleElementPlanarTests::trianglesTangencyCritical3_Triangulation() + { + std::vector< double > actual_result; + INTERP_KERNEL::intersec_de_polygone<2>(_triangle8,_triangle9,3,3,actual_result,_Epsilon/_Precision, _Precision ); + + std::vector< double > expected_result; + expected_result.push_back(22.4601);expected_result.push_back(35.2129); + expected_result.push_back(13.9921);expected_result.push_back(34.693); + + CPPUNIT_ASSERT_MESSAGE("Triangles tangency critical (3) test failed (TRIANGULATION)", + (INTERP_KERNEL::checkEqualPolygons<std::vector<double>,2>(&actual_result, &expected_result, _Epsilon))); + } + void SingleElementPlanarTests::trianglesTangencyCritical4() + { + INTERP_KERNEL::PolygonAlgorithms<2> intersector (_Epsilon, _Precision);; + std::deque< double > actual_result = intersector.intersectConvexPolygons(_triangle10,_triangle11,3,3); + + std::deque< double > expected_result; + expected_result.push_back(82.745193090443536);expected_result.push_back(96.184114390029166); + expected_result.push_back(82.260099999999994);expected_result.push_back(95.720200000000006); + expected_result.push_back(80);expected_result.push_back(100.); + + + CPPUNIT_ASSERT_MESSAGE("Triangles tangency critical (4) test failed (CONVEX)", + (INTERP_KERNEL::checkEqualPolygons<std::deque<double>,2>(&actual_result, &expected_result, _Epsilon))); + } + void SingleElementPlanarTests::trianglesTangencyCritical4_Triangulation() + { + std::vector< double > actual_result; + INTERP_KERNEL::intersec_de_polygone<2>(_triangle10,_triangle11,3,3,actual_result,_Epsilon/_Precision, _Precision ); + + std::vector< double > expected_result; + expected_result.push_back(80);expected_result.push_back(100.); + expected_result.push_back(82.745193090443536);expected_result.push_back(96.184114390029166); + expected_result.push_back(82.260099999999994);expected_result.push_back(95.720200000000006); + + CPPUNIT_ASSERT_MESSAGE("Triangles tangency critical (4) test failed (TRIANGULATION)", + (INTERP_KERNEL::checkEqualPolygons<std::vector<double>,2>(&actual_result, &expected_result, _Epsilon))); + } + +} diff --git a/src/medtool/src/INTERP_KERNELTest/SingleElementPlanarTests.hxx b/src/medtool/src/INTERP_KERNELTest/SingleElementPlanarTests.hxx new file mode 100644 index 000000000..446781f24 --- /dev/null +++ b/src/medtool/src/INTERP_KERNELTest/SingleElementPlanarTests.hxx @@ -0,0 +1,140 @@ +// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 +// 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 __SINGLE_ELEMENT_PLANAR_TESTS_HXX_ +#define __SINGLE_ELEMENT_PLANAR_TESTS_HXX_ + +#include "InterpKernelTestExport.hxx" +#include "InterpolationPlanarTestSuite.hxx" + +namespace INTERP_TEST +{ + /** + * \brief Class testing algorithm by intersecting simple meshes having only one planar element each. + * This serves mainly to verify that the volume calculations between elements is correct. + * + */ + class INTERPKERNELTEST_EXPORT SingleElementPlanarTests : public InterpolationPlanarTestSuite + { + CPPUNIT_TEST_SUITE( SingleElementPlanarTests ); + + CPPUNIT_TEST( diamondsBasic ); + CPPUNIT_TEST( tangentDiamonds ); + CPPUNIT_TEST( tangentSquares ); + CPPUNIT_TEST( diamondsSharingVertex1 ); + CPPUNIT_TEST( identicalSquares ); + CPPUNIT_TEST( squareAndDiamondBasic ); + CPPUNIT_TEST( squareAndDiamondCritical ); + CPPUNIT_TEST( diamondsCritical ); + CPPUNIT_TEST( quadranglesCritical ); + CPPUNIT_TEST( quadrangleAndDiamondCritical ); + CPPUNIT_TEST( diamondsCritical2 ); + CPPUNIT_TEST( hexagonsCritical1 ); + CPPUNIT_TEST( hexagonsCritical2 ); + CPPUNIT_TEST( squareAndQuadrangleCritical ); + CPPUNIT_TEST( diamondsSharingVertex2 ); + CPPUNIT_TEST( triangleAndDiamondCritical ); + CPPUNIT_TEST( triangleAndSquareBasic ); + CPPUNIT_TEST( trianglesCritical ); + CPPUNIT_TEST( paralellogramsCritical1 ); + CPPUNIT_TEST( paralellogramsCritical2 ); + CPPUNIT_TEST( trianglesTangencyCritical ); + CPPUNIT_TEST( trianglesTangencyCritical2 ); + CPPUNIT_TEST( trianglesTangencyCritical3 ); + CPPUNIT_TEST( trianglesTangencyCritical4 ); + CPPUNIT_TEST( diamondsBasic_Triangulation ); + CPPUNIT_TEST( tangentDiamonds_Triangulation ); + CPPUNIT_TEST( tangentSquares_Triangulation ); + CPPUNIT_TEST( diamondsSharingVertex1_Triangulation ); + CPPUNIT_TEST( identicalSquares_Triangulation ); + //CPPUNIT_TEST( squareAndDiamondBasic_Triangulation ); + //CPPUNIT_TEST( squareAndDiamondCritical_Triangulation ); + CPPUNIT_TEST( diamondsCritical_Triangulation ); + CPPUNIT_TEST( quadranglesCritical_Triangulation ); + CPPUNIT_TEST( quadrangleAndDiamondCritical_Triangulation ); + CPPUNIT_TEST( diamondsCritical2_Triangulation ); + CPPUNIT_TEST( hexagonsCritical1_Triangulation ); + CPPUNIT_TEST( hexagonsCritical2_Triangulation ); + CPPUNIT_TEST( squareAndQuadrangleCritical_Triangulation ); + CPPUNIT_TEST( diamondsSharingVertex2_Triangulation ); + CPPUNIT_TEST( triangleAndDiamondCritical_Triangulation ); + CPPUNIT_TEST( triangleAndSquareBasic_Triangulation ); + CPPUNIT_TEST( trianglesCritical_Triangulation ); + CPPUNIT_TEST( paralellogramsCritical1_Triangulation ); + CPPUNIT_TEST( paralellogramsCritical2_Triangulation ); + CPPUNIT_TEST( trianglesTangencyCritical_Triangulation ); + CPPUNIT_TEST( trianglesTangencyCritical2_Triangulation ); + CPPUNIT_TEST( trianglesTangencyCritical3_Triangulation ); + CPPUNIT_TEST( trianglesTangencyCritical4_Triangulation ); + + CPPUNIT_TEST_SUITE_END(); + + public: + + void diamondsBasic(); + void tangentDiamonds(); + void tangentSquares(); + void diamondsSharingVertex1(); + void identicalSquares(); + void squareAndDiamondBasic(); + void squareAndDiamondCritical(); + void diamondsCritical(); + void quadranglesCritical(); + void quadrangleAndDiamondCritical(); + void diamondsCritical2(); + void hexagonsCritical1(); + void hexagonsCritical2(); + void squareAndQuadrangleCritical(); + void diamondsSharingVertex2(); + void triangleAndDiamondCritical(); + void triangleAndSquareBasic(); + void trianglesCritical(); + void paralellogramsCritical1(); + void paralellogramsCritical2(); + void trianglesTangencyCritical(); + void trianglesTangencyCritical2(); + void trianglesTangencyCritical3(); + void trianglesTangencyCritical4(); + void diamondsBasic_Triangulation(); + void tangentDiamonds_Triangulation(); + void tangentSquares_Triangulation(); + void diamondsSharingVertex1_Triangulation(); + void identicalSquares_Triangulation(); + void squareAndDiamondBasic_Triangulation(); + void squareAndDiamondCritical_Triangulation(); + void diamondsCritical_Triangulation(); + void quadranglesCritical_Triangulation(); + void quadrangleAndDiamondCritical_Triangulation(); + void diamondsCritical2_Triangulation(); + void hexagonsCritical1_Triangulation(); + void hexagonsCritical2_Triangulation(); + void squareAndQuadrangleCritical_Triangulation(); + void diamondsSharingVertex2_Triangulation(); + void triangleAndDiamondCritical_Triangulation(); + void triangleAndSquareBasic_Triangulation(); + void trianglesCritical_Triangulation(); + void paralellogramsCritical1_Triangulation(); + void paralellogramsCritical2_Triangulation(); + void trianglesTangencyCritical_Triangulation(); + void trianglesTangencyCritical2_Triangulation(); + void trianglesTangencyCritical3_Triangulation(); + void trianglesTangencyCritical4_Triangulation(); + }; +} +#endif diff --git a/src/medtool/src/INTERP_KERNELTest/SingleElementTetraTests.hxx b/src/medtool/src/INTERP_KERNELTest/SingleElementTetraTests.hxx new file mode 100644 index 000000000..023b7a2ab --- /dev/null +++ b/src/medtool/src/INTERP_KERNELTest/SingleElementTetraTests.hxx @@ -0,0 +1,170 @@ +// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 +// 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 __SINGLE_ELEMENT_TETRA_TESTS_HXX_ +#define __SINGLE_ELEMENT_TETRA_TESTS_HXX_ + +#include "InterpolationTestSuite.hxx" + +namespace INTERP_TEST +{ + /** + * \brief Class testing algorithm by intersecting simple meshes having only one element each. This serves mainly to verify that + * the volume calculations between elements is correct. + * + */ + class SingleElementTetraTests : public InterpolationTestSuite<3,3> + { + CPPUNIT_TEST_SUITE( SingleElementTetraTests ); + + CPPUNIT_TEST( tetraReflexiveUnit ); + CPPUNIT_TEST( tetraReflexiveGeneral ); + CPPUNIT_TEST( tetraNudgedSimpler ); + CPPUNIT_TEST( tetraNudged ); + CPPUNIT_TEST( tetraCorner ); + CPPUNIT_TEST( tetraSimpleIncluded ); + CPPUNIT_TEST( tetraDegenEdge ); + CPPUNIT_TEST( tetraDegenFace ); + CPPUNIT_TEST( tetraDegenTranslatedInPlane ); + CPPUNIT_TEST( tetraHalfstripOnly ); + CPPUNIT_TEST( tetraHalfstripOnly2 ); + CPPUNIT_TEST( tetraSimpleHalfstripOnly ); + CPPUNIT_TEST( generalTetra ); + CPPUNIT_TEST( trickyTetra1 ); + // CPPUNIT_TEST( inconsistentTetra ); + + CPPUNIT_TEST_SUITE_END(); + + public: + + /// Unit tetrahedron mesh intersecting itself + /// \brief Status : pass + void tetraReflexiveUnit() + { + _testTools->intersectMeshes("UnitTetra", "UnitTetra", 1.0/6.0); + } + + /// Tetrahedron mesh with itself + /// \brief Status : pass + void tetraReflexiveGeneral() + { + _testTools->intersectMeshes("GeneralTetra", "GeneralTetra", 0.428559); + } + + /// Unit tetrahedron mesh intersecting slightly displaced copy of itself + /// \brief Status : pass + void tetraNudged() + { + _testTools->intersectMeshes("UnitTetra", "NudgedTetra", 0.142896); + } + + /// Single-element unit tetrahedron mesh intersecting even slightly displaced (along one axis only) copy of itself + /// \brief Status : pass + void tetraNudgedSimpler() + { + _testTools->intersectMeshes("UnitTetra", "NudgedSimpler", 0.152112); + } + + /// Tetrahedron intersecting unit tetrahedron with in non-degenerate way around corner O + /// \brief Status : pass + void tetraCorner() + { + _testTools->intersectMeshes("UnitTetra", "CornerTetra", 0.0135435); + } + + /// Tetrahedron situated totally inside another + /// \brief Status : pass + void tetraSimpleIncluded() + { + _testTools->intersectMeshes("SimpleIncludedTetra", "SimpleIncludingTetra", 17.0156); + } + + /// Displaced unit tetrahedron intersecting another unit tetrahedron with which it shares an edge + /// \brief Status : pass + void tetraDegenEdge() + { + _testTools->intersectMeshes("UnitTetraDegenT", "DegenEdgeXY", 0.0); + } + + /// Displaced unit tetrahedron intersecting another unit tetrahedron with which it shares a face + /// \brief Status : pass + void tetraDegenFace() + { + _testTools->intersectMeshes("UnitTetraDegenT", "DegenFaceXYZ", 0.0); + } + + /// Displaced unit tetrahedron intersecting another unit tetrahedron with which it shares a part of the face XYZ + /// \brief Status : pass + void tetraDegenTranslatedInPlane() + { + _testTools->intersectMeshes("UnitTetraDegenT", "DegenTranslatedInPlane", 0.0571667); + } + + /// Tetrahedron having only half-strip intersections with the unit tetrahedron + /// \brief Status : pass, but does not really test what it should - does not check that the intersections are detected. No longer needed. + void tetraHalfstripOnly() + { + // NB this test is not completely significant : we should also verify that + // there are triangles on the element that give a non-zero volume + _testTools->intersectMeshes("HalfstripOnly", "UnitTetra", 0.0); + } + + /// Tetrahedron having only half-strip intersections with the unit tetrahedron + /// \brief Status : pass, but does not really test what it should - does not check that the intersections are detected. No longer needed. + void tetraHalfstripOnly2() + { + // NB this test is not completely significant : we should also verify that + // there are triangles on the element that give a non-zero volume + _testTools->intersectMeshes("HalfstripOnly2", "UnitTetra", 0.0); + } + + /// Tetrahedron having only half-strip intersections with the unit tetrahedron + /// \brief Status : pass, but does not really test what it should - does not check that the intersections are detected. No longer needed. + void tetraSimpleHalfstripOnly() + { + // NB this test is not completely significant : we should also verify that + // there are triangles on the element that give a non-zero volume + _testTools->intersectMeshes("SimpleHalfstripOnly", "UnitTetra", 0.0); + } + + /// Two intersecting tetrahedra situated in a general position in space + /// \brief Status : pass + void generalTetra() + { + _testTools->intersectMeshes("GenTetra1", "GenTetra2", 4.91393); + } + + /// Tetrahedron which is in a tricky position relative to unit tetrahedron. + /// \brief Status : pass + void trickyTetra1() + { + _testTools->intersectMeshes("UnitTetra", "TrickyTetra1", 0.0); + } + + /// Two large tetrahedra which nearly share part of an edge and intersect at the origin. Created with goal of getting the as-of-yet uncovered "consistency" test + /// part of the correction of double products covered. However, it does not succeed with this. + /// \brief Status : fails, but is quite far-fetched as far as typical use cases are concerned + void inconsistentTetra() + { + _testTools->intersectMeshes("LargeUnitTetra.med", "LargeUnitTetra", "LargeInconsistentTetra.med", "LargeInconsistent", 7.86231e7); + } + + }; +} +#endif diff --git a/src/medtool/src/INTERP_KERNELTest/TestInterpKernel.cxx b/src/medtool/src/INTERP_KERNELTest/TestInterpKernel.cxx new file mode 100644 index 000000000..bfc450a26 --- /dev/null +++ b/src/medtool/src/INTERP_KERNELTest/TestInterpKernel.cxx @@ -0,0 +1,58 @@ +// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// + +#include "CppUnitTest.hxx" +#include "BBTreeTest.hxx" +#include "ExprEvalInterpTest.hxx" +#include "QuadraticPlanarInterpTest.hxx" +#include "SingleElementPlanarTests.hxx" +#include "TransformedTriangleIntersectTest.hxx" +#include "TransformedTriangleTest.hxx" +#include "UnitTetraIntersectionBaryTest.hxx" +#include "UnitTetra3D2DIntersectionTest.hxx" + +#include "HexaTests.hxx" +#include "InterpolationOptionsTest.hxx" +#include "MultiElement2DTests.hxx" +#include "MultiElementTetraTests.hxx" +#include "SingleElementTetraTests.hxx" +#include "ThreeDSurfProjectionTest.hxx" + +using namespace INTERP_TEST; + +//--- Registers the fixture into the 'registry' + +CPPUNIT_TEST_SUITE_REGISTRATION( BBTreeTest ); +CPPUNIT_TEST_SUITE_REGISTRATION( ExprEvalInterpTest ); +CPPUNIT_TEST_SUITE_REGISTRATION( QuadraticPlanarInterpTest ); +CPPUNIT_TEST_SUITE_REGISTRATION( SingleElementPlanarTests ); +CPPUNIT_TEST_SUITE_REGISTRATION( TransformedTriangleIntersectTest ); +CPPUNIT_TEST_SUITE_REGISTRATION( TransformedTriangleTest ); +CPPUNIT_TEST_SUITE_REGISTRATION( UnitTetraIntersectionBaryTest ); +CPPUNIT_TEST_SUITE_REGISTRATION( UnitTetra3D2DIntersectionTest ); + +CPPUNIT_TEST_SUITE_REGISTRATION( InterpolationOptionsTest ); +CPPUNIT_TEST_SUITE_REGISTRATION( HexaTests ); +CPPUNIT_TEST_SUITE_REGISTRATION( MultiElement2DTests ); +CPPUNIT_TEST_SUITE_REGISTRATION( MultiElementTetraTests ); +CPPUNIT_TEST_SUITE_REGISTRATION( SingleElementTetraTests ); +CPPUNIT_TEST_SUITE_REGISTRATION( ThreeDSurfProjectionTest ); +// --- generic Main program from KERNEL_SRC/src/Basics/Test + +#include "BasicMainTest.hxx" diff --git a/src/medtool/src/INTERP_KERNELTest/TestInterpKernelUtils.cxx b/src/medtool/src/INTERP_KERNELTest/TestInterpKernelUtils.cxx new file mode 100644 index 000000000..d82a4c273 --- /dev/null +++ b/src/medtool/src/INTERP_KERNELTest/TestInterpKernelUtils.cxx @@ -0,0 +1,44 @@ +// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// + +#include "TestInterpKernelUtils.hxx" + +#include <cstdlib> + +namespace INTERP_TEST +{ + std::string getResourceFile( const std::string& filename ) + { + std::string resourceFile = ""; + + if ( getenv("top_srcdir") ) { + // we are in 'make test' step + resourceFile = getenv("top_srcdir"); + resourceFile += "/resources/"; + } + else if ( getenv("MED_ROOT_DIR") ) { + // use MED_ROOT_DIR env.var + resourceFile = getenv("MED_ROOT_DIR"); + resourceFile += "/share/salome/resources/med/"; + } + resourceFile += filename; + return resourceFile; + } + +} // namespace INTERP_TEST diff --git a/src/medtool/src/INTERP_KERNELTest/TestInterpKernelUtils.hxx b/src/medtool/src/INTERP_KERNELTest/TestInterpKernelUtils.hxx new file mode 100644 index 000000000..d17240a7f --- /dev/null +++ b/src/medtool/src/INTERP_KERNELTest/TestInterpKernelUtils.hxx @@ -0,0 +1,34 @@ +// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 +// 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 _TESTINTERPKERNELUTILS_HXX_ +#define _TESTINTERPKERNELUTILS_HXX_ + +#include "InterpKernelTestExport.hxx" + +#include <string> + +namespace INTERP_TEST +{ + + INTERPKERNELTEST_EXPORT std::string getResourceFile( const std::string& ); + +} // namespace INTERP_TEST + +#endif // _TESTINTERPKERNELUTILS_HXX_ diff --git a/src/medtool/src/INTERP_KERNELTest/ThreeDSurfProjectionTest.cxx b/src/medtool/src/INTERP_KERNELTest/ThreeDSurfProjectionTest.cxx new file mode 100644 index 000000000..2a84b503a --- /dev/null +++ b/src/medtool/src/INTERP_KERNELTest/ThreeDSurfProjectionTest.cxx @@ -0,0 +1,128 @@ +// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// + +#include "ThreeDSurfProjectionTest.hxx" +#include "PlanarIntersector.txx" + +class MyMeshType +{ +public: + static const int MY_SPACEDIM=3; + static const int MY_MESHDIM=3; + static const INTERP_KERNEL::NumberingPolicy My_numPol=INTERP_KERNEL::ALL_C_MODE; + typedef int MyConnType; +}; + +class MyMatrixType +{ +}; + +void INTERP_TEST::ThreeDSurfProjectionTest::test1() +{ + // Two triangles coo and coo2 are perfectly // each others with a distance equal to 1e-6. + // A little rotation to make it more funny. + //coo=DataArrayDouble([0.,0.,0.,1.,0.,0.,0.,1.,0.],3,3) + //eps=1e-6 + //coo2=DataArrayDouble([0.,0.,eps,1.,0.,eps,0.,1.,eps],3,3) + //MEDCouplingPointSet.Rotate3DAlg([0.,0.,0.],[2.,1.,3.],0.3,coo) + //MEDCouplingPointSet.Rotate3DAlg([0.,0.,0.],[2.,1.,3.],0.3,coo2) + const double coo[9]={0.,0.,0.,0.96809749223257568,0.24332379388106262,-0.059839592782071335,-0.23056279077409292,0.95852673990234838,0.16753294721527912}; + const double coo2[9]={9.8122602102980502e-08,-1.4839144255482456e-7,9.8404874611628791e-7,0.96809759035517784,0.24332364548962007,-0.059838608733325221,-0.23056269265149082,0.9585265915109058,0.16753393126402524}; + double *tmp0(new double[9]),*tmp1(new double[9]); + int ret; + //eps=1e-2. eps is a tolerance to detect that two points are the same or not in a same polygon. + // here the max 3D distance is 1e-5 > 1e-6 so 1 is expected + std::copy(coo,coo+9,tmp0); + std::copy(coo2,coo2+9,tmp1); + ret=INTERP_KERNEL::PlanarIntersector<MyMeshType,MyMatrixType>::Projection(tmp0,tmp1,3,3,1e-2,1e-5/* <- */,-1.,0.5,true); + CPPUNIT_ASSERT_EQUAL(1,ret); + const double expected0[9]={0.,0.,0.,1.,0.,0.,0.,1.,0.}; + for(int i=0;i<9;i++) + { + CPPUNIT_ASSERT_DOUBLES_EQUAL(expected0[i],tmp0[i],1e-15); + CPPUNIT_ASSERT_DOUBLES_EQUAL(expected0[i],tmp1[i],1e-15); + } + // here the max 3D distance is 1e-8 < 1e-6 so 0 is expected + std::copy(coo,coo+9,tmp0); + std::copy(coo2,coo2+9,tmp1); + ret=INTERP_KERNEL::PlanarIntersector<MyMeshType,MyMatrixType>::Projection(tmp0,tmp1,3,3,1e-2,1e-8/* <- */,-1.,0.5,true); + CPPUNIT_ASSERT_EQUAL(0,ret); + // here testing when max 3D distance is 1e-5 > 1e-6 with inverted cells + std::copy(coo,coo+9,tmp0); + std::copy(coo2,coo2+3,tmp1+6); std::copy(coo2+3,coo2+6,tmp1+3); std::copy(coo2+6,coo2+9,tmp1); + ret=INTERP_KERNEL::PlanarIntersector<MyMeshType,MyMatrixType>::Projection(tmp0,tmp1,3,3,1e-2,1e-5/* <- */,-1.,0.5,true); + CPPUNIT_ASSERT_EQUAL(-1,ret); + const double expected1[9]={-0.7071067811865476,-0.7071067811865476,0.,0.,-1.4142135623730951,0.,-1.4142135623730951,-1.4142135623730951,0.}; + const double expected2[9]={-1.4142135623730951,-1.4142135623730951,0.,0.,-1.4142135623730951,0.,-0.7071067811865476,-0.7071067811865476,0.}; + for(int i=0;i<9;i++) + { + CPPUNIT_ASSERT_DOUBLES_EQUAL(expected1[i],tmp0[i],1e-14); + CPPUNIT_ASSERT_DOUBLES_EQUAL(expected2[i],tmp1[i],1e-14); + } + // + delete [] tmp0; + delete [] tmp1; +} + +void INTERP_TEST::ThreeDSurfProjectionTest::test2() +{// here the two triangles have their center of inertia very close (eps) but the angle between the two planes is "big" + //coo=DataArrayDouble([0.,0.,0.,1.,0.,0.,0.,1.,0.],3,3) + //coocpy=coo.deepCpy() + //MEDCouplingPointSet.Rotate3DAlg([0.,0.,0.],[-1,-1.,0.],pi/3,coocpy) + //coocpy+=[eps*sqrt(3)/2,eps/2,eps*0.] + // + const double coo[9]={0.,0.,0.,0.96809749223257568,0.24332379388106262,-0.059839592782071335,-0.23056279077409292,0.95852673990234838,0.16753294721527912}; + const double coo2[9]={7.2311562622637225e-07,6.8998795679738294e-07,3.1943866106249849e-08,0.72852072144314628,0.33125439126063028,0.5996079016637561,0.0090154262465889021,0.87059752249869415,-0.49191448334281612}; + double *tmp0(new double[9]),*tmp1(new double[9]); + int ret; + //eps=1e-2. eps is a tolerance to detect that two points are the same or not in a same polygon. + // here the max 3D distance is 1e-5 > 1e-6 so 1 is expected + std::copy(coo,coo+9,tmp0); + std::copy(coo2,coo2+9,tmp1); + ret=INTERP_KERNEL::PlanarIntersector<MyMeshType,MyMatrixType>::Projection(tmp0,tmp1,3,3,1e-2,1e-5/* <- */,-1.,0.5,true); + CPPUNIT_ASSERT_EQUAL(1,ret); + // here the max 3D distance is 1e-8 < 1e-6 so 0 is expected + std::copy(coo,coo+9,tmp0); + std::copy(coo2,coo2+9,tmp1); + ret=INTERP_KERNEL::PlanarIntersector<MyMeshType,MyMatrixType>::Projection(tmp0,tmp1,3,3,1e-2,1e-8/* <- */,-1.,0.5,true); + CPPUNIT_ASSERT_EQUAL(0,ret); + // again max 3D distance is 1e-5 > 1e-6 so 1 is expected + std::copy(coo,coo+9,tmp0); + std::copy(coo2,coo2+9,tmp1); + ret=INTERP_KERNEL::PlanarIntersector<MyMeshType,MyMatrixType>::Projection(tmp0,tmp1,3,3,1e-2,1e-5/* <- */,-1.,0.5,true); + CPPUNIT_ASSERT_EQUAL(1,ret); + // again max 3D distance is 1e-5 > 1e-6 but minDot set to 0.8. 0 expected. because the angle is pi/4 so cos(pi/3) > 0.8 + std::copy(coo,coo+9,tmp0); + std::copy(coo2,coo2+9,tmp1); + ret=INTERP_KERNEL::PlanarIntersector<MyMeshType,MyMatrixType>::Projection(tmp0,tmp1,3,3,1e-2,1e-5/* <- */,0.8/* <- */,0.5,true); + CPPUNIT_ASSERT_EQUAL(0,ret); + // again max 3D distance is 1e-5 > 1e-6 but minDot set to 0.7. 1 expected. because the angle is pi/4 so cos(pi/3) < 0.49 + std::copy(coo,coo+9,tmp0); + std::copy(coo2,coo2+9,tmp1); + ret=INTERP_KERNEL::PlanarIntersector<MyMeshType,MyMatrixType>::Projection(tmp0,tmp1,3,3,1e-2,1e-5/* <- */,0.49/* <- */,0.5,true); + CPPUNIT_ASSERT_EQUAL(1,ret); + // again max 3D distance is 1e-5 > 1e-6 but minDot set to 0.7. 0 expected. because the angle is pi/4 so cos(pi/3) > 0.51 + std::copy(coo,coo+9,tmp0); + std::copy(coo2,coo2+9,tmp1); + ret=INTERP_KERNEL::PlanarIntersector<MyMeshType,MyMatrixType>::Projection(tmp0,tmp1,3,3,1e-2,1e-5/* <- */,0.51/* <- */,0.5,true); + CPPUNIT_ASSERT_EQUAL(0,ret); + // + delete [] tmp0; + delete [] tmp1; +} diff --git a/src/medtool/src/INTERP_KERNELTest/ThreeDSurfProjectionTest.hxx b/src/medtool/src/INTERP_KERNELTest/ThreeDSurfProjectionTest.hxx new file mode 100644 index 000000000..40d27a587 --- /dev/null +++ b/src/medtool/src/INTERP_KERNELTest/ThreeDSurfProjectionTest.hxx @@ -0,0 +1,44 @@ +// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 +// 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 __THREEDSURFPROJECTIONTEST_HXX__ +#define __THREEDSURFPROJECTIONTEST_HXX__ + +#include <cppunit/extensions/HelperMacros.h> + +#include "InterpKernelTestExport.hxx" + +namespace INTERP_TEST +{ + /** + * \brief Class dedicated of the test of the preprocessing of 3D surf cells before performing invoking 2D algorithms. + */ + class INTERPKERNELTEST_EXPORT ThreeDSurfProjectionTest : public CppUnit::TestFixture + { + CPPUNIT_TEST_SUITE( ThreeDSurfProjectionTest ); + CPPUNIT_TEST ( test1 ); + CPPUNIT_TEST ( test2 ); + CPPUNIT_TEST_SUITE_END(); + public: + void test1(); + void test2(); + }; +} + +#endif diff --git a/src/medtool/src/INTERP_KERNELTest/TransformedTriangleIntersectTest.cxx b/src/medtool/src/INTERP_KERNELTest/TransformedTriangleIntersectTest.cxx new file mode 100644 index 000000000..8fdc77df3 --- /dev/null +++ b/src/medtool/src/INTERP_KERNELTest/TransformedTriangleIntersectTest.cxx @@ -0,0 +1,2284 @@ +// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// + +#include "TransformedTriangleIntersectTest.hxx" +#include <iostream> + +#include "Log.hxx" + +/// macro to test for zero double products outside the segment-edge intersection test method +/// as is done in TransformedTriangle when OPTIMIZE is defined +#define TEST_ZERO_DP_EDGE(seg, edge) isZero[TT::NO_DP*int(seg) + int(DoubleProduct(edge))] + +/// macro to test for zero double products outside the segment-corner intersection test method +/// as is done in TransformedTriangle when OPTIMIZE is defined +#define TEST_ZERO_DP_CORNER(seg, corner) \ + isZero[DoubleProduct(TT::NO_DP*int(seg) + TT::EDGES_FOR_CORNER[3*corner] )] && \ + isZero[DoubleProduct(TT::NO_DP*int(seg) + TT::EDGES_FOR_CORNER[3*corner+1] )] && \ + isZero[DoubleProduct(TT::NO_DP*int(seg) + TT::EDGES_FOR_CORNER[3*corner+2] )] + +/// macro to test for zero double products outside the segment-ray intersection test method +/// as is done in TransformedTriangle when OPTIMIZE is defined +#define TEST_ZERO_DP_RAY(seg, corner) isZero[TT::NO_DP*int(seg) + TT::DP_SEGMENT_RAY_INTERSECTION[7*(corner-1)]] + +using namespace INTERP_KERNEL; + +namespace INTERP_TEST +{ + + //////////////////////////////////////////////////////////////////////////////////////////////////////// + /// \class TransformedTriangleIntersectTest + /// \brief Class testing the intersection detection methods of TransformedTriangle. + /// + /// This class contains unit tests for the intersection methods of the TransformedTriangle class. + //////////////////////////////////////////////////////////////////////////////////////////////////////// + /// Each method in the class runs all the intersection tests with some triangle. The goal is to cover all + /// the different types of intersections between a triangle and a tetrahedron. The table below gives a + /// a summary of what is being tested. Before each method, there is also a summary of what how the + /// triangle in the method intersects the unit tetrahedron. + /// + /// Since performing all tests would require a large number of triangles, we have limited our coverage to + /// be such that each column and each row in the table below has at least one entry for each type of + /// intersection. The intersection forumlae are totally symmetric with respect to changing the segment + /// (PQ, QR, or RP) of the triangle, so they only enter in a very simple way in the code. Testing + /// all these cases is therefore of low priority. + //////////////////////////////////////////////////////////////////////////////////////////////////////// + /// + //////////////////////////////////////////////////////////////////////////////////////////////////////// + /// Intersections tested (number indicates first triangle which contains the intersection): + /// <PRE> + /// ----------------------------------------------------------------------------------------------------- + /// CI -> P: 3 Q: 4 R: 7 + /// COH -> P: 9 Q: 8 R: 10 + /// CAH -> P: 4 Q: 10 R: 9 + /// ----------------------------------------------------------------------------------------------------- + /// SF -> (PQ, OZX) : 1 (PQ, OYZ) : 2 (PQ, OXY) : 1 (PQ, XYZ) : 3 + /// -> (QR, OZX) : 8 (QR, OYZ) : - (QR, OXY) : 4 (QR, XYZ) : 7 + /// -> (RP, OZX) : 1 (RP, OYZ) : 3 (RP, OXY) : 7 (RP, XYZ) : 1 + /// ----------------------------------------------------------------------------------------------------- + /// SE -> (PQ, OX) : 11 (PQ, OY) : - (PQ, OZ) : 12 (PQ, XY) : 2 (PQ, ZX) : - (PQ, YZ) : 10 + /// -> (QR, OX) : - (QR, OY) : - (QR, OZ) : - (QR, XY) : - (QR, ZX) : 9 (QR, YZ) : - + /// -> (RP, OX) : - (RP, OY) : 12 (RP, OZ) : - (RP, XY) : - (RP, ZX) : - (RP, YZ) : - + /// ----------------------------------------------------------------------------------------------------- + /// SC -> (PQ, O) : - (PQ, X) : - (PQ, Y) : 8 (PQ, Z) : - + /// -> (QR, O) : - (QR, X) : 2 (QR, Y) : - (QR, Z) : 13 + /// -> (RP, O) : 11 (RP, X) : - (RP, Y) : - (RP, Z) : - + /// ----------------------------------------------------------------------------------------------------- + /// SHS -> (PQ, XY) : 3 (PQ, ZX) : - (PQ, YZ) : 13 + /// -> (QR, XY) : 3 (QR, ZX) : 5 (QR, YZ) : 3 + /// -> (RP, XY) : 1 (RP, ZX) : 4 (RP, YZ) : - + /// ----------------------------------------------------------------------------------------------------- + /// SR -> (PQ, X) : 6 (PQ, Y) : 5 (PQ, Z) : - + /// -> (QR, X) : - (QR, Y) : - (QR, Z) : 6 + /// -> (RP, X) : - (RP, Y) : - (RP, Z) : - + /// ----------------------------------------------------------------------------------------------------- + /// TE -> OX : 4 OY : 7 OZ : 8 XY : 1 ZX : 4 YZ : 3 + /// ----------------------------------------------------------------------------------------------------- + /// TR -> X : 7 Y : 6 Z : 5 + /// ----------------------------------------------------------------------------------------------------- + /// </PRE> + //////////////////////////////////////////////////////////////////////////////////////////////////////// + + //////////////////////////////////////////////////////////////////////////////////////////////////////// + /// Key to triangle descriptions : + /// CI = Triangle corner contained in tetrahedron + /// COH = Triangle corner on h = 0 face of tetrahedron + /// CAH = Triangle corner above h = 0 face of tetrahedron in z-direction + /// SF = Segment - facet intersection + /// SE = Segment - edge intersection + /// SC = Segment - corner intersection + /// SHS = Segment - halfstrip intersection + /// SR = Segment - ray intersection + /// TE = Tetrahedron edge intersects triangle (surface - edge intersection) + /// TR = Surface - ray intersection + /// + /// In the descriptions for each triangle, square brackets indicate superfluous but allowed intersections + /// that arise as by-products of for instance segment-corner intersections. + /// E.g. A segment - corner intersection can imply three surface - edge intersections + /// Since these "extra" intersections arise under special circumstances, they are not counted in the + /// table above + //////////////////////////////////////////////////////////////////////////////////////////////////////// + + + //////////////////////////////////////////////////////////////////////////////////////////////////////// + /// Triangle 1 has the following intersections + /// <PRE> + /// CI - + /// COH - + /// CAH - + /// SF (PQ, OXY), (PQ, OZX), (RP, XYZ), (RP, OZX) + /// SE - + /// SC - + /// SHS (RP, XY) + /// SR - + /// TE XY + /// TR - + /// </PRE> + /// \brief Status : pass + void TransformedTriangleIntersectTest::testTriangle1() + { + LOG(1, "+++++++ Testing triangle 1" ); + + typedef TransformedTriangle TT; + + double coords[9] = + { + 0.4,-0.5, 0.5, // P + 0.4, 2.5,-1.0, // Q + 0.4, 2.5, 0.5 // R + }; + + TransformedTriangle* tri = new TransformedTriangle(&coords[0], &coords[3], &coords[6]); + + // run all intersection tests and ensure that the ones + // listed with yes in the tables above return true and + // that the ones listed with no or not listed at all return false + + bool isZero[TT::NO_TRI_SEGMENT * TT::NO_DP]; + + for(TriSegment seg = TT::PQ ; seg < TT::NO_TRI_SEGMENT ; seg = TT::TriSegment(seg + 1)) + { + // check beforehand which double-products are zero + for(DoubleProduct dp = TT::C_YZ; dp < TT::NO_DP; dp = DoubleProduct(dp + 1)) + { + isZero[TT::NO_DP*int(seg) + int(dp)] = (tri->calcStableC(seg, dp) == 0.0); + } + } + + // corner in tetrahedron (3 possibilities) + CPPUNIT_ASSERT_EQUAL(false, tri->testCornerInTetrahedron(TT::P)); + CPPUNIT_ASSERT_EQUAL(false, tri->testCornerInTetrahedron(TT::Q)); + CPPUNIT_ASSERT_EQUAL(false, tri->testCornerInTetrahedron(TT::R)); + + // corner on XYZ facet (3 possibilities) + CPPUNIT_ASSERT_EQUAL(false, tri->testCornerOnXYZFacet(TT::P)); + CPPUNIT_ASSERT_EQUAL(false, tri->testCornerOnXYZFacet(TT::Q)); + CPPUNIT_ASSERT_EQUAL(false, tri->testCornerOnXYZFacet(TT::R)); + + // corner above XYZ facet (3 possibilities) + CPPUNIT_ASSERT_EQUAL(false, tri->testCornerAboveXYZFacet(TT::P)); + CPPUNIT_ASSERT_EQUAL(false, tri->testCornerAboveXYZFacet(TT::Q)); + CPPUNIT_ASSERT_EQUAL(false, tri->testCornerAboveXYZFacet(TT::R)); + + // segment-facet (9 possibilities) + CPPUNIT_ASSERT_EQUAL(true , tri->testSegmentFacetIntersection(TT::PQ, TT::OZX)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::PQ, TT::OYZ)); + CPPUNIT_ASSERT_EQUAL(true , tri->testSegmentFacetIntersection(TT::PQ, TT::OXY)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::PQ, TT::XYZ)); + + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::QR, TT::OZX)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::QR, TT::OYZ)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::QR, TT::OXY)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::QR, TT::XYZ)); + + CPPUNIT_ASSERT_EQUAL(true , tri->testSegmentFacetIntersection(TT::RP, TT::OZX)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::RP, TT::OYZ)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::RP, TT::OXY)); + CPPUNIT_ASSERT_EQUAL(true , tri->testSegmentFacetIntersection(TT::RP, TT::XYZ)); + + // segment-edge (18 possibilities) + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::PQ, TT::OX) && tri->testSegmentEdgeIntersection(TT::PQ, TT::OX)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::PQ, TT::OY) && tri->testSegmentEdgeIntersection(TT::PQ, TT::OY)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::PQ, TT::OZ) && tri->testSegmentEdgeIntersection(TT::PQ, TT::OZ)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::PQ, TT::YZ) && tri->testSegmentEdgeIntersection(TT::PQ, TT::YZ)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::PQ, TT::ZX) && tri->testSegmentEdgeIntersection(TT::PQ, TT::ZX)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::PQ, TT::XY) && tri->testSegmentEdgeIntersection(TT::PQ, TT::XY)); + + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::QR, TT::OX) && tri->testSegmentEdgeIntersection(TT::QR, TT::OX)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::QR, TT::OY) && tri->testSegmentEdgeIntersection(TT::QR, TT::OY)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::QR, TT::OZ) && tri->testSegmentEdgeIntersection(TT::QR, TT::OZ)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::QR, TT::YZ) && tri->testSegmentEdgeIntersection(TT::QR, TT::YZ)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::QR, TT::ZX) && tri->testSegmentEdgeIntersection(TT::QR, TT::ZX)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::QR, TT::XY) && tri->testSegmentEdgeIntersection(TT::QR, TT::XY)); + + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::RP, TT::OX) && tri->testSegmentEdgeIntersection(TT::RP, TT::OX)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::RP, TT::OY) && tri->testSegmentEdgeIntersection(TT::RP, TT::OY)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::RP, TT::OZ) && tri->testSegmentEdgeIntersection(TT::RP, TT::OZ)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::RP, TT::YZ) && tri->testSegmentEdgeIntersection(TT::RP, TT::YZ)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::RP, TT::ZX) && tri->testSegmentEdgeIntersection(TT::RP, TT::ZX)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::RP, TT::XY) && tri->testSegmentEdgeIntersection(TT::RP, TT::XY)); + + // segment - corner (12 possibilities) + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::PQ, TT::O) && tri->testSegmentCornerIntersection(TT::PQ, TT::O)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::PQ, TT::X) && tri->testSegmentCornerIntersection(TT::PQ, TT::X)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::PQ, TT::Y) && tri->testSegmentCornerIntersection(TT::PQ, TT::Y)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::PQ, TT::Z) && tri->testSegmentCornerIntersection(TT::PQ, TT::Z)); + + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::QR, TT::O) && tri->testSegmentCornerIntersection(TT::QR, TT::O)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::QR, TT::X) && tri->testSegmentCornerIntersection(TT::QR, TT::X)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::QR, TT::Y) && tri->testSegmentCornerIntersection(TT::QR, TT::Y)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::QR, TT::Z) && tri->testSegmentCornerIntersection(TT::QR, TT::Z)); + + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::RP, TT::O) && tri->testSegmentCornerIntersection(TT::RP, TT::O)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::RP, TT::X) && tri->testSegmentCornerIntersection(TT::RP, TT::X)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::RP, TT::Y) && tri->testSegmentCornerIntersection(TT::RP, TT::Y)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::RP, TT::Z) && tri->testSegmentCornerIntersection(TT::RP, TT::Z)); + + // segment-halfstrip (9 possibilities) + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentHalfstripIntersection(TT::PQ, TT::YZ)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentHalfstripIntersection(TT::PQ, TT::ZX)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentHalfstripIntersection(TT::PQ, TT::XY)); + + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentHalfstripIntersection(TT::QR, TT::YZ)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentHalfstripIntersection(TT::QR, TT::ZX)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentHalfstripIntersection(TT::QR, TT::XY)); + + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentHalfstripIntersection(TT::RP, TT::YZ)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentHalfstripIntersection(TT::RP, TT::ZX)); + CPPUNIT_ASSERT_EQUAL(true , tri->testSegmentHalfstripIntersection(TT::RP, TT::XY)); + + // segment-ray (9 possibilities) + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_RAY(TT::PQ, TT::X) && tri->testSegmentRayIntersection(TT::PQ, TT::X)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_RAY(TT::PQ, TT::Y) && tri->testSegmentRayIntersection(TT::PQ, TT::Y)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_RAY(TT::PQ, TT::Z) && tri->testSegmentRayIntersection(TT::PQ, TT::Z)); + + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_RAY(TT::QR, TT::X) && tri->testSegmentRayIntersection(TT::QR, TT::X)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_RAY(TT::QR, TT::Y) && tri->testSegmentRayIntersection(TT::QR, TT::Y)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_RAY(TT::QR, TT::Z) && tri->testSegmentRayIntersection(TT::QR, TT::Z)); + + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_RAY(TT::RP, TT::X) && tri->testSegmentRayIntersection(TT::RP, TT::X)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_RAY(TT::RP, TT::Y) && tri->testSegmentRayIntersection(TT::RP, TT::Y)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_RAY(TT::RP, TT::Z) && tri->testSegmentRayIntersection(TT::RP, TT::Z)); + + // surface-edge (6 possibilities) + CPPUNIT_ASSERT_EQUAL(false, tri->testSurfaceEdgeIntersection(TT::OX)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSurfaceEdgeIntersection(TT::OY)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSurfaceEdgeIntersection(TT::OZ)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSurfaceEdgeIntersection(TT::YZ)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSurfaceEdgeIntersection(TT::ZX)); + CPPUNIT_ASSERT(tri->testSurfaceEdgeIntersection(TT::XY)); + + // surface-ray (3 possibilities) + CPPUNIT_ASSERT_EQUAL(false, tri->testSurfaceRayIntersection(TT::X)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSurfaceRayIntersection(TT::Y)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSurfaceRayIntersection(TT::Z)); + + delete tri; + + } + + /// Triangle 2 has the following intersections + /// <PRE> + /// CI - + /// COH - + /// CAH - + /// SF (PQ, OYZ) + /// SE (PQ, XY) + /// SC (QR, X) + /// SHS - + /// SR - + /// TE [OX, OZ, ZX] + /// TR - + /// </PRE> + /// \brief Status: pass + void TransformedTriangleIntersectTest::testTriangle2() + { + LOG(1, "+++++++ Testing triangle 2" ); + typedef TransformedTriangle TT; + + double coords[9] = + { + -0.5, 0.5, 0.25, // P + 1.5, 0.5,-0.25, // Q + -0.5,-1.5, 0.75 // R + }; + TransformedTriangle* tri = new TransformedTriangle(&coords[0], &coords[3], &coords[6]); + + // run all intersection tests and ensure that the ones + // listed with yes in the tables above return true and + // that the ones listed with no or not listed at all return false + + bool isZero[TT::NO_TRI_SEGMENT * TT::NO_DP]; + + for(TriSegment seg = TT::PQ ; seg < TT::NO_TRI_SEGMENT ; seg = TT::TriSegment(seg + 1)) + { + // check beforehand which double-products are zero + for(DoubleProduct dp = TT::C_YZ; dp < TT::NO_DP; dp = DoubleProduct(dp + 1)) + { + isZero[TT::NO_DP*int(seg) + int(dp)] = (tri->calcStableC(seg, dp) == 0.0); + } + } + + // corner in tetrahedron (3 possibilities) + CPPUNIT_ASSERT_EQUAL(false, tri->testCornerInTetrahedron(TT::P)); + CPPUNIT_ASSERT_EQUAL(false, tri->testCornerInTetrahedron(TT::Q)); + CPPUNIT_ASSERT_EQUAL(false, tri->testCornerInTetrahedron(TT::R)); + + // corner on XYZ facet (3 possibilities) + CPPUNIT_ASSERT_EQUAL(false, tri->testCornerOnXYZFacet(TT::P)); + CPPUNIT_ASSERT_EQUAL(false, tri->testCornerOnXYZFacet(TT::Q)); + CPPUNIT_ASSERT_EQUAL(false, tri->testCornerOnXYZFacet(TT::R)); + + // corner above XYZ facet (3 possibilities) + CPPUNIT_ASSERT_EQUAL(false, tri->testCornerAboveXYZFacet(TT::P)); + CPPUNIT_ASSERT_EQUAL(false, tri->testCornerAboveXYZFacet(TT::Q)); + CPPUNIT_ASSERT_EQUAL(false, tri->testCornerAboveXYZFacet(TT::R)); + + // segment-facet (9 possibilities) + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::PQ, TT::OZX)); + CPPUNIT_ASSERT_EQUAL(true , tri->testSegmentFacetIntersection(TT::PQ, TT::OYZ)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::PQ, TT::OXY)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::PQ, TT::XYZ)); + + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::QR, TT::OZX)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::QR, TT::OYZ)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::QR, TT::OXY)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::QR, TT::XYZ)); + + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::RP, TT::OZX)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::RP, TT::OYZ)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::RP, TT::OXY)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::RP, TT::XYZ)); + + // segment-edge (18 possibilities) + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::PQ, TT::OX) && tri->testSegmentEdgeIntersection(TT::PQ, TT::OX)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::PQ, TT::OY) && tri->testSegmentEdgeIntersection(TT::PQ, TT::OY)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::PQ, TT::OZ) && tri->testSegmentEdgeIntersection(TT::PQ, TT::OZ)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::PQ, TT::YZ) && tri->testSegmentEdgeIntersection(TT::PQ, TT::YZ)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::PQ, TT::ZX) && tri->testSegmentEdgeIntersection(TT::PQ, TT::ZX)); + CPPUNIT_ASSERT_EQUAL(true , TEST_ZERO_DP_EDGE(TT::PQ, TT::XY) && tri->testSegmentEdgeIntersection(TT::PQ, TT::XY)); + + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::QR, TT::OX) && tri->testSegmentEdgeIntersection(TT::QR, TT::OX)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::QR, TT::OY) && tri->testSegmentEdgeIntersection(TT::QR, TT::OY)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::QR, TT::OZ) && tri->testSegmentEdgeIntersection(TT::QR, TT::OZ)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::QR, TT::YZ) && tri->testSegmentEdgeIntersection(TT::QR, TT::YZ)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::QR, TT::ZX) && tri->testSegmentEdgeIntersection(TT::QR, TT::ZX)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::QR, TT::XY) && tri->testSegmentEdgeIntersection(TT::QR, TT::XY)); + + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::RP, TT::OX) && tri->testSegmentEdgeIntersection(TT::RP, TT::OX)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::RP, TT::OY) && tri->testSegmentEdgeIntersection(TT::RP, TT::OY)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::RP, TT::OZ) && tri->testSegmentEdgeIntersection(TT::RP, TT::OZ)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::RP, TT::YZ) && tri->testSegmentEdgeIntersection(TT::RP, TT::YZ)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::RP, TT::ZX) && tri->testSegmentEdgeIntersection(TT::RP, TT::ZX)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::RP, TT::XY) && tri->testSegmentEdgeIntersection(TT::RP, TT::XY)); + + // segment - corner (12 possibilities) + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::PQ, TT::O) && tri->testSegmentCornerIntersection(TT::PQ, TT::O)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::PQ, TT::X) && tri->testSegmentCornerIntersection(TT::PQ, TT::X)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::PQ, TT::Y) && tri->testSegmentCornerIntersection(TT::PQ, TT::Y)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::PQ, TT::Z) && tri->testSegmentCornerIntersection(TT::PQ, TT::Z)); + + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::QR, TT::O) && tri->testSegmentCornerIntersection(TT::QR, TT::O)); + CPPUNIT_ASSERT_EQUAL(true , TEST_ZERO_DP_CORNER(TT::QR, TT::X) && tri->testSegmentCornerIntersection(TT::QR, TT::X)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::QR, TT::Y) && tri->testSegmentCornerIntersection(TT::QR, TT::Y)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::QR, TT::Z) && tri->testSegmentCornerIntersection(TT::QR, TT::Z)); + + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::RP, TT::O) && tri->testSegmentCornerIntersection(TT::RP, TT::O)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::RP, TT::X) && tri->testSegmentCornerIntersection(TT::RP, TT::X)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::RP, TT::Y) && tri->testSegmentCornerIntersection(TT::RP, TT::Y)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::RP, TT::Z) && tri->testSegmentCornerIntersection(TT::RP, TT::Z)); + + // segment-halfstrip (9 possibilities) + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentHalfstripIntersection(TT::PQ, TT::YZ)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentHalfstripIntersection(TT::PQ, TT::ZX)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentHalfstripIntersection(TT::PQ, TT::XY)); + + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentHalfstripIntersection(TT::QR, TT::YZ)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentHalfstripIntersection(TT::QR, TT::ZX)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentHalfstripIntersection(TT::QR, TT::XY)); + + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentHalfstripIntersection(TT::RP, TT::YZ)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentHalfstripIntersection(TT::RP, TT::ZX)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentHalfstripIntersection(TT::RP, TT::XY)); + + // segment-ray (9 possibilities) + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_RAY(TT::PQ, TT::X) && tri->testSegmentRayIntersection(TT::PQ, TT::X)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_RAY(TT::PQ, TT::Y) && tri->testSegmentRayIntersection(TT::PQ, TT::Y)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_RAY(TT::PQ, TT::Z) && tri->testSegmentRayIntersection(TT::PQ, TT::Z)); + + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_RAY(TT::QR, TT::X) && tri->testSegmentRayIntersection(TT::QR, TT::X)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_RAY(TT::QR, TT::Y) && tri->testSegmentRayIntersection(TT::QR, TT::Y)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_RAY(TT::QR, TT::Z) && tri->testSegmentRayIntersection(TT::QR, TT::Z)); + + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_RAY(TT::RP, TT::X) && tri->testSegmentRayIntersection(TT::RP, TT::X)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_RAY(TT::RP, TT::Y) && tri->testSegmentRayIntersection(TT::RP, TT::Y)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_RAY(TT::RP, TT::Z) && tri->testSegmentRayIntersection(TT::RP, TT::Z)); + + // surface-edge (6 possibilities) + CPPUNIT_ASSERT_EQUAL(true , tri->testSurfaceEdgeIntersection(TT::OX)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSurfaceEdgeIntersection(TT::OY)); + CPPUNIT_ASSERT_EQUAL(true , tri->testSurfaceEdgeIntersection(TT::OZ)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSurfaceEdgeIntersection(TT::YZ)); + CPPUNIT_ASSERT_EQUAL(true , tri->testSurfaceEdgeIntersection(TT::ZX)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSurfaceEdgeIntersection(TT::XY)); + + // surface-ray (3 possibilities) + CPPUNIT_ASSERT_EQUAL(false, tri->testSurfaceRayIntersection(TT::X)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSurfaceRayIntersection(TT::Y)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSurfaceRayIntersection(TT::Z)); + + delete tri; + } + + /// Triangle 3 has the following intersections + /// <PRE> + /// CI P + /// COH - + /// CAH - + /// SF (PQ, XYZ), (RP, OYZ) + /// SE - + /// SC - + /// SHS (PQ, XY), (QR, YZ), (QR, XY) + /// SR - + /// TE YZ + /// TR - + /// </PRE> + /// \brief Status : pass + void TransformedTriangleIntersectTest::testTriangle3() + { + LOG(1, "+++++++ Testing triangle 3" ); + typedef TransformedTriangle TT; + + double coords[9] = + { + 0.35, 0.15, 0.1, // P + 0.8, 0.8, 0.8, // Q + -0.4, 0.3, 0.9 // R + }; + + TransformedTriangle* tri = new TransformedTriangle(&coords[0], &coords[3], &coords[6]); + + // run all intersection tests and ensure that the ones + // listed with yes in the tables above return true and + // that the ones listed with no or not listed at all return false + + bool isZero[TT::NO_TRI_SEGMENT * TT::NO_DP]; + + for(TriSegment seg = TT::PQ ; seg < TT::NO_TRI_SEGMENT ; seg = TT::TriSegment(seg + 1)) + { + // check beforehand which double-products are zero + for(DoubleProduct dp = TT::C_YZ; dp < TT::NO_DP; dp = DoubleProduct(dp + 1)) + { + isZero[TT::NO_DP*int(seg) + int(dp)] = (tri->calcStableC(seg, dp) == 0.0); + } + } + + // corner in tetrahedron (3 possibilities) + CPPUNIT_ASSERT_EQUAL(true , tri->testCornerInTetrahedron(TT::P)); + CPPUNIT_ASSERT_EQUAL(false, tri->testCornerInTetrahedron(TT::Q)); + CPPUNIT_ASSERT_EQUAL(false, tri->testCornerInTetrahedron(TT::R)); + + // corner on XYZ facet (3 possibilities) + CPPUNIT_ASSERT_EQUAL(false, tri->testCornerOnXYZFacet(TT::P)); + CPPUNIT_ASSERT_EQUAL(false, tri->testCornerOnXYZFacet(TT::Q)); + CPPUNIT_ASSERT_EQUAL(false, tri->testCornerOnXYZFacet(TT::R)); + + // corner above XYZ facet (3 possibilities) + CPPUNIT_ASSERT_EQUAL(false, tri->testCornerAboveXYZFacet(TT::P)); + CPPUNIT_ASSERT_EQUAL(false, tri->testCornerAboveXYZFacet(TT::Q)); + CPPUNIT_ASSERT_EQUAL(false, tri->testCornerAboveXYZFacet(TT::R)); + + // segment-facet (9 possibilities) + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::PQ, TT::OZX)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::PQ, TT::OYZ)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::PQ, TT::OXY)); + CPPUNIT_ASSERT_EQUAL(true , tri->testSegmentFacetIntersection(TT::PQ, TT::XYZ)); + + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::QR, TT::OZX)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::QR, TT::OYZ)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::QR, TT::OXY)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::QR, TT::XYZ)); + + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::RP, TT::OZX)); + CPPUNIT_ASSERT_EQUAL(true , tri->testSegmentFacetIntersection(TT::RP, TT::OYZ)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::RP, TT::OXY)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::RP, TT::XYZ)); + + // segment-edge (18 possibilities) + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::PQ, TT::OX) && tri->testSegmentEdgeIntersection(TT::PQ, TT::OX)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::PQ, TT::OY) && tri->testSegmentEdgeIntersection(TT::PQ, TT::OY)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::PQ, TT::OZ) && tri->testSegmentEdgeIntersection(TT::PQ, TT::OZ)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::PQ, TT::YZ) && tri->testSegmentEdgeIntersection(TT::PQ, TT::YZ)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::PQ, TT::ZX) && tri->testSegmentEdgeIntersection(TT::PQ, TT::ZX)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::PQ, TT::XY) && tri->testSegmentEdgeIntersection(TT::PQ, TT::XY)); + + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::QR, TT::OX) && tri->testSegmentEdgeIntersection(TT::QR, TT::OX)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::QR, TT::OY) && tri->testSegmentEdgeIntersection(TT::QR, TT::OY)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::QR, TT::OZ) && tri->testSegmentEdgeIntersection(TT::QR, TT::OZ)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::QR, TT::YZ) && tri->testSegmentEdgeIntersection(TT::QR, TT::YZ)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::QR, TT::ZX) && tri->testSegmentEdgeIntersection(TT::QR, TT::ZX)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::QR, TT::XY) && tri->testSegmentEdgeIntersection(TT::QR, TT::XY)); + + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::RP, TT::OX) && tri->testSegmentEdgeIntersection(TT::RP, TT::OX)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::RP, TT::OY) && tri->testSegmentEdgeIntersection(TT::RP, TT::OY)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::RP, TT::OZ) && tri->testSegmentEdgeIntersection(TT::RP, TT::OZ)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::RP, TT::YZ) && tri->testSegmentEdgeIntersection(TT::RP, TT::YZ)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::RP, TT::ZX) && tri->testSegmentEdgeIntersection(TT::RP, TT::ZX)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::RP, TT::XY) && tri->testSegmentEdgeIntersection(TT::RP, TT::XY)); + + // segment - corner (12 possibilities) + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::PQ, TT::O) && tri->testSegmentCornerIntersection(TT::PQ, TT::O)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::PQ, TT::X) && tri->testSegmentCornerIntersection(TT::PQ, TT::X)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::PQ, TT::Y) && tri->testSegmentCornerIntersection(TT::PQ, TT::Y)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::PQ, TT::Z) && tri->testSegmentCornerIntersection(TT::PQ, TT::Z)); + + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::QR, TT::O) && tri->testSegmentCornerIntersection(TT::QR, TT::O)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::QR, TT::X) && tri->testSegmentCornerIntersection(TT::QR, TT::X)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::QR, TT::Y) && tri->testSegmentCornerIntersection(TT::QR, TT::Y)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::QR, TT::Z) && tri->testSegmentCornerIntersection(TT::QR, TT::Z)); + + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::RP, TT::O) && tri->testSegmentCornerIntersection(TT::RP, TT::O)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::RP, TT::X) && tri->testSegmentCornerIntersection(TT::RP, TT::X)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::RP, TT::Y) && tri->testSegmentCornerIntersection(TT::RP, TT::Y)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::RP, TT::Z) && tri->testSegmentCornerIntersection(TT::RP, TT::Z)); + + // segment-halfstrip (9 possibilities) + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentHalfstripIntersection(TT::PQ, TT::YZ)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentHalfstripIntersection(TT::PQ, TT::ZX)); + CPPUNIT_ASSERT_EQUAL(true , tri->testSegmentHalfstripIntersection(TT::PQ, TT::XY)); + + CPPUNIT_ASSERT_EQUAL(true , tri->testSegmentHalfstripIntersection(TT::QR, TT::YZ)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentHalfstripIntersection(TT::QR, TT::ZX)); + CPPUNIT_ASSERT_EQUAL(true , tri->testSegmentHalfstripIntersection(TT::QR, TT::XY)); + + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentHalfstripIntersection(TT::RP, TT::YZ)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentHalfstripIntersection(TT::RP, TT::ZX)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentHalfstripIntersection(TT::RP, TT::XY)); + + // segment-ray (9 possibilities) + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_RAY(TT::PQ, TT::X) && tri->testSegmentRayIntersection(TT::PQ, TT::X)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_RAY(TT::PQ, TT::Y) && tri->testSegmentRayIntersection(TT::PQ, TT::Y)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_RAY(TT::PQ, TT::Z) && tri->testSegmentRayIntersection(TT::PQ, TT::Z)); + + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_RAY(TT::QR, TT::X) && tri->testSegmentRayIntersection(TT::QR, TT::X)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_RAY(TT::QR, TT::Y) && tri->testSegmentRayIntersection(TT::QR, TT::Y)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_RAY(TT::QR, TT::Z) && tri->testSegmentRayIntersection(TT::QR, TT::Z)); + + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_RAY(TT::RP, TT::X) && tri->testSegmentRayIntersection(TT::RP, TT::X)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_RAY(TT::RP, TT::Y) && tri->testSegmentRayIntersection(TT::RP, TT::Y)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_RAY(TT::RP, TT::Z) && tri->testSegmentRayIntersection(TT::RP, TT::Z)); + + // surface-edge (6 possibilities) + CPPUNIT_ASSERT_EQUAL(false, tri->testSurfaceEdgeIntersection(TT::OX)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSurfaceEdgeIntersection(TT::OY)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSurfaceEdgeIntersection(TT::OZ)); + CPPUNIT_ASSERT_EQUAL(true , tri->testSurfaceEdgeIntersection(TT::YZ)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSurfaceEdgeIntersection(TT::ZX)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSurfaceEdgeIntersection(TT::XY)); + + // surface-ray (3 possibilities) + CPPUNIT_ASSERT_EQUAL(false, tri->testSurfaceRayIntersection(TT::X)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSurfaceRayIntersection(TT::Y)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSurfaceRayIntersection(TT::Z)); + + delete tri; + } + + /// Triangle 4 has the following intersections + /// <PRE> + /// CI Q + /// COH - + /// CAH P + /// SF (PQ, XYZ), (QR, OXY) + /// SE - + /// SC - + /// SHS (RP, ZX) + /// SR - + /// TE (OX, ZX) + /// TR - + /// </PRE> + /// \brief Status : pass + void TransformedTriangleIntersectTest::testTriangle4() + { + LOG(1, "+++++++ Testing triangle 4" ); + typedef TransformedTriangle TT; + + double coords[9] = + { + 0.3, 0.3, 1.8, // P + 0.75, 0.1, 0.1, // Q + 0.2, -1.3, -1.4 // R + }; + + TransformedTriangle* tri = new TransformedTriangle(&coords[0], &coords[3], &coords[6]); + + // run all intersection tests and ensure that the ones + // listed with yes in the tables above return true and + // that the ones listed with no or not listed at all return false + + bool isZero[TT::NO_TRI_SEGMENT * TT::NO_DP]; + + for(TriSegment seg = TT::PQ ; seg < TT::NO_TRI_SEGMENT ; seg = TT::TriSegment(seg + 1)) + { + // check beforehand which double-products are zero + for(DoubleProduct dp = TT::C_YZ; dp < TT::NO_DP; dp = DoubleProduct(dp + 1)) + { + isZero[TT::NO_DP*int(seg) + int(dp)] = (tri->calcStableC(seg, dp) == 0.0); + } + } + + // corner in tetrahedron (3 possibilities) + CPPUNIT_ASSERT_EQUAL(false, tri->testCornerInTetrahedron(TT::P)); + CPPUNIT_ASSERT_EQUAL(true , tri->testCornerInTetrahedron(TT::Q)); + CPPUNIT_ASSERT_EQUAL(false, tri->testCornerInTetrahedron(TT::R)); + + // corner on XYZ facet (3 possibilities) + CPPUNIT_ASSERT_EQUAL(false, tri->testCornerOnXYZFacet(TT::P)); + CPPUNIT_ASSERT_EQUAL(false, tri->testCornerOnXYZFacet(TT::Q)); + CPPUNIT_ASSERT_EQUAL(false, tri->testCornerOnXYZFacet(TT::R)); + + // corner above XYZ facet (3 possibilities) + CPPUNIT_ASSERT_EQUAL(true , tri->testCornerAboveXYZFacet(TT::P)); + CPPUNIT_ASSERT_EQUAL(false, tri->testCornerAboveXYZFacet(TT::Q)); + CPPUNIT_ASSERT_EQUAL(false, tri->testCornerAboveXYZFacet(TT::R)); + + // segment-facet (9 possibilities) + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::PQ, TT::OZX)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::PQ, TT::OYZ)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::PQ, TT::OXY)); + CPPUNIT_ASSERT_EQUAL(true , tri->testSegmentFacetIntersection(TT::PQ, TT::XYZ)); + + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::QR, TT::OZX)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::QR, TT::OYZ)); + CPPUNIT_ASSERT_EQUAL(true , tri->testSegmentFacetIntersection(TT::QR, TT::OXY)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::QR, TT::XYZ)); + + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::RP, TT::OZX)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::RP, TT::OYZ)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::RP, TT::OXY)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::RP, TT::XYZ)); + + // segment-edge (18 possibilities) + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::PQ, TT::OX) && tri->testSegmentEdgeIntersection(TT::PQ, TT::OX)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::PQ, TT::OY) && tri->testSegmentEdgeIntersection(TT::PQ, TT::OY)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::PQ, TT::OZ) && tri->testSegmentEdgeIntersection(TT::PQ, TT::OZ)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::PQ, TT::YZ) && tri->testSegmentEdgeIntersection(TT::PQ, TT::YZ)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::PQ, TT::ZX) && tri->testSegmentEdgeIntersection(TT::PQ, TT::ZX)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::PQ, TT::XY) && tri->testSegmentEdgeIntersection(TT::PQ, TT::XY)); + + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::QR, TT::OX) && tri->testSegmentEdgeIntersection(TT::QR, TT::OX)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::QR, TT::OY) && tri->testSegmentEdgeIntersection(TT::QR, TT::OY)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::QR, TT::OZ) && tri->testSegmentEdgeIntersection(TT::QR, TT::OZ)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::QR, TT::YZ) && tri->testSegmentEdgeIntersection(TT::QR, TT::YZ)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::QR, TT::ZX) && tri->testSegmentEdgeIntersection(TT::QR, TT::ZX)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::QR, TT::XY) && tri->testSegmentEdgeIntersection(TT::QR, TT::XY)); + + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::RP, TT::OX) && tri->testSegmentEdgeIntersection(TT::RP, TT::OX)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::RP, TT::OY) && tri->testSegmentEdgeIntersection(TT::RP, TT::OY)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::RP, TT::OZ) && tri->testSegmentEdgeIntersection(TT::RP, TT::OZ)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::RP, TT::YZ) && tri->testSegmentEdgeIntersection(TT::RP, TT::YZ)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::RP, TT::ZX) && tri->testSegmentEdgeIntersection(TT::RP, TT::ZX)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::RP, TT::XY) && tri->testSegmentEdgeIntersection(TT::RP, TT::XY)); + + // segment - corner (12 possibilities) + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::PQ, TT::O) && tri->testSegmentCornerIntersection(TT::PQ, TT::O)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::PQ, TT::X) && tri->testSegmentCornerIntersection(TT::PQ, TT::X)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::PQ, TT::Y) && tri->testSegmentCornerIntersection(TT::PQ, TT::Y)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::PQ, TT::Z) && tri->testSegmentCornerIntersection(TT::PQ, TT::Z)); + + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::QR, TT::O) && tri->testSegmentCornerIntersection(TT::QR, TT::O)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::QR, TT::X) && tri->testSegmentCornerIntersection(TT::QR, TT::X)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::QR, TT::Y) && tri->testSegmentCornerIntersection(TT::QR, TT::Y)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::QR, TT::Z) && tri->testSegmentCornerIntersection(TT::QR, TT::Z)); + + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::RP, TT::O) && tri->testSegmentCornerIntersection(TT::RP, TT::O)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::RP, TT::X) && tri->testSegmentCornerIntersection(TT::RP, TT::X)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::RP, TT::Y) && tri->testSegmentCornerIntersection(TT::RP, TT::Y)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::RP, TT::Z) && tri->testSegmentCornerIntersection(TT::RP, TT::Z)); + + + // segment-halfstrip (9 possibilities) + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentHalfstripIntersection(TT::PQ, TT::YZ)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentHalfstripIntersection(TT::PQ, TT::ZX)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentHalfstripIntersection(TT::PQ, TT::XY)); + + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentHalfstripIntersection(TT::QR, TT::YZ)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentHalfstripIntersection(TT::QR, TT::ZX)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentHalfstripIntersection(TT::QR, TT::XY)); + + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentHalfstripIntersection(TT::RP, TT::YZ)); + CPPUNIT_ASSERT_EQUAL(true , tri->testSegmentHalfstripIntersection(TT::RP, TT::ZX)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentHalfstripIntersection(TT::RP, TT::XY)); + + // segment-ray (9 possibilities) + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_RAY(TT::PQ, TT::X) && tri->testSegmentRayIntersection(TT::PQ, TT::X)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_RAY(TT::PQ, TT::Y) && tri->testSegmentRayIntersection(TT::PQ, TT::Y)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_RAY(TT::PQ, TT::Z) && tri->testSegmentRayIntersection(TT::PQ, TT::Z)); + + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_RAY(TT::QR, TT::X) && tri->testSegmentRayIntersection(TT::QR, TT::X)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_RAY(TT::QR, TT::Y) && tri->testSegmentRayIntersection(TT::QR, TT::Y)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_RAY(TT::QR, TT::Z) && tri->testSegmentRayIntersection(TT::QR, TT::Z)); + + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_RAY(TT::RP, TT::X) && tri->testSegmentRayIntersection(TT::RP, TT::X)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_RAY(TT::RP, TT::Y) && tri->testSegmentRayIntersection(TT::RP, TT::Y)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_RAY(TT::RP, TT::Z) && tri->testSegmentRayIntersection(TT::RP, TT::Z)); + + // surface-edge (6 possibilities) + CPPUNIT_ASSERT_EQUAL(true , tri->testSurfaceEdgeIntersection(TT::OX)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSurfaceEdgeIntersection(TT::OY)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSurfaceEdgeIntersection(TT::OZ)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSurfaceEdgeIntersection(TT::YZ)); + CPPUNIT_ASSERT_EQUAL(true , tri->testSurfaceEdgeIntersection(TT::ZX)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSurfaceEdgeIntersection(TT::XY)); + + // surface-ray (3 possibilities) + CPPUNIT_ASSERT_EQUAL(false, tri->testSurfaceRayIntersection(TT::X)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSurfaceRayIntersection(TT::Y)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSurfaceRayIntersection(TT::Z)); + + delete tri; + } + + /// Triangle 5 has the following intersections + /// <PRE> + /// CI - + /// COH - + /// CAH - + /// SF - + /// SE - + /// SC - + /// SHS (QR, ZX), (QR, XY) + /// SR (PQ, Y) + /// TE - + /// TR Z + /// </PRE> + /// \brief Status : pass + void TransformedTriangleIntersectTest::testTriangle5() + { + LOG(1, "+++++++ Testing triangle 5" ); + + typedef TransformedTriangle TT; + + double coords[9] = + { + -0.5, 0.5, 2.3, // P + 0.5, 1.5, 2.8, // Q + 0.5, -2.6, 1.3 // R + }; + + TransformedTriangle* tri = new TransformedTriangle(&coords[0], &coords[3], &coords[6]); + + // run all intersection tests and ensure that the ones + // listed with yes in the tables above return true and + // that the ones listed with no or not listed at all return false + + bool isZero[TT::NO_TRI_SEGMENT * TT::NO_DP]; + + for(TriSegment seg = TT::PQ ; seg < TT::NO_TRI_SEGMENT ; seg = TT::TriSegment(seg + 1)) + { + // check beforehand which double-products are zero + for(DoubleProduct dp = TT::C_YZ; dp < TT::NO_DP; dp = DoubleProduct(dp + 1)) + { + isZero[TT::NO_DP*int(seg) + int(dp)] = (tri->calcStableC(seg, dp) == 0.0); + } + } + + // corner in tetrahedron (3 possibilities) + CPPUNIT_ASSERT_EQUAL(false, tri->testCornerInTetrahedron(TT::P)); + CPPUNIT_ASSERT_EQUAL(false, tri->testCornerInTetrahedron(TT::Q)); + CPPUNIT_ASSERT_EQUAL(false, tri->testCornerInTetrahedron(TT::R)); + + // corner on XYZ facet (3 possibilities) + CPPUNIT_ASSERT_EQUAL(false, tri->testCornerOnXYZFacet(TT::P)); + CPPUNIT_ASSERT_EQUAL(false, tri->testCornerOnXYZFacet(TT::Q)); + CPPUNIT_ASSERT_EQUAL(false, tri->testCornerOnXYZFacet(TT::R)); + + // corner above XYZ facet (3 possibilities) + CPPUNIT_ASSERT_EQUAL(false, tri->testCornerAboveXYZFacet(TT::P)); + CPPUNIT_ASSERT_EQUAL(false, tri->testCornerAboveXYZFacet(TT::Q)); + CPPUNIT_ASSERT_EQUAL(false, tri->testCornerAboveXYZFacet(TT::R)); + + // segment-facet (9 possibilities) + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::PQ, TT::OZX)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::PQ, TT::OYZ)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::PQ, TT::OXY)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::PQ, TT::XYZ)); + + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::QR, TT::OZX)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::QR, TT::OYZ)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::QR, TT::OXY)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::QR, TT::XYZ)); + + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::RP, TT::OZX)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::RP, TT::OYZ)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::RP, TT::OXY)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::RP, TT::XYZ)); + + // segment-edge (18 possibilities) + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::PQ, TT::OX) && tri->testSegmentEdgeIntersection(TT::PQ, TT::OX)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::PQ, TT::OY) && tri->testSegmentEdgeIntersection(TT::PQ, TT::OY)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::PQ, TT::OZ) && tri->testSegmentEdgeIntersection(TT::PQ, TT::OZ)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::PQ, TT::YZ) && tri->testSegmentEdgeIntersection(TT::PQ, TT::YZ)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::PQ, TT::ZX) && tri->testSegmentEdgeIntersection(TT::PQ, TT::ZX)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::PQ, TT::XY) && tri->testSegmentEdgeIntersection(TT::PQ, TT::XY)); + + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::QR, TT::OX) && tri->testSegmentEdgeIntersection(TT::QR, TT::OX)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::QR, TT::OY) && tri->testSegmentEdgeIntersection(TT::QR, TT::OY)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::QR, TT::OZ) && tri->testSegmentEdgeIntersection(TT::QR, TT::OZ)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::QR, TT::YZ) && tri->testSegmentEdgeIntersection(TT::QR, TT::YZ)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::QR, TT::ZX) && tri->testSegmentEdgeIntersection(TT::QR, TT::ZX)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::QR, TT::XY) && tri->testSegmentEdgeIntersection(TT::QR, TT::XY)); + + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::RP, TT::OX) && tri->testSegmentEdgeIntersection(TT::RP, TT::OX)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::RP, TT::OY) && tri->testSegmentEdgeIntersection(TT::RP, TT::OY)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::RP, TT::OZ) && tri->testSegmentEdgeIntersection(TT::RP, TT::OZ)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::RP, TT::YZ) && tri->testSegmentEdgeIntersection(TT::RP, TT::YZ)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::RP, TT::ZX) && tri->testSegmentEdgeIntersection(TT::RP, TT::ZX)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::RP, TT::XY) && tri->testSegmentEdgeIntersection(TT::RP, TT::XY)); + + // segment - corner (12 possibilities) + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::PQ, TT::O) && tri->testSegmentCornerIntersection(TT::PQ, TT::O)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::PQ, TT::X) && tri->testSegmentCornerIntersection(TT::PQ, TT::X)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::PQ, TT::Y) && tri->testSegmentCornerIntersection(TT::PQ, TT::Y)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::PQ, TT::Z) && tri->testSegmentCornerIntersection(TT::PQ, TT::Z)); + + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::QR, TT::O) && tri->testSegmentCornerIntersection(TT::QR, TT::O)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::QR, TT::X) && tri->testSegmentCornerIntersection(TT::QR, TT::X)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::QR, TT::Y) && tri->testSegmentCornerIntersection(TT::QR, TT::Y)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::QR, TT::Z) && tri->testSegmentCornerIntersection(TT::QR, TT::Z)); + + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::RP, TT::O) && tri->testSegmentCornerIntersection(TT::RP, TT::O)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::RP, TT::X) && tri->testSegmentCornerIntersection(TT::RP, TT::X)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::RP, TT::Y) && tri->testSegmentCornerIntersection(TT::RP, TT::Y)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::RP, TT::Z) && tri->testSegmentCornerIntersection(TT::RP, TT::Z)); + + // segment-halfstrip (9 possibilities) + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentHalfstripIntersection(TT::PQ, TT::YZ)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentHalfstripIntersection(TT::PQ, TT::ZX)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentHalfstripIntersection(TT::PQ, TT::XY)); + + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentHalfstripIntersection(TT::QR, TT::YZ)); + CPPUNIT_ASSERT_EQUAL(true , tri->testSegmentHalfstripIntersection(TT::QR, TT::ZX)); + CPPUNIT_ASSERT_EQUAL(true , tri->testSegmentHalfstripIntersection(TT::QR, TT::XY)); + + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentHalfstripIntersection(TT::RP, TT::YZ)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentHalfstripIntersection(TT::RP, TT::ZX)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentHalfstripIntersection(TT::RP, TT::XY)); + + // segment-ray (9 possibilities) + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_RAY(TT::PQ, TT::X) && tri->testSegmentRayIntersection(TT::PQ, TT::X)); + CPPUNIT_ASSERT_EQUAL(true , TEST_ZERO_DP_RAY(TT::PQ, TT::Y) && tri->testSegmentRayIntersection(TT::PQ, TT::Y)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_RAY(TT::PQ, TT::Z) && tri->testSegmentRayIntersection(TT::PQ, TT::Z)); + + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_RAY(TT::QR, TT::X) && tri->testSegmentRayIntersection(TT::QR, TT::X)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_RAY(TT::QR, TT::Y) && tri->testSegmentRayIntersection(TT::QR, TT::Y)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_RAY(TT::QR, TT::Z) && tri->testSegmentRayIntersection(TT::QR, TT::Z)); + + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_RAY(TT::RP, TT::X) && tri->testSegmentRayIntersection(TT::RP, TT::X)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_RAY(TT::RP, TT::Y) && tri->testSegmentRayIntersection(TT::RP, TT::Y)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_RAY(TT::RP, TT::Z) && tri->testSegmentRayIntersection(TT::RP, TT::Z)); + + // surface-edge (6 possibilities) + CPPUNIT_ASSERT_EQUAL(false, tri->testSurfaceEdgeIntersection(TT::OX)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSurfaceEdgeIntersection(TT::OY)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSurfaceEdgeIntersection(TT::OZ)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSurfaceEdgeIntersection(TT::YZ)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSurfaceEdgeIntersection(TT::ZX)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSurfaceEdgeIntersection(TT::XY)); + + // surface-ray (3 possibilities) + CPPUNIT_ASSERT_EQUAL(false, tri->testSurfaceRayIntersection(TT::X)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSurfaceRayIntersection(TT::Y)); + CPPUNIT_ASSERT_EQUAL(true , tri->testSurfaceRayIntersection(TT::Z)); + + delete tri; + } + + /// Triangle 6 has the following intersections + /// <PRE> + /// CI - + /// COH - + /// CAH - + /// SF - + /// SE - + /// SC - + /// SHS - + /// SR (PQ, X), (QR, Z) + /// TE - + /// TR Y + /// </PRE> + /// \brief Status : pass + void TransformedTriangleIntersectTest::testTriangle6() + { + LOG(1, "+++++++ Testing triangle 6" ); + + typedef TransformedTriangle TT; + + double coords[9] = + { + 1.5, 0.5, 1.35, // P + 0.5, -0.5, 2.1, // Q + -3.0, 3.0, -0.5 // R + }; + + TransformedTriangle* tri = new TransformedTriangle(&coords[0], &coords[3], &coords[6]); + + // run all intersection tests and ensure that the ones + // listed with yes in the tables above return true and + // that the ones listed with no or not listed at all return false + + bool isZero[TT::NO_TRI_SEGMENT * TT::NO_DP]; + + for(TriSegment seg = TT::PQ ; seg < TT::NO_TRI_SEGMENT ; seg = TT::TriSegment(seg + 1)) + { + // check beforehand which double-products are zero + for(DoubleProduct dp = TT::C_YZ; dp < TT::NO_DP; dp = DoubleProduct(dp + 1)) + { + isZero[TT::NO_DP*int(seg) + int(dp)] = (tri->calcStableC(seg, dp) == 0.0); + } + } + + // corner in tetrahedron (3 possibilities) + CPPUNIT_ASSERT_EQUAL(false, tri->testCornerInTetrahedron(TT::P)); + CPPUNIT_ASSERT_EQUAL(false, tri->testCornerInTetrahedron(TT::Q)); + CPPUNIT_ASSERT_EQUAL(false, tri->testCornerInTetrahedron(TT::R)); + + // corner on XYZ facet (3 possibilities) + CPPUNIT_ASSERT_EQUAL(false, tri->testCornerOnXYZFacet(TT::P)); + CPPUNIT_ASSERT_EQUAL(false, tri->testCornerOnXYZFacet(TT::Q)); + CPPUNIT_ASSERT_EQUAL(false, tri->testCornerOnXYZFacet(TT::R)); + + // corner above XYZ facet (3 possibilities) + CPPUNIT_ASSERT_EQUAL(false, tri->testCornerAboveXYZFacet(TT::P)); + CPPUNIT_ASSERT_EQUAL(false, tri->testCornerAboveXYZFacet(TT::Q)); + CPPUNIT_ASSERT_EQUAL(false, tri->testCornerAboveXYZFacet(TT::R)); + + // segment-facet (9 possibilities) + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::PQ, TT::OZX)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::PQ, TT::OYZ)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::PQ, TT::OXY)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::PQ, TT::XYZ)); + + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::QR, TT::OZX)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::QR, TT::OYZ)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::QR, TT::OXY)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::QR, TT::XYZ)); + + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::RP, TT::OZX)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::RP, TT::OYZ)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::RP, TT::OXY)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::RP, TT::XYZ)); + + // segment-edge (18 possibilities) + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::PQ, TT::OX) && tri->testSegmentEdgeIntersection(TT::PQ, TT::OX)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::PQ, TT::OY) && tri->testSegmentEdgeIntersection(TT::PQ, TT::OY)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::PQ, TT::OZ) && tri->testSegmentEdgeIntersection(TT::PQ, TT::OZ)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::PQ, TT::YZ) && tri->testSegmentEdgeIntersection(TT::PQ, TT::YZ)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::PQ, TT::ZX) && tri->testSegmentEdgeIntersection(TT::PQ, TT::ZX)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::PQ, TT::XY) && tri->testSegmentEdgeIntersection(TT::PQ, TT::XY)); + + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::QR, TT::OX) && tri->testSegmentEdgeIntersection(TT::QR, TT::OX)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::QR, TT::OY) && tri->testSegmentEdgeIntersection(TT::QR, TT::OY)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::QR, TT::OZ) && tri->testSegmentEdgeIntersection(TT::QR, TT::OZ)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::QR, TT::YZ) && tri->testSegmentEdgeIntersection(TT::QR, TT::YZ)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::QR, TT::ZX) && tri->testSegmentEdgeIntersection(TT::QR, TT::ZX)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::QR, TT::XY) && tri->testSegmentEdgeIntersection(TT::QR, TT::XY)); + + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::RP, TT::OX) && tri->testSegmentEdgeIntersection(TT::RP, TT::OX)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::RP, TT::OY) && tri->testSegmentEdgeIntersection(TT::RP, TT::OY)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::RP, TT::OZ) && tri->testSegmentEdgeIntersection(TT::RP, TT::OZ)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::RP, TT::YZ) && tri->testSegmentEdgeIntersection(TT::RP, TT::YZ)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::RP, TT::ZX) && tri->testSegmentEdgeIntersection(TT::RP, TT::ZX)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::RP, TT::XY) && tri->testSegmentEdgeIntersection(TT::RP, TT::XY)); + + // segment - corner (12 possibilities) + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::PQ, TT::O) && tri->testSegmentCornerIntersection(TT::PQ, TT::O)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::PQ, TT::X) && tri->testSegmentCornerIntersection(TT::PQ, TT::X)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::PQ, TT::Y) && tri->testSegmentCornerIntersection(TT::PQ, TT::Y)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::PQ, TT::Z) && tri->testSegmentCornerIntersection(TT::PQ, TT::Z)); + + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::QR, TT::O) && tri->testSegmentCornerIntersection(TT::QR, TT::O)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::QR, TT::X) && tri->testSegmentCornerIntersection(TT::QR, TT::X)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::QR, TT::Y) && tri->testSegmentCornerIntersection(TT::QR, TT::Y)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::QR, TT::Z) && tri->testSegmentCornerIntersection(TT::QR, TT::Z)); + + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::RP, TT::O) && tri->testSegmentCornerIntersection(TT::RP, TT::O)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::RP, TT::X) && tri->testSegmentCornerIntersection(TT::RP, TT::X)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::RP, TT::Y) && tri->testSegmentCornerIntersection(TT::RP, TT::Y)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::RP, TT::Z) && tri->testSegmentCornerIntersection(TT::RP, TT::Z)); + + // segment-halfstrip (9 possibilities) + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentHalfstripIntersection(TT::PQ, TT::YZ)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentHalfstripIntersection(TT::PQ, TT::ZX)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentHalfstripIntersection(TT::PQ, TT::XY)); + + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentHalfstripIntersection(TT::QR, TT::YZ)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentHalfstripIntersection(TT::QR, TT::ZX)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentHalfstripIntersection(TT::QR, TT::XY)); + + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentHalfstripIntersection(TT::RP, TT::YZ)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentHalfstripIntersection(TT::RP, TT::ZX)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentHalfstripIntersection(TT::RP, TT::XY)); + + // segment-ray (9 possibilities) + CPPUNIT_ASSERT_EQUAL(true , TEST_ZERO_DP_RAY(TT::PQ, TT::X) && tri->testSegmentRayIntersection(TT::PQ, TT::X)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_RAY(TT::PQ, TT::Y) && tri->testSegmentRayIntersection(TT::PQ, TT::Y)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_RAY(TT::PQ, TT::Z) && tri->testSegmentRayIntersection(TT::PQ, TT::Z)); + + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_RAY(TT::QR, TT::X) && tri->testSegmentRayIntersection(TT::QR, TT::X)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_RAY(TT::QR, TT::Y) && tri->testSegmentRayIntersection(TT::QR, TT::Y)); + CPPUNIT_ASSERT_EQUAL(true , TEST_ZERO_DP_RAY(TT::QR, TT::Z) && tri->testSegmentRayIntersection(TT::QR, TT::Z)); + + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_RAY(TT::RP, TT::X) && tri->testSegmentRayIntersection(TT::RP, TT::X)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_RAY(TT::RP, TT::Y) && tri->testSegmentRayIntersection(TT::RP, TT::Y)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_RAY(TT::RP, TT::Z) && tri->testSegmentRayIntersection(TT::RP, TT::Z)); + + // surface-edge (6 possibilities) + CPPUNIT_ASSERT_EQUAL(false, tri->testSurfaceEdgeIntersection(TT::OX)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSurfaceEdgeIntersection(TT::OY)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSurfaceEdgeIntersection(TT::OZ)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSurfaceEdgeIntersection(TT::YZ)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSurfaceEdgeIntersection(TT::ZX)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSurfaceEdgeIntersection(TT::XY)); + + // surface-ray (3 possibilities) + CPPUNIT_ASSERT_EQUAL(false, tri->testSurfaceRayIntersection(TT::X)); + CPPUNIT_ASSERT_EQUAL(true , tri->testSurfaceRayIntersection(TT::Y)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSurfaceRayIntersection(TT::Z)); + + delete tri; + } + + /// Triangle 7 has the following intersections + /// <PRE> + /// CI R + /// COH - + /// CAH - + /// SF (RP, OXY),(QR,XYZ) + /// SE - + /// SC - + /// SHS (QR, XY) + /// SR - + /// TE OX, ZX + /// TR X + /// </PRE> + /// \brief Status : pass + void TransformedTriangleIntersectTest::testTriangle7() + { + + LOG(1, "+++++++ Testing triangle 7" ); + typedef TransformedTriangle TT; + + double coords[9] = + { + -2.3, -1.5, -2.5, // P + 3.1, 0.15, 0.8, // Q + 0.3, 0.4, 0.2 // R + }; + + TransformedTriangle* tri = new TransformedTriangle(&coords[0], &coords[3], &coords[6]); + + // run all intersection tests and ensure that the ones + // listed with yes in the tables above return true and + // that the ones listed with no or not listed at all return false + + bool isZero[TT::NO_TRI_SEGMENT * TT::NO_DP]; + + for(TriSegment seg = TT::PQ ; seg < TT::NO_TRI_SEGMENT ; seg = TT::TriSegment(seg + 1)) + { + // check beforehand which double-products are zero + for(DoubleProduct dp = TT::C_YZ; dp < TT::NO_DP; dp = DoubleProduct(dp + 1)) + { + isZero[TT::NO_DP*int(seg) + int(dp)] = (tri->calcStableC(seg, dp) == 0.0); + } + } + + // corner in tetrahedron (3 possibilities) + CPPUNIT_ASSERT_EQUAL(false, tri->testCornerInTetrahedron(TT::P)); + CPPUNIT_ASSERT_EQUAL(false, tri->testCornerInTetrahedron(TT::Q)); + CPPUNIT_ASSERT_EQUAL(true , tri->testCornerInTetrahedron(TT::R)); + + // corner on XYZ facet (3 possibilities) + CPPUNIT_ASSERT_EQUAL(false, tri->testCornerOnXYZFacet(TT::P)); + CPPUNIT_ASSERT_EQUAL(false, tri->testCornerOnXYZFacet(TT::Q)); + CPPUNIT_ASSERT_EQUAL(false, tri->testCornerOnXYZFacet(TT::R)); + + // corner above XYZ facet (3 possibilities) + CPPUNIT_ASSERT_EQUAL(false, tri->testCornerAboveXYZFacet(TT::P)); + CPPUNIT_ASSERT_EQUAL(false, tri->testCornerAboveXYZFacet(TT::Q)); + CPPUNIT_ASSERT_EQUAL(false, tri->testCornerAboveXYZFacet(TT::R)); + + // segment-facet (9 possibilities) + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::PQ, TT::OZX)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::PQ, TT::OYZ)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::PQ, TT::OXY)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::PQ, TT::XYZ)); + + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::QR, TT::OZX)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::QR, TT::OYZ)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::QR, TT::OXY)); + CPPUNIT_ASSERT_EQUAL(true , tri->testSegmentFacetIntersection(TT::QR, TT::XYZ)); + + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::RP, TT::OZX)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::RP, TT::OYZ)); + CPPUNIT_ASSERT_EQUAL(true , tri->testSegmentFacetIntersection(TT::RP, TT::OXY)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::RP, TT::XYZ)); + + // segment-edge (18 possibilities) + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::PQ, TT::OX) && tri->testSegmentEdgeIntersection(TT::PQ, TT::OX)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::PQ, TT::OY) && tri->testSegmentEdgeIntersection(TT::PQ, TT::OY)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::PQ, TT::OZ) && tri->testSegmentEdgeIntersection(TT::PQ, TT::OZ)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::PQ, TT::YZ) && tri->testSegmentEdgeIntersection(TT::PQ, TT::YZ)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::PQ, TT::ZX) && tri->testSegmentEdgeIntersection(TT::PQ, TT::ZX)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::PQ, TT::XY) && tri->testSegmentEdgeIntersection(TT::PQ, TT::XY)); + + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::QR, TT::OX) && tri->testSegmentEdgeIntersection(TT::QR, TT::OX)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::QR, TT::OY) && tri->testSegmentEdgeIntersection(TT::QR, TT::OY)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::QR, TT::OZ) && tri->testSegmentEdgeIntersection(TT::QR, TT::OZ)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::QR, TT::YZ) && tri->testSegmentEdgeIntersection(TT::QR, TT::YZ)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::QR, TT::ZX) && tri->testSegmentEdgeIntersection(TT::QR, TT::ZX)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::QR, TT::XY) && tri->testSegmentEdgeIntersection(TT::QR, TT::XY)); + + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::RP, TT::OX) && tri->testSegmentEdgeIntersection(TT::RP, TT::OX)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::RP, TT::OY) && tri->testSegmentEdgeIntersection(TT::RP, TT::OY)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::RP, TT::OZ) && tri->testSegmentEdgeIntersection(TT::RP, TT::OZ)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::RP, TT::YZ) && tri->testSegmentEdgeIntersection(TT::RP, TT::YZ)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::RP, TT::ZX) && tri->testSegmentEdgeIntersection(TT::RP, TT::ZX)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::RP, TT::XY) && tri->testSegmentEdgeIntersection(TT::RP, TT::XY)); + + // segment - corner (12 possibilities) + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::PQ, TT::O) && tri->testSegmentCornerIntersection(TT::PQ, TT::O)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::PQ, TT::X) && tri->testSegmentCornerIntersection(TT::PQ, TT::X)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::PQ, TT::Y) && tri->testSegmentCornerIntersection(TT::PQ, TT::Y)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::PQ, TT::Z) && tri->testSegmentCornerIntersection(TT::PQ, TT::Z)); + + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::QR, TT::O) && tri->testSegmentCornerIntersection(TT::QR, TT::O)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::QR, TT::X) && tri->testSegmentCornerIntersection(TT::QR, TT::X)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::QR, TT::Y) && tri->testSegmentCornerIntersection(TT::QR, TT::Y)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::QR, TT::Z) && tri->testSegmentCornerIntersection(TT::QR, TT::Z)); + + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::RP, TT::O) && tri->testSegmentCornerIntersection(TT::RP, TT::O)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::RP, TT::X) && tri->testSegmentCornerIntersection(TT::RP, TT::X)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::RP, TT::Y) && tri->testSegmentCornerIntersection(TT::RP, TT::Y)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::RP, TT::Z) && tri->testSegmentCornerIntersection(TT::RP, TT::Z)); + + + // segment-halfstrip (9 possibilities) + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentHalfstripIntersection(TT::PQ, TT::YZ)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentHalfstripIntersection(TT::PQ, TT::ZX)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentHalfstripIntersection(TT::PQ, TT::XY)); + + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentHalfstripIntersection(TT::QR, TT::YZ)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentHalfstripIntersection(TT::QR, TT::ZX)); + CPPUNIT_ASSERT_EQUAL(true , tri->testSegmentHalfstripIntersection(TT::QR, TT::XY)); + + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentHalfstripIntersection(TT::RP, TT::YZ)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentHalfstripIntersection(TT::RP, TT::ZX)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentHalfstripIntersection(TT::RP, TT::XY)); + + // segment-ray (9 possibilities) + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_RAY(TT::PQ, TT::X) && tri->testSegmentRayIntersection(TT::PQ, TT::X)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_RAY(TT::PQ, TT::Y) && tri->testSegmentRayIntersection(TT::PQ, TT::Y)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_RAY(TT::PQ, TT::Z) && tri->testSegmentRayIntersection(TT::PQ, TT::Z)); + + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_RAY(TT::QR, TT::X) && tri->testSegmentRayIntersection(TT::QR, TT::X)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_RAY(TT::QR, TT::Y) && tri->testSegmentRayIntersection(TT::QR, TT::Y)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_RAY(TT::QR, TT::Z) && tri->testSegmentRayIntersection(TT::QR, TT::Z)); + + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_RAY(TT::RP, TT::X) && tri->testSegmentRayIntersection(TT::RP, TT::X)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_RAY(TT::RP, TT::Y) && tri->testSegmentRayIntersection(TT::RP, TT::Y)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_RAY(TT::RP, TT::Z) && tri->testSegmentRayIntersection(TT::RP, TT::Z)); + + // surface-edge (6 possibilities) + CPPUNIT_ASSERT_EQUAL(true , tri->testSurfaceEdgeIntersection(TT::OX)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSurfaceEdgeIntersection(TT::OY)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSurfaceEdgeIntersection(TT::OZ)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSurfaceEdgeIntersection(TT::YZ)); + CPPUNIT_ASSERT_EQUAL(true , tri->testSurfaceEdgeIntersection(TT::ZX)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSurfaceEdgeIntersection(TT::XY)); + + // surface-ray (3 possibilities) + CPPUNIT_ASSERT_EQUAL(true , tri->testSurfaceRayIntersection(TT::X)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSurfaceRayIntersection(TT::Y)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSurfaceRayIntersection(TT::Z)); + + delete tri; + } + + /// Triangle 8 has the following intersections + /// <PRE> + /// CI [Q] + /// COH Q + /// CAH - + /// SF (QR, OZX), [ (QR, XYZ) ] + /// SE - + /// SC (PQ,Y) + /// SHS - + /// SR - + /// TE OZ, [YZ,OY,XY] + /// TR - + /// </PRE> + /// \brief Status : pass + void TransformedTriangleIntersectTest::testTriangle8() + { + LOG(1, "+++++++ Testing triangle 8" ); + typedef TransformedTriangle TT; + + double coords[9] = + { + -0.75, 3.25, -1.5, // P + 0.25, 0.25, 0.5, // Q + -0.1, -0.4, 0.9 // R + }; + + TransformedTriangle* tri = new TransformedTriangle(&coords[0], &coords[3], &coords[6]); + + // run all intersection tests and ensure that the ones + // listed with yes in the tables above return true and + // that the ones listed with no or not listed at all return false + + bool isZero[TT::NO_TRI_SEGMENT * TT::NO_DP]; + + for(TriSegment seg = TT::PQ ; seg < TT::NO_TRI_SEGMENT ; seg = TT::TriSegment(seg + 1)) + { + // check beforehand which double-products are zero + for(DoubleProduct dp = TT::C_YZ; dp < TT::NO_DP; dp = DoubleProduct(dp + 1)) + { + isZero[TT::NO_DP*int(seg) + int(dp)] = (tri->calcStableC(seg, dp) == 0.0); + } + } + + // corner in tetrahedron (3 possibilities) + CPPUNIT_ASSERT_EQUAL(false, tri->testCornerInTetrahedron(TT::P)); + CPPUNIT_ASSERT_EQUAL(true , tri->testCornerInTetrahedron(TT::Q)); + CPPUNIT_ASSERT_EQUAL(false, tri->testCornerInTetrahedron(TT::R)); + + // corner on XYZ facet (3 possibilities) + CPPUNIT_ASSERT_EQUAL(false, tri->testCornerOnXYZFacet(TT::P)); + CPPUNIT_ASSERT_EQUAL(true , tri->testCornerOnXYZFacet(TT::Q)); + CPPUNIT_ASSERT_EQUAL(false, tri->testCornerOnXYZFacet(TT::R)); + + // corner above XYZ facet (3 possibilities) + CPPUNIT_ASSERT_EQUAL(false, tri->testCornerAboveXYZFacet(TT::P)); + CPPUNIT_ASSERT_EQUAL(false, tri->testCornerAboveXYZFacet(TT::Q)); + CPPUNIT_ASSERT_EQUAL(false, tri->testCornerAboveXYZFacet(TT::R)); + + // segment-facet (9 possibilities) + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::PQ, TT::OZX)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::PQ, TT::OYZ)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::PQ, TT::OXY)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::PQ, TT::XYZ)); + + CPPUNIT_ASSERT_EQUAL(true , tri->testSegmentFacetIntersection(TT::QR, TT::OZX)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::QR, TT::OYZ)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::QR, TT::OXY)); + CPPUNIT_ASSERT_EQUAL(true , tri->testSegmentFacetIntersection(TT::QR, TT::XYZ)); + + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::RP, TT::OZX)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::RP, TT::OYZ)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::RP, TT::OXY)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::RP, TT::XYZ)); + + // segment-edge (18 possibilities) + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::PQ, TT::OX) && tri->testSegmentEdgeIntersection(TT::PQ, TT::OX)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::PQ, TT::OY) && tri->testSegmentEdgeIntersection(TT::PQ, TT::OY)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::PQ, TT::OZ) && tri->testSegmentEdgeIntersection(TT::PQ, TT::OZ)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::PQ, TT::YZ) && tri->testSegmentEdgeIntersection(TT::PQ, TT::YZ)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::PQ, TT::ZX) && tri->testSegmentEdgeIntersection(TT::PQ, TT::ZX)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::PQ, TT::XY) && tri->testSegmentEdgeIntersection(TT::PQ, TT::XY)); + + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::QR, TT::OX) && tri->testSegmentEdgeIntersection(TT::QR, TT::OX)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::QR, TT::OY) && tri->testSegmentEdgeIntersection(TT::QR, TT::OY)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::QR, TT::OZ) && tri->testSegmentEdgeIntersection(TT::QR, TT::OZ)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::QR, TT::YZ) && tri->testSegmentEdgeIntersection(TT::QR, TT::YZ)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::QR, TT::ZX) && tri->testSegmentEdgeIntersection(TT::QR, TT::ZX)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::QR, TT::XY) && tri->testSegmentEdgeIntersection(TT::QR, TT::XY)); + + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::RP, TT::OX) && tri->testSegmentEdgeIntersection(TT::RP, TT::OX)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::RP, TT::OY) && tri->testSegmentEdgeIntersection(TT::RP, TT::OY)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::RP, TT::OZ) && tri->testSegmentEdgeIntersection(TT::RP, TT::OZ)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::RP, TT::YZ) && tri->testSegmentEdgeIntersection(TT::RP, TT::YZ)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::RP, TT::ZX) && tri->testSegmentEdgeIntersection(TT::RP, TT::ZX)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::RP, TT::XY) && tri->testSegmentEdgeIntersection(TT::RP, TT::XY)); + + // segment - corner (12 possibilities) + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::PQ, TT::O) && tri->testSegmentCornerIntersection(TT::PQ, TT::O)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::PQ, TT::X) && tri->testSegmentCornerIntersection(TT::PQ, TT::X)); + CPPUNIT_ASSERT_EQUAL(true , TEST_ZERO_DP_CORNER(TT::PQ, TT::Y) && tri->testSegmentCornerIntersection(TT::PQ, TT::Y)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::PQ, TT::Z) && tri->testSegmentCornerIntersection(TT::PQ, TT::Z)); + + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::QR, TT::O) && tri->testSegmentCornerIntersection(TT::QR, TT::O)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::QR, TT::X) && tri->testSegmentCornerIntersection(TT::QR, TT::X)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::QR, TT::Y) && tri->testSegmentCornerIntersection(TT::QR, TT::Y)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::QR, TT::Z) && tri->testSegmentCornerIntersection(TT::QR, TT::Z)); + + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::RP, TT::O) && tri->testSegmentCornerIntersection(TT::RP, TT::O)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::RP, TT::X) && tri->testSegmentCornerIntersection(TT::RP, TT::X)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::RP, TT::Y) && tri->testSegmentCornerIntersection(TT::RP, TT::Y)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::RP, TT::Z) && tri->testSegmentCornerIntersection(TT::RP, TT::Z)); + + // segment-halfstrip (9 possibilities) + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentHalfstripIntersection(TT::PQ, TT::YZ)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentHalfstripIntersection(TT::PQ, TT::ZX)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentHalfstripIntersection(TT::PQ, TT::XY)); + + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentHalfstripIntersection(TT::QR, TT::YZ)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentHalfstripIntersection(TT::QR, TT::ZX)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentHalfstripIntersection(TT::QR, TT::XY)); + + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentHalfstripIntersection(TT::RP, TT::YZ)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentHalfstripIntersection(TT::RP, TT::ZX)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentHalfstripIntersection(TT::RP, TT::XY)); + + // segment-ray (9 possibilities) + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_RAY(TT::PQ, TT::X) && tri->testSegmentRayIntersection(TT::PQ, TT::X)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_RAY(TT::PQ, TT::Y) && tri->testSegmentRayIntersection(TT::PQ, TT::Y)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_RAY(TT::PQ, TT::Z) && tri->testSegmentRayIntersection(TT::PQ, TT::Z)); + + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_RAY(TT::QR, TT::X) && tri->testSegmentRayIntersection(TT::QR, TT::X)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_RAY(TT::QR, TT::Y) && tri->testSegmentRayIntersection(TT::QR, TT::Y)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_RAY(TT::QR, TT::Z) && tri->testSegmentRayIntersection(TT::QR, TT::Z)); + + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_RAY(TT::RP, TT::X) && tri->testSegmentRayIntersection(TT::RP, TT::X)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_RAY(TT::RP, TT::Y) && tri->testSegmentRayIntersection(TT::RP, TT::Y)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_RAY(TT::RP, TT::Z) && tri->testSegmentRayIntersection(TT::RP, TT::Z)); + + // surface-edge (6 possibilities) + CPPUNIT_ASSERT_EQUAL(false, tri->testSurfaceEdgeIntersection(TT::OX)); + CPPUNIT_ASSERT_EQUAL(true , tri->testSurfaceEdgeIntersection(TT::OY)); + CPPUNIT_ASSERT_EQUAL(true , tri->testSurfaceEdgeIntersection(TT::OZ)); + CPPUNIT_ASSERT_EQUAL(true , tri->testSurfaceEdgeIntersection(TT::YZ)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSurfaceEdgeIntersection(TT::ZX)); + CPPUNIT_ASSERT_EQUAL(true , tri->testSurfaceEdgeIntersection(TT::XY)); + + // surface-ray (3 possibilities) + CPPUNIT_ASSERT_EQUAL(false, tri->testSurfaceRayIntersection(TT::X)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSurfaceRayIntersection(TT::Y)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSurfaceRayIntersection(TT::Z)); + + delete tri; + } + + /// Triangle 9 has the following intersections + /// <PRE> + /// CI [P] + /// COH P + /// CAH R + /// SF (PQ, OZX), [(PQ, XYZ), (RP,XYZ)] + /// SE (QR, ZX) + /// SC - + /// SHS - + /// SR - + /// TE [ZX] + /// TR - + /// </PRE> + /// \brief Status : pass + void TransformedTriangleIntersectTest::testTriangle9() + { + LOG(1, "+++++++ Testing triangle 9" ); + typedef TransformedTriangle TT; + + double coords[9] = + { + 0.6, 0.2, 0.2, // P + 0.3, -0.2, 0.8, // Q + 0.1, 0.2, 0.8 // R + }; + + TransformedTriangle* tri = new TransformedTriangle(&coords[0], &coords[3], &coords[6]); + + // run all intersection tests and ensure that the ones + // listed with yes in the tables above return true and + // that the ones listed with no or not listed at all return false + + bool isZero[TT::NO_TRI_SEGMENT * TT::NO_DP]; + + for(TriSegment seg = TT::PQ ; seg < TT::NO_TRI_SEGMENT ; seg = TT::TriSegment(seg + 1)) + { + // check beforehand which double-products are zero + for(DoubleProduct dp = TT::C_YZ; dp < TT::NO_DP; dp = DoubleProduct(dp + 1)) + { + isZero[TT::NO_DP*int(seg) + int(dp)] = (tri->calcStableC(seg, dp) == 0.0); + } + } + + // corner in tetrahedron (3 possibilities) + CPPUNIT_ASSERT_EQUAL(true , tri->testCornerInTetrahedron(TT::P)); + CPPUNIT_ASSERT_EQUAL(false, tri->testCornerInTetrahedron(TT::Q)); + CPPUNIT_ASSERT_EQUAL(false, tri->testCornerInTetrahedron(TT::R)); + + // corner on XYZ facet (3 possibilities) + CPPUNIT_ASSERT_EQUAL(true , tri->testCornerOnXYZFacet(TT::P)); + CPPUNIT_ASSERT_EQUAL(false, tri->testCornerOnXYZFacet(TT::Q)); + CPPUNIT_ASSERT_EQUAL(false, tri->testCornerOnXYZFacet(TT::R)); + + // corner above XYZ facet (3 possibilities) + CPPUNIT_ASSERT_EQUAL(false, tri->testCornerAboveXYZFacet(TT::P)); + CPPUNIT_ASSERT_EQUAL(false, tri->testCornerAboveXYZFacet(TT::Q)); + CPPUNIT_ASSERT_EQUAL(true , tri->testCornerAboveXYZFacet(TT::R)); + + // segment-facet (9 possibilities) + CPPUNIT_ASSERT_EQUAL(true , tri->testSegmentFacetIntersection(TT::PQ, TT::OZX)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::PQ, TT::OYZ)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::PQ, TT::OXY)); + CPPUNIT_ASSERT_EQUAL(true , tri->testSegmentFacetIntersection(TT::PQ, TT::XYZ)); + + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::QR, TT::OZX)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::QR, TT::OYZ)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::QR, TT::OXY)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::QR, TT::XYZ)); + + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::RP, TT::OZX)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::RP, TT::OYZ)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::RP, TT::OXY)); + CPPUNIT_ASSERT_EQUAL(true , tri->testSegmentFacetIntersection(TT::RP, TT::XYZ)); + + // segment-edge (18 possibilities) + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::PQ, TT::OX) && tri->testSegmentEdgeIntersection(TT::PQ, TT::OX)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::PQ, TT::OY) && tri->testSegmentEdgeIntersection(TT::PQ, TT::OY)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::PQ, TT::OZ) && tri->testSegmentEdgeIntersection(TT::PQ, TT::OZ)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::PQ, TT::YZ) && tri->testSegmentEdgeIntersection(TT::PQ, TT::YZ)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::PQ, TT::ZX) && tri->testSegmentEdgeIntersection(TT::PQ, TT::ZX)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::PQ, TT::XY) && tri->testSegmentEdgeIntersection(TT::PQ, TT::XY)); + + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::QR, TT::OX) && tri->testSegmentEdgeIntersection(TT::QR, TT::OX)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::QR, TT::OY) && tri->testSegmentEdgeIntersection(TT::QR, TT::OY)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::QR, TT::OZ) && tri->testSegmentEdgeIntersection(TT::QR, TT::OZ)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::QR, TT::YZ) && tri->testSegmentEdgeIntersection(TT::QR, TT::YZ)); + CPPUNIT_ASSERT_EQUAL(true , TEST_ZERO_DP_EDGE(TT::QR, TT::ZX) && tri->testSegmentEdgeIntersection(TT::QR, TT::ZX)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::QR, TT::XY) && tri->testSegmentEdgeIntersection(TT::QR, TT::XY)); + + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::RP, TT::OX) && tri->testSegmentEdgeIntersection(TT::RP, TT::OX)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::RP, TT::OY) && tri->testSegmentEdgeIntersection(TT::RP, TT::OY)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::RP, TT::OZ) && tri->testSegmentEdgeIntersection(TT::RP, TT::OZ)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::RP, TT::YZ) && tri->testSegmentEdgeIntersection(TT::RP, TT::YZ)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::RP, TT::ZX) && tri->testSegmentEdgeIntersection(TT::RP, TT::ZX)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::RP, TT::XY) && tri->testSegmentEdgeIntersection(TT::RP, TT::XY)); + + // segment - corner (12 possibilities) + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::PQ, TT::O) && tri->testSegmentCornerIntersection(TT::PQ, TT::O)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::PQ, TT::X) && tri->testSegmentCornerIntersection(TT::PQ, TT::X)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::PQ, TT::Y) && tri->testSegmentCornerIntersection(TT::PQ, TT::Y)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::PQ, TT::Z) && tri->testSegmentCornerIntersection(TT::PQ, TT::Z)); + + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::QR, TT::O) && tri->testSegmentCornerIntersection(TT::QR, TT::O)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::QR, TT::X) && tri->testSegmentCornerIntersection(TT::QR, TT::X)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::QR, TT::Y) && tri->testSegmentCornerIntersection(TT::QR, TT::Y)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::QR, TT::Z) && tri->testSegmentCornerIntersection(TT::QR, TT::Z)); + + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::RP, TT::O) && tri->testSegmentCornerIntersection(TT::RP, TT::O)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::RP, TT::X) && tri->testSegmentCornerIntersection(TT::RP, TT::X)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::RP, TT::Y) && tri->testSegmentCornerIntersection(TT::RP, TT::Y)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::RP, TT::Z) && tri->testSegmentCornerIntersection(TT::RP, TT::Z)); + + // segment-halfstrip (9 possibilities) + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentHalfstripIntersection(TT::PQ, TT::YZ)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentHalfstripIntersection(TT::PQ, TT::ZX)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentHalfstripIntersection(TT::PQ, TT::XY)); + + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentHalfstripIntersection(TT::QR, TT::YZ)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentHalfstripIntersection(TT::QR, TT::ZX)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentHalfstripIntersection(TT::QR, TT::XY)); + + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentHalfstripIntersection(TT::RP, TT::YZ)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentHalfstripIntersection(TT::RP, TT::ZX)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentHalfstripIntersection(TT::RP, TT::XY)); + + // segment-ray (9 possibilities) + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_RAY(TT::PQ, TT::X) && tri->testSegmentRayIntersection(TT::PQ, TT::X)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_RAY(TT::PQ, TT::Y) && tri->testSegmentRayIntersection(TT::PQ, TT::Y)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_RAY(TT::PQ, TT::Z) && tri->testSegmentRayIntersection(TT::PQ, TT::Z)); + + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_RAY(TT::QR, TT::X) && tri->testSegmentRayIntersection(TT::QR, TT::X)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_RAY(TT::QR, TT::Y) && tri->testSegmentRayIntersection(TT::QR, TT::Y)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_RAY(TT::QR, TT::Z) && tri->testSegmentRayIntersection(TT::QR, TT::Z)); + + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_RAY(TT::RP, TT::X) && tri->testSegmentRayIntersection(TT::RP, TT::X)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_RAY(TT::RP, TT::Y) && tri->testSegmentRayIntersection(TT::RP, TT::Y)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_RAY(TT::RP, TT::Z) && tri->testSegmentRayIntersection(TT::RP, TT::Z)); + + // surface-edge (6 possibilities) + CPPUNIT_ASSERT_EQUAL(false, tri->testSurfaceEdgeIntersection(TT::OX)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSurfaceEdgeIntersection(TT::OY)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSurfaceEdgeIntersection(TT::OZ)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSurfaceEdgeIntersection(TT::YZ)); + CPPUNIT_ASSERT_EQUAL(true , tri->testSurfaceEdgeIntersection(TT::ZX)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSurfaceEdgeIntersection(TT::XY)); + + // surface-ray (3 possibilities) + CPPUNIT_ASSERT_EQUAL(false, tri->testSurfaceRayIntersection(TT::X)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSurfaceRayIntersection(TT::Y)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSurfaceRayIntersection(TT::Z)); + + delete tri; + } + + + /// Triangle 10 has the following intersections + /// <PRE> + /// CI [R] + /// COH R + /// CAH Q + /// SF (RP, OYZ), [ (RP, XYZ), (QR, XYZ) ] + /// SE (PQ, YZ) + /// SC - + /// SHS - + /// SR - + /// TE [YZ] + /// TR - + /// </PRE> + /// \brief Status : pass + void TransformedTriangleIntersectTest::testTriangle10() + { + LOG(1, "+++++++ Testing triangle 10" ); + typedef TransformedTriangle TT; + + double coords[9] = + { + -0.1, 0.3, 0.6, // P + 0.1, 0.1, 1.0, // Q + 0.4, 0.3, 0.3 // R + }; + + TransformedTriangle* tri = new TransformedTriangle(&coords[0], &coords[3], &coords[6]); + + // run all intersection tests and ensure that the ones + // listed with yes in the tables above return true and + // that the ones listed with no or not listed at all return false + + bool isZero[TT::NO_TRI_SEGMENT * TT::NO_DP]; + + for(TriSegment seg = TT::PQ ; seg < TT::NO_TRI_SEGMENT ; seg = TT::TriSegment(seg + 1)) + { + // check beforehand which double-products are zero + for(DoubleProduct dp = TT::C_YZ; dp < TT::NO_DP; dp = DoubleProduct(dp + 1)) + { + isZero[TT::NO_DP*int(seg) + int(dp)] = (tri->calcStableC(seg, dp) == 0.0); + } + } + + // corner in tetrahedron (3 possibilities) + CPPUNIT_ASSERT_EQUAL(false, tri->testCornerInTetrahedron(TT::P)); + CPPUNIT_ASSERT_EQUAL(false, tri->testCornerInTetrahedron(TT::Q)); + CPPUNIT_ASSERT_EQUAL(true , tri->testCornerInTetrahedron(TT::R)); + + // corner on XYZ facet (3 possibilities) + CPPUNIT_ASSERT_EQUAL(false, tri->testCornerOnXYZFacet(TT::P)); + CPPUNIT_ASSERT_EQUAL(false, tri->testCornerOnXYZFacet(TT::Q)); + CPPUNIT_ASSERT_EQUAL(true , tri->testCornerOnXYZFacet(TT::R)); + + // corner above XYZ facet (3 possibilities) + CPPUNIT_ASSERT_EQUAL(false, tri->testCornerAboveXYZFacet(TT::P)); + CPPUNIT_ASSERT_EQUAL(true , tri->testCornerAboveXYZFacet(TT::Q)); + CPPUNIT_ASSERT_EQUAL(false, tri->testCornerAboveXYZFacet(TT::R)); + + // segment-facet (9 possibilities) + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::PQ, TT::OZX)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::PQ, TT::OYZ)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::PQ, TT::OXY)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::PQ, TT::XYZ)); + + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::QR, TT::OZX)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::QR, TT::OYZ)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::QR, TT::OXY)); + CPPUNIT_ASSERT_EQUAL(true , tri->testSegmentFacetIntersection(TT::QR, TT::XYZ)); + + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::RP, TT::OZX)); + CPPUNIT_ASSERT_EQUAL(true , tri->testSegmentFacetIntersection(TT::RP, TT::OYZ)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::RP, TT::OXY)); + CPPUNIT_ASSERT_EQUAL(true , tri->testSegmentFacetIntersection(TT::RP, TT::XYZ)); + + // segment-edge (18 possibilities) + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::PQ, TT::OX) && tri->testSegmentEdgeIntersection(TT::PQ, TT::OX)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::PQ, TT::OY) && tri->testSegmentEdgeIntersection(TT::PQ, TT::OY)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::PQ, TT::OZ) && tri->testSegmentEdgeIntersection(TT::PQ, TT::OZ)); + CPPUNIT_ASSERT_EQUAL(true , TEST_ZERO_DP_EDGE(TT::PQ, TT::YZ) && tri->testSegmentEdgeIntersection(TT::PQ, TT::YZ)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::PQ, TT::ZX) && tri->testSegmentEdgeIntersection(TT::PQ, TT::ZX)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::PQ, TT::XY) && tri->testSegmentEdgeIntersection(TT::PQ, TT::XY)); + + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::QR, TT::OX) && tri->testSegmentEdgeIntersection(TT::QR, TT::OX)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::QR, TT::OY) && tri->testSegmentEdgeIntersection(TT::QR, TT::OY)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::QR, TT::OZ) && tri->testSegmentEdgeIntersection(TT::QR, TT::OZ)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::QR, TT::YZ) && tri->testSegmentEdgeIntersection(TT::QR, TT::YZ)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::QR, TT::ZX) && tri->testSegmentEdgeIntersection(TT::QR, TT::ZX)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::QR, TT::XY) && tri->testSegmentEdgeIntersection(TT::QR, TT::XY)); + + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::RP, TT::OX) && tri->testSegmentEdgeIntersection(TT::RP, TT::OX)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::RP, TT::OY) && tri->testSegmentEdgeIntersection(TT::RP, TT::OY)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::RP, TT::OZ) && tri->testSegmentEdgeIntersection(TT::RP, TT::OZ)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::RP, TT::YZ) && tri->testSegmentEdgeIntersection(TT::RP, TT::YZ)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::RP, TT::ZX) && tri->testSegmentEdgeIntersection(TT::RP, TT::ZX)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::RP, TT::XY) && tri->testSegmentEdgeIntersection(TT::RP, TT::XY)); + + // segment - corner (12 possibilities) + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::PQ, TT::O) && tri->testSegmentCornerIntersection(TT::PQ, TT::O)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::PQ, TT::X) && tri->testSegmentCornerIntersection(TT::PQ, TT::X)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::PQ, TT::Y) && tri->testSegmentCornerIntersection(TT::PQ, TT::Y)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::PQ, TT::Z) && tri->testSegmentCornerIntersection(TT::PQ, TT::Z)); + + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::QR, TT::O) && tri->testSegmentCornerIntersection(TT::QR, TT::O)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::QR, TT::X) && tri->testSegmentCornerIntersection(TT::QR, TT::X)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::QR, TT::Y) && tri->testSegmentCornerIntersection(TT::QR, TT::Y)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::QR, TT::Z) && tri->testSegmentCornerIntersection(TT::QR, TT::Z)); + + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::RP, TT::O) && tri->testSegmentCornerIntersection(TT::RP, TT::O)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::RP, TT::X) && tri->testSegmentCornerIntersection(TT::RP, TT::X)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::RP, TT::Y) && tri->testSegmentCornerIntersection(TT::RP, TT::Y)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::RP, TT::Z) && tri->testSegmentCornerIntersection(TT::RP, TT::Z)); + + // segment-halfstrip (9 possibilities) + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentHalfstripIntersection(TT::PQ, TT::YZ)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentHalfstripIntersection(TT::PQ, TT::ZX)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentHalfstripIntersection(TT::PQ, TT::XY)); + + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentHalfstripIntersection(TT::QR, TT::YZ)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentHalfstripIntersection(TT::QR, TT::ZX)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentHalfstripIntersection(TT::QR, TT::XY)); + + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentHalfstripIntersection(TT::RP, TT::YZ)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentHalfstripIntersection(TT::RP, TT::ZX)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentHalfstripIntersection(TT::RP, TT::XY)); + + // segment-ray (9 possibilities) + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_RAY(TT::PQ, TT::X) && tri->testSegmentRayIntersection(TT::PQ, TT::X)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_RAY(TT::PQ, TT::Y) && tri->testSegmentRayIntersection(TT::PQ, TT::Y)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_RAY(TT::PQ, TT::Z) && tri->testSegmentRayIntersection(TT::PQ, TT::Z)); + + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_RAY(TT::QR, TT::X) && tri->testSegmentRayIntersection(TT::QR, TT::X)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_RAY(TT::QR, TT::Y) && tri->testSegmentRayIntersection(TT::QR, TT::Y)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_RAY(TT::QR, TT::Z) && tri->testSegmentRayIntersection(TT::QR, TT::Z)); + + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_RAY(TT::RP, TT::X) && tri->testSegmentRayIntersection(TT::RP, TT::X)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_RAY(TT::RP, TT::Y) && tri->testSegmentRayIntersection(TT::RP, TT::Y)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_RAY(TT::RP, TT::Z) && tri->testSegmentRayIntersection(TT::RP, TT::Z)); + + // surface-edge (6 possibilities) + CPPUNIT_ASSERT_EQUAL(false, tri->testSurfaceEdgeIntersection(TT::OX)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSurfaceEdgeIntersection(TT::OY)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSurfaceEdgeIntersection(TT::OZ)); + CPPUNIT_ASSERT_EQUAL(true , tri->testSurfaceEdgeIntersection(TT::YZ)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSurfaceEdgeIntersection(TT::ZX)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSurfaceEdgeIntersection(TT::XY)); + + // surface-ray (3 possibilities) + CPPUNIT_ASSERT_EQUAL(false, tri->testSurfaceRayIntersection(TT::X)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSurfaceRayIntersection(TT::Y)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSurfaceRayIntersection(TT::Z)); + + delete tri; + } + + /// Triangle 11 has the following intersections + /// <PRE> + /// CI Q, R + /// COH - + /// CAH - + /// SF - + /// SE (PQ, OX) + /// SC (RP, O) + /// SHS - + /// SR - + /// TE [OY, OZ] + /// TR - + /// </PRE> + /// \brief Status : pass + void TransformedTriangleIntersectTest::testTriangle11() + { + LOG(1, "+++++++ Testing triangle 11" ); + typedef TransformedTriangle TT; + + double coords[9] = + { + -0.2, -0.2, -0.2, // P + 0.2, 0.1, 0.1, // Q + 0.3, 0.3, 0.3 // R + }; + + TransformedTriangle* tri = new TransformedTriangle(&coords[0], &coords[3], &coords[6]); + + // run all intersection tests and ensure that the ones + // listed with yes in the tables above return true and + // that the ones listed with no or not listed at all return false + + bool isZero[TT::NO_TRI_SEGMENT * TT::NO_DP]; + + for(TriSegment seg = TT::PQ ; seg < TT::NO_TRI_SEGMENT ; seg = TT::TriSegment(seg + 1)) + { + // check beforehand which double-products are zero + for(DoubleProduct dp = TT::C_YZ; dp < TT::NO_DP; dp = DoubleProduct(dp + 1)) + { + isZero[TT::NO_DP*int(seg) + int(dp)] = (tri->calcStableC(seg, dp) == 0.0); + } + } + + // corner in tetrahedron (3 possibilities) + CPPUNIT_ASSERT_EQUAL(false, tri->testCornerInTetrahedron(TT::P)); + CPPUNIT_ASSERT_EQUAL(true , tri->testCornerInTetrahedron(TT::Q)); + CPPUNIT_ASSERT_EQUAL(true , tri->testCornerInTetrahedron(TT::R)); + + // corner on XYZ facet (3 possibilities) + CPPUNIT_ASSERT_EQUAL(false, tri->testCornerOnXYZFacet(TT::P)); + CPPUNIT_ASSERT_EQUAL(false, tri->testCornerOnXYZFacet(TT::Q)); + CPPUNIT_ASSERT_EQUAL(false, tri->testCornerOnXYZFacet(TT::R)); + + // corner above XYZ facet (3 possibilities) + CPPUNIT_ASSERT_EQUAL(false, tri->testCornerAboveXYZFacet(TT::P)); + CPPUNIT_ASSERT_EQUAL(false, tri->testCornerAboveXYZFacet(TT::Q)); + CPPUNIT_ASSERT_EQUAL(false, tri->testCornerAboveXYZFacet(TT::R)); + + // segment-facet (9 possibilities) + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::PQ, TT::OZX)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::PQ, TT::OYZ)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::PQ, TT::OXY)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::PQ, TT::XYZ)); + + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::QR, TT::OZX)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::QR, TT::OYZ)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::QR, TT::OXY)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::QR, TT::XYZ)); + + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::RP, TT::OZX)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::RP, TT::OYZ)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::RP, TT::OXY)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::RP, TT::XYZ)); + + // segment-edge (18 possibilities) + CPPUNIT_ASSERT_EQUAL(true , TEST_ZERO_DP_EDGE(TT::PQ, TT::OX) && tri->testSegmentEdgeIntersection(TT::PQ, TT::OX)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::PQ, TT::OY) && tri->testSegmentEdgeIntersection(TT::PQ, TT::OY)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::PQ, TT::OZ) && tri->testSegmentEdgeIntersection(TT::PQ, TT::OZ)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::PQ, TT::YZ) && tri->testSegmentEdgeIntersection(TT::PQ, TT::YZ)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::PQ, TT::ZX) && tri->testSegmentEdgeIntersection(TT::PQ, TT::ZX)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::PQ, TT::XY) && tri->testSegmentEdgeIntersection(TT::PQ, TT::XY)); + + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::QR, TT::OX) && tri->testSegmentEdgeIntersection(TT::QR, TT::OX)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::QR, TT::OY) && tri->testSegmentEdgeIntersection(TT::QR, TT::OY)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::QR, TT::OZ) && tri->testSegmentEdgeIntersection(TT::QR, TT::OZ)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::QR, TT::YZ) && tri->testSegmentEdgeIntersection(TT::QR, TT::YZ)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::QR, TT::ZX) && tri->testSegmentEdgeIntersection(TT::QR, TT::ZX)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::QR, TT::XY) && tri->testSegmentEdgeIntersection(TT::QR, TT::XY)); + + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::RP, TT::OX) && tri->testSegmentEdgeIntersection(TT::RP, TT::OX)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::RP, TT::OY) && tri->testSegmentEdgeIntersection(TT::RP, TT::OY)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::RP, TT::OZ) && tri->testSegmentEdgeIntersection(TT::RP, TT::OZ)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::RP, TT::YZ) && tri->testSegmentEdgeIntersection(TT::RP, TT::YZ)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::RP, TT::ZX) && tri->testSegmentEdgeIntersection(TT::RP, TT::ZX)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::RP, TT::XY) && tri->testSegmentEdgeIntersection(TT::RP, TT::XY)); + + // segment - corner (12 possibilities) + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::PQ, TT::O) && tri->testSegmentCornerIntersection(TT::PQ, TT::O)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::PQ, TT::X) && tri->testSegmentCornerIntersection(TT::PQ, TT::X)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::PQ, TT::Y) && tri->testSegmentCornerIntersection(TT::PQ, TT::Y)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::PQ, TT::Z) && tri->testSegmentCornerIntersection(TT::PQ, TT::Z)); + + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::QR, TT::O) && tri->testSegmentCornerIntersection(TT::QR, TT::O)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::QR, TT::X) && tri->testSegmentCornerIntersection(TT::QR, TT::X)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::QR, TT::Y) && tri->testSegmentCornerIntersection(TT::QR, TT::Y)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::QR, TT::Z) && tri->testSegmentCornerIntersection(TT::QR, TT::Z)); + + CPPUNIT_ASSERT_EQUAL(true , TEST_ZERO_DP_CORNER(TT::RP, TT::O) && tri->testSegmentCornerIntersection(TT::RP, TT::O)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::RP, TT::X) && tri->testSegmentCornerIntersection(TT::RP, TT::X)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::RP, TT::Y) && tri->testSegmentCornerIntersection(TT::RP, TT::Y)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::RP, TT::Z) && tri->testSegmentCornerIntersection(TT::RP, TT::Z)); + + // segment-halfstrip (9 possibilities) + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentHalfstripIntersection(TT::PQ, TT::YZ)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentHalfstripIntersection(TT::PQ, TT::ZX)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentHalfstripIntersection(TT::PQ, TT::XY)); + + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentHalfstripIntersection(TT::QR, TT::YZ)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentHalfstripIntersection(TT::QR, TT::ZX)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentHalfstripIntersection(TT::QR, TT::XY)); + + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentHalfstripIntersection(TT::RP, TT::YZ)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentHalfstripIntersection(TT::RP, TT::ZX)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentHalfstripIntersection(TT::RP, TT::XY)); + + // segment-ray (9 possibilities) + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_RAY(TT::PQ, TT::X) && tri->testSegmentRayIntersection(TT::PQ, TT::X)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_RAY(TT::PQ, TT::Y) && tri->testSegmentRayIntersection(TT::PQ, TT::Y)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_RAY(TT::PQ, TT::Z) && tri->testSegmentRayIntersection(TT::PQ, TT::Z)); + + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_RAY(TT::QR, TT::X) && tri->testSegmentRayIntersection(TT::QR, TT::X)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_RAY(TT::QR, TT::Y) && tri->testSegmentRayIntersection(TT::QR, TT::Y)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_RAY(TT::QR, TT::Z) && tri->testSegmentRayIntersection(TT::QR, TT::Z)); + + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_RAY(TT::RP, TT::X) && tri->testSegmentRayIntersection(TT::RP, TT::X)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_RAY(TT::RP, TT::Y) && tri->testSegmentRayIntersection(TT::RP, TT::Y)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_RAY(TT::RP, TT::Z) && tri->testSegmentRayIntersection(TT::RP, TT::Z)); + + // surface-edge (6 possibilities) + CPPUNIT_ASSERT_EQUAL(false, tri->testSurfaceEdgeIntersection(TT::OX)); + CPPUNIT_ASSERT_EQUAL(true , tri->testSurfaceEdgeIntersection(TT::OY)); + CPPUNIT_ASSERT_EQUAL(true, tri->testSurfaceEdgeIntersection(TT::OZ)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSurfaceEdgeIntersection(TT::YZ)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSurfaceEdgeIntersection(TT::ZX)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSurfaceEdgeIntersection(TT::XY)); + + // surface-ray (3 possibilities) + CPPUNIT_ASSERT_EQUAL(false, tri->testSurfaceRayIntersection(TT::X)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSurfaceRayIntersection(TT::Y)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSurfaceRayIntersection(TT::Z)); + + delete tri; + } + + + /// Triangle 12 has the following intersections + /// <PRE> + /// CI - + /// COH - + /// CAH - + /// SF (QR, OXY), (QR, OZX) + /// SE (RP, OY), (PQ, OZ) + /// SC - + /// SHS - + /// SR - + /// TE [OY], [OZ] + /// TR - + /// </PRE> + /// \brief Status : pass + void TransformedTriangleIntersectTest::testTriangle12() + { + LOG(1, "+++++++ Testing triangle 12" ); + typedef TransformedTriangle TT; + + double coords[9] = + { + -0.2, 0.2, 0.2, // P + 0.2, -0.2, 0.3, // Q + 0.6, 0.6, -0.6 // R + }; + + TransformedTriangle* tri = new TransformedTriangle(&coords[0], &coords[3], &coords[6]); + + // run all intersection tests and ensure that the ones + // listed with yes in the tables above return true and + // that the ones listed with no or not listed at all return false + + bool isZero[TT::NO_TRI_SEGMENT * TT::NO_DP]; + + for(TriSegment seg = TT::PQ ; seg < TT::NO_TRI_SEGMENT ; seg = TT::TriSegment(seg + 1)) + { + // check beforehand which double-products are zero + for(DoubleProduct dp = TT::C_YZ; dp < TT::NO_DP; dp = DoubleProduct(dp + 1)) + { + isZero[TT::NO_DP*int(seg) + int(dp)] = (tri->calcStableC(seg, dp) == 0.0); + } + } + + // corner in tetrahedron (3 possibilities) + CPPUNIT_ASSERT_EQUAL(false, tri->testCornerInTetrahedron(TT::P)); + CPPUNIT_ASSERT_EQUAL(false, tri->testCornerInTetrahedron(TT::Q)); + CPPUNIT_ASSERT_EQUAL(false, tri->testCornerInTetrahedron(TT::R)); + + // corner on XYZ facet (3 possibilities) + CPPUNIT_ASSERT_EQUAL(false, tri->testCornerOnXYZFacet(TT::P)); + CPPUNIT_ASSERT_EQUAL(false, tri->testCornerOnXYZFacet(TT::Q)); + CPPUNIT_ASSERT_EQUAL(false, tri->testCornerOnXYZFacet(TT::R)); + + // corner above XYZ facet (3 possibilities) + CPPUNIT_ASSERT_EQUAL(false, tri->testCornerAboveXYZFacet(TT::P)); + CPPUNIT_ASSERT_EQUAL(false, tri->testCornerAboveXYZFacet(TT::Q)); + CPPUNIT_ASSERT_EQUAL(false, tri->testCornerAboveXYZFacet(TT::R)); + + // segment-facet (9 possibilities) + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::PQ, TT::OZX)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::PQ, TT::OYZ)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::PQ, TT::OXY)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::PQ, TT::XYZ)); + + CPPUNIT_ASSERT_EQUAL(true , tri->testSegmentFacetIntersection(TT::QR, TT::OZX)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::QR, TT::OYZ)); + CPPUNIT_ASSERT_EQUAL(true , tri->testSegmentFacetIntersection(TT::QR, TT::OXY)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::QR, TT::XYZ)); + + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::RP, TT::OZX)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::RP, TT::OYZ)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::RP, TT::OXY)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::RP, TT::XYZ)); + // segment-edge (18 possibilities) + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::PQ, TT::OX) && tri->testSegmentEdgeIntersection(TT::PQ, TT::OX)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::PQ, TT::OY) && tri->testSegmentEdgeIntersection(TT::PQ, TT::OY)); + CPPUNIT_ASSERT_EQUAL(true , TEST_ZERO_DP_EDGE(TT::PQ, TT::OZ) && tri->testSegmentEdgeIntersection(TT::PQ, TT::OZ)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::PQ, TT::YZ) && tri->testSegmentEdgeIntersection(TT::PQ, TT::YZ)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::PQ, TT::ZX) && tri->testSegmentEdgeIntersection(TT::PQ, TT::ZX)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::PQ, TT::XY) && tri->testSegmentEdgeIntersection(TT::PQ, TT::XY)); + + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::QR, TT::OX) && tri->testSegmentEdgeIntersection(TT::QR, TT::OX)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::QR, TT::OY) && tri->testSegmentEdgeIntersection(TT::QR, TT::OY)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::QR, TT::OZ) && tri->testSegmentEdgeIntersection(TT::QR, TT::OZ)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::QR, TT::YZ) && tri->testSegmentEdgeIntersection(TT::QR, TT::YZ)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::QR, TT::ZX) && tri->testSegmentEdgeIntersection(TT::QR, TT::ZX)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::QR, TT::XY) && tri->testSegmentEdgeIntersection(TT::QR, TT::XY)); + + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::RP, TT::OX) && tri->testSegmentEdgeIntersection(TT::RP, TT::OX)); + CPPUNIT_ASSERT_EQUAL(true , TEST_ZERO_DP_EDGE(TT::RP, TT::OY) && tri->testSegmentEdgeIntersection(TT::RP, TT::OY)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::RP, TT::OZ) && tri->testSegmentEdgeIntersection(TT::RP, TT::OZ)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::RP, TT::YZ) && tri->testSegmentEdgeIntersection(TT::RP, TT::YZ)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::RP, TT::ZX) && tri->testSegmentEdgeIntersection(TT::RP, TT::ZX)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::RP, TT::XY) && tri->testSegmentEdgeIntersection(TT::RP, TT::XY)); + + // segment - corner (12 possibilities) + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::PQ, TT::O) && tri->testSegmentCornerIntersection(TT::PQ, TT::O)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::PQ, TT::X) && tri->testSegmentCornerIntersection(TT::PQ, TT::X)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::PQ, TT::Y) && tri->testSegmentCornerIntersection(TT::PQ, TT::Y)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::PQ, TT::Z) && tri->testSegmentCornerIntersection(TT::PQ, TT::Z)); + + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::QR, TT::O) && tri->testSegmentCornerIntersection(TT::QR, TT::O)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::QR, TT::X) && tri->testSegmentCornerIntersection(TT::QR, TT::X)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::QR, TT::Y) && tri->testSegmentCornerIntersection(TT::QR, TT::Y)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::QR, TT::Z) && tri->testSegmentCornerIntersection(TT::QR, TT::Z)); + + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::RP, TT::O) && tri->testSegmentCornerIntersection(TT::RP, TT::O)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::RP, TT::X) && tri->testSegmentCornerIntersection(TT::RP, TT::X)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::RP, TT::Y) && tri->testSegmentCornerIntersection(TT::RP, TT::Y)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::RP, TT::Z) && tri->testSegmentCornerIntersection(TT::RP, TT::Z)); + + // segment-halfstrip (9 possibilities) + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentHalfstripIntersection(TT::PQ, TT::YZ)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentHalfstripIntersection(TT::PQ, TT::ZX)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentHalfstripIntersection(TT::PQ, TT::XY)); + + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentHalfstripIntersection(TT::QR, TT::YZ)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentHalfstripIntersection(TT::QR, TT::ZX)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentHalfstripIntersection(TT::QR, TT::XY)); + + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentHalfstripIntersection(TT::RP, TT::YZ)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentHalfstripIntersection(TT::RP, TT::ZX)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentHalfstripIntersection(TT::RP, TT::XY)); + + // segment-ray (9 possibilities) + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_RAY(TT::PQ, TT::X) && tri->testSegmentRayIntersection(TT::PQ, TT::X)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_RAY(TT::PQ, TT::Y) && tri->testSegmentRayIntersection(TT::PQ, TT::Y)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_RAY(TT::PQ, TT::Z) && tri->testSegmentRayIntersection(TT::PQ, TT::Z)); + + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_RAY(TT::QR, TT::X) && tri->testSegmentRayIntersection(TT::QR, TT::X)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_RAY(TT::QR, TT::Y) && tri->testSegmentRayIntersection(TT::QR, TT::Y)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_RAY(TT::QR, TT::Z) && tri->testSegmentRayIntersection(TT::QR, TT::Z)); + + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_RAY(TT::RP, TT::X) && tri->testSegmentRayIntersection(TT::RP, TT::X)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_RAY(TT::RP, TT::Y) && tri->testSegmentRayIntersection(TT::RP, TT::Y)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_RAY(TT::RP, TT::Z) && tri->testSegmentRayIntersection(TT::RP, TT::Z)); + + // surface-edge (6 possibilities) + CPPUNIT_ASSERT_EQUAL(false, tri->testSurfaceEdgeIntersection(TT::OX)); + CPPUNIT_ASSERT_EQUAL(true , tri->testSurfaceEdgeIntersection(TT::OY)); + CPPUNIT_ASSERT_EQUAL(true , tri->testSurfaceEdgeIntersection(TT::OZ)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSurfaceEdgeIntersection(TT::YZ)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSurfaceEdgeIntersection(TT::ZX)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSurfaceEdgeIntersection(TT::XY)); + + // surface-ray (3 possibilities) + CPPUNIT_ASSERT_EQUAL(false, tri->testSurfaceRayIntersection(TT::X)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSurfaceRayIntersection(TT::Y)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSurfaceRayIntersection(TT::Z)); + + delete tri; + } + + + /// Triangle 13 has the following intersections + /// <PRE> + /// CI - + /// COH - + /// CAH - + /// SF (QR, OYZ), (PQ, OXY), (PQ, XYZ) + /// SE - + /// SC (QR, Z) + /// SHS (PQ, YZ) + /// SR - + /// TE [OZ, YZ, ZX] + /// TR - + /// </PRE> + /// \brief Status : pass + void TransformedTriangleIntersectTest::testTriangle13() + { + LOG(1, "+++++++ Testing triangle 13" ); + typedef TransformedTriangle TT; + + double coords[9] = + { + -0.2, 0.3, 5.0, // P + 0.2, 0.1, -1.0, // Q + -0.2, -0.1, 3.0 // R + }; + + TransformedTriangle* tri = new TransformedTriangle(&coords[0], &coords[3], &coords[6]); + + // run all intersection tests and ensure that the ones + // listed with yes in the tables above return true and + // that the ones listed with no or not listed at all return false + + bool isZero[TT::NO_TRI_SEGMENT * TT::NO_DP]; + + for(TriSegment seg = TT::PQ ; seg < TT::NO_TRI_SEGMENT ; seg = TT::TriSegment(seg + 1)) + { + // check beforehand which double-products are zero + for(DoubleProduct dp = TT::C_YZ; dp < TT::NO_DP; dp = DoubleProduct(dp + 1)) + { + isZero[TT::NO_DP*int(seg) + int(dp)] = (tri->calcStableC(seg, dp) == 0.0); + } + } + + // corner in tetrahedron (3 possibilities) + CPPUNIT_ASSERT_EQUAL(false, tri->testCornerInTetrahedron(TT::P)); + CPPUNIT_ASSERT_EQUAL(false, tri->testCornerInTetrahedron(TT::Q)); + CPPUNIT_ASSERT_EQUAL(false, tri->testCornerInTetrahedron(TT::R)); + + // corner on XYZ facet (3 possibilities) + CPPUNIT_ASSERT_EQUAL(false, tri->testCornerOnXYZFacet(TT::P)); + CPPUNIT_ASSERT_EQUAL(false, tri->testCornerOnXYZFacet(TT::Q)); + CPPUNIT_ASSERT_EQUAL(false, tri->testCornerOnXYZFacet(TT::R)); + + // corner above XYZ facet (3 possibilities) + CPPUNIT_ASSERT_EQUAL(false, tri->testCornerAboveXYZFacet(TT::P)); + CPPUNIT_ASSERT_EQUAL(false, tri->testCornerAboveXYZFacet(TT::Q)); + CPPUNIT_ASSERT_EQUAL(false, tri->testCornerAboveXYZFacet(TT::R)); + + // segment-facet (9 possibilities) + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::PQ, TT::OZX)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::PQ, TT::OYZ)); + CPPUNIT_ASSERT_EQUAL(true , tri->testSegmentFacetIntersection(TT::PQ, TT::OXY)); + CPPUNIT_ASSERT_EQUAL(true , tri->testSegmentFacetIntersection(TT::PQ, TT::XYZ)); + + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::QR, TT::OZX)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::QR, TT::OYZ)); + CPPUNIT_ASSERT_EQUAL(true , tri->testSegmentFacetIntersection(TT::QR, TT::OXY)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::QR, TT::XYZ)); + + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::RP, TT::OZX)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::RP, TT::OYZ)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::RP, TT::OXY)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::RP, TT::XYZ)); + + // segment-edge (18 possibilities) + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::PQ, TT::OX) && tri->testSegmentEdgeIntersection(TT::PQ, TT::OX)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::PQ, TT::OY) && tri->testSegmentEdgeIntersection(TT::PQ, TT::OY)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::PQ, TT::OZ) && tri->testSegmentEdgeIntersection(TT::PQ, TT::OZ)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::PQ, TT::YZ) && tri->testSegmentEdgeIntersection(TT::PQ, TT::YZ)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::PQ, TT::ZX) && tri->testSegmentEdgeIntersection(TT::PQ, TT::ZX)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::PQ, TT::XY) && tri->testSegmentEdgeIntersection(TT::PQ, TT::XY)); + + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::QR, TT::OX) && tri->testSegmentEdgeIntersection(TT::QR, TT::OX)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::QR, TT::OY) && tri->testSegmentEdgeIntersection(TT::QR, TT::OY)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::QR, TT::OZ) && tri->testSegmentEdgeIntersection(TT::QR, TT::OZ)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::QR, TT::YZ) && tri->testSegmentEdgeIntersection(TT::QR, TT::YZ)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::QR, TT::ZX) && tri->testSegmentEdgeIntersection(TT::QR, TT::ZX)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::QR, TT::XY) && tri->testSegmentEdgeIntersection(TT::QR, TT::XY)); + + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::RP, TT::OX) && tri->testSegmentEdgeIntersection(TT::RP, TT::OX)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::RP, TT::OY) && tri->testSegmentEdgeIntersection(TT::RP, TT::OY)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::RP, TT::OZ) && tri->testSegmentEdgeIntersection(TT::RP, TT::OZ)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::RP, TT::YZ) && tri->testSegmentEdgeIntersection(TT::RP, TT::YZ)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::RP, TT::ZX) && tri->testSegmentEdgeIntersection(TT::RP, TT::ZX)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_EDGE(TT::RP, TT::XY) && tri->testSegmentEdgeIntersection(TT::RP, TT::XY)); + + // segment - corner (12 possibilities) + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::PQ, TT::O) && tri->testSegmentCornerIntersection(TT::PQ, TT::O)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::PQ, TT::X) && tri->testSegmentCornerIntersection(TT::PQ, TT::X)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::PQ, TT::Y) && tri->testSegmentCornerIntersection(TT::PQ, TT::Y)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::PQ, TT::Z) && tri->testSegmentCornerIntersection(TT::PQ, TT::Z)); + + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::QR, TT::O) && tri->testSegmentCornerIntersection(TT::QR, TT::O)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::QR, TT::X) && tri->testSegmentCornerIntersection(TT::QR, TT::X)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::QR, TT::Y) && tri->testSegmentCornerIntersection(TT::QR, TT::Y)); + CPPUNIT_ASSERT_EQUAL(true , TEST_ZERO_DP_CORNER(TT::QR, TT::Z) && tri->testSegmentCornerIntersection(TT::QR, TT::Z)); + + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::RP, TT::O) && tri->testSegmentCornerIntersection(TT::RP, TT::O)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::RP, TT::X) && tri->testSegmentCornerIntersection(TT::RP, TT::X)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::RP, TT::Y) && tri->testSegmentCornerIntersection(TT::RP, TT::Y)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_CORNER(TT::RP, TT::Z) && tri->testSegmentCornerIntersection(TT::RP, TT::Z)); + + // segment-halfstrip (9 possibilities) + CPPUNIT_ASSERT_EQUAL(true , tri->testSegmentHalfstripIntersection(TT::PQ, TT::YZ)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentHalfstripIntersection(TT::PQ, TT::ZX)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentHalfstripIntersection(TT::PQ, TT::XY)); + + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentHalfstripIntersection(TT::QR, TT::YZ)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentHalfstripIntersection(TT::QR, TT::ZX)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentHalfstripIntersection(TT::QR, TT::XY)); + + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentHalfstripIntersection(TT::RP, TT::YZ)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentHalfstripIntersection(TT::RP, TT::ZX)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentHalfstripIntersection(TT::RP, TT::XY)); + + // segment-ray (9 possibilities) + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_RAY(TT::PQ, TT::X) && tri->testSegmentRayIntersection(TT::PQ, TT::X)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_RAY(TT::PQ, TT::Y) && tri->testSegmentRayIntersection(TT::PQ, TT::Y)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_RAY(TT::PQ, TT::Z) && tri->testSegmentRayIntersection(TT::PQ, TT::Z)); + + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_RAY(TT::QR, TT::X) && tri->testSegmentRayIntersection(TT::QR, TT::X)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_RAY(TT::QR, TT::Y) && tri->testSegmentRayIntersection(TT::QR, TT::Y)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_RAY(TT::QR, TT::Z) && tri->testSegmentRayIntersection(TT::QR, TT::Z)); + + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_RAY(TT::RP, TT::X) && tri->testSegmentRayIntersection(TT::RP, TT::X)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_RAY(TT::RP, TT::Y) && tri->testSegmentRayIntersection(TT::RP, TT::Y)); + CPPUNIT_ASSERT_EQUAL(false, TEST_ZERO_DP_RAY(TT::RP, TT::Z) && tri->testSegmentRayIntersection(TT::RP, TT::Z)); + + // surface-edge (6 possibilities) + CPPUNIT_ASSERT_EQUAL(false, tri->testSurfaceEdgeIntersection(TT::OX)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSurfaceEdgeIntersection(TT::OY)); + CPPUNIT_ASSERT_EQUAL(true , tri->testSurfaceEdgeIntersection(TT::OZ)); + CPPUNIT_ASSERT_EQUAL(true , tri->testSurfaceEdgeIntersection(TT::YZ)); + CPPUNIT_ASSERT_EQUAL(true , tri->testSurfaceEdgeIntersection(TT::ZX)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSurfaceEdgeIntersection(TT::XY)); + + // surface-ray (3 possibilities) + CPPUNIT_ASSERT_EQUAL(false, tri->testSurfaceRayIntersection(TT::X)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSurfaceRayIntersection(TT::Y)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSurfaceRayIntersection(TT::Z)); + + delete tri; + } + + +} // NAMESPACE + + + + + + + +///// TEMPLATE /////////////////////////////// + + + +#if 0 +// Triangle x has the following intersections +// CI - +// COH - +// CAH - +// SF - +// SE - +// SC - +// SHS - +// SR - +// TE - +// TR - + +void TransformedTriangleIntersectTest::testTriangleX() +{ + LOG(1, "+++++++ Testing triangle X" ); + typedef TransformedTriangle TT; + + double coords[9] = + { + 0.0, 0.0, 0.0, // P + 0.0, 0.0, 0.0, // Q + 0.0, 0.0, 0.0 // R + }; + + TransformedTriangle* tri = new TransformedTriangle(&coords[0], &coords[3], &coords[6]); + + // run all intersection tests and ensure that the ones + // listed with yes in the tables above return true and + // that the ones listed with no or not listed at all return false + + // corner in tetrahedron (3 possibilities) + CPPUNIT_ASSERT_EQUAL(false, tri->testCornerInTetrahedron(TT::P)); + CPPUNIT_ASSERT_EQUAL(false, tri->testCornerInTetrahedron(TT::Q)); + CPPUNIT_ASSERT_EQUAL(false, tri->testCornerInTetrahedron(TT::R)); + + // corner on XYZ facet (3 possibilities) + CPPUNIT_ASSERT_EQUAL(false, tri->testCornerOnXYZFacet(TT::P)); + CPPUNIT_ASSERT_EQUAL(false, tri->testCornerOnXYZFacet(TT::Q)); + CPPUNIT_ASSERT_EQUAL(false, tri->testCornerOnXYZFacet(TT::R)); + + // corner above XYZ facet (3 possibilities) + CPPUNIT_ASSERT_EQUAL(false, tri->testCornerAboveXYZFacet(TT::P)); + CPPUNIT_ASSERT_EQUAL(false, tri->testCornerAboveXYZFacet(TT::Q)); + CPPUNIT_ASSERT_EQUAL(false, tri->testCornerAboveXYZFacet(TT::R)); + + // segment-facet (9 possibilities) + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::PQ, TT::OZX)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::PQ, TT::OYZ)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::PQ, TT::OXY)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::PQ, TT::XYZ)); + + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::QR, TT::OZX)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::QR, TT::OYZ)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::QR, TT::OXY)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::QR, TT::XYZ)); + + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::RP, TT::OZX)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::RP, TT::OYZ)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::RP, TT::OXY)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentFacetIntersection(TT::RP, TT::XYZ)); + + // segment-edge (18 possibilities) + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentEdgeIntersection(TT::PQ, TT::OX)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentEdgeIntersection(TT::PQ, TT::OY)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentEdgeIntersection(TT::PQ, TT::OZ)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentEdgeIntersection(TT::PQ, TT::YZ)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentEdgeIntersection(TT::PQ, TT::ZX)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentEdgeIntersection(TT::PQ, TT::XY)); + + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentEdgeIntersection(TT::QR, TT::OX)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentEdgeIntersection(TT::QR, TT::OY)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentEdgeIntersection(TT::QR, TT::OZ)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentEdgeIntersection(TT::QR, TT::YZ)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentEdgeIntersection(TT::QR, TT::ZX)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentEdgeIntersection(TT::QR, TT::XY)); + + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentEdgeIntersection(TT::RP, TT::OX)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentEdgeIntersection(TT::RP, TT::OY)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentEdgeIntersection(TT::RP, TT::OZ)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentEdgeIntersection(TT::RP, TT::YZ)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentEdgeIntersection(TT::RP, TT::ZX)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentEdgeIntersection(TT::RP, TT::XY)); + + // segment - corner (12 possibilities) + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentCornerIntersection(TT::PQ, TT::O)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentCornerIntersection(TT::PQ, TT::X)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentCornerIntersection(TT::PQ, TT::Y)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentCornerIntersection(TT::PQ, TT::Z)); + + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentCornerIntersection(TT::QR, TT::O)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentCornerIntersection(TT::QR, TT::X)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentCornerIntersection(TT::QR, TT::Y)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentCornerIntersection(TT::QR, TT::Z)); + + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentCornerIntersection(TT::RP, TT::O)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentCornerIntersection(TT::RP, TT::X)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentCornerIntersection(TT::RP, TT::Y)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentCornerIntersection(TT::RP, TT::Z)); + + // segment-halfstrip (9 possibilities) + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentHalfstripIntersection(TT::PQ, TT::YZ)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentHalfstripIntersection(TT::PQ, TT::ZX)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentHalfstripIntersection(TT::PQ, TT::XY)); + + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentHalfstripIntersection(TT::QR, TT::YZ)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentHalfstripIntersection(TT::QR, TT::ZX)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentHalfstripIntersection(TT::QR, TT::XY)); + + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentHalfstripIntersection(TT::RP, TT::YZ)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentHalfstripIntersection(TT::RP, TT::ZX)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentHalfstripIntersection(TT::RP, TT::XY)); + + // segment-ray (9 possibilities) + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentRayIntersection(TT::PQ, TT::X)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentRayIntersection(TT::PQ, TT::Y)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentRayIntersection(TT::PQ, TT::Z)); + + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentRayIntersection(TT::QR, TT::X)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentRayIntersection(TT::QR, TT::Y)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentRayIntersection(TT::QR, TT::Z)); + + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentRayIntersection(TT::RP, TT::X)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentRayIntersection(TT::RP, TT::Y)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSegmentRayIntersection(TT::RP, TT::Z)); + + // surface-edge (6 possibilities) + CPPUNIT_ASSERT_EQUAL(false, tri->testSurfaceEdgeIntersection(TT::OX)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSurfaceEdgeIntersection(TT::OY)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSurfaceEdgeIntersection(TT::OZ)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSurfaceEdgeIntersection(TT::YZ)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSurfaceEdgeIntersection(TT::ZX)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSurfaceEdgeIntersection(TT::XY)); + + // surface-ray (3 possibilities) + CPPUNIT_ASSERT_EQUAL(false, tri->testSurfaceRayIntersection(TT::X)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSurfaceRayIntersection(TT::Y)); + CPPUNIT_ASSERT_EQUAL(false, tri->testSurfaceRayIntersection(TT::Z)); + + delete tri; +} +#endif diff --git a/src/medtool/src/INTERP_KERNELTest/TransformedTriangleIntersectTest.hxx b/src/medtool/src/INTERP_KERNELTest/TransformedTriangleIntersectTest.hxx new file mode 100644 index 000000000..8ff1196d9 --- /dev/null +++ b/src/medtool/src/INTERP_KERNELTest/TransformedTriangleIntersectTest.hxx @@ -0,0 +1,94 @@ +// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 +// 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 __TU_TRANSFORMED_TRIANGLE_INTERSECT_HXX__ +#define __TU_TRANSFORMED_TRIANGLE_INTERSECT_HXX__ + +#include <cppunit/extensions/HelperMacros.h> + +#include "InterpKernelTestExport.hxx" +#include "TransformedTriangle.hxx" + +namespace INTERP_TEST +{ + + class INTERPKERNELTEST_EXPORT TransformedTriangleIntersectTest : public CppUnit::TestFixture + { + + CPPUNIT_TEST_SUITE( TransformedTriangleIntersectTest ); + + CPPUNIT_TEST( testTriangle1 ); + CPPUNIT_TEST( testTriangle2 ); + CPPUNIT_TEST( testTriangle3 ); + CPPUNIT_TEST( testTriangle4 ); + CPPUNIT_TEST( testTriangle5 ); + CPPUNIT_TEST( testTriangle6 ); + CPPUNIT_TEST( testTriangle7 ); + CPPUNIT_TEST( testTriangle8 ); + CPPUNIT_TEST( testTriangle9 ); + CPPUNIT_TEST( testTriangle10 ); + CPPUNIT_TEST( testTriangle11 ); + CPPUNIT_TEST( testTriangle12 ); + CPPUNIT_TEST( testTriangle13 ); + + CPPUNIT_TEST_SUITE_END(); + + typedef INTERP_KERNEL::TransformedTriangle::TriSegment TriSegment; + typedef INTERP_KERNEL::TransformedTriangle::DoubleProduct DoubleProduct; + + public: + + void testTriangle1(); + + void testTriangle2(); + + void testTriangle3(); + + void testTriangle4(); + + void testTriangle5(); + + void testTriangle6(); + + void testTriangle7(); + + void testTriangle8(); + + void testTriangle9(); + + void testTriangle10(); + + void testTriangle11(); + + void testTriangle12(); + + void testTriangle13(); + + private: + + }; + +} + + + + + + +#endif diff --git a/src/medtool/src/INTERP_KERNELTest/TransformedTriangleTest.cxx b/src/medtool/src/INTERP_KERNELTest/TransformedTriangleTest.cxx new file mode 100644 index 000000000..ee4eb20c2 --- /dev/null +++ b/src/medtool/src/INTERP_KERNELTest/TransformedTriangleTest.cxx @@ -0,0 +1,355 @@ +// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// + +#include "TransformedTriangleTest.hxx" + +#include <iostream> + +using namespace INTERP_KERNEL; + +namespace INTERP_TEST +{ + + /** + * Creates the TransformedTriangle objects used by the tests. + * + */ + void TransformedTriangleTest::setUp() + { + // tri1 -> no unstable double products - no changes brought about by preCalculateDoubleProducts + // this allows the testing of calcUnstableT + // tri2 -> unstable double products - for testing calcStableC / preCalculateDoubleProducts + + // triangle to test unstable C and T calculations + p1[0] = -1.5 ; p1[1] = 0.5; p1[2] = 0.5; + q1[0] = 2.0 ; q1[1] = 0.4; q1[2] = 0.6; + r1[0] = 1.0 ; r1[1] = 2.4; r1[2] = 1.2; + hp1 = 1 - p1[0] - p1[1] - p1[2]; + hq1 = 1 - q1[0] - q1[1] - q1[2]; + hr1 = 1 - r1[0] - r1[1] - r1[2]; + Hp1 = 1 - p1[0] - p1[1]; + Hq1 = 1 - q1[0] - q1[1]; + Hr1 = 1 - r1[0] - r1[1]; + + // std::cout <<std::endl<< "constructing tri1..." << std::endl; + tri1 = new TransformedTriangle(p1, q1, r1); + + + // triangle to test stable C calculation + const double err = 1.5e-3; + + p2[0] = 0.000000000084654984189118; p2[1] = -0.000000000000000027536546231654231688873; p2[2] = 0.0000000000000001649875466831349431; + q2[0] = -p2[0] +err; q2[1] = -p2[1] + err; q2[2] = -p2[2] +err; + r2[0] = 2.01 ; r2[1] = 1.8; r2[2] = 0.92; + + hp2 = 1 - p2[0] - p2[1] - p2[2]; + hq2 = 1 - q2[0] - q2[1] - q2[2]; + hr2 = 1 - r2[0] - r2[1] - r2[2]; + Hp2 = 1 - p2[0] - p2[1]; + Hq2 = 1 - q2[0] - q2[1]; + Hr2 = 1 - r2[0] - r2[1]; + + tri2 = new TransformedTriangle(p2, q2, r2); + + + + } + + /** + * Liberates the transformed triangle objects used by the test suite + * + */ + void TransformedTriangleTest::tearDown() + { + delete tri1; + delete tri2; + } + + /// Tests that _coords has correct values after construction of object is finished + /// \brief Status : pass + void TransformedTriangleTest::test_constructor() { + // test that _coords has correct values after constructor is called + + double good_values1[15] = + { + p1[0], p1[1], p1[2], hp1, Hp1, + q1[0], q1[1], q1[2], hq1, Hq1, + r1[0], r1[1], r1[2], hr1, Hr1 + }; + + double good_values2[15] = + { + p2[0], p2[1], p2[2], hp2, Hp2, + q2[0], q2[1], q2[2], hq2, Hq2, + r2[0], r2[1], r2[2], hr2, Hr2 + }; + + + for(int i = 0 ; i < 15 ; ++i) + { + CPPUNIT_ASSERT_DOUBLES_EQUAL(good_values1[i], tri1->_coords[i], ERR_TOL); + CPPUNIT_ASSERT_DOUBLES_EQUAL(good_values2[i], tri2->_coords[i], ERR_TOL); + } + + CPPUNIT_ASSERT_EQUAL(true, tri1->_is_double_products_calculated); + CPPUNIT_ASSERT_EQUAL(true, tri2->_is_double_products_calculated); + } + + /// Tests the calculation of double products (without the corrections) + /// \brief Status : pass + void TransformedTriangleTest::test_calcUnstableC() { + typedef TransformedTriangle::TriSegment TriSegment; + + // test that the correct c-values are calculated + + double correct_c_vals[24] = + { + p1[0] * q1[1] - p1[1] * q1[0], + p1[1] * q1[2] - p1[2] * q1[1], + p1[2] * q1[0] - p1[0] * q1[2], + p1[0] * hq1 - hp1 * q1[0], + p1[1] * hq1 - hp1 * q1[1], + p1[2] * hq1 - hp1 * q1[2], + Hp1 * q1[0] - p1[0] * Hq1, + p1[1] * Hq1 - Hp1 * q1[1], + q1[0] * r1[1] - q1[1] * r1[0], + q1[1] * r1[2] - q1[2] * r1[1], + q1[2] * r1[0] - q1[0] * r1[2], + q1[0] * hr1 - hq1 * r1[0], + q1[1] * hr1 - hq1 * r1[1], + q1[2] * hr1 - hq1 * r1[2], + Hq1 * r1[0] - q1[0] * Hr1, + q1[1] * Hr1 - Hq1 * r1[1], + r1[0]*p1[1]-r1[1]*p1[0], + r1[1]*p1[2]-r1[2]*p1[1], + r1[2]*p1[0]-r1[0]*p1[2], + r1[0] * hp1 - hr1 * p1[0], + r1[1] * hp1 - hr1 * p1[1], + r1[2] * hp1 - hr1 * p1[2], + Hr1 * p1[0] - r1[0] * Hp1, + r1[1] * Hp1 - Hr1 * p1[1] + }; + + double c_vals[3 * 8]; + for(TriSegment seg = TransformedTriangle::PQ ; seg <= TransformedTriangle::RP ; seg = TriSegment(seg + 1)) { + + c_vals[seg*8 + 0] = tri1->calcUnstableC(seg, TransformedTriangle::C_XY); + c_vals[seg*8 + 1] = tri1->calcUnstableC(seg, TransformedTriangle::C_YZ); + c_vals[seg*8 + 2] = tri1->calcUnstableC(seg, TransformedTriangle::C_ZX); + c_vals[seg*8 + 3] = tri1->calcUnstableC(seg, TransformedTriangle::C_XH); + c_vals[seg*8 + 4] = tri1->calcUnstableC(seg, TransformedTriangle::C_YH); + c_vals[seg*8 + 5] = tri1->calcUnstableC(seg, TransformedTriangle::C_ZH); + c_vals[seg*8 + 6] = tri1->calcUnstableC(seg, TransformedTriangle::C_01); + c_vals[seg*8 + 7] = tri1->calcUnstableC(seg, TransformedTriangle::C_10); + + } + + for(int i = 0 ; i < 3*8 ; ++i) { + CPPUNIT_ASSERT_DOUBLES_EQUAL( correct_c_vals[i], c_vals[i], ERR_TOL ); + } + + + } + + /// Tests the calculation of triple products (without corrections) + /// \brief Status : pass + void TransformedTriangleTest::test_calcUnstableT() + { + typedef TransformedTriangle::TetraCorner TetraCorner; + + // correct values calculated by determinants (Grandy, [15]) + const double correct_t_vals[4] = + { + p1[0]*(q1[1]*r1[2] - q1[2]*r1[1]) - + q1[0]*(p1[1]*r1[2] - p1[2]*r1[1]) + + r1[0]*(p1[1]*q1[2] - p1[2]*q1[1]), + + -(hp1*(q1[1]*r1[2] - q1[2]*r1[1]) - + hq1*(p1[1]*r1[2] - p1[2]*r1[1]) + + hr1*(p1[1]*q1[2] - p1[2]*q1[1])), + + -(p1[0]*(hq1*r1[2] - q1[2]*hr1) - + q1[0]*(hp1*r1[2] - p1[2]*hr1) + + r1[0]*(hp1*q1[2] - p1[2]*hq1)), + + -(p1[0]*(q1[1]*hr1 - r1[1]*hq1) - + q1[0]*(p1[1]*hr1 - r1[1]*hp1) + + r1[0]*(p1[1]*hq1 - q1[1]*hp1)) + }; + + + // test that triple products are correctly calculated + for(TetraCorner corner = TransformedTriangle::O ; corner <= TransformedTriangle::Z ; corner = TetraCorner(corner + 1)) + { + + for(int row = 1 ; row < 4 ; ++row) + { + const double t = tri1->calcTByDevelopingRow(corner, row, false); + // std::cout << std::endl << " Corner = " << corner << " Row = " << row << " got: " << t << + // " expected: " << correct_t_vals[corner]<< std::endl; + CPPUNIT_ASSERT_DOUBLES_EQUAL(correct_t_vals[corner], t, ERR_TOL); + } + } + } + + /// Tests the consistency correction + /// \brief Status : fails because it is not significant - the consistency correction is not brought into play + void TransformedTriangleTest::test_calcStableC_Consistency() + { + + typedef TransformedTriangle::TriSegment TriSegment; + typedef TransformedTriangle::TetraCorner TetraCorner; + + // grandy, eq 14 + double correct_c_vals[24] = + { + p2[0] * q2[1] - p2[1] * q2[0], + p2[1] * q2[2] - p2[2] * q2[1], + p2[2] * q2[0] - p2[0] * q2[2], + p2[0] * hq2 - hp2 * q2[0], + p2[1] * hq2 - hp2 * q2[1], + p2[2] * hq2 - hp2 * q2[2], + Hp2 * q2[0] - p2[0] * Hq2, + p2[1] * Hq2 - Hp2 * q2[1], + q2[0] * r2[1] - q2[1] * r2[0], + q2[1] * r2[2] - q2[2] * r2[1], + q2[2] * r2[0] - q2[0] * r2[2], + q2[0] * hr2 - hq2 * r2[0], + q2[1] * hr2 - hq2 * r2[1], + q2[2] * hr2 - hq2 * r2[2], + Hq2 * r2[0] - q2[0] * Hr2, + q2[1] * Hr2 - Hq2 * r2[1], + r2[0]*p2[1]-r2[1]*p2[0], + r2[1]*p2[2]-r2[2]*p2[1], + r2[2]*p2[0]-r2[0]*p2[2], + r2[0] * hp2 - hr2 * p2[0], + r2[1] * hp2 - hr2 * p2[1], + r2[2] * hp2 - hr2 * p2[2], + Hr2 * p2[0] - r2[0] * Hp2, + r2[1] * Hp2 - Hr2 * p2[1] + }; + + + // number of inconsistent cases found : + // should be (at least) 1 for the test to be meaningful + int num_cases = 0; + + // find unstable products to check for consistency (Grandy [46]) + for(TriSegment seg = TransformedTriangle::PQ ; seg <= TransformedTriangle::RP ; seg = TriSegment(seg + 1)) + { + const double c_xy = tri2->calcUnstableC(seg, TransformedTriangle::C_XY); + const double c_yz = tri2->calcUnstableC(seg, TransformedTriangle::C_YZ); + const double c_zx = tri2->calcUnstableC(seg, TransformedTriangle::C_ZX); + const double c_xh = tri2->calcUnstableC(seg, TransformedTriangle::C_XH); + const double c_yh = tri2->calcUnstableC(seg, TransformedTriangle::C_YH); + const double c_zh = tri2->calcUnstableC(seg, TransformedTriangle::C_ZH); + + const int num_zero = (c_yz*c_xh == 0.0 ? 1 : 0) + (c_zx*c_yh == 0.0 ? 1 : 0) + (c_xy*c_zh == 0.0 ? 1 : 0); + const int num_neg = (c_yz*c_xh < 0.0 ? 1 : 0) + (c_zx*c_yh < 0.0 ? 1 : 0) + (c_xy*c_zh < 0.0 ? 1 : 0); + + if((num_zero == 1 && num_neg != 1) || num_zero == 2 || num_neg == 0 && num_zero !=3 || num_neg == 3 ) + { + ++num_cases; + + double min_dist = -1.0; // initialised first time through loop + TetraCorner min_corner = TransformedTriangle::O; + + for(TetraCorner corner = TransformedTriangle::O ; corner <= TransformedTriangle::Z ; corner = TetraCorner(corner + 1)) + { + // calculate distance from each corner of tetraeder to the segment + // formula : ( (Q-P) x (P - corner) )^2 / norm(Q-P)^2 + + const double ptP[3] = { tri2->_coords[5*seg], tri2->_coords[5*seg + 1], tri2->_coords[5*seg + 2] }; + const double ptQ[3] = { tri2->_coords[5*( (seg+1) % 3)], tri2->_coords[5*( (seg+1) % 3) + 1], tri2->_coords[5*( (seg+1) % 3) + 2] }; + const double ptCorner[3] = { + corner == TransformedTriangle::X ? 1.0 : 0.0, + corner == TransformedTriangle::Y ? 1.0 : 0.0, + corner == TransformedTriangle::Z ? 1.0 : 0.0, + }; + + const double diff_21[3] = { ptQ[0] - ptP[0], ptQ[1] - ptP[1], ptQ[2] - ptP[2] }; + const double diff_1_corner[3] = { ptP[0] - ptCorner[0], ptP[1] - ptCorner[1], ptP[2] - ptCorner[2] }; + + const double cross[3] = { + diff_21[1]*diff_1_corner[2] - diff_21[2]*diff_1_corner[1], + diff_21[2]*diff_1_corner[0] - diff_21[0]*diff_1_corner[2], + diff_21[0]*diff_1_corner[1] - diff_21[1]*diff_1_corner[0] + }; + + const double cross_sq = cross[0]*cross[0] + cross[1]*cross[1] + cross[2]*cross[2]; + + const double norm_pq = diff_21[0]*diff_21[0] + diff_21[1]*diff_21[1] + diff_21[2]*diff_21[2]; + + if(corner == TransformedTriangle::O || (cross_sq / norm_pq) < min_dist) + { + min_dist = cross_sq / norm_pq; + min_corner = corner; + } + } + + // now check if the corresponding double products are zero + static const DoubleProduct DOUBLE_PRODUCTS[12] = + { + TransformedTriangle::C_YZ, TransformedTriangle::C_XY, TransformedTriangle::C_ZX, // O + TransformedTriangle::C_ZH, TransformedTriangle::C_YZ, TransformedTriangle::C_YH, // X + TransformedTriangle::C_ZH, TransformedTriangle::C_ZX, TransformedTriangle::C_XH, // Y + TransformedTriangle::C_XY, TransformedTriangle::C_YH, TransformedTriangle::C_XH // Z + }; + + for(int i = 0; i < 3 ; ++i) + { + DoubleProduct dp = DOUBLE_PRODUCTS[3*min_corner + i]; + // std::cout << std::endl << "in test inconsistent (seg,dp) :(" << seg <<", " << dp << ")" << std::endl; + CPPUNIT_ASSERT_EQUAL(0.0, tri2->calcStableC(seg, dp)); + correct_c_vals[8*seg + dp] = 0.0; + } + } + + } + + if(num_cases < 1) + { + CPPUNIT_FAIL("Consistency test not pertinent"); + } + + // std::cout << std::endl << "Number of geometric inconsistencies : " << num_cases << std::endl; + + // check that all other double products have right value too + double c_vals[8*3]; + + for(TriSegment seg = TransformedTriangle::PQ ; seg <= TransformedTriangle::RP ; seg = TriSegment(seg + 1)) { + + c_vals[seg*8 + 0] = tri2->calcStableC(seg, TransformedTriangle::C_XY); + c_vals[seg*8 + 1] = tri2->calcStableC(seg, TransformedTriangle::C_YZ); + c_vals[seg*8 + 2] = tri2->calcStableC(seg, TransformedTriangle::C_ZX); + c_vals[seg*8 + 3] = tri2->calcStableC(seg, TransformedTriangle::C_XH); + c_vals[seg*8 + 4] = tri2->calcStableC(seg, TransformedTriangle::C_YH); + c_vals[seg*8 + 5] = tri2->calcStableC(seg, TransformedTriangle::C_ZH); + c_vals[seg*8 + 6] = tri2->calcStableC(seg, TransformedTriangle::C_01); + c_vals[seg*8 + 7] = tri2->calcStableC(seg, TransformedTriangle::C_10); + + } + + for(int i = 0 ; i < 24 ; ++i) + { + CPPUNIT_ASSERT_DOUBLES_EQUAL(correct_c_vals[i], c_vals[i], ERR_TOL); + } + } + +} diff --git a/src/medtool/src/INTERP_KERNELTest/TransformedTriangleTest.hxx b/src/medtool/src/INTERP_KERNELTest/TransformedTriangleTest.hxx new file mode 100644 index 000000000..064f4059c --- /dev/null +++ b/src/medtool/src/INTERP_KERNELTest/TransformedTriangleTest.hxx @@ -0,0 +1,88 @@ +// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 +// 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 __TU_TRANSFORMED_TRIANGLE_HXX__ +#define __TU_TRANSFORMED_TRIANGLE_HXX__ + +#include <cppunit/extensions/HelperMacros.h> + +#include "InterpKernelTestExport.hxx" +#include "TransformedTriangle.hxx" + +#define ERR_TOL 1.0e-8 + +namespace INTERP_TEST +{ + + /** + * \brief Test suite testing some of the low level methods of TransformedTriangle. + * + */ + class INTERPKERNELTEST_EXPORT TransformedTriangleTest : public CppUnit::TestFixture + { + + CPPUNIT_TEST_SUITE( TransformedTriangleTest ); + CPPUNIT_TEST( test_constructor ); + CPPUNIT_TEST( test_calcUnstableC ); + CPPUNIT_TEST( test_calcUnstableT ); + //removed because the test fails to enter the desired code branch + // CPPUNIT_TEST( test_calcStableC_Consistency ); + CPPUNIT_TEST_SUITE_END(); + + typedef INTERP_KERNEL::TransformedTriangle::TriSegment TriSegment; + typedef INTERP_KERNEL::TransformedTriangle::DoubleProduct DoubleProduct; + + public: + void setUp(); + + void tearDown(); + + // tests + void test_constructor(); + + void test_calcUnstableC(); + + void test_calcUnstableT(); + + void test_calcStableC_Consistency(); + + double p1[3], q1[3], r1[3]; + double hp1, hq1, hr1; + double Hp1, Hq1, Hr1; + + double p2[3], q2[3], r2[3]; + double hp2, hq2, hr2; + double Hp2, Hq2, Hr2; + + double stable_c2[24]; + + private: + INTERP_KERNEL::TransformedTriangle* tri1; + INTERP_KERNEL::TransformedTriangle* tri2; + + }; + + + + +} + + + +#endif diff --git a/src/medtool/src/INTERP_KERNELTest/UnitTetra3D2DIntersectionTest.cxx b/src/medtool/src/INTERP_KERNELTest/UnitTetra3D2DIntersectionTest.cxx new file mode 100644 index 000000000..031becc04 --- /dev/null +++ b/src/medtool/src/INTERP_KERNELTest/UnitTetra3D2DIntersectionTest.cxx @@ -0,0 +1,176 @@ +// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// + +#include "UnitTetra3D2DIntersectionTest.hxx" + +#include "TetraAffineTransform.hxx" +#include "InterpolationUtils.hxx" +#include "SplitterTetra.txx" + +#include <iostream> + +using namespace INTERP_KERNEL; + +namespace INTERP_TEST +{ + struct __MESH_DUMMY + { + typedef int MyConnType; + static const int MY_SPACEDIM=3; + }; + + static SplitterTetra<__MESH_DUMMY>* buildSplitterTetra() + { + const int conn[4] = { 0,1,2,3 }; + + const double targetCoords[] = { -20., 0.,10., + -20.,10.,10., + -12., 0.,10., + -20., 0.,18. }; + + const double* tetraCoords[]={ targetCoords, targetCoords+3, targetCoords+6, targetCoords+9 }; + + __MESH_DUMMY dummyMesh; + SplitterTetra<__MESH_DUMMY>* targetTetra = new SplitterTetra<__MESH_DUMMY>( dummyMesh, tetraCoords, conn ); + return targetTetra; + } + + void UnitTetra3D2DIntersectionTest::test_UnitTetra3D2DIntersection_1() + { + const int conn[4] = { 0,1,2 }; + + const double sourceCoords[] = { -20., 0., 10., + -12., 0., 10., + -20.,10., 10. }; + + SplitterTetra<__MESH_DUMMY>* targetTetra = buildSplitterTetra(); + const double dimCaracteristic = 1.; + const double precision = 1.e-12; + std::multiset<TriangleFaceKey> listOfTetraFacesTreated; + std::set<TriangleFaceKey> listOfTetraFacesColinear; + + const double* sourceTriCoords[] = { sourceCoords, sourceCoords+3, sourceCoords+6 }; + double surface = targetTetra->intersectSourceFace(NORM_TRI3, + 3, + conn, + sourceTriCoords, + dimCaracteristic, + precision, + listOfTetraFacesTreated, + listOfTetraFacesColinear); + delete targetTetra; + CPPUNIT_ASSERT_DOUBLES_EQUAL(40.,surface,precision); + + CPPUNIT_ASSERT_EQUAL(4,(int)listOfTetraFacesTreated.size()); + std::multiset<TriangleFaceKey> correctListOfTetraFacesTreated; + TriangleFaceKey key1 = TriangleFaceKey(0, 1, 2); + correctListOfTetraFacesTreated.insert(key1); + TriangleFaceKey key2 = TriangleFaceKey(0, 1, 3); + correctListOfTetraFacesTreated.insert(key2); + TriangleFaceKey key3 = TriangleFaceKey(0, 2, 3); + correctListOfTetraFacesTreated.insert(key3); + TriangleFaceKey key4 = TriangleFaceKey(1, 2, 3); + correctListOfTetraFacesTreated.insert(key4); + CPPUNIT_ASSERT(correctListOfTetraFacesTreated == listOfTetraFacesTreated); + + CPPUNIT_ASSERT_EQUAL(1,(int)listOfTetraFacesColinear.size()); + std::set<TriangleFaceKey> correctListOfTetraFacesColinear; + correctListOfTetraFacesColinear.insert(key1); + CPPUNIT_ASSERT(correctListOfTetraFacesColinear == listOfTetraFacesColinear); + + } + + void UnitTetra3D2DIntersectionTest::test_UnitTetra3D2DIntersection_2() + { + const int conn[4] = { 0,1,2,3 }; + + const double sourceCoords[] = { -20., 0., 10., + -12., 0., 10., + -12.,10., 10., + -20.,10., 10. }; + + SplitterTetra<__MESH_DUMMY>* targetTetra = buildSplitterTetra(); + const double dimCaracteristic = 1.; + const double precision = 1.e-12; + std::multiset<TriangleFaceKey> listOfTetraFacesTreated; + std::set<TriangleFaceKey> listOfTetraFacesColinear; + + const double* sourceQuadCoords[] = { sourceCoords, sourceCoords+3, sourceCoords+6, sourceCoords+9 }; + double surface = targetTetra->intersectSourceFace(NORM_QUAD4, + 4, + conn, + sourceQuadCoords, + dimCaracteristic, + precision, + listOfTetraFacesTreated, + listOfTetraFacesColinear); + delete targetTetra; + CPPUNIT_ASSERT_DOUBLES_EQUAL(40.,surface,precision); + + CPPUNIT_ASSERT_EQUAL(4,(int)listOfTetraFacesTreated.size()); + std::multiset<TriangleFaceKey> correctListOfTetraFacesTreated; + TriangleFaceKey key1 = TriangleFaceKey(0, 1, 2); + correctListOfTetraFacesTreated.insert(key1); + TriangleFaceKey key2 = TriangleFaceKey(0, 1, 3); + correctListOfTetraFacesTreated.insert(key2); + TriangleFaceKey key3 = TriangleFaceKey(0, 2, 3); + correctListOfTetraFacesTreated.insert(key3); + TriangleFaceKey key4 = TriangleFaceKey(1, 2, 3); + correctListOfTetraFacesTreated.insert(key4); + CPPUNIT_ASSERT(correctListOfTetraFacesTreated == listOfTetraFacesTreated); + + CPPUNIT_ASSERT_EQUAL(1,(int)listOfTetraFacesColinear.size()); + std::set<TriangleFaceKey> correctListOfTetraFacesColinear; + correctListOfTetraFacesColinear.insert(key1); + CPPUNIT_ASSERT(correctListOfTetraFacesColinear == listOfTetraFacesColinear); + + } + + void UnitTetra3D2DIntersectionTest::test_UnitTetra3D2DIntersection_3() + { + const int conn[4] = { 0,1,2 }; + + const double sourceCoords[] = { -20., 0., 16., + -18., 0., 16., + -20.,2.5, 16. }; + + SplitterTetra<__MESH_DUMMY>* targetTetra = buildSplitterTetra(); + const double dimCaracteristic = 1.; + const double precision = 1.e-12; + std::multiset<TriangleFaceKey> listOfTetraFacesTreated; + std::set<TriangleFaceKey> listOfTetraFacesColinear; + + const double* sourceTri2Coords[] = { sourceCoords, sourceCoords+3, sourceCoords+6 }; + double surface = targetTetra->intersectSourceFace(NORM_TRI3, + 3, + conn, + sourceTri2Coords, + dimCaracteristic, + precision, + listOfTetraFacesTreated, + listOfTetraFacesColinear); + delete targetTetra; + CPPUNIT_ASSERT_DOUBLES_EQUAL(2.5,surface,precision); + + CPPUNIT_ASSERT_EQUAL(0,(int)listOfTetraFacesTreated.size()); + + CPPUNIT_ASSERT_EQUAL(0,(int)listOfTetraFacesColinear.size()); + } + +} diff --git a/src/medtool/src/INTERP_KERNELTest/UnitTetra3D2DIntersectionTest.hxx b/src/medtool/src/INTERP_KERNELTest/UnitTetra3D2DIntersectionTest.hxx new file mode 100644 index 000000000..7ccc1219e --- /dev/null +++ b/src/medtool/src/INTERP_KERNELTest/UnitTetra3D2DIntersectionTest.hxx @@ -0,0 +1,47 @@ +// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 +// 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 __UNITTETRA3D2DINTERSECTIONTEST_HXX__ +#define __UNITTETRA3D2DINTERSECTIONTEST_HXX__ + +#include <cppunit/extensions/HelperMacros.h> + +#include "InterpKernelTestExport.hxx" + +namespace INTERP_TEST +{ + /** + * \brief Test suite testing UnitTetra3D2DIntersection class. + * + */ + class INTERPKERNELTEST_EXPORT UnitTetra3D2DIntersectionTest : public CppUnit::TestFixture + { + CPPUNIT_TEST_SUITE( UnitTetra3D2DIntersectionTest ); + CPPUNIT_TEST( test_UnitTetra3D2DIntersection_1 ); + CPPUNIT_TEST( test_UnitTetra3D2DIntersection_2 ); + CPPUNIT_TEST( test_UnitTetra3D2DIntersection_3 ); + CPPUNIT_TEST_SUITE_END(); + public: + void test_UnitTetra3D2DIntersection_1(); + void test_UnitTetra3D2DIntersection_2(); + void test_UnitTetra3D2DIntersection_3(); + }; +} + +#endif diff --git a/src/medtool/src/INTERP_KERNELTest/UnitTetraIntersectionBaryTest.cxx b/src/medtool/src/INTERP_KERNELTest/UnitTetraIntersectionBaryTest.cxx new file mode 100644 index 000000000..d901f218a --- /dev/null +++ b/src/medtool/src/INTERP_KERNELTest/UnitTetraIntersectionBaryTest.cxx @@ -0,0 +1,346 @@ +// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 +// 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 +// + +// File : UnitTetraIntersectionBaryTest.cxx +// Created : Thu Dec 11 15:54:41 2008 +// Author : Edward AGAPOV (eap) +// +#include "UnitTetraIntersectionBaryTest.hxx" + +#include "UnitTetraIntersectionBary.hxx" +#include "TetraAffineTransform.hxx" +#include "InterpolationUtils.hxx" +#include "SplitterTetra.txx" + +#include <iostream> + +using namespace INTERP_KERNEL; + +namespace INTERP_TEST +{ + void fill_UnitTetraIntersectionBary(UnitTetraIntersectionBary& bary, double nodes[][3]) + { + int faceConn[4][3] = { { 0, 1, 2 },// inverse order + { 0, 3, 1 }, + { 1, 3, 2 }, + { 3, 0, 2 } }; +// int faceConn[4][3] = { { 0, 2, 1 }, +// { 0, 1, 3 }, +// { 1, 2, 3 }, +// { 3, 2, 0 } }; + bary.init(true); + for ( int i = 0; i < 4; ++i ) { + int* faceNodes = faceConn[ i ]; + TransformedTriangle tri(nodes[faceNodes[0]], nodes[faceNodes[1]], nodes[faceNodes[2]]); + tri.calculateIntersectionVolume(); + bary.addSide( tri ); + } + } + void UnitTetraIntersectionBaryTest::test_UnitTetraIntersectionBary_1() + { + // cutting tetra coincides with the unit one + double nodes[4][3] = { { 0.0, 0.0, 0.0 }, + { 1.0, 0.0, 0.0 }, + { 0.0, 1.0, 0.0 }, + { 0.0, 0.0, 1.0 } }; + UnitTetraIntersectionBary bary; + fill_UnitTetraIntersectionBary(bary,nodes); + double baryCenter[3]; + bool ok = bary.getBary( baryCenter ); + double vol = bary.getVolume(); + CPPUNIT_ASSERT( ok ); + CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.166667, vol, 1e-5); + CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.25, baryCenter[0], 1e-5); + CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.25, baryCenter[1], 1e-5); + CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.25, baryCenter[2], 1e-5); + } + void UnitTetraIntersectionBaryTest::test_UnitTetraIntersectionBary_2() + { + // cutting tetra fully include the unit one + double nodes[4][3] = { {-0.1,-0.1,-0.1 }, + { 1.5,-0.1,-0.1 }, + {-0.1, 1.5,-0.1 }, + {-0.1,-0.1, 1.5 } }; + UnitTetraIntersectionBary bary; + fill_UnitTetraIntersectionBary(bary,nodes); + double baryCenter[3]; + bool ok = bary.getBary( baryCenter ); + double vol = bary.getVolume(); + CPPUNIT_ASSERT( ok ); + CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.166667, vol, 1e-5); + CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.25, baryCenter[0], 1e-5); + CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.25, baryCenter[1], 1e-5); + CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.25, baryCenter[2], 1e-5); + } + void UnitTetraIntersectionBaryTest::test_UnitTetraIntersectionBary_3() + { + // cutting tetra is same as the unit one but moved up by 0.5 + double nodes[4][3] = { { 0.0, 0.0, 0.5 }, + { 1.0, 0.0, 0.5 }, + { 0.0, 1.0, 0.5 }, + { 0.0, 0.0, 1.5 } }; + UnitTetraIntersectionBary bary; + fill_UnitTetraIntersectionBary(bary,nodes); + double baryCenter[3]; + bool ok = bary.getBary( baryCenter ); + double vol = bary.getVolume(); + CPPUNIT_ASSERT( ok ); + CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.020833333333333332, vol, 1e-5); + CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.125, baryCenter[0], 1e-5); + CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.125, baryCenter[1], 1e-5); + CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.625, baryCenter[2], 1e-5); + } + void UnitTetraIntersectionBaryTest::test_UnitTetraIntersectionBary_4() + { + // same as previous but no cutting sides lay on the sides of unit tetra + double nodes[4][3] = { {-0.2,-0.2, 0.5 }, + { 1.0, 0.0, 0.5 }, + { 0.0, 1.0, 0.5 }, + { 0.0, 0.0, 2.0 } }; + UnitTetraIntersectionBary bary; + fill_UnitTetraIntersectionBary(bary,nodes); + double baryCenter[3]; + bool ok = bary.getBary( baryCenter ); + double vol = bary.getVolume(); + CPPUNIT_ASSERT( ok ); + CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.020833333333333332, vol, 1e-5); + CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.125, baryCenter[0], 1e-5); + CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.125, baryCenter[1], 1e-5); + CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.625, baryCenter[2], 1e-5); + } + void UnitTetraIntersectionBaryTest::test_UnitTetraIntersectionBary_5() + { + // cutting tetra is similar and parallel to the UT but moved (-0.1,-0.1,-0.1) + double nodes[4][3] = { {-0.1,-0.1,-0.1 }, + { 1.1,-0.1,-0.1 }, + {-0.1, 1.1,-0.1 }, + {-0.1,-0.1, 1.1 } }; + UnitTetraIntersectionBary bary; + fill_UnitTetraIntersectionBary(bary,nodes); + double baryCenter[3]; + bool ok = bary.getBary( baryCenter ); + double vol = bary.getVolume(); + CPPUNIT_ASSERT( ok ); + CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.1215, vol, 1e-5); + CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.225, baryCenter[0], 1e-5); + CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.225, baryCenter[1], 1e-5); + CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.225, baryCenter[2], 1e-5); + } + void UnitTetraIntersectionBaryTest::test_UnitTetraIntersectionBary_6() + { + // cutting tetra is deeped into the UT with one corner + double nodes[4][3] = { { 0.2, 0.2, 0.2 }, + { 1.0, 0.2, 0.2 }, + { 0.9, 1.0, 0.2 }, + { 0.9, 9.0, 1.0 } }; + UnitTetraIntersectionBary bary; + fill_UnitTetraIntersectionBary(bary,nodes); + double baryCenter[3]; + bool ok = bary.getBary( baryCenter ); + double vol = bary.getVolume(); + CPPUNIT_ASSERT( ok ); + CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.000441855, vol, 1e-5); + CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.353463 , baryCenter[0], 1e-5 ); + CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.33877 , baryCenter[1], 1e-5 ); + CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.207767 , baryCenter[2], 1e-5 ); + } + void UnitTetraIntersectionBaryTest::test_UnitTetraIntersectionBary_7() + { + // cutting tetra passes through the UT with one corner + double nodes[4][3] = { {-0.2, 0.2, 0.2 }, + { 1.0, 0.2, 0.2 }, + { 0.9, 1.0, 0.2 }, + { 0.9, 0.9, 1.0 } }; + UnitTetraIntersectionBary bary; + fill_UnitTetraIntersectionBary(bary,nodes); + double baryCenter[3]; + bool ok = bary.getBary( baryCenter ); + double vol = bary.getVolume(); + CPPUNIT_ASSERT( ok ); + CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.0103501, vol, 1e-5); + CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.215578 , baryCenter[0], 1e-5 ); + CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.341363 , baryCenter[1], 1e-5 ); + CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.263903 , baryCenter[2], 1e-5 ); + } + void UnitTetraIntersectionBaryTest::test_UnitTetraIntersectionBary_8() + { + // cutting tetra passes through the UT with one edge + double nodes[4][3] = { { 0.5, 0.2, -0.2 }, // O + {-0.5,-0.2, -0.2 }, // OX + { 1.0,-0.5, -0.2 }, // OY + { 0.5, 0.2, 1.5 } };//OZ + UnitTetraIntersectionBary bary; + fill_UnitTetraIntersectionBary(bary,nodes); + double baryCenter[3]; + bool ok = bary.getBary( baryCenter ); + double vol = bary.getVolume(); + CPPUNIT_ASSERT( ok ); + CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.0349217, vol, 1e-5); + CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.332275 , baryCenter[0], 1e-2 ); + CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.0565892 , baryCenter[1], 1e-3 ); + CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.308713 , baryCenter[2], 1e-2 ); + } + void UnitTetraIntersectionBaryTest::test_UnitTetraIntersectionBary_9() + { + // cutting tetra touches the UT at an edge, intersection volume == 0 + double nodes[4][3] = { { 1.0, 0.0, 0.0 }, // 0 + {-1.0, 2.0, 2.0 }, // OX + {-1.0,-2.0, 2.0 }, // OY + { 1.0, 0.0, 2.0 } };//OZ + UnitTetraIntersectionBary bary; + fill_UnitTetraIntersectionBary(bary,nodes); + double baryCenter[3]; + bool ok = bary.getBary( baryCenter ); + double vol = bary.getVolume(); + CPPUNIT_ASSERT( !ok ); + CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.0, vol, 1e-15); + CPPUNIT_ASSERT_DOUBLES_EQUAL( -1. , baryCenter[0], 1e-5 ); + CPPUNIT_ASSERT_DOUBLES_EQUAL( -1. , baryCenter[1], 1e-5 ); + CPPUNIT_ASSERT_DOUBLES_EQUAL( -1. , baryCenter[2], 1e-5 ); + } + void UnitTetraIntersectionBaryTest::test_UnitTetraIntersectionBary_10() + { + // cutting tetra fully includes theUT and touches it at an edge + double nodes[4][3] = { { 1.0, 0.0, 0.0 }, // 0 + {-1.0,-4.0, 2.0 }, // OX + {-1.0, 4.0, 2.0 }, // OY + { 1.0, 0.0,-2.0 } };//OZ + UnitTetraIntersectionBary bary; + fill_UnitTetraIntersectionBary(bary,nodes); + double baryCenter[3]; + bool ok = bary.getBary( baryCenter ); + double vol = bary.getVolume(); + CPPUNIT_ASSERT( ok ); + CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.166667, vol, 1e-5); + CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.25, baryCenter[0], 1e-5); + CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.25, baryCenter[1], 1e-5); + CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.25, baryCenter[2], 1e-5); + } + void UnitTetraIntersectionBaryTest::test_UnitTetraIntersectionBary_11() + { + // cutting tetra intersects the UT and touches it at an edge + double nodes[4][3] = { { 1.0, 0.0, 0.0 }, // 0 + {-1.0,-4.0, 2.0 }, // OX + {-1.0, 4.0, 2.0 }, // OY + {-1.0, 0.0,-1.0 } };//OZ + UnitTetraIntersectionBary bary; + fill_UnitTetraIntersectionBary(bary,nodes); + double baryCenter[3]; + bool ok = bary.getBary( baryCenter ); + double vol = bary.getVolume(); + CPPUNIT_ASSERT( ok ); + CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.15873 , vol, 1e-5); + CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.250000, baryCenter[0], 1e-5); + CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.230952, baryCenter[1], 1e-5); + CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.260714, baryCenter[2], 1e-5); + } + void UnitTetraIntersectionBaryTest::test_UnitTetraIntersectionBary_12() + { + // cutting tetra has one corner inside the UT and one its side passes through an UT edge + double nodes[4][3] = { { 0.25, 0.25, 0.25 }, // 0 + { 1.75,-0.25,-0.25 }, // OX + { 0.5 , 0.25, 0.25 }, // OY + { 0.5 , 0 , 0.5 } };//OZ + UnitTetraIntersectionBary bary; + fill_UnitTetraIntersectionBary(bary,nodes); + double baryCenter[3]; + bool ok = bary.getBary( baryCenter ); + double vol = bary.getVolume(); + CPPUNIT_ASSERT( ok ); + CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.005208 , vol, 1e-5); + CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.562500, baryCenter[0], 1e-5); + CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.125000, baryCenter[1], 1e-5); + CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.250000, baryCenter[2], 1e-5); + } + + struct __MESH_DUMMY + { + typedef int MyConnType; + }; + + void UnitTetraIntersectionBaryTest::test_UnitTetraIntersectionBary_13() + { + double T[] = { + 66.6666666666666714,133.333333333333343,66.6666666666666714, + 100,200,100, + 100,100,100, + 200,200,0 }; + + double S[] = { + 100,166.666666666666657,66.6666666666666714, + 100,150,50, + 75,150,75, + 100,100,100}; + + int conn[4] = { 0,1,2,3 }; + + const double* tnodes[4]={ T, T+3, T+6, T+9 }; + const double* snodes[4]={ S, S+3, S+6, S+9 }; + + __MESH_DUMMY dummyMesh; + SplitterTetra<__MESH_DUMMY> src( dummyMesh, snodes, conn ); + double volume = src.intersectTetra( tnodes ); + CPPUNIT_ASSERT_DOUBLES_EQUAL(6944.4444444444443,volume,1e-9); + } + + void UnitTetraIntersectionBaryTest::test_TetraAffineTransform_reverseApply() + { + double nodes[12] = { -4.0, 9.0, 3.0, + 11.0, 0.0, 2.0, + 0.0, 0.0, 0.0, + 2.0, 1.0,10.0 }; + // double pSrc[3] = { -4.0, 9.0, 3.0 }; + double pSrc[3] = { 40., -20., 100. }; + double pDest[] = {1,1,1}; + TetraAffineTransform a(nodes); + a.apply( pDest, pSrc ); + a.reverseApply( pDest, pDest ); + CPPUNIT_ASSERT_DOUBLES_EQUAL( pSrc[0], pDest[0], 1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL( pSrc[1], pDest[1], 1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL( pSrc[2], pDest[2], 1e-12); + } + + void UnitTetraIntersectionBaryTest::test_barycentric_coords() + { + // compute barycentric coordinates + double nodes[4][3] = { {11.0, 0.0, 2.0 }, + {-4.0, 9.0, 3.0 }, + { 0.0, 0.0, 0.0 }, + { 6.0, 1.0,10.0 }}; + std::vector<const double*> n (4); + n[0] = &nodes[0][0]; + n[1] = &nodes[1][0]; + n[2] = &nodes[2][0]; + n[3] = &nodes[3][0]; + double p [3] = { 2, 2, 5 }, bc[4]; + barycentric_coords(n, p, bc); + double bcSum = 0; + double p2 [3] = { 0,0,0 }; + for ( int i = 0; i < 4; ++i ) { + bcSum += bc[i]; + p2[0] += bc[i]*n[i][0]; + p2[1] += bc[i]*n[i][1]; + p2[2] += bc[i]*n[i][2]; + } + CPPUNIT_ASSERT_DOUBLES_EQUAL( 1., bcSum, 1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL( p[0], p2[0], 1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL( p[1], p2[1], 1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL( p[2], p2[2], 1e-12); + } +} diff --git a/src/medtool/src/INTERP_KERNELTest/UnitTetraIntersectionBaryTest.hxx b/src/medtool/src/INTERP_KERNELTest/UnitTetraIntersectionBaryTest.hxx new file mode 100644 index 000000000..220da14bc --- /dev/null +++ b/src/medtool/src/INTERP_KERNELTest/UnitTetraIntersectionBaryTest.hxx @@ -0,0 +1,75 @@ +// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 +// 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 +// + +// File : UnitTetraIntersectionBaryTests.hxx +// Created : Thu Nov 6 17:11:27 2008 +// Author : Edward AGAPOV (eap) +// +#ifndef __UNITTETRAINTERSECTIONBARYTEST_HXX__ +#define __UNITTETRAINTERSECTIONBARYTEST_HXX__ + +#include <cppunit/extensions/HelperMacros.h> + +#include "InterpKernelTestExport.hxx" + +namespace INTERP_TEST +{ + /** + * \brief Test suite testing UnitTetraIntersectionBary class. + * + */ + class INTERPKERNELTEST_EXPORT UnitTetraIntersectionBaryTest : public CppUnit::TestFixture + { + CPPUNIT_TEST_SUITE( UnitTetraIntersectionBaryTest ); + CPPUNIT_TEST( test_UnitTetraIntersectionBary_13 ); + CPPUNIT_TEST( test_UnitTetraIntersectionBary_12 ); + CPPUNIT_TEST( test_UnitTetraIntersectionBary_1 ); + CPPUNIT_TEST( test_UnitTetraIntersectionBary_2 ); + CPPUNIT_TEST( test_UnitTetraIntersectionBary_3 ); + CPPUNIT_TEST( test_UnitTetraIntersectionBary_4 ); + CPPUNIT_TEST( test_UnitTetraIntersectionBary_5 ); + CPPUNIT_TEST( test_UnitTetraIntersectionBary_6 ); + CPPUNIT_TEST( test_UnitTetraIntersectionBary_7 ); + CPPUNIT_TEST( test_UnitTetraIntersectionBary_8 ); + CPPUNIT_TEST( test_UnitTetraIntersectionBary_9 ); + CPPUNIT_TEST( test_UnitTetraIntersectionBary_10 ); + CPPUNIT_TEST( test_UnitTetraIntersectionBary_11 ); + CPPUNIT_TEST( test_TetraAffineTransform_reverseApply ); + CPPUNIT_TEST( test_barycentric_coords ); + CPPUNIT_TEST_SUITE_END(); + public: + void test_UnitTetraIntersectionBary_1(); + void test_UnitTetraIntersectionBary_2(); + void test_UnitTetraIntersectionBary_3(); + void test_UnitTetraIntersectionBary_4(); + void test_UnitTetraIntersectionBary_5(); + void test_UnitTetraIntersectionBary_6(); + void test_UnitTetraIntersectionBary_7(); + void test_UnitTetraIntersectionBary_8(); + void test_UnitTetraIntersectionBary_9(); + void test_UnitTetraIntersectionBary_10(); + void test_UnitTetraIntersectionBary_11(); + void test_UnitTetraIntersectionBary_12(); + void test_UnitTetraIntersectionBary_13(); + void test_TetraAffineTransform_reverseApply(); + void test_barycentric_coords(); + }; +} + +#endif diff --git a/src/medtool/src/INTERP_KERNELTest/perf_test.py b/src/medtool/src/INTERP_KERNELTest/perf_test.py new file mode 100755 index 000000000..97f5579b0 --- /dev/null +++ b/src/medtool/src/INTERP_KERNELTest/perf_test.py @@ -0,0 +1,146 @@ +#! /bin/env python +# Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 +# 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 +# + +import re +import sys +import time +import subprocess + +RES_FILE="perf_OPTIMIZE" + +def test_pair(par1,par2): + c=re.compile("[\D]*(?P<num>[\d]+)") + val1=c.match(par1).group("num") + val2=c.match(par2).group("num") + st="%s %s"%(val1,val2) + ret=subprocess.call(["./PerfTest",par1,par2]) + if ret!=0: + f=file(RES_FILE,"w") ; f.write("Error on case %s %s !!!!\n"%(par1,par2)) ; del f + sys.exit(ret) + pass + return st + +def test_box_box(): + st="PerfBox PerfBox\n" + st+=test_pair("PerfBox1495","PerfBox1495") + st+=test_pair("PerfBox2506","PerfBox2506") + st+=test_pair("PerfBox5708","PerfBox5708") + st+=test_pair("PerfBox13461","PerfBox13461") + st+=test_pair("PerfBox30808","PerfBox30808") + st+=test_pair("PerfBox47176","PerfBox47176") + st+=test_pair("PerfBox1495","PerfBox2506") + st+=test_pair("PerfBox1495","PerfBox5708") + st+=test_pair("PerfBox1495","PerfBox13461") + st+=test_pair("PerfBox1495","PerfBox30808") + st+=test_pair("PerfBox1495","PerfBox47176") + st+=test_pair("PerfBox2506","PerfBox5708") + st+=test_pair("PerfBox2506","PerfBox13461") + st+=test_pair("PerfBox2506","PerfBox30808") + st+=test_pair("PerfBox2506","PerfBox47176") + st+=test_pair("PerfBox5708","PerfBox13461") + st+=test_pair("PerfBox5708","PerfBox30808") + st+=test_pair("PerfBox5708","PerfBox47176") + st+=test_pair("PerfBox13461","PerfBox30808") + st+=test_pair("PerfBox13461","PerfBox47176") + st+=test_pair("PerfBox30808","PerfBox47176") + pass + +def test_cyl_cyl(): + st="PerfCyl PerfCyl\n" + st+=test_pair("PerfCyl1047","PerfCyl1047") + st+=test_pair("PerfCyl3020","PerfCyl3020") + st+=test_pair("PerfCyl6556","PerfCyl6556") + st+=test_pair("PerfCyl9766","PerfCyl9766") + st+=test_pair("PerfCyl25745","PerfCyl25745") + st+=test_pair("PerfCyl47601","PerfCyl47601") + st+=test_pair("PerfCyl1047","PerfCyl3020") + st+=test_pair("PerfCyl1047","PerfCyl6556") + st+=test_pair("PerfCyl1047","PerfCyl9766") + st+=test_pair("PerfCyl1047","PerfCyl25745") + st+=test_pair("PerfCyl1047","PerfCyl47601") + st+=test_pair("PerfCyl3020","PerfCyl6556") + st+=test_pair("PerfCyl3020","PerfCyl9766") + st+=test_pair("PerfCyl3020","PerfCyl25745") + st+=test_pair("PerfCyl3020","PerfCyl47601") + st+=test_pair("PerfCyl6556","PerfCyl9766") + st+=test_pair("PerfCyl6556","PerfCyl25745") + st+=test_pair("PerfCyl6556","PerfCyl47601") + st+=test_pair("PerfCyl9766","PerfCyl25745") + st+=test_pair("PerfCyl9766","PerfCyl47601") + st+=test_pair("PerfCyl25745","PerfCyl47601") + return st + +def test_box_cyl(): + st="PerfBox PerfCyl\n" + st+=test_pair("PerfBox1495","PerfCyl1047") + st+=test_pair("PerfBox1495","PerfCyl3020") + st+=test_pair("PerfBox1495","PerfCyl6556") + st+=test_pair("PerfBox1495","PerfCyl9766") + st+=test_pair("PerfBox1495","PerfCyl25745") + st+=test_pair("PerfBox1495","PerfCyl47601") + st+=test_pair("PerfBox2506","PerfCyl1047") + st+=test_pair("PerfBox2506","PerfCyl3020") + st+=test_pair("PerfBox2506","PerfCyl6556") + st+=test_pair("PerfBox2506","PerfCyl9766") + st+=test_pair("PerfBox2506","PerfCyl25745") + st+=test_pair("PerfBox2506","PerfCyl47601") + st+=test_pair("PerfBox5708","PerfCyl1047") + st+=test_pair("PerfBox5708","PerfCyl3020") + st+=test_pair("PerfBox5708","PerfCyl6556") + st+=test_pair("PerfBox5708","PerfCyl9766") + st+=test_pair("PerfBox5708","PerfCyl25745") + st+=test_pair("PerfBox5708","PerfCyl47601") + st+=test_pair("PerfBox13461","PerfCyl1047") + st+=test_pair("PerfBox13461","PerfCyl3020") + st+=test_pair("PerfBox13461","PerfCyl6556") + st+=test_pair("PerfBox13461","PerfCyl9766") + st+=test_pair("PerfBox13461","PerfCyl25745") + st+=test_pair("PerfBox13461","PerfCyl47601") + st+=test_pair("PerfBox30808","PerfCyl1047") + st+=test_pair("PerfBox30808","PerfCyl3020") + st+=test_pair("PerfBox30808","PerfCyl6556") + st+=test_pair("PerfBox30808","PerfCyl9766") + st+=test_pair("PerfBox30808","PerfCyl25745") + st+=test_pair("PerfBox30808","PerfCyl47601") + st+=test_pair("PerfBox47176","PerfCyl1047") + st+=test_pair("PerfBox47176","PerfCyl3020") + st+=test_pair("PerfBox47176","PerfCyl6556") + st+=test_pair("PerfBox47176","PerfCyl9766") + st+=test_pair("PerfBox47176","PerfCyl25745") + st+=test_pair("PerfBox47176","PerfCyl47601") + return st + +def test_box_transbox(): + st=" PerfBox PerfBoxT\n" + st+=test_pair("PerfBox1495","PerfBoxT1493") + st+=test_pair("PerfBox2506","PerfBoxT2676") + st+=test_pair("PerfBox5708","PerfBoxT5717") + st+=test_pair("PerfBox13461","PerfBoxT12469") + st+=test_pair("PerfBox30808","PerfBoxT29019") + st+=test_pair("PerfBox47176","PerfBoxT47278") + return st + +gm=time.strftime("%a. %B %H:%M:%S",gm).lower()+time.strftime(" CET %Y",gm) +st="PerfTest execution on %s\n"%(time.strftime("%a. %B %H:%M:%S",gm).lower()+time.strftime(" CET %Y",gm)) +st+=test_box_cyl() +st+=test_box_box() +st+=test_cyl_cyl() +st+=test_box_transbox() +f=file(RES_FILE,"w") diff --git a/src/medtool/src/INTERP_KERNELTest/perf_test.sh b/src/medtool/src/INTERP_KERNELTest/perf_test.sh new file mode 100755 index 000000000..d65415e1d --- /dev/null +++ b/src/medtool/src/INTERP_KERNELTest/perf_test.sh @@ -0,0 +1,166 @@ +#!/bin/bash +# Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 +# 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 +# + +# should be run from the build directory, so that ./PerfTest is available +# output file +# +RES_FILE=perf_OPTIMIZE + +#outputs lines of form : +#"no. source elems no. target elems user time" +function test_pair { + echo -n $1 | sed 's/\(PerfCyl\)\([0-9]*\)/\2/' | sed 's/\(PerfBoxT\)\([0-9]*\)/\2/' | sed 's/\(PerfBox\)\([0-9]*\)/\2/' >> $RES_FILE + echo -n " " >> $RES_FILE + echo -n $2 | sed 's/\(PerfCyl\)\([0-9]*\)/\2/' | sed 's/\(PerfBoxT\)\([0-9]*\)/\2/' | sed 's/\(PerfBox\)\([0-9]*\)/\2/' >> $RES_FILE + echo -n " " >> $RES_FILE + time -o $RES_FILE --append -f"%U" ./PerfTest $1 $2 + echo +} + +function test_box_box { +echo PerfBox PerfBox >> $RES_FILE + +test_pair PerfBox1495 PerfBox1495 +test_pair PerfBox2506 PerfBox2506 +test_pair PerfBox5708 PerfBox5708 +test_pair PerfBox13461 PerfBox13461 +test_pair PerfBox30808 PerfBox30808 +test_pair PerfBox47176 PerfBox47176 + +test_pair PerfBox1495 PerfBox2506 +test_pair PerfBox1495 PerfBox5708 +test_pair PerfBox1495 PerfBox13461 +test_pair PerfBox1495 PerfBox30808 +test_pair PerfBox1495 PerfBox47176 + +test_pair PerfBox2506 PerfBox5708 +test_pair PerfBox2506 PerfBox13461 +test_pair PerfBox2506 PerfBox30808 +test_pair PerfBox2506 PerfBox47176 + +test_pair PerfBox5708 PerfBox13461 +test_pair PerfBox5708 PerfBox30808 +test_pair PerfBox5708 PerfBox47176 + +test_pair PerfBox13461 PerfBox30808 +test_pair PerfBox13461 PerfBox47176 + +test_pair PerfBox30808 PerfBox47176 + +} + +function test_cyl_cyl { +echo PerfCyl PerfCyl >> $RES_FILE + +test_pair PerfCyl1047 PerfCyl1047 +test_pair PerfCyl3020 PerfCyl3020 +test_pair PerfCyl6556 PerfCyl6556 +test_pair PerfCyl9766 PerfCyl9766 +test_pair PerfCyl25745 PerfCyl25745 +test_pair PerfCyl47601 PerfCyl47601 + +test_pair PerfCyl1047 PerfCyl3020 +test_pair PerfCyl1047 PerfCyl6556 +test_pair PerfCyl1047 PerfCyl9766 +test_pair PerfCyl1047 PerfCyl25745 +test_pair PerfCyl1047 PerfCyl47601 + +test_pair PerfCyl3020 PerfCyl6556 +test_pair PerfCyl3020 PerfCyl9766 +test_pair PerfCyl3020 PerfCyl25745 +test_pair PerfCyl3020 PerfCyl47601 + +test_pair PerfCyl6556 PerfCyl9766 +test_pair PerfCyl6556 PerfCyl25745 +test_pair PerfCyl6556 PerfCyl47601 + +test_pair PerfCyl9766 PerfCyl25745 +test_pair PerfCyl9766 PerfCyl47601 + +test_pair PerfCyl25745 PerfCyl47601 + +} + +function test_box_cyl { + echo PerfBox PerfCyl >> $RES_FILE + test_pair PerfBox1495 PerfCyl1047 + test_pair PerfBox1495 PerfCyl3020 + test_pair PerfBox1495 PerfCyl6556 + test_pair PerfBox1495 PerfCyl9766 + test_pair PerfBox1495 PerfCyl25745 + test_pair PerfBox1495 PerfCyl47601 + + test_pair PerfBox2506 PerfCyl1047 + test_pair PerfBox2506 PerfCyl3020 + test_pair PerfBox2506 PerfCyl6556 + test_pair PerfBox2506 PerfCyl9766 + test_pair PerfBox2506 PerfCyl25745 + test_pair PerfBox2506 PerfCyl47601 + + test_pair PerfBox5708 PerfCyl1047 + test_pair PerfBox5708 PerfCyl3020 + test_pair PerfBox5708 PerfCyl6556 + test_pair PerfBox5708 PerfCyl9766 + test_pair PerfBox5708 PerfCyl25745 + test_pair PerfBox5708 PerfCyl47601 + + test_pair PerfBox13461 PerfCyl1047 + test_pair PerfBox13461 PerfCyl3020 + test_pair PerfBox13461 PerfCyl6556 + test_pair PerfBox13461 PerfCyl9766 + test_pair PerfBox13461 PerfCyl25745 + test_pair PerfBox13461 PerfCyl47601 + + test_pair PerfBox30808 PerfCyl1047 + test_pair PerfBox30808 PerfCyl3020 + test_pair PerfBox30808 PerfCyl6556 + test_pair PerfBox30808 PerfCyl9766 + test_pair PerfBox30808 PerfCyl25745 + test_pair PerfBox30808 PerfCyl47601 + + test_pair PerfBox47176 PerfCyl1047 + test_pair PerfBox47176 PerfCyl3020 + test_pair PerfBox47176 PerfCyl6556 + test_pair PerfBox47176 PerfCyl9766 + test_pair PerfBox47176 PerfCyl25745 + test_pair PerfBox47176 PerfCyl47601 +} + +function test_box_transbox { + echo PerfBox PerfBoxT >> $RES_FILE + test_pair PerfBox1495 PerfBoxT1493 + test_pair PerfBox2506 PerfBoxT2676 + test_pair PerfBox5708 PerfBoxT5717 + test_pair PerfBox13461 PerfBoxT12469 + test_pair PerfBox30808 PerfBoxT29019 + test_pair PerfBox47176 PerfBoxT47278 +} + + + +#functions to execute : + +echo PerfTest execution on `date` > $RES_FILE +test_box_cyl +test_box_box +test_cyl_cyl +test_box_transbox + +cat $RES_FILE \ No newline at end of file diff --git a/src/medtool/src/MEDCoupling/CMakeLists.txt b/src/medtool/src/MEDCoupling/CMakeLists.txt new file mode 100644 index 000000000..2d7d53fcb --- /dev/null +++ b/src/medtool/src/MEDCoupling/CMakeLists.txt @@ -0,0 +1,83 @@ +# Copyright (C) 2012-2015 CEA/DEN, EDF 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, 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 +# 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) + +IF(SALOME_BUILD_TESTS) + ADD_SUBDIRECTORY(Test) +ENDIF(SALOME_BUILD_TESTS) + +INCLUDE_DIRECTORIES( + ${CMAKE_CURRENT_BINARY_DIR}/../.. + ${CMAKE_CURRENT_SOURCE_DIR}/../INTERP_KERNEL + ${CMAKE_CURRENT_SOURCE_DIR}/../INTERP_KERNEL/Bases + ${CMAKE_CURRENT_SOURCE_DIR}/../INTERP_KERNEL/Geometric2D + ${CMAKE_CURRENT_SOURCE_DIR}/../INTERP_KERNEL/ExprEval + ${CMAKE_CURRENT_SOURCE_DIR}/../INTERP_KERNEL/GaussPoints + ) + +SET(medcoupling_SOURCES + MEDCouplingField.cxx + MEDCouplingFieldDouble.cxx + MEDCouplingUMesh.cxx + MEDCoupling1GTUMesh.cxx + MEDCouplingMemArray.cxx + MEDCouplingMemArrayChar.cxx + MEDCouplingTimeLabel.cxx + MEDCouplingCMesh.cxx + MEDCouplingIMesh.cxx + MEDCouplingCurveLinearMesh.cxx + MEDCouplingStructuredMesh.cxx + MEDCouplingTimeDiscretization.cxx + MEDCouplingFieldDiscretization.cxx + MEDCouplingRefCountObject.cxx + MEDCouplingPointSet.cxx + MEDCouplingFieldTemplate.cxx + MEDCouplingExtrudedMesh.cxx + MEDCouplingMesh.cxx + MEDCouplingGaussLocalization.cxx + MEDCouplingNatureOfField.cxx + MEDCouplingMultiFields.cxx + MEDCouplingDefinitionTime.cxx + MEDCouplingFieldOverTime.cxx + MEDCouplingCartesianAMRMesh.cxx + MEDCouplingAMRAttribute.cxx + MEDCouplingMatrix.cxx + MEDCouplingPartDefinition.cxx + MEDCouplingSkyLineArray.cxx + ) + +SET(medcouplingremapper_SOURCES + MEDCouplingRemapper.cxx + ) + +ADD_LIBRARY(medcoupling SHARED ${medcoupling_SOURCES}) +TARGET_LINK_LIBRARIES(medcoupling interpkernel) +INSTALL(TARGETS medcoupling EXPORT ${PROJECT_NAME}TargetGroup DESTINATION ${MEDTOOL_INSTALL_LIBS}) + +ADD_LIBRARY(medcouplingremapper SHARED ${medcouplingremapper_SOURCES}) +TARGET_LINK_LIBRARIES(medcouplingremapper medcoupling) +INSTALL(TARGETS medcouplingremapper EXPORT ${PROJECT_NAME}TargetGroup DESTINATION ${MEDTOOL_INSTALL_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} MEDCouplingNatureOfFieldEnum DESTINATION ${MEDTOOL_INSTALL_HEADERS}) + +# To allow usage as SWIG dependencies: +SET(medcoupling_HEADERS_HXX PARENT_SCOPE) +SET(medcoupling_HEADERS_TXX PARENT_SCOPE) diff --git a/src/medtool/src/MEDCoupling/MEDCoupling.hxx b/src/medtool/src/MEDCoupling/MEDCoupling.hxx new file mode 100644 index 000000000..813515ac8 --- /dev/null +++ b/src/medtool/src/MEDCoupling/MEDCoupling.hxx @@ -0,0 +1,48 @@ +// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 +// 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 _MEDCOUPLING_HXX_ +#define _MEDCOUPLING_HXX_ + +#ifdef WIN32 +# if defined medcoupling_EXPORTS +# define MEDCOUPLING_EXPORT __declspec( dllexport ) +# else +# define MEDCOUPLING_EXPORT __declspec( dllimport ) +# endif +#else +# define MEDCOUPLING_EXPORT +#endif + +#ifdef WIN32 +# if defined medcouplingremapper_EXPORTS +# define MEDCOUPLINGREMAPPER_EXPORT __declspec( dllexport ) +# else +# define MEDCOUPLINGREMAPPER_EXPORT __declspec( dllimport ) +# endif +#else +# define MEDCOUPLINGREMAPPER_EXPORT +#endif + +#ifdef WIN32 +#pragma warning( disable : 4290 ) +#endif + +#endif diff --git a/src/medtool/src/MEDCoupling/MEDCoupling1GTUMesh.cxx b/src/medtool/src/MEDCoupling/MEDCoupling1GTUMesh.cxx new file mode 100644 index 000000000..38eae7a7e --- /dev/null +++ b/src/medtool/src/MEDCoupling/MEDCoupling1GTUMesh.cxx @@ -0,0 +1,3740 @@ +// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 +// 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 "MEDCoupling1GTUMesh.hxx" +#include "MEDCouplingUMesh.hxx" +#include "MEDCouplingFieldDouble.hxx" +#include "MEDCouplingCMesh.hxx" + +#include "SplitterTetra.hxx" +#include "DiameterCalculator.hxx" +#include "InterpKernelAutoPtr.hxx" + +using namespace ParaMEDMEM; + +const int MEDCoupling1SGTUMesh::HEXA8_FACE_PAIRS[6]={0,1,2,4,3,5}; + +MEDCoupling1GTUMesh::MEDCoupling1GTUMesh():_cm(0) +{ +} + +MEDCoupling1GTUMesh::MEDCoupling1GTUMesh(const std::string& name, const INTERP_KERNEL::CellModel& cm):_cm(&cm) +{ + setName(name); +} + +MEDCoupling1GTUMesh::MEDCoupling1GTUMesh(const MEDCoupling1GTUMesh& other, bool recDeepCpy):MEDCouplingPointSet(other,recDeepCpy),_cm(other._cm) +{ +} + +MEDCoupling1GTUMesh *MEDCoupling1GTUMesh::New(const std::string& name, INTERP_KERNEL::NormalizedCellType type) +{ + if(type==INTERP_KERNEL::NORM_ERROR) + throw INTERP_KERNEL::Exception("MEDCoupling1GTUMesh::New : NORM_ERROR is not a valid type to be used as base geometric type for a mesh !"); + const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(type); + if(!cm.isDynamic()) + return MEDCoupling1SGTUMesh::New(name,type); + else + return MEDCoupling1DGTUMesh::New(name,type); +} + +MEDCoupling1GTUMesh *MEDCoupling1GTUMesh::New(const MEDCouplingUMesh *m) +{ + if(!m) + throw INTERP_KERNEL::Exception("MEDCoupling1GTUMesh::New : input mesh is null !"); + std::set<INTERP_KERNEL::NormalizedCellType> gts(m->getAllGeoTypes()); + if(gts.size()!=1) + throw INTERP_KERNEL::Exception("MEDCoupling1GTUMesh::New : input mesh must have exactly one geometric type !"); + const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(*gts.begin()); + if(!cm.isDynamic()) + return MEDCoupling1SGTUMesh::New(m); + else + return MEDCoupling1DGTUMesh::New(m); +} + +const INTERP_KERNEL::CellModel& MEDCoupling1GTUMesh::getCellModel() const +{ + return *_cm; +} + +INTERP_KERNEL::NormalizedCellType MEDCoupling1GTUMesh::getCellModelEnum() const +{ + return _cm->getEnum(); +} + +int MEDCoupling1GTUMesh::getMeshDimension() const +{ + return (int)_cm->getDimension(); +} + +/*! + * This method returns a newly allocated array containing cell ids (ascendingly sorted) whose geometric type are equal to type. + * This method does not throw exception if geometric type \a type is not in \a this. + * This method throws an INTERP_KERNEL::Exception if meshdimension of \b this is not equal to those of \b type. + * The coordinates array is not considered here. + * + * \param [in] type the geometric type + * \return cell ids in this having geometric type \a type. + */ +DataArrayInt *MEDCoupling1GTUMesh::giveCellsWithType(INTERP_KERNEL::NormalizedCellType type) const +{ + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New(); + if(type==getCellModelEnum()) + ret->alloc(getNumberOfCells(),1); + else + ret->alloc(0,1); + ret->iota(); + return ret.retn(); +} + +/*! + * Returns nb of cells having the geometric type \a type. No throw if no cells in \a this has the geometric type \a type. + */ +int MEDCoupling1GTUMesh::getNumberOfCellsWithType(INTERP_KERNEL::NormalizedCellType type) const +{ + return type==getCellModelEnum()?getNumberOfCells():0; +} + +/*! + * Returns a type of a cell by its id. + * \param [in] cellId - the id of the cell of interest. + * \return INTERP_KERNEL::NormalizedCellType - enumeration item describing the cell type. + * \throw If \a cellId is invalid. Valid range is [0, \a this->getNumberOfCells() ). + */ +INTERP_KERNEL::NormalizedCellType MEDCoupling1GTUMesh::getTypeOfCell(int cellId) const +{ + if(cellId>=0 && cellId<getNumberOfCells()) + return getCellModelEnum(); + std::ostringstream oss; oss << "MEDCoupling1GTUMesh::getTypeOfCell : Requesting type of cell #" << cellId << " but it should be in [0," << getNumberOfCells() << ") !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); +} + +/*! + * Returns a set of all cell types available in \a this mesh. + * \return std::set<INTERP_KERNEL::NormalizedCellType> - the set of cell types. + * \warning this method does not throw any exception even if \a this is not defined. + */ +std::set<INTERP_KERNEL::NormalizedCellType> MEDCoupling1GTUMesh::getAllGeoTypes() const +{ + std::set<INTERP_KERNEL::NormalizedCellType> ret; + ret.insert(getCellModelEnum()); + return ret; +} + +/*! + * This method expects that \a this is sorted by types. If not an exception will be thrown. + * This method returns in the same format as code (see MEDCouplingUMesh::checkTypeConsistencyAndContig or MEDCouplingUMesh::splitProfilePerType) how + * \a this is composed in cell types. + * The returned array is of size 3*n where n is the number of different types present in \a this. + * For every k in [0,n] ret[3*k+2]==-1 because it has no sense here. + * This parameter is kept only for compatibility with other methode listed above. + */ +std::vector<int> MEDCoupling1GTUMesh::getDistributionOfTypes() const +{ + std::vector<int> ret(3); + ret[0]=(int)getCellModelEnum(); ret[1]=getNumberOfCells(); ret[2]=-1; + return ret; +} + +/*! + * This method is the opposite of MEDCouplingUMesh::checkTypeConsistencyAndContig method. Given a list of cells in \a profile it returns a list of sub-profiles sorted by geo type. + * The result is put in the array \a idsPerType. In the returned parameter \a code, foreach i \a code[3*i+2] refers (if different from -1) to a location into the \a idsPerType. + * This method has 1 input \a profile and 3 outputs \a code \a idsInPflPerType and \a idsPerType. + * + * \param [out] code is a vector of size 3*n where n is the number of different geometric type in \a this \b reduced to the profile \a profile. \a code has exactly the same semantic than in MEDCouplingUMesh::checkTypeConsistencyAndContig method. + * \param [out] idsInPflPerType is a vector of size of different geometric type in the subpart defined by \a profile of \a this ( equal to \a code.size()/3). For each i, + * \a idsInPflPerType[i] stores the tuple ids in \a profile that correspond to the geometric type code[3*i+0] + * \param [out] idsPerType is a vector of size of different sub profiles needed to be defined to represent the profile \a profile for a given geometric type. + * This vector can be empty in case of all geometric type cells are fully covered in ascending in the given input \a profile. + * + * \warning for performance reasons no deep copy will be performed, if \a profile can been used as this in output parameters \a idsInPflPerType and \a idsPerType. + * + * \throw if \a profile has not exactly one component. It throws too, if \a profile contains some values not in [0,getNumberOfCells()) or if \a this is not fully defined + * + * \b Example1: <br> + * - Before \a this has 3 cells \a profile contains [0,1,2] + * - After \a code contains [NORM_...,nbCells,-1], \a idsInPflPerType [[0,1,2]] and \a idsPerType is empty <br> + * + * \b Example2: <br> + * - Before \a this has 3 cells \a profile contains [1,2] + * - After \a code contains [NORM_...,nbCells,0], \a idsInPflPerType [[0,1]] and \a idsPerType is [[1,2]] <br> + + */ +void MEDCoupling1GTUMesh::splitProfilePerType(const DataArrayInt *profile, std::vector<int>& code, std::vector<DataArrayInt *>& idsInPflPerType, std::vector<DataArrayInt *>& idsPerType) const +{ + if(!profile) + throw INTERP_KERNEL::Exception("MEDCoupling1GTUMesh::splitProfilePerType : input profile is NULL !"); + if(profile->getNumberOfComponents()!=1) + throw INTERP_KERNEL::Exception("MEDCoupling1GTUMesh::splitProfilePerType : input profile should have exactly one component !"); + int nbTuples=profile->getNumberOfTuples(); + int nbOfCells=getNumberOfCells(); + code.resize(3); idsInPflPerType.resize(1); + code[0]=(int)getCellModelEnum(); code[1]=nbTuples; + idsInPflPerType.resize(1); + if(profile->isIdentity() && nbTuples==nbOfCells) + { + code[2]=-1; + idsInPflPerType[0]=const_cast<DataArrayInt *>(profile); idsInPflPerType[0]->incrRef(); + idsPerType.clear(); + return ; + } + code[2]=0; + profile->checkAllIdsInRange(0,nbOfCells); + idsPerType.resize(1); + idsPerType[0]=const_cast<DataArrayInt *>(profile); idsPerType[0]->incrRef(); + idsInPflPerType[0]=DataArrayInt::Range(0,nbTuples,1); +} + +/*! + * This method tries to minimize at most the number of deep copy. + * So if \a idsPerType is not empty it can be returned directly (without copy, but with ref count incremented) in return. + * + * \sa MEDCouplingUMesh::checkTypeConsistencyAndContig + */ +DataArrayInt *MEDCoupling1GTUMesh::checkTypeConsistencyAndContig(const std::vector<int>& code, const std::vector<const DataArrayInt *>& idsPerType) const +{ + int nbOfCells=getNumberOfCells(); + if(code.size()!=3) + throw INTERP_KERNEL::Exception("MEDCoupling1GTUMesh::checkTypeConsistencyAndContig : invalid input code should be exactly of size 3 !"); + if(code[0]!=(int)getCellModelEnum()) + { + std::ostringstream oss; oss << "MEDCoupling1GTUMesh::checkTypeConsistencyAndContig : Mismatch of geometric type ! Asking for " << code[0] << " whereas the geometric type is \a this is " << getCellModelEnum() << " (" << _cm->getRepr() << ") !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + if(code[2]==-1) + { + if(code[1]==nbOfCells) + return 0; + else + { + std::ostringstream oss; oss << "MEDCoupling1GTUMesh::checkTypeConsistencyAndContig : mismatch between the number of cells in this (" << nbOfCells << ") and the number of non profile (" << code[1] << ") !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + } + if(code[2]!=0) + throw INTERP_KERNEL::Exception("MEDCoupling1GTUMesh::checkTypeConsistencyAndContig : single geo type mesh ! 0 or -1 is expected at pos #2 of input code !"); + if(idsPerType.size()!=1) + throw INTERP_KERNEL::Exception("MEDCoupling1GTUMesh::checkTypeConsistencyAndContig : input code points to DataArrayInt #0 whereas the size of idsPerType is not equal to 1 !"); + const DataArrayInt *pfl=idsPerType[0]; + if(!pfl) + throw INTERP_KERNEL::Exception("MEDCoupling1GTUMesh::checkTypeConsistencyAndContig : the input code points to a NULL DataArrayInt at rank 0 !"); + if(pfl->getNumberOfComponents()!=1) + throw INTERP_KERNEL::Exception("MEDCoupling1GTUMesh::checkTypeConsistencyAndContig : input profile should have exactly one component !"); + pfl->checkAllIdsInRange(0,nbOfCells); + pfl->incrRef(); + return const_cast<DataArrayInt *>(pfl); +} + +void MEDCoupling1GTUMesh::writeVTKLL(std::ostream& ofs, const std::string& cellData, const std::string& pointData, DataArrayByte *byteData) const +{ + MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m=buildUnstructured(); + m->writeVTKLL(ofs,cellData,pointData,byteData); +} + +std::string MEDCoupling1GTUMesh::getVTKDataSetType() const +{ + return std::string("UnstructuredGrid"); +} + +std::string MEDCoupling1GTUMesh::getVTKFileExtension() const +{ + return std::string("vtu"); +} + +std::size_t MEDCoupling1GTUMesh::getHeapMemorySizeWithoutChildren() const +{ + return MEDCouplingPointSet::getHeapMemorySizeWithoutChildren(); +} + +bool MEDCoupling1GTUMesh::isEqualIfNotWhy(const MEDCouplingMesh *other, double prec, std::string& reason) const +{ + if(!MEDCouplingPointSet::isEqualIfNotWhy(other,prec,reason)) + return false; + if(!other) + throw INTERP_KERNEL::Exception("MEDCoupling1GTUMesh::isEqualIfNotWhy : input other pointer is null !"); + const MEDCoupling1GTUMesh *otherC=dynamic_cast<const MEDCoupling1GTUMesh *>(other); + if(!otherC) + { + reason="mesh given in input is not castable in MEDCouplingSGTUMesh !"; + return false; + } + if(_cm!=otherC->_cm) + { + reason="mismatch in geometric type !"; + return false; + } + return true; +} + +bool MEDCoupling1GTUMesh::isEqualWithoutConsideringStr(const MEDCouplingMesh *other, double prec) const +{ + if(!MEDCouplingPointSet::isEqualWithoutConsideringStr(other,prec)) + return false; + if(!other) + throw INTERP_KERNEL::Exception("MEDCoupling1GTUMesh::isEqualWithoutConsideringStr : input other pointer is null !"); + const MEDCoupling1GTUMesh *otherC=dynamic_cast<const MEDCoupling1GTUMesh *>(other); + if(!otherC) + return false; + if(_cm!=otherC->_cm) + return false; + return true; +} + +void MEDCoupling1GTUMesh::checkCoherency() const +{ + MEDCouplingPointSet::checkCoherency(); +} + +DataArrayDouble *MEDCoupling1GTUMesh::getBarycenterAndOwner() const +{ + MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m=buildUnstructured(); + MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=m->getBarycenterAndOwner(); + return ret.retn(); +} + +MEDCouplingFieldDouble *MEDCoupling1GTUMesh::getMeasureField(bool isAbs) const +{ + MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m=buildUnstructured(); + MEDCouplingAutoRefCountObjectPtr<MEDCouplingFieldDouble> ret=m->getMeasureField(isAbs); + ret->setMesh(this); + return ret.retn(); +} + +MEDCouplingFieldDouble *MEDCoupling1GTUMesh::getMeasureFieldOnNode(bool isAbs) const +{ + MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m=buildUnstructured(); + MEDCouplingAutoRefCountObjectPtr<MEDCouplingFieldDouble> ret=m->getMeasureFieldOnNode(isAbs); + ret->setMesh(this); + return ret.retn(); +} + +/*! + * to improve perf ! + */ +int MEDCoupling1GTUMesh::getCellContainingPoint(const double *pos, double eps) const +{ + MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m=buildUnstructured(); + return m->getCellContainingPoint(pos,eps); +} + +MEDCouplingFieldDouble *MEDCoupling1GTUMesh::buildOrthogonalField() const +{ + MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m=buildUnstructured(); + MEDCouplingAutoRefCountObjectPtr<MEDCouplingFieldDouble> ret=m->buildOrthogonalField(); + ret->setMesh(this); + return ret.retn(); +} + +DataArrayInt *MEDCoupling1GTUMesh::getCellsInBoundingBox(const double *bbox, double eps) const +{ + MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m=buildUnstructured(); + return m->getCellsInBoundingBox(bbox,eps); +} + +DataArrayInt *MEDCoupling1GTUMesh::getCellsInBoundingBox(const INTERP_KERNEL::DirectedBoundingBox& bbox, double eps) +{ + MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m=buildUnstructured(); + return m->getCellsInBoundingBox(bbox,eps); +} + +MEDCouplingPointSet *MEDCoupling1GTUMesh::buildFacePartOfMySelfNode(const int *start, const int *end, bool fullyIn) const +{ + MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m=buildUnstructured(); + return m->buildFacePartOfMySelfNode(start,end,fullyIn); +} + +DataArrayInt *MEDCoupling1GTUMesh::findBoundaryNodes() const +{ + MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m=buildUnstructured(); + return m->findBoundaryNodes(); +} + +MEDCouplingPointSet *MEDCoupling1GTUMesh::buildBoundaryMesh(bool keepCoords) const +{ + MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m=buildUnstructured(); + return m->buildBoundaryMesh(keepCoords); +} + +void MEDCoupling1GTUMesh::findCommonCells(int compType, int startCellId, DataArrayInt *& commonCellsArr, DataArrayInt *& commonCellsIArr) const +{ + MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m=buildUnstructured(); + m->findCommonCells(compType,startCellId,commonCellsArr,commonCellsIArr); +} + +int MEDCoupling1GTUMesh::getNodalConnectivityLength() const +{ + const DataArrayInt *c1(getNodalConnectivity()); + if(!c1) + throw INTERP_KERNEL::Exception("MEDCoupling1GTUMesh::getNodalConnectivityLength : no connectivity set !"); + if(c1->getNumberOfComponents()!=1) + throw INTERP_KERNEL::Exception("MEDCoupling1GTUMesh::getNodalConnectivityLength : Nodal connectivity array set must have exactly one component !"); + if(!c1->isAllocated()) + throw INTERP_KERNEL::Exception("MEDCoupling1GTUMesh::getNodalConnectivityLength : Nodal connectivity array must be allocated !"); + return c1->getNumberOfTuples(); +} + +/*! + * This method aggregates all the meshes in \a parts to put them in a single unstructured mesh (those returned). + * The order of cells is the returned instance is those in the order of instances in \a parts. + * + * \param [in] parts - all not null parts of single geo type meshes to be aggreagated having the same mesh dimension and same coordinates. + * \return MEDCouplingUMesh * - new object to be dealt by the caller. + * + * \throw If one element is null in \a parts. + * \throw If not all the parts do not have the same mesh dimension. + * \throw If not all the parts do not share the same coordinates. + * \throw If not all the parts have their connectivity set properly. + * \throw If \a parts is empty. + */ +MEDCouplingUMesh *MEDCoupling1GTUMesh::AggregateOnSameCoordsToUMesh(const std::vector< const MEDCoupling1GTUMesh *>& parts) +{ + if(parts.empty()) + throw INTERP_KERNEL::Exception("MEDCoupling1GTUMesh::AggregateOnSameCoordsToUMesh : input parts vector is empty !"); + const MEDCoupling1GTUMesh *firstPart(parts[0]); + if(!firstPart) + throw INTERP_KERNEL::Exception("MEDCoupling1GTUMesh::AggregateOnSameCoordsToUMesh : the first instance in input parts is null !"); + const DataArrayDouble *coords(firstPart->getCoords()); + int meshDim(firstPart->getMeshDimension()); + MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> ret(MEDCouplingUMesh::New(firstPart->getName(),meshDim)); ret->setDescription(firstPart->getDescription()); + ret->setCoords(coords); + int nbOfCells(0),connSize(0); + for(std::vector< const MEDCoupling1GTUMesh *>::const_iterator it=parts.begin();it!=parts.end();it++) + { + if(!(*it)) + throw INTERP_KERNEL::Exception("MEDCoupling1GTUMesh::AggregateOnSameCoordsToUMesh : presence of null pointer in input vector !"); + if((*it)->getMeshDimension()!=meshDim) + throw INTERP_KERNEL::Exception("MEDCoupling1GTUMesh::AggregateOnSameCoordsToUMesh : all the instances in input vector must have same mesh dimension !"); + if((*it)->getCoords()!=coords) + throw INTERP_KERNEL::Exception("MEDCoupling1GTUMesh::AggregateOnSameCoordsToUMesh : all the instances must share the same coordinates pointer !"); + nbOfCells+=(*it)->getNumberOfCells(); + connSize+=(*it)->getNodalConnectivityLength(); + } + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> conn(DataArrayInt::New()),connI(DataArrayInt::New()); + connI->alloc(nbOfCells+1,1); conn->alloc(connSize+nbOfCells,1); + int *c(conn->getPointer()),*ci(connI->getPointer()); *ci=0; + for(std::vector< const MEDCoupling1GTUMesh *>::const_iterator it=parts.begin();it!=parts.end();it++) + { + int curNbCells((*it)->getNumberOfCells()); + int geoType((int)(*it)->getCellModelEnum()); + const int *cinPtr((*it)->getNodalConnectivity()->begin()); + const MEDCoupling1SGTUMesh *ps(dynamic_cast<const MEDCoupling1SGTUMesh *>(*it)); + const MEDCoupling1DGTUMesh *pd(dynamic_cast<const MEDCoupling1DGTUMesh *>(*it)); + if(ps && !pd) + { + int nNodesPerCell(ps->getNumberOfNodesPerCell()); + for(int i=0;i<curNbCells;i++,ci++,cinPtr+=nNodesPerCell) + { + *c++=geoType; + c=std::copy(cinPtr,cinPtr+nNodesPerCell,c); + ci[1]=ci[0]+nNodesPerCell+1; + } + } + else if(!ps && pd) + { + const int *ciinPtr(pd->getNodalConnectivityIndex()->begin()); + for(int i=0;i<curNbCells;i++,ci++,ciinPtr++) + { + *c++=geoType; + c=std::copy(cinPtr+ciinPtr[0],cinPtr+ciinPtr[1],c); + ci[1]=ci[0]+ciinPtr[1]-ciinPtr[0]+1; + } + } + else + throw INTERP_KERNEL::Exception("MEDCoupling1GTUMesh::AggregateOnSameCoordsToUMesh : presence of instance which type is not in [MEDCoupling1SGTUMesh,MEDCoupling1DGTUMesh] !"); + } + ret->setConnectivity(conn,connI,true); + return ret.retn(); +} + +//== + +MEDCoupling1SGTUMesh::MEDCoupling1SGTUMesh(const MEDCoupling1SGTUMesh& other, bool recDeepCpy):MEDCoupling1GTUMesh(other,recDeepCpy),_conn(other._conn) +{ + if(recDeepCpy) + { + const DataArrayInt *c(other._conn); + if(c) + _conn=c->deepCpy(); + } +} + +MEDCoupling1SGTUMesh::MEDCoupling1SGTUMesh(const std::string& name, const INTERP_KERNEL::CellModel& cm):MEDCoupling1GTUMesh(name,cm) +{ +} + +MEDCoupling1SGTUMesh::MEDCoupling1SGTUMesh() +{ +} + +MEDCoupling1SGTUMesh *MEDCoupling1SGTUMesh::New() +{ + return new MEDCoupling1SGTUMesh; +} + +MEDCoupling1SGTUMesh *MEDCoupling1SGTUMesh::New(const std::string& name, INTERP_KERNEL::NormalizedCellType type) +{ + if(type==INTERP_KERNEL::NORM_ERROR) + throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::New : NORM_ERROR is not a valid type to be used as base geometric type for a mesh !"); + const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(type); + if(cm.isDynamic()) + { + std::ostringstream oss; oss << "MEDCoupling1SGTUMesh::New : the input geometric type " << cm.getRepr() << " is dynamic ! Only static types are allowed here !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + return new MEDCoupling1SGTUMesh(name,cm); +} + +MEDCoupling1SGTUMesh *MEDCoupling1SGTUMesh::New(const MEDCouplingUMesh *m) +{ + if(!m) + throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::New : input mesh is null !"); + std::set<INTERP_KERNEL::NormalizedCellType> gts(m->getAllGeoTypes()); + if(gts.size()!=1) + throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::New : input mesh must have exactly one geometric type !"); + int geoType((int)*gts.begin()); + MEDCouplingAutoRefCountObjectPtr<MEDCoupling1SGTUMesh> ret(MEDCoupling1SGTUMesh::New(m->getName(),*gts.begin())); + ret->setCoords(m->getCoords()); ret->setDescription(m->getDescription()); + int nbCells(m->getNumberOfCells()); + int nbOfNodesPerCell(ret->getNumberOfNodesPerCell()); + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> conn(DataArrayInt::New()); conn->alloc(nbCells*nbOfNodesPerCell,1); + int *c(conn->getPointer()); + const int *cin(m->getNodalConnectivity()->begin()),*ciin(m->getNodalConnectivityIndex()->begin()); + for(int i=0;i<nbCells;i++,ciin++) + { + if(cin[ciin[0]]==geoType) + { + if(ciin[1]-ciin[0]==nbOfNodesPerCell+1) + c=std::copy(cin+ciin[0]+1,cin+ciin[1],c); + else + { + std::ostringstream oss; oss << "MEDCoupling1SGTUMesh::New(const MEDCouplingUMesh *m) : something is wrong in the input mesh at cell #" << i << " ! The size of cell is not those expected (" << nbOfNodesPerCell << ") !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + } + else + { + std::ostringstream oss; oss << "MEDCoupling1SGTUMesh::New(const MEDCouplingUMesh *m) : something is wrong in the input mesh at cell #" << i << " ! The geometric type is not those expected !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + } + ret->setNodalConnectivity(conn); + try + { ret->copyTinyInfoFrom(m); } + catch(INTERP_KERNEL::Exception&) { } + return ret.retn(); +} + +MEDCoupling1SGTUMesh *MEDCoupling1SGTUMesh::clone(bool recDeepCpy) const +{ + return new MEDCoupling1SGTUMesh(*this,recDeepCpy); +} + +/*! + * This method behaves mostly like MEDCoupling1SGTUMesh::deepCpy method, except that only nodal connectivity arrays are deeply copied. + * The coordinates are shared between \a this and the returned instance. + * + * \return MEDCouplingUMesh * - A new object instance holding the copy of \a this (deep for connectivity, shallow for coordiantes) + * \sa MEDCoupling1SGTUMesh::deepCpy + */ +MEDCouplingPointSet *MEDCoupling1SGTUMesh::deepCpyConnectivityOnly() const +{ + checkCoherency(); + MEDCouplingAutoRefCountObjectPtr<MEDCoupling1SGTUMesh> ret(clone(false)); + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> c(_conn->deepCpy()); + ret->setNodalConnectivity(c); + return ret.retn(); +} + +void MEDCoupling1SGTUMesh::shallowCopyConnectivityFrom(const MEDCouplingPointSet *other) +{ + if(!other) + throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::shallowCopyConnectivityFrom : input pointer is null !"); + const MEDCoupling1SGTUMesh *otherC=dynamic_cast<const MEDCoupling1SGTUMesh *>(other); + if(!otherC) + throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::shallowCopyConnectivityFrom : input pointer is not an MEDCoupling1SGTUMesh instance !"); + setNodalConnectivity(otherC->getNodalConnectivity()); +} + +void MEDCoupling1SGTUMesh::updateTime() const +{ + MEDCoupling1GTUMesh::updateTime(); + const DataArrayInt *c(_conn); + if(c) + updateTimeWith(*c); +} + +std::size_t MEDCoupling1SGTUMesh::getHeapMemorySizeWithoutChildren() const +{ + return MEDCoupling1GTUMesh::getHeapMemorySizeWithoutChildren(); +} + +std::vector<const BigMemoryObject *> MEDCoupling1SGTUMesh::getDirectChildrenWithNull() const +{ + std::vector<const BigMemoryObject *> ret(MEDCoupling1GTUMesh::getDirectChildrenWithNull()); + ret.push_back((const DataArrayInt *)_conn); + return ret; +} + +MEDCouplingMesh *MEDCoupling1SGTUMesh::deepCpy() const +{ + return clone(true); +} + +bool MEDCoupling1SGTUMesh::isEqualIfNotWhy(const MEDCouplingMesh *other, double prec, std::string& reason) const +{ + if(!other) + throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::isEqualIfNotWhy : input other pointer is null !"); + std::ostringstream oss; oss.precision(15); + const MEDCoupling1SGTUMesh *otherC=dynamic_cast<const MEDCoupling1SGTUMesh *>(other); + if(!otherC) + { + reason="mesh given in input is not castable in MEDCoupling1SGTUMesh !"; + return false; + } + if(!MEDCoupling1GTUMesh::isEqualIfNotWhy(other,prec,reason)) + return false; + const DataArrayInt *c1(_conn),*c2(otherC->_conn); + if(c1==c2) + return true; + if(!c1 || !c2) + { + reason="in connectivity of single static geometric type exactly one among this and other is null !"; + return false; + } + if(!c1->isEqualIfNotWhy(*c2,reason)) + { + reason.insert(0,"Nodal connectivity DataArrayInt differ : "); + return false; + } + return true; +} + +bool MEDCoupling1SGTUMesh::isEqualWithoutConsideringStr(const MEDCouplingMesh *other, double prec) const +{ + if(!other) + throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::isEqualWithoutConsideringStr : input other pointer is null !"); + const MEDCoupling1SGTUMesh *otherC=dynamic_cast<const MEDCoupling1SGTUMesh *>(other); + if(!otherC) + return false; + if(!MEDCoupling1GTUMesh::isEqualWithoutConsideringStr(other,prec)) + return false; + const DataArrayInt *c1(_conn),*c2(otherC->_conn); + if(c1==c2) + return true; + if(!c1 || !c2) + return false; + if(!c1->isEqualWithoutConsideringStr(*c2)) + return false; + return true; +} + +void MEDCoupling1SGTUMesh::checkCoherencyOfConnectivity() const +{ + const DataArrayInt *c1(_conn); + if(c1) + { + if(c1->getNumberOfComponents()!=1) + throw INTERP_KERNEL::Exception("Nodal connectivity array is expected to be with number of components set to one !"); + if(c1->getInfoOnComponent(0)!="") + throw INTERP_KERNEL::Exception("Nodal connectivity array is expected to have no info on its single component !"); + c1->checkAllocated(); + } + else + throw INTERP_KERNEL::Exception("Nodal connectivity array not defined !"); +} + +void MEDCoupling1SGTUMesh::checkCoherency() const +{ + MEDCouplingPointSet::checkCoherency(); + checkCoherencyOfConnectivity(); +} + +void MEDCoupling1SGTUMesh::checkCoherency1(double eps) const +{ + checkCoherency(); + const DataArrayInt *c1(_conn); + int nbOfTuples=c1->getNumberOfTuples(); + int nbOfNodesPerCell=(int)_cm->getNumberOfNodes(); + if(nbOfTuples%nbOfNodesPerCell!=0) + { + std::ostringstream oss; oss << "MEDCoupling1SGTUMesh::checkCoherency1 : the nb of tuples in conn is " << nbOfTuples << " and number of nodes per cell is " << nbOfNodesPerCell << ". But " << nbOfTuples << "%" << nbOfNodesPerCell << " !=0 !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + int nbOfNodes=getNumberOfNodes(); + int nbOfCells=nbOfTuples/nbOfNodesPerCell; + const int *w(c1->begin()); + for(int i=0;i<nbOfCells;i++) + for(int j=0;j<nbOfNodesPerCell;j++,w++) + { + if(*w<0 || *w>=nbOfNodes) + { + std::ostringstream oss; oss << "At node #" << j << " of cell #" << i << ", is equal to " << *w << " must be in [0," << nbOfNodes << ") !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + } +} + +void MEDCoupling1SGTUMesh::checkCoherency2(double eps) const +{ + checkCoherency1(eps); +} + +int MEDCoupling1SGTUMesh::getNumberOfCells() const +{ + int nbOfTuples=getNodalConnectivityLength(); + int nbOfNodesPerCell=getNumberOfNodesPerCell(); + if(nbOfTuples%nbOfNodesPerCell!=0) + { + std::ostringstream oss; oss << "MEDCoupling1SGTUMesh:getNumberOfCells: : the nb of tuples in conn is " << nbOfTuples << " and number of nodes per cell is " << nbOfNodesPerCell << ". But " << nbOfTuples << "%" << nbOfNodesPerCell << " !=0 !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + return nbOfTuples/nbOfNodesPerCell; +} + +int MEDCoupling1SGTUMesh::getNumberOfNodesInCell(int cellId) const +{ + return getNumberOfNodesPerCell(); +} + +int MEDCoupling1SGTUMesh::getNumberOfNodesPerCell() const +{ + checkNonDynamicGeoType(); + return (int)_cm->getNumberOfNodes(); +} + +DataArrayInt *MEDCoupling1SGTUMesh::computeNbOfNodesPerCell() const +{ + checkNonDynamicGeoType(); + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New(); + ret->alloc(getNumberOfCells(),1); + ret->fillWithValue((int)_cm->getNumberOfNodes()); + return ret.retn(); +} + +DataArrayInt *MEDCoupling1SGTUMesh::computeNbOfFacesPerCell() const +{ + checkNonDynamicGeoType(); + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New(); + ret->alloc(getNumberOfCells(),1); + ret->fillWithValue((int)_cm->getNumberOfSons()); + return ret.retn(); +} + +DataArrayInt *MEDCoupling1SGTUMesh::computeEffectiveNbOfNodesPerCell() const +{ + checkNonDynamicGeoType(); + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New(); + int nbCells(getNumberOfCells()); + ret->alloc(nbCells,1); + int *retPtr(ret->getPointer()); + int nbNodesPerCell(getNumberOfNodesPerCell()); + const int *conn(_conn->begin()); + for(int i=0;i<nbCells;i++,conn+=nbNodesPerCell,retPtr++) + { + std::set<int> s(conn,conn+nbNodesPerCell); + *retPtr=(int)s.size(); + } + return ret.retn(); +} + +void MEDCoupling1SGTUMesh::getNodeIdsOfCell(int cellId, std::vector<int>& conn) const +{ + int sz=getNumberOfNodesPerCell(); + conn.resize(sz); + if(cellId>=0 && cellId<getNumberOfCells()) + std::copy(_conn->begin()+cellId*sz,_conn->begin()+(cellId+1)*sz,conn.begin()); + else + { + std::ostringstream oss; oss << "MEDCoupling1SGTUMesh::getNodeIdsOfCell : request for cellId #" << cellId << " must be in [0," << getNumberOfCells() << ") !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } +} + +void MEDCoupling1SGTUMesh::checkNonDynamicGeoType() const +{ + if(_cm->isDynamic()) + throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::checkNonDynamicGeoType : internal error ! the internal geo type is dynamic ! should be static !"); +} + +std::string MEDCoupling1SGTUMesh::simpleRepr() const +{ + static const char msg0[]="No coordinates specified !"; + std::ostringstream ret; + ret << "Single static geometic type (" << _cm->getRepr() << ") unstructured 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 << "Mesh dimension : " << getMeshDimension() << "\nSpace dimension : "; + if(_coords!=0) + { + const int spaceDim=getSpaceDimension(); + ret << spaceDim << "\nInfo attached on space dimension : "; + for(int i=0;i<spaceDim;i++) + ret << "\"" << _coords->getInfoOnComponent(i) << "\" "; + ret << "\n"; + } + else + ret << msg0 << "\n"; + ret << "Number of nodes : "; + if(_coords!=0) + ret << getNumberOfNodes() << "\n"; + else + ret << msg0 << "\n"; + ret << "Number of cells : "; + if((const DataArrayInt *)_conn) + { + if(_conn->isAllocated()) + { + if(_conn->getNumberOfComponents()==1) + ret << getNumberOfCells() << "\n"; + else + ret << "Nodal connectivity array specified and allocated but with not exactly one component !" << "\n"; + } + else + ret << "Nodal connectivity array specified but not allocated !" << "\n"; + } + else + ret << "No connectivity specified !" << "\n"; + ret << "Cell type : " << _cm->getRepr() << "\n"; + return ret.str(); +} + +std::string MEDCoupling1SGTUMesh::advancedRepr() const +{ + std::ostringstream ret; + ret << simpleRepr(); + ret << "\nCoordinates array : \n___________________\n\n"; + if(_coords) + _coords->reprWithoutNameStream(ret); + else + ret << "No array set !\n"; + ret << "\n\nConnectivity array : \n____________________\n\n"; + // + if((const DataArrayInt *)_conn) + { + if(_conn->isAllocated()) + { + if(_conn->getNumberOfComponents()==1) + { + int nbOfCells=getNumberOfCells(); + int sz=getNumberOfNodesPerCell(); + const int *connPtr=_conn->begin(); + for(int i=0;i<nbOfCells;i++,connPtr+=sz) + { + ret << "Cell #" << i << " : "; + std::copy(connPtr,connPtr+sz,std::ostream_iterator<int>(ret," ")); + ret << "\n"; + } + } + else + ret << "Nodal connectivity array specified and allocated but with not exactly one component !" << "\n"; + } + else + ret << "Nodal connectivity array specified but not allocated !" << "\n"; + } + else + ret << "No connectivity specified !" << "\n"; + return ret.str(); +} + +DataArrayDouble *MEDCoupling1SGTUMesh::computeIsoBarycenterOfNodesPerCell() const +{ + MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New(); + int spaceDim=getSpaceDimension(); + int nbOfCells=getNumberOfCells();//checkCoherency() + int nbOfNodes=getNumberOfNodes(); + ret->alloc(nbOfCells,spaceDim); + double *ptToFill=ret->getPointer(); + const double *coor=_coords->begin(); + const int *nodal=_conn->begin(); + int sz=getNumberOfNodesPerCell(); + double coeff=1./(double)sz; + for(int i=0;i<nbOfCells;i++,ptToFill+=spaceDim) + { + std::fill(ptToFill,ptToFill+spaceDim,0.); + for(int j=0;j<sz;j++,nodal++) + if(*nodal>=0 && *nodal<nbOfNodes) + std::transform(coor+spaceDim*nodal[0],coor+spaceDim*(nodal[0]+1),ptToFill,ptToFill,std::plus<double>()); + else + { + std::ostringstream oss; oss << "MEDCoupling1SGTUMesh::computeIsoBarycenterOfNodesPerCell : on cell #" << i << " presence of nodeId #" << *nodal << " should be in [0," << nbOfNodes << ") !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + std::transform(ptToFill,ptToFill+spaceDim,ptToFill,std::bind2nd(std::multiplies<double>(),coeff)); + } + return ret.retn(); +} + +void MEDCoupling1SGTUMesh::renumberCells(const int *old2NewBg, bool check) +{ + int nbCells=getNumberOfCells(); + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> o2n=DataArrayInt::New(); + o2n->useArray(old2NewBg,false,C_DEALLOC,nbCells,1); + if(check) + o2n=o2n->checkAndPreparePermutation(); + // + const int *conn=_conn->begin(); + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> n2o=o2n->invertArrayO2N2N2O(nbCells); + const int *n2oPtr=n2o->begin(); + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> newConn=DataArrayInt::New(); + newConn->alloc(_conn->getNumberOfTuples(),1); + newConn->copyStringInfoFrom(*_conn); + int sz=getNumberOfNodesPerCell(); + // + int *newC=newConn->getPointer(); + for(int i=0;i<nbCells;i++,newC+=sz) + { + int pos=n2oPtr[i]; + std::copy(conn+pos*sz,conn+(pos+1)*sz,newC); + } + _conn=newConn; +} + +/*! + * Keeps from \a this only cells which constituing point id are in the ids specified by [\a begin,\a end). + * The resulting cell ids are stored at the end of the 'cellIdsKept' parameter. + * Parameter \a fullyIn specifies if a cell that has part of its nodes in ids array is kept or not. + * If \a fullyIn is true only cells whose ids are \b fully contained in [\a begin,\a end) tab will be kept. + * + * \param [in] begin input start of array of node ids. + * \param [in] end input end of array of node ids. + * \param [in] fullyIn input that specifies if all node ids must be in [\a begin,\a end) array to consider cell to be in. + * \param [in,out] cellIdsKeptArr array where all candidate cell ids are put at the end. + */ +void MEDCoupling1SGTUMesh::fillCellIdsToKeepFromNodeIds(const int *begin, const int *end, bool fullyIn, DataArrayInt *&cellIdsKeptArr) const +{ + int nbOfCells=getNumberOfCells(); + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> cellIdsKept=DataArrayInt::New(); cellIdsKept->alloc(0,1); + int tmp=-1; + int sz=_conn->getMaxValue(tmp); sz=std::max(sz,0)+1; + std::vector<bool> fastFinder(sz,false); + for(const int *work=begin;work!=end;work++) + if(*work>=0 && *work<sz) + fastFinder[*work]=true; + const int *conn=_conn->begin(); + int nbNodesPerCell=getNumberOfNodesPerCell(); + for(int i=0;i<nbOfCells;i++,conn+=nbNodesPerCell) + { + int ref=0,nbOfHit=0; + for(int j=0;j<nbNodesPerCell;j++) + if(conn[j]>=0) + { + ref++; + if(fastFinder[conn[j]]) + nbOfHit++; + } + if((ref==nbOfHit && fullyIn) || (nbOfHit!=0 && !fullyIn)) + cellIdsKept->pushBackSilent(i); + } + cellIdsKeptArr=cellIdsKept.retn(); +} + +MEDCouplingMesh *MEDCoupling1SGTUMesh::mergeMyselfWith(const MEDCouplingMesh *other) const +{ + if(other->getType()!=SINGLE_STATIC_GEO_TYPE_UNSTRUCTURED) + throw INTERP_KERNEL::Exception("Merge of umesh only available with umesh single static geo type each other !"); + const MEDCoupling1SGTUMesh *otherC=static_cast<const MEDCoupling1SGTUMesh *>(other); + return Merge1SGTUMeshes(this,otherC); +} + +MEDCouplingUMesh *MEDCoupling1SGTUMesh::buildUnstructured() const +{ + MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> ret=MEDCouplingUMesh::New(getName(),getMeshDimension()); + ret->setCoords(getCoords()); + const int *nodalConn=_conn->begin(); + int nbCells=getNumberOfCells(); + int nbNodesPerCell=getNumberOfNodesPerCell(); + int geoType=(int)getCellModelEnum(); + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> c=DataArrayInt::New(); c->alloc(nbCells*(nbNodesPerCell+1),1); + int *cPtr=c->getPointer(); + for(int i=0;i<nbCells;i++,nodalConn+=nbNodesPerCell) + { + *cPtr++=geoType; + cPtr=std::copy(nodalConn,nodalConn+nbNodesPerCell,cPtr); + } + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> cI=DataArrayInt::Range(0,(nbCells+1)*(nbNodesPerCell+1),nbNodesPerCell+1); + ret->setConnectivity(c,cI,true); + try + { ret->copyTinyInfoFrom(this); } + catch(INTERP_KERNEL::Exception&) { } + return ret.retn(); +} + +DataArrayInt *MEDCoupling1SGTUMesh::simplexize(int policy) +{ + switch(policy) + { + case 0: + return simplexizePol0(); + case 1: + return simplexizePol1(); + case (int) INTERP_KERNEL::PLANAR_FACE_5: + return simplexizePlanarFace5(); + case (int) INTERP_KERNEL::PLANAR_FACE_6: + return simplexizePlanarFace6(); + default: + throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::simplexize : unrecognized policy ! Must be :\n - 0 or 1 (only available for meshdim=2) \n - PLANAR_FACE_5, PLANAR_FACE_6 (only for meshdim=3)"); + } +} + +/// @cond INTERNAL + +struct MEDCouplingAccVisit +{ + MEDCouplingAccVisit():_new_nb_of_nodes(0) { } + int operator()(int val) { if(val!=-1) return _new_nb_of_nodes++; else return -1; } + int _new_nb_of_nodes; +}; + +/// @endcond + +/*! + * This method returns all node ids used in \b this. The data array returned has to be dealt by the caller. + * The returned node ids are sortes ascendingly. This method is closed to MEDCoupling1SGTUMesh::getNodeIdsInUse except + * the format of returned DataArrayInt instance. + * + * \return a newly allocated DataArrayInt sorted ascendingly of fetched node ids. + * \sa MEDCoupling1SGTUMesh::getNodeIdsInUse, areAllNodesFetched + */ +DataArrayInt *MEDCoupling1SGTUMesh::computeFetchedNodeIds() const +{ + checkCoherencyOfConnectivity(); + int nbNodes(getNumberOfNodes()); + std::vector<bool> fetchedNodes(nbNodes,false); + computeNodeIdsAlg(fetchedNodes); + int sz((int)std::count(fetchedNodes.begin(),fetchedNodes.end(),true)); + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(sz,1); + int *retPtr(ret->getPointer()); + for(int i=0;i<nbNodes;i++) + if(fetchedNodes[i]) + *retPtr++=i; + return ret.retn(); +} + +/*! + * Finds nodes not used in any cell and returns an array giving a new id to every node + * by excluding the unused nodes, for which the array holds -1. The result array is + * a mapping in "Old to New" mode. + * \param [out] nbrOfNodesInUse - number of node ids present in the nodal connectivity. + * \return DataArrayInt * - a new instance of DataArrayInt. Its length is \a + * this->getNumberOfNodes(). It holds for each node of \a this mesh either -1 + * if the node is unused or a new id else. The caller is to delete this + * array using decrRef() as it is no more needed. + * \throw If the coordinates array is not set. + * \throw If the nodal connectivity of cells is not defined. + * \throw If the nodal connectivity includes an invalid id. + * \sa MEDCoupling1SGTUMesh::computeFetchedNodeIds, areAllNodesFetched + */ +DataArrayInt *MEDCoupling1SGTUMesh::getNodeIdsInUse(int& nbrOfNodesInUse) const +{ + nbrOfNodesInUse=-1; + int nbOfNodes=getNumberOfNodes(); + int nbOfCells=getNumberOfCells(); + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret(DataArrayInt::New()); + ret->alloc(nbOfNodes,1); + int *traducer=ret->getPointer(); + std::fill(traducer,traducer+nbOfNodes,-1); + const int *conn=_conn->begin(); + int nbNodesPerCell=getNumberOfNodesPerCell(); + for(int i=0;i<nbOfCells;i++) + for(int j=0;j<nbNodesPerCell;j++,conn++) + if(*conn>=0 && *conn<nbOfNodes) + traducer[*conn]=1; + else + { + std::ostringstream oss; oss << "MEDCoupling1SGTUMesh::getNodeIdsInUse : In cell #" << i << " presence of node id " << conn[j] << " not in [0," << nbOfNodes << ") !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + nbrOfNodesInUse=(int)std::count(traducer,traducer+nbOfNodes,1); + std::transform(traducer,traducer+nbOfNodes,traducer,MEDCouplingAccVisit()); + return ret.retn(); +} + +/*! + * This method renumbers only nodal connectivity in \a this. The renumbering is only an offset applied. So this method is a specialization of + * \a renumberNodesInConn. \b WARNING, this method does not check that the resulting node ids in the nodal connectivity is in a valid range ! + * + * \param [in] offset - specifies the offset to be applied on each element of connectivity. + * + * \sa renumberNodesInConn + */ +void MEDCoupling1SGTUMesh::renumberNodesWithOffsetInConn(int offset) +{ + getNumberOfCells();//only to check that all is well defined. + _conn->applyLin(1,offset); + updateTime(); +} + +/*! + * Same than renumberNodesInConn(const int *) except that here the format of old-to-new traducer is using map instead + * of array. This method is dedicated for renumbering from a big set of nodes the a tiny set of nodes which is the case during extraction + * of a big mesh. + */ +void MEDCoupling1SGTUMesh::renumberNodesInConn(const INTERP_KERNEL::HashMap<int,int>& newNodeNumbersO2N) +{ + getNumberOfCells();//only to check that all is well defined. + int *begPtr(_conn->getPointer()); + int nbElt(_conn->getNumberOfTuples()); + int *endPtr(begPtr+nbElt); + for(int *it=begPtr;it!=endPtr;it++) + { + INTERP_KERNEL::HashMap<int,int>::const_iterator it2(newNodeNumbersO2N.find(*it)); + if(it2!=newNodeNumbersO2N.end()) + { + *it=(*it2).second; + } + else + { + std::ostringstream oss; oss << "MEDCoupling1SGTUMesh::renumberNodesInConn : At pos #" << std::distance(begPtr,it) << " of nodal connectivity value is " << *it << ". Not in map !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + } + updateTime(); +} + +/*! + * Changes ids of nodes within the nodal connectivity arrays according to a permutation + * array in "Old to New" mode. The node coordinates array is \b not changed by this method. + * This method is a generalization of shiftNodeNumbersInConn(). + * \warning This method performs no check of validity of new ids. **Use it with care !** + * \param [in] newNodeNumbersO2N - a permutation array, of length \a + * this->getNumberOfNodes(), in "Old to New" mode. + * See \ref numbering for more info on renumbering modes. + * \throw If the nodal connectivity of cells is not defined. + */ +void MEDCoupling1SGTUMesh::renumberNodesInConn(const int *newNodeNumbersO2N) +{ + getNumberOfCells();//only to check that all is well defined. + _conn->transformWithIndArr(newNodeNumbersO2N,newNodeNumbersO2N+getNumberOfNodes()); + updateTime(); +} + +MEDCoupling1SGTUMesh *MEDCoupling1SGTUMesh::Merge1SGTUMeshes(const MEDCoupling1SGTUMesh *mesh1, const MEDCoupling1SGTUMesh *mesh2) +{ + std::vector<const MEDCoupling1SGTUMesh *> tmp(2); + tmp[0]=const_cast<MEDCoupling1SGTUMesh *>(mesh1); tmp[1]=const_cast<MEDCoupling1SGTUMesh *>(mesh2); + return Merge1SGTUMeshes(tmp); +} + +MEDCoupling1SGTUMesh *MEDCoupling1SGTUMesh::Merge1SGTUMeshes(std::vector<const MEDCoupling1SGTUMesh *>& a) +{ + std::size_t sz=a.size(); + if(sz==0) + return Merge1SGTUMeshesLL(a); + for(std::size_t ii=0;ii<sz;ii++) + if(!a[ii]) + { + std::ostringstream oss; oss << "MEDCoupling1SGTUMesh::Merge1SGTUMeshes : item #" << ii << " in input array of size "<< sz << " is empty !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + const INTERP_KERNEL::CellModel *cm=&(a[0]->getCellModel()); + for(std::size_t ii=0;ii<sz;ii++) + if(&(a[ii]->getCellModel())!=cm) + throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::Merge1SGTUMeshes : all items must have the same geo type !"); + std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCoupling1SGTUMesh> > bb(sz); + std::vector< const MEDCoupling1SGTUMesh * > aa(sz); + int spaceDim=-3; + for(std::size_t i=0;i<sz && spaceDim==-3;i++) + { + const MEDCoupling1SGTUMesh *cur=a[i]; + const DataArrayDouble *coo=cur->getCoords(); + if(coo) + spaceDim=coo->getNumberOfComponents(); + } + if(spaceDim==-3) + throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::Merge1SGTUMeshes : no spaceDim specified ! unable to perform merge !"); + for(std::size_t i=0;i<sz;i++) + { + bb[i]=a[i]->buildSetInstanceFromThis(spaceDim); + aa[i]=bb[i]; + } + return Merge1SGTUMeshesLL(aa); +} + +/*! + * \throw If presence of a null instance in the input vector \a a. + * \throw If a is empty + */ +MEDCoupling1SGTUMesh *MEDCoupling1SGTUMesh::Merge1SGTUMeshesOnSameCoords(std::vector<const MEDCoupling1SGTUMesh *>& a) +{ + if(a.empty()) + throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::Merge1SGTUMeshesOnSameCoords : input array must be NON EMPTY !"); + std::vector<const MEDCoupling1SGTUMesh *>::const_iterator it=a.begin(); + if(!(*it)) + throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::Merge1SGTUMeshesOnSameCoords : null instance in the first element of input vector !"); + std::vector<const DataArrayInt *> ncs(a.size()); + (*it)->getNumberOfCells();//to check that all is OK + const DataArrayDouble *coords=(*it)->getCoords(); + const INTERP_KERNEL::CellModel *cm=&((*it)->getCellModel()); + ncs[0]=(*it)->getNodalConnectivity(); + it++; + for(int i=1;it!=a.end();i++,it++) + { + if(!(*it)) + throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::Merge1SGTUMeshesOnSameCoords : presence of a null instance in the input vector !"); + if(cm!=&((*it)->getCellModel())) + throw INTERP_KERNEL::Exception("Geometric types mismatches, Merge1SGTUMeshes impossible !"); + (*it)->getNumberOfCells();//to check that all is OK + ncs[i]=(*it)->getNodalConnectivity(); + if(coords!=(*it)->getCoords()) + throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::Merge1SGTUMeshesOnSameCoords : not lying on same coords !"); + } + MEDCouplingAutoRefCountObjectPtr<MEDCoupling1SGTUMesh> ret(new MEDCoupling1SGTUMesh("merge",*cm)); + ret->setCoords(coords); + ret->_conn=DataArrayInt::Aggregate(ncs); + return ret.retn(); +} + +/*! + * Assume that all instances in \a a are non null. If null it leads to a crash. That's why this method is assigned to be low level (LL) + */ +MEDCoupling1SGTUMesh *MEDCoupling1SGTUMesh::Merge1SGTUMeshesLL(std::vector<const MEDCoupling1SGTUMesh *>& a) +{ + if(a.empty()) + throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::Merge1SGTUMeshes : input array must be NON EMPTY !"); + std::vector<const MEDCoupling1SGTUMesh *>::const_iterator it=a.begin(); + int nbOfCells=(*it)->getNumberOfCells(); + const INTERP_KERNEL::CellModel *cm=&((*it)->getCellModel()); + int nbNodesPerCell=(*it)->getNumberOfNodesPerCell(); + it++; + for(;it!=a.end();it++) + { + if(cm!=&((*it)->getCellModel())) + throw INTERP_KERNEL::Exception("Geometric types mismatches, Merge1SGTUMeshes impossible !"); + nbOfCells+=(*it)->getNumberOfCells(); + } + std::vector<const MEDCouplingPointSet *> aps(a.size()); + std::copy(a.begin(),a.end(),aps.begin()); + MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> pts=MergeNodesArray(aps); + MEDCouplingAutoRefCountObjectPtr<MEDCoupling1SGTUMesh> ret(new MEDCoupling1SGTUMesh("merge",*cm)); + ret->setCoords(pts); + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> c=DataArrayInt::New(); + c->alloc(nbOfCells*nbNodesPerCell,1); + int *cPtr=c->getPointer(); + int offset=0; + for(it=a.begin();it!=a.end();it++) + { + int curConnLgth=(*it)->getNodalConnectivityLength(); + const int *curC=(*it)->_conn->begin(); + cPtr=std::transform(curC,curC+curConnLgth,cPtr,std::bind2nd(std::plus<int>(),offset)); + offset+=(*it)->getNumberOfNodes(); + } + // + ret->setNodalConnectivity(c); + return ret.retn(); +} + +MEDCouplingPointSet *MEDCoupling1SGTUMesh::buildPartOfMySelfKeepCoords(const int *begin, const int *end) const +{ + int ncell=getNumberOfCells(); + MEDCouplingAutoRefCountObjectPtr<MEDCoupling1SGTUMesh> ret(new MEDCoupling1SGTUMesh(getName(),*_cm)); + ret->setCoords(_coords); + std::size_t nbOfElemsRet=std::distance(begin,end); + const int *inConn=_conn->getConstPointer(); + int sz=getNumberOfNodesPerCell(); + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> connRet=DataArrayInt::New(); connRet->alloc((int)nbOfElemsRet*sz,1); + int *connPtr=connRet->getPointer(); + for(const int *work=begin;work!=end;work++,connPtr+=sz) + { + if(*work>=0 && *work<ncell) + std::copy(inConn+(work[0])*sz,inConn+(work[0]+1)*sz,connPtr); + else + { + std::ostringstream oss; oss << "MEDCoupling1SGTUMesh::buildPartOfMySelfKeepCoords : On pos #" << std::distance(begin,work) << " input cell id =" << *work << " should be in [0," << ncell << ") !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + } + ret->_conn=connRet; + ret->copyTinyInfoFrom(this); + return ret.retn(); +} + +MEDCouplingPointSet *MEDCoupling1SGTUMesh::buildPartOfMySelfKeepCoords2(int start, int end, int step) const +{ + int ncell=getNumberOfCells(); + int nbOfElemsRet=DataArray::GetNumberOfItemGivenBESRelative(start,end,step,"MEDCoupling1SGTUMesh::buildPartOfMySelfKeepCoords2 : "); + MEDCouplingAutoRefCountObjectPtr<MEDCoupling1SGTUMesh> ret(new MEDCoupling1SGTUMesh(getName(),*_cm)); + ret->setCoords(_coords); + const int *inConn=_conn->getConstPointer(); + int sz=getNumberOfNodesPerCell(); + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> connRet=DataArrayInt::New(); connRet->alloc((int)nbOfElemsRet*sz,1); + int *connPtr=connRet->getPointer(); + int curId=start; + for(int i=0;i<nbOfElemsRet;i++,connPtr+=sz,curId+=step) + { + if(curId>=0 && curId<ncell) + std::copy(inConn+curId*sz,inConn+(curId+1)*sz,connPtr); + else + { + std::ostringstream oss; oss << "MEDCoupling1SGTUMesh::buildPartOfMySelfKeepCoords2 : On pos #" << i << " input cell id =" << curId << " should be in [0," << ncell << ") !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + } + ret->_conn=connRet; + ret->copyTinyInfoFrom(this); + return ret.retn(); +} + +void MEDCoupling1SGTUMesh::computeNodeIdsAlg(std::vector<bool>& nodeIdsInUse) const +{ + int sz((int)nodeIdsInUse.size()); + for(const int *conn=_conn->begin();conn!=_conn->end();conn++) + { + if(*conn>=0 && *conn<sz) + nodeIdsInUse[*conn]=true; + else + { + std::ostringstream oss; oss << "MEDCoupling1SGTUMesh::computeFetchedNodeIds : At pos #" << std::distance(_conn->begin(),conn) << " value is " << *conn << " must be in [0," << sz << ") !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + } +} + +MEDCoupling1SGTUMesh *MEDCoupling1SGTUMesh::buildSetInstanceFromThis(int spaceDim) const +{ + MEDCouplingAutoRefCountObjectPtr<MEDCoupling1SGTUMesh> ret(new MEDCoupling1SGTUMesh(getName(),*_cm)); + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> tmp1; + const DataArrayInt *nodalConn(_conn); + if(!nodalConn) + { + tmp1=DataArrayInt::New(); tmp1->alloc(0,1); + } + else + tmp1=_conn; + ret->_conn=tmp1; + if(!_coords) + { + MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> coords=DataArrayDouble::New(); coords->alloc(0,spaceDim); + ret->setCoords(coords); + } + else + ret->setCoords(_coords); + return ret.retn(); +} + +DataArrayInt *MEDCoupling1SGTUMesh::simplexizePol0() +{ + int nbOfCells=getNumberOfCells(); + if(getCellModelEnum()!=INTERP_KERNEL::NORM_QUAD4) + return DataArrayInt::Range(0,nbOfCells,1); + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> newConn=DataArrayInt::New(); newConn->alloc(2*3*nbOfCells,1); + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(2*nbOfCells,1); + const int *c(_conn->begin()); + int *retPtr(ret->getPointer()),*newConnPtr(newConn->getPointer()); + for(int i=0;i<nbOfCells;i++,c+=4,newConnPtr+=6,retPtr+=2) + { + newConnPtr[0]=c[0]; newConnPtr[1]=c[1]; newConnPtr[2]=c[2]; + newConnPtr[3]=c[0]; newConnPtr[4]=c[2]; newConnPtr[5]=c[3]; + retPtr[0]=i; retPtr[1]=i; + } + _conn=newConn; + _cm=&INTERP_KERNEL::CellModel::GetCellModel(INTERP_KERNEL::NORM_TRI3); + updateTime(); + return ret.retn(); +} + +DataArrayInt *MEDCoupling1SGTUMesh::simplexizePol1() +{ + int nbOfCells=getNumberOfCells(); + if(getCellModelEnum()!=INTERP_KERNEL::NORM_QUAD4) + return DataArrayInt::Range(0,nbOfCells,1); + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> newConn=DataArrayInt::New(); newConn->alloc(2*3*nbOfCells,1); + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(2*nbOfCells,1); + const int *c(_conn->begin()); + int *retPtr(ret->getPointer()),*newConnPtr(newConn->getPointer()); + for(int i=0;i<nbOfCells;i++,c+=4,newConnPtr+=6,retPtr+=2) + { + newConnPtr[0]=c[0]; newConnPtr[1]=c[1]; newConnPtr[2]=c[3]; + newConnPtr[3]=c[1]; newConnPtr[4]=c[2]; newConnPtr[5]=c[3]; + retPtr[0]=i; retPtr[1]=i; + } + _conn=newConn; + _cm=&INTERP_KERNEL::CellModel::GetCellModel(INTERP_KERNEL::NORM_TRI3); + updateTime(); + return ret.retn(); +} + +DataArrayInt *MEDCoupling1SGTUMesh::simplexizePlanarFace5() +{ + int nbOfCells=getNumberOfCells(); + if(getCellModelEnum()!=INTERP_KERNEL::NORM_HEXA8) + return DataArrayInt::Range(0,nbOfCells,1); + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> newConn=DataArrayInt::New(); newConn->alloc(5*4*nbOfCells,1); + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(5*nbOfCells,1); + const int *c(_conn->begin()); + int *retPtr(ret->getPointer()),*newConnPtr(newConn->getPointer()); + for(int i=0;i<nbOfCells;i++,c+=8,newConnPtr+=20,retPtr+=5) + { + for(int j=0;j<20;j++) + newConnPtr[j]=c[INTERP_KERNEL::SPLIT_NODES_5_WO[j]]; + retPtr[0]=i; retPtr[1]=i; retPtr[2]=i; retPtr[3]=i; retPtr[4]=i; + } + _conn=newConn; + _cm=&INTERP_KERNEL::CellModel::GetCellModel(INTERP_KERNEL::NORM_TETRA4); + updateTime(); + return ret.retn(); +} + +DataArrayInt *MEDCoupling1SGTUMesh::simplexizePlanarFace6() +{ + int nbOfCells=getNumberOfCells(); + if(getCellModelEnum()!=INTERP_KERNEL::NORM_HEXA8) + return DataArrayInt::Range(0,nbOfCells,1); + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> newConn=DataArrayInt::New(); newConn->alloc(6*4*nbOfCells,1); + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(6*nbOfCells,1); + const int *c(_conn->begin()); + int *retPtr(ret->getPointer()),*newConnPtr(newConn->getPointer()); + for(int i=0;i<nbOfCells;i++,c+=8,newConnPtr+=24,retPtr+=6) + { + for(int j=0;j<24;j++) + newConnPtr[j]=c[INTERP_KERNEL::SPLIT_NODES_6_WO[j]]; + retPtr[0]=i; retPtr[1]=i; retPtr[2]=i; retPtr[3]=i; retPtr[4]=i; retPtr[5]=i; + } + _conn=newConn; + _cm=&INTERP_KERNEL::CellModel::GetCellModel(INTERP_KERNEL::NORM_TETRA4); + updateTime(); + return ret.retn(); +} + +void MEDCoupling1SGTUMesh::reprQuickOverview(std::ostream& stream) const +{ + stream << "MEDCoupling1SGTUMesh C++ instance at " << this << ". Type=" << _cm->getRepr() << ". Name : \"" << getName() << "\"."; + stream << " Mesh dimension : " << getMeshDimension() << "."; + if(!_coords) + { stream << " No coordinates set !"; return ; } + if(!_coords->isAllocated()) + { stream << " Coordinates set but not allocated !"; return ; } + stream << " Space dimension : " << _coords->getNumberOfComponents() << "." << std::endl; + stream << "Number of nodes : " << _coords->getNumberOfTuples() << "."; + if(!(const DataArrayInt *)_conn) + { stream << std::endl << "Nodal connectivity NOT set !"; return ; } + if(_conn->isAllocated()) + { + if(_conn->getNumberOfComponents()==1) + stream << std::endl << "Number of cells : " << getNumberOfCells() << "."; + } +} + +void MEDCoupling1SGTUMesh::checkFullyDefined() const +{ + if(!((const DataArrayInt *)_conn) || !((const DataArrayDouble *)_coords)) + throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::checkFullyDefined : part of this is not fully defined."); +} + +/*! + * First step of unserialization process. + */ +bool MEDCoupling1SGTUMesh::isEmptyMesh(const std::vector<int>& tinyInfo) const +{ + throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::isEmptyMesh : not implemented yet !"); +} + +void MEDCoupling1SGTUMesh::getTinySerializationInformation(std::vector<double>& tinyInfoD, std::vector<int>& tinyInfo, std::vector<std::string>& 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<std::string> littleStrings2,littleStrings3; + if((const DataArrayDouble *)_coords) + _coords->getTinySerializationStrInformation(littleStrings2); + if((const DataArrayInt *)_conn) + _conn->getTinySerializationStrInformation(littleStrings3); + int sz0((int)littleStrings2.size()),sz1((int)littleStrings3.size()); + littleStrings.insert(littleStrings.end(),littleStrings2.begin(),littleStrings2.end()); + littleStrings.insert(littleStrings.end(),littleStrings3.begin(),littleStrings3.end()); + // + tinyInfo.push_back(getCellModelEnum()); + tinyInfo.push_back(it); + tinyInfo.push_back(order); + std::vector<int> tinyInfo2,tinyInfo3; + if((const DataArrayDouble *)_coords) + _coords->getTinySerializationIntInformation(tinyInfo2); + if((const DataArrayInt *)_conn) + _conn->getTinySerializationIntInformation(tinyInfo3); + int sz2((int)tinyInfo2.size()),sz3((int)tinyInfo3.size()); + tinyInfo.push_back(sz0); tinyInfo.push_back(sz1); tinyInfo.push_back(sz2); tinyInfo.push_back(sz3); + tinyInfo.insert(tinyInfo.end(),tinyInfo2.begin(),tinyInfo2.end()); + tinyInfo.insert(tinyInfo.end(),tinyInfo3.begin(),tinyInfo3.end()); + // + tinyInfoD.push_back(time); +} + +void MEDCoupling1SGTUMesh::resizeForUnserialization(const std::vector<int>& tinyInfo, DataArrayInt *a1, DataArrayDouble *a2, std::vector<std::string>& littleStrings) const +{ + std::vector<int> tinyInfo2(tinyInfo.begin()+7,tinyInfo.begin()+7+tinyInfo[5]); + std::vector<int> tinyInfo1(tinyInfo.begin()+7+tinyInfo[5],tinyInfo.begin()+7+tinyInfo[5]+tinyInfo[6]); + a1->resizeForUnserialization(tinyInfo1); + a2->resizeForUnserialization(tinyInfo2); +} + +void MEDCoupling1SGTUMesh::serialize(DataArrayInt *&a1, DataArrayDouble *&a2) const +{ + int sz(0); + if((const DataArrayInt *)_conn) + if(_conn->isAllocated()) + sz=_conn->getNbOfElems(); + a1=DataArrayInt::New(); + a1->alloc(sz,1); + if(sz!=0 && (const DataArrayInt *)_conn) + std::copy(_conn->begin(),_conn->end(),a1->getPointer()); + 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 MEDCoupling1SGTUMesh::unserialization(const std::vector<double>& tinyInfoD, const std::vector<int>& tinyInfo, const DataArrayInt *a1, DataArrayDouble *a2, + const std::vector<std::string>& littleStrings) +{ + INTERP_KERNEL::NormalizedCellType gt((INTERP_KERNEL::NormalizedCellType)tinyInfo[0]); + _cm=&INTERP_KERNEL::CellModel::GetCellModel(gt); + setName(littleStrings[0]); + setDescription(littleStrings[1]); + setTimeUnit(littleStrings[2]); + setTime(tinyInfoD[0],tinyInfo[1],tinyInfo[2]); + int sz0(tinyInfo[3]),sz1(tinyInfo[4]),sz2(tinyInfo[5]),sz3(tinyInfo[6]); + // + _coords=DataArrayDouble::New(); + std::vector<int> tinyInfo2(tinyInfo.begin()+7,tinyInfo.begin()+7+sz2); + _coords->resizeForUnserialization(tinyInfo2); + std::copy(a2->begin(),a2->end(),_coords->getPointer()); + _conn=DataArrayInt::New(); + std::vector<int> tinyInfo3(tinyInfo.begin()+7+sz2,tinyInfo.begin()+7+sz2+sz3); + _conn->resizeForUnserialization(tinyInfo3); + std::copy(a1->begin(),a1->end(),_conn->getPointer()); + std::vector<std::string> littleStrings2(littleStrings.begin()+3,littleStrings.begin()+3+sz0); + _coords->finishUnserialization(tinyInfo2,littleStrings2); + std::vector<std::string> littleStrings3(littleStrings.begin()+3+sz0,littleStrings.begin()+3+sz0+sz1); + _conn->finishUnserialization(tinyInfo3,littleStrings3); +} + +/*! + * 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 MEDCoupling1SGTUMesh::checkFastEquivalWith(const MEDCouplingMesh *other, double prec) const +{ + MEDCouplingPointSet::checkFastEquivalWith(other,prec); + const MEDCoupling1SGTUMesh *otherC=dynamic_cast<const MEDCoupling1SGTUMesh *>(other); + if(!otherC) + throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::checkFastEquivalWith : Two meshes are not unstructured with single static geometric type !"); + const DataArrayInt *c1(_conn),*c2(otherC->_conn); + if(c1==c2) + return; + if(!c1 || !c2) + throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::checkFastEquivalWith : presence of nodal connectivity only in one of the 2 meshes !"); + if((c1->isAllocated() && !c2->isAllocated()) || (!c1->isAllocated() && c2->isAllocated())) + throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::checkFastEquivalWith : in nodal connectivity, only one is allocated !"); + if(c1->getNumberOfComponents()!=1 || c1->getNumberOfComponents()!=1) + throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::checkFastEquivalWith : in nodal connectivity, must have 1 and only 1 component !"); + if(c1->getHashCode()!=c2->getHashCode()) + throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::checkFastEquivalWith : nodal connectivity differs"); +} + +MEDCouplingPointSet *MEDCoupling1SGTUMesh::mergeMyselfWithOnSameCoords(const MEDCouplingPointSet *other) const +{ + if(!other) + throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::mergeMyselfWithOnSameCoords : input other is null !"); + const MEDCoupling1SGTUMesh *otherC=dynamic_cast<const MEDCoupling1SGTUMesh *>(other); + if(!otherC) + throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::mergeMyselfWithOnSameCoords : the input other mesh is not of type single statuc geo type unstructured !"); + std::vector<const MEDCoupling1SGTUMesh *> ms(2); + ms[0]=this; + ms[1]=otherC; + return Merge1SGTUMeshesOnSameCoords(ms); +} + +void MEDCoupling1SGTUMesh::getReverseNodalConnectivity(DataArrayInt *revNodal, DataArrayInt *revNodalIndx) const +{ + checkFullyDefined(); + int nbOfNodes=getNumberOfNodes(); + 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=_conn->begin(); + int nbOfCells=getNumberOfCells(); + int nbOfEltsInRevNodal=0; + int nbOfNodesPerCell=getNumberOfNodesPerCell(); + for(int eltId=0;eltId<nbOfCells;eltId++) + { + for(int j=0;j<nbOfNodesPerCell;j++,conn++) + { + if(conn[0]>=0 && conn[0]<nbOfNodes) + { + nbOfEltsInRevNodal++; + revNodalIndxPtr[conn[0]+1]++; + } + else + { + std::ostringstream oss; oss << "MEDCoupling1SGTUMesh::getReverseNodalConnectivity : At cell #" << eltId << " presence of nodeId #" << conn[0] << " should be in [0," << nbOfNodes << ") !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + } + } + std::transform(revNodalIndxPtr+1,revNodalIndxPtr+nbOfNodes+1,revNodalIndxPtr,revNodalIndxPtr+1,std::plus<int>()); + conn=_conn->begin(); + 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;eltId<nbOfCells;eltId++) + { + for(int j=0;j<nbOfNodesPerCell;j++,conn++) + { + *std::find_if(revNodalPtr+revNodalIndxPtr[*conn],revNodalPtr+revNodalIndxPtr[*conn+1],std::bind2nd(std::equal_to<int>(),-1))=eltId; + } + } +} + +/*! + * Use \a nodalConn array as nodal connectivity of \a this. The input \a nodalConn pointer can be null. + */ +void MEDCoupling1SGTUMesh::setNodalConnectivity(DataArrayInt *nodalConn) +{ + if(nodalConn) + nodalConn->incrRef(); + _conn=nodalConn; + declareAsNew(); +} + +/*! + * \return DataArrayInt * - the internal reference to the nodal connectivity. The caller is not reponsible to deallocate it. + */ +DataArrayInt *MEDCoupling1SGTUMesh::getNodalConnectivity() const +{ + const DataArrayInt *ret(_conn); + return const_cast<DataArrayInt *>(ret); +} + +/*! + * Allocates memory to store an estimation of the given number of cells. Closer is the estimation to the number of cells effectively inserted, + * less will be the needs to realloc. If the number of cells to be inserted is not known simply put 0 to this parameter. + * If a nodal connectivity previouly existed before the call of this method, it will be reset. + * + * \param [in] nbOfCells - estimation of the number of cell \a this mesh will contain. + */ +void MEDCoupling1SGTUMesh::allocateCells(int nbOfCells) +{ + if(nbOfCells<0) + throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::allocateCells : the input number of cells should be >= 0 !"); + _conn=DataArrayInt::New(); + _conn->reserve(getNumberOfNodesPerCell()*nbOfCells); + declareAsNew(); +} + +/*! + * Appends at the end of \a this a cell having nodal connectivity array defined in [ \a nodalConnOfCellBg, \a nodalConnOfCellEnd ). + * + * \param [in] nodalConnOfCellBg - the begin (included) of nodal connectivity of the cell to add. + * \param [in] nodalConnOfCellEnd - the end (excluded) of nodal connectivity of the cell to add. + * \throw If the length of the input nodal connectivity array of the cell to add is not equal to number of nodes per cell relative to the unique geometric type + * attached to \a this. + * \thow If the nodal connectivity array in \a this is null (call MEDCoupling1SGTUMesh::allocateCells before). + */ +void MEDCoupling1SGTUMesh::insertNextCell(const int *nodalConnOfCellBg, const int *nodalConnOfCellEnd) +{ + int sz=(int)std::distance(nodalConnOfCellBg,nodalConnOfCellEnd); + int ref=getNumberOfNodesPerCell(); + if(sz==ref) + { + DataArrayInt *c(_conn); + if(c) + c->pushBackValsSilent(nodalConnOfCellBg,nodalConnOfCellEnd); + else + throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::insertNextCell : nodal connectivity array is null ! Call MEDCoupling1SGTUMesh::allocateCells before !"); + } + else + { + std::ostringstream oss; oss << "MEDCoupling1SGTUMesh::insertNextCell : input nodal size (" << sz << ") does not match number of nodes per cell of this ("; + oss << ref << ") !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } +} + +/*! + * This method builds the dual mesh of \a this and returns it. + * + * \return MEDCoupling1SGTUMesh * - newly object created to be managed by the caller. + * \throw If \a this is not a mesh containing only simplex cells. + * \throw If \a this is not correctly allocated (coordinates and connectivities have to be correctly set !). + * \throw If at least one node in \a this is orphan (without any simplex cell lying on it !) + */ +MEDCoupling1GTUMesh *MEDCoupling1SGTUMesh::computeDualMesh() const +{ + const INTERP_KERNEL::CellModel& cm(getCellModel()); + if(!cm.isSimplex()) + throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::computeDualMesh : this mesh is not a simplex mesh ! Please invoke simplexize of tetrahedrize on this before calling this method !"); + switch(getMeshDimension()) + { + case 3: + return computeDualMesh3D(); + case 2: + return computeDualMesh2D(); + default: + throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::computeDualMesh : meshdimension must be in [2,3] !"); + } +} + +/*! + * This method explode each NORM_HEXA8 cells in \a this into 6 NORM_QUAD4 cells and put the result into the MEDCoupling1SGTUMesh returned instance. + * + * \return MEDCoupling1SGTUMesh * - a newly allocated instances (to be managed by the caller) storing the result of the explosion. + * \throw If \a this is not a mesh containing only NORM_HEXA8 cells. + * \throw If \a this is not properly allocated. + */ +MEDCoupling1SGTUMesh *MEDCoupling1SGTUMesh::explodeEachHexa8To6Quad4() const +{ + const INTERP_KERNEL::CellModel& cm(getCellModel()); + if(cm.getEnum()!=INTERP_KERNEL::NORM_HEXA8) + throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::explodeEachHexa8To6Quad4 : this method can be applied only on HEXA8 mesh !"); + int nbHexa8(getNumberOfCells()); + const int *inConnPtr(getNodalConnectivity()->begin()); + MEDCouplingAutoRefCountObjectPtr<MEDCoupling1SGTUMesh> ret(MEDCoupling1SGTUMesh::New(getName(),INTERP_KERNEL::NORM_QUAD4)); + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> c(DataArrayInt::New()); c->alloc(nbHexa8*6*4,1); + int *cPtr(c->getPointer()); + for(int i=0;i<nbHexa8;i++,inConnPtr+=8) + { + for(int j=0;j<6;j++,cPtr+=4) + cm.fillSonCellNodalConnectivity(j,inConnPtr,cPtr); + } + ret->setCoords(getCoords()); + ret->setNodalConnectivity(c); + return ret.retn(); +} + +/*! + * This method starts from an unstructured mesh that hides in reality a cartesian mesh. + * If it is not the case, an exception will be thrown. + * This method returns three objects : The cartesian mesh geometrically equivalent to \a this (within a precision of \a eps) and a permutation of cells + * and a permutation of nodes. + * + * - this[cellPerm[i]]=ret[i] + * + * \param [out] cellPerm the permutation array of size \c this->getNumberOfCells() + * \param [out] nodePerm the permutation array of size \c this->getNumberOfNodes() + * \return MEDCouplingCMesh * - a newly allocated mesh that is the result of the structurization of \a this. + */ +MEDCouplingCMesh *MEDCoupling1SGTUMesh::structurizeMe(DataArrayInt *& cellPerm, DataArrayInt *& nodePerm, double eps) const +{ + checkCoherency(); + int spaceDim(getSpaceDimension()),meshDim(getMeshDimension()),nbNodes(getNumberOfNodes()); + if(MEDCouplingStructuredMesh::GetGeoTypeGivenMeshDimension(meshDim)!=getCellModelEnum()) + throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::structurizeMe : the unique geo type in this is not compatible with the geometric type regarding mesh dimension !"); + MEDCouplingAutoRefCountObjectPtr<MEDCouplingCMesh> cm(MEDCouplingCMesh::New()); + for(int i=0;i<spaceDim;i++) + { + std::vector<int> tmp(1,i); + MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> elt(static_cast<DataArrayDouble*>(getCoords()->keepSelectedComponents(tmp))); + elt=elt->getDifferentValues(eps); + elt->sort(true); + cm->setCoordsAt(i,elt); + } + if(nbNodes!=cm->getNumberOfNodes()) + throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::structurizeMe : considering the number of nodes after split per components in space this can't be a cartesian mesh ! Maybe your epsilon parameter is invalid ?"); + try + { cm->copyTinyInfoFrom(this); } + catch(INTERP_KERNEL::Exception&) { } + MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> um(cm->buildUnstructured()),self(buildUnstructured()); + self->checkGeoEquivalWith(um,12,eps,cellPerm,nodePerm); + return cm.retn(); +} + +/// @cond INTERNAL + +bool UpdateHexa8Cell(int validAxis, int neighId, const int *validConnQuad4NeighSide, int *allFacesNodalConn, int *myNeighbours) +{ + static const int TAB[48]={ + 0,1,2,3,4,5,6,7,//0 + 4,7,6,5,0,3,2,1,//1 + 0,3,7,4,1,2,6,5,//2 + 4,0,3,7,5,1,2,6,//3 + 5,1,0,4,6,2,3,7,//4 + 3,7,4,0,2,6,5,1 //5 + }; + static const int TAB2[6]={0,0,3,3,3,3}; + if(myNeighbours[validAxis]==neighId && allFacesNodalConn[4*validAxis+0]==validConnQuad4NeighSide[TAB2[validAxis]]) + return true; + int oldAxis((int)std::distance(myNeighbours,std::find(myNeighbours,myNeighbours+6,neighId))); + std::size_t pos(std::distance(MEDCoupling1SGTUMesh::HEXA8_FACE_PAIRS,std::find(MEDCoupling1SGTUMesh::HEXA8_FACE_PAIRS,MEDCoupling1SGTUMesh::HEXA8_FACE_PAIRS+6,oldAxis))); + std::size_t pos0(pos/2),pos1(pos%2); + int oldAxisOpp(MEDCoupling1SGTUMesh::HEXA8_FACE_PAIRS[2*pos0+(pos1+1)%2]); + int oldConn[8],myConn2[8]={-1,-1,-1,-1,-1,-1,-1,-1},myConn[8],edgeConn[2],allFacesTmp[24],neighTmp[6]; + oldConn[0]=allFacesNodalConn[0]; oldConn[1]=allFacesNodalConn[1]; oldConn[2]=allFacesNodalConn[2]; oldConn[3]=allFacesNodalConn[3]; + oldConn[4]=allFacesNodalConn[4]; oldConn[5]=allFacesNodalConn[7]; oldConn[6]=allFacesNodalConn[6]; oldConn[7]=allFacesNodalConn[5]; + const INTERP_KERNEL::CellModel& cm(INTERP_KERNEL::CellModel::GetCellModel(INTERP_KERNEL::NORM_HEXA8)); + for(int i=0;i<4;i++) + myConn2[i]=validConnQuad4NeighSide[(4-i+TAB2[validAxis])%4]; + for(int i=0;i<4;i++) + { + int nodeId(myConn2[i]);//the node id for which the opposite one will be found + bool found(false); + INTERP_KERNEL::NormalizedCellType typeOfSon; + for(int j=0;j<12 && !found;j++) + { + cm.fillSonEdgesNodalConnectivity3D(j,oldConn,-1,edgeConn,typeOfSon); + if(edgeConn[0]==nodeId || edgeConn[1]==nodeId) + { + if(std::find(allFacesNodalConn+4*oldAxisOpp,allFacesNodalConn+4*oldAxisOpp+4,edgeConn[0]==nodeId?edgeConn[1]:edgeConn[0])!=allFacesNodalConn+4*oldAxisOpp+4) + { + myConn2[i+4]=edgeConn[0]==nodeId?edgeConn[1]:edgeConn[0]; + found=true; + } + } + } + if(!found) + throw INTERP_KERNEL::Exception("UpdateHexa8Cell : Internal Error !"); + } + const int *myTab(TAB+8*validAxis); + for(int i=0;i<8;i++) + myConn[i]=myConn2[myTab[i]]; + for(int i=0;i<6;i++) + { + cm.fillSonCellNodalConnectivity(i,myConn,allFacesTmp+4*i); + std::set<int> s(allFacesTmp+4*i,allFacesTmp+4*i+4); + bool found(false); + for(int j=0;j<6 && !found;j++) + { + std::set<int> s1(allFacesNodalConn+4*j,allFacesNodalConn+4*j+4); + if(s==s1) + { + neighTmp[i]=myNeighbours[j]; + found=true; + } + } + if(!found) + throw INTERP_KERNEL::Exception("UpdateHexa8Cell : Internal Error #2 !"); + } + std::copy(allFacesTmp,allFacesTmp+24,allFacesNodalConn); + std::copy(neighTmp,neighTmp+6,myNeighbours); + return false; +} + +/// @endcond + +/*! + * This method expects the \a this contains NORM_HEXA8 cells only. This method will sort each cells in \a this so that their numbering was + * homogeneous. If it succeeds the result of MEDCouplingUMesh::tetrahedrize will return a conform mesh. + * + * \return DataArrayInt * - a newly allocated array (to be managed by the caller) containing renumbered cell ids. + * + * \throw If \a this is not a mesh containing only NORM_HEXA8 cells. + * \throw If \a this is not properly allocated. + * \sa MEDCouplingUMesh::tetrahedrize, MEDCouplingUMesh::simplexize. + */ +DataArrayInt *MEDCoupling1SGTUMesh::sortHexa8EachOther() +{ + MEDCouplingAutoRefCountObjectPtr<MEDCoupling1SGTUMesh> quads(explodeEachHexa8To6Quad4());//checks that only hexa8 + int nbHexa8(getNumberOfCells()),*cQuads(quads->getNodalConnectivity()->getPointer()); + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> neighOfQuads(DataArrayInt::New()); neighOfQuads->alloc(nbHexa8*6,1); neighOfQuads->fillWithValue(-1); + int *ptNeigh(neighOfQuads->getPointer()); + {//neighOfQuads tells for each face of each Quad8 which cell (if!=-1) is connected to this face. + MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> quadsTmp(quads->buildUnstructured()); + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ccSafe,cciSafe; + DataArrayInt *cc(0),*cci(0); + quadsTmp->findCommonCells(3,0,cc,cci); + ccSafe=cc; cciSafe=cci; + const int *ccPtr(ccSafe->begin()),nbOfPair(cci->getNumberOfTuples()-1); + for(int i=0;i<nbOfPair;i++) + { ptNeigh[ccPtr[2*i+0]]=ccPtr[2*i+1]/6; ptNeigh[ccPtr[2*i+1]]=ccPtr[2*i+0]/6; } + } + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1); + std::vector<bool> fetched(nbHexa8,false); + std::vector<bool>::iterator it(std::find(fetched.begin(),fetched.end(),false)); + while(it!=fetched.end())//it will turns as time as number of connected zones + { + int cellId((int)std::distance(fetched.begin(),it));//it is the seed of the connected zone. + std::set<int> s; s.insert(cellId);//s contains already organized. + while(!s.empty()) + { + std::set<int> sNext; + for(std::set<int>::const_iterator it0=s.begin();it0!=s.end();it0++) + { + fetched[*it0]=true; + int *myNeighb(ptNeigh+6*(*it0)); + for(int i=0;i<6;i++) + { + if(myNeighb[i]!=-1 && !fetched[myNeighb[i]]) + { + std::size_t pos(std::distance(HEXA8_FACE_PAIRS,std::find(HEXA8_FACE_PAIRS,HEXA8_FACE_PAIRS+6,i))); + std::size_t pos0(pos/2),pos1(pos%2); + if(!UpdateHexa8Cell(HEXA8_FACE_PAIRS[2*pos0+(pos1+1)%2],*it0,cQuads+6*4*(*it0)+4*i,cQuads+6*4*myNeighb[i],ptNeigh+6*myNeighb[i])) + ret->pushBackSilent(myNeighb[i]); + fetched[myNeighb[i]]=true; + sNext.insert(myNeighb[i]); + } + } + } + s=sNext; + } + it=std::find(fetched.begin(),fetched.end(),false); + } + if(!ret->empty()) + { + int *conn(getNodalConnectivity()->getPointer()); + for(const int *pt=ret->begin();pt!=ret->end();pt++) + { + int cellId(*pt); + conn[8*cellId+0]=cQuads[24*cellId+0]; conn[8*cellId+1]=cQuads[24*cellId+1]; conn[8*cellId+2]=cQuads[24*cellId+2]; conn[8*cellId+3]=cQuads[24*cellId+3]; + conn[8*cellId+4]=cQuads[24*cellId+4]; conn[8*cellId+5]=cQuads[24*cellId+7]; conn[8*cellId+6]=cQuads[24*cellId+6]; conn[8*cellId+7]=cQuads[24*cellId+5]; + } + declareAsNew(); + } + return ret.retn(); +} + +MEDCoupling1DGTUMesh *MEDCoupling1SGTUMesh::computeDualMesh3D() const +{ + static const int DUAL_TETRA_0[36]={ + 4,1,0, 6,0,3, 7,3,1, + 4,0,1, 5,2,0, 8,1,2, + 6,3,0, 5,0,2, 9,2,3, + 7,1,3, 9,3,2, 8,2,1 + }; + static const int DUAL_TETRA_1[36]={ + 8,4,10, 11,5,8, 10,7,11, + 9,4,8, 8,5,12, 12,6,9, + 10,4,9, 9,6,13, 13,7,10, + 12,5,11, 13,6,12, 11,7,13 + }; + static const int FACEID_NOT_SH_NODE[4]={2,3,1,0}; + if(getCellModelEnum()!=INTERP_KERNEL::NORM_TETRA4) + throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::computeDualMesh3D : only TETRA4 supported !"); + checkFullyDefined(); + MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> thisu(buildUnstructured()); + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> revNodArr(DataArrayInt::New()),revNodIArr(DataArrayInt::New()); + thisu->getReverseNodalConnectivity(revNodArr,revNodIArr); + const int *revNod(revNodArr->begin()),*revNodI(revNodIArr->begin()),*nodal(_conn->begin()); + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> d1Arr(DataArrayInt::New()),di1Arr(DataArrayInt::New()),rd1Arr(DataArrayInt::New()),rdi1Arr(DataArrayInt::New()); + MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> edges(thisu->explode3DMeshTo1D(d1Arr,di1Arr,rd1Arr,rdi1Arr)); + const int *d1(d1Arr->begin()); + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> d2Arr(DataArrayInt::New()),di2Arr(DataArrayInt::New()),rd2Arr(DataArrayInt::New()),rdi2Arr(DataArrayInt::New()); + MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> faces(thisu->buildDescendingConnectivity(d2Arr,di2Arr,rd2Arr,rdi2Arr)); thisu=0; + const int *d2(d2Arr->begin()),*rdi2(rdi2Arr->begin()); + MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> edgesBaryArr(edges->getBarycenterAndOwner()),facesBaryArr(faces->getBarycenterAndOwner()),baryArr(getBarycenterAndOwner()); + const int nbOfNodes(getNumberOfNodes()),offset0(nbOfNodes+faces->getNumberOfCells()),offset1(offset0+edges->getNumberOfCells()); + edges=0; faces=0; + std::vector<const DataArrayDouble *> v(4); v[0]=getCoords(); v[1]=facesBaryArr; v[2]=edgesBaryArr; v[3]=baryArr; + MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> zeArr(DataArrayDouble::Aggregate(v)); baryArr=0; edgesBaryArr=0; facesBaryArr=0; + std::string name("DualOf_"); name+=getName(); + MEDCouplingAutoRefCountObjectPtr<MEDCoupling1DGTUMesh> ret(MEDCoupling1DGTUMesh::New(name,INTERP_KERNEL::NORM_POLYHED)); ret->setCoords(zeArr); + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> cArr(DataArrayInt::New()),ciArr(DataArrayInt::New()); ciArr->alloc(nbOfNodes+1,1); ciArr->setIJ(0,0,0); cArr->alloc(0,1); + for(int i=0;i<nbOfNodes;i++,revNodI++) + { + int nbOfCellsSharingNode(revNodI[1]-revNodI[0]); + if(nbOfCellsSharingNode==0) + { + std::ostringstream oss; oss << "MEDCoupling1SGTUMesh::computeDualMesh3D : Node #" << i << " is orphan !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + for(int j=0;j<nbOfCellsSharingNode;j++) + { + int curCellId(revNod[revNodI[0]+j]); + const int *connOfCurCell(nodal+4*curCellId); + std::size_t nodePosInCurCell(std::distance(connOfCurCell,std::find(connOfCurCell,connOfCurCell+4,i))); + if(j!=0) cArr->pushBackSilent(-1); + int tmp[14]; + // + tmp[0]=d1[6*curCellId+DUAL_TETRA_0[nodePosInCurCell*9+0]-4]+offset0; tmp[1]=d2[4*curCellId+DUAL_TETRA_0[nodePosInCurCell*9+1]]+nbOfNodes; + tmp[2]=curCellId+offset1; tmp[3]=d2[4*curCellId+DUAL_TETRA_0[nodePosInCurCell*9+2]]+nbOfNodes; + tmp[4]=-1; + tmp[5]=d1[6*curCellId+DUAL_TETRA_0[nodePosInCurCell*9+3]-4]+offset0; tmp[6]=d2[4*curCellId+DUAL_TETRA_0[nodePosInCurCell*9+4]]+nbOfNodes; + tmp[7]=curCellId+offset1; tmp[8]=d2[4*curCellId+DUAL_TETRA_0[nodePosInCurCell*9+5]]+nbOfNodes; + tmp[9]=-1; + tmp[10]=d1[6*curCellId+DUAL_TETRA_0[nodePosInCurCell*9+6]-4]+offset0; tmp[11]=d2[4*curCellId+DUAL_TETRA_0[nodePosInCurCell*9+7]]+nbOfNodes; + tmp[12]=curCellId+offset1; tmp[13]=d2[4*curCellId+DUAL_TETRA_0[nodePosInCurCell*9+8]]+nbOfNodes; + cArr->insertAtTheEnd(tmp,tmp+14); + int kk(0); + for(int k=0;k<4;k++) + { + if(FACEID_NOT_SH_NODE[nodePosInCurCell]!=k) + { + const int *faceId(d2+4*curCellId+k); + if(rdi2[*faceId+1]-rdi2[*faceId]==1) + { + int tmp2[5]; tmp2[0]=-1; tmp2[1]=i; + tmp2[2]=d1[6*curCellId+DUAL_TETRA_1[9*nodePosInCurCell+3*kk+0]-8]+offset0; + tmp2[3]=d2[4*curCellId+DUAL_TETRA_1[9*nodePosInCurCell+3*kk+1]-4]+nbOfNodes; + tmp2[4]=d1[6*curCellId+DUAL_TETRA_1[9*nodePosInCurCell+3*kk+2]-8]+offset0; + cArr->insertAtTheEnd(tmp2,tmp2+5); + } + kk++; + } + } + } + ciArr->setIJ(i+1,0,cArr->getNumberOfTuples()); + } + ret->setNodalConnectivity(cArr,ciArr); + return ret.retn(); +} + +MEDCoupling1DGTUMesh *MEDCoupling1SGTUMesh::computeDualMesh2D() const +{ + static const int DUAL_TRI_0[6]={0,2, 1,0, 2,1}; + static const int DUAL_TRI_1[6]={-3,+5, +3,-4, +4,-5}; + static const int FACEID_NOT_SH_NODE[3]={1,2,0}; + if(getCellModelEnum()!=INTERP_KERNEL::NORM_TRI3) + throw INTERP_KERNEL::Exception("MEDCoupling1SGTUMesh::computeDualMesh2D : only TRI3 supported !"); + checkFullyDefined(); + MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> thisu(buildUnstructured()); + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> revNodArr(DataArrayInt::New()),revNodIArr(DataArrayInt::New()); + thisu->getReverseNodalConnectivity(revNodArr,revNodIArr); + const int *revNod(revNodArr->begin()),*revNodI(revNodIArr->begin()),*nodal(_conn->begin()); + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> d2Arr(DataArrayInt::New()),di2Arr(DataArrayInt::New()),rd2Arr(DataArrayInt::New()),rdi2Arr(DataArrayInt::New()); + MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> edges(thisu->buildDescendingConnectivity(d2Arr,di2Arr,rd2Arr,rdi2Arr)); thisu=0; + const int *d2(d2Arr->begin()),*rdi2(rdi2Arr->begin()); + MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> edgesBaryArr(edges->getBarycenterAndOwner()),baryArr(getBarycenterAndOwner()); + const int nbOfNodes(getNumberOfNodes()),offset0(nbOfNodes+edges->getNumberOfCells()); + edges=0; + std::vector<const DataArrayDouble *> v(3); v[0]=getCoords(); v[1]=edgesBaryArr; v[2]=baryArr; + MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> zeArr(DataArrayDouble::Aggregate(v)); baryArr=0; edgesBaryArr=0; + std::string name("DualOf_"); name+=getName(); + MEDCouplingAutoRefCountObjectPtr<MEDCoupling1DGTUMesh> ret(MEDCoupling1DGTUMesh::New(name,INTERP_KERNEL::NORM_POLYGON)); ret->setCoords(zeArr); + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> cArr(DataArrayInt::New()),ciArr(DataArrayInt::New()); ciArr->alloc(nbOfNodes+1,1); ciArr->setIJ(0,0,0); cArr->alloc(0,1); + for(int i=0;i<nbOfNodes;i++,revNodI++) + { + int nbOfCellsSharingNode(revNodI[1]-revNodI[0]); + if(nbOfCellsSharingNode==0) + { + std::ostringstream oss; oss << "MEDCoupling1SGTUMesh::computeDualMesh2D : Node #" << i << " is orphan !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + std::vector< std::vector<int> > polyg; + for(int j=0;j<nbOfCellsSharingNode;j++) + { + int curCellId(revNod[revNodI[0]+j]); + const int *connOfCurCell(nodal+3*curCellId); + std::size_t nodePosInCurCell(std::distance(connOfCurCell,std::find(connOfCurCell,connOfCurCell+4,i))); + std::vector<int> locV(3); + locV[0]=d2[3*curCellId+DUAL_TRI_0[2*nodePosInCurCell+0]]+nbOfNodes; locV[1]=curCellId+offset0; locV[2]=d2[3*curCellId+DUAL_TRI_0[2*nodePosInCurCell+1]]+nbOfNodes; + polyg.push_back(locV); + int kk(0); + for(int k=0;k<3;k++) + { + if(FACEID_NOT_SH_NODE[nodePosInCurCell]!=k) + { + const int *edgeId(d2+3*curCellId+k); + if(rdi2[*edgeId+1]-rdi2[*edgeId]==1) + { + std::vector<int> locV2(2); + int zeLocEdgeIdRel(DUAL_TRI_1[2*nodePosInCurCell+kk]); + if(zeLocEdgeIdRel>0) + { locV2[0]=d2[3*curCellId+zeLocEdgeIdRel-3]+nbOfNodes; locV2[1]=i; } + else + { locV2[0]=i; locV2[1]=d2[3*curCellId-zeLocEdgeIdRel-3]+nbOfNodes; } + polyg.push_back(locV2); + } + kk++; + } + } + } + std::vector<int> zePolyg(MEDCoupling1DGTUMesh::BuildAPolygonFromParts(polyg)); + cArr->insertAtTheEnd(zePolyg.begin(),zePolyg.end()); + ciArr->setIJ(i+1,0,cArr->getNumberOfTuples()); + } + ret->setNodalConnectivity(cArr,ciArr); + return ret.retn(); +} + +/*! + * This method aggregate the bbox of each cell and put it into bbox + * + * \param [in] arcDetEps - a parameter specifying in case of 2D quadratic polygon cell the detection limit between linear and arc circle. (By default 1e-12) + * For all other cases this input parameter is ignored. + * \return DataArrayDouble * - newly created object (to be managed by the caller) \a this number of cells tuples and 2*spacedim components. + * + * \throw If \a this is not fully set (coordinates and connectivity). + * \throw If a cell in \a this has no valid nodeId. + */ +DataArrayDouble *MEDCoupling1SGTUMesh::getBoundingBoxForBBTree(double arcDetEps) const +{ + int spaceDim(getSpaceDimension()),nbOfCells(getNumberOfCells()),nbOfNodes(getNumberOfNodes()),nbOfNodesPerCell(getNumberOfNodesPerCell()); + MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret(DataArrayDouble::New()); ret->alloc(nbOfCells,2*spaceDim); + double *bbox(ret->getPointer()); + for(int i=0;i<nbOfCells*spaceDim;i++) + { + bbox[2*i]=std::numeric_limits<double>::max(); + bbox[2*i+1]=-std::numeric_limits<double>::max(); + } + const double *coordsPtr(_coords->getConstPointer()); + const int *conn(_conn->getConstPointer()); + for(int i=0;i<nbOfCells;i++) + { + int kk(0); + for(int j=0;j<nbOfNodesPerCell;j++,conn++) + { + int nodeId(*conn); + if(nodeId>=0 && nodeId<nbOfNodes) + { + for(int k=0;k<spaceDim;k++) + { + bbox[2*spaceDim*i+2*k]=std::min(bbox[2*spaceDim*i+2*k],coordsPtr[spaceDim*nodeId+k]); + bbox[2*spaceDim*i+2*k+1]=std::max(bbox[2*spaceDim*i+2*k+1],coordsPtr[spaceDim*nodeId+k]); + } + kk++; + } + } + if(kk==0) + { + std::ostringstream oss; oss << "MEDCoupling1SGTUMesh::getBoundingBoxForBBTree : cell #" << i << " contains no valid nodeId !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + } + return ret.retn(); +} + +/*! + * Returns the cell field giving for each cell in \a this its diameter. Diameter means the max length of all possible SEG2 in the cell. + * + * \return a new instance of field containing the result. The returned instance has to be deallocated by the caller. + */ +MEDCouplingFieldDouble *MEDCoupling1SGTUMesh::computeDiameterField() const +{ + checkFullyDefined(); + MEDCouplingAutoRefCountObjectPtr<MEDCouplingFieldDouble> ret(MEDCouplingFieldDouble::New(ON_CELLS,ONE_TIME)); + int nbCells(getNumberOfCells()); + MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> arr(DataArrayDouble::New()); + arr->alloc(nbCells,1); + INTERP_KERNEL::AutoCppPtr<INTERP_KERNEL::DiameterCalculator> dc(_cm->buildInstanceOfDiameterCalulator(getSpaceDimension())); + dc->computeFor1SGTUMeshFrmt(nbCells,_conn->begin(),getCoords()->begin(),arr->getPointer()); + ret->setMesh(this); + ret->setArray(arr); + ret->setName("Diameter"); + return ret.retn(); +} + +//== + +MEDCoupling1DGTUMesh *MEDCoupling1DGTUMesh::New() +{ + return new MEDCoupling1DGTUMesh; +} + +MEDCoupling1DGTUMesh *MEDCoupling1DGTUMesh::New(const std::string& name, INTERP_KERNEL::NormalizedCellType type) +{ + if(type==INTERP_KERNEL::NORM_ERROR) + throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::New : NORM_ERROR is not a valid type to be used as base geometric type for a mesh !"); + const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(type); + if(!cm.isDynamic()) + { + std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::New : the input geometric type " << cm.getRepr() << " is static ! Only dynamic types are allowed here !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + return new MEDCoupling1DGTUMesh(name,cm); +} + +MEDCoupling1DGTUMesh::MEDCoupling1DGTUMesh() +{ +} + +MEDCoupling1DGTUMesh::MEDCoupling1DGTUMesh(const std::string& name, const INTERP_KERNEL::CellModel& cm):MEDCoupling1GTUMesh(name,cm) +{ +} + +MEDCoupling1DGTUMesh::MEDCoupling1DGTUMesh(const MEDCoupling1DGTUMesh& other, bool recDeepCpy):MEDCoupling1GTUMesh(other,recDeepCpy),_conn(other._conn) +{ + if(recDeepCpy) + { + const DataArrayInt *c(other._conn); + if(c) + _conn=c->deepCpy(); + c=other._conn_indx; + if(c) + _conn_indx=c->deepCpy(); + } +} + +MEDCoupling1DGTUMesh *MEDCoupling1DGTUMesh::clone(bool recDeepCpy) const +{ + return new MEDCoupling1DGTUMesh(*this,recDeepCpy); +} + +/*! + * This method behaves mostly like MEDCoupling1DGTUMesh::deepCpy method, except that only nodal connectivity arrays are deeply copied. + * The coordinates are shared between \a this and the returned instance. + * + * \return MEDCouplingUMesh * - A new object instance holding the copy of \a this (deep for connectivity, shallow for coordiantes) + * \sa MEDCoupling1DGTUMesh::deepCpy + */ +MEDCouplingPointSet *MEDCoupling1DGTUMesh::deepCpyConnectivityOnly() const +{ + checkCoherency(); + MEDCouplingAutoRefCountObjectPtr<MEDCoupling1DGTUMesh> ret(clone(false)); + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> c(_conn->deepCpy()),ci(_conn_indx->deepCpy()); + ret->setNodalConnectivity(c,ci); + return ret.retn(); +} + +void MEDCoupling1DGTUMesh::updateTime() const +{ + MEDCoupling1GTUMesh::updateTime(); + const DataArrayInt *c(_conn); + if(c) + updateTimeWith(*c); + c=_conn_indx; + if(c) + updateTimeWith(*c); +} + +std::size_t MEDCoupling1DGTUMesh::getHeapMemorySizeWithoutChildren() const +{ + return MEDCoupling1GTUMesh::getHeapMemorySizeWithoutChildren(); +} + +std::vector<const BigMemoryObject *> MEDCoupling1DGTUMesh::getDirectChildrenWithNull() const +{ + std::vector<const BigMemoryObject *> ret(MEDCoupling1GTUMesh::getDirectChildrenWithNull()); + ret.push_back((const DataArrayInt *)_conn); + ret.push_back((const DataArrayInt *)_conn_indx); + return ret; +} + +MEDCouplingMesh *MEDCoupling1DGTUMesh::deepCpy() const +{ + return clone(true); +} + +bool MEDCoupling1DGTUMesh::isEqualIfNotWhy(const MEDCouplingMesh *other, double prec, std::string& reason) const +{ + if(!other) + throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::isEqualIfNotWhy : input other pointer is null !"); + std::ostringstream oss; oss.precision(15); + const MEDCoupling1DGTUMesh *otherC=dynamic_cast<const MEDCoupling1DGTUMesh *>(other); + if(!otherC) + { + reason="mesh given in input is not castable in MEDCoupling1DGTUMesh !"; + return false; + } + if(!MEDCoupling1GTUMesh::isEqualIfNotWhy(other,prec,reason)) + return false; + const DataArrayInt *c1(_conn),*c2(otherC->_conn); + if(c1==c2) + return true; + if(!c1 || !c2) + { + reason="in connectivity of single dynamic geometric type exactly one among this and other is null !"; + return false; + } + if(!c1->isEqualIfNotWhy(*c2,reason)) + { + reason.insert(0,"Nodal connectivity DataArrayInt differs : "); + return false; + } + c1=_conn_indx; c2=otherC->_conn_indx; + if(c1==c2) + return true; + if(!c1 || !c2) + { + reason="in connectivity index of single dynamic geometric type exactly one among this and other is null !"; + return false; + } + if(!c1->isEqualIfNotWhy(*c2,reason)) + { + reason.insert(0,"Nodal connectivity index DataArrayInt differs : "); + return false; + } + return true; +} + +bool MEDCoupling1DGTUMesh::isEqualWithoutConsideringStr(const MEDCouplingMesh *other, double prec) const +{ + if(!other) + throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::isEqualWithoutConsideringStr : input other pointer is null !"); + const MEDCoupling1DGTUMesh *otherC=dynamic_cast<const MEDCoupling1DGTUMesh *>(other); + if(!otherC) + return false; + if(!MEDCoupling1GTUMesh::isEqualWithoutConsideringStr(other,prec)) + return false; + const DataArrayInt *c1(_conn),*c2(otherC->_conn); + if(c1==c2) + return true; + if(!c1 || !c2) + return false; + if(!c1->isEqualWithoutConsideringStr(*c2)) + return false; + return true; + c1=_conn_indx; c2=otherC->_conn_indx; + if(c1==c2) + return true; + if(!c1 || !c2) + return false; + if(!c1->isEqualWithoutConsideringStr(*c2)) + return false; + return true; +} + +/*! + * 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 MEDCoupling1DGTUMesh::checkFastEquivalWith(const MEDCouplingMesh *other, double prec) const +{ + MEDCouplingPointSet::checkFastEquivalWith(other,prec); + const MEDCoupling1DGTUMesh *otherC=dynamic_cast<const MEDCoupling1DGTUMesh *>(other); + if(!otherC) + throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::checkFastEquivalWith : Two meshes are not unstructured with single dynamic geometric type !"); + const DataArrayInt *c1(_conn),*c2(otherC->_conn); + if(c1!=c2) + { + if(!c1 || !c2) + throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::checkFastEquivalWith : presence of nodal connectivity only in one of the 2 meshes !"); + if((c1->isAllocated() && !c2->isAllocated()) || (!c1->isAllocated() && c2->isAllocated())) + throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::checkFastEquivalWith : in nodal connectivity, only one is allocated !"); + if(c1->getNumberOfComponents()!=1 || c1->getNumberOfComponents()!=1) + throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::checkFastEquivalWith : in nodal connectivity, must have 1 and only 1 component !"); + if(c1->getHashCode()!=c2->getHashCode()) + throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::checkFastEquivalWith : nodal connectivity differs"); + } + c1=_conn_indx; c2=otherC->_conn_indx; + if(c1!=c2) + { + if(!c1 || !c2) + throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::checkFastEquivalWith : presence of nodal connectivity index only in one of the 2 meshes !"); + if((c1->isAllocated() && !c2->isAllocated()) || (!c1->isAllocated() && c2->isAllocated())) + throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::checkFastEquivalWith : in nodal connectivity index, only one is allocated !"); + if(c1->getNumberOfComponents()!=1 || c1->getNumberOfComponents()!=1) + throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::checkFastEquivalWith : in nodal connectivity index, must have 1 and only 1 component !"); + if(c1->getHashCode()!=c2->getHashCode()) + throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::checkFastEquivalWith : nodal connectivity index differs"); + } +} + +void MEDCoupling1DGTUMesh::checkCoherencyOfConnectivity() const +{ + const DataArrayInt *c1(_conn); + if(c1) + { + if(c1->getNumberOfComponents()!=1) + throw INTERP_KERNEL::Exception("Nodal connectivity array is expected to be with number of components set to one !"); + if(c1->getInfoOnComponent(0)!="") + throw INTERP_KERNEL::Exception("Nodal connectivity array is expected to have no info on its single component !"); + c1->checkAllocated(); + } + else + throw INTERP_KERNEL::Exception("Nodal connectivity array not defined !"); + // + int sz2=_conn->getNumberOfTuples(); + c1=_conn_indx; + if(c1) + { + if(c1->getNumberOfComponents()!=1) + throw INTERP_KERNEL::Exception("Nodal connectivity index array is expected to be with number of components set to one !"); + c1->checkAllocated(); + if(c1->getNumberOfTuples()<1) + throw INTERP_KERNEL::Exception("Nodal connectivity index array is expected to have a a size of 1 at least !"); + if(c1->getInfoOnComponent(0)!="") + throw INTERP_KERNEL::Exception("Nodal connectivity index array is expected to have no info on its single component !"); + int f=c1->front(),ll=c1->back(); + if(f<0 || f>=sz2) + { + std::ostringstream oss; oss << "Nodal connectivity index array first value (" << f << ") is expected to be exactly in [0," << sz2 << ") !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + if(ll<0 || ll>sz2) + { + std::ostringstream oss; oss << "Nodal connectivity index array last value (" << ll << ") is expected to be exactly in [0," << sz2 << "] !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + if(f>ll) + { + std::ostringstream oss; oss << "Nodal connectivity index array looks very bad (not increasing monotonic) because front (" << f << ") is greater that back (" << ll << ") !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + } + else + throw INTERP_KERNEL::Exception("Nodal connectivity index array not defined !"); + int szOfC1Exp=_conn_indx->back(); + if(sz2<szOfC1Exp) + { + std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::checkCoherencyOfConnectivity : The expected length of nodal connectivity array regarding index is " << szOfC1Exp << " but the actual size of it is " << c1->getNumberOfTuples() << " !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } +} + +/*! + * If \a this pass this method, you are sure that connectivity arrays are not null, with exactly one component, no name, no component name, allocated. + * In addition you are sure that the length of nodal connectivity index array is bigger than or equal to one. + * In addition you are also sure that length of nodal connectivity is coherent with the content of the last value in the index array. + */ +void MEDCoupling1DGTUMesh::checkCoherency() const +{ + MEDCouplingPointSet::checkCoherency(); + checkCoherencyOfConnectivity(); +} + +void MEDCoupling1DGTUMesh::checkCoherency1(double eps) const +{ + checkCoherency(); + const DataArrayInt *c1(_conn),*c2(_conn_indx); + if(!c2->isMonotonic(true)) + throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::checkCoherency1 : the nodal connectivity index is expected to be increasing monotinic !"); + // + int nbOfTuples=c1->getNumberOfTuples(); + int nbOfNodes=getNumberOfNodes(); + const int *w(c1->begin()); + for(int i=0;i<nbOfTuples;i++,w++) + { + if(*w==-1) continue; + if(*w<0 || *w>=nbOfNodes) + { + std::ostringstream oss; oss << "At pos #" << i << " of nodal connectivity array references to node id #" << *w << " must be in [0," << nbOfNodes << ") !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + } +} + +void MEDCoupling1DGTUMesh::checkCoherency2(double eps) const +{ + checkCoherency1(eps); +} + +int MEDCoupling1DGTUMesh::getNumberOfCells() const +{ + checkCoherencyOfConnectivity();//do not remove + return _conn_indx->getNumberOfTuples()-1; +} + +/*! + * This method returns a newly allocated array containing this->getNumberOfCells() tuples and 1 component. + * For each cell in \b this the number of nodes constituting cell is computed. + * For each polyhedron cell, the sum of the number of nodes of each face constituting polyhedron cell is returned. + * So for pohyhedrons some nodes can be counted several times in the returned result. + * + * \return a newly allocated array + */ +DataArrayInt *MEDCoupling1DGTUMesh::computeNbOfNodesPerCell() const +{ + checkCoherency(); + _conn_indx->checkMonotonic(true); + if(getCellModelEnum()!=INTERP_KERNEL::NORM_POLYHED) + return _conn_indx->deltaShiftIndex(); + // for polyhedrons + int nbOfCells=_conn_indx->getNumberOfTuples()-1; + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New(); + ret->alloc(nbOfCells,1); + int *retPtr=ret->getPointer(); + const int *ci=_conn_indx->begin(),*c=_conn->begin(); + for(int i=0;i<nbOfCells;i++,retPtr++,ci++) + *retPtr=ci[1]-ci[0]-std::count(c+ci[0],c+ci[1],-1); + return ret.retn(); +} + +/*! + * This method returns a newly allocated array containing this->getNumberOfCells() tuples and 1 component. + * For each cell in \b this the number of faces constituting (entity of dimension this->getMeshDimension()-1) cell is computed. + * + * \return a newly allocated array + */ +DataArrayInt *MEDCoupling1DGTUMesh::computeNbOfFacesPerCell() const +{ + checkCoherency(); + _conn_indx->checkMonotonic(true); + if(getCellModelEnum()!=INTERP_KERNEL::NORM_POLYHED && getCellModelEnum()!=INTERP_KERNEL::NORM_QPOLYG) + return _conn_indx->deltaShiftIndex(); + if(getCellModelEnum()==INTERP_KERNEL::NORM_QPOLYG) + { + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=_conn_indx->deltaShiftIndex(); + ret->applyDivideBy(2); + return ret.retn(); + } + // for polyhedrons + int nbOfCells=_conn_indx->getNumberOfTuples()-1; + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New(); + ret->alloc(nbOfCells,1); + int *retPtr=ret->getPointer(); + const int *ci=_conn_indx->begin(),*c=_conn->begin(); + for(int i=0;i<nbOfCells;i++,retPtr++,ci++) + *retPtr=std::count(c+ci[0],c+ci[1],-1)+1; + return ret.retn(); +} + +/*! + * This method computes effective number of nodes per cell. That is to say nodes appearing several times in nodal connectivity of a cell, + * will be counted only once here whereas it will be counted several times in MEDCoupling1DGTUMesh::computeNbOfNodesPerCell method. + * + * \return DataArrayInt * - new object to be deallocated by the caller. + * \sa MEDCoupling1DGTUMesh::computeNbOfNodesPerCell + */ +DataArrayInt *MEDCoupling1DGTUMesh::computeEffectiveNbOfNodesPerCell() const +{ + checkCoherency(); + _conn_indx->checkMonotonic(true); + int nbOfCells(_conn_indx->getNumberOfTuples()-1); + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New(); + ret->alloc(nbOfCells,1); + int *retPtr(ret->getPointer()); + const int *ci(_conn_indx->begin()),*c(_conn->begin()); + if(getCellModelEnum()!=INTERP_KERNEL::NORM_POLYHED) + { + for(int i=0;i<nbOfCells;i++,retPtr++,ci++) + { + std::set<int> s(c+ci[0],c+ci[1]); + *retPtr=(int)s.size(); + } + } + else + { + for(int i=0;i<nbOfCells;i++,retPtr++,ci++) + { + std::set<int> s(c+ci[0],c+ci[1]); s.erase(-1); + *retPtr=(int)s.size(); + } + } + return ret.retn(); +} + +void MEDCoupling1DGTUMesh::getNodeIdsOfCell(int cellId, std::vector<int>& conn) const +{ + int nbOfCells(getNumberOfCells());//performs checks + if(cellId>=0 && cellId<nbOfCells) + { + int strt=_conn_indx->getIJ(cellId,0),stp=_conn_indx->getIJ(cellId+1,0); + int nbOfNodes=stp-strt; + if(nbOfNodes<0) + throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::getNodeIdsOfCell : the index array is invalid ! Should be increasing monotonic !"); + conn.resize(nbOfNodes); + std::copy(_conn->begin()+strt,_conn->begin()+stp,conn.begin()); + } + else + { + std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::getNodeIdsOfCell : request for cellId #" << cellId << " must be in [0," << nbOfCells << ") !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } +} + +int MEDCoupling1DGTUMesh::getNumberOfNodesInCell(int cellId) const +{ + int nbOfCells(getNumberOfCells());//performs checks + if(cellId>=0 && cellId<nbOfCells) + { + const int *conn(_conn->begin()); + int strt=_conn_indx->getIJ(cellId,0),stp=_conn_indx->getIJ(cellId+1,0); + return stp-strt-std::count(conn+strt,conn+stp,-1); + } + else + { + std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::getNumberOfNodesInCell : request for cellId #" << cellId << " must be in [0," << nbOfCells << ") !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } +} + +std::string MEDCoupling1DGTUMesh::simpleRepr() const +{ + static const char msg0[]="No coordinates specified !"; + std::ostringstream ret; + ret << "Single dynamic geometic type (" << _cm->getRepr() << ") unstructured 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 << "Mesh dimension : " << getMeshDimension() << "\nSpace dimension : "; + if(_coords!=0) + { + const int spaceDim=getSpaceDimension(); + ret << spaceDim << "\nInfo attached on space dimension : "; + for(int i=0;i<spaceDim;i++) + ret << "\"" << _coords->getInfoOnComponent(i) << "\" "; + ret << "\n"; + } + else + ret << msg0 << "\n"; + ret << "Number of nodes : "; + if(_coords!=0) + ret << getNumberOfNodes() << "\n"; + else + ret << msg0 << "\n"; + ret << "Number of cells : "; + bool isOK=true; + try { checkCoherency(); } catch(INTERP_KERNEL::Exception& /* e */) + { + ret << "Nodal connectivity arrays are not set or badly set !\n"; + isOK=false; + } + if(isOK) + ret << getNumberOfCells() << "\n"; + ret << "Cell type : " << _cm->getRepr() << "\n"; + return ret.str(); +} + +std::string MEDCoupling1DGTUMesh::advancedRepr() const +{ + std::ostringstream ret; + ret << simpleRepr(); + ret << "\nCoordinates array : \n___________________\n\n"; + if(_coords) + _coords->reprWithoutNameStream(ret); + else + ret << "No array set !\n"; + ret << "\n\nNodal Connectivity : \n____________________\n\n"; + // + bool isOK=true; + try { checkCoherency1(); } catch(INTERP_KERNEL::Exception& /* e */) + { + ret << "Nodal connectivity arrays are not set or badly set !\n"; + isOK=false; + } + if(!isOK) + return ret.str(); + int nbOfCells=getNumberOfCells(); + const int *ci=_conn_indx->begin(),*c=_conn->begin(); + for(int i=0;i<nbOfCells;i++,ci++) + { + ret << "Cell #" << i << " : "; + std::copy(c+ci[0],c+ci[1],std::ostream_iterator<int>(ret," ")); + ret << "\n"; + } + return ret.str(); +} + +DataArrayDouble *MEDCoupling1DGTUMesh::computeIsoBarycenterOfNodesPerCell() const +{ + MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New(); + int spaceDim=getSpaceDimension(); + int nbOfCells=getNumberOfCells();//checkCoherency() + int nbOfNodes=getNumberOfNodes(); + ret->alloc(nbOfCells,spaceDim); + double *ptToFill=ret->getPointer(); + const double *coor=_coords->begin(); + const int *nodal=_conn->begin(),*nodali=_conn_indx->begin(); + nodal+=nodali[0]; + if(getCellModelEnum()!=INTERP_KERNEL::NORM_POLYHED) + { + for(int i=0;i<nbOfCells;i++,ptToFill+=spaceDim,nodali++) + { + std::fill(ptToFill,ptToFill+spaceDim,0.); + if(nodali[0]<nodali[1])// >= to avoid division by 0. + { + for(int j=nodali[0];j<nodali[1];j++,nodal++) + { + if(*nodal>=0 && *nodal<nbOfNodes) + std::transform(coor+spaceDim*nodal[0],coor+spaceDim*(nodal[0]+1),ptToFill,ptToFill,std::plus<double>()); + else + { + std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::computeIsoBarycenterOfNodesPerCell : on cell #" << i << " presence of nodeId #" << *nodal << " should be in [0," << nbOfNodes << ") !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + std::transform(ptToFill,ptToFill+spaceDim,ptToFill,std::bind2nd(std::multiplies<double>(),1./(nodali[1]-nodali[0]))); + } + } + else + { + std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::computeIsoBarycenterOfNodesPerCell : at cell #" << i << " the nodal index array is invalid !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + } + } + else + { + for(int i=0;i<nbOfCells;i++,ptToFill+=spaceDim,nodali++) + { + std::fill(ptToFill,ptToFill+spaceDim,0.); + if(nodali[0]<nodali[1])// >= to avoid division by 0. + { + int nbOfNod=0; + for(int j=nodali[0];j<nodali[1];j++,nodal++) + { + if(*nodal==-1) continue; + if(*nodal>=0 && *nodal<nbOfNodes) + { + std::transform(coor+spaceDim*nodal[0],coor+spaceDim*(nodal[0]+1),ptToFill,ptToFill,std::plus<double>()); + nbOfNod++; + } + else + { + std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::computeIsoBarycenterOfNodesPerCell (polyhedron) : on cell #" << i << " presence of nodeId #" << *nodal << " should be in [0," << nbOfNodes << ") !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + } + if(nbOfNod!=0) + std::transform(ptToFill,ptToFill+spaceDim,ptToFill,std::bind2nd(std::multiplies<double>(),1./nbOfNod)); + else + { + std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::computeIsoBarycenterOfNodesPerCell (polyhedron) : no nodes in cell #" << i << " !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + } + else + { + std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::computeIsoBarycenterOfNodesPerCell (polyhedron) : at cell #" << i << " the nodal index array is invalid !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + } + } + return ret.retn(); +} + +void MEDCoupling1DGTUMesh::renumberCells(const int *old2NewBg, bool check) +{ + int nbCells=getNumberOfCells(); + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> o2n=DataArrayInt::New(); + o2n->useArray(old2NewBg,false,C_DEALLOC,nbCells,1); + if(check) + o2n=o2n->checkAndPreparePermutation(); + // + const int *o2nPtr=o2n->getPointer(); + const int *conn=_conn->begin(),*conni=_conn_indx->begin(); + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> newConn=DataArrayInt::New(); + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> newConnI=DataArrayInt::New(); + newConn->alloc(_conn->getNumberOfTuples(),1); newConnI->alloc(nbCells,1); + newConn->copyStringInfoFrom(*_conn); newConnI->copyStringInfoFrom(*_conn_indx); + // + int *newC=newConn->getPointer(),*newCI=newConnI->getPointer(); + for(int i=0;i<nbCells;i++) + { + int newPos=o2nPtr[i]; + int sz=conni[i+1]-conni[i]; + if(sz>=0) + newCI[newPos]=sz; + else + { + std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::renumberCells : the index nodal array is invalid for cell #" << i << " !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + } + newConnI->computeOffsets2(); newCI=newConnI->getPointer(); + // + for(int i=0;i<nbCells;i++,conni++) + { + int newp=o2nPtr[i]; + std::copy(conn+conni[0],conn+conni[1],newC+newCI[newp]); + } + _conn=newConn; + _conn_indx=newConnI; +} + +MEDCouplingMesh *MEDCoupling1DGTUMesh::mergeMyselfWith(const MEDCouplingMesh *other) const +{ + if(other->getType()!=SINGLE_DYNAMIC_GEO_TYPE_UNSTRUCTURED) + throw INTERP_KERNEL::Exception("Merge of umesh only available with umesh single dynamic geo type each other !"); + const MEDCoupling1DGTUMesh *otherC=static_cast<const MEDCoupling1DGTUMesh *>(other); + return Merge1DGTUMeshes(this,otherC); +} + +MEDCouplingUMesh *MEDCoupling1DGTUMesh::buildUnstructured() const +{ + MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> ret=MEDCouplingUMesh::New(getName(),getMeshDimension()); + ret->setCoords(getCoords()); + const int *nodalConn=_conn->begin(),*nodalConnI=_conn_indx->begin(); + int nbCells=getNumberOfCells();//checkCoherency + int geoType=(int)getCellModelEnum(); + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> c=DataArrayInt::New(); c->alloc(nbCells+_conn->getNumberOfTuples(),1); + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> cI=DataArrayInt::New(); cI->alloc(nbCells+1); + int *cPtr=c->getPointer(),*ciPtr=cI->getPointer(); + ciPtr[0]=0; + for(int i=0;i<nbCells;i++,ciPtr++) + { + int sz=nodalConnI[i+1]-nodalConnI[i]; + if(sz>=0) + { + *cPtr++=geoType; + cPtr=std::copy(nodalConn+nodalConnI[i],nodalConn+nodalConnI[i+1],cPtr); + ciPtr[1]=ciPtr[0]+sz+1; + } + else + { + std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::buildUnstructured : Invalid for nodal index for cell #" << i << " !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + } + ret->setConnectivity(c,cI,true); + try + { ret->copyTinyInfoFrom(this); } + catch(INTERP_KERNEL::Exception&) { } + return ret.retn(); +} + +/*! + * Do nothing for the moment, because there is no policy that allows to split polygons, polyhedrons ... into simplexes + */ +DataArrayInt *MEDCoupling1DGTUMesh::simplexize(int policy) +{ + int nbOfCells=getNumberOfCells(); + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New(); + ret->alloc(nbOfCells,1); + ret->iota(0); + return ret.retn(); +} + +void MEDCoupling1DGTUMesh::reprQuickOverview(std::ostream& stream) const +{ + stream << "MEDCoupling1DGTUMesh C++ instance at " << this << ". Type=" << _cm->getRepr() << ". Name : \"" << getName() << "\"."; + stream << " Mesh dimension : " << getMeshDimension() << "."; + if(!_coords) + { stream << " No coordinates set !"; return ; } + if(!_coords->isAllocated()) + { stream << " Coordinates set but not allocated !"; return ; } + stream << " Space dimension : " << _coords->getNumberOfComponents() << "." << std::endl; + stream << "Number of nodes : " << _coords->getNumberOfTuples() << "."; + bool isOK=true; + try { checkCoherency(); } catch(INTERP_KERNEL::Exception& /* e */) + { + stream << std::endl << "Nodal connectivity NOT set properly !\n"; + isOK=false; + } + if(isOK) + stream << std::endl << "Number of cells : " << getNumberOfCells() << "."; +} + +void MEDCoupling1DGTUMesh::shallowCopyConnectivityFrom(const MEDCouplingPointSet *other) +{ + if(!other) + throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::shallowCopyConnectivityFrom : input pointer is null !"); + const MEDCoupling1DGTUMesh *otherC=dynamic_cast<const MEDCoupling1DGTUMesh *>(other); + if(!otherC) + throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::shallowCopyConnectivityFrom : input pointer is not an MEDCoupling1DGTUMesh instance !"); + setNodalConnectivity(otherC->getNodalConnectivity(),otherC->getNodalConnectivityIndex()); +} + +MEDCouplingPointSet *MEDCoupling1DGTUMesh::mergeMyselfWithOnSameCoords(const MEDCouplingPointSet *other) const +{ + if(!other) + throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::mergeMyselfWithOnSameCoords : input other is null !"); + const MEDCoupling1DGTUMesh *otherC=dynamic_cast<const MEDCoupling1DGTUMesh *>(other); + if(!otherC) + throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::mergeMyselfWithOnSameCoords : the input other mesh is not of type single statuc geo type unstructured !"); + std::vector<const MEDCoupling1DGTUMesh *> ms(2); + ms[0]=this; + ms[1]=otherC; + return Merge1DGTUMeshesOnSameCoords(ms); +} + +MEDCouplingPointSet *MEDCoupling1DGTUMesh::buildPartOfMySelfKeepCoords(const int *begin, const int *end) const +{ + checkCoherency(); + MEDCouplingAutoRefCountObjectPtr<MEDCoupling1DGTUMesh> ret(new MEDCoupling1DGTUMesh(getName(),*_cm)); + ret->setCoords(_coords); + DataArrayInt *c=0,*ci=0; + MEDCouplingUMesh::ExtractFromIndexedArrays(begin,end,_conn,_conn_indx,c,ci); + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> cSafe(c),ciSafe(ci); + ret->setNodalConnectivity(c,ci); + return ret.retn(); +} + +MEDCouplingPointSet *MEDCoupling1DGTUMesh::buildPartOfMySelfKeepCoords2(int start, int end, int step) const +{ + checkCoherency(); + MEDCouplingAutoRefCountObjectPtr<MEDCoupling1DGTUMesh> ret(new MEDCoupling1DGTUMesh(getName(),*_cm)); + ret->setCoords(_coords); + DataArrayInt *c=0,*ci=0; + MEDCouplingUMesh::ExtractFromIndexedArrays2(start,end,step,_conn,_conn_indx,c,ci); + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> cSafe(c),ciSafe(ci); + ret->setNodalConnectivity(c,ci); + return ret.retn(); +} + +void MEDCoupling1DGTUMesh::computeNodeIdsAlg(std::vector<bool>& nodeIdsInUse) const +{ + checkCoherency2(); + int sz((int)nodeIdsInUse.size()); + for(const int *conn=_conn->begin();conn!=_conn->end();conn++) + { + if(*conn>=0 && *conn<sz) + nodeIdsInUse[*conn]=true; + else + { + if(*conn!=-1) + { + std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::computeNodeIdsAlg : At pos #" << std::distance(_conn->begin(),conn) << " value is " << *conn << " must be in [0," << sz << ") !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + } + } +} + +void MEDCoupling1DGTUMesh::getReverseNodalConnectivity(DataArrayInt *revNodal, DataArrayInt *revNodalIndx) const +{ + checkFullyDefined(); + int nbOfNodes=getNumberOfNodes(); + 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=_conn->begin(),*conni=_conn_indx->begin(); + int nbOfCells=getNumberOfCells(); + int nbOfEltsInRevNodal=0; + for(int eltId=0;eltId<nbOfCells;eltId++) + { + int nbOfNodesPerCell=conni[eltId+1]-conni[eltId]; + if(nbOfNodesPerCell>=0) + { + for(int j=0;j<nbOfNodesPerCell;j++) + { + int nodeId=conn[conni[eltId]+j]; + if(nodeId==-1) continue; + if(nodeId>=0 && nodeId<nbOfNodes) + { + nbOfEltsInRevNodal++; + revNodalIndxPtr[nodeId+1]++; + } + else + { + std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::getReverseNodalConnectivity : At cell #" << eltId << " presence of nodeId #" << conn[0] << " should be in [0," << nbOfNodes << ") !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + } + } + else + { + std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::getReverseNodalConnectivity : At cell #" << eltId << "nodal connectivity is invalid !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + } + std::transform(revNodalIndxPtr+1,revNodalIndxPtr+nbOfNodes+1,revNodalIndxPtr,revNodalIndxPtr+1,std::plus<int>()); + conn=_conn->begin(); + 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;eltId<nbOfCells;eltId++) + { + int nbOfNodesPerCell=conni[eltId+1]-conni[eltId]; + for(int j=0;j<nbOfNodesPerCell;j++) + { + int nodeId=conn[conni[eltId]+j]; + if(nodeId!=-1) + *std::find_if(revNodalPtr+revNodalIndxPtr[nodeId],revNodalPtr+revNodalIndxPtr[nodeId+1],std::bind2nd(std::equal_to<int>(),-1))=eltId; + } + } +} + +void MEDCoupling1DGTUMesh::checkFullyDefined() const +{ + if(!((const DataArrayInt *)_conn) || !((const DataArrayInt *)_conn_indx) || !((const DataArrayDouble *)_coords)) + throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::checkFullyDefined : part of this is not fully defined."); +} + +bool MEDCoupling1DGTUMesh::isEmptyMesh(const std::vector<int>& tinyInfo) const +{ + throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::isEmptyMesh : not implemented yet !"); +} + +void MEDCoupling1DGTUMesh::getTinySerializationInformation(std::vector<double>& tinyInfoD, std::vector<int>& tinyInfo, std::vector<std::string>& 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<std::string> littleStrings2,littleStrings3,littleStrings4; + if((const DataArrayDouble *)_coords) + _coords->getTinySerializationStrInformation(littleStrings2); + if((const DataArrayInt *)_conn) + _conn->getTinySerializationStrInformation(littleStrings3); + if((const DataArrayInt *)_conn_indx) + _conn_indx->getTinySerializationStrInformation(littleStrings4); + int sz0((int)littleStrings2.size()),sz1((int)littleStrings3.size()),sz2((int)littleStrings4.size()); + littleStrings.insert(littleStrings.end(),littleStrings2.begin(),littleStrings2.end()); + littleStrings.insert(littleStrings.end(),littleStrings3.begin(),littleStrings3.end()); + littleStrings.insert(littleStrings.end(),littleStrings4.begin(),littleStrings4.end()); + // + tinyInfo.push_back(getCellModelEnum()); + tinyInfo.push_back(it); + tinyInfo.push_back(order); + std::vector<int> tinyInfo2,tinyInfo3,tinyInfo4; + if((const DataArrayDouble *)_coords) + _coords->getTinySerializationIntInformation(tinyInfo2); + if((const DataArrayInt *)_conn) + _conn->getTinySerializationIntInformation(tinyInfo3); + if((const DataArrayInt *)_conn_indx) + _conn_indx->getTinySerializationIntInformation(tinyInfo4); + int sz3((int)tinyInfo2.size()),sz4((int)tinyInfo3.size()),sz5((int)tinyInfo4.size()); + tinyInfo.push_back(sz0); tinyInfo.push_back(sz1); tinyInfo.push_back(sz2); tinyInfo.push_back(sz3); tinyInfo.push_back(sz4); tinyInfo.push_back(sz5); + tinyInfo.insert(tinyInfo.end(),tinyInfo2.begin(),tinyInfo2.end()); + tinyInfo.insert(tinyInfo.end(),tinyInfo3.begin(),tinyInfo3.end()); + tinyInfo.insert(tinyInfo.end(),tinyInfo4.begin(),tinyInfo4.end()); + // + tinyInfoD.push_back(time); +} + +void MEDCoupling1DGTUMesh::resizeForUnserialization(const std::vector<int>& tinyInfo, DataArrayInt *a1, DataArrayDouble *a2, std::vector<std::string>& littleStrings) const +{ + std::vector<int> tinyInfo2(tinyInfo.begin()+9,tinyInfo.begin()+9+tinyInfo[6]); + std::vector<int> tinyInfo1(tinyInfo.begin()+9+tinyInfo[6],tinyInfo.begin()+9+tinyInfo[6]+tinyInfo[7]); + std::vector<int> tinyInfo12(tinyInfo.begin()+9+tinyInfo[6]+tinyInfo[7],tinyInfo.begin()+9+tinyInfo[6]+tinyInfo[7]+tinyInfo[8]); + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> p1(DataArrayInt::New()); p1->resizeForUnserialization(tinyInfo1); + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> p2(DataArrayInt::New()); p2->resizeForUnserialization(tinyInfo12); + std::vector<const DataArrayInt *> v(2); v[0]=p1; v[1]=p2; + p2=DataArrayInt::Aggregate(v); + a2->resizeForUnserialization(tinyInfo2); + a1->alloc(p2->getNbOfElems(),1); +} + +void MEDCoupling1DGTUMesh::serialize(DataArrayInt *&a1, DataArrayDouble *&a2) const +{ + int sz(0); + if((const DataArrayInt *)_conn) + if(_conn->isAllocated()) + sz=_conn->getNbOfElems(); + if((const DataArrayInt *)_conn_indx) + if(_conn_indx->isAllocated()) + sz+=_conn_indx->getNbOfElems(); + a1=DataArrayInt::New(); + a1->alloc(sz,1); + int *work(a1->getPointer()); + if(sz!=0 && (const DataArrayInt *)_conn) + work=std::copy(_conn->begin(),_conn->end(),a1->getPointer()); + if(sz!=0 && (const DataArrayInt *)_conn_indx) + std::copy(_conn_indx->begin(),_conn_indx->end(),work); + 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 MEDCoupling1DGTUMesh::unserialization(const std::vector<double>& tinyInfoD, const std::vector<int>& tinyInfo, const DataArrayInt *a1, DataArrayDouble *a2, + const std::vector<std::string>& littleStrings) +{ + INTERP_KERNEL::NormalizedCellType gt((INTERP_KERNEL::NormalizedCellType)tinyInfo[0]); + _cm=&INTERP_KERNEL::CellModel::GetCellModel(gt); + setName(littleStrings[0]); + setDescription(littleStrings[1]); + setTimeUnit(littleStrings[2]); + setTime(tinyInfoD[0],tinyInfo[1],tinyInfo[2]); + int sz0(tinyInfo[3]),sz1(tinyInfo[4]),sz2(tinyInfo[5]),sz3(tinyInfo[6]),sz4(tinyInfo[7]),sz5(tinyInfo[8]); + // + _coords=DataArrayDouble::New(); + std::vector<int> tinyInfo2(tinyInfo.begin()+9,tinyInfo.begin()+9+sz3); + _coords->resizeForUnserialization(tinyInfo2); + std::copy(a2->begin(),a2->end(),_coords->getPointer()); + _conn=DataArrayInt::New(); + std::vector<int> tinyInfo3(tinyInfo.begin()+9+sz3,tinyInfo.begin()+9+sz3+sz4); + _conn->resizeForUnserialization(tinyInfo3); + std::copy(a1->begin(),a1->begin()+_conn->getNbOfElems(),_conn->getPointer()); + _conn_indx=DataArrayInt::New(); + std::vector<int> tinyInfo4(tinyInfo.begin()+9+sz3+sz4,tinyInfo.begin()+9+sz3+sz4+sz5); + _conn_indx->resizeForUnserialization(tinyInfo4); + std::copy(a1->begin()+_conn->getNbOfElems(),a1->end(),_conn_indx->getPointer()); + std::vector<std::string> littleStrings2(littleStrings.begin()+3,littleStrings.begin()+3+sz0); + _coords->finishUnserialization(tinyInfo2,littleStrings2); + std::vector<std::string> littleStrings3(littleStrings.begin()+3+sz0,littleStrings.begin()+3+sz0+sz1); + _conn->finishUnserialization(tinyInfo3,littleStrings3); + std::vector<std::string> littleStrings4(littleStrings.begin()+3+sz0+sz1,littleStrings.begin()+3+sz0+sz1+sz2); + _conn_indx->finishUnserialization(tinyInfo4,littleStrings4); +} + +/*! + * Finds nodes not used in any cell and returns an array giving a new id to every node + * by excluding the unused nodes, for which the array holds -1. The result array is + * a mapping in "Old to New" mode. + * \param [out] nbrOfNodesInUse - number of node ids present in the nodal connectivity. + * \return DataArrayInt * - a new instance of DataArrayInt. Its length is \a + * this->getNumberOfNodes(). It holds for each node of \a this mesh either -1 + * if the node is unused or a new id else. The caller is to delete this + * array using decrRef() as it is no more needed. + * \throw If the coordinates array is not set. + * \throw If the nodal connectivity of cells is not defined. + * \throw If the nodal connectivity includes an invalid id. + * \sa MEDCoupling1DGTUMesh::getNodeIdsInUse, areAllNodesFetched + */ +DataArrayInt *MEDCoupling1DGTUMesh::computeFetchedNodeIds() const +{ + checkCoherency2(); + int nbNodes(getNumberOfNodes()); + std::vector<bool> fetchedNodes(nbNodes,false); + computeNodeIdsAlg(fetchedNodes); + int sz((int)std::count(fetchedNodes.begin(),fetchedNodes.end(),true)); + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(sz,1); + int *retPtr(ret->getPointer()); + for(int i=0;i<nbNodes;i++) + if(fetchedNodes[i]) + *retPtr++=i; + return ret.retn(); +} + +/*! + * Finds nodes not used in any cell and returns an array giving a new id to every node + * by excluding the unused nodes, for which the array holds -1. The result array is + * a mapping in "Old to New" mode. + * \param [out] nbrOfNodesInUse - number of node ids present in the nodal connectivity. + * \return DataArrayInt * - a new instance of DataArrayInt. Its length is \a + * this->getNumberOfNodes(). It holds for each node of \a this mesh either -1 + * if the node is unused or a new id else. The caller is to delete this + * array using decrRef() as it is no more needed. + * \throw If the coordinates array is not set. + * \throw If the nodal connectivity of cells is not defined. + * \throw If the nodal connectivity includes an invalid id. + * \sa MEDCoupling1DGTUMesh::computeFetchedNodeIds, areAllNodesFetched + */ +DataArrayInt *MEDCoupling1DGTUMesh::getNodeIdsInUse(int& nbrOfNodesInUse) const +{ + nbrOfNodesInUse=-1; + int nbOfNodes=getNumberOfNodes(); + int nbOfCells=getNumberOfCells();//checkCoherency + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New(); + ret->alloc(nbOfNodes,1); + int *traducer=ret->getPointer(); + std::fill(traducer,traducer+nbOfNodes,-1); + const int *conn=_conn->begin(),*conni(_conn_indx->begin()); + for(int i=0;i<nbOfCells;i++,conni++) + { + int nbNodesPerCell=conni[1]-conni[0]; + for(int j=0;j<nbNodesPerCell;j++) + { + int nodeId=conn[conni[0]+j]; + if(nodeId==-1) continue; + if(nodeId>=0 && nodeId<nbOfNodes) + traducer[nodeId]=1; + else + { + std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::getNodeIdsInUse : In cell #" << i << " presence of node id " << nodeId << " not in [0," << nbOfNodes << ") !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + } + } + nbrOfNodesInUse=(int)std::count(traducer,traducer+nbOfNodes,1); + std::transform(traducer,traducer+nbOfNodes,traducer,MEDCouplingAccVisit()); + return ret.retn(); +} + +/*! + * This method renumbers only nodal connectivity in \a this. The renumbering is only an offset applied. So this method is a specialization of + * \a renumberNodesInConn. \b WARNING, this method does not check that the resulting node ids in the nodal connectivity is in a valid range ! + * + * \param [in] offset - specifies the offset to be applied on each element of connectivity. + * + * \sa renumberNodesInConn + */ +void MEDCoupling1DGTUMesh::renumberNodesWithOffsetInConn(int offset) +{ + getNumberOfCells();//only to check that all is well defined. + // + int nbOfTuples(_conn->getNumberOfTuples()); + int *pt(_conn->getPointer()); + for(int i=0;i<nbOfTuples;i++,pt++) + { + if(*pt==-1) continue; + *pt+=offset; + } + // + updateTime(); +} + +/*! + * Same than renumberNodesInConn(const int *) except that here the format of old-to-new traducer is using map instead + * of array. This method is dedicated for renumbering from a big set of nodes the a tiny set of nodes which is the case during extraction + * of a big mesh. + */ +void MEDCoupling1DGTUMesh::renumberNodesInConn(const INTERP_KERNEL::HashMap<int,int>& newNodeNumbersO2N) +{ + getNumberOfCells();//only to check that all is well defined. + // + int nbElemsIn(getNumberOfNodes()),nbOfTuples(_conn->getNumberOfTuples()); + int *pt(_conn->getPointer()); + for(int i=0;i<nbOfTuples;i++,pt++) + { + if(*pt==-1) continue; + if(*pt>=0 && *pt<nbElemsIn) + { + INTERP_KERNEL::HashMap<int,int>::const_iterator it(newNodeNumbersO2N.find(*pt)); + if(it!=newNodeNumbersO2N.end()) + *pt=(*it).second; + else + { + std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::renumberNodesInConn : At pos #" << i << " of connectivity, node id is " << *pt << ". Not in keys of input map !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + } + else + { + std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::renumberNodesInConn : error on tuple #" << i << " value is " << *pt << " and indirectionnal array as a size equal to " << nbElemsIn; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + } + // + updateTime(); +} + +/*! + * Changes ids of nodes within the nodal connectivity arrays according to a permutation + * array in "Old to New" mode. The node coordinates array is \b not changed by this method. + * This method is a generalization of shiftNodeNumbersInConn(). + * \warning This method performs no check of validity of new ids. **Use it with care !** + * \param [in] newNodeNumbersO2N - a permutation array, of length \a + * this->getNumberOfNodes(), in "Old to New" mode. + * See \ref numbering for more info on renumbering modes. + * \throw If the nodal connectivity of cells is not defined. + */ +void MEDCoupling1DGTUMesh::renumberNodesInConn(const int *newNodeNumbersO2N) +{ + getNumberOfCells();//only to check that all is well defined. + // + int nbElemsIn(getNumberOfNodes()),nbOfTuples(_conn->getNumberOfTuples()); + int *pt(_conn->getPointer()); + for(int i=0;i<nbOfTuples;i++,pt++) + { + if(*pt==-1) continue; + if(*pt>=0 && *pt<nbElemsIn) + *pt=newNodeNumbersO2N[*pt]; + else + { + std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::renumberNodesInConn : error on tuple #" << i << " value is " << *pt << " and indirectionnal array as a size equal to " << nbElemsIn; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + } + // + updateTime(); +} + +/*! + * Keeps from \a this only cells which constituing point id are in the ids specified by [\a begin,\a end). + * The resulting cell ids are stored at the end of the 'cellIdsKept' parameter. + * Parameter \a fullyIn specifies if a cell that has part of its nodes in ids array is kept or not. + * If \a fullyIn is true only cells whose ids are \b fully contained in [\a begin,\a end) tab will be kept. + * + * \param [in] begin input start of array of node ids. + * \param [in] end input end of array of node ids. + * \param [in] fullyIn input that specifies if all node ids must be in [\a begin,\a end) array to consider cell to be in. + * \param [in,out] cellIdsKeptArr array where all candidate cell ids are put at the end. + */ +void MEDCoupling1DGTUMesh::fillCellIdsToKeepFromNodeIds(const int *begin, const int *end, bool fullyIn, DataArrayInt *&cellIdsKeptArr) const +{ + int nbOfCells=getNumberOfCells(); + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> cellIdsKept=DataArrayInt::New(); cellIdsKept->alloc(0,1); + int tmp=-1; + int sz=_conn->getMaxValue(tmp); sz=std::max(sz,0)+1; + std::vector<bool> fastFinder(sz,false); + for(const int *work=begin;work!=end;work++) + if(*work>=0 && *work<sz) + fastFinder[*work]=true; + const int *conn=_conn->begin(),*conni=_conn_indx->begin(); + for(int i=0;i<nbOfCells;i++,conni++) + { + int ref=0,nbOfHit=0; + int nbNodesPerCell=conni[1]-conni[0]; + if(nbNodesPerCell>=0) + { + for(int j=0;j<nbNodesPerCell;j++) + { + int nodeId=conn[conni[0]+j]; + if(nodeId>=0) + { + ref++; + if(fastFinder[nodeId]) + nbOfHit++; + } + } + } + else + { + std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::fillCellIdsToKeepFromNodeIds : invalid index array for cell #" << i << " !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + if((ref==nbOfHit && fullyIn) || (nbOfHit!=0 && !fullyIn)) + cellIdsKept->pushBackSilent(i); + } + cellIdsKeptArr=cellIdsKept.retn(); +} + +void MEDCoupling1DGTUMesh::allocateCells(int nbOfCells) +{ + if(nbOfCells<0) + throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::allocateCells : the input number of cells should be >= 0 !"); + _conn=DataArrayInt::New(); + _conn->reserve(nbOfCells*3); + _conn_indx=DataArrayInt::New(); + _conn_indx->reserve(nbOfCells+1); _conn_indx->pushBackSilent(0); + declareAsNew(); +} + +/*! + * Appends at the end of \a this a cell having nodal connectivity array defined in [ \a nodalConnOfCellBg, \a nodalConnOfCellEnd ). + * + * \param [in] nodalConnOfCellBg - the begin (included) of nodal connectivity of the cell to add. + * \param [in] nodalConnOfCellEnd - the end (excluded) of nodal connectivity of the cell to add. + * \throw If the length of the input nodal connectivity array of the cell to add is not equal to number of nodes per cell relative to the unique geometric type + * attached to \a this. + * \thow If the nodal connectivity array in \a this is null (call MEDCoupling1SGTUMesh::allocateCells before). + */ +void MEDCoupling1DGTUMesh::insertNextCell(const int *nodalConnOfCellBg, const int *nodalConnOfCellEnd) +{ + int sz=(int)std::distance(nodalConnOfCellBg,nodalConnOfCellEnd); + DataArrayInt *c(_conn),*c2(_conn_indx); + if(c && c2) + { + int pos=c2->back(); + if(pos==c->getNumberOfTuples()) + { + c->pushBackValsSilent(nodalConnOfCellBg,nodalConnOfCellEnd); + c2->pushBackSilent(pos+sz); + } + else + { + std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::insertNextCell : The nodal index array (end=" << pos << ") mismatches with nodal array (length=" << c->getNumberOfTuples() << ") !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + } + else + throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::insertNextCell : nodal connectivity array is null ! Call MEDCoupling1DGTUMesh::allocateCells before !"); +} + +void MEDCoupling1DGTUMesh::setNodalConnectivity(DataArrayInt *nodalConn, DataArrayInt *nodalConnIndex) +{ + if(nodalConn) + nodalConn->incrRef(); + _conn=nodalConn; + if(nodalConnIndex) + nodalConnIndex->incrRef(); + _conn_indx=nodalConnIndex; + declareAsNew(); +} + +/*! + * \return DataArrayInt * - the internal reference to the nodal connectivity. The caller is not reponsible to deallocate it. + */ +DataArrayInt *MEDCoupling1DGTUMesh::getNodalConnectivity() const +{ + const DataArrayInt *ret(_conn); + return const_cast<DataArrayInt *>(ret); +} + +/*! + * \return DataArrayInt * - the internal reference to the nodal connectivity index. The caller is not reponsible to deallocate it. + */ +DataArrayInt *MEDCoupling1DGTUMesh::getNodalConnectivityIndex() const +{ + const DataArrayInt *ret(_conn_indx); + return const_cast<DataArrayInt *>(ret); +} + +/*! + * See the definition of the nodal connectivity pack \ref MEDCoupling1DGTUMesh::isPacked "here". + * This method tries to build a new instance geometrically equivalent to \a this, by limiting at most the number of new object (nodal connectivity). + * Geometrically the returned mesh is equal to \a this. So if \a this is already packed, the return value is a shallow copy of \a this. + * + * Whatever the status of pack of \a this, the coordinates array of the returned newly created instance is the same than those in \a this. + * + * \param [out] isShallowCpyOfNodalConnn - tells if the returned instance share the same pair of nodal connectivity arrays (true) or if nodal + * connectivity arrays are different (false) + * \return a new object to be managed by the caller. + * + * \sa MEDCoupling1DGTUMesh::retrievePackedNodalConnectivity, MEDCoupling1DGTUMesh::isPacked + */ +MEDCoupling1DGTUMesh *MEDCoupling1DGTUMesh::copyWithNodalConnectivityPacked(bool& isShallowCpyOfNodalConnn) const +{ + MEDCouplingAutoRefCountObjectPtr<MEDCoupling1DGTUMesh> ret(new MEDCoupling1DGTUMesh(getName(),*_cm)); + DataArrayInt *nc=0,*nci=0; + isShallowCpyOfNodalConnn=retrievePackedNodalConnectivity(nc,nci); + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ncs(nc),ncis(nci); + ret->_conn=ncs; ret->_conn_indx=ncis; + ret->setCoords(getCoords()); + return ret.retn(); +} + +/*! + * This method allows to compute, if needed, the packed nodal connectivity pair. + * Indeed, it is possible to store in \a this a nodal connectivity array bigger than ranges convered by nodal connectivity index array. + * It is typically the case when nodalConnIndx starts with an id greater than 0, and finishes with id less than number of tuples in \c this->_conn. + * + * If \a this looks packed (the front of nodal connectivity index equal to 0 and back of connectivity index equal to number of tuple of nodal connectivity array) + * true will be returned and respectively \a this->_conn and \a this->_conn_indx (with ref counter incremented). This is the classical case. + * + * If nodal connectivity index points to a subpart of nodal connectivity index the packed pair of arrays will be computed (new objects) and returned and false + * will be returned. + * + * This method return 3 elements. + * \param [out] nodalConn - a pointer that can be equal to \a this->_conn if true is returned (general case). Whatever the value of return parameter + * this pointer can be seen as a new object, that is to managed by the caller. + * \param [out] nodalConnIndx - a pointer that can be equal to \a this->_conn_indx if true is returned (general case). Whatever the value of return parameter + * this pointer can be seen as a new object, that is to managed by the caller. + * \return bool - an indication of the content of the 2 output parameters. If true, \a this looks packed (general case), if true, \a this is not packed then + * output parameters are newly created objects. + * + * \throw if \a this does not pass MEDCoupling1DGTUMesh::checkCoherency test + */ +bool MEDCoupling1DGTUMesh::retrievePackedNodalConnectivity(DataArrayInt *&nodalConn, DataArrayInt *&nodalConnIndx) const +{ + if(isPacked())//performs the checkCoherency + { + const DataArrayInt *c0(_conn),*c1(_conn_indx); + nodalConn=const_cast<DataArrayInt *>(c0); nodalConnIndx=const_cast<DataArrayInt *>(c1); + nodalConn->incrRef(); nodalConnIndx->incrRef(); + return true; + } + int bg=_conn_indx->front(),end=_conn_indx->back(); + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> nc(_conn->selectByTupleId2(bg,end,1)); + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> nci(_conn_indx->deepCpy()); + nci->applyLin(1,-bg); + nodalConn=nc.retn(); nodalConnIndx=nci.retn(); + return false; +} + +/* + * If \a this looks packed (the front of nodal connectivity index equal to 0 and back of connectivity index equal to number of tuple of nodal connectivity array) + * true will be returned and respectively \a this->_conn and \a this->_conn_indx (with ref counter incremented). This is the classical case. + * If nodal connectivity index points to a subpart of nodal connectivity index false will be returned. + * \return bool - true if \a this looks packed, false is not. + * + * \throw if \a this does not pass MEDCoupling1DGTUMesh::checkCoherency test + */ +bool MEDCoupling1DGTUMesh::isPacked() const +{ + checkCoherency(); + return _conn_indx->front()==0 && _conn_indx->back()==_conn->getNumberOfTuples(); +} + +MEDCoupling1DGTUMesh *MEDCoupling1DGTUMesh::Merge1DGTUMeshes(const MEDCoupling1DGTUMesh *mesh1, const MEDCoupling1DGTUMesh *mesh2) +{ + std::vector<const MEDCoupling1DGTUMesh *> tmp(2); + tmp[0]=const_cast<MEDCoupling1DGTUMesh *>(mesh1); tmp[1]=const_cast<MEDCoupling1DGTUMesh *>(mesh2); + return Merge1DGTUMeshes(tmp); +} + +MEDCoupling1DGTUMesh *MEDCoupling1DGTUMesh::Merge1DGTUMeshes(std::vector<const MEDCoupling1DGTUMesh *>& a) +{ + std::size_t sz=a.size(); + if(sz==0) + return Merge1DGTUMeshesLL(a); + for(std::size_t ii=0;ii<sz;ii++) + if(!a[ii]) + { + std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::Merge1DGTUMeshes : item #" << ii << " in input array of size "<< sz << " is empty !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + const INTERP_KERNEL::CellModel *cm=&(a[0]->getCellModel()); + for(std::size_t ii=0;ii<sz;ii++) + if(&(a[ii]->getCellModel())!=cm) + throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::Merge1DGTUMeshes : all items must have the same geo type !"); + std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCoupling1DGTUMesh> > bb(sz); + std::vector< const MEDCoupling1DGTUMesh * > aa(sz); + int spaceDim=-3; + for(std::size_t i=0;i<sz && spaceDim==-3;i++) + { + const MEDCoupling1DGTUMesh *cur=a[i]; + const DataArrayDouble *coo=cur->getCoords(); + if(coo) + spaceDim=coo->getNumberOfComponents(); + } + if(spaceDim==-3) + throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::Merge1DGTUMeshes : no spaceDim specified ! unable to perform merge !"); + for(std::size_t i=0;i<sz;i++) + { + bb[i]=a[i]->buildSetInstanceFromThis(spaceDim); + aa[i]=bb[i]; + } + return Merge1DGTUMeshesLL(aa); +} + +/*! + * \throw If presence of a null instance in the input vector \a a. + * \throw If a is empty + */ +MEDCoupling1DGTUMesh *MEDCoupling1DGTUMesh::Merge1DGTUMeshesOnSameCoords(std::vector<const MEDCoupling1DGTUMesh *>& a) +{ + if(a.empty()) + throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::Merge1DGTUMeshesOnSameCoords : input array must be NON EMPTY !"); + std::vector<const MEDCoupling1DGTUMesh *>::const_iterator it=a.begin(); + if(!(*it)) + throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::Merge1DGTUMeshesOnSameCoords : null instance in the first element of input vector !"); + std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCoupling1DGTUMesh> > objs(a.size()); + std::vector<const DataArrayInt *> ncs(a.size()),ncis(a.size()); + (*it)->getNumberOfCells();//to check that all is OK + const DataArrayDouble *coords=(*it)->getCoords(); + const INTERP_KERNEL::CellModel *cm=&((*it)->getCellModel()); + bool tmp; + objs[0]=(*it)->copyWithNodalConnectivityPacked(tmp); + ncs[0]=objs[0]->getNodalConnectivity(); ncis[0]=objs[0]->getNodalConnectivityIndex(); + it++; + for(int i=1;it!=a.end();i++,it++) + { + if(!(*it)) + throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::Merge1DGTUMeshesOnSameCoords : presence of null instance !"); + if(cm!=&((*it)->getCellModel())) + throw INTERP_KERNEL::Exception("Geometric types mismatches, Merge1DGTUMeshes impossible !"); + (*it)->getNumberOfCells();//to check that all is OK + objs[i]=(*it)->copyWithNodalConnectivityPacked(tmp); + ncs[i]=objs[i]->getNodalConnectivity(); ncis[i]=objs[i]->getNodalConnectivityIndex(); + if(coords!=(*it)->getCoords()) + throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::Merge1DGTUMeshesOnSameCoords : not lying on same coords !"); + } + MEDCouplingAutoRefCountObjectPtr<MEDCoupling1DGTUMesh> ret(new MEDCoupling1DGTUMesh("merge",*cm)); + ret->setCoords(coords); + ret->_conn=DataArrayInt::Aggregate(ncs); + ret->_conn_indx=DataArrayInt::AggregateIndexes(ncis); + return ret.retn(); +} + +/*! + * Assume that all instances in \a a are non null. If null it leads to a crash. That's why this method is assigned to be low level (LL) + */ +MEDCoupling1DGTUMesh *MEDCoupling1DGTUMesh::Merge1DGTUMeshesLL(std::vector<const MEDCoupling1DGTUMesh *>& a) +{ + if(a.empty()) + throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::Merge1DGTUMeshes : input array must be NON EMPTY !"); + std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCoupling1DGTUMesh> > objs(a.size()); + std::vector<const DataArrayInt *> ncs(a.size()),ncis(a.size()); + std::vector<const MEDCoupling1DGTUMesh *>::const_iterator it=a.begin(); + std::vector<int> nbNodesPerElt(a.size()); + int nbOfCells=(*it)->getNumberOfCells(); + bool tmp; + objs[0]=(*it)->copyWithNodalConnectivityPacked(tmp); + ncs[0]=objs[0]->getNodalConnectivity(); ncis[0]=objs[0]->getNodalConnectivityIndex(); + nbNodesPerElt[0]=0; + int prevNbOfNodes=(*it)->getNumberOfNodes(); + const INTERP_KERNEL::CellModel *cm=&((*it)->getCellModel()); + it++; + for(int i=1;it!=a.end();i++,it++) + { + if(cm!=&((*it)->getCellModel())) + throw INTERP_KERNEL::Exception("Geometric types mismatches, Merge1DGTUMeshes impossible !"); + objs[i]=(*it)->copyWithNodalConnectivityPacked(tmp); + ncs[i]=objs[i]->getNodalConnectivity(); ncis[i]=objs[i]->getNodalConnectivityIndex(); + nbOfCells+=(*it)->getNumberOfCells(); + nbNodesPerElt[i]=nbNodesPerElt[i-1]+prevNbOfNodes; + prevNbOfNodes=(*it)->getNumberOfNodes(); + } + std::vector<const MEDCouplingPointSet *> aps(a.size()); + std::copy(a.begin(),a.end(),aps.begin()); + MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> pts=MergeNodesArray(aps); + MEDCouplingAutoRefCountObjectPtr<MEDCoupling1DGTUMesh> ret(new MEDCoupling1DGTUMesh("merge",*cm)); + ret->setCoords(pts); + ret->_conn=AggregateNodalConnAndShiftNodeIds(ncs,nbNodesPerElt); + ret->_conn_indx=DataArrayInt::AggregateIndexes(ncis); + return ret.retn(); +} + +MEDCoupling1DGTUMesh *MEDCoupling1DGTUMesh::buildSetInstanceFromThis(int spaceDim) const +{ + MEDCouplingAutoRefCountObjectPtr<MEDCoupling1DGTUMesh> ret(new MEDCoupling1DGTUMesh(getName(),*_cm)); + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> tmp1,tmp2; + const DataArrayInt *nodalConn(_conn),*nodalConnI(_conn_indx); + if(!nodalConn) + { + tmp1=DataArrayInt::New(); tmp1->alloc(0,1); + } + else + tmp1=_conn; + ret->_conn=tmp1; + // + if(!nodalConnI) + { + tmp2=DataArrayInt::New(); tmp2->alloc(1,1); tmp2->setIJ(0,0,0); + } + else + tmp2=_conn_indx; + ret->_conn_indx=tmp2; + // + if(!_coords) + { + MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> coords=DataArrayDouble::New(); coords->alloc(0,spaceDim); + ret->setCoords(coords); + } + else + ret->setCoords(_coords); + return ret.retn(); +} + +/*! + * This method aggregate the bbox of each cell and put it into bbox parameter. + * + * \param [in] arcDetEps - a parameter specifying in case of 2D quadratic polygon cell the detection limit between linear and arc circle. (By default 1e-12) + * For all other cases this input parameter is ignored. + * \return DataArrayDouble * - newly created object (to be managed by the caller) \a this number of cells tuples and 2*spacedim components. + * + * \throw If \a this is not fully set (coordinates and connectivity). + * \throw If a cell in \a this has no valid nodeId. + */ +DataArrayDouble *MEDCoupling1DGTUMesh::getBoundingBoxForBBTree(double arcDetEps) const +{ + checkFullyDefined(); + int spaceDim(getSpaceDimension()),nbOfCells(getNumberOfCells()),nbOfNodes(getNumberOfNodes()); + MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret(DataArrayDouble::New()); ret->alloc(nbOfCells,2*spaceDim); + double *bbox(ret->getPointer()); + for(int i=0;i<nbOfCells*spaceDim;i++) + { + bbox[2*i]=std::numeric_limits<double>::max(); + bbox[2*i+1]=-std::numeric_limits<double>::max(); + } + const double *coordsPtr(_coords->getConstPointer()); + const int *conn(_conn->getConstPointer()),*connI(_conn_indx->getConstPointer()); + for(int i=0;i<nbOfCells;i++) + { + int offset=connI[i]; + int nbOfNodesForCell(connI[i+1]-offset),kk(0); + for(int j=0;j<nbOfNodesForCell;j++) + { + int nodeId=conn[offset+j]; + if(nodeId>=0 && nodeId<nbOfNodes) + { + for(int k=0;k<spaceDim;k++) + { + bbox[2*spaceDim*i+2*k]=std::min(bbox[2*spaceDim*i+2*k],coordsPtr[spaceDim*nodeId+k]); + bbox[2*spaceDim*i+2*k+1]=std::max(bbox[2*spaceDim*i+2*k+1],coordsPtr[spaceDim*nodeId+k]); + } + kk++; + } + } + if(kk==0) + { + std::ostringstream oss; oss << "MEDCoupling1SGTUMesh::getBoundingBoxForBBTree : cell #" << i << " contains no valid nodeId !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + } + return ret.retn(); +} + +/*! + * Returns the cell field giving for each cell in \a this its diameter. Diameter means the max length of all possible SEG2 in the cell. + * + * \return a new instance of field containing the result. The returned instance has to be deallocated by the caller. + */ +MEDCouplingFieldDouble *MEDCoupling1DGTUMesh::computeDiameterField() const +{ + throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::computeDiameterField : not implemented yet for dynamic types !"); +} + +std::vector<int> MEDCoupling1DGTUMesh::BuildAPolygonFromParts(const std::vector< std::vector<int> >& parts) +{ + std::vector<int> ret; + if(parts.empty()) + return ret; + ret.insert(ret.end(),parts[0].begin(),parts[0].end()); + int ref(ret.back()); + std::size_t sz(parts.size()),nbh(1); + std::vector<bool> b(sz,true); b[0]=false; + while(nbh<sz) + { + std::size_t i(0); + for(;i<sz;i++) if(b[i] && parts[i].front()==ref) { ret.insert(ret.end(),parts[i].begin()+1,parts[i].end()); nbh++; break; } + if(i<sz) + ref=ret.back(); + else + throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::BuildAPolygonFromParts : the input vector is not a part of a single polygon !"); + } + if(ret.back()==ret.front()) + ret.pop_back(); + return ret; +} + +/*! + * This method performs an aggregation of \a nodalConns (as DataArrayInt::Aggregate does) but in addition of that a shift is applied on the + * values contained in \a nodalConns using corresponding offset specified in input \a offsetInNodeIdsPerElt. + * But it also manage the values -1, that have a semantic in MEDCoupling1DGTUMesh class (separator for polyhedron). + * + * \param [in] nodalConns - a list of nodal connectivity arrays same size than \a offsetInNodeIdsPerElt. + * \param [in] offsetInNodeIdsPerElt - a list of offsets to apply. + * \return DataArrayInt * - A new object (to be managed by the caller) that is the result of the aggregation. + * \throw If \a nodalConns or \a offsetInNodeIdsPerElt are empty. + * \throw If \a nodalConns and \a offsetInNodeIdsPerElt have not the same size. + * \throw If presence of null pointer in \a nodalConns. + * \throw If presence of not allocated or array with not exactly one component in \a nodalConns. + */ +DataArrayInt *MEDCoupling1DGTUMesh::AggregateNodalConnAndShiftNodeIds(const std::vector<const DataArrayInt *>& nodalConns, const std::vector<int>& offsetInNodeIdsPerElt) +{ + std::size_t sz1(nodalConns.size()),sz2(offsetInNodeIdsPerElt.size()); + if(sz1!=sz2) + throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::AggregateNodalConnAndShiftNodeIds : input vectors do not have the same size !"); + if(sz1==0) + throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::AggregateNodalConnAndShiftNodeIds : empty vectors in input !"); + int nbOfTuples=0; + for(std::vector<const DataArrayInt *>::const_iterator it=nodalConns.begin();it!=nodalConns.end();it++) + { + if(!(*it)) + throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::AggregateNodalConnAndShiftNodeIds : presence of null pointer in input vector !"); + if(!(*it)->isAllocated()) + throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::AggregateNodalConnAndShiftNodeIds : presence of non allocated array in input vector !"); + if((*it)->getNumberOfComponents()!=1) + throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::AggregateNodalConnAndShiftNodeIds : presence of array with not exactly one component !"); + nbOfTuples+=(*it)->getNumberOfTuples(); + } + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(nbOfTuples,1); + int *pt=ret->getPointer(); + int i=0; + for(std::vector<const DataArrayInt *>::const_iterator it=nodalConns.begin();it!=nodalConns.end();it++,i++) + { + int curNbt=(*it)->getNumberOfTuples(); + const int *inPt=(*it)->begin(); + int offset=offsetInNodeIdsPerElt[i]; + for(int j=0;j<curNbt;j++,pt++) + { + if(inPt[j]!=-1) + *pt=inPt[j]+offset; + else + *pt=-1; + } + } + return ret.retn(); +} + +MEDCoupling1DGTUMesh *MEDCoupling1DGTUMesh::New(const MEDCouplingUMesh *m) +{ + if(!m) + throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::New : input mesh is null !"); + std::set<INTERP_KERNEL::NormalizedCellType> gts(m->getAllGeoTypes()); + if(gts.size()!=1) + throw INTERP_KERNEL::Exception("MEDCoupling1DGTUMesh::New : input mesh must have exactly one geometric type !"); + int geoType((int)*gts.begin()); + MEDCouplingAutoRefCountObjectPtr<MEDCoupling1DGTUMesh> ret(MEDCoupling1DGTUMesh::New(m->getName(),*gts.begin())); + ret->setCoords(m->getCoords()); ret->setDescription(m->getDescription()); + int nbCells(m->getNumberOfCells()); + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> conn(DataArrayInt::New()),connI(DataArrayInt::New()); + conn->alloc(m->getMeshLength()-nbCells,1); connI->alloc(nbCells+1,1); + int *c(conn->getPointer()),*ci(connI->getPointer()); *ci=0; + const int *cin(m->getNodalConnectivity()->begin()),*ciin(m->getNodalConnectivityIndex()->begin()); + for(int i=0;i<nbCells;i++,ciin++,ci++) + { + if(cin[ciin[0]]==geoType) + { + if(ciin[1]-ciin[0]>=1) + { + c=std::copy(cin+ciin[0]+1,cin+ciin[1],c); + ci[1]=ci[0]+ciin[1]-ciin[0]-1; + } + else + { + std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::New(const MEDCouplingUMesh *m) : something is wrong in the input mesh at cell #" << i << " ! The size of cell is not >=0 !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + } + else + { + std::ostringstream oss; oss << "MEDCoupling1DGTUMesh::New(const MEDCouplingUMesh *m) : something is wrong in the input mesh at cell #" << i << " ! The geometric type is not those expected !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + } + ret->setNodalConnectivity(conn,connI); + return ret.retn(); +} diff --git a/src/medtool/src/MEDCoupling/MEDCoupling1GTUMesh.hxx b/src/medtool/src/MEDCoupling/MEDCoupling1GTUMesh.hxx new file mode 100644 index 000000000..9928bc48f --- /dev/null +++ b/src/medtool/src/MEDCoupling/MEDCoupling1GTUMesh.hxx @@ -0,0 +1,270 @@ +// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 +// 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_MEDCOUPLING1GTUMESH_HXX__ +#define __PARAMEDMEM_MEDCOUPLING1GTUMESH_HXX__ + +#include "MEDCoupling.hxx" +#include "MEDCouplingPointSet.hxx" +#include "MEDCouplingMemArray.hxx" +#include "MEDCouplingAutoRefCountObjectPtr.hxx" + +#include "CellModel.hxx" + +namespace ParaMEDMEM +{ + class MEDCoupling1GTUUMeshCellIterator; + + class MEDCoupling1GTUMesh : public MEDCouplingPointSet + { + public: + MEDCOUPLING_EXPORT static MEDCoupling1GTUMesh *New(const std::string& name, INTERP_KERNEL::NormalizedCellType type); + MEDCOUPLING_EXPORT static MEDCoupling1GTUMesh *New(const MEDCouplingUMesh *m); + MEDCOUPLING_EXPORT const INTERP_KERNEL::CellModel& getCellModel() const; + MEDCOUPLING_EXPORT INTERP_KERNEL::NormalizedCellType getCellModelEnum() const; + MEDCOUPLING_EXPORT int getMeshDimension() const; + MEDCOUPLING_EXPORT DataArrayInt *giveCellsWithType(INTERP_KERNEL::NormalizedCellType type) const; + MEDCOUPLING_EXPORT int getNumberOfCellsWithType(INTERP_KERNEL::NormalizedCellType type) const; + MEDCOUPLING_EXPORT INTERP_KERNEL::NormalizedCellType getTypeOfCell(int cellId) const; + MEDCOUPLING_EXPORT std::set<INTERP_KERNEL::NormalizedCellType> getAllGeoTypes() const; + MEDCOUPLING_EXPORT std::vector<int> getDistributionOfTypes() const; + MEDCOUPLING_EXPORT void splitProfilePerType(const DataArrayInt *profile, std::vector<int>& code, std::vector<DataArrayInt *>& idsInPflPerType, std::vector<DataArrayInt *>& idsPerType) const; + MEDCOUPLING_EXPORT DataArrayInt *checkTypeConsistencyAndContig(const std::vector<int>& code, const std::vector<const DataArrayInt *>& idsPerType) const; + MEDCOUPLING_EXPORT void writeVTKLL(std::ostream& ofs, const std::string& cellData, const std::string& pointData, DataArrayByte *byteData) const; + MEDCOUPLING_EXPORT std::string getVTKDataSetType() const; + MEDCOUPLING_EXPORT std::string getVTKFileExtension() const; + // + MEDCOUPLING_EXPORT std::size_t getHeapMemorySizeWithoutChildren() const; + MEDCOUPLING_EXPORT int getNodalConnectivityLength() const; + MEDCOUPLING_EXPORT bool isEqualIfNotWhy(const MEDCouplingMesh *other, double prec, std::string& reason) const; + MEDCOUPLING_EXPORT bool isEqualWithoutConsideringStr(const MEDCouplingMesh *other, double prec) const; + MEDCOUPLING_EXPORT void checkCoherency() const; + MEDCOUPLING_EXPORT DataArrayDouble *getBarycenterAndOwner() const; + MEDCOUPLING_EXPORT MEDCouplingFieldDouble *getMeasureField(bool isAbs) const; + MEDCOUPLING_EXPORT MEDCouplingFieldDouble *getMeasureFieldOnNode(bool isAbs) const; + MEDCOUPLING_EXPORT int getCellContainingPoint(const double *pos, double eps) const; + MEDCOUPLING_EXPORT MEDCouplingFieldDouble *buildOrthogonalField() const; + MEDCOUPLING_EXPORT DataArrayInt *getCellsInBoundingBox(const double *bbox, double eps) const; + MEDCOUPLING_EXPORT DataArrayInt *getCellsInBoundingBox(const INTERP_KERNEL::DirectedBoundingBox& bbox, double eps); + MEDCOUPLING_EXPORT MEDCouplingPointSet *buildFacePartOfMySelfNode(const int *start, const int *end, bool fullyIn) const; + MEDCOUPLING_EXPORT DataArrayInt *findBoundaryNodes() const; + MEDCOUPLING_EXPORT MEDCouplingPointSet *buildBoundaryMesh(bool keepCoords) const; + MEDCOUPLING_EXPORT void findCommonCells(int compType, int startCellId, DataArrayInt *& commonCellsArr, DataArrayInt *& commonCellsIArr) const; + MEDCOUPLING_EXPORT static MEDCouplingUMesh *AggregateOnSameCoordsToUMesh(const std::vector< const MEDCoupling1GTUMesh *>& parts); + public: + MEDCOUPLING_EXPORT virtual void allocateCells(int nbOfCells=0) = 0; + MEDCOUPLING_EXPORT virtual void insertNextCell(const int *nodalConnOfCellBg, const int *nodalConnOfCellEnd) = 0; + MEDCOUPLING_EXPORT virtual DataArrayInt *getNodalConnectivity() const = 0; + MEDCOUPLING_EXPORT virtual void checkCoherencyOfConnectivity() const = 0; + protected: + MEDCoupling1GTUMesh(const std::string& name, const INTERP_KERNEL::CellModel& cm); + MEDCoupling1GTUMesh(const MEDCoupling1GTUMesh& other, bool recDeepCpy); + MEDCoupling1GTUMesh(); + protected: + const INTERP_KERNEL::CellModel *_cm; + }; + + class MEDCoupling1DGTUMesh; + class MEDCouplingCMesh; + + class MEDCoupling1SGTUMesh : public MEDCoupling1GTUMesh + { + public: + MEDCOUPLING_EXPORT static MEDCoupling1SGTUMesh *New(const std::string& name, INTERP_KERNEL::NormalizedCellType type); + MEDCOUPLING_EXPORT static MEDCoupling1SGTUMesh *New(const MEDCouplingUMesh *m); + //! useless constructor only for CORBA -> not swigged + MEDCOUPLING_EXPORT static MEDCoupling1SGTUMesh *New(); + MEDCOUPLING_EXPORT MEDCoupling1SGTUMesh *clone(bool recDeepCpy) const; + MEDCOUPLING_EXPORT MEDCouplingPointSet *deepCpyConnectivityOnly() const; + // overload of TimeLabel and RefCountObject + MEDCOUPLING_EXPORT void updateTime() const; + MEDCOUPLING_EXPORT std::size_t getHeapMemorySizeWithoutChildren() const; + MEDCOUPLING_EXPORT std::vector<const BigMemoryObject *> getDirectChildrenWithNull() const; + // overload of MEDCouplingMesh + MEDCOUPLING_EXPORT MEDCouplingMeshType getType() const { return SINGLE_STATIC_GEO_TYPE_UNSTRUCTURED; } + MEDCOUPLING_EXPORT MEDCouplingMesh *deepCpy() const; + MEDCOUPLING_EXPORT bool isEqualIfNotWhy(const MEDCouplingMesh *other, double prec, std::string& reason) const; + MEDCOUPLING_EXPORT bool isEqualWithoutConsideringStr(const MEDCouplingMesh *other, double prec) const; + MEDCOUPLING_EXPORT void checkFastEquivalWith(const MEDCouplingMesh *other, double prec) const; + MEDCOUPLING_EXPORT void checkCoherency() const; + MEDCOUPLING_EXPORT void checkCoherency1(double eps=1e-12) const; + MEDCOUPLING_EXPORT void checkCoherency2(double eps=1e-12) const; + MEDCOUPLING_EXPORT int getNumberOfCells() const; + MEDCOUPLING_EXPORT DataArrayInt *computeNbOfNodesPerCell() const; + MEDCOUPLING_EXPORT DataArrayInt *computeNbOfFacesPerCell() const; + MEDCOUPLING_EXPORT DataArrayInt *computeEffectiveNbOfNodesPerCell() const; + MEDCOUPLING_EXPORT void getNodeIdsOfCell(int cellId, std::vector<int>& conn) const; + MEDCOUPLING_EXPORT std::string simpleRepr() const; + MEDCOUPLING_EXPORT std::string advancedRepr() const; + MEDCOUPLING_EXPORT DataArrayDouble *computeIsoBarycenterOfNodesPerCell() const; + MEDCOUPLING_EXPORT void renumberCells(const int *old2NewBg, bool check=true); + MEDCOUPLING_EXPORT MEDCouplingMesh *mergeMyselfWith(const MEDCouplingMesh *other) const; + MEDCOUPLING_EXPORT MEDCouplingUMesh *buildUnstructured() const; + MEDCOUPLING_EXPORT DataArrayInt *simplexize(int policy); + MEDCOUPLING_EXPORT void reprQuickOverview(std::ostream& stream) const; + // overload of MEDCouplingPointSet + MEDCOUPLING_EXPORT void shallowCopyConnectivityFrom(const MEDCouplingPointSet *other); + MEDCOUPLING_EXPORT MEDCouplingPointSet *mergeMyselfWithOnSameCoords(const MEDCouplingPointSet *other) const; + MEDCOUPLING_EXPORT MEDCouplingPointSet *buildPartOfMySelfKeepCoords(const int *begin, const int *end) const; + MEDCOUPLING_EXPORT MEDCouplingPointSet *buildPartOfMySelfKeepCoords2(int start, int end, int step) const; + MEDCOUPLING_EXPORT void computeNodeIdsAlg(std::vector<bool>& nodeIdsInUse) const; + MEDCOUPLING_EXPORT void getReverseNodalConnectivity(DataArrayInt *revNodal, DataArrayInt *revNodalIndx) const; + MEDCOUPLING_EXPORT void checkFullyDefined() const; + MEDCOUPLING_EXPORT bool isEmptyMesh(const std::vector<int>& tinyInfo) const; + MEDCOUPLING_EXPORT DataArrayInt *computeFetchedNodeIds() const; + MEDCOUPLING_EXPORT DataArrayInt *getNodeIdsInUse(int& nbrOfNodesInUse) const; + MEDCOUPLING_EXPORT void renumberNodesWithOffsetInConn(int offset); + MEDCOUPLING_EXPORT void renumberNodesInConn(const INTERP_KERNEL::HashMap<int,int>& newNodeNumbersO2N); + MEDCOUPLING_EXPORT void renumberNodesInConn(const int *newNodeNumbersO2N); + MEDCOUPLING_EXPORT void fillCellIdsToKeepFromNodeIds(const int *begin, const int *end, bool fullyIn, DataArrayInt *&cellIdsKeptArr) const; + MEDCOUPLING_EXPORT int getNumberOfNodesInCell(int cellId) const; + MEDCOUPLING_EXPORT DataArrayDouble *getBoundingBoxForBBTree(double arcDetEps=1e-12) const; + MEDCOUPLING_EXPORT MEDCouplingFieldDouble *computeDiameterField() const; + // overload of MEDCoupling1GTUMesh + MEDCOUPLING_EXPORT void checkCoherencyOfConnectivity() const; + MEDCOUPLING_EXPORT void allocateCells(int nbOfCells=0); + MEDCOUPLING_EXPORT void insertNextCell(const int *nodalConnOfCellBg, const int *nodalConnOfCellEnd); + public://specific + MEDCOUPLING_EXPORT void setNodalConnectivity(DataArrayInt *nodalConn); + MEDCOUPLING_EXPORT DataArrayInt *getNodalConnectivity() const; + MEDCOUPLING_EXPORT int getNumberOfNodesPerCell() const; + MEDCOUPLING_EXPORT static MEDCoupling1SGTUMesh *Merge1SGTUMeshes(const MEDCoupling1SGTUMesh *mesh1, const MEDCoupling1SGTUMesh *mesh2); + MEDCOUPLING_EXPORT static MEDCoupling1SGTUMesh *Merge1SGTUMeshes(std::vector<const MEDCoupling1SGTUMesh *>& a); + MEDCOUPLING_EXPORT static MEDCoupling1SGTUMesh *Merge1SGTUMeshesOnSameCoords(std::vector<const MEDCoupling1SGTUMesh *>& a); + MEDCOUPLING_EXPORT MEDCoupling1SGTUMesh *buildSetInstanceFromThis(int spaceDim) const; + MEDCOUPLING_EXPORT MEDCoupling1GTUMesh *computeDualMesh() const; + MEDCOUPLING_EXPORT DataArrayInt *sortHexa8EachOther(); + MEDCOUPLING_EXPORT MEDCoupling1SGTUMesh *explodeEachHexa8To6Quad4() const; + MEDCOUPLING_EXPORT MEDCouplingCMesh *structurizeMe(DataArrayInt *& cellPerm, DataArrayInt *& nodePerm, double eps=1e-12) const; + public://serialization + MEDCOUPLING_EXPORT void getTinySerializationInformation(std::vector<double>& tinyInfoD, std::vector<int>& tinyInfo, std::vector<std::string>& littleStrings) const; + MEDCOUPLING_EXPORT void resizeForUnserialization(const std::vector<int>& tinyInfo, DataArrayInt *a1, DataArrayDouble *a2, std::vector<std::string>& littleStrings) const; + MEDCOUPLING_EXPORT void serialize(DataArrayInt *&a1, DataArrayDouble *&a2) const; + MEDCOUPLING_EXPORT void unserialization(const std::vector<double>& tinyInfoD, const std::vector<int>& tinyInfo, const DataArrayInt *a1, DataArrayDouble *a2, + const std::vector<std::string>& littleStrings); + private: + MEDCoupling1SGTUMesh(const std::string& name, const INTERP_KERNEL::CellModel& cm); + MEDCoupling1SGTUMesh(const MEDCoupling1SGTUMesh& other, bool recDeepCpy); + MEDCoupling1SGTUMesh(); + private: + void checkNonDynamicGeoType() const; + static MEDCoupling1SGTUMesh *Merge1SGTUMeshesLL(std::vector<const MEDCoupling1SGTUMesh *>& a); + DataArrayInt *simplexizePol0(); + DataArrayInt *simplexizePol1(); + DataArrayInt *simplexizePlanarFace5(); + DataArrayInt *simplexizePlanarFace6(); + MEDCoupling1DGTUMesh *computeDualMesh3D() const; + MEDCoupling1DGTUMesh *computeDualMesh2D() const; + private: + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> _conn; + public: + static const int HEXA8_FACE_PAIRS[6]; + }; + + class MEDCoupling1DGTUMesh : public MEDCoupling1GTUMesh + { + public: + MEDCOUPLING_EXPORT static MEDCoupling1DGTUMesh *New(const std::string& name, INTERP_KERNEL::NormalizedCellType type); + MEDCOUPLING_EXPORT static MEDCoupling1DGTUMesh *New(const MEDCouplingUMesh *m); + //! useless constructor only for CORBA -> not swigged + MEDCOUPLING_EXPORT static MEDCoupling1DGTUMesh *New(); + MEDCOUPLING_EXPORT MEDCoupling1DGTUMesh *clone(bool recDeepCpy) const; + MEDCOUPLING_EXPORT MEDCouplingPointSet *deepCpyConnectivityOnly() const; + // overload of TimeLabel and RefCountObject + MEDCOUPLING_EXPORT void updateTime() const; + MEDCOUPLING_EXPORT std::size_t getHeapMemorySizeWithoutChildren() const; + MEDCOUPLING_EXPORT std::vector<const BigMemoryObject *> getDirectChildrenWithNull() const; + // overload of MEDCouplingMesh + MEDCOUPLING_EXPORT MEDCouplingMeshType getType() const { return SINGLE_DYNAMIC_GEO_TYPE_UNSTRUCTURED; } + MEDCOUPLING_EXPORT MEDCouplingMesh *deepCpy() const; + MEDCOUPLING_EXPORT bool isEqualIfNotWhy(const MEDCouplingMesh *other, double prec, std::string& reason) const; + MEDCOUPLING_EXPORT bool isEqualWithoutConsideringStr(const MEDCouplingMesh *other, double prec) const; + MEDCOUPLING_EXPORT void checkFastEquivalWith(const MEDCouplingMesh *other, double prec) const; + MEDCOUPLING_EXPORT void checkCoherency() const; + MEDCOUPLING_EXPORT void checkCoherency1(double eps=1e-12) const; + MEDCOUPLING_EXPORT void checkCoherency2(double eps=1e-12) const; + MEDCOUPLING_EXPORT int getNumberOfCells() const; + MEDCOUPLING_EXPORT DataArrayInt *computeNbOfNodesPerCell() const; + MEDCOUPLING_EXPORT DataArrayInt *computeNbOfFacesPerCell() const; + MEDCOUPLING_EXPORT DataArrayInt *computeEffectiveNbOfNodesPerCell() const; + MEDCOUPLING_EXPORT void getNodeIdsOfCell(int cellId, std::vector<int>& conn) const; + MEDCOUPLING_EXPORT std::string simpleRepr() const; + MEDCOUPLING_EXPORT std::string advancedRepr() const; + MEDCOUPLING_EXPORT DataArrayDouble *computeIsoBarycenterOfNodesPerCell() const; + MEDCOUPLING_EXPORT void renumberCells(const int *old2NewBg, bool check=true); + MEDCOUPLING_EXPORT MEDCouplingMesh *mergeMyselfWith(const MEDCouplingMesh *other) const; + MEDCOUPLING_EXPORT MEDCouplingUMesh *buildUnstructured() const; + MEDCOUPLING_EXPORT DataArrayInt *simplexize(int policy); + MEDCOUPLING_EXPORT void reprQuickOverview(std::ostream& stream) const; + // overload of MEDCouplingPointSet + MEDCOUPLING_EXPORT void shallowCopyConnectivityFrom(const MEDCouplingPointSet *other); + MEDCOUPLING_EXPORT MEDCouplingPointSet *mergeMyselfWithOnSameCoords(const MEDCouplingPointSet *other) const; + MEDCOUPLING_EXPORT MEDCouplingPointSet *buildPartOfMySelfKeepCoords(const int *begin, const int *end) const; + MEDCOUPLING_EXPORT MEDCouplingPointSet *buildPartOfMySelfKeepCoords2(int start, int end, int step) const; + MEDCOUPLING_EXPORT void computeNodeIdsAlg(std::vector<bool>& nodeIdsInUse) const; + MEDCOUPLING_EXPORT void getReverseNodalConnectivity(DataArrayInt *revNodal, DataArrayInt *revNodalIndx) const; + MEDCOUPLING_EXPORT void checkFullyDefined() const; + MEDCOUPLING_EXPORT bool isEmptyMesh(const std::vector<int>& tinyInfo) const; + MEDCOUPLING_EXPORT DataArrayInt *computeFetchedNodeIds() const; + MEDCOUPLING_EXPORT DataArrayInt *getNodeIdsInUse(int& nbrOfNodesInUse) const; + MEDCOUPLING_EXPORT void renumberNodesWithOffsetInConn(int offset); + MEDCOUPLING_EXPORT void renumberNodesInConn(const INTERP_KERNEL::HashMap<int,int>& newNodeNumbersO2N); + MEDCOUPLING_EXPORT void renumberNodesInConn(const int *newNodeNumbersO2N); + MEDCOUPLING_EXPORT void fillCellIdsToKeepFromNodeIds(const int *begin, const int *end, bool fullyIn, DataArrayInt *&cellIdsKeptArr) const; + MEDCOUPLING_EXPORT int getNumberOfNodesInCell(int cellId) const; + MEDCOUPLING_EXPORT DataArrayDouble *getBoundingBoxForBBTree(double arcDetEps=1e-12) const; + MEDCOUPLING_EXPORT MEDCouplingFieldDouble *computeDiameterField() const; + // overload of MEDCoupling1GTUMesh + MEDCOUPLING_EXPORT void checkCoherencyOfConnectivity() const; + MEDCOUPLING_EXPORT void allocateCells(int nbOfCells=0); + MEDCOUPLING_EXPORT void insertNextCell(const int *nodalConnOfCellBg, const int *nodalConnOfCellEnd); + public://specific + MEDCOUPLING_EXPORT void setNodalConnectivity(DataArrayInt *nodalConn, DataArrayInt *nodalConnIndex); + MEDCOUPLING_EXPORT DataArrayInt *getNodalConnectivity() const; + MEDCOUPLING_EXPORT DataArrayInt *getNodalConnectivityIndex() const; + MEDCOUPLING_EXPORT MEDCoupling1DGTUMesh *copyWithNodalConnectivityPacked(bool& isShallowCpyOfNodalConnn) const; + MEDCOUPLING_EXPORT bool retrievePackedNodalConnectivity(DataArrayInt *&nodalConn, DataArrayInt *&nodalConnIndx) const; + MEDCOUPLING_EXPORT bool isPacked() const; + MEDCOUPLING_EXPORT static MEDCoupling1DGTUMesh *Merge1DGTUMeshes(const MEDCoupling1DGTUMesh *mesh1, const MEDCoupling1DGTUMesh *mesh2); + MEDCOUPLING_EXPORT static MEDCoupling1DGTUMesh *Merge1DGTUMeshes(std::vector<const MEDCoupling1DGTUMesh *>& a); + MEDCOUPLING_EXPORT static MEDCoupling1DGTUMesh *Merge1DGTUMeshesOnSameCoords(std::vector<const MEDCoupling1DGTUMesh *>& a); + MEDCOUPLING_EXPORT static DataArrayInt *AggregateNodalConnAndShiftNodeIds(const std::vector<const DataArrayInt *>& nodalConns, const std::vector<int>& offsetInNodeIdsPerElt); + MEDCOUPLING_EXPORT static std::vector<int> BuildAPolygonFromParts(const std::vector< std::vector<int> >& parts); + MEDCOUPLING_EXPORT MEDCoupling1DGTUMesh *buildSetInstanceFromThis(int spaceDim) const; + public://serialization + MEDCOUPLING_EXPORT void getTinySerializationInformation(std::vector<double>& tinyInfoD, std::vector<int>& tinyInfo, std::vector<std::string>& littleStrings) const; + MEDCOUPLING_EXPORT void resizeForUnserialization(const std::vector<int>& tinyInfo, DataArrayInt *a1, DataArrayDouble *a2, std::vector<std::string>& littleStrings) const; + MEDCOUPLING_EXPORT void serialize(DataArrayInt *&a1, DataArrayDouble *&a2) const; + MEDCOUPLING_EXPORT void unserialization(const std::vector<double>& tinyInfoD, const std::vector<int>& tinyInfo, const DataArrayInt *a1, DataArrayDouble *a2, + const std::vector<std::string>& littleStrings); + private: + MEDCoupling1DGTUMesh(const std::string& name, const INTERP_KERNEL::CellModel& cm); + MEDCoupling1DGTUMesh(const MEDCoupling1DGTUMesh& other, bool recDeepCpy); + MEDCoupling1DGTUMesh(); + private: + void checkDynamicGeoT2ype() const; + static MEDCoupling1DGTUMesh *Merge1DGTUMeshesLL(std::vector<const MEDCoupling1DGTUMesh *>& a); + private: + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> _conn_indx; + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> _conn; + }; +} + +#endif diff --git a/src/medtool/src/MEDCoupling/MEDCouplingAMRAttribute.cxx b/src/medtool/src/MEDCoupling/MEDCouplingAMRAttribute.cxx new file mode 100644 index 000000000..0a9844669 --- /dev/null +++ b/src/medtool/src/MEDCoupling/MEDCouplingAMRAttribute.cxx @@ -0,0 +1,1537 @@ +// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 +// 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 + +#include "MEDCouplingAMRAttribute.hxx" +#include "MEDCouplingFieldDouble.hxx" +#include "MEDCouplingMemArray.hxx" +#include "MEDCouplingIMesh.hxx" + +#include <sstream> +#include <fstream> + +using namespace ParaMEDMEM; + +DataArrayDoubleCollection *DataArrayDoubleCollection::New(const std::vector< std::pair<std::string,int> >& fieldNames) +{ + return new DataArrayDoubleCollection(fieldNames); +} + +DataArrayDoubleCollection *DataArrayDoubleCollection::deepCpy() const +{ + return new DataArrayDoubleCollection(*this); +} + +void DataArrayDoubleCollection::allocTuples(int nbOfTuples) +{ + std::size_t sz(_arrs.size()); + for(std::size_t i=0;i<sz;i++) + _arrs[i].first->reAlloc(nbOfTuples); +} + +void DataArrayDoubleCollection::dellocTuples() +{ + std::size_t sz(_arrs.size()); + for(std::size_t i=0;i<sz;i++) + _arrs[i].first->reAlloc(0); +} + +void DataArrayDoubleCollection::copyFrom(const DataArrayDoubleCollection& other) +{ + std::size_t sz(_arrs.size()); + if(sz!=other._arrs.size()) + throw INTERP_KERNEL::Exception("DataArrayDoubleCollection::copyFrom : size are not the same !"); + for(std::size_t i=0;i<sz;i++) + { + DataArrayDouble *thisArr(_arrs[i].first); + const DataArrayDouble *otherArr(other._arrs[i].first); + if(!thisArr || !otherArr) + throw INTERP_KERNEL::Exception("DataArrayDoubleCollection::copyFrom : empty DataArray !"); + thisArr->cpyFrom(*otherArr); + } +} + +void DataArrayDoubleCollection::spillInfoOnComponents(const std::vector< std::vector<std::string> >& compNames) +{ + std::size_t sz(_arrs.size()); + if(sz!=compNames.size()) + throw INTERP_KERNEL::Exception("DataArrayDoubleCollection::spillInfoOnComponents : first size of compNames has to be equal to the number of fields defined !"); + for(std::size_t i=0;i<sz;i++) + { + const std::vector<std::string>& names(compNames[i]); + _arrs[i].first->setInfoOnComponents(names); + } +} + +void DataArrayDoubleCollection::spillNatures(const std::vector<NatureOfField>& nfs) +{ + std::size_t sz(_arrs.size()); + if(sz!=nfs.size()) + throw INTERP_KERNEL::Exception("DataArrayDoubleCollection::spillNatures : first size of vector of NatureOfField has to be equal to the number of fields defined !"); + for(std::size_t i=0;i<sz;i++) + { + CheckValidNature(nfs[i]); + _arrs[i].second=nfs[i]; + } +} + +std::vector< std::pair < std::string, std::vector<std::string> > > DataArrayDoubleCollection::getInfoOnComponents() const +{ + std::size_t sz(_arrs.size()); + std::vector< std::pair < std::string, std::vector<std::string> > > ret(sz); + for(std::size_t i=0;i<sz;i++) + { + const DataArrayDouble *elt(_arrs[i].first); + if(!elt) + throw INTERP_KERNEL::Exception("DataArrayDoubleCollection::getInfoOnComponents : empty array !"); + ret[i]=std::pair < std::string, std::vector<std::string> >(elt->getName(),elt->getInfoOnComponents()); + } + return ret; +} + +std::vector<NatureOfField> DataArrayDoubleCollection::getNatures() const +{ + std::size_t sz(_arrs.size()); + std::vector<NatureOfField> ret(sz); + for(std::size_t i=0;i<sz;i++) + ret[i]=_arrs[i].second; + return ret; +} + +std::vector<DataArrayDouble *> DataArrayDoubleCollection::retrieveFields() const +{ + std::size_t sz(_arrs.size()); + std::vector<DataArrayDouble *> ret(sz); + for(std::size_t i=0;i<sz;i++) + { + const DataArrayDouble *tmp(_arrs[i].first); + ret[i]=const_cast<DataArrayDouble *>(tmp); + if(ret[i]) + ret[i]->incrRef(); + } + return ret; +} + +const DataArrayDouble *DataArrayDoubleCollection::getFieldWithName(const std::string& name) const +{ + std::vector<std::string> vec; + for(std::vector< std::pair< MEDCouplingAutoRefCountObjectPtr<DataArrayDouble>, NatureOfField > >::const_iterator it=_arrs.begin();it!=_arrs.end();it++) + { + const DataArrayDouble *obj((*it).first); + if(obj) + { + if(obj->getName()==name) + return obj; + else + vec.push_back(obj->getName()); + } + } + std::ostringstream oss; oss << "DataArrayDoubleCollection::getFieldWithName : fieldName \"" << name << "\" does not exist in this ! Possibilities are :"; + std::copy(vec.begin(),vec.end(),std::ostream_iterator<std::string>(oss," ")); + throw INTERP_KERNEL::Exception(oss.str().c_str()); +} + +DataArrayDouble *DataArrayDoubleCollection::getFieldWithName(const std::string& name) +{ + std::vector<std::string> vec; + for(std::vector< std::pair< MEDCouplingAutoRefCountObjectPtr<DataArrayDouble>, NatureOfField > >::iterator it=_arrs.begin();it!=_arrs.end();it++) + { + DataArrayDouble *obj((*it).first); + if(obj) + { + if(obj->getName()==name) + return obj; + else + vec.push_back(obj->getName()); + } + } + std::ostringstream oss; oss << "DataArrayDoubleCollection::getFieldWithName non const : fieldName \"" << name << "\" does not exist in this ! Possibilities are :"; + std::copy(vec.begin(),vec.end(),std::ostream_iterator<std::string>(oss," ")); + throw INTERP_KERNEL::Exception(oss.str().c_str()); +} + +DataArrayDouble *DataArrayDoubleCollection::at(int pos) +{ + if(pos<0 || pos>=(int)_arrs.size()) + throw INTERP_KERNEL::Exception("DataArrayDoubleCollection::at (non const) : pos must be in [0,nbOfFields) !"); + return _arrs[pos].first; +} + +const DataArrayDouble *DataArrayDoubleCollection::at(int pos) const +{ + if(pos<0 || pos>=(int)_arrs.size()) + throw INTERP_KERNEL::Exception("DataArrayDoubleCollection::at : pos must be in [0,nbOfFields) !"); + return _arrs[pos].first; +} + +int DataArrayDoubleCollection::size() const +{ + return (int)_arrs.size(); +} + +void DataArrayDoubleCollection::SynchronizeFineToCoarse(int ghostLev, const MEDCouplingCartesianAMRMeshGen *fatherOfFineMesh, int patchId, const DataArrayDoubleCollection *fine, DataArrayDoubleCollection *coarse) +{ + if(!fine || !coarse) + throw INTERP_KERNEL::Exception("DataArrayDoubleCollection::SynchronizeFineToCoarse : the input DataArrayDouble collections must be non NULL !"); + std::size_t sz(coarse->_arrs.size()); + if(fine->_arrs.size()!=sz) + throw INTERP_KERNEL::Exception("DataArrayDoubleCollection::SynchronizeFineToCoarse : the input DataArrayDouble collection must have the same size !"); + for(std::size_t i=0;i<sz;i++) + { + CheckSameNatures(fine->_arrs[i].second,coarse->_arrs[i].second); + fatherOfFineMesh->fillCellFieldComingFromPatchGhost(patchId,fine->_arrs[i].first,coarse->_arrs[i].first,ghostLev,IsConservativeNature(coarse->_arrs[i].second)); + } +} + +void DataArrayDoubleCollection::SynchronizeCoarseToFine(int ghostLev, const MEDCouplingCartesianAMRMeshGen *fatherOfFineMesh, int patchId, const DataArrayDoubleCollection *coarse, DataArrayDoubleCollection *fine) +{ + if(!fine || !coarse) + throw INTERP_KERNEL::Exception("DataArrayDoubleCollection::SynchronizeCoarseToFine : the input DataArrayDouble collections must be non NULL !"); + std::size_t sz(coarse->_arrs.size()); + if(fine->_arrs.size()!=sz) + throw INTERP_KERNEL::Exception("DataArrayDoubleCollection::SynchronizeCoarseToFine : the input DataArrayDouble collection must have the same size !"); + for(std::size_t i=0;i<sz;i++) + { + CheckSameNatures(fine->_arrs[i].second,coarse->_arrs[i].second); + fatherOfFineMesh->fillCellFieldOnPatchGhost(patchId,coarse->_arrs[i].first,fine->_arrs[i].first,ghostLev,IsConservativeNature(coarse->_arrs[i].second)); + } +} + +void DataArrayDoubleCollection::SynchronizeFineEachOther(int patchId, int ghostLev, const MEDCouplingCartesianAMRMeshGen *fatherOfFineMesh, const std::vector<const MEDCouplingCartesianAMRMeshGen *>& children, const std::vector<DataArrayDoubleCollection *>& fieldsOnFine) +{ + if(!fatherOfFineMesh) + throw INTERP_KERNEL::Exception("DataArrayDoubleCollection::SynchronizeFineEachOther : father is NULL !"); + std::size_t sz(children.size()); + if(fieldsOnFine.size()!=sz) + throw INTERP_KERNEL::Exception("DataArrayDoubleCollection::SynchronizeFineEachOther : sizes of vectors mismatch !"); + if(sz<=1) + return ; + std::size_t nbOfCall(fieldsOnFine[0]->_arrs.size()); + for(std::size_t i=0;i<sz;i++) + if(fatherOfFineMesh->getPatchIdFromChildMesh(children[i])!=(int)i) + throw INTERP_KERNEL::Exception("DataArrayDoubleCollection::SynchronizeFineEachOther : internal error !"); + for(std::size_t i=1;i<sz;i++) + if(nbOfCall!=fieldsOnFine[i]->_arrs.size()) + throw INTERP_KERNEL::Exception("DataArrayDoubleCollection::SynchronizeFineEachOther : the collection of DataArrayDouble must have all the same size !"); + for(std::size_t i=0;i<nbOfCall;i++) + { + std::vector<const DataArrayDouble *> arrs(sz); + for(std::size_t j=0;j<sz;j++) + arrs[j]=fieldsOnFine[j]->_arrs[i].first; + fatherOfFineMesh->fillCellFieldOnPatchOnlyGhostAdv(patchId,ghostLev,arrs); + } +} + +/*! + * This method updates \a p1dac ghost zone parts using \a p2dac (which is really const). \a p2 is in the neighborhood of \a p1 (which size is defined by \a ghostLev). + */ +void DataArrayDoubleCollection::SynchronizeGhostZoneOfOneUsingTwo(int ghostLev, const MEDCouplingCartesianAMRPatch *p1, const DataArrayDoubleCollection *p1dac, const MEDCouplingCartesianAMRPatch *p2, const DataArrayDoubleCollection *p2dac) +{ + if(!p1 || !p1dac || !p2 || !p2dac) + throw INTERP_KERNEL::Exception("DataArrayDoubleCollection::SynchronizeGhostZoneOfOneUsingTwo : input pointer must be not NULL !"); + std::size_t sz(p1dac->_arrs.size()); + if(p2dac->_arrs.size()!=sz) + throw INTERP_KERNEL::Exception("DataArrayDoubleCollection::SynchronizeGhostZoneOfOneUsingTwo : size of DataArrayDouble Collection must be the same !"); + for(std::size_t i=0;i<sz;i++) + { + const DataArrayDouble *zeArrWhichGhostsWillBeUpdated(p1dac->_arrs[i].first); + DataArrayDoubleCollection::CheckSameNatures(p1dac->_arrs[i].second,p2dac->_arrs[i].second); + bool isConservative(DataArrayDoubleCollection::IsConservativeNature(p1dac->_arrs[i].second)); + MEDCouplingCartesianAMRPatch::UpdateNeighborsOfOneWithTwoMixedLev(ghostLev,p1,p2,const_cast<DataArrayDouble *>(zeArrWhichGhostsWillBeUpdated),p2dac->_arrs[i].first,isConservative); + } +} + +void DataArrayDoubleCollection::SynchronizeCoarseToFineOnlyInGhostZone(int ghostLev, const MEDCouplingCartesianAMRMeshGen *fatherOfFineMesh, int patchId, const DataArrayDoubleCollection *coarse, DataArrayDoubleCollection *fine) +{ + if(!fine || !coarse) + throw INTERP_KERNEL::Exception("DataArrayDoubleCollection::SynchronizeCoarseToFineOnlyInGhostZone : the input DataArrayDouble collections must be non NULL !"); + std::size_t sz(coarse->_arrs.size()); + if(fine->_arrs.size()!=sz) + throw INTERP_KERNEL::Exception("DataArrayDoubleCollection::SynchronizeCoarseToFineOnlyInGhostZone : the input DataArrayDouble collection must have the same size !"); + for(std::size_t i=0;i<sz;i++) + fatherOfFineMesh->fillCellFieldOnPatchOnlyOnGhostZone(patchId,coarse->_arrs[i].first,fine->_arrs[i].first,ghostLev); +} + +void DataArrayDoubleCollection::synchronizeMyGhostZoneUsing(int ghostLev, const DataArrayDoubleCollection& other, const MEDCouplingCartesianAMRPatch *thisp, const MEDCouplingCartesianAMRPatch *otherp, const MEDCouplingCartesianAMRMeshGen *father) const +{ + DataArrayDoubleCollection *thisNC(const_cast<DataArrayDoubleCollection *>(this)); + std::size_t sz(_arrs.size()); + if(other._arrs.size()!=sz) + throw INTERP_KERNEL::Exception("DataArrayDoubleCollection::synchronizeMyGhostZoneUsing : sizes of collections must match !"); + for(std::size_t i=0;i<sz;i++) + father->fillCellFieldOnPatchOnlyOnGhostZoneWith(ghostLev,thisp,otherp,thisNC->_arrs[i].first,other._arrs[i].first); +} + +void DataArrayDoubleCollection::synchronizeMyGhostZoneUsingExt(int ghostLev, const DataArrayDoubleCollection& other, const MEDCouplingCartesianAMRPatch *thisp, const MEDCouplingCartesianAMRPatch *otherp) const +{ + DataArrayDoubleCollection *thisNC(const_cast<DataArrayDoubleCollection *>(this)); + std::size_t sz(_arrs.size()); + if(other._arrs.size()!=sz) + throw INTERP_KERNEL::Exception("DataArrayDoubleCollection::synchronizeMyGhostZoneUsingExt : sizes of collections must match !"); + for(std::size_t i=0;i<sz;i++) + MEDCouplingCartesianAMRPatch::UpdateNeighborsOfOneWithTwoExt(ghostLev,thisp,otherp,thisNC->_arrs[i].first,other._arrs[i].first); +} + +DataArrayDoubleCollection::DataArrayDoubleCollection(const std::vector< std::pair<std::string,int> >& fieldNames):_arrs(fieldNames.size()) +{ + std::size_t sz(fieldNames.size()); + std::vector<std::string> names(sz); + for(std::size_t i=0;i<sz;i++) + { + const std::pair<std::string,int>& info(fieldNames[i]); + if(info.second<=0) + { + std::ostringstream oss; oss << "DataArrayDoubleCollection constructor : At pos #" << i << " the array with name \"" << info.first << "\" as a number of components equal to " << info.second; + oss << " It has to be >=1 !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + _arrs[i].first=DataArrayDouble::New(); + _arrs[i].first->alloc(0,info.second); + _arrs[i].first->setName(info.first); + names[i]=info.second; + _arrs[i].second=ConservativeVolumic; + } + CheckDiscriminantNames(names); +} + +DataArrayDoubleCollection::DataArrayDoubleCollection(const DataArrayDoubleCollection& other):RefCountObject(other),_arrs(other._arrs.size()) +{ + std::size_t sz(other._arrs.size()); + for(std::size_t i=0;i<sz;i++) + { + _arrs[i].second=other._arrs[i].second; + const DataArrayDouble *da(other._arrs[i].first); + if(da) + _arrs[i].first=da->deepCpy(); + } +} + +std::size_t DataArrayDoubleCollection::getHeapMemorySizeWithoutChildren() const +{ + std::size_t ret(sizeof(DataArrayDoubleCollection)); + ret+=_arrs.capacity()*sizeof(MEDCouplingAutoRefCountObjectPtr<DataArrayDouble>); + return ret; +} + +std::vector<const BigMemoryObject *> DataArrayDoubleCollection::getDirectChildrenWithNull() const +{ + std::vector<const BigMemoryObject *> ret; + for(std::vector< std::pair< MEDCouplingAutoRefCountObjectPtr<DataArrayDouble>, NatureOfField > >::const_iterator it=_arrs.begin();it!=_arrs.end();it++) + ret.push_back((const DataArrayDouble *)(*it).first); + return ret; +} + +void DataArrayDoubleCollection::updateTime() const +{ + for(std::vector< std::pair< MEDCouplingAutoRefCountObjectPtr<DataArrayDouble>, NatureOfField > >::const_iterator it=_arrs.begin();it!=_arrs.end();it++) + { + const DataArrayDouble *pt((*it).first); + if(pt) + updateTimeWith(*pt); + } +} + +void DataArrayDoubleCollection::CheckDiscriminantNames(const std::vector<std::string>& names) +{ + std::set<std::string> s(names.begin(),names.end()); + if(s.size()!=names.size()) + throw INTERP_KERNEL::Exception("DataArrayDoubleCollection::CheckDiscriminantNames : The names of fields must be different each other ! It is not the case !"); +} + +bool DataArrayDoubleCollection::IsConservativeNature(NatureOfField n) +{ + CheckValidNature(n); + return n==RevIntegral || n==IntegralGlobConstraint; +} + +void DataArrayDoubleCollection::CheckSameNatures(NatureOfField n1, NatureOfField n2) +{ + CheckValidNature(n1); + CheckValidNature(n2); + if(n1!=n2) + throw INTERP_KERNEL::Exception("DataArrayDoubleCollection::CheckSameNatures : natures are not the same !"); +} + +void DataArrayDoubleCollection::CheckValidNature(NatureOfField n) +{ + if(n!=ConservativeVolumic && n!=Integral && n!=IntegralGlobConstraint && n!=RevIntegral) + throw INTERP_KERNEL::Exception("DataArrayDoubleCollection::CheckValidNature : unrecognized nature !"); +} + +MEDCouplingGridCollection *MEDCouplingGridCollection::New(const std::vector<const MEDCouplingCartesianAMRMeshGen *>& ms, const std::vector< std::pair<std::string,int> >& fieldNames) +{ + return new MEDCouplingGridCollection(ms,fieldNames); +} + +MEDCouplingGridCollection *MEDCouplingGridCollection::deepCpy(const MEDCouplingCartesianAMRMeshGen *newGf, const MEDCouplingCartesianAMRMeshGen *oldGf) const +{ + return new MEDCouplingGridCollection(*this,newGf,oldGf); +} + +void MEDCouplingGridCollection::alloc(int ghostLev) +{ + for(std::vector< std::pair<const MEDCouplingCartesianAMRMeshGen *,MEDCouplingAutoRefCountObjectPtr<DataArrayDoubleCollection> > >::iterator it=_map_of_dadc.begin();it!=_map_of_dadc.end();it++) + { + int nbTuples((*it).first->getNumberOfCellsAtCurrentLevelGhost(ghostLev)); + DataArrayDoubleCollection *dadc((*it).second); + if(dadc) + dadc->allocTuples(nbTuples); + else + throw INTERP_KERNEL::Exception("MEDCouplingGridCollection::alloc : internal error !"); + } +} + +void MEDCouplingGridCollection::dealloc() +{ + for(std::vector< std::pair<const MEDCouplingCartesianAMRMeshGen *,MEDCouplingAutoRefCountObjectPtr<DataArrayDoubleCollection> > >::iterator it=_map_of_dadc.begin();it!=_map_of_dadc.end();it++) + { + DataArrayDoubleCollection *dadc((*it).second); + if(dadc) + dadc->dellocTuples(); + else + throw INTERP_KERNEL::Exception("MEDCouplingGridCollection::dealloc : internal error !"); + } +} + +void MEDCouplingGridCollection::spillInfoOnComponents(const std::vector< std::vector<std::string> >& compNames) +{ + for(std::vector< std::pair<const MEDCouplingCartesianAMRMeshGen *,MEDCouplingAutoRefCountObjectPtr<DataArrayDoubleCollection> > >::iterator it=_map_of_dadc.begin();it!=_map_of_dadc.end();it++) + (*it).second->spillInfoOnComponents(compNames); +} + +void MEDCouplingGridCollection::spillNatures(const std::vector<NatureOfField>& nfs) +{ + for(std::vector< std::pair<const MEDCouplingCartesianAMRMeshGen *,MEDCouplingAutoRefCountObjectPtr<DataArrayDoubleCollection> > >::iterator it=_map_of_dadc.begin();it!=_map_of_dadc.end();it++) + (*it).second->spillNatures(nfs); +} + +std::vector< std::pair<std::string, std::vector<std::string> > > MEDCouplingGridCollection::getInfoOnComponents() const +{ + if(_map_of_dadc.empty()) + throw INTERP_KERNEL::Exception("MEDCouplingGridCollection::getInfoOnComponents : empty map !"); + const DataArrayDoubleCollection *elt(_map_of_dadc[0].second); + if(!elt) + throw INTERP_KERNEL::Exception("MEDCouplingGridCollection::getInfoOnComponents : null pointer !"); + return elt->getInfoOnComponents(); +} + +std::vector<NatureOfField> MEDCouplingGridCollection::getNatures() const +{ + if(_map_of_dadc.empty()) + throw INTERP_KERNEL::Exception("MEDCouplingGridCollection::getNatures : empty map !"); + const DataArrayDoubleCollection *elt(_map_of_dadc[0].second); + if(!elt) + throw INTERP_KERNEL::Exception("MEDCouplingGridCollection::getNatures : null pointer !"); + return elt->getNatures(); +} + +bool MEDCouplingGridCollection::presenceOf(const MEDCouplingCartesianAMRMeshGen *m, int& pos) const +{ + int ret(0); + for(std::vector< std::pair<const MEDCouplingCartesianAMRMeshGen *,MEDCouplingAutoRefCountObjectPtr<DataArrayDoubleCollection> > >::const_iterator it=_map_of_dadc.begin();it!=_map_of_dadc.end();it++,ret++) + { + if((*it).first==m) + { + pos=ret; + return true; + } + } + return false; +} + +const DataArrayDoubleCollection& MEDCouplingGridCollection::getFieldsAt(int pos) const +{ + if(pos<0 || pos>(int)_map_of_dadc.size()) + throw INTERP_KERNEL::Exception("MEDCouplingGridCollection::getFieldsAt : invalid pos given in input ! Must be in [0,size) !"); + return *_map_of_dadc[pos].second; +} + +DataArrayDoubleCollection& MEDCouplingGridCollection::getFieldsAt(int pos) +{ + if(pos<0 || pos>(int)_map_of_dadc.size()) + throw INTERP_KERNEL::Exception("MEDCouplingGridCollection::getFieldsAt (non const) : invalid pos given in input ! Must be in [0,size) !"); + return *_map_of_dadc[pos].second; +} + +/*! + * This method copies for all grids intersecting themselves (between \a this and \a other), the values of fields of \a other to the intersecting + * part of fields of \a this. The fields are expected to be the same between \a other and \a this. + * This methods makes the hypothesis that \a this and \a other share two god father that are compatible each other that is to say with the same cell grid structure. + */ +void MEDCouplingGridCollection::copyOverlappedZoneFrom(int ghostLev, const MEDCouplingGridCollection& other) +{ + for(std::vector< std::pair<const MEDCouplingCartesianAMRMeshGen *,MEDCouplingAutoRefCountObjectPtr<DataArrayDoubleCollection> > >::iterator it=_map_of_dadc.begin();it!=_map_of_dadc.end();it++) + { + std::vector<int> deltaThis,deltaOther; + std::vector< std::pair<int,int> > rgThis((*it).first->positionRelativeToGodFather(deltaThis)); + std::vector<int> thisSt((*it).first->getImageMesh()->getCellGridStructure()); + std::transform(thisSt.begin(),thisSt.end(),thisSt.begin(),std::bind2nd(std::plus<int>(),2*ghostLev)); + for(std::vector< std::pair<const MEDCouplingCartesianAMRMeshGen *,MEDCouplingAutoRefCountObjectPtr<DataArrayDoubleCollection> > >::const_iterator it2=other._map_of_dadc.begin();it2!=other._map_of_dadc.end();it2++) + { + std::vector< std::pair<int,int> > rgOther((*it2).first->positionRelativeToGodFather(deltaOther)); + if(MEDCouplingStructuredMesh::AreRangesIntersect(rgThis,rgOther)) + { + std::vector< std::pair<int,int> > isect(MEDCouplingStructuredMesh::IntersectRanges(rgThis,rgOther)); + std::vector< std::pair<int,int> > pThis,pOther; + MEDCouplingStructuredMesh::ChangeReferenceFromGlobalOfCompactFrmt(rgThis,isect,pThis,true); + MEDCouplingStructuredMesh::ChangeReferenceFromGlobalOfCompactFrmt(rgOther,isect,pOther,true); + std::vector<int> otherSt((*it2).first->getImageMesh()->getCellGridStructure()); + MEDCouplingStructuredMesh::ApplyGhostOnCompactFrmt(pThis,ghostLev); + MEDCouplingStructuredMesh::ApplyGhostOnCompactFrmt(pOther,ghostLev); + std::transform(otherSt.begin(),otherSt.end(),otherSt.begin(),std::bind2nd(std::plus<int>(),2*ghostLev)); + int sz((*it2).second->size()); + for(int i=0;i<sz;i++) + { + const DataArrayDouble *otherArr((*it2).second->at(i)); + DataArrayDouble *thisArr((*it).second->at(i)); + MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> partOfOther(MEDCouplingStructuredMesh::ExtractFieldOfDoubleFrom(otherSt,otherArr,pOther)); + MEDCouplingStructuredMesh::AssignPartOfFieldOfDoubleUsing(thisSt,thisArr,pThis,partOfOther); + } + } + } + } +} + +void MEDCouplingGridCollection::SynchronizeFineToCoarse(int ghostLev, const MEDCouplingGridCollection *fine, const MEDCouplingGridCollection *coarse) +{ + if(!fine || !coarse) + throw INTERP_KERNEL::Exception("MEDCouplingGridCollection::SynchronizeFineToCoarse : one or more input pointer is NULL !"); + const std::vector< std::pair<const MEDCouplingCartesianAMRMeshGen *,MEDCouplingAutoRefCountObjectPtr<DataArrayDoubleCollection> > >& mf(fine->_map_of_dadc); + const std::vector< std::pair<const MEDCouplingCartesianAMRMeshGen *,MEDCouplingAutoRefCountObjectPtr<DataArrayDoubleCollection> > >& mc(coarse->_map_of_dadc); + for(std::vector< std::pair<const MEDCouplingCartesianAMRMeshGen *,MEDCouplingAutoRefCountObjectPtr<DataArrayDoubleCollection> > >::const_iterator it=mf.begin();it!=mf.end();it++) + { + const MEDCouplingCartesianAMRMeshGen *fineMesh((*it).first); + const MEDCouplingCartesianAMRMeshGen *fatherOfFineMesh(fineMesh->getFather()); + bool found(false); + for(std::vector< std::pair<const MEDCouplingCartesianAMRMeshGen *,MEDCouplingAutoRefCountObjectPtr<DataArrayDoubleCollection> > >::const_iterator it0=mc.begin();it0!=mc.end() && !found;it0++) + { + if((*it0).first==fatherOfFineMesh) + { + found=true; + int patchId(fatherOfFineMesh->getPatchIdFromChildMesh(fineMesh)); + const DataArrayDoubleCollection *coarseDaCol((*it0).second); + DataArrayDoubleCollection *coarseModified(const_cast<DataArrayDoubleCollection *>(coarseDaCol));//coarse values in DataArrayDouble will be altered + DataArrayDoubleCollection::SynchronizeFineToCoarse(ghostLev,fatherOfFineMesh,patchId,(*it).second,coarseModified); + } + } + if(!found) + throw INTERP_KERNEL::Exception("MEDCouplingGridCollection::SynchronizeFineToCoarse : a fine mesh is orphan regarding given coarse meshes !"); + } +} + +void MEDCouplingGridCollection::SynchronizeCoarseToFine(int ghostLev, const MEDCouplingGridCollection *coarse, const MEDCouplingGridCollection *fine) +{ + if(!fine || !coarse) + throw INTERP_KERNEL::Exception("MEDCouplingGridCollection::SynchronizeCoarseToFine : one or more input pointer is NULL !"); + const std::vector< std::pair<const MEDCouplingCartesianAMRMeshGen *,MEDCouplingAutoRefCountObjectPtr<DataArrayDoubleCollection> > >& mf(fine->_map_of_dadc); + const std::vector< std::pair<const MEDCouplingCartesianAMRMeshGen *,MEDCouplingAutoRefCountObjectPtr<DataArrayDoubleCollection> > >& mc(coarse->_map_of_dadc); + for(std::vector< std::pair<const MEDCouplingCartesianAMRMeshGen *,MEDCouplingAutoRefCountObjectPtr<DataArrayDoubleCollection> > >::const_iterator it=mf.begin();it!=mf.end();it++) + { + const MEDCouplingCartesianAMRMeshGen *fineMesh((*it).first); + const MEDCouplingCartesianAMRMeshGen *fatherOfFineMesh(fineMesh->getFather()); + bool found(false); + for(std::vector< std::pair<const MEDCouplingCartesianAMRMeshGen *,MEDCouplingAutoRefCountObjectPtr<DataArrayDoubleCollection> > >::const_iterator it0=mc.begin();it0!=mc.end() && !found;it0++) + { + if((*it0).first==fatherOfFineMesh) + { + found=true; + int patchId(fatherOfFineMesh->getPatchIdFromChildMesh(fineMesh)); + const DataArrayDoubleCollection *fineDaCol((*it).second); + DataArrayDoubleCollection *fineModified(const_cast<DataArrayDoubleCollection *>(fineDaCol));//fine values in DataArrayDouble will be altered + DataArrayDoubleCollection::SynchronizeCoarseToFine(ghostLev,fatherOfFineMesh,patchId,(*it0).second,fineModified); + } + } + if(!found) + throw INTERP_KERNEL::Exception("MEDCouplingGridCollection::SynchronizeCoarseToFine : a fine mesh is orphan regarding given coarse meshes !"); + } +} + +/*! + * All the pairs in \a ps must share the same father. If not call synchronizeFineEachOtherExt instead. + * + * \sa synchronizeFineEachOtherExt + */ +void MEDCouplingGridCollection::synchronizeFineEachOther(int ghostLev, const std::vector< std::pair<const MEDCouplingCartesianAMRPatch *,const MEDCouplingCartesianAMRPatch *> >& ps) const +{ + for(std::vector< std::pair<const MEDCouplingCartesianAMRPatch *,const MEDCouplingCartesianAMRPatch *> >::const_iterator it=ps.begin();it!=ps.end();it++) + { + int p1,p2; + if(!presenceOf((*it).first->getMesh(),p1)) + throw INTERP_KERNEL::Exception("MEDCouplingGridCollection::synchronizeFineEachOther : internal error #1 !"); + if(!presenceOf((*it).second->getMesh(),p2)) + throw INTERP_KERNEL::Exception("MEDCouplingGridCollection::synchronizeFineEachOther : internal error #2 !"); + const DataArrayDoubleCollection& col1(getFieldsAt(p1)); + const DataArrayDoubleCollection& col2(getFieldsAt(p2)); + col1.synchronizeMyGhostZoneUsing(ghostLev,col2,(*it).first,(*it).second,(*it).first->getMesh()->getFather()); + } +} + +/*! + * This method is a generalization of synchronizeFineEachOther because elements in pairs are \b not sharing the same father but are neighbors nevertheless. + * + * \sa synchronizeFineEachOther + */ +void MEDCouplingGridCollection::synchronizeFineEachOtherExt(int ghostLev, const std::vector< std::pair<const MEDCouplingCartesianAMRPatch *,const MEDCouplingCartesianAMRPatch *> >& ps) const +{ + for(std::vector< std::pair<const MEDCouplingCartesianAMRPatch *,const MEDCouplingCartesianAMRPatch *> >::const_iterator it=ps.begin();it!=ps.end();it++) + { + int p1,p2; + if(!presenceOf((*it).first->getMesh(),p1)) + throw INTERP_KERNEL::Exception("MEDCouplingGridCollection::synchronizeFineEachOtherExt : internal error #1 !"); + if(!presenceOf((*it).second->getMesh(),p2)) + throw INTERP_KERNEL::Exception("MEDCouplingGridCollection::synchronizeFineEachOtherExt : internal error #2 !"); + const DataArrayDoubleCollection& col1(getFieldsAt(p1)); + const DataArrayDoubleCollection& col2(getFieldsAt(p2)); + col1.synchronizeMyGhostZoneUsingExt(ghostLev,col2,(*it).first,(*it).second); + } +} + +/*! + * The pairs returned share the same direct father. The number of returned elements must be even. + */ +std::vector< std::pair<const MEDCouplingCartesianAMRPatch *,const MEDCouplingCartesianAMRPatch *> > MEDCouplingGridCollection::findNeighbors(int ghostLev) const +{ + std::vector< std::pair<const MEDCouplingCartesianAMRPatch *,const MEDCouplingCartesianAMRPatch *> > ret; + std::map<const MEDCouplingCartesianAMRMeshGen *,std::vector< const MEDCouplingCartesianAMRMeshGen * > > m; + for(std::vector< std::pair<const MEDCouplingCartesianAMRMeshGen *,MEDCouplingAutoRefCountObjectPtr<DataArrayDoubleCollection> > >::const_iterator it=_map_of_dadc.begin();it!=_map_of_dadc.end();it++) + { + const MEDCouplingCartesianAMRMeshGen *fineMesh((*it).first); + const MEDCouplingCartesianAMRMeshGen *fatherOfFineMesh(fineMesh->getFather()); + m[fatherOfFineMesh].push_back(fineMesh); + } + for(std::map<const MEDCouplingCartesianAMRMeshGen *,std::vector< const MEDCouplingCartesianAMRMeshGen * > >::const_iterator it0=m.begin();it0!=m.end();it0++) + { + for(std::vector<const MEDCouplingCartesianAMRMeshGen *>::const_iterator it1=(*it0).second.begin();it1!=(*it0).second.end();it1++) + { + int patchId((*it0).first->getPatchIdFromChildMesh(*it1)); + std::vector<int> neighs((*it0).first->getPatchIdsInTheNeighborhoodOf(patchId,ghostLev)); + const MEDCouplingCartesianAMRPatch *pRef((*it0).first->getPatch(patchId)); + for(std::vector<int>::const_iterator it2=neighs.begin();it2!=neighs.end();it2++) + { + const MEDCouplingCartesianAMRPatch *pLoc((*it0).first->getPatch(*it2)); + ret.push_back(std::pair<const MEDCouplingCartesianAMRPatch *,const MEDCouplingCartesianAMRPatch *>(pRef,pLoc)); + } + } + } + if(ret.size()%2!=0) + throw INTERP_KERNEL::Exception("MEDCouplingGridCollection::findNeighbors : something is wrong ! The number of neighbor pairs must be %2 ==0 !"); + return ret; +} + +void MEDCouplingGridCollection::SynchronizeCoarseToFineOnlyInGhostZone(int ghostLev, const MEDCouplingGridCollection *coarse, const MEDCouplingGridCollection *fine) +{ + if(!fine || !coarse) + throw INTERP_KERNEL::Exception("MEDCouplingGridCollection::SynchronizeCoarseToFineOnlyInGhostZone : one or more input pointer is NULL !"); + const std::vector< std::pair<const MEDCouplingCartesianAMRMeshGen *,MEDCouplingAutoRefCountObjectPtr<DataArrayDoubleCollection> > >& mf(fine->_map_of_dadc); + const std::vector< std::pair<const MEDCouplingCartesianAMRMeshGen *,MEDCouplingAutoRefCountObjectPtr<DataArrayDoubleCollection> > >& mc(coarse->_map_of_dadc); + for(std::vector< std::pair<const MEDCouplingCartesianAMRMeshGen *,MEDCouplingAutoRefCountObjectPtr<DataArrayDoubleCollection> > >::const_iterator it=mf.begin();it!=mf.end();it++) + { + const MEDCouplingCartesianAMRMeshGen *fineMesh((*it).first); + const MEDCouplingCartesianAMRMeshGen *fatherOfFineMesh(fineMesh->getFather()); + bool found(false); + for(std::vector< std::pair<const MEDCouplingCartesianAMRMeshGen *,MEDCouplingAutoRefCountObjectPtr<DataArrayDoubleCollection> > >::const_iterator it0=mc.begin();it0!=mc.end() && !found;it0++) + { + if((*it0).first==fatherOfFineMesh) + { + found=true; + int patchId(fatherOfFineMesh->getPatchIdFromChildMesh(fineMesh)); + const DataArrayDoubleCollection *fineDaCol((*it).second); + DataArrayDoubleCollection *fineModified(const_cast<DataArrayDoubleCollection *>(fineDaCol));//fine values in DataArrayDouble will be altered + DataArrayDoubleCollection::SynchronizeCoarseToFineOnlyInGhostZone(ghostLev,fatherOfFineMesh,patchId,(*it0).second,fineModified); + } + } + if(!found) + throw INTERP_KERNEL::Exception("MEDCouplingGridCollection::SynchronizeCoarseToFineOnlyInGhostZone : a fine mesh is orphan regarding given coarse meshes !"); + } +} + +void MEDCouplingGridCollection::fillIfInTheProgenyOf(const std::string& fieldName, const MEDCouplingCartesianAMRMeshGen *head, std::vector<const DataArrayDouble *>& recurseArrs) const +{ + for(std::vector< std::pair<const MEDCouplingCartesianAMRMeshGen *,MEDCouplingAutoRefCountObjectPtr<DataArrayDoubleCollection> > >::const_iterator it=_map_of_dadc.begin();it!=_map_of_dadc.end();it++) + { + const MEDCouplingCartesianAMRMeshGen *a((*it).first); + if(head==a || head->isObjectInTheProgeny(a)) + { + const DataArrayDoubleCollection *gc((*it).second); + recurseArrs.push_back(gc->getFieldWithName(fieldName)); + } + } +} + +MEDCouplingGridCollection::MEDCouplingGridCollection(const std::vector<const MEDCouplingCartesianAMRMeshGen *>& ms, const std::vector< std::pair<std::string,int> >& fieldNames):_map_of_dadc(ms.size()) +{ + std::size_t sz(ms.size()); + for(std::size_t i=0;i<sz;i++) + { + if(!ms[i]) + throw INTERP_KERNEL::Exception("MEDCouplingGridCollection constructor : presence of NULL MEDCouplingCartesianAMRMeshGen instance !"); + _map_of_dadc[i].first=ms[i]; + _map_of_dadc[i].second=DataArrayDoubleCollection::New(fieldNames); + } +} + +MEDCouplingGridCollection::MEDCouplingGridCollection(const MEDCouplingGridCollection& other, const MEDCouplingCartesianAMRMeshGen *newGf, const MEDCouplingCartesianAMRMeshGen *oldGf):RefCountObject(other),_map_of_dadc(other._map_of_dadc.size()) +{ + std::size_t sz(other._map_of_dadc.size()); + for(std::size_t i=0;i<sz;i++) + { + std::vector<int> pos(other._map_of_dadc[i].first->getPositionRelativeTo(oldGf)); + _map_of_dadc[i].first=newGf->getMeshAtPosition(pos); + const DataArrayDoubleCollection *dac(other._map_of_dadc[i].second); + if(dac) + _map_of_dadc[i].second=dac->deepCpy(); + } +} + +std::size_t MEDCouplingGridCollection::getHeapMemorySizeWithoutChildren() const +{ + std::size_t ret(sizeof(MEDCouplingGridCollection)); + ret+=_map_of_dadc.capacity()*sizeof(std::pair<const MEDCouplingCartesianAMRMeshGen *,MEDCouplingAutoRefCountObjectPtr<DataArrayDoubleCollection> >); + return ret; +} + +std::vector<const BigMemoryObject *> MEDCouplingGridCollection::getDirectChildrenWithNull() const +{ + std::vector<const BigMemoryObject *> ret; + for(std::vector< std::pair<const MEDCouplingCartesianAMRMeshGen *,MEDCouplingAutoRefCountObjectPtr<DataArrayDoubleCollection> > >::const_iterator it=_map_of_dadc.begin();it!=_map_of_dadc.end();it++) + ret.push_back((const DataArrayDoubleCollection *)(*it).second); + return ret; +} + +void MEDCouplingGridCollection::updateTime() const +{ + for(std::vector< std::pair<const MEDCouplingCartesianAMRMeshGen *,MEDCouplingAutoRefCountObjectPtr<DataArrayDoubleCollection> > >::const_iterator it=_map_of_dadc.begin();it!=_map_of_dadc.end();it++) + { + const MEDCouplingCartesianAMRMeshGen *a((*it).first); + if(a) + updateTimeWith(*a); + const DataArrayDoubleCollection *b((*it).second); + if(b) + updateTimeWith(*b); + } +} + +MEDCouplingCartesianAMRMesh *MEDCouplingDataForGodFather::getMyGodFather() +{ + return _gf; +} + +const MEDCouplingCartesianAMRMesh *MEDCouplingDataForGodFather::getMyGodFather() const +{ + return _gf; +} + +MEDCouplingDataForGodFather::MEDCouplingDataForGodFather(MEDCouplingCartesianAMRMesh *gf):_gf(gf),_tlc(gf) +{ + if(!gf) + throw INTERP_KERNEL::Exception("MEDCouplingDataForGodFather constructor : A data has to be attached to a AMR Mesh instance !"); + gf->incrRef(); +} + +void MEDCouplingDataForGodFather::checkGodFatherFrozen() const +{ + _tlc.checkConst(); +} + +bool MEDCouplingDataForGodFather::changeGodFather(MEDCouplingCartesianAMRMesh *gf) +{ + bool ret(_tlc.keepTrackOfNewTL(gf)); + if(ret) + { + _gf=gf; + if(gf) + gf->incrRef(); + } + return ret; +} + +MEDCouplingDataForGodFather::MEDCouplingDataForGodFather(const MEDCouplingDataForGodFather& other, bool deepCpyGF):RefCountObject(other),_gf(other._gf),_tlc(other._gf) +{ + other._tlc.checkConst(); + if(deepCpyGF) + { + const MEDCouplingCartesianAMRMesh *gf(other._gf); + if(gf) + _gf=gf->deepCpy(0); + _tlc.keepTrackOfNewTL(_gf); + } +} + +/*! + * This method creates, attach to a main AMR mesh \a gf ( called god father :-) ) and returns a data linked to \a gf ready for the computation. + */ +MEDCouplingAMRAttribute *MEDCouplingAMRAttribute::New(MEDCouplingCartesianAMRMesh *gf, const std::vector< std::pair<std::string,int> >& fieldNames, int ghostLev) +{ + return new MEDCouplingAMRAttribute(gf,fieldNames,ghostLev); +} + +MEDCouplingAMRAttribute *MEDCouplingAMRAttribute::New(MEDCouplingCartesianAMRMesh *gf, const std::vector< std::pair<std::string, std::vector<std::string> > >& fieldNames, int ghostLev) +{ + std::size_t sz(fieldNames.size()); + std::vector< std::pair<std::string,int> > fieldNames2(sz); + std::vector< std::vector<std::string> > compNames(sz); + for(std::size_t i=0;i<sz;i++) + { + fieldNames2[i].first=fieldNames[i].first; + fieldNames2[i].second=(int)fieldNames[i].second.size(); + compNames[i]=fieldNames[i].second; + } + MEDCouplingAutoRefCountObjectPtr<MEDCouplingAMRAttribute> ret(New(gf,fieldNames2,ghostLev)); + ret->spillInfoOnComponents(compNames); + return ret.retn(); +} + +/*! + * Assign the info on components for all DataArrayDouble instance recursively stored in \a this. + * The first dim of input \a compNames is the field id in the same order than those implicitely specified in \a fieldNames parameter of MEDCouplingAMRAttribute::New. + * The second dim of \a compNames represent the component names component per component corresponding to the field. The size of this 2nd dimension has + * to perfectly fit with those specified in MEDCouplingAMRAttribute::New. + */ +void MEDCouplingAMRAttribute::spillInfoOnComponents(const std::vector< std::vector<std::string> >& compNames) +{ + _tlc.checkConst(); + for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCouplingGridCollection> >::iterator it=_levs.begin();it!=_levs.end();it++) + (*it)->spillInfoOnComponents(compNames); +} + +/*! + * Assign nature for each fields in \a this. + * \param [in] nfs + */ +void MEDCouplingAMRAttribute::spillNatures(const std::vector<NatureOfField>& nfs) +{ + _tlc.checkConst(); + for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCouplingGridCollection> >::iterator it=_levs.begin();it!=_levs.end();it++) + (*it)->spillNatures(nfs); +} + +MEDCouplingAMRAttribute *MEDCouplingAMRAttribute::deepCpy() const +{ + return new MEDCouplingAMRAttribute(*this,true); +} + +MEDCouplingAMRAttribute *MEDCouplingAMRAttribute::deepCpyWithoutGodFather() const +{ + return new MEDCouplingAMRAttribute(*this,false); +} + +/*! + * Returns the number of levels by \b only \b considering \a this (god father instance is considered only to see if it has not changed still last update of \a this). + * + */ +int MEDCouplingAMRAttribute::getNumberOfLevels() const +{ + checkGodFatherFrozen(); + return (int)_levs.size(); +} + +/*! + * This method returns all DataArrayDouble instances lying on the specified mesh \a mesh. + * If \a mesh is not part of the progeny of god father object given at construction of \a this an exception will be thrown. + * + * \return std::vector<DataArrayDouble *> - DataArrayDouble instances to be deallocated by the caller (using decrRef). + * \sa retrieveFieldOn + */ +std::vector<DataArrayDouble *> MEDCouplingAMRAttribute::retrieveFieldsOn(MEDCouplingCartesianAMRMeshGen *mesh) const +{ + for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCouplingGridCollection> >::const_iterator it=_levs.begin();it!=_levs.end();it++) + { + int tmp(-1); + if((*it)->presenceOf(mesh,tmp)) + { + const DataArrayDoubleCollection& ddc((*it)->getFieldsAt(tmp)); + return ddc.retrieveFields(); + } + } + throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::retrieveFieldsOn : the mesh specified is not in the progeny of this !"); +} + +/*! + * \sa retrieveFieldsOn + */ +const DataArrayDouble *MEDCouplingAMRAttribute::getFieldOn(MEDCouplingCartesianAMRMeshGen *mesh, const std::string& fieldName) const +{ + for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCouplingGridCollection> >::const_iterator it=_levs.begin();it!=_levs.end();it++) + { + int tmp(-1); + if((*it)->presenceOf(mesh,tmp)) + { + const DataArrayDoubleCollection& ddc((*it)->getFieldsAt(tmp)); + return ddc.getFieldWithName(fieldName); + } + } + throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::getFieldOn : the mesh specified is not in the progeny of this !"); +} + +DataArrayDouble *MEDCouplingAMRAttribute::getFieldOn(MEDCouplingCartesianAMRMeshGen *mesh, const std::string& fieldName) +{ + for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCouplingGridCollection> >::iterator it=_levs.begin();it!=_levs.end();it++) + { + int tmp(-1); + if((*it)->presenceOf(mesh,tmp)) + { + DataArrayDoubleCollection& ddc((*it)->getFieldsAt(tmp)); + return ddc.getFieldWithName(fieldName); + } + } + throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::getFieldOn non const : the mesh specified is not in the progeny of this !"); +} + +/*! + * This method returns a field on an unstructured mesh the most refined as possible without overlap. + * Ghost part are not visible here. + * + * \return MEDCouplingFieldDouble * - a field on cells that the caller has to deal with (deallocate it). + */ +MEDCouplingFieldDouble *MEDCouplingAMRAttribute::buildCellFieldOnRecurseWithoutOverlapWithoutGhost(MEDCouplingCartesianAMRMeshGen *mesh, const std::string& fieldName) const +{ + std::vector<const DataArrayDouble *> recurseArrs; + std::size_t lev(0); + for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCouplingGridCollection> >::const_iterator it=_levs.begin();it!=_levs.end();it++,lev++) + { + int tmp(-1); + if((*it)->presenceOf(mesh,tmp)) + { + const DataArrayDoubleCollection& ddc((*it)->getFieldsAt(tmp)); + recurseArrs.push_back(ddc.getFieldWithName(fieldName)); + break; + } + } + lev++; + for(std::size_t i=lev;i<_levs.size();i++) + { + const MEDCouplingGridCollection *gc(_levs[i]); + gc->fillIfInTheProgenyOf(fieldName,mesh,recurseArrs); + } + return mesh->buildCellFieldOnRecurseWithoutOverlapWithoutGhost(_ghost_lev,recurseArrs); +} + +/*! + * This method builds a newly created field on cell just lying on mesh \a mesh without its eventual refinement. + * The output field also displays ghost cells. + * + * \return MEDCouplingFieldDouble * - a field on cells that the caller has to deal with (deallocate it). + * + * \sa buildCellFieldOnWithoutGhost + */ +MEDCouplingFieldDouble *MEDCouplingAMRAttribute::buildCellFieldOnWithGhost(MEDCouplingCartesianAMRMeshGen *mesh, const std::string& fieldName) const +{ + const DataArrayDouble *arr(0); + for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCouplingGridCollection> >::const_iterator it=_levs.begin();it!=_levs.end();it++) + { + int tmp(-1); + if((*it)->presenceOf(mesh,tmp)) + { + const DataArrayDoubleCollection& ddc((*it)->getFieldsAt(tmp)); + arr=ddc.getFieldWithName(fieldName); + } + } + if(!arr) + throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::buildCellFieldOnWithGhost : the mesh specified is not in the progeny of this !"); + MEDCouplingAutoRefCountObjectPtr<MEDCouplingIMesh> im(mesh->getImageMesh()->buildWithGhost(_ghost_lev)); + MEDCouplingAutoRefCountObjectPtr<MEDCouplingFieldDouble> ret(MEDCouplingFieldDouble::New(ON_CELLS)); + ret->setMesh(im); + ret->setArray(const_cast<DataArrayDouble *>(arr)); + ret->setName(arr->getName()); + return ret.retn(); +} + +/*! + * This method builds a newly created field on cell just lying on mesh \a mesh without its eventual refinement. + * The output field does not display ghost cells. + * + * \return MEDCouplingFieldDouble * - a field on cells that the caller has to deal with (deallocate it). + * + * \sa buildCellFieldOnWithGhost + */ +MEDCouplingFieldDouble *MEDCouplingAMRAttribute::buildCellFieldOnWithoutGhost(MEDCouplingCartesianAMRMeshGen *mesh, const std::string& fieldName) const +{ + const DataArrayDouble *arr(0); + for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCouplingGridCollection> >::const_iterator it=_levs.begin();it!=_levs.end();it++) + { + int tmp(-1); + if((*it)->presenceOf(mesh,tmp)) + { + const DataArrayDoubleCollection& ddc((*it)->getFieldsAt(tmp)); + arr=ddc.getFieldWithName(fieldName); + } + } + if(!arr) + throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::buildCellFieldOnWithoutGhost : the mesh specified is not in the progeny of this !"); + // + MEDCouplingAutoRefCountObjectPtr<MEDCouplingIMesh> im(mesh->getImageMesh()->buildWithGhost(_ghost_lev)); + std::vector<int> cgs(mesh->getImageMesh()->getCellGridStructure()),cgsWG(im->getCellGridStructure()); + MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> arr2(DataArrayDouble::New()); + arr2->alloc(mesh->getImageMesh()->getNumberOfCells(),arr->getNumberOfComponents()); + std::vector< std::pair<int,int> > cgs2(MEDCouplingStructuredMesh::GetCompactFrmtFromDimensions(cgs)); + MEDCouplingStructuredMesh::ApplyGhostOnCompactFrmt(cgs2,_ghost_lev); + std::vector<int> fakeFactors(mesh->getImageMesh()->getSpaceDimension(),1); + MEDCouplingIMesh::SpreadCoarseToFine(arr,cgsWG,arr2,cgs2,fakeFactors); + arr2->copyStringInfoFrom(*arr); + // + MEDCouplingAutoRefCountObjectPtr<MEDCouplingFieldDouble> ret(MEDCouplingFieldDouble::New(ON_CELLS)); + ret->setMesh(mesh->getImageMesh()); + ret->setArray(arr2); + ret->setName(arr->getName()); + return ret.retn(); +} + + +std::string MEDCouplingAMRAttribute::writeVTHB(const std::string& fileName) const +{ + static const char EXT[]=".vthb"; + std::string baseName,extName,zeFileName; + MEDCouplingMesh::SplitExtension(fileName,baseName,extName); + if(extName==EXT) + zeFileName=fileName; + else + { zeFileName=baseName; zeFileName+=EXT; } + // + std::ofstream ofs(fileName.c_str()); + ofs << "<VTKFile type=\"vtkOverlappingAMR\" version=\"1.1\" byte_order=\"" << MEDCouplingByteOrderStr() << "\">\n"; + const MEDCouplingCartesianAMRMesh *gf(getMyGodFather()); + ofs << " <vtkOverlappingAMR origin=\""; + const MEDCouplingIMesh *gfm(gf->getImageMesh()); + std::vector<double> orig(gfm->getOrigin()); + std::vector<double> spacing(gfm->getDXYZ()); + int dim((int)orig.size()); + std::copy(orig.begin(),orig.end(),std::ostream_iterator<double>(ofs," ")); ofs << "\" grid_description=\""; + for(int i=0;i<dim;i++) + { + char tmp[2]; tmp[0]='X'+i; tmp[1]='\0'; + ofs << tmp; + } + ofs << "\">\n"; + // + int maxLev(gf->getMaxNumberOfLevelsRelativeToThis()),kk(0); + for(int i=0;i<maxLev;i++) + { + std::vector<MEDCouplingCartesianAMRPatchGen *> patches(gf->retrieveGridsAt(i)); + std::size_t sz(patches.size()); + std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCouplingCartesianAMRPatchGen> > patchesSafe(sz); + for(std::size_t j=0;j<sz;j++) + patchesSafe[j]=patches[j]; + if(sz==0) + continue; + ofs << " <Block level=\"" << i << "\" spacing=\""; + std::copy(spacing.begin(),spacing.end(),std::ostream_iterator<double>(ofs," ")); + ofs << "\">\n"; + if(i!=maxLev-1) + { + std::vector<int> factors(patches[0]->getMesh()->getFactors()); + for(int k=0;k<dim;k++) + spacing[k]*=1./((double) factors[k]); + } + std::size_t jj(0); + for(std::vector<MEDCouplingCartesianAMRPatchGen *>::const_iterator it=patches.begin();it!=patches.end();it++,jj++,kk++) + { + ofs << " <DataSet index=\"" << jj << "\" amr_box=\""; + const MEDCouplingCartesianAMRPatch *patchCast(dynamic_cast<const MEDCouplingCartesianAMRPatch *>(*it)); + const MEDCouplingCartesianAMRMeshGen *mesh((*it)->getMesh()); + if(patchCast) + { + const std::vector< std::pair<int,int> >& bltr(patchCast->getBLTRRangeRelativeToGF()); + for(int pp=0;pp<dim;pp++) + ofs << bltr[pp].first << " " << bltr[pp].second-1 << " "; + } + else + { + const MEDCouplingIMesh *im((*it)->getMesh()->getImageMesh()); + std::vector<int> cgs(im->getCellGridStructure()); + for(int pp=0;pp<dim;pp++) + ofs << "0 " << cgs[pp]-1 << " "; + } + ofs << "\" file=\""; + // + int tmp(-1); + if(_levs[i]->presenceOf((*it)->getMesh(),tmp)) + { + const DataArrayDoubleCollection& ddc(_levs[i]->getFieldsAt(tmp)); + std::vector<DataArrayDouble *> arrs(ddc.retrieveFields()); + std::size_t nbFields(arrs.size()); + std::vector< MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> > arrsSafe(nbFields),arrs2Safe(nbFields); + std::vector< const MEDCouplingFieldDouble *> fields(nbFields); + std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCouplingFieldDouble> > fieldsSafe(nbFields); + for(std::size_t pp=0;pp<nbFields;pp++) + arrsSafe[pp]=arrs[pp]; + for(std::size_t pp=0;pp<nbFields;pp++) + { + MEDCouplingAutoRefCountObjectPtr<MEDCouplingIMesh> im(mesh->getImageMesh()->buildWithGhost(_ghost_lev)); + std::vector<int> cgs(mesh->getImageMesh()->getCellGridStructure()),cgsWG(im->getCellGridStructure()); + arrs2Safe[pp]=DataArrayDouble::New(); + arrs2Safe[pp]->alloc(mesh->getImageMesh()->getNumberOfCells(),arrs[pp]->getNumberOfComponents()); + std::vector< std::pair<int,int> > cgs2(MEDCouplingStructuredMesh::GetCompactFrmtFromDimensions(cgs)); + MEDCouplingStructuredMesh::ApplyGhostOnCompactFrmt(cgs2,_ghost_lev); + std::vector<int> fakeFactors(mesh->getImageMesh()->getSpaceDimension(),1); + MEDCouplingIMesh::SpreadCoarseToFine(arrs[pp],cgsWG,arrs2Safe[pp],cgs2,fakeFactors); + arrs2Safe[pp]->copyStringInfoFrom(*arrs[pp]); + // + fieldsSafe[pp]=MEDCouplingFieldDouble::New(ON_CELLS); fields[pp]=fieldsSafe[pp]; + fieldsSafe[pp]->setMesh(mesh->getImageMesh()); + fieldsSafe[pp]->setArray(arrs2Safe[pp]); + fieldsSafe[pp]->setName(arrs[pp]->getName()); + } + std::ostringstream vtiFileName; vtiFileName << baseName << "_" << kk << ".vti"; + MEDCouplingFieldDouble::WriteVTK(vtiFileName.str(),fields,true); + // + ofs << vtiFileName.str() << "\">\n"; + ofs << " \n </DataSet>\n"; + } + } + ofs << " </Block>\n"; + } + // + ofs << " </vtkOverlappingAMR>\n"; + ofs << "</VTKFile>\n"; + return zeFileName; +} + + /*! + * This method is useful just after a remesh after a time step computation to project values in \a this to the new + * mesh \a targetGF. + * + * This method performs a projection from \a this to a target AMR mesh \a targetGF. + * This method performs the projection by trying to transfer the finest information to \a targetGF. + * \b WARNING this method does not update the ghost zone, if any. + * The level0 of \a this god father must have the same structure than those of \a targetGF. + * + * This method makes checks that ghost size of \a this and \a targetGF are the same, and that + * the number of levels in \a this and in \a targetGF are also the same. + */ +MEDCouplingAMRAttribute *MEDCouplingAMRAttribute::projectTo(MEDCouplingCartesianAMRMesh *targetGF) const +{ + if(!targetGF) + throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::projectTo : given other target god is NULL !"); + if(_levs.empty()) + throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::projectTo : no levels in this !"); + const MEDCouplingGridCollection *lev0(_levs[0]); + if(!lev0) + throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::projectTo : lev0 is NULL !"); + std::vector< std::pair < std::string, std::vector<std::string> > > fieldNames(lev0->getInfoOnComponents()); + MEDCouplingAutoRefCountObjectPtr<MEDCouplingAMRAttribute> ret(MEDCouplingAMRAttribute::New(targetGF,fieldNames,_ghost_lev)); + ret->spillNatures(lev0->getNatures()); + ret->alloc(); + int nbLevs(getNumberOfLevels()); + if(targetGF->getMaxNumberOfLevelsRelativeToThis()!=nbLevs) + throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::projectTo : number of levels of this and targetGF must be the same !"); + // first step copy level0 + if(getMyGodFather()->getImageMesh()->getCellGridStructure()!=targetGF->getImageMesh()->getCellGridStructure()) + throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::projectTo : god father of this and target ones do not have the same structure !"); + const DataArrayDoubleCollection& col(lev0->getFieldsAt(0)); + DataArrayDoubleCollection& colTarget(ret->_levs[0]->getFieldsAt(0)); + colTarget.copyFrom(col); + // then go deeper and deeper + for(int i=1;i<nbLevs;i++) + { + ret->synchronizeCoarseToFineByOneLevel(i-1); + MEDCouplingGridCollection *targetCol(ret->_levs[i]); + if(!targetCol) + throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::projectTo : null lev of target !"); + const MEDCouplingGridCollection *thisCol(_levs[i]); + if(!thisCol) + throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::projectTo : null lev of this !"); + targetCol->copyOverlappedZoneFrom(_ghost_lev,*thisCol); + } + return ret.retn(); +} + +/*! + * This method synchronizes from fine to coarse direction arrays. This method makes the hypothesis that \a this has been allocated before using + * MEDCouplingAMRAttribute::alloc method. + * This method \b DOES \b NOT \b UPDATE the ghost zones (neither the fine not the coarse) + * + * \sa synchronizeFineToCoarseBetween + */ +void MEDCouplingAMRAttribute::synchronizeFineToCoarse() +{ + if(_levs.empty()) + throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::synchronizeFineToCoarse : not any levels in this !"); + std::size_t sz(_levs.size()); + // + while(sz>1) + { + sz--; + synchronizeFineToCoarseByOneLevel((int)sz); + } +} + +/*! + * This method allows to synchronizes fields on fine patches on level \a fromLev to coarser patches at \a toLev level. + * This method operates step by step performing the synchronization the \a fromLev to \a fromLev - 1, then \a fromLev -1 to \a fromLev - 2 ... + * until reaching \a toLev level. + * This method \b DOES \b NOT \b UPDATE the ghost zones (neither the fine not the coarse). + * + * \param [in] fromLev - an existing level considered as fine so bigger than \a toLev + * \param [in] toLev - an existing level considered as the target level to reach. + * + */ +void MEDCouplingAMRAttribute::synchronizeFineToCoarseBetween(int fromLev, int toLev) +{ + int nbl(getNumberOfLevels()); + if(fromLev<0 || toLev<0 || fromLev>=nbl || toLev>=nbl) + throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::synchronizeFineToCoarseBetween : fromLev and toLev must be >= 0 and lower than number of levels in this !"); + if(fromLev==toLev) + return ;//nothing to do + if(fromLev<toLev) + throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::synchronizeFineToCoarseBetween : the fromLev level is lower than toLev level ! Call synchronizeFineToCoarseBetween "); + for(int i=fromLev;i>toLev;i--) + synchronizeFineToCoarseByOneLevel(i); +} + +/*! + * This method synchronizes from coarse to fine arrays and fine to fine each other (if _ghost_lev is >0). This method makes the hypothesis that \a this has been allocated before using + * MEDCouplingAMRAttribute::alloc method. + * This method \b DOES \b UPDATE \b the \b ghost \b zone (contrary to synchronizeFineToCoarse method) + */ +void MEDCouplingAMRAttribute::synchronizeCoarseToFine() +{ + if(_levs.empty()) + throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::synchronizeCoarseToFine : not any levels in this !"); + std::size_t sz(_levs.size()); + // + for(std::size_t i=0;i<sz-1;i++) + synchronizeCoarseToFineByOneLevel((int)i); +} + +/*! + * This method allows to synchronizes fields on coarse patches on level \a fromLev to their respective refined patches at \a toLev level. + * This method operates step by step performing the synchronization the \a fromLev to \a fromLev + 1, then \a fromLev + 1 to \a fromLev + 2 ... + * until reaching \a toLev level. + * This method \b DOES \b UPDATE \b the \b ghost \b zone (contrary to synchronizeFineToCoarseBetween method) + * + * \param [in] fromLev - an existing level considered as coarse so lower than \a toLev + * \param [in] toLev - an existing level considered as the target level to reach. + */ +void MEDCouplingAMRAttribute::synchronizeCoarseToFineBetween(int fromLev, int toLev) +{ + int nbl(getNumberOfLevels()); + if(fromLev<0 || toLev<0 || fromLev>=nbl || toLev>=nbl) + throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::synchronizeCoarseToFineBetween : fromLev and toLev must be >= 0 and lower than number of levels in this !"); + if(fromLev==toLev) + return ;//nothing to do + if(fromLev>toLev) + throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::synchronizeCoarseToFineBetween : the fromLev level is greater than toLev level ! Call synchronizeFineToCoarseBetween instead !"); + for(int i=fromLev;i<toLev;i++) + synchronizeCoarseToFineByOneLevel(i); +} + +/*! + * This method synchronizes the ghost zone of all patches (excepted the god father one). + * This method operates in 4 steps. Larger is the number of steps more accurate is the information in the ghost zone. + * + * - firstly coarse to fine with no interactions between brother patches. + * - secondly connected brother patches in a same master patch are updated. + * - thirdly connected nephew patches are updated each other. + * - forthly nth generation cousin patches are updated each other. + * + * This method makes the hypothesis that \a this has been allocated before using MEDCouplingAMRAttribute::alloc method. + * So if \a _ghost_lev == 0 this method has no effect. + */ +void MEDCouplingAMRAttribute::synchronizeAllGhostZones() +{ + int sz(getNumberOfLevels()); + if(sz==0) + throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::synchronizeFineEachOther : not any levels in this !"); + // 1st - synchronize from coarse to the finest all the patches (excepted the god father one) + for(int i=1;i<sz;i++) + { + const MEDCouplingGridCollection *fine(_levs[i]),*coarse(_levs[i-1]); + MEDCouplingGridCollection::SynchronizeCoarseToFineOnlyInGhostZone(_ghost_lev,coarse,fine); + } + // 2nd - classical direct sublevel inside common patch + for(int i=1;i<sz;i++) + { + const MEDCouplingGridCollection *curLev(_levs[i]); + if(!curLev) + throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::synchronizeFineEachOtherInGhostZone : presence of a NULL element !"); + curLev->synchronizeFineEachOther(_ghost_lev,_neighbors[i]); + } + // 3rd - mixed level + for(std::vector< std::pair<const MEDCouplingCartesianAMRPatch *,const MEDCouplingCartesianAMRPatch *> >::const_iterator it=_mixed_lev_neighbors.begin();it!=_mixed_lev_neighbors.end();it++) + { + const DataArrayDoubleCollection *firstDAC(&findCollectionAttachedTo((*it).first->getMesh())),*secondDAC(&findCollectionAttachedTo((*it).second->getMesh())); + DataArrayDoubleCollection::SynchronizeGhostZoneOfOneUsingTwo(_ghost_lev,(*it).first,firstDAC,(*it).second,secondDAC); + } + // 4th - same level but with far ancestor. + for(int i=1;i<sz;i++) + { + const MEDCouplingGridCollection *fine(_levs[i]); + fine->synchronizeFineEachOtherExt(_ghost_lev,_cross_lev_neighbors[i]); + } +} + +/*! + * This method works \b ONLY \b ON \b DIRECT \b SONS \b OF \a mesh. So only a part of patches at a given level is updated here. + * The ghost zone of all of these sons of \a mesh are updated using the brother patches (the patches sharing the \b SAME \a mesh). + * It is sometimes possible that a ghost zone of some sons of \a mesh are covered by a patch of same level but different father. + * For such cases, the ghost zones are \b NOT updated. If you need a more thorough (but more costly) ghost zone update use synchronizeAllGhostZonesAtASpecifiedLevel method instead. + * + * \param [in] mesh - an element in the progeny of god father in \a this, which the ghost zone of its sons will be updated each other. + * + */ +void MEDCouplingAMRAttribute::synchronizeAllGhostZonesOfDirectChidrenOf(const MEDCouplingCartesianAMRMeshGen *mesh) +{ + if(!mesh) + throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::synchronizeAllGhostZonesOfDirectChidrenOf : input mesh is NULL !"); + int level(mesh->getAbsoluteLevelRelativeTo(_gf)),sz(getNumberOfLevels()); + if(level<0 || level>=sz-1) + throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::synchronizeAllGhostZonesOfDirectChidrenOf : the specified level does not exist ! Must be in [0,nbOfLevelsOfThis-1) !"); + const std::vector< std::pair<const MEDCouplingCartesianAMRPatch *,const MEDCouplingCartesianAMRPatch *> >& itemsToFilter(_neighbors[level+1]); + std::vector< std::pair<const MEDCouplingCartesianAMRPatch *,const MEDCouplingCartesianAMRPatch *> > itemsToSync; itemsToSync.reserve(itemsToFilter.size()); + for(std::vector< std::pair<const MEDCouplingCartesianAMRPatch *,const MEDCouplingCartesianAMRPatch *> >::const_iterator it=itemsToFilter.begin();it!=itemsToFilter.end();it++) + { + if((*it).first->getMesh()->getFather()==mesh && (*it).second->getMesh()->getFather()==mesh) + itemsToSync.push_back(std::pair<const MEDCouplingCartesianAMRPatch *,const MEDCouplingCartesianAMRPatch *>((*it).first,(*it).second)); + } + const MEDCouplingGridCollection *curLev(_levs[level+1]); + if(!curLev) + throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::synchronizeAllGhostZonesOfDirectChidrenOf : presence of a NULL element !"); + curLev->synchronizeFineEachOther(_ghost_lev,itemsToSync); +} + +/*! + * This method updates \b all the patches at level \a level each other without consideration of their father. + * So this method is more time consuming than synchronizeAllGhostZonesOfDirectChidrenOf. + */ +void MEDCouplingAMRAttribute::synchronizeAllGhostZonesAtASpecifiedLevel(int level) +{ + int maxLev(getNumberOfLevels()); + if(level<0 || level>=maxLev) + throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::synchronizeAllGhostZonesAtASpecifiedLevel : the specified level must be in [0,maxLevel) !"); + if(level==0) + return ;//at level 0 only one patch -> no need to update + // 1st step - updates all patches pairs at level \a level sharing the same father + const std::vector< std::pair<const MEDCouplingCartesianAMRPatch *,const MEDCouplingCartesianAMRPatch *> >& items(_neighbors[level]); + const MEDCouplingGridCollection *curLev(_levs[level]); + if(!curLev) + throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::synchronizeAllGhostZonesAtASpecifiedLevel : presence of a NULL element !"); + curLev->synchronizeFineEachOther(_ghost_lev,items); + //2nd step - updates all patches pairs at level \a level not sharing the same father + const std::vector< std::pair<const MEDCouplingCartesianAMRPatch *,const MEDCouplingCartesianAMRPatch *> >& items2(_cross_lev_neighbors[level]); + curLev->synchronizeFineEachOtherExt(_ghost_lev,items2); +} + +/*! + * This method updates ghost zones of patches at level \a level whatever their father \b using \b father \b patches \b ONLY (at level \b level - 1). + * This method is useful to propagate to the ghost zone of childhood the modification. + */ +void MEDCouplingAMRAttribute::synchronizeAllGhostZonesAtASpecifiedLevelUsingOnlyFather(int level) +{ + int maxLev(getNumberOfLevels()); + if(level<=0 || level>=maxLev) + throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::synchronizeAllGhostZonesAtASpecifiedLevelUsingOnlyFather : the specified level must be in (0,maxLevel) !"); + const MEDCouplingGridCollection *fine(_levs[level]),*coarse(_levs[level-1]); + MEDCouplingGridCollection::SynchronizeCoarseToFineOnlyInGhostZone(_ghost_lev,coarse,fine); + //_cross_lev_neighbors is not needed. +} + +/*! + * This method allocates all DataArrayDouble instances stored recursively in \a this. + * + * \sa dealloc + */ +void MEDCouplingAMRAttribute::alloc() +{ + _tlc.resetState(); + for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCouplingGridCollection> >::iterator it=_levs.begin();it!=_levs.end();it++) + { + MEDCouplingGridCollection *elt(*it); + if(elt) + elt->alloc(_ghost_lev); + else + throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::alloc : internal error !"); + } +} + +/*! + * This method deallocates all DataArrayDouble instances stored recursively in \a this. + * \sa alloc + */ +void MEDCouplingAMRAttribute::dealloc() +{ + _tlc.checkConst(); + for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCouplingGridCollection> >::iterator it=_levs.begin();it!=_levs.end();it++) + { + MEDCouplingGridCollection *elt(*it); + if(elt) + elt->dealloc(); + else + throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::dealloc : internal error !"); + } +} + +bool MEDCouplingAMRAttribute::changeGodFather(MEDCouplingCartesianAMRMesh *gf) +{ + bool ret(MEDCouplingDataForGodFather::changeGodFather(gf)); + return ret; +} + +std::size_t MEDCouplingAMRAttribute::getHeapMemorySizeWithoutChildren() const +{ + std::size_t ret(sizeof(MEDCouplingAMRAttribute)); + ret+=_levs.capacity()*sizeof(MEDCouplingAutoRefCountObjectPtr<MEDCouplingGridCollection>); + return ret; +} + +std::vector<const BigMemoryObject *> MEDCouplingAMRAttribute::getDirectChildrenWithNull() const +{ + std::vector<const BigMemoryObject *> ret; + for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCouplingGridCollection> >::const_iterator it=_levs.begin();it!=_levs.end();it++) + ret.push_back((const MEDCouplingGridCollection *)*it); + return ret; +} + +void MEDCouplingAMRAttribute::updateTime() const +{//tony +} + +MEDCouplingAMRAttribute::MEDCouplingAMRAttribute(MEDCouplingCartesianAMRMesh *gf, const std::vector< std::pair<std::string,int> >& fieldNames, int ghostLev):MEDCouplingDataForGodFather(gf),_ghost_lev(ghostLev) +{ + //gf non empty, checked by constructor + int maxLev(gf->getMaxNumberOfLevelsRelativeToThis()); + _levs.resize(maxLev); + for(int i=0;i<maxLev;i++) + { + std::vector<MEDCouplingCartesianAMRPatchGen *> patches(gf->retrieveGridsAt(i)); + std::size_t sz(patches.size()); + std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCouplingCartesianAMRPatchGen> > patchesSafe(patches.size()); + for(std::size_t j=0;j<sz;j++) + patchesSafe[j]=patches[j]; + std::vector<const MEDCouplingCartesianAMRMeshGen *> ms(sz); + for(std::size_t j=0;j<sz;j++) + { + ms[j]=patches[j]->getMesh(); + } + _levs[i]=MEDCouplingGridCollection::New(ms,fieldNames); + } + // updates cross levels neighbors + _neighbors.resize(_levs.size()); + _cross_lev_neighbors.resize(_levs.size()); + if(_levs.empty()) + throw INTERP_KERNEL::Exception("constructor of MEDCouplingAMRAttribute : not any levels in this !"); + std::size_t sz(_levs.size()); + for(std::size_t i=1;i<sz;i++) + { + const MEDCouplingGridCollection *fine(_levs[i]); + if(!fine) + throw INTERP_KERNEL::Exception("constructor of MEDCouplingAMRAttribute : presence of a NULL element !"); + _neighbors[i]=fine->findNeighbors(_ghost_lev); + if(i!=sz-1) + { + for(std::vector< std::pair<const MEDCouplingCartesianAMRPatch *,const MEDCouplingCartesianAMRPatch *> >::const_iterator it=_neighbors[i].begin();it!=_neighbors[i].end();it++) + { + MEDCouplingCartesianAMRPatch::FindNeighborsOfSubPatchesOf(_ghost_lev,(*it).first,(*it).second,_mixed_lev_neighbors); + std::vector< std::vector < std::pair<const MEDCouplingCartesianAMRPatch *,const MEDCouplingCartesianAMRPatch *> > > neighs2(MEDCouplingCartesianAMRPatch::FindNeighborsOfSubPatchesOfSameLev(_ghost_lev,(*it).first,(*it).second)); + std::size_t fullLev(i+neighs2.size()); + if(fullLev>=sz) + throw INTERP_KERNEL::Exception("constructor of MEDCouplingAMRAttribute : internal error ! something is wrong in computation of cross level neighbors !"); + std::size_t ii(i+1); + for(std::vector< std::vector< std::pair<const MEDCouplingCartesianAMRPatch *,const MEDCouplingCartesianAMRPatch *> > >::const_iterator it0=neighs2.begin();it0!=neighs2.end();it0++,ii++) + _cross_lev_neighbors[ii].insert(_cross_lev_neighbors[ii].end(),(*it0).begin(),(*it0).end()); + } + } + } +} + +MEDCouplingAMRAttribute::MEDCouplingAMRAttribute(const MEDCouplingAMRAttribute& other, bool deepCpyGF):MEDCouplingDataForGodFather(other,deepCpyGF),_ghost_lev(other._ghost_lev),_levs(other._levs.size()),_neighbors(other._neighbors),_mixed_lev_neighbors(other._mixed_lev_neighbors),_cross_lev_neighbors(other._cross_lev_neighbors) +{ + std::size_t sz(other._levs.size()); + for(std::size_t i=0;i<sz;i++) + { + const MEDCouplingGridCollection *elt(other._levs[i]); + if(elt) + { + _levs[i]=other._levs[i]->deepCpy(_gf,other._gf); + } + } + //_cross_lev_neighbors(other._cross_lev_neighbors) + sz=other._neighbors.size(); + for(std::size_t i=0;i<sz;i++) + { + const std::vector< std::pair<const MEDCouplingCartesianAMRPatch *,const MEDCouplingCartesianAMRPatch *> >& neigh2(other._neighbors[i]); + std::size_t sz2(neigh2.size()); + std::vector< std::pair<const MEDCouplingCartesianAMRPatch *,const MEDCouplingCartesianAMRPatch *> >& neigh3(_neighbors[i]); + for(std::size_t j=0;j<sz2;j++) + { + const MEDCouplingCartesianAMRPatch *p1(neigh2[j].first),*p2(neigh2[j].second); + std::vector<int> pp1(p1->getMesh()->getPositionRelativeTo(other._gf)),pp2(p2->getMesh()->getPositionRelativeTo(other._gf)); + neigh3[j].first=_gf->getPatchAtPosition(pp1); + neigh3[j].second=_gf->getPatchAtPosition(pp2); + } + } + // + sz=other._mixed_lev_neighbors.size(); + for(std::size_t i=0;i<sz;i++) + { + const MEDCouplingCartesianAMRPatch *p1(other._mixed_lev_neighbors[i].first),*p2(other._mixed_lev_neighbors[i].second); + std::vector<int> pp1(p1->getMesh()->getPositionRelativeTo(other._gf)),pp2(p2->getMesh()->getPositionRelativeTo(other._gf)); + _mixed_lev_neighbors[i].first=_gf->getPatchAtPosition(pp1); + _mixed_lev_neighbors[i].second=_gf->getPatchAtPosition(pp2); + } + // + sz=other._cross_lev_neighbors.size(); + for(std::size_t i=0;i<sz;i++) + { + const std::vector< std::pair<const MEDCouplingCartesianAMRPatch *,const MEDCouplingCartesianAMRPatch *> >& neigh2(other._cross_lev_neighbors[i]); + std::size_t sz2(neigh2.size()); + std::vector< std::pair<const MEDCouplingCartesianAMRPatch *,const MEDCouplingCartesianAMRPatch *> >& neigh3(_cross_lev_neighbors[i]); + for(std::size_t j=0;j<sz2;j++) + { + const MEDCouplingCartesianAMRPatch *p1(neigh2[j].first),*p2(neigh2[j].second); + std::vector<int> pp1(p1->getMesh()->getPositionRelativeTo(other._gf)),pp2(p2->getMesh()->getPositionRelativeTo(other._gf)); + neigh3[j].first=_gf->getPatchAtPosition(pp1); + neigh3[j].second=_gf->getPatchAtPosition(pp2); + } + } +} + +const DataArrayDoubleCollection& MEDCouplingAMRAttribute::findCollectionAttachedTo(const MEDCouplingCartesianAMRMeshGen *m) const +{ + for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCouplingGridCollection> >::const_iterator it=_levs.begin();it!=_levs.end();it++) + { + const MEDCouplingGridCollection *elt(*it); + if(elt) + { + int tmp(-1); + if(elt->presenceOf(m,tmp)) + { + return elt->getFieldsAt(tmp); + } + } + } + throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::findCollectionAttachedTo : unable to find such part of mesh in this !"); +} + +void MEDCouplingAMRAttribute::synchronizeFineToCoarseByOneLevel(int level) +{ + int nbl(getNumberOfLevels()); + if(level<=0 || level>=nbl) + throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::synchronizeFineToCoarseByOneLevel : the input level must be in ]0,nb_of_levels[ !"); + const MEDCouplingGridCollection *fine(_levs[level]),*coarse(_levs[level-1]); + MEDCouplingGridCollection::SynchronizeFineToCoarse(_ghost_lev,fine,coarse); +} + +void MEDCouplingAMRAttribute::synchronizeCoarseToFineByOneLevel(int level) +{ + int nbl(getNumberOfLevels()); + if(level<0 || level>=nbl-1) + throw INTERP_KERNEL::Exception("MEDCouplingAMRAttribute::synchronizeFineToCoarseByOneLevel : the input level must be in [0,nb_of_levels[ !"); + const MEDCouplingGridCollection *fine(_levs[level+1]),*coarse(_levs[level]); + MEDCouplingGridCollection::SynchronizeCoarseToFine(_ghost_lev,coarse,fine); +} diff --git a/src/medtool/src/MEDCoupling/MEDCouplingAMRAttribute.hxx b/src/medtool/src/MEDCoupling/MEDCouplingAMRAttribute.hxx new file mode 100644 index 000000000..2af4d3b92 --- /dev/null +++ b/src/medtool/src/MEDCoupling/MEDCouplingAMRAttribute.hxx @@ -0,0 +1,182 @@ +// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 +// 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 + +#ifndef __MEDCOUPLINGAMRATTRIBUTE_HXX__ +#define __MEDCOUPLINGAMRATTRIBUTE_HXX__ + +#include "MEDCoupling.hxx" +#include "MEDCouplingNatureOfFieldEnum" +#include "MEDCouplingCartesianAMRMesh.hxx" + +namespace ParaMEDMEM +{ + /// @cond INTERNAL + class DataArrayDoubleCollection : public RefCountObject, public TimeLabel + { + public: + static DataArrayDoubleCollection *New(const std::vector< std::pair<std::string,int> >& fieldNames); + DataArrayDoubleCollection *deepCpy() const; + void allocTuples(int nbOfTuples); + void dellocTuples(); + void copyFrom(const DataArrayDoubleCollection& other); + void spillInfoOnComponents(const std::vector< std::vector<std::string> >& compNames); + void spillNatures(const std::vector<NatureOfField>& nfs); + std::vector< std::pair<std::string, std::vector<std::string> > > getInfoOnComponents() const; + std::vector<NatureOfField> getNatures() const; + std::vector<DataArrayDouble *> retrieveFields() const; + const DataArrayDouble *getFieldWithName(const std::string& name) const; + DataArrayDouble *getFieldWithName(const std::string& name); + DataArrayDouble *at(int pos); + const DataArrayDouble *at(int pos) const; + int size() const; + static void SynchronizeFineToCoarse(int ghostLev, const MEDCouplingCartesianAMRMeshGen *fatherOfFineMesh, int patchId, const DataArrayDoubleCollection *fine, DataArrayDoubleCollection *coarse); + static void SynchronizeCoarseToFine(int ghostLev, const MEDCouplingCartesianAMRMeshGen *fatherOfFineMesh, int patchId, const DataArrayDoubleCollection *coarse, DataArrayDoubleCollection *fine); + static void SynchronizeFineEachOther(int patchId, int ghostLev, const MEDCouplingCartesianAMRMeshGen *fatherOfFineMesh, const std::vector<const MEDCouplingCartesianAMRMeshGen *>& children, const std::vector<DataArrayDoubleCollection *>& fieldsOnFine); + static void SynchronizeCoarseToFineOnlyInGhostZone(int ghostLev, const MEDCouplingCartesianAMRMeshGen *fatherOfFineMesh, int patchId, const DataArrayDoubleCollection *coarse, DataArrayDoubleCollection *fine); + static void SynchronizeGhostZoneOfOneUsingTwo(int ghostLev, const MEDCouplingCartesianAMRPatch *p1, const DataArrayDoubleCollection *p1dac, const MEDCouplingCartesianAMRPatch *p2, const DataArrayDoubleCollection *p2dac); + void synchronizeMyGhostZoneUsing(int ghostLev, const DataArrayDoubleCollection& other, const MEDCouplingCartesianAMRPatch *thisp, const MEDCouplingCartesianAMRPatch *otherp, const MEDCouplingCartesianAMRMeshGen *father) const; + void synchronizeMyGhostZoneUsingExt(int ghostLev, const DataArrayDoubleCollection& other, const MEDCouplingCartesianAMRPatch *thisp, const MEDCouplingCartesianAMRPatch *otherp) const; + private: + DataArrayDoubleCollection(const std::vector< std::pair<std::string,int> >& fieldNames); + DataArrayDoubleCollection(const DataArrayDoubleCollection& other); + std::size_t getHeapMemorySizeWithoutChildren() const; + std::vector<const BigMemoryObject *> getDirectChildrenWithNull() const; + void updateTime() const; + static void CheckDiscriminantNames(const std::vector<std::string>& names); + static bool IsConservativeNature(NatureOfField n); + static void CheckSameNatures(NatureOfField n1, NatureOfField n2); + static void CheckValidNature(NatureOfField n); + private: + std::vector< std::pair< MEDCouplingAutoRefCountObjectPtr<DataArrayDouble>, NatureOfField > > _arrs; + }; + + class MEDCouplingGridCollection : public RefCountObject, public TimeLabel + { + public: + static MEDCouplingGridCollection *New(const std::vector<const MEDCouplingCartesianAMRMeshGen *>& ms, const std::vector< std::pair<std::string,int> >& fieldNames); + MEDCouplingGridCollection *deepCpy(const MEDCouplingCartesianAMRMeshGen *newGf, const MEDCouplingCartesianAMRMeshGen *oldGf) const; + void alloc(int ghostLev); + void dealloc(); + void spillInfoOnComponents(const std::vector< std::vector<std::string> >& compNames); + void spillNatures(const std::vector<NatureOfField>& nfs); + std::vector< std::pair<std::string, std::vector<std::string> > > getInfoOnComponents() const; + std::vector<NatureOfField> getNatures() const; + bool presenceOf(const MEDCouplingCartesianAMRMeshGen *m, int& pos) const; + const DataArrayDoubleCollection& getFieldsAt(int pos) const; + DataArrayDoubleCollection& getFieldsAt(int pos); + void copyOverlappedZoneFrom(int ghostLev, const MEDCouplingGridCollection& other); + static void SynchronizeFineToCoarse(int ghostLev, const MEDCouplingGridCollection *fine, const MEDCouplingGridCollection *coarse); + static void SynchronizeCoarseToFine(int ghostLev, const MEDCouplingGridCollection *coarse, const MEDCouplingGridCollection *fine); + void synchronizeFineEachOther(int ghostLev, const std::vector< std::pair<const MEDCouplingCartesianAMRPatch *,const MEDCouplingCartesianAMRPatch *> >& ps) const; + void synchronizeFineEachOtherExt(int ghostLev, const std::vector< std::pair<const MEDCouplingCartesianAMRPatch *,const MEDCouplingCartesianAMRPatch *> >& ps) const; + std::vector< std::pair<const MEDCouplingCartesianAMRPatch *,const MEDCouplingCartesianAMRPatch *> > findNeighbors(int ghostLev) const; + static void SynchronizeCoarseToFineOnlyInGhostZone(int ghostLev, const MEDCouplingGridCollection *coarse, const MEDCouplingGridCollection *fine); + void fillIfInTheProgenyOf(const std::string& fieldName, const MEDCouplingCartesianAMRMeshGen *head, std::vector<const DataArrayDouble *>& recurseArrs) const; + private: + MEDCouplingGridCollection(const std::vector<const MEDCouplingCartesianAMRMeshGen *>& ms, const std::vector< std::pair<std::string,int> >& fieldNames); + MEDCouplingGridCollection(const MEDCouplingGridCollection& other, const MEDCouplingCartesianAMRMeshGen *newGf, const MEDCouplingCartesianAMRMeshGen *oldGf); + std::size_t getHeapMemorySizeWithoutChildren() const; + std::vector<const BigMemoryObject *> getDirectChildrenWithNull() const; + void updateTime() const; + private: + std::vector< std::pair<const MEDCouplingCartesianAMRMeshGen *,MEDCouplingAutoRefCountObjectPtr<DataArrayDoubleCollection> > > _map_of_dadc; + }; + + /// @endcond + + class MEDCouplingDataForGodFather : public RefCountObject + { + friend class MEDCouplingCartesianAMRMesh; + public: + MEDCOUPLING_EXPORT MEDCouplingCartesianAMRMesh *getMyGodFather(); + MEDCOUPLING_EXPORT const MEDCouplingCartesianAMRMesh *getMyGodFather() const; + MEDCOUPLING_EXPORT virtual void synchronizeFineToCoarse() = 0; + MEDCOUPLING_EXPORT virtual void synchronizeFineToCoarseBetween(int fromLev, int toLev) = 0; + MEDCOUPLING_EXPORT virtual void synchronizeCoarseToFine() = 0; + MEDCOUPLING_EXPORT virtual void synchronizeCoarseToFineBetween(int fromLev, int toLev) = 0; + MEDCOUPLING_EXPORT virtual void synchronizeAllGhostZones() = 0; + MEDCOUPLING_EXPORT virtual void synchronizeAllGhostZonesOfDirectChidrenOf(const MEDCouplingCartesianAMRMeshGen *mesh) = 0; + MEDCOUPLING_EXPORT virtual void synchronizeAllGhostZonesAtASpecifiedLevel(int level) = 0; + MEDCOUPLING_EXPORT virtual void synchronizeAllGhostZonesAtASpecifiedLevelUsingOnlyFather(int level) = 0; + MEDCOUPLING_EXPORT virtual void alloc() = 0; + MEDCOUPLING_EXPORT virtual void dealloc() = 0; + protected: + MEDCouplingDataForGodFather(MEDCouplingCartesianAMRMesh *gf); + void checkGodFatherFrozen() const; + protected: + virtual bool changeGodFather(MEDCouplingCartesianAMRMesh *gf); + MEDCouplingDataForGodFather(const MEDCouplingDataForGodFather& other, bool deepCpyGF); + protected: + MEDCouplingAutoRefCountObjectPtr<MEDCouplingCartesianAMRMesh> _gf; + TimeLabelConstOverseer _tlc; + }; + + class MEDCouplingAMRAttribute : public MEDCouplingDataForGodFather, public TimeLabel + { + public: + MEDCOUPLING_EXPORT static MEDCouplingAMRAttribute *New(MEDCouplingCartesianAMRMesh *gf, const std::vector< std::pair<std::string,int> >& fieldNames, int ghostLev); + MEDCOUPLING_EXPORT static MEDCouplingAMRAttribute *New(MEDCouplingCartesianAMRMesh *gf, const std::vector< std::pair<std::string, std::vector<std::string> > >& fieldNames, int ghostLev); + MEDCOUPLING_EXPORT void spillInfoOnComponents(const std::vector< std::vector<std::string> >& compNames); + MEDCOUPLING_EXPORT void spillNatures(const std::vector<NatureOfField>& nfs); + MEDCOUPLING_EXPORT MEDCouplingAMRAttribute *deepCpy() const; + MEDCOUPLING_EXPORT MEDCouplingAMRAttribute *deepCpyWithoutGodFather() const; + MEDCOUPLING_EXPORT int getNumberOfLevels() const; + MEDCOUPLING_EXPORT std::vector<DataArrayDouble *> retrieveFieldsOn(MEDCouplingCartesianAMRMeshGen *mesh) const; + MEDCOUPLING_EXPORT const DataArrayDouble *getFieldOn(MEDCouplingCartesianAMRMeshGen *mesh, const std::string& fieldName) const; + MEDCOUPLING_EXPORT DataArrayDouble *getFieldOn(MEDCouplingCartesianAMRMeshGen *mesh, const std::string& fieldName); + MEDCOUPLING_EXPORT MEDCouplingFieldDouble *buildCellFieldOnRecurseWithoutOverlapWithoutGhost(MEDCouplingCartesianAMRMeshGen *mesh, const std::string& fieldName) const; + MEDCOUPLING_EXPORT MEDCouplingFieldDouble *buildCellFieldOnWithGhost(MEDCouplingCartesianAMRMeshGen *mesh, const std::string& fieldName) const; + MEDCOUPLING_EXPORT MEDCouplingFieldDouble *buildCellFieldOnWithoutGhost(MEDCouplingCartesianAMRMeshGen *mesh, const std::string& fieldName) const; + MEDCOUPLING_EXPORT std::string writeVTHB(const std::string& fileName) const; + // + MEDCOUPLING_EXPORT MEDCouplingAMRAttribute *projectTo(MEDCouplingCartesianAMRMesh *targetGF) const; + // + MEDCOUPLING_EXPORT void synchronizeFineToCoarse(); + MEDCOUPLING_EXPORT void synchronizeFineToCoarseBetween(int fromLev, int toLev); + MEDCOUPLING_EXPORT void synchronizeCoarseToFine(); + MEDCOUPLING_EXPORT void synchronizeCoarseToFineBetween(int fromLev, int toLev); + MEDCOUPLING_EXPORT void synchronizeAllGhostZones(); + MEDCOUPLING_EXPORT void synchronizeAllGhostZonesOfDirectChidrenOf(const MEDCouplingCartesianAMRMeshGen *mesh); + MEDCOUPLING_EXPORT void synchronizeAllGhostZonesAtASpecifiedLevel(int level); + MEDCOUPLING_EXPORT void synchronizeAllGhostZonesAtASpecifiedLevelUsingOnlyFather(int level); + // + MEDCOUPLING_EXPORT void alloc(); + MEDCOUPLING_EXPORT void dealloc(); + MEDCOUPLING_EXPORT bool changeGodFather(MEDCouplingCartesianAMRMesh *gf); + // + MEDCOUPLING_EXPORT std::size_t getHeapMemorySizeWithoutChildren() const; + MEDCOUPLING_EXPORT std::vector<const BigMemoryObject *> getDirectChildrenWithNull() const; + MEDCOUPLING_EXPORT void updateTime() const; + private: + MEDCouplingAMRAttribute(MEDCouplingCartesianAMRMesh *gf, const std::vector< std::pair<std::string,int> >& fieldNames, int ghostLev); + MEDCouplingAMRAttribute(const MEDCouplingAMRAttribute& other, bool deepCpyGF); + const DataArrayDoubleCollection& findCollectionAttachedTo(const MEDCouplingCartesianAMRMeshGen *m) const; + void synchronizeFineToCoarseByOneLevel(int level); + void synchronizeCoarseToFineByOneLevel(int level); + private: + int _ghost_lev; + std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCouplingGridCollection> > _levs; + std::vector< std::vector< std::pair<const MEDCouplingCartesianAMRPatch *,const MEDCouplingCartesianAMRPatch *> > > _neighbors; + std::vector< std::pair<const MEDCouplingCartesianAMRPatch *,const MEDCouplingCartesianAMRPatch *> > _mixed_lev_neighbors; + std::vector< std::vector< std::pair<const MEDCouplingCartesianAMRPatch *,const MEDCouplingCartesianAMRPatch *> > > _cross_lev_neighbors; + }; +} + +#endif diff --git a/src/medtool/src/MEDCoupling/MEDCouplingAutoRefCountObjectPtr.hxx b/src/medtool/src/MEDCoupling/MEDCouplingAutoRefCountObjectPtr.hxx new file mode 100644 index 000000000..02719b50b --- /dev/null +++ b/src/medtool/src/MEDCoupling/MEDCouplingAutoRefCountObjectPtr.hxx @@ -0,0 +1,79 @@ +// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 +// 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_MEDCOUPLINGAUTOREFCOUNTOBJECTPTR_HXX__ +#define __PARAMEDMEM_MEDCOUPLINGAUTOREFCOUNTOBJECTPTR_HXX__ + +#include "MEDCouplingRefCountObject.hxx" +#include "InterpKernelException.hxx" + +namespace ParaMEDMEM +{ + template<class T> + class MEDCouplingAutoRefCountObjectPtr + { + public: + MEDCouplingAutoRefCountObjectPtr(const MEDCouplingAutoRefCountObjectPtr& other):_ptr(0) { referPtr(other._ptr); } + MEDCouplingAutoRefCountObjectPtr(T *ptr=0):_ptr(ptr) { } + ~MEDCouplingAutoRefCountObjectPtr() { destroyPtr(); } + bool operator==(const MEDCouplingAutoRefCountObjectPtr& other) const { return _ptr==other._ptr; } + bool operator==(const T *other) const { return _ptr==other; } + MEDCouplingAutoRefCountObjectPtr &operator=(const MEDCouplingAutoRefCountObjectPtr& other) { if(_ptr!=other._ptr) { destroyPtr(); referPtr(other._ptr); } return *this; } + MEDCouplingAutoRefCountObjectPtr &operator=(T *ptr) { if(_ptr!=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; } + 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(); } + private: + T *_ptr; + }; + + template<class T, class U> + typename ParaMEDMEM::MEDCouplingAutoRefCountObjectPtr<U> DynamicCast(typename ParaMEDMEM::MEDCouplingAutoRefCountObjectPtr<T>& autoSubPtr) throw() + { + T *subPtr(autoSubPtr); + U *ptr(dynamic_cast<U *>(subPtr)); + typename ParaMEDMEM::MEDCouplingAutoRefCountObjectPtr<U> ret(ptr); + if(ptr) + ptr->incrRef(); + return ret; + } + + template<class T, class U> + typename ParaMEDMEM::MEDCouplingAutoRefCountObjectPtr<U> DynamicCastSafe(typename ParaMEDMEM::MEDCouplingAutoRefCountObjectPtr<T>& autoSubPtr) + { + T *subPtr(autoSubPtr); + U *ptr(dynamic_cast<U *>(subPtr)); + if(subPtr && !ptr) + throw INTERP_KERNEL::Exception("DynamicCastSafe : U is not a subtype of T !"); + typename ParaMEDMEM::MEDCouplingAutoRefCountObjectPtr<U> ret(ptr); + if(ptr) + ptr->incrRef(); + return ret; + } +} + +#endif diff --git a/src/medtool/src/MEDCoupling/MEDCouplingCMesh.cxx b/src/medtool/src/MEDCoupling/MEDCouplingCMesh.cxx new file mode 100644 index 000000000..597b682a6 --- /dev/null +++ b/src/medtool/src/MEDCoupling/MEDCouplingCMesh.cxx @@ -0,0 +1,923 @@ +// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 +// 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 "MEDCouplingCMesh.hxx" +#include "MEDCouplingMemArray.hxx" +#include "MEDCouplingFieldDouble.hxx" + +#include <functional> +#include <algorithm> +#include <sstream> +#include <numeric> + +using namespace ParaMEDMEM; + +MEDCouplingCMesh::MEDCouplingCMesh():_x_array(0),_y_array(0),_z_array(0) +{ +} + +MEDCouplingCMesh::MEDCouplingCMesh(const MEDCouplingCMesh& other, bool deepCopy):MEDCouplingStructuredMesh(other,deepCopy) +{ + if(deepCopy) + { + if(other._x_array) + _x_array=other._x_array->deepCpy(); + else + _x_array=0; + if(other._y_array) + _y_array=other._y_array->deepCpy(); + else + _y_array=0; + if(other._z_array) + _z_array=other._z_array->deepCpy(); + else + _z_array=0; + } + else + { + _x_array=other._x_array; + if(_x_array) + _x_array->incrRef(); + _y_array=other._y_array; + if(_y_array) + _y_array->incrRef(); + _z_array=other._z_array; + if(_z_array) + _z_array->incrRef(); + } +} + +MEDCouplingCMesh::~MEDCouplingCMesh() +{ + if(_x_array) + _x_array->decrRef(); + if(_y_array) + _y_array->decrRef(); + if(_z_array) + _z_array->decrRef(); +} + +MEDCouplingCMesh *MEDCouplingCMesh::New() +{ + return new MEDCouplingCMesh; +} + +MEDCouplingCMesh *MEDCouplingCMesh::New(const std::string& meshName) +{ + MEDCouplingCMesh *ret=new MEDCouplingCMesh; + ret->setName(meshName); + return ret; +} + +MEDCouplingMesh *MEDCouplingCMesh::deepCpy() const +{ + return clone(true); +} + +MEDCouplingCMesh *MEDCouplingCMesh::clone(bool recDeepCpy) const +{ + return new MEDCouplingCMesh(*this,recDeepCpy); +} + +void MEDCouplingCMesh::updateTime() const +{ + if(_x_array) + updateTimeWith(*_x_array); + if(_y_array) + updateTimeWith(*_y_array); + if(_z_array) + updateTimeWith(*_z_array); +} + +std::size_t MEDCouplingCMesh::getHeapMemorySizeWithoutChildren() const +{ + return MEDCouplingStructuredMesh::getHeapMemorySizeWithoutChildren(); +} + +std::vector<const BigMemoryObject *> MEDCouplingCMesh::getDirectChildrenWithNull() const +{ + std::vector<const BigMemoryObject *> ret; + ret.push_back(_x_array); + ret.push_back(_y_array); + ret.push_back(_z_array); + return ret; +} + +/*! + * This method copyies all tiny strings from other (name and components name). + * @throw if other and this have not same mesh type. + */ +void MEDCouplingCMesh::copyTinyStringsFrom(const MEDCouplingMesh *other) +{ + MEDCouplingStructuredMesh::copyTinyStringsFrom(other); + const MEDCouplingCMesh *otherC(dynamic_cast<const MEDCouplingCMesh *>(other)); + if(!otherC) + throw INTERP_KERNEL::Exception("MEDCouplingCMesh::copyTinyStringsFrom : meshes have not same type !"); + if(_x_array && otherC->_x_array) + _x_array->copyStringInfoFrom(*otherC->_x_array); + if(_y_array && otherC->_y_array) + _y_array->copyStringInfoFrom(*otherC->_y_array); + if(_z_array && otherC->_z_array) + _z_array->copyStringInfoFrom(*otherC->_z_array); +} + +bool MEDCouplingCMesh::isEqualIfNotWhy(const MEDCouplingMesh *other, double prec, std::string& reason) const +{ + if(!other) + throw INTERP_KERNEL::Exception("MEDCouplingCMesh::isEqualIfNotWhy : input other pointer is null !"); + const MEDCouplingCMesh *otherC=dynamic_cast<const MEDCouplingCMesh *>(other); + if(!otherC) + { + reason="mesh given in input is not castable in MEDCouplingCMesh !"; + return false; + } + if(!MEDCouplingStructuredMesh::isEqualIfNotWhy(other,prec,reason)) + return false; + const DataArrayDouble *thisArr[3]={_x_array,_y_array,_z_array}; + const DataArrayDouble *otherArr[3]={otherC->_x_array,otherC->_y_array,otherC->_z_array}; + std::ostringstream oss; oss.precision(15); + for(int i=0;i<3;i++) + { + if((thisArr[i]!=0 && otherArr[i]==0) || (thisArr[i]==0 && otherArr[i]!=0)) + { + oss << "Only one CMesh between the two this and other has its coordinates of rank" << i << " defined !"; + reason=oss.str(); + return false; + } + if(thisArr[i]) + if(!thisArr[i]->isEqualIfNotWhy(*otherArr[i],prec,reason)) + { + oss << "Coordinates DataArrayDouble of rank #" << i << " differ :"; + reason.insert(0,oss.str()); + return false; + } + } + return true; +} + +bool MEDCouplingCMesh::isEqualWithoutConsideringStr(const MEDCouplingMesh *other, double prec) const +{ + const MEDCouplingCMesh *otherC=dynamic_cast<const MEDCouplingCMesh *>(other); + if(!otherC) + return false; + const DataArrayDouble *thisArr[3]={_x_array,_y_array,_z_array}; + const DataArrayDouble *otherArr[3]={otherC->_x_array,otherC->_y_array,otherC->_z_array}; + for(int i=0;i<3;i++) + { + if((thisArr[i]!=0 && otherArr[i]==0) || (thisArr[i]==0 && otherArr[i]!=0)) + return false; + if(thisArr[i]) + if(!thisArr[i]->isEqualWithoutConsideringStr(*otherArr[i],prec)) + return false; + } + return true; +} + +void MEDCouplingCMesh::checkDeepEquivalWith(const MEDCouplingMesh *other, int cellCompPol, double prec, + DataArrayInt *&cellCor, DataArrayInt *&nodeCor) const +{ + if(!isEqualWithoutConsideringStr(other,prec)) + throw INTERP_KERNEL::Exception("MEDCouplingCMesh::checkDeepEquivalWith : Meshes are not the same !"); +} + +/*! + * Nothing is done here (except to check that the other is a ParaMEDMEM::MEDCouplingCMesh instance too). + * The user intend that the nodes are the same, so by construction of ParaMEDMEM::MEDCouplingCMesh, \a this and \a other are the same ! + */ +void MEDCouplingCMesh::checkDeepEquivalOnSameNodesWith(const MEDCouplingMesh *other, int cellCompPol, double prec, + DataArrayInt *&cellCor) const +{ + if(!isEqualWithoutConsideringStr(other,prec)) + throw INTERP_KERNEL::Exception("MEDCouplingCMesh::checkDeepEquivalOnSameNodesWith : Meshes are not the same !"); +} + +void MEDCouplingCMesh::checkCoherency() const +{ + const char msg0[]="Invalid "; + const char msg1[]=" array ! Must contain more than 1 element."; + const char msg2[]=" array ! Must be with only one component."; + getSpaceDimension();// here to check that no holes in arrays ! + if(_x_array) + { + if(_x_array->getNbOfElems()<2) + { + std::ostringstream os; os << msg0 << 'X' << msg1; + throw INTERP_KERNEL::Exception(os.str().c_str()); + } + if(_x_array->getNumberOfComponents()!=1) + { + std::ostringstream os; os << msg0 << 'X' << msg2; + throw INTERP_KERNEL::Exception(os.str().c_str()); + } + } + if(_y_array) + { + if(_y_array->getNbOfElems()<2) + { + std::ostringstream os; os << msg0 << 'Y' << msg1; + throw INTERP_KERNEL::Exception(os.str().c_str()); + } + if(_y_array->getNumberOfComponents()!=1) + { + std::ostringstream os; os << msg0 << 'Y' << msg2; + throw INTERP_KERNEL::Exception(os.str().c_str()); + } + } + if(_z_array) + { + if(_z_array->getNbOfElems()<2) + { + std::ostringstream os; os << msg0 << 'Z' << msg1; + throw INTERP_KERNEL::Exception(os.str().c_str()); + } + if(_z_array->getNumberOfComponents()!=1) + { + std::ostringstream os; os << msg0 << 'Z' << msg2; + throw INTERP_KERNEL::Exception(os.str().c_str()); + } + } +} + +void MEDCouplingCMesh::checkCoherency1(double eps) const +{ + checkCoherency(); + if(_x_array) + _x_array->checkMonotonic(true, eps); + if(_y_array) + _y_array->checkMonotonic(true, eps); + if(_z_array) + _z_array->checkMonotonic(true, eps); +} + +void MEDCouplingCMesh::checkCoherency2(double eps) const +{ + checkCoherency1(eps); +} + +void MEDCouplingCMesh::getNodeGridStructure(int *res) const +{ + std::vector<int> ret(getNodeGridStructure()); + std::copy(ret.begin(),ret.end(),res); +} + +std::vector<int> MEDCouplingCMesh::getNodeGridStructure() const +{ + static const char MSG[]="MEDCouplingCMesh::getNodeGridStructure : mesh is invalid ! null vectors (X, Y or Z) must be put contiguously at the end !"; + std::vector<int> ret; + bool isOK(true); + if(_x_array) + { + if(!_x_array->isAllocated() || _x_array->getNumberOfComponents()!=1) + throw INTERP_KERNEL::Exception("MEDCouplingCMesh::getNodeGridStructure : X array exits but it is not allocated or with nb of components equal to one !"); + ret.push_back(_x_array->getNumberOfTuples()); + } + else + isOK=false; + if(_y_array) + { + if(!_y_array->isAllocated() || _y_array->getNumberOfComponents()!=1) + throw INTERP_KERNEL::Exception("MEDCouplingCMesh::getNodeGridStructure : Y array exits but it is not allocated or with nb of components equal to one !"); + if(!isOK) + throw INTERP_KERNEL::Exception(MSG); + ret.push_back(_y_array->getNumberOfTuples()); + } + else + isOK=false; + if(_z_array) + { + if(!_z_array->isAllocated() || _z_array->getNumberOfComponents()!=1) + throw INTERP_KERNEL::Exception("MEDCouplingCMesh::getNodeGridStructure : Z array exits but it is not allocated or with nb of components equal to one !"); + if(!isOK) + throw INTERP_KERNEL::Exception(MSG); + ret.push_back(_z_array->getNumberOfTuples()); + } + return ret; +} + +MEDCouplingStructuredMesh *MEDCouplingCMesh::buildStructuredSubPart(const std::vector< std::pair<int,int> >& cellPart) const +{ + checkCoherency(); + int dim(getSpaceDimension()); + if(dim!=(int)cellPart.size()) + { + std::ostringstream oss; oss << "MEDCouplingCMesh::buildStructuredSubPart : the space dimension is " << dim << " and cell part size is " << cellPart.size() << " !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + MEDCouplingAutoRefCountObjectPtr<MEDCouplingCMesh> ret(dynamic_cast<MEDCouplingCMesh *>(deepCpy())); + for(int i=0;i<dim;i++) + { + MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> tmp(ret->getCoordsAt(i)->selectByTupleId2(cellPart[i].first,cellPart[i].second+1,1)); + ret->setCoordsAt(i,tmp); + } + return ret.retn(); +} + +/*! + * Return the space dimension of \a this. It only considers the arrays along X, Y and Z to deduce that. + * This method throws exceptions if the not null arrays defining this are not contiguously at the end. For example X!=0,Y==0,Z!=0 will throw. + */ +int MEDCouplingCMesh::getSpaceDimension() const +{ + return (int)getNodeGridStructure().size(); +} + +void MEDCouplingCMesh::getCoordinatesOfNode(int nodeId, std::vector<double>& coo) const +{ + int tmp[3]; + int spaceDim=getSpaceDimension(); + getSplitNodeValues(tmp); + const DataArrayDouble *tabs[3]={getCoordsAt(0),getCoordsAt(1),getCoordsAt(2)}; + int tmp2[3]; + GetPosFromId(nodeId,spaceDim,tmp,tmp2); + for(int j=0;j<spaceDim;j++) + if(tabs[j]) + coo.push_back(tabs[j]->getConstPointer()[tmp2[j]]); +} + +std::string MEDCouplingCMesh::simpleRepr() const +{ + std::ostringstream ret; + ret << "Cartesian 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 << "Space dimension : " << getSpaceDimension() << "\n\nArrays :\n________\n\n"; + if(_x_array) + { + ret << "X Array :\n"; + _x_array->reprZipWithoutNameStream(ret); + } + if(_y_array) + { + ret << "Y Array :\n"; + _y_array->reprZipWithoutNameStream(ret); + } + if(_z_array) + { + ret << "Z Array :\n"; + _z_array->reprZipWithoutNameStream(ret); + } + return ret.str(); +} + +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]. + * + * \if ENABLE_EXAMPLES + * \ref cpp_mccmesh_getCoordsAt "Here is a C++ example".<br> + * \ref py_mccmesh_getCoordsAt "Here is a Python example". + * \endif + */ +const DataArrayDouble *MEDCouplingCMesh::getCoordsAt(int i) const +{ + switch(i) + { + case 0: + return _x_array; + case 1: + return _y_array; + case 2: + return _z_array; + default: + throw INTERP_KERNEL::Exception("Invalid rank specified must be 0 or 1 or 2."); + } +} + +/*! + * 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]. + * + * \if ENABLE_EXAMPLES + * \ref cpp_mccmesh_getCoordsAt "Here is a C++ example".<br> + * \ref py_mccmesh_getCoordsAt "Here is a Python example". + * \endif + */ +DataArrayDouble *MEDCouplingCMesh::getCoordsAt(int i) +{ + switch(i) + { + case 0: + return _x_array; + case 1: + return _y_array; + case 2: + return _z_array; + default: + throw INTERP_KERNEL::Exception("Invalid rank specified must be 0 or 1 or 2."); + } +} + +/*! + * 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]. + * + * \if ENABLE_EXAMPLES + * \ref medcouplingcppexamplesCmeshStdBuild1 "Here is a C++ example".<br> + * \ref medcouplingpyexamplesCmeshStdBuild1 "Here is a Python example". + * \endif + */ +void MEDCouplingCMesh::setCoordsAt(int i, const DataArrayDouble *arr) +{ + if(arr) + arr->checkNbOfComps(1,"MEDCouplingCMesh::setCoordsAt"); + DataArrayDouble **thisArr[3]={&_x_array,&_y_array,&_z_array}; + if(i<0 || i>2) + throw INTERP_KERNEL::Exception("Invalid rank specified must be 0 or 1 or 2."); + if(arr!=*(thisArr[i])) + { + if(*(thisArr[i])) + (*(thisArr[i]))->decrRef(); + (*(thisArr[i]))=const_cast<DataArrayDouble *>(arr); + if(*(thisArr[i])) + (*(thisArr[i]))->incrRef(); + declareAsNew(); + } +} + +/*! + * 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. + * + * \if ENABLE_EXAMPLES + * \ref medcouplingcppexamplesCmeshStdBuild1 "Here is a C++ example".<br> + * \ref medcouplingpyexamplesCmeshStdBuild1 "Here is a Python example". + * \endif + */ +void MEDCouplingCMesh::setCoords(const DataArrayDouble *coordsX, const DataArrayDouble *coordsY, const DataArrayDouble *coordsZ) +{ + if(coordsX) + coordsX->checkNbOfComps(1,"MEDCouplingCMesh::setCoords : coordsX"); + if(coordsY) + coordsY->checkNbOfComps(1,"MEDCouplingCMesh::setCoords : coordsY"); + if(coordsZ) + coordsZ->checkNbOfComps(1,"MEDCouplingCMesh::setCoords : coordsZ"); + if(_x_array) + _x_array->decrRef(); + _x_array=const_cast<DataArrayDouble *>(coordsX); + if(_x_array) + _x_array->incrRef(); + if(_y_array) + _y_array->decrRef(); + _y_array=const_cast<DataArrayDouble *>(coordsY); + if(_y_array) + _y_array->incrRef(); + if(_z_array) + _z_array->decrRef(); + _z_array=const_cast<DataArrayDouble *>(coordsZ); + if(_z_array) + _z_array->incrRef(); + declareAsNew(); +} + +void MEDCouplingCMesh::getBoundingBox(double *bbox) const +{ + int dim=getSpaceDimension(); + int j=0; + for (int idim=0; idim<dim; idim++) + { + const DataArrayDouble *c=getCoordsAt(idim); + if(c) + { + const double *coords=c->getConstPointer(); + int nb=c->getNbOfElems(); + bbox[2*j]=coords[0]; + bbox[2*j+1]=coords[nb-1]; + j++; + } + } +} + +/*! + * Returns a new MEDCouplingFieldDouble containing volumes of cells constituting \a this + * mesh.<br> + * For 1D cells, the returned field contains lengths.<br> + * For 2D cells, the returned field contains areas.<br> + * 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,ONE_TIME); + field->setName(name); + DataArrayDouble* array=DataArrayDouble::New(); + array->alloc(nbelem,1); + double *area_vol=array->getPointer(); + field->setArray(array) ; + array->decrRef(); + field->setMesh(const_cast<MEDCouplingCMesh *>(this)); + field->synchronizeTimeWithMesh(); + int tmp[3]; + getSplitCellValues(tmp); + int dim=getSpaceDimension(); + const double **thisArr=new const double *[dim]; + const DataArrayDouble *thisArr2[3]={_x_array,_y_array,_z_array}; + for(int i=0;i<dim;i++) + thisArr[i]=thisArr2[i]->getConstPointer(); + for(int icell=0;icell<nbelem;icell++) + { + int tmp2[3]; + GetPosFromId(icell,dim,tmp,tmp2); + area_vol[icell]=1.; + for(int i=0;i<dim;i++) + area_vol[icell]*=thisArr[i][tmp2[i]+1]-thisArr[i][tmp2[i]]; + } + delete [] thisArr; + return field; +} + +/*! + * not implemented yet ! + */ +MEDCouplingFieldDouble *MEDCouplingCMesh::getMeasureFieldOnNode(bool isAbs) const +{ + throw INTERP_KERNEL::Exception("MEDCouplingCMesh::getMeasureFieldOnNode : not implemented yet !"); + //return 0; +} + +int MEDCouplingCMesh::getCellContainingPoint(const double *pos, double eps) const +{ + int dim=getSpaceDimension(); + int ret=0; + int coeff=1; + for(int i=0;i<dim;i++) + { + const double *d=getCoordsAt(i)->getConstPointer(); + int nbOfNodes=getCoordsAt(i)->getNbOfElems(); + double ref=pos[i]; + const double *w=std::find_if(d,d+nbOfNodes,std::bind2nd(std::greater_equal<double>(),ref)); + int w2=(int)std::distance(d,w); + if(w2<nbOfNodes) + { + if(w2==0) + { + if(ref>d[0]-eps) + w2=1; + else + return -1; + } + ret+=coeff*(w2-1); + coeff*=nbOfNodes-1; + } + else + return -1; + } + return ret; +} + +void MEDCouplingCMesh::rotate(const double *center, const double *vector, double angle) +{ + throw INTERP_KERNEL::Exception("No rotation available on CMesh : Traduce it to untructured mesh 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) + std::transform(_x_array->getConstPointer(),_x_array->getConstPointer()+_x_array->getNbOfElems(), + _x_array->getPointer(),std::bind2nd(std::plus<double>(),vector[0])); + if(_y_array) + std::transform(_y_array->getConstPointer(),_y_array->getConstPointer()+_y_array->getNbOfElems(), + _y_array->getPointer(),std::bind2nd(std::plus<double>(),vector[1])); + if(_z_array) + std::transform(_z_array->getConstPointer(),_z_array->getConstPointer()+_z_array->getNbOfElems(), + _z_array->getPointer(),std::bind2nd(std::plus<double>(),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++) + { + DataArrayDouble *c=getCoordsAt(i); + if(c) + { + double *coords=c->getPointer(); + int lgth=c->getNbOfElems(); + std::transform(coords,coords+lgth,coords,std::bind2nd(std::minus<double>(),point[i])); + std::transform(coords,coords+lgth,coords,std::bind2nd(std::multiplies<double>(),factor)); + std::transform(coords,coords+lgth,coords,std::bind2nd(std::plus<double>(),point[i])); + c->declareAsNew(); + } + } + updateTime(); +} + +MEDCouplingMesh *MEDCouplingCMesh::mergeMyselfWith(const MEDCouplingMesh *other) const +{ + //not implemented yet ! + 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(); + int spaceDim=getSpaceDimension(); + int nbNodes=getNumberOfNodes(); + ret->alloc(nbNodes,spaceDim); + double *pt=ret->getPointer(); + int tmp[3]; + getSplitNodeValues(tmp); + const DataArrayDouble *tabs[3]={getCoordsAt(0),getCoordsAt(1),getCoordsAt(2)}; + const double *tabsPtr[3]; + for(int j=0;j<spaceDim;j++) + { + tabsPtr[j]=tabs[j]->getConstPointer(); + ret->setInfoOnComponent(j,tabs[j]->getInfoOnComponent(0)); + } + int tmp2[3]; + for(int i=0;i<nbNodes;i++) + { + GetPosFromId(i,spaceDim,tmp,tmp2); + for(int j=0;j<spaceDim;j++) + pt[i*spaceDim+j]=tabsPtr[j][tmp2[j]]; + } + 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(); + int spaceDim=getSpaceDimension(); + int nbCells=getNumberOfCells(); + ret->alloc(nbCells,spaceDim); + double *pt=ret->getPointer(); + int tmp[3]; + getSplitCellValues(tmp); + const DataArrayDouble *tabs[3]={getCoordsAt(0),getCoordsAt(1),getCoordsAt(2)}; + std::vector<double> tabsPtr[3]; + for(int j=0;j<spaceDim;j++) + { + int sz=tabs[j]->getNbOfElems()-1; + ret->setInfoOnComponent(j,tabs[j]->getInfoOnComponent(0)); + const double *srcPtr=tabs[j]->getConstPointer(); + tabsPtr[j].insert(tabsPtr[j].end(),srcPtr,srcPtr+sz); + std::transform(tabsPtr[j].begin(),tabsPtr[j].end(),srcPtr+1,tabsPtr[j].begin(),std::plus<double>()); + std::transform(tabsPtr[j].begin(),tabsPtr[j].end(),tabsPtr[j].begin(),std::bind2nd(std::multiplies<double>(),0.5)); + } + int tmp2[3]; + for(int i=0;i<nbCells;i++) + { + GetPosFromId(i,spaceDim,tmp,tmp2); + for(int j=0;j<spaceDim;j++) + pt[i*spaceDim+j]=tabsPtr[j][tmp2[j]]; + } + return ret; +} + +DataArrayDouble *MEDCouplingCMesh::computeIsoBarycenterOfNodesPerCell() const +{ + return MEDCouplingCMesh::getBarycenterAndOwner(); +} + +void MEDCouplingCMesh::renumberCells(const int *old2NewBg, bool check) +{ + throw INTERP_KERNEL::Exception("Functionnality of renumbering cell not available for CMesh !"); +} + +void MEDCouplingCMesh::getTinySerializationInformation(std::vector<double>& tinyInfoD, std::vector<int>& tinyInfo, std::vector<std::string>& 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()); + const DataArrayDouble *thisArr[3]={_x_array,_y_array,_z_array}; + for(int i=0;i<3;i++) + { + int val=-1; + std::string st; + if(thisArr[i]) + { + val=thisArr[i]->getNumberOfTuples(); + st=thisArr[i]->getInfoOnComponent(0); + } + tinyInfo.push_back(val); + littleStrings.push_back(st); + } + tinyInfo.push_back(it); + tinyInfo.push_back(order); + tinyInfoD.push_back(time); +} + +void MEDCouplingCMesh::resizeForUnserialization(const std::vector<int>& tinyInfo, DataArrayInt *a1, DataArrayDouble *a2, std::vector<std::string>& littleStrings) const +{ + a1->alloc(0,1); + int sum=0; + for(int i=0;i<3;i++) + if(tinyInfo[i]!=-1) + sum+=tinyInfo[i]; + a2->alloc(sum,1); +} + +void MEDCouplingCMesh::serialize(DataArrayInt *&a1, DataArrayDouble *&a2) const +{ + a1=DataArrayInt::New(); + a1->alloc(0,1); + const DataArrayDouble *thisArr[3]={_x_array,_y_array,_z_array}; + int sz=0; + for(int i=0;i<3;i++) + { + if(thisArr[i]) + sz+=thisArr[i]->getNumberOfTuples(); + } + a2=DataArrayDouble::New(); + a2->alloc(sz,1); + double *a2Ptr=a2->getPointer(); + for(int i=0;i<3;i++) + if(thisArr[i]) + a2Ptr=std::copy(thisArr[i]->getConstPointer(),thisArr[i]->getConstPointer()+thisArr[i]->getNumberOfTuples(),a2Ptr); +} + +void MEDCouplingCMesh::unserialization(const std::vector<double>& tinyInfoD, const std::vector<int>& tinyInfo, const DataArrayInt *a1, DataArrayDouble *a2, + const std::vector<std::string>& littleStrings) +{ + setName(littleStrings[0]); + setDescription(littleStrings[1]); + setTimeUnit(littleStrings[2]); + DataArrayDouble **thisArr[3]={&_x_array,&_y_array,&_z_array}; + const double *data=a2->getConstPointer(); + for(int i=0;i<3;i++) + { + if(tinyInfo[i]!=-1) + { + (*(thisArr[i]))=DataArrayDouble::New(); + (*(thisArr[i]))->alloc(tinyInfo[i],1); + (*(thisArr[i]))->setInfoOnComponent(0,littleStrings[i+3]); + std::copy(data,data+tinyInfo[i],(*(thisArr[i]))->getPointer()); + data+=tinyInfo[i]; + } + } + setTime(tinyInfoD[0],tinyInfo[3],tinyInfo[4]); +} + +void MEDCouplingCMesh::writeVTKLL(std::ostream& ofs, const std::string& cellData, const std::string& pointData, DataArrayByte *byteData) const +{ + 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 << " <Piece Extent=\"" << extent.str() << "\">\n"; + ofs << " <PointData>\n" << pointData << std::endl; + ofs << " </PointData>\n"; + ofs << " <CellData>\n" << cellData << std::endl; + ofs << " </CellData>\n"; + ofs << " <Coordinates>\n"; + for(int i=0;i<3;i++) + { + if(thisArr[i]) + thisArr[i]->writeVTK(ofs,8,"Array",byteData); + else + { + MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> coo=DataArrayDouble::New(); coo->alloc(1,1); + coo->setIJ(0,0,0.); + coo->writeVTK(ofs,8,"Array",byteData); + } + } + ofs << " </Coordinates>\n"; + ofs << " </Piece>\n"; + ofs << " </" << getVTKDataSetType() << ">\n"; +} + +void MEDCouplingCMesh::reprQuickOverview(std::ostream& stream) const +{ + 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::getVTKFileExtension() const +{ + return std::string("vtr"); +} + +std::string MEDCouplingCMesh::getVTKDataSetType() const +{ + return std::string("RectilinearGrid"); +} diff --git a/src/medtool/src/MEDCoupling/MEDCouplingCMesh.hxx b/src/medtool/src/MEDCoupling/MEDCouplingCMesh.hxx new file mode 100644 index 000000000..81811212f --- /dev/null +++ b/src/medtool/src/MEDCoupling/MEDCouplingCMesh.hxx @@ -0,0 +1,98 @@ +// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 +// 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_MEDCOUPLINGCMESH_HXX__ +#define __PARAMEDMEM_MEDCOUPLINGCMESH_HXX__ + +#include "MEDCoupling.hxx" +#include "MEDCouplingStructuredMesh.hxx" + +namespace ParaMEDMEM +{ + class MEDCouplingCMesh : public MEDCouplingStructuredMesh + { + public: + MEDCOUPLING_EXPORT static MEDCouplingCMesh *New(); + MEDCOUPLING_EXPORT static MEDCouplingCMesh *New(const std::string& meshName); + MEDCOUPLING_EXPORT MEDCouplingMesh *deepCpy() const; + MEDCOUPLING_EXPORT MEDCouplingCMesh *clone(bool recDeepCpy) const; + MEDCOUPLING_EXPORT void updateTime() const; + MEDCOUPLING_EXPORT std::size_t getHeapMemorySizeWithoutChildren() const; + MEDCOUPLING_EXPORT std::vector<const BigMemoryObject *> getDirectChildrenWithNull() const; + MEDCOUPLING_EXPORT MEDCouplingMeshType getType() const { return CARTESIAN; } + MEDCOUPLING_EXPORT void copyTinyStringsFrom(const MEDCouplingMesh *other); + MEDCOUPLING_EXPORT bool isEqualIfNotWhy(const MEDCouplingMesh *other, double prec, std::string& reason) const; + MEDCOUPLING_EXPORT bool isEqualWithoutConsideringStr(const MEDCouplingMesh *other, double prec) const; + MEDCOUPLING_EXPORT void checkDeepEquivalWith(const MEDCouplingMesh *other, int cellCompPol, double prec, + DataArrayInt *&cellCor, DataArrayInt *&nodeCor) const; + MEDCOUPLING_EXPORT void checkDeepEquivalOnSameNodesWith(const MEDCouplingMesh *other, int cellCompPol, double prec, + DataArrayInt *&cellCor) const; + MEDCOUPLING_EXPORT void checkCoherency() const; + MEDCOUPLING_EXPORT void checkCoherency1(double eps=1e-12) const; + MEDCOUPLING_EXPORT void checkCoherency2(double eps=1e-12) const; + MEDCOUPLING_EXPORT int getSpaceDimension() const; + MEDCOUPLING_EXPORT void getCoordinatesOfNode(int nodeId, std::vector<double>& coo) const; + MEDCOUPLING_EXPORT std::string simpleRepr() const; + MEDCOUPLING_EXPORT std::string advancedRepr() const; + MEDCOUPLING_EXPORT const DataArrayDouble *getCoordsAt(int i) const; + MEDCOUPLING_EXPORT DataArrayDouble *getCoordsAt(int i); + MEDCOUPLING_EXPORT void setCoordsAt(int i, const DataArrayDouble *arr); + MEDCOUPLING_EXPORT void setCoords(const DataArrayDouble *coordsX, + const DataArrayDouble *coordsY=0, + const DataArrayDouble *coordsZ=0); + // tools + MEDCOUPLING_EXPORT void getBoundingBox(double *bbox) const; + MEDCOUPLING_EXPORT MEDCouplingFieldDouble *getMeasureField(bool isAbs) const; + MEDCOUPLING_EXPORT MEDCouplingFieldDouble *getMeasureFieldOnNode(bool isAbs) const; + MEDCOUPLING_EXPORT int getCellContainingPoint(const double *pos, double eps) const; + MEDCOUPLING_EXPORT void rotate(const double *center, const double *vector, double angle); + MEDCOUPLING_EXPORT void translate(const double *vector); + MEDCOUPLING_EXPORT void scale(const double *point, double factor); + MEDCOUPLING_EXPORT MEDCouplingMesh *mergeMyselfWith(const MEDCouplingMesh *other) const; + MEDCOUPLING_EXPORT DataArrayDouble *getCoordinatesAndOwner() const; + MEDCOUPLING_EXPORT DataArrayDouble *getBarycenterAndOwner() const; + MEDCOUPLING_EXPORT DataArrayDouble *computeIsoBarycenterOfNodesPerCell() const; + MEDCOUPLING_EXPORT void renumberCells(const int *old2NewBg, bool check=true); + //some useful methods + MEDCOUPLING_EXPORT void getNodeGridStructure(int *res) const; + MEDCOUPLING_EXPORT std::vector<int> getNodeGridStructure() const; + MEDCouplingStructuredMesh *buildStructuredSubPart(const std::vector< std::pair<int,int> >& cellPart) const; + //serialisation-unserialization + MEDCOUPLING_EXPORT void getTinySerializationInformation(std::vector<double>& tinyInfoD, std::vector<int>& tinyInfo, std::vector<std::string>& littleStrings) const; + MEDCOUPLING_EXPORT void resizeForUnserialization(const std::vector<int>& tinyInfo, DataArrayInt *a1, DataArrayDouble *a2, std::vector<std::string>& littleStrings) const; + MEDCOUPLING_EXPORT void serialize(DataArrayInt *&a1, DataArrayDouble *&a2) const; + MEDCOUPLING_EXPORT void unserialization(const std::vector<double>& tinyInfoD, const std::vector<int>& tinyInfo, const DataArrayInt *a1, DataArrayDouble *a2, + const std::vector<std::string>& littleStrings); + MEDCOUPLING_EXPORT void reprQuickOverview(std::ostream& stream) const; + MEDCOUPLING_EXPORT std::string getVTKFileExtension() const; + private: + MEDCouplingCMesh(); + MEDCouplingCMesh(const MEDCouplingCMesh& other, bool deepCpy); + ~MEDCouplingCMesh(); + void writeVTKLL(std::ostream& ofs, const std::string& cellData, const std::string& pointData, DataArrayByte *byteData) const; + std::string getVTKDataSetType() const; + private: + DataArrayDouble *_x_array; + DataArrayDouble *_y_array; + DataArrayDouble *_z_array; + }; +} + +#endif diff --git a/src/medtool/src/MEDCoupling/MEDCouplingCartesianAMRMesh.cxx b/src/medtool/src/MEDCoupling/MEDCouplingCartesianAMRMesh.cxx new file mode 100644 index 000000000..cf8a37b37 --- /dev/null +++ b/src/medtool/src/MEDCoupling/MEDCouplingCartesianAMRMesh.cxx @@ -0,0 +1,1978 @@ +// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 +// 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 + +#include "MEDCouplingCartesianAMRMesh.hxx" +#include "MEDCouplingAMRAttribute.hxx" +#include "MEDCouplingFieldDouble.hxx" +#include "MEDCoupling1GTUMesh.hxx" +#include "MEDCouplingIMesh.hxx" +#include "MEDCouplingUMesh.hxx" + +#include <limits> +#include <sstream> +#include <numeric> + +using namespace ParaMEDMEM; + +/// @cond INTERNAL + +int MEDCouplingCartesianAMRPatchGen::getNumberOfCellsRecursiveWithOverlap() const +{ + return _mesh->getNumberOfCellsRecursiveWithOverlap(); +} + +int MEDCouplingCartesianAMRPatchGen::getNumberOfCellsRecursiveWithoutOverlap() const +{ + return _mesh->getNumberOfCellsRecursiveWithoutOverlap(); +} + +int MEDCouplingCartesianAMRPatchGen::getMaxNumberOfLevelsRelativeToThis() const +{ + return _mesh->getMaxNumberOfLevelsRelativeToThis(); +} + +MEDCouplingCartesianAMRPatchGen::MEDCouplingCartesianAMRPatchGen(MEDCouplingCartesianAMRMeshGen *mesh) +{ + if(!mesh) + throw INTERP_KERNEL::Exception("MEDCouplingCartesianAMRPatchGen constructor : input mesh is NULL !"); + _mesh=mesh; _mesh->incrRef(); +} + +MEDCouplingCartesianAMRPatchGen::MEDCouplingCartesianAMRPatchGen(const MEDCouplingCartesianAMRPatchGen& other, MEDCouplingCartesianAMRMeshGen *father):RefCountObject(other),_mesh(other._mesh) +{ + const MEDCouplingCartesianAMRMeshGen *mesh(other._mesh); + if(mesh) + _mesh=mesh->deepCpy(father); +} + +const MEDCouplingCartesianAMRMeshGen *MEDCouplingCartesianAMRPatchGen::getMeshSafe() const +{ + const MEDCouplingCartesianAMRMeshGen *mesh(_mesh); + if(!mesh) + throw INTERP_KERNEL::Exception("MEDCouplingCartesianAMRPatchGen::getMeshSafe const : the mesh is NULL !"); + return mesh; +} + +MEDCouplingCartesianAMRMeshGen *MEDCouplingCartesianAMRPatchGen::getMeshSafe() +{ + MEDCouplingCartesianAMRMeshGen *mesh(_mesh); + if(!mesh) + throw INTERP_KERNEL::Exception("MEDCouplingCartesianAMRPatchGen::getMeshSafe : the mesh is NULL !"); + return mesh; +} + +std::vector<const BigMemoryObject *> MEDCouplingCartesianAMRPatchGen::getDirectChildrenWithNull() const +{ + std::vector<const BigMemoryObject *> ret; + ret.push_back((const MEDCouplingCartesianAMRMeshGen *)_mesh); + return ret; +} + +/*! + * \param [in] mesh not null pointer of refined mesh replacing the cell range of \a father defined by the bottom left and top right just after. + * \param [in] bottomLeftTopRight a vector equal to the space dimension of \a mesh that specifies for each dimension, the included cell start of the range for the first element of the pair, + * a the end cell (\b excluded) of the range for the second element of the pair. + */ +MEDCouplingCartesianAMRPatch::MEDCouplingCartesianAMRPatch(MEDCouplingCartesianAMRMeshGen *mesh, const std::vector< std::pair<int,int> >& bottomLeftTopRight):MEDCouplingCartesianAMRPatchGen(mesh),_bl_tr(bottomLeftTopRight) +{ + int dim((int)bottomLeftTopRight.size()),dimExp(_mesh->getSpaceDimension()); + if(dim!=dimExp) + throw INTERP_KERNEL::Exception("MEDCouplingCartesianAMRPatch constructor : space dimension of father and input bottomLeft/topRight size mismatches !"); +} + +MEDCouplingCartesianAMRPatch *MEDCouplingCartesianAMRPatch::deepCpy(MEDCouplingCartesianAMRMeshGen *father) const +{ + return new MEDCouplingCartesianAMRPatch(*this,father); +} + +void MEDCouplingCartesianAMRPatch::addPatch(const std::vector< std::pair<int,int> >& bottomLeftTopRight, const std::vector<int>& factors) +{ + return getMeshSafe()->addPatch(bottomLeftTopRight,factors); +} + +int MEDCouplingCartesianAMRPatch::getNumberOfOverlapedCellsForFather() const +{ + return MEDCouplingStructuredMesh::DeduceNumberOfGivenRangeInCompactFrmt(_bl_tr); +} + +/*! + * This method states if \a other patch is in the neighborhood of \a this. The neighborhood zone is defined by \a ghostLev parameter + * the must be >= 0. \b WARNING this method only works if \a this and \a other share the same father (no check of this will be done !). + * Call isInMyNeighborhoodExt to deal with 2 patches not sharing directly the same father. + * + * \param [in] other - The other patch + * \param [in] ghostLev - The size of the neighborhood zone. + * + * \throw if \a this or \a other are invalid (end before start). + * \throw if \a ghostLev is \b not >= 0 . + * \throw if \a this and \a other have not the same space dimension. + * + * \sa isInMyNeighborhoodExt + */ +bool MEDCouplingCartesianAMRPatch::isInMyNeighborhood(const MEDCouplingCartesianAMRPatch *other, int ghostLev) const +{ + if(ghostLev<0) + throw INTERP_KERNEL::Exception("MEDCouplingCartesianAMRPatch::isInMyNeighborhood : the size of the neighborhood must be >= 0 !"); + if(!other) + throw INTERP_KERNEL::Exception("MEDCouplingCartesianAMRPatch::isInMyNeighborhood : the input patch is NULL !"); + const std::vector< std::pair<int,int> >& thisp(getBLTRRange()); + const std::vector< std::pair<int,int> >& otherp(other->getBLTRRange()); + return IsInMyNeighborhood(ghostLev==0?0:1,thisp,otherp);//make hypothesis that nb this->_mesh->getFather->getFactors() is >= ghostLev +} + +/*! + * This method states if \a other patch is in the neighborhood of \a this. The neighborhood zone is defined by \a ghostLev parameter + * the must be >= 0. This method works even if \a this and \a other does not share the same father. But the level between their common + * ancestor must be the same. If they don't have the same ancestor an exception will be thrown. + * + * \param [in] other - The other patch + * \param [in] ghostLev - The size of the neighborhood zone. + * + * \throw if \a this or \a other are invalid (end before start). + * \throw if \a ghostLev is \b not >= 0 . + * \throw if \a this and \a other have not the same space dimension. + * \throw if there is not common ancestor of \a this and \a other. + * + * \sa isInMyNeighborhood, isInMyNeighborhoodDiffLev + */ +bool MEDCouplingCartesianAMRPatch::isInMyNeighborhoodExt(const MEDCouplingCartesianAMRPatch *other, int ghostLev) const +{ + if(ghostLev<0) + throw INTERP_KERNEL::Exception("MEDCouplingCartesianAMRPatch::isInMyNeighborhoodExt : the size of the neighborhood must be >= 0 !"); + if(!other) + throw INTERP_KERNEL::Exception("MEDCouplingCartesianAMRPatch::isInMyNeighborhoodExt : the input patch is NULL !"); + int lev; + const MEDCouplingCartesianAMRMeshGen *com(FindCommonAncestor(this,other,lev));//check that factors are OK + if(lev==0) + return isInMyNeighborhood(other,ghostLev); + std::vector<int> offset(ComputeOffsetFromTwoToOne(com,lev,this,other)); + const std::vector< std::pair<int,int> >& thisp(getBLTRRange()); + std::vector< std::pair<int,int> > otherp(other->getBLTRRange()); + otherp=MEDCouplingStructuredMesh::TranslateCompactFrmt(otherp,offset); + return IsInMyNeighborhood(ghostLev,thisp,otherp); +} + +/*! + * This method states if \a other patch is in the neighborhood of \a this. The neighborhood zone is defined by \a ghostLev parameter + * the must be >= 0. This method works even if \a this and \a other does not share the same father. + * \a this is expected to be more refined than \a other. That is to say lev of \a this is greater than level of \a other. + * + * \param [in] other - The other patch + * \param [in] ghostLev - The size of the neighborhood zone. + * + * \throw if \a this or \a other are invalid (end before start). + * \throw if \a ghostLev is \b not >= 0 . + * \throw if \a this and \a other have not the same space dimension. + * \throw if there is not common ancestor of \a this and \a other. + * + * \sa isInMyNeighborhoodExt + */ +bool MEDCouplingCartesianAMRPatch::isInMyNeighborhoodDiffLev(const MEDCouplingCartesianAMRPatch *other, int ghostLev) const +{ + std::vector< std::pair<int,int> > thispp,otherpp; + std::vector<int> factors; + ComputeZonesOfTwoRelativeToOneDiffLev(ghostLev,this,other,thispp,otherpp,factors); + return IsInMyNeighborhood(ghostLev>0?1:0,thispp,otherpp);//1 not ghostLev ! It is not a bug ( I hope :) ) ! Because as \a this is a refinement of \a other ghostLev is supposed to be <= factors +} + +std::vector< std::pair<int,int> > MEDCouplingCartesianAMRPatch::getBLTRRangeRelativeToGF() const +{ + std::vector< std::pair<int,int> > ret(_bl_tr); + const MEDCouplingCartesianAMRMeshGen *mesh(getMesh()); + if(!mesh) + throw INTERP_KERNEL::Exception("MEDCouplingCartesianAMRPatch::getBLTRRangeRelativeToGF : not valid !"); + const MEDCouplingCartesianAMRMeshGen *fath(mesh->getFather()); + if(!fath) + throw INTERP_KERNEL::Exception("MEDCouplingCartesianAMRPatch::getBLTRRangeRelativeToGF : not valid 2 !"); + std::vector<int> factors(fath->getFactors()); + std::size_t sz(ret.size()); + for(std::size_t ii=0;ii<sz;ii++) + { + ret[ii].first*=factors[ii]; + ret[ii].second*=factors[ii]; + } + const MEDCouplingCartesianAMRMeshGen *oldFather(fath); + fath=oldFather->getFather(); + while(fath) + { + int pos(fath->getPatchIdFromChildMesh(oldFather)); + const MEDCouplingCartesianAMRPatch *p(fath->getPatch(pos)); + const std::vector< std::pair<int,int> >& tmp(p->getBLTRRange()); + const std::vector<int>& factors2(fath->getFactors()); + std::transform(factors.begin(),factors.end(),factors2.begin(),factors.begin(),std::multiplies<int>()); + for(std::size_t ii=0;ii<sz;ii++) + { + int delta(ret[ii].second-ret[ii].first); + ret[ii].first+=tmp[ii].first*factors[ii]; + ret[ii].second=ret[ii].first+delta; + } + oldFather=fath; + fath=oldFather->getFather(); + } + return ret; +} + +std::vector<int> MEDCouplingCartesianAMRPatch::computeCellGridSt() const +{ + const MEDCouplingCartesianAMRMeshGen *m(getMesh()); + if(!m) + throw INTERP_KERNEL::Exception("MEDCouplingCartesianAMRPatch::computeCellGridSt : no mesh held by this !"); + const MEDCouplingCartesianAMRMeshGen *father(m->getFather()); + if(!father) + throw INTERP_KERNEL::Exception("MEDCouplingCartesianAMRPatch::computeCellGridSt : no father help by underlying mesh !"); + const std::vector< std::pair<int,int> >& bltr(getBLTRRange()); + const std::vector<int>& factors(father->getFactors()); + std::vector<int> ret(MEDCouplingStructuredMesh::GetDimensionsFromCompactFrmt(bltr)); + std::transform(ret.begin(),ret.end(),factors.begin(),ret.begin(),std::multiplies<int>()); + return ret; +} + +bool MEDCouplingCartesianAMRPatch::IsInMyNeighborhood(int ghostLev, const std::vector< std::pair<int,int> >& p1, const std::vector< std::pair<int,int> >& p2) +{ + std::size_t thispsize(p1.size()); + if(thispsize!=p2.size()) + throw INTERP_KERNEL::Exception("MEDCouplingCartesianAMRPatch::isInMyNeighborhood : the dimensions must be the same !"); + for(std::size_t i=0;i<thispsize;i++) + { + const std::pair<int,int>& thispp(p1[i]); + const std::pair<int,int>& otherpp(p2[i]); + if(thispp.second<thispp.first) + throw INTERP_KERNEL::Exception("MEDCouplingCartesianAMRPatch::isInMyNeighborhood : this patch is invalid !"); + if(otherpp.second<otherpp.first) + throw INTERP_KERNEL::Exception("MEDCouplingCartesianAMRPatch::isInMyNeighborhood : this patch is invalid !"); + if(otherpp.first==thispp.second+ghostLev-1) + continue; + if(otherpp.second+ghostLev-1==thispp.first) + continue; + int start(std::max(thispp.first,otherpp.first)),end(std::min(thispp.second,otherpp.second)); + if(end<start) + return false; + } + return true; +} + +/*! + * \sa FindNeighborsOfSubPatchesOf + */ +std::vector< std::vector< std::pair<const MEDCouplingCartesianAMRPatch *,const MEDCouplingCartesianAMRPatch *> > > MEDCouplingCartesianAMRPatch::FindNeighborsOfSubPatchesOfSameLev(int ghostLev, const MEDCouplingCartesianAMRPatch *p1, const MEDCouplingCartesianAMRPatch *p2) +{ + if(!p1 || !p2) + throw INTERP_KERNEL::Exception("MEDCouplingCartesianAMRPatch::FindNeighborsOfSubPatchesOfSameLev : the input pointers must be not NULL !"); + std::vector< std::vector< std::pair<const MEDCouplingCartesianAMRPatch *,const MEDCouplingCartesianAMRPatch *> > > ret; + std::vector< const MEDCouplingCartesianAMRPatch *> p1Work(p1->getMesh()->getPatches()),p2Work(p2->getMesh()->getPatches()); + while(!p1Work.empty()) + { + std::vector< std::pair<const MEDCouplingCartesianAMRPatch *,const MEDCouplingCartesianAMRPatch *> > retTmp; + std::vector<const MEDCouplingCartesianAMRPatch *> p1Work2,p2Work2; + for(std::vector<const MEDCouplingCartesianAMRPatch *>::const_iterator it1=p1Work.begin();it1!=p1Work.end();it1++) + { + for(std::vector<const MEDCouplingCartesianAMRPatch *>::const_iterator it2=p2Work.begin();it2!=p2Work.end();it2++) + { + if((*it1)->isInMyNeighborhoodExt(*it2,ghostLev>0?1:0))//1 not ghostLev ! It is not a bug ( I hope :) ) ! Because as \a this is a refinement of \a other ghostLev is supposed to be <= factors + retTmp.push_back(std::pair<const MEDCouplingCartesianAMRPatch *,const MEDCouplingCartesianAMRPatch *>(*it1,*it2)); + } + std::vector<const MEDCouplingCartesianAMRPatch *> tmp1((*it1)->getMesh()->getPatches()); + p1Work2.insert(p1Work2.end(),tmp1.begin(),tmp1.end()); + } + for(std::vector<const MEDCouplingCartesianAMRPatch *>::const_iterator it2=p2Work.begin();it2!=p2Work.end();it2++) + { + std::vector<const MEDCouplingCartesianAMRPatch *> tmp2((*it2)->getMesh()->getPatches()); + p2Work2.insert(p2Work2.end(),tmp2.begin(),tmp2.end()); + } + ret.push_back(retTmp); + p1Work=p1Work2; + p2Work=p2Work2; + } + return ret; +} + +/*! + * This method returns all pair of patches (pa,pb) so that pb is in the neighborhood of pa (size of neighborhood is \a ghostLev). + * pa is a refinement (a child) of \b p1 and pb is equal to \a p2. So the returned pair do not have the same level as it is the case for + * FindNeighborsOfSubPatchesOfSameLev. + * + * \sa FindNeighborsOfSubPatchesOfSameLev + */ +void MEDCouplingCartesianAMRPatch::FindNeighborsOfSubPatchesOf(int ghostLev, const MEDCouplingCartesianAMRPatch *p1, const MEDCouplingCartesianAMRPatch *p2, std::vector< std::pair<const MEDCouplingCartesianAMRPatch *, const MEDCouplingCartesianAMRPatch *> >& ret) +{ + if(!p1 || !p2) + throw INTERP_KERNEL::Exception("MEDCouplingCartesianAMRPatch::FindNeighborsOfSubPatchesOf : the input pointers must be not NULL !"); + std::vector< const MEDCouplingCartesianAMRPatch *> p1Work(p1->getMesh()->getPatches()); + while(!p1Work.empty()) + { + std::vector<const MEDCouplingCartesianAMRPatch *> p1Work2; + for(std::vector<const MEDCouplingCartesianAMRPatch *>::const_iterator it0=p1Work.begin();it0!=p1Work.end();it0++) + { + if((*it0)->isInMyNeighborhoodDiffLev(p2,ghostLev)) + ret.push_back(std::pair<const MEDCouplingCartesianAMRPatch *,const MEDCouplingCartesianAMRPatch *>(*it0,p2)); + std::vector<const MEDCouplingCartesianAMRPatch *> tmp2((*it0)->getMesh()->getPatches()); + p1Work2.insert(p1Work2.end(),tmp2.begin(),tmp2.end()); + } + p1Work=p1Work2; + } +} + +/*! + * \a p1 and \a p2 are expected to be neighbors (inside the \a ghostLev zone). This method updates \a dataOnP1 only in the ghost part using a part of \a dataOnP2. + * + * \saUpdateNeighborsOfOneWithTwoExt + */ +void MEDCouplingCartesianAMRPatch::UpdateNeighborsOfOneWithTwo(int ghostLev, const std::vector<int>& factors, const MEDCouplingCartesianAMRPatch *p1, const MEDCouplingCartesianAMRPatch *p2, DataArrayDouble *dataOnP1, const DataArrayDouble *dataOnP2) +{ + const std::vector< std::pair<int,int> >& p1BLTR(p1->getBLTRRange()); + const std::vector< std::pair<int,int> >& p2BLTR(p2->getBLTRRange()); + UpdateNeighborsOfOneWithTwoInternal(ghostLev,factors,p1BLTR,p2BLTR,dataOnP1,dataOnP2); +} + +/*! + * Idem than UpdateNeighborsOfOneWithTwo, except that here \a p1 and \a p2 are not sharing the same direct father. + * + * \sa UpdateNeighborsOfOneWithTwo + */ +void MEDCouplingCartesianAMRPatch::UpdateNeighborsOfOneWithTwoExt(int ghostLev, const MEDCouplingCartesianAMRPatch *p1, const MEDCouplingCartesianAMRPatch *p2, DataArrayDouble *dataOnP1, const DataArrayDouble *dataOnP2) +{ + const std::vector< std::pair<int,int> >& p1BLTR(p1->getBLTRRange());//p1BLTR=[(10,12),(5,8)] + std::vector< std::pair<int,int> > p2BLTR(p2->getBLTRRange());//p2BLTR=[(0,1),(0,5)] + int lev(0); + const MEDCouplingCartesianAMRMeshGen *ca(FindCommonAncestor(p1,p2,lev)); + std::vector<int> offset(ComputeOffsetFromTwoToOne(ca,lev,p1,p2));//[12,4] + p2BLTR=MEDCouplingStructuredMesh::TranslateCompactFrmt(p2BLTR,offset);//p2BLTR=[(12,13),(4,9)] + UpdateNeighborsOfOneWithTwoInternal(ghostLev,p1->getMesh()->getFather()->getFactors(),p1BLTR,p2BLTR,dataOnP1,dataOnP2); +} + +/*! + * \a p1 is expected to be more refined than \a p2. \a p1 and \a p2 have to share a common ancestor. Compared to UpdateNeighborsOfOneWithTwoExt here \a p1 and \a p2 are \b not at the same level ! + */ +void MEDCouplingCartesianAMRPatch::UpdateNeighborsOfOneWithTwoMixedLev(int ghostLev, const MEDCouplingCartesianAMRPatch *p1, const MEDCouplingCartesianAMRPatch *p2, DataArrayDouble *dataOnP1, const DataArrayDouble *dataOnP2, bool isConservative) +{ + std::vector< std::pair<int,int> > p1pp,p2pp; + std::vector<int> factors; + ComputeZonesOfTwoRelativeToOneDiffLev(ghostLev,p1,p2,p1pp,p2pp,factors); + // + std::vector<int> dimsP2NotRefined(p2->computeCellGridSt()); + std::vector<int> dimsP2Refined(dimsP2NotRefined); + std::transform(dimsP2NotRefined.begin(),dimsP2NotRefined.end(),factors.begin(),dimsP2Refined.begin(),std::multiplies<int>()); + std::vector< std::pair<int,int> > p2RefinedAbs(MEDCouplingStructuredMesh::GetCompactFrmtFromDimensions(dimsP2NotRefined)); + std::vector<int> dimsP2RefinedGhost(dimsP2Refined.size()); + std::transform(dimsP2Refined.begin(),dimsP2Refined.end(),dimsP2RefinedGhost.begin(),std::bind2nd(std::plus<int>(),2*ghostLev)); + MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> fineP2(DataArrayDouble::New()); fineP2->alloc(MEDCouplingStructuredMesh::DeduceNumberOfGivenStructure(dimsP2RefinedGhost),dataOnP2->getNumberOfComponents()); + MEDCouplingIMesh::SpreadCoarseToFineGhost(dataOnP2,dimsP2NotRefined,fineP2,p2RefinedAbs,factors,ghostLev); + if(isConservative) + { + int fact(MEDCouplingStructuredMesh::DeduceNumberOfGivenStructure(factors)); + std::transform(fineP2->begin(),fineP2->end(),fineP2->getPointer(),std::bind2nd(std::multiplies<double>(),1./((double)fact))); + } + // + UpdateNeighborsOfOneWithTwoInternal(ghostLev,p1->getMesh()->getFather()->getFactors(),p1pp,p2pp,dataOnP1,fineP2); +} + +/*! + * \a p1 is expected to be more refined than \a p2. \a p1 and \a p2 have to share a common ancestor. Compared to UpdateNeighborsOfOneWithTwoExt here \a p1 and \a p2 are \b not at the same level ! + * This method has 3 outputs. 2 two first are the resp the position of \a p1 and \a p2 relative to \a p1. And \a factToApplyOn2 is the coeff of refinement to be applied on \a p2 to be virtualy + * on the same level as \a p1. + */ +void MEDCouplingCartesianAMRPatch::ComputeZonesOfTwoRelativeToOneDiffLev(int ghostLev, const MEDCouplingCartesianAMRPatch *p1, const MEDCouplingCartesianAMRPatch *p2, std::vector< std::pair<int,int> >& p1Zone, std::vector< std::pair<int,int> >& p2Zone, std::vector<int>& factToApplyOn2) +{ + std::vector<const MEDCouplingCartesianAMRMeshGen *> ancestorsOfThis; + const MEDCouplingCartesianAMRMeshGen *work(p1->getMesh()),*work2(0); + ancestorsOfThis.push_back(work); + while(work) + { + work=work->getFather(); + if(work) + ancestorsOfThis.push_back(work); + } + // + work=p2->getMesh(); + bool found(false); + std::size_t levThis(0),levOther(0); + while(work && !found) + { + work2=work; + work=work->getFather(); + if(work) + { + levOther++; + std::vector<const MEDCouplingCartesianAMRMeshGen *>::iterator it(std::find(ancestorsOfThis.begin(),ancestorsOfThis.end(),work)); + if(it!=ancestorsOfThis.end()) + { + levThis=std::distance(ancestorsOfThis.begin(),it); + found=true; + } + } + } + if(!found) + throw INTERP_KERNEL::Exception("MEDCouplingCartesianAMRPatch::ComputeZonesOfTwoRelativeToOneDiffLev : no common ancestor found !"); + if(levThis<=levOther) + throw INTERP_KERNEL::Exception("MEDCouplingCartesianAMRPatch::ComputeZonesOfTwoRelativeToOneDiffLev : this method is not called correctly !"); + // + const MEDCouplingCartesianAMRMeshGen *comAncestor(ancestorsOfThis[levThis]); + int idThis(comAncestor->getPatchIdFromChildMesh(ancestorsOfThis[levThis-1])),idOther(comAncestor->getPatchIdFromChildMesh(work2)); + const MEDCouplingCartesianAMRPatch *thisp(comAncestor->getPatch(idThis)),*otherp(comAncestor->getPatch(idOther)); + std::vector<int> offset(ComputeOffsetFromTwoToOne(comAncestor,levOther,thisp,otherp)); + p1Zone=thisp->getBLTRRange(); p2Zone=MEDCouplingStructuredMesh::TranslateCompactFrmt(otherp->getBLTRRange(),offset); + factToApplyOn2.resize(p1Zone.size()); std::fill(factToApplyOn2.begin(),factToApplyOn2.end(),1); + // + std::size_t nbOfTurn(levThis-levOther); + for(std::size_t i=0;i<nbOfTurn;i++) + { + std::vector< std::pair<int,int> > tmp0; + MEDCouplingStructuredMesh::ChangeReferenceFromGlobalOfCompactFrmt(p1Zone,p2Zone,tmp0,false); + p2Zone=tmp0; + const MEDCouplingCartesianAMRMeshGen *curAncestor(ancestorsOfThis[levThis-i]); + ApplyFactorsOnCompactFrmt(p2Zone,curAncestor->getFactors()); + curAncestor=ancestorsOfThis[levThis-1-i]; + const std::vector<int>& factors(curAncestor->getFactors()); + std::transform(factToApplyOn2.begin(),factToApplyOn2.end(),factors.begin(),factToApplyOn2.begin(),std::multiplies<int>()); + int tmpId(curAncestor->getPatchIdFromChildMesh(ancestorsOfThis[levThis-2-i])); + p1Zone=curAncestor->getPatch(tmpId)->getBLTRRange(); + } +} + +std::size_t MEDCouplingCartesianAMRPatch::getHeapMemorySizeWithoutChildren() const +{ + std::size_t ret(sizeof(MEDCouplingCartesianAMRPatch)); + ret+=_bl_tr.capacity()*sizeof(std::pair<int,int>); + return ret; +} + +const MEDCouplingCartesianAMRMeshGen *MEDCouplingCartesianAMRPatch::FindCommonAncestor(const MEDCouplingCartesianAMRPatch *p1, const MEDCouplingCartesianAMRPatch *p2, int& lev) +{ + const MEDCouplingCartesianAMRMeshGen *f1(p1->_mesh),*f2(p2->_mesh); + lev=0; + while(f1!=f2 || f1==0 || f2==0) + { + f1=f1->getFather(); f2=f2->getFather(); + if(f1->getFactors()!=f2->getFactors()) + throw INTERP_KERNEL::Exception("MEDCouplingCartesianAMRPatch::FindCommonAncestor : factors differ !"); + lev++; + } + if(f1!=f2) + throw INTERP_KERNEL::Exception("MEDCouplingCartesianAMRPatch::FindCommonAncestor : no common ancestor between p1 and p2 !"); + return f1; +} + +std::vector<int> MEDCouplingCartesianAMRPatch::ComputeOffsetFromTwoToOne(const MEDCouplingCartesianAMRMeshGen *comAncestor, int lev, const MEDCouplingCartesianAMRPatch *p1, const MEDCouplingCartesianAMRPatch *p2) +{ + if(lev<=0) + throw INTERP_KERNEL::Exception("MEDCouplingCartesianAMRPatch::ComputeOffsetFromTwoToOne : this method is useful only for lev > 0 !"); + int zeLev(lev-1); + int dim(p1->getMesh()->getSpaceDimension()); + if(p2->getMesh()->getSpaceDimension()!=dim) + throw INTERP_KERNEL::Exception("MEDCouplingCartesianAMRPatch::ComputeOffsetFromTwoToOne : dimension must be the same !"); + std::vector< int > ret(dim,0); + for(int i=0;i<zeLev;i++) + { + const MEDCouplingCartesianAMRMeshGen *f1(p1->_mesh),*f2(p2->_mesh); + const MEDCouplingCartesianAMRPatch *p1h(0),*p2h(0); + for(int j=0;j<lev-i;j++) + { + const MEDCouplingCartesianAMRMeshGen *f1tmp(f1->getFather()),*f2tmp(f2->getFather()); + int pid1(f1tmp->getPatchIdFromChildMesh(f1)),pid2(f2tmp->getPatchIdFromChildMesh(f2)); + p1h=f1tmp->getPatch(pid1); p2h=f2tmp->getPatch(pid2); + f1=f1tmp; f2=f2tmp; + } + std::vector< std::pair<int,int> > p2c(p2h->getBLTRRange()); + for(int k=0;k<dim;k++) + { + p2c[k].first+=ret[k]; + p2c[k].second+=ret[k]; + } + for(int k=0;k<dim;k++) + { + ret[k]=p2c[k].first-p1h->getBLTRRange()[k].first; + ret[k]*=f1->getFactors()[k]; + } + } + return ret; +} + +void MEDCouplingCartesianAMRPatch::UpdateNeighborsOfOneWithTwoInternal(int ghostLev, const std::vector<int>& factors, const std::vector< std::pair<int,int> >&p1 ,const std::vector< std::pair<int,int> >&p2, DataArrayDouble *dataOnP1, const DataArrayDouble *dataOnP2) +{//p1=[(1,4),(2,4)] p2=[(4,5),(3,4)] + int dim((int)factors.size()); + std::vector<int> dimsCoarse(MEDCouplingStructuredMesh::GetDimensionsFromCompactFrmt(p1));//[3,2] + std::transform(dimsCoarse.begin(),dimsCoarse.end(),factors.begin(),dimsCoarse.begin(),std::multiplies<int>());//[12,8] + std::transform(dimsCoarse.begin(),dimsCoarse.end(),dimsCoarse.begin(),std::bind2nd(std::plus<int>(),2*ghostLev));//[14,10] + std::vector< std::pair<int,int> > rangeCoarse(MEDCouplingStructuredMesh::GetCompactFrmtFromDimensions(dimsCoarse));//[(0,14),(0,10)] + std::vector<int> fakeFactors(dim,1); + // + std::vector< std::pair<int,int> > tmp0,tmp1,tmp2; + MEDCouplingStructuredMesh::ChangeReferenceFromGlobalOfCompactFrmt(p1,p2,tmp0,false);//tmp0=[(3,4),(1,2)] + ApplyFactorsOnCompactFrmt(tmp0,factors);//tmp0=[(12,16),(4,8)] + MEDCouplingStructuredMesh::ApplyGhostOnCompactFrmt(tmp0,ghostLev);//tmp0=[(13,17),(5,9)] + std::vector< std::pair<int,int> > interstRange(MEDCouplingStructuredMesh::IntersectRanges(tmp0,rangeCoarse));//interstRange=[(13,14),(5,9)] + MEDCouplingStructuredMesh::ChangeReferenceFromGlobalOfCompactFrmt(p2,p1,tmp1,false);//tmp1=[(-3,0),(-1,1)] + ApplyFactorsOnCompactFrmt(tmp1,factors);//tmp1=[(-12,-4),(-4,0)] + MEDCouplingStructuredMesh::ChangeReferenceToGlobalOfCompactFrmt(tmp1,interstRange,tmp2,false);//tmp2=[(1,2),(1,5)] + // + std::vector< std::pair<int,int> > dimsFine(p2); + ApplyFactorsOnCompactFrmt(dimsFine,factors); + ApplyAllGhostOnCompactFrmt(dimsFine,ghostLev); + // + MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ghostVals(MEDCouplingStructuredMesh::ExtractFieldOfDoubleFrom(MEDCouplingStructuredMesh::GetDimensionsFromCompactFrmt(dimsFine),dataOnP2,tmp2)); + MEDCouplingIMesh::CondenseFineToCoarse(dimsCoarse,ghostVals,interstRange,fakeFactors,dataOnP1); +} + +MEDCouplingCartesianAMRPatch::MEDCouplingCartesianAMRPatch(const MEDCouplingCartesianAMRPatch& other, MEDCouplingCartesianAMRMeshGen *father):MEDCouplingCartesianAMRPatchGen(other,father),_bl_tr(other._bl_tr) +{ +} + +/*! + * \param [in,out] partBeforeFact - the part of a image mesh in compact format that will be put in refined reference. + * \param [in] factors - the factors per axis. + */ +void MEDCouplingCartesianAMRPatch::ApplyFactorsOnCompactFrmt(std::vector< std::pair<int,int> >& partBeforeFact, const std::vector<int>& factors) +{ + std::size_t sz(factors.size()); + if(sz!=partBeforeFact.size()) + throw INTERP_KERNEL::Exception("MEDCouplingCartesianAMRPatch::ApplyFactorsOnCompactFrmt : size of input vectors must be the same !"); + for(std::size_t i=0;i<sz;i++) + { + partBeforeFact[i].first*=factors[i]; + partBeforeFact[i].second*=factors[i]; + } +} + +/*! + * This method is different than ApplyGhostOnCompactFrmt. The \a partBeforeFact parameter is enlarger contrary to ApplyGhostOnCompactFrmt. + * + * \param [in,out] partBeforeFact - the part of a image mesh in compact format that will be put in ghost reference. + * \param [in] ghostSize - the ghost size of zone for all axis. + */ +void MEDCouplingCartesianAMRPatch::ApplyAllGhostOnCompactFrmt(std::vector< std::pair<int,int> >& partBeforeFact, int ghostSize) +{ + if(ghostSize<0) + throw INTERP_KERNEL::Exception("MEDCouplingCartesianAMRPatch::ApplyAllGhostOnCompactFrmt : ghost size must be >= 0 !"); + std::size_t sz(partBeforeFact.size()); + for(std::size_t i=0;i<sz;i++) + { + partBeforeFact[i].first-=ghostSize; + partBeforeFact[i].second+=ghostSize; + } +} + +MEDCouplingCartesianAMRPatchGF::MEDCouplingCartesianAMRPatchGF(MEDCouplingCartesianAMRMesh *mesh):MEDCouplingCartesianAMRPatchGen(mesh) +{ +} + +MEDCouplingCartesianAMRPatchGF *MEDCouplingCartesianAMRPatchGF::deepCpy(MEDCouplingCartesianAMRMeshGen *father) const +{ + return new MEDCouplingCartesianAMRPatchGF(*this,father); +} + +std::size_t MEDCouplingCartesianAMRPatchGF::getHeapMemorySizeWithoutChildren() const +{ + return sizeof(MEDCouplingCartesianAMRPatchGF); +} + +MEDCouplingCartesianAMRPatchGF::MEDCouplingCartesianAMRPatchGF(const MEDCouplingCartesianAMRPatchGF& other, MEDCouplingCartesianAMRMeshGen *father):MEDCouplingCartesianAMRPatchGen(other,father) +{ +} + +/// @endcond + +int MEDCouplingCartesianAMRMeshGen::getSpaceDimension() const +{ + return _mesh->getSpaceDimension(); +} + +void MEDCouplingCartesianAMRMeshGen::setFactors(const std::vector<int>& newFactors) +{ + if(getSpaceDimension()!=(int)newFactors.size()) + throw INTERP_KERNEL::Exception("MEDCouplingCartesianAMRMeshGen::setFactors : size of input factors is not equal to the space dimension !"); + if(_factors.empty()) + { + _factors=newFactors; + return ; + } + if(_factors==newFactors) + return ; + if(!_patches.empty()) + throw INTERP_KERNEL::Exception("MEDCouplingCartesianAMRMeshGen::setFactors : modification of factors is not allowed when presence of patches !"); + _factors=newFactors; + declareAsNew(); +} + +int MEDCouplingCartesianAMRMeshGen::getMaxNumberOfLevelsRelativeToThis() const +{ + int ret(1); + for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCouplingCartesianAMRPatch> >::const_iterator it=_patches.begin();it!=_patches.end();it++) + ret=std::max(ret,(*it)->getMaxNumberOfLevelsRelativeToThis()+1); + return ret; +} + +/*! + * This method returns the number of cells of \a this with the help of the MEDCouplingIMesh instance representing \a this. + * The patches in \a this are ignored here. + * \sa getNumberOfCellsAtCurrentLevelGhost, getNumberOfCellsRecursiveWithOverlap + */ +int MEDCouplingCartesianAMRMeshGen::getNumberOfCellsAtCurrentLevel() const +{ + return _mesh->getNumberOfCells(); +} + +/*! + * This method returns the number of cells of \a this with the help of the MEDCouplingIMesh instance representing \a this enlarged by \a ghostLev size + * to take into account of the ghost cells for future computation. + * The patches in \a this are ignored here. + * + * \sa getNumberOfCellsAtCurrentLevel + */ +int MEDCouplingCartesianAMRMeshGen::getNumberOfCellsAtCurrentLevelGhost(int ghostLev) const +{ + MEDCouplingAutoRefCountObjectPtr<MEDCouplingIMesh> tmp(_mesh->buildWithGhost(ghostLev)); + return tmp->getNumberOfCells(); +} + +/*! + * This method returns the number of cells including the current level but \b also \b including recursively all cells of other levels + * starting from this. The set of cells which size is returned here are generally overlapping each other. + */ +int MEDCouplingCartesianAMRMeshGen::getNumberOfCellsRecursiveWithOverlap() const +{ + int ret(_mesh->getNumberOfCells()); + for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCouplingCartesianAMRPatch> >::const_iterator it=_patches.begin();it!=_patches.end();it++) + { + ret+=(*it)->getNumberOfCellsRecursiveWithOverlap(); + } + return ret; +} + +/*! + * This method returns the max number of cells covering all the space without overlapping. + * It returns the number of cells of the mesh with the highest resolution. + * The returned value is equal to the number of cells of mesh returned by buildUnstructured. + * + * \sa buildUnstructured + */ +int MEDCouplingCartesianAMRMeshGen::getNumberOfCellsRecursiveWithoutOverlap() const +{ + int ret(_mesh->getNumberOfCells()); + for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCouplingCartesianAMRPatch> >::const_iterator it=_patches.begin();it!=_patches.end();it++) + { + ret-=(*it)->getNumberOfOverlapedCellsForFather(); + ret+=(*it)->getNumberOfCellsRecursiveWithoutOverlap(); + } + return ret; +} + +/*! + * This method returns a vector of size equal to getAbsoluteLevelRelativeTo. It allows to find position an absolute position of \a this + * relative to \a ref (that is typically the god father). + * + * \sa getPatchAtPosition + */ +std::vector<int> MEDCouplingCartesianAMRMeshGen::getPositionRelativeTo(const MEDCouplingCartesianAMRMeshGen *ref) const +{ + if(!ref) + throw INTERP_KERNEL::Exception("MEDCouplingCartesianAMRMeshGen::getPositionRelativeTo : input pointer is NULL !"); + std::vector<int> ret; + getPositionRelativeToInternal(ref,ret); + std::reverse(ret.begin(),ret.end()); + return ret; +} + +/*! + * \sa getPositionRelativeTo, getMeshAtPosition + */ +const MEDCouplingCartesianAMRPatch *MEDCouplingCartesianAMRMeshGen::getPatchAtPosition(const std::vector<int>& pos) const +{ + std::size_t sz(pos.size()); + if(sz==0) + throw INTERP_KERNEL::Exception("MEDCouplingCartesianAMRMeshGen::getPatchAtPosition : empty input -> no patch by definition !"); + int patchId(pos[0]); + const MEDCouplingCartesianAMRPatch *elt(getPatch(patchId)); + if(sz==1) + return elt; + if(!elt || !elt->getMesh()) + throw INTERP_KERNEL::Exception("MEDCouplingCartesianAMRMeshGen::getPatchAtPosition : NULL element found during walk !"); + std::vector<int> pos2(pos.begin()+1,pos.end()); + return elt->getMesh()->getPatchAtPosition(pos2); +} + +const MEDCouplingCartesianAMRMeshGen *MEDCouplingCartesianAMRMeshGen::getMeshAtPosition(const std::vector<int>& pos) const +{ + std::size_t sz(pos.size()); + if(sz==0) + return this; + int patchId(pos[0]); + const MEDCouplingCartesianAMRPatch *elt(getPatch(patchId)); + if(sz==1) + { + if(!elt) + throw INTERP_KERNEL::Exception("MEDCouplingCartesianAMRMeshGen::getMeshAtPosition : NULL patch !"); + return elt->getMesh(); + } + if(!elt || !elt->getMesh()) + throw INTERP_KERNEL::Exception("MEDCouplingCartesianAMRMeshGen::getPatchAtPosition : NULL element found during walk !"); + std::vector<int> pos2(pos.begin()+1,pos.end()); + return elt->getMesh()->getMeshAtPosition(pos2); +} + +/*! + * This method returns grids relative to god father to specified level \a absoluteLev. + * + * \return std::vector<MEDCouplingCartesianAMRPatchGen *> - objects in vector are to be managed (decrRef) by the caller. + */ +std::vector<MEDCouplingCartesianAMRPatchGen *> MEDCouplingCartesianAMRMeshGen::retrieveGridsAt(int absoluteLev) const +{ + if(absoluteLev<0) + throw INTERP_KERNEL::Exception("MEDCouplingCartesianAMRMesh::retrieveGridsAt : absolute level must be >=0 !"); + return getGodFather()->retrieveGridsAt(absoluteLev); +} + +/*! + * \param [in] bottomLeftTopRight a vector equal to the space dimension of \a mesh that specifies for each dimension, the included cell start of the range for the first element of the pair, + * a the end cell (\b excluded) of the range for the second element of the pair. + * \param [in] factors The factor of refinement per axis (different from 0). + */ +void MEDCouplingCartesianAMRMeshGen::addPatch(const std::vector< std::pair<int,int> >& bottomLeftTopRight, const std::vector<int>& factors) +{ + checkFactorsAndIfNotSetAssign(factors); + MEDCouplingAutoRefCountObjectPtr<MEDCouplingIMesh> mesh(static_cast<MEDCouplingIMesh *>(_mesh->buildStructuredSubPart(bottomLeftTopRight))); + mesh->refineWithFactor(factors); + MEDCouplingAutoRefCountObjectPtr<MEDCouplingCartesianAMRMeshSub> zeMesh(new MEDCouplingCartesianAMRMeshSub(this,mesh)); + MEDCouplingAutoRefCountObjectPtr<MEDCouplingCartesianAMRPatch> elt(new MEDCouplingCartesianAMRPatch(zeMesh,bottomLeftTopRight)); + _patches.push_back(elt); + declareAsNew(); +} + +/// @cond INTERNAL + +class InternalPatch : public RefCountObjectOnly +{ +public: + InternalPatch():_nb_of_true(0) { } + int getDimension() const { return (int)_part.size(); } + double getEfficiency() const { return (double)_nb_of_true/(double)_crit.size(); } + int getNumberOfCells() const { return (int)_crit.size(); } + void setNumberOfTrue(int nboft) { _nb_of_true=nboft; } + std::vector<bool>& getCriterion() { return _crit; } + const std::vector<bool>& getConstCriterion() const { return _crit; } + void setPart(const std::vector< std::pair<int,int> >& part) { _part=part; } + std::vector< std::pair<int,int> >& getPart() { return _part; } + const std::vector< std::pair<int,int> >& getConstPart() const { return _part; } + bool presenceOfTrue() const { return _nb_of_true>0; } + std::vector<int> computeCGS() const { return MEDCouplingStructuredMesh::GetDimensionsFromCompactFrmt(_part); } + std::vector< std::vector<int> > computeSignature() const { return MEDCouplingStructuredMesh::ComputeSignaturePerAxisOf(computeCGS(),getConstCriterion()); } + double getEfficiencyPerAxis(int axisId) const { return (double)_nb_of_true/((double)(_part[axisId].second-_part[axisId].first)); } + void zipToFitOnCriterion(int minPatchLgth); + void updateNumberOfTrue() const; + MEDCouplingAutoRefCountObjectPtr<InternalPatch> extractPart(const std::vector< std::pair<int,int> >&partInGlobal) const; + MEDCouplingAutoRefCountObjectPtr<InternalPatch> deepCpy() const; +protected: + ~InternalPatch() { } +private: + mutable int _nb_of_true; + std::vector<bool> _crit; + //! _part is global + std::vector< std::pair<int,int> > _part; +}; + +void InternalPatch::zipToFitOnCriterion(int minPatchLgth) +{ + std::vector<int> cgs(computeCGS()); + std::vector<bool> newCrit; + std::vector< std::pair<int,int> > newPart,newPart2; + int newNbOfTrue(MEDCouplingStructuredMesh::FindMinimalPartOf(minPatchLgth,cgs,_crit,newCrit,newPart)); + MEDCouplingStructuredMesh::ChangeReferenceToGlobalOfCompactFrmt(_part,newPart,newPart2); + if(newNbOfTrue!=_nb_of_true) + throw INTERP_KERNEL::Exception("InternalPatch::zipToFitOnCrit : internal error !"); + _crit=newCrit; _part=newPart2; +} + +void InternalPatch::updateNumberOfTrue() const +{ + _nb_of_true=(int)std::count(_crit.begin(),_crit.end(),true); +} + +MEDCouplingAutoRefCountObjectPtr<InternalPatch> InternalPatch::extractPart(const std::vector< std::pair<int,int> >&partInGlobal) const +{ + MEDCouplingAutoRefCountObjectPtr<InternalPatch> ret(new InternalPatch); + std::vector<int> cgs(computeCGS()); + std::vector< std::pair<int,int> > newPart; + MEDCouplingStructuredMesh::ChangeReferenceFromGlobalOfCompactFrmt(_part,partInGlobal,newPart); + MEDCouplingStructuredMesh::ExtractFieldOfBoolFrom(cgs,_crit,newPart,ret->getCriterion()); + ret->setPart(partInGlobal); + ret->updateNumberOfTrue(); + return ret; +} + +MEDCouplingAutoRefCountObjectPtr<InternalPatch> InternalPatch::deepCpy() const +{ + MEDCouplingAutoRefCountObjectPtr<InternalPatch> ret(new InternalPatch); + (*ret)=*this; + return ret; +} + +void DissectBigPatch(const INTERP_KERNEL::BoxSplittingOptions& bso, const InternalPatch *patchToBeSplit, int axisId, int largestLength, int& cutPlace) +{ + int minimumPatchLength(bso.getMinimumPatchLength()); + std::vector<double> ratio(largestLength-minimumPatchLength,std::numeric_limits<double>::max()); + int index_min = -1; + double minSemiEfficiencyRatio(std::numeric_limits<double>::max()); + double efficiencyPerAxis[2]; + + for(int i=minimumPatchLength-1;i<largestLength-minimumPatchLength;i++) + { + for(int h=0;h<2;h++) + { + std::vector< std::pair<int,int> > rectH(patchToBeSplit->getConstPart()); + if(h==0) + rectH[axisId].second=patchToBeSplit->getConstPart()[axisId].first+i; + else + rectH[axisId].first=patchToBeSplit->getConstPart()[axisId].first+i; + MEDCouplingAutoRefCountObjectPtr<InternalPatch> p(patchToBeSplit->deepCpy()); + p->zipToFitOnCriterion(bso.getMinimumPatchLength()); + efficiencyPerAxis[h]=p->getEfficiencyPerAxis(axisId); + } + ratio[i]=std::max(efficiencyPerAxis[0], efficiencyPerAxis[1]) / std::min(efficiencyPerAxis[0], efficiencyPerAxis[1]); + if(ratio[i]<minSemiEfficiencyRatio) + { + minSemiEfficiencyRatio = ratio[i]; + index_min = i; + } + } + + if(index_min==-1) + throw INTERP_KERNEL::Exception("DissectBigPatch : just call to Arthur !"); + + cutPlace=index_min+patchToBeSplit->getConstPart()[axisId].first; +} + +bool FindHole(const INTERP_KERNEL::BoxSplittingOptions& bso, const InternalPatch *patchToBeSplit, int axisId, int& cutPlace) +{ + cutPlace=-1; + int minimumPatchLength(bso.getMinimumPatchLength()); + const int dim(patchToBeSplit->getDimension()); + std::vector< std::vector<int> > signatures(patchToBeSplit->computeSignature()); + for(int id=0;id<dim;id++) + { + const std::vector<int>& signature(signatures[id]); + std::vector<int> hole; + std::vector<double> distance; + int len((int)signature.size()); + for(int i=minimumPatchLength-1;i<len-minimumPatchLength;i++) + if(signature[i]==0) + hole.push_back(i); + if(!hole.empty()) + { + int closestHoleToMiddle(hole[0]); + int oldDistanceToMiddle(std::abs(hole[0]-len/2)); + int newDistanceToMiddle(oldDistanceToMiddle); + for(std::size_t i=0;i<hole.size();i++) + { + newDistanceToMiddle=std::abs(hole[i]-len/2); + if(newDistanceToMiddle < oldDistanceToMiddle) + { + oldDistanceToMiddle = newDistanceToMiddle; + closestHoleToMiddle = hole[i]; + } + } + cutPlace=closestHoleToMiddle+patchToBeSplit->getConstPart()[axisId].first; + return true; + } + } + return false; +} + +bool FindInflection(const INTERP_KERNEL::BoxSplittingOptions& bso, const InternalPatch *patchToBeSplit, int& cutPlace, int& axisId) +{ + bool cutFound(false); cutPlace=-1;// do not set axisId before to be sure that cutFound was set to true + const std::vector< std::pair<int,int> >& part(patchToBeSplit->getConstPart()); + int sign,minimumPatchLength(bso.getMinimumPatchLength()); + const int dim(patchToBeSplit->getDimension()); + + std::vector<int> zeroCrossDims(dim,-1); + std::vector<int> zeroCrossVals(dim,-1); + std::vector< std::vector<int> > signatures(patchToBeSplit->computeSignature()); + for (int id=0;id<dim;id++) + { + const std::vector<int>& signature(signatures[id]); + + std::vector<int> derivate_second_order,gradient_absolute,zero_cross,edge,max_cross_list ; + std::vector<double> distance ; + + for(std::size_t i=1;i<signature.size()-1;i++) + derivate_second_order.push_back(signature[i-1]-2*signature[i]+signature[i+1]) ; + + // Gradient absolute value + for(std::size_t i=1;i<derivate_second_order.size();i++) + gradient_absolute.push_back(abs(derivate_second_order[i]-derivate_second_order[i-1])) ; + if(derivate_second_order.empty()) + continue; + for(std::size_t i=1;i<derivate_second_order.size()-1;i++) + { + if (derivate_second_order[i]*derivate_second_order[i+1] < 0 ) + sign = -1 ; + if (derivate_second_order[i]*derivate_second_order[i+1] > 0 ) + sign = 1 ; + if (derivate_second_order[i]*derivate_second_order[i+1] == 0 ) + sign = 0 ; + if ( sign==0 || sign==-1 ) + if ( i >= (std::size_t)minimumPatchLength-2 && i <= signature.size()-minimumPatchLength-2 ) + { + zero_cross.push_back(i) ; + edge.push_back(gradient_absolute[i]) ; + } + } + if ( zero_cross.size() > 0 ) + { + int max_cross=*max_element(edge.begin(),edge.end()) ; + for (unsigned int i=0;i<edge.size();i++) + if (edge[i]==max_cross) + max_cross_list.push_back(zero_cross[i]+1) ; + + double center((signature.size()/2.0)); + for (unsigned int i=0;i<max_cross_list.size();i++) + distance.push_back(fabs(max_cross_list[i]+1-center)); + + double distance_min=*min_element(distance.begin(),distance.end()) ; + int pos_distance_min=find(distance.begin(),distance.end(),distance_min)-distance.begin(); + int best_place = max_cross_list[pos_distance_min] + part[id].first ; + if ( max_cross >=0 ) + { + zeroCrossDims[id] = best_place ; + zeroCrossVals[id] = max_cross ; + } + } + derivate_second_order.clear() ; + gradient_absolute.clear() ; + zero_cross.clear() ; + edge.clear() ; + max_cross_list.clear() ; + distance.clear() ; + } + + if ( zeroCrossDims[0]!=-1 || zeroCrossDims[1]!=-1 ) + { + int max_cross_dims = *max_element(zeroCrossVals.begin(),zeroCrossVals.end()) ; + + if (zeroCrossVals[0]==max_cross_dims && zeroCrossVals[1]==max_cross_dims ) + { + int nl_left(part[0].second-part[0].first); + int nc_left(part[1].second-part[1].first); + if ( nl_left >= nc_left ) + max_cross_dims = 0 ; + else + max_cross_dims = 1 ; + } + else + max_cross_dims=std::find(zeroCrossVals.begin(),zeroCrossVals.end(),max_cross_dims)-zeroCrossVals.begin(); + cutFound=true; + cutPlace=zeroCrossDims[max_cross_dims]; + axisId=max_cross_dims ; + } + return cutFound; +} + +bool TryAction4(const INTERP_KERNEL::BoxSplittingOptions& bso, const InternalPatch *patchToBeSplit, int axisId, int rangeOfAxisId, int& cutPlace) +{ + if(patchToBeSplit->getEfficiency()<=bso.getEfficiencyGoal()) + { + if(rangeOfAxisId>=2*bso.getMinimumPatchLength()) + { + cutPlace=rangeOfAxisId/2+patchToBeSplit->getConstPart()[axisId].first-1; + } + else + return false; + } + else + { + if(patchToBeSplit->getNumberOfCells()>bso.getMaximumNbOfCellsInPatch() || rangeOfAxisId>bso.getMaximumPatchLength()) + { + DissectBigPatch(bso,patchToBeSplit,axisId,rangeOfAxisId,cutPlace); + } + else + return false; + } + return true; +} + +MEDCouplingAutoRefCountObjectPtr<InternalPatch> DealWithNoCut(const InternalPatch *patch) +{ + MEDCouplingAutoRefCountObjectPtr<InternalPatch> ret(const_cast<InternalPatch *>(patch)); + ret->incrRef(); + return ret; +} + +void DealWithCut(double minPatchLgth, const InternalPatch *patchToBeSplit, int axisId, int cutPlace, std::vector<MEDCouplingAutoRefCountObjectPtr<InternalPatch> >& listOfPatches) +{ + MEDCouplingAutoRefCountObjectPtr<InternalPatch> leftPart,rightPart; + std::vector< std::pair<int,int> > rect(patchToBeSplit->getConstPart()); + std::vector< std::pair<int,int> > leftRect(rect),rightRect(rect); + leftRect[axisId].second=cutPlace+1; + rightRect[axisId].first=cutPlace+1; + leftPart=patchToBeSplit->extractPart(leftRect); + rightPart=patchToBeSplit->extractPart(rightRect); + leftPart->zipToFitOnCriterion(minPatchLgth); rightPart->zipToFitOnCriterion(minPatchLgth); + listOfPatches.push_back(leftPart); + listOfPatches.push_back(rightPart); +} + +/// @endcond + +void MEDCouplingCartesianAMRMeshGen::removeAllPatches() +{ + _patches.clear(); + declareAsNew(); +} + +void MEDCouplingCartesianAMRMeshGen::removePatch(int patchId) +{ + checkPatchId(patchId); + int sz((int)_patches.size()),j(0); + std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCouplingCartesianAMRPatch> > patches(sz-1); + for(int i=0;i<sz;i++) + if(i!=patchId) + patches[j++]=_patches[i]; + (const_cast<MEDCouplingCartesianAMRMeshGen *>(_patches[patchId]->getMesh()))->detachFromFather(); + _patches=patches; + declareAsNew(); +} + +int MEDCouplingCartesianAMRMeshGen::getNumberOfPatches() const +{ + return (int)_patches.size(); +} + +/*! + * This method is a generic algorithm to create patches in \a this (by destroying the patches if any). + * This method uses \a criterion array as a field on cells on this level. + * This method only create patches at level 0 relative to \a this. + * + * This generic algorithm can be degenerated into three child ones, depending on the arguments given; in particular depending + * on whether they are equal to 0 or not. + * 1/ If minimumPatchLength = maximumPatchLength = maximumPatchVolume = 0, then we have the Berger-Rigoutsos algorithm. + * This algorithm was developed in 1991 and seems appropriate for sequential programming. + * 2/ If maximumPatchLength = 0, then we have the Livne algorithm. + * This algorithm was developed in 2004 and is an improvement of the Berger-Rigoutsos algorithm. + * 3/ If maximumPatchVolume = 0, the we have the lmin-lmax algorithm. + * This algorithm was developed by Arthur TALPAERT in 2014 and is an improvement of the Livne algorithm. It is especially + * appropriate for parallel computing, where one patch would be given to one CPU. See Arthur TALPAERT's 2014 CANUM poster + * for more information. + * + */ +void MEDCouplingCartesianAMRMeshGen::createPatchesFromCriterion(const INTERP_KERNEL::BoxSplittingOptions& bso, const std::vector<bool>& criterion, const std::vector<int>& factors) +{ + int nbCells(getNumberOfCellsAtCurrentLevel()); + if(nbCells!=(int)criterion.size()) + throw INTERP_KERNEL::Exception("MEDCouplingCartesianAMRMeshGen::createPatchesFromCriterion : the number of tuples of criterion array must be equal to the number of cells at the current level !"); + _patches.clear(); + std::vector<int> cgs(_mesh->getCellGridStructure()); + std::vector< MEDCouplingAutoRefCountObjectPtr<InternalPatch> > listOfPatches,listOfPatchesOK; + // + MEDCouplingAutoRefCountObjectPtr<InternalPatch> p(new InternalPatch); + p->setNumberOfTrue(MEDCouplingStructuredMesh::FindMinimalPartOf(bso.getMinimumPatchLength(),cgs,criterion,p->getCriterion(),p->getPart())); + if(p->presenceOfTrue()) + listOfPatches.push_back(p); + while(!listOfPatches.empty()) + { + std::vector< MEDCouplingAutoRefCountObjectPtr<InternalPatch> > listOfPatchesTmp; + for(std::vector< MEDCouplingAutoRefCountObjectPtr<InternalPatch> >::iterator it=listOfPatches.begin();it!=listOfPatches.end();it++) + { + // + int axisId,largestLength,cutPlace; + MEDCouplingStructuredMesh::FindTheWidestAxisOfGivenRangeInCompactFrmt((*it)->getConstPart(),axisId,largestLength); + if((*it)->getEfficiency()>=bso.getEfficiencyThreshold() && ((*it)->getNumberOfCells()>bso.getMaximumNbOfCellsInPatch() || largestLength>bso.getMaximumPatchLength())) + { + DissectBigPatch(bso,*it,axisId,largestLength,cutPlace); + DealWithCut(bso.getMinimumPatchLength(),*it,axisId,cutPlace,listOfPatchesTmp); + continue; + }//action 1 + if(FindHole(bso,*it,axisId,cutPlace))//axisId overwritten here if FindHole equal to true ! + { DealWithCut(bso.getMinimumPatchLength(),*it,axisId,cutPlace,listOfPatchesTmp); continue; }//action 2 + if(FindInflection(bso,*it,cutPlace,axisId))//axisId overwritten here if cutFound equal to true ! + { DealWithCut(bso.getMinimumPatchLength(),*it,axisId,cutPlace,listOfPatchesTmp); continue; }//action 3 + if(TryAction4(bso,*it,axisId,largestLength,cutPlace)) + { DealWithCut(bso.getMinimumPatchLength(),*it,axisId,cutPlace,listOfPatchesTmp); continue; }//action 4 + else + listOfPatchesOK.push_back(DealWithNoCut(*it)); + } + listOfPatches=listOfPatchesTmp; + } + for(std::vector< MEDCouplingAutoRefCountObjectPtr<InternalPatch> >::const_iterator it=listOfPatchesOK.begin();it!=listOfPatchesOK.end();it++) + addPatch((*it)->getConstPart(),factors); + declareAsNew(); +} + +/*! + * This method creates patches in \a this (by destroying the patches if any). This method uses \a criterion array as a field on cells on this level. + * This method only create patches at level 0 relative to \a this. + */ +void MEDCouplingCartesianAMRMeshGen::createPatchesFromCriterion(const INTERP_KERNEL::BoxSplittingOptions& bso, const DataArrayByte *criterion, const std::vector<int>& factors) +{ + if(!criterion || !criterion->isAllocated()) + throw INTERP_KERNEL::Exception("MEDCouplingCartesianAMRMeshGen::createPatchesFromCriterion : the criterion DataArrayByte instance must be allocated and not NULL !"); + std::vector<bool> crit(criterion->toVectorOfBool());//check that criterion has one component. + createPatchesFromCriterion(bso,crit,factors); + declareAsNew(); +} + +void MEDCouplingCartesianAMRMeshGen::createPatchesFromCriterion(const INTERP_KERNEL::BoxSplittingOptions& bso, const DataArrayDouble *criterion, const std::vector<int>& factors, double eps) +{ + if(!criterion) + throw INTERP_KERNEL::Exception("MEDCouplingCartesianAMRMeshGen::createPatchesFromCriterion : null criterion pointer !"); + std::vector<bool> inp(criterion->toVectorOfBool(eps)); + createPatchesFromCriterion(bso,inp,factors); +} + +int MEDCouplingCartesianAMRMeshGen::getPatchIdFromChildMesh(const MEDCouplingCartesianAMRMeshGen *mesh) const +{ + int ret(0); + for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCouplingCartesianAMRPatch> >::const_iterator it=_patches.begin();it!=_patches.end();it++,ret++) + { + if((*it)->getMesh()==mesh) + return ret; + } + throw INTERP_KERNEL::Exception("MEDCouplingCartesianAMRMeshGen::getPatchIdFromChildMesh : no such a mesh in my direct progeny !"); +} + +std::vector< const MEDCouplingCartesianAMRPatch *> MEDCouplingCartesianAMRMeshGen::getPatches() const +{ + std::size_t sz(_patches.size()); + std::vector< const MEDCouplingCartesianAMRPatch *> ret(sz); + for(std::size_t i=0;i<sz;i++) + ret[i]=_patches[i]; + return ret; +} + +const MEDCouplingCartesianAMRPatch *MEDCouplingCartesianAMRMeshGen::getPatch(int patchId) const +{ + checkPatchId(patchId); + return _patches[patchId]; +} + +/*! + * This method states if patch2 (with id \a patchId2) is in the neighborhood of patch1 (with id \a patchId1). + * The neighborhood size is defined by \a ghostLev in the reference of \a this ( \b not in the reference of patches !). + */ +bool MEDCouplingCartesianAMRMeshGen::isPatchInNeighborhoodOf(int patchId1, int patchId2, int ghostLev) const +{ + const MEDCouplingCartesianAMRPatch *p1(getPatch(patchId1)),*p2(getPatch(patchId2)); + return p1->isInMyNeighborhood(p2,ghostLev); +} + +/*! + * This method creates a new cell field array on given \a patchId patch in \a this starting from a coarse cell field on \a this \a cellFieldOnThis. + * This method can be seen as a fast projection from the cell field \a cellFieldOnThis on \c this->getImageMesh() to a refined part of \a this + * defined by the patch with id \a patchId. + * + * \param [in] patchId - The id of the patch \a cellFieldOnThis has to be put on. + * \param [in] cellFieldOnThis - The array of the cell field on \c this->getImageMesh() to be projected to patch having id \a patchId. + * \return DataArrayDouble * - The array of the cell field on the requested patch + * + * \throw if \a patchId is not in [ 0 , \c this->getNumberOfPatches() ) + * \throw if \a cellFieldOnThis is NULL or not allocated + * \sa fillCellFieldOnPatch, MEDCouplingIMesh::SpreadCoarseToFine + */ +DataArrayDouble *MEDCouplingCartesianAMRMeshGen::createCellFieldOnPatch(int patchId, const DataArrayDouble *cellFieldOnThis) const +{ + if(!cellFieldOnThis || !cellFieldOnThis->isAllocated()) + throw INTERP_KERNEL::Exception("MEDCouplingCartesianAMRMesh::createCellFieldOnPatch : the input cell field array is NULL or not allocated !"); + const MEDCouplingCartesianAMRPatch *patch(getPatch(patchId)); + const MEDCouplingIMesh *fine(patch->getMesh()->getImageMesh()); + MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret(DataArrayDouble::New()); ret->alloc(fine->getNumberOfCells(),cellFieldOnThis->getNumberOfComponents()); + ret->copyStringInfoFrom(*cellFieldOnThis); + MEDCouplingIMesh::SpreadCoarseToFine(cellFieldOnThis,_mesh->getCellGridStructure(),ret,patch->getBLTRRange(),getFactors()); + return ret.retn(); +} + +/*! + * This method is equivalent to MEDCouplingCartesianAMRMesh::createCellFieldOnPatch except that here instead of creating a new instance + * it fills the value into the \a cellFieldOnPatch data. + * + * \param [in] patchId - The id of the patch \a cellFieldOnThis has to be put on. + * \param [in] cellFieldOnThis - The array of the cell field on \c this->getImageMesh() to be projected to patch having id \a patchId. + * \param [in,out] cellFieldOnPatch - The array of the cell field on the requested patch to be filled. + * + * \sa createCellFieldOnPatch, fillCellFieldComingFromPatch + */ +void MEDCouplingCartesianAMRMeshGen::fillCellFieldOnPatch(int patchId, const DataArrayDouble *cellFieldOnThis, DataArrayDouble *cellFieldOnPatch, bool isConservative) const +{ + if(!cellFieldOnThis || !cellFieldOnThis->isAllocated()) + throw INTERP_KERNEL::Exception("MEDCouplingCartesianAMRMesh::createCellFieldOnPatch : the input cell field array is NULL or not allocated !"); + const MEDCouplingCartesianAMRPatch *patch(getPatch(patchId)); + MEDCouplingIMesh::SpreadCoarseToFine(cellFieldOnThis,_mesh->getCellGridStructure(),cellFieldOnPatch,patch->getBLTRRange(),getFactors()); + if(isConservative) + { + int fact(MEDCouplingStructuredMesh::DeduceNumberOfGivenStructure(getFactors())); + std::transform(cellFieldOnPatch->begin(),cellFieldOnPatch->end(),cellFieldOnPatch->getPointer(),std::bind2nd(std::multiplies<double>(),1./((double)fact))); + } +} + +/*! + * This method is the generalization of fillCellFieldOnPatch method. This method only projects coarse to fine without considering the + * potential neighbor patches covered by the ghost cells of patch with id \a patchId. + * + * \param [in] patchId - The id of the patch \a cellFieldOnThis has to be put on. + * \param [in] cellFieldOnThis - The array of the cell field on \c this->getImageMesh() to be projected to patch having id \a patchId. + * \param [in,out] cellFieldOnPatch - The array of the cell field on the requested patch to be filled. + * \param [in] ghostLev - The size of the ghost zone (must be >=0 !) + * + * \sa fillCellFieldOnPatch, fillCellFieldOnPatchGhostAdv + */ +void MEDCouplingCartesianAMRMeshGen::fillCellFieldOnPatchGhost(int patchId, const DataArrayDouble *cellFieldOnThis, DataArrayDouble *cellFieldOnPatch, int ghostLev, bool isConservative) const +{ + if(!cellFieldOnThis || !cellFieldOnThis->isAllocated()) + throw INTERP_KERNEL::Exception("MEDCouplingCartesianAMRMesh::createCellFieldOnPatchGhost : the input cell field array is NULL or not allocated !"); + const MEDCouplingCartesianAMRPatch *patch(getPatch(patchId)); + MEDCouplingIMesh::SpreadCoarseToFineGhost(cellFieldOnThis,_mesh->getCellGridStructure(),cellFieldOnPatch,patch->getBLTRRange(),getFactors(),ghostLev); + if(isConservative) + { + int fact(MEDCouplingStructuredMesh::DeduceNumberOfGivenStructure(getFactors())); + std::transform(cellFieldOnPatch->begin(),cellFieldOnPatch->end(),cellFieldOnPatch->getPointer(),std::bind2nd(std::multiplies<double>(),1./((double)fact))); + } +} + +/*! + * This method is equivalent to fillCellFieldOnPatchGhost except that here \b ONLY \b the \b ghost \b zone will be updated + * in \a cellFieldOnPatch. + * + * \param [in] patchId - The id of the patch \a cellFieldOnThis has to be put on. + * \param [in] cellFieldOnThis - The array of the cell field on \c this->getImageMesh() to be projected to patch having id \a patchId. + * \param [in,out] cellFieldOnPatch - The array of the cell field on the requested patch to be filled \b only \b in \b the \b ghost \b zone. + * \param [in] ghostLev - The size of the ghost zone (must be >=0 !) + */ +void MEDCouplingCartesianAMRMeshGen::fillCellFieldOnPatchOnlyOnGhostZone(int patchId, const DataArrayDouble *cellFieldOnThis, DataArrayDouble *cellFieldOnPatch, int ghostLev) const +{ + if(!cellFieldOnThis || !cellFieldOnThis->isAllocated()) + throw INTERP_KERNEL::Exception("MEDCouplingCartesianAMRMesh::fillCellFieldOnPatchOnlyOnGhostZone : the input cell field array is NULL or not allocated !"); + const MEDCouplingCartesianAMRPatch *patch(getPatch(patchId)); + MEDCouplingIMesh::SpreadCoarseToFineGhostZone(cellFieldOnThis,_mesh->getCellGridStructure(),cellFieldOnPatch,patch->getBLTRRange(),getFactors(),ghostLev); +} + +/*! + * This method is a refinement of fillCellFieldOnPatchGhost. fillCellFieldOnPatchGhost is first called. + * Then for all other patches than those pointed by \a patchId that overlap the ghost zone of the patch impact the ghost zone adequately. + * + * \param [in] patchId - The id of the patch \a cellFieldOnThis has to be put on. + * \param [in] cellFieldOnThis - The array of the cell field on \c this->getImageMesh() to be projected to patch having id \a patchId. + * \param [in,out] cellFieldOnPatch - The array of the cell field on the requested patch to be filled. + * \param [in] ghostLev - The size of the ghost zone (must be >=0 !) + * \param [in] arrsOnPatches - \b WARNING arrsOnPatches[patchId] is \b NOT \b const. All others are const. + * + * \sa fillCellFieldOnPatchOnlyGhostAdv + */ +void MEDCouplingCartesianAMRMeshGen::fillCellFieldOnPatchGhostAdv(int patchId, const DataArrayDouble *cellFieldOnThis, int ghostLev, const std::vector<const DataArrayDouble *>& arrsOnPatches, bool isConservative) const +{ + int nbp(getNumberOfPatches()); + if(nbp!=(int)arrsOnPatches.size()) + { + std::ostringstream oss; oss << "MEDCouplingCartesianAMRMesh::fillCellFieldOnPatchGhostAdv : there are " << nbp << " patches in this and " << arrsOnPatches.size() << " arrays in the last parameter !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + DataArrayDouble *theFieldToFill(const_cast<DataArrayDouble *>(arrsOnPatches[patchId])); + // first, do as usual + fillCellFieldOnPatchGhost(patchId,cellFieldOnThis,theFieldToFill,ghostLev,isConservative); + fillCellFieldOnPatchOnlyGhostAdv(patchId,ghostLev,arrsOnPatches); +} + +/*! + * This method updates the patch with id \a patchId considering the only the all the patches in \a this to fill ghost zone. + * So \b warning, the DataArrayDouble instance \a arrsOnPatches[patchId] is non const. + * + * \sa getPatchIdsInTheNeighborhoodOf + */ +void MEDCouplingCartesianAMRMeshGen::fillCellFieldOnPatchOnlyGhostAdv(int patchId, int ghostLev, const std::vector<const DataArrayDouble *>& arrsOnPatches) const +{ + int nbp(getNumberOfPatches()); + if(nbp!=(int)arrsOnPatches.size()) + { + std::ostringstream oss; oss << "MEDCouplingCartesianAMRMesh::fillCellFieldOnPatchOnlyGhostAdv : there are " << nbp << " patches in this and " << arrsOnPatches.size() << " arrays in the last parameter !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + const MEDCouplingCartesianAMRPatch *refP(getPatch(patchId)); + DataArrayDouble *theFieldToFill(const_cast<DataArrayDouble *>(arrsOnPatches[patchId])); + std::vector<int> ids(getPatchIdsInTheNeighborhoodOf(patchId,ghostLev)); + for(std::vector<int>::const_iterator it=ids.begin();it!=ids.end();it++) + { + const MEDCouplingCartesianAMRPatch *otherP(getPatch(*it)); + MEDCouplingCartesianAMRPatch::UpdateNeighborsOfOneWithTwo(ghostLev,_factors,refP,otherP,theFieldToFill,arrsOnPatches[*it]); + } +} + +void MEDCouplingCartesianAMRMeshGen::fillCellFieldOnPatchOnlyOnGhostZoneWith(int ghostLev, const MEDCouplingCartesianAMRPatch *patchToBeModified, const MEDCouplingCartesianAMRPatch *neighborPatch, DataArrayDouble *cellFieldOnPatch, const DataArrayDouble *cellFieldNeighbor) const +{ + MEDCouplingCartesianAMRPatch::UpdateNeighborsOfOneWithTwo(ghostLev,_factors,patchToBeModified,neighborPatch,cellFieldOnPatch,cellFieldNeighbor); +} + +/*! + * This method updates \a cellFieldOnThis part of values coming from the cell field \a cellFieldOnPatch lying on patch having id \a patchId. + * + * \param [in] patchId - The id of the patch \a cellFieldOnThis has to be put on. + * \param [in] cellFieldOnPatch - The array of the cell field on patch with id \a patchId. + * \param [in,out] cellFieldOnThis The array of the cell field on \a this to be updated only on the part concerning the patch with id \a patchId. + * \param [in] isConservative - true if the field needs to be conserved. false if maximum principle has to be applied. + * + * \throw if \a patchId is not in [ 0 , \c this->getNumberOfPatches() ) + * \throw if \a cellFieldOnPatch is NULL or not allocated + * \sa createCellFieldOnPatch, MEDCouplingIMesh::CondenseFineToCoarse,fillCellFieldComingFromPatchGhost + */ +void MEDCouplingCartesianAMRMeshGen::fillCellFieldComingFromPatch(int patchId, const DataArrayDouble *cellFieldOnPatch, DataArrayDouble *cellFieldOnThis, bool isConservative) const +{ + if(!cellFieldOnPatch || !cellFieldOnPatch->isAllocated()) + throw INTERP_KERNEL::Exception("MEDCouplingCartesianAMRMesh::fillCellFieldComingFromPatch : the input cell field array is NULL or not allocated !"); + const MEDCouplingCartesianAMRPatch *patch(getPatch(patchId)); + MEDCouplingIMesh::CondenseFineToCoarse(_mesh->getCellGridStructure(),cellFieldOnPatch,patch->getBLTRRange(),getFactors(),cellFieldOnThis); + if(!isConservative) + { + int fact(MEDCouplingStructuredMesh::DeduceNumberOfGivenStructure(getFactors())); + MEDCouplingStructuredMesh::MultiplyPartOf(_mesh->getCellGridStructure(),patch->getBLTRRange(),1./((double)fact),cellFieldOnThis); + } +} + +/*! + * This method is the extension of MEDCouplingCartesianAMRMesh::fillCellFieldComingFromPatch managing the ghost cells. If this + * method is called with \a ghostLev equal to 0 it behaves exactly as MEDCouplingCartesianAMRMesh::fillCellFieldComingFromPatch. + * + * \param [in] patchId - The id of the patch \a cellFieldOnThis has to be put on. + * \param [in] cellFieldOnPatch - The array of the cell field on patch with id \a patchId. + * \param [in,out] cellFieldOnThis The array of the cell field on \a this to be updated only on the part concerning the patch with id \a patchId. + * \param [in] ghostLev The size of ghost zone (must be >= 0 !) + * \param [in] isConservative - true if the field needs to be conserved. false if maximum principle has to be applied. + * + * \throw if \a patchId is not in [ 0 , \c this->getNumberOfPatches() ) + * \throw if \a cellFieldOnPatch is NULL or not allocated + * \sa fillCellFieldComingFromPatch + */ +void MEDCouplingCartesianAMRMeshGen::fillCellFieldComingFromPatchGhost(int patchId, const DataArrayDouble *cellFieldOnPatch, DataArrayDouble *cellFieldOnThis, int ghostLev, bool isConservative) const +{ + if(!cellFieldOnPatch || !cellFieldOnPatch->isAllocated()) + throw INTERP_KERNEL::Exception("MEDCouplingCartesianAMRMesh::fillCellFieldComingFromPatchGhost : the input cell field array is NULL or not allocated !"); + const MEDCouplingCartesianAMRPatch *patch(getPatch(patchId)); + MEDCouplingIMesh::CondenseFineToCoarseGhost(_mesh->getCellGridStructure(),cellFieldOnPatch,patch->getBLTRRange(),getFactors(),cellFieldOnThis,ghostLev); + if(!isConservative) + { + int fact(MEDCouplingStructuredMesh::DeduceNumberOfGivenStructure(getFactors())); + MEDCouplingStructuredMesh::MultiplyPartOfByGhost(_mesh->getCellGridStructure(),patch->getBLTRRange(),ghostLev,1./((double)fact),cellFieldOnThis); + } +} + +/*! + * This method finds all patches (located by their ids) that are in the neighborhood of patch with id \a patchId. The neighborhood size is + * defined by ghostLev. + * + * \param [in] patchId - the id of the considered patch. + * \param [in] ghostLev - the size of the neighborhood. + * \return DataArrayInt * - the newly allocated array containing the list of patches in the neighborhood of the considered patch. This array is to be deallocated by the caller. + */ +DataArrayInt *MEDCouplingCartesianAMRMeshGen::findPatchesInTheNeighborhoodOf(int patchId, int ghostLev) const +{ + int nbp(getNumberOfPatches()); + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1); + for(int i=0;i<nbp;i++) + { + if(i!=patchId) + if(isPatchInNeighborhoodOf(i,patchId,ghostLev)) + ret->pushBackSilent(i); + } + return ret.retn(); +} + +MEDCouplingUMesh *MEDCouplingCartesianAMRMeshGen::buildUnstructured() const +{ + MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> part(_mesh->buildUnstructured()); + std::vector<bool> bs(_mesh->getNumberOfCells(),false); + std::vector<int> cgs(_mesh->getCellGridStructure()); + std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> > msSafe(_patches.size()+1); + std::size_t ii(0); + for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCouplingCartesianAMRPatch> >::const_iterator it=_patches.begin();it!=_patches.end();it++,ii++) + { + MEDCouplingStructuredMesh::SwitchOnIdsFrom(cgs,(*it)->getBLTRRange(),bs); + msSafe[ii+1]=(*it)->getMesh()->buildUnstructured(); + } + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> eltsOff(DataArrayInt::BuildListOfSwitchedOff(bs)); + msSafe[0]=static_cast<MEDCouplingUMesh *>(part->buildPartOfMySelf(eltsOff->begin(),eltsOff->end(),false)); + std::vector< const MEDCouplingUMesh * > ms(msSafe.size()); + for(std::size_t i=0;i<msSafe.size();i++) + ms[i]=msSafe[i]; + return MEDCouplingUMesh::MergeUMeshes(ms); +} + +/*! + * This method returns a mesh containing as cells that there is patches at the current level. + * The patches are seen like 'boxes' that is too say the refinement will not appear here. + * + * \return MEDCoupling1SGTUMesh * - A new object to be managed by the caller containing as cells as there are patches in \a this. + */ +MEDCoupling1SGTUMesh *MEDCouplingCartesianAMRMeshGen::buildMeshFromPatchEnvelop() const +{ + std::vector<const MEDCoupling1SGTUMesh *> cells; + std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCoupling1SGTUMesh> > cellsSafe; + for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCouplingCartesianAMRPatch> >::const_iterator it=_patches.begin();it!=_patches.end();it++) + { + const MEDCouplingCartesianAMRPatch *patch(*it); + if(patch) + { + MEDCouplingAutoRefCountObjectPtr<MEDCouplingIMesh> cell(patch->getMesh()->getImageMesh()->asSingleCell()); + MEDCouplingAutoRefCountObjectPtr<MEDCoupling1SGTUMesh> cell1SGT(cell->build1SGTUnstructured()); + cellsSafe.push_back(cell1SGT); cells.push_back(cell1SGT); + } + } + return MEDCoupling1SGTUMesh::Merge1SGTUMeshes(cells); +} + +MEDCoupling1SGTUMesh *MEDCouplingCartesianAMRMeshGen::buildMeshOfDirectChildrenOnly() const +{ + std::vector<const MEDCoupling1SGTUMesh *> patches; + std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCoupling1SGTUMesh> > patchesSafe; + for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCouplingCartesianAMRPatch> >::const_iterator it=_patches.begin();it!=_patches.end();it++) + { + const MEDCouplingCartesianAMRPatch *patch(*it); + if(patch) + { + MEDCouplingAutoRefCountObjectPtr<MEDCoupling1SGTUMesh> patchMesh(patch->getMesh()->getImageMesh()->build1SGTUnstructured()); + patchesSafe.push_back(patchMesh); patches.push_back(patchMesh); + } + } + return MEDCoupling1SGTUMesh::Merge1SGTUMeshes(patches); +} + +/*! + * This method works same as buildUnstructured except that arrays are given in input to build a field on cell in output. + * \return MEDCouplingFieldDouble * - a newly created instance the caller has reponsability to deal with. + * \sa buildUnstructured + */ +MEDCouplingFieldDouble *MEDCouplingCartesianAMRMeshGen::buildCellFieldOnRecurseWithoutOverlapWithoutGhost(int ghostSz, const std::vector<const DataArrayDouble *>& recurseArrs) const +{ + if(recurseArrs.empty()) + throw INTERP_KERNEL::Exception("MEDCouplingCartesianAMRMeshGen::buildCellFieldOnRecurseWithoutOverlapWithoutGhost : array is empty ! Should never happen !"); + // + std::vector<bool> bs(_mesh->getNumberOfCells(),false); + std::vector<int> cgs(_mesh->getCellGridStructure()); + std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCouplingFieldDouble> > msSafe(_patches.size()+1); + std::size_t ii(0); + for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCouplingCartesianAMRPatch> >::const_iterator it=_patches.begin();it!=_patches.end();it++,ii++) + { + MEDCouplingStructuredMesh::SwitchOnIdsFrom(cgs,(*it)->getBLTRRange(),bs); + std::vector<const DataArrayDouble *> tmpArrs(extractSubTreeFromGlobalFlatten((*it)->getMesh(),recurseArrs)); + msSafe[ii+1]=(*it)->getMesh()->buildCellFieldOnRecurseWithoutOverlapWithoutGhost(ghostSz,tmpArrs); + } + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> eltsOff(DataArrayInt::BuildListOfSwitchedOff(bs)); + // + MEDCouplingAutoRefCountObjectPtr<MEDCouplingFieldDouble> ret(MEDCouplingFieldDouble::New(ON_CELLS)); + MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> arr2(extractGhostFrom(ghostSz,recurseArrs[0])); + arr2=arr2->selectByTupleIdSafe(eltsOff->begin(),eltsOff->end()); + ret->setArray(arr2); + ret->setName(arr2->getName()); + MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> part(_mesh->buildUnstructured()); + MEDCouplingAutoRefCountObjectPtr<MEDCouplingMesh> mesh(part->buildPartOfMySelf(eltsOff->begin(),eltsOff->end(),false)); + ret->setMesh(mesh); + msSafe[0]=ret; + // + std::vector< const MEDCouplingFieldDouble * > ms(msSafe.size()); + for(std::size_t i=0;i<msSafe.size();i++) + ms[i]=msSafe[i]; + // + return MEDCouplingFieldDouble::MergeFields(ms); +} + +/*! + * This method extracts from \arr arr the part inside \a arr by cutting the \a ghostSz external part. + * \arr is expected to be an array having a number of tuples equal to \c getImageMesh()->buildWithGhost(ghostSz). + */ +DataArrayDouble *MEDCouplingCartesianAMRMeshGen::extractGhostFrom(int ghostSz, const DataArrayDouble *arr) const +{ + std::vector<int> st(_mesh->getCellGridStructure()); + std::vector< std::pair<int,int> > p(MEDCouplingStructuredMesh::GetCompactFrmtFromDimensions(st)); + std::transform(st.begin(),st.end(),st.begin(),std::bind2nd(std::plus<int>(),2*ghostSz)); + MEDCouplingStructuredMesh::ApplyGhostOnCompactFrmt(p,ghostSz); + MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret(MEDCouplingStructuredMesh::ExtractFieldOfDoubleFrom(st,arr,p)); + return ret.retn(); +} + +/*! + * This method returns all the patches in \a this not equal to \a patchId that are in neighborhood of patch with id \a patchId. + * + * \sa fillCellFieldOnPatchOnlyGhostAdv + */ +std::vector<int> MEDCouplingCartesianAMRMeshGen::getPatchIdsInTheNeighborhoodOf(int patchId, int ghostLev) const +{ + std::vector<int> ret; + int nbp(getNumberOfPatches()); + // + for(int i=0;i<nbp;i++) + { + if(i!=patchId) + if(isPatchInNeighborhoodOf(i,patchId,ghostLev)) + ret.push_back(i); + } + return ret; +} + +/*! + * This method returns a dump python of \a this. It is useful for users of createPatchesFromCriterion method for debugging. + * + * \sa dumpPatchesOf, createPatchesFromCriterion, createPatchesFromCriterionML + */ +std::string MEDCouplingCartesianAMRMeshGen::buildPythonDumpOfThis() const +{ + std::ostringstream oss; + oss << "amr=MEDCouplingCartesianAMRMesh(\""<< getImageMesh()->getName() << "\"," << getSpaceDimension() << ",["; + std::vector<int> ngs(getImageMesh()->getNodeGridStructure()); + std::vector<double> orig(getImageMesh()->getOrigin()),dxyz(getImageMesh()->getDXYZ()); + std::copy(ngs.begin(),ngs.end(),std::ostream_iterator<int>(oss,",")); + oss << "],["; + std::copy(orig.begin(),orig.end(),std::ostream_iterator<double>(oss,",")); + oss << "],["; + std::copy(dxyz.begin(),dxyz.end(),std::ostream_iterator<double>(oss,",")); + oss << "])\n"; + dumpPatchesOf("amr",oss); + return oss.str(); +} + +MEDCouplingCartesianAMRMeshGen::MEDCouplingCartesianAMRMeshGen(const MEDCouplingCartesianAMRMeshGen& other):RefCountObject(other),_mesh(other._mesh),_patches(other._patches),_factors(other._factors) +{ + const MEDCouplingIMesh *mesh(other._mesh); + if(mesh) + _mesh=static_cast<MEDCouplingIMesh *>(mesh->deepCpy()); + std::size_t sz(other._patches.size()); + for(std::size_t i=0;i<sz;i++) + { + const MEDCouplingCartesianAMRPatch *patch(other._patches[i]); + if(patch) + _patches[i]=patch->deepCpy(this); + } +} + +MEDCouplingCartesianAMRMeshGen::MEDCouplingCartesianAMRMeshGen(const std::string& meshName, int spaceDim, const int *nodeStrctStart, const int *nodeStrctStop, + const double *originStart, const double *originStop, const double *dxyzStart, const double *dxyzStop) +{ + _mesh=MEDCouplingIMesh::New(meshName,spaceDim,nodeStrctStart,nodeStrctStop,originStart,originStop,dxyzStart,dxyzStop); +} + +MEDCouplingCartesianAMRMeshGen::MEDCouplingCartesianAMRMeshGen(MEDCouplingIMesh *mesh) +{ + if(!mesh) + throw INTERP_KERNEL::Exception("MEDCouplingCartesianAMRMeshGen(MEDCouplingIMesh *mesh) constructor : The input mesh is null !"); + mesh->checkCoherency(); + _mesh=mesh; _mesh->incrRef(); +} + +void MEDCouplingCartesianAMRMeshGen::checkPatchId(int patchId) const +{ + int sz(getNumberOfPatches()); + if(patchId<0 || patchId>=sz) + { + std::ostringstream oss; oss << "MEDCouplingCartesianAMRMeshGen::checkPatchId : invalid patchId (" << patchId << ") ! Must be in [0," << sz << ") !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } +} + +void MEDCouplingCartesianAMRMeshGen::checkFactorsAndIfNotSetAssign(const std::vector<int>& factors) +{ + if(getSpaceDimension()!=(int)factors.size()) + throw INTERP_KERNEL::Exception("MEDCouplingCartesianAMRMeshGen::checkFactorsAndIfNotSetAssign : invalid size of factors ! size must be equal to the spaceDimension !"); + if(_factors.empty()) + { + _factors=factors; + } + else + { + if(_factors!=factors) + throw INTERP_KERNEL::Exception("MEDCouplingCartesianAMRMesh::checkFactorsAndIfNotSetAssign : the factors "); + } +} + +void MEDCouplingCartesianAMRMeshGen::retrieveGridsAtInternal(int lev, std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCouplingCartesianAMRPatchGen> >& grids) const +{ + if(lev==0) + { + const MEDCouplingCartesianAMRMesh *thisc(dynamic_cast<const MEDCouplingCartesianAMRMesh *>(this));//tony + MEDCouplingAutoRefCountObjectPtr<MEDCouplingCartesianAMRPatchGF> elt(new MEDCouplingCartesianAMRPatchGF(const_cast<MEDCouplingCartesianAMRMesh *>(thisc))); + grids.push_back(DynamicCastSafe<MEDCouplingCartesianAMRPatchGF,MEDCouplingCartesianAMRPatchGen>(elt)); + } + else if(lev==1) + { + for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCouplingCartesianAMRPatch> >::const_iterator it=_patches.begin();it!=_patches.end();it++) + { + const MEDCouplingCartesianAMRPatch *pt(*it); + if(pt) + { + MEDCouplingAutoRefCountObjectPtr<MEDCouplingCartesianAMRPatch> tmp1(*it); + grids.push_back(DynamicCastSafe<MEDCouplingCartesianAMRPatch,MEDCouplingCartesianAMRPatchGen>(tmp1)); + } + } + } + else + { + for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCouplingCartesianAMRPatch> >::const_iterator it=_patches.begin();it!=_patches.end();it++) + { + const MEDCouplingCartesianAMRPatch *pt(*it); + if(pt) + pt->getMesh()->retrieveGridsAtInternal(lev-1,grids); + } + } +} + +int MEDCouplingCartesianAMRMeshGen::GetGhostLevelInFineRef(int ghostLev, const std::vector<int>& factors) +{ + if(ghostLev<0) + throw INTERP_KERNEL::Exception("MEDCouplingCartesianAMRMesh::GetGhostLevelInFineRef : the ghost size must be >=0 !"); + if(factors.empty()) + throw INTERP_KERNEL::Exception("MEDCouplingCartesianAMRMesh::GetGhostLevelInFineRef : no factors defined !"); + int ghostLevInPatchRef; + if(ghostLev==0) + ghostLevInPatchRef=0; + else + { + ghostLevInPatchRef=(ghostLev-1)/factors[0]+1; + for(std::size_t i=0;i<factors.size();i++) + ghostLevInPatchRef=std::max(ghostLevInPatchRef,(ghostLev-1)/factors[i]+1); + } + return ghostLevInPatchRef; +} + +/*! + * This method returns a sub set of \a all. The subset is defined by the \a head in the tree defined by \a this. + * Elements in \a all are expected to be sorted from god father to most refined structure. + */ +std::vector<const DataArrayDouble *> MEDCouplingCartesianAMRMeshGen::extractSubTreeFromGlobalFlatten(const MEDCouplingCartesianAMRMeshGen *head, const std::vector<const DataArrayDouble *>& all) const +{ + int maxLev(getMaxNumberOfLevelsRelativeToThis()); + std::vector<const DataArrayDouble *> ret; + std::vector<const MEDCouplingCartesianAMRMeshGen *> meshes(1,this); + std::size_t kk(0); + for(int i=0;i<maxLev;i++) + { + std::vector<const MEDCouplingCartesianAMRMeshGen *> meshesTmp; + for(std::vector<const MEDCouplingCartesianAMRMeshGen *>::const_iterator it=meshes.begin();it!=meshes.end();it++) + { + if((*it)==head || head->isObjectInTheProgeny(*it)) + ret.push_back(all[kk]); + kk++; + std::vector< const MEDCouplingCartesianAMRPatch *> ps((*it)->getPatches()); + for(std::vector< const MEDCouplingCartesianAMRPatch *>::const_iterator it0=ps.begin();it0!=ps.end();it0++) + { + const MEDCouplingCartesianAMRMeshGen *mesh((*it0)->getMesh()); + meshesTmp.push_back(mesh); + } + } + meshes=meshesTmp; + } + if(kk!=all.size()) + throw INTERP_KERNEL::Exception("MEDCouplingCartesianAMRMeshGen::extractSubTreeFromGlobalFlatten : the size of input vector is not compatible with number of leaves in this !"); + return ret; +} + +void MEDCouplingCartesianAMRMeshGen::dumpPatchesOf(const std::string& varName, std::ostream& oss) const +{ + std::size_t j(0); + for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCouplingCartesianAMRPatch> >::const_iterator it=_patches.begin();it!=_patches.end();it++) + { + const MEDCouplingCartesianAMRPatch *patch(*it); + if(patch) + { + std::ostringstream oss2; oss2 << varName << ".addPatch(["; + const std::vector< std::pair<int,int> >& bltr(patch->getBLTRRange()); + std::size_t sz(bltr.size()); + for(std::size_t i=0;i<sz;i++) + { + oss2 << "(" << bltr[i].first << "," << bltr[i].second << ")"; + if(i!=sz-1) + oss2 << ","; + } + oss2 << "],["; + std::copy(_factors.begin(),_factors.end(),std::ostream_iterator<int>(oss2,",")); + oss2 << "])\n"; + oss << oss2.str(); + std::ostringstream oss3; oss3 << varName << "[" << j++ << "]"; + patch->getMesh()->dumpPatchesOf(oss3.str(),oss); + } + } +} + +std::size_t MEDCouplingCartesianAMRMeshGen::getHeapMemorySizeWithoutChildren() const +{ + return sizeof(MEDCouplingCartesianAMRMeshGen); +} + +std::vector<const BigMemoryObject *> MEDCouplingCartesianAMRMeshGen::getDirectChildrenWithNull() const +{ + std::vector<const BigMemoryObject *> ret; + ret.push_back((const MEDCouplingIMesh *)_mesh); + for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCouplingCartesianAMRPatch> >::const_iterator it=_patches.begin();it!=_patches.end();it++) + ret.push_back((const MEDCouplingCartesianAMRPatch*)*it); + return ret; +} + +void MEDCouplingCartesianAMRMeshGen::updateTime() const +{ + if((const MEDCouplingIMesh *)_mesh) + updateTimeWith(*_mesh); + for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCouplingCartesianAMRPatch> >::const_iterator it=_patches.begin();it!=_patches.end();it++) + { + const MEDCouplingCartesianAMRPatch *elt(*it); + if(!elt) + continue; + const MEDCouplingCartesianAMRMeshGen *mesh(elt->getMesh()); + if(mesh) + updateTimeWith(*mesh); + } +} + +MEDCouplingCartesianAMRMeshSub::MEDCouplingCartesianAMRMeshSub(MEDCouplingCartesianAMRMeshGen *father, MEDCouplingIMesh *mesh):MEDCouplingCartesianAMRMeshGen(mesh),_father(father) +{ + if(!_father) + throw INTERP_KERNEL::Exception("MEDCouplingCartesianAMRMeshSub(MEDCouplingCartesianAMRMeshGen *father, MEDCouplingIMesh *mesh) constructor : empty father !"); +} + +const MEDCouplingCartesianAMRMeshGen *MEDCouplingCartesianAMRMeshSub::getFather() const +{ + return _father; +} + +const MEDCouplingCartesianAMRMeshGen *MEDCouplingCartesianAMRMeshSub::getGodFather() const +{ + if(!_father) + throw INTERP_KERNEL::Exception("MEDCouplingCartesianAMRMeshSub::getGodFather : Impossible to find a god father because there is a hole in chain !"); + return _father->getGodFather(); +} + +/*! + * This method returns the level of \a this. 0 for god father. 1 for children of god father ... + */ +int MEDCouplingCartesianAMRMeshSub::getAbsoluteLevel() const +{ + if(!_father) + throw INTERP_KERNEL::Exception("MEDCouplingCartesianAMRMeshSub::getAbsoluteLevel : Impossible to find a god father because there is a hole in chain !"); + return _father->getAbsoluteLevel()+1; +} + +void MEDCouplingCartesianAMRMeshSub::detachFromFather() +{ + _father=0; + declareAsNew(); +} + +std::vector< std::pair<int,int> > MEDCouplingCartesianAMRMeshSub::positionRelativeToGodFather(std::vector<int>& st) const +{ + st=_father->getFactors(); + std::size_t dim(st.size()); + std::vector<int> prev(st); + int id(_father->getPatchIdFromChildMesh(this)); + const MEDCouplingCartesianAMRPatch *p(_father->getPatch(id)); + std::vector< std::pair<int,int> > ret(p->getBLTRRange()); + std::vector<int> delta(MEDCouplingStructuredMesh::GetDimensionsFromCompactFrmt(ret)),start(dim); + std::transform(delta.begin(),delta.end(),prev.begin(),delta.begin(),std::multiplies<int>()); + for(std::size_t i=0;i<dim;i++) + start[i]=ret[i].first; + std::transform(start.begin(),start.end(),prev.begin(),start.begin(),std::multiplies<int>()); + const MEDCouplingCartesianAMRMeshGen *it(_father); + while(!dynamic_cast<const MEDCouplingCartesianAMRMesh *>(it)) + { + const MEDCouplingCartesianAMRMeshSub *itc(static_cast<const MEDCouplingCartesianAMRMeshSub *>(it)); + int id2(itc->_father->getPatchIdFromChildMesh(itc)); + const MEDCouplingCartesianAMRPatch *p2(itc->_father->getPatch(id2)); + const std::vector< std::pair<int,int> >& start2(p2->getBLTRRange()); + std::vector<int> tmp(dim); + for(std::size_t i=0;i<dim;i++) + tmp[i]=start2[i].first; + // + prev=itc->_father->getFactors(); + std::transform(st.begin(),st.end(),prev.begin(),st.begin(),std::multiplies<int>()); + std::transform(st.begin(),st.end(),tmp.begin(),tmp.begin(),std::multiplies<int>()); + std::transform(start.begin(),start.end(),tmp.begin(),start.begin(),std::plus<int>()); + it=itc->_father; + } + for(std::size_t i=0;i<dim;i++) + { + ret[i].first=start[i]; + ret[i].second=start[i]+delta[i]; + } + return ret; +} + +int MEDCouplingCartesianAMRMeshSub::getAbsoluteLevelRelativeTo(const MEDCouplingCartesianAMRMeshGen *ref) const +{ + if(this==ref) + return 0; + if(_father==0) + throw INTERP_KERNEL::Exception("MEDCouplingCartesianAMRMeshSub::getAbsoluteLevelRelativeTo : ref is not in the progeny of this !"); + else + return _father->getAbsoluteLevelRelativeTo(ref)+1; +} + +MEDCouplingCartesianAMRMeshSub::MEDCouplingCartesianAMRMeshSub(const MEDCouplingCartesianAMRMeshSub& other, MEDCouplingCartesianAMRMeshGen *father):MEDCouplingCartesianAMRMeshGen(other),_father(father) +{ +} + +MEDCouplingCartesianAMRMeshSub *MEDCouplingCartesianAMRMeshSub::deepCpy(MEDCouplingCartesianAMRMeshGen *fath) const +{ + return new MEDCouplingCartesianAMRMeshSub(*this,fath); +} + +/*! + * \sa getPositionRelativeTo + */ +void MEDCouplingCartesianAMRMeshSub::getPositionRelativeToInternal(const MEDCouplingCartesianAMRMeshGen *ref, std::vector<int>& ret) const +{ + if(this==ref) + return ; + if(!_father) + throw INTERP_KERNEL::Exception("MEDCouplingCartesianAMRMeshSub::getPositionRelativeToInternal : ref is not in the progeny of this !"); + int myId(_father->getPatchIdFromChildMesh(this)); + ret.push_back(myId); + _father->getPositionRelativeToInternal(ref,ret); +} + +MEDCouplingCartesianAMRMesh *MEDCouplingCartesianAMRMesh::New(const std::string& meshName, int spaceDim, const int *nodeStrctStart, const int *nodeStrctStop, + const double *originStart, const double *originStop, const double *dxyzStart, const double *dxyzStop) +{ + return new MEDCouplingCartesianAMRMesh(meshName,spaceDim,nodeStrctStart,nodeStrctStop,originStart,originStop,dxyzStart,dxyzStop); +} + +MEDCouplingCartesianAMRMesh *MEDCouplingCartesianAMRMesh::New(MEDCouplingIMesh *mesh) +{ + return new MEDCouplingCartesianAMRMesh(mesh); +} + +const MEDCouplingCartesianAMRMeshGen *MEDCouplingCartesianAMRMesh::getFather() const +{ + //I'm god father ! No father ! + return 0; +} + +const MEDCouplingCartesianAMRMeshGen *MEDCouplingCartesianAMRMesh::getGodFather() const +{ + return this; +} + +int MEDCouplingCartesianAMRMesh::getAbsoluteLevel() const +{ + return 0; +} + +void MEDCouplingCartesianAMRMesh::detachFromFather() +{//not a bug - do nothing +} + +std::vector< std::pair<int,int> > MEDCouplingCartesianAMRMesh::positionRelativeToGodFather(std::vector<int>& st) const +{ + st=_mesh->getCellGridStructure(); + return MEDCouplingStructuredMesh::GetCompactFrmtFromDimensions(st); +} + +int MEDCouplingCartesianAMRMesh::getAbsoluteLevelRelativeTo(const MEDCouplingCartesianAMRMeshGen *ref) const +{ + if(this==ref) + return 0; + throw INTERP_KERNEL::Exception("MEDCouplingCartesianAMRMesh::getAbsoluteLevelRelativeTo : ref is not in the progeny of this !"); +} + +std::vector<MEDCouplingCartesianAMRPatchGen *> MEDCouplingCartesianAMRMesh::retrieveGridsAt(int absoluteLev) const +{ + std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCouplingCartesianAMRPatchGen> > rets; + retrieveGridsAtInternal(absoluteLev,rets); + std::vector< MEDCouplingCartesianAMRPatchGen * > ret(rets.size()); + for(std::size_t i=0;i<rets.size();i++) + { + ret[i]=rets[i].retn(); + } + return ret; +} + +MEDCouplingCartesianAMRMesh *MEDCouplingCartesianAMRMesh::deepCpy(MEDCouplingCartesianAMRMeshGen *father) const +{ + if(father) + throw INTERP_KERNEL::Exception("MEDCouplingCartesianAMRMesh::deepCpy : specifying a not null father for a God Father object !"); + return new MEDCouplingCartesianAMRMesh(*this); +} + +/*! + * This method creates a multi level patches split at once. + * This method calls as times as size of \a bso createPatchesFromCriterion. Size of \a bso and size of \a factors must be the same ! + * \b WARNING, after the call the number of levels in \a this is equal to bso.size() + 1 ! + * + * \param [in] bso + * \param [in] criterion + * \param [in] factors + * \param [in] eps - See DataArrayDouble::toVectorOfBool for more information about the semantic of eps. + * + * \sa createPatchesFromCriterion + */ +void MEDCouplingCartesianAMRMesh::createPatchesFromCriterionML(const std::vector<const INTERP_KERNEL::BoxSplittingOptions *>& bso, const DataArrayDouble *criterion, const std::vector< std::vector<int> >& factors, double eps) +{ + std::size_t nbOfLevs(bso.size()); + if(nbOfLevs!=factors.size()) + throw INTERP_KERNEL::Exception("MEDCouplingCartesianAMRMesh::createPatchesFromCriterionML : size of vectors must be the same !"); + if(nbOfLevs==0) + return ; + if(!bso[0]) + throw INTERP_KERNEL::Exception("MEDCouplingCartesianAMRMesh::createPatchesFromCriterionML : pointers in 1st arg must be not NULL !"); + createPatchesFromCriterion(*bso[0],criterion,factors[0],eps); + for(std::size_t i=1;i<nbOfLevs;i++) + { + if(!bso[i]) + throw INTERP_KERNEL::Exception("MEDCouplingCartesianAMRMesh::createPatchesFromCriterionML : presence of a NULL BoxSplittingOptions in input vector !"); + // + std::vector<MEDCouplingCartesianAMRPatchGen *> elts(retrieveGridsAt((int)(i))); + std::size_t sz(elts.size()); + std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCouplingCartesianAMRPatchGen> > elts2(sz); + std::vector< MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> > elts3(sz); + for(std::size_t ii=0;ii<sz;ii++) + elts2[ii]=elts[ii]; + // + static const char TMP_STR[]="TMP"; + std::vector< std::pair<std::string,int> > fieldNames(1); fieldNames[0].first=TMP_STR; fieldNames[0].second=1; + MEDCouplingAutoRefCountObjectPtr<MEDCouplingAMRAttribute> att(MEDCouplingAMRAttribute::New(this,fieldNames,0)); + att->alloc(); + DataArrayDouble *tmpDa(const_cast<DataArrayDouble *>(att->getFieldOn(this,TMP_STR))); + tmpDa->cpyFrom(*criterion); + att->synchronizeCoarseToFine(); + for(std::size_t ii=0;ii<sz;ii++) + { + const DataArrayDouble *critOnLeaf(att->getFieldOn(const_cast<MEDCouplingCartesianAMRMeshGen *>(elts[ii]->getMesh()),TMP_STR)); + elts3[ii]=const_cast<DataArrayDouble *>(critOnLeaf); elts3[ii]->incrRef(); + } + att=0; + for(std::size_t ii=0;ii<sz;ii++) + const_cast<MEDCouplingCartesianAMRMeshGen *>(elts[ii]->getMesh())->createPatchesFromCriterion(*bso[i],elts3[ii],factors[i],eps); + } +} + +void MEDCouplingCartesianAMRMesh::getPositionRelativeToInternal(const MEDCouplingCartesianAMRMeshGen *ref, std::vector<int>& ret) const +{ + +} + +MEDCouplingCartesianAMRMesh::MEDCouplingCartesianAMRMesh(const MEDCouplingCartesianAMRMesh& other):MEDCouplingCartesianAMRMeshGen(other) +{ +} + +MEDCouplingCartesianAMRMesh::MEDCouplingCartesianAMRMesh(const std::string& meshName, int spaceDim, const int *nodeStrctStart, const int *nodeStrctStop, + const double *originStart, const double *originStop, const double *dxyzStart, const double *dxyzStop):MEDCouplingCartesianAMRMeshGen(meshName,spaceDim,nodeStrctStart,nodeStrctStop,originStart,originStop,dxyzStart,dxyzStop) +{ +} + +MEDCouplingCartesianAMRMesh::MEDCouplingCartesianAMRMesh(MEDCouplingIMesh *mesh):MEDCouplingCartesianAMRMeshGen(mesh) +{ +} + +std::vector<const BigMemoryObject *> MEDCouplingCartesianAMRMesh::getDirectChildrenWithNull() const +{ + std::vector<const BigMemoryObject *> ret(MEDCouplingCartesianAMRMeshGen::getDirectChildrenWithNull()); + return ret; +} + +MEDCouplingCartesianAMRMesh::~MEDCouplingCartesianAMRMesh() +{ +} diff --git a/src/medtool/src/MEDCoupling/MEDCouplingCartesianAMRMesh.hxx b/src/medtool/src/MEDCoupling/MEDCouplingCartesianAMRMesh.hxx new file mode 100644 index 000000000..f67e08064 --- /dev/null +++ b/src/medtool/src/MEDCoupling/MEDCouplingCartesianAMRMesh.hxx @@ -0,0 +1,258 @@ +// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 +// 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 + +#ifndef __MEDCOUPLINGCARTESIANAMRMESH_HXX__ +#define __MEDCOUPLINGCARTESIANAMRMESH_HXX__ + +#include "MEDCoupling.hxx" +#include "MEDCouplingTimeLabel.hxx" +#include "MEDCouplingRefCountObject.hxx" +#include "MEDCouplingAutoRefCountObjectPtr.hxx" + +#include "BoxSplittingOptions.hxx" +#include "InterpKernelException.hxx" + +namespace ParaMEDMEM +{ + class MEDCouplingIMesh; + class MEDCouplingUMesh; + class DataArrayInt; + class DataArrayByte; + class DataArrayDouble; + class MEDCoupling1SGTUMesh; + class MEDCouplingFieldDouble; + class MEDCouplingCartesianAMRMesh; + class MEDCouplingCartesianAMRMeshGen; + + /// @cond INTERNAL + + /*! + * This class does not inherit from TimeLabel so only const method should exist. + */ + class MEDCouplingCartesianAMRPatchGen : public RefCountObject + { + public: + MEDCOUPLING_EXPORT virtual MEDCouplingCartesianAMRPatchGen *deepCpy(MEDCouplingCartesianAMRMeshGen *father) const = 0; + MEDCOUPLING_EXPORT int getNumberOfCellsRecursiveWithOverlap() const; + MEDCOUPLING_EXPORT int getNumberOfCellsRecursiveWithoutOverlap() const; + MEDCOUPLING_EXPORT int getMaxNumberOfLevelsRelativeToThis() const; + MEDCOUPLING_EXPORT const MEDCouplingCartesianAMRMeshGen *getMesh() const { return _mesh; } + protected: + MEDCouplingCartesianAMRPatchGen(const MEDCouplingCartesianAMRPatchGen& other, MEDCouplingCartesianAMRMeshGen *father); + MEDCouplingCartesianAMRPatchGen(MEDCouplingCartesianAMRMeshGen *mesh); + const MEDCouplingCartesianAMRMeshGen *getMeshSafe() const; + MEDCouplingCartesianAMRMeshGen *getMeshSafe(); + private: + std::vector<const BigMemoryObject *> getDirectChildrenWithNull() const; + protected: + MEDCouplingAutoRefCountObjectPtr<MEDCouplingCartesianAMRMeshGen> _mesh; + }; + + /*! + * This class does not inherit from TimeLabel so only const method should exist. + */ + class MEDCouplingCartesianAMRPatch : public MEDCouplingCartesianAMRPatchGen + { + public: + MEDCouplingCartesianAMRPatch(MEDCouplingCartesianAMRMeshGen *mesh, const std::vector< std::pair<int,int> >& bottomLeftTopRight); + MEDCouplingCartesianAMRPatch *deepCpy(MEDCouplingCartesianAMRMeshGen *father) const; + // direct forward to _mesh + MEDCOUPLING_EXPORT void addPatch(const std::vector< std::pair<int,int> >& bottomLeftTopRight, const std::vector<int>& factors); + // end of direct forward to _mesh + MEDCOUPLING_EXPORT int getNumberOfOverlapedCellsForFather() const; + MEDCOUPLING_EXPORT bool isInMyNeighborhood(const MEDCouplingCartesianAMRPatch *other, int ghostLev) const; + MEDCOUPLING_EXPORT bool isInMyNeighborhoodExt(const MEDCouplingCartesianAMRPatch *other, int ghostLev) const; + MEDCOUPLING_EXPORT bool isInMyNeighborhoodDiffLev(const MEDCouplingCartesianAMRPatch *other, int ghostLev) const; + // basic set/get + MEDCOUPLING_EXPORT const std::vector< std::pair<int,int> >& getBLTRRange() const { return _bl_tr; } + MEDCOUPLING_EXPORT std::vector< std::pair<int,int> > getBLTRRangeRelativeToGF() const; + MEDCOUPLING_EXPORT std::vector<int> computeCellGridSt() const; + MEDCOUPLING_EXPORT static bool IsInMyNeighborhood(int ghostLev, const std::vector< std::pair<int,int> >& p1, const std::vector< std::pair<int,int> >& p2); + // + static std::vector< std::vector< std::pair<const MEDCouplingCartesianAMRPatch *,const MEDCouplingCartesianAMRPatch *> > > FindNeighborsOfSubPatchesOfSameLev(int ghostLev, const MEDCouplingCartesianAMRPatch *p1, const MEDCouplingCartesianAMRPatch *p2); + static void FindNeighborsOfSubPatchesOf(int ghostLev, const MEDCouplingCartesianAMRPatch *p1, const MEDCouplingCartesianAMRPatch *p2, std::vector< std::pair<const MEDCouplingCartesianAMRPatch *,const MEDCouplingCartesianAMRPatch *> >& ret); + static void UpdateNeighborsOfOneWithTwo(int ghostLev, const std::vector<int>& factors, const MEDCouplingCartesianAMRPatch *p1, const MEDCouplingCartesianAMRPatch *p2, DataArrayDouble *dataOnP1, const DataArrayDouble *dataOnP2); + static void UpdateNeighborsOfOneWithTwoExt(int ghostLev, const MEDCouplingCartesianAMRPatch *p1, const MEDCouplingCartesianAMRPatch *p2, DataArrayDouble *dataOnP1, const DataArrayDouble *dataOnP2); + static void UpdateNeighborsOfOneWithTwoMixedLev(int ghostLev, const MEDCouplingCartesianAMRPatch *p1, const MEDCouplingCartesianAMRPatch *p2, DataArrayDouble *dataOnP1, const DataArrayDouble *dataOnP2, bool isConservative); + private: + static void ComputeZonesOfTwoRelativeToOneDiffLev(int ghostLev, const MEDCouplingCartesianAMRPatch *p1, const MEDCouplingCartesianAMRPatch *p2, std::vector< std::pair<int,int> >& p1Zone, std::vector< std::pair<int,int> >& p2Zone, std::vector<int>& factToApplyOn2); + private: + std::size_t getHeapMemorySizeWithoutChildren() const; + static const MEDCouplingCartesianAMRMeshGen *FindCommonAncestor(const MEDCouplingCartesianAMRPatch *p1, const MEDCouplingCartesianAMRPatch *p2, int& lev); + static std::vector<int> ComputeOffsetFromTwoToOne(const MEDCouplingCartesianAMRMeshGen *comAncestor, int lev, const MEDCouplingCartesianAMRPatch *p1, const MEDCouplingCartesianAMRPatch *p2); + static void UpdateNeighborsOfOneWithTwoInternal(int ghostLev, const std::vector<int>& factors, const std::vector< std::pair<int,int> >&p1 ,const std::vector< std::pair<int,int> >&p2, DataArrayDouble *dataOnP1, const DataArrayDouble *dataOnP2); + public: + static void ApplyFactorsOnCompactFrmt(std::vector< std::pair<int,int> >& partBeforeFact, const std::vector<int>& factors); + static void ApplyAllGhostOnCompactFrmt(std::vector< std::pair<int,int> >& partBeforeFact, int ghostSize); + private: + MEDCouplingCartesianAMRPatch(const MEDCouplingCartesianAMRPatch& other, MEDCouplingCartesianAMRMeshGen *father); + private: + //! bottom left/top right cell range relative to \a _father + std::vector< std::pair<int,int> > _bl_tr; + }; + + /*! + * This class does not inherit from TimeLabel so only const method should exist. + */ + class MEDCouplingCartesianAMRPatchGF : public MEDCouplingCartesianAMRPatchGen + { + public: + MEDCouplingCartesianAMRPatchGF(MEDCouplingCartesianAMRMesh *mesh); + MEDCouplingCartesianAMRPatchGF *deepCpy(MEDCouplingCartesianAMRMeshGen *father) const; + private: + std::size_t getHeapMemorySizeWithoutChildren() const; + private: + MEDCouplingCartesianAMRPatchGF(const MEDCouplingCartesianAMRPatchGF& other, MEDCouplingCartesianAMRMeshGen *father); + }; + + /// @endcond + + /*! + * This class is the base class dedicated to AMR using Adaptative Hierarchical Overlapped image Grid. + * This class does \b NOT inherit from MEDCouplingMesh because this class overlaps image grid structured meshes to perform adaptative mesh refinement. + * But this class aggregates MEDCouplingMesh instances ! + */ + class MEDCouplingCartesianAMRMeshGen : public RefCountObject, public TimeLabel + { + public: + MEDCOUPLING_EXPORT virtual MEDCouplingCartesianAMRMeshGen *deepCpy(MEDCouplingCartesianAMRMeshGen *father) const = 0; + MEDCOUPLING_EXPORT int getSpaceDimension() const; + MEDCOUPLING_EXPORT const std::vector<int>& getFactors() const { return _factors; } + MEDCOUPLING_EXPORT void setFactors(const std::vector<int>& newFactors); + MEDCOUPLING_EXPORT int getMaxNumberOfLevelsRelativeToThis() const; + MEDCOUPLING_EXPORT int getNumberOfCellsAtCurrentLevel() const; + MEDCOUPLING_EXPORT int getNumberOfCellsAtCurrentLevelGhost(int ghostLev) const; + MEDCOUPLING_EXPORT int getNumberOfCellsRecursiveWithOverlap() const; + MEDCOUPLING_EXPORT int getNumberOfCellsRecursiveWithoutOverlap() const; + MEDCOUPLING_EXPORT const MEDCouplingIMesh *getImageMesh() const { return _mesh; } + // + MEDCOUPLING_EXPORT virtual const MEDCouplingCartesianAMRMeshGen *getFather() const = 0; + MEDCOUPLING_EXPORT virtual const MEDCouplingCartesianAMRMeshGen *getGodFather() const = 0; + MEDCOUPLING_EXPORT virtual int getAbsoluteLevel() const = 0; + MEDCOUPLING_EXPORT virtual void detachFromFather() = 0; + MEDCOUPLING_EXPORT virtual std::vector< std::pair<int,int> > positionRelativeToGodFather(std::vector<int>& st) const = 0; + MEDCOUPLING_EXPORT virtual int getAbsoluteLevelRelativeTo(const MEDCouplingCartesianAMRMeshGen *ref) const = 0; + MEDCOUPLING_EXPORT std::vector<int> getPositionRelativeTo(const MEDCouplingCartesianAMRMeshGen *ref) const; + MEDCOUPLING_EXPORT const MEDCouplingCartesianAMRPatch *getPatchAtPosition(const std::vector<int>& pos) const; + MEDCOUPLING_EXPORT const MEDCouplingCartesianAMRMeshGen *getMeshAtPosition(const std::vector<int>& pos) const; + MEDCOUPLING_EXPORT virtual std::vector<MEDCouplingCartesianAMRPatchGen *> retrieveGridsAt(int absoluteLev) const; + MEDCOUPLING_EXPORT void addPatch(const std::vector< std::pair<int,int> >& bottomLeftTopRight, const std::vector<int>& factors); + MEDCOUPLING_EXPORT void removeAllPatches(); + MEDCOUPLING_EXPORT void removePatch(int patchId); + MEDCOUPLING_EXPORT int getNumberOfPatches() const; + MEDCOUPLING_EXPORT void createPatchesFromCriterion(const INTERP_KERNEL::BoxSplittingOptions& bso, const std::vector<bool>& criterion, const std::vector<int>& factors); + MEDCOUPLING_EXPORT void createPatchesFromCriterion(const INTERP_KERNEL::BoxSplittingOptions& bso, const DataArrayByte *criterion, const std::vector<int>& factors); + MEDCOUPLING_EXPORT void createPatchesFromCriterion(const INTERP_KERNEL::BoxSplittingOptions& bso, const DataArrayDouble *criterion, const std::vector<int>& factors, double eps); + MEDCOUPLING_EXPORT int getPatchIdFromChildMesh(const MEDCouplingCartesianAMRMeshGen *mesh) const; + MEDCOUPLING_EXPORT std::vector< const MEDCouplingCartesianAMRPatch *> getPatches() const; + MEDCOUPLING_EXPORT const MEDCouplingCartesianAMRPatch *getPatch(int patchId) const; + MEDCOUPLING_EXPORT bool isPatchInNeighborhoodOf(int patchId1, int patchId2, int ghostLev) const; + MEDCOUPLING_EXPORT DataArrayDouble *createCellFieldOnPatch(int patchId, const DataArrayDouble *cellFieldOnThis) const; + // coarse to fine + MEDCOUPLING_EXPORT void fillCellFieldOnPatch(int patchId, const DataArrayDouble *cellFieldOnThis, DataArrayDouble *cellFieldOnPatch, bool isConservative=true) const; + MEDCOUPLING_EXPORT void fillCellFieldOnPatchGhost(int patchId, const DataArrayDouble *cellFieldOnThis, DataArrayDouble *cellFieldOnPatch, int ghostLev, bool isConservative=true) const; + MEDCOUPLING_EXPORT void fillCellFieldOnPatchOnlyOnGhostZone(int patchId, const DataArrayDouble *cellFieldOnThis, DataArrayDouble *cellFieldOnPatch, int ghostLev) const; + // coarse to fine + fine to fine + MEDCOUPLING_EXPORT void fillCellFieldOnPatchGhostAdv(int patchId, const DataArrayDouble *cellFieldOnThis, int ghostLev, const std::vector<const DataArrayDouble *>& arrsOnPatches, bool isConservative=true) const; + // fine to fine + MEDCOUPLING_EXPORT void fillCellFieldOnPatchOnlyGhostAdv(int patchId, int ghostLev, const std::vector<const DataArrayDouble *>& arrsOnPatches) const; + MEDCOUPLING_EXPORT void fillCellFieldOnPatchOnlyOnGhostZoneWith(int ghostLev, const MEDCouplingCartesianAMRPatch *patchToBeModified, const MEDCouplingCartesianAMRPatch *neighborPatch, DataArrayDouble *cellFieldOnPatch, const DataArrayDouble *cellFieldNeighbor) const; + // fine to coarse + MEDCOUPLING_EXPORT void fillCellFieldComingFromPatch(int patchId, const DataArrayDouble *cellFieldOnPatch, DataArrayDouble *cellFieldOnThis, bool isConservative=true) const; + MEDCOUPLING_EXPORT void fillCellFieldComingFromPatchGhost(int patchId, const DataArrayDouble *cellFieldOnPatch, DataArrayDouble *cellFieldOnThis, int ghostLev, bool isConservative=true) const; + // + MEDCOUPLING_EXPORT DataArrayInt *findPatchesInTheNeighborhoodOf(int patchId, int ghostLev) const; + // + MEDCOUPLING_EXPORT MEDCouplingUMesh *buildUnstructured() const; + MEDCOUPLING_EXPORT MEDCoupling1SGTUMesh *buildMeshFromPatchEnvelop() const; + MEDCOUPLING_EXPORT MEDCoupling1SGTUMesh *buildMeshOfDirectChildrenOnly() const; + MEDCOUPLING_EXPORT MEDCouplingFieldDouble *buildCellFieldOnRecurseWithoutOverlapWithoutGhost(int ghostSz, const std::vector<const DataArrayDouble *>& recurseArrs) const; + MEDCOUPLING_EXPORT DataArrayDouble *extractGhostFrom(int ghostSz, const DataArrayDouble *arr) const; + MEDCOUPLING_EXPORT std::vector<int> getPatchIdsInTheNeighborhoodOf(int patchId, int ghostLev) const; + MEDCOUPLING_EXPORT std::string buildPythonDumpOfThis() const; + protected: + MEDCouplingCartesianAMRMeshGen(const MEDCouplingCartesianAMRMeshGen& other); + MEDCouplingCartesianAMRMeshGen(const std::string& meshName, int spaceDim, const int *nodeStrctStart, const int *nodeStrctStop, + const double *originStart, const double *originStop, const double *dxyzStart, const double *dxyzStop); + MEDCouplingCartesianAMRMeshGen(MEDCouplingIMesh *mesh); + void checkPatchId(int patchId) const; + void checkFactorsAndIfNotSetAssign(const std::vector<int>& factors); + void retrieveGridsAtInternal(int lev, std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCouplingCartesianAMRPatchGen> >& grids) const; + static int GetGhostLevelInFineRef(int ghostLev, const std::vector<int>& factors); + std::vector<const DataArrayDouble *> extractSubTreeFromGlobalFlatten(const MEDCouplingCartesianAMRMeshGen *head, const std::vector<const DataArrayDouble *>& all) const; + void dumpPatchesOf(const std::string& varName, std::ostream& oss) const; + public: + virtual void getPositionRelativeToInternal(const MEDCouplingCartesianAMRMeshGen *ref, std::vector<int>& ret) const = 0; + protected: + MEDCOUPLING_EXPORT std::size_t getHeapMemorySizeWithoutChildren() const; + MEDCOUPLING_EXPORT std::vector<const BigMemoryObject *> getDirectChildrenWithNull() const; + MEDCOUPLING_EXPORT void updateTime() const; + protected: + MEDCouplingAutoRefCountObjectPtr<MEDCouplingIMesh> _mesh; + std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCouplingCartesianAMRPatch> > _patches; + std::vector<int> _factors; + }; + + class MEDCouplingCartesianAMRMeshSub : public MEDCouplingCartesianAMRMeshGen + { + public: + MEDCouplingCartesianAMRMeshSub(MEDCouplingCartesianAMRMeshGen *father, MEDCouplingIMesh *mesh); + MEDCOUPLING_EXPORT const MEDCouplingCartesianAMRMeshGen *getFather() const; + MEDCOUPLING_EXPORT const MEDCouplingCartesianAMRMeshGen *getGodFather() const; + MEDCOUPLING_EXPORT int getAbsoluteLevel() const; + MEDCOUPLING_EXPORT void detachFromFather(); + MEDCOUPLING_EXPORT std::vector< std::pair<int,int> > positionRelativeToGodFather(std::vector<int>& st) const; + MEDCOUPLING_EXPORT int getAbsoluteLevelRelativeTo(const MEDCouplingCartesianAMRMeshGen *ref) const; + private: + MEDCouplingCartesianAMRMeshSub(const MEDCouplingCartesianAMRMeshSub& other, MEDCouplingCartesianAMRMeshGen *father); + MEDCouplingCartesianAMRMeshSub *deepCpy(MEDCouplingCartesianAMRMeshGen *father) const; + void getPositionRelativeToInternal(const MEDCouplingCartesianAMRMeshGen *ref, std::vector<int>& ret) const; + protected: + MEDCouplingCartesianAMRMeshGen *_father; + }; + + class MEDCouplingCartesianAMRMesh : public MEDCouplingCartesianAMRMeshGen + { + public: + MEDCOUPLING_EXPORT static MEDCouplingCartesianAMRMesh *New(const std::string& meshName, int spaceDim, const int *nodeStrctStart, const int *nodeStrctStop, + const double *originStart, const double *originStop, const double *dxyzStart, const double *dxyzStop); + MEDCOUPLING_EXPORT static MEDCouplingCartesianAMRMesh *New(MEDCouplingIMesh *mesh); + MEDCOUPLING_EXPORT const MEDCouplingCartesianAMRMeshGen *getFather() const; + MEDCOUPLING_EXPORT const MEDCouplingCartesianAMRMeshGen *getGodFather() const; + MEDCOUPLING_EXPORT int getAbsoluteLevel() const; + MEDCOUPLING_EXPORT void detachFromFather(); + MEDCOUPLING_EXPORT std::vector< std::pair<int,int> > positionRelativeToGodFather(std::vector<int>& st) const; + MEDCOUPLING_EXPORT int getAbsoluteLevelRelativeTo(const MEDCouplingCartesianAMRMeshGen *ref) const; + MEDCOUPLING_EXPORT std::vector<MEDCouplingCartesianAMRPatchGen *> retrieveGridsAt(int absoluteLev) const; + MEDCouplingCartesianAMRMesh *deepCpy(MEDCouplingCartesianAMRMeshGen *father) const; + MEDCOUPLING_EXPORT void createPatchesFromCriterionML(const std::vector<const INTERP_KERNEL::BoxSplittingOptions *>& bso, const DataArrayDouble *criterion, const std::vector< std::vector<int> >& factors, double eps); + private: + void getPositionRelativeToInternal(const MEDCouplingCartesianAMRMeshGen *ref, std::vector<int>& ret) const; + MEDCouplingCartesianAMRMesh(const MEDCouplingCartesianAMRMesh& other); + MEDCouplingCartesianAMRMesh(const std::string& meshName, int spaceDim, const int *nodeStrctStart, const int *nodeStrctStop, + const double *originStart, const double *originStop, const double *dxyzStart, const double *dxyzStop); + MEDCouplingCartesianAMRMesh(MEDCouplingIMesh *mesh); + MEDCOUPLING_EXPORT std::vector<const BigMemoryObject *> getDirectChildrenWithNull() const; + ~MEDCouplingCartesianAMRMesh(); + }; +} + +#endif + diff --git a/src/medtool/src/MEDCoupling/MEDCouplingCurveLinearMesh.cxx b/src/medtool/src/MEDCoupling/MEDCouplingCurveLinearMesh.cxx new file mode 100644 index 000000000..601ea910d --- /dev/null +++ b/src/medtool/src/MEDCoupling/MEDCouplingCurveLinearMesh.cxx @@ -0,0 +1,936 @@ +// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 +// 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 <functional> +#include <algorithm> +#include <sstream> +#include <numeric> + +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 std::string& 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::getHeapMemorySizeWithoutChildren() const +{ + std::size_t ret(MEDCouplingStructuredMesh::getHeapMemorySizeWithoutChildren()); + ret+=_structure.capacity()*sizeof(int); + return ret; +} + +std::vector<const BigMemoryObject *> MEDCouplingCurveLinearMesh::getDirectChildrenWithNull() const +{ + std::vector<const BigMemoryObject *> ret; + ret.push_back((const DataArrayDouble *)_coords); + return 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) +{ + const MEDCouplingCurveLinearMesh *otherC=dynamic_cast<const MEDCouplingCurveLinearMesh *>(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 +{ + if(!other) + throw INTERP_KERNEL::Exception("MEDCouplingCurveLinearMesh::isEqualIfNotWhy : input other pointer is null !"); + const MEDCouplingCurveLinearMesh *otherC=dynamic_cast<const MEDCouplingCurveLinearMesh *>(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<const MEDCouplingCurveLinearMesh *>(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 +{ + 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, \a this and \a other are the same ! + */ +void MEDCouplingCurveLinearMesh::checkDeepEquivalOnSameNodesWith(const MEDCouplingMesh *other, int cellCompPol, double prec, + DataArrayInt *&cellCor) const +{ + if(!isEqualWithoutConsideringStr(other,prec)) + throw INTERP_KERNEL::Exception("MEDCouplingCurveLinearMesh::checkDeepEquivalOnSameNodesWith : Meshes are not the same !"); +} + +void MEDCouplingCurveLinearMesh::checkCoherency() const +{ + 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<int>::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 +{ + checkCoherency(); +} + +void MEDCouplingCurveLinearMesh::checkCoherency2(double eps) const +{ + checkCoherency1(eps); +} + +int MEDCouplingCurveLinearMesh::getNumberOfCells() const +{ + checkCoherency(); + return MEDCouplingStructuredMesh::getNumberOfCells(); +} + +int MEDCouplingCurveLinearMesh::getNumberOfNodes() const +{ + checkCoherency(); + return MEDCouplingStructuredMesh::getNumberOfNodes(); +} + +void MEDCouplingCurveLinearMesh::getNodeGridStructure(int *res) const +{ + std::copy(_structure.begin(),_structure.end(),res); +} + +/*! + * MEDCouplingCurveLinearMesh has the property to define 2 space dimensions. One coming from its coordinates. The other coming from the node structure. + * Normally they should be equal ! This method returns the space dimension from coordinates. If the other one is requested call getSpaceDimensionOnNodeStruct. + * + * \sa MEDCouplingStructuredMesh::getSpaceDimensionOnNodeStruct + */ +int MEDCouplingCurveLinearMesh::getSpaceDimension() const +{ + if(!((const DataArrayDouble *)_coords)) + throw INTERP_KERNEL::Exception("MEDCouplingCurveLinearMesh::getSpaceDimension : no array set ! impossible to deduce a space dimension !"); + return _coords->getNumberOfComponents(); +} + +void MEDCouplingCurveLinearMesh::getCoordinatesOfNode(int nodeId, std::vector<double>& coo) const +{ + 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<int>(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() +{ + return _coords; +} + +const DataArrayDouble *MEDCouplingCurveLinearMesh::getCoords() const +{ + return _coords; +} + +void MEDCouplingCurveLinearMesh::setCoords(const DataArrayDouble *coords) +{ + if(coords!=(const DataArrayDouble *)_coords) + { + _coords=const_cast<DataArrayDouble *>(coords); + if(coords) + coords->incrRef(); + declareAsNew(); + } +} + +void MEDCouplingCurveLinearMesh::setNodeGridStructure(const int *gridStructBg, const int *gridStructEnd) +{ + 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<int> MEDCouplingCurveLinearMesh::getNodeGridStructure() const +{ + return _structure; +} + +MEDCouplingStructuredMesh *MEDCouplingCurveLinearMesh::buildStructuredSubPart(const std::vector< std::pair<int,int> >& cellPart) const +{ + checkCoherency(); + int dim(getSpaceDimension()); + std::vector<int> dims(getMeshDimension()); + if(dim!=(int)cellPart.size()) + { + std::ostringstream oss; oss << "MEDCouplingCurveLinearMesh::buildStructuredSubPart : the space dimension is " << dim << " and cell part size is " << cellPart.size() << " !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + std::vector< std::pair<int,int> > nodePartFormat(cellPart); + for(std::vector< std::pair<int,int> >::iterator it=nodePartFormat.begin();it!=nodePartFormat.end();it++) + (*it).second++; + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> tmp1(BuildExplicitIdsFrom(getNodeGridStructure(),nodePartFormat)); + MEDCouplingAutoRefCountObjectPtr<MEDCouplingCurveLinearMesh> ret(dynamic_cast<MEDCouplingCurveLinearMesh *>(deepCpy())); + const DataArrayDouble *coo(ret->getCoords()); + if(coo) + { + MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> coo2(coo->selectByTupleIdSafe(tmp1->begin(),tmp1->end())); + ret->setCoords(coo2); + } + for(int i=0;i<dim;i++) + { + dims[i]=cellPart[i].second-cellPart[i].first+1; + if(dims[i]<1) + throw INTERP_KERNEL::Exception("MEDCouplingCurveLinearMesh::buildStructuredSubPart : invalid input cellPart !"); + } + ret->setNodeGridStructure(&dims[0],&dims[0]+dims.size()); + return ret.retn(); +} + +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<MEDCouplingFieldDouble> field=MEDCouplingFieldDouble::New(ON_CELLS,ONE_TIME); + field->setName(name); field->setMesh(const_cast<MEDCouplingCurveLinearMesh *>(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 +{ + int nbnodes=getNumberOfNodes(); + int spaceDim=getSpaceDimension(); + MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> 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<double>()); + if(isAbs) + arr->abs(); + } + else + { + MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> tmp=DataArrayDouble::New(); tmp->alloc(nbnodes-1,spaceDim); + std::transform(_coords->begin()+spaceDim,_coords->end(),_coords->begin(),tmp->getPointer(),std::minus<double>()); + MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> 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 +{ + 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<DataArrayDouble> 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<nbcells;i++,pt++) + { + int cy=i/nX,cx=i-cy*nX; + conn[0]=cy*(nX+1)+cx; conn[1]=(cy+1)*(nX+1)+cx; conn[2]=(cy+1)*(nX+1)+1+cx; conn[3]=cy*(nX+1)+cx+1; + *pt=INTERP_KERNEL::computeVolSurfOfCell2<int,INTERP_KERNEL::ALL_C_MODE>(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 +{ + 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<DataArrayDouble> 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<nbcells;i++,pt++) + { + int cz=i/nY; + int cy=(i-cz*nY)/nX; + int cx=(i-cz*nY)-nX*cy; + conn[0]=cz*nY1+cy*(nX+1)+cx; conn[1]=cz*nY1+(cy+1)*(nX+1)+cx; conn[2]=cz*nY1+(cy+1)*(nX+1)+1+cx; conn[3]=cz*nY1+cy*(nX+1)+cx+1; + conn[4]=(cz+1)*nY1+cy*(nX+1)+cx; conn[5]=(cz+1)*nY1+(cy+1)*(nX+1)+cx; conn[6]=(cz+1)*nY1+(cy+1)*(nX+1)+1+cx; conn[7]=(cz+1)*nY1+cy*(nX+1)+cx+1; + *pt=INTERP_KERNEL::computeVolSurfOfCell2<int,INTERP_KERNEL::ALL_C_MODE>(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;i<nbOfCells;i++) + { vals[3*i]=0.; vals[3*i+1]=0.; vals[3*i+2]=1.; } + ret->setArray(array); + array->decrRef(); + ret->setMesh(this); + return ret; +} + +/// @cond INTERNAL + +namespace ParaMEDMEM +{ + template<const int SPACEDIMM> + 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<DummyClsMCL<1> >::isElementContainsPoint(pos,INTERP_KERNEL::NORM_SEG2,coords,conn,2,eps)) + return nodeId-1; + } + if(nodeId<nbOfNodes-1) + { + conn[0]=nodeId; conn[1]=nodeId+1; + if(INTERP_KERNEL::PointLocatorAlgos<DummyClsMCL<1> >::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<DummyClsMCL<2> >::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<DummyClsMCL<2> >::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<DummyClsMCL<2> >::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<DummyClsMCL<2> >::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<DummyClsMCL<3> >::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<DummyClsMCL<3> >::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<DummyClsMCL<3> >::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<DummyClsMCL<3> >::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<DummyClsMCL<3> >::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<DummyClsMCL<3> >::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<DummyClsMCL<3> >::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<DummyClsMCL<3> >::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; i<nbNodes; i++) + for(int idim=0; idim<dim;idim++) + coords[i*dim+idim]+=vector[idim]; + _coords->declareAsNew(); + 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<nbNodes;i++) + { + std::transform(coords+i*dim,coords+(i+1)*dim,point,coords+i*dim,std::minus<double>()); + std::transform(coords+i*dim,coords+(i+1)*dim,coords+i*dim,std::bind2nd(std::multiplies<double>(),factor)); + std::transform(coords+i*dim,coords+(i+1)*dim,point,coords+i*dim,std::plus<double>()); + } + _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<DataArrayDouble *>((const DataArrayDouble *)_coords); + if(ret) + ret->incrRef(); + return ret; +} + +DataArrayDouble *MEDCouplingCurveLinearMesh::getBarycenterAndOwner() const +{ + checkCoherency(); + MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> 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 +{ + 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<nbOfCells;i++) + { + int cz=i/nY; + int cy=(i-cz*nY)/nX; + int cx=(i-cz*nY)-nX*cy; + conn[0]=cz*nY1+cy*(nX+1)+cx+1; conn[1]=cz*nY1+cy*(nX+1)+cx; conn[2]=cz*nY1+(cy+1)*(nX+1)+cx; conn[3]=cz*nY1+(cy+1)*(nX+1)+1+cx; + conn[4]=(cz+1)*nY1+cy*(nX+1)+cx+1; conn[5]=(cz+1)*nY1+cy*(nX+1)+cx; conn[6]=(cz+1)*nY1+(cy+1)*(nX+1)+cx; conn[7]=(cz+1)*nY1+(cy+1)*(nX+1)+1+cx; + INTERP_KERNEL::computeBarycenter2<int,INTERP_KERNEL::ALL_C_MODE>(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<nbcells;i++) + { + int cy=i/nX,cx=i-cy*nX; + conn[0]=cy*(nX+1)+cx; conn[1]=(cy+1)*(nX+1)+cx; conn[2]=(cy+1)*(nX+1)+1+cx; conn[3]=cy*(nX+1)+cx+1; + INTERP_KERNEL::computeBarycenter2<int,INTERP_KERNEL::ALL_C_MODE>(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<double>()); + std::transform(bary->begin(),bary->end(),bary->getPointer(),std::bind2nd(std::multiplies<double>(),0.5)); +} + +void MEDCouplingCurveLinearMesh::renumberCells(const int *old2NewBg, bool check) +{ + throw INTERP_KERNEL::Exception("Functionnality of renumbering cell not available for CurveLinear Mesh !"); +} + +void MEDCouplingCurveLinearMesh::getTinySerializationInformation(std::vector<double>& tinyInfoD, std::vector<int>& tinyInfo, std::vector<std::string>& 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<std::string> 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<int>::const_iterator itt=_structure.begin();itt!=_structure.end();itt++) + tinyInfo.push_back(*itt); + std::vector<int> 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<int>& tinyInfo, DataArrayInt *a1, DataArrayDouble *a2, std::vector<std::string>& littleStrings) const +{ + a1->alloc(tinyInfo[2],1); + std::vector<int> 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<int>::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<double>& tinyInfoD, const std::vector<int>& tinyInfo, const DataArrayInt *a1, DataArrayDouble *a2, + const std::vector<std::string>& littleStrings) +{ + setName(littleStrings[0]); + setDescription(littleStrings[1]); + setTimeUnit(littleStrings[2]); + setTime(tinyInfoD[0],tinyInfo[0],tinyInfo[1]); + int sz=tinyInfo[2]; + _structure.resize(sz); + for(int i=0;i<sz;i++) + _structure[i]=tinyInfo[3+i]; + if((int)tinyInfo.size()>sz+3) + { + _coords=DataArrayDouble::New(); + std::vector<int> tinyInfo2(tinyInfo.begin()+3+sz,tinyInfo.end()); + _coords->resizeForUnserialization(tinyInfo2); + std::copy(a2->begin(),a2->end(),_coords->getPointer()); + std::vector<std::string> littleStrings2(littleStrings.begin()+3,littleStrings.end()); + _coords->finishUnserialization(tinyInfo2,littleStrings2); + } +} + +void MEDCouplingCurveLinearMesh::writeVTKLL(std::ostream& ofs, const std::string& cellData, const std::string& pointData, DataArrayByte *byteData) const +{ + 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<meshDim?_structure[i]-1:0; extent << "0 " << val << " "; } + ofs << " <" << getVTKDataSetType() << " WholeExtent=\"" << extent.str() << "\">\n"; + ofs << " <Piece Extent=\"" << extent.str() << "\">\n"; + ofs << " <PointData>\n" << pointData << std::endl; + ofs << " </PointData>\n"; + ofs << " <CellData>\n" << cellData << std::endl; + ofs << " </CellData>\n"; + ofs << " <Points>\n"; + if(getSpaceDimension()==3) + _coords->writeVTK(ofs,8,"Points",byteData); + else + { + MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> coo=_coords->changeNbOfComponents(3,0.); + coo->writeVTK(ofs,8,"Points",byteData); + } + ofs << " </Points>\n"; + ofs << " </Piece>\n"; + ofs << " </" << getVTKDataSetType() << ">\n"; +} + +void MEDCouplingCurveLinearMesh::reprQuickOverview(std::ostream& stream) const +{ + 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()); + int nbOfCompoExp(-1); + try + { + nbOfCompoExp=getSpaceDimension(); + } + catch(INTERP_KERNEL::Exception& e) + { + } + if(nbOfCompo!=nbOfCompoExp) + { 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::getVTKFileExtension() const +{ + return std::string("vts"); +} + +std::string MEDCouplingCurveLinearMesh::getVTKDataSetType() const +{ + return std::string("StructuredGrid"); +} diff --git a/src/medtool/src/MEDCoupling/MEDCouplingCurveLinearMesh.hxx b/src/medtool/src/MEDCoupling/MEDCouplingCurveLinearMesh.hxx new file mode 100644 index 000000000..341075947 --- /dev/null +++ b/src/medtool/src/MEDCoupling/MEDCouplingCurveLinearMesh.hxx @@ -0,0 +1,106 @@ +// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 +// 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 MEDCouplingCurveLinearMesh : public MEDCouplingStructuredMesh + { + public: + MEDCOUPLING_EXPORT static MEDCouplingCurveLinearMesh *New(); + MEDCOUPLING_EXPORT static MEDCouplingCurveLinearMesh *New(const std::string& meshName); + MEDCOUPLING_EXPORT MEDCouplingMesh *deepCpy() const; + MEDCOUPLING_EXPORT MEDCouplingCurveLinearMesh *clone(bool recDeepCpy) const; + MEDCOUPLING_EXPORT void updateTime() const; + MEDCOUPLING_EXPORT std::size_t getHeapMemorySizeWithoutChildren() const; + MEDCOUPLING_EXPORT std::vector<const BigMemoryObject *> getDirectChildrenWithNull() const; + MEDCOUPLING_EXPORT MEDCouplingMeshType getType() const { return CURVE_LINEAR; } + MEDCOUPLING_EXPORT void copyTinyStringsFrom(const MEDCouplingMesh *other); + MEDCOUPLING_EXPORT bool isEqualIfNotWhy(const MEDCouplingMesh *other, double prec, std::string& reason) const; + MEDCOUPLING_EXPORT bool isEqualWithoutConsideringStr(const MEDCouplingMesh *other, double prec) const; + MEDCOUPLING_EXPORT void checkDeepEquivalWith(const MEDCouplingMesh *other, int cellCompPol, double prec, + DataArrayInt *&cellCor, DataArrayInt *&nodeCor) const; + MEDCOUPLING_EXPORT void checkDeepEquivalOnSameNodesWith(const MEDCouplingMesh *other, int cellCompPol, double prec, + DataArrayInt *&cellCor) const; + MEDCOUPLING_EXPORT void checkCoherency() const; + MEDCOUPLING_EXPORT void checkCoherency1(double eps=1e-12) const; + MEDCOUPLING_EXPORT void checkCoherency2(double eps=1e-12) const; + MEDCOUPLING_EXPORT int getNumberOfCells() const; + MEDCOUPLING_EXPORT int getNumberOfNodes() const; + MEDCOUPLING_EXPORT int getSpaceDimension() const; + MEDCOUPLING_EXPORT void getCoordinatesOfNode(int nodeId, std::vector<double>& coo) const; + MEDCOUPLING_EXPORT std::string simpleRepr() const; + MEDCOUPLING_EXPORT std::string advancedRepr() const; + MEDCOUPLING_EXPORT DataArrayDouble *getCoords(); + MEDCOUPLING_EXPORT const DataArrayDouble *getCoords() const; + MEDCOUPLING_EXPORT void setCoords(const DataArrayDouble *coords); + MEDCOUPLING_EXPORT void setNodeGridStructure(const int *gridStructBg, const int *gridStructEnd); + MEDCOUPLING_EXPORT std::vector<int> getNodeGridStructure() const; + MEDCOUPLING_EXPORT MEDCouplingStructuredMesh *buildStructuredSubPart(const std::vector< std::pair<int,int> >& cellPart) const; + // tools + MEDCOUPLING_EXPORT void getBoundingBox(double *bbox) const; + MEDCOUPLING_EXPORT MEDCouplingFieldDouble *getMeasureField(bool isAbs) const; + MEDCOUPLING_EXPORT MEDCouplingFieldDouble *getMeasureFieldOnNode(bool isAbs) const; + MEDCOUPLING_EXPORT MEDCouplingFieldDouble *buildOrthogonalField() const; + MEDCOUPLING_EXPORT int getCellContainingPoint(const double *pos, double eps) const; + MEDCOUPLING_EXPORT void rotate(const double *center, const double *vector, double angle); + MEDCOUPLING_EXPORT void translate(const double *vector); + MEDCOUPLING_EXPORT void scale(const double *point, double factor); + MEDCOUPLING_EXPORT MEDCouplingMesh *mergeMyselfWith(const MEDCouplingMesh *other) const; + MEDCOUPLING_EXPORT DataArrayDouble *getCoordinatesAndOwner() const; + MEDCOUPLING_EXPORT DataArrayDouble *getBarycenterAndOwner() const; + MEDCOUPLING_EXPORT DataArrayDouble *computeIsoBarycenterOfNodesPerCell() const; + MEDCOUPLING_EXPORT void renumberCells(const int *old2NewBg, bool check=true); + //some useful methods + MEDCOUPLING_EXPORT void getNodeGridStructure(int *res) const; + //serialisation-unserialization + MEDCOUPLING_EXPORT void getTinySerializationInformation(std::vector<double>& tinyInfoD, std::vector<int>& tinyInfo, std::vector<std::string>& littleStrings) const; + MEDCOUPLING_EXPORT void resizeForUnserialization(const std::vector<int>& tinyInfo, DataArrayInt *a1, DataArrayDouble *a2, std::vector<std::string>& littleStrings) const; + MEDCOUPLING_EXPORT void serialize(DataArrayInt *&a1, DataArrayDouble *&a2) const; + MEDCOUPLING_EXPORT void unserialization(const std::vector<double>& tinyInfoD, const std::vector<int>& tinyInfo, const DataArrayInt *a1, DataArrayDouble *a2, + const std::vector<std::string>& littleStrings); + MEDCOUPLING_EXPORT void reprQuickOverview(std::ostream& stream) const; + MEDCOUPLING_EXPORT std::string getVTKFileExtension() const; + private: + void getMeasureFieldMeshDim1(bool isAbs, MEDCouplingFieldDouble *field) const; + void getMeasureFieldMeshDim2(bool isAbs, MEDCouplingFieldDouble *field) const; + void getMeasureFieldMeshDim3(bool isAbs, MEDCouplingFieldDouble *field) const; + 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, DataArrayByte *byteData) const; + std::string getVTKDataSetType() const; + private: + MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> _coords; + std::vector<int> _structure; + }; +} + +#endif diff --git a/src/medtool/src/MEDCoupling/MEDCouplingDefinitionTime.cxx b/src/medtool/src/MEDCoupling/MEDCouplingDefinitionTime.cxx new file mode 100644 index 000000000..bbc7021d0 --- /dev/null +++ b/src/medtool/src/MEDCoupling/MEDCouplingDefinitionTime.cxx @@ -0,0 +1,622 @@ +// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 +// 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 "MEDCouplingDefinitionTime.hxx" +#include "MEDCouplingFieldDouble.hxx" + +#include <cmath> + +using namespace ParaMEDMEM; + +const double MEDCouplingDefinitionTime::EPS_DFT=1e-15; + +MEDCouplingDefinitionTimeSlice *MEDCouplingDefinitionTimeSlice::New(const MEDCouplingFieldDouble *f, int meshId, const std::vector<int>& arrId, int fieldId) +{ + static const char msg[]="TimeSlice::New : mismatch of arrays number of a fieldDouble and its policy !!! Internal error !!!"; + if(!f) + throw INTERP_KERNEL::Exception("MEDCouplingDefinitionTimeSlice::New : empty field !"); + switch(f->getTimeDiscretization()) + { + case ONE_TIME: + { + if(arrId.size()!=1) + throw INTERP_KERNEL::Exception(msg); + return new MEDCouplingDefinitionTimeSliceInst(f,meshId,arrId[0],fieldId); + } + case CONST_ON_TIME_INTERVAL: + { + if(arrId.size()!=1) + throw INTERP_KERNEL::Exception(msg); + return new MEDCouplingDefinitionTimeSliceCstOnTI(f,meshId,arrId[0],fieldId); + } + case LINEAR_TIME: + { + if(arrId.size()!=2) + throw INTERP_KERNEL::Exception(msg); + return new MEDCouplingDefinitionTimeSliceLT(f,meshId,arrId[0],arrId[1],fieldId); + } + case NO_TIME: + throw INTERP_KERNEL::Exception("Invalide time discretization ! NO_TIME ! Impossible to build a definition time slice !"); + default: + throw INTERP_KERNEL::Exception("Invalide time discretization : Not recognized !"); + } +} + +MEDCouplingDefinitionTimeSlice *MEDCouplingDefinitionTimeSlice::New(TypeOfTimeDiscretization type, const std::vector<int>& tiI, const std::vector<double>& tiD) +{ + switch(type) + { + case ONE_TIME: + return MEDCouplingDefinitionTimeSliceInst::New(tiI,tiD); + case CONST_ON_TIME_INTERVAL: + return MEDCouplingDefinitionTimeSliceCstOnTI::New(tiI,tiD); + case LINEAR_TIME: + return MEDCouplingDefinitionTimeSliceLT::New(tiI,tiD); + default: + throw INTERP_KERNEL::Exception("MEDCouplingDefinitionTimeSlice::New : unrecognized time discretization type !"); + } +} + +bool MEDCouplingDefinitionTimeSlice::isEqual(const MEDCouplingDefinitionTimeSlice& other, double eps) const +{ + if(_mesh_id!=other._mesh_id) + return false; + if(_array_id!=other._array_id) + return false; + if(_field_id!=other._field_id) + return false; + return true; +} + +int MEDCouplingDefinitionTimeSlice::getStartId() const +{ + return _array_id; +} + +int MEDCouplingDefinitionTimeSlice::getEndId() const +{ + return _array_id; +} + +void MEDCouplingDefinitionTimeSlice::appendRepr(std::ostream& stream) const +{ + stream << " *** MeshId : " << _mesh_id << " ArrayId : " << _array_id; +} + +MEDCouplingDefinitionTimeSlice::MEDCouplingDefinitionTimeSlice(const MEDCouplingFieldDouble *f, int meshId, int arrId, int fieldId):_mesh_id(meshId),_array_id(arrId),_field_id(fieldId) +{ + int tmp1,tmp2; + double t1=f->getStartTime(tmp1,tmp2); + double t2=f->getEndTime(tmp1,tmp2); + if(t2<t1) + throw INTERP_KERNEL::Exception("MEDCouplingDefinitionTimeSlice : End time strictly before Start time ..."); +} + +std::size_t MEDCouplingDefinitionTimeSlice::getHeapMemorySizeWithoutChildren() const +{ + return 0; +} + +std::vector<const BigMemoryObject *> MEDCouplingDefinitionTimeSlice::getDirectChildrenWithNull() const +{ + return std::vector<const BigMemoryObject *>(); +} + +bool MEDCouplingDefinitionTimeSlice::isFullyIncludedInMe(const MEDCouplingDefinitionTimeSlice *other, double eps) const +{ + double t1=getStartTime(); + double t2=getEndTime(); + double o1=other->getStartTime(); + double o2=other->getEndTime(); + return o1>t1-eps && o2<t2+eps; +} + +bool MEDCouplingDefinitionTimeSlice::isOverllapingWithMe(const MEDCouplingDefinitionTimeSlice *other, double eps) const +{ + double t1=getStartTime(); + double t2=getEndTime(); + double o1=other->getStartTime(); + double o2=other->getEndTime(); + return (o1<t1+eps && o2<t1+eps) || (o1>t2-eps && o2>t2-eps); +} + +bool MEDCouplingDefinitionTimeSlice::isAfterMe(const MEDCouplingDefinitionTimeSlice *other, double eps) const +{ + double t2=getEndTime(); + double o1=other->getStartTime(); + double o2=other->getEndTime(); + return (o1>t2-eps && o2>t2-eps); +} + +bool MEDCouplingDefinitionTimeSlice::isBeforeMe(const MEDCouplingDefinitionTimeSlice *other, double eps) const +{ + double t1=getStartTime(); + double o1=other->getStartTime(); + double o2=other->getEndTime(); + return (o1<t1+eps && o2<t1+eps); +} + +MEDCouplingDefinitionTimeSliceInst *MEDCouplingDefinitionTimeSliceInst::New(const std::vector<int>& tiI, const std::vector<double>& tiD) +{ + MEDCouplingDefinitionTimeSliceInst *ret=new MEDCouplingDefinitionTimeSliceInst; + ret->unserialize(tiI,tiD); + return ret; +} + +void MEDCouplingDefinitionTimeSliceInst::getTinySerializationInformation(std::vector<int>& tiI, std::vector<double>& tiD) const +{ + tiI.resize(3); + tiI[0]=_mesh_id; tiI[1]=_array_id; tiI[2]=_field_id; + tiD.resize(1); + tiD[0]=_instant; +} + +void MEDCouplingDefinitionTimeSliceInst::unserialize(const std::vector<int>& tiI, const std::vector<double>& tiD) +{ + _mesh_id=tiI[0]; _array_id=tiI[1]; _field_id=tiI[2]; + _instant=tiD[0]; +} + +TypeOfTimeDiscretization MEDCouplingDefinitionTimeSliceInst::getTimeType() const +{ + return ONE_TIME; +} + +MEDCouplingDefinitionTimeSlice *MEDCouplingDefinitionTimeSliceInst::copy() const +{ + return new MEDCouplingDefinitionTimeSliceInst(*this); +} + +bool MEDCouplingDefinitionTimeSliceInst::isEqual(const MEDCouplingDefinitionTimeSlice& other, double eps) const +{ + if(!MEDCouplingDefinitionTimeSlice::isEqual(other,eps)) + return false; + const MEDCouplingDefinitionTimeSliceInst *otherC=dynamic_cast<const MEDCouplingDefinitionTimeSliceInst *>(&other); + if(!otherC) + return false; + return fabs(otherC->_instant-_instant)<eps; +} + +void MEDCouplingDefinitionTimeSliceInst::getHotSpotsTime(std::vector<double>& ret) const +{ + ret.resize(1); + ret[0]=_instant; +} + +void MEDCouplingDefinitionTimeSliceInst::getIdsOnTime(double tm, double eps, int& meshId, int& arrId, int& arrIdInField, int& fieldId) const +{ + meshId=_mesh_id; + arrId=_array_id; + arrIdInField=0; + fieldId=_field_id; +} + +bool MEDCouplingDefinitionTimeSliceInst::isContaining(double tmp, double eps) const +{ + return fabs(tmp-_instant)<eps; +} + +void MEDCouplingDefinitionTimeSliceInst::appendRepr(std::ostream& stream) const +{ + stream << "single point " << _instant; + MEDCouplingDefinitionTimeSlice::appendRepr(stream); +} + +double MEDCouplingDefinitionTimeSliceInst::getStartTime() const +{ + return _instant; +} + +double MEDCouplingDefinitionTimeSliceInst::getEndTime() const +{ + return _instant; +} + +MEDCouplingDefinitionTimeSliceInst::MEDCouplingDefinitionTimeSliceInst(const MEDCouplingFieldDouble *f, int meshId, int arrId, int fieldId):MEDCouplingDefinitionTimeSlice(f,meshId,arrId,fieldId) +{ + int tmp1,tmp2; + double t1=f->getStartTime(tmp1,tmp2); + double t2=f->getEndTime(tmp1,tmp2); + double eps=f->getTimeTolerance(); + if(fabs(t1-t2)>eps) + throw INTERP_KERNEL::Exception("MEDCouplingDefinitionTimeSliceInst : times differs in this"); + _instant=t1; +} + +MEDCouplingDefinitionTimeSliceCstOnTI *MEDCouplingDefinitionTimeSliceCstOnTI::New(const std::vector<int>& tiI, const std::vector<double>& tiD) +{ + MEDCouplingDefinitionTimeSliceCstOnTI *ret=new MEDCouplingDefinitionTimeSliceCstOnTI; + ret->unserialize(tiI,tiD); + return ret; +} + +MEDCouplingDefinitionTimeSlice *MEDCouplingDefinitionTimeSliceCstOnTI::copy() const +{ + return new MEDCouplingDefinitionTimeSliceCstOnTI(*this); +} + +bool MEDCouplingDefinitionTimeSliceCstOnTI::isEqual(const MEDCouplingDefinitionTimeSlice& other, double eps) const +{ + if(!MEDCouplingDefinitionTimeSlice::isEqual(other,eps)) + return false; + const MEDCouplingDefinitionTimeSliceCstOnTI *otherC=dynamic_cast<const MEDCouplingDefinitionTimeSliceCstOnTI *>(&other); + if(!otherC) + return false; + if(fabs(otherC->_start-_start)>eps) + return false; + return fabs(otherC->_end-_end)<eps; +} + +void MEDCouplingDefinitionTimeSliceCstOnTI::getHotSpotsTime(std::vector<double>& ret) const +{ + ret.resize(1); + ret[0]=(_start+_end)/2.; +} + +void MEDCouplingDefinitionTimeSliceCstOnTI::getIdsOnTime(double tm, double eps, int& meshId, int& arrId, int& arrIdInField, int& fieldId) const +{ + meshId=_mesh_id; + arrId=_array_id; + arrIdInField=0; + fieldId=_field_id; +} + +bool MEDCouplingDefinitionTimeSliceCstOnTI::isContaining(double tmp, double eps) const +{ + return _start-eps<tmp && _end+eps>tmp; +} + +void MEDCouplingDefinitionTimeSliceCstOnTI::appendRepr(std::ostream& stream) const +{ + stream << "Constant on time interval [" << _start << "," << _end << "]"; + MEDCouplingDefinitionTimeSlice::appendRepr(stream); +} + +double MEDCouplingDefinitionTimeSliceCstOnTI::getStartTime() const +{ + return _start; +} + +double MEDCouplingDefinitionTimeSliceCstOnTI::getEndTime() const +{ + return _end; +} + +void MEDCouplingDefinitionTimeSliceCstOnTI::getTinySerializationInformation(std::vector<int>& tiI, std::vector<double>& tiD) const +{ + tiI.resize(3); + tiI[0]=_mesh_id; tiI[1]=_array_id; tiI[2]=_field_id; + tiD.resize(2); + tiD[0]=_start; tiD[1]=_end; +} + +void MEDCouplingDefinitionTimeSliceCstOnTI::unserialize(const std::vector<int>& tiI, const std::vector<double>& tiD) +{ + _mesh_id=tiI[0]; _array_id=tiI[1]; _field_id=tiI[2]; + _start=tiD[0]; _end=tiD[1]; +} + +TypeOfTimeDiscretization MEDCouplingDefinitionTimeSliceCstOnTI::getTimeType() const +{ + return CONST_ON_TIME_INTERVAL; +} + +MEDCouplingDefinitionTimeSliceCstOnTI::MEDCouplingDefinitionTimeSliceCstOnTI(const MEDCouplingFieldDouble *f, int meshId, int arrId, int fieldId):MEDCouplingDefinitionTimeSlice(f,meshId,arrId,fieldId) +{ + int tmp1,tmp2; + double t1=f->getStartTime(tmp1,tmp2); + double t2=f->getEndTime(tmp1,tmp2); + _start=t1; + _end=t2; +} + +MEDCouplingDefinitionTimeSliceLT *MEDCouplingDefinitionTimeSliceLT::New(const std::vector<int>& tiI, const std::vector<double>& tiD) +{ + MEDCouplingDefinitionTimeSliceLT *ret=new MEDCouplingDefinitionTimeSliceLT; + ret->unserialize(tiI,tiD); + return ret; +} + +MEDCouplingDefinitionTimeSlice *MEDCouplingDefinitionTimeSliceLT::copy() const +{ + return new MEDCouplingDefinitionTimeSliceLT(*this); +} + +bool MEDCouplingDefinitionTimeSliceLT::isEqual(const MEDCouplingDefinitionTimeSlice& other, double eps) const +{ + if(!MEDCouplingDefinitionTimeSlice::isEqual(other,eps)) + return false; + const MEDCouplingDefinitionTimeSliceLT *otherC=dynamic_cast<const MEDCouplingDefinitionTimeSliceLT *>(&other); + if(!otherC) + return false; + if(_array_id_end!=otherC->_array_id_end) + return false; + if(fabs(otherC->_start-_start)>eps) + return false; + return fabs(otherC->_end-_end)<eps; +} + +void MEDCouplingDefinitionTimeSliceLT::getHotSpotsTime(std::vector<double>& ret) const +{ + ret.resize(2); + ret[0]=_start; + ret[1]=_end; +} + +void MEDCouplingDefinitionTimeSliceLT::getIdsOnTime(double tm, double eps, int& meshId, int& arrId, int& arrIdInField, int& fieldId) const +{ + if(fabs(tm-_start)<eps) + { + meshId=_mesh_id; + arrId=_array_id; + arrIdInField=0; + fieldId=_field_id; + return ; + } + if(fabs(tm-_end)<eps) + { + meshId=_mesh_id; + arrId=_array_id_end; + arrIdInField=1; + fieldId=_field_id; + return ; + } + throw INTERP_KERNEL::Exception("LinearTime request not in boundary of this ! use hot spots !"); +} + +bool MEDCouplingDefinitionTimeSliceLT::isContaining(double tmp, double eps) const +{ + return _start-eps<tmp && _end+eps>tmp; +} + +void MEDCouplingDefinitionTimeSliceLT::appendRepr(std::ostream& stream) const +{ + stream << "Linear on time interval [" << _start << "," << _end << "]"; + MEDCouplingDefinitionTimeSlice::appendRepr(stream); + stream << " EndArrayId : " << _array_id_end; +} + +double MEDCouplingDefinitionTimeSliceLT::getStartTime() const +{ + return _start; +} + +double MEDCouplingDefinitionTimeSliceLT::getEndTime() const +{ + return _end; +} + +int MEDCouplingDefinitionTimeSliceLT::getEndId() const +{ + return _array_id_end; +} + +void MEDCouplingDefinitionTimeSliceLT::getTinySerializationInformation(std::vector<int>& tiI, std::vector<double>& tiD) const +{ + tiI.resize(4); + tiI[0]=_mesh_id; tiI[1]=_array_id; tiI[2]=_field_id; tiI[3]=_array_id_end; + tiD.resize(2); + tiD[0]=_start; tiD[1]=_end; +} + +void MEDCouplingDefinitionTimeSliceLT::unserialize(const std::vector<int>& tiI, const std::vector<double>& tiD) +{ + _mesh_id=tiI[0]; _array_id=tiI[1]; _field_id=tiI[2]; _array_id_end=tiI[3]; + _start=tiD[0]; _end=tiD[1]; +} + +TypeOfTimeDiscretization MEDCouplingDefinitionTimeSliceLT::getTimeType() const +{ + return LINEAR_TIME; +} + +MEDCouplingDefinitionTimeSliceLT::MEDCouplingDefinitionTimeSliceLT(const MEDCouplingFieldDouble *f, int meshId, int arrId, int arr2Id, int fieldId):MEDCouplingDefinitionTimeSlice(f,meshId,arrId,fieldId),_array_id_end(arr2Id) +{ + int tmp1,tmp2; + double t1=f->getStartTime(tmp1,tmp2); + double t2=f->getEndTime(tmp1,tmp2); + _start=t1; + _end=t2; +} + +MEDCouplingDefinitionTime::MEDCouplingDefinitionTime():_eps(EPS_DFT) +{ +} + +MEDCouplingDefinitionTime::MEDCouplingDefinitionTime(const std::vector<const MEDCouplingFieldDouble *>& fs, const std::vector<int>& meshRefs, const std::vector<std::vector<int> >& arrRefs) +{ + std::size_t sz=fs.size(); + if(sz!=arrRefs.size()) + throw INTERP_KERNEL::Exception("MEDCouplingDefinitionTime constructor : internal error ! should never happen !"); + _slices.resize(sz); + for(std::size_t i=0;i<sz;i++) + { + if(arrRefs.empty()) + throw INTERP_KERNEL::Exception("MEDCouplingDefinitionTime constructor : A field is null in list impossible to build a time definition !"); + _slices[i]=MEDCouplingDefinitionTimeSlice::New(fs[i],meshRefs[i],arrRefs[i],(int)i); + } + if(sz<=1) + return ; + const MEDCouplingDefinitionTimeSlice *ref=_slices[0]; + _eps=fs[0]->getTimeTolerance(); + for(std::size_t i=1;i<sz;i++) + { + if(!ref->isAfterMe(_slices[i],_eps)) + throw INTERP_KERNEL::Exception("MEDCouplingDefinitionTime constructors : the sequences of fields does NOT defines a stricly ascendant monotonic time sequence !"); + // double t1=ref->getEndTime(); + // double t2=_slices[i]->getStartTime(); + // if(fabs(t1-t2)<_eps) + // if(ref->getEndId() != _slices[i]->getStartId()) + // throw INTERP_KERNEL::Exception("MEDCouplingDefinitionTime constructor : 2 slices refers to the same time and underlying arrays differs !"); + ref=_slices[i]; + } +} + +std::size_t MEDCouplingDefinitionTime::getHeapMemorySizeWithoutChildren() const +{ + return _slices.capacity()*(sizeof(MEDCouplingDefinitionTimeSlice)+sizeof(int)); +} + +std::vector<const BigMemoryObject *> MEDCouplingDefinitionTime::getDirectChildrenWithNull() const +{ + return std::vector<const BigMemoryObject *>(); +} + +void MEDCouplingDefinitionTime::assign(const MEDCouplingDefinitionTime& other) +{ + std::size_t sz=other._slices.size(); + _slices.resize(sz); + for(std::size_t i=0;i<sz;i++) + _slices[i]=other._slices[i]->copy(); +} + +bool MEDCouplingDefinitionTime::isEqual(const MEDCouplingDefinitionTime& other) const +{ + std::size_t sz=_slices.size(); + if(sz!=other._slices.size()) + return false; + for(std::size_t i=0;i<sz;i++) + if(!_slices[i]->isEqual(*other._slices[i],_eps)) + return false; + return true; +} + +void MEDCouplingDefinitionTime::getIdsOnTimeRight(double tm, int& meshId, int& arrId, int& arrIdInField, int& fieldId) const +{ + std::vector<int> meshIds; + std::vector<int> arrIds; + std::vector<int> arrIdsInField; + std::vector<int> fieldIds; + getIdsOnTime(tm,meshIds,arrIds,arrIdsInField,fieldIds); + meshId=meshIds.back(); + arrId=arrIds.back(); + arrIdInField=arrIdsInField.back(); + fieldId=fieldIds.back(); +} + +void MEDCouplingDefinitionTime::getIdsOnTimeLeft(double tm, int& meshId, int& arrId, int& arrIdInField, int& fieldId) const +{ + std::vector<int> meshIds; + std::vector<int> arrIds; + std::vector<int> arrIdsInField; + std::vector<int> fieldIds; + getIdsOnTime(tm,meshIds,arrIds,arrIdsInField,fieldIds); + meshId=meshIds.front(); + arrId=arrIds.front(); + arrIdInField=arrIdsInField.front(); + fieldId=fieldIds.front(); +} + +void MEDCouplingDefinitionTime::getIdsOnTime(double tm, std::vector<int>& meshIds, std::vector<int>& arrIds, std::vector<int>& arrIdsInField, std::vector<int>& fieldIds) const +{ + std::vector<int> ids; + int id=0; + for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCouplingDefinitionTimeSlice> >::const_iterator it=_slices.begin();it!=_slices.end();it++,id++) + if((*it)->isContaining(tm,_eps)) + ids.push_back(id); + if(ids.empty()) + throw INTERP_KERNEL::Exception("MEDCouplingDefinitionTime::getIdsOnTime : No matching slice for such time !"); + std::size_t sz=ids.size(); + if(sz>2) + throw INTERP_KERNEL::Exception("MEDCouplingDefinitionTime::getIdsOnTime : Too many slices match this time !"); + // + meshIds.resize(sz); + arrIds.resize(sz); + arrIdsInField.resize(sz); + fieldIds.resize(sz); + for(std::size_t i=0;i<sz;i++) + _slices[ids[i]]->getIdsOnTime(tm,_eps,meshIds[i],arrIds[i],arrIdsInField[i],fieldIds[i]); +} + +std::vector<double> MEDCouplingDefinitionTime::getHotSpotsTime() const +{ + std::vector<double> ret; + for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCouplingDefinitionTimeSlice> >::const_iterator it=_slices.begin();it!=_slices.end();it++) + { + std::vector<double> tmp; + (*it)->getHotSpotsTime(tmp); + if(!ret.empty()) + { + if(fabs(ret.back()-tmp.front())>_eps) + ret.insert(ret.end(),tmp.begin(),tmp.end()); + else + ret.insert(ret.end(),tmp.begin()+1,tmp.end()); + } + else + ret.insert(ret.end(),tmp.begin(),tmp.end()); + } + return ret; +} + +void MEDCouplingDefinitionTime::appendRepr(std::ostream& stream) const +{ + stream << "Time definition :\n"; + for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCouplingDefinitionTimeSlice> >::const_iterator it=_slices.begin();it!=_slices.end();it++) + { + stream << " - "; + (*it)->appendRepr(stream); + stream << std::endl; + } +} + +void MEDCouplingDefinitionTime::getTinySerializationInformation(std::vector<int>& tinyInfoI, std::vector<double>& tinyInfoD) const +{ + int sz=(int)_slices.size(); + tinyInfoD.resize(1); + tinyInfoD[0]=_eps; + tinyInfoI.resize(3*sz+2); + tinyInfoI[0]=sz; + std::vector<int> coreData; + for(int i=0;i<sz;i++) + { + std::vector<int> tmp1; + std::vector<double> tmp2; + tinyInfoI[i+2]=(int)_slices[i]->getTimeType(); + _slices[i]->getTinySerializationInformation(tmp1,tmp2); + tinyInfoI[i+sz+2]=(int)tmp1.size(); + tinyInfoI[i+2*sz+2]=(int)tmp2.size(); + coreData.insert(coreData.end(),tmp1.begin(),tmp1.end()); + tinyInfoD.insert(tinyInfoD.end(),tmp2.begin(),tmp2.end()); + } + tinyInfoI[1]=(int)coreData.size(); + tinyInfoI.insert(tinyInfoI.end(),coreData.begin(),coreData.end()); +} + +void MEDCouplingDefinitionTime::unserialize(const std::vector<int>& tinyInfoI, const std::vector<double>& tinyInfoD) +{ + int sz=tinyInfoI[0]; + _slices.resize(sz); + _eps=tinyInfoD[0]; + int offset1=0; + int offset2=1; + for(int i=0;i<sz;i++) + { + TypeOfTimeDiscretization ty=(TypeOfTimeDiscretization) tinyInfoI[i+2]; + int sz1=tinyInfoI[i+sz+2]; + int sz2=tinyInfoI[i+2*sz+2]; + std::vector<int> tmp1(tinyInfoI.begin()+3*sz+2+offset1,tinyInfoI.begin()+3*sz+2+offset1+sz1); + std::vector<double> tmp2(tinyInfoD.begin()+offset2,tinyInfoD.begin()+offset2+sz2); + MEDCouplingDefinitionTimeSlice *pt=MEDCouplingDefinitionTimeSlice::New(ty,tmp1,tmp2); + _slices[i]=pt; + offset1+=sz1; + offset2+=sz2; + } +} + diff --git a/src/medtool/src/MEDCoupling/MEDCouplingDefinitionTime.hxx b/src/medtool/src/MEDCoupling/MEDCouplingDefinitionTime.hxx new file mode 100644 index 000000000..ab2536b70 --- /dev/null +++ b/src/medtool/src/MEDCoupling/MEDCouplingDefinitionTime.hxx @@ -0,0 +1,167 @@ +// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 +// 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_MEDCOUPLINGDEFINITIONTIME_HXX__ +#define __PARAMEDMEM_MEDCOUPLINGDEFINITIONTIME_HXX__ + +#include "MEDCouplingRefCountObject.hxx" +#include "MEDCouplingAutoRefCountObjectPtr.hxx" + +#include "InterpKernelException.hxx" + +#include <vector> +#include <sstream> + +namespace ParaMEDMEM +{ + class MEDCouplingFieldDouble; + + class MEDCouplingDefinitionTimeSlice : public RefCountObject + { + public: + MEDCOUPLING_EXPORT static MEDCouplingDefinitionTimeSlice *New(const MEDCouplingFieldDouble *f, int meshId, const std::vector<int>& arrId, int fieldId); + MEDCOUPLING_EXPORT static MEDCouplingDefinitionTimeSlice *New(TypeOfTimeDiscretization type, const std::vector<int>& tiI, const std::vector<double>& tiD); + MEDCOUPLING_EXPORT int getArrayId() const { return _array_id; } + MEDCOUPLING_EXPORT virtual MEDCouplingDefinitionTimeSlice *copy() const = 0; + MEDCOUPLING_EXPORT virtual bool isEqual(const MEDCouplingDefinitionTimeSlice& other, double eps) const; + MEDCOUPLING_EXPORT virtual void getHotSpotsTime(std::vector<double>& ret) const = 0; + MEDCOUPLING_EXPORT virtual void getIdsOnTime(double tm, double eps, int& meshId, int& arrId, int& arrIdInField, int& fieldId) const = 0; + MEDCOUPLING_EXPORT virtual bool isContaining(double tmp, double eps) const = 0; + MEDCOUPLING_EXPORT virtual int getStartId() const; + MEDCOUPLING_EXPORT virtual int getEndId() const; + MEDCOUPLING_EXPORT virtual void appendRepr(std::ostream& stream) const; + MEDCOUPLING_EXPORT virtual double getStartTime() const = 0; + MEDCOUPLING_EXPORT virtual double getEndTime() const = 0; + MEDCOUPLING_EXPORT virtual void getTinySerializationInformation(std::vector<int>& tiI, std::vector<double>& tiD) const = 0; + MEDCOUPLING_EXPORT virtual TypeOfTimeDiscretization getTimeType() const = 0; + MEDCOUPLING_EXPORT std::size_t getHeapMemorySizeWithoutChildren() const; + MEDCOUPLING_EXPORT std::vector<const BigMemoryObject *> getDirectChildrenWithNull() const; + MEDCOUPLING_EXPORT bool isFullyIncludedInMe(const MEDCouplingDefinitionTimeSlice *other, double eps) const; + MEDCOUPLING_EXPORT bool isOverllapingWithMe(const MEDCouplingDefinitionTimeSlice *other, double eps) const; + MEDCOUPLING_EXPORT bool isAfterMe(const MEDCouplingDefinitionTimeSlice *other, double eps) const; + MEDCOUPLING_EXPORT bool isBeforeMe(const MEDCouplingDefinitionTimeSlice *other, double eps) const; + protected: + MEDCOUPLING_EXPORT MEDCouplingDefinitionTimeSlice() { } + MEDCOUPLING_EXPORT MEDCouplingDefinitionTimeSlice(const MEDCouplingFieldDouble *f, int meshId, int arrId, int fieldId); + protected: + int _mesh_id; + int _array_id; + int _field_id; + }; + + class MEDCouplingDefinitionTimeSliceInst : public MEDCouplingDefinitionTimeSlice + { + public: + static MEDCouplingDefinitionTimeSliceInst *New(const std::vector<int>& tiI, const std::vector<double>& tiD); + MEDCouplingDefinitionTimeSlice *copy() const; + bool isEqual(const MEDCouplingDefinitionTimeSlice& other, double eps) const; + void getHotSpotsTime(std::vector<double>& ret) const; + void getIdsOnTime(double tm, double eps, int& meshId, int& arrId, int& arrIdInField, int& fieldId) const; + bool isContaining(double tmp, double eps) const; + void appendRepr(std::ostream& stream) const; + double getStartTime() const; + double getEndTime() const; + void getTinySerializationInformation(std::vector<int>& tiI, std::vector<double>& tiD) const; + void unserialize(const std::vector<int>& tiI, const std::vector<double>& tiD); + TypeOfTimeDiscretization getTimeType() const; + public: + MEDCouplingDefinitionTimeSliceInst(const MEDCouplingFieldDouble *f, int meshId, int arrId, int fieldId); + protected: + MEDCouplingDefinitionTimeSliceInst() { } + protected: + double _instant; + }; + + class MEDCouplingDefinitionTimeSliceCstOnTI : public MEDCouplingDefinitionTimeSlice + { + public: + static MEDCouplingDefinitionTimeSliceCstOnTI *New(const std::vector<int>& tiI, const std::vector<double>& tiD); + MEDCouplingDefinitionTimeSlice *copy() const; + bool isEqual(const MEDCouplingDefinitionTimeSlice& other, double eps) const; + void getHotSpotsTime(std::vector<double>& ret) const; + void getIdsOnTime(double tm, double eps, int& meshId, int& arrId, int& arrIdInField, int& fieldId) const; + bool isContaining(double tmp, double eps) const; + void appendRepr(std::ostream& stream) const; + double getStartTime() const; + double getEndTime() const; + void getTinySerializationInformation(std::vector<int>& tiI, std::vector<double>& tiD) const; + void unserialize(const std::vector<int>& tiI, const std::vector<double>& tiD); + TypeOfTimeDiscretization getTimeType() const; + public: + MEDCouplingDefinitionTimeSliceCstOnTI(const MEDCouplingFieldDouble *f, int meshId, int arrId, int fieldId); + protected: + MEDCouplingDefinitionTimeSliceCstOnTI() { } + protected: + double _start; + double _end; + }; + + class MEDCouplingDefinitionTimeSliceLT : public MEDCouplingDefinitionTimeSlice + { + public: + static MEDCouplingDefinitionTimeSliceLT *New(const std::vector<int>& tiI, const std::vector<double>& tiD); + MEDCouplingDefinitionTimeSlice *copy() const; + bool isEqual(const MEDCouplingDefinitionTimeSlice& other, double eps) const; + void getHotSpotsTime(std::vector<double>& ret) const; + void getIdsOnTime(double tm, double eps, int& meshId, int& arrId, int& arrIdInField, int& fieldId) const; + bool isContaining(double tmp, double eps) const; + void appendRepr(std::ostream& stream) const; + double getStartTime() const; + double getEndTime() const; + int getEndId() const; + void getTinySerializationInformation(std::vector<int>& tiI, std::vector<double>& tiD) const; + void unserialize(const std::vector<int>& tiI, const std::vector<double>& tiD); + TypeOfTimeDiscretization getTimeType() const; + public: + MEDCouplingDefinitionTimeSliceLT(const MEDCouplingFieldDouble *f, int meshId, int arrId, int arr2Id, int fieldId); + protected: + MEDCouplingDefinitionTimeSliceLT() { } + protected: + int _array_id_end; + double _start; + double _end; + }; + + class MEDCouplingDefinitionTime + { + public: + MEDCOUPLING_EXPORT MEDCouplingDefinitionTime(); + MEDCOUPLING_EXPORT MEDCouplingDefinitionTime(const std::vector<const MEDCouplingFieldDouble *>& fs, const std::vector<int>& meshRefs, const std::vector<std::vector<int> >& arrRefs); + MEDCOUPLING_EXPORT std::size_t getHeapMemorySizeWithoutChildren() const; + MEDCOUPLING_EXPORT std::vector<const BigMemoryObject *> getDirectChildrenWithNull() const; + MEDCOUPLING_EXPORT void assign(const MEDCouplingDefinitionTime& other); + MEDCOUPLING_EXPORT bool isEqual(const MEDCouplingDefinitionTime& other) const; + MEDCOUPLING_EXPORT double getTimeResolution() const { return _eps; } + MEDCOUPLING_EXPORT void getIdsOnTimeRight(double tm, int& meshId, int& arrId, int& arrIdInField, int& fieldId) const; + MEDCOUPLING_EXPORT void getIdsOnTimeLeft(double tm, int& meshId, int& arrId, int& arrIdInField, int& fieldId) const; + MEDCOUPLING_EXPORT void getIdsOnTime(double tm, std::vector<int>& meshIds, std::vector<int>& arrIds, std::vector<int>& arrIdsInField, std::vector<int>& fieldIds) const; + MEDCOUPLING_EXPORT std::vector<double> getHotSpotsTime() const; + MEDCOUPLING_EXPORT void appendRepr(std::ostream& stream) const; + public: + MEDCOUPLING_EXPORT void getTinySerializationInformation(std::vector<int>& tinyInfoI, std::vector<double>& tinyInfoD) const; + MEDCOUPLING_EXPORT void unserialize(const std::vector<int>& tinyInfoI, const std::vector<double>& tinyInfoD); + private: + double _eps; + std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCouplingDefinitionTimeSlice> > _slices; + static const double EPS_DFT; + }; +} + +#endif diff --git a/src/medtool/src/MEDCoupling/MEDCouplingExtrudedMesh.cxx b/src/medtool/src/MEDCoupling/MEDCouplingExtrudedMesh.cxx new file mode 100644 index 000000000..3df24b33b --- /dev/null +++ b/src/medtool/src/MEDCoupling/MEDCouplingExtrudedMesh.cxx @@ -0,0 +1,961 @@ +// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 +// 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 "MEDCouplingExtrudedMesh.hxx" +#include "MEDCouplingUMesh.hxx" +#include "MEDCouplingMemArray.hxx" +#include "MEDCouplingFieldDouble.hxx" +#include "MEDCouplingAutoRefCountObjectPtr.hxx" +#include "CellModel.hxx" + +#include "InterpolationUtils.hxx" + +#include <limits> +#include <algorithm> +#include <functional> +#include <iterator> +#include <sstream> +#include <cmath> +#include <list> +#include <set> + +using namespace ParaMEDMEM; + +/*! + * Build an extruded mesh instance from 3D and 2D unstructured mesh lying on the \b same \b coords. + * @param mesh3D 3D unstructured mesh. + * @param mesh2D 2D unstructured mesh lying on the same coordinates than mesh3D. \b Warning mesh2D is \b not \b const + * because the mesh is aggregated and potentially modified by rotate or translate method. + * @param cell2DId Id of cell in mesh2D mesh where the computation of 1D mesh will be done. + */ +MEDCouplingExtrudedMesh *MEDCouplingExtrudedMesh::New(const MEDCouplingUMesh *mesh3D, const MEDCouplingUMesh *mesh2D, int cell2DId) +{ + return new MEDCouplingExtrudedMesh(mesh3D,mesh2D,cell2DId); +} + +/*! + * This constructor is here only for unserialisation process. + * This constructor is normally completely useless for end user. + */ +MEDCouplingExtrudedMesh *MEDCouplingExtrudedMesh::New() +{ + return new MEDCouplingExtrudedMesh; +} + +MEDCouplingMeshType MEDCouplingExtrudedMesh::getType() const +{ + return EXTRUDED; +} + +std::size_t MEDCouplingExtrudedMesh::getHeapMemorySizeWithoutChildren() const +{ + return MEDCouplingMesh::getHeapMemorySizeWithoutChildren(); +} + +std::vector<const BigMemoryObject *> MEDCouplingExtrudedMesh::getDirectChildrenWithNull() const +{ + std::vector<const BigMemoryObject *> ret; + ret.push_back(_mesh2D); + ret.push_back(_mesh1D); + ret.push_back(_mesh3D_ids); + return ret; +} + +/*! + * This method copyies all tiny strings from other (name and components name). + * @throw if other and this have not same mesh type. + */ +void MEDCouplingExtrudedMesh::copyTinyStringsFrom(const MEDCouplingMesh *other) +{ + const MEDCouplingExtrudedMesh *otherC=dynamic_cast<const MEDCouplingExtrudedMesh *>(other); + if(!otherC) + throw INTERP_KERNEL::Exception("MEDCouplingExtrudedMesh::copyTinyStringsFrom : meshes have not same type !"); + MEDCouplingMesh::copyTinyStringsFrom(other); + _mesh2D->copyTinyStringsFrom(otherC->_mesh2D); + _mesh1D->copyTinyStringsFrom(otherC->_mesh1D); +} + +MEDCouplingExtrudedMesh::MEDCouplingExtrudedMesh(const MEDCouplingUMesh *mesh3D, const MEDCouplingUMesh *mesh2D, int cell2DId) +try:_mesh2D(const_cast<MEDCouplingUMesh *>(mesh2D)),_mesh1D(MEDCouplingUMesh::New()),_mesh3D_ids(0),_cell_2D_id(cell2DId) +{ + if(_mesh2D!=0) + _mesh2D->incrRef(); + computeExtrusion(mesh3D); + setName(mesh3D->getName()); +} +catch(INTERP_KERNEL::Exception& e) +{ + if(_mesh2D) + _mesh2D->decrRef(); + if(_mesh1D) + _mesh1D->decrRef(); + if(_mesh3D_ids) + _mesh3D_ids->decrRef(); + throw e; +} + +MEDCouplingExtrudedMesh::MEDCouplingExtrudedMesh():_mesh2D(0),_mesh1D(0),_mesh3D_ids(0),_cell_2D_id(-1) +{ +} + +MEDCouplingExtrudedMesh::MEDCouplingExtrudedMesh(const MEDCouplingExtrudedMesh& other, bool deepCopy):MEDCouplingMesh(other),_cell_2D_id(other._cell_2D_id) +{ + if(deepCopy) + { + _mesh2D=other._mesh2D->clone(true); + _mesh1D=other._mesh1D->clone(true); + _mesh3D_ids=other._mesh3D_ids->deepCpy(); + } + else + { + _mesh2D=other._mesh2D; + if(_mesh2D) + _mesh2D->incrRef(); + _mesh1D=other._mesh1D; + if(_mesh1D) + _mesh1D->incrRef(); + _mesh3D_ids=other._mesh3D_ids; + if(_mesh3D_ids) + _mesh3D_ids->incrRef(); + } +} + +int MEDCouplingExtrudedMesh::getNumberOfCells() const +{ + return _mesh2D->getNumberOfCells()*_mesh1D->getNumberOfCells(); +} + +int MEDCouplingExtrudedMesh::getNumberOfNodes() const +{ + return _mesh2D->getNumberOfNodes(); +} + +int MEDCouplingExtrudedMesh::getSpaceDimension() const +{ + return 3; +} + +int MEDCouplingExtrudedMesh::getMeshDimension() const +{ + return 3; +} + +MEDCouplingMesh *MEDCouplingExtrudedMesh::deepCpy() const +{ + return clone(true); +} + +MEDCouplingExtrudedMesh *MEDCouplingExtrudedMesh::clone(bool recDeepCpy) const +{ + return new MEDCouplingExtrudedMesh(*this,recDeepCpy); +} + +bool MEDCouplingExtrudedMesh::isEqualIfNotWhy(const MEDCouplingMesh *other, double prec, std::string& reason) const +{ + if(!other) + throw INTERP_KERNEL::Exception("MEDCouplingExtrudedMesh::isEqualIfNotWhy : input other pointer is null !"); + const MEDCouplingExtrudedMesh *otherC=dynamic_cast<const MEDCouplingExtrudedMesh *>(other); + std::ostringstream oss; + if(!otherC) + { + reason="mesh given in input is not castable in MEDCouplingExtrudedMesh !"; + return false; + } + if(!MEDCouplingMesh::isEqualIfNotWhy(other,prec,reason)) + return false; + if(!_mesh2D->isEqualIfNotWhy(otherC->_mesh2D,prec,reason)) + { + reason.insert(0,"Mesh2D unstructured meshes differ : "); + return false; + } + if(!_mesh1D->isEqualIfNotWhy(otherC->_mesh1D,prec,reason)) + { + reason.insert(0,"Mesh1D unstructured meshes differ : "); + return false; + } + if(!_mesh3D_ids->isEqualIfNotWhy(*otherC->_mesh3D_ids,reason)) + { + reason.insert(0,"Mesh3D ids DataArrayInt instances differ : "); + return false; + } + if(_cell_2D_id!=otherC->_cell_2D_id) + { + oss << "Cell 2D id of the two extruded mesh differ : this = " << _cell_2D_id << " other = " << otherC->_cell_2D_id; + reason=oss.str(); + return false; + } + return true; +} + +bool MEDCouplingExtrudedMesh::isEqualWithoutConsideringStr(const MEDCouplingMesh *other, double prec) const +{ + const MEDCouplingExtrudedMesh *otherC=dynamic_cast<const MEDCouplingExtrudedMesh *>(other); + if(!otherC) + return false; + if(!_mesh2D->isEqualWithoutConsideringStr(otherC->_mesh2D,prec)) + return false; + if(!_mesh1D->isEqualWithoutConsideringStr(otherC->_mesh1D,prec)) + return false; + if(!_mesh3D_ids->isEqualWithoutConsideringStr(*otherC->_mesh3D_ids)) + return false; + if(_cell_2D_id!=otherC->_cell_2D_id) + return false; + return true; +} + +void MEDCouplingExtrudedMesh::checkDeepEquivalWith(const MEDCouplingMesh *other, int cellCompPol, double prec, + DataArrayInt *&cellCor, DataArrayInt *&nodeCor) const +{ + throw INTERP_KERNEL::Exception("MEDCouplingExtrudedMesh::checkDeepEquivalWith : not implemented yet !"); +} + +void MEDCouplingExtrudedMesh::checkDeepEquivalOnSameNodesWith(const MEDCouplingMesh *other, int cellCompPol, double prec, + DataArrayInt *&cellCor) const +{ + throw INTERP_KERNEL::Exception("MEDCouplingExtrudedMesh::checkDeepEquivalOnSameNodesWith : not implemented yet !"); +} + +INTERP_KERNEL::NormalizedCellType MEDCouplingExtrudedMesh::getTypeOfCell(int cellId) const +{ + const int *ids=_mesh3D_ids->getConstPointer(); + int nbOf3DCells=_mesh3D_ids->getNumberOfTuples(); + const int *where=std::find(ids,ids+nbOf3DCells,cellId); + if(where==ids+nbOf3DCells) + throw INTERP_KERNEL::Exception("Invalid cellId specified >= getNumberOfCells() !"); + int nbOfCells2D=_mesh2D->getNumberOfCells(); + int locId=((int)std::distance(ids,where))%nbOfCells2D; + INTERP_KERNEL::NormalizedCellType tmp=_mesh2D->getTypeOfCell(locId); + return INTERP_KERNEL::CellModel::GetCellModel(tmp).getExtrudedType(); +} + +std::set<INTERP_KERNEL::NormalizedCellType> MEDCouplingExtrudedMesh::getAllGeoTypes() const +{ + std::set<INTERP_KERNEL::NormalizedCellType> ret2D(_mesh2D->getAllGeoTypes()); + std::set<INTERP_KERNEL::NormalizedCellType> ret; + for(std::set<INTERP_KERNEL::NormalizedCellType>::const_iterator it=ret2D.begin();it!=ret2D.end();it++) + ret.insert(INTERP_KERNEL::CellModel::GetCellModel(*it).getExtrudedType()); + return ret; +} + +DataArrayInt *MEDCouplingExtrudedMesh::giveCellsWithType(INTERP_KERNEL::NormalizedCellType type) const +{ + const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(type); + INTERP_KERNEL::NormalizedCellType revExtTyp=cm.getReverseExtrudedType(); + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New(); + if(revExtTyp==INTERP_KERNEL::NORM_ERROR) + { + ret->alloc(0,1); + return ret.retn(); + } + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> 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;i<nbOfLevs;i++,pt+=nbOfTuples) + std::transform(tmp->begin(),tmp->end(),pt,std::bind2nd(std::plus<int>(),i*nbOfCells2D)); + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret2=ret->renumberR(_mesh3D_ids->begin()); + ret2->sort(); + return ret2.retn(); +} + +DataArrayInt *MEDCouplingExtrudedMesh::computeNbOfNodesPerCell() const +{ + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret2D=_mesh2D->computeNbOfNodesPerCell(); + int nbOfLevs=_mesh1D->getNumberOfCells(); + int nbOfCells2D=_mesh2D->getNumberOfCells(); + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret3D=DataArrayInt::New(); ret3D->alloc(nbOfLevs*nbOfCells2D,1); + int *pt=ret3D->getPointer(); + for(int i=0;i<nbOfLevs;i++,pt+=nbOfCells2D) + std::copy(ret2D->begin(),ret2D->end(),pt); + ret3D->applyLin(2,0,0); + return ret3D->renumberR(_mesh3D_ids->begin()); +} + +DataArrayInt *MEDCouplingExtrudedMesh::computeNbOfFacesPerCell() const +{ + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret2D=_mesh2D->computeNbOfNodesPerCell(); + int nbOfLevs=_mesh1D->getNumberOfCells(); + int nbOfCells2D=_mesh2D->getNumberOfCells(); + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret3D=DataArrayInt::New(); ret3D->alloc(nbOfLevs*nbOfCells2D,1); + int *pt=ret3D->getPointer(); + for(int i=0;i<nbOfLevs;i++,pt+=nbOfCells2D) + std::copy(ret2D->begin(),ret2D->end(),pt); + ret3D->applyLin(2,2,0); + return ret3D->renumberR(_mesh3D_ids->begin()); +} + +DataArrayInt *MEDCouplingExtrudedMesh::computeEffectiveNbOfNodesPerCell() const +{ + return computeNbOfNodesPerCell(); +} + +int MEDCouplingExtrudedMesh::getNumberOfCellsWithType(INTERP_KERNEL::NormalizedCellType type) const +{ + int ret=0; + int nbOfCells2D=_mesh2D->getNumberOfCells(); + for(int i=0;i<nbOfCells2D;i++) + { + INTERP_KERNEL::NormalizedCellType t=_mesh2D->getTypeOfCell(i); + if(INTERP_KERNEL::CellModel::GetCellModel(t).getExtrudedType()==type) + ret++; + } + return ret*_mesh1D->getNumberOfCells(); +} + +void MEDCouplingExtrudedMesh::getNodeIdsOfCell(int cellId, std::vector<int>& conn) const +{ + int nbOfCells2D=_mesh2D->getNumberOfCells(); + int nbOfNodes2D=_mesh2D->getNumberOfNodes(); + int locId=cellId%nbOfCells2D; + int lev=cellId/nbOfCells2D; + std::vector<int> tmp,tmp2; + _mesh2D->getNodeIdsOfCell(locId,tmp); + tmp2=tmp; + std::transform(tmp.begin(),tmp.end(),tmp.begin(),std::bind2nd(std::plus<int>(),nbOfNodes2D*lev)); + std::transform(tmp2.begin(),tmp2.end(),tmp2.begin(),std::bind2nd(std::plus<int>(),nbOfNodes2D*(lev+1))); + conn.insert(conn.end(),tmp.begin(),tmp.end()); + conn.insert(conn.end(),tmp2.begin(),tmp2.end()); +} + +void MEDCouplingExtrudedMesh::getCoordinatesOfNode(int nodeId, std::vector<double>& coo) const +{ + int nbOfNodes2D=_mesh2D->getNumberOfNodes(); + int locId=nodeId%nbOfNodes2D; + int lev=nodeId/nbOfNodes2D; + std::vector<double> tmp,tmp2; + _mesh2D->getCoordinatesOfNode(locId,tmp); + tmp2=tmp; + int spaceDim=_mesh1D->getSpaceDimension(); + const double *z=_mesh1D->getCoords()->getConstPointer(); + std::transform(tmp.begin(),tmp.end(),z+lev*spaceDim,tmp.begin(),std::plus<double>()); + std::transform(tmp2.begin(),tmp2.end(),z+(lev+1)*spaceDim,tmp2.begin(),std::plus<double>()); + coo.insert(coo.end(),tmp.begin(),tmp.end()); + coo.insert(coo.end(),tmp2.begin(),tmp2.end()); +} + +std::string MEDCouplingExtrudedMesh::simpleRepr() const +{ + std::ostringstream ret; + ret << "3D Extruded mesh from a 2D Surf 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 << "Cell id where 1D mesh has been deduced : " << _cell_2D_id << "\n"; + ret << "Number of cells : " << getNumberOfCells() << "(" << _mesh2D->getNumberOfCells() << "x" << _mesh1D->getNumberOfCells() << ")\n"; + ret << "1D Mesh info : _____________________\n\n\n"; + ret << _mesh1D->simpleRepr(); + ret << "\n\n\n2D Mesh info : _____________________\n\n\n" << _mesh2D->simpleRepr() << "\n\n\n"; + return ret.str(); +} + +std::string MEDCouplingExtrudedMesh::advancedRepr() const +{ + std::ostringstream ret; + ret << "3D Extruded mesh from a 2D Surf 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 << "Cell id where 1D mesh has been deduced : " << _cell_2D_id << "\n"; + ret << "Number of cells : " << getNumberOfCells() << "(" << _mesh2D->getNumberOfCells() << "x" << _mesh1D->getNumberOfCells() << ")\n"; + ret << "1D Mesh info : _____________________\n\n\n"; + ret << _mesh1D->advancedRepr(); + ret << "\n\n\n2D Mesh info : _____________________\n\n\n" << _mesh2D->advancedRepr() << "\n\n\n"; + ret << "3D cell ids per level :\n"; + return ret.str(); +} + +void MEDCouplingExtrudedMesh::checkCoherency() const +{ +} + +void MEDCouplingExtrudedMesh::checkCoherency1(double eps) const +{ + checkCoherency(); +} + +void MEDCouplingExtrudedMesh::checkCoherency2(double eps) const +{ + checkCoherency1(eps); +} + +void MEDCouplingExtrudedMesh::getBoundingBox(double *bbox) const +{ + double bbox2D[6]; + _mesh2D->getBoundingBox(bbox2D); + const double *nodes1D=_mesh1D->getCoords()->getConstPointer(); + int nbOfNodes1D=_mesh1D->getNumberOfNodes(); + double bbox1DMin[3],bbox1DMax[3],tmp[3]; + std::fill(bbox1DMin,bbox1DMin+3,std::numeric_limits<double>::max()); + std::fill(bbox1DMax,bbox1DMax+3,-(std::numeric_limits<double>::max())); + for(int i=0;i<nbOfNodes1D;i++) + { + std::transform(nodes1D+3*i,nodes1D+3*(i+1),bbox1DMin,bbox1DMin,static_cast<const double& (*)(const double&, const double&)>(std::min<double>)); + std::transform(nodes1D+3*i,nodes1D+3*(i+1),bbox1DMax,bbox1DMax,static_cast<const double& (*)(const double&, const double&)>(std::max<double>)); + } + std::transform(bbox1DMax,bbox1DMax+3,bbox1DMin,tmp,std::minus<double>()); + int id=(int)std::distance(tmp,std::max_element(tmp,tmp+3)); + bbox[0]=bbox1DMin[0]; bbox[1]=bbox1DMax[0]; + bbox[2]=bbox1DMin[1]; bbox[3]=bbox1DMax[1]; + bbox[4]=bbox1DMin[2]; bbox[5]=bbox1DMax[2]; + bbox[2*id+1]+=tmp[id]; +} + +void MEDCouplingExtrudedMesh::updateTime() const +{ + if(_mesh2D) + { + updateTimeWith(*_mesh2D); + } + if(_mesh1D) + { + updateTimeWith(*_mesh1D); + } +} + +void MEDCouplingExtrudedMesh::renumberCells(const int *old2NewBg, bool check) +{ + throw INTERP_KERNEL::Exception("Functionnality of renumbering cells unavailable for ExtrudedMesh"); +} + +MEDCouplingUMesh *MEDCouplingExtrudedMesh::build3DUnstructuredMesh() const +{ + MEDCouplingUMesh *ret=_mesh2D->buildExtrudedMesh(_mesh1D,0); + const int *renum=_mesh3D_ids->getConstPointer(); + ret->renumberCells(renum,false); + ret->setName(getName()); + return ret; +} + +MEDCouplingUMesh *MEDCouplingExtrudedMesh::buildUnstructured() const +{ + return build3DUnstructuredMesh(); +} + +MEDCouplingFieldDouble *MEDCouplingExtrudedMesh::getMeasureField(bool) const +{ + std::string name="MeasureOfMesh_"; + name+=getName(); + MEDCouplingFieldDouble *ret2D=_mesh2D->getMeasureField(true); + MEDCouplingFieldDouble *ret1D=_mesh1D->getMeasureField(true); + const double *ret2DPtr=ret2D->getArray()->getConstPointer(); + const double *ret1DPtr=ret1D->getArray()->getConstPointer(); + int nbOf2DCells=_mesh2D->getNumberOfCells(); + int nbOf1DCells=_mesh1D->getNumberOfCells(); + int nbOf3DCells=nbOf2DCells*nbOf1DCells; + const int *renum=_mesh3D_ids->getConstPointer(); + 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(); + for(int i=0;i<nbOf1DCells;i++) + for(int j=0;j<nbOf2DCells;j++) + retPtr[renum[i*nbOf2DCells+j]]=ret2DPtr[j]*ret1DPtr[i]; + ret->setArray(da); + da->decrRef(); + ret->setName(name); + ret2D->decrRef(); + ret1D->decrRef(); + return ret; +} + +MEDCouplingFieldDouble *MEDCouplingExtrudedMesh::getMeasureFieldOnNode(bool isAbs) const +{ + //not implemented yet + return 0; +} + +MEDCouplingFieldDouble *MEDCouplingExtrudedMesh::buildOrthogonalField() const +{ + throw INTERP_KERNEL::Exception("MEDCouplingExtrudedMesh::buildOrthogonalField : This method has no sense for MEDCouplingExtrudedMesh that is 3D !"); +} + +int MEDCouplingExtrudedMesh::getCellContainingPoint(const double *pos, double eps) const +{ + throw INTERP_KERNEL::Exception("MEDCouplingExtrudedMesh::getCellContainingPoint : not implemented yet !"); +} + +MEDCouplingExtrudedMesh::~MEDCouplingExtrudedMesh() +{ + if(_mesh2D) + _mesh2D->decrRef(); + if(_mesh1D) + _mesh1D->decrRef(); + if(_mesh3D_ids) + _mesh3D_ids->decrRef(); +} + +void MEDCouplingExtrudedMesh::computeExtrusion(const MEDCouplingUMesh *mesh3D) +{ + const char errMsg1[]="2D mesh is empty unable to compute extrusion !"; + const char errMsg2[]="Coords between 2D and 3D meshes are not the same ! Try MEDCouplingPointSet::tryToShareSameCoords method"; + const char errMsg3[]="No chance to find extrusion pattern in mesh3D,mesh2D couple because nbCells3D%nbCells2D!=0 !"; + if(_mesh2D==0 || mesh3D==0) + throw INTERP_KERNEL::Exception(errMsg1); + if(_mesh2D->getCoords()!=mesh3D->getCoords()) + throw INTERP_KERNEL::Exception(errMsg2); + if(mesh3D->getNumberOfCells()%_mesh2D->getNumberOfCells()!=0) + throw INTERP_KERNEL::Exception(errMsg3); + if(!_mesh3D_ids) + _mesh3D_ids=DataArrayInt::New(); + if(!_mesh1D) + _mesh1D=MEDCouplingUMesh::New(); + computeExtrusionAlg(mesh3D); +} + +void MEDCouplingExtrudedMesh::build1DExtrusion(int idIn3DDesc, int newId, int nbOf1DLev, MEDCouplingUMesh *subMesh, + const int *desc3D, const int *descIndx3D, + const int *revDesc3D, const int *revDescIndx3D, + bool computeMesh1D) +{ + int nbOf2DCells=_mesh2D->getNumberOfCells(); + int start=revDescIndx3D[idIn3DDesc]; + int end=revDescIndx3D[idIn3DDesc+1]; + if(end-start!=1) + { + std::ostringstream ost; ost << "Invalid bases 2D mesh specified : 2D cell # " << idIn3DDesc; + ost << " shared by more than 1 3D cell !!!"; + throw INTERP_KERNEL::Exception(ost.str().c_str()); + } + int current3DCell=revDesc3D[start]; + int current2DCell=idIn3DDesc; + int *mesh3DIDs=_mesh3D_ids->getPointer(); + mesh3DIDs[newId]=current3DCell; + const int *conn2D=subMesh->getNodalConnectivity()->getConstPointer(); + const int *conn2DIndx=subMesh->getNodalConnectivityIndex()->getConstPointer(); + for(int i=1;i<nbOf1DLev;i++) + { + std::vector<int> conn(conn2D+conn2DIndx[current2DCell]+1,conn2D+conn2DIndx[current2DCell+1]); + std::sort(conn.begin(),conn.end()); + if(computeMesh1D) + computeBaryCenterOfFace(conn,i-1); + current2DCell=findOppositeFaceOf(current2DCell,current3DCell,conn, + desc3D,descIndx3D,conn2D,conn2DIndx); + start=revDescIndx3D[current2DCell]; + end=revDescIndx3D[current2DCell+1]; + if(end-start!=2) + { + std::ostringstream ost; ost << "Expecting to have 2 3D cells attached to 2D cell " << current2DCell << "!"; + ost << " : Impossible or call tryToShareSameCoords method !"; + throw INTERP_KERNEL::Exception(ost.str().c_str()); + } + if(revDesc3D[start]!=current3DCell) + current3DCell=revDesc3D[start]; + else + current3DCell=revDesc3D[start+1]; + mesh3DIDs[i*nbOf2DCells+newId]=current3DCell; + } + if(computeMesh1D) + { + std::vector<int> conn(conn2D+conn2DIndx[current2DCell]+1,conn2D+conn2DIndx[current2DCell+1]); + std::sort(conn.begin(),conn.end()); + computeBaryCenterOfFace(conn,nbOf1DLev-1); + current2DCell=findOppositeFaceOf(current2DCell,current3DCell,conn, + desc3D,descIndx3D,conn2D,conn2DIndx); + conn.clear(); + conn.insert(conn.end(),conn2D+conn2DIndx[current2DCell]+1,conn2D+conn2DIndx[current2DCell+1]); + std::sort(conn.begin(),conn.end()); + computeBaryCenterOfFace(conn,nbOf1DLev); + } +} + +int MEDCouplingExtrudedMesh::findOppositeFaceOf(int current2DCell, int current3DCell, const std::vector<int>& connSorted, + const int *desc3D, const int *descIndx3D, + const int *conn2D, const int *conn2DIndx) +{ + int start=descIndx3D[current3DCell]; + int end=descIndx3D[current3DCell+1]; + bool found=false; + for(const int *candidate2D=desc3D+start;candidate2D!=desc3D+end && !found;candidate2D++) + { + if(*candidate2D!=current2DCell) + { + std::vector<int> conn2(conn2D+conn2DIndx[*candidate2D]+1,conn2D+conn2DIndx[*candidate2D+1]); + std::sort(conn2.begin(),conn2.end()); + std::list<int> intersect; + std::set_intersection(connSorted.begin(),connSorted.end(),conn2.begin(),conn2.end(), + std::insert_iterator< std::list<int> >(intersect,intersect.begin())); + if(intersect.empty()) + return *candidate2D; + } + } + std::ostringstream ost; ost << "Impossible to find an opposite 2D face of face # " << current2DCell; + ost << " in 3D cell # " << current3DCell << " : Impossible or call tryToShareSameCoords method !"; + throw INTERP_KERNEL::Exception(ost.str().c_str()); +} + +void MEDCouplingExtrudedMesh::computeBaryCenterOfFace(const std::vector<int>& nodalConnec, int lev1DId) +{ + double *zoneToUpdate=_mesh1D->getCoords()->getPointer()+lev1DId*3; + std::fill(zoneToUpdate,zoneToUpdate+3,0.); + const double *coords=_mesh2D->getCoords()->getConstPointer(); + for(std::vector<int>::const_iterator iter=nodalConnec.begin();iter!=nodalConnec.end();iter++) + std::transform(zoneToUpdate,zoneToUpdate+3,coords+3*(*iter),zoneToUpdate,std::plus<double>()); + std::transform(zoneToUpdate,zoneToUpdate+3,zoneToUpdate,std::bind2nd(std::multiplies<double>(),(double)(1./(int)nodalConnec.size()))); +} + +int MEDCouplingExtrudedMesh::FindCorrespCellByNodalConn(const std::vector<int>& nodalConnec, const int *revNodalPtr, const int *revNodalIndxPtr) +{ + std::vector<int>::const_iterator iter=nodalConnec.begin(); + std::set<int> s1(revNodalPtr+revNodalIndxPtr[*iter],revNodalPtr+revNodalIndxPtr[*iter+1]); + iter++; + for(;iter!=nodalConnec.end();iter++) + { + std::set<int> s2(revNodalPtr+revNodalIndxPtr[*iter],revNodalPtr+revNodalIndxPtr[*iter+1]); + std::set<int> s3; + std::set_intersection(s1.begin(),s1.end(),s2.begin(),s2.end(),std::insert_iterator< std::set<int> >(s3,s3.end())); + s1=s3; + } + if(s1.size()==1) + return *(s1.begin()); + std::ostringstream ostr; + ostr << "Cell with nodal connec : "; + std::copy(nodalConnec.begin(),nodalConnec.end(),std::ostream_iterator<int>(ostr," ")); + ostr << " is not part of mesh"; + throw INTERP_KERNEL::Exception(ostr.str().c_str()); +} + +/*! + * This method is callable on 1Dmeshes (meshDim==1 && spaceDim==3) returned by MEDCouplingExtrudedMesh::getMesh1D typically. + * These 1Dmeshes (meshDim==1 && spaceDim==3) have a special semantic because these meshes do not specify a static location but a translation along a path. + * This method checks that 'm1' and 'm2' are compatible, if not an exception is thrown. In case these meshes ('m1' and 'm2') are compatible 2 corresponding meshes + * are created ('m1r' and 'm2r') that can be used for interpolation. + * @param m1 input mesh with meshDim==1 and spaceDim==3 + * @param m2 input mesh with meshDim==1 and spaceDim==3 + * @param eps tolerance acceptable to determine compatibility + * @param m1r output mesh with ref count equal to 1 with meshDim==1 and spaceDim==1 + * @param m2r output mesh with ref count equal to 1 with meshDim==1 and spaceDim==1 + * @param v is the output normalized vector of the common direction of 'm1' and 'm2' + * @throw in case that m1 and m2 are not compatible each other. + */ +void MEDCouplingExtrudedMesh::Project1DMeshes(const MEDCouplingUMesh *m1, const MEDCouplingUMesh *m2, double eps, + MEDCouplingUMesh *&m1r, MEDCouplingUMesh *&m2r, double *v) +{ + if(m1->getSpaceDimension()!=3 || m1->getSpaceDimension()!=3) + throw INTERP_KERNEL::Exception("Input meshes are expected to have a spaceDim==3 for Projec1D !"); + m1r=m1->clone(true); + m2r=m2->clone(true); + m1r->changeSpaceDimension(1); + m2r->changeSpaceDimension(1); + std::vector<int> c; + std::vector<double> ref,ref2; + m1->getNodeIdsOfCell(0,c); + m1->getCoordinatesOfNode(c[0],ref); + m1->getCoordinatesOfNode(c[1],ref2); + std::transform(ref2.begin(),ref2.end(),ref.begin(),v,std::minus<double>()); + double n=INTERP_KERNEL::norm<3>(v); + std::transform(v,v+3,v,std::bind2nd(std::multiplies<double>(),1/n)); + m1->project1D(&ref[0],v,eps,m1r->getCoords()->getPointer()); + m2->project1D(&ref[0],v,eps,m2r->getCoords()->getPointer()); +} + +void MEDCouplingExtrudedMesh::rotate(const double *center, const double *vector, double angle) +{ + _mesh2D->rotate(center,vector,angle); + _mesh1D->rotate(center,vector,angle); +} + +void MEDCouplingExtrudedMesh::translate(const double *vector) +{ + _mesh2D->translate(vector); + _mesh1D->translate(vector); +} + +void MEDCouplingExtrudedMesh::scale(const double *point, double factor) +{ + _mesh2D->scale(point,factor); + _mesh1D->scale(point,factor); +} + +std::vector<int> MEDCouplingExtrudedMesh::getDistributionOfTypes() const +{ + throw INTERP_KERNEL::Exception("Not implemented yet !"); +} + +DataArrayInt *MEDCouplingExtrudedMesh::checkTypeConsistencyAndContig(const std::vector<int>& code, const std::vector<const DataArrayInt *>& idsPerType) const +{ + throw INTERP_KERNEL::Exception("Not implemented yet !"); +} + +void MEDCouplingExtrudedMesh::splitProfilePerType(const DataArrayInt *profile, std::vector<int>& code, std::vector<DataArrayInt *>& idsInPflPerType, std::vector<DataArrayInt *>& idsPerType) const +{ + throw INTERP_KERNEL::Exception("Not implemented yet !"); +} + +MEDCouplingMesh *MEDCouplingExtrudedMesh::buildPart(const int *start, const int *end) const +{ + // not implemented yet ! + return 0; +} + +MEDCouplingMesh *MEDCouplingExtrudedMesh::buildPartAndReduceNodes(const int *start, const int *end, DataArrayInt*& arr) const +{ + // not implemented yet ! + return 0; +} + +DataArrayInt *MEDCouplingExtrudedMesh::simplexize(int policy) +{ + throw INTERP_KERNEL::Exception("MEDCouplingExtrudedMesh::simplexize : unavailable for such a type of mesh : Extruded !"); +} + +MEDCouplingMesh *MEDCouplingExtrudedMesh::mergeMyselfWith(const MEDCouplingMesh *other) const +{ + // not implemented yet ! + return 0; +} + +DataArrayDouble *MEDCouplingExtrudedMesh::getCoordinatesAndOwner() const +{ + DataArrayDouble *arr2D=_mesh2D->getCoords(); + DataArrayDouble *arr1D=_mesh1D->getCoords(); + DataArrayDouble *ret=DataArrayDouble::New(); + ret->alloc(getNumberOfNodes(),3); + int nbOf1DLev=_mesh1D->getNumberOfNodes(); + int nbOf2DNodes=_mesh2D->getNumberOfNodes(); + const double *ptSrc=arr2D->getConstPointer(); + double *pt=ret->getPointer(); + std::copy(ptSrc,ptSrc+3*nbOf2DNodes,pt); + for(int i=1;i<nbOf1DLev;i++) + { + std::copy(ptSrc,ptSrc+3*nbOf2DNodes,pt+3*i*nbOf2DNodes); + double vec[3]; + std::copy(arr1D->getConstPointer()+3*i,arr1D->getConstPointer()+3*(i+1),vec); + std::transform(arr1D->getConstPointer()+3*(i-1),arr1D->getConstPointer()+3*i,vec,vec,std::minus<double>()); + for(int j=0;j<nbOf2DNodes;j++) + std::transform(vec,vec+3,pt+3*(i*nbOf2DNodes+j),pt+3*(i*nbOf2DNodes+j),std::plus<double>()); + } + return ret; +} + +DataArrayDouble *MEDCouplingExtrudedMesh::getBarycenterAndOwner() const +{ + throw INTERP_KERNEL::Exception("MEDCouplingExtrudedMesh::getBarycenterAndOwner : not yet implemented !"); +} + +DataArrayDouble *MEDCouplingExtrudedMesh::computeIsoBarycenterOfNodesPerCell() const +{ + throw INTERP_KERNEL::Exception("MEDCouplingExtrudedMesh::computeIsoBarycenterOfNodesPerCell: not yet implemented !"); +} + +void MEDCouplingExtrudedMesh::getReverseNodalConnectivity(DataArrayInt *revNodal, DataArrayInt *revNodalIndx) const +{ + MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m(buildUnstructured()); + m->getReverseNodalConnectivity(revNodal,revNodalIndx); +} + +void MEDCouplingExtrudedMesh::computeExtrusionAlg(const MEDCouplingUMesh *mesh3D) +{ + _mesh3D_ids->alloc(mesh3D->getNumberOfCells(),1); + int nbOf1DLev=mesh3D->getNumberOfCells()/_mesh2D->getNumberOfCells(); + _mesh1D->setMeshDimension(1); + _mesh1D->allocateCells(nbOf1DLev); + int tmpConn[2]; + for(int i=0;i<nbOf1DLev;i++) + { + tmpConn[0]=i; + tmpConn[1]=i+1; + _mesh1D->insertNextCell(INTERP_KERNEL::NORM_SEG2,2,tmpConn); + } + _mesh1D->finishInsertingCells(); + DataArrayDouble *myCoords=DataArrayDouble::New(); + myCoords->alloc(nbOf1DLev+1,3); + _mesh1D->setCoords(myCoords); + myCoords->decrRef(); + DataArrayInt *desc,*descIndx,*revDesc,*revDescIndx; + desc=DataArrayInt::New(); descIndx=DataArrayInt::New(); revDesc=DataArrayInt::New(); revDescIndx=DataArrayInt::New(); + MEDCouplingUMesh *subMesh=mesh3D->buildDescendingConnectivity(desc,descIndx,revDesc,revDescIndx); + DataArrayInt *revNodal2D,*revNodalIndx2D; + revNodal2D=DataArrayInt::New(); revNodalIndx2D=DataArrayInt::New(); + subMesh->getReverseNodalConnectivity(revNodal2D,revNodalIndx2D); + const int *nodal2D=_mesh2D->getNodalConnectivity()->getConstPointer(); + const int *nodal2DIndx=_mesh2D->getNodalConnectivityIndex()->getConstPointer(); + const int *revNodal2DPtr=revNodal2D->getConstPointer(); + const int *revNodalIndx2DPtr=revNodalIndx2D->getConstPointer(); + const int *descP=desc->getConstPointer(); + const int *descIndxP=descIndx->getConstPointer(); + const int *revDescP=revDesc->getConstPointer(); + const int *revDescIndxP=revDescIndx->getConstPointer(); + // + int nbOf2DCells=_mesh2D->getNumberOfCells(); + for(int i=0;i<nbOf2DCells;i++) + { + int idInSubMesh; + std::vector<int> nodalConnec(nodal2D+nodal2DIndx[i]+1,nodal2D+nodal2DIndx[i+1]); + try + { + idInSubMesh=FindCorrespCellByNodalConn(nodalConnec,revNodal2DPtr,revNodalIndx2DPtr); + } + catch(INTERP_KERNEL::Exception& e) + { + std::ostringstream ostr; ostr << "mesh2D cell # " << i << " is not part of any cell of 3D mesh !\n"; + ostr << e.what(); + throw INTERP_KERNEL::Exception(ostr.str().c_str()); + } + build1DExtrusion(idInSubMesh,i,nbOf1DLev,subMesh,descP,descIndxP,revDescP,revDescIndxP,i==_cell_2D_id); + } + // + revNodal2D->decrRef(); + revNodalIndx2D->decrRef(); + subMesh->decrRef(); + desc->decrRef(); + descIndx->decrRef(); + revDesc->decrRef(); + revDescIndx->decrRef(); +} + +void MEDCouplingExtrudedMesh::getTinySerializationInformation(std::vector<double>& tinyInfoD, std::vector<int>& tinyInfo, std::vector<std::string>& littleStrings) const +{ + std::vector<int> tinyInfo1; + std::vector<std::string> ls1; + std::vector<double> ls3; + _mesh2D->getTinySerializationInformation(ls3,tinyInfo1,ls1); + std::vector<int> tinyInfo2; + std::vector<std::string> ls2; + std::vector<double> ls4; + _mesh1D->getTinySerializationInformation(ls4,tinyInfo2,ls2); + tinyInfo.clear(); littleStrings.clear(); + tinyInfo.insert(tinyInfo.end(),tinyInfo1.begin(),tinyInfo1.end()); + littleStrings.insert(littleStrings.end(),ls1.begin(),ls1.end()); + tinyInfo.insert(tinyInfo.end(),tinyInfo2.begin(),tinyInfo2.end()); + littleStrings.insert(littleStrings.end(),ls2.begin(),ls2.end()); + tinyInfo.push_back(_cell_2D_id); + tinyInfo.push_back((int)tinyInfo1.size()); + tinyInfo.push_back(_mesh3D_ids->getNbOfElems()); + littleStrings.push_back(getName()); + littleStrings.push_back(getDescription()); +} + +void MEDCouplingExtrudedMesh::resizeForUnserialization(const std::vector<int>& tinyInfo, DataArrayInt *a1, DataArrayDouble *a2, std::vector<std::string>& littleStrings) const +{ + std::size_t sz=tinyInfo.size(); + int sz1=tinyInfo[sz-2]; + std::vector<int> ti1(tinyInfo.begin(),tinyInfo.begin()+sz1); + std::vector<int> ti2(tinyInfo.begin()+sz1,tinyInfo.end()-3); + MEDCouplingUMesh *um=MEDCouplingUMesh::New(); + DataArrayInt *a1tmp=DataArrayInt::New(); + DataArrayDouble *a2tmp=DataArrayDouble::New(); + int la1=0,la2=0; + std::vector<std::string> ls1,ls2; + um->resizeForUnserialization(ti1,a1tmp,a2tmp,ls1); + la1+=a1tmp->getNbOfElems(); la2+=a2tmp->getNbOfElems(); + a1tmp->decrRef(); a2tmp->decrRef(); + a1tmp=DataArrayInt::New(); a2tmp=DataArrayDouble::New(); + um->resizeForUnserialization(ti2,a1tmp,a2tmp,ls2); + la1+=a1tmp->getNbOfElems(); la2+=a2tmp->getNbOfElems(); + a1tmp->decrRef(); a2tmp->decrRef(); + um->decrRef(); + // + a1->alloc(la1+tinyInfo[sz-1],1); + a2->alloc(la2,1); + littleStrings.resize(ls1.size()+ls2.size()+2); +} + +void MEDCouplingExtrudedMesh::serialize(DataArrayInt *&a1, DataArrayDouble *&a2) const +{ + a1=DataArrayInt::New(); a2=DataArrayDouble::New(); + DataArrayInt *a1_1=0,*a1_2=0; + DataArrayDouble *a2_1=0,*a2_2=0; + _mesh2D->serialize(a1_1,a2_1); + _mesh1D->serialize(a1_2,a2_2); + a1->alloc(a1_1->getNbOfElems()+a1_2->getNbOfElems()+_mesh3D_ids->getNbOfElems(),1); + int *ptri=a1->getPointer(); + ptri=std::copy(a1_1->getConstPointer(),a1_1->getConstPointer()+a1_1->getNbOfElems(),ptri); + a1_1->decrRef(); + ptri=std::copy(a1_2->getConstPointer(),a1_2->getConstPointer()+a1_2->getNbOfElems(),ptri); + a1_2->decrRef(); + std::copy(_mesh3D_ids->getConstPointer(),_mesh3D_ids->getConstPointer()+_mesh3D_ids->getNbOfElems(),ptri); + a2->alloc(a2_1->getNbOfElems()+a2_2->getNbOfElems(),1); + double *ptrd=a2->getPointer(); + ptrd=std::copy(a2_1->getConstPointer(),a2_1->getConstPointer()+a2_1->getNbOfElems(),ptrd); + a2_1->decrRef(); + std::copy(a2_2->getConstPointer(),a2_2->getConstPointer()+a2_2->getNbOfElems(),ptrd); + a2_2->decrRef(); +} + +void MEDCouplingExtrudedMesh::unserialization(const std::vector<double>& tinyInfoD, const std::vector<int>& tinyInfo, const DataArrayInt *a1, DataArrayDouble *a2, const std::vector<std::string>& littleStrings) +{ + setName(littleStrings[littleStrings.size()-2]); + setDescription(littleStrings.back()); + std::size_t sz=tinyInfo.size(); + int sz1=tinyInfo[sz-2]; + _cell_2D_id=tinyInfo[sz-3]; + std::vector<int> ti1(tinyInfo.begin(),tinyInfo.begin()+sz1); + std::vector<int> ti2(tinyInfo.begin()+sz1,tinyInfo.end()-3); + DataArrayInt *a1tmp=DataArrayInt::New(); + DataArrayDouble *a2tmp=DataArrayDouble::New(); + const int *a1Ptr=a1->getConstPointer(); + const double *a2Ptr=a2->getConstPointer(); + _mesh2D=MEDCouplingUMesh::New(); + std::vector<std::string> ls1,ls2; + _mesh2D->resizeForUnserialization(ti1,a1tmp,a2tmp,ls1); + std::copy(a2Ptr,a2Ptr+a2tmp->getNbOfElems(),a2tmp->getPointer()); + std::copy(a1Ptr,a1Ptr+a1tmp->getNbOfElems(),a1tmp->getPointer()); + a2Ptr+=a2tmp->getNbOfElems(); + a1Ptr+=a1tmp->getNbOfElems(); + ls2.insert(ls2.end(),littleStrings.begin(),littleStrings.begin()+ls1.size()); + std::vector<double> d1(1); + _mesh2D->unserialization(d1,ti1,a1tmp,a2tmp,ls2); + a1tmp->decrRef(); a2tmp->decrRef(); + // + ls2.clear(); + ls2.insert(ls2.end(),littleStrings.begin()+ls1.size(),littleStrings.end()-2); + _mesh1D=MEDCouplingUMesh::New(); + a1tmp=DataArrayInt::New(); a2tmp=DataArrayDouble::New(); + _mesh1D->resizeForUnserialization(ti2,a1tmp,a2tmp,ls1); + std::copy(a2Ptr,a2Ptr+a2tmp->getNbOfElems(),a2tmp->getPointer()); + std::copy(a1Ptr,a1Ptr+a1tmp->getNbOfElems(),a1tmp->getPointer()); + a1Ptr+=a1tmp->getNbOfElems(); + _mesh1D->unserialization(d1,ti2,a1tmp,a2tmp,ls2); + a1tmp->decrRef(); a2tmp->decrRef(); + // + _mesh3D_ids=DataArrayInt::New(); + int szIds=(int)std::distance(a1Ptr,a1->getConstPointer()+a1->getNbOfElems()); + _mesh3D_ids->alloc(szIds,1); + std::copy(a1Ptr,a1Ptr+szIds,_mesh3D_ids->getPointer()); +} + +void MEDCouplingExtrudedMesh::writeVTKLL(std::ostream& ofs, const std::string& cellData, const std::string& pointData, DataArrayByte *byteData) const +{ + MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m=buildUnstructured(); + m->writeVTKLL(ofs,cellData,pointData,byteData); +} + +void MEDCouplingExtrudedMesh::reprQuickOverview(std::ostream& stream) const +{ + stream << "MEDCouplingExtrudedMesh C++ instance at " << this << ". Name : \"" << getName() << "\"."; +} + +std::string MEDCouplingExtrudedMesh::getVTKFileExtension() const +{ + return _mesh2D->getVTKFileExtension(); +} + +std::string MEDCouplingExtrudedMesh::getVTKDataSetType() const +{ + return _mesh2D->getVTKDataSetType(); +} diff --git a/src/medtool/src/MEDCoupling/MEDCouplingExtrudedMesh.hxx b/src/medtool/src/MEDCoupling/MEDCouplingExtrudedMesh.hxx new file mode 100644 index 000000000..c72f42cf4 --- /dev/null +++ b/src/medtool/src/MEDCoupling/MEDCouplingExtrudedMesh.hxx @@ -0,0 +1,135 @@ +// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 +// 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_MEDCOUPLINGEXTRUDEDMESH_HXX__ +#define __PARAMEDMEM_MEDCOUPLINGEXTRUDEDMESH_HXX__ + +#include "MEDCoupling.hxx" +#include "MEDCouplingMesh.hxx" + +#include <vector> + +namespace ParaMEDMEM +{ + class DataArrayInt; + class DataArrayDouble; + class MEDCouplingUMesh; + class MEDCouplingFieldDouble; + + class MEDCouplingExtrudedMesh : public MEDCouplingMesh + { + public: + MEDCOUPLING_EXPORT static MEDCouplingExtrudedMesh *New(const MEDCouplingUMesh *mesh3D, const MEDCouplingUMesh *mesh2D, int cell2DId); + MEDCOUPLING_EXPORT static MEDCouplingExtrudedMesh *New(); + MEDCOUPLING_EXPORT MEDCouplingMeshType getType() const; + MEDCOUPLING_EXPORT std::size_t getHeapMemorySizeWithoutChildren() const; + MEDCOUPLING_EXPORT std::vector<const BigMemoryObject *> getDirectChildrenWithNull() const; + MEDCOUPLING_EXPORT void copyTinyStringsFrom(const MEDCouplingMesh *other); + MEDCOUPLING_EXPORT int getNumberOfCells() const; + MEDCOUPLING_EXPORT int getNumberOfNodes() const; + MEDCOUPLING_EXPORT int getSpaceDimension() const; + MEDCOUPLING_EXPORT int getMeshDimension() const; + MEDCOUPLING_EXPORT MEDCouplingMesh *deepCpy() const; + MEDCouplingExtrudedMesh *clone(bool recDeepCpy) const; + MEDCOUPLING_EXPORT bool isEqualIfNotWhy(const MEDCouplingMesh *other, double prec, std::string& reason) const; + MEDCOUPLING_EXPORT bool isEqualWithoutConsideringStr(const MEDCouplingMesh *other, double prec) const; + MEDCOUPLING_EXPORT void checkDeepEquivalWith(const MEDCouplingMesh *other, int cellCompPol, double prec, + DataArrayInt *&cellCor, DataArrayInt *&nodeCor) const; + MEDCOUPLING_EXPORT void checkDeepEquivalOnSameNodesWith(const MEDCouplingMesh *other, int cellCompPol, double prec, + DataArrayInt *&cellCor) const; + MEDCOUPLING_EXPORT INTERP_KERNEL::NormalizedCellType getTypeOfCell(int cellId) const; + MEDCOUPLING_EXPORT std::set<INTERP_KERNEL::NormalizedCellType> getAllGeoTypes() const; + MEDCOUPLING_EXPORT DataArrayInt *giveCellsWithType(INTERP_KERNEL::NormalizedCellType type) const; + MEDCOUPLING_EXPORT DataArrayInt *computeNbOfNodesPerCell() const; + MEDCOUPLING_EXPORT DataArrayInt *computeNbOfFacesPerCell() const; + MEDCOUPLING_EXPORT DataArrayInt *computeEffectiveNbOfNodesPerCell() const; + MEDCOUPLING_EXPORT int getNumberOfCellsWithType(INTERP_KERNEL::NormalizedCellType type) const; + MEDCOUPLING_EXPORT void getNodeIdsOfCell(int cellId, std::vector<int>& conn) const; + MEDCOUPLING_EXPORT void getCoordinatesOfNode(int nodeId, std::vector<double>& coo) const; + MEDCOUPLING_EXPORT std::string simpleRepr() const; + MEDCOUPLING_EXPORT std::string advancedRepr() const; + MEDCOUPLING_EXPORT void checkCoherency() const; + MEDCOUPLING_EXPORT void checkCoherency1(double eps=1e-12) const; + MEDCOUPLING_EXPORT void checkCoherency2(double eps=1e-12) const; + MEDCOUPLING_EXPORT void getBoundingBox(double *bbox) const; + MEDCOUPLING_EXPORT void updateTime() const; + MEDCOUPLING_EXPORT void renumberCells(const int *old2NewBg, bool check=true); + MEDCOUPLING_EXPORT MEDCouplingUMesh *getMesh2D() const { return _mesh2D; } + MEDCOUPLING_EXPORT MEDCouplingUMesh *getMesh1D() const { return _mesh1D; } + MEDCOUPLING_EXPORT DataArrayInt *getMesh3DIds() const { return _mesh3D_ids; } + MEDCOUPLING_EXPORT MEDCouplingUMesh *build3DUnstructuredMesh() const; + MEDCOUPLING_EXPORT MEDCouplingUMesh *buildUnstructured() const; + MEDCOUPLING_EXPORT MEDCouplingFieldDouble *getMeasureField(bool) const; + MEDCOUPLING_EXPORT MEDCouplingFieldDouble *getMeasureFieldOnNode(bool) const; + MEDCOUPLING_EXPORT MEDCouplingFieldDouble *buildOrthogonalField() const; + MEDCOUPLING_EXPORT int getCellContainingPoint(const double *pos, double eps) const; + MEDCOUPLING_EXPORT static int FindCorrespCellByNodalConn(const std::vector<int>& nodalConnec, + const int *revNodalPtr, const int *revNodalIndxPtr); + MEDCOUPLING_EXPORT static void Project1DMeshes(const MEDCouplingUMesh *m1, const MEDCouplingUMesh *m2, double eps, + MEDCouplingUMesh *&m1r, MEDCouplingUMesh *&m2r, double *v); + MEDCOUPLING_EXPORT void rotate(const double *center, const double *vector, double angle); + MEDCOUPLING_EXPORT void translate(const double *vector); + MEDCOUPLING_EXPORT void scale(const double *point, double factor); + MEDCOUPLING_EXPORT std::vector<int> getDistributionOfTypes() const; + MEDCOUPLING_EXPORT DataArrayInt *checkTypeConsistencyAndContig(const std::vector<int>& code, const std::vector<const DataArrayInt *>& idsPerType) const; + MEDCOUPLING_EXPORT void splitProfilePerType(const DataArrayInt *profile, std::vector<int>& code, std::vector<DataArrayInt *>& idsInPflPerType, std::vector<DataArrayInt *>& idsPerType) const; + MEDCOUPLING_EXPORT MEDCouplingMesh *buildPart(const int *start, const int *end) const; + MEDCOUPLING_EXPORT MEDCouplingMesh *buildPartAndReduceNodes(const int *start, const int *end, DataArrayInt*& arr) const; + MEDCOUPLING_EXPORT DataArrayInt *simplexize(int policy); + MEDCOUPLING_EXPORT MEDCouplingMesh *mergeMyselfWith(const MEDCouplingMesh *other) const; + MEDCOUPLING_EXPORT DataArrayDouble *getCoordinatesAndOwner() const; + MEDCOUPLING_EXPORT DataArrayDouble *getBarycenterAndOwner() const; + MEDCOUPLING_EXPORT DataArrayDouble *computeIsoBarycenterOfNodesPerCell() const; + MEDCOUPLING_EXPORT void getReverseNodalConnectivity(DataArrayInt *revNodal, DataArrayInt *revNodalIndx) const; + //Serialization unserialisation + MEDCOUPLING_EXPORT void getTinySerializationInformation(std::vector<double>& tinyInfoD, std::vector<int>& tinyInfo, std::vector<std::string>& littleStrings) const; + MEDCOUPLING_EXPORT void resizeForUnserialization(const std::vector<int>& tinyInfo, DataArrayInt *a1, DataArrayDouble *a2, std::vector<std::string>& littleStrings) const; + MEDCOUPLING_EXPORT void serialize(DataArrayInt *&a1, DataArrayDouble *&a2) const; + MEDCOUPLING_EXPORT void unserialization(const std::vector<double>& tinyInfoD, const std::vector<int>& tinyInfo, const DataArrayInt *a1, DataArrayDouble *a2, + const std::vector<std::string>& littleStrings); + MEDCOUPLING_EXPORT void reprQuickOverview(std::ostream& stream) const; + MEDCOUPLING_EXPORT std::string getVTKFileExtension() const; + private: + MEDCouplingExtrudedMesh(const MEDCouplingUMesh *mesh3D, const MEDCouplingUMesh *mesh2D, int cell2DId); + MEDCouplingExtrudedMesh(const MEDCouplingExtrudedMesh& other, bool deepCopy); + MEDCouplingExtrudedMesh(); + void computeExtrusion(const MEDCouplingUMesh *mesh3D); + void computeExtrusionAlg(const MEDCouplingUMesh *mesh3D); + void build1DExtrusion(int idIn3DDesc, int newId, int nbOf1DLev, MEDCouplingUMesh *subMesh, + const int *desc3D, const int *descIndx3D, + const int *revDesc3D, const int *revDescIndx3D, + bool computeMesh1D); + int findOppositeFaceOf(int current2DCell, int current3DCell, const std::vector<int>& connSorted, + const int *desc3D, const int *descIndx3D, + const int *conn2D, const int *conn2DIndx); + void computeBaryCenterOfFace(const std::vector<int>& nodalConnec, int lev1DId); + ~MEDCouplingExtrudedMesh(); + void writeVTKLL(std::ostream& ofs, const std::string& cellData, const std::string& pointData, DataArrayByte *byteData) const; + std::string getVTKDataSetType() const; + private: + MEDCouplingUMesh *_mesh2D; + MEDCouplingUMesh *_mesh1D; + //! New to old 3D cell Ids Array + DataArrayInt *_mesh3D_ids; + int _cell_2D_id; + }; +} + +#endif diff --git a/src/medtool/src/MEDCoupling/MEDCouplingField.cxx b/src/medtool/src/MEDCoupling/MEDCouplingField.cxx new file mode 100644 index 000000000..463a44bbb --- /dev/null +++ b/src/medtool/src/MEDCoupling/MEDCouplingField.cxx @@ -0,0 +1,635 @@ +// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 +// 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 "MEDCouplingField.hxx" +#include "MEDCouplingMesh.hxx" +#include "MEDCouplingFieldDiscretization.hxx" + +#include <sstream> + +using namespace ParaMEDMEM; + +bool MEDCouplingField::isEqualIfNotWhy(const MEDCouplingField *other, double meshPrec, double valsPrec, std::string& reason) const +{ + if(!other) + throw INTERP_KERNEL::Exception("MEDCouplingField::isEqualIfNotWhy : other instance is NULL !"); + std::ostringstream oss; oss.precision(15); + if(_name!=other->_name) + { + oss << "Field names differ : this name = \"" << _name << "\" and other name = \"" << other->_name << "\" !"; + reason=oss.str(); + return false; + } + if(_desc!=other->_desc) + { + oss << "Field descriptions differ : this description = \"" << _desc << "\" and other description = \"" << other->_desc << "\" !"; + reason=oss.str(); + return false; + } + if(_nature!=other->_nature) + { + oss << "Field nature differ : this nature = \"" << MEDCouplingNatureOfField::GetRepr(_nature) << "\" and other nature = \"" << MEDCouplingNatureOfField::GetRepr(other->_nature) << "\" !"; + reason=oss.str(); + return false; + } + if(!_type->isEqualIfNotWhy(other->_type,valsPrec,reason)) + { + reason.insert(0,"Spatial discretizations differ :"); + return false; + } + if(_mesh==0 && other->_mesh==0) + return true; + if(_mesh==0 || other->_mesh==0) + { + reason="Only one field between the two this and other has its underlying mesh defined !"; + return false; + } + if(_mesh==other->_mesh) + return true; + bool ret=_mesh->isEqualIfNotWhy(other->_mesh,meshPrec,reason); + if(!ret) + reason.insert(0,"Underlying meshes of fields differ for the following reason : "); + 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) + return false; + if(_mesh==0 && other->_mesh==0) + return true; + if(_mesh==0 || other->_mesh==0) + return false; + if(_mesh==other->_mesh) + return true; + return _mesh->isEqualWithoutConsideringStr(other->_mesh,meshPrec); +} + +/*! + * This method states if 'this' and 'other' are compatibles each other before performing any treatment. + * This method is good for methods like : mergeFields. + * This method is not very demanding compared to areStrictlyCompatible that is better for operation on fields. + */ +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) + return false; + if(_mesh==other->_mesh) + return true; + return _mesh->areCompatibleForMerge(other->_mesh); +} + +/*! + * This method is more strict than MEDCouplingField::areCompatibleForMerge method. + * This method is used for operation on fields to operate a first check before attempting operation. + */ +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) + return false; + return _mesh==other->_mesh; +} + +/*! + * This method is less strict than MEDCouplingField::areStrictlyCompatible method. + * The difference is that the nature is not checked. + * This method is used for multiplication and division on fields to operate a first check before attempting operation. + */ +bool MEDCouplingField::areStrictlyCompatibleForMulDiv(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; + return _mesh==other->_mesh; +} + + +void MEDCouplingField::updateTime() const +{ + if(_mesh) + updateTimeWith(*_mesh); + if(_type) + updateTimeWith(*_type); +} + +std::size_t MEDCouplingField::getHeapMemorySizeWithoutChildren() const +{ + std::size_t ret=0; + ret+=_name.capacity(); + ret+=_desc.capacity(); + return ret; +} + +std::vector<const BigMemoryObject *> MEDCouplingField::getDirectChildrenWithNull() const +{ + std::vector<const BigMemoryObject *> ret; + ret.push_back(_mesh); + ret.push_back((const MEDCouplingFieldDiscretization *)_type); + 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. + * \throw If the geometric type is empty. + */ +TypeOfField MEDCouplingField::getTypeOfField() const +{ + if(!((const MEDCouplingFieldDiscretization *)_type)) + throw INTERP_KERNEL::Exception("MEDCouplingField::getTypeOfField : spatial discretization is null !"); + return _type->getEnum(); +} + +/*! + * 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 +{ + return _nature; +} + +/*! + * 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) +{ + MEDCouplingNatureOfField::GetRepr(nat);//generate a throw if nat not recognized + _nature=nat; +} + +/*! + * 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 +{ + 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); +} + +/*! + * 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).<br> + * For 1D cells, the returned field contains lengths.<br> + * For 2D cells, the returned field contains areas.<br> + * 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 +{ + 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) + { + if(_mesh) + _mesh->decrRef(); + _mesh=mesh; + declareAsNew(); + if(_mesh) + { + _mesh->incrRef(); + updateTimeWith(*_mesh); + } + } +} + +/*! + * 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<double>& refCoo, + const std::vector<double>& gsCoo, const std::vector<double>& wg) +{ + 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); +} + +/*! + * 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<double>& refCoo, + const std::vector<double>& gsCoo, const std::vector<double>& wg) +{ + 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); +} + +/*! + * 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. + */ +void MEDCouplingField::clearGaussLocalizations() +{ + if(!((const MEDCouplingFieldDiscretization *)_type)) + throw INTERP_KERNEL::Exception("Spatial discretization not set ! Impossible to call clearGaussLocalizations method !"); + _type->clearGaussLocalizations(); +} + +/*! + * 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 <em> 0 <= locId < getNbOfGaussLocalization() </em>. + * \return \ref ParaMEDMEM::MEDCouplingGaussLocalization "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. + */ +MEDCouplingGaussLocalization& MEDCouplingField::getGaussLocalization(int locId) +{ + if(!((const MEDCouplingFieldDiscretization *)_type)) + throw INTERP_KERNEL::Exception("Spatial discretization not set ! Impossible to call getGaussLocalization method !"); + return _type->getGaussLocalization(locId); +} + +/*! + * 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 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 +{ + 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<int> - 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 + */ +std::set<int> MEDCouplingField::getGaussLocalizationIdsOfOneType(INTERP_KERNEL::NormalizedCellType type) const +{ + if(!((const MEDCouplingFieldDiscretization *)_type)) + throw INTERP_KERNEL::Exception("Spatial discretization not set ! Impossible to call getGaussLocalizationIdsOfOneType method !"); + return _type->getGaussLocalizationIdsOfOneType(type); +} + +/*! + * 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. + */ +int MEDCouplingField::getNbOfGaussLocalization() const +{ + if(!((const MEDCouplingFieldDiscretization *)_type)) + throw INTERP_KERNEL::Exception("Spatial discretization not set ! Impossible to call getNbOfGaussLocalization method !"); + return _type->getNbOfGaussLocalization(); +} + +/*! + * 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 no Gauss localization object found for the given cell. + */ +int MEDCouplingField::getGaussLocalizationIdOfOneCell(int cellId) const +{ + if(!((const MEDCouplingFieldDiscretization *)_type)) + throw INTERP_KERNEL::Exception("Spatial discretization not set ! Impossible to call getGaussLocalizationIdOfOneCell method !"); + return _type->getGaussLocalizationIdOfOneCell(cellId); +} + +/*! + * 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 <em> 0 <= locId < getNbOfGaussLocalization() </em>. + * \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. + */ +void MEDCouplingField::getCellIdsHavingGaussLocalization(int locId, std::vector<int>& cellIds) const +{ + cellIds.clear(); + if(!((const MEDCouplingFieldDiscretization *)_type)) + throw INTERP_KERNEL::Exception("Spatial discretization not set ! Impossible to call getCellIdsHavingGaussLocalization method !"); + _type->getCellIdsHavingGaussLocalization(locId,cellIds); +} + +/*! + * 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 <em> 0 <= locId < getNbOfGaussLocalization() </em>. + * \return const \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. + */ +const MEDCouplingGaussLocalization& MEDCouplingField::getGaussLocalization(int locId) const +{ + if(!((const MEDCouplingFieldDiscretization *)_type)) + throw INTERP_KERNEL::Exception("Spatial discretization not set ! Impossible to call getGaussLocalization method !"); + return _type->getGaussLocalization(locId); +} + +MEDCouplingField::~MEDCouplingField() +{ + if(_mesh) + _mesh->decrRef(); +} + +MEDCouplingField::MEDCouplingField(MEDCouplingFieldDiscretization *type, NatureOfField nature):_nature(nature),_mesh(0),_type(type) +{ +} + +MEDCouplingField::MEDCouplingField(TypeOfField type):_nature(NoNature),_mesh(0),_type(MEDCouplingFieldDiscretization::New(type)) +{ +} + +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; +} + +/*! + * 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); +} + +/*! + * Returns number of tuples expected regarding the spatial discretization of \a this + * field and number of entities in the underlying mesh. This method behaves exactly as MEDCouplingFieldDouble::getNumberOfTuples. + * \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 +{ + 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(); +} + +/*! + * 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 +{ + 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) +{ + if(other) + { + setName(other->_name); + setDescription(other->_desc); + } +} + +/*! + * This method computes the number of tuples a DataArrayDouble instance should have to build a correct MEDCouplingFieldDouble instance starting from a + * submesh of a virtual mesh on which a substraction per type had been applied regarding the spatial discretization in \a this. + * + * For spatial discretization \b not equal to ON_GAUSS_NE this method will make the hypothesis that any positive entity id in \a code \a idsPerType is valid. + * So in those cases attribute \a _mesh of \a this is ignored. + * + * For spatial discretization equal to ON_GAUSS_NE \a _mesh attribute will be taken into account. + * + * The input code is those implemented in MEDCouplingUMesh::splitProfilePerType. + * + * \param [in] code - a code with format described above. + * \param [in] idsPerType - a list of subparts + * \throw If \a this has no spatial discretization set. + * \throw If input code point to invalid zones in spatial discretization. + * \throw If spatial discretization in \a this requires a mesh and those mesh is invalid (null,...) + */ +int MEDCouplingField::getNumberOfTuplesExpectedRegardingCode(const std::vector<int>& code, const std::vector<const DataArrayInt *>& idsPerType) const +{ + const MEDCouplingFieldDiscretization *t(_type); + if(!t) + throw INTERP_KERNEL::Exception("MEDCouplingField::getNumberOfTuplesExpectedRegardingCode : no spatial discretization set !"); + return t->getNumberOfTuplesExpectedRegardingCode(code,idsPerType); +} diff --git a/src/medtool/src/MEDCoupling/MEDCouplingField.hxx b/src/medtool/src/MEDCoupling/MEDCouplingField.hxx new file mode 100644 index 000000000..9154f56c2 --- /dev/null +++ b/src/medtool/src/MEDCoupling/MEDCouplingField.hxx @@ -0,0 +1,108 @@ +// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 +// 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_MEDCOUPLINGFIELD_HXX__ +#define __PARAMEDMEM_MEDCOUPLINGFIELD_HXX__ + +#include "MEDCoupling.hxx" +#include "MEDCouplingTimeLabel.hxx" +#include "MEDCouplingNatureOfField.hxx" +#include "MEDCouplingRefCountObject.hxx" +#include "NormalizedUnstructuredMesh.hxx" +#include "MEDCouplingAutoRefCountObjectPtr.hxx" +#include "MEDCouplingFieldDiscretization.hxx" +#include "InterpKernelException.hxx" + +#include <string> +#include <vector> + +namespace ParaMEDMEM +{ + class DataArrayInt; + class DataArrayDouble; + class MEDCouplingMesh; + class MEDCouplingFieldDouble; + class MEDCouplingGaussLocalization; + + class MEDCouplingField : public RefCountObject, public TimeLabel + { + public: + MEDCOUPLING_EXPORT virtual void checkCoherency() const = 0; + MEDCOUPLING_EXPORT virtual bool areCompatibleForMerge(const MEDCouplingField *other) const; + MEDCOUPLING_EXPORT virtual bool areStrictlyCompatible(const MEDCouplingField *other) const; + MEDCOUPLING_EXPORT virtual bool areStrictlyCompatibleForMulDiv(const MEDCouplingField *other) const; + MEDCOUPLING_EXPORT virtual bool isEqualIfNotWhy(const MEDCouplingField *other, double meshPrec, double valsPrec, std::string& reason) const; + MEDCOUPLING_EXPORT virtual bool isEqual(const MEDCouplingField *other, double meshPrec, double valsPrec) const; + MEDCOUPLING_EXPORT virtual bool isEqualWithoutConsideringStr(const MEDCouplingField *other, double meshPrec, double valsPrec) const; + MEDCOUPLING_EXPORT virtual void copyTinyStringsFrom(const MEDCouplingField *other); + MEDCOUPLING_EXPORT void setMesh(const ParaMEDMEM::MEDCouplingMesh *mesh); + MEDCOUPLING_EXPORT const ParaMEDMEM::MEDCouplingMesh *getMesh() const { return _mesh; } + MEDCOUPLING_EXPORT ParaMEDMEM::MEDCouplingMesh *getMesh() { return const_cast<ParaMEDMEM::MEDCouplingMesh *>(_mesh); } + MEDCOUPLING_EXPORT void setName(const std::string& name) { _name=name; } + MEDCOUPLING_EXPORT std::string getDescription() const { return _desc; } + MEDCOUPLING_EXPORT void setDescription(const std::string& desc) { _desc=desc; } + MEDCOUPLING_EXPORT std::string getName() const { return _name; } + MEDCOUPLING_EXPORT TypeOfField getTypeOfField() const; + MEDCOUPLING_EXPORT NatureOfField getNature() const; + MEDCOUPLING_EXPORT virtual void setNature(NatureOfField nat); + MEDCOUPLING_EXPORT DataArrayDouble *getLocalizationOfDiscr() const; + MEDCOUPLING_EXPORT MEDCouplingFieldDouble *buildMeasureField(bool isAbs) const; + MEDCOUPLING_EXPORT MEDCouplingMesh *buildSubMeshData(const int *start, const int *end, DataArrayInt *&di) const; + MEDCOUPLING_EXPORT MEDCouplingMesh *buildSubMeshDataRange(int begin, int end, int step, int& beginOut, int& endOut, int& stepOut, DataArrayInt *&di) const; + MEDCOUPLING_EXPORT DataArrayInt *computeTupleIdsToSelectFromCellIds(const int *startCellIds, const int *endCellIds) const; + MEDCOUPLING_EXPORT const MEDCouplingFieldDiscretization *getDiscretization() const { return _type; } + MEDCOUPLING_EXPORT MEDCouplingFieldDiscretization *getDiscretization() { return _type; } + MEDCOUPLING_EXPORT void setDiscretization(MEDCouplingFieldDiscretization *newDisc); + MEDCOUPLING_EXPORT int getNumberOfTuplesExpected() const; + MEDCOUPLING_EXPORT int getNumberOfMeshPlacesExpected() const; + // Gauss point specific methods + MEDCOUPLING_EXPORT void setGaussLocalizationOnType(INTERP_KERNEL::NormalizedCellType type, const std::vector<double>& refCoo, + const std::vector<double>& gsCoo, const std::vector<double>& wg); + MEDCOUPLING_EXPORT void setGaussLocalizationOnCells(const int *begin, const int *end, const std::vector<double>& refCoo, + const std::vector<double>& gsCoo, const std::vector<double>& wg); + MEDCOUPLING_EXPORT void clearGaussLocalizations(); + MEDCOUPLING_EXPORT MEDCouplingGaussLocalization& getGaussLocalization(int locId); + MEDCOUPLING_EXPORT int getGaussLocalizationIdOfOneType(INTERP_KERNEL::NormalizedCellType type) const; + MEDCOUPLING_EXPORT std::set<int> getGaussLocalizationIdsOfOneType(INTERP_KERNEL::NormalizedCellType type) const; + MEDCOUPLING_EXPORT int getNbOfGaussLocalization() const; + MEDCOUPLING_EXPORT int getGaussLocalizationIdOfOneCell(int cellId) const; + MEDCOUPLING_EXPORT void getCellIdsHavingGaussLocalization(int locId, std::vector<int>& cellIds) const; + MEDCOUPLING_EXPORT const MEDCouplingGaussLocalization& getGaussLocalization(int locId) const; + MEDCOUPLING_EXPORT void updateTime() const; + MEDCOUPLING_EXPORT std::size_t getHeapMemorySizeWithoutChildren() const; + MEDCOUPLING_EXPORT std::vector<const BigMemoryObject *> getDirectChildrenWithNull() const; + // for MED file RW + MEDCOUPLING_EXPORT int getNumberOfTuplesExpectedRegardingCode(const std::vector<int>& code, const std::vector<const DataArrayInt *>& idsPerType) const; + MEDCOUPLING_EXPORT virtual void reprQuickOverview(std::ostream& stream) const = 0; + protected: + MEDCOUPLING_EXPORT MEDCouplingField(TypeOfField type); + MEDCOUPLING_EXPORT MEDCouplingField(const MEDCouplingField& other, bool deepCopy=true); + MEDCOUPLING_EXPORT MEDCouplingField(MEDCouplingFieldDiscretization *type, NatureOfField nature=NoNature); + MEDCOUPLING_EXPORT virtual ~MEDCouplingField(); + protected: + std::string _name; + std::string _desc; + NatureOfField _nature; + const MEDCouplingMesh *_mesh; + MEDCouplingAutoRefCountObjectPtr<MEDCouplingFieldDiscretization> _type; + }; +} + +#endif diff --git a/src/medtool/src/MEDCoupling/MEDCouplingFieldDiscretization.cxx b/src/medtool/src/MEDCoupling/MEDCouplingFieldDiscretization.cxx new file mode 100644 index 000000000..0be106c75 --- /dev/null +++ b/src/medtool/src/MEDCoupling/MEDCouplingFieldDiscretization.cxx @@ -0,0 +1,3061 @@ +// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 +// 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 "MEDCouplingFieldDiscretization.hxx" +#include "MEDCouplingCMesh.hxx" +#include "MEDCouplingUMesh.hxx" +#include "MEDCouplingFieldDouble.hxx" +#include "MEDCouplingAutoRefCountObjectPtr.hxx" + +#include "CellModel.hxx" +#include "InterpolationUtils.hxx" +#include "InterpKernelAutoPtr.hxx" +#include "InterpKernelGaussCoords.hxx" +#include "InterpKernelMatrixTools.hxx" + +#include <set> +#include <list> +#include <limits> +#include <sstream> +#include <numeric> +#include <algorithm> +#include <functional> + +using namespace ParaMEDMEM; + +const double MEDCouplingFieldDiscretization::DFLT_PRECISION=1.e-12; + +const char MEDCouplingFieldDiscretizationP0::REPR[]="P0"; + +const TypeOfField MEDCouplingFieldDiscretizationP0::TYPE=ON_CELLS; + +const char MEDCouplingFieldDiscretizationP1::REPR[]="P1"; + +const TypeOfField MEDCouplingFieldDiscretizationP1::TYPE=ON_NODES; + +const int MEDCouplingFieldDiscretizationPerCell::DFT_INVALID_LOCID_VALUE=-1; + +const char MEDCouplingFieldDiscretizationGauss::REPR[]="GAUSS"; + +const TypeOfField MEDCouplingFieldDiscretizationGauss::TYPE=ON_GAUSS_PT; + +const char MEDCouplingFieldDiscretizationGaussNE::REPR[]="GSSNE"; + +const TypeOfField MEDCouplingFieldDiscretizationGaussNE::TYPE=ON_GAUSS_NE; + +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_POINT1[1]={0.}; +const double MEDCouplingFieldDiscretizationGaussNE::FGP_SEG2[2]={1.,1.}; +const double MEDCouplingFieldDiscretizationGaussNE::FGP_SEG3[3]={0.5555555555555556,0.8888888888888888,0.5555555555555556}; +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_QUAD8[8]={1.,1.,1.,1.,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_TETRA10[10]={1.,1.,1.,1.,1.,1.,1.,1.,1.,1.};//to check +const double MEDCouplingFieldDiscretizationGaussNE::FGP_PENTA6[6]={0.16666666666666666,0.16666666666666666,0.16666666666666666,0.16666666666666666,0.16666666666666666,0.16666666666666666}; +const double MEDCouplingFieldDiscretizationGaussNE::FGP_PENTA15[15]={1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.};//to check +const double MEDCouplingFieldDiscretizationGaussNE::FGP_HEXA8[8]={1.,1.,1.,1.,1.,1.,1.,1.}; +const double MEDCouplingFieldDiscretizationGaussNE::FGP_HEXA20[20]={1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.}; +const double MEDCouplingFieldDiscretizationGaussNE::FGP_HEXA27[27]={1.,1.,1.,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::FGP_PYRA5[5]={0.13333333333333333,0.13333333333333333,0.13333333333333333,0.13333333333333333,0.13333333333333333}; +const double MEDCouplingFieldDiscretizationGaussNE::FGP_PYRA13[13]={1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.};//to check +const double MEDCouplingFieldDiscretizationGaussNE::REF_SEG2[2]={-1.,1.}; +const double MEDCouplingFieldDiscretizationGaussNE::REF_SEG3[3]={-1.,1.,0.}; +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.,-1.,0.,-1.,0.,1.,-1.,1.,0.,-1.,0.,-1.,-1.,-1.,0.,1.,0.,1.,1.,1.,0.,1.,0.,-1.,1.,-1.,-1.,0.,-1.,1.,0.,1.,1.,0.,1.,-1.,0.,0.,0.,-1.,-1.,0.,0.,0.,1.,0.,1.,0.,0.,0.,-1.,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}; +const double MEDCouplingFieldDiscretizationGaussNE::LOC_SEG2[2]={0.577350269189626,-0.577350269189626}; +const double MEDCouplingFieldDiscretizationGaussNE::LOC_SEG3[3]={-0.774596669241,0.,0.774596669241}; +const double MEDCouplingFieldDiscretizationGaussNE::LOC_SEG4[4]={0.339981043584856,-0.339981043584856,0.861136311594053,-0.861136311594053}; +const double MEDCouplingFieldDiscretizationGaussNE::LOC_TRI3[6]={0.16666666666666667,0.16666666666666667,0.6666666666666667,0.16666666666666667,0.16666666666666667,0.6666666666666667}; +const double MEDCouplingFieldDiscretizationGaussNE::LOC_TRI6[12]={0.091576213509771,0.091576213509771,0.816847572980458,0.091576213509771,0.091576213509771,0.816847572980458,0.445948490915965,0.10810301816807,0.445948490915965,0.445948490915965,0.10810301816807,0.445948490915965}; +const double MEDCouplingFieldDiscretizationGaussNE::LOC_TRI7[14]={0.3333333333333333,0.3333333333333333,0.470142064105115,0.470142064105115,0.05971587178977,0.470142064105115,0.470142064105115,0.05971587178977,0.101286507323456,0.101286507323456,0.797426985353088,0.101286507323456,0.101286507323456,0.797426985353088}; +const double MEDCouplingFieldDiscretizationGaussNE::LOC_QUAD4[8]={-0.774596669241483,-0.774596669241483,0.774596669241483,-0.774596669241483,0.774596669241483,0.774596669241483,-0.774596669241483,0.774596669241483}; +const double MEDCouplingFieldDiscretizationGaussNE::LOC_QUAD8[16]={-0.774596669241483,-0.774596669241483,0.774596669241483,-0.774596669241483,0.774596669241483,0.774596669241483,-0.774596669241483,0.774596669241483,0.,-0.774596669241483,0.774596669241483,0.,0.,0.774596669241483,-0.774596669241483,0.}; +const double MEDCouplingFieldDiscretizationGaussNE::LOC_QUAD9[18]={-0.774596669241483,-0.774596669241483,0.774596669241483,-0.774596669241483,0.774596669241483,0.774596669241483,-0.774596669241483,0.774596669241483,0.,-0.774596669241483,0.774596669241483,0.,0.,0.774596669241483,-0.774596669241483,0.,0.,0.}; +const double MEDCouplingFieldDiscretizationGaussNE::LOC_TETRA4[12]={0.1381966011250105,0.1381966011250105,0.1381966011250105,0.1381966011250105,0.1381966011250105,0.5854101966249685,0.1381966011250105,0.5854101966249685,0.1381966011250105,0.5854101966249685,0.1381966011250105,0.1381966011250105}; +const double MEDCouplingFieldDiscretizationGaussNE::LOC_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.};//to check +const double MEDCouplingFieldDiscretizationGaussNE::LOC_PENTA6[18]={-0.5773502691896258,0.5,0.5,-0.5773502691896258,0.,0.5,-0.5773502691896258,0.5,0.,0.5773502691896258,0.5,0.5,0.5773502691896258,0.,0.5,0.5773502691896258,0.5,0.}; +const double MEDCouplingFieldDiscretizationGaussNE::LOC_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.};//to check +const double MEDCouplingFieldDiscretizationGaussNE::LOC_HEXA8[24]={-0.5773502691896258,-0.5773502691896258,-0.5773502691896258,-0.5773502691896258,-0.5773502691896258,0.5773502691896258,-0.5773502691896258,0.5773502691896258,-0.5773502691896258,-0.5773502691896258,0.5773502691896258,0.5773502691896258,0.5773502691896258,-0.5773502691896258,-0.5773502691896258,0.5773502691896258,-0.5773502691896258,0.5773502691896258,0.5773502691896258,0.5773502691896258,-0.5773502691896258,0.5773502691896258,0.5773502691896258,0.5773502691896258}; +const double MEDCouplingFieldDiscretizationGaussNE::LOC_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.};//to check +const double MEDCouplingFieldDiscretizationGaussNE::LOC_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.,-1.,0.,-1.,0.,1.,-1.,1.,0.,-1.,0.,-1.,-1.,-1.,0.,1.,0.,1.,1.,1.,0.,1.,0.,-1.,1.,-1.,-1.,0.,-1.,1.,0.,1.,1.,0.,1.,-1.,0.,0.,0.,-1.,-1.,0.,0.,0.,1.,0.,1.,0.,0.,0.,-1.,0.,0.,0.,1.,0.,0.,0.}; +const double MEDCouplingFieldDiscretizationGaussNE::LOC_PYRA5[15]={0.5,0.,0.1531754163448146,0.,0.5,0.1531754163448146,-0.5,0.,0.1531754163448146,0.,-0.5,0.1531754163448146,0.,0.,0.6372983346207416}; +const double MEDCouplingFieldDiscretizationGaussNE::LOC_PYRA13[39]={1.,0.,0.,0.,-1.,0.,-1.,0.,0.,0.,1.,0.,0.,0.,0.999999999999,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};//to check 0.99999... to avoid nan ! on node #4 of PYRA13 + +MEDCouplingFieldDiscretization::MEDCouplingFieldDiscretization():_precision(DFLT_PRECISION) +{ +} + +MEDCouplingFieldDiscretization *MEDCouplingFieldDiscretization::New(TypeOfField type) +{ + switch(type) + { + case MEDCouplingFieldDiscretizationP0::TYPE: + return new MEDCouplingFieldDiscretizationP0; + case MEDCouplingFieldDiscretizationP1::TYPE: + return new MEDCouplingFieldDiscretizationP1; + case MEDCouplingFieldDiscretizationGauss::TYPE: + return new MEDCouplingFieldDiscretizationGauss; + case MEDCouplingFieldDiscretizationGaussNE::TYPE: + return new MEDCouplingFieldDiscretizationGaussNE; + case MEDCouplingFieldDiscretizationKriging::TYPE: + return new MEDCouplingFieldDiscretizationKriging; + default: + throw INTERP_KERNEL::Exception("Choosen discretization is not implemented yet."); + } +} + +TypeOfField MEDCouplingFieldDiscretization::GetTypeOfFieldFromStringRepr(const std::string& repr) +{ + if(repr==MEDCouplingFieldDiscretizationP0::REPR) + return MEDCouplingFieldDiscretizationP0::TYPE; + if(repr==MEDCouplingFieldDiscretizationP1::REPR) + return MEDCouplingFieldDiscretizationP1::TYPE; + if(repr==MEDCouplingFieldDiscretizationGauss::REPR) + return MEDCouplingFieldDiscretizationGauss::TYPE; + if(repr==MEDCouplingFieldDiscretizationGaussNE::REPR) + return MEDCouplingFieldDiscretizationGaussNE::TYPE; + if(repr==MEDCouplingFieldDiscretizationKriging::REPR) + return MEDCouplingFieldDiscretizationKriging::TYPE; + throw INTERP_KERNEL::Exception("Representation does not match with any field discretization !"); +} + +std::string MEDCouplingFieldDiscretization::GetTypeOfFieldRepr(TypeOfField type) +{ + if(type==MEDCouplingFieldDiscretizationP0::TYPE) + return MEDCouplingFieldDiscretizationP0::REPR; + if(type==MEDCouplingFieldDiscretizationP1::TYPE) + return MEDCouplingFieldDiscretizationP1::REPR; + if(type==MEDCouplingFieldDiscretizationGauss::TYPE) + return MEDCouplingFieldDiscretizationGauss::REPR; + if(type==MEDCouplingFieldDiscretizationGaussNE::TYPE) + return MEDCouplingFieldDiscretizationGaussNE::REPR; + if(type==MEDCouplingFieldDiscretizationKriging::TYPE) + return MEDCouplingFieldDiscretizationKriging::REPR; + throw INTERP_KERNEL::Exception("GetTypeOfFieldRepr : Representation does not match with any field discretization !"); +} + +bool MEDCouplingFieldDiscretization::isEqual(const MEDCouplingFieldDiscretization *other, double eps) const +{ + std::string reason; + return isEqualIfNotWhy(other,eps,reason); +} + +bool MEDCouplingFieldDiscretization::isEqualWithoutConsideringStr(const MEDCouplingFieldDiscretization *other, double eps) const +{ + 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. + */ +MEDCouplingFieldDiscretization *MEDCouplingFieldDiscretization::clonePart(const int *startCellIds, const int *endCellIds) 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. + */ +void MEDCouplingFieldDiscretization::updateTime() const +{ +} + +std::size_t MEDCouplingFieldDiscretization::getHeapMemorySizeWithoutChildren() const +{ + return 0; +} + +std::vector<const BigMemoryObject *> MEDCouplingFieldDiscretization::getDirectChildrenWithNull() const +{ + return std::vector<const BigMemoryObject *>(); +} + +/*! + * Computes normL1 of DataArrayDouble instance arr. + * @param res output parameter expected to be of size arr->getNumberOfComponents(); + * @throw when the field discretization fails on getMeasure fields (gauss points for example) + */ +void MEDCouplingFieldDiscretization::normL1(const MEDCouplingMesh *mesh, const DataArrayDouble *arr, double *res) const +{ + MEDCouplingAutoRefCountObjectPtr<MEDCouplingFieldDouble> vol=getMeasureField(mesh,true); + int nbOfCompo=arr->getNumberOfComponents(); + int nbOfElems=getNumberOfTuples(mesh); + std::fill(res,res+nbOfCompo,0.); + const double *arrPtr=arr->getConstPointer(); + const double *volPtr=vol->getArray()->getConstPointer(); + double deno=0.; + for(int i=0;i<nbOfElems;i++) + { + double v=fabs(volPtr[i]); + for(int j=0;j<nbOfCompo;j++) + res[j]+=fabs(arrPtr[i*nbOfCompo+j])*v; + deno+=v; + } + std::transform(res,res+nbOfCompo,res,std::bind2nd(std::multiplies<double>(),1./deno)); +} + +/*! + * Computes normL2 of DataArrayDouble instance arr. + * @param res output parameter expected to be of size arr->getNumberOfComponents(); + * @throw when the field discretization fails on getMeasure fields (gauss points for example) + */ +void MEDCouplingFieldDiscretization::normL2(const MEDCouplingMesh *mesh, const DataArrayDouble *arr, double *res) const +{ + MEDCouplingAutoRefCountObjectPtr<MEDCouplingFieldDouble> vol=getMeasureField(mesh,true); + int nbOfCompo=arr->getNumberOfComponents(); + int nbOfElems=getNumberOfTuples(mesh); + std::fill(res,res+nbOfCompo,0.); + const double *arrPtr=arr->getConstPointer(); + const double *volPtr=vol->getArray()->getConstPointer(); + double deno=0.; + for(int i=0;i<nbOfElems;i++) + { + double v=fabs(volPtr[i]); + for(int j=0;j<nbOfCompo;j++) + res[j]+=arrPtr[i*nbOfCompo+j]*arrPtr[i*nbOfCompo+j]*v; + deno+=v; + } + std::transform(res,res+nbOfCompo,res,std::bind2nd(std::multiplies<double>(),1./deno)); + std::transform(res,res+nbOfCompo,res,std::ptr_fun<double,double>(std::sqrt)); +} + +/*! + * Computes integral of DataArrayDouble instance arr. + * @param res output parameter expected to be of size arr->getNumberOfComponents(); + * @throw when the field discretization fails on getMeasure fields (gauss points for example) + */ +void MEDCouplingFieldDiscretization::integral(const MEDCouplingMesh *mesh, const DataArrayDouble *arr, bool isWAbs, double *res) const +{ + if(!mesh) + throw INTERP_KERNEL::Exception("MEDCouplingFieldDiscretization::integral : mesh is NULL !"); + if(!arr) + throw INTERP_KERNEL::Exception("MEDCouplingFieldDiscretization::integral : input array is NULL !"); + MEDCouplingAutoRefCountObjectPtr<MEDCouplingFieldDouble> 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(); + INTERP_KERNEL::AutoPtr<double> tmp=new double[nbOfCompo]; + for (int i=0;i<nbOfElems;i++) + { + std::transform(arrPtr+i*nbOfCompo,arrPtr+(i+1)*nbOfCompo,(double *)tmp,std::bind2nd(std::multiplies<double>(),volPtr[i])); + std::transform((double *)tmp,(double *)tmp+nbOfCompo,res,res,std::plus<double>()); + } +} + +/*! + * 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<DataArrayInt> da=DataArrayInt::Range(beginCellIds,endCellIds,stepCellIds); + return buildSubMeshData(mesh,da->begin(),da->end(),di); +} + +void MEDCouplingFieldDiscretization::getSerializationIntArray(DataArrayInt *& arr) const +{ + arr=0; +} + +/*! + * Empty : Not a bug + */ +void MEDCouplingFieldDiscretization::getTinySerializationIntInformation(std::vector<int>& tinyInfo) const +{ +} + +/*! + * Empty : Not a bug + */ +void MEDCouplingFieldDiscretization::getTinySerializationDbleInformation(std::vector<double>& tinyInfo) const +{ +} + +void MEDCouplingFieldDiscretization::resizeForUnserialization(const std::vector<int>& tinyInfo, DataArrayInt *& arr) +{ + arr=0; +} + +/*! + * Empty : Not a bug + */ +void MEDCouplingFieldDiscretization::checkForUnserialization(const std::vector<int>& tinyInfo, const DataArrayInt *arr) +{ +} + +/*! + * Empty : Not a bug + */ +void MEDCouplingFieldDiscretization::finishUnserialization(const std::vector<double>& tinyInfo) +{ +} + +/*! + * This method is typically the first step of renumbering. The implementation is empty it is not a bug only gauss is impacted + * virtualy by this method. + */ +void MEDCouplingFieldDiscretization::renumberCells(const int *old2NewBg, bool check) +{ +} + +double MEDCouplingFieldDiscretization::getIJK(const MEDCouplingMesh *mesh, const DataArrayDouble *da, int cellId, int nodeIdInCell, int compoId) const +{ + throw INTERP_KERNEL::Exception("getIJK Invalid ! only for GaussPoint and GaussNE discretizations !"); +} + +void MEDCouplingFieldDiscretization::setGaussLocalizationOnType(const MEDCouplingMesh *m, INTERP_KERNEL::NormalizedCellType type, const std::vector<double>& refCoo, + const std::vector<double>& gsCoo, const std::vector<double>& wg) +{ + throw INTERP_KERNEL::Exception("Invalid method for the corresponding field discretization : available only for GaussPoint discretization !"); +} + +void MEDCouplingFieldDiscretization::setGaussLocalizationOnCells(const MEDCouplingMesh *m, const int *begin, const int *end, const std::vector<double>& refCoo, + const std::vector<double>& gsCoo, const std::vector<double>& wg) +{ + throw INTERP_KERNEL::Exception("Invalid method for the corresponding field discretization : available only for GaussPoint discretization !"); +} + +void MEDCouplingFieldDiscretization::clearGaussLocalizations() +{ + throw INTERP_KERNEL::Exception("Invalid method for the corresponding field discretization : available only for GaussPoint discretization !"); +} + +MEDCouplingGaussLocalization& MEDCouplingFieldDiscretization::getGaussLocalization(int locId) +{ + throw INTERP_KERNEL::Exception("Invalid method for the corresponding field discretization : available only for GaussPoint discretization !"); +} + +const MEDCouplingGaussLocalization& MEDCouplingFieldDiscretization::getGaussLocalization(int locId) const +{ + throw INTERP_KERNEL::Exception("Invalid method for the corresponding field discretization : available only for GaussPoint discretization !"); +} + +int MEDCouplingFieldDiscretization::getNbOfGaussLocalization() const +{ + throw INTERP_KERNEL::Exception("Invalid method for the corresponding field discretization : available only for GaussPoint discretization !"); +} + +int MEDCouplingFieldDiscretization::getGaussLocalizationIdOfOneCell(int cellId) const +{ + throw INTERP_KERNEL::Exception("Invalid method for the corresponding field discretization : available only for GaussPoint discretization !"); +} + +int MEDCouplingFieldDiscretization::getGaussLocalizationIdOfOneType(INTERP_KERNEL::NormalizedCellType type) const +{ + throw INTERP_KERNEL::Exception("Invalid method for the corresponding field discretization : available only for GaussPoint discretization !"); +} + +std::set<int> MEDCouplingFieldDiscretization::getGaussLocalizationIdsOfOneType(INTERP_KERNEL::NormalizedCellType type) const +{ + throw INTERP_KERNEL::Exception("Invalid method for the corresponding field discretization : available only for GaussPoint discretization !"); +} + +void MEDCouplingFieldDiscretization::getCellIdsHavingGaussLocalization(int locId, std::vector<int>& cellIds) const +{ + throw INTERP_KERNEL::Exception("Invalid method for the corresponding field discretization : available only for GaussPoint discretization !"); +} + +void MEDCouplingFieldDiscretization::RenumberEntitiesFromO2NArr(double eps, const int *old2NewPtr, int newNbOfEntity, DataArrayDouble *arr, const std::string& msg) +{ + if(!arr) + throw INTERP_KERNEL::Exception("MEDCouplingFieldDiscretization::RenumberEntitiesFromO2NArr : input array is NULL !"); + int oldNbOfElems=arr->getNumberOfTuples(); + int nbOfComp=arr->getNumberOfComponents(); + int newNbOfTuples=newNbOfEntity; + MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> arrCpy=arr->deepCpy(); + const double *ptSrc=arrCpy->getConstPointer(); + arr->reAlloc(newNbOfTuples); + double *ptToFill=arr->getPointer(); + std::fill(ptToFill,ptToFill+nbOfComp*newNbOfTuples,std::numeric_limits<double>::max()); + INTERP_KERNEL::AutoPtr<double> tmp=new double[nbOfComp]; + for(int i=0;i<oldNbOfElems;i++) + { + int newNb=old2NewPtr[i]; + if(newNb>=0)//if newNb<0 the node is considered as out. + { + if(std::find_if(ptToFill+newNb*nbOfComp,ptToFill+(newNb+1)*nbOfComp,std::bind2nd(std::not_equal_to<double>(),std::numeric_limits<double>::max())) + ==ptToFill+(newNb+1)*nbOfComp) + std::copy(ptSrc+i*nbOfComp,ptSrc+(i+1)*nbOfComp,ptToFill+newNb*nbOfComp); + else + { + std::transform(ptSrc+i*nbOfComp,ptSrc+(i+1)*nbOfComp,ptToFill+newNb*nbOfComp,(double *)tmp,std::minus<double>()); + std::transform((double *)tmp,((double *)tmp)+nbOfComp,(double *)tmp,std::ptr_fun<double,double>(fabs)); + //if(!std::equal(ptSrc+i*nbOfComp,ptSrc+(i+1)*nbOfComp,ptToFill+newNb*nbOfComp)) + if(*std::max_element((double *)tmp,((double *)tmp)+nbOfComp)>eps) + { + std::ostringstream oss; + oss << msg << " " << i << " and " << std::find(old2NewPtr,old2NewPtr+i,newNb)-old2NewPtr + << " have been merged and " << msg << " field on them are different !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + } + } + } +} + +void MEDCouplingFieldDiscretization::RenumberEntitiesFromN2OArr(const int *new2OldPtr, int new2OldSz, DataArrayDouble *arr, const std::string& msg) +{ + int nbOfComp=arr->getNumberOfComponents(); + MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> arrCpy=arr->deepCpy(); + const double *ptSrc=arrCpy->getConstPointer(); + arr->reAlloc(new2OldSz); + double *ptToFill=arr->getPointer(); + for(int i=0;i<new2OldSz;i++) + { + int oldNb=new2OldPtr[i]; + std::copy(ptSrc+oldNb*nbOfComp,ptSrc+(oldNb+1)*nbOfComp,ptToFill+i*nbOfComp); + } +} + +MEDCouplingFieldDiscretization::~MEDCouplingFieldDiscretization() +{ +} + +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; +} + +std::string MEDCouplingFieldDiscretizationP0::getStringRepr() const +{ + return std::string(REPR); +} + +const char *MEDCouplingFieldDiscretizationP0::getRepr() const +{ + return REPR; +} + +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<const MEDCouplingFieldDiscretizationP0 *>(other); + bool ret=otherC!=0; + if(!ret) + reason="Spatial discrtization of this is ON_CELLS, which is not the case of other."; + return ret; +} + +int MEDCouplingFieldDiscretizationP0::getNumberOfTuples(const MEDCouplingMesh *mesh) const +{ + if(!mesh) + throw INTERP_KERNEL::Exception("MEDCouplingFieldDiscretizationP0::getNumberOfTuples : NULL input mesh !"); + return mesh->getNumberOfCells(); +} + +/*! + * This method returns the number of tuples regarding exclusively the input code \b without \b using \b a \b mesh \b in \b input. + * The input code coherency is also checked regarding spatial discretization of \a this. + * If an incoherency is detected, an exception will be thrown. If the input code is coherent, the number of tuples expected is returned. + * The number of tuples expected is equal to those to have a valid field lying on \a this and having a mesh fitting perfectly the input code (geometric type distribution). + */ +int MEDCouplingFieldDiscretizationP0::getNumberOfTuplesExpectedRegardingCode(const std::vector<int>& code, const std::vector<const DataArrayInt *>& idsPerType) const +{ + if(code.size()%3!=0) + throw INTERP_KERNEL::Exception("MEDCouplingFieldDiscretizationP0::getNumberOfTuplesExpectedRegardingCode : invalid input code !"); + int nbOfSplit=(int)idsPerType.size(); + int nbOfTypes=(int)code.size()/3; + int ret=0; + for(int i=0;i<nbOfTypes;i++) + { + int nbOfEltInChunk=code[3*i+1]; + if(nbOfEltInChunk<0) + throw INTERP_KERNEL::Exception("MEDCouplingFieldDiscretizationP0::getNumberOfTuplesExpectedRegardingCode : invalid input code ! presence of negative value in a type !"); + int pos=code[3*i+2]; + if(pos!=-1) + { + if(pos<0 || pos>=nbOfSplit) + { + std::ostringstream oss; oss << "MEDCouplingFieldDiscretizationP0::getNumberOfTuplesExpectedRegardingCode : input code points to pos " << pos << " in typeid " << i << " ! Should be in [0," << nbOfSplit << ") !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + const DataArrayInt *ids(idsPerType[pos]); + if(!ids || !ids->isAllocated() || ids->getNumberOfComponents()!=1 || ids->getNumberOfTuples()!=nbOfEltInChunk || ids->getMinValueInArray()<0) + { + std::ostringstream oss; oss << "MEDCouplingFieldDiscretizationP0::getNumberOfTuplesExpectedRegardingCode : input pfl chunck at pos " << pos << " should have " << i << " tuples and one component and with ids all >=0 !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + } + ret+=nbOfEltInChunk; + } + return ret; +} + +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); + ret->iota(0); + return ret; +} + +void MEDCouplingFieldDiscretizationP0::renumberArraysForCell(const MEDCouplingMesh *mesh, const std::vector<DataArray *>& arrays, + const int *old2NewBg, bool check) +{ + 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<DataArray *>::const_iterator it=arrays.begin();it!=arrays.end();it++) + { + if(*it) + (*it)->renumberInPlace(array); + } + if(check) + free(const_cast<int *>(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 *tupleIdsBg, const int *tupleIdsEnd, + DataArrayInt *&cellRestriction, DataArrayInt *&trueTupleRestriction) const +{ + if(!mesh) + throw INTERP_KERNEL::Exception("MEDCouplingFieldDiscretizationP0::computeMeshRestrictionFromTupleIds : NULL input mesh !"); + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> tmp=DataArrayInt::New(); + tmp->alloc((int)std::distance(tupleIdsBg,tupleIdsEnd),1); + std::copy(tupleIdsBg,tupleIdsEnd,tmp->getPointer()); + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> tmp2(tmp->deepCpy()); + cellRestriction=tmp.retn(); + trueTupleRestriction=tmp2.retn(); +} + +void MEDCouplingFieldDiscretizationP0::reprQuickOverview(std::ostream& stream) const +{ + stream << "P0 spatial discretization."; +} + +void MEDCouplingFieldDiscretizationP0::checkCompatibilityWithNature(NatureOfField nat) const +{ +} + +void MEDCouplingFieldDiscretizationP0::checkCoherencyBetween(const MEDCouplingMesh *mesh, const DataArray *da) const +{ + if(!mesh || !da) + throw INTERP_KERNEL::Exception("MEDCouplingFieldDiscretizationP0::checkCoherencyBetween : NULL input mesh or DataArray !"); + if(mesh->getNumberOfCells()!=da->getNumberOfTuples()) + { + std::ostringstream message; + message << "Field on cells invalid because there are " << mesh->getNumberOfCells(); + message << " cells in mesh and " << da->getNumberOfTuples() << " tuples in field !"; + throw INTERP_KERNEL::Exception(message.str().c_str()); + } +} + +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 !"); + arr->getTuple(id,res); +} + +void MEDCouplingFieldDiscretizationP0::getValueOnPos(const DataArrayDouble *arr, const MEDCouplingMesh *mesh, int i, int j, int k, double *res) const +{ + const MEDCouplingCMesh *meshC=dynamic_cast<const MEDCouplingCMesh *>(mesh); + if(!meshC) + throw INTERP_KERNEL::Exception("P0::getValueOnPos is only accessible for structured meshes !"); + int id=meshC->getCellIdFromPos(i,j,k); + arr->getTuple(id,res); +} + +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 !"); + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> eltsArr,eltsIndexArr; + mesh->getCellsContainingPoints(loc,nbOfPoints,_precision,eltsArr,eltsIndexArr); + const int *elts(eltsArr->begin()),*eltsIndex(eltsIndexArr->begin()); + int spaceDim=mesh->getSpaceDimension(); + int nbOfComponents=arr->getNumberOfComponents(); + MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New(); + ret->alloc(nbOfPoints,nbOfComponents); + double *ptToFill=ret->getPointer(); + for(int i=0;i<nbOfPoints;i++,ptToFill+=nbOfComponents) + if(eltsIndex[i+1]-eltsIndex[i]>=1) + arr->getTuple(elts[eltsIndex[i]],ptToFill); + else + { + std::ostringstream oss; oss << "Point #" << i << " with coordinates : ("; + std::copy(loc+i*spaceDim,loc+(i+1)*spaceDim,std::ostream_iterator<double>(oss,", ")); + oss << ") detected outside mesh : unable to apply P0::getValueOnMulti ! "; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + return ret.retn(); +} + +/*! + * Nothing to do. It's not a bug. + */ +void MEDCouplingFieldDiscretizationP0::renumberValuesOnNodes(double , const int *, int newNbOfNodes, DataArrayDouble *) const +{ +} + +void MEDCouplingFieldDiscretizationP0::renumberValuesOnCells(double epsOnVals, const MEDCouplingMesh *mesh, const int *old2New, int newSz, DataArrayDouble *arr) const +{ + RenumberEntitiesFromO2NArr(epsOnVals,old2New,newSz,arr,"Cell"); +} + +void MEDCouplingFieldDiscretizationP0::renumberValuesOnCellsR(const MEDCouplingMesh *mesh, const int *new2old, int newSz, DataArrayDouble *arr) const +{ + RenumberEntitiesFromN2OArr(new2old,newSz,arr,"Cell"); +} + +/*! + * This method returns a tuple ids selection from cell ids selection [start;end). + * This method is called by MEDCouplingFieldDiscretizationP0::buildSubMeshData to return parameter \b di. + * Here for P0 it's very simple ! + * + * \return a newly allocated array containing ids to select into the DataArrayDouble of the field. + * + */ +DataArrayInt *MEDCouplingFieldDiscretizationP0::computeTupleIdsToSelectFromCellIds(const MEDCouplingMesh *mesh, const int *startCellIds, const int *endCellIds) const +{ + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New(); + ret->alloc((int)std::distance(startCellIds,endCellIds),1); + std::copy(startCellIds,endCellIds,ret->getPointer()); + 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 +{ + if(!mesh) + throw INTERP_KERNEL::Exception("MEDCouplingFieldDiscretizationP0::buildSubMeshData : NULL input mesh !"); + MEDCouplingAutoRefCountObjectPtr<MEDCouplingMesh> ret=mesh->buildPart(start,end); + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> diSafe=DataArrayInt::New(); + diSafe->alloc((int)std::distance(start,end),1); + std::copy(start,end,diSafe->getPointer()); + di=diSafe.retn(); + return ret.retn(); +} + +/*! + * 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<MEDCouplingMesh> ret=mesh->buildPartRange(beginCellIds,endCellIds,stepCellIds); + di=0; beginOut=beginCellIds; endOut=endCellIds; stepOut=stepCellIds; + return ret.retn(); +} + +int MEDCouplingFieldDiscretizationOnNodes::getNumberOfTuples(const MEDCouplingMesh *mesh) const +{ + if(!mesh) + throw INTERP_KERNEL::Exception("MEDCouplingFieldDiscretizationNodes::getNumberOfTuples : NULL input mesh !"); + return mesh->getNumberOfNodes(); +} + +/*! + * This method returns the number of tuples regarding exclusively the input code \b without \b using \b a \b mesh \b in \b input. + * The input code coherency is also checked regarding spatial discretization of \a this. + * If an incoherency is detected, an exception will be thrown. If the input code is coherent, the number of tuples expected is returned. + * The number of tuples expected is equal to those to have a valid field lying on \a this and having a mesh fitting perfectly the input code (geometric type distribution). + */ +int MEDCouplingFieldDiscretizationOnNodes::getNumberOfTuplesExpectedRegardingCode(const std::vector<int>& code, const std::vector<const DataArrayInt *>& idsPerType) const +{ + if(code.size()%3!=0) + throw INTERP_KERNEL::Exception("MEDCouplingFieldDiscretizationOnNodes::getNumberOfTuplesExpectedRegardingCode : invalid input code !"); + int nbOfSplit=(int)idsPerType.size(); + int nbOfTypes=(int)code.size()/3; + int ret=0; + for(int i=0;i<nbOfTypes;i++) + { + int nbOfEltInChunk=code[3*i+1]; + if(nbOfEltInChunk<0) + throw INTERP_KERNEL::Exception("MEDCouplingFieldDiscretizationOnNodes::getNumberOfTuplesExpectedRegardingCode : invalid input code ! presence of negative value in a type !"); + int pos=code[3*i+2]; + if(pos!=-1) + { + if(pos<0 || pos>=nbOfSplit) + { + std::ostringstream oss; oss << "MEDCouplingFieldDiscretizationOnNodes::getNumberOfTuplesExpectedRegardingCode : input code points to pos " << pos << " in typeid " << i << " ! Should be in [0," << nbOfSplit << ") !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + const DataArrayInt *ids(idsPerType[pos]); + if(!ids || !ids->isAllocated() || ids->getNumberOfComponents()!=1 || ids->getNumberOfTuples()!=nbOfEltInChunk || ids->getMinValueInArray()<0) + { + std::ostringstream oss; oss << "MEDCouplingFieldDiscretizationOnNodes::getNumberOfTuplesExpectedRegardingCode : input pfl chunck at pos " << pos << " should have " << i << " tuples and one component and with ids all >=0 !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + } + ret+=nbOfEltInChunk; + } + return ret; +} + +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<DataArray *>& arrays, + const int *old2NewBg, bool check) +{ +} + +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); + ret->iota(0); + return ret; +} + +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 *tupleIdsBg, const int *tupleIdsEnd, + DataArrayInt *&cellRestriction, DataArrayInt *&trueTupleRestriction) const +{ + if(!mesh) + throw INTERP_KERNEL::Exception("MEDCouplingFieldDiscretizationOnNodes::computeMeshRestrictionFromTupleIds : NULL input mesh !"); + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret1=mesh->getCellIdsFullyIncludedInNodeIds(tupleIdsBg,tupleIdsEnd); + const MEDCouplingUMesh *meshc=dynamic_cast<const MEDCouplingUMesh *>(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<MEDCouplingUMesh> meshPart=static_cast<MEDCouplingUMesh *>(meshc->buildPartOfMySelf(ret1->begin(),ret1->end(),true)); + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret2=meshPart->computeFetchedNodeIds(); + cellRestriction=ret1.retn(); + trueTupleRestriction=ret2.retn(); +} + +void MEDCouplingFieldDiscretizationOnNodes::checkCoherencyBetween(const MEDCouplingMesh *mesh, const DataArray *da) const +{ + if(!mesh || !da) + throw INTERP_KERNEL::Exception("MEDCouplingFieldDiscretizationNodes::checkCoherencyBetween : NULL input mesh or DataArray !"); + if(mesh->getNumberOfNodes()!=da->getNumberOfTuples()) + { + std::ostringstream message; + message << "Field on nodes invalid because there are " << mesh->getNumberOfNodes(); + message << " nodes in mesh and " << da->getNumberOfTuples() << " tuples in field !"; + throw INTERP_KERNEL::Exception(message.str().c_str()); + } +} + +/*! + * 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 nodes ids) in mesh 'mesh' of entity in returned submesh. + * Example : The first node id of returned mesh has the (*di)[0] id in 'mesh' + */ +MEDCouplingMesh *MEDCouplingFieldDiscretizationOnNodes::buildSubMeshData(const MEDCouplingMesh *mesh, const int *start, const int *end, DataArrayInt *&di) const +{ + if(!mesh) + throw INTERP_KERNEL::Exception("MEDCouplingFieldDiscretizationNodes::buildSubMeshData : NULL input mesh !"); + DataArrayInt *diTmp=0; + MEDCouplingAutoRefCountObjectPtr<MEDCouplingMesh> ret=mesh->buildPartAndReduceNodes(start,end,diTmp); + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> diTmpSafe(diTmp); + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> 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<MEDCouplingMesh> ret=mesh->buildPartRangeAndReduceNodes(beginCellIds,endCellIds,stepCellIds,beginOut,endOut,stepOut,diTmp); + if(diTmp) + { + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> diTmpSafe(diTmp); + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> di2=diTmpSafe->invertArrayO2N2N2O(ret->getNumberOfNodes()); + di=di2.retn(); + } + return ret.retn(); +} + +/*! + * This method returns a tuple ids selection from cell ids selection [start;end). + * This method is called by MEDCouplingFieldDiscretizationOnNodes::buildSubMeshData to return parameter \b di. + * Here for P1 only nodes fetched by submesh of mesh[startCellIds:endCellIds) is returned ! + * + * \return a newly allocated array containing ids to select into the DataArrayDouble of the field. + * + */ +DataArrayInt *MEDCouplingFieldDiscretizationOnNodes::computeTupleIdsToSelectFromCellIds(const MEDCouplingMesh *mesh, const int *startCellIds, const int *endCellIds) const +{ + if(!mesh) + throw INTERP_KERNEL::Exception("MEDCouplingFieldDiscretizationP1::computeTupleIdsToSelectFromCellIds : NULL input mesh !"); + const MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> umesh=mesh->buildUnstructured(); + MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> umesh2=static_cast<MEDCouplingUMesh *>(umesh->buildPartOfMySelf(startCellIds,endCellIds,true)); + return umesh2->computeFetchedNodeIds(); +} + +void MEDCouplingFieldDiscretizationOnNodes::renumberValuesOnNodes(double epsOnVals, const int *old2NewPtr, int newNbOfNodes, DataArrayDouble *arr) const +{ + RenumberEntitiesFromO2NArr(epsOnVals,old2NewPtr,newNbOfNodes,arr,"Node"); +} + +/*! + * Nothing to do it's not a bug. + */ +void MEDCouplingFieldDiscretizationOnNodes::renumberValuesOnCells(double epsOnVals, const MEDCouplingMesh *mesh, const int *old2New, int newSz, DataArrayDouble *arr) const +{ +} + +/*! + * Nothing to do it's not a bug. + */ +void MEDCouplingFieldDiscretizationOnNodes::renumberValuesOnCellsR(const MEDCouplingMesh *mesh, const int *new2old, int newSz, DataArrayDouble *arr) const +{ +} + +void MEDCouplingFieldDiscretizationOnNodes::getValueOnPos(const DataArrayDouble *arr, const MEDCouplingMesh *mesh, int i, int j, int k, double *res) const +{ + const MEDCouplingCMesh *meshC=dynamic_cast<const MEDCouplingCMesh *>(mesh); + if(!meshC) + throw INTERP_KERNEL::Exception("OnNodes::getValueOnPos(i,j,k) is only accessible for structured meshes !"); + int id=meshC->getNodeIdFromPos(i,j,k); + arr->getTuple(id,res); +} + +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; +} + +std::string MEDCouplingFieldDiscretizationP1::getStringRepr() const +{ + return std::string(REPR); +} + +const char *MEDCouplingFieldDiscretizationP1::getRepr() const +{ + return REPR; +} + +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<const MEDCouplingFieldDiscretizationP1 *>(other); + bool ret=otherC!=0; + if(!ret) + reason="Spatial discrtization of this is ON_NODES, which is not the case of other."; + return ret; +} + +void MEDCouplingFieldDiscretizationP1::checkCompatibilityWithNature(NatureOfField nat) const +{ + if(nat!=ConservativeVolumic) + throw INTERP_KERNEL::Exception("Invalid nature for P1 field : expected ConservativeVolumic !"); +} + +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 !"); + INTERP_KERNEL::NormalizedCellType type=mesh->getTypeOfCell(id); + if(type!=INTERP_KERNEL::NORM_SEG2 && type!=INTERP_KERNEL::NORM_TRI3 && type!=INTERP_KERNEL::NORM_TETRA4) + throw INTERP_KERNEL::Exception("P1 getValueOn is not specified for not simplex cells !"); + getValueInCell(mesh,id,arr,loc,res); +} + +/*! + * This method localizes a point defined by 'loc' in a cell with id 'cellId' into mesh 'mesh'. + * The result is put into res expected to be of size at least arr->getNumberOfComponents() + */ +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<int> conn; + std::vector<double> coo; + mesh->getNodeIdsOfCell(cellId,conn); + for(std::vector<int>::const_iterator iter=conn.begin();iter!=conn.end();iter++) + mesh->getCoordinatesOfNode(*iter,coo); + int spaceDim=mesh->getSpaceDimension(); + std::size_t nbOfNodes=conn.size(); + std::vector<const double *> vec(nbOfNodes); + for(std::size_t i=0;i<nbOfNodes;i++) + vec[i]=&coo[i*spaceDim]; + INTERP_KERNEL::AutoPtr<double> tmp=new double[nbOfNodes]; + INTERP_KERNEL::barycentric_coords(vec,loc,tmp); + int sz=arr->getNumberOfComponents(); + INTERP_KERNEL::AutoPtr<double> tmp2=new double[sz]; + std::fill(res,res+sz,0.); + for(std::size_t i=0;i<nbOfNodes;i++) + { + arr->getTuple(conn[i],(double *)tmp2); + std::transform((double *)tmp2,((double *)tmp2)+sz,(double *)tmp2,std::bind2nd(std::multiplies<double>(),tmp[i])); + std::transform(res,res+sz,(double *)tmp2,res,std::plus<double>()); + } +} + +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 !"); + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> eltsArr,eltsIndexArr; + mesh->getCellsContainingPoints(loc,nbOfPoints,_precision,eltsArr,eltsIndexArr); + const int *elts(eltsArr->begin()),*eltsIndex(eltsIndexArr->begin()); + int spaceDim=mesh->getSpaceDimension(); + int nbOfComponents=arr->getNumberOfComponents(); + MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New(); + ret->alloc(nbOfPoints,nbOfComponents); + double *ptToFill=ret->getPointer(); + for(int i=0;i<nbOfPoints;i++) + if(eltsIndex[i+1]-eltsIndex[i]>=1) + getValueInCell(mesh,elts[eltsIndex[i]],arr,loc+i*spaceDim,ptToFill+i*nbOfComponents); + else + { + std::ostringstream oss; oss << "Point #" << i << " with coordinates : ("; + std::copy(loc+i*spaceDim,loc+(i+1)*spaceDim,std::ostream_iterator<double>(oss,", ")); + oss << ") detected outside mesh : unable to apply P1::getValueOnMulti ! "; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + return ret.retn(); +} + +void MEDCouplingFieldDiscretizationP1::reprQuickOverview(std::ostream& stream) const +{ + stream << "P1 spatial discretization."; +} + +MEDCouplingFieldDiscretizationPerCell::MEDCouplingFieldDiscretizationPerCell():_discr_per_cell(0) +{ +} + +MEDCouplingFieldDiscretizationPerCell::~MEDCouplingFieldDiscretizationPerCell() +{ + if(_discr_per_cell) + _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; + if(arr) + { + if(startCellIds==0 && endCellIds==0) + _discr_per_cell=arr->deepCpy(); + else + _discr_per_cell=arr->selectByTupleIdSafe(startCellIds,endCellIds); + } +} + +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); +} + +std::size_t MEDCouplingFieldDiscretizationPerCell::getHeapMemorySizeWithoutChildren() const +{ + std::size_t ret(MEDCouplingFieldDiscretization::getHeapMemorySizeWithoutChildren()); + return ret; +} + +std::vector<const BigMemoryObject *> MEDCouplingFieldDiscretizationPerCell::getDirectChildrenWithNull() const +{ + std::vector<const BigMemoryObject *> ret(MEDCouplingFieldDiscretization::getDirectChildrenWithNull()); + ret.push_back(_discr_per_cell); + return ret; +} + +void MEDCouplingFieldDiscretizationPerCell::checkCoherencyBetween(const MEDCouplingMesh *mesh, const DataArray *da) const +{ + 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 !"); +} + +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<const MEDCouplingFieldDiscretizationPerCell *>(other); + if(!otherC) + { + reason="Spatial discretization of this is ON_GAUSS, which is not the case of other."; + return false; + } + if(_discr_per_cell==0) + return otherC->_discr_per_cell==0; + if(otherC->_discr_per_cell==0) + return false; + bool ret=_discr_per_cell->isEqualIfNotWhy(*otherC->_discr_per_cell,reason); + if(!ret) + reason.insert(0,"Field discretization per cell DataArrayInt given the discid per cell :"); + return ret; +} + +bool MEDCouplingFieldDiscretizationPerCell::isEqualWithoutConsideringStr(const MEDCouplingFieldDiscretization *other, double eps) const +{ + const MEDCouplingFieldDiscretizationPerCell *otherC=dynamic_cast<const MEDCouplingFieldDiscretizationPerCell *>(other); + if(!otherC) + return false; + if(_discr_per_cell==0) + return otherC->_discr_per_cell==0; + if(otherC->_discr_per_cell==0) + return false; + return _discr_per_cell->isEqualWithoutConsideringStr(*otherC->_discr_per_cell); +} + +/*! + * This method is typically the first step of renumbering. The impact on _discr_per_cell is necessary here. + * virtualy by this method. + */ +void MEDCouplingFieldDiscretizationPerCell::renumberCells(const int *old2NewBg, bool check) +{ + int nbCells=_discr_per_cell->getNumberOfTuples(); + const int *array=old2NewBg; + if(check) + array=DataArrayInt::CheckAndPreparePermutation(old2NewBg,old2NewBg+nbCells); + // + DataArrayInt *dpc=_discr_per_cell->renumber(array); + _discr_per_cell->decrRef(); + _discr_per_cell=dpc; + // + if(check) + free(const_cast<int *>(array)); +} + +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=mesh->getNumberOfCells(); + _discr_per_cell->alloc(nbTuples,1); + int *ptr=_discr_per_cell->getPointer(); + std::fill(ptr,ptr+nbTuples,DFT_INVALID_LOCID_VALUE); + } +} + +void MEDCouplingFieldDiscretizationPerCell::checkNoOrphanCells() const +{ + if(!_discr_per_cell) + throw INTERP_KERNEL::Exception("MEDCouplingFieldDiscretizationPerCell::checkNoOrphanCells : no discretization defined !"); + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> test=_discr_per_cell->getIdsEqual(DFT_INVALID_LOCID_VALUE); + if(test->getNumberOfTuples()!=0) + 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<DataArrayInt *> MEDCouplingFieldDiscretizationPerCell::splitIntoSingleGaussDicrPerCellType(std::vector<int>& locIds) const +{ + 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) +{ + if(adids!=_discr_per_cell) + { + if(_discr_per_cell) + _discr_per_cell->decrRef(); + _discr_per_cell=const_cast<DataArrayInt *>(adids); + if(_discr_per_cell) + _discr_per_cell->incrRef(); + declareAsNew(); + } +} + +MEDCouplingFieldDiscretizationGauss::MEDCouplingFieldDiscretizationGauss() +{ +} + +MEDCouplingFieldDiscretizationGauss::MEDCouplingFieldDiscretizationGauss(const MEDCouplingFieldDiscretizationGauss& other, const int *startCellIds, const int *endCellIds):MEDCouplingFieldDiscretizationPerCell(other,startCellIds,endCellIds),_loc(other._loc) +{ +} + +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; +} + +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<const MEDCouplingFieldDiscretizationGauss *>(other); + if(!otherC) + { + reason="Spatial discrtization of this is ON_GAUSS, which is not the case of other."; + return false; + } + if(!MEDCouplingFieldDiscretizationPerCell::isEqualIfNotWhy(other,eps,reason)) + return false; + if(_loc.size()!=otherC->_loc.size()) + { + reason="Gauss spatial discretization : localization sizes differ"; + return false; + } + std::size_t sz=_loc.size(); + for(std::size_t i=0;i<sz;i++) + if(!_loc[i].isEqual(otherC->_loc[i],eps)) + { + std::ostringstream oss; oss << "Gauss spatial discretization : Localization #" << i << " differ from this to other."; + reason=oss.str(); + return false; + } + return true; +} + +bool MEDCouplingFieldDiscretizationGauss::isEqualWithoutConsideringStr(const MEDCouplingFieldDiscretization *other, double eps) const +{ + const MEDCouplingFieldDiscretizationGauss *otherC=dynamic_cast<const MEDCouplingFieldDiscretizationGauss *>(other); + if(!otherC) + return false; + if(!MEDCouplingFieldDiscretizationPerCell::isEqualWithoutConsideringStr(other,eps)) + return false; + if(_loc.size()!=otherC->_loc.size()) + return false; + std::size_t sz=_loc.size(); + for(std::size_t i=0;i<sz;i++) + if(!_loc[i].isEqual(otherC->_loc[i],eps)) + return false; + 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); +} + +MEDCouplingFieldDiscretization *MEDCouplingFieldDiscretizationGauss::clonePart(const int *startCellIds, const int *endCellIds) const +{ + 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; + if(_discr_per_cell) + { + if(_discr_per_cell->isAllocated()) + { + oss << "Discretization per cell : "; + std::copy(_discr_per_cell->begin(),_discr_per_cell->end(),std::ostream_iterator<int>(oss,", ")); + oss << std::endl; + } + } + oss << "Presence of " << _loc.size() << " localizations." << std::endl; + int i=0; + for(std::vector<MEDCouplingGaussLocalization>::const_iterator it=_loc.begin();it!=_loc.end();it++,i++) + { + oss << "+++++ Localization #" << i << " +++++" << std::endl; + oss << (*it).getStringRepr(); + oss << "++++++++++" << std::endl; + } + return oss.str(); +} + +std::size_t MEDCouplingFieldDiscretizationGauss::getHeapMemorySizeWithoutChildren() const +{ + std::size_t ret(MEDCouplingFieldDiscretizationPerCell::getHeapMemorySizeWithoutChildren()); + ret+=_loc.capacity()*sizeof(MEDCouplingGaussLocalization); + for(std::vector<MEDCouplingGaussLocalization>::const_iterator it=_loc.begin();it!=_loc.end();it++) + ret+=(*it).getMemorySize(); + return ret; +} + +const char *MEDCouplingFieldDiscretizationGauss::getRepr() const +{ + return REPR; +} + +/*! + * This method returns the number of tuples regarding exclusively the input code \b without \b using \b a \b mesh \b in \b input. + * The input code coherency is also checked regarding spatial discretization of \a this. + * If an incoherency is detected, an exception will be thrown. If the input code is coherent, the number of tuples expected is returned. + * The number of tuples expected is equal to those to have a valid field lying on \a this and having a mesh fitting perfectly the input code (geometric type distribution). + */ +int MEDCouplingFieldDiscretizationGauss::getNumberOfTuplesExpectedRegardingCode(const std::vector<int>& code, const std::vector<const DataArrayInt *>& idsPerType) const +{ + if(!_discr_per_cell || !_discr_per_cell->isAllocated() || _discr_per_cell->getNumberOfComponents()!=1) + throw INTERP_KERNEL::Exception("MEDCouplingFieldDiscretizationGauss::getNumberOfTuplesExpectedRegardingCode"); + if(code.size()%3!=0) + throw INTERP_KERNEL::Exception("MEDCouplingFieldDiscretizationGauss::getNumberOfTuplesExpectedRegardingCode : invalid input code !"); + int nbOfSplit=(int)idsPerType.size(); + int nbOfTypes=(int)code.size()/3; + int ret=0; + for(int i=0;i<nbOfTypes;i++) + { + int nbOfEltInChunk=code[3*i+1]; + if(nbOfEltInChunk<0) + throw INTERP_KERNEL::Exception("MEDCouplingFieldDiscretizationGauss::getNumberOfTuplesExpectedRegardingCode : invalid input code ! presence of negative value in a type !"); + int pos=code[3*i+2]; + if(pos!=-1) + { + if(pos<0 || pos>=nbOfSplit) + { + std::ostringstream oss; oss << "MEDCouplingFieldDiscretizationGauss::getNumberOfTuplesExpectedRegardingCode : input code points to pos " << pos << " in typeid " << i << " ! Should be in [0," << nbOfSplit << ") !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + const DataArrayInt *ids(idsPerType[pos]); + if(!ids || !ids->isAllocated() || ids->getNumberOfComponents()!=1 || ids->getNumberOfTuples()!=nbOfEltInChunk || ids->getMinValueInArray()<0) + { + std::ostringstream oss; oss << "MEDCouplingFieldDiscretizationGauss::getNumberOfTuplesExpectedRegardingCode : input pfl chunck at pos " << pos << " should have " << i << " tuples and one component and with ids all >=0 !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + } + ret+=nbOfEltInChunk; + } + if(ret!=_discr_per_cell->getNumberOfTuples()) + { + std::ostringstream oss; oss << "MEDCouplingFieldDiscretizationGauss::getNumberOfTuplesExpectedRegardingCode : input code points to " << ret << " cells whereas discretization percell array lgth is " << _discr_per_cell->getNumberOfTuples() << " !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + return getNumberOfTuples(0);//0 is not an error ! It is to be sure that input mesh is not used +} + +int MEDCouplingFieldDiscretizationGauss::getNumberOfTuples(const MEDCouplingMesh *) const +{ + 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(); + int maxSz=(int)_loc.size(); + for(const int *w=dcPtr;w!=dcPtr+nbOfTuples;w++) + { + if(*w>=0 && *w<maxSz) + ret+=_loc[*w].getNumberOfGaussPt(); + else + { + std::ostringstream oss; oss << "MEDCouplingFieldDiscretizationGauss::getNumberOfTuples : At cell #" << std::distance(dcPtr,w) << " localization id is " << *w << " should be in [0," << maxSz << ") !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + } + return ret; +} + +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<DataArrayInt> ret=DataArrayInt::New(); + ret->alloc(nbOfTuples+1,1); + int *retPtr=ret->getPointer(); + const int *start=_discr_per_cell->getConstPointer(); + if(_discr_per_cell->getNumberOfTuples()!=nbOfTuples) + throw INTERP_KERNEL::Exception("MEDCouplingFieldDiscretizationGauss::getOffsetArr : mismatch between the mesh and the discretization ids array length !"); + int maxPossible=(int)_loc.size(); + retPtr[0]=0; + for(int i=0;i<nbOfTuples;i++,start++) + { + if(*start>=0 && *start<maxPossible) + retPtr[i+1]=retPtr[i]+_loc[*start].getNumberOfGaussPt(); + else + { + std::ostringstream oss; oss << "MEDCouplingFieldDiscretizationGauss::getOffsetArr : At position #" << i << " the locid = " << *start << " whereas it should be in [0," << maxPossible << ") !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + } + return ret.retn(); +} + +void MEDCouplingFieldDiscretizationGauss::renumberArraysForCell(const MEDCouplingMesh *mesh, const std::vector<DataArray *>& arrays, + const int *old2NewBg, bool check) +{ + if(!mesh) + throw INTERP_KERNEL::Exception("MEDCouplingFieldDiscretizationGauss::renumberArraysForCell : NULL input mesh !"); + const int *array=old2NewBg; + if(check) + array=DataArrayInt::CheckAndPreparePermutation(old2NewBg,old2NewBg+mesh->getNumberOfCells()); + int nbOfCells=_discr_per_cell->getNumberOfTuples(); + int nbOfTuples=getNumberOfTuples(0); + const int *dcPtr=_discr_per_cell->getConstPointer(); + int *array2=new int[nbOfTuples];//stores the final conversion array old2New to give to arrays in renumberInPlace. + int *array3=new int[nbOfCells];//store for each cell in present dcp array (already renumbered) the offset needed by each cell in new numbering. + array3[0]=0; + for(int i=1;i<nbOfCells;i++) + array3[i]=array3[i-1]+_loc[dcPtr[i-1]].getNumberOfGaussPt(); + int j=0; + for(int i=0;i<nbOfCells;i++) + { + int nbOfGaussPt=_loc[dcPtr[array[i]]].getNumberOfGaussPt(); + for(int k=0;k<nbOfGaussPt;k++,j++) + array2[j]=array3[array[i]]+k; + } + delete [] array3; + for(std::vector<DataArray *>::const_iterator it=arrays.begin();it!=arrays.end();it++) + if(*it) + (*it)->renumberInPlace(array2); + delete [] array2; + if(check) + free(const_cast<int*>(array)); +} + +DataArrayDouble *MEDCouplingFieldDiscretizationGauss::getLocalizationOfDiscValues(const MEDCouplingMesh *mesh) const +{ + if(!mesh) + throw INTERP_KERNEL::Exception("MEDCouplingFieldDiscretizationGauss::getLocalizationOfDiscValues : NULL input mesh !"); + checkNoOrphanCells(); + MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> umesh=mesh->buildUnstructured();//in general do nothing + int nbOfTuples=getNumberOfTuples(mesh); + MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New(); + int spaceDim=mesh->getSpaceDimension(); + ret->alloc(nbOfTuples,spaceDim); + std::vector< int > locIds; + std::vector<DataArrayInt *> parts=splitIntoSingleGaussDicrPerCellType(locIds); + std::vector< MEDCouplingAutoRefCountObjectPtr<DataArrayInt> > parts2(parts.size()); + std::copy(parts.begin(),parts.end(),parts2.begin()); + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> offsets=buildNbOfGaussPointPerCellField(); + offsets->computeOffsets(); + const int *ptrOffsets=offsets->getConstPointer(); + const double *coords=umesh->getCoords()->getConstPointer(); + const int *connI=umesh->getNodalConnectivityIndex()->getConstPointer(); + const int *conn=umesh->getNodalConnectivity()->getConstPointer(); + double *valsToFill=ret->getPointer(); + for(std::size_t i=0;i<parts2.size();i++) + { + INTERP_KERNEL::GaussCoords calculator; + // + const MEDCouplingGaussLocalization& cli=_loc[locIds[i]];//curLocInfo + INTERP_KERNEL::NormalizedCellType typ=cli.getType(); + const std::vector<double>& wg=cli.getWeights(); + calculator.addGaussInfo(typ,INTERP_KERNEL::CellModel::GetCellModel(typ).getDimension(), + &cli.getGaussCoords()[0],(int)wg.size(),&cli.getRefCoords()[0], + INTERP_KERNEL::CellModel::GetCellModel(typ).getNumberOfNodes()); + // + int nbt=parts2[i]->getNumberOfTuples(); + for(const int *w=parts2[i]->getConstPointer();w!=parts2[i]->getConstPointer()+nbt;w++) + calculator.calculateCoords(cli.getType(),coords,spaceDim,conn+connI[*w]+1,valsToFill+spaceDim*(ptrOffsets[*w])); + } + ret->copyStringInfoFrom(*umesh->getCoords()); + return ret.retn(); +} + +void MEDCouplingFieldDiscretizationGauss::computeMeshRestrictionFromTupleIds(const MEDCouplingMesh *mesh, const int *tupleIdsBg, const int *tupleIdsEnd, + DataArrayInt *&cellRestriction, DataArrayInt *&trueTupleRestriction) const +{ + if(!mesh) + throw INTERP_KERNEL::Exception("MEDCouplingFieldDiscretizationGauss::computeMeshRestrictionFromTupleIds : NULL input mesh !"); + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> tmp=DataArrayInt::New(); tmp->alloc((int)std::distance(tupleIdsBg,tupleIdsEnd),1); + std::copy(tupleIdsBg,tupleIdsEnd,tmp->getPointer()); + tmp->sort(true); + tmp=tmp->buildUnique(); + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> nbOfNodesPerCell=buildNbOfGaussPointPerCellField(); + nbOfNodesPerCell->computeOffsets2(); + nbOfNodesPerCell->searchRangesInListOfIds(tmp,cellRestriction,trueTupleRestriction); +} + +/*! + * Empty : not a bug + */ +void MEDCouplingFieldDiscretizationGauss::checkCompatibilityWithNature(NatureOfField nat) const +{ +} + +void MEDCouplingFieldDiscretizationGauss::getTinySerializationIntInformation(std::vector<int>& tinyInfo) const +{ + int val=-1; + if(_discr_per_cell) + val=_discr_per_cell->getNumberOfTuples(); + tinyInfo.push_back(val); + tinyInfo.push_back((int)_loc.size()); + if(_loc.empty()) + tinyInfo.push_back(-1); + else + tinyInfo.push_back(_loc[0].getDimension()); + for(std::vector<MEDCouplingGaussLocalization>::const_iterator iter=_loc.begin();iter!=_loc.end();iter++) + (*iter).pushTinySerializationIntInfo(tinyInfo); +} + +void MEDCouplingFieldDiscretizationGauss::getTinySerializationDbleInformation(std::vector<double>& tinyInfo) const +{ + for(std::vector<MEDCouplingGaussLocalization>::const_iterator iter=_loc.begin();iter!=_loc.end();iter++) + (*iter).pushTinySerializationDblInfo(tinyInfo); +} + +void MEDCouplingFieldDiscretizationGauss::getSerializationIntArray(DataArrayInt *& arr) const +{ + arr=0; + if(_discr_per_cell) + arr=_discr_per_cell; +} + +void MEDCouplingFieldDiscretizationGauss::resizeForUnserialization(const std::vector<int>& tinyInfo, DataArrayInt *& arr) +{ + int val=tinyInfo[0]; + if(val>=0) + { + _discr_per_cell=DataArrayInt::New(); + _discr_per_cell->alloc(val,1); + } + else + _discr_per_cell=0; + arr=_discr_per_cell; + commonUnserialization(tinyInfo); +} + +void MEDCouplingFieldDiscretizationGauss::checkForUnserialization(const std::vector<int>& tinyInfo, const DataArrayInt *arr) +{ + static const char MSG[]="MEDCouplingFieldDiscretizationGauss::checkForUnserialization : expect to have one not null DataArrayInt !"; + int val=tinyInfo[0]; + if(val>=0) + { + if(!arr) + throw INTERP_KERNEL::Exception(MSG); + arr->checkNbOfTuplesAndComp(val,1,MSG); + _discr_per_cell=const_cast<DataArrayInt *>(arr); + _discr_per_cell->incrRef(); + } + else + _discr_per_cell=0; + commonUnserialization(tinyInfo); +} + +void MEDCouplingFieldDiscretizationGauss::finishUnserialization(const std::vector<double>& tinyInfo) +{ + double *tmp=new double[tinyInfo.size()]; + std::copy(tinyInfo.begin(),tinyInfo.end(),tmp); + const double *work=tmp; + for(std::vector<MEDCouplingGaussLocalization>::iterator iter=_loc.begin();iter!=_loc.end();iter++) + work=(*iter).fillWithValues(work); + delete [] tmp; +} + +double MEDCouplingFieldDiscretizationGauss::getIJK(const MEDCouplingMesh *mesh, const DataArrayDouble *da, int cellId, int nodeIdInCell, int compoId) const +{ + int offset=getOffsetOfCell(cellId); + return da->getIJ(offset+nodeIdInCell,compoId); +} + +void MEDCouplingFieldDiscretizationGauss::checkCoherencyBetween(const MEDCouplingMesh *mesh, const DataArray *da) const +{ + if(!mesh || !da) + throw INTERP_KERNEL::Exception("MEDCouplingFieldDiscretizationGauss::checkCoherencyBetween : NULL input mesh or DataArray !"); + MEDCouplingFieldDiscretizationPerCell::checkCoherencyBetween(mesh,da); + for(std::vector<MEDCouplingGaussLocalization>::const_iterator iter=_loc.begin();iter!=_loc.end();iter++) + (*iter).checkCoherency(); + int nbOfDesc=(int)_loc.size(); + int nbOfCells=mesh->getNumberOfCells(); + const int *dc=_discr_per_cell->getConstPointer(); + for(int i=0;i<nbOfCells;i++) + { + if(dc[i]>=nbOfDesc) + { + std::ostringstream oss; oss << "Cell # " << i << " of mesh \"" << mesh->getName() << "\" has an undefined gauss location ! Should never happend !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + if(dc[i]<0) + { + std::ostringstream oss; oss << "Cell # " << i << " of mesh \"" << mesh->getName() << "\" has no gauss location !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + if(mesh->getTypeOfCell(i)!=_loc[dc[i]].getType()) + { + std::ostringstream oss; oss << "Types of mesh and gauss location mismatch for cell # " << i; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + } + int nbOfTuples=getNumberOfTuples(mesh); + if(nbOfTuples!=da->getNumberOfTuples()) + { + std::ostringstream oss; oss << "Invalid number of tuples in the array : expecting " << nbOfTuples << " !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } +} + +MEDCouplingFieldDouble *MEDCouplingFieldDiscretizationGauss::getMeasureField(const MEDCouplingMesh *mesh, bool isAbs) const +{ + if(!mesh) + throw INTERP_KERNEL::Exception("MEDCouplingFieldDiscretizationGauss::getMeasureField : mesh instance specified is NULL !"); + MEDCouplingAutoRefCountObjectPtr<MEDCouplingFieldDouble> vol=mesh->getMeasureField(isAbs); + const double *volPtr=vol->getArray()->begin(); + MEDCouplingAutoRefCountObjectPtr<MEDCouplingFieldDouble> ret=MEDCouplingFieldDouble::New(ON_GAUSS_PT); + ret->setMesh(mesh); + ret->setDiscretization(const_cast<MEDCouplingFieldDiscretizationGauss *>(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<DataArrayInt> offset=getOffsetArr(mesh); + MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> 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<int> locIds; + std::vector<DataArrayInt *> ids=splitIntoSingleGaussDicrPerCellType(locIds); + std::vector< MEDCouplingAutoRefCountObjectPtr<DataArrayInt> > ids2(ids.size()); std::copy(ids.begin(),ids.end(),ids2.begin()); + for(std::size_t i=0;i<locIds.size();i++) + { + const DataArrayInt *curIds=ids[i]; + int locId=locIds[i]; + if(locId>=0 && locId<maxGaussLoc) + { + const MEDCouplingGaussLocalization& loc=_loc[locId]; + int nbOfGaussPt=loc.getNumberOfGaussPt(); + INTERP_KERNEL::AutoPtr<double> 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<double>(),1./sum)); + for(const int *cellId=curIds->begin();cellId!=curIds->end();cellId++) + for(int j=0;j<nbOfGaussPt;j++) + arrPtr[offsetPtr[*cellId]+j]=weights[j]*volPtr[*cellId]; + } + else + { + std::ostringstream oss; oss << "MEDCouplingFieldDiscretizationGauss::getMeasureField : Presence of localization id " << locId << " in cell #" << curIds->getIJ(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 +{ + throw INTERP_KERNEL::Exception("Not implemented yet !"); +} + +void MEDCouplingFieldDiscretizationGauss::getValueOnPos(const DataArrayDouble *arr, const MEDCouplingMesh *mesh, int i, int j, int k, double *res) const +{ + throw INTERP_KERNEL::Exception("getValueOnPos(i,j,k) : Not applyable for Gauss points !"); +} + +DataArrayDouble *MEDCouplingFieldDiscretizationGauss::getValueOnMulti(const DataArrayDouble *arr, const MEDCouplingMesh *mesh, const double *loc, int nbOfPoints) const +{ + throw INTERP_KERNEL::Exception("getValueOnMulti : Not implemented yet for gauss points !"); +} + +MEDCouplingMesh *MEDCouplingFieldDiscretizationGauss::buildSubMeshData(const MEDCouplingMesh *mesh, const int *start, const int *end, DataArrayInt *&di) const +{ + if(!mesh) + throw INTERP_KERNEL::Exception("MEDCouplingFieldDiscretizationGauss::buildSubMeshData : NULL input mesh !"); + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> diSafe=computeTupleIdsToSelectFromCellIds(mesh,start,end); + MEDCouplingAutoRefCountObjectPtr<MEDCouplingMesh> 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<nbOfTuples;i++,w++) + { + if(*w!=DFT_INVALID_LOCID_VALUE) + { + if(*w>=0 && *w<nbMaxOfLocId) + { + int delta=_loc[*w].getNumberOfGaussPt(); + if(i<beginCellIds) + beginOut+=delta; + endOut+=delta; + if(i>=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<MEDCouplingMesh> 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 MEDCouplingFieldDiscretizationGauss::buildSubMeshData to return parameter \b di. + * + * \return a newly allocated array containing ids to select into the DataArrayDouble of the field. + * + */ +DataArrayInt *MEDCouplingFieldDiscretizationGauss::computeTupleIdsToSelectFromCellIds(const MEDCouplingMesh *mesh, const int *startCellIds, const int *endCellIds) const +{ + if(!mesh) + throw INTERP_KERNEL::Exception("MEDCouplingFieldDiscretizationGauss::computeTupleIdsToSelectFromCellIds : null mesh !"); + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> 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 !"); + nbOfNodesPerCell->computeOffsets2(); + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> sel=DataArrayInt::New(); sel->useArray(startCellIds,false,CPP_DEALLOC,(int)std::distance(startCellIds,endCellIds),1); + return sel->buildExplicitArrByRanges(nbOfNodesPerCell); +} + +/*! + * No implementation needed ! + */ +void MEDCouplingFieldDiscretizationGauss::renumberValuesOnNodes(double , const int *, int newNbOfNodes, DataArrayDouble *) const +{ +} + +void MEDCouplingFieldDiscretizationGauss::renumberValuesOnCells(double epsOnVals, const MEDCouplingMesh *mesh, const int *old2New, int newSz, DataArrayDouble *arr) const +{ + throw INTERP_KERNEL::Exception("Not implemented yet !"); +} + +void MEDCouplingFieldDiscretizationGauss::renumberValuesOnCellsR(const MEDCouplingMesh *mesh, const int *new2old, int newSz, DataArrayDouble *arr) const +{ + 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 *mesh, INTERP_KERNEL::NormalizedCellType type, const std::vector<double>& refCoo, + const std::vector<double>& gsCoo, const std::vector<double>& wg) +{ + 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()!=mesh->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(mesh); + int id=(int)_loc.size(); + MEDCouplingGaussLocalization elt(type,refCoo,gsCoo,wg); + _loc.push_back(elt); + int *ptr=_discr_per_cell->getPointer(); + int nbCells=mesh->getNumberOfCells(); + for(int i=0;i<nbCells;i++) + if(mesh->getTypeOfCell(i)==type) + ptr[i]=id; + zipGaussLocalizations(); +} + +void MEDCouplingFieldDiscretizationGauss::setGaussLocalizationOnCells(const MEDCouplingMesh *mesh, const int *begin, const int *end, const std::vector<double>& refCoo, + const std::vector<double>& gsCoo, const std::vector<double>& wg) +{ + 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=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(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()); + } + } + // + for(const int *w2=begin;w2!=end;w2++) + ptr[*w2]=id; + // + _loc.push_back(elt); + zipGaussLocalizations(); +} + +void MEDCouplingFieldDiscretizationGauss::clearGaussLocalizations() +{ + if(_discr_per_cell) + { + _discr_per_cell->decrRef(); + _discr_per_cell=0; + } + _loc.clear(); +} + +void MEDCouplingFieldDiscretizationGauss::setGaussLocalization(int locId, const MEDCouplingGaussLocalization& loc) +{ + 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) +{ + 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) +{ + checkLocalizationId(locId); + return _loc[locId]; +} + +int MEDCouplingFieldDiscretizationGauss::getNbOfGaussLocalization() const +{ + return (int)_loc.size(); +} + +int MEDCouplingFieldDiscretizationGauss::getGaussLocalizationIdOfOneCell(int cellId) const +{ + if(!_discr_per_cell) + throw INTERP_KERNEL::Exception("No Gauss localization still set !"); + int locId=_discr_per_cell->begin()[cellId]; + if(locId<0) + throw INTERP_KERNEL::Exception("No Gauss localization set for the specified cell !"); + return locId; +} + +int MEDCouplingFieldDiscretizationGauss::getGaussLocalizationIdOfOneType(INTERP_KERNEL::NormalizedCellType type) const +{ + std::set<int> ret=getGaussLocalizationIdsOfOneType(type); + if(ret.empty()) + throw INTERP_KERNEL::Exception("No gauss discretization found for the specified type !"); + if(ret.size()>1) + throw INTERP_KERNEL::Exception("Several gauss discretizations have been found for the specified type !"); + return *ret.begin(); +} + +std::set<int> MEDCouplingFieldDiscretizationGauss::getGaussLocalizationIdsOfOneType(INTERP_KERNEL::NormalizedCellType type) const +{ + if(!_discr_per_cell) + throw INTERP_KERNEL::Exception("No Gauss localization still set !"); + std::set<int> ret; + int id=0; + for(std::vector<MEDCouplingGaussLocalization>::const_iterator iter=_loc.begin();iter!=_loc.end();iter++,id++) + if((*iter).getType()==type) + ret.insert(id); + return ret; +} + +void MEDCouplingFieldDiscretizationGauss::getCellIdsHavingGaussLocalization(int locId, std::vector<int>& cellIds) const +{ + if(locId<0 || locId>=(int)_loc.size()) + throw INTERP_KERNEL::Exception("Invalid locId given : must be in range [0:getNbOfGaussLocalization()) !"); + int nbOfTuples=_discr_per_cell->getNumberOfTuples(); + const int *ptr=_discr_per_cell->getConstPointer(); + for(int i=0;i<nbOfTuples;i++) + if(ptr[i]==locId) + cellIds.push_back(i); +} + +const MEDCouplingGaussLocalization& MEDCouplingFieldDiscretizationGauss::getGaussLocalization(int locId) const +{ + checkLocalizationId(locId); + return _loc[locId]; +} + +void MEDCouplingFieldDiscretizationGauss::checkLocalizationId(int locId) const +{ + if(locId<0 || locId>=(int)_loc.size()) + throw INTERP_KERNEL::Exception("Invalid locId given : must be in range [0:getNbOfGaussLocalization()) !"); +} + +int MEDCouplingFieldDiscretizationGauss::getOffsetOfCell(int cellId) const +{ + int ret=0; + const int *start=_discr_per_cell->getConstPointer(); + for(const int *w=start;w!=start+cellId;w++) + ret+=_loc[*w].getNumberOfGaussPt(); + return ret; +} + +/*! + * This method do the assumption that there is no orphan cell. If there is an exception is thrown. + * This method makes the assumption too that '_discr_per_cell' is defined. If not an exception is thrown. + * This method returns a newly created array with number of tuples equals to '_discr_per_cell->getNumberOfTuples' and number of components equal to 1. + * The i_th tuple in returned array is the number of gauss point if the corresponding cell. + */ +DataArrayInt *MEDCouplingFieldDiscretizationGauss::buildNbOfGaussPointPerCellField() const +{ + if(!_discr_per_cell) + throw INTERP_KERNEL::Exception("MEDCouplingFieldDiscretizationGauss::buildNbOfGaussPointPerCellField : no discretization array set !"); + int nbOfTuples=_discr_per_cell->getNumberOfTuples(); + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New(); + 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<nbOfTuples;i++,w++) + if(*w!=DFT_INVALID_LOCID_VALUE) + { + if(*w>=0 && *w<nbMaxOfLocId) + valsToFill[i]=_loc[*w].getNumberOfGaussPt(); + else + { + std::ostringstream oss; oss << "MEDCouplingFieldDiscretizationGauss::buildNbOfGaussPointPerCellField : cell #" << i << " has invalid id (" << *w << ") ! Should be in [0," << nbMaxOfLocId << ") !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + } + else + { + 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 +{ + 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 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->begin(); + int nbOfTuples=_discr_per_cell->getNumberOfTuples(); + INTERP_KERNEL::AutoPtr<int> tmp=new int[_loc.size()]; + std::fill((int *)tmp,(int *)tmp+_loc.size(),-2); + for(const int *w=start;w!=start+nbOfTuples;w++) + if(*w>=0) + tmp[*w]=1; + int fid=0; + for(int i=0;i<(int)_loc.size();i++) + if(tmp[i]!=-2) + tmp[i]=fid++; + if(fid==(int)_loc.size()) + return; + // zip needed + int *start2=_discr_per_cell->getPointer(); + for(int *w2=start2;w2!=start2+nbOfTuples;w2++) + if(*w2>=0) + *w2=tmp[*w2]; + std::vector<MEDCouplingGaussLocalization> tmpLoc; + for(int i=0;i<(int)_loc.size();i++) + if(tmp[i]!=-2) + tmpLoc.push_back(_loc[i]); + _loc=tmpLoc; +} + +void MEDCouplingFieldDiscretizationGauss::commonUnserialization(const std::vector<int>& tinyInfo) +{ + int nbOfLoc=tinyInfo[1]; + _loc.clear(); + int dim=tinyInfo[2]; + int delta=-1; + if(nbOfLoc>0) + delta=((int)tinyInfo.size()-3)/nbOfLoc; + for(int i=0;i<nbOfLoc;i++) + { + std::vector<int> tmp(tinyInfo.begin()+3+i*delta,tinyInfo.begin()+3+(i+1)*delta); + MEDCouplingGaussLocalization elt=MEDCouplingGaussLocalization::BuildNewInstanceFromTinyInfo(dim,tmp); + _loc.push_back(elt); + } +} + +MEDCouplingFieldDiscretizationGaussNE::MEDCouplingFieldDiscretizationGaussNE() +{ +} + +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); +} + +std::string MEDCouplingFieldDiscretizationGaussNE::getStringRepr() const +{ + return std::string(REPR); +} + +const char *MEDCouplingFieldDiscretizationGaussNE::getRepr() const +{ + return REPR; +} + +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<const MEDCouplingFieldDiscretizationGaussNE *>(other); + bool ret=otherC!=0; + if(!ret) + reason="Spatial discrtization of this is ON_GAUSS_NE, which is not the case of other."; + return ret; +} + +/*! + * This method returns the number of tuples regarding exclusively the input code \b without \b using \b a \b mesh \b in \b input. + * The input code coherency is also checked regarding spatial discretization of \a this. + * If an incoherency is detected, an exception will be thrown. If the input code is coherent, the number of tuples expected is returned. + * The number of tuples expected is equal to those to have a valid field lying on \a this and having a mesh fitting perfectly the input code (geometric type distribution). + */ +int MEDCouplingFieldDiscretizationGaussNE::getNumberOfTuplesExpectedRegardingCode(const std::vector<int>& code, const std::vector<const DataArrayInt *>& idsPerType) const +{ + if(code.size()%3!=0) + throw INTERP_KERNEL::Exception("MEDCouplingFieldDiscretizationGaussNE::getNumberOfTuplesExpectedRegardingCode : invalid input code !"); + int nbOfSplit=(int)idsPerType.size(); + int nbOfTypes=(int)code.size()/3; + int ret(0); + for(int i=0;i<nbOfTypes;i++) + { + const INTERP_KERNEL::CellModel& cm(INTERP_KERNEL::CellModel::GetCellModel((INTERP_KERNEL::NormalizedCellType)code[3*i])); + if(cm.isDynamic()) + { + std::ostringstream oss; oss << "MEDCouplingFieldDiscretizationGaussNE::getNumberOfTuplesExpectedRegardingCode : At pos #" << i << " the geometric type " << cm.getRepr() << " is dynamic ! There are not managed by GAUSS_NE field discretization !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + int nbOfEltInChunk=code[3*i+1]; + if(nbOfEltInChunk<0) + throw INTERP_KERNEL::Exception("MEDCouplingFieldDiscretizationGaussNE::getNumberOfTuplesExpectedRegardingCode : invalid input code ! presence of negative value in a type !"); + int pos=code[3*i+2]; + if(pos!=-1) + { + if(pos<0 || pos>=nbOfSplit) + { + std::ostringstream oss; oss << "MEDCouplingFieldDiscretizationGaussNE::getNumberOfTuplesExpectedRegardingCode : input code points to pos " << pos << " in typeid " << i << " ! Should be in [0," << nbOfSplit << ") !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + const DataArrayInt *ids(idsPerType[pos]); + if(!ids || !ids->isAllocated() || ids->getNumberOfComponents()!=1 || ids->getNumberOfTuples()!=nbOfEltInChunk || ids->getMinValueInArray()<0) + { + std::ostringstream oss; oss << "MEDCouplingFieldDiscretizationGaussNE::getNumberOfTuplesExpectedRegardingCode : input pfl chunck at pos " << pos << " should have " << i << " tuples and one component and with ids all >=0 !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + } + ret+=nbOfEltInChunk*(int)cm.getNumberOfNodes(); + } + return ret; +} + +int MEDCouplingFieldDiscretizationGaussNE::getNumberOfTuples(const MEDCouplingMesh *mesh) const +{ + if(!mesh) + throw INTERP_KERNEL::Exception("MEDCouplingFieldDiscretizationGaussNE::getNumberOfTuples : NULL input mesh !"); + int ret=0; + int nbOfCells=mesh->getNumberOfCells(); + for(int i=0;i<nbOfCells;i++) + { + INTERP_KERNEL::NormalizedCellType type=mesh->getTypeOfCell(i); + const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(type); + if(cm.isDynamic()) + throw INTERP_KERNEL::Exception("Not implemented yet Gauss node on elements for polygons and polyedrons !"); + ret+=cm.getNumberOfNodes(); + } + return ret; +} + +int MEDCouplingFieldDiscretizationGaussNE::getNumberOfMeshPlaces(const MEDCouplingMesh *mesh) const +{ + if(!mesh) + throw INTERP_KERNEL::Exception("MEDCouplingFieldDiscretizationGaussNE::getNumberOfMeshPlaces : NULL input mesh !"); + return mesh->getNumberOfCells(); +} + +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); + int *retPtr=ret->getPointer(); + retPtr[0]=0; + for(int i=0;i<nbOfTuples;i++) + { + INTERP_KERNEL::NormalizedCellType type=mesh->getTypeOfCell(i); + const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(type); + if(cm.isDynamic()) + throw INTERP_KERNEL::Exception("Not implemented yet Gauss node on elements for polygons and polyedrons !"); + retPtr[i+1]=retPtr[i]+cm.getNumberOfNodes(); + } + return ret; +} + +void MEDCouplingFieldDiscretizationGaussNE::renumberArraysForCell(const MEDCouplingMesh *mesh, const std::vector<DataArray *>& arrays, + const int *old2NewBg, bool check) +{ + if(!mesh) + throw INTERP_KERNEL::Exception("MEDCouplingFieldDiscretizationGaussNE::renumberArraysForCell : NULL input mesh !"); + const int *array=old2NewBg; + if(check) + array=DataArrayInt::CheckAndPreparePermutation(old2NewBg,old2NewBg+mesh->getNumberOfCells()); + int nbOfCells=mesh->getNumberOfCells(); + int nbOfTuples=getNumberOfTuples(mesh); + int *array2=new int[nbOfTuples];//stores the final conversion array old2New to give to arrays in renumberInPlace. + int *array3=new int[nbOfCells];//store for each cell in after renumbering the offset needed by each cell in new numbering. + array3[0]=0; + for(int i=1;i<nbOfCells;i++) + { + INTERP_KERNEL::NormalizedCellType type=mesh->getTypeOfCell((int)std::distance(array,std::find(array,array+nbOfCells,i-1))); + const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(type); + array3[i]=array3[i-1]+cm.getNumberOfNodes(); + } + int j=0; + for(int i=0;i<nbOfCells;i++) + { + INTERP_KERNEL::NormalizedCellType type=mesh->getTypeOfCell(i); + const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(type); + for(int k=0;k<(int)cm.getNumberOfNodes();k++,j++) + array2[j]=array3[array[i]]+k; + } + delete [] array3; + for(std::vector<DataArray *>::const_iterator it=arrays.begin();it!=arrays.end();it++) + if(*it) + (*it)->renumberInPlace(array2); + delete [] array2; + if(check) + free(const_cast<int *>(array)); +} + +DataArrayDouble *MEDCouplingFieldDiscretizationGaussNE::getLocalizationOfDiscValues(const MEDCouplingMesh *mesh) const +{ + if(!mesh) + throw INTERP_KERNEL::Exception("MEDCouplingFieldDiscretizationGaussNE::getLocalizationOfDiscValues : NULL input mesh !"); + MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New(); + MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> 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<nbCells;i++,connI++) + for(const int *w=conn+connI[0]+1;w!=conn+connI[1];w++) + if(*w>=0) + retPtr=std::copy(coords+(*w)*spaceDim,coords+((*w)+1)*spaceDim,retPtr); + return ret.retn(); +} + +/*! + * 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 +{ + 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<MEDCouplingFieldDouble> vol=mesh->getMeasureField(isWAbs); + std::set<INTERP_KERNEL::NormalizedCellType> types=mesh->getAllGeoTypes(); + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> nbOfNodesPerCell=mesh->computeNbOfNodesPerCell(); + nbOfNodesPerCell->computeOffsets2(); + const double *arrPtr=arr->begin(),*volPtr=vol->getArray()->begin(); + for(std::set<INTERP_KERNEL::NormalizedCellType>::const_iterator it=types.begin();it!=types.end();it++) + { + std::size_t wArrSz=-1; + const double *wArr=GetWeightArrayFromGeometricType(*it,wArrSz); + INTERP_KERNEL::AutoPtr<double> wArr2=new double[wArrSz]; + double sum=std::accumulate(wArr,wArr+wArrSz,0.); + std::transform(wArr,wArr+wArrSz,(double *)wArr2,std::bind2nd(std::multiplies<double>(),1./sum)); + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ids=mesh->giveCellsWithType(*it); + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ids2=ids->buildExplicitArrByRanges(nbOfNodesPerCell); + const int *ptIds2=ids2->begin(),*ptIds=ids->begin(); + int nbOfCellsWithCurGeoType=ids->getNumberOfTuples(); + for(int i=0;i<nbOfCellsWithCurGeoType;i++,ptIds++,ptIds2+=wArrSz) + { + for(int k=0;k<nbOfCompo;k++) + { + double tmp=0.; + for(std::size_t j=0;j<wArrSz;j++) + tmp+=arrPtr[nbOfCompo*ptIds2[j]+k]*wArr2[j]; + res[k]+=tmp*volPtr[*ptIds]; + } + } + } +} + +const double *MEDCouplingFieldDiscretizationGaussNE::GetWeightArrayFromGeometricType(INTERP_KERNEL::NormalizedCellType geoType, std::size_t& lgth) +{ + switch(geoType) + { + case INTERP_KERNEL::NORM_POINT1: + lgth=(int)sizeof(FGP_POINT1)/sizeof(double); + return FGP_POINT1; + case INTERP_KERNEL::NORM_SEG2: + lgth=(int)sizeof(FGP_SEG2)/sizeof(double); + return FGP_SEG2; + case INTERP_KERNEL::NORM_SEG3: + lgth=(int)sizeof(FGP_SEG3)/sizeof(double); + return FGP_SEG3; + case INTERP_KERNEL::NORM_SEG4: + lgth=(int)sizeof(FGP_SEG4)/sizeof(double); + return FGP_SEG4; + case INTERP_KERNEL::NORM_TRI3: + lgth=(int)sizeof(FGP_TRI3)/sizeof(double); + return FGP_TRI3; + case INTERP_KERNEL::NORM_TRI6: + lgth=(int)sizeof(FGP_TRI6)/sizeof(double); + return FGP_TRI6; + case INTERP_KERNEL::NORM_TRI7: + lgth=(int)sizeof(FGP_TRI7)/sizeof(double); + return FGP_TRI7; + case INTERP_KERNEL::NORM_QUAD4: + lgth=(int)sizeof(FGP_QUAD4)/sizeof(double); + return FGP_QUAD4; + case INTERP_KERNEL::NORM_QUAD8: + lgth=(int)sizeof(FGP_QUAD8)/sizeof(double); + return FGP_QUAD8; + case INTERP_KERNEL::NORM_QUAD9: + lgth=(int)sizeof(FGP_QUAD9)/sizeof(double); + return FGP_QUAD9; + case INTERP_KERNEL::NORM_TETRA4: + lgth=(int)sizeof(FGP_TETRA4)/sizeof(double); + return FGP_TETRA4; + case INTERP_KERNEL::NORM_TETRA10: + lgth=(int)sizeof(FGP_TETRA10)/sizeof(double); + return FGP_TETRA10; + case INTERP_KERNEL::NORM_PENTA6: + lgth=(int)sizeof(FGP_PENTA6)/sizeof(double); + return FGP_PENTA6; + case INTERP_KERNEL::NORM_PENTA15: + lgth=(int)sizeof(FGP_PENTA15)/sizeof(double); + return FGP_PENTA15; + case INTERP_KERNEL::NORM_HEXA8: + lgth=(int)sizeof(FGP_HEXA8)/sizeof(double); + return FGP_HEXA8; + case INTERP_KERNEL::NORM_HEXA20: + lgth=(int)sizeof(FGP_HEXA20)/sizeof(double); + return FGP_HEXA20; + case INTERP_KERNEL::NORM_HEXA27: + lgth=(int)sizeof(FGP_HEXA27)/sizeof(double); + return FGP_HEXA27; + case INTERP_KERNEL::NORM_PYRA5: + lgth=(int)sizeof(FGP_PYRA5)/sizeof(double); + return FGP_PYRA5; + case INTERP_KERNEL::NORM_PYRA13: + lgth=(int)sizeof(FGP_PYRA13)/sizeof(double); + return FGP_PYRA13; + default: + throw INTERP_KERNEL::Exception("MEDCouplingFieldDiscretizationGaussNE::GetWeightArrayFromGeometricType : only SEG[2,3,4], TRI[3,6,7], QUAD[4,9], TETRA[4,10], PENTA[6,15], HEXA[8,20,27], PYRA[5,13] supported !"); + } +} + +const double *MEDCouplingFieldDiscretizationGaussNE::GetRefCoordsFromGeometricType(INTERP_KERNEL::NormalizedCellType geoType, std::size_t& lgth) +{ + switch(geoType) + { + case INTERP_KERNEL::NORM_POINT1: + lgth=0; + return 0; + case INTERP_KERNEL::NORM_SEG2: + lgth=(int)sizeof(REF_SEG2)/sizeof(double); + return REF_SEG2; + case INTERP_KERNEL::NORM_SEG3: + lgth=(int)sizeof(REF_SEG3)/sizeof(double); + return REF_SEG3; + case INTERP_KERNEL::NORM_SEG4: + lgth=(int)sizeof(REF_SEG4)/sizeof(double); + return REF_SEG4; + case INTERP_KERNEL::NORM_TRI3: + lgth=(int)sizeof(REF_TRI3)/sizeof(double); + return REF_TRI3; + case INTERP_KERNEL::NORM_TRI6: + lgth=(int)sizeof(REF_TRI6)/sizeof(double); + return REF_TRI6; + case INTERP_KERNEL::NORM_TRI7: + lgth=(int)sizeof(REF_TRI7)/sizeof(double); + return REF_TRI7; + case INTERP_KERNEL::NORM_QUAD4: + lgth=(int)sizeof(REF_QUAD4)/sizeof(double); + return REF_QUAD4; + case INTERP_KERNEL::NORM_QUAD8: + lgth=(int)sizeof(REF_QUAD8)/sizeof(double); + return REF_QUAD8; + case INTERP_KERNEL::NORM_QUAD9: + lgth=(int)sizeof(REF_QUAD9)/sizeof(double); + return REF_QUAD9; + case INTERP_KERNEL::NORM_TETRA4: + lgth=(int)sizeof(REF_TETRA4)/sizeof(double); + return REF_TETRA4; + case INTERP_KERNEL::NORM_TETRA10: + lgth=(int)sizeof(REF_TETRA10)/sizeof(double); + return REF_TETRA10; + case INTERP_KERNEL::NORM_PENTA6: + lgth=(int)sizeof(REF_PENTA6)/sizeof(double); + return REF_PENTA6; + case INTERP_KERNEL::NORM_PENTA15: + lgth=(int)sizeof(REF_PENTA15)/sizeof(double); + return REF_PENTA15; + case INTERP_KERNEL::NORM_HEXA8: + lgth=(int)sizeof(REF_HEXA8)/sizeof(double); + return REF_HEXA8; + case INTERP_KERNEL::NORM_HEXA20: + lgth=(int)sizeof(REF_HEXA20)/sizeof(double); + return REF_HEXA20; + case INTERP_KERNEL::NORM_HEXA27: + lgth=(int)sizeof(REF_HEXA27)/sizeof(double); + return REF_HEXA27; + case INTERP_KERNEL::NORM_PYRA5: + lgth=(int)sizeof(REF_PYRA5)/sizeof(double); + return REF_PYRA5; + case INTERP_KERNEL::NORM_PYRA13: + lgth=(int)sizeof(REF_PYRA13)/sizeof(double); + return REF_PYRA13; + default: + throw INTERP_KERNEL::Exception("MEDCouplingFieldDiscretizationGaussNE::GetRefCoordsFromGeometricType : only SEG[2,3,4], TRI[3,6,7], QUAD[4,8,9], TETRA[4,10], PENTA[6,15], HEXA[8,20,27], PYRA[5,13] supported !"); + } +} + +const double *MEDCouplingFieldDiscretizationGaussNE::GetLocsFromGeometricType(INTERP_KERNEL::NormalizedCellType geoType, std::size_t& lgth) +{ + switch(geoType) + { + case INTERP_KERNEL::NORM_POINT1: + { + lgth=0; + return 0; + } + case INTERP_KERNEL::NORM_SEG2: + { + lgth=(int)sizeof(LOC_SEG2)/sizeof(double); + return LOC_SEG2; + } + case INTERP_KERNEL::NORM_SEG3: + { + lgth=(int)sizeof(LOC_SEG3)/sizeof(double); + return LOC_SEG3; + } + case INTERP_KERNEL::NORM_SEG4: + { + lgth=(int)sizeof(LOC_SEG4)/sizeof(double); + return LOC_SEG4; + } + case INTERP_KERNEL::NORM_TRI3: + { + lgth=(int)sizeof(LOC_TRI3)/sizeof(double); + return LOC_TRI3; + } + case INTERP_KERNEL::NORM_TRI6: + { + lgth=(int)sizeof(LOC_TRI6)/sizeof(double); + return LOC_TRI6; + } + case INTERP_KERNEL::NORM_TRI7: + { + lgth=(int)sizeof(LOC_TRI7)/sizeof(double); + return LOC_TRI7; + } + case INTERP_KERNEL::NORM_QUAD4: + { + lgth=(int)sizeof(LOC_QUAD4)/sizeof(double); + return LOC_QUAD4; + } + case INTERP_KERNEL::NORM_QUAD8: + { + lgth=(int)sizeof(LOC_QUAD8)/sizeof(double); + return LOC_QUAD8; + } + case INTERP_KERNEL::NORM_QUAD9: + { + lgth=(int)sizeof(LOC_QUAD9)/sizeof(double); + return LOC_QUAD9; + } + case INTERP_KERNEL::NORM_TETRA4: + { + lgth=(int)sizeof(LOC_TETRA4)/sizeof(double); + return LOC_TETRA4; + } + case INTERP_KERNEL::NORM_TETRA10: + { + lgth=(int)sizeof(LOC_TETRA10)/sizeof(double); + return LOC_TETRA10; + } + case INTERP_KERNEL::NORM_PENTA6: + { + lgth=(int)sizeof(LOC_PENTA6)/sizeof(double); + return LOC_PENTA6; + } + case INTERP_KERNEL::NORM_PENTA15: + { + lgth=(int)sizeof(LOC_PENTA15)/sizeof(double); + return LOC_PENTA15; + } + case INTERP_KERNEL::NORM_HEXA8: + { + lgth=(int)sizeof(LOC_HEXA8)/sizeof(double); + return LOC_HEXA8; + } + case INTERP_KERNEL::NORM_HEXA20: + { + lgth=(int)sizeof(LOC_HEXA20)/sizeof(double); + return LOC_HEXA20; + } + case INTERP_KERNEL::NORM_HEXA27: + { + lgth=(int)sizeof(LOC_HEXA27)/sizeof(double); + return LOC_HEXA27; + } + case INTERP_KERNEL::NORM_PYRA5: + { + lgth=(int)sizeof(LOC_PYRA5)/sizeof(double); + return LOC_PYRA5; + } + case INTERP_KERNEL::NORM_PYRA13: + { + lgth=(int)sizeof(LOC_PYRA13)/sizeof(double); + return LOC_PYRA13; + } + default: + throw INTERP_KERNEL::Exception("MEDCouplingFieldDiscretizationGaussNE::GetLocsFromGeometricType : only SEG[2,3,4], TRI[3,6,7], QUAD[4,8,9], TETRA[4,10], PENTA[6,15], HEXA[8,20,27], PYRA[5,13] supported !"); + } +} + +void MEDCouplingFieldDiscretizationGaussNE::computeMeshRestrictionFromTupleIds(const MEDCouplingMesh *mesh, const int *tupleIdsBg, const int *tupleIdsEnd, + DataArrayInt *&cellRestriction, DataArrayInt *&trueTupleRestriction) const +{ + if(!mesh) + throw INTERP_KERNEL::Exception("MEDCouplingFieldDiscretizationGaussNE::computeMeshRestrictionFromTupleIds : NULL input mesh !"); + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> tmp=DataArrayInt::New(); tmp->alloc((int)std::distance(tupleIdsBg,tupleIdsEnd),1); + std::copy(tupleIdsBg,tupleIdsEnd,tmp->getPointer()); + tmp->sort(true); + tmp=tmp->buildUnique(); + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> nbOfNodesPerCell=mesh->computeNbOfNodesPerCell(); + nbOfNodesPerCell->computeOffsets2(); + nbOfNodesPerCell->searchRangesInListOfIds(tmp,cellRestriction,trueTupleRestriction); +} + +void MEDCouplingFieldDiscretizationGaussNE::checkCompatibilityWithNature(NatureOfField nat) const +{ +} + +double MEDCouplingFieldDiscretizationGaussNE::getIJK(const MEDCouplingMesh *mesh, const DataArrayDouble *da, int cellId, int nodeIdInCell, int compoId) const +{ + if(!mesh) + throw INTERP_KERNEL::Exception("MEDCouplingFieldDiscretizationGaussNE::getIJK : NULL input mesh !"); + int offset=0; + for(int i=0;i<cellId;i++) + { + INTERP_KERNEL::NormalizedCellType type=mesh->getTypeOfCell(i); + const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(type); + offset+=cm.getNumberOfNodes(); + } + return da->getIJ(offset+nodeIdInCell,compoId); +} + +void MEDCouplingFieldDiscretizationGaussNE::checkCoherencyBetween(const MEDCouplingMesh *mesh, const DataArray *da) const +{ + int nbOfTuples=getNumberOfTuples(mesh); + if(nbOfTuples!=da->getNumberOfTuples()) + { + std::ostringstream oss; oss << "Invalid number of tuples in the array : expecting " << nbOfTuples << " !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } +} + +MEDCouplingFieldDouble *MEDCouplingFieldDiscretizationGaussNE::getMeasureField(const MEDCouplingMesh *mesh, bool isAbs) const +{ + if(!mesh) + throw INTERP_KERNEL::Exception("MEDCouplingFieldDiscretizationGaussNE::getMeasureField : mesh instance specified is NULL !"); + MEDCouplingAutoRefCountObjectPtr<MEDCouplingFieldDouble> vol=mesh->getMeasureField(isAbs); + const double *volPtr=vol->getArray()->begin(); + MEDCouplingAutoRefCountObjectPtr<MEDCouplingFieldDouble> ret=MEDCouplingFieldDouble::New(ON_GAUSS_NE); + ret->setMesh(mesh); + // + std::set<INTERP_KERNEL::NormalizedCellType> types=mesh->getAllGeoTypes(); + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> nbOfNodesPerCell=mesh->computeNbOfNodesPerCell(); + int nbTuples=nbOfNodesPerCell->accumulate(0); + nbOfNodesPerCell->computeOffsets2(); + MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> arr=DataArrayDouble::New(); arr->alloc(nbTuples,1); + ret->setArray(arr); + double *arrPtr=arr->getPointer(); + for(std::set<INTERP_KERNEL::NormalizedCellType>::const_iterator it=types.begin();it!=types.end();it++) + { + std::size_t wArrSz=-1; + const double *wArr=GetWeightArrayFromGeometricType(*it,wArrSz); + INTERP_KERNEL::AutoPtr<double> wArr2=new double[wArrSz]; + double sum=std::accumulate(wArr,wArr+wArrSz,0.); + std::transform(wArr,wArr+wArrSz,(double *)wArr2,std::bind2nd(std::multiplies<double>(),1./sum)); + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ids=mesh->giveCellsWithType(*it); + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ids2=ids->buildExplicitArrByRanges(nbOfNodesPerCell); + const int *ptIds2=ids2->begin(),*ptIds=ids->begin(); + int nbOfCellsWithCurGeoType=ids->getNumberOfTuples(); + for(int i=0;i<nbOfCellsWithCurGeoType;i++,ptIds++) + for(std::size_t j=0;j<wArrSz;j++,ptIds2++) + arrPtr[*ptIds2]=wArr2[j]*volPtr[*ptIds]; + } + ret->synchronizeTimeWithSupport(); + return ret.retn(); +} + +void MEDCouplingFieldDiscretizationGaussNE::getValueOn(const DataArrayDouble *arr, const MEDCouplingMesh *mesh, const double *loc, double *res) const +{ + throw INTERP_KERNEL::Exception("Not implemented yet !"); +} + +void MEDCouplingFieldDiscretizationGaussNE::getValueOnPos(const DataArrayDouble *arr, const MEDCouplingMesh *mesh, int i, int j, int k, double *res) const +{ + throw INTERP_KERNEL::Exception("getValueOnPos(i,j,k) : Not applyable for Gauss points !"); +} + +DataArrayDouble *MEDCouplingFieldDiscretizationGaussNE::getValueOnMulti(const DataArrayDouble *arr, const MEDCouplingMesh *mesh, const double *loc, int nbOfPoints) const +{ + throw INTERP_KERNEL::Exception("getValueOnMulti : Not implemented for Gauss NE !"); +} + +MEDCouplingMesh *MEDCouplingFieldDiscretizationGaussNE::buildSubMeshData(const MEDCouplingMesh *mesh, const int *start, const int *end, DataArrayInt *&di) const +{ + if(!mesh) + throw INTERP_KERNEL::Exception("MEDCouplingFieldDiscretizationGaussNE::buildSubMeshData : NULL input mesh !"); + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> diSafe=computeTupleIdsToSelectFromCellIds(mesh,start,end); + MEDCouplingAutoRefCountObjectPtr<MEDCouplingMesh> 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;i<nbOfCells;i++) + { + INTERP_KERNEL::NormalizedCellType type=mesh->getTypeOfCell(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<beginCellIds) + beginOut+=delta; + endOut+=delta; + if(i>=endCellIds) + break; + } + MEDCouplingAutoRefCountObjectPtr<MEDCouplingMesh> 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. + * + * \return a newly allocated array containing ids to select into the DataArrayDouble of the field. + * + */ +DataArrayInt *MEDCouplingFieldDiscretizationGaussNE::computeTupleIdsToSelectFromCellIds(const MEDCouplingMesh *mesh, const int *startCellIds, const int *endCellIds) const +{ + if(!mesh) + throw INTERP_KERNEL::Exception("MEDCouplingFieldDiscretizationGaussNE::computeTupleIdsToSelectFromCellIds : null mesh !"); + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> nbOfNodesPerCell=mesh->computeNbOfNodesPerCell(); + nbOfNodesPerCell->computeOffsets2(); + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> sel=DataArrayInt::New(); sel->useArray(startCellIds,false,CPP_DEALLOC,(int)std::distance(startCellIds,endCellIds),1); + return sel->buildExplicitArrByRanges(nbOfNodesPerCell); +} + +/*! + * No implementation needed ! + */ +void MEDCouplingFieldDiscretizationGaussNE::renumberValuesOnNodes(double , const int *, int newNbOfNodes, DataArrayDouble *) const +{ +} + +void MEDCouplingFieldDiscretizationGaussNE::renumberValuesOnCells(double epsOnVals, const MEDCouplingMesh *mesh, const int *old2New, int newSz, DataArrayDouble *arr) const +{ + throw INTERP_KERNEL::Exception("Not implemented yet !"); +} + +void MEDCouplingFieldDiscretizationGaussNE::renumberValuesOnCellsR(const MEDCouplingMesh *mesh, const int *new2old, int newSz, DataArrayDouble *arr) const +{ + throw INTERP_KERNEL::Exception("Not implemented yet !"); +} + +void MEDCouplingFieldDiscretizationGaussNE::reprQuickOverview(std::ostream& stream) const +{ + stream << "Gauss points on nodes per element spatial discretization."; +} + +MEDCouplingFieldDiscretizationGaussNE::MEDCouplingFieldDiscretizationGaussNE(const MEDCouplingFieldDiscretizationGaussNE& other):MEDCouplingFieldDiscretization(other) +{ +} + +TypeOfField MEDCouplingFieldDiscretizationKriging::getEnum() const +{ + return TYPE; +} + +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; +} + +std::string MEDCouplingFieldDiscretizationKriging::getStringRepr() const +{ + return std::string(REPR); +} + +void MEDCouplingFieldDiscretizationKriging::checkCompatibilityWithNature(NatureOfField nat) const +{ + if(nat!=ConservativeVolumic) + throw INTERP_KERNEL::Exception("Invalid nature for Kriging field : expected ConservativeVolumic !"); +} + +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<const MEDCouplingFieldDiscretizationKriging *>(other); + bool ret=otherC!=0; + if(!ret) + reason="Spatial discrtization of this is ON_NODES_KR, which is not the case of other."; + return ret; +} + +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 !"); +} + +void MEDCouplingFieldDiscretizationKriging::getValueOn(const DataArrayDouble *arr, const MEDCouplingMesh *mesh, const double *loc, double *res) const +{ + MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> res2=MEDCouplingFieldDiscretizationKriging::getValueOnMulti(arr,mesh,loc,1); + std::copy(res2->begin(),res2->end(),res); +} + +DataArrayDouble *MEDCouplingFieldDiscretizationKriging::getValueOnMulti(const DataArrayDouble *arr, const MEDCouplingMesh *mesh, const double *loc, int nbOfTargetPoints) const +{ + if(!arr || !arr->isAllocated()) + throw INTERP_KERNEL::Exception("MEDCouplingFieldDiscretizationKriging::getValueOnMulti : input array is null or not allocated !"); + int nbOfRows(getNumberOfMeshPlaces(mesh)); + if(arr->getNumberOfTuples()!=nbOfRows) + { + std::ostringstream oss; oss << "MEDCouplingFieldDiscretizationKriging::getValueOnMulti : input array does not have correct number of tuples ! Excepted " << nbOfRows << " having " << arr->getNumberOfTuples() << " !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + int nbCols(-1),nbCompo(arr->getNumberOfComponents()); + MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> m(computeEvaluationMatrixOnGivenPts(mesh,loc,nbOfTargetPoints,nbCols)); + MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret(DataArrayDouble::New()); + ret->alloc(nbOfTargetPoints,nbCompo); + INTERP_KERNEL::matrixProduct(m->begin(),nbOfTargetPoints,nbCols,arr->begin(),nbOfRows,nbCompo,ret->getPointer()); + return ret.retn(); +} + +void MEDCouplingFieldDiscretizationKriging::reprQuickOverview(std::ostream& stream) const +{ + stream << "Kriging spatial discretization."; +} + +/*! + * Returns the matrix of size nbRows = \a nbOfTargetPoints and \a nbCols = \a nbCols. This matrix is useful if + * + * \return the new result matrix to be deallocated by the caller. + */ +DataArrayDouble *MEDCouplingFieldDiscretizationKriging::computeEvaluationMatrixOnGivenPts(const MEDCouplingMesh *mesh, const double *loc, int nbOfTargetPoints, int& nbCols) const +{ + int isDrift(-1),nbRows(-1); + MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> matrixInv(computeInverseMatrix(mesh,isDrift,nbRows)); + // + MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> coords=getLocalizationOfDiscValues(mesh); + int nbOfPts(coords->getNumberOfTuples()),dimension(coords->getNumberOfComponents()); + MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> locArr=DataArrayDouble::New(); + locArr->useArray(loc,false,CPP_DEALLOC,nbOfTargetPoints,dimension); + nbCols=nbOfPts; + // + MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> matrix2=coords->buildEuclidianDistanceDenseMatrixWith(locArr); + operateOnDenseMatrix(mesh->getSpaceDimension(),nbOfTargetPoints*nbOfPts,matrix2->getPointer()); + // + MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> matrix3=DataArrayDouble::New(); + matrix3->alloc(nbOfTargetPoints*nbRows,1); + double *work=matrix3->getPointer(); + const double *workCst(matrix2->begin()),*workCst2(loc); + for(int i=0;i<nbOfTargetPoints;i++,workCst+=nbOfPts,workCst2+=isDrift-1) + { + for(int j=0;j<nbOfPts;j++) + work[i*nbRows+j]=workCst[j]; + work[i*nbRows+nbOfPts]=1.0; + for(int j=0;j<isDrift-1;j++) + work[i*nbRows+(nbOfPts+1+j)]=workCst2[j]; + } + MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret(DataArrayDouble::New()); + ret->alloc(nbOfTargetPoints,nbRows); + INTERP_KERNEL::matrixProduct(matrix3->begin(),nbOfTargetPoints,nbRows,matrixInv->begin(),nbRows,nbRows,ret->getPointer()); + MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret2(DataArrayDouble::New()); + ret2->alloc(nbOfTargetPoints*nbOfPts,1); + workCst=ret->begin(); work=ret2->getPointer(); + for(int i=0;i<nbOfTargetPoints;i++,workCst+=nbRows) + work=std::copy(workCst,workCst+nbOfPts,work); + return ret2.retn(); +} + +/*! + * This method returns the square matrix of size \a matSz that is the inverse of the kriging matrix. The returned matrix can returned all the coeffs of kriging + * when multiplied by the vector of values attached to each point. + * + * \param [out] isDrift return if drift coefficients are present in the returned vector of coefficients. If different from 0 there is presence of drift coefficients. + * \param [out] matSz the size of returned square matrix + * \return the new result matrix to be deallocated by the caller. + * \sa computeMatrix + */ +DataArrayDouble *MEDCouplingFieldDiscretizationKriging::computeInverseMatrix(const MEDCouplingMesh *mesh, int& isDrift, int& matSz) const +{ + MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> matrixWithDrift(computeMatrix(mesh,isDrift,matSz)); + MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> matrixInv(DataArrayDouble::New()); + matrixInv->alloc(matSz*matSz,1); + INTERP_KERNEL::inverseMatrix(matrixWithDrift->getConstPointer(),matSz,matrixInv->getPointer()); + return matrixInv.retn(); +} + +/*! + * This method computes the kriging matrix. + * \return the new result matrix to be deallocated by the caller. + * \sa computeInverseMatrix + */ +DataArrayDouble *MEDCouplingFieldDiscretizationKriging::computeMatrix(const MEDCouplingMesh *mesh, int& isDrift, int& matSz) const +{ + if(!mesh) + throw INTERP_KERNEL::Exception("MEDCouplingFieldDiscretizationKriging::computeMatrix : NULL input mesh !"); + MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> coords(getLocalizationOfDiscValues(mesh)); + int nbOfPts(coords->getNumberOfTuples()); + MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> matrix(coords->buildEuclidianDistanceDenseMatrix()); + operateOnDenseMatrix(mesh->getSpaceDimension(),nbOfPts*nbOfPts,matrix->getPointer()); + // Drift + MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> matrixWithDrift(performDrift(matrix,coords,isDrift)); + matSz=nbOfPts+isDrift; + return matrixWithDrift.retn(); +} + +/*! + * This method computes coefficients to apply to each representing points of \a mesh, that is to say the nodes of \a mesh given a field array \a arr whose + * number of tuples should be equal to the number of representing points in \a mesh. + * + * \param [in] mesh is the sources of nodes on which kriging will be done regarding the parameters and the value of \c this->getSpaceDimension() + * \param [in] arr input field DataArrayDouble whose number of tuples must be equal to the number of nodes in \a mesh + * \param [out] isDrift return if drift coefficients are present in the returned vector of coefficients. If different from 0 there is presence of drift coefficients. + * Whatever the value of \a isDrift the number of tuples of returned DataArrayDouble will be equal to \c arr->getNumberOfTuples() + \a isDrift. + * \return a newly allocated array containing coefficients including or not drift coefficient at the end depending the value of \a isDrift parameter. + */ +DataArrayDouble *MEDCouplingFieldDiscretizationKriging::computeVectorOfCoefficients(const MEDCouplingMesh *mesh, const DataArrayDouble *arr, int& isDrift) const +{ + int nbRows(-1); + MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> matrixInv(computeInverseMatrix(mesh,isDrift,nbRows)); + MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> KnewiK(DataArrayDouble::New()); + KnewiK->alloc(nbRows*1,1); + MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> arr2(PerformDriftOfVec(arr,isDrift)); + INTERP_KERNEL::matrixProduct(matrixInv->getConstPointer(),nbRows,nbRows,arr2->getConstPointer(),arr2->getNumberOfTuples(),1,KnewiK->getPointer()); + return KnewiK.retn(); +} + +/*! + * Apply \f f(x) on each element x in \a matrixPtr. \a matrixPtr is expected to be a dense matrix represented by a chunck of memory of size at least equal to \a nbOfElems. + * + * \param [in] spaceDimension space dimension of the input mesh on which the Kriging has to be performed + * \param [in] nbOfElems is the result of the product of nb of rows and the nb of columns of matrix \a matrixPtr + * \param [in,out] matrixPtr is the dense matrix whose on each values the operation will be applied + */ +void MEDCouplingFieldDiscretizationKriging::operateOnDenseMatrix(int spaceDimension, int nbOfElems, double *matrixPtr) const +{ + switch(spaceDimension) + { + case 1: + { + OperateOnDenseMatrixH3(nbOfElems,matrixPtr); + break; + } + case 2: + { + OperateOnDenseMatrixH2Ln(nbOfElems,matrixPtr); + break; + } + case 3: + { + //nothing here : it is not a bug g(h)=h with spaceDim 3. + break; + } + default: + throw INTERP_KERNEL::Exception("MEDCouplingFieldDiscretizationKriging::operateOnDenseMatrix : only dimension 1, 2 and 3 implemented !"); + } +} + +void MEDCouplingFieldDiscretizationKriging::OperateOnDenseMatrixH3(int nbOfElems, double *matrixPtr) +{ + for(int i=0;i<nbOfElems;i++) + { + double val=matrixPtr[i]; + matrixPtr[i]=val*val*val; + } +} + +void MEDCouplingFieldDiscretizationKriging::OperateOnDenseMatrixH2Ln(int nbOfElems, double *matrixPtr) +{ + for(int i=0;i<nbOfElems;i++) + { + double val=matrixPtr[i]; + if(val!=0.) + matrixPtr[i]=val*val*log(val); + } +} + +/*! + * Performs a drift to the rectangular input matrix \a matr. + * This method generate a dense matrix starting from an input dense matrix \a matr and input array \a arr. + * \param [in] matr The rectangular dense matrix (with only one component). The number of rows of \a matr must be equal to the number of tuples of \a arr + * \param [in] arr The array of coords to be appended in the input dense matrix \a matr. Typically arr is an array of coordinates. + * \param [out] delta the delta of number of columns between returned dense matrix and input dense matrix \a matr. \a delta is equal to number of components of \a arr + 1. + * \sa performDrift + */ +DataArrayDouble *MEDCouplingFieldDiscretizationKriging::PerformDriftRect(const DataArrayDouble *matr, const DataArrayDouble *arr, int& delta) +{ + if(!matr || !matr->isAllocated() || matr->getNumberOfComponents()!=1) + throw INTERP_KERNEL::Exception("MEDCouplingFieldDiscretizationKriging::PerformDriftRect : invalid input dense matrix ! Must be allocated not NULL and with exactly one component !"); + if(!arr || !arr->isAllocated()) + throw INTERP_KERNEL::Exception("MEDCouplingFieldDiscretizationKriging::PerformDriftRect : invalid input array of coordiantes ! Must be allocated and not NULL !"); + int spaceDimension(arr->getNumberOfComponents()),nbOfPts(arr->getNumberOfTuples()),nbOfEltInMatrx(matr->getNumberOfTuples()); + delta=spaceDimension+1; + int nbOfCols(nbOfEltInMatrx/nbOfPts); + if(nbOfEltInMatrx%nbOfPts!=0) + throw INTERP_KERNEL::Exception("MEDCouplingFieldDiscretizationKriging::PerformDriftRect : size of input dense matrix and input arrays mismatch ! NbOfElems in matrix % nb of tuples in array must be equal to 0 !"); + MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret(DataArrayDouble::New()); ret->alloc(nbOfPts*(nbOfCols+delta)); + double *retPtr(ret->getPointer()); + const double *mPtr(matr->begin()),*aPtr(arr->begin()); + for(int i=0;i<nbOfPts;i++,aPtr+=spaceDimension,mPtr+=nbOfCols) + { + retPtr=std::copy(mPtr,mPtr+nbOfCols,retPtr); + *retPtr++=1.; + retPtr=std::copy(aPtr,aPtr+spaceDimension,retPtr); + } + return ret.retn(); +} + +/*! + * \return a newly allocated array having \a isDrift more tuples than \a arr. + * \sa computeVectorOfCoefficients + */ +DataArrayDouble *MEDCouplingFieldDiscretizationKriging::PerformDriftOfVec(const DataArrayDouble *arr, int isDrift) +{ + if(!arr || !arr->isAllocated() || arr->getNumberOfComponents()!=1) + throw INTERP_KERNEL::Exception("MEDCouplingFieldDiscretizationKriging::PerformDriftOfVec : input array must be not NULL allocated and with one component !"); + if(isDrift<0) + throw INTERP_KERNEL::Exception("MEDCouplingFieldDiscretizationKriging::PerformDriftOfVec : isDrift parameter must be >=0 !"); + MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> arr2(DataArrayDouble::New()); + arr2->alloc((arr->getNumberOfTuples()+isDrift)*1,1); + double *work(std::copy(arr->begin(),arr->end(),arr2->getPointer())); + std::fill(work,work+isDrift,0.); + return arr2.retn(); +} + +/*! + * Starting from a square matrix \a matr, this method returns a newly allocated dense square matrix whose \a matr is included in returned matrix + * in the top left corner, and in the remaining returned matrix the parameters to take into account about the kriging drift. + * For the moment only linear srift is implemented. + * + * \param [in] arr the position of points were input mesh geometry is considered for Kriging + * \param [in] matr input matrix whose drift part will be added + * \param [out] delta the difference between the size of the output matrix and the input matrix \a matr. + * \return a newly allocated matrix bigger than input matrix \a matr. + * \sa MEDCouplingFieldDiscretizationKriging::PerformDriftRect + */ +DataArrayDouble *MEDCouplingFieldDiscretizationKriging::performDrift(const DataArrayDouble *matr, const DataArrayDouble *arr, int& delta) const +{ + int spaceDimension=arr->getNumberOfComponents(); + delta=spaceDimension+1; + int szOfMatrix=arr->getNumberOfTuples(); + if(szOfMatrix*szOfMatrix!=matr->getNumberOfTuples()) + throw INTERP_KERNEL::Exception("MEDCouplingFieldDiscretizationKriging::performDrift : invalid size"); + MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New(); + ret->alloc((szOfMatrix+delta)*(szOfMatrix+delta),1); + const double *srcWork=matr->getConstPointer(); + const double *srcWork2=arr->getConstPointer(); + double *destWork=ret->getPointer(); + for(int i=0;i<szOfMatrix;i++) + { + destWork=std::copy(srcWork,srcWork+szOfMatrix,destWork); + srcWork+=szOfMatrix; + *destWork++=1.; + destWork=std::copy(srcWork2,srcWork2+spaceDimension,destWork); + srcWork2+=spaceDimension; + } + std::fill(destWork,destWork+szOfMatrix,1.); destWork+=szOfMatrix; + std::fill(destWork,destWork+spaceDimension+1,0.); destWork+=spaceDimension+1; + MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> arrNoI=arr->toNoInterlace(); + srcWork2=arrNoI->getConstPointer(); + for(int i=0;i<spaceDimension;i++) + { + destWork=std::copy(srcWork2,srcWork2+szOfMatrix,destWork); + srcWork2+=szOfMatrix; + std::fill(destWork,destWork+spaceDimension+1,0.); + destWork+=spaceDimension+1; + } + // + return ret.retn(); +} diff --git a/src/medtool/src/MEDCoupling/MEDCouplingFieldDiscretization.hxx b/src/medtool/src/MEDCoupling/MEDCouplingFieldDiscretization.hxx new file mode 100644 index 000000000..e4868efe4 --- /dev/null +++ b/src/medtool/src/MEDCoupling/MEDCouplingFieldDiscretization.hxx @@ -0,0 +1,429 @@ +// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 +// 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_MEDCOUPLINGFIELDDISCRETIZATION_HXX__ +#define __PARAMEDMEM_MEDCOUPLINGFIELDDISCRETIZATION_HXX__ + +#include "MEDCoupling.hxx" +#include "MEDCouplingRefCountObject.hxx" +#include "InterpKernelException.hxx" +#include "MEDCouplingTimeLabel.hxx" +#include "MEDCouplingNatureOfField.hxx" +#include "MEDCouplingGaussLocalization.hxx" +#include "MEDCouplingAutoRefCountObjectPtr.hxx" + +#include <set> +#include <vector> + +namespace ParaMEDMEM +{ + class DataArray; + class DataArrayInt; + class MEDCouplingMesh; + class DataArrayDouble; + class MEDCouplingFieldDouble; + + class MEDCouplingFieldDiscretization : public RefCountObject, public TimeLabel + { + public: + MEDCOUPLING_EXPORT static MEDCouplingFieldDiscretization *New(TypeOfField type); + MEDCOUPLING_EXPORT double getPrecision() const { return _precision; } + MEDCOUPLING_EXPORT void setPrecision(double val) { _precision=val; } + MEDCOUPLING_EXPORT void updateTime() const; + MEDCOUPLING_EXPORT std::size_t getHeapMemorySizeWithoutChildren() const; + MEDCOUPLING_EXPORT std::vector<const BigMemoryObject *> getDirectChildrenWithNull() const; + MEDCOUPLING_EXPORT static TypeOfField GetTypeOfFieldFromStringRepr(const std::string& repr); + MEDCOUPLING_EXPORT static std::string GetTypeOfFieldRepr(TypeOfField type); + MEDCOUPLING_EXPORT virtual TypeOfField getEnum() const = 0; + MEDCOUPLING_EXPORT virtual bool isEqual(const MEDCouplingFieldDiscretization *other, double eps) const; + MEDCOUPLING_EXPORT virtual bool isEqualIfNotWhy(const MEDCouplingFieldDiscretization *other, double eps, std::string& reason) const = 0; + MEDCOUPLING_EXPORT virtual bool isEqualWithoutConsideringStr(const MEDCouplingFieldDiscretization *other, double eps) const; + MEDCOUPLING_EXPORT virtual MEDCouplingFieldDiscretization *deepCpy() const; + MEDCOUPLING_EXPORT virtual MEDCouplingFieldDiscretization *clone() const = 0; + MEDCOUPLING_EXPORT virtual MEDCouplingFieldDiscretization *clonePart(const int *startCellIds, const int *endCellIds) const; + MEDCOUPLING_EXPORT virtual MEDCouplingFieldDiscretization *clonePartRange(int beginCellIds, int endCellIds, int stepCellIds) const; + MEDCOUPLING_EXPORT virtual std::string getStringRepr() const = 0; + MEDCOUPLING_EXPORT virtual const char *getRepr() const = 0; + MEDCOUPLING_EXPORT virtual int getNumberOfTuplesExpectedRegardingCode(const std::vector<int>& code, const std::vector<const DataArrayInt *>& idsPerType) const = 0; + MEDCOUPLING_EXPORT virtual int getNumberOfTuples(const MEDCouplingMesh *mesh) const = 0; + MEDCOUPLING_EXPORT virtual int getNumberOfMeshPlaces(const MEDCouplingMesh *mesh) const = 0; + MEDCOUPLING_EXPORT virtual DataArrayInt *getOffsetArr(const MEDCouplingMesh *mesh) const = 0; + MEDCOUPLING_EXPORT virtual void normL1(const MEDCouplingMesh *mesh, const DataArrayDouble *arr, double *res) const; + MEDCOUPLING_EXPORT virtual void normL2(const MEDCouplingMesh *mesh, const DataArrayDouble *arr, double *res) const; + MEDCOUPLING_EXPORT virtual void integral(const MEDCouplingMesh *mesh, const DataArrayDouble *arr, bool isWAbs, double *res) const; + MEDCOUPLING_EXPORT virtual DataArrayDouble *getLocalizationOfDiscValues(const MEDCouplingMesh *mesh) const = 0; + MEDCOUPLING_EXPORT virtual void computeMeshRestrictionFromTupleIds(const MEDCouplingMesh *mesh, const int *tupleIdsBg, const int *tupleIdsEnd, + DataArrayInt *&cellRestriction, DataArrayInt *&trueTupleRestriction) const = 0; + MEDCOUPLING_EXPORT virtual void checkCompatibilityWithNature(NatureOfField nat) const = 0; + MEDCOUPLING_EXPORT virtual void renumberCells(const int *old2NewBg, bool check=true); + MEDCOUPLING_EXPORT virtual void renumberArraysForCell(const MEDCouplingMesh *mesh, const std::vector<DataArray *>& arrays, + const int *old2NewBg, bool check) = 0; + MEDCOUPLING_EXPORT virtual double getIJK(const MEDCouplingMesh *mesh, const DataArrayDouble *da, int cellId, int nodeIdInCell, int compoId) const; + MEDCOUPLING_EXPORT virtual void checkCoherencyBetween(const MEDCouplingMesh *mesh, const DataArray *da) const = 0; + MEDCOUPLING_EXPORT virtual MEDCouplingFieldDouble *getMeasureField(const MEDCouplingMesh *mesh, bool isAbs) const = 0; + MEDCOUPLING_EXPORT virtual void getValueOn(const DataArrayDouble *arr, const MEDCouplingMesh *mesh, const double *loc, double *res) const = 0; + MEDCOUPLING_EXPORT virtual void getValueOnPos(const DataArrayDouble *arr, const MEDCouplingMesh *mesh, int i, int j, int k, double *res) const = 0; + MEDCOUPLING_EXPORT virtual DataArrayDouble *getValueOnMulti(const DataArrayDouble *arr, const MEDCouplingMesh *mesh, const double *loc, int nbOfPoints) const = 0; + MEDCOUPLING_EXPORT virtual DataArrayInt *computeTupleIdsToSelectFromCellIds(const MEDCouplingMesh *mesh, const int *startCellIds, const int *endCellIds) const = 0; + MEDCOUPLING_EXPORT virtual MEDCouplingMesh *buildSubMeshData(const MEDCouplingMesh *mesh, const int *start, const int *end, DataArrayInt *&di) const = 0; + MEDCOUPLING_EXPORT virtual MEDCouplingMesh *buildSubMeshDataRange(const MEDCouplingMesh *mesh, int beginCellIds, int endCellIds, int stepCellIds, int& beginOut, int& endOut, int& stepOut, DataArrayInt *&di) const; + MEDCOUPLING_EXPORT virtual void renumberValuesOnNodes(double epsOnVals, const int *old2New, int newNbOfNodes, DataArrayDouble *arr) const = 0; + MEDCOUPLING_EXPORT virtual void renumberValuesOnCells(double epsOnVals, const MEDCouplingMesh *mesh, const int *old2New, int newSz, DataArrayDouble *arr) const = 0; + MEDCOUPLING_EXPORT virtual void renumberValuesOnCellsR(const MEDCouplingMesh *mesh, const int *new2old, int newSz, DataArrayDouble *arr) const = 0; + MEDCOUPLING_EXPORT virtual void getSerializationIntArray(DataArrayInt *& arr) const; + MEDCOUPLING_EXPORT virtual void getTinySerializationIntInformation(std::vector<int>& tinyInfo) const; + MEDCOUPLING_EXPORT virtual void getTinySerializationDbleInformation(std::vector<double>& tinyInfo) const; + MEDCOUPLING_EXPORT virtual void finishUnserialization(const std::vector<double>& tinyInfo); + MEDCOUPLING_EXPORT virtual void resizeForUnserialization(const std::vector<int>& tinyInfo, DataArrayInt *& arr); + MEDCOUPLING_EXPORT virtual void checkForUnserialization(const std::vector<int>& tinyInfo, const DataArrayInt *arr); + MEDCOUPLING_EXPORT virtual void setGaussLocalizationOnType(const MEDCouplingMesh *m, INTERP_KERNEL::NormalizedCellType type, const std::vector<double>& refCoo, + const std::vector<double>& gsCoo, const std::vector<double>& wg); + MEDCOUPLING_EXPORT virtual void setGaussLocalizationOnCells(const MEDCouplingMesh *m, const int *begin, const int *end, const std::vector<double>& refCoo, + const std::vector<double>& gsCoo, const std::vector<double>& wg); + MEDCOUPLING_EXPORT virtual void clearGaussLocalizations(); + MEDCOUPLING_EXPORT virtual MEDCouplingGaussLocalization& getGaussLocalization(int locId); + MEDCOUPLING_EXPORT virtual int getNbOfGaussLocalization() const; + MEDCOUPLING_EXPORT virtual int getGaussLocalizationIdOfOneCell(int cellId) const; + MEDCOUPLING_EXPORT virtual int getGaussLocalizationIdOfOneType(INTERP_KERNEL::NormalizedCellType type) const; + MEDCOUPLING_EXPORT virtual std::set<int> getGaussLocalizationIdsOfOneType(INTERP_KERNEL::NormalizedCellType type) const; + MEDCOUPLING_EXPORT virtual void getCellIdsHavingGaussLocalization(int locId, std::vector<int>& cellIds) const; + MEDCOUPLING_EXPORT virtual const MEDCouplingGaussLocalization& getGaussLocalization(int locId) const; + MEDCOUPLING_EXPORT virtual void reprQuickOverview(std::ostream& stream) const = 0; + MEDCOUPLING_EXPORT virtual ~MEDCouplingFieldDiscretization(); + protected: + MEDCOUPLING_EXPORT MEDCouplingFieldDiscretization(); + MEDCOUPLING_EXPORT static void RenumberEntitiesFromO2NArr(double epsOnVals, const int *old2NewPtr, int newNbOfEntity, DataArrayDouble *arr, const std::string& msg); + MEDCOUPLING_EXPORT static void RenumberEntitiesFromN2OArr(const int *new2OldPtr, int new2OldSz, DataArrayDouble *arr, const std::string& msg); + protected: + double _precision; + static const double DFLT_PRECISION; + }; + + class MEDCouplingFieldDiscretizationP0 : public MEDCouplingFieldDiscretization + { + public: + MEDCOUPLING_EXPORT TypeOfField getEnum() const; + MEDCOUPLING_EXPORT MEDCouplingFieldDiscretization *clone() const; + MEDCOUPLING_EXPORT std::string getStringRepr() const; + MEDCOUPLING_EXPORT const char *getRepr() const; + MEDCOUPLING_EXPORT bool isEqualIfNotWhy(const MEDCouplingFieldDiscretization *other, double eps, std::string& reason) const; + MEDCOUPLING_EXPORT int getNumberOfTuplesExpectedRegardingCode(const std::vector<int>& code, const std::vector<const DataArrayInt *>& idsPerType) const; + MEDCOUPLING_EXPORT int getNumberOfTuples(const MEDCouplingMesh *mesh) const; + MEDCOUPLING_EXPORT int getNumberOfMeshPlaces(const MEDCouplingMesh *mesh) const; + MEDCOUPLING_EXPORT DataArrayInt *getOffsetArr(const MEDCouplingMesh *mesh) const; + MEDCOUPLING_EXPORT void renumberArraysForCell(const MEDCouplingMesh *mesh, const std::vector<DataArray *>& arrays, + const int *old2NewBg, bool check); + MEDCOUPLING_EXPORT DataArrayDouble *getLocalizationOfDiscValues(const MEDCouplingMesh *mesh) const; + MEDCOUPLING_EXPORT void checkCompatibilityWithNature(NatureOfField nat) const; + MEDCOUPLING_EXPORT void computeMeshRestrictionFromTupleIds(const MEDCouplingMesh *mesh, const int *tupleIdsBg, const int *tupleIdsEnd, + DataArrayInt *&cellRestriction, DataArrayInt *&trueTupleRestriction) const; + MEDCOUPLING_EXPORT void checkCoherencyBetween(const MEDCouplingMesh *mesh, const DataArray *da) const; + MEDCOUPLING_EXPORT MEDCouplingFieldDouble *getMeasureField(const MEDCouplingMesh *mesh, bool isAbs) const; + MEDCOUPLING_EXPORT void getValueOn(const DataArrayDouble *arr, const MEDCouplingMesh *mesh, const double *loc, double *res) const; + MEDCOUPLING_EXPORT void getValueOnPos(const DataArrayDouble *arr, const MEDCouplingMesh *mesh, int i, int j, int k, double *res) const; + MEDCOUPLING_EXPORT DataArrayDouble *getValueOnMulti(const DataArrayDouble *arr, const MEDCouplingMesh *mesh, const double *loc, int nbOfPoints) const; + MEDCOUPLING_EXPORT void renumberValuesOnNodes(double epsOnVals, const int *old2New, int newNbOfNodes, DataArrayDouble *arr) const; + MEDCOUPLING_EXPORT void renumberValuesOnCells(double epsOnVals, const MEDCouplingMesh *mesh, const int *old2New, int newSz, DataArrayDouble *arr) const; + MEDCOUPLING_EXPORT void renumberValuesOnCellsR(const MEDCouplingMesh *mesh, const int *new2old, int newSz, DataArrayDouble *arr) const; + MEDCOUPLING_EXPORT MEDCouplingMesh *buildSubMeshData(const MEDCouplingMesh *mesh, const int *start, const int *end, DataArrayInt *&di) const; + MEDCOUPLING_EXPORT MEDCouplingMesh *buildSubMeshDataRange(const MEDCouplingMesh *mesh, int beginCellIds, int endCellIds, int stepCellIds, int& beginOut, int& endOut, int& stepOut, DataArrayInt *&di) const; + MEDCOUPLING_EXPORT DataArrayInt *computeTupleIdsToSelectFromCellIds(const MEDCouplingMesh *mesh, const int *startCellIds, const int *endCellIds) const; + MEDCOUPLING_EXPORT void reprQuickOverview(std::ostream& stream) const; + public: + static const char REPR[]; + static const TypeOfField TYPE; + }; + + class MEDCouplingFieldDiscretizationOnNodes : public MEDCouplingFieldDiscretization + { + public: + MEDCOUPLING_EXPORT int getNumberOfTuples(const MEDCouplingMesh *mesh) const; + MEDCOUPLING_EXPORT int getNumberOfTuplesExpectedRegardingCode(const std::vector<int>& code, const std::vector<const DataArrayInt *>& idsPerType) const; + MEDCOUPLING_EXPORT int getNumberOfMeshPlaces(const MEDCouplingMesh *mesh) const; + MEDCOUPLING_EXPORT DataArrayInt *getOffsetArr(const MEDCouplingMesh *mesh) const; + MEDCOUPLING_EXPORT void renumberArraysForCell(const MEDCouplingMesh *mesh, const std::vector<DataArray *>& arrays, + const int *old2NewBg, bool check); + MEDCOUPLING_EXPORT DataArrayDouble *getLocalizationOfDiscValues(const MEDCouplingMesh *mesh) const; + MEDCOUPLING_EXPORT void computeMeshRestrictionFromTupleIds(const MEDCouplingMesh *mesh, const int *tupleIdsBg, const int *tupleIdsEnd, + DataArrayInt *&cellRestriction, DataArrayInt *&trueTupleRestriction) const; + MEDCOUPLING_EXPORT void checkCoherencyBetween(const MEDCouplingMesh *mesh, const DataArray *da) const; + MEDCOUPLING_EXPORT MEDCouplingMesh *buildSubMeshData(const MEDCouplingMesh *mesh, const int *start, const int *end, DataArrayInt *&di) const; + MEDCOUPLING_EXPORT MEDCouplingMesh *buildSubMeshDataRange(const MEDCouplingMesh *mesh, int beginCellIds, int endCellIds, int stepCellIds, int& beginOut, int& endOut, int& stepOut, DataArrayInt *&di) const; + MEDCOUPLING_EXPORT DataArrayInt *computeTupleIdsToSelectFromCellIds(const MEDCouplingMesh *mesh, const int *startCellIds, const int *endCellIds) const; + MEDCOUPLING_EXPORT void renumberValuesOnNodes(double epsOnVals, const int *old2New, int newNbOfNodes, DataArrayDouble *arr) const; + MEDCOUPLING_EXPORT void renumberValuesOnCells(double epsOnVals, const MEDCouplingMesh *mesh, const int *old2New, int newSz, DataArrayDouble *arr) const; + MEDCOUPLING_EXPORT void renumberValuesOnCellsR(const MEDCouplingMesh *mesh, const int *new2old, int newSz, DataArrayDouble *arr) const; + public: + MEDCOUPLING_EXPORT void getValueOnPos(const DataArrayDouble *arr, const MEDCouplingMesh *mesh, int i, int j, int k, double *res) const; + }; + + class MEDCouplingFieldDiscretizationP1 : public MEDCouplingFieldDiscretizationOnNodes + { + public: + MEDCOUPLING_EXPORT TypeOfField getEnum() const; + MEDCOUPLING_EXPORT MEDCouplingFieldDiscretization *clone() const; + MEDCOUPLING_EXPORT std::string getStringRepr() const; + MEDCOUPLING_EXPORT const char *getRepr() const; + MEDCOUPLING_EXPORT void checkCompatibilityWithNature(NatureOfField nat) const; + MEDCOUPLING_EXPORT bool isEqualIfNotWhy(const MEDCouplingFieldDiscretization *other, double eps, std::string& reason) const; + MEDCOUPLING_EXPORT MEDCouplingFieldDouble *getMeasureField(const MEDCouplingMesh *mesh, bool isAbs) const; + MEDCOUPLING_EXPORT void getValueOn(const DataArrayDouble *arr, const MEDCouplingMesh *mesh, const double *loc, double *res) const; + MEDCOUPLING_EXPORT DataArrayDouble *getValueOnMulti(const DataArrayDouble *arr, const MEDCouplingMesh *mesh, const double *loc, int nbOfPoints) const; + MEDCOUPLING_EXPORT void reprQuickOverview(std::ostream& stream) const; + public: + static const char REPR[]; + static const TypeOfField TYPE; + protected: + MEDCOUPLING_EXPORT void getValueInCell(const MEDCouplingMesh *mesh, int cellId, const DataArrayDouble *arr, const double *loc, double *res) const; + }; + + /*! + * This class abstracts MEDCouplingFieldDiscretization that needs an information on each cell to perform their job. + * All classes that inherits from this are more linked to mesh. + */ + class MEDCouplingFieldDiscretizationPerCell : public MEDCouplingFieldDiscretization + { + public: + MEDCOUPLING_EXPORT const DataArrayInt *getArrayOfDiscIds() const; + MEDCOUPLING_EXPORT void setArrayOfDiscIds(const DataArrayInt *adids); + MEDCOUPLING_EXPORT void checkNoOrphanCells() const; + MEDCOUPLING_EXPORT std::vector<DataArrayInt *> splitIntoSingleGaussDicrPerCellType(std::vector< int >& locIds) const; + 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; + std::size_t getHeapMemorySizeWithoutChildren() const; + std::vector<const BigMemoryObject *> getDirectChildrenWithNull() const; + void checkCoherencyBetween(const MEDCouplingMesh *mesh, const DataArray *da) const; + 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); + protected: + void buildDiscrPerCellIfNecessary(const MEDCouplingMesh *mesh); + protected: + DataArrayInt *_discr_per_cell; + static const int DFT_INVALID_LOCID_VALUE; + }; + + class MEDCouplingFieldDiscretizationGauss : public MEDCouplingFieldDiscretizationPerCell + { + public: + MEDCOUPLING_EXPORT MEDCouplingFieldDiscretizationGauss(); + MEDCOUPLING_EXPORT TypeOfField getEnum() const; + MEDCOUPLING_EXPORT bool isEqualIfNotWhy(const MEDCouplingFieldDiscretization *other, double eps, std::string& reason) const; + MEDCOUPLING_EXPORT bool isEqualWithoutConsideringStr(const MEDCouplingFieldDiscretization *other, double eps) const; + MEDCOUPLING_EXPORT MEDCouplingFieldDiscretization *clone() const; + MEDCOUPLING_EXPORT MEDCouplingFieldDiscretization *clonePart(const int *startCellIds, const int *endCellIds) const; + MEDCOUPLING_EXPORT MEDCouplingFieldDiscretization *clonePartRange(int beginCellIds, int endCellIds, int stepCellIds) const; + MEDCOUPLING_EXPORT std::string getStringRepr() const; + MEDCOUPLING_EXPORT const char *getRepr() const; + MEDCOUPLING_EXPORT std::size_t getHeapMemorySizeWithoutChildren() const; + MEDCOUPLING_EXPORT int getNumberOfTuplesExpectedRegardingCode(const std::vector<int>& code, const std::vector<const DataArrayInt *>& idsPerType) const; + MEDCOUPLING_EXPORT int getNumberOfTuples(const MEDCouplingMesh *mesh) const; + MEDCOUPLING_EXPORT int getNumberOfMeshPlaces(const MEDCouplingMesh *mesh) const; + MEDCOUPLING_EXPORT DataArrayInt *getOffsetArr(const MEDCouplingMesh *mesh) const; + MEDCOUPLING_EXPORT void renumberArraysForCell(const MEDCouplingMesh *mesh, const std::vector<DataArray *>& arrays, + const int *old2NewBg, bool check); + MEDCOUPLING_EXPORT DataArrayDouble *getLocalizationOfDiscValues(const MEDCouplingMesh *mesh) const; + MEDCOUPLING_EXPORT void computeMeshRestrictionFromTupleIds(const MEDCouplingMesh *mesh, const int *tupleIdsBg, const int *tupleIdsEnd, + DataArrayInt *&cellRestriction, DataArrayInt *&trueTupleRestriction) const; + MEDCOUPLING_EXPORT void checkCompatibilityWithNature(NatureOfField nat) const; + MEDCOUPLING_EXPORT void getTinySerializationIntInformation(std::vector<int>& tinyInfo) const; + MEDCOUPLING_EXPORT void getTinySerializationDbleInformation(std::vector<double>& tinyInfo) const; + MEDCOUPLING_EXPORT void finishUnserialization(const std::vector<double>& tinyInfo); + MEDCOUPLING_EXPORT void getSerializationIntArray(DataArrayInt *& arr) const; + MEDCOUPLING_EXPORT void resizeForUnserialization(const std::vector<int>& tinyInfo, DataArrayInt *& arr); + MEDCOUPLING_EXPORT void checkForUnserialization(const std::vector<int>& tinyInfo, const DataArrayInt *arr); + MEDCOUPLING_EXPORT double getIJK(const MEDCouplingMesh *mesh, const DataArrayDouble *da, int cellId, int nodeIdInCell, int compoId) const; + MEDCOUPLING_EXPORT void checkCoherencyBetween(const MEDCouplingMesh *mesh, const DataArray *da) const; + MEDCOUPLING_EXPORT MEDCouplingFieldDouble *getMeasureField(const MEDCouplingMesh *mesh, bool isAbs) const; + MEDCOUPLING_EXPORT void getValueOn(const DataArrayDouble *arr, const MEDCouplingMesh *mesh, const double *loc, double *res) const; + MEDCOUPLING_EXPORT void getValueOnPos(const DataArrayDouble *arr, const MEDCouplingMesh *mesh, int i, int j, int k, double *res) const; + MEDCOUPLING_EXPORT DataArrayDouble *getValueOnMulti(const DataArrayDouble *arr, const MEDCouplingMesh *mesh, const double *loc, int nbOfPoints) const; + MEDCOUPLING_EXPORT MEDCouplingMesh *buildSubMeshData(const MEDCouplingMesh *mesh, const int *start, const int *end, DataArrayInt *&di) const; + MEDCOUPLING_EXPORT MEDCouplingMesh *buildSubMeshDataRange(const MEDCouplingMesh *mesh, int beginCellIds, int endCellIds, int stepCellIds, int& beginOut, int& endOut, int& stepOut, DataArrayInt *&di) const; + MEDCOUPLING_EXPORT DataArrayInt *computeTupleIdsToSelectFromCellIds(const MEDCouplingMesh *mesh, const int *startCellIds, const int *endCellIds) const; + MEDCOUPLING_EXPORT void renumberValuesOnNodes(double epsOnVals, const int *old2New, int newNbOfNodes, DataArrayDouble *arr) const; + MEDCOUPLING_EXPORT void renumberValuesOnCells(double epsOnVals, const MEDCouplingMesh *mesh, const int *old2New, int newSz, DataArrayDouble *arr) const; + MEDCOUPLING_EXPORT void renumberValuesOnCellsR(const MEDCouplingMesh *mesh, const int *new2old, int newSz, DataArrayDouble *arr) const; + MEDCOUPLING_EXPORT void setGaussLocalizationOnType(const MEDCouplingMesh *mesh, INTERP_KERNEL::NormalizedCellType type, const std::vector<double>& refCoo, + const std::vector<double>& gsCoo, const std::vector<double>& wg); + MEDCOUPLING_EXPORT void setGaussLocalizationOnCells(const MEDCouplingMesh *mesh, const int *begin, const int *end, const std::vector<double>& refCoo, + const std::vector<double>& gsCoo, const std::vector<double>& wg); + MEDCOUPLING_EXPORT void clearGaussLocalizations(); + MEDCOUPLING_EXPORT void setGaussLocalization(int locId, const MEDCouplingGaussLocalization& loc); + MEDCOUPLING_EXPORT void resizeLocalizationVector(int newSz); + MEDCOUPLING_EXPORT MEDCouplingGaussLocalization& getGaussLocalization(int locId); + MEDCOUPLING_EXPORT int getNbOfGaussLocalization() const; + MEDCOUPLING_EXPORT int getGaussLocalizationIdOfOneCell(int cellId) const; + MEDCOUPLING_EXPORT int getGaussLocalizationIdOfOneType(INTERP_KERNEL::NormalizedCellType type) const; + MEDCOUPLING_EXPORT std::set<int> getGaussLocalizationIdsOfOneType(INTERP_KERNEL::NormalizedCellType type) const; + MEDCOUPLING_EXPORT void getCellIdsHavingGaussLocalization(int locId, std::vector<int>& cellIds) const; + MEDCOUPLING_EXPORT const MEDCouplingGaussLocalization& getGaussLocalization(int locId) const; + MEDCOUPLING_EXPORT DataArrayInt *buildNbOfGaussPointPerCellField() const; + MEDCOUPLING_EXPORT void reprQuickOverview(std::ostream& stream) const; + 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; + void checkLocalizationId(int locId) const; + void commonUnserialization(const std::vector<int>& tinyInfo); + public: + static const char REPR[]; + static const TypeOfField TYPE; + private: + std::vector<MEDCouplingGaussLocalization> _loc; + }; + + /*! + * Gauss with points of values located on nodes of element. This is a specialization of MEDCouplingFieldDiscretizationGauss. + */ + class MEDCouplingFieldDiscretizationGaussNE : public MEDCouplingFieldDiscretization + { + public: + MEDCOUPLING_EXPORT MEDCouplingFieldDiscretizationGaussNE(); + MEDCOUPLING_EXPORT TypeOfField getEnum() const; + MEDCOUPLING_EXPORT MEDCouplingFieldDiscretization *clone() const; + MEDCOUPLING_EXPORT std::string getStringRepr() const; + MEDCOUPLING_EXPORT const char *getRepr() const; + MEDCOUPLING_EXPORT bool isEqualIfNotWhy(const MEDCouplingFieldDiscretization *other, double eps, std::string& reason) const; + MEDCOUPLING_EXPORT int getNumberOfTuplesExpectedRegardingCode(const std::vector<int>& code, const std::vector<const DataArrayInt *>& idsPerType) const; + MEDCOUPLING_EXPORT int getNumberOfTuples(const MEDCouplingMesh *mesh) const; + MEDCOUPLING_EXPORT int getNumberOfMeshPlaces(const MEDCouplingMesh *mesh) const; + MEDCOUPLING_EXPORT DataArrayInt *getOffsetArr(const MEDCouplingMesh *mesh) const; + MEDCOUPLING_EXPORT void renumberArraysForCell(const MEDCouplingMesh *mesh, const std::vector<DataArray *>& arrays, + const int *old2NewBg, bool check); + MEDCOUPLING_EXPORT DataArrayDouble *getLocalizationOfDiscValues(const MEDCouplingMesh *mesh) const; + MEDCOUPLING_EXPORT void integral(const MEDCouplingMesh *mesh, const DataArrayDouble *arr, bool isWAbs, double *res) const; + MEDCOUPLING_EXPORT void computeMeshRestrictionFromTupleIds(const MEDCouplingMesh *mesh, const int *tupleIdsBg, const int *tupleIdsEnd, + DataArrayInt *&cellRestriction, DataArrayInt *&trueTupleRestriction) const; + MEDCOUPLING_EXPORT void checkCompatibilityWithNature(NatureOfField nat) const; + MEDCOUPLING_EXPORT double getIJK(const MEDCouplingMesh *mesh, const DataArrayDouble *da, int cellId, int nodeIdInCell, int compoId) const; + MEDCOUPLING_EXPORT void checkCoherencyBetween(const MEDCouplingMesh *mesh, const DataArray *da) const; + MEDCOUPLING_EXPORT MEDCouplingFieldDouble *getMeasureField(const MEDCouplingMesh *mesh, bool isAbs) const; + MEDCOUPLING_EXPORT void getValueOn(const DataArrayDouble *arr, const MEDCouplingMesh *mesh, const double *loc, double *res) const; + MEDCOUPLING_EXPORT void getValueOnPos(const DataArrayDouble *arr, const MEDCouplingMesh *mesh, int i, int j, int k, double *res) const; + MEDCOUPLING_EXPORT DataArrayDouble *getValueOnMulti(const DataArrayDouble *arr, const MEDCouplingMesh *mesh, const double *loc, int nbOfPoints) const; + MEDCOUPLING_EXPORT MEDCouplingMesh *buildSubMeshData(const MEDCouplingMesh *mesh, const int *start, const int *end, DataArrayInt *&di) const; + MEDCOUPLING_EXPORT MEDCouplingMesh *buildSubMeshDataRange(const MEDCouplingMesh *mesh, int beginCellIds, int endCellIds, int stepCellIds, int& beginOut, int& endOut, int& stepOut, DataArrayInt *&di) const; + MEDCOUPLING_EXPORT DataArrayInt *computeTupleIdsToSelectFromCellIds(const MEDCouplingMesh *mesh, const int *startCellIds, const int *endCellIds) const; + MEDCOUPLING_EXPORT void renumberValuesOnNodes(double epsOnVals, const int *old2New, int newNbOfNodes, DataArrayDouble *arr) const; + MEDCOUPLING_EXPORT void renumberValuesOnCells(double epsOnVals, const MEDCouplingMesh *mesh, const int *old2New, int newSz, DataArrayDouble *arr) const; + MEDCOUPLING_EXPORT void renumberValuesOnCellsR(const MEDCouplingMesh *mesh, const int *new2old, int newSz, DataArrayDouble *arr) const; + MEDCOUPLING_EXPORT void reprQuickOverview(std::ostream& stream) const; + MEDCOUPLING_EXPORT static const double *GetWeightArrayFromGeometricType(INTERP_KERNEL::NormalizedCellType geoType, std::size_t& lgth); + MEDCOUPLING_EXPORT static const double *GetRefCoordsFromGeometricType(INTERP_KERNEL::NormalizedCellType geoType, std::size_t& lgth); + MEDCOUPLING_EXPORT static const double *GetLocsFromGeometricType(INTERP_KERNEL::NormalizedCellType geoType, std::size_t& lgth); + protected: + MEDCOUPLING_EXPORT MEDCouplingFieldDiscretizationGaussNE(const MEDCouplingFieldDiscretizationGaussNE& other); + public: + static const char REPR[]; + static const TypeOfField TYPE; + static const double FGP_POINT1[1]; + 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];//to check + static const double FGP_PENTA6[6]; + static const double FGP_PENTA15[15];//to check + static const double FGP_HEXA8[8]; + static const double FGP_HEXA20[20];//to check + static const double FGP_HEXA27[27]; + static const double FGP_PYRA5[5]; + static const double FGP_PYRA13[13];//to check + 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]; + static const double LOC_SEG2[2]; + static const double LOC_SEG3[3]; + static const double LOC_SEG4[4]; + static const double LOC_TRI3[6]; + static const double LOC_TRI6[12]; + static const double LOC_TRI7[14]; + static const double LOC_QUAD4[8]; + static const double LOC_QUAD8[16]; + static const double LOC_QUAD9[18]; + static const double LOC_TETRA4[12]; + static const double LOC_TETRA10[30];//to check + static const double LOC_PENTA6[18]; + static const double LOC_PENTA15[45];//to check + static const double LOC_HEXA8[24]; + static const double LOC_HEXA20[60];//to check + static const double LOC_HEXA27[81]; + static const double LOC_PYRA5[15]; + static const double LOC_PYRA13[39];//to check + }; + + class MEDCouplingFieldDiscretizationKriging : public MEDCouplingFieldDiscretizationOnNodes + { + public: + MEDCOUPLING_EXPORT TypeOfField getEnum() const; + MEDCOUPLING_EXPORT const char *getRepr() const; + MEDCOUPLING_EXPORT MEDCouplingFieldDiscretization *clone() const; + MEDCOUPLING_EXPORT std::string getStringRepr() const; + MEDCOUPLING_EXPORT void checkCompatibilityWithNature(NatureOfField nat) const; + MEDCOUPLING_EXPORT bool isEqualIfNotWhy(const MEDCouplingFieldDiscretization *other, double eps, std::string& reason) const; + MEDCOUPLING_EXPORT MEDCouplingFieldDouble *getMeasureField(const MEDCouplingMesh *mesh, bool isAbs) const; + MEDCOUPLING_EXPORT void getValueOn(const DataArrayDouble *arr, const MEDCouplingMesh *mesh, const double *loc, double *res) const; + MEDCOUPLING_EXPORT DataArrayDouble *getValueOnMulti(const DataArrayDouble *arr, const MEDCouplingMesh *mesh, const double *loc, int nbOfPoints) const; + MEDCOUPLING_EXPORT void reprQuickOverview(std::ostream& stream) const; + public://specific part + MEDCOUPLING_EXPORT DataArrayDouble *computeEvaluationMatrixOnGivenPts(const MEDCouplingMesh *mesh, const double *loc, int nbOfTargetPoints, int& nbCols) const; + MEDCOUPLING_EXPORT DataArrayDouble *computeInverseMatrix(const MEDCouplingMesh *mesh, int& isDrift, int& matSz) const; + MEDCOUPLING_EXPORT DataArrayDouble *computeMatrix(const MEDCouplingMesh *mesh, int& isDrift, int& matSz) const; + MEDCOUPLING_EXPORT DataArrayDouble *computeVectorOfCoefficients(const MEDCouplingMesh *mesh, const DataArrayDouble *arr, int& isDrift) const; + MEDCOUPLING_EXPORT void operateOnDenseMatrix(int spaceDimension, int nbOfElems, double *matrixPtr) const; + MEDCOUPLING_EXPORT DataArrayDouble *performDrift(const DataArrayDouble *matr, const DataArrayDouble *arr, int& delta) const; + MEDCOUPLING_EXPORT static void OperateOnDenseMatrixH3(int nbOfElems, double *matrixPtr); + MEDCOUPLING_EXPORT static void OperateOnDenseMatrixH2Ln(int nbOfElems, double *matrixPtr); + MEDCOUPLING_EXPORT static DataArrayDouble *PerformDriftRect(const DataArrayDouble *matr, const DataArrayDouble *arr, int& delta); + MEDCOUPLING_EXPORT static DataArrayDouble *PerformDriftOfVec(const DataArrayDouble *arr, int isDrift); + public: + static const char REPR[]; + static const TypeOfField TYPE; + }; +} + +#endif diff --git a/src/medtool/src/MEDCoupling/MEDCouplingFieldDouble.cxx b/src/medtool/src/MEDCoupling/MEDCouplingFieldDouble.cxx new file mode 100644 index 000000000..23d1314c6 --- /dev/null +++ b/src/medtool/src/MEDCoupling/MEDCouplingFieldDouble.cxx @@ -0,0 +1,3356 @@ +// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 +// 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 "MEDCouplingFieldDouble.hxx" +#include "MEDCouplingFieldTemplate.hxx" +#include "MEDCouplingUMesh.hxx" +#include "MEDCouplingTimeDiscretization.hxx" +#include "MEDCouplingFieldDiscretization.hxx" +#include "MEDCouplingAutoRefCountObjectPtr.hxx" +#include "MEDCouplingNatureOfField.hxx" + +#include "InterpKernelAutoPtr.hxx" + +#include <sstream> +#include <limits> +#include <algorithm> +#include <functional> + +using namespace ParaMEDMEM; + + +/*! + * 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); +} + +/*! + * 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 std::string& unit) +{ + _time_discr->setTimeUnit(unit); +} + +/*! + * Returns a time unit of \a this field. + * \return a string describing units in which time is measured. + */ +std::string MEDCouplingFieldDouble::getTimeUnit() const +{ + return _time_discr->getTimeUnit(); +} + +/*! + * This method if possible the time information (time unit, time iteration, time unit and time value) with its support + * that is to say its mesh. + * + * \throw If \c this->_mesh is null an exception will be thrown. An exception will also be throw if the spatial discretization is + * NO_TIME. + */ +void MEDCouplingFieldDouble::synchronizeTimeWithSupport() +{ + _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". + * + * \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 +{ + return new MEDCouplingFieldDouble(*this,recDeepCpy); +} + +/*! + * 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". + * + * 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 +{ + MEDCouplingAutoRefCountObjectPtr<MEDCouplingFieldDouble> ret=clone(recDeepCpy); + if(_mesh) + { + MEDCouplingAutoRefCountObjectPtr<MEDCouplingMesh> mCpy=_mesh->deepCpy(); + ret->setMesh(mCpy); + } + return ret.retn(); +} + +/*! + * 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. + * + * \if ENABLE_EXAMPLES + * \ref cpp_mcfielddouble_buildNewTimeReprFromThis "Here is a C++ example."<br> + * \ref py_mcfielddouble_buildNewTimeReprFromThis "Here is a Python example." + * \endif + * \sa clone() + */ +MEDCouplingFieldDouble *MEDCouplingFieldDouble::buildNewTimeReprFromThis(TypeOfTimeDiscretization td, bool deepCopy) const +{ + MEDCouplingTimeDiscretization *tdo=_time_discr->buildNewTimeReprFromThis(td,deepCopy); + MEDCouplingAutoRefCountObjectPtr<MEDCouplingFieldDiscretization> disc; + if(_type) + disc=_type->clone(); + MEDCouplingAutoRefCountObjectPtr<MEDCouplingFieldDouble> ret=new MEDCouplingFieldDouble(getNature(),tdo,disc.retn()); + ret->setMesh(getMesh()); + ret->setName(getName()); + ret->setDescription(getDescription()); + return ret.retn(); +} + +/*! + * This method converts a field on nodes (\a this) to a cell field (returned field). The convertion is a \b non \b conservative remapping ! + * This method is useful only for users that need a fast convertion from node to cell spatial discretization. The algorithm applied is simply to attach + * to each cell the average of values on nodes constituting this cell. + * + * \return MEDCouplingFieldDouble* - a new instance of MEDCouplingFieldDouble. The + * caller is to delete this field using decrRef() as it is no more needed. The returned field will share the same mesh object object than those in \a this. + * \throw If \a this spatial discretization is empty or not ON_NODES. + * \throw If \a this is not coherent (see MEDCouplingFieldDouble::checkCoherency). + * + * \warning This method is a \b non \b conservative method of remapping from node spatial discretization to cell spatial discretization. + * If a conservative method of interpolation is required ParaMEDMEM::MEDCouplingRemapper class should be used instead with "P1P0" method. + */ +MEDCouplingFieldDouble *MEDCouplingFieldDouble::nodeToCellDiscretization() const +{ + checkCoherency(); + TypeOfField tf(getTypeOfField()); + if(tf!=ON_NODES) + throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::nodeToCellDiscretization : this field is expected to be on ON_NODES !"); + MEDCouplingAutoRefCountObjectPtr<MEDCouplingFieldDouble> ret(clone(false)); + MEDCouplingAutoRefCountObjectPtr<MEDCouplingFieldDiscretizationP0> nsp(new MEDCouplingFieldDiscretizationP0); + ret->setDiscretization(nsp); + const MEDCouplingMesh *m(getMesh());//m is non empty thanks to checkCoherency call + int nbCells(m->getNumberOfCells()); + std::vector<DataArrayDouble *> arrs(getArrays()); + std::size_t sz(arrs.size()); + std::vector< MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> > outArrsSafe(sz); std::vector<DataArrayDouble *> outArrs(sz); + for(std::size_t j=0;j<sz;j++) + { + int nbCompo(arrs[j]->getNumberOfComponents()); + outArrsSafe[j]=DataArrayDouble::New(); outArrsSafe[j]->alloc(nbCells,nbCompo); + outArrsSafe[j]->copyStringInfoFrom(*arrs[j]); + outArrs[j]=outArrsSafe[j]; + double *pt(outArrsSafe[j]->getPointer()); + const double *srcPt(arrs[j]->begin()); + for(int i=0;i<nbCells;i++,pt+=nbCompo) + { + std::vector<int> nodeIds; + m->getNodeIdsOfCell(i,nodeIds); + std::fill(pt,pt+nbCompo,0.); + std::size_t nbNodesInCell(nodeIds.size()); + for(std::size_t k=0;k<nbNodesInCell;k++) + std::transform(srcPt+nodeIds[k]*nbCompo,srcPt+(nodeIds[k]+1)*nbCompo,pt,pt,std::plus<double>()); + if(nbNodesInCell!=0) + std::transform(pt,pt+nbCompo,pt,std::bind2nd(std::multiplies<double>(),1./((double)nbNodesInCell))); + else + { + std::ostringstream oss; oss << "MEDCouplingFieldDouble::nodeToCellDiscretization : Cell id #" << i << " has been detected to have no nodes !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + } + } + ret->setArrays(outArrs); + return ret.retn(); +} + +/*! + * This method converts a field on cell (\a this) to a node field (returned field). The convertion is a \b non \b conservative remapping ! + * This method is useful only for users that need a fast convertion from cell to node spatial discretization. The algorithm applied is simply to attach + * to each node the average of values on cell sharing this node. If \a this lies on a mesh having orphan nodes the values applied on them will be NaN (division by 0.). + * + * \return MEDCouplingFieldDouble* - a new instance of MEDCouplingFieldDouble. The + * caller is to delete this field using decrRef() as it is no more needed. The returned field will share the same mesh object object than those in \a this. + * \throw If \a this spatial discretization is empty or not ON_CELLS. + * \throw If \a this is not coherent (see MEDCouplingFieldDouble::checkCoherency). + * + * \warning This method is a \b non \b conservative method of remapping from cell spatial discretization to node spatial discretization. + * If a conservative method of interpolation is required ParaMEDMEM::MEDCouplingRemapper class should be used instead with "P0P1" method. + */ +MEDCouplingFieldDouble *MEDCouplingFieldDouble::cellToNodeDiscretization() const +{ + checkCoherency(); + TypeOfField tf(getTypeOfField()); + if(tf!=ON_CELLS) + throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::cellToNodeDiscretization : this field is expected to be on ON_CELLS !"); + MEDCouplingAutoRefCountObjectPtr<MEDCouplingFieldDouble> ret(clone(false)); + MEDCouplingAutoRefCountObjectPtr<MEDCouplingFieldDiscretizationP1> nsp(new MEDCouplingFieldDiscretizationP1); + ret->setDiscretization(nsp); + const MEDCouplingMesh *m(getMesh());//m is non empty thanks to checkCoherency call + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> rn(DataArrayInt::New()),rni(DataArrayInt::New()); + m->getReverseNodalConnectivity(rn,rni); + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> rni2(rni->deltaShiftIndex()); + MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> rni3(rni2->convertToDblArr()); rni2=0; + std::vector<DataArrayDouble *> arrs(getArrays()); + std::size_t sz(arrs.size()); + std::vector< MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> > outArrsSafe(sz); std::vector<DataArrayDouble *> outArrs(sz); + for(std::size_t j=0;j<sz;j++) + { + MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> tmp(arrs[j]->selectByTupleIdSafe(rn->begin(),rn->end())); + outArrsSafe[j]=(tmp->accumulatePerChunck(rni->begin(),rni->end())); tmp=0; + outArrsSafe[j]->divideEqual(rni3); + outArrsSafe[j]->copyStringInfoFrom(*arrs[j]); + outArrs[j]=outArrsSafe[j]; + } + ret->setArrays(outArrs); + return ret.retn(); +} + +/*! + * 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 MEDCouplingField *other) +{ + MEDCouplingField::copyTinyStringsFrom(other); + const MEDCouplingFieldDouble *otherC=dynamic_cast<const MEDCouplingFieldDouble *>(other); + if(otherC) + { + _time_discr->copyTinyStringsFrom(*otherC->_time_discr); + } +} + +/*! + * 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) +{ + if(other) + { + _time_discr->copyTinyAttrFrom(*other->_time_discr); + } +} + +void MEDCouplingFieldDouble::copyAllTinyAttrFrom(const MEDCouplingFieldDouble *other) +{ + 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"; + 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()) + { + 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;i<nbOfCompo;i++) + ret << "\"" << getArray()->getInfoOnComponent(i) << "\" "; + ret << "\n"; + } + else + { + ret << "Array set but not allocated !\n"; + } + } + if(_mesh) + ret << "Mesh support information :\n__________________________\n" << _mesh->simpleRepr(); + else + ret << "Mesh support information : No mesh set !\n"; + 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"; + 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) + ret << "Mesh support information :\n__________________________\n" << _mesh->advancedRepr(); + else + ret << "Mesh support information : No mesh set !\n"; + std::vector<DataArrayDouble *> arrays; + _time_discr->getArrays(arrays); + int arrayId=0; + for(std::vector<DataArrayDouble *>::const_iterator iter=arrays.begin();iter!=arrays.end();iter++,arrayId++) + { + ret << "Array #" << arrayId << " :\n__________\n"; + if(*iter) + (*iter)->reprWithoutNameStream(ret); + else + ret << "Array empty !"; + ret << "\n"; + } + return ret.str(); +} + +std::string MEDCouplingFieldDouble::writeVTK(const std::string& fileName, bool isBinary) const +{ + std::vector<const MEDCouplingFieldDouble *> fs(1,this); + return MEDCouplingFieldDouble::WriteVTK(fileName,fs,isBinary); +} + +bool MEDCouplingFieldDouble::isEqualIfNotWhy(const MEDCouplingField *other, double meshPrec, double valsPrec, std::string& reason) const +{ + if(!other) + throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::isEqualIfNotWhy : other instance is NULL !"); + const MEDCouplingFieldDouble *otherC=dynamic_cast<const MEDCouplingFieldDouble *>(other); + if(!otherC) + { + reason="field given in input is not castable in MEDCouplingFieldDouble !"; + return false; + } + if(!MEDCouplingField::isEqualIfNotWhy(other,meshPrec,valsPrec,reason)) + return false; + if(!_time_discr->isEqualIfNotWhy(otherC->_time_discr,valsPrec,reason)) + { + reason.insert(0,"In FieldDouble time discretizations differ :"); + return false; + } + 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<const MEDCouplingFieldDouble *>(other); + if(!otherC) + return false; + if(!MEDCouplingField::isEqualWithoutConsideringStr(other,meshPrec,valsPrec)) + return false; + if(!_time_discr->isEqualWithoutConsideringStr(otherC->_time_discr,valsPrec)) + return false; + return true; +} + +/*! + * This method states if \a this and 'other' are compatibles each other before performing any treatment. + * This method is good for methods like : mergeFields. + * This method is not very demanding compared to areStrictlyCompatible that is better for operation on fields. + */ +bool MEDCouplingFieldDouble::areCompatibleForMerge(const MEDCouplingField *other) const +{ + if(!MEDCouplingField::areCompatibleForMerge(other)) + return false; + const MEDCouplingFieldDouble *otherC=dynamic_cast<const MEDCouplingFieldDouble *>(other); + if(!otherC) + return false; + if(!_time_discr->areCompatible(otherC->_time_discr)) + return false; + return true; +} + +/*! + * This method is more strict than MEDCouplingField::areCompatibleForMerge method. + * This method is used for operation on fields to operate a first check before attempting operation. + */ +bool MEDCouplingFieldDouble::areStrictlyCompatible(const MEDCouplingField *other) const +{ + std::string tmp; + if(!MEDCouplingField::areStrictlyCompatible(other)) + return false; + const MEDCouplingFieldDouble *otherC=dynamic_cast<const MEDCouplingFieldDouble *>(other); + if(!otherC) + return false; + if(!_time_discr->areStrictlyCompatible(otherC->_time_discr,tmp)) + return false; + return true; +} + +/*! + * Method with same principle than MEDCouplingFieldDouble::areStrictlyCompatibleForMulDiv method except that + * number of components between \a this and 'other' can be different here (for operator*). + */ +bool MEDCouplingFieldDouble::areCompatibleForMul(const MEDCouplingField *other) const +{ + if(!MEDCouplingField::areStrictlyCompatibleForMulDiv(other)) + return false; + const MEDCouplingFieldDouble *otherC=dynamic_cast<const MEDCouplingFieldDouble *>(other); + if(!otherC) + return false; + if(!_time_discr->areStrictlyCompatibleForMul(otherC->_time_discr)) + return false; + return true; +} + +/*! + * Method with same principle than MEDCouplingFieldDouble::areStrictlyCompatibleForMulDiv method except that + * number of components between \a this and 'other' can be different here (for operator/). + */ +bool MEDCouplingFieldDouble::areCompatibleForDiv(const MEDCouplingField *other) const +{ + if(!MEDCouplingField::areStrictlyCompatibleForMulDiv(other)) + return false; + const MEDCouplingFieldDouble *otherC=dynamic_cast<const MEDCouplingFieldDouble *>(other); + if(!otherC) + return false; + if(!_time_discr->areStrictlyCompatibleForDiv(otherC->_time_discr)) + return false; + return true; +} + +/*! + * This method is invocated before any attempt of melding. This method is very close to areStrictlyCompatible, + * except that \a this and other can have different number of components. + */ +bool MEDCouplingFieldDouble::areCompatibleForMeld(const MEDCouplingFieldDouble *other) const +{ + if(!MEDCouplingField::areStrictlyCompatible(other)) + return false; + if(!_time_discr->areCompatibleForMeld(other->_time_discr)) + return false; + return true; +} + +/*! + * 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. + * ** Warning, this method modifies the mesh aggreagated by \a this (by performing a deep copy ) **. + * + * \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). + * + * \if ENABLE_EXAMPLES + * \ref cpp_mcfielddouble_renumberCells "Here is a C++ example".<br> + * \ref py_mcfielddouble_renumberCells "Here is a Python example". + * \endif + */ +void MEDCouplingFieldDouble::renumberCells(const int *old2NewBg, bool check) +{ + renumberCellsWithoutMesh(old2NewBg,check); + MEDCouplingAutoRefCountObjectPtr<MEDCouplingMesh> m=_mesh->deepCpy(); + m->renumberCells(old2NewBg,check); + setMesh(m); + updateTime(); +} + +/*! + * 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) +{ + if(!_mesh) + 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<DataArrayDouble *> arrays; + _time_discr->getArrays(arrays); + std::vector<DataArray *> arrays2(arrays.size()); std::copy(arrays.begin(),arrays.end(),arrays2.begin()); + _type->renumberArraysForCell(_mesh,arrays2,old2NewBg,check); + // + updateTime(); +} + +/*! + * 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. + * + * \if ENABLE_EXAMPLES + * \ref cpp_mcfielddouble_renumberNodes "Here is a C++ example".<br> + * \ref py_mcfielddouble_renumberNodes "Here is a Python example". + * \endif + */ +void MEDCouplingFieldDouble::renumberNodes(const int *old2NewBg, double eps) +{ + const MEDCouplingPointSet *meshC=dynamic_cast<const MEDCouplingPointSet *>(_mesh); + if(!meshC) + throw INTERP_KERNEL::Exception("Invalid mesh to apply renumberNodes on it !"); + int nbOfNodes=meshC->getNumberOfNodes(); + MEDCouplingAutoRefCountObjectPtr<MEDCouplingPointSet> meshC2((MEDCouplingPointSet *)meshC->deepCpy()); + int newNbOfNodes=*std::max_element(old2NewBg,old2NewBg+nbOfNodes)+1; + renumberNodesWithoutMesh(old2NewBg,newNbOfNodes,eps); + meshC2->renumberNodes(old2NewBg,newNbOfNodes); + setMesh(meshC2); +} + +/*! + * 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) +{ + if(!((const MEDCouplingFieldDiscretization *)_type)) + throw INTERP_KERNEL::Exception("Expecting a spatial discretization to be able to operate a renumbering !"); + std::vector<DataArrayDouble *> arrays; + _time_discr->getArrays(arrays); + for(std::vector<DataArrayDouble *>::const_iterator iter=arrays.begin();iter!=arrays.end();iter++) + if(*iter) + _type->renumberValuesOnNodes(eps,old2NewBg,newNbOfNodes,*iter); +} + +/*! + * 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 +{ + if(getArray()==0) + throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::getIdsInRange : no default array set !"); + return getArray()->getIdsInRange(vmin,vmax); +} + +/*! + * 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 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.<br> + * 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().<br> + * 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().<br> + * 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. + * + * \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 ENABLE_EXAMPLES + * \ref cpp_mcfielddouble_subpart1 "Here is a C++ example".<br> + * \ref py_mcfielddouble_subpart1 "Here is a Python example". + * \endif + * \sa MEDCouplingFieldDouble::buildSubPartRange + */ + +MEDCouplingFieldDouble *MEDCouplingFieldDouble::buildSubPart(const DataArrayInt *part) const +{ + if(part==0) + throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::buildSubPart : not empty array must be passed to this method !"); + 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 \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"). + * + * 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(). + * + * 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 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 \a this->getMesh(). + * + * \if ENABLE_EXAMPLES + * \ref cpp_mcfielddouble_subpart1 "Here a C++ example."<br> + * \ref py_mcfielddouble_subpart1 "Here a Python example." + * \endif + * \sa ParaMEDMEM::MEDCouplingFieldDouble::buildSubPart(const DataArrayInt *) const, MEDCouplingFieldDouble::buildSubPartRange + */ +MEDCouplingFieldDouble *MEDCouplingFieldDouble::buildSubPart(const int *partBg, const int *partEnd) const +{ + if(!((const MEDCouplingFieldDiscretization *)_type)) + throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::buildSubPart : Expecting a not NULL spatial discretization !"); + DataArrayInt *arrSelect; + MEDCouplingAutoRefCountObjectPtr<MEDCouplingMesh> m=_type->buildSubMeshData(_mesh,partBg,partEnd,arrSelect); + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> arrSelect2(arrSelect); + MEDCouplingAutoRefCountObjectPtr<MEDCouplingFieldDouble> ret=clone(false);//quick shallow copy. + const MEDCouplingFieldDiscretization *disc=getDiscretization(); + if(disc) + ret->setDiscretization(MEDCouplingAutoRefCountObjectPtr<MEDCouplingFieldDiscretization>(disc->clonePart(partBg,partEnd))); + ret->setMesh(m); + std::vector<DataArrayDouble *> arrays; + _time_discr->getArrays(arrays); + std::vector<DataArrayDouble *> arrs; + std::vector< MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> > arrsSafe; + const int *arrSelBg=arrSelect->begin(); + const int *arrSelEnd=arrSelect->end(); + for(std::vector<DataArrayDouble *>::const_iterator iter=arrays.begin();iter!=arrays.end();iter++) + { + DataArrayDouble *arr=0; + if(*iter) + arr=(*iter)->selectByTupleIdSafe(arrSelBg,arrSelEnd); + arrs.push_back(arr); arrsSafe.push_back(arr); + } + ret->_time_discr->setArrays(arrs,0); + 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 +{ + if(!((const MEDCouplingFieldDiscretization *)_type)) + throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::buildSubPart : Expecting a not NULL spatial discretization !"); + DataArrayInt *arrSelect; + int beginOut,endOut,stepOut; + MEDCouplingAutoRefCountObjectPtr<MEDCouplingMesh> m=_type->buildSubMeshDataRange(_mesh,begin,end,step,beginOut,endOut,stepOut,arrSelect); + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> arrSelect2(arrSelect); + MEDCouplingAutoRefCountObjectPtr<MEDCouplingFieldDouble> ret=clone(false);//quick shallow copy. + const MEDCouplingFieldDiscretization *disc=getDiscretization(); + if(disc) + ret->setDiscretization(MEDCouplingAutoRefCountObjectPtr<MEDCouplingFieldDiscretization>(disc->clonePartRange(begin,end,step))); + ret->setMesh(m); + std::vector<DataArrayDouble *> arrays; + _time_discr->getArrays(arrays); + std::vector<DataArrayDouble *> arrs; + std::vector< MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> > arrsSafe; + for(std::vector<DataArrayDouble *>::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(); +} + +MEDCouplingFieldDouble::MEDCouplingFieldDouble(TypeOfField type, TypeOfTimeDiscretization td):MEDCouplingField(type), + _time_discr(MEDCouplingTimeDiscretization::New(td)) +{ +} + +/*! + * ** 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,deepCopy), + _time_discr(other._time_discr->performCpy(deepCopy)) +{ +} + +MEDCouplingFieldDouble::MEDCouplingFieldDouble(NatureOfField n, MEDCouplingTimeDiscretization *td, MEDCouplingFieldDiscretization *type):MEDCouplingField(type,n),_time_discr(td) +{ +} + +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 +{ + 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()); +} + +/*! + * 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 +{ + if(getArray()==0) + throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::accumulate : no default array defined !"); + return getArray()->accumulate(compId); +} + +/*! + * 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 +{ + if(getArray()==0) + throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::accumulate : no default array defined !"); + getArray()->accumulate(res); +} + +/*! + * 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 +{ + std::vector<DataArrayDouble *> arrays; + _time_discr->getArrays(arrays); + double ret=-std::numeric_limits<double>::max(); + bool isExistingArr=false; + for(std::vector<DataArrayDouble *>::const_iterator iter=arrays.begin();iter!=arrays.end();iter++) + { + if(*iter) + { + isExistingArr=true; + int loc; + ret=std::max(ret,(*iter)->getMaxValue(loc)); + } + } + if(!isExistingArr) + throw INTERP_KERNEL::Exception("getMaxValue : No arrays defined !"); + return ret; +} + +/*! + * 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 +{ + std::vector<DataArrayDouble *> arrays; + _time_discr->getArrays(arrays); + double ret=-std::numeric_limits<double>::max(); + bool isExistingArr=false; + tupleIds=0; + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret1; + for(std::vector<DataArrayDouble *>::const_iterator iter=arrays.begin();iter!=arrays.end();iter++) + { + if(*iter) + { + isExistingArr=true; + DataArrayInt *tmp; + ret=std::max(ret,(*iter)->getMaxValue2(tmp)); + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> tmpSafe(tmp); + if(!((const DataArrayInt *)ret1)) + ret1=tmpSafe; + } + } + if(!isExistingArr) + throw INTERP_KERNEL::Exception("getMaxValue2 : No arrays defined !"); + tupleIds=ret1.retn(); + return ret; +} + +/*! + * 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 +{ + std::vector<DataArrayDouble *> arrays; + _time_discr->getArrays(arrays); + double ret=std::numeric_limits<double>::max(); + bool isExistingArr=false; + for(std::vector<DataArrayDouble *>::const_iterator iter=arrays.begin();iter!=arrays.end();iter++) + { + if(*iter) + { + isExistingArr=true; + int loc; + ret=std::min(ret,(*iter)->getMinValue(loc)); + } + } + if(!isExistingArr) + throw INTERP_KERNEL::Exception("getMinValue : No arrays defined !"); + return ret; +} + +/*! + * 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 +{ + std::vector<DataArrayDouble *> arrays; + _time_discr->getArrays(arrays); + double ret=-std::numeric_limits<double>::max(); + bool isExistingArr=false; + tupleIds=0; + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret1; + for(std::vector<DataArrayDouble *>::const_iterator iter=arrays.begin();iter!=arrays.end();iter++) + { + if(*iter) + { + isExistingArr=true; + DataArrayInt *tmp; + ret=std::max(ret,(*iter)->getMinValue2(tmp)); + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> tmpSafe(tmp); + if(!((const DataArrayInt *)ret1)) + ret1=tmpSafe; + } + } + if(!isExistingArr) + throw INTERP_KERNEL::Exception("getMinValue2 : No arrays defined !"); + tupleIds=ret1.retn(); + return ret; +} + +/*! + * 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 +{ + if(getArray()==0) + throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::getAverageValue : no default array defined !"); + return getArray()->getAverageValue(); +} + +/*! + * This method returns the euclidean norm of \a this field. + * \f[ + * \sqrt{\sum_{0 \leq i < nbOfEntity}val[i]*val[i]} + * \f] + * \throw If the data array is not set. + */ +double MEDCouplingFieldDouble::norm2() const +{ + if(getArray()==0) + throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::norm2 : no default array defined !"); + return getArray()->norm2(); +} + +/*! + * This method returns the max norm of \a this field. + * \f[ + * \max_{0 \leq i < nbOfEntity}{abs(val[i])} + * \f] + * \throw If the data array is not set. + */ +double MEDCouplingFieldDouble::normMax() const +{ + if(getArray()==0) + throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::normMax : no default array defined !"); + return getArray()->normMax(); +} + +/*! + * Computes the weighted average of values of each component of \a this field, the weights being the + * 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 weights computed by + * buildMeasureField(). It makes this method slower. If you are sure that all + * the cells of the underlying mesh have a correct orientation (no negative volume), you can put \a isWAbs == + * \c false to speed up the method. + * \throw If the mesh is not set. + * \throw If the data array is not set. + */ +void MEDCouplingFieldDouble::getWeightedAverageValue(double *res, bool isWAbs) const +{ + if(getArray()==0) + throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::getWeightedAverageValue : no default array defined !"); + MEDCouplingAutoRefCountObjectPtr<MEDCouplingFieldDouble> w=buildMeasureField(isWAbs); + double deno=w->getArray()->accumulate(0); + MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> arr=getArray()->deepCpy(); + arr->multiplyEqual(w->getArray()); + arr->accumulate(res); + int nCompo = getArray()->getNumberOfComponents(); + std::transform(res,res+nCompo,res,std::bind2nd(std::multiplies<double>(),1./deno)); +} + +/*! + * Computes the weighted average of values of a given component of \a this field, the weights being the + * 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 weights computed by + * buildMeasureField(). It makes this method slower. If you are sure that all + * the cells of the underlying mesh have a correct orientation (no negative volume), you can put \a isWAbs == + * \c false to speed up the 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 +{ + 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<double> 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] + * \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 +{ + 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 !"); + int nbComps=getArray()->getNumberOfComponents(); + if(compId<0 || compId>=nbComps) + { + 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()); + } + INTERP_KERNEL::AutoPtr<double> res=new double[nbComps]; + _type->normL1(_mesh,getArray(),res); + return res[compId]; +} + +/*! + * 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] + * \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 +{ + 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 \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] + * \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 +{ + 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<0 || compId>=nbComps) + { + 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()); + } + INTERP_KERNEL::AutoPtr<double> res=new double[nbComps]; + _type->normL2(_mesh,getArray(),res); + return res[compId]; +} + +/*! + * 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] + * \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 +{ + 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); +} + +/*! + * 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 +{ + 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<0 || compId>=nbComps) + { + 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()); + } + INTERP_KERNEL::AutoPtr<double> res=new double[nbComps]; + _type->integral(_mesh,getArray(),isWAbs,res); + return res[compId]; +} + +/*! + * 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 +{ + 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); +} + +/*! + * 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. + * + * \if ENABLE_EXAMPLES + * \ref cpp_mcfielddouble_getValueOnPos "Here is a C++ example".<br> + * \ref py_mcfielddouble_getValueOnPos "Here is a Python example". + * \endif + */ +void MEDCouplingFieldDouble::getValueOnPos(int i, int j, int k, double *res) const +{ + 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 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. + * + * \if ENABLE_EXAMPLES + * \ref cpp_mcfielddouble_getValueOn "Here is a C++ example".<br> + * \ref py_mcfielddouble_getValueOn "Here is a Python example". + * \endif + */ +void MEDCouplingFieldDouble::getValueOn(const double *spaceLoc, double *res) const +{ + 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 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. + * + * \if ENABLE_EXAMPLES + * \ref cpp_mcfielddouble_getValueOnMulti "Here is a C++ example".<br> + * \ref py_mcfielddouble_getValueOnMulti "Here is a Python example". + * \endif + */ +DataArrayDouble *MEDCouplingFieldDouble::getValueOnMulti(const double *spaceLoc, int nbOfPoints) const +{ + 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 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. + * + * \if ENABLE_EXAMPLES + * \ref cpp_mcfielddouble_getValueOn_time "Here is a C++ example".<br> + * \ref py_mcfielddouble_getValueOn_time "Here is a Python example". + * \endif + */ +void MEDCouplingFieldDouble::getValueOn(const double *spaceLoc, double time, double *res) const +{ + 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<double> res2; + for(std::vector< const DataArrayDouble *>::const_iterator iter=arrs.begin();iter!=arrs.end();iter++) + { + int sz=(int)res2.size(); + res2.resize(sz+(*iter)->getNumberOfComponents()); + _type->getValueOn(*iter,_mesh,spaceLoc,&res2[sz]); + } + _time_discr->getValueForTime(time,res2,res); +} + +/*! + * Apply a linear function to a given component of \a this field, so that + * a component value <em>(x)</em> 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) +{ + _time_discr->applyLin(a,b,compoId); +} + +/*! + * Apply a linear function to all components of \a this field, so that + * values <em>(x)</em> 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 the data array(s) is(are) not set. + */ +void MEDCouplingFieldDouble::applyLin(double a, double b) +{ + _time_discr->applyLin(a,b); +} + +/*! + * This method sets \a this to a uniform scalar field with one component. + * All tuples will have the same value 'value'. + * An exception is thrown if no underlying mesh is defined. + */ +MEDCouplingFieldDouble &MEDCouplingFieldDouble::operator=(double value) +{ + 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->setOrCreateUniformValueOnAllComponents(nbOfTuple,value); + return *this; +} + +/*! + * 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. + * + * \if ENABLE_EXAMPLES + * \ref cpp_mcfielddouble_fillFromAnalytic_c_func "Here is a C++ example". + * \endif + */ +void MEDCouplingFieldDouble::fillFromAnalytic(int nbOfComp, FunctionToEvaluate func) +{ + 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<DataArrayDouble> loc=_type->getLocalizationOfDiscValues(_mesh); + _time_discr->fillFromAnalytic(loc,nbOfComp,func); +} + +/*! + * Creates data array(s) of \a this field by using a function for value generation.<br> + * 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. <br> + * 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)!<br> + * 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.<br> + * 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. + * + * \if ENABLE_EXAMPLES + * \ref cpp_mcfielddouble_fillFromAnalytic "Here is a C++ example".<br> + * \ref py_mcfielddouble_fillFromAnalytic "Here is a Python example". + * \endif + */ +void MEDCouplingFieldDouble::fillFromAnalytic(int nbOfComp, const std::string& func) +{ + 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<DataArrayDouble> loc=_type->getLocalizationOfDiscValues(_mesh); + _time_discr->fillFromAnalytic(loc,nbOfComp,func); +} + +/*! + * Creates data array(s) of \a this field by using a function for value generation.<br> + * 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.<br> + * This method differs from + * \ref ParaMEDMEM::MEDCouplingFieldDouble::fillFromAnalytic(int nbOfComp, const std::string& 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()).<br> + * For more info on supported expressions that can be used in the function, see \ref + * MEDCouplingArrayApplyFuncExpr. <br> + * 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.<br> + * 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. + * + * \if ENABLE_EXAMPLES + * \ref cpp_mcfielddouble_fillFromAnalytic2 "Here is a C++ example".<br> + * \ref py_mcfielddouble_fillFromAnalytic2 "Here is a Python example". + * \endif + */ +void MEDCouplingFieldDouble::fillFromAnalytic2(int nbOfComp, const std::string& func) +{ + 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<DataArrayDouble> loc=_type->getLocalizationOfDiscValues(_mesh); + _time_discr->fillFromAnalytic2(loc,nbOfComp,func); +} + +/*! + * Creates data array(s) of \a this field by using a function for value generation.<br> + * 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.<br> + * This method differs from + * \ref ParaMEDMEM::MEDCouplingFieldDouble::fillFromAnalytic(int nbOfComp, const std::string& 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.<br> + * 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.<br> + * 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. + * + * \if ENABLE_EXAMPLES + * \ref cpp_mcfielddouble_fillFromAnalytic3 "Here is a C++ example".<br> + * \ref py_mcfielddouble_fillFromAnalytic3 "Here is a Python example". + * \endif + */ +void MEDCouplingFieldDouble::fillFromAnalytic3(int nbOfComp, const std::vector<std::string>& varsOrder, const std::string& func) +{ + 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<DataArrayDouble> loc=_type->getLocalizationOfDiscValues(_mesh); + _time_discr->fillFromAnalytic3(loc,nbOfComp,varsOrder,func); +} + +/*! + * 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. + * + * \if ENABLE_EXAMPLES + * \ref cpp_mcfielddouble_applyFunc_c_func "Here is a C++ example". + * \endif + */ +void MEDCouplingFieldDouble::applyFunc(int nbOfComp, FunctionToEvaluate func) +{ + _time_discr->applyFunc(nbOfComp,func); +} + +/*! + * Fill \a this field with a given value.<br> + * 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. + * + * \if ENABLE_EXAMPLES + * \ref cpp_mcfielddouble_applyFunc_val "Here is a C++ example".<br> + * \ref py_mcfielddouble_applyFunc_val "Here is a Python example". + * \endif + */ +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); +} + +/*! + * 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. <br> + * 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)!<br> + * 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.<br> + * 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. + * + * \if ENABLE_EXAMPLES + * \ref cpp_mcfielddouble_applyFunc "Here is a C++ example".<br> + * \ref py_mcfielddouble_applyFunc "Here is a Python example". + * \endif + */ +void MEDCouplingFieldDouble::applyFunc(int nbOfComp, const std::string& func) +{ + _time_discr->applyFunc(nbOfComp,func); +} + + +/*! + * 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. <br> + * This method differs from + * \ref ParaMEDMEM::MEDCouplingFieldDouble::applyFunc(int nbOfComp, const std::string& 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()).<br> + * 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.<br> + * 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. + * + * \if ENABLE_EXAMPLES + * \ref cpp_mcfielddouble_applyFunc2 "Here is a C++ example".<br> + * \ref py_mcfielddouble_applyFunc2 "Here is a Python example". + * \endif + */ +void MEDCouplingFieldDouble::applyFunc2(int nbOfComp, const std::string& func) +{ + _time_discr->applyFunc2(nbOfComp,func); +} + +/*! + * 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 std::string& 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.<br> + * 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.<br> + * 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. + * + * \if ENABLE_EXAMPLES + * \ref cpp_mcfielddouble_applyFunc3 "Here is a C++ example".<br> + * \ref py_mcfielddouble_applyFunc3 "Here is a Python example". + * \endif + */ +void MEDCouplingFieldDouble::applyFunc3(int nbOfComp, const std::vector<std::string>& varsOrder, const std::string& func) +{ + _time_discr->applyFunc3(nbOfComp,varsOrder,func); +} + +/*! + * Modifies values of \a this field by applying a function to each atomic value of all + * data arrays. The function computes a new single value basing on an old single value. + * For more info on supported expressions that can be used in the function, see \ref + * MEDCouplingArrayApplyFuncExpr. <br> + * The function can include **only one** arbitrary named variable + * (e.g. "x","y" or "va44") to refer to a field atomic value. <br> + * 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.<br> + * 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. + * + * \if ENABLE_EXAMPLES + * \ref cpp_mcfielddouble_applyFunc_same_nb_comp "Here is a C++ example".<br> + * \ref py_mcfielddouble_applyFunc_same_nb_comp "Here is a Python example". + * \endif + */ +void MEDCouplingFieldDouble::applyFunc(const std::string& func) +{ + _time_discr->applyFunc(func); +} + +/*! + * Applyies the function specified by the string repr 'func' on each tuples on all arrays contained in _time_discr. + * The field will contain exactly the same number of components after the call. + * Use is not warranted for the moment ! + */ +void MEDCouplingFieldDouble::applyFuncFast32(const std::string& func) +{ + _time_discr->applyFuncFast32(func); +} + +/*! + * Applyies the function specified by the string repr 'func' on each tuples on all arrays contained in _time_discr. + * The field will contain exactly the same number of components after the call. + * Use is not warranted for the moment ! + */ +void MEDCouplingFieldDouble::applyFuncFast64(const std::string& func) +{ + _time_discr->applyFuncFast64(func); +} + +/*! + * Returns number of components in the data array. For more info on the data arrays, + * see \ref arrays. + * \return int - the number of components in the data array. + * \throw If the data array is not set. + */ +int MEDCouplingFieldDouble::getNumberOfComponents() const +{ + if(getArray()==0) + throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::getNumberOfComponents : No array specified !"); + return getArray()->getNumberOfComponents(); +} + +/*! + * Use MEDCouplingField::getNumberOfTuplesExpected instead of this method. This method will be removed soon, because it is + * confusing compared to getNumberOfComponents() and getNumberOfValues() behaviour. + * + * 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 \b not \b 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 (Sorry, it is confusing !). + * So \b this \b method \b behaves \b exactly \b as MEDCouplingField::getNumberOfTuplesExpected \b method. + * + * \warning No checkCoherency() is done here. + * For more info on the data arrays, see \ref arrays. + * \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. + * \sa MEDCouplingField::getNumberOfTuplesExpected + */ +int MEDCouplingFieldDouble::getNumberOfTuples() const +{ + //std::cerr << " ******* MEDCouplingFieldDouble::getNumberOfTuples is deprecated : use MEDCouplingField::getNumberOfTuplesExpected instead ! ******" << std::endl; + 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); +} + +/*! + * Returns number of atomic double values in the data array of \a this field. + * For more info on the data arrays, see \ref arrays. + * \return int - (number of tuples) * (number of components) of the + * data array. + * \throw If the data array is not set. + */ +int MEDCouplingFieldDouble::getNumberOfValues() const +{ + if(getArray()==0) + throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::getNumberOfValues : No array specified !"); + 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::getHeapMemorySizeWithoutChildren() const +{ + return MEDCouplingField::getHeapMemorySizeWithoutChildren(); +} + +std::vector<const BigMemoryObject *> MEDCouplingFieldDouble::getDirectChildrenWithNull() const +{ + std::vector<const BigMemoryObject *> ret(MEDCouplingField::getDirectChildrenWithNull()); + if(_time_discr) + { + std::vector<const BigMemoryObject *> ret2(_time_discr->getDirectChildrenWithNull()); + ret.insert(ret.end(),ret2.begin(),ret2.end()); + } + return ret; +} + +/*! + * Sets \ref NatureOfField. + * \param [in] nat - an item of enum ParaMEDMEM::NatureOfField. + */ +void MEDCouplingFieldDouble::setNature(NatureOfField nat) +{ + MEDCouplingField::setNature(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() +{ + 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); +} + +/*! + * 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<DataArrayDouble *>& arrs) +{ + _time_discr->setArrays(arrs,this); +} + +void MEDCouplingFieldDouble::getTinySerializationStrInformation(std::vector<std::string>& tinyInfo) const +{ + tinyInfo.clear(); + _time_discr->getTinySerializationStrInformation(tinyInfo); + tinyInfo.push_back(_name); + tinyInfo.push_back(_desc); + tinyInfo.push_back(getTimeUnit()); +} + +/*! + * This method retrieves some critical values to resize and prepare remote instance. + * The first two elements returned in tinyInfo correspond to the parameters to give in constructor. + * @param tinyInfo out parameter resized correctly after the call. The length of this vector is tiny. + */ +void MEDCouplingFieldDouble::getTinySerializationIntInformation(std::vector<int>& 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()); + tinyInfo.push_back((int)_nature); + _time_discr->getTinySerializationIntInformation(tinyInfo); + std::vector<int> tinyInfo2; + _type->getTinySerializationIntInformation(tinyInfo2); + tinyInfo.insert(tinyInfo.end(),tinyInfo2.begin(),tinyInfo2.end()); + tinyInfo.push_back((int)tinyInfo2.size()); +} + +/*! + * This method retrieves some critical values to resize and prepare remote instance. + * @param tinyInfo out parameter resized correctly after the call. The length of this vector is tiny. + */ +void MEDCouplingFieldDouble::getTinySerializationDbleInformation(std::vector<double>& 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<double> tinyInfo2; + _type->getTinySerializationDbleInformation(tinyInfo2); + tinyInfo.insert(tinyInfo.end(),tinyInfo2.begin(),tinyInfo2.end()); + tinyInfo.push_back((int)tinyInfo2.size());//very bad, lack of time to improve it +} + +/*! + * This method has to be called to the new instance filled by CORBA, MPI, File... + * @param tinyInfoI is the value retrieves from distant result of getTinySerializationIntInformation on source instance to be copied. + * @param dataInt out parameter. If not null the pointer is already owned by \a this after the call of this method. In this case no decrRef must be applied. + * @param arrays out parameter is a vector resized to the right size. The pointers in the vector is already owned by \a this after the call of this method. + * No decrRef must be applied to every instances in returned vector. + * \sa checkForUnserialization + */ +void MEDCouplingFieldDouble::resizeForUnserialization(const std::vector<int>& tinyInfoI, DataArrayInt *&dataInt, std::vector<DataArrayDouble *>& arrays) +{ + if(!((const MEDCouplingFieldDiscretization *)_type)) + throw INTERP_KERNEL::Exception("No spatial discretization underlying this field to perform resizeForUnserialization !"); + dataInt=0; + std::vector<int> tinyInfoITmp(tinyInfoI); + int sz=tinyInfoITmp.back(); + tinyInfoITmp.pop_back(); + std::vector<int> tinyInfoITmp2(tinyInfoITmp.begin(),tinyInfoITmp.end()-sz); + std::vector<int> tinyInfoI2(tinyInfoITmp2.begin()+3,tinyInfoITmp2.end()); + _time_discr->resizeForUnserialization(tinyInfoI2,arrays); + std::vector<int> tinyInfoITmp3(tinyInfoITmp.end()-sz,tinyInfoITmp.end()); + _type->resizeForUnserialization(tinyInfoITmp3,dataInt); +} + +/*! + * This method is extremely close to resizeForUnserialization except that here the arrays in \a dataInt and in \a arrays are attached in \a this + * after having checked that size is correct. This method is used in python pickeling context to avoid copy of data. + * \sa resizeForUnserialization + */ +void MEDCouplingFieldDouble::checkForUnserialization(const std::vector<int>& tinyInfoI, const DataArrayInt *dataInt, const std::vector<DataArrayDouble *>& arrays) +{ + if(!((const MEDCouplingFieldDiscretization *)_type)) + throw INTERP_KERNEL::Exception("No spatial discretization underlying this field to perform resizeForUnserialization !"); + std::vector<int> tinyInfoITmp(tinyInfoI); + int sz=tinyInfoITmp.back(); + tinyInfoITmp.pop_back(); + std::vector<int> tinyInfoITmp2(tinyInfoITmp.begin(),tinyInfoITmp.end()-sz); + std::vector<int> tinyInfoI2(tinyInfoITmp2.begin()+3,tinyInfoITmp2.end()); + _time_discr->checkForUnserialization(tinyInfoI2,arrays); + std::vector<int> tinyInfoITmp3(tinyInfoITmp.end()-sz,tinyInfoITmp.end()); + _type->checkForUnserialization(tinyInfoITmp3,dataInt); +} + +void MEDCouplingFieldDouble::finishUnserialization(const std::vector<int>& tinyInfoI, const std::vector<double>& tinyInfoD, const std::vector<std::string>& tinyInfoS) +{ + if(!((const MEDCouplingFieldDiscretization *)_type)) + throw INTERP_KERNEL::Exception("No spatial discretization underlying this field to perform finishUnserialization !"); + std::vector<int> tinyInfoI2(tinyInfoI.begin()+3,tinyInfoI.end()); + // + std::vector<double> tmp(tinyInfoD); + int sz=(int)tinyInfoD.back();//very bad, lack of time to improve it + tmp.pop_back(); + std::vector<double> tmp1(tmp.begin(),tmp.end()-sz); + std::vector<double> tmp2(tmp.end()-sz,tmp.end()); + // + _time_discr->finishUnserialization(tinyInfoI2,tmp1,tinyInfoS); + _nature=(NatureOfField)tinyInfoI[2]; + _type->finishUnserialization(tmp2); + int nbOfElemS=(int)tinyInfoS.size(); + _name=tinyInfoS[nbOfElemS-3]; + _desc=tinyInfoS[nbOfElemS-2]; + setTimeUnit(tinyInfoS[nbOfElemS-1]); +} + +/*! + * Contrary to MEDCouplingPointSet class the returned arrays are \b not the responsabilities of the caller. + * The values returned must be consulted only in readonly mode. + */ +void MEDCouplingFieldDouble::serialize(DataArrayInt *&dataInt, std::vector<DataArrayDouble *>& 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); +} + +/*! + * 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. + * + * \if ENABLE_EXAMPLES + * \ref cpp_mcfielddouble_changeUnderlyingMesh "Here is a C++ example".<br> + * \ref py_mcfielddouble_changeUnderlyingMesh "Here is a Python example". + * \endif + */ +void MEDCouplingFieldDouble::changeUnderlyingMesh(const MEDCouplingMesh *other, int levOfCheck, double precOnMesh, double eps) +{ + 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,precOnMesh,cellCor,nodeCor); + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> cellCor2(cellCor),nodeCor2(nodeCor); + if(cellCor) + renumberCellsWithoutMesh(cellCor->getConstPointer(),false); + if(nodeCor) + renumberNodesWithoutMesh(nodeCor->getConstPointer(),nodeCor->getMaxValueInArray()+1,eps); + setMesh(other); +} + +/*! + * 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.<br> + * 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.<br> + * This method requires that \a f and \a this are coherent (checkCoherency()) and that \a f + * and \a this are coherent for a merge.<br> + * "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. + * + * \if ENABLE_EXAMPLES + * \ref cpp_mcfielddouble_substractInPlaceDM "Here is a C++ example".<br> + * \ref py_mcfielddouble_substractInPlaceDM "Here is a Python example". + * \endif + * \sa changeUnderlyingMesh(). + */ +void MEDCouplingFieldDouble::substractInPlaceDM(const MEDCouplingFieldDouble *f, int levOfCheck, double precOnMesh, double eps) +{ + checkCoherency(); + if(!f) + throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::substractInPlaceDM : input field is NULL !"); + f->checkCoherency(); + if(!areCompatibleForMerge(f)) + throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::substractInPlaceDM : Fields are not compatible ; unable to apply mergeFields on them !"); + changeUnderlyingMesh(f->getMesh(),levOfCheck,precOnMesh,eps); + operator-=(*f); +} + +/*! + * 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) +{ + const MEDCouplingPointSet *meshC=dynamic_cast<const MEDCouplingPointSet *>(_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<MEDCouplingPointSet> meshC2((MEDCouplingPointSet *)meshC->deepCpy()); + bool ret; + int ret2; + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> arr=meshC2->mergeNodes(eps,ret,ret2); + if(!ret)//no nodes have been merged. + return ret; + std::vector<DataArrayDouble *> arrays; + _time_discr->getArrays(arrays); + for(std::vector<DataArrayDouble *>::const_iterator iter=arrays.begin();iter!=arrays.end();iter++) + if(*iter) + _type->renumberValuesOnNodes(epsOnVals,arr->getConstPointer(),meshC2->getNumberOfNodes(),*iter); + setMesh(meshC2); + return true; +} + +/*! + * 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.<br> + * 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) +{ + const MEDCouplingPointSet *meshC=dynamic_cast<const MEDCouplingPointSet *>(_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<MEDCouplingPointSet> meshC2((MEDCouplingPointSet *)meshC->deepCpy()); + bool ret; + int ret2; + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> arr=meshC2->mergeNodes2(eps,ret,ret2); + if(!ret)//no nodes have been merged. + return ret; + std::vector<DataArrayDouble *> arrays; + _time_discr->getArrays(arrays); + for(std::vector<DataArrayDouble *>::const_iterator iter=arrays.begin();iter!=arrays.end();iter++) + if(*iter) + _type->renumberValuesOnNodes(epsOnVals,arr->getConstPointer(),meshC2->getNumberOfNodes(),*iter); + setMesh(meshC2); + return true; +} + +/*! + * 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.<br> + * \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) +{ + const MEDCouplingPointSet *meshC=dynamic_cast<const MEDCouplingPointSet *>(_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<MEDCouplingPointSet> meshC2((MEDCouplingPointSet *)meshC->deepCpy()); + int oldNbOfNodes=meshC2->getNumberOfNodes(); + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> arr=meshC2->zipCoordsTraducer(); + if(meshC2->getNumberOfNodes()!=oldNbOfNodes) + { + std::vector<DataArrayDouble *> arrays; + _time_discr->getArrays(arrays); + for(std::vector<DataArrayDouble *>::const_iterator iter=arrays.begin();iter!=arrays.end();iter++) + if(*iter) + _type->renumberValuesOnNodes(epsOnVals,arr->getConstPointer(),meshC2->getNumberOfNodes(),*iter); + setMesh(meshC2); + return true; + } + return false; +} + +/*! + * 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.<br> + * \param [in] compType - specifies a cell comparison technique. Meaning of its + * valid values [0,1,2] is explained in the description of + * MEDCouplingPointSet::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) +{ + const MEDCouplingUMesh *meshC=dynamic_cast<const MEDCouplingUMesh *>(_mesh); + if(!meshC) + 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<MEDCouplingUMesh> meshC2((MEDCouplingUMesh *)meshC->deepCpy()); + int oldNbOfCells=meshC2->getNumberOfCells(); + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> arr=meshC2->zipConnectivityTraducer(compType); + if(meshC2->getNumberOfCells()!=oldNbOfCells) + { + std::vector<DataArrayDouble *> arrays; + _time_discr->getArrays(arrays); + for(std::vector<DataArrayDouble *>::const_iterator iter=arrays.begin();iter!=arrays.end();iter++) + if(*iter) + _type->renumberValuesOnCells(epsOnVals,meshC,arr->getConstPointer(),meshC2->getNumberOfCells(),*iter); + setMesh(meshC2); + return true; + } + return false; +} + +/*! + * This method calls MEDCouplingUMesh::buildSlice3D method. So this method makes the assumption that underlying mesh exists. + * For the moment, this method is implemented for fields on cells. + * + * \return a newly allocated field double containing the result that the user should deallocate. + */ +MEDCouplingFieldDouble *MEDCouplingFieldDouble::extractSlice3D(const double *origin, const double *vec, double eps) const +{ + const MEDCouplingMesh *mesh=getMesh(); + if(!mesh) + throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::extractSlice3D : underlying mesh is null !"); + if(getTypeOfField()!=ON_CELLS) + throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::extractSlice3D : only implemented for fields on cells !"); + const MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> umesh(mesh->buildUnstructured()); + MEDCouplingAutoRefCountObjectPtr<MEDCouplingFieldDouble> ret=clone(false); + ret->setMesh(umesh); + DataArrayInt *cellIds=0; + MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> mesh2=umesh->buildSlice3D(origin,vec,eps,cellIds); + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> cellIds2=cellIds; + ret->setMesh(mesh2); + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> tupleIds=computeTupleIdsToSelectFromCellIds(cellIds->begin(),cellIds->end()); + std::vector<DataArrayDouble *> arrays; + _time_discr->getArrays(arrays); + int i=0; + std::vector<DataArrayDouble *> newArr(arrays.size()); + std::vector< MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> > newArr2(arrays.size()); + for(std::vector<DataArrayDouble *>::const_iterator iter=arrays.begin();iter!=arrays.end();iter++,i++) + { + if(*iter) + { + newArr2[i]=(*iter)->selectByTupleIdSafe(cellIds->begin(),cellIds->end()); + newArr[i]=newArr2[i]; + } + } + ret->setArrays(newArr); + return ret.retn(); +} + +/*! + * 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.<br> + * \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) +{ + 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<MEDCouplingMesh> meshC2(_mesh->deepCpy()); + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> arr=meshC2->simplexize(policy); + int newNbOfCells=meshC2->getNumberOfCells(); + if(oldNbOfCells==newNbOfCells) + return false; + std::vector<DataArrayDouble *> arrays; + _time_discr->getArrays(arrays); + for(std::vector<DataArrayDouble *>::const_iterator iter=arrays.begin();iter!=arrays.end();iter++) + if(*iter) + _type->renumberValuesOnCellsR(_mesh,arr->getConstPointer(),arr->getNbOfElems(),*iter); + setMesh(meshC2); + 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 <em>(t)</em> 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 +{ + 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); + MEDCouplingAutoRefCountObjectPtr<MEDCouplingFieldDouble> ret=new MEDCouplingFieldDouble(getNature(),td,_type->clone()); + ret->setName("DoublyContractedProduct"); + ret->setMesh(getMesh()); + 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 +{ + 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); + MEDCouplingAutoRefCountObjectPtr<MEDCouplingFieldDouble> ret=new MEDCouplingFieldDouble(getNature(),td,_type->clone()); + ret->setName("Determinant"); + ret->setMesh(getMesh()); + 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 +{ + 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); + MEDCouplingAutoRefCountObjectPtr<MEDCouplingFieldDouble> ret=new MEDCouplingFieldDouble(getNature(),td,_type->clone()); + ret->setName("EigenValues"); + ret->setMesh(getMesh()); + 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 +{ + 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); + MEDCouplingAutoRefCountObjectPtr<MEDCouplingFieldDouble> ret=new MEDCouplingFieldDouble(getNature(),td,_type->clone()); + ret->setName("EigenVectors"); + ret->setMesh(getMesh()); + 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 +{ + 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); + MEDCouplingAutoRefCountObjectPtr<MEDCouplingFieldDouble> ret=new MEDCouplingFieldDouble(getNature(),td,_type->clone()); + ret->setName("Inversion"); + ret->setMesh(getMesh()); + 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 +{ + 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); + MEDCouplingAutoRefCountObjectPtr<MEDCouplingFieldDouble> ret=new MEDCouplingFieldDouble(getNature(),td,_type->clone()); + ret->setName("Trace"); + ret->setMesh(getMesh()); + 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 +{ + 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); + MEDCouplingAutoRefCountObjectPtr<MEDCouplingFieldDouble> ret=new MEDCouplingFieldDouble(getNature(),td,_type->clone()); + ret->setName("Deviator"); + ret->setMesh(getMesh()); + 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 +{ + 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); + MEDCouplingAutoRefCountObjectPtr<MEDCouplingFieldDouble> ret=new MEDCouplingFieldDouble(getNature(),td,_type->clone()); + ret->setName("Magnitude"); + ret->setMesh(getMesh()); + 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 +{ + 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); + MEDCouplingAutoRefCountObjectPtr<MEDCouplingFieldDouble> ret=new MEDCouplingFieldDouble(getNature(),td,_type->clone()); + std::ostringstream oss; + oss << "Max_" << getName(); + ret->setName(oss.str()); + ret->setMesh(getMesh()); + 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) +{ + _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<int>& compoIds) const +{ + 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); + MEDCouplingAutoRefCountObjectPtr<MEDCouplingFieldDouble> ret=new MEDCouplingFieldDouble(getNature(),td,_type->clone()); + ret->setName(getName()); + ret->setMesh(getMesh()); + 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<int>& compoIds) +{ + _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) +{ + _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 the spatial discretization of \a f1 is NULL. + * \throw If the time discretization of \a f1 is NULL. + * + * \if ENABLE_EXAMPLES + * \ref cpp_mcfielddouble_MergeFields "Here is a C++ example".<br> + * \ref py_mcfielddouble_MergeFields "Here is a Python example". + * \endif + */ +MEDCouplingFieldDouble *MEDCouplingFieldDouble::MergeFields(const MEDCouplingFieldDouble *f1, const MEDCouplingFieldDouble *f2) +{ + if(!f1->areCompatibleForMerge(f2)) + throw INTERP_KERNEL::Exception("Fields are not compatible. Unable to apply MergeFields on them ! Check support mesh, field nature, and spatial and time discretisation."); + const MEDCouplingMesh *m1(f1->getMesh()),*m2(f2->getMesh()); + 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 !"); + MEDCouplingTimeDiscretization *td=f1->_time_discr->aggregate(f2->_time_discr); + td->copyTinyAttrFrom(*f1->_time_discr); + MEDCouplingAutoRefCountObjectPtr<MEDCouplingFieldDouble> ret=new MEDCouplingFieldDouble(f1->getNature(),td,f1->_type->clone()); + ret->setName(f1->getName()); + ret->setDescription(f1->getDescription()); + if(m1) + { + MEDCouplingAutoRefCountObjectPtr<MEDCouplingMesh> m=m1->mergeMyselfWith(m2); + ret->setMesh(m); + } + 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. + * + * \if ENABLE_EXAMPLES + * \ref cpp_mcfielddouble_MergeFields "Here is a C++ example".<br> + * \ref py_mcfielddouble_MergeFields "Here is a Python example". + * \endif + */ +MEDCouplingFieldDouble *MEDCouplingFieldDouble::MergeFields(const std::vector<const MEDCouplingFieldDouble *>& a) +{ + if(a.size()<1) + throw INTERP_KERNEL::Exception("FieldDouble::MergeFields : size of array must be >= 1 !"); + std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> > ms(a.size()); + std::vector< const MEDCouplingUMesh *> ms2(a.size()); + std::vector< const MEDCouplingTimeDiscretization *> tds(a.size()); + std::vector<const MEDCouplingFieldDouble *>::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! Check support mesh, field nature, and spatial and time discretisation."); + for(int i=0;i<(int)a.size();i++) + { + if(a[i]->getMesh()) + { ms[i]=a[i]->getMesh()->buildUnstructured(); ms2[i]=ms[i]; } + else + { ms[i]=0; ms2[i]=0; } + tds[i]=a[i]->_time_discr; + } + MEDCouplingTimeDiscretization *td=tds[0]->aggregate(tds); + td->copyTinyAttrFrom(*(a[0]->_time_discr)); + MEDCouplingAutoRefCountObjectPtr<MEDCouplingFieldDouble> ret=new MEDCouplingFieldDouble(a[0]->getNature(),td,a[0]->_type->clone()); + ret->setName(a[0]->getName()); + ret->setDescription(a[0]->getDescription()); + if(ms2[0]) + { + MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m=MEDCouplingUMesh::MergeUMeshes(ms2); + m->copyTinyInfoFrom(ms2[0]); + ret->setMesh(m); + } + 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) +{ + if(!f1->areCompatibleForMeld(f2)) + throw INTERP_KERNEL::Exception("Fields are not compatible. Unable to apply MeldFields on them ! Check support mesh, field nature, and spatial and time discretisation."); + MEDCouplingTimeDiscretization *td=f1->_time_discr->meld(f2->_time_discr); + td->copyTinyAttrFrom(*f1->_time_discr); + MEDCouplingAutoRefCountObjectPtr<MEDCouplingFieldDouble> ret=new MEDCouplingFieldDouble(f1->getNature(),td,f1->_type->clone()); + ret->setMesh(f1->getMesh()); + 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) +{ + if(!f1) + throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::DotFields : input field is NULL !"); + if(!f1->areStrictlyCompatibleForMulDiv(f2)) + throw INTERP_KERNEL::Exception("Fields are not compatible. Unable to apply DotFields on them! Check support mesh, and spatial and time discretisation."); + MEDCouplingTimeDiscretization *td=f1->_time_discr->dot(f2->_time_discr); + td->copyTinyAttrFrom(*f1->_time_discr); + MEDCouplingFieldDouble *ret=new MEDCouplingFieldDouble(NoNature,td,f1->_type->clone()); + ret->setMesh(f1->getMesh()); + 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) +{ + if(!f1) + throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::CrossProductFields : input field is NULL !"); + if(!f1->areStrictlyCompatibleForMulDiv(f2)) + throw INTERP_KERNEL::Exception("Fields are not compatible. Unable to apply CrossProductFields on them! Check support mesh, and spatial and time discretisation."); + MEDCouplingTimeDiscretization *td=f1->_time_discr->crossProduct(f2->_time_discr); + td->copyTinyAttrFrom(*f1->_time_discr); + MEDCouplingAutoRefCountObjectPtr<MEDCouplingFieldDouble> ret=new MEDCouplingFieldDouble(NoNature,td,f1->_type->clone()); + ret->setMesh(f1->getMesh()); + 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. + * + * \if ENABLE_EXAMPLES + * \ref cpp_mcfielddouble_MaxFields "Here is a C++ example".<br> + * \ref py_mcfielddouble_MaxFields "Here is a Python example". + * \endif + */ +MEDCouplingFieldDouble *MEDCouplingFieldDouble::MaxFields(const MEDCouplingFieldDouble *f1, const MEDCouplingFieldDouble *f2) +{ + 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! Check support mesh, field nature, and spatial and time discretisation."); + MEDCouplingTimeDiscretization *td=f1->_time_discr->max(f2->_time_discr); + td->copyTinyAttrFrom(*f1->_time_discr); + MEDCouplingAutoRefCountObjectPtr<MEDCouplingFieldDouble> ret=new MEDCouplingFieldDouble(f1->getNature(),td,f1->_type->clone()); + ret->setMesh(f1->getMesh()); + 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. + * + * \if ENABLE_EXAMPLES + * \ref cpp_mcfielddouble_MaxFields "Here is a C++ example".<br> + * \ref py_mcfielddouble_MaxFields "Here is a Python example". + * \endif + */ +MEDCouplingFieldDouble *MEDCouplingFieldDouble::MinFields(const MEDCouplingFieldDouble *f1, const MEDCouplingFieldDouble *f2) +{ + 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! Check support mesh, field nature, and spatial and time discretisation."); + MEDCouplingTimeDiscretization *td=f1->_time_discr->min(f2->_time_discr); + td->copyTinyAttrFrom(*f1->_time_discr); + MEDCouplingAutoRefCountObjectPtr<MEDCouplingFieldDouble> ret=new MEDCouplingFieldDouble(f1->getNature(),td,f1->_type->clone()); + ret->setMesh(f1->getMesh()); + 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 +{ + 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<MEDCouplingFieldDouble> 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) +{ + 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! Check support mesh, field nature, and spatial and time discretisation."); + MEDCouplingTimeDiscretization *td=f1->_time_discr->add(f2->_time_discr); + td->copyTinyAttrFrom(*f1->_time_discr); + MEDCouplingAutoRefCountObjectPtr<MEDCouplingFieldDouble> ret=new MEDCouplingFieldDouble(f1->getNature(),td,f1->_type->clone()); + ret->setMesh(f1->getMesh()); + 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) +{ + if(!areStrictlyCompatible(&other)) + throw INTERP_KERNEL::Exception("Fields are not compatible. Unable to apply += on them! Check support mesh, field nature, and spatial and time discretisation."); + _time_discr->addEqual(other._time_discr); + 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) +{ + 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! Check support mesh, field nature, and spatial and time discretisation."); + MEDCouplingTimeDiscretization *td=f1->_time_discr->substract(f2->_time_discr); + td->copyTinyAttrFrom(*f1->_time_discr); + MEDCouplingAutoRefCountObjectPtr<MEDCouplingFieldDouble> ret=new MEDCouplingFieldDouble(f1->getNature(),td,f1->_type->clone()); + ret->setMesh(f1->getMesh()); + 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) +{ + if(!areStrictlyCompatible(&other)) + throw INTERP_KERNEL::Exception("Fields are not compatible. Unable to apply -= on them! Check support mesh, field nature, and spatial and time discretisation."); + _time_discr->substractEqual(other._time_discr); + 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, with no nature set. + * 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 multiplication (areCompatibleForMul()), + * i.e. they differ not only in values and possibly number of components. + */ +MEDCouplingFieldDouble *MEDCouplingFieldDouble::MultiplyFields(const MEDCouplingFieldDouble *f1, const MEDCouplingFieldDouble *f2) +{ + 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! Check support mesh, and spatial and time discretisation."); + MEDCouplingTimeDiscretization *td=f1->_time_discr->multiply(f2->_time_discr); + td->copyTinyAttrFrom(*f1->_time_discr); + MEDCouplingAutoRefCountObjectPtr<MEDCouplingFieldDouble> ret=new MEDCouplingFieldDouble(NoNature,td,f1->_type->clone()); + ret->setMesh(f1->getMesh()); + 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, with no nature set. + * 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 multiplication + * (areCompatibleForMul()), + * i.e. they differ not only in values and possibly in number of components. + */ +const MEDCouplingFieldDouble &MEDCouplingFieldDouble::operator*=(const MEDCouplingFieldDouble& other) +{ + if(!areCompatibleForMul(&other)) + throw INTERP_KERNEL::Exception("Fields are not compatible. Unable to apply *= on them! Check support mesh, and spatial and time discretisation."); + _time_discr->multiplyEqual(other._time_discr); + _nature = NoNature; + 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, with no nature set. + * 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) +{ + 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! Check support mesh, and spatial and time discretisation."); + MEDCouplingTimeDiscretization *td=f1->_time_discr->divide(f2->_time_discr); + td->copyTinyAttrFrom(*f1->_time_discr); + MEDCouplingAutoRefCountObjectPtr<MEDCouplingFieldDouble> ret=new MEDCouplingFieldDouble(NoNature,td,f1->_type->clone()); + ret->setMesh(f1->getMesh()); + 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) +{ + if(!areCompatibleForDiv(&other)) + throw INTERP_KERNEL::Exception("Fields are not compatible. Unable to apply /= on them! Check support mesh, and spatial and time discretisation."); + _time_discr->divideEqual(other._time_discr); + _nature = NoNature; + return *this; +} + +/*! + * Directly called by MEDCouplingFieldDouble::operator^. + * + * \sa MEDCouplingFieldDouble::operator^ + */ +MEDCouplingFieldDouble *MEDCouplingFieldDouble::PowFields(const MEDCouplingFieldDouble *f1, const MEDCouplingFieldDouble *f2) +{ + 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! Check support mesh, and spatial and time discretisation."); + MEDCouplingTimeDiscretization *td=f1->_time_discr->pow(f2->_time_discr); + td->copyTinyAttrFrom(*f1->_time_discr); + MEDCouplingAutoRefCountObjectPtr<MEDCouplingFieldDouble> ret=new MEDCouplingFieldDouble(NoNature,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 +{ + return PowFields(this,&other); +} + +const MEDCouplingFieldDouble &MEDCouplingFieldDouble::operator^=(const MEDCouplingFieldDouble& other) +{ + if(!areCompatibleForDiv(&other)) + throw INTERP_KERNEL::Exception("Fields are not compatible. Unable to apply ^= on them! Check support mesh, and spatial and time discretisation."); + _time_discr->powEqual(other._time_discr); + _nature = NoNature; + 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. + * \param [in] isBinary - specifies the VTK format of the written file. By default true (Binary mode) + * \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. + * + * \if ENABLE_EXAMPLES + * \ref cpp_mcfielddouble_WriteVTK "Here is a C++ example".<br> + * \ref py_mcfielddouble_WriteVTK "Here is a Python example". + * \endif + */ +std::string MEDCouplingFieldDouble::WriteVTK(const std::string& fileName, const std::vector<const MEDCouplingFieldDouble *>& fs, bool isBinary) +{ + if(fs.empty()) + return std::string(); + 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;i<nfs;i++) + if(fs[i]->getMesh()!=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."); + if(!m) + throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::WriteVTK : Fields are lying on a same mesh but it is empty !"); + std::string ret(m->getVTKFileNameOf(fileName)); + MEDCouplingAutoRefCountObjectPtr<DataArrayByte> byteArr; + if(isBinary) + { byteArr=DataArrayByte::New(); byteArr->alloc(0,1); } + std::ostringstream coss,noss; + for(std::size_t i=0;i<nfs;i++) + { + const MEDCouplingFieldDouble *cur=fs[i]; + std::string name(cur->getName()); + if(name.empty()) + { + std::ostringstream oss; oss << "MEDCouplingFieldDouble::WriteVTK : Field in pos #" << i << " has no name !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + TypeOfField typ=cur->getTypeOfField(); + if(typ==ON_CELLS) + cur->getArray()->writeVTK(coss,8,cur->getName(),byteArr); + else if(typ==ON_NODES) + cur->getArray()->writeVTK(noss,8,cur->getName(),byteArr); + else + throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::WriteVTK : only node and cell fields supported for the moment !"); + } + m->writeVTKAdvanced(ret,coss.str(),noss.str(),byteArr); + return ret; +} + +void MEDCouplingFieldDouble::reprQuickOverview(std::ostream& stream) const +{ + 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/medtool/src/MEDCoupling/MEDCouplingFieldDouble.hxx b/src/medtool/src/MEDCoupling/MEDCouplingFieldDouble.hxx new file mode 100644 index 000000000..ee9a2506a --- /dev/null +++ b/src/medtool/src/MEDCoupling/MEDCouplingFieldDouble.hxx @@ -0,0 +1,211 @@ +// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 +// 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_MEDCOUPLINGFIELDDOUBLE_HXX__ +#define __PARAMEDMEM_MEDCOUPLINGFIELDDOUBLE_HXX__ + +#include "MEDCoupling.hxx" +#include "MEDCouplingField.hxx" +#include "MEDCouplingTimeDiscretization.hxx" +#include "MEDCouplingMemArray.hxx" + +namespace ParaMEDMEM +{ + class MEDCouplingFieldTemplate; + + class MEDCouplingFieldDouble : public MEDCouplingField + { + public: + MEDCOUPLING_EXPORT static MEDCouplingFieldDouble *New(TypeOfField type, TypeOfTimeDiscretization td=ONE_TIME); + MEDCOUPLING_EXPORT static MEDCouplingFieldDouble *New(const MEDCouplingFieldTemplate& ft, TypeOfTimeDiscretization td=ONE_TIME); + MEDCOUPLING_EXPORT void setTimeUnit(const std::string& unit); + MEDCOUPLING_EXPORT std::string getTimeUnit() const; + MEDCOUPLING_EXPORT void synchronizeTimeWithSupport(); + MEDCOUPLING_EXPORT void copyTinyStringsFrom(const MEDCouplingField *other); + MEDCOUPLING_EXPORT void copyTinyAttrFrom(const MEDCouplingFieldDouble *other); + MEDCOUPLING_EXPORT void copyAllTinyAttrFrom(const MEDCouplingFieldDouble *other); + MEDCOUPLING_EXPORT std::string simpleRepr() const; + MEDCOUPLING_EXPORT std::string advancedRepr() const; + MEDCOUPLING_EXPORT std::string writeVTK(const std::string& fileName, bool isBinary=true) const; + MEDCOUPLING_EXPORT bool isEqualIfNotWhy(const MEDCouplingField *other, double meshPrec, double valsPrec, std::string& reason) const; + MEDCOUPLING_EXPORT bool isEqualWithoutConsideringStr(const MEDCouplingField *other, double meshPrec, double valsPrec) const; + MEDCOUPLING_EXPORT bool areCompatibleForMerge(const MEDCouplingField *other) const; + MEDCOUPLING_EXPORT bool areStrictlyCompatible(const MEDCouplingField *other) const; + MEDCOUPLING_EXPORT bool areCompatibleForMul(const MEDCouplingField *other) const; + MEDCOUPLING_EXPORT bool areCompatibleForDiv(const MEDCouplingField *other) const; + MEDCOUPLING_EXPORT bool areCompatibleForMeld(const MEDCouplingFieldDouble *other) const; + MEDCOUPLING_EXPORT void renumberCells(const int *old2NewBg, bool check=true); + MEDCOUPLING_EXPORT void renumberCellsWithoutMesh(const int *old2NewBg, bool check=true); + MEDCOUPLING_EXPORT void renumberNodes(const int *old2NewBg, double eps=1e-15); + MEDCOUPLING_EXPORT void renumberNodesWithoutMesh(const int *old2NewBg, int newNbOfNodes, double eps=1e-15); + MEDCOUPLING_EXPORT DataArrayInt *getIdsInRange(double vmin, double vmax) const; + MEDCOUPLING_EXPORT MEDCouplingFieldDouble *buildSubPart(const DataArrayInt *part) const; + MEDCOUPLING_EXPORT MEDCouplingFieldDouble *buildSubPart(const int *partBg, const int *partEnd) const; + MEDCOUPLING_EXPORT MEDCouplingFieldDouble *buildSubPartRange(int begin, int end, int step) const; + MEDCOUPLING_EXPORT MEDCouplingFieldDouble *deepCpy() const; + MEDCOUPLING_EXPORT MEDCouplingFieldDouble *clone(bool recDeepCpy) const; + MEDCOUPLING_EXPORT MEDCouplingFieldDouble *cloneWithMesh(bool recDeepCpy) const; + MEDCOUPLING_EXPORT MEDCouplingFieldDouble *buildNewTimeReprFromThis(TypeOfTimeDiscretization td, bool deepCopy) const; + MEDCOUPLING_EXPORT MEDCouplingFieldDouble *nodeToCellDiscretization() const; + MEDCOUPLING_EXPORT MEDCouplingFieldDouble *cellToNodeDiscretization() const; + MEDCOUPLING_EXPORT TypeOfTimeDiscretization getTimeDiscretization() const; + MEDCOUPLING_EXPORT void checkCoherency() const; + MEDCOUPLING_EXPORT void setNature(NatureOfField nat); + MEDCOUPLING_EXPORT void setTimeTolerance(double val) { _time_discr->setTimeTolerance(val); } + MEDCOUPLING_EXPORT double getTimeTolerance() const { return _time_discr->getTimeTolerance(); } + MEDCOUPLING_EXPORT void setIteration(int it) { _time_discr->setIteration(it); } + MEDCOUPLING_EXPORT void setEndIteration(int it) { _time_discr->setEndIteration(it); } + MEDCOUPLING_EXPORT void setOrder(int order) { _time_discr->setOrder(order); } + MEDCOUPLING_EXPORT void setEndOrder(int order) { _time_discr->setEndOrder(order); } + MEDCOUPLING_EXPORT void setTimeValue(double val) { _time_discr->setTimeValue(val); } + MEDCOUPLING_EXPORT void setEndTimeValue(double val) { _time_discr->setEndTimeValue(val); } + MEDCOUPLING_EXPORT void setTime(double val, int iteration, int order) { _time_discr->setTime(val,iteration,order); } + MEDCOUPLING_EXPORT void synchronizeTimeWithMesh(); + MEDCOUPLING_EXPORT void setStartTime(double val, int iteration, int order) { _time_discr->setStartTime(val,iteration,order); } + MEDCOUPLING_EXPORT void setEndTime(double val, int iteration, int order) { _time_discr->setEndTime(val,iteration,order); } + MEDCOUPLING_EXPORT double getTime(int& iteration, int& order) const { return _time_discr->getTime(iteration,order); } + MEDCOUPLING_EXPORT double getStartTime(int& iteration, int& order) const { return _time_discr->getStartTime(iteration,order); } + MEDCOUPLING_EXPORT double getEndTime(int& iteration, int& order) const { return _time_discr->getEndTime(iteration,order); } + MEDCOUPLING_EXPORT double getIJ(int tupleId, int compoId) const { return getArray()->getIJ(tupleId,compoId); } + MEDCOUPLING_EXPORT double getIJK(int cellId, int nodeIdInCell, int compoId) const; + MEDCOUPLING_EXPORT void setArray(DataArrayDouble *array); + MEDCOUPLING_EXPORT void setEndArray(DataArrayDouble *array); + MEDCOUPLING_EXPORT void setArrays(const std::vector<DataArrayDouble *>& arrs); + MEDCOUPLING_EXPORT const DataArrayDouble *getArray() const { return _time_discr->getArray(); } + MEDCOUPLING_EXPORT DataArrayDouble *getArray() { return _time_discr->getArray(); } + MEDCOUPLING_EXPORT const DataArrayDouble *getEndArray() const { return _time_discr->getEndArray(); } + MEDCOUPLING_EXPORT DataArrayDouble *getEndArray() { return _time_discr->getEndArray(); } + MEDCOUPLING_EXPORT std::vector<DataArrayDouble *> getArrays() const { std::vector<DataArrayDouble *> ret; _time_discr->getArrays(ret); return ret; } + MEDCOUPLING_EXPORT double accumulate(int compId) const; + MEDCOUPLING_EXPORT void accumulate(double *res) const; + MEDCOUPLING_EXPORT double getMaxValue() const; + MEDCOUPLING_EXPORT double getMaxValue2(DataArrayInt*& tupleIds) const; + MEDCOUPLING_EXPORT double getMinValue() const; + MEDCOUPLING_EXPORT double getMinValue2(DataArrayInt*& tupleIds) const; + MEDCOUPLING_EXPORT double getAverageValue() const; + MEDCOUPLING_EXPORT double norm2() const; + MEDCOUPLING_EXPORT double normMax() const; + MEDCOUPLING_EXPORT void getWeightedAverageValue(double *res, bool isWAbs=true) const; + MEDCOUPLING_EXPORT double getWeightedAverageValue(int compId, bool isWAbs=true) const; + MEDCOUPLING_EXPORT double normL1(int compId) const; + MEDCOUPLING_EXPORT void normL1(double *res) const; + MEDCOUPLING_EXPORT double normL2(int compId) const; + MEDCOUPLING_EXPORT void normL2(double *res) const; + MEDCOUPLING_EXPORT double integral(int compId, bool isWAbs) const; + MEDCOUPLING_EXPORT void integral(bool isWAbs, double *res) const; + MEDCOUPLING_EXPORT void getValueOnPos(int i, int j, int k, double *res) const; + MEDCOUPLING_EXPORT void getValueOn(const double *spaceLoc, double *res) const; + MEDCOUPLING_EXPORT void getValueOn(const double *spaceLoc, double time, double *res) const; + MEDCOUPLING_EXPORT DataArrayDouble *getValueOnMulti(const double *spaceLoc, int nbOfPoints) const; + MEDCOUPLING_EXPORT void applyLin(double a, double b, int compoId); + MEDCOUPLING_EXPORT void applyLin(double a, double b); + MEDCOUPLING_EXPORT MEDCouplingFieldDouble &operator=(double value); + MEDCOUPLING_EXPORT void fillFromAnalytic(int nbOfComp, FunctionToEvaluate func); + MEDCOUPLING_EXPORT void fillFromAnalytic(int nbOfComp, const std::string& func); + MEDCOUPLING_EXPORT void fillFromAnalytic2(int nbOfComp, const std::string& func); + MEDCOUPLING_EXPORT void fillFromAnalytic3(int nbOfComp, const std::vector<std::string>& varsOrder, const std::string& func); + MEDCOUPLING_EXPORT void applyFunc(int nbOfComp, FunctionToEvaluate func); + MEDCOUPLING_EXPORT void applyFunc(int nbOfComp, double val); + MEDCOUPLING_EXPORT void applyFunc(int nbOfComp, const std::string& func); + MEDCOUPLING_EXPORT void applyFunc2(int nbOfComp, const std::string& func); + MEDCOUPLING_EXPORT void applyFunc3(int nbOfComp, const std::vector<std::string>& varsOrder, const std::string& func); + MEDCOUPLING_EXPORT void applyFunc(const std::string& func); + MEDCOUPLING_EXPORT void applyFuncFast32(const std::string& func); + MEDCOUPLING_EXPORT void applyFuncFast64(const std::string& func); + MEDCOUPLING_EXPORT int getNumberOfComponents() const; + MEDCOUPLING_EXPORT int getNumberOfTuples() const; + MEDCOUPLING_EXPORT int getNumberOfValues() const; + MEDCOUPLING_EXPORT void updateTime() const; + MEDCOUPLING_EXPORT std::size_t getHeapMemorySizeWithoutChildren() const; + MEDCOUPLING_EXPORT std::vector<const BigMemoryObject *> getDirectChildrenWithNull() const; + // + MEDCOUPLING_EXPORT void getTinySerializationIntInformation(std::vector<int>& tinyInfo) const; + MEDCOUPLING_EXPORT void getTinySerializationDbleInformation(std::vector<double>& tinyInfo) const; + MEDCOUPLING_EXPORT void getTinySerializationStrInformation(std::vector<std::string>& tinyInfo) const; + MEDCOUPLING_EXPORT void resizeForUnserialization(const std::vector<int>& tinyInfoI, DataArrayInt *&dataInt, std::vector<DataArrayDouble *>& arrays); + MEDCOUPLING_EXPORT void checkForUnserialization(const std::vector<int>& tinyInfoI, const DataArrayInt *dataInt, const std::vector<DataArrayDouble *>& arrays); + MEDCOUPLING_EXPORT void finishUnserialization(const std::vector<int>& tinyInfoI, const std::vector<double>& tinyInfoD, const std::vector<std::string>& tinyInfoS); + MEDCOUPLING_EXPORT void serialize(DataArrayInt *&dataInt, std::vector<DataArrayDouble *>& arrays) const; + // + MEDCOUPLING_EXPORT void changeUnderlyingMesh(const MEDCouplingMesh *other, int levOfCheck, double precOnMesh, double eps=1e-15); + MEDCOUPLING_EXPORT void substractInPlaceDM(const MEDCouplingFieldDouble *f, int levOfCheck, double precOnMesh, double eps=1e-15); + MEDCOUPLING_EXPORT bool mergeNodes(double eps, double epsOnVals=1e-15); + MEDCOUPLING_EXPORT bool mergeNodes2(double eps, double epsOnVals=1e-15); + MEDCOUPLING_EXPORT bool zipCoords(double epsOnVals=1e-15); + MEDCOUPLING_EXPORT bool zipConnectivity(int compType, double epsOnVals=1e-15); + MEDCOUPLING_EXPORT MEDCouplingFieldDouble *extractSlice3D(const double *origin, const double *vec, double eps) const; + MEDCOUPLING_EXPORT bool simplexize(int policy); + MEDCOUPLING_EXPORT MEDCouplingFieldDouble *doublyContractedProduct() const; + MEDCOUPLING_EXPORT MEDCouplingFieldDouble *determinant() const; + MEDCOUPLING_EXPORT MEDCouplingFieldDouble *eigenValues() const; + MEDCOUPLING_EXPORT MEDCouplingFieldDouble *eigenVectors() const; + MEDCOUPLING_EXPORT MEDCouplingFieldDouble *inverse() const; + MEDCOUPLING_EXPORT MEDCouplingFieldDouble *trace() const; + MEDCOUPLING_EXPORT MEDCouplingFieldDouble *deviator() const; + MEDCOUPLING_EXPORT MEDCouplingFieldDouble *magnitude() const; + MEDCOUPLING_EXPORT MEDCouplingFieldDouble *maxPerTuple() const; + MEDCOUPLING_EXPORT void changeNbOfComponents(int newNbOfComp, double dftValue=0.); + MEDCOUPLING_EXPORT MEDCouplingFieldDouble *keepSelectedComponents(const std::vector<int>& compoIds) const; + MEDCOUPLING_EXPORT void setSelectedComponents(const MEDCouplingFieldDouble *f, const std::vector<int>& compoIds); + MEDCOUPLING_EXPORT void sortPerTuple(bool asc); + MEDCOUPLING_EXPORT static MEDCouplingFieldDouble *MergeFields(const MEDCouplingFieldDouble *f1, const MEDCouplingFieldDouble *f2); + MEDCOUPLING_EXPORT static MEDCouplingFieldDouble *MergeFields(const std::vector<const MEDCouplingFieldDouble *>& a); + MEDCOUPLING_EXPORT static MEDCouplingFieldDouble *MeldFields(const MEDCouplingFieldDouble *f1, const MEDCouplingFieldDouble *f2); + MEDCOUPLING_EXPORT static MEDCouplingFieldDouble *DotFields(const MEDCouplingFieldDouble *f1, const MEDCouplingFieldDouble *f2); + MEDCOUPLING_EXPORT MEDCouplingFieldDouble *dot(const MEDCouplingFieldDouble& other) const { return DotFields(this,&other); } + MEDCOUPLING_EXPORT static MEDCouplingFieldDouble *CrossProductFields(const MEDCouplingFieldDouble *f1, const MEDCouplingFieldDouble *f2); + MEDCOUPLING_EXPORT MEDCouplingFieldDouble *crossProduct(const MEDCouplingFieldDouble& other) const { return CrossProductFields(this,&other); } + MEDCOUPLING_EXPORT static MEDCouplingFieldDouble *MaxFields(const MEDCouplingFieldDouble *f1, const MEDCouplingFieldDouble *f2); + MEDCOUPLING_EXPORT MEDCouplingFieldDouble *max(const MEDCouplingFieldDouble& other) const { return MaxFields(this,&other); } + MEDCOUPLING_EXPORT static MEDCouplingFieldDouble *MinFields(const MEDCouplingFieldDouble *f1, const MEDCouplingFieldDouble *f2); + MEDCOUPLING_EXPORT MEDCouplingFieldDouble *min(const MEDCouplingFieldDouble& other) const { return MinFields(this,&other); } + MEDCOUPLING_EXPORT MEDCouplingFieldDouble *negate() const; + MEDCOUPLING_EXPORT MEDCouplingFieldDouble *operator+(const MEDCouplingFieldDouble& other) const throw(INTERP_KERNEL::Exception) { return AddFields(this,&other); } + MEDCOUPLING_EXPORT const MEDCouplingFieldDouble &operator+=(const MEDCouplingFieldDouble& other); + MEDCOUPLING_EXPORT static MEDCouplingFieldDouble *AddFields(const MEDCouplingFieldDouble *f1, const MEDCouplingFieldDouble *f2); + MEDCOUPLING_EXPORT MEDCouplingFieldDouble *operator-(const MEDCouplingFieldDouble& other) const throw(INTERP_KERNEL::Exception) { return SubstractFields(this,&other); } + MEDCOUPLING_EXPORT const MEDCouplingFieldDouble &operator-=(const MEDCouplingFieldDouble& other); + MEDCOUPLING_EXPORT static MEDCouplingFieldDouble *SubstractFields(const MEDCouplingFieldDouble *f1, const MEDCouplingFieldDouble *f2); + MEDCouplingFieldDouble *operator*(const MEDCouplingFieldDouble& other) const throw(INTERP_KERNEL::Exception) { return MultiplyFields(this,&other); } + MEDCOUPLING_EXPORT const MEDCouplingFieldDouble &operator*=(const MEDCouplingFieldDouble& other); + MEDCOUPLING_EXPORT static MEDCouplingFieldDouble *MultiplyFields(const MEDCouplingFieldDouble *f1, const MEDCouplingFieldDouble *f2); + MEDCOUPLING_EXPORT MEDCouplingFieldDouble *operator/(const MEDCouplingFieldDouble& other) const throw(INTERP_KERNEL::Exception) { return DivideFields(this,&other); } + MEDCOUPLING_EXPORT const MEDCouplingFieldDouble &operator/=(const MEDCouplingFieldDouble& other); + MEDCOUPLING_EXPORT static MEDCouplingFieldDouble *DivideFields(const MEDCouplingFieldDouble *f1, const MEDCouplingFieldDouble *f2); + MEDCOUPLING_EXPORT MEDCouplingFieldDouble *operator^(const MEDCouplingFieldDouble& other) const; + MEDCOUPLING_EXPORT const MEDCouplingFieldDouble &operator^=(const MEDCouplingFieldDouble& other); + MEDCOUPLING_EXPORT static MEDCouplingFieldDouble *PowFields(const MEDCouplingFieldDouble *f1, const MEDCouplingFieldDouble *f2); + MEDCOUPLING_EXPORT static std::string WriteVTK(const std::string& fileName, const std::vector<const MEDCouplingFieldDouble *>& fs, bool isBinary=true); + public: + MEDCOUPLING_EXPORT const MEDCouplingTimeDiscretization *getTimeDiscretizationUnderGround() const { return _time_discr; } + MEDCOUPLING_EXPORT MEDCouplingTimeDiscretization *getTimeDiscretizationUnderGround() { return _time_discr; } + MEDCOUPLING_EXPORT void reprQuickOverview(std::ostream& stream) const; + private: + MEDCouplingFieldDouble(TypeOfField type, TypeOfTimeDiscretization td); + MEDCouplingFieldDouble(const MEDCouplingFieldTemplate& ft, TypeOfTimeDiscretization td); + MEDCouplingFieldDouble(const MEDCouplingFieldDouble& other, bool deepCopy); + MEDCouplingFieldDouble(NatureOfField n, MEDCouplingTimeDiscretization *td, MEDCouplingFieldDiscretization *type); + ~MEDCouplingFieldDouble(); + private: + MEDCouplingTimeDiscretization *_time_discr; + }; +} + +#endif diff --git a/src/medtool/src/MEDCoupling/MEDCouplingFieldOverTime.cxx b/src/medtool/src/MEDCoupling/MEDCouplingFieldOverTime.cxx new file mode 100644 index 000000000..20d5f283f --- /dev/null +++ b/src/medtool/src/MEDCoupling/MEDCouplingFieldOverTime.cxx @@ -0,0 +1,165 @@ +// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 +// 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 "MEDCouplingFieldOverTime.hxx" +#include "MEDCouplingMesh.hxx" + +#include <cmath> + +using namespace ParaMEDMEM; + +MEDCouplingFieldOverTime *MEDCouplingFieldOverTime::New(const std::vector<MEDCouplingFieldDouble *>& fs) +{ + return new MEDCouplingFieldOverTime(fs); +} + +double MEDCouplingFieldOverTime::getTimeTolerance() const +{ + std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCouplingFieldDouble> >::const_iterator it=_fs.begin(); + if(_fs.empty()) + throw INTERP_KERNEL::Exception("MEDCouplingFieldOverTime::getTimeTolerance : empty set !"); + for(;it!=_fs.end();it++) + if((const MEDCouplingFieldDouble *)(*it)!=0) + return (*it)->getTimeTolerance(); + throw INTERP_KERNEL::Exception("MEDCouplingFieldOverTime::getTimeTolerance : only empty fields in this !"); +} + +void MEDCouplingFieldOverTime::checkCoherency() const +{ + MEDCouplingMultiFields::checkCoherency(); + std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCouplingFieldDouble> >::const_iterator it=_fs.begin(); + for(;it!=_fs.end();it++) + if((*it)->getTimeDiscretization()==NO_TIME) + { + std::ostringstream oss; oss << "MEDCouplingFieldOverTime::checkCoherency : At rank #" << std::distance(_fs.begin(),it) << " the field has no time !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + if(_fs.empty()) + return ; + it=_fs.begin(); + const MEDCouplingFieldDouble& ref=*(*(it++)); + int tt1,tt2; + double reft=ref.getEndTime(tt1,tt2); + double eps=getTimeTolerance(); + int id=1; + for(;it!=_fs.end();it++,id++) + { + if(!ref.getMesh()->areCompatibleForMerge((*it)->getMesh())) + { + std::ostringstream oss; oss << "Field slice at rank #" << id << " is not compatible with the first !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + double curt=(*it)->getStartTime(tt1,tt2); + if(curt<reft-eps) + throw INTERP_KERNEL::Exception("MEDCouplingFieldOverTime::checkCoherency : fields are NOT sorted properly in ascending time !"); + reft=(*it)->getEndTime(tt1,tt2); + } +} + +std::string MEDCouplingFieldOverTime::simpleRepr() const +{ + std::ostringstream ret; + ret << "MEDCouplingFieldOverTime with name : \"" << getName() << "\"\n"; + ret << "Description of MEDCouplingFieldOverTime is : \"" << getDescription() << "\"\n"; + ret << "Number of discretization : " << _fs.size() << "\n"; + ret << "Number of different meshes : "; + std::vector<MEDCouplingMesh *> ms; + std::vector<int> refms; + try + { + ms=getDifferentMeshes(refms); + ret << ms.size() << "\n"; + } + catch(INTERP_KERNEL::Exception& /*e*/) + { ret << "Current instance is INVALID !\n"; } + try + { + MEDCouplingDefinitionTime dt=getDefinitionTimeZone(); + dt.appendRepr(ret); + } + catch(INTERP_KERNEL::Exception& /*e*/) + { ret << "Definition zone is INVALID !\n"; } + return ret.str(); +} + +bool MEDCouplingFieldOverTime::isEqual(const MEDCouplingMultiFields *other, double meshPrec, double valsPrec) const +{ + if(!MEDCouplingMultiFields::isEqual(other,meshPrec,valsPrec)) + return false; + const MEDCouplingFieldOverTime *otherC=dynamic_cast<const MEDCouplingFieldOverTime *>(other); + if(!otherC) + return false; + // to implement + return true; +} + +bool MEDCouplingFieldOverTime::isEqualWithoutConsideringStr(const MEDCouplingMultiFields *other, double meshPrec, double valsPrec) const +{ + if(!MEDCouplingMultiFields::isEqualWithoutConsideringStr(other,meshPrec,valsPrec)) + return false; + const MEDCouplingFieldOverTime *otherC=dynamic_cast<const MEDCouplingFieldOverTime *>(other); + if(!otherC) + return false; + // to implement + return true; +} + +std::vector<MEDCouplingMesh *> MEDCouplingFieldOverTime::getMeshes() const +{ + checkCoherency(); + return MEDCouplingMultiFields::getMeshes(); +} + +std::vector<MEDCouplingMesh *> MEDCouplingFieldOverTime::getDifferentMeshes(std::vector<int>& refs) const +{ + checkCoherency(); + return MEDCouplingMultiFields::getDifferentMeshes(refs); +} + +std::vector<DataArrayDouble *> MEDCouplingFieldOverTime::getArrays() const +{ + checkCoherency(); + return MEDCouplingMultiFields::getArrays(); +} + +std::vector<DataArrayDouble *> MEDCouplingFieldOverTime::getDifferentArrays(std::vector< std::vector<int> >& refs) const +{ + checkCoherency(); + return MEDCouplingMultiFields::getDifferentArrays(refs); +} + +MEDCouplingDefinitionTime MEDCouplingFieldOverTime::getDefinitionTimeZone() const +{ + std::vector< std::vector<int> > tmp; + getDifferentArrays(tmp); + std::vector<const MEDCouplingFieldDouble *> tmp2(_fs.begin(),_fs.end()); + std::vector<int> tmp3; + getDifferentMeshes(tmp3); + return MEDCouplingDefinitionTime(tmp2,tmp3,tmp); +} + +MEDCouplingFieldOverTime::MEDCouplingFieldOverTime(const std::vector<MEDCouplingFieldDouble *>& fs):MEDCouplingMultiFields(fs) +{ + checkCoherency(); +} + +MEDCouplingFieldOverTime::MEDCouplingFieldOverTime() +{ +} diff --git a/src/medtool/src/MEDCoupling/MEDCouplingFieldOverTime.hxx b/src/medtool/src/MEDCoupling/MEDCouplingFieldOverTime.hxx new file mode 100644 index 000000000..4d4351ca7 --- /dev/null +++ b/src/medtool/src/MEDCoupling/MEDCouplingFieldOverTime.hxx @@ -0,0 +1,56 @@ +// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 +// 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_MEDCOUPLINGFIELDOVERTIME_HXX__ +#define __PARAMEDMEM_MEDCOUPLINGFIELDOVERTIME_HXX__ + +#include "MEDCouplingMultiFields.hxx" +#include "MEDCouplingDefinitionTime.hxx" +#include "MEDCouplingFieldDouble.hxx" + +#include <vector> + +namespace ParaMEDMEM +{ + class MEDCouplingFieldOverTime : public MEDCouplingMultiFields + { + public: + MEDCOUPLING_EXPORT static MEDCouplingFieldOverTime *New(const std::vector<MEDCouplingFieldDouble *>& fs); + MEDCOUPLING_EXPORT void checkCoherency() const; + MEDCOUPLING_EXPORT double getTimeTolerance() const; + MEDCOUPLING_EXPORT std::string simpleRepr() const; + MEDCOUPLING_EXPORT bool isEqual(const MEDCouplingMultiFields *other, double meshPrec, double valsPrec) const; + MEDCOUPLING_EXPORT bool isEqualWithoutConsideringStr(const MEDCouplingMultiFields *other, double meshPrec, double valsPrec) const; + //void getIdsToFetch(double time, int& fieldId, int& arrId, int& meshId) const; + //void setFieldOnId(int fieldId, MEDCouplingFieldDouble *f); + //void dispatchPointers(); + MEDCOUPLING_EXPORT std::vector<MEDCouplingMesh *> getMeshes() const; + MEDCOUPLING_EXPORT std::vector<MEDCouplingMesh *> getDifferentMeshes(std::vector<int>& refs) const; + MEDCOUPLING_EXPORT std::vector<DataArrayDouble *> getArrays() const; + MEDCOUPLING_EXPORT std::vector<DataArrayDouble *> getDifferentArrays(std::vector< std::vector<int> >& refs) const; + MEDCOUPLING_EXPORT MEDCouplingDefinitionTime getDefinitionTimeZone() const; + protected: + MEDCOUPLING_EXPORT MEDCouplingFieldOverTime(); + private: + MEDCouplingFieldOverTime(const std::vector<MEDCouplingFieldDouble *>& fs); + }; +} + +#endif diff --git a/src/medtool/src/MEDCoupling/MEDCouplingFieldTemplate.cxx b/src/medtool/src/MEDCoupling/MEDCouplingFieldTemplate.cxx new file mode 100644 index 000000000..4bb5a3974 --- /dev/null +++ b/src/medtool/src/MEDCoupling/MEDCouplingFieldTemplate.cxx @@ -0,0 +1,159 @@ +// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 +// 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 "MEDCouplingFieldTemplate.hxx" +#include "MEDCouplingMesh.hxx" +#include "MEDCouplingFieldDouble.hxx" +#include "MEDCouplingFieldDiscretization.hxx" + +#include <sstream> + +using namespace ParaMEDMEM; + +MEDCouplingFieldTemplate *MEDCouplingFieldTemplate::New(const MEDCouplingFieldDouble& f) +{ + return new MEDCouplingFieldTemplate(f); +} + +/*! + * The user should \b not use this method. Only useful for CORBA serialization/unserialization. + */ +MEDCouplingFieldTemplate *MEDCouplingFieldTemplate::New(TypeOfField type) +{ + return new MEDCouplingFieldTemplate(type); +} + +MEDCouplingFieldTemplate::MEDCouplingFieldTemplate(const MEDCouplingFieldDouble& f):MEDCouplingField(f,false) +{ + forceTimeOfThis(f); + checkCoherency(); +} + +MEDCouplingFieldTemplate::MEDCouplingFieldTemplate(TypeOfField type):MEDCouplingField(type) +{ +} + +void MEDCouplingFieldTemplate::checkCoherency() const +{ + if(_mesh==0) + throw INTERP_KERNEL::Exception("MEDCouplingFieldTemplate::checkCoherency : Empty mesh !"); +} + +std::string MEDCouplingFieldTemplate::simpleRepr() const +{ + std::ostringstream ret; + ret << "FieldTemplate with name : \"" << getName() << "\"\n"; + ret << "Description of field is : \"" << getDescription() << "\"\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 + ret << "Mesh support information : No mesh set !\n"; + return ret.str(); +} + +std::string MEDCouplingFieldTemplate::advancedRepr() const +{ + return simpleRepr(); +} + +void MEDCouplingFieldTemplate::getTinySerializationIntInformation(std::vector<int>& 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); + std::vector<int> tinyInfo2; + _type->getTinySerializationIntInformation(tinyInfo2); + tinyInfo.insert(tinyInfo.end(),tinyInfo2.begin(),tinyInfo2.end()); + tinyInfo.push_back((int)tinyInfo2.size()); +} + +void MEDCouplingFieldTemplate::getTinySerializationDbleInformation(std::vector<double>& tinyInfo) const +{ + if(!((const MEDCouplingFieldDiscretization *)_type)) + throw INTERP_KERNEL::Exception("No spatial discretization underlying this field to perform getTinySerializationDbleInformation !"); + tinyInfo.clear(); + _type->getTinySerializationDbleInformation(tinyInfo); +} + +void MEDCouplingFieldTemplate::getTinySerializationStrInformation(std::vector<std::string>& tinyInfo) const +{ + tinyInfo.clear(); + tinyInfo.push_back(_name); + tinyInfo.push_back(_desc); +} + +void MEDCouplingFieldTemplate::resizeForUnserialization(const std::vector<int>& tinyInfoI, DataArrayInt *&dataInt) +{ + if(!((const MEDCouplingFieldDiscretization *)_type)) + throw INTERP_KERNEL::Exception("No spatial discretization underlying this field to perform resizeForUnserialization !"); + dataInt=0; + std::vector<int> tinyInfoITmp(tinyInfoI.begin()+2,tinyInfoI.end()); + _type->resizeForUnserialization(tinyInfoITmp,dataInt); +} + +void MEDCouplingFieldTemplate::finishUnserialization(const std::vector<int>& tinyInfoI, const std::vector<double>& tinyInfoD, const std::vector<std::string>& 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]; + _desc=tinyInfoS[1]; +} + +void MEDCouplingFieldTemplate::serialize(DataArrayInt *&dataInt) const +{ + _type->getSerializationIntArray(dataInt); +} + +void MEDCouplingFieldTemplate::reprQuickOverview(std::ostream& stream) const +{ + 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/medtool/src/MEDCoupling/MEDCouplingFieldTemplate.hxx b/src/medtool/src/MEDCoupling/MEDCouplingFieldTemplate.hxx new file mode 100644 index 000000000..8b3a3c8dd --- /dev/null +++ b/src/medtool/src/MEDCoupling/MEDCouplingFieldTemplate.hxx @@ -0,0 +1,59 @@ +// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 +// 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_MEDCOUPLINGFIELDTEMPLATE_HXX__ +#define __PARAMEDMEM_MEDCOUPLINGFIELDTEMPLATE_HXX__ + +#include "MEDCouplingField.hxx" + +namespace ParaMEDMEM +{ + class MEDCouplingFieldDouble; + /*! + * \brief A field template can be seen as a field without array of values. + * + * A field template instance aggregates a MEDCouplingMesh instance and a spatial discretization object (instance of MEDCouplingFieldDiscretization). + * + * Instances of type MEDCouplingFieldTemplate are the most appropriate for preparation of matrix using MEDCouplingRemapper::prepareEx. + */ + class MEDCouplingFieldTemplate : public MEDCouplingField + { + public: + MEDCOUPLING_EXPORT static MEDCouplingFieldTemplate *New(const MEDCouplingFieldDouble& f); + MEDCOUPLING_EXPORT static MEDCouplingFieldTemplate *New(TypeOfField type); + MEDCOUPLING_EXPORT std::string simpleRepr() const; + MEDCOUPLING_EXPORT std::string advancedRepr() const; + MEDCOUPLING_EXPORT void checkCoherency() const; + // + MEDCOUPLING_EXPORT void getTinySerializationIntInformation(std::vector<int>& tinyInfo) const; + MEDCOUPLING_EXPORT void getTinySerializationDbleInformation(std::vector<double>& tinyInfo) const; + MEDCOUPLING_EXPORT void getTinySerializationStrInformation(std::vector<std::string>& tinyInfo) const; + MEDCOUPLING_EXPORT void resizeForUnserialization(const std::vector<int>& tinyInfoI, DataArrayInt *&dataInt); + MEDCOUPLING_EXPORT void finishUnserialization(const std::vector<int>& tinyInfoI, const std::vector<double>& tinyInfoD, const std::vector<std::string>& tinyInfoS); + MEDCOUPLING_EXPORT void serialize(DataArrayInt *&dataInt) const; + // + MEDCOUPLING_EXPORT void reprQuickOverview(std::ostream& stream) const; + private: + MEDCouplingFieldTemplate(const MEDCouplingFieldDouble& f); + MEDCouplingFieldTemplate(TypeOfField type); + }; +} + +#endif diff --git a/src/medtool/src/MEDCoupling/MEDCouplingGaussLocalization.cxx b/src/medtool/src/MEDCoupling/MEDCouplingGaussLocalization.cxx new file mode 100644 index 000000000..4af4bd6c3 --- /dev/null +++ b/src/medtool/src/MEDCoupling/MEDCouplingGaussLocalization.cxx @@ -0,0 +1,268 @@ +// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 +// 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 "MEDCouplingGaussLocalization.hxx" +#include "CellModel.hxx" + +#include <cmath> +#include <numeric> +#include <sstream> +#include <iterator> +#include <algorithm> + +ParaMEDMEM::MEDCouplingGaussLocalization::MEDCouplingGaussLocalization(INTERP_KERNEL::NormalizedCellType type, const std::vector<double>& refCoo, + const std::vector<double>& gsCoo, const std::vector<double>& w) +try:_type(type),_ref_coord(refCoo),_gauss_coord(gsCoo),_weight(w) +{ + checkCoherency(); +} +catch(INTERP_KERNEL::Exception& e) +{ + _type=INTERP_KERNEL::NORM_ERROR; + _ref_coord.clear(); + _gauss_coord.clear(); + _weight.clear(); + throw e; +} + +ParaMEDMEM::MEDCouplingGaussLocalization::MEDCouplingGaussLocalization(INTERP_KERNEL::NormalizedCellType typ) +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) +{ + INTERP_KERNEL::CellModel::GetCellModel(typ);//throws if not found. This is a check + _type=typ; +} + +void ParaMEDMEM::MEDCouplingGaussLocalization::checkCoherency() const +{ + const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(_type); + int nbNodes=cm.getNumberOfNodes(); + int dim=cm.getDimension(); + if(!cm.isDynamic()) + { + if((int)_ref_coord.size()!=nbNodes*dim) + { + std::ostringstream oss; oss << "Invalid size of refCoo : expecting to be : " << nbNodes << " (nbNodePerCell) * " << dim << " (dim) !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + } + if(_gauss_coord.size()!=dim*_weight.size()) + { + std::ostringstream oss; oss << "Invalid gsCoo size and weight size : gsCoo.size() must be equal to _weight.size() * " << dim << " (dim) !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } +} + +int ParaMEDMEM::MEDCouplingGaussLocalization::getDimension() const +{ + if(_weight.empty()) + return -1; + return (int)_gauss_coord.size()/(int)_weight.size(); +} + +int ParaMEDMEM::MEDCouplingGaussLocalization::getNumberOfPtsInRefCell() const +{ + int dim=getDimension(); + if(dim==0) + return -1; + return (int)_ref_coord.size()/dim; +} + +std::string ParaMEDMEM::MEDCouplingGaussLocalization::getStringRepr() const +{ + std::ostringstream oss; + oss << "CellType : " << INTERP_KERNEL::CellModel::GetCellModel(_type).getRepr() << std::endl; + oss << "Ref coords : "; std::copy(_ref_coord.begin(),_ref_coord.end(),std::ostream_iterator<double>(oss,", ")); oss << std::endl; + oss << "Localization coords : "; std::copy(_gauss_coord.begin(),_gauss_coord.end(),std::ostream_iterator<double>(oss,", ")); oss << std::endl; + oss << "Weight : "; std::copy(_weight.begin(),_weight.end(),std::ostream_iterator<double>(oss,", ")); oss << std::endl; + return oss.str(); +} + +std::size_t ParaMEDMEM::MEDCouplingGaussLocalization::getMemorySize() 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) + return false; + if(!AreAlmostEqual(_ref_coord,other._ref_coord,eps)) + return false; + if(!AreAlmostEqual(_gauss_coord,other._gauss_coord,eps)) + return false; + if(!AreAlmostEqual(_weight,other._weight,eps)) + return false; + return true; +} + +double ParaMEDMEM::MEDCouplingGaussLocalization::getRefCoord(int ptIdInCell, int comp) const +{ + const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(_type); + int nbNodes=cm.getNumberOfNodes(); + int dim=cm.getDimension(); + if(ptIdInCell<0 || ptIdInCell>=nbNodes) + throw INTERP_KERNEL::Exception("ptIdInCell specified is invalid : must be in [0;nbNodesPerCell) !"); + if(comp<0 || comp>=dim) + throw INTERP_KERNEL::Exception("comp specified is invalid : must be in [0:dimOfCell) !"); + return _ref_coord[ptIdInCell*dim+comp]; +} + +double ParaMEDMEM::MEDCouplingGaussLocalization::getGaussCoord(int gaussPtIdInCell, int comp) const +{ + int dim=checkCoherencyOfRequest(gaussPtIdInCell,comp); + return _gauss_coord[gaussPtIdInCell*dim+comp]; +} + +double ParaMEDMEM::MEDCouplingGaussLocalization::getWeight(int gaussPtIdInCell, double newVal) const +{ + checkCoherencyOfRequest(gaussPtIdInCell,0); + return _weight[gaussPtIdInCell]; +} + +/*! + * Completely useless method for end user. Only for CORBA MPI serialization/unserialization. + * push at the end of tinyInfo its basic serialization info. The size of pushed data is always the same. + * @param tinyInfo inout parameter. + */ +void ParaMEDMEM::MEDCouplingGaussLocalization::pushTinySerializationIntInfo(std::vector<int>& tinyInfo) const +{ + tinyInfo.push_back((int)_type); + tinyInfo.push_back(getNumberOfPtsInRefCell()); + tinyInfo.push_back(getNumberOfGaussPt()); +} + +/*! + * Completely useless method for end user. Only for CORBA MPI serialization/unserialization. + * push at the end of tinyInfo its basic serialization info. The size of pushed data is \b NOT always the same contrary to pushTinySerializationIntInfo. + * @param tinyInfo inout parameter. + */ +void ParaMEDMEM::MEDCouplingGaussLocalization::pushTinySerializationDblInfo(std::vector<double>& tinyInfo) const +{ + tinyInfo.insert(tinyInfo.end(),_ref_coord.begin(),_ref_coord.end()); + tinyInfo.insert(tinyInfo.end(),_gauss_coord.begin(),_gauss_coord.end()); + tinyInfo.insert(tinyInfo.end(),_weight.begin(),_weight.end()); +} + +/*! + * This method operates the exact inverse operation than ParaMEDMEM::MEDCouplingGaussLocalization::pushTinySerializationDblInfo method. This is one of the last step of unserialization process. + * This method should be called on an object resized by buildNewInstanceFromTinyInfo static method. + * This method takes in argument a pointer 'vals' that point to the begin of double data pushed remotely by pushTinySerializationDblInfo method. + * This method returns the pointer 'vals' with an offset of size what it has been read in this method. + */ +const double *ParaMEDMEM::MEDCouplingGaussLocalization::fillWithValues(const double *vals) +{ + const double *work=vals; + std::copy(work,work+_ref_coord.size(),_ref_coord.begin()); + work+=_ref_coord.size(); + std::copy(work,work+_gauss_coord.size(),_gauss_coord.begin()); + work+=_gauss_coord.size(); + std::copy(work,work+_weight.size(),_weight.begin()); + work+=_weight.size(); + return work; +} + +/*! + * This method sets the comp_th component of ptIdInCell_th point coordinate of reference element of type this->_type. + * @throw if not 0<=ptIdInCell<nbOfNodePerCell or if not 0<=comp<dim + */ +void ParaMEDMEM::MEDCouplingGaussLocalization::setRefCoord(int ptIdInCell, int comp, double newVal) +{ + const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(_type); + int nbNodes=cm.getNumberOfNodes(); + int dim=cm.getDimension(); + if(ptIdInCell<0 || ptIdInCell>=nbNodes) + throw INTERP_KERNEL::Exception("ptIdInCell specified is invalid : must be in [0;nbNodesPerCell) !"); + if(comp<0 || comp>=dim) + throw INTERP_KERNEL::Exception("comp specified is invalid : must be in [0:dimOfCell) !"); + _ref_coord[ptIdInCell*dim+comp]=newVal; +} + +void ParaMEDMEM::MEDCouplingGaussLocalization::setGaussCoord(int gaussPtIdInCell, int comp, double newVal) +{ + int dim=checkCoherencyOfRequest(gaussPtIdInCell,comp); + _gauss_coord[gaussPtIdInCell*dim+comp]=newVal; +} + +void ParaMEDMEM::MEDCouplingGaussLocalization::setWeight(int gaussPtIdInCell, double newVal) +{ + checkCoherencyOfRequest(gaussPtIdInCell,0); + _weight[gaussPtIdInCell]=newVal; +} + +void ParaMEDMEM::MEDCouplingGaussLocalization::setRefCoords(const std::vector<double>& refCoo) +{ + _ref_coord=refCoo; +} + +void ParaMEDMEM::MEDCouplingGaussLocalization::setGaussCoords(const std::vector<double>& gsCoo) +{ + _gauss_coord=gsCoo; +} + +void ParaMEDMEM::MEDCouplingGaussLocalization::setWeights(const std::vector<double>& w) +{ + _weight=w; +} + +/*! + * The format of 'tinyData' parameter is the same than pushed in method ParaMEDMEM::MEDCouplingGaussLocalization::pushTinySerializationIntInfo. + */ +ParaMEDMEM::MEDCouplingGaussLocalization ParaMEDMEM::MEDCouplingGaussLocalization::BuildNewInstanceFromTinyInfo(int dim, const std::vector<int>& tinyData) +{ + std::vector<double> v1(dim*tinyData[1]),v2(dim*tinyData[2]),v3(tinyData[2]); + return ParaMEDMEM::MEDCouplingGaussLocalization((INTERP_KERNEL::NormalizedCellType)tinyData[0],v1,v2,v3); +} + +int ParaMEDMEM::MEDCouplingGaussLocalization::checkCoherencyOfRequest(int gaussPtIdInCell, int comp) const +{ + const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(_type); + int dim=cm.getDimension(); + int nbGsPts=getNumberOfGaussPt(); + if(gaussPtIdInCell<0 || gaussPtIdInCell>=nbGsPts) + throw INTERP_KERNEL::Exception("gaussPtIdInCell specified is invalid : must be in [0:nbGsPts) !"); + if(comp<0 || comp>=dim) + throw INTERP_KERNEL::Exception("comp specified is invalid : must be in [0:dimOfCell) !"); + return dim; +} + +bool ParaMEDMEM::MEDCouplingGaussLocalization::AreAlmostEqual(const std::vector<double>& v1, const std::vector<double>& v2, double eps) +{ + std::size_t sz=v1.size(); + if(sz!=v2.size()) + return false; + std::vector<double> tmp(sz); + std::transform(v1.begin(),v1.end(),v2.begin(),tmp.begin(),std::minus<double>()); + std::transform(tmp.begin(),tmp.end(),tmp.begin(),std::ptr_fun<double,double>(fabs)); + return *std::max_element(tmp.begin(),tmp.end())<eps; +} diff --git a/src/medtool/src/MEDCoupling/MEDCouplingGaussLocalization.hxx b/src/medtool/src/MEDCoupling/MEDCouplingGaussLocalization.hxx new file mode 100644 index 000000000..eebdccaf6 --- /dev/null +++ b/src/medtool/src/MEDCoupling/MEDCouplingGaussLocalization.hxx @@ -0,0 +1,78 @@ +// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 +// 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_MEDCOUPLINGGAUSSLOCALIZATION_HXX__ +#define __PARAMEDMEM_MEDCOUPLINGGAUSSLOCALIZATION_HXX__ + +#include "MEDCoupling.hxx" +#include "NormalizedUnstructuredMesh.hxx" +#include "InterpKernelException.hxx" + +#include <vector> + +namespace ParaMEDMEM +{ + class MEDCouplingMesh; + + class MEDCouplingGaussLocalization + { + public: + MEDCOUPLING_EXPORT MEDCouplingGaussLocalization(INTERP_KERNEL::NormalizedCellType type, const std::vector<double>& refCoo, + const std::vector<double>& gsCoo, const std::vector<double>& w); + MEDCOUPLING_EXPORT MEDCouplingGaussLocalization(INTERP_KERNEL::NormalizedCellType typ); + MEDCOUPLING_EXPORT INTERP_KERNEL::NormalizedCellType getType() const { return _type; } + MEDCOUPLING_EXPORT void setType(INTERP_KERNEL::NormalizedCellType typ); + MEDCOUPLING_EXPORT int getNumberOfGaussPt() const { return (int)_weight.size(); } + MEDCOUPLING_EXPORT int getDimension() const; + MEDCOUPLING_EXPORT int getNumberOfPtsInRefCell() const; + MEDCOUPLING_EXPORT std::string getStringRepr() const; + MEDCOUPLING_EXPORT std::size_t getMemorySize() const; + MEDCOUPLING_EXPORT void checkCoherency() const; + MEDCOUPLING_EXPORT bool isEqual(const MEDCouplingGaussLocalization& other, double eps) const; + MEDCOUPLING_EXPORT void pushTinySerializationIntInfo(std::vector<int>& tinyInfo) const; + MEDCOUPLING_EXPORT void pushTinySerializationDblInfo(std::vector<double>& tinyInfo) const; + MEDCOUPLING_EXPORT const double *fillWithValues(const double *vals); + // + MEDCOUPLING_EXPORT const std::vector<double>& getRefCoords() const { return _ref_coord; } + MEDCOUPLING_EXPORT double getRefCoord(int ptIdInCell, int comp) const; + MEDCOUPLING_EXPORT const std::vector<double>& getGaussCoords() const { return _gauss_coord; } + MEDCOUPLING_EXPORT double getGaussCoord(int gaussPtIdInCell, int comp) const; + MEDCOUPLING_EXPORT const std::vector<double>& getWeights() const { return _weight; } + MEDCOUPLING_EXPORT double getWeight(int gaussPtIdInCell, double newVal) const; + MEDCOUPLING_EXPORT void setRefCoord(int ptIdInCell, int comp, double newVal); + MEDCOUPLING_EXPORT void setGaussCoord(int gaussPtIdInCell, int comp, double newVal); + MEDCOUPLING_EXPORT void setWeight(int gaussPtIdInCell, double newVal); + MEDCOUPLING_EXPORT void setRefCoords(const std::vector<double>& refCoo); + MEDCOUPLING_EXPORT void setGaussCoords(const std::vector<double>& gsCoo); + MEDCOUPLING_EXPORT void setWeights(const std::vector<double>& w); + // + MEDCOUPLING_EXPORT static MEDCouplingGaussLocalization BuildNewInstanceFromTinyInfo(int dim, const std::vector<int>& tinyData); + MEDCOUPLING_EXPORT static bool AreAlmostEqual(const std::vector<double>& v1, const std::vector<double>& v2, double eps); + private: + int checkCoherencyOfRequest(int gaussPtIdInCell, int comp) const; + private: + INTERP_KERNEL::NormalizedCellType _type; + std::vector<double> _ref_coord; + std::vector<double> _gauss_coord; + std::vector<double> _weight; + }; +} + +#endif diff --git a/src/medtool/src/MEDCoupling/MEDCouplingIMesh.cxx b/src/medtool/src/MEDCoupling/MEDCouplingIMesh.cxx new file mode 100644 index 000000000..e7a4ae0ac --- /dev/null +++ b/src/medtool/src/MEDCoupling/MEDCouplingIMesh.cxx @@ -0,0 +1,1495 @@ +// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 +// 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 "MEDCouplingIMesh.hxx" +#include "MEDCouplingCMesh.hxx" +#include "MEDCouplingMemArray.hxx" +#include "MEDCouplingFieldDouble.hxx" + +#include <functional> +#include <algorithm> +#include <sstream> +#include <numeric> + +using namespace ParaMEDMEM; + +MEDCouplingIMesh::MEDCouplingIMesh():_space_dim(-1) +{ + _origin[0]=0.; _origin[1]=0.; _origin[2]=0.; + _dxyz[0]=0.; _dxyz[1]=0.; _dxyz[2]=0.; + _structure[0]=0; _structure[1]=0; _structure[2]=0; +} + +MEDCouplingIMesh::MEDCouplingIMesh(const MEDCouplingIMesh& other, bool deepCopy):MEDCouplingStructuredMesh(other,deepCopy),_space_dim(other._space_dim),_axis_unit(other._axis_unit) +{ + _origin[0]=other._origin[0]; _origin[1]=other._origin[1]; _origin[2]=other._origin[2]; + _dxyz[0]=other._dxyz[0]; _dxyz[1]=other._dxyz[1]; _dxyz[2]=other._dxyz[2]; + _structure[0]=other._structure[0]; _structure[1]=other._structure[1]; _structure[2]=other._structure[2]; +} + +MEDCouplingIMesh::~MEDCouplingIMesh() +{ +} + +MEDCouplingIMesh *MEDCouplingIMesh::New() +{ + return new MEDCouplingIMesh; +} + +MEDCouplingIMesh *MEDCouplingIMesh::New(const std::string& meshName, int spaceDim, const int *nodeStrctStart, const int *nodeStrctStop, + const double *originStart, const double *originStop, const double *dxyzStart, const double *dxyzStop) +{ + MEDCouplingAutoRefCountObjectPtr<MEDCouplingIMesh> ret(new MEDCouplingIMesh); + ret->setName(meshName); + ret->setSpaceDimension(spaceDim); + ret->setNodeStruct(nodeStrctStart,nodeStrctStop); + ret->setOrigin(originStart,originStop); + ret->setDXYZ(dxyzStart,dxyzStop); + return ret.retn(); +} + +MEDCouplingMesh *MEDCouplingIMesh::deepCpy() const +{ + return clone(true); +} + +MEDCouplingIMesh *MEDCouplingIMesh::clone(bool recDeepCpy) const +{ + return new MEDCouplingIMesh(*this,recDeepCpy); +} + +/*! + * This method creates a copy of \a this enlarged by \a ghostLev cells on each axis. + * If \a ghostLev equal to 0 this method behaves as MEDCouplingIMesh::clone. + * + * \param [in] ghostLev - the ghost level expected + * \return MEDCouplingIMesh * - a newly alloacted object to be managed by the caller. + * \throw if \a ghostLev < 0. + */ +MEDCouplingIMesh *MEDCouplingIMesh::buildWithGhost(int ghostLev) const +{ + if(ghostLev<0) + throw INTERP_KERNEL::Exception("MEDCouplingIMesh::buildWithGhost : the ghostLev must be >= 0 !"); + checkCoherency(); + int spaceDim(getSpaceDimension()); + double origin[3],dxyz[3]; + int structure[3]; + for(int i=0;i<spaceDim;i++) + { + origin[i]=_origin[i]-ghostLev*_dxyz[i]; + dxyz[i]=_dxyz[i]; + structure[i]=_structure[i]+2*ghostLev; + } + MEDCouplingAutoRefCountObjectPtr<MEDCouplingIMesh> ret(MEDCouplingIMesh::New(getName(),spaceDim,structure,structure+spaceDim,origin,origin+spaceDim,dxyz,dxyz+spaceDim)); + ret->copyTinyInfoFrom(this); + return ret.retn(); +} + +void MEDCouplingIMesh::setNodeStruct(const int *nodeStrctStart, const int *nodeStrctStop) +{ + checkSpaceDimension(); + int sz((int)std::distance(nodeStrctStart,nodeStrctStop)); + if(sz!=_space_dim) + throw INTERP_KERNEL::Exception("MEDCouplingIMesh::setNodeStruct : input vector of node structure has not the right size ! Or change space dimension before calling it !"); + std::copy(nodeStrctStart,nodeStrctStop,_structure); + declareAsNew(); +} + +std::vector<int> MEDCouplingIMesh::getNodeStruct() const +{ + checkSpaceDimension(); + return std::vector<int>(_structure,_structure+_space_dim); +} + +void MEDCouplingIMesh::setOrigin(const double *originStart, const double *originStop) +{ + checkSpaceDimension(); + int sz((int)std::distance(originStart,originStop)); + if(sz!=_space_dim) + throw INTERP_KERNEL::Exception("MEDCouplingIMesh::setOrigin : input vector of origin vector has not the right size ! Or change space dimension before calling it !"); + std::copy(originStart,originStop,_origin); + declareAsNew(); +} + +std::vector<double> MEDCouplingIMesh::getOrigin() const +{ + checkSpaceDimension(); + return std::vector<double>(_origin,_origin+_space_dim); +} + +void MEDCouplingIMesh::setDXYZ(const double *dxyzStart, const double *dxyzStop) +{ + checkSpaceDimension(); + int sz((int)std::distance(dxyzStart,dxyzStop)); + if(sz!=_space_dim) + throw INTERP_KERNEL::Exception("MEDCouplingIMesh::setDXYZ : input vector of dxyz vector has not the right size ! Or change space dimension before calling it !"); + std::copy(dxyzStart,dxyzStop,_dxyz); + declareAsNew(); +} + +std::vector<double> MEDCouplingIMesh::getDXYZ() const +{ + checkSpaceDimension(); + return std::vector<double>(_dxyz,_dxyz+_space_dim); +} + +void MEDCouplingIMesh::setAxisUnit(const std::string& unitName) +{ + _axis_unit=unitName; + declareAsNew(); +} + +std::string MEDCouplingIMesh::getAxisUnit() const +{ + return _axis_unit; +} + +/*! + * This method returns the measure of any cell in \a this. + * This specific method of image grid mesh utilizes the fact that any cell in \a this have the same measure. + * The value returned by this method is those used to feed the returned field in the MEDCouplingIMesh::getMeasureField. + * + * \sa getMeasureField + */ +double MEDCouplingIMesh::getMeasureOfAnyCell() const +{ + checkCoherency(); + int dim(getSpaceDimension()); + double ret(1.); + for(int i=0;i<dim;i++) + ret*=fabs(_dxyz[i]); + return ret; +} + +/*! + * This method is allows to convert \a this into MEDCouplingCMesh instance. + * This method is the middle level between MEDCouplingIMesh and the most general MEDCouplingUMesh. + * This method is useful for MED writers that do not have still the image grid support. + * + * \sa MEDCouplingMesh::buildUnstructured + */ +MEDCouplingCMesh *MEDCouplingIMesh::convertToCartesian() const +{ + checkCoherency(); + MEDCouplingAutoRefCountObjectPtr<MEDCouplingCMesh> ret(MEDCouplingCMesh::New()); + try + { ret->copyTinyInfoFrom(this); } + catch(INTERP_KERNEL::Exception& ) { } + int spaceDim(getSpaceDimension()); + std::vector<std::string> infos(buildInfoOnComponents()); + for(int i=0;i<spaceDim;i++) + { + MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> arr(DataArrayDouble::New()); arr->alloc(_structure[i],1); arr->setInfoOnComponent(0,infos[i]); + arr->iota(); arr->applyLin(_dxyz[i],_origin[i]); + ret->setCoordsAt(i,arr); + } + return ret.retn(); +} + +/*! + * This method refines \a this uniformaly along all of its dimensions. In case of success the space covered by \a this will remain + * the same before the invocation except that the number of cells will be multiplied by \a factor ^ this->getMeshDimension(). + * The origin of \a this will be not touched only spacing and node structure will be changed. + * This method can be useful for AMR users. + */ +void MEDCouplingIMesh::refineWithFactor(const std::vector<int>& factors) +{ + if((int)factors.size()!=_space_dim) + throw INTERP_KERNEL::Exception("MEDCouplingIMesh::refineWithFactor : refinement factors must have size equal to spaceDim !"); + checkCoherency(); + std::vector<int> structure(_structure,_structure+3); + std::vector<double> dxyz(_dxyz,_dxyz+3); + for(int i=0;i<_space_dim;i++) + { + if(factors[i]<=0) + { + std::ostringstream oss; oss << "MEDCouplingIMesh::refineWithFactor : factor for axis #" << i << " (" << factors[i] << ")is invalid ! Must be > 0 !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + int factAbs(std::abs(factors[i])); + double fact2(1./(double)factors[i]); + structure[i]=(_structure[i]-1)*factAbs+1; + dxyz[i]=fact2*_dxyz[i]; + } + std::copy(structure.begin(),structure.end(),_structure); + std::copy(dxyz.begin(),dxyz.end(),_dxyz); + declareAsNew(); +} + +/*! + * This method returns a newly created mesh containing a single cell in it. This returned cell covers exactly the space covered by \a this. + * + * \return MEDCouplingIMesh * - A newly created object (to be managed by the caller with decrRef) containing simply one cell. + * + * \throw if \a this does not pass the \c checkCoherency test. + */ +MEDCouplingIMesh *MEDCouplingIMesh::asSingleCell() const +{ + checkCoherency(); + int spaceDim(getSpaceDimension()),nodeSt[3]; + double dxyz[3]; + for(int i=0;i<spaceDim;i++) + { + if(_structure[i]>=2) + { + nodeSt[i]=2; + dxyz[i]=(_structure[i]-1)*_dxyz[i]; + } + else + { + nodeSt[i]=_structure[i]; + dxyz[i]=_dxyz[i]; + } + } + MEDCouplingAutoRefCountObjectPtr<MEDCouplingIMesh> ret(MEDCouplingIMesh::New(getName(),getSpaceDimension(),nodeSt,nodeSt+spaceDim,_origin,_origin+spaceDim,dxyz,dxyz+spaceDim)); + ret->copyTinyInfoFrom(this); + return ret.retn(); +} + +/*! + * This static method is useful to condense field on cells of a MEDCouplingIMesh instance coming from a refinement ( MEDCouplingIMesh::refineWithFactor for example) + * to a coarse MEDCouplingIMesh instance. So this method can be seen as a specialization in P0P0 conservative interpolation non overlaping from fine image mesh + * to a coarse image mesh. Only tuples ( deduced from \a fineLocInCoarse ) of \a coarseDA will be modified. Other tuples of \a coarseDA will be let unchanged. + * + * \param [in] coarseSt The cell structure of coarse mesh. + * \param [in] fineDA The DataArray containing the cell field on uniformly refined mesh + * \param [in] fineLocInCoarse The cell localization of refined mesh into the coarse one. + * \param [in] facts The refinement coefficient per axis. + * \param [in,out] coarseDA The DataArrayDouble corresponding to the a cell field of a coarse mesh whose cell structure is defined by \a coarseSt. + * + * \sa CondenseFineToCoarseGhost,SpreadCoarseToFine + */ +void MEDCouplingIMesh::CondenseFineToCoarse(const std::vector<int>& coarseSt, const DataArrayDouble *fineDA, const std::vector< std::pair<int,int> >& fineLocInCoarse, const std::vector<int>& facts, DataArrayDouble *coarseDA) +{ + if(coarseSt.size()!=fineLocInCoarse.size() || coarseSt.size()!=facts.size()) + throw INTERP_KERNEL::Exception("MEDCouplingIMesh::CondenseFineToCoarse : All input vectors (dimension) must have the same size !"); + if(!coarseDA || !coarseDA->isAllocated() || !fineDA || !fineDA->isAllocated()) + throw INTERP_KERNEL::Exception("MEDCouplingIMesh::CondenseFineToCoarse : the parameters 1 or 3 are NULL or not allocated !"); + int meshDim((int)coarseSt.size()),nbOfTuplesInCoarseExp(MEDCouplingStructuredMesh::DeduceNumberOfGivenStructure(coarseSt)),nbOfTuplesInFineExp(MEDCouplingStructuredMesh::DeduceNumberOfGivenRangeInCompactFrmt(fineLocInCoarse)); + int nbCompo(fineDA->getNumberOfComponents()); + if(coarseDA->getNumberOfComponents()!=nbCompo) + throw INTERP_KERNEL::Exception("MEDCouplingIMesh::CondenseFineToCoarse : the number of components of fine DA and coarse one mismatches !"); + if(meshDim!=(int)fineLocInCoarse.size() || meshDim!=(int)facts.size()) + throw INTERP_KERNEL::Exception("MEDCouplingIMesh::CondenseFineToCoarse : the size of fineLocInCoarse (4th param) and facts (5th param) must be equal to the sier of coarseSt (2nd param) !"); + if(coarseDA->getNumberOfTuples()!=nbOfTuplesInCoarseExp) + { + std::ostringstream oss; oss << "MEDCouplingIMesh::CondenseFineToCoarse : Expecting " << nbOfTuplesInCoarseExp << " tuples having " << coarseDA->getNumberOfTuples() << " !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + int nbTuplesFine(fineDA->getNumberOfTuples()); + if(nbOfTuplesInFineExp==0) + { + if(nbTuplesFine==0) + return ; + else + throw INTERP_KERNEL::Exception("MEDCouplingIMesh::CondenseFineToCoarse : Nothing to condense considering the range specified ! But DataArray is not empty !"); + } + if(nbTuplesFine%nbOfTuplesInFineExp!=0) + throw INTERP_KERNEL::Exception("MEDCouplingIMesh::CondenseFineToCoarse : Invalid nb of tuples in fine DataArray regarding its structure !"); + int fact(std::accumulate(facts.begin(),facts.end(),1,std::multiplies<int>())); + if(nbTuplesFine!=fact*nbOfTuplesInFineExp) + { + std::ostringstream oss; oss << "MEDCouplingIMesh::CondenseFineToCoarse : Invalid number of tuples (" << nbTuplesFine << ") of fine dataarray is invalid ! Must be " << fact*nbOfTuplesInFineExp << "!"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + // to improve use jump-iterator. Factorizes with SwitchOnIdsFrom BuildExplicitIdsFrom + double *outPtr(coarseDA->getPointer()); + const double *inPtr(fineDA->begin()); + // + std::vector<int> dims(MEDCouplingStructuredMesh::GetDimensionsFromCompactFrmt(fineLocInCoarse)); + switch(meshDim) + { + case 1: + { + int offset(fineLocInCoarse[0].first),fact0(facts[0]); + for(int i=0;i<dims[0];i++) + { + double *loc(outPtr+(offset+i)*nbCompo); + for(int ifact=0;ifact<fact0;ifact++,inPtr+=nbCompo) + { + if(ifact!=0) + std::transform(inPtr,inPtr+nbCompo,loc,loc,std::plus<double>()); + else + std::copy(inPtr,inPtr+nbCompo,loc); + } + } + break; + } + case 2: + { + int kk(fineLocInCoarse[0].first+coarseSt[0]*fineLocInCoarse[1].first),fact1(facts[1]),fact0(facts[0]); + for(int j=0;j<dims[1];j++) + { + for(int jfact=0;jfact<fact1;jfact++) + { + for(int i=0;i<dims[0];i++) + { + double *loc(outPtr+(kk+i)*nbCompo); + for(int ifact=0;ifact<fact0;ifact++,inPtr+=nbCompo) + { + if(jfact!=0 || ifact!=0) + std::transform(inPtr,inPtr+nbCompo,loc,loc,std::plus<double>()); + else + std::copy(inPtr,inPtr+nbCompo,loc); + } + } + } + kk+=coarseSt[0]; + } + break; + } + case 3: + { + int kk(fineLocInCoarse[0].first+coarseSt[0]*fineLocInCoarse[1].first+coarseSt[0]*coarseSt[1]*fineLocInCoarse[2].first),fact2(facts[2]),fact1(facts[1]),fact0(facts[0]); + for(int k=0;k<dims[2];k++) + { + for(int kfact=0;kfact<fact2;kfact++) + { + for(int j=0;j<dims[1];j++) + { + for(int jfact=0;jfact<fact1;jfact++) + { + for(int i=0;i<dims[0];i++) + { + double *loc(outPtr+(kk+i+j*coarseSt[0])*nbCompo); + for(int ifact=0;ifact<fact0;ifact++,inPtr+=nbCompo) + { + if(kfact!=0 || jfact!=0 || ifact!=0) + std::transform(inPtr,inPtr+nbCompo,loc,loc,std::plus<double>()); + else + std::copy(inPtr,inPtr+nbCompo,loc); + } + } + } + } + } + kk+=coarseSt[0]*coarseSt[1]; + } + break; + } + default: + throw INTERP_KERNEL::Exception("MEDCouplingIMesh::CondenseFineToCoarse : only dimensions 1, 2 and 3 supported !"); + } +} + +/*! + * This static method is useful to condense field on cells of a MEDCouplingIMesh instance coming from a refinement ( MEDCouplingIMesh::refineWithFactor for example) + * to a coarse MEDCouplingIMesh instance. So this method can be seen as a specialization in P0P0 conservative interpolation non overlaping from fine image mesh + * to a coarse image mesh. Only tuples ( deduced from \a fineLocInCoarse ) of \a coarseDA will be modified. Other tuples of \a coarseDA will be let unchanged. + * + * \param [in] coarseSt The cell structure of coarse mesh. + * \param [in] fineDA The DataArray containing the cell field on uniformly refined mesh + * \param [in] fineLocInCoarse The cell localization of refined mesh into the coarse one. + * \param [in] facts The refinement coefficient per axis. + * \param [in,out] coarseDA The DataArrayDouble corresponding to the a cell field of a coarse mesh whose cell structure is defined by \a coarseSt. + * \param [in] ghostSize - The size of the ghost zone. The ghost zone is expected to be the same for all axis and both for coarse and fine meshes. + * + * \sa CondenseFineToCoarse,SpreadCoarseToFineGhost + */ +void MEDCouplingIMesh::CondenseFineToCoarseGhost(const std::vector<int>& coarseSt, const DataArrayDouble *fineDA, const std::vector< std::pair<int,int> >& fineLocInCoarse, const std::vector<int>& facts, DataArrayDouble *coarseDA, int ghostSize) +{ + if(ghostSize<0) + throw INTERP_KERNEL::Exception("MEDCouplingIMesh::CondenseFineToCoarseGhost : ghost level has to be >= 0 !"); + if(coarseSt.size()!=fineLocInCoarse.size() || coarseSt.size()!=facts.size()) + throw INTERP_KERNEL::Exception("MEDCouplingIMesh::CondenseFineToCoarseGhost : All input vectors (dimension) must have the same size !"); + if(!coarseDA || !coarseDA->isAllocated() || !fineDA || !fineDA->isAllocated()) + throw INTERP_KERNEL::Exception("MEDCouplingIMesh::CondenseFineToCoarseGhost : the parameters 1 or 3 are NULL or not allocated !"); + std::vector<int> coarseStG(coarseSt.size()); std::transform(coarseSt.begin(),coarseSt.end(),coarseStG.begin(),std::bind2nd(std::plus<int>(),2*ghostSize)); + int meshDim((int)coarseSt.size()),nbOfTuplesInCoarseExp(MEDCouplingStructuredMesh::DeduceNumberOfGivenStructure(coarseStG)); + int nbCompo(fineDA->getNumberOfComponents()); + if(coarseDA->getNumberOfComponents()!=nbCompo) + throw INTERP_KERNEL::Exception("MEDCouplingIMesh::CondenseFineToCoarseGhost : the number of components of fine DA and coarse one mismatches !"); + if(meshDim!=(int)fineLocInCoarse.size() || meshDim!=(int)facts.size()) + throw INTERP_KERNEL::Exception("MEDCouplingIMesh::CondenseFineToCoarseGhost : the size of fineLocInCoarse (4th param) and facts (5th param) must be equal to the sier of coarseSt (2nd param) !"); + if(coarseDA->getNumberOfTuples()!=nbOfTuplesInCoarseExp) + { + std::ostringstream oss; oss << "MEDCouplingIMesh::CondenseFineToCoarseGhost : Expecting " << nbOfTuplesInCoarseExp << " tuples in coarse DataArray having " << coarseDA->getNumberOfTuples() << " !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + // + std::vector<int> fineStG(MEDCouplingStructuredMesh::GetDimensionsFromCompactFrmt(fineLocInCoarse)); + std::transform(fineStG.begin(),fineStG.end(),facts.begin(),fineStG.begin(),std::multiplies<int>()); + std::transform(fineStG.begin(),fineStG.end(),fineStG.begin(),std::bind2nd(std::plus<int>(),2*ghostSize)); + int nbTuplesFine(fineDA->getNumberOfTuples()),nbTuplesFineExp(MEDCouplingStructuredMesh::DeduceNumberOfGivenStructure(fineStG)); + if(fineDA->getNumberOfTuples()!=nbTuplesFineExp) + { + std::ostringstream oss; oss << "MEDCouplingIMesh::CondenseFineToCoarseGhost : Expecting " << nbTuplesFineExp << " tuples in fine DataArray having " << nbTuplesFine << " !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + // + double *outPtr(coarseDA->getPointer()); + const double *inPtr(fineDA->begin()); + // + std::vector<int> dims(MEDCouplingStructuredMesh::GetDimensionsFromCompactFrmt(fineLocInCoarse)); + switch(meshDim) + { + case 1: + { + int offset(fineLocInCoarse[0].first+ghostSize),fact0(facts[0]); + inPtr+=ghostSize*nbCompo; + for(int i=0;i<dims[0];i++) + { + double *loc(outPtr+(offset+i)*nbCompo); + for(int ifact=0;ifact<fact0;ifact++,inPtr+=nbCompo) + { + if(ifact!=0) + std::transform(inPtr,inPtr+nbCompo,loc,loc,std::plus<double>()); + else + std::copy(inPtr,inPtr+nbCompo,loc); + } + } + break; + } + case 2: + { + int nxwg(coarseSt[0]+2*ghostSize); + int kk(fineLocInCoarse[0].first+ghostSize+nxwg*(fineLocInCoarse[1].first+ghostSize)),fact1(facts[1]),fact0(facts[0]); + inPtr+=(dims[0]*fact0+2*ghostSize)*ghostSize*nbCompo; + for(int j=0;j<dims[1];j++) + { + for(int jfact=0;jfact<fact1;jfact++) + { + inPtr+=ghostSize*nbCompo; + for(int i=0;i<dims[0];i++) + { + double *loc(outPtr+(kk+i)*nbCompo); + for(int ifact=0;ifact<fact0;ifact++,inPtr+=nbCompo) + { + if(jfact!=0 || ifact!=0) + std::transform(inPtr,inPtr+nbCompo,loc,loc,std::plus<double>()); + else + std::copy(inPtr,inPtr+nbCompo,loc); + } + } + inPtr+=ghostSize*nbCompo; + } + kk+=nxwg; + } + break; + } + case 3: + { + int nxwg(coarseSt[0]+2*ghostSize),nxywg((coarseSt[0]+2*ghostSize)*(coarseSt[1]+2*ghostSize)); + int kk(fineLocInCoarse[0].first+ghostSize+nxwg*(fineLocInCoarse[1].first+ghostSize)+nxywg*(fineLocInCoarse[2].first+ghostSize)),fact2(facts[2]),fact1(facts[1]),fact0(facts[0]); + inPtr+=(dims[0]*fact0+2*ghostSize)*(dims[1]*fact1+2*ghostSize)*ghostSize*nbCompo; + for(int k=0;k<dims[2];k++) + { + for(int kfact=0;kfact<fact2;kfact++) + { + inPtr+=ghostSize*(dims[0]*fact0+2*ghostSize)*nbCompo; + for(int j=0;j<dims[1];j++) + { + int kky(j*nxwg); + for(int jfact=0;jfact<fact1;jfact++) + { + inPtr+=ghostSize*nbCompo; + for(int i=0;i<dims[0];i++) + { + double *loc(outPtr+(kky+kk+i)*nbCompo); + for(int ifact=0;ifact<fact0;ifact++,inPtr+=nbCompo) + { + if(kfact!=0 || jfact!=0 || ifact!=0) + std::transform(inPtr,inPtr+nbCompo,loc,loc,std::plus<double>()); + else + std::copy(inPtr,inPtr+nbCompo,loc); + } + } + inPtr+=ghostSize*nbCompo; + } + } + inPtr+=ghostSize*(dims[0]*fact0+2*ghostSize)*nbCompo; + } + kk+=nxywg; + } + break; + } + default: + throw INTERP_KERNEL::Exception("MEDCouplingIMesh::CondenseFineToCoarseGhost : only dimensions 1, 2, 3 supported !"); + } +} + +/*! + * This method spreads the values of coarse data \a coarseDA into \a fineDA. + * + * \param [in] coarseDA The DataArrayDouble corresponding to the a cell field of a coarse mesh whose cell structure is defined by \a coarseSt. + * \param [in] coarseSt The cell structure of coarse mesh. + * \param [in,out] fineDA The DataArray containing the cell field on uniformly refined mesh + * \param [in] fineLocInCoarse The cell localization of refined mesh into the coarse one. + * \param [in] facts The refinement coefficient per axis. + * \sa SpreadCoarseToFineGhost, CondenseFineToCoarse + */ +void MEDCouplingIMesh::SpreadCoarseToFine(const DataArrayDouble *coarseDA, const std::vector<int>& coarseSt, DataArrayDouble *fineDA, const std::vector< std::pair<int,int> >& fineLocInCoarse, const std::vector<int>& facts) +{ + if(coarseSt.size()!=fineLocInCoarse.size() || coarseSt.size()!=facts.size()) + throw INTERP_KERNEL::Exception("MEDCouplingIMesh::SpreadCoarseToFine : All input vectors (dimension) must have the same size !"); + if(!coarseDA || !coarseDA->isAllocated() || !fineDA || !fineDA->isAllocated()) + throw INTERP_KERNEL::Exception("MEDCouplingIMesh::SpreadCoarseToFine : the parameters 1 or 3 are NULL or not allocated !"); + int meshDim((int)coarseSt.size()),nbOfTuplesInCoarseExp(MEDCouplingStructuredMesh::DeduceNumberOfGivenStructure(coarseSt)),nbOfTuplesInFineExp(MEDCouplingStructuredMesh::DeduceNumberOfGivenRangeInCompactFrmt(fineLocInCoarse)); + int nbCompo(fineDA->getNumberOfComponents()); + if(coarseDA->getNumberOfComponents()!=nbCompo) + throw INTERP_KERNEL::Exception("MEDCouplingIMesh::SpreadCoarseToFine : the number of components of fine DA and coarse one mismatches !"); + if(meshDim!=(int)fineLocInCoarse.size() || meshDim!=(int)facts.size()) + throw INTERP_KERNEL::Exception("MEDCouplingIMesh::SpreadCoarseToFine : the size of fineLocInCoarse (4th param) and facts (5th param) must be equal to the sier of coarseSt (2nd param) !"); + if(coarseDA->getNumberOfTuples()!=nbOfTuplesInCoarseExp) + { + std::ostringstream oss; oss << "MEDCouplingIMesh::SpreadCoarseToFine : Expecting " << nbOfTuplesInCoarseExp << " tuples having " << coarseDA->getNumberOfTuples() << " !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + int nbTuplesFine(fineDA->getNumberOfTuples()); + if(nbTuplesFine%nbOfTuplesInFineExp!=0) + throw INTERP_KERNEL::Exception("MEDCouplingIMesh::SpreadCoarseToFine : Invalid nb of tuples in fine DataArray regarding its structure !"); + int fact(std::accumulate(facts.begin(),facts.end(),1,std::multiplies<int>())); + if(nbTuplesFine!=fact*nbOfTuplesInFineExp) + { + std::ostringstream oss; oss << "MEDCouplingIMesh::SpreadCoarseToFine : Invalid number of tuples (" << nbTuplesFine << ") of fine dataarray is invalid ! Must be " << fact*nbOfTuplesInFineExp << "!"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + // to improve use jump-iterator. Factorizes with SwitchOnIdsFrom BuildExplicitIdsFrom + double *outPtr(fineDA->getPointer()); + const double *inPtr(coarseDA->begin()); + // + std::vector<int> dims(MEDCouplingStructuredMesh::GetDimensionsFromCompactFrmt(fineLocInCoarse)); + switch(meshDim) + { + case 1: + { + int offset(fineLocInCoarse[0].first),fact0(facts[0]); + for(int i=0;i<dims[0];i++) + { + const double *loc(inPtr+(offset+i)*nbCompo); + for(int ifact=0;ifact<fact0;ifact++) + outPtr=std::copy(loc,loc+nbCompo,outPtr); + } + break; + } + case 2: + { + int kk(fineLocInCoarse[0].first+coarseSt[0]*fineLocInCoarse[1].first),fact0(facts[0]),fact1(facts[1]); + for(int j=0;j<dims[1];j++) + { + for(int jfact=0;jfact<fact1;jfact++) + { + for(int i=0;i<dims[0];i++) + { + const double *loc(inPtr+(kk+i)*nbCompo); + for(int ifact=0;ifact<fact0;ifact++) + outPtr=std::copy(loc,loc+nbCompo,outPtr); + } + } + kk+=coarseSt[0]; + } + break; + } + case 3: + { + int kk(fineLocInCoarse[0].first+coarseSt[0]*fineLocInCoarse[1].first+coarseSt[0]*coarseSt[1]*fineLocInCoarse[2].first),fact0(facts[0]),fact1(facts[2]),fact2(facts[2]); + for(int k=0;k<dims[2];k++) + { + for(int kfact=0;kfact<fact2;kfact++) + { + for(int j=0;j<dims[1];j++) + { + for(int jfact=0;jfact<fact1;jfact++) + { + for(int i=0;i<dims[0];i++) + { + const double *loc(inPtr+(kk+i+j*coarseSt[0])*nbCompo); + for(int ifact=0;ifact<fact0;ifact++) + outPtr=std::copy(loc,loc+nbCompo,outPtr); + } + } + } + } + kk+=coarseSt[0]*coarseSt[1]; + } + break; + } + default: + throw INTERP_KERNEL::Exception("MEDCouplingIMesh::SpreadCoarseToFine : only dimensions 1, 2 and 3 supported !"); + } +} + +/*! + * This method spreads the values of coarse data \a coarseDA into \a fineDA. + * + * \param [in] coarseDA The DataArrayDouble corresponding to the a cell field of a coarse mesh whose cell structure is defined by \a coarseSt. + * \param [in] coarseSt The cell structure of coarse mesh. + * \param [in,out] fineDA The DataArray containing the cell field on uniformly refined mesh + * \param [in] fineLocInCoarse The cell localization of refined mesh into the coarse one. + * \param [in] facts The refinement coefficient per axis. + * \param [in] ghostSize - The size of the ghost zone. The ghost zone is expected to be the same for all axis and both for coarse and fine meshes. + * + * \sa CondenseFineToCoarse, SpreadCoarseToFineGhostZone + */ +void MEDCouplingIMesh::SpreadCoarseToFineGhost(const DataArrayDouble *coarseDA, const std::vector<int>& coarseSt, DataArrayDouble *fineDA, const std::vector< std::pair<int,int> >& fineLocInCoarse, const std::vector<int>& facts, int ghostSize) +{ + if(ghostSize<0) + throw INTERP_KERNEL::Exception("MEDCouplingIMesh::SpreadCoarseToFineGhost : ghost level has to be >= 0 !"); + if(coarseSt.size()!=fineLocInCoarse.size() || coarseSt.size()!=facts.size()) + throw INTERP_KERNEL::Exception("MEDCouplingIMesh::SpreadCoarseToFineGhost : All input vectors (dimension) must have the same size !"); + if(!coarseDA || !coarseDA->isAllocated() || !fineDA || !fineDA->isAllocated()) + throw INTERP_KERNEL::Exception("MEDCouplingIMesh::SpreadCoarseToFineGhost : the parameters 1 or 3 are NULL or not allocated !"); + std::vector<int> coarseStG(coarseSt.size()); std::transform(coarseSt.begin(),coarseSt.end(),coarseStG.begin(),std::bind2nd(std::plus<int>(),2*ghostSize)); + int meshDim((int)coarseSt.size()),nbOfTuplesInCoarseExp(MEDCouplingStructuredMesh::DeduceNumberOfGivenStructure(coarseStG)); + int nbCompo(fineDA->getNumberOfComponents()); + if(coarseDA->getNumberOfComponents()!=nbCompo) + throw INTERP_KERNEL::Exception("MEDCouplingIMesh::SpreadCoarseToFineGhost : the number of components of fine DA and coarse one mismatches !"); + if(meshDim!=(int)fineLocInCoarse.size() || meshDim!=(int)facts.size()) + throw INTERP_KERNEL::Exception("MEDCouplingIMesh::SpreadCoarseToFineGhost : the size of fineLocInCoarse (4th param) and facts (5th param) must be equal to the sier of coarseSt (2nd param) !"); + if(coarseDA->getNumberOfTuples()!=nbOfTuplesInCoarseExp) + { + std::ostringstream oss; oss << "MEDCouplingIMesh::SpreadCoarseToFineGhost : Expecting " << nbOfTuplesInCoarseExp << " tuples having " << coarseDA->getNumberOfTuples() << " !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + // + std::vector<int> fineStG(MEDCouplingStructuredMesh::GetDimensionsFromCompactFrmt(fineLocInCoarse)); + std::transform(fineStG.begin(),fineStG.end(),facts.begin(),fineStG.begin(),std::multiplies<int>()); + std::transform(fineStG.begin(),fineStG.end(),fineStG.begin(),std::bind2nd(std::plus<int>(),2*ghostSize)); + int nbTuplesFine(fineDA->getNumberOfTuples()),nbTuplesFineExp(MEDCouplingStructuredMesh::DeduceNumberOfGivenStructure(fineStG)); + if(fineDA->getNumberOfTuples()!=nbTuplesFineExp) + { + std::ostringstream oss; oss << "MEDCouplingIMesh::SpreadCoarseToFineGhost : Expecting " << nbTuplesFineExp << " tuples in fine DataArray having " << nbTuplesFine << " !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + // + double *outPtr(fineDA->getPointer()); + const double *inPtr(coarseDA->begin()); + // + switch(meshDim) + { + case 1: + { + std::vector<int> dims(MEDCouplingStructuredMesh::GetDimensionsFromCompactFrmt(fineLocInCoarse)); + int offset(fineLocInCoarse[0].first+ghostSize-1),fact0(facts[0]);//offset is always >=0 thanks to the fact that ghostSize>=1 ! + for(int i=0;i<ghostSize;i++) + outPtr=std::copy(inPtr+offset*nbCompo,inPtr+(offset+1)*nbCompo,outPtr); + offset=fineLocInCoarse[0].first+ghostSize; + for(int i=0;i<dims[0];i++) + { + const double *loc(inPtr+(offset+i)*nbCompo); + for(int ifact=0;ifact<fact0;ifact++) + outPtr=std::copy(loc,loc+nbCompo,outPtr); + } + offset=fineLocInCoarse[0].second+ghostSize; + for(int i=0;i<ghostSize;i++) + outPtr=std::copy(inPtr+offset*nbCompo,inPtr+(offset+1)*nbCompo,outPtr); + break; + } + case 2: + { + SpreadCoarseToFineGhost2D(inPtr,outPtr,nbCompo,coarseSt,fineLocInCoarse,facts,ghostSize); + break; + } + case 3: + { + std::vector<int> dims(MEDCouplingStructuredMesh::GetDimensionsFromCompactFrmt(fineLocInCoarse)); + int fact0(facts[0]),fact1(facts[1]),fact2(facts[2]); + int nxyWgCoarse((coarseSt[0]+2*ghostSize)*(coarseSt[1]+2*ghostSize)),nxyWgFine((dims[0]*fact0+2*ghostSize)*(dims[1]*fact1+2*ghostSize)); + int offset((fineLocInCoarse[2].first+ghostSize-1)*nxyWgCoarse);//offset is always >=0 thanks to the fact that ghostSize>=1 ! + for(int i=0;i<ghostSize;i++,outPtr+=nxyWgFine*nbCompo) + SpreadCoarseToFineGhost2D(inPtr+offset*nbCompo,outPtr,nbCompo,coarseSt,fineLocInCoarse,facts,ghostSize); + offset+=nxyWgCoarse; + for(int i=0;i<dims[2];i++,offset+=nxyWgCoarse) + for(int j=0;j<fact2;j++,outPtr+=nxyWgFine*nbCompo) + SpreadCoarseToFineGhost2D(inPtr+offset*nbCompo,outPtr,nbCompo,coarseSt,fineLocInCoarse,facts,ghostSize); + for(int i=0;i<ghostSize;i++,outPtr+=nxyWgFine*nbCompo) + SpreadCoarseToFineGhost2D(inPtr+offset*nbCompo,outPtr,nbCompo,coarseSt,fineLocInCoarse,facts,ghostSize); + break; + } + default: + throw INTERP_KERNEL::Exception("MEDCouplingIMesh::SpreadCoarseToFineGhost : only dimensions 1, 2, 3 supported !"); + } +} + +/*! + * This method spreads the values of coarse data \a coarseDA into \a fineDA \b ONLY \b in \b the \b ghost \b zone (contrary to SpreadCoarseToFineGhost that spread the values everywhere). + * + * \param [in] coarseDA The DataArrayDouble corresponding to the a cell field of a coarse mesh whose cell structure is defined by \a coarseSt. + * \param [in] coarseSt The cell structure of coarse mesh. + * \param [in,out] fineDA The DataArray containing the cell field on uniformly refined mesh + * \param [in] fineLocInCoarse The cell localization of refined mesh into the coarse one. + * \param [in] facts The refinement coefficient per axis. + * \param [in] ghostSize - The size of the ghost zone. The ghost zone is expected to be the same for all axis and both for coarse and fine meshes. + * + * \sa SpreadCoarseToFineGhost + */ +void MEDCouplingIMesh::SpreadCoarseToFineGhostZone(const DataArrayDouble *coarseDA, const std::vector<int>& coarseSt, DataArrayDouble *fineDA, const std::vector< std::pair<int,int> >& fineLocInCoarse, const std::vector<int>& facts, int ghostSize) +{ + if(ghostSize<0) + throw INTERP_KERNEL::Exception("MEDCouplingIMesh::SpreadCoarseToFineGhostZone : ghost level has to be >= 0 !"); + if(coarseSt.size()!=fineLocInCoarse.size() || coarseSt.size()!=facts.size()) + throw INTERP_KERNEL::Exception("MEDCouplingIMesh::SpreadCoarseToFineGhostZone : All input vectors (dimension) must have the same size !"); + if(!coarseDA || !coarseDA->isAllocated() || !fineDA || !fineDA->isAllocated()) + throw INTERP_KERNEL::Exception("MEDCouplingIMesh::SpreadCoarseToFineGhostZone : the parameters 1 or 3 are NULL or not allocated !"); + std::vector<int> coarseStG(coarseSt.size()); std::transform(coarseSt.begin(),coarseSt.end(),coarseStG.begin(),std::bind2nd(std::plus<int>(),2*ghostSize)); + int meshDim((int)coarseSt.size()),nbOfTuplesInCoarseExp(MEDCouplingStructuredMesh::DeduceNumberOfGivenStructure(coarseStG)); + int nbCompo(fineDA->getNumberOfComponents()); + if(coarseDA->getNumberOfComponents()!=nbCompo) + throw INTERP_KERNEL::Exception("MEDCouplingIMesh::SpreadCoarseToFineGhostZone : the number of components of fine DA and coarse one mismatches !"); + if(meshDim!=(int)fineLocInCoarse.size() || meshDim!=(int)facts.size()) + throw INTERP_KERNEL::Exception("MEDCouplingIMesh::SpreadCoarseToFineGhostZone : the size of fineLocInCoarse (4th param) and facts (5th param) must be equal to the sier of coarseSt (2nd param) !"); + if(coarseDA->getNumberOfTuples()!=nbOfTuplesInCoarseExp) + { + std::ostringstream oss; oss << "MEDCouplingIMesh::SpreadCoarseToFineGhostZone : Expecting " << nbOfTuplesInCoarseExp << " tuples having " << coarseDA->getNumberOfTuples() << " !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + // + std::vector<int> fineStG(MEDCouplingStructuredMesh::GetDimensionsFromCompactFrmt(fineLocInCoarse)); + std::transform(fineStG.begin(),fineStG.end(),facts.begin(),fineStG.begin(),std::multiplies<int>()); + std::transform(fineStG.begin(),fineStG.end(),fineStG.begin(),std::bind2nd(std::plus<int>(),2*ghostSize)); + int nbTuplesFine(fineDA->getNumberOfTuples()),nbTuplesFineExp(MEDCouplingStructuredMesh::DeduceNumberOfGivenStructure(fineStG)); + if(fineDA->getNumberOfTuples()!=nbTuplesFineExp) + { + std::ostringstream oss; oss << "MEDCouplingIMesh::SpreadCoarseToFineGhostZone : Expecting " << nbTuplesFineExp << " tuples in fine DataArray having " << nbTuplesFine << " !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + // + double *outPtr(fineDA->getPointer()); + const double *inPtr(coarseDA->begin()); + // + std::vector<int> dims(MEDCouplingStructuredMesh::GetDimensionsFromCompactFrmt(fineLocInCoarse)); + switch(meshDim) + { + case 1: + { + int offset(fineLocInCoarse[0].first+ghostSize-1),fact0(facts[0]);//offset is always >=0 thanks to the fact that ghostSize>=1 ! + for(int i=0;i<ghostSize;i++) + outPtr=std::copy(inPtr+offset*nbCompo,inPtr+(offset+1)*nbCompo,outPtr); + outPtr+=nbCompo*fact0*dims[0]; + offset=fineLocInCoarse[0].second+ghostSize; + for(int i=0;i<ghostSize;i++) + outPtr=std::copy(inPtr+offset*nbCompo,inPtr+(offset+1)*nbCompo,outPtr); + break; + } + case 2: + { + SpreadCoarseToFineGhostZone2D(inPtr,outPtr,nbCompo,coarseSt,fineLocInCoarse,facts,ghostSize); + break; + } + case 3: + { + int fact0(facts[0]),fact1(facts[1]),fact2(facts[2]); + int nxyWgCoarse((coarseSt[0]+2*ghostSize)*(coarseSt[1]+2*ghostSize)),nxyWgFine((dims[0]*fact0+2*ghostSize)*(dims[1]*fact1+2*ghostSize)); + int offset((fineLocInCoarse[2].first+ghostSize-1)*nxyWgCoarse);//offset is always >=0 thanks to the fact that ghostSize>=1 ! + for(int i=0;i<ghostSize;i++,outPtr+=nxyWgFine*nbCompo) + SpreadCoarseToFineGhost2D(inPtr+offset*nbCompo,outPtr,nbCompo,coarseSt,fineLocInCoarse,facts,ghostSize); + offset+=nxyWgCoarse; + for(int i=0;i<dims[2];i++,offset+=nxyWgCoarse) + for(int j=0;j<fact2;j++,outPtr+=nxyWgFine*nbCompo) + SpreadCoarseToFineGhostZone2D(inPtr+offset*nbCompo,outPtr,nbCompo,coarseSt,fineLocInCoarse,facts,ghostSize); + for(int i=0;i<ghostSize;i++,outPtr+=nxyWgFine*nbCompo) + SpreadCoarseToFineGhost2D(inPtr+offset*nbCompo,outPtr,nbCompo,coarseSt,fineLocInCoarse,facts,ghostSize); + break; + } + default: + throw INTERP_KERNEL::Exception("MEDCouplingIMesh::SpreadCoarseToFineGhostZone : only dimensions 1, 2, 3 supported !"); + } +} + +void MEDCouplingIMesh::setSpaceDimension(int spaceDim) +{ + if(spaceDim==_space_dim) + return ; + CheckSpaceDimension(spaceDim); + _space_dim=spaceDim; + declareAsNew(); +} + +void MEDCouplingIMesh::updateTime() const +{ +} + +std::size_t MEDCouplingIMesh::getHeapMemorySizeWithoutChildren() const +{ + return MEDCouplingStructuredMesh::getHeapMemorySizeWithoutChildren(); +} + +std::vector<const BigMemoryObject *> MEDCouplingIMesh::getDirectChildrenWithNull() const +{ + return std::vector<const BigMemoryObject *>(); +} + +/*! + * This method copyies all tiny strings from other (name and components name). + * @throw if other and this have not same mesh type. + */ +void MEDCouplingIMesh::copyTinyStringsFrom(const MEDCouplingMesh *other) +{ + const MEDCouplingIMesh *otherC=dynamic_cast<const MEDCouplingIMesh *>(other); + if(!otherC) + throw INTERP_KERNEL::Exception("MEDCouplingIMesh::copyTinyStringsFrom : meshes have not same type !"); + MEDCouplingStructuredMesh::copyTinyStringsFrom(other); + declareAsNew(); +} + +bool MEDCouplingIMesh::isEqualIfNotWhy(const MEDCouplingMesh *other, double prec, std::string& reason) const +{ + if(!other) + throw INTERP_KERNEL::Exception("MEDCouplingIMesh::isEqualIfNotWhy : input other pointer is null !"); + const MEDCouplingIMesh *otherC(dynamic_cast<const MEDCouplingIMesh *>(other)); + if(!otherC) + { + reason="mesh given in input is not castable in MEDCouplingIMesh !"; + return false; + } + if(!MEDCouplingStructuredMesh::isEqualIfNotWhy(other,prec,reason)) + return false; + if(!isEqualWithoutConsideringStrInternal(otherC,prec,reason)) + return false; + if(_axis_unit!=otherC->_axis_unit) + { + reason="The units of axis are not the same !"; + return false; + } + return true; +} + +bool MEDCouplingIMesh::isEqualWithoutConsideringStr(const MEDCouplingMesh *other, double prec) const +{ + const MEDCouplingIMesh *otherC=dynamic_cast<const MEDCouplingIMesh *>(other); + if(!otherC) + return false; + std::string tmp; + return isEqualWithoutConsideringStrInternal(other,prec,tmp); +} + +bool MEDCouplingIMesh::isEqualWithoutConsideringStrInternal(const MEDCouplingMesh *other, double prec, std::string& reason) const +{ + const MEDCouplingIMesh *otherC=dynamic_cast<const MEDCouplingIMesh *>(other); + if(!otherC) + return false; + if(_space_dim!=otherC->_space_dim) + { + std::ostringstream oss; + oss << "The spaceDimension of this (" << _space_dim << ") is not equal to those of other (" << otherC->_space_dim << ") !"; + return false; + } + checkSpaceDimension(); + for(int i=0;i<_space_dim;i++) + { + if(fabs(_origin[i]-otherC->_origin[i])>prec) + { + std::ostringstream oss; + oss << "The origin of this and other differs at " << i << " !"; + reason=oss.str(); + return false; + } + } + for(int i=0;i<_space_dim;i++) + { + if(fabs(_dxyz[i]-otherC->_dxyz[i])>prec) + { + std::ostringstream oss; + oss << "The delta of this and other differs at " << i << " !"; + reason=oss.str(); + return false; + } + } + for(int i=0;i<_space_dim;i++) + { + if(_structure[i]!=otherC->_structure[i]) + { + std::ostringstream oss; + oss << "The structure of this and other differs at " << i << " !"; + reason=oss.str(); + return false; + } + } + return true; +} + +void MEDCouplingIMesh::checkDeepEquivalWith(const MEDCouplingMesh *other, int cellCompPol, double prec, + DataArrayInt *&cellCor, DataArrayInt *&nodeCor) const +{ + if(!isEqualWithoutConsideringStr(other,prec)) + throw INTERP_KERNEL::Exception("MEDCouplingIMesh::checkDeepEquivalWith : Meshes are not the same !"); +} + +/*! + * Nothing is done here (except to check that the other is a ParaMEDMEM::MEDCouplingIMesh instance too). + * The user intend that the nodes are the same, so by construction of ParaMEDMEM::MEDCouplingIMesh, \a this and \a other are the same ! + */ +void MEDCouplingIMesh::checkDeepEquivalOnSameNodesWith(const MEDCouplingMesh *other, int cellCompPol, double prec, + DataArrayInt *&cellCor) const +{ + if(!isEqualWithoutConsideringStr(other,prec)) + throw INTERP_KERNEL::Exception("MEDCouplingIMesh::checkDeepEquivalOnSameNodesWith : Meshes are not the same !"); +} + +void MEDCouplingIMesh::checkCoherency() const +{ + checkSpaceDimension(); + for(int i=0;i<_space_dim;i++) + if(_structure[i]<1) + { + std::ostringstream oss; oss << "MEDCouplingIMesh::checkCoherency : On axis " << i << "/" << _space_dim << ", number of nodes is equal to " << _structure[i] << " ! must be >=1 !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } +} + +void MEDCouplingIMesh::checkCoherency1(double eps) const +{ + checkCoherency(); +} + +void MEDCouplingIMesh::checkCoherency2(double eps) const +{ + checkCoherency1(eps); +} + +void MEDCouplingIMesh::getNodeGridStructure(int *res) const +{ + checkSpaceDimension(); + std::copy(_structure,_structure+_space_dim,res); +} + +std::vector<int> MEDCouplingIMesh::getNodeGridStructure() const +{ + checkSpaceDimension(); + std::vector<int> ret(_structure,_structure+_space_dim); + return ret; +} + +MEDCouplingStructuredMesh *MEDCouplingIMesh::buildStructuredSubPart(const std::vector< std::pair<int,int> >& cellPart) const +{ + checkCoherency(); + int dim(getSpaceDimension()); + if(dim!=(int)cellPart.size()) + { + std::ostringstream oss; oss << "MEDCouplingIMesh::buildStructuredSubPart : the space dimension is " << dim << " and cell part size is " << cellPart.size() << " !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + double retOrigin[3]={0.,0.,0.}; + int retStruct[3]={0,0,0}; + MEDCouplingAutoRefCountObjectPtr<MEDCouplingIMesh> ret(dynamic_cast<MEDCouplingIMesh *>(deepCpy())); + for(int i=0;i<dim;i++) + { + int startNode(cellPart[i].first),endNode(cellPart[i].second+1); + int myDelta(endNode-startNode); + if(startNode<0 || startNode>=_structure[i]) + { + std::ostringstream oss; oss << "MEDCouplingIMesh::buildStructuredSubPart : At dimension #" << i << " the start node id is " << startNode << " it should be in [0," << _structure[i] << ") !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + if(myDelta<0 || myDelta>_structure[i]) + { + std::ostringstream oss; oss << "MEDCouplingIMesh::buildStructuredSubPart : Along dimension #" << i << " the number of nodes is " << _structure[i] << ", and you are requesting for " << myDelta << " nodes wide range !" << std::endl; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + retOrigin[i]=_origin[i]+startNode*_dxyz[i]; + retStruct[i]=myDelta; + } + ret->setNodeStruct(retStruct,retStruct+dim); + ret->setOrigin(retOrigin,retOrigin+dim); + ret->checkCoherency(); + return ret.retn(); +} + +/*! + * Return the space dimension of \a this. + */ +int MEDCouplingIMesh::getSpaceDimension() const +{ + return _space_dim; +} + +void MEDCouplingIMesh::getCoordinatesOfNode(int nodeId, std::vector<double>& coo) const +{ + int tmp[3]; + int spaceDim(getSpaceDimension()); + getSplitNodeValues(tmp); + int tmp2[3]; + GetPosFromId(nodeId,spaceDim,tmp,tmp2); + for(int j=0;j<spaceDim;j++) + coo.push_back(_origin[j]+_dxyz[j]*tmp2[j]); +} + +std::string MEDCouplingIMesh::simpleRepr() const +{ + std::ostringstream ret; + ret << "Image grid with name : \"" << getName() << "\"\n"; + ret << "Description of mesh : \"" << getDescription() << "\"\n"; + int tmpp1,tmpp2; + double tt(getTime(tmpp1,tmpp2)); + int spaceDim(_space_dim); + ret << "Time attached to the mesh [unit] : " << tt << " [" << getTimeUnit() << "]\n"; + ret << "Iteration : " << tmpp1 << " Order : " << tmpp2 << "\n"; + ret << "Space dimension : " << spaceDim << "\n"; + if(spaceDim<0 || spaceDim>3) + return ret.str(); + ret << "The nodal structure is : "; std::copy(_structure,_structure+spaceDim,std::ostream_iterator<int>(ret," ")); ret << "\n"; + ret << "The origin position is [" << _axis_unit << "]: "; + std::copy(_origin,_origin+spaceDim,std::ostream_iterator<double>(ret," ")); ret << "\n"; + ret << "The intervals along axis are : "; + std::copy(_dxyz,_dxyz+spaceDim,std::ostream_iterator<double>(ret," ")); ret << "\n"; + return ret.str(); +} + +std::string MEDCouplingIMesh::advancedRepr() const +{ + return simpleRepr(); +} + +void MEDCouplingIMesh::getBoundingBox(double *bbox) const +{ + checkCoherency(); + int dim(getSpaceDimension()); + for(int idim=0; idim<dim; idim++) + { + bbox[2*idim]=_origin[idim]; + int coeff(_structure[idim]); + if(_structure[idim]<0) + { + std::ostringstream oss; oss << "MEDCouplingIMesh::getBoundingBox : on axis #" << idim << " number of nodes in structure is < 0 !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + if(_structure[idim]>1) + coeff=_structure[idim]-1; + bbox[2*idim+1]=_origin[idim]+_dxyz[idim]*coeff; + } +} + +/*! + * Returns a new MEDCouplingFieldDouble containing volumes of cells constituting \a this + * mesh.<br> + * For 1D cells, the returned field contains lengths.<br> + * For 2D cells, the returned field contains areas.<br> + * 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 *MEDCouplingIMesh::getMeasureField(bool isAbs) const +{ + checkCoherency(); + std::string name="MeasureOfMesh_"; + name+=getName(); + int nbelem(getNumberOfCells()); + MEDCouplingFieldDouble *field(MEDCouplingFieldDouble::New(ON_CELLS,ONE_TIME)); + field->setName(name); + DataArrayDouble* array(DataArrayDouble::New()); + array->alloc(nbelem,1); + array->fillWithValue(getMeasureOfAnyCell()); + field->setArray(array) ; + array->decrRef(); + field->setMesh(const_cast<MEDCouplingIMesh *>(this)); + field->synchronizeTimeWithMesh(); + return field; +} + +/*! + * not implemented yet ! + */ +MEDCouplingFieldDouble *MEDCouplingIMesh::getMeasureFieldOnNode(bool isAbs) const +{ + throw INTERP_KERNEL::Exception("MEDCouplingIMesh::getMeasureFieldOnNode : not implemented yet !"); + //return 0; +} + +int MEDCouplingIMesh::getCellContainingPoint(const double *pos, double eps) const +{ + int dim(getSpaceDimension()),ret(0),coeff(1); + for(int i=0;i<dim;i++) + { + int nbOfCells(_structure[i]-1); + double ref(pos[i]); + int tmp((int)((ref-_origin[i])/_dxyz[i])); + if(tmp>=0 && tmp<nbOfCells) + { + ret+=coeff*tmp; + coeff*=nbOfCells; + } + else + return -1; + } + return ret; +} + +void MEDCouplingIMesh::rotate(const double *center, const double *vector, double angle) +{ + throw INTERP_KERNEL::Exception("No rotation available on IMesh : Traduce it to unstructured mesh 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 MEDCouplingIMesh::translate(const double *vector) +{ + checkSpaceDimension(); + int dim(getSpaceDimension()); + std::transform(_origin,_origin+dim,vector,_origin,std::plus<double>()); + declareAsNew(); +} + +/*! + * 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 MEDCouplingIMesh::scale(const double *point, double factor) +{ + checkSpaceDimension(); + int dim(getSpaceDimension()); + std::transform(_origin,_origin+dim,point,_origin,std::minus<double>()); + std::transform(_origin,_origin+dim,_origin,std::bind2nd(std::multiplies<double>(),factor)); + std::transform(_dxyz,_dxyz+dim,_dxyz,std::bind2nd(std::multiplies<double>(),factor)); + std::transform(_origin,_origin+dim,point,_origin,std::plus<double>()); + declareAsNew(); +} + +MEDCouplingMesh *MEDCouplingIMesh::mergeMyselfWith(const MEDCouplingMesh *other) const +{ + //not implemented yet ! + 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 *MEDCouplingIMesh::getCoordinatesAndOwner() const +{ + checkCoherency(); + MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret(DataArrayDouble::New()); + int spaceDim(getSpaceDimension()),nbNodes(getNumberOfNodes()); + ret->alloc(nbNodes,spaceDim); + double *pt(ret->getPointer()); + ret->setInfoOnComponents(buildInfoOnComponents()); + int tmp2[3],tmp[3]; + getSplitNodeValues(tmp); + for(int i=0;i<nbNodes;i++) + { + GetPosFromId(i,spaceDim,tmp,tmp2); + for(int j=0;j<spaceDim;j++) + pt[i*spaceDim+j]=_dxyz[j]*tmp2[j]+_origin[j]; + } + return ret.retn(); +} + +/*! + * 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 *MEDCouplingIMesh::getBarycenterAndOwner() const +{ + checkCoherency(); + MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret(DataArrayDouble::New()); + int spaceDim(getSpaceDimension()),nbCells(getNumberOfCells()),tmp[3],tmp2[3]; + ret->alloc(nbCells,spaceDim); + double *pt(ret->getPointer()),shiftOrigin[3]; + std::transform(_dxyz,_dxyz+spaceDim,shiftOrigin,std::bind2nd(std::multiplies<double>(),0.5)); + std::transform(_origin,_origin+spaceDim,shiftOrigin,shiftOrigin,std::plus<double>()); + getSplitCellValues(tmp); + ret->setInfoOnComponents(buildInfoOnComponents()); + for(int i=0;i<nbCells;i++) + { + GetPosFromId(i,spaceDim,tmp,tmp2); + for(int j=0;j<spaceDim;j++) + pt[i*spaceDim+j]=_dxyz[j]*tmp2[j]+shiftOrigin[j]; + } + return ret.retn(); +} + +DataArrayDouble *MEDCouplingIMesh::computeIsoBarycenterOfNodesPerCell() const +{ + return MEDCouplingIMesh::getBarycenterAndOwner(); +} + +void MEDCouplingIMesh::renumberCells(const int *old2NewBg, bool check) +{ + throw INTERP_KERNEL::Exception("Functionnality of renumbering cell not available for IMesh !"); +} + +void MEDCouplingIMesh::getTinySerializationInformation(std::vector<double>& tinyInfoD, std::vector<int>& tinyInfo, std::vector<std::string>& 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()); + littleStrings.push_back(getAxisUnit()); + tinyInfo.push_back(it); + tinyInfo.push_back(order); + tinyInfo.push_back(_space_dim); + tinyInfo.insert(tinyInfo.end(),_structure,_structure+3); + tinyInfoD.push_back(time); + tinyInfoD.insert(tinyInfoD.end(),_dxyz,_dxyz+3); + tinyInfoD.insert(tinyInfoD.end(),_origin,_origin+3); +} + +void MEDCouplingIMesh::resizeForUnserialization(const std::vector<int>& tinyInfo, DataArrayInt *a1, DataArrayDouble *a2, std::vector<std::string>& littleStrings) const +{ + a1->alloc(0,1); + a2->alloc(0,1); +} + +void MEDCouplingIMesh::serialize(DataArrayInt *&a1, DataArrayDouble *&a2) const +{ + a1=DataArrayInt::New(); + a1->alloc(0,1); + a2=DataArrayDouble::New(); + a2->alloc(0,1); +} + +void MEDCouplingIMesh::unserialization(const std::vector<double>& tinyInfoD, const std::vector<int>& tinyInfo, const DataArrayInt *a1, DataArrayDouble *a2, + const std::vector<std::string>& littleStrings) +{ + setName(littleStrings[0]); + setDescription(littleStrings[1]); + setTimeUnit(littleStrings[2]); + setAxisUnit(littleStrings[3]); + setTime(tinyInfoD[0],tinyInfo[0],tinyInfo[1]); + _space_dim=tinyInfo[2]; + _structure[0]=tinyInfo[3]; _structure[1]=tinyInfo[4]; _structure[2]=tinyInfo[5]; + _dxyz[0]=tinyInfoD[1]; _dxyz[1]=tinyInfoD[2]; _dxyz[2]=tinyInfoD[3]; + _origin[0]=tinyInfoD[4]; _origin[1]=tinyInfoD[5]; _origin[2]=tinyInfoD[6]; + declareAsNew(); +} + +void MEDCouplingIMesh::writeVTKLL(std::ostream& ofs, const std::string& cellData, const std::string& pointData, DataArrayByte *byteData) const +{ + checkCoherency(); + std::ostringstream extent,origin,spacing; + for(int i=0;i<3;i++) + { + if(i<_space_dim) + { extent << "0 " << _structure[i]-1 << " "; origin << _origin[i] << " "; spacing << _dxyz[i] << " "; } + else + { extent << "0 0 "; origin << "0 "; spacing << "0 "; } + } + ofs << " <" << getVTKDataSetType() << " WholeExtent=\"" << extent.str() << "\" Origin=\"" << origin.str() << "\" Spacing=\"" << spacing.str() << "\">\n"; + ofs << " <Piece Extent=\"" << extent.str() << "\">\n"; + ofs << " <PointData>\n" << pointData << std::endl; + ofs << " </PointData>\n"; + ofs << " <CellData>\n" << cellData << std::endl; + ofs << " </CellData>\n"; + ofs << " <Coordinates>\n"; + ofs << " </Coordinates>\n"; + ofs << " </Piece>\n"; + ofs << " </" << getVTKDataSetType() << ">\n"; +} + +void MEDCouplingIMesh::reprQuickOverview(std::ostream& stream) const +{ + stream << "MEDCouplingIMesh C++ instance at " << this << ". Name : \"" << getName() << "\". Space dimension : " << _space_dim << "."; + if(_space_dim<0 || _space_dim>3) + return ; + stream << "\n"; + std::ostringstream stream0,stream1; + int nbNodes(1),nbCells(0); + bool isPb(false); + for(int i=0;i<_space_dim;i++) + { + char tmp('X'+i); + int tmpNodes(_structure[i]); + stream1 << "- Axis " << tmp << " : " << tmpNodes << " nodes (orig=" << _origin[i] << ", inter=" << _dxyz[i] << ")."; + if(i!=_space_dim-1) + stream1 << std::endl; + if(tmpNodes>=1) + nbNodes*=tmpNodes; + else + isPb=true; + if(tmpNodes>=2) + nbCells=nbCells==0?tmpNodes-1:nbCells*(tmpNodes-1); + } + if(!isPb) + { + stream0 << "Number of cells : " << nbCells << ", Number of nodes : " << nbNodes; + stream << stream0.str(); + if(_space_dim>0) + stream << std::endl; + } + stream << stream1.str(); +} + +std::string MEDCouplingIMesh::getVTKFileExtension() const +{ + return std::string("vti"); +} + +std::string MEDCouplingIMesh::getVTKDataSetType() const +{ + return std::string("ImageData"); +} + +std::vector<std::string> MEDCouplingIMesh::buildInfoOnComponents() const +{ + checkSpaceDimension(); + int dim(getSpaceDimension()); + std::vector<std::string> ret(dim); + for(int i=0;i<dim;i++) + { + std::ostringstream oss; + char tmp('X'+i); oss << tmp; + ret[i]=DataArray::BuildInfoFromVarAndUnit(oss.str(),_axis_unit); + } + return ret; +} + +void MEDCouplingIMesh::checkSpaceDimension() const +{ + CheckSpaceDimension(_space_dim); +} + +void MEDCouplingIMesh::CheckSpaceDimension(int spaceDim) +{ + if(spaceDim<0 || spaceDim>3) + throw INTERP_KERNEL::Exception("MEDCouplingIMesh::CheckSpaceDimension : input spaceDim must be in [0,1,2,3] !"); +} + +int MEDCouplingIMesh::FindIntRoot(int val, int order) +{ + if(order==0) + return 1; + if(val<0) + throw INTERP_KERNEL::Exception("MEDCouplingIMesh::FindIntRoot : input val is < 0 ! Not possible to compute a root !"); + if(order==1) + return val; + if(order!=2 && order!=3) + throw INTERP_KERNEL::Exception("MEDCouplingIMesh::FindIntRoot : the order available are 0,1,2 or 3 !"); + double valf((double)val); + if(order==2) + { + double retf(sqrt(valf)); + int ret((int)retf); + if(ret*ret!=val) + throw INTERP_KERNEL::Exception("MEDCouplingIMesh::FindIntRoot : the input val is not a perfect square root !"); + return ret; + } + else//order==3 + { + double retf(std::pow(val,0.3333333333333333)); + int ret((int)retf),ret2(ret+1); + if(ret*ret*ret!=val && ret2*ret2*ret2!=val) + throw INTERP_KERNEL::Exception("MEDCouplingIMesh::FindIntRoot : the input val is not a perfect cublic root !"); + if(ret*ret*ret==val) + return ret; + else + return ret2; + } +} + +void MEDCouplingIMesh::SpreadCoarseToFineGhost2D(const double *inPtr, double *outPtr, int nbCompo, const std::vector<int>& coarseSt, const std::vector< std::pair<int,int> >& fineLocInCoarse, const std::vector<int>& facts, int ghostSize) +{ + double *outPtrWork(outPtr); + std::vector<int> dims(MEDCouplingStructuredMesh::GetDimensionsFromCompactFrmt(fineLocInCoarse)); + int nxwg(coarseSt[0]+2*ghostSize),fact0(facts[0]),fact1(facts[1]); + int kk(fineLocInCoarse[0].first+ghostSize-1+nxwg*(fineLocInCoarse[1].first+ghostSize-1));//kk is always >=0 thanks to the fact that ghostSize>=1 ! + for(int jg=0;jg<ghostSize;jg++) + { + for(int ig=0;ig<ghostSize;ig++) + outPtrWork=std::copy(inPtr+kk*nbCompo,inPtr+(kk+1)*nbCompo,outPtrWork); + int kk0(kk+1); + for(int ig=0;ig<dims[0];ig++,kk0++) + for(int ifact=0;ifact<fact0;ifact++) + outPtrWork=std::copy(inPtr+(kk0)*nbCompo,inPtr+(kk0+1)*nbCompo,outPtrWork); + for(int ik=0;ik<ghostSize;ik++) + outPtrWork=std::copy(inPtr+kk0*nbCompo,inPtr+(kk0+1)*nbCompo,outPtrWork); + } + for(int j=0;j<dims[1];j++) + { + kk=fineLocInCoarse[0].first-1+ghostSize+nxwg*(fineLocInCoarse[1].first+ghostSize+j); + for(int jfact=0;jfact<fact1;jfact++) + { + for(int ig=0;ig<ghostSize;ig++) + outPtrWork=std::copy(inPtr+kk*nbCompo,inPtr+(kk+1)*nbCompo,outPtrWork); + int kk0(kk+1);//1 not ghost. We make the hypothesis that factors is >= ghostlev + for(int i=0;i<dims[0];i++,kk0++) + { + const double *loc(inPtr+kk0*nbCompo); + for(int ifact=0;ifact<fact0;ifact++) + outPtrWork=std::copy(loc,loc+nbCompo,outPtrWork); + } + for(int ig=0;ig<ghostSize;ig++) + outPtrWork=std::copy(inPtr+kk0*nbCompo,inPtr+(kk0+1)*nbCompo,outPtrWork); + } + } + kk=fineLocInCoarse[0].first+ghostSize-1+nxwg*(fineLocInCoarse[1].second+ghostSize); + for(int jg=0;jg<ghostSize;jg++) + { + for(int ig=0;ig<ghostSize;ig++) + outPtrWork=std::copy(inPtr+kk*nbCompo,inPtr+(kk+1)*nbCompo,outPtrWork); + int kk0(kk+1); + for(int ig=0;ig<dims[0];ig++,kk0++) + for(int ifact=0;ifact<fact0;ifact++) + outPtrWork=std::copy(inPtr+(kk0)*nbCompo,inPtr+(kk0+1)*nbCompo,outPtrWork); + for(int ik=0;ik<ghostSize;ik++) + outPtrWork=std::copy(inPtr+kk0*nbCompo,inPtr+(kk0+1)*nbCompo,outPtrWork); + } +} + +void MEDCouplingIMesh::SpreadCoarseToFineGhostZone2D(const double *inPtr, double *outPtr, int nbCompo, const std::vector<int>& coarseSt, const std::vector< std::pair<int,int> >& fineLocInCoarse, const std::vector<int>& facts, int ghostSize) +{ + double *outPtr2(outPtr); + std::vector<int> dims(MEDCouplingStructuredMesh::GetDimensionsFromCompactFrmt(fineLocInCoarse)); + int nxwg(coarseSt[0]+2*ghostSize),fact0(facts[0]),fact1(facts[1]); + int kk(fineLocInCoarse[0].first+ghostSize-1+nxwg*(fineLocInCoarse[1].first+ghostSize-1));//kk is always >=0 thanks to the fact that ghostSize>=1 ! + for(int jg=0;jg<ghostSize;jg++) + { + for(int ig=0;ig<ghostSize;ig++) + outPtr2=std::copy(inPtr+kk*nbCompo,inPtr+(kk+1)*nbCompo,outPtr2); + int kk0(kk+1); + for(int ig=0;ig<dims[0];ig++,kk0++) + for(int ifact=0;ifact<fact0;ifact++) + outPtr2=std::copy(inPtr+(kk0)*nbCompo,inPtr+(kk0+1)*nbCompo,outPtr2); + for(int ik=0;ik<ghostSize;ik++) + outPtr2=std::copy(inPtr+kk0*nbCompo,inPtr+(kk0+1)*nbCompo,outPtr2); + } + for(int j=0;j<dims[1];j++) + { + kk=fineLocInCoarse[0].first-1+ghostSize+nxwg*(fineLocInCoarse[1].first+ghostSize+j); + for(int jfact=0;jfact<fact1;jfact++) + { + for(int ig=0;ig<ghostSize;ig++) + outPtr2=std::copy(inPtr+kk*nbCompo,inPtr+(kk+1)*nbCompo,outPtr2); + int kk0(kk+1+dims[0]);//1 not ghost. We make the hypothesis that factors is >= ghostlev + outPtr2+=fact0*nbCompo*dims[0]; + for(int ig=0;ig<ghostSize;ig++) + outPtr2=std::copy(inPtr+kk0*nbCompo,inPtr+(kk0+1)*nbCompo,outPtr2); + } + } + kk=fineLocInCoarse[0].first+ghostSize-1+nxwg*(fineLocInCoarse[1].second+ghostSize); + for(int jg=0;jg<ghostSize;jg++) + { + for(int ig=0;ig<ghostSize;ig++) + outPtr2=std::copy(inPtr+kk*nbCompo,inPtr+(kk+1)*nbCompo,outPtr2); + int kk0(kk+1); + for(int ig=0;ig<dims[0];ig++,kk0++) + for(int ifact=0;ifact<fact0;ifact++) + outPtr2=std::copy(inPtr+(kk0)*nbCompo,inPtr+(kk0+1)*nbCompo,outPtr2); + for(int ik=0;ik<ghostSize;ik++) + outPtr2=std::copy(inPtr+kk0*nbCompo,inPtr+(kk0+1)*nbCompo,outPtr2); + } +} diff --git a/src/medtool/src/MEDCoupling/MEDCouplingIMesh.hxx b/src/medtool/src/MEDCoupling/MEDCouplingIMesh.hxx new file mode 100644 index 000000000..415770326 --- /dev/null +++ b/src/medtool/src/MEDCoupling/MEDCouplingIMesh.hxx @@ -0,0 +1,125 @@ +// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 +// 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_MEDCOUPLINGIMESH_HXX__ +#define __PARAMEDMEM_MEDCOUPLINGIMESH_HXX__ + +#include "MEDCoupling.hxx" +#include "MEDCouplingStructuredMesh.hxx" + +namespace ParaMEDMEM +{ + class MEDCouplingCMesh; + + class MEDCouplingIMesh : public MEDCouplingStructuredMesh + { + public: + MEDCOUPLING_EXPORT static MEDCouplingIMesh *New(); + MEDCOUPLING_EXPORT static MEDCouplingIMesh *New(const std::string& meshName, int spaceDim, const int *nodeStrctStart, const int *nodeStrctStop, + const double *originStart, const double *originStop, const double *dxyzStart, const double *dxyzStop); + // + MEDCOUPLING_EXPORT void setSpaceDimension(int spaceDim); + MEDCOUPLING_EXPORT void setNodeStruct(const int *nodeStrctStart, const int *nodeStrctStop); + MEDCOUPLING_EXPORT std::vector<int> getNodeStruct() const; + MEDCOUPLING_EXPORT void setOrigin(const double *originStart, const double *originStop); + MEDCOUPLING_EXPORT std::vector<double> getOrigin() const; + MEDCOUPLING_EXPORT void setDXYZ(const double *dxyzStart, const double *dxyzStop); + MEDCOUPLING_EXPORT std::vector<double> getDXYZ() const; + MEDCOUPLING_EXPORT void setAxisUnit(const std::string& unitName); + MEDCOUPLING_EXPORT std::string getAxisUnit() const; + MEDCOUPLING_EXPORT double getMeasureOfAnyCell() const; + MEDCOUPLING_EXPORT MEDCouplingCMesh *convertToCartesian() const; + MEDCOUPLING_EXPORT void refineWithFactor(const std::vector<int>& factors); + MEDCOUPLING_EXPORT MEDCouplingIMesh *asSingleCell() const; + MEDCOUPLING_EXPORT static void CondenseFineToCoarse(const std::vector<int>& coarseSt, const DataArrayDouble *fineDA, const std::vector< std::pair<int,int> >& fineLocInCoarse, const std::vector<int>& facts, DataArrayDouble *coarseDA); + MEDCOUPLING_EXPORT static void CondenseFineToCoarseGhost(const std::vector<int>& coarseSt, const DataArrayDouble *fineDA, const std::vector< std::pair<int,int> >& fineLocInCoarse, const std::vector<int>& facts, DataArrayDouble *coarseDA, int ghostSize); + MEDCOUPLING_EXPORT static void SpreadCoarseToFine(const DataArrayDouble *coarseDA, const std::vector<int>& coarseSt, DataArrayDouble *fineDA, const std::vector< std::pair<int,int> >& fineLocInCoarse, const std::vector<int>& facts); + MEDCOUPLING_EXPORT static void SpreadCoarseToFineGhost(const DataArrayDouble *coarseDA, const std::vector<int>& coarseSt, DataArrayDouble *fineDA, const std::vector< std::pair<int,int> >& fineLocInCoarse, const std::vector<int>& facts, int ghostSize); + MEDCOUPLING_EXPORT static void SpreadCoarseToFineGhostZone(const DataArrayDouble *coarseDA, const std::vector<int>& coarseSt, DataArrayDouble *fineDA, const std::vector< std::pair<int,int> >& fineLocInCoarse, const std::vector<int>& facts, int ghostSize); + // + MEDCOUPLING_EXPORT MEDCouplingMesh *deepCpy() const; + MEDCOUPLING_EXPORT MEDCouplingIMesh *clone(bool recDeepCpy) const; + MEDCOUPLING_EXPORT MEDCouplingIMesh *buildWithGhost(int ghostLev) const; + MEDCOUPLING_EXPORT void updateTime() const; + MEDCOUPLING_EXPORT std::size_t getHeapMemorySizeWithoutChildren() const; + MEDCOUPLING_EXPORT std::vector<const BigMemoryObject *> getDirectChildrenWithNull() const; + MEDCOUPLING_EXPORT MEDCouplingMeshType getType() const { return IMAGE_GRID; } + MEDCOUPLING_EXPORT void copyTinyStringsFrom(const MEDCouplingMesh *other); + MEDCOUPLING_EXPORT bool isEqualIfNotWhy(const MEDCouplingMesh *other, double prec, std::string& reason) const; + MEDCOUPLING_EXPORT bool isEqualWithoutConsideringStr(const MEDCouplingMesh *other, double prec) const; + MEDCOUPLING_EXPORT void checkDeepEquivalWith(const MEDCouplingMesh *other, int cellCompPol, double prec, + DataArrayInt *&cellCor, DataArrayInt *&nodeCor) const; + MEDCOUPLING_EXPORT void checkDeepEquivalOnSameNodesWith(const MEDCouplingMesh *other, int cellCompPol, double prec, + DataArrayInt *&cellCor) const; + MEDCOUPLING_EXPORT void checkCoherency() const; + MEDCOUPLING_EXPORT void checkCoherency1(double eps=1e-12) const; + MEDCOUPLING_EXPORT void checkCoherency2(double eps=1e-12) const; + MEDCOUPLING_EXPORT int getSpaceDimension() const; + MEDCOUPLING_EXPORT void getCoordinatesOfNode(int nodeId, std::vector<double>& coo) const; + MEDCOUPLING_EXPORT std::string simpleRepr() const; + MEDCOUPLING_EXPORT std::string advancedRepr() const; + // tools + MEDCOUPLING_EXPORT void getBoundingBox(double *bbox) const; + MEDCOUPLING_EXPORT MEDCouplingFieldDouble *getMeasureField(bool isAbs) const; + MEDCOUPLING_EXPORT MEDCouplingFieldDouble *getMeasureFieldOnNode(bool isAbs) const; + MEDCOUPLING_EXPORT int getCellContainingPoint(const double *pos, double eps) const; + MEDCOUPLING_EXPORT void rotate(const double *center, const double *vector, double angle); + MEDCOUPLING_EXPORT void translate(const double *vector); + MEDCOUPLING_EXPORT void scale(const double *point, double factor); + MEDCOUPLING_EXPORT MEDCouplingMesh *mergeMyselfWith(const MEDCouplingMesh *other) const; + MEDCOUPLING_EXPORT DataArrayDouble *getCoordinatesAndOwner() const; + MEDCOUPLING_EXPORT DataArrayDouble *getBarycenterAndOwner() const; + MEDCOUPLING_EXPORT DataArrayDouble *computeIsoBarycenterOfNodesPerCell() const; + MEDCOUPLING_EXPORT void renumberCells(const int *old2NewBg, bool check=true); + //some useful methods + MEDCOUPLING_EXPORT void getNodeGridStructure(int *res) const; + MEDCOUPLING_EXPORT std::vector<int> getNodeGridStructure() const; + MEDCouplingStructuredMesh *buildStructuredSubPart(const std::vector< std::pair<int,int> >& cellPart) const; + //serialisation-unserialization + MEDCOUPLING_EXPORT void getTinySerializationInformation(std::vector<double>& tinyInfoD, std::vector<int>& tinyInfo, std::vector<std::string>& littleStrings) const; + MEDCOUPLING_EXPORT void resizeForUnserialization(const std::vector<int>& tinyInfo, DataArrayInt *a1, DataArrayDouble *a2, std::vector<std::string>& littleStrings) const; + MEDCOUPLING_EXPORT void serialize(DataArrayInt *&a1, DataArrayDouble *&a2) const; + MEDCOUPLING_EXPORT void unserialization(const std::vector<double>& tinyInfoD, const std::vector<int>& tinyInfo, const DataArrayInt *a1, DataArrayDouble *a2, + const std::vector<std::string>& littleStrings); + MEDCOUPLING_EXPORT void reprQuickOverview(std::ostream& stream) const; + MEDCOUPLING_EXPORT std::string getVTKFileExtension() const; + private: + MEDCouplingIMesh(); + MEDCouplingIMesh(const MEDCouplingIMesh& other, bool deepCpy); + ~MEDCouplingIMesh(); + void writeVTKLL(std::ostream& ofs, const std::string& cellData, const std::string& pointData, DataArrayByte *byteData) const; + std::string getVTKDataSetType() const; + bool isEqualWithoutConsideringStrInternal(const MEDCouplingMesh *other, double prec, std::string& reason) const; + std::vector<std::string> buildInfoOnComponents() const; + void checkSpaceDimension() const; + static void CheckSpaceDimension(int spaceDim); + static int FindIntRoot(int val, int order); + static void SpreadCoarseToFineGhost2D(const double *inPtr, double *outPtr, int nbCompo, const std::vector<int>& coarseSt, const std::vector< std::pair<int,int> >& fineLocInCoarse, const std::vector<int>& facts, int ghostSize); + static void SpreadCoarseToFineGhostZone2D(const double *inPtr, double *outPtr, int nbCompo, const std::vector<int>& coarseSt, const std::vector< std::pair<int,int> >& fineLocInCoarse, const std::vector<int>& facts, int ghostSize); + private: + int _space_dim; + double _origin[3]; + double _dxyz[3]; + int _structure[3]; + std::string _axis_unit; + }; +} + +#endif diff --git a/src/medtool/src/MEDCoupling/MEDCouplingMatrix.cxx b/src/medtool/src/MEDCoupling/MEDCouplingMatrix.cxx new file mode 100644 index 000000000..4f0172dc4 --- /dev/null +++ b/src/medtool/src/MEDCoupling/MEDCouplingMatrix.cxx @@ -0,0 +1,324 @@ +// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 +// 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 + +#include "MEDCouplingMatrix.hxx" + +#include "InterpKernelMatrixTools.hxx" + +using namespace ParaMEDMEM; + +DenseMatrix *DenseMatrix::New(int nbRows, int nbCols) +{ + return new DenseMatrix(nbRows,nbCols); +} + +DenseMatrix *DenseMatrix::New(DataArrayDouble *array, int nbRows, int nbCols) +{ + return new DenseMatrix(array,nbRows,nbCols); +} + +DenseMatrix *DenseMatrix::deepCpy() const +{ + MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> arr(getData()->deepCpy()); + MEDCouplingAutoRefCountObjectPtr<DenseMatrix> ret(DenseMatrix::New(arr,getNumberOfRows(),getNumberOfCols())); + return ret.retn(); +} + +DenseMatrix *DenseMatrix::shallowCpy() const +{ + MEDCouplingAutoRefCountObjectPtr<DenseMatrix> ret(DenseMatrix::New(const_cast<DataArrayDouble *>(getData()),getNumberOfRows(),getNumberOfCols())); + return ret.retn(); +} + +std::size_t DenseMatrix::getHeapMemorySizeWithoutChildren() const +{ + return sizeof(DenseMatrix); +} + +std::vector<const BigMemoryObject *> DenseMatrix::getDirectChildrenWithNull() const +{ + std::vector<const BigMemoryObject *> ret; + ret.push_back((const DataArrayDouble *)_data); + return ret; +} + +void DenseMatrix::updateTime() const +{ + const DataArrayDouble *pt(_data); + if(pt) + updateTimeWith(*pt); +} + +/*! + * This method scratch \a this to use a new input. The shape of \a this can be modified freely without any constraints. + * + * \param [in] array - The array containing data that is expected to be taken as new data. + * \param [in] nbRows - The new number of rows (>0 or -1). If -1, the current number of rows will be taken. + * \param [in] nbCols - The new number of columns (>0 or -1). If -1, the current number of cols will be taken. + * + * \sa reShape + */ +void DenseMatrix::reBuild(DataArrayDouble *array, int nbRows, int nbCols) +{ + int nbr(getNumberOfRowsExt(nbRows)),nbc(getNumberOfColsExt(nbCols)); + CheckArraySizes(array,nbr,nbc); + DataArrayDouble *data(_data); + if(data!=array) + { + _data=array; _data->incrRef(); + declareAsNew(); + } + if(nbr!=_nb_rows) + { + _nb_rows=nbr; + declareAsNew(); + } + if(nbc!=_nb_cols) + { + _nb_cols=nbc; + declareAsNew(); + } +} + +/*! + * This method does \b not change the content of the data in \a this. It only changes the shape (with a same number of elements in the matrix). + * If the number of elements needs to be changed call reBuild method instead. + * + * \param [in] nbRows - The new number of rows (>0) + * \param [in] nbCols - The new number of columns (>0) + * \throw if the \c nbRows*nbCols is not equal to \c this->getNbOfElems() + * \sa reBuild + */ +void DenseMatrix::reShape(int nbRows, int nbCols) +{ + if(nbRows<0 || nbCols<0) + throw INTERP_KERNEL::Exception("DenseMatrix::reShape : number of rows and number of cols must be > 0 both !"); + if(nbRows*nbCols!=getNbOfElems()) + throw INTERP_KERNEL::Exception("DenseMatrix::reShape : This method is designed to change only the shape ! Number of elements must remain the same !"); + if(_nb_rows!=nbRows) + { + _nb_rows=nbRows; + declareAsNew(); + } + if(_nb_cols!=nbCols) + { + _nb_cols=nbCols; + declareAsNew(); + } +} + +void DenseMatrix::transpose() +{ + const MemArray<double>& mem(getData()->accessToMemArray()); + double *pt(mem.toNoInterlace(getNumberOfCols())); + std::copy(pt,pt+getNbOfElems(),getData()->getPointer());//declareAsNew done here automatically by getPointer + free(pt); + std::swap(_nb_rows,_nb_cols); + updateTime(); +} + +bool DenseMatrix::isEqual(const DenseMatrix& other, double eps) const +{ + std::string tmp; + return isEqualIfNotWhy(other,eps,tmp); +} + +bool DenseMatrix::isEqualIfNotWhy(const DenseMatrix& other, double eps, std::string& reason) const +{ + if(_nb_rows!=other._nb_rows) + { + std::ostringstream oss; oss << "Number of rows differs (" << _nb_rows << "!=" << other._nb_rows << ") !"; + reason+=oss.str(); + return false; + } + if(_nb_cols!=other._nb_cols) + { + std::ostringstream oss; oss << "Number of cols differs (" << _nb_cols << "!=" << other._nb_cols << ") !"; + reason+=oss.str(); + return false; + } + std::string tmp1; + if(!_data->isEqualIfNotWhy(*other._data,eps,tmp1)) + { + reason+="Data differs : "+tmp1; + return false; + } + return true; +} + +DataArrayDouble *DenseMatrix::matVecMult(const DataArrayDouble *vec) const +{ + return MatVecMult(this,vec); +} + +DataArrayDouble *DenseMatrix::MatVecMult(const DenseMatrix *mat, const DataArrayDouble *vec) +{ + if(!mat || !vec) + throw INTERP_KERNEL::Exception("DenseMatrix::MatVecMult : input matrix or vec is NULL !"); + vec->checkAllocated(); + if(vec->getNumberOfComponents()!=1) + throw INTERP_KERNEL::Exception("DenseMatrix::MatVecMult : input vector must have only one component !"); + if(vec->getNumberOfTuples()!=mat->getNumberOfCols()) + throw INTERP_KERNEL::Exception("DenseMatrix::MatVecMult : Number of columns of this must be equal to number of tuples of vec !"); + MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret(DataArrayDouble::New()); ret->alloc(mat->getNumberOfRows(),1); + INTERP_KERNEL::matrixProduct(mat->getData()->begin(),mat->getNumberOfRows(),mat->getNumberOfCols(),vec->begin(),vec->getNumberOfTuples(),1,ret->getPointer()); + return ret.retn(); +} + +DenseMatrix *DenseMatrix::Add(const DenseMatrix *a1, const DenseMatrix *a2) +{ + if(!a1 || !a2) + throw INTERP_KERNEL::Exception("DenseMatrix::Add : input matrices must be not NULL !"); + CheckSameSize(a1,a2); + MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> data(DataArrayDouble::Add(a1->getData(),a2->getData())); + MEDCouplingAutoRefCountObjectPtr<DenseMatrix> ret(DenseMatrix::New(data,a1->getNumberOfRows(),a1->getNumberOfCols())); + return ret.retn(); +} + +void DenseMatrix::addEqual(const DenseMatrix *other) +{ + if(!other) + throw INTERP_KERNEL::Exception("DenseMatrix::addEqual : other must be not NULL !"); + CheckSameSize(this,other); + getData()->addEqual(other->getData()); +} + +DenseMatrix *DenseMatrix::Substract(const DenseMatrix *a1, const DenseMatrix *a2) +{ + if(!a1 || !a2) + throw INTERP_KERNEL::Exception("DenseMatrix::Substract : input matrices must be not NULL !"); + CheckSameSize(a1,a2); + MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> data(DataArrayDouble::Substract(a1->getData(),a2->getData())); + MEDCouplingAutoRefCountObjectPtr<DenseMatrix> ret(DenseMatrix::New(data,a1->getNumberOfRows(),a1->getNumberOfCols())); + return ret.retn(); +} + +void DenseMatrix::substractEqual(const DenseMatrix *other) +{ + if(!other) + throw INTERP_KERNEL::Exception("DenseMatrix::substractEqual : other must be not NULL !"); + CheckSameSize(this,other); + getData()->substractEqual(other->getData()); +} + +DenseMatrix *DenseMatrix::Multiply(const DenseMatrix *a1, const DenseMatrix *a2) +{ + if(!a1 || !a2) + throw INTERP_KERNEL::Exception("DenseMatrix::Multiply : input matrices must be not NULL !"); + CheckCompatibleSizeForMul(a1,a2); + int nbr(a1->getNumberOfRows()),nbc(a2->getNumberOfCols()); + MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> data(DataArrayDouble::New()); data->alloc(nbr*nbc,1); + MEDCouplingAutoRefCountObjectPtr<DenseMatrix> ret(DenseMatrix::New(data,a1->getNumberOfRows(),a2->getNumberOfCols())); + INTERP_KERNEL::matrixProduct(a1->getData()->begin(),a1->getNumberOfRows(),a1->getNumberOfCols(),a2->getData()->begin(),a2->getNumberOfRows(),a2->getNumberOfCols(),data->getPointer()); + return ret.retn(); +} + +DenseMatrix *DenseMatrix::Multiply(const DenseMatrix *a1, const DataArrayDouble *a2) +{ + if(!a1 || !a2 || !a2->isAllocated()) + throw INTERP_KERNEL::Exception("DenseMatrix::Multiply #2 : input matrices must be not NULL and a2 allocated !"); + if(a2->getNumberOfComponents()!=1) + throw INTERP_KERNEL::Exception("DenseMatrix::Multiply #2 : The 2nd member must have exactly one component !"); + MEDCouplingAutoRefCountObjectPtr<DenseMatrix> a2Bis(DenseMatrix::New(const_cast<DataArrayDouble *>(a2),a2->getNumberOfTuples(),1)); + return DenseMatrix::Multiply(a1,a2Bis); +} + +DenseMatrix::~DenseMatrix() +{ +} + +DenseMatrix::DenseMatrix(int nbRows, int nbCols):_nb_rows(nbRows),_nb_cols(nbCols),_data(DataArrayDouble::New()) +{ + if(_nb_rows<0 || _nb_cols<0) + throw INTERP_KERNEL::Exception("constructor of DenseMatrix : number of rows and number of cols must be > 0 both !"); + int nbOfTuples(_nb_rows*_nb_cols); + _data->alloc(nbOfTuples,1); +} + +DenseMatrix::DenseMatrix(DataArrayDouble *array, int nbRows, int nbCols):_nb_rows(nbRows),_nb_cols(nbCols) +{ + CheckArraySizes(array,_nb_rows,_nb_cols); + _data=array; _data->incrRef(); +} + +int DenseMatrix::getNumberOfRowsExt(int nbRows) const +{ + if(nbRows<-1) + throw INTERP_KERNEL::Exception("DenseMatrix::getNumberOfRowsExt : invalid input must be >= -1 !"); + if(nbRows==-1) + return _nb_rows; + else + return nbRows; +} + +int DenseMatrix::getNumberOfColsExt(int nbCols) const +{ + if(nbCols<-1) + throw INTERP_KERNEL::Exception("DenseMatrix::getNumberOfColsExt : invalid input must be >= -1 !"); + if(nbCols==-1) + return _nb_cols; + else + return nbCols; +} + +void DenseMatrix::checkValidData() const +{ + if(!getData()) + throw INTERP_KERNEL::Exception("DenseMatrix::checkValidData : data is NULL !"); + if(!getData()->isAllocated()) + throw INTERP_KERNEL::Exception("DenseMatrix::checkValidData : data is not allocated !"); + if(getData()->getNumberOfComponents()!=1) + throw INTERP_KERNEL::Exception("DenseMatrix::checkValidData : data has not 1 component !"); +} + +void DenseMatrix::CheckArraySizes(DataArrayDouble *array, int nbRows, int nbCols) +{ + if(nbRows<0 || nbCols<0) + throw INTERP_KERNEL::Exception("constructor #2 of DenseMatrix : number of rows and number of cols must be > 0 both !"); + if(!array || !array->isAllocated()) + throw INTERP_KERNEL::Exception("constructor #2 of DenseMatrix : input array is empty or not allocated !"); + if(array->getNumberOfComponents()!=1) + throw INTERP_KERNEL::Exception("constructor #2 of DenseMatrix : input array must have exactly one component !"); + std::size_t nbr((std::size_t)nbRows),nbc((std::size_t)nbCols); + if(nbr*nbc!=array->getNbOfElems()) + throw INTERP_KERNEL::Exception("constructor #2 of DenseMatrix : the number of elems in input array is not equal to the product of nbRows and nbCols !"); +} + +void DenseMatrix::CheckSameSize(const DenseMatrix *a1, const DenseMatrix *a2) +{ + if(!a1 || !a2) + throw INTERP_KERNEL::Exception("DenseMatrix::CheckSameSize : a1 or a2 is NULL !"); + a1->checkValidData(); a2->checkValidData(); + if(a1->getNumberOfRows()!=a2->getNumberOfRows()) + throw INTERP_KERNEL::Exception("DenseMatrix::CheckSameSize : number of rows mismatches !"); + if(a1->getNumberOfCols()!=a2->getNumberOfCols()) + throw INTERP_KERNEL::Exception("DenseMatrix::CheckSameSize : number of columns mismatches !"); + +} + +void DenseMatrix::CheckCompatibleSizeForMul(const DenseMatrix *a1, const DenseMatrix *a2) +{ + if(!a1 || !a2) + throw INTERP_KERNEL::Exception("DenseMatrix::CheckCompatibleSizeForMul : a1 or a2 is NULL !"); + a1->checkValidData(); a2->checkValidData(); + if(a1->getNumberOfCols()!=a2->getNumberOfRows()) + throw INTERP_KERNEL::Exception("DenseMatrix::CheckCompatibleSizeForMul : number of cols of a1 must be equal to number of rows of a2 !"); +} + diff --git a/src/medtool/src/MEDCoupling/MEDCouplingMatrix.hxx b/src/medtool/src/MEDCoupling/MEDCouplingMatrix.hxx new file mode 100644 index 000000000..93c7f6502 --- /dev/null +++ b/src/medtool/src/MEDCoupling/MEDCouplingMatrix.hxx @@ -0,0 +1,86 @@ +// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 +// 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 + +#ifndef __PARAMEDMEM_MEDCOUPLINGMATRIX_HXX__ +#define __PARAMEDMEM_MEDCOUPLINGMATRIX_HXX__ + +#include "MEDCoupling.hxx" +#include "MEDCouplingTimeLabel.hxx" +#include "MEDCouplingRefCountObject.hxx" +#include "MEDCouplingMemArray.hxx" +#include "MEDCouplingAutoRefCountObjectPtr.hxx" + +#include "InterpKernelException.hxx" + +namespace ParaMEDMEM +{ + /*! + * The aim of this class is \b NOT to reimplement all linear algebra but only to store a dense matrix. + * It only provides basic set/get and basic operations and bindings to linear algebra libraries (numpy/scipy) and a compatible format to Petsc. + */ + class DenseMatrix : public RefCountObject, public TimeLabel + { + public: + MEDCOUPLING_EXPORT static DenseMatrix *New(int nbRows, int nbCols); + MEDCOUPLING_EXPORT static DenseMatrix *New(DataArrayDouble *array, int nbRows, int nbCols); + MEDCOUPLING_EXPORT DenseMatrix *deepCpy() const; + MEDCOUPLING_EXPORT DenseMatrix *shallowCpy() const; + MEDCOUPLING_EXPORT std::size_t getHeapMemorySizeWithoutChildren() const; + MEDCOUPLING_EXPORT std::vector<const BigMemoryObject *> getDirectChildrenWithNull() const; + MEDCOUPLING_EXPORT void updateTime() const; + // + MEDCOUPLING_EXPORT int getNumberOfRows() const { return _nb_rows; } + MEDCOUPLING_EXPORT int getNumberOfCols() const { return _nb_cols; } + MEDCOUPLING_EXPORT int getNbOfElems() const { return _nb_rows*_nb_cols; } + MEDCOUPLING_EXPORT void reBuild(DataArrayDouble *array, int nbRows=-1, int nbCols=-1); + MEDCOUPLING_EXPORT void reShape(int nbRows, int nbCols); + MEDCOUPLING_EXPORT void transpose(); + // + MEDCOUPLING_EXPORT bool isEqual(const DenseMatrix& other, double eps) const; + MEDCOUPLING_EXPORT bool isEqualIfNotWhy(const DenseMatrix& other, double eps, std::string& reason) const; + MEDCOUPLING_EXPORT DataArrayDouble *matVecMult(const DataArrayDouble *vec) const; + MEDCOUPLING_EXPORT static DataArrayDouble *MatVecMult(const DenseMatrix *mat, const DataArrayDouble *vec); + MEDCOUPLING_EXPORT static DenseMatrix *Add(const DenseMatrix *a1, const DenseMatrix *a2); + MEDCOUPLING_EXPORT void addEqual(const DenseMatrix *other); + MEDCOUPLING_EXPORT static DenseMatrix *Substract(const DenseMatrix *a1, const DenseMatrix *a2); + MEDCOUPLING_EXPORT void substractEqual(const DenseMatrix *other); + MEDCOUPLING_EXPORT static DenseMatrix *Multiply(const DenseMatrix *a1, const DenseMatrix *a2); + MEDCOUPLING_EXPORT static DenseMatrix *Multiply(const DenseMatrix *a1, const DataArrayDouble *a2); + // + MEDCOUPLING_EXPORT const DataArrayDouble *getData() const { return _data; } + MEDCOUPLING_EXPORT DataArrayDouble *getData() { return _data; } + private: + ~DenseMatrix(); + DenseMatrix(int nbRows, int nbCols); + DenseMatrix(DataArrayDouble *array, int nbRows, int nbCols); + int getNumberOfRowsExt(int nbRows) const; + int getNumberOfColsExt(int nbCols) const; + void checkValidData() const; + static void CheckArraySizes(DataArrayDouble *array, int nbRows, int nbCols); + static void CheckSameSize(const DenseMatrix *a1, const DenseMatrix *a2); + static void CheckCompatibleSizeForMul(const DenseMatrix *a1, const DenseMatrix *a2); + private: + int _nb_rows; + int _nb_cols; + MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> _data; + }; +} + +#endif diff --git a/src/medtool/src/MEDCoupling/MEDCouplingMemArray.cxx b/src/medtool/src/MEDCoupling/MEDCouplingMemArray.cxx new file mode 100644 index 000000000..751741283 --- /dev/null +++ b/src/medtool/src/MEDCoupling/MEDCouplingMemArray.cxx @@ -0,0 +1,11860 @@ +// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 +// 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 "BBTree.txx" +#include "GenMathFormulae.hxx" +#include "InterpKernelAutoPtr.hxx" +#include "InterpKernelExprParser.hxx" + +#include <set> +#include <cmath> +#include <limits> +#include <numeric> +#include <algorithm> +#include <functional> + +typedef double (*MYFUNCPTR)(double); + +using namespace ParaMEDMEM; + +template<int SPACEDIM> +void DataArrayDouble::findCommonTuplesAlg(const double *bbox, int nbNodes, int limitNodeId, double prec, DataArrayInt *c, DataArrayInt *cI) const +{ + const double *coordsPtr=getConstPointer(); + BBTreePts<SPACEDIM,int> myTree(bbox,0,0,nbNodes,prec); + std::vector<bool> isDone(nbNodes); + for(int i=0;i<nbNodes;i++) + { + if(!isDone[i]) + { + std::vector<int> intersectingElems; + myTree.getElementsAroundPoint(coordsPtr+i*SPACEDIM,intersectingElems); + if(intersectingElems.size()>1) + { + std::vector<int> commonNodes; + for(std::vector<int>::const_iterator it=intersectingElems.begin();it!=intersectingElems.end();it++) + if(*it!=i) + if(*it>=limitNodeId) + { + commonNodes.push_back(*it); + isDone[*it]=true; + } + if(!commonNodes.empty()) + { + cI->pushBackSilent(cI->back()+(int)commonNodes.size()+1); + c->pushBackSilent(i); + c->insertAtTheEnd(commonNodes.begin(),commonNodes.end()); + } + } + } + } +} + +template<int SPACEDIM> +void DataArrayDouble::FindTupleIdsNearTuplesAlg(const BBTreePts<SPACEDIM,int>& myTree, const double *pos, int nbOfTuples, double eps, + DataArrayInt *c, DataArrayInt *cI) +{ + for(int i=0;i<nbOfTuples;i++) + { + std::vector<int> intersectingElems; + myTree.getElementsAroundPoint(pos+i*SPACEDIM,intersectingElems); + std::vector<int> commonNodes; + for(std::vector<int>::const_iterator it=intersectingElems.begin();it!=intersectingElems.end();it++) + commonNodes.push_back(*it); + cI->pushBackSilent(cI->back()+(int)commonNodes.size()); + c->insertAtTheEnd(commonNodes.begin(),commonNodes.end()); + } +} + +template<int SPACEDIM> +void DataArrayDouble::FindClosestTupleIdAlg(const BBTreePts<SPACEDIM,int>& 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<nbOfTuples;i++,p+=SPACEDIM,r++) + { + while(true) + { + int elem=-1; + double ret=myTree.getElementsAroundPoint2(p,distOpt,elem); + if(ret!=std::numeric_limits<double>::max()) + { + distOpt=std::max(ret,1e-4); + *r=elem; + break; + } + else + { distOpt=2*distOpt; continue; } + } + } +} + +std::size_t DataArray::getHeapMemorySizeWithoutChildren() const +{ + std::size_t sz1=_name.capacity(); + std::size_t sz2=_info_on_compo.capacity(); + std::size_t sz3=0; + for(std::vector<std::string>::const_iterator it=_info_on_compo.begin();it!=_info_on_compo.end();it++) + sz3+=(*it).capacity(); + return sz1+sz2+sz3; +} + +std::vector<const BigMemoryObject *> DataArray::getDirectChildrenWithNull() const +{ + return std::vector<const BigMemoryObject *>(); +} + +/*! + * 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 std::string& 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) +{ + if(_info_on_compo.size()!=other._info_on_compo.size()) + throw INTERP_KERNEL::Exception("Size of arrays mismatches on copyStringInfoFrom !"); + _name=other._name; + _info_on_compo=other._info_on_compo; +} + +void DataArray::copyPartOfStringInfoFrom(const DataArray& other, const std::vector<int>& compoIds) +{ + int nbOfCompoOth=other.getNumberOfComponents(); + std::size_t newNbOfCompo=compoIds.size(); + for(std::size_t i=0;i<newNbOfCompo;i++) + if(compoIds[i]>=nbOfCompoOth || compoIds[i]<0) + { + std::ostringstream oss; oss << "Specified component id is out of range (" << compoIds[i] << ") compared with nb of actual components (" << nbOfCompoOth << ")"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + for(std::size_t i=0;i<newNbOfCompo;i++) + setInfoOnComponent((int)i,other.getInfoOnComponent(compoIds[i])); +} + +void DataArray::copyPartOfStringInfoFrom2(const std::vector<int>& compoIds, const DataArray& other) +{ + int nbOfCompo=getNumberOfComponents(); + std::size_t partOfCompoToSet=compoIds.size(); + if((int)partOfCompoToSet!=other.getNumberOfComponents()) + throw INTERP_KERNEL::Exception("Given compoIds has not the same size as number of components of given array !"); + for(std::size_t i=0;i<partOfCompoToSet;i++) + if(compoIds[i]>=nbOfCompo || compoIds[i]<0) + { + std::ostringstream oss; oss << "Specified component id is out of range (" << compoIds[i] << ") compared with nb of actual components (" << nbOfCompo << ")"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + for(std::size_t i=0;i<partOfCompoToSet;i++) + setInfoOnComponent(compoIds[i],other.getInfoOnComponent((int)i)); +} + +bool DataArray::areInfoEqualsIfNotWhy(const DataArray& other, std::string& reason) const +{ + std::ostringstream oss; + if(_name!=other._name) + { + oss << "Names DataArray mismatch : this name=\"" << _name << " other name=\"" << other._name << "\" !"; + reason=oss.str(); + return false; + } + if(_info_on_compo!=other._info_on_compo) + { + oss << "Components DataArray mismatch : \nThis components="; + for(std::vector<std::string>::const_iterator it=_info_on_compo.begin();it!=_info_on_compo.end();it++) + oss << "\"" << *it << "\","; + oss << "\nOther components="; + for(std::vector<std::string>::const_iterator it=other._info_on_compo.begin();it!=other._info_on_compo.end();it++) + oss << "\"" << *it << "\","; + reason=oss.str(); + return false; + } + return true; +} + +/*! + * 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 +{ + std::string tmp; + return areInfoEqualsIfNotWhy(other,tmp); +} + +void DataArray::reprWithoutNameStream(std::ostream& stream) const +{ + stream << "Number of components : "<< getNumberOfComponents() << "\n"; + stream << "Info of these components : "; + for(std::vector<std::string>::const_iterator iter=_info_on_compo.begin();iter!=_info_on_compo.end();iter++) + stream << "\"" << *iter << "\" "; + stream << "\n"; +} + +std::string DataArray::cppRepr(const std::string& varName) const +{ + std::ostringstream ret; + reprCppStream(varName,ret); + 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<std::string>& info) +{ + if(getNumberOfComponents()!=(int)info.size()) + { + std::ostringstream oss; oss << "DataArray::setInfoOnComponents : input is of size " << info.size() << " whereas number of components is equal to " << getNumberOfComponents() << " !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + _info_on_compo=info; +} + +/*! + * This method is only a dispatcher towards DataArrayDouble::setPartOfValues3, DataArrayInt::setPartOfValues3, DataArrayChar::setPartOfValues3 depending on the true + * type of \a this and \a aBase. + * + * \throw If \a aBase and \a this do not have the same type. + * + * \sa DataArrayDouble::setPartOfValues3, DataArrayInt::setPartOfValues3, DataArrayChar::setPartOfValues3. + */ +void DataArray::setPartOfValuesBase3(const DataArray *aBase, const int *bgTuples, const int *endTuples, int bgComp, int endComp, int stepComp, bool strictCompoCompare) +{ + if(!aBase) + throw INTERP_KERNEL::Exception("DataArray::setPartOfValuesBase3 : input aBase object is NULL !"); + DataArrayDouble *this1(dynamic_cast<DataArrayDouble *>(this)); + DataArrayInt *this2(dynamic_cast<DataArrayInt *>(this)); + DataArrayChar *this3(dynamic_cast<DataArrayChar *>(this)); + const DataArrayDouble *a1(dynamic_cast<const DataArrayDouble *>(aBase)); + const DataArrayInt *a2(dynamic_cast<const DataArrayInt *>(aBase)); + const DataArrayChar *a3(dynamic_cast<const DataArrayChar *>(aBase)); + if(this1 && a1) + { + this1->setPartOfValues3(a1,bgTuples,endTuples,bgComp,endComp,stepComp,strictCompoCompare); + return ; + } + if(this2 && a2) + { + this2->setPartOfValues3(a2,bgTuples,endTuples,bgComp,endComp,stepComp,strictCompoCompare); + return ; + } + if(this3 && a3) + { + this3->setPartOfValues3(a3,bgTuples,endTuples,bgComp,endComp,stepComp,strictCompoCompare); + return ; + } + throw INTERP_KERNEL::Exception("DataArray::setPartOfValuesBase3 : input aBase object and this do not have the same type !"); +} + +std::vector<std::string> DataArray::getVarsOnComponent() const +{ + int nbOfCompo=(int)_info_on_compo.size(); + std::vector<std::string> ret(nbOfCompo); + for(int i=0;i<nbOfCompo;i++) + ret[i]=getVarOnComponent(i); + return ret; +} + +std::vector<std::string> DataArray::getUnitsOnComponent() const +{ + int nbOfCompo=(int)_info_on_compo.size(); + std::vector<std::string> ret(nbOfCompo); + for(int i=0;i<nbOfCompo;i++) + ret[i]=getUnitOnComponent(i); + 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 +{ + if(i<(int)_info_on_compo.size() && i>=0) + return _info_on_compo[i]; + else + { + std::ostringstream oss; oss << "DataArray::getInfoOnComponent : Specified component id is out of range (" << i << ") compared with nb of actual components (" << (int) _info_on_compo.size(); + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } +} + +/*! + * 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 +{ + if(i<(int)_info_on_compo.size() && i>=0) + { + return GetVarNameFromInfo(_info_on_compo[i]); + } + else + { + std::ostringstream oss; oss << "DataArray::getVarOnComponent : Specified component id is out of range (" << i << ") compared with nb of actual components (" << (int) _info_on_compo.size(); + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } +} + +/*! + * 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 +{ + if(i<(int)_info_on_compo.size() && i>=0) + { + return GetUnitFromInfo(_info_on_compo[i]); + } + else + { + std::ostringstream oss; oss << "DataArray::getUnitOnComponent : Specified component id is out of range (" << i << ") compared with nb of actual components (" << (int) _info_on_compo.size(); + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } +} + +/*! + * 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) +{ + std::size_t p1=info.find_last_of('['); + std::size_t p2=info.find_last_of(']'); + if(p1==std::string::npos || p2==std::string::npos) + return info; + if(p1>p2) + return info; + if(p1==0) + return std::string(); + std::size_t p3=info.find_last_not_of(' ',p1-1); + 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) +{ + std::size_t p1=info.find_last_of('['); + std::size_t p2=info.find_last_of(']'); + if(p1==std::string::npos || p2==std::string::npos) + return std::string(); + if(p1>p2) + return std::string(); + return info.substr(p1+1,p2-p1-1); +} + +/*! + * This method put in info format the result of the merge of \a var and \a unit. + * The standard format for that is "var [unit]". + * Inversely you can retrieve the var part or the unit part of info string using resp. GetVarNameFromInfo and GetUnitFromInfo. + */ +std::string DataArray::BuildInfoFromVarAndUnit(const std::string& var, const std::string& unit) +{ + std::ostringstream oss; + oss << var << " [" << unit << "]"; + return oss.str(); +} + +/*! + * Returns a new DataArray 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] arrs - a sequence of arrays to include in the result array. All arrays must have the same type. + * \return DataArray * - the new instance of DataArray (that can be either DataArrayInt, DataArrayDouble, DataArrayChar). + * The caller is to delete this result array using decrRef() as it is no more + * needed. + * \throw If all arrays within \a arrs are NULL. + * \throw If all not null arrays in \a arrs have not the same type. + * \throw If getNumberOfComponents() of arrays within \a arrs. + */ +DataArray *DataArray::Aggregate(const std::vector<const DataArray *>& arrs) +{ + std::vector<const DataArray *> arr2; + for(std::vector<const DataArray *>::const_iterator it=arrs.begin();it!=arrs.end();it++) + if(*it) + arr2.push_back(*it); + if(arr2.empty()) + throw INTERP_KERNEL::Exception("DataArray::Aggregate : only null instance in input vector !"); + std::vector<const DataArrayDouble *> arrd; + std::vector<const DataArrayInt *> arri; + std::vector<const DataArrayChar *> arrc; + for(std::vector<const DataArray *>::const_iterator it=arr2.begin();it!=arr2.end();it++) + { + const DataArrayDouble *a=dynamic_cast<const DataArrayDouble *>(*it); + if(a) + { arrd.push_back(a); continue; } + const DataArrayInt *b=dynamic_cast<const DataArrayInt *>(*it); + if(b) + { arri.push_back(b); continue; } + const DataArrayChar *c=dynamic_cast<const DataArrayChar *>(*it); + if(c) + { arrc.push_back(c); continue; } + throw INTERP_KERNEL::Exception("DataArray::Aggregate : presence of not null instance in inuput that is not in [DataArrayDouble, DataArrayInt, DataArrayChar] !"); + } + if(arr2.size()==arrd.size()) + return DataArrayDouble::Aggregate(arrd); + if(arr2.size()==arri.size()) + return DataArrayInt::Aggregate(arri); + if(arr2.size()==arrc.size()) + return DataArrayChar::Aggregate(arrc); + throw INTERP_KERNEL::Exception("DataArray::Aggregate : all input arrays must have the same type !"); +} + +/*! + * 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 std::string& info) +{ + if(i<(int)_info_on_compo.size() && i>=0) + _info_on_compo[i]=info; + else + { + std::ostringstream oss; oss << "DataArray::setInfoOnComponent : Specified component id is out of range (" << i << ") compared with nb of actual components (" << (int) _info_on_compo.size(); + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } +} + +/*! + * 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 in \a this only if \a this is not allocated. + * The condition of number of components must not be changed. + * + * 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<std::string>& info) +{ + 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 std::string& msg) const +{ + if(getNumberOfTuples()!=nbOfTuples) + { + std::ostringstream oss; oss << msg << " : mismatch number of tuples : expected " << nbOfTuples << " having " << getNumberOfTuples() << " !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } +} + +void DataArray::checkNbOfComps(int nbOfCompo, const std::string& msg) const +{ + if(getNumberOfComponents()!=nbOfCompo) + { + std::ostringstream oss; oss << msg << " : mismatch number of components : expected " << nbOfCompo << " having " << getNumberOfComponents() << " !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } +} + +void DataArray::checkNbOfElems(std::size_t nbOfElems, const std::string& msg) const +{ + if(getNbOfElems()!=nbOfElems) + { + std::ostringstream oss; oss << msg << " : mismatch number of elems : Expected " << nbOfElems << " having " << getNbOfElems() << " !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } +} + +void DataArray::checkNbOfTuplesAndComp(const DataArray& other, const std::string& msg) const +{ + if(getNumberOfTuples()!=other.getNumberOfTuples()) + { + std::ostringstream oss; oss << msg << " : mismatch number of tuples : expected " << other.getNumberOfTuples() << " having " << getNumberOfTuples() << " !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + if(getNumberOfComponents()!=other.getNumberOfComponents()) + { + std::ostringstream oss; oss << msg << " : mismatch number of components : expected " << other.getNumberOfComponents() << " having " << getNumberOfComponents() << " !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } +} + +void DataArray::checkNbOfTuplesAndComp(int nbOfTuples, int nbOfCompo, const std::string& msg) const +{ + checkNbOfTuples(nbOfTuples,msg); + checkNbOfComps(nbOfCompo,msg); +} + +/*! + * Simply this method checks that \b value is in [0,\b ref). + */ +void DataArray::CheckValueInRange(int ref, int value, const std::string& msg) +{ + if(value<0 || value>=ref) + { + std::ostringstream oss; oss << "DataArray::CheckValueInRange : " << msg << " ! Expected in range [0," << ref << "[ having " << value << " !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } +} + +/*! + * This method checks that [\b start, \b end) is compliant with ref length \b value. + * typicaly start in [0,\b value) and end in [0,\b value). If value==start and start==end, it is supported. + */ +void DataArray::CheckValueInRangeEx(int value, int start, int end, const std::string& msg) +{ + if(start<0 || start>=value) + { + if(value!=start || end!=start) + { + 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::CheckValueInRangeEx : " << msg << " ! Expected end " << end << " of input range, in [0," << value << "] !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } +} + +void DataArray::CheckClosingParInRange(int ref, int value, const std::string& msg) +{ + if(value<0 || value>ref) + { + 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) +{ + 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<nbOfSlices-1) + stopSlice=start+minNbOfElemsPerSlice*step*(sliceId+1); + else + stopSlice=stop; +} + +int DataArray::GetNumberOfItemGivenBES(int begin, int end, int step, const std::string& msg) +{ + if(end<begin) + { + std::ostringstream oss; oss << msg << " : end before begin !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + if(end==begin) + return 0; + if(step<=0) + { + std::ostringstream oss; oss << msg << " : invalid step should be > 0 !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + return (end-1-begin)/step+1; +} + +int DataArray::GetNumberOfItemGivenBESRelative(int begin, int end, int step, const std::string& msg) +{ + if(step==0) + throw INTERP_KERNEL::Exception("DataArray::GetNumberOfItemGivenBES : step=0 is not allowed !"); + if(end<begin && step>0) + { + std::ostringstream oss; oss << msg << " : end before begin whereas step is positive !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + if(begin<end && step<0) + { + std::ostringstream oss; oss << msg << " : invalid step should be > 0 !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + if(begin!=end) + return (std::max(begin,end)-1-std::min(begin,end))/std::abs(step)+1; + else + return 0; +} + +int DataArray::GetPosOfItemGivenBESRelativeNoThrow(int value, int begin, int end, int step) +{ + if(step!=0) + { + if(step>0) + { + if(begin<=value && value<end) + { + if((value-begin)%step==0) + return (value-begin)/step; + else + return -1; + } + else + return -1; + } + else + { + if(begin>=value && value>end) + { + if((begin-value)%(-step)==0) + return (begin-value)/(-step); + else + return -1; + } + else + return -1; + } + } + else + 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; +} + +/*! + * 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 +{ + 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 +{ + if(!isAllocated()) + throw INTERP_KERNEL::Exception("DataArrayDouble::checkAllocated : Array is defined but not allocated ! Call alloc or setValues method first !"); +} + +/*! + * This method desallocated \a this without modification of informations relative to the components. + * After call of this method, DataArrayDouble::isAllocated will return false. + * If \a this is already not allocated, \a this is let unchanged. + */ +void DataArrayDouble::desallocate() +{ + _mem.destroy(); +} + +std::size_t DataArrayDouble::getHeapMemorySizeWithoutChildren() const +{ + std::size_t sz(_mem.getNbOfElemAllocated()); + sz*=sizeof(double); + return DataArray::getHeapMemorySizeWithoutChildren()+sz; +} + +/*! + * 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 +{ + if(isAllocated()) + { + if(getNbOfElems()==1) + { + return *getConstPointer(); + } + else + throw INTERP_KERNEL::Exception("DataArrayDouble::doubleValue : DataArrayDouble instance is allocated but number of elements is not equal to 1 !"); + } + else + throw INTERP_KERNEL::Exception("DataArrayDouble::doubleValue : DataArrayDouble instance is not allocated !"); +} + +/*! + * 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 +{ + checkAllocated(); + return getNumberOfTuples()==0; +} + +/*! + * 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 +{ + return new DataArrayDouble(*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 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 +{ + if(dCpy) + return deepCpy(); + else + { + incrRef(); + return const_cast<DataArrayDouble *>(this); + } +} + +/*! + * 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) +{ + other.checkAllocated(); + int nbOfTuples=other.getNumberOfTuples(); + int nbOfComp=other.getNumberOfComponents(); + allocIfNecessary(nbOfTuples,nbOfComp); + std::size_t nbOfElems=(std::size_t)nbOfTuples*nbOfComp; + double *pt=getPointer(); + const double *ptI=other.getConstPointer(); + for(std::size_t i=0;i<nbOfElems;i++) + pt[i]=ptI[i]; + copyStringInfoFrom(other); +} + +/*! + * This method reserve nbOfElems elements in memory ( nbOfElems*8 bytes ) \b without impacting the number of tuples in \a this. + * If \a this has already been allocated, this method checks that \a this has only one component. If not an INTERP_KERNEL::Exception will be thrown. + * If \a this has not already been allocated, number of components is set to one. + * This method allows to reduce number of reallocations on invokation of DataArrayDouble::pushBackSilent and DataArrayDouble::pushBackValsSilent on \a this. + * + * \sa DataArrayDouble::pack, DataArrayDouble::pushBackSilent, DataArrayDouble::pushBackValsSilent + */ +void DataArrayDouble::reserve(std::size_t nbOfElems) +{ + int nbCompo=getNumberOfComponents(); + if(nbCompo==1) + { + _mem.reserve(nbOfElems); + } + else if(nbCompo==0) + { + _mem.reserve(nbOfElems); + _info_on_compo.resize(1); + } + else + throw INTERP_KERNEL::Exception("DataArrayDouble::reserve : not available for DataArrayDouble with number of components different than 1 !"); +} + +/*! + * This method adds at the end of \a this the single value \a val. This method do \b not update its time label to avoid useless incrementation + * of counter. So the caller is expected to call TimeLabel::declareAsNew on \a this at the end of the push session. + * + * \param [in] val the value to be added in \a this + * \throw If \a this has already been allocated with number of components different from one. + * \sa DataArrayDouble::pushBackValsSilent + */ +void DataArrayDouble::pushBackSilent(double val) +{ + int nbCompo=getNumberOfComponents(); + if(nbCompo==1) + _mem.pushBack(val); + else if(nbCompo==0) + { + _info_on_compo.resize(1); + _mem.pushBack(val); + } + else + throw INTERP_KERNEL::Exception("DataArrayDouble::pushBackSilent : not available for DataArrayDouble with number of components different than 1 !"); +} + +/*! + * This method adds at the end of \a this a serie of values [\c valsBg,\c valsEnd). This method do \b not update its time label to avoid useless incrementation + * of counter. So the caller is expected to call TimeLabel::declareAsNew on \a this at the end of the push session. + * + * \param [in] valsBg - an array of values to push at the end of \c this. + * \param [in] valsEnd - specifies the end of the array \a valsBg, so that + * the last value of \a valsBg is \a valsEnd[ -1 ]. + * \throw If \a this has already been allocated with number of components different from one. + * \sa DataArrayDouble::pushBackSilent + */ +void DataArrayDouble::pushBackValsSilent(const double *valsBg, const double *valsEnd) +{ + int nbCompo=getNumberOfComponents(); + if(nbCompo==1) + _mem.insertAtTheEnd(valsBg,valsEnd); + else if(nbCompo==0) + { + _info_on_compo.resize(1); + _mem.insertAtTheEnd(valsBg,valsEnd); + } + else + throw INTERP_KERNEL::Exception("DataArrayDouble::pushBackValsSilent : not available for DataArrayDouble with number of components different than 1 !"); +} + +/*! + * This method returns silently ( without updating time label in \a this ) the last value, if any and suppress it. + * \throw If \a this is already empty. + * \throw If \a this has number of components different from one. + */ +double DataArrayDouble::popBackSilent() +{ + if(getNumberOfComponents()==1) + return _mem.popBack(); + else + throw INTERP_KERNEL::Exception("DataArrayDouble::popBackSilent : not available for DataArrayDouble with number of components different than 1 !"); +} + +/*! + * This method \b do \b not modify content of \a this. It only modify its memory footprint if the allocated memory is to high regarding real data to store. + * + * \sa DataArrayDouble::getHeapMemorySizeWithoutChildren, DataArrayDouble::reserve + */ +void DataArrayDouble::pack() const +{ + _mem.pack(); +} + +/*! + * Allocates the raw data in memory. If exactly same memory as needed already + * allocated, it is not re-allocated. + * \param [in] nbOfTuple - number of tuples of data to allocate. + * \param [in] nbOfCompo - number of components of data to allocate. + * \throw If \a nbOfTuple < 0 or \a nbOfCompo < 0. + */ +void DataArrayDouble::allocIfNecessary(int nbOfTuple, int nbOfCompo) +{ + if(isAllocated()) + { + if(nbOfTuple!=getNumberOfTuples() || nbOfCompo!=getNumberOfComponents()) + alloc(nbOfTuple,nbOfCompo); + } + else + alloc(nbOfTuple,nbOfCompo); +} + +/*! + * Allocates the raw data in memory. If the memory was already allocated, then it is + * freed and re-allocated. See an example of this method use + * \ref MEDCouplingArraySteps1WC "here". + * \param [in] nbOfTuple - number of tuples of data to allocate. + * \param [in] nbOfCompo - number of components of data to allocate. + * \throw If \a nbOfTuple < 0 or \a nbOfCompo < 0. + */ +void DataArrayDouble::alloc(int nbOfTuple, int nbOfCompo) +{ + if(nbOfTuple<0 || nbOfCompo<0) + throw INTERP_KERNEL::Exception("DataArrayDouble::alloc : request for negative length of data !"); + _info_on_compo.resize(nbOfCompo); + _mem.alloc(nbOfCompo*(std::size_t)nbOfTuple); + 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 DataArrayDouble::fillWithZero() +{ + 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 DataArrayDouble::fillWithValue(double val) +{ + checkAllocated(); + _mem.fillWithValue(val); + declareAsNew(); +} + +/*! + * Set all values in \a this array so that the i-th element equals to \a init + i + * (i starts from zero). To know more on filling arrays see \ref MEDCouplingArrayFill. + * \param [in] init - value to assign to the first element of array. + * \throw If \a this->getNumberOfComponents() != 1 + * \throw If \a this is not allocated. + */ +void DataArrayDouble::iota(double init) +{ + checkAllocated(); + if(getNumberOfComponents()!=1) + throw INTERP_KERNEL::Exception("DataArrayDouble::iota : works only for arrays with only one component, you can call 'rearrange' method before !"); + double *ptr=getPointer(); + int ntuples=getNumberOfTuples(); + for(int i=0;i<ntuples;i++) + ptr[i]=init+double(i); + 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 +{ + checkAllocated(); + if(getNumberOfComponents()!=1) + throw INTERP_KERNEL::Exception("DataArrayDouble::isUniform : must be applied on DataArrayDouble with only one component, you can call 'rearrange' method before !"); + int nbOfTuples=getNumberOfTuples(); + const double *w=getConstPointer(); + const double *end2=w+nbOfTuples; + const double vmin=val-eps; + const double vmax=val+eps; + for(;w!=end2;w++) + if(*w<vmin || *w>vmax) + return false; + 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) +{ + 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() +{ + checkAllocated(); + _mem.reverse(getNumberOfComponents()); + declareAsNew(); +} + +/*! + * 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 +{ + if(!isMonotonic(increasing,eps)) + { + if (increasing) + throw INTERP_KERNEL::Exception("DataArrayDouble::checkMonotonic : 'this' is not INCREASING monotonic !"); + else + throw INTERP_KERNEL::Exception("DataArrayDouble::checkMonotonic : 'this' is not DECREASING monotonic !"); + } +} + +/*! + * 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 +{ + checkAllocated(); + if(getNumberOfComponents()!=1) + throw INTERP_KERNEL::Exception("DataArrayDouble::isMonotonic : only supported with 'this' array with ONE component !"); + int nbOfElements=getNumberOfTuples(); + const double *ptr=getConstPointer(); + if(nbOfElements==0) + return true; + double ref=ptr[0]; + double absEps=fabs(eps); + if(increasing) + { + for(int i=1;i<nbOfElements;i++) + { + if(ptr[i]<(ref+absEps)) + return false; + ref=ptr[i]; + } + return true; + } + else + { + for(int i=1;i<nbOfElements;i++) + { + if(ptr[i]>(ref-absEps)) + return false; + ref=ptr[i]; + } + return true; + } +} + +/*! + * Returns a textual and human readable representation of \a this instance of + * DataArrayDouble. This text is shown when a DataArrayDouble is printed in Python. + * \return std::string - text describing \a this DataArrayDouble. + * + * \sa reprNotTooLong, reprZip + */ +std::string DataArrayDouble::repr() const +{ + std::ostringstream ret; + reprStream(ret); + return ret.str(); +} + +std::string DataArrayDouble::reprZip() const +{ + std::ostringstream ret; + reprZipStream(ret); + return ret.str(); +} + +/*! + * This method is close to repr method except that when \a this has more than 1000 tuples, all tuples are not + * printed out to avoid to consume too much space in interpretor. + * \sa repr + */ +std::string DataArrayDouble::reprNotTooLong() const +{ + std::ostringstream ret; + reprNotTooLongStream(ret); + return ret.str(); +} + +void DataArrayDouble::writeVTK(std::ostream& ofs, int indent, const std::string& nameInFile, DataArrayByte *byteArr) const +{ + static const char SPACE[4]={' ',' ',' ',' '}; + checkAllocated(); + std::string idt(indent,' '); + ofs.precision(17); + ofs << idt << "<DataArray type=\"Float32\" Name=\"" << nameInFile << "\" NumberOfComponents=\"" << getNumberOfComponents() << "\""; + // + bool areAllEmpty(true); + for(std::vector<std::string>::const_iterator it=_info_on_compo.begin();it!=_info_on_compo.end();it++) + if(!(*it).empty()) + areAllEmpty=false; + if(!areAllEmpty) + for(std::size_t i=0;i<_info_on_compo.size();i++) + ofs << " ComponentName" << i << "=\"" << _info_on_compo[i] << "\""; + // + if(byteArr) + { + ofs << " format=\"appended\" offset=\"" << byteArr->getNumberOfTuples() << "\">"; + INTERP_KERNEL::AutoPtr<float> tmp(new float[getNbOfElems()]); + float *pt(tmp); + // to make Visual C++ happy : instead of std::copy(begin(),end(),(float *)tmp); + for(const double *src=begin();src!=end();src++,pt++) + *pt=float(*src); + const char *data(reinterpret_cast<const char *>((float *)tmp)); + std::size_t sz(getNbOfElems()*sizeof(float)); + byteArr->insertAtTheEnd(data,data+sz); + byteArr->insertAtTheEnd(SPACE,SPACE+4); + } + else + { + ofs << " RangeMin=\"" << getMinValueInArray() << "\" RangeMax=\"" << getMaxValueInArray() << "\" format=\"ascii\">\n" << idt; + std::copy(begin(),end(),std::ostream_iterator<double>(ofs," ")); + } + ofs << std::endl << idt << "</DataArray>\n"; +} + +void DataArrayDouble::reprStream(std::ostream& stream) const +{ + stream << "Name of double array : \"" << _name << "\"\n"; + reprWithoutNameStream(stream); +} + +void DataArrayDouble::reprZipStream(std::ostream& stream) const +{ + stream << "Name of double array : \"" << _name << "\"\n"; + reprZipWithoutNameStream(stream); +} + +void DataArrayDouble::reprNotTooLongStream(std::ostream& stream) const +{ + stream << "Name of double array : \"" << _name << "\"\n"; + reprNotTooLongWithoutNameStream(stream); +} + +void DataArrayDouble::reprWithoutNameStream(std::ostream& stream) const +{ + DataArray::reprWithoutNameStream(stream); + stream.precision(17); + _mem.repr(getNumberOfComponents(),stream); +} + +void DataArrayDouble::reprZipWithoutNameStream(std::ostream& stream) const +{ + DataArray::reprWithoutNameStream(stream); + stream.precision(17); + _mem.reprZip(getNumberOfComponents(),stream); +} + +void DataArrayDouble::reprNotTooLongWithoutNameStream(std::ostream& stream) const +{ + DataArray::reprWithoutNameStream(stream); + stream.precision(17); + _mem.reprNotTooLong(getNumberOfComponents(),stream); +} + +void DataArrayDouble::reprCppStream(const std::string& varName, std::ostream& stream) const +{ + int nbTuples=getNumberOfTuples(),nbComp=getNumberOfComponents(); + const double *data=getConstPointer(); + stream.precision(17); + stream << "DataArrayDouble *" << varName << "=DataArrayDouble::New();" << std::endl; + if(nbTuples*nbComp>=1) + { + stream << "const double " << varName << "Data[" << nbTuples*nbComp << "]={"; + std::copy(data,data+nbTuples*nbComp-1,std::ostream_iterator<double>(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 DataArrayDouble::reprQuickOverview(std::ostream& stream) const +{ + 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 +{ + 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;i<nbOfTuples && isFinished;i++) + { + if(nbOfCompo>1) + { + oss2 << "("; + for(int j=0;j<nbOfCompo;j++,data++) + { + oss2 << *data; + if(j!=nbOfCompo-1) oss2 << ", "; + } + oss2 << ")"; + } + else + oss2 << *data++; + if(i!=nbOfTuples-1) oss2 << ", "; + std::string oss3Str(oss2.str()); + if(oss3Str.length()<maxNbOfByteInRepr) + oss2Str=oss3Str; + else + isFinished=false; + } + stream << oss2Str; + if(!isFinished) + stream << "... "; + stream << "]"; +} + +/*! + * Equivalent to DataArrayDouble::isEqual except that if false the reason of + * mismatch is given. + * + * \param [in] other the instance to be compared with \a this + * \param [in] prec the precision to compare numeric data of the arrays. + * \param [out] reason In case of inequality returns the reason. + * \sa DataArrayDouble::isEqual + */ +bool DataArrayDouble::isEqualIfNotWhy(const DataArrayDouble& other, double prec, std::string& reason) const +{ + if(!areInfoEqualsIfNotWhy(other,reason)) + return false; + return _mem.isEqual(other._mem,prec,reason); +} + +/*! + * Checks if \a this and another DataArrayDouble are fully equal. For more info see + * \ref MEDCouplingArrayBasicsCompare. + * \param [in] other - an instance of DataArrayDouble to compare with \a this one. + * \param [in] prec - precision value to compare numeric data of the arrays. + * \return bool - \a true if the two arrays are equal, \a false else. + */ +bool DataArrayDouble::isEqual(const DataArrayDouble& other, double prec) const +{ + std::string tmp; + return isEqualIfNotWhy(other,prec,tmp); +} + +/*! + * Checks if values of \a this and another DataArrayDouble are equal. For more info see + * \ref MEDCouplingArrayBasicsCompare. + * \param [in] other - an instance of DataArrayDouble to compare with \a this one. + * \param [in] prec - precision value to compare numeric data of the arrays. + * \return bool - \a true if the values of two arrays are equal, \a false else. + */ +bool DataArrayDouble::isEqualWithoutConsideringStr(const DataArrayDouble& other, double prec) const +{ + std::string tmp; + return _mem.isEqual(other._mem,prec,tmp); +} + +/*! + * 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. + * \throw If \a nbOfTuples is negative. + */ +void DataArrayDouble::reAlloc(int nbOfTuples) +{ + if(nbOfTuples<0) + throw INTERP_KERNEL::Exception("DataArrayDouble::reAlloc : input new number of tuples should be >=0 !"); + 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 DataArrayInt. + */ +DataArrayInt *DataArrayDouble::convertToIntArr() const +{ + DataArrayInt *ret=DataArrayInt::New(); + ret->alloc(getNumberOfTuples(),getNumberOfComponents()); + int *dest=ret->getPointer(); + // to make Visual C++ happy : instead of std::size_t nbOfVals=getNbOfElems(); std::copy(src,src+nbOfVals,dest); + for(const double *src=begin();src!=end();src++,dest++) + *dest=(int)*src; + ret->copyStringInfoFrom(*this); + 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 +{ + 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,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 +{ + if(_mem.isNull()) + throw INTERP_KERNEL::Exception("DataArrayDouble::toNoInterlace : Not defined array !"); + double *tab=_mem.toNoInterlace(getNumberOfComponents()); + DataArrayDouble *ret=DataArrayDouble::New(); + ret->useArray(tab,true,C_DEALLOC,getNumberOfTuples(),getNumberOfComponents()); + 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 \c this one. + * If a permutation reduction is needed, substr() or selectByTupleId() should be used. + * For more info on renumbering see \ref numbering. + * \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) +{ + checkAllocated(); + int nbTuples=getNumberOfTuples(); + int nbOfCompo=getNumberOfComponents(); + double *tmp=new double[nbTuples*nbOfCompo]; + const double *iptr=getConstPointer(); + for(int i=0;i<nbTuples;i++) + { + int v=old2New[i]; + if(v>=0 && v<nbTuples) + std::copy(iptr+nbOfCompo*i,iptr+nbOfCompo*(i+1),tmp+nbOfCompo*v); + else + { + std::ostringstream oss; oss << "DataArrayDouble::renumberInPlace : At place #" << i << " value is " << v << " ! Should be in [0," << nbTuples << ") !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + } + std::copy(tmp,tmp+nbTuples*nbOfCompo,getPointer()); + delete [] tmp; + declareAsNew(); +} + +/*! + * 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 \c this one. + * For more info on renumbering see \ref numbering. + * \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) +{ + checkAllocated(); + int nbTuples=getNumberOfTuples(); + int nbOfCompo=getNumberOfComponents(); + double *tmp=new double[nbTuples*nbOfCompo]; + const double *iptr=getConstPointer(); + for(int i=0;i<nbTuples;i++) + { + int v=new2Old[i]; + if(v>=0 && v<nbTuples) + std::copy(iptr+nbOfCompo*v,iptr+nbOfCompo*(v+1),tmp+nbOfCompo*i); + else + { + std::ostringstream oss; oss << "DataArrayDouble::renumberInPlaceR : At place #" << i << " value is " << v << " ! Should be in [0," << nbTuples << ") !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + } + std::copy(tmp,tmp+nbTuples*nbOfCompo,getPointer()); + delete [] tmp; + declareAsNew(); +} + +/*! + * 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 \c this one. + * If a permutation reduction is needed, renumberAndReduce() should be used. + * For more info on renumbering see \ref numbering. + * \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 +{ + checkAllocated(); + int nbTuples=getNumberOfTuples(); + int nbOfCompo=getNumberOfComponents(); + MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New(); + ret->alloc(nbTuples,nbOfCompo); + ret->copyStringInfoFrom(*this); + const double *iptr=getConstPointer(); + double *optr=ret->getPointer(); + for(int i=0;i<nbTuples;i++) + std::copy(iptr+nbOfCompo*i,iptr+nbOfCompo*(i+1),optr+nbOfCompo*old2New[i]); + ret->copyStringInfoFrom(*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 \c this one. + * If a permutation reduction is needed, substr() or selectByTupleId() should be used. + * For more info on renumbering see \ref numbering. + * \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 +{ + checkAllocated(); + int nbTuples=getNumberOfTuples(); + int nbOfCompo=getNumberOfComponents(); + MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New(); + ret->alloc(nbTuples,nbOfCompo); + ret->copyStringInfoFrom(*this); + const double *iptr=getConstPointer(); + double *optr=ret->getPointer(); + for(int i=0;i<nbTuples;i++) + std::copy(iptr+nbOfCompo*new2Old[i],iptr+nbOfCompo*(new2Old[i]+1),optr+i*nbOfCompo); + ret->copyStringInfoFrom(*this); + return ret.retn(); +} + +/*! + * 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 numbering. + * \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 +{ + checkAllocated(); + int nbTuples=getNumberOfTuples(); + int nbOfCompo=getNumberOfComponents(); + MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New(); + ret->alloc(newNbOfTuple,nbOfCompo); + const double *iptr=getConstPointer(); + double *optr=ret->getPointer(); + for(int i=0;i<nbTuples;i++) + { + int w=old2New[i]; + if(w>=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 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 numbering. + * \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 +{ + checkAllocated(); + MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New(); + int nbComp=getNumberOfComponents(); + ret->alloc((int)std::distance(new2OldBg,new2OldEnd),nbComp); + ret->copyStringInfoFrom(*this); + double *pt=ret->getPointer(); + const double *srcPt=getConstPointer(); + int i=0; + 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.retn(); +} + +/*! + * 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 numbering. + * \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 +{ + checkAllocated(); + MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New(); + int nbComp=getNumberOfComponents(); + int oldNbOfTuples=getNumberOfTuples(); + ret->alloc((int)std::distance(new2OldBg,new2OldEnd),nbComp); + ret->copyStringInfoFrom(*this); + double *pt=ret->getPointer(); + const double *srcPt=getConstPointer(); + int i=0; + for(const int *w=new2OldBg;w!=new2OldEnd;w++,i++) + if(*w>=0 && *w<oldNbOfTuples) + std::copy(srcPt+(*w)*nbComp,srcPt+((*w)+1)*nbComp,pt+i*nbComp); + else + throw INTERP_KERNEL::Exception("DataArrayDouble::selectByTupleIdSafe : some ids has been detected to be out of [0,this->getNumberOfTuples) !"); + ret->copyStringInfoFrom(*this); + return ret.retn(); +} + +/*! + * 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 numbering. + * \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 +{ + checkAllocated(); + MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New(); + int nbComp=getNumberOfComponents(); + 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;i<newNbOfTuples;i++,srcPt+=step*nbComp) + std::copy(srcPt,srcPt+nbComp,pt+i*nbComp); + ret->copyStringInfoFrom(*this); + return ret.retn(); +} + +/*! + * 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 numbering. + * \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. + */ +DataArray *DataArrayDouble::selectByTupleRanges(const std::vector<std::pair<int,int> >& ranges) const +{ + checkAllocated(); + int nbOfComp=getNumberOfComponents(); + int nbOfTuplesThis=getNumberOfTuples(); + if(ranges.empty()) + { + DataArrayDouble *ret=DataArrayDouble::New(); + ret->alloc(0,nbOfComp); + ret->copyStringInfoFrom(*this); + return ret; + } + int ref=ranges.front().first; + int nbOfTuples=0; + bool isIncreasing=true; + for(std::vector<std::pair<int,int> >::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 << "DataArrayDouble::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 << "DataArrayDouble::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<DataArrayDouble> ret=DataArrayDouble::New(); + ret->alloc(nbOfTuples,nbOfComp); + ret->copyStringInfoFrom(*this); + const double *src=getConstPointer(); + double *work=ret->getPointer(); + for(std::vector<std::pair<int,int> >::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 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 +{ + checkAllocated(); + int nbt=getNumberOfTuples(); + if(tupleIdBg<0) + throw INTERP_KERNEL::Exception("DataArrayDouble::substr : The tupleIdBg parameter must be greater than 0 !"); + if(tupleIdBg>nbt) + throw INTERP_KERNEL::Exception("DataArrayDouble::substr : The tupleIdBg parameter is greater than number of tuples !"); + int trueEnd=tupleIdEnd; + if(tupleIdEnd!=-1) + { + if(tupleIdEnd>nbt) + throw INTERP_KERNEL::Exception("DataArrayDouble::substr : The tupleIdBg parameter is greater or equal than number of tuples !"); + } + else + trueEnd=nbt; + int nbComp=getNumberOfComponents(); + MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New(); + 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. + */ +DataArrayDouble *DataArrayDouble::changeNbOfComponents(int newNbOfComp, double dftValue) const +{ + checkAllocated(); + MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New(); + ret->alloc(getNumberOfTuples(),newNbOfComp); + const double *oldc=getConstPointer(); + double *nc=ret->getPointer(); + int nbOfTuples=getNumberOfTuples(); + int oldNbOfComp=getNumberOfComponents(); + int dim=std::min(oldNbOfComp,newNbOfComp); + for(int i=0;i<nbOfTuples;i++) + { + int j=0; + for(;j<dim;j++) + nc[newNbOfComp*i+j]=oldc[i*oldNbOfComp+j]; + for(;j<newNbOfComp;j++) + nc[newNbOfComp*i+j]=dftValue; + } + ret->setName(getName()); + for(int i=0;i<dim;i++) + ret->setInfoOnComponent(i,getInfoOnComponent(i)); + ret->setName(getName()); + return ret.retn(); +} + +/*! + * 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) +{ + checkAllocated(); + 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 !"); + if(nbOfElems/newNbOfCompo>(std::size_t)std::numeric_limits<int>::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(); +} + +/*! + * 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() +{ + checkAllocated(); + int nbOfTuples=getNumberOfTuples(); + rearrange(nbOfTuples); +} + +/*! + * 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(). + * + * \if ENABLE_EXAMPLES + * \ref py_mcdataarraydouble_KeepSelectedComponents "Here is a Python example". + * \endif + */ +DataArrayDouble *DataArrayDouble::keepSelectedComponents(const std::vector<int>& compoIds) const +{ + checkAllocated(); + MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret(DataArrayDouble::New()); + std::size_t newNbOfCompo=compoIds.size(); + int oldNbOfCompo=getNumberOfComponents(); + for(std::vector<int>::const_iterator it=compoIds.begin();it!=compoIds.end();it++) + if((*it)<0 || (*it)>=oldNbOfCompo) + { + std::ostringstream oss; oss << "DataArrayDouble::keepSelectedComponents : invalid requested component : " << *it << " whereas it should be in [0," << oldNbOfCompo << ") !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + int nbOfTuples=getNumberOfTuples(); + ret->alloc(nbOfTuples,(int)newNbOfCompo); + ret->copyPartOfStringInfoFrom(*this,compoIds); + const double *oldc=getConstPointer(); + double *nc=ret->getPointer(); + for(int i=0;i<nbOfTuples;i++) + for(std::size_t j=0;j<newNbOfCompo;j++,nc++) + *nc=oldc[i*oldNbOfCompo+compoIds[j]]; + return ret.retn(); +} + +/*! + * 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. + * + * \if ENABLE_EXAMPLES + * \ref cpp_mcdataarraydouble_meldwith "Here is a C++ example". + * + * \ref py_mcdataarraydouble_meldwith "Here is a Python example". + * \endif + */ +void DataArrayDouble::meldWith(const DataArrayDouble *other) +{ + checkAllocated(); + other->checkAllocated(); + int nbOfTuples=getNumberOfTuples(); + if(nbOfTuples!=other->getNumberOfTuples()) + throw INTERP_KERNEL::Exception("DataArrayDouble::meldWith : mismatch of number of tuples !"); + int nbOfComp1=getNumberOfComponents(); + int nbOfComp2=other->getNumberOfComponents(); + double *newArr=(double *)malloc((nbOfTuples*(nbOfComp1+nbOfComp2))*sizeof(double)); + double *w=newArr; + const double *inp1=getConstPointer(); + const double *inp2=other->getConstPointer(); + for(int i=0;i<nbOfTuples;i++,inp1+=nbOfComp1,inp2+=nbOfComp2) + { + w=std::copy(inp1,inp1+nbOfComp1,w); + w=std::copy(inp2,inp2+nbOfComp2,w); + } + useArray(newArr,true,C_DEALLOC,nbOfTuples,nbOfComp1+nbOfComp2); + std::vector<int> compIds(nbOfComp2); + for(int i=0;i<nbOfComp2;i++) + compIds[i]=nbOfComp1+i; + copyPartOfStringInfoFrom2(compIds,*other); +} + +/*! + * This method checks that all tuples in \a other are in \a this. + * If true, the output param \a tupleIds contains the tuples ids of \a this that correspond to tupes in \a this. + * For each i in [ 0 , other->getNumberOfTuples() ) tuple #i in \a other is equal ( regarding input precision \a prec ) to tuple tupleIds[i] in \a this. + * + * \param [in] other - the array having the same number of components than \a this. + * \param [out] tupleIds - the tuple ids containing the same number of tuples than \a other has. + * \sa DataArrayDouble::findCommonTuples + */ +bool DataArrayDouble::areIncludedInMe(const DataArrayDouble *other, double prec, DataArrayInt *&tupleIds) const +{ + if(!other) + throw INTERP_KERNEL::Exception("DataArrayDouble::areIncludedInMe : input array is NULL !"); + checkAllocated(); other->checkAllocated(); + if(getNumberOfComponents()!=other->getNumberOfComponents()) + throw INTERP_KERNEL::Exception("DataArrayDouble::areIncludedInMe : the number of components does not match !"); + MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> a=DataArrayDouble::Aggregate(this,other); + DataArrayInt *c=0,*ci=0; + a->findCommonTuples(prec,getNumberOfTuples(),c,ci); + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> cSafe(c),ciSafe(ci); + int newNbOfTuples=-1; + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ids=DataArrayInt::BuildOld2NewArrayFromSurjectiveFormat2(a->getNumberOfTuples(),c->begin(),ci->begin(),ci->end(),newNbOfTuples); + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret1=ids->selectByTupleId2(getNumberOfTuples(),a->getNumberOfTuples(),1); + tupleIds=ret1.retn(); + return newNbOfTuples==getNumberOfTuples(); +} + +/*! + * Searches for tuples coincident within \a prec tolerance. Each tuple is considered + * as coordinates of a point in getNumberOfComponents()-dimensional space. The + * distance separating two points is computed with the infinite norm. + * + * 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,4]. + * + * \if ENABLE_EXAMPLES + * \ref cpp_mcdataarraydouble_findcommontuples "Here is a C++ example". + * + * \ref py_mcdataarraydouble_findcommontuples "Here is a Python example". + * \endif + * \sa DataArrayInt::BuildOld2NewArrayFromSurjectiveFormat2(), DataArrayDouble::areIncludedInMe + */ +void DataArrayDouble::findCommonTuples(double prec, int limitTupleId, DataArrayInt *&comm, DataArrayInt *&commIndex) const +{ + checkAllocated(); + int nbOfCompo=getNumberOfComponents(); + if ((nbOfCompo<1) || (nbOfCompo>4)) //test before work + throw INTERP_KERNEL::Exception("DataArrayDouble::findCommonTuples : Unexpected spacedim of coords. Must be 1, 2, 3 or 4."); + + int nbOfTuples=getNumberOfTuples(); + // + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> c(DataArrayInt::New()),cI(DataArrayInt::New()); c->alloc(0,1); cI->pushBackSilent(0); + switch(nbOfCompo) + { + case 4: + findCommonTuplesAlg<4>(begin(),nbOfTuples,limitTupleId,prec,c,cI); + break; + case 3: + findCommonTuplesAlg<3>(begin(),nbOfTuples,limitTupleId,prec,c,cI); + break; + case 2: + findCommonTuplesAlg<2>(begin(),nbOfTuples,limitTupleId,prec,c,cI); + break; + case 1: + findCommonTuplesAlg<1>(begin(),nbOfTuples,limitTupleId,prec,c,cI); + break; + default: + throw INTERP_KERNEL::Exception("DataArrayDouble::findCommonTuples : nb of components managed are 1,2,3 and 4 ! not implemented for other number of components !"); + } + comm=c.retn(); + commIndex=cI.retn(); +} + +/*! + * + * \param [in] nbTimes specifies the nb of times each tuples in \a this will be duplicated contiguouly in returned DataArrayDouble instance. + * \a nbTimes should be at least equal to 1. + * \return a newly allocated DataArrayDouble having one component and number of tuples equal to \a nbTimes * \c this->getNumberOfTuples. + * \throw if \a this is not allocated or if \a this has not number of components set to one or if \a nbTimes is lower than 1. + */ +DataArrayDouble *DataArrayDouble::duplicateEachTupleNTimes(int nbTimes) const +{ + checkAllocated(); + if(getNumberOfComponents()!=1) + throw INTERP_KERNEL::Exception("DataArrayDouble::duplicateEachTupleNTimes : this should have only one component !"); + if(nbTimes<1) + throw INTERP_KERNEL::Exception("DataArrayDouble::duplicateEachTupleNTimes : nb times should be >= 1 !"); + int nbTuples=getNumberOfTuples(); + const double *inPtr=getConstPointer(); + MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New(); ret->alloc(nbTimes*nbTuples,1); + double *retPtr=ret->getPointer(); + for(int i=0;i<nbTuples;i++,inPtr++) + { + double val=*inPtr; + for(int j=0;j<nbTimes;j++,retPtr++) + *retPtr=val; + } + ret->copyStringInfoFrom(*this); + return ret.retn(); +} + +/*! + * 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 [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 + */ +double DataArrayDouble::minimalDistanceTo(const DataArrayDouble *other, int& thisTupleId, int& otherTupleId) const +{ + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> 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<double>::max(); + for(int i=0;i<otherNbTuples;i++,part1Pt++,otherPt+=nbOfCompo) + { + double tmp(0.); + for(int j=0;j<nbOfCompo;j++) + tmp+=(otherPt[j]-thisPt[nbOfCompo*(*part1Pt)+j])*(otherPt[j]-thisPt[nbOfCompo*(*part1Pt)+j]); + if(tmp<ret) + { ret=tmp; thisTupleId=*part1Pt; otherTupleId=i; } + } + return sqrt(ret); +} + +/*! + * This methods returns for each tuple in \a other which tuple in \a this is the closest. + * 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. + * + * \return a newly allocated (new object to be dealt by the caller) DataArrayInt having \c other->getNumberOfTuples() tuples and one components. + * \sa DataArrayDouble::minimalDistanceTo + */ +DataArrayInt *DataArrayDouble::findClosestTupleId(const DataArrayDouble *other) const +{ + 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<DataArrayInt> 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(); +} + +/*! + * This method expects that \a this and \a otherBBoxFrmt arrays are bounding box arrays ( as the output of MEDCouplingPointSet::getBoundingBoxForBBTree method ). + * This method will return a DataArrayInt array having the same number of tuples than \a this. This returned array tells for each cell in \a this + * how many bounding boxes in \a otherBBoxFrmt. + * So, this method expects that \a this and \a otherBBoxFrmt have the same number of components. + * + * \param [in] otherBBoxFrmt - It is an array . + * \param [in] eps - the absolute precision of the detection. when eps < 0 the bboxes are enlarged so more interactions are detected. Inversely when > 0 the bboxes are stretched. + * \sa MEDCouplingPointSet::getBoundingBoxForBBTree + * \throw If \a this and \a otherBBoxFrmt have not the same number of components. + * \throw If \a this and \a otherBBoxFrmt number of components is not even (BBox format). + */ +DataArrayInt *DataArrayDouble::computeNbOfInteractionsWith(const DataArrayDouble *otherBBoxFrmt, double eps) const +{ + if(!otherBBoxFrmt) + throw INTERP_KERNEL::Exception("DataArrayDouble::computeNbOfInteractionsWith : input array is NULL !"); + if(!isAllocated() || !otherBBoxFrmt->isAllocated()) + throw INTERP_KERNEL::Exception("DataArrayDouble::computeNbOfInteractionsWith : this and input array must be allocated !"); + int nbOfComp(getNumberOfComponents()),nbOfTuples(getNumberOfTuples()); + if(nbOfComp!=otherBBoxFrmt->getNumberOfComponents()) + { + std::ostringstream oss; oss << "DataArrayDouble::computeNbOfInteractionsWith : this number of components (" << nbOfComp << ") must be equal to the number of components of input array (" << otherBBoxFrmt->getNumberOfComponents() << ") !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + if(nbOfComp%2!=0) + { + std::ostringstream oss; oss << "DataArrayDouble::computeNbOfInteractionsWith : Number of components (" << nbOfComp << ") is not even ! It should be to be compatible with bbox format !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(nbOfTuples,1); + const double *thisBBPtr(begin()); + int *retPtr(ret->getPointer()); + switch(nbOfComp/2) + { + case 3: + { + BBTree<3,int> bbt(otherBBoxFrmt->begin(),0,0,otherBBoxFrmt->getNumberOfTuples(),eps); + for(int i=0;i<nbOfTuples;i++,retPtr++,thisBBPtr+=nbOfComp) + *retPtr=bbt.getNbOfIntersectingElems(thisBBPtr); + break; + } + case 2: + { + BBTree<2,int> bbt(otherBBoxFrmt->begin(),0,0,otherBBoxFrmt->getNumberOfTuples(),eps); + for(int i=0;i<nbOfTuples;i++,retPtr++,thisBBPtr+=nbOfComp) + *retPtr=bbt.getNbOfIntersectingElems(thisBBPtr); + break; + } + case 1: + { + BBTree<1,int> bbt(otherBBoxFrmt->begin(),0,0,otherBBoxFrmt->getNumberOfTuples(),eps); + for(int i=0;i<nbOfTuples;i++,retPtr++,thisBBPtr+=nbOfComp) + *retPtr=bbt.getNbOfIntersectingElems(thisBBPtr); + break; + } + default: + throw INTERP_KERNEL::Exception("DataArrayDouble::computeNbOfInteractionsWith : space dimension supported are [1,2,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,4]. + * + * \if ENABLE_EXAMPLES + * \ref py_mcdataarraydouble_getdifferentvalues "Here is a Python example". + * \endif + */ +DataArrayDouble *DataArrayDouble::getDifferentValues(double prec, int limitTupleId) const +{ + checkAllocated(); + DataArrayInt *c0=0,*cI0=0; + findCommonTuples(prec,limitTupleId,c0,cI0); + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> c(c0),cI(cI0); + int newNbOfTuples=-1; + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> 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(). + * + * \if ENABLE_EXAMPLES + * \ref py_mcdataarraydouble_setselectedcomponents "Here is a Python example". + * \endif + */ +void DataArrayDouble::setSelectedComponents(const DataArrayDouble *a, const std::vector<int>& compoIds) +{ + 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=std::min(getNumberOfTuples(),a->getNumberOfTuples()); + const double *ac=a->getConstPointer(); + double *nc=getPointer(); + for(int i=0;i<nbOfTuples;i++) + for(std::size_t j=0;j<partOfCompoSz;j++,ac++) + nc[nbOfCompo*i+compoIds[j]]=*ac; +} + +/*! + * Copy all values from another DataArrayDouble into specified tuples and components + * of \a this array. Textual data is not copied. + * The tree parameters defining set of indices of tuples and components are similar to + * the tree parameters of the Python function \c range(\c start,\c stop,\c step). + * \param [in] a - the array to copy values from. + * \param [in] bgTuples - index of the first tuple of \a this array to assign values to. + * \param [in] endTuples - index of the tuple before which the tuples to assign to + * are located. + * \param [in] stepTuples - index increment to get index of the next tuple to assign to. + * \param [in] bgComp - index of the first component of \a this array to assign values 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 - if \a true (by default), then \a a->getNumberOfComponents() + * 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)). + * + * \if ENABLE_EXAMPLES + * \ref py_mcdataarraydouble_setpartofvalues1 "Here is a Python example". + * \endif + */ +void DataArrayDouble::setPartOfValues1(const DataArrayDouble *a, int bgTuples, int endTuples, int stepTuples, int bgComp, int endComp, int stepComp, bool strictCompoCompare) +{ + if(!a) + throw INTERP_KERNEL::Exception("DataArrayDouble::setPartOfValues1 : input DataArrayDouble is NULL !"); + const char msg[]="DataArrayDouble::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; + } + const double *srcPt=a->getConstPointer(); + double *pt=getPointer()+bgTuples*nbComp+bgComp; + if(assignTech) + { + for(int i=0;i<newNbOfTuples;i++,pt+=stepTuples*nbComp) + for(int j=0;j<newNbOfComp;j++,srcPt++) + pt[j*stepComp]=*srcPt; + } + else + { + for(int i=0;i<newNbOfTuples;i++,pt+=stepTuples*nbComp) + { + const double *srcPt2=srcPt; + for(int j=0;j<newNbOfComp;j++,srcPt2++) + pt[j*stepComp]=*srcPt2; + } + } +} + +/*! + * Assign a given value to values at specified tuples and components of \a this array. + * The tree parameters defining set of indices of tuples and components are similar to + * the tree parameters of the Python function \c range(\c start,\c stop,\c step).. + * \param [in] a - the value to assign. + * \param [in] bgTuples - index of the first tuple of \a this array to assign to. + * \param [in] endTuples - index of the tuple before which the tuples to assign to + * are located. + * \param [in] stepTuples - index increment to get index of the next tuple to assign to. + * \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 parameters specifying tuples and components to assign to, do not give a + * non-empty range of increasing indices or indices are out of a valid range + * for \c this array. + * + * \if ENABLE_EXAMPLES + * \ref py_mcdataarraydouble_setpartofvaluessimple1 "Here is a Python example". + * \endif + */ +void DataArrayDouble::setPartOfValuesSimple1(double a, int bgTuples, int endTuples, int stepTuples, int bgComp, int endComp, int stepComp) +{ + const char msg[]="DataArrayDouble::setPartOfValuesSimple1"; + 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"); + double *pt=getPointer()+bgTuples*nbComp+bgComp; + for(int i=0;i<newNbOfTuples;i++,pt+=stepTuples*nbComp) + for(int j=0;j<newNbOfComp;j++) + pt[j*stepComp]=a; +} + +/*! + * Copy all values from another DataArrayDouble (\a a) into specified tuples and + * components of \a this array. Textual data is not copied. + * The tuples and components to assign to are defined by C arrays of indices. + * 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 <em>(pi)</em> 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 <em>(pi)</em> 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 <em>bgTuples / bgComp</em> is + * out of a valid range for \a this array. + * \throw In the first *mode of usage*, if <em>strictCompoCompare == true </em> and + * if <em> a->getNumberOfComponents() != (endComp - bgComp) </em>. + * \throw In the second *mode of usage*, if \a a->getNumberOfTuples() != 1 or + * <em> a->getNumberOfComponents() != (endComp - bgComp)</em>. + * + * \if ENABLE_EXAMPLES + * \ref py_mcdataarraydouble_setpartofvalues2 "Here is a Python example". + * \endif + */ +void DataArrayDouble::setPartOfValues2(const DataArrayDouble *a, const int *bgTuples, const int *endTuples, const int *bgComp, const int *endComp, bool strictCompoCompare) +{ + if(!a) + throw INTERP_KERNEL::Exception("DataArrayDouble::setPartOfValues2 : input DataArrayDouble is NULL !"); + const char msg[]="DataArrayDouble::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; + } + double *pt=getPointer(); + const double *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 double *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 <em>bgTuples / bgComp</em> is + * out of a valid range for \a this array. + * + * \if ENABLE_EXAMPLES + * \ref py_mcdataarraydouble_setpartofvaluessimple2 "Here is a Python example". + * \endif + */ +void DataArrayDouble::setPartOfValuesSimple2(double a, const int *bgTuples, const int *endTuples, const int *bgComp, const int *endComp) +{ + checkAllocated(); + int nbComp=getNumberOfComponents(); + int nbOfTuples=getNumberOfTuples(); + for(const int *z=bgComp;z!=endComp;z++) + DataArray::CheckValueInRange(nbComp,*z,"invalid component id"); + double *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 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 <em>(pi)</em> 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 <em>strictCompoCompare == true </em> and + * if <em> a->getNumberOfComponents()</em> is unequal to the number of components + * defined by <em>(bgComp,endComp,stepComp)</em>. + * \throw In the second *mode of usage*, if \a a->getNumberOfTuples() != 1 or + * <em> a->getNumberOfComponents()</em> is unequal to the number of components + * defined by <em>(bgComp,endComp,stepComp)</em>. + * \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 \c this array. + * + * \if ENABLE_EXAMPLES + * \ref py_mcdataarraydouble_setpartofvalues3 "Here is a Python example". + * \endif + */ +void DataArrayDouble::setPartOfValues3(const DataArrayDouble *a, const int *bgTuples, const int *endTuples, int bgComp, int endComp, int stepComp, bool strictCompoCompare) +{ + if(!a) + throw INTERP_KERNEL::Exception("DataArrayDouble::setPartOfValues3 : input DataArrayDouble is NULL !"); + const char msg[]="DataArrayDouble::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; + } + double *pt=getPointer()+bgComp; + const double *srcPt=a->getConstPointer(); + if(assignTech) + { + for(const int *w=bgTuples;w!=endTuples;w++) + for(int j=0;j<newNbOfComp;j++,srcPt++) + { + DataArray::CheckValueInRange(nbOfTuples,*w,"invalid tuple id"); + pt[(std::size_t)(*w)*nbComp+j*stepComp]=*srcPt; + } + } + else + { + for(const int *w=bgTuples;w!=endTuples;w++) + { + const double *srcPt2=srcPt; + for(int j=0;j<newNbOfComp;j++,srcPt2++) + { + DataArray::CheckValueInRange(nbOfTuples,*w,"invalid tuple id"); + pt[(std::size_t)(*w)*nbComp+j*stepComp]=*srcPt2; + } + } + } +} + +/*! + * Assign a given value to values at specified tuples and components of \a this array. + * 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). + * \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 <em>(pi)</em> 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 \c this array. + * + * \if ENABLE_EXAMPLES + * \ref py_mcdataarraydouble_setpartofvaluessimple3 "Here is a Python example". + * \endif + */ +void DataArrayDouble::setPartOfValuesSimple3(double a, const int *bgTuples, const int *endTuples, int bgComp, int endComp, int stepComp) +{ + const char msg[]="DataArrayDouble::setPartOfValuesSimple3"; + checkAllocated(); + int newNbOfComp=DataArray::GetNumberOfItemGivenBES(bgComp,endComp,stepComp,msg); + int nbComp=getNumberOfComponents(); + int nbOfTuples=getNumberOfTuples(); + DataArray::CheckValueInRangeEx(nbComp,bgComp,endComp,"invalid component value"); + double *pt=getPointer()+bgComp; + for(const int *w=bgTuples;w!=endTuples;w++) + for(int j=0;j<newNbOfComp;j++) + { + DataArray::CheckValueInRange(nbOfTuples,*w,"invalid tuple id"); + pt[(std::size_t)(*w)*nbComp+j*stepComp]=a; + } +} + +/*! + * Copy all values from another DataArrayDouble into specified tuples and components + * of \a this array. Textual data is not copied. + * The tree parameters defining set of indices of tuples and components are similar to + * the tree parameters of the Python function \c range(\c start,\c stop,\c step). + * \param [in] a - the array to copy values from. + * \param [in] bgTuples - index of the first tuple of \a this array to assign values to. + * \param [in] endTuples - index of the tuple before which the tuples to assign to + * are located. + * \param [in] stepTuples - index increment to get index of the next tuple to assign to. + * \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. + * \param [in] strictCompoCompare - if \a true (by default), then \a a->getNumberOfComponents() + * 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::setPartOfValues4(const DataArrayDouble *a, int bgTuples, int endTuples, int stepTuples, const int *bgComp, const int *endComp, bool strictCompoCompare) +{ + 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;i<newNbOfTuples;i++,pt+=stepTuples*nbComp) + for(const int *z=bgComp;z!=endComp;z++,srcPt++) + pt[*z]=*srcPt; + } + else + { + for(int i=0;i<newNbOfTuples;i++,pt+=stepTuples*nbComp) + { + const double *srcPt2=srcPt; + for(const int *z=bgComp;z!=endComp;z++,srcPt2++) + pt[*z]=*srcPt2; + } + } +} + +void DataArrayDouble::setPartOfValuesSimple4(double a, int bgTuples, int endTuples, int stepTuples, const int *bgComp, const int *endComp) +{ + const char msg[]="DataArrayDouble::setPartOfValuesSimple4"; + checkAllocated(); + int newNbOfTuples=DataArray::GetNumberOfItemGivenBES(bgTuples,endTuples,stepTuples,msg); + 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"); + double *pt=getPointer()+bgTuples*nbComp; + for(int i=0;i<newNbOfTuples;i++,pt+=stepTuples*nbComp) + for(const int *z=bgComp;z!=endComp;z++) + pt[*z]=a; +} + +/*! + * Copy some tuples from another DataArrayDouble into specified tuples + * of \a this array. Textual data is not copied. Both arrays must have equal number of + * components. + * Both the tuples to assign and the tuples to assign to are defined by a DataArrayInt. + * All components of selected tuples are copied. + * \param [in] a - the array to copy values from. + * \param [in] tuplesSelec - the array specifying both source tuples of \a a and + * target tuples of \a this. \a tuplesSelec has two components, and the + * first component specifies index of the source tuple and the second + * one specifies index of the target tuple. + * \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 <em>this->getNumberOfComponents() != a->getNumberOfComponents()</em>. + * \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) +{ + if(!a || !tuplesSelec) + throw INTERP_KERNEL::Exception("DataArrayDouble::setPartOfValuesAdv : input DataArrayDouble is NULL !"); + checkAllocated(); + a->checkAllocated(); + tuplesSelec->checkAllocated(); + int nbOfComp=getNumberOfComponents(); + if(nbOfComp!=a->getNumberOfComponents()) + throw INTERP_KERNEL::Exception("DataArrayDouble::setPartOfValuesAdv : This and a do not have the same number of components !"); + if(tuplesSelec->getNumberOfComponents()!=2) + throw INTERP_KERNEL::Exception("DataArrayDouble::setPartOfValuesAdv : Expecting to have a tuple selector DataArrayInt instance with exactly 2 components !"); + int thisNt=getNumberOfTuples(); + int aNt=a->getNumberOfTuples(); + double *valsToSet=getPointer(); + const double *valsSrc=a->getConstPointer(); + for(const int *tuple=tuplesSelec->begin();tuple!=tuplesSelec->end();tuple+=2) + { + if(tuple[1]>=0 && tuple[1]<aNt) + { + if(tuple[0]>=0 && tuple[0]<thisNt) + std::copy(valsSrc+nbOfComp*tuple[1],valsSrc+nbOfComp*(tuple[1]+1),valsToSet+nbOfComp*tuple[0]); + else + { + std::ostringstream oss; oss << "DataArrayDouble::setPartOfValuesAdv : Tuple #" << std::distance(tuplesSelec->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 << "DataArrayDouble::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 DataArrayDouble (\a aBase) 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] aBase - 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 aBase is NULL. + * \throw If \a aBase is not allocated. + * \throw If \a tuplesSelec is NULL. + * \throw If \a tuplesSelec is not allocated. + * \throw If <em>this->getNumberOfComponents() != aBase->getNumberOfComponents()</em>. + * \throw If \a tuplesSelec->getNumberOfComponents() != 1. + * \throw If <em>tupleIdStart + tuplesSelec->getNumberOfTuples() > this->getNumberOfTuples().</em> + * \throw If any tuple index given by \a tuplesSelec is out of a valid range for + * \a aBase array. + */ +void DataArrayDouble::setContigPartOfSelectedValues(int tupleIdStart, const DataArray *aBase, const DataArrayInt *tuplesSelec) +{ + if(!aBase || !tuplesSelec) + throw INTERP_KERNEL::Exception("DataArrayDouble::setContigPartOfSelectedValues : input DataArray is NULL !"); + const DataArrayDouble *a=dynamic_cast<const DataArrayDouble *>(aBase); + if(!a) + throw INTERP_KERNEL::Exception("DataArrayDouble::setContigPartOfSelectedValues : input DataArray aBase is not a DataArrayDouble !"); + checkAllocated(); + a->checkAllocated(); + tuplesSelec->checkAllocated(); + int nbOfComp=getNumberOfComponents(); + if(nbOfComp!=a->getNumberOfComponents()) + throw INTERP_KERNEL::Exception("DataArrayDouble::setContigPartOfSelectedValues : This and a do not have the same number of components !"); + if(tuplesSelec->getNumberOfComponents()!=1) + throw INTERP_KERNEL::Exception("DataArrayDouble::setContigPartOfSelectedValues : Expecting to have a tuple selector DataArrayInt instance with exactly 1 component !"); + int thisNt=getNumberOfTuples(); + int aNt=a->getNumberOfTuples(); + int nbOfTupleToWrite=tuplesSelec->getNumberOfTuples(); + double *valsToSet=getPointer()+tupleIdStart*nbOfComp; + if(tupleIdStart+nbOfTupleToWrite>thisNt) + throw INTERP_KERNEL::Exception("DataArrayDouble::setContigPartOfSelectedValues : invalid number range of values to write !"); + const double *valsSrc=a->getConstPointer(); + for(const int *tuple=tuplesSelec->begin();tuple!=tuplesSelec->end();tuple++,valsToSet+=nbOfComp) + { + if(*tuple>=0 && *tuple<aNt) + { + std::copy(valsSrc+nbOfComp*(*tuple),valsSrc+nbOfComp*(*tuple+1),valsToSet); + } + else + { + std::ostringstream oss; oss << "DataArrayDouble::setContigPartOfSelectedValues : Tuple #" << std::distance(tuplesSelec->begin(),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 DataArrayDouble (\a aBase) 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] aBase - the array to copy values from. + * \param [in] bg - index of the first tuple to copy of the array \a aBase. + * \param [in] end2 - index of the tuple of \a aBase 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 aBase is NULL. + * \throw If \a aBase is not allocated. + * \throw If <em>this->getNumberOfComponents() != aBase->getNumberOfComponents()</em>. + * \throw If <em>tupleIdStart + len(range(bg,end2,step)) > this->getNumberOfTuples().</em> + * \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 aBase. + */ +void DataArrayDouble::setContigPartOfSelectedValues2(int tupleIdStart, const DataArray *aBase, int bg, int end2, int step) +{ + if(!aBase) + throw INTERP_KERNEL::Exception("DataArrayDouble::setContigPartOfSelectedValues2 : input DataArray is NULL !"); + const DataArrayDouble *a=dynamic_cast<const DataArrayDouble *>(aBase); + if(!a) + throw INTERP_KERNEL::Exception("DataArrayDouble::setContigPartOfSelectedValues2 : input DataArray aBase is not a DataArrayDouble !"); + checkAllocated(); + a->checkAllocated(); + int nbOfComp=getNumberOfComponents(); + const char msg[]="DataArrayDouble::setContigPartOfSelectedValues2"; + int nbOfTupleToWrite=DataArray::GetNumberOfItemGivenBES(bg,end2,step,msg); + if(nbOfComp!=a->getNumberOfComponents()) + throw INTERP_KERNEL::Exception("DataArrayDouble::setContigPartOfSelectedValues2 : This and a do not have the same number of components !"); + int thisNt=getNumberOfTuples(); + int aNt=a->getNumberOfTuples(); + double *valsToSet=getPointer()+tupleIdStart*nbOfComp; + if(tupleIdStart+nbOfTupleToWrite>thisNt) + throw INTERP_KERNEL::Exception("DataArrayDouble::setContigPartOfSelectedValues2 : invalid number range of values to write !"); + if(end2>aNt) + throw INTERP_KERNEL::Exception("DataArrayDouble::setContigPartOfSelectedValues2 : invalid range of values to read !"); + const double *valsSrc=a->getConstPointer()+bg*nbOfComp; + for(int i=0;i<nbOfTupleToWrite;i++,valsToSet+=nbOfComp,valsSrc+=step*nbOfComp) + { + std::copy(valsSrc,valsSrc+nbOfComp,valsToSet); + } +} + +/*! + * 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 <em>( 0 <= tupleId < this->getNumberOfTuples() )</em> is violated. + * \throw If condition <em>( 0 <= compoId < this->getNumberOfComponents() )</em> is violated. + */ +double DataArrayDouble::getIJSafe(int tupleId, int compoId) const +{ + checkAllocated(); + if(tupleId<0 || tupleId>=getNumberOfTuples()) + { + std::ostringstream oss; oss << "DataArrayDouble::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 << "DataArrayDouble::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 first 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::front() const +{ + checkAllocated(); + if(getNumberOfComponents()!=1) + throw INTERP_KERNEL::Exception("DataArrayDouble::front : number of components not equal to one !"); + int nbOfTuples=getNumberOfTuples(); + if(nbOfTuples<1) + throw INTERP_KERNEL::Exception("DataArrayDouble::front : number of tuples must be >= 1 !"); + return *(getConstPointer()); +} + +/*! + * 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 +{ + checkAllocated(); + if(getNumberOfComponents()!=1) + throw INTERP_KERNEL::Exception("DataArrayDouble::back : number of components not equal to one !"); + int nbOfTuples=getNumberOfTuples(); + if(nbOfTuples<1) + throw INTERP_KERNEL::Exception("DataArrayDouble::back : number of tuples must be >= 1 !"); + return *(getConstPointer()+nbOfTuples-1); +} + +void DataArrayDouble::SetArrayIn(DataArrayDouble *newArray, DataArrayDouble* &arrayToSet) +{ + if(newArray!=arrayToSet) + { + if(arrayToSet) + arrayToSet->decrRef(); + arrayToSet=newArray; + if(arrayToSet) + arrayToSet->incrRef(); + } +} + +/*! + * 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) +{ + _info_on_compo.resize(nbOfCompo); + _mem.useArray(array,ownership,type,(std::size_t)nbOfTuple*nbOfCompo); + declareAsNew(); +} + +void DataArrayDouble::useExternalArrayWithRWAccess(const double *array, int nbOfTuple, int nbOfCompo) +{ + _info_on_compo.resize(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 +{ + const double *tmp=getConstPointer(); + 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 !"); +} + +/*! + * 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:<br> + * \a bounds[0] = \c min_of_component_0 <br> + * \a bounds[1] = \c max_of_component_0 <br> + * \a bounds[2] = \c min_of_component_1 <br> + * \a bounds[3] = \c max_of_component_1 <br> + * ... + */ +void DataArrayDouble::getMinMaxPerComponent(double *bounds) const +{ + checkAllocated(); + int dim=getNumberOfComponents(); + for (int idim=0; idim<dim; idim++) + { + bounds[idim*2]=std::numeric_limits<double>::max(); + bounds[idim*2+1]=-std::numeric_limits<double>::max(); + } + const double *ptr=getConstPointer(); + int nbOfTuples=getNumberOfTuples(); + for(int i=0;i<nbOfTuples;i++) + { + for(int idim=0;idim<dim;idim++) + { + if(bounds[idim*2]>ptr[i*dim+idim]) + { + bounds[idim*2]=ptr[i*dim+idim]; + } + if(bounds[idim*2+1]<ptr[i*dim+idim]) + { + bounds[idim*2+1]=ptr[i*dim+idim]; + } + } + } +} + +/*! + * This method retrieves a newly allocated DataArrayDouble instance having same number of tuples than \a this and twice number of components than \a this + * to store both the min and max per component of each tuples. + * \param [in] epsilon the width of the bbox (identical in each direction) - 0.0 by default + * + * \return a newly created DataArrayDouble instance having \c this->getNumberOfTuples() tuples and 2 * \c this->getNumberOfComponent() components + * + * \throw If \a this is not allocated yet. + */ +DataArrayDouble *DataArrayDouble::computeBBoxPerTuple(double epsilon) const +{ + checkAllocated(); + const double *dataPtr=getConstPointer(); + int nbOfCompo=getNumberOfComponents(); + int nbTuples=getNumberOfTuples(); + MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> bbox=DataArrayDouble::New(); + bbox->alloc(nbTuples,2*nbOfCompo); + double *bboxPtr=bbox->getPointer(); + for(int i=0;i<nbTuples;i++) + { + for(int j=0;j<nbOfCompo;j++) + { + bboxPtr[2*nbOfCompo*i+2*j]=dataPtr[nbOfCompo*i+j]-epsilon; + bboxPtr[2*nbOfCompo*i+2*j+1]=dataPtr[nbOfCompo*i+j]+epsilon; + } + } + return bbox.retn(); +} + +/*! + * For each tuples **t** in \a other, this method retrieves tuples in \a this that are equal to **t**. + * 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 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. + * + * \throw In case of: + * - \a this is not allocated + * - \a other is not allocated or null + * - \a this and \a other do not have the same number of components + * - if number of components of \a this is not in [1,2,3] + * + * \sa MEDCouplingPointSet::getNodeIdsNearPoints, DataArrayDouble::getDifferentValues + */ +void DataArrayDouble::computeTupleIdsNearTuples(const DataArrayDouble *other, double eps, DataArrayInt *& c, DataArrayInt *& cI) const +{ + if(!other) + throw INTERP_KERNEL::Exception("DataArrayDouble::computeTupleIdsNearTuples : input pointer other is null !"); + 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(); + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> cArr(DataArrayInt::New()),cIArr(DataArrayInt::New()); cArr->alloc(0,1); cIArr->pushBackSilent(0); + switch(nbOfCompo) + { + case 3: + { + BBTreePts<3,int> myTree(begin(),0,0,getNumberOfTuples(),eps); + FindTupleIdsNearTuplesAlg<3>(myTree,other->getConstPointer(),nbOfTuplesOther,eps,cArr,cIArr); + break; + } + case 2: + { + BBTreePts<2,int> myTree(begin(),0,0,getNumberOfTuples(),eps); + FindTupleIdsNearTuplesAlg<2>(myTree,other->getConstPointer(),nbOfTuplesOther,eps,cArr,cIArr); + break; + } + case 1: + { + 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(); +} + +/*! + * This method recenter tuples in \b this in order to be centered at the origin to benefit about the advantages of maximal precision to be around the box + * around origin of 'radius' 1. + * + * \param [in] eps absolute epsilon. under that value of delta between max and min no scale is performed. + */ +void DataArrayDouble::recenterForMaxPrecision(double eps) +{ + checkAllocated(); + int dim=getNumberOfComponents(); + std::vector<double> bounds(2*dim); + getMinMaxPerComponent(&bounds[0]); + for(int i=0;i<dim;i++) + { + double delta=bounds[2*i+1]-bounds[2*i]; + double offset=(bounds[2*i]+bounds[2*i+1])/2.; + if(delta>eps) + applyLin(1./delta,-offset/delta,i); + else + applyLin(1.,-offset,i); + } +} + +/*! + * 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 +{ + 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(); + if(nbOfTuples<=0) + throw INTERP_KERNEL::Exception("DataArrayDouble::getMaxValue : array exists but number of tuples must be > 0 !"); + const double *vals=getConstPointer(); + const double *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 double - the maximal value among all values of \a this array. + * \throw If \a this is not allocated. + */ +double DataArrayDouble::getMaxValueInArray() const +{ + checkAllocated(); + const double *loc=std::max_element(begin(),end()); + 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 +{ + int tmp; + tupleIds=0; + double ret=getMaxValue(tmp); + tupleIds=getIdsInRange(ret,ret); + 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 +{ + 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(); + if(nbOfTuples<=0) + throw INTERP_KERNEL::Exception("DataArrayDouble::getMinValue : array exists but number of tuples must be > 0 !"); + const double *vals=getConstPointer(); + const double *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 double - the minimal value among all values of \a this array. + * \throw If \a this is not allocated. + */ +double DataArrayDouble::getMinValueInArray() const +{ + checkAllocated(); + const double *loc=std::min_element(begin(),end()); + 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 +{ + int tmp; + tupleIds=0; + double ret=getMinValue(tmp); + tupleIds=getIdsInRange(ret,ret); + 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 +{ + 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;i<nbOfTuples;i++,vals++) + if(fabs(*vals-value)<=eps) + ret++; + return ret; +} + +/*! + * Returns the average value of \a this one-dimensional array. + * \return double - the average value over all values of \a this array. + * \throw If \a this->getNumberOfComponents() != 1 + * \throw If \a this->getNumberOfTuples() < 1 + */ +double DataArrayDouble::getAverageValue() const +{ + if(getNumberOfComponents()!=1) + throw INTERP_KERNEL::Exception("DataArrayDouble::getAverageValue : must be applied on DataArrayDouble with only one component, you can call 'rearrange' method before !"); + int nbOfTuples=getNumberOfTuples(); + if(nbOfTuples<=0) + throw INTERP_KERNEL::Exception("DataArrayDouble::getAverageValue : array exists but number of tuples must be > 0 !"); + const double *vals=getConstPointer(); + double ret=std::accumulate(vals,vals+nbOfTuples,0.); + 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 +{ + checkAllocated(); + double ret=0.; + std::size_t nbOfElems=getNbOfElems(); + const double *pt=getConstPointer(); + for(std::size_t i=0;i<nbOfElems;i++,pt++) + ret+=(*pt)*(*pt); + return sqrt(ret); +} + +/*! + * Returns the maximum norm of the vector defined by \a this array. + * This method works even if the number of components is diferent from one. + * If the number of elements in \a this is 0, -1. is returned. + * \return double - the value of the maximum norm, i.e. + * the maximal absolute value among values of \a this array (whatever its number of components). + * \throw If \a this is not allocated. + */ +double DataArrayDouble::normMax() const +{ + checkAllocated(); + double ret(-1.); + std::size_t nbOfElems(getNbOfElems()); + const double *pt(getConstPointer()); + for(std::size_t i=0;i<nbOfElems;i++,pt++) + { + double val(std::abs(*pt)); + if(val>ret) + ret=val; + } + return ret; +} + +/*! + * Returns the minimum norm (absolute value) of the vector defined by \a this array. + * This method works even if the number of components is diferent from one. + * If the number of elements in \a this is 0, std::numeric_limits<double>::max() is returned. + * \return double - the value of the minimum norm, i.e. + * the minimal absolute value among values of \a this array (whatever its number of components). + * \throw If \a this is not allocated. + */ +double DataArrayDouble::normMin() const +{ + checkAllocated(); + double ret(std::numeric_limits<double>::max()); + std::size_t nbOfElems(getNbOfElems()); + const double *pt(getConstPointer()); + for(std::size_t i=0;i<nbOfElems;i++,pt++) + { + double val(std::abs(*pt)); + if(val<ret) + ret=val; + } + 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 +{ + checkAllocated(); + const double *ptr=getConstPointer(); + int nbTuple=getNumberOfTuples(); + int nbComps=getNumberOfComponents(); + std::fill(res,res+nbComps,0.); + for(int i=0;i<nbTuple;i++) + std::transform(ptr+i*nbComps,ptr+(i+1)*nbComps,res,res,std::plus<double>()); +} + +/*! + * 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 +{ + 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<double>::max(); + tupleId=-1; + const double *work=getConstPointer(); + for(int i=0;i<nbTuple;i++) + { + double val=0.; + for(int j=0;j<nbComps;j++,work++) + val+=(*work-tupleBg[j])*((*work-tupleBg[j])); + if(val>=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 +{ + checkAllocated(); + const double *ptr=getConstPointer(); + int nbTuple=getNumberOfTuples(); + int nbComps=getNumberOfComponents(); + 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;i<nbTuple;i++) + ret+=ptr[i*nbComps+compId]; + return ret; +} + +/*! + * This method accumulate using addition tuples in \a this using input index array [ \a bgOfIndex, \a endOfIndex ). + * The returned array will have same number of components than \a this and number of tuples equal to + * \c std::distance(bgOfIndex,endOfIndex) \b minus \b one. + * + * The input index array is expected to be ascendingly sorted in which the all referenced ids should be in [0, \c this->getNumberOfTuples). + * 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 +{ + 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<DataArrayDouble> 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<sz;i++,tmp+=nbCompo,w++) + { + std::fill(tmp,tmp+nbCompo,0.); + if(w[1]>=w[0]) + { + for(int j=w[0];j<w[1];j++,srcPt+=nbCompo) + { + if(j>=0 && j<nbOfTuples) + std::transform(srcPt,srcPt+nbCompo,tmp,tmp,std::plus<double>()); + 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 +{ + checkAllocated(); + int nbOfComp=getNumberOfComponents(); + if(nbOfComp!=2) + throw INTERP_KERNEL::Exception("DataArrayDouble::fromPolarToCart : must be an array with exactly 2 components !"); + int nbOfTuple=getNumberOfTuples(); + DataArrayDouble *ret=DataArrayDouble::New(); + ret->alloc(nbOfTuple,2); + double *w=ret->getPointer(); + const double *wIn=getConstPointer(); + for(int i=0;i<nbOfTuple;i++,w+=2,wIn+=2) + { + w[0]=wIn[0]*cos(wIn[1]); + w[1]=wIn[0]*sin(wIn[1]); + } + 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 +{ + checkAllocated(); + int nbOfComp=getNumberOfComponents(); + if(nbOfComp!=3) + throw INTERP_KERNEL::Exception("DataArrayDouble::fromCylToCart : must be an array with exactly 3 components !"); + int nbOfTuple=getNumberOfTuples(); + DataArrayDouble *ret=DataArrayDouble::New(); + ret->alloc(getNumberOfTuples(),3); + double *w=ret->getPointer(); + const double *wIn=getConstPointer(); + for(int i=0;i<nbOfTuple;i++,w+=3,wIn+=3) + { + w[0]=wIn[0]*cos(wIn[1]); + w[1]=wIn[0]*sin(wIn[1]); + w[2]=wIn[2]; + } + ret->setInfoOnComponent(2,getInfoOnComponent(2)); + 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 +{ + checkAllocated(); + int nbOfComp=getNumberOfComponents(); + if(nbOfComp!=3) + throw INTERP_KERNEL::Exception("DataArrayDouble::fromSpherToCart : must be an array with exactly 3 components !"); + int nbOfTuple=getNumberOfTuples(); + DataArrayDouble *ret=DataArrayDouble::New(); + ret->alloc(getNumberOfTuples(),3); + double *w=ret->getPointer(); + const double *wIn=getConstPointer(); + for(int i=0;i<nbOfTuple;i++,w+=3,wIn+=3) + { + w[0]=wIn[0]*cos(wIn[2])*sin(wIn[1]); + w[1]=wIn[0]*sin(wIn[2])*sin(wIn[1]); + w[2]=wIn[0]*cos(wIn[1]); + } + 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 <em>(t)</em> 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 +{ + checkAllocated(); + int nbOfComp=getNumberOfComponents(); + if(nbOfComp!=6) + throw INTERP_KERNEL::Exception("DataArrayDouble::doublyContractedProduct : must be an array with exactly 6 components !"); + DataArrayDouble *ret=DataArrayDouble::New(); + int nbOfTuple=getNumberOfTuples(); + ret->alloc(nbOfTuple,1); + const double *src=getConstPointer(); + double *dest=ret->getPointer(); + for(int i=0;i<nbOfTuple;i++,dest++,src+=6) + *dest=src[0]*src[0]+src[1]*src[1]+src[2]*src[2]+2.*src[3]*src[3]+2.*src[4]*src[4]+2.*src[5]*src[5]; + 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 +{ + checkAllocated(); + DataArrayDouble *ret=DataArrayDouble::New(); + int nbOfTuple=getNumberOfTuples(); + ret->alloc(nbOfTuple,1); + const double *src=getConstPointer(); + double *dest=ret->getPointer(); + switch(getNumberOfComponents()) + { + case 6: + for(int i=0;i<nbOfTuple;i++,dest++,src+=6) + *dest=src[0]*src[1]*src[2]+2.*src[4]*src[5]*src[3]-src[0]*src[4]*src[4]-src[2]*src[3]*src[3]-src[1]*src[5]*src[5]; + return ret; + case 4: + for(int i=0;i<nbOfTuple;i++,dest++,src+=4) + *dest=src[0]*src[3]-src[1]*src[2]; + return ret; + case 9: + for(int i=0;i<nbOfTuple;i++,dest++,src+=9) + *dest=src[0]*src[4]*src[8]+src[1]*src[5]*src[6]+src[2]*src[3]*src[7]-src[0]*src[5]*src[7]-src[1]*src[3]*src[8]-src[2]*src[4]*src[6]; + return ret; + default: + ret->decrRef(); + throw INTERP_KERNEL::Exception("DataArrayDouble::determinant : Invalid number of components ! must be in 4,6,9 !"); + } +} + +/*! + * 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 +{ + checkAllocated(); + int nbOfComp=getNumberOfComponents(); + if(nbOfComp!=6) + throw INTERP_KERNEL::Exception("DataArrayDouble::eigenValues : must be an array with exactly 6 components !"); + DataArrayDouble *ret=DataArrayDouble::New(); + int nbOfTuple=getNumberOfTuples(); + ret->alloc(nbOfTuple,3); + const double *src=getConstPointer(); + double *dest=ret->getPointer(); + for(int i=0;i<nbOfTuple;i++,dest+=3,src+=6) + INTERP_KERNEL::computeEigenValues6(src,dest); + 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 +{ + checkAllocated(); + int nbOfComp=getNumberOfComponents(); + if(nbOfComp!=6) + throw INTERP_KERNEL::Exception("DataArrayDouble::eigenVectors : must be an array with exactly 6 components !"); + DataArrayDouble *ret=DataArrayDouble::New(); + int nbOfTuple=getNumberOfTuples(); + ret->alloc(nbOfTuple,9); + const double *src=getConstPointer(); + double *dest=ret->getPointer(); + for(int i=0;i<nbOfTuple;i++,src+=6) + { + double tmp[3]; + INTERP_KERNEL::computeEigenValues6(src,tmp); + for(int j=0;j<3;j++,dest+=3) + INTERP_KERNEL::computeEigenVectorForEigenValue6(src,tmp[j],1e-12,dest); + } + 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 +{ + 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 !"); + DataArrayDouble *ret=DataArrayDouble::New(); + int nbOfTuple=getNumberOfTuples(); + ret->alloc(nbOfTuple,nbOfComp); + const double *src=getConstPointer(); + double *dest=ret->getPointer(); + if(nbOfComp==6) + for(int i=0;i<nbOfTuple;i++,dest+=6,src+=6) + { + double det=src[0]*src[1]*src[2]+2.*src[4]*src[5]*src[3]-src[0]*src[4]*src[4]-src[2]*src[3]*src[3]-src[1]*src[5]*src[5]; + dest[0]=(src[1]*src[2]-src[4]*src[4])/det; + dest[1]=(src[0]*src[2]-src[5]*src[5])/det; + dest[2]=(src[0]*src[1]-src[3]*src[3])/det; + dest[3]=(src[5]*src[4]-src[3]*src[2])/det; + dest[4]=(src[5]*src[3]-src[0]*src[4])/det; + dest[5]=(src[3]*src[4]-src[1]*src[5])/det; + } + else if(nbOfComp==4) + for(int i=0;i<nbOfTuple;i++,dest+=4,src+=4) + { + double det=src[0]*src[3]-src[1]*src[2]; + dest[0]=src[3]/det; + dest[1]=-src[1]/det; + dest[2]=-src[2]/det; + dest[3]=src[0]/det; + } + else + for(int i=0;i<nbOfTuple;i++,dest+=9,src+=9) + { + double det=src[0]*src[4]*src[8]+src[1]*src[5]*src[6]+src[2]*src[3]*src[7]-src[0]*src[5]*src[7]-src[1]*src[3]*src[8]-src[2]*src[4]*src[6]; + dest[0]=(src[4]*src[8]-src[7]*src[5])/det; + dest[1]=(src[7]*src[2]-src[1]*src[8])/det; + dest[2]=(src[1]*src[5]-src[4]*src[2])/det; + dest[3]=(src[6]*src[5]-src[3]*src[8])/det; + dest[4]=(src[0]*src[8]-src[6]*src[2])/det; + dest[5]=(src[2]*src[3]-src[0]*src[5])/det; + dest[6]=(src[3]*src[7]-src[6]*src[4])/det; + dest[7]=(src[6]*src[1]-src[0]*src[7])/det; + dest[8]=(src[0]*src[4]-src[1]*src[3])/det; + } + 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 +{ + 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 !"); + DataArrayDouble *ret=DataArrayDouble::New(); + int nbOfTuple=getNumberOfTuples(); + ret->alloc(nbOfTuple,1); + const double *src=getConstPointer(); + double *dest=ret->getPointer(); + if(nbOfComp==6) + for(int i=0;i<nbOfTuple;i++,dest++,src+=6) + *dest=src[0]+src[1]+src[2]; + else if(nbOfComp==4) + for(int i=0;i<nbOfTuple;i++,dest++,src+=4) + *dest=src[0]+src[3]; + else + for(int i=0;i<nbOfTuple;i++,dest++,src+=9) + *dest=src[0]+src[4]+src[8]; + 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 +{ + checkAllocated(); + int nbOfComp=getNumberOfComponents(); + if(nbOfComp!=6) + throw INTERP_KERNEL::Exception("DataArrayDouble::deviator : must be an array with exactly 6 components !"); + DataArrayDouble *ret=DataArrayDouble::New(); + int nbOfTuple=getNumberOfTuples(); + ret->alloc(nbOfTuple,6); + const double *src=getConstPointer(); + double *dest=ret->getPointer(); + for(int i=0;i<nbOfTuple;i++,dest+=6,src+=6) + { + double tr=(src[0]+src[1]+src[2])/3.; + dest[0]=src[0]-tr; + dest[1]=src[1]-tr; + dest[2]=src[2]-tr; + dest[3]=src[3]; + dest[4]=src[4]; + dest[5]=src[5]; + } + 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 +{ + checkAllocated(); + int nbOfComp=getNumberOfComponents(); + DataArrayDouble *ret=DataArrayDouble::New(); + int nbOfTuple=getNumberOfTuples(); + ret->alloc(nbOfTuple,1); + const double *src=getConstPointer(); + double *dest=ret->getPointer(); + for(int i=0;i<nbOfTuple;i++,dest++) + { + double sum=0.; + for(int j=0;j<nbOfComp;j++,src++) + sum+=(*src)*(*src); + *dest=sqrt(sum); + } + return ret; +} + +/*! + * Computes for each tuple the sum of number of components values in the tuple and return it. + * + * \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::sumPerTuple() const +{ + checkAllocated(); + int nbOfComp(getNumberOfComponents()),nbOfTuple(getNumberOfTuples()); + MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret(DataArrayDouble::New()); + ret->alloc(nbOfTuple,1); + const double *src(getConstPointer()); + double *dest(ret->getPointer()); + for(int i=0;i<nbOfTuple;i++,dest++,src+=nbOfComp) + *dest=std::accumulate(src,src+nbOfComp,0.); + return ret.retn(); +} + +/*! + * 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 +{ + checkAllocated(); + int nbOfComp=getNumberOfComponents(); + MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New(); + int nbOfTuple=getNumberOfTuples(); + ret->alloc(nbOfTuple,1); + const double *src=getConstPointer(); + double *dest=ret->getPointer(); + for(int i=0;i<nbOfTuple;i++,dest++,src+=nbOfComp) + *dest=*std::max_element(src,src+nbOfComp); + return ret.retn(); +} + +/*! + * 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 +{ + checkAllocated(); + int nbOfComp=getNumberOfComponents(); + MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret0=DataArrayDouble::New(); + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> 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;i<nbOfTuple;i++,dest++,dest1++,src+=nbOfComp) + { + const double *loc=std::max_element(src,src+nbOfComp); + *dest=*loc; + *dest1=(int)std::distance(src,loc); + } + compoIdOfMaxPerTuple=ret1.retn(); + return ret0.retn(); +} + +/*! + * This method returns a newly allocated DataArrayDouble instance having one component and \c this->getNumberOfTuples() * \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. + * + * \throw If \a this is not allocated. + * + * \sa DataArrayDouble::buildEuclidianDistanceDenseMatrixWith + */ +DataArrayDouble *DataArrayDouble::buildEuclidianDistanceDenseMatrix() const +{ + checkAllocated(); + int nbOfComp=getNumberOfComponents(); + int nbOfTuples=getNumberOfTuples(); + const double *inData=getConstPointer(); + MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New(); + ret->alloc(nbOfTuples*nbOfTuples,1); + double *outData=ret->getPointer(); + for(int i=0;i<nbOfTuples;i++) + { + outData[i*nbOfTuples+i]=0.; + for(int j=i+1;j<nbOfTuples;j++) + { + double dist=0.; + for(int k=0;k<nbOfComp;k++) + { double delta=inData[i*nbOfComp+k]-inData[j*nbOfComp+k]; dist+=delta*delta; } + dist=sqrt(dist); + outData[i*nbOfTuples+j]=dist; + outData[j*nbOfTuples+i]=dist; + } + } + return ret.retn(); +} + +/*! + * This method returns a newly allocated DataArrayDouble instance having one component and \c this->getNumberOfTuples() * \c other->getNumberOfTuples() tuples. + * \n This returned array contains the euclidian distance for each tuple in \a other with each tuple in \a this. + * \n So the returned array can be seen as a dense rectangular matrix with \c other->getNumberOfTuples() rows and \c this->getNumberOfTuples() columns. + * \n Output rectangular matrix is sorted along rows. + * \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 ! + * + * \param [in] other DataArrayDouble instance having same number of components than \a this. + * \return A newly allocated (huge) ParaMEDMEM::DataArrayDouble instance that the caller should deal with. + * + * \throw If \a this is not allocated, or if \a other is null or if \a other is not allocated, or if number of components of \a other and \a this differs. + * + * \sa DataArrayDouble::buildEuclidianDistanceDenseMatrix + */ +DataArrayDouble *DataArrayDouble::buildEuclidianDistanceDenseMatrixWith(const DataArrayDouble *other) const +{ + if(!other) + throw INTERP_KERNEL::Exception("DataArrayDouble::buildEuclidianDistanceDenseMatrixWith : input parameter is null !"); + checkAllocated(); + other->checkAllocated(); + int nbOfComp=getNumberOfComponents(); + int otherNbOfComp=other->getNumberOfComponents(); + if(nbOfComp!=otherNbOfComp) + { + std::ostringstream oss; oss << "DataArrayDouble::buildEuclidianDistanceDenseMatrixWith : this nb of compo=" << nbOfComp << " and other nb of compo=" << otherNbOfComp << ". It should match !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + int nbOfTuples=getNumberOfTuples(); + int otherNbOfTuples=other->getNumberOfTuples(); + const double *inData=getConstPointer(); + const double *inDataOther=other->getConstPointer(); + MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New(); + ret->alloc(otherNbOfTuples*nbOfTuples,1); + double *outData=ret->getPointer(); + for(int i=0;i<otherNbOfTuples;i++,inDataOther+=nbOfComp) + { + for(int j=0;j<nbOfTuples;j++) + { + double dist=0.; + for(int k=0;k<nbOfComp;k++) + { double delta=inDataOther[k]-inData[j*nbOfComp+k]; dist+=delta*delta; } + dist=sqrt(dist); + outData[i*nbOfTuples+j]=dist; + } + } + 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) +{ + checkAllocated(); + double *pt=getPointer(); + int nbOfTuple=getNumberOfTuples(); + int nbOfComp=getNumberOfComponents(); + if(asc) + for(int i=0;i<nbOfTuple;i++,pt+=nbOfComp) + std::sort(pt,pt+nbOfComp); + else + for(int i=0;i<nbOfTuple;i++,pt+=nbOfComp) + std::sort(pt,pt+nbOfComp,std::greater<double>()); + declareAsNew(); +} + +/*! + * Converts every value of \a this array to its absolute value. + * \b WARNING this method is non const. If a new DataArrayDouble instance should be built containing the result of abs DataArrayDouble::computeAbs + * should be called instead. + * + * \throw If \a this is not allocated. + * \sa DataArrayDouble::computeAbs + */ +void DataArrayDouble::abs() +{ + checkAllocated(); + double *ptr(getPointer()); + std::size_t nbOfElems(getNbOfElems()); + std::transform(ptr,ptr+nbOfElems,ptr,std::ptr_fun<double,double>(fabs)); + declareAsNew(); +} + +/*! + * This method builds a new instance of \a this object containing the result of std::abs applied of all elements in \a this. + * This method is a const method (that do not change any values in \a this) contrary to DataArrayDouble::abs method. + * + * \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. + * \sa DataArrayDouble::abs + */ +DataArrayDouble *DataArrayDouble::computeAbs() const +{ + checkAllocated(); + DataArrayDouble *newArr(DataArrayDouble::New()); + int nbOfTuples(getNumberOfTuples()); + int nbOfComp(getNumberOfComponents()); + newArr->alloc(nbOfTuples,nbOfComp); + std::transform(begin(),end(),newArr->getPointer(),std::ptr_fun<double,double>(fabs)); + newArr->copyStringInfoFrom(*this); + return newArr; +} + +/*! + * Apply a linear function to a given component of \a this array, so that + * an array element <em>(x)</em> 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, or \a compoId is not in [0,\c this->getNumberOfComponents() ). + */ +void DataArrayDouble::applyLin(double a, double b, int compoId) +{ + checkAllocated(); + double *ptr(getPointer()+compoId); + int nbOfComp(getNumberOfComponents()),nbOfTuple(getNumberOfTuples()); + if(compoId<0 || compoId>=nbOfComp) + { + std::ostringstream oss; oss << "DataArrayDouble::applyLin : The compoId requested (" << compoId << ") is not valid ! Must be in [0," << nbOfComp << ") !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + for(int i=0;i<nbOfTuple;i++,ptr+=nbOfComp) + *ptr=a*(*ptr)+b; + declareAsNew(); +} + +/*! + * Apply a linear 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) +{ + checkAllocated(); + double *ptr=getPointer(); + std::size_t nbOfElems=getNbOfElems(); + for(std::size_t i=0;i<nbOfElems;i++,ptr++) + *ptr=a*(*ptr)+b; + declareAsNew(); +} + +/*! + * Modify all elements of \a this array, so that + * an element _x_ becomes \f$ numerator / x \f$. + * \warning If an exception is thrown because of presence of 0.0 element in \a this + * array, all elements processed before detection of the zero element remain + * modified. + * \param [in] numerator - the numerator used to modify array elements. + * \throw If \a this is not allocated. + * \throw If there is an element equal to 0.0 in \a this array. + */ +void DataArrayDouble::applyInv(double numerator) +{ + checkAllocated(); + double *ptr=getPointer(); + std::size_t nbOfElems=getNbOfElems(); + for(std::size_t i=0;i<nbOfElems;i++,ptr++) + { + if(std::abs(*ptr)>std::numeric_limits<double>::min()) + { + *ptr=numerator/(*ptr); + } + else + { + std::ostringstream oss; oss << "DataArrayDouble::applyInv : presence of null value in tuple #" << i/getNumberOfComponents() << " component #" << i%getNumberOfComponents(); + oss << " !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + } + declareAsNew(); +} + +/*! + * 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 +{ + checkAllocated(); + DataArrayDouble *newArr=DataArrayDouble::New(); + int nbOfTuples=getNumberOfTuples(); + int nbOfComp=getNumberOfComponents(); + newArr->alloc(nbOfTuples,nbOfComp); + const double *cptr=getConstPointer(); + std::transform(cptr,cptr+nbOfTuples*nbOfComp,newArr->getPointer(),std::negate<double>()); + newArr->copyStringInfoFrom(*this); + return newArr; +} + +/*! + * Modify all elements of \a this array, so that + * an element _x_ becomes <em> val ^ x </em>. 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) +{ + 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<nbOfElems;i++,ptr++) + { + if(*ptr>=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<nbOfElems;i++,ptr++) + *ptr=pow(*ptr,val2); + } + declareAsNew(); +} + +/*! + * Modify all elements of \a this array, so that + * an element _x_ becomes \f$ val ^ x \f$. + * \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. + * \warning If an exception is thrown because of presence of 0 element in \a this + * array, all elements processed before detection of the zero element remain + * modified. + */ +void DataArrayDouble::applyRPow(double val) +{ + checkAllocated(); + if(val<0.) + throw INTERP_KERNEL::Exception("DataArrayDouble::applyRPow : the input value has to be >= 0 !"); + double *ptr=getPointer(); + std::size_t nbOfElems=getNbOfElems(); + for(std::size_t i=0;i<nbOfElems;i++,ptr++) + *ptr=pow(val,*ptr); + declareAsNew(); +} + +/*! + * Returns a new DataArrayDouble created from \a this one by applying \a + * FunctionToEvaluate to every tuple of \a this array. Textual data is not copied. + * For more info see \ref MEDCouplingArrayApplyFunc + * \param [in] nbOfComp - number of components in the result array. + * \param [in] func - the \a FunctionToEvaluate declared as + * \c bool (*\a func)(\c const \c double *\a pos, \c double *\a res), + * where \a pos points to the first component of a tuple of \a this array + * and \a res points to the first component of a tuple of the result array. + * Note that length (number of components) of \a pos can differ from + * that of \a res. + * \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 returns \a false. + */ +DataArrayDouble *DataArrayDouble::applyFunc(int nbOfComp, FunctionToEvaluate func) const +{ + checkAllocated(); + DataArrayDouble *newArr=DataArrayDouble::New(); + int nbOfTuples=getNumberOfTuples(); + int oldNbOfComp=getNumberOfComponents(); + newArr->alloc(nbOfTuples,nbOfComp); + const double *ptr=getConstPointer(); + double *ptrToFill=newArr->getPointer(); + for(int i=0;i<nbOfTuples;i++) + { + if(!func(ptr+i*oldNbOfComp,ptrToFill+i*nbOfComp)) + { + std::ostringstream oss; oss << "For tuple # " << i << " with value ("; + std::copy(ptr+oldNbOfComp*i,ptr+oldNbOfComp*(i+1),std::ostream_iterator<double>(oss,", ")); + oss << ") : Evaluation of function failed !"; + newArr->decrRef(); + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + } + 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 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". + * \param [in] isSafe - By default true. If true invalid operation (division by 0. acos of value > 1. ...) leads to a throw of an exception. + * If false the computation is carried on without any notification. When false the evaluation is a little faster. + * \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 std::string& func, bool isSafe) const +{ + INTERP_KERNEL::ExprParser expr(func); + expr.parse(); + std::set<std::string> vars; + expr.getTrueSetOfVars(vars); + std::vector<std::string> varsV(vars.begin(),vars.end()); + return applyFunc3(nbOfComp,varsV,func,isSafe); +} + +/*! + * 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. This method works by tuples (whatever its size). + * If \a this is a one component array, call applyFuncOnThis instead that performs the same work faster. + * + * 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". + * \param [in] isSafe - By default true. If true invalid operation (division by 0. acos of value > 1. ...) leads to a throw of an exception. + * If false the computation is carried on without any notification. When false the evaluation is a little faster. + * \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. + * \sa applyFuncOnThis + * \throw If \a this is not allocated. + * \throw If computing \a func fails. + */ +DataArrayDouble *DataArrayDouble::applyFunc(const std::string& func, bool isSafe) const +{ + int nbOfComp(getNumberOfComponents()); + if(nbOfComp<=0) + throw INTERP_KERNEL::Exception("DataArrayDouble::applyFunc : output number of component must be > 0 !"); + checkAllocated(); + int nbOfTuples(getNumberOfTuples()); + MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> newArr(DataArrayDouble::New()); + newArr->alloc(nbOfTuples,nbOfComp); + INTERP_KERNEL::ExprParser expr(func); + expr.parse(); + std::set<std::string> vars; + expr.getTrueSetOfVars(vars); + if((int)vars.size()>1) + { + std::ostringstream oss; oss << "DataArrayDouble::applyFunc : this method works only with at most one var func expression ! If you need to map comps on variables please use applyFunc2 or applyFunc3 instead ! Vars in expr are : "; + std::copy(vars.begin(),vars.end(),std::ostream_iterator<std::string>(oss," ")); + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + if(vars.empty()) + { + expr.prepareFastEvaluator(); + newArr->rearrange(1); + newArr->fillWithValue(expr.evaluateDouble()); + newArr->rearrange(nbOfComp); + return newArr.retn(); + } + std::vector<std::string> vars2(vars.begin(),vars.end()); + double buff,*ptrToFill(newArr->getPointer()); + const double *ptr(begin()); + std::vector<double> stck; + expr.prepareExprEvaluationDouble(vars2,1,1,0,&buff,&buff+1); + expr.prepareFastEvaluator(); + if(!isSafe) + { + for(int i=0;i<nbOfTuples;i++) + { + for(int iComp=0;iComp<nbOfComp;iComp++,ptr++,ptrToFill++) + { + buff=*ptr; + expr.evaluateDoubleInternal(stck); + *ptrToFill=stck.back(); + stck.pop_back(); + } + } + } + else + { + for(int i=0;i<nbOfTuples;i++) + { + for(int iComp=0;iComp<nbOfComp;iComp++,ptr++,ptrToFill++) + { + buff=*ptr; + try + { + expr.evaluateDoubleInternalSafe(stck); + } + catch(INTERP_KERNEL::Exception& e) + { + std::ostringstream oss; oss << "For tuple # " << i << " component # " << iComp << " with value ("; + oss << buff; + oss << ") : Evaluation of function failed !" << e.what(); + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + *ptrToFill=stck.back(); + stck.pop_back(); + } + } + } + return newArr.retn(); +} + +/*! + * This method is a non const method that modify the array in \a this. + * This method only works on one component array. It means that function \a func must + * contain at most one variable. + * This method is a specialization of applyFunc method with one parameter on one component array. + * + * \param [in] func - the expression defining how to transform a tuple of \a this array. + * Supported expressions are described \ref MEDCouplingArrayApplyFuncExpr "here". + * \param [in] isSafe - By default true. If true invalid operation (division by 0. acos of value > 1. ...) leads to a throw of an exception. + * If false the computation is carried on without any notification. When false the evaluation is a little faster. + * + * \sa applyFunc + */ +void DataArrayDouble::applyFuncOnThis(const std::string& func, bool isSafe) +{ + int nbOfComp(getNumberOfComponents()); + if(nbOfComp<=0) + throw INTERP_KERNEL::Exception("DataArrayDouble::applyFuncOnThis : output number of component must be > 0 !"); + checkAllocated(); + int nbOfTuples(getNumberOfTuples()); + INTERP_KERNEL::ExprParser expr(func); + expr.parse(); + std::set<std::string> vars; + expr.getTrueSetOfVars(vars); + if((int)vars.size()>1) + { + std::ostringstream oss; oss << "DataArrayDouble::applyFuncOnThis : this method works only with at most one var func expression ! If you need to map comps on variables please use applyFunc2 or applyFunc3 instead ! Vars in expr are : "; + std::copy(vars.begin(),vars.end(),std::ostream_iterator<std::string>(oss," ")); + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + if(vars.empty()) + { + expr.prepareFastEvaluator(); + std::vector<std::string> compInfo(getInfoOnComponents()); + rearrange(1); + fillWithValue(expr.evaluateDouble()); + rearrange(nbOfComp); + setInfoOnComponents(compInfo); + return ; + } + std::vector<std::string> vars2(vars.begin(),vars.end()); + double buff,*ptrToFill(getPointer()); + const double *ptr(begin()); + std::vector<double> stck; + expr.prepareExprEvaluationDouble(vars2,1,1,0,&buff,&buff+1); + expr.prepareFastEvaluator(); + if(!isSafe) + { + for(int i=0;i<nbOfTuples;i++) + { + for(int iComp=0;iComp<nbOfComp;iComp++,ptr++,ptrToFill++) + { + buff=*ptr; + expr.evaluateDoubleInternal(stck); + *ptrToFill=stck.back(); + stck.pop_back(); + } + } + } + else + { + for(int i=0;i<nbOfTuples;i++) + { + for(int iComp=0;iComp<nbOfComp;iComp++,ptr++,ptrToFill++) + { + buff=*ptr; + try + { + expr.evaluateDoubleInternalSafe(stck); + } + catch(INTERP_KERNEL::Exception& e) + { + std::ostringstream oss; oss << "For tuple # " << i << " component # " << iComp << " with value ("; + oss << buff; + oss << ") : Evaluation of function failed !" << e.what(); + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + *ptrToFill=stck.back(); + stck.pop_back(); + } + } + } +} + +/*! + * 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". + * \param [in] isSafe - By default true. If true invalid operation (division by 0. acos of value > 1. ...) leads to a throw of an exception. + * If false the computation is carried on without any notification. When false the evaluation is a little faster. + * \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 std::string& func, bool isSafe) const +{ + return applyFunc3(nbOfComp,getVarsOnComponent(),func,isSafe); +} + +/*! + * 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". + * \param [in] isSafe - By default true. If true invalid operation (division by 0. acos of value > 1. ...) leads to a throw of an exception. + * If false the computation is carried on without any notification. When false the evaluation is a little faster. + * \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<std::string>& varsOrder, const std::string& func, bool isSafe) const +{ + if(nbOfComp<=0) + throw INTERP_KERNEL::Exception("DataArrayDouble::applyFunc3 : output number of component must be > 0 !"); + std::vector<std::string> varsOrder2(varsOrder); + int oldNbOfComp(getNumberOfComponents()); + for(int i=(int)varsOrder.size();i<oldNbOfComp;i++) + varsOrder2.push_back(std::string()); + checkAllocated(); + int nbOfTuples(getNumberOfTuples()); + INTERP_KERNEL::ExprParser expr(func); + expr.parse(); + std::set<std::string> vars; + expr.getTrueSetOfVars(vars); + if((int)vars.size()>oldNbOfComp) + { + std::ostringstream oss; oss << "The field has " << oldNbOfComp << " components and there are "; + oss << vars.size() << " variables : "; + std::copy(vars.begin(),vars.end(),std::ostream_iterator<std::string>(oss," ")); + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> newArr(DataArrayDouble::New()); + newArr->alloc(nbOfTuples,nbOfComp); + INTERP_KERNEL::AutoPtr<double> buff(new double[oldNbOfComp]); + double *buffPtr(buff),*ptrToFill; + std::vector<double> stck; + for(int iComp=0;iComp<nbOfComp;iComp++) + { + expr.prepareExprEvaluationDouble(varsOrder2,oldNbOfComp,nbOfComp,iComp,buffPtr,buffPtr+oldNbOfComp); + expr.prepareFastEvaluator(); + const double *ptr(getConstPointer()); + ptrToFill=newArr->getPointer()+iComp; + if(!isSafe) + { + for(int i=0;i<nbOfTuples;i++,ptrToFill+=nbOfComp,ptr+=oldNbOfComp) + { + std::copy(ptr,ptr+oldNbOfComp,buffPtr); + expr.evaluateDoubleInternal(stck); + *ptrToFill=stck.back(); + stck.pop_back(); + } + } + else + { + for(int i=0;i<nbOfTuples;i++,ptrToFill+=nbOfComp,ptr+=oldNbOfComp) + { + std::copy(ptr,ptr+oldNbOfComp,buffPtr); + try + { + expr.evaluateDoubleInternalSafe(stck); + *ptrToFill=stck.back(); + stck.pop_back(); + } + catch(INTERP_KERNEL::Exception& e) + { + std::ostringstream oss; oss << "For tuple # " << i << " with value ("; + std::copy(ptr+oldNbOfComp*i,ptr+oldNbOfComp*(i+1),std::ostream_iterator<double>(oss,", ")); + oss << ") : Evaluation of function failed !" << e.what(); + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + } + } + } + return newArr.retn(); +} + +void DataArrayDouble::applyFuncFast32(const std::string& func) +{ + checkAllocated(); + INTERP_KERNEL::ExprParser expr(func); + expr.parse(); + char *funcStr=expr.compileX86(); + MYFUNCPTR funcPtr; + *((void **)&funcPtr)=funcStr;//he he... + // + double *ptr=getPointer(); + int nbOfComp=getNumberOfComponents(); + int nbOfTuples=getNumberOfTuples(); + int nbOfElems=nbOfTuples*nbOfComp; + for(int i=0;i<nbOfElems;i++,ptr++) + *ptr=funcPtr(*ptr); + declareAsNew(); +} + +void DataArrayDouble::applyFuncFast64(const std::string& func) +{ + checkAllocated(); + INTERP_KERNEL::ExprParser expr(func); + expr.parse(); + char *funcStr=expr.compileX86_64(); + MYFUNCPTR funcPtr; + *((void **)&funcPtr)=funcStr;//he he... + // + double *ptr=getPointer(); + int nbOfComp=getNumberOfComponents(); + int nbOfTuples=getNumberOfTuples(); + int nbOfElems=nbOfTuples*nbOfComp; + for(int i=0;i<nbOfElems;i++,ptr++) + *ptr=funcPtr(*ptr); + declareAsNew(); +} + +DataArrayDoubleIterator *DataArrayDouble::iterator() +{ + 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. + * + * \sa DataArrayDouble::getIdsNotInRange + * + * \if ENABLE_EXAMPLES + * \ref cpp_mcdataarraydouble_getidsinrange "Here is a C++ example".<br> + * \ref py_mcdataarraydouble_getidsinrange "Here is a Python example". + * \endif + */ +DataArrayInt *DataArrayDouble::getIdsInRange(double vmin, double vmax) const +{ + checkAllocated(); + if(getNumberOfComponents()!=1) + throw INTERP_KERNEL::Exception("DataArrayDouble::getIdsInRange : this must have exactly one component !"); + const double *cptr(begin()); + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1); + int nbOfTuples(getNumberOfTuples()); + for(int i=0;i<nbOfTuples;i++,cptr++) + if(*cptr>=vmin && *cptr<=vmax) + ret->pushBackSilent(i); + return ret.retn(); +} + +/*! + * Returns a new DataArrayInt contating indices of tuples of \a this one-dimensional + * array whose values are not within a given range. Textual data is not copied. + * \param [in] vmin - a lowest not acceptable value (excluded). + * \param [in] vmax - a greatest not acceptable value (excluded). + * \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. + * + * \sa DataArrayDouble::getIdsInRange + */ +DataArrayInt *DataArrayDouble::getIdsNotInRange(double vmin, double vmax) const +{ + checkAllocated(); + if(getNumberOfComponents()!=1) + throw INTERP_KERNEL::Exception("DataArrayDouble::getIdsNotInRange : this must have exactly one component !"); + const double *cptr(begin()); + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1); + int nbOfTuples(getNumberOfTuples()); + for(int i=0;i<nbOfTuples;i++,cptr++) + if(*cptr<vmin || *cptr>vmax) + 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) +{ + std::vector<const DataArrayDouble *> tmp(2); + tmp[0]=a1; tmp[1]=a2; + 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. + * If the number of non null of elements in \a arr is equal to one the returned object is a copy of it + * not the object itself. + * \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<const DataArrayDouble *>& arr) +{ + std::vector<const DataArrayDouble *> a; + for(std::vector<const DataArrayDouble *>::const_iterator it4=arr.begin();it4!=arr.end();it4++) + if(*it4) + a.push_back(*it4); + if(a.empty()) + throw INTERP_KERNEL::Exception("DataArrayDouble::Aggregate : input list must contain at least one NON EMPTY DataArrayDouble !"); + std::vector<const DataArrayDouble *>::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("DataArrayDouble::Aggregate : Nb of components mismatch for array aggregation !"); + nbt+=(*it)->getNumberOfTuples(); + } + MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> 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.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) +{ + std::vector<const DataArrayDouble *> arr(2); + arr[0]=a1; arr[1]=a2; + 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<const DataArrayDouble *>& arr) +{ + std::vector<const DataArrayDouble *> a; + for(std::vector<const DataArrayDouble *>::const_iterator it4=arr.begin();it4!=arr.end();it4++) + if(*it4) + a.push_back(*it4); + if(a.empty()) + throw INTERP_KERNEL::Exception("DataArrayDouble::Meld : input list must contain at least one NON EMPTY DataArrayDouble !"); + std::vector<const DataArrayDouble *>::const_iterator it; + for(it=a.begin();it!=a.end();it++) + (*it)->checkAllocated(); + it=a.begin(); + int nbOfTuples=(*it)->getNumberOfTuples(); + std::vector<int> nbc(a.size()); + std::vector<const double *> 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("DataArrayDouble::Meld : mismatch of number of tuples !"); + nbc[i]=(*it)->getNumberOfComponents(); + pts[i]=(*it)->getConstPointer(); + } + int totalNbOfComp=std::accumulate(nbc.begin(),nbc.end(),0); + DataArrayDouble *ret=DataArrayDouble::New(); + ret->alloc(nbOfTuples,totalNbOfComp); + double *retPtr=ret->getPointer(); + for(int i=0;i<nbOfTuples;i++) + for(int j=0;j<(int)a.size();j++) + { + retPtr=std::copy(pts[j],pts[j]+nbc[j],retPtr); + pts[j]+=nbc[j]; + } + int k=0; + for(int i=0;i<(int)a.size();i++) + for(int j=0;j<nbc[i];j++,k++) + ret->setInfoOnComponent(k,a[i]->getInfoOnComponent(j)); + return ret; +} + +/*! + * Returns a new DataArrayDouble containing a dot product of two given arrays, so that + * the i-th tuple of the result array is a sum of products of j-th components of i-th + * tuples of given arrays (\f$ a_i = \sum_{j=1}^n a1_j * a2_j \f$). + * Info on components and name 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 - 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 any given array is not allocated. + * \throw If \a a1->getNumberOfTuples() != \a a2->getNumberOfTuples() + * \throw If \a a1->getNumberOfComponents() != \a a2->getNumberOfComponents() + */ +DataArrayDouble *DataArrayDouble::Dot(const DataArrayDouble *a1, const DataArrayDouble *a2) +{ + if(!a1 || !a2) + throw INTERP_KERNEL::Exception("DataArrayDouble::Dot : input DataArrayDouble instance is NULL !"); + a1->checkAllocated(); + a2->checkAllocated(); + int nbOfComp=a1->getNumberOfComponents(); + if(nbOfComp!=a2->getNumberOfComponents()) + throw INTERP_KERNEL::Exception("Nb of components mismatch for array Dot !"); + int nbOfTuple=a1->getNumberOfTuples(); + if(nbOfTuple!=a2->getNumberOfTuples()) + throw INTERP_KERNEL::Exception("Nb of tuples mismatch for array Dot !"); + DataArrayDouble *ret=DataArrayDouble::New(); + ret->alloc(nbOfTuple,1); + double *retPtr=ret->getPointer(); + const double *a1Ptr=a1->getConstPointer(); + const double *a2Ptr=a2->getConstPointer(); + for(int i=0;i<nbOfTuple;i++) + { + double sum=0.; + for(int j=0;j<nbOfComp;j++) + sum+=a1Ptr[i*nbOfComp+j]*a2Ptr[i*nbOfComp+j]; + retPtr[i]=sum; + } + ret->setInfoOnComponent(0,a1->getInfoOnComponent(0)); + ret->setName(a1->getName()); + 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) +{ + if(!a1 || !a2) + throw INTERP_KERNEL::Exception("DataArrayDouble::CrossProduct : input DataArrayDouble instance is NULL !"); + int nbOfComp=a1->getNumberOfComponents(); + if(nbOfComp!=a2->getNumberOfComponents()) + throw INTERP_KERNEL::Exception("Nb of components mismatch for array crossProduct !"); + if(nbOfComp!=3) + throw INTERP_KERNEL::Exception("Nb of components must be equal to 3 for array crossProduct !"); + int nbOfTuple=a1->getNumberOfTuples(); + if(nbOfTuple!=a2->getNumberOfTuples()) + throw INTERP_KERNEL::Exception("Nb of tuples mismatch for array crossProduct !"); + DataArrayDouble *ret=DataArrayDouble::New(); + ret->alloc(nbOfTuple,3); + double *retPtr=ret->getPointer(); + const double *a1Ptr=a1->getConstPointer(); + const double *a2Ptr=a2->getConstPointer(); + for(int i=0;i<nbOfTuple;i++) + { + retPtr[3*i]=a1Ptr[3*i+1]*a2Ptr[3*i+2]-a1Ptr[3*i+2]*a2Ptr[3*i+1]; + retPtr[3*i+1]=a1Ptr[3*i+2]*a2Ptr[3*i]-a1Ptr[3*i]*a2Ptr[3*i+2]; + retPtr[3*i+2]=a1Ptr[3*i]*a2Ptr[3*i+1]-a1Ptr[3*i+1]*a2Ptr[3*i]; + } + ret->copyStringInfoFrom(*a1); + 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) +{ + if(!a1 || !a2) + throw INTERP_KERNEL::Exception("DataArrayDouble::Max : input DataArrayDouble instance is NULL !"); + int nbOfComp=a1->getNumberOfComponents(); + if(nbOfComp!=a2->getNumberOfComponents()) + throw INTERP_KERNEL::Exception("Nb of components mismatch for array Max !"); + int nbOfTuple=a1->getNumberOfTuples(); + if(nbOfTuple!=a2->getNumberOfTuples()) + throw INTERP_KERNEL::Exception("Nb of tuples mismatch for array Max !"); + DataArrayDouble *ret=DataArrayDouble::New(); + ret->alloc(nbOfTuple,nbOfComp); + double *retPtr=ret->getPointer(); + const double *a1Ptr=a1->getConstPointer(); + const double *a2Ptr=a2->getConstPointer(); + int nbElem=nbOfTuple*nbOfComp; + for(int i=0;i<nbElem;i++) + retPtr[i]=std::max(a1Ptr[i],a2Ptr[i]); + ret->copyStringInfoFrom(*a1); + 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) +{ + if(!a1 || !a2) + throw INTERP_KERNEL::Exception("DataArrayDouble::Min : input DataArrayDouble instance is NULL !"); + int nbOfComp=a1->getNumberOfComponents(); + if(nbOfComp!=a2->getNumberOfComponents()) + throw INTERP_KERNEL::Exception("Nb of components mismatch for array min !"); + int nbOfTuple=a1->getNumberOfTuples(); + if(nbOfTuple!=a2->getNumberOfTuples()) + throw INTERP_KERNEL::Exception("Nb of tuples mismatch for array min !"); + DataArrayDouble *ret=DataArrayDouble::New(); + ret->alloc(nbOfTuple,nbOfComp); + double *retPtr=ret->getPointer(); + const double *a1Ptr=a1->getConstPointer(); + const double *a2Ptr=a2->getConstPointer(); + int nbElem=nbOfTuple*nbOfComp; + for(int i=0;i<nbElem;i++) + retPtr[i]=std::min(a1Ptr[i],a2Ptr[i]); + ret->copyStringInfoFrom(*a1); + 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) +{ + if(!a1 || !a2) + throw INTERP_KERNEL::Exception("DataArrayDouble::Add : input DataArrayDouble instance is NULL !"); + int nbOfTuple=a1->getNumberOfTuples(); + int nbOfTuple2=a2->getNumberOfTuples(); + int nbOfComp=a1->getNumberOfComponents(); + int nbOfComp2=a2->getNumberOfComponents(); + MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=0; + if(nbOfTuple==nbOfTuple2) + { + if(nbOfComp==nbOfComp2) + { + ret=DataArrayDouble::New(); + ret->alloc(nbOfTuple,nbOfComp); + std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::plus<double>()); + ret->copyStringInfoFrom(*a1); + } + else + { + int nbOfCompMin,nbOfCompMax; + const DataArrayDouble *aMin, *aMax; + if(nbOfComp>nbOfComp2) + { + nbOfCompMin=nbOfComp2; nbOfCompMax=nbOfComp; + aMin=a2; aMax=a1; + } + else + { + nbOfCompMin=nbOfComp; nbOfCompMax=nbOfComp2; + aMin=a1; aMax=a2; + } + if(nbOfCompMin==1) + { + ret=DataArrayDouble::New(); + ret->alloc(nbOfTuple,nbOfCompMax); + const double *aMinPtr=aMin->getConstPointer(); + const double *aMaxPtr=aMax->getConstPointer(); + double *res=ret->getPointer(); + for(int i=0;i<nbOfTuple;i++) + res=std::transform(aMaxPtr+i*nbOfCompMax,aMaxPtr+(i+1)*nbOfCompMax,res,std::bind2nd(std::plus<double>(),aMinPtr[i])); + ret->copyStringInfoFrom(*aMax); + } + else + throw INTERP_KERNEL::Exception("Nb of components mismatch for array Add !"); + } + } + else if((nbOfTuple==1 && nbOfTuple2>1) || (nbOfTuple>1 && nbOfTuple2==1)) + { + if(nbOfComp==nbOfComp2) + { + int nbOfTupleMax=std::max(nbOfTuple,nbOfTuple2); + const DataArrayDouble *aMin=nbOfTuple>nbOfTuple2?a2:a1; + const DataArrayDouble *aMax=nbOfTuple>nbOfTuple2?a1:a2; + const double *aMinPtr=aMin->getConstPointer(),*aMaxPtr=aMax->getConstPointer(); + ret=DataArrayDouble::New(); + ret->alloc(nbOfTupleMax,nbOfComp); + double *res=ret->getPointer(); + for(int i=0;i<nbOfTupleMax;i++) + res=std::transform(aMaxPtr+i*nbOfComp,aMaxPtr+(i+1)*nbOfComp,aMinPtr,res,std::plus<double>()); + ret->copyStringInfoFrom(*aMax); + } + else + throw INTERP_KERNEL::Exception("Nb of components mismatch for array Add !"); + } + else + throw INTERP_KERNEL::Exception("Nb of tuples mismatch for array Add !"); + 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) +{ + 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(); + int nbOfComp2=other->getNumberOfComponents(); + if(nbOfTuple==nbOfTuple2) + { + if(nbOfComp==nbOfComp2) + { + std::transform(begin(),end(),other->begin(),getPointer(),std::plus<double>()); + } + else if(nbOfComp2==1) + { + double *ptr=getPointer(); + const double *ptrc=other->getConstPointer(); + for(int i=0;i<nbOfTuple;i++) + std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptr+i*nbOfComp,std::bind2nd(std::plus<double>(),*ptrc++)); + } + else + throw INTERP_KERNEL::Exception(msg); + } + else if(nbOfTuple2==1) + { + if(nbOfComp2==nbOfComp) + { + double *ptr=getPointer(); + const double *ptrc=other->getConstPointer(); + for(int i=0;i<nbOfTuple;i++) + std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptrc,ptr+i*nbOfComp,std::plus<double>()); + } + else + throw INTERP_KERNEL::Exception(msg); + } + else + throw INTERP_KERNEL::Exception(msg); + 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) +{ + if(!a1 || !a2) + throw INTERP_KERNEL::Exception("DataArrayDouble::Substract : input DataArrayDouble instance is NULL !"); + int nbOfTuple1=a1->getNumberOfTuples(); + int nbOfTuple2=a2->getNumberOfTuples(); + int nbOfComp1=a1->getNumberOfComponents(); + int nbOfComp2=a2->getNumberOfComponents(); + if(nbOfTuple2==nbOfTuple1) + { + if(nbOfComp1==nbOfComp2) + { + MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New(); + ret->alloc(nbOfTuple2,nbOfComp1); + std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::minus<double>()); + ret->copyStringInfoFrom(*a1); + return ret.retn(); + } + else if(nbOfComp2==1) + { + MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New(); + ret->alloc(nbOfTuple1,nbOfComp1); + const double *a2Ptr=a2->getConstPointer(); + const double *a1Ptr=a1->getConstPointer(); + double *res=ret->getPointer(); + for(int i=0;i<nbOfTuple1;i++) + res=std::transform(a1Ptr+i*nbOfComp1,a1Ptr+(i+1)*nbOfComp1,res,std::bind2nd(std::minus<double>(),a2Ptr[i])); + ret->copyStringInfoFrom(*a1); + return ret.retn(); + } + else + { + a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Substract !"); + return 0; + } + } + else if(nbOfTuple2==1) + { + a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Substract !"); + MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New(); + ret->alloc(nbOfTuple1,nbOfComp1); + const double *a1ptr=a1->getConstPointer(),*a2ptr=a2->getConstPointer(); + double *pt=ret->getPointer(); + for(int i=0;i<nbOfTuple1;i++) + pt=std::transform(a1ptr+i*nbOfComp1,a1ptr+(i+1)*nbOfComp1,a2ptr,pt,std::minus<double>()); + ret->copyStringInfoFrom(*a1); + return ret.retn(); + } + else + { + a1->checkNbOfTuples(nbOfTuple2,"Nb of tuples mismatch for array Substract !");//will always throw an exception + return 0; + } +} + +/*! + * 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) +{ + 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(); + int nbOfComp2=other->getNumberOfComponents(); + if(nbOfTuple==nbOfTuple2) + { + if(nbOfComp==nbOfComp2) + { + std::transform(begin(),end(),other->begin(),getPointer(),std::minus<double>()); + } + else if(nbOfComp2==1) + { + double *ptr=getPointer(); + const double *ptrc=other->getConstPointer(); + for(int i=0;i<nbOfTuple;i++) + std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptr+i*nbOfComp,std::bind2nd(std::minus<double>(),*ptrc++)); + } + else + throw INTERP_KERNEL::Exception(msg); + } + else if(nbOfTuple2==1) + { + if(nbOfComp2==nbOfComp) + { + double *ptr=getPointer(); + const double *ptrc=other->getConstPointer(); + for(int i=0;i<nbOfTuple;i++) + std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptrc,ptr+i*nbOfComp,std::minus<double>()); + } + else + throw INTERP_KERNEL::Exception(msg); + } + else + throw INTERP_KERNEL::Exception(msg); + 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) +{ + if(!a1 || !a2) + throw INTERP_KERNEL::Exception("DataArrayDouble::Multiply : input DataArrayDouble instance is NULL !"); + int nbOfTuple=a1->getNumberOfTuples(); + int nbOfTuple2=a2->getNumberOfTuples(); + int nbOfComp=a1->getNumberOfComponents(); + int nbOfComp2=a2->getNumberOfComponents(); + MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=0; + if(nbOfTuple==nbOfTuple2) + { + if(nbOfComp==nbOfComp2) + { + ret=DataArrayDouble::New(); + ret->alloc(nbOfTuple,nbOfComp); + std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::multiplies<double>()); + ret->copyStringInfoFrom(*a1); + } + else + { + int nbOfCompMin,nbOfCompMax; + const DataArrayDouble *aMin, *aMax; + if(nbOfComp>nbOfComp2) + { + nbOfCompMin=nbOfComp2; nbOfCompMax=nbOfComp; + aMin=a2; aMax=a1; + } + else + { + nbOfCompMin=nbOfComp; nbOfCompMax=nbOfComp2; + aMin=a1; aMax=a2; + } + if(nbOfCompMin==1) + { + ret=DataArrayDouble::New(); + ret->alloc(nbOfTuple,nbOfCompMax); + const double *aMinPtr=aMin->getConstPointer(); + const double *aMaxPtr=aMax->getConstPointer(); + double *res=ret->getPointer(); + for(int i=0;i<nbOfTuple;i++) + res=std::transform(aMaxPtr+i*nbOfCompMax,aMaxPtr+(i+1)*nbOfCompMax,res,std::bind2nd(std::multiplies<double>(),aMinPtr[i])); + ret->copyStringInfoFrom(*aMax); + } + else + throw INTERP_KERNEL::Exception("Nb of components mismatch for array Multiply !"); + } + } + else if((nbOfTuple==1 && nbOfTuple2>1) || (nbOfTuple>1 && nbOfTuple2==1)) + { + if(nbOfComp==nbOfComp2) + { + int nbOfTupleMax=std::max(nbOfTuple,nbOfTuple2); + const DataArrayDouble *aMin=nbOfTuple>nbOfTuple2?a2:a1; + const DataArrayDouble *aMax=nbOfTuple>nbOfTuple2?a1:a2; + const double *aMinPtr=aMin->getConstPointer(),*aMaxPtr=aMax->getConstPointer(); + ret=DataArrayDouble::New(); + ret->alloc(nbOfTupleMax,nbOfComp); + double *res=ret->getPointer(); + for(int i=0;i<nbOfTupleMax;i++) + res=std::transform(aMaxPtr+i*nbOfComp,aMaxPtr+(i+1)*nbOfComp,aMinPtr,res,std::multiplies<double>()); + ret->copyStringInfoFrom(*aMax); + } + else + throw INTERP_KERNEL::Exception("Nb of components mismatch for array Multiply !"); + } + else + throw INTERP_KERNEL::Exception("Nb of tuples mismatch for array Multiply !"); + 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) +{ + 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(); + int nbOfComp2=other->getNumberOfComponents(); + if(nbOfTuple==nbOfTuple2) + { + if(nbOfComp==nbOfComp2) + { + std::transform(begin(),end(),other->begin(),getPointer(),std::multiplies<double>()); + } + else if(nbOfComp2==1) + { + double *ptr=getPointer(); + const double *ptrc=other->getConstPointer(); + for(int i=0;i<nbOfTuple;i++) + std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptr+i*nbOfComp,std::bind2nd(std::multiplies<double>(),*ptrc++)); + } + else + throw INTERP_KERNEL::Exception(msg); + } + else if(nbOfTuple2==1) + { + if(nbOfComp2==nbOfComp) + { + double *ptr=getPointer(); + const double *ptrc=other->getConstPointer(); + for(int i=0;i<nbOfTuple;i++) + std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptrc,ptr+i*nbOfComp,std::multiplies<double>()); + } + else + throw INTERP_KERNEL::Exception(msg); + } + else + throw INTERP_KERNEL::Exception(msg); + 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) +{ + if(!a1 || !a2) + throw INTERP_KERNEL::Exception("DataArrayDouble::Divide : input DataArrayDouble instance is NULL !"); + int nbOfTuple1=a1->getNumberOfTuples(); + int nbOfTuple2=a2->getNumberOfTuples(); + int nbOfComp1=a1->getNumberOfComponents(); + int nbOfComp2=a2->getNumberOfComponents(); + if(nbOfTuple2==nbOfTuple1) + { + if(nbOfComp1==nbOfComp2) + { + MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New(); + ret->alloc(nbOfTuple2,nbOfComp1); + std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::divides<double>()); + ret->copyStringInfoFrom(*a1); + return ret.retn(); + } + else if(nbOfComp2==1) + { + MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New(); + ret->alloc(nbOfTuple1,nbOfComp1); + const double *a2Ptr=a2->getConstPointer(); + const double *a1Ptr=a1->getConstPointer(); + double *res=ret->getPointer(); + for(int i=0;i<nbOfTuple1;i++) + res=std::transform(a1Ptr+i*nbOfComp1,a1Ptr+(i+1)*nbOfComp1,res,std::bind2nd(std::divides<double>(),a2Ptr[i])); + ret->copyStringInfoFrom(*a1); + return ret.retn(); + } + else + { + a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Divide !"); + return 0; + } + } + else if(nbOfTuple2==1) + { + a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Divide !"); + MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New(); + ret->alloc(nbOfTuple1,nbOfComp1); + const double *a1ptr=a1->getConstPointer(),*a2ptr=a2->getConstPointer(); + double *pt=ret->getPointer(); + for(int i=0;i<nbOfTuple1;i++) + pt=std::transform(a1ptr+i*nbOfComp1,a1ptr+(i+1)*nbOfComp1,a2ptr,pt,std::divides<double>()); + ret->copyStringInfoFrom(*a1); + return ret.retn(); + } + else + { + a1->checkNbOfTuples(nbOfTuple2,"Nb of tuples mismatch for array Divide !");//will always throw an exception + return 0; + } +} + +/*! + * 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) +{ + 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(); + int nbOfComp2=other->getNumberOfComponents(); + if(nbOfTuple==nbOfTuple2) + { + if(nbOfComp==nbOfComp2) + { + std::transform(begin(),end(),other->begin(),getPointer(),std::divides<double>()); + } + else if(nbOfComp2==1) + { + double *ptr=getPointer(); + const double *ptrc=other->getConstPointer(); + for(int i=0;i<nbOfTuple;i++) + std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptr+i*nbOfComp,std::bind2nd(std::divides<double>(),*ptrc++)); + } + else + throw INTERP_KERNEL::Exception(msg); + } + else if(nbOfTuple2==1) + { + if(nbOfComp2==nbOfComp) + { + double *ptr=getPointer(); + const double *ptrc=other->getConstPointer(); + for(int i=0;i<nbOfTuple;i++) + std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptrc,ptr+i*nbOfComp,std::divides<double>()); + } + else + throw INTERP_KERNEL::Exception(msg); + } + else + throw INTERP_KERNEL::Exception(msg); + 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) +{ + 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<DataArrayDouble> ret=DataArrayDouble::New(); ret->alloc(nbOfTuple,1); + const double *ptr1(a1->begin()),*ptr2(a2->begin()); + double *ptr=ret->getPointer(); + for(int i=0;i<nbOfTuple;i++,ptr1++,ptr2++,ptr++) + { + if(*ptr1>=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) +{ + 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<nbOfTuple;i++,ptrc++,ptr++) + { + if(*ptr>=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(); +} + +/*! + * This method is \b NOT wrapped into python because it can be useful only for performance reasons in C++ context. + * All values in \a this must be 0. or 1. within eps error. 0 means false, 1 means true. + * If an another value than 0 or 1 appear (within eps precision) an INTERP_KERNEL::Exception will be thrown. + * + * \throw if \a this is not allocated. + * \throw if \a this has not exactly one component. + */ +std::vector<bool> DataArrayDouble::toVectorOfBool(double eps) const +{ + checkAllocated(); + if(getNumberOfComponents()!=1) + throw INTERP_KERNEL::Exception("DataArrayDouble::toVectorOfBool : must be applied on single component array !"); + int nbt(getNumberOfTuples()); + std::vector<bool> ret(nbt); + const double *pt(begin()); + for(int i=0;i<nbt;i++) + { + if(fabs(pt[i])<eps) + ret[i]=false; + else if(fabs(pt[i]-1.)<eps) + ret[i]=true; + else + { + std::ostringstream oss; oss << "DataArrayDouble::toVectorOfBool : the tuple #" << i << " has value " << pt[i] << " is invalid ! must be 0. or 1. !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + } + return ret; +} + +/*! + * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class. + * Server side. + */ +void DataArrayDouble::getTinySerializationIntInformation(std::vector<int>& tinyInfo) const +{ + tinyInfo.resize(2); + if(isAllocated()) + { + tinyInfo[0]=getNumberOfTuples(); + tinyInfo[1]=getNumberOfComponents(); + } + else + { + tinyInfo[0]=-1; + tinyInfo[1]=-1; + } +} + +/*! + * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class. + * Server side. + */ +void DataArrayDouble::getTinySerializationStrInformation(std::vector<std::string>& tinyInfo) const +{ + if(isAllocated()) + { + int nbOfCompo=getNumberOfComponents(); + tinyInfo.resize(nbOfCompo+1); + tinyInfo[0]=getName(); + for(int i=0;i<nbOfCompo;i++) + tinyInfo[i+1]=getInfoOnComponent(i); + } + else + { + tinyInfo.resize(1); + tinyInfo[0]=getName(); + } +} + +/*! + * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class. + * This method returns if a feeding is needed. + */ +bool DataArrayDouble::resizeForUnserialization(const std::vector<int>& tinyInfoI) +{ + int nbOfTuple=tinyInfoI[0]; + int nbOfComp=tinyInfoI[1]; + if(nbOfTuple!=-1 || nbOfComp!=-1) + { + alloc(nbOfTuple,nbOfComp); + return true; + } + return false; +} + +/*! + * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class. + */ +void DataArrayDouble::finishUnserialization(const std::vector<int>& tinyInfoI, const std::vector<std::string>& tinyInfoS) +{ + setName(tinyInfoS[0]); + if(isAllocated()) + { + int nbOfCompo=getNumberOfComponents(); + for(int i=0;i<nbOfCompo;i++) + setInfoOnComponent(i,tinyInfoS[i+1]); + } +} + +DataArrayDoubleIterator::DataArrayDoubleIterator(DataArrayDouble *da):_da(da),_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(); + } + } +} + +DataArrayDoubleIterator::~DataArrayDoubleIterator() +{ + if(_da) + _da->decrRef(); +} + +DataArrayDoubleTuple *DataArrayDoubleIterator::nextt() +{ + if(_tuple_id<_nb_tuple) + { + _tuple_id++; + DataArrayDoubleTuple *ret=new DataArrayDoubleTuple(_pt,_nb_comp); + _pt+=_nb_comp; + return ret; + } + else + return 0; +} + +DataArrayDoubleTuple::DataArrayDoubleTuple(double *pt, int nbOfComp):_pt(pt),_nb_of_compo(nbOfComp) +{ +} + + +std::string DataArrayDoubleTuple::repr() const +{ + std::ostringstream oss; oss.precision(17); oss << "("; + for(int i=0;i<_nb_of_compo-1;i++) + oss << _pt[i] << ", "; + oss << _pt[_nb_of_compo-1] << ")"; + return oss.str(); +} + +double DataArrayDoubleTuple::doubleValue() const +{ + if(_nb_of_compo==1) + return *_pt; + throw INTERP_KERNEL::Exception("DataArrayDoubleTuple::doubleValue : DataArrayDoubleTuple instance has not exactly 1 component -> Not possible to convert it into a double precision float !"); +} + +/*! + * This method returns a newly allocated instance the caller should dealed with by a ParaMEDMEM::DataArrayDouble::decrRef. + * This method performs \b no copy of data. The content is only referenced using ParaMEDMEM::DataArrayDouble::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. + */ +DataArrayDouble *DataArrayDoubleTuple::buildDADouble(int nbOfTuples, int nbOfCompo) const +{ + if((_nb_of_compo==nbOfCompo && nbOfTuples==1) || (_nb_of_compo==nbOfTuples && nbOfCompo==1)) + { + DataArrayDouble *ret=DataArrayDouble::New(); + ret->useExternalArrayWithRWAccess(_pt,nbOfTuples,nbOfCompo); + return ret; + } + else + { + std::ostringstream oss; oss << "DataArrayDoubleTuple::buildDADouble : unable to build a requested DataArrayDouble 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 DataArrayInt. The caller is to delete this array + * using decrRef() as it is no more needed. + */ +DataArrayInt *DataArrayInt::New() +{ + return new DataArrayInt; +} + +/*! + * 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 +{ + 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 +{ + if(!isAllocated()) + throw INTERP_KERNEL::Exception("DataArrayInt::checkAllocated : Array is defined but not allocated ! Call alloc or setValues method first !"); +} + +/*! + * This method desallocated \a this without modification of informations relative to the components. + * After call of this method, DataArrayInt::isAllocated will return false. + * If \a this is already not allocated, \a this is let unchanged. + */ +void DataArrayInt::desallocate() +{ + _mem.destroy(); +} + +std::size_t DataArrayInt::getHeapMemorySizeWithoutChildren() const +{ + std::size_t sz(_mem.getNbOfElemAllocated()); + sz*=sizeof(int); + return DataArray::getHeapMemorySizeWithoutChildren()+sz; +} + +/*! + * 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 +{ + if(isAllocated()) + { + if(getNbOfElems()==1) + { + return *getConstPointer(); + } + else + throw INTERP_KERNEL::Exception("DataArrayInt::intValue : DataArrayInt instance is allocated but number of elements is not equal to 1 !"); + } + else + throw INTERP_KERNEL::Exception("DataArrayInt::intValue : DataArrayInt instance is not allocated !"); +} + +/*! + * 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 +{ + checkAllocated(); + 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(std::size_t i=0;i<nbOfElems;i+=delta) + ret0+=pt[i] & 0x1FFF; + return ret+ret0; +} + +/*! + * Checks the number of tuples. + * \return bool - \a true if getNumberOfTuples() == 0, \a false else. + * \throw If \a this is not allocated. + */ +bool DataArrayInt::empty() const +{ + checkAllocated(); + return getNumberOfTuples()==0; +} + +/*! + * Returns a full copy of \a this. For more info on copying data arrays see + * \ref MEDCouplingArrayBasicsCopyDeep. + * \return DataArrayInt * - a new instance of DataArrayInt. + */ +DataArrayInt *DataArrayInt::deepCpy() const +{ + return new DataArrayInt(*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 DataArrayInt * - either a new instance of DataArrayInt (if \a dCpy + * == \a true) or \a this instance (if \a dCpy == \a false). + */ +DataArrayInt *DataArrayInt::performCpy(bool dCpy) const +{ + if(dCpy) + return deepCpy(); + else + { + incrRef(); + return const_cast<DataArrayInt *>(this); + } +} + +/*! + * Copies all the data from another DataArrayInt. For more info see + * \ref MEDCouplingArrayBasicsCopyDeepAssign. + * \param [in] other - another instance of DataArrayInt to copy data from. + * \throw If the \a other is not allocated. + */ +void DataArrayInt::cpyFrom(const DataArrayInt& other) +{ + other.checkAllocated(); + int nbOfTuples=other.getNumberOfTuples(); + int nbOfComp=other.getNumberOfComponents(); + allocIfNecessary(nbOfTuples,nbOfComp); + std::size_t nbOfElems=(std::size_t)nbOfTuples*nbOfComp; + int *pt=getPointer(); + const int *ptI=other.getConstPointer(); + for(std::size_t i=0;i<nbOfElems;i++) + pt[i]=ptI[i]; + copyStringInfoFrom(other); +} + +/*! + * This method reserve nbOfElems elements in memory ( nbOfElems*4 bytes ) \b without impacting the number of tuples in \a this. + * If \a this has already been allocated, this method checks that \a this has only one component. If not an INTERP_KERNEL::Exception will be thrown. + * If \a this has not already been allocated, number of components is set to one. + * This method allows to reduce number of reallocations on invokation of DataArrayInt::pushBackSilent and DataArrayInt::pushBackValsSilent on \a this. + * + * \sa DataArrayInt::pack, DataArrayInt::pushBackSilent, DataArrayInt::pushBackValsSilent + */ +void DataArrayInt::reserve(std::size_t nbOfElems) +{ + int nbCompo=getNumberOfComponents(); + if(nbCompo==1) + { + _mem.reserve(nbOfElems); + } + else if(nbCompo==0) + { + _mem.reserve(nbOfElems); + _info_on_compo.resize(1); + } + else + throw INTERP_KERNEL::Exception("DataArrayInt::reserve : not available for DataArrayInt with number of components different than 1 !"); +} + +/*! + * This method adds at the end of \a this the single value \a val. This method do \b not update its time label to avoid useless incrementation + * of counter. So the caller is expected to call TimeLabel::declareAsNew on \a this at the end of the push session. + * + * \param [in] val the value to be added in \a this + * \throw If \a this has already been allocated with number of components different from one. + * \sa DataArrayInt::pushBackValsSilent + */ +void DataArrayInt::pushBackSilent(int val) +{ + int nbCompo=getNumberOfComponents(); + if(nbCompo==1) + _mem.pushBack(val); + else if(nbCompo==0) + { + _info_on_compo.resize(1); + _mem.pushBack(val); + } + else + throw INTERP_KERNEL::Exception("DataArrayInt::pushBackSilent : not available for DataArrayInt with number of components different than 1 !"); +} + +/*! + * This method adds at the end of \a this a serie of values [\c valsBg,\c valsEnd). This method do \b not update its time label to avoid useless incrementation + * of counter. So the caller is expected to call TimeLabel::declareAsNew on \a this at the end of the push session. + * + * \param [in] valsBg - an array of values to push at the end of \c this. + * \param [in] valsEnd - specifies the end of the array \a valsBg, so that + * the last value of \a valsBg is \a valsEnd[ -1 ]. + * \throw If \a this has already been allocated with number of components different from one. + * \sa DataArrayInt::pushBackSilent + */ +void DataArrayInt::pushBackValsSilent(const int *valsBg, const int *valsEnd) +{ + int nbCompo=getNumberOfComponents(); + if(nbCompo==1) + _mem.insertAtTheEnd(valsBg,valsEnd); + else if(nbCompo==0) + { + _info_on_compo.resize(1); + _mem.insertAtTheEnd(valsBg,valsEnd); + } + else + throw INTERP_KERNEL::Exception("DataArrayInt::pushBackValsSilent : not available for DataArrayInt with number of components different than 1 !"); +} + +/*! + * This method returns silently ( without updating time label in \a this ) the last value, if any and suppress it. + * \throw If \a this is already empty. + * \throw If \a this has number of components different from one. + */ +int DataArrayInt::popBackSilent() +{ + if(getNumberOfComponents()==1) + return _mem.popBack(); + else + throw INTERP_KERNEL::Exception("DataArrayInt::popBackSilent : not available for DataArrayInt with number of components different than 1 !"); +} + +/*! + * This method \b do \b not modify content of \a this. It only modify its memory footprint if the allocated memory is to high regarding real data to store. + * + * \sa DataArrayInt::getHeapMemorySizeWithoutChildren, DataArrayInt::reserve + */ +void DataArrayInt::pack() const +{ + _mem.pack(); +} + +/*! + * Allocates the raw data in memory. If exactly as same memory as needed already + * allocated, it is not re-allocated. + * \param [in] nbOfTuple - number of tuples of data to allocate. + * \param [in] nbOfCompo - number of components of data to allocate. + * \throw If \a nbOfTuple < 0 or \a nbOfCompo < 0. + */ +void DataArrayInt::allocIfNecessary(int nbOfTuple, int nbOfCompo) +{ + if(isAllocated()) + { + if(nbOfTuple!=getNumberOfTuples() || nbOfCompo!=getNumberOfComponents()) + alloc(nbOfTuple,nbOfCompo); + } + else + alloc(nbOfTuple,nbOfCompo); +} + +/*! + * Allocates the raw data in memory. If the memory was already allocated, then it is + * freed and re-allocated. See an example of this method use + * \ref MEDCouplingArraySteps1WC "here". + * \param [in] nbOfTuple - number of tuples of data to allocate. + * \param [in] nbOfCompo - number of components of data to allocate. + * \throw If \a nbOfTuple < 0 or \a nbOfCompo < 0. + */ +void DataArrayInt::alloc(int nbOfTuple, int nbOfCompo) +{ + if(nbOfTuple<0 || nbOfCompo<0) + throw INTERP_KERNEL::Exception("DataArrayInt::alloc : request for negative length of data !"); + _info_on_compo.resize(nbOfCompo); + _mem.alloc(nbOfCompo*(std::size_t)nbOfTuple); + 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 DataArrayInt::fillWithZero() +{ + 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 DataArrayInt::fillWithValue(int val) +{ + checkAllocated(); + _mem.fillWithValue(val); + declareAsNew(); +} + +/*! + * Set all values in \a this array so that the i-th element equals to \a init + i + * (i starts from zero). To know more on filling arrays see \ref MEDCouplingArrayFill. + * \param [in] init - value to assign to the first element of array. + * \throw If \a this->getNumberOfComponents() != 1 + * \throw If \a this is not allocated. + */ +void DataArrayInt::iota(int init) +{ + checkAllocated(); + if(getNumberOfComponents()!=1) + throw INTERP_KERNEL::Exception("DataArrayInt::iota : works only for arrays with only one component, you can call 'rearrange' method before !"); + int *ptr=getPointer(); + int ntuples=getNumberOfTuples(); + for(int i=0;i<ntuples;i++) + ptr[i]=init+i; + declareAsNew(); +} + +/*! + * 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. + * + * \sa reprNotTooLong, reprZip + */ +std::string DataArrayInt::repr() const +{ + std::ostringstream ret; + reprStream(ret); + return ret.str(); +} + +std::string DataArrayInt::reprZip() const +{ + std::ostringstream ret; + reprZipStream(ret); + return ret.str(); +} + +/*! + * This method is close to repr method except that when \a this has more than 1000 tuples, all tuples are not + * printed out to avoid to consume too much space in interpretor. + * \sa repr + */ +std::string DataArrayInt::reprNotTooLong() const +{ + std::ostringstream ret; + reprNotTooLongStream(ret); + return ret.str(); +} + +void DataArrayInt::writeVTK(std::ostream& ofs, int indent, const std::string& type, const std::string& nameInFile, DataArrayByte *byteArr) const +{ + static const char SPACE[4]={' ',' ',' ',' '}; + checkAllocated(); + std::string idt(indent,' '); + ofs << idt << "<DataArray type=\"" << type << "\" Name=\"" << nameInFile << "\" NumberOfComponents=\"" << getNumberOfComponents() << "\""; + if(byteArr) + { + ofs << " format=\"appended\" offset=\"" << byteArr->getNumberOfTuples() << "\">"; + if(std::string(type)=="Int32") + { + const char *data(reinterpret_cast<const char *>(begin())); + std::size_t sz(getNbOfElems()*sizeof(int)); + byteArr->insertAtTheEnd(data,data+sz); + byteArr->insertAtTheEnd(SPACE,SPACE+4); + } + else if(std::string(type)=="Int8") + { + INTERP_KERNEL::AutoPtr<char> tmp(new char[getNbOfElems()]); + std::copy(begin(),end(),(char *)tmp); + byteArr->insertAtTheEnd((char *)tmp,(char *)tmp+getNbOfElems()); + byteArr->insertAtTheEnd(SPACE,SPACE+4); + } + else if(std::string(type)=="UInt8") + { + INTERP_KERNEL::AutoPtr<unsigned char> tmp(new unsigned char[getNbOfElems()]); + std::copy(begin(),end(),(unsigned char *)tmp); + byteArr->insertAtTheEnd((unsigned char *)tmp,(unsigned char *)tmp+getNbOfElems()); + byteArr->insertAtTheEnd(SPACE,SPACE+4); + } + else + throw INTERP_KERNEL::Exception("DataArrayInt::writeVTK : Only Int32, Int8 and UInt8 supported !"); + } + else + { + ofs << " RangeMin=\"" << getMinValueInArray() << "\" RangeMax=\"" << getMaxValueInArray() << "\" format=\"ascii\">\n" << idt; + std::copy(begin(),end(),std::ostream_iterator<int>(ofs," ")); + } + ofs << std::endl << idt << "</DataArray>\n"; +} + +void DataArrayInt::reprStream(std::ostream& stream) const +{ + stream << "Name of int array : \"" << _name << "\"\n"; + reprWithoutNameStream(stream); +} + +void DataArrayInt::reprZipStream(std::ostream& stream) const +{ + stream << "Name of int array : \"" << _name << "\"\n"; + reprZipWithoutNameStream(stream); +} + +void DataArrayInt::reprNotTooLongStream(std::ostream& stream) const +{ + stream << "Name of int array : \"" << _name << "\"\n"; + reprNotTooLongWithoutNameStream(stream); +} + +void DataArrayInt::reprWithoutNameStream(std::ostream& stream) const +{ + DataArray::reprWithoutNameStream(stream); + _mem.repr(getNumberOfComponents(),stream); +} + +void DataArrayInt::reprZipWithoutNameStream(std::ostream& stream) const +{ + DataArray::reprWithoutNameStream(stream); + _mem.reprZip(getNumberOfComponents(),stream); +} + +void DataArrayInt::reprNotTooLongWithoutNameStream(std::ostream& stream) const +{ + DataArray::reprWithoutNameStream(stream); + stream.precision(17); + _mem.reprNotTooLong(getNumberOfComponents(),stream); +} + +void DataArrayInt::reprCppStream(const std::string& varName, std::ostream& stream) const +{ + int nbTuples=getNumberOfTuples(),nbComp=getNumberOfComponents(); + const int *data=getConstPointer(); + stream << "DataArrayInt *" << varName << "=DataArrayInt::New();" << std::endl; + if(nbTuples*nbComp>=1) + { + stream << "const int " << varName << "Data[" << nbTuples*nbComp << "]={"; + std::copy(data,data+nbTuples*nbComp-1,std::ostream_iterator<int>(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 DataArrayInt::reprQuickOverview(std::ostream& stream) const +{ + 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 +{ + 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;i<nbOfTuples && isFinished;i++) + { + if(nbOfCompo>1) + { + oss2 << "("; + for(int j=0;j<nbOfCompo;j++,data++) + { + oss2 << *data; + if(j!=nbOfCompo-1) oss2 << ", "; + } + oss2 << ")"; + } + else + oss2 << *data++; + if(i!=nbOfTuples-1) oss2 << ", "; + std::string oss3Str(oss2.str()); + if(oss3Str.length()<maxNbOfByteInRepr) + oss2Str=oss3Str; + else + isFinished=false; + } + stream << oss2Str; + if(!isFinished) + stream << "... "; + stream << "]"; +} + +/*! + * Modifies in place \a this one-dimensional array so that each value \a v = \a indArrBg[ \a v ], + * i.e. a current value is used as in index to get a new value from \a indArrBg. + * \param [in] indArrBg - pointer to the first element of array of new values to assign + * to \a this array. + * \param [in] indArrEnd - specifies the end of the array \a indArrBg, so that + * the last value of \a indArrBg is \a indArrEnd[ -1 ]. + * \throw If \a this->getNumberOfComponents() != 1 + * \throw If any value of \a this can't be used as a valid index for + * [\a indArrBg, \a indArrEnd). + * + * \sa replaceOneValByInThis + */ +void DataArrayInt::transformWithIndArr(const int *indArrBg, const int *indArrEnd) +{ + 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)),nbOfTuples(getNumberOfTuples()),*pt(getPointer()); + for(int i=0;i<nbOfTuples;i++,pt++) + { + if(*pt>=0 && *pt<nbElemsIn) + *pt=indArrBg[*pt]; + else + { + std::ostringstream oss; oss << "DataArrayInt::transformWithIndArr : error on tuple #" << i << " of this value is " << *pt << ", should be in [0," << nbElemsIn << ") !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + } + declareAsNew(); +} + +/*! + * Modifies in place \a this one-dimensional array like this : each id in \a this so that this[id] equal to \a valToBeReplaced will be replaced at the same place by \a replacedBy. + * + * \param [in] valToBeReplaced - the value in \a this to be replaced. + * \param [in] replacedBy - the value taken by each tuple previously equal to \a valToBeReplaced. + * + * \sa DataArrayInt::transformWithIndArr + */ +void DataArrayInt::replaceOneValByInThis(int valToBeReplaced, int replacedBy) +{ + checkAllocated(); + if(getNumberOfComponents()!=1) + throw INTERP_KERNEL::Exception("Call replaceOneValByInThis method on DataArrayInt with only one component, you can call 'rearrange' method before !"); + if(valToBeReplaced==replacedBy) + return ; + int nbOfTuples(getNumberOfTuples()),*pt(getPointer()); + for(int i=0;i<nbOfTuples;i++,pt++) + { + if(*pt==valToBeReplaced) + *pt=replacedBy; + } +} + +/*! + * 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] + * + * 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 +{ + 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(); + std::size_t nbOfCast=std::distance(arrBg,arrEnd); + if(nbOfCast<2) + throw INTERP_KERNEL::Exception("DataArrayInt::splitByValueRange : The input array giving the cast range values should be of size >=2 !"); + nbOfCast--; + const int *work=getConstPointer(); + typedef std::reverse_iterator<const int *> rintstart; + rintstart bg(arrEnd);//OK no problem because size of 'arr' is greater or equal 2 + rintstart end2(arrBg); + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret1=DataArrayInt::New(); + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret2=DataArrayInt::New(); + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret3=DataArrayInt::New(); + ret1->alloc(nbOfTuples,1); + ret2->alloc(nbOfTuples,1); + int *ret1Ptr=ret1->getPointer(); + int *ret2Ptr=ret2->getPointer(); + std::set<std::size_t> castsDetected; + for(int i=0;i<nbOfTuples;i++) + { + rintstart res=std::find_if(bg,end2,std::bind2nd(std::less_equal<int>(), work[i])); + std::size_t pos=std::distance(bg,res); + std::size_t pos2=nbOfCast-pos; + if(pos2<nbOfCast) + { + ret1Ptr[i]=(int)pos2; + ret2Ptr[i]=work[i]-arrBg[pos2]; + castsDetected.insert(pos2); + } + else + { + std::ostringstream oss; oss << "DataArrayInt::splitByValueRange : At rank #" << i << " the value is " << work[i] << " should be in [0," << *bg << ") !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + } + ret3->alloc((int)castsDetected.size(),1); + std::copy(castsDetected.begin(),castsDetected.end(),ret3->getPointer()); + castArr=ret1.retn(); + rankInsideCast=ret2.retn(); + castsPresent=ret3.retn(); +} + +/*! + * This method look at \a this if it can be considered as a range defined by the 3-tuple ( \a strt , \a sttoopp , \a stteepp ). + * If false is returned the tuple must be ignored. If true is returned \a this can be considered by a range( \a strt , \a sttoopp , \a stteepp ). + * This method works only if \a this is allocated and single component. If not an exception will be thrown. + * + * \param [out] strt - the start of the range (included) if true is returned. + * \param [out] sttoopp - the end of the range (not included) if true is returned. + * \param [out] stteepp - the step of the range if true is returned. + * \return the verdict of the check. + * + * \sa DataArray::GetNumberOfItemGivenBES + */ +bool DataArrayInt::isRange(int& strt, int& sttoopp, int& stteepp) const +{ + checkAllocated(); + if(getNumberOfComponents()!=1) + throw INTERP_KERNEL::Exception("DataArrayInt::isRange : this must be single component array !"); + int nbTuples(getNumberOfTuples()); + if(nbTuples==0) + { strt=0; sttoopp=0; stteepp=1; return true; } + const int *pt(begin()); + strt=*pt; + if(nbTuples==1) + { sttoopp=strt+1; stteepp=1; return true; } + strt=*pt; sttoopp=pt[nbTuples-1]; + if(strt==sttoopp) + return false; + if(sttoopp>strt) + { + sttoopp++; + int a(sttoopp-1-strt),tmp(strt); + if(a%(nbTuples-1)!=0) + return false; + stteepp=a/(nbTuples-1); + for(int i=0;i<nbTuples;i++,tmp+=stteepp) + if(pt[i]!=tmp) + return false; + return true; + } + else + { + sttoopp--; + int a(strt-sttoopp-1),tmp(strt); + if(a%(nbTuples-1)!=0) + return false; + stteepp=-(a/(nbTuples-1)); + for(int i=0;i<nbTuples;i++,tmp+=stteepp) + if(pt[i]!=tmp) + return false; + return true; + } +} + +/*! + * 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 +{ + 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); + int nbOfTuples=getNumberOfTuples(); + const int *pt=getConstPointer(); + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New(); + ret->alloc(nbOfTuples,1); + ret->fillWithValue(-1); + int *tmp=ret->getPointer(); + for(int i=0;i<nbOfTuples;i++,pt++) + { + if(*pt>=0 && *pt<nbElemsIn) + { + int pos=indArrBg[*pt]; + if(pos>=0 && pos<nbOfTuples) + tmp[pos]=i; + else + { + std::ostringstream oss; oss << "DataArrayInt::transformWithIndArrR : error on tuple #" << i << " value of new pos is " << pos << " ( indArrBg[" << *pt << "]) ! Should be in [0," << nbOfTuples << ") !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + } + else + { + std::ostringstream oss; oss << "DataArrayInt::transformWithIndArrR : error on tuple #" << i << " value is " << *pt << " and indirectionnal array as a size equal to " << nbElemsIn << " !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + } + 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 + * "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 numbering. + * \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. + * + * \if ENABLE_EXAMPLES + * \ref cpp_mcdataarrayint_invertarrayo2n2n2o "Here is a C++ example".<br> + * \ref py_mcdataarrayint_invertarrayo2n2n2o "Here is a Python example". + * \endif + */ +DataArrayInt *DataArrayInt::invertArrayO2N2N2O(int newNbOfElem) const +{ + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New(); + ret->alloc(newNbOfElem,1); + int nbOfOldNodes=getNumberOfTuples(); + const int *old2New=getConstPointer(); + int *pt=ret->getPointer(); + for(int i=0;i!=nbOfOldNodes;i++) + { + int newp(old2New[i]); + if(newp!=-1) + { + if(newp>=0 && newp<newNbOfElem) + pt[newp]=i; + else + { + std::ostringstream oss; oss << "DataArrayInt::invertArrayO2N2N2O : At place #" << i << " the newplace is " << newp << " must be in [0," << newNbOfElem << ") !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + } + } + return ret.retn(); +} + +/*! + * 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 +{ + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New(); + ret->alloc(newNbOfElem,1); + int nbOfOldNodes=getNumberOfTuples(); + const int *old2New=getConstPointer(); + int *pt=ret->getPointer(); + for(int i=nbOfOldNodes-1;i>=0;i--) + { + int newp(old2New[i]); + if(newp!=-1) + { + if(newp>=0 && newp<newNbOfElem) + pt[newp]=i; + else + { + std::ostringstream oss; oss << "DataArrayInt::invertArrayO2N2N2OBis : At place #" << i << " the newplace is " << newp << " must be in [0," << newNbOfElem << ") !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + } + } + 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 numbering. + * \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. + * + * \if ENABLE_EXAMPLES + * \ref cpp_mcdataarrayint_invertarrayn2o2o2n "Here is a C++ example". + * + * \ref py_mcdataarrayint_invertarrayn2o2o2n "Here is a Python example". + * \endif + */ +DataArrayInt *DataArrayInt::invertArrayN2O2O2N(int oldNbOfElem) const +{ + checkAllocated(); + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New(); + ret->alloc(oldNbOfElem,1); + const int *new2Old=getConstPointer(); + int *pt=ret->getPointer(); + std::fill(pt,pt+oldNbOfElem,-1); + int nbOfNewElems=getNumberOfTuples(); + for(int i=0;i<nbOfNewElems;i++) + { + int v(new2Old[i]); + if(v>=0 && v<oldNbOfElem) + pt[v]=i; + else + { + std::ostringstream oss; oss << "DataArrayInt::invertArrayN2O2O2N : in new id #" << i << " old value is " << v << " expected to be in [0," << oldNbOfElem << ") !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + } + return ret.retn(); +} + +/*! + * Equivalent to DataArrayInt::isEqual except that if false the reason of + * mismatch is given. + * + * \param [in] other the instance to be compared with \a this + * \param [out] reason In case of inequality returns the reason. + * \sa DataArrayInt::isEqual + */ +bool DataArrayInt::isEqualIfNotWhy(const DataArrayInt& other, std::string& reason) const +{ + if(!areInfoEqualsIfNotWhy(other,reason)) + return false; + return _mem.isEqual(other._mem,0,reason); +} + +/*! + * Checks if \a this and another DataArrayInt are fully equal. For more info see + * \ref MEDCouplingArrayBasicsCompare. + * \param [in] other - an instance of DataArrayInt to compare with \a this one. + * \return bool - \a true if the two arrays are equal, \a false else. + */ +bool DataArrayInt::isEqual(const DataArrayInt& other) const +{ + std::string tmp; + return isEqualIfNotWhy(other,tmp); +} + +/*! + * Checks if values of \a this and another DataArrayInt are equal. For more info see + * \ref MEDCouplingArrayBasicsCompare. + * \param [in] other - an instance of DataArrayInt to compare with \a this one. + * \return bool - \a true if the values of two arrays are equal, \a false else. + */ +bool DataArrayInt::isEqualWithoutConsideringStr(const DataArrayInt& other) const +{ + std::string tmp; + return _mem.isEqual(other._mem,0,tmp); +} + +/*! + * Checks if values of \a this and another DataArrayInt are equal. Comparison is + * performed on sorted value sequences. + * For more info see\ref MEDCouplingArrayBasicsCompare. + * \param [in] other - an instance of DataArrayInt to compare with \a this one. + * \return bool - \a true if the sorted values of two arrays are equal, \a false else. + */ +bool DataArrayInt::isEqualWithoutConsideringStrAndOrder(const DataArrayInt& other) const +{ + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> a=deepCpy(); + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> b=other.deepCpy(); + a->sort(); + b->sort(); + return a->isEqualWithoutConsideringStr(*b); +} + +/*! + * This method compares content of input vector \a v and \a this. + * If for each id in \a this v[id]==True and for all other ids id2 not in \a this v[id2]==False, true is returned. + * For performance reasons \a this is expected to be sorted ascendingly. If not an exception will be thrown. + * + * \param [in] v - the vector of 'flags' to be compared with \a this. + * + * \throw If \a this is not sorted ascendingly. + * \throw If \a this has not exactly one component. + * \throw If \a this is not allocated. + */ +bool DataArrayInt::isFittingWith(const std::vector<bool>& v) const +{ + checkAllocated(); + if(getNumberOfComponents()!=1) + throw INTERP_KERNEL::Exception("DataArrayInt::isFittingWith : number of components of this should be equal to one !"); + const int *w(begin()),*end2(end()); + int refVal=-std::numeric_limits<int>::max(); + int i=0; + std::vector<bool>::const_iterator it(v.begin()); + for(;it!=v.end();it++,i++) + { + if(*it) + { + if(w!=end2) + { + if(*w++==i) + { + if(i>refVal) + refVal=i; + else + { + std::ostringstream oss; oss << "DataArrayInt::isFittingWith : At pos #" << std::distance(begin(),w-1) << " this is not sorted ascendingly !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + } + else + return false; + } + else + return false; + } + } + return w==end2; +} + +/*! + * This method assumes that \a this has one component and is allocated. This method scans all tuples in \a this and for all tuple equal to \a val + * put True to the corresponding entry in \a vec. + * \a vec is expected to be with the same size than the number of tuples of \a this. + */ +void DataArrayInt::switchOnTupleEqualTo(int val, std::vector<bool>& vec) const +{ + checkAllocated(); + if(getNumberOfComponents()!=1) + throw INTERP_KERNEL::Exception("DataArrayInt::switchOnTupleEqualTo : number of components of this should be equal to one !"); + int nbOfTuples(getNumberOfTuples()); + if(nbOfTuples!=(int)vec.size()) + throw INTERP_KERNEL::Exception("DataArrayInt::switchOnTupleEqualTo : number of tuples of this should be equal to size of input vector of bool !"); + const int *pt(begin()); + for(int i=0;i<nbOfTuples;i++) + if(pt[i]==val) + vec[i]=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 DataArrayInt::sort(bool asc) +{ + checkAllocated(); + if(getNumberOfComponents()!=1) + throw INTERP_KERNEL::Exception("DataArrayInt::sort : only supported with 'this' array with ONE component !"); + _mem.sort(asc); + declareAsNew(); +} + +/*! + * Computes for each tuple the sum of number of components values in the tuple and return it. + * + * \return DataArrayInt * - the new instance of DataArrayInt 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. + */ +DataArrayInt *DataArrayInt::sumPerTuple() const +{ + checkAllocated(); + int nbOfComp(getNumberOfComponents()),nbOfTuple(getNumberOfTuples()); + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret(DataArrayInt::New()); + ret->alloc(nbOfTuple,1); + const int *src(getConstPointer()); + int *dest(ret->getPointer()); + for(int i=0;i<nbOfTuple;i++,dest++,src+=nbOfComp) + *dest=std::accumulate(src,src+nbOfComp,0); + return ret.retn(); +} + +/*! + * Reverse the array values. + * \throw If \a this->getNumberOfComponents() < 1. + * \throw If \a this is not allocated. + */ +void DataArrayInt::reverse() +{ + 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 +{ + 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 +{ + 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<nbOfElements;i++) + { + if(ptr[i]>=ref) + ref=ptr[i]; + else + return false; + } + } + else + { + for(int i=1;i<nbOfElements;i++) + { + if(ptr[i]<=ref) + ref=ptr[i]; + else + return false; + } + } + return true; +} + +/*! + * This method check that array consistently INCREASING or DECREASING in value. + */ +bool DataArrayInt::isStrictlyMonotonic(bool increasing) const +{ + checkAllocated(); + if(getNumberOfComponents()!=1) + throw INTERP_KERNEL::Exception("DataArrayInt::isStrictlyMonotonic : 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<nbOfElements;i++) + { + if(ptr[i]>ref) + ref=ptr[i]; + else + return false; + } + } + else + { + for(int i=1;i<nbOfElements;i++) + { + if(ptr[i]<ref) + ref=ptr[i]; + else + return false; + } + } + return true; +} + +/*! + * This method check that array consistently INCREASING or DECREASING in value. + */ +void DataArrayInt::checkStrictlyMonotonic(bool increasing) const +{ + if(!isStrictlyMonotonic(increasing)) + { + if (increasing) + throw INTERP_KERNEL::Exception("DataArrayInt::checkStrictlyMonotonic : 'this' is not strictly INCREASING monotonic !"); + else + throw INTERP_KERNEL::Exception("DataArrayInt::checkStrictlyMonotonic : 'this' is not strictly DECREASING monotonic !"); + } +} + +/*! + * 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 + * <em> other.getIJ(i,0) == this->getIJ(ret->getIJ(i),0)</em>. 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. + * + * \if ENABLE_EXAMPLES + * \ref cpp_mcdataarrayint_buildpermutationarr "Here is a C++ example". + * + * \ref py_mcdataarrayint_buildpermutationarr "Here is a Python example". + * \endif + */ +DataArrayInt *DataArrayInt::buildPermutationArr(const DataArrayInt& other) const +{ + 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<DataArrayInt> ret=DataArrayInt::New(); + ret->alloc(nbTuple,1); + ret->fillWithValue(-1); + const int *pt=getConstPointer(); + std::map<int,int> mm; + for(int i=0;i<nbTuple;i++) + mm[pt[i]]=i; + pt=other.getConstPointer(); + int *retToFill=ret->getPointer(); + for(int i=0;i<nbTuple;i++) + { + std::map<int,int>::const_iterator it=mm.find(pt[i]); + if(it==mm.end()) + { + std::ostringstream oss; oss << "DataArrayInt::buildPermutationArr : Arrays mismatch : element (" << pt[i] << ") in 'other' not findable in 'this' !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + retToFill[i]=(*it).second; + } + return ret.retn(); +} + +/*! + * 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) +{ + _info_on_compo.resize(nbOfCompo); + _mem.useArray(array,ownership,type,nbOfTuple*nbOfCompo); + declareAsNew(); +} + +void DataArrayInt::useExternalArrayWithRWAccess(const int *array, int nbOfTuple, int nbOfCompo) +{ + _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 +{ + 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,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 +{ + 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,C_DEALLOC,getNumberOfTuples(),getNumberOfComponents()); + 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 \c this one. + * If a permutation reduction is needed, substr() or selectByTupleId() should be used. + * For more info on renumbering see \ref numbering. + * \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) +{ + checkAllocated(); + int nbTuples=getNumberOfTuples(); + int nbOfCompo=getNumberOfComponents(); + int *tmp=new int[nbTuples*nbOfCompo]; + const int *iptr=getConstPointer(); + for(int i=0;i<nbTuples;i++) + { + int v=old2New[i]; + if(v>=0 && v<nbTuples) + std::copy(iptr+nbOfCompo*i,iptr+nbOfCompo*(i+1),tmp+nbOfCompo*v); + else + { + std::ostringstream oss; oss << "DataArrayInt::renumberInPlace : At place #" << i << " value is " << v << " ! Should be in [0," << nbTuples << ") !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + } + std::copy(tmp,tmp+nbTuples*nbOfCompo,getPointer()); + delete [] tmp; + declareAsNew(); +} + +/*! + * 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 \c this one. + * For more info on renumbering see \ref numbering. + * \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) +{ + checkAllocated(); + int nbTuples=getNumberOfTuples(); + int nbOfCompo=getNumberOfComponents(); + int *tmp=new int[nbTuples*nbOfCompo]; + const int *iptr=getConstPointer(); + for(int i=0;i<nbTuples;i++) + { + int v=new2Old[i]; + if(v>=0 && v<nbTuples) + std::copy(iptr+nbOfCompo*v,iptr+nbOfCompo*(v+1),tmp+nbOfCompo*i); + else + { + std::ostringstream oss; oss << "DataArrayInt::renumberInPlaceR : At place #" << i << " value is " << v << " ! Should be in [0," << nbTuples << ") !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + } + std::copy(tmp,tmp+nbTuples*nbOfCompo,getPointer()); + delete [] tmp; + declareAsNew(); +} + +/*! + * 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 \c this one. + * If a permutation reduction is needed, renumberAndReduce() should be used. + * For more info on renumbering see \ref numbering. + * \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 +{ + checkAllocated(); + int nbTuples=getNumberOfTuples(); + int nbOfCompo=getNumberOfComponents(); + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New(); + ret->alloc(nbTuples,nbOfCompo); + ret->copyStringInfoFrom(*this); + const int *iptr=getConstPointer(); + int *optr=ret->getPointer(); + for(int i=0;i<nbTuples;i++) + std::copy(iptr+nbOfCompo*i,iptr+nbOfCompo*(i+1),optr+nbOfCompo*old2New[i]); + ret->copyStringInfoFrom(*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 \c this one. + * If a permutation reduction is needed, substr() or selectByTupleId() should be used. + * For more info on renumbering see \ref numbering. + * \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 +{ + checkAllocated(); + int nbTuples=getNumberOfTuples(); + int nbOfCompo=getNumberOfComponents(); + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New(); + ret->alloc(nbTuples,nbOfCompo); + ret->copyStringInfoFrom(*this); + const int *iptr=getConstPointer(); + int *optr=ret->getPointer(); + for(int i=0;i<nbTuples;i++) + std::copy(iptr+nbOfCompo*new2Old[i],iptr+nbOfCompo*(new2Old[i]+1),optr+nbOfCompo*i); + ret->copyStringInfoFrom(*this); + return ret.retn(); +} + +/*! + * 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 numbering. + * \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 +{ + checkAllocated(); + int nbTuples=getNumberOfTuples(); + int nbOfCompo=getNumberOfComponents(); + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New(); + ret->alloc(newNbOfTuple,nbOfCompo); + const int *iptr=getConstPointer(); + int *optr=ret->getPointer(); + for(int i=0;i<nbTuples;i++) + { + int w=old2New[i]; + if(w>=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 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 numbering. + * \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 +{ + checkAllocated(); + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New(); + int nbComp=getNumberOfComponents(); + ret->alloc((int)std::distance(new2OldBg,new2OldEnd),nbComp); + ret->copyStringInfoFrom(*this); + int *pt=ret->getPointer(); + const int *srcPt=getConstPointer(); + int i=0; + 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.retn(); +} + +/*! + * 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 numbering. + * \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 +{ + checkAllocated(); + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New(); + int nbComp=getNumberOfComponents(); + int oldNbOfTuples=getNumberOfTuples(); + ret->alloc((int)std::distance(new2OldBg,new2OldEnd),nbComp); + ret->copyStringInfoFrom(*this); + int *pt=ret->getPointer(); + const int *srcPt=getConstPointer(); + int i=0; + for(const int *w=new2OldBg;w!=new2OldEnd;w++,i++) + if(*w>=0 && *w<oldNbOfTuples) + std::copy(srcPt+(*w)*nbComp,srcPt+((*w)+1)*nbComp,pt+i*nbComp); + else + throw INTERP_KERNEL::Exception("DataArrayInt::selectByTupleIdSafe : some ids has been detected to be out of [0,this->getNumberOfTuples) !"); + ret->copyStringInfoFrom(*this); + return ret.retn(); +} + +/*! + * 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 numbering. + * \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 +{ + checkAllocated(); + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New(); + int nbComp=getNumberOfComponents(); + 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;i<newNbOfTuples;i++,srcPt+=step*nbComp) + std::copy(srcPt,srcPt+nbComp,pt+i*nbComp); + ret->copyStringInfoFrom(*this); + return ret.retn(); +} + +/*! + * 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 numbering. + * \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. + */ +DataArray *DataArrayInt::selectByTupleRanges(const std::vector<std::pair<int,int> >& ranges) const +{ + checkAllocated(); + int nbOfComp=getNumberOfComponents(); + int nbOfTuplesThis=getNumberOfTuples(); + if(ranges.empty()) + { + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New(); + ret->alloc(0,nbOfComp); + ret->copyStringInfoFrom(*this); + return ret.retn(); + } + int ref=ranges.front().first; + int nbOfTuples=0; + bool isIncreasing=true; + for(std::vector<std::pair<int,int> >::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 << "DataArrayInt::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 << "DataArrayInt::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<DataArrayInt> ret=DataArrayInt::New(); + ret->alloc(nbOfTuples,nbOfComp); + ret->copyStringInfoFrom(*this); + const int *src=getConstPointer(); + int *work=ret->getPointer(); + for(std::vector<std::pair<int,int> >::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 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 numbering. + * \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 +{ + checkAllocated(); + if(getNumberOfComponents()!=1) + throw INTERP_KERNEL::Exception("DataArrayInt::checkAndPreparePermutation : number of components must == 1 !"); + int nbTuples=getNumberOfTuples(); + const int *pt=getConstPointer(); + int *pt2=CheckAndPreparePermutation(pt,pt+nbTuples); + DataArrayInt *ret=DataArrayInt::New(); + ret->useArray(pt2,true,C_DEALLOC,nbTuples,1); + return ret; +} + +/*! + * This method tries to find the permutation to apply to the first input \a ids1 to obtain the same array (without considering strings informations) the second + * input array \a ids2. + * \a ids1 and \a ids2 are expected to be both a list of ids (both with number of components equal to one) not sorted and with values that can be negative. + * This method will throw an exception is no such permutation array can be obtained. It is typically the case if there is some ids in \a ids1 not in \a ids2 or + * inversely. + * In case of success (no throw) : \c ids1->renumber(ret)->isEqual(ids2) where \a ret is the return of this method. + * + * \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete this + * array using decrRef() as it is no more needed. + * \throw If either ids1 or ids2 is null not allocated or not with one components. + * + */ +DataArrayInt *DataArrayInt::FindPermutationFromFirstToSecond(const DataArrayInt *ids1, const DataArrayInt *ids2) +{ + if(!ids1 || !ids2) + throw INTERP_KERNEL::Exception("DataArrayInt::FindPermutationFromFirstToSecond : the two input arrays must be not null !"); + if(!ids1->isAllocated() || !ids2->isAllocated()) + throw INTERP_KERNEL::Exception("DataArrayInt::FindPermutationFromFirstToSecond : the two input arrays must be allocated !"); + if(ids1->getNumberOfComponents()!=1 || ids2->getNumberOfComponents()!=1) + throw INTERP_KERNEL::Exception("DataArrayInt::FindPermutationFromFirstToSecond : the two input arrays have exactly one component !"); + if(ids1->getNumberOfTuples()!=ids2->getNumberOfTuples()) + { + std::ostringstream oss; oss << "DataArrayInt::FindPermutationFromFirstToSecond : first array has " << ids1->getNumberOfTuples() << " tuples and the second one " << ids2->getNumberOfTuples() << " tuples ! No chance to find a permutation between the 2 arrays !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> p1(ids1->deepCpy()); + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> p2(ids2->deepCpy()); + p1->sort(true); p2->sort(true); + if(!p1->isEqualWithoutConsideringStr(*p2)) + throw INTERP_KERNEL::Exception("DataArrayInt::FindPermutationFromFirstToSecond : the two arrays are not lying on same ids ! Impossible to find a permutation between the 2 arrays !"); + p1=ids1->checkAndPreparePermutation(); + p2=ids2->checkAndPreparePermutation(); + p2=p2->invertArrayO2N2N2O(p2->getNumberOfTuples()); + p2=p2->selectByTupleIdSafe(p1->begin(),p1->end()); + return p2.retn(); +} + +/*! + * 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 <em> this->getIJ( tid, 0 ) == id</em>. <br> + * 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. <br> + * For more info on + * mapping and its usage in renumbering see \ref numbering. <br> + * \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: <br> + * 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 ]]);<br> + * 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 ]]); <br> 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 +{ + checkAllocated(); + if(getNumberOfComponents()!=1) + throw INTERP_KERNEL::Exception("DataArrayInt::changeSurjectiveFormat : number of components must == 1 !"); + int nbOfTuples=getNumberOfTuples(); + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret(DataArrayInt::New()); + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> retI(DataArrayInt::New()); + retI->alloc(targetNb+1,1); + const int *input=getConstPointer(); + std::vector< std::vector<int> > tmp(targetNb); + for(int i=0;i<nbOfTuples;i++) + { + int tmp2=input[i]; + if(tmp2>=0 && tmp2<targetNb) + tmp[tmp2].push_back(i); + else + { + std::ostringstream oss; oss << "DataArrayInt::changeSurjectiveFormat : At pos " << i << " presence of element " << tmp2 << " ! should be in [0," << targetNb << ") !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + } + int *retIPtr=retI->getPointer(); + *retIPtr=0; + for(std::vector< std::vector<int> >::const_iterator it1=tmp.begin();it1!=tmp.end();it1++,retIPtr++) + retIPtr[1]=retIPtr[0]+(int)((*it1).size()); + if(nbOfTuples!=retI->getIJ(targetNb,0)) + throw INTERP_KERNEL::Exception("DataArrayInt::changeSurjectiveFormat : big problem should never happen !"); + ret->alloc(nbOfTuples,1); + int *retPtr=ret->getPointer(); + for(std::vector< std::vector<int> >::const_iterator it1=tmp.begin();it1!=tmp.end();it1++) + retPtr=std::copy((*it1).begin(),(*it1).end(),retPtr); + arr=ret.retn(); + arrI=retI.retn(); +} + + +/*! + * 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. <br> + * For more info on renumbering see \ref numbering. <br> + * \b Example: <br> + * - \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 [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 int *arr, const int *arrIBg, const int *arrIEnd, int &newNbOfTuples) +{ + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New(); + ret->alloc(nbOfOldTuples,1); + int *pt=ret->getPointer(); + std::fill(pt,pt+nbOfOldTuples,-1); + int nbOfGrps=((int)std::distance(arrIBg,arrIEnd))-1; + const int *cIPtr=arrIBg; + for(int i=0;i<nbOfGrps;i++) + pt[arr[cIPtr[i]]]=-(i+2); + int newNb=0; + for(int iNode=0;iNode<nbOfOldTuples;iNode++) + { + if(pt[iNode]<0) + { + if(pt[iNode]==-1) + pt[iNode]=newNb++; + else + { + int grpId=-(pt[iNode]+2); + for(int j=cIPtr[grpId];j<cIPtr[grpId+1];j++) + { + if(arr[j]>=0 && arr[j]<nbOfOldTuples) + pt[arr[j]]=newNb; + else + { + std::ostringstream oss; oss << "DataArrayInt::BuildOld2NewArrayFromSurjectiveFormat2 : With element #" << j << " value is " << arr[j] << " should be in [0," << nbOfOldTuples << ") !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + } + newNb++; + } + } + } + newNbOfTuples=newNb; + return ret.retn(); +} + +/*! + * 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 numbering. <br> + * \b Example: <br> + * - \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 +{ + checkAllocated(); + if(getNumberOfComponents()!=1) + throw INTERP_KERNEL::Exception("DataArrayInt::buildPermArrPerLevel : number of components must == 1 !"); + int nbOfTuples=getNumberOfTuples(); + const int *pt=getConstPointer(); + std::map<int,int> m; + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New(); + ret->alloc(nbOfTuples,1); + int *opt=ret->getPointer(); + for(int i=0;i<nbOfTuples;i++,pt++,opt++) + { + int val=*pt; + std::map<int,int>::iterator it=m.find(val); + if(it!=m.end()) + { + *opt=(*it).second; + (*it).second++; + } + else + { + *opt=0; + m.insert(std::pair<int,int>(val,1)); + } + } + int sum=0; + for(std::map<int,int>::iterator it=m.begin();it!=m.end();it++) + { + int vt=(*it).second; + (*it).second=sum; + sum+=vt; + } + pt=getConstPointer(); + opt=ret->getPointer(); + for(int i=0;i<nbOfTuples;i++,pt++,opt++) + *opt+=m[*pt]; + // + return ret.retn(); +} + +/*! + * 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. In this case it is better to use isIdentity2 + * method of isIdentity method. + * + * \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. + * \sa isIdentity2 + */ +bool DataArrayInt::isIdentity() const +{ + checkAllocated(); + if(getNumberOfComponents()!=1) + return false; + int nbOfTuples(getNumberOfTuples()); + const int *pt=getConstPointer(); + for(int i=0;i<nbOfTuples;i++,pt++) + if(*pt!=i) + return false; + return true; +} + +/*! + * This method is stronger than isIdentity method. This method checks than \a this can be considered as an identity function + * of a set having \a sizeExpected elements into itself. + * + * \param [in] sizeExpected - The number of elements + * \return bool - \a true if \a this array contents == \a range( \a this->getNumberOfTuples()) and if \a this has \a sizeExpected tuples in it. + * + * \throw If \a this is not allocated. + * \throw If \a this->getNumberOfComponents() != 1. + * \sa isIdentity + */ +bool DataArrayInt::isIdentity2(int sizeExpected) const +{ + bool ret0(isIdentity()); + if(!ret0) + return false; + return getNumberOfTuples()==sizeExpected; +} + +/*! + * 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 +{ + checkAllocated(); + if(getNumberOfComponents()!=1) + throw INTERP_KERNEL::Exception("DataArrayInt::isUniform : must be applied on DataArrayInt with only one component, you can call 'rearrange' method before !"); + int nbOfTuples=getNumberOfTuples(); + const int *w=getConstPointer(); + const int *end2=w+nbOfTuples; + for(;w!=end2;w++) + if(*w!=val) + return false; + 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()); + std::size_t nbOfVals=getNbOfElems(); + const int *src=getConstPointer(); + double *dest=ret->getPointer(); + std::copy(src,src+nbOfVals,dest); + ret->copyStringInfoFrom(*this); + return ret; +} + +/*! + * 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 +{ + checkAllocated(); + int nbt=getNumberOfTuples(); + if(tupleIdBg<0) + throw INTERP_KERNEL::Exception("DataArrayInt::substr : The tupleIdBg parameter must be greater than 0 !"); + if(tupleIdBg>nbt) + throw INTERP_KERNEL::Exception("DataArrayInt::substr : The tupleIdBg parameter is greater than number of tuples !"); + int trueEnd=tupleIdEnd; + if(tupleIdEnd!=-1) + { + if(tupleIdEnd>nbt) + throw INTERP_KERNEL::Exception("DataArrayInt::substr : The tupleIdBg parameter is greater or equal than number of tuples !"); + } + else + trueEnd=nbt; + int nbComp=getNumberOfComponents(); + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New(); + ret->alloc(trueEnd-tupleIdBg,nbComp); + ret->copyStringInfoFrom(*this); + std::copy(getConstPointer()+tupleIdBg*nbComp,getConstPointer()+trueEnd*nbComp,ret->getPointer()); + return ret.retn(); +} + +/*! + * 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) +{ + checkAllocated(); + 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 !"); + if(nbOfElems/newNbOfCompo>(std::size_t)std::numeric_limits<int>::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(); +} + +/*! + * 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() +{ + checkAllocated(); + int nbOfTuples=getNumberOfTuples(); + rearrange(nbOfTuples); +} + +/*! + * 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 +{ + checkAllocated(); + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New(); + ret->alloc(getNumberOfTuples(),newNbOfComp); + const int *oldc=getConstPointer(); + int *nc=ret->getPointer(); + int nbOfTuples=getNumberOfTuples(); + int oldNbOfComp=getNumberOfComponents(); + int dim=std::min(oldNbOfComp,newNbOfComp); + for(int i=0;i<nbOfTuples;i++) + { + int j=0; + for(;j<dim;j++) + nc[newNbOfComp*i+j]=oldc[i*oldNbOfComp+j]; + for(;j<newNbOfComp;j++) + nc[newNbOfComp*i+j]=dftValue; + } + ret->setName(getName()); + for(int i=0;i<dim;i++) + ret->setInfoOnComponent(i,getInfoOnComponent(i)); + ret->setName(getName()); + 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. + * \throw If \a nbOfTuples is negative. + */ +void DataArrayInt::reAlloc(int nbOfTuples) +{ + if(nbOfTuples<0) + throw INTERP_KERNEL::Exception("DataArrayInt::reAlloc : input new number of tuples should be >=0 !"); + checkAllocated(); + _mem.reAlloc(getNumberOfComponents()*(std::size_t)nbOfTuples); + declareAsNew(); +} + + +/*! + * 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(). + * + * \if ENABLE_EXAMPLES + * \ref py_mcdataarrayint_keepselectedcomponents "Here is a Python example". + * \endif + */ +DataArrayInt *DataArrayInt::keepSelectedComponents(const std::vector<int>& compoIds) const +{ + checkAllocated(); + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret(DataArrayInt::New()); + int newNbOfCompo=(int)compoIds.size(); + int oldNbOfCompo=getNumberOfComponents(); + for(std::vector<int>::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 int *oldc=getConstPointer(); + int *nc=ret->getPointer(); + for(int i=0;i<nbOfTuples;i++) + for(int j=0;j<newNbOfCompo;j++,nc++) + *nc=oldc[i*oldNbOfCompo+compoIds[j]]; + return ret.retn(); +} + +/*! + * 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. + * + * \if ENABLE_EXAMPLES + * \ref cpp_mcdataarrayint_meldwith "Here is a C++ example". + * + * \ref py_mcdataarrayint_meldwith "Here is a Python example". + * \endif + */ +void DataArrayInt::meldWith(const DataArrayInt *other) +{ + if(!other) + throw INTERP_KERNEL::Exception("DataArrayInt::meldWith : DataArrayInt pointer in input is NULL !"); + checkAllocated(); + other->checkAllocated(); + int nbOfTuples=getNumberOfTuples(); + if(nbOfTuples!=other->getNumberOfTuples()) + throw INTERP_KERNEL::Exception("DataArrayInt::meldWith : mismatch of number of tuples !"); + int nbOfComp1=getNumberOfComponents(); + int nbOfComp2=other->getNumberOfComponents(); + int *newArr=(int *)malloc(nbOfTuples*(nbOfComp1+nbOfComp2)*sizeof(int)); + int *w=newArr; + const int *inp1=getConstPointer(); + const int *inp2=other->getConstPointer(); + for(int i=0;i<nbOfTuples;i++,inp1+=nbOfComp1,inp2+=nbOfComp2) + { + w=std::copy(inp1,inp1+nbOfComp1,w); + w=std::copy(inp2,inp2+nbOfComp2,w); + } + useArray(newArr,true,C_DEALLOC,nbOfTuples,nbOfComp1+nbOfComp2); + std::vector<int> compIds(nbOfComp2); + for(int i=0;i<nbOfComp2;i++) + compIds[i]=nbOfComp1+i; + copyPartOfStringInfoFrom2(compIds,*other); +} + +/*! + * Copy all components in a specified order from another DataArrayInt. + * The specified components become the first ones in \a this array. + * 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(). + * + * \if ENABLE_EXAMPLES + * \ref py_mcdataarrayint_setselectedcomponents "Here is a Python example". + * \endif + */ +void DataArrayInt::setSelectedComponents(const DataArrayInt *a, const std::vector<int>& compoIds) +{ + 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=std::min(getNumberOfTuples(),a->getNumberOfTuples()); + const int *ac=a->getConstPointer(); + int *nc=getPointer(); + for(int i=0;i<nbOfTuples;i++) + for(std::size_t j=0;j<partOfCompoSz;j++,ac++) + nc[nbOfCompo*i+compoIds[j]]=*ac; +} + +/*! + * Copy all values from another DataArrayInt into specified tuples and components + * of \a this array. Textual data is not copied. + * The tree parameters defining set of indices of tuples and components are similar to + * the tree parameters of the Python function \c range(\c start,\c stop,\c step). + * \param [in] a - the array to copy values from. + * \param [in] bgTuples - index of the first tuple of \a this array to assign values to. + * \param [in] endTuples - index of the tuple before which the tuples to assign to + * are located. + * \param [in] stepTuples - index increment to get index of the next tuple to assign to. + * \param [in] bgComp - index of the first component of \a this array to assign values 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 - if \a true (by default), then \a a->getNumberOfComponents() + * 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)). + * + * \if ENABLE_EXAMPLES + * \ref py_mcdataarrayint_setpartofvalues1 "Here is a Python example". + * \endif + */ +void DataArrayInt::setPartOfValues1(const DataArrayInt *a, int bgTuples, int endTuples, int stepTuples, int bgComp, int endComp, int stepComp, bool strictCompoCompare) +{ + if(!a) + throw INTERP_KERNEL::Exception("DataArrayInt::setPartOfValues1 : DataArrayInt pointer in input is NULL !"); + const char msg[]="DataArrayInt::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; + } + int *pt=getPointer()+bgTuples*nbComp+bgComp; + const int *srcPt=a->getConstPointer(); + if(assignTech) + { + for(int i=0;i<newNbOfTuples;i++,pt+=stepTuples*nbComp) + for(int j=0;j<newNbOfComp;j++,srcPt++) + pt[j*stepComp]=*srcPt; + } + else + { + for(int i=0;i<newNbOfTuples;i++,pt+=stepTuples*nbComp) + { + const int *srcPt2=srcPt; + for(int j=0;j<newNbOfComp;j++,srcPt2++) + pt[j*stepComp]=*srcPt2; + } + } +} + +/*! + * Assign a given value to values at specified tuples and components of \a this array. + * The tree parameters defining set of indices of tuples and components are similar to + * the tree parameters of the Python function \c range(\c start,\c stop,\c step).. + * \param [in] a - the value to assign. + * \param [in] bgTuples - index of the first tuple of \a this array to assign to. + * \param [in] endTuples - index of the tuple before which the tuples to assign to + * are located. + * \param [in] stepTuples - index increment to get index of the next tuple to assign to. + * \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 parameters specifying tuples and components to assign to, do not give a + * non-empty range of increasing indices or indices are out of a valid range + * for \c this array. + * + * \if ENABLE_EXAMPLES + * \ref py_mcdataarrayint_setpartofvaluessimple1 "Here is a Python example". + * \endif + */ +void DataArrayInt::setPartOfValuesSimple1(int a, int bgTuples, int endTuples, int stepTuples, int bgComp, int endComp, int stepComp) +{ + const char msg[]="DataArrayInt::setPartOfValuesSimple1"; + 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"); + int *pt=getPointer()+bgTuples*nbComp+bgComp; + for(int i=0;i<newNbOfTuples;i++,pt+=stepTuples*nbComp) + for(int j=0;j<newNbOfComp;j++) + pt[j*stepComp]=a; +} + + +/*! + * Copy all values from another DataArrayInt (\a a) into specified tuples and + * components of \a this array. Textual data is not copied. + * The tuples and components to assign to are defined by C arrays of indices. + * 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 <em>(pi)</em> 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 <em>(pi)</em> 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 <em>bgTuples / bgComp</em> is + * out of a valid range for \a this array. + * \throw In the first *mode of usage*, if <em>strictCompoCompare == true </em> and + * if <em> a->getNumberOfComponents() != (endComp - bgComp) </em>. + * \throw In the second *mode of usage*, if \a a->getNumberOfTuples() != 1 or + * <em> a->getNumberOfComponents() != (endComp - bgComp)</em>. + * + * \if ENABLE_EXAMPLES + * \ref py_mcdataarrayint_setpartofvalues2 "Here is a Python example". + * \endif + */ +void DataArrayInt::setPartOfValues2(const DataArrayInt *a, const int *bgTuples, const int *endTuples, const int *bgComp, const int *endComp, bool strictCompoCompare) +{ + if(!a) + throw INTERP_KERNEL::Exception("DataArrayInt::setPartOfValues2 : DataArrayInt pointer in input is NULL !"); + const char msg[]="DataArrayInt::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; + } + int *pt=getPointer(); + const int *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 int *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 <em>bgTuples / bgComp</em> is + * out of a valid range for \a this array. + * + * \if ENABLE_EXAMPLES + * \ref py_mcdataarrayint_setpartofvaluessimple2 "Here is a Python example". + * \endif + */ +void DataArrayInt::setPartOfValuesSimple2(int a, const int *bgTuples, const int *endTuples, const int *bgComp, const int *endComp) +{ + checkAllocated(); + int nbComp=getNumberOfComponents(); + int nbOfTuples=getNumberOfTuples(); + for(const int *z=bgComp;z!=endComp;z++) + DataArray::CheckValueInRange(nbComp,*z,"invalid component id"); + int *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 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 <em>(pi)</em> 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 <em>strictCompoCompare == true </em> and + * if <em> a->getNumberOfComponents()</em> is unequal to the number of components + * defined by <em>(bgComp,endComp,stepComp)</em>. + * \throw In the second *mode of usage*, if \a a->getNumberOfTuples() != 1 or + * <em> a->getNumberOfComponents()</em> is unequal to the number of components + * defined by <em>(bgComp,endComp,stepComp)</em>. + * \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 \c this array. + * + * \if ENABLE_EXAMPLES + * \ref py_mcdataarrayint_setpartofvalues3 "Here is a Python example". + * \endif + */ +void DataArrayInt::setPartOfValues3(const DataArrayInt *a, const int *bgTuples, const int *endTuples, int bgComp, int endComp, int stepComp, bool strictCompoCompare) +{ + if(!a) + throw INTERP_KERNEL::Exception("DataArrayInt::setPartOfValues3 : DataArrayInt pointer in input is NULL !"); + const char msg[]="DataArrayInt::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; + } + int *pt=getPointer()+bgComp; + const int *srcPt=a->getConstPointer(); + if(assignTech) + { + for(const int *w=bgTuples;w!=endTuples;w++) + for(int j=0;j<newNbOfComp;j++,srcPt++) + { + DataArray::CheckValueInRange(nbOfTuples,*w,"invalid tuple id"); + pt[(std::size_t)(*w)*nbComp+j*stepComp]=*srcPt; + } + } + else + { + for(const int *w=bgTuples;w!=endTuples;w++) + { + const int *srcPt2=srcPt; + for(int j=0;j<newNbOfComp;j++,srcPt2++) + { + DataArray::CheckValueInRange(nbOfTuples,*w,"invalid tuple id"); + pt[(std::size_t)(*w)*nbComp+j*stepComp]=*srcPt2; + } + } + } +} + +/*! + * Assign a given value to values at specified tuples and components of \a this array. + * 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). + * \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 <em>(pi)</em> 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 \c this array. + * + * \if ENABLE_EXAMPLES + * \ref py_mcdataarrayint_setpartofvaluessimple3 "Here is a Python example". + * \endif + */ +void DataArrayInt::setPartOfValuesSimple3(int a, const int *bgTuples, const int *endTuples, int bgComp, int endComp, int stepComp) +{ + const char msg[]="DataArrayInt::setPartOfValuesSimple3"; + checkAllocated(); + int newNbOfComp=DataArray::GetNumberOfItemGivenBES(bgComp,endComp,stepComp,msg); + int nbComp=getNumberOfComponents(); + int nbOfTuples=getNumberOfTuples(); + DataArray::CheckValueInRangeEx(nbComp,bgComp,endComp,"invalid component value"); + int *pt=getPointer()+bgComp; + for(const int *w=bgTuples;w!=endTuples;w++) + for(int j=0;j<newNbOfComp;j++) + { + DataArray::CheckValueInRange(nbOfTuples,*w,"invalid tuple id"); + pt[(std::size_t)(*w)*nbComp+j*stepComp]=a; + } +} + +void DataArrayInt::setPartOfValues4(const DataArrayInt *a, int bgTuples, int endTuples, int stepTuples, const int *bgComp, const int *endComp, bool strictCompoCompare) +{ + if(!a) + throw INTERP_KERNEL::Exception("DataArrayInt::setPartOfValues4 : input DataArrayInt is NULL !"); + const char msg[]="DataArrayInt::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 int *srcPt=a->getConstPointer(); + int *pt=getPointer()+bgTuples*nbComp; + if(assignTech) + { + for(int i=0;i<newNbOfTuples;i++,pt+=stepTuples*nbComp) + for(const int *z=bgComp;z!=endComp;z++,srcPt++) + pt[*z]=*srcPt; + } + else + { + for(int i=0;i<newNbOfTuples;i++,pt+=stepTuples*nbComp) + { + const int *srcPt2=srcPt; + for(const int *z=bgComp;z!=endComp;z++,srcPt2++) + pt[*z]=*srcPt2; + } + } +} + +void DataArrayInt::setPartOfValuesSimple4(int a, int bgTuples, int endTuples, int stepTuples, const int *bgComp, const int *endComp) +{ + const char msg[]="DataArrayInt::setPartOfValuesSimple4"; + checkAllocated(); + int newNbOfTuples=DataArray::GetNumberOfItemGivenBES(bgTuples,endTuples,stepTuples,msg); + 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"); + int *pt=getPointer()+bgTuples*nbComp; + for(int i=0;i<newNbOfTuples;i++,pt+=stepTuples*nbComp) + for(const int *z=bgComp;z!=endComp;z++) + pt[*z]=a; +} + +/*! + * Copy some tuples from another DataArrayInt into specified tuples + * of \a this array. Textual data is not copied. Both arrays must have equal number of + * components. + * Both the tuples to assign and the tuples to assign to are defined by a DataArrayInt. + * All components of selected tuples are copied. + * \param [in] a - the array to copy values from. + * \param [in] tuplesSelec - the array specifying both source tuples of \a a and + * target tuples of \a this. \a tuplesSelec has two components, and the + * first component specifies index of the source tuple and the second + * one specifies index of the target tuple. + * \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 <em>this->getNumberOfComponents() != a->getNumberOfComponents()</em>. + * \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) +{ + if(!a || !tuplesSelec) + throw INTERP_KERNEL::Exception("DataArrayInt::setPartOfValuesAdv : DataArrayInt pointer in input is NULL !"); + checkAllocated(); + a->checkAllocated(); + tuplesSelec->checkAllocated(); + int nbOfComp=getNumberOfComponents(); + if(nbOfComp!=a->getNumberOfComponents()) + throw INTERP_KERNEL::Exception("DataArrayInt::setPartOfValuesAdv : This and a do not have the same number of components !"); + if(tuplesSelec->getNumberOfComponents()!=2) + throw INTERP_KERNEL::Exception("DataArrayInt::setPartOfValuesAdv : Expecting to have a tuple selector DataArrayInt instance with exactly 2 components !"); + int thisNt=getNumberOfTuples(); + int aNt=a->getNumberOfTuples(); + int *valsToSet=getPointer(); + const int *valsSrc=a->getConstPointer(); + for(const int *tuple=tuplesSelec->begin();tuple!=tuplesSelec->end();tuple+=2) + { + if(tuple[1]>=0 && tuple[1]<aNt) + { + if(tuple[0]>=0 && tuple[0]<thisNt) + std::copy(valsSrc+nbOfComp*tuple[1],valsSrc+nbOfComp*(tuple[1]+1),valsToSet+nbOfComp*tuple[0]); + else + { + std::ostringstream oss; oss << "DataArrayInt::setPartOfValuesAdv : Tuple #" << std::distance(tuplesSelec->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 << "DataArrayInt::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 DataArrayInt (\a aBase) 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] aBase - the array to copy values from. + * \param [in] tuplesSelec - the array specifying tuples of \a aBase to copy. + * \throw If \a this is not allocated. + * \throw If \a aBase is NULL. + * \throw If \a aBase is not allocated. + * \throw If \a tuplesSelec is NULL. + * \throw If \a tuplesSelec is not allocated. + * \throw If <em>this->getNumberOfComponents() != a->getNumberOfComponents()</em>. + * \throw If \a tuplesSelec->getNumberOfComponents() != 1. + * \throw If <em>tupleIdStart + tuplesSelec->getNumberOfTuples() > this->getNumberOfTuples().</em> + * \throw If any tuple index given by \a tuplesSelec is out of a valid range for + * \a aBase array. + */ +void DataArrayInt::setContigPartOfSelectedValues(int tupleIdStart, const DataArray *aBase, const DataArrayInt *tuplesSelec) +{ + if(!aBase || !tuplesSelec) + throw INTERP_KERNEL::Exception("DataArrayInt::setContigPartOfSelectedValues : input DataArray is NULL !"); + const DataArrayInt *a=dynamic_cast<const DataArrayInt *>(aBase); + if(!a) + throw INTERP_KERNEL::Exception("DataArrayInt::setContigPartOfSelectedValues : input DataArray aBase is not a DataArrayInt !"); + checkAllocated(); + a->checkAllocated(); + tuplesSelec->checkAllocated(); + int nbOfComp=getNumberOfComponents(); + if(nbOfComp!=a->getNumberOfComponents()) + throw INTERP_KERNEL::Exception("DataArrayInt::setContigPartOfSelectedValues : This and a do not have the same number of components !"); + if(tuplesSelec->getNumberOfComponents()!=1) + throw INTERP_KERNEL::Exception("DataArrayInt::setContigPartOfSelectedValues : Expecting to have a tuple selector DataArrayInt instance with exactly 1 component !"); + int thisNt=getNumberOfTuples(); + int aNt=a->getNumberOfTuples(); + int nbOfTupleToWrite=tuplesSelec->getNumberOfTuples(); + int *valsToSet=getPointer()+tupleIdStart*nbOfComp; + if(tupleIdStart+nbOfTupleToWrite>thisNt) + throw INTERP_KERNEL::Exception("DataArrayInt::setContigPartOfSelectedValues : invalid number range of values to write !"); + const int *valsSrc=a->getConstPointer(); + for(const int *tuple=tuplesSelec->begin();tuple!=tuplesSelec->end();tuple++,valsToSet+=nbOfComp) + { + if(*tuple>=0 && *tuple<aNt) + { + std::copy(valsSrc+nbOfComp*(*tuple),valsSrc+nbOfComp*(*tuple+1),valsToSet); + } + else + { + std::ostringstream oss; oss << "DataArrayInt::setContigPartOfSelectedValues : Tuple #" << std::distance(tuplesSelec->begin(),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 DataArrayInt (\a aBase) 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] aBase - the array to copy values from. + * \param [in] bg - index of the first tuple to copy of the array \a aBase. + * \param [in] end2 - index of the tuple of \a aBase 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 aBase is NULL. + * \throw If \a aBase is not allocated. + * \throw If <em>this->getNumberOfComponents() != aBase->getNumberOfComponents()</em>. + * \throw If <em>tupleIdStart + len(range(bg,end2,step)) > this->getNumberOfTuples().</em> + * \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 aBase. + */ +void DataArrayInt::setContigPartOfSelectedValues2(int tupleIdStart, const DataArray *aBase, int bg, int end2, int step) +{ + if(!aBase) + throw INTERP_KERNEL::Exception("DataArrayInt::setContigPartOfSelectedValues2 : input DataArray is NULL !"); + const DataArrayInt *a=dynamic_cast<const DataArrayInt *>(aBase); + if(!a) + throw INTERP_KERNEL::Exception("DataArrayInt::setContigPartOfSelectedValues2 : input DataArray aBase is not a DataArrayInt !"); + checkAllocated(); + a->checkAllocated(); + int nbOfComp=getNumberOfComponents(); + const char msg[]="DataArrayInt::setContigPartOfSelectedValues2"; + int nbOfTupleToWrite=DataArray::GetNumberOfItemGivenBES(bg,end2,step,msg); + if(nbOfComp!=a->getNumberOfComponents()) + throw INTERP_KERNEL::Exception("DataArrayInt::setContigPartOfSelectedValues2 : This and a do not have the same number of components !"); + int thisNt=getNumberOfTuples(); + int aNt=a->getNumberOfTuples(); + int *valsToSet=getPointer()+tupleIdStart*nbOfComp; + if(tupleIdStart+nbOfTupleToWrite>thisNt) + throw INTERP_KERNEL::Exception("DataArrayInt::setContigPartOfSelectedValues2 : invalid number range of values to write !"); + if(end2>aNt) + throw INTERP_KERNEL::Exception("DataArrayInt::setContigPartOfSelectedValues2 : invalid range of values to read !"); + const int *valsSrc=a->getConstPointer()+bg*nbOfComp; + for(int i=0;i<nbOfTupleToWrite;i++,valsToSet+=nbOfComp,valsSrc+=step*nbOfComp) + { + std::copy(valsSrc,valsSrc+nbOfComp,valsToSet); + } +} + +/*! + * 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 <em>( 0 <= tupleId < this->getNumberOfTuples() )</em> is violated. + * \throw If condition <em>( 0 <= compoId < this->getNumberOfComponents() )</em> is violated. + */ +int DataArrayInt::getIJSafe(int tupleId, int compoId) const +{ + checkAllocated(); + if(tupleId<0 || tupleId>=getNumberOfTuples()) + { + std::ostringstream oss; oss << "DataArrayInt::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 << "DataArrayInt::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 first value of \a this. + * \return int - 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::front() const +{ + checkAllocated(); + if(getNumberOfComponents()!=1) + throw INTERP_KERNEL::Exception("DataArrayInt::front : number of components not equal to one !"); + int nbOfTuples=getNumberOfTuples(); + if(nbOfTuples<1) + throw INTERP_KERNEL::Exception("DataArrayInt::front : number of tuples must be >= 1 !"); + return *(getConstPointer()); +} + +/*! + * Returns the last value of \a this. + * \return int - 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 +{ + checkAllocated(); + if(getNumberOfComponents()!=1) + throw INTERP_KERNEL::Exception("DataArrayInt::back : number of components not equal to one !"); + int nbOfTuples=getNumberOfTuples(); + if(nbOfTuples<1) + throw INTERP_KERNEL::Exception("DataArrayInt::back : number of tuples must be >= 1 !"); + 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) + { + if(arrayToSet) + arrayToSet->decrRef(); + arrayToSet=newArray; + if(arrayToSet) + arrayToSet->incrRef(); + } +} + +DataArrayIntIterator *DataArrayInt::iterator() +{ + return new DataArrayIntIterator(this); +} + +/*! + * Creates a new DataArrayInt containing IDs (indices) of tuples holding value equal to a + * given one. The ids are sorted in the ascending order. + * \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. + * \sa DataArrayInt::getIdsEqualTuple + */ +DataArrayInt *DataArrayInt::getIdsEqual(int val) const +{ + 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()); + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1); + int nbOfTuples=getNumberOfTuples(); + for(int i=0;i<nbOfTuples;i++,cptr++) + if(*cptr==val) + 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 +{ + 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()); + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1); + int nbOfTuples=getNumberOfTuples(); + for(int i=0;i<nbOfTuples;i++,cptr++) + if(*cptr!=val) + ret->pushBackSilent(i); + return ret.retn(); +} + +/*! + * Creates a new DataArrayInt containing IDs (indices) of tuples holding tuple equal to those defined by [ \a tupleBg , \a tupleEnd ) + * This method is an extension of DataArrayInt::getIdsEqual method. + * + * \param [in] tupleBg - the begin (included) of the input tuple to find within \a this. + * \param [in] tupleEnd - the end (excluded) of the input tuple 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() != std::distance(tupleBg,tupleEnd). + * \throw If \a this->getNumberOfComponents() is equal to 0. + * \sa DataArrayInt::getIdsEqual + */ +DataArrayInt *DataArrayInt::getIdsEqualTuple(const int *tupleBg, const int *tupleEnd) const +{ + std::size_t nbOfCompoExp(std::distance(tupleBg,tupleEnd)); + checkAllocated(); + if(getNumberOfComponents()!=(int)nbOfCompoExp) + { + std::ostringstream oss; oss << "DataArrayInt::getIdsEqualTuple : mismatch of number of components. Input tuple has " << nbOfCompoExp << " whereas this array has " << getNumberOfComponents() << " components !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + if(nbOfCompoExp==0) + throw INTERP_KERNEL::Exception("DataArrayInt::getIdsEqualTuple : number of components should be > 0 !"); + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1); + const int *bg(begin()),*end2(end()),*work(begin()); + while(work!=end2) + { + work=std::search(work,end2,tupleBg,tupleEnd); + if(work!=end2) + { + std::size_t pos(std::distance(bg,work)); + if(pos%nbOfCompoExp==0) + ret->pushBackSilent(pos/nbOfCompoExp); + work++; + } + } + return ret.retn(); +} + +/*! + * 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) +{ + checkAllocated(); + if(getNumberOfComponents()!=1) + throw INTERP_KERNEL::Exception("DataArrayInt::changeValue : the array must have only one component, you can call 'rearrange' method before !"); + int *start=getPointer(); + int *end2=start+getNbOfElems(); + int ret=0; + for(int *val=start;val!=end2;val++) + { + if(*val==oldValue) + { + *val=newValue; + ret++; + } + } + 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 +{ + if(getNumberOfComponents()!=1) + throw INTERP_KERNEL::Exception("DataArrayInt::getIdsEqualList : the array must have only one component, you can call 'rearrange' method before !"); + std::set<int> vals2(valsBg,valsEnd); + const int *cptr=getConstPointer(); + std::vector<int> res; + int nbOfTuples=getNumberOfTuples(); + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1); + for(int i=0;i<nbOfTuples;i++,cptr++) + if(vals2.find(*cptr)!=vals2.end()) + 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 +{ + if(getNumberOfComponents()!=1) + throw INTERP_KERNEL::Exception("DataArrayInt::getIdsNotEqualList : the array must have only one component, you can call 'rearrange' method before !"); + std::set<int> vals2(valsBg,valsEnd); + const int *cptr=getConstPointer(); + std::vector<int> res; + int nbOfTuples=getNumberOfTuples(); + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1); + for(int i=0;i<nbOfTuples;i++,cptr++) + if(vals2.find(*cptr)==vals2.end()) + ret->pushBackSilent(i); + return ret.retn(); +} + +/*! + * This method is an extension of DataArrayInt::locateValue method because this method works for DataArrayInt 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 DataArrayInt::search, DataArrayInt::presenceOfTuple. + */ +int DataArrayInt::locateTuple(const std::vector<int>& tupl) const +{ + checkAllocated(); + int nbOfCompo=getNumberOfComponents(); + if(nbOfCompo==0) + throw INTERP_KERNEL::Exception("DataArrayInt::locateTuple : 0 components in 'this' !"); + if(nbOfCompo!=(int)tupl.size()) + { + std::ostringstream oss; oss << "DataArrayInt::locateTuple : 'this' contains " << nbOfCompo << " components and searching for a tuple of length " << tupl.size() << " !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + const int *cptr=getConstPointer(); + std::size_t nbOfVals=getNbOfElems(); + for(const int *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 searches the sequence specified in input parameter \b vals in \b this. + * This works only for DataArrayInt having number of components equal to one (if not an INTERP_KERNEL::Exception will be thrown). + * This method differs from DataArrayInt::locateTuple in that the position is internal raw data is not considered here contrary to DataArrayInt::locateTuple. + * \sa DataArrayInt::locateTuple + */ +int DataArrayInt::search(const std::vector<int>& vals) const +{ + 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(); + 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); + 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 equal to \b value. + * If not any tuple contains \b value -1 is returned. + * \sa DataArrayInt::presenceOfValue + */ +int DataArrayInt::locateValue(int value) const +{ + 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(); + int nbOfTuples=getNumberOfTuples(); + const int *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 DataArrayInt::presenceOfValue + */ +int DataArrayInt::locateValue(const std::vector<int>& vals) const +{ + 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<int> 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; +} + +/*! + * 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 +{ + 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<nbOfTuples;i++,vals++) + if(*vals==value) + ret++; + return ret; +} + +/*! + * This method is an extension of DataArrayInt::presenceOfValue method because this method works for DataArrayInt 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 DataArrayInt::locateTuple + */ +bool DataArrayInt::presenceOfTuple(const std::vector<int>& tupl) const +{ + 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 DataArrayInt::presenceOfValue(int value) const +{ + 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 DataArrayInt::locateValue + */ +bool DataArrayInt::presenceOfValue(const std::vector<int>& vals) const +{ + 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 +{ + checkAllocated(); + const int *ptr=getConstPointer(); + int nbTuple=getNumberOfTuples(); + int nbComps=getNumberOfComponents(); + std::fill(res,res+nbComps,0); + for(int i=0;i<nbTuple;i++) + std::transform(ptr+i*nbComps,ptr+(i+1)*nbComps,res,res,std::plus<int>()); +} + +int DataArrayInt::accumulate(int compId) const +{ + 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;i<nbTuple;i++) + ret+=ptr[i*nbComps+compId]; + return ret; +} + +/*! + * This method accumulate using addition tuples in \a this using input index array [ \a bgOfIndex, \a endOfIndex ). + * The returned array will have same number of components than \a this and number of tuples equal to + * \c std::distance(bgOfIndex,endOfIndex) \b minus \b one. + * + * The input index array is expected to be ascendingly sorted in which the all referenced ids should be in [0, \c this->getNumberOfTuples). + * + * \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 +{ + 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<DataArrayInt> 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<sz;i++,tmp+=nbCompo,w++) + { + std::fill(tmp,tmp+nbCompo,0); + if(w[1]>=w[0]) + { + for(int j=w[0];j<w[1];j++,srcPt+=nbCompo) + { + if(j>=0 && j<nbOfTuples) + std::transform(srcPt,srcPt+nbCompo,tmp,tmp,std::plus<int>()); + 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 <em> a1->getNumberOfTuples() + a2->getNumberOfTuples() - + * offsetA2</em> 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) + throw INTERP_KERNEL::Exception("DataArrayInt::Aggregate : input DataArrayInt instance is NULL !"); + int nbOfComp=a1->getNumberOfComponents(); + if(nbOfComp!=a2->getNumberOfComponents()) + throw INTERP_KERNEL::Exception("Nb of components mismatch for array Aggregation !"); + int nbOfTuple1=a1->getNumberOfTuples(); + int nbOfTuple2=a2->getNumberOfTuples(); + DataArrayInt *ret=DataArrayInt::New(); + ret->alloc(nbOfTuple1+nbOfTuple2-offsetA2,nbOfComp); + int *pt=std::copy(a1->getConstPointer(),a1->getConstPointer()+nbOfTuple1*nbOfComp,ret->getPointer()); + std::copy(a2->getConstPointer()+offsetA2*nbOfComp,a2->getConstPointer()+nbOfTuple2*nbOfComp,pt); + ret->copyStringInfoFrom(*a1); + 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. + * If the number of non null of elements in \a arr is equal to one the returned object is a copy of it + * not the object itself. + * \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<const DataArrayInt *>& arr) +{ + std::vector<const DataArrayInt *> a; + for(std::vector<const DataArrayInt *>::const_iterator it4=arr.begin();it4!=arr.end();it4++) + if(*it4) + a.push_back(*it4); + if(a.empty()) + throw INTERP_KERNEL::Exception("DataArrayInt::Aggregate : input list must be NON EMPTY !"); + std::vector<const DataArrayInt *>::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("DataArrayInt::Aggregate : Nb of components mismatch for array aggregation !"); + nbt+=(*it)->getNumberOfTuples(); + } + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> 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.retn(); +} + +/*! + * This method takes as input a list of DataArrayInt instances \a arrs that represent each a packed index arrays. + * A packed index array is an allocated array with one component, and at least one tuple. The first element + * of each array in \a arrs must be 0. Each array in \a arrs is expected to be increasingly monotonic. + * This method is useful for users that want to aggregate a pair of DataArrayInt representing an indexed data (typically nodal connectivity index in unstructured meshes. + * + * \return DataArrayInt * - a new object to be managed by the caller. + */ +DataArrayInt *DataArrayInt::AggregateIndexes(const std::vector<const DataArrayInt *>& arrs) +{ + int retSz=1; + for(std::vector<const DataArrayInt *>::const_iterator it4=arrs.begin();it4!=arrs.end();it4++) + { + if(*it4) + { + (*it4)->checkAllocated(); + if((*it4)->getNumberOfComponents()!=1) + { + std::ostringstream oss; oss << "DataArrayInt::AggregateIndexes : presence of a DataArrayInt instance with nb of compo != 1 at pos " << std::distance(arrs.begin(),it4) << " !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + int nbTupl=(*it4)->getNumberOfTuples(); + if(nbTupl<1) + { + std::ostringstream oss; oss << "DataArrayInt::AggregateIndexes : presence of a DataArrayInt instance with nb of tuples < 1 at pos " << std::distance(arrs.begin(),it4) << " !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + if((*it4)->front()!=0) + { + std::ostringstream oss; oss << "DataArrayInt::AggregateIndexes : presence of a DataArrayInt instance with front value != 0 at pos " << std::distance(arrs.begin(),it4) << " !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + retSz+=nbTupl-1; + } + else + { + std::ostringstream oss; oss << "DataArrayInt::AggregateIndexes : presence of a null instance at pos " << std::distance(arrs.begin(),it4) << " !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + } + if(arrs.empty()) + throw INTERP_KERNEL::Exception("DataArrayInt::AggregateIndexes : input list must be NON EMPTY !"); + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New(); + ret->alloc(retSz,1); + int *pt=ret->getPointer(); *pt++=0; + for(std::vector<const DataArrayInt *>::const_iterator it=arrs.begin();it!=arrs.end();it++) + pt=std::transform((*it)->begin()+1,(*it)->end(),pt,std::bind2nd(std::plus<int>(),pt[-1])); + ret->copyStringInfoFrom(*(arrs[0])); + 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 +{ + checkAllocated(); + if(getNumberOfComponents()!=1) + throw INTERP_KERNEL::Exception("DataArrayInt::getMaxValue : must be applied on DataArrayInt with only one component !"); + int nbOfTuples=getNumberOfTuples(); + if(nbOfTuples<=0) + throw INTERP_KERNEL::Exception("DataArrayInt::getMaxValue : array exists but number of tuples must be > 0 !"); + const int *vals=getConstPointer(); + const int *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 int - the maximal value among all values of \a this array. + * \throw If \a this is not allocated. + */ +int DataArrayInt::getMaxValueInArray() const +{ + checkAllocated(); + const int *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 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 +{ + checkAllocated(); + if(getNumberOfComponents()!=1) + throw INTERP_KERNEL::Exception("DataArrayInt::getMaxValue : must be applied on DataArrayInt with only one component !"); + int nbOfTuples=getNumberOfTuples(); + if(nbOfTuples<=0) + throw INTERP_KERNEL::Exception("DataArrayInt::getMaxValue : array exists but number of tuples must be > 0 !"); + const int *vals=getConstPointer(); + const int *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 int - the minimal value among all values of \a this array. + * \throw If \a this is not allocated. + */ +int DataArrayInt::getMinValueInArray() const +{ + checkAllocated(); + const int *loc=std::min_element(begin(),end()); + return *loc; +} + +/*! + * Returns in a single walk in \a this the min value and the max value in \a this. + * \a this is expected to be single component array. + * + * \param [out] minValue - the min value in \a this. + * \param [out] maxValue - the max value in \a this. + * + * \sa getMinValueInArray, getMinValue, getMaxValueInArray, getMaxValue + */ +void DataArrayInt::getMinMaxValues(int& minValue, int& maxValue) const +{ + checkAllocated(); + if(getNumberOfComponents()!=1) + throw INTERP_KERNEL::Exception("DataArrayInt::getMinMaxValues : must be applied on DataArrayInt with only one component !"); + int nbTuples(getNumberOfTuples()); + const int *pt(begin()); + minValue=std::numeric_limits<int>::max(); maxValue=-std::numeric_limits<int>::max(); + for(int i=0;i<nbTuples;i++,pt++) + { + if(*pt<minValue) + minValue=*pt; + if(*pt>maxValue) + maxValue=*pt; + } +} + +/*! + * Converts every value of \a this array to its absolute value. + * \b WARNING this method is non const. If a new DataArrayInt instance should be built containing the result of abs DataArrayInt::computeAbs + * should be called instead. + * + * \throw If \a this is not allocated. + * \sa DataArrayInt::computeAbs + */ +void DataArrayInt::abs() +{ + checkAllocated(); + int *ptr(getPointer()); + std::size_t nbOfElems(getNbOfElems()); + std::transform(ptr,ptr+nbOfElems,ptr,std::ptr_fun<int,int>(std::abs)); + declareAsNew(); +} + +/*! + * This method builds a new instance of \a this object containing the result of std::abs applied of all elements in \a this. + * This method is a const method (that do not change any values in \a this) contrary to DataArrayInt::abs method. + * + * \return DataArrayInt * - the new instance of DataArrayInt 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. + * \sa DataArrayInt::abs + */ +DataArrayInt *DataArrayInt::computeAbs() const +{ + checkAllocated(); + DataArrayInt *newArr(DataArrayInt::New()); + int nbOfTuples(getNumberOfTuples()); + int nbOfComp(getNumberOfComponents()); + newArr->alloc(nbOfTuples,nbOfComp); + std::transform(begin(),end(),newArr->getPointer(),std::ptr_fun<int,int>(std::abs)); + newArr->copyStringInfoFrom(*this); + return newArr; +} + +/*! + * Apply a liner function to a given component of \a this array, so that + * an array element <em>(x)</em> 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) +{ + checkAllocated(); + int *ptr=getPointer()+compoId; + int nbOfComp=getNumberOfComponents(); + int nbOfTuple=getNumberOfTuples(); + for(int i=0;i<nbOfTuple;i++,ptr+=nbOfComp) + *ptr=a*(*ptr)+b; + 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) +{ + checkAllocated(); + int *ptr=getPointer(); + std::size_t nbOfElems=getNbOfElems(); + for(std::size_t i=0;i<nbOfElems;i++,ptr++) + *ptr=a*(*ptr)+b; + declareAsNew(); +} + +/*! + * Returns a full copy of \a this array except that sign of all elements is reversed. + * \return DataArrayInt * - the new instance of DataArrayInt 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. + */ +DataArrayInt *DataArrayInt::negate() const +{ + checkAllocated(); + DataArrayInt *newArr=DataArrayInt::New(); + int nbOfTuples=getNumberOfTuples(); + int nbOfComp=getNumberOfComponents(); + newArr->alloc(nbOfTuples,nbOfComp); + const int *cptr=getConstPointer(); + std::transform(cptr,cptr+nbOfTuples*nbOfComp,newArr->getPointer(),std::negate<int>()); + newArr->copyStringInfoFrom(*this); + return newArr; +} + +/*! + * Modify all elements of \a this array, so that + * an element _x_ becomes \f$ numerator / x \f$. + * \warning If an exception is thrown because of presence of 0 element in \a this + * array, all elements processed before detection of the zero element remain + * modified. + * \param [in] numerator - the numerator used to modify array elements. + * \throw If \a this is not allocated. + * \throw If there is an element equal to 0 in \a this array. + */ +void DataArrayInt::applyInv(int numerator) +{ + checkAllocated(); + int *ptr=getPointer(); + std::size_t nbOfElems=getNbOfElems(); + for(std::size_t i=0;i<nbOfElems;i++,ptr++) + { + if(*ptr!=0) + { + *ptr=numerator/(*ptr); + } + else + { + std::ostringstream oss; oss << "DataArrayInt::applyInv : presence of null value in tuple #" << i/getNumberOfComponents() << " component #" << i%getNumberOfComponents(); + oss << " !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + } + declareAsNew(); +} + +/*! + * Modify all elements of \a this array, so that + * an element _x_ becomes \f$ x / val \f$. + * \param [in] val - the denominator used to modify array elements. + * \throw If \a this is not allocated. + * \throw If \a val == 0. + */ +void DataArrayInt::applyDivideBy(int val) +{ + if(val==0) + throw INTERP_KERNEL::Exception("DataArrayInt::applyDivideBy : Trying to divide by 0 !"); + checkAllocated(); + int *ptr=getPointer(); + std::size_t nbOfElems=getNbOfElems(); + std::transform(ptr,ptr+nbOfElems,ptr,std::bind2nd(std::divides<int>(),val)); + declareAsNew(); +} + +/*! + * Modify all elements of \a this array, so that + * an element _x_ becomes <em> x % val </em>. + * \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) +{ + if(val<=0) + throw INTERP_KERNEL::Exception("DataArrayInt::applyDivideBy : Trying to operate modulus on value <= 0 !"); + checkAllocated(); + int *ptr=getPointer(); + std::size_t nbOfElems=getNbOfElems(); + std::transform(ptr,ptr+nbOfElems,ptr,std::bind2nd(std::modulus<int>(),val)); + declareAsNew(); +} + +/*! + * 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 (included). + * \param [in] 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. + * + * \sa DataArrayInt::getIdsNotInRange , DataArrayInt::getIdsStrictlyNegative + */ +DataArrayInt *DataArrayInt::getIdsInRange(int vmin, int vmax) const +{ + checkAllocated(); + if(getNumberOfComponents()!=1) + throw INTERP_KERNEL::Exception("DataArrayInt::getIdsInRange : this must have exactly one component !"); + const int *cptr(begin()); + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1); + int nbOfTuples(getNumberOfTuples()); + for(int i=0;i<nbOfTuples;i++,cptr++) + if(*cptr>=vmin && *cptr<vmax) + ret->pushBackSilent(i); + return ret.retn(); +} + +/*! + * 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] \b not in [\b vmin,\b vmax) + * + * \param [in] vmin begin of range. This value is \b not included in range (excluded). + * \param [in] vmax end of range. This value is included in range (included). + * \return a newly allocated data array that the caller should deal with. + * + * \sa DataArrayInt::getIdsInRange , DataArrayInt::getIdsStrictlyNegative + */ +DataArrayInt *DataArrayInt::getIdsNotInRange(int vmin, int vmax) const +{ + checkAllocated(); + if(getNumberOfComponents()!=1) + throw INTERP_KERNEL::Exception("DataArrayInt::getIdsNotInRange : this must have exactly one component !"); + const int *cptr(getConstPointer()); + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1); + int nbOfTuples(getNumberOfTuples()); + for(int i=0;i<nbOfTuples;i++,cptr++) + if(*cptr<vmin || *cptr>=vmax) + ret->pushBackSilent(i); + return ret.retn(); +} + +/*! + * This method works only on data array with one component. This method returns a newly allocated array storing stored ascendantly of tuple ids in \a this so that this[id]<0. + * + * \return a newly allocated data array that the caller should deal with. + * \sa DataArrayInt::getIdsInRange + */ +DataArrayInt *DataArrayInt::getIdsStrictlyNegative() const +{ + checkAllocated(); + if(getNumberOfComponents()!=1) + throw INTERP_KERNEL::Exception("DataArrayInt::getIdsStrictlyNegative : this must have exactly one component !"); + const int *cptr(getConstPointer()); + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1); + int nbOfTuples(getNumberOfTuples()); + for(int i=0;i<nbOfTuples;i++,cptr++) + if(*cptr<0) + ret->pushBackSilent(i); + return ret.retn(); +} + +/*! + * This method works only on data array with one component. + * This method checks that all ids in \b this are in [ \b vmin, \b vmax ). If there is at least one element in \a this not in [ \b vmin, \b vmax ) an exception will be thrown. + * + * \param [in] vmin begin of range. This value is included in range (included). + * \param [in] vmax end of range. This value is \b not included in range (excluded). + * \return if all ids in \a this are so that (*this)[i]==i for all i in [ 0, \c this->getNumberOfTuples() ). */ +bool DataArrayInt::checkAllIdsInRange(int vmin, int vmax) const +{ + checkAllocated(); + if(getNumberOfComponents()!=1) + throw INTERP_KERNEL::Exception("DataArrayInt::checkAllIdsInRange : this must have exactly one component !"); + int nbOfTuples=getNumberOfTuples(); + bool ret=true; + const int *cptr=getConstPointer(); + for(int i=0;i<nbOfTuples;i++,cptr++) + { + if(*cptr>=vmin && *cptr<vmax) + { ret=ret && *cptr==i; } + else + { + std::ostringstream oss; oss << "DataArrayInt::checkAllIdsInRange : tuple #" << i << " has value " << *cptr << " should be in [" << vmin << "," << vmax << ") !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + } + return ret; +} + +/*! + * Modify all elements of \a this array, so that + * an element _x_ becomes <em> val % x </em>. + * \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) +{ + checkAllocated(); + int *ptr=getPointer(); + std::size_t nbOfElems=getNbOfElems(); + for(std::size_t i=0;i<nbOfElems;i++,ptr++) + { + if(*ptr>0) + { + *ptr=val%(*ptr); + } + else + { + std::ostringstream oss; oss << "DataArrayInt::applyRModulus : presence of value <=0 in tuple #" << i/getNumberOfComponents() << " component #" << i%getNumberOfComponents(); + oss << " !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + } + declareAsNew(); +} + +/*! + * Modify all elements of \a this array, so that + * an element _x_ becomes <em> val ^ x </em>. + * \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) +{ + 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<nbOfElems;i++,ptr++) + { + int tmp=1; + for(int j=0;j<val;j++) + tmp*=*ptr; + *ptr=tmp; + } + declareAsNew(); +} + +/*! + * Modify all elements of \a this array, so that + * an element _x_ becomes \f$ val ^ x \f$. + * \param [in] val - the value used to apply pow on all array elements. + * \throw If \a this is not allocated. + * \throw If there is an element < 0 in \a this array. + * \warning If an exception is thrown because of presence of 0 element in \a this + * array, all elements processed before detection of the zero element remain + * modified. + */ +void DataArrayInt::applyRPow(int val) +{ + checkAllocated(); + int *ptr=getPointer(); + std::size_t nbOfElems=getNbOfElems(); + for(std::size_t i=0;i<nbOfElems;i++,ptr++) + { + if(*ptr>=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) +{ + std::vector<const DataArrayInt *> arr(2); + arr[0]=a1; arr[1]=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<const DataArrayInt *>& arr) +{ + std::vector<const DataArrayInt *> a; + for(std::vector<const DataArrayInt *>::const_iterator it4=arr.begin();it4!=arr.end();it4++) + if(*it4) + a.push_back(*it4); + if(a.empty()) + throw INTERP_KERNEL::Exception("DataArrayInt::Meld : array must be NON empty !"); + std::vector<const DataArrayInt *>::const_iterator it; + for(it=a.begin();it!=a.end();it++) + (*it)->checkAllocated(); + it=a.begin(); + int nbOfTuples=(*it)->getNumberOfTuples(); + std::vector<int> nbc(a.size()); + std::vector<const int *> 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("DataArrayInt::meld : mismatch of number of tuples !"); + nbc[i]=(*it)->getNumberOfComponents(); + pts[i]=(*it)->getConstPointer(); + } + int totalNbOfComp=std::accumulate(nbc.begin(),nbc.end(),0); + DataArrayInt *ret=DataArrayInt::New(); + ret->alloc(nbOfTuples,totalNbOfComp); + int *retPtr=ret->getPointer(); + for(int i=0;i<nbOfTuples;i++) + for(int j=0;j<(int)a.size();j++) + { + retPtr=std::copy(pts[j],pts[j]+nbc[j],retPtr); + pts[j]+=nbc[j]; + } + int k=0; + for(int i=0;i<(int)a.size();i++) + for(int j=0;j<nbc[i];j++,k++) + ret->setInfoOnComponent(k,a[i]->getInfoOnComponent(j)); + return ret; +} + +/*! + * Returns a new DataArrayInt which is a minimal partition of elements of \a groups. + * The i-th item of the result array is an ID of a set of elements belonging to a + * unique set of groups, which the i-th element is a part of. This set of elements + * belonging to a unique set of groups is called \a family, so the result array contains + * IDs of families each element belongs to. + * + * \b Example: if we have two groups of elements: \a group1 [0,4] and \a group2 [ 0,1,2 ], + * then there are 3 families: + * - \a family1 (with ID 1) contains element [0] belonging to ( \a group1 + \a group2 ), + * - \a family2 (with ID 2) contains elements [4] belonging to ( \a group1 ), + * - \a family3 (with ID 3) contains element [1,2] belonging to ( \a group2 ), <br> + * and the result array contains IDs of families [ 1,3,3,0,2 ]. <br> Note a family ID 0 which + * stands for the element #3 which is in none of groups. + * + * \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<const DataArrayInt *>& groups, int newNb, std::vector< std::vector<int> >& fidsOfGroups) +{ + std::vector<const DataArrayInt *> groups2; + for(std::vector<const DataArrayInt *>::const_iterator it4=groups.begin();it4!=groups.end();it4++) + if(*it4) + groups2.push_back(*it4); + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New(); + ret->alloc(newNb,1); + int *retPtr=ret->getPointer(); + std::fill(retPtr,retPtr+newNb,0); + int fid=1; + for(std::vector<const DataArrayInt *>::const_iterator iter=groups2.begin();iter!=groups2.end();iter++) + { + const int *ptr=(*iter)->getConstPointer(); + std::size_t nbOfElem=(*iter)->getNbOfElems(); + int sfid=fid; + for(int j=0;j<sfid;j++) + { + bool found=false; + for(std::size_t i=0;i<nbOfElem;i++) + { + if(ptr[i]>=0 && ptr[i]<newNb) + { + if(retPtr[ptr[i]]==j) + { + retPtr[ptr[i]]=fid; + found=true; + } + } + else + { + std::ostringstream oss; oss << "DataArrayInt::MakePartition : In group \"" << (*iter)->getName() << "\" in tuple #" << i << " value = " << ptr[i] << " ! Should be in [0," << newNb; + oss << ") !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + } + if(found) + fid++; + } + } + fidsOfGroups.clear(); + fidsOfGroups.resize(groups2.size()); + int grId=0; + for(std::vector<const DataArrayInt *>::const_iterator iter=groups2.begin();iter!=groups2.end();iter++,grId++) + { + std::set<int> tmp; + const int *ptr=(*iter)->getConstPointer(); + 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()); + } + 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<const DataArrayInt *>& arr) +{ + std::vector<const DataArrayInt *> a; + for(std::vector<const DataArrayInt *>::const_iterator it4=arr.begin();it4!=arr.end();it4++) + if(*it4) + a.push_back(*it4); + for(std::vector<const DataArrayInt *>::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 !"); + } + // + std::set<int> r; + for(std::vector<const DataArrayInt *>::const_iterator it=a.begin();it!=a.end();it++) + { + const int *pt=(*it)->getConstPointer(); + int nbOfTuples=(*it)->getNumberOfTuples(); + r.insert(pt,pt+nbOfTuples); + } + DataArrayInt *ret=DataArrayInt::New(); + ret->alloc((int)r.size(),1); + std::copy(r.begin(),r.end(),ret->getPointer()); + 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<const DataArrayInt *>& arr) +{ + std::vector<const DataArrayInt *> a; + for(std::vector<const DataArrayInt *>::const_iterator it4=arr.begin();it4!=arr.end();it4++) + if(*it4) + a.push_back(*it4); + for(std::vector<const DataArrayInt *>::const_iterator it=a.begin();it!=a.end();it++) + { + (*it)->checkAllocated(); + if((*it)->getNumberOfComponents()!=1) + throw INTERP_KERNEL::Exception("DataArrayInt::BuildIntersection : only single component allowed !"); + } + // + std::set<int> r; + for(std::vector<const DataArrayInt *>::const_iterator it=a.begin();it!=a.end();it++) + { + const int *pt=(*it)->getConstPointer(); + int nbOfTuples=(*it)->getNumberOfTuples(); + std::set<int> s1(pt,pt+nbOfTuples); + if(it!=a.begin()) + { + std::set<int> r2; + std::set_intersection(r.begin(),r.end(),s1.begin(),s1.end(),inserter(r2,r2.end())); + r=r2; + } + else + r=s1; + } + DataArrayInt *ret(DataArrayInt::New()); + ret->alloc((int)r.size(),1); + std::copy(r.begin(),r.end(),ret->getPointer()); + return ret; +} + +/// @cond INTERNAL +namespace ParaMEDMEMImpl +{ + class OpSwitchedOn + { + public: + OpSwitchedOn(int *pt):_pt(pt),_cnt(0) { } + void operator()(const bool& b) { if(b) *_pt++=_cnt; _cnt++; } + private: + int *_pt; + int _cnt; + }; + + class OpSwitchedOff + { + public: + OpSwitchedOff(int *pt):_pt(pt),_cnt(0) { } + void operator()(const bool& b) { if(!b) *_pt++=_cnt; _cnt++; } + private: + int *_pt; + int _cnt; + }; +} +/// @endcond + +/*! + * This method returns the list of ids in ascending mode so that v[id]==true. + */ +DataArrayInt *DataArrayInt::BuildListOfSwitchedOn(const std::vector<bool>& v) +{ + int sz((int)std::count(v.begin(),v.end(),true)); + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(sz,1); + std::for_each(v.begin(),v.end(),ParaMEDMEMImpl::OpSwitchedOn(ret->getPointer())); + return ret.retn(); +} + +/*! + * This method returns the list of ids in ascending mode so that v[id]==false. + */ +DataArrayInt *DataArrayInt::BuildListOfSwitchedOff(const std::vector<bool>& v) +{ + int sz((int)std::count(v.begin(),v.end(),false)); + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(sz,1); + std::for_each(v.begin(),v.end(),ParaMEDMEMImpl::OpSwitchedOff(ret->getPointer())); + return ret.retn(); +} + +/*! + * This method allows to put a vector of vector of integer into a more compact data stucture (skyline). + * This method is not available into python because no available optimized data structure available to map std::vector< std::vector<int> >. + * + * \param [in] v the input data structure to be translate into skyline format. + * \param [out] data the first element of the skyline format. The user is expected to deal with newly allocated array. + * \param [out] dataIndex the second element of the skyline format. + */ +void DataArrayInt::PutIntoToSkylineFrmt(const std::vector< std::vector<int> >& v, DataArrayInt *& data, DataArrayInt *& dataIndex) +{ + int sz((int)v.size()); + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret0(DataArrayInt::New()),ret1(DataArrayInt::New()); + ret1->alloc(sz+1,1); + int *pt(ret1->getPointer()); *pt=0; + for(int i=0;i<sz;i++,pt++) + pt[1]=pt[0]+(int)v[i].size(); + ret0->alloc(ret1->back(),1); + pt=ret0->getPointer(); + for(int i=0;i<sz;i++) + pt=std::copy(v[i].begin(),v[i].end(),pt); + data=ret0.retn(); dataIndex=ret1.retn(); +} + +/*! + * Returns a new DataArrayInt which contains a complement of elements of \a this + * one-dimensional array. I.e. the result array contains all elements from the range [0, + * \a nbOfElement) not present in \a this array. + * \param [in] nbOfElement - maximal size of the result array. + * \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 any element \a x of \a this array violates condition ( 0 <= \a x < \a + * nbOfElement ). + */ +DataArrayInt *DataArrayInt::buildComplement(int nbOfElement) const +{ + checkAllocated(); + if(getNumberOfComponents()!=1) + throw INTERP_KERNEL::Exception("DataArrayInt::buildComplement : only single component allowed !"); + std::vector<bool> tmp(nbOfElement); + const int *pt=getConstPointer(); + int nbOfTuples=getNumberOfTuples(); + for(const int *w=pt;w!=pt+nbOfTuples;w++) + if(*w>=0 && *w<nbOfElement) + tmp[*w]=true; + else + throw INTERP_KERNEL::Exception("DataArrayInt::buildComplement : an element is not in valid range : [0,nbOfElement) !"); + int nbOfRetVal=(int)std::count(tmp.begin(),tmp.end(),false); + DataArrayInt *ret=DataArrayInt::New(); + ret->alloc(nbOfRetVal,1); + int j=0; + int *retPtr=ret->getPointer(); + for(int i=0;i<nbOfElement;i++) + if(!tmp[i]) + retPtr[j++]=i; + 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 +{ + if(!other) + throw INTERP_KERNEL::Exception("DataArrayInt::buildSubstraction : DataArrayInt pointer in input is NULL !"); + checkAllocated(); + other->checkAllocated(); + if(getNumberOfComponents()!=1) + throw INTERP_KERNEL::Exception("DataArrayInt::buildSubstraction : only single component allowed !"); + if(other->getNumberOfComponents()!=1) + throw INTERP_KERNEL::Exception("DataArrayInt::buildSubstraction : only single component allowed for other type !"); + const int *pt=getConstPointer(); + int nbOfTuples=getNumberOfTuples(); + std::set<int> s1(pt,pt+nbOfTuples); + pt=other->getConstPointer(); + nbOfTuples=other->getNumberOfTuples(); + std::set<int> s2(pt,pt+nbOfTuples); + std::vector<int> r; + std::set_difference(s1.begin(),s1.end(),s2.begin(),s2.end(),std::back_insert_iterator< std::vector<int> >(r)); + DataArrayInt *ret=DataArrayInt::New(); + ret->alloc((int)r.size(),1); + std::copy(r.begin(),r.end(),ret->getPointer()); + 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 +{ + 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()); + const int *work1(pt1Bg),*work2(pt2Bg); + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> 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 +{ + std::vector<const DataArrayInt *>arrs(2); + arrs[0]=this; arrs[1]=other; + 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 +{ + std::vector<const DataArrayInt *>arrs(2); + arrs[0]=this; arrs[1]=other; + return BuildIntersection(arrs); +} + +/*! + * This method can be applied on allocated with one component DataArrayInt instance. + * This method is typically relevant for sorted arrays. All consecutive duplicated items in \a this will appear only once in returned DataArrayInt instance. + * Example : if \a this contains [1,2,2,3,3,3,3,4,5,5,7,7,7,19] the returned array will contain [1,2,3,4,5,7,19] + * + * \return a newly allocated array that contain the result of the unique operation applied on \a this. + * \throw if \a this is not allocated or if \a this has not exactly one component. + * \sa DataArrayInt::buildUniqueNotSorted + */ +DataArrayInt *DataArrayInt::buildUnique() const +{ + checkAllocated(); + if(getNumberOfComponents()!=1) + throw INTERP_KERNEL::Exception("DataArrayInt::buildUnique : only single component allowed !"); + int nbOfTuples=getNumberOfTuples(); + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> tmp=deepCpy(); + int *data=tmp->getPointer(); + int *last=std::unique(data,data+nbOfTuples); + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New(); + ret->alloc(std::distance(data,last),1); + std::copy(data,last,ret->getPointer()); + return ret.retn(); +} + +/*! + * This method can be applied on allocated with one component DataArrayInt instance. + * This method keep elements only once by keeping the same order in \a this that is not expected to be sorted. + * + * \return a newly allocated array that contain the result of the unique operation applied on \a this. + * + * \throw if \a this is not allocated or if \a this has not exactly one component. + * + * \sa DataArrayInt::buildUnique + */ +DataArrayInt *DataArrayInt::buildUniqueNotSorted() const +{ + checkAllocated(); + if(getNumberOfComponents()!=1) + throw INTERP_KERNEL::Exception("DataArrayInt::buildUniqueNotSorted : only single component allowed !"); + int minVal,maxVal; + getMinMaxValues(minVal,maxVal); + std::vector<bool> b(maxVal-minVal+1,false); + const int *ptBg(begin()),*endBg(end()); + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1); + for(const int *pt=ptBg;pt!=endBg;pt++) + { + if(!b[*pt-minVal]) + { + ret->pushBackSilent(*pt); + b[*pt-minVal]=true; + } + } + ret->copyStringInfoFrom(*this); + return ret.retn(); +} + +/*! + * 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. + * This method preforms the reverse operation of DataArrayInt::computeOffsets2. + * \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: <br> + * - 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. + * + * \sa DataArrayInt::computeOffsets2 + */ +DataArrayInt *DataArrayInt::deltaShiftIndex() const +{ + checkAllocated(); + if(getNumberOfComponents()!=1) + throw INTERP_KERNEL::Exception("DataArrayInt::deltaShiftIndex : only single component allowed !"); + int nbOfTuples=getNumberOfTuples(); + if(nbOfTuples<2) + throw INTERP_KERNEL::Exception("DataArrayInt::deltaShiftIndex : 1 tuple at least must be present in 'this' !"); + const int *ptr=getConstPointer(); + DataArrayInt *ret=DataArrayInt::New(); + ret->alloc(nbOfTuples-1,1); + int *out=ret->getPointer(); + std::transform(ptr+1,ptr+nbOfTuples,ptr,out,std::minus<int>()); + return ret; +} + +/*! + * 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.<br> + * 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: <br> + * - Before \a this contains [3,5,1,2,0,8] + * - After \a this contains [0,3,8,9,11,11]<br> + * 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() +{ + checkAllocated(); + if(getNumberOfComponents()!=1) + throw INTERP_KERNEL::Exception("DataArrayInt::computeOffsets : only single component allowed !"); + int nbOfTuples=getNumberOfTuples(); + if(nbOfTuples==0) + return ; + int *work=getPointer(); + int tmp=work[0]; + work[0]=0; + for(int i=1;i<nbOfTuples;i++) + { + int tmp2=work[i]; + work[i]=work[i-1]+tmp; + tmp=tmp2; + } + declareAsNew(); +} + + +/*! + * 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.<br> + * 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. + * This method preforms the reverse operation of DataArrayInt::deltaShiftIndex. + * \throw If \a this is not allocated. + * \throw If \a this->getNumberOfComponents() != 1. + * + * \b Example: <br> + * - Before \a this contains [3,5,1,2,0,8] + * - After \a this contains [0,3,8,9,11,11,19]<br> + * \sa DataArrayInt::deltaShiftIndex + */ +void DataArrayInt::computeOffsets2() +{ + checkAllocated(); + if(getNumberOfComponents()!=1) + throw INTERP_KERNEL::Exception("DataArrayInt::computeOffsets2 : only single component allowed !"); + int nbOfTuples=getNumberOfTuples(); + int *ret=(int *)malloc((nbOfTuples+1)*sizeof(int)); + if(nbOfTuples==0) + return ; + const int *work=getConstPointer(); + ret[0]=0; + for(int i=0;i<nbOfTuples;i++) + ret[i+1]=work[i]+ret[i]; + useArray(ret,true,C_DEALLOC,nbOfTuples+1,1); + declareAsNew(); +} + +/*! + * 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: <br> + * - \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. + * <br> + */ +void DataArrayInt::searchRangesInListOfIds(const DataArrayInt *listOfIds, DataArrayInt *& rangeIdsFetched, DataArrayInt *& idsInInputListThatFetch) const +{ + 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<DataArrayInt> ret0=DataArrayInt::New(); ret0->alloc(0,1); + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> 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(i<offPtr[1] && *tupPtr==i && tupPtr!=tupEnd) { i++; tupPtr++; } + if(i==offPtr[1]) + { + ret0->pushBackSilent((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: <br> + * - \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] == <br> + * \c range(0,3) + \c range(6,10) + \c range(10,14) ==<br> + * \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 +{ + if(!offsets) + throw INTERP_KERNEL::Exception("DataArrayInt::buildExplicitArrByRanges : DataArrayInt pointer in input is NULL !"); + checkAllocated(); + if(getNumberOfComponents()!=1) + throw INTERP_KERNEL::Exception("DataArrayInt::buildExplicitArrByRanges : only single component allowed !"); + offsets->checkAllocated(); + if(offsets->getNumberOfComponents()!=1) + throw INTERP_KERNEL::Exception("DataArrayInt::buildExplicitArrByRanges : input array should have only single component !"); + int othNbTuples=offsets->getNumberOfTuples()-1; + int nbOfTuples=getNumberOfTuples(); + int retNbOftuples=0; + const int *work=getConstPointer(); + const int *offPtr=offsets->getConstPointer(); + for(int i=0;i<nbOfTuples;i++) + { + int val=work[i]; + if(val>=0 && val<othNbTuples) + { + int delta=offPtr[val+1]-offPtr[val]; + if(delta>=0) + retNbOftuples+=delta; + else + { + std::ostringstream oss; oss << "DataArrayInt::buildExplicitArrByRanges : Tuple #" << val << " of offset array has a delta < 0 !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + } + else + { + std::ostringstream oss; oss << "DataArrayInt::buildExplicitArrByRanges : Tuple #" << i << " in this contains " << val; + oss << " whereas offsets array is of size " << othNbTuples+1 << " !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + } + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New(); + ret->alloc(retNbOftuples,1); + int *retPtr=ret->getPointer(); + for(int i=0;i<nbOfTuples;i++) + { + int val=work[i]; + int start=offPtr[val]; + int off=offPtr[val+1]-start; + for(int j=0;j<off;j++,retPtr++) + *retPtr=start+j; + } + return ret.retn(); +} + +/*! + * Returns a new DataArrayInt whose contents is computed using \a this that must be a + * scaled array (monotonically increasing). +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 is NULL. + * \throw If \a this is not allocated. + * \throw If \a this->getNumberOfComponents() != 1. + * \throw If \a this->getNumberOfTuples() == 0. + * \throw If \a this is not monotonically increasing. + * \throw If any element of ids in ( \a bg \a stop \a step ) points outside the scale in \a this. + * + * \b Example: <br> + * - \a bg , \a stop and \a step : (0,5,2) + * - \a this: [0,3,6,10,14,20] + * - result array: [0,0,0, 2,2,2,2, 4,4,4,4,4,4] == <br> + */ +DataArrayInt *DataArrayInt::buildExplicitArrOfSliceOnScaledArr(int bg, int stop, int step) const +{ + if(!isAllocated()) + throw INTERP_KERNEL::Exception("DataArrayInt::buildExplicitArrOfSliceOnScaledArr : not allocated array !"); + if(getNumberOfComponents()!=1) + throw INTERP_KERNEL::Exception("DataArrayInt::buildExplicitArrOfSliceOnScaledArr : number of components is expected to be equal to one !"); + int nbOfTuples(getNumberOfTuples()); + if(nbOfTuples==0) + throw INTERP_KERNEL::Exception("DataArrayInt::buildExplicitArrOfSliceOnScaledArr : number of tuples must be != 0 !"); + const int *ids(begin()); + int nbOfEltsInSlc(GetNumberOfItemGivenBESRelative(bg,stop,step,"DataArrayInt::buildExplicitArrOfSliceOnScaledArr")),sz(0),pos(bg); + for(int i=0;i<nbOfEltsInSlc;i++,pos+=step) + { + if(pos>=0 && pos<nbOfTuples-1) + { + int delta(ids[pos+1]-ids[pos]); + sz+=delta; + if(delta<0) + { + std::ostringstream oss; oss << "DataArrayInt::buildExplicitArrOfSliceOnScaledArr : At pos #" << i << " of input slice, value is " << pos << " and at this pos this is not monotonically increasing !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + } + else + { + std::ostringstream oss; oss << "DataArrayInt::buildExplicitArrOfSliceOnScaledArr : At pos #" << i << " of input slice, value is " << pos << " should be in [0," << nbOfTuples-1 << ") !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + } + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(sz,1); + int *retPtr(ret->getPointer()); + pos=bg; + for(int i=0;i<nbOfEltsInSlc;i++,pos+=step) + { + int delta(ids[pos+1]-ids[pos]); + for(int j=0;j<delta;j++,retPtr++) + *retPtr=pos; + } + return ret.retn(); +} + +/*! + * Given in input ranges \a ranges, it returns a newly allocated DataArrayInt instance having one component and the same number of tuples than \a this. + * For each tuple at place **i** in \a this it tells which is the first range in \a ranges that contains value \c this->getIJ(i,0) and put the result + * in tuple **i** of returned DataArrayInt. + * If ranges overlapped (in theory it should not) this method do not detect it and always returns the first range. + * + * For example if \a this contains : [1,24,7,8,10,17] and \a ranges contains [(0,3),(3,8),(8,15),(15,22),(22,30)] + * The return DataArrayInt will contain : **[0,4,1,2,2,3]** + * + * \param [in] ranges typically come from output of MEDCouplingUMesh::ComputeRangesFromTypeDistribution. Each range is specified like this : 1st component is + * for lower value included and 2nd component is the upper value of corresponding range **excluded**. + * \throw If offsets is a null pointer or does not have 2 components or if \a this is not allocated or \a this do not have exactly one component. To finish an exception + * is thrown if no ranges in \a ranges contains value in \a this. + * + * \sa DataArrayInt::findIdInRangeForEachTuple + */ +DataArrayInt *DataArrayInt::findRangeIdForEachTuple(const DataArrayInt *ranges) const +{ + if(!ranges) + throw INTERP_KERNEL::Exception("DataArrayInt::findRangeIdForEachTuple : null input pointer !"); + if(ranges->getNumberOfComponents()!=2) + throw INTERP_KERNEL::Exception("DataArrayInt::findRangeIdForEachTuple : input DataArrayInt instance should have 2 components !"); + checkAllocated(); + if(getNumberOfComponents()!=1) + throw INTERP_KERNEL::Exception("DataArrayInt::findRangeIdForEachTuple : this should have only one component !"); + int nbTuples=getNumberOfTuples(); + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(nbTuples,1); + int nbOfRanges=ranges->getNumberOfTuples(); + const int *rangesPtr=ranges->getConstPointer(); + int *retPtr=ret->getPointer(); + const int *inPtr=getConstPointer(); + for(int i=0;i<nbTuples;i++,retPtr++) + { + int val=inPtr[i]; + bool found=false; + for(int j=0;j<nbOfRanges && !found;j++) + if(val>=rangesPtr[2*j] && val<rangesPtr[2*j+1]) + { *retPtr=j; found=true; } + if(found) + continue; + else + { + std::ostringstream oss; oss << "DataArrayInt::findRangeIdForEachTuple : tuple #" << i << " not found by any ranges !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + } + return ret.retn(); +} + +/*! + * Given in input ranges \a ranges, it returns a newly allocated DataArrayInt instance having one component and the same number of tuples than \a this. + * For each tuple at place **i** in \a this it tells which is the sub position of the first range in \a ranges that contains value \c this->getIJ(i,0) and put the result + * in tuple **i** of returned DataArrayInt. + * If ranges overlapped (in theory it should not) this method do not detect it and always returns the sub position of the first range. + * + * For example if \a this contains : [1,24,7,8,10,17] and \a ranges contains [(0,3),(3,8),(8,15),(15,22),(22,30)] + * The return DataArrayInt will contain : **[1,2,4,0,2,2]** + * This method is often called in pair with DataArrayInt::findRangeIdForEachTuple method. + * + * \param [in] ranges typically come from output of MEDCouplingUMesh::ComputeRangesFromTypeDistribution. Each range is specified like this : 1st component is + * for lower value included and 2nd component is the upper value of corresponding range **excluded**. + * \throw If offsets is a null pointer or does not have 2 components or if \a this is not allocated or \a this do not have exactly one component. To finish an exception + * is thrown if no ranges in \a ranges contains value in \a this. + * \sa DataArrayInt::findRangeIdForEachTuple + */ +DataArrayInt *DataArrayInt::findIdInRangeForEachTuple(const DataArrayInt *ranges) const +{ + if(!ranges) + throw INTERP_KERNEL::Exception("DataArrayInt::findIdInRangeForEachTuple : null input pointer !"); + if(ranges->getNumberOfComponents()!=2) + throw INTERP_KERNEL::Exception("DataArrayInt::findIdInRangeForEachTuple : input DataArrayInt instance should have 2 components !"); + checkAllocated(); + if(getNumberOfComponents()!=1) + throw INTERP_KERNEL::Exception("DataArrayInt::findIdInRangeForEachTuple : this should have only one component !"); + int nbTuples=getNumberOfTuples(); + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(nbTuples,1); + int nbOfRanges=ranges->getNumberOfTuples(); + const int *rangesPtr=ranges->getConstPointer(); + int *retPtr=ret->getPointer(); + const int *inPtr=getConstPointer(); + for(int i=0;i<nbTuples;i++,retPtr++) + { + int val=inPtr[i]; + bool found=false; + for(int j=0;j<nbOfRanges && !found;j++) + if(val>=rangesPtr[2*j] && val<rangesPtr[2*j+1]) + { *retPtr=val-rangesPtr[2*j]; found=true; } + if(found) + continue; + else + { + std::ostringstream oss; oss << "DataArrayInt::findIdInRangeForEachTuple : tuple #" << i << " not found by any ranges !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + } + return ret.retn(); +} + +/*! + * \b WARNING this method is a \b non \a const \b method. This method works tuple by tuple. Each tuple is expected to be pairs (number of components must be equal to 2). + * This method rearrange each pair in \a this so that, tuple with id \b tid will be after the call \c this->getIJ(tid,0)==this->getIJ(tid-1,1) and \c this->getIJ(tid,1)==this->getIJ(tid+1,0). + * If it is impossible to reach such condition an exception will be thrown ! \b WARNING In case of throw \a this can be partially modified ! + * If this method has correctly worked, \a this will be able to be considered as a linked list. + * This method does nothing if number of tuples is lower of equal to 1. + * + * This method is useful for users having an unstructured mesh having only SEG2 to rearrange internaly the connectibity without any coordinates consideration. + * + * \sa MEDCouplingUMesh::orderConsecutiveCells1D + */ +void DataArrayInt::sortEachPairToMakeALinkedList() +{ + checkAllocated(); + if(getNumberOfComponents()!=2) + throw INTERP_KERNEL::Exception("DataArrayInt::sortEachPairToMakeALinkedList : Only works on DataArrayInt instance with nb of components equal to 2 !"); + int nbOfTuples(getNumberOfTuples()); + if(nbOfTuples<=1) + return ; + int *conn(getPointer()); + for(int i=1;i<nbOfTuples;i++,conn+=2) + { + if(i>1) + { + if(conn[2]==conn[3]) + { + std::ostringstream oss; oss << "DataArrayInt::sortEachPairToMakeALinkedList : In the tuple #" << i << " presence of a pair filled with same ids !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + if(conn[2]!=conn[1] && conn[3]==conn[1] && conn[2]!=conn[0]) + std::swap(conn[2],conn[3]); + //not(conn[2]==conn[1] && conn[3]!=conn[1] && conn[3]!=conn[0]) + if(conn[2]!=conn[1] || conn[3]==conn[1] || conn[3]==conn[0]) + { + std::ostringstream oss; oss << "DataArrayInt::sortEachPairToMakeALinkedList : In the tuple #" << i << " something is invalid !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + } + else + { + if(conn[0]==conn[1] || conn[2]==conn[3]) + throw INTERP_KERNEL::Exception("DataArrayInt::sortEachPairToMakeALinkedList : In the 2 first tuples presence of a pair filled with same ids !"); + int tmp[4]; + std::set<int> s; + s.insert(conn,conn+4); + if(s.size()!=3) + throw INTERP_KERNEL::Exception("DataArrayInt::sortEachPairToMakeALinkedList : This can't be considered as a linked list regarding 2 first tuples !"); + if(std::count(conn,conn+4,conn[0])==2) + { + tmp[0]=conn[1]; + tmp[1]=conn[0]; + tmp[2]=conn[0]; + if(conn[2]==conn[0]) + { tmp[3]=conn[3]; } + else + { tmp[3]=conn[2];} + std::copy(tmp,tmp+4,conn); + } + } + } +} + +/*! + * + * \param [in] nbTimes specifies the nb of times each tuples in \a this will be duplicated contiguouly in returned DataArrayInt instance. + * \a nbTimes should be at least equal to 1. + * \return a newly allocated DataArrayInt having one component and number of tuples equal to \a nbTimes * \c this->getNumberOfTuples. + * \throw if \a this is not allocated or if \a this has not number of components set to one or if \a nbTimes is lower than 1. + */ +DataArrayInt *DataArrayInt::duplicateEachTupleNTimes(int nbTimes) const +{ + checkAllocated(); + if(getNumberOfComponents()!=1) + throw INTERP_KERNEL::Exception("DataArrayInt::duplicateEachTupleNTimes : this should have only one component !"); + if(nbTimes<1) + throw INTERP_KERNEL::Exception("DataArrayInt::duplicateEachTupleNTimes : nb times should be >= 1 !"); + int nbTuples=getNumberOfTuples(); + const int *inPtr=getConstPointer(); + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(nbTimes*nbTuples,1); + int *retPtr=ret->getPointer(); + for(int i=0;i<nbTuples;i++,inPtr++) + { + int val=*inPtr; + for(int j=0;j<nbTimes;j++,retPtr++) + *retPtr=val; + } + ret->copyStringInfoFrom(*this); + 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. + */ +DataArrayInt *DataArrayInt::getDifferentValues() const +{ + checkAllocated(); + std::set<int> ret; + ret.insert(begin(),end()); + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret2=DataArrayInt::New(); ret2->alloc((int)ret.size(),1); + std::copy(ret.begin(),ret.end(),ret2->getPointer()); + return ret2.retn(); +} + +/*! + * This method is a refinement of DataArrayInt::getDifferentValues because it returns not only different values in \a this but also, for each of + * them it tells which tuple id have this id. + * This method works only on arrays with one component (if it is not the case call DataArrayInt::rearrange(1) ). + * This method returns two arrays having same size. + * The instances of DataArrayInt in the returned vector have be specially allocated and computed by this method. Each of them should be dealt by the caller of this method. + * Example : if this is equal to [1,0,1,2,0,2,2,-3,2] -> differentIds=[-3,0,1,2] and returned array will be equal to [[7],[1,4],[0,2],[3,5,6,8]] + */ +std::vector<DataArrayInt *> DataArrayInt::partitionByDifferentValues(std::vector<int>& differentIds) const +{ + checkAllocated(); + if(getNumberOfComponents()!=1) + throw INTERP_KERNEL::Exception("DataArrayInt::partitionByDifferentValues : this should have only one component !"); + int id=0; + std::map<int,int> m,m2,m3; + for(const int *w=begin();w!=end();w++) + m[*w]++; + differentIds.resize(m.size()); + std::vector<DataArrayInt *> ret(m.size()); + std::vector<int *> retPtr(m.size()); + for(std::map<int,int>::const_iterator it=m.begin();it!=m.end();it++,id++) + { + m2[(*it).first]=id; + ret[id]=DataArrayInt::New(); + ret[id]->alloc((*it).second,1); + retPtr[id]=ret[id]->getPointer(); + differentIds[id]=(*it).first; + } + id=0; + for(const int *w=begin();w!=end();w++,id++) + { + retPtr[m2[*w]][m3[*w]++]=id; + } + return ret; +} + +/*! + * This method split ids in [0, \c this->getNumberOfTuples() ) using \a this array as a field of weight (>=0 each). + * The aim of this method is to return a set of \a nbOfSlices chunk of contiguous ids as balanced as possible. + * + * \param [in] nbOfSlices - number of slices expected. + * \return - a vector having a size equal to \a nbOfSlices giving the start (included) and the stop (excluded) of each chunks. + * + * \sa DataArray::GetSlice + * \throw If \a this is not allocated or not with exactly one component. + * \throw If an element in \a this if < 0. + */ +std::vector< std::pair<int,int> > DataArrayInt::splitInBalancedSlices(int nbOfSlices) const +{ + if(!isAllocated() || getNumberOfComponents()!=1) + throw INTERP_KERNEL::Exception("DataArrayInt::splitInBalancedSlices : this array should have number of components equal to one and must be allocated !"); + if(nbOfSlices<=0) + throw INTERP_KERNEL::Exception("DataArrayInt::splitInBalancedSlices : number of slices must be >= 1 !"); + int sum(accumulate(0)),nbOfTuples(getNumberOfTuples()); + int sumPerSlc(sum/nbOfSlices),pos(0); + const int *w(begin()); + std::vector< std::pair<int,int> > ret(nbOfSlices); + for(int i=0;i<nbOfSlices;i++) + { + std::pair<int,int> p(pos,-1); + int locSum(0); + while(locSum<sumPerSlc && pos<nbOfTuples) { pos++; locSum+=*w++; } + if(i!=nbOfSlices-1) + p.second=pos; + else + p.second=nbOfTuples; + ret[i]=p; + } + 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) +{ + if(!a1 || !a2) + throw INTERP_KERNEL::Exception("DataArrayInt::Add : input DataArrayInt instance is NULL !"); + int nbOfTuple=a1->getNumberOfTuples(); + int nbOfTuple2=a2->getNumberOfTuples(); + int nbOfComp=a1->getNumberOfComponents(); + int nbOfComp2=a2->getNumberOfComponents(); + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=0; + if(nbOfTuple==nbOfTuple2) + { + if(nbOfComp==nbOfComp2) + { + ret=DataArrayInt::New(); + ret->alloc(nbOfTuple,nbOfComp); + std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::plus<int>()); + ret->copyStringInfoFrom(*a1); + } + else + { + int nbOfCompMin,nbOfCompMax; + const DataArrayInt *aMin, *aMax; + if(nbOfComp>nbOfComp2) + { + nbOfCompMin=nbOfComp2; nbOfCompMax=nbOfComp; + aMin=a2; aMax=a1; + } + else + { + nbOfCompMin=nbOfComp; nbOfCompMax=nbOfComp2; + aMin=a1; aMax=a2; + } + if(nbOfCompMin==1) + { + ret=DataArrayInt::New(); + ret->alloc(nbOfTuple,nbOfCompMax); + const int *aMinPtr=aMin->getConstPointer(); + const int *aMaxPtr=aMax->getConstPointer(); + int *res=ret->getPointer(); + for(int i=0;i<nbOfTuple;i++) + res=std::transform(aMaxPtr+i*nbOfCompMax,aMaxPtr+(i+1)*nbOfCompMax,res,std::bind2nd(std::plus<int>(),aMinPtr[i])); + ret->copyStringInfoFrom(*aMax); + } + else + throw INTERP_KERNEL::Exception("Nb of components mismatch for array Add !"); + } + } + else if((nbOfTuple==1 && nbOfTuple2>1) || (nbOfTuple>1 && nbOfTuple2==1)) + { + if(nbOfComp==nbOfComp2) + { + int nbOfTupleMax=std::max(nbOfTuple,nbOfTuple2); + const DataArrayInt *aMin=nbOfTuple>nbOfTuple2?a2:a1; + const DataArrayInt *aMax=nbOfTuple>nbOfTuple2?a1:a2; + const int *aMinPtr=aMin->getConstPointer(),*aMaxPtr=aMax->getConstPointer(); + ret=DataArrayInt::New(); + ret->alloc(nbOfTupleMax,nbOfComp); + int *res=ret->getPointer(); + for(int i=0;i<nbOfTupleMax;i++) + res=std::transform(aMaxPtr+i*nbOfComp,aMaxPtr+(i+1)*nbOfComp,aMinPtr,res,std::plus<int>()); + ret->copyStringInfoFrom(*aMax); + } + else + throw INTERP_KERNEL::Exception("Nb of components mismatch for array Add !"); + } + else + throw INTERP_KERNEL::Exception("Nb of tuples mismatch for array Add !"); + 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) +{ + 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(); + int nbOfComp2=other->getNumberOfComponents(); + if(nbOfTuple==nbOfTuple2) + { + if(nbOfComp==nbOfComp2) + { + std::transform(begin(),end(),other->begin(),getPointer(),std::plus<int>()); + } + else if(nbOfComp2==1) + { + int *ptr=getPointer(); + const int *ptrc=other->getConstPointer(); + for(int i=0;i<nbOfTuple;i++) + std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptr+i*nbOfComp,std::bind2nd(std::plus<int>(),*ptrc++)); + } + else + throw INTERP_KERNEL::Exception(msg); + } + else if(nbOfTuple2==1) + { + if(nbOfComp2==nbOfComp) + { + int *ptr=getPointer(); + const int *ptrc=other->getConstPointer(); + for(int i=0;i<nbOfTuple;i++) + std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptrc,ptr+i*nbOfComp,std::plus<int>()); + } + else + throw INTERP_KERNEL::Exception(msg); + } + else + throw INTERP_KERNEL::Exception(msg); + 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) +{ + if(!a1 || !a2) + throw INTERP_KERNEL::Exception("DataArrayInt::Substract : input DataArrayInt instance is NULL !"); + int nbOfTuple1=a1->getNumberOfTuples(); + int nbOfTuple2=a2->getNumberOfTuples(); + int nbOfComp1=a1->getNumberOfComponents(); + int nbOfComp2=a2->getNumberOfComponents(); + if(nbOfTuple2==nbOfTuple1) + { + if(nbOfComp1==nbOfComp2) + { + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New(); + ret->alloc(nbOfTuple2,nbOfComp1); + std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::minus<int>()); + ret->copyStringInfoFrom(*a1); + return ret.retn(); + } + else if(nbOfComp2==1) + { + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New(); + ret->alloc(nbOfTuple1,nbOfComp1); + const int *a2Ptr=a2->getConstPointer(); + const int *a1Ptr=a1->getConstPointer(); + int *res=ret->getPointer(); + for(int i=0;i<nbOfTuple1;i++) + res=std::transform(a1Ptr+i*nbOfComp1,a1Ptr+(i+1)*nbOfComp1,res,std::bind2nd(std::minus<int>(),a2Ptr[i])); + ret->copyStringInfoFrom(*a1); + return ret.retn(); + } + else + { + a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Substract !"); + return 0; + } + } + else if(nbOfTuple2==1) + { + a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Substract !"); + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New(); + ret->alloc(nbOfTuple1,nbOfComp1); + const int *a1ptr=a1->getConstPointer(),*a2ptr=a2->getConstPointer(); + int *pt=ret->getPointer(); + for(int i=0;i<nbOfTuple1;i++) + pt=std::transform(a1ptr+i*nbOfComp1,a1ptr+(i+1)*nbOfComp1,a2ptr,pt,std::minus<int>()); + ret->copyStringInfoFrom(*a1); + return ret.retn(); + } + else + { + a1->checkNbOfTuples(nbOfTuple2,"Nb of tuples mismatch for array Substract !");//will always throw an exception + return 0; + } +} + +/*! + * 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) +{ + 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(); + int nbOfComp2=other->getNumberOfComponents(); + if(nbOfTuple==nbOfTuple2) + { + if(nbOfComp==nbOfComp2) + { + std::transform(begin(),end(),other->begin(),getPointer(),std::minus<int>()); + } + else if(nbOfComp2==1) + { + int *ptr=getPointer(); + const int *ptrc=other->getConstPointer(); + for(int i=0;i<nbOfTuple;i++) + std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptr+i*nbOfComp,std::bind2nd(std::minus<int>(),*ptrc++)); + } + else + throw INTERP_KERNEL::Exception(msg); + } + else if(nbOfTuple2==1) + { + int *ptr=getPointer(); + const int *ptrc=other->getConstPointer(); + for(int i=0;i<nbOfTuple;i++) + std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptrc,ptr+i*nbOfComp,std::minus<int>()); + } + else + throw INTERP_KERNEL::Exception(msg); + 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) +{ + if(!a1 || !a2) + throw INTERP_KERNEL::Exception("DataArrayInt::Multiply : input DataArrayInt instance is NULL !"); + int nbOfTuple=a1->getNumberOfTuples(); + int nbOfTuple2=a2->getNumberOfTuples(); + int nbOfComp=a1->getNumberOfComponents(); + int nbOfComp2=a2->getNumberOfComponents(); + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=0; + if(nbOfTuple==nbOfTuple2) + { + if(nbOfComp==nbOfComp2) + { + ret=DataArrayInt::New(); + ret->alloc(nbOfTuple,nbOfComp); + std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::multiplies<int>()); + ret->copyStringInfoFrom(*a1); + } + else + { + int nbOfCompMin,nbOfCompMax; + const DataArrayInt *aMin, *aMax; + if(nbOfComp>nbOfComp2) + { + nbOfCompMin=nbOfComp2; nbOfCompMax=nbOfComp; + aMin=a2; aMax=a1; + } + else + { + nbOfCompMin=nbOfComp; nbOfCompMax=nbOfComp2; + aMin=a1; aMax=a2; + } + if(nbOfCompMin==1) + { + ret=DataArrayInt::New(); + ret->alloc(nbOfTuple,nbOfCompMax); + const int *aMinPtr=aMin->getConstPointer(); + const int *aMaxPtr=aMax->getConstPointer(); + int *res=ret->getPointer(); + for(int i=0;i<nbOfTuple;i++) + res=std::transform(aMaxPtr+i*nbOfCompMax,aMaxPtr+(i+1)*nbOfCompMax,res,std::bind2nd(std::multiplies<int>(),aMinPtr[i])); + ret->copyStringInfoFrom(*aMax); + } + else + throw INTERP_KERNEL::Exception("Nb of components mismatch for array Multiply !"); + } + } + else if((nbOfTuple==1 && nbOfTuple2>1) || (nbOfTuple>1 && nbOfTuple2==1)) + { + if(nbOfComp==nbOfComp2) + { + int nbOfTupleMax=std::max(nbOfTuple,nbOfTuple2); + const DataArrayInt *aMin=nbOfTuple>nbOfTuple2?a2:a1; + const DataArrayInt *aMax=nbOfTuple>nbOfTuple2?a1:a2; + const int *aMinPtr=aMin->getConstPointer(),*aMaxPtr=aMax->getConstPointer(); + ret=DataArrayInt::New(); + ret->alloc(nbOfTupleMax,nbOfComp); + int *res=ret->getPointer(); + for(int i=0;i<nbOfTupleMax;i++) + res=std::transform(aMaxPtr+i*nbOfComp,aMaxPtr+(i+1)*nbOfComp,aMinPtr,res,std::multiplies<int>()); + ret->copyStringInfoFrom(*aMax); + } + else + throw INTERP_KERNEL::Exception("Nb of components mismatch for array Multiply !"); + } + else + throw INTERP_KERNEL::Exception("Nb of tuples mismatch for array Multiply !"); + 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) +{ + 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(); + int nbOfComp2=other->getNumberOfComponents(); + if(nbOfTuple==nbOfTuple2) + { + if(nbOfComp==nbOfComp2) + { + std::transform(begin(),end(),other->begin(),getPointer(),std::multiplies<int>()); + } + else if(nbOfComp2==1) + { + int *ptr=getPointer(); + const int *ptrc=other->getConstPointer(); + for(int i=0;i<nbOfTuple;i++) + std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptr+i*nbOfComp,std::bind2nd(std::multiplies<int>(),*ptrc++)); + } + else + throw INTERP_KERNEL::Exception(msg); + } + else if(nbOfTuple2==1) + { + if(nbOfComp2==nbOfComp) + { + int *ptr=getPointer(); + const int *ptrc=other->getConstPointer(); + for(int i=0;i<nbOfTuple;i++) + std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptrc,ptr+i*nbOfComp,std::multiplies<int>()); + } + else + throw INTERP_KERNEL::Exception(msg); + } + else + throw INTERP_KERNEL::Exception(msg); + 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) +{ + if(!a1 || !a2) + throw INTERP_KERNEL::Exception("DataArrayInt::Divide : input DataArrayInt instance is NULL !"); + int nbOfTuple1=a1->getNumberOfTuples(); + int nbOfTuple2=a2->getNumberOfTuples(); + int nbOfComp1=a1->getNumberOfComponents(); + int nbOfComp2=a2->getNumberOfComponents(); + if(nbOfTuple2==nbOfTuple1) + { + if(nbOfComp1==nbOfComp2) + { + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New(); + ret->alloc(nbOfTuple2,nbOfComp1); + std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::divides<int>()); + ret->copyStringInfoFrom(*a1); + return ret.retn(); + } + else if(nbOfComp2==1) + { + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New(); + ret->alloc(nbOfTuple1,nbOfComp1); + const int *a2Ptr=a2->getConstPointer(); + const int *a1Ptr=a1->getConstPointer(); + int *res=ret->getPointer(); + for(int i=0;i<nbOfTuple1;i++) + res=std::transform(a1Ptr+i*nbOfComp1,a1Ptr+(i+1)*nbOfComp1,res,std::bind2nd(std::divides<int>(),a2Ptr[i])); + ret->copyStringInfoFrom(*a1); + return ret.retn(); + } + else + { + a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Divide !"); + return 0; + } + } + else if(nbOfTuple2==1) + { + a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Divide !"); + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New(); + ret->alloc(nbOfTuple1,nbOfComp1); + const int *a1ptr=a1->getConstPointer(),*a2ptr=a2->getConstPointer(); + int *pt=ret->getPointer(); + for(int i=0;i<nbOfTuple1;i++) + pt=std::transform(a1ptr+i*nbOfComp1,a1ptr+(i+1)*nbOfComp1,a2ptr,pt,std::divides<int>()); + ret->copyStringInfoFrom(*a1); + return ret.retn(); + } + else + { + a1->checkNbOfTuples(nbOfTuple2,"Nb of tuples mismatch for array Divide !");//will always throw an exception + return 0; + } +} + +/*! + * 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) +{ + 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(); + int nbOfComp2=other->getNumberOfComponents(); + if(nbOfTuple==nbOfTuple2) + { + if(nbOfComp==nbOfComp2) + { + std::transform(begin(),end(),other->begin(),getPointer(),std::divides<int>()); + } + else if(nbOfComp2==1) + { + int *ptr=getPointer(); + const int *ptrc=other->getConstPointer(); + for(int i=0;i<nbOfTuple;i++) + std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptr+i*nbOfComp,std::bind2nd(std::divides<int>(),*ptrc++)); + } + else + throw INTERP_KERNEL::Exception(msg); + } + else if(nbOfTuple2==1) + { + if(nbOfComp2==nbOfComp) + { + int *ptr=getPointer(); + const int *ptrc=other->getConstPointer(); + for(int i=0;i<nbOfTuple;i++) + std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptrc,ptr+i*nbOfComp,std::divides<int>()); + } + else + throw INTERP_KERNEL::Exception(msg); + } + else + throw INTERP_KERNEL::Exception(msg); + 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) +{ + if(!a1 || !a2) + throw INTERP_KERNEL::Exception("DataArrayInt::Modulus : input DataArrayInt instance is NULL !"); + int nbOfTuple1=a1->getNumberOfTuples(); + int nbOfTuple2=a2->getNumberOfTuples(); + int nbOfComp1=a1->getNumberOfComponents(); + int nbOfComp2=a2->getNumberOfComponents(); + if(nbOfTuple2==nbOfTuple1) + { + if(nbOfComp1==nbOfComp2) + { + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New(); + ret->alloc(nbOfTuple2,nbOfComp1); + std::transform(a1->begin(),a1->end(),a2->begin(),ret->getPointer(),std::modulus<int>()); + ret->copyStringInfoFrom(*a1); + return ret.retn(); + } + else if(nbOfComp2==1) + { + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New(); + ret->alloc(nbOfTuple1,nbOfComp1); + const int *a2Ptr=a2->getConstPointer(); + const int *a1Ptr=a1->getConstPointer(); + int *res=ret->getPointer(); + for(int i=0;i<nbOfTuple1;i++) + res=std::transform(a1Ptr+i*nbOfComp1,a1Ptr+(i+1)*nbOfComp1,res,std::bind2nd(std::modulus<int>(),a2Ptr[i])); + ret->copyStringInfoFrom(*a1); + return ret.retn(); + } + else + { + a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Modulus !"); + return 0; + } + } + else if(nbOfTuple2==1) + { + a1->checkNbOfComps(nbOfComp2,"Nb of components mismatch for array Modulus !"); + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New(); + ret->alloc(nbOfTuple1,nbOfComp1); + const int *a1ptr=a1->getConstPointer(),*a2ptr=a2->getConstPointer(); + int *pt=ret->getPointer(); + for(int i=0;i<nbOfTuple1;i++) + pt=std::transform(a1ptr+i*nbOfComp1,a1ptr+(i+1)*nbOfComp1,a2ptr,pt,std::modulus<int>()); + ret->copyStringInfoFrom(*a1); + return ret.retn(); + } + else + { + a1->checkNbOfTuples(nbOfTuple2,"Nb of tuples mismatch for array Modulus !");//will always throw an exception + return 0; + } +} + +/*! + * 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) +{ + 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(); + int nbOfComp2=other->getNumberOfComponents(); + if(nbOfTuple==nbOfTuple2) + { + if(nbOfComp==nbOfComp2) + { + std::transform(begin(),end(),other->begin(),getPointer(),std::modulus<int>()); + } + else if(nbOfComp2==1) + { + if(nbOfComp2==nbOfComp) + { + int *ptr=getPointer(); + const int *ptrc=other->getConstPointer(); + for(int i=0;i<nbOfTuple;i++) + std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptr+i*nbOfComp,std::bind2nd(std::modulus<int>(),*ptrc++)); + } + else + throw INTERP_KERNEL::Exception(msg); + } + else + throw INTERP_KERNEL::Exception(msg); + } + else if(nbOfTuple2==1) + { + int *ptr=getPointer(); + const int *ptrc=other->getConstPointer(); + for(int i=0;i<nbOfTuple;i++) + std::transform(ptr+i*nbOfComp,ptr+(i+1)*nbOfComp,ptrc,ptr+i*nbOfComp,std::modulus<int>()); + } + else + throw INTERP_KERNEL::Exception(msg); + 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) +{ + 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<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(nbOfTuple,1); + const int *ptr1(a1->begin()),*ptr2(a2->begin()); + int *ptr=ret->getPointer(); + for(int i=0;i<nbOfTuple;i++,ptr1++,ptr2++,ptr++) + { + if(*ptr2>=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) +{ + 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<nbOfTuple;i++,ptrc++,ptr++) + { + if(*ptrc>=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=(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; + free(ret); + throw INTERP_KERNEL::Exception("Some elements are equals in the specified array !"); + } + std::map<int,int> 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=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) +{ + int nbOfTuples=GetNumberOfItemGivenBESRelative(begin,end,step,"DataArrayInt::Range"); + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New(); + ret->alloc(nbOfTuples,1); + int *ptr=ret->getPointer(); + if(step>0) + { + for(int i=begin;i<end;i+=step,ptr++) + *ptr=i; + } + else + { + for(int i=begin;i>end;i+=step,ptr++) + *ptr=i; + } + return ret.retn(); +} + +/*! + * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class. + * Server side. + */ +void DataArrayInt::getTinySerializationIntInformation(std::vector<int>& tinyInfo) const +{ + tinyInfo.resize(2); + if(isAllocated()) + { + tinyInfo[0]=getNumberOfTuples(); + tinyInfo[1]=getNumberOfComponents(); + } + else + { + tinyInfo[0]=-1; + tinyInfo[1]=-1; + } +} + +/*! + * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class. + * Server side. + */ +void DataArrayInt::getTinySerializationStrInformation(std::vector<std::string>& tinyInfo) const +{ + if(isAllocated()) + { + int nbOfCompo=getNumberOfComponents(); + tinyInfo.resize(nbOfCompo+1); + tinyInfo[0]=getName(); + for(int i=0;i<nbOfCompo;i++) + tinyInfo[i+1]=getInfoOnComponent(i); + } + else + { + tinyInfo.resize(1); + tinyInfo[0]=getName(); + } +} + +/*! + * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class. + * This method returns if a feeding is needed. + */ +bool DataArrayInt::resizeForUnserialization(const std::vector<int>& tinyInfoI) +{ + int nbOfTuple=tinyInfoI[0]; + int nbOfComp=tinyInfoI[1]; + if(nbOfTuple!=-1 || nbOfComp!=-1) + { + alloc(nbOfTuple,nbOfComp); + return true; + } + return false; +} + +/*! + * Useless method for end user. Only for MPI/Corba/File serialsation for multi arrays class. + * This method returns if a feeding is needed. + */ +void DataArrayInt::finishUnserialization(const std::vector<int>& tinyInfoI, const std::vector<std::string>& tinyInfoS) +{ + setName(tinyInfoS[0]); + if(isAllocated()) + { + int nbOfCompo=tinyInfoI[1]; + for(int i=0;i<nbOfCompo;i++) + setInfoOnComponent(i,tinyInfoS[i+1]); + } +} + +DataArrayIntIterator::DataArrayIntIterator(DataArrayInt *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(); + } + } +} + +DataArrayIntIterator::~DataArrayIntIterator() +{ + if(_da) + _da->decrRef(); +} + +DataArrayIntTuple *DataArrayIntIterator::nextt() +{ + if(_tuple_id<_nb_tuple) + { + _tuple_id++; + DataArrayIntTuple *ret=new DataArrayIntTuple(_pt,_nb_comp); + _pt+=_nb_comp; + return ret; + } + else + return 0; +} + +DataArrayIntTuple::DataArrayIntTuple(int *pt, int nbOfComp):_pt(pt),_nb_of_compo(nbOfComp) +{ +} + +std::string DataArrayIntTuple::repr() const +{ + std::ostringstream oss; oss << "("; + for(int i=0;i<_nb_of_compo-1;i++) + oss << _pt[i] << ", "; + oss << _pt[_nb_of_compo-1] << ")"; + return oss.str(); +} + +int DataArrayIntTuple::intValue() const +{ + if(_nb_of_compo==1) + return *_pt; + throw INTERP_KERNEL::Exception("DataArrayIntTuple::intValue : DataArrayIntTuple instance has not exactly 1 component -> Not possible to convert it into an integer !"); +} + +/*! + * This method returns a newly allocated instance the caller should dealed with by a ParaMEDMEM::DataArrayInt::decrRef. + * This method performs \b no copy of data. The content is only referenced using ParaMEDMEM::DataArrayInt::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. + */ +DataArrayInt *DataArrayIntTuple::buildDAInt(int nbOfTuples, int nbOfCompo) const +{ + if((_nb_of_compo==nbOfCompo && nbOfTuples==1) || (_nb_of_compo==nbOfTuples && nbOfCompo==1)) + { + DataArrayInt *ret=DataArrayInt::New(); + ret->useExternalArrayWithRWAccess(_pt,nbOfTuples,nbOfCompo); + return ret; + } + else + { + std::ostringstream oss; oss << "DataArrayIntTuple::buildDAInt : unable to build a requested DataArrayInt 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/medtool/src/MEDCoupling/MEDCouplingMemArray.hxx b/src/medtool/src/MEDCoupling/MEDCouplingMemArray.hxx new file mode 100644 index 000000000..1fc39204c --- /dev/null +++ b/src/medtool/src/MEDCoupling/MEDCouplingMemArray.hxx @@ -0,0 +1,946 @@ +// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 +// 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_MEDCOUPLINGMEMARRAY_HXX__ +#define __PARAMEDMEM_MEDCOUPLINGMEMARRAY_HXX__ + +#include "MEDCoupling.hxx" +#include "MEDCouplingTimeLabel.hxx" +#include "MEDCouplingRefCountObject.hxx" +#include "InterpKernelException.hxx" +#include "BBTreePts.txx" + +#include <string> +#include <vector> +#include <iterator> + +namespace ParaMEDMEM +{ + template<class T> + class MEDCouplingPointer + { + public: + MEDCouplingPointer():_internal(0),_external(0) { } + void null() { _internal=0; _external=0; } + bool isNull() const { return _internal==0 && _external==0; } + void setInternal(T *pointer); + void setExternal(const T *pointer); + const T *getConstPointer() const { if(_internal) return _internal; else return _external; } + 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; + const T *_external; + }; + + template<class T> + class MemArray + { + public: + 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<T>& other); + bool isNull() const { return _pointer.isNull(); } + 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<T> &operator=(const MemArray<T>& other); + 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<T>& 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 reprNotTooLong(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(int nbOfComp); + void alloc(std::size_t nbOfElements); + void reserve(std::size_t newNbOfElements); + void reAlloc(std::size_t newNbOfElements); + 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<class InputIterator> + void insertAtTheEnd(InputIterator first, InputIterator last); + void pushBack(T elem); + T popBack(); + 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: + static void DestroyPointer(T *pt, Deallocator dealloc, void *param); + static Deallocator BuildFromType(DeallocType type); + private: + std::size_t _nb_of_elem; + std::size_t _nb_of_elem_alloc; + bool _ownership; + MEDCouplingPointer<T> _pointer; + Deallocator _dealloc; + void *_param_for_deallocator; + }; + + class DataArrayInt; + class DataArrayByte; + + class DataArray : public RefCountObject, public TimeLabel + { + public: + MEDCOUPLING_EXPORT std::size_t getHeapMemorySizeWithoutChildren() const; + MEDCOUPLING_EXPORT std::vector<const BigMemoryObject *> getDirectChildrenWithNull() const; + MEDCOUPLING_EXPORT void setName(const std::string& name); + MEDCOUPLING_EXPORT void copyStringInfoFrom(const DataArray& other); + MEDCOUPLING_EXPORT void copyPartOfStringInfoFrom(const DataArray& other, const std::vector<int>& compoIds); + MEDCOUPLING_EXPORT void copyPartOfStringInfoFrom2(const std::vector<int>& compoIds, const DataArray& other); + MEDCOUPLING_EXPORT bool areInfoEqualsIfNotWhy(const DataArray& other, std::string& reason) const; + MEDCOUPLING_EXPORT bool areInfoEquals(const DataArray& other) const; + MEDCOUPLING_EXPORT std::string cppRepr(const std::string& varName) const; + MEDCOUPLING_EXPORT std::string getName() const { return _name; } + MEDCOUPLING_EXPORT const std::vector<std::string> &getInfoOnComponents() const { return _info_on_compo; } + MEDCOUPLING_EXPORT std::vector<std::string> &getInfoOnComponents() { return _info_on_compo; } + MEDCOUPLING_EXPORT void setInfoOnComponents(const std::vector<std::string>& info); + MEDCOUPLING_EXPORT void setInfoAndChangeNbOfCompo(const std::vector<std::string>& info); + MEDCOUPLING_EXPORT std::vector<std::string> getVarsOnComponent() const; + MEDCOUPLING_EXPORT std::vector<std::string> getUnitsOnComponent() const; + MEDCOUPLING_EXPORT std::string getInfoOnComponent(int i) const; + MEDCOUPLING_EXPORT std::string getVarOnComponent(int i) const; + MEDCOUPLING_EXPORT std::string getUnitOnComponent(int i) const; + MEDCOUPLING_EXPORT void setInfoOnComponent(int i, const std::string& info); + MEDCOUPLING_EXPORT int getNumberOfComponents() const { return (int)_info_on_compo.size(); } + MEDCOUPLING_EXPORT void setPartOfValuesBase3(const DataArray *aBase, const int *bgTuples, const int *endTuples, int bgComp, int endComp, int stepComp, bool strictCompoCompare=true); + MEDCOUPLING_EXPORT virtual DataArray *deepCpy() const = 0; + MEDCOUPLING_EXPORT virtual bool isAllocated() const = 0; + MEDCOUPLING_EXPORT virtual void checkAllocated() const = 0; + MEDCOUPLING_EXPORT virtual void desallocate() = 0; + MEDCOUPLING_EXPORT virtual int getNumberOfTuples() const = 0; + MEDCOUPLING_EXPORT virtual std::size_t getNbOfElems() const = 0; + MEDCOUPLING_EXPORT virtual std::size_t getNbOfElemAllocated() const = 0; + MEDCOUPLING_EXPORT virtual void alloc(int nbOfTuple, int nbOfCompo=1) = 0; + MEDCOUPLING_EXPORT virtual void reAlloc(int newNbOfTuple) = 0; + MEDCOUPLING_EXPORT virtual void renumberInPlace(const int *old2New) = 0; + MEDCOUPLING_EXPORT virtual void renumberInPlaceR(const int *new2Old) = 0; + MEDCOUPLING_EXPORT virtual void setContigPartOfSelectedValues(int tupleIdStart, const DataArray *aBase, const DataArrayInt *tuplesSelec) = 0; + MEDCOUPLING_EXPORT virtual void setContigPartOfSelectedValues2(int tupleIdStart, const DataArray *aBase, int bg, int end2, int step) = 0; + MEDCOUPLING_EXPORT virtual DataArray *selectByTupleRanges(const std::vector<std::pair<int,int> >& ranges) const = 0; + MEDCOUPLING_EXPORT virtual DataArray *keepSelectedComponents(const std::vector<int>& compoIds) const = 0; + MEDCOUPLING_EXPORT virtual DataArray *selectByTupleId(const int *new2OldBg, const int *new2OldEnd) const = 0; + MEDCOUPLING_EXPORT virtual DataArray *selectByTupleIdSafe(const int *new2OldBg, const int *new2OldEnd) const = 0; + MEDCOUPLING_EXPORT virtual DataArray *selectByTupleId2(int bg, int end2, int step) const = 0; + MEDCOUPLING_EXPORT virtual void rearrange(int newNbOfCompo) = 0; + MEDCOUPLING_EXPORT void checkNbOfTuples(int nbOfTuples, const std::string& msg) const; + MEDCOUPLING_EXPORT void checkNbOfComps(int nbOfCompo, const std::string& msg) const; + MEDCOUPLING_EXPORT void checkNbOfTuplesAndComp(const DataArray& other, const std::string& msg) const; + MEDCOUPLING_EXPORT void checkNbOfTuplesAndComp(int nbOfTuples, int nbOfCompo, const std::string& msg) const; + MEDCOUPLING_EXPORT void checkNbOfElems(std::size_t nbOfElems, const std::string& msg) const; + MEDCOUPLING_EXPORT static void GetSlice(int start, int stop, int step, int sliceId, int nbOfSlices, int& startSlice, int& stopSlice); + MEDCOUPLING_EXPORT static int GetNumberOfItemGivenBES(int begin, int end, int step, const std::string& msg); + MEDCOUPLING_EXPORT static int GetNumberOfItemGivenBESRelative(int begin, int end, int step, const std::string& msg); + MEDCOUPLING_EXPORT static int GetPosOfItemGivenBESRelativeNoThrow(int value, int begin, int end, int step); + MEDCOUPLING_EXPORT static std::string GetVarNameFromInfo(const std::string& info); + MEDCOUPLING_EXPORT static std::string GetUnitFromInfo(const std::string& info); + MEDCOUPLING_EXPORT static std::string BuildInfoFromVarAndUnit(const std::string& var, const std::string& unit); + MEDCOUPLING_EXPORT static DataArray *Aggregate(const std::vector<const DataArray *>& arrs); + MEDCOUPLING_EXPORT virtual void reprStream(std::ostream& stream) const = 0; + MEDCOUPLING_EXPORT virtual void reprZipStream(std::ostream& stream) const = 0; + MEDCOUPLING_EXPORT virtual void reprWithoutNameStream(std::ostream& stream) const; + MEDCOUPLING_EXPORT virtual void reprZipWithoutNameStream(std::ostream& stream) const = 0; + MEDCOUPLING_EXPORT virtual void reprCppStream(const std::string& varName, std::ostream& stream) const = 0; + MEDCOUPLING_EXPORT virtual void reprQuickOverview(std::ostream& stream) const = 0; + MEDCOUPLING_EXPORT virtual void reprQuickOverviewData(std::ostream& stream, std::size_t maxNbOfByteInRepr) const = 0; + protected: + DataArray() { } + ~DataArray() { } + protected: + static void CheckValueInRange(int ref, int value, const std::string& msg); + static void CheckValueInRangeEx(int value, int start, int end, const std::string& msg); + static void CheckClosingParInRange(int ref, int value, const std::string& msg); + protected: + std::string _name; + std::vector<std::string> _info_on_compo; + }; +} + +#include "MEDCouplingMemArray.txx" + +namespace ParaMEDMEM +{ + class DataArrayInt; + class DataArrayDoubleIterator; + class DataArrayDouble : public DataArray + { + public: + MEDCOUPLING_EXPORT static DataArrayDouble *New(); + MEDCOUPLING_EXPORT bool isAllocated() const; + MEDCOUPLING_EXPORT void checkAllocated() const; + MEDCOUPLING_EXPORT void desallocate(); + MEDCOUPLING_EXPORT int getNumberOfTuples() const { return _info_on_compo.empty()?0:_mem.getNbOfElem()/getNumberOfComponents(); } + MEDCOUPLING_EXPORT std::size_t getNbOfElems() const { return _mem.getNbOfElem(); } + MEDCOUPLING_EXPORT std::size_t getHeapMemorySizeWithoutChildren() const; + MEDCOUPLING_EXPORT double doubleValue() const; + MEDCOUPLING_EXPORT bool empty() const; + MEDCOUPLING_EXPORT DataArrayDouble *deepCpy() const; + MEDCOUPLING_EXPORT DataArrayDouble *performCpy(bool deepCpy) const; + MEDCOUPLING_EXPORT void cpyFrom(const DataArrayDouble& other); + MEDCOUPLING_EXPORT void reserve(std::size_t nbOfElems); + MEDCOUPLING_EXPORT void pushBackSilent(double val); + MEDCOUPLING_EXPORT void pushBackValsSilent(const double *valsBg, const double *valsEnd); + MEDCOUPLING_EXPORT double popBackSilent(); + MEDCOUPLING_EXPORT void pack() const; + MEDCOUPLING_EXPORT std::size_t getNbOfElemAllocated() const { return _mem.getNbOfElemAllocated(); } + MEDCOUPLING_EXPORT void alloc(int nbOfTuple, int nbOfCompo=1); + MEDCOUPLING_EXPORT void allocIfNecessary(int nbOfTuple, int nbOfCompo); + MEDCOUPLING_EXPORT void fillWithZero(); + MEDCOUPLING_EXPORT void fillWithValue(double val); + MEDCOUPLING_EXPORT void iota(double init=0.); + MEDCOUPLING_EXPORT bool isUniform(double val, double eps) const; + MEDCOUPLING_EXPORT void sort(bool asc=true); + MEDCOUPLING_EXPORT void reverse(); + MEDCOUPLING_EXPORT void checkMonotonic(bool increasing, double eps) const; + MEDCOUPLING_EXPORT bool isMonotonic(bool increasing, double eps) const; + MEDCOUPLING_EXPORT std::string repr() const; + MEDCOUPLING_EXPORT std::string reprZip() const; + MEDCOUPLING_EXPORT std::string reprNotTooLong() const; + MEDCOUPLING_EXPORT void writeVTK(std::ostream& ofs, int indent, const std::string& nameInFile, DataArrayByte *byteArr) const; + MEDCOUPLING_EXPORT void reprStream(std::ostream& stream) const; + MEDCOUPLING_EXPORT void reprZipStream(std::ostream& stream) const; + MEDCOUPLING_EXPORT void reprNotTooLongStream(std::ostream& stream) const; + MEDCOUPLING_EXPORT void reprWithoutNameStream(std::ostream& stream) const; + MEDCOUPLING_EXPORT void reprZipWithoutNameStream(std::ostream& stream) const; + MEDCOUPLING_EXPORT void reprNotTooLongWithoutNameStream(std::ostream& stream) const; + MEDCOUPLING_EXPORT void reprCppStream(const std::string& varName, std::ostream& stream) const; + MEDCOUPLING_EXPORT void reprQuickOverview(std::ostream& stream) const; + MEDCOUPLING_EXPORT void reprQuickOverviewData(std::ostream& stream, std::size_t maxNbOfByteInRepr) 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; + MEDCOUPLING_EXPORT void reAlloc(int nbOfTuples); + MEDCOUPLING_EXPORT DataArrayInt *convertToIntArr() const; + MEDCOUPLING_EXPORT DataArrayDouble *fromNoInterlace() const; + MEDCOUPLING_EXPORT DataArrayDouble *toNoInterlace() const; + 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 DataArrayDouble *selectByTupleId(const int *new2OldBg, const int *new2OldEnd) const; + MEDCOUPLING_EXPORT DataArrayDouble *selectByTupleIdSafe(const int *new2OldBg, const int *new2OldEnd) const; + MEDCOUPLING_EXPORT DataArrayDouble *selectByTupleId2(int bg, int end2, int step) const; + MEDCOUPLING_EXPORT DataArray *selectByTupleRanges(const std::vector<std::pair<int,int> >& ranges) const; + MEDCOUPLING_EXPORT DataArrayDouble *substr(int tupleIdBg, int tupleIdEnd=-1) const; + MEDCOUPLING_EXPORT void rearrange(int newNbOfCompo); + MEDCOUPLING_EXPORT void transpose(); + MEDCOUPLING_EXPORT DataArrayDouble *changeNbOfComponents(int newNbOfComp, double dftValue) const; + MEDCOUPLING_EXPORT DataArrayDouble *keepSelectedComponents(const std::vector<int>& compoIds) const; + MEDCOUPLING_EXPORT void meldWith(const DataArrayDouble *other); + MEDCOUPLING_EXPORT bool areIncludedInMe(const DataArrayDouble *other, double prec, DataArrayInt *&tupleIds) const; + MEDCOUPLING_EXPORT void findCommonTuples(double prec, int limitTupleId, DataArrayInt *&comm, DataArrayInt *&commIndex) const; + MEDCOUPLING_EXPORT double minimalDistanceTo(const DataArrayDouble *other, int& thisTupleId, int& otherTupleId) const; + MEDCOUPLING_EXPORT DataArrayDouble *duplicateEachTupleNTimes(int nbTimes) const; + MEDCOUPLING_EXPORT DataArrayDouble *getDifferentValues(double prec, int limitTupleId=-1) const; + MEDCOUPLING_EXPORT DataArrayInt *findClosestTupleId(const DataArrayDouble *other) const; + MEDCOUPLING_EXPORT DataArrayInt *computeNbOfInteractionsWith(const DataArrayDouble *otherBBoxFrmt, double eps) const; + MEDCOUPLING_EXPORT void setSelectedComponents(const DataArrayDouble *a, const std::vector<int>& compoIds); + MEDCOUPLING_EXPORT void setPartOfValues1(const DataArrayDouble *a, int bgTuples, int endTuples, int stepTuples, int bgComp, int endComp, int stepComp, bool strictCompoCompare=true); + MEDCOUPLING_EXPORT void setPartOfValuesSimple1(double a, int bgTuples, int endTuples, int stepTuples, int bgComp, int endComp, int stepComp); + MEDCOUPLING_EXPORT void setPartOfValues2(const DataArrayDouble *a, const int *bgTuples, const int *endTuples, const int *bgComp, const int *endComp, bool strictCompoCompare=true); + MEDCOUPLING_EXPORT void setPartOfValuesSimple2(double a, const int *bgTuples, const int *endTuples, const int *bgComp, const int *endComp); + MEDCOUPLING_EXPORT void setPartOfValues3(const DataArrayDouble *a, const int *bgTuples, const int *endTuples, int bgComp, int endComp, int stepComp, bool strictCompoCompare=true); + MEDCOUPLING_EXPORT void setPartOfValuesSimple3(double a, const int *bgTuples, const int *endTuples, int bgComp, int endComp, int stepComp); + MEDCOUPLING_EXPORT void setPartOfValues4(const DataArrayDouble *a, int bgTuples, int endTuples, int stepTuples, const int *bgComp, const int *endComp, bool strictCompoCompare=true); + MEDCOUPLING_EXPORT void setPartOfValuesSimple4(double a, int bgTuples, int endTuples, int stepTuples, const int *bgComp, const int *endComp); + MEDCOUPLING_EXPORT void setPartOfValuesAdv(const DataArrayDouble *a, const DataArrayInt *tuplesSelec); + MEDCOUPLING_EXPORT void setContigPartOfSelectedValues(int tupleIdStart, const DataArray *aBase, const DataArrayInt *tuplesSelec); + MEDCOUPLING_EXPORT void setContigPartOfSelectedValues2(int tupleIdStart, const DataArray *aBase, int bg, int end2, int step); + MEDCOUPLING_EXPORT void getTuple(int tupleId, double *res) const { 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 front() const; + MEDCOUPLING_EXPORT double back() const; + MEDCOUPLING_EXPORT double getIJSafe(int tupleId, int compoId) const; + MEDCOUPLING_EXPORT void setIJ(int tupleId, int compoId, double newVal) { _mem[tupleId*_info_on_compo.size()+compoId]=newVal; declareAsNew(); } + MEDCOUPLING_EXPORT void setIJSilent(int tupleId, int compoId, double newVal) { _mem[tupleId*_info_on_compo.size()+compoId]=newVal; } + MEDCOUPLING_EXPORT double *getPointer() { return _mem.getPointer(); declareAsNew(); } + 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); + template<class InputIterator> + void insertAtTheEnd(InputIterator first, InputIterator last); + 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; + MEDCOUPLING_EXPORT void getMinMaxPerComponent(double *bounds) const; + MEDCOUPLING_EXPORT DataArrayDouble *computeBBoxPerTuple(double epsilon=0.0) const; + MEDCOUPLING_EXPORT void computeTupleIdsNearTuples(const DataArrayDouble *other, double eps, DataArrayInt *& c, DataArrayInt *& cI) const; + MEDCOUPLING_EXPORT void recenterForMaxPrecision(double eps); + MEDCOUPLING_EXPORT double getMaxValue(int& tupleId) const; + MEDCOUPLING_EXPORT double getMaxValueInArray() const; + MEDCOUPLING_EXPORT double getMinValue(int& tupleId) const; + MEDCOUPLING_EXPORT double getMinValueInArray() const; + MEDCOUPLING_EXPORT double getMaxValue2(DataArrayInt*& tupleIds) const; + MEDCOUPLING_EXPORT double getMinValue2(DataArrayInt*& tupleIds) const; + MEDCOUPLING_EXPORT int count(double value, double eps) const; + MEDCOUPLING_EXPORT double getAverageValue() const; + MEDCOUPLING_EXPORT double norm2() const; + MEDCOUPLING_EXPORT double normMax() const; + MEDCOUPLING_EXPORT double normMin() const; + MEDCOUPLING_EXPORT void accumulate(double *res) const; + MEDCOUPLING_EXPORT double accumulate(int compId) const; + MEDCOUPLING_EXPORT DataArrayDouble *accumulatePerChunck(const int *bgOfIndex, const int *endOfIndex) const; + MEDCOUPLING_EXPORT double distanceToTuple(const double *tupleBg, const double *tupleEnd, int& tupleId) const; + MEDCOUPLING_EXPORT DataArrayDouble *fromPolarToCart() const; + MEDCOUPLING_EXPORT DataArrayDouble *fromCylToCart() const; + MEDCOUPLING_EXPORT DataArrayDouble *fromSpherToCart() const; + MEDCOUPLING_EXPORT DataArrayDouble *doublyContractedProduct() const; + MEDCOUPLING_EXPORT DataArrayDouble *determinant() const; + MEDCOUPLING_EXPORT DataArrayDouble *eigenValues() const; + MEDCOUPLING_EXPORT DataArrayDouble *eigenVectors() const; + MEDCOUPLING_EXPORT DataArrayDouble *inverse() const; + MEDCOUPLING_EXPORT DataArrayDouble *trace() const; + MEDCOUPLING_EXPORT DataArrayDouble *deviator() const; + MEDCOUPLING_EXPORT DataArrayDouble *magnitude() const; + MEDCOUPLING_EXPORT DataArrayDouble *sumPerTuple() const; + MEDCOUPLING_EXPORT DataArrayDouble *maxPerTuple() const; + MEDCOUPLING_EXPORT DataArrayDouble *maxPerTupleWithCompoId(DataArrayInt* &compoIdOfMaxPerTuple) const; + MEDCOUPLING_EXPORT DataArrayDouble *buildEuclidianDistanceDenseMatrix() const; + MEDCOUPLING_EXPORT DataArrayDouble *buildEuclidianDistanceDenseMatrixWith(const DataArrayDouble *other) const; + MEDCOUPLING_EXPORT void sortPerTuple(bool asc); + MEDCOUPLING_EXPORT void abs(); + MEDCOUPLING_EXPORT DataArrayDouble *computeAbs() const; + MEDCOUPLING_EXPORT void applyLin(double a, double b, int compoId); + MEDCOUPLING_EXPORT void applyLin(double a, double b); + MEDCOUPLING_EXPORT void applyInv(double numerator); + MEDCOUPLING_EXPORT void applyPow(double val); + MEDCOUPLING_EXPORT void applyRPow(double val); + MEDCOUPLING_EXPORT DataArrayDouble *negate() const; + MEDCOUPLING_EXPORT DataArrayDouble *applyFunc(int nbOfComp, FunctionToEvaluate func) const; + MEDCOUPLING_EXPORT DataArrayDouble *applyFunc(int nbOfComp, const std::string& func, bool isSafe=true) const; + MEDCOUPLING_EXPORT DataArrayDouble *applyFunc(const std::string& func, bool isSafe=true) const; + MEDCOUPLING_EXPORT void applyFuncOnThis(const std::string& func, bool isSafe=true); + MEDCOUPLING_EXPORT DataArrayDouble *applyFunc2(int nbOfComp, const std::string& func, bool isSafe=true) const; + MEDCOUPLING_EXPORT DataArrayDouble *applyFunc3(int nbOfComp, const std::vector<std::string>& varsOrder, const std::string& func, bool isSafe=true) const; + MEDCOUPLING_EXPORT void applyFuncFast32(const std::string& func); + MEDCOUPLING_EXPORT void applyFuncFast64(const std::string& func); + MEDCOUPLING_EXPORT DataArrayInt *getIdsInRange(double vmin, double vmax) const; + MEDCOUPLING_EXPORT DataArrayInt *getIdsNotInRange(double vmin, double vmax) const; + MEDCOUPLING_EXPORT static DataArrayDouble *Aggregate(const DataArrayDouble *a1, const DataArrayDouble *a2); + MEDCOUPLING_EXPORT static DataArrayDouble *Aggregate(const std::vector<const DataArrayDouble *>& arr); + MEDCOUPLING_EXPORT static DataArrayDouble *Meld(const DataArrayDouble *a1, const DataArrayDouble *a2); + MEDCOUPLING_EXPORT static DataArrayDouble *Meld(const std::vector<const DataArrayDouble *>& arr); + MEDCOUPLING_EXPORT static DataArrayDouble *Dot(const DataArrayDouble *a1, const DataArrayDouble *a2); + MEDCOUPLING_EXPORT static DataArrayDouble *CrossProduct(const DataArrayDouble *a1, const DataArrayDouble *a2); + MEDCOUPLING_EXPORT static DataArrayDouble *Max(const DataArrayDouble *a1, const DataArrayDouble *a2); + MEDCOUPLING_EXPORT static DataArrayDouble *Min(const DataArrayDouble *a1, const DataArrayDouble *a2); + MEDCOUPLING_EXPORT static DataArrayDouble *Add(const DataArrayDouble *a1, const DataArrayDouble *a2); + MEDCOUPLING_EXPORT void addEqual(const DataArrayDouble *other); + MEDCOUPLING_EXPORT static DataArrayDouble *Substract(const DataArrayDouble *a1, const DataArrayDouble *a2); + MEDCOUPLING_EXPORT void substractEqual(const DataArrayDouble *other); + MEDCOUPLING_EXPORT static DataArrayDouble *Multiply(const DataArrayDouble *a1, const DataArrayDouble *a2); + MEDCOUPLING_EXPORT void multiplyEqual(const DataArrayDouble *other); + MEDCOUPLING_EXPORT static DataArrayDouble *Divide(const DataArrayDouble *a1, const DataArrayDouble *a2); + MEDCOUPLING_EXPORT void divideEqual(const DataArrayDouble *other); + MEDCOUPLING_EXPORT static DataArrayDouble *Pow(const DataArrayDouble *a1, const DataArrayDouble *a2); + MEDCOUPLING_EXPORT void powEqual(const DataArrayDouble *other); + MEDCOUPLING_EXPORT void updateTime() const { } + MEDCOUPLING_EXPORT MemArray<double>& accessToMemArray() { return _mem; } + MEDCOUPLING_EXPORT const MemArray<double>& accessToMemArray() const { return _mem; } + MEDCOUPLING_EXPORT std::vector<bool> toVectorOfBool(double eps) const; + public: + MEDCOUPLING_EXPORT void getTinySerializationIntInformation(std::vector<int>& tinyInfo) const; + MEDCOUPLING_EXPORT void getTinySerializationStrInformation(std::vector<std::string>& tinyInfo) const; + MEDCOUPLING_EXPORT bool resizeForUnserialization(const std::vector<int>& tinyInfoI); + MEDCOUPLING_EXPORT void finishUnserialization(const std::vector<int>& tinyInfoI, const std::vector<std::string>& tinyInfoS); + public: + template<int SPACEDIM> + void findCommonTuplesAlg(const double *bbox, int nbNodes, int limitNodeId, double prec, DataArrayInt *c, DataArrayInt *cI) const; + template<int SPACEDIM> + static void FindClosestTupleIdAlg(const BBTreePts<SPACEDIM,int>& myTree, double dist, const double *pos, int nbOfTuples, const double *thisPt, int thisNbOfTuples, int *res); + template<int SPACEDIM> + static void FindTupleIdsNearTuplesAlg(const BBTreePts<SPACEDIM,int>& myTree, const double *pos, int nbOfTuples, double eps, + DataArrayInt *c, DataArrayInt *cI); + private: + ~DataArrayDouble() { } + DataArrayDouble() { } + private: + MemArray<double> _mem; + }; + + class DataArrayDoubleTuple; + + class DataArrayDoubleIterator + { + public: + MEDCOUPLING_EXPORT DataArrayDoubleIterator(DataArrayDouble *da); + MEDCOUPLING_EXPORT ~DataArrayDoubleIterator(); + MEDCOUPLING_EXPORT DataArrayDoubleTuple *nextt(); + private: + DataArrayDouble *_da; + double *_pt; + int _tuple_id; + int _nb_comp; + int _nb_tuple; + }; + + class DataArrayDoubleTuple + { + public: + MEDCOUPLING_EXPORT DataArrayDoubleTuple(double *pt, int nbOfComp); + MEDCOUPLING_EXPORT std::string repr() const; + MEDCOUPLING_EXPORT int getNumberOfCompo() const { return _nb_of_compo; } + MEDCOUPLING_EXPORT const double *getConstPointer() const { return _pt; } + MEDCOUPLING_EXPORT double *getPointer() { return _pt; } + MEDCOUPLING_EXPORT double doubleValue() const; + MEDCOUPLING_EXPORT DataArrayDouble *buildDADouble(int nbOfTuples, int nbOfCompo) const; + private: + double *_pt; + int _nb_of_compo; + }; + + class DataArrayIntIterator; + + class DataArrayInt : public DataArray + { + public: + MEDCOUPLING_EXPORT static DataArrayInt *New(); + MEDCOUPLING_EXPORT bool isAllocated() const; + MEDCOUPLING_EXPORT void checkAllocated() const; + MEDCOUPLING_EXPORT void desallocate(); + MEDCOUPLING_EXPORT int getNumberOfTuples() const { return _info_on_compo.empty()?0:_mem.getNbOfElem()/getNumberOfComponents(); } + MEDCOUPLING_EXPORT std::size_t getNbOfElems() const { return _mem.getNbOfElem(); } + MEDCOUPLING_EXPORT std::size_t getHeapMemorySizeWithoutChildren() const; + MEDCOUPLING_EXPORT int intValue() const; + MEDCOUPLING_EXPORT int getHashCode() const; + MEDCOUPLING_EXPORT bool empty() const; + MEDCOUPLING_EXPORT DataArrayInt *deepCpy() const; + MEDCOUPLING_EXPORT DataArrayInt *performCpy(bool deepCpy) const; + MEDCOUPLING_EXPORT void cpyFrom(const DataArrayInt& other); + MEDCOUPLING_EXPORT void reserve(std::size_t nbOfElems); + MEDCOUPLING_EXPORT void pushBackSilent(int val); + MEDCOUPLING_EXPORT void pushBackValsSilent(const int *valsBg, const int *valsEnd); + MEDCOUPLING_EXPORT int popBackSilent(); + MEDCOUPLING_EXPORT void pack() const; + MEDCOUPLING_EXPORT std::size_t getNbOfElemAllocated() const { return _mem.getNbOfElemAllocated(); } + MEDCOUPLING_EXPORT void alloc(int nbOfTuple, int nbOfCompo=1); + 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 bool isEqualWithoutConsideringStrAndOrder(const DataArrayInt& other) const; + MEDCOUPLING_EXPORT bool isFittingWith(const std::vector<bool>& v) const; + MEDCOUPLING_EXPORT void switchOnTupleEqualTo(int val, std::vector<bool>& vec) const; + MEDCOUPLING_EXPORT DataArrayInt *buildPermutationArr(const DataArrayInt& other) const; + MEDCOUPLING_EXPORT DataArrayInt *sumPerTuple() const; + MEDCOUPLING_EXPORT void sort(bool asc=true); + MEDCOUPLING_EXPORT void reverse(); + MEDCOUPLING_EXPORT void checkMonotonic(bool increasing) const; + MEDCOUPLING_EXPORT bool isMonotonic(bool increasing) const; + MEDCOUPLING_EXPORT void checkStrictlyMonotonic(bool increasing) const; + MEDCOUPLING_EXPORT bool isStrictlyMonotonic(bool increasing) const; + MEDCOUPLING_EXPORT void fillWithZero(); + MEDCOUPLING_EXPORT void fillWithValue(int val); + MEDCOUPLING_EXPORT void iota(int init=0); + MEDCOUPLING_EXPORT std::string repr() const; + MEDCOUPLING_EXPORT std::string reprZip() const; + MEDCOUPLING_EXPORT std::string reprNotTooLong() const; + MEDCOUPLING_EXPORT void writeVTK(std::ostream& ofs, int indent, const std::string& type, const std::string& nameInFile, DataArrayByte *byteArr) const; + MEDCOUPLING_EXPORT void reprStream(std::ostream& stream) const; + MEDCOUPLING_EXPORT void reprZipStream(std::ostream& stream) const; + MEDCOUPLING_EXPORT void reprNotTooLongStream(std::ostream& stream) const; + MEDCOUPLING_EXPORT void reprWithoutNameStream(std::ostream& stream) const; + MEDCOUPLING_EXPORT void reprZipWithoutNameStream(std::ostream& stream) const; + MEDCOUPLING_EXPORT void reprNotTooLongWithoutNameStream(std::ostream& stream) const; + MEDCOUPLING_EXPORT void reprCppStream(const std::string& varName, std::ostream& stream) const; + MEDCOUPLING_EXPORT void reprQuickOverview(std::ostream& stream) const; + MEDCOUPLING_EXPORT void reprQuickOverviewData(std::ostream& stream, std::size_t maxNbOfByteInRepr) const; + MEDCOUPLING_EXPORT void transformWithIndArr(const int *indArrBg, const int *indArrEnd); + MEDCOUPLING_EXPORT void replaceOneValByInThis(int valToBeReplaced, int replacedBy); + MEDCOUPLING_EXPORT DataArrayInt *transformWithIndArrR(const int *indArrBg, const int *indArrEnd) const; + MEDCOUPLING_EXPORT void splitByValueRange(const int *arrBg, const int *arrEnd, + DataArrayInt *& castArr, DataArrayInt *& rankInsideCast, DataArrayInt *& castsPresent) const; + MEDCOUPLING_EXPORT bool isRange(int& strt, int& sttoopp, int& stteepp) const; + MEDCOUPLING_EXPORT DataArrayInt *invertArrayO2N2N2O(int newNbOfElem) const; + MEDCOUPLING_EXPORT DataArrayInt *invertArrayN2O2O2N(int oldNbOfElem) const; + MEDCOUPLING_EXPORT DataArrayInt *invertArrayO2N2N2OBis(int newNbOfElem) const; + MEDCOUPLING_EXPORT void reAlloc(int nbOfTuples); + MEDCOUPLING_EXPORT DataArrayDouble *convertToDblArr() const; + MEDCOUPLING_EXPORT DataArrayInt *fromNoInterlace() const; + MEDCOUPLING_EXPORT DataArrayInt *toNoInterlace() const; + 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 DataArrayInt *selectByTupleId(const int *new2OldBg, const int *new2OldEnd) const; + MEDCOUPLING_EXPORT DataArrayInt *selectByTupleIdSafe(const int *new2OldBg, const int *new2OldEnd) const; + MEDCOUPLING_EXPORT DataArrayInt *selectByTupleId2(int bg, int end, int step) const; + MEDCOUPLING_EXPORT DataArray *selectByTupleRanges(const std::vector<std::pair<int,int> >& ranges) const; + MEDCOUPLING_EXPORT DataArrayInt *checkAndPreparePermutation() const; + MEDCOUPLING_EXPORT static DataArrayInt *FindPermutationFromFirstToSecond(const DataArrayInt *ids1, const DataArrayInt *ids2); + MEDCOUPLING_EXPORT void changeSurjectiveFormat(int targetNb, DataArrayInt *&arr, DataArrayInt *&arrI) const; + MEDCOUPLING_EXPORT static DataArrayInt *BuildOld2NewArrayFromSurjectiveFormat2(int nbOfOldTuples, const int *arr, const int *arrIBg, const int *arrIEnd, int &newNbOfTuples); + MEDCOUPLING_EXPORT DataArrayInt *buildPermArrPerLevel() const; + MEDCOUPLING_EXPORT bool isIdentity() const; + MEDCOUPLING_EXPORT bool isIdentity2(int sizeExpected) const; + MEDCOUPLING_EXPORT bool isUniform(int val) const; + MEDCOUPLING_EXPORT DataArrayInt *substr(int tupleIdBg, int tupleIdEnd=-1) const; + MEDCOUPLING_EXPORT void rearrange(int newNbOfCompo); + MEDCOUPLING_EXPORT void transpose(); + MEDCOUPLING_EXPORT DataArrayInt *changeNbOfComponents(int newNbOfComp, int dftValue) const; + MEDCOUPLING_EXPORT DataArrayInt *keepSelectedComponents(const std::vector<int>& compoIds) const; + MEDCOUPLING_EXPORT void meldWith(const DataArrayInt *other); + MEDCOUPLING_EXPORT void setSelectedComponents(const DataArrayInt *a, const std::vector<int>& compoIds); + MEDCOUPLING_EXPORT void setPartOfValues1(const DataArrayInt *a, int bgTuples, int endTuples, int stepTuples, int bgComp, int endComp, int stepComp, bool strictCompoCompare=true); + MEDCOUPLING_EXPORT void setPartOfValuesSimple1(int a, int bgTuples, int endTuples, int stepTuples, int bgComp, int endComp, int stepComp); + MEDCOUPLING_EXPORT void setPartOfValues2(const DataArrayInt *a, const int *bgTuples, const int *endTuples, const int *bgComp, const int *endComp, bool strictCompoCompare=true); + MEDCOUPLING_EXPORT void setPartOfValuesSimple2(int a, const int *bgTuples, const int *endTuples, const int *bgComp, const int *endComp); + MEDCOUPLING_EXPORT void setPartOfValues3(const DataArrayInt *a, const int *bgTuples, const int *endTuples, int bgComp, int endComp, int stepComp, bool strictCompoCompare=true); + MEDCOUPLING_EXPORT void setPartOfValuesSimple3(int a, const int *bgTuples, const int *endTuples, int bgComp, int endComp, int stepComp); + MEDCOUPLING_EXPORT void setPartOfValues4(const DataArrayInt *a, int bgTuples, int endTuples, int stepTuples, const int *bgComp, const int *endComp, bool strictCompoCompare=true); + MEDCOUPLING_EXPORT void setPartOfValuesSimple4(int a, int bgTuples, int endTuples, int stepTuples, const int *bgComp, const int *endComp); + MEDCOUPLING_EXPORT void setPartOfValuesAdv(const DataArrayInt *a, const DataArrayInt *tuplesSelec); + MEDCOUPLING_EXPORT void setContigPartOfSelectedValues(int tupleIdStart, const DataArray *aBase, const DataArrayInt *tuplesSelec); + MEDCOUPLING_EXPORT void setContigPartOfSelectedValues2(int tupleIdStart, const DataArray *aBase, int bg, int end2, int step); + MEDCOUPLING_EXPORT void getTuple(int tupleId, int *res) const { 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 { return _mem[tupleId*_info_on_compo.size()+compoId]; } + MEDCOUPLING_EXPORT int getIJSafe(int tupleId, int compoId) const; + MEDCOUPLING_EXPORT int front() const; + MEDCOUPLING_EXPORT int back() const; + MEDCOUPLING_EXPORT void setIJ(int tupleId, int compoId, int newVal) { _mem[tupleId*_info_on_compo.size()+compoId]=newVal; declareAsNew(); } + MEDCOUPLING_EXPORT void setIJSilent(int tupleId, int compoId, int newVal) { _mem[tupleId*_info_on_compo.size()+compoId]=newVal; } + MEDCOUPLING_EXPORT int *getPointer() { return _mem.getPointer(); declareAsNew(); } + 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 DataArrayInt *getIdsEqual(int val) const; + MEDCOUPLING_EXPORT DataArrayInt *getIdsNotEqual(int val) const; + MEDCOUPLING_EXPORT DataArrayInt *getIdsEqualList(const int *valsBg, const int *valsEnd) const; + MEDCOUPLING_EXPORT DataArrayInt *getIdsNotEqualList(const int *valsBg, const int *valsEnd) const; + MEDCOUPLING_EXPORT DataArrayInt *getIdsEqualTuple(const int *tupleBg, const int *tupleEnd) const; + MEDCOUPLING_EXPORT int changeValue(int oldValue, int newValue); + MEDCOUPLING_EXPORT int locateTuple(const std::vector<int>& tupl) const; + MEDCOUPLING_EXPORT int locateValue(int value) const; + MEDCOUPLING_EXPORT int locateValue(const std::vector<int>& vals) const; + MEDCOUPLING_EXPORT int search(const std::vector<int>& vals) const; + MEDCOUPLING_EXPORT bool presenceOfTuple(const std::vector<int>& tupl) const; + MEDCOUPLING_EXPORT bool presenceOfValue(int value) const; + MEDCOUPLING_EXPORT bool presenceOfValue(const std::vector<int>& vals) const; + MEDCOUPLING_EXPORT int count(int value) const; + MEDCOUPLING_EXPORT void accumulate(int *res) const; + MEDCOUPLING_EXPORT int accumulate(int compId) const; + MEDCOUPLING_EXPORT DataArrayInt *accumulatePerChunck(const int *bgOfIndex, const int *endOfIndex) const; + MEDCOUPLING_EXPORT int getMaxValue(int& tupleId) const; + MEDCOUPLING_EXPORT int getMaxValueInArray() const; + MEDCOUPLING_EXPORT int getMinValue(int& tupleId) const; + MEDCOUPLING_EXPORT int getMinValueInArray() const; + MEDCOUPLING_EXPORT void getMinMaxValues(int& minValue, int& maxValue) const; + MEDCOUPLING_EXPORT void abs(); + MEDCOUPLING_EXPORT DataArrayInt *computeAbs() const; + MEDCOUPLING_EXPORT void applyLin(int a, int b, int compoId); + MEDCOUPLING_EXPORT void applyLin(int a, int b); + MEDCOUPLING_EXPORT void applyInv(int numerator); + MEDCOUPLING_EXPORT DataArrayInt *negate() const; + MEDCOUPLING_EXPORT void applyDivideBy(int val); + MEDCOUPLING_EXPORT void applyModulus(int val); + MEDCOUPLING_EXPORT void applyRModulus(int val); + MEDCOUPLING_EXPORT void applyPow(int val); + MEDCOUPLING_EXPORT void applyRPow(int val); + MEDCOUPLING_EXPORT DataArrayInt *getIdsInRange(int vmin, int vmax) const; + MEDCOUPLING_EXPORT DataArrayInt *getIdsNotInRange(int vmin, int vmax) const; + MEDCOUPLING_EXPORT DataArrayInt *getIdsStrictlyNegative() const; + MEDCOUPLING_EXPORT bool checkAllIdsInRange(int vmin, int vmax) const; + MEDCOUPLING_EXPORT static DataArrayInt *Aggregate(const DataArrayInt *a1, const DataArrayInt *a2, int offsetA2); + MEDCOUPLING_EXPORT static DataArrayInt *Aggregate(const std::vector<const DataArrayInt *>& arr); + MEDCOUPLING_EXPORT static DataArrayInt *AggregateIndexes(const std::vector<const DataArrayInt *>& arrs); + MEDCOUPLING_EXPORT static DataArrayInt *Meld(const DataArrayInt *a1, const DataArrayInt *a2); + MEDCOUPLING_EXPORT static DataArrayInt *Meld(const std::vector<const DataArrayInt *>& arr); + MEDCOUPLING_EXPORT static DataArrayInt *MakePartition(const std::vector<const DataArrayInt *>& groups, int newNb, std::vector< std::vector<int> >& fidsOfGroups); + MEDCOUPLING_EXPORT static DataArrayInt *BuildUnion(const std::vector<const DataArrayInt *>& arr); + MEDCOUPLING_EXPORT static DataArrayInt *BuildIntersection(const std::vector<const DataArrayInt *>& arr); + MEDCOUPLING_EXPORT static DataArrayInt *BuildListOfSwitchedOn(const std::vector<bool>& v); + MEDCOUPLING_EXPORT static DataArrayInt *BuildListOfSwitchedOff(const std::vector<bool>& v); + MEDCOUPLING_EXPORT static void PutIntoToSkylineFrmt(const std::vector< std::vector<int> >& v, DataArrayInt *& data, DataArrayInt *& dataIndex); + MEDCOUPLING_EXPORT DataArrayInt *buildComplement(int nbOfElement) const; + MEDCOUPLING_EXPORT DataArrayInt *buildSubstraction(const DataArrayInt *other) const; + MEDCOUPLING_EXPORT DataArrayInt *buildSubstractionOptimized(const DataArrayInt *other) const; + MEDCOUPLING_EXPORT DataArrayInt *buildUnion(const DataArrayInt *other) const; + MEDCOUPLING_EXPORT DataArrayInt *buildIntersection(const DataArrayInt *other) const; + MEDCOUPLING_EXPORT DataArrayInt *buildUnique() const; + MEDCOUPLING_EXPORT DataArrayInt *buildUniqueNotSorted() const; + MEDCOUPLING_EXPORT DataArrayInt *deltaShiftIndex() const; + MEDCOUPLING_EXPORT void computeOffsets(); + MEDCOUPLING_EXPORT void computeOffsets2(); + MEDCOUPLING_EXPORT void searchRangesInListOfIds(const DataArrayInt *listOfIds, DataArrayInt *& rangeIdsFetched, DataArrayInt *& idsInInputListThatFetch) const; + MEDCOUPLING_EXPORT DataArrayInt *buildExplicitArrByRanges(const DataArrayInt *offsets) const; + MEDCOUPLING_EXPORT DataArrayInt *buildExplicitArrOfSliceOnScaledArr(int begin, int stop, int step) const; + MEDCOUPLING_EXPORT DataArrayInt *findRangeIdForEachTuple(const DataArrayInt *ranges) const; + MEDCOUPLING_EXPORT DataArrayInt *findIdInRangeForEachTuple(const DataArrayInt *ranges) const; + MEDCOUPLING_EXPORT void sortEachPairToMakeALinkedList(); + MEDCOUPLING_EXPORT DataArrayInt *duplicateEachTupleNTimes(int nbTimes) const; + MEDCOUPLING_EXPORT DataArrayInt *getDifferentValues() const; + MEDCOUPLING_EXPORT std::vector<DataArrayInt *> partitionByDifferentValues(std::vector<int>& differentIds) const; + MEDCOUPLING_EXPORT std::vector< std::pair<int,int> > splitInBalancedSlices(int nbOfSlices) const; + 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); + template<class InputIterator> + void insertAtTheEnd(InputIterator first, InputIterator last); + 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); + MEDCOUPLING_EXPORT void addEqual(const DataArrayInt *other); + MEDCOUPLING_EXPORT static DataArrayInt *Substract(const DataArrayInt *a1, const DataArrayInt *a2); + MEDCOUPLING_EXPORT void substractEqual(const DataArrayInt *other); + MEDCOUPLING_EXPORT static DataArrayInt *Multiply(const DataArrayInt *a1, const DataArrayInt *a2); + MEDCOUPLING_EXPORT void multiplyEqual(const DataArrayInt *other); + MEDCOUPLING_EXPORT static DataArrayInt *Divide(const DataArrayInt *a1, const DataArrayInt *a2); + MEDCOUPLING_EXPORT void divideEqual(const DataArrayInt *other); + MEDCOUPLING_EXPORT static DataArrayInt *Modulus(const DataArrayInt *a1, const DataArrayInt *a2); + MEDCOUPLING_EXPORT void modulusEqual(const DataArrayInt *other); + MEDCOUPLING_EXPORT static DataArrayInt *Pow(const DataArrayInt *a1, const DataArrayInt *a2); + MEDCOUPLING_EXPORT void powEqual(const DataArrayInt *other); + MEDCOUPLING_EXPORT void updateTime() const { } + MEDCOUPLING_EXPORT MemArray<int>& accessToMemArray() { return _mem; } + MEDCOUPLING_EXPORT const MemArray<int>& 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); + public: + MEDCOUPLING_EXPORT void getTinySerializationIntInformation(std::vector<int>& tinyInfo) const; + MEDCOUPLING_EXPORT void getTinySerializationStrInformation(std::vector<std::string>& tinyInfo) const; + MEDCOUPLING_EXPORT bool resizeForUnserialization(const std::vector<int>& tinyInfoI); + MEDCOUPLING_EXPORT void finishUnserialization(const std::vector<int>& tinyInfoI, const std::vector<std::string>& tinyInfoS); + private: + ~DataArrayInt() { } + DataArrayInt() { } + private: + MemArray<int> _mem; + }; + + class DataArrayIntTuple; + + class DataArrayIntIterator + { + public: + MEDCOUPLING_EXPORT DataArrayIntIterator(DataArrayInt *da); + MEDCOUPLING_EXPORT ~DataArrayIntIterator(); + MEDCOUPLING_EXPORT DataArrayIntTuple *nextt(); + private: + DataArrayInt *_da; + int *_pt; + int _tuple_id; + int _nb_comp; + int _nb_tuple; + }; + + class DataArrayIntTuple + { + public: + MEDCOUPLING_EXPORT DataArrayIntTuple(int *pt, int nbOfComp); + MEDCOUPLING_EXPORT std::string repr() const; + MEDCOUPLING_EXPORT int getNumberOfCompo() const { return _nb_of_compo; } + MEDCOUPLING_EXPORT const int *getConstPointer() const { return _pt; } + MEDCOUPLING_EXPORT int *getPointer() { return _pt; } + MEDCOUPLING_EXPORT int intValue() const; + MEDCOUPLING_EXPORT DataArrayInt *buildDAInt(int nbOfTuples, int nbOfCompo) const; + private: + int *_pt; + int _nb_of_compo; + }; + + class DataArrayChar : public DataArray + { + public: + MEDCOUPLING_EXPORT virtual DataArrayChar *buildEmptySpecializedDAChar() const = 0; + MEDCOUPLING_EXPORT bool isAllocated() const; + MEDCOUPLING_EXPORT void checkAllocated() const; + MEDCOUPLING_EXPORT void desallocate(); + MEDCOUPLING_EXPORT int getNumberOfTuples() const { return _info_on_compo.empty()?0:_mem.getNbOfElem()/getNumberOfComponents(); } + MEDCOUPLING_EXPORT std::size_t getNbOfElems() const { return _mem.getNbOfElem(); } + MEDCOUPLING_EXPORT std::size_t getHeapMemorySizeWithoutChildren() const; + MEDCOUPLING_EXPORT int getHashCode() const; + MEDCOUPLING_EXPORT bool empty() const; + MEDCOUPLING_EXPORT void cpyFrom(const DataArrayChar& other); + MEDCOUPLING_EXPORT void reserve(std::size_t nbOfElems); + MEDCOUPLING_EXPORT void pushBackSilent(char val); + MEDCOUPLING_EXPORT void pushBackValsSilent(const char *valsBg, const char *valsEnd); + MEDCOUPLING_EXPORT char popBackSilent(); + MEDCOUPLING_EXPORT void pack() const; + MEDCOUPLING_EXPORT std::size_t getNbOfElemAllocated() const { return _mem.getNbOfElemAllocated(); } + MEDCOUPLING_EXPORT void alloc(int nbOfTuple, int nbOfCompo=1); + MEDCOUPLING_EXPORT void allocIfNecessary(int nbOfTuple, int nbOfCompo); + MEDCOUPLING_EXPORT bool isEqual(const DataArrayChar& other) const; + MEDCOUPLING_EXPORT virtual bool isEqualIfNotWhy(const DataArrayChar& other, std::string& reason) const; + MEDCOUPLING_EXPORT bool isEqualWithoutConsideringStr(const DataArrayChar& other) const; + MEDCOUPLING_EXPORT void reverse(); + MEDCOUPLING_EXPORT void fillWithZero(); + MEDCOUPLING_EXPORT void fillWithValue(char val); + MEDCOUPLING_EXPORT std::string repr() const; + MEDCOUPLING_EXPORT std::string reprZip() const; + MEDCOUPLING_EXPORT void reAlloc(int nbOfTuples); + MEDCOUPLING_EXPORT DataArrayInt *convertToIntArr() const; + MEDCOUPLING_EXPORT void renumberInPlace(const int *old2New); + MEDCOUPLING_EXPORT void renumberInPlaceR(const int *new2Old); + MEDCOUPLING_EXPORT DataArrayChar *renumber(const int *old2New) const; + MEDCOUPLING_EXPORT DataArrayChar *renumberR(const int *new2Old) const; + MEDCOUPLING_EXPORT DataArrayChar *renumberAndReduce(const int *old2NewBg, int newNbOfTuple) const; + MEDCOUPLING_EXPORT DataArrayChar *selectByTupleId(const int *new2OldBg, const int *new2OldEnd) const; + MEDCOUPLING_EXPORT DataArrayChar *selectByTupleIdSafe(const int *new2OldBg, const int *new2OldEnd) const; + MEDCOUPLING_EXPORT DataArrayChar *selectByTupleId2(int bg, int end, int step) const; + MEDCOUPLING_EXPORT bool isUniform(char val) const; + MEDCOUPLING_EXPORT void rearrange(int newNbOfCompo); + MEDCOUPLING_EXPORT DataArrayChar *substr(int tupleIdBg, int tupleIdEnd=-1) const; + MEDCOUPLING_EXPORT DataArrayChar *changeNbOfComponents(int newNbOfComp, char dftValue) const; + MEDCOUPLING_EXPORT DataArrayChar *keepSelectedComponents(const std::vector<int>& compoIds) const; + MEDCOUPLING_EXPORT void meldWith(const DataArrayChar *other); + MEDCOUPLING_EXPORT void setPartOfValues1(const DataArrayChar *a, int bgTuples, int endTuples, int stepTuples, int bgComp, int endComp, int stepComp, bool strictCompoCompare=true); + MEDCOUPLING_EXPORT void setPartOfValuesSimple1(char a, int bgTuples, int endTuples, int stepTuples, int bgComp, int endComp, int stepComp); + MEDCOUPLING_EXPORT void setPartOfValues2(const DataArrayChar *a, const int *bgTuples, const int *endTuples, const int *bgComp, const int *endComp, bool strictCompoCompare=true); + MEDCOUPLING_EXPORT void setPartOfValuesSimple2(char a, const int *bgTuples, const int *endTuples, const int *bgComp, const int *endComp); + MEDCOUPLING_EXPORT void setPartOfValues3(const DataArrayChar *a, const int *bgTuples, const int *endTuples, int bgComp, int endComp, int stepComp, bool strictCompoCompare=true); + MEDCOUPLING_EXPORT void setPartOfValuesSimple3(char a, const int *bgTuples, const int *endTuples, int bgComp, int endComp, int stepComp); + MEDCOUPLING_EXPORT void setPartOfValues4(const DataArrayChar *a, int bgTuples, int endTuples, int stepTuples, const int *bgComp, const int *endComp, bool strictCompoCompare=true); + MEDCOUPLING_EXPORT void setPartOfValuesSimple4(char a, int bgTuples, int endTuples, int stepTuples, const int *bgComp, const int *endComp); + MEDCOUPLING_EXPORT void setPartOfValuesAdv(const DataArrayChar *a, const DataArrayChar *tuplesSelec); + MEDCOUPLING_EXPORT void setContigPartOfSelectedValues(int tupleIdStart, const DataArray *aBase, const DataArrayInt *tuplesSelec); + MEDCOUPLING_EXPORT void setContigPartOfSelectedValues2(int tupleIdStart, const DataArray *aBase, int bg, int end2, int step); + MEDCOUPLING_EXPORT DataArray *selectByTupleRanges(const std::vector<std::pair<int,int> >& ranges) const; + 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; + MEDCOUPLING_EXPORT char front() const; + MEDCOUPLING_EXPORT char back() const; + 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(); declareAsNew(); } + MEDCOUPLING_EXPORT const char *getConstPointer() const { return _mem.getConstPointer(); } + MEDCOUPLING_EXPORT const char *begin() const { return getConstPointer(); } + MEDCOUPLING_EXPORT const char *end() const { return getConstPointer()+getNbOfElems(); } + MEDCOUPLING_EXPORT DataArrayInt *getIdsEqual(char val) const; + MEDCOUPLING_EXPORT DataArrayInt *getIdsNotEqual(char val) const; + MEDCOUPLING_EXPORT int search(const std::vector<char>& vals) const; + MEDCOUPLING_EXPORT int locateTuple(const std::vector<char>& tupl) const; + MEDCOUPLING_EXPORT int locateValue(char value) const; + MEDCOUPLING_EXPORT int locateValue(const std::vector<char>& vals) const; + MEDCOUPLING_EXPORT bool presenceOfTuple(const std::vector<char>& tupl) const; + MEDCOUPLING_EXPORT bool presenceOfValue(char value) const; + MEDCOUPLING_EXPORT bool presenceOfValue(const std::vector<char>& vals) const; + MEDCOUPLING_EXPORT char getMaxValue(int& tupleId) const; + MEDCOUPLING_EXPORT char getMaxValueInArray() const; + MEDCOUPLING_EXPORT char getMinValue(int& tupleId) const; + MEDCOUPLING_EXPORT char getMinValueInArray() const; + MEDCOUPLING_EXPORT DataArrayInt *getIdsInRange(char vmin, char vmax) const; + MEDCOUPLING_EXPORT static DataArrayChar *Aggregate(const DataArrayChar *a1, const DataArrayChar *a2); + MEDCOUPLING_EXPORT static DataArrayChar *Aggregate(const std::vector<const DataArrayChar *>& arr); + MEDCOUPLING_EXPORT static DataArrayChar *Meld(const DataArrayChar *a1, const DataArrayChar *a2); + MEDCOUPLING_EXPORT static DataArrayChar *Meld(const std::vector<const DataArrayChar *>& arr); + MEDCOUPLING_EXPORT void useArray(const char *array, bool ownership, DeallocType type, int nbOfTuple, int nbOfCompo); + template<class InputIterator> + void insertAtTheEnd(InputIterator first, InputIterator last); + MEDCOUPLING_EXPORT void useExternalArrayWithRWAccess(const char *array, int nbOfTuple, int nbOfCompo); + MEDCOUPLING_EXPORT void updateTime() const { } + MEDCOUPLING_EXPORT MemArray<char>& accessToMemArray() { return _mem; } + MEDCOUPLING_EXPORT const MemArray<char>& accessToMemArray() const { return _mem; } + public: + //MEDCOUPLING_EXPORT void getTinySerializationIntInformation(std::vector<int>& tinyInfo) const; + //MEDCOUPLING_EXPORT void getTinySerializationStrInformation(std::vector<std::string>& tinyInfo) const; + //MEDCOUPLING_EXPORT bool resizeForUnserialization(const std::vector<int>& tinyInfoI); + //MEDCOUPLING_EXPORT void finishUnserialization(const std::vector<int>& tinyInfoI, const std::vector<std::string>& tinyInfoS); + protected: + DataArrayChar() { } + protected: + MemArray<char> _mem; + }; + + class DataArrayByteIterator; + + class DataArrayByte : public DataArrayChar + { + public: + MEDCOUPLING_EXPORT static DataArrayByte *New(); + MEDCOUPLING_EXPORT DataArrayChar *buildEmptySpecializedDAChar() const; + MEDCOUPLING_EXPORT DataArrayByteIterator *iterator(); + MEDCOUPLING_EXPORT DataArrayByte *deepCpy() const; + MEDCOUPLING_EXPORT DataArrayByte *performCpy(bool deepCpy) const; + MEDCOUPLING_EXPORT char byteValue() const; + 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 std::string& varName, std::ostream& stream) const; + MEDCOUPLING_EXPORT void reprQuickOverview(std::ostream& stream) const; + MEDCOUPLING_EXPORT void reprQuickOverviewData(std::ostream& stream, std::size_t maxNbOfByteInRepr) const; + MEDCOUPLING_EXPORT bool isEqualIfNotWhy(const DataArrayChar& other, std::string& reason) const; + MEDCOUPLING_EXPORT std::vector<bool> toVectorOfBool() const; + private: + ~DataArrayByte() { } + DataArrayByte() { } + }; + + class DataArrayByteTuple; + + class DataArrayByteIterator + { + public: + MEDCOUPLING_EXPORT DataArrayByteIterator(DataArrayByte *da); + MEDCOUPLING_EXPORT ~DataArrayByteIterator(); + MEDCOUPLING_EXPORT DataArrayByteTuple *nextt(); + private: + DataArrayByte *_da; + char *_pt; + int _tuple_id; + int _nb_comp; + int _nb_tuple; + }; + + class DataArrayByteTuple + { + public: + MEDCOUPLING_EXPORT DataArrayByteTuple(char *pt, int nbOfComp); + MEDCOUPLING_EXPORT std::string repr() const; + MEDCOUPLING_EXPORT int getNumberOfCompo() const { return _nb_of_compo; } + MEDCOUPLING_EXPORT const char *getConstPointer() const { return _pt; } + MEDCOUPLING_EXPORT char *getPointer() { return _pt; } + MEDCOUPLING_EXPORT char byteValue() const; + MEDCOUPLING_EXPORT DataArrayByte *buildDAByte(int nbOfTuples, int nbOfCompo) const; + 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); + MEDCOUPLING_EXPORT static DataArrayAsciiChar *New(const std::vector<std::string>& vst, char defaultChar); + MEDCOUPLING_EXPORT DataArrayChar *buildEmptySpecializedDAChar() const; + MEDCOUPLING_EXPORT DataArrayAsciiCharIterator *iterator(); + MEDCOUPLING_EXPORT DataArrayAsciiChar *deepCpy() const; + MEDCOUPLING_EXPORT DataArrayAsciiChar *performCpy(bool deepCpy) const; + MEDCOUPLING_EXPORT char asciiCharValue() const; + 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 std::string& varName, std::ostream& stream) const; + MEDCOUPLING_EXPORT void reprQuickOverview(std::ostream& stream) const; + MEDCOUPLING_EXPORT void reprQuickOverviewData(std::ostream& stream, std::size_t maxNbOfByteInRepr) const; + MEDCOUPLING_EXPORT bool isEqualIfNotWhy(const DataArrayChar& other, std::string& reason) const; + private: + ~DataArrayAsciiChar() { } + DataArrayAsciiChar() { } + DataArrayAsciiChar(const std::string& st); + DataArrayAsciiChar(const std::vector<std::string>& vst, char defaultChar); + }; + + class DataArrayAsciiCharTuple; + + class DataArrayAsciiCharIterator + { + public: + MEDCOUPLING_EXPORT DataArrayAsciiCharIterator(DataArrayAsciiChar *da); + MEDCOUPLING_EXPORT ~DataArrayAsciiCharIterator(); + MEDCOUPLING_EXPORT DataArrayAsciiCharTuple *nextt(); + private: + DataArrayAsciiChar *_da; + char *_pt; + int _tuple_id; + int _nb_comp; + int _nb_tuple; + }; + + class DataArrayAsciiCharTuple + { + public: + MEDCOUPLING_EXPORT DataArrayAsciiCharTuple(char *pt, int nbOfComp); + MEDCOUPLING_EXPORT std::string repr() const; + MEDCOUPLING_EXPORT int getNumberOfCompo() const { return _nb_of_compo; } + MEDCOUPLING_EXPORT const char *getConstPointer() const { return _pt; } + MEDCOUPLING_EXPORT char *getPointer() { return _pt; } + MEDCOUPLING_EXPORT char asciiCharValue() const; + MEDCOUPLING_EXPORT DataArrayAsciiChar *buildDAAsciiChar(int nbOfTuples, int nbOfCompo) const; + private: + char *_pt; + int _nb_of_compo; + }; + + template<class InputIterator> + void DataArrayDouble::insertAtTheEnd(InputIterator first, InputIterator last) + { + 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<class InputIterator> + void DataArrayInt::insertAtTheEnd(InputIterator first, InputIterator last) + { + 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 !"); + } + + template<class InputIterator> + void DataArrayChar::insertAtTheEnd(InputIterator first, InputIterator last) + { + 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("DataArrayChar::insertAtTheEnd : not available for DataArrayChar with number of components different than 1 !"); + } +} + +#endif diff --git a/src/medtool/src/MEDCoupling/MEDCouplingMemArray.txx b/src/medtool/src/MEDCoupling/MEDCouplingMemArray.txx new file mode 100644 index 000000000..693e6e4f0 --- /dev/null +++ b/src/medtool/src/MEDCoupling/MEDCouplingMemArray.txx @@ -0,0 +1,495 @@ +// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 +// 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_MEDCOUPLINGMEMARRAY_TXX__ +#define __PARAMEDMEM_MEDCOUPLINGMEMARRAY_TXX__ + +#include "MEDCouplingMemArray.hxx" +#include "NormalizedUnstructuredMesh.hxx" +#include "InterpKernelException.hxx" +#include "InterpolationUtils.hxx" + +#include <sstream> +#include <cstdlib> +#include <algorithm> + +namespace ParaMEDMEM +{ + template<class T> + void MEDCouplingPointer<T>::setInternal(T *pointer) + { + _internal=pointer; + _external=0; + } + + template<class T> + void MEDCouplingPointer<T>::setExternal(const T *pointer) + { + _external=pointer; + _internal=0; + } + + template<class T> + MemArray<T>::MemArray(const MemArray<T>& other):_nb_of_elem(0),_nb_of_elem_alloc(0),_ownership(false),_dealloc(0),_param_for_deallocator(0) + { + if(!other._pointer.isNull()) + { + _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,C_DEALLOC,other._nb_of_elem); + } + } + + template<class T> + void MemArray<T>::useArray(const T *array, bool ownership, DeallocType type, std::size_t nbOfElem) + { + destroy(); + _nb_of_elem=nbOfElem; + _nb_of_elem_alloc=nbOfElem; + if(ownership) + _pointer.setInternal(const_cast<T *>(array)); + else + _pointer.setExternal(array); + _ownership=ownership; + _dealloc=BuildFromType(type); + } + + template<class T> + void MemArray<T>::useExternalArrayWithRWAccess(const T *array, std::size_t nbOfElem) + { + destroy(); + _nb_of_elem=nbOfElem; + _nb_of_elem_alloc=nbOfElem; + _pointer.setInternal(const_cast<T *>(array)); + _ownership=false; + _dealloc=CPPDeallocator; + } + + template<class T> + void MemArray<T>::writeOnPlace(std::size_t id, T element0, const T *others, std::size_t sizeOfOthers) + { + 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<std::size_t>(_nb_of_elem,id+sizeOfOthers+1); + } + + template<class T> + template<class InputIterator> + void MemArray<T>::insertAtTheEnd(InputIterator first, InputIterator last) + { + T *pointer=_pointer.getPointer(); + while(first!=last) + { + if(_nb_of_elem>=_nb_of_elem_alloc) + { + reserve(_nb_of_elem_alloc>0?2*_nb_of_elem_alloc:1); + pointer=_pointer.getPointer(); + } + pointer[_nb_of_elem++]=*first++; + } + } + + template<class T> + void MemArray<T>::pushBack(T elem) + { + 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<class T> + T MemArray<T>::popBack() + { + 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<class T> + void MemArray<T>::pack() const + { + (const_cast<MemArray<T> * >(this))->reserve(_nb_of_elem); + } + + template<class T> + bool MemArray<T>::isEqual(const MemArray<T>& other, T prec, std::string& reason) const + { + std::ostringstream oss; oss.precision(15); + if(_nb_of_elem!=other._nb_of_elem) + { + oss << "Number of elements in coarse data of DataArray mismatch : this=" << _nb_of_elem << " other=" << other._nb_of_elem; + reason=oss.str(); + return false; + } + const T *pt1=_pointer.getConstPointer(); + const T *pt2=other._pointer.getConstPointer(); + if(pt1==0 && pt2==0) + return true; + if(pt1==0 || pt2==0) + { + oss << "coarse data pointer is defined for only one DataArray instance !"; + reason=oss.str(); + return false; + } + if(pt1==pt2) + return true; + 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]; + reason=oss.str(); + return false; + } + return true; + } + + /*! + * \param [in] sl is typically the number of components + * \return True if a not null pointer is present, False if not. + */ + template<class T> + bool MemArray<T>::reprHeader(int sl, std::ostream& stream) const + { + stream << "Number of tuples : "; + if(!_pointer.isNull()) + { + if(sl!=0) + 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"; + bool ret=!_pointer.isNull(); + if(!ret) + stream << "No data !\n"; + return ret; + } + + /*! + * \param [in] sl is typically the number of components + */ + template<class T> + void MemArray<T>::repr(int sl, std::ostream& stream) const + { + if(reprHeader(sl,stream)) + { + const T *data=getConstPointer(); + if(_nb_of_elem!=0 && sl!=0) + { + std::size_t nbOfTuples=_nb_of_elem/std::abs(sl); + for(std::size_t i=0;i<nbOfTuples;i++) + { + stream << "Tuple #" << i << " : "; + std::copy(data,data+sl,std::ostream_iterator<T>(stream," ")); + stream << "\n"; + data+=sl; + } + } + else + stream << "Empty Data\n"; + } + } + + /*! + * \param [in] sl is typically the number of components + */ + template<class T> + void MemArray<T>::reprZip(int sl, std::ostream& stream) const + { + stream << "Number of tuples : "; + if(!_pointer.isNull()) + { + if(sl!=0) + stream << _nb_of_elem/sl; + else + stream << "Empty Data"; + } + else + stream << "No data"; + stream << "\n"; + stream << "Data content : "; + const T *data=getConstPointer(); + if(!_pointer.isNull()) + { + if(_nb_of_elem!=0 && sl!=0) + { + std::size_t nbOfTuples=_nb_of_elem/std::abs(sl); + for(std::size_t i=0;i<nbOfTuples;i++) + { + stream << "|"; + std::copy(data,data+sl,std::ostream_iterator<T>(stream," ")); + stream << "| "; + data+=sl; + } + stream << "\n"; + } + else + stream << "Empty Data\n"; + } + else + stream << "No data !\n"; + } + + /*! + * \param [in] sl is typically the number of components + */ + template<class T> + void MemArray<T>::reprNotTooLong(int sl, std::ostream& stream) const + { + if(reprHeader(sl,stream)) + { + const T *data=getConstPointer(); + if(_nb_of_elem!=0 && sl!=0) + { + std::size_t nbOfTuples=_nb_of_elem/std::abs(sl); + if(nbOfTuples<=1000) + { + for(std::size_t i=0;i<nbOfTuples;i++) + { + stream << "Tuple #" << i << " : "; + std::copy(data,data+sl,std::ostream_iterator<T>(stream," ")); + stream << "\n"; + data+=sl; + } + } + else + {// too much tuples -> print the 3 first tuples and 3 last. + stream << "Tuple #0 : "; + std::copy(data,data+sl,std::ostream_iterator<T>(stream," ")); stream << "\n"; + stream << "Tuple #1 : "; + std::copy(data+sl,data+2*sl,std::ostream_iterator<T>(stream," ")); stream << "\n"; + stream << "Tuple #2 : "; + std::copy(data+2*sl,data+3*sl,std::ostream_iterator<T>(stream," ")); stream << "\n"; + stream << "...\n"; + stream << "Tuple #" << nbOfTuples-3 << " : "; + std::copy(data+(nbOfTuples-3)*sl,data+(nbOfTuples-2)*sl,std::ostream_iterator<T>(stream," ")); stream << "\n"; + stream << "Tuple #" << nbOfTuples-2 << " : "; + std::copy(data+(nbOfTuples-2)*sl,data+(nbOfTuples-1)*sl,std::ostream_iterator<T>(stream," ")); stream << "\n"; + stream << "Tuple #" << nbOfTuples-1 << " : "; + std::copy(data+(nbOfTuples-1)*sl,data+nbOfTuples*sl,std::ostream_iterator<T>(stream," ")); stream << "\n"; + } + } + else + stream << "Empty Data\n"; + } + } + + template<class T> + void MemArray<T>::fillWithValue(const T& val) + { + T *pt=_pointer.getPointer(); + std::fill(pt,pt+_nb_of_elem,val); + } + + template<class T> + T *MemArray<T>::fromNoInterlace(int nbOfComp) const + { + if(nbOfComp<1) + throw INTERP_KERNEL::Exception("MemArray<T>::fromNoInterlace : number of components must be > 0 !"); + const T *pt=_pointer.getConstPointer(); + std::size_t nbOfTuples=_nb_of_elem/nbOfComp; + T *ret=(T*)malloc(_nb_of_elem*sizeof(T)); + T *w=ret; + for(std::size_t i=0;i<nbOfTuples;i++) + for(int j=0;j<nbOfComp;j++,w++) + *w=pt[j*nbOfTuples+i]; + return ret; + } + + template<class T> + T *MemArray<T>::toNoInterlace(int nbOfComp) const + { + if(nbOfComp<1) + throw INTERP_KERNEL::Exception("MemArray<T>::toNoInterlace : number of components must be > 0 !"); + const T *pt=_pointer.getConstPointer(); + 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<nbOfComp;i++) + for(std::size_t j=0;j<nbOfTuples;j++,w++) + *w=pt[j*nbOfComp+i]; + return ret; + } + + template<class T> + void MemArray<T>::sort(bool asc) + { + T *pt=_pointer.getPointer(); + if(asc) + std::sort(pt,pt+_nb_of_elem); + else + { + typename std::reverse_iterator<T *> it1(pt+_nb_of_elem); + typename std::reverse_iterator<T *> it2(pt); + std::sort(it1,it2); + } + } + + template<class T> + void MemArray<T>::reverse(int nbOfComp) + { + if(nbOfComp<1) + throw INTERP_KERNEL::Exception("MemArray<T>::reverse : only supported with 'this' array with ONE or more than ONE component !"); + T *pt=_pointer.getPointer(); + 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<nbOfTuples/2;i++,pt+=nbOfComp,pt2-=nbOfComp) + { + for(int j=0;j<nbOfComp;j++) + std::swap(pt[j],pt2[j]); + } + } + } + + template<class T> + void MemArray<T>::alloc(std::size_t nbOfElements) + { + destroy(); + _nb_of_elem=nbOfElements; + _nb_of_elem_alloc=nbOfElements; + _pointer.setInternal((T*)malloc(_nb_of_elem_alloc*sizeof(T))); + _ownership=true; + _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<T>::reAlloc method. + * So after the call of this method \a _nb_of_elem will be equal tostd::min<std::size_t>(_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<T>::reserve that is close to MemArray<T>::reAlloc but not same. + */ + template<class T> + void MemArray<T>::reserve(std::size_t newNbOfElements) + { + if(_nb_of_elem_alloc==newNbOfElements) + return ; + T *pointer=(T*)malloc(newNbOfElements*sizeof(T)); + std::copy(_pointer.getConstPointer(),_pointer.getConstPointer()+std::min<std::size_t>(_nb_of_elem,newNbOfElements),pointer); + if(_ownership) + DestroyPointer(const_cast<T *>(_pointer.getConstPointer()),_dealloc,_param_for_deallocator);//Do not use getPointer because in case of _external + _pointer.setInternal(pointer); + _nb_of_elem=std::min<std::size_t>(_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<std::size_t>(_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<T>::reserve that is close to MemArray<T>::reAlloc but not same. + */ + template<class T> + void MemArray<T>::reAlloc(std::size_t newNbOfElements) + { + if(_nb_of_elem==newNbOfElements) + return ; + T *pointer=(T*)malloc(newNbOfElements*sizeof(T)); + std::copy(_pointer.getConstPointer(),_pointer.getConstPointer()+std::min<std::size_t>(_nb_of_elem,newNbOfElements),pointer); + if(_ownership) + DestroyPointer(const_cast<T *>(_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=CDeallocator; + _param_for_deallocator=0; + } + + template<class T> + void MemArray<T>::CPPDeallocator(void *pt, void *param) + { + delete [] reinterpret_cast<T*>(pt); + } + + template<class T> + void MemArray<T>::CDeallocator(void *pt, void *param) + { + free(pt); + } + + template<class T> + typename MemArray<T>::Deallocator MemArray<T>::BuildFromType(DeallocType type) + { + switch(type) + { + case CPP_DEALLOC: + return CPPDeallocator; + case C_DEALLOC: + return CDeallocator; + default: + throw INTERP_KERNEL::Exception("Invalid deallocation requested ! Unrecognized enum DeallocType !"); + } + } + + template<class T> + void MemArray<T>::DestroyPointer(T *pt, typename MemArray<T>::Deallocator dealloc, void *param) + { + if(dealloc) + dealloc(pt,param); + } + + template<class T> + void MemArray<T>::destroy() + { + if(_ownership) + DestroyPointer(const_cast<T *>(_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; + _nb_of_elem=0; + _nb_of_elem_alloc=0; + } + + template<class T> + MemArray<T> &MemArray<T>::operator=(const MemArray<T>& other) + { + alloc(other._nb_of_elem); + std::copy(other._pointer.getConstPointer(),other._pointer.getConstPointer()+_nb_of_elem,_pointer.getPointer()); + return *this; + } +} + +#endif diff --git a/src/medtool/src/MEDCoupling/MEDCouplingMemArrayChar.cxx b/src/medtool/src/MEDCoupling/MEDCouplingMemArrayChar.cxx new file mode 100644 index 000000000..59d29b2aa --- /dev/null +++ b/src/medtool/src/MEDCoupling/MEDCouplingMemArrayChar.cxx @@ -0,0 +1,2602 @@ +// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 +// 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 <set> +#include <cmath> +#include <limits> +#include <numeric> +#include <algorithm> +#include <functional> + +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 +{ + 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 +{ + if(!isAllocated()) + throw INTERP_KERNEL::Exception("DataArrayChar::checkAllocated : Array is defined but not allocated ! Call alloc or setValues method first !"); +} + +/*! + * This method desallocated \a this without modification of informations relative to the components. + * After call of this method, DataArrayChar::isAllocated will return false. + * If \a this is already not allocated, \a this is let unchanged. + */ +void DataArrayChar::desallocate() +{ + _mem.destroy(); +} + +std::size_t DataArrayChar::getHeapMemorySizeWithoutChildren() const +{ + std::size_t sz(_mem.getNbOfElemAllocated()); + return DataArray::getHeapMemorySizeWithoutChildren()+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 +{ + 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;i<nbOfElems;i+=delta) + ret0+=pt[i]; + return ret+ret0; +} + +/*! + * Checks the number of tuples. + * \return bool - \a true if getNumberOfTuples() == 0, \a false else. + * \throw If \a this is not allocated. + */ +bool DataArrayChar::empty() const +{ + checkAllocated(); + return getNumberOfTuples()==0; +} + +/*! + * Copies all the data from another DataArrayChar. For more info see + * \ref MEDCouplingArrayBasicsCopyDeepAssign. + * \param [in] other - another instance of DataArrayChar to copy data from. + * \throw If the \a other is not allocated. + */ +void DataArrayChar::cpyFrom(const DataArrayChar& other) +{ + other.checkAllocated(); + int nbOfTuples=other.getNumberOfTuples(); + int nbOfComp=other.getNumberOfComponents(); + allocIfNecessary(nbOfTuples,nbOfComp); + std::size_t nbOfElems=(std::size_t)nbOfTuples*nbOfComp; + char *pt=getPointer(); + const char *ptI=other.getConstPointer(); + for(std::size_t i=0;i<nbOfElems;i++) + pt[i]=ptI[i]; + copyStringInfoFrom(other); +} + +/*! + * This method reserve nbOfElems elements in memory ( nbOfElems*4 bytes ) \b without impacting the number of tuples in \a this. + * If \a this has already been allocated, this method checks that \a this has only one component. If not an INTERP_KERNEL::Exception will be thrown. + * If \a this has not already been allocated, number of components is set to one. + * This method allows to reduce number of reallocations on invokation of DataArrayChar::pushBackSilent and DataArrayChar::pushBackValsSilent on \a this. + * + * \sa DataArrayChar::pack, DataArrayChar::pushBackSilent, DataArrayChar::pushBackValsSilent + */ +void DataArrayChar::reserve(std::size_t nbOfElems) +{ + int nbCompo=getNumberOfComponents(); + if(nbCompo==1) + { + _mem.reserve(nbOfElems); + } + else if(nbCompo==0) + { + _mem.reserve(nbOfElems); + _info_on_compo.resize(1); + } + else + throw INTERP_KERNEL::Exception("DataArrayChar::reserve : not available for DataArrayChar with number of components different than 1 !"); +} + +/*! + * This method adds at the end of \a this the single value \a val. This method do \b not update its time label to avoid useless incrementation + * of counter. So the caller is expected to call TimeLabel::declareAsNew on \a this at the end of the push session. + * + * \param [in] val the value to be added in \a this + * \throw If \a this has already been allocated with number of components different from one. + * \sa DataArrayChar::pushBackValsSilent + */ +void DataArrayChar::pushBackSilent(char val) +{ + int nbCompo=getNumberOfComponents(); + if(nbCompo==1) + _mem.pushBack(val); + else if(nbCompo==0) + { + _info_on_compo.resize(1); + _mem.pushBack(val); + } + else + throw INTERP_KERNEL::Exception("DataArrayChar::pushBackSilent : not available for DataArrayChar with number of components different than 1 !"); +} + +/*! + * This method adds at the end of \a this a serie of values [\c valsBg,\c valsEnd). This method do \b not update its time label to avoid useless incrementation + * of counter. So the caller is expected to call TimeLabel::declareAsNew on \a this at the end of the push session. + * + * \param [in] valsBg - an array of values to push at the end of \this. + * \param [in] valsEnd - specifies the end of the array \a valsBg, so that + * the last value of \a valsBg is \a valsEnd[ -1 ]. + * \throw If \a this has already been allocated with number of components different from one. + * \sa DataArrayChar::pushBackSilent + */ +void DataArrayChar::pushBackValsSilent(const char *valsBg, const char *valsEnd) +{ + int nbCompo=getNumberOfComponents(); + if(nbCompo==1) + _mem.insertAtTheEnd(valsBg,valsEnd); + else if(nbCompo==0) + { + _info_on_compo.resize(1); + _mem.insertAtTheEnd(valsBg,valsEnd); + } + else + throw INTERP_KERNEL::Exception("DataArrayChar::pushBackValsSilent : not available for DataArrayChar with number of components different than 1 !"); +} + +/*! + * This method returns silently ( without updating time label in \a this ) the last value, if any and suppress it. + * \throw If \a this is already empty. + * \throw If \a this has number of components different from one. + */ +char DataArrayChar::popBackSilent() +{ + if(getNumberOfComponents()==1) + return _mem.popBack(); + else + throw INTERP_KERNEL::Exception("DataArrayChar::popBackSilent : not available for DataArrayChar with number of components different than 1 !"); +} + +/*! + * This method \b do \b not modify content of \a this. It only modify its memory footprint if the allocated memory is to high regarding real data to store. + * + * \sa DataArrayChar::getHeapMemorySizeWithoutChildren, DataArrayChar::reserve + */ +void DataArrayChar::pack() const +{ + _mem.pack(); +} + +/*! + * Allocates the raw data in memory. If exactly as same memory as needed already + * allocated, it is not re-allocated. + * \param [in] nbOfTuple - number of tuples of data to allocate. + * \param [in] nbOfCompo - number of components of data to allocate. + * \throw If \a nbOfTuple < 0 or \a nbOfCompo < 0. + */ +void DataArrayChar::allocIfNecessary(int nbOfTuple, int nbOfCompo) +{ + if(isAllocated()) + { + if(nbOfTuple!=getNumberOfTuples() || nbOfCompo!=getNumberOfComponents()) + alloc(nbOfTuple,nbOfCompo); + } + else + alloc(nbOfTuple,nbOfCompo); +} + +/*! + * Allocates the raw data in memory. If the memory was already allocated, then it is + * freed and re-allocated. See an example of this method use + * \ref MEDCouplingArraySteps1WC "here". + * \param [in] nbOfTuple - number of tuples of data to allocate. + * \param [in] nbOfCompo - number of components of data to allocate. + * \throw If \a nbOfTuple < 0 or \a nbOfCompo < 0. + */ +void DataArrayChar::alloc(int nbOfTuple, int nbOfCompo) +{ + if(nbOfTuple<0 || nbOfCompo<0) + throw INTERP_KERNEL::Exception("DataArrayChar::alloc : request for negative length of data !"); + _info_on_compo.resize(nbOfCompo); + _mem.alloc(nbOfCompo*(std::size_t)nbOfTuple); + declareAsNew(); +} + +/*! + * Checks if \a this and another DataArrayChar are fully equal. For more info see + * \ref MEDCouplingArrayBasicsCompare. + * \param [in] other - an instance of DataArrayChar to compare with \a this one. + * \return bool - \a true if the two arrays are equal, \a false else. + */ +bool DataArrayChar::isEqual(const DataArrayChar& other) const +{ + std::string tmp; + return isEqualIfNotWhy(other,tmp); +} + +/*! + * Equivalent to DataArrayChar::isEqual except that if false the reason of + * mismatch is given. + * + * \param [in] other the instance to be compared with \a this + * \param [out] reason In case of inequality returns the reason. + * \sa DataArrayChar::isEqual + */ +bool DataArrayChar::isEqualIfNotWhy(const DataArrayChar& other, std::string& reason) const +{ + if(!areInfoEqualsIfNotWhy(other,reason)) + return false; + return _mem.isEqual(other._mem,0,reason); +} + +/*! + * Checks if values of \a this and another DataArrayChar are equal. For more info see + * \ref MEDCouplingArrayBasicsCompare. + * \param [in] other - an instance of DataArrayChar to compare with \a this one. + * \return bool - \a true if the values of two arrays are equal, \a false else. + */ +bool DataArrayChar::isEqualWithoutConsideringStr(const DataArrayChar& other) const +{ + std::string tmp; + return _mem.isEqual(other._mem,0,tmp); +} + +/*! + * Reverse the array values. + * \throw If \a this->getNumberOfComponents() < 1. + * \throw If \a this is not allocated. + */ +void DataArrayChar::reverse() +{ + 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() +{ + 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) +{ + 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 +{ + std::ostringstream ret; + reprStream(ret); + return ret.str(); +} + +std::string DataArrayChar::reprZip() const +{ + 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. + * \throw If \a nbOfTuples is negative. + */ +void DataArrayChar::reAlloc(int nbOfTuples) +{ + if(nbOfTuples<0) + throw INTERP_KERNEL::Exception("DataArrayChar::reAlloc : input new number of tuples should be >=0 !"); + 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 +{ + 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 numbering. + * \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) +{ + checkAllocated(); + int nbTuples=getNumberOfTuples(); + int nbOfCompo=getNumberOfComponents(); + char *tmp=new char[nbTuples*nbOfCompo]; + const char *iptr=getConstPointer(); + for(int i=0;i<nbTuples;i++) + std::copy(iptr+nbOfCompo*i,iptr+nbOfCompo*(i+1),tmp+nbOfCompo*old2New[i]); + std::copy(tmp,tmp+nbTuples*nbOfCompo,getPointer()); + delete [] tmp; + declareAsNew(); +} + +/*! + * 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 numbering. + * \param [in] new2Old - C array of length equal to \a this->getNumberOfTuples() + * giving a previous position of i-th new value. + */ +void DataArrayChar::renumberInPlaceR(const int *new2Old) +{ + checkAllocated(); + int nbTuples=getNumberOfTuples(); + int nbOfCompo=getNumberOfComponents(); + char *tmp=new char[nbTuples*nbOfCompo]; + const char *iptr=getConstPointer(); + for(int i=0;i<nbTuples;i++) + std::copy(iptr+nbOfCompo*new2Old[i],iptr+nbOfCompo*(new2Old[i]+1),tmp+nbOfCompo*i); + std::copy(tmp,tmp+nbTuples*nbOfCompo,getPointer()); + delete [] tmp; + declareAsNew(); +} + +/*! + * 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 numbering. + * \param [in] old2New - C array of length equal to \a this->getNumberOfTuples() + * 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 +{ + checkAllocated(); + int nbTuples=getNumberOfTuples(); + int nbOfCompo=getNumberOfComponents(); + MEDCouplingAutoRefCountObjectPtr<DataArrayChar> ret=buildEmptySpecializedDAChar(); + ret->alloc(nbTuples,nbOfCompo); + ret->copyStringInfoFrom(*this); + const char *iptr=getConstPointer(); + char *optr=ret->getPointer(); + for(int i=0;i<nbTuples;i++) + std::copy(iptr+nbOfCompo*i,iptr+nbOfCompo*(i+1),optr+nbOfCompo*old2New[i]); + ret->copyStringInfoFrom(*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 numbering. + * \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 +{ + checkAllocated(); + int nbTuples=getNumberOfTuples(); + int nbOfCompo=getNumberOfComponents(); + MEDCouplingAutoRefCountObjectPtr<DataArrayChar> ret=buildEmptySpecializedDAChar(); + ret->alloc(nbTuples,nbOfCompo); + ret->copyStringInfoFrom(*this); + const char *iptr=getConstPointer(); + char *optr=ret->getPointer(); + for(int i=0;i<nbTuples;i++) + std::copy(iptr+nbOfCompo*new2Old[i],iptr+nbOfCompo*(new2Old[i]+1),optr+nbOfCompo*i); + ret->copyStringInfoFrom(*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 numbering. + * \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 +{ + checkAllocated(); + int nbTuples=getNumberOfTuples(); + int nbOfCompo=getNumberOfComponents(); + MEDCouplingAutoRefCountObjectPtr<DataArrayChar> ret=buildEmptySpecializedDAChar(); + ret->alloc(newNbOfTuple,nbOfCompo); + const char *iptr=getConstPointer(); + char *optr=ret->getPointer(); + for(int i=0;i<nbTuples;i++) + { + int w=old2New[i]; + if(w>=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. + * For more info on renumbering see \ref numbering. + * \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. + */ +DataArrayChar *DataArrayChar::selectByTupleId(const int *new2OldBg, const int *new2OldEnd) const +{ + return selectByTupleIdSafe(new2OldBg,new2OldEnd); +} + +/*! + * 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 numbering. + * \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 +{ + checkAllocated(); + MEDCouplingAutoRefCountObjectPtr<DataArrayChar> 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 && *w<oldNbOfTuples) + std::copy(srcPt+(*w)*nbComp,srcPt+((*w)+1)*nbComp,pt+i*nbComp); + else + throw INTERP_KERNEL::Exception("DataArrayChar::selectByTupleIdSafe : some ids has been detected to be out of [0,this->getNumberOfTuples) !"); + 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 numbering. + * \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 +{ + checkAllocated(); + MEDCouplingAutoRefCountObjectPtr<DataArrayChar> 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;i<newNbOfTuples;i++,srcPt+=step*nbComp) + std::copy(srcPt,srcPt+nbComp,pt+i*nbComp); + ret->copyStringInfoFrom(*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 +{ + 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) +{ + 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<int>::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 +{ + 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<DataArrayChar> 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 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::changeNbOfComponents(int newNbOfComp, char dftValue) const +{ + checkAllocated(); + MEDCouplingAutoRefCountObjectPtr<DataArrayChar> 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;i<nbOfTuples;i++) + { + int j=0; + for(;j<dim;j++) + nc[newNbOfComp*i+j]=oldc[i*oldNbOfComp+j]; + for(;j<newNbOfComp;j++) + nc[newNbOfComp*i+j]=dftValue; + } + ret->setName(getName()); + for(int i=0;i<dim;i++) + ret->setInfoOnComponent(i,getInfoOnComponent(i)); + ret->setName(getName()); + 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(). + * + * \if ENABLE_EXAMPLES + * \ref py_mcdataarrayint_keepselectedcomponents "Here is a Python example". + * \endif + */ +DataArrayChar *DataArrayChar::keepSelectedComponents(const std::vector<int>& compoIds) const +{ + checkAllocated(); + MEDCouplingAutoRefCountObjectPtr<DataArrayChar> ret(buildEmptySpecializedDAChar()); + int newNbOfCompo=(int)compoIds.size(); + int oldNbOfCompo=getNumberOfComponents(); + for(std::vector<int>::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;i<nbOfTuples;i++) + for(int j=0;j<newNbOfCompo;j++,nc++) + *nc=oldc[i*oldNbOfCompo+compoIds[j]]; + return ret.retn(); +} + +/*! + * 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 DataArrayChar 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. + * + * \if ENABLE_EXAMPLES + * \ref cpp_mcdataarrayint_meldwith "Here is a C++ example". + * + * \ref py_mcdataarrayint_meldwith "Here is a Python example". + * \endif + */ +void DataArrayChar::meldWith(const DataArrayChar *other) +{ + if(!other) + throw INTERP_KERNEL::Exception("DataArrayChar::meldWith : DataArrayChar pointer in input is NULL !"); + checkAllocated(); + other->checkAllocated(); + 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<nbOfTuples;i++,inp1+=nbOfComp1,inp2+=nbOfComp2) + { + w=std::copy(inp1,inp1+nbOfComp1,w); + w=std::copy(inp2,inp2+nbOfComp2,w); + } + useArray(newArr,true,C_DEALLOC,nbOfTuples,nbOfComp1+nbOfComp2); + std::vector<int> compIds(nbOfComp2); + for(int i=0;i<nbOfComp2;i++) + compIds[i]=nbOfComp1+i; + copyPartOfStringInfoFrom2(compIds,*other); +} + +/*! + * Copy all values from another DataArrayChar into specified tuples and components + * of \a this array. Textual data is not copied. + * The tree parameters defining set of indices of tuples and components are similar to + * the tree parameters of the Python function \c range(\c start,\c stop,\c step). + * \param [in] a - the array to copy values from. + * \param [in] bgTuples - index of the first tuple of \a this array to assign values to. + * \param [in] endTuples - index of the tuple before which the tuples to assign to + * are located. + * \param [in] stepTuples - index increment to get index of the next tuple to assign to. + * \param [in] bgComp - index of the first component of \a this array to assign values 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 - if \a true (by default), then \a a->getNumberOfComponents() + * 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)). + * + * \if ENABLE_EXAMPLES + * \ref py_mcdataarrayint_setpartofvalues1 "Here is a Python example". + * \endif + */ +void DataArrayChar::setPartOfValues1(const DataArrayChar *a, int bgTuples, int endTuples, int stepTuples, int bgComp, int endComp, int stepComp, bool strictCompoCompare) +{ + 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;i<newNbOfTuples;i++,pt+=stepTuples*nbComp) + for(int j=0;j<newNbOfComp;j++,srcPt++) + pt[j*stepComp]=*srcPt; + } + else + { + for(int i=0;i<newNbOfTuples;i++,pt+=stepTuples*nbComp) + { + const char *srcPt2=srcPt; + for(int j=0;j<newNbOfComp;j++,srcPt2++) + pt[j*stepComp]=*srcPt2; + } + } +} + +/*! + * Assign a given value to values at specified tuples and components of \a this array. + * The tree parameters defining set of indices of tuples and components are similar to + * the tree parameters of the Python function \c range(\c start,\c stop,\c step).. + * \param [in] a - the value to assign. + * \param [in] bgTuples - index of the first tuple of \a this array to assign to. + * \param [in] endTuples - index of the tuple before which the tuples to assign to + * are located. + * \param [in] stepTuples - index increment to get index of the next tuple to assign to. + * \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 parameters specifying tuples and 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. + * + * \if ENABLE_EXAMPLES + * \ref py_mcdataarrayint_setpartofvaluessimple1 "Here is a Python example". + * \endif + */ +void DataArrayChar::setPartOfValuesSimple1(char a, int bgTuples, int endTuples, int stepTuples, int bgComp, int endComp, int stepComp) +{ + const char msg[]="DataArrayChar::setPartOfValuesSimple1"; + 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"); + char *pt=getPointer()+bgTuples*nbComp+bgComp; + for(int i=0;i<newNbOfTuples;i++,pt+=stepTuples*nbComp) + for(int j=0;j<newNbOfComp;j++) + pt[j*stepComp]=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 and components to assign to are defined by C arrays of indices. + * 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 <em>(pi)</em> 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 <em>(pi)</em> 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 <em>bgTuples / bgComp</em> is + * out of a valid range for \a this array. + * \throw In the first *mode of usage*, if <em>strictCompoCompare == true </em> and + * if <em> a->getNumberOfComponents() != (endComp - bgComp) </em>. + * \throw In the second *mode of usage*, if \a a->getNumberOfTuples() != 1 or + * <em> a->getNumberOfComponents() != (endComp - bgComp)</em>. + * + * \if ENABLE_EXAMPLES + * \ref py_mcdataarrayint_setpartofvalues2 "Here is a Python example". + * \endif + */ +void DataArrayChar::setPartOfValues2(const DataArrayChar *a, const int *bgTuples, const int *endTuples, const int *bgComp, const int *endComp, bool strictCompoCompare) +{ + 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 <em>bgTuples / bgComp</em> is + * out of a valid range for \a this array. + * + * \if ENABLE_EXAMPLES + * \ref py_mcdataarrayint_setpartofvaluessimple2 "Here is a Python example". + * \endif + */ +void DataArrayChar::setPartOfValuesSimple2(char a, const int *bgTuples, const int *endTuples, const int *bgComp, const int *endComp) +{ + 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 <em>(pi)</em> 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 <em>strictCompoCompare == true </em> and + * if <em> a->getNumberOfComponents()</em> is unequal to the number of components + * defined by <em>(bgComp,endComp,stepComp)</em>. + * \throw In the second *mode of usage*, if \a a->getNumberOfTuples() != 1 or + * <em> a->getNumberOfComponents()</em> is unequal to the number of components + * defined by <em>(bgComp,endComp,stepComp)</em>. + * \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. + * + * \if ENABLE_EXAMPLES + * \ref py_mcdataarrayint_setpartofvalues3 "Here is a Python example". + * \endif + */ +void DataArrayChar::setPartOfValues3(const DataArrayChar *a, const int *bgTuples, const int *endTuples, int bgComp, int endComp, int stepComp, bool strictCompoCompare) +{ + 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<newNbOfComp;j++,srcPt++) + { + DataArray::CheckValueInRange(nbOfTuples,*w,"invalid tuple id"); + pt[(std::size_t)(*w)*nbComp+j*stepComp]=*srcPt; + } + } + else + { + for(const int *w=bgTuples;w!=endTuples;w++) + { + const char *srcPt2=srcPt; + for(int j=0;j<newNbOfComp;j++,srcPt2++) + { + DataArray::CheckValueInRange(nbOfTuples,*w,"invalid tuple id"); + pt[(std::size_t)(*w)*nbComp+j*stepComp]=*srcPt2; + } + } + } +} + +/*! + * Assign a given value to values at specified tuples and components of \a this array. + * 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). + * \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 <em>(pi)</em> 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. + * + * \if ENABLE_EXAMPLES + * \ref py_mcdataarrayint_setpartofvaluessimple3 "Here is a Python example". + * \endif + */ +void DataArrayChar::setPartOfValuesSimple3(char a, const int *bgTuples, const int *endTuples, int bgComp, int endComp, int stepComp) +{ + 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;j<newNbOfComp;j++) + { + DataArray::CheckValueInRange(nbOfTuples,*w,"invalid tuple id"); + pt[(*w)*nbComp+j*stepComp]=a; + } +} + +void DataArrayChar::setPartOfValues4(const DataArrayChar *a, int bgTuples, int endTuples, int stepTuples, const int *bgComp, const int *endComp, bool strictCompoCompare) +{ + if(!a) + throw INTERP_KERNEL::Exception("DataArrayInt::setPartOfValues4 : input DataArrayInt is NULL !"); + const char msg[]="DataArrayInt::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 char *srcPt=a->getConstPointer(); + char *pt=getPointer()+bgTuples*nbComp; + if(assignTech) + { + for(int i=0;i<newNbOfTuples;i++,pt+=stepTuples*nbComp) + for(const int *z=bgComp;z!=endComp;z++,srcPt++) + pt[*z]=*srcPt; + } + else + { + for(int i=0;i<newNbOfTuples;i++,pt+=stepTuples*nbComp) + { + const char *srcPt2=srcPt; + for(const int *z=bgComp;z!=endComp;z++,srcPt2++) + pt[*z]=*srcPt2; + } + } +} + +void DataArrayChar::setPartOfValuesSimple4(char a, int bgTuples, int endTuples, int stepTuples, const int *bgComp, const int *endComp) +{ + const char msg[]="DataArrayInt::setPartOfValuesSimple4"; + checkAllocated(); + int newNbOfTuples=DataArray::GetNumberOfItemGivenBES(bgTuples,endTuples,stepTuples,msg); + 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"); + char *pt=getPointer()+bgTuples*nbComp; + for(int i=0;i<newNbOfTuples;i++,pt+=stepTuples*nbComp) + for(const int *z=bgComp;z!=endComp;z++) + pt[*z]=a; +} + +/*! + * Copy some tuples from another DataArrayChar into specified tuples + * of \a this array. Textual data is not copied. Both arrays must have equal number of + * components. + * Both the tuples to assign and the tuples to assign to are defined by a DataArrayChar. + * All components of selected tuples are copied. + * \param [in] a - the array to copy values from. + * \param [in] tuplesSelec - the array specifying both source tuples of \a a and + * target tuples of \a this. \a tuplesSelec has two components, and the + * first component specifies index of the source tuple and the second + * one specifies index of the target tuple. + * \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 <em>this->getNumberOfComponents() != a->getNumberOfComponents()</em>. + * \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) +{ + 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]<aNt) + { + if(tuple[0]>=0 && tuple[0]<thisNt) + std::copy(valsSrc+nbOfComp*tuple[1],valsSrc+nbOfComp*(tuple[1]+1),valsToSet+nbOfComp*tuple[0]); + else + { + std::ostringstream oss; oss << "DataArrayChar::setPartOfValuesAdv : Tuple #" << std::distance(tuplesSelec->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 aBase) 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] aBase - the array to copy values from. + * \param [in] tuplesSelec - the array specifying tuples of \a aBase to copy. + * \throw If \a this is not allocated. + * \throw If \a aBase is NULL. + * \throw If \a aBase is not allocated. + * \throw If \a tuplesSelec is NULL. + * \throw If \a tuplesSelec is not allocated. + * \throw If <em>this->getNumberOfComponents() != aBase->getNumberOfComponents()</em>. + * \throw If \a tuplesSelec->getNumberOfComponents() != 1. + * \throw If <em>tupleIdStart + tuplesSelec->getNumberOfTuples() > this->getNumberOfTuples().</em> + * \throw If any tuple index given by \a tuplesSelec is out of a valid range for + * \a aBase array. + */ +void DataArrayChar::setContigPartOfSelectedValues(int tupleIdStart, const DataArray *aBase, const DataArrayInt *tuplesSelec) +{ + if(!aBase || !tuplesSelec) + throw INTERP_KERNEL::Exception("DataArrayChar::setContigPartOfSelectedValues : input DataArray is NULL !"); + const DataArrayChar *a=dynamic_cast<const DataArrayChar *>(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 && *tuple<aNt) + { + std::copy(valsSrc+nbOfComp*(*tuple),valsSrc+nbOfComp*(*tuple+1),valsToSet); + } + else + { + std::ostringstream oss; oss << "DataArrayChar::setContigPartOfSelectedValues : Tuple #" << std::distance(tuplesSelec->begin(),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 aBase) 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] aBase - the array to copy values from. + * \param [in] bg - index of the first tuple to copy of the array \a aBase. + * \param [in] end2 - index of the tuple of \a aBase 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 aBase is NULL. + * \throw If \a aBase is not allocated. + * \throw If <em>this->getNumberOfComponents() != aBase->getNumberOfComponents()</em>. + * \throw If <em>tupleIdStart + len(range(bg,end2,step)) > this->getNumberOfTuples().</em> + * \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 aBase. + */ +void DataArrayChar::setContigPartOfSelectedValues2(int tupleIdStart, const DataArray *aBase, int bg, int end2, int step) +{ + if(!aBase) + throw INTERP_KERNEL::Exception("DataArrayChar::setContigPartOfSelectedValues2 : input DataArray is NULL !"); + const DataArrayChar *a=dynamic_cast<const DataArrayChar *>(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<nbOfTupleToWrite;i++,valsToSet+=nbOfComp,valsSrc+=step*nbOfComp) + { + std::copy(valsSrc,valsSrc+nbOfComp,valsToSet); + } +} + +/*! + * Returns a shorten copy of \a this array. The new DataArrayChar contains ranges + * of tuples specified by \a ranges parameter. + * For more info on renumbering see \ref numbering. + * \param [in] ranges - std::vector of std::pair's each of which defines a range + * of tuples in [\c begin,\c end) format. + * \return DataArrayChar * - the new instance of DataArrayChar 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. + */ +DataArray *DataArrayChar::selectByTupleRanges(const std::vector<std::pair<int,int> >& ranges) const +{ + checkAllocated(); + int nbOfComp=getNumberOfComponents(); + int nbOfTuplesThis=getNumberOfTuples(); + if(ranges.empty()) + { + MEDCouplingAutoRefCountObjectPtr<DataArrayChar> 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<std::pair<int,int> >::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<DataArrayChar> ret=buildEmptySpecializedDAChar(); + ret->alloc(nbOfTuples,nbOfComp); + ret->copyStringInfoFrom(*this); + const char *src=getConstPointer(); + char *work=ret->getPointer(); + for(std::vector<std::pair<int,int> >::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 char - value located by \a tupleId and \a compoId. + * \throw If \a this is not allocated. + * \throw If condition <em>( 0 <= tupleId < this->getNumberOfTuples() )</em> is violated. + * \throw If condition <em>( 0 <= compoId < this->getNumberOfComponents() )</em> is violated. + */ +char DataArrayChar::getIJSafe(int tupleId, int compoId) const +{ + 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 first value of \a this. + * \return char - 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::front() const +{ + checkAllocated(); + if(getNumberOfComponents()!=1) + throw INTERP_KERNEL::Exception("DataArrayChar::front : number of components not equal to one !"); + int nbOfTuples=getNumberOfTuples(); + if(nbOfTuples<1) + throw INTERP_KERNEL::Exception("DataArrayChar::front : number of tuples must be >= 1 !"); + return *(getConstPointer()); +} + +/*! + * Returns the last value of \a this. + * \return char - 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 +{ + 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 +{ + 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<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1); + int nbOfTuples=getNumberOfTuples(); + for(int i=0;i<nbOfTuples;i++,cptr++) + if(*cptr==val) + ret->pushBackSilent(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 +{ + 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<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1); + int nbOfTuples=getNumberOfTuples(); + for(int i=0;i<nbOfTuples;i++,cptr++) + if(*cptr!=val) + ret->pushBackSilent(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<char>& vals) const +{ + 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<char>& tupl) const +{ + 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<char>& tupl) const +{ + 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 +{ + 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<char>& vals) const +{ + 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 +{ + 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<char>& vals) const +{ + 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<char> 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 char - 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 +{ + 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 +{ + 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 +{ + 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 +{ + 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 [in] 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 +{ + checkAllocated(); + if(getNumberOfComponents()!=1) + throw INTERP_KERNEL::Exception("DataArrayChar::getIdsInRange : this must have exactly one component !"); + const char *cptr=getConstPointer(); + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(0,1); + int nbOfTuples=getNumberOfTuples(); + for(int i=0;i<nbOfTuples;i++,cptr++) + if(*cptr>=vmin && *cptr<vmax) + ret->pushBackSilent(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 <em> a1->getNumberOfTuples() + a2->getNumberOfTuples() - + * offsetA2</em> 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<const DataArrayChar *> 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<const DataArrayChar *>& arr) +{ + std::vector<const DataArrayChar *> a; + for(std::vector<const DataArrayChar *>::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 DataArrayChar *>::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<DataArrayChar> 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) +{ + std::vector<const DataArrayChar *> 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<const DataArrayChar *>& arr) +{ + std::vector<const DataArrayChar *> a; + for(std::vector<const DataArrayChar *>::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 DataArrayChar *>::const_iterator it; + for(it=a.begin();it!=a.end();it++) + (*it)->checkAllocated(); + it=a.begin(); + int nbOfTuples=(*it)->getNumberOfTuples(); + std::vector<int> nbc(a.size()); + std::vector<const char *> 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;i<nbOfTuples;i++) + for(int j=0;j<(int)a.size();j++) + { + retPtr=std::copy(pts[j],pts[j]+nbc[j],retPtr); + pts[j]+=nbc[j]; + } + int k=0; + for(int i=0;i<(int)a.size();i++) + for(int j=0;j<nbc[i];j++,k++) + ret->setInfoOnComponent(k,a[i]->getInfoOnComponent(j)); + 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) +{ + _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) +{ + _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<DataArrayByte *>(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 char - the sole value stored in \a this array. + * \throw If at least one of conditions stated above is not fulfilled. + */ +char DataArrayByte::byteValue() const +{ + 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 +{ + return DataArrayByte::New(); +} + +void DataArrayByte::reprStream(std::ostream& stream) const +{ + stream << "Name of byte array : \"" << _name << "\"\n"; + reprWithoutNameStream(stream); +} + +void DataArrayByte::reprZipStream(std::ostream& stream) const +{ + stream << "Name of byte array : \"" << _name << "\"\n"; + reprZipWithoutNameStream(stream); +} + +void DataArrayByte::reprWithoutNameStream(std::ostream& stream) const +{ + DataArray::reprWithoutNameStream(stream); + if(_mem.reprHeader(getNumberOfComponents(),stream)) + { + const char *data=begin(); + int nbOfTuples=getNumberOfTuples(); + int nbCompo=getNumberOfComponents(); + for(int i=0;i<nbOfTuples;i++,data+=nbCompo) + { + stream << "Tuple #" << i << " : "; + std::copy(data,data+nbCompo,std::ostream_iterator<int>(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 +{ + DataArray::reprWithoutNameStream(stream); + _mem.reprZip(getNumberOfComponents(),stream); +} + +void DataArrayByte::reprCppStream(const std::string& varName, std::ostream& stream) const +{ + 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<char>(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 +{ + 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 +{ + 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<nbOfTuples && isFinished;i++) + { + if(nbOfCompo>1) + { + oss2 << "("; + for(int j=0;j<nbOfCompo;j++,data++) + { + oss2 << (int)*data; + if(j!=nbOfCompo-1) oss2 << ", "; + } + oss2 << ")"; + } + else + { oss2 << (int)*data; data++; } + if(i!=nbOfTuples-1) oss2 << ", "; + std::string oss3Str(oss2.str()); + if(oss3Str.length()<maxNbOfByteInRepr) + oss2Str=oss3Str; + else + isFinished=false; + } + stream << oss2Str; + if(!isFinished) + stream << "... "; + stream << "]"; +} + +bool DataArrayByte::isEqualIfNotWhy(const DataArrayChar& other, std::string& reason) const +{ + const DataArrayByte *otherC=dynamic_cast<const DataArrayByte *>(&other); + if(!otherC) + { reason="this is of type DataArrayByte whereas other is not a DataArrayByte instance"; return false; } + return DataArrayChar::isEqualIfNotWhy(other,reason); +} + +/*! + * This method is \b NOT wrapped into python because it can be useful only for performance reasons in C++ context. + * \throw if \a this is not allocated. + * \throw if \a this has not exactly one component. + */ +std::vector<bool> DataArrayByte::toVectorOfBool() const +{ + checkAllocated(); + if(getNumberOfComponents()!=1) + throw INTERP_KERNEL::Exception("DataArrayByte::toVectorOfBool : this method can be used only if this has one component !"); + int nbt(getNumberOfTuples()); + std::vector<bool> ret(nbt,false); + const char *pt(begin()); + for(int i=0;i<nbt;i++,pt++) + if(*pt!=0) + ret[i]=true; + return ret; +} + +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() +{ + 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 +{ + 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 +{ + 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 +{ + 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) +{ + 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) +{ + 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<std::string>& vst, char defaultChar) +{ + 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<std::string>& vst, char defaultChar) +{ + if(vst.empty()) + throw INTERP_KERNEL::Exception("DataArrayAsciiChar contructor with vector of strings ! Empty array !"); + std::size_t nbCompo=0; + for(std::vector<std::string>::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<nbTuples;i++,pt+=nbCompo) + { + const std::string& tmp=vst[i]; + std::size_t sz=tmp.length(); + std::copy(tmp.begin(),tmp.begin()+sz,pt); + std::fill(pt+sz,pt+nbCompo,defaultChar); + } +} + +DataArrayAsciiCharIterator *DataArrayAsciiChar::iterator() +{ + return new DataArrayAsciiCharIterator(this); +} + +/*! + * Returns a full copy of \a this. For more info on copying data arrays see + * \ref MEDCouplingArrayBasicsCopyDeep. + * \return DataArrayAsciiChar * - a new instance of DataArrayAsciiChar. + */ +DataArrayAsciiChar *DataArrayAsciiChar::deepCpy() const +{ + return new DataArrayAsciiChar(*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 DataArrayAsciiChar * - either a new instance of DataArrayAsciiChar (if \a dCpy + * == \a true) or \a this instance (if \a dCpy == \a false). + */ +DataArrayAsciiChar *DataArrayAsciiChar::performCpy(bool dCpy) const +{ + if(dCpy) + return deepCpy(); + else + { + incrRef(); + return const_cast<DataArrayAsciiChar *>(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 char - the sole value stored in \a this array. + * \throw If at least one of conditions stated above is not fulfilled. + */ +char DataArrayAsciiChar::asciiCharValue() const +{ + 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 +{ + return DataArrayAsciiChar::New(); +} + +void DataArrayAsciiChar::reprStream(std::ostream& stream) const +{ + stream << "Name of ASCII char array : \"" << _name << "\"\n"; + reprWithoutNameStream(stream); +} + +void DataArrayAsciiChar::reprZipStream(std::ostream& stream) const +{ + stream << "Name of ASCII char array : \"" << _name << "\"\n"; + reprZipWithoutNameStream(stream); +} + +void DataArrayAsciiChar::reprWithoutNameStream(std::ostream& stream) const +{ + DataArray::reprWithoutNameStream(stream); + if(_mem.reprHeader(getNumberOfComponents(),stream)) + { + const char *data=begin(); + int nbOfTuples=getNumberOfTuples(); + int nbCompo=getNumberOfComponents(); + for(int i=0;i<nbOfTuples;i++,data+=nbCompo) + { + stream << "Tuple #" << i << " : \""; + std::copy(data,data+nbCompo,std::ostream_iterator<char>(stream)); + stream << "\"\n"; + } + } +} + +void DataArrayAsciiChar::reprZipWithoutNameStream(std::ostream& stream) const +{ + reprWithoutNameStream(stream); +} + +void DataArrayAsciiChar::reprCppStream(const std::string& varName, std::ostream& stream) const +{ + 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<char>(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 +{ + 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 +{ + 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<nbOfTuples && isFinished;i++) + { + bool isAscii=true; + for(int j=0;j<nbOfCompo;j++) + if(data[j]<32) isAscii=false; + if(isAscii) + { + oss2 << "\'"; + for(int j=0;j<nbOfCompo;j++,data++) + oss2 << *data; + oss2 << "\'"; + } + else + { + oss2 << "("; + for(int j=0;j<nbOfCompo;j++,data++) + { + oss2 << (int)*data; + if(j!=nbOfCompo-1) oss2 << ", "; + } + oss2 << ")"; + } + if(i!=nbOfTuples-1) oss2 << ", "; + std::string oss3Str(oss2.str()); + if(oss3Str.length()<maxNbOfByteInRepr) + oss2Str=oss3Str; + else + isFinished=false; + } + stream << oss2Str; + if(!isFinished) + stream << "... "; + stream << "]"; +} + +bool DataArrayAsciiChar::isEqualIfNotWhy(const DataArrayChar& other, std::string& reason) const +{ + const DataArrayAsciiChar *otherC=dynamic_cast<const DataArrayAsciiChar *>(&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() +{ + 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 +{ + std::ostringstream oss; + std::copy(_pt,_pt+_nb_of_compo,std::ostream_iterator<char>(oss)); + return oss.str(); +} + +char DataArrayAsciiCharTuple::asciiCharValue() const +{ + 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 +{ + 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/medtool/src/MEDCoupling/MEDCouplingMesh.cxx b/src/medtool/src/MEDCoupling/MEDCouplingMesh.cxx new file mode 100644 index 000000000..ea60f27de --- /dev/null +++ b/src/medtool/src/MEDCoupling/MEDCouplingMesh.cxx @@ -0,0 +1,760 @@ +// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 +// 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 "MEDCouplingMesh.hxx" +#include "MEDCouplingUMesh.hxx" +#include "MEDCouplingMemArray.hxx" +#include "MEDCouplingFieldDouble.hxx" +#include "MEDCouplingFieldDiscretization.hxx" +#include "MEDCouplingAutoRefCountObjectPtr.hxx" + +#include <set> +#include <cmath> +#include <sstream> +#include <fstream> +#include <iterator> + +using namespace ParaMEDMEM; + +MEDCouplingMesh::MEDCouplingMesh():_time(0.),_iteration(-1),_order(-1) +{ +} + +MEDCouplingMesh::MEDCouplingMesh(const MEDCouplingMesh& other):RefCountObject(other),_name(other._name),_description(other._description), + _time(other._time),_iteration(other._iteration), + _order(other._order),_time_unit(other._time_unit) +{ +} + +std::size_t MEDCouplingMesh::getHeapMemorySizeWithoutChildren() const +{ + return _name.capacity()+_description.capacity()+_time_unit.capacity(); +} + +/*! + * This method is only for ParaMEDMEM in ParaFIELD constructor. + */ +bool MEDCouplingMesh::isStructured() const +{ + return getType()==CARTESIAN; +} + +bool MEDCouplingMesh::isEqualIfNotWhy(const MEDCouplingMesh *other, double prec, std::string& reason) const +{ + if(!other) + throw INTERP_KERNEL::Exception("MEDCouplingMesh::isEqualIfNotWhy : other instance is NULL !"); + std::ostringstream oss; oss.precision(15); + if(_name!=other->_name) + { + oss << "Mesh names differ : this name = \"" << _name << "\" and other name = \"" << other->_name << "\" !"; + reason=oss.str(); + return false; + } + if(_description!=other->_description) + { + oss << "Mesh descriptions differ : this description = \"" << _description << "\" and other description = \"" << other->_description << "\" !"; + reason=oss.str(); + return false; + } + if(_iteration!=other->_iteration) + { + oss << "Mesh iterations differ : this iteration = \"" << _iteration << "\" and other iteration = \"" << other->_iteration << "\" !"; + reason=oss.str(); + return false; + } + if(_order!=other->_order) + { + oss << "Mesh orders differ : this order = \"" << _order << "\" and other order = \"" << other->_order << "\" !"; + reason=oss.str(); + return false; + } + if(_time_unit!=other->_time_unit) + { + oss << "Mesh time units differ : this time unit = \"" << _time_unit << "\" and other time unit = \"" << other->_time_unit << "\" !"; + reason=oss.str(); + return false; + } + if(fabs(_time-other->_time)>=1e-12) + { + oss << "Mesh times differ : this time = \"" << _time << "\" and other time = \"" << other->_time << "\" !"; + reason=oss.str(); + return false; + } + 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 +{ + std::string tmp; + return isEqualIfNotWhy(other,prec,tmp); +} + +/*! + * 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. + * + * 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. \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 +{ + cellCor=0; + nodeCor=0; + if(this==other) + return ; + switch(levOfCheck) + { + case 0: + { + if(!isEqual(other,prec)) + throw INTERP_KERNEL::Exception("checkGeoFitWith : Meshes are not equal !"); + return ; + } + case 10: + case 11: + case 12: + { + checkDeepEquivalWith(other,levOfCheck-10,prec,cellCor,nodeCor); + return ; + } + case 20: + case 21: + case 22: + { + checkDeepEquivalOnSameNodesWith(other,levOfCheck-20,prec,cellCor); + return ; + } + case 1: + { + checkFastEquivalWith(other,prec); + return; + } + case 2: + { + if(!isEqualWithoutConsideringStr(other,prec)) + throw INTERP_KERNEL::Exception("checkGeoFitWith : Meshes are not equal without considering strings !"); + return ; + } + default: + throw INTERP_KERNEL::Exception("checkGeoFitWith : Invalid levOfCheck specified ! Value must be in 0,1,2,10,11 or 12."); + } +} + +/*! + * 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 +{ + std::vector<int> crest; + std::set<int> p(partBg,partEnd); + int nbOfCells=getNumberOfCells(); + for(int i=0;i<nbOfCells;i++) + { + std::vector<int> conn; + getNodeIdsOfCell(i,conn); + bool cont=true; + for(std::vector<int>::const_iterator iter=conn.begin();iter!=conn.end() && cont;iter++) + if(p.find(*iter)==p.end()) + cont=false; + if(cont) + crest.push_back(i); + } + DataArrayInt *ret=DataArrayInt::New(); + ret->alloc((int)crest.size(),1); + std::copy(crest.begin(),crest.end(),ret->getPointer()); + return ret; +} + +/*! + * 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 +{ + if(!other) + throw INTERP_KERNEL::Exception("MEDCouplingMesh::checkFastEquivalWith : input mesh is null !"); + if(getMeshDimension()!=other->getMeshDimension()) + throw INTERP_KERNEL::Exception("checkFastEquivalWith : Mesh dimensions are not equal !"); + if(getSpaceDimension()!=other->getSpaceDimension()) + throw INTERP_KERNEL::Exception("checkFastEquivalWith : Space dimensions are not equal !"); + if(getNumberOfCells()!=other->getNumberOfCells()) + throw INTERP_KERNEL::Exception("checkFastEquivalWith : number of cells are not equal !"); +} + +/*! + * 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 +{ + if(!other) + throw INTERP_KERNEL::Exception("MEDCouplingMesh::areCompatibleForMerge : input mesh is null !"); + if(getMeshDimension()!=other->getMeshDimension()) + return false; + if(getSpaceDimension()!=other->getSpaceDimension()) + return false; + return true; +} + +/*! + * 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. + * \b WARNING , there is a big difference compared to MEDCouplingMesh::buildPart method. + * If the input range is equal all cells in \a this, \a this is returned ! + * + * \return a new ref to be managed by the caller. Warning this ref can be equal to \a this if input slice is exactly equal to the whole cells in the same order. + * + * \sa MEDCouplingMesh::buildPart + */ +MEDCouplingMesh *MEDCouplingMesh::buildPartRange(int beginCellIds, int endCellIds, int stepCellIds) const +{ + if(beginCellIds==0 && endCellIds==getNumberOfCells() && stepCellIds==1) + { + MEDCouplingMesh *ret(const_cast<MEDCouplingMesh *>(this)); + ret->incrRef(); + return ret; + } + else + { + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> 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 +{ + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> 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 + * evaluate. + * Contrary to other fillFromAnalytic methods this method requests a C++ function pointer as input. + * 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. + */ +MEDCouplingFieldDouble *MEDCouplingMesh::fillFromAnalytic(TypeOfField t, int nbOfComp, FunctionToEvaluate func) const +{ + MEDCouplingAutoRefCountObjectPtr<MEDCouplingFieldDouble> ret=MEDCouplingFieldDouble::New(t,ONE_TIME); + ret->setMesh(this); + ret->fillFromAnalytic(nbOfComp,func); + ret->synchronizeTimeWithSupport(); + return ret.retn(); +} + +/*! + * This method copyies all tiny strings from other (name and components name). + * @throw if other and this have not same mesh type. + */ +void MEDCouplingMesh::copyTinyStringsFrom(const MEDCouplingMesh *other) +{ + if(!other) + throw INTERP_KERNEL::Exception("MEDCouplingMesh::copyTinyStringsFrom : input mesh is null !"); + _name=other->_name; + _description=other->_description; + _time_unit=other->_time_unit; +} + +/*! + * This method copies all attributes that are \b NOT arrays in this. + * All tiny attributes not usefully for state of \a this are ignored. + */ +void MEDCouplingMesh::copyTinyInfoFrom(const MEDCouplingMesh *other) +{ + _time=other->_time; + _iteration=other->_iteration; + _order=other->_order; + copyTinyStringsFrom(other); +} + +/*! + * \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.<br> + * 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)!<br> + * 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.<br> + * 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.) + * + * \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. + * + * \if ENABLE_EXAMPLES + * \ref cpp_mcmesh_fillFromAnalytic "Here is a C++ example".<br> + * \ref py_mcmesh_fillFromAnalytic "Here is a Python example". + * \endif + */ +MEDCouplingFieldDouble *MEDCouplingMesh::fillFromAnalytic(TypeOfField t, int nbOfComp, const std::string& func) const +{ + MEDCouplingAutoRefCountObjectPtr<MEDCouplingFieldDouble> ret=MEDCouplingFieldDouble::New(t,ONE_TIME); + ret->setMesh(this); + ret->fillFromAnalytic(nbOfComp,func); + ret->synchronizeTimeWithSupport(); + return ret.retn(); +} + +/*! + * 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 std::string& 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()).<br> + * For more info on supported expressions that can be used in the function, see \ref + * MEDCouplingArrayApplyFuncExpr. <br> + * 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.<br> + * 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 [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. + * + * \if ENABLE_EXAMPLES + * \ref cpp_mcmesh_fillFromAnalytic2 "Here is a C++ example".<br> + * \ref py_mcmesh_fillFromAnalytic2 "Here is a Python example". + * \endif + */ +MEDCouplingFieldDouble *MEDCouplingMesh::fillFromAnalytic2(TypeOfField t, int nbOfComp, const std::string& func) const +{ + MEDCouplingAutoRefCountObjectPtr<MEDCouplingFieldDouble> ret=MEDCouplingFieldDouble::New(t,ONE_TIME); + ret->setMesh(this); + ret->fillFromAnalytic2(nbOfComp,func); + ret->synchronizeTimeWithSupport(); + return ret.retn(); +} + +/*! + * 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.<br> + * 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.<br> + * 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. + * + * \if ENABLE_EXAMPLES + * \ref cpp_mcmesh_fillFromAnalytic3 "Here is a C++ example".<br> + * \ref py_mcmesh_fillFromAnalytic3 "Here is a Python example". + * \endif + */ +MEDCouplingFieldDouble *MEDCouplingMesh::fillFromAnalytic3(TypeOfField t, int nbOfComp, const std::vector<std::string>& varsOrder, const std::string& func) const +{ + MEDCouplingAutoRefCountObjectPtr<MEDCouplingFieldDouble> ret=MEDCouplingFieldDouble::New(t,ONE_TIME); + ret->setMesh(this); + ret->fillFromAnalytic3(nbOfComp,varsOrder,func); + ret->synchronizeTimeWithSupport(); + return ret.retn(); +} + +/*! + * 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) +{ + if(!mesh1) + throw INTERP_KERNEL::Exception("MEDCouplingMesh::MergeMeshes : first parameter is an empty mesh !"); + if(!mesh2) + throw INTERP_KERNEL::Exception("MEDCouplingMesh::MergeMeshes : second parameter is an empty mesh !"); + return mesh1->mergeMyselfWith(mesh2); +} + +/*! + * 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<const MEDCouplingMesh *>& meshes) +{ + std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> > ms1(meshes.size()); + std::vector< const MEDCouplingUMesh * > ms2(meshes.size()); + for(std::size_t i=0;i<meshes.size();i++) + { + if(meshes[i]) + { + MEDCouplingUMesh *cur=meshes[i]->buildUnstructured(); + ms1[i]=cur; ms2[i]=cur; + } + else + { + std::ostringstream oss; oss << "MEDCouplingMesh::MergeMeshes(std::vector<const MEDCouplingMesh *>& meshes) : mesh at pos #" << i << " of input vector of size " << meshes.size() << " is empty !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + } + return MEDCouplingUMesh::MergeUMeshes(ms2); +} + +/*! + * For example if \a type is INTERP_KERNEL::NORM_TRI3 , INTERP_KERNEL::NORM_POLYGON is returned. + * If \a type is INTERP_KERNEL::NORM_HEXA8 , INTERP_KERNEL::NORM_POLYHED is returned. + * + * \param [in] type the geometric type for which the corresponding dynamic type, is asked. + * \return the corresponding dynamic type, able to store the input \a type. + * + * \throw if type is equal to \c INTERP_KERNEL::NORM_ERROR or to an unexisting geometric type. + */ +INTERP_KERNEL::NormalizedCellType MEDCouplingMesh::GetCorrespondingPolyType(INTERP_KERNEL::NormalizedCellType type) +{ + const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(type); + return cm.getCorrespondingPolyType(); +} + +/*! + * \param [in] type the geometric type for which the number of nodes consituting it, is asked. + * \return number of nodes consituting the input geometric type \a type. + * + * \throw if type is dynamic as \c INTERP_KERNEL::NORM_POLYHED , \c INTERP_KERNEL::NORM_POLYGON , \c INTERP_KERNEL::NORM_QPOLYG + * \throw if type is equal to \c INTERP_KERNEL::NORM_ERROR or to an unexisting geometric type. + */ +int MEDCouplingMesh::GetNumberOfNodesOfGeometricType(INTERP_KERNEL::NormalizedCellType type) +{ + const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(type); + if(cm.isDynamic()) + throw INTERP_KERNEL::Exception("MEDCouplingMesh::GetNumberOfNodesOfGeometricType : the input geometric type is dynamic ! Impossible to return a fixed number of nodes constituting it !"); + return (int) cm.getNumberOfNodes(); +} + +/*! + * \param [in] type the geometric type for which the status static/dynamic is asked. + * \return true for static geometric type, false for dynamic geometric type. + * + * \throw if type is equal to \c INTERP_KERNEL::NORM_ERROR or to an unexisting geometric type. + */ +bool MEDCouplingMesh::IsStaticGeometricType(INTERP_KERNEL::NormalizedCellType type) +{ + const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(type); + return !cm.isDynamic(); +} + +bool MEDCouplingMesh::IsLinearGeometricType(INTERP_KERNEL::NormalizedCellType type) +{ + const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(type); + return !cm.isQuadratic(); +} + +/*! + * \param [in] type the geometric type for which the dimension is asked. + * \return the dimension associated to the input geometric type \a type. + * + * \throw if type is equal to \c INTERP_KERNEL::NORM_ERROR or to an unexisting geometric type. + */ +int MEDCouplingMesh::GetDimensionOfGeometricType(INTERP_KERNEL::NormalizedCellType type) +{ + const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(type); + return (int) cm.getDimension(); +} + +/*! + * \param [in] type the geometric type for which the representation is asked. + * \return the string representation corresponding to the input geometric type \a type. + * + * \throw if type is equal to \c INTERP_KERNEL::NORM_ERROR or to an unexisting geometric type. + */ +const char *MEDCouplingMesh::GetReprOfGeometricType(INTERP_KERNEL::NormalizedCellType type) +{ + const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(type); + return cm.getRepr(); +} + +/*! + * Finds cells in contact with a ball (i.e. a point with precision). + * \warning This method is suitable if the caller intends to evaluate only one + * point, for more points getCellsContainingPoints() is recommended as it is + * faster. + * \param [in] pos - array of coordinates of the ball central point. + * \param [in] eps - ball radius. + * \param [in,out] elts - vector returning ids of the found cells. It is cleared + * before inserting ids. + * + * \if ENABLE_EXAMPLES + * \ref cpp_mcumesh_getCellsContainingPoint "Here is a C++ example".<br> + * \ref py_mcumesh_getCellsContainingPoint "Here is a Python example". + * \endif + */ +void MEDCouplingMesh::getCellsContainingPoint(const double *pos, double eps, std::vector<int>& 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 [out] elts - vector returning ids of found cells. + * \param [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* ]. + * + * \if ENABLE_EXAMPLES + * \ref cpp_mcumesh_getCellsContainingPoints "Here is a C++ example".<br> + * \ref py_mcumesh_getCellsContainingPoints "Here is a Python example". + * \endif + */ +void MEDCouplingMesh::getCellsContainingPoints(const double *pos, int nbOfPoints, double eps, MEDCouplingAutoRefCountObjectPtr<DataArrayInt>& elts, MEDCouplingAutoRefCountObjectPtr<DataArrayInt>& eltsIndex) const +{ + eltsIndex=DataArrayInt::New(); elts=DataArrayInt::New(); eltsIndex->alloc(nbOfPoints+1,1); eltsIndex->setIJ(0,0,0); elts->alloc(0,1); + int *eltsIndexPtr(eltsIndex->getPointer()); + int spaceDim(getSpaceDimension()); + const double *work(pos); + for(int i=0;i<nbOfPoints;i++,work+=spaceDim) + { + int ret=getCellContainingPoint(work,eps); + if(ret>=0) + { + elts->pushBackSilent(ret); + eltsIndexPtr[i+1]=eltsIndexPtr[i]+1; + } + else + eltsIndexPtr[i+1]=eltsIndexPtr[i]; + } +} + +/*! + * Writes \a this mesh into a VTK format file named as specified. + * \param [in] fileName - the name of the file to write in. If the extension is OK the fileName will be used directly. + * If extension is invalid or no extension the right extension will be appended. + * \return - the real fileName + * \throw If \a fileName is not a writable file. + * \sa getVTKFileNameOf + */ +std::string MEDCouplingMesh::writeVTK(const std::string& fileName, bool isBinary) const +{ + std::string ret(getVTKFileNameOf(fileName)); + // + std::string cda,pda; + MEDCouplingAutoRefCountObjectPtr<DataArrayByte> byteArr; + if(isBinary) + { byteArr=DataArrayByte::New(); byteArr->alloc(0,1); } + writeVTKAdvanced(ret,cda,pda,byteArr); + return ret; +} + +/*! + * This method takes in input a file name \a fileName and considering the VTK extension of \a this (depending on the type of \a this) + * returns a right file name. If the input \a fileName has a valid extension the returned string is equal to \a fileName. + * + * \sa getVTKFileExtension + */ +std::string MEDCouplingMesh::getVTKFileNameOf(const std::string& fileName) const +{ + std::string ret; + std::string part0,part1; + SplitExtension(fileName,part0,part1); + std::string ext("."); ext+=getVTKFileExtension(); + if(part1==ext) + ret=fileName; + else + ret=fileName+ext; + return ret; +} + +void MEDCouplingMesh::writeVTKAdvanced(const std::string& fileName, const std::string& cda, const std::string& pda, DataArrayByte *byteData) const +{ + std::ofstream ofs(fileName.c_str()); + ofs << "<VTKFile type=\"" << getVTKDataSetType() << "\" version=\"0.1\" byte_order=\"" << MEDCouplingByteOrderStr() << "\">\n"; + writeVTKLL(ofs,cda,pda,byteData); + if(byteData) + { + ofs << "<AppendedData encoding=\"raw\">\n_1234"; + ofs << std::flush; ofs.close(); + std::ofstream ofs2(fileName.c_str(),std::ios_base::binary | std::ios_base::app); + ofs2.write(byteData->begin(),byteData->getNbOfElems()); ofs2 << std::flush; ofs2.close(); + std::ofstream ofs3(fileName.c_str(),std::ios_base::app); ofs3 << "\n</AppendedData>\n</VTKFile>\n"; ofs3.close(); + } + else + { + ofs << "</VTKFile>\n"; + ofs.close(); + } +} + +void MEDCouplingMesh::SplitExtension(const std::string& fileName, std::string& baseName, std::string& extension) +{ + std::size_t pos(fileName.find_last_of('.')); + if(pos==std::string::npos) + { + baseName=fileName; + extension.clear(); + return ; + } + baseName=fileName.substr(0,pos); + extension=fileName.substr(pos); +} diff --git a/src/medtool/src/MEDCoupling/MEDCouplingMesh.hxx b/src/medtool/src/MEDCoupling/MEDCouplingMesh.hxx new file mode 100644 index 000000000..b4a20e705 --- /dev/null +++ b/src/medtool/src/MEDCoupling/MEDCouplingMesh.hxx @@ -0,0 +1,172 @@ +// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 +// 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_MEDCOUPLINGMESH_HXX__ +#define __PARAMEDMEM_MEDCOUPLINGMESH_HXX__ + +#include "MEDCoupling.hxx" +#include "MEDCouplingTimeLabel.hxx" +#include "MEDCouplingRefCountObject.hxx" +#include "NormalizedUnstructuredMesh.hxx" +#include "MEDCouplingAutoRefCountObjectPtr.hxx" + +#include "InterpKernelException.hxx" + +#include <set> +#include <vector> + +namespace ParaMEDMEM +{ + typedef enum + { + UNSTRUCTURED = 5, + CARTESIAN = 7, + EXTRUDED = 8, + CURVE_LINEAR = 9, + SINGLE_STATIC_GEO_TYPE_UNSTRUCTURED = 10, + SINGLE_DYNAMIC_GEO_TYPE_UNSTRUCTURED = 11, + IMAGE_GRID = 12 + } MEDCouplingMeshType; + // -- WARNING this enum must be synchronized with MEDCouplingCommon.i file ! -- + + class DataArrayInt; + class DataArrayByte; + class DataArrayDouble; + class MEDCouplingUMesh; + class MEDCouplingFieldDouble; + + class MEDCouplingMesh : public RefCountObject, public TimeLabel + { + public: + MEDCOUPLING_EXPORT std::size_t getHeapMemorySizeWithoutChildren() const; + MEDCOUPLING_EXPORT void setName(const std::string& name) { _name=name; } + MEDCOUPLING_EXPORT std::string getName() const { return _name; } + MEDCOUPLING_EXPORT void setDescription(const std::string& descr) { _description=descr; } + MEDCOUPLING_EXPORT std::string getDescription() const { return _description; } + MEDCOUPLING_EXPORT double getTime(int& iteration, int& order) const { iteration=_iteration; order=_order; return _time; } + MEDCOUPLING_EXPORT void setTime(double val, int iteration, int order) { _time=val; _iteration=iteration; _order=order; } + MEDCOUPLING_EXPORT void setTimeUnit(const std::string& unit) { _time_unit=unit; } + MEDCOUPLING_EXPORT std::string getTimeUnit() const { return _time_unit; } + MEDCOUPLING_EXPORT virtual MEDCouplingMesh *deepCpy() const = 0; + MEDCOUPLING_EXPORT virtual MEDCouplingMeshType getType() const = 0; + MEDCOUPLING_EXPORT bool isStructured() const; + MEDCOUPLING_EXPORT virtual void copyTinyStringsFrom(const MEDCouplingMesh *other); + MEDCOUPLING_EXPORT virtual void copyTinyInfoFrom(const MEDCouplingMesh *other); + // comparison methods + MEDCOUPLING_EXPORT virtual bool isEqualIfNotWhy(const MEDCouplingMesh *other, double prec, std::string& reason) const; + MEDCOUPLING_EXPORT virtual bool isEqual(const MEDCouplingMesh *other, double prec) const; + MEDCOUPLING_EXPORT virtual bool isEqualWithoutConsideringStr(const MEDCouplingMesh *other, double prec) const = 0; + MEDCOUPLING_EXPORT virtual void checkDeepEquivalWith(const MEDCouplingMesh *other, int cellCompPol, double prec, + DataArrayInt *&cellCor, DataArrayInt *&nodeCor) const = 0; + MEDCOUPLING_EXPORT virtual void checkDeepEquivalOnSameNodesWith(const MEDCouplingMesh *other, int cellCompPol, double prec, + DataArrayInt *&cellCor) const = 0; + MEDCOUPLING_EXPORT virtual void checkFastEquivalWith(const MEDCouplingMesh *other, double prec) const; + MEDCOUPLING_EXPORT void checkGeoEquivalWith(const MEDCouplingMesh *other, int levOfCheck, double prec, + DataArrayInt *&cellCor, DataArrayInt *&nodeCor) const; + // + MEDCOUPLING_EXPORT virtual void checkCoherency() const = 0; + MEDCOUPLING_EXPORT virtual void checkCoherency1(double eps=1e-12) const = 0; + MEDCOUPLING_EXPORT virtual void checkCoherency2(double eps=1e-12) const = 0; + MEDCOUPLING_EXPORT virtual int getNumberOfCells() const = 0; + MEDCOUPLING_EXPORT virtual int getNumberOfNodes() const = 0; + MEDCOUPLING_EXPORT virtual int getSpaceDimension() const = 0; + MEDCOUPLING_EXPORT virtual int getMeshDimension() const = 0; + MEDCOUPLING_EXPORT virtual DataArrayDouble *getCoordinatesAndOwner() const = 0; + MEDCOUPLING_EXPORT virtual DataArrayDouble *getBarycenterAndOwner() const = 0; + MEDCOUPLING_EXPORT virtual DataArrayDouble *computeIsoBarycenterOfNodesPerCell() const = 0; + MEDCOUPLING_EXPORT virtual DataArrayInt *giveCellsWithType(INTERP_KERNEL::NormalizedCellType type) const = 0; + MEDCOUPLING_EXPORT virtual DataArrayInt *computeNbOfNodesPerCell() const = 0; + MEDCOUPLING_EXPORT virtual DataArrayInt *computeEffectiveNbOfNodesPerCell() const = 0; + MEDCOUPLING_EXPORT virtual DataArrayInt *computeNbOfFacesPerCell() const = 0; + MEDCOUPLING_EXPORT virtual int getNumberOfCellsWithType(INTERP_KERNEL::NormalizedCellType type) const = 0; + MEDCOUPLING_EXPORT virtual INTERP_KERNEL::NormalizedCellType getTypeOfCell(int cellId) const = 0; + MEDCOUPLING_EXPORT virtual std::set<INTERP_KERNEL::NormalizedCellType> getAllGeoTypes() const = 0; + MEDCOUPLING_EXPORT virtual void getNodeIdsOfCell(int cellId, std::vector<int>& conn) const = 0; + MEDCOUPLING_EXPORT virtual DataArrayInt *getCellIdsFullyIncludedInNodeIds(const int *partBg, const int *partEnd) const; + MEDCOUPLING_EXPORT virtual void getCoordinatesOfNode(int nodeId, std::vector<double>& coo) const = 0; + MEDCOUPLING_EXPORT virtual std::string simpleRepr() const = 0; + MEDCOUPLING_EXPORT virtual std::string advancedRepr() const = 0; + // tools + MEDCOUPLING_EXPORT virtual std::vector<int> getDistributionOfTypes() const = 0; + MEDCOUPLING_EXPORT virtual DataArrayInt *checkTypeConsistencyAndContig(const std::vector<int>& code, const std::vector<const DataArrayInt *>& idsPerType) const = 0; + MEDCOUPLING_EXPORT virtual void splitProfilePerType(const DataArrayInt *profile, std::vector<int>& code, std::vector<DataArrayInt *>& idsInPflPerType, std::vector<DataArrayInt *>& idsPerType) const = 0; + MEDCOUPLING_EXPORT virtual void getBoundingBox(double *bbox) const = 0; + MEDCOUPLING_EXPORT virtual MEDCouplingFieldDouble *getMeasureField(bool isAbs) const = 0; + MEDCOUPLING_EXPORT virtual MEDCouplingFieldDouble *getMeasureFieldOnNode(bool isAbs) const = 0; + MEDCOUPLING_EXPORT virtual int getCellContainingPoint(const double *pos, double eps) const = 0; + MEDCOUPLING_EXPORT virtual void getCellsContainingPoint(const double *pos, double eps, std::vector<int>& elts) const; + MEDCOUPLING_EXPORT virtual void getCellsContainingPoints(const double *pos, int nbOfPoints, double eps, MEDCouplingAutoRefCountObjectPtr<DataArrayInt>& elts, MEDCouplingAutoRefCountObjectPtr<DataArrayInt>& eltsIndex) const; + MEDCOUPLING_EXPORT virtual MEDCouplingFieldDouble *fillFromAnalytic(TypeOfField t, int nbOfComp, FunctionToEvaluate func) const; + MEDCOUPLING_EXPORT virtual MEDCouplingFieldDouble *fillFromAnalytic(TypeOfField t, int nbOfComp, const std::string& func) const; + MEDCOUPLING_EXPORT virtual MEDCouplingFieldDouble *fillFromAnalytic2(TypeOfField t, int nbOfComp, const std::string& func) const; + MEDCOUPLING_EXPORT virtual MEDCouplingFieldDouble *fillFromAnalytic3(TypeOfField t, int nbOfComp, const std::vector<std::string>& varsOrder, const std::string& func) const; + MEDCOUPLING_EXPORT virtual MEDCouplingFieldDouble *buildOrthogonalField() const = 0; + MEDCOUPLING_EXPORT virtual void rotate(const double *center, const double *vector, double angle) = 0; + MEDCOUPLING_EXPORT virtual void translate(const double *vector) = 0; + MEDCOUPLING_EXPORT virtual void scale(const double *point, double factor) = 0; + MEDCOUPLING_EXPORT virtual void renumberCells(const int *old2NewBg, bool check=true) = 0; + MEDCOUPLING_EXPORT virtual MEDCouplingMesh *mergeMyselfWith(const MEDCouplingMesh *other) const = 0; + MEDCOUPLING_EXPORT virtual MEDCouplingMesh *buildPart(const int *start, const int *end) const = 0; + MEDCOUPLING_EXPORT virtual MEDCouplingMesh *buildPartAndReduceNodes(const int *start, const int *end, DataArrayInt*& arr) const = 0; + MEDCOUPLING_EXPORT virtual MEDCouplingMesh *buildPartRange(int beginCellIds, int endCellIds, int stepCellIds) const; + MEDCOUPLING_EXPORT virtual MEDCouplingMesh *buildPartRangeAndReduceNodes(int beginCellIds, int endCellIds, int stepCellIds, int& beginOut, int& endOut, int& stepOut, DataArrayInt*& arr) const; + MEDCOUPLING_EXPORT virtual MEDCouplingUMesh *buildUnstructured() const = 0; + MEDCOUPLING_EXPORT virtual DataArrayInt *simplexize(int policy) = 0; + MEDCOUPLING_EXPORT virtual void getReverseNodalConnectivity(DataArrayInt *revNodal, DataArrayInt *revNodalIndx) const = 0; + MEDCOUPLING_EXPORT virtual bool areCompatibleForMerge(const MEDCouplingMesh *other) const; + MEDCOUPLING_EXPORT static MEDCouplingMesh *MergeMeshes(const MEDCouplingMesh *mesh1, const MEDCouplingMesh *mesh2); + MEDCOUPLING_EXPORT static MEDCouplingMesh *MergeMeshes(std::vector<const MEDCouplingMesh *>& meshes); + MEDCOUPLING_EXPORT static bool IsStaticGeometricType(INTERP_KERNEL::NormalizedCellType type); + MEDCOUPLING_EXPORT static bool IsLinearGeometricType(INTERP_KERNEL::NormalizedCellType type); + MEDCOUPLING_EXPORT static INTERP_KERNEL::NormalizedCellType GetCorrespondingPolyType(INTERP_KERNEL::NormalizedCellType type); + MEDCOUPLING_EXPORT static int GetNumberOfNodesOfGeometricType(INTERP_KERNEL::NormalizedCellType type); + MEDCOUPLING_EXPORT static int GetDimensionOfGeometricType(INTERP_KERNEL::NormalizedCellType type); + MEDCOUPLING_EXPORT static const char *GetReprOfGeometricType(INTERP_KERNEL::NormalizedCellType type); + //serialisation-unserialization + MEDCOUPLING_EXPORT virtual void getTinySerializationInformation(std::vector<double>& tinyInfoD, std::vector<int>& tinyInfo, std::vector<std::string>& littleStrings) const = 0; + MEDCOUPLING_EXPORT virtual void resizeForUnserialization(const std::vector<int>& tinyInfo, DataArrayInt *a1, DataArrayDouble *a2, std::vector<std::string>& littleStrings) const = 0; + MEDCOUPLING_EXPORT virtual void serialize(DataArrayInt *&a1, DataArrayDouble *&a2) const = 0; + MEDCOUPLING_EXPORT virtual void unserialization(const std::vector<double>& tinyInfoD, const std::vector<int>& tinyInfo, const DataArrayInt *a1, DataArrayDouble *a2, + const std::vector<std::string>& littleStrings) = 0; + MEDCOUPLING_EXPORT std::string writeVTK(const std::string& fileName, bool isBinary=true) const; + MEDCOUPLING_EXPORT std::string getVTKFileNameOf(const std::string& fileName) const; + MEDCOUPLING_EXPORT virtual std::string getVTKFileExtension() const = 0; + /// @cond INTERNAL + MEDCOUPLING_EXPORT void writeVTKAdvanced(const std::string& fileName, const std::string& cda, const std::string& pda, DataArrayByte *byteData) const; + MEDCOUPLING_EXPORT static void SplitExtension(const std::string& fileName, std::string& baseName, std::string& extension); + /// @endcond + MEDCOUPLING_EXPORT virtual void writeVTKLL(std::ostream& ofs, const std::string& cellData, const std::string& pointData, DataArrayByte *byteData) const = 0; + MEDCOUPLING_EXPORT virtual void reprQuickOverview(std::ostream& stream) const = 0; + protected: + MEDCOUPLING_EXPORT MEDCouplingMesh(); + MEDCOUPLING_EXPORT MEDCouplingMesh(const MEDCouplingMesh& other); + MEDCOUPLING_EXPORT virtual std::string getVTKDataSetType() const = 0; + MEDCOUPLING_EXPORT virtual ~MEDCouplingMesh() { } + private: + std::string _name; + std::string _description; + double _time; + int _iteration; + int _order; + std::string _time_unit; + }; +} + +#endif diff --git a/src/medtool/src/MEDCoupling/MEDCouplingMultiFields.cxx b/src/medtool/src/MEDCoupling/MEDCouplingMultiFields.cxx new file mode 100644 index 000000000..f493405d8 --- /dev/null +++ b/src/medtool/src/MEDCoupling/MEDCouplingMultiFields.cxx @@ -0,0 +1,460 @@ +// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 +// 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 "MEDCouplingMultiFields.hxx" +#include "MEDCouplingFieldTemplate.hxx" +#include "MEDCouplingFieldDouble.hxx" +#include "MEDCouplingMesh.hxx" +#include "MEDCouplingAutoRefCountObjectPtr.hxx" + +#include <sstream> +#include <algorithm> + +using namespace ParaMEDMEM; + +MEDCouplingMultiFields *MEDCouplingMultiFields::New(const std::vector<MEDCouplingFieldDouble *>& fs) +{ + return new MEDCouplingMultiFields(fs); +} + +MEDCouplingMultiFields *MEDCouplingMultiFields::New() +{ + return new MEDCouplingMultiFields; +} + +MEDCouplingMultiFields *MEDCouplingMultiFields::deepCpy() const +{ + return new MEDCouplingMultiFields(*this); +} + +bool MEDCouplingMultiFields::isEqual(const MEDCouplingMultiFields *other, double meshPrec, double valsPrec) const +{ + std::size_t sz=_fs.size(); + if(sz!=other->_fs.size()) + return false; + for(std::size_t i=0;i<sz;i++) + { + const MEDCouplingFieldDouble *f1=_fs[i]; + const MEDCouplingFieldDouble *f2=other->_fs[i]; + if(f1!=f2) + { + if(f1==0 || f2==0) + return false; + if(!_fs[i]->isEqual(other->_fs[i],meshPrec,valsPrec)) + return false; + } + } + std::vector<int> refs1,refs2; + std::vector<MEDCouplingMesh *> ms1=getDifferentMeshes(refs1); + std::vector<MEDCouplingMesh *> ms2=other->getDifferentMeshes(refs2); + if(ms1.size()!=ms2.size()) + return false; + if(refs1!=refs2) + return false; + std::vector< std::vector<int> > refs3,refs4; + std::vector<DataArrayDouble *> das1=getDifferentArrays(refs3); + std::vector<DataArrayDouble *> das2=getDifferentArrays(refs4); + if(das1.size()!=das2.size()) + return false; + if(refs3!=refs4) + return false; + return true; +} + +std::string MEDCouplingMultiFields::getName() const +{ + std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCouplingFieldDouble> >::const_iterator it=_fs.begin(); + for(;it!=_fs.end();it++) + if((const MEDCouplingFieldDouble *)(*it)) + return (*it)->getName(); + return std::string(); +} + +std::string MEDCouplingMultiFields::getDescription() const +{ + std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCouplingFieldDouble> >::const_iterator it=_fs.begin(); + for(;it!=_fs.end();it++) + if((const MEDCouplingFieldDouble *)(*it)) + return (*it)->getDescription(); + return std::string(); +} + +std::string MEDCouplingMultiFields::getTimeUnit() const +{ + std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCouplingFieldDouble> >::const_iterator it=_fs.begin(); + for(;it!=_fs.end();it++) + if((const MEDCouplingFieldDouble *)(*it)) + return (*it)->getTimeUnit(); + return std::string(); +} + +double MEDCouplingMultiFields::getTimeResolution() const +{ + std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCouplingFieldDouble> >::const_iterator it=_fs.begin(); + for(;it!=_fs.end();it++) + if((const MEDCouplingFieldDouble *)(*it)) + return (*it)->getTimeTolerance(); + throw INTERP_KERNEL::Exception("MEDCouplingMultiFields::getTimeResolution : no not null field !"); +} + +std::string MEDCouplingMultiFields::simpleRepr() const +{ + std::ostringstream ret; + ret << "MEDCouplingMultiFields with name : \"" << getName() << "\"\n"; + ret << "Description of MEDCouplingMultiFields is : \"" << getDescription() << "\"\n"; + ret << "Number of discretization : " << _fs.size() << "\n"; + ret << "Number of different meshes : "; + std::vector<MEDCouplingMesh *> ms; + std::vector<int> refms; + try + { + ms=getDifferentMeshes(refms); + ret << ms.size() << "\n"; + } + catch(INTERP_KERNEL::Exception& /*e*/) + { ret << "Current instance is INVALID !\n"; } + return ret.str(); +} + +std::string MEDCouplingMultiFields::advancedRepr() const +{ + return simpleRepr(); +} + +bool MEDCouplingMultiFields::isEqualWithoutConsideringStr(const MEDCouplingMultiFields *other, double meshPrec, double valsPrec) const +{ + std::size_t sz=_fs.size(); + if(sz!=other->_fs.size()) + return false; + for(std::size_t i=0;i<sz;i++) + if(!_fs[i]->isEqualWithoutConsideringStr(other->_fs[i],meshPrec,valsPrec)) + return false; + return true; +} + +const MEDCouplingFieldDouble *MEDCouplingMultiFields::getFieldWithId(int id) const +{ + if(id>=(int)_fs.size() || id < 0) + throw INTERP_KERNEL::Exception("MEDCouplingMultiFields::getFieldWithId : invalid id outside boundaries !"); + return _fs[id]; +} + +std::vector<const MEDCouplingFieldDouble *> MEDCouplingMultiFields::getFields() const +{ + std::vector<const MEDCouplingFieldDouble *> ret(_fs.size()); + std::copy(_fs.begin(),_fs.end(),ret.begin()); + return ret; +} + +int MEDCouplingMultiFields::getNumberOfFields() const +{ + return (int)_fs.size(); +} + +const MEDCouplingFieldDouble *MEDCouplingMultiFields::getFieldAtPos(int id) const +{ + if(id<0 || id>=(int)_fs.size()) + { + std::ostringstream oss; oss << "MEDCouplingMultiFields::getFieldAtPos : Invalid given pos : should be >=0 and < " << _fs.size() << " !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + return _fs[id]; +} + +void MEDCouplingMultiFields::updateTime() const +{ + std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCouplingFieldDouble> >::const_iterator it=_fs.begin(); + for(;it!=_fs.end();it++) + if((const MEDCouplingFieldDouble *)(*it)) + (*it)->updateTime(); + it=_fs.begin(); + for(;it!=_fs.end();it++) + if((const MEDCouplingFieldDouble *)(*it)) + updateTimeWith(*(*it)); +} + +std::size_t MEDCouplingMultiFields::getHeapMemorySizeWithoutChildren() const +{ + return 0; +} + +std::vector<const BigMemoryObject *> MEDCouplingMultiFields::getDirectChildrenWithNull() const +{ + std::vector<const BigMemoryObject *> ret; + for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCouplingFieldDouble> >::const_iterator it=_fs.begin();it!=_fs.end();it++) + ret.push_back((const MEDCouplingFieldDouble *)*it); + return ret; +} + +std::vector<MEDCouplingMesh *> MEDCouplingMultiFields::getMeshes() const +{ + std::vector<MEDCouplingMesh *> ms; + for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCouplingFieldDouble> >::const_iterator it=_fs.begin();it!=_fs.end();it++) + { + const MEDCouplingMesh *m=0; + if((const MEDCouplingFieldDouble *)(*it)) + m=(*it)->getMesh(); + ms.push_back(const_cast<MEDCouplingMesh *>(m)); + } + return ms; +} + +std::vector<MEDCouplingMesh *> MEDCouplingMultiFields::getDifferentMeshes(std::vector<int>& refs) const +{ + refs.resize(_fs.size()); + std::vector<MEDCouplingMesh *> ms; + int id=0; + for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCouplingFieldDouble> >::const_iterator it=_fs.begin();it!=_fs.end();it++,id++) + { + const MEDCouplingMesh *m=0; + if((const MEDCouplingFieldDouble *)(*it)) + m=(*it)->getMesh(); + if(m) + { + std::vector<MEDCouplingMesh *>::iterator it2=std::find(ms.begin(),ms.end(),m); + if(it2==ms.end()) + { + ms.push_back(const_cast<MEDCouplingMesh *>(m)); + refs[id]=(int)ms.size()-1; + } + else + refs[id]=(int)std::distance(ms.begin(),it2); + } + else + refs[id]=-1; + } + return ms; +} + +std::vector<DataArrayDouble *> MEDCouplingMultiFields::getArrays() const +{ + std::vector<DataArrayDouble *> tmp; + for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCouplingFieldDouble> >::const_iterator it=_fs.begin();it!=_fs.end();it++) + { + std::vector<DataArrayDouble *> tmp2=(*it)->getArrays(); + tmp.insert(tmp.end(),tmp2.begin(),tmp2.end()); + } + return tmp; +} + +std::vector<DataArrayDouble *> MEDCouplingMultiFields::getDifferentArrays(std::vector< std::vector<int> >& refs) const +{ + refs.resize(_fs.size()); + int id=0; + std::vector<DataArrayDouble *> ret; + for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCouplingFieldDouble> >::const_iterator it=_fs.begin();it!=_fs.end();it++,id++) + { + std::vector<DataArrayDouble *> tmp2; + if((const MEDCouplingFieldDouble *)(*it)) + { + tmp2=(*it)->getArrays(); + refs[id].resize(tmp2.size()); + } + else + refs[id].clear(); + int id2=0; + for(std::vector<DataArrayDouble *>::const_iterator it2=tmp2.begin();it2!=tmp2.end();it2++,id2++) + { + if(*it2) + { + std::vector<DataArrayDouble *>::iterator it3=std::find(ret.begin(),ret.end(),*it2); + if(it3==ret.end()) + { + ret.push_back(*it2); + refs[id][id2]=(int)ret.size()-1; + } + else + refs[id][id2]=(int)std::distance(ret.begin(),it3); + } + else + refs[id][id2]=-1; + } + } + return ret; +} + +void MEDCouplingMultiFields::checkCoherency() const +{ + std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCouplingFieldDouble> >::const_iterator it=_fs.begin(); + for(;it!=_fs.end();it++) + { + if((const MEDCouplingFieldDouble *)(*it)==0) + throw INTERP_KERNEL::Exception("MEDCouplingMultiFields::checkCoherency : There is an empty Field in array..."); + (*it)->checkCoherency(); + } +} + +MEDCouplingMultiFields::MEDCouplingMultiFields(const std::vector<MEDCouplingFieldDouble *>& fs):_fs(fs.size()) +{ + int id=0; + for(std::vector< MEDCouplingFieldDouble * >::const_iterator it=fs.begin();it!=fs.end();it++,id++) + { + if(*it) + (*it)->incrRef(); + else + throw INTERP_KERNEL::Exception("MEDCouplingMultiFields constructor : empty field found in vector !"); + (*it)->checkCoherency(); + _fs[id]=*it; + } +} + + +/*! + * Performs deepCpy. + */ +MEDCouplingMultiFields::MEDCouplingMultiFields(const MEDCouplingMultiFields& other):RefCountObject(other) +{ + std::size_t sz=other._fs.size(); + _fs.resize(sz); + std::vector<int> refs; + std::vector< std::vector<int> > refs2; + std::vector<MEDCouplingMesh *> ms=other.getDifferentMeshes(refs); + std::size_t msLgh=ms.size(); + std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCouplingMesh> > ms2(msLgh); + for(std::size_t i=0;i<msLgh;i++) + ms2[i]=ms[i]->deepCpy(); + std::vector<DataArrayDouble *> das=other.getDifferentArrays(refs2); + std::size_t dasLgth=das.size(); + std::vector< MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> > das2(dasLgth); + for(std::size_t i=0;i<dasLgth;i++) + das2[i]=das[i]->deepCpy(); + for(std::size_t i=0;i<sz;i++) + { + if((const MEDCouplingFieldDouble *)other._fs[i]) + { + 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]]); + std::size_t nbOfArr=refs2[i].size(); + std::vector<DataArrayDouble *> tmp2(nbOfArr); + for(std::size_t j=0;j<nbOfArr;j++) + { + if(refs2[i][j]!=-1) + tmp2[j]=das2[refs2[i][j]]; + else + tmp2[j]=0; + } + _fs[i]->setArrays(tmp2); + std::vector<int> tinyInfo; + std::vector<double> tinyInfo2; + other._fs[i]->getTimeDiscretizationUnderGround()->getTinySerializationIntInformation2(tinyInfo); + other._fs[i]->getTimeDiscretizationUnderGround()->getTinySerializationDbleInformation2(tinyInfo2); + _fs[i]->getTimeDiscretizationUnderGround()->finishUnserialization2(tinyInfo,tinyInfo2); + } + } +} + +MEDCouplingMultiFields::MEDCouplingMultiFields() +{ +} + +void MEDCouplingMultiFields::getTinySerializationInformation(std::vector<int>& tinyInfo, std::vector<double>& tinyInfo2, int& nbOfDiffMeshes, int& nbOfDiffArr) const +{ + std::vector<int> refs; + std::vector<MEDCouplingMesh *> ms=getDifferentMeshes(refs); + nbOfDiffMeshes=(int)ms.size(); + std::vector< std::vector<int> > refs2; + std::vector<DataArrayDouble *> fs=getDifferentArrays(refs2); + nbOfDiffArr=(int)fs.size(); + // + std::size_t sz=refs.size();//==_fs.size() + int sz2=0; + for(std::size_t i=0;i<sz;i++) + sz2+=(int)refs2[i].size(); + // + tinyInfo2.clear(); + std::vector<int> doubleDaInd(sz); + std::vector<int> timeDiscrInt; + tinyInfo.resize(sz2+5*sz+3); + tinyInfo[0]=(int)sz; + tinyInfo[1]=sz2; + for(std::size_t i=0;i<sz;i++) + { + std::vector<double> tmp; + std::vector<int> tmp2; + _fs[i]->getTimeDiscretizationUnderGround()->getTinySerializationDbleInformation2(tmp); + _fs[i]->getTimeDiscretizationUnderGround()->getTinySerializationIntInformation2(tmp2); + tinyInfo[3*sz+3+i]=(int)tmp.size(); + tinyInfo[4*sz+3+i]=(int)tmp2.size(); + tinyInfo2.insert(tinyInfo2.end(),tmp.begin(),tmp.end()); + timeDiscrInt.insert(timeDiscrInt.end(),tmp2.begin(),tmp2.end()); + } + int sz3=(int)timeDiscrInt.size(); + tinyInfo[2]=sz3; + // + for(std::size_t i=0;i<sz;i++) + tinyInfo[i+3]=refs[i]; + for(std::size_t i=0;i<sz;i++) + tinyInfo[i+sz+3]=(int)refs2[i].size(); + for(std::size_t i=0;i<sz;i++) + tinyInfo[i+2*sz+3]=(int)_fs[i]->getTimeDiscretization(); + int k=0; + for(std::size_t i=0;i<sz;i++) + for(std::vector<int>::const_iterator it=refs2[i].begin();it!=refs2[i].end();it++,k++) + tinyInfo[5*sz+k+3]=*it; + tinyInfo.insert(tinyInfo.end(),timeDiscrInt.begin(),timeDiscrInt.end());//tinyInfo has lgth==sz3+sz2+5*sz+3 +} + +void MEDCouplingMultiFields::finishUnserialization(const std::vector<int>& tinyInfoI, const std::vector<double>& tinyInfoD, + const std::vector<MEDCouplingFieldTemplate *>& ft, const std::vector<MEDCouplingMesh *>& ms, + const std::vector<DataArrayDouble *>& das) +{ + int sz=tinyInfoI[0]; + _fs.resize(sz); + int sz2=tinyInfoI[1]; + // dealing with ft with no mesh set. + for(int i=0;i<sz;i++) + { + int meshId=tinyInfoI[3+i]; + if(meshId!=-1) + ft[i]->setMesh(ms[meshId]); + } + // dealing with fieldtemplate->fielddouble + int k=0; + int offI=0; + int offD=0; + for(int i=0;i<sz;i++) + { + _fs[i]=MEDCouplingFieldDouble::New(*ft[i],(TypeOfTimeDiscretization)tinyInfoI[2*sz+3+i]); + int sz3=tinyInfoI[sz+i+3]; + std::vector<DataArrayDouble *> tmp(sz3); + for(int j=0;j<sz3;j++,k++) + { + int daId=tinyInfoI[5*sz+k+3]; + if(daId!=-1) + tmp[j]=das[daId]; + else + tmp[j]=0; + } + _fs[i]->setArrays(tmp); + // time discr tiny info + int lgthI=tinyInfoI[4*sz+3+i]; + int lgthD=tinyInfoI[3*sz+3+i]; + // + std::vector<int> tdInfoI(tinyInfoI.begin()+sz2+5*sz+3+offI,tinyInfoI.begin()+sz2+5*sz+3+offI+lgthI); + std::vector<double> tdInfoD(tinyInfoD.begin()+offD,tinyInfoD.begin()+offD+lgthD); + _fs[i]->getTimeDiscretizationUnderGround()->finishUnserialization2(tdInfoI,tdInfoD); + // + offI+=lgthI; + offD+=lgthD; + } +} diff --git a/src/medtool/src/MEDCoupling/MEDCouplingMultiFields.hxx b/src/medtool/src/MEDCoupling/MEDCouplingMultiFields.hxx new file mode 100644 index 000000000..b092bc60d --- /dev/null +++ b/src/medtool/src/MEDCoupling/MEDCouplingMultiFields.hxx @@ -0,0 +1,79 @@ +// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 +// 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_MEDCOUPLINGMULTIFIELDS_HXX__ +#define __PARAMEDMEM_MEDCOUPLINGMULTIFIELDS_HXX__ + +#include "MEDCouplingRefCountObject.hxx" +#include "MEDCouplingTimeLabel.hxx" +#include "MEDCouplingAutoRefCountObjectPtr.hxx" + +#include "InterpKernelException.hxx" + +#include <vector> + +namespace ParaMEDMEM +{ + class MEDCouplingMesh; + class DataArrayDouble; + class MEDCouplingFieldDouble; + class MEDCouplingFieldTemplate; + + class MEDCouplingMultiFields : public RefCountObject, public TimeLabel + { + public: + MEDCOUPLING_EXPORT static MEDCouplingMultiFields *New(const std::vector<MEDCouplingFieldDouble *>& fs); + MEDCOUPLING_EXPORT static MEDCouplingMultiFields *New(); + MEDCOUPLING_EXPORT MEDCouplingMultiFields *deepCpy() const; + MEDCOUPLING_EXPORT std::string getName() const; + MEDCOUPLING_EXPORT std::string getDescription() const; + MEDCOUPLING_EXPORT std::string getTimeUnit() const; + MEDCOUPLING_EXPORT double getTimeResolution() const; + MEDCOUPLING_EXPORT virtual std::string simpleRepr() const; + MEDCOUPLING_EXPORT virtual std::string advancedRepr() const; + MEDCOUPLING_EXPORT virtual bool isEqual(const MEDCouplingMultiFields *other, double meshPrec, double valsPrec) const; + MEDCOUPLING_EXPORT virtual bool isEqualWithoutConsideringStr(const MEDCouplingMultiFields *other, double meshPrec, double valsPrec) const; + MEDCOUPLING_EXPORT const MEDCouplingFieldDouble *getFieldWithId(int id) const; + MEDCOUPLING_EXPORT std::vector<const MEDCouplingFieldDouble *> getFields() const; + MEDCOUPLING_EXPORT int getNumberOfFields() const; + MEDCOUPLING_EXPORT const MEDCouplingFieldDouble *getFieldAtPos(int id) const; + MEDCOUPLING_EXPORT virtual std::vector<MEDCouplingMesh *> getMeshes() const; + MEDCOUPLING_EXPORT virtual std::vector<MEDCouplingMesh *> getDifferentMeshes(std::vector<int>& refs) const; + MEDCOUPLING_EXPORT virtual std::vector<DataArrayDouble *> getArrays() const; + MEDCOUPLING_EXPORT virtual std::vector<DataArrayDouble *> getDifferentArrays(std::vector< std::vector<int> >& refs) const; + MEDCOUPLING_EXPORT void updateTime() const; + MEDCOUPLING_EXPORT std::size_t getHeapMemorySizeWithoutChildren() const; + MEDCOUPLING_EXPORT std::vector<const BigMemoryObject *> getDirectChildrenWithNull() const; + MEDCOUPLING_EXPORT void getTinySerializationInformation(std::vector<int>& tinyInfo, std::vector<double>& tinyInfo2, int& nbOfDiffMeshes, int& nbOfDiffArr) const; + MEDCOUPLING_EXPORT void finishUnserialization(const std::vector<int>& tinyInfoI, const std::vector<double>& tinyInfoD, + const std::vector<MEDCouplingFieldTemplate *>& ft, const std::vector<MEDCouplingMesh *>& ms, + const std::vector<DataArrayDouble *>& das); + MEDCOUPLING_EXPORT virtual void checkCoherency() const; + protected: + MEDCOUPLING_EXPORT MEDCouplingMultiFields(const std::vector<MEDCouplingFieldDouble *>& fs); + MEDCOUPLING_EXPORT MEDCouplingMultiFields(const MEDCouplingMultiFields& other); + MEDCOUPLING_EXPORT MEDCouplingMultiFields(); + protected: + std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCouplingFieldDouble> > _fs; + }; +} + +#endif + diff --git a/src/medtool/src/MEDCoupling/MEDCouplingNatureOfField.cxx b/src/medtool/src/MEDCoupling/MEDCouplingNatureOfField.cxx new file mode 100644 index 000000000..26f05c670 --- /dev/null +++ b/src/medtool/src/MEDCoupling/MEDCouplingNatureOfField.cxx @@ -0,0 +1,70 @@ +// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 +// 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 "MEDCouplingNatureOfField.hxx" + +#include <algorithm> +#include <sstream> + +namespace ParaMEDMEM +{ + const char *MEDCouplingNatureOfField::REPR_OF_NATUREOFFIELD[NB_OF_POSSIBILITIES]= + { "NoNature", + "ConservativeVolumic", + "Integral", + "IntegralGlobConstraint", + "RevIntegral"}; + + const int MEDCouplingNatureOfField::POS_OF_NATUREOFFIELD[NB_OF_POSSIBILITIES]={17,26,32,35,37}; + + const char *MEDCouplingNatureOfField::GetRepr(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) + { + 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<NB_OF_POSSIBILITIES;i++) + { + oss << REPR_OF_NATUREOFFIELD[i] << "(value=" << POS_OF_NATUREOFFIELD[i] << ")"; + if(i!=NB_OF_POSSIBILITIES-1) + oss << ", "; + } + return oss.str(); + } +} diff --git a/src/medtool/src/MEDCoupling/MEDCouplingNatureOfField.hxx b/src/medtool/src/MEDCoupling/MEDCouplingNatureOfField.hxx new file mode 100644 index 000000000..6c1b32ec9 --- /dev/null +++ b/src/medtool/src/MEDCoupling/MEDCouplingNatureOfField.hxx @@ -0,0 +1,44 @@ +// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 +// 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_MEDCOUPLINGNATUREOFFIELD_HXX__ +#define __PARAMEDMEM_MEDCOUPLINGNATUREOFFIELD_HXX__ + +#include "MEDCoupling.hxx" +#include "MEDCouplingNatureOfFieldEnum" + +#include "InterpKernelException.hxx" + +namespace ParaMEDMEM +{ + class MEDCouplingNatureOfField + { + public: + MEDCOUPLING_EXPORT static const char *GetRepr(NatureOfField nat); + MEDCOUPLING_EXPORT static std::string GetReprNoThrow(NatureOfField nat); + MEDCOUPLING_EXPORT static std::string GetAllPossibilitiesStr(); + private: + static const int NB_OF_POSSIBILITIES=5; + static const char *REPR_OF_NATUREOFFIELD[NB_OF_POSSIBILITIES]; + static const int POS_OF_NATUREOFFIELD[NB_OF_POSSIBILITIES]; + }; +} + +#endif diff --git a/src/medtool/src/MEDCoupling/MEDCouplingNatureOfFieldEnum b/src/medtool/src/MEDCoupling/MEDCouplingNatureOfFieldEnum new file mode 100644 index 000000000..c06799db6 --- /dev/null +++ b/src/medtool/src/MEDCoupling/MEDCouplingNatureOfFieldEnum @@ -0,0 +1,36 @@ +// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 +// 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_MEDCOUPLINGNATUREOFFIELDENUM__ +#define __PARAMEDMEM_MEDCOUPLINGNATUREOFFIELDENUM__ + +namespace ParaMEDMEM +{ + typedef enum + { + NoNature = 17, + ConservativeVolumic = 26, + Integral = 32, + IntegralGlobConstraint = 35, + RevIntegral = 37 + } NatureOfField; +} + +#endif diff --git a/src/medtool/src/MEDCoupling/MEDCouplingNormalizedCartesianMesh.hxx b/src/medtool/src/MEDCoupling/MEDCouplingNormalizedCartesianMesh.hxx new file mode 100644 index 000000000..529f439f8 --- /dev/null +++ b/src/medtool/src/MEDCoupling/MEDCouplingNormalizedCartesianMesh.hxx @@ -0,0 +1,53 @@ +// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 +// 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_MEDCOUPLINGNORMALIZEDCARTESIANMESH_HXX__ +#define __PARAMEDMEM_MEDCOUPLINGNORMALIZEDCARTESIANMESH_HXX__ + +#include "NormalizedUnstructuredMesh.hxx" + +namespace ParaMEDMEM +{ + class MEDCouplingCMesh; +} + +template<int SPACEDIM> +class MEDCouplingNormalizedCartesianMesh +{ +public: + static const int MY_SPACEDIM=SPACEDIM; + static const int MY_MESHDIM=SPACEDIM; + typedef int MyConnType; + static const INTERP_KERNEL::NumberingPolicy My_numPol=INTERP_KERNEL::ALL_C_MODE; +public: + MEDCouplingNormalizedCartesianMesh(const ParaMEDMEM::MEDCouplingCMesh *mesh); + //void getBoundingBox(double *boundingBox) const; + //INTERP_KERNEL::NormalizedCellType getTypeOfElement(int eltId) const; + //int getNumberOfNodesOfElement(int eltId) const; + //int getNumberOfNodes() const; + unsigned long getNumberOfElements() const; + unsigned long nbCellsAlongAxis(int axis) const; + const double * getCoordsAlongAxis(int axis) const; + ~MEDCouplingNormalizedCartesianMesh(); +private: + const ParaMEDMEM::MEDCouplingCMesh *_mesh; +}; + +#endif diff --git a/src/medtool/src/MEDCoupling/MEDCouplingNormalizedCartesianMesh.txx b/src/medtool/src/MEDCoupling/MEDCouplingNormalizedCartesianMesh.txx new file mode 100644 index 000000000..2fe1f85c1 --- /dev/null +++ b/src/medtool/src/MEDCoupling/MEDCouplingNormalizedCartesianMesh.txx @@ -0,0 +1,57 @@ +// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 +// 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 +// +// File : MEDCouplingNormalizedCartesianMesh.txx +// Created : Mon Aug 17 12:00:38 2009 +// Author : Edward AGAPOV (eap) +// + +#include "MEDCouplingNormalizedCartesianMesh.hxx" +#include "MEDCouplingCMesh.hxx" + +template<int SPACEDIM> +MEDCouplingNormalizedCartesianMesh<SPACEDIM>::MEDCouplingNormalizedCartesianMesh(const ParaMEDMEM::MEDCouplingCMesh *mesh):_mesh(mesh) +{ + if(_mesh) + _mesh->incrRef(); +} + +template<int SPACEDIM> +MEDCouplingNormalizedCartesianMesh<SPACEDIM>::~MEDCouplingNormalizedCartesianMesh() +{ + if(_mesh) + _mesh->decrRef(); +} + +template<int SPACEDIM> +unsigned long MEDCouplingNormalizedCartesianMesh<SPACEDIM>::getNumberOfElements() const +{ + return _mesh->getNumberOfCells(); +} + +template<int SPACEDIM> +unsigned long MEDCouplingNormalizedCartesianMesh<SPACEDIM>::nbCellsAlongAxis(int axis) const +{ + return _mesh->getCoordsAt(axis)->getNumberOfTuples() - 1; +} + +template<int SPACEDIM> +const double * MEDCouplingNormalizedCartesianMesh<SPACEDIM>::getCoordsAlongAxis(int axis) const +{ + return _mesh->getCoordsAt(axis)->getConstPointer(); +} diff --git a/src/medtool/src/MEDCoupling/MEDCouplingNormalizedUnstructuredMesh.hxx b/src/medtool/src/MEDCoupling/MEDCouplingNormalizedUnstructuredMesh.hxx new file mode 100644 index 000000000..d3e8ce6b3 --- /dev/null +++ b/src/medtool/src/MEDCoupling/MEDCouplingNormalizedUnstructuredMesh.hxx @@ -0,0 +1,59 @@ +// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 +// 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_MEDCOUPLINGNORMALIZEDUNSTRUCTUREDMESH_HXX__ +#define __PARAMEDMEM_MEDCOUPLINGNORMALIZEDUNSTRUCTUREDMESH_HXX__ + +#include "NormalizedUnstructuredMesh.hxx" + +namespace ParaMEDMEM +{ + class MEDCouplingPointSet; +} + +template<int SPACEDIM,int MESHDIM> +class MEDCouplingNormalizedUnstructuredMesh +{ +public: + static const int MY_SPACEDIM=SPACEDIM; + static const int MY_MESHDIM=MESHDIM; + typedef int MyConnType; + static const INTERP_KERNEL::NumberingPolicy My_numPol=INTERP_KERNEL::ALL_C_MODE; +public: + MEDCouplingNormalizedUnstructuredMesh(const ParaMEDMEM::MEDCouplingPointSet *mesh); + void getBoundingBox(double *boundingBox) const; + INTERP_KERNEL::NormalizedCellType getTypeOfElement(int eltId) const; + int getNumberOfNodesOfElement(int eltId) const; + int getNumberOfElements() const; + int getNumberOfNodes() const; + const int *getConnectivityPtr() const; + const double *getCoordinatesPtr() const; + const int *getConnectivityIndexPtr() const; + void releaseTempArrays(); + ~MEDCouplingNormalizedUnstructuredMesh(); +private: + void prepare(); +private: + const ParaMEDMEM::MEDCouplingPointSet *_mesh; + int *_conn_for_interp; + int *_conn_index_for_interp; +}; + +#endif diff --git a/src/medtool/src/MEDCoupling/MEDCouplingNormalizedUnstructuredMesh.txx b/src/medtool/src/MEDCoupling/MEDCouplingNormalizedUnstructuredMesh.txx new file mode 100644 index 000000000..5e8cfb985 --- /dev/null +++ b/src/medtool/src/MEDCoupling/MEDCouplingNormalizedUnstructuredMesh.txx @@ -0,0 +1,176 @@ +// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 +// 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 __MEDCOUPLINGNORMALIZEDUNSTRUCTUREDMESH_TXX__ +#define __MEDCOUPLINGNORMALIZEDUNSTRUCTUREDMESH_TXX__ + +#include "MEDCouplingNormalizedUnstructuredMesh.hxx" + +#include "MEDCouplingUMesh.hxx" +#include "MEDCoupling1GTUMesh.hxx" +#include "MEDCouplingMemArray.hxx" + +#include <limits> + +template<int SPACEDIM,int MESHDIM> +MEDCouplingNormalizedUnstructuredMesh<SPACEDIM,MESHDIM>::MEDCouplingNormalizedUnstructuredMesh(const ParaMEDMEM::MEDCouplingPointSet *mesh):_mesh(mesh) +{ + if(_mesh) + _mesh->incrRef(); + prepare(); +} + +template<int SPACEDIM,int MESHDIM> +void MEDCouplingNormalizedUnstructuredMesh<SPACEDIM,MESHDIM>::getBoundingBox(double *boundingBox) const +{ + for(int i=0;i<SPACEDIM;i++) + { + boundingBox[i]=std::numeric_limits<double>::max(); + boundingBox[SPACEDIM+i]=-std::numeric_limits<double>::max(); + } + const ParaMEDMEM::DataArrayDouble *array=_mesh->getCoords(); + const double *ptr=array->getConstPointer(); + int nbOfPts=array->getNbOfElems()/SPACEDIM; + for(int j=0;j<SPACEDIM;j++) + { + const double *work=ptr+j; + for(int i=0;i<nbOfPts;i++,work+=SPACEDIM) + { + if(boundingBox[j]>*work) + boundingBox[j]=*work; + if(boundingBox[j+SPACEDIM]<*work) + boundingBox[j+SPACEDIM]=*work; + } + } +} + +template<int SPACEDIM,int MESHDIM> +INTERP_KERNEL::NormalizedCellType MEDCouplingNormalizedUnstructuredMesh<SPACEDIM,MESHDIM>::getTypeOfElement(int eltId) const +{ + return _mesh->getTypeOfCell(eltId); +} + +template<int SPACEDIM,int MESHDIM> +int MEDCouplingNormalizedUnstructuredMesh<SPACEDIM,MESHDIM>::getNumberOfNodesOfElement(int eltId) const +{ + return _mesh->getNumberOfNodesInCell(eltId); +} + +template<int SPACEDIM,int MESHDIM> +int MEDCouplingNormalizedUnstructuredMesh<SPACEDIM,MESHDIM>::getNumberOfElements() const +{ + return _mesh->getNumberOfCells(); +} + +template<int SPACEDIM,int MESHDIM> +int MEDCouplingNormalizedUnstructuredMesh<SPACEDIM,MESHDIM>::getNumberOfNodes() const +{ + return _mesh->getNumberOfNodes(); +} + +template<int SPACEDIM,int MESHDIM> +const int *MEDCouplingNormalizedUnstructuredMesh<SPACEDIM,MESHDIM>::getConnectivityPtr() const +{ + return _conn_for_interp; +} + +template<int SPACEDIM,int MESHDIM> +const double *MEDCouplingNormalizedUnstructuredMesh<SPACEDIM,MESHDIM>::getCoordinatesPtr() const +{ + const ParaMEDMEM::DataArrayDouble *array=_mesh->getCoords(); + return array->getConstPointer(); +} + +template<int SPACEDIM,int MESHDIM> +const int *MEDCouplingNormalizedUnstructuredMesh<SPACEDIM,MESHDIM>::getConnectivityIndexPtr() const +{ + return _conn_index_for_interp; +} + +template<int SPACEDIM,int MESHDIM> +void MEDCouplingNormalizedUnstructuredMesh<SPACEDIM,MESHDIM>::releaseTempArrays() +{ + delete [] _conn_for_interp; + delete [] _conn_index_for_interp; + _conn_for_interp=0; + _conn_index_for_interp=0; +} + +template<int SPACEDIM,int MESHDIM> +MEDCouplingNormalizedUnstructuredMesh<SPACEDIM,MESHDIM>::~MEDCouplingNormalizedUnstructuredMesh() +{ + if(_mesh) + _mesh->decrRef(); + releaseTempArrays(); +} + +template<int SPACEDIM,int MESHDIM> +void MEDCouplingNormalizedUnstructuredMesh<SPACEDIM,MESHDIM>::prepare() +{ + const ParaMEDMEM::MEDCouplingUMesh *m1(dynamic_cast<const ParaMEDMEM::MEDCouplingUMesh *>(_mesh)); + if(m1) + { + int nbOfCell=m1->getNumberOfCells(); + int initialConnSize=m1->getNodalConnectivity()->getNbOfElems(); + _conn_for_interp=new int[initialConnSize-nbOfCell]; + _conn_index_for_interp=new int[nbOfCell+1]; + _conn_index_for_interp[0]=0; + const int *work_conn=m1->getNodalConnectivity()->getConstPointer()+1; + const int *work_conn_index=m1->getNodalConnectivityIndex()->getConstPointer(); + int *work_conn_for_interp=_conn_for_interp; + int *work_conn_index_for_interp=_conn_index_for_interp; + for(int i=0;i<nbOfCell;i++) + { + int nbOfValsToCopy=work_conn_index[1]-work_conn_index[0]-1; + work_conn_for_interp=std::copy(work_conn,work_conn+nbOfValsToCopy,work_conn_for_interp); + work_conn_index_for_interp[1]=work_conn_index_for_interp[0]+nbOfValsToCopy; + work_conn_index++; + work_conn+=nbOfValsToCopy+1; + work_conn_index_for_interp++; + } + return ; + } + const ParaMEDMEM::MEDCoupling1DGTUMesh *m2(dynamic_cast<const ParaMEDMEM::MEDCoupling1DGTUMesh *>(_mesh)); + if(m2) + { + int nbOfCell(m2->getNumberOfCells()); + _conn_index_for_interp=new int[nbOfCell+1]; + const int *conni(m2->getNodalConnectivityIndex()->begin()); + std::copy(conni,conni+nbOfCell+1,_conn_index_for_interp); + _conn_for_interp=new int[m2->getNodalConnectivity()->getNumberOfTuples()]; + std::copy(m2->getNodalConnectivity()->begin(),m2->getNodalConnectivity()->end(),_conn_for_interp); + return ; + } + const ParaMEDMEM::MEDCoupling1SGTUMesh *m3(dynamic_cast<const ParaMEDMEM::MEDCoupling1SGTUMesh *>(_mesh)); + if(m3) + { + int nbOfCell(m3->getNumberOfCells()),nbNodesPerCell(m3->getNumberOfNodesPerCell()); + _conn_index_for_interp=new int[nbOfCell+1]; _conn_index_for_interp[0]=0; + int *work(_conn_index_for_interp); + for(int i=0;i<nbOfCell;i++,work++) + work[1]=work[0]+nbNodesPerCell; + _conn_for_interp=new int[m3->getNodalConnectivity()->getNumberOfTuples()]; + std::copy(m3->getNodalConnectivity()->begin(),m3->getNodalConnectivity()->end(),_conn_for_interp); + return ; + } + throw INTERP_KERNEL::Exception("MEDCouplingNormalizedUnstructuredMesh::prepare : Unrecognized unstructured mesh ! Type must be in MEDCouplingUMesh, MEDCoupling1DGTUMesh, MEDCoupling1SGTUMesh !"); +} + +#endif diff --git a/src/medtool/src/MEDCoupling/MEDCouplingPartDefinition.cxx b/src/medtool/src/MEDCoupling/MEDCouplingPartDefinition.cxx new file mode 100644 index 000000000..7523d938b --- /dev/null +++ b/src/medtool/src/MEDCoupling/MEDCouplingPartDefinition.cxx @@ -0,0 +1,419 @@ +// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 +// 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 (EDF R&D) + +#include "MEDCouplingPartDefinition.hxx" + +using namespace ParaMEDMEM; + +PartDefinition *PartDefinition::New(int start, int stop, int step) +{ + return SlicePartDefinition::New(start,stop,step); +} + +PartDefinition *PartDefinition::New(DataArrayInt *listOfIds) +{ + return DataArrayPartDefinition::New(listOfIds); +} + +PartDefinition *PartDefinition::Unserialize(std::vector<int>& tinyInt, std::vector< MEDCouplingAutoRefCountObjectPtr<DataArrayInt> >& bigArraysI) +{ + if(tinyInt.empty()) + { + MEDCouplingAutoRefCountObjectPtr<PartDefinition> ret(DataArrayPartDefinition::New(bigArraysI.back())); + bigArraysI.pop_back(); + return ret.retn(); + } + else if(tinyInt.size()==3) + { + MEDCouplingAutoRefCountObjectPtr<PartDefinition> ret(SlicePartDefinition::New(tinyInt[0],tinyInt[1],tinyInt[2])); + tinyInt.erase(tinyInt.begin(),tinyInt.begin()+3); + return ret.retn(); + } + else + throw INTERP_KERNEL::Exception("PartDefinition::Unserialize"); +} + +PartDefinition::~PartDefinition() +{ +} + +DataArrayPartDefinition *DataArrayPartDefinition::New(DataArrayInt *listOfIds) +{ + return new DataArrayPartDefinition(listOfIds); +} + +bool DataArrayPartDefinition::isEqual(const PartDefinition *other, std::string& what) const +{ + if(!other) + { + what="DataArrayPartDefinition::isEqual : other is null, this is not null !"; + return false; + } + const DataArrayPartDefinition *otherC(dynamic_cast<const DataArrayPartDefinition *>(other)); + if(!otherC) + { + what="DataArrayPartDefinition::isEqual : other is not DataArrayPartDefinition !"; + return false; + } + const DataArrayInt *arr0(_arr),*arr1(otherC->_arr); + if(!arr0 && !arr1) + return true; + if((arr0 && !arr1) || (!arr0 && arr1)) + { + what="DataArrayPartDefinition::isEqual : array is not defined both in other and this !"; + return false; + } + std::string what1; + bool ret(arr0->isEqualIfNotWhy(*arr1,what1)); + if(!ret) + { + what=std::string("DataArrayPartDefinition::isEqual : arrays are not equal :\n")+what1; + return false; + } + return true; +} + +DataArrayPartDefinition *DataArrayPartDefinition::deepCpy() const +{ + const DataArrayInt *arr(_arr); + if(!arr) + throw INTERP_KERNEL::Exception("DataArrayPartDefinition::deepCpy : array is null !"); + return DataArrayPartDefinition::New(const_cast<DataArrayInt *>(arr)); +} + +int DataArrayPartDefinition::getNumberOfElems() const +{ + checkInternalArrayOK(); + return _arr->getNumberOfTuples(); +} + +PartDefinition *DataArrayPartDefinition::operator+(const PartDefinition& other) const +{ + const PartDefinition *otherPt(&other); + if(!otherPt) + throw INTERP_KERNEL::Exception("DataArrayPartDefinition::operator+ : NULL input !"); + const DataArrayPartDefinition *other1(dynamic_cast<const DataArrayPartDefinition *>(otherPt)); + if(other1) + return add1(other1); + const SlicePartDefinition *other2(dynamic_cast<const SlicePartDefinition *>(otherPt)); + if(other2) + return add2(other2); + throw INTERP_KERNEL::Exception("DataArrayPartDefinition::operator+ : unrecognized type in input !"); +} + +std::string DataArrayPartDefinition::getRepr() const +{ + std::ostringstream oss; oss << "DataArray Part : "; + const DataArrayInt *arr(_arr); + if(arr) + arr->reprQuickOverview(oss); + else + oss << "No Data !"; + return oss.str(); +} + +/*! + * This method operates FoG where F is \a this and G is \a other. + * Example : if \a other is SlicePart(4,14,1) and if \a this is DataArrayPartDefinition([0,1,2,3,6,7,8,9]) -> DataArrayPartDefinition([4,5,6,7,11,12,13]) will be returned + */ +PartDefinition *DataArrayPartDefinition::composeWith(const PartDefinition *other) const +{ + if(!other) + throw INTERP_KERNEL::Exception("DataArrayPartDefinition::composeWith : input PartDef must be not NULL !"); + checkCoherency(); + other->checkCoherency(); + const SlicePartDefinition *spd(dynamic_cast<const SlicePartDefinition *>(other)); + if(spd) + {//special case for optim + int a(0),b(0),c(0); + spd->getSlice(a,b,c); + if(c==1) + { + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> arr(DataArrayInt::New()); + arr->alloc(_arr->getNumberOfTuples(),1); + std::transform(_arr->begin(),_arr->end(),arr->getPointer(),std::bind2nd(std::plus<int>(),a)); + return DataArrayPartDefinition::New(arr); + } + } + // + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> arr1(other->toDAI()); + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> arr2(arr1->selectByTupleIdSafe(_arr->begin(),_arr->end())); + return DataArrayPartDefinition::New(arr2); +} + +void DataArrayPartDefinition::checkCoherency() const +{ + CheckInternalArrayOK(_arr); +} + +/*! + * This method tries to simplify \a this if possible. + * + * \return a new reference (equal to this) to be decrRefed. + */ +PartDefinition *DataArrayPartDefinition::tryToSimplify() const +{ + checkCoherency(); + int a(0),b(0),c(0); + if(_arr->isRange(a,b,c)) + { + return SlicePartDefinition::New(a,b,c); + } + else + { + PartDefinition *ret(const_cast<DataArrayPartDefinition *>(this)); + ret->incrRef(); + return ret; + } +} + +void DataArrayPartDefinition::serialize(std::vector<int>& tinyInt, std::vector< MEDCouplingAutoRefCountObjectPtr<DataArrayInt> >& bigArraysI) const +{ + bigArraysI.push_back(_arr); +} + +DataArrayInt *DataArrayPartDefinition::toDAI() const +{ + checkInternalArrayOK(); + const DataArrayInt *arr(_arr); + DataArrayInt *arr2(const_cast<DataArrayInt *>(arr)); + arr2->incrRef(); + return arr2; +} + +DataArrayPartDefinition::DataArrayPartDefinition(DataArrayInt *listOfIds) +{ + CheckInternalArrayOK(listOfIds); + _arr=listOfIds; + _arr->incrRef(); +} + +void DataArrayPartDefinition::checkInternalArrayOK() const +{ + CheckInternalArrayOK(_arr); +} + +void DataArrayPartDefinition::CheckInternalArrayOK(const DataArrayInt *listOfIds) +{ + if(!listOfIds || !listOfIds->isAllocated() || listOfIds->getNumberOfComponents()!=1) + throw INTERP_KERNEL::Exception("DataArrayPartDefinition::CheckInternalArrayOK : Input list must be not null allocated and with one components !"); +} + +void DataArrayPartDefinition::updateTime() const +{ + if((const DataArrayInt *)_arr) + updateTimeWith(*_arr); +} + +std::size_t DataArrayPartDefinition::getHeapMemorySizeWithoutChildren() const +{ + return sizeof(DataArrayPartDefinition); +} + +std::vector<const BigMemoryObject *> DataArrayPartDefinition::getDirectChildrenWithNull() const +{ + std::vector<const BigMemoryObject *> ret(1,(const DataArrayInt *)_arr); + return ret; +} + +DataArrayPartDefinition *DataArrayPartDefinition::add1(const DataArrayPartDefinition *other) const +{ + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> a1(toDAI()),a2(other->toDAI()); + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> a3(DataArrayInt::Aggregate(a1,a2,0)); + a3->sort(); + return DataArrayPartDefinition::New(a3); +} + +DataArrayPartDefinition *DataArrayPartDefinition::add2(const SlicePartDefinition *other) const +{ + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> a1(toDAI()),a2(other->toDAI()); + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> a3(DataArrayInt::Aggregate(a1,a2,0)); + a3->sort(); + return DataArrayPartDefinition::New(a3); +} + +DataArrayPartDefinition::~DataArrayPartDefinition() +{ +} + +SlicePartDefinition *SlicePartDefinition::New(int start, int stop, int step) +{ + return new SlicePartDefinition(start,stop,step); +} + +bool SlicePartDefinition::isEqual(const PartDefinition *other, std::string& what) const +{ + if(!other) + { + what="SlicePartDefinition::isEqual : other is null, this is not null !"; + return false; + } + const SlicePartDefinition *otherC(dynamic_cast<const SlicePartDefinition *>(other)); + if(!otherC) + { + what="SlicePartDefinition::isEqual : other is not SlicePartDefinition !"; + return false; + } + bool ret((_start==otherC->_start) && (_stop==otherC->_stop) && (_step==otherC->_step)); + if(!ret) + { + what="SlicePartDefinition::isEqual : values are not the same !"; + return false; + } + return true; +} + +SlicePartDefinition *SlicePartDefinition::deepCpy() const +{ + return SlicePartDefinition::New(_start,_stop,_step); +} + +DataArrayInt *SlicePartDefinition::toDAI() const +{ + return DataArrayInt::Range(_start,_stop,_step); +} + +int SlicePartDefinition::getNumberOfElems() const +{ + return DataArray::GetNumberOfItemGivenBES(_start,_stop,_step,"SlicePartDefinition::getNumberOfElems"); +} + +PartDefinition *SlicePartDefinition::operator+(const PartDefinition& other) const +{ + const PartDefinition *otherPt(&other); + if(!otherPt) + throw INTERP_KERNEL::Exception("DataArrayPartDefinition::operator+ : NULL input !"); + const DataArrayPartDefinition *other1(dynamic_cast<const DataArrayPartDefinition *>(otherPt)); + if(other1) + return add1(other1); + const SlicePartDefinition *other2(dynamic_cast<const SlicePartDefinition *>(otherPt)); + if(other2) + return add2(other2); + throw INTERP_KERNEL::Exception("SlicePartDefinition::operator+ : unrecognized type in input !"); +} + +/*! + * This method operates FoG where F is \a this and G is \a other. + * Example : if \a this is SlicePart(4,6,1) and if \a other is DataArrayPartDefinition([12,13,17,18,22,28,34,44]) -> DataArrayPartDefinition([22,28]) will be returned + */ +PartDefinition *SlicePartDefinition::composeWith(const PartDefinition *other) const +{ + if(!other) + throw INTERP_KERNEL::Exception("SlicePartDefinition::composeWith : input PartDef must be not NULL !"); + checkCoherency(); + other->checkCoherency(); + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> arr(other->toDAI()); + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> arr1(arr->selectByTupleId2(_start,_stop,_step)); + return DataArrayPartDefinition::New(arr1); +} + +/*! + * Do nothing it is not a bug. + */ +void SlicePartDefinition::checkCoherency() const +{ +} + +/*! + * Return \a this (because it cannot be simplified) + * + * \return a new reference (equal to this) to be decrRefed. + */ +PartDefinition *SlicePartDefinition::tryToSimplify() const +{ + PartDefinition *ret(const_cast<SlicePartDefinition *>(this)); + ret->incrRef(); + return ret; +} + +void SlicePartDefinition::serialize(std::vector<int>& tinyInt, std::vector< MEDCouplingAutoRefCountObjectPtr<DataArrayInt> >& bigArraysI) const +{ + tinyInt.push_back(_start); + tinyInt.push_back(_stop); + tinyInt.push_back(_step); +} + +std::string SlicePartDefinition::getRepr() const +{ + std::ostringstream oss; + oss << "Slice is defined with : start=" << _start << " stop=" << _stop << " step=" << _step; + return oss.str(); +} + +int SlicePartDefinition::getEffectiveStop() const +{ + int nbElems(DataArray::GetNumberOfItemGivenBES(_start,_stop,_step,"SlicePartDefinition::getEffectiveStop")); + return _start+nbElems*_step; +} + +void SlicePartDefinition::getSlice(int& start, int& stop, int& step) const +{ + start=_start; + stop=_stop; + step=_step; +} + +SlicePartDefinition::SlicePartDefinition(int start, int stop, int step):_start(start),_stop(stop),_step(step) +{ +} + +/*! + * No child ! It is the leaf ! So no implementation. + */ +void SlicePartDefinition::updateTime() const +{ +} + +std::size_t SlicePartDefinition::getHeapMemorySizeWithoutChildren() const +{ + return sizeof(SlicePartDefinition); +} + +std::vector<const BigMemoryObject *> SlicePartDefinition::getDirectChildrenWithNull() const +{ + return std::vector<const BigMemoryObject *>(); +} + +DataArrayPartDefinition *SlicePartDefinition::add1(const DataArrayPartDefinition *other) const +{ + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> a1(toDAI()),a2(other->toDAI()); + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> a3(DataArrayInt::Aggregate(a1,a2,0)); + a3->sort(); + return DataArrayPartDefinition::New(a3); +} + +PartDefinition *SlicePartDefinition::add2(const SlicePartDefinition *other) const +{ + if(_step==other->_step && getEffectiveStop()==other->_start) + { + return SlicePartDefinition::New(_start,other->_stop,_step); + } + else + { + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> a1(toDAI()),a2(other->toDAI()); + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> a3(DataArrayInt::Aggregate(a1,a2,0)); + a3->sort(); + return DataArrayPartDefinition::New(a3); + } +} + +SlicePartDefinition::~SlicePartDefinition() +{ +} diff --git a/src/medtool/src/MEDCoupling/MEDCouplingPartDefinition.hxx b/src/medtool/src/MEDCoupling/MEDCouplingPartDefinition.hxx new file mode 100644 index 000000000..49bc3d379 --- /dev/null +++ b/src/medtool/src/MEDCoupling/MEDCouplingPartDefinition.hxx @@ -0,0 +1,112 @@ +// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 +// 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 (EDF R&D) + +#ifndef __PARAMEDMEM_MEDCOUPLINGPARTDEFINITION_HXX__ +#define __PARAMEDMEM_MEDCOUPLINGPARTDEFINITION_HXX__ + +#include "MEDCoupling.hxx" +#include "MEDCouplingMemArray.hxx" +#include "MEDCouplingAutoRefCountObjectPtr.hxx" + +namespace ParaMEDMEM +{ + class PartDefinition : public RefCountObject, public TimeLabel + { + public: + MEDCOUPLING_EXPORT static PartDefinition *New(int start, int stop, int step); + MEDCOUPLING_EXPORT static PartDefinition *New(DataArrayInt *listOfIds); + MEDCOUPLING_EXPORT static PartDefinition *Unserialize(std::vector<int>& tinyInt, std::vector< MEDCouplingAutoRefCountObjectPtr<DataArrayInt> >& bigArraysI); + MEDCOUPLING_EXPORT virtual bool isEqual(const PartDefinition *other, std::string& what) const = 0; + MEDCOUPLING_EXPORT virtual PartDefinition *deepCpy() const = 0; + MEDCOUPLING_EXPORT virtual DataArrayInt *toDAI() const = 0; + MEDCOUPLING_EXPORT virtual int getNumberOfElems() const = 0; + MEDCOUPLING_EXPORT virtual PartDefinition *operator+(const PartDefinition& other) const = 0; + MEDCOUPLING_EXPORT virtual std::string getRepr() const = 0; + MEDCOUPLING_EXPORT virtual PartDefinition *composeWith(const PartDefinition *other) const = 0; + MEDCOUPLING_EXPORT virtual void checkCoherency() const = 0; + MEDCOUPLING_EXPORT virtual PartDefinition *tryToSimplify() const = 0; + MEDCOUPLING_EXPORT virtual void serialize(std::vector<int>& tinyInt, std::vector< MEDCouplingAutoRefCountObjectPtr<DataArrayInt> >& bigArraysI) const = 0; + protected: + virtual ~PartDefinition(); + }; + + class SlicePartDefinition; + + class DataArrayPartDefinition : public PartDefinition + { + public: + MEDCOUPLING_EXPORT static DataArrayPartDefinition *New(DataArrayInt *listOfIds); + MEDCOUPLING_EXPORT bool isEqual(const PartDefinition *other, std::string& what) const; + MEDCOUPLING_EXPORT DataArrayPartDefinition *deepCpy() const; + MEDCOUPLING_EXPORT DataArrayInt *toDAI() const; + MEDCOUPLING_EXPORT int getNumberOfElems() const; + MEDCOUPLING_EXPORT PartDefinition *operator+(const PartDefinition& other) const; + MEDCOUPLING_EXPORT std::string getRepr() const; + MEDCOUPLING_EXPORT PartDefinition *composeWith(const PartDefinition *other) const; + MEDCOUPLING_EXPORT void checkCoherency() const; + MEDCOUPLING_EXPORT PartDefinition *tryToSimplify() const; + MEDCOUPLING_EXPORT void serialize(std::vector<int>& tinyInt, std::vector< MEDCouplingAutoRefCountObjectPtr<DataArrayInt> >& bigArraysI) const; + private: + DataArrayPartDefinition(DataArrayInt *listOfIds); + void checkInternalArrayOK() const; + static void CheckInternalArrayOK(const DataArrayInt *listOfIds); + MEDCOUPLING_EXPORT void updateTime() const; + MEDCOUPLING_EXPORT std::size_t getHeapMemorySizeWithoutChildren() const; + MEDCOUPLING_EXPORT std::vector<const BigMemoryObject *> getDirectChildrenWithNull() const; + DataArrayPartDefinition *add1(const DataArrayPartDefinition *other) const; + DataArrayPartDefinition *add2(const SlicePartDefinition *other) const; + virtual ~DataArrayPartDefinition(); + private: + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> _arr; + }; + + class SlicePartDefinition : public PartDefinition + { + public: + MEDCOUPLING_EXPORT static SlicePartDefinition *New(int start, int stop, int step); + MEDCOUPLING_EXPORT bool isEqual(const PartDefinition *other, std::string& what) const; + MEDCOUPLING_EXPORT SlicePartDefinition *deepCpy() const; + MEDCOUPLING_EXPORT DataArrayInt *toDAI() const; + MEDCOUPLING_EXPORT int getNumberOfElems() const; + MEDCOUPLING_EXPORT PartDefinition *operator+(const PartDefinition& other) const; + MEDCOUPLING_EXPORT std::string getRepr() const; + MEDCOUPLING_EXPORT PartDefinition *composeWith(const PartDefinition *other) const; + MEDCOUPLING_EXPORT void checkCoherency() const; + MEDCOUPLING_EXPORT PartDefinition *tryToSimplify() const; + MEDCOUPLING_EXPORT void serialize(std::vector<int>& tinyInt, std::vector< MEDCouplingAutoRefCountObjectPtr<DataArrayInt> >& bigArraysI) const; + //specific method + MEDCOUPLING_EXPORT int getEffectiveStop() const; + MEDCOUPLING_EXPORT void getSlice(int& start, int& stop, int& step) const; + private: + SlicePartDefinition(int start, int stop, int step); + MEDCOUPLING_EXPORT void updateTime() const; + MEDCOUPLING_EXPORT std::size_t getHeapMemorySizeWithoutChildren() const; + MEDCOUPLING_EXPORT std::vector<const BigMemoryObject *> getDirectChildrenWithNull() const; + DataArrayPartDefinition *add1(const DataArrayPartDefinition *other) const; + PartDefinition *add2(const SlicePartDefinition *other) const; + virtual ~SlicePartDefinition(); + private: + int _start; + int _stop; + int _step; + }; +} + +#endif diff --git a/src/medtool/src/MEDCoupling/MEDCouplingPointSet.cxx b/src/medtool/src/MEDCoupling/MEDCouplingPointSet.cxx new file mode 100644 index 000000000..4793b7993 --- /dev/null +++ b/src/medtool/src/MEDCoupling/MEDCouplingPointSet.cxx @@ -0,0 +1,1695 @@ +// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 +// 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 "MEDCouplingPointSet.hxx" +#include "MEDCouplingAutoRefCountObjectPtr.hxx" +#include "MEDCoupling1GTUMesh.hxx" +#include "MEDCouplingUMesh.hxx" +#include "MEDCouplingMemArray.hxx" +#include "PlanarIntersector.txx" +#include "InterpKernelGeo2DQuadraticPolygon.hxx" +#include "InterpKernelGeo2DNode.hxx" +#include "DirectedBoundingBox.hxx" +#include "InterpKernelAutoPtr.hxx" + +#include <cmath> +#include <limits> +#include <numeric> + +using namespace ParaMEDMEM; + +MEDCouplingPointSet::MEDCouplingPointSet():_coords(0) +{ +} + +MEDCouplingPointSet::MEDCouplingPointSet(const MEDCouplingPointSet& other, bool deepCopy):MEDCouplingMesh(other),_coords(0) +{ + if(other._coords) + _coords=other._coords->performCpy(deepCopy); +} + +MEDCouplingPointSet::~MEDCouplingPointSet() +{ + if(_coords) + _coords->decrRef(); +} + +int MEDCouplingPointSet::getNumberOfNodes() const +{ + if(_coords) + return _coords->getNumberOfTuples(); + else + throw INTERP_KERNEL::Exception("Unable to get number of nodes because no coordinates specified !"); +} + +int MEDCouplingPointSet::getSpaceDimension() const +{ + if(_coords) + return _coords->getNumberOfComponents(); + else + throw INTERP_KERNEL::Exception("Unable to get space dimension because no coordinates specified !"); +} + +void MEDCouplingPointSet::updateTime() const +{ + if(_coords) + { + updateTimeWith(*_coords); + } +} + +std::size_t MEDCouplingPointSet::getHeapMemorySizeWithoutChildren() const +{ + return MEDCouplingMesh::getHeapMemorySizeWithoutChildren(); +} + +std::vector<const BigMemoryObject *> MEDCouplingPointSet::getDirectChildrenWithNull() const +{ + std::vector<const BigMemoryObject *> ret; + ret.push_back(_coords); + return ret; +} + +void MEDCouplingPointSet::setCoords(const DataArrayDouble *coords) +{ + if( coords != _coords ) + { + if (_coords) + _coords->decrRef(); + _coords=const_cast<DataArrayDouble *>(coords); + if(_coords) + _coords->incrRef(); + declareAsNew(); + } +} + +/*! + * 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) + _coords->incrRef(); + return _coords; +} + +/*! + * 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) +{ + MEDCouplingMesh::copyTinyStringsFrom(other); + const MEDCouplingPointSet *otherC=dynamic_cast<const MEDCouplingPointSet *>(other); + if(!otherC) + throw INTERP_KERNEL::Exception("MEDCouplingPointSet::copyTinyStringsFrom : meshes have not same type !"); + if(_coords && otherC->_coords) + _coords->copyStringInfoFrom(*otherC->_coords); +} + +bool MEDCouplingPointSet::isEqualIfNotWhy(const MEDCouplingMesh *other, double prec, std::string& reason) const +{ + if(!other) + throw INTERP_KERNEL::Exception("MEDCouplingPointSet::isEqualIfNotWhy : null mesh instance in input !"); + const MEDCouplingPointSet *otherC=dynamic_cast<const MEDCouplingPointSet *>(other); + if(!otherC) + { + reason="mesh given in input is not castable in MEDCouplingPointSet !"; + return false; + } + if(!MEDCouplingMesh::isEqualIfNotWhy(other,prec,reason)) + return false; + if(!areCoordsEqualIfNotWhy(*otherC,prec,reason)) + return false; + 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<const MEDCouplingPointSet *>(other); + if(!otherC) + return false; + if(!areCoordsEqualWithoutConsideringStr(*otherC,prec)) + return false; + return true; +} + +bool MEDCouplingPointSet::areCoordsEqualIfNotWhy(const MEDCouplingPointSet& other, double prec, std::string& reason) const +{ + if(_coords==0 && other._coords==0) + return true; + if(_coords==0 || other._coords==0) + { + reason="Only one PointSet between the two this and other has coordinate defined !"; + return false; + } + if(_coords==other._coords) + return true; + bool ret=_coords->isEqualIfNotWhy(*other._coords,prec,reason); + if(!ret) + reason.insert(0,"Coordinates DataArray do not match : "); + 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) + return true; + if(_coords==0 || other._coords==0) + return false; + if(_coords==other._coords) + return true; + return _coords->isEqualWithoutConsideringStr(*other._coords,prec); +} + +/*! + * 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. + * + * \if ENABLE_EXAMPLES + * \ref cpp_mcpointset_getcoordinatesofnode "Here is a C++ example".<br> + * \ref py_mcpointset_getcoordinatesofnode "Here is a Python example". + * \endif + */ +void MEDCouplingPointSet::getCoordinatesOfNode(int nodeId, std::vector<double>& coo) const +{ + if(!_coords) + throw INTERP_KERNEL::Exception("MEDCouplingPointSet::getCoordinatesOfNode : no coordinates array set !"); + int nbNodes=getNumberOfNodes(); + if(nodeId>=0 && nodeId<nbNodes) + { + const double *cooPtr=_coords->getConstPointer(); + int spaceDim=getSpaceDimension(); + coo.insert(coo.end(),cooPtr+spaceDim*nodeId,cooPtr+spaceDim*(nodeId+1)); + } + else + { + std::ostringstream oss; oss << "MEDCouplingPointSet::getCoordinatesOfNode : request of nodeId \"" << nodeId << "\" but it should be in [0,"<< nbNodes << ") !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } +} + +/*! + * 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 numbering. 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(); + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=buildNewNumberingFromCommonNodesFormat(comm,commI,newNbOfNodes); + areNodesMerged=(oldNbOfNodes!=newNbOfNodes); + comm->decrRef(); + commI->decrRef(); + return ret.retn(); +} + +/*! + * Finds nodes coincident within \a prec tolerance. + * Ids of coincident nodes are stored in output arrays in the \ref numbering-indirect format. + * \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 (\ref numbering-indirect). 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. + * + * \if ENABLE_EXAMPLES + * \ref cpp_mcpointset_findcommonnodes "Here is a C++ example".<br> + * \ref py_mcpointset_findcommonnodes "Here is a Python example". + * \endif + */ +void MEDCouplingPointSet::findCommonNodes(double prec, int limitNodeId, DataArrayInt *&comm, DataArrayInt *&commIndex) const +{ + if(!_coords) + throw INTERP_KERNEL::Exception("MEDCouplingPointSet::findCommonNodes : no coords specified !"); + _coords->findCommonTuples(prec,limitNodeId,comm,commIndex); +} + +/*! + * 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. + * + * \if ENABLE_EXAMPLES + * \ref cpp_mcpointset_getnodeidsnearpoint "Here is a C++ example".<br> + * \ref py_mcpointset_getnodeidsnearpoint "Here is a Python example". + * \endif + */ +DataArrayInt *MEDCouplingPointSet::getNodeIdsNearPoint(const double *pos, double eps) const +{ + DataArrayInt *c=0,*cI=0; + getNodeIdsNearPoints(pos,1,eps,c,cI); + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> cITmp(cI); + return c; +} + +/*! + * 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 (\ref numbering-indirect) 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 (\ref numbering-indirect). <br>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. + * + * \if ENABLE_EXAMPLES + * \ref cpp_mcpointset_getnodeidsnearpoints "Here is a C++ example".<br> + * \ref py_mcpointset_getnodeidsnearpoints "Here is a Python example". + * \endif + */ +void MEDCouplingPointSet::getNodeIdsNearPoints(const double *pos, int nbOfPoints, double eps, DataArrayInt *& c, DataArrayInt *& cI) const +{ + if(!_coords) + throw INTERP_KERNEL::Exception("MEDCouplingPointSet::getNodeIdsNearPoint : no coordiantes set !"); + int spaceDim=getSpaceDimension(); + MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> points=DataArrayDouble::New(); + points->useArray(pos,false,CPP_DEALLOC,nbOfPoints,spaceDim); + _coords->computeTupleIdsNearTuples(points,eps,c,cI); +} + +/*! + * @param comm in param in the same format than one returned by findCommonNodes method (\ref numbering-indirect). + * @param commI in param in the same format than one returned by findCommonNodes method (\ref numbering-indirect). + * @return the old to new correspondance array. + */ +DataArrayInt *MEDCouplingPointSet::buildNewNumberingFromCommonNodesFormat(const DataArrayInt *comm, const DataArrayInt *commIndex, + int& newNbOfNodes) const +{ + if(!_coords) + throw INTERP_KERNEL::Exception("MEDCouplingPointSet::buildNewNumberingFromCommonNodesFormat : no coords specified !"); + return DataArrayInt::BuildOld2NewArrayFromSurjectiveFormat2(getNumberOfNodes(),comm->begin(),commIndex->begin(),commIndex->end(),newNbOfNodes); +} + +/*! + * Permutes and possibly removes nodes as specified by \a newNodeNumbers array. + * If \a newNodeNumbers[ i ] < 0 then the i-th node is removed, + * else \a newNodeNumbers[ i ] is a new id of the i-th node. The nodal connectivity + * array is modified accordingly. + * \param [in] newNodeNumbers - a permutation array, of length \a + * this->getNumberOfNodes(), in "Old to New" mode. + * See \ref numbering for more info on renumbering modes. + * \param [in] newNbOfNodes - number of nodes remaining after renumbering. + * \throw If the coordinates array is not set. + * \throw If the nodal connectivity of cells is not defined. + * + * \if ENABLE_EXAMPLES + * \ref cpp_mcumesh_renumberNodes "Here is a C++ example".<br> + * \ref py_mcumesh_renumberNodes "Here is a Python example". + * \endif + */ +void MEDCouplingPointSet::renumberNodes(const int *newNodeNumbers, int newNbOfNodes) +{ + if(!_coords) + throw INTERP_KERNEL::Exception("MEDCouplingPointSet::renumberNodes : no coords specified !"); + MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> newCoords=_coords->renumberAndReduce(newNodeNumbers,newNbOfNodes); + renumberNodesInConn(newNodeNumbers); + setCoords(newCoords);//let it here not before renumberNodesInConn because old number of nodes is sometimes used... +} + +/*! + * Permutes and possibly removes nodes as specified by \a newNodeNumbers array. + * If \a newNodeNumbers[ i ] < 0 then the i-th node is removed, + * else \a newNodeNumbers[ i ] is a new id of the i-th node. The nodal connectivity + * array is modified accordingly. In contrast to renumberNodes(), location + * of merged nodes (whose new ids coincide) is changed to be at their barycenter. + * \param [in] newNodeNumbers - a permutation array, of length \a + * this->getNumberOfNodes(), in "Old to New" mode. + * See \ref numbering for more info on renumbering modes. + * \param [in] newNbOfNodes - number of nodes remaining after renumbering, which is + * actually one more than the maximal id in \a newNodeNumbers. + * \throw If the coordinates array is not set. + * \throw If the nodal connectivity of cells is not defined. + * + * \if ENABLE_EXAMPLES + * \ref cpp_mcumesh_renumberNodes "Here is a C++ example".<br> + * \ref py_mcumesh_renumberNodes "Here is a Python example". + * \endif + */ +void MEDCouplingPointSet::renumberNodes2(const int *newNodeNumbers, int newNbOfNodes) +{ + DataArrayDouble *newCoords=DataArrayDouble::New(); + std::vector<int> div(newNbOfNodes); + int spaceDim=getSpaceDimension(); + newCoords->alloc(newNbOfNodes,spaceDim); + newCoords->copyStringInfoFrom(*_coords); + newCoords->fillWithZero(); + int oldNbOfNodes=getNumberOfNodes(); + double *ptToFill=newCoords->getPointer(); + const double *oldCoordsPtr=_coords->getConstPointer(); + for(int i=0;i<oldNbOfNodes;i++) + { + std::transform(oldCoordsPtr+i*spaceDim,oldCoordsPtr+(i+1)*spaceDim,ptToFill+newNodeNumbers[i]*spaceDim, + ptToFill+newNodeNumbers[i]*spaceDim,std::plus<double>()); + div[newNodeNumbers[i]]++; + } + for(int i=0;i<newNbOfNodes;i++) + ptToFill=std::transform(ptToFill,ptToFill+spaceDim,ptToFill,std::bind2nd(std::multiplies<double>(),1./(double)div[i])); + setCoords(newCoords); + newCoords->decrRef(); + renumberNodesInConn(newNodeNumbers); +} + +/*! + * 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. + * + * \if ENABLE_EXAMPLES + * \ref cpp_mcpointset_getBoundingBox "Here is a C++ example".<br> + * \ref py_mcpointset_getBoundingBox "Here is a Python example". + * \endif + */ +void MEDCouplingPointSet::getBoundingBox(double *bbox) const +{ + if(!_coords) + throw INTERP_KERNEL::Exception("MEDCouplingPointSet::getBoundingBox : Coordinates not set !"); + _coords->getMinMaxPerComponent(bbox); +} + +/*! + * 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() +{ + checkFullyDefined(); + DataArrayInt *traducer=zipCoordsTraducer(); + traducer->decrRef(); +} + +/*! \cond HIDDEN_ITEMS */ +struct MEDCouplingCompAbs +{ + bool operator()(double x, double y) { return std::abs(x)<std::abs(y);} +}; +/*! \endcond */ + +/*! + * 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 +{ + if(!_coords) + throw INTERP_KERNEL::Exception("MEDCouplingPointSet::getCaracteristicDimension : Coordinates not set !"); + const double *coords=_coords->getConstPointer(); + int nbOfValues=_coords->getNbOfElems(); + return std::abs(*std::max_element(coords,coords+nbOfValues,MEDCouplingCompAbs())); +} + +/*! + * 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. + * + */ +void MEDCouplingPointSet::recenterForMaxPrecision(double eps) +{ + if(!_coords) + throw INTERP_KERNEL::Exception("MEDCouplingPointSet::recenterForMaxPrecision : Coordinates not set !"); + _coords->recenterForMaxPrecision(eps); + updateTime(); +} + +/*! + * 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. + * + * \if ENABLE_EXAMPLES + * \ref cpp_mcpointset_rotate "Here is a C++ example".<br> + * \ref py_mcpointset_rotate "Here is a Python example". + * \endif + */ +void MEDCouplingPointSet::rotate(const double *center, const double *vector, double angle) +{ + int spaceDim=getSpaceDimension(); + if(spaceDim==3) + rotate3D(center,vector,angle); + else if(spaceDim==2) + rotate2D(center,angle); + else + throw INTERP_KERNEL::Exception("MEDCouplingPointSet::rotate : invalid space dim for rotation must be 2 or 3"); + _coords->declareAsNew(); + updateTime(); +} + +/*! + * 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. + * + * \if ENABLE_EXAMPLES + * \ref cpp_mcpointset_translate "Here is a C++ example".<br> + * \ref py_mcpointset_translate "Here is a Python example". + * \endif + */ +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(); + for(int i=0; i<nbNodes; i++) + for(int idim=0; idim<dim;idim++) + coords[i*dim+idim]+=vector[idim]; + _coords->declareAsNew(); + updateTime(); +} + + +/*! + * 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. + * + * \if ENABLE_EXAMPLES + * \ref cpp_mcpointset_scale "Here is a C++ example".<br> + * \ref py_mcpointset_scale "Here is a Python example". + * \endif + */ +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(); + for(int i=0;i<nbNodes;i++) + { + std::transform(coords+i*dim,coords+(i+1)*dim,point,coords+i*dim,std::minus<double>()); + std::transform(coords+i*dim,coords+(i+1)*dim,coords+i*dim,std::bind2nd(std::multiplies<double>(),factor)); + std::transform(coords+i*dim,coords+(i+1)*dim,point,coords+i*dim,std::plus<double>()); + } + _coords->declareAsNew(); + updateTime(); +} + +/*! + * Converts \a this set of points to an other dimension by changing number of + * components of point coordinates. If the dimension increases, added components + * are filled with \a dftValue. If the dimension decreases, last components are lost. + * If the new dimension is same as \a this->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) +{ + if(getCoords()==0) + throw INTERP_KERNEL::Exception("changeSpaceDimension must be called on an MEDCouplingPointSet instance with coordinates set !"); + if(newSpaceDim<1) + throw INTERP_KERNEL::Exception("changeSpaceDimension must be called a newSpaceDim >=1 !"); + int oldSpaceDim=getSpaceDimension(); + if(newSpaceDim==oldSpaceDim) + return ; + DataArrayDouble *newCoords=getCoords()->changeNbOfComponents(newSpaceDim,dftValue); + setCoords(newCoords); + newCoords->decrRef(); + updateTime(); +} + +/*! + * 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) +{ + if(_coords==other._coords) + return ; + if(!_coords) + throw INTERP_KERNEL::Exception("Current instance has no coords whereas other has !"); + if(!other._coords) + throw INTERP_KERNEL::Exception("Other instance has no coords whereas current has !"); + if(!_coords->isEqualWithoutConsideringStr(*other._coords,epsilon)) + throw INTERP_KERNEL::Exception("Coords are not the same !"); + setCoords(other._coords); +} + +/*! + * This method duplicates the nodes whose ids are in [\b nodeIdsToDuplicateBg, \b nodeIdsToDuplicateEnd) and put the result of their duplication at the end + * of existing node ids. + * + * \param [in] nodeIdsToDuplicateBg begin of node ids (included) to be duplicated in connectivity only + * \param [in] nodeIdsToDuplicateEnd end of node ids (excluded) to be duplicated in connectivity only + */ +void MEDCouplingPointSet::duplicateNodesInCoords(const int *nodeIdsToDuplicateBg, const int *nodeIdsToDuplicateEnd) +{ + if(!_coords) + throw INTERP_KERNEL::Exception("MEDCouplingPointSet::duplicateNodesInCoords : no coords set !"); + MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> newCoords=_coords->selectByTupleIdSafe(nodeIdsToDuplicateBg,nodeIdsToDuplicateEnd); + MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> newCoords2=DataArrayDouble::Aggregate(_coords,newCoords); + setCoords(newCoords2); +} + +/*! + * 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<int>& nodes) const +{ + 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<std::numeric_limits<double>::min()) + throw INTERP_KERNEL::Exception("MEDCouplingPointSet::findNodesOnPlane : vector pointer specified has norm equal to 0. !"); + const double *work=_coords->getConstPointer(); + for(int i=0;i<nbOfNodes;i++) + { + if(std::abs(a*work[0]+b*work[1]+c*work[2]+d)/deno<eps) + nodes.push_back(i); + work+=3; + } +} + +/*! + * 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<int>& nodes) const +{ + 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;i<spaceDim;i++) + den+=vec[i]*vec[i]; + double deno=sqrt(den); + if(deno<10.*eps) + throw INTERP_KERNEL::Exception("MEDCouplingPointSet::findNodesOnLine : Invalid given direction vector ! Norm is too small !"); + INTERP_KERNEL::AutoPtr<double> vecn=new double[spaceDim]; + for(int i=0;i<spaceDim;i++) + vecn[i]=vec[i]/deno; + const double *work=_coords->getConstPointer(); + if(spaceDim==2) + { + for(int i=0;i<nbOfNodes;i++) + { + if(std::abs(vecn[0]*(work[1]-pt[1])-vecn[1]*(work[0]-pt[0]))<eps) + nodes.push_back(i); + work+=2; + } + } + else + { + for(int i=0;i<nbOfNodes;i++) + { + double a=vecn[0]*(work[1]-pt[1])-vecn[1]*(work[0]-pt[0]); + double b=vecn[1]*(work[2]-pt[2])-vecn[2]*(work[1]-pt[1]); + double c=vecn[2]*(work[0]-pt[0])-vecn[0]*(work[2]-pt[2]); + if(std::sqrt(a*a+b*b+c*c)<eps) + nodes.push_back(i); + work+=3; + } + } +} + +/*! + * Returns a new array of node coordinates by concatenating node coordinates of two + * given point sets, so that (1) the number of nodes in the result array is a sum of the + * number of nodes of given point sets and (2) the number of component in the result array + * is same as that of each of given point sets. Info on components is copied from the first + * of the given point set. Space dimension of the given point sets must be the same. + * \param [in] m1 - a point set whose coordinates will be included in the result array. + * \param [in] m2 - another point set whose coordinates will be included 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 m1 and \a m2 are NULL. + * \throw If \a m1->getSpaceDimension() != \a m2->getSpaceDimension(). + */ +DataArrayDouble *MEDCouplingPointSet::MergeNodesArray(const MEDCouplingPointSet *m1, const MEDCouplingPointSet *m2) +{ + int spaceDim=m1->getSpaceDimension(); + if(spaceDim!=m2->getSpaceDimension()) + throw INTERP_KERNEL::Exception("Mismatch in SpaceDim during call of MergeNodesArray !"); + return DataArrayDouble::Aggregate(m1->getCoords(),m2->getCoords()); +} + +DataArrayDouble *MEDCouplingPointSet::MergeNodesArray(const std::vector<const MEDCouplingPointSet *>& ms) +{ + if(ms.empty()) + throw INTERP_KERNEL::Exception("MEDCouplingPointSet::MergeNodesArray : input array must be NON EMPTY !"); + std::vector<const MEDCouplingPointSet *>::const_iterator it=ms.begin(); + std::vector<const DataArrayDouble *> coo(ms.size()); + int spaceDim=(*it)->getSpaceDimension(); + coo[0]=(*it++)->getCoords(); + if(!coo[0]->isAllocated()) + throw INTERP_KERNEL::Exception("MEDCouplingPointSet::MergeNodesArray : first element in coordinates is not allocated !"); + for(int i=1;it!=ms.end();it++,i++) + { + const DataArrayDouble *tmp=(*it)->getCoords(); + if(tmp) + { + if(tmp->isAllocated()) + { + if((*it)->getSpaceDimension()==spaceDim) + coo[i]=tmp; + else + throw INTERP_KERNEL::Exception("MEDCouplingPointSet::MergeNodesArray : Mismatch in SpaceDim !"); + } + else + throw INTERP_KERNEL::Exception("MEDCouplingPointSet::MergeNodesArray : Presence of a non allocated array !"); + } + else + throw INTERP_KERNEL::Exception("MEDCouplingPointSet::MergeNodesArray : Empty coords detected !"); + } + return DataArrayDouble::Aggregate(coo); +} + +/*! + * Factory to build new instance of instanciable subclasses of MEDCouplingPointSet. + * This method is used during unserialization process. + */ +MEDCouplingPointSet *MEDCouplingPointSet::BuildInstanceFromMeshType(MEDCouplingMeshType type) +{ + switch(type) + { + case UNSTRUCTURED: + return MEDCouplingUMesh::New(); + case SINGLE_STATIC_GEO_TYPE_UNSTRUCTURED: + return MEDCoupling1SGTUMesh::New(); + case SINGLE_DYNAMIC_GEO_TYPE_UNSTRUCTURED: + return MEDCoupling1DGTUMesh::New(); + default: + throw INTERP_KERNEL::Exception("Invalid type of mesh specified"); + } +} + +/*! + * First step of serialization process. Used by ParaMEDMEM and MEDCouplingCorba to transfert data between process. + */ +void MEDCouplingPointSet::getTinySerializationInformation(std::vector<double>& tinyInfoD, std::vector<int>& tinyInfo, std::vector<std::string>& littleStrings) const +{ + int it,order; + double time=getTime(it,order); + if(_coords) + { + int spaceDim=getSpaceDimension(); + littleStrings.resize(spaceDim+4); + littleStrings[0]=getName(); + littleStrings[1]=getDescription(); + littleStrings[2]=_coords->getName(); + littleStrings[3]=getTimeUnit(); + for(int i=0;i<spaceDim;i++) + littleStrings[i+4]=getCoords()->getInfoOnComponent(i); + tinyInfo.clear(); + tinyInfo.push_back(getType()); + tinyInfo.push_back(spaceDim); + tinyInfo.push_back(getNumberOfNodes()); + tinyInfo.push_back(it); + tinyInfo.push_back(order); + tinyInfoD.push_back(time); + } + else + { + littleStrings.resize(3); + littleStrings[0]=getName(); + littleStrings[1]=getDescription(); + littleStrings[2]=getTimeUnit(); + tinyInfo.clear(); + tinyInfo.push_back(getType()); + tinyInfo.push_back(-1); + tinyInfo.push_back(-1); + tinyInfo.push_back(it); + tinyInfo.push_back(order); + tinyInfoD.push_back(time); + } +} + +/*! + * Third and final step of serialization process. + */ +void MEDCouplingPointSet::serialize(DataArrayInt *&a1, DataArrayDouble *&a2) const +{ + if(_coords) + { + a2=const_cast<DataArrayDouble *>(getCoords()); + a2->incrRef(); + } + else + a2=0; +} + +/*! + * Second step of serialization process. + * @param tinyInfo must be equal to the result given by getTinySerializationInformation method. + */ +void MEDCouplingPointSet::resizeForUnserialization(const std::vector<int>& tinyInfo, DataArrayInt *a1, DataArrayDouble *a2, std::vector<std::string>& littleStrings) const +{ + if(tinyInfo[2]>=0 && tinyInfo[1]>=1) + { + a2->alloc(tinyInfo[2],tinyInfo[1]); + littleStrings.resize(tinyInfo[1]+4); + } + else + { + littleStrings.resize(3); + } +} + +/*! + * Second and final unserialization process. + * @param tinyInfo must be equal to the result given by getTinySerializationInformation method. + */ +void MEDCouplingPointSet::unserialization(const std::vector<double>& tinyInfoD, const std::vector<int>& tinyInfo, const DataArrayInt *a1, DataArrayDouble *a2, const std::vector<std::string>& littleStrings) +{ + if(tinyInfo[2]>=0 && tinyInfo[1]>=1) + { + setCoords(a2); + setName(littleStrings[0]); + setDescription(littleStrings[1]); + a2->setName(littleStrings[2]); + setTimeUnit(littleStrings[3]); + for(int i=0;i<tinyInfo[1];i++) + getCoords()->setInfoOnComponent(i,littleStrings[i+4]); + setTime(tinyInfoD[0],tinyInfo[3],tinyInfo[4]); + } + else + { + setName(littleStrings[0]); + setDescription(littleStrings[1]); + setTimeUnit(littleStrings[2]); + setTime(tinyInfoD[0],tinyInfo[3],tinyInfo[4]); + } +} + +void MEDCouplingPointSet::checkCoherency() const +{ + if(!_coords) + throw INTERP_KERNEL::Exception("MEDCouplingPointSet::checkCoherency : no coordinates set !"); +} + +/*! + * Intersect Bounding Box given 2 Bounding Boxes. + */ +bool MEDCouplingPointSet::intersectsBoundingBox(const double* bb1, const double* bb2, int dim, double eps) +{ + double* bbtemp = new double[2*dim]; + double deltamax=0.0; + + for (int i=0; i< dim; i++) + { + double delta = bb1[2*i+1]-bb1[2*i]; + if ( delta > deltamax ) + { + deltamax = delta ; + } + } + for (int i=0; i<dim; i++) + { + bbtemp[i*2]=bb1[i*2]-deltamax*eps; + bbtemp[i*2+1]=bb1[i*2+1]+deltamax*eps; + } + + for (int idim=0; idim < dim; idim++) + { + bool intersects = (bbtemp[idim*2]<bb2[idim*2+1]) + && (bb2[idim*2]<bbtemp[idim*2+1]) ; + if (!intersects) + { + delete [] bbtemp; + return false; + } + } + delete [] bbtemp; + return true; +} + +/*! + * Intersect 2 given Bounding Boxes. + */ +bool MEDCouplingPointSet::intersectsBoundingBox(const INTERP_KERNEL::DirectedBoundingBox& bb1, const double* bb2, int dim, double eps) +{ + double* bbtemp = new double[2*dim]; + double deltamax=0.0; + + for (int i=0; i< dim; i++) + { + double delta = bb2[2*i+1]-bb2[2*i]; + if ( delta > deltamax ) + { + deltamax = delta ; + } + } + for (int i=0; i<dim; i++) + { + bbtemp[i*2]=bb2[i*2]-deltamax*eps; + bbtemp[i*2+1]=bb2[i*2+1]+deltamax*eps; + } + + bool intersects = !bb1.isDisjointWith( bbtemp ); + delete [] bbtemp; + return intersects; +} + +/*! + * 'This' is expected to be of spaceDim==3. Idem for 'center' and 'vect' + */ +void MEDCouplingPointSet::rotate3D(const double *center, const double *vect, double angle) +{ + double *coords=_coords->getPointer(); + int nbNodes=getNumberOfNodes(); + Rotate3DAlg(center,vect,angle,nbNodes,coords); +} + +/*! + * Low static method that operates 3D rotation of 'nbNodes' 3D nodes whose coordinates are arranged in 'coords' + * around an axe ('center','vect') and with angle 'angle'. + */ +void MEDCouplingPointSet::Rotate3DAlg(const double *center, const double *vect, double angle, int nbNodes, double *coords) +{ + if(!center || !vect) + throw INTERP_KERNEL::Exception("MEDCouplingPointSet::Rotate3DAlg : null vector in input !"); + double sina=sin(angle); + double cosa=cos(angle); + double vectorNorm[3]; + double matrix[9]; + double matrixTmp[9]; + double norm=sqrt(vect[0]*vect[0]+vect[1]*vect[1]+vect[2]*vect[2]); + if(norm<std::numeric_limits<double>::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<double>(),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; + matrixTmp[0]=vectorNorm[0]*vectorNorm[0]; matrixTmp[1]=vectorNorm[0]*vectorNorm[1]; matrixTmp[2]=vectorNorm[0]*vectorNorm[2]; + matrixTmp[3]=vectorNorm[1]*vectorNorm[0]; matrixTmp[4]=vectorNorm[1]*vectorNorm[1]; matrixTmp[5]=vectorNorm[1]*vectorNorm[2]; + matrixTmp[6]=vectorNorm[2]*vectorNorm[0]; matrixTmp[7]=vectorNorm[2]*vectorNorm[1]; matrixTmp[8]=vectorNorm[2]*vectorNorm[2]; + std::transform(matrixTmp,matrixTmp+9,matrixTmp,std::bind2nd(std::multiplies<double>(),1-cosa)); + std::transform(matrix,matrix+9,matrixTmp,matrix,std::plus<double>()); + matrixTmp[0]=0.; matrixTmp[1]=-vectorNorm[2]; matrixTmp[2]=vectorNorm[1]; + matrixTmp[3]=vectorNorm[2]; matrixTmp[4]=0.; matrixTmp[5]=-vectorNorm[0]; + matrixTmp[6]=-vectorNorm[1]; matrixTmp[7]=vectorNorm[0]; matrixTmp[8]=0.; + std::transform(matrixTmp,matrixTmp+9,matrixTmp,std::bind2nd(std::multiplies<double>(),sina)); + std::transform(matrix,matrix+9,matrixTmp,matrix,std::plus<double>()); + //rotation matrix computed. + double tmp[3]; + for(int i=0; i<nbNodes; i++) + { + std::transform(coords+i*3,coords+(i+1)*3,center,tmp,std::minus<double>()); + coords[i*3]=matrix[0]*tmp[0]+matrix[1]*tmp[1]+matrix[2]*tmp[2]+center[0]; + coords[i*3+1]=matrix[3]*tmp[0]+matrix[4]*tmp[1]+matrix[5]*tmp[2]+center[1]; + coords[i*3+2]=matrix[6]*tmp[0]+matrix[7]*tmp[1]+matrix[8]*tmp[2]+center[2]; + } +} + +/*! + * This method allows to give for each cell in \a trgMesh, how much it interacts with cells of \a srcMesh. + * The returned array can be seen as a weighted array on the target cells of \a trgMesh input parameter. + * + * \param [in] srcMesh - source mesh + * \param [in] trgMesh - target mesh + * \param [in] eps - precision of the detection + * \return DataArrayInt * - An array that gives for each cell of \a trgMesh, how many cells in \a srcMesh (regarding the precision of detection \a eps) can interacts. + * + * \throw If \a srcMesh and \a trgMesh have not the same space dimension. + */ +DataArrayInt *MEDCouplingPointSet::ComputeNbOfInteractionsWithSrcCells(const MEDCouplingPointSet *srcMesh, const MEDCouplingPointSet *trgMesh, double eps) +{ + if(!srcMesh || !trgMesh) + throw INTERP_KERNEL::Exception("MEDCouplingPointSet::ComputeNbOfInteractionsWithSrcCells : the input meshes must be not NULL !"); + MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> sbbox(srcMesh->getBoundingBoxForBBTree()),tbbox(trgMesh->getBoundingBoxForBBTree()); + return tbbox->computeNbOfInteractionsWith(sbbox,eps); +} + +/*! + * 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 +{ + return buildPartOfMySelf(start,end,true); +} + +/*! + * 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. + * <br> 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 +{ + MEDCouplingAutoRefCountObjectPtr<MEDCouplingPointSet> ret=buildPartOfMySelf(start,end,true); + arr=ret->zipCoordsTraducer(); + return ret.retn(); +} + +/*! + * This method specialized the MEDCouplingMesh::buildPartRange. + * 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. + * \b WARNING , there is a big difference compared to MEDCouplingMesh::buildPart method. + * If the input range is equal all cells in \a this, \a this is returned ! + * + * \return a new ref to be managed by the caller. Warning this ref can be equal to \a this if input slice is exactly equal to the whole cells in the same order. + * + * \sa MEDCouplingUMesh::buildPartOfMySelf2 + */ +MEDCouplingMesh *MEDCouplingPointSet::buildPartRange(int beginCellIds, int endCellIds, int stepCellIds) const +{ + if(beginCellIds==0 && endCellIds==getNumberOfCells() && stepCellIds==1) + { + MEDCouplingMesh *ret(const_cast<MEDCouplingPointSet *>(this)); + ret->incrRef(); + return ret; + } + else + { + 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 +{ + MEDCouplingAutoRefCountObjectPtr<MEDCouplingPointSet> 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' + */ +void MEDCouplingPointSet::rotate2D(const double *center, double angle) +{ + double *coords=_coords->getPointer(); + int nbNodes=getNumberOfNodes(); + Rotate2DAlg(center,angle,nbNodes,coords); +} + +/*! + * Low static method that operates 3D rotation of 'nbNodes' 3D nodes whose coordinates are arranged in 'coords' + * around the center point 'center' and with angle 'angle'. + */ +void MEDCouplingPointSet::Rotate2DAlg(const double *center, double angle, int nbNodes, double *coords) +{ + double cosa=cos(angle); + double sina=sin(angle); + double matrix[4]; + matrix[0]=cosa; matrix[1]=-sina; matrix[2]=sina; matrix[3]=cosa; + double tmp[2]; + for(int i=0; i<nbNodes; i++) + { + std::transform(coords+i*2,coords+(i+1)*2,center,tmp,std::minus<double>()); + coords[i*2]=matrix[0]*tmp[0]+matrix[1]*tmp[1]+center[0]; + coords[i*2+1]=matrix[2]*tmp[0]+matrix[3]*tmp[1]+center[1]; + } +} + +/// @cond INTERNAL + +class DummyClsMCPS +{ +public: + static const int MY_SPACEDIM=3; + static const int MY_MESHDIM=2; + typedef int MyConnType; + static const INTERP_KERNEL::NumberingPolicy My_numPol=INTERP_KERNEL::ALL_C_MODE; +}; + +/// @endcond + +/*! + * res should be an empty vector before calling this method. + * This method returns all the node coordinates included in _coords which ids are in [startConn;endConn) and put it into 'res' vector. + * If spaceDim==3 a projection will be done for each nodes on the middle plane containing these all nodes in [startConn;endConn). + * And after each projected nodes are moved to Oxy plane in order to consider these nodes as 2D nodes. + */ +void MEDCouplingPointSet::project2DCellOnXY(const int *startConn, const int *endConn, std::vector<double>& res) const +{ + const double *coords=_coords->getConstPointer(); + int spaceDim=getSpaceDimension(); + for(const int *it=startConn;it!=endConn;it++) + res.insert(res.end(),coords+spaceDim*(*it),coords+spaceDim*(*it+1)); + if(spaceDim==2) + return ; + if(spaceDim==3) + { + std::vector<double> cpy(res); + int nbNodes=(int)std::distance(startConn,endConn); + INTERP_KERNEL::PlanarIntersector<DummyClsMCPS,int>::Projection(&res[0],&cpy[0],nbNodes,nbNodes,1.e-12,0./*max distance*/,-1./*min dot*/,0.,true); + res.resize(2*nbNodes); + for(int i=0;i<nbNodes;i++) + { + res[2*i]=cpy[3*i]; + res[2*i+1]=cpy[3*i+1]; + } + return ; + } + throw INTERP_KERNEL::Exception("Invalid spacedim for project2DCellOnXY !"); +} + +/*! + * low level method that checks that the 2D cell is not a butterfly cell. + */ +bool MEDCouplingPointSet::isButterfly2DCell(const std::vector<double>& res, bool isQuad, double eps) +{ + std::size_t nbOfNodes=res.size()/2; + std::vector<INTERP_KERNEL::Node *> nodes(nbOfNodes); + for(std::size_t i=0;i<nbOfNodes;i++) + { + INTERP_KERNEL::Node *tmp=new INTERP_KERNEL::Node(res[2*i],res[2*i+1]); + nodes[i]=tmp; + } + INTERP_KERNEL::QUADRATIC_PLANAR::_precision=eps; + INTERP_KERNEL::QUADRATIC_PLANAR::_arc_detection_precision=eps; + INTERP_KERNEL::QuadraticPolygon *pol=0; + if(isQuad) + pol=INTERP_KERNEL::QuadraticPolygon::BuildArcCirclePolygon(nodes); + else + pol=INTERP_KERNEL::QuadraticPolygon::BuildLinearPolygon(nodes); + bool ret=pol->isButterflyAbs(); + delete pol; + return ret; +} + +/*! + * This method compares 2 cells coming from two unstructured meshes : \a this and \a other. + * This method compares 2 cells having the same id 'cellId' in \a this and \a other. + */ +bool MEDCouplingPointSet::areCellsFrom2MeshEqual(const MEDCouplingPointSet *other, int cellId, double prec) const +{ + if(getTypeOfCell(cellId)!=other->getTypeOfCell(cellId)) + return false; + std::vector<int> c1,c2; + getNodeIdsOfCell(cellId,c1); + other->getNodeIdsOfCell(cellId,c2); + std::size_t sz=c1.size(); + if(sz!=c2.size()) + return false; + for(std::size_t i=0;i<sz;i++) + { + std::vector<double> n1,n2; + getCoordinatesOfNode(c1[0],n1); + other->getCoordinatesOfNode(c2[0],n2); + std::transform(n1.begin(),n1.end(),n2.begin(),n1.begin(),std::minus<double>()); + std::transform(n1.begin(),n1.end(),n1.begin(),std::ptr_fun<double,double>(fabs)); + if(*std::max_element(n1.begin(),n1.end())>prec) + return false; + } + return true; +} + +/*! + * Substitutes node coordinates array of \a this mesh with that of \a other mesh + * (i.e. \a this->_coords with \a other._coords) provided that coordinates of the two + * meshes match with a specified precision, else an exception is thrown and \a this + * remains unchanged. In case of success the nodal connectivity of \a this mesh + * is permuted according to new order of nodes. + * Contrary to tryToShareSameCoords() this method makes a deeper analysis of + * coordinates (and so more expensive) than simple equality. + * \param [in] other - the other mesh whose node coordinates array will be used by + * \a this mesh in case of their equality. + * \param [in] epsilon - the precision used to compare coordinates (using infinite norm). + * \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::tryToShareSameCoordsPermute(const MEDCouplingPointSet& other, double epsilon) +{ + const DataArrayDouble *coords=other.getCoords(); + if(!coords) + throw INTERP_KERNEL::Exception("MEDCouplingPointSet::tryToShareSameCoordsPermute : No coords specified in other !"); + if(!_coords) + throw INTERP_KERNEL::Exception("MEDCouplingPointSet::tryToShareSameCoordsPermute : No coords specified in this whereas there is any in other !"); + int otherNbOfNodes=other.getNumberOfNodes(); + MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> newCoords=MergeNodesArray(&other,this); + _coords->incrRef(); + MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> oldCoords=_coords; + setCoords(newCoords); + bool areNodesMerged; + int newNbOfNodes; + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> da=buildPermArrayForMergeNode(epsilon,otherNbOfNodes,areNodesMerged,newNbOfNodes); + if(!areNodesMerged) + { + setCoords(oldCoords); + throw INTERP_KERNEL::Exception("MEDCouplingPointSet::tryToShareSameCoordsPermute fails : no nodes are mergeable with specified given epsilon !"); + } + int maxId=*std::max_element(da->getConstPointer(),da->getConstPointer()+otherNbOfNodes); + const int *pt=std::find_if(da->getConstPointer()+otherNbOfNodes,da->getConstPointer()+da->getNbOfElems(),std::bind2nd(std::greater<int>(),maxId)); + if(pt!=da->getConstPointer()+da->getNbOfElems()) + { + setCoords(oldCoords); + throw INTERP_KERNEL::Exception("MEDCouplingPointSet::tryToShareSameCoordsPermute fails : some nodes in this are not in other !"); + } + setCoords(oldCoords); + renumberNodesInConn(da->getConstPointer()+otherNbOfNodes); + setCoords(coords); +} + +MEDCouplingPointSet *MEDCouplingPointSet::buildPartOfMySelf(const int *begin, const int *end, bool keepCoords) const +{ + MEDCouplingAutoRefCountObjectPtr<MEDCouplingPointSet> ret=buildPartOfMySelfKeepCoords(begin,end); + if(!keepCoords) + ret->zipCoords(); + return ret.retn(); +} + +MEDCouplingPointSet *MEDCouplingPointSet::buildPartOfMySelf2(int start, int end, int step, bool keepCoords) const +{ + MEDCouplingAutoRefCountObjectPtr<MEDCouplingPointSet> ret=buildPartOfMySelfKeepCoords2(start,end,step); + if(!keepCoords) + ret->zipCoords(); + return ret.retn(); +} + +/*! + Creates a new MEDCouplingUMesh containing some cells of \a this mesh. The cells to + copy are selected basing on specified node ids and the value of \a fullyIn + parameter. If \a fullyIn ==\c true, a cell is copied if its all nodes are in the + array \a begin of node ids. If \a fullyIn ==\c false, a cell is copied if any its + node is in the array of node ids. The created mesh shares the node coordinates array + with \a this mesh. + * \param [in] begin - the array of node ids. + * \param [in] end - a pointer to the (last+1)-th element of \a begin. + * \param [in] fullyIn - if \c true, then cells whose all nodes are in the + * array \a begin are copied, else cells whose any node is in the + * array \a begin are copied. + * \return MEDCouplingPointSet * - 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 not defined. + * \throw If any node id in \a begin is not valid. + * + * \if ENABLE_EXAMPLES + * \ref cpp_mcumesh_buildPartOfMySelfNode "Here is a C++ example".<br> + * \ref py_mcumesh_buildPartOfMySelfNode "Here is a Python example". + * \endif + */ +MEDCouplingPointSet *MEDCouplingPointSet::buildPartOfMySelfNode(const int *begin, const int *end, bool fullyIn) const +{ + DataArrayInt *cellIdsKept=0; + fillCellIdsToKeepFromNodeIds(begin,end,fullyIn,cellIdsKept); + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> cellIdsKept2(cellIdsKept); + return buildPartOfMySelf(cellIdsKept->begin(),cellIdsKept->end(),true); +} + +/*! + * Removes duplicates of cells from \a this mesh and returns an array mapping between + * new and old cell ids in "Old to New" mode. Nothing is changed in \a this mesh if no + * equal cells found. + * \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] compType - specifies a cell comparison technique. Meaning of its + * valid values [0,1,2] is as follows. + * - 0 : "exact". Two cells are considered equal \c iff they have exactly same nodal + * connectivity and type. This is the strongest policy. + * - 1 : "permuted same orientation". Two cells are considered equal \c iff they + * are based on same nodes and have the same type and orientation. + * - 2 : "nodal". Two cells are considered equal \c iff they + * are based on same nodes and have the same type. This is the weakest + * policy, it can be used by users not sensitive to cell orientation. + * \param [in] startCellId - specifies the cell id at which search for equal cells + * starts. By default it is 0, which means that all cells in \a this will be + * scanned. + * \return DataArrayInt - a new instance of DataArrayInt, of length \a + * this->getNumberOfCells() before call of this method. The caller is to + * delete this array using decrRef() as it is no more needed. + * \throw If the coordinates array is not set. + * \throw If the nodal connectivity of cells is not defined. + * \throw If the nodal connectivity includes an invalid id. + * + * \if ENABLE_EXAMPLES + * \ref cpp_mcumesh_zipConnectivityTraducer "Here is a C++ example".<br> + * \ref py_mcumesh_zipConnectivityTraducer "Here is a Python example". + * \endif + */ +DataArrayInt *MEDCouplingPointSet::zipConnectivityTraducer(int compType, int startCellId) +{ + DataArrayInt *commonCells=0,*commonCellsI=0; + findCommonCells(compType,startCellId,commonCells,commonCellsI); + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> commonCellsTmp(commonCells),commonCellsITmp(commonCellsI); + int newNbOfCells=-1; + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::BuildOld2NewArrayFromSurjectiveFormat2(getNumberOfCells(),commonCells->begin(),commonCellsI->begin(), + commonCellsI->end(),newNbOfCells); + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret2=ret->invertArrayO2N2N2O(newNbOfCells); + MEDCouplingAutoRefCountObjectPtr<MEDCouplingPointSet> self=buildPartOfMySelf(ret2->begin(),ret2->end(),true); + shallowCopyConnectivityFrom(self); + return ret.retn(); +} + +/*! + * This const method states if the nodal connectivity of this fetches all nodes in \a this. + * In other words, this method looks is there are no orphan nodes in \a this. + * \sa zipCoordsTraducer, getNodeIdsInUse, computeFetchedNodeIds. + */ +bool MEDCouplingPointSet::areAllNodesFetched() const +{ + checkFullyDefined(); + int nbNodes(getNumberOfNodes()); + std::vector<bool> fetchedNodes(nbNodes,false); + computeNodeIdsAlg(fetchedNodes); + return std::find(fetchedNodes.begin(),fetchedNodes.end(),false)==fetchedNodes.end(); +} + +/*! + * 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 MEDCouplingPointSet::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. + * + * \if ENABLE_EXAMPLES + * \ref cpp_mcumesh_checkDeepEquivalWith "Here is a C++ example".<br> + * \ref py_mcumesh_checkDeepEquivalWith "Here is a Python example". + * \endif + */ +void MEDCouplingPointSet::checkDeepEquivalWith(const MEDCouplingMesh *other, int cellCompPol, double prec, + DataArrayInt *&cellCor, DataArrayInt *&nodeCor) const +{ + if(!other) + throw INTERP_KERNEL::Exception("MEDCouplingPointSet::checkDeepEquivalWith : input is null !"); + const MEDCouplingPointSet *otherC=dynamic_cast<const MEDCouplingPointSet *>(other); + if(!otherC) + throw INTERP_KERNEL::Exception("MEDCouplingPointSet::checkDeepEquivalWith : other is not a PointSet mesh !"); + MEDCouplingAutoRefCountObjectPtr<MEDCouplingPointSet> m=dynamic_cast<MEDCouplingPointSet *>(mergeMyselfWith(otherC)); + bool areNodesMerged; + int newNbOfNodes; + int oldNbOfNodes=getNumberOfNodes(); + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> da=m->buildPermArrayForMergeNode(prec,oldNbOfNodes,areNodesMerged,newNbOfNodes); + //mergeNodes + if(!areNodesMerged && oldNbOfNodes != 0) + throw INTERP_KERNEL::Exception("checkDeepEquivalWith : Nodes are incompatible ! "); + const int *pt=std::find_if(da->getConstPointer()+oldNbOfNodes,da->getConstPointer()+da->getNbOfElems(),std::bind2nd(std::greater<int>(),oldNbOfNodes-1)); + if(pt!=da->getConstPointer()+da->getNbOfElems()) + throw INTERP_KERNEL::Exception("checkDeepEquivalWith : some nodes in other are not in this !"); + m->renumberNodes(da->getConstPointer(),newNbOfNodes); + // + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> nodeCor2=da->substr(oldNbOfNodes); + da=m->mergeNodes(prec,areNodesMerged,newNbOfNodes); + // + da=m->zipConnectivityTraducer(cellCompPol); + int nbCells=getNumberOfCells(); + if (nbCells != other->getNumberOfCells()) + throw INTERP_KERNEL::Exception("checkDeepEquivalWith : some cells in other are not in this !"); + int dan(da->getNumberOfTuples()); + if (dan) + { + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> da1(DataArrayInt::New()),da2(DataArrayInt::New()); + da1->alloc(dan/2,1); da2->alloc(dan/2,1); + std::copy(da->getConstPointer(), da->getConstPointer()+dan/2, da1->getPointer()); + std::copy(da->getConstPointer()+dan/2, da->getConstPointer()+dan, da2->getPointer()); + da1->sort(); da2->sort(); + if (!da1->isEqualWithoutConsideringStr(*da2)) + throw INTERP_KERNEL::Exception("checkDeepEquivalWith : some cells in other are not in this !"); + } + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> 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 MEDCouplingPointSet::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. + * + * \if ENABLE_EXAMPLES + * \ref cpp_mcumesh_checkDeepEquivalWith "Here is a C++ example".<br> + * \ref py_mcumesh_checkDeepEquivalWith "Here is a Python example". + * \endif + */ +void MEDCouplingPointSet::checkDeepEquivalOnSameNodesWith(const MEDCouplingMesh *other, int cellCompPol, double prec, + DataArrayInt *&cellCor) const +{ + if(!other) + throw INTERP_KERNEL::Exception("MEDCouplingPointSet::checkDeepEquivalOnSameNodesWith : input is null !"); + const MEDCouplingPointSet *otherC=dynamic_cast<const MEDCouplingPointSet *>(other); + if(!otherC) + throw INTERP_KERNEL::Exception("MEDCouplingPointSet::checkDeepEquivalOnSameNodesWith : other is not a PointSet mesh !"); + if(_coords!=otherC->_coords) + throw INTERP_KERNEL::Exception("checkDeepEquivalOnSameNodesWith : meshes do not share the same coordinates ! Use tryToShareSameCoordinates or call checkDeepEquivalWith !"); + MEDCouplingAutoRefCountObjectPtr<MEDCouplingPointSet> m=mergeMyselfWithOnSameCoords(otherC); + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> da=m->zipConnectivityTraducer(cellCompPol); + int maxId=*std::max_element(da->getConstPointer(),da->getConstPointer()+getNumberOfCells()); + const int *pt=std::find_if(da->getConstPointer()+getNumberOfCells(),da->getConstPointer()+da->getNbOfElems(),std::bind2nd(std::greater<int>(),maxId)); + if(pt!=da->getConstPointer()+da->getNbOfElems()) + { + throw INTERP_KERNEL::Exception("checkDeepEquivalOnSameNodesWith : some cells in other are not in this !"); + } + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> cellCor2=da->selectByTupleId2(getNumberOfCells(),da->getNbOfElems(),1); + cellCor=cellCor2->isIdentity()?0:cellCor2.retn(); +} + +void MEDCouplingPointSet::checkFastEquivalWith(const MEDCouplingMesh *other, double prec) const +{ + MEDCouplingMesh::checkFastEquivalWith(other,prec); + //other not null checked by the line before + const MEDCouplingPointSet *otherC=dynamic_cast<const MEDCouplingPointSet *>(other); + if(!otherC) + throw INTERP_KERNEL::Exception("MEDCouplingPointSet::checkFastEquivalWith : fails because other is not a pointset mesh !"); + int nbOfCells=getNumberOfCells(); + if(nbOfCells<1) + return ; + bool status=true; + status&=areCellsFrom2MeshEqual(otherC,0,prec); + status&=areCellsFrom2MeshEqual(otherC,nbOfCells/2,prec); + status&=areCellsFrom2MeshEqual(otherC,nbOfCells-1,prec); + if(!status) + throw INTERP_KERNEL::Exception("checkFastEquivalWith : Two meshes are not equal because on 3 test cells some difference have been detected !"); +} + +/*! + * Finds cells whose all or some nodes are in a given array of node ids. + * \param [in] begin - the array of node ids. + * \param [in] end - a pointer to the (last+1)-th element of \a begin. + * \param [in] fullyIn - if \c true, then cells whose all nodes are in the + * array \a begin are returned only, else cells whose any node is in the + * array \a begin are returned. + * \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. + * \throw If the coordinates array is not set. + * \throw If the nodal connectivity of cells is not defined. + * \throw If any cell id in \a begin is not valid. + * + * \sa MEDCouplingPointSet::getCellIdsFullyIncludedInNodeIds + * + * \if ENABLE_EXAMPLES + * \ref cpp_mcumesh_getCellIdsLyingOnNodes "Here is a C++ example".<br> + * \ref py_mcumesh_getCellIdsLyingOnNodes "Here is a Python example". + * \endif + */ +DataArrayInt *MEDCouplingPointSet::getCellIdsLyingOnNodes(const int *begin, const int *end, bool fullyIn) const +{ + DataArrayInt *cellIdsKept=0; + fillCellIdsToKeepFromNodeIds(begin,end,fullyIn,cellIdsKept); + cellIdsKept->setName(getName()); + return cellIdsKept; +} + +/*! + * Finds cells whose all nodes are in a given array of node ids. + * This method is a specialization of MEDCouplingPointSet::getCellIdsLyingOnNodes (true + * as last input argument). + * \param [in] partBg - the array of node ids. + * \param [in] partEnd - 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. + * \throw If the coordinates array is not set. + * \throw If the nodal connectivity of cells is not defined. + * \throw If any cell id in \a partBg is not valid. + * + * \sa MEDCouplingPointSet::getCellIdsLyingOnNodes + * + * \if ENABLE_EXAMPLES + * \ref cpp_mcumesh_getCellIdsFullyIncludedInNodeIds "Here is a C++ example".<br> + * \ref py_mcumesh_getCellIdsFullyIncludedInNodeIds "Here is a Python example". + * \endif + */ +DataArrayInt *MEDCouplingPointSet::getCellIdsFullyIncludedInNodeIds(const int *partBg, const int *partEnd) const +{ + return getCellIdsLyingOnNodes(partBg,partEnd,true); +} + +/*! + * Removes unused nodes (the node coordinates array is shorten) and returns an array + * mapping between new and old node ids in "Old to New" mode. -1 values in the returned + * array mean that the corresponding old node is no more used. + * \return DataArrayInt * - a new instance of DataArrayInt of length \a + * this->getNumberOfNodes() before call of this method. The caller is to + * delete this array using decrRef() as it is no more needed. + * \throw If the coordinates array is not set. + * \throw If the nodal connectivity of cells is not defined. + * \throw If the nodal connectivity includes an invalid id. + * + * \if ENABLE_EXAMPLES + * \ref cpp_mcumesh_zipCoordsTraducer "Here is a C++ example".<br> + * \ref py_mcumesh_zipCoordsTraducer "Here is a Python example". + * \endif + */ +DataArrayInt *MEDCouplingPointSet::zipCoordsTraducer() +{ + int newNbOfNodes=-1; + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> traducer=getNodeIdsInUse(newNbOfNodes); + renumberNodes(traducer->getConstPointer(),newNbOfNodes); + return traducer.retn(); +} + +/*! + * Merges nodes equal within \a precision and returns an array describing the + * permutation used to remove duplicate nodes. + * \param [in] precision - minimal absolute distance between two nodes at which they are + * considered not coincident. + * \param [out] areNodesMerged - is set to \c true if any coincident nodes removed. + * \param [out] newNbOfNodes - number of nodes remaining after the removal. + * \return DataArrayInt * - the permutation array in "Old to New" mode. For more + * info on "Old to New" mode see \ref numbering. The caller + * is to delete this array using decrRef() as it is no more needed. + * \throw If the coordinates array is not set. + * \throw If the nodal connectivity of cells is not defined. + * + * \if ENABLE_EXAMPLES + * \ref cpp_mcumesh_mergeNodes "Here is a C++ example".<br> + * \ref py_mcumesh_mergeNodes "Here is a Python example". + * \endif + */ +DataArrayInt *MEDCouplingPointSet::mergeNodes(double precision, bool& areNodesMerged, int& newNbOfNodes) +{ + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=buildPermArrayForMergeNode(precision,-1,areNodesMerged,newNbOfNodes); + if(areNodesMerged) + renumberNodes(ret->begin(),newNbOfNodes); + return ret.retn(); +} + +/*! + * Merges nodes equal within \a precision and returns an array describing the + * permutation used to remove duplicate nodes. In contrast to mergeNodes(), location + * of merged nodes is changed to be at their barycenter. + * \param [in] precision - minimal absolute distance between two nodes at which they are + * considered not coincident. + * \param [out] areNodesMerged - is set to \c true if any coincident nodes removed. + * \param [out] newNbOfNodes - number of nodes remaining after the removal. + * \return DataArrayInt * - the permutation array in "Old to New" mode. For more + * info on "Old to New" mode see \ref numbering. The caller + * is to delete this array using decrRef() as it is no more needed. + * \throw If the coordinates array is not set. + * \throw If the nodal connectivity of cells is not defined. + * + * \if ENABLE_EXAMPLES + * \ref cpp_mcumesh_mergeNodes "Here is a C++ example".<br> + * \ref py_mcumesh_mergeNodes "Here is a Python example". + * \endif + */ +DataArrayInt *MEDCouplingPointSet::mergeNodes2(double precision, bool& areNodesMerged, int& newNbOfNodes) +{ + DataArrayInt *ret=buildPermArrayForMergeNode(precision,-1,areNodesMerged,newNbOfNodes); + if(areNodesMerged) + renumberNodes2(ret->getConstPointer(),newNbOfNodes); + return ret; +} diff --git a/src/medtool/src/MEDCoupling/MEDCouplingPointSet.hxx b/src/medtool/src/MEDCoupling/MEDCouplingPointSet.hxx new file mode 100644 index 000000000..21c830d2f --- /dev/null +++ b/src/medtool/src/MEDCoupling/MEDCouplingPointSet.hxx @@ -0,0 +1,162 @@ +// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 +// 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_MEDCOUPLINGPOINTSET_HXX__ +#define __PARAMEDMEM_MEDCOUPLINGPOINTSET_HXX__ + +#include "MEDCoupling.hxx" +#include "MEDCouplingMesh.hxx" + +#include "InterpKernelHashMap.hxx" + +#include <vector> + +namespace INTERP_KERNEL +{ + class DirectedBoundingBox; +} + +namespace ParaMEDMEM +{ + class DataArrayInt; + class DataArrayDouble; + + /*! + * This class is abstract and not instanciable. + * ParaMEDMEM::MEDCouplingUMesh class inherits from this class. + * This class aggregates an array '_coords' containing nodes coordinates. + * So all operations on coordinates are managed by this class. + * This is the case for example for following methods : + * rotation, translation, scaling, getNodeIdsNearPoint, boundingbox... + */ + class MEDCouplingPointSet : public MEDCouplingMesh + { + protected: + MEDCOUPLING_EXPORT MEDCouplingPointSet(); + MEDCOUPLING_EXPORT MEDCouplingPointSet(const MEDCouplingPointSet& other, bool deepCopy); + MEDCOUPLING_EXPORT ~MEDCouplingPointSet(); + public: + MEDCOUPLING_EXPORT void updateTime() const; + MEDCOUPLING_EXPORT std::size_t getHeapMemorySizeWithoutChildren() const; + MEDCOUPLING_EXPORT std::vector<const BigMemoryObject *> getDirectChildrenWithNull() const; + MEDCOUPLING_EXPORT int getNumberOfNodes() const; + MEDCOUPLING_EXPORT int getSpaceDimension() const; + MEDCOUPLING_EXPORT void setCoords(const DataArrayDouble *coords); + MEDCOUPLING_EXPORT const DataArrayDouble *getCoords() const { return _coords; } + MEDCOUPLING_EXPORT DataArrayDouble *getCoords() { return _coords; } + MEDCOUPLING_EXPORT DataArrayDouble *getCoordinatesAndOwner() const; + MEDCOUPLING_EXPORT void copyTinyStringsFrom(const MEDCouplingMesh *other); + MEDCOUPLING_EXPORT bool isEqualIfNotWhy(const MEDCouplingMesh *other, double prec, std::string& reason) const; + MEDCOUPLING_EXPORT bool isEqualWithoutConsideringStr(const MEDCouplingMesh *other, double prec) const; + MEDCOUPLING_EXPORT void checkFastEquivalWith(const MEDCouplingMesh *other, double prec) const; + MEDCOUPLING_EXPORT void checkDeepEquivalWith(const MEDCouplingMesh *other, int cellCompPol, double prec, + DataArrayInt *&cellCor, DataArrayInt *&nodeCor) const; + MEDCOUPLING_EXPORT void checkDeepEquivalOnSameNodesWith(const MEDCouplingMesh *other, int cellCompPol, double prec, + DataArrayInt *&cellCor) const; + MEDCOUPLING_EXPORT bool areCoordsEqualIfNotWhy(const MEDCouplingPointSet& other, double prec, std::string& reason) const; + MEDCOUPLING_EXPORT bool areCoordsEqual(const MEDCouplingPointSet& other, double prec) const; + MEDCOUPLING_EXPORT bool areCoordsEqualWithoutConsideringStr(const MEDCouplingPointSet& other, double prec) const; + MEDCOUPLING_EXPORT virtual MEDCouplingPointSet *deepCpyConnectivityOnly() const = 0; + MEDCOUPLING_EXPORT virtual void shallowCopyConnectivityFrom(const MEDCouplingPointSet *other) = 0; + MEDCOUPLING_EXPORT virtual DataArrayInt *mergeNodes(double precision, bool& areNodesMerged, int& newNbOfNodes); + MEDCOUPLING_EXPORT virtual DataArrayInt *mergeNodes2(double precision, bool& areNodesMerged, int& newNbOfNodes); + MEDCOUPLING_EXPORT virtual MEDCouplingPointSet *mergeMyselfWithOnSameCoords(const MEDCouplingPointSet *other) const = 0; + MEDCOUPLING_EXPORT virtual void computeNodeIdsAlg(std::vector<bool>& nodeIdsInUse) const = 0; + MEDCOUPLING_EXPORT void getCoordinatesOfNode(int nodeId, std::vector<double>& coo) const; + MEDCOUPLING_EXPORT DataArrayInt *buildPermArrayForMergeNode(double precision, int limitNodeId, bool& areNodesMerged, int& newNbOfNodes) const; + MEDCOUPLING_EXPORT DataArrayInt *getNodeIdsNearPoint(const double *pos, double eps) const; + MEDCOUPLING_EXPORT void getNodeIdsNearPoints(const double *pos, int nbOfPoints, double eps, DataArrayInt *& c, DataArrayInt *& cI) const; + MEDCOUPLING_EXPORT void findCommonNodes(double prec, int limitNodeId, DataArrayInt *&comm, DataArrayInt *&commIndex) const; + MEDCOUPLING_EXPORT virtual void findCommonCells(int compType, int startCellId, DataArrayInt *& commonCellsArr, DataArrayInt *& commonCellsIArr) const = 0; + MEDCOUPLING_EXPORT DataArrayInt *buildNewNumberingFromCommonNodesFormat(const DataArrayInt *comm, const DataArrayInt *commIndex, + int& newNbOfNodes) const; + MEDCOUPLING_EXPORT void getBoundingBox(double *bbox) const; + MEDCOUPLING_EXPORT void zipCoords(); + MEDCOUPLING_EXPORT double getCaracteristicDimension() const; + MEDCOUPLING_EXPORT void recenterForMaxPrecision(double eps); + MEDCOUPLING_EXPORT void rotate(const double *center, const double *vector, double angle); + MEDCOUPLING_EXPORT void translate(const double *vector); + MEDCOUPLING_EXPORT void scale(const double *point, double factor); + MEDCOUPLING_EXPORT void changeSpaceDimension(int newSpaceDim, double dftVal=0.); + MEDCOUPLING_EXPORT void tryToShareSameCoords(const MEDCouplingPointSet& other, double epsilon); + MEDCOUPLING_EXPORT void duplicateNodesInCoords(const int *nodeIdsToDuplicateBg, const int *nodeIdsToDuplicateEnd); + MEDCOUPLING_EXPORT virtual void tryToShareSameCoordsPermute(const MEDCouplingPointSet& other, double epsilon); + MEDCOUPLING_EXPORT void findNodesOnPlane(const double *pt, const double *vec, double eps, std::vector<int>& nodes) const; + MEDCOUPLING_EXPORT void findNodesOnLine(const double *pt, const double *vec, double eps, std::vector<int>& nodes) const; + MEDCOUPLING_EXPORT static DataArrayDouble *MergeNodesArray(const MEDCouplingPointSet *m1, const MEDCouplingPointSet *m2); + MEDCOUPLING_EXPORT static DataArrayDouble *MergeNodesArray(const std::vector<const MEDCouplingPointSet *>& ms); + MEDCOUPLING_EXPORT static MEDCouplingPointSet *BuildInstanceFromMeshType(MEDCouplingMeshType type); + MEDCOUPLING_EXPORT static void Rotate2DAlg(const double *center, double angle, int nbNodes, double *coords); + MEDCOUPLING_EXPORT static void Rotate3DAlg(const double *center, const double *vect, double angle, int nbNodes, double *coords); + MEDCOUPLING_EXPORT static DataArrayInt *ComputeNbOfInteractionsWithSrcCells(const MEDCouplingPointSet *srcMesh, const MEDCouplingPointSet *trgMesh, double eps); + MEDCOUPLING_EXPORT MEDCouplingMesh *buildPart(const int *start, const int *end) const; + MEDCOUPLING_EXPORT MEDCouplingMesh *buildPartAndReduceNodes(const int *start, const int *end, DataArrayInt*& arr) const; + MEDCOUPLING_EXPORT MEDCouplingMesh *buildPartRange(int beginCellIds, int endCellIds, int stepCellIds) const; + MEDCOUPLING_EXPORT MEDCouplingMesh *buildPartRangeAndReduceNodes(int beginCellIds, int endCellIds, int stepCellIds, int& beginOut, int& endOut, int& stepOut, DataArrayInt*& arr) const; + MEDCOUPLING_EXPORT DataArrayInt *getCellIdsFullyIncludedInNodeIds(const int *partBg, const int *partEnd) const; + MEDCOUPLING_EXPORT DataArrayInt *getCellIdsLyingOnNodes(const int *begin, const int *end, bool fullyIn) const; + MEDCOUPLING_EXPORT virtual MEDCouplingPointSet *buildPartOfMySelf(const int *start, const int *end, bool keepCoords=true) const; + MEDCOUPLING_EXPORT virtual MEDCouplingPointSet *buildPartOfMySelf2(int start, int end, int step, bool keepCoords=true) const; + MEDCOUPLING_EXPORT virtual MEDCouplingPointSet *buildPartOfMySelfKeepCoords(const int *begin, const int *end) const = 0; + MEDCOUPLING_EXPORT virtual MEDCouplingPointSet *buildPartOfMySelfKeepCoords2(int start, int end, int step) const = 0; + MEDCOUPLING_EXPORT virtual MEDCouplingPointSet *buildPartOfMySelfNode(const int *start, const int *end, bool fullyIn) const; + MEDCOUPLING_EXPORT virtual MEDCouplingPointSet *buildFacePartOfMySelfNode(const int *start, const int *end, bool fullyIn) const = 0; + MEDCOUPLING_EXPORT virtual DataArrayInt *findBoundaryNodes() const = 0; + MEDCOUPLING_EXPORT virtual MEDCouplingPointSet *buildBoundaryMesh(bool keepCoords) const = 0; + MEDCOUPLING_EXPORT virtual int getNumberOfNodesInCell(int cellId) const = 0; + MEDCOUPLING_EXPORT virtual DataArrayInt *computeFetchedNodeIds() const = 0; + MEDCOUPLING_EXPORT virtual DataArrayInt *getNodeIdsInUse(int& nbrOfNodesInUse) const = 0; + MEDCOUPLING_EXPORT virtual void fillCellIdsToKeepFromNodeIds(const int *begin, const int *end, bool fullyIn, DataArrayInt *&cellIdsKeptArr) const = 0; + MEDCOUPLING_EXPORT virtual void renumberNodesInConn(const int *newNodeNumbersO2N) = 0; + MEDCOUPLING_EXPORT virtual void renumberNodesInConn(const INTERP_KERNEL::HashMap<int,int>& newNodeNumbersO2N) = 0; + MEDCOUPLING_EXPORT virtual void renumberNodesWithOffsetInConn(int offset) = 0; + MEDCOUPLING_EXPORT virtual void renumberNodes(const int *newNodeNumbers, int newNbOfNodes); + MEDCOUPLING_EXPORT virtual void renumberNodes2(const int *newNodeNumbers, int newNbOfNodes); + MEDCOUPLING_EXPORT virtual bool isEmptyMesh(const std::vector<int>& tinyInfo) const = 0; + MEDCOUPLING_EXPORT virtual void checkFullyDefined() const = 0; + MEDCOUPLING_EXPORT void getTinySerializationInformation(std::vector<double>& tinyInfoD, std::vector<int>& tinyInfo, std::vector<std::string>& littleStrings) const; + MEDCOUPLING_EXPORT void resizeForUnserialization(const std::vector<int>& tinyInfo, DataArrayInt *a1, DataArrayDouble *a2, std::vector<std::string>& littleStrings) const; + MEDCOUPLING_EXPORT void serialize(DataArrayInt *&a1, DataArrayDouble *&a2) const; + MEDCOUPLING_EXPORT void unserialization(const std::vector<double>& tinyInfoD, const std::vector<int>& tinyInfo, const DataArrayInt *a1, DataArrayDouble *a2, + const std::vector<std::string>& littleStrings); + MEDCOUPLING_EXPORT virtual DataArrayDouble *getBoundingBoxForBBTree(double arcDetEps=1e-12) const = 0; + MEDCOUPLING_EXPORT virtual DataArrayInt *getCellsInBoundingBox(const double *bbox, double eps) const = 0; + MEDCOUPLING_EXPORT virtual DataArrayInt *getCellsInBoundingBox(const INTERP_KERNEL::DirectedBoundingBox& bbox, double eps) = 0; + MEDCOUPLING_EXPORT virtual MEDCouplingFieldDouble *computeDiameterField() const = 0; + MEDCOUPLING_EXPORT virtual DataArrayInt *zipCoordsTraducer(); + MEDCOUPLING_EXPORT virtual DataArrayInt *zipConnectivityTraducer(int compType, int startCellId=0); + MEDCOUPLING_EXPORT virtual bool areAllNodesFetched() const; + //tools + public: + MEDCOUPLING_EXPORT bool areCellsFrom2MeshEqual(const MEDCouplingPointSet *other, int cellId, double prec) const; + protected: + MEDCOUPLING_EXPORT void checkCoherency() const; + MEDCOUPLING_EXPORT static bool intersectsBoundingBox(const double* bb1, const double* bb2, int dim, double eps); + MEDCOUPLING_EXPORT static bool intersectsBoundingBox(const INTERP_KERNEL::DirectedBoundingBox& bb1, const double* bb2, int dim, double eps); + MEDCOUPLING_EXPORT void rotate2D(const double *center, double angle); + MEDCOUPLING_EXPORT void rotate3D(const double *center, const double *vect, double angle); + MEDCOUPLING_EXPORT void project2DCellOnXY(const int *startConn, const int *endConn, std::vector<double>& res) const; + MEDCOUPLING_EXPORT static bool isButterfly2DCell(const std::vector<double>& res, bool isQuad, double eps); + protected: + DataArrayDouble *_coords; + }; +} + +#endif diff --git a/src/medtool/src/MEDCoupling/MEDCouplingRefCountObject.cxx b/src/medtool/src/MEDCoupling/MEDCouplingRefCountObject.cxx new file mode 100644 index 000000000..080d4d265 --- /dev/null +++ b/src/medtool/src/MEDCoupling/MEDCouplingRefCountObject.cxx @@ -0,0 +1,275 @@ +// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 +// 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 "MEDCouplingRefCountObject.hxx" +#include "MEDtool_version.h" + +#include <sstream> +#include <algorithm> + +using namespace ParaMEDMEM; + +const char *ParaMEDMEM::MEDCouplingVersionStr() +{ + return MEDTOOL_VERSION_STR; +} + +int ParaMEDMEM::MEDCouplingVersion() +{ + return MEDTOOL_VERSION; +} + +void ParaMEDMEM::MEDCouplingVersionMajMinRel(int& maj, int& minor, int& releas) +{ + int ver=MEDTOOL_VERSION; + maj=(ver & 0xFF0000) >> 16; + minor=(ver & 0xFF00) >> 8; + releas=(ver & 0xFF); +} + +int ParaMEDMEM::MEDCouplingSizeOfVoidStar() +{ + return 8*sizeof(std::size_t); +} + +/*! + * If true is returned it is a LittleEndian machine. + * If false it is a BigEndian machine. + * \return the coding mode of integers of the machine. + */ +bool ParaMEDMEM::MEDCouplingByteOrder() +{ + unsigned int x(1); + unsigned char *xc(reinterpret_cast<unsigned char *>(&x)); + return xc[0]==1; +} + +const char *ParaMEDMEM::MEDCouplingByteOrderStr() +{ + static const char LITTLEENDIAN_STR[]="LittleEndian"; + static const char BIGENDIAN_STR[]="BigEndian"; + if(MEDCouplingByteOrder()) + return LITTLEENDIAN_STR; + else + return BIGENDIAN_STR; +} + +//= + +std::size_t BigMemoryObject::getHeapMemorySize() const +{ + std::size_t ret(getHeapMemorySizeWithoutChildren()); + std::vector<const BigMemoryObject *> v(getDirectChildren()); + std::set<const BigMemoryObject *> s1,s2(v.begin(),v.end()); + return ret+GetHeapMemoryOfSet(s1,s2); +} + +/*! + * This method returns all the progeny of \a this (this is \b not included in returned vector). + * All the progeny means all the subobjects (children), subsubobjects (little children), ... of \a this. + * The elements in returned array are reported only once even if they appear several times in the progeny of \a this. + */ +std::vector<const BigMemoryObject *> BigMemoryObject::getAllTheProgeny() const +{ + std::vector<const BigMemoryObject *> s1(getDirectChildren()); + std::vector<const BigMemoryObject *> ret; + while(!s1.empty()) + { + ret.insert(ret.end(),s1.begin(),s1.end()); + std::vector<const BigMemoryObject *> s3; + for(std::vector<const BigMemoryObject *>::const_iterator it0=s1.begin();it0!=s1.end();it0++) + { + std::vector<const BigMemoryObject *> s2; + if(*it0) + s2=(*it0)->getDirectChildren(); + for(std::vector<const BigMemoryObject *>::const_iterator it1=s2.begin();it1!=s2.end();it1++) + { + if(*it1) + if(std::find(ret.begin(),ret.end(),*it1)==ret.end()) + s3.push_back(*it1); + } + } + s1=s3; + } + return ret; +} + +/*! + * This method scan all the progeny of \a this (\a this excluded) to see if \a obj is part of it. + * If obj is NULL false is returned. + * \sa BigMemoryObject::getAllTheProgeny + */ +bool BigMemoryObject::isObjectInTheProgeny(const BigMemoryObject *obj) const +{ + if(!obj) + return false; + std::vector<const BigMemoryObject *> objs(getAllTheProgeny()); + return std::find(objs.begin(),objs.end(),obj)!=objs.end(); +} + +std::size_t BigMemoryObject::GetHeapMemorySizeOfObjs(const std::vector<const BigMemoryObject *>& objs) +{ + std::size_t ret(0); + std::set<const BigMemoryObject *> s1,s2; + for(std::vector<const BigMemoryObject *>::const_iterator it0=objs.begin();it0!=objs.end();it0++) + { + if(*it0) + if(s1.find(*it0)==s1.end()) + { + std::vector<const BigMemoryObject *> vTmp((*it0)->getDirectChildren()); + s2.insert(vTmp.begin(),vTmp.end()); + ret+=(*it0)->getHeapMemorySizeWithoutChildren(); + s1.insert(*it0); + } + } + return ret+GetHeapMemoryOfSet(s1,s2); +} + +std::size_t BigMemoryObject::GetHeapMemoryOfSet(std::set<const BigMemoryObject *>& s1, std::set<const BigMemoryObject *>& s2) +{ + std::size_t ret(0); + while(!s2.empty()) + { + std::set<const BigMemoryObject *> s3; + for(std::set<const BigMemoryObject *>::const_iterator it=s2.begin();it!=s2.end();it++) + { + if(s1.find(*it)==s1.end()) + { + ret+=(*it)->getHeapMemorySizeWithoutChildren(); + s1.insert(*it); + std::vector<const BigMemoryObject *> v2((*it)->getDirectChildren()); + for(std::vector<const BigMemoryObject *>::const_iterator it2=v2.begin();it2!=v2.end();it2++) + if(s1.find(*it2)==s1.end()) + s3.insert(*it2); + } + } + s2=s3; + } + return ret; +} + +std::string BigMemoryObject::getHeapMemorySizeStr() const +{ + static const char *UNITS[4]={"B","kB","MB","GB"}; + std::size_t m(getHeapMemorySize()); + std::ostringstream oss; oss.precision(3); + std::size_t remain(0); + int i(0); + for(;i<4;i++) + { + if(m<1024) + { + oss << m; + if(remain!=0) + { + std::ostringstream oss2; oss2 << std::fixed << ((double)remain)/1024.; + std::string s(oss2.str()); + s=s.substr(1,4); + std::size_t pos(s.find_last_not_of('0')); + if(pos==4) + oss << s; + else + oss << s.substr(0,pos+1); + } + oss << " " << UNITS[i]; + break; + } + else + { + if(i!=3) + { + remain=(m%1024); + m/=1024; + } + } + } + if(i==4) + oss << m << " " << UNITS[3]; + return oss.str(); +} + +std::vector<const BigMemoryObject *> BigMemoryObject::getDirectChildren() const +{ + std::vector<const BigMemoryObject *> ret; + std::vector<const BigMemoryObject *> retWithNull(getDirectChildrenWithNull()); + for(std::vector<const BigMemoryObject *>::const_iterator it=retWithNull.begin();it!=retWithNull.end();it++) + if(*it) + ret.push_back(*it); + return ret; +} + +BigMemoryObject::~BigMemoryObject() +{ +} + +//= + +RefCountObjectOnly::RefCountObjectOnly():_cnt(1) +{ +} + +RefCountObjectOnly::RefCountObjectOnly(const RefCountObjectOnly& other):_cnt(1) +{ +} + +bool RefCountObjectOnly::decrRef() const +{ + bool ret=((--_cnt)==0); + if(ret) + delete this; + return ret; +} + +void RefCountObjectOnly::incrRef() const +{ + _cnt++; +} + +int RefCountObjectOnly::getRCValue() const +{ + return _cnt; +} + +RefCountObjectOnly::~RefCountObjectOnly() +{ +} + +/*! + * Do nothing here ! It is not a bug ( I hope :) ) because all subclasses that + * copies using operator= should not copy the ref counter of \a other ! + */ +RefCountObjectOnly& RefCountObjectOnly::operator=(const RefCountObjectOnly& other) +{ + return *this; +} + +//= + +RefCountObject::RefCountObject() +{ +} + +RefCountObject::RefCountObject(const RefCountObject& other):RefCountObjectOnly(other) +{ +} + +RefCountObject::~RefCountObject() +{ +} diff --git a/src/medtool/src/MEDCoupling/MEDCouplingRefCountObject.hxx b/src/medtool/src/MEDCoupling/MEDCouplingRefCountObject.hxx new file mode 100644 index 000000000..4eea72a52 --- /dev/null +++ b/src/medtool/src/MEDCoupling/MEDCouplingRefCountObject.hxx @@ -0,0 +1,106 @@ +// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 +// 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_MEDCOUPLINGREFCOUNTOBJECT_HXX__ +#define __PARAMEDMEM_MEDCOUPLINGREFCOUNTOBJECT_HXX__ + +#include "MEDCoupling.hxx" + +#include <set> +#include <vector> +#include <string> +#include <cstddef> + +namespace ParaMEDMEM +{ + typedef enum + { + C_DEALLOC = 2, + CPP_DEALLOC = 3 + } DeallocType; + + typedef enum + { + ON_CELLS = 0, + ON_NODES = 1, + ON_GAUSS_PT = 2, + ON_GAUSS_NE = 3, + ON_NODES_KR = 4 + } TypeOfField; + + typedef enum + { + NO_TIME = 4, + ONE_TIME = 5, + LINEAR_TIME = 6, + CONST_ON_TIME_INTERVAL = 7 + } TypeOfTimeDiscretization; + + typedef bool (*FunctionToEvaluate)(const double *pos, double *res); + + MEDCOUPLING_EXPORT const char *MEDCouplingVersionStr(); + MEDCOUPLING_EXPORT int MEDCouplingVersion(); + MEDCOUPLING_EXPORT void MEDCouplingVersionMajMinRel(int& maj, int& minor, int& releas); + MEDCOUPLING_EXPORT int MEDCouplingSizeOfVoidStar(); + MEDCOUPLING_EXPORT bool MEDCouplingByteOrder(); + MEDCOUPLING_EXPORT const char *MEDCouplingByteOrderStr(); + + class BigMemoryObject + { + public: + MEDCOUPLING_EXPORT std::size_t getHeapMemorySize() const; + MEDCOUPLING_EXPORT std::string getHeapMemorySizeStr() const; + MEDCOUPLING_EXPORT std::vector<const BigMemoryObject *> getDirectChildren() const; + MEDCOUPLING_EXPORT std::vector<const BigMemoryObject *> getAllTheProgeny() const; + MEDCOUPLING_EXPORT bool isObjectInTheProgeny(const BigMemoryObject *obj) const; + MEDCOUPLING_EXPORT static std::size_t GetHeapMemorySizeOfObjs(const std::vector<const BigMemoryObject *>& objs); + MEDCOUPLING_EXPORT virtual std::size_t getHeapMemorySizeWithoutChildren() const = 0; + MEDCOUPLING_EXPORT virtual std::vector<const BigMemoryObject *> getDirectChildrenWithNull() const = 0; + MEDCOUPLING_EXPORT virtual ~BigMemoryObject(); + private: + static std::size_t GetHeapMemoryOfSet(std::set<const BigMemoryObject *>& s1, std::set<const BigMemoryObject *>& s2); + }; + + class RefCountObjectOnly + { + protected: + MEDCOUPLING_EXPORT RefCountObjectOnly(); + MEDCOUPLING_EXPORT RefCountObjectOnly(const RefCountObjectOnly& other); + public: + MEDCOUPLING_EXPORT bool decrRef() const; + MEDCOUPLING_EXPORT void incrRef() const; + MEDCOUPLING_EXPORT int getRCValue() const; + MEDCOUPLING_EXPORT RefCountObjectOnly& operator=(const RefCountObjectOnly& other); + protected: + virtual ~RefCountObjectOnly(); + private: + mutable int _cnt; + }; + + class RefCountObject : public RefCountObjectOnly, public BigMemoryObject + { + protected: + MEDCOUPLING_EXPORT RefCountObject(); + MEDCOUPLING_EXPORT RefCountObject(const RefCountObject& other); + MEDCOUPLING_EXPORT virtual ~RefCountObject(); + }; +} + +#endif diff --git a/src/medtool/src/MEDCoupling/MEDCouplingRemapper.cxx b/src/medtool/src/MEDCoupling/MEDCouplingRemapper.cxx new file mode 100644 index 000000000..18741778f --- /dev/null +++ b/src/medtool/src/MEDCoupling/MEDCouplingRemapper.cxx @@ -0,0 +1,1312 @@ +// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 +// 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 "MEDCouplingRemapper.hxx" +#include "MEDCouplingMemArray.hxx" +#include "MEDCouplingFieldDouble.hxx" +#include "MEDCouplingFieldTemplate.hxx" +#include "MEDCouplingFieldDiscretization.hxx" +#include "MEDCouplingExtrudedMesh.hxx" +#include "MEDCouplingCMesh.hxx" +#include "MEDCouplingNormalizedUnstructuredMesh.txx" +#include "MEDCouplingNormalizedCartesianMesh.txx" + +#include "Interpolation1D.txx" +#include "Interpolation2DCurve.hxx" +#include "Interpolation2D.txx" +#include "Interpolation3D.txx" +#include "Interpolation3DSurf.hxx" +#include "Interpolation2D1D.txx" +#include "Interpolation3D2D.txx" +#include "InterpolationCU.txx" +#include "InterpolationCC.txx" + +using namespace ParaMEDMEM; + +MEDCouplingRemapper::MEDCouplingRemapper():_src_ft(0),_target_ft(0),_interp_matrix_pol(IK_ONLY_PREFERED),_nature_of_deno(NoNature),_time_deno_update(0) +{ +} + +MEDCouplingRemapper::~MEDCouplingRemapper() +{ + releaseData(false); +} + +/*! + * This method is the second step of the remapping process. The remapping process works in three phases : + * + * - Set remapping options appropriately + * - The computation of remapping matrix + * - Apply the matrix vector multiply to obtain the result of the remapping + * + * This method performs the second step (computation of remapping matrix) which may be CPU-time consuming. This phase is also the most critical (where the most tricky algorithm) in the remapping process. + * Strictly speaking to perform the computation of the remapping matrix the field templates source-side and target-side is required (which is the case of MEDCouplingRemapper::prepareEx). + * So this method is less precise but a more user friendly way to compute a remapping matrix. + * + * \param [in] srcMesh the source mesh + * \param [in] targetMesh the target mesh + * \param [in] method A string obtained by aggregation of the spatial discretisation string representation of source field and target field. The string representation is those returned by MEDCouplingFieldDiscretization::getStringRepr. + * Example : "P0" is for cell discretization. "P1" is for node discretization. So "P0P1" for \a method parameter means from a source cell field (lying on \a srcMesh) to a target node field (lying on \a targetMesh). + * + * \sa MEDCouplingRemapper::prepareEx + */ +int MEDCouplingRemapper::prepare(const MEDCouplingMesh *srcMesh, const MEDCouplingMesh *targetMesh, const std::string& method) +{ + if(!srcMesh || !targetMesh) + throw INTERP_KERNEL::Exception("MEDCouplingRemapper::prepare : presence of NULL input pointer !"); + std::string srcMethod,targetMethod; + INTERP_KERNEL::Interpolation<INTERP_KERNEL::Interpolation3D>::CheckAndSplitInterpolationMethod(method,srcMethod,targetMethod); + MEDCouplingAutoRefCountObjectPtr<MEDCouplingFieldTemplate> src=MEDCouplingFieldTemplate::New(MEDCouplingFieldDiscretization::GetTypeOfFieldFromStringRepr(srcMethod)); + src->setMesh(srcMesh); + MEDCouplingAutoRefCountObjectPtr<MEDCouplingFieldTemplate> target=MEDCouplingFieldTemplate::New(MEDCouplingFieldDiscretization::GetTypeOfFieldFromStringRepr(targetMethod)); + target->setMesh(targetMesh); + return prepareEx(src,target); +} + +/*! + * This method is the generalization of MEDCouplingRemapper::prepare. Indeed, MEDCouplingFieldTemplate instances gives all required information to compute the remapping matrix. + * This method must be used instead of MEDCouplingRemapper::prepare if Gauss point to Gauss point must be applied. + * + * \param [in] src is the field template source side. + * \param [in] target is the field template target side. + * + * \sa MEDCouplingRemapper::prepare + */ +int MEDCouplingRemapper::prepareEx(const MEDCouplingFieldTemplate *src, const MEDCouplingFieldTemplate *target) +{ + 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_ft=const_cast<MEDCouplingFieldTemplate *>(src); _src_ft->incrRef(); + _target_ft=const_cast<MEDCouplingFieldTemplate *>(target); _target_ft->incrRef(); + if(isInterpKernelOnlyOrNotOnly()) + return prepareInterpKernelOnly(); + else + return prepareNotInterpKernelOnly(); +} + +int MEDCouplingRemapper::prepareInterpKernelOnly() +{ + int meshInterpType=((int)_src_ft->getMesh()->getType()*16)+(int)_target_ft->getMesh()->getType(); + switch(meshInterpType) + { + case 90: + case 91: + case 165: + case 181: + case 170: + case 171: + case 186: + case 187: + case 85://Unstructured-Unstructured + return prepareInterpKernelOnlyUU(); + case 167: + case 183: + case 87://Unstructured-Cartesian + return prepareInterpKernelOnlyUC(); + case 122: + case 123: + case 117://Cartesian-Unstructured + return prepareInterpKernelOnlyCU(); + case 119://Cartesian-Cartesian + return prepareInterpKernelOnlyCC(); + case 136://Extruded-Extruded + return prepareInterpKernelOnlyEE(); + default: + 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::prepareNotInterpKernelOnly() +{ + 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()); + } + } +} + +/*! + * This method performs the operation source to target using matrix computed in ParaMEDMEM::MEDCouplingRemapper::prepare method. + * If meshes of \b srcField and \b targetField do not match exactly those given into \ref ParaMEDMEM::MEDCouplingRemapper::prepare "prepare method" an exception will be thrown. + * + * \param [in] srcField is the source field from which the interpolation will be done. The mesh into \b srcField should be the same than those specified on ParaMEDMEM::MEDCouplingRemapper::prepare. + * \param [in/out] targetField the destination field with the allocated array in which all tuples will be overwritten. + * \param [in] dftValue is the value that will be assigned in the targetField to each entity of target mesh (entity depending on the method selected on prepare invocation) that is not intercepted by any entity of source mesh. + * For example in "P0P0" case (cell-cell) if a cell in target mesh is not overlapped by any source cell the \a dftValue value will be attached on that cell in the returned \a targetField. In some cases a target + * cell not intercepted by any source cell is a bug so in this case it is advised to set a huge value (1e300 for example) to \a dftValue to quickly point to the problem. But for users doing parallelism a target cell can + * be intercepted by a source cell on a different process. In this case 0. assigned to \a dftValue is more appropriate. + * + * \sa transferField + */ +void MEDCouplingRemapper::transfer(const MEDCouplingFieldDouble *srcField, MEDCouplingFieldDouble *targetField, double dftValue) +{ + if(!srcField || !targetField) + throw INTERP_KERNEL::Exception("MEDCouplingRemapper::transfer : input field must be both not NULL !"); + transferUnderground(srcField,targetField,true,dftValue); +} + +/*! + * This method is equivalent to ParaMEDMEM::MEDCouplingRemapper::transfer except that here \b targetField is a in/out parameter. + * If an entity (cell for example) in targetField is not fetched by any entity (cell for example) of \b srcField, the value in targetField is + * let unchanged. + * This method requires that \b targetField was fully defined and allocated. If the array is not allocated an exception will be thrown. + * + * \param [in] srcField is the source field from which the interpolation will be done. The mesh into \b srcField should be the same than those specified on ParaMEDMEM::MEDCouplingRemapper::prepare. + * \param [in,out] targetField the destination field with the allocated array in which only tuples whose entities are fetched by interpolation will be overwritten only. + */ +void MEDCouplingRemapper::partialTransfer(const MEDCouplingFieldDouble *srcField, MEDCouplingFieldDouble *targetField) +{ + if(!srcField || !targetField) + throw INTERP_KERNEL::Exception("MEDCouplingRemapper::partialTransfer : input field must be both not NULL !"); + transferUnderground(srcField,targetField,false,std::numeric_limits<double>::max()); +} + +void MEDCouplingRemapper::reverseTransfer(MEDCouplingFieldDouble *srcField, const MEDCouplingFieldDouble *targetField, double dftValue) +{ + if(!srcField || !targetField) + throw INTERP_KERNEL::Exception("MEDCouplingRemapper::reverseTransfer : input fields must be both not NULL !"); + checkPrepare(); + targetField->checkCoherency(); + if(_src_ft->getDiscretization()->getStringRepr()!=srcField->getDiscretization()->getStringRepr()) + throw INTERP_KERNEL::Exception("Incoherency with prepare call for source field"); + 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 !"); + if(targetField->getNumberOfTuplesExpected()!=_target_ft->getNumberOfTuplesExpected()) + { + std::ostringstream oss; + oss << "MEDCouplingRemapper::reverseTransfer : in given source field the number of tuples required is " << _target_ft->getNumberOfTuplesExpected() << " (on prepare) and number of tuples in given target field is " << targetField->getNumberOfTuplesExpected(); + oss << " ! It appears that the target support is not the same between the prepare and the transfer !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + DataArrayDouble *array(srcField->getArray()); + int trgNbOfCompo=targetField->getNumberOfComponents(); + if(array) + { + srcField->checkCoherency(); + if(trgNbOfCompo!=srcField->getNumberOfTuplesExpected()) + throw INTERP_KERNEL::Exception("Number of components mismatch !"); + } + else + { + MEDCouplingAutoRefCountObjectPtr<DataArrayDouble > tmp(DataArrayDouble::New()); + tmp->alloc(srcField->getNumberOfTuplesExpected(),trgNbOfCompo); + srcField->setArray(tmp); + } + computeDeno(srcField->getNature(),srcField,targetField); + double *resPointer(srcField->getArray()->getPointer()); + const double *inputPointer=targetField->getArray()->getConstPointer(); + computeReverseProduct(inputPointer,trgNbOfCompo,dftValue,resPointer); +} + +/*! + * This method performs the operation source to target using matrix computed in ParaMEDMEM::MEDCouplingRemapper::prepare method. + * If mesh of \b srcField does not match exactly those given into \ref ParaMEDMEM::MEDCouplingRemapper::prepare "prepare method" an exception will be thrown. + * + * \param [in] srcField is the source field from which the interpolation will be done. The mesh into \b srcField should be the same than those specified on ParaMEDMEM::MEDCouplingRemapper::prepare. + * \param [in] dftValue is the value that will be assigned in the targetField to each entity of target mesh (entity depending on the method selected on prepare invocation) that is not intercepted by any entity of source mesh. + * For example in "P0P0" case (cell-cell) if a cell in target mesh is not overlapped by any source cell the \a dftValue value will be attached on that cell in the returned \a targetField. In some cases a target + * cell not intercepted by any source cell is a bug so in this case it is advised to set a huge value (1e300 for example) to \a dftValue to quickly point to the problem. But for users doing parallelism a target cell can + * be intercepted by a source cell on a different process. In this case 0. assigned to \a dftValue is more appropriate. + * \return destination field to be deallocated by the caller. + * + * \sa transfer + */ +MEDCouplingFieldDouble *MEDCouplingRemapper::transferField(const MEDCouplingFieldDouble *srcField, double dftValue) +{ + checkPrepare(); + if(!srcField) + throw INTERP_KERNEL::Exception("MEDCouplingRemapper::transferField : input srcField is NULL !"); + srcField->checkCoherency(); + if(_src_ft->getDiscretization()->getStringRepr()!=srcField->getDiscretization()->getStringRepr()) + throw INTERP_KERNEL::Exception("Incoherency with prepare call for source field"); + MEDCouplingFieldDouble *ret=MEDCouplingFieldDouble::New(*_target_ft,srcField->getTimeDiscretization()); + ret->setNature(srcField->getNature()); + 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) +{ + if(!targetField) + throw INTERP_KERNEL::Exception("MEDCouplingRemapper::transferField : input targetField is NULL !"); + targetField->checkCoherency(); + checkPrepare(); + if(_target_ft->getDiscretization()->getStringRepr()!=targetField->getDiscretization()->getStringRepr()) + throw INTERP_KERNEL::Exception("Incoherency with prepare call for target field"); + MEDCouplingFieldDouble *ret=MEDCouplingFieldDouble::New(*_src_ft,targetField->getTimeDiscretization()); + ret->setNature(targetField->getNature()); + 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); +} + +/*! + * 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) +{ + 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() +{ + const MEDCouplingPointSet *src_mesh=static_cast<const MEDCouplingPointSet *>(_src_ft->getMesh()); + const MEDCouplingPointSet *target_mesh=static_cast<const MEDCouplingPointSet *>(_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) + srcSpaceDim=src_mesh->getSpaceDimension(); + const int trgMeshDim=target_mesh->getMeshDimension(); + int trgSpaceDim=-1; + if(trgMeshDim!=-1) + trgSpaceDim=target_mesh->getSpaceDimension(); + if(trgSpaceDim!=srcSpaceDim) + if(trgSpaceDim!=-1 && srcSpaceDim!=-1) + throw INTERP_KERNEL::Exception("Incoherent space dimension detected between target and source."); + int nbCols; + if(srcMeshDim==1 && trgMeshDim==1 && srcSpaceDim==1) + { + 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); + } + 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); + } + 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); + } + 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); + } + 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); + } + else if(srcMeshDim==3 && trgMeshDim==1 && srcSpaceDim==3) + { + if(getIntersectionType()!=INTERP_KERNEL::PointLocator) + throw INTERP_KERNEL::Exception("Invalid interpolation requested between 3D and 1D ! Select PointLocator as intersection type !"); + 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); + } + else if(srcMeshDim==1 && trgMeshDim==3 && srcSpaceDim==3) + { + if(getIntersectionType()!=INTERP_KERNEL::PointLocator) + throw INTERP_KERNEL::Exception("Invalid interpolation requested between 3D and 1D ! Select PointLocator as intersection type !"); + MEDCouplingNormalizedUnstructuredMesh<3,3> source_mesh_wrapper(src_mesh); + MEDCouplingNormalizedUnstructuredMesh<3,3> target_mesh_wrapper(target_mesh); + INTERP_KERNEL::Interpolation3D interpolation(*this); + std::vector<std::map<int,double> > matrixTmp; + std::string revMethod(BuildMethodFrom(trgMeth,srcMeth)); + nbCols=interpolation.interpolateMeshes(target_mesh_wrapper,source_mesh_wrapper,matrixTmp,revMethod); + ReverseMatrix(matrixTmp,nbCols,_matrix); + nbCols=matrixTmp.size(); + } + else if(srcMeshDim==2 && trgMeshDim==1 && srcSpaceDim==2) + { + if(getIntersectionType()==INTERP_KERNEL::PointLocator) + { + 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); + } + else + { + MEDCouplingNormalizedUnstructuredMesh<2,2> source_mesh_wrapper(src_mesh); + MEDCouplingNormalizedUnstructuredMesh<2,2> target_mesh_wrapper(target_mesh); + INTERP_KERNEL::Interpolation2D1D interpolation(*this); + std::vector<std::map<int,double> > matrixTmp; + std::string revMethod(BuildMethodFrom(trgMeth,srcMeth)); + nbCols=interpolation.interpolateMeshes(target_mesh_wrapper,source_mesh_wrapper,matrixTmp,revMethod); + ReverseMatrix(matrixTmp,nbCols,_matrix); + nbCols=matrixTmp.size(); + INTERP_KERNEL::Interpolation2D1D::DuplicateFacesType duplicateFaces=interpolation.retrieveDuplicateFaces(); + if(!duplicateFaces.empty()) + { + std::ostringstream oss; oss << "An unexpected situation happend ! For the following 1D Cells are part of edges shared by 2D cells :\n"; + for(std::map<int,std::set<int> >::const_iterator it=duplicateFaces.begin();it!=duplicateFaces.end();it++) + { + oss << "1D Cell #" << (*it).first << " is part of common edge of following 2D cells ids : "; + std::copy((*it).second.begin(),(*it).second.end(),std::ostream_iterator<int>(oss," ")); + oss << std::endl; + } + } + } + } + else if(srcMeshDim==1 && trgMeshDim==2 && srcSpaceDim==2) + { + if(getIntersectionType()==INTERP_KERNEL::PointLocator) + { + MEDCouplingNormalizedUnstructuredMesh<2,2> source_mesh_wrapper(src_mesh); + MEDCouplingNormalizedUnstructuredMesh<2,2> target_mesh_wrapper(target_mesh); + INTERP_KERNEL::Interpolation2D interpolation(*this); + std::vector<std::map<int,double> > matrixTmp; + std::string revMethod(BuildMethodFrom(trgMeth,srcMeth)); + nbCols=interpolation.interpolateMeshes(target_mesh_wrapper,source_mesh_wrapper,matrixTmp,revMethod); + ReverseMatrix(matrixTmp,nbCols,_matrix); + nbCols=matrixTmp.size(); + } + else + { + 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); + INTERP_KERNEL::Interpolation2D1D::DuplicateFacesType duplicateFaces=interpolation.retrieveDuplicateFaces(); + if(!duplicateFaces.empty()) + { + std::ostringstream oss; oss << "An unexpected situation happend ! For the following 1D Cells are part of edges shared by 2D cells :\n"; + for(std::map<int,std::set<int> >::const_iterator it=duplicateFaces.begin();it!=duplicateFaces.end();it++) + { + oss << "1D Cell #" << (*it).first << " is part of common edge of following 2D cells ids : "; + std::copy((*it).second.begin(),(*it).second.end(),std::ostream_iterator<int>(oss," ")); + oss << std::endl; + } + } + } + } + else if(srcMeshDim==2 && trgMeshDim==3 && srcSpaceDim==3) + { + 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); + INTERP_KERNEL::Interpolation3D2D::DuplicateFacesType duplicateFaces=interpolation.retrieveDuplicateFaces(); + if(!duplicateFaces.empty()) + { + std::ostringstream oss; oss << "An unexpected situation happend ! For the following 2D Cells are part of edges shared by 3D cells :\n"; + for(std::map<int,std::set<int> >::const_iterator it=duplicateFaces.begin();it!=duplicateFaces.end();it++) + { + oss << "2D Cell #" << (*it).first << " is part of common face of following 3D cells ids : "; + std::copy((*it).second.begin(),(*it).second.end(),std::ostream_iterator<int>(oss," ")); + oss << std::endl; + } + } + } + else if(srcMeshDim==3 && trgMeshDim==2 && srcSpaceDim==3) + { + MEDCouplingNormalizedUnstructuredMesh<3,3> source_mesh_wrapper(src_mesh); + MEDCouplingNormalizedUnstructuredMesh<3,3> target_mesh_wrapper(target_mesh); + INTERP_KERNEL::Interpolation3D2D interpolation(*this); + std::vector<std::map<int,double> > matrixTmp; + std::string revMethod(BuildMethodFrom(trgMeth,srcMeth)); + nbCols=interpolation.interpolateMeshes(target_mesh_wrapper,source_mesh_wrapper,matrixTmp,revMethod); + ReverseMatrix(matrixTmp,nbCols,_matrix); + nbCols=matrixTmp.size(); + INTERP_KERNEL::Interpolation3D2D::DuplicateFacesType duplicateFaces=interpolation.retrieveDuplicateFaces(); + if(!duplicateFaces.empty()) + { + std::ostringstream oss; oss << "An unexpected situation happend ! For the following 2D Cells are part of edges shared by 3D cells :\n"; + for(std::map<int,std::set<int> >::const_iterator it=duplicateFaces.begin();it!=duplicateFaces.end();it++) + { + oss << "2D Cell #" << (*it).first << " is part of common face of following 3D cells ids : "; + std::copy((*it).second.begin(),(*it).second.end(),std::ostream_iterator<int>(oss," ")); + oss << std::endl; + } + } + } + else if(trgMeshDim==-1) + { + if(srcMeshDim==2 && srcSpaceDim==2) + { + MEDCouplingNormalizedUnstructuredMesh<2,2> source_mesh_wrapper(src_mesh); + INTERP_KERNEL::Interpolation2D interpolation(*this); + nbCols=interpolation.toIntegralUniform(source_mesh_wrapper,_matrix,srcMeth); + } + 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,srcMeth); + } + 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,srcMeth); + } + else + throw INTERP_KERNEL::Exception("No interpolation available for the given mesh and space dimension of source mesh to -1D targetMesh"); + } + else if(srcMeshDim==-1) + { + if(trgMeshDim==2 && trgSpaceDim==2) + { + MEDCouplingNormalizedUnstructuredMesh<2,2> source_mesh_wrapper(target_mesh); + INTERP_KERNEL::Interpolation2D interpolation(*this); + nbCols=interpolation.fromIntegralUniform(source_mesh_wrapper,_matrix,trgMeth); + } + 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,trgMeth); + } + 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,trgMeth); + } + else + throw INTERP_KERNEL::Exception("No interpolation available for the given mesh and space dimension of source mesh from -1D sourceMesh"); + } + else + throw INTERP_KERNEL::Exception("No interpolation available for the given mesh and space dimension"); + _deno_multiply.clear(); + _deno_multiply.resize(_matrix.size()); + _deno_reverse_multiply.clear(); + _deno_reverse_multiply.resize(nbCols); + declareAsNew(); + return 1; +} + +int MEDCouplingRemapper::prepareInterpKernelOnlyEE() +{ + std::string srcMeth,trgMeth; + std::string methC=checkAndGiveInterpolationMethodStr(srcMeth,trgMeth); + const MEDCouplingExtrudedMesh *src_mesh=static_cast<const MEDCouplingExtrudedMesh *>(_src_ft->getMesh()); + const MEDCouplingExtrudedMesh *target_mesh=static_cast<const MEDCouplingExtrudedMesh *>(_target_ft->getMesh()); + if(methC!="P0P0") + 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<std::map<int,double> > matrix2D; + int nbCols2D=interpolation2D.interpolateMeshes(source_mesh_wrapper,target_mesh_wrapper,matrix2D,methC); + MEDCouplingUMesh *s1D,*t1D; + double v[3]; + MEDCouplingExtrudedMesh::Project1DMeshes(src_mesh->getMesh1D(),target_mesh->getMesh1D(),getPrecision(),s1D,t1D,v); + MEDCouplingNormalizedUnstructuredMesh<1,1> s1DWrapper(s1D); + MEDCouplingNormalizedUnstructuredMesh<1,1> t1DWrapper(t1D); + std::vector<std::map<int,double> > matrix1D; + INTERP_KERNEL::Interpolation1D interpolation1D(*this); + int nbCols1D=interpolation1D.interpolateMeshes(s1DWrapper,t1DWrapper,matrix1D,methC); + s1D->decrRef(); + t1D->decrRef(); + buildFinalInterpolationMatrixByConvolution(matrix1D,matrix2D,src_mesh->getMesh3DIds()->getConstPointer(),nbCols2D,nbCols1D, + target_mesh->getMesh3DIds()->getConstPointer()); + // + _deno_multiply.clear(); + _deno_multiply.resize(_matrix.size()); + _deno_reverse_multiply.clear(); + _deno_reverse_multiply.resize(nbCols2D*nbCols1D); + declareAsNew(); + return 1; +} + +int MEDCouplingRemapper::prepareInterpKernelOnlyUC() +{ + std::string srcMeth,trgMeth; + std::string methodCpp=checkAndGiveInterpolationMethodStr(srcMeth,trgMeth); + if(methodCpp!="P0P0") + throw INTERP_KERNEL::Exception("MEDCouplingRemapper::prepareInterpKernelOnlyUC : only P0P0 interpolation supported for the moment !"); + const MEDCouplingUMesh *src_mesh=static_cast<const MEDCouplingUMesh *>(_src_ft->getMesh()); + const MEDCouplingCMesh *target_mesh=static_cast<const MEDCouplingCMesh *>(_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::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<std::map<int,double> > res; + switch(srcMeshDim) + { + case 1: + { + MEDCouplingNormalizedCartesianMesh<1> targetWrapper(target_mesh); + MEDCouplingNormalizedUnstructuredMesh<1,1> sourceWrapper(src_mesh); + INTERP_KERNEL::InterpolationCU myInterpolator(*this); + myInterpolator.interpolateMeshes(targetWrapper,sourceWrapper,res,"P0P0"); + break; + } + case 2: + { + MEDCouplingNormalizedCartesianMesh<2> targetWrapper(target_mesh); + MEDCouplingNormalizedUnstructuredMesh<2,2> sourceWrapper(src_mesh); + INTERP_KERNEL::InterpolationCU myInterpolator(*this); + myInterpolator.interpolateMeshes(targetWrapper,sourceWrapper,res,"P0P0"); + break; + } + case 3: + { + MEDCouplingNormalizedCartesianMesh<3> targetWrapper(target_mesh); + MEDCouplingNormalizedUnstructuredMesh<3,3> sourceWrapper(src_mesh); + INTERP_KERNEL::InterpolationCU myInterpolator(*this); + myInterpolator.interpolateMeshes(targetWrapper,sourceWrapper,res,"P0P0"); + break; + } + default: + throw INTERP_KERNEL::Exception("MEDCouplingRemapper::prepareInterpKernelOnlyUC : only dimension 1 2 or 3 supported !"); + } + ReverseMatrix(res,target_mesh->getNumberOfCells(),_matrix); + nullifiedTinyCoeffInCrudeMatrixAbs(0.); + // + _deno_multiply.clear(); + _deno_multiply.resize(_matrix.size()); + _deno_reverse_multiply.clear(); + _deno_reverse_multiply.resize(src_mesh->getNumberOfCells()); + declareAsNew(); + return 1; +} + +int MEDCouplingRemapper::prepareInterpKernelOnlyCU() +{ + std::string srcMeth,trgMeth; + std::string methodCpp=checkAndGiveInterpolationMethodStr(srcMeth,trgMeth); + if(methodCpp!="P0P0") + throw INTERP_KERNEL::Exception("MEDCouplingRemapper::prepareInterpKernelOnlyCU : only P0P0 interpolation supported for the moment !"); + const MEDCouplingCMesh *src_mesh=static_cast<const MEDCouplingCMesh *>(_src_ft->getMesh()); + const MEDCouplingUMesh *target_mesh=static_cast<const MEDCouplingUMesh *>(_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::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: + { + MEDCouplingNormalizedCartesianMesh<1> sourceWrapper(src_mesh); + MEDCouplingNormalizedUnstructuredMesh<1,1> targetWrapper(target_mesh); + INTERP_KERNEL::InterpolationCU myInterpolator(*this); + myInterpolator.interpolateMeshes(sourceWrapper,targetWrapper,_matrix,"P0P0"); + break; + } + case 2: + { + MEDCouplingNormalizedCartesianMesh<2> sourceWrapper(src_mesh); + MEDCouplingNormalizedUnstructuredMesh<2,2> targetWrapper(target_mesh); + INTERP_KERNEL::InterpolationCU myInterpolator(*this); + myInterpolator.interpolateMeshes(sourceWrapper,targetWrapper,_matrix,"P0P0"); + break; + } + case 3: + { + MEDCouplingNormalizedCartesianMesh<3> sourceWrapper(src_mesh); + MEDCouplingNormalizedUnstructuredMesh<3,3> targetWrapper(target_mesh); + INTERP_KERNEL::InterpolationCU myInterpolator(*this); + myInterpolator.interpolateMeshes(sourceWrapper,targetWrapper,_matrix,"P0P0"); + break; + } + default: + throw INTERP_KERNEL::Exception("MEDCouplingRemapper::prepareInterpKernelOnlyCU : only dimension 1 2 or 3 supported !"); + } + nullifiedTinyCoeffInCrudeMatrixAbs(0.); + // + _deno_multiply.clear(); + _deno_multiply.resize(_matrix.size()); + _deno_reverse_multiply.clear(); + _deno_reverse_multiply.resize(src_mesh->getNumberOfCells()); + declareAsNew(); + return 1; +} + +int MEDCouplingRemapper::prepareInterpKernelOnlyCC() +{ + std::string srcMeth,trgMeth; + std::string methodCpp=checkAndGiveInterpolationMethodStr(srcMeth,trgMeth); + if(methodCpp!="P0P0") + throw INTERP_KERNEL::Exception("MEDCouplingRemapper::prepareInterpKernelOnlyCC : only P0P0 interpolation supported for the moment !"); + const MEDCouplingCMesh *src_mesh=static_cast<const MEDCouplingCMesh *>(_src_ft->getMesh()); + const MEDCouplingCMesh *target_mesh=static_cast<const MEDCouplingCMesh *>(_target_ft->getMesh()); + const int srcMeshDim=src_mesh->getMeshDimension(); + const int trgMeshDim=target_mesh->getMeshDimension(); + if(trgMeshDim!=srcMeshDim) + throw INTERP_KERNEL::Exception("MEDCouplingRemapper::prepareInterpKernelOnlyCC : dim of target cartesian should be equal to dim of source cartesian dimension !"); + switch(srcMeshDim) + { + case 1: + { + MEDCouplingNormalizedCartesianMesh<1> sourceWrapper(src_mesh); + MEDCouplingNormalizedCartesianMesh<1> targetWrapper(target_mesh); + INTERP_KERNEL::InterpolationCC myInterpolator(*this); + myInterpolator.interpolateMeshes(sourceWrapper,targetWrapper,_matrix,"P0P0"); + break; + } + case 2: + { + MEDCouplingNormalizedCartesianMesh<2> sourceWrapper(src_mesh); + MEDCouplingNormalizedCartesianMesh<2> targetWrapper(target_mesh); + INTERP_KERNEL::InterpolationCC myInterpolator(*this); + myInterpolator.interpolateMeshes(sourceWrapper,targetWrapper,_matrix,"P0P0"); + break; + } + case 3: + { + MEDCouplingNormalizedCartesianMesh<3> sourceWrapper(src_mesh); + MEDCouplingNormalizedCartesianMesh<3> targetWrapper(target_mesh); + INTERP_KERNEL::InterpolationCC myInterpolator(*this); + myInterpolator.interpolateMeshes(sourceWrapper,targetWrapper,_matrix,"P0P0"); + break; + } + default: + throw INTERP_KERNEL::Exception("MEDCouplingRemapper::prepareInterpKernelOnlyCC : only dimension 1 2 or 3 supported !"); + } + nullifiedTinyCoeffInCrudeMatrixAbs(0.); + // + _deno_multiply.clear(); + _deno_multiply.resize(_matrix.size()); + _deno_reverse_multiply.clear(); + _deno_reverse_multiply.resize(src_mesh->getNumberOfCells()); + declareAsNew(); + return 1; +} + +int MEDCouplingRemapper::prepareNotInterpKernelOnlyGaussGauss() +{ + 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<DataArrayDouble> trgLoc=_target_ft->getLocalizationOfDiscr(); + const double *trgLocPtr=trgLoc->begin(); + int trgSpaceDim=trgLoc->getNumberOfComponents(); + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> 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<DataArrayDouble> srcLoc=_src_ft->getLocalizationOfDiscr(); + const double *srcLocPtr=srcLoc->begin(); + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> eltsArr,eltsIndexArr; + int trgNbOfGaussPts=trgLoc->getNumberOfTuples(); + _matrix.resize(trgNbOfGaussPts); + _src_ft->getMesh()->getCellsContainingPoints(trgLoc->begin(),trgNbOfGaussPts,getPrecision(),eltsArr,eltsIndexArr); + const int *elts(eltsArr->begin()),*eltsIndex(eltsIndexArr->begin()); + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> nbOfSrcCellsShTrgPts(eltsIndexArr->deltaShiftIndex()); + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> 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<double>::max(); + int srcEntry=-1; + for(int srcId=srcOffsetArrPtr[srcCellId];srcId<srcOffsetArrPtr[srcCellId+1];srcId++) + { + const double *ptSrc=srcLocPtr+trgSpaceDim*srcId; + double tmp=0.; + for(int i=0;i<trgSpaceDim;i++) + tmp+=(ptTrg[i]-ptSrc[i])*(ptTrg[i]-ptSrc[i]); + if(tmp<dist) + { dist=tmp; srcEntry=srcId; } + } + _matrix[*trgId][srcEntry]=1.; + } + if(ids0->getNumberOfTuples()!=trgNbOfGaussPts) + { + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> orphanTrgIds=nbOfSrcCellsShTrgPts->getIdsEqual(0); + MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> orphanTrg=trgLoc->selectByTupleId(orphanTrgIds->begin(),orphanTrgIds->end()); + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> 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) +{ + 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 +{ + 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<INTERP_KERNEL::Interpolation3D>::CheckAndSplitInterpolationMethod(method,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 +{ + 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 +{ + 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(); + return BuildMethodFrom(srcMeth,trgMeth); +} + +std::string MEDCouplingRemapper::BuildMethodFrom(const std::string& meth1, const std::string& meth2) +{ + std::string method(meth1); method+=meth2; + return method; +} + +void MEDCouplingRemapper::releaseData(bool matrixSuppression) +{ + _src_ft=0; + _target_ft=0; + if(matrixSuppression) + { + _matrix.clear(); + _deno_multiply.clear(); + _deno_reverse_multiply.clear(); + } +} + +void MEDCouplingRemapper::transferUnderground(const MEDCouplingFieldDouble *srcField, MEDCouplingFieldDouble *targetField, bool isDftVal, double dftValue) +{ + if(!srcField || !targetField) + throw INTERP_KERNEL::Exception("MEDCouplingRemapper::transferUnderground : srcField or targetField is NULL !"); + srcField->checkCoherency(); + checkPrepare(); + if(_src_ft->getDiscretization()->getStringRepr()!=srcField->getDiscretization()->getStringRepr()) + throw INTERP_KERNEL::Exception("Incoherency with prepare call for source field"); + 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 !"); + if(srcField->getNumberOfTuplesExpected()!=_src_ft->getNumberOfTuplesExpected()) + { + std::ostringstream oss; + oss << "MEDCouplingRemapper::transferUnderground : in given source field the number of tuples required is " << _src_ft->getNumberOfTuplesExpected() << " (on prepare) and number of tuples in given source field is " << srcField->getNumberOfTuplesExpected(); + oss << " ! It appears that the source support is not the same between the prepare and the transfer !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + DataArrayDouble *array(targetField->getArray()); + int srcNbOfCompo(srcField->getNumberOfComponents()); + if(array) + { + targetField->checkCoherency(); + if(srcNbOfCompo!=targetField->getNumberOfComponents()) + throw INTERP_KERNEL::Exception("Number of components mismatch !"); + } + else + { + if(!isDftVal) + throw INTERP_KERNEL::Exception("MEDCouplingRemapper::partialTransfer : This method requires that the array of target field exists ! Allocate it or call MEDCouplingRemapper::transfer instead !"); + MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> tmp(DataArrayDouble::New()); + tmp->alloc(targetField->getNumberOfTuples(),srcNbOfCompo); + targetField->setArray(tmp); + } + computeDeno(srcField->getNature(),srcField,targetField); + double *resPointer(targetField->getArray()->getPointer()); + const double *inputPointer(srcField->getArray()->getConstPointer()); + computeProduct(inputPointer,srcNbOfCompo,isDftVal,dftValue,resPointer); +} + +void MEDCouplingRemapper::computeDeno(NatureOfField nat, const MEDCouplingFieldDouble *srcField, const MEDCouplingFieldDouble *trgField) +{ + if(nat==NoNature) + return computeDenoFromScratch(nat,srcField,trgField); + else if(nat!=_nature_of_deno) + return computeDenoFromScratch(nat,srcField,trgField); + else if(nat==_nature_of_deno && _time_deno_update!=getTimeOfThis()) + return computeDenoFromScratch(nat,srcField,trgField); +} + +void MEDCouplingRemapper::computeDenoFromScratch(NatureOfField nat, const MEDCouplingFieldDouble *srcField, const MEDCouplingFieldDouble *trgField) +{ + _nature_of_deno=nat; + _time_deno_update=getTimeOfThis(); + switch(_nature_of_deno) + { + case ConservativeVolumic: + { + ComputeRowSumAndColSum(_matrix,_deno_multiply,_deno_reverse_multiply); + break; + } + case Integral: + { + 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) + { + double *denoRPtr2=denoR->getArray()->getPointer(); + denoRPtr2[0]=std::accumulate(denoPtr,denoPtr+deno->getNumberOfTuples(),0.); + } + if(srcField->getMesh()->getMeshDimension()==-1) + { + double *denoPtr2=deno->getArray()->getPointer(); + denoPtr2[0]=std::accumulate(denoRPtr,denoRPtr+denoR->getNumberOfTuples(),0.); + } + int idx=0; + for(std::vector<std::map<int,double> >::const_iterator iter1=_matrix.begin();iter1!=_matrix.end();iter1++,idx++) + for(std::map<int,double>::const_iterator iter2=(*iter1).begin();iter2!=(*iter1).end();iter2++) + { + _deno_multiply[idx][(*iter2).first]=denoPtr[(*iter2).first]; + _deno_reverse_multiply[(*iter2).first][idx]=denoRPtr[idx]; + } + deno->decrRef(); + denoR->decrRef(); + break; + } + case IntegralGlobConstraint: + { + ComputeColSumAndRowSum(_matrix,_deno_multiply,_deno_reverse_multiply); + break; + } + case RevIntegral: + { + 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) + { + double *denoRPtr2=denoR->getArray()->getPointer(); + denoRPtr2[0]=std::accumulate(denoPtr,denoPtr+deno->getNumberOfTuples(),0.); + } + if(srcField->getMesh()->getMeshDimension()==-1) + { + double *denoPtr2=deno->getArray()->getPointer(); + denoPtr2[0]=std::accumulate(denoRPtr,denoRPtr+denoR->getNumberOfTuples(),0.); + } + int idx=0; + for(std::vector<std::map<int,double> >::const_iterator iter1=_matrix.begin();iter1!=_matrix.end();iter1++,idx++) + for(std::map<int,double>::const_iterator iter2=(*iter1).begin();iter2!=(*iter1).end();iter2++) + { + _deno_multiply[idx][(*iter2).first]=denoPtr[idx]; + _deno_reverse_multiply[(*iter2).first][idx]=denoRPtr[(*iter2).first]; + } + deno->decrRef(); + denoR->decrRef(); + break; + } + case NoNature: + throw INTERP_KERNEL::Exception("No nature specified ! Select one !"); + } +} + +void MEDCouplingRemapper::computeProduct(const double *inputPointer, int inputNbOfCompo, bool isDftVal, double dftValue, double *resPointer) +{ + int idx=0; + double *tmp=new double[inputNbOfCompo]; + for(std::vector<std::map<int,double> >::const_iterator iter1=_matrix.begin();iter1!=_matrix.end();iter1++,idx++) + { + if((*iter1).empty()) + { + if(isDftVal) + std::fill(resPointer+idx*inputNbOfCompo,resPointer+(idx+1)*inputNbOfCompo,dftValue); + continue; + } + else + std::fill(resPointer+idx*inputNbOfCompo,resPointer+(idx+1)*inputNbOfCompo,0.); + std::map<int,double>::const_iterator iter3=_deno_multiply[idx].begin(); + for(std::map<int,double>::const_iterator iter2=(*iter1).begin();iter2!=(*iter1).end();iter2++,iter3++) + { + std::transform(inputPointer+(*iter2).first*inputNbOfCompo,inputPointer+((*iter2).first+1)*inputNbOfCompo,tmp,std::bind2nd(std::multiplies<double>(),(*iter2).second/(*iter3).second)); + std::transform(tmp,tmp+inputNbOfCompo,resPointer+idx*inputNbOfCompo,resPointer+idx*inputNbOfCompo,std::plus<double>()); + } + } + delete [] tmp; +} + +void MEDCouplingRemapper::computeReverseProduct(const double *inputPointer, int inputNbOfCompo, double dftValue, double *resPointer) +{ + std::vector<bool> isReached(_deno_reverse_multiply.size(),false); + int idx=0; + double *tmp=new double[inputNbOfCompo]; + std::fill(resPointer,resPointer+inputNbOfCompo*_deno_reverse_multiply.size(),0.); + for(std::vector<std::map<int,double> >::const_iterator iter1=_matrix.begin();iter1!=_matrix.end();iter1++,idx++) + { + for(std::map<int,double>::const_iterator iter2=(*iter1).begin();iter2!=(*iter1).end();iter2++) + { + isReached[(*iter2).first]=true; + std::transform(inputPointer+idx*inputNbOfCompo,inputPointer+(idx+1)*inputNbOfCompo,tmp,std::bind2nd(std::multiplies<double>(),(*iter2).second/_deno_reverse_multiply[(*iter2).first][idx])); + std::transform(tmp,tmp+inputNbOfCompo,resPointer+((*iter2).first)*inputNbOfCompo,resPointer+((*iter2).first)*inputNbOfCompo,std::plus<double>()); + } + } + delete [] tmp; + idx=0; + for(std::vector<bool>::const_iterator iter3=isReached.begin();iter3!=isReached.end();iter3++,idx++) + if(!*iter3) + std::fill(resPointer+idx*inputNbOfCompo,resPointer+(idx+1)*inputNbOfCompo,dftValue); +} + +void MEDCouplingRemapper::ReverseMatrix(const std::vector<std::map<int,double> >& matIn, int nbColsMatIn, std::vector<std::map<int,double> >& matOut) +{ + matOut.resize(nbColsMatIn); + int id=0; + for(std::vector<std::map<int,double> >::const_iterator iter1=matIn.begin();iter1!=matIn.end();iter1++,id++) + for(std::map<int,double>::const_iterator iter2=(*iter1).begin();iter2!=(*iter1).end();iter2++) + matOut[(*iter2).first][id]=(*iter2).second; +} + +void MEDCouplingRemapper::ComputeRowSumAndColSum(const std::vector<std::map<int,double> >& matrixDeno, + std::vector<std::map<int,double> >& deno, std::vector<std::map<int,double> >& denoReverse) +{ + std::map<int,double> values; + int idx=0; + for(std::vector<std::map<int,double> >::const_iterator iter1=matrixDeno.begin();iter1!=matrixDeno.end();iter1++,idx++) + { + double sum=0.; + for(std::map<int,double>::const_iterator iter2=(*iter1).begin();iter2!=(*iter1).end();iter2++) + { + sum+=(*iter2).second; + values[(*iter2).first]+=(*iter2).second; + } + for(std::map<int,double>::const_iterator iter2=(*iter1).begin();iter2!=(*iter1).end();iter2++) + deno[idx][(*iter2).first]=sum; + } + idx=0; + for(std::vector<std::map<int,double> >::const_iterator iter1=matrixDeno.begin();iter1!=matrixDeno.end();iter1++,idx++) + { + for(std::map<int,double>::const_iterator iter2=(*iter1).begin();iter2!=(*iter1).end();iter2++) + denoReverse[(*iter2).first][idx]=values[(*iter2).first]; + } +} + +void MEDCouplingRemapper::ComputeColSumAndRowSum(const std::vector<std::map<int,double> >& matrixDeno, + std::vector<std::map<int,double> >& deno, std::vector<std::map<int,double> >& denoReverse) +{ + std::map<int,double> values; + int idx=0; + for(std::vector<std::map<int,double> >::const_iterator iter1=matrixDeno.begin();iter1!=matrixDeno.end();iter1++,idx++) + { + double sum=0.; + for(std::map<int,double>::const_iterator iter2=(*iter1).begin();iter2!=(*iter1).end();iter2++) + { + sum+=(*iter2).second; + values[(*iter2).first]+=(*iter2).second; + } + for(std::map<int,double>::const_iterator iter2=(*iter1).begin();iter2!=(*iter1).end();iter2++) + denoReverse[(*iter2).first][idx]=sum; + } + idx=0; + for(std::vector<std::map<int,double> >::const_iterator iter1=matrixDeno.begin();iter1!=matrixDeno.end();iter1++,idx++) + { + for(std::map<int,double>::const_iterator iter2=(*iter1).begin();iter2!=(*iter1).end();iter2++) + deno[idx][(*iter2).first]=values[(*iter2).first]; + } +} + +void MEDCouplingRemapper::buildFinalInterpolationMatrixByConvolution(const std::vector< std::map<int,double> >& m1D, + const std::vector< std::map<int,double> >& m2D, + const int *corrCellIdSrc, int nbOf2DCellsSrc, int nbOf1DCellsSrc, + const int *corrCellIdTrg) +{ + int nbOf2DCellsTrg=m2D.size(); + int nbOf1DCellsTrg=m1D.size(); + int nbOf3DCellsTrg=nbOf2DCellsTrg*nbOf1DCellsTrg; + _matrix.resize(nbOf3DCellsTrg); + int id2R=0; + for(std::vector< std::map<int,double> >::const_iterator iter2R=m2D.begin();iter2R!=m2D.end();iter2R++,id2R++) + { + for(std::map<int,double>::const_iterator iter2C=(*iter2R).begin();iter2C!=(*iter2R).end();iter2C++) + { + int id1R=0; + for(std::vector< std::map<int,double> >::const_iterator iter1R=m1D.begin();iter1R!=m1D.end();iter1R++,id1R++) + { + for(std::map<int,double>::const_iterator iter1C=(*iter1R).begin();iter1C!=(*iter1R).end();iter1C++) + { + _matrix[corrCellIdTrg[id1R*nbOf2DCellsTrg+id2R]][corrCellIdSrc[(*iter1C).first*nbOf2DCellsSrc+(*iter2C).first]]=(*iter1C).second*((*iter2C).second); + } + } + } + } +} + +void MEDCouplingRemapper::PrintMatrix(const std::vector<std::map<int,double> >& m) +{ + int id=0; + for(std::vector<std::map<int,double> >::const_iterator iter1=m.begin();iter1!=m.end();iter1++,id++) + { + std::cout << "Target Cell # " << id << " : "; + for(std::map<int,double>::const_iterator iter2=(*iter1).begin();iter2!=(*iter1).end();iter2++) + std::cout << "(" << (*iter2).first << "," << (*iter2).second << "), "; + std::cout << std::endl; + } +} + +const std::vector<std::map<int,double> >& MEDCouplingRemapper::getCrudeMatrix() const +{ + return _matrix; +} + +/*! + * Returns the number of columns of matrix returned by MEDCouplingRemapper::getCrudeMatrix method. + */ +int MEDCouplingRemapper::getNumberOfColsOfMatrix() const +{ + return (int)_deno_reverse_multiply.size(); +} + +/*! + * This method is supposed to be called , if needed, right after MEDCouplingRemapper::prepare or MEDCouplingRemapper::prepareEx. + * If not the behaviour is unpredictable. + * This method works on precomputed \a this->_matrix. All coefficients in the matrix is lower than \a maxValAbs this coefficient is + * set to 0. That is to say that its entry disappear from the map storing the corresponding row in the data storage of sparse crude matrix. + * This method is useful to correct at a high level some problems linked to precision. Indeed, with some \ref NatureOfField "natures of field" some threshold effect + * can occur. + * + * \param [in] maxValAbs is a limit behind which a coefficient is set to 0. \a maxValAbs is expected to be positive, if not this method do nothing. + * \return a positive value that tells the number of coefficients put to 0. The 0 returned value means that the matrix has remained unchanged. + * \sa MEDCouplingRemapper::nullifiedTinyCoeffInCrudeMatrix + */ +int MEDCouplingRemapper::nullifiedTinyCoeffInCrudeMatrixAbs(double maxValAbs) +{ + int ret=0; + std::vector<std::map<int,double> > matrixNew(_matrix.size()); + int i=0; + for(std::vector<std::map<int,double> >::const_iterator it1=_matrix.begin();it1!=_matrix.end();it1++,i++) + { + std::map<int,double>& rowNew=matrixNew[i]; + for(std::map<int,double>::const_iterator it2=(*it1).begin();it2!=(*it1).end();it2++) + { + if(fabs((*it2).second)>maxValAbs) + rowNew[(*it2).first]=(*it2).second; + else + ret++; + } + } + if(ret>0) + _matrix=matrixNew; + return ret; +} + +/*! + * This method is supposed to be called , if needed, right after MEDCouplingRemapper::prepare or MEDCouplingRemapper::prepareEx. + * If not the behaviour is unpredictable. + * This method works on precomputed \a this->_matrix. All coefficients in the matrix is lower than delta multiplied by \a scaleFactor this coefficient is + * set to 0. That is to say that its entry disappear from the map storing the corresponding row in the data storage of sparse crude matrix. + * delta is the value returned by MEDCouplingRemapper::getMaxValueInCrudeMatrix method. + * This method is useful to correct at a high level some problems linked to precision. Indeed, with some \ref NatureOfField "natures of field" some threshold effect + * can occur. + * + * \param [in] scaleFactor is the scale factor from which coefficients lower than \a scaleFactor times range width of coefficients are set to zero. + * \return a positive value that tells the number of coefficients put to 0. The 0 returned value means that the matrix has remained unchanged. If -1 is returned it means + * that all coefficients are null. + * \sa MEDCouplingRemapper::nullifiedTinyCoeffInCrudeMatrixAbs + */ +int MEDCouplingRemapper::nullifiedTinyCoeffInCrudeMatrix(double scaleFactor) +{ + double maxVal=getMaxValueInCrudeMatrix(); + if(maxVal==0.) + return -1; + return nullifiedTinyCoeffInCrudeMatrixAbs(scaleFactor*maxVal); +} + +/*! + * This method is supposed to be called , if needed, right after MEDCouplingRemapper::prepare or MEDCouplingRemapper::prepareEx. + * If not the behaviour is unpredictable. + * This method returns the maximum of the absolute values of coefficients into the sparse crude matrix. + * The returned value is positive. + */ +double MEDCouplingRemapper::getMaxValueInCrudeMatrix() const +{ + double ret=0.; + for(std::vector<std::map<int,double> >::const_iterator it1=_matrix.begin();it1!=_matrix.end();it1++) + for(std::map<int,double>::const_iterator it2=(*it1).begin();it2!=(*it1).end();it2++) + if(fabs((*it2).second)>ret) + ret=fabs((*it2).second); + return ret; +} diff --git a/src/medtool/src/MEDCoupling/MEDCouplingRemapper.hxx b/src/medtool/src/MEDCoupling/MEDCouplingRemapper.hxx new file mode 100644 index 000000000..61bee847d --- /dev/null +++ b/src/medtool/src/MEDCoupling/MEDCouplingRemapper.hxx @@ -0,0 +1,123 @@ +// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 +// 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_MEDCOUPLINGREMAPPER_HXX__ +#define __PARAMEDMEM_MEDCOUPLINGREMAPPER_HXX__ + +#include "MEDCoupling.hxx" +#include "MEDCouplingTimeLabel.hxx" +#include "InterpolationOptions.hxx" +#include "MEDCouplingNatureOfField.hxx" +#include "MEDCouplingAutoRefCountObjectPtr.hxx" + +#include "InterpKernelException.hxx" + +#include <map> +#include <vector> + +namespace ParaMEDMEM +{ + class MEDCouplingMesh; + 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: + MEDCOUPLINGREMAPPER_EXPORT MEDCouplingRemapper(); + MEDCOUPLINGREMAPPER_EXPORT ~MEDCouplingRemapper(); + MEDCOUPLINGREMAPPER_EXPORT int prepare(const MEDCouplingMesh *srcMesh, const MEDCouplingMesh *targetMesh, const std::string& method); + MEDCOUPLINGREMAPPER_EXPORT int prepareEx(const MEDCouplingFieldTemplate *src, const MEDCouplingFieldTemplate *target); + MEDCOUPLINGREMAPPER_EXPORT void transfer(const MEDCouplingFieldDouble *srcField, MEDCouplingFieldDouble *targetField, double dftValue); + MEDCOUPLINGREMAPPER_EXPORT void partialTransfer(const MEDCouplingFieldDouble *srcField, MEDCouplingFieldDouble *targetField); + MEDCOUPLINGREMAPPER_EXPORT void reverseTransfer(MEDCouplingFieldDouble *srcField, const MEDCouplingFieldDouble *targetField, double dftValue); + MEDCOUPLINGREMAPPER_EXPORT MEDCouplingFieldDouble *transferField(const MEDCouplingFieldDouble *srcField, double dftValue); + MEDCOUPLINGREMAPPER_EXPORT MEDCouplingFieldDouble *reverseTransferField(const MEDCouplingFieldDouble *targetField, double dftValue); + 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); + // + MEDCOUPLINGREMAPPER_EXPORT int nullifiedTinyCoeffInCrudeMatrixAbs(double maxValAbs); + MEDCOUPLINGREMAPPER_EXPORT int nullifiedTinyCoeffInCrudeMatrix(double scaleFactor); + MEDCOUPLINGREMAPPER_EXPORT double getMaxValueInCrudeMatrix() const; + public: + MEDCOUPLINGREMAPPER_EXPORT const std::vector<std::map<int,double> >& getCrudeMatrix() const; + MEDCOUPLINGREMAPPER_EXPORT int getNumberOfColsOfMatrix() const; + MEDCOUPLINGREMAPPER_EXPORT static void PrintMatrix(const std::vector<std::map<int,double> >& m); + MEDCOUPLINGREMAPPER_EXPORT static std::string BuildMethodFrom(const std::string& meth1, const std::string& meth2); + private: + int prepareInterpKernelOnly(); + int prepareInterpKernelOnlyUU(); + int prepareInterpKernelOnlyEE(); + int prepareInterpKernelOnlyUC(); + int prepareInterpKernelOnlyCU(); + int prepareInterpKernelOnlyCC(); + // + int prepareNotInterpKernelOnly(); + int prepareNotInterpKernelOnlyGaussGauss(); + // + static int CheckInterpolationMethodManageableByNotOnlyInterpKernel(const std::string& method); + // + bool isInterpKernelOnlyOrNotOnly() const; + void updateTime() const; + void checkPrepare() const; + std::string checkAndGiveInterpolationMethodStr(std::string& srcMeth, std::string& trgMeth) const; + void releaseData(bool matrixSuppression); + void transferUnderground(const MEDCouplingFieldDouble *srcField, MEDCouplingFieldDouble *targetField, bool isDftVal, double dftValue); + void computeDeno(NatureOfField nat, const MEDCouplingFieldDouble *srcField, const MEDCouplingFieldDouble *trgField); + void computeDenoFromScratch(NatureOfField nat, const MEDCouplingFieldDouble *srcField, const MEDCouplingFieldDouble *trgField); + void computeProduct(const double *inputPointer, int inputNbOfCompo, bool isDftVal, double dftValue, double *resPointer); + void computeReverseProduct(const double *inputPointer, int inputNbOfCompo, double dftValue, double *resPointer); + void buildFinalInterpolationMatrixByConvolution(const std::vector< std::map<int,double> >& m1D, + const std::vector< std::map<int,double> >& m2D, + const int *corrCellIdSrc, int nbOf2DCellsSrc, int nbOf1DCellsSrc, + const int *corrCellIdTrg); + static void ReverseMatrix(const std::vector<std::map<int,double> >& matIn, int nbColsMatIn, + std::vector<std::map<int,double> >& matOut); + static void ComputeRowSumAndColSum(const std::vector<std::map<int,double> >& matrixDeno, + std::vector<std::map<int,double> >& deno, std::vector<std::map<int,double> >& denoReverse); + static void ComputeColSumAndRowSum(const std::vector<std::map<int,double> >& matrixDeno, + std::vector<std::map<int,double> >& deno, std::vector<std::map<int,double> >& denoReverse); + private: + MEDCouplingAutoRefCountObjectPtr<MEDCouplingFieldTemplate> _src_ft; + MEDCouplingAutoRefCountObjectPtr<MEDCouplingFieldTemplate> _target_ft; + InterpolationMatrixPolicy _interp_matrix_pol; + NatureOfField _nature_of_deno; + unsigned int _time_deno_update; + std::vector<std::map<int,double> > _matrix; + std::vector<std::map<int,double> > _deno_multiply; + std::vector<std::map<int,double> > _deno_reverse_multiply; + }; +} + +#endif diff --git a/src/medtool/src/MEDCoupling/MEDCouplingSkyLineArray.cxx b/src/medtool/src/MEDCoupling/MEDCouplingSkyLineArray.cxx new file mode 100644 index 000000000..87f1bae2d --- /dev/null +++ b/src/medtool/src/MEDCoupling/MEDCouplingSkyLineArray.cxx @@ -0,0 +1,102 @@ +// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// + +#include "MEDCouplingSkyLineArray.hxx" + +using namespace ParaMEDMEM; + +MEDCouplingSkyLineArray::MEDCouplingSkyLineArray(): + _index( DataArrayInt::New() ), _value( DataArrayInt::New() ) +{ +} + +MEDCouplingSkyLineArray::MEDCouplingSkyLineArray(const MEDCouplingSkyLineArray &myArray) +{ + _index=myArray._index; + _value=myArray._value; +} + +MEDCouplingSkyLineArray::~MEDCouplingSkyLineArray() +{ +} + +MEDCouplingSkyLineArray::MEDCouplingSkyLineArray(DataArrayInt* index, DataArrayInt* value) +{ + set( index, value ); +} + +MEDCouplingSkyLineArray::MEDCouplingSkyLineArray( const std::vector<int>& index, + const std::vector<int>& value ): + _index( DataArrayInt::New() ), _value( DataArrayInt::New() ) +{ + _index->reserve( index.size() ); + _index->insertAtTheEnd( index.begin(), index.end() ); + _value->reserve( value.size() ); + _value->insertAtTheEnd( value.begin(), value.end() ); +} + +void MEDCouplingSkyLineArray::set( DataArrayInt* index, DataArrayInt* value ) +{ + _index=index; + _value=value; + if ( (DataArrayInt*)_index ) _index->incrRef(); + else _index = DataArrayInt::New(); + if ( (DataArrayInt*)_value ) _value->incrRef(); + else _value = DataArrayInt::New(); +} + +DataArrayInt* MEDCouplingSkyLineArray::getIndexArray() const +{ + return ((MEDCouplingSkyLineArray*)this)->_index; +} + +DataArrayInt* MEDCouplingSkyLineArray::getValueArray() const +{ + return ((MEDCouplingSkyLineArray*)this)->_value; +} + +std::string MEDCouplingSkyLineArray::simpleRepr() const +{ + std::ostringstream oss; + oss << "MEDCouplingSkyLineArray" << std::endl; + oss << " Nb of items: " << getNumberOf() << std::endl; + oss << " Nb of values: " << getLength() << std::endl; + oss << " Index:" << std::endl; + oss << " "; + const int * i = _index->begin(); + for ( ; i != _index->end(); ++i ) + oss << *i << " "; + oss << std::endl; + oss << " Value:" << std::endl; + oss << " "; + const int * v = _value->begin(); + int cnt = 0; + for ( i = _index->begin(); v != _value->end(); ++v, ++cnt ) + { + if ( cnt == *i ) + { + oss << "| "; + ++i; + } + oss << *v << " "; + } + oss << std::endl; + + return oss.str(); +} diff --git a/src/medtool/src/MEDCoupling/MEDCouplingSkyLineArray.hxx b/src/medtool/src/MEDCoupling/MEDCouplingSkyLineArray.hxx new file mode 100644 index 000000000..c12dc6b68 --- /dev/null +++ b/src/medtool/src/MEDCoupling/MEDCouplingSkyLineArray.hxx @@ -0,0 +1,56 @@ +// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 +// 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 __PARAMEDMEM_MEDCOUPLINGSKYLINEARRAY_HXX__ +#define __PARAMEDMEM_MEDCOUPLINGSKYLINEARRAY_HXX__ + +#include "MEDCoupling.hxx" +#include "MEDCouplingMemArray.hxx" +#include "MEDCouplingAutoRefCountObjectPtr.hxx" + +#include <vector> + +namespace ParaMEDMEM +{ + class MEDCOUPLING_EXPORT MEDCouplingSkyLineArray + { + private: + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> _index; + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> _value; + public: + MEDCouplingSkyLineArray(); + MEDCouplingSkyLineArray( const MEDCouplingSkyLineArray &myArray ); + MEDCouplingSkyLineArray( const std::vector<int>& index, const std::vector<int>& value ); + MEDCouplingSkyLineArray( DataArrayInt* index, DataArrayInt* value ); + ~MEDCouplingSkyLineArray(); + + void set( DataArrayInt* index, DataArrayInt* value ); + + int getNumberOf() const { return _index->getNbOfElems()-1; } + int getLength() const { return _value->getNbOfElems(); } + const int* getIndex() const { return _index->begin(); } + const int* getValue() const { return _value->begin(); } + + DataArrayInt* getIndexArray() const; + DataArrayInt* getValueArray() const; + + std::string simpleRepr() const; + }; +} +# endif diff --git a/src/medtool/src/MEDCoupling/MEDCouplingStructuredMesh.cxx b/src/medtool/src/MEDCoupling/MEDCouplingStructuredMesh.cxx new file mode 100644 index 000000000..ceec53712 --- /dev/null +++ b/src/medtool/src/MEDCoupling/MEDCouplingStructuredMesh.cxx @@ -0,0 +1,2109 @@ +// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 +// 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 "MEDCoupling1GTUMesh.hxx" +#include "MEDCouplingUMesh.hxx" +#include "MEDCouplingIMesh.hxx"//tony to throw when optimization will be performed in AssignPartOfFieldOfDoubleUsing + +#include <numeric> + +using namespace ParaMEDMEM; + +MEDCouplingStructuredMesh::MEDCouplingStructuredMesh() +{ +} + +MEDCouplingStructuredMesh::MEDCouplingStructuredMesh(const MEDCouplingStructuredMesh& other, bool deepCopy):MEDCouplingMesh(other) +{ +} + +MEDCouplingStructuredMesh::~MEDCouplingStructuredMesh() +{ +} + +std::size_t MEDCouplingStructuredMesh::getHeapMemorySizeWithoutChildren() const +{ + return MEDCouplingMesh::getHeapMemorySizeWithoutChildren(); +} + +void MEDCouplingStructuredMesh::copyTinyStringsFrom(const MEDCouplingMesh *other) +{ + MEDCouplingMesh::copyTinyStringsFrom(other); +} + +bool MEDCouplingStructuredMesh::isEqualIfNotWhy(const MEDCouplingMesh *other, double prec, std::string& reason) const +{ + return MEDCouplingMesh::isEqualIfNotWhy(other,prec,reason); +} + +INTERP_KERNEL::NormalizedCellType MEDCouplingStructuredMesh::getTypeOfCell(int cellId) const +{ + return GetGeoTypeGivenMeshDimension(getMeshDimension()); +} + +INTERP_KERNEL::NormalizedCellType MEDCouplingStructuredMesh::GetGeoTypeGivenMeshDimension(int meshDim) +{ + switch(meshDim) + { + case 3: + return INTERP_KERNEL::NORM_HEXA8; + case 2: + return INTERP_KERNEL::NORM_QUAD4; + case 1: + return INTERP_KERNEL::NORM_SEG2; + case 0: + return INTERP_KERNEL::NORM_POINT1; + default: + throw INTERP_KERNEL::Exception("Unexpected dimension for MEDCouplingStructuredMesh::GetGeoTypeGivenMeshDimension !"); + } +} + +std::set<INTERP_KERNEL::NormalizedCellType> MEDCouplingStructuredMesh::getAllGeoTypes() const +{ + std::set<INTERP_KERNEL::NormalizedCellType> 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 +{ + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> 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 +{ + int nbCells=getNumberOfCells(); + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> 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 +{ + int nbCells=getNumberOfCells(); + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> 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(); +} + +/*! + * This method computes effective number of nodes per cell. That is to say nodes appearing several times in nodal connectivity of a cell, + * will be counted only once here whereas it will be counted several times in MEDCouplingMesh::computeNbOfNodesPerCell method. + * Here for structured mesh it returns exactly as MEDCouplingStructuredMesh::computeNbOfNodesPerCell does. + * + * \return DataArrayInt * - new object to be deallocated by the caller. + */ +DataArrayInt *MEDCouplingStructuredMesh::computeEffectiveNbOfNodesPerCell() const +{ + return computeNbOfNodesPerCell(); +} + +void MEDCouplingStructuredMesh::getNodeIdsOfCell(int cellId, std::vector<int>& 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]*tmpNode[1]+tmp2[0]); conn.push_back(tmp2[1]*tmpNode[1]+tmp2[0]+1); + conn.push_back((tmp2[1]+1)*tmpNode[1]+tmp2[0]+1); conn.push_back((tmp2[1]+1)*tmpNode[1]+tmp2[0]); + break; + case 3: + conn.push_back(tmp2[1]*tmpNode[1]+tmp2[0]+tmp2[2]*tmpNode[2]); conn.push_back(tmp2[1]*tmpNode[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]*tmpNode[1]+tmp2[0]+(tmp2[2]+1)*tmpNode[2]); conn.push_back(tmp2[1]*tmpNode[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 !"); + }; +} + +/*! + * This method returns the mesh dimension of \a this. It can be different from space dimension in case of a not null dimension contains only one node. + */ +int MEDCouplingStructuredMesh::getMeshDimension() const +{ + std::vector<int> ngs(getNodeGridStructure()); + int ret(0),pos(0); + for(std::vector<int>::const_iterator it=ngs.begin();it!=ngs.end();it++,pos++) + { + if(*it<=0) + { + std::ostringstream oss; oss << "MEDCouplingStructuredMesh::getMeshDimension : At pos #" << pos << " number of nodes is " << *it << " ! Must be > 0 !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + if(*it>1) + ret++; + } + return ret; +} + +/*! + * This method returns the space dimension by only considering the node grid structure. + * For cartesian mesh the returned value is equal to those returned by getSpaceDimension. + * But for curvelinear is could be different ! + */ +int MEDCouplingStructuredMesh::getSpaceDimensionOnNodeStruct() const +{ + std::vector<int> nodeStr(getNodeGridStructure()); + int spd1(0),pos(0); + for(std::vector<int>::const_iterator it=nodeStr.begin();it!=nodeStr.end();it++,pos++) + { + int elt(*it); + if(elt<=0) + { + std::ostringstream oss; oss << "MEDCouplingStructuredMesh::getSpaceDimensionOnNodeStruct : At pos #" << pos << " value of node grid structure is " << *it << " ! must be >=1 !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + spd1++; + } + return spd1; +} + +void MEDCouplingStructuredMesh::getSplitCellValues(int *res) const +{ + std::vector<int> strct(getCellGridStructure()); + std::vector<int> ret(MEDCouplingStructuredMesh::GetSplitVectFromStruct(strct)); + std::copy(ret.begin(),ret.end(),res); +} + +void MEDCouplingStructuredMesh::getSplitNodeValues(int *res) const +{ + std::vector<int> strct(getNodeGridStructure()); + std::vector<int> ret(MEDCouplingStructuredMesh::GetSplitVectFromStruct(strct)); + std::copy(ret.begin(),ret.end(),res); +} + +/*! + * This method returns the number of cells of unstructured sub level mesh, without building it. + */ +int MEDCouplingStructuredMesh::getNumberOfCellsOfSubLevelMesh() const +{ + std::vector<int> cgs(getCellGridStructure()); + return GetNumberOfCellsOfSubLevelMesh(cgs,getMeshDimension()); +} + +/*! + * See MEDCouplingUMesh::getDistributionOfTypes for more information + */ +std::vector<int> MEDCouplingStructuredMesh::getDistributionOfTypes() const +{ + //only one type of cell + std::vector<int> ret(3); + ret[0]=getTypeOfCell(0); + ret[1]=getNumberOfCells(); + ret[2]=-1; //ret[3*k+2]==-1 because it has no sense here + return ret; +} + +/*! + * This method tries to minimize at most the number of deep copy. + * So if \a idsPerType is not empty it can be returned directly (without copy, but with ref count incremented) in return. + * + * See MEDCouplingUMesh::checkTypeConsistencyAndContig for more information + */ +DataArrayInt *MEDCouplingStructuredMesh::checkTypeConsistencyAndContig(const std::vector<int>& code, const std::vector<const DataArrayInt *>& idsPerType) const +{ + int nbOfCells=getNumberOfCells(); + if(code.size()!=3) + throw INTERP_KERNEL::Exception("MEDCouplingStructuredMesh::checkTypeConsistencyAndContig : invalid input code should be exactly of size 3 !"); + if(code[0]!=(int)getTypeOfCell(0)) + { + std::ostringstream oss; oss << "MEDCouplingStructuredMesh::checkTypeConsistencyAndContig : Mismatch of geometric type ! Asking for " << code[0] << " whereas the geometric type is \a this is " << getTypeOfCell(0) << " !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + if(code[2]==-1) + { + if(code[1]==nbOfCells) + return 0; + else + { + std::ostringstream oss; oss << "MEDCouplingStructuredMesh::checkTypeConsistencyAndContig : mismatch between the number of cells in this (" << nbOfCells << ") and the number of non profile (" << code[1] << ") !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + } + if(code[2]!=0) + throw INTERP_KERNEL::Exception("MEDCouplingStructuredMesh::checkTypeConsistencyAndContig : single geo type mesh ! 0 or -1 is expected at pos #2 of input code !"); + if(idsPerType.size()!=1) + throw INTERP_KERNEL::Exception("MEDCouplingStructuredMesh::checkTypeConsistencyAndContig : input code points to DataArrayInt #0 whereas the size of idsPerType is not equal to 1 !"); + const DataArrayInt *pfl=idsPerType[0]; + if(!pfl) + throw INTERP_KERNEL::Exception("MEDCouplingStructuredMesh::checkTypeConsistencyAndContig : the input code points to a NULL DataArrayInt at rank 0 !"); + if(pfl->getNumberOfComponents()!=1) + throw INTERP_KERNEL::Exception("MEDCouplingStructuredMesh::checkTypeConsistencyAndContig : input profile should have exactly one component !"); + pfl->checkAllIdsInRange(0,nbOfCells); + pfl->incrRef(); + return const_cast<DataArrayInt *>(pfl); +} + +/*! + * This method is the opposite of MEDCouplingUMesh::checkTypeConsistencyAndContig method. Given a list of cells in \a profile it returns a list of sub-profiles sorted by geo type. + * The result is put in the array \a idsPerType. In the returned parameter \a code, foreach i \a code[3*i+2] refers (if different from -1) to a location into the \a idsPerType. + * This method has 1 input \a profile and 3 outputs \a code \a idsInPflPerType and \a idsPerType. + * + * \param [out] code is a vector of size 3*n where n is the number of different geometric type in \a this \b reduced to the profile \a profile. \a code has exactly the same semantic than in MEDCouplingUMesh::checkTypeConsistencyAndContig method. + * \param [out] idsInPflPerType is a vector of size of different geometric type in the subpart defined by \a profile of \a this ( equal to \a code.size()/3). For each i, + * \a idsInPflPerType[i] stores the tuple ids in \a profile that correspond to the geometric type code[3*i+0] + * \param [out] idsPerType is a vector of size of different sub profiles needed to be defined to represent the profile \a profile for a given geometric type. + * This vector can be empty in case of all geometric type cells are fully covered in ascending in the given input \a profile. + * + * \warning for performance reasons no deep copy will be performed, if \a profile can been used as this in output parameters \a idsInPflPerType and \a idsPerType. + * + * \throw if \a profile has not exactly one component. It throws too, if \a profile contains some values not in [0,getNumberOfCells()) or if \a this is not fully defined + * + * \b Example1: <br> + * - Before \a this has 3 cells \a profile contains [0,1,2] + * - After \a code contains [NORM_...,nbCells,-1], \a idsInPflPerType [[0,1,2]] and \a idsPerType is empty <br> + * + * \b Example2: <br> + * - Before \a this has 3 cells \a profile contains [1,2] + * - After \a code contains [NORM_...,nbCells,0], \a idsInPflPerType [[0,1]] and \a idsPerType is [[1,2]] <br> + + */ +void MEDCouplingStructuredMesh::splitProfilePerType(const DataArrayInt *profile, std::vector<int>& code, std::vector<DataArrayInt *>& idsInPflPerType, std::vector<DataArrayInt *>& idsPerType) const +{ + if(!profile || !profile->isAllocated()) + throw INTERP_KERNEL::Exception("MEDCouplingStructuredMesh::splitProfilePerType : input profile is NULL or not allocated !"); + if(profile->getNumberOfComponents()!=1) + throw INTERP_KERNEL::Exception("MEDCouplingStructuredMesh::splitProfilePerType : input profile should have exactly one component !"); + int nbTuples(profile->getNumberOfTuples()); + int nbOfCells=getNumberOfCells(); + code.resize(3); idsInPflPerType.resize(1); + code[0]=(int)getTypeOfCell(0); code[1]=nbOfCells; + idsInPflPerType.resize(1); + if(profile->isIdentity2(nbOfCells)) + { + code[2]=-1; + idsInPflPerType[0]=profile->deepCpy(); + idsPerType.clear(); + return ; + } + code[1]=profile->getNumberOfTuples(); + code[2]=0; + profile->checkAllIdsInRange(0,nbOfCells); + idsPerType.resize(1); + idsPerType[0]=profile->deepCpy(); + idsInPflPerType[0]=DataArrayInt::Range(0,nbTuples,1); +} + +/*! + * Creates a new unstructured mesh (MEDCoupling1SGTUMesh) 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]. + */ +MEDCoupling1SGTUMesh *MEDCouplingStructuredMesh::build1SGTUnstructured() const +{ + int meshDim(getMeshDimension()),spaceDim(getSpaceDimensionOnNodeStruct()); + if((meshDim<0 || meshDim>3) || (spaceDim<0 || spaceDim>3)) + throw INTERP_KERNEL::Exception("MEDCouplingStructuredMesh::build1SGTUnstructured : meshdim and spacedim must be in [1,2,3] !"); + MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> coords(getCoordinatesAndOwner()); + int ns[3]; + getNodeGridStructure(ns); + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> conn(Build1GTNodalConnectivity(ns,ns+spaceDim)); + MEDCouplingAutoRefCountObjectPtr<MEDCoupling1SGTUMesh> ret(MEDCoupling1SGTUMesh::New(getName(),GetGeoTypeGivenMeshDimension(meshDim))); + ret->setNodalConnectivity(conn); ret->setCoords(coords); + try + { ret->copyTinyInfoFrom(this); } + catch(INTERP_KERNEL::Exception&) { } + return ret.retn(); +} + +/*! + * This method returns the unstructured mesh (having single geometric type) of the sub level mesh of \a this. + * This method is equivalent to computing MEDCouplingUMesh::buildDescendingConnectivity on the unstructurized \a this mesh. + * + * The caller is to delete the returned mesh using decrRef() as it is no more needed. + */ +MEDCoupling1SGTUMesh *MEDCouplingStructuredMesh::build1SGTSubLevelMesh() const +{ + int meshDim(getMeshDimension()); + if(meshDim<1 || meshDim>3) + throw INTERP_KERNEL::Exception("MEDCouplingStructuredMesh::build1SGTSubLevelMesh : meshdim must be in [2,3] !"); + MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> coords(getCoordinatesAndOwner()); + int ns[3]; + getNodeGridStructure(ns); + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> conn(Build1GTNodalConnectivityOfSubLevelMesh(ns,ns+meshDim)); + MEDCouplingAutoRefCountObjectPtr<MEDCoupling1SGTUMesh> ret(MEDCoupling1SGTUMesh::New(getName(),GetGeoTypeGivenMeshDimension(meshDim-1))); + ret->setNodalConnectivity(conn); ret->setCoords(coords); + return ret.retn(); +} + +/*! + * 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 +{ + MEDCouplingAutoRefCountObjectPtr<MEDCoupling1SGTUMesh> ret0(build1SGTUnstructured()); + return ret0->buildUnstructured(); +} + +/*! + * 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 +{ + std::vector<int> cgs(getCellGridStructure()); + std::vector< std::pair<int,int> > cellPartFormat,nodePartFormat; + if(IsPartStructured(start,end,cgs,cellPartFormat)) + { + MEDCouplingAutoRefCountObjectPtr<MEDCouplingStructuredMesh> ret(buildStructuredSubPart(cellPartFormat)); + nodePartFormat=cellPartFormat; + for(std::vector< std::pair<int,int> >::iterator it=nodePartFormat.begin();it!=nodePartFormat.end();it++) + (*it).second++; + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> tmp1(BuildExplicitIdsFrom(getNodeGridStructure(),nodePartFormat)); + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> tmp2(DataArrayInt::New()); tmp2->alloc(getNumberOfNodes(),1); + tmp2->fillWithValue(-1); + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> tmp3(DataArrayInt::New()); tmp3->alloc(tmp1->getNumberOfTuples(),1); tmp3->iota(0); + tmp2->setPartOfValues3(tmp3,tmp1->begin(),tmp1->end(),0,1,1); + arr=tmp2.retn(); + return ret.retn(); + } + else + { + MEDCouplingUMesh *um=buildUnstructured(); + MEDCouplingMesh *ret=um->buildPartAndReduceNodes(start,end,arr); + um->decrRef(); + return ret; + } +} + +DataArrayInt *MEDCouplingStructuredMesh::simplexize(int policy) +{ + 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;i<nbOfCells;i++) + { vals[3*i]=0.; vals[3*i+1]=0.; vals[3*i+2]=1.; } + ret->setArray(array); + array->decrRef(); + ret->setMesh(this); + return ret; +} + +void MEDCouplingStructuredMesh::getReverseNodalConnectivity(DataArrayInt *revNodal, DataArrayInt *revNodalIndx) const +{ + std::vector<int> ngs(getNodeGridStructure()); + int dim(getSpaceDimension()); + switch(dim) + { + case 1: + return GetReverseNodalConnectivity1(ngs,revNodal,revNodalIndx); + case 2: + return GetReverseNodalConnectivity2(ngs,revNodal,revNodalIndx); + case 3: + return GetReverseNodalConnectivity3(ngs,revNodal,revNodalIndx); + default: + throw INTERP_KERNEL::Exception("MEDCouplingStructuredMesh::getReverseNodalConnectivity : only dimensions 1, 2 and 3 are supported !"); + } +} + +void MEDCouplingStructuredMesh::GetReverseNodalConnectivity1(const std::vector<int>& ngs, DataArrayInt *revNodal, DataArrayInt *revNodalIndx) +{ + int nbNodes(ngs[0]); + revNodalIndx->alloc(nbNodes+1,1); + if(nbNodes==0) + { revNodal->alloc(0,1); revNodalIndx->setIJ(0,0,0); return ; } + if(nbNodes==1) + { revNodal->alloc(1,1); revNodal->setIJ(0,0,0); revNodalIndx->setIJ(0,0,0); revNodalIndx->setIJ(1,0,1); return ; } + revNodal->alloc(2*(nbNodes-1),1); + int *rn(revNodal->getPointer()),*rni(revNodalIndx->getPointer()); + *rni++=0; *rni=1; *rn++=0; + for(int i=1;i<nbNodes-1;i++,rni++) + { + rn[0]=i-1; rn[1]=i; + rni[1]=rni[0]+2; + rn+=2; + } + rn[0]=nbNodes-2; rni[1]=rni[0]+1; +} + +void MEDCouplingStructuredMesh::GetReverseNodalConnectivity2(const std::vector<int>& ngs, DataArrayInt *revNodal, DataArrayInt *revNodalIndx) +{ + int nbNodesX(ngs[0]),nbNodesY(ngs[1]); + int nbNodes(nbNodesX*nbNodesY); + if(nbNodesX==0 || nbNodesY==0) + { revNodal->alloc(0,1); revNodalIndx->setIJ(0,0,0); return ; } + if(nbNodesX==1 || nbNodesY==1) + { std::vector<int> ngs2(1); ngs2[0]=std::max(nbNodesX,nbNodesY); return GetReverseNodalConnectivity1(ngs2,revNodal,revNodalIndx); } + revNodalIndx->alloc(nbNodes+1,1); + int nbCellsX(nbNodesX-1),nbCellsY(nbNodesY-1); + revNodal->alloc(4*(nbNodesX-2)*(nbNodesY-2)+2*2*(nbNodesX-2)+2*2*(nbNodesY-2)+4,1); + int *rn(revNodal->getPointer()),*rni(revNodalIndx->getPointer()); + *rni++=0; *rni=1; *rn++=0; + for(int i=1;i<nbNodesX-1;i++,rni++,rn+=2) + { + rn[0]=i-1; rn[1]=i; + rni[1]=rni[0]+2; + } + rni[1]=rni[0]+1; *rn++=nbCellsX-1; + rni++; + for(int j=1;j<nbNodesY-1;j++) + { + int off(nbCellsX*(j-1)),off2(nbCellsX*j); + rni[1]=rni[0]+2; rn[0]=off; rn[1]=off2; + rni++; rn+=2; + for(int i=1;i<nbNodesX-1;i++,rni++,rn+=4) + { + rn[0]=i-1+off; rn[1]=i+off; rn[2]=i-1+off2; rn[3]=i+off2; + rni[1]=rni[0]+4; + } + rni[1]=rni[0]+2; rn[0]=off+nbCellsX-1; rn[1]=off2+nbCellsX-1; + rni++; rn+=2; + } + int off3(nbCellsX*(nbCellsY-1)); + rni[1]=rni[0]+1; + rni++; *rn++=off3; + for(int i=1;i<nbNodesX-1;i++,rni++,rn+=2) + { + rn[0]=i-1+off3; rn[1]=i+off3; + rni[1]=rni[0]+2; + } + rni[1]=rni[0]+1; rn[0]=nbCellsX*nbCellsY-1; +} + +void MEDCouplingStructuredMesh::GetReverseNodalConnectivity3(const std::vector<int>& ngs, DataArrayInt *revNodal, DataArrayInt *revNodalIndx) +{ + int nbNodesX(ngs[0]),nbNodesY(ngs[1]),nbNodesZ(ngs[2]); + int nbNodes(nbNodesX*nbNodesY*nbNodesZ); + if(nbNodesX==0 || nbNodesY==0 || nbNodesZ==0) + { revNodal->alloc(0,1); revNodalIndx->setIJ(0,0,0); return ; } + if(nbNodesX==1 || nbNodesY==1 || nbNodesZ==1) + { + std::vector<int> ngs2(2); + int pos(0); + bool pass(false); + for(int i=0;i<3;i++) + { + if(pass) + { ngs2[pos++]=ngs[i]; } + else + { + pass=ngs[i]==1; + if(!pass) + { ngs2[pos++]=ngs[i]; } + } + } + return GetReverseNodalConnectivity2(ngs2,revNodal,revNodalIndx); + } + revNodalIndx->alloc(nbNodes+1,1); + int nbCellsX(nbNodesX-1),nbCellsY(nbNodesY-1),nbCellsZ(nbNodesZ-1); + revNodal->alloc(8*(nbNodesX-2)*(nbNodesY-2)*(nbNodesZ-2)+4*(2*(nbNodesX-2)*(nbNodesY-2)+2*(nbNodesX-2)*(nbNodesZ-2)+2*(nbNodesY-2)*(nbNodesZ-2))+2*4*(nbNodesX-2)+2*4*(nbNodesY-2)+2*4*(nbNodesZ-2)+8,1); + int *rn(revNodal->getPointer()),*rni(revNodalIndx->getPointer()); + *rni=0; + for(int k=0;k<nbNodesZ;k++) + { + bool factZ(k!=0 && k!=nbNodesZ-1); + int offZ0((k-1)*nbCellsX*nbCellsY),offZ1(k*nbCellsX*nbCellsY); + for(int j=0;j<nbNodesY;j++) + { + bool factYZ(factZ && (j!=0 && j!=nbNodesY-1)); + int off00((j-1)*nbCellsX+offZ0),off01(j*nbCellsX+offZ0),off10((j-1)*nbCellsX+offZ1),off11(j*nbCellsX+offZ1); + for(int i=0;i<nbNodesX;i++,rni++) + { + int fact(factYZ && (i!=0 && i!=nbNodesX-1)); + if(fact) + {//most of points fall in this part of code + rn[0]=off00+i-1; rn[1]=off00+i; rn[2]=off01+i-1; rn[3]=off01+i; + rn[4]=off10+i-1; rn[5]=off10+i; rn[6]=off11+i-1; rn[7]=off11+i; + rni[1]=rni[0]+8; + rn+=8; + } + else + { + int *rnRef(rn); + if(k>=1 && j>=1 && i>=1) + *rn++=off00+i-1; + if(k>=1 && j>=1 && i<nbCellsX) + *rn++=off00+i; + if(k>=1 && j<nbCellsY && i>=1) + *rn++=off01+i-1; + if(k>=1 && j<nbCellsY && i<nbCellsX) + *rn++=off01+i; + // + if(k<nbCellsZ && j>=1 && i>=1) + *rn++=off10+i-1; + if(k<nbCellsZ && j>=1 && i<nbCellsX) + *rn++=off10+i; + if(k<nbCellsZ && j<nbCellsY && i>=1) + *rn++=off11+i-1; + if(k<nbCellsZ && j<nbCellsY && i<nbCellsX) + *rn++=off11+i; + rni[1]=rni[0]+(int)(std::distance(rnRef,rn)); + } + } + } + } +} + +/*! + * \return DataArrayInt * - newly allocated instance of nodal connectivity compatible for MEDCoupling1SGTMesh instance + */ +DataArrayInt *MEDCouplingStructuredMesh::Build1GTNodalConnectivity(const int *nodeStBg, const int *nodeStEnd) +{ + int zippedNodeSt[3]; + int dim(ZipNodeStructure(nodeStBg,nodeStEnd,zippedNodeSt)); + switch(dim) + { + case 0: + { + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> conn(DataArrayInt::New()); + conn->alloc(1,1); conn->setIJ(0,0,0); + return conn.retn(); + } + case 1: + return Build1GTNodalConnectivity1D(zippedNodeSt); + case 2: + return Build1GTNodalConnectivity2D(zippedNodeSt); + case 3: + return Build1GTNodalConnectivity3D(zippedNodeSt); + default: + throw INTERP_KERNEL::Exception("MEDCouplingStructuredMesh::Build1GTNodalConnectivity : only dimension in [0,1,2,3] supported !"); + } +} + +DataArrayInt *MEDCouplingStructuredMesh::Build1GTNodalConnectivityOfSubLevelMesh(const int *nodeStBg, const int *nodeStEnd) +{ + std::size_t dim(std::distance(nodeStBg,nodeStEnd)); + switch(dim) + { + case 3: + return Build1GTNodalConnectivityOfSubLevelMesh3D(nodeStBg); + case 2: + return Build1GTNodalConnectivityOfSubLevelMesh2D(nodeStBg); + default: + throw INTERP_KERNEL::Exception("MEDCouplingStructuredMesh::Build1GTNodalConnectivityOfSubLevelMesh: only dimension in [2,3] supported !"); + } +} + +/*! + * This method returns the list of ids sorted ascendingly of entities that are in the corner in ghost zone. + * The ids are returned in a newly created DataArrayInt having a single component. + * + * \param [in] st - The structure \b without ghost cells. + * \param [in] ghostLev - The size of the ghost zone (>=0) + * \return DataArrayInt * - The DataArray containing all the ids the caller is to deallocate. + */ +DataArrayInt *MEDCouplingStructuredMesh::ComputeCornersGhost(const std::vector<int>& st, int ghostLev) +{ + if(ghostLev<0) + throw INTERP_KERNEL::Exception("MEDCouplingStructuredMesh::ComputeCornersGhost : ghost lev must be >= 0 !"); + std::size_t dim(st.size()); + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret(DataArrayInt::New()); + switch(dim) + { + case 1: + { + ret->alloc(2*ghostLev,1); + int *ptr(ret->getPointer()); + for(int i=0;i<ghostLev;i++,ptr++) + *ptr=i; + int offset(st[0]); + if(offset<0) + throw INTERP_KERNEL::Exception("MEDCouplingStructuredMesh::ComputeCornersGhost : element in 1D structure must be >= 0 !"); + for(int i=0;i<ghostLev;i++,ptr++) + *ptr=offset+ghostLev+i; + break; + } + case 2: + { + int offsetX(st[0]),offsetY(st[1]); + if(offsetX<0 || offsetY<0) + throw INTERP_KERNEL::Exception("MEDCouplingStructuredMesh::ComputeCornersGhost : elements in 2D structure must be >= 0 !"); + ret->alloc(4*ghostLev,1); + int *ptr(ret->getPointer()); + for(int i=0;i<ghostLev;i++) + { + *ptr++=i*(2*ghostLev+offsetX+1); + *ptr++=offsetX+2*ghostLev-1+i*(2*ghostLev+offsetX-1); + } + for(int i=0;i<ghostLev;i++) + { + *ptr++=(2*ghostLev+offsetX)*(offsetY+ghostLev)+ghostLev-1+i*(2*ghostLev+offsetX-1); + *ptr++=(2*ghostLev+offsetX)*(offsetY+ghostLev)+offsetX+ghostLev+i*(2*ghostLev+offsetX+1); + } + break; + } + case 3: + { + int offsetX(st[0]),offsetY(st[1]),offsetZ(st[2]); + if(offsetX<0 || offsetY<0 || offsetZ<0) + throw INTERP_KERNEL::Exception("MEDCouplingStructuredMesh::ComputeCornersGhost : elements in 3D structure must be >= 0 !"); + ret->alloc(8*ghostLev,1); + int *ptr(ret->getPointer()); + int zeOffsetZ((offsetX+2*ghostLev)*(offsetY+2*ghostLev)); + for(int i=0;i<ghostLev;i++) + { + *ptr++=i*(2*ghostLev+offsetX+1)+i*zeOffsetZ; + *ptr++=offsetX+2*ghostLev-1+i*(2*ghostLev+offsetX-1)+i*zeOffsetZ; + *ptr++=(2*ghostLev+offsetX)*(offsetY+ghostLev)+ghostLev-1+(ghostLev-i-1)*(2*ghostLev+offsetX-1)+i*zeOffsetZ; + *ptr++=(2*ghostLev+offsetX)*(offsetY+ghostLev)+offsetX+ghostLev+(ghostLev-i-1)*(2*ghostLev+offsetX+1)+i*zeOffsetZ; + } + int j(0),zeOffsetZ2(zeOffsetZ*(offsetZ+ghostLev)); + for(int i=ghostLev-1;i>=0;i--,j++) + { + *ptr++=i*(2*ghostLev+offsetX+1)+j*zeOffsetZ+zeOffsetZ2; + *ptr++=offsetX+2*ghostLev-1+i*(2*ghostLev+offsetX-1)+j*zeOffsetZ+zeOffsetZ2; + *ptr++=(2*ghostLev+offsetX)*(offsetY+ghostLev)+ghostLev-1+(ghostLev-i-1)*(2*ghostLev+offsetX-1)+j*zeOffsetZ+zeOffsetZ2; + *ptr++=(2*ghostLev+offsetX)*(offsetY+ghostLev)+offsetX+ghostLev+(ghostLev-i-1)*(2*ghostLev+offsetX+1)+j*zeOffsetZ+zeOffsetZ2; + } + break; + } + default: + throw INTERP_KERNEL::Exception("MEDCouplingStructuredMesh::ComputeCornersGhost : Only dimensions 1, 2 and 3 are supported actually !"); + } + return ret.retn(); +} + +/*! + * This method retrieves the number of entities (it can be cells or nodes) given a range in compact standard format + * used in methods like BuildExplicitIdsFrom,IsPartStructured. + * + * \sa BuildExplicitIdsFrom,IsPartStructured + */ +int MEDCouplingStructuredMesh::DeduceNumberOfGivenRangeInCompactFrmt(const std::vector< std::pair<int,int> >& partCompactFormat) +{ + int ret(1); + std::size_t ii(0); + for(std::vector< std::pair<int,int> >::const_iterator it=partCompactFormat.begin();it!=partCompactFormat.end();it++,ii++) + { + int a((*it).first),b((*it).second); + if(a<0 || b<0 || b-a<0) + { + std::ostringstream oss; oss << "MEDCouplingStructuredMesh::DeduceNumberOfGivenRangeInCompactFrmt : invalid input at dimension " << ii << " !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + ret*=(b-a); + } + return ret; +} + +int MEDCouplingStructuredMesh::DeduceNumberOfGivenStructure(const std::vector<int>& st) +{ + int ret(1); + bool isFetched(false); + for(std::size_t i=0;i<st.size();i++) + { + if(st[i]<0) + throw INTERP_KERNEL::Exception("MEDCouplingStructuredMesh::DeduceNumberOfGivenStructure : presence of a negative value in structure !"); + ret*=st[i]; + isFetched=true; + } + return isFetched?ret:0; +} + +void MEDCouplingStructuredMesh::FindTheWidestAxisOfGivenRangeInCompactFrmt(const std::vector< std::pair<int,int> >& partCompactFormat, int& axisId, int& sizeOfRange) +{ + int dim((int)partCompactFormat.size()); + int ret(-1); + for(int i=0;i<dim;i++) + { + int curDelta(partCompactFormat[i].second-partCompactFormat[i].first); + if(curDelta<0) + { + std::ostringstream oss; oss << "MEDCouplingStructuredMesh::FindTheWidestAxisOfGivenRangeInCompactFrmt : at axis #" << i << " the range is invalid (first value < second value) !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + if(curDelta>ret) + { + axisId=i; sizeOfRange=curDelta; + ret=curDelta; + } + } +} + +/*! + * This method is \b NOT wrapped in python because it has no sense in python (for performance reasons). + * This method starts from a structured mesh with structure \a st on which a boolean field \a crit is set. + * This method find for such minimalist information of mesh and field which is the part of the mesh, given by the range per axis in output parameter + * \a partCompactFormat that contains all the True in \a crit. The returned vector of boolean is the field reduced to that part. + * So the number of True is equal in \a st and in returned vector of boolean. + * + * \param [in] minPatchLgth - minimum length that the patch may have for all directions. + * \param [in] st - The structure per axis of the structured mesh considered. + * \param [in] crit - The field of boolean (for performance reasons) lying on the mesh defined by \a st. + * \param [out] partCompactFormat - The minimal part of \a st containing all the true of \a crit. + * \param [out] reducedCrit - The reduction of \a criterion on \a partCompactFormat. + * \return - The number of True in \a st (that is equal to those in \a reducedCrit) + */ +int MEDCouplingStructuredMesh::FindMinimalPartOf(int minPatchLgth, const std::vector<int>& st, const std::vector<bool>& crit, std::vector<bool>& reducedCrit, std::vector< std::pair<int,int> >& partCompactFormat) +{ + if(minPatchLgth<0) + throw INTERP_KERNEL::Exception("MEDCouplingStructuredMesh::FindMinimalPartOf : the input minPatchLgth has to be >=0 !"); + if((int)crit.size()!=DeduceNumberOfGivenStructure(st)) + throw INTERP_KERNEL::Exception("MEDCouplingStructuredMesh::FindMinimalPartOf : size of vector of boolean is invalid regarding the declared structure !"); + int ret(-1); + switch((int)st.size()) + { + case 1: + { + ret=FindMinimalPartOf1D(st,crit,partCompactFormat); + break; + } + case 2: + { + ret=FindMinimalPartOf2D(st,crit,partCompactFormat); + break; + } + case 3: + { + ret=FindMinimalPartOf3D(st,crit,partCompactFormat); + break; + } + default: + throw INTERP_KERNEL::Exception("MEDCouplingStructuredMesh::FindMinimalPartOf : only dimension 1, 2 and 3 are supported actually !"); + } + std::vector<int> dims(MEDCouplingStructuredMesh::GetDimensionsFromCompactFrmt(partCompactFormat)); + int i(0); + for(std::vector< std::pair<int,int> >::iterator it=partCompactFormat.begin();it!=partCompactFormat.end();it++,i++) + { + if(st[i]<minPatchLgth) + throw INTERP_KERNEL::Exception("MEDCouplingStructuredMesh::FindMinimalPartOf : the input patch is tinier than the min length constraint !"); + int start((*it).first),stop((*it).second),middle((start+stop)/2); + if(stop-start<minPatchLgth) + { + (*it).first=middle-minPatchLgth/2; + (*it).second=middle+minPatchLgth-minPatchLgth/2; + if((*it).first<0) + { + (*it).second+=-(*it).first; + (*it).first=0; + } + if((*it).second>st[i]) + { + (*it).first-=(*it).second-st[i]; + (*it).second=st[i]; + } + } + } + ExtractFieldOfBoolFrom(st,crit,partCompactFormat,reducedCrit); + return ret; +} + +/*! + * This method is \b NOT wrapped in python. + * This method considers \a crit input parameter as a matrix having dimensions specified by \a st. This method returns for each axis + * the signature, that is to say the number of elems equal to true in \a crit along this axis. + */ +std::vector< std::vector<int> > MEDCouplingStructuredMesh::ComputeSignaturePerAxisOf(const std::vector<int>& st, const std::vector<bool>& crit) +{ + int dim((int)st.size()); + std::vector< std::vector<int> > ret(dim); + switch(dim) + { + case 1: + { + int nx(st[0]); + ret[0].resize(nx); + std::vector<int>& retX(ret[0]); + for(int i=0;i<nx;i++) + retX[i]=crit[i]?1:0; + break; + } + case 2: + { + int nx(st[0]),ny(st[1]); + ret[0].resize(nx); ret[1].resize(ny); + std::vector<int>& retX(ret[0]); + for(int i=0;i<nx;i++) + { + int cnt(0); + for(int j=0;j<ny;j++) + if(crit[j*nx+i]) + cnt++; + retX[i]=cnt; + } + std::vector<int>& retY(ret[1]); + for(int j=0;j<ny;j++) + { + int cnt(0); + for(int i=0;i<nx;i++) + if(crit[j*nx+i]) + cnt++; + retY[j]=cnt; + } + break; + } + case 3: + { + int nx(st[0]),ny(st[1]),nz(st[2]); + ret[0].resize(nx); ret[1].resize(ny); ret[2].resize(nz); + std::vector<int>& retX(ret[0]); + for(int i=0;i<nx;i++) + { + int cnt(0); + for(int k=0;k<nz;k++) + { + int offz(k*nx*ny+i); + for(int j=0;j<ny;j++) + if(crit[offz+j*nx]) + cnt++; + } + retX[i]=cnt; + } + std::vector<int>& retY(ret[1]); + for(int j=0;j<ny;j++) + { + int cnt(0),offy(j*nx); + for(int k=0;k<nz;k++) + { + int offz(k*nx*ny+offy); + for(int i=0;i<nx;i++) + if(crit[offz+i]) + cnt++; + } + retY[j]=cnt; + } + std::vector<int>& retZ(ret[2]); + for(int k=0;k<nz;k++) + { + int cnt(0),offz(k*nx*ny); + for(int j=0;j<ny;j++) + { + int offy(offz+j*nx); + for(int i=0;i<nx;i++) + if(crit[offy+i]) + cnt++; + } + retZ[k]=cnt; + } + break; + } + default: + throw INTERP_KERNEL::Exception("MEDCouplingStructuredMesh::ComputeSignatureOf : only dimensions 1, 2 and 3 are supported !"); + } + return ret; +} + +DataArrayInt *MEDCouplingStructuredMesh::Build1GTNodalConnectivity1D(const int *nodeStBg) +{ + int nbOfCells(*nodeStBg-1); + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> conn(DataArrayInt::New()); + conn->alloc(2*nbOfCells,1); + int *cp=conn->getPointer(); + for(int i=0;i<nbOfCells;i++) + { + cp[2*i+0]=i; + cp[2*i+1]=i+1; + } + return conn.retn(); +} + +DataArrayInt *MEDCouplingStructuredMesh::Build1GTNodalConnectivity2D(const int *nodeStBg) +{ + int n1=nodeStBg[0]-1; + int n2=nodeStBg[1]-1; + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> conn(DataArrayInt::New()); + conn->alloc(4*n1*n2,1); + int *cp=conn->getPointer(); + int pos=0; + for(int j=0;j<n2;j++) + for(int i=0;i<n1;i++,pos++) + { + cp[4*pos+0]=i+1+j*(n1+1); + cp[4*pos+1]=i+j*(n1+1); + cp[4*pos+2]=i+(j+1)*(n1+1); + cp[4*pos+3]=i+1+(j+1)*(n1+1); + } + return conn.retn(); +} + +DataArrayInt *MEDCouplingStructuredMesh::Build1GTNodalConnectivity3D(const int *nodeStBg) +{ + int n1=nodeStBg[0]-1; + int n2=nodeStBg[1]-1; + int n3=nodeStBg[2]-1; + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> conn(DataArrayInt::New()); + conn->alloc(8*n1*n2*n3,1); + int *cp=conn->getPointer(); + int pos=0; + for(int k=0;k<n3;k++) + for(int j=0;j<n2;j++) + for(int i=0;i<n1;i++,pos++) + { + int tmp=(n1+1)*(n2+1); + cp[8*pos+0]=i+1+j*(n1+1)+k*tmp; + cp[8*pos+1]=i+j*(n1+1)+k*tmp; + cp[8*pos+2]=i+(j+1)*(n1+1)+k*tmp; + cp[8*pos+3]=i+1+(j+1)*(n1+1)+k*tmp; + cp[8*pos+4]=i+1+j*(n1+1)+(k+1)*tmp; + cp[8*pos+5]=i+j*(n1+1)+(k+1)*tmp; + cp[8*pos+6]=i+(j+1)*(n1+1)+(k+1)*tmp; + cp[8*pos+7]=i+1+(j+1)*(n1+1)+(k+1)*tmp; + } + return conn.retn(); +} + +DataArrayInt *MEDCouplingStructuredMesh::Build1GTNodalConnectivityOfSubLevelMesh3D(const int *nodeStBg) +{ + std::vector<int> ngs(3); + int n0(nodeStBg[0]-1),n1(nodeStBg[1]-1),n2(nodeStBg[2]-1); ngs[0]=n0; ngs[1]=n1; ngs[2]=n2; + int off0(nodeStBg[0]),off1(nodeStBg[0]*nodeStBg[1]); + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> conn(DataArrayInt::New()); + conn->alloc(4*GetNumberOfCellsOfSubLevelMesh(ngs,3)); + int *cp(conn->getPointer()); + //X + for(int i=0;i<nodeStBg[0];i++) + for(int j=0;j<n1;j++) + for(int k=0;k<n2;k++,cp+=4) + { cp[0]=k*off1+j*off0+i; cp[1]=(k+1)*off1+j*off0+i; cp[2]=(k+1)*off1+(j+1)*off0+i; cp[3]=k*off1+(j+1)*off0+i; } + //Y + for(int j=0;j<nodeStBg[1];j++) + for(int i=0;i<n0;i++) + for(int k=0;k<n2;k++,cp+=4) + { cp[0]=k*off1+j*off0+i; cp[1]=(k+1)*off1+j*off0+i; cp[2]=(k+1)*off1+j*off0+(i+1); cp[3]=k*off1+j*off0+(i+1); } + //Z + for(int k=0;k<nodeStBg[2];k++) + for(int i=0;i<n0;i++) + for(int j=0;j<n1;j++,cp+=4) + { cp[0]=k*off1+j*off0+i; cp[1]=k*off1+j*off0+(i+1); cp[2]=k*off1+(j+1)*off0+(i+1); cp[3]=k*off1+(j+1)*off0+i; } + return conn.retn(); +} + +/*! + * \sa MEDCouplingStructuredMesh::FindMinimalPartOf + */ +int MEDCouplingStructuredMesh::FindMinimalPartOf1D(const std::vector<int>& st, const std::vector<bool>& crit, std::vector< std::pair<int,int> >& partCompactFormat) +{ + if(st.size()!=1) + throw INTERP_KERNEL::Exception("MEDCouplingStructuredMesh::FindMinimalPartOf1D : the input size of st must be equal to 1 !"); + int nxMin(std::numeric_limits<int>::max()),nxMax(-std::numeric_limits<int>::max()); + int nx(st[0]),ret(0); + for(int i=0;i<nx;i++) + { + if(crit[i]) + { + nxMin=std::min(nxMin,i); nxMax=std::max(nxMax,i); + ret++; + } + } + if(ret==0) + { + std::size_t sz(st.size()); + partCompactFormat.resize(sz); + for(std::size_t i=0;i<sz;i++) + { + partCompactFormat[i].first=st[i]/2; + partCompactFormat[i].second=st[i]/2; + } + return ret; + } + partCompactFormat.resize(1); + partCompactFormat[0].first=nxMin; partCompactFormat[0].second=nxMax+1; + return ret; +} + +/*! + * \sa MEDCouplingStructuredMesh::FindMinimalPartOf + */ +int MEDCouplingStructuredMesh::FindMinimalPartOf2D(const std::vector<int>& st, const std::vector<bool>& crit, std::vector< std::pair<int,int> >& partCompactFormat) +{ + if(st.size()!=2) + throw INTERP_KERNEL::Exception("MEDCouplingStructuredMesh::FindMinimalPartOf2D : the input size of st must be equal to 2 !"); + int nxMin(std::numeric_limits<int>::max()),nxMax(-std::numeric_limits<int>::max()),nyMin(std::numeric_limits<int>::max()),nyMax(-std::numeric_limits<int>::max()); + int it(0),nx(st[0]),ny(st[1]); + int ret(0); + for(int i=0;i<ny;i++) + for(int j=0;j<nx;j++,it++) + { + if(crit[it]) + { + nxMin=std::min(nxMin,j); nxMax=std::max(nxMax,j); + nyMin=std::min(nyMin,i); nyMax=std::max(nyMax,i); + ret++; + } + } + if(ret==0) + { + std::size_t sz(st.size()); + partCompactFormat.resize(sz); + for(std::size_t i=0;i<sz;i++) + { + partCompactFormat[i].first=st[i]/2; + partCompactFormat[i].second=st[i]/2; + } + return ret; + } + partCompactFormat.resize(2); + partCompactFormat[0].first=nxMin; partCompactFormat[0].second=nxMax+1; + partCompactFormat[1].first=nyMin; partCompactFormat[1].second=nyMax+1; + return ret; +} + +/*! + * \sa MEDCouplingStructuredMesh::FindMinimalPartOf + */ +int MEDCouplingStructuredMesh::FindMinimalPartOf3D(const std::vector<int>& st, const std::vector<bool>& crit, std::vector< std::pair<int,int> >& partCompactFormat) +{ + if(st.size()!=3) + throw INTERP_KERNEL::Exception("MEDCouplingStructuredMesh::FindMinimalPartOf3D : the input size of st must be equal to 3 !"); + int nxMin(std::numeric_limits<int>::max()),nxMax(-std::numeric_limits<int>::max()),nyMin(std::numeric_limits<int>::max()),nyMax(-std::numeric_limits<int>::max()),nzMin(std::numeric_limits<int>::max()),nzMax(-std::numeric_limits<int>::max()); + int it(0),nx(st[0]),ny(st[1]),nz(st[2]); + int ret(0); + for(int i=0;i<nz;i++) + for(int j=0;j<ny;j++) + for(int k=0;k<nx;k++,it++) + { + if(crit[it]) + { + nxMin=std::min(nxMin,k); nxMax=std::max(nxMax,k); + nyMin=std::min(nyMin,j); nyMax=std::max(nyMax,j); + nzMin=std::min(nzMin,i); nzMax=std::max(nzMax,i); + ret++; + } + } + if(ret==0) + { + std::size_t sz(st.size()); + partCompactFormat.resize(sz); + for(std::size_t i=0;i<sz;i++) + { + partCompactFormat[i].first=st[i]/2; + partCompactFormat[i].second=st[i]/2; + } + return ret; + } + partCompactFormat.resize(3); + partCompactFormat[0].first=nxMin; partCompactFormat[0].second=nxMax+1; + partCompactFormat[1].first=nyMin; partCompactFormat[1].second=nyMax+1; + partCompactFormat[2].first=nzMin; partCompactFormat[2].second=nzMax+1; + return ret; +} + +/*! + * This method computes given the nodal structure defined by [ \a nodeStBg , \a nodeStEnd ) the zipped form. + * std::distance( \a nodeStBg, \a nodeStEnd ) is equal to the space dimension. The returned value is equal to + * the meshDimension (or the zipped spaceDimension). + * + * \param [out] zipNodeSt - The zipped node strucutre + * \return int - the + */ +int MEDCouplingStructuredMesh::ZipNodeStructure(const int *nodeStBg, const int *nodeStEnd, int zipNodeSt[3]) +{ + int spaceDim((int)std::distance(nodeStBg,nodeStEnd)); + if(spaceDim>3 || spaceDim<1) + throw INTERP_KERNEL::Exception("MEDCouplingStructuredMesh::ZipNodeStructure : spaceDim must in [1,2,3] !"); + zipNodeSt[0]=0; zipNodeSt[1]=0; zipNodeSt[2]=0; + int zippedI(0); + for(int i=0;i<spaceDim;i++) + { + int elt(nodeStBg[i]); + if(elt<1) + { + std::ostringstream oss; oss << "MEDCouplingStructuredMesh::ZipNodeStructure : the input nodal structure at pos#" << i << "(" << nodeStBg[i] << ") is invalid !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + if(elt>=2) + zipNodeSt[zippedI++]=elt; + } + return zippedI; +} + +DataArrayInt *MEDCouplingStructuredMesh::Build1GTNodalConnectivityOfSubLevelMesh2D(const int *nodeStBg) +{ + std::vector<int> ngs(2); + int n0(nodeStBg[0]-1),n1(nodeStBg[1]-1); ngs[0]=n0; ngs[1]=n1; + int off0(nodeStBg[0]); + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> conn(DataArrayInt::New()); + conn->alloc(2*GetNumberOfCellsOfSubLevelMesh(ngs,2)); + int *cp(conn->getPointer()); + //X + for(int i=0;i<nodeStBg[0];i++) + for(int j=0;j<n1;j++,cp+=2) + { cp[0]=j*off0+i; cp[1]=(j+1)*off0+i; } + //Y + for(int j=0;j<nodeStBg[1];j++) + for(int i=0;i<n0;i++,cp+=2) + { cp[0]=j*off0+i; cp[1]=j*off0+(i+1); } + return conn.retn(); +} + +/*! + * 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<int>()); + 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 spaceDim(getSpaceDimension()); + getSplitNodeValues(tmp2); + std::transform(tmp,tmp+spaceDim,tmp2,tmp,std::multiplies<int>()); + return std::accumulate(tmp,tmp+spaceDim,0); +} + + +int MEDCouplingStructuredMesh::getNumberOfCells() const +{ + std::vector<int> ngs(getNodeGridStructure()); + int ret(1); + bool isCatched(false); + std::size_t ii(0); + for(std::vector<int>::const_iterator it=ngs.begin();it!=ngs.end();it++,ii++) + { + int elt(*it); + if(elt<=0) + { + std::ostringstream oss; oss << "MEDCouplingStructuredMesh::getNumberOfCells : at pos #" << ii << " the number of nodes in nodeStructure is " << *it << " ! Must be > 0 !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + if(elt>1) + { + ret*=elt-1; + isCatched=true; + } + } + return isCatched?ret:0; +} + +int MEDCouplingStructuredMesh::getNumberOfNodes() const +{ + std::vector<int> ngs(getNodeGridStructure()); + int ret(1); + for(std::vector<int>::const_iterator it=ngs.begin();it!=ngs.end();it++) + ret*=*it; + return ret; +} + +/*! + * This method returns for a cell which id is \a cellId the location (locX,locY,locZ) of this cell in \a this. + * + * \param [in] cellId + * \return - A vector of size this->getMeshDimension() + * \throw if \a cellId not in [ 0, this->getNumberOfCells() ) + */ +std::vector<int> MEDCouplingStructuredMesh::getLocationFromCellId(int cellId) const +{ + int meshDim(getMeshDimension()); + std::vector<int> ret(meshDim); + std::vector<int> struc(getCellGridStructure()); + int nbCells(std::accumulate(struc.begin(),struc.end(),1,std::multiplies<int>())); + if(cellId<0 || cellId>=nbCells) + { + std::ostringstream oss; oss << "MEDCouplingStructuredMesh::getLocationFromCellId : Input cell id (" << cellId << ") is invalid ! Should be in [0," << nbCells << ") !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + std::vector<int> spt(GetSplitVectFromStruct(struc)); + GetPosFromId(cellId,meshDim,&spt[0],&ret[0]); + return ret; +} + +/*! + * This method returns for a node which id is \a nodeId the location (locX,locY,locZ) of this node in \a this. + * + * \param [in] nodeId + * \return - A vector of size this->getSpaceDimension() + * \throw if \a cellId not in [ 0, this->getNumberOfNodes() ) + */ +std::vector<int> MEDCouplingStructuredMesh::getLocationFromNodeId(int nodeId) const +{ + int spaceDim(getSpaceDimension()); + std::vector<int> ret(spaceDim); + std::vector<int> struc(getNodeGridStructure()); + int nbNodes(std::accumulate(struc.begin(),struc.end(),1,std::multiplies<int>())); + if(nodeId<0 || nodeId>=nbNodes) + { + std::ostringstream oss; oss << "MEDCouplingStructuredMesh::getLocationFromNodeId : Input node id (" << nodeId << ") is invalid ! Should be in [0," << nbNodes << ") !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + std::vector<int> spt(GetSplitVectFromStruct(struc)); + GetPosFromId(nodeId,spaceDim,&spt[0],&ret[0]); + return ret; +} + +void MEDCouplingStructuredMesh::GetPosFromId(int eltId, int meshDim, const int *split, int *res) +{ + int work(eltId); + for(int i=meshDim-1;i>=0;i--) + { + int pos=work/split[i]; + work=work%split[i]; + res[i]=pos; + } +} + +std::vector<int> MEDCouplingStructuredMesh::getCellGridStructure() const +{ + std::vector<int> ret(getNodeGridStructure()); + std::transform(ret.begin(),ret.end(),ret.begin(),std::bind2nd(std::plus<int>(),-1)); + return ret; +} + +/*! + * This method returns the squareness of \a this (quadrature). \a this is expected to be with a mesh dimension equal to 2 or 3. + */ +double MEDCouplingStructuredMesh::computeSquareness() const +{ + std::vector<int> cgs(getCellGridStructure()); + if(cgs.empty()) + throw INTERP_KERNEL::Exception("MEDCouplingStructuredMesh::computeSquareness : empty mesh !"); + std::size_t dim(cgs.size()); + if(dim==1) + throw INTERP_KERNEL::Exception("MEDCouplingStructuredMesh::computeSquareness : A segment cannot be square !"); + if(dim<4) + { + int minAx(cgs[0]),maxAx(cgs[0]); + for(std::size_t i=1;i<dim;i++) + { + minAx=std::min(minAx,cgs[i]); + maxAx=std::max(maxAx,cgs[i]); + } + return (double)minAx/(double)maxAx; + } + throw INTERP_KERNEL::Exception("MEDCouplingStructuredMesh::computeSquareness : only dimension 2 and 3 supported !"); +} + +/*! + * Given a struct \a strct it returns a split vector [1,strct[0],strct[0]*strct[1]...] + * This decomposition allows to quickly find i,j,k given a global id. + */ +std::vector<int> MEDCouplingStructuredMesh::GetSplitVectFromStruct(const std::vector<int>& strct) +{ + int spaceDim((int)strct.size()); + std::vector<int> res(spaceDim); + for(int l=0;l<spaceDim;l++) + { + int val=1; + for(int p=0;p<spaceDim-l-1;p++) + val*=strct[p]; + res[spaceDim-l-1]=val; + } + return res; +} + +/*! + * This method states if given part ids [ \a startIds, \a stopIds) and a structure \a st returns if it can be considered as a structured dataset. + * If true is returned \a partCompactFormat will contain the information to build the corresponding part. + * + * \sa MEDCouplingStructuredMesh::BuildExplicitIdsFrom, MEDCouplingStructuredMesh::DeduceNumberOfGivenRangeInCompactFrmt + */ +bool MEDCouplingStructuredMesh::IsPartStructured(const int *startIds, const int *stopIds, const std::vector<int>& st, std::vector< std::pair<int,int> >& partCompactFormat) +{ + int dim((int)st.size()); + partCompactFormat.resize(dim); + if(dim<1 || dim>3) + throw INTERP_KERNEL::Exception("MEDCouplingStructuredMesh::isPartStructured : input structure must be of dimension in [1,2,3] !"); + std::vector<int> tmp2(dim),tmp(dim),tmp3(dim),tmp4(dim); tmp2[0]=1; + for(int i=1;i<dim;i++) + tmp2[i]=tmp2[i-1]*st[i-1]; + std::size_t sz(std::distance(startIds,stopIds)); + if(sz==0) + throw INTERP_KERNEL::Exception("MEDCouplingStructuredMesh::IsPartStructured : empty input !"); + GetPosFromId(*startIds,dim,&tmp2[0],&tmp[0]); + partCompactFormat.resize(dim); + for(int i=0;i<dim;i++) + partCompactFormat[i].first=tmp[i]; + if(tmp[dim-1]<0 || tmp[dim-1]>=st[dim-1]) + throw INTERP_KERNEL::Exception("MEDCouplingStructuredMesh::IsPartStructured : first id in input is not in valid range !"); + if(sz==1) + { + for(int i=0;i<dim;i++) + partCompactFormat[i].second=tmp[i]+1; + return true; + } + GetPosFromId(startIds[sz-1],dim,&tmp2[0],&tmp3[0]); + int szExp(1); + for(int i=0;i<dim;i++) + { + if(tmp3[i]<0 || tmp3[i]>=st[i]) + throw INTERP_KERNEL::Exception("MEDCouplingStructuredMesh::IsPartStructured : last id in input is not in valid range !"); + partCompactFormat[i].second=tmp3[i]+1; + tmp4[i]=partCompactFormat[i].second-partCompactFormat[i].first; + if(tmp4[i]<=0) + return false; + szExp*=tmp4[i]; + } + if(szExp!=(int)sz) + return false; + const int *w(startIds); + switch(dim) + { + case 3: + { + for(int i=0;i<tmp4[2];i++) + { + int a=tmp2[2]*(partCompactFormat[2].first+i); + for(int j=0;j<tmp4[1];j++) + { + int b=tmp2[1]*(partCompactFormat[1].first+j); + for(int k=0;k<tmp4[0];k++,w++) + { + if(partCompactFormat[0].first+k+b+a!=*w) + return false; + } + } + } + return true; + } + case 2: + { + for(int j=0;j<tmp4[1];j++) + { + int b=tmp2[1]*(partCompactFormat[1].first+j); + for(int k=0;k<tmp4[0];k++,w++) + { + if(partCompactFormat[0].first+k+b!=*w) + return false; + } + } + return true; + } + case 1: + { + for(int k=0;k<tmp4[0];k++,w++) + { + if(partCompactFormat[0].first+k!=*w) + return false; + } + return true; + } + default: + throw INTERP_KERNEL::Exception("MEDCouplingStructuredMesh::IsPartStructured : internal error !"); + } +} + +/*! + * This method takes in input a compact format [[Xmax,Xmin),[Ymin,Ymax)] and returns the corresponding dimensions for each axis that is to say + * [Xmax-Xmin,Ymax-Ymin]. + * + * \throw if an axis range is so that max<min + * \sa GetCompactFrmtFromDimensions + */ +std::vector<int> MEDCouplingStructuredMesh::GetDimensionsFromCompactFrmt(const std::vector< std::pair<int,int> >& partCompactFormat) +{ + std::vector<int> ret(partCompactFormat.size()); + for(std::size_t i=0;i<partCompactFormat.size();i++) + { + if(partCompactFormat[i].first>partCompactFormat[i].second) + { + std::ostringstream oss; oss << "MEDCouplingStructuredMesh::GetDimensionsFromCompactFrmt : For axis #" << i << " end is before start !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + ret[i]=partCompactFormat[i].second-partCompactFormat[i].first; + } + return ret; +} + +/*! + * This method takes in input a vector giving the number of entity per axis and returns for each axis a range starting from [0,0...] + * + * \throw if there is an axis in \a dims that is < 0. + * \sa GetDimensionsFromCompactFrmt, ChangeReferenceFromGlobalOfCompactFrmt, ChangeReferenceToGlobalOfCompactFrmt + */ +std::vector< std::pair<int,int> > MEDCouplingStructuredMesh::GetCompactFrmtFromDimensions(const std::vector<int>& dims) +{ + std::size_t sz(dims.size()); + std::vector< std::pair<int,int> > ret(sz); + for(std::size_t i=0;i<sz;i++) + { + if(dims[i]<0) + { + std::ostringstream oss; oss << "MEDCouplingStructuredMesh::GetDimensionsFromCompactFrmt : For axis #" << i << " dimension < 0 !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + ret[i].first=0; + ret[i].second=dims[i]; + } + return ret; +} + +/*! + * This method returns the intersection zone of two ranges (in compact format) \a r1 and \a r2. + * This method will throw exception if on one axis the intersection is empty. + * + * \sa AreRangesIntersect + */ +std::vector< std::pair<int,int> > MEDCouplingStructuredMesh::IntersectRanges(const std::vector< std::pair<int,int> >& r1, const std::vector< std::pair<int,int> >& r2) +{ + std::size_t sz(r1.size()); + if(sz!=r2.size()) + throw INTERP_KERNEL::Exception("MEDCouplingStructuredMesh::IntersectRanges : the two ranges must have the same dimension !"); + std::vector< std::pair<int,int> > ret(sz); + for(std::size_t i=0;i<sz;i++) + { + if(r1[i].first>r1[i].second) + { + std::ostringstream oss; oss << "MEDCouplingStructuredMesh::IntersectRanges : On axis " << i << " of range r1, end is before start !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + if(r2[i].first>r2[i].second) + { + std::ostringstream oss; oss << "MEDCouplingStructuredMesh::IntersectRanges : On axis " << i << " of range r2, end is before start !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + ret[i].first=std::max(r1[i].first,r2[i].first); + ret[i].second=std::min(r1[i].second,r2[i].second); + if(ret[i].first>ret[i].second) + { + std::ostringstream oss; oss << "MEDCouplingStructuredMesh::IntersectRanges : On axis " << i << " the intersection of r1 and r2 is empty !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + } + return ret; +} + +/*! + * This method states if \a r1 and \a r2 do overlap of not. If yes you can call IntersectRanges to know the intersection area. + * + * \sa IntersectRanges + */ +bool MEDCouplingStructuredMesh::AreRangesIntersect(const std::vector< std::pair<int,int> >& r1, const std::vector< std::pair<int,int> >& r2) +{ + std::size_t sz(r1.size()); + if(sz!=r2.size()) + throw INTERP_KERNEL::Exception("MEDCouplingStructuredMesh::AreRangesIntersect : the two ranges must have the same dimension !"); + for(std::size_t i=0;i<sz;i++) + { + if(r1[i].first>r1[i].second) + { + std::ostringstream oss; oss << "MEDCouplingStructuredMesh::AreRangesIntersect : On axis " << i << " of range r1, end is before start !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + if(r2[i].first>r2[i].second) + { + std::ostringstream oss; oss << "MEDCouplingStructuredMesh::AreRangesIntersect : On axis " << i << " of range r2, end is before start !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + if(r1[i].second<=r2[i].first) + return false; + if(r1[i].first>=r2[i].second) + return false; + } + return true; +} + +/*! + * This method is close to BuildExplicitIdsFrom except that instead of returning a DataArrayInt instance containing explicit ids it + * enable elems in the vector of booleans (for performance reasons). As it is method for performance, this method is \b not + * available in python. + * + * \param [in] st The entity structure. + * \param [in] partCompactFormat The compact subpart to be enabled. + * \param [in,out] vectToSwitchOn Vector which fetched items are enabled. + * + * \sa MEDCouplingStructuredMesh::BuildExplicitIdsFrom, ExtractFieldOfBoolFrom + */ +void MEDCouplingStructuredMesh::SwitchOnIdsFrom(const std::vector<int>& st, const std::vector< std::pair<int,int> >& partCompactFormat, std::vector<bool>& vectToSwitchOn) +{ + if(st.size()!=partCompactFormat.size()) + throw INTERP_KERNEL::Exception("MEDCouplingStructuredMesh::SwitchOnIdsFrom : input arrays must have the same size !"); + if((int)vectToSwitchOn.size()!=DeduceNumberOfGivenStructure(st)) + throw INTERP_KERNEL::Exception("MEDCouplingStructuredMesh::SwitchOnIdsFrom : invalid size of input vector of boolean regarding the structure !"); + std::vector<int> dims(GetDimensionsFromCompactFrmt(partCompactFormat)); + switch(st.size()) + { + case 3: + { + for(int i=0;i<dims[2];i++) + { + int a=(partCompactFormat[2].first+i)*st[0]*st[1]; + for(int j=0;j<dims[1];j++) + { + int b=(partCompactFormat[1].first+j)*st[0]; + for(int k=0;k<dims[0];k++) + vectToSwitchOn[partCompactFormat[0].first+k+b+a]=true; + } + } + break; + } + case 2: + { + for(int j=0;j<dims[1];j++) + { + int b=(partCompactFormat[1].first+j)*st[0]; + for(int k=0;k<dims[0];k++) + vectToSwitchOn[partCompactFormat[0].first+k+b]=true; + } + break; + } + case 1: + { + for(int k=0;k<dims[0];k++) + vectToSwitchOn[partCompactFormat[0].first+k]=true; + break; + } + default: + throw INTERP_KERNEL::Exception("MEDCouplingStructuredMesh::SwitchOnIdsFrom : Dimension supported are 1,2 or 3 !"); + } +} + +/*! + * Obviously this method is \b NOT wrapped in python. + * This method is close to SwitchOnIdsFrom except that here, a sub field \a fieldOut is built starting from the input field \a fieldOfBool having the structure \a st. + * The extraction is defined by \a partCompactFormat. + * + * \param [in] st The entity structure. + * \param [in] fieldOfBool field of booleans having the size equal to \c MEDCouplingStructuredMesh::DeduceNumberOfGivenStructure(st). + * \param [in] partCompactFormat The compact subpart to be enabled. + * \param [out] fieldOut the result of the extraction. + * + * \sa MEDCouplingStructuredMesh::BuildExplicitIdsFrom, SwitchOnIdsFrom, ExtractFieldOfDoubleFrom + */ +void MEDCouplingStructuredMesh::ExtractFieldOfBoolFrom(const std::vector<int>& st, const std::vector<bool>& fieldOfBool, const std::vector< std::pair<int,int> >& partCompactFormat, std::vector<bool>& fieldOut) +{ + if(st.size()!=partCompactFormat.size()) + throw INTERP_KERNEL::Exception("MEDCouplingStructuredMesh::ExtractFieldOfBoolFrom : input arrays must have the same size !"); + if((int)fieldOfBool.size()!=DeduceNumberOfGivenStructure(st)) + throw INTERP_KERNEL::Exception("MEDCouplingStructuredMesh::ExtractFieldOfBoolFrom : invalid size of input field of boolean regarding the structure !"); + std::vector<int> dims(GetDimensionsFromCompactFrmt(partCompactFormat)); + int nbOfTuplesOfOutField(DeduceNumberOfGivenStructure(dims)); + fieldOut.resize(nbOfTuplesOfOutField); + int it(0); + switch(st.size()) + { + case 3: + { + for(int i=0;i<dims[2];i++) + { + int a=(partCompactFormat[2].first+i)*st[0]*st[1]; + for(int j=0;j<dims[1];j++) + { + int b=(partCompactFormat[1].first+j)*st[0]; + for(int k=0;k<dims[0];k++) + fieldOut[it++]=fieldOfBool[partCompactFormat[0].first+k+b+a]; + } + } + break; + } + case 2: + { + for(int j=0;j<dims[1];j++) + { + int b=(partCompactFormat[1].first+j)*st[0]; + for(int k=0;k<dims[0];k++) + fieldOut[it++]=fieldOfBool[partCompactFormat[0].first+k+b]; + } + break; + } + case 1: + { + for(int k=0;k<dims[0];k++) + fieldOut[it++]=fieldOfBool[partCompactFormat[0].first+k]; + break; + } + default: + throw INTERP_KERNEL::Exception("MEDCouplingStructuredMesh::ExtractFieldOfBoolFrom : Dimension supported are 1,2 or 3 !"); + } +} + +/*! + * This method is close to SwitchOnIdsFrom except that here, a sub field \a fieldOut is built starting from the input field \a fieldOfDbl having the structure \a st. + * The extraction is defined by \a partCompactFormat. + * + * \param [in] st The entity structure. + * \param [in] fieldOfDbl field of doubles having a number of tuples equal to \c MEDCouplingStructuredMesh::DeduceNumberOfGivenStructure(st). + * \param [in] partCompactFormat The compact subpart to be enabled. + * \return DataArrayDouble * -the result of the extraction. + * + * \sa MEDCouplingStructuredMesh::BuildExplicitIdsFrom, SwitchOnIdsFrom, ExtractFieldOfBoolFrom + */ +DataArrayDouble *MEDCouplingStructuredMesh::ExtractFieldOfDoubleFrom(const std::vector<int>& st, const DataArrayDouble *fieldOfDbl, const std::vector< std::pair<int,int> >& partCompactFormat) +{ + if(!fieldOfDbl || !fieldOfDbl->isAllocated()) + throw INTERP_KERNEL::Exception("MEDCouplingStructuredMesh::ExtractFieldOfDoubleFrom : input array of double is NULL or not allocated!"); + if(st.size()!=partCompactFormat.size()) + throw INTERP_KERNEL::Exception("MEDCouplingStructuredMesh::ExtractFieldOfDoubleFrom : input arrays must have the same size !"); + if(fieldOfDbl->getNumberOfTuples()!=DeduceNumberOfGivenStructure(st)) + throw INTERP_KERNEL::Exception("MEDCouplingStructuredMesh::ExtractFieldOfDoubleFrom : invalid size of input array of double regarding the structure !"); + std::vector<int> dims(GetDimensionsFromCompactFrmt(partCompactFormat)); + int nbOfTuplesOfOutField(DeduceNumberOfGivenStructure(dims)),nbComp(fieldOfDbl->getNumberOfComponents()); + MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret(DataArrayDouble::New()); ret->alloc(nbOfTuplesOfOutField,nbComp); + ret->copyStringInfoFrom(*fieldOfDbl); + double *ptRet(ret->getPointer()); + const double *fieldOfDblPtr(fieldOfDbl->begin()); + switch(st.size()) + { + case 3: + { + for(int i=0;i<dims[2];i++) + { + int a=(partCompactFormat[2].first+i)*st[0]*st[1]; + for(int j=0;j<dims[1];j++) + { + int b=(partCompactFormat[1].first+j)*st[0]; + for(int k=0;k<dims[0];k++) + ptRet=std::copy(fieldOfDblPtr+(partCompactFormat[0].first+k+b+a)*nbComp,fieldOfDblPtr+(partCompactFormat[0].first+k+b+a+1)*nbComp,ptRet); + } + } + break; + } + case 2: + { + for(int j=0;j<dims[1];j++) + { + int b=(partCompactFormat[1].first+j)*st[0]; + for(int k=0;k<dims[0];k++) + ptRet=std::copy(fieldOfDblPtr+(partCompactFormat[0].first+k+b)*nbComp,fieldOfDblPtr+(partCompactFormat[0].first+k+b+1)*nbComp,ptRet); + } + break; + } + case 1: + { + for(int k=0;k<dims[0];k++) + ptRet=std::copy(fieldOfDblPtr+(partCompactFormat[0].first+k)*nbComp,fieldOfDblPtr+(partCompactFormat[0].first+k+1)*nbComp,ptRet); + break; + } + default: + throw INTERP_KERNEL::Exception("MEDCouplingStructuredMesh::ExtractFieldOfDoubleFrom : Dimension supported are 1,2 or 3 !"); + } + return ret.retn(); +} + +/*! + * This method assign a part of values in \a fieldOfDbl using entirely values of \b other. + * + * \param [in] st - the structure of \a fieldOfDbl. + * \param [in,out] fieldOfDbl - the array that will be partially filled using \a other. + * \param [in] partCompactFormat - the specification of the part. + * \param [in] other - the array that will be used to fill \a fieldOfDbl. + */ +void MEDCouplingStructuredMesh::AssignPartOfFieldOfDoubleUsing(const std::vector<int>& st, DataArrayDouble *fieldOfDbl, const std::vector< std::pair<int,int> >& partCompactFormat, const DataArrayDouble *other) +{//to be optimized + std::vector<int> facts(st.size(),1.); + MEDCouplingIMesh::CondenseFineToCoarse(st,other,partCompactFormat,facts,fieldOfDbl); +} + +/*! + * This method changes the reference of a part of structured mesh \a partOfBigInAbs define in absolute reference to a new reference \a bigInAbs. + * So this method only performs a translation by doing \a partOfBigRelativeToBig = \a partOfBigInAbs - \a bigInAbs + * This method also checks (if \a check=true) that \a partOfBigInAbs is included in \a bigInAbs. + * This method is useful to extract a part from a field lying on a big mesh. + * + * \sa ChangeReferenceToGlobalOfCompactFrmt, BuildExplicitIdsFrom, SwitchOnIdsFrom, ExtractFieldOfBoolFrom, ExtractFieldOfDoubleFrom + */ +void MEDCouplingStructuredMesh::ChangeReferenceFromGlobalOfCompactFrmt(const std::vector< std::pair<int,int> >& bigInAbs, const std::vector< std::pair<int,int> >& partOfBigInAbs, std::vector< std::pair<int,int> >& partOfBigRelativeToBig, bool check) +{ + std::size_t dim(bigInAbs.size()); + if(dim!=partOfBigInAbs.size()) + throw INTERP_KERNEL::Exception("MEDCouplingStructuredMesh::ChangeReferenceFromGlobalOfCompactFrmt : The size of parts (dimension) must be the same !"); + partOfBigRelativeToBig.resize(dim); + for(std::size_t i=0;i<dim;i++) + { + if(check) + { + if(bigInAbs[i].first>bigInAbs[i].second) + { + std::ostringstream oss; oss << "MEDCouplingStructuredMesh::ChangeReferenceFromGlobalOfCompactFrmt : Error at axis #" << i << " the input big part invalid, end before start !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + if(partOfBigInAbs[i].first<bigInAbs[i].first || partOfBigInAbs[i].first>=bigInAbs[i].second) + { + std::ostringstream oss; oss << "MEDCouplingStructuredMesh::ChangeReferenceFromGlobalOfCompactFrmt : Error at axis #" << i << " the part is not included in the big one (start) !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + } + partOfBigRelativeToBig[i].first=partOfBigInAbs[i].first-bigInAbs[i].first; + if(check) + { + if(partOfBigInAbs[i].second<partOfBigInAbs[i].first || partOfBigInAbs[i].second>bigInAbs[i].second) + { + std::ostringstream oss; oss << "MEDCouplingStructuredMesh::ChangeReferenceFromGlobalOfCompactFrmt : Error at axis #" << i << " the part is not included in the big one (end) !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + } + partOfBigRelativeToBig[i].second=partOfBigInAbs[i].second-bigInAbs[i].first; + } +} + +/* + * This method is performs the opposite reference modification than explained in ChangeReferenceFromGlobalOfCompactFrmt. + * + * \sa ChangeReferenceFromGlobalOfCompactFrmt + */ +void MEDCouplingStructuredMesh::ChangeReferenceToGlobalOfCompactFrmt(const std::vector< std::pair<int,int> >& bigInAbs, const std::vector< std::pair<int,int> >& partOfBigRelativeToBig, std::vector< std::pair<int,int> >& partOfBigInAbs, bool check) +{ + std::size_t dim(bigInAbs.size()); + if(dim!=partOfBigRelativeToBig.size()) + throw INTERP_KERNEL::Exception("MEDCouplingStructuredMesh::ChangeReferenceToGlobalOfCompactFrmt : The size of parts (dimension) must be the same !"); + partOfBigInAbs.resize(dim); + for(std::size_t i=0;i<dim;i++) + { + if(check) + { + if(bigInAbs[i].first>bigInAbs[i].second) + { + std::ostringstream oss; oss << "MEDCouplingStructuredMesh::ChangeReferenceToGlobalOfCompactFrmt : Error at axis #" << i << " the input big part invalid, end before start !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + if(partOfBigRelativeToBig[i].first<0 || partOfBigRelativeToBig[i].first>=bigInAbs[i].second-bigInAbs[i].first) + { + std::ostringstream oss; oss << "MEDCouplingStructuredMesh::ChangeReferenceToGlobalOfCompactFrmt : Error at axis #" << i << " the start of part is not in the big one !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + } + partOfBigInAbs[i].first=partOfBigRelativeToBig[i].first+bigInAbs[i].first; + if(check) + { + if(partOfBigRelativeToBig[i].second<partOfBigRelativeToBig[i].first || partOfBigRelativeToBig[i].second>bigInAbs[i].second-bigInAbs[i].first) + { + std::ostringstream oss; oss << "MEDCouplingStructuredMesh::ChangeReferenceToGlobalOfCompactFrmt : Error at axis #" << i << " the end of part is not in the big one !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + } + partOfBigInAbs[i].second=partOfBigRelativeToBig[i].second+bigInAbs[i].first; + } +} + +/*! + * This method performs a translation (defined by \a translation) of \a part and returns the result of translated part. + * + * \sa FindTranslationFrom + */ +std::vector< std::pair<int,int> > MEDCouplingStructuredMesh::TranslateCompactFrmt(const std::vector< std::pair<int,int> >& part, const std::vector<int>& translation) +{ + std::size_t sz(part.size()); + if(translation.size()!=sz) + throw INTERP_KERNEL::Exception("MEDCouplingStructuredMesh::TranslateCompactFrmt : the sizes are not equal !"); + std::vector< std::pair<int,int> > ret(sz); + for(std::size_t i=0;i<sz;i++) + { + ret[i].first=part[i].first+translation[i]; + ret[i].second=part[i].second+translation[i]; + } + return ret; +} + +/*! + * \sa TranslateCompactFrmt + */ +std::vector<int> MEDCouplingStructuredMesh::FindTranslationFrom(const std::vector< std::pair<int,int> >& startingFrom, const std::vector< std::pair<int,int> >& goingTo) +{ + std::size_t sz(startingFrom.size()); + if(goingTo.size()!=sz) + throw INTERP_KERNEL::Exception("MEDCouplingStructuredMesh::FindTranslationFrom : the sizes are not equal !"); + std::vector< int > ret(sz); + for(std::size_t i=0;i<sz;i++) + { + ret[i]=goingTo[i].first-startingFrom[i].first; + } + return ret; +} + +/*! + * This method builds the explicit entity array from the structure in \a st and the range in \a partCompactFormat. + * If the range contains invalid values regarding sructure an exception will be thrown. + * + * \return DataArrayInt * - a new object. + * \sa MEDCouplingStructuredMesh::IsPartStructured, MEDCouplingStructuredMesh::DeduceNumberOfGivenRangeInCompactFrmt, SwitchOnIdsFrom, ExtractFieldOfBoolFrom, ExtractFieldOfDoubleFrom, MultiplyPartOf + */ +DataArrayInt *MEDCouplingStructuredMesh::BuildExplicitIdsFrom(const std::vector<int>& st, const std::vector< std::pair<int,int> >& partCompactFormat) +{ + if(st.size()!=partCompactFormat.size()) + throw INTERP_KERNEL::Exception("MEDCouplingStructuredMesh::BuildExplicitIdsFrom : input arrays must have the same size !"); + int nbOfItems(1); + std::vector<int> dims(st.size()); + for(std::size_t i=0;i<st.size();i++) + { + if(partCompactFormat[i].first<0 || partCompactFormat[i].first>st[i]) + throw INTERP_KERNEL::Exception("MEDCouplingStructuredMesh::BuildExplicitIdsFrom : invalid input range 1 !"); + if(partCompactFormat[i].second<0 || partCompactFormat[i].second>st[i]) + throw INTERP_KERNEL::Exception("MEDCouplingStructuredMesh::BuildExplicitIdsFrom : invalid input range 2 !"); + if(partCompactFormat[i].second<partCompactFormat[i].first) + throw INTERP_KERNEL::Exception("MEDCouplingStructuredMesh::BuildExplicitIdsFrom : invalid input range 3 !"); + dims[i]=partCompactFormat[i].second-partCompactFormat[i].first; + nbOfItems*=dims[i]; + } + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret(DataArrayInt::New()); + ret->alloc(nbOfItems,1); + int *pt(ret->getPointer()); + switch(st.size()) + { + case 3: + { + for(int i=0;i<dims[2];i++) + { + int a=(partCompactFormat[2].first+i)*st[0]*st[1]; + for(int j=0;j<dims[1];j++) + { + int b=(partCompactFormat[1].first+j)*st[0]; + for(int k=0;k<dims[0];k++,pt++) + *pt=partCompactFormat[0].first+k+b+a; + } + } + break; + } + case 2: + { + for(int j=0;j<dims[1];j++) + { + int b=(partCompactFormat[1].first+j)*st[0]; + for(int k=0;k<dims[0];k++,pt++) + *pt=partCompactFormat[0].first+k+b; + } + break; + } + case 1: + { + for(int k=0;k<dims[0];k++,pt++) + *pt=partCompactFormat[0].first+k; + break; + } + default: + throw INTERP_KERNEL::Exception("MEDCouplingStructuredMesh::BuildExplicitIdsFrom : Dimension supported are 1,2 or 3 !"); + } + return ret.retn(); +} + +/*! + * This method multiplies by \a factor values in tuples located by \a part in \a da. + * + * \param [in] st - the structure of grid ( \b without considering ghost cells). + * \param [in] part - the part in the structure ( \b without considering ghost cells) contained in grid whose structure is defined by \a st. + * \param [in] factor - the factor, the tuples in \a da will be multiply by. + * \param [in,out] da - The DataArray in wich only tuples specified by \a part will be modified. + * + * \sa BuildExplicitIdsFrom + */ +void MEDCouplingStructuredMesh::MultiplyPartOf(const std::vector<int>& st, const std::vector< std::pair<int,int> >& part, double factor, DataArrayDouble *da) +{ + if(!da || !da->isAllocated()) + throw INTERP_KERNEL::Exception("MEDCouplingStructuredMesh::MultiplyPartOf : DataArrayDouble instance must be not NULL and allocated !"); + if(st.size()!=part.size()) + throw INTERP_KERNEL::Exception("MEDCouplingStructuredMesh::MultiplyPartOf : input arrays must have the same size !"); + std::vector<int> dims(st.size()); + for(std::size_t i=0;i<st.size();i++) + { + if(part[i].first<0 || part[i].first>st[i]) + throw INTERP_KERNEL::Exception("MEDCouplingStructuredMesh::MultiplyPartOf : invalid input range 1 !"); + if(part[i].second<0 || part[i].second>st[i]) + throw INTERP_KERNEL::Exception("MEDCouplingStructuredMesh::MultiplyPartOf : invalid input range 2 !"); + if(part[i].second<part[i].first) + throw INTERP_KERNEL::Exception("MEDCouplingStructuredMesh::MultiplyPartOf : invalid input range 3 !"); + dims[i]=part[i].second-part[i].first; + } + int nbOfTuplesExp(MEDCouplingStructuredMesh::DeduceNumberOfGivenStructure(st)),nbCompo(da->getNumberOfComponents()); + if(da->getNumberOfTuples()!=nbOfTuplesExp) + { + std::ostringstream oss; oss << "MEDCouplingStructuredMesh::MultiplyPartOf : invalid nb of tuples ! Expected " << nbOfTuplesExp << " having " << da->getNumberOfTuples() << " !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + double *pt(da->getPointer()); + switch(st.size()) + { + case 3: + { + for(int i=0;i<dims[2];i++) + { + int a=(part[2].first+i)*st[0]*st[1]; + for(int j=0;j<dims[1];j++) + { + int b=(part[1].first+j)*st[0]; + for(int k=0;k<dims[0];k++) + { + int offset(part[0].first+k+b+a); + std::transform(pt+nbCompo*offset,pt+nbCompo*(offset+1),pt+nbCompo*offset,std::bind2nd(std::multiplies<double>(),factor)); + } + } + } + break; + } + case 2: + { + for(int j=0;j<dims[1];j++) + { + int b=(part[1].first+j)*st[0]; + for(int k=0;k<dims[0];k++) + { + int offset(part[0].first+k+b); + std::transform(pt+nbCompo*offset,pt+nbCompo*(offset+1),pt+nbCompo*offset,std::bind2nd(std::multiplies<double>(),factor)); + } + } + break; + } + case 1: + { + for(int k=0;k<dims[0];k++) + { + int offset(part[0].first+k); + std::transform(pt+nbCompo*offset,pt+nbCompo*(offset+1),pt+nbCompo*offset,std::bind2nd(std::multiplies<double>(),factor)); + } + break; + } + default: + throw INTERP_KERNEL::Exception("MEDCouplingStructuredMesh::MultiplyPartOf : Dimension supported are 1,2 or 3 !"); + } +} + +/*! + * This method multiplies by \a factor values in tuples located by \a part in \a da. + * + * \param [in] st - the structure of grid ( \b without considering ghost cells). + * \param [in] part - the part in the structure ( \b without considering ghost cells) contained in grid whose structure is defined by \a st. + * \param [in] ghostSize - \a ghostSize must be >= 0. + * \param [in] factor - the factor, the tuples in \a da will be multiply by. + * \param [in,out] da - The DataArray in wich only tuples specified by \a part will be modified. + * + * \sa MultiplyPartOf, PutInGhostFormat + */ +void MEDCouplingStructuredMesh::MultiplyPartOfByGhost(const std::vector<int>& st, const std::vector< std::pair<int,int> >& part, int ghostSize, double factor, DataArrayDouble *da) +{ + std::vector<int> stWG; + std::vector< std::pair<int,int> > partWG; + PutInGhostFormat(ghostSize,st,part,stWG,partWG); + MultiplyPartOf(stWG,partWG,factor,da); +} + +/*! + * This method multiplies by \a factor values in tuples located by \a part in \a da. + * + * \param [in] st - the structure of grid ( \b without considering ghost cells). + * \param [in] part - the part in the structure ( \b without considering ghost cells) contained in grid whose structure is defined by \a st. + * \param [in] ghostSize - \a ghostSize must be >= 0. + * \param [out] stWithGhost - the structure considering ghost cells. + * \param [out] partWithGhost - the part considering the ghost cells. + * + * \sa MultiplyPartOf, PutInGhostFormat + */ +void MEDCouplingStructuredMesh::PutInGhostFormat(int ghostSize, const std::vector<int>& st, const std::vector< std::pair<int,int> >& part, std::vector<int>& stWithGhost, std::vector< std::pair<int,int> >&partWithGhost) +{ + if(ghostSize<0) + throw INTERP_KERNEL::Exception("MEDCouplingStructuredMesh::PutInGhostFormat : ghost size must be >= 0 !"); + std::size_t dim(part.size()); + if(st.size()!=dim) + throw INTERP_KERNEL::Exception("MEDCouplingStructuredMesh::PutInGhostFormat : the dimension of input vectors must be the same !"); + for(std::size_t i=0;i<dim;i++) + if(part[i].first<0 || part[i].first>part[i].second || part[i].second>st[i]) + throw INTERP_KERNEL::Exception("MEDCouplingStructuredMesh::PutInGhostFormat : the specified part is invalid ! The begin must be >= 0 and <= end ! The end must be <= to the size at considered dimension !"); + stWithGhost.resize(st.size()); + std::transform(st.begin(),st.end(),stWithGhost.begin(),std::bind2nd(std::plus<int>(),2*ghostSize)); + partWithGhost=part; + ApplyGhostOnCompactFrmt(partWithGhost,ghostSize); +} + +/*! + * \param [in,out] partBeforeFact - the part of a image mesh in compact format that will be put in ghost reference. + * \param [in] ghostSize - the ghost size of zone for all axis. + */ +void MEDCouplingStructuredMesh::ApplyGhostOnCompactFrmt(std::vector< std::pair<int,int> >& partBeforeFact, int ghostSize) +{ + if(ghostSize<0) + throw INTERP_KERNEL::Exception("MEDCouplingStructuredMesh::ApplyGhostOnCompactFrmt : ghost size must be >= 0 !"); + std::size_t sz(partBeforeFact.size()); + for(std::size_t i=0;i<sz;i++) + { + partBeforeFact[i].first+=ghostSize; + partBeforeFact[i].second+=ghostSize; + } +} + +int MEDCouplingStructuredMesh::GetNumberOfCellsOfSubLevelMesh(const std::vector<int>& cgs, int mdim) +{ + int ret(0); + for(int i=0;i<mdim;i++) + { + int locRet(1); + for(int j=0;j<mdim;j++) + if(j!=i) + locRet*=cgs[j]; + else + locRet*=cgs[j]+1; + ret+=locRet; + } + return ret; +} diff --git a/src/medtool/src/MEDCoupling/MEDCouplingStructuredMesh.hxx b/src/medtool/src/MEDCoupling/MEDCouplingStructuredMesh.hxx new file mode 100644 index 000000000..a052bf0d4 --- /dev/null +++ b/src/medtool/src/MEDCoupling/MEDCouplingStructuredMesh.hxx @@ -0,0 +1,125 @@ +// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 +// 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 MEDCoupling1SGTUMesh; + + class MEDCouplingStructuredMesh : public MEDCouplingMesh + { + public: + MEDCOUPLING_EXPORT INTERP_KERNEL::NormalizedCellType getTypeOfCell(int cellId) const; + MEDCOUPLING_EXPORT std::set<INTERP_KERNEL::NormalizedCellType> getAllGeoTypes() const; + MEDCOUPLING_EXPORT int getNumberOfCellsWithType(INTERP_KERNEL::NormalizedCellType type) const; + MEDCOUPLING_EXPORT DataArrayInt *giveCellsWithType(INTERP_KERNEL::NormalizedCellType type) const; + MEDCOUPLING_EXPORT DataArrayInt *computeNbOfNodesPerCell() const; + MEDCOUPLING_EXPORT DataArrayInt *computeNbOfFacesPerCell() const; + MEDCOUPLING_EXPORT DataArrayInt *computeEffectiveNbOfNodesPerCell() const; + MEDCOUPLING_EXPORT std::vector<int> getLocationFromCellId(int cellId) const; + MEDCOUPLING_EXPORT std::vector<int> getLocationFromNodeId(int nodeId) const; + MEDCOUPLING_EXPORT static void GetPosFromId(int eltId, int meshDim, const int *split, int *res); + MEDCOUPLING_EXPORT static INTERP_KERNEL::NormalizedCellType GetGeoTypeGivenMeshDimension(int meshDim); + MEDCOUPLING_EXPORT void getNodeIdsOfCell(int cellId, std::vector<int>& conn) const; + MEDCOUPLING_EXPORT std::size_t getHeapMemorySizeWithoutChildren() const; + MEDCOUPLING_EXPORT void copyTinyStringsFrom(const MEDCouplingMesh *other); + MEDCOUPLING_EXPORT bool isEqualIfNotWhy(const MEDCouplingMesh *other, double prec, std::string& reason) const; + //tools + MEDCOUPLING_EXPORT std::vector<int> getDistributionOfTypes() const; + MEDCOUPLING_EXPORT DataArrayInt *checkTypeConsistencyAndContig(const std::vector<int>& code, const std::vector<const DataArrayInt *>& idsPerType) const; + MEDCOUPLING_EXPORT void splitProfilePerType(const DataArrayInt *profile, std::vector<int>& code, std::vector<DataArrayInt *>& idsInPflPerType, std::vector<DataArrayInt *>& idsPerType) const; + MEDCOUPLING_EXPORT MEDCoupling1SGTUMesh *build1SGTUnstructured() const; + MEDCOUPLING_EXPORT MEDCouplingUMesh *buildUnstructured() const; + MEDCOUPLING_EXPORT MEDCouplingMesh *buildPart(const int *start, const int *end) const; + MEDCOUPLING_EXPORT MEDCouplingMesh *buildPartAndReduceNodes(const int *start, const int *end, DataArrayInt*& arr) const; + MEDCOUPLING_EXPORT DataArrayInt *simplexize(int policy); + MEDCOUPLING_EXPORT MEDCouplingFieldDouble *buildOrthogonalField() const; + MEDCOUPLING_EXPORT void getReverseNodalConnectivity(DataArrayInt *revNodal, DataArrayInt *revNodalIndx) const; + //some useful methods + MEDCOUPLING_EXPORT MEDCoupling1SGTUMesh *build1SGTSubLevelMesh() const; + MEDCOUPLING_EXPORT int getCellIdFromPos(int i, int j, int k) const; + MEDCOUPLING_EXPORT int getNodeIdFromPos(int i, int j, int k) const; + MEDCOUPLING_EXPORT int getNumberOfCells() const; + MEDCOUPLING_EXPORT int getNumberOfNodes() const; + MEDCOUPLING_EXPORT int getMeshDimension() const; + MEDCOUPLING_EXPORT int getNumberOfCellsOfSubLevelMesh() const; + MEDCOUPLING_EXPORT int getSpaceDimensionOnNodeStruct() const; + MEDCOUPLING_EXPORT virtual void getNodeGridStructure(int *res) const = 0; + MEDCOUPLING_EXPORT virtual void getSplitCellValues(int *res) const; + MEDCOUPLING_EXPORT virtual void getSplitNodeValues(int *res) const; + MEDCOUPLING_EXPORT virtual std::vector<int> getNodeGridStructure() const = 0; + MEDCOUPLING_EXPORT std::vector<int> getCellGridStructure() const; + MEDCOUPLING_EXPORT double computeSquareness() const; + MEDCOUPLING_EXPORT virtual MEDCouplingStructuredMesh *buildStructuredSubPart(const std::vector< std::pair<int,int> >& cellPart) const = 0; + MEDCOUPLING_EXPORT static std::vector<int> GetSplitVectFromStruct(const std::vector<int>& strct); + MEDCOUPLING_EXPORT static bool IsPartStructured(const int *startIds, const int *stopIds, const std::vector<int>& st, std::vector< std::pair<int,int> >& partCompactFormat); + MEDCOUPLING_EXPORT static std::vector<int> GetDimensionsFromCompactFrmt(const std::vector< std::pair<int,int> >& partCompactFormat); + MEDCOUPLING_EXPORT static std::vector< std::pair<int,int> > GetCompactFrmtFromDimensions(const std::vector<int>& dims); + MEDCOUPLING_EXPORT static std::vector< std::pair<int,int> > IntersectRanges(const std::vector< std::pair<int,int> >& r1, const std::vector< std::pair<int,int> >& r2); + MEDCOUPLING_EXPORT static bool AreRangesIntersect(const std::vector< std::pair<int,int> >& r1, const std::vector< std::pair<int,int> >& r2); + MEDCOUPLING_EXPORT static void SwitchOnIdsFrom(const std::vector<int>& st, const std::vector< std::pair<int,int> >& partCompactFormat, std::vector<bool>& vectToSwitchOn); + MEDCOUPLING_EXPORT static void ExtractFieldOfBoolFrom(const std::vector<int>& st, const std::vector<bool>& fieldOfBool, const std::vector< std::pair<int,int> >& partCompactFormat, std::vector<bool>& fieldOut); + MEDCOUPLING_EXPORT static DataArrayDouble *ExtractFieldOfDoubleFrom(const std::vector<int>& st, const DataArrayDouble *fieldOfDbl, const std::vector< std::pair<int,int> >& partCompactFormat); + MEDCOUPLING_EXPORT static void AssignPartOfFieldOfDoubleUsing(const std::vector<int>& st, DataArrayDouble *fieldOfDbl, const std::vector< std::pair<int,int> >& partCompactFormat, const DataArrayDouble *other); + MEDCOUPLING_EXPORT static void ChangeReferenceFromGlobalOfCompactFrmt(const std::vector< std::pair<int,int> >& bigInAbs, const std::vector< std::pair<int,int> >& partOfBigInAbs, std::vector< std::pair<int,int> >& partOfBigRelativeToBig, bool check=true); + MEDCOUPLING_EXPORT static void ChangeReferenceToGlobalOfCompactFrmt(const std::vector< std::pair<int,int> >& bigInAbs, const std::vector< std::pair<int,int> >& partOfBigRelativeToBig, std::vector< std::pair<int,int> >& partOfBigInAbs, bool check=true); + MEDCOUPLING_EXPORT static std::vector< std::pair<int,int> > TranslateCompactFrmt(const std::vector< std::pair<int,int> >& part, const std::vector<int>& translation); + MEDCOUPLING_EXPORT static std::vector<int> FindTranslationFrom(const std::vector< std::pair<int,int> >& startingFrom, const std::vector< std::pair<int,int> >& goingTo); + MEDCOUPLING_EXPORT static DataArrayInt *BuildExplicitIdsFrom(const std::vector<int>& st, const std::vector< std::pair<int,int> >& partCompactFormat); + MEDCOUPLING_EXPORT static void MultiplyPartOf(const std::vector<int>& st, const std::vector< std::pair<int,int> >& part, double factor, DataArrayDouble *da); + MEDCOUPLING_EXPORT static void MultiplyPartOfByGhost(const std::vector<int>& st, const std::vector< std::pair<int,int> >& part, int ghostSize, double factor, DataArrayDouble *da); + MEDCOUPLING_EXPORT static void PutInGhostFormat(int ghostSize, const std::vector<int>& st, const std::vector< std::pair<int,int> >& part, std::vector<int>& stWithGhost, std::vector< std::pair<int,int> >&partWithGhost); + MEDCOUPLING_EXPORT static void ApplyGhostOnCompactFrmt(std::vector< std::pair<int,int> >& partBeforeFact, int ghostSize); + MEDCOUPLING_EXPORT static DataArrayInt *Build1GTNodalConnectivity(const int *nodeStBg, const int *nodeStEnd); + MEDCOUPLING_EXPORT static DataArrayInt *Build1GTNodalConnectivityOfSubLevelMesh(const int *nodeStBg, const int *nodeStEnd); + MEDCOUPLING_EXPORT static DataArrayInt *ComputeCornersGhost(const std::vector<int>& st, int ghostLev); + MEDCOUPLING_EXPORT static int DeduceNumberOfGivenRangeInCompactFrmt(const std::vector< std::pair<int,int> >& partCompactFormat); + MEDCOUPLING_EXPORT static int DeduceNumberOfGivenStructure(const std::vector<int>& st); + MEDCOUPLING_EXPORT static void FindTheWidestAxisOfGivenRangeInCompactFrmt(const std::vector< std::pair<int,int> >& partCompactFormat, int& axisId, int& sizeOfRange); + MEDCOUPLING_EXPORT static int FindMinimalPartOf(int minPatchLgth, const std::vector<int>& st, const std::vector<bool>& crit, std::vector<bool>& reducedCrit, std::vector< std::pair<int,int> >& partCompactFormat); + MEDCOUPLING_EXPORT static std::vector< std::vector<int> > ComputeSignaturePerAxisOf(const std::vector<int>& st, const std::vector<bool>& crit); + private: + static int GetNumberOfCellsOfSubLevelMesh(const std::vector<int>& cgs, int mdim); + static void GetReverseNodalConnectivity1(const std::vector<int>& ngs, DataArrayInt *revNodal, DataArrayInt *revNodalIndx); + static void GetReverseNodalConnectivity2(const std::vector<int>& ngs, DataArrayInt *revNodal, DataArrayInt *revNodalIndx); + static void GetReverseNodalConnectivity3(const std::vector<int>& ngs, DataArrayInt *revNodal, DataArrayInt *revNodalIndx); + static DataArrayInt *Build1GTNodalConnectivity1D(const int *nodeStBg); + static DataArrayInt *Build1GTNodalConnectivity2D(const int *nodeStBg); + static DataArrayInt *Build1GTNodalConnectivity3D(const int *nodeStBg); + static DataArrayInt *Build1GTNodalConnectivityOfSubLevelMesh2D(const int *nodeStBg); + static DataArrayInt *Build1GTNodalConnectivityOfSubLevelMesh3D(const int *nodeStBg); + static int FindMinimalPartOf1D(const std::vector<int>& st, const std::vector<bool>& crit, std::vector< std::pair<int,int> >& partCompactFormat); + static int FindMinimalPartOf2D(const std::vector<int>& st, const std::vector<bool>& crit, std::vector< std::pair<int,int> >& partCompactFormat); + static int FindMinimalPartOf3D(const std::vector<int>& st, const std::vector<bool>& crit, std::vector< std::pair<int,int> >& partCompactFormat); + protected: + static int ZipNodeStructure(const int *nodeStBg, const int *nodeStEnd, int zipNodeSt[3]); + protected: + MEDCOUPLING_EXPORT MEDCouplingStructuredMesh(); + MEDCOUPLING_EXPORT MEDCouplingStructuredMesh(const MEDCouplingStructuredMesh& other, bool deepCpy); + MEDCOUPLING_EXPORT ~MEDCouplingStructuredMesh(); + }; +} + +#endif diff --git a/src/medtool/src/MEDCoupling/MEDCouplingTimeDiscretization.cxx b/src/medtool/src/MEDCoupling/MEDCouplingTimeDiscretization.cxx new file mode 100644 index 000000000..cb456a024 --- /dev/null +++ b/src/medtool/src/MEDCoupling/MEDCouplingTimeDiscretization.cxx @@ -0,0 +1,2951 @@ +// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 +// 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 "MEDCouplingTimeDiscretization.hxx" +#include "MEDCouplingAutoRefCountObjectPtr.hxx" +#include "MEDCouplingMemArray.hxx" +#include "MEDCouplingMesh.hxx" + +#include <cmath> +#include <sstream> +#include <iterator> +#include <algorithm> +#include <functional> + +using namespace ParaMEDMEM; + +const double MEDCouplingTimeDiscretization::TIME_TOLERANCE_DFT=1.e-12; + +const char MEDCouplingNoTimeLabel::EXCEPTION_MSG[]="MEDCouplingNoTimeLabel::setTime : no time info attached."; + +const char MEDCouplingNoTimeLabel::REPR[]="No time label defined."; + +const char MEDCouplingWithTimeStep::EXCEPTION_MSG[]="No data on this time."; + +const char MEDCouplingWithTimeStep::REPR[]="One time label."; + +const char MEDCouplingConstOnTimeInterval::EXCEPTION_MSG[]="No data on this time."; + +const char MEDCouplingConstOnTimeInterval::REPR[]="Constant on a time interval."; + +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) +{ + switch(type) + { + case MEDCouplingNoTimeLabel::DISCRETIZATION: + return new MEDCouplingNoTimeLabel; + case MEDCouplingWithTimeStep::DISCRETIZATION: + return new MEDCouplingWithTimeStep; + case MEDCouplingConstOnTimeInterval::DISCRETIZATION: + return new MEDCouplingConstOnTimeInterval; + case MEDCouplingLinearTime::DISCRETIZATION: + return new MEDCouplingLinearTime; + default: + throw INTERP_KERNEL::Exception("Time discretization not implemented yet"); + } +} + +void MEDCouplingTimeDiscretization::copyTinyAttrFrom(const MEDCouplingTimeDiscretization& other) +{ + _time_tolerance=other._time_tolerance; + _time_unit=other._time_unit; +} + +void MEDCouplingTimeDiscretization::copyTinyStringsFrom(const MEDCouplingTimeDiscretization& other) +{ + _time_unit=other._time_unit; + if(_array && other._array) + _array->copyStringInfoFrom(*other._array); +} + +void MEDCouplingTimeDiscretization::checkCoherency() const +{ + if(!_array) + throw INTERP_KERNEL::Exception("Field invalid because no values set !"); + if(_time_tolerance<0.) + throw INTERP_KERNEL::Exception("time tolerance is expected to be greater than 0. !"); +} + +void MEDCouplingTimeDiscretization::updateTime() const +{ + if(_array) + updateTimeWith(*_array); +} + +std::size_t MEDCouplingTimeDiscretization::getHeapMemorySizeWithoutChildren() const +{ + std::size_t ret(_time_unit.capacity()); + return ret; +} + +std::vector<const BigMemoryObject *> MEDCouplingTimeDiscretization::getDirectChildrenWithNull() const +{ + std::vector<const BigMemoryObject *> ret; + ret.push_back(_array); + return ret; +} + +bool MEDCouplingTimeDiscretization::areCompatible(const MEDCouplingTimeDiscretization *other) const +{ + if(std::fabs(_time_tolerance-other->_time_tolerance)>1.e-16) + return false; + if(_array==0 && other->_array==0) + return true; + if(_array==0 || other->_array==0) + return false; + if(_array->getNumberOfComponents()!=other->_array->getNumberOfComponents()) + return false; + return true; +} + +bool MEDCouplingTimeDiscretization::areStrictlyCompatible(const MEDCouplingTimeDiscretization *other, std::string& reason) const +{ + std::ostringstream oss; oss.precision(15); + if(_time_unit!=other->_time_unit) + { + oss << "Field discretizations differ : this time unit = \"" << _time_unit << "\" and other time unit = \"" << other->_time_unit << "\" !"; + reason=oss.str(); + return false; + } + if(std::fabs(_time_tolerance-other->_time_tolerance)>1.e-16) + { + oss << "Field discretizations differ : this time tolerance = \"" << _time_tolerance << "\" and other time tolerance = \"" << other->_time_tolerance << "\" !"; + reason=oss.str(); + return false; + } + if(_array==0 && other->_array==0) + return true; + if(_array==0 || other->_array==0) + { + reason="Field discretizations differ : Only one timediscretization between the two this and other has a DataArrayDouble for values defined"; + return false; + } + if(_array->getNumberOfComponents()!=other->_array->getNumberOfComponents()) + return false; + if(_array->getNumberOfTuples()!=other->_array->getNumberOfTuples()) + return false; + return true; +} + +bool MEDCouplingTimeDiscretization::areCompatibleForMeld(const MEDCouplingTimeDiscretization *other) const +{ + if(std::fabs(_time_tolerance-other->_time_tolerance)>1.e-16) + return false; + if(_array==0 && other->_array==0) + return true; + if(_array==0 || other->_array==0) + return false; + if(_array->getNumberOfTuples()!=other->_array->getNumberOfTuples()) + return false; + return true; +} + +bool MEDCouplingTimeDiscretization::areStrictlyCompatibleForMul(const MEDCouplingTimeDiscretization *other) const +{ + if(std::fabs(_time_tolerance-other->_time_tolerance)>1.e-16) + return false; + if(_array==0 && other->_array==0) + return true; + if(_array==0 || other->_array==0) + return false; + int nbC1=_array->getNumberOfComponents(); + int nbC2=other->_array->getNumberOfComponents(); + int nbMin=std::min(nbC1,nbC2); + if(nbC1!=nbC2 && nbMin!=1) + return false; + return true; +} + +bool MEDCouplingTimeDiscretization::areStrictlyCompatibleForDiv(const MEDCouplingTimeDiscretization *other) const +{ + if(std::fabs(_time_tolerance-other->_time_tolerance)>1.e-16) + return false; + if(_array==0 && other->_array==0) + return true; + if(_array==0 || other->_array==0) + return false; + int nbC1=_array->getNumberOfComponents(); + int nbC2=other->_array->getNumberOfComponents(); + if(nbC1!=nbC2 && nbC2!=1) + return false; + return true; +} + +bool MEDCouplingTimeDiscretization::isEqualIfNotWhy(const MEDCouplingTimeDiscretization *other, double prec, std::string& reason) const +{ + if(!areStrictlyCompatible(other,reason)) + return false; + if(_array==other->_array) + return true; + return _array->isEqualIfNotWhy(*other->_array,prec,reason); +} + +bool MEDCouplingTimeDiscretization::isEqual(const MEDCouplingTimeDiscretization *other, double prec) const +{ + std::string reason; + return isEqualIfNotWhy(other,prec,reason); +} + +bool MEDCouplingTimeDiscretization::isEqualWithoutConsideringStr(const MEDCouplingTimeDiscretization *other, double prec) const +{ + std::string tmp; + if(!areStrictlyCompatible(other,tmp)) + return false; + if(_array==other->_array) + return true; + return _array->isEqualWithoutConsideringStr(*other->_array,prec); +} + +MEDCouplingTimeDiscretization *MEDCouplingTimeDiscretization::buildNewTimeReprFromThis(TypeOfTimeDiscretization type, bool deepCpy) const +{ + MEDCouplingTimeDiscretization *ret=MEDCouplingTimeDiscretization::New(type); + ret->setTimeUnit(getTimeUnit()); + const DataArrayDouble *arrSrc=getArray(); + MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> arr; + if(arrSrc) + arr=arrSrc->performCpy(deepCpy); + ret->setArray(arr,0); + return ret; +} + +void MEDCouplingTimeDiscretization::getTinySerializationIntInformation(std::vector<int>& tinyInfo) const +{ + if(_array) + { + tinyInfo.push_back(_array->getNumberOfTuples()); + tinyInfo.push_back(_array->getNumberOfComponents()); + } + else + { + tinyInfo.push_back(-1); + tinyInfo.push_back(-1); + } +} + +void MEDCouplingTimeDiscretization::resizeForUnserialization(const std::vector<int>& tinyInfoI, std::vector<DataArrayDouble *>& arrays) +{ + arrays.resize(1); + if(_array!=0) + _array->decrRef(); + DataArrayDouble *arr=0; + if(tinyInfoI[0]!=-1 && tinyInfoI[1]!=-1) + { + arr=DataArrayDouble::New(); + arr->alloc(tinyInfoI[0],tinyInfoI[1]); + } + _array=arr; + arrays[0]=arr; +} + +void MEDCouplingTimeDiscretization::checkForUnserialization(const std::vector<int>& tinyInfoI, const std::vector<DataArrayDouble *>& arrays) +{ + static const char MSG[]="MEDCouplingTimeDiscretization::checkForUnserialization : arrays in input is expected to have size one !"; + if(arrays.size()!=1) + throw INTERP_KERNEL::Exception(MSG); + if(_array!=0) + _array->decrRef(); + _array=0; + if(tinyInfoI[0]!=-1 && tinyInfoI[1]!=-1) + { + if(!arrays[0]) + throw INTERP_KERNEL::Exception(MSG); + arrays[0]->checkNbOfTuplesAndComp(tinyInfoI[0],tinyInfoI[1],MSG); + _array=arrays[0]; + _array->incrRef(); + } +} + +void MEDCouplingTimeDiscretization::finishUnserialization(const std::vector<int>& tinyInfoI, const std::vector<double>& tinyInfoD, const std::vector<std::string>& tinyInfoS) +{ + _time_tolerance=tinyInfoD[0]; + int nbOfCompo=_array->getNumberOfComponents(); + for(int i=0;i<nbOfCompo;i++) + _array->setInfoOnComponent(i,tinyInfoS[i]); +} + +void MEDCouplingTimeDiscretization::getTinySerializationDbleInformation(std::vector<double>& tinyInfo) const +{ + tinyInfo.push_back(_time_tolerance); +} + +void MEDCouplingTimeDiscretization::getTinySerializationStrInformation(std::vector<std::string>& tinyInfo) const +{ + int nbOfCompo=_array->getNumberOfComponents(); + for(int i=0;i<nbOfCompo;i++) + tinyInfo.push_back(_array->getInfoOnComponent(i)); +} + +MEDCouplingTimeDiscretization::MEDCouplingTimeDiscretization():_time_tolerance(TIME_TOLERANCE_DFT),_array(0) +{ +} + +MEDCouplingTimeDiscretization::MEDCouplingTimeDiscretization(const MEDCouplingTimeDiscretization& other, bool deepCpy):_time_unit(other._time_unit),_time_tolerance(other._time_tolerance) +{ + if(other._array) + _array=other._array->performCpy(deepCpy); + else + _array=0; +} + +MEDCouplingTimeDiscretization::~MEDCouplingTimeDiscretization() +{ + if(_array) + _array->decrRef(); +} + +void MEDCouplingTimeDiscretization::setArray(DataArrayDouble *array, TimeLabel *owner) +{ + if(array!=_array) + { + if(_array) + _array->decrRef(); + _array=array; + if(_array) + _array->incrRef(); + if(owner) + owner->declareAsNew(); + } +} + +const DataArrayDouble *MEDCouplingTimeDiscretization::getEndArray() const +{ + throw INTERP_KERNEL::Exception("getEndArray not available for this type of time discretization !"); +} + +DataArrayDouble *MEDCouplingTimeDiscretization::getEndArray() +{ + throw INTERP_KERNEL::Exception("getEndArray not available for this type of time discretization !"); +} + +void MEDCouplingTimeDiscretization::setEndArray(DataArrayDouble *array, TimeLabel *owner) +{ + throw INTERP_KERNEL::Exception("setEndArray not available for this type of time discretization !"); +} + +void MEDCouplingTimeDiscretization::setArrays(const std::vector<DataArrayDouble *>& arrays, TimeLabel *owner) +{ + if(arrays.size()!=1) + throw INTERP_KERNEL::Exception("MEDCouplingTimeDiscretization::setArrays : number of arrays must be one."); + setArray(arrays.back(),owner); +} + +void MEDCouplingTimeDiscretization::getArrays(std::vector<DataArrayDouble *>& arrays) const +{ + arrays.resize(1); + arrays[0]=_array; +} + +bool MEDCouplingTimeDiscretization::isBefore(const MEDCouplingTimeDiscretization *other) const +{ + int iteration,order; + double time1=getEndTime(iteration,order)-_time_tolerance; + double time2=other->getStartTime(iteration,order)+other->getTimeTolerance(); + return time1<=time2; +} + +bool MEDCouplingTimeDiscretization::isStrictlyBefore(const MEDCouplingTimeDiscretization *other) const +{ + int iteration,order; + double time1=getEndTime(iteration,order)+_time_tolerance; + double time2=other->getStartTime(iteration,order)-other->getTimeTolerance(); + return time1<time2; +} + +MEDCouplingTimeDiscretization *MEDCouplingTimeDiscretization::doublyContractedProduct() const +{ + MEDCouplingTimeDiscretization *ret=MEDCouplingTimeDiscretization::New(getEnum()); + ret->setTimeUnit(getTimeUnit()); + std::vector<DataArrayDouble *> arrays; + getArrays(arrays); + std::vector< MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> > arrays2(arrays.size()); + for(std::size_t j=0;j<arrays.size();j++) + { + if(arrays[j]) + arrays2[j]=arrays[j]->doublyContractedProduct(); + else + arrays2[j]=0; + } + std::vector<DataArrayDouble *> arrays3(arrays.size()); + for(std::size_t j=0;j<arrays.size();j++) + arrays3[j]=arrays2[j]; + ret->setArrays(arrays3,0); + return ret; +} + +MEDCouplingTimeDiscretization *MEDCouplingTimeDiscretization::determinant() const +{ + std::vector<DataArrayDouble *> arrays; + getArrays(arrays); + std::vector< MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> > arrays2(arrays.size()); + for(std::size_t j=0;j<arrays.size();j++) + { + if(arrays[j]) + arrays2[j]=arrays[j]->determinant(); + else + arrays2[j]=0; + } + std::vector<DataArrayDouble *> arrays3(arrays.size()); + for(std::size_t j=0;j<arrays.size();j++) + arrays3[j]=arrays2[j]; + MEDCouplingTimeDiscretization *ret=MEDCouplingTimeDiscretization::New(getEnum()); + ret->setTimeUnit(getTimeUnit()); + ret->setArrays(arrays3,0); + return ret; +} + +MEDCouplingTimeDiscretization *MEDCouplingTimeDiscretization::eigenValues() const +{ + std::vector<DataArrayDouble *> arrays; + getArrays(arrays); + std::vector< MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> > arrays2(arrays.size()); + for(std::size_t j=0;j<arrays.size();j++) + { + if(arrays[j]) + arrays2[j]=arrays[j]->eigenValues(); + else + arrays2[j]=0; + } + std::vector<DataArrayDouble *> arrays3(arrays.size()); + for(std::size_t j=0;j<arrays.size();j++) + arrays3[j]=arrays2[j]; + MEDCouplingTimeDiscretization *ret=MEDCouplingTimeDiscretization::New(getEnum()); + ret->setTimeUnit(getTimeUnit()); + ret->setArrays(arrays3,0); + return ret; +} + +MEDCouplingTimeDiscretization *MEDCouplingTimeDiscretization::eigenVectors() const +{ + std::vector<DataArrayDouble *> arrays; + getArrays(arrays); + std::vector< MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> > arrays2(arrays.size()); + for(std::size_t j=0;j<arrays.size();j++) + { + if(arrays[j]) + arrays2[j]=arrays[j]->eigenVectors(); + else + arrays2[j]=0; + } + std::vector<DataArrayDouble *> arrays3(arrays.size()); + for(std::size_t j=0;j<arrays.size();j++) + arrays3[j]=arrays2[j]; + MEDCouplingTimeDiscretization *ret=MEDCouplingTimeDiscretization::New(getEnum()); + ret->setTimeUnit(getTimeUnit()); + ret->setArrays(arrays3,0); + return ret; +} + +MEDCouplingTimeDiscretization *MEDCouplingTimeDiscretization::inverse() const +{ + std::vector<DataArrayDouble *> arrays; + getArrays(arrays); + std::vector< MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> > arrays2(arrays.size()); + for(std::size_t j=0;j<arrays.size();j++) + { + if(arrays[j]) + arrays2[j]=arrays[j]->inverse(); + else + arrays2[j]=0; + } + std::vector<DataArrayDouble *> arrays3(arrays.size()); + for(std::size_t j=0;j<arrays.size();j++) + arrays3[j]=arrays2[j]; + MEDCouplingTimeDiscretization *ret=MEDCouplingTimeDiscretization::New(getEnum()); + ret->setTimeUnit(getTimeUnit()); + ret->setArrays(arrays3,0); + return ret; +} + +MEDCouplingTimeDiscretization *MEDCouplingTimeDiscretization::trace() const +{ + std::vector<DataArrayDouble *> arrays; + getArrays(arrays); + std::vector< MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> > arrays2(arrays.size()); + for(std::size_t j=0;j<arrays.size();j++) + { + if(arrays[j]) + arrays2[j]=arrays[j]->trace(); + else + arrays2[j]=0; + } + std::vector<DataArrayDouble *> arrays3(arrays.size()); + for(std::size_t j=0;j<arrays.size();j++) + arrays3[j]=arrays2[j]; + MEDCouplingTimeDiscretization *ret=MEDCouplingTimeDiscretization::New(getEnum()); + ret->setTimeUnit(getTimeUnit()); + ret->setArrays(arrays3,0); + return ret; +} + +MEDCouplingTimeDiscretization *MEDCouplingTimeDiscretization::deviator() const +{ + std::vector<DataArrayDouble *> arrays; + getArrays(arrays); + std::vector< MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> > arrays2(arrays.size()); + for(std::size_t j=0;j<arrays.size();j++) + { + if(arrays[j]) + arrays2[j]=arrays[j]->deviator(); + else + arrays2[j]=0; + } + std::vector<DataArrayDouble *> arrays3(arrays.size()); + for(std::size_t j=0;j<arrays.size();j++) + arrays3[j]=arrays2[j]; + MEDCouplingTimeDiscretization *ret=MEDCouplingTimeDiscretization::New(getEnum()); + ret->setTimeUnit(getTimeUnit()); + ret->setArrays(arrays3,0); + return ret; +} + +MEDCouplingTimeDiscretization *MEDCouplingTimeDiscretization::magnitude() const +{ + std::vector<DataArrayDouble *> arrays; + getArrays(arrays); + std::vector< MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> > arrays2(arrays.size()); + for(std::size_t j=0;j<arrays.size();j++) + { + if(arrays[j]) + arrays2[j]=arrays[j]->magnitude(); + else + arrays2[j]=0; + } + std::vector<DataArrayDouble *> arrays3(arrays.size()); + for(std::size_t j=0;j<arrays.size();j++) + arrays3[j]=arrays2[j]; + MEDCouplingTimeDiscretization *ret=MEDCouplingTimeDiscretization::New(getEnum()); + ret->setTimeUnit(getTimeUnit()); + ret->setArrays(arrays3,0); + return ret; +} + +MEDCouplingTimeDiscretization *MEDCouplingTimeDiscretization::negate() const +{ + std::vector<DataArrayDouble *> arrays; + getArrays(arrays); + std::vector< MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> > arrays2(arrays.size()); + for(std::size_t j=0;j<arrays.size();j++) + { + if(arrays[j]) + arrays2[j]=arrays[j]->negate(); + else + arrays2[j]=0; + } + std::vector<DataArrayDouble *> arrays3(arrays.size()); + for(std::size_t j=0;j<arrays.size();j++) + arrays3[j]=arrays2[j]; + MEDCouplingTimeDiscretization *ret=MEDCouplingTimeDiscretization::New(getEnum()); + ret->setTimeUnit(getTimeUnit()); + ret->setArrays(arrays3,0); + return ret; +} + +MEDCouplingTimeDiscretization *MEDCouplingTimeDiscretization::maxPerTuple() const +{ + std::vector<DataArrayDouble *> arrays; + getArrays(arrays); + std::vector< MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> > arrays2(arrays.size()); + for(std::size_t j=0;j<arrays.size();j++) + { + if(arrays[j]) + arrays2[j]=arrays[j]->maxPerTuple(); + else + arrays2[j]=0; + } + std::vector<DataArrayDouble *> arrays3(arrays.size()); + for(std::size_t j=0;j<arrays.size();j++) + arrays3[j]=arrays2[j]; + MEDCouplingTimeDiscretization *ret=MEDCouplingTimeDiscretization::New(getEnum()); + ret->setTimeUnit(getTimeUnit()); + ret->setArrays(arrays3,0); + return ret; +} + +MEDCouplingTimeDiscretization *MEDCouplingTimeDiscretization::keepSelectedComponents(const std::vector<int>& compoIds) const +{ + std::vector<DataArrayDouble *> arrays; + getArrays(arrays); + std::vector< MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> > arrays2(arrays.size()); + for(std::size_t j=0;j<arrays.size();j++) + { + if(arrays[j]) + arrays2[j]=static_cast<DataArrayDouble *>(arrays[j]->keepSelectedComponents(compoIds)); + else + arrays2[j]=0; + } + std::vector<DataArrayDouble *> arrays3(arrays.size()); + for(std::size_t j=0;j<arrays.size();j++) + arrays3[j]=arrays2[j]; + MEDCouplingTimeDiscretization *ret=MEDCouplingTimeDiscretization::New(getEnum()); + ret->setTimeUnit(getTimeUnit()); + ret->setArrays(arrays3,0); + return ret; +} + +void MEDCouplingTimeDiscretization::setSelectedComponents(const MEDCouplingTimeDiscretization *other, const std::vector<int>& compoIds) +{ + std::vector<DataArrayDouble *> arrays1,arrays2; + getArrays(arrays1); + other->getArrays(arrays2); + if(arrays1.size()!=arrays2.size()) + throw INTERP_KERNEL::Exception("TimeDiscretization::setSelectedComponents : number of arrays mismatch !"); + for(std::size_t i=0;i<arrays1.size();i++) + { + if(arrays1[i]!=0 && arrays2[i]!=0) + arrays1[i]->setSelectedComponents(arrays2[i],compoIds); + else if(arrays1[i]!=0 || arrays2[i]!=0) + throw INTERP_KERNEL::Exception("TimeDiscretization::setSelectedComponents : some time array in correspondance are not defined symetrically !"); + } +} + +void MEDCouplingTimeDiscretization::changeNbOfComponents(int newNbOfComp, double dftValue) +{ + std::vector<DataArrayDouble *> arrays; + getArrays(arrays); + std::vector< MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> > arrays2(arrays.size()); + for(std::size_t j=0;j<arrays.size();j++) + { + if(arrays[j]) + arrays2[j]=arrays[j]->changeNbOfComponents(newNbOfComp,dftValue); + else + arrays2[j]=0; + } + std::vector<DataArrayDouble *> arrays3(arrays.size()); + for(std::size_t j=0;j<arrays.size();j++) + arrays3[j]=arrays2[j]; + setArrays(arrays3,0); +} + +void MEDCouplingTimeDiscretization::sortPerTuple(bool asc) +{ + std::vector<DataArrayDouble *> arrays; + getArrays(arrays); + for(std::size_t j=0;j<arrays.size();j++) + { + if(arrays[j]) + arrays[j]->sortPerTuple(asc); + } +} + +void MEDCouplingTimeDiscretization::setUniformValue(int nbOfTuple, int nbOfCompo, double value) +{ + std::vector<DataArrayDouble *> arrays; + getArrays(arrays); + std::vector< MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> > arrays2(arrays.size()); + for(std::size_t j=0;j<arrays.size();j++) + { + if(arrays[j]) + { + arrays2[j]=arrays[j]->changeNbOfComponents(nbOfCompo,value); + arrays2[j]->fillWithValue(value); + } + else + { + arrays2[j]=DataArrayDouble::New(); + arrays2[j]->alloc(nbOfTuple,nbOfCompo); + arrays2[j]->fillWithValue(value); + } + } + std::vector<DataArrayDouble *> arrays3(arrays.size()); + for(std::size_t j=0;j<arrays.size();j++) + arrays3[j]=arrays2[j]; + setArrays(arrays3,0); +} + +void MEDCouplingTimeDiscretization::setOrCreateUniformValueOnAllComponents(int nbOfTuple, double value) +{ + std::vector<DataArrayDouble *> arrays; + getArrays(arrays); + std::vector< MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> > arrays2(arrays.size()); + bool newArr=false; + for(std::size_t j=0;j<arrays.size();j++) + { + if(arrays[j]) + { + arrays2[j]=arrays[j]; arrays2[j]->incrRef(); + arrays2[j]->fillWithValue(value); + } + else + { + newArr=true; + arrays2[j]=DataArrayDouble::New(); + arrays2[j]->alloc(nbOfTuple,1); + arrays2[j]->fillWithValue(value); + } + } + if(newArr) + { + std::vector<DataArrayDouble *> arrays3(arrays.size()); + for(std::size_t j=0;j<arrays.size();j++) + arrays3[j]=arrays2[j]; + setArrays(arrays3,0); + } +} + +void MEDCouplingTimeDiscretization::applyLin(double a, double b, int compoId) +{ + std::vector<DataArrayDouble *> arrays; + getArrays(arrays); + for(std::size_t j=0;j<arrays.size();j++) + { + if(arrays[j]) + arrays[j]->applyLin(a,b,compoId); + } +} + +void MEDCouplingTimeDiscretization::applyLin(double a, double b) +{ + std::vector<DataArrayDouble *> arrays; + getArrays(arrays); + for(std::size_t j=0;j<arrays.size();j++) + { + if(arrays[j]) + arrays[j]->applyLin(a,b); + } +} + +void MEDCouplingTimeDiscretization::applyFunc(int nbOfComp, FunctionToEvaluate func) +{ + std::vector<DataArrayDouble *> arrays; + getArrays(arrays); + std::vector< MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> > arrays2(arrays.size()); + for(std::size_t j=0;j<arrays.size();j++) + { + if(arrays[j]) + arrays2[j]=arrays[j]->applyFunc(nbOfComp,func); + else + arrays2[j]=0; + } + std::vector<DataArrayDouble *> arrays3(arrays.size()); + for(std::size_t j=0;j<arrays.size();j++) + arrays3[j]=arrays2[j]; + setArrays(arrays3,0); +} + +void MEDCouplingTimeDiscretization::applyFunc(int nbOfComp, const std::string& func) +{ + std::vector<DataArrayDouble *> arrays; + getArrays(arrays); + std::vector< MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> > arrays2(arrays.size()); + for(std::size_t j=0;j<arrays.size();j++) + { + if(arrays[j]) + arrays2[j]=arrays[j]->applyFunc(nbOfComp,func); + else + arrays2[j]=0; + } + std::vector<DataArrayDouble *> arrays3(arrays.size()); + for(std::size_t j=0;j<arrays.size();j++) + arrays3[j]=arrays2[j]; + setArrays(arrays3,0); +} + +void MEDCouplingTimeDiscretization::applyFunc2(int nbOfComp, const std::string& func) +{ + std::vector<DataArrayDouble *> arrays; + getArrays(arrays); + std::vector< MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> > arrays2(arrays.size()); + for(std::size_t j=0;j<arrays.size();j++) + { + if(arrays[j]) + arrays2[j]=arrays[j]->applyFunc2(nbOfComp,func); + else + arrays2[j]=0; + } + std::vector<DataArrayDouble *> arrays3(arrays.size()); + for(std::size_t j=0;j<arrays.size();j++) + arrays3[j]=arrays2[j]; + setArrays(arrays3,0); +} + +void MEDCouplingTimeDiscretization::applyFunc3(int nbOfComp, const std::vector<std::string>& varsOrder, const std::string& func) +{ + std::vector<DataArrayDouble *> arrays; + getArrays(arrays); + std::vector< MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> > arrays2(arrays.size()); + for(std::size_t j=0;j<arrays.size();j++) + { + if(arrays[j]) + arrays2[j]=arrays[j]->applyFunc3(nbOfComp,varsOrder,func); + else + arrays2[j]=0; + } + std::vector<DataArrayDouble *> arrays3(arrays.size()); + for(std::size_t j=0;j<arrays.size();j++) + arrays3[j]=arrays2[j]; + setArrays(arrays3,0); +} + +void MEDCouplingTimeDiscretization::applyFunc(const std::string& func) +{ + std::vector<DataArrayDouble *> arrays; + getArrays(arrays); + std::vector< MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> > arrays2(arrays.size()); + for(std::size_t j=0;j<arrays.size();j++) + { + if(arrays[j]) + arrays2[j]=arrays[j]->applyFunc(func); + else + arrays2[j]=0; + } + std::vector<DataArrayDouble *> arrays3(arrays.size()); + for(std::size_t j=0;j<arrays.size();j++) + arrays3[j]=arrays2[j]; + setArrays(arrays3,0); +} + +void MEDCouplingTimeDiscretization::applyFuncFast32(const std::string& func) +{ + std::vector<DataArrayDouble *> arrays; + getArrays(arrays); + for(std::size_t j=0;j<arrays.size();j++) + { + if(arrays[j]) + arrays[j]->applyFuncFast32(func); + } +} + +void MEDCouplingTimeDiscretization::applyFuncFast64(const std::string& func) +{ + std::vector<DataArrayDouble *> arrays; + getArrays(arrays); + for(std::size_t j=0;j<arrays.size();j++) + { + if(arrays[j]) + arrays[j]->applyFuncFast64(func); + } +} + +void MEDCouplingTimeDiscretization::fillFromAnalytic(const DataArrayDouble *loc, int nbOfComp, FunctionToEvaluate func) +{ + std::vector<DataArrayDouble *> arrays; + getArrays(arrays); + std::vector< MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> > arrays2(arrays.size()); + for(std::size_t j=0;j<arrays.size();j++) + arrays2[j]=loc->applyFunc(nbOfComp,func); + std::vector<DataArrayDouble *> arrays3(arrays.size()); + for(std::size_t j=0;j<arrays.size();j++) + arrays3[j]=arrays2[j]; + setArrays(arrays3,0); +} + +void MEDCouplingTimeDiscretization::fillFromAnalytic(const DataArrayDouble *loc, int nbOfComp, const std::string& func) +{ + std::vector<DataArrayDouble *> arrays; + getArrays(arrays); + std::vector< MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> > arrays2(arrays.size()); + for(std::size_t j=0;j<arrays.size();j++) + arrays2[j]=loc->applyFunc(nbOfComp,func); + std::vector<DataArrayDouble *> arrays3(arrays.size()); + for(std::size_t j=0;j<arrays.size();j++) + arrays3[j]=arrays2[j]; + setArrays(arrays3,0); +} + +void MEDCouplingTimeDiscretization::fillFromAnalytic2(const DataArrayDouble *loc, int nbOfComp, const std::string& func) +{ + std::vector<DataArrayDouble *> arrays; + getArrays(arrays); + std::vector< MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> > arrays2(arrays.size()); + for(std::size_t j=0;j<arrays.size();j++) + arrays2[j]=loc->applyFunc2(nbOfComp,func); + std::vector<DataArrayDouble *> arrays3(arrays.size()); + for(std::size_t j=0;j<arrays.size();j++) + arrays3[j]=arrays2[j]; + setArrays(arrays3,0); +} + +void MEDCouplingTimeDiscretization::fillFromAnalytic3(const DataArrayDouble *loc, int nbOfComp, const std::vector<std::string>& varsOrder, const std::string& func) +{ + std::vector<DataArrayDouble *> arrays; + getArrays(arrays); + std::vector< MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> > arrays2(arrays.size()); + for(std::size_t j=0;j<arrays.size();j++) + arrays2[j]=loc->applyFunc3(nbOfComp,varsOrder,func); + std::vector<DataArrayDouble *> arrays3(arrays.size()); + for(std::size_t j=0;j<arrays.size();j++) + arrays3[j]=arrays2[j]; + setArrays(arrays3,0); +} + +MEDCouplingNoTimeLabel::MEDCouplingNoTimeLabel() +{ +} + +MEDCouplingNoTimeLabel::MEDCouplingNoTimeLabel(const MEDCouplingTimeDiscretization& other, bool deepCpy):MEDCouplingTimeDiscretization(other,deepCpy) +{ +} + +std::string MEDCouplingNoTimeLabel::getStringRepr() const +{ + std::ostringstream stream; + stream << REPR; + stream << "\nTime unit is : \"" << _time_unit << "\""; + return stream.str(); +} + +void MEDCouplingNoTimeLabel::synchronizeTimeWith(const MEDCouplingMesh *mesh) +{ + throw INTERP_KERNEL::Exception("MEDCouplingNoTimeLabel::synchronizeTimeWith : impossible to synchronize time with a MEDCouplingMesh because the time discretization is incompatible with it !"); +} + +bool MEDCouplingNoTimeLabel::areCompatible(const MEDCouplingTimeDiscretization *other) const +{ + if(!MEDCouplingTimeDiscretization::areCompatible(other)) + return false; + const MEDCouplingNoTimeLabel *otherC=dynamic_cast<const MEDCouplingNoTimeLabel *>(other); + return otherC!=0; +} + +bool MEDCouplingNoTimeLabel::areStrictlyCompatible(const MEDCouplingTimeDiscretization *other, std::string& reason) const +{ + if(!MEDCouplingTimeDiscretization::areStrictlyCompatible(other,reason)) + return false; + const MEDCouplingNoTimeLabel *otherC=dynamic_cast<const MEDCouplingNoTimeLabel *>(other); + bool ret=otherC!=0; + if(!ret) + reason.insert(0,"time discretization of this is NO_TIME, other has a different time discretization."); + return ret; +} + +bool MEDCouplingNoTimeLabel::areStrictlyCompatibleForMul(const MEDCouplingTimeDiscretization *other) const +{ + if(!MEDCouplingTimeDiscretization::areStrictlyCompatibleForMul(other)) + return false; + const MEDCouplingNoTimeLabel *otherC=dynamic_cast<const MEDCouplingNoTimeLabel *>(other); + return otherC!=0; +} + +bool MEDCouplingNoTimeLabel::areStrictlyCompatibleForDiv(const MEDCouplingTimeDiscretization *other) const +{ + if(!MEDCouplingTimeDiscretization::areStrictlyCompatibleForDiv(other)) + return false; + const MEDCouplingNoTimeLabel *otherC=dynamic_cast<const MEDCouplingNoTimeLabel *>(other); + return otherC!=0; +} + +bool MEDCouplingNoTimeLabel::areCompatibleForMeld(const MEDCouplingTimeDiscretization *other) const +{ + if(!MEDCouplingTimeDiscretization::areCompatibleForMeld(other)) + return false; + const MEDCouplingNoTimeLabel *otherC=dynamic_cast<const MEDCouplingNoTimeLabel *>(other); + return otherC!=0; +} + +bool MEDCouplingNoTimeLabel::isEqualIfNotWhy(const MEDCouplingTimeDiscretization *other, double prec, std::string& reason) const +{ + const MEDCouplingNoTimeLabel *otherC=dynamic_cast<const MEDCouplingNoTimeLabel *>(other); + if(!otherC) + { + reason="This has time discretization NO_TIME, other not."; + return false; + } + return MEDCouplingTimeDiscretization::isEqualIfNotWhy(other,prec,reason); +} + +bool MEDCouplingNoTimeLabel::isEqualWithoutConsideringStr(const MEDCouplingTimeDiscretization *other, double prec) const +{ + const MEDCouplingNoTimeLabel *otherC=dynamic_cast<const MEDCouplingNoTimeLabel *>(other); + if(!otherC) + return false; + return MEDCouplingTimeDiscretization::isEqualWithoutConsideringStr(other,prec); +} + +MEDCouplingTimeDiscretization *MEDCouplingNoTimeLabel::aggregate(const MEDCouplingTimeDiscretization *other) const +{ + const MEDCouplingNoTimeLabel *otherC=dynamic_cast<const MEDCouplingNoTimeLabel *>(other); + if(!otherC) + throw INTERP_KERNEL::Exception("NoTimeLabel::aggregation on mismatched time discretization !"); + MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> arr=DataArrayDouble::Aggregate(getArray(),other->getArray()); + MEDCouplingNoTimeLabel *ret=new MEDCouplingNoTimeLabel; + ret->setArray(arr,0); + return ret; +} + +MEDCouplingTimeDiscretization *MEDCouplingNoTimeLabel::aggregate(const std::vector<const MEDCouplingTimeDiscretization *>& other) const +{ + std::vector<const DataArrayDouble *> a(other.size()); + int i=0; + for(std::vector<const MEDCouplingTimeDiscretization *>::const_iterator it=other.begin();it!=other.end();it++,i++) + { + const MEDCouplingNoTimeLabel *itC=dynamic_cast<const MEDCouplingNoTimeLabel *>(*it); + if(!itC) + throw INTERP_KERNEL::Exception("NoTimeLabel::aggregate on mismatched time discretization !"); + a[i]=itC->getArray(); + } + MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> arr=DataArrayDouble::Aggregate(a); + MEDCouplingNoTimeLabel *ret=new MEDCouplingNoTimeLabel; + ret->setArray(arr,0); + return ret; +} + +MEDCouplingTimeDiscretization *MEDCouplingNoTimeLabel::meld(const MEDCouplingTimeDiscretization *other) const +{ + const MEDCouplingNoTimeLabel *otherC=dynamic_cast<const MEDCouplingNoTimeLabel *>(other); + if(!otherC) + throw INTERP_KERNEL::Exception("NoTimeLabel::meld on mismatched time discretization !"); + MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> arr=DataArrayDouble::Meld(getArray(),other->getArray()); + MEDCouplingNoTimeLabel *ret=new MEDCouplingNoTimeLabel; + ret->setTimeTolerance(getTimeTolerance()); + ret->setArray(arr,0); + return ret; +} + +MEDCouplingTimeDiscretization *MEDCouplingNoTimeLabel::dot(const MEDCouplingTimeDiscretization *other) const +{ + const MEDCouplingNoTimeLabel *otherC=dynamic_cast<const MEDCouplingNoTimeLabel *>(other); + if(!otherC) + throw INTERP_KERNEL::Exception("NoTimeLabel::dot on mismatched time discretization !"); + MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> arr=DataArrayDouble::Dot(getArray(),other->getArray()); + MEDCouplingNoTimeLabel *ret=new MEDCouplingNoTimeLabel; + ret->setArray(arr,0); + return ret; +} + +MEDCouplingTimeDiscretization *MEDCouplingNoTimeLabel::crossProduct(const MEDCouplingTimeDiscretization *other) const +{ + const MEDCouplingNoTimeLabel *otherC=dynamic_cast<const MEDCouplingNoTimeLabel *>(other); + if(!otherC) + throw INTERP_KERNEL::Exception("NoTimeLabel::crossProduct on mismatched time discretization !"); + MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> arr=DataArrayDouble::CrossProduct(getArray(),other->getArray()); + MEDCouplingNoTimeLabel *ret=new MEDCouplingNoTimeLabel; + ret->setArray(arr,0); + return ret; +} + +MEDCouplingTimeDiscretization *MEDCouplingNoTimeLabel::max(const MEDCouplingTimeDiscretization *other) const +{ + const MEDCouplingNoTimeLabel *otherC=dynamic_cast<const MEDCouplingNoTimeLabel *>(other); + if(!otherC) + throw INTERP_KERNEL::Exception("NoTimeLabel::max on mismatched time discretization !"); + MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> arr=DataArrayDouble::Max(getArray(),other->getArray()); + MEDCouplingNoTimeLabel *ret=new MEDCouplingNoTimeLabel; + ret->setArray(arr,0); + return ret; +} + +MEDCouplingTimeDiscretization *MEDCouplingNoTimeLabel::min(const MEDCouplingTimeDiscretization *other) const +{ + const MEDCouplingNoTimeLabel *otherC=dynamic_cast<const MEDCouplingNoTimeLabel *>(other); + if(!otherC) + throw INTERP_KERNEL::Exception("NoTimeLabel::max on mismatched time discretization !"); + MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> arr=DataArrayDouble::Min(getArray(),other->getArray()); + MEDCouplingNoTimeLabel *ret=new MEDCouplingNoTimeLabel; + ret->setArray(arr,0); + return ret; +} + +MEDCouplingTimeDiscretization *MEDCouplingNoTimeLabel::add(const MEDCouplingTimeDiscretization *other) const +{ + const MEDCouplingNoTimeLabel *otherC=dynamic_cast<const MEDCouplingNoTimeLabel *>(other); + if(!otherC) + throw INTERP_KERNEL::Exception("NoTimeLabel::add on mismatched time discretization !"); + MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> arr=DataArrayDouble::Add(getArray(),other->getArray()); + MEDCouplingNoTimeLabel *ret=new MEDCouplingNoTimeLabel; + ret->setArray(arr,0); + return ret; +} + +void MEDCouplingNoTimeLabel::addEqual(const MEDCouplingTimeDiscretization *other) +{ + const MEDCouplingNoTimeLabel *otherC=dynamic_cast<const MEDCouplingNoTimeLabel *>(other); + if(!otherC) + throw INTERP_KERNEL::Exception("NoTimeLabel::addEqual on mismatched time discretization !"); + if(!getArray()) + throw INTERP_KERNEL::Exception("MEDCouplingNoTimeLabel::addEqual : Data Array is NULL !"); + getArray()->addEqual(other->getArray()); +} + +MEDCouplingTimeDiscretization *MEDCouplingNoTimeLabel::substract(const MEDCouplingTimeDiscretization *other) const +{ + const MEDCouplingNoTimeLabel *otherC=dynamic_cast<const MEDCouplingNoTimeLabel *>(other); + if(!otherC) + throw INTERP_KERNEL::Exception("NoTimeLabel::substract on mismatched time discretization !"); + if(!getArray()) + throw INTERP_KERNEL::Exception("MEDCouplingNoTimeLabel::substract : Data Array is NULL !"); + MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> arr=DataArrayDouble::Substract(getArray(),other->getArray()); + MEDCouplingNoTimeLabel *ret=new MEDCouplingNoTimeLabel; + ret->setArray(arr,0); + return ret; +} + +void MEDCouplingNoTimeLabel::substractEqual(const MEDCouplingTimeDiscretization *other) +{ + const MEDCouplingNoTimeLabel *otherC=dynamic_cast<const MEDCouplingNoTimeLabel *>(other); + if(!otherC) + throw INTERP_KERNEL::Exception("NoTimeLabel::substractEqual on mismatched time discretization !"); + if(!getArray()) + throw INTERP_KERNEL::Exception("MEDCouplingNoTimeLabel::substractEqual : Data Array is NULL !"); + getArray()->substractEqual(other->getArray()); +} + +MEDCouplingTimeDiscretization *MEDCouplingNoTimeLabel::multiply(const MEDCouplingTimeDiscretization *other) const +{ + const MEDCouplingNoTimeLabel *otherC=dynamic_cast<const MEDCouplingNoTimeLabel *>(other); + if(!otherC) + throw INTERP_KERNEL::Exception("NoTimeLabel::multiply on mismatched time discretization !"); + MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> arr=DataArrayDouble::Multiply(getArray(),other->getArray()); + MEDCouplingNoTimeLabel *ret=new MEDCouplingNoTimeLabel; + ret->setArray(arr,0); + return ret; +} + +void MEDCouplingNoTimeLabel::multiplyEqual(const MEDCouplingTimeDiscretization *other) +{ + const MEDCouplingNoTimeLabel *otherC=dynamic_cast<const MEDCouplingNoTimeLabel *>(other); + if(!otherC) + throw INTERP_KERNEL::Exception("NoTimeLabel::multiplyEqual on mismatched time discretization !"); + if(!getArray()) + throw INTERP_KERNEL::Exception("MEDCouplingNoTimeLabel::multiplyEqual : Data Array is NULL !"); + getArray()->multiplyEqual(other->getArray()); +} + +MEDCouplingTimeDiscretization *MEDCouplingNoTimeLabel::divide(const MEDCouplingTimeDiscretization *other) const +{ + const MEDCouplingNoTimeLabel *otherC=dynamic_cast<const MEDCouplingNoTimeLabel *>(other); + if(!otherC) + throw INTERP_KERNEL::Exception("divide on mismatched time discretization !"); + MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> arr=DataArrayDouble::Divide(getArray(),other->getArray()); + MEDCouplingNoTimeLabel *ret=new MEDCouplingNoTimeLabel; + ret->setArray(arr,0); + return ret; +} + +void MEDCouplingNoTimeLabel::divideEqual(const MEDCouplingTimeDiscretization *other) +{ + const MEDCouplingNoTimeLabel *otherC=dynamic_cast<const MEDCouplingNoTimeLabel *>(other); + if(!otherC) + throw INTERP_KERNEL::Exception("NoTimeLabel::divideEqual on mismatched time discretization !"); + if(!getArray()) + throw INTERP_KERNEL::Exception("MEDCouplingNoTimeLabel::divideEqual : Data Array is NULL !"); + getArray()->divideEqual(other->getArray()); +} + +MEDCouplingTimeDiscretization *MEDCouplingNoTimeLabel::pow(const MEDCouplingTimeDiscretization *other) const +{ + const MEDCouplingNoTimeLabel *otherC=dynamic_cast<const MEDCouplingNoTimeLabel *>(other); + if(!otherC) + throw INTERP_KERNEL::Exception("pow on mismatched time discretization !"); + MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> arr=DataArrayDouble::Pow(getArray(),other->getArray()); + MEDCouplingNoTimeLabel *ret=new MEDCouplingNoTimeLabel; + ret->setArray(arr,0); + return ret; +} + +void MEDCouplingNoTimeLabel::powEqual(const MEDCouplingTimeDiscretization *other) +{ + const MEDCouplingNoTimeLabel *otherC=dynamic_cast<const MEDCouplingNoTimeLabel *>(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 +{ + return new MEDCouplingNoTimeLabel(*this,deepCpy); +} + +void MEDCouplingNoTimeLabel::checkTimePresence(double time) const +{ + throw INTERP_KERNEL::Exception(EXCEPTION_MSG); +} + +std::vector< const DataArrayDouble *> MEDCouplingNoTimeLabel::getArraysForTime(double time) const +{ + throw INTERP_KERNEL::Exception(EXCEPTION_MSG); +} + +void MEDCouplingNoTimeLabel::getValueForTime(double time, const std::vector<double>& vals, double *res) const +{ + throw INTERP_KERNEL::Exception(EXCEPTION_MSG); +} + +bool MEDCouplingNoTimeLabel::isBefore(const MEDCouplingTimeDiscretization *other) const +{ + throw INTERP_KERNEL::Exception(EXCEPTION_MSG); +} + +bool MEDCouplingNoTimeLabel::isStrictlyBefore(const MEDCouplingTimeDiscretization *other) const +{ + throw INTERP_KERNEL::Exception(EXCEPTION_MSG); +} + +double MEDCouplingNoTimeLabel::getStartTime(int& iteration, int& order) const +{ + throw INTERP_KERNEL::Exception(EXCEPTION_MSG); +} + +double MEDCouplingNoTimeLabel::getEndTime(int& iteration, int& order) const +{ + throw INTERP_KERNEL::Exception(EXCEPTION_MSG); +} + +void MEDCouplingNoTimeLabel::setStartIteration(int it) +{ + throw INTERP_KERNEL::Exception(EXCEPTION_MSG); +} + +void MEDCouplingNoTimeLabel::setEndIteration(int it) +{ + throw INTERP_KERNEL::Exception(EXCEPTION_MSG); +} + +void MEDCouplingNoTimeLabel::setStartOrder(int order) +{ + throw INTERP_KERNEL::Exception(EXCEPTION_MSG); +} + +void MEDCouplingNoTimeLabel::setEndOrder(int order) +{ + throw INTERP_KERNEL::Exception(EXCEPTION_MSG); +} + +void MEDCouplingNoTimeLabel::setStartTimeValue(double time) +{ + throw INTERP_KERNEL::Exception(EXCEPTION_MSG); +} + +void MEDCouplingNoTimeLabel::setEndTimeValue(double time) +{ + throw INTERP_KERNEL::Exception(EXCEPTION_MSG); +} + +void MEDCouplingNoTimeLabel::setStartTime(double time, int iteration, int order) +{ + throw INTERP_KERNEL::Exception(EXCEPTION_MSG); +} + +void MEDCouplingNoTimeLabel::setEndTime(double time, int iteration, int order) +{ + throw INTERP_KERNEL::Exception(EXCEPTION_MSG); +} + +void MEDCouplingNoTimeLabel::getValueOnTime(int eltId, double time, double *value) const +{ + throw INTERP_KERNEL::Exception(EXCEPTION_MSG); +} + +void MEDCouplingNoTimeLabel::getValueOnDiscTime(int eltId, int iteration, int order, double *value) const +{ + throw INTERP_KERNEL::Exception(EXCEPTION_MSG); +} + +/*! + * idem getTinySerializationIntInformation except that it is for multi field fetch + */ +void MEDCouplingNoTimeLabel::getTinySerializationIntInformation2(std::vector<int>& tinyInfo) const +{ + tinyInfo.clear(); +} + +/*! + * idem getTinySerializationDbleInformation except that it is for multi field fetch + */ +void MEDCouplingNoTimeLabel::getTinySerializationDbleInformation2(std::vector<double>& tinyInfo) const +{ + tinyInfo.resize(1); + tinyInfo[0]=_time_tolerance; +} + +/*! + * idem finishUnserialization except that it is for multi field fetch + */ +void MEDCouplingNoTimeLabel::finishUnserialization2(const std::vector<int>& tinyInfoI, const std::vector<double>& tinyInfoD) +{ + _time_tolerance=tinyInfoD[0]; +} + +MEDCouplingWithTimeStep::MEDCouplingWithTimeStep(const MEDCouplingWithTimeStep& other, bool deepCpy):MEDCouplingTimeDiscretization(other,deepCpy), + _time(other._time),_iteration(other._iteration),_order(other._order) +{ +} + +MEDCouplingWithTimeStep::MEDCouplingWithTimeStep():_time(0.),_iteration(-1),_order(-1) +{ +} + +std::string MEDCouplingWithTimeStep::getStringRepr() const +{ + std::ostringstream stream; + stream << REPR << " Time is defined by iteration=" << _iteration << " order=" << _order << " and time=" << _time << "."; + stream << "\nTime unit is : \"" << _time_unit << "\""; + return stream.str(); +} + +void MEDCouplingWithTimeStep::synchronizeTimeWith(const MEDCouplingMesh *mesh) +{ + 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<int>& tinyInfo) const +{ + MEDCouplingTimeDiscretization::getTinySerializationIntInformation(tinyInfo); + tinyInfo.push_back(_iteration); + tinyInfo.push_back(_order); +} + +void MEDCouplingWithTimeStep::getTinySerializationDbleInformation(std::vector<double>& tinyInfo) const +{ + MEDCouplingTimeDiscretization::getTinySerializationDbleInformation(tinyInfo); + tinyInfo.push_back(_time); +} + +void MEDCouplingWithTimeStep::finishUnserialization(const std::vector<int>& tinyInfoI, const std::vector<double>& tinyInfoD, const std::vector<std::string>& tinyInfoS) +{ + MEDCouplingTimeDiscretization::finishUnserialization(tinyInfoI,tinyInfoD,tinyInfoS); + _time=tinyInfoD[1]; + _iteration=tinyInfoI[2]; + _order=tinyInfoI[3]; +} + +/*! + * idem getTinySerializationIntInformation except that it is for multi field fetch + */ +void MEDCouplingWithTimeStep::getTinySerializationIntInformation2(std::vector<int>& tinyInfo) const +{ + tinyInfo.resize(2); + tinyInfo[0]=_iteration; + tinyInfo[1]=_order; +} + +/*! + * idem getTinySerializationDbleInformation except that it is for multi field fetch + */ +void MEDCouplingWithTimeStep::getTinySerializationDbleInformation2(std::vector<double>& tinyInfo) const +{ + tinyInfo.resize(2); + tinyInfo[0]=_time_tolerance; + tinyInfo[1]=_time; +} + +/*! + * idem finishUnserialization except that it is for multi field fetch + */ +void MEDCouplingWithTimeStep::finishUnserialization2(const std::vector<int>& tinyInfoI, const std::vector<double>& tinyInfoD) +{ + _iteration=tinyInfoI[0]; + _order=tinyInfoI[1]; + _time_tolerance=tinyInfoD[0]; + _time=tinyInfoD[1]; +} + +bool MEDCouplingWithTimeStep::areCompatible(const MEDCouplingTimeDiscretization *other) const +{ + if(!MEDCouplingTimeDiscretization::areCompatible(other)) + return false; + const MEDCouplingWithTimeStep *otherC=dynamic_cast<const MEDCouplingWithTimeStep *>(other); + return otherC!=0; +} + +bool MEDCouplingWithTimeStep::areStrictlyCompatible(const MEDCouplingTimeDiscretization *other, std::string& reason) const +{ + if(!MEDCouplingTimeDiscretization::areStrictlyCompatible(other,reason)) + return false; + const MEDCouplingWithTimeStep *otherC=dynamic_cast<const MEDCouplingWithTimeStep *>(other); + bool ret=otherC!=0; + if(!ret) + reason.insert(0,"time discretization of this is ONE_TIME, other has a different time discretization."); + return ret; +} + +bool MEDCouplingWithTimeStep::areStrictlyCompatibleForMul(const MEDCouplingTimeDiscretization *other) const +{ + if(!MEDCouplingTimeDiscretization::areStrictlyCompatibleForMul(other)) + return false; + const MEDCouplingWithTimeStep *otherC=dynamic_cast<const MEDCouplingWithTimeStep *>(other); + return otherC!=0; +} + +bool MEDCouplingWithTimeStep::areStrictlyCompatibleForDiv(const MEDCouplingTimeDiscretization *other) const +{ + if(!MEDCouplingTimeDiscretization::areStrictlyCompatibleForDiv(other)) + return false; + const MEDCouplingWithTimeStep *otherC=dynamic_cast<const MEDCouplingWithTimeStep *>(other); + return otherC!=0; +} + +bool MEDCouplingWithTimeStep::areCompatibleForMeld(const MEDCouplingTimeDiscretization *other) const +{ + if(!MEDCouplingTimeDiscretization::areCompatibleForMeld(other)) + return false; + const MEDCouplingWithTimeStep *otherC=dynamic_cast<const MEDCouplingWithTimeStep *>(other); + return otherC!=0; +} + +bool MEDCouplingWithTimeStep::isEqualIfNotWhy(const MEDCouplingTimeDiscretization *other, double prec, std::string& reason) const +{ + const MEDCouplingWithTimeStep *otherC=dynamic_cast<const MEDCouplingWithTimeStep *>(other); + std::ostringstream oss; oss.precision(15); + if(!otherC) + { + reason="This has time discretization ONE_TIME, other not."; + return false; + } + if(_iteration!=otherC->_iteration) + { + oss << "iterations differ. this iteration=" << _iteration << " other iteration=" << otherC->_iteration; + reason=oss.str(); + return false; + } + if(_order!=otherC->_order) + { + oss << "orders differ. this order=" << _order << " other order=" << otherC->_order; + reason=oss.str(); + return false; + } + if(std::fabs(_time-otherC->_time)>_time_tolerance) + { + oss << "times differ. this time=" << _time << " other time=" << otherC->_time; + reason=oss.str(); + return false; + } + return MEDCouplingTimeDiscretization::isEqualIfNotWhy(other,prec,reason); +} + +bool MEDCouplingWithTimeStep::isEqualWithoutConsideringStr(const MEDCouplingTimeDiscretization *other, double prec) const +{ + const MEDCouplingWithTimeStep *otherC=dynamic_cast<const MEDCouplingWithTimeStep *>(other); + if(!otherC) + return false; + if(_iteration!=otherC->_iteration) + return false; + if(_order!=otherC->_order) + return false; + if(std::fabs(_time-otherC->_time)>_time_tolerance) + return false; + return MEDCouplingTimeDiscretization::isEqualWithoutConsideringStr(other,prec); +} + +void MEDCouplingWithTimeStep::copyTinyAttrFrom(const MEDCouplingTimeDiscretization& other) +{ + MEDCouplingTimeDiscretization::copyTinyAttrFrom(other); + const MEDCouplingWithTimeStep *otherC=dynamic_cast<const MEDCouplingWithTimeStep *>(&other); + if(!otherC) + throw INTERP_KERNEL::Exception("MEDCouplingWithTimeStep::copyTinyAttrFrom : mismatch of time discretization !"); + _time=otherC->_time; + _iteration=otherC->_iteration; + _order=otherC->_order; +} + +MEDCouplingTimeDiscretization *MEDCouplingWithTimeStep::aggregate(const MEDCouplingTimeDiscretization *other) const +{ + const MEDCouplingWithTimeStep *otherC=dynamic_cast<const MEDCouplingWithTimeStep *>(other); + if(!otherC) + throw INTERP_KERNEL::Exception("WithTimeStep::aggregation on mismatched time discretization !"); + MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> arr=DataArrayDouble::Aggregate(getArray(),other->getArray()); + MEDCouplingWithTimeStep *ret=new MEDCouplingWithTimeStep; + ret->setArray(arr,0); + return ret; +} + +MEDCouplingTimeDiscretization *MEDCouplingWithTimeStep::aggregate(const std::vector<const MEDCouplingTimeDiscretization *>& other) const +{ + std::vector<const DataArrayDouble *> a(other.size()); + int i=0; + for(std::vector<const MEDCouplingTimeDiscretization *>::const_iterator it=other.begin();it!=other.end();it++,i++) + { + const MEDCouplingWithTimeStep *itC=dynamic_cast<const MEDCouplingWithTimeStep *>(*it); + if(!itC) + throw INTERP_KERNEL::Exception("WithTimeStep::aggregate on mismatched time discretization !"); + a[i]=itC->getArray(); + } + MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> arr=DataArrayDouble::Aggregate(a); + MEDCouplingWithTimeStep *ret=new MEDCouplingWithTimeStep; + ret->setArray(arr,0); + return ret; +} + +MEDCouplingTimeDiscretization *MEDCouplingWithTimeStep::meld(const MEDCouplingTimeDiscretization *other) const +{ + const MEDCouplingWithTimeStep *otherC=dynamic_cast<const MEDCouplingWithTimeStep *>(other); + if(!otherC) + throw INTERP_KERNEL::Exception("WithTimeStep::meld on mismatched time discretization !"); + MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> arr=DataArrayDouble::Meld(getArray(),other->getArray()); + MEDCouplingWithTimeStep *ret=new MEDCouplingWithTimeStep; + ret->setArray(arr,0); + return ret; +} + +MEDCouplingTimeDiscretization *MEDCouplingWithTimeStep::dot(const MEDCouplingTimeDiscretization *other) const +{ + const MEDCouplingWithTimeStep *otherC=dynamic_cast<const MEDCouplingWithTimeStep *>(other); + if(!otherC) + throw INTERP_KERNEL::Exception("WithTimeStep::dot on mismatched time discretization !"); + MEDCouplingWithTimeStep *ret=new MEDCouplingWithTimeStep; + MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> arr=DataArrayDouble::Dot(getArray(),other->getArray()); + ret->setArray(arr,0); + return ret; +} + +MEDCouplingTimeDiscretization *MEDCouplingWithTimeStep::crossProduct(const MEDCouplingTimeDiscretization *other) const +{ + const MEDCouplingWithTimeStep *otherC=dynamic_cast<const MEDCouplingWithTimeStep *>(other); + if(!otherC) + throw INTERP_KERNEL::Exception("WithTimeStep::crossProduct on mismatched time discretization !"); + MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> arr=DataArrayDouble::CrossProduct(getArray(),other->getArray()); + MEDCouplingWithTimeStep *ret=new MEDCouplingWithTimeStep; + ret->setArray(arr,0); + return ret; +} + +MEDCouplingTimeDiscretization *MEDCouplingWithTimeStep::max(const MEDCouplingTimeDiscretization *other) const +{ + const MEDCouplingWithTimeStep *otherC=dynamic_cast<const MEDCouplingWithTimeStep *>(other); + if(!otherC) + throw INTERP_KERNEL::Exception("WithTimeStep::max on mismatched time discretization !"); + MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> arr=DataArrayDouble::Max(getArray(),other->getArray()); + MEDCouplingWithTimeStep *ret=new MEDCouplingWithTimeStep; + ret->setArray(arr,0); + return ret; +} + +MEDCouplingTimeDiscretization *MEDCouplingWithTimeStep::min(const MEDCouplingTimeDiscretization *other) const +{ + const MEDCouplingWithTimeStep *otherC=dynamic_cast<const MEDCouplingWithTimeStep *>(other); + if(!otherC) + throw INTERP_KERNEL::Exception("WithTimeStep::min on mismatched time discretization !"); + MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> arr=DataArrayDouble::Min(getArray(),other->getArray()); + MEDCouplingWithTimeStep *ret=new MEDCouplingWithTimeStep; + ret->setArray(arr,0); + return ret; +} + +MEDCouplingTimeDiscretization *MEDCouplingWithTimeStep::add(const MEDCouplingTimeDiscretization *other) const +{ + const MEDCouplingWithTimeStep *otherC=dynamic_cast<const MEDCouplingWithTimeStep *>(other); + if(!otherC) + throw INTERP_KERNEL::Exception("WithTimeStep::add on mismatched time discretization !"); + MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> arr=DataArrayDouble::Add(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::addEqual(const MEDCouplingTimeDiscretization *other) +{ + const MEDCouplingWithTimeStep *otherC=dynamic_cast<const MEDCouplingWithTimeStep *>(other); + if(!otherC) + throw INTERP_KERNEL::Exception("WithTimeStep::addEqual on mismatched time discretization !"); + if(!getArray()) + throw INTERP_KERNEL::Exception("MEDCouplingWithTimeLabel::addEqual : Data Array is NULL !"); + getArray()->addEqual(other->getArray()); +} + +MEDCouplingTimeDiscretization *MEDCouplingWithTimeStep::substract(const MEDCouplingTimeDiscretization *other) const +{ + const MEDCouplingWithTimeStep *otherC=dynamic_cast<const MEDCouplingWithTimeStep *>(other); + if(!otherC) + throw INTERP_KERNEL::Exception("WithTimeStep::substract on mismatched time discretization !"); + MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> arr=DataArrayDouble::Substract(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::substractEqual(const MEDCouplingTimeDiscretization *other) +{ + const MEDCouplingWithTimeStep *otherC=dynamic_cast<const MEDCouplingWithTimeStep *>(other); + if(!otherC) + throw INTERP_KERNEL::Exception("WithTimeStep::substractEqual on mismatched time discretization !"); + if(!getArray()) + throw INTERP_KERNEL::Exception("MEDCouplingWithTimeLabel::substractEqual : Data Array is NULL !"); + getArray()->substractEqual(other->getArray()); +} + +MEDCouplingTimeDiscretization *MEDCouplingWithTimeStep::multiply(const MEDCouplingTimeDiscretization *other) const +{ + const MEDCouplingWithTimeStep *otherC=dynamic_cast<const MEDCouplingWithTimeStep *>(other); + if(!otherC) + throw INTERP_KERNEL::Exception("WithTimeStep::multiply on mismatched time discretization !"); + MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> arr=DataArrayDouble::Multiply(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::multiplyEqual(const MEDCouplingTimeDiscretization *other) +{ + const MEDCouplingWithTimeStep *otherC=dynamic_cast<const MEDCouplingWithTimeStep *>(other); + if(!otherC) + throw INTERP_KERNEL::Exception("WithTimeStep::multiplyEqual on mismatched time discretization !"); + if(!getArray()) + throw INTERP_KERNEL::Exception("MEDCouplingWithTimeLabel::multiplyEqual : Data Array is NULL !"); + getArray()->multiplyEqual(other->getArray()); +} + +MEDCouplingTimeDiscretization *MEDCouplingWithTimeStep::divide(const MEDCouplingTimeDiscretization *other) const +{ + const MEDCouplingWithTimeStep *otherC=dynamic_cast<const MEDCouplingWithTimeStep *>(other); + if(!otherC) + throw INTERP_KERNEL::Exception("WithTimeStep::divide on mismatched time discretization !"); + MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> arr=DataArrayDouble::Divide(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::divideEqual(const MEDCouplingTimeDiscretization *other) +{ + const MEDCouplingWithTimeStep *otherC=dynamic_cast<const MEDCouplingWithTimeStep *>(other); + if(!otherC) + throw INTERP_KERNEL::Exception("WithTimeStep::divideEqual on mismatched time discretization !"); + if(!getArray()) + throw INTERP_KERNEL::Exception("MEDCouplingWithTimeLabel::divideEqual : Data Array is NULL !"); + getArray()->divideEqual(other->getArray()); +} + +MEDCouplingTimeDiscretization *MEDCouplingWithTimeStep::pow(const MEDCouplingTimeDiscretization *other) const +{ + const MEDCouplingWithTimeStep *otherC=dynamic_cast<const MEDCouplingWithTimeStep *>(other); + if(!otherC) + throw INTERP_KERNEL::Exception("WithTimeStep::pow on mismatched time discretization !"); + MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> 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) +{ + const MEDCouplingWithTimeStep *otherC=dynamic_cast<const MEDCouplingWithTimeStep *>(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 +{ + return new MEDCouplingWithTimeStep(*this,deepCpy); +} + +void MEDCouplingWithTimeStep::checkNoTimePresence() const +{ + throw INTERP_KERNEL::Exception("No time specified on a field defined on one time"); +} + +void MEDCouplingWithTimeStep::checkTimePresence(double time) const +{ + if(std::fabs(time-_time)>_time_tolerance) + { + std::ostringstream stream; + stream << "The field is defined on time " << _time << " with eps=" << _time_tolerance << " and asking time = " << time << " !"; + throw INTERP_KERNEL::Exception(stream.str().c_str()); + } +} + +std::vector< const DataArrayDouble *> MEDCouplingWithTimeStep::getArraysForTime(double time) const +{ + if(std::fabs(time-_time)<=_time_tolerance) + { + std::vector< const DataArrayDouble *> ret(1); + ret[0]=_array; + return ret; + } + else + throw INTERP_KERNEL::Exception(EXCEPTION_MSG); +} + +void MEDCouplingWithTimeStep::getValueForTime(double time, const std::vector<double>& vals, double *res) const +{ + std::copy(vals.begin(),vals.end(),res); +} + +void MEDCouplingWithTimeStep::getValueOnTime(int eltId, double time, double *value) const +{ + if(std::fabs(time-_time)<=_time_tolerance) + if(_array) + _array->getTuple(eltId,value); + else + throw INTERP_KERNEL::Exception("No array existing."); + else + throw INTERP_KERNEL::Exception(EXCEPTION_MSG); +} + +void MEDCouplingWithTimeStep::getValueOnDiscTime(int eltId, int iteration, int order, double *value) const +{ + if(_iteration==iteration && _order==order) + if(_array) + _array->getTuple(eltId,value); + else + throw INTERP_KERNEL::Exception("No array existing."); + else + throw INTERP_KERNEL::Exception("No data on this discrete time."); +} + +MEDCouplingConstOnTimeInterval::MEDCouplingConstOnTimeInterval():_start_time(0.),_end_time(0.),_start_iteration(-1),_end_iteration(-1),_start_order(-1),_end_order(-1) +{ +} + +void MEDCouplingConstOnTimeInterval::copyTinyAttrFrom(const MEDCouplingTimeDiscretization& other) +{ + MEDCouplingTimeDiscretization::copyTinyAttrFrom(other); + const MEDCouplingConstOnTimeInterval *otherC=dynamic_cast<const MEDCouplingConstOnTimeInterval *>(&other); + if(!otherC) + throw INTERP_KERNEL::Exception("MEDCouplingConstOnTimeInterval::copyTinyAttrFrom : mismatch of time discretization !"); + _start_time=otherC->_start_time; + _end_time=otherC->_end_time; + _start_iteration=otherC->_start_iteration; + _end_iteration=otherC->_end_iteration; + _start_order=otherC->_start_order; + _end_order=otherC->_end_order; +} + +void MEDCouplingConstOnTimeInterval::getTinySerializationIntInformation(std::vector<int>& tinyInfo) const +{ + MEDCouplingTimeDiscretization::getTinySerializationIntInformation(tinyInfo); + tinyInfo.push_back(_start_iteration); + tinyInfo.push_back(_start_order); + tinyInfo.push_back(_end_iteration); + tinyInfo.push_back(_end_order); +} + +void MEDCouplingConstOnTimeInterval::getTinySerializationDbleInformation(std::vector<double>& tinyInfo) const +{ + MEDCouplingTimeDiscretization::getTinySerializationDbleInformation(tinyInfo); + tinyInfo.push_back(_start_time); + tinyInfo.push_back(_end_time); +} + +void MEDCouplingConstOnTimeInterval::finishUnserialization(const std::vector<int>& tinyInfoI, const std::vector<double>& tinyInfoD, const std::vector<std::string>& tinyInfoS) +{ + MEDCouplingTimeDiscretization::finishUnserialization(tinyInfoI,tinyInfoD,tinyInfoS); + _start_time=tinyInfoD[1]; + _end_time=tinyInfoD[2]; + _start_iteration=tinyInfoI[2]; + _start_order=tinyInfoI[3]; + _end_iteration=tinyInfoI[4]; + _end_order=tinyInfoI[5]; +} + +/*! + * idem getTinySerializationIntInformation except that it is for multi field fetch + */ +void MEDCouplingConstOnTimeInterval::getTinySerializationIntInformation2(std::vector<int>& tinyInfo) const +{ + tinyInfo.resize(4); + tinyInfo[0]=_start_iteration; + tinyInfo[1]=_start_order; + tinyInfo[2]=_end_iteration; + tinyInfo[3]=_end_order; +} + +/*! + * idem getTinySerializationDbleInformation except that it is for multi field fetch + */ +void MEDCouplingConstOnTimeInterval::getTinySerializationDbleInformation2(std::vector<double>& tinyInfo) const +{ + tinyInfo.resize(3); + tinyInfo[0]=_time_tolerance; + tinyInfo[1]=_start_time; + tinyInfo[2]=_end_time; +} + +/*! + * idem finishUnserialization except that it is for multi field fetch + */ +void MEDCouplingConstOnTimeInterval::finishUnserialization2(const std::vector<int>& tinyInfoI, const std::vector<double>& tinyInfoD) +{ + _start_iteration=tinyInfoI[0]; + _start_order=tinyInfoI[1]; + _end_iteration=tinyInfoI[2]; + _end_order=tinyInfoI[3]; + _time_tolerance=tinyInfoD[0]; + _start_time=tinyInfoD[1]; + _end_time=tinyInfoD[2]; +} + +MEDCouplingConstOnTimeInterval::MEDCouplingConstOnTimeInterval(const MEDCouplingConstOnTimeInterval& 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),_start_order(other._start_order),_end_order(other._end_order) +{ +} + +std::string MEDCouplingConstOnTimeInterval::getStringRepr() const +{ + std::ostringstream stream; + stream << REPR << " Time interval is defined by :\niteration_start=" << _start_iteration << " order_start=" << _start_order << " and time_start=" << _start_time << "\n"; + stream << "iteration_end=" << _end_iteration << " order_end=" << _end_order << " and end_time=" << _end_time << "\n"; + stream << "\nTime unit is : \"" << _time_unit << "\""; + return stream.str(); +} + +void MEDCouplingConstOnTimeInterval::synchronizeTimeWith(const MEDCouplingMesh *mesh) +{ + if(!mesh) + throw INTERP_KERNEL::Exception("MEDCouplingWithTimeStep::synchronizeTimeWith : mesh instance is NULL ! Impossible to synchronize time !"); + int it=-1,order=-1; + double val=mesh->getTime(it,order); + _start_time=val; _start_iteration=it; _start_order=order; + _end_time=val; _end_iteration=it; _end_order=order; + std::string tUnit=mesh->getTimeUnit(); + _time_unit=tUnit; +} + +MEDCouplingTimeDiscretization *MEDCouplingConstOnTimeInterval::performCpy(bool deepCpy) const +{ + return new MEDCouplingConstOnTimeInterval(*this,deepCpy); +} + +std::vector< const DataArrayDouble *> MEDCouplingConstOnTimeInterval::getArraysForTime(double time) const +{ + if(time>_start_time-_time_tolerance && time<_end_time+_time_tolerance) + { + std::vector< const DataArrayDouble *> ret(1); + ret[0]=_array; + return ret; + } + else + throw INTERP_KERNEL::Exception(EXCEPTION_MSG); +} + +void MEDCouplingConstOnTimeInterval::getValueForTime(double time, const std::vector<double>& vals, double *res) const +{ + std::copy(vals.begin(),vals.end(),res); +} + +bool MEDCouplingConstOnTimeInterval::areCompatible(const MEDCouplingTimeDiscretization *other) const +{ + if(!MEDCouplingTimeDiscretization::areCompatible(other)) + return false; + const MEDCouplingConstOnTimeInterval *otherC=dynamic_cast<const MEDCouplingConstOnTimeInterval *>(other); + return otherC!=0; +} + +bool MEDCouplingConstOnTimeInterval::areStrictlyCompatible(const MEDCouplingTimeDiscretization *other, std::string& reason) const +{ + if(!MEDCouplingTimeDiscretization::areStrictlyCompatible(other,reason)) + return false; + const MEDCouplingConstOnTimeInterval *otherC=dynamic_cast<const MEDCouplingConstOnTimeInterval *>(other); + bool ret=otherC!=0; + if(!ret) + reason.insert(0,"time discretization of this is CONST_ON_TIME_INTERVAL, other has a different time discretization."); + return ret; +} + +bool MEDCouplingConstOnTimeInterval::areStrictlyCompatibleForMul(const MEDCouplingTimeDiscretization *other) const +{ + if(!MEDCouplingTimeDiscretization::areStrictlyCompatibleForMul(other)) + return false; + const MEDCouplingConstOnTimeInterval *otherC=dynamic_cast<const MEDCouplingConstOnTimeInterval *>(other); + return otherC!=0; +} + +bool MEDCouplingConstOnTimeInterval::areStrictlyCompatibleForDiv(const MEDCouplingTimeDiscretization *other) const +{ + if(!MEDCouplingTimeDiscretization::areStrictlyCompatibleForDiv(other)) + return false; + const MEDCouplingConstOnTimeInterval *otherC=dynamic_cast<const MEDCouplingConstOnTimeInterval *>(other); + return otherC!=0; +} + +bool MEDCouplingConstOnTimeInterval::areCompatibleForMeld(const MEDCouplingTimeDiscretization *other) const +{ + if(!MEDCouplingTimeDiscretization::areCompatibleForMeld(other)) + return false; + const MEDCouplingConstOnTimeInterval *otherC=dynamic_cast<const MEDCouplingConstOnTimeInterval *>(other); + return otherC!=0; +} + +bool MEDCouplingConstOnTimeInterval::isEqualIfNotWhy(const MEDCouplingTimeDiscretization *other, double prec, std::string& reason) const +{ + const MEDCouplingConstOnTimeInterval *otherC=dynamic_cast<const MEDCouplingConstOnTimeInterval *>(other); + std::ostringstream oss; oss.precision(15); + if(!otherC) + { + reason="This has time discretization CONST_ON_TIME_INTERVAL, other not."; + return false; + } + if(_start_iteration!=otherC->_start_iteration) + { + oss << "start iterations differ. this start iteration=" << _start_iteration << " other start iteration=" << otherC->_start_iteration; + reason=oss.str(); + return false; + } + if(_start_order!=otherC->_start_order) + { + oss << "start orders differ. this start order=" << _start_order << " other start order=" << otherC->_start_order; + reason=oss.str(); + return false; + } + if(std::fabs(_start_time-otherC->_start_time)>_time_tolerance) + { + oss << "start times differ. this start time=" << _start_time << " other start time=" << otherC->_start_time; + reason=oss.str(); + return false; + } + if(_end_iteration!=otherC->_end_iteration) + { + oss << "end iterations differ. this end iteration=" << _end_iteration << " other end iteration=" << otherC->_end_iteration; + reason=oss.str(); + return false; + } + if(_end_order!=otherC->_end_order) + { + oss << "end orders differ. this end order=" << _end_order << " other end order=" << otherC->_end_order; + reason=oss.str(); + return false; + } + if(std::fabs(_end_time-otherC->_end_time)>_time_tolerance) + { + oss << "end times differ. this end time=" << _end_time << " other end time=" << otherC->_end_time; + reason=oss.str(); + return false; + } + return MEDCouplingTimeDiscretization::isEqualIfNotWhy(other,prec,reason); +} + +bool MEDCouplingConstOnTimeInterval::isEqualWithoutConsideringStr(const MEDCouplingTimeDiscretization *other, double prec) const +{ + const MEDCouplingConstOnTimeInterval *otherC=dynamic_cast<const MEDCouplingConstOnTimeInterval *>(other); + if(!otherC) + return false; + if(_start_iteration!=otherC->_start_iteration) + return false; + if(_start_order!=otherC->_start_order) + return false; + if(std::fabs(_start_time-otherC->_start_time)>_time_tolerance) + return false; + if(_end_iteration!=otherC->_end_iteration) + return false; + if(_end_order!=otherC->_end_order) + return false; + if(std::fabs(_end_time-otherC->_end_time)>_time_tolerance) + return false; + return MEDCouplingTimeDiscretization::isEqualWithoutConsideringStr(other,prec); +} + +void MEDCouplingConstOnTimeInterval::getValueOnTime(int eltId, double time, double *value) const +{ + if(time>_start_time-_time_tolerance && time<_end_time+_time_tolerance) + if(_array) + _array->getTuple(eltId,value); + else + throw INTERP_KERNEL::Exception("No array existing."); + else + throw INTERP_KERNEL::Exception(EXCEPTION_MSG); +} + +void MEDCouplingConstOnTimeInterval::getValueOnDiscTime(int eltId, int iteration, int order, double *value) const +{ + if(iteration>=_start_iteration && iteration<=_end_iteration) + if(_array) + _array->getTuple(eltId,value); + else + throw INTERP_KERNEL::Exception("No array existing."); + else + throw INTERP_KERNEL::Exception(EXCEPTION_MSG); +} + +void MEDCouplingConstOnTimeInterval::checkNoTimePresence() const +{ + throw INTERP_KERNEL::Exception("No time specified on a field defined as constant on one time interval"); +} + +void MEDCouplingConstOnTimeInterval::checkTimePresence(double time) const +{ + if(time<_start_time-_time_tolerance || time>_end_time+_time_tolerance) + { + std::ostringstream stream; + stream << "The field is defined between times " << _start_time << " and " << _end_time << " worderh tolerance "; + stream << _time_tolerance << " and trying to access on time = " << time; + throw INTERP_KERNEL::Exception(stream.str().c_str()); + } +} + +MEDCouplingTimeDiscretization *MEDCouplingConstOnTimeInterval::aggregate(const MEDCouplingTimeDiscretization *other) const +{ + const MEDCouplingConstOnTimeInterval *otherC=dynamic_cast<const MEDCouplingConstOnTimeInterval *>(other); + if(!otherC) + throw INTERP_KERNEL::Exception("ConstOnTimeInterval::aggregation on mismatched time discretization !"); + MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> arr=DataArrayDouble::Aggregate(getArray(),other->getArray()); + MEDCouplingConstOnTimeInterval *ret=new MEDCouplingConstOnTimeInterval; + ret->setArray(arr,0); + return ret; +} + +MEDCouplingTimeDiscretization *MEDCouplingConstOnTimeInterval::aggregate(const std::vector<const MEDCouplingTimeDiscretization *>& other) const +{ + std::vector<const DataArrayDouble *> a(other.size()); + int i=0; + for(std::vector<const MEDCouplingTimeDiscretization *>::const_iterator it=other.begin();it!=other.end();it++,i++) + { + const MEDCouplingConstOnTimeInterval *itC=dynamic_cast<const MEDCouplingConstOnTimeInterval *>(*it); + if(!itC) + throw INTERP_KERNEL::Exception("ConstOnTimeInterval::aggregate on mismatched time discretization !"); + a[i]=itC->getArray(); + } + MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> arr=DataArrayDouble::Aggregate(a); + MEDCouplingConstOnTimeInterval *ret=new MEDCouplingConstOnTimeInterval; + ret->setArray(arr,0); + return ret; +} + +MEDCouplingTimeDiscretization *MEDCouplingConstOnTimeInterval::meld(const MEDCouplingTimeDiscretization *other) const +{ + const MEDCouplingConstOnTimeInterval *otherC=dynamic_cast<const MEDCouplingConstOnTimeInterval *>(other); + if(!otherC) + throw INTERP_KERNEL::Exception("ConstOnTimeInterval::meld on mismatched time discretization !"); + MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> arr=DataArrayDouble::Meld(getArray(),other->getArray()); + MEDCouplingConstOnTimeInterval *ret=new MEDCouplingConstOnTimeInterval; + ret->setTimeTolerance(getTimeTolerance()); + ret->setArray(arr,0); + return ret; +} + +MEDCouplingTimeDiscretization *MEDCouplingConstOnTimeInterval::dot(const MEDCouplingTimeDiscretization *other) const +{ + const MEDCouplingConstOnTimeInterval *otherC=dynamic_cast<const MEDCouplingConstOnTimeInterval *>(other); + if(!otherC) + throw INTERP_KERNEL::Exception("ConstOnTimeInterval::dot on mismatched time discretization !"); + MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> arr=DataArrayDouble::Dot(getArray(),other->getArray()); + MEDCouplingConstOnTimeInterval *ret=new MEDCouplingConstOnTimeInterval; + ret->setArray(arr,0); + return ret; +} + +MEDCouplingTimeDiscretization *MEDCouplingConstOnTimeInterval::crossProduct(const MEDCouplingTimeDiscretization *other) const +{ + const MEDCouplingConstOnTimeInterval *otherC=dynamic_cast<const MEDCouplingConstOnTimeInterval *>(other); + if(!otherC) + throw INTERP_KERNEL::Exception("ConstOnTimeInterval::crossProduct on mismatched time discretization !"); + MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> arr=DataArrayDouble::CrossProduct(getArray(),other->getArray()); + MEDCouplingConstOnTimeInterval *ret=new MEDCouplingConstOnTimeInterval; + ret->setArray(arr,0); + return ret; +} + +MEDCouplingTimeDiscretization *MEDCouplingConstOnTimeInterval::max(const MEDCouplingTimeDiscretization *other) const +{ + const MEDCouplingConstOnTimeInterval *otherC=dynamic_cast<const MEDCouplingConstOnTimeInterval *>(other); + if(!otherC) + throw INTERP_KERNEL::Exception("ConstOnTimeInterval::max on mismatched time discretization !"); + MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> arr=DataArrayDouble::Max(getArray(),other->getArray()); + MEDCouplingConstOnTimeInterval *ret=new MEDCouplingConstOnTimeInterval; + ret->setArray(arr,0); + return ret; +} + +MEDCouplingTimeDiscretization *MEDCouplingConstOnTimeInterval::min(const MEDCouplingTimeDiscretization *other) const +{ + const MEDCouplingConstOnTimeInterval *otherC=dynamic_cast<const MEDCouplingConstOnTimeInterval *>(other); + if(!otherC) + throw INTERP_KERNEL::Exception("ConstOnTimeInterval::min on mismatched time discretization !"); + MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> arr=DataArrayDouble::Min(getArray(),other->getArray()); + MEDCouplingConstOnTimeInterval *ret=new MEDCouplingConstOnTimeInterval; + ret->setArray(arr,0); + return ret; +} + +MEDCouplingTimeDiscretization *MEDCouplingConstOnTimeInterval::add(const MEDCouplingTimeDiscretization *other) const +{ + const MEDCouplingConstOnTimeInterval *otherC=dynamic_cast<const MEDCouplingConstOnTimeInterval *>(other); + if(!otherC) + throw INTERP_KERNEL::Exception("ConstOnTimeInterval::add on mismatched time discretization !"); + MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> arr=DataArrayDouble::Add(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::addEqual(const MEDCouplingTimeDiscretization *other) +{ + const MEDCouplingConstOnTimeInterval *otherC=dynamic_cast<const MEDCouplingConstOnTimeInterval *>(other); + if(!otherC) + throw INTERP_KERNEL::Exception("ConstOnTimeInterval::addEqual on mismatched time discretization !"); + if(!getArray()) + throw INTERP_KERNEL::Exception("MEDCouplingConstOnTimeInterval::substractaddEqual : Data Array is NULL !"); + getArray()->addEqual(other->getArray()); +} + +MEDCouplingTimeDiscretization *MEDCouplingConstOnTimeInterval::substract(const MEDCouplingTimeDiscretization *other) const +{ + const MEDCouplingConstOnTimeInterval *otherC=dynamic_cast<const MEDCouplingConstOnTimeInterval *>(other); + if(!otherC) + throw INTERP_KERNEL::Exception("ConstOnTimeInterval::substract on mismatched time discretization !"); + MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> arr=DataArrayDouble::Substract(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::substractEqual(const MEDCouplingTimeDiscretization *other) +{ + const MEDCouplingConstOnTimeInterval *otherC=dynamic_cast<const MEDCouplingConstOnTimeInterval *>(other); + if(!otherC) + throw INTERP_KERNEL::Exception("ConstOnTimeInterval::substractEqual on mismatched time discretization !"); + if(!getArray()) + throw INTERP_KERNEL::Exception("MEDCouplingConstOnTimeInterval::substractEqual : Data Array is NULL !"); + getArray()->substractEqual(other->getArray()); +} + +MEDCouplingTimeDiscretization *MEDCouplingConstOnTimeInterval::multiply(const MEDCouplingTimeDiscretization *other) const +{ + const MEDCouplingConstOnTimeInterval *otherC=dynamic_cast<const MEDCouplingConstOnTimeInterval *>(other); + if(!otherC) + throw INTERP_KERNEL::Exception("multiply on mismatched time discretization !"); + MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> arr=DataArrayDouble::Multiply(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::multiplyEqual(const MEDCouplingTimeDiscretization *other) +{ + const MEDCouplingConstOnTimeInterval *otherC=dynamic_cast<const MEDCouplingConstOnTimeInterval *>(other); + if(!otherC) + throw INTERP_KERNEL::Exception("ConstOnTimeInterval::multiplyEqual on mismatched time discretization !"); + if(!getArray()) + throw INTERP_KERNEL::Exception("MEDCouplingConstOnTimeInterval::multiplyEqual : Data Array is NULL !"); + getArray()->multiplyEqual(other->getArray()); +} + +MEDCouplingTimeDiscretization *MEDCouplingConstOnTimeInterval::divide(const MEDCouplingTimeDiscretization *other) const +{ + const MEDCouplingConstOnTimeInterval *otherC=dynamic_cast<const MEDCouplingConstOnTimeInterval *>(other); + if(!otherC) + throw INTERP_KERNEL::Exception("divide on mismatched time discretization !"); + MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> arr=DataArrayDouble::Divide(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::divideEqual(const MEDCouplingTimeDiscretization *other) +{ + const MEDCouplingConstOnTimeInterval *otherC=dynamic_cast<const MEDCouplingConstOnTimeInterval *>(other); + if(!otherC) + throw INTERP_KERNEL::Exception("ConstOnTimeInterval::divideEqual on mismatched time discretization !"); + if(!getArray()) + throw INTERP_KERNEL::Exception("MEDCouplingConstOnTimeInterval::divideEqual : Data Array is NULL !"); + getArray()->divideEqual(other->getArray()); +} + +MEDCouplingTimeDiscretization *MEDCouplingConstOnTimeInterval::pow(const MEDCouplingTimeDiscretization *other) const +{ + const MEDCouplingConstOnTimeInterval *otherC=dynamic_cast<const MEDCouplingConstOnTimeInterval *>(other); + if(!otherC) + throw INTERP_KERNEL::Exception("pow on mismatched time discretization !"); + MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> 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) +{ + const MEDCouplingConstOnTimeInterval *otherC=dynamic_cast<const MEDCouplingConstOnTimeInterval *>(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), + _start_order(other._start_order),_end_order(other._end_order) +{ + if(other._end_array) + _end_array=other._end_array->performCpy(deepCpy); + else + _end_array=0; +} + +void MEDCouplingTwoTimeSteps::updateTime() const +{ + MEDCouplingTimeDiscretization::updateTime(); + if(_end_array) + updateTimeWith(*_end_array); +} + +void MEDCouplingTwoTimeSteps::synchronizeTimeWith(const MEDCouplingMesh *mesh) +{ + 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::getHeapMemorySizeWithoutChildren() const +{ + return MEDCouplingTimeDiscretization::getHeapMemorySizeWithoutChildren(); +} + +std::vector<const BigMemoryObject *> MEDCouplingTwoTimeSteps::getDirectChildrenWithNull() const +{ + std::vector<const BigMemoryObject *> ret(MEDCouplingTimeDiscretization::getDirectChildrenWithNull()); + ret.push_back(_end_array); + return ret; +} + +void MEDCouplingTwoTimeSteps::copyTinyAttrFrom(const MEDCouplingTimeDiscretization& other) +{ + MEDCouplingTimeDiscretization::copyTinyAttrFrom(other); + const MEDCouplingTwoTimeSteps *otherC=dynamic_cast<const MEDCouplingTwoTimeSteps *>(&other); + if(!otherC) + throw INTERP_KERNEL::Exception("MEDCouplingTwoTimeSteps::copyTinyAttrFrom : mismatch of time discretization !"); + _start_time=otherC->_start_time; + _end_time=otherC->_end_time; + _start_iteration=otherC->_start_iteration; + _end_iteration=otherC->_end_iteration; + _start_order=otherC->_start_order; + _end_order=otherC->_end_order; +} + +void MEDCouplingTwoTimeSteps::copyTinyStringsFrom(const MEDCouplingTimeDiscretization& other) +{ + MEDCouplingTimeDiscretization::copyTinyStringsFrom(other); + const MEDCouplingTwoTimeSteps *otherC=dynamic_cast<const MEDCouplingTwoTimeSteps *>(&other); + if(!otherC) + throw INTERP_KERNEL::Exception("Trying to operate copyTinyStringsFrom on different field type (two times//one time) !"); + if(_end_array && otherC->_end_array) + _end_array->copyStringInfoFrom(*otherC->_end_array); +} + +const DataArrayDouble *MEDCouplingTwoTimeSteps::getEndArray() const +{ + return _end_array; +} + +DataArrayDouble *MEDCouplingTwoTimeSteps::getEndArray() +{ + return _end_array; +} + +void MEDCouplingTwoTimeSteps::checkCoherency() const +{ + MEDCouplingTimeDiscretization::checkCoherency(); + if(!_end_array) + throw INTERP_KERNEL::Exception("No end array specified !"); + if(_array->getNumberOfComponents()!=_end_array->getNumberOfComponents()) + throw INTERP_KERNEL::Exception("The number of components mismatch between the start and the end arrays !"); + if(_array->getNumberOfTuples()!=_end_array->getNumberOfTuples()) + 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 +{ + std::ostringstream oss; + const MEDCouplingTwoTimeSteps *otherC=dynamic_cast<const MEDCouplingTwoTimeSteps *>(other); + if(!otherC) + { + reason="This has time discretization LINEAR_TIME, other not."; + return false; + } + if(_start_iteration!=otherC->_start_iteration) + { + oss << "start iterations differ. this start iteration=" << _start_iteration << " other start iteration=" << otherC->_start_iteration; + reason=oss.str(); + return false; + } + if(_start_order!=otherC->_start_order) + { + oss << "start orders differ. this start order=" << _start_order << " other start order=" << otherC->_start_order; + reason=oss.str(); + return false; + } + if(std::fabs(_start_time-otherC->_start_time)>_time_tolerance) + { + oss << "start times differ. this start time=" << _start_time << " other start time=" << otherC->_start_time; + reason=oss.str(); + return false; + } + if(_end_iteration!=otherC->_end_iteration) + { + oss << "end iterations differ. this end iteration=" << _end_iteration << " other end iteration=" << otherC->_end_iteration; + reason=oss.str(); + return false; + } + if(_end_order!=otherC->_end_order) + { + oss << "end orders differ. this end order=" << _end_order << " other end order=" << otherC->_end_order; + reason=oss.str(); + return false; + } + if(std::fabs(_end_time-otherC->_end_time)>_time_tolerance) + { + oss << "end times differ. this end time=" << _end_time << " other end time=" << otherC->_end_time; + reason=oss.str(); + return false; + } + if(_end_array!=otherC->_end_array) + if(!_end_array->isEqualIfNotWhy(*otherC->_end_array,prec,reason)) + { + reason.insert(0,"end arrays differ for linear time."); + return false; + } + return MEDCouplingTimeDiscretization::isEqualIfNotWhy(other,prec,reason); +} + +bool MEDCouplingTwoTimeSteps::isEqualWithoutConsideringStr(const MEDCouplingTimeDiscretization *other, double prec) const +{ + const MEDCouplingTwoTimeSteps *otherC=dynamic_cast<const MEDCouplingTwoTimeSteps *>(other); + if(!otherC) + return false; + if(_start_iteration!=otherC->_start_iteration) + return false; + if(_end_iteration!=otherC->_end_iteration) + return false; + if(_start_order!=otherC->_start_order) + return false; + if(_end_order!=otherC->_end_order) + return false; + if(std::fabs(_start_time-otherC->_start_time)>_time_tolerance) + return false; + if(std::fabs(_end_time-otherC->_end_time)>_time_tolerance) + return false; + if(_end_array!=otherC->_end_array) + if(!_end_array->isEqualWithoutConsideringStr(*otherC->_end_array,prec)) + return false; + return MEDCouplingTimeDiscretization::isEqualWithoutConsideringStr(other,prec); +} + +MEDCouplingTwoTimeSteps::MEDCouplingTwoTimeSteps():_start_time(0.),_end_time(0.),_start_iteration(-1),_end_iteration(-1),_start_order(-1),_end_order(-1),_end_array(0) +{ +} + +MEDCouplingTwoTimeSteps::~MEDCouplingTwoTimeSteps() +{ + if(_end_array) + _end_array->decrRef(); +} + +void MEDCouplingTwoTimeSteps::checkNoTimePresence() const +{ + throw INTERP_KERNEL::Exception("The field presents a time to be specified in every access !"); +} + +void MEDCouplingTwoTimeSteps::checkTimePresence(double time) const +{ + if(time<_start_time-_time_tolerance || time>_end_time+_time_tolerance) + { + std::ostringstream stream; + stream << "The field is defined between times " << _start_time << " and " << _end_time << " worderh tolerance "; + stream << _time_tolerance << " and trying to access on time = " << time; + throw INTERP_KERNEL::Exception(stream.str().c_str()); + } +} + +void MEDCouplingTwoTimeSteps::getArrays(std::vector<DataArrayDouble *>& arrays) const +{ + arrays.resize(2); + arrays[0]=_array; + arrays[1]=_end_array; +} + +void MEDCouplingTwoTimeSteps::setEndArray(DataArrayDouble *array, TimeLabel *owner) +{ + if(array!=_end_array) + { + if(_end_array) + _end_array->decrRef(); + _end_array=array; + if(_end_array) + _end_array->incrRef(); + if(owner) + owner->declareAsNew(); + } +} + +void MEDCouplingTwoTimeSteps::getTinySerializationIntInformation(std::vector<int>& tinyInfo) const +{ + MEDCouplingTimeDiscretization::getTinySerializationIntInformation(tinyInfo); + tinyInfo.push_back(_start_iteration); + tinyInfo.push_back(_start_order); + tinyInfo.push_back(_end_iteration); + tinyInfo.push_back(_end_order); + if(_end_array) + { + tinyInfo.push_back(_end_array->getNumberOfTuples()); + tinyInfo.push_back(_end_array->getNumberOfComponents()); + } + else + { + tinyInfo.push_back(-1); + tinyInfo.push_back(-1); + } +} + +void MEDCouplingTwoTimeSteps::getTinySerializationDbleInformation(std::vector<double>& tinyInfo) const +{ + MEDCouplingTimeDiscretization::getTinySerializationDbleInformation(tinyInfo); + tinyInfo.push_back(_start_time); + tinyInfo.push_back(_end_time); +} + +void MEDCouplingTwoTimeSteps::getTinySerializationStrInformation(std::vector<std::string>& tinyInfo) const +{ + int nbOfCompo=_array->getNumberOfComponents(); + for(int i=0;i<nbOfCompo;i++) + tinyInfo.push_back(_array->getInfoOnComponent(i)); + for(int i=0;i<nbOfCompo;i++) + tinyInfo.push_back(_end_array->getInfoOnComponent(i)); +} + +void MEDCouplingTwoTimeSteps::resizeForUnserialization(const std::vector<int>& tinyInfoI, std::vector<DataArrayDouble *>& arrays) +{ + arrays.resize(2); + if(_array!=0) + _array->decrRef(); + if(_end_array!=0) + _end_array->decrRef(); + DataArrayDouble *arr=0; + if(tinyInfoI[0]!=-1 && tinyInfoI[1]!=-1) + { + arr=DataArrayDouble::New(); + arr->alloc(tinyInfoI[0],tinyInfoI[1]); + } + _array=arr; + arrays[0]=arr; + arr=0; + if(tinyInfoI[6]!=-1 && tinyInfoI[7]!=-1) + { + arr=DataArrayDouble::New(); + arr->alloc(tinyInfoI[6],tinyInfoI[7]); + } + _end_array=arr; + arrays[1]=arr; +} + +void MEDCouplingTwoTimeSteps::checkForUnserialization(const std::vector<int>& tinyInfoI, const std::vector<DataArrayDouble *>& arrays) +{ + static const char MSG[]="MEDCouplingTimeDiscretization::checkForUnserialization : arrays in input is expected to have size two !"; + if(arrays.size()!=2) + throw INTERP_KERNEL::Exception(MSG); + if(_array!=0) + _array->decrRef(); + if(_end_array!=0) + _end_array->decrRef(); + _array=0; _end_array=0; + if(tinyInfoI[0]!=-1 && tinyInfoI[1]!=-1) + { + if(!arrays[0]) + throw INTERP_KERNEL::Exception(MSG); + arrays[0]->checkNbOfTuplesAndComp(tinyInfoI[0],tinyInfoI[1],MSG); + _array=arrays[0]; _array->incrRef(); + } + if(tinyInfoI[6]!=-1 && tinyInfoI[7]!=-1) + { + if(!arrays[1]) + throw INTERP_KERNEL::Exception(MSG); + arrays[1]->checkNbOfTuplesAndComp(tinyInfoI[0],tinyInfoI[1],MSG); + _end_array=arrays[1]; _end_array->incrRef(); + } +} + +void MEDCouplingTwoTimeSteps::finishUnserialization(const std::vector<int>& tinyInfoI, const std::vector<double>& tinyInfoD, const std::vector<std::string>& tinyInfoS) +{ + MEDCouplingTimeDiscretization::finishUnserialization(tinyInfoI,tinyInfoD,tinyInfoS); + _start_time=tinyInfoD[1]; + _end_time=tinyInfoD[2]; + _start_iteration=tinyInfoI[2]; + _start_order=tinyInfoI[3]; + _end_iteration=tinyInfoI[4]; + _end_order=tinyInfoI[5]; +} + +/*! + * idem getTinySerializationIntInformation except that it is for multi field fetch + */ +void MEDCouplingTwoTimeSteps::getTinySerializationIntInformation2(std::vector<int>& tinyInfo) const +{ + tinyInfo.resize(4); + tinyInfo[0]=_start_iteration; + tinyInfo[1]=_start_order; + tinyInfo[2]=_end_iteration; + tinyInfo[3]=_end_order; +} + +/*! + * idem getTinySerializationDbleInformation except that it is for multi field fetch + */ +void MEDCouplingTwoTimeSteps::getTinySerializationDbleInformation2(std::vector<double>& tinyInfo) const +{ + tinyInfo.resize(3); + tinyInfo[0]=_time_tolerance; + tinyInfo[1]=_start_time; + tinyInfo[2]=_end_time; +} + +/*! + * idem finishUnserialization except that it is for multi field fetch + */ +void MEDCouplingTwoTimeSteps::finishUnserialization2(const std::vector<int>& tinyInfoI, const std::vector<double>& tinyInfoD) +{ + _start_iteration=tinyInfoI[0]; + _start_order=tinyInfoI[1]; + _end_iteration=tinyInfoI[2]; + _end_order=tinyInfoI[3]; + _time_tolerance=tinyInfoD[0]; + _start_time=tinyInfoD[1]; + _end_time=tinyInfoD[2]; +} + +std::vector< const DataArrayDouble *> MEDCouplingTwoTimeSteps::getArraysForTime(double time) const +{ + if(time>_start_time-_time_tolerance && time<_end_time+_time_tolerance) + { + std::vector< const DataArrayDouble *> ret(2); + ret[0]=_array; + ret[1]=_end_array; + return ret; + } + else + throw INTERP_KERNEL::Exception(EXCEPTION_MSG); +} + +void MEDCouplingTwoTimeSteps::setArrays(const std::vector<DataArrayDouble *>& arrays, TimeLabel *owner) +{ + if(arrays.size()!=2) + throw INTERP_KERNEL::Exception("MEDCouplingTwoTimeSteps::setArrays : number of arrays must be two."); + setArray(arrays.front(),owner); + setEndArray(arrays.back(),owner); +} + +MEDCouplingLinearTime::MEDCouplingLinearTime(const MEDCouplingLinearTime& other, bool deepCpy):MEDCouplingTwoTimeSteps(other,deepCpy) +{ +} + +MEDCouplingLinearTime::MEDCouplingLinearTime() +{ +} + +std::string MEDCouplingLinearTime::getStringRepr() const +{ + std::ostringstream stream; + stream << REPR << " Time interval is defined by :\niteration_start=" << _start_iteration << " order_start=" << _start_order << " and time_start=" << _start_time << "\n"; + stream << "iteration_end=" << _end_iteration << " order_end=" << _end_order << " and end_time=" << _end_time << "\n"; + stream << "Time unit is : \"" << _time_unit << "\""; + return stream.str(); +} + +void MEDCouplingLinearTime::checkCoherency() const +{ + MEDCouplingTwoTimeSteps::checkCoherency(); + if(std::fabs(_start_time-_end_time)<_time_tolerance) + throw INTERP_KERNEL::Exception("Start time and end time are equals regarding time tolerance."); +} + +MEDCouplingTimeDiscretization *MEDCouplingLinearTime::performCpy(bool deepCpy) const +{ + return new MEDCouplingLinearTime(*this,deepCpy); +} + +bool MEDCouplingLinearTime::areCompatible(const MEDCouplingTimeDiscretization *other) const +{ + if(!MEDCouplingTimeDiscretization::areCompatible(other)) + return false; + const MEDCouplingLinearTime *otherC=dynamic_cast<const MEDCouplingLinearTime *>(other); + if(otherC==0) + return false; + if(_end_array==0 && otherC->_end_array==0) + return true; + if(_end_array==0 || otherC->_end_array==0) + return false; + if(_end_array->getNumberOfComponents()!=otherC->_end_array->getNumberOfComponents()) + return false; + return true; +} + +bool MEDCouplingLinearTime::areStrictlyCompatible(const MEDCouplingTimeDiscretization *other, std::string& reason) const +{ + if(!MEDCouplingTimeDiscretization::areStrictlyCompatible(other,reason)) + return false; + const MEDCouplingLinearTime *otherC=dynamic_cast<const MEDCouplingLinearTime *>(other); + bool ret=otherC!=0; + if(!ret) + reason.insert(0,"time discretization of this is LINEAR_TIME, other has a different time discretization."); + return ret; +} + +bool MEDCouplingLinearTime::areStrictlyCompatibleForMul(const MEDCouplingTimeDiscretization *other) const +{ + if(!MEDCouplingTimeDiscretization::areStrictlyCompatibleForMul(other)) + return false; + const MEDCouplingLinearTime *otherC=dynamic_cast<const MEDCouplingLinearTime *>(other); + return otherC!=0; +} + +bool MEDCouplingLinearTime::areStrictlyCompatibleForDiv(const MEDCouplingTimeDiscretization *other) const +{ + if(!MEDCouplingTimeDiscretization::areStrictlyCompatibleForDiv(other)) + return false; + const MEDCouplingLinearTime *otherC=dynamic_cast<const MEDCouplingLinearTime *>(other); + if(otherC==0) + return false; + if(_end_array==0 && otherC->_end_array==0) + return true; + if(_end_array==0 || otherC->_end_array==0) + return false; + int nbC1=_end_array->getNumberOfComponents(); + int nbC2=otherC->_end_array->getNumberOfComponents(); + if(nbC1!=nbC2 && nbC2!=1) + return false; + return true; +} + +bool MEDCouplingLinearTime::areCompatibleForMeld(const MEDCouplingTimeDiscretization *other) const +{ + if(!MEDCouplingTimeDiscretization::areCompatibleForMeld(other)) + return false; + const MEDCouplingLinearTime *otherC=dynamic_cast<const MEDCouplingLinearTime *>(other); + return otherC!=0; +} + +/*! + * vals is expected to be of size 2*_array->getNumberOfTuples()==_array->getNumberOfTuples()+_end_array->getNumberOfTuples() + */ +void MEDCouplingLinearTime::getValueForTime(double time, const std::vector<double>& vals, double *res) const +{ + double alpha=(_end_time-time)/(_end_time-_start_time); + std::size_t nbComp=vals.size()/2; + std::transform(vals.begin(),vals.begin()+nbComp,res,std::bind2nd(std::multiplies<double>(),alpha)); + std::vector<double> tmp(nbComp); + std::transform(vals.begin()+nbComp,vals.end(),tmp.begin(),std::bind2nd(std::multiplies<double>(),1-alpha)); + std::transform(tmp.begin(),tmp.end(),res,res,std::plus<double>()); +} + +void MEDCouplingLinearTime::getValueOnTime(int eltId, double time, double *value) const +{ + double alpha=(_end_time-time)/(_end_time-_start_time); + int nbComp; + if(_array) + _array->getTuple(eltId,value); + else + throw INTERP_KERNEL::Exception("No start array existing."); + nbComp=_array->getNumberOfComponents(); + std::transform(value,value+nbComp,value,std::bind2nd(std::multiplies<double>(),alpha)); + std::vector<double> tmp(nbComp); + if(_end_array) + _end_array->getTuple(eltId,&tmp[0]); + else + throw INTERP_KERNEL::Exception("No end array existing."); + std::transform(tmp.begin(),tmp.end(),tmp.begin(),std::bind2nd(std::multiplies<double>(),1-alpha)); + std::transform(tmp.begin(),tmp.end(),value,value,std::plus<double>()); +} + +void MEDCouplingLinearTime::getValueOnDiscTime(int eltId, int iteration, int order, double *value) const +{ + if(iteration==_start_iteration && order==_start_order) + { + if(_array) + _array->getTuple(eltId,value); + else + throw INTERP_KERNEL::Exception("iteration order match with start time but no start array existing."); + } + if(iteration==_end_iteration && order==_end_order) + { + if(_end_array) + _end_array->getTuple(eltId,value); + else + throw INTERP_KERNEL::Exception("iteration order match with end time but no end array existing."); + } + else + throw INTERP_KERNEL::Exception(EXCEPTION_MSG); +} + +MEDCouplingTimeDiscretization *MEDCouplingLinearTime::aggregate(const MEDCouplingTimeDiscretization *other) const +{ + const MEDCouplingLinearTime *otherC=dynamic_cast<const MEDCouplingLinearTime *>(other); + if(!otherC) + throw INTERP_KERNEL::Exception("LinearTime::aggregation on mismatched time discretization !"); + MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> arr1=DataArrayDouble::Aggregate(getArray(),other->getArray()); + MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> arr2=DataArrayDouble::Aggregate(getEndArray(),other->getEndArray()); + MEDCouplingLinearTime *ret=new MEDCouplingLinearTime; + ret->setArray(arr1,0); + ret->setEndArray(arr2,0); + return ret; +} + +MEDCouplingTimeDiscretization *MEDCouplingLinearTime::aggregate(const std::vector<const MEDCouplingTimeDiscretization *>& other) const +{ + std::vector<const DataArrayDouble *> a(other.size()); + std::vector<const DataArrayDouble *> b(other.size()); + int i=0; + for(std::vector<const MEDCouplingTimeDiscretization *>::const_iterator it=other.begin();it!=other.end();it++,i++) + { + const MEDCouplingLinearTime *itC=dynamic_cast<const MEDCouplingLinearTime *>(*it); + if(!itC) + throw INTERP_KERNEL::Exception("MEDCouplingLinearTime::aggregate on mismatched time discretization !"); + a[i]=itC->getArray(); + b[i]=itC->getEndArray(); + } + MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> arr=DataArrayDouble::Aggregate(a); + MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> arr2=DataArrayDouble::Aggregate(b); + MEDCouplingLinearTime *ret=new MEDCouplingLinearTime; + ret->setArray(arr,0); + ret->setEndArray(arr2,0); + return ret; +} + +MEDCouplingTimeDiscretization *MEDCouplingLinearTime::meld(const MEDCouplingTimeDiscretization *other) const +{ + const MEDCouplingLinearTime *otherC=dynamic_cast<const MEDCouplingLinearTime *>(other); + if(!otherC) + throw INTERP_KERNEL::Exception("LinearTime::meld on mismatched time discretization !"); + MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> arr1=DataArrayDouble::Meld(getArray(),other->getArray()); + MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> arr2=DataArrayDouble::Meld(getEndArray(),other->getEndArray()); + MEDCouplingLinearTime *ret=new MEDCouplingLinearTime; + ret->setTimeTolerance(getTimeTolerance()); + ret->setArray(arr1,0); + ret->setEndArray(arr2,0); + return ret; +} + +MEDCouplingTimeDiscretization *MEDCouplingLinearTime::dot(const MEDCouplingTimeDiscretization *other) const +{ + const MEDCouplingLinearTime *otherC=dynamic_cast<const MEDCouplingLinearTime *>(other); + if(!otherC) + throw INTERP_KERNEL::Exception("LinearTime::dot on mismatched time discretization !"); + MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> arr1=DataArrayDouble::Dot(getArray(),other->getArray()); + MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> arr2=DataArrayDouble::Dot(getEndArray(),other->getEndArray()); + MEDCouplingLinearTime *ret=new MEDCouplingLinearTime; + ret->setArray(arr1,0); + ret->setEndArray(arr2,0); + return ret; +} + +MEDCouplingTimeDiscretization *MEDCouplingLinearTime::crossProduct(const MEDCouplingTimeDiscretization *other) const +{ + const MEDCouplingLinearTime *otherC=dynamic_cast<const MEDCouplingLinearTime *>(other); + if(!otherC) + throw INTERP_KERNEL::Exception("LinearTime::crossProduct on mismatched time discretization !"); + MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> arr1=DataArrayDouble::CrossProduct(getArray(),other->getArray()); + MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> arr2=DataArrayDouble::CrossProduct(getEndArray(),other->getEndArray()); + MEDCouplingLinearTime *ret=new MEDCouplingLinearTime; + ret->setArray(arr1,0); + ret->setEndArray(arr2,0); + return ret; +} + +MEDCouplingTimeDiscretization *MEDCouplingLinearTime::max(const MEDCouplingTimeDiscretization *other) const +{ + const MEDCouplingLinearTime *otherC=dynamic_cast<const MEDCouplingLinearTime *>(other); + if(!otherC) + throw INTERP_KERNEL::Exception("LinearTime::max on mismatched time discretization !"); + MEDCouplingLinearTime *ret=new MEDCouplingLinearTime; + MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> arr1=DataArrayDouble::Max(getArray(),other->getArray()); + MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> arr2=DataArrayDouble::Max(getEndArray(),other->getEndArray()); + ret->setArray(arr1,0); + ret->setEndArray(arr2,0); + return ret; +} + +MEDCouplingTimeDiscretization *MEDCouplingLinearTime::min(const MEDCouplingTimeDiscretization *other) const +{ + const MEDCouplingLinearTime *otherC=dynamic_cast<const MEDCouplingLinearTime *>(other); + if(!otherC) + throw INTERP_KERNEL::Exception("LinearTime::min on mismatched time discretization !"); + MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> arr1=DataArrayDouble::Min(getArray(),other->getArray()); + MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> arr2=DataArrayDouble::Min(getEndArray(),other->getEndArray()); + MEDCouplingLinearTime *ret=new MEDCouplingLinearTime; + ret->setArray(arr1,0); + ret->setEndArray(arr2,0); + return ret; +} + +MEDCouplingTimeDiscretization *MEDCouplingLinearTime::add(const MEDCouplingTimeDiscretization *other) const +{ + const MEDCouplingLinearTime *otherC=dynamic_cast<const MEDCouplingLinearTime *>(other); + if(!otherC) + throw INTERP_KERNEL::Exception("LinearTime::add on mismatched time discretization !"); + MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> arr1=DataArrayDouble::Add(getArray(),other->getArray()); + MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> arr2=DataArrayDouble::Add(getEndArray(),other->getEndArray()); + MEDCouplingLinearTime *ret=new MEDCouplingLinearTime; + ret->setArray(arr1,0); + ret->setEndArray(arr2,0); + return ret; +} + +void MEDCouplingLinearTime::addEqual(const MEDCouplingTimeDiscretization *other) +{ + const MEDCouplingLinearTime *otherC=dynamic_cast<const MEDCouplingLinearTime *>(other); + if(!otherC) + throw INTERP_KERNEL::Exception("LinearTime::addEqual on mismatched time discretization !"); + if(!getArray()) + throw INTERP_KERNEL::Exception("MEDCouplingLinearTime::addEqual : Data Array is NULL !"); + if(!getEndArray()) + throw INTERP_KERNEL::Exception("MEDCouplingLinearTime::addEqual : Data Array (end) is NULL !"); + getArray()->addEqual(other->getArray()); + getEndArray()->addEqual(other->getEndArray()); +} + +MEDCouplingTimeDiscretization *MEDCouplingLinearTime::substract(const MEDCouplingTimeDiscretization *other) const +{ + const MEDCouplingLinearTime *otherC=dynamic_cast<const MEDCouplingLinearTime *>(other); + if(!otherC) + throw INTERP_KERNEL::Exception("LinearTime::substract on mismatched time discretization !"); + MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> arr1=DataArrayDouble::Substract(getArray(),other->getArray()); + MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> arr2=DataArrayDouble::Substract(getEndArray(),other->getEndArray()); + MEDCouplingLinearTime *ret=new MEDCouplingLinearTime; + ret->setArray(arr1,0); + ret->setEndArray(arr2,0); + return ret; +} + +void MEDCouplingLinearTime::substractEqual(const MEDCouplingTimeDiscretization *other) +{ + const MEDCouplingLinearTime *otherC=dynamic_cast<const MEDCouplingLinearTime *>(other); + if(!otherC) + throw INTERP_KERNEL::Exception("LinearTime::addEqual on mismatched time discretization !"); + if(!getArray()) + throw INTERP_KERNEL::Exception("MEDCouplingLinearTime::substractEqual : Data Array is NULL !"); + if(!getEndArray()) + throw INTERP_KERNEL::Exception("MEDCouplingLinearTime::substractEqual : Data Array (end) is NULL !"); + getArray()->substractEqual(other->getArray()); + getEndArray()->substractEqual(other->getEndArray()); +} + +MEDCouplingTimeDiscretization *MEDCouplingLinearTime::multiply(const MEDCouplingTimeDiscretization *other) const +{ + const MEDCouplingLinearTime *otherC=dynamic_cast<const MEDCouplingLinearTime *>(other); + if(!otherC) + throw INTERP_KERNEL::Exception("LinearTime::multiply on mismatched time discretization !"); + MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> arr1=DataArrayDouble::Multiply(getArray(),other->getArray()); + MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> arr2=DataArrayDouble::Multiply(getEndArray(),other->getEndArray()); + MEDCouplingLinearTime *ret=new MEDCouplingLinearTime; + ret->setArray(arr1,0); + ret->setEndArray(arr2,0); + return ret; +} + +void MEDCouplingLinearTime::multiplyEqual(const MEDCouplingTimeDiscretization *other) +{ + const MEDCouplingLinearTime *otherC=dynamic_cast<const MEDCouplingLinearTime *>(other); + if(!otherC) + throw INTERP_KERNEL::Exception("LinearTime::addEqual on mismatched time discretization !"); + if(!getArray()) + throw INTERP_KERNEL::Exception("MEDCouplingLinearTime::multiplyEqual : Data Array is NULL !"); + if(!getEndArray()) + throw INTERP_KERNEL::Exception("MEDCouplingLinearTime::multiplyEqual : Data Array (end) is NULL !"); + getArray()->multiplyEqual(other->getArray()); + getEndArray()->multiplyEqual(other->getEndArray()); +} + +MEDCouplingTimeDiscretization *MEDCouplingLinearTime::divide(const MEDCouplingTimeDiscretization *other) const +{ + const MEDCouplingLinearTime *otherC=dynamic_cast<const MEDCouplingLinearTime *>(other); + if(!otherC) + throw INTERP_KERNEL::Exception("LinearTime::divide on mismatched time discretization !"); + MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> arr1=DataArrayDouble::Divide(getArray(),other->getArray()); + MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> arr2=DataArrayDouble::Divide(getEndArray(),other->getEndArray()); + MEDCouplingLinearTime *ret=new MEDCouplingLinearTime; + ret->setArray(arr1,0); + ret->setEndArray(arr2,0); + return ret; +} + +void MEDCouplingLinearTime::divideEqual(const MEDCouplingTimeDiscretization *other) +{ + const MEDCouplingLinearTime *otherC=dynamic_cast<const MEDCouplingLinearTime *>(other); + if(!otherC) + throw INTERP_KERNEL::Exception("LinearTime::addEqual on mismatched time discretization !"); + if(!getArray()) + throw INTERP_KERNEL::Exception("MEDCouplingLinearTime::divideEqual : Data Array is NULL !"); + if(!getEndArray()) + throw INTERP_KERNEL::Exception("MEDCouplingLinearTime::divideEqual : Data Array (end) is NULL !"); + getArray()->divideEqual(other->getArray()); + getEndArray()->divideEqual(other->getEndArray()); +} + +MEDCouplingTimeDiscretization *MEDCouplingLinearTime::pow(const MEDCouplingTimeDiscretization *other) const +{ + const MEDCouplingLinearTime *otherC=dynamic_cast<const MEDCouplingLinearTime *>(other); + if(!otherC) + throw INTERP_KERNEL::Exception("LinearTime::pow on mismatched time discretization !"); + MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> arr1=DataArrayDouble::Pow(getArray(),other->getArray()); + MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> 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) +{ + const MEDCouplingLinearTime *otherC=dynamic_cast<const MEDCouplingLinearTime *>(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/medtool/src/MEDCoupling/MEDCouplingTimeDiscretization.hxx b/src/medtool/src/MEDCoupling/MEDCouplingTimeDiscretization.hxx new file mode 100644 index 000000000..3bf7b82ad --- /dev/null +++ b/src/medtool/src/MEDCoupling/MEDCouplingTimeDiscretization.hxx @@ -0,0 +1,460 @@ +// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 +// 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_MEDCOUPLINGTIMEDISCRETIZATION_HXX__ +#define __PARAMEDMEM_MEDCOUPLINGTIMEDISCRETIZATION_HXX__ + +#include "MEDCoupling.hxx" +#include "MEDCouplingTimeLabel.hxx" +#include "MEDCouplingRefCountObject.hxx" +#include "InterpKernelException.hxx" + +#include <vector> + +namespace ParaMEDMEM +{ + class MEDCouplingMesh; + class DataArrayDouble; + class TimeLabel; + + class MEDCouplingTimeDiscretization : public TimeLabel, public BigMemoryObject + { + protected: + MEDCOUPLING_EXPORT MEDCouplingTimeDiscretization(); + MEDCOUPLING_EXPORT MEDCouplingTimeDiscretization(const MEDCouplingTimeDiscretization& other, bool deepCpy); + public: + MEDCOUPLING_EXPORT void updateTime() const; + MEDCOUPLING_EXPORT virtual std::size_t getHeapMemorySizeWithoutChildren() const; + MEDCOUPLING_EXPORT virtual std::vector<const BigMemoryObject *> getDirectChildrenWithNull() const; + MEDCOUPLING_EXPORT static MEDCouplingTimeDiscretization *New(TypeOfTimeDiscretization type); + MEDCOUPLING_EXPORT void setTimeUnit(const std::string& unit) { _time_unit=unit; } + MEDCOUPLING_EXPORT std::string getTimeUnit() const { return _time_unit; } + MEDCOUPLING_EXPORT virtual void copyTinyAttrFrom(const MEDCouplingTimeDiscretization& other); + MEDCOUPLING_EXPORT virtual void copyTinyStringsFrom(const MEDCouplingTimeDiscretization& other); + MEDCOUPLING_EXPORT virtual void checkCoherency() const; + MEDCOUPLING_EXPORT virtual bool areCompatible(const MEDCouplingTimeDiscretization *other) const; + MEDCOUPLING_EXPORT virtual bool areStrictlyCompatible(const MEDCouplingTimeDiscretization *other, std::string& reason) const; + MEDCOUPLING_EXPORT virtual bool areStrictlyCompatibleForMul(const MEDCouplingTimeDiscretization *other) const; + MEDCOUPLING_EXPORT virtual bool areStrictlyCompatibleForDiv(const MEDCouplingTimeDiscretization *other) const; + MEDCOUPLING_EXPORT virtual bool areCompatibleForMeld(const MEDCouplingTimeDiscretization *other) const; + MEDCOUPLING_EXPORT virtual bool isEqualIfNotWhy(const MEDCouplingTimeDiscretization *other, double prec, std::string& reason) const; + MEDCOUPLING_EXPORT virtual bool isEqual(const MEDCouplingTimeDiscretization *other, double prec) const; + MEDCOUPLING_EXPORT virtual bool isEqualWithoutConsideringStr(const MEDCouplingTimeDiscretization *other, double prec) const; + MEDCOUPLING_EXPORT virtual MEDCouplingTimeDiscretization *buildNewTimeReprFromThis(TypeOfTimeDiscretization type, bool deepCpy) const; + MEDCOUPLING_EXPORT virtual std::string getStringRepr() const = 0; + MEDCOUPLING_EXPORT virtual TypeOfTimeDiscretization getEnum() const = 0; + MEDCOUPLING_EXPORT virtual void synchronizeTimeWith(const MEDCouplingMesh *mesh) = 0; + MEDCOUPLING_EXPORT virtual MEDCouplingTimeDiscretization *aggregate(const MEDCouplingTimeDiscretization *other) const = 0; + MEDCOUPLING_EXPORT virtual MEDCouplingTimeDiscretization *aggregate(const std::vector<const MEDCouplingTimeDiscretization *>& other) const = 0; + MEDCOUPLING_EXPORT virtual MEDCouplingTimeDiscretization *meld(const MEDCouplingTimeDiscretization *other) const = 0; + MEDCOUPLING_EXPORT virtual MEDCouplingTimeDiscretization *dot(const MEDCouplingTimeDiscretization *other) const = 0; + MEDCOUPLING_EXPORT virtual MEDCouplingTimeDiscretization *crossProduct(const MEDCouplingTimeDiscretization *other) const = 0; + MEDCOUPLING_EXPORT virtual MEDCouplingTimeDiscretization *max(const MEDCouplingTimeDiscretization *other) const = 0; + MEDCOUPLING_EXPORT virtual MEDCouplingTimeDiscretization *min(const MEDCouplingTimeDiscretization *other) const = 0; + MEDCOUPLING_EXPORT virtual MEDCouplingTimeDiscretization *add(const MEDCouplingTimeDiscretization *other) const = 0; + MEDCOUPLING_EXPORT virtual void addEqual(const MEDCouplingTimeDiscretization *other) = 0; + MEDCOUPLING_EXPORT virtual MEDCouplingTimeDiscretization *substract(const MEDCouplingTimeDiscretization *other) const = 0; + MEDCOUPLING_EXPORT virtual void substractEqual(const MEDCouplingTimeDiscretization *other) = 0; + MEDCOUPLING_EXPORT virtual MEDCouplingTimeDiscretization *multiply(const MEDCouplingTimeDiscretization *other) const = 0; + MEDCOUPLING_EXPORT virtual void multiplyEqual(const MEDCouplingTimeDiscretization *other) = 0; + MEDCOUPLING_EXPORT virtual MEDCouplingTimeDiscretization *divide(const MEDCouplingTimeDiscretization *other) const = 0; + MEDCOUPLING_EXPORT virtual void divideEqual(const MEDCouplingTimeDiscretization *other) = 0; + MEDCOUPLING_EXPORT virtual MEDCouplingTimeDiscretization *pow(const MEDCouplingTimeDiscretization *other) const = 0; + MEDCOUPLING_EXPORT virtual void powEqual(const MEDCouplingTimeDiscretization *other) = 0; + MEDCOUPLING_EXPORT virtual void getTinySerializationIntInformation(std::vector<int>& tinyInfo) const; + MEDCOUPLING_EXPORT virtual void getTinySerializationDbleInformation(std::vector<double>& tinyInfo) const; + MEDCOUPLING_EXPORT virtual void getTinySerializationStrInformation(std::vector<std::string>& tinyInfo) const; + MEDCOUPLING_EXPORT virtual void resizeForUnserialization(const std::vector<int>& tinyInfoI, std::vector<DataArrayDouble *>& arrays); + MEDCOUPLING_EXPORT virtual void checkForUnserialization(const std::vector<int>& tinyInfoI, const std::vector<DataArrayDouble *>& arrays); + MEDCOUPLING_EXPORT virtual void finishUnserialization(const std::vector<int>& tinyInfoI, const std::vector<double>& tinyInfoD, const std::vector<std::string>& tinyInfoS); + MEDCOUPLING_EXPORT virtual void getTinySerializationIntInformation2(std::vector<int>& tinyInfo) const = 0; + MEDCOUPLING_EXPORT virtual void getTinySerializationDbleInformation2(std::vector<double>& tinyInfo) const = 0; + MEDCOUPLING_EXPORT virtual void finishUnserialization2(const std::vector<int>& tinyInfoI, const std::vector<double>& tinyInfoD) = 0; + MEDCOUPLING_EXPORT virtual MEDCouplingTimeDiscretization *performCpy(bool deepCpy) const = 0; + MEDCOUPLING_EXPORT void setTimeTolerance(double val) { _time_tolerance=val; } + MEDCOUPLING_EXPORT double getTimeTolerance() const { return _time_tolerance; } + MEDCOUPLING_EXPORT virtual void checkNoTimePresence() const = 0; + MEDCOUPLING_EXPORT virtual void checkTimePresence(double time) const = 0; + MEDCOUPLING_EXPORT virtual void setArray(DataArrayDouble *array, TimeLabel *owner); + MEDCOUPLING_EXPORT virtual void setEndArray(DataArrayDouble *array, TimeLabel *owner); + MEDCOUPLING_EXPORT virtual void setArrays(const std::vector<DataArrayDouble *>& arrays, TimeLabel *owner); + MEDCOUPLING_EXPORT DataArrayDouble *getArray() { return _array; } + MEDCOUPLING_EXPORT const DataArrayDouble *getArray() const { return _array; } + MEDCOUPLING_EXPORT virtual const DataArrayDouble *getEndArray() const; + MEDCOUPLING_EXPORT virtual DataArrayDouble *getEndArray(); + MEDCOUPLING_EXPORT virtual std::vector< const DataArrayDouble *> getArraysForTime(double time) const = 0; + MEDCOUPLING_EXPORT virtual void getValueForTime(double time, const std::vector<double>& vals, double *res) const = 0; + MEDCOUPLING_EXPORT virtual void getArrays(std::vector<DataArrayDouble *>& arrays) const; + MEDCOUPLING_EXPORT virtual bool isBefore(const MEDCouplingTimeDiscretization *other) const; + MEDCOUPLING_EXPORT virtual bool isStrictlyBefore(const MEDCouplingTimeDiscretization *other) const; + MEDCOUPLING_EXPORT double getTime(int& iteration, int& order) const { return getStartTime(iteration,order); } + MEDCOUPLING_EXPORT virtual double getStartTime(int& iteration, int& order) const = 0; + MEDCOUPLING_EXPORT virtual double getEndTime(int& iteration, int& order) const = 0; + MEDCOUPLING_EXPORT void setTime(double time, int iteration, int order) { setStartTime(time,iteration,order); } + MEDCOUPLING_EXPORT void setIteration(int it) { setStartIteration(it); } + MEDCOUPLING_EXPORT void setOrder(int order) { setStartOrder(order); } + MEDCOUPLING_EXPORT void setTimeValue(double val) { setStartTimeValue(val); } + MEDCOUPLING_EXPORT virtual void setStartIteration(int it) = 0; + MEDCOUPLING_EXPORT virtual void setEndIteration(int it) = 0; + MEDCOUPLING_EXPORT virtual void setStartOrder(int order) = 0; + MEDCOUPLING_EXPORT virtual void setEndOrder(int order) = 0; + MEDCOUPLING_EXPORT virtual void setStartTimeValue(double time) = 0; + MEDCOUPLING_EXPORT virtual void setEndTimeValue(double time) = 0; + MEDCOUPLING_EXPORT virtual void setStartTime(double time, int iteration, int order) = 0; + MEDCOUPLING_EXPORT virtual void setEndTime(double time, int iteration, int order) = 0; + MEDCOUPLING_EXPORT virtual void getValueOnTime(int eltId, double time, double *value) const = 0; + MEDCOUPLING_EXPORT virtual void getValueOnDiscTime(int eltId, int iteration, int order, double *value) const = 0; + // + MEDCOUPLING_EXPORT virtual MEDCouplingTimeDiscretization *doublyContractedProduct() const; + MEDCOUPLING_EXPORT virtual MEDCouplingTimeDiscretization *determinant() const; + MEDCOUPLING_EXPORT virtual MEDCouplingTimeDiscretization *eigenValues() const; + MEDCOUPLING_EXPORT virtual MEDCouplingTimeDiscretization *eigenVectors() const; + MEDCOUPLING_EXPORT virtual MEDCouplingTimeDiscretization *inverse() const; + MEDCOUPLING_EXPORT virtual MEDCouplingTimeDiscretization *trace() const; + MEDCOUPLING_EXPORT virtual MEDCouplingTimeDiscretization *deviator() const; + MEDCOUPLING_EXPORT virtual MEDCouplingTimeDiscretization *magnitude() const; + MEDCOUPLING_EXPORT virtual MEDCouplingTimeDiscretization *negate() const; + MEDCOUPLING_EXPORT virtual MEDCouplingTimeDiscretization *maxPerTuple() const; + MEDCOUPLING_EXPORT virtual MEDCouplingTimeDiscretization *keepSelectedComponents(const std::vector<int>& compoIds) const; + MEDCOUPLING_EXPORT virtual void setSelectedComponents(const MEDCouplingTimeDiscretization *other, const std::vector<int>& compoIds); + MEDCOUPLING_EXPORT virtual void changeNbOfComponents(int newNbOfComp, double dftValue); + MEDCOUPLING_EXPORT virtual void sortPerTuple(bool asc); + MEDCOUPLING_EXPORT virtual void setUniformValue(int nbOfTuple, int nbOfCompo, double value); + MEDCOUPLING_EXPORT virtual void setOrCreateUniformValueOnAllComponents(int nbOfTuple, double value); + MEDCOUPLING_EXPORT virtual void applyLin(double a, double b, int compoId); + MEDCOUPLING_EXPORT virtual void applyLin(double a, double b); + MEDCOUPLING_EXPORT virtual void applyFunc(int nbOfComp, FunctionToEvaluate func); + MEDCOUPLING_EXPORT virtual void applyFunc(int nbOfComp, const std::string& func); + MEDCOUPLING_EXPORT virtual void applyFunc2(int nbOfComp, const std::string& func); + MEDCOUPLING_EXPORT virtual void applyFunc3(int nbOfComp, const std::vector<std::string>& varsOrder, const std::string& func); + MEDCOUPLING_EXPORT virtual void applyFunc(const std::string& func); + MEDCOUPLING_EXPORT virtual void applyFuncFast32(const std::string& func); + MEDCOUPLING_EXPORT virtual void applyFuncFast64(const std::string& func); + MEDCOUPLING_EXPORT virtual void fillFromAnalytic(const DataArrayDouble *loc, int nbOfComp, FunctionToEvaluate func); + MEDCOUPLING_EXPORT virtual void fillFromAnalytic(const DataArrayDouble *loc, int nbOfComp, const std::string& func); + MEDCOUPLING_EXPORT virtual void fillFromAnalytic2(const DataArrayDouble *loc, int nbOfComp, const std::string& func); + MEDCOUPLING_EXPORT virtual void fillFromAnalytic3(const DataArrayDouble *loc, int nbOfComp, const std::vector<std::string>& varsOrder, const std::string& func); + // + MEDCOUPLING_EXPORT virtual ~MEDCouplingTimeDiscretization(); + protected: + std::string _time_unit; + double _time_tolerance; + DataArrayDouble *_array; + protected: + static const double TIME_TOLERANCE_DFT; + }; + + class MEDCouplingNoTimeLabel : public MEDCouplingTimeDiscretization + { + public: + MEDCOUPLING_EXPORT MEDCouplingNoTimeLabel(); + MEDCOUPLING_EXPORT MEDCouplingNoTimeLabel(const MEDCouplingTimeDiscretization& other, bool deepCpy); + MEDCOUPLING_EXPORT std::string getStringRepr() const; + MEDCOUPLING_EXPORT TypeOfTimeDiscretization getEnum() const { return DISCRETIZATION; } + MEDCOUPLING_EXPORT void synchronizeTimeWith(const MEDCouplingMesh *mesh); + MEDCOUPLING_EXPORT MEDCouplingTimeDiscretization *aggregate(const MEDCouplingTimeDiscretization *other) const; + MEDCOUPLING_EXPORT MEDCouplingTimeDiscretization *aggregate(const std::vector<const MEDCouplingTimeDiscretization *>& other) const; + MEDCOUPLING_EXPORT MEDCouplingTimeDiscretization *meld(const MEDCouplingTimeDiscretization *other) const; + MEDCOUPLING_EXPORT MEDCouplingTimeDiscretization *dot(const MEDCouplingTimeDiscretization *other) const; + MEDCOUPLING_EXPORT MEDCouplingTimeDiscretization *crossProduct(const MEDCouplingTimeDiscretization *other) const; + MEDCOUPLING_EXPORT MEDCouplingTimeDiscretization *max(const MEDCouplingTimeDiscretization *other) const; + MEDCOUPLING_EXPORT MEDCouplingTimeDiscretization *min(const MEDCouplingTimeDiscretization *other) const; + MEDCOUPLING_EXPORT MEDCouplingTimeDiscretization *add(const MEDCouplingTimeDiscretization *other) const; + MEDCOUPLING_EXPORT void addEqual(const MEDCouplingTimeDiscretization *other); + MEDCOUPLING_EXPORT MEDCouplingTimeDiscretization *substract(const MEDCouplingTimeDiscretization *other) const; + MEDCOUPLING_EXPORT void substractEqual(const MEDCouplingTimeDiscretization *other); + MEDCOUPLING_EXPORT MEDCouplingTimeDiscretization *multiply(const MEDCouplingTimeDiscretization *other) const; + MEDCOUPLING_EXPORT void multiplyEqual(const MEDCouplingTimeDiscretization *other); + MEDCOUPLING_EXPORT MEDCouplingTimeDiscretization *divide(const MEDCouplingTimeDiscretization *other) const; + MEDCOUPLING_EXPORT void divideEqual(const MEDCouplingTimeDiscretization *other); + MEDCOUPLING_EXPORT MEDCouplingTimeDiscretization *pow(const MEDCouplingTimeDiscretization *other) const; + MEDCOUPLING_EXPORT void powEqual(const MEDCouplingTimeDiscretization *other); + MEDCOUPLING_EXPORT bool isEqualIfNotWhy(const MEDCouplingTimeDiscretization *other, double prec, std::string& reason) const; + MEDCOUPLING_EXPORT bool isEqualWithoutConsideringStr(const MEDCouplingTimeDiscretization *other, double prec) const; + MEDCOUPLING_EXPORT bool areCompatible(const MEDCouplingTimeDiscretization *other) const; + MEDCOUPLING_EXPORT bool areStrictlyCompatible(const MEDCouplingTimeDiscretization *other, std::string& reason) const; + MEDCOUPLING_EXPORT bool areStrictlyCompatibleForMul(const MEDCouplingTimeDiscretization *other) const; + MEDCOUPLING_EXPORT bool areStrictlyCompatibleForDiv(const MEDCouplingTimeDiscretization *other) const; + MEDCOUPLING_EXPORT bool areCompatibleForMeld(const MEDCouplingTimeDiscretization *other) const; + MEDCOUPLING_EXPORT MEDCouplingTimeDiscretization *performCpy(bool deepCpy) const; + MEDCOUPLING_EXPORT void checkNoTimePresence() const { } + MEDCOUPLING_EXPORT void checkTimePresence(double time) const; + MEDCOUPLING_EXPORT std::vector< const DataArrayDouble *> getArraysForTime(double time) const; + MEDCOUPLING_EXPORT void getValueForTime(double time, const std::vector<double>& vals, double *res) const; + MEDCOUPLING_EXPORT bool isBefore(const MEDCouplingTimeDiscretization *other) const; + MEDCOUPLING_EXPORT bool isStrictlyBefore(const MEDCouplingTimeDiscretization *other) const; + MEDCOUPLING_EXPORT double getStartTime(int& iteration, int& order) const; + MEDCOUPLING_EXPORT double getEndTime(int& iteration, int& order) const; + MEDCOUPLING_EXPORT void setStartIteration(int it); + MEDCOUPLING_EXPORT void setEndIteration(int it); + MEDCOUPLING_EXPORT void setStartOrder(int order); + MEDCOUPLING_EXPORT void setEndOrder(int order); + MEDCOUPLING_EXPORT void setStartTimeValue(double time); + MEDCOUPLING_EXPORT void setEndTimeValue(double time); + MEDCOUPLING_EXPORT void setStartTime(double time, int iteration, int order); + MEDCOUPLING_EXPORT void setEndTime(double time, int iteration, int order); + MEDCOUPLING_EXPORT void getValueOnTime(int eltId, double time, double *value) const; + MEDCOUPLING_EXPORT void getValueOnDiscTime(int eltId, int iteration, int order, double *value) const; + MEDCOUPLING_EXPORT void getTinySerializationIntInformation2(std::vector<int>& tinyInfo) const; + MEDCOUPLING_EXPORT void getTinySerializationDbleInformation2(std::vector<double>& tinyInfo) const; + MEDCOUPLING_EXPORT void finishUnserialization2(const std::vector<int>& tinyInfoI, const std::vector<double>& tinyInfoD); + public: + static const TypeOfTimeDiscretization DISCRETIZATION=NO_TIME; + MEDCOUPLING_EXPORT static const char REPR[]; + private: + static const char EXCEPTION_MSG[]; + }; + + class MEDCouplingWithTimeStep : public MEDCouplingTimeDiscretization + { + protected: + MEDCOUPLING_EXPORT MEDCouplingWithTimeStep(const MEDCouplingWithTimeStep& other, bool deepCpy); + public: + MEDCOUPLING_EXPORT MEDCouplingWithTimeStep(); + MEDCOUPLING_EXPORT std::string getStringRepr() const; + MEDCOUPLING_EXPORT void copyTinyAttrFrom(const MEDCouplingTimeDiscretization& other); + MEDCOUPLING_EXPORT TypeOfTimeDiscretization getEnum() const { return DISCRETIZATION; } + MEDCOUPLING_EXPORT void synchronizeTimeWith(const MEDCouplingMesh *mesh); + MEDCOUPLING_EXPORT MEDCouplingTimeDiscretization *aggregate(const MEDCouplingTimeDiscretization *other) const; + MEDCOUPLING_EXPORT MEDCouplingTimeDiscretization *aggregate(const std::vector<const MEDCouplingTimeDiscretization *>& other) const; + MEDCOUPLING_EXPORT MEDCouplingTimeDiscretization *meld(const MEDCouplingTimeDiscretization *other) const; + MEDCOUPLING_EXPORT MEDCouplingTimeDiscretization *dot(const MEDCouplingTimeDiscretization *other) const; + MEDCOUPLING_EXPORT MEDCouplingTimeDiscretization *crossProduct(const MEDCouplingTimeDiscretization *other) const; + MEDCOUPLING_EXPORT MEDCouplingTimeDiscretization *max(const MEDCouplingTimeDiscretization *other) const; + MEDCOUPLING_EXPORT MEDCouplingTimeDiscretization *min(const MEDCouplingTimeDiscretization *other) const; + MEDCOUPLING_EXPORT MEDCouplingTimeDiscretization *add(const MEDCouplingTimeDiscretization *other) const; + MEDCOUPLING_EXPORT void addEqual(const MEDCouplingTimeDiscretization *other); + MEDCOUPLING_EXPORT MEDCouplingTimeDiscretization *substract(const MEDCouplingTimeDiscretization *other) const; + MEDCOUPLING_EXPORT void substractEqual(const MEDCouplingTimeDiscretization *other); + MEDCOUPLING_EXPORT MEDCouplingTimeDiscretization *multiply(const MEDCouplingTimeDiscretization *other) const; + MEDCOUPLING_EXPORT void multiplyEqual(const MEDCouplingTimeDiscretization *other); + MEDCOUPLING_EXPORT MEDCouplingTimeDiscretization *divide(const MEDCouplingTimeDiscretization *other) const; + MEDCOUPLING_EXPORT void divideEqual(const MEDCouplingTimeDiscretization *other); + MEDCOUPLING_EXPORT MEDCouplingTimeDiscretization *pow(const MEDCouplingTimeDiscretization *other) const; + MEDCOUPLING_EXPORT void powEqual(const MEDCouplingTimeDiscretization *other); + MEDCOUPLING_EXPORT bool isEqualIfNotWhy(const MEDCouplingTimeDiscretization *other, double prec, std::string& reason) const; + MEDCOUPLING_EXPORT bool isEqualWithoutConsideringStr(const MEDCouplingTimeDiscretization *other, double prec) const; + MEDCOUPLING_EXPORT bool areCompatible(const MEDCouplingTimeDiscretization *other) const; + MEDCOUPLING_EXPORT bool areStrictlyCompatible(const MEDCouplingTimeDiscretization *other, std::string& reason) const; + MEDCOUPLING_EXPORT bool areStrictlyCompatibleForMul(const MEDCouplingTimeDiscretization *other) const; + MEDCOUPLING_EXPORT bool areStrictlyCompatibleForDiv(const MEDCouplingTimeDiscretization *other) const; + MEDCOUPLING_EXPORT bool areCompatibleForMeld(const MEDCouplingTimeDiscretization *other) const; + MEDCOUPLING_EXPORT void getTinySerializationIntInformation(std::vector<int>& tinyInfo) const; + MEDCOUPLING_EXPORT void getTinySerializationDbleInformation(std::vector<double>& tinyInfo) const; + MEDCOUPLING_EXPORT void finishUnserialization(const std::vector<int>& tinyInfoI, const std::vector<double>& tinyInfoD, const std::vector<std::string>& tinyInfoS); + MEDCOUPLING_EXPORT void getTinySerializationIntInformation2(std::vector<int>& tinyInfo) const; + MEDCOUPLING_EXPORT void getTinySerializationDbleInformation2(std::vector<double>& tinyInfo) const; + MEDCOUPLING_EXPORT void finishUnserialization2(const std::vector<int>& tinyInfoI, const std::vector<double>& tinyInfoD); + MEDCOUPLING_EXPORT MEDCouplingTimeDiscretization *performCpy(bool deepCpy) const; + MEDCOUPLING_EXPORT void checkNoTimePresence() const; + MEDCOUPLING_EXPORT void checkTimePresence(double time) const; + MEDCOUPLING_EXPORT void setStartTime(double time, int iteration, int order) { _time=time; _iteration=iteration; _order=order; } + MEDCOUPLING_EXPORT void setEndTime(double time, int iteration, int order) { _time=time; _iteration=iteration; _order=order; } + MEDCOUPLING_EXPORT double getStartTime(int& iteration, int& order) const { iteration=_iteration; order=_order; return _time; } + MEDCOUPLING_EXPORT double getEndTime(int& iteration, int& order) const { iteration=_iteration; order=_order; return _time; } + MEDCOUPLING_EXPORT void setStartIteration(int it) { _iteration=it; } + MEDCOUPLING_EXPORT void setEndIteration(int it) { _iteration=it; } + MEDCOUPLING_EXPORT void setStartOrder(int order) { _order=order; } + MEDCOUPLING_EXPORT void setEndOrder(int order) { _order=order; } + MEDCOUPLING_EXPORT void setStartTimeValue(double time) { _time=time; } + MEDCOUPLING_EXPORT void setEndTimeValue(double time) { _time=time; } + MEDCOUPLING_EXPORT std::vector< const DataArrayDouble *> getArraysForTime(double time) const; + MEDCOUPLING_EXPORT void getValueForTime(double time, const std::vector<double>& vals, double *res) const; + MEDCOUPLING_EXPORT void getValueOnTime(int eltId, double time, double *value) const; + MEDCOUPLING_EXPORT void getValueOnDiscTime(int eltId, int iteration, int order, double *value) const; + public: + static const TypeOfTimeDiscretization DISCRETIZATION=ONE_TIME; + MEDCOUPLING_EXPORT static const char REPR[]; + private: + static const char EXCEPTION_MSG[]; + protected: + double _time; + int _iteration; + int _order; + }; + + class MEDCouplingConstOnTimeInterval : public MEDCouplingTimeDiscretization + { + protected: + MEDCOUPLING_EXPORT MEDCouplingConstOnTimeInterval(const MEDCouplingConstOnTimeInterval& other, bool deepCpy); + public: + MEDCOUPLING_EXPORT MEDCouplingConstOnTimeInterval(); + MEDCOUPLING_EXPORT void copyTinyAttrFrom(const MEDCouplingTimeDiscretization& other); + MEDCOUPLING_EXPORT void getTinySerializationIntInformation(std::vector<int>& tinyInfo) const; + MEDCOUPLING_EXPORT void getTinySerializationDbleInformation(std::vector<double>& tinyInfo) const; + MEDCOUPLING_EXPORT void finishUnserialization(const std::vector<int>& tinyInfoI, const std::vector<double>& tinyInfoD, const std::vector<std::string>& tinyInfoS); + MEDCOUPLING_EXPORT void getTinySerializationIntInformation2(std::vector<int>& tinyInfo) const; + MEDCOUPLING_EXPORT void getTinySerializationDbleInformation2(std::vector<double>& tinyInfo) const; + MEDCOUPLING_EXPORT void finishUnserialization2(const std::vector<int>& tinyInfoI, const std::vector<double>& tinyInfoD); + MEDCOUPLING_EXPORT MEDCouplingTimeDiscretization *performCpy(bool deepCpy) const; + MEDCOUPLING_EXPORT bool areCompatible(const MEDCouplingTimeDiscretization *other) const; + MEDCOUPLING_EXPORT bool areStrictlyCompatible(const MEDCouplingTimeDiscretization *other, std::string& reason) const; + MEDCOUPLING_EXPORT bool areStrictlyCompatibleForMul(const MEDCouplingTimeDiscretization *other) const; + MEDCOUPLING_EXPORT bool areStrictlyCompatibleForDiv(const MEDCouplingTimeDiscretization *other) const; + MEDCOUPLING_EXPORT bool areCompatibleForMeld(const MEDCouplingTimeDiscretization *other) const; + MEDCOUPLING_EXPORT bool isEqualIfNotWhy(const MEDCouplingTimeDiscretization *other, double prec, std::string& reason) const; + MEDCOUPLING_EXPORT bool isEqualWithoutConsideringStr(const MEDCouplingTimeDiscretization *other, double prec) const; + MEDCOUPLING_EXPORT std::vector< const DataArrayDouble *> getArraysForTime(double time) const; + MEDCOUPLING_EXPORT void getValueForTime(double time, const std::vector<double>& vals, double *res) const; + MEDCOUPLING_EXPORT void getValueOnTime(int eltId, double time, double *value) const; + MEDCOUPLING_EXPORT void getValueOnDiscTime(int eltId, int iteration, int order, double *value) const; + MEDCOUPLING_EXPORT TypeOfTimeDiscretization getEnum() const { return DISCRETIZATION; } + MEDCOUPLING_EXPORT void synchronizeTimeWith(const MEDCouplingMesh *mesh); + MEDCOUPLING_EXPORT std::string getStringRepr() const; + MEDCOUPLING_EXPORT MEDCouplingTimeDiscretization *aggregate(const MEDCouplingTimeDiscretization *other) const; + MEDCOUPLING_EXPORT MEDCouplingTimeDiscretization *aggregate(const std::vector<const MEDCouplingTimeDiscretization *>& other) const; + MEDCOUPLING_EXPORT MEDCouplingTimeDiscretization *meld(const MEDCouplingTimeDiscretization *other) const; + MEDCOUPLING_EXPORT MEDCouplingTimeDiscretization *dot(const MEDCouplingTimeDiscretization *other) const; + MEDCOUPLING_EXPORT MEDCouplingTimeDiscretization *crossProduct(const MEDCouplingTimeDiscretization *other) const; + MEDCOUPLING_EXPORT MEDCouplingTimeDiscretization *max(const MEDCouplingTimeDiscretization *other) const; + MEDCOUPLING_EXPORT MEDCouplingTimeDiscretization *min(const MEDCouplingTimeDiscretization *other) const; + MEDCOUPLING_EXPORT MEDCouplingTimeDiscretization *add(const MEDCouplingTimeDiscretization *other) const; + MEDCOUPLING_EXPORT void addEqual(const MEDCouplingTimeDiscretization *other); + MEDCOUPLING_EXPORT MEDCouplingTimeDiscretization *substract(const MEDCouplingTimeDiscretization *other) const; + MEDCOUPLING_EXPORT void substractEqual(const MEDCouplingTimeDiscretization *other); + MEDCOUPLING_EXPORT MEDCouplingTimeDiscretization *multiply(const MEDCouplingTimeDiscretization *other) const; + MEDCOUPLING_EXPORT void multiplyEqual(const MEDCouplingTimeDiscretization *other); + MEDCOUPLING_EXPORT MEDCouplingTimeDiscretization *divide(const MEDCouplingTimeDiscretization *other) const; + MEDCOUPLING_EXPORT void divideEqual(const MEDCouplingTimeDiscretization *other); + MEDCouplingTimeDiscretization *pow(const MEDCouplingTimeDiscretization *other) const; + MEDCOUPLING_EXPORT void powEqual(const MEDCouplingTimeDiscretization *other); + MEDCOUPLING_EXPORT void setStartTime(double time, int iteration, int order) { _start_time=time; _start_iteration=iteration; _start_order=order; } + MEDCOUPLING_EXPORT void setEndTime(double time, int iteration, int order) { _end_time=time; _end_iteration=iteration; _end_order=order; } + MEDCOUPLING_EXPORT double getStartTime(int& iteration, int& order) const { iteration=_start_iteration; order=_start_order; return _start_time; } + MEDCOUPLING_EXPORT double getEndTime(int& iteration, int& order) const { iteration=_end_iteration; order=_end_order; return _end_time; } + MEDCOUPLING_EXPORT void setStartIteration(int it) { _start_iteration=it; } + MEDCOUPLING_EXPORT void setEndIteration(int it) { _end_iteration=it; } + MEDCOUPLING_EXPORT void setStartOrder(int order) { _start_order=order; } + MEDCOUPLING_EXPORT void setEndOrder(int order) { _end_order=order; } + MEDCOUPLING_EXPORT void setStartTimeValue(double time) { _start_time=time; } + MEDCOUPLING_EXPORT void setEndTimeValue(double time) { _end_time=time; } + MEDCOUPLING_EXPORT void checkNoTimePresence() const; + MEDCOUPLING_EXPORT void checkTimePresence(double time) const; + public: + static const TypeOfTimeDiscretization DISCRETIZATION=CONST_ON_TIME_INTERVAL; + MEDCOUPLING_EXPORT static const char REPR[]; + private: + static const char EXCEPTION_MSG[]; + protected: + double _start_time; + double _end_time; + int _start_iteration; + int _end_iteration; + int _start_order; + int _end_order; + }; + + class MEDCouplingTwoTimeSteps : public MEDCouplingTimeDiscretization + { + protected: + MEDCOUPLING_EXPORT MEDCouplingTwoTimeSteps(const MEDCouplingTwoTimeSteps& other, bool deepCpy); + MEDCOUPLING_EXPORT MEDCouplingTwoTimeSteps(); + MEDCOUPLING_EXPORT ~MEDCouplingTwoTimeSteps(); + public: + MEDCOUPLING_EXPORT void updateTime() const; + MEDCOUPLING_EXPORT void synchronizeTimeWith(const MEDCouplingMesh *mesh); + MEDCOUPLING_EXPORT std::size_t getHeapMemorySizeWithoutChildren() const; + MEDCOUPLING_EXPORT std::vector<const BigMemoryObject *> getDirectChildrenWithNull() const; + MEDCOUPLING_EXPORT void copyTinyAttrFrom(const MEDCouplingTimeDiscretization& other); + MEDCOUPLING_EXPORT void copyTinyStringsFrom(const MEDCouplingTimeDiscretization& other); + MEDCOUPLING_EXPORT const DataArrayDouble *getEndArray() const; + MEDCOUPLING_EXPORT DataArrayDouble *getEndArray(); + MEDCOUPLING_EXPORT void checkCoherency() const; + MEDCOUPLING_EXPORT bool isEqualIfNotWhy(const MEDCouplingTimeDiscretization *other, double prec, std::string& reason) const; + MEDCOUPLING_EXPORT bool isEqualWithoutConsideringStr(const MEDCouplingTimeDiscretization *other, double prec) const; + MEDCOUPLING_EXPORT void checkNoTimePresence() const; + MEDCOUPLING_EXPORT void checkTimePresence(double time) const; + MEDCOUPLING_EXPORT void getArrays(std::vector<DataArrayDouble *>& arrays) const; + MEDCOUPLING_EXPORT void setEndArray(DataArrayDouble *array, TimeLabel *owner); + MEDCOUPLING_EXPORT void setStartTime(double time, int iteration, int order) { _start_time=time; _start_iteration=iteration; _start_order=order; } + MEDCOUPLING_EXPORT void setEndTime(double time, int iteration, int order) { _end_time=time; _end_iteration=iteration; _end_order=order; } + MEDCOUPLING_EXPORT double getStartTime(int& iteration, int& order) const { iteration=_start_iteration; order=_start_order; return _start_time; } + MEDCOUPLING_EXPORT double getEndTime(int& iteration, int& order) const { iteration=_end_iteration; order=_end_order; return _end_time; } + MEDCOUPLING_EXPORT void setStartIteration(int it) { _start_iteration=it; } + MEDCOUPLING_EXPORT void setEndIteration(int it) { _end_iteration=it; } + MEDCOUPLING_EXPORT void setStartOrder(int order) { _start_order=order; } + MEDCOUPLING_EXPORT void setEndOrder(int order) { _end_order=order; } + MEDCOUPLING_EXPORT void setStartTimeValue(double time) { _start_time=time; } + MEDCOUPLING_EXPORT void setEndTimeValue(double time) { _end_time=time; } + MEDCOUPLING_EXPORT void getTinySerializationIntInformation(std::vector<int>& tinyInfo) const; + MEDCOUPLING_EXPORT void getTinySerializationDbleInformation(std::vector<double>& tinyInfo) const; + MEDCOUPLING_EXPORT void getTinySerializationStrInformation(std::vector<std::string>& tinyInfo) const; + MEDCOUPLING_EXPORT void resizeForUnserialization(const std::vector<int>& tinyInfoI, std::vector<DataArrayDouble *>& arrays); + MEDCOUPLING_EXPORT void checkForUnserialization(const std::vector<int>& tinyInfoI, const std::vector<DataArrayDouble *>& arrays); + MEDCOUPLING_EXPORT void finishUnserialization(const std::vector<int>& tinyInfoI, const std::vector<double>& tinyInfoD, const std::vector<std::string>& tinyInfoS); + MEDCOUPLING_EXPORT void getTinySerializationIntInformation2(std::vector<int>& tinyInfo) const; + MEDCOUPLING_EXPORT void getTinySerializationDbleInformation2(std::vector<double>& tinyInfo) const; + MEDCOUPLING_EXPORT void finishUnserialization2(const std::vector<int>& tinyInfoI, const std::vector<double>& tinyInfoD); + MEDCOUPLING_EXPORT std::vector< const DataArrayDouble *> getArraysForTime(double time) const; + MEDCOUPLING_EXPORT void setArrays(const std::vector<DataArrayDouble *>& arrays, TimeLabel *owner); + protected: + static const char EXCEPTION_MSG[]; + protected: + double _start_time; + double _end_time; + int _start_iteration; + int _end_iteration; + int _start_order; + int _end_order; + DataArrayDouble *_end_array; + }; + + class MEDCouplingLinearTime : public MEDCouplingTwoTimeSteps + { + protected: + MEDCOUPLING_EXPORT MEDCouplingLinearTime(const MEDCouplingLinearTime& other, bool deepCpy); + public: + MEDCOUPLING_EXPORT MEDCouplingLinearTime(); + MEDCOUPLING_EXPORT std::string getStringRepr() const; + MEDCOUPLING_EXPORT TypeOfTimeDiscretization getEnum() const { return DISCRETIZATION; } + MEDCOUPLING_EXPORT void checkCoherency() const; + MEDCOUPLING_EXPORT MEDCouplingTimeDiscretization *performCpy(bool deepCpy) const; + MEDCOUPLING_EXPORT bool areCompatible(const MEDCouplingTimeDiscretization *other) const; + MEDCOUPLING_EXPORT bool areStrictlyCompatible(const MEDCouplingTimeDiscretization *other, std::string& reason) const; + MEDCOUPLING_EXPORT bool areStrictlyCompatibleForMul(const MEDCouplingTimeDiscretization *other) const; + MEDCOUPLING_EXPORT bool areStrictlyCompatibleForDiv(const MEDCouplingTimeDiscretization *other) const; + MEDCOUPLING_EXPORT bool areCompatibleForMeld(const MEDCouplingTimeDiscretization *other) const; + MEDCOUPLING_EXPORT void getValueForTime(double time, const std::vector<double>& vals, double *res) const; + MEDCOUPLING_EXPORT void getValueOnTime(int eltId, double time, double *value) const; + MEDCOUPLING_EXPORT void getValueOnDiscTime(int eltId, int iteration, int order, double *value) const; + MEDCOUPLING_EXPORT MEDCouplingTimeDiscretization *aggregate(const MEDCouplingTimeDiscretization *other) const; + MEDCOUPLING_EXPORT MEDCouplingTimeDiscretization *aggregate(const std::vector<const MEDCouplingTimeDiscretization *>& other) const; + MEDCOUPLING_EXPORT MEDCouplingTimeDiscretization *meld(const MEDCouplingTimeDiscretization *other) const; + MEDCOUPLING_EXPORT MEDCouplingTimeDiscretization *dot(const MEDCouplingTimeDiscretization *other) const; + MEDCOUPLING_EXPORT MEDCouplingTimeDiscretization *crossProduct(const MEDCouplingTimeDiscretization *other) const; + MEDCOUPLING_EXPORT MEDCouplingTimeDiscretization *max(const MEDCouplingTimeDiscretization *other) const; + MEDCOUPLING_EXPORT MEDCouplingTimeDiscretization *min(const MEDCouplingTimeDiscretization *other) const; + MEDCOUPLING_EXPORT MEDCouplingTimeDiscretization *add(const MEDCouplingTimeDiscretization *other) const; + MEDCOUPLING_EXPORT void addEqual(const MEDCouplingTimeDiscretization *other); + MEDCOUPLING_EXPORT MEDCouplingTimeDiscretization *substract(const MEDCouplingTimeDiscretization *other) const; + MEDCOUPLING_EXPORT void substractEqual(const MEDCouplingTimeDiscretization *other); + MEDCOUPLING_EXPORT MEDCouplingTimeDiscretization *multiply(const MEDCouplingTimeDiscretization *other) const; + MEDCOUPLING_EXPORT void multiplyEqual(const MEDCouplingTimeDiscretization *other); + MEDCOUPLING_EXPORT MEDCouplingTimeDiscretization *divide(const MEDCouplingTimeDiscretization *other) const; + MEDCOUPLING_EXPORT void divideEqual(const MEDCouplingTimeDiscretization *other); + MEDCOUPLING_EXPORT MEDCouplingTimeDiscretization *pow(const MEDCouplingTimeDiscretization *other) const; + MEDCOUPLING_EXPORT void powEqual(const MEDCouplingTimeDiscretization *other); + public: + static const TypeOfTimeDiscretization DISCRETIZATION=LINEAR_TIME; + MEDCOUPLING_EXPORT static const char REPR[]; + }; +} + +#endif diff --git a/src/medtool/src/MEDCoupling/MEDCouplingTimeLabel.cxx b/src/medtool/src/MEDCoupling/MEDCouplingTimeLabel.cxx new file mode 100644 index 000000000..4bb3671f7 --- /dev/null +++ b/src/medtool/src/MEDCoupling/MEDCouplingTimeLabel.cxx @@ -0,0 +1,112 @@ +// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 +// 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 "MEDCouplingTimeLabel.hxx" + +#include "InterpKernelException.hxx" + +#include <limits> + +using namespace ParaMEDMEM; + +std::size_t TimeLabel::GLOBAL_TIME=0; + +TimeLabel::TimeLabel():_time(GLOBAL_TIME++) +{ +} + +TimeLabel::~TimeLabel() +{ +} + +TimeLabel& TimeLabel::operator=(const TimeLabel& other) +{ + _time=GLOBAL_TIME++; + return *this; +} + +void TimeLabel::declareAsNew() const +{ + _time=GLOBAL_TIME++; +} + +void TimeLabel::updateTimeWith(const TimeLabel& other) const +{ + if(_time<other._time) + _time=other._time; +} + +/*! + * This method has to be called with a lot of care. It set agressively the time in this with the + * time in \a other. + */ +void TimeLabel::forceTimeOfThis(const TimeLabel& other) const +{ + _time=other._time; +} + +TimeLabelConstOverseer::TimeLabelConstOverseer(const TimeLabel *tl):_tl(tl),_ref_time(std::numeric_limits<std::size_t>::max()) +{ + if(!_tl) + throw INTERP_KERNEL::Exception("TimeLabelConstOverseer constructor : input instance must be not NULL !"); + _tl->updateTime(); + _ref_time=tl->getTimeOfThis(); +} + +/*! + * This method checks that the tracked instance is not NULL and if not NULL that its internal state has not changed. + */ +void TimeLabelConstOverseer::checkConst() const +{ + if(!_tl) + throw INTERP_KERNEL::Exception("TimeLabelConstOverseer::checkConst : NULL tracked instance !"); + _tl->updateTime(); + if(_ref_time!=_tl->getTimeOfThis()) + throw INTERP_KERNEL::Exception("TimeLabelConstOverseer::checkConst : the state of the controlled instance of TimeLable has changed !"); +} + +bool TimeLabelConstOverseer::resetState() +{ + if(_tl) + { + _tl->updateTime(); + _ref_time=_tl->getTimeOfThis(); + return true; + } + else + return false; +} + +bool TimeLabelConstOverseer::keepTrackOfNewTL(const TimeLabel *tl) +{ + if(_tl==tl) + return false; + _tl=tl; + if(_tl) + { + _tl->updateTime(); + _ref_time=_tl->getTimeOfThis(); + } + else + { + _ref_time=std::numeric_limits<std::size_t>::max(); + } + return true; +} diff --git a/src/medtool/src/MEDCoupling/MEDCouplingTimeLabel.hxx b/src/medtool/src/MEDCoupling/MEDCouplingTimeLabel.hxx new file mode 100644 index 000000000..2ab528aad --- /dev/null +++ b/src/medtool/src/MEDCoupling/MEDCouplingTimeLabel.hxx @@ -0,0 +1,66 @@ +// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 +// 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_TIMELABEL_HXX__ +#define __PARAMEDMEM_TIMELABEL_HXX__ + +#include "MEDCoupling.hxx" + +#include <cstddef> + +namespace ParaMEDMEM +{ + /*! + * Class representing a label of time of the lastely modified part of this. + * More _time is high more the object has been modified recently. + */ + class TimeLabel + { + public: + MEDCOUPLING_EXPORT TimeLabel& operator=(const TimeLabel& other); + //! This method should be called when write access has been done on this. + MEDCOUPLING_EXPORT void declareAsNew() const; + //! This method should be called on high level classes as Field or Mesh to take into acount modifications done in aggregates objects. + MEDCOUPLING_EXPORT virtual void updateTime() const = 0; + MEDCOUPLING_EXPORT std::size_t getTimeOfThis() const { return _time; } + protected: + MEDCOUPLING_EXPORT TimeLabel(); + MEDCOUPLING_EXPORT virtual ~TimeLabel(); + MEDCOUPLING_EXPORT void updateTimeWith(const TimeLabel& other) const; + MEDCOUPLING_EXPORT void forceTimeOfThis(const TimeLabel& other) const; + private: + static std::size_t GLOBAL_TIME; + mutable std::size_t _time; + }; + + class TimeLabelConstOverseer + { + public: + MEDCOUPLING_EXPORT TimeLabelConstOverseer(const TimeLabel *tl); + MEDCOUPLING_EXPORT void checkConst() const; + MEDCOUPLING_EXPORT bool resetState(); + MEDCOUPLING_EXPORT bool keepTrackOfNewTL(const TimeLabel *tl); + private: + const TimeLabel *_tl; + std::size_t _ref_time; + }; +} + +#endif diff --git a/src/medtool/src/MEDCoupling/MEDCouplingUMesh.cxx b/src/medtool/src/MEDCoupling/MEDCouplingUMesh.cxx new file mode 100644 index 000000000..d50bf73c2 --- /dev/null +++ b/src/medtool/src/MEDCoupling/MEDCouplingUMesh.cxx @@ -0,0 +1,11916 @@ +// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 +// 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 "MEDCouplingUMesh.hxx" +#include "MEDCoupling1GTUMesh.hxx" +#include "MEDCouplingMemArray.txx" +#include "MEDCouplingFieldDouble.hxx" +#include "MEDCouplingSkyLineArray.hxx" +#include "CellModel.hxx" +#include "VolSurfUser.txx" +#include "InterpolationUtils.hxx" +#include "PointLocatorAlgos.txx" +#include "BBTree.txx" +#include "BBTreeDst.txx" +#include "SplitterTetra.hxx" +#include "DiameterCalculator.hxx" +#include "DirectedBoundingBox.hxx" +#include "InterpKernelMatrixTools.hxx" +#include "InterpKernelMeshQuality.hxx" +#include "InterpKernelCellSimplify.hxx" +#include "InterpKernelGeo2DEdgeArcCircle.hxx" +#include "InterpKernelAutoPtr.hxx" +#include "InterpKernelGeo2DNode.hxx" +#include "InterpKernelGeo2DEdgeLin.hxx" +#include "InterpKernelGeo2DEdgeArcCircle.hxx" +#include "InterpKernelGeo2DQuadraticPolygon.hxx" + +#include <sstream> +#include <fstream> +#include <numeric> +#include <cstring> +#include <limits> +#include <list> + +using namespace ParaMEDMEM; + +double MEDCouplingUMesh::EPS_FOR_POLYH_ORIENTATION=1.e-14; + +const INTERP_KERNEL::NormalizedCellType MEDCouplingUMesh::MEDMEM_ORDER[N_MEDMEM_ORDER] = { INTERP_KERNEL::NORM_POINT1, INTERP_KERNEL::NORM_SEG2, INTERP_KERNEL::NORM_SEG3, INTERP_KERNEL::NORM_SEG4, INTERP_KERNEL::NORM_POLYL, INTERP_KERNEL::NORM_TRI3, INTERP_KERNEL::NORM_QUAD4, INTERP_KERNEL::NORM_TRI6, INTERP_KERNEL::NORM_TRI7, INTERP_KERNEL::NORM_QUAD8, INTERP_KERNEL::NORM_QUAD9, INTERP_KERNEL::NORM_POLYGON, INTERP_KERNEL::NORM_QPOLYG, INTERP_KERNEL::NORM_TETRA4, INTERP_KERNEL::NORM_PYRA5, INTERP_KERNEL::NORM_PENTA6, INTERP_KERNEL::NORM_HEXA8, INTERP_KERNEL::NORM_HEXGP12, INTERP_KERNEL::NORM_TETRA10, INTERP_KERNEL::NORM_PYRA13, INTERP_KERNEL::NORM_PENTA15, INTERP_KERNEL::NORM_HEXA20, INTERP_KERNEL::NORM_HEXA27, INTERP_KERNEL::NORM_POLYHED }; + +MEDCouplingUMesh *MEDCouplingUMesh::New() +{ + return new MEDCouplingUMesh; +} + +MEDCouplingUMesh *MEDCouplingUMesh::New(const std::string& meshName, int meshDim) +{ + MEDCouplingUMesh *ret=new MEDCouplingUMesh; + ret->setName(meshName); + ret->setMeshDimension(meshDim); + return ret; +} + +/*! + * Returns a new MEDCouplingMesh which is a full copy of \a this one. No data is shared + * between \a this and the new mesh. + * \return MEDCouplingMesh * - a new instance of MEDCouplingMesh. The caller is to + * delete this mesh using decrRef() as it is no more needed. + */ +MEDCouplingMesh *MEDCouplingUMesh::deepCpy() const +{ + return clone(true); +} + +/*! + * Returns a new MEDCouplingMesh which is a copy of \a this one. + * \param [in] recDeepCpy - if \a true, the copy is deep, else all data arrays of \a + * this mesh are shared by the new mesh. + * \return MEDCouplingMesh * - a new instance of MEDCouplingMesh. The caller is to + * delete this mesh using decrRef() as it is no more needed. + */ +MEDCouplingUMesh *MEDCouplingUMesh::clone(bool recDeepCpy) const +{ + return new MEDCouplingUMesh(*this,recDeepCpy); +} + +/*! + * This method behaves mostly like MEDCouplingUMesh::deepCpy method, except that only nodal connectivity arrays are deeply copied. + * The coordinates are shared between \a this and the returned instance. + * + * \return MEDCouplingUMesh * - A new object instance holding the copy of \a this (deep for connectivity, shallow for coordiantes) + * \sa MEDCouplingUMesh::deepCpy + */ +MEDCouplingPointSet *MEDCouplingUMesh::deepCpyConnectivityOnly() const +{ + checkConnectivityFullyDefined(); + MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> ret=clone(false); + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> c(getNodalConnectivity()->deepCpy()),ci(getNodalConnectivityIndex()->deepCpy()); + ret->setConnectivity(c,ci); + return ret.retn(); +} + +void MEDCouplingUMesh::shallowCopyConnectivityFrom(const MEDCouplingPointSet *other) +{ + if(!other) + throw INTERP_KERNEL::Exception("MEDCouplingUMesh::shallowCopyConnectivityFrom : input pointer is null !"); + const MEDCouplingUMesh *otherC=dynamic_cast<const MEDCouplingUMesh *>(other); + if(!otherC) + throw INTERP_KERNEL::Exception("MEDCouplingUMesh::shallowCopyConnectivityFrom : input pointer is not an MEDCouplingUMesh instance !"); + MEDCouplingUMesh *otherC2=const_cast<MEDCouplingUMesh *>(otherC);//sorry :( + setConnectivity(otherC2->getNodalConnectivity(),otherC2->getNodalConnectivityIndex(),true); +} + +std::size_t MEDCouplingUMesh::getHeapMemorySizeWithoutChildren() const +{ + std::size_t ret(MEDCouplingPointSet::getHeapMemorySizeWithoutChildren()); + return ret; +} + +std::vector<const BigMemoryObject *> MEDCouplingUMesh::getDirectChildrenWithNull() const +{ + std::vector<const BigMemoryObject *> ret(MEDCouplingPointSet::getDirectChildrenWithNull()); + ret.push_back(_nodal_connec); + ret.push_back(_nodal_connec_index); + return ret; +} + +void MEDCouplingUMesh::updateTime() const +{ + MEDCouplingPointSet::updateTime(); + if(_nodal_connec) + { + updateTimeWith(*_nodal_connec); + } + if(_nodal_connec_index) + { + updateTimeWith(*_nodal_connec_index); + } +} + +MEDCouplingUMesh::MEDCouplingUMesh():_mesh_dim(-2),_nodal_connec(0),_nodal_connec_index(0) +{ +} + +/*! + * 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 +{ + if(_mesh_dim<-1) + throw INTERP_KERNEL::Exception("No mesh dimension specified !"); + if(_mesh_dim!=-1) + MEDCouplingPointSet::checkCoherency(); + for(std::set<INTERP_KERNEL::NormalizedCellType>::const_iterator iter=_types.begin();iter!=_types.end();iter++) + { + if((int)INTERP_KERNEL::CellModel::GetCellModel(*iter).getDimension()!=_mesh_dim) + { + std::ostringstream message; + message << "Mesh invalid because dimension is " << _mesh_dim << " and there is presence of cell(s) with type " << (*iter); + throw INTERP_KERNEL::Exception(message.str().c_str()); + } + } + if(_nodal_connec) + { + if(_nodal_connec->getNumberOfComponents()!=1) + throw INTERP_KERNEL::Exception("Nodal connectivity array is expected to be with number of components set to one !"); + if(_nodal_connec->getInfoOnComponent(0)!="") + throw INTERP_KERNEL::Exception("Nodal connectivity array is expected to have no info on its single component !"); + } + else + if(_mesh_dim!=-1) + throw INTERP_KERNEL::Exception("Nodal connectivity array is not defined !"); + if(_nodal_connec_index) + { + if(_nodal_connec_index->getNumberOfComponents()!=1) + throw INTERP_KERNEL::Exception("Nodal connectivity index array is expected to be with number of components set to one !"); + if(_nodal_connec_index->getInfoOnComponent(0)!="") + throw INTERP_KERNEL::Exception("Nodal connectivity index array is expected to have no info on its single component !"); + } + else + if(_mesh_dim!=-1) + throw INTERP_KERNEL::Exception("Nodal connectivity index array is not defined !"); +} + +/*! + * 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. <br> 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 +{ + checkCoherency(); + if(_mesh_dim==-1) + return ; + int meshDim=getMeshDimension(); + int nbOfNodes=getNumberOfNodes(); + int nbOfCells=getNumberOfCells(); + const int *ptr=_nodal_connec->getConstPointer(); + const int *ptrI=_nodal_connec_index->getConstPointer(); + for(int i=0;i<nbOfCells;i++) + { + const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel((INTERP_KERNEL::NormalizedCellType)ptr[ptrI[i]]); + if((int)cm.getDimension()!=meshDim) + { + std::ostringstream oss; + oss << "MEDCouplingUMesh::checkCoherency1 : cell << #" << i<< " with type Type " << cm.getRepr() << " in 'this' whereas meshdim == " << meshDim << " !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + int nbOfNodesInCell=ptrI[i+1]-ptrI[i]-1; + if(!cm.isDynamic()) + if(nbOfNodesInCell!=(int)cm.getNumberOfNodes()) + { + std::ostringstream oss; + oss << "MEDCouplingUMesh::checkCoherency1 : cell #" << i << " with static Type '" << cm.getRepr() << "' has " << cm.getNumberOfNodes(); + oss << " nodes whereas in connectivity there is " << nbOfNodesInCell << " nodes ! Looks very bad !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + if(cm.isQuadratic() && cm.isDynamic() && meshDim == 2) + if (nbOfNodesInCell % 2 || nbOfNodesInCell < 4) + { + std::ostringstream oss; + oss << "MEDCouplingUMesh::checkCoherency1 : cell #" << i << " with quadratic type '" << cm.getRepr() << "' has " << nbOfNodesInCell; + oss << " nodes. This should be even, and greater or equal than 4!! Looks very bad!"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + for(const int *w=ptr+ptrI[i]+1;w!=ptr+ptrI[i+1];w++) + { + int nodeId=*w; + if(nodeId>=0) + { + if(nodeId>=nbOfNodes) + { + std::ostringstream oss; oss << "Cell #" << i << " is built with node #" << nodeId << " whereas there are only " << nbOfNodes << " nodes in the mesh !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + } + else if(nodeId<-1) + { + std::ostringstream oss; oss << "Cell #" << i << " is built with node #" << nodeId << " in connectivity ! sounds bad !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + else + { + if((INTERP_KERNEL::NormalizedCellType)(ptr[ptrI[i]])!=INTERP_KERNEL::NORM_POLYHED) + { + std::ostringstream oss; oss << "Cell #" << i << " is built with node #-1 in connectivity ! sounds bad !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + } + } + } +} + + +/*! + * 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. <br> 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 +{ + 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 <em> -1 <= meshDim <= 3</em>. + */ +void MEDCouplingUMesh::setMeshDimension(int meshDim) +{ + 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 an estimation of the given number of cells. The closer is the estimation to the number of cells effectively inserted, + * the less will the library need to reallocate memory. If the number of cells to be inserted is not known simply put 0 to this parameter. + * If a nodal connectivity previouly existed before the call of this method, it will be reset. + * + * \param [in] nbOfCells - estimation of the number of cell \a this mesh will contain. + * + * \if ENABLE_EXAMPLES + * \ref medcouplingcppexamplesUmeshStdBuild1 "Here is a C++ example".<br> + * \ref medcouplingpyexamplesUmeshStdBuild1 "Here is a Python example". + * \endif + */ +void MEDCouplingUMesh::allocateCells(int nbOfCells) +{ + if(nbOfCells<0) + throw INTERP_KERNEL::Exception("MEDCouplingUMesh::allocateCells : the input number of cells should be >= 0 !"); + if(_nodal_connec_index) + { + _nodal_connec_index->decrRef(); + } + if(_nodal_connec) + { + _nodal_connec->decrRef(); + } + _nodal_connec_index=DataArrayInt::New(); + _nodal_connec_index->reserve(nbOfCells+1); + _nodal_connec_index->pushBackSilent(0); + _nodal_connec=DataArrayInt::New(); + _nodal_connec->reserve(2*nbOfCells); + _types.clear(); + declareAsNew(); +} + +/*! + * 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. + * + * \if ENABLE_EXAMPLES + * \ref medcouplingcppexamplesUmeshStdBuild1 "Here is a C++ example".<br> + * \ref medcouplingpyexamplesUmeshStdBuild1 "Here is a Python example". + * \endif + */ +void MEDCouplingUMesh::insertNextCell(INTERP_KERNEL::NormalizedCellType type, int size, const int *nodalConnOfCell) +{ + const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(type); + if(_nodal_connec_index==0) + throw INTERP_KERNEL::Exception("MEDCouplingUMesh::insertNextCell : nodal connectivity not set ! invoke allocateCells before calling insertNextCell !"); + if((int)cm.getDimension()==_mesh_dim) + { + 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); + } + else + { + std::ostringstream oss; oss << "MEDCouplingUMesh::insertNextCell : cell type " << cm.getRepr() << " has a dimension " << cm.getDimension(); + oss << " whereas Mesh Dimension of current UMesh instance is set to " << _mesh_dim << " ! Please invoke \"setMeshDimension\" method before or invoke "; + oss << "\"MEDCouplingUMesh::New\" static method with 2 parameters name and meshDimension !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } +} + +/*! + * Compacts data arrays to release unused memory. This method is to be called after + * finishing cell insertion using \a this->insertNextCell(). + * + * \if ENABLE_EXAMPLES + * \ref medcouplingcppexamplesUmeshStdBuild1 "Here is a C++ example".<br> + * \ref medcouplingpyexamplesUmeshStdBuild1 "Here is a Python example". + * \endif + */ +void MEDCouplingUMesh::finishInsertingCells() +{ + _nodal_connec->pack(); + _nodal_connec_index->pack(); + _nodal_connec->declareAsNew(); + _nodal_connec_index->declareAsNew(); + updateTime(); +} + +/*! + * Entry point for iteration over cells of this. Warning the returned cell iterator should be deallocated. + * Useful for python users. + */ +MEDCouplingUMeshCellIterator *MEDCouplingUMesh::cellIterator() +{ + return new MEDCouplingUMeshCellIterator(this); +} + +/*! + * Entry point for iteration over cells groups geo types per geotypes. Warning the returned cell iterator should be deallocated. + * If \a this is not so that that cells are grouped by geo types this method will throw an exception. + * In this case MEDCouplingUMesh::sortCellsInMEDFileFrmt or MEDCouplingUMesh::rearrange2ConsecutiveCellTypes methods for example can be called before invoking this method. + * Useful for python users. + */ +MEDCouplingUMeshCellByTypeEntry *MEDCouplingUMesh::cellsByType() +{ + if(!checkConsecutiveCellTypes()) + throw INTERP_KERNEL::Exception("MEDCouplingUMesh::cellsByType : this mesh is not sorted by type !"); + return new MEDCouplingUMeshCellByTypeEntry(this); +} + +/*! + * Returns a set of all cell types available in \a this mesh. + * \return std::set<INTERP_KERNEL::NormalizedCellType> - the set of cell types. + * \warning this method does not throw any exception even if \a this is not defined. + * \sa MEDCouplingUMesh::getAllGeoTypesSorted + */ +std::set<INTERP_KERNEL::NormalizedCellType> MEDCouplingUMesh::getAllGeoTypes() const +{ + return _types; +} + +/*! + * This method returns the sorted list of geometric types in \a this. + * Sorted means in the same order than the cells in \a this. A single entry in return vector means the maximal chunk of consecutive cells in \a this + * having the same geometric type. So a same geometric type can appear more than once if the cells are not sorted per geometric type. + * + * \throw if connectivity in \a this is not correctly defined. + * + * \sa MEDCouplingMesh::getAllGeoTypes + */ +std::vector<INTERP_KERNEL::NormalizedCellType> MEDCouplingUMesh::getAllGeoTypesSorted() const +{ + std::vector<INTERP_KERNEL::NormalizedCellType> ret; + checkConnectivityFullyDefined(); + int nbOfCells(getNumberOfCells()); + if(nbOfCells==0) + return ret; + if(getMeshLength()<1) + throw INTERP_KERNEL::Exception("MEDCouplingUMesh::getAllGeoTypesSorted : the connectivity in this seems invalid !"); + const int *c(_nodal_connec->begin()),*ci(_nodal_connec_index->begin()); + ret.push_back((INTERP_KERNEL::NormalizedCellType)c[*ci++]); + for(int i=1;i<nbOfCells;i++,ci++) + if(ret.back()!=((INTERP_KERNEL::NormalizedCellType)c[*ci])) + ret.push_back((INTERP_KERNEL::NormalizedCellType)c[*ci]); + return ret; +} + +/*! + * This method is a method that compares \a this and \a other. + * This method compares \b all attributes, even names and component names. + */ +bool MEDCouplingUMesh::isEqualIfNotWhy(const MEDCouplingMesh *other, double prec, std::string& reason) const +{ + if(!other) + throw INTERP_KERNEL::Exception("MEDCouplingUMesh::isEqualIfNotWhy : input other pointer is null !"); + std::ostringstream oss; oss.precision(15); + const MEDCouplingUMesh *otherC=dynamic_cast<const MEDCouplingUMesh *>(other); + if(!otherC) + { + reason="mesh given in input is not castable in MEDCouplingUMesh !"; + return false; + } + if(!MEDCouplingPointSet::isEqualIfNotWhy(other,prec,reason)) + return false; + if(_mesh_dim!=otherC->_mesh_dim) + { + oss << "umesh dimension mismatch : this mesh dimension=" << _mesh_dim << " other mesh dimension=" << otherC->_mesh_dim; + reason=oss.str(); + return false; + } + if(_types!=otherC->_types) + { + oss << "umesh geometric type mismatch :\nThis geometric types are :"; + for(std::set<INTERP_KERNEL::NormalizedCellType>::const_iterator iter=_types.begin();iter!=_types.end();iter++) + { const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(*iter); oss << cm.getRepr() << ", "; } + oss << "\nOther geometric types are :"; + for(std::set<INTERP_KERNEL::NormalizedCellType>::const_iterator iter=otherC->_types.begin();iter!=otherC->_types.end();iter++) + { const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(*iter); oss << cm.getRepr() << ", "; } + reason=oss.str(); + return false; + } + if(_nodal_connec!=0 || otherC->_nodal_connec!=0) + if(_nodal_connec==0 || otherC->_nodal_connec==0) + { + reason="Only one UMesh between the two this and other has its nodal connectivity DataArrayInt defined !"; + return false; + } + if(_nodal_connec!=otherC->_nodal_connec) + if(!_nodal_connec->isEqualIfNotWhy(*otherC->_nodal_connec,reason)) + { + reason.insert(0,"Nodal connectivity DataArrayInt differ : "); + return false; + } + if(_nodal_connec_index!=0 || otherC->_nodal_connec_index!=0) + if(_nodal_connec_index==0 || otherC->_nodal_connec_index==0) + { + reason="Only one UMesh between the two this and other has its nodal connectivity index DataArrayInt defined !"; + return false; + } + if(_nodal_connec_index!=otherC->_nodal_connec_index) + if(!_nodal_connec_index->isEqualIfNotWhy(*otherC->_nodal_connec_index,reason)) + { + reason.insert(0,"Nodal connectivity index DataArrayInt differ : "); + return false; + } + 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<const MEDCouplingUMesh *>(other); + if(!otherC) + return false; + if(!MEDCouplingPointSet::isEqualWithoutConsideringStr(other,prec)) + return false; + if(_mesh_dim!=otherC->_mesh_dim) + return false; + if(_types!=otherC->_types) + return false; + if(_nodal_connec!=0 || otherC->_nodal_connec!=0) + if(_nodal_connec==0 || otherC->_nodal_connec==0) + return false; + if(_nodal_connec!=otherC->_nodal_connec) + if(!_nodal_connec->isEqualWithoutConsideringStr(*otherC->_nodal_connec)) + return false; + if(_nodal_connec_index!=0 || otherC->_nodal_connec_index!=0) + if(_nodal_connec_index==0 || otherC->_nodal_connec_index==0) + return false; + if(_nodal_connec_index!=otherC->_nodal_connec_index) + if(!_nodal_connec_index->isEqualWithoutConsideringStr(*otherC->_nodal_connec_index)) + return false; + return true; +} + +/*! + * 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 +{ + MEDCouplingPointSet::checkFastEquivalWith(other,prec); + const MEDCouplingUMesh *otherC=dynamic_cast<const MEDCouplingUMesh *>(other); + if(!otherC) + throw INTERP_KERNEL::Exception("MEDCouplingUMesh::checkFastEquivalWith : Two meshes are not not unstructured !"); +} + +/*! + * 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. + * + * \if ENABLE_EXAMPLES + * \ref cpp_mcumesh_getReverseNodalConnectivity "Here is a C++ example".<br> + * \ref py_mcumesh_getReverseNodalConnectivity "Here is a Python example". + * \endif + */ +void MEDCouplingUMesh::getReverseNodalConnectivity(DataArrayInt *revNodal, DataArrayInt *revNodalIndx) const +{ + checkFullyDefined(); + int nbOfNodes=getNumberOfNodes(); + 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(); + int nbOfCells=getNumberOfCells(); + int nbOfEltsInRevNodal=0; + for(int eltId=0;eltId<nbOfCells;eltId++) + { + const int *strtNdlConnOfCurCell=conn+connIndex[eltId]+1; + const int *endNdlConnOfCurCell=conn+connIndex[eltId+1]; + for(const int *iter=strtNdlConnOfCurCell;iter!=endNdlConnOfCurCell;iter++) + if(*iter>=0)//for polyhedrons + { + nbOfEltsInRevNodal++; + revNodalIndxPtr[(*iter)+1]++; + } + } + std::transform(revNodalIndxPtr+1,revNodalIndxPtr+nbOfNodes+1,revNodalIndxPtr,revNodalIndxPtr+1,std::plus<int>()); + 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;eltId<nbOfCells;eltId++) + { + const int *strtNdlConnOfCurCell=conn+connIndex[eltId]+1; + const int *endNdlConnOfCurCell=conn+connIndex[eltId+1]; + for(const int *iter=strtNdlConnOfCurCell;iter!=endNdlConnOfCurCell;iter++) + if(*iter>=0)//for polyhedrons + *std::find_if(revNodalPtr+revNodalIndxPtr[*iter],revNodalPtr+revNodalIndxPtr[*iter+1],std::bind2nd(std::equal_to<int>(),-1))=eltId; + } +} + +/// @cond INTERNAL + +int MEDCouplingFastNbrer(int id, unsigned nb, const INTERP_KERNEL::CellModel& cm, bool compute, const int *conn1, const int *conn2) +{ + return id; +} + +int MEDCouplingOrientationSensitiveNbrer(int id, unsigned nb, const INTERP_KERNEL::CellModel& cm, bool compute, const int *conn1, const int *conn2) +{ + if(!compute) + return id+1; + else + { + if(cm.getOrientationStatus(nb,conn1,conn2)) + return id+1; + else + return -(id+1); + } +} + +class MinusOneSonsGenerator +{ +public: + MinusOneSonsGenerator(const INTERP_KERNEL::CellModel& cm):_cm(cm) { } + unsigned getNumberOfSons2(const int *conn, int lgth) const { return _cm.getNumberOfSons2(conn,lgth); } + unsigned fillSonCellNodalConnectivity2(int sonId, const int *nodalConn, int lgth, int *sonNodalConn, INTERP_KERNEL::NormalizedCellType& typeOfSon) const { return _cm.fillSonCellNodalConnectivity2(sonId,nodalConn,lgth,sonNodalConn,typeOfSon); } + static const int DELTA=1; +private: + const INTERP_KERNEL::CellModel& _cm; +}; + +class MinusOneSonsGeneratorBiQuadratic +{ +public: + MinusOneSonsGeneratorBiQuadratic(const INTERP_KERNEL::CellModel& cm):_cm(cm) { } + unsigned getNumberOfSons2(const int *conn, int lgth) const { return _cm.getNumberOfSons2(conn,lgth); } + unsigned fillSonCellNodalConnectivity2(int sonId, const int *nodalConn, int lgth, int *sonNodalConn, INTERP_KERNEL::NormalizedCellType& typeOfSon) const { return _cm.fillSonCellNodalConnectivity4(sonId,nodalConn,lgth,sonNodalConn,typeOfSon); } + static const int DELTA=1; +private: + const INTERP_KERNEL::CellModel& _cm; +}; + +class MinusTwoSonsGenerator +{ +public: + MinusTwoSonsGenerator(const INTERP_KERNEL::CellModel& cm):_cm(cm) { } + unsigned getNumberOfSons2(const int *conn, int lgth) const { return _cm.getNumberOfEdgesIn3D(conn,lgth); } + unsigned fillSonCellNodalConnectivity2(int sonId, const int *nodalConn, int lgth, int *sonNodalConn, INTERP_KERNEL::NormalizedCellType& typeOfSon) const { return _cm.fillSonEdgesNodalConnectivity3D(sonId,nodalConn,lgth,sonNodalConn,typeOfSon); } + static const int DELTA=2; +private: + const INTERP_KERNEL::CellModel& _cm; +}; + +/// @endcond + +/*! + * 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 (\ref numbering-indirect) 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 (\ref numbering-indirect) 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. + * + * \if ENABLE_EXAMPLES + * \ref cpp_mcumesh_buildDescendingConnectivity "Here is a C++ example".<br> + * \ref py_mcumesh_buildDescendingConnectivity "Here is a Python example". + * \endif + * \sa buildDescendingConnectivity2() + */ +MEDCouplingUMesh *MEDCouplingUMesh::buildDescendingConnectivity(DataArrayInt *desc, DataArrayInt *descIndx, DataArrayInt *revDesc, DataArrayInt *revDescIndx) const +{ + return buildDescendingConnectivityGen<MinusOneSonsGenerator>(desc,descIndx,revDesc,revDescIndx,MEDCouplingFastNbrer); +} + +/*! + * \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 +{ + checkFullyDefined(); + if(getMeshDimension()!=3) + throw INTERP_KERNEL::Exception("MEDCouplingUMesh::explode3DMeshTo1D : This has to have a mesh dimension to 3 !"); + return buildDescendingConnectivityGen<MinusTwoSonsGenerator>(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 (\ref numbering-indirect) 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 (\ref numbering-indirect) 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. + * + * \if ENABLE_EXAMPLES + * \ref cpp_mcumesh_buildDescendingConnectivity2 "Here is a C++ example".<br> + * \ref py_mcumesh_buildDescendingConnectivity2 "Here is a Python example". + * \endif + * \sa buildDescendingConnectivity() + */ +MEDCouplingUMesh *MEDCouplingUMesh::buildDescendingConnectivity2(DataArrayInt *desc, DataArrayInt *descIndx, DataArrayInt *revDesc, DataArrayInt *revDescIndx) const +{ + return buildDescendingConnectivityGen<MinusOneSonsGenerator>(desc,descIndx,revDesc,revDescIndx,MEDCouplingOrientationSensitiveNbrer); +} + +/*! + * \b 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 calls + * MEDCouplingUMesh::buildDescendingConnectivity to compute the result. + * This method lists cell by cell in \b this which are its neighbors. To compute the result + * only connectivities are considered. + * The neighbor cells of cell having id 'cellId' are neighbors[neighborsIndx[cellId]:neighborsIndx[cellId+1]]. + * The format of return is hence \ref numbering-indirect. + * + * \param [out] neighbors is an array storing all the neighbors of all cells in \b this. This array is newly + * allocated and should be dealt by the caller. \b neighborsIndx 2nd output + * parameter allows to select the right part in this array (\ref numbering-indirect). The number of tuples + * is equal to the last values in \b neighborsIndx. + * \param [out] neighborsIndx is an array of size this->getNumberOfCells()+1 newly allocated and should be + * dealt by the caller. This arrays allow to use the first output parameter \b neighbors (\ref numbering-indirect). + */ +void MEDCouplingUMesh::computeNeighborsOfCells(DataArrayInt *&neighbors, DataArrayInt *&neighborsIndx) const +{ + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> desc=DataArrayInt::New(); + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> descIndx=DataArrayInt::New(); + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> revDesc=DataArrayInt::New(); + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> revDescIndx=DataArrayInt::New(); + MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> meshDM1=buildDescendingConnectivity(desc,descIndx,revDesc,revDescIndx); + meshDM1=0; + ComputeNeighborsOfCellsAdv(desc,descIndx,revDesc,revDescIndx,neighbors,neighborsIndx); +} + +/*! + * This method is called by MEDCouplingUMesh::computeNeighborsOfCells. This methods performs the algorithm + * of MEDCouplingUMesh::computeNeighborsOfCells. + * This method is useful for users that want to reduce along a criterion the set of neighbours cell. This is + * typically the case to extract a set a neighbours, + * excluding a set of meshdim-1 cells in input descending connectivity. + * Typically \b desc, \b descIndx, \b revDesc and \b revDescIndx (\ref numbering-indirect) input params are + * the result of MEDCouplingUMesh::buildDescendingConnectivity. + * This method lists cell by cell in \b this which are its neighbors. To compute the result only connectivities + * are considered. + * The neighbor cells of cell having id 'cellId' are neighbors[neighborsIndx[cellId]:neighborsIndx[cellId+1]]. + * + * \param [in] desc descending connectivity array. + * \param [in] descIndx descending connectivity index array used to walk through \b desc (\ref numbering-indirect). + * \param [in] revDesc reverse descending connectivity array. + * \param [in] revDescIndx reverse descending connectivity index array used to walk through \b revDesc (\ref numbering-indirect). + * \param [out] neighbors is an array storing all the neighbors of all cells in \b this. This array is newly allocated and should be dealt by the caller. \b neighborsIndx 2nd output + * parameter allows to select the right part in this array. The number of tuples is equal to the last values in \b neighborsIndx. + * \param [out] neighborsIndx is an array of size this->getNumberOfCells()+1 newly allocated and should be dealt by the caller. This arrays allow to use the first output parameter \b neighbors. + */ +void MEDCouplingUMesh::ComputeNeighborsOfCellsAdv(const DataArrayInt *desc, const DataArrayInt *descIndx, const DataArrayInt *revDesc, const DataArrayInt *revDescIndx, + DataArrayInt *&neighbors, DataArrayInt *&neighborsIndx) +{ + if(!desc || !descIndx || !revDesc || !revDescIndx) + throw INTERP_KERNEL::Exception("MEDCouplingUMesh::ComputeNeighborsOfCellsAdv some input array is empty !"); + const int *descPtr=desc->getConstPointer(); + const int *descIPtr=descIndx->getConstPointer(); + const int *revDescPtr=revDesc->getConstPointer(); + const int *revDescIPtr=revDescIndx->getConstPointer(); + // + int nbCells=descIndx->getNumberOfTuples()-1; + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> out0=DataArrayInt::New(); + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> out1=DataArrayInt::New(); out1->alloc(nbCells+1,1); + int *out1Ptr=out1->getPointer(); + *out1Ptr++=0; + out0->reserve(desc->getNumberOfTuples()); + for(int i=0;i<nbCells;i++,descIPtr++,out1Ptr++) + { + for(const int *w1=descPtr+descIPtr[0];w1!=descPtr+descIPtr[1];w1++) + { + std::set<int> s(revDescPtr+revDescIPtr[*w1],revDescPtr+revDescIPtr[(*w1)+1]); + s.erase(i); + out0->insertAtTheEnd(s.begin(),s.end()); + } + *out1Ptr=out0->getNumberOfTuples(); + } + neighbors=out0.retn(); + neighborsIndx=out1.retn(); +} + +/*! + * \b 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 calls + * MEDCouplingUMesh::buildDescendingConnectivity to compute the result. + * This method lists node by node in \b this which are its neighbors. To compute the result + * only connectivities are considered. + * The neighbor nodes of node having id 'nodeId' are neighbors[neighborsIndx[cellId]:neighborsIndx[cellId+1]]. + * + * \param [out] neighbors is an array storing all the neighbors of all nodes in \b this. This array + * is newly allocated and should be dealt by the caller. \b neighborsIndx 2nd output + * parameter allows to select the right part in this array (\ref numbering-indirect). + * The number of tuples is equal to the last values in \b neighborsIndx. + * \param [out] neighborsIdx is an array of size this->getNumberOfCells()+1 newly allocated and should + * be dealt by the caller. This arrays allow to use the first output parameter \b neighbors. + */ +void MEDCouplingUMesh::computeNeighborsOfNodes(DataArrayInt *&neighbors, DataArrayInt *&neighborsIdx) const +{ + checkFullyDefined(); + int mdim(getMeshDimension()),nbNodes(getNumberOfNodes()); + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> desc(DataArrayInt::New()),descIndx(DataArrayInt::New()),revDesc(DataArrayInt::New()),revDescIndx(DataArrayInt::New()); + MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> mesh1D; + switch(mdim) + { + case 3: + { + mesh1D=explode3DMeshTo1D(desc,descIndx,revDesc,revDescIndx); + break; + } + case 2: + { + mesh1D=buildDescendingConnectivity(desc,descIndx,revDesc,revDescIndx); + break; + } + case 1: + { + mesh1D=const_cast<MEDCouplingUMesh *>(this); + mesh1D->incrRef(); + break; + } + default: + { + throw INTERP_KERNEL::Exception("MEDCouplingUMesh::computeNeighborsOfNodes : Mesh dimension supported are [3,2,1] !"); + } + } + desc=DataArrayInt::New(); descIndx=DataArrayInt::New(); revDesc=0; revDescIndx=0; + mesh1D->getReverseNodalConnectivity(desc,descIndx); + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret0(DataArrayInt::New()); + ret0->alloc(desc->getNumberOfTuples(),1); + int *r0Pt(ret0->getPointer()); + const int *c1DPtr(mesh1D->getNodalConnectivity()->begin()),*rn(desc->begin()),*rni(descIndx->begin()); + for(int i=0;i<nbNodes;i++,rni++) + { + for(const int *oneDCellIt=rn+rni[0];oneDCellIt!=rn+rni[1];oneDCellIt++) + *r0Pt++=c1DPtr[3*(*oneDCellIt)+1]==i?c1DPtr[3*(*oneDCellIt)+2]:c1DPtr[3*(*oneDCellIt)+1]; + } + neighbors=ret0.retn(); + neighborsIdx=descIndx.retn(); +} + +/// @cond INTERNAL + +/*! + * \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<class SonsGenerator> +MEDCouplingUMesh *MEDCouplingUMesh::buildDescendingConnectivityGen(DataArrayInt *desc, DataArrayInt *descIndx, DataArrayInt *revDesc, DataArrayInt *revDescIndx, DimM1DescNbrer nbrer) const +{ + 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<DataArrayInt> 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::string name="Mesh constituent of "; name+=getName(); + MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> ret=MEDCouplingUMesh::New(name,getMeshDimension()-SonsGenerator::DELTA); + ret->setCoords(getCoords()); + ret->allocateCells(2*nbOfCells); + descIndx->alloc(nbOfCells+1,1); + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> revDesc2(DataArrayInt::New()); revDesc2->reserve(2*nbOfCells); + int *descIndxPtr=descIndx->getPointer(); *descIndxPtr++=0; + for(int eltId=0;eltId<nbOfCells;eltId++,descIndxPtr++) + { + int pos=connIndex[eltId]; + int posP1=connIndex[eltId+1]; + const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel((INTERP_KERNEL::NormalizedCellType)conn[pos]); + SonsGenerator sg(cm); + unsigned nbOfSons=sg.getNumberOfSons2(conn+pos+1,posP1-pos-1); + INTERP_KERNEL::AutoPtr<int> tmp=new int[posP1-pos]; + for(unsigned i=0;i<nbOfSons;i++) + { + INTERP_KERNEL::NormalizedCellType cmsId; + unsigned nbOfNodesSon=sg.fillSonCellNodalConnectivity2(i,conn+pos+1,posP1-pos-1,tmp,cmsId); + for(unsigned k=0;k<nbOfNodesSon;k++) + if(tmp[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<int>()); + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> 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<nbOfCellsM1;eltId++) + { + const int *strtNdlConnOfCurCell=connM1+connIndexM1[eltId]+1; + const int *endNdlConnOfCurCell=connM1+connIndexM1[eltId+1]; + for(const int *iter=strtNdlConnOfCurCell;iter!=endNdlConnOfCurCell;iter++) + if(*iter>=0)//for polyhedrons + *std::find_if(revNodalPtr+revNodalIndxPtr[*iter],revNodalPtr+revNodalIndxPtr[*iter+1],std::bind2nd(std::equal_to<int>(),-1))=eltId; + } + // + DataArrayInt *commonCells=0,*commonCellsI=0; + FindCommonCellsAlg(3,0,ret->getNodalConnectivity(),ret->getNodalConnectivityIndex(),revNodal,revNodalIndx,commonCells,commonCellsI); + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> commonCellsTmp(commonCells),commonCellsITmp(commonCellsI); + const int *commonCellsPtr(commonCells->getConstPointer()),*commonCellsIPtr(commonCellsI->getConstPointer()); + int newNbOfCellsM1=-1; + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> o2nM1=DataArrayInt::BuildOld2NewArrayFromSurjectiveFormat2(nbOfCellsM1,commonCells->begin(), + commonCellsI->begin(),commonCellsI->end(),newNbOfCellsM1); + std::vector<bool> 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<DataArrayInt> n2oM1=o2nM1->invertArrayO2N2N2OBis(newNbOfCellsM1); + const int *n2oM1Ptr=n2oM1->getConstPointer(); + MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> ret2=static_cast<MEDCouplingUMesh *>(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;i<nbOfCellsM1;i++,descPtr++) + { + if(!isImpacted[i]) + *descPtr=nbrer(o2nM1Ptr[i],0,cmsDft,false,0,0); + else + { + if(i!=n2oM1Ptr[o2nM1Ptr[i]]) + { + const INTERP_KERNEL::CellModel& cms=INTERP_KERNEL::CellModel::GetCellModel((INTERP_KERNEL::NormalizedCellType)connM1[connIndexM1[i]]); + *descPtr=nbrer(o2nM1Ptr[i],connIndexM1[i+1]-connIndexM1[i]-1,cms,true,connM1+connIndexM1[n2oM1Ptr[o2nM1Ptr[i]]]+1,connM1+connIndexM1[i]+1); + } + else + *descPtr=nbrer(o2nM1Ptr[i],0,cmsDft,false,0,0); + } + } + revDesc->reserve(newNbOfCellsM1); + revDescIndx->alloc(newNbOfCellsM1+1,1); + int *revDescIndxPtr=revDescIndx->getPointer(); *revDescIndxPtr++=0; + const int *revDesc2Ptr=revDesc2->getConstPointer(); + for(int i=0;i<newNbOfCellsM1;i++,revDescIndxPtr++) + { + int oldCellIdM1=n2oM1Ptr[i]; + if(!isImpacted[oldCellIdM1]) + { + revDesc->pushBackSilent(revDesc2Ptr[oldCellIdM1]); + revDescIndxPtr[0]=revDescIndxPtr[-1]+1; + } + else + { + for(int j=commonCellsIPtr[0];j<commonCellsIPtr[1];j++) + revDesc->pushBackSilent(revDesc2Ptr[commonCellsPtr[j]]); + revDescIndxPtr[0]=revDescIndxPtr[-1]+commonCellsIPtr[1]-commonCellsIPtr[0]; + commonCellsIPtr++; + } + } + // + return ret2.retn(); +} + +struct MEDCouplingAccVisit +{ + MEDCouplingAccVisit():_new_nb_of_nodes(0) { } + int operator()(int val) { if(val!=-1) return _new_nb_of_nodes++; else return -1; } + int _new_nb_of_nodes; +}; + +/// @endcond + +/*! + * 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. <br> 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. + * + * \if ENABLE_EXAMPLES + * \ref cpp_mcumesh_convertToPolyTypes "Here is a C++ example".<br> + * \ref py_mcumesh_convertToPolyTypes "Here is a Python example". + * \endif + */ +void MEDCouplingUMesh::convertToPolyTypes(const int *cellIdsToConvertBg, const int *cellIdsToConvertEnd) +{ + checkFullyDefined(); + int dim=getMeshDimension(); + if(dim<2 || dim>3) + throw INTERP_KERNEL::Exception("Invalid mesh dimension : must be 2 or 3 !"); + int nbOfCells(getNumberOfCells()); + if(dim==2) + { + const int *connIndex=_nodal_connec_index->getConstPointer(); + int *conn=_nodal_connec->getPointer(); + for(const int *iter=cellIdsToConvertBg;iter!=cellIdsToConvertEnd;iter++) + { + if(*iter>=0 && *iter<nbOfCells) + { + const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel((INTERP_KERNEL::NormalizedCellType)conn[connIndex[*iter]]); + if(!cm.isQuadratic()) + conn[connIndex[*iter]]=INTERP_KERNEL::NORM_POLYGON; + else + conn[connIndex[*iter]]=INTERP_KERNEL::NORM_QPOLYG; + } + else + { + std::ostringstream oss; oss << "MEDCouplingUMesh::convertToPolyTypes : On rank #" << std::distance(cellIdsToConvertBg,iter) << " value is " << *iter << " which is not"; + oss << " in range [0," << nbOfCells << ") !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + } + } + else + { + int *connIndex(_nodal_connec_index->getPointer()); + const int *connOld(_nodal_connec->getConstPointer()); + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> connNew(DataArrayInt::New()),connNewI(DataArrayInt::New()); connNew->alloc(0,1); connNewI->alloc(1,1); connNewI->setIJ(0,0,0); + std::vector<bool> toBeDone(nbOfCells,false); + for(const int *iter=cellIdsToConvertBg;iter!=cellIdsToConvertEnd;iter++) + { + if(*iter>=0 && *iter<nbOfCells) + toBeDone[*iter]=true; + else + { + std::ostringstream oss; oss << "MEDCouplingUMesh::convertToPolyTypes : On rank #" << std::distance(cellIdsToConvertBg,iter) << " value is " << *iter << " which is not"; + oss << " in range [0," << nbOfCells << ") !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + } + for(int cellId=0;cellId<nbOfCells;cellId++) + { + int pos(connIndex[cellId]),posP1(connIndex[cellId+1]); + int lgthOld(posP1-pos-1); + if(toBeDone[cellId]) + { + const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel((INTERP_KERNEL::NormalizedCellType)connOld[pos]); + unsigned nbOfFaces(cm.getNumberOfSons2(connOld+pos+1,lgthOld)); + int *tmp(new int[nbOfFaces*lgthOld+1]); + int *work=tmp; *work++=INTERP_KERNEL::NORM_POLYHED; + for(unsigned j=0;j<nbOfFaces;j++) + { + INTERP_KERNEL::NormalizedCellType type; + unsigned offset=cm.fillSonCellNodalConnectivity2(j,connOld+pos+1,lgthOld,work,type); + work+=offset; + *work++=-1; + } + std::size_t newLgth(std::distance(tmp,work)-1);//-1 for last -1 + connNew->pushBackValsSilent(tmp,tmp+newLgth); + connNewI->pushBackSilent(connNewI->back()+(int)newLgth); + delete [] tmp; + } + else + { + connNew->pushBackValsSilent(connOld+pos,connOld+posP1); + connNewI->pushBackSilent(connNewI->back()+posP1-pos); + } + } + setConnectivity(connNew,connNewI,false);//false because computeTypes called just behind. + } + computeTypes(); +} + +/*! + * Converts all cells to either polygons (if \a this is a 2D mesh) or + * polyhedrons (if \a this is a 3D mesh). + * \warning As this method is purely for user-friendliness and no optimization is + * done to avoid construction of a useless vector, this method can be costly + * in memory. + * \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. + */ +void MEDCouplingUMesh::convertAllToPoly() +{ + int nbOfCells=getNumberOfCells(); + std::vector<int> cellIds(nbOfCells); + for(int i=0;i<nbOfCells;i++) + cellIds[i]=i; + convertToPolyTypes(&cellIds[0],&cellIds[0]+cellIds.size()); +} + +/*! + * Fixes nodal connectivity of invalid cells of type NORM_POLYHED. This method + * expects that all NORM_POLYHED cells have connectivity similar to that of prismatic + * volumes like NORM_HEXA8, NORM_PENTA6 etc., i.e. the first half of nodes describes a + * base facet of the volume and the second half of nodes describes an opposite facet + * having the same number of nodes as the base one. This method converts such + * connectivity to a valid polyhedral format where connectivity of each facet is + * explicitly described and connectivity of facets are separated by -1. If \a this mesh + * contains a NORM_POLYHED cell with a valid connectivity, or an invalid connectivity is + * not as expected, an exception is thrown and the mesh remains unchanged. Care of + * a correct orientation of the first facet of a polyhedron, else orientation of a + * corrected cell is reverse.<br> + * This method is useful to build an extruded unstructured mesh with polyhedrons as + * it releases the user from boring description of polyhedra connectivity in the valid + * format. + * \throw If \a this->getMeshDimension() != 3. + * \throw If \a this->getSpaceDimension() != 3. + * \throw If the nodal connectivity of cells is not defined. + * \throw If the coordinates array is not set. + * \throw If \a this mesh contains polyhedrons with the valid connectivity. + * \throw If \a this mesh contains polyhedrons with odd number of nodes. + * + * \if ENABLE_EXAMPLES + * \ref cpp_mcumesh_arePolyhedronsNotCorrectlyOriented "Here is a C++ example".<br> + * \ref py_mcumesh_arePolyhedronsNotCorrectlyOriented "Here is a Python example". + * \endif + */ +void MEDCouplingUMesh::convertExtrudedPolyhedra() +{ + checkFullyDefined(); + if(getMeshDimension()!=3 || getSpaceDimension()!=3) + throw INTERP_KERNEL::Exception("MEDCouplingUMesh::convertExtrudedPolyhedra works on umeshes with meshdim equal to 3 and spaceDim equal to 3 too!"); + int nbOfCells=getNumberOfCells(); + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> newCi=DataArrayInt::New(); + newCi->alloc(nbOfCells+1,1); + int *newci=newCi->getPointer(); + const int *ci=_nodal_connec_index->getConstPointer(); + const int *c=_nodal_connec->getConstPointer(); + newci[0]=0; + for(int i=0;i<nbOfCells;i++) + { + INTERP_KERNEL::NormalizedCellType type=(INTERP_KERNEL::NormalizedCellType)c[ci[i]]; + if(type==INTERP_KERNEL::NORM_POLYHED) + { + if(std::count(c+ci[i]+1,c+ci[i+1],-1)!=0) + { + std::ostringstream oss; oss << "MEDCouplingUMesh::convertExtrudedPolyhedra : cell # " << i << " is a polhedron BUT it has NOT exactly 1 face !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + std::size_t n2=std::distance(c+ci[i]+1,c+ci[i+1]); + if(n2%2!=0) + { + std::ostringstream oss; oss << "MEDCouplingUMesh::convertExtrudedPolyhedra : cell # " << i << " is a polhedron with 1 face but there is a mismatch of number of nodes in face should be even !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + int n1=(int)(n2/2); + newci[i+1]=7*n1+2+newci[i];//6*n1 (nodal length) + n1+2 (number of faces) - 1 (number of '-1' separator is equal to number of faces -1) + 1 (for cell type) + } + else + newci[i+1]=(ci[i+1]-ci[i])+newci[i]; + } + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> newC=DataArrayInt::New(); + newC->alloc(newci[nbOfCells],1); + int *newc=newC->getPointer(); + for(int i=0;i<nbOfCells;i++) + { + INTERP_KERNEL::NormalizedCellType type=(INTERP_KERNEL::NormalizedCellType)c[ci[i]]; + if(type==INTERP_KERNEL::NORM_POLYHED) + { + std::size_t n1=std::distance(c+ci[i]+1,c+ci[i+1])/2; + newc=std::copy(c+ci[i],c+ci[i]+n1+1,newc); + *newc++=-1; + for(std::size_t j=0;j<n1;j++) + { + newc[j]=c[ci[i]+1+n1+(n1-j)%n1]; + newc[n1+5*j]=-1; + newc[n1+5*j+1]=c[ci[i]+1+j]; + newc[n1+5*j+2]=c[ci[i]+1+j+n1]; + newc[n1+5*j+3]=c[ci[i]+1+(j+1)%n1+n1]; + newc[n1+5*j+4]=c[ci[i]+1+(j+1)%n1]; + } + newc+=n1*6; + } + else + newc=std::copy(c+ci[i],c+ci[i+1],newc); + } + _nodal_connec_index->decrRef(); _nodal_connec_index=newCi.retn(); + _nodal_connec->decrRef(); _nodal_connec=newC.retn(); +} + + +/*! + * Converts all polygons (if \a this is a 2D mesh) or polyhedrons (if \a this is a 3D + * mesh) to cells of classical types. This method is opposite to convertToPolyTypes(). + * \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(). + * \return \c true if at least one cell has been converted, \c false else. In the + * last case the nodal connectivity remains unchanged. + * \throw If the coordinates array is not set. + * \throw If the nodal connectivity of cells is not defined. + * \throw If \a this->getMeshDimension() < 0. + */ +bool MEDCouplingUMesh::unPolyze() +{ + checkFullyDefined(); + int mdim=getMeshDimension(); + if(mdim<0) + throw INTERP_KERNEL::Exception("MEDCouplingUMesh::unPolyze works on umeshes with meshdim equals to 0, 1 2 or 3 !"); + if(mdim<=1) + return false; + int nbOfCells=getNumberOfCells(); + if(nbOfCells<1) + return false; + int initMeshLgth=getMeshLength(); + int *conn=_nodal_connec->getPointer(); + int *index=_nodal_connec_index->getPointer(); + int posOfCurCell=0; + int newPos=0; + int lgthOfCurCell; + bool ret=false; + for(int i=0;i<nbOfCells;i++) + { + lgthOfCurCell=index[i+1]-posOfCurCell; + INTERP_KERNEL::NormalizedCellType type=(INTERP_KERNEL::NormalizedCellType)conn[posOfCurCell]; + const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(type); + INTERP_KERNEL::NormalizedCellType newType=INTERP_KERNEL::NORM_ERROR; + int newLgth; + if(cm.isDynamic()) + { + switch(cm.getDimension()) + { + case 2: + { + INTERP_KERNEL::AutoPtr<int> tmp=new int[lgthOfCurCell-1]; + std::copy(conn+posOfCurCell+1,conn+posOfCurCell+lgthOfCurCell,(int *)tmp); + newType=INTERP_KERNEL::CellSimplify::tryToUnPoly2D(cm.isQuadratic(),tmp,lgthOfCurCell-1,conn+newPos+1,newLgth); + break; + } + case 3: + { + int nbOfFaces,lgthOfPolyhConn; + INTERP_KERNEL::AutoPtr<int> zipFullReprOfPolyh=INTERP_KERNEL::CellSimplify::getFullPolyh3DCell(type,conn+posOfCurCell+1,lgthOfCurCell-1,nbOfFaces,lgthOfPolyhConn); + newType=INTERP_KERNEL::CellSimplify::tryToUnPoly3D(zipFullReprOfPolyh,nbOfFaces,lgthOfPolyhConn,conn+newPos+1,newLgth); + break; + } + case 1: + { + newType=(lgthOfCurCell==3)?INTERP_KERNEL::NORM_SEG2:INTERP_KERNEL::NORM_POLYL; + break; + } + } + ret=ret || (newType!=type); + conn[newPos]=newType; + newPos+=newLgth+1; + posOfCurCell=index[i+1]; + index[i+1]=newPos; + } + else + { + std::copy(conn+posOfCurCell,conn+posOfCurCell+lgthOfCurCell,conn+newPos); + newPos+=lgthOfCurCell; + posOfCurCell+=lgthOfCurCell; + index[i+1]=newPos; + } + } + if(newPos!=initMeshLgth) + _nodal_connec->reAlloc(newPos); + if(ret) + computeTypes(); + return ret; +} + +/*! + * This method expects that spaceDimension is equal to 3 and meshDimension equal to 3. + * This method performs operation only on polyhedrons in \b this. If no polyhedrons exists in \b this, \b this remains unchanged. + * This method allows to merge if any coplanar 3DSurf cells that may appear in some polyhedrons cells. + * + * \param [in] eps is a relative precision that allows to establish if some 3D plane are coplanar or not. This epsilon is used to recenter around origin to have maximal + * precision. + */ +void MEDCouplingUMesh::simplifyPolyhedra(double eps) +{ + checkFullyDefined(); + if(getMeshDimension()!=3 || getSpaceDimension()!=3) + throw INTERP_KERNEL::Exception("MEDCouplingUMesh::simplifyPolyhedra : works on meshdimension 3 and spaceDimension 3 !"); + MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> coords=getCoords()->deepCpy(); + coords->recenterForMaxPrecision(eps); + // + int nbOfCells=getNumberOfCells(); + const int *conn=_nodal_connec->getConstPointer(); + const int *index=_nodal_connec_index->getConstPointer(); + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> connINew=DataArrayInt::New(); + connINew->alloc(nbOfCells+1,1); + int *connINewPtr=connINew->getPointer(); *connINewPtr++=0; + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> connNew=DataArrayInt::New(); connNew->alloc(0,1); + bool changed=false; + for(int i=0;i<nbOfCells;i++,connINewPtr++) + { + if(conn[index[i]]==(int)INTERP_KERNEL::NORM_POLYHED) + { + SimplifyPolyhedronCell(eps,coords,conn+index[i],conn+index[i+1],connNew); + changed=true; + } + else + connNew->insertAtTheEnd(conn+index[i],conn+index[i+1]); + *connINewPtr=connNew->getNumberOfTuples(); + } + if(changed) + setConnectivity(connNew,connINew,false); +} + +/*! + * This method returns all node ids used in the connectivity of \b this. The data array returned has to be dealt by the caller. + * The returned node ids are sorted ascendingly. This method is close to MEDCouplingUMesh::getNodeIdsInUse except + * the format of the returned DataArrayInt instance. + * + * \return a newly allocated DataArrayInt sorted ascendingly of fetched node ids. + * \sa MEDCouplingUMesh::getNodeIdsInUse, areAllNodesFetched + */ +DataArrayInt *MEDCouplingUMesh::computeFetchedNodeIds() const +{ + checkConnectivityFullyDefined(); + int nbOfCells=getNumberOfCells(); + const int *connIndex=_nodal_connec_index->getConstPointer(); + const int *conn=_nodal_connec->getConstPointer(); + const int *maxEltPt=std::max_element(_nodal_connec->begin(),_nodal_connec->end()); + int maxElt=maxEltPt==_nodal_connec->end()?0:std::abs(*maxEltPt)+1; + std::vector<bool> retS(maxElt,false); + for(int i=0;i<nbOfCells;i++) + for(int j=connIndex[i]+1;j<connIndex[i+1];j++) + if(conn[j]>=0) + retS[conn[j]]=true; + int sz=0; + for(int i=0;i<maxElt;i++) + if(retS[i]) + sz++; + DataArrayInt *ret=DataArrayInt::New(); + ret->alloc(sz,1); + int *retPtr=ret->getPointer(); + for(int i=0;i<maxElt;i++) + if(retS[i]) + *retPtr++=i; + return ret; +} + +/*! + * \param [in,out] nodeIdsInUse an array of size typically equal to nbOfNodes. + * \sa MEDCouplingUMesh::getNodeIdsInUse, areAllNodesFetched + */ +void MEDCouplingUMesh::computeNodeIdsAlg(std::vector<bool>& nodeIdsInUse) const +{ + int nbOfNodes((int)nodeIdsInUse.size()),nbOfCells(getNumberOfCells()); + const int *connIndex(_nodal_connec_index->getConstPointer()),*conn(_nodal_connec->getConstPointer()); + for(int i=0;i<nbOfCells;i++) + for(int j=connIndex[i]+1;j<connIndex[i+1];j++) + if(conn[j]>=0) + { + if(conn[j]<nbOfNodes) + nodeIdsInUse[conn[j]]=true; + else + { + std::ostringstream oss; oss << "MEDCouplingUMesh::computeNodeIdsAlg : In cell #" << i << " presence of node id " << conn[j] << " not in [0," << nbOfNodes << ") !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + } +} + +/*! + * Finds nodes not used in any cell and returns an array giving a new id to every node + * by excluding the unused nodes, for which the array holds -1. The result array is + * a mapping in "Old to New" mode. + * \param [out] nbrOfNodesInUse - number of node ids present in the nodal connectivity. + * \return DataArrayInt * - a new instance of DataArrayInt. Its length is \a + * this->getNumberOfNodes(). It holds for each node of \a this mesh either -1 + * if the node is unused or a new id else. The caller is to delete this + * array using decrRef() as it is no more needed. + * \throw If the coordinates array is not set. + * \throw If the nodal connectivity of cells is not defined. + * \throw If the nodal connectivity includes an invalid id. + * + * \if ENABLE_EXAMPLES + * \ref cpp_mcumesh_getNodeIdsInUse "Here is a C++ example".<br> + * \ref py_mcumesh_getNodeIdsInUse "Here is a Python example". + * \endif + * \sa computeFetchedNodeIds, computeNodeIdsAlg() + */ +DataArrayInt *MEDCouplingUMesh::getNodeIdsInUse(int& nbrOfNodesInUse) const +{ + nbrOfNodesInUse=-1; + int nbOfNodes(getNumberOfNodes()); + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New(); + ret->alloc(nbOfNodes,1); + int *traducer=ret->getPointer(); + std::fill(traducer,traducer+nbOfNodes,-1); + int nbOfCells=getNumberOfCells(); + const int *connIndex=_nodal_connec_index->getConstPointer(); + const int *conn=_nodal_connec->getConstPointer(); + for(int i=0;i<nbOfCells;i++) + for(int j=connIndex[i]+1;j<connIndex[i+1];j++) + if(conn[j]>=0) + { + if(conn[j]<nbOfNodes) + traducer[conn[j]]=1; + else + { + std::ostringstream oss; oss << "MEDCouplingUMesh::getNodeIdsInUse : In cell #" << i << " presence of node id " << conn[j] << " not in [0," << nbOfNodes << ") !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + } + nbrOfNodesInUse=(int)std::count(traducer,traducer+nbOfNodes,1); + std::transform(traducer,traducer+nbOfNodes,traducer,MEDCouplingAccVisit()); + return ret.retn(); +} + +/*! + * This method returns a newly allocated array containing this->getNumberOfCells() tuples and 1 component. + * For each cell in \b this the number of nodes constituting cell is computed. + * For each polyhedron cell, the sum of the number of nodes of each face constituting polyhedron cell is returned. + * So for pohyhedrons some nodes can be counted several times in the returned result. + * + * \return a newly allocated array + * \sa MEDCouplingUMesh::computeEffectiveNbOfNodesPerCell + */ +DataArrayInt *MEDCouplingUMesh::computeNbOfNodesPerCell() const +{ + checkConnectivityFullyDefined(); + int nbOfCells=getNumberOfCells(); + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New(); + ret->alloc(nbOfCells,1); + int *retPtr=ret->getPointer(); + const int *conn=getNodalConnectivity()->getConstPointer(); + const int *connI=getNodalConnectivityIndex()->getConstPointer(); + for(int i=0;i<nbOfCells;i++,retPtr++) + { + if(conn[connI[i]]!=(int)INTERP_KERNEL::NORM_POLYHED) + *retPtr=connI[i+1]-connI[i]-1; + else + *retPtr=connI[i+1]-connI[i]-1-std::count(conn+connI[i]+1,conn+connI[i+1],-1); + } + return ret.retn(); +} + +/*! + * This method computes effective number of nodes per cell. That is to say nodes appearing several times in nodal connectivity of a cell, + * will be counted only once here whereas it will be counted several times in MEDCouplingUMesh::computeNbOfNodesPerCell method. + * + * \return DataArrayInt * - new object to be deallocated by the caller. + * \sa MEDCouplingUMesh::computeNbOfNodesPerCell + */ +DataArrayInt *MEDCouplingUMesh::computeEffectiveNbOfNodesPerCell() const +{ + checkConnectivityFullyDefined(); + int nbOfCells=getNumberOfCells(); + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New(); + ret->alloc(nbOfCells,1); + int *retPtr=ret->getPointer(); + const int *conn=getNodalConnectivity()->getConstPointer(); + const int *connI=getNodalConnectivityIndex()->getConstPointer(); + for(int i=0;i<nbOfCells;i++,retPtr++) + { + std::set<int> s(conn+connI[i]+1,conn+connI[i+1]); + if(conn[connI[i]]!=(int)INTERP_KERNEL::NORM_POLYHED) + *retPtr=(int)s.size(); + else + { + s.erase(-1); + *retPtr=(int)s.size(); + } + } + return ret.retn(); +} + +/*! + * This method returns a newly allocated array containing this->getNumberOfCells() tuples and 1 component. + * For each cell in \b this the number of faces constituting (entity of dimension this->getMeshDimension()-1) cell is computed. + * + * \return a newly allocated array + */ +DataArrayInt *MEDCouplingUMesh::computeNbOfFacesPerCell() const +{ + checkConnectivityFullyDefined(); + int nbOfCells=getNumberOfCells(); + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New(); + ret->alloc(nbOfCells,1); + int *retPtr=ret->getPointer(); + const int *conn=getNodalConnectivity()->getConstPointer(); + const int *connI=getNodalConnectivityIndex()->getConstPointer(); + for(int i=0;i<nbOfCells;i++,retPtr++,connI++) + { + const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel((INTERP_KERNEL::NormalizedCellType)conn[*connI]); + *retPtr=cm.getNumberOfSons2(conn+connI[0]+1,connI[1]-connI[0]-1); + } + return ret.retn(); +} + +/*! + * Removes unused nodes (the node coordinates array is shorten) and returns an array + * mapping between new and old node ids in "Old to New" mode. -1 values in the returned + * array mean that the corresponding old node is no more used. + * \return DataArrayInt * - a new instance of DataArrayInt of length \a + * this->getNumberOfNodes() before call of this method. The caller is to + * delete this array using decrRef() as it is no more needed. + * \throw If the coordinates array is not set. + * \throw If the nodal connectivity of cells is not defined. + * \throw If the nodal connectivity includes an invalid id. + * \sa areAllNodesFetched + * + * \if ENABLE_EXAMPLES + * \ref cpp_mcumesh_zipCoordsTraducer "Here is a C++ example".<br> + * \ref py_mcumesh_zipCoordsTraducer "Here is a Python example". + * \endif + */ +DataArrayInt *MEDCouplingUMesh::zipCoordsTraducer() +{ + return MEDCouplingPointSet::zipCoordsTraducer(); +} + +/*! + * This method stands if 'cell1' and 'cell2' are equals regarding 'compType' policy. + * The semantic of 'compType' is specified in MEDCouplingPointSet::zipConnectivityTraducer method. + */ +int MEDCouplingUMesh::AreCellsEqual(const int *conn, const int *connI, int cell1, int cell2, int compType) +{ + switch(compType) + { + case 0: + return AreCellsEqual0(conn,connI,cell1,cell2); + case 1: + return AreCellsEqual1(conn,connI,cell1,cell2); + case 2: + return AreCellsEqual2(conn,connI,cell1,cell2); + case 3: + return AreCellsEqual3(conn,connI,cell1,cell2); + case 7: + return AreCellsEqual7(conn,connI,cell1,cell2); + } + throw INTERP_KERNEL::Exception("Unknown comparison asked ! Must be in 0,1,2,3 or 7."); +} + +/*! + * This method is the last step of the MEDCouplingPointSet::zipConnectivityTraducer with policy 0. + */ +int MEDCouplingUMesh::AreCellsEqual0(const int *conn, const int *connI, int cell1, int cell2) +{ + if(connI[cell1+1]-connI[cell1]==connI[cell2+1]-connI[cell2]) + return std::equal(conn+connI[cell1]+1,conn+connI[cell1+1],conn+connI[cell2]+1)?1:0; + return 0; +} + +/*! + * This method is the last step of the MEDCouplingPointSet::zipConnectivityTraducer with policy 1. + */ +int MEDCouplingUMesh::AreCellsEqual1(const int *conn, const int *connI, int cell1, int cell2) +{ + int sz=connI[cell1+1]-connI[cell1]; + if(sz==connI[cell2+1]-connI[cell2]) + { + if(conn[connI[cell1]]==conn[connI[cell2]]) + { + const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel((INTERP_KERNEL::NormalizedCellType)conn[connI[cell1]]); + unsigned dim=cm.getDimension(); + if(dim!=3) + { + if(dim!=1) + { + int sz1=2*(sz-1); + INTERP_KERNEL::AutoPtr<int> tmp=new int[sz1]; + int *work=std::copy(conn+connI[cell1]+1,conn+connI[cell1+1],(int *)tmp); + std::copy(conn+connI[cell1]+1,conn+connI[cell1+1],work); + work=std::search((int *)tmp,(int *)tmp+sz1,conn+connI[cell2]+1,conn+connI[cell2+1]); + return work!=tmp+sz1?1:0; + } + else + return std::equal(conn+connI[cell1]+1,conn+connI[cell1+1],conn+connI[cell2]+1)?1:0;//case of SEG2 and SEG3 + } + else + throw INTERP_KERNEL::Exception("MEDCouplingUMesh::AreCellsEqual1 : not implemented yet for meshdim == 3 !"); + } + } + return 0; +} + +/*! + * This method is the last step of the MEDCouplingPointSet::zipConnectivityTraducer with policy 2. + */ +int MEDCouplingUMesh::AreCellsEqual2(const int *conn, const int *connI, int cell1, int cell2) +{ + if(connI[cell1+1]-connI[cell1]==connI[cell2+1]-connI[cell2]) + { + if(conn[connI[cell1]]==conn[connI[cell2]]) + { + std::set<int> s1(conn+connI[cell1]+1,conn+connI[cell1+1]); + std::set<int> s2(conn+connI[cell2]+1,conn+connI[cell2+1]); + return s1==s2?1:0; + } + } + return 0; +} + +/*! + * This method is less restrictive than AreCellsEqual2. Here the geometric type is absolutely not taken into account ! + */ +int MEDCouplingUMesh::AreCellsEqual3(const int *conn, const int *connI, int cell1, int cell2) +{ + if(connI[cell1+1]-connI[cell1]==connI[cell2+1]-connI[cell2]) + { + std::set<int> s1(conn+connI[cell1]+1,conn+connI[cell1+1]); + std::set<int> s2(conn+connI[cell2]+1,conn+connI[cell2+1]); + return s1==s2?1:0; + } + return 0; +} + +/*! + * This method is the last step of the MEDCouplingPointSet::zipConnectivityTraducer with policy 7. + */ +int MEDCouplingUMesh::AreCellsEqual7(const int *conn, const int *connI, int cell1, int cell2) +{ + int sz=connI[cell1+1]-connI[cell1]; + if(sz==connI[cell2+1]-connI[cell2]) + { + if(conn[connI[cell1]]==conn[connI[cell2]]) + { + const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel((INTERP_KERNEL::NormalizedCellType)conn[connI[cell1]]); + unsigned dim=cm.getDimension(); + if(dim!=3) + { + if(dim!=1) + { + int sz1=2*(sz-1); + INTERP_KERNEL::AutoPtr<int> tmp=new int[sz1]; + int *work=std::copy(conn+connI[cell1]+1,conn+connI[cell1+1],(int *)tmp); + std::copy(conn+connI[cell1]+1,conn+connI[cell1+1],work); + work=std::search((int *)tmp,(int *)tmp+sz1,conn+connI[cell2]+1,conn+connI[cell2+1]); + if(work!=tmp+sz1) + return 1; + else + { + std::reverse_iterator<int *> it1((int *)tmp+sz1); + std::reverse_iterator<int *> it2((int *)tmp); + if(std::search(it1,it2,conn+connI[cell2]+1,conn+connI[cell2+1])!=it2) + return 2; + else + return 0; + } + + return work!=tmp+sz1?1:0; + } + else + {//case of SEG2 and SEG3 + if(std::equal(conn+connI[cell1]+1,conn+connI[cell1+1],conn+connI[cell2]+1)) + return 1; + if(!cm.isQuadratic()) + { + std::reverse_iterator<const int *> it1(conn+connI[cell1+1]); + std::reverse_iterator<const int *> it2(conn+connI[cell1]+1); + if(std::equal(it1,it2,conn+connI[cell2]+1)) + return 2; + return 0; + } + else + { + if(conn[connI[cell1]+1]==conn[connI[cell2]+2] && conn[connI[cell1]+2]==conn[connI[cell2]+1] && conn[connI[cell1]+3]==conn[connI[cell2]+3]) + return 2; + return 0; + } + } + } + else + throw INTERP_KERNEL::Exception("MEDCouplingUMesh::AreCellsEqual7 : not implemented yet for meshdim == 3 !"); + } + } + return 0; +} + +/*! + * This method find in candidate pool defined by 'candidates' the cells equal following the polycy 'compType'. + * If any true is returned and the results will be put at the end of 'result' output parameter. If not false is returned + * and result remains unchanged. + * The semantic of 'compType' is specified in MEDCouplingPointSet::zipConnectivityTraducer method. + * If in 'candidates' pool -1 value is considered as an empty value. + * WARNING this method returns only ONE set of result ! + */ +bool MEDCouplingUMesh::AreCellsEqualInPool(const std::vector<int>& candidates, int compType, const int *conn, const int *connI, DataArrayInt *result) +{ + if(candidates.size()<1) + return false; + bool ret=false; + std::vector<int>::const_iterator iter=candidates.begin(); + int start=(*iter++); + for(;iter!=candidates.end();iter++) + { + int status=AreCellsEqual(conn,connI,start,*iter,compType); + if(status!=0) + { + if(!ret) + { + result->pushBackSilent(start); + ret=true; + } + if(status==1) + result->pushBackSilent(*iter); + else + result->pushBackSilent(status==2?(*iter+1):-(*iter+1)); + } + } + return ret; +} + +/*! + * This method find cells that are equal (regarding \a compType) in \a this. The comparison is specified + * by \a compType. + * This method keeps the coordiantes of \a this. This method is time consuming. + * + * \param [in] compType input specifying the technique used to compare cells each other. + * - 0 : exactly. A cell is detected to be the same if and only if the connectivity is exactly the same without permutation and types same too. This is the strongest policy. + * - 1 : permutation same orientation. cell1 and cell2 are considered equal if the connectivity of cell2 can be deduced by those of cell1 by direct permutation (with exactly the same orientation) + * and their type equal. For 1D mesh the policy 1 is equivalent to 0. + * - 2 : nodal. cell1 and cell2 are equal if and only if cell1 and cell2 have same type and have the same nodes constituting connectivity. This is the laziest policy. This policy + * can be used for users not sensitive to orientation of cell + * \param [in] startCellId specifies the cellId starting from which the equality computation will be carried out. By default it is 0, which it means that all cells in \a this will be scanned. + * \param [out] commonCellsArr common cells ids (\ref numbering-indirect) + * \param [out] commonCellsIArr common cells ids (\ref numbering-indirect) + * \return the correspondance array old to new in a newly allocated array. + * + */ +void MEDCouplingUMesh::findCommonCells(int compType, int startCellId, DataArrayInt *& commonCellsArr, DataArrayInt *& commonCellsIArr) const +{ + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> revNodal=DataArrayInt::New(),revNodalI=DataArrayInt::New(); + getReverseNodalConnectivity(revNodal,revNodalI); + FindCommonCellsAlg(compType,startCellId,_nodal_connec,_nodal_connec_index,revNodal,revNodalI,commonCellsArr,commonCellsIArr); +} + +void MEDCouplingUMesh::FindCommonCellsAlg(int compType, int startCellId, const DataArrayInt *nodal, const DataArrayInt *nodalI, const DataArrayInt *revNodal, const DataArrayInt *revNodalI, + DataArrayInt *& commonCellsArr, DataArrayInt *& commonCellsIArr) +{ + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> commonCells=DataArrayInt::New(),commonCellsI=DataArrayInt::New(); commonCells->alloc(0,1); + int nbOfCells=nodalI->getNumberOfTuples()-1; + commonCellsI->reserve(1); commonCellsI->pushBackSilent(0); + const int *revNodalPtr=revNodal->getConstPointer(),*revNodalIPtr=revNodalI->getConstPointer(); + const int *connPtr=nodal->getConstPointer(),*connIPtr=nodalI->getConstPointer(); + std::vector<bool> isFetched(nbOfCells,false); + if(startCellId==0) + { + for(int i=0;i<nbOfCells;i++) + { + if(!isFetched[i]) + { + const int *connOfNode=std::find_if(connPtr+connIPtr[i]+1,connPtr+connIPtr[i+1],std::bind2nd(std::not_equal_to<int>(),-1)); + std::vector<int> v,v2; + if(connOfNode!=connPtr+connIPtr[i+1]) + { + const int *locRevNodal=std::find(revNodalPtr+revNodalIPtr[*connOfNode],revNodalPtr+revNodalIPtr[*connOfNode+1],i); + v2.insert(v2.end(),locRevNodal,revNodalPtr+revNodalIPtr[*connOfNode+1]); + connOfNode++; + } + for(;connOfNode!=connPtr+connIPtr[i+1] && v2.size()>1;connOfNode++) + if(*connOfNode>=0) + { + v=v2; + const int *locRevNodal=std::find(revNodalPtr+revNodalIPtr[*connOfNode],revNodalPtr+revNodalIPtr[*connOfNode+1],i); + std::vector<int>::iterator it=std::set_intersection(v.begin(),v.end(),locRevNodal,revNodalPtr+revNodalIPtr[*connOfNode+1],v2.begin()); + v2.resize(std::distance(v2.begin(),it)); + } + if(v2.size()>1) + { + if(AreCellsEqualInPool(v2,compType,connPtr,connIPtr,commonCells)) + { + int pos=commonCellsI->back(); + commonCellsI->pushBackSilent(commonCells->getNumberOfTuples()); + for(const int *it=commonCells->begin()+pos;it!=commonCells->end();it++) + isFetched[*it]=true; + } + } + } + } + } + else + { + for(int i=startCellId;i<nbOfCells;i++) + { + if(!isFetched[i]) + { + const int *connOfNode=std::find_if(connPtr+connIPtr[i]+1,connPtr+connIPtr[i+1],std::bind2nd(std::not_equal_to<int>(),-1)); + std::vector<int> v,v2; + if(connOfNode!=connPtr+connIPtr[i+1]) + { + v2.insert(v2.end(),revNodalPtr+revNodalIPtr[*connOfNode],revNodalPtr+revNodalIPtr[*connOfNode+1]); + connOfNode++; + } + for(;connOfNode!=connPtr+connIPtr[i+1] && v2.size()>1;connOfNode++) + if(*connOfNode>=0) + { + v=v2; + std::vector<int>::iterator it=std::set_intersection(v.begin(),v.end(),revNodalPtr+revNodalIPtr[*connOfNode],revNodalPtr+revNodalIPtr[*connOfNode+1],v2.begin()); + v2.resize(std::distance(v2.begin(),it)); + } + if(v2.size()>1) + { + if(AreCellsEqualInPool(v2,compType,connPtr,connIPtr,commonCells)) + { + int pos=commonCellsI->back(); + commonCellsI->pushBackSilent(commonCells->getNumberOfTuples()); + for(const int *it=commonCells->begin()+pos;it!=commonCells->end();it++) + isFetched[*it]=true; + } + } + } + } + } + commonCellsArr=commonCells.retn(); + commonCellsIArr=commonCellsI.retn(); +} + +/*! + * Checks if \a this mesh includes all cells of an \a other mesh, and returns an array + * giving for each cell of the \a other an id of a cell in \a this mesh. A value larger + * than \a other->getNumberOfCells() in the returned array means that there is no + * corresponding cell in \a this mesh. + * It is expected that \a this and \a other meshes share the same node coordinates + * array, if it is not so an exception is thrown. + * \param [in] other - the mesh to compare with. + * \param [in] compType - specifies a cell comparison technique. For meaning of its + * valid values [0,1,2], see zipConnectivityTraducer(). + * \param [out] arr - a new instance of DataArrayInt returning correspondence + * between cells of the two meshes. It contains \a other->getNumberOfCells() + * values. The caller is to delete this array using + * decrRef() as it is no more needed. + * \return bool - \c true if all cells of \a other mesh are present in the \a this + * mesh. + * + * \if ENABLE_EXAMPLES + * \ref cpp_mcumesh_areCellsIncludedIn "Here is a C++ example".<br> + * \ref py_mcumesh_areCellsIncludedIn "Here is a Python example". + * \endif + * \sa checkDeepEquivalOnSameNodesWith() + * \sa checkGeoEquivalWith() + */ +bool MEDCouplingUMesh::areCellsIncludedIn(const MEDCouplingUMesh *other, int compType, DataArrayInt *& arr) const +{ + MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> mesh=MergeUMeshesOnSameCoords(this,other); + int nbOfCells=getNumberOfCells(); + static const int possibleCompType[]={0,1,2}; + if(std::find(possibleCompType,possibleCompType+sizeof(possibleCompType)/sizeof(int),compType)==possibleCompType+sizeof(possibleCompType)/sizeof(int)) + { + std::ostringstream oss; oss << "MEDCouplingUMesh::areCellsIncludedIn : only following policies are possible : "; + std::copy(possibleCompType,possibleCompType+sizeof(possibleCompType)/sizeof(int),std::ostream_iterator<int>(oss," ")); + oss << " !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> o2n=mesh->zipConnectivityTraducer(compType,nbOfCells); + arr=o2n->substr(nbOfCells); + arr->setName(other->getName()); + int tmp; + if(other->getNumberOfCells()==0) + return true; + return arr->getMaxValue(tmp)<nbOfCells; +} + +/*! + * This method makes the assumption that \a this and \a other share the same coords. If not an exception will be thrown ! + * This method tries to determine if \b other is fully included in \b this. + * The main difference is that this method is not expected to throw exception. + * This method has two outputs : + * + * \param other other mesh + * \param arr is an output parameter that returns a \b newly created instance. This array is of size 'other->getNumberOfCells()'. + * \return If \a other is fully included in 'this 'true is returned. If not false is returned. + */ +bool MEDCouplingUMesh::areCellsIncludedIn2(const MEDCouplingUMesh *other, DataArrayInt *& arr) const +{ + MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> mesh=MergeUMeshesOnSameCoords(this,other); + DataArrayInt *commonCells=0,*commonCellsI=0; + int thisNbCells=getNumberOfCells(); + mesh->findCommonCells(7,thisNbCells,commonCells,commonCellsI); + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> commonCellsTmp(commonCells),commonCellsITmp(commonCellsI); + const int *commonCellsPtr=commonCells->getConstPointer(),*commonCellsIPtr=commonCellsI->getConstPointer(); + int otherNbCells=other->getNumberOfCells(); + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> arr2=DataArrayInt::New(); + arr2->alloc(otherNbCells,1); + arr2->fillWithZero(); + int *arr2Ptr=arr2->getPointer(); + int nbOfCommon=commonCellsI->getNumberOfTuples()-1; + for(int i=0;i<nbOfCommon;i++) + { + int start=commonCellsPtr[commonCellsIPtr[i]]; + if(start<thisNbCells) + { + for(int j=commonCellsIPtr[i]+1;j!=commonCellsIPtr[i+1];j++) + { + int sig=commonCellsPtr[j]>0?1:-1; + int val=std::abs(commonCellsPtr[j])-1; + if(val>=thisNbCells) + arr2Ptr[val-thisNbCells]=sig*(start+1); + } + } + } + arr2->setName(other->getName()); + if(arr2->presenceOfValue(0)) + return false; + arr=arr2.retn(); + return true; +} + +MEDCouplingPointSet *MEDCouplingUMesh::mergeMyselfWithOnSameCoords(const MEDCouplingPointSet *other) const +{ + if(!other) + throw INTERP_KERNEL::Exception("MEDCouplingUMesh::mergeMyselfWithOnSameCoords : input other is null !"); + const MEDCouplingUMesh *otherC=dynamic_cast<const MEDCouplingUMesh *>(other); + if(!otherC) + throw INTERP_KERNEL::Exception("MEDCouplingUMesh::mergeMyselfWithOnSameCoords : the input other mesh is not of type unstructured !"); + std::vector<const MEDCouplingUMesh *> ms(2); + ms[0]=this; + ms[1]=otherC; + return MergeUMeshesOnSameCoords(ms); +} + +/*! + * Build a sub part of \b this lying or not on the same coordinates than \b this (regarding value of \b keepCoords). + * By default coordinates are kept. This method is close to MEDCouplingUMesh::buildPartOfMySelf except that here input + * cellIds is not given explicitely but by a range python like. + * + * \param start + * \param end + * \param step + * \param keepCoords that specifies if you want or not to keep coords as this or zip it (see ParaMEDMEM::MEDCouplingUMesh::zipCoords). If true zipCoords is \b NOT called, if false, zipCoords is called. + * \return a newly allocated + * + * \warning This method modifies can generate an unstructured mesh whose cells are not sorted by geometric type order. + * In view of the MED file writing, a renumbering of cells of returned unstructured mesh (using MEDCouplingUMesh::sortCellsInMEDFileFrmt) should be necessary. + */ +MEDCouplingPointSet *MEDCouplingUMesh::buildPartOfMySelf2(int start, int end, int step, bool keepCoords) const +{ + if(getMeshDimension()!=-1) + return MEDCouplingPointSet::buildPartOfMySelf2(start,end,step,keepCoords); + else + { + int newNbOfCells=DataArray::GetNumberOfItemGivenBESRelative(start,end,step,"MEDCouplingUMesh::buildPartOfMySelf2 for -1 dimension mesh "); + if(newNbOfCells!=1) + throw INTERP_KERNEL::Exception("-1D mesh has only one cell !"); + if(start!=0) + throw INTERP_KERNEL::Exception("-1D mesh has only one cell : 0 !"); + incrRef(); + return const_cast<MEDCouplingUMesh *>(this); + } +} + +/*! + * Creates a new MEDCouplingUMesh containing specified cells of \a this mesh. + * The result mesh shares or not the node coordinates array with \a this mesh depending + * on \a keepCoords parameter. + * \warning Cells of the result mesh can be \b not sorted by geometric type, hence, + * to write this mesh to the MED file, its cells must be sorted using + * sortCellsInMEDFileFrmt(). + * \param [in] begin - an array of cell ids to include to the new mesh. + * \param [in] end - a pointer to last-plus-one-th element of \a begin. + * \param [in] keepCoords - if \c true, the result mesh shares the node coordinates + * array of \a this mesh, else "free" nodes are removed from the result mesh + * by calling zipCoords(). + * \return MEDCouplingPointSet * - 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 not defined. + * \throw If any cell id in the array \a begin is not valid. + * + * \if ENABLE_EXAMPLES + * \ref cpp_mcumesh_buildPartOfMySelf "Here is a C++ example".<br> + * \ref py_mcumesh_buildPartOfMySelf "Here is a Python example". + * \endif + */ +MEDCouplingPointSet *MEDCouplingUMesh::buildPartOfMySelf(const int *begin, const int *end, bool keepCoords) const +{ + if(getMeshDimension()!=-1) + return MEDCouplingPointSet::buildPartOfMySelf(begin,end,keepCoords); + else + { + if(end-begin!=1) + throw INTERP_KERNEL::Exception("-1D mesh has only one cell !"); + if(begin[0]!=0) + throw INTERP_KERNEL::Exception("-1D mesh has only one cell : 0 !"); + incrRef(); + return const_cast<MEDCouplingUMesh *>(this); + } +} + +/*! + * This method operates only on nodal connectivity on \b this. Coordinates of \b this is completely ignored here. + * + * This method allows to partially modify some cells in \b this (whose list is specified by [ \b cellIdsBg, \b cellIdsEnd ) ) with cells coming in \b otherOnSameCoordsThanThis. + * Size of [ \b cellIdsBg, \b cellIdsEnd ) ) must be equal to the number of cells of otherOnSameCoordsThanThis. + * The number of cells of \b this will remain the same with this method. + * + * \param [in] cellIdsBg begin of cell ids (included) of cells in this to assign + * \param [in] cellIdsEnd end of cell ids (excluded) of cells in this to assign + * \param [in] otherOnSameCoordsThanThis an another mesh with same meshdimension than \b this with exactly the same number of cells than cell ids list in [\b cellIdsBg, \b cellIdsEnd ). + * Coordinate pointer of \b this and those of \b otherOnSameCoordsThanThis must be the same + */ +void MEDCouplingUMesh::setPartOfMySelf(const int *cellIdsBg, const int *cellIdsEnd, const MEDCouplingUMesh& otherOnSameCoordsThanThis) +{ + checkConnectivityFullyDefined(); + otherOnSameCoordsThanThis.checkConnectivityFullyDefined(); + if(getCoords()!=otherOnSameCoordsThanThis.getCoords()) + throw INTERP_KERNEL::Exception("MEDCouplingUMesh::setPartOfMySelf : coordinates pointer are not the same ! Invoke setCoords or call tryToShareSameCoords method !"); + if(getMeshDimension()!=otherOnSameCoordsThanThis.getMeshDimension()) + { + std::ostringstream oss; oss << "MEDCouplingUMesh::setPartOfMySelf : Mismatch of meshdimensions ! this is equal to " << getMeshDimension(); + oss << ", whereas other mesh dimension is set equal to " << otherOnSameCoordsThanThis.getMeshDimension() << " !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + int nbOfCellsToModify=(int)std::distance(cellIdsBg,cellIdsEnd); + if(nbOfCellsToModify!=otherOnSameCoordsThanThis.getNumberOfCells()) + { + std::ostringstream oss; oss << "MEDCouplingUMesh::setPartOfMySelf : cells ids length (" << nbOfCellsToModify << ") do not match the number of cells of other mesh (" << otherOnSameCoordsThanThis.getNumberOfCells() << ") !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + int nbOfCells=getNumberOfCells(); + bool easyAssign=true; + const int *connI=_nodal_connec_index->getConstPointer(); + const int *connIOther=otherOnSameCoordsThanThis._nodal_connec_index->getConstPointer(); + for(const int *it=cellIdsBg;it!=cellIdsEnd && easyAssign;it++,connIOther++) + { + if(*it>=0 && *it<nbOfCells) + { + easyAssign=(connIOther[1]-connIOther[0])==(connI[*it+1]-connI[*it]); + } + else + { + std::ostringstream oss; oss << "MEDCouplingUMesh::setPartOfMySelf : On pos #" << std::distance(cellIdsBg,it) << " id is equal to " << *it << " which is not in [0," << nbOfCells << ") !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + } + if(easyAssign) + { + MEDCouplingUMesh::SetPartOfIndexedArraysSameIdx(cellIdsBg,cellIdsEnd,_nodal_connec,_nodal_connec_index,otherOnSameCoordsThanThis._nodal_connec,otherOnSameCoordsThanThis._nodal_connec_index); + computeTypes(); + } + else + { + DataArrayInt *arrOut=0,*arrIOut=0; + MEDCouplingUMesh::SetPartOfIndexedArrays(cellIdsBg,cellIdsEnd,_nodal_connec,_nodal_connec_index,otherOnSameCoordsThanThis._nodal_connec,otherOnSameCoordsThanThis._nodal_connec_index, + arrOut,arrIOut); + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> arrOutAuto(arrOut),arrIOutAuto(arrIOut); + setConnectivity(arrOut,arrIOut,true); + } +} + +void MEDCouplingUMesh::setPartOfMySelf2(int start, int end, int step, const MEDCouplingUMesh& otherOnSameCoordsThanThis) +{ + checkConnectivityFullyDefined(); + otherOnSameCoordsThanThis.checkConnectivityFullyDefined(); + if(getCoords()!=otherOnSameCoordsThanThis.getCoords()) + throw INTERP_KERNEL::Exception("MEDCouplingUMesh::setPartOfMySelf2 : coordinates pointer are not the same ! Invoke setCoords or call tryToShareSameCoords method !"); + if(getMeshDimension()!=otherOnSameCoordsThanThis.getMeshDimension()) + { + std::ostringstream oss; oss << "MEDCouplingUMesh::setPartOfMySelf2 : Mismatch of meshdimensions ! this is equal to " << getMeshDimension(); + oss << ", whereas other mesh dimension is set equal to " << otherOnSameCoordsThanThis.getMeshDimension() << " !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + int nbOfCellsToModify=DataArray::GetNumberOfItemGivenBESRelative(start,end,step,"MEDCouplingUMesh::setPartOfMySelf2 : "); + if(nbOfCellsToModify!=otherOnSameCoordsThanThis.getNumberOfCells()) + { + std::ostringstream oss; oss << "MEDCouplingUMesh::setPartOfMySelf2 : cells ids length (" << nbOfCellsToModify << ") do not match the number of cells of other mesh (" << otherOnSameCoordsThanThis.getNumberOfCells() << ") !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + int nbOfCells=getNumberOfCells(); + bool easyAssign=true; + const int *connI=_nodal_connec_index->getConstPointer(); + const int *connIOther=otherOnSameCoordsThanThis._nodal_connec_index->getConstPointer(); + int it=start; + for(int i=0;i<nbOfCellsToModify && easyAssign;i++,it+=step,connIOther++) + { + if(it>=0 && it<nbOfCells) + { + easyAssign=(connIOther[1]-connIOther[0])==(connI[it+1]-connI[it]); + } + else + { + std::ostringstream oss; oss << "MEDCouplingUMesh::setPartOfMySelf2 : On pos #" << i << " id is equal to " << it << " which is not in [0," << nbOfCells << ") !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + } + if(easyAssign) + { + MEDCouplingUMesh::SetPartOfIndexedArraysSameIdx2(start,end,step,_nodal_connec,_nodal_connec_index,otherOnSameCoordsThanThis._nodal_connec,otherOnSameCoordsThanThis._nodal_connec_index); + computeTypes(); + } + else + { + DataArrayInt *arrOut=0,*arrIOut=0; + MEDCouplingUMesh::SetPartOfIndexedArrays2(start,end,step,_nodal_connec,_nodal_connec_index,otherOnSameCoordsThanThis._nodal_connec,otherOnSameCoordsThanThis._nodal_connec_index, + arrOut,arrIOut); + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> arrOutAuto(arrOut),arrIOutAuto(arrIOut); + setConnectivity(arrOut,arrIOut,true); + } +} + +/*! + * Keeps from \a this only cells which constituing point id are in the ids specified by [ \a begin,\a end ). + * The resulting cell ids are stored at the end of the 'cellIdsKept' parameter. + * Parameter \a fullyIn specifies if a cell that has part of its nodes in ids array is kept or not. + * If \a fullyIn is true only cells whose ids are \b fully contained in [ \a begin,\a end ) tab will be kept. + * + * \param [in] begin input start of array of node ids. + * \param [in] end input end of array of node ids. + * \param [in] fullyIn input that specifies if all node ids must be in [ \a begin,\a end ) array to consider cell to be in. + * \param [in,out] cellIdsKeptArr array where all candidate cell ids are put at the end. + */ +void MEDCouplingUMesh::fillCellIdsToKeepFromNodeIds(const int *begin, const int *end, bool fullyIn, DataArrayInt *&cellIdsKeptArr) const +{ + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> cellIdsKept=DataArrayInt::New(); cellIdsKept->alloc(0,1); + checkConnectivityFullyDefined(); + int tmp=-1; + int sz=getNodalConnectivity()->getMaxValue(tmp); sz=std::max(sz,0)+1; + std::vector<bool> fastFinder(sz,false); + for(const int *work=begin;work!=end;work++) + if(*work>=0 && *work<sz) + fastFinder[*work]=true; + int nbOfCells=getNumberOfCells(); + const int *conn=getNodalConnectivity()->getConstPointer(); + const int *connIndex=getNodalConnectivityIndex()->getConstPointer(); + for(int i=0;i<nbOfCells;i++) + { + int ref=0,nbOfHit=0; + for(const int *work2=conn+connIndex[i]+1;work2!=conn+connIndex[i+1];work2++) + if(*work2>=0) + { + ref++; + if(fastFinder[*work2]) + nbOfHit++; + } + if((ref==nbOfHit && fullyIn) || (nbOfHit!=0 && !fullyIn)) + cellIdsKept->pushBackSilent(i); + } + cellIdsKeptArr=cellIdsKept.retn(); +} + +/*! + * Creates a new MEDCouplingUMesh containing cells, of dimension one less than \a + * this->getMeshDimension(), that bound some cells of \a this mesh. + * The cells of lower dimension to include to the result mesh are selected basing on + * specified node ids and the value of \a fullyIn parameter. If \a fullyIn ==\c true, a + * cell is copied if its all nodes are in the array \a begin of node ids. If \a fullyIn + * ==\c false, a cell is copied if any its node is in the array of node ids. The + * created mesh shares the node coordinates array with \a this mesh. + * \param [in] begin - the array of node ids. + * \param [in] end - a pointer to the (last+1)-th element of \a begin. + * \param [in] fullyIn - if \c true, then cells whose all nodes are in the + * array \a begin are added, else cells whose any node is in the + * array \a begin are added. + * \return MEDCouplingPointSet * - 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 not defined. + * \throw If any node id in \a begin is not valid. + * + * \if ENABLE_EXAMPLES + * \ref cpp_mcumesh_buildFacePartOfMySelfNode "Here is a C++ example".<br> + * \ref py_mcumesh_buildFacePartOfMySelfNode "Here is a Python example". + * \endif + */ +MEDCouplingPointSet *MEDCouplingUMesh::buildFacePartOfMySelfNode(const int *begin, const int *end, bool fullyIn) const +{ + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> desc,descIndx,revDesc,revDescIndx; + desc=DataArrayInt::New(); descIndx=DataArrayInt::New(); revDesc=DataArrayInt::New(); revDescIndx=DataArrayInt::New(); + MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> subMesh=buildDescendingConnectivity(desc,descIndx,revDesc,revDescIndx); + desc=0; descIndx=0; revDesc=0; revDescIndx=0; + return subMesh->buildPartOfMySelfNode(begin,end,fullyIn); +} + +/*! + * Creates a new MEDCouplingUMesh containing cells, of dimension one less than \a + * this->getMeshDimension(), which bound only one cell of \a this mesh. + * \param [in] keepCoords - if \c true, the result mesh shares the node coordinates + * array of \a this mesh, else "free" nodes are removed from the result mesh + * by calling zipCoords(). + * \return MEDCouplingPointSet * - 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 not defined. + * + * \if ENABLE_EXAMPLES + * \ref cpp_mcumesh_buildBoundaryMesh "Here is a C++ example".<br> + * \ref py_mcumesh_buildBoundaryMesh "Here is a Python example". + * \endif + */ +MEDCouplingPointSet *MEDCouplingUMesh::buildBoundaryMesh(bool keepCoords) const +{ + DataArrayInt *desc=DataArrayInt::New(); + DataArrayInt *descIndx=DataArrayInt::New(); + DataArrayInt *revDesc=DataArrayInt::New(); + DataArrayInt *revDescIndx=DataArrayInt::New(); + // + MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> meshDM1=buildDescendingConnectivity(desc,descIndx,revDesc,revDescIndx); + revDesc->decrRef(); + desc->decrRef(); + descIndx->decrRef(); + int nbOfCells=meshDM1->getNumberOfCells(); + const int *revDescIndxC=revDescIndx->getConstPointer(); + std::vector<int> boundaryCells; + for(int i=0;i<nbOfCells;i++) + if(revDescIndxC[i+1]-revDescIndxC[i]==1) + boundaryCells.push_back(i); + revDescIndx->decrRef(); + MEDCouplingPointSet *ret=meshDM1->buildPartOfMySelf(&boundaryCells[0],&boundaryCells[0]+boundaryCells.size(),keepCoords); + return ret; +} + +/*! + * This method returns a newly created DataArrayInt instance containing ids of cells located in boundary. + * A cell is detected to be on boundary if it contains one or more than one face having only one father. + * This method makes the assumption that \a this is fully defined (coords,connectivity). If not an exception will be thrown. + */ +DataArrayInt *MEDCouplingUMesh::findCellIdsOnBoundary() const +{ + checkFullyDefined(); + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> desc=DataArrayInt::New(); + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> descIndx=DataArrayInt::New(); + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> revDesc=DataArrayInt::New(); + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> revDescIndx=DataArrayInt::New(); + // + buildDescendingConnectivity(desc,descIndx,revDesc,revDescIndx)->decrRef(); + desc=(DataArrayInt*)0; descIndx=(DataArrayInt*)0; + // + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> tmp=revDescIndx->deltaShiftIndex(); + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> faceIds=tmp->getIdsEqual(1); tmp=(DataArrayInt*)0; + const int *revDescPtr=revDesc->getConstPointer(); + const int *revDescIndxPtr=revDescIndx->getConstPointer(); + int nbOfCells=getNumberOfCells(); + std::vector<bool> ret1(nbOfCells,false); + int sz=0; + for(const int *pt=faceIds->begin();pt!=faceIds->end();pt++) + if(!ret1[revDescPtr[revDescIndxPtr[*pt]]]) + { ret1[revDescPtr[revDescIndxPtr[*pt]]]=true; sz++; } + // + DataArrayInt *ret2=DataArrayInt::New(); + ret2->alloc(sz,1); + int *ret2Ptr=ret2->getPointer(); + sz=0; + for(std::vector<bool>::const_iterator it=ret1.begin();it!=ret1.end();it++,sz++) + if(*it) + *ret2Ptr++=sz; + ret2->setName("BoundaryCells"); + return ret2; +} + +/*! + * This method finds in \b this the cell ids that lie on mesh \b otherDimM1OnSameCoords. + * \b this and \b otherDimM1OnSameCoords have to lie on the same coordinate array pointer. The coherency of that coords array with connectivity + * of \b this and \b otherDimM1OnSameCoords is not important here because this method works only on connectivity. + * this->getMeshDimension() - 1 must be equal to otherDimM1OnSameCoords.getMeshDimension() + * + * s0 is the cell ids set in \b this lying on at least one node in the fetched nodes in \b otherDimM1OnSameCoords. + * This method also returns the cells ids set s1 which contains the cell ids in \b this for which one of the dim-1 constituent + * equals a cell in \b otherDimM1OnSameCoords. + * + * \throw if \b otherDimM1OnSameCoords is not part of constituent of \b this, or if coordinate pointer of \b this and \b otherDimM1OnSameCoords + * are not same, or if this->getMeshDimension()-1!=otherDimM1OnSameCoords.getMeshDimension() + * + * \param [in] otherDimM1OnSameCoords + * \param [out] cellIdsRk0 a newly allocated array containing the cell ids of s0 (which are cell ids of \b this) in the above algorithm. + * \param [out] cellIdsRk1 a newly allocated array containing the cell ids of s1 \b indexed into the \b cellIdsRk0 subset. To get the absolute ids of s1, simply invoke + * cellIdsRk1->transformWithIndArr(cellIdsRk0->begin(),cellIdsRk0->end()); + */ +void MEDCouplingUMesh::findCellIdsLyingOn(const MEDCouplingUMesh& otherDimM1OnSameCoords, DataArrayInt *&cellIdsRk0, DataArrayInt *&cellIdsRk1) const +{ + if(getCoords()!=otherDimM1OnSameCoords.getCoords()) + throw INTERP_KERNEL::Exception("MEDCouplingUMesh::findCellIdsLyingOn : coordinates pointer are not the same ! Use tryToShareSameCoords method !"); + checkConnectivityFullyDefined(); + otherDimM1OnSameCoords.checkConnectivityFullyDefined(); + if(getMeshDimension()-1!=otherDimM1OnSameCoords.getMeshDimension()) + throw INTERP_KERNEL::Exception("MEDCouplingUMesh::findCellIdsLyingOn : invalid mesh dimension of input mesh regarding meshdimesion of this !"); + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> fetchedNodeIds1=otherDimM1OnSameCoords.computeFetchedNodeIds(); + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> s0arr=getCellIdsLyingOnNodes(fetchedNodeIds1->begin(),fetchedNodeIds1->end(),false); + MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> thisPart=static_cast<MEDCouplingUMesh *>(buildPartOfMySelf(s0arr->begin(),s0arr->end(),true)); + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> descThisPart=DataArrayInt::New(),descIThisPart=DataArrayInt::New(),revDescThisPart=DataArrayInt::New(),revDescIThisPart=DataArrayInt::New(); + MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> thisPartConsti=thisPart->buildDescendingConnectivity(descThisPart,descIThisPart,revDescThisPart,revDescIThisPart); + const int *revDescThisPartPtr=revDescThisPart->getConstPointer(),*revDescIThisPartPtr=revDescIThisPart->getConstPointer(); + DataArrayInt *idsOtherInConsti=0; + bool b=thisPartConsti->areCellsIncludedIn(&otherDimM1OnSameCoords,2,idsOtherInConsti); + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> idsOtherInConstiAuto(idsOtherInConsti); + if(!b) + throw INTERP_KERNEL::Exception("MEDCouplingUMesh::findCellIdsLyingOn : the given mdim-1 mesh in other is not a constituent of this !"); + std::set<int> s1; + for(const int *idOther=idsOtherInConsti->begin();idOther!=idsOtherInConsti->end();idOther++) + s1.insert(revDescThisPartPtr+revDescIThisPartPtr[*idOther],revDescThisPartPtr+revDescIThisPartPtr[*idOther+1]); + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> s1arr_renum1=DataArrayInt::New(); s1arr_renum1->alloc((int)s1.size(),1); std::copy(s1.begin(),s1.end(),s1arr_renum1->getPointer()); + s1arr_renum1->sort(); + cellIdsRk0=s0arr.retn(); + //cellIdsRk1=s_renum1.retn(); + cellIdsRk1=s1arr_renum1.retn(); +} + +/*! + * This method computes the skin of \b this. That is to say the consituting meshdim-1 mesh is built and only the boundary subpart is + * returned. This subpart of meshdim-1 mesh is built using meshdim-1 cells in it shared only one cell in \b this. + * + * \return a newly allocated mesh lying on the same coordinates than \b this. The caller has to deal with returned mesh. + */ +MEDCouplingUMesh *MEDCouplingUMesh::computeSkin() const +{ + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> desc=DataArrayInt::New(); + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> descIndx=DataArrayInt::New(); + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> revDesc=DataArrayInt::New(); + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> revDescIndx=DataArrayInt::New(); + // + MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> meshDM1=buildDescendingConnectivity(desc,descIndx,revDesc,revDescIndx); + revDesc=0; desc=0; descIndx=0; + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> revDescIndx2=revDescIndx->deltaShiftIndex(); + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> part=revDescIndx2->getIdsEqual(1); + return static_cast<MEDCouplingUMesh *>(meshDM1->buildPartOfMySelf(part->begin(),part->end(),true)); +} + +/*! + * Finds nodes lying on the boundary of \a this mesh. + * \return DataArrayInt * - a new instance of DataArrayInt holding ids of found + * nodes. The caller is to delete this array 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. + * + * \if ENABLE_EXAMPLES + * \ref cpp_mcumesh_findBoundaryNodes "Here is a C++ example".<br> + * \ref py_mcumesh_findBoundaryNodes "Here is a Python example". + * \endif + */ +DataArrayInt *MEDCouplingUMesh::findBoundaryNodes() const +{ + MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> skin=computeSkin(); + return skin->computeFetchedNodeIds(); +} + +MEDCouplingUMesh *MEDCouplingUMesh::buildUnstructured() const +{ + incrRef(); + return const_cast<MEDCouplingUMesh *>(this); +} + +/*! + * This method expects that \b this and \b otherDimM1OnSameCoords share the same coordinates array. + * otherDimM1OnSameCoords->getMeshDimension() is expected to be equal to this->getMeshDimension()-1. + * This method searches for nodes needed to be duplicated. These nodes are nodes fetched by \b otherDimM1OnSameCoords which are not part of the boundary of \b otherDimM1OnSameCoords. + * If a node is in the boundary of \b this \b and in the boundary of \b otherDimM1OnSameCoords this node is considerd as needed to be duplicated. + * When the set of node ids \b nodeIdsToDuplicate is computed, cell ids in \b this is searched so that their connectivity includes at least 1 node in \b nodeIdsToDuplicate. + * + * \param [in] otherDimM1OnSameCoords a mesh lying on the same coords than \b this and with a mesh dimension equal to those of \b this minus 1. WARNING this input + * parameter is altered during the call. + * \param [out] nodeIdsToDuplicate node ids needed to be duplicated following the algorithm explain above. + * \param [out] cellIdsNeededToBeRenum cell ids in \b this in which the renumber of nodes should be performed. + * \param [out] cellIdsNotModified cell ids int \b this that lies on \b otherDimM1OnSameCoords mesh whose connectivity do \b not need to be modified as it is the case for \b cellIdsNeededToBeRenum. + * + * \warning This method modifies param \b otherDimM1OnSameCoords (for speed reasons). + */ +void MEDCouplingUMesh::findNodesToDuplicate(const MEDCouplingUMesh& otherDimM1OnSameCoords, DataArrayInt *& nodeIdsToDuplicate, + DataArrayInt *& cellIdsNeededToBeRenum, DataArrayInt *& cellIdsNotModified) const +{ + typedef MEDCouplingAutoRefCountObjectPtr<DataArrayInt> DAInt; + + checkFullyDefined(); + otherDimM1OnSameCoords.checkFullyDefined(); + if(getCoords()!=otherDimM1OnSameCoords.getCoords()) + throw INTERP_KERNEL::Exception("MEDCouplingUMesh::findNodesToDuplicate : meshes do not share the same coords array !"); + if(otherDimM1OnSameCoords.getMeshDimension()!=getMeshDimension()-1) + throw INTERP_KERNEL::Exception("MEDCouplingUMesh::findNodesToDuplicate : the mesh given in other parameter must have this->getMeshDimension()-1 !"); + DataArrayInt *cellIdsRk0=0,*cellIdsRk1=0; + findCellIdsLyingOn(otherDimM1OnSameCoords,cellIdsRk0,cellIdsRk1); + DAInt cellIdsRk0Auto(cellIdsRk0),cellIdsRk1Auto(cellIdsRk1); + DAInt s0=cellIdsRk1->buildComplement(cellIdsRk0->getNumberOfTuples()); + s0->transformWithIndArr(cellIdsRk0Auto->begin(),cellIdsRk0Auto->end()); + MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m0Part=static_cast<MEDCouplingUMesh *>(buildPartOfMySelf(s0->begin(),s0->end(),true)); + DAInt s1=m0Part->computeFetchedNodeIds(); + DAInt s2=otherDimM1OnSameCoords.computeFetchedNodeIds(); + DAInt s3=s2->buildSubstraction(s1); + cellIdsRk1->transformWithIndArr(cellIdsRk0Auto->begin(),cellIdsRk0Auto->end()); + // + MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m0Part2=static_cast<MEDCouplingUMesh *>(buildPartOfMySelf(cellIdsRk1->begin(),cellIdsRk1->end(),true)); + int nCells2 = m0Part2->getNumberOfCells(); + DAInt desc00=DataArrayInt::New(),descI00=DataArrayInt::New(),revDesc00=DataArrayInt::New(),revDescI00=DataArrayInt::New(); + MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m01=m0Part2->buildDescendingConnectivity(desc00,descI00,revDesc00,revDescI00); + // Neighbor information of the mesh without considering the crack (serves to count how many connex pieces it is made of) + DataArrayInt *tmp00=0,*tmp11=0; + MEDCouplingUMesh::ComputeNeighborsOfCellsAdv(desc00,descI00,revDesc00,revDescI00, tmp00, tmp11); + DAInt neighInit00(tmp00); + DAInt neighIInit00(tmp11); + // Neighbor information of the mesh WITH the crack (some neighbors are removed): + DataArrayInt *idsTmp=0; + bool b=m01->areCellsIncludedIn(&otherDimM1OnSameCoords,2,idsTmp); + DAInt ids(idsTmp); + if(!b) + throw INTERP_KERNEL::Exception("MEDCouplingUMesh::findNodesToDuplicate : the given mdim-1 mesh in other is not a constituent of this !"); + // In the neighbor information remove the connection between high dimension cells and its low level constituents which are part + // of the frontier given in parameter (i.e. the cells of low dimension from the group delimiting the crack): + MEDCouplingUMesh::RemoveIdsFromIndexedArrays(ids->begin(),ids->end(),desc00,descI00); + DataArrayInt *tmp0=0,*tmp1=0; + // Compute the neighbor of each cell in m0Part2, taking into account the broken link above. Two + // cells on either side of the crack (defined by the mesh of low dimension) are not neighbor anymore. + ComputeNeighborsOfCellsAdv(desc00,descI00,revDesc00,revDescI00,tmp0,tmp1); + DAInt neigh00(tmp0); + DAInt neighI00(tmp1); + + // For each initial connex part of the sub-mesh (or said differently for each independent crack): + int seed = 0, nIter = 0; + int nIterMax = nCells2+1; // Safety net for the loop + DAInt hitCells = DataArrayInt::New(); hitCells->alloc(nCells2); + hitCells->fillWithValue(-1); + DAInt cellsToModifyConn0_torenum = DataArrayInt::New(); + cellsToModifyConn0_torenum->alloc(0,1); + while (nIter < nIterMax) + { + DAInt t = hitCells->getIdsEqual(-1); + if (!t->getNumberOfTuples()) + break; + // Connex zone without the crack (to compute the next seed really) + int dnu; + DAInt connexCheck = MEDCouplingUMesh::ComputeSpreadZoneGraduallyFromSeed(&seed, &seed+1, neighInit00,neighIInit00, -1, dnu); + int cnt = 0; + for (int * ptr = connexCheck->getPointer(); cnt < connexCheck->getNumberOfTuples(); ptr++, cnt++) + hitCells->setIJ(*ptr,0,1); + // Connex zone WITH the crack (to identify cells lying on either part of the crack) + DAInt spreadZone = MEDCouplingUMesh::ComputeSpreadZoneGraduallyFromSeed(&seed, &seed+1, neigh00,neighI00, -1, dnu); + cellsToModifyConn0_torenum = DataArrayInt::Aggregate(cellsToModifyConn0_torenum, spreadZone, 0); + // Compute next seed, i.e. a cell in another connex part, which was not covered by the previous iterations + DAInt comple = cellsToModifyConn0_torenum->buildComplement(nCells2); + DAInt nonHitCells = hitCells->getIdsEqual(-1); + DAInt intersec = nonHitCells->buildIntersection(comple); + if (intersec->getNumberOfTuples()) + { seed = intersec->getIJ(0,0); } + else + { break; } + nIter++; + } + if (nIter >= nIterMax) + throw INTERP_KERNEL::Exception("MEDCouplingUMesh::findNodesToDuplicate(): internal error - too many iterations."); + + DAInt cellsToModifyConn1_torenum=cellsToModifyConn0_torenum->buildComplement(neighI00->getNumberOfTuples()-1); + cellsToModifyConn0_torenum->transformWithIndArr(cellIdsRk1->begin(),cellIdsRk1->end()); + cellsToModifyConn1_torenum->transformWithIndArr(cellIdsRk1->begin(),cellIdsRk1->end()); + // + cellIdsNeededToBeRenum=cellsToModifyConn0_torenum.retn(); + cellIdsNotModified=cellsToModifyConn1_torenum.retn(); + nodeIdsToDuplicate=s3.retn(); +} + +/*! + * This method operates a modification of the connectivity and coords in \b this. + * Every time that a node id in [ \b nodeIdsToDuplicateBg, \b nodeIdsToDuplicateEnd ) will append in nodal connectivity of \b this + * its ids will be modified to id this->getNumberOfNodes()+std::distance(nodeIdsToDuplicateBg,std::find(nodeIdsToDuplicateBg,nodeIdsToDuplicateEnd,id)). + * More explicitely the renumber array in nodes is not explicitely given in old2new to avoid to build a big array of renumbering whereas typically few node ids needs to be + * renumbered. The node id nodeIdsToDuplicateBg[0] will have id this->getNumberOfNodes()+0, node id nodeIdsToDuplicateBg[1] will have id this->getNumberOfNodes()+1, + * node id nodeIdsToDuplicateBg[2] will have id this->getNumberOfNodes()+2... + * + * As a consequence nodal connectivity array length will remain unchanged by this method, and nodal connectivity index array will remain unchanged by this method. + * + * \param [in] nodeIdsToDuplicateBg begin of node ids (included) to be duplicated in connectivity only + * \param [in] nodeIdsToDuplicateEnd end of node ids (excluded) to be duplicated in connectivity only + */ +void MEDCouplingUMesh::duplicateNodes(const int *nodeIdsToDuplicateBg, const int *nodeIdsToDuplicateEnd) +{ + int nbOfNodes=getNumberOfNodes(); + duplicateNodesInCoords(nodeIdsToDuplicateBg,nodeIdsToDuplicateEnd); + duplicateNodesInConn(nodeIdsToDuplicateBg,nodeIdsToDuplicateEnd,nbOfNodes); +} + +/*! + * This method renumbers only nodal connectivity in \a this. The renumbering is only an offset applied. So this method is a specialization of + * \a renumberNodesInConn. \b WARNING, this method does not check that the resulting node ids in the nodal connectivity is in a valid range ! + * + * \param [in] offset - specifies the offset to be applied on each element of connectivity. + * + * \sa renumberNodesInConn + */ +void MEDCouplingUMesh::renumberNodesWithOffsetInConn(int offset) +{ + checkConnectivityFullyDefined(); + int *conn(getNodalConnectivity()->getPointer()); + const int *connIndex(getNodalConnectivityIndex()->getConstPointer()); + int nbOfCells(getNumberOfCells()); + for(int i=0;i<nbOfCells;i++) + for(int iconn=connIndex[i]+1;iconn!=connIndex[i+1];iconn++) + { + int& node=conn[iconn]; + if(node>=0)//avoid polyhedron separator + { + node+=offset; + } + } + _nodal_connec->declareAsNew(); + updateTime(); +} + +/*! + * Same than renumberNodesInConn(const int *) except that here the format of old-to-new traducer is using map instead + * of array. This method is dedicated for renumbering from a big set of nodes the a tiny set of nodes which is the case during extraction + * of a big mesh. + */ +void MEDCouplingUMesh::renumberNodesInConn(const INTERP_KERNEL::HashMap<int,int>& newNodeNumbersO2N) +{ + checkConnectivityFullyDefined(); + int *conn(getNodalConnectivity()->getPointer()); + const int *connIndex(getNodalConnectivityIndex()->getConstPointer()); + int nbOfCells(getNumberOfCells()); + for(int i=0;i<nbOfCells;i++) + for(int iconn=connIndex[i]+1;iconn!=connIndex[i+1];iconn++) + { + int& node=conn[iconn]; + if(node>=0)//avoid polyhedron separator + { + INTERP_KERNEL::HashMap<int,int>::const_iterator it(newNodeNumbersO2N.find(node)); + if(it!=newNodeNumbersO2N.end()) + { + node=(*it).second; + } + else + { + std::ostringstream oss; oss << "MEDCouplingUMesh::renumberNodesInConn(map) : presence in connectivity for cell #" << i << " of node #" << node << " : Not in map !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + } + } + _nodal_connec->declareAsNew(); + updateTime(); +} + +/*! + * Changes ids of nodes within the nodal connectivity arrays according to a permutation + * array in "Old to New" mode. The node coordinates array is \b not changed by this method. + * This method is a generalization of shiftNodeNumbersInConn(). + * \warning This method performs no check of validity of new ids. **Use it with care !** + * \param [in] newNodeNumbersO2N - a permutation array, of length \a + * this->getNumberOfNodes(), in "Old to New" mode. + * See \ref numbering for more info on renumbering modes. + * \throw If the nodal connectivity of cells is not defined. + * + * \if ENABLE_EXAMPLES + * \ref cpp_mcumesh_renumberNodesInConn "Here is a C++ example".<br> + * \ref py_mcumesh_renumberNodesInConn "Here is a Python example". + * \endif + */ +void MEDCouplingUMesh::renumberNodesInConn(const int *newNodeNumbersO2N) +{ + checkConnectivityFullyDefined(); + int *conn=getNodalConnectivity()->getPointer(); + const int *connIndex=getNodalConnectivityIndex()->getConstPointer(); + int nbOfCells(getNumberOfCells()); + for(int i=0;i<nbOfCells;i++) + for(int iconn=connIndex[i]+1;iconn!=connIndex[i+1];iconn++) + { + int& node=conn[iconn]; + if(node>=0)//avoid polyhedron separator + { + node=newNodeNumbersO2N[node]; + } + } + _nodal_connec->declareAsNew(); + updateTime(); +} + +/*! + * This method renumbers nodes \b in \b connectivity \b only \b without \b any \b reference \b to \b coords. + * This method performs no check on the fact that new coordinate ids are valid. \b Use \b it \b with \b care ! + * This method is an specialization of \ref ParaMEDMEM::MEDCouplingUMesh::renumberNodesInConn "renumberNodesInConn method". + * + * \param [in] delta specifies the shift size applied to nodeId in nodal connectivity in \b this. + */ +void MEDCouplingUMesh::shiftNodeNumbersInConn(int delta) +{ + checkConnectivityFullyDefined(); + int *conn=getNodalConnectivity()->getPointer(); + const int *connIndex=getNodalConnectivityIndex()->getConstPointer(); + int nbOfCells=getNumberOfCells(); + for(int i=0;i<nbOfCells;i++) + for(int iconn=connIndex[i]+1;iconn!=connIndex[i+1];iconn++) + { + int& node=conn[iconn]; + if(node>=0)//avoid polyhedron separator + { + node+=delta; + } + } + _nodal_connec->declareAsNew(); + updateTime(); +} + +/*! + * This method operates a modification of the connectivity in \b this. + * Coordinates are \b NOT considered here and will remain unchanged by this method. this->_coords can ever been null for the needs of this method. + * Every time that a node id in [ \b nodeIdsToDuplicateBg, \b nodeIdsToDuplicateEnd ) will append in nodal connectivity of \b this + * its ids will be modified to id offset+std::distance(nodeIdsToDuplicateBg,std::find(nodeIdsToDuplicateBg,nodeIdsToDuplicateEnd,id)). + * More explicitely the renumber array in nodes is not explicitely given in old2new to avoid to build a big array of renumbering whereas typically few node ids needs to be + * renumbered. The node id nodeIdsToDuplicateBg[0] will have id offset+0, node id nodeIdsToDuplicateBg[1] will have id offset+1, + * node id nodeIdsToDuplicateBg[2] will have id offset+2... + * + * As a consequence nodal connectivity array length will remain unchanged by this method, and nodal connectivity index array will remain unchanged by this method. + * As an another consequense after the call of this method \b this can be transiently non cohrent. + * + * \param [in] nodeIdsToDuplicateBg begin of node ids (included) to be duplicated in connectivity only + * \param [in] nodeIdsToDuplicateEnd end of node ids (excluded) to be duplicated in connectivity only + * \param [in] offset the offset applied to all node ids in connectivity that are in [ \a nodeIdsToDuplicateBg, \a nodeIdsToDuplicateEnd ). + */ +void MEDCouplingUMesh::duplicateNodesInConn(const int *nodeIdsToDuplicateBg, const int *nodeIdsToDuplicateEnd, int offset) +{ + checkConnectivityFullyDefined(); + std::map<int,int> m; + int val=offset; + for(const int *work=nodeIdsToDuplicateBg;work!=nodeIdsToDuplicateEnd;work++,val++) + m[*work]=val; + int *conn=getNodalConnectivity()->getPointer(); + const int *connIndex=getNodalConnectivityIndex()->getConstPointer(); + int nbOfCells=getNumberOfCells(); + for(int i=0;i<nbOfCells;i++) + for(int iconn=connIndex[i]+1;iconn!=connIndex[i+1];iconn++) + { + int& node=conn[iconn]; + if(node>=0)//avoid polyhedron separator + { + std::map<int,int>::iterator it=m.find(node); + if(it!=m.end()) + node=(*it).second; + } + } + updateTime(); +} + +/*! + * This method renumbers cells of \a this using the array specified by [old2NewBg;old2NewBg+getNumberOfCells()) + * + * Contrary to MEDCouplingPointSet::renumberNodes, this method makes a permutation without any fuse of cell. + * After the call of this method the number of cells remains the same as before. + * + * If 'check' equals true the method will check that any elements in [ \a old2NewBg; \a old2NewEnd ) is unique ; if not + * an INTERP_KERNEL::Exception will be thrown. When 'check' equals true [ \a old2NewBg ; \a old2NewEnd ) is not expected to + * be strictly in [0;this->getNumberOfCells()). + * + * If 'check' equals false the method will not check the content of [ \a old2NewBg ; \a old2NewEnd ). + * To avoid any throw of SIGSEGV when 'check' equals false, the elements in [ \a old2NewBg ; \a old2NewEnd ) should be unique and + * should be contained in[0;this->getNumberOfCells()). + * + * \param [in] old2NewBg is expected to be a dynamically allocated pointer of size at least equal to this->getNumberOfCells() + * \param check + */ +void MEDCouplingUMesh::renumberCells(const int *old2NewBg, bool check) +{ + checkConnectivityFullyDefined(); + int nbCells=getNumberOfCells(); + const int *array=old2NewBg; + if(check) + array=DataArrayInt::CheckAndPreparePermutation(old2NewBg,old2NewBg+nbCells); + // + const int *conn=_nodal_connec->getConstPointer(); + const int *connI=_nodal_connec_index->getConstPointer(); + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> o2n=DataArrayInt::New(); o2n->useArray(array,false,C_DEALLOC,nbCells,1); + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> n2o=o2n->invertArrayO2N2N2O(nbCells); + const int *n2oPtr=n2o->begin(); + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> newConn=DataArrayInt::New(); + newConn->alloc(_nodal_connec->getNumberOfTuples(),_nodal_connec->getNumberOfComponents()); + newConn->copyStringInfoFrom(*_nodal_connec); + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> newConnI=DataArrayInt::New(); + newConnI->alloc(_nodal_connec_index->getNumberOfTuples(),_nodal_connec_index->getNumberOfComponents()); + newConnI->copyStringInfoFrom(*_nodal_connec_index); + // + int *newC=newConn->getPointer(); + int *newCI=newConnI->getPointer(); + int loc=0; + newCI[0]=loc; + for(int i=0;i<nbCells;i++) + { + int pos=n2oPtr[i]; + int nbOfElts=connI[pos+1]-connI[pos]; + newC=std::copy(conn+connI[pos],conn+connI[pos+1],newC); + loc+=nbOfElts; + newCI[i+1]=loc; + } + // + setConnectivity(newConn,newConnI); + if(check) + free(const_cast<int *>(array)); +} + +/*! + * Finds cells whose bounding boxes intersect a given bounding box. + * \param [in] bbox - an array defining the bounding box via coordinates of its + * extremum points in "no interlace" mode, i.e. xMin, xMax, yMin, yMax, zMin, + * zMax (if in 3D). + * \param [in] eps - a factor used to increase size of the bounding box of cell + * before comparing it with \a bbox. This factor is multiplied by the maximal + * extent of the bounding box of cell to produce an addition to this bounding box. + * \return DataArrayInt * - a new instance of DataArrayInt holding ids for found + * cells. The caller is to delete this array using decrRef() as it is no more + * needed. + * \throw If the coordinates array is not set. + * \throw If the nodal connectivity of cells is not defined. + * + * \if ENABLE_EXAMPLES + * \ref cpp_mcumesh_getCellsInBoundingBox "Here is a C++ example".<br> + * \ref py_mcumesh_getCellsInBoundingBox "Here is a Python example". + * \endif + */ +DataArrayInt *MEDCouplingUMesh::getCellsInBoundingBox(const double *bbox, double eps) const +{ + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> elems=DataArrayInt::New(); elems->alloc(0,1); + if(getMeshDimension()==-1) + { + elems->pushBackSilent(0); + return elems.retn(); + } + int dim=getSpaceDimension(); + INTERP_KERNEL::AutoPtr<double> elem_bb=new double[2*dim]; + const int* conn = getNodalConnectivity()->getConstPointer(); + const int* conn_index= getNodalConnectivityIndex()->getConstPointer(); + const double* coords = getCoords()->getConstPointer(); + int nbOfCells=getNumberOfCells(); + for ( int ielem=0; ielem<nbOfCells;ielem++ ) + { + for (int i=0; i<dim; i++) + { + elem_bb[i*2]=std::numeric_limits<double>::max(); + elem_bb[i*2+1]=-std::numeric_limits<double>::max(); + } + + for (int inode=conn_index[ielem]+1; inode<conn_index[ielem+1]; inode++)//+1 due to offset of cell type. + { + int node= conn[inode]; + if(node>=0)//avoid polyhedron separator + { + for (int idim=0; idim<dim; idim++) + { + if ( coords[node*dim+idim] < elem_bb[idim*2] ) + { + elem_bb[idim*2] = coords[node*dim+idim] ; + } + if ( coords[node*dim+idim] > elem_bb[idim*2+1] ) + { + elem_bb[idim*2+1] = coords[node*dim+idim] ; + } + } + } + } + if (intersectsBoundingBox(elem_bb, bbox, dim, eps)) + elems->pushBackSilent(ielem); + } + return elems.retn(); +} + +/*! + * Given a boundary box 'bbox' returns elements 'elems' contained in this 'bbox' or touching 'bbox' (within 'eps' distance). + * Warning 'elems' is incremented during the call so if elems is not empty before call returned elements will be + * added in 'elems' parameter. + */ +DataArrayInt *MEDCouplingUMesh::getCellsInBoundingBox(const INTERP_KERNEL::DirectedBoundingBox& bbox, double eps) +{ + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> elems=DataArrayInt::New(); elems->alloc(0,1); + if(getMeshDimension()==-1) + { + elems->pushBackSilent(0); + return elems.retn(); + } + int dim=getSpaceDimension(); + INTERP_KERNEL::AutoPtr<double> elem_bb=new double[2*dim]; + const int* conn = getNodalConnectivity()->getConstPointer(); + const int* conn_index= getNodalConnectivityIndex()->getConstPointer(); + const double* coords = getCoords()->getConstPointer(); + int nbOfCells=getNumberOfCells(); + for ( int ielem=0; ielem<nbOfCells;ielem++ ) + { + for (int i=0; i<dim; i++) + { + elem_bb[i*2]=std::numeric_limits<double>::max(); + elem_bb[i*2+1]=-std::numeric_limits<double>::max(); + } + + for (int inode=conn_index[ielem]+1; inode<conn_index[ielem+1]; inode++)//+1 due to offset of cell type. + { + int node= conn[inode]; + if(node>=0)//avoid polyhedron separator + { + for (int idim=0; idim<dim; idim++) + { + if ( coords[node*dim+idim] < elem_bb[idim*2] ) + { + elem_bb[idim*2] = coords[node*dim+idim] ; + } + if ( coords[node*dim+idim] > elem_bb[idim*2+1] ) + { + elem_bb[idim*2+1] = coords[node*dim+idim] ; + } + } + } + } + if(intersectsBoundingBox(bbox, elem_bb, dim, eps)) + elems->pushBackSilent(ielem); + } + return elems.retn(); +} + +/*! + * Returns a type of a cell by its id. + * \param [in] cellId - the id of the cell of interest. + * \return INTERP_KERNEL::NormalizedCellType - enumeration item describing the cell type. + * \throw If \a cellId is invalid. Valid range is [0, \a this->getNumberOfCells() ). + */ +INTERP_KERNEL::NormalizedCellType MEDCouplingUMesh::getTypeOfCell(int cellId) const +{ + const int *ptI=_nodal_connec_index->getConstPointer(); + const int *pt=_nodal_connec->getConstPointer(); + if(cellId>=0 && cellId<(int)_nodal_connec_index->getNbOfElems()-1) + return (INTERP_KERNEL::NormalizedCellType) pt[ptI[cellId]]; + else + { + std::ostringstream oss; oss << "MEDCouplingUMesh::getTypeOfCell : Requesting type of cell #" << cellId << " but it should be in [0," << _nodal_connec_index->getNbOfElems()-1 << ") !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } +} + +/*! + * This method returns a newly allocated array containing cell ids (ascendingly sorted) whose geometric type are equal to type. + * This method does not throw exception if geometric type \a type is not in \a this. + * This method throws an INTERP_KERNEL::Exception if meshdimension of \b this is not equal to those of \b type. + * The coordinates array is not considered here. + * + * \param [in] type the geometric type + * \return cell ids in this having geometric type \a type. + */ +DataArrayInt *MEDCouplingUMesh::giveCellsWithType(INTERP_KERNEL::NormalizedCellType type) const +{ + + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New(); + ret->alloc(0,1); + checkConnectivityFullyDefined(); + int nbCells=getNumberOfCells(); + int mdim=getMeshDimension(); + const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(type); + if(mdim!=(int)cm.getDimension()) + throw INTERP_KERNEL::Exception("MEDCouplingUMesh::giveCellsWithType : Mismatch between mesh dimension and dimension of the cell !"); + const int *ptI=_nodal_connec_index->getConstPointer(); + const int *pt=_nodal_connec->getConstPointer(); + for(int i=0;i<nbCells;i++) + { + if((INTERP_KERNEL::NormalizedCellType)pt[ptI[i]]==type) + ret->pushBackSilent(i); + } + return ret.retn(); +} + +/*! + * Returns nb of cells having the geometric type \a type. No throw if no cells in \a this has the geometric type \a type. + */ +int MEDCouplingUMesh::getNumberOfCellsWithType(INTERP_KERNEL::NormalizedCellType type) const +{ + const int *ptI=_nodal_connec_index->getConstPointer(); + const int *pt=_nodal_connec->getConstPointer(); + int nbOfCells=getNumberOfCells(); + int ret=0; + for(int i=0;i<nbOfCells;i++) + if((INTERP_KERNEL::NormalizedCellType) pt[ptI[i]]==type) + ret++; + return ret; +} + +/*! + * Returns the nodal connectivity of a given cell. + * The separator of faces within polyhedron connectivity (-1) is not returned, thus + * all returned node ids can be used in getCoordinatesOfNode(). + * \param [in] cellId - an id of the cell of interest. + * \param [in,out] conn - a vector where the node ids are appended. It is not + * cleared before the appending. + * \throw If \a cellId is invalid. Valid range is [0, \a this->getNumberOfCells() ). + */ +void MEDCouplingUMesh::getNodeIdsOfCell(int cellId, std::vector<int>& conn) const +{ + const int *ptI=_nodal_connec_index->getConstPointer(); + const int *pt=_nodal_connec->getConstPointer(); + for(const int *w=pt+ptI[cellId]+1;w!=pt+ptI[cellId+1];w++) + if(*w>=0) + conn.push_back(*w); +} + +std::string MEDCouplingUMesh::simpleRepr() const +{ + static const char msg0[]="No coordinates specified !"; + std::ostringstream ret; + ret << "Unstructured 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"; + if(_mesh_dim>=-1) + { ret << "Mesh dimension : " << _mesh_dim << "\nSpace dimension : "; } + else + { ret << " Mesh dimension has not been set or is invalid !"; } + if(_coords!=0) + { + const int spaceDim=getSpaceDimension(); + ret << spaceDim << "\nInfo attached on space dimension : "; + for(int i=0;i<spaceDim;i++) + ret << "\"" << _coords->getInfoOnComponent(i) << "\" "; + ret << "\n"; + } + else + ret << msg0 << "\n"; + ret << "Number of nodes : "; + if(_coords!=0) + ret << getNumberOfNodes() << "\n"; + else + ret << msg0 << "\n"; + ret << "Number of cells : "; + if(_nodal_connec!=0 && _nodal_connec_index!=0) + ret << getNumberOfCells() << "\n"; + else + ret << "No connectivity specified !" << "\n"; + ret << "Cell types present : "; + for(std::set<INTERP_KERNEL::NormalizedCellType>::const_iterator iter=_types.begin();iter!=_types.end();iter++) + { + const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(*iter); + ret << cm.getRepr() << " "; + } + ret << "\n"; + return ret.str(); +} + +std::string MEDCouplingUMesh::advancedRepr() const +{ + std::ostringstream ret; + ret << simpleRepr(); + ret << "\nCoordinates array : \n___________________\n\n"; + if(_coords) + _coords->reprWithoutNameStream(ret); + else + ret << "No array set !\n"; + ret << "\n\nConnectivity arrays : \n_____________________\n\n"; + reprConnectivityOfThisLL(ret); + return ret.str(); +} + +/*! + * This method returns a C++ code that is a dump of \a this. + * This method will throw if this is not fully defined. + */ +std::string MEDCouplingUMesh::cppRepr() const +{ + static const char coordsName[]="coords"; + static const char connName[]="conn"; + static const char connIName[]="connI"; + checkFullyDefined(); + std::ostringstream ret; ret << "// coordinates" << std::endl; + _coords->reprCppStream(coordsName,ret); ret << std::endl << "// connectivity" << std::endl; + _nodal_connec->reprCppStream(connName,ret); ret << std::endl; + _nodal_connec_index->reprCppStream(connIName,ret); ret << std::endl; + ret << "MEDCouplingUMesh *mesh=MEDCouplingUMesh::New(\"" << getName() << "\"," << getMeshDimension() << ");" << std::endl; + ret << "mesh->setCoords(" << coordsName << ");" << std::endl; + ret << "mesh->setConnectivity(" << connName << "," << connIName << ",true);" << std::endl; + ret << coordsName << "->decrRef(); " << connName << "->decrRef(); " << connIName << "->decrRef();" << std::endl; + return ret.str(); +} + +std::string MEDCouplingUMesh::reprConnectivityOfThis() const +{ + std::ostringstream ret; + reprConnectivityOfThisLL(ret); + return ret.str(); +} + +/*! + * This method builds a newly allocated instance (with the same name than \a this) that the caller has the responsability to deal with. + * This method returns an instance with all arrays allocated (connectivity, connectivity index, coordinates) + * but with length of these arrays set to 0. It allows to define an "empty" mesh (with nor cells nor nodes but compliant with + * some algos). + * + * This method expects that \a this has a mesh dimension set and higher or equal to 0. If not an exception will be thrown. + * This method analyzes the 3 arrays of \a this. For each the following behaviour is done : if the array is null a newly one is created + * with number of tuples set to 0, if not the array is taken as this in the returned instance. + */ +MEDCouplingUMesh *MEDCouplingUMesh::buildSetInstanceFromThis(int spaceDim) const +{ + int mdim=getMeshDimension(); + if(mdim<0) + throw INTERP_KERNEL::Exception("MEDCouplingUMesh::buildSetInstanceFromThis : invalid mesh dimension ! Should be >= 0 !"); + MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> ret=MEDCouplingUMesh::New(getName(),mdim); + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> tmp1,tmp2; + bool needToCpyCT=true; + if(!_nodal_connec) + { + tmp1=DataArrayInt::New(); tmp1->alloc(0,1); + needToCpyCT=false; + } + else + { + tmp1=_nodal_connec; + tmp1->incrRef(); + } + if(!_nodal_connec_index) + { + tmp2=DataArrayInt::New(); tmp2->alloc(1,1); tmp2->setIJ(0,0,0); + needToCpyCT=false; + } + else + { + tmp2=_nodal_connec_index; + tmp2->incrRef(); + } + ret->setConnectivity(tmp1,tmp2,false); + if(needToCpyCT) + ret->_types=_types; + if(!_coords) + { + MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> coords=DataArrayDouble::New(); coords->alloc(0,spaceDim); + ret->setCoords(coords); + } + else + ret->setCoords(_coords); + return ret.retn(); +} + +void MEDCouplingUMesh::reprConnectivityOfThisLL(std::ostringstream& stream) const +{ + if(_nodal_connec!=0 && _nodal_connec_index!=0) + { + int nbOfCells=getNumberOfCells(); + const int *c=_nodal_connec->getConstPointer(); + const int *ci=_nodal_connec_index->getConstPointer(); + for(int i=0;i<nbOfCells;i++) + { + const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel((INTERP_KERNEL::NormalizedCellType)c[ci[i]]); + stream << "Cell #" << i << " " << cm.getRepr() << " : "; + std::copy(c+ci[i]+1,c+ci[i+1],std::ostream_iterator<int>(stream," ")); + stream << "\n"; + } + } + else + stream << "Connectivity not defined !\n"; +} + +int MEDCouplingUMesh::getNumberOfNodesInCell(int cellId) const +{ + const int *ptI=_nodal_connec_index->getConstPointer(); + const int *pt=_nodal_connec->getConstPointer(); + if(pt[ptI[cellId]]!=INTERP_KERNEL::NORM_POLYHED) + return ptI[cellId+1]-ptI[cellId]-1; + else + return (int)std::count_if(pt+ptI[cellId]+1,pt+ptI[cellId+1],std::bind2nd(std::not_equal_to<int>(),-1)); +} + +/*! + * Returns types of cells of the specified part of \a this mesh. + * This method avoids computing sub-mesh explicitely to get its types. + * \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. + * \return std::set<INTERP_KERNEL::NormalizedCellType> - a set of enumeration items + * describing the cell types. + * \throw If the coordinates array is not set. + * \throw If the nodal connectivity of cells is not defined. + * \sa getAllGeoTypes() + */ +std::set<INTERP_KERNEL::NormalizedCellType> MEDCouplingUMesh::getTypesOfPart(const int *begin, const int *end) const +{ + checkFullyDefined(); + std::set<INTERP_KERNEL::NormalizedCellType> ret; + const int *conn=_nodal_connec->getConstPointer(); + const int *connIndex=_nodal_connec_index->getConstPointer(); + for(const int *w=begin;w!=end;w++) + ret.insert((INTERP_KERNEL::NormalizedCellType)conn[connIndex[*w]]); + return ret; +} + +/*! + * Defines the nodal connectivity using given connectivity arrays in \ref numbering-indirect format. + * Optionally updates + * a set of types of cells constituting \a this mesh. + * This method is for advanced users having prepared their connectivity before. For + * more info on using this method see \ref MEDCouplingUMeshAdvBuild. + * \param [in] conn - the nodal connectivity array. + * \param [in] connIndex - the nodal connectivity index array. + * \param [in] isComputingTypes - if \c true, the set of types constituting \a this + * mesh is updated. + */ +void MEDCouplingUMesh::setConnectivity(DataArrayInt *conn, DataArrayInt *connIndex, bool isComputingTypes) +{ + DataArrayInt::SetArrayIn(conn,_nodal_connec); + DataArrayInt::SetArrayIn(connIndex,_nodal_connec_index); + if(isComputingTypes) + computeTypes(); + declareAsNew(); +} + +/*! + * Copy constructor. If 'deepCpy' is false \a this is a shallow copy of other. + * If 'deeCpy' is true all arrays (coordinates and connectivities) are deeply copied. + */ +MEDCouplingUMesh::MEDCouplingUMesh(const MEDCouplingUMesh& other, bool deepCopy):MEDCouplingPointSet(other,deepCopy),_mesh_dim(other._mesh_dim), + _nodal_connec(0),_nodal_connec_index(0), + _types(other._types) +{ + if(other._nodal_connec) + _nodal_connec=other._nodal_connec->performCpy(deepCopy); + if(other._nodal_connec_index) + _nodal_connec_index=other._nodal_connec_index->performCpy(deepCopy); +} + +MEDCouplingUMesh::~MEDCouplingUMesh() +{ + if(_nodal_connec) + _nodal_connec->decrRef(); + if(_nodal_connec_index) + _nodal_connec_index->decrRef(); +} + +/*! + * Recomputes a set of cell types of \a this mesh. For more info see + * \ref MEDCouplingUMeshNodalConnectivity. + */ +void MEDCouplingUMesh::computeTypes() +{ + ComputeAllTypesInternal(_types,_nodal_connec,_nodal_connec_index); +} + +/*! + * This method checks that all arrays are set. If yes nothing done if no an exception is thrown. + */ +void MEDCouplingUMesh::checkFullyDefined() const +{ + if(!_nodal_connec_index || !_nodal_connec || !_coords) + throw INTERP_KERNEL::Exception("Reverse nodal connectivity computation requires full connectivity and coordinates set in unstructured mesh."); +} + +/*! + * This method checks that all connectivity arrays are set. If yes nothing done if no an exception is thrown. + */ +void MEDCouplingUMesh::checkConnectivityFullyDefined() const +{ + if(!_nodal_connec_index || !_nodal_connec) + throw INTERP_KERNEL::Exception("Reverse nodal connectivity computation requires full connectivity set in unstructured mesh."); +} + +/*! + * Returns a number of cells constituting \a this mesh. + * \return int - the number of cells in \a this mesh. + * \throw If the nodal connectivity of cells is not defined. + */ +int MEDCouplingUMesh::getNumberOfCells() const +{ + if(_nodal_connec_index) + return _nodal_connec_index->getNumberOfTuples()-1; + else + if(_mesh_dim==-1) + return 1; + else + throw INTERP_KERNEL::Exception("Unable to get number of cells because no connectivity specified !"); +} + +/*! + * Returns a dimension of \a this mesh, i.e. a dimension of cells constituting \a this + * mesh. For more info see \ref meshes. + * \return int - the dimension of \a this mesh. + * \throw If the mesh dimension is not defined using setMeshDimension(). + */ +int MEDCouplingUMesh::getMeshDimension() const +{ + if(_mesh_dim<-1) + throw INTERP_KERNEL::Exception("No mesh dimension specified !"); + return _mesh_dim; +} + +/*! + * Returns a length of the nodal connectivity array. + * This method is for test reason. Normally the integer returned is not useable by + * user. For more info see \ref MEDCouplingUMeshNodalConnectivity. + * \return int - the length of the nodal connectivity array. + */ +int MEDCouplingUMesh::getMeshLength() const +{ + return _nodal_connec->getNbOfElems(); +} + +/*! + * First step of serialization process. Used by ParaMEDMEM and MEDCouplingCorba to transfert data between process. + */ +void MEDCouplingUMesh::getTinySerializationInformation(std::vector<double>& tinyInfoD, std::vector<int>& tinyInfo, std::vector<std::string>& littleStrings) const +{ + MEDCouplingPointSet::getTinySerializationInformation(tinyInfoD,tinyInfo,littleStrings); + tinyInfo.push_back(getMeshDimension()); + tinyInfo.push_back(getNumberOfCells()); + if(_nodal_connec) + tinyInfo.push_back(getMeshLength()); + else + tinyInfo.push_back(-1); +} + +/*! + * First step of unserialization process. + */ +bool MEDCouplingUMesh::isEmptyMesh(const std::vector<int>& tinyInfo) const +{ + return tinyInfo[6]<=0; +} + +/*! + * Second step of serialization process. + * \param tinyInfo must be equal to the result given by getTinySerializationInformation method. + * \param a1 + * \param a2 + * \param littleStrings + */ +void MEDCouplingUMesh::resizeForUnserialization(const std::vector<int>& tinyInfo, DataArrayInt *a1, DataArrayDouble *a2, std::vector<std::string>& littleStrings) const +{ + MEDCouplingPointSet::resizeForUnserialization(tinyInfo,a1,a2,littleStrings); + if(tinyInfo[5]!=-1) + a1->alloc(tinyInfo[7]+tinyInfo[6]+1,1); +} + +/*! + * Third and final step of serialization process. + */ +void MEDCouplingUMesh::serialize(DataArrayInt *&a1, DataArrayDouble *&a2) const +{ + MEDCouplingPointSet::serialize(a1,a2); + if(getMeshDimension()>-1) + { + a1=DataArrayInt::New(); + a1->alloc(getMeshLength()+getNumberOfCells()+1,1); + int *ptA1=a1->getPointer(); + const int *conn=getNodalConnectivity()->getConstPointer(); + const int *index=getNodalConnectivityIndex()->getConstPointer(); + ptA1=std::copy(index,index+getNumberOfCells()+1,ptA1); + std::copy(conn,conn+getMeshLength(),ptA1); + } + else + a1=0; +} + +/*! + * Second and final unserialization process. + * \param tinyInfo must be equal to the result given by getTinySerializationInformation method. + */ +void MEDCouplingUMesh::unserialization(const std::vector<double>& tinyInfoD, const std::vector<int>& tinyInfo, const DataArrayInt *a1, DataArrayDouble *a2, const std::vector<std::string>& littleStrings) +{ + MEDCouplingPointSet::unserialization(tinyInfoD,tinyInfo,a1,a2,littleStrings); + setMeshDimension(tinyInfo[5]); + if(tinyInfo[7]!=-1) + { + // Connectivity + const int *recvBuffer=a1->getConstPointer(); + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> myConnecIndex=DataArrayInt::New(); + myConnecIndex->alloc(tinyInfo[6]+1,1); + std::copy(recvBuffer,recvBuffer+tinyInfo[6]+1,myConnecIndex->getPointer()); + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> myConnec=DataArrayInt::New(); + myConnec->alloc(tinyInfo[7],1); + std::copy(recvBuffer+tinyInfo[6]+1,recvBuffer+tinyInfo[6]+1+tinyInfo[7],myConnec->getPointer()); + setConnectivity(myConnec, myConnecIndex); + } +} + +/*! + * This is the low algorithm of MEDCouplingUMesh::buildPartOfMySelf2. + * CellIds are given using range specified by a start an end and step. + */ +MEDCouplingPointSet *MEDCouplingUMesh::buildPartOfMySelfKeepCoords2(int start, int end, int step) const +{ + checkFullyDefined(); + int ncell=getNumberOfCells(); + MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> ret=MEDCouplingUMesh::New(); + ret->_mesh_dim=_mesh_dim; + ret->setCoords(_coords); + int newNbOfCells=DataArray::GetNumberOfItemGivenBESRelative(start,end,step,"MEDCouplingUMesh::buildPartOfMySelfKeepCoords2 : "); + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> newConnI=DataArrayInt::New(); newConnI->alloc(newNbOfCells+1,1); + int *newConnIPtr=newConnI->getPointer(); *newConnIPtr=0; + int work=start; + const int *conn=_nodal_connec->getConstPointer(); + const int *connIndex=_nodal_connec_index->getConstPointer(); + for(int i=0;i<newNbOfCells;i++,newConnIPtr++,work+=step) + { + if(work>=0 && work<ncell) + { + newConnIPtr[1]=newConnIPtr[0]+connIndex[work+1]-connIndex[work]; + } + else + { + std::ostringstream oss; oss << "MEDCouplingUMesh::buildPartOfMySelfKeepCoords2 : On pos #" << i << " input cell id =" << work << " should be in [0," << ncell << ") !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + } + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> newConn=DataArrayInt::New(); newConn->alloc(newConnIPtr[0],1); + int *newConnPtr=newConn->getPointer(); + std::set<INTERP_KERNEL::NormalizedCellType> types; + work=start; + for(int i=0;i<newNbOfCells;i++,newConnIPtr++,work+=step) + { + types.insert((INTERP_KERNEL::NormalizedCellType)conn[connIndex[work]]); + newConnPtr=std::copy(conn+connIndex[work],conn+connIndex[work+1],newConnPtr); + } + ret->setConnectivity(newConn,newConnI,false); + ret->_types=types; + ret->copyTinyInfoFrom(this); + return ret.retn(); +} + +/*! + * This is the low algorithm of MEDCouplingUMesh::buildPartOfMySelf. + * Keeps from \a this only cells which constituing point id are in the ids specified by [ \a begin,\a end ). + * The return newly allocated mesh will share the same coordinates as \a this. + */ +MEDCouplingPointSet *MEDCouplingUMesh::buildPartOfMySelfKeepCoords(const int *begin, const int *end) const +{ + checkConnectivityFullyDefined(); + int ncell=getNumberOfCells(); + MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> ret=MEDCouplingUMesh::New(); + ret->_mesh_dim=_mesh_dim; + ret->setCoords(_coords); + std::size_t nbOfElemsRet=std::distance(begin,end); + int *connIndexRet=(int *)malloc((nbOfElemsRet+1)*sizeof(int)); + connIndexRet[0]=0; + const int *conn=_nodal_connec->getConstPointer(); + const int *connIndex=_nodal_connec_index->getConstPointer(); + int newNbring=0; + for(const int *work=begin;work!=end;work++,newNbring++) + { + if(*work>=0 && *work<ncell) + connIndexRet[newNbring+1]=connIndexRet[newNbring]+connIndex[*work+1]-connIndex[*work]; + else + { + free(connIndexRet); + std::ostringstream oss; oss << "MEDCouplingUMesh::buildPartOfMySelfKeepCoords : On pos #" << std::distance(begin,work) << " input cell id =" << *work << " should be in [0," << ncell << ") !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + } + int *connRet=(int *)malloc(connIndexRet[nbOfElemsRet]*sizeof(int)); + int *connRetWork=connRet; + std::set<INTERP_KERNEL::NormalizedCellType> types; + for(const int *work=begin;work!=end;work++) + { + types.insert((INTERP_KERNEL::NormalizedCellType)conn[connIndex[*work]]); + connRetWork=std::copy(conn+connIndex[*work],conn+connIndex[*work+1],connRetWork); + } + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> connRetArr=DataArrayInt::New(); + connRetArr->useArray(connRet,true,C_DEALLOC,connIndexRet[nbOfElemsRet],1); + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> connIndexRetArr=DataArrayInt::New(); + connIndexRetArr->useArray(connIndexRet,true,C_DEALLOC,(int)nbOfElemsRet+1,1); + ret->setConnectivity(connRetArr,connIndexRetArr,false); + ret->_types=types; + ret->copyTinyInfoFrom(this); + return ret.retn(); +} + +/*! + * Returns a new MEDCouplingFieldDouble containing volumes of cells constituting \a this + * mesh.<br> + * For 1D cells, the returned field contains lengths.<br> + * For 2D cells, the returned field contains areas.<br> + * 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 on cells + * and one time . The caller is to delete this field using decrRef() as it is no + * more needed. + */ +MEDCouplingFieldDouble *MEDCouplingUMesh::getMeasureField(bool isAbs) const +{ + std::string name="MeasureOfMesh_"; + name+=getName(); + int nbelem=getNumberOfCells(); + MEDCouplingAutoRefCountObjectPtr<MEDCouplingFieldDouble> field=MEDCouplingFieldDouble::New(ON_CELLS,ONE_TIME); + field->setName(name); + MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> array=DataArrayDouble::New(); + array->alloc(nbelem,1); + double *area_vol=array->getPointer(); + field->setArray(array) ; array=0; + field->setMesh(const_cast<MEDCouplingUMesh *>(this)); + field->synchronizeTimeWithMesh(); + if(getMeshDimension()!=-1) + { + int ipt; + INTERP_KERNEL::NormalizedCellType type; + int dim_space=getSpaceDimension(); + const double *coords=getCoords()->getConstPointer(); + const int *connec=getNodalConnectivity()->getConstPointer(); + const int *connec_index=getNodalConnectivityIndex()->getConstPointer(); + for(int iel=0;iel<nbelem;iel++) + { + ipt=connec_index[iel]; + type=(INTERP_KERNEL::NormalizedCellType)connec[ipt]; + area_vol[iel]=INTERP_KERNEL::computeVolSurfOfCell2<int,INTERP_KERNEL::ALL_C_MODE>(type,connec+ipt+1,connec_index[iel+1]-ipt-1,coords,dim_space); + } + if(isAbs) + std::transform(area_vol,area_vol+nbelem,area_vol,std::ptr_fun<double,double>(fabs)); + } + else + { + area_vol[0]=std::numeric_limits<double>::max(); + } + return field.retn(); +} + +/*! + * Returns a new DataArrayDouble containing volumes of specified cells of \a this + * mesh.<br> + * For 1D cells, the returned array contains lengths.<br> + * For 2D cells, the returned array contains areas.<br> + * For 3D cells, the returned array contains volumes. + * This method avoids building explicitly a part of \a this mesh to perform the work. + * \param [in] isAbs - if \c true, the computed cell volume does not reflect cell + * orientation, i.e. the volume is always positive. + * \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. + * \return DataArrayDouble * - a new instance of DataArrayDouble. The caller is to + * delete this array using decrRef() as it is no more needed. + * + * \if ENABLE_EXAMPLES + * \ref cpp_mcumesh_getPartMeasureField "Here is a C++ example".<br> + * \ref py_mcumesh_getPartMeasureField "Here is a Python example". + * \endif + * \sa getMeasureField() + */ +DataArrayDouble *MEDCouplingUMesh::getPartMeasureField(bool isAbs, const int *begin, const int *end) const +{ + std::string name="PartMeasureOfMesh_"; + name+=getName(); + int nbelem=(int)std::distance(begin,end); + MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> array=DataArrayDouble::New(); + array->setName(name); + array->alloc(nbelem,1); + double *area_vol=array->getPointer(); + if(getMeshDimension()!=-1) + { + int ipt; + INTERP_KERNEL::NormalizedCellType type; + int dim_space=getSpaceDimension(); + const double *coords=getCoords()->getConstPointer(); + const int *connec=getNodalConnectivity()->getConstPointer(); + const int *connec_index=getNodalConnectivityIndex()->getConstPointer(); + for(const int *iel=begin;iel!=end;iel++) + { + ipt=connec_index[*iel]; + type=(INTERP_KERNEL::NormalizedCellType)connec[ipt]; + *area_vol++=INTERP_KERNEL::computeVolSurfOfCell2<int,INTERP_KERNEL::ALL_C_MODE>(type,connec+ipt+1,connec_index[*iel+1]-ipt-1,coords,dim_space); + } + if(isAbs) + std::transform(array->getPointer(),area_vol,array->getPointer(),std::ptr_fun<double,double>(fabs)); + } + else + { + area_vol[0]=std::numeric_limits<double>::max(); + } + return array.retn(); +} + +/*! + * Returns a new MEDCouplingFieldDouble containing volumes of cells of a dual mesh of + * \a this one. The returned field contains the dual cell volume for each corresponding + * node in \a this mesh. In other words, the field returns the getMeasureField() of + * the dual mesh in P1 sens of \a this.<br> + * For 1D cells, the returned field contains lengths.<br> + * For 2D cells, the returned field contains areas.<br> + * For 3D cells, the returned field contains volumes. + * This method is useful to check "P1*" conservative interpolators. + * \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 on + * nodes and one time. The caller is to delete this array using decrRef() as + * it is no more needed. + */ +MEDCouplingFieldDouble *MEDCouplingUMesh::getMeasureFieldOnNode(bool isAbs) const +{ + MEDCouplingAutoRefCountObjectPtr<MEDCouplingFieldDouble> tmp=getMeasureField(isAbs); + std::string name="MeasureOnNodeOfMesh_"; + name+=getName(); + int nbNodes=getNumberOfNodes(); + MEDCouplingAutoRefCountObjectPtr<MEDCouplingFieldDouble> ret=MEDCouplingFieldDouble::New(ON_NODES); + double cst=1./((double)getMeshDimension()+1.); + MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> array=DataArrayDouble::New(); + array->alloc(nbNodes,1); + double *valsToFill=array->getPointer(); + std::fill(valsToFill,valsToFill+nbNodes,0.); + const double *values=tmp->getArray()->getConstPointer(); + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> da=DataArrayInt::New(); + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> daInd=DataArrayInt::New(); + getReverseNodalConnectivity(da,daInd); + const int *daPtr=da->getConstPointer(); + const int *daIPtr=daInd->getConstPointer(); + for(int i=0;i<nbNodes;i++) + for(const int *cell=daPtr+daIPtr[i];cell!=daPtr+daIPtr[i+1];cell++) + valsToFill[i]+=cst*values[*cell]; + ret->setMesh(this); + ret->setArray(array); + return ret.retn(); +} + +/*! + * Returns a new MEDCouplingFieldDouble holding normal vectors to cells of \a this + * mesh. The returned normal vectors to each cell have a norm2 equal to 1. + * The computed vectors have <em> this->getMeshDimension()+1 </em> components + * and are normalized. + * <br> \a this can be either + * - a 2D mesh in 2D or 3D space or + * - an 1D mesh in 2D space. + * + * \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 the nodal connectivity of cells is not defined. + * \throw If the coordinates array is not set. + * \throw If the mesh dimension is not set. + * \throw If the mesh and space dimension is not as specified above. + */ +MEDCouplingFieldDouble *MEDCouplingUMesh::buildOrthogonalField() const +{ + if((getMeshDimension()!=2) && (getMeshDimension()!=1 || getSpaceDimension()!=2)) + throw INTERP_KERNEL::Exception("Expected a umesh with ( meshDim == 2 spaceDim == 2 or 3 ) or ( meshDim == 1 spaceDim == 2 ) !"); + MEDCouplingAutoRefCountObjectPtr<MEDCouplingFieldDouble> ret=MEDCouplingFieldDouble::New(ON_CELLS,ONE_TIME); + MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> array=DataArrayDouble::New(); + int nbOfCells=getNumberOfCells(); + int nbComp=getMeshDimension()+1; + array->alloc(nbOfCells,nbComp); + double *vals=array->getPointer(); + const int *connI=_nodal_connec_index->getConstPointer(); + const int *conn=_nodal_connec->getConstPointer(); + const double *coords=_coords->getConstPointer(); + if(getMeshDimension()==2) + { + if(getSpaceDimension()==3) + { + MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> loc=getBarycenterAndOwner(); + const double *locPtr=loc->getConstPointer(); + for(int i=0;i<nbOfCells;i++,vals+=3) + { + int offset=connI[i]; + INTERP_KERNEL::crossprod<3>(locPtr+3*i,coords+3*conn[offset+1],coords+3*conn[offset+2],vals); + double n=INTERP_KERNEL::norm<3>(vals); + std::transform(vals,vals+3,vals,std::bind2nd(std::multiplies<double>(),1./n)); + } + } + else + { + MEDCouplingAutoRefCountObjectPtr<MEDCouplingFieldDouble> isAbs=getMeasureField(false); + const double *isAbsPtr=isAbs->getArray()->begin(); + for(int i=0;i<nbOfCells;i++,isAbsPtr++) + { vals[3*i]=0.; vals[3*i+1]=0.; vals[3*i+2]=*isAbsPtr>0.?1.:-1.; } + } + } + else//meshdimension==1 + { + double tmp[2]; + for(int i=0;i<nbOfCells;i++) + { + int offset=connI[i]; + std::transform(coords+2*conn[offset+2],coords+2*conn[offset+2]+2,coords+2*conn[offset+1],tmp,std::minus<double>()); + double n=INTERP_KERNEL::norm<2>(tmp); + std::transform(tmp,tmp+2,tmp,std::bind2nd(std::multiplies<double>(),1./n)); + *vals++=-tmp[1]; + *vals++=tmp[0]; + } + } + ret->setArray(array); + ret->setMesh(this); + ret->synchronizeTimeWithSupport(); + return ret.retn(); +} + +/*! + * Returns a new MEDCouplingFieldDouble holding normal vectors to specified cells of + * \a this mesh. The computed vectors have <em> this->getMeshDimension()+1 </em> components + * and are normalized. + * <br> \a this can be either + * - a 2D mesh in 2D or 3D space or + * - an 1D mesh in 2D space. + * + * This method avoids building explicitly a part of \a this mesh to perform the work. + * \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. + * \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 the nodal connectivity of cells is not defined. + * \throw If the coordinates array is not set. + * \throw If the mesh dimension is not set. + * \throw If the mesh and space dimension is not as specified above. + * \sa buildOrthogonalField() + * + * \if ENABLE_EXAMPLES + * \ref cpp_mcumesh_buildPartOrthogonalField "Here is a C++ example".<br> + * \ref py_mcumesh_buildPartOrthogonalField "Here is a Python example". + * \endif + */ +MEDCouplingFieldDouble *MEDCouplingUMesh::buildPartOrthogonalField(const int *begin, const int *end) const +{ + if((getMeshDimension()!=2) && (getMeshDimension()!=1 || getSpaceDimension()!=2)) + throw INTERP_KERNEL::Exception("Expected a umesh with ( meshDim == 2 spaceDim == 2 or 3 ) or ( meshDim == 1 spaceDim == 2 ) !"); + MEDCouplingAutoRefCountObjectPtr<MEDCouplingFieldDouble> ret=MEDCouplingFieldDouble::New(ON_CELLS,ONE_TIME); + MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> array=DataArrayDouble::New(); + std::size_t nbelems=std::distance(begin,end); + int nbComp=getMeshDimension()+1; + array->alloc((int)nbelems,nbComp); + double *vals=array->getPointer(); + const int *connI=_nodal_connec_index->getConstPointer(); + const int *conn=_nodal_connec->getConstPointer(); + const double *coords=_coords->getConstPointer(); + if(getMeshDimension()==2) + { + if(getSpaceDimension()==3) + { + MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> loc=getPartBarycenterAndOwner(begin,end); + const double *locPtr=loc->getConstPointer(); + for(const int *i=begin;i!=end;i++,vals+=3,locPtr+=3) + { + int offset=connI[*i]; + INTERP_KERNEL::crossprod<3>(locPtr,coords+3*conn[offset+1],coords+3*conn[offset+2],vals); + double n=INTERP_KERNEL::norm<3>(vals); + std::transform(vals,vals+3,vals,std::bind2nd(std::multiplies<double>(),1./n)); + } + } + else + { + for(std::size_t i=0;i<nbelems;i++) + { vals[3*i]=0.; vals[3*i+1]=0.; vals[3*i+2]=1.; } + } + } + else//meshdimension==1 + { + double tmp[2]; + for(const int *i=begin;i!=end;i++) + { + int offset=connI[*i]; + std::transform(coords+2*conn[offset+2],coords+2*conn[offset+2]+2,coords+2*conn[offset+1],tmp,std::minus<double>()); + double n=INTERP_KERNEL::norm<2>(tmp); + std::transform(tmp,tmp+2,tmp,std::bind2nd(std::multiplies<double>(),1./n)); + *vals++=-tmp[1]; + *vals++=tmp[0]; + } + } + ret->setArray(array); + ret->setMesh(this); + ret->synchronizeTimeWithSupport(); + return ret.retn(); +} + +/*! + * Returns a new MEDCouplingFieldDouble holding a direction vector for each SEG2 in \a + * this 1D mesh. The computed vectors have <em> this->getSpaceDimension() </em> components + * and are \b not 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 the nodal connectivity of cells is not defined. + * \throw If the coordinates array is not set. + * \throw If \a this->getMeshDimension() != 1. + * \throw If \a this mesh includes cells of type other than SEG2. + */ +MEDCouplingFieldDouble *MEDCouplingUMesh::buildDirectionVectorField() const +{ + if(getMeshDimension()!=1) + throw INTERP_KERNEL::Exception("Expected a umesh with meshDim == 1 for buildDirectionVectorField !"); + if(_types.size()!=1 || *(_types.begin())!=INTERP_KERNEL::NORM_SEG2) + throw INTERP_KERNEL::Exception("Expected a umesh with only NORM_SEG2 type of elements for buildDirectionVectorField !"); + MEDCouplingAutoRefCountObjectPtr<MEDCouplingFieldDouble> ret=MEDCouplingFieldDouble::New(ON_CELLS,ONE_TIME); + MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> array=DataArrayDouble::New(); + int nbOfCells=getNumberOfCells(); + int spaceDim=getSpaceDimension(); + array->alloc(nbOfCells,spaceDim); + double *pt=array->getPointer(); + const double *coo=getCoords()->getConstPointer(); + std::vector<int> conn; + conn.reserve(2); + for(int i=0;i<nbOfCells;i++) + { + conn.resize(0); + getNodeIdsOfCell(i,conn); + pt=std::transform(coo+conn[1]*spaceDim,coo+(conn[1]+1)*spaceDim,coo+conn[0]*spaceDim,pt,std::minus<double>()); + } + ret->setArray(array); + ret->setMesh(this); + ret->synchronizeTimeWithSupport(); + return ret.retn(); +} + +/*! + * Creates a 2D mesh by cutting \a this 3D mesh with a plane. In addition to the mesh, + * returns a new DataArrayInt, of length equal to the number of 2D cells in the result + * mesh, holding, for each cell in the result mesh, an id of a 3D cell it comes + * from. If a result face is shared by two 3D cells, then the face in included twice in + * the result mesh. + * \param [in] origin - 3 components of a point defining location of the plane. + * \param [in] vec - 3 components of a vector normal to the plane. Vector magnitude + * must be greater than 1e-6. + * \param [in] eps - half-thickness of the plane. + * \param [out] cellIds - a new instance of DataArrayInt holding ids of 3D cells + * producing correspondent 2D cells. The caller is to delete this array + * using decrRef() as it is no more needed. + * \return MEDCouplingUMesh * - a new instance of MEDCouplingUMesh. This mesh does + * not share 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 not defined. + * \throw If \a this->getMeshDimension() != 3 or \a this->getSpaceDimension() != 3. + * \throw If magnitude of \a vec is less than 1e-6. + * \throw If the plane does not intersect any 3D cell of \a this mesh. + * \throw If \a this includes quadratic cells. + */ +MEDCouplingUMesh *MEDCouplingUMesh::buildSlice3D(const double *origin, const double *vec, double eps, DataArrayInt *&cellIds) const +{ + checkFullyDefined(); + if(getMeshDimension()!=3 || getSpaceDimension()!=3) + throw INTERP_KERNEL::Exception("MEDCouplingUMesh::buildSlice3D works on umeshes with meshdim equal to 3 and spaceDim equal to 3 too!"); + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> candidates=getCellIdsCrossingPlane(origin,vec,eps); + if(candidates->empty()) + throw INTERP_KERNEL::Exception("MEDCouplingUMesh::buildSlice3D : No 3D cells in this intercepts the specified plane considering bounding boxes !"); + std::vector<int> nodes; + DataArrayInt *cellIds1D=0; + MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> subMesh=static_cast<MEDCouplingUMesh*>(buildPartOfMySelf(candidates->begin(),candidates->end(),false)); + subMesh->findNodesOnPlane(origin,vec,eps,nodes); + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> desc1=DataArrayInt::New(),desc2=DataArrayInt::New(); + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> descIndx1=DataArrayInt::New(),descIndx2=DataArrayInt::New(); + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> revDesc1=DataArrayInt::New(),revDesc2=DataArrayInt::New(); + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> revDescIndx1=DataArrayInt::New(),revDescIndx2=DataArrayInt::New(); + MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> mDesc2=subMesh->buildDescendingConnectivity(desc2,descIndx2,revDesc2,revDescIndx2);//meshDim==2 spaceDim==3 + revDesc2=0; revDescIndx2=0; + MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> mDesc1=mDesc2->buildDescendingConnectivity(desc1,descIndx1,revDesc1,revDescIndx1);//meshDim==1 spaceDim==3 + revDesc1=0; revDescIndx1=0; + mDesc1->fillCellIdsToKeepFromNodeIds(&nodes[0],&nodes[0]+nodes.size(),true,cellIds1D); + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> cellIds1DTmp(cellIds1D); + // + std::vector<int> cut3DCurve(mDesc1->getNumberOfCells(),-2); + for(const int *it=cellIds1D->begin();it!=cellIds1D->end();it++) + cut3DCurve[*it]=-1; + mDesc1->split3DCurveWithPlane(origin,vec,eps,cut3DCurve); + std::vector< std::pair<int,int> > cut3DSurf(mDesc2->getNumberOfCells()); + AssemblyForSplitFrom3DCurve(cut3DCurve,nodes,mDesc2->getNodalConnectivity()->getConstPointer(),mDesc2->getNodalConnectivityIndex()->getConstPointer(), + mDesc1->getNodalConnectivity()->getConstPointer(),mDesc1->getNodalConnectivityIndex()->getConstPointer(), + desc1->getConstPointer(),descIndx1->getConstPointer(),cut3DSurf); + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> conn(DataArrayInt::New()),connI(DataArrayInt::New()),cellIds2(DataArrayInt::New()); + connI->pushBackSilent(0); conn->alloc(0,1); cellIds2->alloc(0,1); + subMesh->assemblyForSplitFrom3DSurf(cut3DSurf,desc2->getConstPointer(),descIndx2->getConstPointer(),conn,connI,cellIds2); + if(cellIds2->empty()) + throw INTERP_KERNEL::Exception("MEDCouplingUMesh::buildSlice3D : No 3D cells in this intercepts the specified plane !"); + MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> ret=MEDCouplingUMesh::New("Slice3D",2); + ret->setCoords(mDesc1->getCoords()); + ret->setConnectivity(conn,connI,true); + cellIds=candidates->selectByTupleId(cellIds2->begin(),cellIds2->end()); + return ret.retn(); +} + +/*! + * Creates an 1D mesh by cutting \a this 2D mesh in 3D space with a plane. In +addition to the mesh, returns a new DataArrayInt, of length equal to the number of 1D cells in the result mesh, holding, for each cell in the result mesh, an id of a 2D cell it comes +from. If a result segment is shared by two 2D cells, then the segment in included twice in +the result mesh. + * \param [in] origin - 3 components of a point defining location of the plane. + * \param [in] vec - 3 components of a vector normal to the plane. Vector magnitude + * must be greater than 1e-6. + * \param [in] eps - half-thickness of the plane. + * \param [out] cellIds - a new instance of DataArrayInt holding ids of faces + * producing correspondent segments. The caller is to delete this array + * using decrRef() as it is no more needed. + * \return MEDCouplingUMesh * - a new instance of MEDCouplingUMesh. This is an 1D + * mesh in 3D space. This mesh does not share 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 not defined. + * \throw If \a this->getMeshDimension() != 2 or \a this->getSpaceDimension() != 3. + * \throw If magnitude of \a vec is less than 1e-6. + * \throw If the plane does not intersect any 2D cell of \a this mesh. + * \throw If \a this includes quadratic cells. + */ +MEDCouplingUMesh *MEDCouplingUMesh::buildSlice3DSurf(const double *origin, const double *vec, double eps, DataArrayInt *&cellIds) const +{ + checkFullyDefined(); + if(getMeshDimension()!=2 || getSpaceDimension()!=3) + throw INTERP_KERNEL::Exception("MEDCouplingUMesh::buildSlice3DSurf works on umeshes with meshdim equal to 2 and spaceDim equal to 3 !"); + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> candidates=getCellIdsCrossingPlane(origin,vec,eps); + if(candidates->empty()) + throw INTERP_KERNEL::Exception("MEDCouplingUMesh::buildSlice3DSurf : No 3D surf cells in this intercepts the specified plane considering bounding boxes !"); + std::vector<int> nodes; + DataArrayInt *cellIds1D=0; + MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> subMesh=static_cast<MEDCouplingUMesh*>(buildPartOfMySelf(candidates->begin(),candidates->end(),false)); + subMesh->findNodesOnPlane(origin,vec,eps,nodes); + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> desc1=DataArrayInt::New(); + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> descIndx1=DataArrayInt::New(); + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> revDesc1=DataArrayInt::New(); + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> revDescIndx1=DataArrayInt::New(); + MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> mDesc1=subMesh->buildDescendingConnectivity(desc1,descIndx1,revDesc1,revDescIndx1);//meshDim==1 spaceDim==3 + mDesc1->fillCellIdsToKeepFromNodeIds(&nodes[0],&nodes[0]+nodes.size(),true,cellIds1D); + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> cellIds1DTmp(cellIds1D); + // + std::vector<int> cut3DCurve(mDesc1->getNumberOfCells(),-2); + for(const int *it=cellIds1D->begin();it!=cellIds1D->end();it++) + cut3DCurve[*it]=-1; + mDesc1->split3DCurveWithPlane(origin,vec,eps,cut3DCurve); + int ncellsSub=subMesh->getNumberOfCells(); + std::vector< std::pair<int,int> > cut3DSurf(ncellsSub); + AssemblyForSplitFrom3DCurve(cut3DCurve,nodes,subMesh->getNodalConnectivity()->getConstPointer(),subMesh->getNodalConnectivityIndex()->getConstPointer(), + mDesc1->getNodalConnectivity()->getConstPointer(),mDesc1->getNodalConnectivityIndex()->getConstPointer(), + desc1->getConstPointer(),descIndx1->getConstPointer(),cut3DSurf); + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> conn(DataArrayInt::New()),connI(DataArrayInt::New()),cellIds2(DataArrayInt::New()); connI->pushBackSilent(0); + conn->alloc(0,1); + const int *nodal=subMesh->getNodalConnectivity()->getConstPointer(); + const int *nodalI=subMesh->getNodalConnectivityIndex()->getConstPointer(); + for(int i=0;i<ncellsSub;i++) + { + if(cut3DSurf[i].first!=-1 && cut3DSurf[i].second!=-1) + { + if(cut3DSurf[i].first!=-2) + { + conn->pushBackSilent((int)INTERP_KERNEL::NORM_SEG2); conn->pushBackSilent(cut3DSurf[i].first); conn->pushBackSilent(cut3DSurf[i].second); + connI->pushBackSilent(conn->getNumberOfTuples()); + cellIds2->pushBackSilent(i); + } + else + { + int cellId3DSurf=cut3DSurf[i].second; + int offset=nodalI[cellId3DSurf]+1; + int nbOfEdges=nodalI[cellId3DSurf+1]-offset; + for(int j=0;j<nbOfEdges;j++) + { + conn->pushBackSilent((int)INTERP_KERNEL::NORM_SEG2); conn->pushBackSilent(nodal[offset+j]); conn->pushBackSilent(nodal[offset+(j+1)%nbOfEdges]); + connI->pushBackSilent(conn->getNumberOfTuples()); + cellIds2->pushBackSilent(cellId3DSurf); + } + } + } + } + if(cellIds2->empty()) + throw INTERP_KERNEL::Exception("MEDCouplingUMesh::buildSlice3DSurf : No 3DSurf cells in this intercepts the specified plane !"); + MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> ret=MEDCouplingUMesh::New("Slice3DSurf",1); + ret->setCoords(mDesc1->getCoords()); + ret->setConnectivity(conn,connI,true); + cellIds=candidates->selectByTupleId(cellIds2->begin(),cellIds2->end()); + return ret.retn(); +} + +/*! + * Finds cells whose bounding boxes intersect a given plane. + * \param [in] origin - 3 components of a point defining location of the plane. + * \param [in] vec - 3 components of a vector normal to the plane. Vector magnitude + * must be greater than 1e-6. + * \param [in] eps - half-thickness of the plane. + * \return DataArrayInt * - a new instance of DataArrayInt holding ids of the found + * cells. The caller is to delete this array using decrRef() as it is no more + * needed. + * \throw If the coordinates array is not set. + * \throw If the nodal connectivity of cells is not defined. + * \throw If \a this->getSpaceDimension() != 3. + * \throw If magnitude of \a vec is less than 1e-6. + * \sa buildSlice3D() + */ +DataArrayInt *MEDCouplingUMesh::getCellIdsCrossingPlane(const double *origin, const double *vec, double eps) const +{ + checkFullyDefined(); + if(getSpaceDimension()!=3) + throw INTERP_KERNEL::Exception("MEDCouplingUMesh::buildSlice3D works on umeshes with spaceDim equal to 3 !"); + double normm=sqrt(vec[0]*vec[0]+vec[1]*vec[1]+vec[2]*vec[2]); + if(normm<1e-6) + throw INTERP_KERNEL::Exception("MEDCouplingUMesh::getCellIdsCrossingPlane : parameter 'vec' should have a norm2 greater than 1e-6 !"); + double vec2[3]; + vec2[0]=vec[1]; vec2[1]=-vec[0]; vec2[2]=0.;//vec2 is the result of cross product of vec with (0,0,1) + double angle=acos(vec[2]/normm); + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> cellIds; + double bbox[6]; + if(angle>eps) + { + MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> coo=_coords->deepCpy(); + double normm2(sqrt(vec2[0]*vec2[0]+vec2[1]*vec2[1]+vec2[2]*vec2[2])); + if(normm2/normm>1e-6) + MEDCouplingPointSet::Rotate3DAlg(origin,vec2,angle,coo->getNumberOfTuples(),coo->getPointer()); + MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> mw=clone(false);//false -> shallow copy + mw->setCoords(coo); + mw->getBoundingBox(bbox); + bbox[4]=origin[2]-eps; bbox[5]=origin[2]+eps; + cellIds=mw->getCellsInBoundingBox(bbox,eps); + } + else + { + getBoundingBox(bbox); + bbox[4]=origin[2]-eps; bbox[5]=origin[2]+eps; + cellIds=getCellsInBoundingBox(bbox,eps); + } + return cellIds.retn(); +} + +/*! + * This method checks that \a this is a contiguous mesh. The user is expected to call this method on a mesh with meshdim==1. + * If not an exception will thrown. If this is an empty mesh with no cell an exception will be thrown too. + * No consideration of coordinate is done by this method. + * A 1D mesh is said contiguous if : a cell i with nodal connectivity (k,p) the cell i+1 the nodal connectivity should be (p,m) + * If not false is returned. In case that false is returned a call to ParaMEDMEM::MEDCouplingUMesh::mergeNodes could be usefull. + */ +bool MEDCouplingUMesh::isContiguous1D() const +{ + if(getMeshDimension()!=1) + throw INTERP_KERNEL::Exception("MEDCouplingUMesh::isContiguous1D : this method has a sense only for 1D mesh !"); + int nbCells=getNumberOfCells(); + if(nbCells<1) + throw INTERP_KERNEL::Exception("MEDCouplingUMesh::isContiguous1D : this method has a sense for non empty mesh !"); + const int *connI=_nodal_connec_index->getConstPointer(); + const int *conn=_nodal_connec->getConstPointer(); + int ref=conn[connI[0]+2]; + for(int i=1;i<nbCells;i++) + { + if(conn[connI[i]+1]!=ref) + return false; + ref=conn[connI[i]+2]; + } + return true; +} + +/*! + * This method is only callable on mesh with meshdim == 1 containing only SEG2 and spaceDim==3. + * This method projects this on the 3D line defined by (pt,v). This methods first checks that all SEG2 are along v vector. + * \param pt reference point of the line + * \param v normalized director vector of the line + * \param eps max precision before throwing an exception + * \param res output of size this->getNumberOfCells + */ +void MEDCouplingUMesh::project1D(const double *pt, const double *v, double eps, double *res) const +{ + if(getMeshDimension()!=1) + throw INTERP_KERNEL::Exception("Expected a umesh with meshDim == 1 for project1D !"); + if(_types.size()!=1 || *(_types.begin())!=INTERP_KERNEL::NORM_SEG2) + throw INTERP_KERNEL::Exception("Expected a umesh with only NORM_SEG2 type of elements for project1D !"); + if(getSpaceDimension()!=3) + throw INTERP_KERNEL::Exception("Expected a umesh with spaceDim==3 for project1D !"); + MEDCouplingAutoRefCountObjectPtr<MEDCouplingFieldDouble> f=buildDirectionVectorField(); + const double *fPtr=f->getArray()->getConstPointer(); + double tmp[3]; + for(int i=0;i<getNumberOfCells();i++) + { + const double *tmp1=fPtr+3*i; + tmp[0]=tmp1[1]*v[2]-tmp1[2]*v[1]; + tmp[1]=tmp1[2]*v[0]-tmp1[0]*v[2]; + tmp[2]=tmp1[0]*v[1]-tmp1[1]*v[0]; + double n1=INTERP_KERNEL::norm<3>(tmp); + n1/=INTERP_KERNEL::norm<3>(tmp1); + if(n1>eps) + throw INTERP_KERNEL::Exception("UMesh::Projection 1D failed !"); + } + const double *coo=getCoords()->getConstPointer(); + for(int i=0;i<getNumberOfNodes();i++) + { + std::transform(coo+i*3,coo+i*3+3,pt,tmp,std::minus<double>()); + std::transform(tmp,tmp+3,v,tmp,std::multiplies<double>()); + res[i]=std::accumulate(tmp,tmp+3,0.); + } +} + +/*! + * This method computes the distance from a point \a pt to \a this and the first \a cellId in \a this corresponding to the returned distance. + * \a this is expected to be a mesh so that its space dimension is equal to its + * mesh dimension + 1. Furthermore only mesh dimension 1 and 2 are supported for the moment. + * Distance from \a ptBg to \a ptEnd is expected to be equal to the space dimension. \a this is also expected to be fully defined (connectivity and coordinates). + * + * WARNING, if there is some orphan nodes in \a this (nodes not fetched by any cells in \a this ( see MEDCouplingUMesh::zipCoords ) ) these nodes will ** not ** been taken + * into account in this method. Only cells and nodes lying on them are considered in the algorithm (even if one of these orphan nodes is closer than returned distance). + * A user that needs to consider orphan nodes should invoke DataArrayDouble::minimalDistanceTo method on the coordinates array of \a this. + * + * So this method is more accurate (so, more costly) than simply searching for the closest point in \a this. + * If only this information is enough for you simply call \c getCoords()->distanceToTuple on \a this. + * + * \param [in] ptBg the start pointer (included) of the coordinates of the point + * \param [in] ptEnd the end pointer (not included) of the coordinates of the point + * \param [out] cellId that corresponds to minimal distance. If the closer node is not linked to any cell in \a this -1 is returned. + * \return the positive value of the distance. + * \throw if distance from \a ptBg to \a ptEnd is not equal to the space dimension. An exception is also thrown if mesh dimension of \a this is not equal to space + * dimension - 1. + * \sa DataArrayDouble::distanceToTuple, MEDCouplingUMesh::distanceToPoints + */ +double MEDCouplingUMesh::distanceToPoint(const double *ptBg, const double *ptEnd, int& cellId) const +{ + int meshDim=getMeshDimension(),spaceDim=getSpaceDimension(); + if(meshDim!=spaceDim-1) + throw INTERP_KERNEL::Exception("MEDCouplingUMesh::distanceToPoint works only for spaceDim=meshDim+1 !"); + if(meshDim!=2 && meshDim!=1) + throw INTERP_KERNEL::Exception("MEDCouplingUMesh::distanceToPoint : only mesh dimension 2 and 1 are implemented !"); + checkFullyDefined(); + if((int)std::distance(ptBg,ptEnd)!=spaceDim) + { std::ostringstream oss; oss << "MEDCouplingUMesh::distanceToPoint : input point has to have dimension equal to the space dimension of this (" << spaceDim << ") !"; throw INTERP_KERNEL::Exception(oss.str().c_str()); } + DataArrayInt *ret1=0; + MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> pts=DataArrayDouble::New(); pts->useArray(ptBg,false,C_DEALLOC,1,spaceDim); + MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret0=distanceToPoints(pts,ret1); + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret1Safe(ret1); + cellId=*ret1Safe->begin(); + return *ret0->begin(); +} + +/*! + * This method computes the distance from each point of points serie \a pts (stored in a DataArrayDouble in which each tuple represents a point) + * to \a this and the first \a cellId in \a this corresponding to the returned distance. + * WARNING, if there is some orphan nodes in \a this (nodes not fetched by any cells in \a this ( see MEDCouplingUMesh::zipCoords ) ) these nodes will ** not ** been taken + * into account in this method. Only cells and nodes lying on them are considered in the algorithm (even if one of these orphan nodes is closer than returned distance). + * A user that needs to consider orphan nodes should invoke DataArrayDouble::minimalDistanceTo method on the coordinates array of \a this. + * + * \a this is expected to be a mesh so that its space dimension is equal to its + * mesh dimension + 1. Furthermore only mesh dimension 1 and 2 are supported for the moment. + * Number of components of \a pts is expected to be equal to the space dimension. \a this is also expected to be fully defined (connectivity and coordinates). + * + * So this method is more accurate (so, more costly) than simply searching for each point in \a pts the closest point in \a this. + * If only this information is enough for you simply call \c getCoords()->distanceToTuple on \a this. + * + * \param [in] pts the list of points in which each tuple represents a point + * \param [out] cellIds a newly allocated object that tells for each point in \a pts the first cell id in \a this that minimizes the distance. + * \return a newly allocated object to be dealed by the caller that tells for each point in \a pts the distance to \a this. + * \throw if number of components of \a pts is not equal to the space dimension. + * \throw if mesh dimension of \a this is not equal to space dimension - 1. + * \sa DataArrayDouble::distanceToTuple, MEDCouplingUMesh::distanceToPoint + */ +DataArrayDouble *MEDCouplingUMesh::distanceToPoints(const DataArrayDouble *pts, DataArrayInt *& cellIds) const +{ + if(!pts) + throw INTERP_KERNEL::Exception("MEDCouplingUMesh::distanceToPoints : input points pointer is NULL !"); + pts->checkAllocated(); + int meshDim=getMeshDimension(),spaceDim=getSpaceDimension(); + if(meshDim!=spaceDim-1) + throw INTERP_KERNEL::Exception("MEDCouplingUMesh::distanceToPoints works only for spaceDim=meshDim+1 !"); + if(meshDim!=2 && meshDim!=1) + throw INTERP_KERNEL::Exception("MEDCouplingUMesh::distanceToPoints : only mesh dimension 2 and 1 are implemented !"); + if(pts->getNumberOfComponents()!=spaceDim) + { + std::ostringstream oss; oss << "MEDCouplingUMesh::distanceToPoints : input pts DataArrayDouble has " << pts->getNumberOfComponents() << " components whereas it should be equal to " << spaceDim << " (mesh spaceDimension) !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + checkFullyDefined(); + int nbCells=getNumberOfCells(); + if(nbCells==0) + throw INTERP_KERNEL::Exception("MEDCouplingUMesh::distanceToPoints : no cells in this !"); + int nbOfPts=pts->getNumberOfTuples(); + MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret0=DataArrayDouble::New(); ret0->alloc(nbOfPts,1); + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret1=DataArrayInt::New(); ret1->alloc(nbOfPts,1); + const int *nc=_nodal_connec->begin(),*ncI=_nodal_connec_index->begin(); const double *coords=_coords->begin(); + double *ret0Ptr=ret0->getPointer(); int *ret1Ptr=ret1->getPointer(); const double *ptsPtr=pts->begin(); + MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> bboxArr(getBoundingBoxForBBTree()); + const double *bbox(bboxArr->begin()); + switch(spaceDim) + { + case 3: + { + BBTreeDst<3> myTree(bbox,0,0,nbCells); + for(int i=0;i<nbOfPts;i++,ret0Ptr++,ret1Ptr++,ptsPtr+=3) + { + double x=std::numeric_limits<double>::max(); + std::vector<int> elems; + myTree.getMinDistanceOfMax(ptsPtr,x); + myTree.getElemsWhoseMinDistanceToPtSmallerThan(ptsPtr,x,elems); + DistanceToPoint3DSurfAlg(ptsPtr,&elems[0],&elems[0]+elems.size(),coords,nc,ncI,*ret0Ptr,*ret1Ptr); + } + break; + } + case 2: + { + BBTreeDst<2> myTree(bbox,0,0,nbCells); + for(int i=0;i<nbOfPts;i++,ret0Ptr++,ret1Ptr++,ptsPtr+=2) + { + double x=std::numeric_limits<double>::max(); + std::vector<int> elems; + myTree.getMinDistanceOfMax(ptsPtr,x); + myTree.getElemsWhoseMinDistanceToPtSmallerThan(ptsPtr,x,elems); + DistanceToPoint2DCurveAlg(ptsPtr,&elems[0],&elems[0]+elems.size(),coords,nc,ncI,*ret0Ptr,*ret1Ptr); + } + break; + } + default: + throw INTERP_KERNEL::Exception("MEDCouplingUMesh::distanceToPoints : only spacedim 2 and 3 supported !"); + } + cellIds=ret1.retn(); + return ret0.retn(); +} + +/*! + * \param [in] pt the start pointer (included) of the coordinates of the point + * \param [in] cellIdsBg the start pointer (included) of cellIds + * \param [in] cellIdsEnd the end pointer (excluded) of cellIds + * \param [in] nc nodal connectivity + * \param [in] ncI nodal connectivity index + * \param [in,out] ret0 the min distance between \a this and the external input point + * \param [out] cellId that corresponds to minimal distance. If the closer node is not linked to any cell in \a this -1 is returned. + * \sa MEDCouplingUMesh::distanceToPoint, MEDCouplingUMesh::distanceToPoints + */ +void MEDCouplingUMesh::DistanceToPoint3DSurfAlg(const double *pt, const int *cellIdsBg, const int *cellIdsEnd, const double *coords, const int *nc, const int *ncI, double& ret0, int& cellId) +{ + cellId=-1; + ret0=std::numeric_limits<double>::max(); + for(const int *zeCell=cellIdsBg;zeCell!=cellIdsEnd;zeCell++) + { + switch((INTERP_KERNEL::NormalizedCellType)nc[ncI[*zeCell]]) + { + case INTERP_KERNEL::NORM_TRI3: + { + double tmp=INTERP_KERNEL::DistanceFromPtToTriInSpaceDim3(pt,coords+3*nc[ncI[*zeCell]+1],coords+3*nc[ncI[*zeCell]+2],coords+3*nc[ncI[*zeCell]+3]); + if(tmp<ret0) + { ret0=tmp; cellId=*zeCell; } + break; + } + case INTERP_KERNEL::NORM_QUAD4: + case INTERP_KERNEL::NORM_POLYGON: + { + double tmp=INTERP_KERNEL::DistanceFromPtToPolygonInSpaceDim3(pt,nc+ncI[*zeCell]+1,nc+ncI[*zeCell+1],coords); + if(tmp<ret0) + { ret0=tmp; cellId=*zeCell; } + break; + } + default: + throw INTERP_KERNEL::Exception("MEDCouplingUMesh::distanceToPoint3DSurfAlg : not managed cell type ! Supporting TRI3, QUAD4 and POLYGON !"); + } + } +} + +/*! + * \param [in] pt the start pointer (included) of the coordinates of the point + * \param [in] cellIdsBg the start pointer (included) of cellIds + * \param [in] cellIdsEnd the end pointer (excluded) of cellIds + * \param [in] nc nodal connectivity + * \param [in] ncI nodal connectivity index + * \param [in,out] ret0 the min distance between \a this and the external input point + * \param [out] cellId that corresponds to minimal distance. If the closer node is not linked to any cell in \a this -1 is returned. + * \sa MEDCouplingUMesh::distanceToPoint, MEDCouplingUMesh::distanceToPoints + */ +void MEDCouplingUMesh::DistanceToPoint2DCurveAlg(const double *pt, const int *cellIdsBg, const int *cellIdsEnd, const double *coords, const int *nc, const int *ncI, double& ret0, int& cellId) +{ + cellId=-1; + ret0=std::numeric_limits<double>::max(); + for(const int *zeCell=cellIdsBg;zeCell!=cellIdsEnd;zeCell++) + { + switch((INTERP_KERNEL::NormalizedCellType)nc[ncI[*zeCell]]) + { + case INTERP_KERNEL::NORM_SEG2: + { + std::size_t uselessEntry=0; + double tmp=INTERP_KERNEL::SquareDistanceFromPtToSegInSpaceDim2(pt,coords+2*nc[ncI[*zeCell]+1],coords+2*nc[ncI[*zeCell]+2],uselessEntry); + tmp=sqrt(tmp); + if(tmp<ret0) + { ret0=tmp; cellId=*zeCell; } + break; + } + default: + throw INTERP_KERNEL::Exception("MEDCouplingUMesh::distanceToPoint2DCurveAlg : not managed cell type ! Supporting SEG2 !"); + } + } +} + +/*! + * Finds cells in contact with a ball (i.e. a point with precision). + * For speed reasons, the INTERP_KERNEL::NORM_QUAD4, INTERP_KERNEL::NORM_TRI6 and INTERP_KERNEL::NORM_QUAD8 cells are considered as convex cells to detect if a point is IN or OUT. + * If it is not the case, please change their types to INTERP_KERNEL::NORM_POLYGON or INTERP_KERNEL::NORM_QPOLYG before invoking this method. + * + * \warning This method is suitable if the caller intends to evaluate only one + * point, for more points getCellsContainingPoints() is recommended as it is + * faster. + * \param [in] pos - array of coordinates of the ball central point. + * \param [in] eps - ball radius. + * \return int - a smallest id of cells being in contact with the ball, -1 in case + * if there are no such cells. + * \throw If the coordinates array is not set. + * \throw If \a this->getMeshDimension() != \a this->getSpaceDimension(). + */ +int MEDCouplingUMesh::getCellContainingPoint(const double *pos, double eps) const +{ + std::vector<int> elts; + getCellsContainingPoint(pos,eps,elts); + if(elts.empty()) + return -1; + return elts.front(); +} + +/*! + * Finds cells in contact with a ball (i.e. a point with precision). + * For speed reasons, the INTERP_KERNEL::NORM_QUAD4, INTERP_KERNEL::NORM_TRI6 and INTERP_KERNEL::NORM_QUAD8 cells are considered as convex cells to detect if a point is IN or OUT. + * If it is not the case, please change their types to INTERP_KERNEL::NORM_POLYGON or INTERP_KERNEL::NORM_QPOLYG before invoking this method. + * \warning This method is suitable if the caller intends to evaluate only one + * point, for more points getCellsContainingPoints() is recommended as it is + * faster. + * \param [in] pos - array of coordinates of the ball central point. + * \param [in] eps - ball radius. + * \param [out] elts - vector returning ids of the found cells. It is cleared + * before inserting ids. + * \throw If the coordinates array is not set. + * \throw If \a this->getMeshDimension() != \a this->getSpaceDimension(). + * + * \if ENABLE_EXAMPLES + * \ref cpp_mcumesh_getCellsContainingPoint "Here is a C++ example".<br> + * \ref py_mcumesh_getCellsContainingPoint "Here is a Python example". + * \endif + */ +void MEDCouplingUMesh::getCellsContainingPoint(const double *pos, double eps, std::vector<int>& elts) const +{ + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> eltsUg,eltsIndexUg; + getCellsContainingPoints(pos,1,eps,eltsUg,eltsIndexUg); + elts.clear(); elts.insert(elts.end(),eltsUg->begin(),eltsUg->end()); +} + +/// @cond INTERNAL + +namespace ParaMEDMEM +{ + template<const int SPACEDIMM> + class DummyClsMCUG + { + 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 + }; + + INTERP_KERNEL::Edge *MEDCouplingUMeshBuildQPFromEdge2(INTERP_KERNEL::NormalizedCellType typ, const int *bg, const double *coords2D, std::map< MEDCouplingAutoRefCountObjectPtr<INTERP_KERNEL::Node>,int>& m) + { + INTERP_KERNEL::Edge *ret(0); + MEDCouplingAutoRefCountObjectPtr<INTERP_KERNEL::Node> n0(new INTERP_KERNEL::Node(coords2D[2*bg[0]],coords2D[2*bg[0]+1])),n1(new INTERP_KERNEL::Node(coords2D[2*bg[1]],coords2D[2*bg[1]+1])); + m[n0]=bg[0]; m[n1]=bg[1]; + switch(typ) + { + case INTERP_KERNEL::NORM_SEG2: + { + ret=new INTERP_KERNEL::EdgeLin(n0,n1); + break; + } + case INTERP_KERNEL::NORM_SEG3: + { + INTERP_KERNEL::Node *n2(new INTERP_KERNEL::Node(coords2D[2*bg[2]],coords2D[2*bg[2]+1])); m[n2]=bg[2]; + INTERP_KERNEL::EdgeLin *e1(new INTERP_KERNEL::EdgeLin(n0,n2)),*e2(new INTERP_KERNEL::EdgeLin(n2,n1)); + INTERP_KERNEL::SegSegIntersector inters(*e1,*e2); + // is the SEG3 degenerated, and thus can be reduced to a SEG2? + bool colinearity(inters.areColinears()); + delete e1; delete e2; + if(colinearity) + { ret=new INTERP_KERNEL::EdgeLin(n0,n1); } + else + { ret=new INTERP_KERNEL::EdgeArcCircle(n0,n2,n1); } + break; + } + default: + throw INTERP_KERNEL::Exception("MEDCouplingUMeshBuildQPFromEdge2 : Expecting a mesh with spaceDim==2 and meshDim==1 !"); + } + return ret; + } + + INTERP_KERNEL::Edge *MEDCouplingUMeshBuildQPFromEdge(INTERP_KERNEL::NormalizedCellType typ, std::map<int, std::pair<INTERP_KERNEL::Node *,bool> >& mapp2, const int *bg) + { + INTERP_KERNEL::Edge *ret=0; + switch(typ) + { + case INTERP_KERNEL::NORM_SEG2: + { + ret=new INTERP_KERNEL::EdgeLin(mapp2[bg[0]].first,mapp2[bg[1]].first); + break; + } + case INTERP_KERNEL::NORM_SEG3: + { + INTERP_KERNEL::EdgeLin *e1=new INTERP_KERNEL::EdgeLin(mapp2[bg[0]].first,mapp2[bg[2]].first); + INTERP_KERNEL::EdgeLin *e2=new INTERP_KERNEL::EdgeLin(mapp2[bg[2]].first,mapp2[bg[1]].first); + INTERP_KERNEL::SegSegIntersector inters(*e1,*e2); + // is the SEG3 degenerated, and thus can be reduced to a SEG2? + bool colinearity=inters.areColinears(); + delete e1; delete e2; + if(colinearity) + ret=new INTERP_KERNEL::EdgeLin(mapp2[bg[0]].first,mapp2[bg[1]].first); + else + ret=new INTERP_KERNEL::EdgeArcCircle(mapp2[bg[0]].first,mapp2[bg[2]].first,mapp2[bg[1]].first); + mapp2[bg[2]].second=false; + break; + } + default: + throw INTERP_KERNEL::Exception("MEDCouplingUMeshBuildQPFromEdge : Expecting a mesh with spaceDim==2 and meshDim==1 !"); + } + return ret; + } + + /*! + * This method creates a sub mesh in Geometric2D DS. The sub mesh is composed by the sub set of cells in 'candidates' taken from + * the global mesh 'mDesc'. + * The input mesh 'mDesc' must be so that mDim==1 and spaceDim==2. + * 'mapp' returns a mapping between local numbering in submesh (represented by a Node*) and the global node numbering in 'mDesc'. + */ + INTERP_KERNEL::QuadraticPolygon *MEDCouplingUMeshBuildQPFromMesh(const MEDCouplingUMesh *mDesc, const std::vector<int>& candidates, + std::map<INTERP_KERNEL::Node *,int>& mapp) + { + mapp.clear(); + std::map<int, std::pair<INTERP_KERNEL::Node *,bool> > mapp2;//bool is for a flag specifying if node is boundary (true) or only a middle for SEG3. + const double *coo=mDesc->getCoords()->getConstPointer(); + const int *c=mDesc->getNodalConnectivity()->getConstPointer(); + const int *cI=mDesc->getNodalConnectivityIndex()->getConstPointer(); + std::set<int> s; + for(std::vector<int>::const_iterator it=candidates.begin();it!=candidates.end();it++) + s.insert(c+cI[*it]+1,c+cI[(*it)+1]); + for(std::set<int>::const_iterator it2=s.begin();it2!=s.end();it2++) + { + INTERP_KERNEL::Node *n=new INTERP_KERNEL::Node(coo[2*(*it2)],coo[2*(*it2)+1]); + mapp2[*it2]=std::pair<INTERP_KERNEL::Node *,bool>(n,true); + } + INTERP_KERNEL::QuadraticPolygon *ret=new INTERP_KERNEL::QuadraticPolygon; + for(std::vector<int>::const_iterator it=candidates.begin();it!=candidates.end();it++) + { + INTERP_KERNEL::NormalizedCellType typ=(INTERP_KERNEL::NormalizedCellType)c[cI[*it]]; + ret->pushBack(MEDCouplingUMeshBuildQPFromEdge(typ,mapp2,c+cI[*it]+1)); + } + for(std::map<int, std::pair<INTERP_KERNEL::Node *,bool> >::const_iterator it2=mapp2.begin();it2!=mapp2.end();it2++) + { + if((*it2).second.second) + mapp[(*it2).second.first]=(*it2).first; + ((*it2).second.first)->decrRef(); + } + return ret; + } + + INTERP_KERNEL::Node *MEDCouplingUMeshBuildQPNode(int nodeId, const double *coo1, int offset1, const double *coo2, int offset2, const std::vector<double>& addCoo) + { + if(nodeId>=offset2) + { + int locId=nodeId-offset2; + return new INTERP_KERNEL::Node(addCoo[2*locId],addCoo[2*locId+1]); + } + if(nodeId>=offset1) + { + int locId=nodeId-offset1; + return new INTERP_KERNEL::Node(coo2[2*locId],coo2[2*locId+1]); + } + return new INTERP_KERNEL::Node(coo1[2*nodeId],coo1[2*nodeId+1]); + } + + /** + * Construct a mapping between set of Nodes and the standart MEDCoupling connectivity format (c, cI). + */ + void MEDCouplingUMeshBuildQPFromMesh3(const double *coo1, int offset1, const double *coo2, int offset2, const std::vector<double>& addCoo, + const int *desc1Bg, const int *desc1End, const std::vector<std::vector<int> >& intesctEdges1, + /*output*/std::map<INTERP_KERNEL::Node *,int>& mapp, std::map<int,INTERP_KERNEL::Node *>& mappRev) + { + for(const int *desc1=desc1Bg;desc1!=desc1End;desc1++) + { + int eltId1=abs(*desc1)-1; + for(std::vector<int>::const_iterator it1=intesctEdges1[eltId1].begin();it1!=intesctEdges1[eltId1].end();it1++) + { + std::map<int,INTERP_KERNEL::Node *>::const_iterator it=mappRev.find(*it1); + if(it==mappRev.end()) + { + INTERP_KERNEL::Node *node=MEDCouplingUMeshBuildQPNode(*it1,coo1,offset1,coo2,offset2,addCoo); + mapp[node]=*it1; + mappRev[*it1]=node; + } + } + } + } +} + +/// @endcond + +template<int SPACEDIM> +void MEDCouplingUMesh::getCellsContainingPointsAlg(const double *coords, const double *pos, int nbOfPoints, + double eps, MEDCouplingAutoRefCountObjectPtr<DataArrayInt>& elts, MEDCouplingAutoRefCountObjectPtr<DataArrayInt>& eltsIndex) const +{ + elts=DataArrayInt::New(); eltsIndex=DataArrayInt::New(); eltsIndex->alloc(nbOfPoints+1,1); eltsIndex->setIJ(0,0,0); elts->alloc(0,1); + int *eltsIndexPtr(eltsIndex->getPointer()); + MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> bboxArr(getBoundingBoxForBBTree(eps)); + const double *bbox(bboxArr->begin()); + int nbOfCells=getNumberOfCells(); + const int *conn=_nodal_connec->getConstPointer(); + const int *connI=_nodal_connec_index->getConstPointer(); + double bb[2*SPACEDIM]; + BBTree<SPACEDIM,int> myTree(&bbox[0],0,0,nbOfCells,-eps); + for(int i=0;i<nbOfPoints;i++) + { + eltsIndexPtr[i+1]=eltsIndexPtr[i]; + for(int j=0;j<SPACEDIM;j++) + { + bb[2*j]=pos[SPACEDIM*i+j]; + bb[2*j+1]=pos[SPACEDIM*i+j]; + } + std::vector<int> candidates; + myTree.getIntersectingElems(bb,candidates); + for(std::vector<int>::const_iterator iter=candidates.begin();iter!=candidates.end();iter++) + { + int sz(connI[(*iter)+1]-connI[*iter]-1); + INTERP_KERNEL::NormalizedCellType ct((INTERP_KERNEL::NormalizedCellType)conn[connI[*iter]]); + bool status(false); + if(ct!=INTERP_KERNEL::NORM_POLYGON && ct!=INTERP_KERNEL::NORM_QPOLYG) + status=INTERP_KERNEL::PointLocatorAlgos<DummyClsMCUG<SPACEDIM> >::isElementContainsPoint(pos+i*SPACEDIM,ct,coords,conn+connI[*iter]+1,sz,eps); + else + { + if(SPACEDIM!=2) + throw INTERP_KERNEL::Exception("MEDCouplingUMesh::getCellsContainingPointsAlg : not implemented yet for POLYGON and QPOLYGON in spaceDim 3 !"); + INTERP_KERNEL::QUADRATIC_PLANAR::_precision=eps; + INTERP_KERNEL::QUADRATIC_PLANAR::_arc_detection_precision=eps; + std::vector<INTERP_KERNEL::Node *> nodes(sz); + INTERP_KERNEL::QuadraticPolygon *pol(0); + for(int j=0;j<sz;j++) + { + int nodeId(conn[connI[*iter]+1+j]); + nodes[j]=new INTERP_KERNEL::Node(coords[nodeId*SPACEDIM],coords[nodeId*SPACEDIM+1]); + } + if(!INTERP_KERNEL::CellModel::GetCellModel(ct).isQuadratic()) + pol=INTERP_KERNEL::QuadraticPolygon::BuildLinearPolygon(nodes); + else + pol=INTERP_KERNEL::QuadraticPolygon::BuildArcCirclePolygon(nodes); + INTERP_KERNEL::Node *n(new INTERP_KERNEL::Node(pos[i*SPACEDIM],pos[i*SPACEDIM+1])); + double a(0.),b(0.),c(0.); + a=pol->normalizeMe(b,c); n->applySimilarity(b,c,a); + status=pol->isInOrOut2(n); + delete pol; n->decrRef(); + } + if(status) + { + eltsIndexPtr[i+1]++; + elts->pushBackSilent(*iter); + } + } + } +} +/*! + * 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. + * For speed reasons, the INTERP_KERNEL::NORM_QUAD4, INTERP_KERNEL::NORM_TRI6 and INTERP_KERNEL::NORM_QUAD8 cells are considered as convex cells to detect if a point is IN or OUT. + * If it is not the case, please change their types to INTERP_KERNEL::NORM_POLYGON or INTERP_KERNEL::NORM_QPOLYG before invoking this method. + * \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 [out] elts - vector returning ids of found cells. + * \param [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* ]. + * \throw If the coordinates array is not set. + * \throw If \a this->getMeshDimension() != \a this->getSpaceDimension(). + * + * \if ENABLE_EXAMPLES + * \ref cpp_mcumesh_getCellsContainingPoints "Here is a C++ example".<br> + * \ref py_mcumesh_getCellsContainingPoints "Here is a Python example". + * \endif + */ +void MEDCouplingUMesh::getCellsContainingPoints(const double *pos, int nbOfPoints, double eps, + MEDCouplingAutoRefCountObjectPtr<DataArrayInt>& elts, MEDCouplingAutoRefCountObjectPtr<DataArrayInt>& eltsIndex) const +{ + int spaceDim=getSpaceDimension(); + int mDim=getMeshDimension(); + if(spaceDim==3) + { + if(mDim==3) + { + const double *coords=_coords->getConstPointer(); + getCellsContainingPointsAlg<3>(coords,pos,nbOfPoints,eps,elts,eltsIndex); + } + /*else if(mDim==2) + { + + }*/ + else + throw INTERP_KERNEL::Exception("For spaceDim==3 only meshDim==3 implemented for getelementscontainingpoints !"); + } + else if(spaceDim==2) + { + if(mDim==2) + { + const double *coords=_coords->getConstPointer(); + getCellsContainingPointsAlg<2>(coords,pos,nbOfPoints,eps,elts,eltsIndex); + } + else + throw INTERP_KERNEL::Exception("For spaceDim==2 only meshDim==2 implemented for getelementscontainingpoints !"); + } + else if(spaceDim==1) + { + if(mDim==1) + { + const double *coords=_coords->getConstPointer(); + getCellsContainingPointsAlg<1>(coords,pos,nbOfPoints,eps,elts,eltsIndex); + } + else + throw INTERP_KERNEL::Exception("For spaceDim==1 only meshDim==1 implemented for getelementscontainingpoints !"); + } + else + throw INTERP_KERNEL::Exception("MEDCouplingUMesh::getCellsContainingPoints : not managed for mdim not in [1,2,3] !"); +} + +/*! + * Finds butterfly cells in \a this mesh. A 2D cell is considered to be butterfly if at + * least two its edges intersect each other anywhere except their extremities. An + * INTERP_KERNEL::NORM_NORI3 cell can \b not be butterfly. + * \param [in,out] cells - a vector returning ids of the found cells. It is not + * cleared before filling in. + * \param [in] eps - precision. + * \throw If \a this->getMeshDimension() != 2. + * \throw If \a this->getSpaceDimension() != 2 && \a this->getSpaceDimension() != 3. + */ +void MEDCouplingUMesh::checkButterflyCells(std::vector<int>& cells, double eps) const +{ + const char msg[]="Butterfly detection work only for 2D cells with spaceDim==2 or 3!"; + if(getMeshDimension()!=2) + throw INTERP_KERNEL::Exception(msg); + int spaceDim=getSpaceDimension(); + if(spaceDim!=2 && spaceDim!=3) + throw INTERP_KERNEL::Exception(msg); + const int *conn=_nodal_connec->getConstPointer(); + const int *connI=_nodal_connec_index->getConstPointer(); + int nbOfCells=getNumberOfCells(); + std::vector<double> cell2DinS2; + for(int i=0;i<nbOfCells;i++) + { + int offset=connI[i]; + int nbOfNodesForCell=connI[i+1]-offset-1; + if(nbOfNodesForCell<=3) + continue; + bool isQuad=INTERP_KERNEL::CellModel::GetCellModel((INTERP_KERNEL::NormalizedCellType)conn[offset]).isQuadratic(); + project2DCellOnXY(conn+offset+1,conn+connI[i+1],cell2DinS2); + if(isButterfly2DCell(cell2DinS2,isQuad,eps)) + cells.push_back(i); + cell2DinS2.clear(); + } +} + +/*! + * This method is typically requested to unbutterfly 2D linear cells in \b this. + * + * This method expects that space dimension is equal to 2 and mesh dimension is equal to 2 too. If it is not the case an INTERP_KERNEL::Exception will be thrown. + * This method works only for linear 2D cells. If there is any of non linear cells (INTERP_KERNEL::NORM_QUAD8 for example) an INTERP_KERNEL::Exception will be thrown too. + * + * For each 2D linear cell in \b this, this method builds the convex envelop (or the convex hull) of the current cell. + * This convex envelop is computed using Jarvis march algorithm. + * The coordinates and the number of cells of \b this remain unchanged on invocation of this method. + * Only connectivity of some cells could be modified if those cells were not representing a convex envelop. If a cell already equals its convex envelop (regardless orientation) + * its connectivity will remain unchanged. If the computation leads to a modification of nodal connectivity of a cell its geometric type will be modified to INTERP_KERNEL::NORM_POLYGON. + * + * \return a newly allocated array containing cellIds that have been modified if any. If no cells have been impacted by this method NULL is returned. + * \sa MEDCouplingUMesh::colinearize2D + */ +DataArrayInt *MEDCouplingUMesh::convexEnvelop2D() +{ + if(getMeshDimension()!=2 || getSpaceDimension()!=2) + throw INTERP_KERNEL::Exception("MEDCouplingUMesh::convexEnvelop2D works only for meshDim=2 and spaceDim=2 !"); + checkFullyDefined(); + const double *coords=getCoords()->getConstPointer(); + int nbOfCells=getNumberOfCells(); + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> nodalConnecIndexOut=DataArrayInt::New(); + nodalConnecIndexOut->alloc(nbOfCells+1,1); + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> nodalConnecOut(DataArrayInt::New()); + int *workIndexOut=nodalConnecIndexOut->getPointer(); + *workIndexOut=0; + const int *nodalConnecIn=_nodal_connec->getConstPointer(); + const int *nodalConnecIndexIn=_nodal_connec_index->getConstPointer(); + std::set<INTERP_KERNEL::NormalizedCellType> types; + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> isChanged(DataArrayInt::New()); + isChanged->alloc(0,1); + for(int i=0;i<nbOfCells;i++,workIndexOut++) + { + int pos=nodalConnecOut->getNumberOfTuples(); + if(BuildConvexEnvelopOf2DCellJarvis(coords,nodalConnecIn+nodalConnecIndexIn[i],nodalConnecIn+nodalConnecIndexIn[i+1],nodalConnecOut)) + isChanged->pushBackSilent(i); + types.insert((INTERP_KERNEL::NormalizedCellType)nodalConnecOut->getIJ(pos,0)); + workIndexOut[1]=nodalConnecOut->getNumberOfTuples(); + } + if(isChanged->empty()) + return 0; + setConnectivity(nodalConnecOut,nodalConnecIndexOut,false); + _types=types; + return isChanged.retn(); +} + +/*! + * This method is \b NOT const because it can modify \a this. + * \a this is expected to be an unstructured mesh with meshDim==2 and spaceDim==3. If not an exception will be thrown. + * \param mesh1D is an unstructured mesh with MeshDim==1 and spaceDim==3. If not an exception will be thrown. + * \param policy specifies the type of extrusion chosen. \b 0 for translation (most simple), + * \b 1 for translation and rotation around point of 'mesh1D'. + * \return an unstructured mesh with meshDim==3 and spaceDim==3. The returned mesh has the same coords than \a this. + */ +MEDCouplingUMesh *MEDCouplingUMesh::buildExtrudedMesh(const MEDCouplingUMesh *mesh1D, int policy) +{ + checkFullyDefined(); + mesh1D->checkFullyDefined(); + if(!mesh1D->isContiguous1D()) + throw INTERP_KERNEL::Exception("buildExtrudedMesh : 1D mesh passed in parameter is not contiguous !"); + if(getSpaceDimension()!=mesh1D->getSpaceDimension()) + throw INTERP_KERNEL::Exception("Invalid call to buildExtrudedMesh this and mesh1D must have same space dimension !"); + if((getMeshDimension()!=2 || getSpaceDimension()!=3) && (getMeshDimension()!=1 || getSpaceDimension()!=2)) + throw INTERP_KERNEL::Exception("Invalid 'this' for buildExtrudedMesh method : must be (meshDim==2 and spaceDim==3) or (meshDim==1 and spaceDim==2) !"); + if(mesh1D->getMeshDimension()!=1) + throw INTERP_KERNEL::Exception("Invalid 'mesh1D' for buildExtrudedMesh method : must be meshDim==1 !"); + bool isQuad=false; + if(isPresenceOfQuadratic()) + { + if(mesh1D->isFullyQuadratic()) + isQuad=true; + else + throw INTERP_KERNEL::Exception("Invalid 2D mesh and 1D mesh because 2D mesh has quadratic cells and 1D is not fully quadratic !"); + } + int oldNbOfNodes(getNumberOfNodes()); + MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> newCoords; + switch(policy) + { + case 0: + { + newCoords=fillExtCoordsUsingTranslation(mesh1D,isQuad); + break; + } + case 1: + { + newCoords=fillExtCoordsUsingTranslAndAutoRotation(mesh1D,isQuad); + break; + } + default: + throw INTERP_KERNEL::Exception("Not implemented extrusion policy : must be in (0) !"); + } + setCoords(newCoords); + MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> ret(buildExtrudedMeshFromThisLowLev(oldNbOfNodes,isQuad)); + updateTime(); + return ret.retn(); +} + +/*! + * This method works on a 3D curve linear mesh that is to say (meshDim==1 and spaceDim==3). + * If it is not the case an exception will be thrown. + * This method is non const because the coordinate of \a this can be appended with some new points issued from + * intersection of plane defined by ('origin','vec'). + * This method has one in/out parameter : 'cut3DCurve'. + * Param 'cut3DCurve' is expected to be of size 'this->getNumberOfCells()'. For each i in [0,'this->getNumberOfCells()') + * if cut3DCurve[i]==-2, it means that for cell #i in \a this nothing has been detected previously. + * if cut3DCurve[i]==-1, it means that cell#i has been already detected to be fully part of plane defined by ('origin','vec'). + * This method will throw an exception if \a this contains a non linear segment. + */ +void MEDCouplingUMesh::split3DCurveWithPlane(const double *origin, const double *vec, double eps, std::vector<int>& cut3DCurve) +{ + checkFullyDefined(); + if(getMeshDimension()!=1 || getSpaceDimension()!=3) + throw INTERP_KERNEL::Exception("MEDCouplingUMesh::split3DCurveWithPlane works on umeshes with meshdim equal to 1 and spaceDim equal to 3 !"); + int ncells=getNumberOfCells(); + int nnodes=getNumberOfNodes(); + double vec2[3],vec3[3],vec4[3]; + double normm=sqrt(vec[0]*vec[0]+vec[1]*vec[1]+vec[2]*vec[2]); + if(normm<1e-6) + throw INTERP_KERNEL::Exception("MEDCouplingUMesh::split3DCurveWithPlane : parameter 'vec' should have a norm2 greater than 1e-6 !"); + vec2[0]=vec[0]/normm; vec2[1]=vec[1]/normm; vec2[2]=vec[2]/normm; + const int *conn=_nodal_connec->getConstPointer(); + const int *connI=_nodal_connec_index->getConstPointer(); + const double *coo=_coords->getConstPointer(); + std::vector<double> addCoo; + for(int i=0;i<ncells;i++) + { + if(conn[connI[i]]==(int)INTERP_KERNEL::NORM_SEG2) + { + if(cut3DCurve[i]==-2) + { + int st=conn[connI[i]+1],endd=conn[connI[i]+2]; + vec3[0]=coo[3*endd]-coo[3*st]; vec3[1]=coo[3*endd+1]-coo[3*st+1]; vec3[2]=coo[3*endd+2]-coo[3*st+2]; + double normm2=sqrt(vec3[0]*vec3[0]+vec3[1]*vec3[1]+vec3[2]*vec3[2]); + double colin=std::abs((vec3[0]*vec2[0]+vec3[1]*vec2[1]+vec3[2]*vec2[2])/normm2); + if(colin>eps)//if colin<=eps -> current SEG2 is colinear to the input plane + { + const double *st2=coo+3*st; + vec4[0]=st2[0]-origin[0]; vec4[1]=st2[1]-origin[1]; vec4[2]=st2[2]-origin[2]; + double pos=-(vec4[0]*vec2[0]+vec4[1]*vec2[1]+vec4[2]*vec2[2])/((vec3[0]*vec2[0]+vec3[1]*vec2[1]+vec3[2]*vec2[2])); + if(pos>eps && pos<1-eps) + { + int nNode=((int)addCoo.size())/3; + vec4[0]=st2[0]+pos*vec3[0]; vec4[1]=st2[1]+pos*vec3[1]; vec4[2]=st2[2]+pos*vec3[2]; + addCoo.insert(addCoo.end(),vec4,vec4+3); + cut3DCurve[i]=nnodes+nNode; + } + } + } + } + else + throw INTERP_KERNEL::Exception("MEDCouplingUMesh::split3DCurveWithPlane : this method is only available for linear cell (NORM_SEG2) !"); + } + if(!addCoo.empty()) + { + int newNbOfNodes=nnodes+((int)addCoo.size())/3; + MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> coo2=DataArrayDouble::New(); + coo2->alloc(newNbOfNodes,3); + double *tmp=coo2->getPointer(); + tmp=std::copy(_coords->begin(),_coords->end(),tmp); + std::copy(addCoo.begin(),addCoo.end(),tmp); + DataArrayDouble::SetArrayIn(coo2,_coords); + } +} + +/*! + * This method incarnates the policy 0 for MEDCouplingUMesh::buildExtrudedMesh method. + * \param mesh1D is the input 1D mesh used for translation computation. + * \return newCoords new coords filled by this method. + */ +DataArrayDouble *MEDCouplingUMesh::fillExtCoordsUsingTranslation(const MEDCouplingUMesh *mesh1D, bool isQuad) const +{ + int oldNbOfNodes=getNumberOfNodes(); + int nbOf1DCells=mesh1D->getNumberOfCells(); + int spaceDim=getSpaceDimension(); + DataArrayDouble *ret=DataArrayDouble::New(); + std::vector<bool> isQuads; + int nbOfLevsInVec=isQuad?2*nbOf1DCells+1:nbOf1DCells+1; + ret->alloc(oldNbOfNodes*nbOfLevsInVec,spaceDim); + double *retPtr=ret->getPointer(); + const double *coords=getCoords()->getConstPointer(); + double *work=std::copy(coords,coords+spaceDim*oldNbOfNodes,retPtr); + std::vector<int> v; + std::vector<double> c; + double vec[3]; + v.reserve(3); + c.reserve(6); + for(int i=0;i<nbOf1DCells;i++) + { + v.resize(0); + mesh1D->getNodeIdsOfCell(i,v); + c.resize(0); + mesh1D->getCoordinatesOfNode(v[isQuad?2:1],c); + mesh1D->getCoordinatesOfNode(v[0],c); + std::transform(c.begin(),c.begin()+spaceDim,c.begin()+spaceDim,vec,std::minus<double>()); + for(int j=0;j<oldNbOfNodes;j++) + work=std::transform(vec,vec+spaceDim,retPtr+spaceDim*(i*oldNbOfNodes+j),work,std::plus<double>()); + if(isQuad) + { + c.resize(0); + mesh1D->getCoordinatesOfNode(v[1],c); + mesh1D->getCoordinatesOfNode(v[0],c); + std::transform(c.begin(),c.begin()+spaceDim,c.begin()+spaceDim,vec,std::minus<double>()); + for(int j=0;j<oldNbOfNodes;j++) + work=std::transform(vec,vec+spaceDim,retPtr+spaceDim*(i*oldNbOfNodes+j),work,std::plus<double>()); + } + } + ret->copyStringInfoFrom(*getCoords()); + return ret; +} + +/*! + * This method incarnates the policy 1 for MEDCouplingUMesh::buildExtrudedMesh method. + * \param mesh1D is the input 1D mesh used for translation and automatic rotation computation. + * \return newCoords new coords filled by this method. + */ +DataArrayDouble *MEDCouplingUMesh::fillExtCoordsUsingTranslAndAutoRotation(const MEDCouplingUMesh *mesh1D, bool isQuad) const +{ + if(mesh1D->getSpaceDimension()==2) + return fillExtCoordsUsingTranslAndAutoRotation2D(mesh1D,isQuad); + if(mesh1D->getSpaceDimension()==3) + return fillExtCoordsUsingTranslAndAutoRotation3D(mesh1D,isQuad); + throw INTERP_KERNEL::Exception("Not implemented rotation and translation alg. for spacedim other than 2 and 3 !"); +} + +/*! + * This method incarnates the policy 1 for MEDCouplingUMesh::buildExtrudedMesh method. + * \param mesh1D is the input 1D mesh used for translation and automatic rotation computation. + * \return newCoords new coords filled by this method. + */ +DataArrayDouble *MEDCouplingUMesh::fillExtCoordsUsingTranslAndAutoRotation2D(const MEDCouplingUMesh *mesh1D, bool isQuad) const +{ + if(isQuad) + throw INTERP_KERNEL::Exception("MEDCouplingUMesh::fillExtCoordsUsingTranslAndAutoRotation2D : not implemented for quadratic cells !"); + int oldNbOfNodes=getNumberOfNodes(); + int nbOf1DCells=mesh1D->getNumberOfCells(); + if(nbOf1DCells<2) + throw INTERP_KERNEL::Exception("MEDCouplingUMesh::fillExtCoordsUsingTranslAndAutoRotation2D : impossible to detect any angle of rotation ! Change extrusion policy 1->0 !"); + MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New(); + int nbOfLevsInVec=nbOf1DCells+1; + ret->alloc(oldNbOfNodes*nbOfLevsInVec,2); + double *retPtr=ret->getPointer(); + retPtr=std::copy(getCoords()->getConstPointer(),getCoords()->getConstPointer()+getCoords()->getNbOfElems(),retPtr); + MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> tmp=MEDCouplingUMesh::New(); + MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> tmp2=getCoords()->deepCpy(); + tmp->setCoords(tmp2); + const double *coo1D=mesh1D->getCoords()->getConstPointer(); + const int *conn1D=mesh1D->getNodalConnectivity()->getConstPointer(); + const int *connI1D=mesh1D->getNodalConnectivityIndex()->getConstPointer(); + for(int i=1;i<nbOfLevsInVec;i++) + { + const double *begin=coo1D+2*conn1D[connI1D[i-1]+1]; + const double *end=coo1D+2*conn1D[connI1D[i-1]+2]; + const double *third=i+1<nbOfLevsInVec?coo1D+2*conn1D[connI1D[i]+2]:coo1D+2*conn1D[connI1D[i-2]+1]; + const double vec[2]={end[0]-begin[0],end[1]-begin[1]}; + tmp->translate(vec); + double tmp3[2],radius,alpha,alpha0; + const double *p0=i+1<nbOfLevsInVec?begin:third; + const double *p1=i+1<nbOfLevsInVec?end:begin; + const double *p2=i+1<nbOfLevsInVec?third:end; + INTERP_KERNEL::EdgeArcCircle::GetArcOfCirclePassingThru(p0,p1,p2,tmp3,radius,alpha,alpha0); + double cosangle=i+1<nbOfLevsInVec?(p0[0]-tmp3[0])*(p1[0]-tmp3[0])+(p0[1]-tmp3[1])*(p1[1]-tmp3[1]):(p2[0]-tmp3[0])*(p1[0]-tmp3[0])+(p2[1]-tmp3[1])*(p1[1]-tmp3[1]); + double angle=acos(cosangle/(radius*radius)); + tmp->rotate(end,0,angle); + retPtr=std::copy(tmp2->getConstPointer(),tmp2->getConstPointer()+tmp2->getNbOfElems(),retPtr); + } + return ret.retn(); +} + +/*! + * This method incarnates the policy 1 for MEDCouplingUMesh::buildExtrudedMesh method. + * \param mesh1D is the input 1D mesh used for translation and automatic rotation computation. + * \return newCoords new coords filled by this method. + */ +DataArrayDouble *MEDCouplingUMesh::fillExtCoordsUsingTranslAndAutoRotation3D(const MEDCouplingUMesh *mesh1D, bool isQuad) const +{ + if(isQuad) + throw INTERP_KERNEL::Exception("MEDCouplingUMesh::fillExtCoordsUsingTranslAndAutoRotation3D : not implemented for quadratic cells !"); + int oldNbOfNodes=getNumberOfNodes(); + int nbOf1DCells=mesh1D->getNumberOfCells(); + if(nbOf1DCells<2) + throw INTERP_KERNEL::Exception("MEDCouplingUMesh::fillExtCoordsUsingTranslAndAutoRotation3D : impossible to detect any angle of rotation ! Change extrusion policy 1->0 !"); + MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New(); + int nbOfLevsInVec=nbOf1DCells+1; + ret->alloc(oldNbOfNodes*nbOfLevsInVec,3); + double *retPtr=ret->getPointer(); + retPtr=std::copy(getCoords()->getConstPointer(),getCoords()->getConstPointer()+getCoords()->getNbOfElems(),retPtr); + MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> tmp=MEDCouplingUMesh::New(); + MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> tmp2=getCoords()->deepCpy(); + tmp->setCoords(tmp2); + const double *coo1D=mesh1D->getCoords()->getConstPointer(); + const int *conn1D=mesh1D->getNodalConnectivity()->getConstPointer(); + const int *connI1D=mesh1D->getNodalConnectivityIndex()->getConstPointer(); + for(int i=1;i<nbOfLevsInVec;i++) + { + const double *begin=coo1D+3*conn1D[connI1D[i-1]+1]; + const double *end=coo1D+3*conn1D[connI1D[i-1]+2]; + const double *third=i+1<nbOfLevsInVec?coo1D+3*conn1D[connI1D[i]+2]:coo1D+3*conn1D[connI1D[i-2]+1]; + const double vec[3]={end[0]-begin[0],end[1]-begin[1],end[2]-begin[2]}; + tmp->translate(vec); + double tmp3[2],radius,alpha,alpha0; + const double *p0=i+1<nbOfLevsInVec?begin:third; + const double *p1=i+1<nbOfLevsInVec?end:begin; + const double *p2=i+1<nbOfLevsInVec?third:end; + double vecPlane[3]={ + (p1[1]-p0[1])*(p2[2]-p1[2])-(p1[2]-p0[2])*(p2[1]-p1[1]), + (p1[2]-p0[2])*(p2[0]-p1[0])-(p1[0]-p0[0])*(p2[2]-p1[2]), + (p1[0]-p0[0])*(p2[1]-p1[1])-(p1[1]-p0[1])*(p2[0]-p1[0]), + }; + double norm=sqrt(vecPlane[0]*vecPlane[0]+vecPlane[1]*vecPlane[1]+vecPlane[2]*vecPlane[2]); + if(norm>1.e-7) + { + vecPlane[0]/=norm; vecPlane[1]/=norm; vecPlane[2]/=norm; + double norm2=sqrt(vecPlane[0]*vecPlane[0]+vecPlane[1]*vecPlane[1]); + double vec2[2]={vecPlane[1]/norm2,-vecPlane[0]/norm2}; + double s2=norm2; + double c2=cos(asin(s2)); + double m[3][3]={ + {vec2[0]*vec2[0]*(1-c2)+c2, vec2[0]*vec2[1]*(1-c2), vec2[1]*s2}, + {vec2[0]*vec2[1]*(1-c2), vec2[1]*vec2[1]*(1-c2)+c2, -vec2[0]*s2}, + {-vec2[1]*s2, vec2[0]*s2, c2} + }; + double p0r[3]={m[0][0]*p0[0]+m[0][1]*p0[1]+m[0][2]*p0[2], m[1][0]*p0[0]+m[1][1]*p0[1]+m[1][2]*p0[2], m[2][0]*p0[0]+m[2][1]*p0[1]+m[2][2]*p0[2]}; + double p1r[3]={m[0][0]*p1[0]+m[0][1]*p1[1]+m[0][2]*p1[2], m[1][0]*p1[0]+m[1][1]*p1[1]+m[1][2]*p1[2], m[2][0]*p1[0]+m[2][1]*p1[1]+m[2][2]*p1[2]}; + double p2r[3]={m[0][0]*p2[0]+m[0][1]*p2[1]+m[0][2]*p2[2], m[1][0]*p2[0]+m[1][1]*p2[1]+m[1][2]*p2[2], m[2][0]*p2[0]+m[2][1]*p2[1]+m[2][2]*p2[2]}; + INTERP_KERNEL::EdgeArcCircle::GetArcOfCirclePassingThru(p0r,p1r,p2r,tmp3,radius,alpha,alpha0); + double cosangle=i+1<nbOfLevsInVec?(p0r[0]-tmp3[0])*(p1r[0]-tmp3[0])+(p0r[1]-tmp3[1])*(p1r[1]-tmp3[1]):(p2r[0]-tmp3[0])*(p1r[0]-tmp3[0])+(p2r[1]-tmp3[1])*(p1r[1]-tmp3[1]); + double angle=acos(cosangle/(radius*radius)); + tmp->rotate(end,vecPlane,angle); + } + retPtr=std::copy(tmp2->getConstPointer(),tmp2->getConstPointer()+tmp2->getNbOfElems(),retPtr); + } + return ret.retn(); +} + +/*! + * This method is private because not easy to use for end user. This method is const contrary to + * MEDCouplingUMesh::buildExtrudedMesh method because this->_coords are expected to contain + * the coords sorted slice by slice. + * \param isQuad specifies presence of quadratic cells. + */ +MEDCouplingUMesh *MEDCouplingUMesh::buildExtrudedMeshFromThisLowLev(int nbOfNodesOf1Lev, bool isQuad) const +{ + int nbOf1DCells(getNumberOfNodes()/nbOfNodesOf1Lev-1); + int nbOf2DCells(getNumberOfCells()); + int nbOf3DCells(nbOf2DCells*nbOf1DCells); + MEDCouplingUMesh *ret(MEDCouplingUMesh::New("Extruded",getMeshDimension()+1)); + const int *conn(_nodal_connec->begin()),*connI(_nodal_connec_index->begin()); + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> newConn(DataArrayInt::New()),newConnI(DataArrayInt::New()); + newConnI->alloc(nbOf3DCells+1,1); + int *newConnIPtr(newConnI->getPointer()); + *newConnIPtr++=0; + std::vector<int> newc; + for(int j=0;j<nbOf2DCells;j++) + { + AppendExtrudedCell(conn+connI[j],conn+connI[j+1],nbOfNodesOf1Lev,isQuad,newc); + *newConnIPtr++=(int)newc.size(); + } + newConn->alloc((int)(newc.size())*nbOf1DCells,1); + int *newConnPtr(newConn->getPointer()); + int deltaPerLev(isQuad?2*nbOfNodesOf1Lev:nbOfNodesOf1Lev); + newConnIPtr=newConnI->getPointer(); + for(int iz=0;iz<nbOf1DCells;iz++) + { + if(iz!=0) + std::transform(newConnIPtr+1,newConnIPtr+1+nbOf2DCells,newConnIPtr+1+iz*nbOf2DCells,std::bind2nd(std::plus<int>(),newConnIPtr[iz*nbOf2DCells])); + const int *posOfTypeOfCell(newConnIPtr); + for(std::vector<int>::const_iterator iter=newc.begin();iter!=newc.end();iter++,newConnPtr++) + { + int icell((int)(iter-newc.begin()));//std::distance unfortunately cannot been called here in C++98 + if(icell!=*posOfTypeOfCell) + { + if(*iter!=-1) + *newConnPtr=(*iter)+iz*deltaPerLev; + else + *newConnPtr=-1; + } + else + { + *newConnPtr=*iter; + posOfTypeOfCell++; + } + } + } + ret->setConnectivity(newConn,newConnI,true); + ret->setCoords(getCoords()); + return ret; +} + +/*! + * Checks if \a this mesh is constituted by only quadratic cells. + * \return bool - \c true if there are only quadratic cells in \a this mesh. + * \throw If the coordinates array is not set. + * \throw If the nodal connectivity of cells is not defined. + */ +bool MEDCouplingUMesh::isFullyQuadratic() const +{ + checkFullyDefined(); + bool ret=true; + int nbOfCells=getNumberOfCells(); + for(int i=0;i<nbOfCells && ret;i++) + { + INTERP_KERNEL::NormalizedCellType type=getTypeOfCell(i); + const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(type); + ret=cm.isQuadratic(); + } + return ret; +} + +/*! + * Checks if \a this mesh includes any quadratic cell. + * \return bool - \c true if there is at least one quadratic cells in \a this mesh. + * \throw If the coordinates array is not set. + * \throw If the nodal connectivity of cells is not defined. + */ +bool MEDCouplingUMesh::isPresenceOfQuadratic() const +{ + checkFullyDefined(); + bool ret=false; + int nbOfCells=getNumberOfCells(); + for(int i=0;i<nbOfCells && !ret;i++) + { + INTERP_KERNEL::NormalizedCellType type=getTypeOfCell(i); + const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(type); + ret=cm.isQuadratic(); + } + return ret; +} + +/*! + * Converts all quadratic cells to linear ones. If there are no quadratic cells in \a + * this mesh, it remains unchanged. + * \throw If the coordinates array is not set. + * \throw If the nodal connectivity of cells is not defined. + */ +void MEDCouplingUMesh::convertQuadraticCellsToLinear() +{ + checkFullyDefined(); + int nbOfCells=getNumberOfCells(); + int delta=0; + const int *iciptr=_nodal_connec_index->getConstPointer(); + for(int i=0;i<nbOfCells;i++) + { + INTERP_KERNEL::NormalizedCellType type=getTypeOfCell(i); + const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(type); + if(cm.isQuadratic()) + { + INTERP_KERNEL::NormalizedCellType typel=cm.getLinearType(); + const INTERP_KERNEL::CellModel& cml=INTERP_KERNEL::CellModel::GetCellModel(typel); + if(!cml.isDynamic()) + delta+=cm.getNumberOfNodes()-cml.getNumberOfNodes(); + else + delta+=(iciptr[i+1]-iciptr[i]-1)/2; + } + } + if(delta==0) + return ; + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> newConn=DataArrayInt::New(); + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> newConnI=DataArrayInt::New(); + const int *icptr=_nodal_connec->getConstPointer(); + newConn->alloc(getMeshLength()-delta,1); + newConnI->alloc(nbOfCells+1,1); + int *ocptr=newConn->getPointer(); + int *ociptr=newConnI->getPointer(); + *ociptr=0; + _types.clear(); + for(int i=0;i<nbOfCells;i++,ociptr++) + { + INTERP_KERNEL::NormalizedCellType type=(INTERP_KERNEL::NormalizedCellType)icptr[iciptr[i]]; + const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(type); + if(!cm.isQuadratic()) + { + _types.insert(type); + ocptr=std::copy(icptr+iciptr[i],icptr+iciptr[i+1],ocptr); + ociptr[1]=ociptr[0]+iciptr[i+1]-iciptr[i]; + } + else + { + INTERP_KERNEL::NormalizedCellType typel=cm.getLinearType(); + _types.insert(typel); + const INTERP_KERNEL::CellModel& cml=INTERP_KERNEL::CellModel::GetCellModel(typel); + int newNbOfNodes=cml.getNumberOfNodes(); + if(cml.isDynamic()) + newNbOfNodes=(iciptr[i+1]-iciptr[i]-1)/2; + *ocptr++=(int)typel; + ocptr=std::copy(icptr+iciptr[i]+1,icptr+iciptr[i]+newNbOfNodes+1,ocptr); + ociptr[1]=ociptr[0]+newNbOfNodes+1; + } + } + setConnectivity(newConn,newConnI,false); +} + +/*! + * This method converts all linear cell in \a this to quadratic one. + * Contrary to MEDCouplingUMesh::convertQuadraticCellsToLinear method, here it is needed to specify the target + * type of cells expected. For example INTERP_KERNEL::NORM_TRI3 can be converted to INTERP_KERNEL::NORM_TRI6 if \a conversionType is equal to 0 (the default) + * or to INTERP_KERNEL::NORM_TRI7 if \a conversionType is equal to 1. All non linear cells and polyhedron in \a this are let untouched. + * Contrary to MEDCouplingUMesh::convertQuadraticCellsToLinear method, the coordinates in \a this can be become bigger. All created nodes will be put at the + * end of the existing coordinates. + * + * \param [in] conversionType specifies the type of conversion expected. Only 0 (default) and 1 are supported presently. 0 those that creates the 'most' simple + * corresponding quadratic cells. 1 is those creating the 'most' complex. + * \return a newly created DataArrayInt instance that the caller should deal with containing cell ids of converted cells. + * + * \throw if \a this is not fully defined. It throws too if \a conversionType is not in [0,1]. + * + * \sa MEDCouplingUMesh::convertQuadraticCellsToLinear + */ +DataArrayInt *MEDCouplingUMesh::convertLinearCellsToQuadratic(int conversionType) +{ + DataArrayInt *conn=0,*connI=0; + DataArrayDouble *coords=0; + std::set<INTERP_KERNEL::NormalizedCellType> types; + checkFullyDefined(); + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret,connSafe,connISafe; + MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> coordsSafe; + int meshDim=getMeshDimension(); + switch(conversionType) + { + case 0: + switch(meshDim) + { + case 1: + ret=convertLinearCellsToQuadratic1D0(conn,connI,coords,types); + connSafe=conn; connISafe=connI; coordsSafe=coords; + break; + case 2: + ret=convertLinearCellsToQuadratic2D0(conn,connI,coords,types); + connSafe=conn; connISafe=connI; coordsSafe=coords; + break; + case 3: + ret=convertLinearCellsToQuadratic3D0(conn,connI,coords,types); + connSafe=conn; connISafe=connI; coordsSafe=coords; + break; + default: + throw INTERP_KERNEL::Exception("MEDCouplingUMesh::convertLinearCellsToQuadratic : conversion of type 0 mesh dimensions available are [1,2,3] !"); + } + break; + case 1: + { + switch(meshDim) + { + case 1: + ret=convertLinearCellsToQuadratic1D0(conn,connI,coords,types);//it is not a bug. In 1D policy 0 and 1 are equals + connSafe=conn; connISafe=connI; coordsSafe=coords; + break; + case 2: + ret=convertLinearCellsToQuadratic2D1(conn,connI,coords,types); + connSafe=conn; connISafe=connI; coordsSafe=coords; + break; + case 3: + ret=convertLinearCellsToQuadratic3D1(conn,connI,coords,types); + connSafe=conn; connISafe=connI; coordsSafe=coords; + break; + default: + throw INTERP_KERNEL::Exception("MEDCouplingUMesh::convertLinearCellsToQuadratic : conversion of type 1 mesh dimensions available are [1,2,3] !"); + } + break; + } + default: + throw INTERP_KERNEL::Exception("MEDCouplingUMesh::convertLinearCellsToQuadratic : conversion type available are 0 (default, the simplest) and 1 (the most complex) !"); + } + setConnectivity(connSafe,connISafe,false); + _types=types; + setCoords(coordsSafe); + return ret.retn(); +} + +#if 0 +/*! + * This method only works if \a this has spaceDimension equal to 2 and meshDimension also equal to 2. + * This method allows to modify connectivity of cells in \a this that shares some edges in \a edgeIdsToBeSplit. + * The nodes to be added in those 2D cells are defined by the pair of \a nodeIdsToAdd and \a nodeIdsIndexToAdd. + * Length of \a nodeIdsIndexToAdd is expected to equal to length of \a edgeIdsToBeSplit + 1. + * The node ids in \a nodeIdsToAdd should be valid. Those nodes have to be sorted exactly following exactly the direction of the edge. + * This method can be seen as the opposite method of colinearize2D. + * This method can be lead to create some new nodes if quadratic polygon cells have to be split. In this case the added nodes will be put at the end + * to avoid to modify the numbering of existing nodes. + * + * \param [in] nodeIdsToAdd - the list of node ids to be added (\a nodeIdsIndexToAdd array allows to walk on this array) + * \param [in] nodeIdsIndexToAdd - the entry point of \a nodeIdsToAdd to point to the corresponding nodes to be added. + * \param [in] mesh1Desc - 1st output of buildDescendingConnectivity2 on \a this. + * \param [in] desc - 2nd output of buildDescendingConnectivity2 on \a this. + * \param [in] descI - 3rd output of buildDescendingConnectivity2 on \a this. + * \param [in] revDesc - 4th output of buildDescendingConnectivity2 on \a this. + * \param [in] revDescI - 5th output of buildDescendingConnectivity2 on \a this. + * + * \sa buildDescendingConnectivity2 + */ +void MEDCouplingUMesh::splitSomeEdgesOf2DMesh(const DataArrayInt *nodeIdsToAdd, const DataArrayInt *nodeIdsIndexToAdd, const DataArrayInt *edgeIdsToBeSplit, + const MEDCouplingUMesh *mesh1Desc, const DataArrayInt *desc, const DataArrayInt *descI, const DataArrayInt *revDesc, const DataArrayInt *revDescI) +{ + if(!nodeIdsToAdd || !nodeIdsIndexToAdd || !edgeIdsToBeSplit || !mesh1Desc || !desc || !descI || !revDesc || !revDescI) + throw INTERP_KERNEL::Exception("MEDCouplingUMesh::splitSomeEdgesOf2DMesh : input pointers must be not NULL !"); + nodeIdsToAdd->checkAllocated(); nodeIdsIndexToAdd->checkAllocated(); edgeIdsToBeSplit->checkAllocated(); desc->checkAllocated(); descI->checkAllocated(); revDesc->checkAllocated(); revDescI->checkAllocated(); + if(getSpaceDimension()!=2 || getMeshDimension()!=2) + throw INTERP_KERNEL::Exception("MEDCouplingUMesh::splitSomeEdgesOf2DMesh : this must have spacedim=meshdim=2 !"); + if(mesh1Desc->getSpaceDimension()!=2 || mesh1Desc->getMeshDimension()!=1) + throw INTERP_KERNEL::Exception("MEDCouplingUMesh::splitSomeEdgesOf2DMesh : mesh1Desc must be the explosion of this with spaceDim=2 and meshDim = 1 !"); + //DataArrayInt *out0(0),*outi0(0); + //MEDCouplingUMesh::ExtractFromIndexedArrays(idsInDesc2DToBeRefined->begin(),idsInDesc2DToBeRefined->end(),dd3,dd4,out0,outi0); + //MEDCouplingAutoRefCountObjectPtr<DataArrayInt> out0s(out0),outi0s(outi0); + //out0s=out0s->buildUnique(); out0s->sort(true); +} +#endif + +/*! + * Implementes \a conversionType 0 for meshes with meshDim = 1, of MEDCouplingUMesh::convertLinearCellsToQuadratic method. + * \return a newly created DataArrayInt instance that the caller should deal with containing cell ids of converted cells. + * \sa MEDCouplingUMesh::convertLinearCellsToQuadratic. + */ +DataArrayInt *MEDCouplingUMesh::convertLinearCellsToQuadratic1D0(DataArrayInt *&conn, DataArrayInt *&connI, DataArrayDouble *& coords, std::set<INTERP_KERNEL::NormalizedCellType>& types) const +{ + MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> bary=getBarycenterAndOwner(); + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> newConn=DataArrayInt::New(); newConn->alloc(0,1); + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> newConnI=DataArrayInt::New(); newConnI->alloc(1,1); newConnI->setIJ(0,0,0); + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(0,1); + int nbOfCells=getNumberOfCells(); + int nbOfNodes=getNumberOfNodes(); + const int *cPtr=_nodal_connec->getConstPointer(); + const int *icPtr=_nodal_connec_index->getConstPointer(); + int lastVal=0,offset=nbOfNodes; + for(int i=0;i<nbOfCells;i++,icPtr++) + { + INTERP_KERNEL::NormalizedCellType type=(INTERP_KERNEL::NormalizedCellType)cPtr[*icPtr]; + if(type==INTERP_KERNEL::NORM_SEG2) + { + types.insert(INTERP_KERNEL::NORM_SEG3); + newConn->pushBackSilent((int)INTERP_KERNEL::NORM_SEG3); + newConn->pushBackValsSilent(cPtr+icPtr[0]+1,cPtr+icPtr[0]+3); + newConn->pushBackSilent(offset++); + lastVal+=4; + newConnI->pushBackSilent(lastVal); + ret->pushBackSilent(i); + } + else + { + types.insert(type); + lastVal+=(icPtr[1]-icPtr[0]); + newConnI->pushBackSilent(lastVal); + newConn->pushBackValsSilent(cPtr+icPtr[0],cPtr+icPtr[1]); + } + } + MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> tmp=bary->selectByTupleIdSafe(ret->begin(),ret->end()); + coords=DataArrayDouble::Aggregate(getCoords(),tmp); conn=newConn.retn(); connI=newConnI.retn(); + return ret.retn(); +} + +DataArrayInt *MEDCouplingUMesh::convertLinearCellsToQuadratic2DAnd3D0(const MEDCouplingUMesh *m1D, const DataArrayInt *desc, const DataArrayInt *descI, DataArrayInt *&conn, DataArrayInt *&connI, DataArrayDouble *& coords, std::set<INTERP_KERNEL::NormalizedCellType>& types) const +{ + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> newConn=DataArrayInt::New(); newConn->alloc(0,1); + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> newConnI=DataArrayInt::New(); newConnI->alloc(1,1); newConnI->setIJ(0,0,0); + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(0,1); + // + const int *descPtr(desc->begin()),*descIPtr(descI->begin()); + DataArrayInt *conn1D=0,*conn1DI=0; + std::set<INTERP_KERNEL::NormalizedCellType> types1D; + DataArrayDouble *coordsTmp=0; + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret1D=m1D->convertLinearCellsToQuadratic1D0(conn1D,conn1DI,coordsTmp,types1D); ret1D=0; + MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> coordsTmpSafe(coordsTmp); + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> conn1DSafe(conn1D),conn1DISafe(conn1DI); + const int *c1DPtr=conn1D->begin(); + const int *c1DIPtr=conn1DI->begin(); + int nbOfCells=getNumberOfCells(); + const int *cPtr=_nodal_connec->getConstPointer(); + const int *icPtr=_nodal_connec_index->getConstPointer(); + int lastVal=0; + for(int i=0;i<nbOfCells;i++,icPtr++,descIPtr++) + { + INTERP_KERNEL::NormalizedCellType typ=(INTERP_KERNEL::NormalizedCellType)cPtr[*icPtr]; + const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(typ); + if(!cm.isQuadratic()) + { + INTERP_KERNEL::NormalizedCellType typ2=cm.getQuadraticType(); + types.insert(typ2); newConn->pushBackSilent(typ2); + newConn->pushBackValsSilent(cPtr+icPtr[0]+1,cPtr+icPtr[1]); + for(const int *d=descPtr+descIPtr[0];d!=descPtr+descIPtr[1];d++) + newConn->pushBackSilent(c1DPtr[c1DIPtr[*d]+3]); + lastVal+=(icPtr[1]-icPtr[0])+(descIPtr[1]-descIPtr[0]); + newConnI->pushBackSilent(lastVal); + ret->pushBackSilent(i); + } + else + { + types.insert(typ); + lastVal+=(icPtr[1]-icPtr[0]); + newConnI->pushBackSilent(lastVal); + newConn->pushBackValsSilent(cPtr+icPtr[0],cPtr+icPtr[1]); + } + } + conn=newConn.retn(); connI=newConnI.retn(); coords=coordsTmpSafe.retn(); + return ret.retn(); +} + +/*! + * Implementes \a conversionType 0 for meshes with meshDim = 2, of MEDCouplingUMesh::convertLinearCellsToQuadratic method. + * \return a newly created DataArrayInt instance that the caller should deal with containing cell ids of converted cells. + * \sa MEDCouplingUMesh::convertLinearCellsToQuadratic. + */ +DataArrayInt *MEDCouplingUMesh::convertLinearCellsToQuadratic2D0(DataArrayInt *&conn, DataArrayInt *&connI, DataArrayDouble *& coords, std::set<INTERP_KERNEL::NormalizedCellType>& types) const +{ + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> desc(DataArrayInt::New()),descI(DataArrayInt::New()),tmp2(DataArrayInt::New()),tmp3(DataArrayInt::New()); + MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m1D=buildDescendingConnectivity(desc,descI,tmp2,tmp3); tmp2=0; tmp3=0; + return convertLinearCellsToQuadratic2DAnd3D0(m1D,desc,descI,conn,connI,coords,types); +} + +DataArrayInt *MEDCouplingUMesh::convertLinearCellsToQuadratic2D1(DataArrayInt *&conn, DataArrayInt *&connI, DataArrayDouble *& coords, std::set<INTERP_KERNEL::NormalizedCellType>& types) const +{ + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> desc(DataArrayInt::New()),descI(DataArrayInt::New()),tmp2(DataArrayInt::New()),tmp3(DataArrayInt::New()); + MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m1D=buildDescendingConnectivity(desc,descI,tmp2,tmp3); tmp2=0; tmp3=0; + // + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> newConn=DataArrayInt::New(); newConn->alloc(0,1); + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> newConnI=DataArrayInt::New(); newConnI->alloc(1,1); newConnI->setIJ(0,0,0); + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(0,1); + // + MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> bary=getBarycenterAndOwner(); + const int *descPtr(desc->begin()),*descIPtr(descI->begin()); + DataArrayInt *conn1D=0,*conn1DI=0; + std::set<INTERP_KERNEL::NormalizedCellType> types1D; + DataArrayDouble *coordsTmp=0; + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret1D=m1D->convertLinearCellsToQuadratic1D0(conn1D,conn1DI,coordsTmp,types1D); ret1D=0; + MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> coordsTmpSafe(coordsTmp); + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> conn1DSafe(conn1D),conn1DISafe(conn1DI); + const int *c1DPtr=conn1D->begin(); + const int *c1DIPtr=conn1DI->begin(); + int nbOfCells=getNumberOfCells(); + const int *cPtr=_nodal_connec->getConstPointer(); + const int *icPtr=_nodal_connec_index->getConstPointer(); + int lastVal=0,offset=coordsTmpSafe->getNumberOfTuples(); + for(int i=0;i<nbOfCells;i++,icPtr++,descIPtr++) + { + INTERP_KERNEL::NormalizedCellType typ=(INTERP_KERNEL::NormalizedCellType)cPtr[*icPtr]; + const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(typ); + if(!cm.isQuadratic()) + { + INTERP_KERNEL::NormalizedCellType typ2=cm.getQuadraticType2(); + types.insert(typ2); newConn->pushBackSilent(typ2); + newConn->pushBackValsSilent(cPtr+icPtr[0]+1,cPtr+icPtr[1]); + for(const int *d=descPtr+descIPtr[0];d!=descPtr+descIPtr[1];d++) + newConn->pushBackSilent(c1DPtr[c1DIPtr[*d]+3]); + newConn->pushBackSilent(offset+ret->getNumberOfTuples()); + lastVal+=(icPtr[1]-icPtr[0])+(descIPtr[1]-descIPtr[0])+1; + newConnI->pushBackSilent(lastVal); + ret->pushBackSilent(i); + } + else + { + types.insert(typ); + lastVal+=(icPtr[1]-icPtr[0]); + newConnI->pushBackSilent(lastVal); + newConn->pushBackValsSilent(cPtr+icPtr[0],cPtr+icPtr[1]); + } + } + MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> tmp=bary->selectByTupleIdSafe(ret->begin(),ret->end()); + coords=DataArrayDouble::Aggregate(coordsTmpSafe,tmp); conn=newConn.retn(); connI=newConnI.retn(); + return ret.retn(); +} + +/*! + * Implementes \a conversionType 0 for meshes with meshDim = 3, of MEDCouplingUMesh::convertLinearCellsToQuadratic method. + * \return a newly created DataArrayInt instance that the caller should deal with containing cell ids of converted cells. + * \sa MEDCouplingUMesh::convertLinearCellsToQuadratic. + */ +DataArrayInt *MEDCouplingUMesh::convertLinearCellsToQuadratic3D0(DataArrayInt *&conn, DataArrayInt *&connI, DataArrayDouble *& coords, std::set<INTERP_KERNEL::NormalizedCellType>& types) const +{ + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> desc(DataArrayInt::New()),descI(DataArrayInt::New()),tmp2(DataArrayInt::New()),tmp3(DataArrayInt::New()); + MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m1D=explode3DMeshTo1D(desc,descI,tmp2,tmp3); tmp2=0; tmp3=0; + return convertLinearCellsToQuadratic2DAnd3D0(m1D,desc,descI,conn,connI,coords,types); +} + +DataArrayInt *MEDCouplingUMesh::convertLinearCellsToQuadratic3D1(DataArrayInt *&conn, DataArrayInt *&connI, DataArrayDouble *& coords, std::set<INTERP_KERNEL::NormalizedCellType>& types) const +{ + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> desc2(DataArrayInt::New()),desc2I(DataArrayInt::New()),tmp2(DataArrayInt::New()),tmp3(DataArrayInt::New()); + MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m2D=buildDescendingConnectivityGen<MinusOneSonsGeneratorBiQuadratic>(desc2,desc2I,tmp2,tmp3,MEDCouplingFastNbrer); tmp2=0; tmp3=0; + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> desc1(DataArrayInt::New()),desc1I(DataArrayInt::New()),tmp4(DataArrayInt::New()),tmp5(DataArrayInt::New()); + MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m1D=explode3DMeshTo1D(desc1,desc1I,tmp4,tmp5); tmp4=0; tmp5=0; + // + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> newConn=DataArrayInt::New(); newConn->alloc(0,1); + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> newConnI=DataArrayInt::New(); newConnI->alloc(1,1); newConnI->setIJ(0,0,0); + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New(),ret2=DataArrayInt::New(); ret->alloc(0,1); ret2->alloc(0,1); + // + MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> bary=getBarycenterAndOwner(); + const int *descPtr(desc1->begin()),*descIPtr(desc1I->begin()),*desc2Ptr(desc2->begin()),*desc2IPtr(desc2I->begin()); + DataArrayInt *conn1D=0,*conn1DI=0,*conn2D=0,*conn2DI=0; + std::set<INTERP_KERNEL::NormalizedCellType> types1D,types2D; + DataArrayDouble *coordsTmp=0,*coordsTmp2=0; + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret1D=m1D->convertLinearCellsToQuadratic1D0(conn1D,conn1DI,coordsTmp,types1D); ret1D=DataArrayInt::New(); ret1D->alloc(0,1); + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> conn1DSafe(conn1D),conn1DISafe(conn1DI); + MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> coordsTmpSafe(coordsTmp); + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret2D=m2D->convertLinearCellsToQuadratic2D1(conn2D,conn2DI,coordsTmp2,types2D); ret2D=DataArrayInt::New(); ret2D->alloc(0,1); + MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> coordsTmp2Safe(coordsTmp2); + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> conn2DSafe(conn2D),conn2DISafe(conn2DI); + const int *c1DPtr=conn1D->begin(),*c1DIPtr=conn1DI->begin(),*c2DPtr=conn2D->begin(),*c2DIPtr=conn2DI->begin(); + int nbOfCells=getNumberOfCells(); + const int *cPtr=_nodal_connec->getConstPointer(); + const int *icPtr=_nodal_connec_index->getConstPointer(); + int lastVal=0,offset=coordsTmpSafe->getNumberOfTuples(); + for(int i=0;i<nbOfCells;i++,icPtr++,descIPtr++,desc2IPtr++) + { + INTERP_KERNEL::NormalizedCellType typ=(INTERP_KERNEL::NormalizedCellType)cPtr[*icPtr]; + const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(typ); + if(!cm.isQuadratic()) + { + INTERP_KERNEL::NormalizedCellType typ2=cm.getQuadraticType2(); + if(typ2==INTERP_KERNEL::NORM_ERROR) + { + std::ostringstream oss; oss << "MEDCouplingUMesh::convertLinearCellsToQuadratic3D1 : On cell #" << i << " the linear cell type does not support advanced quadratization !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + types.insert(typ2); newConn->pushBackSilent(typ2); + newConn->pushBackValsSilent(cPtr+icPtr[0]+1,cPtr+icPtr[1]); + for(const int *d=descPtr+descIPtr[0];d!=descPtr+descIPtr[1];d++) + newConn->pushBackSilent(c1DPtr[c1DIPtr[*d]+3]); + for(const int *d=desc2Ptr+desc2IPtr[0];d!=desc2Ptr+desc2IPtr[1];d++) + { + int nodeId2=c2DPtr[c2DIPtr[(*d)+1]-1]; + int tmpPos=newConn->getNumberOfTuples(); + newConn->pushBackSilent(nodeId2); + ret2D->pushBackSilent(nodeId2); ret1D->pushBackSilent(tmpPos); + } + newConn->pushBackSilent(offset+ret->getNumberOfTuples()); + lastVal+=(icPtr[1]-icPtr[0])+(descIPtr[1]-descIPtr[0])+(desc2IPtr[1]-desc2IPtr[0])+1; + newConnI->pushBackSilent(lastVal); + ret->pushBackSilent(i); + } + else + { + types.insert(typ); + lastVal+=(icPtr[1]-icPtr[0]); + newConnI->pushBackSilent(lastVal); + newConn->pushBackValsSilent(cPtr+icPtr[0],cPtr+icPtr[1]); + } + } + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> diffRet2D=ret2D->getDifferentValues(); + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> o2nRet2D=diffRet2D->invertArrayN2O2O2N(coordsTmp2Safe->getNumberOfTuples()); + coordsTmp2Safe=coordsTmp2Safe->selectByTupleId(diffRet2D->begin(),diffRet2D->end()); + MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> tmp=bary->selectByTupleIdSafe(ret->begin(),ret->end()); + std::vector<const DataArrayDouble *> v(3); v[0]=coordsTmpSafe; v[1]=coordsTmp2Safe; v[2]=tmp; + int *c=newConn->getPointer(); + const int *cI(newConnI->begin()); + for(const int *elt=ret1D->begin();elt!=ret1D->end();elt++) + c[*elt]=o2nRet2D->getIJ(c[*elt],0)+offset; + offset=coordsTmp2Safe->getNumberOfTuples(); + for(const int *elt=ret->begin();elt!=ret->end();elt++) + c[cI[(*elt)+1]-1]+=offset; + coords=DataArrayDouble::Aggregate(v); conn=newConn.retn(); connI=newConnI.retn(); + return ret.retn(); +} + +/*! + * Tessellates \a this 2D mesh by dividing not straight edges of quadratic faces, + * so that the number of cells remains the same. Quadratic faces are converted to + * polygons. This method works only for 2D meshes in + * 2D space. If no cells are quadratic (INTERP_KERNEL::NORM_QUAD8, + * INTERP_KERNEL::NORM_TRI6, INTERP_KERNEL::NORM_QPOLYG ), \a this mesh remains unchanged. + * \warning This method can lead to a huge amount of nodes if \a eps is very low. + * \param [in] eps - specifies the maximal angle (in radians) between 2 sub-edges of + * a polylinized edge constituting the input polygon. + * \throw If the coordinates array is not set. + * \throw If the nodal connectivity of cells is not defined. + * \throw If \a this->getMeshDimension() != 2. + * \throw If \a this->getSpaceDimension() != 2. + */ +void MEDCouplingUMesh::tessellate2D(double eps) +{ + checkFullyDefined(); + if(getMeshDimension()!=2 || getSpaceDimension()!=2) + throw INTERP_KERNEL::Exception("MEDCouplingUMesh::tessellate2D works on umeshes with meshdim equal to 2 and spaceDim equal to 2 too!"); + double epsa=fabs(eps); + if(epsa<std::numeric_limits<double>::min()) + throw INTERP_KERNEL::Exception("MEDCouplingUMesh::tessellate2DCurve : epsilon is null ! Please specify a higher epsilon. If too tiny it can lead to a huge amount of nodes and memory !"); + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> desc1=DataArrayInt::New(); + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> descIndx1=DataArrayInt::New(); + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> revDesc1=DataArrayInt::New(); + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> revDescIndx1=DataArrayInt::New(); + MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> mDesc=buildDescendingConnectivity2(desc1,descIndx1,revDesc1,revDescIndx1); + revDesc1=0; revDescIndx1=0; + mDesc->tessellate2DCurve(eps); + subDivide2DMesh(mDesc->_nodal_connec->getConstPointer(),mDesc->_nodal_connec_index->getConstPointer(),desc1->getConstPointer(),descIndx1->getConstPointer()); + setCoords(mDesc->getCoords()); +} + +/*! + * Tessellates \a this 1D mesh in 2D space by dividing not straight quadratic edges. + * \warning This method can lead to a huge amount of nodes if \a eps is very low. + * \param [in] eps - specifies the maximal angle (in radian) between 2 sub-edges of + * a sub-divided edge. + * \throw If the coordinates array is not set. + * \throw If the nodal connectivity of cells is not defined. + * \throw If \a this->getMeshDimension() != 1. + * \throw If \a this->getSpaceDimension() != 2. + */ +void MEDCouplingUMesh::tessellate2DCurve(double eps) +{ + checkFullyDefined(); + if(getMeshDimension()!=1 || getSpaceDimension()!=2) + throw INTERP_KERNEL::Exception("MEDCouplingUMesh::tessellate2DCurve works on umeshes with meshdim equal to 1 and spaceDim equal to 2 too!"); + double epsa=fabs(eps); + if(epsa<std::numeric_limits<double>::min()) + throw INTERP_KERNEL::Exception("MEDCouplingUMesh::tessellate2DCurve : epsilon is null ! Please specify a higher epsilon. If too tiny it can lead to a huge amount of nodes and memory !"); + INTERP_KERNEL::QUADRATIC_PLANAR::_arc_detection_precision=1.e-10; + int nbCells=getNumberOfCells(); + int nbNodes=getNumberOfNodes(); + const int *conn=_nodal_connec->getConstPointer(); + const int *connI=_nodal_connec_index->getConstPointer(); + const double *coords=_coords->getConstPointer(); + std::vector<double> addCoo; + std::vector<int> newConn;//no direct DataArrayInt because interface with Geometric2D + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> newConnI(DataArrayInt::New()); + newConnI->alloc(nbCells+1,1); + int *newConnIPtr=newConnI->getPointer(); + *newConnIPtr=0; + int tmp1[3]; + INTERP_KERNEL::Node *tmp2[3]; + std::set<INTERP_KERNEL::NormalizedCellType> types; + for(int i=0;i<nbCells;i++,newConnIPtr++) + { + const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel((INTERP_KERNEL::NormalizedCellType)conn[connI[i]]); + if(cm.isQuadratic()) + {//assert(connI[i+1]-connI[i]-1==3) + tmp1[0]=conn[connI[i]+1+0]; tmp1[1]=conn[connI[i]+1+1]; tmp1[2]=conn[connI[i]+1+2]; + tmp2[0]=new INTERP_KERNEL::Node(coords[2*tmp1[0]],coords[2*tmp1[0]+1]); + tmp2[1]=new INTERP_KERNEL::Node(coords[2*tmp1[1]],coords[2*tmp1[1]+1]); + tmp2[2]=new INTERP_KERNEL::Node(coords[2*tmp1[2]],coords[2*tmp1[2]+1]); + INTERP_KERNEL::EdgeArcCircle *eac=INTERP_KERNEL::EdgeArcCircle::BuildFromNodes(tmp2[0],tmp2[2],tmp2[1]); + if(eac) + { + eac->tesselate(tmp1,nbNodes,epsa,newConn,addCoo); + types.insert((INTERP_KERNEL::NormalizedCellType)newConn[newConnIPtr[0]]); + delete eac; + newConnIPtr[1]=(int)newConn.size(); + } + else + { + types.insert(INTERP_KERNEL::NORM_SEG2); + newConn.push_back(INTERP_KERNEL::NORM_SEG2); + newConn.insert(newConn.end(),conn+connI[i]+1,conn+connI[i]+3); + newConnIPtr[1]=newConnIPtr[0]+3; + } + } + else + { + types.insert((INTERP_KERNEL::NormalizedCellType)conn[connI[i]]); + newConn.insert(newConn.end(),conn+connI[i],conn+connI[i+1]); + newConnIPtr[1]=newConnIPtr[0]+3; + } + } + if(addCoo.empty() && ((int)newConn.size())==_nodal_connec->getNumberOfTuples())//nothing happens during tessellation : no update needed + return ; + _types=types; + DataArrayInt::SetArrayIn(newConnI,_nodal_connec_index); + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> newConnArr=DataArrayInt::New(); + newConnArr->alloc((int)newConn.size(),1); + std::copy(newConn.begin(),newConn.end(),newConnArr->getPointer()); + DataArrayInt::SetArrayIn(newConnArr,_nodal_connec); + MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> newCoords=DataArrayDouble::New(); + newCoords->alloc(nbNodes+((int)addCoo.size())/2,2); + double *work=std::copy(_coords->begin(),_coords->end(),newCoords->getPointer()); + std::copy(addCoo.begin(),addCoo.end(),work); + DataArrayDouble::SetArrayIn(newCoords,_coords); + updateTime(); +} + +/*! + * Divides every cell of \a this mesh into simplices (triangles in 2D and tetrahedra in 3D). + * In addition, returns an array mapping new cells to old ones. <br> + * This method typically increases the number of cells in \a this mesh + * but the number of nodes remains \b unchanged. + * That's why the 3D splitting policies + * INTERP_KERNEL::GENERAL_24 and INTERP_KERNEL::GENERAL_48 are not available here. + * \param [in] policy - specifies a pattern used for splitting. + * The semantic of \a policy is: + * - 0 - to split QUAD4 by cutting it along 0-2 diagonal (for 2D mesh only). + * - 1 - to split QUAD4 by cutting it along 1-3 diagonal (for 2D mesh only). + * - INTERP_KERNEL::PLANAR_FACE_5 - to split HEXA8 into 5 TETRA4 (for 3D mesh only - see INTERP_KERNEL::SplittingPolicy for an image). + * - INTERP_KERNEL::PLANAR_FACE_6 - to split HEXA8 into 6 TETRA4 (for 3D mesh only - see INTERP_KERNEL::SplittingPolicy for an image). + * + * + * \return DataArrayInt * - a new instance of DataArrayInt holding, for each new cell, + * an id of old cell producing it. The caller is to delete this array using + * decrRef() as it is no more needed. + * + * \throw If \a policy is 0 or 1 and \a this->getMeshDimension() != 2. + * \throw If \a policy is INTERP_KERNEL::PLANAR_FACE_5 or INTERP_KERNEL::PLANAR_FACE_6 + * and \a this->getMeshDimension() != 3. + * \throw If \a policy is not one of the four discussed above. + * \throw If the nodal connectivity of cells is not defined. + * \sa MEDCouplingUMesh::tetrahedrize, MEDCoupling1SGTUMesh::sortHexa8EachOther + */ +DataArrayInt *MEDCouplingUMesh::simplexize(int policy) +{ + switch(policy) + { + case 0: + return simplexizePol0(); + case 1: + return simplexizePol1(); + case (int) INTERP_KERNEL::PLANAR_FACE_5: + return simplexizePlanarFace5(); + case (int) INTERP_KERNEL::PLANAR_FACE_6: + return simplexizePlanarFace6(); + default: + throw INTERP_KERNEL::Exception("MEDCouplingUMesh::simplexize : unrecognized policy ! Must be :\n - 0 or 1 (only available for meshdim=2) \n - PLANAR_FACE_5, PLANAR_FACE_6 (only for meshdim=3)"); + } +} + +/*! + * Checks if \a this mesh is constituted by simplex cells only. Simplex cells are: + * - 1D: INTERP_KERNEL::NORM_SEG2 + * - 2D: INTERP_KERNEL::NORM_TRI3 + * - 3D: INTERP_KERNEL::NORM_TETRA4. + * + * This method is useful for users that need to use P1 field services as + * MEDCouplingFieldDouble::getValueOn(), MEDCouplingField::buildMeasureField() etc. + * All these methods need mesh support containing only simplex cells. + * \return bool - \c true if there are only simplex cells in \a this mesh. + * \throw If the coordinates array is not set. + * \throw If the nodal connectivity of cells is not defined. + * \throw If \a this->getMeshDimension() < 1. + */ +bool MEDCouplingUMesh::areOnlySimplexCells() const +{ + checkFullyDefined(); + int mdim=getMeshDimension(); + if(mdim<1 || mdim>3) + throw INTERP_KERNEL::Exception("MEDCouplingUMesh::areOnlySimplexCells : only available with meshes having a meshdim 1, 2 or 3 !"); + int nbCells=getNumberOfCells(); + const int *conn=_nodal_connec->getConstPointer(); + const int *connI=_nodal_connec_index->getConstPointer(); + for(int i=0;i<nbCells;i++) + { + const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel((INTERP_KERNEL::NormalizedCellType)conn[connI[i]]); + if(!cm.isSimplex()) + return false; + } + return true; +} + +/*! + * This method implements policy 0 of virtual method ParaMEDMEM::MEDCouplingUMesh::simplexize. + */ +DataArrayInt *MEDCouplingUMesh::simplexizePol0() +{ + checkConnectivityFullyDefined(); + if(getMeshDimension()!=2) + throw INTERP_KERNEL::Exception("MEDCouplingUMesh::simplexizePol0 : this policy is only available for mesh with meshdim == 2 !"); + int nbOfCells=getNumberOfCells(); + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New(); + int nbOfCutCells=getNumberOfCellsWithType(INTERP_KERNEL::NORM_QUAD4); + ret->alloc(nbOfCells+nbOfCutCells,1); + if(nbOfCutCells==0) { ret->iota(0); return ret.retn(); } + int *retPt=ret->getPointer(); + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> newConn=DataArrayInt::New(); + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> newConnI=DataArrayInt::New(); + newConnI->alloc(nbOfCells+nbOfCutCells+1,1); + newConn->alloc(getMeshLength()+3*nbOfCutCells,1); + int *pt=newConn->getPointer(); + int *ptI=newConnI->getPointer(); + ptI[0]=0; + const int *oldc=_nodal_connec->getConstPointer(); + const int *ci=_nodal_connec_index->getConstPointer(); + for(int i=0;i<nbOfCells;i++,ci++) + { + if((INTERP_KERNEL::NormalizedCellType)oldc[ci[0]]==INTERP_KERNEL::NORM_QUAD4) + { + const int tmp[8]={(int)INTERP_KERNEL::NORM_TRI3,oldc[ci[0]+1],oldc[ci[0]+2],oldc[ci[0]+3], + (int)INTERP_KERNEL::NORM_TRI3,oldc[ci[0]+1],oldc[ci[0]+3],oldc[ci[0]+4]}; + pt=std::copy(tmp,tmp+8,pt); + ptI[1]=ptI[0]+4; + ptI[2]=ptI[0]+8; + *retPt++=i; + *retPt++=i; + ptI+=2; + } + else + { + pt=std::copy(oldc+ci[0],oldc+ci[1],pt); + ptI[1]=ptI[0]+ci[1]-ci[0]; + ptI++; + *retPt++=i; + } + } + _nodal_connec->decrRef(); + _nodal_connec=newConn.retn(); + _nodal_connec_index->decrRef(); + _nodal_connec_index=newConnI.retn(); + computeTypes(); + updateTime(); + return ret.retn(); +} + +/*! + * This method implements policy 1 of virtual method ParaMEDMEM::MEDCouplingUMesh::simplexize. + */ +DataArrayInt *MEDCouplingUMesh::simplexizePol1() +{ + checkConnectivityFullyDefined(); + if(getMeshDimension()!=2) + throw INTERP_KERNEL::Exception("MEDCouplingUMesh::simplexizePol0 : this policy is only available for mesh with meshdim == 2 !"); + int nbOfCells=getNumberOfCells(); + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New(); + int nbOfCutCells=getNumberOfCellsWithType(INTERP_KERNEL::NORM_QUAD4); + ret->alloc(nbOfCells+nbOfCutCells,1); + if(nbOfCutCells==0) { ret->iota(0); return ret.retn(); } + int *retPt=ret->getPointer(); + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> newConn=DataArrayInt::New(); + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> newConnI=DataArrayInt::New(); + newConnI->alloc(nbOfCells+nbOfCutCells+1,1); + newConn->alloc(getMeshLength()+3*nbOfCutCells,1); + int *pt=newConn->getPointer(); + int *ptI=newConnI->getPointer(); + ptI[0]=0; + const int *oldc=_nodal_connec->getConstPointer(); + const int *ci=_nodal_connec_index->getConstPointer(); + for(int i=0;i<nbOfCells;i++,ci++) + { + if((INTERP_KERNEL::NormalizedCellType)oldc[ci[0]]==INTERP_KERNEL::NORM_QUAD4) + { + const int tmp[8]={(int)INTERP_KERNEL::NORM_TRI3,oldc[ci[0]+1],oldc[ci[0]+2],oldc[ci[0]+4], + (int)INTERP_KERNEL::NORM_TRI3,oldc[ci[0]+2],oldc[ci[0]+3],oldc[ci[0]+4]}; + pt=std::copy(tmp,tmp+8,pt); + ptI[1]=ptI[0]+4; + ptI[2]=ptI[0]+8; + *retPt++=i; + *retPt++=i; + ptI+=2; + } + else + { + pt=std::copy(oldc+ci[0],oldc+ci[1],pt); + ptI[1]=ptI[0]+ci[1]-ci[0]; + ptI++; + *retPt++=i; + } + } + _nodal_connec->decrRef(); + _nodal_connec=newConn.retn(); + _nodal_connec_index->decrRef(); + _nodal_connec_index=newConnI.retn(); + computeTypes(); + updateTime(); + return ret.retn(); +} + +/*! + * This method implements policy INTERP_KERNEL::PLANAR_FACE_5 of virtual method ParaMEDMEM::MEDCouplingUMesh::simplexize. + */ +DataArrayInt *MEDCouplingUMesh::simplexizePlanarFace5() +{ + checkConnectivityFullyDefined(); + if(getMeshDimension()!=3) + throw INTERP_KERNEL::Exception("MEDCouplingUMesh::simplexizePlanarFace5 : this policy is only available for mesh with meshdim == 3 !"); + int nbOfCells=getNumberOfCells(); + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New(); + int nbOfCutCells=getNumberOfCellsWithType(INTERP_KERNEL::NORM_HEXA8); + ret->alloc(nbOfCells+4*nbOfCutCells,1); + if(nbOfCutCells==0) { ret->iota(0); return ret.retn(); } + int *retPt=ret->getPointer(); + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> newConn=DataArrayInt::New(); + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> newConnI=DataArrayInt::New(); + newConnI->alloc(nbOfCells+4*nbOfCutCells+1,1); + newConn->alloc(getMeshLength()+16*nbOfCutCells,1);//21 + int *pt=newConn->getPointer(); + int *ptI=newConnI->getPointer(); + ptI[0]=0; + const int *oldc=_nodal_connec->getConstPointer(); + const int *ci=_nodal_connec_index->getConstPointer(); + for(int i=0;i<nbOfCells;i++,ci++) + { + if((INTERP_KERNEL::NormalizedCellType)oldc[ci[0]]==INTERP_KERNEL::NORM_HEXA8) + { + for(int j=0;j<5;j++,pt+=5,ptI++) + { + pt[0]=(int)INTERP_KERNEL::NORM_TETRA4; + pt[1]=oldc[ci[0]+INTERP_KERNEL::SPLIT_NODES_5_WO[4*j+0]+1]; pt[2]=oldc[ci[0]+INTERP_KERNEL::SPLIT_NODES_5_WO[4*j+1]+1]; pt[3]=oldc[ci[0]+INTERP_KERNEL::SPLIT_NODES_5_WO[4*j+2]+1]; pt[4]=oldc[ci[0]+INTERP_KERNEL::SPLIT_NODES_5_WO[4*j+3]+1]; + *retPt++=i; + ptI[1]=ptI[0]+5; + } + } + else + { + pt=std::copy(oldc+ci[0],oldc+ci[1],pt); + ptI[1]=ptI[0]+ci[1]-ci[0]; + ptI++; + *retPt++=i; + } + } + _nodal_connec->decrRef(); + _nodal_connec=newConn.retn(); + _nodal_connec_index->decrRef(); + _nodal_connec_index=newConnI.retn(); + computeTypes(); + updateTime(); + return ret.retn(); +} + +/*! + * This method implements policy INTERP_KERNEL::PLANAR_FACE_6 of virtual method ParaMEDMEM::MEDCouplingUMesh::simplexize. + */ +DataArrayInt *MEDCouplingUMesh::simplexizePlanarFace6() +{ + checkConnectivityFullyDefined(); + if(getMeshDimension()!=3) + throw INTERP_KERNEL::Exception("MEDCouplingUMesh::simplexizePlanarFace6 : this policy is only available for mesh with meshdim == 3 !"); + int nbOfCells=getNumberOfCells(); + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New(); + int nbOfCutCells=getNumberOfCellsWithType(INTERP_KERNEL::NORM_HEXA8); + ret->alloc(nbOfCells+5*nbOfCutCells,1); + if(nbOfCutCells==0) { ret->iota(0); return ret.retn(); } + int *retPt=ret->getPointer(); + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> newConn=DataArrayInt::New(); + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> newConnI=DataArrayInt::New(); + newConnI->alloc(nbOfCells+5*nbOfCutCells+1,1); + newConn->alloc(getMeshLength()+21*nbOfCutCells,1); + int *pt=newConn->getPointer(); + int *ptI=newConnI->getPointer(); + ptI[0]=0; + const int *oldc=_nodal_connec->getConstPointer(); + const int *ci=_nodal_connec_index->getConstPointer(); + for(int i=0;i<nbOfCells;i++,ci++) + { + if((INTERP_KERNEL::NormalizedCellType)oldc[ci[0]]==INTERP_KERNEL::NORM_HEXA8) + { + for(int j=0;j<6;j++,pt+=5,ptI++) + { + pt[0]=(int)INTERP_KERNEL::NORM_TETRA4; + pt[1]=oldc[ci[0]+INTERP_KERNEL::SPLIT_NODES_6_WO[4*j+0]+1]; pt[2]=oldc[ci[0]+INTERP_KERNEL::SPLIT_NODES_6_WO[4*j+1]+1]; pt[3]=oldc[ci[0]+INTERP_KERNEL::SPLIT_NODES_6_WO[4*j+2]+1]; pt[4]=oldc[ci[0]+INTERP_KERNEL::SPLIT_NODES_6_WO[4*j+3]+1]; + *retPt++=i; + ptI[1]=ptI[0]+5; + } + } + else + { + pt=std::copy(oldc+ci[0],oldc+ci[1],pt); + ptI[1]=ptI[0]+ci[1]-ci[0]; + ptI++; + *retPt++=i; + } + } + _nodal_connec->decrRef(); + _nodal_connec=newConn.retn(); + _nodal_connec_index->decrRef(); + _nodal_connec_index=newConnI.retn(); + computeTypes(); + updateTime(); + return ret.retn(); +} + +/*! + * This private method is used to subdivide edges of a mesh with meshdim==2. If \a this has no a meshdim equal to 2 an exception will be thrown. + * This method completly ignore coordinates. + * \param nodeSubdived is the nodal connectivity of subdivision of edges + * \param nodeIndxSubdived is the nodal connectivity index of subdivision of edges + * \param desc is descending connectivity in format specified in MEDCouplingUMesh::buildDescendingConnectivity2 + * \param descIndex is descending connectivity index in format specified in MEDCouplingUMesh::buildDescendingConnectivity2 + */ +void MEDCouplingUMesh::subDivide2DMesh(const int *nodeSubdived, const int *nodeIndxSubdived, const int *desc, const int *descIndex) +{ + checkFullyDefined(); + if(getMeshDimension()!=2) + throw INTERP_KERNEL::Exception("MEDCouplingUMesh::subDivide2DMesh : works only on umesh with meshdim==2 !"); + int nbOfCells=getNumberOfCells(); + int *connI=_nodal_connec_index->getPointer(); + int newConnLgth=0; + for(int i=0;i<nbOfCells;i++,connI++) + { + int offset=descIndex[i]; + int nbOfEdges=descIndex[i+1]-offset; + // + bool ddirect=desc[offset+nbOfEdges-1]>0; + int eedgeId=std::abs(desc[offset+nbOfEdges-1])-1; + int ref=ddirect?nodeSubdived[nodeIndxSubdived[eedgeId+1]-1]:nodeSubdived[nodeIndxSubdived[eedgeId]+1]; + for(int j=0;j<nbOfEdges;j++) + { + bool direct=desc[offset+j]>0; + int edgeId=std::abs(desc[offset+j])-1; + if(!INTERP_KERNEL::CellModel::GetCellModel((INTERP_KERNEL::NormalizedCellType)nodeSubdived[nodeIndxSubdived[edgeId]]).isQuadratic()) + { + int id1=nodeSubdived[nodeIndxSubdived[edgeId]+1]; + int id2=nodeSubdived[nodeIndxSubdived[edgeId+1]-1]; + int ref2=direct?id1:id2; + if(ref==ref2) + { + int nbOfSubNodes=nodeIndxSubdived[edgeId+1]-nodeIndxSubdived[edgeId]-1; + newConnLgth+=nbOfSubNodes-1; + ref=direct?id2:id1; + } + else + { + std::ostringstream oss; oss << "MEDCouplingUMesh::subDivide2DMesh : On polygon #" << i << " edgeid #" << j << " subedges mismatch : end subedge k!=start subedge k+1 !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + } + else + { + throw INTERP_KERNEL::Exception("MEDCouplingUMesh::subDivide2DMesh : this method only subdivides into linear edges !"); + } + } + newConnLgth++;//+1 is for cell type + connI[1]=newConnLgth; + } + // + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> newConn=DataArrayInt::New(); + newConn->alloc(newConnLgth,1); + int *work=newConn->getPointer(); + for(int i=0;i<nbOfCells;i++) + { + *work++=INTERP_KERNEL::NORM_POLYGON; + int offset=descIndex[i]; + int nbOfEdges=descIndex[i+1]-offset; + for(int j=0;j<nbOfEdges;j++) + { + bool direct=desc[offset+j]>0; + int edgeId=std::abs(desc[offset+j])-1; + if(direct) + work=std::copy(nodeSubdived+nodeIndxSubdived[edgeId]+1,nodeSubdived+nodeIndxSubdived[edgeId+1]-1,work); + else + { + int nbOfSubNodes=nodeIndxSubdived[edgeId+1]-nodeIndxSubdived[edgeId]-1; + std::reverse_iterator<const int *> it(nodeSubdived+nodeIndxSubdived[edgeId+1]); + work=std::copy(it,it+nbOfSubNodes-1,work); + } + } + } + DataArrayInt::SetArrayIn(newConn,_nodal_connec); + _types.clear(); + if(nbOfCells>0) + _types.insert(INTERP_KERNEL::NORM_POLYGON); +} + +/*! + * Converts degenerated 2D or 3D linear cells of \a this mesh into cells of simpler + * type. For example an INTERP_KERNEL::NORM_QUAD4 cell having only three unique nodes in + * its connectivity is transformed into an INTERP_KERNEL::NORM_TRI3 cell. This method + * does \b not perform geometrical checks and checks only nodal connectivity of cells, + * so it can be useful to call mergeNodes() before calling this method. + * \throw If \a this->getMeshDimension() <= 1. + * \throw If the coordinates array is not set. + * \throw If the nodal connectivity of cells is not defined. + */ +void MEDCouplingUMesh::convertDegeneratedCells() +{ + checkFullyDefined(); + if(getMeshDimension()<=1) + throw INTERP_KERNEL::Exception("MEDCouplingUMesh::convertDegeneratedCells works on umeshes with meshdim equals to 2 or 3 !"); + int nbOfCells=getNumberOfCells(); + if(nbOfCells<1) + return ; + int initMeshLgth=getMeshLength(); + int *conn=_nodal_connec->getPointer(); + int *index=_nodal_connec_index->getPointer(); + int posOfCurCell=0; + int newPos=0; + int lgthOfCurCell; + for(int i=0;i<nbOfCells;i++) + { + lgthOfCurCell=index[i+1]-posOfCurCell; + INTERP_KERNEL::NormalizedCellType type=(INTERP_KERNEL::NormalizedCellType)conn[posOfCurCell]; + int newLgth; + INTERP_KERNEL::NormalizedCellType newType=INTERP_KERNEL::CellSimplify::simplifyDegeneratedCell(type,conn+posOfCurCell+1,lgthOfCurCell-1, + conn+newPos+1,newLgth); + conn[newPos]=newType; + newPos+=newLgth+1; + posOfCurCell=index[i+1]; + index[i+1]=newPos; + } + if(newPos!=initMeshLgth) + _nodal_connec->reAlloc(newPos); + computeTypes(); +} + +/*! + * Finds incorrectly oriented cells of this 2D mesh in 3D space. + * A cell is considered to be oriented correctly if an angle between its + * normal vector and a given vector is less than \c PI / \c 2. + * \param [in] vec - 3 components of the vector specifying the correct orientation of + * cells. + * \param [in] polyOnly - if \c true, only polygons are checked, else, all cells are + * checked. + * \param [in,out] cells - a vector returning ids of incorrectly oriented cells. It + * is not cleared before filling in. + * \throw If \a this->getMeshDimension() != 2. + * \throw If \a this->getSpaceDimension() != 3. + * + * \if ENABLE_EXAMPLES + * \ref cpp_mcumesh_are2DCellsNotCorrectlyOriented "Here is a C++ example".<br> + * \ref py_mcumesh_are2DCellsNotCorrectlyOriented "Here is a Python example". + * \endif + */ +void MEDCouplingUMesh::are2DCellsNotCorrectlyOriented(const double *vec, bool polyOnly, std::vector<int>& cells) const +{ + if(getMeshDimension()!=2 || getSpaceDimension()!=3) + throw INTERP_KERNEL::Exception("Invalid mesh to apply are2DCellsNotCorrectlyOriented on it : must be meshDim==2 and spaceDim==3 !"); + int nbOfCells=getNumberOfCells(); + const int *conn=_nodal_connec->getConstPointer(); + const int *connI=_nodal_connec_index->getConstPointer(); + const double *coordsPtr=_coords->getConstPointer(); + for(int i=0;i<nbOfCells;i++) + { + INTERP_KERNEL::NormalizedCellType type=(INTERP_KERNEL::NormalizedCellType)conn[connI[i]]; + if(!polyOnly || (type==INTERP_KERNEL::NORM_POLYGON || type==INTERP_KERNEL::NORM_QPOLYG)) + { + bool isQuadratic=INTERP_KERNEL::CellModel::GetCellModel(type).isQuadratic(); + if(!IsPolygonWellOriented(isQuadratic,vec,conn+connI[i]+1,conn+connI[i+1],coordsPtr)) + cells.push_back(i); + } + } +} + +/*! + * Reverse connectivity of 2D cells whose orientation is not correct. A cell is + * considered to be oriented correctly if an angle between its normal vector and a + * given vector is less than \c PI / \c 2. + * \param [in] vec - 3 components of the vector specifying the correct orientation of + * cells. + * \param [in] polyOnly - if \c true, only polygons are checked, else, all cells are + * checked. + * \throw If \a this->getMeshDimension() != 2. + * \throw If \a this->getSpaceDimension() != 3. + * + * \if ENABLE_EXAMPLES + * \ref cpp_mcumesh_are2DCellsNotCorrectlyOriented "Here is a C++ example".<br> + * \ref py_mcumesh_are2DCellsNotCorrectlyOriented "Here is a Python example". + * \endif + * + * \sa changeOrientationOfCells + */ +void MEDCouplingUMesh::orientCorrectly2DCells(const double *vec, bool polyOnly) +{ + if(getMeshDimension()!=2 || getSpaceDimension()!=3) + throw INTERP_KERNEL::Exception("Invalid mesh to apply orientCorrectly2DCells on it : must be meshDim==2 and spaceDim==3 !"); + int nbOfCells(getNumberOfCells()),*conn(_nodal_connec->getPointer()); + const int *connI(_nodal_connec_index->getConstPointer()); + const double *coordsPtr(_coords->getConstPointer()); + bool isModified(false); + for(int i=0;i<nbOfCells;i++) + { + INTERP_KERNEL::NormalizedCellType type((INTERP_KERNEL::NormalizedCellType)conn[connI[i]]); + if(!polyOnly || (type==INTERP_KERNEL::NORM_POLYGON || type==INTERP_KERNEL::NORM_QPOLYG)) + { + const INTERP_KERNEL::CellModel& cm(INTERP_KERNEL::CellModel::GetCellModel(type)); + bool isQuadratic(cm.isQuadratic()); + if(!IsPolygonWellOriented(isQuadratic,vec,conn+connI[i]+1,conn+connI[i+1],coordsPtr)) + { + isModified=true; + cm.changeOrientationOf2D(conn+connI[i]+1,(unsigned int)(connI[i+1]-connI[i]-1)); + } + } + } + if(isModified) + _nodal_connec->declareAsNew(); + updateTime(); +} + +/*! + * This method change the orientation of cells in \a this without any consideration of coordinates. Only connectivity is impacted. + * + * \sa orientCorrectly2DCells + */ +void MEDCouplingUMesh::changeOrientationOfCells() +{ + int mdim(getMeshDimension()); + if(mdim!=2 && mdim!=1) + throw INTERP_KERNEL::Exception("Invalid mesh to apply changeOrientationOfCells on it : must be meshDim==2 or meshDim==1 !"); + int nbOfCells(getNumberOfCells()),*conn(_nodal_connec->getPointer()); + const int *connI(_nodal_connec_index->getConstPointer()); + if(mdim==2) + {//2D + for(int i=0;i<nbOfCells;i++) + { + INTERP_KERNEL::NormalizedCellType type((INTERP_KERNEL::NormalizedCellType)conn[connI[i]]); + const INTERP_KERNEL::CellModel& cm(INTERP_KERNEL::CellModel::GetCellModel(type)); + cm.changeOrientationOf2D(conn+connI[i]+1,(unsigned int)(connI[i+1]-connI[i]-1)); + } + } + else + {//1D + for(int i=0;i<nbOfCells;i++) + { + INTERP_KERNEL::NormalizedCellType type((INTERP_KERNEL::NormalizedCellType)conn[connI[i]]); + const INTERP_KERNEL::CellModel& cm(INTERP_KERNEL::CellModel::GetCellModel(type)); + cm.changeOrientationOf1D(conn+connI[i]+1,(unsigned int)(connI[i+1]-connI[i]-1)); + } + } +} + +/*! + * Finds incorrectly oriented polyhedral cells, i.e. polyhedrons having correctly + * oriented facets. The normal vector of the facet should point out of the cell. + * \param [in,out] cells - a vector returning ids of incorrectly oriented cells. It + * is not cleared before filling in. + * \throw If \a this->getMeshDimension() != 3. + * \throw If \a this->getSpaceDimension() != 3. + * \throw If the coordinates array is not set. + * \throw If the nodal connectivity of cells is not defined. + * + * \if ENABLE_EXAMPLES + * \ref cpp_mcumesh_arePolyhedronsNotCorrectlyOriented "Here is a C++ example".<br> + * \ref py_mcumesh_arePolyhedronsNotCorrectlyOriented "Here is a Python example". + * \endif + */ +void MEDCouplingUMesh::arePolyhedronsNotCorrectlyOriented(std::vector<int>& cells) const +{ + if(getMeshDimension()!=3 || getSpaceDimension()!=3) + throw INTERP_KERNEL::Exception("Invalid mesh to apply arePolyhedronsNotCorrectlyOriented on it : must be meshDim==3 and spaceDim==3 !"); + int nbOfCells=getNumberOfCells(); + const int *conn=_nodal_connec->getConstPointer(); + const int *connI=_nodal_connec_index->getConstPointer(); + const double *coordsPtr=_coords->getConstPointer(); + for(int i=0;i<nbOfCells;i++) + { + INTERP_KERNEL::NormalizedCellType type=(INTERP_KERNEL::NormalizedCellType)conn[connI[i]]; + if(type==INTERP_KERNEL::NORM_POLYHED) + { + if(!IsPolyhedronWellOriented(conn+connI[i]+1,conn+connI[i+1],coordsPtr)) + cells.push_back(i); + } + } +} + +/*! + * Tries to fix connectivity of polyhedra, so that normal vector of all facets to point + * out of the cell. + * \throw If \a this->getMeshDimension() != 3. + * \throw If \a this->getSpaceDimension() != 3. + * \throw If the coordinates array is not set. + * \throw If the nodal connectivity of cells is not defined. + * \throw If the reparation fails. + * + * \if ENABLE_EXAMPLES + * \ref cpp_mcumesh_arePolyhedronsNotCorrectlyOriented "Here is a C++ example".<br> + * \ref py_mcumesh_arePolyhedronsNotCorrectlyOriented "Here is a Python example". + * \endif + * \sa MEDCouplingUMesh::findAndCorrectBadOriented3DCells + */ +void MEDCouplingUMesh::orientCorrectlyPolyhedrons() +{ + if(getMeshDimension()!=3 || getSpaceDimension()!=3) + throw INTERP_KERNEL::Exception("Invalid mesh to apply orientCorrectlyPolyhedrons on it : must be meshDim==3 and spaceDim==3 !"); + int nbOfCells=getNumberOfCells(); + int *conn=_nodal_connec->getPointer(); + const int *connI=_nodal_connec_index->getConstPointer(); + const double *coordsPtr=_coords->getConstPointer(); + for(int i=0;i<nbOfCells;i++) + { + INTERP_KERNEL::NormalizedCellType type=(INTERP_KERNEL::NormalizedCellType)conn[connI[i]]; + if(type==INTERP_KERNEL::NORM_POLYHED) + { + try + { + if(!IsPolyhedronWellOriented(conn+connI[i]+1,conn+connI[i+1],coordsPtr)) + TryToCorrectPolyhedronOrientation(conn+connI[i]+1,conn+connI[i+1],coordsPtr); + } + catch(INTERP_KERNEL::Exception& e) + { + std::ostringstream oss; oss << "Something wrong in polyhedron #" << i << " : " << e.what(); + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + } + } + updateTime(); +} + +/*! + * Finds and fixes incorrectly oriented linear extruded volumes (INTERP_KERNEL::NORM_HEXA8, + * INTERP_KERNEL::NORM_PENTA6, INTERP_KERNEL::NORM_HEXGP12 etc) to respect the MED convention + * according to which the first facet of the cell should be oriented to have the normal vector + * pointing out of cell. + * \return DataArrayInt * - a new instance of DataArrayInt holding ids of fixed + * cells. The caller is to delete this array using decrRef() as it is no more + * needed. + * \throw If \a this->getMeshDimension() != 3. + * \throw If \a this->getSpaceDimension() != 3. + * \throw If the coordinates array is not set. + * \throw If the nodal connectivity of cells is not defined. + * + * \if ENABLE_EXAMPLES + * \ref cpp_mcumesh_findAndCorrectBadOriented3DExtrudedCells "Here is a C++ example".<br> + * \ref py_mcumesh_findAndCorrectBadOriented3DExtrudedCells "Here is a Python example". + * \endif + * \sa MEDCouplingUMesh::findAndCorrectBadOriented3DCells + */ +DataArrayInt *MEDCouplingUMesh::findAndCorrectBadOriented3DExtrudedCells() +{ + const char msg[]="check3DCellsWellOriented detection works only for 3D cells !"; + if(getMeshDimension()!=3) + throw INTERP_KERNEL::Exception(msg); + int spaceDim=getSpaceDimension(); + if(spaceDim!=3) + throw INTERP_KERNEL::Exception(msg); + // + int nbOfCells=getNumberOfCells(); + int *conn=_nodal_connec->getPointer(); + const int *connI=_nodal_connec_index->getConstPointer(); + const double *coo=getCoords()->getConstPointer(); + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> cells(DataArrayInt::New()); cells->alloc(0,1); + for(int i=0;i<nbOfCells;i++) + { + const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel((INTERP_KERNEL::NormalizedCellType)conn[connI[i]]); + if(cm.isExtruded() && !cm.isDynamic() && !cm.isQuadratic()) + { + if(!Is3DExtrudedStaticCellWellOriented(conn+connI[i]+1,conn+connI[i+1],coo)) + { + CorrectExtrudedStaticCell(conn+connI[i]+1,conn+connI[i+1]); + cells->pushBackSilent(i); + } + } + } + return cells.retn(); +} + +/*! + * This method is a faster method to correct orientation of all 3D cells in \a this. + * This method works only if \a this is a 3D mesh, that is to say a mesh with mesh dimension 3 and a space dimension 3. + * This method makes the hypothesis that \a this a coherent that is to say MEDCouplingUMesh::checkCoherency2 should throw no exception. + * + * \return a newly allocated int array with one components containing cell ids renumbered to fit the convention of MED (MED file and MEDCoupling) + * \sa MEDCouplingUMesh::orientCorrectlyPolyhedrons, + */ +DataArrayInt *MEDCouplingUMesh::findAndCorrectBadOriented3DCells() +{ + if(getMeshDimension()!=3 || getSpaceDimension()!=3) + throw INTERP_KERNEL::Exception("Invalid mesh to apply findAndCorrectBadOriented3DCells on it : must be meshDim==3 and spaceDim==3 !"); + int nbOfCells=getNumberOfCells(); + int *conn=_nodal_connec->getPointer(); + const int *connI=_nodal_connec_index->getConstPointer(); + const double *coordsPtr=_coords->getConstPointer(); + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(0,1); + for(int i=0;i<nbOfCells;i++) + { + INTERP_KERNEL::NormalizedCellType type=(INTERP_KERNEL::NormalizedCellType)conn[connI[i]]; + switch(type) + { + case INTERP_KERNEL::NORM_TETRA4: + { + if(!IsTetra4WellOriented(conn+connI[i]+1,conn+connI[i+1],coordsPtr)) + { + std::swap(*(conn+connI[i]+2),*(conn+connI[i]+3)); + ret->pushBackSilent(i); + } + break; + } + case INTERP_KERNEL::NORM_PYRA5: + { + if(!IsPyra5WellOriented(conn+connI[i]+1,conn+connI[i+1],coordsPtr)) + { + std::swap(*(conn+connI[i]+2),*(conn+connI[i]+4)); + ret->pushBackSilent(i); + } + break; + } + case INTERP_KERNEL::NORM_PENTA6: + case INTERP_KERNEL::NORM_HEXA8: + case INTERP_KERNEL::NORM_HEXGP12: + { + if(!Is3DExtrudedStaticCellWellOriented(conn+connI[i]+1,conn+connI[i+1],coordsPtr)) + { + CorrectExtrudedStaticCell(conn+connI[i]+1,conn+connI[i+1]); + ret->pushBackSilent(i); + } + break; + } + case INTERP_KERNEL::NORM_POLYHED: + { + if(!IsPolyhedronWellOriented(conn+connI[i]+1,conn+connI[i+1],coordsPtr)) + { + TryToCorrectPolyhedronOrientation(conn+connI[i]+1,conn+connI[i+1],coordsPtr); + ret->pushBackSilent(i); + } + break; + } + default: + throw INTERP_KERNEL::Exception("MEDCouplingUMesh::orientCorrectly3DCells : Your mesh contains type of cell not supported yet ! send mail to anthony.geay@cea.fr to add it !"); + } + } + updateTime(); + return ret.retn(); +} + +/*! + * This method has a sense for meshes with spaceDim==3 and meshDim==2. + * If it is not the case an exception will be thrown. + * This method is fast because the first cell of \a this is used to compute the plane. + * \param vec output of size at least 3 used to store the normal vector (with norm equal to Area ) of searched plane. + * \param pos output of size at least 3 used to store a point owned of searched plane. + */ +void MEDCouplingUMesh::getFastAveragePlaneOfThis(double *vec, double *pos) const +{ + if(getMeshDimension()!=2 || getSpaceDimension()!=3) + throw INTERP_KERNEL::Exception("Invalid mesh to apply getFastAveragePlaneOfThis on it : must be meshDim==2 and spaceDim==3 !"); + const int *conn=_nodal_connec->getConstPointer(); + const int *connI=_nodal_connec_index->getConstPointer(); + const double *coordsPtr=_coords->getConstPointer(); + INTERP_KERNEL::areaVectorOfPolygon<int,INTERP_KERNEL::ALL_C_MODE>(conn+1,connI[1]-connI[0]-1,coordsPtr,vec); + std::copy(coordsPtr+3*conn[1],coordsPtr+3*conn[1]+3,pos); +} + +/*! + * Creates a new MEDCouplingFieldDouble holding Edge Ratio values of all + * cells. Currently cells of the following types are treated: + * INTERP_KERNEL::NORM_TRI3, INTERP_KERNEL::NORM_QUAD4 and INTERP_KERNEL::NORM_TETRA4. + * For a cell of other type an exception is thrown. + * Space dimension of a 2D mesh can be either 2 or 3. + * The Edge Ratio of a cell \f$t\f$ is: + * \f$\frac{|t|_\infty}{|t|_0}\f$, + * where \f$|t|_\infty\f$ and \f$|t|_0\f$ respectively denote the greatest and + * the smallest edge lengths of \f$t\f$. + * \return MEDCouplingFieldDouble * - a new instance of MEDCouplingFieldDouble on + * cells and one time, lying on \a this mesh. The caller is to delete this + * field using decrRef() as it is no more needed. + * \throw If the coordinates array is not set. + * \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 \a this->getMeshDimension() is neither 2 nor 3. + * \throw If \a this->getSpaceDimension() is neither 2 nor 3. + * \throw If \a this mesh includes cells of type different from the ones enumerated above. + */ +MEDCouplingFieldDouble *MEDCouplingUMesh::getEdgeRatioField() const +{ + checkCoherency(); + int spaceDim=getSpaceDimension(); + int meshDim=getMeshDimension(); + if(spaceDim!=2 && spaceDim!=3) + throw INTERP_KERNEL::Exception("MEDCouplingUMesh::getEdgeRatioField : SpaceDimension must be equal to 2 or 3 !"); + if(meshDim!=2 && meshDim!=3) + throw INTERP_KERNEL::Exception("MEDCouplingUMesh::getEdgeRatioField : MeshDimension must be equal to 2 or 3 !"); + MEDCouplingAutoRefCountObjectPtr<MEDCouplingFieldDouble> ret=MEDCouplingFieldDouble::New(ON_CELLS,ONE_TIME); + ret->setMesh(this); + int nbOfCells=getNumberOfCells(); + MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> arr=DataArrayDouble::New(); + arr->alloc(nbOfCells,1); + double *pt=arr->getPointer(); + ret->setArray(arr);//In case of throw to avoid mem leaks arr will be used after decrRef. + const int *conn=_nodal_connec->getConstPointer(); + const int *connI=_nodal_connec_index->getConstPointer(); + const double *coo=_coords->getConstPointer(); + double tmp[12]; + for(int i=0;i<nbOfCells;i++,pt++) + { + INTERP_KERNEL::NormalizedCellType t=(INTERP_KERNEL::NormalizedCellType)*conn; + switch(t) + { + case INTERP_KERNEL::NORM_TRI3: + { + FillInCompact3DMode(spaceDim,3,conn+1,coo,tmp); + *pt=INTERP_KERNEL::triEdgeRatio(tmp); + break; + } + case INTERP_KERNEL::NORM_QUAD4: + { + FillInCompact3DMode(spaceDim,4,conn+1,coo,tmp); + *pt=INTERP_KERNEL::quadEdgeRatio(tmp); + break; + } + case INTERP_KERNEL::NORM_TETRA4: + { + FillInCompact3DMode(spaceDim,4,conn+1,coo,tmp); + *pt=INTERP_KERNEL::tetraEdgeRatio(tmp); + break; + } + default: + throw INTERP_KERNEL::Exception("MEDCouplingUMesh::getEdgeRatioField : A cell with not manged type (NORM_TRI3, NORM_QUAD4 and NORM_TETRA4) has been detected !"); + } + conn+=connI[i+1]-connI[i]; + } + ret->setName("EdgeRatio"); + ret->synchronizeTimeWithSupport(); + return ret.retn(); +} + +/*! + * Creates a new MEDCouplingFieldDouble holding Aspect Ratio values of all + * cells. Currently cells of the following types are treated: + * INTERP_KERNEL::NORM_TRI3, INTERP_KERNEL::NORM_QUAD4 and INTERP_KERNEL::NORM_TETRA4. + * For a cell of other type an exception is thrown. + * Space dimension of a 2D mesh can be either 2 or 3. + * \return MEDCouplingFieldDouble * - a new instance of MEDCouplingFieldDouble on + * cells and one time, lying on \a this mesh. The caller is to delete this + * field using decrRef() as it is no more needed. + * \throw If the coordinates array is not set. + * \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 \a this->getMeshDimension() is neither 2 nor 3. + * \throw If \a this->getSpaceDimension() is neither 2 nor 3. + * \throw If \a this mesh includes cells of type different from the ones enumerated above. + */ +MEDCouplingFieldDouble *MEDCouplingUMesh::getAspectRatioField() const +{ + checkCoherency(); + int spaceDim=getSpaceDimension(); + int meshDim=getMeshDimension(); + if(spaceDim!=2 && spaceDim!=3) + throw INTERP_KERNEL::Exception("MEDCouplingUMesh::getAspectRatioField : SpaceDimension must be equal to 2 or 3 !"); + if(meshDim!=2 && meshDim!=3) + throw INTERP_KERNEL::Exception("MEDCouplingUMesh::getAspectRatioField : MeshDimension must be equal to 2 or 3 !"); + MEDCouplingAutoRefCountObjectPtr<MEDCouplingFieldDouble> ret=MEDCouplingFieldDouble::New(ON_CELLS,ONE_TIME); + ret->setMesh(this); + int nbOfCells=getNumberOfCells(); + MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> arr=DataArrayDouble::New(); + arr->alloc(nbOfCells,1); + double *pt=arr->getPointer(); + ret->setArray(arr);//In case of throw to avoid mem leaks arr will be used after decrRef. + const int *conn=_nodal_connec->getConstPointer(); + const int *connI=_nodal_connec_index->getConstPointer(); + const double *coo=_coords->getConstPointer(); + double tmp[12]; + for(int i=0;i<nbOfCells;i++,pt++) + { + INTERP_KERNEL::NormalizedCellType t=(INTERP_KERNEL::NormalizedCellType)*conn; + switch(t) + { + case INTERP_KERNEL::NORM_TRI3: + { + FillInCompact3DMode(spaceDim,3,conn+1,coo,tmp); + *pt=INTERP_KERNEL::triAspectRatio(tmp); + break; + } + case INTERP_KERNEL::NORM_QUAD4: + { + FillInCompact3DMode(spaceDim,4,conn+1,coo,tmp); + *pt=INTERP_KERNEL::quadAspectRatio(tmp); + break; + } + case INTERP_KERNEL::NORM_TETRA4: + { + FillInCompact3DMode(spaceDim,4,conn+1,coo,tmp); + *pt=INTERP_KERNEL::tetraAspectRatio(tmp); + break; + } + default: + throw INTERP_KERNEL::Exception("MEDCouplingUMesh::getAspectRatioField : A cell with not manged type (NORM_TRI3, NORM_QUAD4 and NORM_TETRA4) has been detected !"); + } + conn+=connI[i+1]-connI[i]; + } + ret->setName("AspectRatio"); + ret->synchronizeTimeWithSupport(); + return ret.retn(); +} + +/*! + * Creates a new MEDCouplingFieldDouble holding Warping factor values of all + * cells of \a this 2D mesh in 3D space. Currently cells of the following types are + * treated: INTERP_KERNEL::NORM_QUAD4. + * For a cell of other type an exception is thrown. + * \return MEDCouplingFieldDouble * - a new instance of MEDCouplingFieldDouble on + * cells and one time, lying on \a this mesh. The caller is to delete this + * field using decrRef() as it is no more needed. + * \throw If the coordinates array is not set. + * \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 \a this->getMeshDimension() != 2. + * \throw If \a this->getSpaceDimension() != 3. + * \throw If \a this mesh includes cells of type different from the ones enumerated above. + */ +MEDCouplingFieldDouble *MEDCouplingUMesh::getWarpField() const +{ + checkCoherency(); + int spaceDim=getSpaceDimension(); + int meshDim=getMeshDimension(); + if(spaceDim!=3) + throw INTERP_KERNEL::Exception("MEDCouplingUMesh::getWarpField : SpaceDimension must be equal to 3 !"); + if(meshDim!=2) + throw INTERP_KERNEL::Exception("MEDCouplingUMesh::getWarpField : MeshDimension must be equal to 2 !"); + MEDCouplingAutoRefCountObjectPtr<MEDCouplingFieldDouble> ret=MEDCouplingFieldDouble::New(ON_CELLS,ONE_TIME); + ret->setMesh(this); + int nbOfCells=getNumberOfCells(); + MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> arr=DataArrayDouble::New(); + arr->alloc(nbOfCells,1); + double *pt=arr->getPointer(); + ret->setArray(arr);//In case of throw to avoid mem leaks arr will be used after decrRef. + const int *conn=_nodal_connec->getConstPointer(); + const int *connI=_nodal_connec_index->getConstPointer(); + const double *coo=_coords->getConstPointer(); + double tmp[12]; + for(int i=0;i<nbOfCells;i++,pt++) + { + INTERP_KERNEL::NormalizedCellType t=(INTERP_KERNEL::NormalizedCellType)*conn; + switch(t) + { + case INTERP_KERNEL::NORM_QUAD4: + { + FillInCompact3DMode(3,4,conn+1,coo,tmp); + *pt=INTERP_KERNEL::quadWarp(tmp); + break; + } + default: + throw INTERP_KERNEL::Exception("MEDCouplingUMesh::getWarpField : A cell with not manged type (NORM_QUAD4) has been detected !"); + } + conn+=connI[i+1]-connI[i]; + } + ret->setName("Warp"); + ret->synchronizeTimeWithSupport(); + return ret.retn(); +} + + +/*! + * Creates a new MEDCouplingFieldDouble holding Skew factor values of all + * cells of \a this 2D mesh in 3D space. Currently cells of the following types are + * treated: INTERP_KERNEL::NORM_QUAD4. + * For a cell of other type an exception is thrown. + * \return MEDCouplingFieldDouble * - a new instance of MEDCouplingFieldDouble on + * cells and one time, lying on \a this mesh. The caller is to delete this + * field using decrRef() as it is no more needed. + * \throw If the coordinates array is not set. + * \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 \a this->getMeshDimension() != 2. + * \throw If \a this->getSpaceDimension() != 3. + * \throw If \a this mesh includes cells of type different from the ones enumerated above. + */ +MEDCouplingFieldDouble *MEDCouplingUMesh::getSkewField() const +{ + checkCoherency(); + int spaceDim=getSpaceDimension(); + int meshDim=getMeshDimension(); + if(spaceDim!=3) + throw INTERP_KERNEL::Exception("MEDCouplingUMesh::getSkewField : SpaceDimension must be equal to 3 !"); + if(meshDim!=2) + throw INTERP_KERNEL::Exception("MEDCouplingUMesh::getSkewField : MeshDimension must be equal to 2 !"); + MEDCouplingAutoRefCountObjectPtr<MEDCouplingFieldDouble> ret=MEDCouplingFieldDouble::New(ON_CELLS,ONE_TIME); + ret->setMesh(this); + int nbOfCells=getNumberOfCells(); + MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> arr=DataArrayDouble::New(); + arr->alloc(nbOfCells,1); + double *pt=arr->getPointer(); + ret->setArray(arr);//In case of throw to avoid mem leaks arr will be used after decrRef. + const int *conn=_nodal_connec->getConstPointer(); + const int *connI=_nodal_connec_index->getConstPointer(); + const double *coo=_coords->getConstPointer(); + double tmp[12]; + for(int i=0;i<nbOfCells;i++,pt++) + { + INTERP_KERNEL::NormalizedCellType t=(INTERP_KERNEL::NormalizedCellType)*conn; + switch(t) + { + case INTERP_KERNEL::NORM_QUAD4: + { + FillInCompact3DMode(3,4,conn+1,coo,tmp); + *pt=INTERP_KERNEL::quadSkew(tmp); + break; + } + default: + throw INTERP_KERNEL::Exception("MEDCouplingUMesh::getSkewField : A cell with not manged type (NORM_QUAD4) has been detected !"); + } + conn+=connI[i+1]-connI[i]; + } + ret->setName("Skew"); + ret->synchronizeTimeWithSupport(); + return ret.retn(); +} + +/*! + * Returns the cell field giving for each cell in \a this its diameter. Diameter means the max length of all possible SEG2 in the cell. + * + * \return a new instance of field containing the result. The returned instance has to be deallocated by the caller. + * + * \sa getSkewField, getWarpField, getAspectRatioField, getEdgeRatioField + */ +MEDCouplingFieldDouble *MEDCouplingUMesh::computeDiameterField() const +{ + checkCoherency(); + MEDCouplingAutoRefCountObjectPtr<MEDCouplingFieldDouble> ret(MEDCouplingFieldDouble::New(ON_CELLS,ONE_TIME)); + ret->setMesh(this); + std::set<INTERP_KERNEL::NormalizedCellType> types; + ComputeAllTypesInternal(types,_nodal_connec,_nodal_connec_index); + int spaceDim(getSpaceDimension()),nbCells(getNumberOfCells()); + MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> arr(DataArrayDouble::New()); + arr->alloc(nbCells,1); + for(std::set<INTERP_KERNEL::NormalizedCellType>::const_iterator it=types.begin();it!=types.end();it++) + { + INTERP_KERNEL::AutoCppPtr<INTERP_KERNEL::DiameterCalculator> dc(INTERP_KERNEL::CellModel::GetCellModel(*it).buildInstanceOfDiameterCalulator(spaceDim)); + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> cellIds(giveCellsWithType(*it)); + dc->computeForListOfCellIdsUMeshFrmt(cellIds->begin(),cellIds->end(),_nodal_connec_index->begin(),_nodal_connec->begin(),getCoords()->begin(),arr->getPointer()); + } + ret->setArray(arr); + ret->setName("Diameter"); + return ret.retn(); +} + +/*! + * This method aggregate the bbox of each cell and put it into bbox parameter. + * + * \param [in] arcDetEps - a parameter specifying in case of 2D quadratic polygon cell the detection limit between linear and arc circle. (By default 1e-12) + * For all other cases this input parameter is ignored. + * \return DataArrayDouble * - newly created object (to be managed by the caller) \a this number of cells tuples and 2*spacedim components. + * + * \throw If \a this is not fully set (coordinates and connectivity). + * \throw If a cell in \a this has no valid nodeId. + * \sa MEDCouplingUMesh::getBoundingBoxForBBTreeFast, MEDCouplingUMesh::getBoundingBoxForBBTree2DQuadratic + */ +DataArrayDouble *MEDCouplingUMesh::getBoundingBoxForBBTree(double arcDetEps) const +{ + int mDim(getMeshDimension()),sDim(getSpaceDimension()); + if((mDim==3 && sDim==3) || (mDim==2 && sDim==3) || (mDim==1 && sDim==1) || ( mDim==1 && sDim==3)) // Compute refined boundary box for quadratic elements only in 2D. + return getBoundingBoxForBBTreeFast(); + if((mDim==2 && sDim==2) || (mDim==1 && sDim==2)) + { + bool presenceOfQuadratic(false); + for(std::set<INTERP_KERNEL::NormalizedCellType>::const_iterator it=_types.begin();it!=_types.end();it++) + { + const INTERP_KERNEL::CellModel& cm(INTERP_KERNEL::CellModel::GetCellModel(*it)); + if(cm.isQuadratic()) + presenceOfQuadratic=true; + } + if(!presenceOfQuadratic) + return getBoundingBoxForBBTreeFast(); + if(mDim==2 && sDim==2) + return getBoundingBoxForBBTree2DQuadratic(arcDetEps); + else + return getBoundingBoxForBBTree1DQuadratic(arcDetEps); + } + throw INTERP_KERNEL::Exception("MEDCouplingUMesh::getBoundingBoxForBBTree : Managed dimensions are (mDim=1,sDim=1), (mDim=1,sDim=2), (mDim=1,sDim=3), (mDim=2,sDim=2), (mDim=2,sDim=3) and (mDim=3,sDim=3) !"); +} + +/*! + * This method aggregate the bbox of each cell only considering the nodes constituting each cell and put it into bbox parameter. + * So meshes having quadratic cells the computed bounding boxes can be invalid ! + * + * \return DataArrayDouble * - newly created object (to be managed by the caller) \a this number of cells tuples and 2*spacedim components. + * + * \throw If \a this is not fully set (coordinates and connectivity). + * \throw If a cell in \a this has no valid nodeId. + */ +DataArrayDouble *MEDCouplingUMesh::getBoundingBoxForBBTreeFast() const +{ + checkFullyDefined(); + int spaceDim(getSpaceDimension()),nbOfCells(getNumberOfCells()),nbOfNodes(getNumberOfNodes()); + MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret(DataArrayDouble::New()); ret->alloc(nbOfCells,2*spaceDim); + double *bbox(ret->getPointer()); + for(int i=0;i<nbOfCells*spaceDim;i++) + { + bbox[2*i]=std::numeric_limits<double>::max(); + bbox[2*i+1]=-std::numeric_limits<double>::max(); + } + const double *coordsPtr(_coords->getConstPointer()); + const int *conn(_nodal_connec->getConstPointer()),*connI(_nodal_connec_index->getConstPointer()); + for(int i=0;i<nbOfCells;i++) + { + int offset=connI[i]+1; + int nbOfNodesForCell(connI[i+1]-offset),kk(0); + for(int j=0;j<nbOfNodesForCell;j++) + { + int nodeId=conn[offset+j]; + if(nodeId>=0 && nodeId<nbOfNodes) + { + for(int k=0;k<spaceDim;k++) + { + bbox[2*spaceDim*i+2*k]=std::min(bbox[2*spaceDim*i+2*k],coordsPtr[spaceDim*nodeId+k]); + bbox[2*spaceDim*i+2*k+1]=std::max(bbox[2*spaceDim*i+2*k+1],coordsPtr[spaceDim*nodeId+k]); + } + kk++; + } + } + if(kk==0) + { + std::ostringstream oss; oss << "MEDCouplingUMesh::getBoundingBoxForBBTree : cell #" << i << " contains no valid nodeId !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + } + return ret.retn(); +} + +/*! + * This method aggregates the bbox of each 2D cell in \a this considering the whole shape. This method is particularly + * useful for 2D meshes having quadratic cells + * because for this type of cells getBoundingBoxForBBTreeFast method may return invalid bounding boxes (since it just considers + * the two extremities of the arc of circle). + * + * \param [in] arcDetEps - a parameter specifying in case of 2D quadratic polygon cell the detection limit between linear and arc circle. (By default 1e-12) + * \return DataArrayDouble * - newly created object (to be managed by the caller) \a this number of cells tuples and 2*spacedim components. + * \throw If \a this is not fully defined. + * \throw If \a this is not a mesh with meshDimension equal to 2. + * \throw If \a this is not a mesh with spaceDimension equal to 2. + * \sa MEDCouplingUMesh::getBoundingBoxForBBTree1DQuadratic + */ +DataArrayDouble *MEDCouplingUMesh::getBoundingBoxForBBTree2DQuadratic(double arcDetEps) const +{ + checkFullyDefined(); + int spaceDim(getSpaceDimension()),mDim(getMeshDimension()),nbOfCells(getNumberOfCells()); + if(spaceDim!=2 || mDim!=2) + throw INTERP_KERNEL::Exception("MEDCouplingUMesh::getBoundingBoxForBBTree2DQuadratic : This method should be applied on mesh with mesh dimension equal to 2 and space dimension also equal to 2!"); + MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret(DataArrayDouble::New()); ret->alloc(nbOfCells,2*spaceDim); + double *bbox(ret->getPointer()); + const double *coords(_coords->getConstPointer()); + const int *conn(_nodal_connec->getConstPointer()),*connI(_nodal_connec_index->getConstPointer()); + for(int i=0;i<nbOfCells;i++,bbox+=4,connI++) + { + const INTERP_KERNEL::CellModel& cm(INTERP_KERNEL::CellModel::GetCellModel((INTERP_KERNEL::NormalizedCellType)conn[*connI])); + int sz(connI[1]-connI[0]-1); + INTERP_KERNEL::QUADRATIC_PLANAR::_arc_detection_precision=arcDetEps; + std::vector<INTERP_KERNEL::Node *> nodes(sz); + INTERP_KERNEL::QuadraticPolygon *pol(0); + for(int j=0;j<sz;j++) + { + int nodeId(conn[*connI+1+j]); + nodes[j]=new INTERP_KERNEL::Node(coords[nodeId*2],coords[nodeId*2+1]); + } + if(!cm.isQuadratic()) + pol=INTERP_KERNEL::QuadraticPolygon::BuildLinearPolygon(nodes); + else + pol=INTERP_KERNEL::QuadraticPolygon::BuildArcCirclePolygon(nodes); + INTERP_KERNEL::Bounds b; b.prepareForAggregation(); pol->fillBounds(b); delete pol; + bbox[0]=b.getXMin(); bbox[1]=b.getXMax(); bbox[2]=b.getYMin(); bbox[3]=b.getYMax(); + } + return ret.retn(); +} + +/*! + * This method aggregates the bbox of each 1D cell in \a this considering the whole shape. This method is particularly + * useful for 2D meshes having quadratic cells + * because for this type of cells getBoundingBoxForBBTreeFast method may return invalid bounding boxes (since it just considers + * the two extremities of the arc of circle). + * + * \param [in] arcDetEps - a parameter specifying in case of 2D quadratic polygon cell the detection limit between linear and arc circle. (By default 1e-12) + * \return DataArrayDouble * - newly created object (to be managed by the caller) \a this number of cells tuples and 2*spacedim components. + * \throw If \a this is not fully defined. + * \throw If \a this is not a mesh with meshDimension equal to 1. + * \throw If \a this is not a mesh with spaceDimension equal to 2. + * \sa MEDCouplingUMesh::getBoundingBoxForBBTree2DQuadratic + */ +DataArrayDouble *MEDCouplingUMesh::getBoundingBoxForBBTree1DQuadratic(double arcDetEps) const +{ + checkFullyDefined(); + int spaceDim(getSpaceDimension()),mDim(getMeshDimension()),nbOfCells(getNumberOfCells()); + if(spaceDim!=2 || mDim!=1) + throw INTERP_KERNEL::Exception("MEDCouplingUMesh::getBoundingBoxForBBTree1DQuadratic : This method should be applied on mesh with mesh dimension equal to 1 and space dimension also equal to 2!"); + MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret(DataArrayDouble::New()); ret->alloc(nbOfCells,2*spaceDim); + double *bbox(ret->getPointer()); + const double *coords(_coords->getConstPointer()); + const int *conn(_nodal_connec->getConstPointer()),*connI(_nodal_connec_index->getConstPointer()); + for(int i=0;i<nbOfCells;i++,bbox+=4,connI++) + { + const INTERP_KERNEL::CellModel& cm(INTERP_KERNEL::CellModel::GetCellModel((INTERP_KERNEL::NormalizedCellType)conn[*connI])); + int sz(connI[1]-connI[0]-1); + INTERP_KERNEL::QUADRATIC_PLANAR::_arc_detection_precision=arcDetEps; + std::vector<INTERP_KERNEL::Node *> nodes(sz); + INTERP_KERNEL::Edge *edge(0); + for(int j=0;j<sz;j++) + { + int nodeId(conn[*connI+1+j]); + nodes[j]=new INTERP_KERNEL::Node(coords[nodeId*2],coords[nodeId*2+1]); + } + if(!cm.isQuadratic()) + edge=INTERP_KERNEL::QuadraticPolygon::BuildLinearEdge(nodes); + else + edge=INTERP_KERNEL::QuadraticPolygon::BuildArcCircleEdge(nodes); + const INTERP_KERNEL::Bounds& b(edge->getBounds()); + bbox[0]=b.getXMin(); bbox[1]=b.getXMax(); bbox[2]=b.getYMin(); bbox[3]=b.getYMax(); edge->decrRef(); + } + return ret.retn(); +} + +/// @cond INTERNAL + +namespace ParaMEDMEMImpl +{ + class ConnReader + { + public: + ConnReader(const int *c, int val):_conn(c),_val(val) { } + bool operator() (const int& pos) { return _conn[pos]!=_val; } + private: + const int *_conn; + int _val; + }; + + class ConnReader2 + { + public: + ConnReader2(const int *c, int val):_conn(c),_val(val) { } + bool operator() (const int& pos) { return _conn[pos]==_val; } + private: + const int *_conn; + int _val; + }; +} + +/// @endcond + +/*! + * This method expects that \a this is sorted by types. If not an exception will be thrown. + * This method returns in the same format as code (see MEDCouplingUMesh::checkTypeConsistencyAndContig or MEDCouplingUMesh::splitProfilePerType) how + * \a this is composed in cell types. + * The returned array is of size 3*n where n is the number of different types present in \a this. + * For every k in [0,n] ret[3*k+2]==-1 because it has no sense here. + * This parameter is kept only for compatibility with other methode listed above. + */ +std::vector<int> MEDCouplingUMesh::getDistributionOfTypes() const +{ + checkConnectivityFullyDefined(); + const int *conn=_nodal_connec->getConstPointer(); + const int *connI=_nodal_connec_index->getConstPointer(); + const int *work=connI; + int nbOfCells=getNumberOfCells(); + std::size_t n=getAllGeoTypes().size(); + std::vector<int> ret(3*n,-1); //ret[3*k+2]==-1 because it has no sense here + std::set<INTERP_KERNEL::NormalizedCellType> types; + for(std::size_t i=0;work!=connI+nbOfCells;i++) + { + INTERP_KERNEL::NormalizedCellType typ=(INTERP_KERNEL::NormalizedCellType)conn[*work]; + if(types.find(typ)!=types.end()) + { + std::ostringstream oss; oss << "MEDCouplingUMesh::getDistributionOfTypes : Type " << INTERP_KERNEL::CellModel::GetCellModel(typ).getRepr(); + oss << " is not contiguous !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + types.insert(typ); + ret[3*i]=typ; + const int *work2=std::find_if(work+1,connI+nbOfCells,ParaMEDMEMImpl::ConnReader(conn,typ)); + ret[3*i+1]=(int)std::distance(work,work2); + work=work2; + } + return ret; +} + +/*! + * This method is used to check that this has contiguous cell type in same order than described in \a code. + * only for types cell, type node is not managed. + * Format of \a code is the following. \a code should be of size 3*n and non empty. If not an exception is thrown. + * foreach k in [0,n) on 3*k pos represent the geometric type and 3*k+1 number of elements of type 3*k. + * 3*k+2 refers if different from -1 the pos in 'idsPerType' to get the corresponding array. + * If 2 or more same geometric type is in \a code and exception is thrown too. + * + * This method firstly checks + * If it exists k so that 3*k geometric type is not in geometric types of this an exception will be thrown. + * If it exists k so that 3*k geometric type exists but the number of consecutive cell types does not match, + * an exception is thrown too. + * + * If all geometric types in \a code are exactly those in \a this null pointer is returned. + * If it exists a geometric type in \a this \b not in \a code \b no exception is thrown + * and a DataArrayInt instance is returned that the user has the responsability to deallocate. + */ +DataArrayInt *MEDCouplingUMesh::checkTypeConsistencyAndContig(const std::vector<int>& code, const std::vector<const DataArrayInt *>& idsPerType) const +{ + if(code.empty()) + throw INTERP_KERNEL::Exception("MEDCouplingUMesh::checkTypeConsistencyAndContig : code is empty, should not !"); + std::size_t sz=code.size(); + std::size_t n=sz/3; + if(sz%3!=0) + throw INTERP_KERNEL::Exception("MEDCouplingUMesh::checkTypeConsistencyAndContig : code size is NOT %3 !"); + std::vector<INTERP_KERNEL::NormalizedCellType> types; + int nb=0; + bool isNoPflUsed=true; + for(std::size_t i=0;i<n;i++) + if(std::find(types.begin(),types.end(),(INTERP_KERNEL::NormalizedCellType)code[3*i])==types.end()) + { + types.push_back((INTERP_KERNEL::NormalizedCellType)code[3*i]); + nb+=code[3*i+1]; + if(_types.find((INTERP_KERNEL::NormalizedCellType)code[3*i])==_types.end()) + throw INTERP_KERNEL::Exception("MEDCouplingUMesh::checkTypeConsistencyAndContig : expected geo types not in this !"); + isNoPflUsed=isNoPflUsed && (code[3*i+2]==-1); + } + if(types.size()!=n) + throw INTERP_KERNEL::Exception("MEDCouplingUMesh::checkTypeConsistencyAndContig : code contains duplication of types in unstructured mesh !"); + if(isNoPflUsed) + { + if(!checkConsecutiveCellTypesAndOrder(&types[0],&types[0]+types.size())) + throw INTERP_KERNEL::Exception("MEDCouplingUMesh::checkTypeConsistencyAndContig : non contiguous type !"); + if(types.size()==_types.size()) + return 0; + } + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New(); + ret->alloc(nb,1); + int *retPtr=ret->getPointer(); + const int *connI=_nodal_connec_index->getConstPointer(); + const int *conn=_nodal_connec->getConstPointer(); + int nbOfCells=getNumberOfCells(); + const int *i=connI; + int kk=0; + for(std::vector<INTERP_KERNEL::NormalizedCellType>::const_iterator it=types.begin();it!=types.end();it++,kk++) + { + i=std::find_if(i,connI+nbOfCells,ParaMEDMEMImpl::ConnReader2(conn,(int)(*it))); + int offset=(int)std::distance(connI,i); + const int *j=std::find_if(i+1,connI+nbOfCells,ParaMEDMEMImpl::ConnReader(conn,(int)(*it))); + int nbOfCellsOfCurType=(int)std::distance(i,j); + if(code[3*kk+2]==-1) + for(int k=0;k<nbOfCellsOfCurType;k++) + *retPtr++=k+offset; + else + { + int idInIdsPerType=code[3*kk+2]; + if(idInIdsPerType>=0 && idInIdsPerType<(int)idsPerType.size()) + { + const DataArrayInt *zePfl=idsPerType[idInIdsPerType]; + if(zePfl) + { + zePfl->checkAllocated(); + if(zePfl->getNumberOfComponents()==1) + { + for(const int *k=zePfl->begin();k!=zePfl->end();k++,retPtr++) + { + if(*k>=0 && *k<nbOfCellsOfCurType) + *retPtr=(*k)+offset; + else + { + std::ostringstream oss; oss << "MEDCouplingUMesh::checkTypeConsistencyAndContig : the section " << kk << " points to the profile #" << idInIdsPerType; + oss << ", and this profile contains a value " << *k << " should be in [0," << nbOfCellsOfCurType << ") !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + } + } + else + throw INTERP_KERNEL::Exception("MEDCouplingUMesh::checkTypeConsistencyAndContig : presence of a profile with nb of compo != 1 !"); + } + else + throw INTERP_KERNEL::Exception("MEDCouplingUMesh::checkTypeConsistencyAndContig : presence of null profile !"); + } + else + { + std::ostringstream oss; oss << "MEDCouplingUMesh::checkTypeConsistencyAndContig : at section " << kk << " of code it points to the array #" << idInIdsPerType; + oss << " should be in [0," << idsPerType.size() << ") !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + } + i=j; + } + return ret.retn(); +} + +/*! + * This method makes the hypothesis that \a this is sorted by type. If not an exception will be thrown. + * This method is the opposite of MEDCouplingUMesh::checkTypeConsistencyAndContig method. Given a list of cells in \a profile it returns a list of sub-profiles sorted by geo type. + * The result is put in the array \a idsPerType. In the returned parameter \a code, foreach i \a code[3*i+2] refers (if different from -1) to a location into the \a idsPerType. + * This method has 1 input \a profile and 3 outputs \a code \a idsInPflPerType and \a idsPerType. + * + * \param [in] profile + * \param [out] code is a vector of size 3*n where n is the number of different geometric type in \a this \b reduced to the profile \a profile. \a code has exactly the same semantic than in MEDCouplingUMesh::checkTypeConsistencyAndContig method. + * \param [out] idsInPflPerType is a vector of size of different geometric type in the subpart defined by \a profile of \a this ( equal to \a code.size()/3). For each i, + * \a idsInPflPerType[i] stores the tuple ids in \a profile that correspond to the geometric type code[3*i+0] + * \param [out] idsPerType is a vector of size of different sub profiles needed to be defined to represent the profile \a profile for a given geometric type. + * This vector can be empty in case of all geometric type cells are fully covered in ascending in the given input \a profile. + * \throw if \a profile has not exactly one component. It throws too, if \a profile contains some values not in [0,getNumberOfCells()) or if \a this is not fully defined + */ +void MEDCouplingUMesh::splitProfilePerType(const DataArrayInt *profile, std::vector<int>& code, std::vector<DataArrayInt *>& idsInPflPerType, std::vector<DataArrayInt *>& idsPerType) const +{ + if(!profile) + throw INTERP_KERNEL::Exception("MEDCouplingUMesh::splitProfilePerType : input profile is NULL !"); + if(profile->getNumberOfComponents()!=1) + throw INTERP_KERNEL::Exception("MEDCouplingUMesh::splitProfilePerType : input profile should have exactly one component !"); + checkConnectivityFullyDefined(); + const int *conn=_nodal_connec->getConstPointer(); + const int *connI=_nodal_connec_index->getConstPointer(); + int nbOfCells=getNumberOfCells(); + std::vector<INTERP_KERNEL::NormalizedCellType> types; + std::vector<int> typeRangeVals(1); + for(const int *i=connI;i!=connI+nbOfCells;) + { + INTERP_KERNEL::NormalizedCellType curType=(INTERP_KERNEL::NormalizedCellType)conn[*i]; + if(std::find(types.begin(),types.end(),curType)!=types.end()) + { + throw INTERP_KERNEL::Exception("MEDCouplingUMesh::splitProfilePerType : current mesh is not sorted by type !"); + } + types.push_back(curType); + i=std::find_if(i+1,connI+nbOfCells,ParaMEDMEMImpl::ConnReader(conn,(int)curType)); + typeRangeVals.push_back((int)std::distance(connI,i)); + } + // + DataArrayInt *castArr=0,*rankInsideCast=0,*castsPresent=0; + profile->splitByValueRange(&typeRangeVals[0],&typeRangeVals[0]+typeRangeVals.size(),castArr,rankInsideCast,castsPresent); + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> tmp0=castArr; + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> tmp1=rankInsideCast; + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> tmp2=castsPresent; + // + int nbOfCastsFinal=castsPresent->getNumberOfTuples(); + code.resize(3*nbOfCastsFinal); + std::vector< MEDCouplingAutoRefCountObjectPtr<DataArrayInt> > idsInPflPerType2; + std::vector< MEDCouplingAutoRefCountObjectPtr<DataArrayInt> > idsPerType2; + for(int i=0;i<nbOfCastsFinal;i++) + { + int castId=castsPresent->getIJ(i,0); + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> tmp3=castArr->getIdsEqual(castId); + idsInPflPerType2.push_back(tmp3); + code[3*i]=(int)types[castId]; + code[3*i+1]=tmp3->getNumberOfTuples(); + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> tmp4=rankInsideCast->selectByTupleId(tmp3->getConstPointer(),tmp3->getConstPointer()+tmp3->getNumberOfTuples()); + if(tmp4->getNumberOfTuples()!=typeRangeVals[castId+1]-typeRangeVals[castId] || !tmp4->isIdentity()) + { + tmp4->copyStringInfoFrom(*profile); + idsPerType2.push_back(tmp4); + code[3*i+2]=(int)idsPerType2.size()-1; + } + else + { + code[3*i+2]=-1; + } + } + std::size_t sz2=idsInPflPerType2.size(); + idsInPflPerType.resize(sz2); + for(std::size_t i=0;i<sz2;i++) + { + DataArrayInt *locDa=idsInPflPerType2[i]; + locDa->incrRef(); + idsInPflPerType[i]=locDa; + } + std::size_t sz=idsPerType2.size(); + idsPerType.resize(sz); + for(std::size_t i=0;i<sz;i++) + { + DataArrayInt *locDa=idsPerType2[i]; + locDa->incrRef(); + idsPerType[i]=locDa; + } +} + +/*! + * This method is here too emulate the MEDMEM behaviour on BDC (buildDescendingConnectivity). Hoping this method becomes deprecated very soon. + * This method make the assumption that \a this and 'nM1LevMesh' mesh lyies on same coords (same pointer) as MED and MEDMEM does. + * The following equality should be verified 'nM1LevMesh->getMeshDimension()==this->getMeshDimension()-1' + * This method returns 5+2 elements. 'desc', 'descIndx', 'revDesc', 'revDescIndx' and 'meshnM1' behaves exactly as ParaMEDMEM::MEDCouplingUMesh::buildDescendingConnectivity except the content as described after. The returned array specifies the n-1 mesh reordered by type as MEDMEM does. 'nM1LevMeshIds' contains the ids in returned 'meshnM1'. Finally 'meshnM1Old2New' contains numbering old2new that is to say the cell #k in coarse 'nM1LevMesh' will have the number ret[k] in returned mesh 'nM1LevMesh' MEDMEM reordered. + */ +MEDCouplingUMesh *MEDCouplingUMesh::emulateMEDMEMBDC(const MEDCouplingUMesh *nM1LevMesh, DataArrayInt *desc, DataArrayInt *descIndx, DataArrayInt *&revDesc, DataArrayInt *&revDescIndx, DataArrayInt *& nM1LevMeshIds, DataArrayInt *&meshnM1Old2New) const +{ + checkFullyDefined(); + nM1LevMesh->checkFullyDefined(); + if(getMeshDimension()-1!=nM1LevMesh->getMeshDimension()) + throw INTERP_KERNEL::Exception("MEDCouplingUMesh::emulateMEDMEMBDC : The mesh passed as first argument should have a meshDim equal to this->getMeshDimension()-1 !" ); + if(_coords!=nM1LevMesh->getCoords()) + throw INTERP_KERNEL::Exception("MEDCouplingUMesh::emulateMEDMEMBDC : 'this' and mesh in first argument should share the same coords : Use tryToShareSameCoords method !"); + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> tmp0=DataArrayInt::New(); + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> tmp1=DataArrayInt::New(); + MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> ret1=buildDescendingConnectivity(desc,descIndx,tmp0,tmp1); + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret0=ret1->sortCellsInMEDFileFrmt(); + desc->transformWithIndArr(ret0->getConstPointer(),ret0->getConstPointer()+ret0->getNbOfElems()); + MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> tmp=MEDCouplingUMesh::New(); + tmp->setConnectivity(tmp0,tmp1); + tmp->renumberCells(ret0->getConstPointer(),false); + revDesc=tmp->getNodalConnectivity(); + revDescIndx=tmp->getNodalConnectivityIndex(); + DataArrayInt *ret=0; + if(!ret1->areCellsIncludedIn(nM1LevMesh,2,ret)) + { + int tmp2; + ret->getMaxValue(tmp2); + ret->decrRef(); + std::ostringstream oss; oss << "MEDCouplingUMesh::emulateMEDMEMBDC : input N-1 mesh present a cell not in descending mesh ... Id of cell is " << tmp2 << " !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + nM1LevMeshIds=ret; + // + revDesc->incrRef(); + revDescIndx->incrRef(); + ret1->incrRef(); + ret0->incrRef(); + meshnM1Old2New=ret0; + return ret1; +} + +/*! + * Permutes the nodal connectivity arrays so that the cells are sorted by type, which is + * necessary for writing the mesh to MED file. Additionally returns a permutation array + * in "Old to New" mode. + * \return DataArrayInt * - a new instance of DataArrayInt. The caller is to delete + * this array using decrRef() as it is no more needed. + * \throw If the nodal connectivity of cells is not defined. + */ +DataArrayInt *MEDCouplingUMesh::sortCellsInMEDFileFrmt() +{ + checkConnectivityFullyDefined(); + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=getRenumArrForMEDFileFrmt(); + renumberCells(ret->getConstPointer(),false); + return ret.retn(); +} + +/*! + * This methods checks that cells are sorted by their types. + * This method makes asumption (no check) that connectivity is correctly set before calling. + */ +bool MEDCouplingUMesh::checkConsecutiveCellTypes() const +{ + checkFullyDefined(); + const int *conn=_nodal_connec->getConstPointer(); + const int *connI=_nodal_connec_index->getConstPointer(); + int nbOfCells=getNumberOfCells(); + std::set<INTERP_KERNEL::NormalizedCellType> types; + for(const int *i=connI;i!=connI+nbOfCells;) + { + INTERP_KERNEL::NormalizedCellType curType=(INTERP_KERNEL::NormalizedCellType)conn[*i]; + if(types.find(curType)!=types.end()) + return false; + types.insert(curType); + i=std::find_if(i+1,connI+nbOfCells,ParaMEDMEMImpl::ConnReader(conn,(int)curType)); + } + return true; +} + +/*! + * This method is a specialization of MEDCouplingUMesh::checkConsecutiveCellTypesAndOrder method that is called here. + * The geometric type order is specified by MED file. + * + * \sa MEDCouplingUMesh::checkConsecutiveCellTypesAndOrder + */ +bool MEDCouplingUMesh::checkConsecutiveCellTypesForMEDFileFrmt() const +{ + return checkConsecutiveCellTypesAndOrder(MEDMEM_ORDER,MEDMEM_ORDER+N_MEDMEM_ORDER); +} + +/*! + * This method performs the same job as checkConsecutiveCellTypes except that the order of types sequence is analyzed to check + * that the order is specified in array defined by [ \a orderBg , \a orderEnd ). + * If there is some geo types in \a this \b NOT in [ \a orderBg, \a orderEnd ) it is OK (return true) if contiguous. + * If there is some geo types in [ \a orderBg, \a orderEnd ) \b NOT in \a this it is OK too (return true) if contiguous. + */ +bool MEDCouplingUMesh::checkConsecutiveCellTypesAndOrder(const INTERP_KERNEL::NormalizedCellType *orderBg, const INTERP_KERNEL::NormalizedCellType *orderEnd) const +{ + checkFullyDefined(); + const int *conn=_nodal_connec->getConstPointer(); + const int *connI=_nodal_connec_index->getConstPointer(); + int nbOfCells=getNumberOfCells(); + if(nbOfCells==0) + return true; + int lastPos=-1; + std::set<INTERP_KERNEL::NormalizedCellType> sg; + for(const int *i=connI;i!=connI+nbOfCells;) + { + INTERP_KERNEL::NormalizedCellType curType=(INTERP_KERNEL::NormalizedCellType)conn[*i]; + const INTERP_KERNEL::NormalizedCellType *isTypeExists=std::find(orderBg,orderEnd,curType); + if(isTypeExists!=orderEnd) + { + int pos=(int)std::distance(orderBg,isTypeExists); + if(pos<=lastPos) + return false; + lastPos=pos; + i=std::find_if(i+1,connI+nbOfCells,ParaMEDMEMImpl::ConnReader(conn,(int)curType)); + } + else + { + if(sg.find(curType)==sg.end()) + { + i=std::find_if(i+1,connI+nbOfCells,ParaMEDMEMImpl::ConnReader(conn,(int)curType)); + sg.insert(curType); + } + else + return false; + } + } + return true; +} + +/*! + * This method returns 2 newly allocated DataArrayInt instances. The first is an array of size 'this->getNumberOfCells()' with one component, + * that tells for each cell the pos of its type in the array on type given in input parameter. The 2nd output parameter is an array with the same + * number of tuples than input type array and with one component. This 2nd output array gives type by type the number of occurence of type in 'this'. + */ +DataArrayInt *MEDCouplingUMesh::getLevArrPerCellTypes(const INTERP_KERNEL::NormalizedCellType *orderBg, const INTERP_KERNEL::NormalizedCellType *orderEnd, DataArrayInt *&nbPerType) const +{ + checkConnectivityFullyDefined(); + int nbOfCells=getNumberOfCells(); + const int *conn=_nodal_connec->getConstPointer(); + const int *connI=_nodal_connec_index->getConstPointer(); + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> tmpa=DataArrayInt::New(); + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> tmpb=DataArrayInt::New(); + tmpa->alloc(nbOfCells,1); + tmpb->alloc((int)std::distance(orderBg,orderEnd),1); + tmpb->fillWithZero(); + int *tmp=tmpa->getPointer(); + int *tmp2=tmpb->getPointer(); + for(const int *i=connI;i!=connI+nbOfCells;i++) + { + const INTERP_KERNEL::NormalizedCellType *where=std::find(orderBg,orderEnd,(INTERP_KERNEL::NormalizedCellType)conn[*i]); + if(where!=orderEnd) + { + int pos=(int)std::distance(orderBg,where); + tmp2[pos]++; + tmp[std::distance(connI,i)]=pos; + } + else + { + const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel((INTERP_KERNEL::NormalizedCellType)conn[*i]); + std::ostringstream oss; oss << "MEDCouplingUMesh::getLevArrPerCellTypes : Cell #" << std::distance(connI,i); + oss << " has a type " << cm.getRepr() << " not in input array of type !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + } + nbPerType=tmpb.retn(); + return tmpa.retn(); +} + +/*! + * This method behaves exactly as MEDCouplingUMesh::getRenumArrForConsecutiveCellTypesSpec but the order is those defined in MED file spec. + * + * \return a new object containing the old to new correspondance. + * + * \sa MEDCouplingUMesh::getRenumArrForConsecutiveCellTypesSpec, MEDCouplingUMesh::sortCellsInMEDFileFrmt. + */ +DataArrayInt *MEDCouplingUMesh::getRenumArrForMEDFileFrmt() const +{ + return getRenumArrForConsecutiveCellTypesSpec(MEDMEM_ORDER,MEDMEM_ORDER+N_MEDMEM_ORDER); +} + +/*! + * This method is similar to method MEDCouplingUMesh::rearrange2ConsecutiveCellTypes except that the type order is specfied by [ \a orderBg , \a orderEnd ) (as MEDCouplingUMesh::checkConsecutiveCellTypesAndOrder method) and that this method is \b const and performs \b NO permutation in \a this. + * This method returns an array of size getNumberOfCells() that gives a renumber array old2New that can be used as input of MEDCouplingMesh::renumberCells. + * The mesh after this call to MEDCouplingMesh::renumberCells will pass the test of MEDCouplingUMesh::checkConsecutiveCellTypesAndOrder with the same inputs. + * The returned array minimizes the permutations that is to say the order of cells inside same geometric type remains the same. + */ +DataArrayInt *MEDCouplingUMesh::getRenumArrForConsecutiveCellTypesSpec(const INTERP_KERNEL::NormalizedCellType *orderBg, const INTERP_KERNEL::NormalizedCellType *orderEnd) const +{ + DataArrayInt *nbPerType=0; + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> tmpa=getLevArrPerCellTypes(orderBg,orderEnd,nbPerType); + nbPerType->decrRef(); + return tmpa->buildPermArrPerLevel(); +} + +/*! + * This method reorganize the cells of \a this so that the cells with same geometric types are put together. + * The number of cells remains unchanged after the call of this method. + * This method tries to minimizes the number of needed permutations. So, this method behaves not exactly as + * MEDCouplingUMesh::sortCellsInMEDFileFrmt. + * + * \return the array giving the correspondance old to new. + */ +DataArrayInt *MEDCouplingUMesh::rearrange2ConsecutiveCellTypes() +{ + checkFullyDefined(); + computeTypes(); + const int *conn=_nodal_connec->getConstPointer(); + const int *connI=_nodal_connec_index->getConstPointer(); + int nbOfCells=getNumberOfCells(); + std::vector<INTERP_KERNEL::NormalizedCellType> types; + for(const int *i=connI;i!=connI+nbOfCells && (types.size()!=_types.size());) + if(std::find(types.begin(),types.end(),(INTERP_KERNEL::NormalizedCellType)conn[*i])==types.end()) + { + INTERP_KERNEL::NormalizedCellType curType=(INTERP_KERNEL::NormalizedCellType)conn[*i]; + types.push_back(curType); + for(i++;i!=connI+nbOfCells && (INTERP_KERNEL::NormalizedCellType)conn[*i]==curType;i++); + } + DataArrayInt *ret=DataArrayInt::New(); + ret->alloc(nbOfCells,1); + int *retPtr=ret->getPointer(); + std::fill(retPtr,retPtr+nbOfCells,-1); + int newCellId=0; + for(std::vector<INTERP_KERNEL::NormalizedCellType>::const_iterator iter=types.begin();iter!=types.end();iter++) + { + for(const int *i=connI;i!=connI+nbOfCells;i++) + if((INTERP_KERNEL::NormalizedCellType)conn[*i]==(*iter)) + retPtr[std::distance(connI,i)]=newCellId++; + } + renumberCells(retPtr,false); + return ret; +} + +/*! + * This method splits \a this into as mush as untructured meshes that consecutive set of same type cells. + * So this method has typically a sense if MEDCouplingUMesh::checkConsecutiveCellTypes has a sense. + * This method makes asumption that connectivity is correctly set before calling. + */ +std::vector<MEDCouplingUMesh *> MEDCouplingUMesh::splitByType() const +{ + checkConnectivityFullyDefined(); + const int *conn=_nodal_connec->getConstPointer(); + const int *connI=_nodal_connec_index->getConstPointer(); + int nbOfCells=getNumberOfCells(); + std::vector<MEDCouplingUMesh *> ret; + for(const int *i=connI;i!=connI+nbOfCells;) + { + INTERP_KERNEL::NormalizedCellType curType=(INTERP_KERNEL::NormalizedCellType)conn[*i]; + int beginCellId=(int)std::distance(connI,i); + i=std::find_if(i+1,connI+nbOfCells,ParaMEDMEMImpl::ConnReader(conn,(int)curType)); + int endCellId=(int)std::distance(connI,i); + int sz=endCellId-beginCellId; + int *cells=new int[sz]; + for(int j=0;j<sz;j++) + cells[j]=beginCellId+j; + MEDCouplingUMesh *m=(MEDCouplingUMesh *)buildPartOfMySelf(cells,cells+sz,true); + delete [] cells; + ret.push_back(m); + } + return ret; +} + +/*! + * This method performs the opposite operation than those in MEDCoupling1SGTUMesh::buildUnstructured. + * If \a this is a single geometric type unstructured mesh, it will be converted into a more compact data structure, + * MEDCoupling1GTUMesh instance. The returned instance will aggregate the same DataArrayDouble instance of coordinates than \a this. + * + * \return a newly allocated instance, that the caller must manage. + * \throw If \a this contains more than one geometric type. + * \throw If the nodal connectivity of \a this is not fully defined. + * \throw If the internal data is not coherent. + */ +MEDCoupling1GTUMesh *MEDCouplingUMesh::convertIntoSingleGeoTypeMesh() const +{ + checkConnectivityFullyDefined(); + if(_types.size()!=1) + throw INTERP_KERNEL::Exception("MEDCouplingUMesh::convertIntoSingleGeoTypeMesh : current mesh does not contain exactly one geometric type !"); + INTERP_KERNEL::NormalizedCellType typ=*_types.begin(); + MEDCouplingAutoRefCountObjectPtr<MEDCoupling1GTUMesh> ret=MEDCoupling1GTUMesh::New(getName(),typ); + ret->setCoords(getCoords()); + MEDCoupling1SGTUMesh *retC=dynamic_cast<MEDCoupling1SGTUMesh *>((MEDCoupling1GTUMesh*)ret); + if(retC) + { + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> c=convertNodalConnectivityToStaticGeoTypeMesh(); + retC->setNodalConnectivity(c); + } + else + { + MEDCoupling1DGTUMesh *retD=dynamic_cast<MEDCoupling1DGTUMesh *>((MEDCoupling1GTUMesh*)ret); + if(!retD) + throw INTERP_KERNEL::Exception("MEDCouplingUMesh::convertIntoSingleGeoTypeMesh : Internal error !"); + DataArrayInt *c=0,*ci=0; + convertNodalConnectivityToDynamicGeoTypeMesh(c,ci); + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> cs(c),cis(ci); + retD->setNodalConnectivity(cs,cis); + } + return ret.retn(); +} + +DataArrayInt *MEDCouplingUMesh::convertNodalConnectivityToStaticGeoTypeMesh() const +{ + checkConnectivityFullyDefined(); + if(_types.size()!=1) + throw INTERP_KERNEL::Exception("MEDCouplingUMesh::convertNodalConnectivityToStaticGeoTypeMesh : current mesh does not contain exactly one geometric type !"); + INTERP_KERNEL::NormalizedCellType typ=*_types.begin(); + const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(typ); + if(cm.isDynamic()) + { + std::ostringstream oss; oss << "MEDCouplingUMesh::convertNodalConnectivityToStaticGeoTypeMesh : this contains a single geo type (" << cm.getRepr() << ") but "; + oss << "this type is dynamic ! Only static geometric type is possible for that type ! call convertNodalConnectivityToDynamicGeoTypeMesh instead !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + int nbCells=getNumberOfCells(); + int typi=(int)typ; + int nbNodesPerCell=(int)cm.getNumberOfNodes(); + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> connOut=DataArrayInt::New(); connOut->alloc(nbCells*nbNodesPerCell,1); + int *outPtr=connOut->getPointer(); + const int *conn=_nodal_connec->begin(); + const int *connI=_nodal_connec_index->begin(); + nbNodesPerCell++; + for(int i=0;i<nbCells;i++,connI++) + { + if(conn[connI[0]]==typi && connI[1]-connI[0]==nbNodesPerCell) + outPtr=std::copy(conn+connI[0]+1,conn+connI[1],outPtr); + else + { + std::ostringstream oss; oss << "MEDCouplingUMesh::convertNodalConnectivityToStaticGeoTypeMesh : there something wrong in cell #" << i << " ! The type of cell is not those expected, or the length of nodal connectivity is not those expected (" << nbNodesPerCell-1 << ") !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + } + return connOut.retn(); +} + +/*! + * Convert the nodal connectivity of the mesh so that all the cells are of dynamic types (polygon or quadratic + * polygon). This returns the corresponding new nodal connectivity in \ref numbering-indirect format. + * \param nodalConn + * \param nodalConnI + */ +void MEDCouplingUMesh::convertNodalConnectivityToDynamicGeoTypeMesh(DataArrayInt *&nodalConn, DataArrayInt *&nodalConnIndex) const +{ + static const char msg0[]="MEDCouplingUMesh::convertNodalConnectivityToDynamicGeoTypeMesh : nodal connectivity in this are invalid ! Call checkCoherency2 !"; + checkConnectivityFullyDefined(); + if(_types.size()!=1) + throw INTERP_KERNEL::Exception("MEDCouplingUMesh::convertNodalConnectivityToDynamicGeoTypeMesh : current mesh does not contain exactly one geometric type !"); + int nbCells=getNumberOfCells(),lgth=_nodal_connec->getNumberOfTuples(); + if(lgth<nbCells) + throw INTERP_KERNEL::Exception(msg0); + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> c(DataArrayInt::New()),ci(DataArrayInt::New()); + c->alloc(lgth-nbCells,1); ci->alloc(nbCells+1,1); + int *cp(c->getPointer()),*cip(ci->getPointer()); + const int *incp(_nodal_connec->begin()),*incip(_nodal_connec_index->begin()); + cip[0]=0; + for(int i=0;i<nbCells;i++,cip++,incip++) + { + int strt(incip[0]+1),stop(incip[1]);//+1 to skip geo type + int delta(stop-strt); + if(delta>=1) + { + if((strt>=0 && strt<lgth) && (stop>=0 && stop<=lgth)) + cp=std::copy(incp+strt,incp+stop,cp); + else + throw INTERP_KERNEL::Exception(msg0); + } + else + throw INTERP_KERNEL::Exception(msg0); + cip[1]=cip[0]+delta; + } + nodalConn=c.retn(); nodalConnIndex=ci.retn(); +} + +/*! + * This method takes in input a vector of MEDCouplingUMesh instances lying on the same coordinates with same mesh dimensions. + * Each mesh in \b ms must be sorted by type with the same order (typically using MEDCouplingUMesh::sortCellsInMEDFileFrmt). + * This method is particulary useful for MED file interaction. It allows to aggregate several meshes and keeping the type sorting + * and the track of the permutation by chunk of same geotype cells to retrieve it. The traditional formats old2new and new2old + * are not used here to avoid the build of big permutation array. + * + * \param [in] ms meshes with same mesh dimension lying on the same coords and sorted by type following de the same geometric type order than + * those specified in MEDCouplingUMesh::sortCellsInMEDFileFrmt method. + * \param [out] szOfCellGrpOfSameType is a newly allocated DataArrayInt instance whose number of tuples is equal to the number of chunks of same geotype + * in all meshes in \b ms. The accumulation of all values of this array is equal to the number of cells of returned mesh. + * \param [out] idInMsOfCellGrpOfSameType is a newly allocated DataArrayInt instance having the same size than \b szOfCellGrpOfSameType. This + * output array gives for each chunck of same type the corresponding mesh id in \b ms. + * \return A newly allocated unstructured mesh that is the result of the aggregation on same coords of all meshes in \b ms. This returned mesh + * is sorted by type following the geo cell types order of MEDCouplingUMesh::sortCellsInMEDFileFrmt method. + */ +MEDCouplingUMesh *MEDCouplingUMesh::AggregateSortedByTypeMeshesOnSameCoords(const std::vector<const MEDCouplingUMesh *>& ms, + DataArrayInt *&szOfCellGrpOfSameType, + DataArrayInt *&idInMsOfCellGrpOfSameType) +{ + std::vector<const MEDCouplingUMesh *> ms2; + for(std::vector<const MEDCouplingUMesh *>::const_iterator it=ms.begin();it!=ms.end();it++) + if(*it) + { + (*it)->checkConnectivityFullyDefined(); + ms2.push_back(*it); + } + if(ms2.empty()) + throw INTERP_KERNEL::Exception("MEDCouplingUMesh::AggregateSortedByTypeMeshesOnSameCoords : input vector is empty !"); + const DataArrayDouble *refCoo=ms2[0]->getCoords(); + int meshDim=ms2[0]->getMeshDimension(); + std::vector<const MEDCouplingUMesh *> m1ssm; + std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> > m1ssmAuto; + // + std::vector<const MEDCouplingUMesh *> m1ssmSingle; + std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> > m1ssmSingleAuto; + int fake=0,rk=0; + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret1(DataArrayInt::New()),ret2(DataArrayInt::New()); + ret1->alloc(0,1); ret2->alloc(0,1); + for(std::vector<const MEDCouplingUMesh *>::const_iterator it=ms2.begin();it!=ms2.end();it++,rk++) + { + if(meshDim!=(*it)->getMeshDimension()) + throw INTERP_KERNEL::Exception("MEDCouplingUMesh::AggregateSortedByTypeMeshesOnSameCoords : meshdims mismatch !"); + if(refCoo!=(*it)->getCoords()) + throw INTERP_KERNEL::Exception("MEDCouplingUMesh::AggregateSortedByTypeMeshesOnSameCoords : meshes are not shared by a single coordinates coords !"); + std::vector<MEDCouplingUMesh *> sp=(*it)->splitByType(); + std::copy(sp.begin(),sp.end(),std::back_insert_iterator< std::vector<const MEDCouplingUMesh *> >(m1ssm)); + std::copy(sp.begin(),sp.end(),std::back_insert_iterator< std::vector<MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> > >(m1ssmAuto)); + for(std::vector<MEDCouplingUMesh *>::const_iterator it2=sp.begin();it2!=sp.end();it2++) + { + MEDCouplingUMesh *singleCell=static_cast<MEDCouplingUMesh *>((*it2)->buildPartOfMySelf(&fake,&fake+1,true)); + m1ssmSingleAuto.push_back(singleCell); + m1ssmSingle.push_back(singleCell); + ret1->pushBackSilent((*it2)->getNumberOfCells()); ret2->pushBackSilent(rk); + } + } + MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m1ssmSingle2=MEDCouplingUMesh::MergeUMeshesOnSameCoords(m1ssmSingle); + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> renum=m1ssmSingle2->sortCellsInMEDFileFrmt(); + std::vector<const MEDCouplingUMesh *> m1ssmfinal(m1ssm.size()); + for(std::size_t i=0;i<m1ssm.size();i++) + m1ssmfinal[renum->getIJ(i,0)]=m1ssm[i]; + MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> ret0=MEDCouplingUMesh::MergeUMeshesOnSameCoords(m1ssmfinal); + szOfCellGrpOfSameType=ret1->renumber(renum->getConstPointer()); + idInMsOfCellGrpOfSameType=ret2->renumber(renum->getConstPointer()); + return ret0.retn(); +} + +/*! + * This method returns a newly created DataArrayInt instance. + * This method retrieves cell ids in [ \a begin, \a end ) that have the type \a type. + */ +DataArrayInt *MEDCouplingUMesh::keepCellIdsByType(INTERP_KERNEL::NormalizedCellType type, const int *begin, const int *end) const +{ + checkFullyDefined(); + const int *conn=_nodal_connec->getConstPointer(); + const int *connIndex=_nodal_connec_index->getConstPointer(); + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1); + for(const int *w=begin;w!=end;w++) + if((INTERP_KERNEL::NormalizedCellType)conn[connIndex[*w]]==type) + ret->pushBackSilent(*w); + return ret.retn(); +} + +/*! + * This method makes the assumption that da->getNumberOfTuples()<this->getNumberOfCells(). This method makes the assumption that ids contained in 'da' + * are in [0:getNumberOfCells()) + */ +DataArrayInt *MEDCouplingUMesh::convertCellArrayPerGeoType(const DataArrayInt *da) const +{ + checkFullyDefined(); + const int *conn=_nodal_connec->getConstPointer(); + const int *connI=_nodal_connec_index->getConstPointer(); + int nbOfCells=getNumberOfCells(); + std::set<INTERP_KERNEL::NormalizedCellType> types(getAllGeoTypes()); + int *tmp=new int[nbOfCells]; + for(std::set<INTERP_KERNEL::NormalizedCellType>::const_iterator iter=types.begin();iter!=types.end();iter++) + { + int j=0; + for(const int *i=connI;i!=connI+nbOfCells;i++) + if((INTERP_KERNEL::NormalizedCellType)conn[*i]==(*iter)) + tmp[std::distance(connI,i)]=j++; + } + DataArrayInt *ret=DataArrayInt::New(); + ret->alloc(da->getNumberOfTuples(),da->getNumberOfComponents()); + ret->copyStringInfoFrom(*da); + int *retPtr=ret->getPointer(); + const int *daPtr=da->getConstPointer(); + int nbOfElems=da->getNbOfElems(); + for(int k=0;k<nbOfElems;k++) + retPtr[k]=tmp[daPtr[k]]; + delete [] tmp; + return ret; +} + +/*! + * This method reduced number of cells of this by keeping cells whose type is different from 'type' and if type=='type' + * This method \b works \b for mesh sorted by type. + * cells whose ids is in 'idsPerGeoType' array. + * This method conserves coords and name of mesh. + */ +MEDCouplingUMesh *MEDCouplingUMesh::keepSpecifiedCells(INTERP_KERNEL::NormalizedCellType type, const int *idsPerGeoTypeBg, const int *idsPerGeoTypeEnd) const +{ + std::vector<int> code=getDistributionOfTypes(); + std::size_t nOfTypesInThis=code.size()/3; + int sz=0,szOfType=0; + for(std::size_t i=0;i<nOfTypesInThis;i++) + { + if(code[3*i]!=type) + sz+=code[3*i+1]; + else + szOfType=code[3*i+1]; + } + for(const int *work=idsPerGeoTypeBg;work!=idsPerGeoTypeEnd;work++) + if(*work<0 || *work>=szOfType) + { + std::ostringstream oss; oss << "MEDCouplingUMesh::keepSpecifiedCells : Request on type " << type << " at place #" << std::distance(idsPerGeoTypeBg,work) << " value " << *work; + oss << ". It should be in [0," << szOfType << ") !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> idsTokeep=DataArrayInt::New(); idsTokeep->alloc(sz+(int)std::distance(idsPerGeoTypeBg,idsPerGeoTypeEnd),1); + int *idsPtr=idsTokeep->getPointer(); + int offset=0; + for(std::size_t i=0;i<nOfTypesInThis;i++) + { + if(code[3*i]!=type) + for(int j=0;j<code[3*i+1];j++) + *idsPtr++=offset+j; + else + idsPtr=std::transform(idsPerGeoTypeBg,idsPerGeoTypeEnd,idsPtr,std::bind2nd(std::plus<int>(),offset)); + offset+=code[3*i+1]; + } + MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> ret=static_cast<MEDCouplingUMesh *>(buildPartOfMySelf(idsTokeep->begin(),idsTokeep->end(),true)); + ret->copyTinyInfoFrom(this); + return ret.retn(); +} + +/*! + * This method returns a vector of size 'this->getNumberOfCells()'. + * This method retrieves for each cell in \a this if it is linear (false) or quadratic(true). + */ +std::vector<bool> MEDCouplingUMesh::getQuadraticStatus() const +{ + int ncell=getNumberOfCells(); + std::vector<bool> ret(ncell); + const int *cI=getNodalConnectivityIndex()->getConstPointer(); + const int *c=getNodalConnectivity()->getConstPointer(); + for(int i=0;i<ncell;i++) + { + INTERP_KERNEL::NormalizedCellType typ=(INTERP_KERNEL::NormalizedCellType)c[cI[i]]; + const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(typ); + ret[i]=cm.isQuadratic(); + } + return ret; +} + +/*! + * Returns a newly created mesh (with ref count ==1) that contains merge of \a this and \a other. + */ +MEDCouplingMesh *MEDCouplingUMesh::mergeMyselfWith(const MEDCouplingMesh *other) const +{ + if(other->getType()!=UNSTRUCTURED) + throw INTERP_KERNEL::Exception("Merge of umesh only available with umesh each other !"); + const MEDCouplingUMesh *otherC=static_cast<const MEDCouplingUMesh *>(other); + return MergeUMeshes(this,otherC); +} + +/*! + * Returns a new DataArrayDouble holding barycenters of all cells. The barycenter is + * computed by averaging coordinates of cell nodes, so this method is not a right + * choice for degnerated meshes (not well oriented, cells with measure close to zero). + * \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. + * \throw If the coordinates array is not set. + * \throw If the nodal connectivity of cells is not defined. + * \sa MEDCouplingUMesh::computeIsoBarycenterOfNodesPerCell + */ +DataArrayDouble *MEDCouplingUMesh::getBarycenterAndOwner() const +{ + MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New(); + int spaceDim=getSpaceDimension(); + int nbOfCells=getNumberOfCells(); + ret->alloc(nbOfCells,spaceDim); + ret->copyStringInfoFrom(*getCoords()); + double *ptToFill=ret->getPointer(); + const int *nodal=_nodal_connec->getConstPointer(); + const int *nodalI=_nodal_connec_index->getConstPointer(); + const double *coor=_coords->getConstPointer(); + for(int i=0;i<nbOfCells;i++) + { + INTERP_KERNEL::NormalizedCellType type=(INTERP_KERNEL::NormalizedCellType)nodal[nodalI[i]]; + INTERP_KERNEL::computeBarycenter2<int,INTERP_KERNEL::ALL_C_MODE>(type,nodal+nodalI[i]+1,nodalI[i+1]-nodalI[i]-1,coor,spaceDim,ptToFill); + ptToFill+=spaceDim; + } + return ret.retn(); +} + +/*! + * This method computes for each cell in \a this, the location of the iso barycenter of nodes constituting + * the cell. Contrary to badly named MEDCouplingUMesh::getBarycenterAndOwner method that returns the center of inertia of the + * + * \return a newly allocated DataArrayDouble instance that the caller has to deal with. The returned + * DataArrayDouble instance will have \c this->getNumberOfCells() tuples and \c this->getSpaceDimension() components. + * + * \sa MEDCouplingUMesh::getBarycenterAndOwner + * \throw If \a this is not fully defined (coordinates and connectivity) + * \throw If there is presence in nodal connectivity in \a this of node ids not in [0, \c this->getNumberOfNodes() ) + */ +DataArrayDouble *MEDCouplingUMesh::computeIsoBarycenterOfNodesPerCell() const +{ + checkFullyDefined(); + MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New(); + int spaceDim=getSpaceDimension(); + int nbOfCells=getNumberOfCells(); + int nbOfNodes=getNumberOfNodes(); + ret->alloc(nbOfCells,spaceDim); + double *ptToFill=ret->getPointer(); + const int *nodal=_nodal_connec->getConstPointer(); + const int *nodalI=_nodal_connec_index->getConstPointer(); + const double *coor=_coords->getConstPointer(); + for(int i=0;i<nbOfCells;i++,ptToFill+=spaceDim) + { + INTERP_KERNEL::NormalizedCellType type=(INTERP_KERNEL::NormalizedCellType)nodal[nodalI[i]]; + std::fill(ptToFill,ptToFill+spaceDim,0.); + if(type!=INTERP_KERNEL::NORM_POLYHED) + { + for(const int *conn=nodal+nodalI[i]+1;conn!=nodal+nodalI[i+1];conn++) + { + if(*conn>=0 && *conn<nbOfNodes) + std::transform(coor+spaceDim*conn[0],coor+spaceDim*(conn[0]+1),ptToFill,ptToFill,std::plus<double>()); + else + { + std::ostringstream oss; oss << "MEDCouplingUMesh::computeIsoBarycenterOfNodesPerCell : on cell #" << i << " presence of nodeId #" << *conn << " should be in [0," << nbOfNodes << ") !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + } + int nbOfNodesInCell=nodalI[i+1]-nodalI[i]-1; + if(nbOfNodesInCell>0) + std::transform(ptToFill,ptToFill+spaceDim,ptToFill,std::bind2nd(std::multiplies<double>(),1./(double)nbOfNodesInCell)); + else + { + std::ostringstream oss; oss << "MEDCouplingUMesh::computeIsoBarycenterOfNodesPerCell : on cell #" << i << " presence of cell with no nodes !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + } + else + { + std::set<int> s(nodal+nodalI[i]+1,nodal+nodalI[i+1]); + s.erase(-1); + for(std::set<int>::const_iterator it=s.begin();it!=s.end();it++) + { + if(*it>=0 && *it<nbOfNodes) + std::transform(coor+spaceDim*(*it),coor+spaceDim*((*it)+1),ptToFill,ptToFill,std::plus<double>()); + else + { + std::ostringstream oss; oss << "MEDCouplingUMesh::computeIsoBarycenterOfNodesPerCell : on cell polyhedron cell #" << i << " presence of nodeId #" << *it << " should be in [0," << nbOfNodes << ") !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + } + if(!s.empty()) + std::transform(ptToFill,ptToFill+spaceDim,ptToFill,std::bind2nd(std::multiplies<double>(),1./(double)s.size())); + else + { + std::ostringstream oss; oss << "MEDCouplingUMesh::computeIsoBarycenterOfNodesPerCell : on polyhedron cell #" << i << " there are no nodes !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + } + } + return ret.retn(); +} + +/*! + * Returns a new DataArrayDouble holding barycenters of specified cells. The + * barycenter is computed by averaging coordinates of cell nodes. The cells to treat + * are specified via an array of cell ids. + * \warning Validity of the specified cell ids is not checked! + * Valid range is [ 0, \a this->getNumberOfCells() ). + * \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. + * \return DataArrayDouble * - a new instance of DataArrayDouble, of size ( \a + * end - \a begin ) tuples per \a this->getSpaceDimension() components. The + * caller is to delete this array using decrRef() as it is no more needed. + * \throw If the coordinates array is not set. + * \throw If the nodal connectivity of cells is not defined. + * + * \if ENABLE_EXAMPLES + * \ref cpp_mcumesh_getPartBarycenterAndOwner "Here is a C++ example".<br> + * \ref py_mcumesh_getPartBarycenterAndOwner "Here is a Python example". + * \endif + */ +DataArrayDouble *MEDCouplingUMesh::getPartBarycenterAndOwner(const int *begin, const int *end) const +{ + DataArrayDouble *ret=DataArrayDouble::New(); + int spaceDim=getSpaceDimension(); + int nbOfTuple=(int)std::distance(begin,end); + ret->alloc(nbOfTuple,spaceDim); + double *ptToFill=ret->getPointer(); + double *tmp=new double[spaceDim]; + const int *nodal=_nodal_connec->getConstPointer(); + const int *nodalI=_nodal_connec_index->getConstPointer(); + const double *coor=_coords->getConstPointer(); + for(const int *w=begin;w!=end;w++) + { + INTERP_KERNEL::NormalizedCellType type=(INTERP_KERNEL::NormalizedCellType)nodal[nodalI[*w]]; + INTERP_KERNEL::computeBarycenter2<int,INTERP_KERNEL::ALL_C_MODE>(type,nodal+nodalI[*w]+1,nodalI[*w+1]-nodalI[*w]-1,coor,spaceDim,ptToFill); + ptToFill+=spaceDim; + } + delete [] tmp; + return ret; +} + +/*! + * Returns a DataArrayDouble instance giving for each cell in \a this the equation of plane given by "a*X+b*Y+c*Z+d=0". + * So the returned instance will have 4 components and \c this->getNumberOfCells() tuples. + * So this method expects that \a this has a spaceDimension equal to 3 and meshDimension equal to 2. + * The computation of the plane equation is done using each time the 3 first nodes of 2D cells. + * This method is useful to detect 2D cells in 3D space that are not coplanar. + * + * \return DataArrayDouble * - a new instance of DataArrayDouble having 4 components and a number of tuples equal to number of cells in \a this. + * \throw If spaceDim!=3 or meshDim!=2. + * \throw If connectivity of \a this is invalid. + * \throw If connectivity of a cell in \a this points to an invalid node. + */ +DataArrayDouble *MEDCouplingUMesh::computePlaneEquationOf3DFaces() const +{ + MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret(DataArrayDouble::New()); + int nbOfCells(getNumberOfCells()),nbOfNodes(getNumberOfNodes()); + if(getSpaceDimension()!=3 || getMeshDimension()!=2) + throw INTERP_KERNEL::Exception("MEDCouplingUMesh::computePlaneEquationOf3DFaces : This method must be applied on a mesh having meshDimension equal 2 and a spaceDimension equal to 3 !"); + ret->alloc(nbOfCells,4); + double *retPtr(ret->getPointer()); + const int *nodal(_nodal_connec->begin()),*nodalI(_nodal_connec_index->begin()); + const double *coor(_coords->begin()); + for(int i=0;i<nbOfCells;i++,nodalI++,retPtr+=4) + { + double matrix[16]={0,0,0,1,0,0,0,1,0,0,0,1,1,1,1,0},matrix2[16]; + if(nodalI[1]-nodalI[0]>=3) + { + for(int j=0;j<3;j++) + { + int nodeId(nodal[nodalI[0]+1+j]); + if(nodeId>=0 && nodeId<nbOfNodes) + std::copy(coor+nodeId*3,coor+(nodeId+1)*3,matrix+4*j); + else + { + std::ostringstream oss; oss << "MEDCouplingUMesh::computePlaneEquationOf3DFaces : invalid 2D cell #" << i << " ! This cell points to an invalid nodeId : " << nodeId << " !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + } + } + else + { + std::ostringstream oss; oss << "MEDCouplingUMesh::computePlaneEquationOf3DFaces : invalid 2D cell #" << i << " ! Must be constitued by more than 3 nodes !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + INTERP_KERNEL::inverseMatrix(matrix,4,matrix2); + retPtr[0]=matrix2[3]; retPtr[1]=matrix2[7]; retPtr[2]=matrix2[11]; retPtr[3]=matrix2[15]; + } + return ret.retn(); +} + +/*! + * This method expects as input a DataArrayDouble non nul instance 'da' that should be allocated. If not an exception is thrown. + * + */ +MEDCouplingUMesh *MEDCouplingUMesh::Build0DMeshFromCoords(DataArrayDouble *da) +{ + if(!da) + throw INTERP_KERNEL::Exception("MEDCouplingUMesh::Build0DMeshFromCoords : instance of DataArrayDouble must be not null !"); + da->checkAllocated(); + MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> ret=MEDCouplingUMesh::New(da->getName(),0); + ret->setCoords(da); + int nbOfTuples=da->getNumberOfTuples(); + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> c=DataArrayInt::New(); + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> cI=DataArrayInt::New(); + c->alloc(2*nbOfTuples,1); + cI->alloc(nbOfTuples+1,1); + int *cp=c->getPointer(); + int *cip=cI->getPointer(); + *cip++=0; + for(int i=0;i<nbOfTuples;i++) + { + *cp++=INTERP_KERNEL::NORM_POINT1; + *cp++=i; + *cip++=2*(i+1); + } + ret->setConnectivity(c,cI,true); + return ret.retn(); +} +/*! + * Creates a new MEDCouplingUMesh by concatenating two given meshes of the same dimension. + * Cells and nodes of + * the first mesh precede cells and nodes of the second mesh within the result mesh. + * \param [in] mesh1 - the first mesh. + * \param [in] mesh2 - the second mesh. + * \return MEDCouplingUMesh * - 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 mesh1 == NULL or \a mesh2 == NULL. + * \throw If the coordinates array is not set in none of the meshes. + * \throw If \a mesh1->getMeshDimension() < 0 or \a mesh2->getMeshDimension() < 0. + * \throw If \a mesh1->getMeshDimension() != \a mesh2->getMeshDimension(). + */ +MEDCouplingUMesh *MEDCouplingUMesh::MergeUMeshes(const MEDCouplingUMesh *mesh1, const MEDCouplingUMesh *mesh2) +{ + std::vector<const MEDCouplingUMesh *> tmp(2); + tmp[0]=const_cast<MEDCouplingUMesh *>(mesh1); tmp[1]=const_cast<MEDCouplingUMesh *>(mesh2); + return MergeUMeshes(tmp); +} + +/*! + * Creates a new MEDCouplingUMesh by concatenating all given meshes of the same dimension. + * Cells and nodes of + * the *i*-th mesh precede cells and nodes of the (*i*+1)-th mesh within the result mesh. + * \param [in] a - a vector of meshes (MEDCouplingUMesh) to concatenate. + * \return MEDCouplingUMesh * - 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 a.size() == 0. + * \throw If \a a[ *i* ] == NULL. + * \throw If the coordinates array is not set in none of the meshes. + * \throw If \a a[ *i* ]->getMeshDimension() < 0. + * \throw If the meshes in \a a are of different dimension (getMeshDimension()). + */ +MEDCouplingUMesh *MEDCouplingUMesh::MergeUMeshes(std::vector<const MEDCouplingUMesh *>& a) +{ + std::size_t sz=a.size(); + if(sz==0) + return MergeUMeshesLL(a); + for(std::size_t ii=0;ii<sz;ii++) + if(!a[ii]) + { + std::ostringstream oss; oss << "MEDCouplingUMesh::MergeUMeshes : item #" << ii << " in input array of size "<< sz << " is empty !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> > bb(sz); + std::vector< const MEDCouplingUMesh * > aa(sz); + int spaceDim=-3; + for(std::size_t i=0;i<sz && spaceDim==-3;i++) + { + const MEDCouplingUMesh *cur=a[i]; + const DataArrayDouble *coo=cur->getCoords(); + if(coo) + spaceDim=coo->getNumberOfComponents(); + } + if(spaceDim==-3) + throw INTERP_KERNEL::Exception("MEDCouplingUMesh::MergeUMeshes : no spaceDim specified ! unable to perform merge !"); + for(std::size_t i=0;i<sz;i++) + { + bb[i]=a[i]->buildSetInstanceFromThis(spaceDim); + aa[i]=bb[i]; + } + return MergeUMeshesLL(aa); +} + +/// @cond INTERNAL + +MEDCouplingUMesh *MEDCouplingUMesh::MergeUMeshesLL(std::vector<const MEDCouplingUMesh *>& a) +{ + if(a.empty()) + throw INTERP_KERNEL::Exception("MEDCouplingUMesh::MergeUMeshes : input array must be NON EMPTY !"); + std::vector<const MEDCouplingUMesh *>::const_iterator it=a.begin(); + int meshDim=(*it)->getMeshDimension(); + int nbOfCells=(*it)->getNumberOfCells(); + int meshLgth=(*it++)->getMeshLength(); + for(;it!=a.end();it++) + { + if(meshDim!=(*it)->getMeshDimension()) + throw INTERP_KERNEL::Exception("Mesh dimensions mismatches, MergeUMeshes impossible !"); + nbOfCells+=(*it)->getNumberOfCells(); + meshLgth+=(*it)->getMeshLength(); + } + std::vector<const MEDCouplingPointSet *> aps(a.size()); + std::copy(a.begin(),a.end(),aps.begin()); + MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> pts=MergeNodesArray(aps); + MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> ret=MEDCouplingUMesh::New("merge",meshDim); + ret->setCoords(pts); + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> c=DataArrayInt::New(); + c->alloc(meshLgth,1); + int *cPtr=c->getPointer(); + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> cI=DataArrayInt::New(); + cI->alloc(nbOfCells+1,1); + int *cIPtr=cI->getPointer(); + *cIPtr++=0; + int offset=0; + int offset2=0; + for(it=a.begin();it!=a.end();it++) + { + int curNbOfCell=(*it)->getNumberOfCells(); + const int *curCI=(*it)->_nodal_connec_index->getConstPointer(); + const int *curC=(*it)->_nodal_connec->getConstPointer(); + cIPtr=std::transform(curCI+1,curCI+curNbOfCell+1,cIPtr,std::bind2nd(std::plus<int>(),offset)); + for(int j=0;j<curNbOfCell;j++) + { + const int *src=curC+curCI[j]; + *cPtr++=*src++; + for(;src!=curC+curCI[j+1];src++,cPtr++) + { + if(*src!=-1) + *cPtr=*src+offset2; + else + *cPtr=-1; + } + } + offset+=curCI[curNbOfCell]; + offset2+=(*it)->getNumberOfNodes(); + } + // + ret->setConnectivity(c,cI,true); + return ret.retn(); +} + +/// @endcond + +/*! + * Creates a new MEDCouplingUMesh by concatenating cells of two given meshes of same + * dimension and sharing the node coordinates array. + * All cells of the first mesh precede all cells of the second mesh + * within the result mesh. + * \param [in] mesh1 - the first mesh. + * \param [in] mesh2 - the second mesh. + * \return MEDCouplingUMesh * - 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 mesh1 == NULL or \a mesh2 == NULL. + * \throw If the meshes do not share the node coordinates array. + * \throw If \a mesh1->getMeshDimension() < 0 or \a mesh2->getMeshDimension() < 0. + * \throw If \a mesh1->getMeshDimension() != \a mesh2->getMeshDimension(). + */ +MEDCouplingUMesh *MEDCouplingUMesh::MergeUMeshesOnSameCoords(const MEDCouplingUMesh *mesh1, const MEDCouplingUMesh *mesh2) +{ + std::vector<const MEDCouplingUMesh *> tmp(2); + tmp[0]=mesh1; tmp[1]=mesh2; + return MergeUMeshesOnSameCoords(tmp); +} + +/*! + * Creates a new MEDCouplingUMesh by concatenating cells of all given meshes of same + * dimension and sharing the node coordinates array. + * All cells of the *i*-th mesh precede all cells of the + * (*i*+1)-th mesh within the result mesh. + * \param [in] meshes - a vector of meshes (MEDCouplingUMesh) to concatenate. + * \return MEDCouplingUMesh * - 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 a.size() == 0. + * \throw If \a a[ *i* ] == NULL. + * \throw If the meshes do not share the node coordinates array. + * \throw If \a a[ *i* ]->getMeshDimension() < 0. + * \throw If the meshes in \a a are of different dimension (getMeshDimension()). + */ +MEDCouplingUMesh *MEDCouplingUMesh::MergeUMeshesOnSameCoords(const std::vector<const MEDCouplingUMesh *>& meshes) +{ + if(meshes.empty()) + throw INTERP_KERNEL::Exception("meshes input parameter is expected to be non empty."); + for(std::size_t ii=0;ii<meshes.size();ii++) + if(!meshes[ii]) + { + std::ostringstream oss; oss << "MEDCouplingUMesh::MergeUMeshesOnSameCoords : item #" << ii << " in input array of size "<< meshes.size() << " is empty !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + const DataArrayDouble *coords=meshes.front()->getCoords(); + int meshDim=meshes.front()->getMeshDimension(); + std::vector<const MEDCouplingUMesh *>::const_iterator iter=meshes.begin(); + int meshLgth=0; + int meshIndexLgth=0; + for(;iter!=meshes.end();iter++) + { + if(coords!=(*iter)->getCoords()) + throw INTERP_KERNEL::Exception("meshes does not share the same coords ! Try using tryToShareSameCoords method !"); + if(meshDim!=(*iter)->getMeshDimension()) + throw INTERP_KERNEL::Exception("Mesh dimensions mismatches, FuseUMeshesOnSameCoords impossible !"); + meshLgth+=(*iter)->getMeshLength(); + meshIndexLgth+=(*iter)->getNumberOfCells(); + } + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> nodal=DataArrayInt::New(); + nodal->alloc(meshLgth,1); + int *nodalPtr=nodal->getPointer(); + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> nodalIndex=DataArrayInt::New(); + nodalIndex->alloc(meshIndexLgth+1,1); + int *nodalIndexPtr=nodalIndex->getPointer(); + int offset=0; + for(iter=meshes.begin();iter!=meshes.end();iter++) + { + const int *nod=(*iter)->getNodalConnectivity()->getConstPointer(); + const int *index=(*iter)->getNodalConnectivityIndex()->getConstPointer(); + int nbOfCells=(*iter)->getNumberOfCells(); + int meshLgth2=(*iter)->getMeshLength(); + nodalPtr=std::copy(nod,nod+meshLgth2,nodalPtr); + if(iter!=meshes.begin()) + nodalIndexPtr=std::transform(index+1,index+nbOfCells+1,nodalIndexPtr,std::bind2nd(std::plus<int>(),offset)); + else + nodalIndexPtr=std::copy(index,index+nbOfCells+1,nodalIndexPtr); + offset+=meshLgth2; + } + MEDCouplingUMesh *ret=MEDCouplingUMesh::New(); + ret->setName("merge"); + ret->setMeshDimension(meshDim); + ret->setConnectivity(nodal,nodalIndex,true); + ret->setCoords(coords); + return ret; +} + +/*! + * Creates a new MEDCouplingUMesh by concatenating cells of all given meshes of same + * dimension and sharing the node coordinates array. Cells of the *i*-th mesh precede + * cells of the (*i*+1)-th mesh within the result mesh. Duplicates of cells are + * removed from \a this mesh and arrays mapping between new and old cell ids in "Old to + * New" mode are returned for each input mesh. + * \param [in] meshes - a vector of meshes (MEDCouplingUMesh) to concatenate. + * \param [in] compType - specifies a cell comparison technique. For meaning of its + * valid values [0,1,2], see zipConnectivityTraducer(). + * \param [in,out] corr - an array of DataArrayInt, of the same size as \a + * meshes. The *i*-th array describes cell ids mapping for \a meshes[ *i* ] + * mesh. The caller is to delete each of the arrays using decrRef() as it is + * no more needed. + * \return MEDCouplingUMesh * - 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 meshes[ *i* ] == NULL. + * \throw If the meshes do not share the node coordinates array. + * \throw If \a meshes[ *i* ]->getMeshDimension() < 0. + * \throw If the \a meshes are of different dimension (getMeshDimension()). + * \throw If the nodal connectivity of cells of any of \a meshes is not defined. + * \throw If the nodal connectivity any of \a meshes includes an invalid id. + */ +MEDCouplingUMesh *MEDCouplingUMesh::FuseUMeshesOnSameCoords(const std::vector<const MEDCouplingUMesh *>& meshes, int compType, std::vector<DataArrayInt *>& corr) +{ + //All checks are delegated to MergeUMeshesOnSameCoords + MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> ret=MergeUMeshesOnSameCoords(meshes); + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> o2n=ret->zipConnectivityTraducer(compType); + corr.resize(meshes.size()); + std::size_t nbOfMeshes=meshes.size(); + int offset=0; + const int *o2nPtr=o2n->getConstPointer(); + for(std::size_t i=0;i<nbOfMeshes;i++) + { + DataArrayInt *tmp=DataArrayInt::New(); + int curNbOfCells=meshes[i]->getNumberOfCells(); + tmp->alloc(curNbOfCells,1); + std::copy(o2nPtr+offset,o2nPtr+offset+curNbOfCells,tmp->getPointer()); + offset+=curNbOfCells; + tmp->setName(meshes[i]->getName()); + corr[i]=tmp; + } + return ret.retn(); +} + +/*! + * Makes all given meshes share the nodal connectivity array. The common connectivity + * array is created by concatenating the connectivity arrays of all given meshes. All + * the given meshes must be of the same space dimension but dimension of cells **can + * differ**. This method is particulary useful in MEDLoader context to build a \ref + * ParaMEDMEM::MEDFileUMesh "MEDFileUMesh" instance that expects that underlying + * MEDCouplingUMesh'es of different dimension share the same nodal connectivity array. + * \param [in,out] meshes - a vector of meshes to update. + * \throw If any of \a meshes is NULL. + * \throw If the coordinates array is not set in any of \a meshes. + * \throw If the nodal connectivity of cells is not defined in any of \a meshes. + * \throw If \a meshes are of different space dimension. + */ +void MEDCouplingUMesh::PutUMeshesOnSameAggregatedCoords(const std::vector<MEDCouplingUMesh *>& meshes) +{ + std::size_t sz=meshes.size(); + if(sz==0 || sz==1) + return; + std::vector< const DataArrayDouble * > coords(meshes.size()); + std::vector< const DataArrayDouble * >::iterator it2=coords.begin(); + for(std::vector<MEDCouplingUMesh *>::const_iterator it=meshes.begin();it!=meshes.end();it++,it2++) + { + if((*it)) + { + (*it)->checkConnectivityFullyDefined(); + const DataArrayDouble *coo=(*it)->getCoords(); + if(coo) + *it2=coo; + else + { + std::ostringstream oss; oss << " MEDCouplingUMesh::PutUMeshesOnSameAggregatedCoords : Item #" << std::distance(meshes.begin(),it) << " inside the vector of length " << meshes.size(); + oss << " has no coordinate array defined !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + } + else + { + std::ostringstream oss; oss << " MEDCouplingUMesh::PutUMeshesOnSameAggregatedCoords : Item #" << std::distance(meshes.begin(),it) << " inside the vector of length " << meshes.size(); + oss << " is null !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + } + MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> res=DataArrayDouble::Aggregate(coords); + std::vector<MEDCouplingUMesh *>::const_iterator it=meshes.begin(); + int offset=(*it)->getNumberOfNodes(); + (*it++)->setCoords(res); + for(;it!=meshes.end();it++) + { + int oldNumberOfNodes=(*it)->getNumberOfNodes(); + (*it)->setCoords(res); + (*it)->shiftNodeNumbersInConn(offset); + offset+=oldNumberOfNodes; + } +} + +/*! + * Merges nodes coincident with a given precision within all given meshes that share + * the nodal connectivity array. The given meshes **can be of different** mesh + * dimension. This method is particulary useful in MEDLoader context to build a \ref + * ParaMEDMEM::MEDFileUMesh "MEDFileUMesh" instance that expects that underlying + * MEDCouplingUMesh'es of different dimension share the same nodal connectivity array. + * \param [in,out] meshes - a vector of meshes to update. + * \param [in] eps - the precision used to detect coincident nodes (infinite norm). + * \throw If any of \a meshes is NULL. + * \throw If the \a meshes do not share the same node coordinates array. + * \throw If the nodal connectivity of cells is not defined in any of \a meshes. + */ +void MEDCouplingUMesh::MergeNodesOnUMeshesSharingSameCoords(const std::vector<MEDCouplingUMesh *>& meshes, double eps) +{ + if(meshes.empty()) + return ; + std::set<const DataArrayDouble *> s; + for(std::vector<MEDCouplingUMesh *>::const_iterator it=meshes.begin();it!=meshes.end();it++) + { + if(*it) + s.insert((*it)->getCoords()); + else + { + std::ostringstream oss; oss << "MEDCouplingUMesh::MergeNodesOnUMeshesSharingSameCoords : In input vector of unstructured meshes of size " << meshes.size() << " the element #" << std::distance(meshes.begin(),it) << " is null !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + } + if(s.size()!=1) + { + std::ostringstream oss; oss << "MEDCouplingUMesh::MergeNodesOnUMeshesSharingSameCoords : In input vector of unstructured meshes of size " << meshes.size() << ", it appears that they do not share the same instance of DataArrayDouble for coordiantes ! tryToShareSameCoordsPermute method can help to reach that !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + const DataArrayDouble *coo=*(s.begin()); + if(!coo) + return; + // + DataArrayInt *comm,*commI; + coo->findCommonTuples(eps,-1,comm,commI); + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> tmp1(comm),tmp2(commI); + int oldNbOfNodes=coo->getNumberOfTuples(); + int newNbOfNodes; + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> o2n=DataArrayInt::BuildOld2NewArrayFromSurjectiveFormat2(oldNbOfNodes,comm->begin(),commI->begin(),commI->end(),newNbOfNodes); + if(oldNbOfNodes==newNbOfNodes) + return ; + MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> newCoords=coo->renumberAndReduce(o2n->getConstPointer(),newNbOfNodes); + for(std::vector<MEDCouplingUMesh *>::const_iterator it=meshes.begin();it!=meshes.end();it++) + { + (*it)->renumberNodesInConn(o2n->getConstPointer()); + (*it)->setCoords(newCoords); + } +} + +/*! + * This method takes in input a cell defined by its MEDcouplingUMesh connectivity [ \a connBg , \a connEnd ) and returns its extruded cell by inserting the result at the end of ret. + * \param nbOfNodesPerLev in parameter that specifies the number of nodes of one slice of global dataset + * \param isQuad specifies the policy of connectivity. + * @ret in/out parameter in which the result will be append + */ +void MEDCouplingUMesh::AppendExtrudedCell(const int *connBg, const int *connEnd, int nbOfNodesPerLev, bool isQuad, std::vector<int>& ret) +{ + INTERP_KERNEL::NormalizedCellType flatType=(INTERP_KERNEL::NormalizedCellType)connBg[0]; + const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(flatType); + ret.push_back(cm.getExtrudedType()); + int deltaz=isQuad?2*nbOfNodesPerLev:nbOfNodesPerLev; + switch(flatType) + { + case INTERP_KERNEL::NORM_POINT1: + { + ret.push_back(connBg[1]); + ret.push_back(connBg[1]+nbOfNodesPerLev); + break; + } + case INTERP_KERNEL::NORM_SEG2: + { + int conn[4]={connBg[1],connBg[2],connBg[2]+deltaz,connBg[1]+deltaz}; + ret.insert(ret.end(),conn,conn+4); + break; + } + case INTERP_KERNEL::NORM_SEG3: + { + int conn[8]={connBg[1],connBg[3],connBg[3]+deltaz,connBg[1]+deltaz,connBg[2],connBg[3]+nbOfNodesPerLev,connBg[2]+deltaz,connBg[1]+nbOfNodesPerLev}; + ret.insert(ret.end(),conn,conn+8); + break; + } + case INTERP_KERNEL::NORM_QUAD4: + { + int conn[8]={connBg[1],connBg[2],connBg[3],connBg[4],connBg[1]+deltaz,connBg[2]+deltaz,connBg[3]+deltaz,connBg[4]+deltaz}; + ret.insert(ret.end(),conn,conn+8); + break; + } + case INTERP_KERNEL::NORM_TRI3: + { + int conn[6]={connBg[1],connBg[2],connBg[3],connBg[1]+deltaz,connBg[2]+deltaz,connBg[3]+deltaz}; + ret.insert(ret.end(),conn,conn+6); + break; + } + case INTERP_KERNEL::NORM_TRI6: + { + int conn[15]={connBg[1],connBg[2],connBg[3],connBg[1]+deltaz,connBg[2]+deltaz,connBg[3]+deltaz,connBg[4],connBg[5],connBg[6],connBg[4]+deltaz,connBg[5]+deltaz,connBg[6]+deltaz, + connBg[1]+nbOfNodesPerLev,connBg[2]+nbOfNodesPerLev,connBg[3]+nbOfNodesPerLev}; + ret.insert(ret.end(),conn,conn+15); + break; + } + case INTERP_KERNEL::NORM_QUAD8: + { + int conn[20]={ + connBg[1],connBg[2],connBg[3],connBg[4],connBg[1]+deltaz,connBg[2]+deltaz,connBg[3]+deltaz,connBg[4]+deltaz, + connBg[5],connBg[6],connBg[7],connBg[8],connBg[5]+deltaz,connBg[6]+deltaz,connBg[7]+deltaz,connBg[8]+deltaz, + connBg[1]+nbOfNodesPerLev,connBg[2]+nbOfNodesPerLev,connBg[3]+nbOfNodesPerLev,connBg[4]+nbOfNodesPerLev + }; + ret.insert(ret.end(),conn,conn+20); + break; + } + case INTERP_KERNEL::NORM_POLYGON: + { + std::back_insert_iterator< std::vector<int> > ii(ret); + std::copy(connBg+1,connEnd,ii); + *ii++=-1; + std::reverse_iterator<const int *> rConnBg(connEnd); + std::reverse_iterator<const int *> rConnEnd(connBg+1); + std::transform(rConnBg,rConnEnd,ii,std::bind2nd(std::plus<int>(),deltaz)); + std::size_t nbOfRadFaces=std::distance(connBg+1,connEnd); + for(std::size_t i=0;i<nbOfRadFaces;i++) + { + *ii++=-1; + int conn[4]={connBg[(i+1)%nbOfRadFaces+1],connBg[i+1],connBg[i+1]+deltaz,connBg[(i+1)%nbOfRadFaces+1]+deltaz}; + std::copy(conn,conn+4,ii); + } + break; + } + default: + throw INTERP_KERNEL::Exception("A flat type has been detected that has not its extruded representation !"); + } +} + +/*! + * This static operates only for coords in 3D. The polygon is specfied by its connectivity nodes in [ \a begin , \a end ). + */ +bool MEDCouplingUMesh::IsPolygonWellOriented(bool isQuadratic, const double *vec, const int *begin, const int *end, const double *coords) +{ + std::size_t i, ip1; + double v[3]={0.,0.,0.}; + std::size_t sz=std::distance(begin,end); + if(isQuadratic) + sz/=2; + for(i=0;i<sz;i++) + { + v[0]+=coords[3*begin[i]+1]*coords[3*begin[(i+1)%sz]+2]-coords[3*begin[i]+2]*coords[3*begin[(i+1)%sz]+1]; + v[1]+=coords[3*begin[i]+2]*coords[3*begin[(i+1)%sz]]-coords[3*begin[i]]*coords[3*begin[(i+1)%sz]+2]; + v[2]+=coords[3*begin[i]]*coords[3*begin[(i+1)%sz]+1]-coords[3*begin[i]+1]*coords[3*begin[(i+1)%sz]]; + } + double ret = vec[0]*v[0]+vec[1]*v[1]+vec[2]*v[2]; + + // Try using quadratic points if standard points are degenerated (for example a QPOLYG with two + // SEG3 forming a circle): + if (fabs(ret) < INTERP_KERNEL::DEFAULT_ABS_TOL && isQuadratic) + { + v[0] = 0.0; v[1] = 0.0; v[2] = 0.0; + for(std::size_t j=0;j<sz;j++) + { + if (j%2) // current point i is quadratic, next point i+1 is standard + { + i = sz+j; + ip1 = (j+1)%sz; // ip1 = "i+1" + } + else // current point i is standard, next point i+1 is quadratic + { + i = j; + ip1 = j+sz; + } + v[0]+=coords[3*begin[i]+1]*coords[3*begin[ip1]+2]-coords[3*begin[i]+2]*coords[3*begin[ip1]+1]; + v[1]+=coords[3*begin[i]+2]*coords[3*begin[ip1]]-coords[3*begin[i]]*coords[3*begin[ip1]+2]; + v[2]+=coords[3*begin[i]]*coords[3*begin[ip1]+1]-coords[3*begin[i]+1]*coords[3*begin[ip1]]; + } + ret = vec[0]*v[0]+vec[1]*v[1]+vec[2]*v[2]; + } + return (ret>0.); +} + +/*! + * The polyhedron is specfied by its connectivity nodes in [ \a begin , \a end ). + */ +bool MEDCouplingUMesh::IsPolyhedronWellOriented(const int *begin, const int *end, const double *coords) +{ + std::vector<std::pair<int,int> > edges; + std::size_t nbOfFaces=std::count(begin,end,-1)+1; + const int *bgFace=begin; + for(std::size_t i=0;i<nbOfFaces;i++) + { + const int *endFace=std::find(bgFace+1,end,-1); + std::size_t nbOfEdgesInFace=std::distance(bgFace,endFace); + for(std::size_t j=0;j<nbOfEdgesInFace;j++) + { + std::pair<int,int> p1(bgFace[j],bgFace[(j+1)%nbOfEdgesInFace]); + if(std::find(edges.begin(),edges.end(),p1)!=edges.end()) + return false; + edges.push_back(p1); + } + bgFace=endFace+1; + } + return INTERP_KERNEL::calculateVolumeForPolyh2<int,INTERP_KERNEL::ALL_C_MODE>(begin,(int)std::distance(begin,end),coords)>-EPS_FOR_POLYH_ORIENTATION; +} + +/*! + * The 3D extruded static cell (PENTA6,HEXA8,HEXAGP12...) its connectivity nodes in [ \a begin , \a end ). + */ +bool MEDCouplingUMesh::Is3DExtrudedStaticCellWellOriented(const int *begin, const int *end, const double *coords) +{ + double vec0[3],vec1[3]; + std::size_t sz=std::distance(begin,end); + if(sz%2!=0) + throw INTERP_KERNEL::Exception("MEDCouplingUMesh::Is3DExtrudedStaticCellWellOriented : the length of nodal connectivity of extruded cell is not even !"); + int nbOfNodes=(int)sz/2; + INTERP_KERNEL::areaVectorOfPolygon<int,INTERP_KERNEL::ALL_C_MODE>(begin,nbOfNodes,coords,vec0); + const double *pt0=coords+3*begin[0]; + const double *pt1=coords+3*begin[nbOfNodes]; + vec1[0]=pt1[0]-pt0[0]; vec1[1]=pt1[1]-pt0[1]; vec1[2]=pt1[2]-pt0[2]; + return (vec0[0]*vec1[0]+vec0[1]*vec1[1]+vec0[2]*vec1[2])<0.; +} + +void MEDCouplingUMesh::CorrectExtrudedStaticCell(int *begin, int *end) +{ + std::size_t sz=std::distance(begin,end); + INTERP_KERNEL::AutoPtr<int> tmp=new int[sz]; + std::size_t nbOfNodes(sz/2); + std::copy(begin,end,(int *)tmp); + for(std::size_t j=1;j<nbOfNodes;j++) + { + begin[j]=tmp[nbOfNodes-j]; + begin[j+nbOfNodes]=tmp[nbOfNodes+nbOfNodes-j]; + } +} + +bool MEDCouplingUMesh::IsTetra4WellOriented(const int *begin, const int *end, const double *coords) +{ + std::size_t sz=std::distance(begin,end); + if(sz!=4) + throw INTERP_KERNEL::Exception("MEDCouplingUMesh::IsTetra4WellOriented : Tetra4 cell with not 4 nodes ! Call checkCoherency2 !"); + double vec0[3],vec1[3]; + const double *pt0=coords+3*begin[0],*pt1=coords+3*begin[1],*pt2=coords+3*begin[2],*pt3=coords+3*begin[3]; + vec0[0]=pt1[0]-pt0[0]; vec0[1]=pt1[1]-pt0[1]; vec0[2]=pt1[2]-pt0[2]; vec1[0]=pt2[0]-pt0[0]; vec1[1]=pt2[1]-pt0[1]; vec1[2]=pt2[2]-pt0[2]; + return ((vec0[1]*vec1[2]-vec0[2]*vec1[1])*(pt3[0]-pt0[0])+(vec0[2]*vec1[0]-vec0[0]*vec1[2])*(pt3[1]-pt0[1])+(vec0[0]*vec1[1]-vec0[1]*vec1[0])*(pt3[2]-pt0[2]))<0; +} + +bool MEDCouplingUMesh::IsPyra5WellOriented(const int *begin, const int *end, const double *coords) +{ + std::size_t sz=std::distance(begin,end); + if(sz!=5) + throw INTERP_KERNEL::Exception("MEDCouplingUMesh::IsPyra5WellOriented : Pyra5 cell with not 5 nodes ! Call checkCoherency2 !"); + double vec0[3]; + INTERP_KERNEL::areaVectorOfPolygon<int,INTERP_KERNEL::ALL_C_MODE>(begin,4,coords,vec0); + const double *pt0=coords+3*begin[0],*pt1=coords+3*begin[4]; + return (vec0[0]*(pt1[0]-pt0[0])+vec0[1]*(pt1[1]-pt0[1])+vec0[2]*(pt1[2]-pt0[2]))<0.; +} + +/*! + * This method performs a simplyfication of a single polyedron cell. To do that each face of cell whose connectivity is defined by [ \b begin , \b end ) + * is compared with the others in order to find faces in the same plane (with approx of eps). If any, the cells are grouped together and projected to + * a 2D space. + * + * \param [in] eps is a relative precision that allows to establish if some 3D plane are coplanar or not. + * \param [in] coords the coordinates with nb of components exactly equal to 3 + * \param [in] begin begin of the nodal connectivity (geometric type included) of a single polyhedron cell + * \param [in] end end of nodal connectivity of a single polyhedron cell (excluded) + * \param [out] res the result is put at the end of the vector without any alteration of the data. + */ +void MEDCouplingUMesh::SimplifyPolyhedronCell(double eps, const DataArrayDouble *coords, const int *begin, const int *end, DataArrayInt *res) +{ + int nbFaces=std::count(begin+1,end,-1)+1; + MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> v=DataArrayDouble::New(); v->alloc(nbFaces,3); + double *vPtr=v->getPointer(); + MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> p=DataArrayDouble::New(); p->alloc(nbFaces,1); + double *pPtr=p->getPointer(); + const int *stFaceConn=begin+1; + for(int i=0;i<nbFaces;i++,vPtr+=3,pPtr++) + { + const int *endFaceConn=std::find(stFaceConn,end,-1); + ComputeVecAndPtOfFace(eps,coords->getConstPointer(),stFaceConn,endFaceConn,vPtr,pPtr); + stFaceConn=endFaceConn+1; + } + pPtr=p->getPointer(); vPtr=v->getPointer(); + DataArrayInt *comm1=0,*commI1=0; + v->findCommonTuples(eps,-1,comm1,commI1); + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> comm1Auto(comm1),commI1Auto(commI1); + const int *comm1Ptr=comm1->getConstPointer(); + const int *commI1Ptr=commI1->getConstPointer(); + int nbOfGrps1=commI1Auto->getNumberOfTuples()-1; + res->pushBackSilent((int)INTERP_KERNEL::NORM_POLYHED); + // + MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> mm=MEDCouplingUMesh::New("",3); + mm->setCoords(const_cast<DataArrayDouble *>(coords)); mm->allocateCells(1); mm->insertNextCell(INTERP_KERNEL::NORM_POLYHED,(int)std::distance(begin+1,end),begin+1); + mm->finishInsertingCells(); + // + for(int i=0;i<nbOfGrps1;i++) + { + int vecId=comm1Ptr[commI1Ptr[i]]; + MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> tmpgrp2=p->selectByTupleId(comm1Ptr+commI1Ptr[i],comm1Ptr+commI1Ptr[i+1]); + DataArrayInt *comm2=0,*commI2=0; + tmpgrp2->findCommonTuples(eps,-1,comm2,commI2); + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> comm2Auto(comm2),commI2Auto(commI2); + const int *comm2Ptr=comm2->getConstPointer(); + const int *commI2Ptr=commI2->getConstPointer(); + int nbOfGrps2=commI2Auto->getNumberOfTuples()-1; + for(int j=0;j<nbOfGrps2;j++) + { + if(commI2Ptr[j+1]-commI2Ptr[j]<=1) + { + res->insertAtTheEnd(begin,end); + res->pushBackSilent(-1); + } + else + { + int pointId=comm1Ptr[commI1Ptr[i]+comm2Ptr[commI2Ptr[j]]]; + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ids2=comm2->selectByTupleId2(commI2Ptr[j],commI2Ptr[j+1],1); + ids2->transformWithIndArr(comm1Ptr+commI1Ptr[i],comm1Ptr+commI1Ptr[i+1]); + DataArrayInt *tmp0=DataArrayInt::New(),*tmp1=DataArrayInt::New(),*tmp2=DataArrayInt::New(),*tmp3=DataArrayInt::New(); + MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> mm2=mm->buildDescendingConnectivity(tmp0,tmp1,tmp2,tmp3); tmp0->decrRef(); tmp1->decrRef(); tmp2->decrRef(); tmp3->decrRef(); + MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> mm3=static_cast<MEDCouplingUMesh *>(mm2->buildPartOfMySelf(ids2->begin(),ids2->end(),true)); + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> idsNodeTmp=mm3->zipCoordsTraducer(); + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> idsNode=idsNodeTmp->invertArrayO2N2N2O(mm3->getNumberOfNodes()); + const int *idsNodePtr=idsNode->getConstPointer(); + double center[3]; center[0]=pPtr[pointId]*vPtr[3*vecId]; center[1]=pPtr[pointId]*vPtr[3*vecId+1]; center[2]=pPtr[pointId]*vPtr[3*vecId+2]; + double vec[3]; vec[0]=vPtr[3*vecId+1]; vec[1]=-vPtr[3*vecId]; vec[2]=0.; + double norm=vec[0]*vec[0]+vec[1]*vec[1]+vec[2]*vec[2]; + if(std::abs(norm)>eps) + { + double angle=INTERP_KERNEL::EdgeArcCircle::SafeAsin(norm); + mm3->rotate(center,vec,angle); + } + mm3->changeSpaceDimension(2); + MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> mm4=mm3->buildSpreadZonesWithPoly(); + const int *conn4=mm4->getNodalConnectivity()->getConstPointer(); + const int *connI4=mm4->getNodalConnectivityIndex()->getConstPointer(); + int nbOfCells=mm4->getNumberOfCells(); + for(int k=0;k<nbOfCells;k++) + { + int l=0; + for(const int *work=conn4+connI4[k]+1;work!=conn4+connI4[k+1];work++,l++) + res->pushBackSilent(idsNodePtr[*work]); + res->pushBackSilent(-1); + } + } + } + } + res->popBackSilent(); +} + +/*! + * This method computes the normalized vector of the plane and the pos of the point belonging to the plane and the line defined by the vector going + * through origin. The plane is defined by its nodal connectivity [ \b begin, \b end ). + * + * \param [in] eps below that value the dot product of 2 vectors is considered as colinears + * \param [in] coords coordinates expected to have 3 components. + * \param [in] begin start of the nodal connectivity of the face. + * \param [in] end end of the nodal connectivity (excluded) of the face. + * \param [out] v the normalized vector of size 3 + * \param [out] p the pos of plane + */ +void MEDCouplingUMesh::ComputeVecAndPtOfFace(double eps, const double *coords, const int *begin, const int *end, double *v, double *p) +{ + std::size_t nbPoints=std::distance(begin,end); + if(nbPoints<3) + throw INTERP_KERNEL::Exception("MEDCouplingUMesh::ComputeVecAndPtOfFace : < of 3 points in face ! not able to find a plane on that face !"); + double vec[3]={0.,0.,0.}; + std::size_t j=0; + bool refFound=false; + for(;j<nbPoints-1 && !refFound;j++) + { + vec[0]=coords[3*begin[j+1]]-coords[3*begin[j]]; + vec[1]=coords[3*begin[j+1]+1]-coords[3*begin[j]+1]; + vec[2]=coords[3*begin[j+1]+2]-coords[3*begin[j]+2]; + double norm=sqrt(vec[0]*vec[0]+vec[1]*vec[1]+vec[2]*vec[2]); + if(norm>eps) + { + refFound=true; + vec[0]/=norm; vec[1]/=norm; vec[2]/=norm; + } + } + for(std::size_t i=j;i<nbPoints-1;i++) + { + double curVec[3]; + curVec[0]=coords[3*begin[i+1]]-coords[3*begin[i]]; + curVec[1]=coords[3*begin[i+1]+1]-coords[3*begin[i]+1]; + curVec[2]=coords[3*begin[i+1]+2]-coords[3*begin[i]+2]; + double norm=sqrt(curVec[0]*curVec[0]+curVec[1]*curVec[1]+curVec[2]*curVec[2]); + if(norm<eps) + continue; + curVec[0]/=norm; curVec[1]/=norm; curVec[2]/=norm; + v[0]=vec[1]*curVec[2]-vec[2]*curVec[1]; v[1]=vec[2]*curVec[0]-vec[0]*curVec[2]; v[2]=vec[0]*curVec[1]-vec[1]*curVec[0]; + norm=sqrt(v[0]*v[0]+v[1]*v[1]+v[2]*v[2]); + if(norm>eps) + { + v[0]/=norm; v[1]/=norm; v[2]/=norm; + *p=v[0]*coords[3*begin[i]]+v[1]*coords[3*begin[i]+1]+v[2]*coords[3*begin[i]+2]; + return ; + } + } + throw INTERP_KERNEL::Exception("Not able to find a normal vector of that 3D face !"); +} + +/*! + * This method tries to obtain a well oriented polyhedron. + * If the algorithm fails, an exception will be thrown. + */ +void MEDCouplingUMesh::TryToCorrectPolyhedronOrientation(int *begin, int *end, const double *coords) +{ + std::list< std::pair<int,int> > edgesOK,edgesFinished; + std::size_t nbOfFaces=std::count(begin,end,-1)+1; + std::vector<bool> isPerm(nbOfFaces,false);//field on faces False: I don't know, True : oriented + isPerm[0]=true; + int *bgFace=begin,*endFace=std::find(begin+1,end,-1); + std::size_t nbOfEdgesInFace=std::distance(bgFace,endFace); + for(std::size_t l=0;l<nbOfEdgesInFace;l++) { std::pair<int,int> p1(bgFace[l],bgFace[(l+1)%nbOfEdgesInFace]); edgesOK.push_back(p1); } + // + while(std::find(isPerm.begin(),isPerm.end(),false)!=isPerm.end()) + { + bgFace=begin; + std::size_t smthChanged=0; + for(std::size_t i=0;i<nbOfFaces;i++) + { + endFace=std::find(bgFace+1,end,-1); + nbOfEdgesInFace=std::distance(bgFace,endFace); + if(!isPerm[i]) + { + bool b; + for(std::size_t j=0;j<nbOfEdgesInFace;j++) + { + std::pair<int,int> p1(bgFace[j],bgFace[(j+1)%nbOfEdgesInFace]); + std::pair<int,int> p2(p1.second,p1.first); + bool b1=std::find(edgesOK.begin(),edgesOK.end(),p1)!=edgesOK.end(); + bool b2=std::find(edgesOK.begin(),edgesOK.end(),p2)!=edgesOK.end(); + if(b1 || b2) { b=b2; isPerm[i]=true; smthChanged++; break; } + } + if(isPerm[i]) + { + if(!b) + std::reverse(bgFace+1,endFace); + for(std::size_t j=0;j<nbOfEdgesInFace;j++) + { + std::pair<int,int> p1(bgFace[j],bgFace[(j+1)%nbOfEdgesInFace]); + std::pair<int,int> p2(p1.second,p1.first); + if(std::find(edgesOK.begin(),edgesOK.end(),p1)!=edgesOK.end()) + { std::ostringstream oss; oss << "Face #" << j << " of polyhedron looks bad !"; throw INTERP_KERNEL::Exception(oss.str().c_str()); } + if(std::find(edgesFinished.begin(),edgesFinished.end(),p1)!=edgesFinished.end() || std::find(edgesFinished.begin(),edgesFinished.end(),p2)!=edgesFinished.end()) + { std::ostringstream oss; oss << "Face #" << j << " of polyhedron looks bad !"; throw INTERP_KERNEL::Exception(oss.str().c_str()); } + std::list< std::pair<int,int> >::iterator it=std::find(edgesOK.begin(),edgesOK.end(),p2); + if(it!=edgesOK.end()) + { + edgesOK.erase(it); + edgesFinished.push_back(p1); + } + else + edgesOK.push_back(p1); + } + } + } + bgFace=endFace+1; + } + if(smthChanged==0) + { throw INTERP_KERNEL::Exception("The polyhedron looks too bad to be repaired !"); } + } + if(!edgesOK.empty()) + { throw INTERP_KERNEL::Exception("The polyhedron looks too bad to be repaired : Some edges are shared only once !"); } + if(INTERP_KERNEL::calculateVolumeForPolyh2<int,INTERP_KERNEL::ALL_C_MODE>(begin,(int)std::distance(begin,end),coords)<-EPS_FOR_POLYH_ORIENTATION) + {//not lucky ! The first face was not correctly oriented : reorient all faces... + bgFace=begin; + for(std::size_t i=0;i<nbOfFaces;i++) + { + endFace=std::find(bgFace+1,end,-1); + std::reverse(bgFace+1,endFace); + bgFace=endFace+1; + } + } +} + +DataArrayInt *MEDCouplingUMesh::buildUnionOf2DMeshLinear(const MEDCouplingUMesh *skin, const DataArrayInt *n2o) const +{ + int nbOfNodesExpected(skin->getNumberOfNodes()); + const int *n2oPtr(n2o->getConstPointer()); + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> revNodal(DataArrayInt::New()),revNodalI(DataArrayInt::New()); + skin->getReverseNodalConnectivity(revNodal,revNodalI); + const int *revNodalPtr(revNodal->getConstPointer()),*revNodalIPtr(revNodalI->getConstPointer()); + const int *nodalPtr(skin->getNodalConnectivity()->getConstPointer()); + const int *nodalIPtr(skin->getNodalConnectivityIndex()->getConstPointer()); + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(nbOfNodesExpected+1,1); + int *work(ret->getPointer()); *work++=INTERP_KERNEL::NORM_POLYGON; + if(nbOfNodesExpected<1) + return ret.retn(); + int prevCell(0),prevNode(nodalPtr[nodalIPtr[0]+1]); + *work++=n2oPtr[prevNode]; + for(int i=1;i<nbOfNodesExpected;i++) + { + if(nodalIPtr[prevCell+1]-nodalIPtr[prevCell]==3) + { + std::set<int> conn(nodalPtr+nodalIPtr[prevCell]+1,nodalPtr+nodalIPtr[prevCell]+3); + conn.erase(prevNode); + if(conn.size()==1) + { + int curNode(*(conn.begin())); + *work++=n2oPtr[curNode]; + std::set<int> shar(revNodalPtr+revNodalIPtr[curNode],revNodalPtr+revNodalIPtr[curNode+1]); + shar.erase(prevCell); + if(shar.size()==1) + { + prevCell=*(shar.begin()); + prevNode=curNode; + } + else + throw INTERP_KERNEL::Exception("MEDCouplingUMesh::buildUnionOf2DMeshLinear : presence of unexpected 2 !"); + } + else + throw INTERP_KERNEL::Exception("MEDCouplingUMesh::buildUnionOf2DMeshLinear : presence of unexpected 1 !"); + } + else + throw INTERP_KERNEL::Exception("MEDCouplingUMesh::buildUnionOf2DMeshLinear : presence of unexpected cell !"); + } + return ret.retn(); +} + +DataArrayInt *MEDCouplingUMesh::buildUnionOf2DMeshQuadratic(const MEDCouplingUMesh *skin, const DataArrayInt *n2o) const +{ + int nbOfNodesExpected(skin->getNumberOfNodes()); + int nbOfTurn(nbOfNodesExpected/2); + const int *n2oPtr(n2o->getConstPointer()); + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> revNodal(DataArrayInt::New()),revNodalI(DataArrayInt::New()); + skin->getReverseNodalConnectivity(revNodal,revNodalI); + const int *revNodalPtr(revNodal->getConstPointer()),*revNodalIPtr(revNodalI->getConstPointer()); + const int *nodalPtr(skin->getNodalConnectivity()->getConstPointer()); + const int *nodalIPtr(skin->getNodalConnectivityIndex()->getConstPointer()); + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(nbOfNodesExpected+1,1); + int *work(ret->getPointer()); *work++=INTERP_KERNEL::NORM_QPOLYG; + if(nbOfNodesExpected<1) + return ret.retn(); + int prevCell(0),prevNode(nodalPtr[nodalIPtr[0]+1]); + *work=n2oPtr[prevNode]; work[nbOfTurn]=n2oPtr[nodalPtr[nodalIPtr[0]+3]]; work++; + for(int i=1;i<nbOfTurn;i++) + { + if(nodalIPtr[prevCell+1]-nodalIPtr[prevCell]==4) + { + std::set<int> conn(nodalPtr+nodalIPtr[prevCell]+1,nodalPtr+nodalIPtr[prevCell]+3); + conn.erase(prevNode); + if(conn.size()==1) + { + int curNode(*(conn.begin())); + *work=n2oPtr[curNode]; + std::set<int> shar(revNodalPtr+revNodalIPtr[curNode],revNodalPtr+revNodalIPtr[curNode+1]); + shar.erase(prevCell); + if(shar.size()==1) + { + int curCell(*(shar.begin())); + work[nbOfTurn]=n2oPtr[nodalPtr[nodalIPtr[curCell]+3]]; + prevCell=curCell; + prevNode=curNode; + work++; + } + else + throw INTERP_KERNEL::Exception("MEDCouplingUMesh::buildUnionOf2DMeshQuadratic : presence of unexpected 2 !"); + } + else + throw INTERP_KERNEL::Exception("MEDCouplingUMesh::buildUnionOf2DMeshQuadratic : presence of unexpected 1 !"); + } + else + throw INTERP_KERNEL::Exception("MEDCouplingUMesh::buildUnionOf2DMeshQuadratic : presence of unexpected cell !"); + } + return ret.retn(); +} + +/*! + * This method makes the assumption spacedimension == meshdimension == 2. + * This method works only for linear cells. + * + * \return a newly allocated array containing the connectivity of a polygon type enum included (NORM_POLYGON in pos#0) + */ +DataArrayInt *MEDCouplingUMesh::buildUnionOf2DMesh() const +{ + if(getMeshDimension()!=2 || getSpaceDimension()!=2) + throw INTERP_KERNEL::Exception("MEDCouplingUMesh::buildUnionOf2DMesh : meshdimension, spacedimension must be equal to 2 !"); + MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> skin(computeSkin()); + int oldNbOfNodes(skin->getNumberOfNodes()); + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> o2n(skin->zipCoordsTraducer()); + int nbOfNodesExpected(skin->getNumberOfNodes()); + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> n2o(o2n->invertArrayO2N2N2O(oldNbOfNodes)); + int nbCells(skin->getNumberOfCells()); + if(nbCells==nbOfNodesExpected) + return buildUnionOf2DMeshLinear(skin,n2o); + else if(2*nbCells==nbOfNodesExpected) + return buildUnionOf2DMeshQuadratic(skin,n2o); + else + throw INTERP_KERNEL::Exception("MEDCouplingUMesh::buildUnionOf2DMesh : the mesh 2D in input appears to be not in a single part of a 2D mesh !"); +} + +/*! + * This method makes the assumption spacedimension == meshdimension == 3. + * This method works only for linear cells. + * + * \return a newly allocated array containing the connectivity of a polygon type enum included (NORM_POLYHED in pos#0) + */ +DataArrayInt *MEDCouplingUMesh::buildUnionOf3DMesh() const +{ + if(getMeshDimension()!=3 || getSpaceDimension()!=3) + throw INTERP_KERNEL::Exception("MEDCouplingUMesh::buildUnionOf3DMesh : meshdimension, spacedimension must be equal to 2 !"); + MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m=computeSkin(); + const int *conn=m->getNodalConnectivity()->getConstPointer(); + const int *connI=m->getNodalConnectivityIndex()->getConstPointer(); + int nbOfCells=m->getNumberOfCells(); + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(m->getNodalConnectivity()->getNumberOfTuples(),1); + int *work=ret->getPointer(); *work++=INTERP_KERNEL::NORM_POLYHED; + if(nbOfCells<1) + return ret.retn(); + work=std::copy(conn+connI[0]+1,conn+connI[1],work); + for(int i=1;i<nbOfCells;i++) + { + *work++=-1; + work=std::copy(conn+connI[i]+1,conn+connI[i+1],work); + } + return ret.retn(); +} + +/*! + * \brief Creates a graph of cell neighbors + * \return MEDCouplingSkyLineArray * - an sky line array the user should delete. + * In the sky line array, graph arcs are stored in terms of (index,value) notation. + * For example + * - index: 0 3 5 6 6 + * - value: 1 2 3 2 3 3 + * means 6 arcs (0,1), (0,2), (0,3), (1,2), (1,3), (2,3) + * Arcs are not doubled but reflexive (1,1) arcs are present for each cell + */ +MEDCouplingSkyLineArray *MEDCouplingUMesh::generateGraph() const +{ + checkConnectivityFullyDefined(); + + int meshDim = this->getMeshDimension(); + ParaMEDMEM::DataArrayInt* indexr=ParaMEDMEM::DataArrayInt::New(); + ParaMEDMEM::DataArrayInt* revConn=ParaMEDMEM::DataArrayInt::New(); + this->getReverseNodalConnectivity(revConn,indexr); + const int* indexr_ptr=indexr->getConstPointer(); + const int* revConn_ptr=revConn->getConstPointer(); + + const ParaMEDMEM::DataArrayInt* index; + const ParaMEDMEM::DataArrayInt* conn; + conn=this->getNodalConnectivity(); // it includes a type as the 1st element!!! + index=this->getNodalConnectivityIndex(); + int nbCells=this->getNumberOfCells(); + const int* index_ptr=index->getConstPointer(); + const int* conn_ptr=conn->getConstPointer(); + + //creating graph arcs (cell to cell relations) + //arcs are stored in terms of (index,value) notation + // 0 3 5 6 6 + // 1 2 3 2 3 3 + // means 6 arcs (0,1), (0,2), (0,3), (1,2), (1,3), (2,3) + // in present version arcs are not doubled but reflexive (1,1) arcs are present for each cell + + //warning here one node have less than or equal effective number of cell with it + //but cell could have more than effective nodes + //because other equals nodes in other domain (with other global inode) + std::vector <int> cell2cell_index(nbCells+1,0); + std::vector <int> cell2cell; + cell2cell.reserve(3*nbCells); + + for (int icell=0; icell<nbCells;icell++) + { + std::map<int,int > counter; + for (int iconn=index_ptr[icell]+1; iconn<index_ptr[icell+1];iconn++) + { + int inode=conn_ptr[iconn]; + for (int iconnr=indexr_ptr[inode]; iconnr<indexr_ptr[inode+1];iconnr++) + { + int icell2=revConn_ptr[iconnr]; + std::map<int,int>::iterator iter=counter.find(icell2); + if (iter!=counter.end()) (iter->second)++; + else counter.insert(std::make_pair(icell2,1)); + } + } + for (std::map<int,int>::const_iterator iter=counter.begin(); + iter!=counter.end(); iter++) + if (iter->second >= meshDim) + { + cell2cell_index[icell+1]++; + cell2cell.push_back(iter->first); + } + } + indexr->decrRef(); + revConn->decrRef(); + cell2cell_index[0]=0; + for (int icell=0; icell<nbCells;icell++) + cell2cell_index[icell+1]=cell2cell_index[icell]+cell2cell_index[icell+1]; + + //filling up index and value to create skylinearray structure + MEDCouplingSkyLineArray* array=new MEDCouplingSkyLineArray(cell2cell_index,cell2cell); + return array; +} + +/*! + * This method put in zip format into parameter 'zipFrmt' in full interlace mode. + * This format is often asked by INTERP_KERNEL algorithms to avoid many indirections into coordinates array. + */ +void MEDCouplingUMesh::FillInCompact3DMode(int spaceDim, int nbOfNodesInCell, const int *conn, const double *coo, double *zipFrmt) +{ + double *w=zipFrmt; + if(spaceDim==3) + for(int i=0;i<nbOfNodesInCell;i++) + w=std::copy(coo+3*conn[i],coo+3*conn[i]+3,w); + else if(spaceDim==2) + { + for(int i=0;i<nbOfNodesInCell;i++) + { + w=std::copy(coo+2*conn[i],coo+2*conn[i]+2,w); + *w++=0.; + } + } + else + throw INTERP_KERNEL::Exception("MEDCouplingUMesh::FillInCompact3DMode : Invalid spaceDim specified : must be 2 or 3 !"); +} + +void MEDCouplingUMesh::writeVTKLL(std::ostream& ofs, const std::string& cellData, const std::string& pointData, DataArrayByte *byteData) const +{ + int nbOfCells=getNumberOfCells(); + if(nbOfCells<=0) + throw INTERP_KERNEL::Exception("MEDCouplingUMesh::writeVTK : the unstructured mesh has no cells !"); + static const int PARAMEDMEM2VTKTYPETRADUCER[INTERP_KERNEL::NORM_MAXTYPE+1]={1,3,21,5,9,7,22,34,23,28,-1,-1,-1,-1,10,14,13,-1,12,-1,24,-1,16,27,-1,26,-1,29,-1,-1,25,42,36,4}; + ofs << " <" << getVTKDataSetType() << ">\n"; + ofs << " <Piece NumberOfPoints=\"" << getNumberOfNodes() << "\" NumberOfCells=\"" << nbOfCells << "\">\n"; + ofs << " <PointData>\n" << pointData << std::endl; + ofs << " </PointData>\n"; + ofs << " <CellData>\n" << cellData << std::endl; + ofs << " </CellData>\n"; + ofs << " <Points>\n"; + if(getSpaceDimension()==3) + _coords->writeVTK(ofs,8,"Points",byteData); + else + { + MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> coo=_coords->changeNbOfComponents(3,0.); + coo->writeVTK(ofs,8,"Points",byteData); + } + ofs << " </Points>\n"; + ofs << " <Cells>\n"; + const int *cPtr=_nodal_connec->getConstPointer(); + const int *cIPtr=_nodal_connec_index->getConstPointer(); + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> faceoffsets=DataArrayInt::New(); faceoffsets->alloc(nbOfCells,1); + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> types=DataArrayInt::New(); types->alloc(nbOfCells,1); + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> offsets=DataArrayInt::New(); offsets->alloc(nbOfCells,1); + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> connectivity=DataArrayInt::New(); connectivity->alloc(_nodal_connec->getNumberOfTuples()-nbOfCells,1); + int *w1=faceoffsets->getPointer(),*w2=types->getPointer(),*w3=offsets->getPointer(),*w4=connectivity->getPointer(); + int szFaceOffsets=0,szConn=0; + for(int i=0;i<nbOfCells;i++,w1++,w2++,w3++) + { + *w2=cPtr[cIPtr[i]]; + if((INTERP_KERNEL::NormalizedCellType)cPtr[cIPtr[i]]!=INTERP_KERNEL::NORM_POLYHED) + { + *w1=-1; + *w3=szConn+cIPtr[i+1]-cIPtr[i]-1; szConn+=cIPtr[i+1]-cIPtr[i]-1; + w4=std::copy(cPtr+cIPtr[i]+1,cPtr+cIPtr[i+1],w4); + } + else + { + int deltaFaceOffset=cIPtr[i+1]-cIPtr[i]+1; + *w1=szFaceOffsets+deltaFaceOffset; szFaceOffsets+=deltaFaceOffset; + std::set<int> c(cPtr+cIPtr[i]+1,cPtr+cIPtr[i+1]); c.erase(-1); + *w3=szConn+(int)c.size(); szConn+=(int)c.size(); + w4=std::copy(c.begin(),c.end(),w4); + } + } + types->transformWithIndArr(PARAMEDMEM2VTKTYPETRADUCER,PARAMEDMEM2VTKTYPETRADUCER+INTERP_KERNEL::NORM_MAXTYPE+1); + types->writeVTK(ofs,8,"UInt8","types",byteData); + offsets->writeVTK(ofs,8,"Int32","offsets",byteData); + if(szFaceOffsets!=0) + {//presence of Polyhedra + connectivity->reAlloc(szConn); + faceoffsets->writeVTK(ofs,8,"Int32","faceoffsets",byteData); + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> faces=DataArrayInt::New(); faces->alloc(szFaceOffsets,1); + w1=faces->getPointer(); + for(int i=0;i<nbOfCells;i++) + if((INTERP_KERNEL::NormalizedCellType)cPtr[cIPtr[i]]==INTERP_KERNEL::NORM_POLYHED) + { + int nbFaces=std::count(cPtr+cIPtr[i]+1,cPtr+cIPtr[i+1],-1)+1; + *w1++=nbFaces; + const int *w6=cPtr+cIPtr[i]+1,*w5=0; + for(int j=0;j<nbFaces;j++) + { + w5=std::find(w6,cPtr+cIPtr[i+1],-1); + *w1++=(int)std::distance(w6,w5); + w1=std::copy(w6,w5,w1); + w6=w5+1; + } + } + faces->writeVTK(ofs,8,"Int32","faces",byteData); + } + connectivity->writeVTK(ofs,8,"Int32","connectivity",byteData); + ofs << " </Cells>\n"; + ofs << " </Piece>\n"; + ofs << " </" << getVTKDataSetType() << ">\n"; +} + +void MEDCouplingUMesh::reprQuickOverview(std::ostream& stream) const +{ + stream << "MEDCouplingUMesh C++ instance at " << this << ". Name : \"" << getName() << "\"."; + if(_mesh_dim==-2) + { stream << " Not set !"; return ; } + stream << " Mesh dimension : " << _mesh_dim << "."; + if(_mesh_dim==-1) + return ; + if(!_coords) + { stream << " No coordinates set !"; return ; } + if(!_coords->isAllocated()) + { stream << " Coordinates set but not allocated !"; return ; } + stream << " Space dimension : " << _coords->getNumberOfComponents() << "." << std::endl; + stream << "Number of nodes : " << _coords->getNumberOfTuples() << "."; + if(!_nodal_connec_index) + { stream << std::endl << "Nodal connectivity NOT set !"; return ; } + if(!_nodal_connec_index->isAllocated()) + { stream << std::endl << "Nodal connectivity set but not allocated !"; return ; } + int lgth=_nodal_connec_index->getNumberOfTuples(); + int cpt=_nodal_connec_index->getNumberOfComponents(); + if(cpt!=1 || lgth<1) + return ; + stream << std::endl << "Number of cells : " << lgth-1 << "."; +} + +std::string MEDCouplingUMesh::getVTKDataSetType() const +{ + return std::string("UnstructuredGrid"); +} + +std::string MEDCouplingUMesh::getVTKFileExtension() const +{ + return std::string("vtu"); +} + +/*! + * Partitions the first given 2D mesh using the second given 2D mesh as a tool, and + * returns a result mesh constituted by polygons. + * Thus the final result contains all nodes from m1 plus new nodes. However it doesn't necessarily contains + * all nodes from m2. + * The meshes should be in 2D space. In + * addition, returns two arrays mapping cells of the result mesh to cells of the input + * meshes. + * \param [in] m1 - the first input mesh which is a partitioned object. The mesh must be so that each point in the space covered by \a m1 + * must be covered exactly by one entity, \b no \b more. If it is not the case, some tools are available to heal the mesh (conformize2D, mergeNodes) + * \param [in] m2 - the second input mesh which is a partition tool. The mesh must be so that each point in the space covered by \a m2 + * must be covered exactly by one entity, \b no \b more. If it is not the case, some tools are available to heal the mesh (conformize2D, mergeNodes) + * \param [in] eps - precision used to detect coincident mesh entities. + * \param [out] cellNb1 - a new instance of DataArrayInt holding for each result + * cell an id of the cell of \a m1 it comes from. The caller is to delete + * this array using decrRef() as it is no more needed. + * \param [out] cellNb2 - a new instance of DataArrayInt holding for each result + * cell an id of the cell of \a m2 it comes from. -1 value means that a + * result cell comes from a cell (or part of cell) of \a m1 not overlapped by + * any cell of \a m2. The caller is to delete this array using decrRef() as + * it is no more needed. + * \return MEDCouplingUMesh * - the result 2D mesh which is 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 in any of the meshes. + * \throw If the nodal connectivity of cells is not defined in any of the meshes. + * \throw If any of the meshes is not a 2D mesh in 2D space. + * + * \sa conformize2D, mergeNodes + */ +MEDCouplingUMesh *MEDCouplingUMesh::Intersect2DMeshes(const MEDCouplingUMesh *m1, const MEDCouplingUMesh *m2, + double eps, DataArrayInt *&cellNb1, DataArrayInt *&cellNb2) +{ + if(!m1 || !m2) + throw INTERP_KERNEL::Exception("MEDCouplingUMesh::Intersect2DMeshes : input meshes must be not NULL !"); + m1->checkFullyDefined(); + m2->checkFullyDefined(); + if(m1->getMeshDimension()!=2 || m1->getSpaceDimension()!=2 || m2->getMeshDimension()!=2 || m2->getSpaceDimension()!=2) + throw INTERP_KERNEL::Exception("MEDCouplingUMesh::Intersect2DMeshes works on umeshes m1 AND m2 with meshdim equal to 2 and spaceDim equal to 2 too!"); + + // Step 1: compute all edge intersections (new nodes) + std::vector< std::vector<int> > intersectEdge1, colinear2, subDiv2; + MEDCouplingUMesh *m1Desc=0,*m2Desc=0; // descending connec. meshes + DataArrayInt *desc1=0,*descIndx1=0,*revDesc1=0,*revDescIndx1=0,*desc2=0,*descIndx2=0,*revDesc2=0,*revDescIndx2=0; + std::vector<double> addCoo,addCoordsQuadratic; // coordinates of newly created nodes + IntersectDescending2DMeshes(m1,m2,eps,intersectEdge1,colinear2, subDiv2, + m1Desc,desc1,descIndx1,revDesc1,revDescIndx1, + addCoo, m2Desc,desc2,descIndx2,revDesc2,revDescIndx2); + revDesc1->decrRef(); revDescIndx1->decrRef(); revDesc2->decrRef(); revDescIndx2->decrRef(); + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> dd1(desc1),dd2(descIndx1),dd3(desc2),dd4(descIndx2); + MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> dd5(m1Desc),dd6(m2Desc); + + // Step 2: re-order newly created nodes according to the ordering found in m2 + std::vector< std::vector<int> > intersectEdge2; + BuildIntersectEdges(m1Desc,m2Desc,addCoo,subDiv2,intersectEdge2); + subDiv2.clear(); dd5=0; dd6=0; + + // Step 3: + std::vector<int> cr,crI; //no DataArrayInt because interface with Geometric2D + std::vector<int> cNb1,cNb2; //no DataArrayInt because interface with Geometric2D + BuildIntersecting2DCellsFromEdges(eps,m1,desc1->getConstPointer(),descIndx1->getConstPointer(),intersectEdge1,colinear2,m2,desc2->getConstPointer(),descIndx2->getConstPointer(),intersectEdge2,addCoo, + /* outputs -> */addCoordsQuadratic,cr,crI,cNb1,cNb2); + + // Step 4: Prepare final result: + MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> addCooDa(DataArrayDouble::New()); + addCooDa->alloc((int)(addCoo.size())/2,2); + std::copy(addCoo.begin(),addCoo.end(),addCooDa->getPointer()); + MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> addCoordsQuadraticDa(DataArrayDouble::New()); + addCoordsQuadraticDa->alloc((int)(addCoordsQuadratic.size())/2,2); + std::copy(addCoordsQuadratic.begin(),addCoordsQuadratic.end(),addCoordsQuadraticDa->getPointer()); + std::vector<const DataArrayDouble *> coordss(4); + coordss[0]=m1->getCoords(); coordss[1]=m2->getCoords(); coordss[2]=addCooDa; coordss[3]=addCoordsQuadraticDa; + MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> coo(DataArrayDouble::Aggregate(coordss)); + MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> ret(MEDCouplingUMesh::New("Intersect2D",2)); + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> conn(DataArrayInt::New()); conn->alloc((int)cr.size(),1); std::copy(cr.begin(),cr.end(),conn->getPointer()); + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> connI(DataArrayInt::New()); connI->alloc((int)crI.size(),1); std::copy(crI.begin(),crI.end(),connI->getPointer()); + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> c1(DataArrayInt::New()); c1->alloc((int)cNb1.size(),1); std::copy(cNb1.begin(),cNb1.end(),c1->getPointer()); + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> c2(DataArrayInt::New()); c2->alloc((int)cNb2.size(),1); std::copy(cNb2.begin(),cNb2.end(),c2->getPointer()); + ret->setConnectivity(conn,connI,true); + ret->setCoords(coo); + cellNb1=c1.retn(); cellNb2=c2.retn(); + return ret.retn(); +} + +/// @cond INTERNAL + +bool IsColinearOfACellOf(const std::vector< std::vector<int> >& intersectEdge1, const std::vector<int>& candidates, int start, int stop, int& retVal) +{ + if(candidates.empty()) + return false; + for(std::vector<int>::const_iterator it=candidates.begin();it!=candidates.end();it++) + { + const std::vector<int>& pool(intersectEdge1[*it]); + int tmp[2]; tmp[0]=start; tmp[1]=stop; + if(std::search(pool.begin(),pool.end(),tmp,tmp+2)!=pool.end()) + { + retVal=*it+1; + return true; + } + tmp[0]=stop; tmp[1]=start; + if(std::search(pool.begin(),pool.end(),tmp,tmp+2)!=pool.end()) + { + retVal=-*it-1; + return true; + } + } + return false; +} + +MEDCouplingUMesh *BuildMesh1DCutFrom(const MEDCouplingUMesh *mesh1D, const std::vector< std::vector<int> >& intersectEdge2, const DataArrayDouble *coords1, const std::vector<double>& addCoo, const std::map<int,int>& mergedNodes, const std::vector< std::vector<int> >& colinear2, const std::vector< std::vector<int> >& intersectEdge1, + MEDCouplingAutoRefCountObjectPtr<DataArrayInt>& idsInRetColinear, MEDCouplingAutoRefCountObjectPtr<DataArrayInt>& idsInMesh1DForIdsInRetColinear) +{ + idsInRetColinear=DataArrayInt::New(); idsInRetColinear->alloc(0,1); + idsInMesh1DForIdsInRetColinear=DataArrayInt::New(); idsInMesh1DForIdsInRetColinear->alloc(0,1); + int nCells(mesh1D->getNumberOfCells()); + if(nCells!=(int)intersectEdge2.size()) + throw INTERP_KERNEL::Exception("BuildMesh1DCutFrom : internal error # 1 !"); + const DataArrayDouble *coo2(mesh1D->getCoords()); + const int *c(mesh1D->getNodalConnectivity()->begin()),*ci(mesh1D->getNodalConnectivityIndex()->begin()); + const double *coo2Ptr(coo2->begin()); + int offset1(coords1->getNumberOfTuples()); + int offset2(offset1+coo2->getNumberOfTuples()); + int offset3(offset2+addCoo.size()/2); + std::vector<double> addCooQuad; + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> cOut(DataArrayInt::New()),ciOut(DataArrayInt::New()); cOut->alloc(0,1); ciOut->alloc(1,1); ciOut->setIJ(0,0,0); + int tmp[4],cicnt(0),kk(0); + for(int i=0;i<nCells;i++) + { + std::map<MEDCouplingAutoRefCountObjectPtr<INTERP_KERNEL::Node>,int> m; + INTERP_KERNEL::Edge *e(MEDCouplingUMeshBuildQPFromEdge2((INTERP_KERNEL::NormalizedCellType)c[ci[i]],c+ci[i]+1,coo2Ptr,m)); + const std::vector<int>& subEdges(intersectEdge2[i]); + int nbSubEdge(subEdges.size()/2); + for(int j=0;j<nbSubEdge;j++,kk++) + { + MEDCouplingAutoRefCountObjectPtr<INTERP_KERNEL::Node> n1(MEDCouplingUMeshBuildQPNode(subEdges[2*j],coords1->begin(),offset1,coo2Ptr,offset2,addCoo)),n2(MEDCouplingUMeshBuildQPNode(subEdges[2*j+1],coords1->begin(),offset1,coo2Ptr,offset2,addCoo)); + MEDCouplingAutoRefCountObjectPtr<INTERP_KERNEL::Edge> e2(e->buildEdgeLyingOnMe(n1,n2)); + INTERP_KERNEL::Edge *e2Ptr(e2); + std::map<int,int>::const_iterator itm; + if(dynamic_cast<INTERP_KERNEL::EdgeArcCircle *>(e2Ptr)) + { + tmp[0]=INTERP_KERNEL::NORM_SEG3; + itm=mergedNodes.find(subEdges[2*j]); + tmp[1]=itm!=mergedNodes.end()?(*itm).second:subEdges[2*j]; + itm=mergedNodes.find(subEdges[2*j+1]); + tmp[2]=itm!=mergedNodes.end()?(*itm).second:subEdges[2*j+1]; + tmp[3]=offset3+(int)addCooQuad.size()/2; + double tmp2[2]; + e2->getBarycenter(tmp2); addCooQuad.insert(addCooQuad.end(),tmp2,tmp2+2); + cicnt+=4; + cOut->insertAtTheEnd(tmp,tmp+4); + ciOut->pushBackSilent(cicnt); + } + else + { + tmp[0]=INTERP_KERNEL::NORM_SEG2; + itm=mergedNodes.find(subEdges[2*j]); + tmp[1]=itm!=mergedNodes.end()?(*itm).second:subEdges[2*j]; + itm=mergedNodes.find(subEdges[2*j+1]); + tmp[2]=itm!=mergedNodes.end()?(*itm).second:subEdges[2*j+1]; + cicnt+=3; + cOut->insertAtTheEnd(tmp,tmp+3); + ciOut->pushBackSilent(cicnt); + } + int tmp00; + if(IsColinearOfACellOf(intersectEdge1,colinear2[i],tmp[1],tmp[2],tmp00)) + { + idsInRetColinear->pushBackSilent(kk); + idsInMesh1DForIdsInRetColinear->pushBackSilent(tmp00); + } + } + e->decrRef(); + } + MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> ret(MEDCouplingUMesh::New(mesh1D->getName(),1)); + ret->setConnectivity(cOut,ciOut,true); + MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> arr3(DataArrayDouble::New()); + arr3->useArray(&addCoo[0],false,C_DEALLOC,(int)addCoo.size()/2,2); + MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> arr4(DataArrayDouble::New()); arr4->useArray(&addCooQuad[0],false,C_DEALLOC,(int)addCooQuad.size()/2,2); + std::vector<const DataArrayDouble *> coordss(4); + coordss[0]=coords1; coordss[1]=mesh1D->getCoords(); coordss[2]=arr3; coordss[3]=arr4; + MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> arr(DataArrayDouble::Aggregate(coordss)); + ret->setCoords(arr); + return ret.retn(); +} + +MEDCouplingUMesh *BuildRefined2DCellLinear(const DataArrayDouble *coords, const int *descBg, const int *descEnd, const std::vector< std::vector<int> >& intersectEdge1) +{ + std::vector<int> allEdges; + for(const int *it2(descBg);it2!=descEnd;it2++) + { + const std::vector<int>& edge1(intersectEdge1[std::abs(*it2)-1]); + if(*it2>0) + allEdges.insert(allEdges.end(),edge1.begin(),edge1.end()); + else + allEdges.insert(allEdges.end(),edge1.rbegin(),edge1.rend()); + } + std::size_t nb(allEdges.size()); + if(nb%2!=0) + throw INTERP_KERNEL::Exception("BuildRefined2DCellLinear : internal error 1 !"); + std::size_t nbOfEdgesOf2DCellSplit(nb/2); + MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> ret(MEDCouplingUMesh::New("",2)); + ret->setCoords(coords); + ret->allocateCells(1); + std::vector<int> connOut(nbOfEdgesOf2DCellSplit); + for(std::size_t kk=0;kk<nbOfEdgesOf2DCellSplit;kk++) + connOut[kk]=allEdges[2*kk]; + ret->insertNextCell(INTERP_KERNEL::NORM_POLYGON,connOut.size(),&connOut[0]); + return ret.retn(); +} + +MEDCouplingUMesh *BuildRefined2DCellQuadratic(const DataArrayDouble *coords, const MEDCouplingUMesh *mesh2D, int cellIdInMesh2D, const int *descBg, const int *descEnd, const std::vector< std::vector<int> >& intersectEdge1) +{ + const int *c(mesh2D->getNodalConnectivity()->begin()),*ci(mesh2D->getNodalConnectivityIndex()->begin()); + const INTERP_KERNEL::CellModel& cm(INTERP_KERNEL::CellModel::GetCellModel((INTERP_KERNEL::NormalizedCellType)c[ci[cellIdInMesh2D]])); + std::size_t ii(0); + unsigned sz(cm.getNumberOfSons2(c+ci[cellIdInMesh2D]+1,ci[cellIdInMesh2D+1]-ci[cellIdInMesh2D]-1)); + if(sz!=std::distance(descBg,descEnd)) + throw INTERP_KERNEL::Exception("BuildRefined2DCellQuadratic : internal error 1 !"); + INTERP_KERNEL::AutoPtr<int> tmpPtr(new int[ci[cellIdInMesh2D+1]-ci[cellIdInMesh2D]]); + std::vector<int> allEdges,centers; + const double *coordsPtr(coords->begin()); + MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> addCoo(DataArrayDouble::New()); addCoo->alloc(0,1); + int offset(coords->getNumberOfTuples()); + for(const int *it2(descBg);it2!=descEnd;it2++,ii++) + { + INTERP_KERNEL::NormalizedCellType typeOfSon; + cm.fillSonCellNodalConnectivity2(ii,c+ci[cellIdInMesh2D]+1,ci[cellIdInMesh2D+1]-ci[cellIdInMesh2D]-1,tmpPtr,typeOfSon); + const std::vector<int>& edge1(intersectEdge1[std::abs(*it2)-1]); + if(*it2>0) + allEdges.insert(allEdges.end(),edge1.begin(),edge1.end()); + else + allEdges.insert(allEdges.end(),edge1.rbegin(),edge1.rend()); + if(edge1.size()==2) + centers.push_back(tmpPtr[2]);//special case where no subsplit of edge -> reuse the original center. + else + {//the current edge has been subsplit -> create corresponding centers. + std::size_t nbOfCentersToAppend(edge1.size()/2); + std::map< MEDCouplingAutoRefCountObjectPtr<INTERP_KERNEL::Node>,int> m; + MEDCouplingAutoRefCountObjectPtr<INTERP_KERNEL::Edge> ee(MEDCouplingUMeshBuildQPFromEdge2(typeOfSon,tmpPtr,coordsPtr,m)); + std::vector<int>::const_iterator it3(allEdges.end()-edge1.size()); + for(std::size_t k=0;k<nbOfCentersToAppend;k++) + { + double tmpp[2]; + const double *aa(coordsPtr+2*(*it3++)); + const double *bb(coordsPtr+2*(*it3++)); + ee->getMiddleOfPoints(aa,bb,tmpp); + addCoo->insertAtTheEnd(tmpp,tmpp+2); + centers.push_back(offset+k); + } + } + } + std::size_t nb(allEdges.size()); + if(nb%2!=0) + throw INTERP_KERNEL::Exception("BuildRefined2DCellQuadratic : internal error 2 !"); + std::size_t nbOfEdgesOf2DCellSplit(nb/2); + MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> ret(MEDCouplingUMesh::New("",2)); + if(addCoo->empty()) + ret->setCoords(coords); + else + { + addCoo->rearrange(2); + addCoo=DataArrayDouble::Aggregate(coords,addCoo); + ret->setCoords(addCoo); + } + ret->allocateCells(1); + std::vector<int> connOut(nbOfEdgesOf2DCellSplit); + for(std::size_t kk=0;kk<nbOfEdgesOf2DCellSplit;kk++) + connOut[kk]=allEdges[2*kk]; + connOut.insert(connOut.end(),centers.begin(),centers.end()); + ret->insertNextCell(INTERP_KERNEL::NORM_QPOLYG,connOut.size(),&connOut[0]); + return ret.retn(); +} + +/*! + * This method creates a refinement of a cell in \a mesh2D. Those cell is defined by descending connectivity and the sorted subdivided nodal connectivity + * of those edges. + * + * \param [in] mesh2D - The origin 2D mesh. \b Warning \b coords are not those of \a mesh2D. But mesh2D->getCoords()==coords[:mesh2D->getNumberOfNodes()] + */ +MEDCouplingUMesh *BuildRefined2DCell(const DataArrayDouble *coords, const MEDCouplingUMesh *mesh2D, int cellIdInMesh2D, const int *descBg, const int *descEnd, const std::vector< std::vector<int> >& intersectEdge1) +{ + const INTERP_KERNEL::CellModel& cm(INTERP_KERNEL::CellModel::GetCellModel(mesh2D->getTypeOfCell(cellIdInMesh2D))); + if(!cm.isQuadratic()) + return BuildRefined2DCellLinear(coords,descBg,descEnd,intersectEdge1); + else + return BuildRefined2DCellQuadratic(coords,mesh2D,cellIdInMesh2D,descBg,descEnd,intersectEdge1); +} + +void AddCellInMesh2D(MEDCouplingUMesh *mesh2D, const std::vector<int>& conn, const std::vector< MEDCouplingAutoRefCountObjectPtr<INTERP_KERNEL::Edge> >& edges) +{ + bool isQuad(false); + for(std::vector< MEDCouplingAutoRefCountObjectPtr<INTERP_KERNEL::Edge> >::const_iterator it=edges.begin();it!=edges.end();it++) + { + const INTERP_KERNEL::Edge *ee(*it); + if(dynamic_cast<const INTERP_KERNEL::EdgeArcCircle *>(ee)) + isQuad=true; + } + if(!isQuad) + mesh2D->insertNextCell(INTERP_KERNEL::NORM_POLYGON,conn.size(),&conn[0]); + else + { + const double *coo(mesh2D->getCoords()->begin()); + std::size_t sz(conn.size()); + std::vector<double> addCoo; + std::vector<int> conn2(conn); + int offset(mesh2D->getNumberOfNodes()); + for(std::size_t i=0;i<sz;i++) + { + double tmp[2]; + edges[(i+1)%sz]->getMiddleOfPoints(coo+2*conn[i],coo+2*conn[(i+1)%sz],tmp);// tony a chier i+1 -> i + addCoo.insert(addCoo.end(),tmp,tmp+2); + conn2.push_back(offset+(int)i); + } + mesh2D->getCoords()->rearrange(1); + mesh2D->getCoords()->pushBackValsSilent(&addCoo[0],&addCoo[0]+addCoo.size()); + mesh2D->getCoords()->rearrange(2); + mesh2D->insertNextCell(INTERP_KERNEL::NORM_QPOLYG,conn2.size(),&conn2[0]); + } +} + +/*! + * \b WARNING edges in out1 coming from \a splitMesh1D are \b NOT oriented because only used for equation of curve. + * + * This method cuts in 2 parts the input 2D cell given using boundaries description (\a edge1Bis and \a edge1BisPtr) using + * a set of edges defined in \a splitMesh1D. + */ +void BuildMesh2DCutInternal2(const MEDCouplingUMesh *splitMesh1D, const std::vector<int>& edge1Bis, const std::vector< MEDCouplingAutoRefCountObjectPtr<INTERP_KERNEL::Edge> >& edge1BisPtr, + std::vector< std::vector<int> >& out0, std::vector< std::vector< MEDCouplingAutoRefCountObjectPtr<INTERP_KERNEL::Edge> > >& out1) +{ + std::size_t nb(edge1Bis.size()/2); + std::size_t nbOfEdgesOf2DCellSplit(nb/2); + int iEnd(splitMesh1D->getNumberOfCells()); + if(iEnd==0) + throw INTERP_KERNEL::Exception("BuildMesh2DCutInternal2 : internal error ! input 1D mesh must have at least one cell !"); + std::size_t ii,jj; + const int *cSplitPtr(splitMesh1D->getNodalConnectivity()->begin()),*ciSplitPtr(splitMesh1D->getNodalConnectivityIndex()->begin()); + for(ii=0;ii<nb && edge1Bis[2*ii]!=cSplitPtr[ciSplitPtr[0]+1];ii++); + for(jj=ii;jj<nb && edge1Bis[2*jj+1]!=cSplitPtr[ciSplitPtr[iEnd-1]+2];jj++); + // + if(jj==nb) + {//the edges splitMesh1D[iStart:iEnd] does not fully cut the current 2D cell -> single output cell + out0.resize(1); out1.resize(1); + std::vector<int>& connOut(out0[0]); + connOut.resize(nbOfEdgesOf2DCellSplit); + std::vector< MEDCouplingAutoRefCountObjectPtr<INTERP_KERNEL::Edge> >& edgesPtr(out1[0]); + edgesPtr.resize(nbOfEdgesOf2DCellSplit); + for(std::size_t kk=0;kk<nbOfEdgesOf2DCellSplit;kk++) + { + connOut[kk]=edge1Bis[2*kk]; + edgesPtr[kk]=edge1BisPtr[2*kk]; + } + } + else + { + // [i,iEnd[ contains the + out0.resize(2); out1.resize(2); + std::vector<int>& connOutLeft(out0[0]); + std::vector<int>& connOutRight(out0[1]);//connOutLeft should end with edge1Bis[2*ii] and connOutRight should end with edge1Bis[2*jj+1] + std::vector< MEDCouplingAutoRefCountObjectPtr<INTERP_KERNEL::Edge> >& eleft(out1[0]); + std::vector< MEDCouplingAutoRefCountObjectPtr<INTERP_KERNEL::Edge> >& eright(out1[1]); + for(std::size_t k=ii;k<jj+1;k++) + { connOutLeft.push_back(edge1Bis[2*k+1]); eleft.push_back(edge1BisPtr[2*k+1]); } + std::vector< MEDCouplingAutoRefCountObjectPtr<INTERP_KERNEL::Edge> > ees(iEnd); + for(int ik=0;ik<iEnd;ik++) + { + std::map< MEDCouplingAutoRefCountObjectPtr<INTERP_KERNEL::Node>,int> m; + MEDCouplingAutoRefCountObjectPtr<INTERP_KERNEL::Edge> ee(MEDCouplingUMeshBuildQPFromEdge2((INTERP_KERNEL::NormalizedCellType)cSplitPtr[ciSplitPtr[ik]],cSplitPtr+ciSplitPtr[ik]+1,splitMesh1D->getCoords()->begin(),m)); + ees[ik]=ee; + } + for(int ik=iEnd-1;ik>=0;ik--) + connOutLeft.push_back(cSplitPtr[ciSplitPtr[ik]+1]); + for(std::size_t k=jj+1;k<nbOfEdgesOf2DCellSplit+ii;k++) + { connOutRight.push_back(edge1Bis[2*k+1]); eright.push_back(edge1BisPtr[2*k+1]); } + eleft.insert(eleft.end(),ees.rbegin(),ees.rend()); + for(int ik=0;ik<iEnd;ik++) + connOutRight.push_back(cSplitPtr[ciSplitPtr[ik]+2]); + eright.insert(eright.end(),ees.begin(),ees.end()); + } +} + +/// @endcond + +/// @cond INTERNAL + +struct CellInfo +{ +public: + CellInfo() { } + CellInfo(const std::vector<int>& edges, const std::vector< MEDCouplingAutoRefCountObjectPtr<INTERP_KERNEL::Edge> >& edgesPtr); +public: + std::vector<int> _edges; + std::vector< MEDCouplingAutoRefCountObjectPtr<INTERP_KERNEL::Edge> > _edges_ptr; +}; + +CellInfo::CellInfo(const std::vector<int>& edges, const std::vector< MEDCouplingAutoRefCountObjectPtr<INTERP_KERNEL::Edge> >& edgesPtr) +{ + std::size_t nbe(edges.size()); + std::vector<int> edges2(2*nbe); std::vector< MEDCouplingAutoRefCountObjectPtr<INTERP_KERNEL::Edge> > edgesPtr2(2*nbe); + for(std::size_t i=0;i<nbe;i++) + { + edges2[2*i]=edges[i]; edges2[2*i+1]=edges[(i+1)%nbe]; + edgesPtr2[2*i]=edgesPtr[(i+1)%nbe]; edgesPtr2[2*i+1]=edgesPtr[(i+1)%nbe];//tony a chier + } + _edges.resize(4*nbe); _edges_ptr.resize(4*nbe); + std::copy(edges2.begin(),edges2.end(),_edges.begin()); std::copy(edges2.begin(),edges2.end(),_edges.begin()+2*nbe); + std::copy(edgesPtr2.begin(),edgesPtr2.end(),_edges_ptr.begin()); std::copy(edgesPtr2.begin(),edgesPtr2.end(),_edges_ptr.begin()+2*nbe); +} + +class EdgeInfo +{ +public: + EdgeInfo(int istart, int iend, const MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh>& mesh):_istart(istart),_iend(iend),_mesh(mesh),_left(-7),_right(-7) { } + EdgeInfo(int istart, int iend, int pos, const MEDCouplingAutoRefCountObjectPtr<INTERP_KERNEL::Edge>& edge):_istart(istart),_iend(iend),_edge(edge),_left(pos),_right(pos+1) { } + bool isInMyRange(int pos) const { return pos>=_istart && pos<_iend; } + void somethingHappendAt(int pos, const std::vector< MEDCouplingAutoRefCountObjectPtr<INTERP_KERNEL::Edge> >& newLeft, const std::vector< MEDCouplingAutoRefCountObjectPtr<INTERP_KERNEL::Edge> >& newRight); + void feedEdgeInfoAt(double eps, const MEDCouplingUMesh *mesh2D, int offset, int neighbors[2]) const; +private: + int _istart; + int _iend; + MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> _mesh; + MEDCouplingAutoRefCountObjectPtr<INTERP_KERNEL::Edge> _edge; + int _left; + int _right; +}; + +void EdgeInfo::somethingHappendAt(int pos, const std::vector< MEDCouplingAutoRefCountObjectPtr<INTERP_KERNEL::Edge> >& newLeft, const std::vector< MEDCouplingAutoRefCountObjectPtr<INTERP_KERNEL::Edge> >& newRight) +{ + const MEDCouplingUMesh *mesh(_mesh); + if(mesh) + return ; + if(_right<pos) + return ; + if(_left>pos) + { _left++; _right++; return ; } + if(_right==pos) + { + bool isLeft(std::find(newLeft.begin(),newLeft.end(),_edge)!=newLeft.end()),isRight(std::find(newRight.begin(),newRight.end(),_edge)!=newRight.end()); + if((isLeft && isRight) || (!isLeft && !isRight)) + throw INTERP_KERNEL::Exception("EdgeInfo::somethingHappendAt : internal error # 1 !"); + if(isLeft) + return ; + if(isRight) + { + _right++; + return ; + } + } + if(_left==pos) + { + bool isLeft(std::find(newLeft.begin(),newLeft.end(),_edge)!=newLeft.end()),isRight(std::find(newRight.begin(),newRight.end(),_edge)!=newRight.end()); + if((isLeft && isRight) || (!isLeft && !isRight)) + throw INTERP_KERNEL::Exception("EdgeInfo::somethingHappendAt : internal error # 2 !"); + if(isLeft) + { + _right++; + return ; + } + if(isRight) + { + _left++; + _right++; + return ; + } + } +} + +void EdgeInfo::feedEdgeInfoAt(double eps, const MEDCouplingUMesh *mesh2D, int offset, int neighbors[2]) const +{ + const MEDCouplingUMesh *mesh(_mesh); + if(!mesh) + { + neighbors[0]=offset+_left; neighbors[1]=offset+_right; + } + else + {// not fully splitting cell case + if(mesh2D->getNumberOfCells()==1) + {//little optimization. 1 cell no need to find in which cell mesh is ! + neighbors[0]=offset; neighbors[1]=offset; + return; + } + else + { + MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> barys(mesh->getBarycenterAndOwner()); + int cellId(mesh2D->getCellContainingPoint(barys->begin(),eps)); + if(cellId==-1) + throw INTERP_KERNEL::Exception("EdgeInfo::feedEdgeInfoAt : internal error !"); + neighbors[0]=offset+cellId; neighbors[1]=offset+cellId; + } + } +} + +class VectorOfCellInfo +{ +public: + VectorOfCellInfo(const std::vector<int>& edges, const std::vector< MEDCouplingAutoRefCountObjectPtr<INTERP_KERNEL::Edge> >& edgesPtr); + std::size_t size() const { return _pool.size(); } + int getPositionOf(double eps, const MEDCouplingUMesh *mesh) const; + void setMeshAt(int pos, const MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh>& mesh, int istart, int iend, const MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh>& mesh1DInCase, const std::vector< std::vector<int> >& edges, const std::vector< std::vector< MEDCouplingAutoRefCountObjectPtr<INTERP_KERNEL::Edge> > >& edgePtrs); + const std::vector<int>& getConnOf(int pos) const { return get(pos)._edges; } + const std::vector< MEDCouplingAutoRefCountObjectPtr<INTERP_KERNEL::Edge> >& getEdgePtrOf(int pos) const { return get(pos)._edges_ptr; } + MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> getZeMesh() const { return _ze_mesh; } + void feedEdgeInfoAt(double eps, int pos, int offset, int neighbors[2]) const; +private: + int getZePosOfEdgeGivenItsGlobalId(int pos) const; + void updateEdgeInfo(int pos, const std::vector< MEDCouplingAutoRefCountObjectPtr<INTERP_KERNEL::Edge> >& newLeft, const std::vector< MEDCouplingAutoRefCountObjectPtr<INTERP_KERNEL::Edge> >& newRight); + const CellInfo& get(int pos) const; + CellInfo& get(int pos); +private: + std::vector<CellInfo> _pool; + MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> _ze_mesh; + std::vector<EdgeInfo> _edge_info; +}; + +VectorOfCellInfo::VectorOfCellInfo(const std::vector<int>& edges, const std::vector< MEDCouplingAutoRefCountObjectPtr<INTERP_KERNEL::Edge> >& edgesPtr):_pool(1) +{ + _pool[0]._edges=edges; + _pool[0]._edges_ptr=edgesPtr; +} + +int VectorOfCellInfo::getPositionOf(double eps, const MEDCouplingUMesh *mesh) const +{ + if(_pool.empty()) + throw INTERP_KERNEL::Exception("VectorOfCellSplitter::getPositionOf : empty !"); + if(_pool.size()==1) + return 0; + const MEDCouplingUMesh *zeMesh(_ze_mesh); + if(!zeMesh) + throw INTERP_KERNEL::Exception("VectorOfCellSplitter::getPositionOf : null aggregated mesh !"); + MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> barys(mesh->getBarycenterAndOwner()); + return zeMesh->getCellContainingPoint(barys->begin(),eps); +} + +void VectorOfCellInfo::setMeshAt(int pos, const MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh>& mesh, int istart, int iend, const MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh>& mesh1DInCase, const std::vector< std::vector<int> >& edges, const std::vector< std::vector< MEDCouplingAutoRefCountObjectPtr<INTERP_KERNEL::Edge> > >& edgePtrs) +{ + get(pos);//to check pos + bool isFast(pos==0 && _pool.size()==1); + std::size_t sz(edges.size()); + // dealing with edges + if(sz==1) + _edge_info.push_back(EdgeInfo(istart,iend,mesh1DInCase)); + else + _edge_info.push_back(EdgeInfo(istart,iend,pos,edgePtrs[0].back())); + // + std::vector<CellInfo> pool(_pool.size()-1+sz); + for(int i=0;i<pos;i++) + pool[i]=_pool[i]; + for(std::size_t j=0;j<sz;j++) + pool[pos+j]=CellInfo(edges[j],edgePtrs[j]); + for(int i=pos+1;i<(int)_pool.size();i++) + pool[i+sz-1]=_pool[i]; + _pool=pool; + // + if(sz==2) + updateEdgeInfo(pos,edgePtrs[0],edgePtrs[1]); + // + if(isFast) + { + _ze_mesh=mesh; + return ; + } + // + std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> > ms; + if(pos>0) + { + MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> elt(static_cast<MEDCouplingUMesh *>(_ze_mesh->buildPartOfMySelf2(0,pos,true))); + ms.push_back(elt); + } + ms.push_back(mesh); + if(pos<_ze_mesh->getNumberOfCells()-1) + { + MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> elt(static_cast<MEDCouplingUMesh *>(_ze_mesh->buildPartOfMySelf2(pos+1,_ze_mesh->getNumberOfCells(),true))); + ms.push_back(elt); + } + std::vector< const MEDCouplingUMesh *> ms2(ms.size()); + for(std::size_t j=0;j<ms2.size();j++) + ms2[j]=ms[j]; + _ze_mesh=MEDCouplingUMesh::MergeUMeshesOnSameCoords(ms2); +} + +void VectorOfCellInfo::feedEdgeInfoAt(double eps, int pos, int offset, int neighbors[2]) const +{ + _edge_info[getZePosOfEdgeGivenItsGlobalId(pos)].feedEdgeInfoAt(eps,_ze_mesh,offset,neighbors); +} + +int VectorOfCellInfo::getZePosOfEdgeGivenItsGlobalId(int pos) const +{ + if(pos<0) + throw INTERP_KERNEL::Exception("VectorOfCellInfo::getZePosOfEdgeGivenItsGlobalId : invalid id ! Must be >=0 !"); + int ret(0); + for(std::vector<EdgeInfo>::const_iterator it=_edge_info.begin();it!=_edge_info.end();it++,ret++) + { + if((*it).isInMyRange(pos)) + return ret; + } + throw INTERP_KERNEL::Exception("VectorOfCellInfo::getZePosOfEdgeGivenItsGlobalId : invalid id !"); +} + +void VectorOfCellInfo::updateEdgeInfo(int pos, const std::vector< MEDCouplingAutoRefCountObjectPtr<INTERP_KERNEL::Edge> >& newLeft, const std::vector< MEDCouplingAutoRefCountObjectPtr<INTERP_KERNEL::Edge> >& newRight) +{ + get(pos);//to check; + if(_edge_info.empty()) + return ; + std::size_t sz(_edge_info.size()-1); + for(std::size_t i=0;i<sz;i++) + _edge_info[i].somethingHappendAt(pos,newLeft,newRight); +} + +const CellInfo& VectorOfCellInfo::get(int pos) const +{ + if(pos<0 || pos>=(int)_pool.size()) + throw INTERP_KERNEL::Exception("VectorOfCellSplitter::get const : invalid pos !"); + return _pool[pos]; +} + +CellInfo& VectorOfCellInfo::get(int pos) +{ + if(pos<0 || pos>=(int)_pool.size()) + throw INTERP_KERNEL::Exception("VectorOfCellSplitter::get : invalid pos !"); + return _pool[pos]; +} + +/*! + * Given : + * - a \b closed set of edges ( \a allEdges and \a allEdgesPtr ) that defines the split descending 2D cell. + * - \a splitMesh1D a split 2D curve mesh contained into 2D cell defined above. + * + * This method returns the 2D mesh and feeds \a idsLeftRight using offset. + * + * Algorithm : \a splitMesh1D is cut into contiguous parts. Each contiguous parts will build incrementally the output 2D cells. + * + * \param [in] allEdges a list of pairs (beginNode, endNode). Linked with \a allEdgesPtr to get the equation of edge. + */ +MEDCouplingUMesh *BuildMesh2DCutInternal(double eps, const MEDCouplingUMesh *splitMesh1D, const std::vector<int>& allEdges, const std::vector< MEDCouplingAutoRefCountObjectPtr<INTERP_KERNEL::Edge> >& allEdgesPtr, int offset, + MEDCouplingAutoRefCountObjectPtr<DataArrayInt>& idsLeftRight) +{ + int nbCellsInSplitMesh1D(splitMesh1D->getNumberOfCells()); + if(nbCellsInSplitMesh1D==0) + throw INTERP_KERNEL::Exception("BuildMesh2DCutInternal : internal error ! input 1D mesh must have at least one cell !"); + const int *cSplitPtr(splitMesh1D->getNodalConnectivity()->begin()),*ciSplitPtr(splitMesh1D->getNodalConnectivityIndex()->begin()); + std::size_t nb(allEdges.size()),jj; + if(nb%2!=0) + throw INTERP_KERNEL::Exception("BuildMesh2DCutFrom : internal error 2 !"); + std::vector<int> edge1Bis(nb*2); + std::vector< MEDCouplingAutoRefCountObjectPtr<INTERP_KERNEL::Edge> > edge1BisPtr(nb*2); + std::copy(allEdges.begin(),allEdges.end(),edge1Bis.begin()); + std::copy(allEdges.begin(),allEdges.end(),edge1Bis.begin()+nb); + std::copy(allEdgesPtr.begin(),allEdgesPtr.end(),edge1BisPtr.begin()); + std::copy(allEdgesPtr.begin(),allEdgesPtr.end(),edge1BisPtr.begin()+nb); + // + idsLeftRight=DataArrayInt::New(); idsLeftRight->alloc(nbCellsInSplitMesh1D*2); idsLeftRight->fillWithValue(-2); idsLeftRight->rearrange(2); + int *idsLeftRightPtr(idsLeftRight->getPointer()); + VectorOfCellInfo pool(edge1Bis,edge1BisPtr); + for(int iStart=0;iStart<nbCellsInSplitMesh1D;) + {// split [0:nbCellsInSplitMesh1D) in contiguous parts [iStart:iEnd) + int iEnd(iStart); + for(;iEnd<nbCellsInSplitMesh1D;) + { + for(jj=0;jj<nb && edge1Bis[2*jj+1]!=cSplitPtr[ciSplitPtr[iEnd]+2];jj++); + if(jj!=nb) + break; + else + iEnd++; + } + if(iEnd<nbCellsInSplitMesh1D) + iEnd++; + // + MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> partOfSplitMesh1D(static_cast<MEDCouplingUMesh *>(splitMesh1D->buildPartOfMySelf2(iStart,iEnd,1,true))); + int pos(pool.getPositionOf(eps,partOfSplitMesh1D)); + // + MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh>retTmp(MEDCouplingUMesh::New("",2)); + retTmp->setCoords(splitMesh1D->getCoords()); + retTmp->allocateCells(); + + std::vector< std::vector<int> > out0; + std::vector< std::vector< MEDCouplingAutoRefCountObjectPtr<INTERP_KERNEL::Edge> > > out1; + + BuildMesh2DCutInternal2(partOfSplitMesh1D,pool.getConnOf(pos),pool.getEdgePtrOf(pos),out0,out1); + for(std::size_t cnt=0;cnt<out0.size();cnt++) + AddCellInMesh2D(retTmp,out0[cnt],out1[cnt]); + pool.setMeshAt(pos,retTmp,iStart,iEnd,partOfSplitMesh1D,out0,out1); + // + iStart=iEnd; + } + for(int mm=0;mm<nbCellsInSplitMesh1D;mm++) + pool.feedEdgeInfoAt(eps,mm,offset,idsLeftRightPtr+2*mm); + return pool.getZeMesh().retn(); +} + +MEDCouplingUMesh *BuildMesh2DCutFrom(double eps, int cellIdInMesh2D, const MEDCouplingUMesh *mesh2DDesc, const MEDCouplingUMesh *splitMesh1D, + const int *descBg, const int *descEnd, const std::vector< std::vector<int> >& intersectEdge1, int offset, + MEDCouplingAutoRefCountObjectPtr<DataArrayInt>& idsLeftRight) +{ + const int *cdescPtr(mesh2DDesc->getNodalConnectivity()->begin()),*cidescPtr(mesh2DDesc->getNodalConnectivityIndex()->begin()); + // + std::vector<int> allEdges; + std::vector< MEDCouplingAutoRefCountObjectPtr<INTERP_KERNEL::Edge> > allEdgesPtr; // for each sub edge in splitMesh2D the uncut Edge object of the original mesh2D + for(const int *it(descBg);it!=descEnd;it++) // for all edges in the descending connectivity of the 2D mesh in relative Fortran mode + { + int edgeId(std::abs(*it)-1); + std::map< MEDCouplingAutoRefCountObjectPtr<INTERP_KERNEL::Node>,int> m; + MEDCouplingAutoRefCountObjectPtr<INTERP_KERNEL::Edge> ee(MEDCouplingUMeshBuildQPFromEdge2((INTERP_KERNEL::NormalizedCellType)cdescPtr[cidescPtr[edgeId]],cdescPtr+cidescPtr[edgeId]+1,mesh2DDesc->getCoords()->begin(),m)); + const std::vector<int>& edge1(intersectEdge1[edgeId]); + if(*it>0) + allEdges.insert(allEdges.end(),edge1.begin(),edge1.end()); + else + allEdges.insert(allEdges.end(),edge1.rbegin(),edge1.rend()); + std::size_t sz(edge1.size()); + for(std::size_t cnt=0;cnt<sz;cnt++) + allEdgesPtr.push_back(ee); + } + // + return BuildMesh2DCutInternal(eps,splitMesh1D,allEdges,allEdgesPtr,offset,idsLeftRight); +} + +bool AreEdgeEqual(const double *coo2D, const INTERP_KERNEL::CellModel& typ1, const int *conn1, const INTERP_KERNEL::CellModel& typ2, const int *conn2, double eps) +{ + if(!typ1.isQuadratic() && !typ2.isQuadratic()) + {//easy case comparison not + return conn1[0]==conn2[0] && conn1[1]==conn2[1]; + } + else if(typ1.isQuadratic() && typ2.isQuadratic()) + { + bool status0(conn1[0]==conn2[0] && conn1[1]==conn2[1]); + if(!status0) + return false; + if(conn1[2]==conn2[2]) + return true; + const double *a(coo2D+2*conn1[2]),*b(coo2D+2*conn2[2]); + double dist(sqrt((a[0]-b[0])*(a[0]-b[0])+(a[1]-b[1])*(a[1]-b[1]))); + return dist<eps; + } + else + {//only one is quadratic + bool status0(conn1[0]==conn2[0] && conn1[1]==conn2[1]); + if(!status0) + return false; + const double *a(0),*bb(0),*be(0); + if(typ1.isQuadratic()) + { + a=coo2D+2*conn1[2]; bb=coo2D+2*conn2[0]; be=coo2D+2*conn2[1]; + } + else + { + a=coo2D+2*conn2[2]; bb=coo2D+2*conn1[0]; be=coo2D+2*conn1[1]; + } + double b[2]; b[0]=(be[0]+bb[0])/2.; b[1]=(be[1]+bb[1])/2.; + double dist(sqrt((a[0]-b[0])*(a[0]-b[0])+(a[1]-b[1])*(a[1]-b[1]))); + return dist<eps; + } +} + +/*! + * This method returns among the cellIds [ \a candidatesIn2DBg , \a candidatesIn2DEnd ) in \a mesh2DSplit those exactly sharing \a cellIdInMesh1DSplitRelative in \a mesh1DSplit. + * \a mesh2DSplit and \a mesh1DSplit are expected to share the coordinates array. + * + * \param [in] cellIdInMesh1DSplitRelative is in Fortran mode using sign to specify direction. + */ +int FindRightCandidateAmong(const MEDCouplingUMesh *mesh2DSplit, const int *candidatesIn2DBg, const int *candidatesIn2DEnd, const MEDCouplingUMesh *mesh1DSplit, int cellIdInMesh1DSplitRelative, double eps) +{ + if(candidatesIn2DEnd==candidatesIn2DBg) + throw INTERP_KERNEL::Exception("FindRightCandidateAmong : internal error 1 !"); + const double *coo(mesh2DSplit->getCoords()->begin()); + if(std::distance(candidatesIn2DBg,candidatesIn2DEnd)==1) + return *candidatesIn2DBg; + int edgeId(std::abs(cellIdInMesh1DSplitRelative)-1); + MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> cur1D(static_cast<MEDCouplingUMesh *>(mesh1DSplit->buildPartOfMySelf(&edgeId,&edgeId+1,true))); + if(cellIdInMesh1DSplitRelative<0) + cur1D->changeOrientationOfCells(); + const int *c1D(cur1D->getNodalConnectivity()->begin()); + const INTERP_KERNEL::CellModel& ref1DType(INTERP_KERNEL::CellModel::GetCellModel((INTERP_KERNEL::NormalizedCellType)c1D[0])); + for(const int *it=candidatesIn2DBg;it!=candidatesIn2DEnd;it++) + { + MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> cur2D(static_cast<MEDCouplingUMesh *>(mesh2DSplit->buildPartOfMySelf(it,it+1,true))); + const int *c(cur2D->getNodalConnectivity()->begin()),*ci(cur2D->getNodalConnectivityIndex()->begin()); + const INTERP_KERNEL::CellModel &cm(INTERP_KERNEL::CellModel::GetCellModel((INTERP_KERNEL::NormalizedCellType)c[ci[0]])); + unsigned sz(cm.getNumberOfSons2(c+ci[0]+1,ci[1]-ci[0]-1)); + INTERP_KERNEL::AutoPtr<int> tmpPtr(new int[ci[1]-ci[0]]); + for(unsigned it2=0;it2<sz;it2++) + { + INTERP_KERNEL::NormalizedCellType typeOfSon; + cm.fillSonCellNodalConnectivity2(it2,c+ci[0]+1,ci[1]-ci[0]-1,tmpPtr,typeOfSon); + const INTERP_KERNEL::CellModel &curCM(INTERP_KERNEL::CellModel::GetCellModel(typeOfSon)); + if(AreEdgeEqual(coo,ref1DType,c1D+1,curCM,tmpPtr,eps)) + return *it; + } + } + throw INTERP_KERNEL::Exception("FindRightCandidateAmong : internal error 2 ! Unable to find the edge among split cell !"); +} + +/// @endcond + +/*! + * Partitions the first given 2D mesh using the second given 1D mesh as a tool. + * Thus the final result contains the aggregation of nodes of \a mesh2D, then nodes of \a mesh1D, then new nodes that are the result of the intersection + * and finaly, in case of quadratic polygon the centers of edges new nodes. + * The meshes should be in 2D space. In addition, returns two arrays mapping cells of the resulting mesh to cells of the input. + * + * \param [in] mesh2D - the 2D mesh (spacedim=meshdim=2) to be intersected using \a mesh1D tool. The mesh must be so that each point in the space covered by \a mesh2D + * must be covered exactly by one entity, \b no \b more. If it is not the case, some tools are available to heal the mesh (conformize2D, mergeNodes) + * \param [in] mesh1D - the 1D mesh (spacedim=2 meshdim=1) the is the tool that will be used to intersect \a mesh2D. \a mesh1D must be ordered consecutively. If it is not the case + * you can invoke orderConsecutiveCells1D on \a mesh1D. + * \param [in] eps - precision used to perform intersections and localization operations. + * \param [out] splitMesh2D - the result of the split of \a mesh2D mesh. + * \param [out] splitMesh1D - the result of the split of \a mesh1D mesh. + * \param [out] cellIdInMesh2D - the array that gives for each cell id \a i in \a splitMesh2D the id in \a mesh2D it comes from. + * So this array has a number of tuples equal to the number of cells of \a splitMesh2D and a number of component equal to 1. + * \param [out] cellIdInMesh1D - the array of pair that gives for each cell id \a i in \a splitMesh1D the cell in \a splitMesh2D on the left for the 1st component + * and the cell in \a splitMesh2D on the right for the 2nt component. -1 means no cell. + * So this array has a number of tuples equal to the number of cells of \a splitMesh1D and a number of components equal to 2. + * + * \sa Intersect2DMeshes, orderConsecutiveCells1D, conformize2D, mergeNodes + */ +void MEDCouplingUMesh::Intersect2DMeshWith1DLine(const MEDCouplingUMesh *mesh2D, const MEDCouplingUMesh *mesh1D, double eps, MEDCouplingUMesh *&splitMesh2D, MEDCouplingUMesh *&splitMesh1D, DataArrayInt *&cellIdInMesh2D, DataArrayInt *&cellIdInMesh1D) +{ + if(!mesh2D || !mesh1D) + throw INTERP_KERNEL::Exception("MEDCouplingUMesh::Intersect2DMeshWith1DLine : input meshes must be not NULL !"); + mesh2D->checkFullyDefined(); + mesh1D->checkFullyDefined(); + const std::vector<std::string>& compNames(mesh2D->getCoords()->getInfoOnComponents()); + if(mesh2D->getMeshDimension()!=2 || mesh2D->getSpaceDimension()!=2 || mesh1D->getMeshDimension()!=1 || mesh1D->getSpaceDimension()!=2) + throw INTERP_KERNEL::Exception("MEDCouplingUMesh::Intersect2DMeshWith1DLine works with mesh2D with spacedim=meshdim=2 and mesh1D with meshdim=1 spaceDim=2 !"); + // Step 1: compute all edge intersections (new nodes) + std::vector< std::vector<int> > intersectEdge1, colinear2, subDiv2; + std::vector<double> addCoo,addCoordsQuadratic; // coordinates of newly created nodes + INTERP_KERNEL::QUADRATIC_PLANAR::_precision=eps; + INTERP_KERNEL::QUADRATIC_PLANAR::_arc_detection_precision=eps; + // + // Build desc connectivity + DataArrayInt *desc1(DataArrayInt::New()),*descIndx1(DataArrayInt::New()),*revDesc1(DataArrayInt::New()),*revDescIndx1(DataArrayInt::New()); + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> dd1(desc1),dd2(descIndx1),dd3(revDesc1),dd4(revDescIndx1); + MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m1Desc(mesh2D->buildDescendingConnectivity2(desc1,descIndx1,revDesc1,revDescIndx1)); + std::map<int,int> mergedNodes; + Intersect1DMeshes(m1Desc,mesh1D,eps,intersectEdge1,colinear2,subDiv2,addCoo,mergedNodes); + // use mergeNodes to fix intersectEdge1 + for(std::vector< std::vector<int> >::iterator it0=intersectEdge1.begin();it0!=intersectEdge1.end();it0++) + { + std::size_t n((*it0).size()/2); + int eltStart((*it0)[0]),eltEnd((*it0)[2*n-1]); + std::map<int,int>::const_iterator it1; + it1=mergedNodes.find(eltStart); + if(it1!=mergedNodes.end()) + (*it0)[0]=(*it1).second; + it1=mergedNodes.find(eltEnd); + if(it1!=mergedNodes.end()) + (*it0)[2*n-1]=(*it1).second; + } + // + MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> addCooDa(DataArrayDouble::New()); + addCooDa->useArray(&addCoo[0],false,C_DEALLOC,(int)addCoo.size()/2,2); + // Step 2: re-order newly created nodes according to the ordering found in m2 + std::vector< std::vector<int> > intersectEdge2; + BuildIntersectEdges(m1Desc,mesh1D,addCoo,subDiv2,intersectEdge2); + subDiv2.clear(); + // Step 3: compute splitMesh1D + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> idsInRet1Colinear,idsInDescMesh2DForIdsInRetColinear; + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret2(DataArrayInt::New()); ret2->alloc(0,1); + MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> ret1(BuildMesh1DCutFrom(mesh1D,intersectEdge2,mesh2D->getCoords(),addCoo,mergedNodes,colinear2,intersectEdge1, + idsInRet1Colinear,idsInDescMesh2DForIdsInRetColinear)); + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret3(DataArrayInt::New()); ret3->alloc(ret1->getNumberOfCells()*2,1); ret3->fillWithValue(std::numeric_limits<int>::max()); ret3->rearrange(2); + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> idsInRet1NotColinear(idsInRet1Colinear->buildComplement(ret1->getNumberOfCells())); + // deal with cells in mesh2D that are not cut but only some of their edges are + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> idsInDesc2DToBeRefined(idsInDescMesh2DForIdsInRetColinear->deepCpy()); + idsInDesc2DToBeRefined->abs(); idsInDesc2DToBeRefined->applyLin(1,-1); + idsInDesc2DToBeRefined=idsInDesc2DToBeRefined->buildUnique(); + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> out0s;//ids in mesh2D that are impacted by the fact that some edges of \a mesh1D are part of the edges of those cells + if(!idsInDesc2DToBeRefined->empty()) + { + DataArrayInt *out0(0),*outi0(0); + MEDCouplingUMesh::ExtractFromIndexedArrays(idsInDesc2DToBeRefined->begin(),idsInDesc2DToBeRefined->end(),dd3,dd4,out0,outi0); + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> outi0s(outi0); + out0s=out0; + out0s=out0s->buildUnique(); + out0s->sort(true); + } + // + MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> ret1NonCol(static_cast<MEDCouplingUMesh *>(ret1->buildPartOfMySelf(idsInRet1NotColinear->begin(),idsInRet1NotColinear->end()))); + MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> baryRet1(ret1NonCol->getBarycenterAndOwner()); + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> elts,eltsIndex; + mesh2D->getCellsContainingPoints(baryRet1->begin(),baryRet1->getNumberOfTuples(),eps,elts,eltsIndex); + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> eltsIndex2(eltsIndex->deltaShiftIndex()); + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> eltsIndex3(eltsIndex2->getIdsEqual(1)); + if(eltsIndex2->count(0)+eltsIndex3->getNumberOfTuples()!=ret1NonCol->getNumberOfCells()) + throw INTERP_KERNEL::Exception("Intersect2DMeshWith1DLine : internal error 1 !"); + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> cellsToBeModified(elts->buildUnique()); + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> untouchedCells(cellsToBeModified->buildComplement(mesh2D->getNumberOfCells())); + if((DataArrayInt *)out0s) + untouchedCells=untouchedCells->buildSubstraction(out0s);//if some edges in ret1 are colinear to descending mesh of mesh2D remove cells from untouched one + std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> > outMesh2DSplit; + // OK all is ready to insert in ret2 mesh + if(!untouchedCells->empty()) + {// the most easy part, cells in mesh2D not impacted at all + outMesh2DSplit.push_back(static_cast<MEDCouplingUMesh *>(mesh2D->buildPartOfMySelf(untouchedCells->begin(),untouchedCells->end()))); + outMesh2DSplit.back()->setCoords(ret1->getCoords()); + ret2->pushBackValsSilent(untouchedCells->begin(),untouchedCells->end()); + } + if((DataArrayInt *)out0s) + {// here dealing with cells in out0s but not in cellsToBeModified + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> fewModifiedCells(out0s->buildSubstraction(cellsToBeModified)); + const int *rdptr(dd3->begin()),*rdiptr(dd4->begin()),*dptr(dd1->begin()),*diptr(dd2->begin()); + for(const int *it=fewModifiedCells->begin();it!=fewModifiedCells->end();it++) + { + outMesh2DSplit.push_back(BuildRefined2DCell(ret1->getCoords(),mesh2D,*it,dptr+diptr[*it],dptr+diptr[*it+1],intersectEdge1)); + ret1->setCoords(outMesh2DSplit.back()->getCoords()); + } + int offset(ret2->getNumberOfTuples()); + ret2->pushBackValsSilent(fewModifiedCells->begin(),fewModifiedCells->end()); + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> partOfRet3(DataArrayInt::New()); partOfRet3->alloc(2*idsInRet1Colinear->getNumberOfTuples(),1); + partOfRet3->fillWithValue(std::numeric_limits<int>::max()); partOfRet3->rearrange(2); + int kk(0),*ret3ptr(partOfRet3->getPointer()); + for(const int *it=idsInDescMesh2DForIdsInRetColinear->begin();it!=idsInDescMesh2DForIdsInRetColinear->end();it++,kk++) + { + int faceId(std::abs(*it)-1); + for(const int *it2=rdptr+rdiptr[faceId];it2!=rdptr+rdiptr[faceId+1];it2++) + { + int tmp(fewModifiedCells->locateValue(*it2)); + if(tmp!=-1) + { + if(std::find(dptr+diptr[*it2],dptr+diptr[*it2+1],-(*it))!=dptr+diptr[*it2+1]) + ret3ptr[2*kk]=tmp+offset; + if(std::find(dptr+diptr[*it2],dptr+diptr[*it2+1],(*it))!=dptr+diptr[*it2+1]) + ret3ptr[2*kk+1]=tmp+offset; + } + else + {//the current edge is shared by a 2D cell that will be split just after + if(std::find(dptr+diptr[*it2],dptr+diptr[*it2+1],-(*it))!=dptr+diptr[*it2+1]) + ret3ptr[2*kk]=-(*it2+1); + if(std::find(dptr+diptr[*it2],dptr+diptr[*it2+1],(*it))!=dptr+diptr[*it2+1]) + ret3ptr[2*kk+1]=-(*it2+1); + } + } + } + m1Desc->setCoords(ret1->getCoords()); + ret1NonCol->setCoords(ret1->getCoords()); + ret3->setPartOfValues3(partOfRet3,idsInRet1Colinear->begin(),idsInRet1Colinear->end(),0,2,1,true); + if(!outMesh2DSplit.empty()) + { + DataArrayDouble *da(outMesh2DSplit.back()->getCoords()); + for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> >::iterator itt=outMesh2DSplit.begin();itt!=outMesh2DSplit.end();itt++) + (*itt)->setCoords(da); + } + } + cellsToBeModified=cellsToBeModified->buildUniqueNotSorted(); + for(const int *it=cellsToBeModified->begin();it!=cellsToBeModified->end();it++) + { + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> idsNonColPerCell(elts->getIdsEqual(*it)); + idsNonColPerCell->transformWithIndArr(eltsIndex3->begin(),eltsIndex3->end()); + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> idsNonColPerCell2(idsInRet1NotColinear->selectByTupleId(idsNonColPerCell->begin(),idsNonColPerCell->end())); + MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> partOfMesh1CuttingCur2DCell(static_cast<MEDCouplingUMesh *>(ret1NonCol->buildPartOfMySelf(idsNonColPerCell->begin(),idsNonColPerCell->end()))); + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> partOfRet3; + MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> splitOfOneCell(BuildMesh2DCutFrom(eps,*it,m1Desc,partOfMesh1CuttingCur2DCell,dd1->begin()+dd2->getIJ(*it,0),dd1->begin()+dd2->getIJ((*it)+1,0),intersectEdge1,ret2->getNumberOfTuples(),partOfRet3)); + ret3->setPartOfValues3(partOfRet3,idsNonColPerCell2->begin(),idsNonColPerCell2->end(),0,2,1,true); + outMesh2DSplit.push_back(splitOfOneCell); + for(int i=0;i<splitOfOneCell->getNumberOfCells();i++) + ret2->pushBackSilent(*it); + } + // + std::size_t nbOfMeshes(outMesh2DSplit.size()); + std::vector<const MEDCouplingUMesh *> tmp(nbOfMeshes); + for(std::size_t i=0;i<nbOfMeshes;i++) + tmp[i]=outMesh2DSplit[i]; + // + ret1->getCoords()->setInfoOnComponents(compNames); + MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> ret2D(MEDCouplingUMesh::MergeUMeshesOnSameCoords(tmp)); + // To finish - filter ret3 - std::numeric_limits<int>::max() -> -1 - negate values must be resolved. + ret3->rearrange(1); + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> edgesToDealWith(ret3->getIdsStrictlyNegative()); + for(const int *it=edgesToDealWith->begin();it!=edgesToDealWith->end();it++) + { + int old2DCellId(-ret3->getIJ(*it,0)-1); + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> candidates(ret2->getIdsEqual(old2DCellId)); + ret3->setIJ(*it,0,FindRightCandidateAmong(ret2D,candidates->begin(),candidates->end(),ret1,*it%2==0?-((*it)/2+1):(*it)/2+1,eps));// div by 2 because 2 components natively in ret3 + } + ret3->replaceOneValByInThis(std::numeric_limits<int>::max(),-1); + ret3->rearrange(2); + // + splitMesh1D=ret1.retn(); + splitMesh2D=ret2D.retn(); + cellIdInMesh2D=ret2.retn(); + cellIdInMesh1D=ret3.retn(); +} + +/** + * Private. Third step of the partitioning algorithm (Intersect2DMeshes): reconstruct full 2D cells from the + * (newly created) nodes corresponding to the edge intersections. + * Output params: + * @param[out] cr, crI connectivity of the resulting mesh + * @param[out] cNb1, cNb2 correspondance arrays giving for the merged mesh the initial cells IDs in m1 / m2 + * TODO: describe input parameters + */ +void MEDCouplingUMesh::BuildIntersecting2DCellsFromEdges(double eps, const MEDCouplingUMesh *m1, const int *desc1, const int *descIndx1, + const std::vector<std::vector<int> >& intesctEdges1, const std::vector< std::vector<int> >& colinear2, + const MEDCouplingUMesh *m2, const int *desc2, const int *descIndx2, const std::vector<std::vector<int> >& intesctEdges2, + const std::vector<double>& addCoords, + std::vector<double>& addCoordsQuadratic, std::vector<int>& cr, std::vector<int>& crI, std::vector<int>& cNb1, std::vector<int>& cNb2) +{ + static const int SPACEDIM=2; + const double *coo1(m1->getCoords()->getConstPointer()); + const int *conn1(m1->getNodalConnectivity()->getConstPointer()),*connI1(m1->getNodalConnectivityIndex()->getConstPointer()); + int offset1(m1->getNumberOfNodes()); + const double *coo2(m2->getCoords()->getConstPointer()); + const int *conn2(m2->getNodalConnectivity()->getConstPointer()),*connI2(m2->getNodalConnectivityIndex()->getConstPointer()); + int offset2(offset1+m2->getNumberOfNodes()); + int offset3(offset2+((int)addCoords.size())/2); + MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> bbox1Arr(m1->getBoundingBoxForBBTree()),bbox2Arr(m2->getBoundingBoxForBBTree()); + const double *bbox1(bbox1Arr->begin()),*bbox2(bbox2Arr->begin()); + // Here a BBTree on 2D-cells, not on segments: + BBTree<SPACEDIM,int> myTree(bbox2,0,0,m2->getNumberOfCells(),eps); + int ncell1(m1->getNumberOfCells()); + crI.push_back(0); + for(int i=0;i<ncell1;i++) + { + std::vector<int> candidates2; + myTree.getIntersectingElems(bbox1+i*2*SPACEDIM,candidates2); + std::map<INTERP_KERNEL::Node *,int> mapp; + std::map<int,INTERP_KERNEL::Node *> mappRev; + INTERP_KERNEL::QuadraticPolygon pol1; + INTERP_KERNEL::NormalizedCellType typ=(INTERP_KERNEL::NormalizedCellType)conn1[connI1[i]]; + const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(typ); + // Populate mapp and mappRev with nodes from the current cell (i) from mesh1 - this also builds the Node* objects: + MEDCouplingUMeshBuildQPFromMesh3(coo1,offset1,coo2,offset2,addCoords,desc1+descIndx1[i],desc1+descIndx1[i+1],intesctEdges1,/* output */mapp,mappRev); + // pol1 is the full cell from mesh2, in QP format, with all the additional intersecting nodes. + pol1.buildFromCrudeDataArray(mappRev,cm.isQuadratic(),conn1+connI1[i]+1,coo1, + desc1+descIndx1[i],desc1+descIndx1[i+1],intesctEdges1); + // + std::set<INTERP_KERNEL::Edge *> edges1;// store all edges of pol1 that are NOT consumed by intersect cells. If any after iteration over candidates2 -> a part of pol1 should appear in result + std::set<INTERP_KERNEL::Edge *> edgesBoundary2;// store all edges that are on boundary of (pol2 intersect pol1) minus edges on pol1. + INTERP_KERNEL::IteratorOnComposedEdge it1(&pol1); + for(it1.first();!it1.finished();it1.next()) + edges1.insert(it1.current()->getPtr()); + // + std::map<int,std::vector<INTERP_KERNEL::ElementaryEdge *> > edgesIn2ForShare; // common edges + std::vector<INTERP_KERNEL::QuadraticPolygon> pol2s(candidates2.size()); + int ii=0; + for(std::vector<int>::const_iterator it2=candidates2.begin();it2!=candidates2.end();it2++,ii++) + { + INTERP_KERNEL::NormalizedCellType typ2=(INTERP_KERNEL::NormalizedCellType)conn2[connI2[*it2]]; + const INTERP_KERNEL::CellModel& cm2=INTERP_KERNEL::CellModel::GetCellModel(typ2); + // Complete mapping with elements coming from the current cell it2 in mesh2: + MEDCouplingUMeshBuildQPFromMesh3(coo1,offset1,coo2,offset2,addCoords,desc2+descIndx2[*it2],desc2+descIndx2[*it2+1],intesctEdges2,/* output */mapp,mappRev); + // pol2 is the new QP in the final merged result. + pol2s[ii].buildFromCrudeDataArray2(mappRev,cm2.isQuadratic(),conn2+connI2[*it2]+1,coo2,desc2+descIndx2[*it2],desc2+descIndx2[*it2+1],intesctEdges2, + pol1,desc1+descIndx1[i],desc1+descIndx1[i+1],intesctEdges1,colinear2, /* output */ edgesIn2ForShare); + } + ii=0; + for(std::vector<int>::const_iterator it2=candidates2.begin();it2!=candidates2.end();it2++,ii++) + { + INTERP_KERNEL::ComposedEdge::InitLocationsWithOther(pol1,pol2s[ii]); + pol2s[ii].updateLocOfEdgeFromCrudeDataArray2(desc2+descIndx2[*it2],desc2+descIndx2[*it2+1],intesctEdges2,pol1,desc1+descIndx1[i],desc1+descIndx1[i+1],intesctEdges1,colinear2); + //MEDCouplingUMeshAssignOnLoc(pol1,pol2,desc1+descIndx1[i],desc1+descIndx1[i+1],intesctEdges1,desc2+descIndx2[*it2],desc2+descIndx2[*it2+1],intesctEdges2,colinear2); + pol1.buildPartitionsAbs(pol2s[ii],edges1,edgesBoundary2,mapp,i,*it2,offset3,addCoordsQuadratic,cr,crI,cNb1,cNb2); + } + // Deals with remaining (non-consumed) edges from m1: these are the edges that were never touched + // by m2 but that we still want to keep in the final result. + if(!edges1.empty()) + { + try + { + INTERP_KERNEL::QuadraticPolygon::ComputeResidual(pol1,edges1,edgesBoundary2,mapp,offset3,i,addCoordsQuadratic,cr,crI,cNb1,cNb2); + } + catch(INTERP_KERNEL::Exception& e) + { + std::ostringstream oss; oss << "Error when computing residual of cell #" << i << " in source/m1 mesh ! Maybe the neighbours of this cell in mesh are not well connected !\n" << "The deep reason is the following : " << e.what(); + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + } + for(std::map<int,INTERP_KERNEL::Node *>::const_iterator it=mappRev.begin();it!=mappRev.end();it++) + (*it).second->decrRef(); + } +} + +/** + * Provides a renumbering of the cells of this (which has to be a piecewise connected 1D line), so that + * the segments of the line are indexed in consecutive order (i.e. cells \a i and \a i+1 are neighbors). + * This doesn't modify the mesh. This method only works using nodal connectivity consideration. Coordinates of nodes are ignored here. + * The caller is to deal with the resulting DataArrayInt. + * \throw If the coordinate array is not set. + * \throw If the nodal connectivity of the cells is not defined. + * \throw If m1 is not a mesh of dimension 2, or m1 is not a mesh of dimension 1 + * \throw If m2 is not a (piecewise) line (i.e. if a point has more than 2 adjacent segments) + * + * \sa DataArrayInt::sortEachPairToMakeALinkedList + */ +DataArrayInt *MEDCouplingUMesh::orderConsecutiveCells1D() const +{ + checkFullyDefined(); + if(getMeshDimension()!=1) + throw INTERP_KERNEL::Exception("MEDCouplingUMesh::orderConsecutiveCells1D works on unstructured mesh with meshdim = 1 !"); + + // Check that this is a line (and not a more complex 1D mesh) - each point is used at most by 2 segments: + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> _d(DataArrayInt::New()),_dI(DataArrayInt::New()); + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> _rD(DataArrayInt::New()),_rDI(DataArrayInt::New()); + MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m_points(buildDescendingConnectivity(_d, _dI, _rD, _rDI)); + const int *d(_d->getConstPointer()), *dI(_dI->getConstPointer()); + const int *rD(_rD->getConstPointer()), *rDI(_rDI->getConstPointer()); + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> _dsi(_rDI->deltaShiftIndex()); + const int * dsi(_dsi->getConstPointer()); + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> dsii = _dsi->getIdsNotInRange(0,3); + m_points=0; + if (dsii->getNumberOfTuples()) + throw INTERP_KERNEL::Exception("MEDCouplingUMesh::orderConsecutiveCells1D only work with a mesh being a (piecewise) connected line!"); + + int nc(getNumberOfCells()); + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> result(DataArrayInt::New()); + result->alloc(nc,1); + + // set of edges not used so far + std::set<int> edgeSet; + for (int i=0; i<nc; edgeSet.insert(i), i++); + + int startSeg=0; + int newIdx=0; + // while we have points with only one neighbor segments + do + { + std::list<int> linePiece; + // fills a list of consecutive segment linked to startSeg. This can go forward or backward. + for (int direction=0;direction<2;direction++) // direction=0 --> forward, direction=1 --> backward + { + // Fill the list forward (resp. backward) from the start segment: + int activeSeg = startSeg; + int prevPointId = -20; + int ptId; + while (!edgeSet.empty()) + { + if (!(direction == 1 && prevPointId==-20)) // prevent adding twice startSeg + { + if (direction==0) + linePiece.push_back(activeSeg); + else + linePiece.push_front(activeSeg); + edgeSet.erase(activeSeg); + } + + int ptId1 = d[dI[activeSeg]], ptId2 = d[dI[activeSeg]+1]; + ptId = direction ? (ptId1 == prevPointId ? ptId2 : ptId1) : (ptId2 == prevPointId ? ptId1 : ptId2); + if (dsi[ptId] == 1) // hitting the end of the line + break; + prevPointId = ptId; + int seg1 = rD[rDI[ptId]], seg2 = rD[rDI[ptId]+1]; + activeSeg = (seg1 == activeSeg) ? seg2 : seg1; + } + } + // Done, save final piece into DA: + std::copy(linePiece.begin(), linePiece.end(), result->getPointer()+newIdx); + newIdx += linePiece.size(); + + // identify next valid start segment (one which is not consumed) + if(!edgeSet.empty()) + startSeg = *(edgeSet.begin()); + } + while (!edgeSet.empty()); + return result.retn(); +} + +/// @cond INTERNAL + +void IKGeo2DInternalMapper2(INTERP_KERNEL::Node *n, const std::map<MEDCouplingAutoRefCountObjectPtr<INTERP_KERNEL::Node>,int>& m, int forbVal0, int forbVal1, std::vector<int>& isect) +{ + MEDCouplingAutoRefCountObjectPtr<INTERP_KERNEL::Node> nTmp(n); nTmp->incrRef(); + std::map<MEDCouplingAutoRefCountObjectPtr<INTERP_KERNEL::Node>,int>::const_iterator it(m.find(nTmp)); + if(it==m.end()) + throw INTERP_KERNEL::Exception("Internal error in remapping !"); + int v((*it).second); + if(v==forbVal0 || v==forbVal1) + return ; + if(std::find(isect.begin(),isect.end(),v)==isect.end()) + isect.push_back(v); +} + +bool IKGeo2DInternalMapper(const INTERP_KERNEL::ComposedEdge& c, const std::map<MEDCouplingAutoRefCountObjectPtr<INTERP_KERNEL::Node>,int>& m, int forbVal0, int forbVal1, std::vector<int>& isect) +{ + int sz(c.size()); + if(sz<=1) + return false; + bool presenceOfOn(false); + for(int i=0;i<sz;i++) + { + INTERP_KERNEL::ElementaryEdge *e(c[i]); + if(e->getLoc()!=INTERP_KERNEL::FULL_ON_1) + continue ; + IKGeo2DInternalMapper2(e->getStartNode(),m,forbVal0,forbVal1,isect); + IKGeo2DInternalMapper2(e->getEndNode(),m,forbVal0,forbVal1,isect); + } + return presenceOfOn; +} + +/// @endcond + +/** + * This method split some of edges of 2D cells in \a this. The edges to be split are specified in \a subNodesInSeg + * and in \a subNodesInSegI using \ref numbering-indirect storage mode. + * To do the work this method can optionally needs information about middle of subedges for quadratic cases if + * a minimal creation of new nodes is wanted. + * So this method try to reduce at most the number of new nodes. The only case that can lead this method to add + * nodes if a SEG3 is split without information of middle. + * \b WARNING : is returned value is different from 0 a call to MEDCouplingUMesh::mergeNodes is necessary to + * avoid to have a non conform mesh. + * + * \return int - the number of new nodes created (in most of cases 0). + * + * \throw If \a this is not coherent. + * \throw If \a this has not spaceDim equal to 2. + * \throw If \a this has not meshDim equal to 2. + * \throw If some subcells needed to be split are orphan. + * \sa MEDCouplingUMesh::conformize2D + */ +int MEDCouplingUMesh::split2DCells(const DataArrayInt *desc, const DataArrayInt *descI, const DataArrayInt *subNodesInSeg, const DataArrayInt *subNodesInSegI, const DataArrayInt *midOpt, const DataArrayInt *midOptI) +{ + if(!desc || !descI || !subNodesInSeg || !subNodesInSegI) + throw INTERP_KERNEL::Exception("MEDCouplingUMesh::split2DCells : the 4 first arrays must be not null !"); + desc->checkAllocated(); descI->checkAllocated(); subNodesInSeg->checkAllocated(); subNodesInSegI->checkAllocated(); + if(getSpaceDimension()!=2 || getMeshDimension()!=2) + throw INTERP_KERNEL::Exception("MEDCouplingUMesh::split2DCells : This method only works for meshes with spaceDim=2 and meshDim=2 !"); + if(midOpt==0 && midOptI==0) + { + split2DCellsLinear(desc,descI,subNodesInSeg,subNodesInSegI); + return 0; + } + else if(midOpt!=0 && midOptI!=0) + return split2DCellsQuadratic(desc,descI,subNodesInSeg,subNodesInSegI,midOpt,midOptI); + else + throw INTERP_KERNEL::Exception("MEDCouplingUMesh::split2DCells : middle parameters must be set to null for all or not null for all."); +} + +/*! + * \b WARNING this method is \b potentially \b non \b const (if returned array is empty). + * \b WARNING this method lead to have a non geometric type sorted mesh (for MED file users) ! + * This method performs a conformization of \b this. So if a edge in \a this can be split into entire edges in \a this this method + * will suppress such edges to use sub edges in \a this. So this method does not add nodes in \a this if merged edges are both linear (INTERP_KERNEL::NORM_SEG2). + * In the other cases new nodes can be created. If any are created, they will be appended at the end of the coordinates object before the invokation of this method. + * + * Whatever the returned value, this method does not alter the order of cells in \a this neither the orientation of cells. + * The modified cells, if any, are systematically declared as NORM_POLYGON or NORM_QPOLYG depending on the initial quadraticness of geometric type. + * + * This method expects that \b this has a meshDim equal 2 and spaceDim equal to 2 too. + * This method expects that all nodes in \a this are not closer than \a eps. + * If it is not the case you can invoke MEDCouplingUMesh::mergeNodes before calling this method. + * + * \param [in] eps the relative error to detect merged edges. + * \return DataArrayInt * - The list of cellIds in \a this that have been subdivided. If empty, nothing changed in \a this (as if it were a const method). The array is a newly allocated array + * that the user is expected to deal with. + * + * \throw If \a this is not coherent. + * \throw If \a this has not spaceDim equal to 2. + * \throw If \a this has not meshDim equal to 2. + * \sa MEDCouplingUMesh::mergeNodes, MEDCouplingUMesh::split2DCells + */ +DataArrayInt *MEDCouplingUMesh::conformize2D(double eps) +{ + static const int SPACEDIM=2; + checkCoherency(); + if(getSpaceDimension()!=2 || getMeshDimension()!=2) + throw INTERP_KERNEL::Exception("MEDCouplingUMesh::conformize2D : This method only works for meshes with spaceDim=2 and meshDim=2 !"); + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> desc1(DataArrayInt::New()),descIndx1(DataArrayInt::New()),revDesc1(DataArrayInt::New()),revDescIndx1(DataArrayInt::New()); + MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> mDesc(buildDescendingConnectivity(desc1,descIndx1,revDesc1,revDescIndx1)); + const int *c(mDesc->getNodalConnectivity()->getConstPointer()),*ci(mDesc->getNodalConnectivityIndex()->getConstPointer()),*rd(revDesc1->getConstPointer()),*rdi(revDescIndx1->getConstPointer()); + MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> bboxArr(mDesc->getBoundingBoxForBBTree()); + const double *bbox(bboxArr->begin()),*coords(getCoords()->begin()); + int nCell(getNumberOfCells()),nDescCell(mDesc->getNumberOfCells()); + std::vector< std::vector<int> > intersectEdge(nDescCell),overlapEdge(nDescCell); + std::vector<double> addCoo; + BBTree<SPACEDIM,int> myTree(bbox,0,0,nDescCell,-eps); + INTERP_KERNEL::QUADRATIC_PLANAR::_precision=eps; + INTERP_KERNEL::QUADRATIC_PLANAR::_arc_detection_precision=eps; + for(int i=0;i<nDescCell;i++) + { + std::vector<int> candidates; + myTree.getIntersectingElems(bbox+i*2*SPACEDIM,candidates); + for(std::vector<int>::const_iterator it=candidates.begin();it!=candidates.end();it++) + if(*it>i) + { + std::map<MEDCouplingAutoRefCountObjectPtr<INTERP_KERNEL::Node>,int> m; + INTERP_KERNEL::Edge *e1(MEDCouplingUMeshBuildQPFromEdge2((INTERP_KERNEL::NormalizedCellType)c[ci[i]],c+ci[i]+1,coords,m)), + *e2(MEDCouplingUMeshBuildQPFromEdge2((INTERP_KERNEL::NormalizedCellType)c[ci[*it]],c+ci[*it]+1,coords,m)); + INTERP_KERNEL::MergePoints merge; + INTERP_KERNEL::QuadraticPolygon c1,c2; + e1->intersectWith(e2,merge,c1,c2); + e1->decrRef(); e2->decrRef(); + if(IKGeo2DInternalMapper(c1,m,c[ci[i]+1],c[ci[i]+2],intersectEdge[i])) + overlapEdge[i].push_back(*it); + if(IKGeo2DInternalMapper(c2,m,c[ci[*it]+1],c[ci[*it]+2],intersectEdge[*it])) + overlapEdge[*it].push_back(i); + } + } + // splitting done. sort intersect point in intersectEdge. + std::vector< std::vector<int> > middle(nDescCell); + int nbOf2DCellsToBeSplit(0); + bool middleNeedsToBeUsed(false); + std::vector<bool> cells2DToTreat(nDescCell,false); + for(int i=0;i<nDescCell;i++) + { + std::vector<int>& isect(intersectEdge[i]); + int sz((int)isect.size()); + if(sz>1) + { + std::map<MEDCouplingAutoRefCountObjectPtr<INTERP_KERNEL::Node>,int> m; + INTERP_KERNEL::Edge *e(MEDCouplingUMeshBuildQPFromEdge2((INTERP_KERNEL::NormalizedCellType)c[ci[i]],c+ci[i]+1,coords,m)); + e->sortSubNodesAbs(coords,isect); + e->decrRef(); + } + if(sz!=0) + { + int idx0(rdi[i]),idx1(rdi[i+1]); + if(idx1-idx0!=1) + throw INTERP_KERNEL::Exception("MEDCouplingUMesh::conformize2D : internal error #0 !"); + if(!cells2DToTreat[rd[idx0]]) + { + cells2DToTreat[rd[idx0]]=true; + nbOf2DCellsToBeSplit++; + } + // try to reuse at most eventual 'middle' of SEG3 + std::vector<int>& mid(middle[i]); + mid.resize(sz+1,-1); + if((INTERP_KERNEL::NormalizedCellType)c[ci[i]]==INTERP_KERNEL::NORM_SEG3) + { + middleNeedsToBeUsed=true; + const std::vector<int>& candidates(overlapEdge[i]); + std::vector<int> trueCandidates; + for(std::vector<int>::const_iterator itc=candidates.begin();itc!=candidates.end();itc++) + if((INTERP_KERNEL::NormalizedCellType)c[ci[*itc]]==INTERP_KERNEL::NORM_SEG3) + trueCandidates.push_back(*itc); + int stNode(c[ci[i]+1]),endNode(isect[0]); + for(int j=0;j<sz+1;j++) + { + for(std::vector<int>::const_iterator itc=trueCandidates.begin();itc!=trueCandidates.end();itc++) + { + int tmpSt(c[ci[*itc]+1]),tmpEnd(c[ci[*itc]+2]); + if((tmpSt==stNode && tmpEnd==endNode) || (tmpSt==endNode && tmpEnd==stNode)) + { mid[j]=*itc; break; } + } + stNode=endNode; + endNode=j<sz-1?isect[j+1]:c[ci[i]+2]; + } + } + } + } + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret(DataArrayInt::New()),notRet(DataArrayInt::New()); ret->alloc(nbOf2DCellsToBeSplit,1); + if(nbOf2DCellsToBeSplit==0) + return ret.retn(); + // + int *retPtr(ret->getPointer()); + for(int i=0;i<nCell;i++) + if(cells2DToTreat[i]) + *retPtr++=i; + // + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> mSafe,nSafe,oSafe,pSafe,qSafe,rSafe; + DataArrayInt *m(0),*n(0),*o(0),*p(0),*q(0),*r(0); + MEDCouplingUMesh::ExtractFromIndexedArrays(ret->begin(),ret->end(),desc1,descIndx1,m,n); mSafe=m; nSafe=n; + DataArrayInt::PutIntoToSkylineFrmt(intersectEdge,o,p); oSafe=o; pSafe=p; + if(middleNeedsToBeUsed) + { DataArrayInt::PutIntoToSkylineFrmt(middle,q,r); qSafe=q; rSafe=r; } + MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> modif(static_cast<MEDCouplingUMesh *>(buildPartOfMySelf(ret->begin(),ret->end(),true))); + int nbOfNodesCreated(modif->split2DCells(mSafe,nSafe,oSafe,pSafe,qSafe,rSafe)); + setCoords(modif->getCoords());//if nbOfNodesCreated==0 modif and this have the same coordinates pointer so this line has no effect. But for quadratic cases this line is important. + setPartOfMySelf(ret->begin(),ret->end(),*modif); + { + bool areNodesMerged; int newNbOfNodes; + if(nbOfNodesCreated!=0) + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> tmp(mergeNodes(eps,areNodesMerged,newNbOfNodes)); + } + return ret.retn(); +} + +/*! + * This non const method works on 2D mesh. This method scans every cell in \a this and look if each edge constituting this cell is not mergeable with neighbors edges of that cell. + * If yes, the cell is "repaired" to minimize at most its number of edges. So this method do not change the overall shape of cells in \a this (with eps precision). + * This method do not take care of shared edges between cells, so this method can lead to a non conform mesh (\a this). If a conform mesh is required you're expected + * to invoke MEDCouplingUMesh::mergeNodes and MEDCouplingUMesh::conformize2D right after this call. + * This method works on any 2D geometric types of cell (even static one). If a cell is touched its type becomes dynamic automaticaly. For 2D "repaired" quadratic cells + * new nodes for center of merged edges is are systematically created and appended at the end of the previously existing nodes. + * + * If the returned array is empty it means that nothing has changed in \a this (as if it were a const method). If the array is not empty the connectivity of \a this is modified + * using new instance, idem for coordinates. + * + * If \a this is constituted by only linear 2D cells, this method is close to the computation of the convex hull of each cells in \a this. + * + * \return DataArrayInt * - The list of cellIds in \a this that have at least one edge colinearized. + * + * \throw If \a this is not coherent. + * \throw If \a this has not spaceDim equal to 2. + * \throw If \a this has not meshDim equal to 2. + * + * \sa MEDCouplingUMesh::conformize2D, MEDCouplingUMesh::mergeNodes, MEDCouplingUMesh::convexEnvelop2D. + */ +DataArrayInt *MEDCouplingUMesh::colinearize2D(double eps) +{ + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(0,1); + checkCoherency(); + if(getSpaceDimension()!=2 || getMeshDimension()!=2) + throw INTERP_KERNEL::Exception("MEDCouplingUMesh::colinearize2D : This method only works for meshes with spaceDim=2 and meshDim=2 !"); + INTERP_KERNEL::QUADRATIC_PLANAR::_arc_detection_precision=eps; + INTERP_KERNEL::QUADRATIC_PLANAR::_precision=eps; + int nbOfCells(getNumberOfCells()),nbOfNodes(getNumberOfNodes()); + const int *cptr(_nodal_connec->begin()),*ciptr(_nodal_connec_index->begin()); + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> newc(DataArrayInt::New()),newci(DataArrayInt::New()); newci->alloc(nbOfCells+1,1); newc->alloc(0,1); newci->setIJ(0,0,0); + MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> appendedCoords(DataArrayDouble::New()); appendedCoords->alloc(0,1);//1 not 2 it is not a bug. + const double *coords(_coords->begin()); + int *newciptr(newci->getPointer()); + for(int i=0;i<nbOfCells;i++,newciptr++,ciptr++) + { + if(Colinearize2DCell(coords,cptr+ciptr[0],cptr+ciptr[1],nbOfNodes,newc,appendedCoords)) + ret->pushBackSilent(i); + newciptr[1]=newc->getNumberOfTuples(); + } + // + if(ret->empty()) + return ret.retn(); + if(!appendedCoords->empty()) + { + appendedCoords->rearrange(2); + MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> newCoords(DataArrayDouble::Aggregate(getCoords(),appendedCoords));//treat info on components + //non const part + setCoords(newCoords); + } + //non const part + setConnectivity(newc,newci,true); + return ret.retn(); +} + +/*! + * \param [out] intersectEdge1 - for each cell in \a m1Desc returns the result of the split. The result is given using pair of int given resp start and stop. + * So for all edge \a i in \a m1Desc \a intersectEdge1[i] is of length 2*n where n is the number of sub edges. + * And for each j in [1,n) intersect[i][2*(j-1)+1]==intersect[i][2*j]. + * \param [out] subDiv2 - for each cell in \a m2Desc returns nodes that split it using convention \a m1Desc first, then \a m2Desc, then addCoo + * \param [out] colinear2 - for each cell in \a m2Desc returns the edges in \a m1Desc that are colinear to it. + * \param [out] addCoo - nodes to be append at the end + * \param [out] mergedNodes - gives all pair of nodes of \a m2Desc that have same location than some nodes in \a m1Desc. key is id in \a m2Desc offseted and value is id in \a m1Desc. + */ +void MEDCouplingUMesh::Intersect1DMeshes(const MEDCouplingUMesh *m1Desc, const MEDCouplingUMesh *m2Desc, double eps, + std::vector< std::vector<int> >& intersectEdge1, std::vector< std::vector<int> >& colinear2, std::vector< std::vector<int> >& subDiv2, std::vector<double>& addCoo, std::map<int,int>& mergedNodes) +{ + static const int SPACEDIM=2; + INTERP_KERNEL::QUADRATIC_PLANAR::_precision=eps; + INTERP_KERNEL::QUADRATIC_PLANAR::_arc_detection_precision=eps; + const int *c1(m1Desc->getNodalConnectivity()->getConstPointer()),*ci1(m1Desc->getNodalConnectivityIndex()->getConstPointer()); + // Build BB tree of all edges in the tool mesh (second mesh) + MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> bbox1Arr(m1Desc->getBoundingBoxForBBTree()),bbox2Arr(m2Desc->getBoundingBoxForBBTree()); + const double *bbox1(bbox1Arr->begin()),*bbox2(bbox2Arr->begin()); + int nDescCell1(m1Desc->getNumberOfCells()),nDescCell2(m2Desc->getNumberOfCells()); + intersectEdge1.resize(nDescCell1); + colinear2.resize(nDescCell2); + subDiv2.resize(nDescCell2); + BBTree<SPACEDIM,int> myTree(bbox2,0,0,m2Desc->getNumberOfCells(),-eps); + + std::vector<int> candidates1(1); + int offset1(m1Desc->getNumberOfNodes()); + int offset2(offset1+m2Desc->getNumberOfNodes()); + for(int i=0;i<nDescCell1;i++) // for all edges in the first mesh + { + std::vector<int> candidates2; // edges of mesh2 candidate for intersection + myTree.getIntersectingElems(bbox1+i*2*SPACEDIM,candidates2); + if(!candidates2.empty()) // candidates2 holds edges from the second mesh potentially intersecting current edge i in mesh1 + { + std::map<INTERP_KERNEL::Node *,int> map1,map2; + // pol2 is not necessarily a closed polygon: just a set of (quadratic) edges (same as candidates2) in the Geometric DS format + INTERP_KERNEL::QuadraticPolygon *pol2=MEDCouplingUMeshBuildQPFromMesh(m2Desc,candidates2,map2); + candidates1[0]=i; + INTERP_KERNEL::QuadraticPolygon *pol1=MEDCouplingUMeshBuildQPFromMesh(m1Desc,candidates1,map1); + // This following part is to avoid that some removed nodes (for example due to a merge between pol1 and pol2) are replaced by a newly created one + // This trick guarantees that Node * are discriminant (i.e. form a unique identifier) + std::set<INTERP_KERNEL::Node *> nodes; + pol1->getAllNodes(nodes); pol2->getAllNodes(nodes); + std::size_t szz(nodes.size()); + std::vector< MEDCouplingAutoRefCountObjectPtr<INTERP_KERNEL::Node> > nodesSafe(szz); + std::set<INTERP_KERNEL::Node *>::const_iterator itt(nodes.begin()); + for(std::size_t iii=0;iii<szz;iii++,itt++) + { (*itt)->incrRef(); nodesSafe[iii]=*itt; } + // end of protection + // Performs egde cutting: + pol1->splitAbs(*pol2,map1,map2,offset1,offset2,candidates2,intersectEdge1[i],i,colinear2,subDiv2,addCoo,mergedNodes); + delete pol2; + delete pol1; + } + else + // Copy the edge (take only the two first points, ie discard quadratic point at this stage) + intersectEdge1[i].insert(intersectEdge1[i].end(),c1+ci1[i]+1,c1+ci1[i]+3); + } +} + +/*! + * This method is private and is the first step of Partition of 2D mesh (spaceDim==2 and meshDim==2). + * It builds the descending connectivity of the two meshes, and then using a binary tree + * it computes the edge intersections. This results in new points being created : they're stored in addCoo. + * Documentation about parameters colinear2 and subDiv2 can be found in method QuadraticPolygon::splitAbs(). + */ +void MEDCouplingUMesh::IntersectDescending2DMeshes(const MEDCouplingUMesh *m1, const MEDCouplingUMesh *m2, double eps, + std::vector< std::vector<int> >& intersectEdge1, std::vector< std::vector<int> >& colinear2, std::vector< std::vector<int> >& subDiv2, + MEDCouplingUMesh *& m1Desc, DataArrayInt *&desc1, DataArrayInt *&descIndx1, DataArrayInt *&revDesc1, DataArrayInt *&revDescIndx1, + std::vector<double>& addCoo, + MEDCouplingUMesh *& m2Desc, DataArrayInt *&desc2, DataArrayInt *&descIndx2, DataArrayInt *&revDesc2, DataArrayInt *&revDescIndx2) +{ + // Build desc connectivity + desc1=DataArrayInt::New(); descIndx1=DataArrayInt::New(); revDesc1=DataArrayInt::New(); revDescIndx1=DataArrayInt::New(); + desc2=DataArrayInt::New(); + descIndx2=DataArrayInt::New(); + revDesc2=DataArrayInt::New(); + revDescIndx2=DataArrayInt::New(); + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> dd1(desc1),dd2(descIndx1),dd3(revDesc1),dd4(revDescIndx1); + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> dd5(desc2),dd6(descIndx2),dd7(revDesc2),dd8(revDescIndx2); + m1Desc=m1->buildDescendingConnectivity2(desc1,descIndx1,revDesc1,revDescIndx1); + m2Desc=m2->buildDescendingConnectivity2(desc2,descIndx2,revDesc2,revDescIndx2); + MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> dd9(m1Desc),dd10(m2Desc); + std::map<int,int> notUsedMap; + Intersect1DMeshes(m1Desc,m2Desc,eps,intersectEdge1,colinear2,subDiv2,addCoo,notUsedMap); + m1Desc->incrRef(); desc1->incrRef(); descIndx1->incrRef(); revDesc1->incrRef(); revDescIndx1->incrRef(); + m2Desc->incrRef(); desc2->incrRef(); descIndx2->incrRef(); revDesc2->incrRef(); revDescIndx2->incrRef(); +} + +/*! + * This method performs the 2nd step of Partition of 2D mesh. + * This method has 4 inputs : + * - a mesh 'm1' with meshDim==1 and a SpaceDim==2 + * - a mesh 'm2' with meshDim==1 and a SpaceDim==2 + * - subDiv of size 'm2->getNumberOfCells()' that lists for each seg cell in 'm' the splitting node ids randomly sorted. + * The aim of this method is to sort the splitting nodes, if any, and to put them in 'intersectEdge' output parameter based on edges of mesh 'm2' + * Nodes end up lying consecutively on a cutted edge. + * \param m1 is expected to be a mesh of meshDimension equal to 1 and spaceDim equal to 2. No check of that is performed by this method. + * (Only present for its coords in case of 'subDiv' shares some nodes of 'm1') + * \param m2 is expected to be a mesh of meshDimension equal to 1 and spaceDim equal to 2. No check of that is performed by this method. + * \param addCoo input parameter with additional nodes linked to intersection of the 2 meshes. + * \param[out] intersectEdge the same content as subDiv, but correclty oriented. + */ +void MEDCouplingUMesh::BuildIntersectEdges(const MEDCouplingUMesh *m1, const MEDCouplingUMesh *m2, + const std::vector<double>& addCoo, + const std::vector< std::vector<int> >& subDiv, std::vector< std::vector<int> >& intersectEdge) +{ + int offset1=m1->getNumberOfNodes(); + int ncell=m2->getNumberOfCells(); + const int *c=m2->getNodalConnectivity()->getConstPointer(); + const int *cI=m2->getNodalConnectivityIndex()->getConstPointer(); + const double *coo=m2->getCoords()->getConstPointer(); + const double *cooBis=m1->getCoords()->getConstPointer(); + int offset2=offset1+m2->getNumberOfNodes(); + intersectEdge.resize(ncell); + for(int i=0;i<ncell;i++,cI++) + { + const std::vector<int>& divs=subDiv[i]; + int nnode=cI[1]-cI[0]-1; + std::map<int, std::pair<INTERP_KERNEL::Node *,bool> > mapp2; + std::map<INTERP_KERNEL::Node *, int> mapp22; + for(int j=0;j<nnode;j++) + { + INTERP_KERNEL::Node *nn=new INTERP_KERNEL::Node(coo[2*c[(*cI)+j+1]],coo[2*c[(*cI)+j+1]+1]); + int nnid=c[(*cI)+j+1]; + mapp2[nnid]=std::pair<INTERP_KERNEL::Node *,bool>(nn,true); + mapp22[nn]=nnid+offset1; + } + INTERP_KERNEL::Edge *e=MEDCouplingUMeshBuildQPFromEdge((INTERP_KERNEL::NormalizedCellType)c[*cI],mapp2,c+(*cI)+1); + for(std::map<int, std::pair<INTERP_KERNEL::Node *,bool> >::const_iterator it=mapp2.begin();it!=mapp2.end();it++) + ((*it).second.first)->decrRef(); + std::vector<INTERP_KERNEL::Node *> addNodes(divs.size()); + std::map<INTERP_KERNEL::Node *,int> mapp3; + for(std::size_t j=0;j<divs.size();j++) + { + int id=divs[j]; + INTERP_KERNEL::Node *tmp=0; + if(id<offset1) + tmp=new INTERP_KERNEL::Node(cooBis[2*id],cooBis[2*id+1]); + else if(id<offset2) + tmp=new INTERP_KERNEL::Node(coo[2*(id-offset1)],coo[2*(id-offset1)+1]);//if it happens, bad news mesh 'm2' is non conform. + else + tmp=new INTERP_KERNEL::Node(addCoo[2*(id-offset2)],addCoo[2*(id-offset2)+1]); + addNodes[j]=tmp; + mapp3[tmp]=id; + } + e->sortIdsAbs(addNodes,mapp22,mapp3,intersectEdge[i]); + for(std::vector<INTERP_KERNEL::Node *>::const_iterator it=addNodes.begin();it!=addNodes.end();it++) + (*it)->decrRef(); + e->decrRef(); + } +} + +/*! + * This method is part of the Slice3D algorithm. It is the first step of assembly process, ones coordinates have been computed (by MEDCouplingUMesh::split3DCurveWithPlane method). + * This method allows to compute given the status of 3D curve cells and the descending connectivity 3DSurf->3DCurve to deduce the intersection of each 3D surf cells + * with a plane. The result will be put in 'cut3DSuf' out parameter. + * \param [in] cut3DCurve input paramter that gives for each 3DCurve cell if it owns fully to the plane or partially. + * \param [out] nodesOnPlane, returns all the nodes that are on the plane. + * \param [in] nodal3DSurf is the nodal connectivity of 3D surf mesh. + * \param [in] nodalIndx3DSurf is the nodal connectivity index of 3D surf mesh. + * \param [in] nodal3DCurve is the nodal connectivity of 3D curve mesh. + * \param [in] nodal3DIndxCurve is the nodal connectivity index of 3D curve mesh. + * \param [in] desc is the descending connectivity 3DSurf->3DCurve + * \param [in] descIndx is the descending connectivity index 3DSurf->3DCurve + * \param [out] cut3DSuf input/output param. + */ +void MEDCouplingUMesh::AssemblyForSplitFrom3DCurve(const std::vector<int>& cut3DCurve, std::vector<int>& nodesOnPlane, const int *nodal3DSurf, const int *nodalIndx3DSurf, + const int *nodal3DCurve, const int *nodalIndx3DCurve, + const int *desc, const int *descIndx, + std::vector< std::pair<int,int> >& cut3DSurf) +{ + std::set<int> nodesOnP(nodesOnPlane.begin(),nodesOnPlane.end()); + int nbOf3DSurfCell=(int)cut3DSurf.size(); + for(int i=0;i<nbOf3DSurfCell;i++) + { + std::vector<int> res; + int offset=descIndx[i]; + int nbOfSeg=descIndx[i+1]-offset; + for(int j=0;j<nbOfSeg;j++) + { + int edgeId=desc[offset+j]; + int status=cut3DCurve[edgeId]; + if(status!=-2) + { + if(status>-1) + res.push_back(status); + else + { + res.push_back(nodal3DCurve[nodalIndx3DCurve[edgeId]+1]); + res.push_back(nodal3DCurve[nodalIndx3DCurve[edgeId]+2]); + } + } + } + switch(res.size()) + { + case 2: + { + cut3DSurf[i].first=res[0]; cut3DSurf[i].second=res[1]; + break; + } + case 1: + case 0: + { + std::set<int> s1(nodal3DSurf+nodalIndx3DSurf[i]+1,nodal3DSurf+nodalIndx3DSurf[i+1]); + std::set_intersection(nodesOnP.begin(),nodesOnP.end(),s1.begin(),s1.end(),std::back_insert_iterator< std::vector<int> >(res)); + if(res.size()==2) + { + cut3DSurf[i].first=res[0]; cut3DSurf[i].second=res[1]; + } + else + { + cut3DSurf[i].first=-1; cut3DSurf[i].second=-1; + } + break; + } + default: + {// case when plane is on a multi colinear edge of a polyhedron + if((int)res.size()==2*nbOfSeg) + { + cut3DSurf[i].first=-2; cut3DSurf[i].second=i; + } + else + throw INTERP_KERNEL::Exception("MEDCouplingUMesh::AssemblyPointsFrom3DCurve : unexpected situation !"); + } + } + } +} + +/*! + * \a this is expected to be a mesh with spaceDim==3 and meshDim==3. If not an exception will be thrown. + * This method is part of the Slice3D algorithm. It is the second step of assembly process, ones coordinates have been computed (by MEDCouplingUMesh::split3DCurveWithPlane method). + * This method allows to compute given the result of 3D surf cells with plane and the descending connectivity 3D->3DSurf to deduce the intersection of each 3D cells + * with a plane. The result will be put in 'nodalRes' 'nodalResIndx' and 'cellIds' out parameters. + * \param cut3DSurf input paramter that gives for each 3DSurf its intersection with plane (result of MEDCouplingUMesh::AssemblyForSplitFrom3DCurve). + * \param desc is the descending connectivity 3D->3DSurf + * \param descIndx is the descending connectivity index 3D->3DSurf + */ +void MEDCouplingUMesh::assemblyForSplitFrom3DSurf(const std::vector< std::pair<int,int> >& cut3DSurf, + const int *desc, const int *descIndx, + DataArrayInt *nodalRes, DataArrayInt *nodalResIndx, DataArrayInt *cellIds) const +{ + checkFullyDefined(); + if(getMeshDimension()!=3 || getSpaceDimension()!=3) + throw INTERP_KERNEL::Exception("MEDCouplingUMesh::assemblyForSplitFrom3DSurf works on umeshes with meshdim equal to 3 and spaceDim equal to 3 too!"); + const int *nodal3D=_nodal_connec->getConstPointer(); + const int *nodalIndx3D=_nodal_connec_index->getConstPointer(); + int nbOfCells=getNumberOfCells(); + for(int i=0;i<nbOfCells;i++) + { + std::map<int, std::set<int> > m; + int offset=descIndx[i]; + int nbOfFaces=descIndx[i+1]-offset; + int start=-1; + int end=-1; + for(int j=0;j<nbOfFaces;j++) + { + const std::pair<int,int>& p=cut3DSurf[desc[offset+j]]; + if(p.first!=-1 && p.second!=-1) + { + if(p.first!=-2) + { + start=p.first; end=p.second; + m[p.first].insert(p.second); + m[p.second].insert(p.first); + } + else + { + const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel((INTERP_KERNEL::NormalizedCellType)nodal3D[nodalIndx3D[i]]); + int sz=nodalIndx3D[i+1]-nodalIndx3D[i]-1; + INTERP_KERNEL::AutoPtr<int> tmp=new int[sz]; + INTERP_KERNEL::NormalizedCellType cmsId; + unsigned nbOfNodesSon=cm.fillSonCellNodalConnectivity2(j,nodal3D+nodalIndx3D[i]+1,sz,tmp,cmsId); + start=tmp[0]; end=tmp[nbOfNodesSon-1]; + for(unsigned k=0;k<nbOfNodesSon;k++) + { + m[tmp[k]].insert(tmp[(k+1)%nbOfNodesSon]); + m[tmp[(k+1)%nbOfNodesSon]].insert(tmp[k]); + } + } + } + } + if(m.empty()) + continue; + std::vector<int> conn(1,(int)INTERP_KERNEL::NORM_POLYGON); + int prev=end; + while(end!=start) + { + std::map<int, std::set<int> >::const_iterator it=m.find(start); + const std::set<int>& s=(*it).second; + std::set<int> s2; s2.insert(prev); + std::set<int> s3; + std::set_difference(s.begin(),s.end(),s2.begin(),s2.end(),inserter(s3,s3.begin())); + if(s3.size()==1) + { + int val=*s3.begin(); + conn.push_back(start); + prev=start; + start=val; + } + else + start=end; + } + conn.push_back(end); + if(conn.size()>3) + { + nodalRes->insertAtTheEnd(conn.begin(),conn.end()); + nodalResIndx->pushBackSilent(nodalRes->getNumberOfTuples()); + cellIds->pushBackSilent(i); + } + } +} + +/*! + * This method compute the convex hull of a single 2D cell. This method tries to conserve at maximum the given input connectivity. In particular, if the orientation of cell is not clockwise + * as in MED format norm. If definitely the result of Jarvis algorithm is not matchable with the input connectivity, the result will be copied into \b nodalConnecOut parameter and + * the geometric cell type set to INTERP_KERNEL::NORM_POLYGON. + * This method excepts that \b coords parameter is expected to be in dimension 2. [ \b nodalConnBg , \b nodalConnEnd ) is the nodal connectivity of the input + * cell (geometric cell type included at the position 0). If the meshdimension of the input cell is not equal to 2 an INTERP_KERNEL::Exception will be thrown. + * + * \return false if the input connectivity represents already the convex hull, true if the input cell needs to be reordered. + */ +bool MEDCouplingUMesh::BuildConvexEnvelopOf2DCellJarvis(const double *coords, const int *nodalConnBg, const int *nodalConnEnd, DataArrayInt *nodalConnecOut) +{ + std::size_t sz=std::distance(nodalConnBg,nodalConnEnd); + if(sz>=4) + { + const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel((INTERP_KERNEL::NormalizedCellType)*nodalConnBg); + if(cm.getDimension()==2) + { + const int *node=nodalConnBg+1; + int startNode=*node++; + double refX=coords[2*startNode]; + for(;node!=nodalConnEnd;node++) + { + if(coords[2*(*node)]<refX) + { + startNode=*node; + refX=coords[2*startNode]; + } + } + std::vector<int> tmpOut; tmpOut.reserve(sz); tmpOut.push_back(startNode); + refX=1e300; + double tmp1; + double tmp2[2]; + double angle0=-M_PI/2; + // + int nextNode=-1; + int prevNode=-1; + double resRef; + double angleNext=0.; + while(nextNode!=startNode) + { + nextNode=-1; + resRef=1e300; + for(node=nodalConnBg+1;node!=nodalConnEnd;node++) + { + if(*node!=tmpOut.back() && *node!=prevNode) + { + tmp2[0]=coords[2*(*node)]-coords[2*tmpOut.back()]; tmp2[1]=coords[2*(*node)+1]-coords[2*tmpOut.back()+1]; + double angleM=INTERP_KERNEL::EdgeArcCircle::GetAbsoluteAngle(tmp2,tmp1); + double res; + if(angleM<=angle0) + res=angle0-angleM; + else + res=angle0-angleM+2.*M_PI; + if(res<resRef) + { + nextNode=*node; + resRef=res; + angleNext=angleM; + } + } + } + if(nextNode!=startNode) + { + angle0=angleNext-M_PI; + if(angle0<-M_PI) + angle0+=2*M_PI; + prevNode=tmpOut.back(); + tmpOut.push_back(nextNode); + } + } + std::vector<int> tmp3(2*(sz-1)); + std::vector<int>::iterator it=std::copy(nodalConnBg+1,nodalConnEnd,tmp3.begin()); + std::copy(nodalConnBg+1,nodalConnEnd,it); + if(std::search(tmp3.begin(),tmp3.end(),tmpOut.begin(),tmpOut.end())!=tmp3.end()) + { + nodalConnecOut->insertAtTheEnd(nodalConnBg,nodalConnEnd); + return false; + } + if(std::search(tmp3.rbegin(),tmp3.rend(),tmpOut.begin(),tmpOut.end())!=tmp3.rend()) + { + nodalConnecOut->insertAtTheEnd(nodalConnBg,nodalConnEnd); + return false; + } + else + { + nodalConnecOut->pushBackSilent((int)INTERP_KERNEL::NORM_POLYGON); + nodalConnecOut->insertAtTheEnd(tmpOut.begin(),tmpOut.end()); + return true; + } + } + else + throw INTERP_KERNEL::Exception("MEDCouplingUMesh::BuildConvexEnvelopOf2DCellJarvis : invalid 2D cell connectivity !"); + } + else + throw INTERP_KERNEL::Exception("MEDCouplingUMesh::BuildConvexEnvelopOf2DCellJarvis : invalid 2D cell connectivity !"); +} + +/*! + * This method works on an input pair (\b arr, \b arrIndx) where \b arr indexes is in \b arrIndx. + * This method will not impact the size of inout parameter \b arrIndx but the size of \b arr will be modified in case of suppression. + * + * \param [in] idsToRemoveBg begin of set of ids to remove in \b arr (included) + * \param [in] idsToRemoveEnd end of set of ids to remove in \b arr (excluded) + * \param [in,out] arr array in which the remove operation will be done. + * \param [in,out] arrIndx array in the remove operation will modify + * \param [in] offsetForRemoval (by default 0) offset so that for each i in [0,arrIndx->getNumberOfTuples()-1) removal process will be performed in the following range [arr+arrIndx[i]+offsetForRemoval,arr+arr[i+1]) + * \return true if \b arr and \b arrIndx have been modified, false if not. + */ +bool MEDCouplingUMesh::RemoveIdsFromIndexedArrays(const int *idsToRemoveBg, const int *idsToRemoveEnd, DataArrayInt *arr, DataArrayInt *arrIndx, int offsetForRemoval) +{ + if(!arrIndx || !arr) + throw INTERP_KERNEL::Exception("MEDCouplingUMesh::RemoveIdsFromIndexedArrays : some input arrays are empty !"); + if(offsetForRemoval<0) + throw INTERP_KERNEL::Exception("MEDCouplingUMesh::RemoveIdsFromIndexedArrays : offsetForRemoval should be >=0 !"); + std::set<int> s(idsToRemoveBg,idsToRemoveEnd); + int nbOfGrps=arrIndx->getNumberOfTuples()-1; + int *arrIPtr=arrIndx->getPointer(); + *arrIPtr++=0; + int previousArrI=0; + const int *arrPtr=arr->getConstPointer(); + std::vector<int> arrOut;//no utility to switch to DataArrayInt because copy always needed + for(int i=0;i<nbOfGrps;i++,arrIPtr++) + { + if(*arrIPtr-previousArrI>offsetForRemoval) + { + for(const int *work=arrPtr+previousArrI+offsetForRemoval;work!=arrPtr+*arrIPtr;work++) + { + if(s.find(*work)==s.end()) + arrOut.push_back(*work); + } + } + previousArrI=*arrIPtr; + *arrIPtr=(int)arrOut.size(); + } + if(arr->getNumberOfTuples()==(int)arrOut.size()) + return false; + arr->alloc((int)arrOut.size(),1); + std::copy(arrOut.begin(),arrOut.end(),arr->getPointer()); + return true; +} + +/*! + * This method works on a pair input (\b arrIn, \b arrIndxIn) where \b arrIn indexes is in \b arrIndxIn + * (\ref numbering-indirect). + * This method returns the result of the extraction ( specified by a set of ids in [\b idsOfSelectBg , \b idsOfSelectEnd ) ). + * The selection of extraction is done standardly in new2old format. + * This method returns indexed arrays (\ref numbering-indirect) using 2 arrays (arrOut,arrIndexOut). + * + * \param [in] idsOfSelectBg begin of set of ids of the input extraction (included) + * \param [in] idsOfSelectEnd end of set of ids of the input extraction (excluded) + * \param [in] arrIn arr origin array from which the extraction will be done. + * \param [in] arrIndxIn is the input index array allowing to walk into \b arrIn + * \param [out] arrOut the resulting array + * \param [out] arrIndexOut the index array of the resulting array \b arrOut + * \sa MEDCouplingUMesh::ExtractFromIndexedArrays2 + */ +void MEDCouplingUMesh::ExtractFromIndexedArrays(const int *idsOfSelectBg, const int *idsOfSelectEnd, const DataArrayInt *arrIn, const DataArrayInt *arrIndxIn, + DataArrayInt* &arrOut, DataArrayInt* &arrIndexOut) +{ + if(!arrIn || !arrIndxIn) + throw INTERP_KERNEL::Exception("MEDCouplingUMesh::ExtractFromIndexedArrays : input pointer is NULL !"); + arrIn->checkAllocated(); arrIndxIn->checkAllocated(); + if(arrIn->getNumberOfComponents()!=1 || arrIndxIn->getNumberOfComponents()!=1) + throw INTERP_KERNEL::Exception("MEDCouplingUMesh::ExtractFromIndexedArrays : input arrays must have exactly one component !"); + std::size_t sz=std::distance(idsOfSelectBg,idsOfSelectEnd); + const int *arrInPtr=arrIn->getConstPointer(); + const int *arrIndxPtr=arrIndxIn->getConstPointer(); + int nbOfGrps=arrIndxIn->getNumberOfTuples()-1; + if(nbOfGrps<0) + throw INTERP_KERNEL::Exception("MEDCouplingUMesh::ExtractFromIndexedArrays : The format of \"arrIndxIn\" is invalid ! Its nb of tuples should be >=1 !"); + int maxSizeOfArr=arrIn->getNumberOfTuples(); + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> arro=DataArrayInt::New(); + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> arrIo=DataArrayInt::New(); + arrIo->alloc((int)(sz+1),1); + const int *idsIt=idsOfSelectBg; + int *work=arrIo->getPointer(); + *work++=0; + int lgth=0; + for(std::size_t i=0;i<sz;i++,work++,idsIt++) + { + if(*idsIt>=0 && *idsIt<nbOfGrps) + lgth+=arrIndxPtr[*idsIt+1]-arrIndxPtr[*idsIt]; + else + { + std::ostringstream oss; oss << "MEDCouplingUMesh::ExtractFromIndexedArrays : id located on pos #" << i << " value is " << *idsIt << " ! Must be in [0," << nbOfGrps << ") !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + if(lgth>=work[-1]) + *work=lgth; + else + { + std::ostringstream oss; oss << "MEDCouplingUMesh::ExtractFromIndexedArrays : id located on pos #" << i << " value is " << *idsIt << " and at this pos arrIndxIn[" << *idsIt; + oss << "+1]-arrIndxIn[" << *idsIt << "] < 0 ! The input index array is bugged !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + } + arro->alloc(lgth,1); + work=arro->getPointer(); + idsIt=idsOfSelectBg; + for(std::size_t i=0;i<sz;i++,idsIt++) + { + if(arrIndxPtr[*idsIt]>=0 && arrIndxPtr[*idsIt+1]<=maxSizeOfArr) + work=std::copy(arrInPtr+arrIndxPtr[*idsIt],arrInPtr+arrIndxPtr[*idsIt+1],work); + else + { + std::ostringstream oss; oss << "MEDCouplingUMesh::ExtractFromIndexedArrays : id located on pos #" << i << " value is " << *idsIt << " arrIndx[" << *idsIt << "] must be >= 0 and arrIndx["; + oss << *idsIt << "+1] <= " << maxSizeOfArr << " (the size of arrIn)!"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + } + arrOut=arro.retn(); + arrIndexOut=arrIo.retn(); +} + +/*! + * This method works on a pair input (\b arrIn, \b arrIndxIn) where \b arrIn indexes is in \b arrIndxIn + * (\ref numbering-indirect). + * This method returns the result of the extraction ( specified by a set of ids with a slice given by \a idsOfSelectStart, \a idsOfSelectStop and \a idsOfSelectStep ). + * The selection of extraction is done standardly in new2old format. + * This method returns indexed arrays (\ref numbering-indirect) using 2 arrays (arrOut,arrIndexOut). + * + * \param [in] idsOfSelectStart begin of set of ids of the input extraction (included) + * \param [in] idsOfSelectStop end of set of ids of the input extraction (excluded) + * \param [in] idsOfSelectStep + * \param [in] arrIn arr origin array from which the extraction will be done. + * \param [in] arrIndxIn is the input index array allowing to walk into \b arrIn + * \param [out] arrOut the resulting array + * \param [out] arrIndexOut the index array of the resulting array \b arrOut + * \sa MEDCouplingUMesh::ExtractFromIndexedArrays + */ +void MEDCouplingUMesh::ExtractFromIndexedArrays2(int idsOfSelectStart, int idsOfSelectStop, int idsOfSelectStep, const DataArrayInt *arrIn, const DataArrayInt *arrIndxIn, + DataArrayInt* &arrOut, DataArrayInt* &arrIndexOut) +{ + if(!arrIn || !arrIndxIn) + throw INTERP_KERNEL::Exception("MEDCouplingUMesh::ExtractFromIndexedArrays2 : input pointer is NULL !"); + arrIn->checkAllocated(); arrIndxIn->checkAllocated(); + if(arrIn->getNumberOfComponents()!=1 || arrIndxIn->getNumberOfComponents()!=1) + throw INTERP_KERNEL::Exception("MEDCouplingUMesh::ExtractFromIndexedArrays2 : input arrays must have exactly one component !"); + int sz=DataArrayInt::GetNumberOfItemGivenBESRelative(idsOfSelectStart,idsOfSelectStop,idsOfSelectStep,"MEDCouplingUMesh::ExtractFromIndexedArrays2 : Input slice "); + const int *arrInPtr=arrIn->getConstPointer(); + const int *arrIndxPtr=arrIndxIn->getConstPointer(); + int nbOfGrps=arrIndxIn->getNumberOfTuples()-1; + if(nbOfGrps<0) + throw INTERP_KERNEL::Exception("MEDCouplingUMesh::ExtractFromIndexedArrays2 : The format of \"arrIndxIn\" is invalid ! Its nb of tuples should be >=1 !"); + int maxSizeOfArr=arrIn->getNumberOfTuples(); + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> arro=DataArrayInt::New(); + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> arrIo=DataArrayInt::New(); + arrIo->alloc((int)(sz+1),1); + int idsIt=idsOfSelectStart; + int *work=arrIo->getPointer(); + *work++=0; + int lgth=0; + for(int i=0;i<sz;i++,work++,idsIt+=idsOfSelectStep) + { + if(idsIt>=0 && idsIt<nbOfGrps) + lgth+=arrIndxPtr[idsIt+1]-arrIndxPtr[idsIt]; + else + { + std::ostringstream oss; oss << "MEDCouplingUMesh::ExtractFromIndexedArrays2 : id located on pos #" << i << " value is " << idsIt << " ! Must be in [0," << nbOfGrps << ") !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + if(lgth>=work[-1]) + *work=lgth; + else + { + std::ostringstream oss; oss << "MEDCouplingUMesh::ExtractFromIndexedArrays2 : id located on pos #" << i << " value is " << idsIt << " and at this pos arrIndxIn[" << idsIt; + oss << "+1]-arrIndxIn[" << idsIt << "] < 0 ! The input index array is bugged !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + } + arro->alloc(lgth,1); + work=arro->getPointer(); + idsIt=idsOfSelectStart; + for(int i=0;i<sz;i++,idsIt+=idsOfSelectStep) + { + if(arrIndxPtr[idsIt]>=0 && arrIndxPtr[idsIt+1]<=maxSizeOfArr) + work=std::copy(arrInPtr+arrIndxPtr[idsIt],arrInPtr+arrIndxPtr[idsIt+1],work); + else + { + std::ostringstream oss; oss << "MEDCouplingUMesh::ExtractFromIndexedArrays2 : id located on pos #" << i << " value is " << idsIt << " arrIndx[" << idsIt << "] must be >= 0 and arrIndx["; + oss << idsIt << "+1] <= " << maxSizeOfArr << " (the size of arrIn)!"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + } + arrOut=arro.retn(); + arrIndexOut=arrIo.retn(); +} + +/*! + * This method works on an input pair (\b arrIn, \b arrIndxIn) where \b arrIn indexes is in \b arrIndxIn. + * This method builds an output pair (\b arrOut,\b arrIndexOut) that is a copy from \b arrIn for all cell ids \b not \b in [ \b idsOfSelectBg , \b idsOfSelectEnd ) and for + * cellIds \b in [ \b idsOfSelectBg , \b idsOfSelectEnd ) a copy coming from the corresponding values in input pair (\b srcArr, \b srcArrIndex). + * This method is an generalization of MEDCouplingUMesh::SetPartOfIndexedArraysSameIdx that performs the same thing but by without building explicitely a result output arrays. + * + * \param [in] idsOfSelectBg begin of set of ids of the input extraction (included) + * \param [in] idsOfSelectEnd end of set of ids of the input extraction (excluded) + * \param [in] arrIn arr origin array from which the extraction will be done. + * \param [in] arrIndxIn is the input index array allowing to walk into \b arrIn + * \param [in] srcArr input array that will be used as source of copy for ids in [ \b idsOfSelectBg, \b idsOfSelectEnd ) + * \param [in] srcArrIndex index array of \b srcArr + * \param [out] arrOut the resulting array + * \param [out] arrIndexOut the index array of the resulting array \b arrOut + * + * \sa MEDCouplingUMesh::SetPartOfIndexedArraysSameIdx + */ +void MEDCouplingUMesh::SetPartOfIndexedArrays(const int *idsOfSelectBg, const int *idsOfSelectEnd, const DataArrayInt *arrIn, const DataArrayInt *arrIndxIn, + const DataArrayInt *srcArr, const DataArrayInt *srcArrIndex, + DataArrayInt* &arrOut, DataArrayInt* &arrIndexOut) +{ + if(arrIn==0 || arrIndxIn==0 || srcArr==0 || srcArrIndex==0) + throw INTERP_KERNEL::Exception("MEDCouplingUMesh::SetPartOfIndexedArrays : presence of null pointer in input parameter !"); + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> arro=DataArrayInt::New(); + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> arrIo=DataArrayInt::New(); + int nbOfTuples=arrIndxIn->getNumberOfTuples()-1; + std::vector<bool> v(nbOfTuples,true); + int offset=0; + const int *arrIndxInPtr=arrIndxIn->getConstPointer(); + const int *srcArrIndexPtr=srcArrIndex->getConstPointer(); + for(const int *it=idsOfSelectBg;it!=idsOfSelectEnd;it++,srcArrIndexPtr++) + { + if(*it>=0 && *it<nbOfTuples) + { + v[*it]=false; + offset+=(srcArrIndexPtr[1]-srcArrIndexPtr[0])-(arrIndxInPtr[*it+1]-arrIndxInPtr[*it]); + } + else + { + std::ostringstream oss; oss << "MEDCouplingUMesh::SetPartOfIndexedArrays : On pos #" << std::distance(idsOfSelectBg,it) << " value is " << *it << " not in [0," << nbOfTuples << ") !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + } + srcArrIndexPtr=srcArrIndex->getConstPointer(); + arrIo->alloc(nbOfTuples+1,1); + arro->alloc(arrIn->getNumberOfTuples()+offset,1); + const int *arrInPtr=arrIn->getConstPointer(); + const int *srcArrPtr=srcArr->getConstPointer(); + int *arrIoPtr=arrIo->getPointer(); *arrIoPtr++=0; + int *arroPtr=arro->getPointer(); + for(int ii=0;ii<nbOfTuples;ii++,arrIoPtr++) + { + if(v[ii]) + { + arroPtr=std::copy(arrInPtr+arrIndxInPtr[ii],arrInPtr+arrIndxInPtr[ii+1],arroPtr); + *arrIoPtr=arrIoPtr[-1]+(arrIndxInPtr[ii+1]-arrIndxInPtr[ii]); + } + else + { + std::size_t pos=std::distance(idsOfSelectBg,std::find(idsOfSelectBg,idsOfSelectEnd,ii)); + arroPtr=std::copy(srcArrPtr+srcArrIndexPtr[pos],srcArrPtr+srcArrIndexPtr[pos+1],arroPtr); + *arrIoPtr=arrIoPtr[-1]+(srcArrIndexPtr[pos+1]-srcArrIndexPtr[pos]); + } + } + arrOut=arro.retn(); + arrIndexOut=arrIo.retn(); +} + +/*! + * This method works on an input pair (\b arrIn, \b arrIndxIn) where \b arrIn indexes is in \b arrIndxIn. + * This method is an specialization of MEDCouplingUMesh::SetPartOfIndexedArrays in the case of assignement do not modify the index in \b arrIndxIn. + * + * \param [in] idsOfSelectBg begin of set of ids of the input extraction (included) + * \param [in] idsOfSelectEnd end of set of ids of the input extraction (excluded) + * \param [in,out] arrInOut arr origin array from which the extraction will be done. + * \param [in] arrIndxIn is the input index array allowing to walk into \b arrIn + * \param [in] srcArr input array that will be used as source of copy for ids in [ \b idsOfSelectBg , \b idsOfSelectEnd ) + * \param [in] srcArrIndex index array of \b srcArr + * + * \sa MEDCouplingUMesh::SetPartOfIndexedArrays + */ +void MEDCouplingUMesh::SetPartOfIndexedArraysSameIdx(const int *idsOfSelectBg, const int *idsOfSelectEnd, DataArrayInt *arrInOut, const DataArrayInt *arrIndxIn, + const DataArrayInt *srcArr, const DataArrayInt *srcArrIndex) +{ + if(arrInOut==0 || arrIndxIn==0 || srcArr==0 || srcArrIndex==0) + throw INTERP_KERNEL::Exception("MEDCouplingUMesh::SetPartOfIndexedArraysSameIdx : presence of null pointer in input parameter !"); + int nbOfTuples=arrIndxIn->getNumberOfTuples()-1; + const int *arrIndxInPtr=arrIndxIn->getConstPointer(); + const int *srcArrIndexPtr=srcArrIndex->getConstPointer(); + int *arrInOutPtr=arrInOut->getPointer(); + const int *srcArrPtr=srcArr->getConstPointer(); + for(const int *it=idsOfSelectBg;it!=idsOfSelectEnd;it++,srcArrIndexPtr++) + { + if(*it>=0 && *it<nbOfTuples) + { + if(srcArrIndexPtr[1]-srcArrIndexPtr[0]==arrIndxInPtr[*it+1]-arrIndxInPtr[*it]) + std::copy(srcArrPtr+srcArrIndexPtr[0],srcArrPtr+srcArrIndexPtr[1],arrInOutPtr+arrIndxInPtr[*it]); + else + { + std::ostringstream oss; oss << "MEDCouplingUMesh::SetPartOfIndexedArraysSameIdx : On pos #" << std::distance(idsOfSelectBg,it) << " id (idsOfSelectBg[" << std::distance(idsOfSelectBg,it)<< "]) is " << *it << " arrIndxIn[id+1]-arrIndxIn[id]!=srcArrIndex[pos+1]-srcArrIndex[pos] !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + } + else + { + std::ostringstream oss; oss << "MEDCouplingUMesh::SetPartOfIndexedArraysSameIdx : On pos #" << std::distance(idsOfSelectBg,it) << " value is " << *it << " not in [0," << nbOfTuples << ") !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + } +} + +/*! + * This method works on a pair input (\b arrIn, \b arrIndxIn) where \b arr indexes is in \b arrIndxIn. + * This method expects that these two input arrays come from the output of MEDCouplingUMesh::computeNeighborsOfCells method. + * This method start from id 0 that will be contained in output DataArrayInt. It searches then all neighbors of id0 looking at arrIn[arrIndxIn[0]:arrIndxIn[0+1]]. + * Then it is repeated recursively until either all ids are fetched or no more ids are reachable step by step. + * A negative value in \b arrIn means that it is ignored. + * This method is useful to see if a mesh is contiguous regarding its connectivity. If it is not the case the size of returned array is different from arrIndxIn->getNumberOfTuples()-1. + * + * \param [in] arrIn arr origin array from which the extraction will be done. + * \param [in] arrIndxIn is the input index array allowing to walk into \b arrIn + * \return a newly allocated DataArray that stores all ids fetched by the gradually spread process. + * \sa MEDCouplingUMesh::ComputeSpreadZoneGraduallyFromSeed, MEDCouplingUMesh::partitionBySpreadZone + */ +DataArrayInt *MEDCouplingUMesh::ComputeSpreadZoneGradually(const DataArrayInt *arrIn, const DataArrayInt *arrIndxIn) +{ + int seed=0,nbOfDepthPeelingPerformed=0; + return ComputeSpreadZoneGraduallyFromSeed(&seed,&seed+1,arrIn,arrIndxIn,-1,nbOfDepthPeelingPerformed); +} + +/*! + * This method works on a pair input (\b arrIn, \b arrIndxIn) where \b arr indexes is in \b arrIndxIn. + * This method expects that these two input arrays come from the output of MEDCouplingUMesh::computeNeighborsOfCells method. + * This method start from id 0 that will be contained in output DataArrayInt. It searches then all neighbors of id0 regarding arrIn[arrIndxIn[0]:arrIndxIn[0+1]]. + * Then it is repeated recursively until either all ids are fetched or no more ids are reachable step by step. + * A negative value in \b arrIn means that it is ignored. + * This method is useful to see if a mesh is contiguous regarding its connectivity. If it is not the case the size of returned array is different from arrIndxIn->getNumberOfTuples()-1. + * \param [in] seedBg the begin pointer (included) of an array containing the seed of the search zone + * \param [in] seedEnd the end pointer (not included) of an array containing the seed of the search zone + * \param [in] arrIn arr origin array from which the extraction will be done. + * \param [in] arrIndxIn is the input index array allowing to walk into \b arrIn + * \param [in] nbOfDepthPeeling the max number of peels requested in search. By default -1, that is to say, no limit. + * \param [out] nbOfDepthPeelingPerformed the number of peels effectively performed. May be different from \a nbOfDepthPeeling + * \return a newly allocated DataArray that stores all ids fetched by the gradually spread process. + * \sa MEDCouplingUMesh::partitionBySpreadZone + */ +DataArrayInt *MEDCouplingUMesh::ComputeSpreadZoneGraduallyFromSeed(const int *seedBg, const int *seedEnd, const DataArrayInt *arrIn, const DataArrayInt *arrIndxIn, int nbOfDepthPeeling, int& nbOfDepthPeelingPerformed) +{ + nbOfDepthPeelingPerformed=0; + if(!arrIndxIn) + throw INTERP_KERNEL::Exception("MEDCouplingUMesh::ComputeSpreadZoneGraduallyFromSeed : arrIndxIn input pointer is NULL !"); + int nbOfTuples=arrIndxIn->getNumberOfTuples()-1; + if(nbOfTuples<=0) + { + DataArrayInt *ret=DataArrayInt::New(); ret->alloc(0,1); + return ret; + } + // + std::vector<bool> fetched(nbOfTuples,false); + return ComputeSpreadZoneGraduallyFromSeedAlg(fetched,seedBg,seedEnd,arrIn,arrIndxIn,nbOfDepthPeeling,nbOfDepthPeelingPerformed); +} + +DataArrayInt *MEDCouplingUMesh::ComputeSpreadZoneGraduallyFromSeedAlg(std::vector<bool>& fetched, const int *seedBg, const int *seedEnd, const DataArrayInt *arrIn, const DataArrayInt *arrIndxIn, int nbOfDepthPeeling, int& nbOfDepthPeelingPerformed) +{ + nbOfDepthPeelingPerformed=0; + if(!seedBg || !seedEnd || !arrIn || !arrIndxIn) + throw INTERP_KERNEL::Exception("MEDCouplingUMesh::ComputeSpreadZoneGraduallyFromSeedAlg : some input pointer is NULL !"); + int nbOfTuples=arrIndxIn->getNumberOfTuples()-1; + std::vector<bool> fetched2(nbOfTuples,false); + int i=0; + for(const int *seedElt=seedBg;seedElt!=seedEnd;seedElt++,i++) + { + if(*seedElt>=0 && *seedElt<nbOfTuples) + { fetched[*seedElt]=true; fetched2[*seedElt]=true; } + else + { std::ostringstream oss; oss << "MEDCouplingUMesh::ComputeSpreadZoneGraduallyFromSeedAlg : At pos #" << i << " of seeds value is " << *seedElt << "! Should be in [0," << nbOfTuples << ") !"; throw INTERP_KERNEL::Exception(oss.str().c_str()); } + } + const int *arrInPtr=arrIn->getConstPointer(); + const int *arrIndxPtr=arrIndxIn->getConstPointer(); + int targetNbOfDepthPeeling=nbOfDepthPeeling!=-1?nbOfDepthPeeling:std::numeric_limits<int>::max(); + std::vector<int> idsToFetch1(seedBg,seedEnd); + std::vector<int> idsToFetch2; + std::vector<int> *idsToFetch=&idsToFetch1; + std::vector<int> *idsToFetchOther=&idsToFetch2; + while(!idsToFetch->empty() && nbOfDepthPeelingPerformed<targetNbOfDepthPeeling) + { + for(std::vector<int>::const_iterator it=idsToFetch->begin();it!=idsToFetch->end();it++) + for(const int *it2=arrInPtr+arrIndxPtr[*it];it2!=arrInPtr+arrIndxPtr[*it+1];it2++) + if(!fetched[*it2]) + { fetched[*it2]=true; fetched2[*it2]=true; idsToFetchOther->push_back(*it2); } + std::swap(idsToFetch,idsToFetchOther); + idsToFetchOther->clear(); + nbOfDepthPeelingPerformed++; + } + int lgth=(int)std::count(fetched2.begin(),fetched2.end(),true); + i=0; + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New(); ret->alloc(lgth,1); + int *retPtr=ret->getPointer(); + for(std::vector<bool>::const_iterator it=fetched2.begin();it!=fetched2.end();it++,i++) + if(*it) + *retPtr++=i; + return ret.retn(); +} + +/*! + * This method works on an input pair (\b arrIn, \b arrIndxIn) where \b arrIn indexes is in \b arrIndxIn. + * This method builds an output pair (\b arrOut,\b arrIndexOut) that is a copy from \b arrIn for all cell ids \b not \b in [ \b idsOfSelectBg , \b idsOfSelectEnd ) and for + * cellIds \b in [\b idsOfSelectBg, \b idsOfSelectEnd) a copy coming from the corresponding values in input pair (\b srcArr, \b srcArrIndex). + * This method is an generalization of MEDCouplingUMesh::SetPartOfIndexedArraysSameIdx that performs the same thing but by without building explicitely a result output arrays. + * + * \param [in] start begin of set of ids of the input extraction (included) + * \param [in] end end of set of ids of the input extraction (excluded) + * \param [in] step step of the set of ids in range mode. + * \param [in] arrIn arr origin array from which the extraction will be done. + * \param [in] arrIndxIn is the input index array allowing to walk into \b arrIn + * \param [in] srcArr input array that will be used as source of copy for ids in [\b idsOfSelectBg, \b idsOfSelectEnd) + * \param [in] srcArrIndex index array of \b srcArr + * \param [out] arrOut the resulting array + * \param [out] arrIndexOut the index array of the resulting array \b arrOut + * + * \sa MEDCouplingUMesh::SetPartOfIndexedArraysSameIdx MEDCouplingUMesh::SetPartOfIndexedArrays + */ +void MEDCouplingUMesh::SetPartOfIndexedArrays2(int start, int end, int step, const DataArrayInt *arrIn, const DataArrayInt *arrIndxIn, + const DataArrayInt *srcArr, const DataArrayInt *srcArrIndex, + DataArrayInt* &arrOut, DataArrayInt* &arrIndexOut) +{ + if(arrIn==0 || arrIndxIn==0 || srcArr==0 || srcArrIndex==0) + throw INTERP_KERNEL::Exception("MEDCouplingUMesh::SetPartOfIndexedArrays2 : presence of null pointer in input parameter !"); + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> arro=DataArrayInt::New(); + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> arrIo=DataArrayInt::New(); + int nbOfTuples=arrIndxIn->getNumberOfTuples()-1; + int offset=0; + const int *arrIndxInPtr=arrIndxIn->getConstPointer(); + const int *srcArrIndexPtr=srcArrIndex->getConstPointer(); + int nbOfElemsToSet=DataArray::GetNumberOfItemGivenBESRelative(start,end,step,"MEDCouplingUMesh::SetPartOfIndexedArrays2 : "); + int it=start; + for(int i=0;i<nbOfElemsToSet;i++,srcArrIndexPtr++,it+=step) + { + if(it>=0 && it<nbOfTuples) + offset+=(srcArrIndexPtr[1]-srcArrIndexPtr[0])-(arrIndxInPtr[it+1]-arrIndxInPtr[it]); + else + { + std::ostringstream oss; oss << "MEDCouplingUMesh::SetPartOfIndexedArrays2 : On pos #" << i << " value is " << it << " not in [0," << nbOfTuples << ") !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + } + srcArrIndexPtr=srcArrIndex->getConstPointer(); + arrIo->alloc(nbOfTuples+1,1); + arro->alloc(arrIn->getNumberOfTuples()+offset,1); + const int *arrInPtr=arrIn->getConstPointer(); + const int *srcArrPtr=srcArr->getConstPointer(); + int *arrIoPtr=arrIo->getPointer(); *arrIoPtr++=0; + int *arroPtr=arro->getPointer(); + for(int ii=0;ii<nbOfTuples;ii++,arrIoPtr++) + { + int pos=DataArray::GetPosOfItemGivenBESRelativeNoThrow(ii,start,end,step); + if(pos<0) + { + arroPtr=std::copy(arrInPtr+arrIndxInPtr[ii],arrInPtr+arrIndxInPtr[ii+1],arroPtr); + *arrIoPtr=arrIoPtr[-1]+(arrIndxInPtr[ii+1]-arrIndxInPtr[ii]); + } + else + { + arroPtr=std::copy(srcArrPtr+srcArrIndexPtr[pos],srcArrPtr+srcArrIndexPtr[pos+1],arroPtr); + *arrIoPtr=arrIoPtr[-1]+(srcArrIndexPtr[pos+1]-srcArrIndexPtr[pos]); + } + } + arrOut=arro.retn(); + arrIndexOut=arrIo.retn(); +} + +/*! + * This method works on an input pair (\b arrIn, \b arrIndxIn) where \b arrIn indexes is in \b arrIndxIn. + * This method is an specialization of MEDCouplingUMesh::SetPartOfIndexedArrays in the case of assignement do not modify the index in \b arrIndxIn. + * + * \param [in] start begin of set of ids of the input extraction (included) + * \param [in] end end of set of ids of the input extraction (excluded) + * \param [in] step step of the set of ids in range mode. + * \param [in,out] arrInOut arr origin array from which the extraction will be done. + * \param [in] arrIndxIn is the input index array allowing to walk into \b arrIn + * \param [in] srcArr input array that will be used as source of copy for ids in [\b idsOfSelectBg, \b idsOfSelectEnd) + * \param [in] srcArrIndex index array of \b srcArr + * + * \sa MEDCouplingUMesh::SetPartOfIndexedArrays2 MEDCouplingUMesh::SetPartOfIndexedArraysSameIdx + */ +void MEDCouplingUMesh::SetPartOfIndexedArraysSameIdx2(int start, int end, int step, DataArrayInt *arrInOut, const DataArrayInt *arrIndxIn, + const DataArrayInt *srcArr, const DataArrayInt *srcArrIndex) +{ + if(arrInOut==0 || arrIndxIn==0 || srcArr==0 || srcArrIndex==0) + throw INTERP_KERNEL::Exception("MEDCouplingUMesh::SetPartOfIndexedArraysSameIdx2 : presence of null pointer in input parameter !"); + int nbOfTuples=arrIndxIn->getNumberOfTuples()-1; + const int *arrIndxInPtr=arrIndxIn->getConstPointer(); + const int *srcArrIndexPtr=srcArrIndex->getConstPointer(); + int *arrInOutPtr=arrInOut->getPointer(); + const int *srcArrPtr=srcArr->getConstPointer(); + int nbOfElemsToSet=DataArray::GetNumberOfItemGivenBESRelative(start,end,step,"MEDCouplingUMesh::SetPartOfIndexedArraysSameIdx2 : "); + int it=start; + for(int i=0;i<nbOfElemsToSet;i++,srcArrIndexPtr++,it+=step) + { + if(it>=0 && it<nbOfTuples) + { + if(srcArrIndexPtr[1]-srcArrIndexPtr[0]==arrIndxInPtr[it+1]-arrIndxInPtr[it]) + std::copy(srcArrPtr+srcArrIndexPtr[0],srcArrPtr+srcArrIndexPtr[1],arrInOutPtr+arrIndxInPtr[it]); + else + { + std::ostringstream oss; oss << "MEDCouplingUMesh::SetPartOfIndexedArraysSameIdx2 : On pos #" << i << " id (idsOfSelectBg[" << i << "]) is " << it << " arrIndxIn[id+1]-arrIndxIn[id]!=srcArrIndex[pos+1]-srcArrIndex[pos] !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + } + else + { + std::ostringstream oss; oss << "MEDCouplingUMesh::SetPartOfIndexedArraysSameIdx2 : On pos #" << i << " value is " << it << " not in [0," << nbOfTuples << ") !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + } +} + +/*! + * \b this is expected to be a mesh fully defined whose spaceDim==meshDim. + * It returns a new allocated mesh having the same mesh dimension and lying on same coordinates. + * The returned mesh contains as poly cells as number of contiguous zone (regarding connectivity). + * A spread contiguous zone is built using poly cells (polyhedra in 3D, polygons in 2D and polyline in 1D). + * The sum of measure field of returned mesh is equal to the sum of measure field of this. + * + * \return a newly allocated mesh lying on the same coords than \b this with same meshdimension than \b this. + */ +MEDCouplingUMesh *MEDCouplingUMesh::buildSpreadZonesWithPoly() const +{ + checkFullyDefined(); + int mdim=getMeshDimension(); + int spaceDim=getSpaceDimension(); + if(mdim!=spaceDim) + throw INTERP_KERNEL::Exception("MEDCouplingUMesh::buildSpreadZonesWithPoly : meshdimension and spacedimension do not match !"); + std::vector<DataArrayInt *> partition=partitionBySpreadZone(); + std::vector< MEDCouplingAutoRefCountObjectPtr<DataArrayInt> > partitionAuto; partitionAuto.reserve(partition.size()); + std::copy(partition.begin(),partition.end(),std::back_insert_iterator<std::vector< MEDCouplingAutoRefCountObjectPtr<DataArrayInt> > >(partitionAuto)); + MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> ret=MEDCouplingUMesh::New(getName(),mdim); + ret->setCoords(getCoords()); + ret->allocateCells((int)partition.size()); + // + for(std::vector<DataArrayInt *>::const_iterator it=partition.begin();it!=partition.end();it++) + { + MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> tmp=static_cast<MEDCouplingUMesh *>(buildPartOfMySelf((*it)->begin(),(*it)->end(),true)); + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> cell; + switch(mdim) + { + case 2: + cell=tmp->buildUnionOf2DMesh(); + break; + case 3: + cell=tmp->buildUnionOf3DMesh(); + break; + default: + throw INTERP_KERNEL::Exception("MEDCouplingUMesh::buildSpreadZonesWithPoly : meshdimension supported are [2,3] ! Not implemented yet for others !"); + } + + ret->insertNextCell((INTERP_KERNEL::NormalizedCellType)cell->getIJSafe(0,0),cell->getNumberOfTuples()-1,cell->getConstPointer()+1); + } + // + ret->finishInsertingCells(); + return ret.retn(); +} + +/*! + * This method partitions \b this into contiguous zone. + * This method only needs a well defined connectivity. Coordinates are not considered here. + * This method returns a vector of \b newly allocated arrays that the caller has to deal with. + */ +std::vector<DataArrayInt *> MEDCouplingUMesh::partitionBySpreadZone() const +{ + int nbOfCellsCur=getNumberOfCells(); + std::vector<DataArrayInt *> ret; + if(nbOfCellsCur<=0) + return ret; + DataArrayInt *neigh=0,*neighI=0; + computeNeighborsOfCells(neigh,neighI); + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> neighAuto(neigh),neighIAuto(neighI); + std::vector<bool> fetchedCells(nbOfCellsCur,false); + std::vector< MEDCouplingAutoRefCountObjectPtr<DataArrayInt> > ret2; + int seed=0; + while(seed<nbOfCellsCur) + { + int nbOfPeelPerformed=0; + ret2.push_back(ComputeSpreadZoneGraduallyFromSeedAlg(fetchedCells,&seed,&seed+1,neigh,neighI,-1,nbOfPeelPerformed)); + seed=(int)std::distance(fetchedCells.begin(),std::find(fetchedCells.begin()+seed,fetchedCells.end(),false)); + } + for(std::vector< MEDCouplingAutoRefCountObjectPtr<DataArrayInt> >::iterator it=ret2.begin();it!=ret2.end();it++) + ret.push_back((*it).retn()); + return ret; +} + +/*! + * This method returns given a distribution of cell type (returned for example by MEDCouplingUMesh::getDistributionOfTypes method and customized after) a + * newly allocated DataArrayInt instance with 2 components ready to be interpreted as input of DataArrayInt::findRangeIdForEachTuple method. + * + * \param [in] code a code with the same format than those returned by MEDCouplingUMesh::getDistributionOfTypes except for the code[3*k+2] that should contain start id of chunck. + * \return a newly allocated DataArrayInt to be managed by the caller. + * \throw In case of \a code has not the right format (typically of size 3*n) + */ +DataArrayInt *MEDCouplingUMesh::ComputeRangesFromTypeDistribution(const std::vector<int>& code) +{ + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New(); + std::size_t nb=code.size()/3; + if(code.size()%3!=0) + throw INTERP_KERNEL::Exception("MEDCouplingUMesh::ComputeRangesFromTypeDistribution : invalid input code !"); + ret->alloc((int)nb,2); + int *retPtr=ret->getPointer(); + for(std::size_t i=0;i<nb;i++,retPtr+=2) + { + retPtr[0]=code[3*i+2]; + retPtr[1]=code[3*i+2]+code[3*i+1]; + } + return ret.retn(); +} + +/*! + * This method expects that \a this a 3D mesh (spaceDim=3 and meshDim=3) with all coordinates and connectivities set. + * All cells in \a this are expected to be linear 3D cells. + * This method will split **all** 3D cells in \a this into INTERP_KERNEL::NORM_TETRA4 cells and put them in the returned mesh. + * It leads to an increase to number of cells. + * This method contrary to MEDCouplingUMesh::simplexize can append coordinates in \a this to perform its work. + * The \a nbOfAdditionalPoints returned value informs about it. If > 0, the coordinates array in returned mesh will have \a nbOfAdditionalPoints + * more tuples (nodes) than in \a this. Anyway, all the nodes in \a this (with the same order) will be in the returned mesh. + * + * \param [in] policy - the policy of splitting that must be in (PLANAR_FACE_5, PLANAR_FACE_6, GENERAL_24, GENERAL_48). The policy will be used only for INTERP_KERNEL::NORM_HEXA8 cells. + * For all other cells, the splitting policy will be ignored. See INTERP_KERNEL::SplittingPolicy for the images. + * \param [out] nbOfAdditionalPoints - number of nodes added to \c this->_coords. If > 0 a new coordinates object will be constructed result of the aggregation of the old one and the new points added. + * \param [out] n2oCells - A new instance of DataArrayInt holding, for each new cell, + * an id of old cell producing it. The caller is to delete this array using + * decrRef() as it is no more needed. + * \return MEDCoupling1SGTUMesh * - the mesh containing only INTERP_KERNEL::NORM_TETRA4 cells. + * + * \warning This method operates on each cells in this independantly ! So it can leads to non conform mesh in returned value ! If you expect to have a conform mesh in output + * the policy PLANAR_FACE_6 should be used on a mesh sorted with MEDCoupling1SGTUMesh::sortHexa8EachOther. + * + * \throw If \a this is not a 3D mesh (spaceDim==3 and meshDim==3). + * \throw If \a this is not fully constituted with linear 3D cells. + * \sa MEDCouplingUMesh::simplexize, MEDCoupling1SGTUMesh::sortHexa8EachOther + */ +MEDCoupling1SGTUMesh *MEDCouplingUMesh::tetrahedrize(int policy, DataArrayInt *& n2oCells, int& nbOfAdditionalPoints) const +{ + INTERP_KERNEL::SplittingPolicy pol((INTERP_KERNEL::SplittingPolicy)policy); + checkConnectivityFullyDefined(); + if(getMeshDimension()!=3 || getSpaceDimension()!=3) + throw INTERP_KERNEL::Exception("MEDCouplingUMesh::tetrahedrize : only available for mesh with meshdim == 3 and spacedim == 3 !"); + int nbOfCells(getNumberOfCells()),nbNodes(getNumberOfNodes()); + MEDCouplingAutoRefCountObjectPtr<MEDCoupling1SGTUMesh> ret0(MEDCoupling1SGTUMesh::New(getName(),INTERP_KERNEL::NORM_TETRA4)); + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(nbOfCells,1); + int *retPt(ret->getPointer()); + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> newConn(DataArrayInt::New()); newConn->alloc(0,1); + MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> addPts(DataArrayDouble::New()); addPts->alloc(0,1); + const int *oldc(_nodal_connec->begin()); + const int *oldci(_nodal_connec_index->begin()); + const double *coords(_coords->begin()); + for(int i=0;i<nbOfCells;i++,oldci++,retPt++) + { + std::vector<int> a; std::vector<double> b; + INTERP_KERNEL::SplitIntoTetras(pol,(INTERP_KERNEL::NormalizedCellType)oldc[oldci[0]],oldc+oldci[0]+1,oldc+oldci[1],coords,a,b); + std::size_t nbOfTet(a.size()/4); *retPt=(int)nbOfTet; + const int *aa(&a[0]); + if(!b.empty()) + { + for(std::vector<int>::iterator it=a.begin();it!=a.end();it++) + if(*it<0) + *it=(-(*(it))-1+nbNodes); + addPts->insertAtTheEnd(b.begin(),b.end()); + nbNodes+=(int)b.size()/3; + } + for(std::size_t j=0;j<nbOfTet;j++,aa+=4) + newConn->insertAtTheEnd(aa,aa+4); + } + if(!addPts->empty()) + { + addPts->rearrange(3); + nbOfAdditionalPoints=addPts->getNumberOfTuples(); + addPts=DataArrayDouble::Aggregate(getCoords(),addPts); + ret0->setCoords(addPts); + } + else + { + nbOfAdditionalPoints=0; + ret0->setCoords(getCoords()); + } + ret0->setNodalConnectivity(newConn); + // + ret->computeOffsets2(); + n2oCells=ret->buildExplicitArrOfSliceOnScaledArr(0,nbOfCells,1); + return ret0.retn(); +} + +/*! + * It is the linear part of MEDCouplingUMesh::split2DCells. Here no additionnal nodes will be added in \b this. So coordinates pointer remain unchanged (is not even touch). + * + * \sa MEDCouplingUMesh::split2DCells + */ +void MEDCouplingUMesh::split2DCellsLinear(const DataArrayInt *desc, const DataArrayInt *descI, const DataArrayInt *subNodesInSeg, const DataArrayInt *subNodesInSegI) +{ + checkConnectivityFullyDefined(); + int ncells(getNumberOfCells()),lgthToReach(getMeshLength()+subNodesInSeg->getNumberOfTuples()); + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> c(DataArrayInt::New()); c->alloc((std::size_t)lgthToReach); + const int *subPtr(subNodesInSeg->begin()),*subIPtr(subNodesInSegI->begin()),*descPtr(desc->begin()),*descIPtr(descI->begin()),*oldConn(getNodalConnectivity()->begin()); + int *cPtr(c->getPointer()),*ciPtr(getNodalConnectivityIndex()->getPointer()); + int prevPosOfCi(ciPtr[0]); + for(int i=0;i<ncells;i++,ciPtr++,descIPtr++) + { + int offset(descIPtr[0]),sz(descIPtr[1]-descIPtr[0]),deltaSz(0); + *cPtr++=(int)INTERP_KERNEL::NORM_POLYGON; *cPtr++=oldConn[prevPosOfCi+1]; + for(int j=0;j<sz;j++) + { + int offset2(subIPtr[descPtr[offset+j]]),sz2(subIPtr[descPtr[offset+j]+1]-subIPtr[descPtr[offset+j]]); + for(int k=0;k<sz2;k++) + *cPtr++=subPtr[offset2+k]; + if(j!=sz-1) + *cPtr++=oldConn[prevPosOfCi+j+2]; + deltaSz+=sz2; + } + prevPosOfCi=ciPtr[1]; + ciPtr[1]=ciPtr[0]+1+sz+deltaSz;//sz==old nb of nodes because (nb of subedges=nb of nodes for polygons) + } + if(c->end()!=cPtr) + throw INTERP_KERNEL::Exception("MEDCouplingUMesh::split2DCellsLinear : Some of edges to be split are orphan !"); + _nodal_connec->decrRef(); + _nodal_connec=c.retn(); _types.clear(); _types.insert(INTERP_KERNEL::NORM_POLYGON); +} + +int InternalAddPoint(const INTERP_KERNEL::Edge *e, int id, const double *coo, int startId, int endId, DataArrayDouble& addCoo, int& nodesCnter) +{ + if(id!=-1) + return id; + else + { + int ret(nodesCnter++); + double newPt[2]; + e->getMiddleOfPoints(coo+2*startId,coo+2*endId,newPt); + addCoo.insertAtTheEnd(newPt,newPt+2); + return ret; + } +} + +int InternalAddPointOriented(const INTERP_KERNEL::Edge *e, int id, const double *coo, int startId, int endId, DataArrayDouble& addCoo, int& nodesCnter) +{ + if(id!=-1) + return id; + else + { + int ret(nodesCnter++); + double newPt[2]; + e->getMiddleOfPointsOriented(coo+2*startId,coo+2*endId,newPt); + addCoo.insertAtTheEnd(newPt,newPt+2); + return ret; + } +} + + +/// @cond INTERNAL + +void EnterTheResultOf2DCellFirst(const INTERP_KERNEL::Edge *e, int start, int stp, int nbOfEdges, bool linOrArc, const double *coords, const int *connBg, int offset, DataArrayInt *newConnOfCell, DataArrayDouble *appendedCoords, std::vector<int>& middles) +{ + int tmp[3]; + int trueStart(start>=0?start:nbOfEdges+start); + tmp[0]=linOrArc?(int)INTERP_KERNEL::NORM_QPOLYG:(int)INTERP_KERNEL::NORM_POLYGON; tmp[1]=connBg[trueStart]; tmp[2]=connBg[stp]; + newConnOfCell->insertAtTheEnd(tmp,tmp+3); + if(linOrArc) + { + if(stp-start>1) + { + int tmp2(0),tmp3(appendedCoords->getNumberOfTuples()/2); + InternalAddPointOriented(e,-1,coords,tmp[1],tmp[2],*appendedCoords,tmp2); + middles.push_back(tmp3+offset); + } + else + middles.push_back(connBg[trueStart+nbOfEdges]); + } +} + +void EnterTheResultOf2DCellMiddle(const INTERP_KERNEL::Edge *e, int start, int stp, int nbOfEdges, bool linOrArc, const double *coords, const int *connBg, int offset, DataArrayInt *newConnOfCell, DataArrayDouble *appendedCoords, std::vector<int>& middles) +{ + int tmpSrt(newConnOfCell->back()),tmpEnd(connBg[stp]); + newConnOfCell->pushBackSilent(tmpEnd); + if(linOrArc) + { + if(stp-start>1) + { + int tmp2(0),tmp3(appendedCoords->getNumberOfTuples()/2); + InternalAddPointOriented(e,-1,coords,tmpSrt,tmpEnd,*appendedCoords,tmp2); + middles.push_back(tmp3+offset); + } + else + middles.push_back(connBg[start+nbOfEdges]); + } +} + +void EnterTheResultOf2DCellEnd(const INTERP_KERNEL::Edge *e, int start, int stp, int nbOfEdges, bool linOrArc, const double *coords, const int *connBg, int offset, DataArrayInt *newConnOfCell, DataArrayDouble *appendedCoords, std::vector<int>& middles) +{ + // only the quadratic point to deal with: + if(linOrArc) + { + if(stp-start>1) + { + int tmpSrt(connBg[start]),tmpEnd(connBg[stp]); + int tmp2(0),tmp3(appendedCoords->getNumberOfTuples()/2); + InternalAddPointOriented(e,-1,coords,tmpSrt,tmpEnd,*appendedCoords,tmp2); + middles.push_back(tmp3+offset); + } + else + middles.push_back(connBg[start+nbOfEdges]); + } +} + +/// @endcond + +/*! + * Returns true if a colinearization has been found in the given cell. If false is returned the content pushed in \a newConnOfCell is equal to [ \a connBg , \a connEnd ) . + * \a appendedCoords is a DataArrayDouble instance with number of components equal to one (even if the items are pushed by pair). + */ +bool MEDCouplingUMesh::Colinearize2DCell(const double *coords, const int *connBg, const int *connEnd, int offset, DataArrayInt *newConnOfCell, DataArrayDouble *appendedCoords) +{ + std::size_t sz(std::distance(connBg,connEnd)); + if(sz<3)//3 because 2+1(for the cell type) and 2 is the minimal number of edges of 2D cell. + throw INTERP_KERNEL::Exception("MEDCouplingUMesh::Colinearize2DCell : the input cell has invalid format !"); + sz--; + INTERP_KERNEL::AutoPtr<int> tmpConn(new int[sz]); + const INTERP_KERNEL::CellModel& cm(INTERP_KERNEL::CellModel::GetCellModel((INTERP_KERNEL::NormalizedCellType)connBg[0])); + unsigned nbs(cm.getNumberOfSons2(connBg+1,sz)); + unsigned nbOfHit(0); // number of fusions operated + int posBaseElt(0),posEndElt(0),nbOfTurn(0); + const unsigned int maxNbOfHit = cm.isQuadratic() ? nbs-2 : nbs-3; // a quad cell is authorized to end up with only two edges, a linear one has to keep 3 at least + INTERP_KERNEL::NormalizedCellType typeOfSon; + std::vector<int> middles; + bool ret(false); + for(;(nbOfTurn+nbOfHit)<nbs;nbOfTurn++) + { + cm.fillSonCellNodalConnectivity2(posBaseElt,connBg+1,sz,tmpConn,typeOfSon); + std::map<MEDCouplingAutoRefCountObjectPtr<INTERP_KERNEL::Node>,int> m; + INTERP_KERNEL::Edge *e(MEDCouplingUMeshBuildQPFromEdge2(typeOfSon,tmpConn,coords,m)); + posEndElt = posBaseElt+1; + + // Look backward first: are the final edges of the cells colinear with the first ones? + // This initializes posBaseElt. + if(nbOfTurn==0) + { + for(unsigned i=1;i<nbs && nbOfHit<maxNbOfHit;i++) // 2nd condition is to avoid ending with a cell wih one single edge + { + cm.fillSonCellNodalConnectivity2(nbs-i,connBg+1,sz,tmpConn,typeOfSon); + INTERP_KERNEL::Edge *eCand(MEDCouplingUMeshBuildQPFromEdge2(typeOfSon,tmpConn,coords,m)); + INTERP_KERNEL::EdgeIntersector *eint(INTERP_KERNEL::Edge::BuildIntersectorWith(e,eCand)); + bool isColinear=eint->areColinears(); + if(isColinear) + { + nbOfHit++; + posBaseElt--; + ret=true; + } + delete eint; + eCand->decrRef(); + if(!isColinear) + break; + } + } + // Now move forward: + const unsigned fwdStart = (nbOfTurn == 0 ? 0 : posBaseElt); // the first element to be inspected going forward + for(unsigned j=fwdStart+1;j<nbs && nbOfHit<maxNbOfHit;j++) // 2nd condition is to avoid ending with a cell wih one single edge + { + cm.fillSonCellNodalConnectivity2((int)j,connBg+1,sz,tmpConn,typeOfSon); // get edge #j's connectivity + INTERP_KERNEL::Edge *eCand(MEDCouplingUMeshBuildQPFromEdge2(typeOfSon,tmpConn,coords,m)); + INTERP_KERNEL::EdgeIntersector *eint(INTERP_KERNEL::Edge::BuildIntersectorWith(e,eCand)); + bool isColinear(eint->areColinears()); + if(isColinear) + { + nbOfHit++; + posEndElt++; + ret=true; + } + delete eint; + eCand->decrRef(); + if(!isColinear) + break; + } + //push [posBaseElt,posEndElt) in newConnOfCell using e + // The if clauses below are (volontary) not mutually exclusive: on a quad cell with 2 edges, the end of the connectivity is also its begining! + if(nbOfTurn==0) + // at the begining of the connectivity (insert type) + EnterTheResultOf2DCellFirst(e,posBaseElt,posEndElt,(int)nbs,cm.isQuadratic(),coords,connBg+1,offset,newConnOfCell,appendedCoords,middles); + else if((nbOfHit+nbOfTurn) != (nbs-1)) + // in the middle + EnterTheResultOf2DCellMiddle(e,posBaseElt,posEndElt,(int)nbs,cm.isQuadratic(),coords,connBg+1,offset,newConnOfCell,appendedCoords,middles); + if ((nbOfHit+nbOfTurn) == (nbs-1)) + // at the end (only quad points to deal with) + EnterTheResultOf2DCellEnd(e,posBaseElt,posEndElt,(int)nbs,cm.isQuadratic(),coords,connBg+1,offset,newConnOfCell,appendedCoords,middles); + posBaseElt=posEndElt; + e->decrRef(); + } + if(!middles.empty()) + newConnOfCell->insertAtTheEnd(middles.begin(),middles.end()); + return ret; +} + +/*! + * It is the quadratic part of MEDCouplingUMesh::split2DCells. Here some additionnal nodes can be added at the end of coordinates array object. + * + * \return int - the number of new nodes created. + * \sa MEDCouplingUMesh::split2DCells + */ +int MEDCouplingUMesh::split2DCellsQuadratic(const DataArrayInt *desc, const DataArrayInt *descI, const DataArrayInt *subNodesInSeg, const DataArrayInt *subNodesInSegI, const DataArrayInt *mid, const DataArrayInt *midI) +{ + checkCoherency(); + int ncells(getNumberOfCells()),lgthToReach(getMeshLength()+2*subNodesInSeg->getNumberOfTuples()),nodesCnt(getNumberOfNodes()); + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> c(DataArrayInt::New()); c->alloc((std::size_t)lgthToReach); + MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> addCoo(DataArrayDouble::New()); addCoo->alloc(0,1); + const int *subPtr(subNodesInSeg->begin()),*subIPtr(subNodesInSegI->begin()),*descPtr(desc->begin()),*descIPtr(descI->begin()),*oldConn(getNodalConnectivity()->begin()); + const int *midPtr(mid->begin()),*midIPtr(midI->begin()); + const double *oldCoordsPtr(getCoords()->begin()); + int *cPtr(c->getPointer()),*ciPtr(getNodalConnectivityIndex()->getPointer()); + int prevPosOfCi(ciPtr[0]); + for(int i=0;i<ncells;i++,ciPtr++,descIPtr++) + { + int offset(descIPtr[0]),sz(descIPtr[1]-descIPtr[0]),deltaSz(sz); + for(int j=0;j<sz;j++) + { int sz2(subIPtr[descPtr[offset+j]+1]-subIPtr[descPtr[offset+j]]); deltaSz+=sz2; } + *cPtr++=(int)INTERP_KERNEL::NORM_QPOLYG; cPtr[0]=oldConn[prevPosOfCi+1]; + for(int j=0;j<sz;j++)//loop over subedges of oldConn + { + int offset2(subIPtr[descPtr[offset+j]]),sz2(subIPtr[descPtr[offset+j]+1]-subIPtr[descPtr[offset+j]]),offset3(midIPtr[descPtr[offset+j]]); + if(sz2==0) + { + if(j<sz-1) + cPtr[1]=oldConn[prevPosOfCi+2+j]; + cPtr[deltaSz]=oldConn[prevPosOfCi+1+j+sz]; cPtr++; + continue; + } + std::vector<INTERP_KERNEL::Node *> ns(3); + ns[0]=new INTERP_KERNEL::Node(oldCoordsPtr[2*oldConn[prevPosOfCi+1+j]],oldCoordsPtr[2*oldConn[prevPosOfCi+1+j]+1]); + ns[1]=new INTERP_KERNEL::Node(oldCoordsPtr[2*oldConn[prevPosOfCi+1+(1+j)%sz]],oldCoordsPtr[2*oldConn[prevPosOfCi+1+(1+j)%sz]+1]); + ns[2]=new INTERP_KERNEL::Node(oldCoordsPtr[2*oldConn[prevPosOfCi+1+sz+j]],oldCoordsPtr[2*oldConn[prevPosOfCi+1+sz+j]+1]); + MEDCouplingAutoRefCountObjectPtr<INTERP_KERNEL::Edge> e(INTERP_KERNEL::QuadraticPolygon::BuildArcCircleEdge(ns)); + for(int k=0;k<sz2;k++)//loop over subsplit of current subedge + { + cPtr[1]=subPtr[offset2+k]; + cPtr[deltaSz]=InternalAddPoint(e,midPtr[offset3+k],oldCoordsPtr,cPtr[0],cPtr[1],*addCoo,nodesCnt); cPtr++; + } + int tmpEnd(oldConn[prevPosOfCi+1+(j+1)%sz]); + if(j!=sz-1) + { cPtr[1]=tmpEnd; } + cPtr[deltaSz]=InternalAddPoint(e,midPtr[offset3+sz2],oldCoordsPtr,cPtr[0],tmpEnd,*addCoo,nodesCnt); cPtr++; + } + prevPosOfCi=ciPtr[1]; cPtr+=deltaSz; + ciPtr[1]=ciPtr[0]+1+2*deltaSz;//sz==old nb of nodes because (nb of subedges=nb of nodes for polygons) + } + if(c->end()!=cPtr) + throw INTERP_KERNEL::Exception("MEDCouplingUMesh::split2DCellsQuadratic : Some of edges to be split are orphan !"); + _nodal_connec->decrRef(); + _nodal_connec=c.retn(); _types.clear(); _types.insert(INTERP_KERNEL::NORM_QPOLYG); + addCoo->rearrange(2); + MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> coo(DataArrayDouble::Aggregate(getCoords(),addCoo));//info are copied from getCoords() by using Aggregate + setCoords(coo); + return addCoo->getNumberOfTuples(); +} + +void MEDCouplingUMesh::ComputeAllTypesInternal(std::set<INTERP_KERNEL::NormalizedCellType>& types, const DataArrayInt *nodalConnec, const DataArrayInt *nodalConnecIndex) +{ + if(nodalConnec && nodalConnecIndex) + { + types.clear(); + const int *conn(nodalConnec->getConstPointer()),*connIndex(nodalConnecIndex->getConstPointer()); + int nbOfElem(nodalConnecIndex->getNbOfElems()-1); + if(nbOfElem>0) + for(const int *pt=connIndex;pt!=connIndex+nbOfElem;pt++) + types.insert((INTERP_KERNEL::NormalizedCellType)conn[*pt]); + } +} + +MEDCouplingUMeshCellIterator::MEDCouplingUMeshCellIterator(MEDCouplingUMesh *mesh):_mesh(mesh),_cell(new MEDCouplingUMeshCell(mesh)), + _own_cell(true),_cell_id(-1),_nb_cell(0) +{ + if(mesh) + { + mesh->incrRef(); + _nb_cell=mesh->getNumberOfCells(); + } +} + +MEDCouplingUMeshCellIterator::~MEDCouplingUMeshCellIterator() +{ + if(_mesh) + _mesh->decrRef(); + if(_own_cell) + delete _cell; +} + +MEDCouplingUMeshCellIterator::MEDCouplingUMeshCellIterator(MEDCouplingUMesh *mesh, MEDCouplingUMeshCell *itc, int bg, int end):_mesh(mesh),_cell(itc), + _own_cell(false),_cell_id(bg-1), + _nb_cell(end) +{ + if(mesh) + mesh->incrRef(); +} + +MEDCouplingUMeshCell *MEDCouplingUMeshCellIterator::nextt() +{ + _cell_id++; + if(_cell_id<_nb_cell) + { + _cell->next(); + return _cell; + } + else + return 0; +} + +MEDCouplingUMeshCellByTypeEntry::MEDCouplingUMeshCellByTypeEntry(MEDCouplingUMesh *mesh):_mesh(mesh) +{ + if(_mesh) + _mesh->incrRef(); +} + +MEDCouplingUMeshCellByTypeIterator *MEDCouplingUMeshCellByTypeEntry::iterator() +{ + return new MEDCouplingUMeshCellByTypeIterator(_mesh); +} + +MEDCouplingUMeshCellByTypeEntry::~MEDCouplingUMeshCellByTypeEntry() +{ + if(_mesh) + _mesh->decrRef(); +} + +MEDCouplingUMeshCellEntry::MEDCouplingUMeshCellEntry(MEDCouplingUMesh *mesh, INTERP_KERNEL::NormalizedCellType type, MEDCouplingUMeshCell *itc, int bg, int end):_mesh(mesh),_type(type), + _itc(itc), + _bg(bg),_end(end) +{ + if(_mesh) + _mesh->incrRef(); +} + +MEDCouplingUMeshCellEntry::~MEDCouplingUMeshCellEntry() +{ + if(_mesh) + _mesh->decrRef(); +} + +INTERP_KERNEL::NormalizedCellType MEDCouplingUMeshCellEntry::getType() const +{ + return _type; +} + +int MEDCouplingUMeshCellEntry::getNumberOfElems() const +{ + return _end-_bg; +} + +MEDCouplingUMeshCellIterator *MEDCouplingUMeshCellEntry::iterator() +{ + return new MEDCouplingUMeshCellIterator(_mesh,_itc,_bg,_end); +} + +MEDCouplingUMeshCellByTypeIterator::MEDCouplingUMeshCellByTypeIterator(MEDCouplingUMesh *mesh):_mesh(mesh),_cell(new MEDCouplingUMeshCell(mesh)),_cell_id(0),_nb_cell(0) +{ + if(mesh) + { + mesh->incrRef(); + _nb_cell=mesh->getNumberOfCells(); + } +} + +MEDCouplingUMeshCellByTypeIterator::~MEDCouplingUMeshCellByTypeIterator() +{ + if(_mesh) + _mesh->decrRef(); + delete _cell; +} + +MEDCouplingUMeshCellEntry *MEDCouplingUMeshCellByTypeIterator::nextt() +{ + const int *c=_mesh->getNodalConnectivity()->getConstPointer(); + const int *ci=_mesh->getNodalConnectivityIndex()->getConstPointer(); + if(_cell_id<_nb_cell) + { + INTERP_KERNEL::NormalizedCellType type=(INTERP_KERNEL::NormalizedCellType)c[ci[_cell_id]]; + int nbOfElems=(int)std::distance(ci+_cell_id,std::find_if(ci+_cell_id,ci+_nb_cell,ParaMEDMEMImpl::ConnReader(c,type))); + int startId=_cell_id; + _cell_id+=nbOfElems; + return new MEDCouplingUMeshCellEntry(_mesh,type,_cell,startId,_cell_id); + } + else + return 0; +} + +MEDCouplingUMeshCell::MEDCouplingUMeshCell(MEDCouplingUMesh *mesh):_conn(0),_conn_indx(0),_conn_lgth(NOTICABLE_FIRST_VAL) +{ + if(mesh) + { + _conn=mesh->getNodalConnectivity()->getPointer(); + _conn_indx=mesh->getNodalConnectivityIndex()->getPointer(); + } +} + +void MEDCouplingUMeshCell::next() +{ + if(_conn_lgth!=NOTICABLE_FIRST_VAL) + { + _conn+=_conn_lgth; + _conn_indx++; + } + _conn_lgth=_conn_indx[1]-_conn_indx[0]; +} + +std::string MEDCouplingUMeshCell::repr() const +{ + if(_conn_lgth!=NOTICABLE_FIRST_VAL) + { + std::ostringstream oss; oss << "Cell Type " << INTERP_KERNEL::CellModel::GetCellModel((INTERP_KERNEL::NormalizedCellType)_conn[0]).getRepr(); + oss << " : "; + std::copy(_conn+1,_conn+_conn_lgth,std::ostream_iterator<int>(oss," ")); + return oss.str(); + } + else + return std::string("MEDCouplingUMeshCell::repr : Invalid pos"); +} + +INTERP_KERNEL::NormalizedCellType MEDCouplingUMeshCell::getType() const +{ + if(_conn_lgth!=NOTICABLE_FIRST_VAL) + return (INTERP_KERNEL::NormalizedCellType)_conn[0]; + else + return INTERP_KERNEL::NORM_ERROR; +} + +const int *MEDCouplingUMeshCell::getAllConn(int& lgth) const +{ + lgth=_conn_lgth; + if(_conn_lgth!=NOTICABLE_FIRST_VAL) + return _conn; + else + return 0; +} diff --git a/src/medtool/src/MEDCoupling/MEDCouplingUMesh.hxx b/src/medtool/src/MEDCoupling/MEDCouplingUMesh.hxx new file mode 100644 index 000000000..e3bb9c6d7 --- /dev/null +++ b/src/medtool/src/MEDCoupling/MEDCouplingUMesh.hxx @@ -0,0 +1,428 @@ +// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 +// 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_MEDCOUPLINGUMESH_HXX__ +#define __PARAMEDMEM_MEDCOUPLINGUMESH_HXX__ + +#include "MEDCoupling.hxx" +#include "MEDCouplingPointSet.hxx" +#include "MEDCouplingMemArray.hxx" + +#include "CellModel.hxx" + +#include <set> + +namespace ParaMEDMEM +{ + class MEDCouplingUMeshCellByTypeEntry; + class MEDCouplingUMeshCellIterator; + class MEDCoupling1SGTUMesh; + class MEDCoupling1GTUMesh; + class MEDCouplingSkyLineArray; + + class MEDCouplingUMesh : public MEDCouplingPointSet + { + public: + MEDCOUPLING_EXPORT static MEDCouplingUMesh *New(); + MEDCOUPLING_EXPORT static MEDCouplingUMesh *New(const std::string& meshName, int meshDim); + MEDCOUPLING_EXPORT MEDCouplingMesh *deepCpy() const; + MEDCOUPLING_EXPORT MEDCouplingUMesh *clone(bool recDeepCpy) const; + MEDCOUPLING_EXPORT MEDCouplingPointSet *deepCpyConnectivityOnly() const; + MEDCOUPLING_EXPORT void shallowCopyConnectivityFrom(const MEDCouplingPointSet *other); + MEDCOUPLING_EXPORT void updateTime() const; + MEDCOUPLING_EXPORT std::size_t getHeapMemorySizeWithoutChildren() const; + MEDCOUPLING_EXPORT std::vector<const BigMemoryObject *> getDirectChildrenWithNull() const; + MEDCOUPLING_EXPORT MEDCouplingMeshType getType() const { return UNSTRUCTURED; } + MEDCOUPLING_EXPORT bool isEqualIfNotWhy(const MEDCouplingMesh *other, double prec, std::string& reason) const; + MEDCOUPLING_EXPORT bool isEqualWithoutConsideringStr(const MEDCouplingMesh *other, double prec) const; + MEDCOUPLING_EXPORT void checkFastEquivalWith(const MEDCouplingMesh *other, double prec) const; + MEDCOUPLING_EXPORT void checkCoherency() const; + MEDCOUPLING_EXPORT void checkCoherency1(double eps=1e-12) const; + MEDCOUPLING_EXPORT void checkCoherency2(double eps=1e-12) const; + MEDCOUPLING_EXPORT void setMeshDimension(int meshDim); + MEDCOUPLING_EXPORT void allocateCells(int nbOfCells=0); + MEDCOUPLING_EXPORT void insertNextCell(INTERP_KERNEL::NormalizedCellType type, int size, const int *nodalConnOfCell); + MEDCOUPLING_EXPORT void finishInsertingCells(); + MEDCOUPLING_EXPORT MEDCouplingUMeshCellIterator *cellIterator(); + MEDCOUPLING_EXPORT MEDCouplingUMeshCellByTypeEntry *cellsByType(); + MEDCOUPLING_EXPORT std::set<INTERP_KERNEL::NormalizedCellType> getAllGeoTypes() const; + MEDCOUPLING_EXPORT std::vector<INTERP_KERNEL::NormalizedCellType> getAllGeoTypesSorted() const; + MEDCOUPLING_EXPORT std::set<INTERP_KERNEL::NormalizedCellType> getTypesOfPart(const int *begin, const int *end) const; + MEDCOUPLING_EXPORT void setConnectivity(DataArrayInt *conn, DataArrayInt *connIndex, bool isComputingTypes=true); + MEDCOUPLING_EXPORT const DataArrayInt *getNodalConnectivity() const { return _nodal_connec; } + MEDCOUPLING_EXPORT const DataArrayInt *getNodalConnectivityIndex() const { return _nodal_connec_index; } + MEDCOUPLING_EXPORT DataArrayInt *getNodalConnectivity() { return _nodal_connec; } + MEDCOUPLING_EXPORT DataArrayInt *getNodalConnectivityIndex() { return _nodal_connec_index; } + MEDCOUPLING_EXPORT INTERP_KERNEL::NormalizedCellType getTypeOfCell(int cellId) const; + MEDCOUPLING_EXPORT DataArrayInt *giveCellsWithType(INTERP_KERNEL::NormalizedCellType type) const; + MEDCOUPLING_EXPORT int getNumberOfCellsWithType(INTERP_KERNEL::NormalizedCellType type) const; + MEDCOUPLING_EXPORT void getNodeIdsOfCell(int cellId, std::vector<int>& conn) const; + MEDCOUPLING_EXPORT std::string simpleRepr() const; + MEDCOUPLING_EXPORT std::string advancedRepr() const; + MEDCOUPLING_EXPORT std::string cppRepr() const; + MEDCOUPLING_EXPORT std::string reprConnectivityOfThis() const; + MEDCOUPLING_EXPORT MEDCouplingUMesh *buildSetInstanceFromThis(int spaceDim) const; + MEDCOUPLING_EXPORT int getNumberOfNodesInCell(int cellId) const; + MEDCOUPLING_EXPORT int getNumberOfCells() const; + MEDCOUPLING_EXPORT int getMeshDimension() const; + MEDCOUPLING_EXPORT int getMeshLength() const; + MEDCOUPLING_EXPORT void computeTypes(); + //! size of returned tinyInfo must be always the same. + MEDCOUPLING_EXPORT void getTinySerializationInformation(std::vector<double>& tinyInfoD, std::vector<int>& tinyInfo, std::vector<std::string>& littleStrings) const; + MEDCOUPLING_EXPORT bool isEmptyMesh(const std::vector<int>& tinyInfo) const; + MEDCOUPLING_EXPORT void resizeForUnserialization(const std::vector<int>& tinyInfo, DataArrayInt *a1, DataArrayDouble *a2, std::vector<std::string>& littleStrings) const; + MEDCOUPLING_EXPORT void serialize(DataArrayInt *&a1, DataArrayDouble *&a2) const; + MEDCOUPLING_EXPORT void unserialization(const std::vector<double>& tinyInfoD, const std::vector<int>& tinyInfo, const DataArrayInt *a1, DataArrayDouble *a2, const std::vector<std::string>& littleStrings); + MEDCOUPLING_EXPORT std::string getVTKDataSetType() const; + MEDCOUPLING_EXPORT std::string getVTKFileExtension() const; + MEDCOUPLING_EXPORT void writeVTKLL(std::ostream& ofs, const std::string& cellData, const std::string& pointData, DataArrayByte *byteData) const; + MEDCOUPLING_EXPORT void reprQuickOverview(std::ostream& stream) const; + //tools + MEDCOUPLING_EXPORT static int AreCellsEqual(const int *conn, const int *connI, int cell1, int cell2, int compType); + MEDCOUPLING_EXPORT static int AreCellsEqual0(const int *conn, const int *connI, int cell1, int cell2); + MEDCOUPLING_EXPORT static int AreCellsEqual1(const int *conn, const int *connI, int cell1, int cell2); + MEDCOUPLING_EXPORT static int AreCellsEqual2(const int *conn, const int *connI, int cell1, int cell2); + MEDCOUPLING_EXPORT static int AreCellsEqual3(const int *conn, const int *connI, int cell1, int cell2); + MEDCOUPLING_EXPORT static int AreCellsEqual7(const int *conn, const int *connI, int cell1, int cell2); + MEDCOUPLING_EXPORT void convertToPolyTypes(const int *cellIdsToConvertBg, const int *cellIdsToConvertEnd); + MEDCOUPLING_EXPORT void convertAllToPoly(); + MEDCOUPLING_EXPORT void convertExtrudedPolyhedra(); + MEDCOUPLING_EXPORT bool unPolyze(); + MEDCOUPLING_EXPORT void simplifyPolyhedra(double eps); + MEDCOUPLING_EXPORT MEDCouplingUMesh *buildSpreadZonesWithPoly() const; + MEDCOUPLING_EXPORT std::vector<DataArrayInt *> partitionBySpreadZone() const; + MEDCOUPLING_EXPORT DataArrayInt *computeFetchedNodeIds() const; + MEDCOUPLING_EXPORT DataArrayInt *getNodeIdsInUse(int& nbrOfNodesInUse) const; + MEDCOUPLING_EXPORT void computeNodeIdsAlg(std::vector<bool>& nodeIdsInUse) const; + MEDCOUPLING_EXPORT DataArrayInt *computeNbOfNodesPerCell() const; + MEDCOUPLING_EXPORT DataArrayInt *computeNbOfFacesPerCell() const; + MEDCOUPLING_EXPORT DataArrayInt *computeEffectiveNbOfNodesPerCell() const; + MEDCOUPLING_EXPORT DataArrayInt *zipCoordsTraducer(); + MEDCOUPLING_EXPORT void findCommonCells(int compType, int startCellId, DataArrayInt *& commonCellsArr, DataArrayInt *& commonCellsIArr) const; + MEDCOUPLING_EXPORT bool areCellsIncludedIn(const MEDCouplingUMesh *other, int compType, DataArrayInt *& arr) const; + MEDCOUPLING_EXPORT bool areCellsIncludedIn2(const MEDCouplingUMesh *other, DataArrayInt *& arr) const; + MEDCOUPLING_EXPORT void getReverseNodalConnectivity(DataArrayInt *revNodal, DataArrayInt *revNodalIndx) const; + MEDCOUPLING_EXPORT MEDCouplingUMesh *explode3DMeshTo1D(DataArrayInt *desc, DataArrayInt *descIndx, DataArrayInt *revDesc, DataArrayInt *revDescIndx) const; + MEDCOUPLING_EXPORT MEDCouplingUMesh *buildDescendingConnectivity(DataArrayInt *desc, DataArrayInt *descIndx, DataArrayInt *revDesc, DataArrayInt *revDescIndx) const; + MEDCOUPLING_EXPORT MEDCouplingUMesh *buildDescendingConnectivity2(DataArrayInt *desc, DataArrayInt *descIndx, DataArrayInt *revDesc, DataArrayInt *revDescIndx) const; + MEDCOUPLING_EXPORT void computeNeighborsOfCells(DataArrayInt *&neighbors, DataArrayInt *&neighborsIdx) const; + MEDCOUPLING_EXPORT static void ComputeNeighborsOfCellsAdv(const DataArrayInt *desc, const DataArrayInt *descI, const DataArrayInt *revDesc, const DataArrayInt *revDescI, + DataArrayInt *&neighbors, DataArrayInt *&neighborsIdx); + MEDCOUPLING_EXPORT void computeNeighborsOfNodes(DataArrayInt *&neighbors, DataArrayInt *&neighborsIdx) const; + MEDCOUPLING_EXPORT MEDCouplingPointSet *mergeMyselfWithOnSameCoords(const MEDCouplingPointSet *other) const; + MEDCOUPLING_EXPORT MEDCouplingPointSet *buildPartOfMySelf(const int *begin, const int *end, bool keepCoords=true) const; + MEDCOUPLING_EXPORT MEDCouplingPointSet *buildPartOfMySelf2(int start, int end, int step, bool keepCoords=true) const; + MEDCOUPLING_EXPORT void setPartOfMySelf(const int *cellIdsBg, const int *cellIdsEnd, const MEDCouplingUMesh& otherOnSameCoordsThanThis); + MEDCOUPLING_EXPORT void setPartOfMySelf2(int start, int end, int step, const MEDCouplingUMesh& otherOnSameCoordsThanThis); + MEDCOUPLING_EXPORT MEDCouplingPointSet *buildFacePartOfMySelfNode(const int *begin, const int *end, bool fullyIn) const; + MEDCOUPLING_EXPORT MEDCouplingUMesh *buildUnstructured() const; + MEDCOUPLING_EXPORT DataArrayInt *findBoundaryNodes() const; + MEDCOUPLING_EXPORT MEDCouplingPointSet *buildBoundaryMesh(bool keepCoords) const; + MEDCOUPLING_EXPORT DataArrayInt *findCellIdsOnBoundary() const; + MEDCOUPLING_EXPORT void findCellIdsLyingOn(const MEDCouplingUMesh& otherDimM1OnSameCoords, DataArrayInt *&cellIdsRk0, DataArrayInt *&cellIdsRk1) const; + MEDCOUPLING_EXPORT MEDCouplingUMesh *computeSkin() const; + MEDCOUPLING_EXPORT void findNodesToDuplicate(const MEDCouplingUMesh& otherDimM1OnSameCoords, DataArrayInt *& nodeIdsToDuplicate, + DataArrayInt *& cellIdsNeededToBeRenum, DataArrayInt *& cellIdsNotModified) const; + MEDCOUPLING_EXPORT void duplicateNodes(const int *nodeIdsToDuplicateBg, const int *nodeIdsToDuplicateEnd); + MEDCOUPLING_EXPORT void renumberNodesWithOffsetInConn(int offset); + MEDCOUPLING_EXPORT void renumberNodesInConn(const INTERP_KERNEL::HashMap<int,int>& newNodeNumbersO2N); + MEDCOUPLING_EXPORT void renumberNodesInConn(const int *newNodeNumbersO2N); + MEDCOUPLING_EXPORT void shiftNodeNumbersInConn(int delta); + MEDCOUPLING_EXPORT void duplicateNodesInConn(const int *nodeIdsToDuplicateBg, const int *nodeIdsToDuplicateEnd, int offset); + MEDCOUPLING_EXPORT void renumberCells(const int *old2NewBg, bool check=true); + MEDCOUPLING_EXPORT DataArrayInt *getCellsInBoundingBox(const double *bbox, double eps) const; + MEDCOUPLING_EXPORT DataArrayInt *getCellsInBoundingBox(const INTERP_KERNEL::DirectedBoundingBox& bbox, double eps); + MEDCOUPLING_EXPORT MEDCouplingFieldDouble *getMeasureField(bool isAbs) const; + MEDCOUPLING_EXPORT DataArrayDouble *getPartMeasureField(bool isAbs, const int *begin, const int *end) const; + MEDCOUPLING_EXPORT MEDCouplingFieldDouble *getMeasureFieldOnNode(bool isAbs) const; + MEDCOUPLING_EXPORT MEDCouplingFieldDouble *buildOrthogonalField() const; + MEDCOUPLING_EXPORT MEDCouplingFieldDouble *buildPartOrthogonalField(const int *begin, const int *end) const; + MEDCOUPLING_EXPORT MEDCouplingFieldDouble *buildDirectionVectorField() const; + MEDCOUPLING_EXPORT MEDCouplingUMesh *buildSlice3D(const double *origin, const double *vec, double eps, DataArrayInt *&cellIds) const; + MEDCOUPLING_EXPORT MEDCouplingUMesh *buildSlice3DSurf(const double *origin, const double *vec, double eps, DataArrayInt *&cellIds) const; + MEDCOUPLING_EXPORT DataArrayInt *getCellIdsCrossingPlane(const double *origin, const double *vec, double eps) const; + MEDCOUPLING_EXPORT bool isContiguous1D() const; + MEDCOUPLING_EXPORT void project1D(const double *pt, const double *v, double eps, double *res) const; + MEDCOUPLING_EXPORT double distanceToPoint(const double *ptBg, const double *ptEnd, int& cellId) const; + MEDCOUPLING_EXPORT DataArrayDouble *distanceToPoints(const DataArrayDouble *pts, DataArrayInt *& cellIds) const; + MEDCOUPLING_EXPORT int getCellContainingPoint(const double *pos, double eps) const; + MEDCOUPLING_EXPORT void getCellsContainingPoint(const double *pos, double eps, std::vector<int>& elts) const; + MEDCOUPLING_EXPORT void getCellsContainingPoints(const double *pos, int nbOfPoints, double eps, MEDCouplingAutoRefCountObjectPtr<DataArrayInt>& elts, MEDCouplingAutoRefCountObjectPtr<DataArrayInt>& eltsIndex) const; + MEDCOUPLING_EXPORT void checkButterflyCells(std::vector<int>& cells, double eps=1e-12) const; + MEDCOUPLING_EXPORT DataArrayInt *convexEnvelop2D(); + MEDCOUPLING_EXPORT DataArrayInt *findAndCorrectBadOriented3DExtrudedCells(); + MEDCOUPLING_EXPORT DataArrayInt *findAndCorrectBadOriented3DCells(); + MEDCOUPLING_EXPORT DataArrayDouble *getBoundingBoxForBBTree(double arcDetEps=1e-12) const; + MEDCOUPLING_EXPORT DataArrayDouble *getBoundingBoxForBBTreeFast() const; + MEDCOUPLING_EXPORT DataArrayDouble *getBoundingBoxForBBTree2DQuadratic(double arcDetEps=1e-12) const; + MEDCOUPLING_EXPORT DataArrayDouble *getBoundingBoxForBBTree1DQuadratic(double arcDetEps=1e-12) const; + MEDCOUPLING_EXPORT MEDCouplingUMesh *buildExtrudedMesh(const MEDCouplingUMesh *mesh1D, int policy); + MEDCOUPLING_EXPORT bool isFullyQuadratic() const; + MEDCOUPLING_EXPORT bool isPresenceOfQuadratic() const; + MEDCOUPLING_EXPORT void convertQuadraticCellsToLinear(); + MEDCOUPLING_EXPORT DataArrayInt *convertLinearCellsToQuadratic(int conversionType=0); + MEDCOUPLING_EXPORT void tessellate2D(double eps); + MEDCOUPLING_EXPORT void tessellate2DCurve(double eps); + MEDCOUPLING_EXPORT MEDCoupling1SGTUMesh *tetrahedrize(int policy, DataArrayInt *& n2oCells, int& nbOfAdditionalPoints) const; + MEDCOUPLING_EXPORT DataArrayInt *simplexize(int policy); + MEDCOUPLING_EXPORT bool areOnlySimplexCells() const; + MEDCOUPLING_EXPORT void convertDegeneratedCells(); + MEDCOUPLING_EXPORT void are2DCellsNotCorrectlyOriented(const double *vec, bool polyOnly, std::vector<int>& cells) const; + MEDCOUPLING_EXPORT void orientCorrectly2DCells(const double *vec, bool polyOnly); + MEDCOUPLING_EXPORT void changeOrientationOfCells(); + MEDCOUPLING_EXPORT void arePolyhedronsNotCorrectlyOriented(std::vector<int>& cells) const; + MEDCOUPLING_EXPORT void orientCorrectlyPolyhedrons(); + MEDCOUPLING_EXPORT void getFastAveragePlaneOfThis(double *vec, double *pos) const; + //Mesh quality + MEDCOUPLING_EXPORT MEDCouplingFieldDouble *getEdgeRatioField() const; + MEDCOUPLING_EXPORT MEDCouplingFieldDouble *getAspectRatioField() const; + MEDCOUPLING_EXPORT MEDCouplingFieldDouble *getWarpField() const; + MEDCOUPLING_EXPORT MEDCouplingFieldDouble *getSkewField() const; + MEDCOUPLING_EXPORT MEDCouplingFieldDouble *computeDiameterField() const; + //utilities for MED File RW + MEDCOUPLING_EXPORT std::vector<int> getDistributionOfTypes() const; + MEDCOUPLING_EXPORT DataArrayInt *checkTypeConsistencyAndContig(const std::vector<int>& code, const std::vector<const DataArrayInt *>& idsPerType) const; + MEDCOUPLING_EXPORT void splitProfilePerType(const DataArrayInt *profile, std::vector<int>& code, std::vector<DataArrayInt *>& idsInPflPerType, std::vector<DataArrayInt *>& idsPerType) const; + MEDCOUPLING_EXPORT MEDCouplingUMesh *emulateMEDMEMBDC(const MEDCouplingUMesh *nM1LevMesh, DataArrayInt *desc, DataArrayInt *descIndx, DataArrayInt *&revDesc, DataArrayInt *&revDescIndx, DataArrayInt *& nM1LevMeshIds, DataArrayInt *&meshnM1Old2New) const; + MEDCOUPLING_EXPORT DataArrayInt *sortCellsInMEDFileFrmt(); + MEDCOUPLING_EXPORT bool checkConsecutiveCellTypes() const; + MEDCOUPLING_EXPORT bool checkConsecutiveCellTypesForMEDFileFrmt() const; + MEDCOUPLING_EXPORT bool checkConsecutiveCellTypesAndOrder(const INTERP_KERNEL::NormalizedCellType *orderBg, const INTERP_KERNEL::NormalizedCellType *orderEnd) const; + MEDCOUPLING_EXPORT DataArrayInt *getLevArrPerCellTypes(const INTERP_KERNEL::NormalizedCellType *orderBg, const INTERP_KERNEL::NormalizedCellType *orderEnd, DataArrayInt *&nbPerType) const; + MEDCOUPLING_EXPORT DataArrayInt *getRenumArrForMEDFileFrmt() const; + MEDCOUPLING_EXPORT DataArrayInt *getRenumArrForConsecutiveCellTypesSpec(const INTERP_KERNEL::NormalizedCellType *orderBg, const INTERP_KERNEL::NormalizedCellType *orderEnd) const; + MEDCOUPLING_EXPORT DataArrayInt *rearrange2ConsecutiveCellTypes(); + MEDCOUPLING_EXPORT std::vector<MEDCouplingUMesh *> splitByType() const; + MEDCOUPLING_EXPORT MEDCoupling1GTUMesh *convertIntoSingleGeoTypeMesh() const; + MEDCOUPLING_EXPORT DataArrayInt *convertNodalConnectivityToStaticGeoTypeMesh() const; + MEDCOUPLING_EXPORT void convertNodalConnectivityToDynamicGeoTypeMesh(DataArrayInt *&nodalConn, DataArrayInt *&nodalConnIndex) const; + MEDCOUPLING_EXPORT static MEDCouplingUMesh *AggregateSortedByTypeMeshesOnSameCoords(const std::vector<const MEDCouplingUMesh *>& ms, + DataArrayInt *&szOfCellGrpOfSameType, + DataArrayInt *&idInMsOfCellGrpOfSameType); + MEDCOUPLING_EXPORT DataArrayInt *keepCellIdsByType(INTERP_KERNEL::NormalizedCellType type, const int *begin, const int *end) const; + MEDCOUPLING_EXPORT DataArrayInt *convertCellArrayPerGeoType(const DataArrayInt *da) const; + MEDCOUPLING_EXPORT MEDCouplingUMesh *keepSpecifiedCells(INTERP_KERNEL::NormalizedCellType type, const int *idsPerGeoTypeBg, const int *idsPerGeoTypeEnd) const; + MEDCOUPLING_EXPORT std::vector<bool> getQuadraticStatus() const; + // + MEDCOUPLING_EXPORT MEDCouplingMesh *mergeMyselfWith(const MEDCouplingMesh *other) const; + MEDCOUPLING_EXPORT DataArrayDouble *getBarycenterAndOwner() const; + MEDCOUPLING_EXPORT DataArrayDouble *computeIsoBarycenterOfNodesPerCell() const; + MEDCOUPLING_EXPORT DataArrayDouble *getPartBarycenterAndOwner(const int *begin, const int *end) const; + MEDCOUPLING_EXPORT DataArrayDouble *computePlaneEquationOf3DFaces() const; + MEDCOUPLING_EXPORT DataArrayInt *conformize2D(double eps); + MEDCOUPLING_EXPORT DataArrayInt *colinearize2D(double eps); + MEDCOUPLING_EXPORT int split2DCells(const DataArrayInt *desc, const DataArrayInt *descI, const DataArrayInt *subNodesInSeg, const DataArrayInt *subNodesInSegI, const DataArrayInt *midOpt=0, const DataArrayInt *midOptI=0); + MEDCOUPLING_EXPORT static MEDCouplingUMesh *Build0DMeshFromCoords(DataArrayDouble *da); + MEDCOUPLING_EXPORT static MEDCouplingUMesh *MergeUMeshes(const MEDCouplingUMesh *mesh1, const MEDCouplingUMesh *mesh2); + MEDCOUPLING_EXPORT static MEDCouplingUMesh *MergeUMeshes(std::vector<const MEDCouplingUMesh *>& a); + MEDCOUPLING_EXPORT static MEDCouplingUMesh *MergeUMeshesOnSameCoords(const MEDCouplingUMesh *mesh1, const MEDCouplingUMesh *mesh2); + MEDCOUPLING_EXPORT static MEDCouplingUMesh *MergeUMeshesOnSameCoords(const std::vector<const MEDCouplingUMesh *>& meshes); + MEDCOUPLING_EXPORT static MEDCouplingUMesh *FuseUMeshesOnSameCoords(const std::vector<const MEDCouplingUMesh *>& meshes, int compType, std::vector<DataArrayInt *>& corr); + MEDCOUPLING_EXPORT static void PutUMeshesOnSameAggregatedCoords(const std::vector<MEDCouplingUMesh *>& meshes); + MEDCOUPLING_EXPORT static void MergeNodesOnUMeshesSharingSameCoords(const std::vector<MEDCouplingUMesh *>& meshes, double eps); + MEDCOUPLING_EXPORT static bool IsPolygonWellOriented(bool isQuadratic, const double *vec, const int *begin, const int *end, const double *coords); + MEDCOUPLING_EXPORT static bool IsPolyhedronWellOriented(const int *begin, const int *end, const double *coords); + MEDCOUPLING_EXPORT static bool Is3DExtrudedStaticCellWellOriented(const int *begin, const int *end, const double *coords); + MEDCOUPLING_EXPORT static void CorrectExtrudedStaticCell(int *begin, int *end); + MEDCOUPLING_EXPORT static bool IsTetra4WellOriented(const int *begin, const int *end, const double *coords); + MEDCOUPLING_EXPORT static bool IsPyra5WellOriented(const int *begin, const int *end, const double *coords); + MEDCOUPLING_EXPORT static void SimplifyPolyhedronCell(double eps, const DataArrayDouble *coords, const int *begin, const int *end, DataArrayInt *res); + MEDCOUPLING_EXPORT static void ComputeVecAndPtOfFace(double eps, const double *coords, const int *begin, const int *end, double *v, double *p); + MEDCOUPLING_EXPORT static void TryToCorrectPolyhedronOrientation(int *begin, int *end, const double *coords); + MEDCOUPLING_EXPORT static MEDCouplingUMesh *Intersect2DMeshes(const MEDCouplingUMesh *m1, const MEDCouplingUMesh *m2, double eps, DataArrayInt *&cellNb1, DataArrayInt *&cellNb2); + MEDCOUPLING_EXPORT static void Intersect2DMeshWith1DLine(const MEDCouplingUMesh *mesh2D, const MEDCouplingUMesh *mesh1D, + double eps, MEDCouplingUMesh *&splitMesh2D, MEDCouplingUMesh *&splitMesh1D, DataArrayInt *&cellIdInMesh2D, DataArrayInt *&cellIdInMesh1D); + MEDCOUPLING_EXPORT static bool BuildConvexEnvelopOf2DCellJarvis(const double *coords, const int *nodalConnBg, const int *nodalConnEnd, DataArrayInt *nodalConnecOut); + MEDCOUPLING_EXPORT static bool RemoveIdsFromIndexedArrays(const int *idsToRemoveBg, const int *idsToRemoveEnd, DataArrayInt *arr, DataArrayInt *arrIndx, int offsetForRemoval=0); + MEDCOUPLING_EXPORT static void ExtractFromIndexedArrays(const int *idsOfSelectBg, const int *idsOfSelectEnd, const DataArrayInt *arrIn, const DataArrayInt *arrIndxIn, + DataArrayInt* &arrOut, DataArrayInt* &arrIndexOut); + MEDCOUPLING_EXPORT static void ExtractFromIndexedArrays2(int idsOfSelectStart, int idsOfSelectStop, int idsOfSelectStep, const DataArrayInt *arrIn, const DataArrayInt *arrIndxIn, + DataArrayInt* &arrOut, DataArrayInt* &arrIndexOut); + MEDCOUPLING_EXPORT static void SetPartOfIndexedArrays(const int *idsOfSelectBg, const int *idsOfSelectEnd, const DataArrayInt *arrIn, const DataArrayInt *arrIndxIn, + const DataArrayInt *srcArr, const DataArrayInt *srcArrIndex, + DataArrayInt* &arrOut, DataArrayInt* &arrIndexOut); + MEDCOUPLING_EXPORT static void SetPartOfIndexedArraysSameIdx(const int *idsOfSelectBg, const int *idsOfSelectEnd, DataArrayInt *arrInOut, const DataArrayInt *arrIndxIn, + const DataArrayInt *srcArr, const DataArrayInt *srcArrIndex); + MEDCOUPLING_EXPORT static void SetPartOfIndexedArrays2(int start, int end, int step, const DataArrayInt *arrIn, const DataArrayInt *arrIndxIn, + const DataArrayInt *srcArr, const DataArrayInt *srcArrIndex, + DataArrayInt* &arrOut, DataArrayInt* &arrIndexOut); + MEDCOUPLING_EXPORT static void SetPartOfIndexedArraysSameIdx2(int start, int end, int step, DataArrayInt *arrInOut, const DataArrayInt *arrIndxIn, + const DataArrayInt *srcArr, const DataArrayInt *srcArrIndex); + MEDCOUPLING_EXPORT static DataArrayInt *ComputeSpreadZoneGradually(const DataArrayInt *arrIn, const DataArrayInt *arrIndxIn); + MEDCOUPLING_EXPORT static DataArrayInt *ComputeSpreadZoneGraduallyFromSeed(const int *seedBg, const int *seedEnd, const DataArrayInt *arrIn, const DataArrayInt *arrIndxIn, int nbOfDepthPeeling, int& nbOfDepthPeelingPerformed); + MEDCOUPLING_EXPORT static void FindCommonCellsAlg(int compType, int startCellId, const DataArrayInt *nodal, const DataArrayInt *nodalI, const DataArrayInt *revNodal, const DataArrayInt *revNodalI, + DataArrayInt *& commonCellsArr, DataArrayInt *& commonCellsIArr); + MEDCOUPLING_EXPORT DataArrayInt *buildUnionOf2DMesh() const; + MEDCOUPLING_EXPORT DataArrayInt *buildUnionOf3DMesh() const; + MEDCOUPLING_EXPORT DataArrayInt *orderConsecutiveCells1D() const; + MEDCOUPLING_EXPORT MEDCouplingSkyLineArray *generateGraph() const; + private: + MEDCouplingUMesh(); + MEDCouplingUMesh(const MEDCouplingUMesh& other, bool deepCopy); + ~MEDCouplingUMesh(); + void checkFullyDefined() const; + void checkConnectivityFullyDefined() const; + void reprConnectivityOfThisLL(std::ostringstream& stream) const; + //tools + DataArrayInt *simplexizePol0(); + DataArrayInt *simplexizePol1(); + DataArrayInt *simplexizePlanarFace5(); + DataArrayInt *simplexizePlanarFace6(); + void subDivide2DMesh(const int *nodeSubdived, const int *nodeIndxSubdived, const int *desc, const int *descIndex); + void fillCellIdsToKeepFromNodeIds(const int *begin, const int *end, bool fullyIn, DataArrayInt *&cellIdsKeptArr) const; + void split3DCurveWithPlane(const double *origin, const double *vec, double eps, std::vector<int>& cut3DCurve); + MEDCouplingUMesh *buildExtrudedMeshFromThisLowLev(int nbOfNodesOf1Lev, bool isQuad) const; + DataArrayDouble *fillExtCoordsUsingTranslation(const MEDCouplingUMesh *mesh1D, bool isQuad) const; + DataArrayDouble *fillExtCoordsUsingTranslAndAutoRotation(const MEDCouplingUMesh *mesh1D, bool isQuad) const; + DataArrayDouble *fillExtCoordsUsingTranslAndAutoRotation2D(const MEDCouplingUMesh *mesh1D, bool isQuad) const; + DataArrayDouble *fillExtCoordsUsingTranslAndAutoRotation3D(const MEDCouplingUMesh *mesh1D, bool isQuad) const; + static bool AreCellsEqualInPool(const std::vector<int>& candidates, int compType, const int *conn, const int *connI, DataArrayInt *result) ; + MEDCouplingPointSet *buildPartOfMySelfKeepCoords(const int *begin, const int *end) const; + MEDCouplingPointSet *buildPartOfMySelfKeepCoords2(int start, int end, int step) const; + DataArrayInt *convertLinearCellsToQuadratic1D0(DataArrayInt *&conn, DataArrayInt *&connI, DataArrayDouble *& coords, std::set<INTERP_KERNEL::NormalizedCellType>& types) const; + DataArrayInt *convertLinearCellsToQuadratic2DAnd3D0(const MEDCouplingUMesh *m1D, const DataArrayInt *desc, const DataArrayInt *descI, DataArrayInt *&conn, DataArrayInt *&connI, DataArrayDouble *& coords, std::set<INTERP_KERNEL::NormalizedCellType>& types) const; + DataArrayInt *convertLinearCellsToQuadratic2D0(DataArrayInt *&conn, DataArrayInt *&connI, DataArrayDouble *& coords, std::set<INTERP_KERNEL::NormalizedCellType>& types) const; + DataArrayInt *convertLinearCellsToQuadratic2D1(DataArrayInt *&conn, DataArrayInt *&connI, DataArrayDouble *& coords, std::set<INTERP_KERNEL::NormalizedCellType>& types) const; + DataArrayInt *convertLinearCellsToQuadratic3D0(DataArrayInt *&conn, DataArrayInt *&connI, DataArrayDouble *& coords, std::set<INTERP_KERNEL::NormalizedCellType>& types) const; + DataArrayInt *convertLinearCellsToQuadratic3D1(DataArrayInt *&conn, DataArrayInt *&connI, DataArrayDouble *& coords, std::set<INTERP_KERNEL::NormalizedCellType>& types) const; + DataArrayInt *buildUnionOf2DMeshLinear(const MEDCouplingUMesh *skin, const DataArrayInt *n2o) const; + DataArrayInt *buildUnionOf2DMeshQuadratic(const MEDCouplingUMesh *skin, const DataArrayInt *n2o) const; + template<int SPACEDIM> + void getCellsContainingPointsAlg(const double *coords, const double *pos, int nbOfPoints, + double eps, MEDCouplingAutoRefCountObjectPtr<DataArrayInt>& elts, MEDCouplingAutoRefCountObjectPtr<DataArrayInt>& eltsIndex) const; +/// @cond INTERNAL + static MEDCouplingUMesh *MergeUMeshesLL(std::vector<const MEDCouplingUMesh *>& a); + typedef int (*DimM1DescNbrer)(int id, unsigned nb, const INTERP_KERNEL::CellModel& cm, bool compute, const int *conn1, const int *conn2); + template<class SonsGenerator> + MEDCouplingUMesh *buildDescendingConnectivityGen(DataArrayInt *desc, DataArrayInt *descIndx, DataArrayInt *revDesc, DataArrayInt *revDescIndx, DimM1DescNbrer nbrer) const; + static void DistanceToPoint3DSurfAlg(const double *pt, const int *cellIdsBg, const int *cellIdsEnd, const double *coords, const int *nc, const int *ncI, double& ret0, int& cellId); + static void DistanceToPoint2DCurveAlg(const double *pt, const int *cellIdsBg, const int *cellIdsEnd, const double *coords, const int *nc, const int *ncI, double& ret0, int& cellId); + static DataArrayInt *ComputeSpreadZoneGraduallyFromSeedAlg(std::vector<bool>& fetched, const int *seedBg, const int *seedEnd, const DataArrayInt *arrIn, const DataArrayInt *arrIndxIn, int nbOfDepthPeeling, int& nbOfDepthPeelingPerformed); + static void FillInCompact3DMode(int spaceDim, int nbOfNodesInCell, const int *conn, const double *coo, double *zipFrmt); + static void AppendExtrudedCell(const int *connBg, const int *connEnd, int nbOfNodesPerLev, bool isQuad, std::vector<int>& ret); + static void Intersect1DMeshes(const MEDCouplingUMesh *m1Desc, const MEDCouplingUMesh *m2Desc, double eps, std::vector< std::vector<int> >& intersectEdge1, std::vector< std::vector<int> >& colinear2, std::vector< std::vector<int> >& subDiv2, std::vector<double>& addCoo, std::map<int,int>& mergedNodes); + static void IntersectDescending2DMeshes(const MEDCouplingUMesh *m1, const MEDCouplingUMesh *m2, double eps, + std::vector< std::vector<int> >& intersectEdge1, std::vector< std::vector<int> >& colinear2, std::vector< std::vector<int> >& subDiv2, + MEDCouplingUMesh *& m1Desc, DataArrayInt *&desc1, DataArrayInt *&descIndx1, DataArrayInt *&revDesc1, DataArrayInt *&revDescIndx1, + std::vector<double>& addCoo, + MEDCouplingUMesh *& m2Desc, DataArrayInt *&desc2, DataArrayInt *&descIndx2, DataArrayInt *&revDesc2, DataArrayInt *&revDescIndx2); + static void BuildIntersectEdges(const MEDCouplingUMesh *m1, const MEDCouplingUMesh *m2, const std::vector<double>& addCoo, const std::vector< std::vector<int> >& subDiv, std::vector< std::vector<int> >& intersectEdge); + static void BuildIntersecting2DCellsFromEdges(double eps, const MEDCouplingUMesh *m1, const int *desc1, const int *descIndx1, const std::vector<std::vector<int> >& intesctEdges1, const std::vector< std::vector<int> >& colinear2, + const MEDCouplingUMesh *m2, const int *desc2, const int *descIndx2, const std::vector<std::vector<int> >& intesctEdges2, + const std::vector<double>& addCoords, + std::vector<double>& addCoordsQuadratic, std::vector<int>& cr, std::vector<int>& crI, std::vector<int>& cNb1, std::vector<int>& cNb2); + static void AssemblyForSplitFrom3DCurve(const std::vector<int>& cut3DCurve, std::vector<int>& nodesOnPlane, const int *nodal3DSurf, const int *nodalIndx3DSurf, + const int *nodal3DCurve, const int *nodalIndx3DCurve, + const int *desc, const int *descIndx, std::vector< std::pair<int,int> >& cut3DSurf); + void assemblyForSplitFrom3DSurf(const std::vector< std::pair<int,int> >& cut3DSurf, + const int *desc, const int *descIndx, DataArrayInt *nodalRes, DataArrayInt *nodalResIndx, DataArrayInt *cellIds) const; + void split2DCellsLinear(const DataArrayInt *desc, const DataArrayInt *descI, const DataArrayInt *subNodesInSeg, const DataArrayInt *subNodesInSegI); + int split2DCellsQuadratic(const DataArrayInt *desc, const DataArrayInt *descI, const DataArrayInt *subNodesInSeg, const DataArrayInt *subNodesInSegI, const DataArrayInt *mid, const DataArrayInt *midI); + static bool Colinearize2DCell(const double *coords, const int *connBg, const int *connEnd, int offset, DataArrayInt *newConnOfCell, DataArrayDouble *appendedCoords); + static void ComputeAllTypesInternal(std::set<INTERP_KERNEL::NormalizedCellType>& types, const DataArrayInt *nodalConnec, const DataArrayInt *nodalConnecIndex); + public: + MEDCOUPLING_EXPORT static DataArrayInt *ComputeRangesFromTypeDistribution(const std::vector<int>& code); + MEDCOUPLING_EXPORT static const int N_MEDMEM_ORDER=24; + MEDCOUPLING_EXPORT static const INTERP_KERNEL::NormalizedCellType MEDMEM_ORDER[N_MEDMEM_ORDER]; + /// @endcond + private: + int _mesh_dim; + DataArrayInt *_nodal_connec; + DataArrayInt *_nodal_connec_index; + std::set<INTERP_KERNEL::NormalizedCellType> _types; + public: + static double EPS_FOR_POLYH_ORIENTATION; + }; + + class MEDCouplingUMeshCell; + + class MEDCouplingUMeshCellIterator + { + public: + MEDCOUPLING_EXPORT MEDCouplingUMeshCellIterator(MEDCouplingUMesh *mesh); + MEDCOUPLING_EXPORT MEDCouplingUMeshCellIterator(MEDCouplingUMesh *mesh, MEDCouplingUMeshCell *itc, int bg, int end); + MEDCOUPLING_EXPORT ~MEDCouplingUMeshCellIterator(); + MEDCOUPLING_EXPORT MEDCouplingUMeshCell *nextt(); + private: + MEDCouplingUMesh *_mesh; + MEDCouplingUMeshCell *_cell; + bool _own_cell; + int _cell_id; + int _nb_cell; + }; + + class MEDCouplingUMeshCellByTypeIterator; + + class MEDCouplingUMeshCellByTypeEntry + { + public: + MEDCOUPLING_EXPORT MEDCouplingUMeshCellByTypeEntry(MEDCouplingUMesh *mesh); + MEDCOUPLING_EXPORT MEDCouplingUMeshCellByTypeIterator *iterator(); + MEDCOUPLING_EXPORT ~MEDCouplingUMeshCellByTypeEntry(); + private: + MEDCouplingUMesh *_mesh; + }; + + class MEDCouplingUMeshCellEntry + { + public: + MEDCOUPLING_EXPORT MEDCouplingUMeshCellEntry(MEDCouplingUMesh *mesh, INTERP_KERNEL::NormalizedCellType type, MEDCouplingUMeshCell *itc, int bg, int end); + MEDCOUPLING_EXPORT ~MEDCouplingUMeshCellEntry(); + MEDCOUPLING_EXPORT INTERP_KERNEL::NormalizedCellType getType() const; + MEDCOUPLING_EXPORT int getNumberOfElems() const; + MEDCOUPLING_EXPORT MEDCouplingUMeshCellIterator *iterator(); + private: + MEDCouplingUMesh *_mesh; + INTERP_KERNEL::NormalizedCellType _type; + MEDCouplingUMeshCell *_itc; + int _bg; + int _end; + }; + + class MEDCouplingUMeshCellByTypeIterator + { + public: + MEDCOUPLING_EXPORT MEDCouplingUMeshCellByTypeIterator(MEDCouplingUMesh *mesh); + MEDCOUPLING_EXPORT ~MEDCouplingUMeshCellByTypeIterator(); + MEDCOUPLING_EXPORT MEDCouplingUMeshCellEntry *nextt(); + private: + MEDCouplingUMesh *_mesh; + MEDCouplingUMeshCell *_cell; + int _cell_id; + int _nb_cell; + }; + + class MEDCouplingUMeshCell + { + public: + MEDCOUPLING_EXPORT MEDCouplingUMeshCell(MEDCouplingUMesh *mesh); + MEDCOUPLING_EXPORT void next(); + MEDCOUPLING_EXPORT std::string repr() const; + MEDCOUPLING_EXPORT INTERP_KERNEL::NormalizedCellType getType() const; + MEDCOUPLING_EXPORT const int *getAllConn(int& lgth) const; + private: + int *_conn; + int *_conn_indx; + int _conn_lgth; + static const int NOTICABLE_FIRST_VAL=-7; + }; +} + +#endif diff --git a/src/medtool/src/MEDCoupling/Test/CMakeLists.txt b/src/medtool/src/MEDCoupling/Test/CMakeLists.txt new file mode 100644 index 000000000..2b8adefc7 --- /dev/null +++ b/src/medtool/src/MEDCoupling/Test/CMakeLists.txt @@ -0,0 +1,85 @@ +# Copyright (C) 2012-2015 CEA/DEN, EDF 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, 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 +# 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) + +ADD_DEFINITIONS(${CPPUNIT_DEFINITIONS}) + +INCLUDE_DIRECTORIES( + ${CPPUNIT_INCLUDE_DIRS} + ${PTHREADS_INCLUDE_DIRS} + ${CMAKE_CURRENT_SOURCE_DIR}/.. + ${CMAKE_CURRENT_SOURCE_DIR}/../../INTERP_KERNEL + ${CMAKE_CURRENT_SOURCE_DIR}/../../INTERP_KERNEL/Bases + ${CMAKE_CURRENT_SOURCE_DIR}/../../INTERP_KERNEL/Geometric2D + ${CMAKE_CURRENT_SOURCE_DIR}/../../INTERP_KERNEL/ExprEval + ${CMAKE_CURRENT_SOURCE_DIR}/../../INTERP_KERNEL/GaussPoints + ${CMAKE_CURRENT_SOURCE_DIR}/../../INTERP_KERNELTest + ) + +SET(TestMEDCoupling_SOURCES + MEDCouplingBasicsTestInterp.cxx + TestMEDCoupling.cxx + MEDCouplingBasicsTest0.cxx + MEDCouplingBasicsTest1.cxx + MEDCouplingBasicsTest2.cxx + MEDCouplingBasicsTest3.cxx + MEDCouplingBasicsTest4.cxx + MEDCouplingBasicsTest5.cxx + ) + +SET(TestMEDCouplingRemapper_SOURCES + TestMEDCouplingRemapper.cxx + MEDCouplingRemapperTest.cxx + MEDCouplingBasicsTest0.cxx + ) + +SET(TestMEDCouplingExamples_SOURCES + MEDCouplingExamplesTest.cxx + MEDCouplingBasicsTest0.cxx + ) + +#SALOME_GENERATE_TESTS_ENVIRONMENT(tests_env) + +ADD_EXECUTABLE(TestMEDCoupling ${TestMEDCoupling_SOURCES}) +TARGET_LINK_LIBRARIES(TestMEDCoupling medcoupling ${CPPUNIT_LIBRARIES} ${PLATFORM_LIBS}) +ADD_TEST(TestMEDCoupling TestMEDCoupling) +SET_TESTS_PROPERTIES(TestMEDCoupling PROPERTIES ENVIRONMENT "${tests_env}") + +ADD_EXECUTABLE(TestMEDCouplingRemapper ${TestMEDCouplingRemapper_SOURCES}) +TARGET_LINK_LIBRARIES(TestMEDCouplingRemapper medcouplingremapper ${CPPUNIT_LIBRARIES} ${PLATFORM_LIBS}) +ADD_TEST(TestMEDCouplingRemapper TestMEDCouplingRemapper) +SET_TESTS_PROPERTIES(TestMEDCouplingRemapper PROPERTIES ENVIRONMENT "${tests_env}") + +ADD_EXECUTABLE(TestMEDCouplingExamples ${TestMEDCouplingExamples_SOURCES}) +TARGET_LINK_LIBRARIES(TestMEDCouplingExamples medcoupling ${CPPUNIT_LIBRARIES} ${PLATFORM_LIBS}) +ADD_TEST(TestMEDCouplingExamples TestMEDCouplingExamples) +SET_TESTS_PROPERTIES(TestMEDCouplingExamples PROPERTIES ENVIRONMENT "${tests_env}") + +INSTALL(TARGETS TestMEDCoupling TestMEDCouplingRemapper TestMEDCouplingExamples DESTINATION ${MEDTOOL_INSTALL_BINS}) + +SET_DIRECTORY_PROPERTIES(PROPERTIES ADDITIONAL_MAKE_CLEAN_FILES UnitTestsResult) + +# Application tests + +SET(TEST_INSTALL_DIRECTORY ${MEDTOOL_INSTALL_SCRIPT_SCRIPTS}/test/MEDCoupling/MEDCoupling) +INSTALL(TARGETS TestMEDCoupling TestMEDCouplingRemapper TestMEDCouplingExamples DESTINATION ${TEST_INSTALL_DIRECTORY}) + +INSTALL(FILES CTestTestfileInstall.cmake + DESTINATION ${TEST_INSTALL_DIRECTORY} + RENAME CTestTestfile.cmake) diff --git a/src/medtool/src/MEDCoupling/Test/CTestTestfileInstall.cmake b/src/medtool/src/MEDCoupling/Test/CTestTestfileInstall.cmake new file mode 100644 index 000000000..fa82537e4 --- /dev/null +++ b/src/medtool/src/MEDCoupling/Test/CTestTestfileInstall.cmake @@ -0,0 +1,27 @@ +# Copyright (C) 2015 CEA/DEN, EDF 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, 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 +# 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_TEST(TestMEDCoupling TestMEDCoupling) +SET_TESTS_PROPERTIES(TestMEDCoupling PROPERTIES LABELS "${COMPONENT_NAME}") + +ADD_TEST(TestMEDCouplingRemapper TestMEDCouplingRemapper) +SET_TESTS_PROPERTIES(TestMEDCouplingRemapper PROPERTIES LABELS "${COMPONENT_NAME}") + +ADD_TEST(TestMEDCouplingExamples TestMEDCouplingExamples) +SET_TESTS_PROPERTIES(TestMEDCouplingExamples PROPERTIES LABELS "${COMPONENT_NAME}") diff --git a/src/medtool/src/MEDCoupling/Test/MEDCouplingBasicsTest.hxx b/src/medtool/src/MEDCoupling/Test/MEDCouplingBasicsTest.hxx new file mode 100644 index 000000000..be5313b08 --- /dev/null +++ b/src/medtool/src/MEDCoupling/Test/MEDCouplingBasicsTest.hxx @@ -0,0 +1,113 @@ +// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 +// 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 __MEDCOUPLINGBASICSTEST_HXX__ +#define __MEDCOUPLINGBASICSTEST_HXX__ + +#include <cppunit/extensions/HelperMacros.h> + +#include <map> +#include <vector> + +namespace ParaMEDMEM +{ + class DataArrayDouble; + class MEDCouplingUMesh; + class MEDCouplingFieldDouble; + class MEDCouplingMultiFields; + + class MEDCouplingBasicsTest : public CppUnit::TestFixture + { + public: + static MEDCouplingUMesh *build3DSourceMesh_2(); + static MEDCouplingUMesh *build3DTargetMesh_2(); + static MEDCouplingUMesh *build1DTargetMesh_1(); + static MEDCouplingUMesh *build2DSourceMesh_1(); + static MEDCouplingUMesh *build2DTargetMesh_1(); + static MEDCouplingUMesh *build2DTargetMeshPerm_1(); + static MEDCouplingUMesh *build2DTargetMesh_2(); + static MEDCouplingUMesh *buildCU1DMesh_U(); + static MEDCouplingUMesh *buildCU2DMesh_U(); + static MEDCouplingUMesh *buildCU3DMesh_U(); + static MEDCouplingUMesh *build3DSurfSourceMesh_1(); + static MEDCouplingUMesh *build3DSurfSourceMesh_2(); + static MEDCouplingUMesh *build3DSurfTargetMesh_1(); + static MEDCouplingUMesh *build3DSurfTargetMeshPerm_1(); + static MEDCouplingUMesh *build3DSurfTargetMesh_2(); + static MEDCouplingUMesh *build3DSourceMesh_1(); + static MEDCouplingUMesh *build3DTargetMesh_1(); + static MEDCouplingUMesh *build2DTargetMeshMergeNode_1(); + static MEDCouplingUMesh *build3DTargetMeshMergeNode_1(); + static MEDCouplingUMesh *build3DExtrudedUMesh_1(MEDCouplingUMesh *&mesh2D); + static void build3DExtrudedUMesh_2(MEDCouplingUMesh *&meshN, MEDCouplingUMesh *&meshTT, MEDCouplingUMesh *&meshTF); + static MEDCouplingUMesh *build2DTargetMeshMerged_1(); + static MEDCouplingUMesh *build2DCurveMesh(double dx, double dy); + static MEDCouplingUMesh *build1DMesh(double dx); + static MEDCouplingUMesh *build1DSourceMesh_2(); + static MEDCouplingUMesh *build1DTargetMesh_2(); + static MEDCouplingUMesh *build2DCurveSourceMesh_2(); + static MEDCouplingUMesh *build2DCurveTargetMesh_2(); + static MEDCouplingUMesh *build1DTargetMesh_3(); + static MEDCouplingUMesh *build2DCurveTargetMesh_3(); + static MEDCouplingUMesh *build2DTargetMesh_3(); + static MEDCouplingUMesh *build3DTargetMesh_3(); + static MEDCouplingUMesh *build2DTargetMesh_4(); + static MEDCouplingUMesh *build1DMultiTypes_1(); + static MEDCouplingUMesh *build2DMultiTypes_1(); + static MEDCouplingUMesh *build3DMultiTypes_1(); + static MEDCouplingUMesh *buildHexa8Mesh_1(); + static MEDCouplingUMesh *buildPointe_1(MEDCouplingUMesh *&m1); + + static MEDCouplingUMesh *build2D1DSourceMesh(); + static MEDCouplingUMesh *build2D1DTargetMesh(); + static MEDCouplingUMesh *build2D1DSegSourceMesh(const double shiftX = 0., + const double inclinationX = 0.); + static MEDCouplingUMesh *build2D1DQuadTargetMesh(const double inclinaisonX = 0.); + static MEDCouplingUMesh *build2D1DTriTargetMesh(const double inclinaisonX = 0.); + static MEDCouplingUMesh *build3D2DSourceMesh(); + static MEDCouplingUMesh *build3D2DTargetMesh(); + static MEDCouplingUMesh* build3D2DQuadSourceMesh(const double shiftX = 0., + const double inclinationX = 0.); + static MEDCouplingUMesh* build3D2DTriSourceMesh(const double shiftX = 0., + const double inclinationX = 0.); + static MEDCouplingUMesh* build3D2DTetraTargetMesh(const double inclinaisonX = 0.); + static MEDCouplingUMesh* build3D2DHexaTargetMesh(const double inclinaisonX = 0.); + + static DataArrayDouble *buildCoordsForMultiTypes_1(); + static MEDCouplingMultiFields *buildMultiFields_1(); + static std::vector<MEDCouplingFieldDouble *> buildMultiFields_2(); + static double sumAll(const std::vector< std::map<int,double> >& matrix); + protected: + static int countNonZero(const std::vector< std::map<int,double> >& matrix); + + static void test2D1DMeshesIntersection(MEDCouplingUMesh *sourceMesh, + MEDCouplingUMesh *targetMesh, + const double correctSurf, + const int correctDuplicateFacesNbr, + const int correctTotalIntersectFacesNbr = -1); + static void test3D2DMeshesIntersection(MEDCouplingUMesh *sourceMesh, + MEDCouplingUMesh *targetMesh, + const double correctSurf, + const int correctDuplicateFacesNbr, + const int correctTotalIntersectFacesNbr = -1); + }; +} + +#endif diff --git a/src/medtool/src/MEDCoupling/Test/MEDCouplingBasicsTest0.cxx b/src/medtool/src/MEDCoupling/Test/MEDCouplingBasicsTest0.cxx new file mode 100644 index 000000000..f42235c44 --- /dev/null +++ b/src/medtool/src/MEDCoupling/Test/MEDCouplingBasicsTest0.cxx @@ -0,0 +1,1716 @@ +// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 +// 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 "MEDCouplingBasicsTest.hxx" +#include "MEDCouplingUMesh.hxx" +#include "MEDCouplingExtrudedMesh.hxx" +#include "MEDCouplingFieldDouble.hxx" +#include "MEDCouplingMemArray.hxx" +#include "MEDCouplingMultiFields.hxx" + +#include "MEDCouplingBasicsTestData1.hxx" + +#include "Interpolation2D.txx" +#include "Interpolation3D2D.txx" +#include "Interpolation2D1D.txx" +#include "MEDCouplingNormalizedUnstructuredMesh.txx" +#include "MEDCouplingNormalizedCartesianMesh.txx" + +using namespace ParaMEDMEM; + +typedef std::vector<std::map<int,double> > IntersectionMatrix; + +MEDCouplingUMesh *MEDCouplingBasicsTest::build3DSourceMesh_2() +{ + double sourceCoords[84]={100.0, 100.0, 0.0, 100.0, 100.0, 100.0, 100.0, 0.0, 100.0, 100.0, 0.0, 0.0, 0.0, 100.0, 0.0, 0.0, 100.0, 100.0, 0.0, + 0.0, 100.0, 0.0, 0.0, 0.0, 100.0, 100.0, 200.0, 100.0, 0.0, 200.0, 0.0, 100.0, 200.0, 0.0, 0.0, 200.0, 100.0, 200.0, + 0.0, 100.0, 200.0, 100.0, 0.0, 200.0, 0.0, 0.0, 200.0, 100.0, 100.0, 200.0, 200.0, 0.0, 200.0, 200.0, 200.0, 100.0, + 0.0, 200.0, 100.00000000833332, 100.00000000833332, 200.0, 0.0, 100.0, 200.0, 0.0, 0.0, 200.0, 100.0, 200.0, 200.0, + 0.0, 200.0, 200.0, 200.0, 0.0, 200.0, 200.0, 100.0, 200.0, 200.0, 200.0, 149.999999970343, 149.9999999874621, 49.999999881628682}; + + + int sourceConn[212]={25, 27, 13, 19, 18, 3, 20, 21, 5, 10, 17, 1, 1, 3, 0, 7, 18, 1, 0, 27, 12, 27, 13, 24, 25, 19, 16, 26, 1, 2, 6, 8, 15, 13, + 12, 5, 24, 13, 25, 27, 10, 11, 9, 6, 19, 8, 23, 1, 22, 8, 23, 19, 16, 13, 17, 1, 6, 9, 10, 8, 13, 17, 5, 15, 5, 4, 1, 12, 18, + 0, 24, 27, 19, 20, 18, 1, 7, 6, 5, 1, 4, 12, 15, 14, 25, 27, 19, 18, 1, 19, 16, 13, 20, 19, 23, 1, 27, 12, 1, 0, 6, 5, 1, 10, + 4, 5, 1, 7, 12, 27, 1, 13, 5, 15, 4, 12, 19, 16, 26, 22, 13, 5, 17, 1, 1, 3, 7, 2, 13, 5, 1, 12, 18, 1, 3, 0, 8, 23, 2, 9, 3, + 1, 18, 20, 1, 27, 19, 13, 24, 25, 18, 27, 25, 16, 19, 13, 7, 1, 2, 6, 3, 1, 20, 2, 8, 16, 17, 1, 7, 4, 0, 1, 18, 19, 1, 27, + 27, 12, 0, 24, 9, 6, 2, 8, 1, 4, 0, 12, 19, 16, 22, 8, 8, 2, 23, 1, 1, 16, 19, 8, 20, 2, 1, 23, 10, 1, 6, 8, 10, 8, 17, 1}; + + MEDCouplingUMesh *sourceMesh=MEDCouplingUMesh::New(); + sourceMesh->setMeshDimension(3); + sourceMesh->allocateCells(53); + for(int i=0;i<53;i++) + sourceMesh->insertNextCell(INTERP_KERNEL::NORM_TETRA4,4,sourceConn+4*i); + sourceMesh->finishInsertingCells(); + DataArrayDouble *myCoords=DataArrayDouble::New(); + myCoords->alloc(28,3); + std::copy(sourceCoords,sourceCoords+84,myCoords->getPointer()); + sourceMesh->setCoords(myCoords); + myCoords->decrRef(); + return sourceMesh; +} + +MEDCouplingUMesh *MEDCouplingBasicsTest::build3DTargetMesh_2() +{ + double targetCoords[24]={200.0, 200.0, 0.0, 200.0, 200.0, 200.0, 200.0, 0.0, 0.0, 200.0, 0.0, 200.0, 0.0, 200.0, 0.0, 0.0, 200.0, 200.0, 0.0, 0.0, 0.0, 0.0, 0.0, 200.0}; + int targetConn[20]={5, 6, 3, 0, 1, 3, 0, 5, 3, 6, 5, 7, 6, 4, 0, 5, 6, 3, 0, 2}; + MEDCouplingUMesh *targetMesh=MEDCouplingUMesh::New(); + targetMesh->setMeshDimension(3); + targetMesh->allocateCells(5); + for(int i=0;i<5;i++) + targetMesh->insertNextCell(INTERP_KERNEL::NORM_TETRA4,4,targetConn+4*i); + targetMesh->finishInsertingCells(); + DataArrayDouble *myCoords=DataArrayDouble::New(); + myCoords->alloc(8,3); + std::copy(targetCoords,targetCoords+24,myCoords->getPointer()); + targetMesh->setCoords(myCoords); + myCoords->decrRef(); + return targetMesh; +} + +MEDCouplingUMesh *MEDCouplingBasicsTest::build1DTargetMesh_1() +{ + double targetCoords[36]={ + 25.,25.,0., 25.,25.,50., 25.,25.,200., 75.,25.,0., 75.,25.,50., 75.,25.,200., + 25.,125.,0., 25.,125.,50., 25.,125.,200., 125.,125.,0., 125.,125.,50., 125.,125.,200. + }; + int targetConn[16]={0,1, 1,2, 3,4, 4,5, 6,7, 7,8, 9,10, 10,11}; + + MEDCouplingUMesh *targetMesh=MEDCouplingUMesh::New("my name of mesh 1D",1); + targetMesh->allocateCells(8); + for(int i=0;i<8;i++) + targetMesh->insertNextCell(INTERP_KERNEL::NORM_SEG2,2,targetConn+2*i); + targetMesh->finishInsertingCells(); + DataArrayDouble *myCoords=DataArrayDouble::New(); + myCoords->alloc(12,3); + std::copy(targetCoords,targetCoords+36,myCoords->getPointer()); + targetMesh->setCoords(myCoords); + myCoords->decrRef(); + return targetMesh; +} + +MEDCouplingUMesh *MEDCouplingBasicsTest::build2DSourceMesh_1() +{ + double sourceCoords[8]={-0.3,-0.3, 0.7,-0.3, -0.3,0.7, 0.7,0.7}; + int sourceConn[6]={0,3,1,0,2,3}; + MEDCouplingUMesh *sourceMesh=MEDCouplingUMesh::New("my name of mesh 2D",2); + sourceMesh->allocateCells(2); + sourceMesh->insertNextCell(INTERP_KERNEL::NORM_TRI3,3,sourceConn); + sourceMesh->insertNextCell(INTERP_KERNEL::NORM_TRI3,3,sourceConn+3); + sourceMesh->finishInsertingCells(); + DataArrayDouble *myCoords=DataArrayDouble::New(); + myCoords->alloc(4,2); + std::copy(sourceCoords,sourceCoords+8,myCoords->getPointer()); + sourceMesh->setCoords(myCoords); + myCoords->decrRef(); + return sourceMesh; +} + +MEDCouplingUMesh *MEDCouplingBasicsTest::build2DTargetMesh_1() +{ + double targetCoords[18]={-0.3,-0.3, 0.2,-0.3, 0.7,-0.3, -0.3,0.2, 0.2,0.2, 0.7,0.2, -0.3,0.7, 0.2,0.7, 0.7,0.7 }; + int targetConn[18]={0,3,4,1, 1,4,2, 4,5,2, 6,7,4,3, 7,8,5,4}; + MEDCouplingUMesh *targetMesh=MEDCouplingUMesh::New(); + targetMesh->setMeshDimension(2); + targetMesh->allocateCells(5); + targetMesh->insertNextCell(INTERP_KERNEL::NORM_QUAD4,4,targetConn); + targetMesh->insertNextCell(INTERP_KERNEL::NORM_TRI3,3,targetConn+4); + targetMesh->insertNextCell(INTERP_KERNEL::NORM_TRI3,3,targetConn+7); + targetMesh->insertNextCell(INTERP_KERNEL::NORM_QUAD4,4,targetConn+10); + targetMesh->insertNextCell(INTERP_KERNEL::NORM_QUAD4,4,targetConn+14); + targetMesh->finishInsertingCells(); + DataArrayDouble *myCoords=DataArrayDouble::New(); + myCoords->alloc(9,2); + std::copy(targetCoords,targetCoords+18,myCoords->getPointer()); + targetMesh->setCoords(myCoords); + myCoords->decrRef(); + return targetMesh; +} + +MEDCouplingUMesh *MEDCouplingBasicsTest::build2DTargetMeshPerm_1() +{ + double targetCoords[18]={-0.3,-0.3, 0.2,-0.3, 0.7,-0.3, -0.3,0.2, 0.2,0.2, 0.7,0.2, -0.3,0.7, 0.2,0.7, 0.7,0.7 }; + int targetConn[18]={0,3,4,1, 1,2,4, 4,5,2, 6,7,4,3, 7,8,5,4}; + MEDCouplingUMesh *targetMesh=MEDCouplingUMesh::New(); + targetMesh->setMeshDimension(2); + targetMesh->allocateCells(5); + targetMesh->insertNextCell(INTERP_KERNEL::NORM_QUAD4,4,targetConn); + targetMesh->insertNextCell(INTERP_KERNEL::NORM_TRI3,3,targetConn+4); + targetMesh->insertNextCell(INTERP_KERNEL::NORM_TRI3,3,targetConn+7); + targetMesh->insertNextCell(INTERP_KERNEL::NORM_QUAD4,4,targetConn+10); + targetMesh->insertNextCell(INTERP_KERNEL::NORM_QUAD4,4,targetConn+14); + targetMesh->finishInsertingCells(); + DataArrayDouble *myCoords=DataArrayDouble::New(); + myCoords->alloc(9,2); + std::copy(targetCoords,targetCoords+18,myCoords->getPointer()); + targetMesh->setCoords(myCoords); + myCoords->decrRef(); + return targetMesh; +} + +MEDCouplingUMesh *MEDCouplingBasicsTest::build2DTargetMesh_2() +{ + double targetCoords[18]={-0.3,-0.3, 0.2,-0.3, 0.7,-0.3, -0.3,0.2, 0.2,0.2, 0.7,0.2, -0.3,0.7, 0.2,0.7, 0.7,0.7 }; + int targetConn[24]={0,3,4, 0,4,1, 1,4,2, 4,5,2, 3,6,4, 6,7,4, 4,7,5, 7,8,5 }; + MEDCouplingUMesh *targetMesh=MEDCouplingUMesh::New(); + targetMesh->setMeshDimension(2); + targetMesh->allocateCells(8); + targetMesh->insertNextCell(INTERP_KERNEL::NORM_TRI3,3,targetConn); + targetMesh->insertNextCell(INTERP_KERNEL::NORM_TRI3,3,targetConn+3); + targetMesh->insertNextCell(INTERP_KERNEL::NORM_TRI3,3,targetConn+6); + targetMesh->insertNextCell(INTERP_KERNEL::NORM_TRI3,3,targetConn+9); + targetMesh->insertNextCell(INTERP_KERNEL::NORM_TRI3,3,targetConn+12); + targetMesh->insertNextCell(INTERP_KERNEL::NORM_TRI3,3,targetConn+15); + targetMesh->insertNextCell(INTERP_KERNEL::NORM_TRI3,3,targetConn+18); + targetMesh->insertNextCell(INTERP_KERNEL::NORM_TRI3,3,targetConn+21); + targetMesh->finishInsertingCells(); + DataArrayDouble *myCoords=DataArrayDouble::New(); + myCoords->alloc(9,2); + std::copy(targetCoords,targetCoords+18,myCoords->getPointer()); + targetMesh->setCoords(myCoords); + myCoords->decrRef(); + return targetMesh; +} + +MEDCouplingUMesh *MEDCouplingBasicsTest::buildCU1DMesh_U() +{ + double coords[4]={ 0.0, 0.3, 0.75, 1.0 }; + int conn[2*3]={ 0,1, 1,2, 2,3 }; + MEDCouplingUMesh *mesh=MEDCouplingUMesh::New(); + mesh->setMeshDimension(1); + mesh->allocateCells(3); + mesh->insertNextCell(INTERP_KERNEL::NORM_SEG2,2,conn); + mesh->insertNextCell(INTERP_KERNEL::NORM_SEG2,2,conn+2); + mesh->insertNextCell(INTERP_KERNEL::NORM_SEG2,2,conn+4); + mesh->finishInsertingCells(); + DataArrayDouble *myCoords=DataArrayDouble::New(); + myCoords->alloc(4,1); + std::copy(coords,coords+4,myCoords->getPointer()); + mesh->setCoords(myCoords); + myCoords->decrRef(); + return mesh; +} +MEDCouplingUMesh *MEDCouplingBasicsTest::buildCU2DMesh_U() +{ + double coords[18]={0.0,0.0, 0.5,0.0, 1.0,0.0, 0.0,0.5, 0.5,0.5, 1.0,0.5, 0.0,1.0, 0.5,1.0, 1.0,1.0 }; + int conn[18]={0,1,4,3, 3,4,7,6, 4,5,8,7, 1,5,4, 1,2,5 }; + MEDCouplingUMesh *mesh=MEDCouplingUMesh::New(); + mesh->setMeshDimension(2); + mesh->allocateCells(5); + mesh->insertNextCell(INTERP_KERNEL::NORM_QUAD4,4,conn); + mesh->insertNextCell(INTERP_KERNEL::NORM_QUAD4,4,conn+4); + mesh->insertNextCell(INTERP_KERNEL::NORM_QUAD4,4,conn+8); + mesh->insertNextCell(INTERP_KERNEL::NORM_TRI3,3,conn+12); + mesh->insertNextCell(INTERP_KERNEL::NORM_TRI3,3,conn+15); + mesh->finishInsertingCells(); + DataArrayDouble *myCoords=DataArrayDouble::New(); + myCoords->alloc(9,2); + std::copy(coords,coords+18,myCoords->getPointer()); + mesh->setCoords(myCoords); + myCoords->decrRef(); + return mesh; +} +MEDCouplingUMesh *MEDCouplingBasicsTest::buildCU3DMesh_U() +{ + double coords[27*3]= + { +// 0.0,1.0,0.0 ,0.0,0.3,0.0 ,0.0,0.3,0.3 ,0.3,0.0,0.0 ,0.3,0.3,1.0 ,1.0,0.0,1.0 ,1.0,0.0,0.3 ,0.3,0.0,0.3 ,0.3,1.0,0.3 ,0.0,0.3,1.0 ,0.3,0.0,1.0 ,0.3,0.3,0.3 ,1.0,0.3,1.0 ,1.0,0.0,0.0 ,0.0,0.0,0.0 ,1.0,0.3,0.3 ,0.3,1.0,0.0 ,1.0,1.0,0.3 ,1.0,1.0,1.0 ,0.0,1.0,1.0 ,0.3,0.3,0.0 ,0.0,1.0,0.3 ,0.0,0.0,1.0 ,0.3,1.0,1.0 ,1.0,0.3,0.0 ,0.0,0.0,0.3 ,1.0,1.0,0.0 + 0.0,0.0,0.0, 0.3,0.0,0.0, 1.0,0.0,0.0, 0.0,0.3,0.0, 0.3,0.3,0.0, 1.0,0.3,0.0, 0.0,1.0,0.0, 0.3,1.0,0.0, 1.0,1.0,0.0, 0.0,0.0,0.3, 0.3,0.0,0.3, 1.0,0.0,0.3, 0.0,0.3,0.3, 0.3,0.3,0.3, 1.0,0.3,0.3, 0.0,1.0,0.3, 0.3,1.0,0.3, 1.0,1.0,0.3, 0.0,0.0,1.0, 0.3,0.0,1.0, 1.0,0.0,1.0, 0.0,0.3,1.0, 0.3,0.3,1.0, 1.0,0.3,1.0, 0.0,1.0,1.0, 0.3,1.0,1.0, 1.0,1.0,1.0, + }; + int conn[8*8]= + { +// 11,15,12,4,8,17,18,23,3,13,6,7,20,24,15,11,14,3,7,25,1,20,11,2,1,20,11,2,0,16,8,21,20,24,15,11,16,26,17,8,25,7,10,22,2,11,4,9,2,11,4,9,21,8,23,19,7,6,5,10,11,15,12,4 + 0,3,4,1,9,12,13,10, 1,4,5,2,10,13,14,11, 3,6,7,4,12,15,16,13, 4,7,8,5,13,16,17,14, 9,12,13,10,18,21,22,19, 10,13,14,11,19,22,23,20, 12,15,16,13,21,24,25,22, 13,16,17,14,22,25,26,23 + }; + MEDCouplingUMesh *mesh=MEDCouplingUMesh::New(); + mesh->setMeshDimension(3); + mesh->allocateCells(8); + for(int i=0;i<8;i++) + mesh->insertNextCell(INTERP_KERNEL::NORM_HEXA8,8,conn+8*i); + mesh->finishInsertingCells(); + DataArrayDouble *myCoords=DataArrayDouble::New(); + myCoords->alloc(27,3); + std::copy(coords,coords+27*3,myCoords->getPointer()); + mesh->setCoords(myCoords); + myCoords->decrRef(); + return mesh; +} + +MEDCouplingUMesh *MEDCouplingBasicsTest::build3DSurfSourceMesh_1() +{ + double sourceCoords[12]={-0.3,-0.3,0.5, 0.7,-0.3,1.5, -0.3,0.7,0.5, 0.7,0.7,1.5}; + int sourceConn[6]={0,3,1,0,2,3}; + MEDCouplingUMesh *sourceMesh=MEDCouplingUMesh::New(); + sourceMesh->setMeshDimension(2); + sourceMesh->allocateCells(2); + sourceMesh->insertNextCell(INTERP_KERNEL::NORM_TRI3,3,sourceConn); + sourceMesh->insertNextCell(INTERP_KERNEL::NORM_TRI3,3,sourceConn+3); + sourceMesh->finishInsertingCells(); + DataArrayDouble *myCoords=DataArrayDouble::New(); + myCoords->alloc(4,3); + std::copy(sourceCoords,sourceCoords+12,myCoords->getPointer()); + sourceMesh->setCoords(myCoords); + myCoords->decrRef(); + return sourceMesh; +} + +MEDCouplingUMesh *MEDCouplingBasicsTest::build3DSurfSourceMesh_2() +{ + double sourceCoords[12]={-0.3,-0.3,0., 0.7,-0.3,0., -0.3,0.7,0., 0.7,0.7,0.}; + int sourceConn[6]={0,3,1,0,2,3}; + MEDCouplingUMesh *sourceMesh=MEDCouplingUMesh::New(); + sourceMesh->setMeshDimension(2); + sourceMesh->allocateCells(2); + sourceMesh->insertNextCell(INTERP_KERNEL::NORM_TRI3,3,sourceConn); + sourceMesh->insertNextCell(INTERP_KERNEL::NORM_TRI3,3,sourceConn+3); + sourceMesh->finishInsertingCells(); + DataArrayDouble *myCoords=DataArrayDouble::New(); + myCoords->alloc(4,3); + std::copy(sourceCoords,sourceCoords+12,myCoords->getPointer()); + sourceMesh->setCoords(myCoords); + myCoords->decrRef(); + return sourceMesh; +} + +MEDCouplingUMesh *MEDCouplingBasicsTest::build3DSurfTargetMesh_1() +{ + double targetCoords[27]={-0.3,-0.3,0.5, 0.2,-0.3,1., 0.7,-0.3,1.5, -0.3,0.2,0.5, 0.2,0.2,1., 0.7,0.2,1.5, -0.3,0.7,0.5, 0.2,0.7,1., 0.7,0.7,1.5}; + int targetConn[18]={0,3,4,1, 1,4,2, 4,5,2, 6,7,4,3, 7,8,5,4}; + MEDCouplingUMesh *targetMesh=MEDCouplingUMesh::New(); + targetMesh->setMeshDimension(2); + targetMesh->allocateCells(5); + targetMesh->insertNextCell(INTERP_KERNEL::NORM_QUAD4,4,targetConn); + targetMesh->insertNextCell(INTERP_KERNEL::NORM_TRI3,3,targetConn+4); + targetMesh->insertNextCell(INTERP_KERNEL::NORM_TRI3,3,targetConn+7); + targetMesh->insertNextCell(INTERP_KERNEL::NORM_QUAD4,4,targetConn+10); + targetMesh->insertNextCell(INTERP_KERNEL::NORM_QUAD4,4,targetConn+14); + targetMesh->finishInsertingCells(); + DataArrayDouble *myCoords=DataArrayDouble::New(); + myCoords->alloc(9,3); + std::copy(targetCoords,targetCoords+27,myCoords->getPointer()); + targetMesh->setCoords(myCoords); + myCoords->decrRef(); + return targetMesh; +} + +/*! + * Idem build3DSurfTargetMesh_1 except that cell id 2 is not correctly numbered. + */ +MEDCouplingUMesh *MEDCouplingBasicsTest::build3DSurfTargetMeshPerm_1() +{ + double targetCoords[27]={-0.3,-0.3,0.5, 0.2,-0.3,1., 0.7,-0.3,1.5, -0.3,0.2,0.5, 0.2,0.2,1., 0.7,0.2,1.5, -0.3,0.7,0.5, 0.2,0.7,1., 0.7,0.7,1.5}; + int targetConn[18]={0,3,4,1, 1,4,2, 4,2,5, 6,7,4,3, 7,8,5,4}; + MEDCouplingUMesh *targetMesh=MEDCouplingUMesh::New(); + targetMesh->setMeshDimension(2); + targetMesh->allocateCells(5); + targetMesh->insertNextCell(INTERP_KERNEL::NORM_QUAD4,4,targetConn); + targetMesh->insertNextCell(INTERP_KERNEL::NORM_TRI3,3,targetConn+4); + targetMesh->insertNextCell(INTERP_KERNEL::NORM_TRI3,3,targetConn+7); + targetMesh->insertNextCell(INTERP_KERNEL::NORM_QUAD4,4,targetConn+10); + targetMesh->insertNextCell(INTERP_KERNEL::NORM_QUAD4,4,targetConn+14); + targetMesh->finishInsertingCells(); + DataArrayDouble *myCoords=DataArrayDouble::New(); + myCoords->alloc(9,3); + std::copy(targetCoords,targetCoords+27,myCoords->getPointer()); + targetMesh->setCoords(myCoords); + myCoords->decrRef(); + return targetMesh; +} + +MEDCouplingUMesh *MEDCouplingBasicsTest::build3DSurfTargetMesh_2() +{ + double targetCoords[27]={-0.3,-0.3,0.5, 0.2,-0.3,1., 0.7,-0.3,1.5, -0.3,0.2,0.5, 0.2,0.2,1., 0.7,0.2,1.5, -0.3,0.7,0.5, 0.2,0.7,1., 0.7,0.7,1.5}; + int targetConn[24]={0,3,4, 0,4,1, 1,4,2, 4,5,2, 3,6,4, 6,7,4, 4,7,5, 7,8,5 }; + MEDCouplingUMesh *targetMesh=MEDCouplingUMesh::New(); + targetMesh->setMeshDimension(2); + targetMesh->allocateCells(8); + targetMesh->insertNextCell(INTERP_KERNEL::NORM_TRI3,3,targetConn); + targetMesh->insertNextCell(INTERP_KERNEL::NORM_TRI3,3,targetConn+3); + targetMesh->insertNextCell(INTERP_KERNEL::NORM_TRI3,3,targetConn+6); + targetMesh->insertNextCell(INTERP_KERNEL::NORM_TRI3,3,targetConn+9); + targetMesh->insertNextCell(INTERP_KERNEL::NORM_TRI3,3,targetConn+12); + targetMesh->insertNextCell(INTERP_KERNEL::NORM_TRI3,3,targetConn+15); + targetMesh->insertNextCell(INTERP_KERNEL::NORM_TRI3,3,targetConn+18); + targetMesh->insertNextCell(INTERP_KERNEL::NORM_TRI3,3,targetConn+21); + targetMesh->finishInsertingCells(); + DataArrayDouble *myCoords=DataArrayDouble::New(); + myCoords->alloc(9,3); + std::copy(targetCoords,targetCoords+27,myCoords->getPointer()); + targetMesh->setCoords(myCoords); + myCoords->decrRef(); + return targetMesh; +} + +MEDCouplingUMesh *MEDCouplingBasicsTest::build3DSourceMesh_1() +{ + double sourceCoords[27]={ 0.0, 0.0, 200.0, 0.0, 0.0, 0.0, 0.0, 200.0, 200.0, 0.0, 200.0, 0.0, 200.0, 0.0, 200.0, + 200.0, 0.0, 0.0, 200.0, 200.0, 200.0, 200.0, 200.0, 0.0, 100.0, 100.0, 100.0 }; + int sourceConn[48]={8,1,7,3, 6,0,8,2, 7,4,5,8, 6,8,4,7, 6,8,0,4, 6,8,7,3, 8,1,3,0, 4,1,5,8, 1,7,5,8, 0,3,8,2, 8,1,0,4, 3,6,8,2}; + MEDCouplingUMesh *sourceMesh=MEDCouplingUMesh::New(); + sourceMesh->setMeshDimension(3); + sourceMesh->allocateCells(12); + sourceMesh->insertNextCell(INTERP_KERNEL::NORM_TETRA4,4,sourceConn); + sourceMesh->insertNextCell(INTERP_KERNEL::NORM_TETRA4,4,sourceConn+4); + sourceMesh->insertNextCell(INTERP_KERNEL::NORM_TETRA4,4,sourceConn+8); + sourceMesh->insertNextCell(INTERP_KERNEL::NORM_TETRA4,4,sourceConn+12); + sourceMesh->insertNextCell(INTERP_KERNEL::NORM_TETRA4,4,sourceConn+16); + sourceMesh->insertNextCell(INTERP_KERNEL::NORM_TETRA4,4,sourceConn+20); + sourceMesh->insertNextCell(INTERP_KERNEL::NORM_TETRA4,4,sourceConn+24); + sourceMesh->insertNextCell(INTERP_KERNEL::NORM_TETRA4,4,sourceConn+28); + sourceMesh->insertNextCell(INTERP_KERNEL::NORM_TETRA4,4,sourceConn+32); + sourceMesh->insertNextCell(INTERP_KERNEL::NORM_TETRA4,4,sourceConn+36); + sourceMesh->insertNextCell(INTERP_KERNEL::NORM_TETRA4,4,sourceConn+40); + sourceMesh->insertNextCell(INTERP_KERNEL::NORM_TETRA4,4,sourceConn+44); + sourceMesh->finishInsertingCells(); + DataArrayDouble *myCoords=DataArrayDouble::New(); + myCoords->alloc(9,3); + std::copy(sourceCoords,sourceCoords+27,myCoords->getPointer()); + sourceMesh->setCoords(myCoords); + myCoords->decrRef(); + return sourceMesh; +} + +MEDCouplingUMesh *MEDCouplingBasicsTest::build3DTargetMesh_1() +{ + double targetCoords[81]={ 0., 0., 0., 50., 0., 0. , 200., 0., 0. , 0., 50., 0., 50., 50., 0. , 200., 50., 0., 0., 200., 0., 50., 200., 0. , 200., 200., 0. , + 0., 0., 50., 50., 0., 50. , 200., 0., 50. , 0., 50., 50., 50., 50., 50. , 200., 50., 50., 0., 200., 50., 50., 200., 50. , 200., 200., 50. , + 0., 0., 200., 50., 0., 200. , 200., 0., 200. , 0., 50., 200., 50., 50., 200. , 200., 50., 200., 0., 200., 200., 50., 200., 200. , 200., 200., 200. }; + int targetConn[64]={0,1,4,3,9,10,13,12, 1,2,5,4,10,11,14,13, 3,4,7,6,12,13,16,15, 4,5,8,7,13,14,17,16, + 9,10,13,12,18,19,22,21, 10,11,14,13,19,20,23,22, 12,13,16,15,21,22,25,24, 13,14,17,16,22,23,26,25}; + MEDCouplingUMesh *targetMesh=MEDCouplingUMesh::New(); + targetMesh->setMeshDimension(3); + targetMesh->allocateCells(12); + for(int i=0;i<8;i++) + targetMesh->insertNextCell(INTERP_KERNEL::NORM_HEXA8,8,targetConn+8*i); + targetMesh->finishInsertingCells(); + DataArrayDouble *myCoords=DataArrayDouble::New(); + myCoords->alloc(27,3); + std::copy(targetCoords,targetCoords+81,myCoords->getPointer()); + targetMesh->setCoords(myCoords); + myCoords->decrRef(); + return targetMesh; +} + +MEDCouplingUMesh *MEDCouplingBasicsTest::build2DTargetMeshMergeNode_1() +{ + double targetCoords[36]={-0.3,-0.3, 0.2,-0.3, 0.7,-0.3, -0.3,-0.3, 0.2,-0.3, 0.2,-0.3, 0.2,0.2, 0.2,0.2, 0.7,-0.3, -0.3,0.2, 0.2,0.2, 0.7,0.2, -0.3,0.7, 0.7,0.2, -0.3,0.7, 0.2,0.7, 0.7,0.7, 0.2,0.7 }; + int targetConn[18]={0,9,7,5, 4,6,2, 10,11,8, 9,14,15,7, 17,16,13,6}; + MEDCouplingUMesh *targetMesh=MEDCouplingUMesh::New(); + targetMesh->setMeshDimension(2); + targetMesh->allocateCells(5); + targetMesh->insertNextCell(INTERP_KERNEL::NORM_QUAD4,4,targetConn); + targetMesh->insertNextCell(INTERP_KERNEL::NORM_TRI3,3,targetConn+4); + targetMesh->insertNextCell(INTERP_KERNEL::NORM_TRI3,3,targetConn+7); + targetMesh->insertNextCell(INTERP_KERNEL::NORM_QUAD4,4,targetConn+10); + targetMesh->insertNextCell(INTERP_KERNEL::NORM_QUAD4,4,targetConn+14); + targetMesh->finishInsertingCells(); + DataArrayDouble *myCoords=DataArrayDouble::New(); + myCoords->alloc(18,2); + std::copy(targetCoords,targetCoords+36,myCoords->getPointer()); + targetMesh->setCoords(myCoords); + myCoords->decrRef(); + return targetMesh; +} + +MEDCouplingUMesh *MEDCouplingBasicsTest::build3DTargetMeshMergeNode_1() +{ + double targetCoords[93]={ 0., 0., 0., 50., 0., 0. , 200., 0., 0. , 0., 50., 0., 50., 50., 0. , 200., 50., 0., 0., 200., 0., 50., 200., 0. , 200., 200., 0. , + 0., 0., 50., 50., 0., 50. , 200., 0., 50. , 0., 50., 50., 50., 50., 50. , 200., 50., 50., 0., 200., 50., 50., 200., 50. , 200., 200., 50. , + 0., 0., 200., 50., 0., 200. , 200., 0., 200. , 0., 50., 200., 50., 50., 200. , 200., 50., 200., 0., 200., 200., 50., 200., 200. , 200., 200., 200., 50.,0.,0., 50.,0.,0., 50.,0.,0., 200., 50., 200.}; + int targetConn[64]={0,29,4,3,9,10,13,12, 28,2,5,4,10,11,14,13, 3,4,7,6,12,13,16,15, 4,5,8,7,13,14,17,16, + 9,10,13,12,18,19,22,21, 10,11,14,13,19,20,23,22, 12,13,16,15,21,22,25,24, 13,14,17,16,22,30,26,25}; + MEDCouplingUMesh *targetMesh=MEDCouplingUMesh::New(); + targetMesh->setMeshDimension(3); + targetMesh->allocateCells(12); + for(int i=0;i<8;i++) + targetMesh->insertNextCell(INTERP_KERNEL::NORM_HEXA8,8,targetConn+8*i); + targetMesh->finishInsertingCells(); + DataArrayDouble *myCoords=DataArrayDouble::New(); + myCoords->alloc(31,3); + std::copy(targetCoords,targetCoords+93,myCoords->getPointer()); + targetMesh->setCoords(myCoords); + myCoords->decrRef(); + return targetMesh; +} + +MEDCouplingUMesh *MEDCouplingBasicsTest::build3DExtrudedUMesh_1(MEDCouplingUMesh *&mesh2D) +{ + double coords[180]={ + 0.,0.,0., 1.,1.,0., 1.,1.25,0., 1.,0.,0., 1.,1.5,0., 2.,0.,0., 2.,1.,0., 1.,2.,0., 0.,2.,0., 3.,1.,0., + 3.,2.,0., 0.,1.,0., 1.,3.,0., 2.,2.,0., 2.,3.,0., + 0.,0.,1., 1.,1.,1., 1.,1.25,1., 1.,0.,1., 1.,1.5,1., 2.,0.,1., 2.,1.,1., 1.,2.,1., 0.,2.,1., 3.,1.,1., + 3.,2.,1., 0.,1.,1., 1.,3.,1., 2.,2.,1., 2.,3.,1., + 0.,0.,2., 1.,1.,2., 1.,1.25,2., 1.,0.,2., 1.,1.5,2., 2.,0.,2., 2.,1.,2., 1.,2.,2., 0.,2.,2., 3.,1.,2., + 3.,2.,2., 0.,1.,2., 1.,3.,2., 2.,2.,2., 2.,3.,2., + 0.,0.,3., 1.,1.,3., 1.,1.25,3., 1.,0.,3., 1.,1.5,3., 2.,0.,3., 2.,1.,3., 1.,2.,3., 0.,2.,3., 3.,1.,3., + 3.,2.,3., 0.,1.,3., 1.,3.,3., 2.,2.,3., 2.,3.,3.}; + + int conn[354]={ + // 0 + 0,11,1,3,15,26,16,18, 1,2,4,7,13,6,-1,1,16,21,6,-1,6,21,28,13,-1,13,7,22,28,-1,7,4,19,22,-1,4,2,17,19,-1,2,1,16,17,-1,16,21,28,22,19,17, + 1,6,5,3,16,21,20,18, 13,10,9,6,28,25,24,21, + 11,8,7,4,2,1,-1,11,26,16,1,-1,1,16,17,2,-1,2,17,19,4,-1,4,19,22,7,-1,7,8,23,22,-1,8,11,26,23,-1,26,16,17,19,22,23, + 7,12,14,13,22,27,29,28, + // 1 + 15,26,16,18,30,41,31,33, 16,17,19,22,28,21,-1,16,31,36,21,-1,21,36,43,28,-1,28,22,37,43,-1,22,19,34,37,-1,19,17,32,34,-1,17,16,31,32,-1,31,36,43,37,34,32, + 16,21,20,18,31,36,35,33, 28,25,24,21,43,40,39,36, + 26,23,22,19,17,16,-1,26,41,31,16,-1,16,31,32,17,-1,17,32,34,19,-1,19,34,37,22,-1,22,23,38,37,-1,23,26,41,38,-1,41,31,32,34,37,38, + 22,27,29,28,37,42,44,43, + // 2 + 30,41,31,33,45,56,46,48, 31,32,34,37,43,36,-1,31,46,51,36,-1,36,51,58,43,-1,43,37,52,58,-1,37,34,49,52,-1,34,32,47,49,-1,32,31,46,47,-1,46,51,58,52,49,47, + 31,36,35,33,46,51,50,48, 43,40,39,36,58,55,54,51, + 41,38,37,34,32,31,-1,41,56,46,31,-1,31,46,47,32,-1,32,47,49,34,-1,34,49,52,37,-1,37,38,53,52,-1,38,41,56,53,-1,56,46,47,49,52,53, + 37,42,44,43,52,57,59,58 + }; + int conn2[28]={7,12,14,13, 11,8,7,4,2,1, 13,10,9,6, 1,6,5,3, 1,2,4,7,13,6, 0,11,1,3}; + // + MEDCouplingUMesh *ret=MEDCouplingUMesh::New(); + ret->setMeshDimension(3); + ret->allocateCells(18); + // + ret->insertNextCell(INTERP_KERNEL::NORM_HEXA8,8,conn); + ret->insertNextCell(INTERP_KERNEL::NORM_POLYHED,43,conn+8); + ret->insertNextCell(INTERP_KERNEL::NORM_HEXA8,8,conn+51); + ret->insertNextCell(INTERP_KERNEL::NORM_HEXA8,8,conn+59); + ret->insertNextCell(INTERP_KERNEL::NORM_POLYHED,43,conn+67); + ret->insertNextCell(INTERP_KERNEL::NORM_HEXA8,8,conn+110); + // + ret->insertNextCell(INTERP_KERNEL::NORM_HEXA8,8,conn+118); + ret->insertNextCell(INTERP_KERNEL::NORM_POLYHED,43,conn+126); + ret->insertNextCell(INTERP_KERNEL::NORM_HEXA8,8,conn+169); + ret->insertNextCell(INTERP_KERNEL::NORM_HEXA8,8,conn+177); + ret->insertNextCell(INTERP_KERNEL::NORM_POLYHED,43,conn+185); + ret->insertNextCell(INTERP_KERNEL::NORM_HEXA8,8,conn+228); + // + ret->insertNextCell(INTERP_KERNEL::NORM_HEXA8,8,conn+236); + ret->insertNextCell(INTERP_KERNEL::NORM_POLYHED,43,conn+244); + ret->insertNextCell(INTERP_KERNEL::NORM_HEXA8,8,conn+287); + ret->insertNextCell(INTERP_KERNEL::NORM_HEXA8,8,conn+295); + ret->insertNextCell(INTERP_KERNEL::NORM_POLYHED,43,conn+303); + ret->insertNextCell(INTERP_KERNEL::NORM_HEXA8,8,conn+346); + // + ret->finishInsertingCells(); + DataArrayDouble *myCoords=DataArrayDouble::New(); + myCoords->alloc(60,3); + std::copy(coords,coords+180,myCoords->getPointer()); + ret->setCoords(myCoords); + // + mesh2D=MEDCouplingUMesh::New(); + mesh2D->setMeshDimension(2); + mesh2D->allocateCells(6); + mesh2D->insertNextCell(INTERP_KERNEL::NORM_QUAD4,4,conn2); + mesh2D->insertNextCell(INTERP_KERNEL::NORM_POLYGON,6,conn2+4); + mesh2D->insertNextCell(INTERP_KERNEL::NORM_QUAD4,4,conn2+10); + mesh2D->insertNextCell(INTERP_KERNEL::NORM_QUAD4,4,conn2+14); + mesh2D->insertNextCell(INTERP_KERNEL::NORM_POLYGON,6,conn2+18); + mesh2D->insertNextCell(INTERP_KERNEL::NORM_QUAD4,4,conn2+24); + mesh2D->setCoords(myCoords); + myCoords->decrRef(); + return ret; +} + +void MEDCouplingBasicsTest::build3DExtrudedUMesh_2(MEDCouplingUMesh *&meshN, MEDCouplingUMesh *&meshTT, MEDCouplingUMesh *&meshTF) +{ + const double coordsN[270]={ + 0, 0, 0, 0.10803000450134277, 0, 0, 0.21606000900268554, 0, 0, 0.28808000564575198, 0, 0, 0.36010002136230468, 0, 0, 0.43212001800537109, 0, 0, 0, + 0.072020001411437995, 0, 0.10803000450134277, 0.072020001411437995, 0, 0.21606000900268554, 0.072020001411437995, 0, 0.28808000564575198, 0.072020001411437995, + 0, 0.36010002136230468, 0.072020001411437995, 0, 0.43212001800537109, 0.072020001411437995, 0, 0, 0.10803000450134277, 0, 0.10803000450134277, + 0.10803000450134277, 0, 0.21606000900268554, 0.10803000450134277, 0, 0.28808000564575198, 0.10803000450134277, 0, 0.36010002136230468, 0.10803000450134277, 0, + 0.43212001800537109, 0.10803000450134277, 0, 0, 0.14404000282287599, 0, 0.10803000450134277, 0.14404000282287599, 0, 0.21606000900268554, 0.14404000282287599, 0, + 0.28808000564575198, 0.14404000282287599, 0, 0.36010002136230468, 0.14404000282287599, 0, 0.43212001800537109, 0.14404000282287599, 0, 0, 0.21606000900268554, 0, + 0.10803000450134277, 0.21606000900268554, 0, 0.21606000900268554, 0.21606000900268554, 0, 0.28808000564575198, 0.21606000900268554, 0, 0.36010002136230468, + 0.21606000900268554, 0, 0.43212001800537109, 0.21606000900268554, 0, 0, 0, 2.1364999389648438, 0.10803000450134277, 0, 2.1364999389648438, 0.21606000900268554, + 0, 2.1364999389648438, 0.28808000564575198, 0, 2.1364999389648438, 0.36010002136230468, 0, 2.1364999389648438, 0.43212001800537109, 0, 2.1364999389648438, 0, + 0.072020001411437995, 2.1364999389648438, 0.10803000450134277, 0.072020001411437995, 2.1364999389648438, 0.21606000900268554, 0.072020001411437995, + 2.1364999389648438, 0.28808000564575198, 0.072020001411437995, 2.1364999389648438, 0.36010002136230468, 0.072020001411437995, 2.1364999389648438, + 0.43212001800537109, 0.072020001411437995, 2.1364999389648438, 0, 0.10803000450134277, 2.1364999389648438, 0.10803000450134277, 0.10803000450134277, + 2.1364999389648438, 0.21606000900268554, 0.10803000450134277, 2.1364999389648438, 0.28808000564575198, 0.10803000450134277, 2.1364999389648438, + 0.36010002136230468, 0.10803000450134277, 2.1364999389648438, 0.43212001800537109, 0.10803000450134277, 2.1364999389648438, 0, 0.14404000282287599, + 2.1364999389648438, 0.10803000450134277, 0.14404000282287599, 2.1364999389648438, 0.21606000900268554, 0.14404000282287599, 2.1364999389648438, + 0.28808000564575198, 0.14404000282287599, 2.1364999389648438, 0.36010002136230468, 0.14404000282287599, 2.1364999389648438, 0.43212001800537109, + 0.14404000282287599, 2.1364999389648438, 0, 0.21606000900268554, 2.1364999389648438, 0.10803000450134277, 0.21606000900268554, 2.1364999389648438, + 0.21606000900268554, 0.21606000900268554, 2.1364999389648438, 0.28808000564575198, 0.21606000900268554, 2.1364999389648438, 0.36010002136230468, + 0.21606000900268554, 2.1364999389648438, 0.43212001800537109, 0.21606000900268554, 2.1364999389648438, 0, 0, 4.2729998779296876, 0.10803000450134277, 0, + 4.2729998779296876, 0.21606000900268554, 0, 4.2729998779296876, 0.28808000564575198, 0, 4.2729998779296876, 0.36010002136230468, 0, 4.2729998779296876, + 0.43212001800537109, 0, 4.2729998779296876, 0, 0.072020001411437995, 4.2729998779296876, 0.10803000450134277, 0.072020001411437995, 4.2729998779296876, + 0.21606000900268554, 0.072020001411437995, 4.2729998779296876, 0.28808000564575198, 0.072020001411437995, 4.2729998779296876, 0.36010002136230468, + 0.072020001411437995, 4.2729998779296876, 0.43212001800537109, 0.072020001411437995, 4.2729998779296876, 0, 0.10803000450134277, 4.2729998779296876, + 0.10803000450134277, 0.10803000450134277, 4.2729998779296876, 0.21606000900268554, 0.10803000450134277, 4.2729998779296876, 0.28808000564575198, + 0.10803000450134277, 4.2729998779296876, 0.36010002136230468, 0.10803000450134277, 4.2729998779296876, 0.43212001800537109, 0.10803000450134277, + 4.2729998779296876, 0, 0.14404000282287599, 4.2729998779296876, 0.10803000450134277, 0.14404000282287599, 4.2729998779296876, 0.21606000900268554, + 0.14404000282287599, 4.2729998779296876, 0.28808000564575198, 0.14404000282287599, 4.2729998779296876, 0.36010002136230468, 0.14404000282287599, + 4.2729998779296876, 0.43212001800537109, 0.14404000282287599, 4.2729998779296876, 0, 0.21606000900268554, 4.2729998779296876, 0.10803000450134277, + 0.21606000900268554, 4.2729998779296876, 0.21606000900268554, 0.21606000900268554, 4.2729998779296876, 0.28808000564575198, 0.21606000900268554, + 4.2729998779296876, 0.36010002136230468, 0.21606000900268554, 4.2729998779296876, 0.43212001800537109, 0.21606000900268554, 4.2729998779296876}; + const int connN[320]={ + 0, 1, 7, 6, 30, 31, 37, 36, 1, 2, 8, 7, 31, 32, 38, 37, 2, 3, 9, 8, 32, 33, 39, 38, 3, 4, 10, 9, 33, 34, 40, 39, 4, 5, 11, 10, 34, 35, 41, 40, 6, + 7, 13, 12, 36, 37, 43, 42, 7, 8, 14, 13, 37, 38, 44, 43, 8, 9, 15, 14, 38, 39, 45, 44, 9, 10, 16, 15, 39, 40, 46, 45, 10, 11, 17, 16, 40, 41, 47, + 46, 12, 13, 19, 18, 42, 43, 49, 48, 13, 14, 20, 19, 43, 44, 50, 49, 14, 15, 21, 20, 44, 45, 51, 50, 15, 16, 22, 21, 45, 46, 52, 51, 16, 17, 23, + 22, 46, 47, 53, 52, 18, 19, 25, 24, 48, 49, 55, 54, 19, 20, 26, 25, 49, 50, 56, 55, 20, 21, 27, 26, 50, 51, 57, 56, 21, 22, 28, 27, 51, 52, 58, + 57, 22, 23, 29, 28, 52, 53, 59, 58, 30, 31, 37, 36, 60, 61, 67, 66, 31, 32, 38, 37, 61, 62, 68, 67, 32, 33, 39, 38, 62, 63, 69, 68, 33, 34, 40, + 39, 63, 64, 70, 69, 34, 35, 41, 40, 64, 65, 71, 70, 36, 37, 43, 42, 66, 67, 73, 72, 37, 38, 44, 43, 67, 68, 74, 73, 38, 39, 45, 44, 68, 69, 75, + 74, 39, 40, 46, 45, 69, 70, 76, 75, 40, 41, 47, 46, 70, 71, 77, 76, 42, 43, 49, 48, 72, 73, 79, 78, 43, 44, 50, 49, 73, 74, 80, 79, 44, 45, 51, + 50, 74, 75, 81, 80, 45, 46, 52, 51, 75, 76, 82, 81, 46, 47, 53, 52, 76, 77, 83, 82, 48, 49, 55, 54, 78, 79, 85, 84, 49, 50, 56, 55, 79, 80, 86, + 85, 50, 51, 57, 56, 80, 81, 87, 86, 51, 52, 58, 57, 81, 82, 88, 87, 52, 53, 59, 58, 82, 83, 89, 88}; + meshN=MEDCouplingUMesh::New(); + meshN->setName("meshExtrudedN"); + meshN->setMeshDimension(3); + meshN->allocateCells(40); + for(int i=0;i<40;i++) + meshN->insertNextCell(INTERP_KERNEL::NORM_HEXA8,8,connN+8*i); + meshN->finishInsertingCells(); + DataArrayDouble *myCoords=DataArrayDouble::New(); + myCoords->alloc(90,3); + std::copy(coordsN,coordsN+270,myCoords->getPointer()); + meshN->setCoords(myCoords); + myCoords->decrRef(); + // + meshTT=MEDCouplingUMesh::New(); + meshTT->setName("meshExtrudedTT"); + meshTT->setMeshDimension(3); + meshTT->allocateCells(200); + for(int i=0;i<200;i++) + meshTT->insertNextCell(INTERP_KERNEL::NORM_POLYHED,connITT[i+1]-connITT[i],connTT+connITT[i]); + meshTT->finishInsertingCells(); + myCoords=DataArrayDouble::New(); + myCoords->alloc(1720,3); + std::copy(coordsTT,coordsTT+5160,myCoords->getPointer()); + meshTT->setCoords(myCoords); + myCoords->decrRef(); + // + meshTF=MEDCouplingUMesh::New(); + meshTF->setName("meshExtrudedTF"); + meshTF->setMeshDimension(3); + meshTF->allocateCells(340); + for(int i=0;i<320;i++) + meshTF->insertNextCell(INTERP_KERNEL::NORM_HEXA8,8,connTFH8+8*i); + for(int i=0;i<20;i++) + meshTF->insertNextCell(INTERP_KERNEL::NORM_POLYHED,connTFPOLH_I[i+1]-connTFPOLH_I[i],connTFPOLH+connTFPOLH_I[i]); + meshTF->finishInsertingCells(); + myCoords=DataArrayDouble::New(); + myCoords->alloc(567,3); + std::copy(coordsTF,coordsTF+1701,myCoords->getPointer()); + meshTF->setCoords(myCoords); + myCoords->decrRef(); +} + +MEDCouplingUMesh *MEDCouplingBasicsTest::build2DTargetMeshMerged_1() +{ + double targetCoords[26]={ + -0.3,-0.3, 0.2,-0.3, 0.7,-0.3, -0.3,0.2, 0.2,0.2, 0.7,0.2, -0.3,0.7, 0.2,0.7, 0.7,0.7, + 0.7,-0.3, 1.7,-0.3, 0.7,0.7, 1.7,0.7 + }; + int targetConn[24]={ + 0,3,4,1, 1,4,2, 4,5,2, 6,7,4,3, 7,8,5,4, + 9,12,10,9,11,12 + }; + MEDCouplingUMesh *targetMesh=MEDCouplingUMesh::New(); + targetMesh->setName("merge"); + targetMesh->setMeshDimension(2); + targetMesh->allocateCells(10); + targetMesh->insertNextCell(INTERP_KERNEL::NORM_QUAD4,4,targetConn); + targetMesh->insertNextCell(INTERP_KERNEL::NORM_TRI3,3,targetConn+4); + targetMesh->insertNextCell(INTERP_KERNEL::NORM_TRI3,3,targetConn+7); + targetMesh->insertNextCell(INTERP_KERNEL::NORM_QUAD4,4,targetConn+10); + targetMesh->insertNextCell(INTERP_KERNEL::NORM_QUAD4,4,targetConn+14); + targetMesh->insertNextCell(INTERP_KERNEL::NORM_TRI3,3,targetConn+18); + targetMesh->insertNextCell(INTERP_KERNEL::NORM_TRI3,3,targetConn+21); + targetMesh->finishInsertingCells(); + DataArrayDouble *myCoords=DataArrayDouble::New(); + myCoords->alloc(13,2); + std::copy(targetCoords,targetCoords+26,myCoords->getPointer()); + targetMesh->setCoords(myCoords); + myCoords->decrRef(); + return targetMesh; +} + +MEDCouplingUMesh *MEDCouplingBasicsTest::build2DCurveMesh(double dx, double dy) +{ + // 1d mesh: + // + // * + // / + // *---* + double targetCoords[3*2]= + { + 0.+dx,0.+dy, 1.+dx,0.+dy, 2.+dx,1.+dy + }; + int targetConn[2*2]={1,2, 0,1}; + + MEDCouplingUMesh *targetMesh=MEDCouplingUMesh::New("2Dcurve 1D mesh",1); + targetMesh->allocateCells(2); + for(int i=0;i<2;i++) + targetMesh->insertNextCell(INTERP_KERNEL::NORM_SEG2,2,targetConn+2*i); + targetMesh->finishInsertingCells(); + DataArrayDouble *myCoords=DataArrayDouble::New(); + myCoords->alloc(3,2); + std::copy(targetCoords,targetCoords+3*2,myCoords->getPointer()); + targetMesh->setCoords(myCoords); + myCoords->decrRef(); + return targetMesh; +} + +MEDCouplingUMesh *MEDCouplingBasicsTest::build1DMesh(double dx) +{ + double targetCoords[4]= + { + 0.+dx, 1.+dx, 3.+dx, 4.+dx + }; + int targetConn[2*3]={1,2, 0,1, 2,3}; + + MEDCouplingUMesh *targetMesh=MEDCouplingUMesh::New("1D mesh",1); + targetMesh->allocateCells(3); + for(int i=0;i<3;i++) + targetMesh->insertNextCell(INTERP_KERNEL::NORM_SEG2,2,targetConn+2*i); + targetMesh->finishInsertingCells(); + DataArrayDouble *myCoords=DataArrayDouble::New(); + myCoords->alloc(4,1); + std::copy(targetCoords,targetCoords+4,myCoords->getPointer()); + targetMesh->setCoords(myCoords); + myCoords->decrRef(); + return targetMesh; +} + +MEDCouplingUMesh *MEDCouplingBasicsTest::build1DSourceMesh_2() +{ + MEDCouplingUMesh *ret=MEDCouplingUMesh::New("1DSourceMesh",1); + ret->allocateCells(4); + int conn[8]={0,1,2,3,1,2,3,4}; + for(int i=0;i<4;i++) + ret->insertNextCell(INTERP_KERNEL::NORM_SEG2,2,conn+2*i); + ret->finishInsertingCells(); + double coords[5]={0.3,0.7,0.9,1.0,1.12}; + DataArrayDouble *myCoords=DataArrayDouble::New(); + myCoords->alloc(5,1); + std::copy(coords,coords+5,myCoords->getPointer()); + ret->setCoords(myCoords); + myCoords->decrRef(); + return ret; +} + +MEDCouplingUMesh *MEDCouplingBasicsTest::build1DTargetMesh_2() +{ + MEDCouplingUMesh *ret=MEDCouplingUMesh::New("1DTargetMesh",1); + ret->allocateCells(2); + int conn[4]={1,2,0,1}; + for(int i=0;i<2;i++) + ret->insertNextCell(INTERP_KERNEL::NORM_SEG2,2,conn+2*i); + ret->finishInsertingCells(); + double coords[3]={0.5,0.75,1.2}; + DataArrayDouble *myCoords=DataArrayDouble::New(); + myCoords->alloc(3,1); + std::copy(coords,coords+3,myCoords->getPointer()); + ret->setCoords(myCoords); + myCoords->decrRef(); + return ret; +} + +MEDCouplingUMesh *MEDCouplingBasicsTest::build2DCurveSourceMesh_2() +{ + MEDCouplingUMesh *ret=MEDCouplingUMesh::New("1DSourceMesh",1); + ret->allocateCells(4); + int conn[8]={0,1,2,3,1,2,3,4}; + for(int i=0;i<4;i++) + ret->insertNextCell(INTERP_KERNEL::NORM_SEG2,2,conn+2*i); + ret->finishInsertingCells(); + double coords[10]={0.3,0.3,0.7,0.7,0.9,0.9,1.0,1.0,1.12,1.12}; + DataArrayDouble *myCoords=DataArrayDouble::New(); + myCoords->alloc(5,2); + std::copy(coords,coords+10,myCoords->getPointer()); + ret->setCoords(myCoords); + myCoords->decrRef(); + return ret; +} + +MEDCouplingUMesh *MEDCouplingBasicsTest::build2DCurveTargetMesh_2() +{ + MEDCouplingUMesh *ret=MEDCouplingUMesh::New("1DTargetMesh",1); + ret->allocateCells(2); + int conn[4]={1,2,0,1}; + for(int i=0;i<2;i++) + ret->insertNextCell(INTERP_KERNEL::NORM_SEG2,2,conn+2*i); + ret->finishInsertingCells(); + double coords[6]={0.5,0.5,0.75,0.75,1.2,1.2}; + DataArrayDouble *myCoords=DataArrayDouble::New(); + myCoords->alloc(3,2); + std::copy(coords,coords+6,myCoords->getPointer()); + ret->setCoords(myCoords); + myCoords->decrRef(); + return ret; +} + +MEDCouplingUMesh *MEDCouplingBasicsTest::build1DTargetMesh_3() +{ + MEDCouplingUMesh *ret=MEDCouplingUMesh::New("1DMesh_3",1); + ret->allocateCells(4); + int conn[10]={0,1,2, 3,4, 6,5,7 ,9,8}; + ret->insertNextCell(INTERP_KERNEL::NORM_SEG3,3,conn); + ret->insertNextCell(INTERP_KERNEL::NORM_SEG2,2,conn+3); + ret->insertNextCell(INTERP_KERNEL::NORM_SEG3,3,conn+5); + ret->insertNextCell(INTERP_KERNEL::NORM_SEG2,2,conn+8); + ret->finishInsertingCells(); + double coords[10]={0.5,1.,0.8,5.,5.21,0.5,1.1,0.7,5.,5.31}; + DataArrayDouble *myCoords=DataArrayDouble::New(); + myCoords->alloc(10,1); + std::copy(coords,coords+10,myCoords->getPointer()); + ret->setCoords(myCoords); + myCoords->decrRef(); + return ret; +} + +MEDCouplingUMesh *MEDCouplingBasicsTest::build2DCurveTargetMesh_3() +{ + MEDCouplingUMesh *ret=MEDCouplingUMesh::New("2DCurveMesh_3",1); + ret->allocateCells(4); + int conn[10]={0,1,2, 3,4, 6,5,7 ,9,8}; + ret->insertNextCell(INTERP_KERNEL::NORM_SEG3,3,conn); + ret->insertNextCell(INTERP_KERNEL::NORM_SEG2,2,conn+3); + ret->insertNextCell(INTERP_KERNEL::NORM_SEG3,3,conn+5); + ret->insertNextCell(INTERP_KERNEL::NORM_SEG2,2,conn+8); + ret->finishInsertingCells(); + double coords[20]={0.5,0.5,1.,1.,0.8,0.8,5.,5.,5.21,5.21,0.5,0.5,1.1,1.1,0.7,0.7,5.,5.,5.31,5.31}; + DataArrayDouble *myCoords=DataArrayDouble::New(); + myCoords->alloc(10,2); + std::copy(coords,coords+20,myCoords->getPointer()); + ret->setCoords(myCoords); + myCoords->decrRef(); + return ret; +} + +MEDCouplingUMesh *MEDCouplingBasicsTest::build2DTargetMesh_3() +{ + MEDCouplingUMesh *ret=MEDCouplingUMesh::New("2DMesh_3",2); + ret->allocateCells(10); + int conn[52]={ + 0,1,2, 0,1,3,4, 0,1,3,5,4, 0,1,2,6,7,8, 0,1,3,4,6,9,2,10, + 0,2,1, 0,4,3,1, 0,4,5,3,1, 0,2,1,8,7,6, 0,4,3,1,10,2,9,6 + }; + ret->insertNextCell(INTERP_KERNEL::NORM_TRI3,3,conn); + ret->insertNextCell(INTERP_KERNEL::NORM_QUAD4,4,conn+3); + ret->insertNextCell(INTERP_KERNEL::NORM_POLYGON,5,conn+7); + ret->insertNextCell(INTERP_KERNEL::NORM_TRI6,6,conn+12); + ret->insertNextCell(INTERP_KERNEL::NORM_QUAD8,8,conn+18); + ret->insertNextCell(INTERP_KERNEL::NORM_TRI3,3,conn+26); + ret->insertNextCell(INTERP_KERNEL::NORM_QUAD4,4,conn+29); + ret->insertNextCell(INTERP_KERNEL::NORM_POLYGON,5,conn+33); + ret->insertNextCell(INTERP_KERNEL::NORM_TRI6,6,conn+38); + ret->insertNextCell(INTERP_KERNEL::NORM_QUAD8,8,conn+44); + ret->finishInsertingCells(); + double coords[22]={0.,0.,1.,0.,0.5,1.,1.,1.,0.,1.,0.5,2.,0.5,0.,0.75,0.5,0.25,0.5,1.,0.5,0.,0.5}; + DataArrayDouble *myCoords=DataArrayDouble::New(); + myCoords->alloc(11,2); + std::copy(coords,coords+22,myCoords->getPointer()); + ret->setCoords(myCoords); + myCoords->decrRef(); + ret->checkCoherency(); + return ret; +} + +/*! + * Same as build2DTargetMesh_1 but with more nodes than needed. To check tryToShareSameCoordsPermute method. + */ +MEDCouplingUMesh *MEDCouplingBasicsTest::build2DTargetMesh_4() +{ + double targetCoords[20]={-0.3,-0.3, 0.2,-0.3, 0.7,-0.3, 0.7,-0.3, -0.3,0.2, 0.2,0.2, 0.7,0.2, -0.3,0.7, 0.2,0.7, 0.7,0.7 }; + int targetConn[18]={0,4,5,1, 1,5,3, 5,6,2, 7,8,5,4, 8,9,6,5}; + MEDCouplingUMesh *targetMesh=MEDCouplingUMesh::New(); + targetMesh->setMeshDimension(2); + targetMesh->allocateCells(5); + targetMesh->insertNextCell(INTERP_KERNEL::NORM_QUAD4,4,targetConn); + targetMesh->insertNextCell(INTERP_KERNEL::NORM_TRI3,3,targetConn+4); + targetMesh->insertNextCell(INTERP_KERNEL::NORM_TRI3,3,targetConn+7); + targetMesh->insertNextCell(INTERP_KERNEL::NORM_QUAD4,4,targetConn+10); + targetMesh->insertNextCell(INTERP_KERNEL::NORM_QUAD4,4,targetConn+14); + targetMesh->finishInsertingCells(); + DataArrayDouble *myCoords=DataArrayDouble::New(); + myCoords->alloc(10,2); + std::copy(targetCoords,targetCoords+20,myCoords->getPointer()); + targetMesh->setCoords(myCoords); + myCoords->decrRef(); + return targetMesh; +} + +MEDCouplingUMesh *MEDCouplingBasicsTest::build3DTargetMesh_3() +{ + return 0; +} + +MEDCouplingMultiFields *MEDCouplingBasicsTest::buildMultiFields_1() +{ + ParaMEDMEM::MEDCouplingUMesh *m1=build2DTargetMesh_1(); + m1->setName("m1"); + ParaMEDMEM::MEDCouplingUMesh *m2=build2DTargetMesh_1(); + m2->setName("m2"); + const double vals0[]={-0.7,-1.,-2.,-3.,-4.}; + const double vals1[]={0.,1.,2.,3.,4.,0.1,0.2,0.3,0.4}; + const double vals1_1[]={170.,171.,172.,173.,174.,170.1,170.2,170.3,170.4}; + const double vals2[]={5.,6.,7.,8.,9.}; + const double vals4[]={15.,16.,17.,18.,19.}; + // + ParaMEDMEM::DataArrayDouble *d0=ParaMEDMEM::DataArrayDouble::New(); d0->alloc(5,1); std::copy(vals0,vals0+5,d0->getPointer()); + ParaMEDMEM::DataArrayDouble *d1=ParaMEDMEM::DataArrayDouble::New(); d1->alloc(9,1); std::copy(vals1,vals1+9,d1->getPointer()); + ParaMEDMEM::DataArrayDouble *d1_1=ParaMEDMEM::DataArrayDouble::New(); d1_1->alloc(9,1); std::copy(vals1_1,vals1_1+9,d1_1->getPointer()); + ParaMEDMEM::DataArrayDouble *d2=ParaMEDMEM::DataArrayDouble::New(); d2->alloc(5,1); std::copy(vals2,vals2+5,d2->getPointer()); + ParaMEDMEM::DataArrayDouble *d4=ParaMEDMEM::DataArrayDouble::New(); d4->alloc(5,1); std::copy(vals4,vals4+5,d4->getPointer()); + // + d0->setName("d0"); d1->setName("d1"); d1_1->setName("d1_1"); d2->setName("d2"); d4->setName("d4"); + d0->setInfoOnComponent(0,"c1"); + d1->setInfoOnComponent(0,"c6"); + d1_1->setInfoOnComponent(0,"c9"); + d2->setInfoOnComponent(0,"c5"); + d4->setInfoOnComponent(0,"c7"); + // + ParaMEDMEM::MEDCouplingFieldDouble *f0=ParaMEDMEM::MEDCouplingFieldDouble::New(ParaMEDMEM::ON_CELLS,ParaMEDMEM::ONE_TIME); + f0->setMesh(m1); + f0->setArray(d0); + f0->setTime(0.2,5,6); + f0->setName("f0"); + ParaMEDMEM::MEDCouplingFieldDouble *f1=ParaMEDMEM::MEDCouplingFieldDouble::New(ParaMEDMEM::ON_NODES,ParaMEDMEM::LINEAR_TIME); + f1->setMesh(m1); + std::vector<ParaMEDMEM::DataArrayDouble *> d1s(2); d1s[0]=d1; d1s[1]=d1_1; + f1->setArrays(d1s); + f1->setStartTime(0.7,7,8); + f1->setEndTime(1.2,9,10); + f1->setName("f1"); + ParaMEDMEM::MEDCouplingFieldDouble *f2=ParaMEDMEM::MEDCouplingFieldDouble::New(ParaMEDMEM::ON_CELLS,ParaMEDMEM::CONST_ON_TIME_INTERVAL); + f2->setMesh(m2); + f2->setArray(d2); + f2->setTime(1.2,11,12); + f2->setEndTime(1.5,13,14); + f2->setName("f2"); + ParaMEDMEM::MEDCouplingFieldDouble *f3=ParaMEDMEM::MEDCouplingFieldDouble::New(ParaMEDMEM::ON_CELLS,ParaMEDMEM::ONE_TIME); + f3->setMesh(m1); + f3->setArray(d2); + f3->setTime(1.7,15,16); + f3->setName("f3"); + ParaMEDMEM::MEDCouplingFieldDouble *f4=ParaMEDMEM::MEDCouplingFieldDouble::New(ParaMEDMEM::ON_CELLS,ParaMEDMEM::NO_TIME); + f4->setMesh(m2); + f4->setArray(d4); + f4->setName("f4"); + // + std::vector<ParaMEDMEM::MEDCouplingFieldDouble *> fs(5); + fs[0]=f0; fs[1]=f1; fs[2]=f2; fs[3]=f3; fs[4]=f4; + ParaMEDMEM::MEDCouplingMultiFields *ret=ParaMEDMEM::MEDCouplingMultiFields::New(fs); + // + m1->decrRef(); + m2->decrRef(); + d0->decrRef(); + d1->decrRef(); + d1_1->decrRef(); + d2->decrRef(); + d4->decrRef(); + f0->decrRef(); + f1->decrRef(); + f2->decrRef(); + f3->decrRef(); + f4->decrRef(); + // + return ret; +} + +std::vector<MEDCouplingFieldDouble *> MEDCouplingBasicsTest::buildMultiFields_2() +{ + ParaMEDMEM::MEDCouplingUMesh *m1=build2DTargetMesh_1(); + m1->setName("m1"); + ParaMEDMEM::MEDCouplingUMesh *m2=build2DTargetMesh_1(); + m2->setName("m2"); + const double vals0[]={-0.7,-1.,-2.,-3.,-4.}; + const double vals1[]={0.,1.,2.,3.,4.}; + const double vals1_1[]={170.,171.,172.,173.,174.}; + const double vals2[]={5.,6.,7.,8.,9.}; + const double vals4[]={15.,16.,17.,18.,19.}; + // + ParaMEDMEM::DataArrayDouble *d0=ParaMEDMEM::DataArrayDouble::New(); d0->alloc(5,1); std::copy(vals0,vals0+5,d0->getPointer()); + ParaMEDMEM::DataArrayDouble *d1=ParaMEDMEM::DataArrayDouble::New(); d1->alloc(5,1); std::copy(vals1,vals1+5,d1->getPointer()); + ParaMEDMEM::DataArrayDouble *d1_1=ParaMEDMEM::DataArrayDouble::New(); d1_1->alloc(5,1); std::copy(vals1_1,vals1_1+5,d1_1->getPointer()); + ParaMEDMEM::DataArrayDouble *d2=ParaMEDMEM::DataArrayDouble::New(); d2->alloc(5,1); std::copy(vals2,vals2+5,d2->getPointer()); + ParaMEDMEM::DataArrayDouble *d4=ParaMEDMEM::DataArrayDouble::New(); d4->alloc(5,1); std::copy(vals4,vals4+5,d4->getPointer()); + // + d0->setName("d0"); d1->setName("d1"); d1_1->setName("d1_1"); d2->setName("d2"); d4->setName("d4"); + d0->setInfoOnComponent(0,"c1"); + d1->setInfoOnComponent(0,"c6"); + d1_1->setInfoOnComponent(0,"c9"); + d2->setInfoOnComponent(0,"c5"); + d4->setInfoOnComponent(0,"c7"); + // + ParaMEDMEM::MEDCouplingFieldDouble *f0=ParaMEDMEM::MEDCouplingFieldDouble::New(ParaMEDMEM::ON_CELLS,ParaMEDMEM::ONE_TIME); + f0->setMesh(m1); + f0->setArray(d0); + f0->setTime(0.2,5,6); + f0->setName("f0"); + ParaMEDMEM::MEDCouplingFieldDouble *f1=ParaMEDMEM::MEDCouplingFieldDouble::New(ParaMEDMEM::ON_CELLS,ParaMEDMEM::LINEAR_TIME); + f1->setMesh(m1); + std::vector<ParaMEDMEM::DataArrayDouble *> d1s(2); d1s[0]=d1; d1s[1]=d1_1; + f1->setArrays(d1s); + f1->setStartTime(0.7,7,8); + f1->setEndTime(1.2,9,10); + f1->setName("f1"); + ParaMEDMEM::MEDCouplingFieldDouble *f2=ParaMEDMEM::MEDCouplingFieldDouble::New(ParaMEDMEM::ON_CELLS,ParaMEDMEM::CONST_ON_TIME_INTERVAL); + f2->setMesh(m2); + f2->setArray(d2); + f2->setTime(1.2,11,12); + f2->setEndTime(1.5,13,14); + f2->setName("f2"); + ParaMEDMEM::MEDCouplingFieldDouble *f3=ParaMEDMEM::MEDCouplingFieldDouble::New(ParaMEDMEM::ON_CELLS,ParaMEDMEM::ONE_TIME); + f3->setMesh(m1); + f3->setArray(d2); + f3->setTime(1.7,15,16); + f3->setName("f3"); + ParaMEDMEM::MEDCouplingFieldDouble *f4=ParaMEDMEM::MEDCouplingFieldDouble::New(ParaMEDMEM::ON_CELLS,ParaMEDMEM::NO_TIME); + f4->setMesh(m2); + f4->setArray(d4); + f4->setName("f4"); + // + std::vector<ParaMEDMEM::MEDCouplingFieldDouble *> fs(5); + fs[0]=f0; fs[1]=f1; fs[2]=f2; fs[3]=f3; fs[4]=f4; + m1->decrRef(); + m2->decrRef(); + d0->decrRef(); + d1->decrRef(); + d1_1->decrRef(); + d2->decrRef(); + d4->decrRef(); + // + return fs; +} + +MEDCouplingUMesh *MEDCouplingBasicsTest::build1DMultiTypes_1() +{ + MEDCouplingUMesh *mesh=MEDCouplingUMesh::New("Multi1DMesh",1); + DataArrayDouble *coo=buildCoordsForMultiTypes_1(); + const int conn[5]={0,2, 0,2,1}; + mesh->allocateCells(2); + mesh->insertNextCell(INTERP_KERNEL::NORM_SEG2,2,conn); + mesh->insertNextCell(INTERP_KERNEL::NORM_SEG3,3,conn+2); + mesh->finishInsertingCells(); + mesh->setCoords(coo); + coo->decrRef(); + return mesh; +} + +MEDCouplingUMesh *MEDCouplingBasicsTest::build2DMultiTypes_1() +{ + MEDCouplingUMesh *mesh=MEDCouplingUMesh::New("Multi2DMesh",2); + DataArrayDouble *coo=buildCoordsForMultiTypes_1(); + const int conn[21]={3,4,5, 3,4,5,6,7,8, 0,9,10,11, 0,9,10,11,12,13,14,15}; + mesh->allocateCells(4); + mesh->insertNextCell(INTERP_KERNEL::NORM_TRI3,3,conn); + mesh->insertNextCell(INTERP_KERNEL::NORM_TRI6,6,conn+3); + mesh->insertNextCell(INTERP_KERNEL::NORM_QUAD4,4,conn+9); + mesh->insertNextCell(INTERP_KERNEL::NORM_QUAD8,8,conn+13); + mesh->finishInsertingCells(); + mesh->setCoords(coo); + coo->decrRef(); + return mesh; +} + +MEDCouplingUMesh *MEDCouplingBasicsTest::build3DMultiTypes_1() +{ + MEDCouplingUMesh *mesh=MEDCouplingUMesh::New("Multi3DMesh",3); + DataArrayDouble *coo=buildCoordsForMultiTypes_1(); + const int conn[81]={0,16,17,18, + 0,16,17,18,19,20,21,22,23,24, + 0,11,10,9,25, + 0,11,10,9,25,15,14,13,12,26,27,28,29, + 0,30,31,32,33,34, + 0,30,31,32,33,34,35,36,37,38,39,40,41,42,43, + 0,9,10,11,44,45,46,47, + 0,9,10,11,44,45,46,47,12,13,14,15,48,49,50,51,52,53,54,55 }; + mesh->allocateCells(8); + mesh->insertNextCell(INTERP_KERNEL::NORM_TETRA4,4,conn); + mesh->insertNextCell(INTERP_KERNEL::NORM_TETRA10,10,conn+4); + mesh->insertNextCell(INTERP_KERNEL::NORM_PYRA5,5,conn+14); + mesh->insertNextCell(INTERP_KERNEL::NORM_PYRA13,13,conn+19); + mesh->insertNextCell(INTERP_KERNEL::NORM_PENTA6,6,conn+32); + mesh->insertNextCell(INTERP_KERNEL::NORM_PENTA15,15,conn+38); + mesh->insertNextCell(INTERP_KERNEL::NORM_HEXA8,8,conn+53); + mesh->insertNextCell(INTERP_KERNEL::NORM_HEXA20,20,conn+61); + mesh->finishInsertingCells(); + mesh->setCoords(coo); + coo->decrRef(); + return mesh; +} + +DataArrayDouble *MEDCouplingBasicsTest::buildCoordsForMultiTypes_1() +{ + DataArrayDouble *coords=DataArrayDouble::New(); + coords->alloc(56,3); + coords->setInfoOnComponent(0,"X (cm)"); + coords->setInfoOnComponent(1,"Y (cm)"); + coords->setInfoOnComponent(2,"Z (cm)"); + const double data[168]={ + 0.0, 0.0, 0.0, //#0 + 0.5, 0.5, 0.5, //#1 + 1.0, 1.0, 1.0, //#2 + 1.0, 1.0, 0.0, //#3 + 2.0, 2.5, 0.0, //#4 + 6.0, 1.5, 0.0, //#5 + 1.0, 2.0, 0.0, //#6 + 4.5, 2.5, 0.0, //#7 + 4.0, 0.5, 0.0, //#8 + 0.0, 4.0, 0.0, //#9 + 4.0, 4.0, 0.0, //#10 + 4.0, 0.0, 0.0, //#11 + 0.0, 2.0, 0.0, //#12 + 2.0, 4.0, 0.0, //#13 + 4.0, 2.0, 0.0, //#14 + 2.0, 0.0, 0.0, //#15 + 0.0, 6.0, 0.0, //#16 + 3.0, 3.0, 0.0, //#17 + 1.3, 3.0, 3.0, //#18 + 0.0, 3.0, 0.0, //#19 + 1.5, 4.5, 0.0, //#20 + 1.5, 1.5, 0.0, //#21 + 0.65, 1.5, 1.5, //#22 + 0.65, 4.5, 1.5, //#23 + 2.15, 3.0, 1.5, //#24 + 2.0, 2.0, 2.0, //#25 + 3.0, 1.0, 1.0, //#26 + 3.0, 3.0, 1.0, //#27 + 1.0, 3.0, 1.0, //#28 + 1.0, 1.0, 1.0, //#29 + 0.0, 3.0, 0.0, //#30 + 2.0, 0.0, 0.0, //#31 + 0.0, 0.0, 6.0, //#32 + 0.0, 3.0, 6.0, //#33 + 3.0, 0.0, 6.0, //#34 + 0.0, 1.5, 0.0, //#35 + 1.5, 1.5, 0.0, //#36 + 1.5, 0.0, 0.0, //#37 + 0.0, 1.5, 6.0, //#38 + 1.5, 1.5, 6.0, //#39 + 1.5, 0.0, 6.0, //#40 + 0.0, 0.0, 3.0, //#41 + 0.0, 3.0, 3.0, //#42 + 3.0, 0.0, 3.0, //#43 + 0.0, 0.0, 4.0, //#44 + 0.0, 4.0, 4.0, //#45 + 4.0, 4.0, 4.0, //#46 + 4.0, 0.0, 4.0, //#47 + 0.0, 2.0, 4.0, //#48 + 2.0, 4.0, 4.0, //#49 + 4.0, 2.0, 4.0, //#50 + 2.0, 0.0, 4.0, //#51 + 0.0, 0.0, 2.0, //#52 + 0.0, 4.0, 2.0, //#53 + 4.0, 4.0, 2.0, //#54 + 4.0, 0.0, 2.0 //#55 + }; + std::copy(data,data+168,coords->getPointer()); + return coords; +} + +MEDCouplingUMesh *MEDCouplingBasicsTest::buildHexa8Mesh_1() +{ + MEDCouplingUMesh *mesh=MEDCouplingUMesh::New("Hexa8Only",3); + DataArrayDouble *coo=DataArrayDouble::New(); + const double coords[81]={0.0, 0.0, 0.0, 0.5, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.5, 0.0, 0.5, 0.5, 0.0, 1.0, 0.5, 0.0, 0.0, 1.0, 0.0, 0.5, 1.0, 0.0, 1.0, 1.0, 0.0, 0.0, 0.0, 0.5, 0.5, 0.0, 0.5, 1.0, 0.0, 0.5, 0.0, 0.5, 0.5, 0.5, 0.5, 0.5, 1.0, 0.5, 0.5, 0.0, 1.0, 0.5, 0.5, 1.0, 0.5, 1.0, 1.0, 0.5, 0.0, 0.0, 1.0, 0.5, 0.0, 1.0, 1.0, 0.0, 1.0, 0.0, 0.5, 1.0, 0.5, 0.5, 1.0, 1.0, 0.5, 1.0, 0.0, 1.0, 1.0, 0.5, 1.0, 1.0, 1.0, 1.0, 1.0}; + coo->alloc(27,3); + std::copy(coords,coords+81,coo->getPointer()); + const int conn[64]={3,12,13,4,0,9,10,1, + 4,13,14,5,1,10,11,2, + 6,15,16,7,3,12,13,4, + 7,16,17,8,4,13,14,5, + 12,21,22,13,9,18,19,10, + 13,22,23,14,10,19,20,11, + 15,24,25,16,12,21,22,13, + 16,25,26,17,13,22,23,14}; + mesh->allocateCells(8); + for(int i=0;i<8;i++) + mesh->insertNextCell(INTERP_KERNEL::NORM_HEXA8,8,conn+8*i); + mesh->finishInsertingCells(); + mesh->setCoords(coo); + coo->decrRef(); + return mesh; +} + +MEDCouplingUMesh *MEDCouplingBasicsTest::buildPointe_1(MEDCouplingUMesh *& m1) +{ + MEDCouplingUMesh *mesh=MEDCouplingUMesh::New("Pointe.med",3); + MEDCouplingUMesh *mesh2=MEDCouplingUMesh::New("Pointe.med",2); + const double coords[57]={0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 2.0, 0.0, 1.0, 0.0, 2.0, 1.0, -2.0, 0.0, 1.0, 0.0, -2.0, 1.0, 1.0, 1.0, 2.0, -1.0, 1.0, 2.0, -1.0, -1.0, 2.0, 1.0, -1.0, 2.0, 1.0, 1.0, 3.0, -1.0, 1.0, 3.0, -1.0, -1.0, 3.0, 1.0, -1.0, 3.0, 1.0, 1.0, 4.0, -1.0, 1.0, 4.0, -1.0, -1.0, 4.0, 1.0, -1.0, 4.0, 0.0, 0.0, 5.0}; + const int conn[74]={0,1,2,5,0,1,3,2,0,1,4,3,0,1,5,4,1,6,3,2,1,7,4,3,1,8,5,4,1,9,2,5,1,6,2,9,1,7,3,6,1,8,4,7,1,9,5,8, 6,7,8,9,1,14,17,16,15,18, 10,11,12,13,6,7,8,9,14,15,16,17,10,11,12,13}; + DataArrayDouble *coo=DataArrayDouble::New(); + coo->alloc(19,3); + std::copy(coords,coords+57,coo->getPointer()); + mesh->setCoords(coo); + mesh2->setCoords(coo); + coo->decrRef(); + mesh->allocateCells(16); + for(int i=0;i<12;i++) + mesh->insertNextCell(INTERP_KERNEL::NORM_TETRA4,4,conn+4*i); + mesh->insertNextCell(INTERP_KERNEL::NORM_PYRA5,5,conn+48); + mesh->insertNextCell(INTERP_KERNEL::NORM_PYRA5,5,conn+53); + mesh->insertNextCell(INTERP_KERNEL::NORM_HEXA8,8,conn+58); + mesh->insertNextCell(INTERP_KERNEL::NORM_HEXA8,8,conn+66); + mesh->finishInsertingCells(); + //[1,34,29,23,41,32] + const int conn2[20]={0,5,1,14,18,17,8,7,4,9,5,2, 12,8,9,13,6,7,8,9}; + mesh2->allocateCells(6); + for(int i=0;i<4;i++) + mesh2->insertNextCell(INTERP_KERNEL::NORM_TRI3,3,conn2+3*i); + mesh2->insertNextCell(INTERP_KERNEL::NORM_QUAD4,4,conn2+12); + mesh2->insertNextCell(INTERP_KERNEL::NORM_QUAD4,4,conn2+16); + mesh2->finishInsertingCells(); + m1=mesh2; + // + return mesh; +} + +double MEDCouplingBasicsTest::sumAll(const std::vector< std::map<int,double> >& matrix) +{ + double ret=0.; + for(std::vector< std::map<int,double> >::const_iterator iter=matrix.begin();iter!=matrix.end();iter++) + for(std::map<int,double>::const_iterator iter2=(*iter).begin();iter2!=(*iter).end();iter2++) + ret+=(*iter2).second; + return ret; +} + +MEDCouplingUMesh *MEDCouplingBasicsTest::build2D1DSourceMesh() +{ + double sourceCoords[18]={-17., 3., -17., 8., -5., 8., + -5., 3., -9., 0., -13., 3., + -9., 8., -7., 0., -7., 8. + }; + int sourceConn[16]={0,1, 1,2, 2,3, 3,0, 3,4, 4,5, 4,6, 7,8}; + MEDCouplingUMesh *sourceMesh=MEDCouplingUMesh::New(); + sourceMesh->setMeshDimension(1); + sourceMesh->allocateCells(8); + sourceMesh->insertNextCell(INTERP_KERNEL::NORM_SEG2,2,sourceConn); + sourceMesh->insertNextCell(INTERP_KERNEL::NORM_SEG2,2,sourceConn+2); + sourceMesh->insertNextCell(INTERP_KERNEL::NORM_SEG2,2,sourceConn+4); + sourceMesh->insertNextCell(INTERP_KERNEL::NORM_SEG2,2,sourceConn+6); + sourceMesh->insertNextCell(INTERP_KERNEL::NORM_SEG2,2,sourceConn+8); + sourceMesh->insertNextCell(INTERP_KERNEL::NORM_SEG2,2,sourceConn+10); + sourceMesh->insertNextCell(INTERP_KERNEL::NORM_SEG2,2,sourceConn+12); + sourceMesh->insertNextCell(INTERP_KERNEL::NORM_SEG2,2,sourceConn+14); + sourceMesh->finishInsertingCells(); + DataArrayDouble *myCoords=DataArrayDouble::New(); + myCoords->alloc(9,2); + std::copy(sourceCoords,sourceCoords+18,myCoords->getPointer()); + sourceMesh->setCoords(myCoords); + myCoords->decrRef(); + return sourceMesh; +} + +MEDCouplingUMesh *MEDCouplingBasicsTest::build2D1DTargetMesh() +{ + double targetCoords[10]={-17., 0., -17.,6., -9.,6., -9.,0., -5., 3.}; + int targetConn[7]={0,1,2,3, 2,3,4}; + MEDCouplingUMesh *targetMesh=MEDCouplingUMesh::New(); + targetMesh->setMeshDimension(2); + targetMesh->allocateCells(2); + targetMesh->insertNextCell(INTERP_KERNEL::NORM_QUAD4,4,targetConn); + targetMesh->insertNextCell(INTERP_KERNEL::NORM_TRI3 ,3,targetConn + 4); + targetMesh->finishInsertingCells(); + DataArrayDouble *myCoords=DataArrayDouble::New(); + myCoords->alloc(5,2); + std::copy(targetCoords,targetCoords+10,myCoords->getPointer()); + targetMesh->setCoords(myCoords); + myCoords->decrRef(); + return targetMesh; +} + +MEDCouplingUMesh* MEDCouplingBasicsTest::build2D1DSegSourceMesh(const double shiftX, + const double inclinationX) +{ + MEDCouplingUMesh *sourceMesh=MEDCouplingUMesh::New(); + sourceMesh->setMeshDimension(1); + + const int nbY = 4; + const int nbYP1 = nbY + 1; + sourceMesh->allocateCells(nbY); + + int sourceConn[2]; + for (int iY = 0; iY < nbY; ++iY) + { + sourceConn[0] = iY ; + sourceConn[1] = iY + 1; + sourceMesh->insertNextCell(INTERP_KERNEL::NORM_SEG2,2,sourceConn); + } + sourceMesh->finishInsertingCells(); + + std::vector<double> sourceCoords; + for (int iY = 0; iY < nbYP1; ++iY) + { + sourceCoords.push_back(iY * inclinationX + shiftX); + sourceCoords.push_back(iY * 4.); + } + DataArrayDouble *myCoords=DataArrayDouble::New(); + myCoords->alloc(nbYP1,2); + std::copy(sourceCoords.begin(),sourceCoords.end(),myCoords->getPointer()); + sourceMesh->setCoords(myCoords); + myCoords->decrRef(); + + return sourceMesh; +} + +MEDCouplingUMesh* MEDCouplingBasicsTest::build2D1DQuadTargetMesh(const double inclinationX) +{ + MEDCouplingUMesh *targetMesh=MEDCouplingUMesh::New(); + targetMesh->setMeshDimension(2); + + const int nbX = 5; + const int nbY = 4; + const int nbXP1 = nbX + 1; + const int nbYP1 = nbY + 1; + targetMesh->allocateCells(nbX * nbY); + + int targetConn[4]; + for (int iX = 0; iX < nbX; ++iX) + { + for (int iY = 0; iY < nbY; ++iY) + { + targetConn[0] = iY + iX * nbYP1; + targetConn[1] = iY + 1 + iX * nbYP1; + targetConn[2] = iY + 1 + (iX + 1) * nbYP1; + targetConn[3] = iY + (iX + 1) * nbYP1; + targetMesh->insertNextCell(INTERP_KERNEL::NORM_QUAD4,4,targetConn); + } + } + targetMesh->finishInsertingCells(); + + std::vector<double> targetCoords; + for (int iX = 0; iX < nbXP1; ++iX) + { + for (int iY = 0; iY < nbYP1; ++iY) + { + targetCoords.push_back(iX * 3. + iY * inclinationX); + targetCoords.push_back(iY * 4.); + } + } + DataArrayDouble *myCoords=DataArrayDouble::New(); + myCoords->alloc(nbXP1 * nbYP1, 2); + std::copy(targetCoords.begin(),targetCoords.end(),myCoords->getPointer()); + targetMesh->setCoords(myCoords); + myCoords->decrRef(); + + return targetMesh; +} + +MEDCouplingUMesh* MEDCouplingBasicsTest::build2D1DTriTargetMesh(const double inclinationX) +{ + MEDCouplingUMesh *targetMesh=MEDCouplingUMesh::New(); + targetMesh->setMeshDimension(2); + + const int nbX = 5; + const int nbY = 4; + const int nbXP1 = nbX + 1; + const int nbYP1 = nbY + 1; + targetMesh->allocateCells(nbX * nbY * 2); + + int targetConn[3]; + for (int iX = 0; iX < nbX; ++iX) + { + for (int iY = 0; iY < nbY; ++iY) + { + targetConn[0] = iY + iX * nbYP1; + targetConn[1] = iY + 1 + iX * nbYP1; + targetConn[2] = iY + 1 + (iX + 1) * nbYP1; + targetMesh->insertNextCell(INTERP_KERNEL::NORM_TRI3,3,targetConn); + targetConn[0] = iY + iX * nbYP1; + targetConn[1] = iY + 1 + (iX + 1) * nbYP1; + targetConn[2] = iY + (iX + 1) * nbYP1; + targetMesh->insertNextCell(INTERP_KERNEL::NORM_TRI3,3,targetConn); + } + } + targetMesh->finishInsertingCells(); + + std::vector<double> targetCoords; + for (int iX = 0; iX < nbXP1; ++iX) + { + for (int iY = 0; iY < nbYP1; ++iY) + { + targetCoords.push_back(iX * 3. + iY * inclinationX); + targetCoords.push_back(iY * 4.); + } + } + DataArrayDouble *myCoords=DataArrayDouble::New(); + myCoords->alloc(nbXP1 * nbYP1, 2); + std::copy(targetCoords.begin(),targetCoords.end(),myCoords->getPointer()); + targetMesh->setCoords(myCoords); + myCoords->decrRef(); + + return targetMesh; +} + +MEDCouplingUMesh *MEDCouplingBasicsTest::build3D2DSourceMesh() +{ + double sourceCoords[63]={-12., 6., 10., -12.,10., 6., -16.,10. , 10., + -20., 0., 0., -12., 0., 0., -12., 0. , -4., -20.,0.,-4., + -20., 0., 10., -12., 0., 10., -20.,10. , 10., + -25., 5., -5., 5., 5., -5., 5., 5. , 25., -25.,5.,25., + -20., 0., 16., -18., 0., 16., -20., 2.5, 16., + -25., 0., -5., 5., 0., -5., 5., 0. , 25., -25.,0.,25. + }; + int sourceConn[25]={0,1,2, 3,4,5,6, 7,8,9, 10,11,12,13, 14,15,16, 3,4,8,7, 17,18,19,20}; + MEDCouplingUMesh *sourceMesh=MEDCouplingUMesh::New(); + sourceMesh->setMeshDimension(2); + sourceMesh->allocateCells(7); + sourceMesh->insertNextCell(INTERP_KERNEL::NORM_TRI3 ,3,sourceConn); + sourceMesh->insertNextCell(INTERP_KERNEL::NORM_QUAD4,4,sourceConn+3); + sourceMesh->insertNextCell(INTERP_KERNEL::NORM_TRI3 ,3,sourceConn+7); + sourceMesh->insertNextCell(INTERP_KERNEL::NORM_QUAD4,4,sourceConn+10); + sourceMesh->insertNextCell(INTERP_KERNEL::NORM_TRI3 ,3,sourceConn+14); + sourceMesh->insertNextCell(INTERP_KERNEL::NORM_QUAD4,4,sourceConn+17); + sourceMesh->insertNextCell(INTERP_KERNEL::NORM_QUAD4,4,sourceConn+21); + sourceMesh->finishInsertingCells(); + DataArrayDouble *myCoords=DataArrayDouble::New(); + myCoords->alloc(21,3); + std::copy(sourceCoords,sourceCoords+63,myCoords->getPointer()); + sourceMesh->setCoords(myCoords); + myCoords->decrRef(); + return sourceMesh; +} + +MEDCouplingUMesh *MEDCouplingBasicsTest::build3D2DTargetMesh() +{ + double targetCoords[45]={-20., 0., 0., -20.,10., 0., -12.,10., 0., + -12., 0., 0., -20., 0.,10., -20.,10.,10., + -12.,10.,10., -12., 0.,10., -20., 0.,18., + -20.,-5.,10., -20.,-5.,-4., -12.,-5.,-4., + -12.,-5.,10., -20., 0.,-4., -12., 0.,-4. + }; + int targetConn[20]={4,5,7,8, 0,3,2,1,4,7,6,5, 4,13,14,7,9,10,11,12}; + MEDCouplingUMesh *targetMesh=MEDCouplingUMesh::New(); + targetMesh->setMeshDimension(3); + targetMesh->allocateCells(3); + targetMesh->insertNextCell(INTERP_KERNEL::NORM_TETRA4,4,targetConn); + targetMesh->insertNextCell(INTERP_KERNEL::NORM_HEXA8,8,targetConn + 4); + targetMesh->insertNextCell(INTERP_KERNEL::NORM_HEXA8,8,targetConn + 12); + targetMesh->finishInsertingCells(); + DataArrayDouble *myCoords=DataArrayDouble::New(); + myCoords->alloc(15,3); + std::copy(targetCoords,targetCoords+45,myCoords->getPointer()); + targetMesh->setCoords(myCoords); + myCoords->decrRef(); + return targetMesh; +} + +MEDCouplingUMesh* MEDCouplingBasicsTest::build3D2DQuadSourceMesh(const double shiftX, + const double inclinationX) +{ + MEDCouplingUMesh *sourceMesh=MEDCouplingUMesh::New(); + sourceMesh->setMeshDimension(2); + + const int nbY = 4; + const int nbZ = 5; + const int nbYP1 = nbY + 1; + const int nbZP1 = nbZ + 1; + sourceMesh->allocateCells(nbY * nbZ); + + int sourceConn[4]; + for (int iY = 0; iY < nbY; ++iY) + { + for (int iZ = 0; iZ < nbZ; ++iZ) + { + sourceConn[0] = iZ + iY * nbZP1; + sourceConn[1] = iZ + 1 + iY * nbZP1; + sourceConn[2] = iZ + 1 + (iY + 1) * nbZP1; + sourceConn[3] = iZ + (iY + 1) * nbZP1; + sourceMesh->insertNextCell(INTERP_KERNEL::NORM_QUAD4,4,sourceConn); + } + } + sourceMesh->finishInsertingCells(); + + std::vector<double> sourceCoords; + for (int iY = 0; iY < nbYP1; ++iY) + { + for (int iZ = 0; iZ < nbZP1; ++iZ) + { + sourceCoords.push_back(iY * inclinationX + shiftX); + sourceCoords.push_back(iY * 4.); + sourceCoords.push_back(iZ * 3.); + } + + } + DataArrayDouble *myCoords=DataArrayDouble::New(); + myCoords->alloc(nbYP1 * nbZP1,3); + std::copy(sourceCoords.begin(),sourceCoords.end(),myCoords->getPointer()); + sourceMesh->setCoords(myCoords); + myCoords->decrRef(); + + return sourceMesh; +} + +MEDCouplingUMesh* MEDCouplingBasicsTest::build3D2DTriSourceMesh(const double shiftX, + const double inclinationX) +{ + MEDCouplingUMesh *sourceMesh=MEDCouplingUMesh::New(); + sourceMesh->setMeshDimension(2); + + const int nbY = 4; + const int nbZ = 5; + const int nbYP1 = nbY + 1; + const int nbZP1 = nbZ + 1; + sourceMesh->allocateCells(nbY * nbZ * 2); + + int sourceConn[3]; + for (int iY = 0; iY < nbY; ++iY) + { + for (int iZ = 0; iZ < nbZ; ++iZ) + { + sourceConn[0] = iZ + iY * nbZP1; + sourceConn[1] = iZ + 1 + iY * nbZP1; + sourceConn[2] = iZ + 1 + (iY + 1) * nbZP1; + sourceMesh->insertNextCell(INTERP_KERNEL::NORM_TRI3,3,sourceConn); + sourceConn[0] = iZ + iY * nbZP1; + sourceConn[1] = iZ + (iY + 1) * nbZP1; + sourceConn[2] = iZ + 1 + (iY + 1) * nbZP1; + sourceMesh->insertNextCell(INTERP_KERNEL::NORM_TRI3,3,sourceConn); + } + } + sourceMesh->finishInsertingCells(); + + std::vector<double> sourceCoords; + for (int iY = 0; iY < nbYP1; ++iY) + { + for (int iZ = 0; iZ < nbZP1; ++iZ) + { + sourceCoords.push_back(iY * inclinationX + shiftX); + sourceCoords.push_back(iY * 4.); + sourceCoords.push_back(iZ * 3.); + } + + } + DataArrayDouble *myCoords=DataArrayDouble::New(); + myCoords->alloc(nbYP1 * nbZP1,3); + std::copy(sourceCoords.begin(),sourceCoords.end(),myCoords->getPointer()); + sourceMesh->setCoords(myCoords); + myCoords->decrRef(); + + return sourceMesh; +} + +MEDCouplingUMesh* MEDCouplingBasicsTest::build3D2DHexaTargetMesh(const double inclinationX) +{ + MEDCouplingUMesh *targetMesh=MEDCouplingUMesh::New(); + targetMesh->setMeshDimension(3); + + const int nbX = 5; + const int nbY = 4; + const int nbZ = 5; + const int nbXP1 = nbX + 1; + const int nbYP1 = nbY + 1; + const int nbZP1 = nbZ + 1; + targetMesh->allocateCells(nbX * nbY * nbZ); + + int targetConn[8]; + for (int iX = 0; iX < nbX; ++iX) + { + for (int iY = 0; iY < nbY; ++iY) + { + for (int iZ = 0; iZ < nbZ; ++iZ) + { + targetConn[0] = iZ + ( iY + iX * nbYP1) * nbZP1; + targetConn[1] = iZ + 1 + ( iY + iX * nbYP1) * nbZP1; + targetConn[2] = iZ + 1 + ((iY + 1) + iX * nbYP1) * nbZP1; + targetConn[3] = iZ + ((iY + 1) + iX * nbYP1) * nbZP1; + targetConn[4] = iZ + ( iY + (iX + 1) * nbYP1) * nbZP1; + targetConn[5] = iZ + 1 + ( iY + (iX + 1) * nbYP1) * nbZP1; + targetConn[6] = iZ + 1 + ((iY + 1) + (iX + 1) * nbYP1) * nbZP1; + targetConn[7] = iZ + ((iY + 1) + (iX + 1) * nbYP1) * nbZP1; + targetMesh->insertNextCell(INTERP_KERNEL::NORM_HEXA8,8,targetConn); + } + } + } + targetMesh->finishInsertingCells(); + + std::vector<double> targetCoords; + for (int iX = 0; iX < nbXP1; ++iX) + { + for (int iY = 0; iY < nbYP1; ++iY) + { + for (int iZ = 0; iZ < nbZP1; ++iZ) + { + targetCoords.push_back(iX * 3. + iY * inclinationX); + targetCoords.push_back(iY * 4.); + targetCoords.push_back(iZ * 3.); + } + } + } + DataArrayDouble *myCoords=DataArrayDouble::New(); + myCoords->alloc(nbXP1 * nbYP1 * nbZP1, 3); + std::copy(targetCoords.begin(),targetCoords.end(),myCoords->getPointer()); + targetMesh->setCoords(myCoords); + myCoords->decrRef(); + + return targetMesh; +} + +MEDCouplingUMesh* MEDCouplingBasicsTest::build3D2DTetraTargetMesh(const double inclinationX) +{ + MEDCouplingUMesh *targetMesh=MEDCouplingUMesh::New(); + targetMesh->setMeshDimension(3); + + const int nbX = 5; + const int nbY = 4; + const int nbZ = 5; + const int nbXP1 = nbX + 1; + const int nbYP1 = nbY + 1; + const int nbZP1 = nbZ + 1; + targetMesh->allocateCells(nbX * nbY * nbZ * 5); + + int targetConn[4]; + for (int iX = 0; iX < nbX; ++iX) + { + for (int iY = 0; iY < nbY; ++iY) + { + for (int iZ = 0; iZ < nbZ; ++iZ) + { + targetConn[0] = iZ + ( iY + iX * nbYP1) * nbZP1; + targetConn[1] = iZ + 1 + ( iY + iX * nbYP1) * nbZP1; + targetConn[2] = iZ + 1 + ( iY + (iX + 1) * nbYP1) * nbZP1; + targetConn[3] = iZ + 1 + ((iY + 1) + iX * nbYP1) * nbZP1; + targetMesh->insertNextCell(INTERP_KERNEL::NORM_TETRA4,4,targetConn); + targetConn[0] = iZ + ( iY + iX * nbYP1) * nbZP1; + targetConn[1] = iZ + ( iY + (iX + 1) * nbYP1) * nbZP1; + targetConn[2] = iZ + 1 + ( iY + (iX + 1) * nbYP1) * nbZP1; + targetConn[3] = iZ + ((iY + 1) + (iX + 1) * nbYP1) * nbZP1; + targetMesh->insertNextCell(INTERP_KERNEL::NORM_TETRA4,4,targetConn); + targetConn[0] = iZ + ( iY + iX * nbYP1) * nbZP1; + targetConn[1] = iZ + ((iY + 1) + iX * nbYP1) * nbZP1; + targetConn[2] = iZ + ((iY + 1) + (iX + 1) * nbYP1) * nbZP1; + targetConn[3] = iZ + 1 + ((iY + 1) + iX * nbYP1) * nbZP1; + targetMesh->insertNextCell(INTERP_KERNEL::NORM_TETRA4,4,targetConn); + targetConn[0] = iZ + 1 + ( iY + (iX + 1) * nbYP1) * nbZP1; + targetConn[1] = iZ + 1 + ((iY + 1) + (iX + 1) * nbYP1) * nbZP1; + targetConn[2] = iZ + ((iY + 1) + (iX + 1) * nbYP1) * nbZP1; + targetConn[3] = iZ + 1 + ((iY + 1) + iX * nbYP1) * nbZP1; + targetMesh->insertNextCell(INTERP_KERNEL::NORM_TETRA4,4,targetConn); + targetConn[0] = iZ + ( iY + iX * nbYP1) * nbZP1; + targetConn[1] = iZ + 1 + ((iY + 1) + iX * nbYP1) * nbZP1; + targetConn[2] = iZ + 1 + ( iY + (iX + 1) * nbYP1) * nbZP1; + targetConn[3] = iZ + ((iY + 1) + (iX + 1) * nbYP1) * nbZP1; + targetMesh->insertNextCell(INTERP_KERNEL::NORM_TETRA4,4,targetConn); + } + } + } + targetMesh->finishInsertingCells(); + + std::vector<double> targetCoords; + for (int iX = 0; iX < nbXP1; ++iX) + { + for (int iY = 0; iY < nbYP1; ++iY) + { + for (int iZ = 0; iZ < nbZP1; ++iZ) + { + targetCoords.push_back(iX * 3. + iY * inclinationX); + targetCoords.push_back(iY * 4.); + targetCoords.push_back(iZ * 3.); + } + } + } + DataArrayDouble *myCoords=DataArrayDouble::New(); + myCoords->alloc(nbXP1 * nbYP1 * nbZP1, 3); + std::copy(targetCoords.begin(),targetCoords.end(),myCoords->getPointer()); + targetMesh->setCoords(myCoords); + myCoords->decrRef(); + + return targetMesh; +} + +int MEDCouplingBasicsTest::countNonZero(const std::vector< std::map<int,double> >& matrix) +{ + int ret=0.; + for(std::vector< std::map<int,double> >::const_iterator iter=matrix.begin();iter!=matrix.end();iter++) + for(std::map<int,double>::const_iterator iter2=(*iter).begin();iter2!=(*iter).end();iter2++) + if (!INTERP_KERNEL::epsilonEqual((*iter2).second, 0.)) ret +=1; + return ret; +} + +void MEDCouplingBasicsTest::test2D1DMeshesIntersection(MEDCouplingUMesh *sourceMesh, + MEDCouplingUMesh *targetMesh, + const double correctLength, + const int correctDuplicateFacesNbr, + const int correctTotalIntersectFacesNbr) +{ + MEDCouplingNormalizedUnstructuredMesh<2,2> sourceWrapper(sourceMesh); + MEDCouplingNormalizedUnstructuredMesh<2,2> targetWrapper(targetMesh); + INTERP_KERNEL::Interpolation2D1D myInterpolator; + myInterpolator.setPrecision(1e-12); + const double prec = 1.0e-5; + IntersectionMatrix matrix; + myInterpolator.setIntersectionType(INTERP_KERNEL::Geometric2D); + myInterpolator.interpolateMeshes(sourceWrapper,targetWrapper,matrix,"P0P0"); + + std::cout.precision(16); + + const double length = sumAll(matrix); + LOG(1, "length = " << surf <<" correctLength = " << correctLength ); + CPPUNIT_ASSERT_DOUBLES_EQUAL(correctLength, length, prec * std::max(correctLength, length)); + + INTERP_KERNEL::Interpolation3D2D::DuplicateFacesType duplicateFaces = myInterpolator.retrieveDuplicateFaces(); + int duplicateFacesNbr = duplicateFaces.size(); + LOG(1, "duplicateFacesNbr = " << duplicateFacesNbr <<" correctDuplicateFacesNbr = " << correctDuplicateFacesNbr); + CPPUNIT_ASSERT_EQUAL(correctDuplicateFacesNbr, duplicateFacesNbr); + + if (correctTotalIntersectFacesNbr >= 0) + { + int totalIntersectFacesNbr = countNonZero(matrix); + LOG(1, "totalIntersectFacesNbr = " << totalIntersectFacesNbr <<" correctTotalIntersectFacesNbr = " << correctTotalIntersectFacesNbr ); + CPPUNIT_ASSERT_EQUAL(correctTotalIntersectFacesNbr, totalIntersectFacesNbr); + } + //clean up + sourceMesh->decrRef(); + targetMesh->decrRef(); +} + +void MEDCouplingBasicsTest::test3D2DMeshesIntersection(MEDCouplingUMesh *sourceMesh, + MEDCouplingUMesh *targetMesh, + const double correctSurf, + const int correctDuplicateFacesNbr, + const int correctTotalIntersectFacesNbr) +{ + MEDCouplingNormalizedUnstructuredMesh<3,3> sourceWrapper(sourceMesh); + MEDCouplingNormalizedUnstructuredMesh<3,3> targetWrapper(targetMesh); + INTERP_KERNEL::Interpolation3D2D myInterpolator; + myInterpolator.setPrecision(1e-12); + const double prec = 1.0e-5; + IntersectionMatrix matrix; + INTERP_KERNEL::SplittingPolicy sp[] = { INTERP_KERNEL::PLANAR_FACE_5, INTERP_KERNEL::PLANAR_FACE_6, INTERP_KERNEL::GENERAL_24, INTERP_KERNEL::GENERAL_48 }; + for ( size_t i = 0; i < sizeof(sp)/sizeof(sp[0]); ++i ) + { + myInterpolator.setSplittingPolicy( sp[i] ); + matrix.clear(); + myInterpolator.interpolateMeshes(sourceWrapper,targetWrapper,matrix,"P0P0"); + + std::cout.precision(16); + + const double surf = sumAll(matrix); + LOG(1, "surf = " << surf <<" correctSurf = " << correctSurf ); + CPPUNIT_ASSERT_DOUBLES_EQUAL(correctSurf, surf, prec * std::max(correctSurf, surf)); + + INTERP_KERNEL::Interpolation3D2D::DuplicateFacesType duplicateFaces = myInterpolator.retrieveDuplicateFaces(); + int duplicateFacesNbr = duplicateFaces.size(); + LOG(1, "duplicateFacesNbr = " << duplicateFacesNbr <<" correctDuplicateFacesNbr = " << correctDuplicateFacesNbr); + CPPUNIT_ASSERT_EQUAL(correctDuplicateFacesNbr, duplicateFacesNbr); + + if (correctTotalIntersectFacesNbr >= 0) + { + int totalIntersectFacesNbr = countNonZero(matrix); + LOG(1, "totalIntersectFacesNbr = " << totalIntersectFacesNbr <<" correctTotalIntersectFacesNbr = " << correctTotalIntersectFacesNbr ); + CPPUNIT_ASSERT_EQUAL(correctTotalIntersectFacesNbr, totalIntersectFacesNbr); + } + } + //clean up + sourceMesh->decrRef(); + targetMesh->decrRef(); +} diff --git a/src/medtool/src/MEDCoupling/Test/MEDCouplingBasicsTest1.cxx b/src/medtool/src/MEDCoupling/Test/MEDCouplingBasicsTest1.cxx new file mode 100644 index 000000000..49d3ed779 --- /dev/null +++ b/src/medtool/src/MEDCoupling/Test/MEDCouplingBasicsTest1.cxx @@ -0,0 +1,2694 @@ +// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 +// 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 "MEDCouplingBasicsTest1.hxx" +#include "MEDCouplingUMesh.hxx" +#include "MEDCouplingCMesh.hxx" +#include "MEDCouplingExtrudedMesh.hxx" +#include "MEDCouplingFieldDouble.hxx" +#include "MEDCouplingMemArray.hxx" + +#include <sstream> +#include <cmath> +#include <algorithm> +#include <functional> + +using namespace ParaMEDMEM; + +void MEDCouplingBasicsTest1::testArray() +{ + int tmp1[6]={7,6,5,4,3,2}; + const int tmp2[3]={8,9,10}; + { + MemArray<int> mem; + mem.useArray(tmp1,false,CPP_DEALLOC,6); + CPPUNIT_ASSERT(tmp1==mem.getConstPointer()); + CPPUNIT_ASSERT_THROW(mem.getPointer(),INTERP_KERNEL::Exception); + CPPUNIT_ASSERT_THROW(mem[2]=7,INTERP_KERNEL::Exception); + CPPUNIT_ASSERT_THROW(mem.writeOnPlace(0,12,tmp2,3),INTERP_KERNEL::Exception); + mem.writeOnPlace(4,12,tmp2,3); + } + { + int *tmp3=new int[6]; + std::copy(tmp1,tmp1+6,tmp3); + MemArray<int> mem2; + mem2.useArray(tmp3,true,CPP_DEALLOC,6); + CPPUNIT_ASSERT(tmp3==mem2.getConstPointer()); + CPPUNIT_ASSERT(tmp3==mem2.getPointer()); + CPPUNIT_ASSERT_EQUAL(5,mem2[2]); + mem2[2]=7; + CPPUNIT_ASSERT_EQUAL(7,mem2[2]); + mem2.writeOnPlace(0,12,tmp2,3); + CPPUNIT_ASSERT_EQUAL(9,mem2[2]); + CPPUNIT_ASSERT_EQUAL(12,mem2[0]); + mem2.writeOnPlace(4,12,tmp2,3); + } +} + +void MEDCouplingBasicsTest1::testArray2() +{ + DataArrayDouble *arr=DataArrayDouble::New(); + arr->alloc(3,4); + double *tmp=arr->getPointer(); + const double arrRef[12]={12.,11.,10.,9.,8.,7.,6.,5.,4.,3.,2.,1.}; + std::copy(arrRef,arrRef+12,tmp); + arr->setInfoOnComponent(0,"ggg"); + arr->setInfoOnComponent(1,"hhhh"); + arr->setInfoOnComponent(2,"jj"); + arr->setInfoOnComponent(3,"kkkkkk"); + DataArrayInt *arr2=arr->convertToIntArr(); + DataArrayDouble *arr3=arr2->convertToDblArr(); + arr2->decrRef(); + CPPUNIT_ASSERT(arr->isEqual(*arr3,1e-14)); + arr3->decrRef(); + arr->decrRef(); +} + +void MEDCouplingBasicsTest1::testArray3() +{ + DataArrayInt *arr1=DataArrayInt::New(); + arr1->alloc(7,2); + int *tmp=arr1->getPointer(); + const int arr1Ref[14]={0,10,1,11,2,12,3,13,4,14,5,15,6,16}; + std::copy(arr1Ref,arr1Ref+14,tmp); + CPPUNIT_ASSERT_EQUAL(7,arr1->getNumberOfTuples()); + CPPUNIT_ASSERT_EQUAL(2,arr1->getNumberOfComponents()); + CPPUNIT_ASSERT(std::equal(arr1Ref,arr1Ref+14,arr1->getConstPointer())); + DataArrayInt *arr2=arr1->substr(3); + CPPUNIT_ASSERT_EQUAL(4,arr2->getNumberOfTuples()); + CPPUNIT_ASSERT_EQUAL(2,arr2->getNumberOfComponents()); + CPPUNIT_ASSERT(std::equal(arr1Ref+6,arr1Ref+14,arr2->getConstPointer())); + arr2->decrRef(); + DataArrayInt *arr3=arr1->substr(2,5); + CPPUNIT_ASSERT_EQUAL(3,arr3->getNumberOfTuples()); + CPPUNIT_ASSERT_EQUAL(2,arr3->getNumberOfComponents()); + CPPUNIT_ASSERT(std::equal(arr1Ref+4,arr1Ref+10,arr3->getConstPointer())); + arr1->decrRef(); + arr3->decrRef(); + // + DataArrayDouble *arr4=DataArrayDouble::New(); + arr4->alloc(7,2); + double *tmp2=arr4->getPointer(); + const double arr4Ref[14]={0.8,10.8,1.9,11.9,2.1,12.1,3.2,13.2,4.3,14.3,5.4,15.4,6.5,16.5}; + std::copy(arr4Ref,arr4Ref+14,tmp2); + CPPUNIT_ASSERT_EQUAL(7,arr4->getNumberOfTuples()); + CPPUNIT_ASSERT_EQUAL(2,arr4->getNumberOfComponents()); + CPPUNIT_ASSERT(std::equal(arr4Ref,arr4Ref+14,arr4->getConstPointer())); + DataArrayDouble *arr5=arr4->substr(3); + CPPUNIT_ASSERT_EQUAL(4,arr5->getNumberOfTuples()); + CPPUNIT_ASSERT_EQUAL(2,arr5->getNumberOfComponents()); + CPPUNIT_ASSERT(std::equal(arr4Ref+6,arr4Ref+14,arr5->getConstPointer())); + arr5->decrRef(); + DataArrayDouble *arr6=arr4->substr(2,5); + CPPUNIT_ASSERT_EQUAL(3,arr6->getNumberOfTuples()); + CPPUNIT_ASSERT_EQUAL(2,arr6->getNumberOfComponents()); + CPPUNIT_ASSERT(std::equal(arr4Ref+4,arr4Ref+10,arr6->getConstPointer())); + arr4->decrRef(); + arr6->decrRef(); +} + +void MEDCouplingBasicsTest1::testMesh() +{ + const int nbOfCells=6; + const int nbOfNodes=12; + + double coords[3*nbOfNodes]={ + 0.024155, 0.04183768725682622, -0.305, 0.04831000000000001, -1.015761910347357e-17, -0.305, 0.09662000000000001, -1.832979297858306e-18, + -0.305, 0.120775, 0.04183768725682623, -0.305, 0.09662000000000001, 0.08367537451365245, -0.305, 0.04831000000000001, + 0.08367537451365246, -0.305, 0.024155, 0.04183768725682622, -0.2863, 0.04831000000000001, -1.015761910347357e-17, -0.2863, + 0.09662000000000001, -1.832979297858306e-18, -0.2863, 0.120775, 0.04183768725682623, -0.2863, 0.09662000000000001, 0.08367537451365245, + -0.2863, 0.04831000000000001, 0.08367537451365246, -0.2863, }; + + int tab4[4*nbOfCells]={ + 1, 2, 8, 7, 2, 3, 9, 8, 3, 4, 10, 9, 4, 5, 11, 10, 5, 0, 6, 11, + 0, 1, 7, 6, }; + CPPUNIT_ASSERT_EQUAL(MEDCouplingMesh::GetNumberOfNodesOfGeometricType(INTERP_KERNEL::NORM_TRI3),3); + CPPUNIT_ASSERT(MEDCouplingMesh::IsStaticGeometricType(INTERP_KERNEL::NORM_TRI3)); + CPPUNIT_ASSERT(MEDCouplingMesh::IsLinearGeometricType(INTERP_KERNEL::NORM_TRI3)); + CPPUNIT_ASSERT_EQUAL(MEDCouplingMesh::GetDimensionOfGeometricType(INTERP_KERNEL::NORM_TRI3),2); + CPPUNIT_ASSERT_EQUAL(std::string(MEDCouplingMesh::GetReprOfGeometricType(INTERP_KERNEL::NORM_TRI3)),std::string("NORM_TRI3")); + CPPUNIT_ASSERT_THROW(MEDCouplingMesh::GetNumberOfNodesOfGeometricType(INTERP_KERNEL::NORM_POLYGON),INTERP_KERNEL::Exception); + CPPUNIT_ASSERT(!MEDCouplingMesh::IsStaticGeometricType(INTERP_KERNEL::NORM_POLYGON)); + CPPUNIT_ASSERT(MEDCouplingMesh::IsLinearGeometricType(INTERP_KERNEL::NORM_POLYGON)); + CPPUNIT_ASSERT_EQUAL(MEDCouplingMesh::GetDimensionOfGeometricType(INTERP_KERNEL::NORM_POLYGON),2); + CPPUNIT_ASSERT_EQUAL(std::string(MEDCouplingMesh::GetReprOfGeometricType(INTERP_KERNEL::NORM_POLYGON)),std::string("NORM_POLYGON")); + CPPUNIT_ASSERT_EQUAL(MEDCouplingMesh::GetNumberOfNodesOfGeometricType(INTERP_KERNEL::NORM_TRI6),6); + CPPUNIT_ASSERT(MEDCouplingMesh::IsStaticGeometricType(INTERP_KERNEL::NORM_TRI6)); + CPPUNIT_ASSERT(!MEDCouplingMesh::IsLinearGeometricType(INTERP_KERNEL::NORM_TRI6)); + CPPUNIT_ASSERT_EQUAL(MEDCouplingMesh::GetDimensionOfGeometricType(INTERP_KERNEL::NORM_TRI6),2); + CPPUNIT_ASSERT_EQUAL(std::string(MEDCouplingMesh::GetReprOfGeometricType(INTERP_KERNEL::NORM_TRI6)),std::string("NORM_TRI6")); + MEDCouplingUMesh *mesh=MEDCouplingUMesh::New(); + mesh->setMeshDimension(2); + mesh->allocateCells(8); + const int *curConn=tab4; + for(int i=0;i<nbOfCells;i++,curConn+=4) + mesh->insertNextCell(INTERP_KERNEL::NORM_QUAD4,4,curConn); + mesh->finishInsertingCells(); + CPPUNIT_ASSERT_EQUAL((std::size_t)30,mesh->getNodalConnectivity()->getNbOfElems()); + CPPUNIT_ASSERT_EQUAL(nbOfCells,mesh->getNumberOfCells()); + //test 0 - no copy no ownership + DataArrayDouble *myCoords=DataArrayDouble::New(); + myCoords->useArray(coords,false,CPP_DEALLOC,nbOfNodes,3); + mesh->setCoords(myCoords); + mesh->setCoords(myCoords); + myCoords->decrRef(); + CPPUNIT_ASSERT_EQUAL(nbOfCells,mesh->getNumberOfCells()); + mesh->checkCoherency(); + //test 1 - no copy ownership C++ + myCoords=DataArrayDouble::New(); + double *tmp=new double[3*nbOfNodes]; + std::copy(coords,coords+3*nbOfNodes,tmp); + myCoords->useArray(tmp,true,CPP_DEALLOC,nbOfNodes,3); + mesh->setCoords(myCoords); + myCoords->decrRef(); + CPPUNIT_ASSERT_EQUAL(nbOfCells,mesh->getNumberOfCells()); + mesh->checkCoherency(); + //test 2 - no copy ownership C + myCoords=DataArrayDouble::New(); + tmp=(double *)malloc(3*nbOfNodes*sizeof(double)); + std::copy(coords,coords+3*nbOfNodes,tmp); + myCoords->useArray(tmp,true,C_DEALLOC,nbOfNodes,3); + mesh->setCoords(myCoords); + myCoords->decrRef(); + CPPUNIT_ASSERT_EQUAL(nbOfNodes,mesh->getNumberOfNodes()); + mesh->checkCoherency(); + //test 3 - copy. + myCoords=DataArrayDouble::New(); + myCoords->alloc(nbOfNodes,3); + tmp=myCoords->getPointer(); + std::copy(coords,coords+3*nbOfNodes,tmp); + // test 3 bis deepcopy + DataArrayDouble *myCoords2=DataArrayDouble::New(); + *myCoords2=*myCoords; + myCoords2->decrRef(); + // + mesh->setCoords(myCoords); + myCoords->decrRef(); + CPPUNIT_ASSERT_EQUAL(nbOfNodes,mesh->getNumberOfNodes()); + mesh->checkCoherency(); + CPPUNIT_ASSERT_EQUAL(3,mesh->getSpaceDimension()); + // test clone not recursively + MEDCouplingUMesh *mesh2=mesh->clone(false); + CPPUNIT_ASSERT(mesh2!=mesh); + mesh2->checkCoherency(); + CPPUNIT_ASSERT_EQUAL(nbOfCells,mesh2->getNumberOfCells()); + CPPUNIT_ASSERT_EQUAL(nbOfNodes,mesh2->getNumberOfNodes()); + CPPUNIT_ASSERT_EQUAL(3,mesh2->getSpaceDimension()); + CPPUNIT_ASSERT(mesh!=mesh2); + CPPUNIT_ASSERT(mesh->getCoords()==mesh2->getCoords()); + CPPUNIT_ASSERT_DOUBLES_EQUAL(-0.2863,mesh2->getCoords()->getIJ(11,2),1e-14); + CPPUNIT_ASSERT(mesh->getNodalConnectivity()==mesh2->getNodalConnectivity()); + CPPUNIT_ASSERT_EQUAL(3,mesh2->getNodalConnectivity()->getIJ(7,0)); + CPPUNIT_ASSERT(mesh->getNodalConnectivityIndex()==mesh2->getNodalConnectivityIndex()); + CPPUNIT_ASSERT_EQUAL(15,mesh2->getNodalConnectivityIndex()->getIJ(3,0)); + mesh2->decrRef(); + // test clone not recursively + MEDCouplingUMesh *mesh3=mesh->clone(true); + CPPUNIT_ASSERT(mesh3!=mesh); + mesh3->checkCoherency(); + CPPUNIT_ASSERT_EQUAL(nbOfCells,mesh3->getNumberOfCells()); + CPPUNIT_ASSERT_EQUAL(nbOfNodes,mesh3->getNumberOfNodes()); + CPPUNIT_ASSERT_EQUAL(3,mesh3->getSpaceDimension()); + CPPUNIT_ASSERT(mesh!=mesh3); + CPPUNIT_ASSERT(mesh->getCoords()!=mesh3->getCoords()); + CPPUNIT_ASSERT_DOUBLES_EQUAL(-0.2863,mesh3->getCoords()->getIJ(11,2),1e-14); + CPPUNIT_ASSERT(mesh->getNodalConnectivity()!=mesh3->getNodalConnectivity()); + CPPUNIT_ASSERT_EQUAL(3,mesh3->getNodalConnectivity()->getIJ(7,0)); + CPPUNIT_ASSERT(mesh->getNodalConnectivityIndex()!=mesh3->getNodalConnectivityIndex()); + CPPUNIT_ASSERT_EQUAL(15,mesh3->getNodalConnectivityIndex()->getIJ(3,0)); + mesh3->decrRef(); + //test 4 - Field on cells + MEDCouplingFieldDouble *fieldOnCells=MEDCouplingFieldDouble::New(ON_CELLS); + fieldOnCells->setMesh(mesh); + DataArrayDouble *array=DataArrayDouble::New(); + array->alloc(nbOfCells,9); + fieldOnCells->setArray(array); + tmp=array->getPointer(); + array->decrRef(); + std::fill(tmp,tmp+9*nbOfCells,7.); + //content of field changed -> declare it. + fieldOnCells->declareAsNew(); + fieldOnCells->checkCoherency(); + // testing clone of fields - no recursive + MEDCouplingFieldDouble *fieldOnCells2=fieldOnCells->clone(false); + CPPUNIT_ASSERT(fieldOnCells2!=fieldOnCells); + fieldOnCells2->checkCoherency(); + CPPUNIT_ASSERT_EQUAL(nbOfCells,fieldOnCells2->getNumberOfTuples()); + CPPUNIT_ASSERT_EQUAL(9,fieldOnCells2->getNumberOfComponents()); + CPPUNIT_ASSERT(fieldOnCells2->getArray()==fieldOnCells->getArray()); + CPPUNIT_ASSERT_DOUBLES_EQUAL(7.,fieldOnCells2->getArray()->getIJ(3,7),1e-14); + CPPUNIT_ASSERT(fieldOnCells2->getMesh()==fieldOnCells->getMesh()); + // testing clone of fields - recursive + MEDCouplingFieldDouble *fieldOnCells3=fieldOnCells->clone(true); + CPPUNIT_ASSERT(fieldOnCells3!=fieldOnCells); + fieldOnCells3->checkCoherency(); + CPPUNIT_ASSERT_EQUAL(nbOfCells,fieldOnCells3->getNumberOfTuples()); + CPPUNIT_ASSERT_EQUAL(9,fieldOnCells3->getNumberOfComponents()); + CPPUNIT_ASSERT(fieldOnCells3->getArray()!=fieldOnCells->getArray()); + CPPUNIT_ASSERT_DOUBLES_EQUAL(7.,fieldOnCells3->getArray()->getIJ(3,7),1e-14); + CPPUNIT_ASSERT(fieldOnCells3->getMesh()==fieldOnCells->getMesh()); + fieldOnCells2->decrRef(); + fieldOnCells3->decrRef(); + // + fieldOnCells->decrRef(); + //clean-up + mesh->decrRef(); +} + +void MEDCouplingBasicsTest1::testMeshPointsCloud() +{ + double targetCoords[27]={-0.3,-0.3,0.5, 0.2,-0.3,1., 0.7,-0.3,1.5, -0.3,0.2,0.5, 0.2,0.2,1., 0.7,0.2,1.5, -0.3,0.7,0.5, 0.2,0.7,1., 0.7,0.7,1.5}; + const int targetConn[]={0,1,2,3,4,5,7,6}; + MEDCouplingUMesh *targetMesh=MEDCouplingUMesh::New(); + targetMesh->setMeshDimension(0); + targetMesh->allocateCells(8); + targetMesh->insertNextCell(INTERP_KERNEL::NORM_POINT1,1,targetConn); + targetMesh->insertNextCell(INTERP_KERNEL::NORM_POINT1,1,targetConn+1); + targetMesh->insertNextCell(INTERP_KERNEL::NORM_POINT1,1,targetConn+2); + targetMesh->insertNextCell(INTERP_KERNEL::NORM_POINT1,1,targetConn+3); + targetMesh->insertNextCell(INTERP_KERNEL::NORM_POINT1,1,targetConn+4); + targetMesh->insertNextCell(INTERP_KERNEL::NORM_POINT1,1,targetConn+5); + targetMesh->insertNextCell(INTERP_KERNEL::NORM_POINT1,1,targetConn+6); + targetMesh->insertNextCell(INTERP_KERNEL::NORM_POINT1,1,targetConn+7); + targetMesh->finishInsertingCells(); + CPPUNIT_ASSERT_THROW(targetMesh->checkCoherency(),INTERP_KERNEL::Exception); + DataArrayDouble *myCoords=DataArrayDouble::New(); + myCoords->alloc(9,3); + std::copy(targetCoords,targetCoords+27,myCoords->getPointer()); + targetMesh->setCoords(myCoords); + myCoords->decrRef(); + // + targetMesh->checkCoherency(); + CPPUNIT_ASSERT_EQUAL(3,targetMesh->getSpaceDimension()); + CPPUNIT_ASSERT_EQUAL(8,targetMesh->getNumberOfCells()); + CPPUNIT_ASSERT_EQUAL(9,targetMesh->getNumberOfNodes()); + CPPUNIT_ASSERT_EQUAL(0,targetMesh->getMeshDimension()); + // + targetMesh->decrRef(); +} + +void MEDCouplingBasicsTest1::testMeshM1D() +{ + MEDCouplingUMesh *meshM1D=MEDCouplingUMesh::New(); + CPPUNIT_ASSERT_THROW(meshM1D->getMeshDimension(),INTERP_KERNEL::Exception); + CPPUNIT_ASSERT_THROW(meshM1D->getNumberOfNodes(),INTERP_KERNEL::Exception); + CPPUNIT_ASSERT_THROW(meshM1D->getNumberOfCells(),INTERP_KERNEL::Exception); + CPPUNIT_ASSERT_THROW(meshM1D->setMeshDimension(-2),INTERP_KERNEL::Exception); + CPPUNIT_ASSERT_THROW(meshM1D->setMeshDimension(-10),INTERP_KERNEL::Exception); + CPPUNIT_ASSERT_THROW(meshM1D->checkCoherency(),INTERP_KERNEL::Exception); + meshM1D->setMeshDimension(-1); + meshM1D->checkCoherency(); + CPPUNIT_ASSERT_EQUAL(-1,meshM1D->getMeshDimension()); + CPPUNIT_ASSERT_EQUAL(1,meshM1D->getNumberOfCells()); + CPPUNIT_ASSERT_THROW(meshM1D->getNumberOfNodes(),INTERP_KERNEL::Exception); + CPPUNIT_ASSERT_THROW(meshM1D->getSpaceDimension(),INTERP_KERNEL::Exception); + MEDCouplingUMesh *cpy=meshM1D->clone(true); + CPPUNIT_ASSERT(cpy->isEqual(meshM1D,1e-12)); + cpy->decrRef(); + MEDCouplingFieldDouble *fieldOnCells=MEDCouplingFieldDouble::New(ON_CELLS); + fieldOnCells->setMesh(meshM1D); + DataArrayDouble *array=DataArrayDouble::New(); + array->alloc(1,6); + fieldOnCells->setArray(array); + double *tmp=array->getPointer(); + array->decrRef(); + std::fill(tmp,tmp+6,7.); + fieldOnCells->checkCoherency(); + // + fieldOnCells->decrRef(); + meshM1D->decrRef(); +} + +void MEDCouplingBasicsTest1::testDeepCopy() +{ + DataArrayDouble *array=DataArrayDouble::New(); + array->alloc(5,3); + std::fill(array->getPointer(),array->getPointer()+5*3,7.); + CPPUNIT_ASSERT_DOUBLES_EQUAL(7.,array->getIJ(3,2),1e-14); + double *tmp1=array->getPointer(); + DataArrayDouble *array2=array->deepCpy(); + double *tmp2=array2->getPointer(); + CPPUNIT_ASSERT(tmp1!=tmp2); + array->decrRef(); + CPPUNIT_ASSERT_DOUBLES_EQUAL(7.,array2->getIJ(3,2),1e-14); + array2->decrRef(); + // + DataArrayInt *array3=DataArrayInt::New(); + array3->alloc(5,3); + std::fill(array3->getPointer(),array3->getPointer()+5*3,17); + CPPUNIT_ASSERT_EQUAL(17,array3->getIJ(3,2)); + int *tmp3=array3->getPointer(); + DataArrayInt *array4=array3->deepCpy(); + int *tmp4=array4->getPointer(); + CPPUNIT_ASSERT(tmp3!=tmp4); + array3->decrRef(); + CPPUNIT_ASSERT_EQUAL(17,array4->getIJ(3,2)); + array4->decrRef(); +} + +void MEDCouplingBasicsTest1::testRevNodal() +{ + MEDCouplingUMesh *mesh=build2DTargetMesh_1(); + DataArrayInt *revNodal=DataArrayInt::New(); + DataArrayInt *revNodalIndx=DataArrayInt::New(); + // + mesh->getReverseNodalConnectivity(revNodal,revNodalIndx); + const int revNodalExpected[18]={0,0,1,1,2,0,3,0,1,2,3,4,2,4,3,3,4,4}; + const int revNodalIndexExpected[10]={0,1,3,5,7,12,14,15,17,18}; + CPPUNIT_ASSERT_EQUAL((std::size_t)18,revNodal->getNbOfElems()); + CPPUNIT_ASSERT_EQUAL((std::size_t)10,revNodalIndx->getNbOfElems()); + CPPUNIT_ASSERT(std::equal(revNodalExpected,revNodalExpected+18,revNodal->getPointer())); + CPPUNIT_ASSERT(std::equal(revNodalIndexExpected,revNodalIndexExpected+10,revNodalIndx->getPointer())); + // + revNodal->decrRef(); + revNodalIndx->decrRef(); + mesh->decrRef(); +} + +void MEDCouplingBasicsTest1::testConvertToPolyTypes() +{ + ////// 2D + MEDCouplingUMesh *mesh=build2DTargetMesh_1(); + // + const int elts[2]={1,3}; + std::vector<int> eltsV(elts,elts+2); + mesh->convertToPolyTypes(&eltsV[0],&eltsV[0]+eltsV.size()); + mesh->checkCoherency(); + CPPUNIT_ASSERT_EQUAL(5,mesh->getNumberOfCells()); + CPPUNIT_ASSERT_EQUAL(23,mesh->getNodalConnectivity()->getNumberOfTuples()); + const int *pt=mesh->getNodalConnectivity()->getConstPointer(); + const int expected1[23]={4, 0, 3, 4, 1, 5, 1, 4, 2, 3, 4, 5, 2, 5, 6, 7, 4, 3, 4, 7, 8, 5, 4}; + CPPUNIT_ASSERT(std::equal(expected1,expected1+23,pt)); + // + mesh->decrRef(); + ////// 3D + mesh=build3DTargetMesh_1(); + mesh->convertToPolyTypes(&eltsV[0],&eltsV[0]+eltsV.size()); + mesh->checkCoherency(); + CPPUNIT_ASSERT_EQUAL(8,mesh->getNumberOfCells()); + CPPUNIT_ASSERT_EQUAL(114,mesh->getNodalConnectivity()->getNumberOfTuples()); + mesh->convertToPolyTypes(&eltsV[0],&eltsV[0]+eltsV.size()); + mesh->checkCoherency(); + CPPUNIT_ASSERT_EQUAL(8,mesh->getNumberOfCells()); + CPPUNIT_ASSERT_EQUAL(114,mesh->getNodalConnectivity()->getNumberOfTuples()); + // + mesh->decrRef(); +} + +void MEDCouplingBasicsTest1::testDescConn2D() +{ + MEDCouplingUMesh *mesh=build2DTargetMesh_1(); + DataArrayInt *desc=DataArrayInt::New(); + DataArrayInt *descIndx=DataArrayInt::New(); + DataArrayInt *revDesc=DataArrayInt::New(); + DataArrayInt *revDescIndx=DataArrayInt::New(); + // + MEDCouplingUMesh *mesh2=mesh->buildDescendingConnectivity(desc,descIndx,revDesc,revDescIndx); + mesh2->checkCoherency(); + CPPUNIT_ASSERT_EQUAL(1,mesh2->getMeshDimension()); + CPPUNIT_ASSERT_EQUAL(13,mesh2->getNumberOfCells()); + CPPUNIT_ASSERT_EQUAL((std::size_t)14,revDescIndx->getNbOfElems()); CPPUNIT_ASSERT_EQUAL(14,revDescIndx->getNumberOfTuples()); + CPPUNIT_ASSERT_EQUAL((std::size_t)6,descIndx->getNbOfElems()); CPPUNIT_ASSERT_EQUAL(6,descIndx->getNumberOfTuples()); + CPPUNIT_ASSERT_EQUAL((std::size_t)18,desc->getNbOfElems()); CPPUNIT_ASSERT_EQUAL(18,desc->getNumberOfTuples()); + CPPUNIT_ASSERT_EQUAL((std::size_t)18,revDesc->getNbOfElems()); CPPUNIT_ASSERT_EQUAL(18,revDesc->getNumberOfTuples()); + const int expected1[18]={0,1,2,3, 2,4,5, 6,7,4, 8,9,1,10, 11,12,6,9}; + CPPUNIT_ASSERT(std::equal(expected1,expected1+18,desc->getConstPointer())); + const int expected2[6]={0,4,7,10,14,18}; + CPPUNIT_ASSERT(std::equal(expected2,expected2+6,descIndx->getConstPointer())); + const int expected3[14]={0,1,3,5,6,8,9,11,12,13,15,16,17,18}; + CPPUNIT_ASSERT(std::equal(expected3,expected3+14,revDescIndx->getConstPointer())); + const int expected4[18]={0, 0,3, 0,1, 0, 1,2, 1, 2,4, 2, 3, 3,4, 3, 4, 4}; + CPPUNIT_ASSERT(std::equal(expected4,expected4+18,revDesc->getConstPointer())); + DataArrayInt *conn=mesh2->getNodalConnectivity(); + DataArrayInt *connIndex=mesh2->getNodalConnectivityIndex(); + const int expected5[14]={0,3,6,9,12,15,18,21,24,27,30,33,36,39}; + CPPUNIT_ASSERT(std::equal(expected5,expected5+14,connIndex->getConstPointer())); + const int expected6[39]={1, 0, 3, 1, 3, 4, 1, 4, 1, 1, 1, 0, 1, 4, 2, 1, 2, 1, 1, 4, 5, 1, 5, 2, 1, 6, 7, 1, 7, 4, 1, 3, 6, 1, 7, 8, 1, 8, 5}; + CPPUNIT_ASSERT(std::equal(expected6,expected6+39,conn->getConstPointer())); + // + desc->decrRef(); + descIndx->decrRef(); + revDesc->decrRef(); + revDescIndx->decrRef(); + mesh2->decrRef(); + // + const int elts[2]={1,3}; + std::vector<int> eltsV(elts,elts+2); + mesh->convertToPolyTypes(&eltsV[0],&eltsV[0]+eltsV.size()); + mesh->checkCoherency(); + // + desc=DataArrayInt::New(); + descIndx=DataArrayInt::New(); + revDesc=DataArrayInt::New(); + revDescIndx=DataArrayInt::New(); + // + mesh2=mesh->buildDescendingConnectivity(desc,descIndx,revDesc,revDescIndx); + mesh2->checkCoherency(); + CPPUNIT_ASSERT_EQUAL(1,mesh2->getMeshDimension()); + CPPUNIT_ASSERT_EQUAL(13,mesh2->getNumberOfCells()); + CPPUNIT_ASSERT_EQUAL((std::size_t)14,revDescIndx->getNbOfElems()); CPPUNIT_ASSERT_EQUAL(14,revDescIndx->getNumberOfTuples()); + CPPUNIT_ASSERT_EQUAL((std::size_t)6,descIndx->getNbOfElems()); CPPUNIT_ASSERT_EQUAL(6,descIndx->getNumberOfTuples()); + CPPUNIT_ASSERT_EQUAL((std::size_t)18,desc->getNbOfElems()); CPPUNIT_ASSERT_EQUAL(18,desc->getNumberOfTuples()); + CPPUNIT_ASSERT_EQUAL((std::size_t)18,revDesc->getNbOfElems()); CPPUNIT_ASSERT_EQUAL(18,revDesc->getNumberOfTuples()); + CPPUNIT_ASSERT(std::equal(expected1,expected1+18,desc->getConstPointer())); + CPPUNIT_ASSERT(std::equal(expected2,expected2+6,descIndx->getConstPointer())); + CPPUNIT_ASSERT(std::equal(expected3,expected3+14,revDescIndx->getConstPointer())); + CPPUNIT_ASSERT(std::equal(expected4,expected4+18,revDesc->getConstPointer())); + conn=mesh2->getNodalConnectivity(); + connIndex=mesh2->getNodalConnectivityIndex(); + CPPUNIT_ASSERT(std::equal(expected5,expected5+14,connIndex->getConstPointer())); + CPPUNIT_ASSERT(std::equal(expected6,expected6+39,conn->getConstPointer())); + // + desc->decrRef(); + descIndx->decrRef(); + revDesc->decrRef(); + revDescIndx->decrRef(); + mesh2->decrRef(); + mesh->decrRef(); +} + +void MEDCouplingBasicsTest1::testDescConn3D() +{ + MEDCouplingUMesh *mesh=build3DTargetMesh_1(); + DataArrayInt *desc=DataArrayInt::New(); + DataArrayInt *descIndx=DataArrayInt::New(); + DataArrayInt *revDesc=DataArrayInt::New(); + DataArrayInt *revDescIndx=DataArrayInt::New(); + // + MEDCouplingUMesh *mesh2=mesh->buildDescendingConnectivity(desc,descIndx,revDesc,revDescIndx); + mesh2->checkCoherency(); + CPPUNIT_ASSERT_EQUAL(2,mesh2->getMeshDimension()); + CPPUNIT_ASSERT_EQUAL(36,mesh2->getNumberOfCells()); + CPPUNIT_ASSERT_EQUAL((std::size_t)37,revDescIndx->getNbOfElems()); CPPUNIT_ASSERT_EQUAL(37,revDescIndx->getNumberOfTuples()); + CPPUNIT_ASSERT_EQUAL((std::size_t)9,descIndx->getNbOfElems()); CPPUNIT_ASSERT_EQUAL(9,descIndx->getNumberOfTuples()); + CPPUNIT_ASSERT_EQUAL((std::size_t)48,desc->getNbOfElems()); CPPUNIT_ASSERT_EQUAL(48,desc->getNumberOfTuples()); + CPPUNIT_ASSERT_EQUAL((std::size_t)48,revDesc->getNbOfElems()); CPPUNIT_ASSERT_EQUAL(48,revDesc->getNumberOfTuples()); + const int expected1[9]={0, 6, 12, 18, 24, 30, 36, 42, 48}; + const int expected2[48]={0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 3, 11, 12, 4, 13, 14, 15, 16, 17, 10, 18, 19, 13, 1, 20, 21, 22, 23, 24, 7, 25, 26, 27, 28, 22, 12, 29, 23, 30, 31, 32, 17, 33, 28, 34, 35, 30}; + const int expected3[37]={0, 1, 3, 4, 6, 8, 9, 10, 12, 13, 14, 16, 17, 19, 21, 22, 23, 24, 26, 27, 28, 29, 30, 32, 34, 35, 36, 37, 38, 40, 41, 43, 44, 45, 46, 47, 48}; + const int expected4[48]={0, 0, 4, 0, 0, 1, 0, 2, 0, 1, 1, 5, 1, 1, 1, 3, 2, 2, 6, 2, 3, 2, 2, 3, 3, 7, 3, 3, 4, 4, 4, 5, 4, 6, 4, 5, 5, 5, 5, 7, 6, 6, 7, 6, 6, 7, 7, 7}; + const int expected5[37]={0, 5, 10, 15, 20, 25, 30, 35, 40, 45, 50, 55, 60, 65, 70, 75, 80, 85, 90, 95, 100, 105, 110, 115, 120, 125, 130, 135, 140, 145, 150, 155, 160, 165, 170, 175, 180}; + const int expected6[180]={4, 0, 1, 4, 3, 4, 9, 12, 13, 10, 4, 0, 9, 10, 1, 4, 1, 10, 13, 4, 4, 4, 13, 12, 3, 4, 3, 12, 9, 0, 4, 1, 2, 5, 4, 4, 10, 13, 14, 11, 4, 1, 10, 11, 2, 4, 2, 11, 14, + 5, 4, 5, 14, 13, 4, 4, 3, 4, 7, 6, 4, 12, 15, 16, 13, 4, 4, 13, 16, 7, 4, 7, 16, 15, 6, 4, 6, 15, 12, 3, 4, 4, 5, 8, 7, 4, 13, 16, 17, 14, 4, 5, 14, 17, 8, 4, 8, + 17, 16, 7, 4, 18, 21, 22, 19, 4, 9, 18, 19, 10, 4, 10, 19, 22, 13, 4, 13, 22, 21, 12, 4, 12, 21, 18, 9, 4, 19, 22, 23, 20, 4, 10, 19, 20, 11, 4, 11, 20, 23, 14, 4, + 14, 23, 22, 13, 4, 21, 24, 25, 22, 4, 13, 22, 25, 16, 4, 16, 25, 24, 15, 4, 15, 24, 21, 12, 4, 22, 25, 26, 23, 4, 14, 23, 26, 17, 4, 17, 26, 25, 16}; + const int expected7[180]={4, 0, 1, 4, 3, 4, 9, 12, 13, 10, 4, 0, 9, 10, 1, 4, 1, 10, 13, 4, 4, 4, 13, 12, 3, 4, 3, 12, 9, 0, 5, 1, 2, 5, 4, 5, 10, 13, 14, 11, 5, 1, 10, 11, 2, 5, 2, 11, 14, + 5, 5, 5, 14, 13, 4, 4, 3, 4, 7, 6, 4, 12, 15, 16, 13, 4, 4, 13, 16, 7, 4, 7, 16, 15, 6, 4, 6, 15, 12, 3, 5, 4, 5, 8, 7, 5, 13, 16, 17, 14, 5, 5, 14, 17, 8, 5, 8, + 17, 16, 7, 4, 18, 21, 22, 19, 4, 9, 18, 19, 10, 4, 10, 19, 22, 13, 4, 13, 22, 21, 12, 4, 12, 21, 18, 9, 4, 19, 22, 23, 20, 4, 10, 19, 20, 11, 4, 11, 20, 23, 14, 4, + 14, 23, 22, 13, 4, 21, 24, 25, 22, 4, 13, 22, 25, 16, 4, 16, 25, 24, 15, 4, 15, 24, 21, 12, 4, 22, 25, 26, 23, 4, 14, 23, 26, 17, 4, 17, 26, 25, 16}; + + CPPUNIT_ASSERT(std::equal(expected1,expected1+9,descIndx->getConstPointer())); + CPPUNIT_ASSERT(std::equal(expected2,expected2+48,desc->getConstPointer())); + CPPUNIT_ASSERT(std::equal(expected3,expected3+37,revDescIndx->getConstPointer())); + CPPUNIT_ASSERT(std::equal(expected4,expected4+48,revDesc->getConstPointer())); + CPPUNIT_ASSERT(std::equal(expected5,expected5+37,mesh2->getNodalConnectivityIndex()->getConstPointer())); + CPPUNIT_ASSERT(std::equal(expected6,expected6+180,mesh2->getNodalConnectivity()->getConstPointer())); + // + desc->decrRef(); + descIndx->decrRef(); + revDesc->decrRef(); + revDescIndx->decrRef(); + mesh2->decrRef(); + // + const int elts[2]={1,3}; + std::vector<int> eltsV(elts,elts+2); + mesh->convertToPolyTypes(&eltsV[0],&eltsV[0]+eltsV.size()); + mesh->checkCoherency(); + desc=DataArrayInt::New(); + descIndx=DataArrayInt::New(); + revDesc=DataArrayInt::New(); + revDescIndx=DataArrayInt::New(); + mesh2=mesh->buildDescendingConnectivity(desc,descIndx,revDesc,revDescIndx); + mesh2->checkCoherency(); + CPPUNIT_ASSERT_EQUAL(2,mesh2->getMeshDimension()); + CPPUNIT_ASSERT_EQUAL(36,mesh2->getNumberOfCells()); + CPPUNIT_ASSERT_EQUAL((std::size_t)37,revDescIndx->getNbOfElems()); CPPUNIT_ASSERT_EQUAL(37,revDescIndx->getNumberOfTuples()); + CPPUNIT_ASSERT_EQUAL((std::size_t)9,descIndx->getNbOfElems()); CPPUNIT_ASSERT_EQUAL(9,descIndx->getNumberOfTuples()); + CPPUNIT_ASSERT_EQUAL((std::size_t)48,desc->getNbOfElems()); CPPUNIT_ASSERT_EQUAL(48,desc->getNumberOfTuples()); + CPPUNIT_ASSERT_EQUAL((std::size_t)48,revDesc->getNbOfElems()); CPPUNIT_ASSERT_EQUAL(48,revDesc->getNumberOfTuples()); + CPPUNIT_ASSERT(std::equal(expected1,expected1+9,descIndx->getConstPointer())); + CPPUNIT_ASSERT(std::equal(expected2,expected2+48,desc->getConstPointer())); + CPPUNIT_ASSERT(std::equal(expected3,expected3+37,revDescIndx->getConstPointer())); + CPPUNIT_ASSERT(std::equal(expected4,expected4+48,revDesc->getConstPointer())); + CPPUNIT_ASSERT(std::equal(expected5,expected5+37,mesh2->getNodalConnectivityIndex()->getConstPointer())); + CPPUNIT_ASSERT(std::equal(expected7,expected7+180,mesh2->getNodalConnectivity()->getConstPointer())); + // + desc->decrRef(); + descIndx->decrRef(); + revDesc->decrRef(); + revDescIndx->decrRef(); + mesh2->decrRef(); + mesh->decrRef(); +} + +void MEDCouplingBasicsTest1::testFindBoundaryNodes() +{ + MEDCouplingUMesh *mesh=build3DTargetMesh_1(); + DataArrayInt *boundaryNodes=mesh->findBoundaryNodes(); + CPPUNIT_ASSERT_EQUAL(26,boundaryNodes->getNumberOfTuples()); + CPPUNIT_ASSERT_EQUAL(1,boundaryNodes->getNumberOfComponents()); + const int expected1[26]={0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26}; + CPPUNIT_ASSERT(std::equal(expected1,expected1+26,boundaryNodes->begin())); + boundaryNodes->decrRef(); + mesh->decrRef(); +} + +void MEDCouplingBasicsTest1::testBoundaryMesh() +{ + MEDCouplingUMesh *mesh=build3DTargetMesh_1(); + MEDCouplingPointSet *mesh2=mesh->buildBoundaryMesh(false); + CPPUNIT_ASSERT_EQUAL(24,mesh2->getNumberOfCells()); + CPPUNIT_ASSERT_EQUAL(26,mesh2->getNumberOfNodes()); + mesh2->decrRef(); + mesh->decrRef(); +} + +void MEDCouplingBasicsTest1::testBuildPartOfMySelf() +{ + MEDCouplingUMesh *mesh=build2DTargetMesh_1(); + mesh->setName("Toto"); + const int tab1[2]={0,4}; + const int tab2[3]={0,2,3}; + // + MEDCouplingPointSet *subMeshSimple=mesh->buildPartOfMySelf(tab1,tab1+2,true); + MEDCouplingUMesh *subMesh=dynamic_cast<MEDCouplingUMesh *>(subMeshSimple); + CPPUNIT_ASSERT(subMesh); + std::string name(subMesh->getName()); + CPPUNIT_ASSERT_EQUAL(2,(int)mesh->getAllGeoTypes().size()); + CPPUNIT_ASSERT_EQUAL(INTERP_KERNEL::NORM_TRI3,*mesh->getAllGeoTypes().begin()); + CPPUNIT_ASSERT_EQUAL(INTERP_KERNEL::NORM_QUAD4,*(++(mesh->getAllGeoTypes().begin()))); + CPPUNIT_ASSERT_EQUAL(1,(int)subMesh->getAllGeoTypes().size()); + CPPUNIT_ASSERT_EQUAL(INTERP_KERNEL::NORM_QUAD4,*subMesh->getAllGeoTypes().begin()); + CPPUNIT_ASSERT(name=="Toto"); + CPPUNIT_ASSERT(mesh->getCoords()==subMesh->getCoords()); + CPPUNIT_ASSERT_EQUAL(2,subMesh->getNumberOfCells()); + const int subConn[10]={4,0,3,4,1,4,7,8,5,4}; + const int subConnIndex[3]={0,5,10}; + CPPUNIT_ASSERT_EQUAL((std::size_t)10,subMesh->getNodalConnectivity()->getNbOfElems()); + CPPUNIT_ASSERT_EQUAL((std::size_t)3,subMesh->getNodalConnectivityIndex()->getNbOfElems()); + CPPUNIT_ASSERT(std::equal(subConn,subConn+10,subMesh->getNodalConnectivity()->getPointer())); + CPPUNIT_ASSERT(std::equal(subConnIndex,subConnIndex+3,subMesh->getNodalConnectivityIndex()->getPointer())); + subMesh->decrRef(); + // + subMeshSimple=mesh->buildPartOfMySelf(tab2,tab2+3,true); + subMesh=dynamic_cast<MEDCouplingUMesh *>(subMeshSimple); + CPPUNIT_ASSERT(subMesh); + name=subMesh->getName(); + CPPUNIT_ASSERT_EQUAL(2,(int)subMesh->getAllGeoTypes().size()); + CPPUNIT_ASSERT_EQUAL(INTERP_KERNEL::NORM_TRI3,*subMesh->getAllGeoTypes().begin()); + CPPUNIT_ASSERT_EQUAL(INTERP_KERNEL::NORM_QUAD4,*(++(subMesh->getAllGeoTypes().begin()))); + CPPUNIT_ASSERT(name=="Toto"); + CPPUNIT_ASSERT(mesh->getCoords()==subMesh->getCoords()); + CPPUNIT_ASSERT_EQUAL(3,subMesh->getNumberOfCells()); + const int subConn2[14]={4,0,3,4,1,3,4,5,2,4,6,7,4,3}; + const int subConnIndex2[4]={0,5,9,14}; + CPPUNIT_ASSERT_EQUAL((std::size_t)14,subMesh->getNodalConnectivity()->getNbOfElems()); + CPPUNIT_ASSERT_EQUAL((std::size_t)4,subMesh->getNodalConnectivityIndex()->getNbOfElems()); + CPPUNIT_ASSERT(std::equal(subConn2,subConn2+14,subMesh->getNodalConnectivity()->getPointer())); + CPPUNIT_ASSERT(std::equal(subConnIndex2,subConnIndex2+4,subMesh->getNodalConnectivityIndex()->getPointer())); + const int tab3[3]={0,1,2}; + MEDCouplingPointSet *subMeshSimple2=subMeshSimple->buildPartOfMySelf(tab3,tab3+3,true); + subMesh->decrRef(); + name=subMeshSimple2->getName(); + CPPUNIT_ASSERT(name=="Toto"); + subMeshSimple2->decrRef(); + // + mesh->decrRef(); +} + +void MEDCouplingBasicsTest1::testBuildPartOfMySelfNode() +{ + MEDCouplingUMesh *mesh=build2DTargetMesh_1(); + const int tab1[4]={5,7,8,4}; + MEDCouplingPointSet *subMeshSimple=mesh->buildPartOfMySelfNode(tab1,tab1+4,true); + MEDCouplingUMesh *subMesh=dynamic_cast<MEDCouplingUMesh *>(subMeshSimple); + CPPUNIT_ASSERT(subMesh); + CPPUNIT_ASSERT_EQUAL(1,(int)subMesh->getAllGeoTypes().size()); + CPPUNIT_ASSERT_EQUAL(INTERP_KERNEL::NORM_QUAD4,*subMesh->getAllGeoTypes().begin()); + CPPUNIT_ASSERT_EQUAL(1,subMesh->getNumberOfCells()); + CPPUNIT_ASSERT_EQUAL((std::size_t)5,subMesh->getNodalConnectivity()->getNbOfElems()); + CPPUNIT_ASSERT_EQUAL((std::size_t)2,subMesh->getNodalConnectivityIndex()->getNbOfElems()); + const int subConn[5]={4,7,8,5,4}; + const int subConnIndex[3]={0,5}; + CPPUNIT_ASSERT(std::equal(subConn,subConn+5,subMesh->getNodalConnectivity()->getPointer())); + CPPUNIT_ASSERT(std::equal(subConnIndex,subConnIndex+2,subMesh->getNodalConnectivityIndex()->getPointer())); + CPPUNIT_ASSERT(subMesh->getCoords()==mesh->getCoords()); + subMeshSimple->decrRef(); + // + subMeshSimple=mesh->buildPartOfMySelfNode(tab1,tab1+2,false); + subMesh=dynamic_cast<MEDCouplingUMesh *>(subMeshSimple); + CPPUNIT_ASSERT(subMesh); + CPPUNIT_ASSERT_EQUAL(2,(int)subMesh->getAllGeoTypes().size()); + CPPUNIT_ASSERT_EQUAL(INTERP_KERNEL::NORM_TRI3,*subMesh->getAllGeoTypes().begin()); + CPPUNIT_ASSERT_EQUAL(INTERP_KERNEL::NORM_QUAD4,*(++subMesh->getAllGeoTypes().begin())); + CPPUNIT_ASSERT_EQUAL(3,subMesh->getNumberOfCells()); + CPPUNIT_ASSERT_EQUAL((std::size_t)14,subMesh->getNodalConnectivity()->getNbOfElems()); + CPPUNIT_ASSERT_EQUAL((std::size_t)4,subMesh->getNodalConnectivityIndex()->getNbOfElems()); + const int subConn2[14]={3,4,5,2,4,6,7,4,3,4,7,8,5,4}; + const int subConnIndex2[4]={0,4,9,14}; + CPPUNIT_ASSERT(std::equal(subConn2,subConn2+14,subMesh->getNodalConnectivity()->getPointer())); + CPPUNIT_ASSERT(std::equal(subConnIndex2,subConnIndex2+4,subMesh->getNodalConnectivityIndex()->getPointer())); + CPPUNIT_ASSERT(subMesh->getCoords()==mesh->getCoords()); + subMeshSimple->decrRef(); + //testing the case where length of tab2 is greater than max number of node per cell. + const int tab2[7]={0,3,2,1,4,5,6}; + subMeshSimple=mesh->buildPartOfMySelfNode(tab2,tab2+7,true); + subMesh=dynamic_cast<MEDCouplingUMesh *>(subMeshSimple); + CPPUNIT_ASSERT(subMesh); + CPPUNIT_ASSERT_EQUAL(2,(int)subMesh->getAllGeoTypes().size()); + CPPUNIT_ASSERT_EQUAL(INTERP_KERNEL::NORM_TRI3,*subMesh->getAllGeoTypes().begin()); + CPPUNIT_ASSERT_EQUAL(INTERP_KERNEL::NORM_QUAD4,*(++subMesh->getAllGeoTypes().begin())); + CPPUNIT_ASSERT_EQUAL(3,subMesh->getNumberOfCells()); + subMeshSimple->decrRef(); + // + mesh->decrRef(); +} + +void MEDCouplingBasicsTest1::testZipCoords() +{ + MEDCouplingUMesh *mesh=build2DTargetMesh_1(); + CPPUNIT_ASSERT_EQUAL(2,(int)mesh->getAllGeoTypes().size()); + CPPUNIT_ASSERT_EQUAL(2,mesh->getSpaceDimension()); + CPPUNIT_ASSERT_EQUAL(9,mesh->getNumberOfNodes()); + CPPUNIT_ASSERT_EQUAL(5,mesh->getNumberOfCells()); + std::vector<int> oldConn(mesh->getNodalConnectivity()->getNbOfElems()); + std::vector<int> oldConnIndex(mesh->getNumberOfCells()+1); + std::copy(mesh->getNodalConnectivity()->getPointer(),mesh->getNodalConnectivity()->getPointer()+oldConn.size(),oldConn.begin()); + std::copy(mesh->getNodalConnectivityIndex()->getPointer(),mesh->getNodalConnectivityIndex()->getPointer()+mesh->getNumberOfCells()+1,oldConnIndex.begin()); + DataArrayDouble *oldCoords=mesh->getCoords(); + oldCoords->incrRef(); + mesh->zipCoords(); + CPPUNIT_ASSERT_EQUAL(2,(int)mesh->getAllGeoTypes().size()); + CPPUNIT_ASSERT_EQUAL(2,mesh->getSpaceDimension()); + CPPUNIT_ASSERT_EQUAL(9,mesh->getNumberOfNodes()); + CPPUNIT_ASSERT_EQUAL(5,mesh->getNumberOfCells()); + CPPUNIT_ASSERT(mesh->getCoords()!=oldCoords); + CPPUNIT_ASSERT(std::equal(mesh->getCoords()->getPointer(),mesh->getCoords()->getPointer()+2*9,oldCoords->getPointer())); + CPPUNIT_ASSERT(std::equal(oldConn.begin(),oldConn.end(),mesh->getNodalConnectivity()->getPointer())); + CPPUNIT_ASSERT(std::equal(oldConnIndex.begin(),oldConnIndex.end(),mesh->getNodalConnectivityIndex()->getPointer())); + oldCoords->decrRef(); + // + const int tab1[2]={0,4}; + MEDCouplingPointSet *subMeshPtSet=mesh->buildPartOfMySelf(tab1,tab1+2,true); + MEDCouplingUMesh *subMesh=dynamic_cast<MEDCouplingUMesh *>(subMeshPtSet); + CPPUNIT_ASSERT(subMesh); + DataArrayInt *traducer=subMesh->zipCoordsTraducer(); + const int expectedTraducer[9]={0,1,-1,2,3,4,-1,5,6}; + CPPUNIT_ASSERT(std::equal(expectedTraducer,expectedTraducer+9,traducer->getPointer())); + traducer->decrRef(); + CPPUNIT_ASSERT_EQUAL(INTERP_KERNEL::NORM_QUAD4,*subMesh->getAllGeoTypes().begin()); + CPPUNIT_ASSERT_EQUAL(2,subMesh->getNumberOfCells()); + const int subConn[10]={4,0,2,3,1,4,5,6,4,3}; + const int subConnIndex[3]={0,5,10}; + CPPUNIT_ASSERT_EQUAL(7,subMesh->getNumberOfNodes()); + CPPUNIT_ASSERT_EQUAL((std::size_t)10,subMesh->getNodalConnectivity()->getNbOfElems()); + CPPUNIT_ASSERT_EQUAL((std::size_t)3,subMesh->getNodalConnectivityIndex()->getNbOfElems()); + CPPUNIT_ASSERT(std::equal(subConn,subConn+10,subMesh->getNodalConnectivity()->getPointer())); + CPPUNIT_ASSERT(std::equal(subConnIndex,subConnIndex+3,subMesh->getNodalConnectivityIndex()->getPointer())); + subMesh->decrRef(); + // + subMeshPtSet=mesh->buildPartOfMySelf(tab1,tab1+2,false); + subMesh=dynamic_cast<MEDCouplingUMesh *>(subMeshPtSet); + CPPUNIT_ASSERT(subMesh); + CPPUNIT_ASSERT_EQUAL(INTERP_KERNEL::NORM_QUAD4,*subMesh->getAllGeoTypes().begin()); + CPPUNIT_ASSERT_EQUAL(2,subMesh->getNumberOfCells()); + CPPUNIT_ASSERT_EQUAL(7,subMesh->getNumberOfNodes()); + CPPUNIT_ASSERT_EQUAL((std::size_t)10,subMesh->getNodalConnectivity()->getNbOfElems()); + CPPUNIT_ASSERT_EQUAL((std::size_t)3,subMesh->getNodalConnectivityIndex()->getNbOfElems()); + CPPUNIT_ASSERT(std::equal(subConn,subConn+10,subMesh->getNodalConnectivity()->getPointer())); + CPPUNIT_ASSERT(std::equal(subConnIndex,subConnIndex+3,subMesh->getNodalConnectivityIndex()->getPointer())); + subMesh->decrRef(); + // + mesh->decrRef(); +} + +void MEDCouplingBasicsTest1::testZipConnectivity() +{ + MEDCouplingUMesh *m1=build2DTargetMesh_1(); + MEDCouplingUMesh *m2=build2DTargetMesh_1(); + int cells1[3]={2,3,4}; + MEDCouplingPointSet *m3_1=m2->buildPartOfMySelf(cells1,cells1+3,true); + MEDCouplingUMesh *m3=dynamic_cast<MEDCouplingUMesh *>(m3_1); + CPPUNIT_ASSERT(m3); + m2->decrRef(); + MEDCouplingUMesh *m4=build2DSourceMesh_1(); + MEDCouplingUMesh *m5=MEDCouplingUMesh::MergeUMeshes(m1,m3); + m1->decrRef(); + m3->decrRef(); + MEDCouplingUMesh *m6=MEDCouplingUMesh::MergeUMeshes(m5,m4); + m4->decrRef(); + m5->decrRef(); + // + bool areNodesMerged; + int newNbOfNodes; + CPPUNIT_ASSERT_EQUAL(10,m6->getNumberOfCells()); + CPPUNIT_ASSERT_EQUAL(22,m6->getNumberOfNodes()); + DataArrayInt *arr=m6->mergeNodes(1e-13,areNodesMerged,newNbOfNodes); + arr->decrRef(); + CPPUNIT_ASSERT(areNodesMerged); + CPPUNIT_ASSERT_EQUAL(10,m6->getNumberOfCells()); + CPPUNIT_ASSERT_EQUAL(9,m6->getNumberOfNodes()); + CPPUNIT_ASSERT_EQUAL(9,newNbOfNodes); + // + arr=m6->zipConnectivityTraducer(0); + CPPUNIT_ASSERT_EQUAL(7,m6->getNumberOfCells()); + arr->decrRef(); + MEDCouplingUMesh *m7=m6->clone(true); + arr=m6->zipConnectivityTraducer(0); + CPPUNIT_ASSERT(m7->isEqual(m6,1e-12)); + CPPUNIT_ASSERT_EQUAL(7,m6->getNumberOfCells()); + arr->decrRef(); + // + m7->decrRef(); + m6->decrRef(); +} + +void MEDCouplingBasicsTest1::testEqualMesh() +{ + MEDCouplingUMesh *mesh1=build2DTargetMesh_1(); + MEDCouplingUMesh *mesh2=build2DTargetMesh_1(); + // + CPPUNIT_ASSERT(mesh1->isEqual(mesh1,1e-12)); + // + CPPUNIT_ASSERT(mesh1->isEqual(mesh2,1e-12)); + CPPUNIT_ASSERT(mesh2->isEqual(mesh1,1e-12)); + double *pt=mesh2->getCoords()->getPointer(); + double tmp=pt[1]; + pt[1]=5.999; + CPPUNIT_ASSERT(!mesh1->isEqual(mesh2,1e-12)); + CPPUNIT_ASSERT(!mesh2->isEqual(mesh1,1e-12)); + pt[1]=tmp; + CPPUNIT_ASSERT(mesh1->isEqual(mesh2,1e-12)); + CPPUNIT_ASSERT(mesh2->isEqual(mesh1,1e-12)); + // + int *pt2=mesh1->getNodalConnectivity()->getPointer(); + pt2[5]++; + CPPUNIT_ASSERT(!mesh1->isEqual(mesh2,1e-12)); + CPPUNIT_ASSERT(!mesh2->isEqual(mesh1,1e-12)); + pt2[5]--; + CPPUNIT_ASSERT(mesh1->isEqual(mesh2,1e-12)); + CPPUNIT_ASSERT(mesh2->isEqual(mesh1,1e-12)); + // + pt2=mesh1->getNodalConnectivityIndex()->getPointer(); + pt2[1]++; + CPPUNIT_ASSERT(!mesh1->isEqual(mesh2,1e-12)); + CPPUNIT_ASSERT(!mesh2->isEqual(mesh1,1e-12)); + pt2[1]--; + CPPUNIT_ASSERT(mesh1->isEqual(mesh2,1e-12)); + CPPUNIT_ASSERT(mesh2->isEqual(mesh1,1e-12)); + // + std::string tmp3=mesh1->getName(); + mesh1->setName("lllll"); + CPPUNIT_ASSERT(!mesh1->isEqual(mesh2,1e-12)); + CPPUNIT_ASSERT(!mesh2->isEqual(mesh1,1e-12)); + mesh1->setName(tmp3.c_str()); + CPPUNIT_ASSERT(mesh1->isEqual(mesh2,1e-12)); + CPPUNIT_ASSERT(mesh2->isEqual(mesh1,1e-12)); + // + tmp3=mesh2->getCoords()->getInfoOnComponent(1); + mesh2->getCoords()->setInfoOnComponent(1,"kkkkkk"); + CPPUNIT_ASSERT(!mesh1->isEqual(mesh2,1e-12)); + CPPUNIT_ASSERT(!mesh2->isEqual(mesh1,1e-12)); + mesh2->getCoords()->setInfoOnComponent(1,tmp3.c_str()); + CPPUNIT_ASSERT(mesh1->isEqual(mesh2,1e-12)); + CPPUNIT_ASSERT(mesh2->isEqual(mesh1,1e-12)); + // + mesh1->decrRef(); + mesh2->decrRef(); +} + +void MEDCouplingBasicsTest1::testEqualFieldDouble() +{ + MEDCouplingUMesh *mesh1=build2DTargetMesh_1(); + MEDCouplingUMesh *mesh2=build2DTargetMesh_1(); + // + MEDCouplingFieldDouble *fieldOnCells1=MEDCouplingFieldDouble::New(ON_CELLS,NO_TIME); + fieldOnCells1->setMesh(mesh1); + MEDCouplingFieldDouble *fieldOnCells2=MEDCouplingFieldDouble::New(ON_CELLS,NO_TIME); + fieldOnCells2->setMesh(mesh2); + // + CPPUNIT_ASSERT(fieldOnCells1->isEqual(fieldOnCells2,1e-12,1e-15)); + CPPUNIT_ASSERT(fieldOnCells2->isEqual(fieldOnCells1,1e-12,1e-15)); + fieldOnCells2->decrRef(); + // + MEDCouplingFieldDouble *fieldOnNodes1=MEDCouplingFieldDouble::New(ON_CELLS,NO_TIME); + CPPUNIT_ASSERT(!fieldOnCells1->isEqual(fieldOnNodes1,1e-12,1e-15)); + CPPUNIT_ASSERT(!fieldOnNodes1->isEqual(fieldOnCells1,1e-12,1e-15)); + fieldOnNodes1->decrRef(); + // + fieldOnCells2=MEDCouplingFieldDouble::New(ON_CELLS,ONE_TIME); + CPPUNIT_ASSERT(!fieldOnCells1->isEqual(fieldOnCells2,1e-12,1e-15)); + CPPUNIT_ASSERT(!fieldOnCells2->isEqual(fieldOnCells1,1e-12,1e-15)); + fieldOnCells1->decrRef(); + fieldOnCells1=MEDCouplingFieldDouble::New(ON_CELLS,ONE_TIME); + CPPUNIT_ASSERT(fieldOnCells1->isEqual(fieldOnCells2,1e-12,1e-15)); + CPPUNIT_ASSERT(fieldOnCells2->isEqual(fieldOnCells1,1e-12,1e-15)); + fieldOnCells1->setTime(4.,6,7); + CPPUNIT_ASSERT(!fieldOnCells1->isEqual(fieldOnCells2,1e-12,1e-15)); + CPPUNIT_ASSERT(!fieldOnCells2->isEqual(fieldOnCells1,1e-12,1e-15)); + fieldOnCells2->setTime(4.,6,7); + CPPUNIT_ASSERT(fieldOnCells1->isEqual(fieldOnCells2,1e-12,1e-15)); + CPPUNIT_ASSERT(fieldOnCells2->isEqual(fieldOnCells1,1e-12,1e-15)); + fieldOnCells1->setName("Power"); + CPPUNIT_ASSERT(!fieldOnCells1->isEqual(fieldOnCells2,1e-12,1e-15)); + CPPUNIT_ASSERT(!fieldOnCells2->isEqual(fieldOnCells1,1e-12,1e-15)); + fieldOnCells2->setName("Power"); + CPPUNIT_ASSERT(fieldOnCells1->isEqual(fieldOnCells2,1e-12,1e-15)); + CPPUNIT_ASSERT(fieldOnCells2->isEqual(fieldOnCells1,1e-12,1e-15)); + // + fieldOnCells1->setMesh(mesh1); + CPPUNIT_ASSERT(!fieldOnCells1->isEqual(fieldOnCells2,1e-12,1e-15)); + CPPUNIT_ASSERT(!fieldOnCells2->isEqual(fieldOnCells1,1e-12,1e-15)); + fieldOnCells2->setMesh(mesh1); + CPPUNIT_ASSERT(fieldOnCells1->isEqual(fieldOnCells2,1e-12,1e-15)); + CPPUNIT_ASSERT(fieldOnCells2->isEqual(fieldOnCells1,1e-12,1e-15)); + DataArrayDouble *arr=DataArrayDouble::New(); + arr->setName("popo"); + arr->alloc(mesh1->getNumberOfCells(),3); + double *pt=arr->getPointer(); + std::fill(pt,pt+mesh1->getNumberOfCells()*3,6.); + fieldOnCells1->setArray(arr); + CPPUNIT_ASSERT(!fieldOnCells1->isEqual(fieldOnCells2,1e-12,1e-15)); + CPPUNIT_ASSERT(!fieldOnCells2->isEqual(fieldOnCells1,1e-12,1e-15)); + fieldOnCells2->setArray(arr); + arr->decrRef(); + CPPUNIT_ASSERT(fieldOnCells1->isEqual(fieldOnCells2,1e-12,1e-15)); + CPPUNIT_ASSERT(fieldOnCells2->isEqual(fieldOnCells1,1e-12,1e-15)); + // + DataArrayDouble *arr2=arr->deepCpy(); + fieldOnCells2->setArray(arr2); + arr2->decrRef(); + CPPUNIT_ASSERT(fieldOnCells1->isEqual(fieldOnCells2,1e-12,1e-15)); + CPPUNIT_ASSERT(fieldOnCells2->isEqual(fieldOnCells1,1e-12,1e-15)); + pt[4]=6.1; + CPPUNIT_ASSERT(!fieldOnCells1->isEqual(fieldOnCells2,1e-12,1e-15)); + CPPUNIT_ASSERT(!fieldOnCells2->isEqual(fieldOnCells1,1e-12,1e-15)); + pt[4]=6.; + CPPUNIT_ASSERT(fieldOnCells1->isEqual(fieldOnCells2,1e-12,1e-15)); + CPPUNIT_ASSERT(fieldOnCells2->isEqual(fieldOnCells1,1e-12,1e-15)); + arr2->setName("popo2"); + CPPUNIT_ASSERT(!fieldOnCells1->isEqual(fieldOnCells2,1e-12,1e-15)); + CPPUNIT_ASSERT(!fieldOnCells2->isEqual(fieldOnCells1,1e-12,1e-15)); + // + arr2->setName("popo"); + CPPUNIT_ASSERT(fieldOnCells1->isEqual(fieldOnCells2,1e-12,1e-15)); + CPPUNIT_ASSERT(fieldOnCells2->isEqual(fieldOnCells1,1e-12,1e-15)); + // + arr2->setInfoOnComponent(2,"jjj"); + CPPUNIT_ASSERT(!fieldOnCells1->isEqual(fieldOnCells2,1e-12,1e-15)); + CPPUNIT_ASSERT(!fieldOnCells2->isEqual(fieldOnCells1,1e-12,1e-15)); + arr->setInfoOnComponent(2,"jjj"); + CPPUNIT_ASSERT(fieldOnCells1->isEqual(fieldOnCells2,1e-12,1e-15)); + CPPUNIT_ASSERT(fieldOnCells2->isEqual(fieldOnCells1,1e-12,1e-15)); + // + fieldOnCells1->decrRef(); + fieldOnCells2->decrRef(); + // + mesh1->decrRef(); + mesh2->decrRef(); +} + +void MEDCouplingBasicsTest1::testNatureChecking() +{ + MEDCouplingFieldDouble *field=MEDCouplingFieldDouble::New(ON_CELLS,NO_TIME); + field->setNature(Integral); + field->setNature(ConservativeVolumic); + field->setNature(IntegralGlobConstraint); + field->decrRef(); + field=MEDCouplingFieldDouble::New(ON_NODES,NO_TIME); + field->setNature(ConservativeVolumic); + CPPUNIT_ASSERT_THROW(field->setNature(Integral),INTERP_KERNEL::Exception); + CPPUNIT_ASSERT_THROW(field->setNature(IntegralGlobConstraint),INTERP_KERNEL::Exception); + field->decrRef(); +} + +void MEDCouplingBasicsTest1::testBuildSubMeshData() +{ + MEDCouplingUMesh *targetMesh=build2DTargetMesh_1(); + //check buildSubMesh on field on cells + MEDCouplingFieldDouble *fieldCells=MEDCouplingFieldDouble::New(ON_CELLS,NO_TIME); + fieldCells->setMesh(targetMesh); + const int elts[3]={1,2,4}; + DataArrayInt *di; + MEDCouplingMesh *ret1=fieldCells->buildSubMeshData(elts,elts+3,di); + CPPUNIT_ASSERT_EQUAL(3,ret1->getNumberOfCells()); + CPPUNIT_ASSERT_EQUAL(9,ret1->getNumberOfNodes()); + CPPUNIT_ASSERT_EQUAL(3,di->getNumberOfTuples()); + CPPUNIT_ASSERT_EQUAL(1,di->getNumberOfComponents()); + const int *toCheck=di->getConstPointer(); + CPPUNIT_ASSERT(std::equal(elts,elts+3,toCheck)); + MEDCouplingUMesh *ret1DC=dynamic_cast<MEDCouplingUMesh *>(ret1); + CPPUNIT_ASSERT(ret1DC); + ret1->decrRef(); + di->decrRef(); + fieldCells->decrRef(); + //check buildSubMesh on field on nodes + MEDCouplingFieldDouble *fieldNodes=MEDCouplingFieldDouble::New(ON_NODES,NO_TIME); + fieldNodes->setMesh(targetMesh); + MEDCouplingMesh *ret2=fieldNodes->buildSubMeshData(elts,elts+3,di); + MEDCouplingUMesh *ret2DC=dynamic_cast<MEDCouplingUMesh *>(ret2); + CPPUNIT_ASSERT(ret2DC); + CPPUNIT_ASSERT_EQUAL(3,ret2->getNumberOfCells()); + CPPUNIT_ASSERT_EQUAL(6,ret2->getNumberOfNodes()); + CPPUNIT_ASSERT_EQUAL(6,di->getNumberOfTuples()); + CPPUNIT_ASSERT_EQUAL(1,di->getNumberOfComponents()); + toCheck=di->getConstPointer(); + const int expected[6]={1,2,4,5,7,8}; + CPPUNIT_ASSERT(std::equal(expected,expected+6,toCheck)); + ret2->decrRef(); + di->decrRef(); + fieldNodes->decrRef(); + targetMesh->decrRef(); +} + +void MEDCouplingBasicsTest1::testExtrudedMesh1() +{ + MEDCouplingUMesh *mesh2D=0; + MEDCouplingUMesh *mesh3D=build3DExtrudedUMesh_1(mesh2D); + MEDCouplingExtrudedMesh *ext=MEDCouplingExtrudedMesh::New(mesh3D,mesh2D,1); + CPPUNIT_ASSERT_EQUAL(18,ext->getNumberOfCells()); + CPPUNIT_ASSERT_EQUAL(60,ext->getNumberOfNodes()); + DataArrayInt *ids3D=ext->getMesh3DIds(); + const int ids3DExpected[18]={5,4,3,2,1,0, 11,10,9,8,7,6, 17,16,15,14,13,12}; + CPPUNIT_ASSERT_EQUAL(18,ids3D->getNumberOfTuples()); + CPPUNIT_ASSERT_EQUAL(1,ids3D->getNumberOfComponents()); + CPPUNIT_ASSERT(std::equal(ids3DExpected,ids3DExpected+18,ids3D->getConstPointer())); + MEDCouplingUMesh *mesh1D=ext->getMesh1D(); + CPPUNIT_ASSERT_EQUAL(4,mesh1D->getNumberOfNodes()); + CPPUNIT_ASSERT_EQUAL(3,mesh1D->getNumberOfCells()); + const double mesh1DExpected[12]={0.66666666666666663, 1.4583333333333333, 0, 0.66666666666666663, 1.4583333333333333, 1, 0.66666666666666663, 1.4583333333333333, 2, 0.66666666666666663, 1.4583333333333333, 3}; + DataArrayDouble *mesh1DCoords=mesh1D->getCoords(); + CPPUNIT_ASSERT_EQUAL(4,mesh1DCoords->getNumberOfTuples()); + CPPUNIT_ASSERT_EQUAL(3,mesh1DCoords->getNumberOfComponents()); + CPPUNIT_ASSERT(std::equal(mesh1DExpected,mesh1DExpected+12,mesh1DCoords->getConstPointer())); + DataArrayInt *conn1D=mesh1D->getNodalConnectivity(); + CPPUNIT_ASSERT_EQUAL(9,conn1D->getNumberOfTuples()); + CPPUNIT_ASSERT_EQUAL(1,conn1D->getNumberOfComponents()); + const int conn1DExpected[9]={1,0,1,1,1,2,1,2,3}; + CPPUNIT_ASSERT(std::equal(conn1DExpected,conn1DExpected+9,conn1D->getConstPointer())); + ext->decrRef(); + mesh3D->decrRef(); + mesh2D->decrRef(); +} + +void MEDCouplingBasicsTest1::testExtrudedMesh2() +{ + MEDCouplingUMesh *mN,*mTT,*mTF; + build3DExtrudedUMesh_2(mN,mTT,mTF); + // + bool b=false; + int newNbOfNodes; + DataArrayInt *da=mTT->mergeNodes(1e-12,b,newNbOfNodes); + CPPUNIT_ASSERT(b); + da->decrRef(); + std::vector<int> n; + double pt[3]={300.,300.,0.}; + double v[3]={0.,0.,2.}; + mTT->findNodesOnPlane(pt,v,1e-12,n); + CPPUNIT_ASSERT_EQUAL(43,(int)n.size()); + MEDCouplingUMesh *mTT3dSurf=(MEDCouplingUMesh *)mTT->buildFacePartOfMySelfNode(&n[0],&n[0]+n.size(),true); + MEDCouplingExtrudedMesh *meTT=MEDCouplingExtrudedMesh::New(mTT,mTT3dSurf,0); + CPPUNIT_ASSERT_EQUAL(200,meTT->getNumberOfCells()); + CPPUNIT_ASSERT_EQUAL(10,meTT->getMesh2D()->getNumberOfCells()); + CPPUNIT_ASSERT_EQUAL(20,meTT->getMesh1D()->getNumberOfCells()); + mTT3dSurf->decrRef(); + // + b=false; + da=mN->mergeNodes(1e-12,b,newNbOfNodes); + da->decrRef(); + CPPUNIT_ASSERT(!b); + n.clear(); + mN->findNodesOnPlane(pt,v,1e-12,n); + CPPUNIT_ASSERT_EQUAL(30,(int)n.size()); + MEDCouplingUMesh *mN3dSurf=(MEDCouplingUMesh *)mN->buildFacePartOfMySelfNode(&n[0],&n[0]+n.size(),true); + MEDCouplingExtrudedMesh *meN=MEDCouplingExtrudedMesh::New(mN,mN3dSurf,0); + CPPUNIT_ASSERT_EQUAL(40,meN->getNumberOfCells()); + CPPUNIT_ASSERT_EQUAL(20,meN->getMesh2D()->getNumberOfCells()); + CPPUNIT_ASSERT_EQUAL(2,meN->getMesh1D()->getNumberOfCells()); + mN3dSurf->decrRef(); + // + b=false; + da=mTF->mergeNodes(1e-12,b,newNbOfNodes); + da->decrRef(); + CPPUNIT_ASSERT(!b); + n.clear(); + mTF->findNodesOnPlane(pt,v,1e-12,n); + CPPUNIT_ASSERT_EQUAL(27,(int)n.size()); + MEDCouplingUMesh *mTF3dSurf=(MEDCouplingUMesh *)mTF->buildFacePartOfMySelfNode(&n[0],&n[0]+n.size(),true); + MEDCouplingExtrudedMesh *meTF=MEDCouplingExtrudedMesh::New(mTF,mTF3dSurf,0); + CPPUNIT_ASSERT_EQUAL(340,meTF->getNumberOfCells()); + CPPUNIT_ASSERT_EQUAL(17,meTF->getMesh2D()->getNumberOfCells()); + CPPUNIT_ASSERT_EQUAL(20,meTF->getMesh1D()->getNumberOfCells()); + mTF3dSurf->decrRef(); + // + meTT->decrRef(); + meN->decrRef(); + meTF->decrRef(); + // + mN->decrRef(); + mTT->decrRef(); + mTF->decrRef(); +} + +/*! + * This test check MEDCouplingUMesh::buildExtrudedMesh method. + */ +void MEDCouplingBasicsTest1::testExtrudedMesh3() +{ + MEDCouplingUMesh *m1=build2DTargetMesh_1(); + m1->changeSpaceDimension(3); + MEDCouplingUMesh *m2=buildCU1DMesh_U(); + m2->changeSpaceDimension(3); + double center[3]={0.,0.,0.}; + double vector[3]={0,1,0}; + m2->rotate(center,vector,-M_PI/2.); + MEDCouplingUMesh *m3=m1->buildExtrudedMesh(m2,0); + // + MEDCouplingExtrudedMesh *m4=MEDCouplingExtrudedMesh::New(m3,m1,0); + CPPUNIT_ASSERT_EQUAL(15,m4->getNumberOfCells()); + CPPUNIT_ASSERT_EQUAL(5,m4->getMesh2D()->getNumberOfCells()); + CPPUNIT_ASSERT_EQUAL(3,m4->getMesh1D()->getNumberOfCells()); + const int *m3DIds=m4->getMesh3DIds()->getConstPointer(); + for(int i=0;i<15;i++) + CPPUNIT_ASSERT_EQUAL(i,m3DIds[i]); + m4->decrRef(); + //some random in cells to check that extrusion alg find it correctly + const int expected1[15]={1,3,2,0,6,5,7,10,11,8,12,9,14,13,4}; + m3->renumberCells(expected1,false); + m4=MEDCouplingExtrudedMesh::New(m3,m1,0); + CPPUNIT_ASSERT_EQUAL(15,m4->getNumberOfCells()); + CPPUNIT_ASSERT_EQUAL(5,m4->getMesh2D()->getNumberOfCells()); + CPPUNIT_ASSERT_EQUAL(3,m4->getMesh1D()->getNumberOfCells()); + m3DIds=m4->getMesh3DIds()->getConstPointer(); + for(int i=0;i<15;i++) + CPPUNIT_ASSERT_EQUAL(expected1[i],m3DIds[i]); + m4->decrRef(); + m3->decrRef(); + //play with polygons and polyedrons + std::vector<int> cells(2); cells[0]=2; cells[1]=3; + m1->convertToPolyTypes(&cells[0],&cells[0]+cells.size()); + m3=m1->buildExtrudedMesh(m2,0); + CPPUNIT_ASSERT_EQUAL((int)INTERP_KERNEL::NORM_HEXA8,(int)m3->getTypeOfCell(0)); + CPPUNIT_ASSERT_EQUAL((int)INTERP_KERNEL::NORM_PENTA6,(int)m3->getTypeOfCell(1)); + CPPUNIT_ASSERT_EQUAL((int)INTERP_KERNEL::NORM_POLYHED,(int)m3->getTypeOfCell(2)); + CPPUNIT_ASSERT_EQUAL((int)INTERP_KERNEL::NORM_POLYHED,(int)m3->getTypeOfCell(3)); + CPPUNIT_ASSERT_EQUAL((int)INTERP_KERNEL::NORM_HEXA8,(int)m3->getTypeOfCell(4)); + m3->renumberCells(expected1,false); + m4=MEDCouplingExtrudedMesh::New(m3,m1,0); + CPPUNIT_ASSERT_EQUAL(15,m4->getNumberOfCells()); + CPPUNIT_ASSERT_EQUAL(5,m4->getMesh2D()->getNumberOfCells()); + CPPUNIT_ASSERT_EQUAL(3,m4->getMesh1D()->getNumberOfCells()); + m3DIds=m4->getMesh3DIds()->getConstPointer(); + for(int i=0;i<15;i++) + CPPUNIT_ASSERT_EQUAL(expected1[i],m3DIds[i]); + m4->decrRef(); + m3->decrRef(); + // + m2->decrRef(); + m1->decrRef(); +} + +/*! + * This test check MEDCouplingUMesh::buildExtrudedMesh method, but also, MEDCouplingExtrudedMesh following methods : + * getCellContainingPoint getMeasureField getNodeIdsOfCell getCoordinateOfNode getTypeOfCell build3DUnstructuredMesh. + */ +void MEDCouplingBasicsTest1::testExtrudedMesh4() +{ + MEDCouplingUMesh *m1=build2DTargetMesh_1(); + std::vector<int> cells(2); cells[0]=2; cells[1]=4; + m1->convertToPolyTypes(&cells[0],&cells[0]+cells.size()); + m1->changeSpaceDimension(3); + MEDCouplingUMesh *m2=buildCU1DMesh_U(); + m2->changeSpaceDimension(3); + double center[3]={0.,0.,0.}; + double vector[3]={0.,1.,0.}; + m2->rotate(center,vector,-M_PI/2.); + m1->zipCoords(); + MEDCouplingUMesh *m3=m1->buildExtrudedMesh(m2,0); + const int expected1[15]= {1,3,2,0,6,5,7,10,11,8,12,9,14,13,4}; + const int rexpected1[15]={3, 0, 2, 1, 14, 5, 4, 6, 9, 11, 7, 8, 10, 13, 12}; + m3->renumberCells(expected1,false); + MEDCouplingExtrudedMesh *m4=MEDCouplingExtrudedMesh::New(m3,m1,0); + CPPUNIT_ASSERT_EQUAL(INTERP_KERNEL::NORM_HEXA8,m4->getTypeOfCell(0)); + CPPUNIT_ASSERT_EQUAL(INTERP_KERNEL::NORM_HEXA8,m4->getTypeOfCell(1)); + CPPUNIT_ASSERT_EQUAL(INTERP_KERNEL::NORM_POLYHED,m4->getTypeOfCell(2)); + CPPUNIT_ASSERT_EQUAL(INTERP_KERNEL::NORM_PENTA6,m4->getTypeOfCell(7)); + MEDCouplingFieldDouble *f=m4->getMeasureField(true); + DataArrayDouble *arr=f->getArray(); + CPPUNIT_ASSERT_EQUAL(15,arr->getNumberOfTuples()); + CPPUNIT_ASSERT_EQUAL(1,arr->getNumberOfComponents()); + const double *arrPtr=arr->getConstPointer(); + const double expected2[15]={0.075,0.0375,0.0375,0.075,0.075, 0.1125,0.05625,0.05625,0.1125,0.1125, 0.0625,0.03125,0.03125,0.0625,0.0625}; + for(int i=0;i<15;i++) + CPPUNIT_ASSERT_DOUBLES_EQUAL(expected2[rexpected1[i]],arrPtr[i],1e-16); + f->decrRef(); + MEDCouplingUMesh *m5=m4->build3DUnstructuredMesh(); + m5->zipCoords(); + CPPUNIT_ASSERT(m5->isEqual(m3,1e-12)); + f=m5->getMeasureField(true); + arr=f->getArray(); + arrPtr=arr->getConstPointer(); + for(int i=0;i<15;i++) + CPPUNIT_ASSERT_DOUBLES_EQUAL(expected2[rexpected1[i]],arrPtr[i],1e-16); + f->decrRef(); + m5->decrRef(); + // + m4->decrRef(); + m3->decrRef(); + m2->decrRef(); + m1->decrRef(); +} + +void MEDCouplingBasicsTest1::testFindCommonNodes() +{ + DataArrayInt *comm,*commI; + MEDCouplingUMesh *targetMesh=build3DTargetMesh_1(); + targetMesh->findCommonNodes(1e-10,-1,comm,commI); + CPPUNIT_ASSERT_EQUAL(1,commI->getNumberOfTuples()); + CPPUNIT_ASSERT_EQUAL(0,comm->getNumberOfTuples()); + int newNbOfNodes; + DataArrayInt *o2n=targetMesh->buildNewNumberingFromCommonNodesFormat(comm,commI,newNbOfNodes); + CPPUNIT_ASSERT_EQUAL(27,newNbOfNodes); + CPPUNIT_ASSERT_EQUAL(27,o2n->getNumberOfTuples()); + const int o2nExp1[27]= + { + 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20, + 21,22,23,24,25,26 + }; + CPPUNIT_ASSERT(std::equal(o2nExp1,o2nExp1+27,o2n->getConstPointer())); + o2n->decrRef(); + comm->decrRef(); + commI->decrRef(); + targetMesh->decrRef(); + // + targetMesh=build3DTargetMeshMergeNode_1(); + CPPUNIT_ASSERT_EQUAL(31,targetMesh->getNumberOfNodes()); + targetMesh->findCommonNodes(1e-10,-1,comm,commI); + CPPUNIT_ASSERT_EQUAL(3,commI->getNumberOfTuples()); + CPPUNIT_ASSERT_EQUAL(6,comm->getNumberOfTuples()); + const int commExpected[6]={1,27,28,29,23,30}; + const int commIExpected[3]={0,4,6}; + CPPUNIT_ASSERT(std::equal(commExpected,commExpected+6,comm->getConstPointer())); + CPPUNIT_ASSERT(std::equal(commIExpected,commIExpected+3,commI->getConstPointer())); + o2n=targetMesh->buildNewNumberingFromCommonNodesFormat(comm,commI,newNbOfNodes); + CPPUNIT_ASSERT_EQUAL(31,o2n->getNumberOfTuples()); + CPPUNIT_ASSERT_EQUAL(27,newNbOfNodes); + const int o2nExp2[31]= + { + 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20, + 21,22,23,24,25,26,1,1,1,23 + }; + CPPUNIT_ASSERT(std::equal(o2nExp2,o2nExp2+31,o2n->getConstPointer())); + o2n->decrRef(); + comm->decrRef(); + commI->decrRef(); + targetMesh->decrRef(); + // + targetMesh=build3DTargetMesh_1(); + bool areNodesMerged; + unsigned int time=targetMesh->getTimeOfThis(); + o2n=targetMesh->mergeNodes(1e-10,areNodesMerged,newNbOfNodes); + targetMesh->updateTime(); + CPPUNIT_ASSERT(time==targetMesh->getTimeOfThis()); + CPPUNIT_ASSERT(!areNodesMerged); + targetMesh->decrRef(); + o2n->decrRef(); + // + targetMesh=build3DTargetMeshMergeNode_1(); + time=targetMesh->getTimeOfThis(); + o2n=targetMesh->mergeNodes(1e-10,areNodesMerged,newNbOfNodes); + targetMesh->updateTime(); + CPPUNIT_ASSERT(time!=targetMesh->getTimeOfThis()); + CPPUNIT_ASSERT(areNodesMerged); + int connExp[72]={18,0,1,4,3,9,10,13,12, 18,1,2,5,4,10,11,14,13, 18,3,4,7,6,12,13,16,15, + 18,4,5,8,7,13,14,17,16, + 18,9,10,13,12,18,19,22,21, 18,10,11,14,13,19,20,23,22, 18,12,13,16,15,21,22,25,24, + 18,13,14,17,16,22,23,26,25}; + CPPUNIT_ASSERT_EQUAL(72,targetMesh->getNodalConnectivity()->getNumberOfTuples()); + CPPUNIT_ASSERT(std::equal(connExp,connExp+72,targetMesh->getNodalConnectivity()->getConstPointer())); + CPPUNIT_ASSERT_EQUAL(27,targetMesh->getCoords()->getNumberOfTuples()); + double coordsExp[81]={ 0., 0., 0., 50., 0., 0. , 200., 0., 0. , 0., 50., 0., 50., 50., 0. , + 200., 50., 0., 0., 200., 0., 50., 200., 0. , 200., 200., 0. , + 0., 0., 50., 50., 0., 50. , 200., 0., 50. , 0., 50., 50., 50., + 50., 50. , 200., 50., 50., 0., 200., 50., 50., 200., 50. , + 200., 200., 50. , 0., 0., 200., 50., 0., 200. , 200., 0., 200. + , 0., 50., 200., 50., 50., 200. , 200., 50., 200., + 0., 200., 200., 50., 200., 200. , 200., 200., 200. }; + CPPUNIT_ASSERT(std::equal(coordsExp,coordsExp+81,targetMesh->getCoords()->getConstPointer())); + targetMesh->decrRef(); + o2n->decrRef(); + //2D + targetMesh=build2DTargetMeshMergeNode_1(); + CPPUNIT_ASSERT_EQUAL(18,targetMesh->getNumberOfNodes()); + time=targetMesh->getTimeOfThis(); + o2n=targetMesh->mergeNodes(1e-10,areNodesMerged,newNbOfNodes); + CPPUNIT_ASSERT(time!=targetMesh->getTimeOfThis()); + CPPUNIT_ASSERT(areNodesMerged); + CPPUNIT_ASSERT_EQUAL(9,targetMesh->getNumberOfNodes()); + int connExp2[23]={4,0,4,3,1, 3,1,3,2, 3,3,5,2, 4,4,6,7,3, 4,7,8,5,3}; + CPPUNIT_ASSERT_EQUAL(23,targetMesh->getNodalConnectivity()->getNumberOfTuples()); + CPPUNIT_ASSERT(std::equal(connExp2,connExp2+23,targetMesh->getNodalConnectivity()->getConstPointer())); + double coordsExp2[18]={-0.3,-0.3, 0.2,-0.3, 0.7,-0.3, 0.2,0.2, -0.3,0.2, 0.7,0.2, -0.3,0.7, 0.2,0.7, 0.7,0.7}; + CPPUNIT_ASSERT_EQUAL(9,targetMesh->getCoords()->getNumberOfTuples()); + CPPUNIT_ASSERT(std::equal(coordsExp2,coordsExp2+18,targetMesh->getCoords()->getConstPointer())); + targetMesh->decrRef(); + o2n->decrRef(); +} + +void MEDCouplingBasicsTest1::testCheckButterflyCells() +{ + std::vector<int> cells; + MEDCouplingUMesh *sourceMesh=build2DTargetMesh_1(); + sourceMesh->checkButterflyCells(cells); + CPPUNIT_ASSERT(cells.empty()); + int *pt=sourceMesh->getNodalConnectivity()->getPointer(); + std::swap(pt[15],pt[16]); + sourceMesh->checkButterflyCells(cells); + CPPUNIT_ASSERT_EQUAL(1,(int)cells.size()); + CPPUNIT_ASSERT_EQUAL(3,cells[0]); + cells.clear(); + std::swap(pt[15],pt[16]); + sourceMesh->checkButterflyCells(cells); + CPPUNIT_ASSERT(cells.empty()); + sourceMesh->decrRef(); + // 3D surf + sourceMesh=build3DSurfTargetMesh_1(); + sourceMesh->checkButterflyCells(cells); + CPPUNIT_ASSERT(cells.empty()); + pt=sourceMesh->getNodalConnectivity()->getPointer(); + std::swap(pt[15],pt[16]); + sourceMesh->checkButterflyCells(cells); + CPPUNIT_ASSERT_EQUAL(1,(int)cells.size()); + CPPUNIT_ASSERT_EQUAL(3,cells[0]); + cells.clear(); + std::swap(pt[15],pt[16]); + sourceMesh->checkButterflyCells(cells); + CPPUNIT_ASSERT(cells.empty()); + sourceMesh->decrRef(); +} + +void MEDCouplingBasicsTest1::testMergeMesh1() +{ + MEDCouplingUMesh *m1=build2DTargetMesh_1(); + MEDCouplingUMesh *m2=build2DSourceMesh_1(); + const double vec[2]={1.,0.}; + m2->translate(vec); + MEDCouplingMesh *m3=m1->mergeMyselfWith(m2); + MEDCouplingUMesh *m3C=dynamic_cast<MEDCouplingUMesh *>(m3); + CPPUNIT_ASSERT(m3C); + m3->checkCoherency(); + MEDCouplingUMesh *m4=build2DTargetMeshMerged_1(); + CPPUNIT_ASSERT(m3->isEqual(m4,1.e-12)); + m4->decrRef(); + bool isMerged; + int newNbOfNodes; + DataArrayInt *da=m3C->mergeNodes(1.e-12,isMerged,newNbOfNodes); + CPPUNIT_ASSERT_EQUAL(11,m3C->getNumberOfNodes()); + CPPUNIT_ASSERT_EQUAL(11,newNbOfNodes); + CPPUNIT_ASSERT(isMerged); + da->decrRef(); + m3->decrRef(); + m1->decrRef(); + m2->decrRef(); +} + +void MEDCouplingBasicsTest1::testMergeMeshOnSameCoords1() +{ + MEDCouplingUMesh *m1=build2DTargetMesh_1(); + MEDCouplingUMesh *m2=build2DTargetMesh_1(); + std::vector<int> cells(5); + for(int i=0;i<5;i++) + cells[i]=i; + m2->convertToPolyTypes(&cells[0],&cells[0]+cells.size()); + m1->tryToShareSameCoords(*m2,1e-12); + MEDCouplingUMesh *m3=build2DTargetMesh_1(); + m3->tryToShareSameCoords(*m2,1e-12); + std::vector<const MEDCouplingUMesh *> meshes; + meshes.push_back(m1); meshes.push_back(m2); meshes.push_back(m3); + MEDCouplingUMesh *m4=MEDCouplingUMesh::MergeUMeshesOnSameCoords(meshes); + m4->checkCoherency(); + CPPUNIT_ASSERT(m4->getCoords()==m1->getCoords()); + CPPUNIT_ASSERT_EQUAL(15,m4->getNumberOfCells()); + const int cells1[5]={0,1,2,3,4}; + MEDCouplingPointSet *m1_1=m4->buildPartOfMySelf(cells1,cells1+5,true); + m1_1->setName(m1->getName().c_str()); + CPPUNIT_ASSERT(m1->isEqual(m1_1,1e-12)); + const int cells2[5]={5,6,7,8,9}; + MEDCouplingPointSet *m2_1=m4->buildPartOfMySelf(cells2,cells2+5,true); + m2_1->setName(m2->getName().c_str()); + CPPUNIT_ASSERT(m2->isEqual(m2_1,1e-12)); + const int cells3[5]={10,11,12,13,14}; + MEDCouplingPointSet *m3_1=m4->buildPartOfMySelf(cells3,cells3+5,true); + m3_1->setName(m3->getName().c_str()); + CPPUNIT_ASSERT(m3->isEqual(m3_1,1e-12)); + m1_1->decrRef(); m2_1->decrRef(); m3_1->decrRef(); + // + m4->decrRef(); + m1->decrRef(); + m2->decrRef(); + m3->decrRef(); +} + +void MEDCouplingBasicsTest1::testMergeField1() +{ + MEDCouplingUMesh *m1=build2DTargetMesh_1(); + MEDCouplingUMesh *m2=build2DSourceMesh_1(); + const double vec[2]={1.,0.}; + m2->translate(vec); + MEDCouplingFieldDouble *f1=m1->getMeasureField(true); + MEDCouplingFieldDouble *f2=m2->getMeasureField(true); + MEDCouplingFieldDouble *f3=MEDCouplingFieldDouble::MergeFields(f1,f2); + f3->checkCoherency(); + MEDCouplingUMesh *m4=build2DTargetMeshMerged_1(); + CPPUNIT_ASSERT(f3->getMesh()->isEqual(m4,1.e-12)); + std::string name=f3->getName(); + CPPUNIT_ASSERT(name=="MeasureOfMesh_"); + CPPUNIT_ASSERT(f3->getTypeOfField()==ON_CELLS); + CPPUNIT_ASSERT(f3->getTimeDiscretization()==ONE_TIME); + CPPUNIT_ASSERT_EQUAL(1,f3->getNumberOfComponents()); + CPPUNIT_ASSERT_EQUAL(7,f3->getNumberOfTuples()); + double values[7]={0.25,0.125,0.125,0.25,0.25,0.5,0.5}; + const double *tmp=f3->getArray()->getConstPointer(); + std::transform(tmp,tmp+7,values,values,std::minus<double>()); + std::transform(values,values+7,values,std::ptr_fun<double,double>(fabs)); + double max=*std::max_element(values,values+7); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.,max,1.e-12); + m4->decrRef(); + f3->decrRef(); + f1->decrRef(); + f2->decrRef(); + m1->decrRef(); + m2->decrRef(); +} + +bool func1(const double *pt, double *res); +bool func2(const double *pt, double *res); +bool func3(const double *pt, double *res); +bool func4(const double *pt, double *res); + +bool func1(const double *pt, double *res) +{ + res[0]=pt[0]+pt[1]; + return true; +} + +bool func2(const double *pt, double *res) +{ + res[0]=pt[0]+pt[1]; + res[1]=2.*(pt[0]+pt[1]); + return true; +} + +bool func3(const double *pt, double *res) +{ + if(fabs(pt[0]-0.2)<1e-12) + return false; + res[0]=1./(pt[0]-0.2); + return true; +} + +void MEDCouplingBasicsTest1::testFillFromAnalytic() +{ + MEDCouplingUMesh *m=build2DTargetMesh_1(); + m->setTime(3.4,5,6); m->setTimeUnit("us"); + int a,b; + MEDCouplingFieldDouble *f1=m->fillFromAnalytic(ON_CELLS,1,func1); + CPPUNIT_ASSERT_DOUBLES_EQUAL(3.4,f1->getTime(a,b),1.e-14); + CPPUNIT_ASSERT_EQUAL(5,a); CPPUNIT_ASSERT_EQUAL(6,b); + CPPUNIT_ASSERT_EQUAL(std::string(f1->getTimeUnit()),std::string("us")); + f1->checkCoherency(); + CPPUNIT_ASSERT(f1->getTypeOfField()==ON_CELLS); + CPPUNIT_ASSERT(f1->getTimeDiscretization()==ONE_TIME); + CPPUNIT_ASSERT_EQUAL(1,f1->getNumberOfComponents()); + CPPUNIT_ASSERT_EQUAL(5,f1->getNumberOfTuples()); + double values1[5]={-0.1,0.23333333333333336,0.56666666666666665,0.4,0.9}; + const double *tmp=f1->getArray()->getConstPointer(); + std::transform(tmp,tmp+5,values1,values1,std::minus<double>()); + std::transform(values1,values1+5,values1,std::ptr_fun<double,double>(fabs)); + double max=*std::max_element(values1,values1+5); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.,max,1.e-12); + f1->decrRef(); + // + f1=m->fillFromAnalytic(ON_NODES,1,func1); + f1->checkCoherency(); + CPPUNIT_ASSERT(f1->getTypeOfField()==ON_NODES); + CPPUNIT_ASSERT(f1->getTimeDiscretization()==ONE_TIME); + CPPUNIT_ASSERT_EQUAL(1,f1->getNumberOfComponents()); + CPPUNIT_ASSERT_EQUAL(9,f1->getNumberOfTuples()); + double values2[9]={-0.6,-0.1,0.4,-0.1,0.4,0.9,0.4,0.9,1.4}; + tmp=f1->getArray()->getConstPointer(); + std::transform(tmp,tmp+9,values2,values2,std::minus<double>()); + std::transform(values2,values2+9,values2,std::ptr_fun<double,double>(fabs)); + max=*std::max_element(values2,values2+9); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.,max,1.e-12); + f1->decrRef(); + // + f1=m->fillFromAnalytic(ON_NODES,2,func2); + f1->checkCoherency(); + CPPUNIT_ASSERT(f1->getTypeOfField()==ON_NODES); + CPPUNIT_ASSERT(f1->getTimeDiscretization()==ONE_TIME); + CPPUNIT_ASSERT_EQUAL(2,f1->getNumberOfComponents()); + CPPUNIT_ASSERT_EQUAL(9,f1->getNumberOfTuples()); + double values3[18]={-0.6,-1.2,-0.1,-0.2,0.4,0.8,-0.1,-0.2,0.4,0.8,0.9,1.8,0.4,0.8,0.9,1.8,1.4,2.8}; + tmp=f1->getArray()->getConstPointer(); + std::transform(tmp,tmp+18,values3,values3,std::minus<double>()); + std::transform(values3,values3+18,values3,std::ptr_fun<double,double>(fabs)); + max=*std::max_element(values3,values3+18); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.,max,1.e-12); + double values4[2]; + f1->accumulate(values4); + CPPUNIT_ASSERT_DOUBLES_EQUAL(3.6,values4[0],1.e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(7.2,values4[1],1.e-12); + f1->integral(true,values4); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.5,values4[0],1.e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,values4[1],1.e-12); + f1->decrRef(); + // + CPPUNIT_ASSERT_THROW(f1=m->fillFromAnalytic(ON_NODES,1,func3),INTERP_KERNEL::Exception); + // + m->decrRef(); +} + +void MEDCouplingBasicsTest1::testFillFromAnalytic2() +{ + MEDCouplingUMesh *m=build2DTargetMesh_1(); + MEDCouplingFieldDouble *f1=m->fillFromAnalytic(ON_CELLS,1,"y+x"); + f1->checkCoherency(); + CPPUNIT_ASSERT(f1->getTypeOfField()==ON_CELLS); + CPPUNIT_ASSERT(f1->getTimeDiscretization()==ONE_TIME); + CPPUNIT_ASSERT_EQUAL(1,f1->getNumberOfComponents()); + CPPUNIT_ASSERT_EQUAL(5,f1->getNumberOfTuples()); + double values1[5]={-0.1,0.23333333333333336,0.56666666666666665,0.4,0.9}; + const double *tmp=f1->getArray()->getConstPointer(); + std::transform(tmp,tmp+5,values1,values1,std::minus<double>()); + std::transform(values1,values1+5,values1,std::ptr_fun<double,double>(fabs)); + double max=*std::max_element(values1,values1+5); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.,max,1.e-12); + f1->decrRef(); + // + f1=m->fillFromAnalytic(ON_NODES,1,"y+2*x"); + f1->checkCoherency(); + CPPUNIT_ASSERT(f1->getTypeOfField()==ON_NODES); + CPPUNIT_ASSERT(f1->getTimeDiscretization()==ONE_TIME); + CPPUNIT_ASSERT_EQUAL(1,f1->getNumberOfComponents()); + CPPUNIT_ASSERT_EQUAL(9,f1->getNumberOfTuples()); + double values2[9]={-0.9,0.1,1.1,-0.4,0.6,1.6,0.1,1.1,2.1}; + tmp=f1->getArray()->getConstPointer(); + std::transform(tmp,tmp+9,values2,values2,std::minus<double>()); + std::transform(values2,values2+9,values2,std::ptr_fun<double,double>(fabs)); + max=*std::max_element(values2,values2+9); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.,max,1.e-12); + f1->decrRef(); + f1=m->fillFromAnalytic(ON_NODES,1,"2.*x+y"); + f1->checkCoherency(); + CPPUNIT_ASSERT(f1->getTypeOfField()==ON_NODES); + CPPUNIT_ASSERT(f1->getTimeDiscretization()==ONE_TIME); + CPPUNIT_ASSERT_EQUAL(1,f1->getNumberOfComponents()); + CPPUNIT_ASSERT_EQUAL(9,f1->getNumberOfTuples()); + tmp=f1->getArray()->getConstPointer(); + double values2Bis[9]={-0.9,0.1,1.1,-0.4,0.6,1.6,0.1,1.1,2.1}; + std::transform(tmp,tmp+9,values2Bis,values2Bis,std::minus<double>()); + std::transform(values2,values2+9,values2Bis,std::ptr_fun<double,double>(fabs)); + max=*std::max_element(values2Bis,values2Bis+9); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.,max,1.e-12); + f1->decrRef(); + // + f1=m->fillFromAnalytic(ON_NODES,2,"(x+y)*IVec+2*(x+y)*JVec"); + f1->checkCoherency(); + CPPUNIT_ASSERT(f1->getTypeOfField()==ON_NODES); + CPPUNIT_ASSERT(f1->getTimeDiscretization()==ONE_TIME); + CPPUNIT_ASSERT_EQUAL(2,f1->getNumberOfComponents()); + CPPUNIT_ASSERT_EQUAL(9,f1->getNumberOfTuples()); + double values3[18]={-0.6,-1.2,-0.1,-0.2,0.4,0.8,-0.1,-0.2,0.4,0.8,0.9,1.8,0.4,0.8,0.9,1.8,1.4,2.8}; + tmp=f1->getArray()->getConstPointer(); + std::transform(tmp,tmp+18,values3,values3,std::minus<double>()); + std::transform(values3,values3+18,values3,std::ptr_fun<double,double>(fabs)); + max=*std::max_element(values3,values3+18); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.,max,1.e-12); + double values4[2]; + f1->accumulate(values4); + CPPUNIT_ASSERT_DOUBLES_EQUAL(3.6,values4[0],1.e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(7.2,values4[1],1.e-12); + f1->integral(true,values4); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.5,values4[0],1.e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,values4[1],1.e-12); + f1->decrRef(); + // + CPPUNIT_ASSERT_THROW(f1=m->fillFromAnalytic(ON_NODES,1,"1./(x-0.2)"),INTERP_KERNEL::Exception); + // + m->decrRef(); +} + +void MEDCouplingBasicsTest1::testApplyFunc() +{ + MEDCouplingUMesh *m=build2DTargetMesh_1(); + MEDCouplingFieldDouble *f1=m->fillFromAnalytic(ON_NODES,2,func2); + f1->checkCoherency(); + CPPUNIT_ASSERT(f1->getTypeOfField()==ON_NODES); + CPPUNIT_ASSERT(f1->getTimeDiscretization()==ONE_TIME); + CPPUNIT_ASSERT_EQUAL(2,f1->getNumberOfComponents()); + CPPUNIT_ASSERT_EQUAL(9,f1->getNumberOfTuples()); + f1->applyFunc(1,func1); + CPPUNIT_ASSERT(f1->getTypeOfField()==ON_NODES); + CPPUNIT_ASSERT(f1->getTimeDiscretization()==ONE_TIME); + CPPUNIT_ASSERT_EQUAL(1,f1->getNumberOfComponents()); + CPPUNIT_ASSERT_EQUAL(9,f1->getNumberOfTuples()); + double values1[9]={-1.8,-0.3,1.2,-0.3,1.2,2.7,1.2,2.7,4.2}; + const double *tmp=f1->getArray()->getConstPointer(); + std::transform(tmp,tmp+9,values1,values1,std::minus<double>()); + std::transform(values1,values1+9,values1,std::ptr_fun<double,double>(fabs)); + double max=*std::max_element(values1,values1+9); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.,max,1.e-12); + f1->decrRef(); + m->decrRef(); +} + +void MEDCouplingBasicsTest1::testApplyFunc2() +{ + MEDCouplingUMesh *m=build2DTargetMesh_1(); + MEDCouplingFieldDouble *f1=m->fillFromAnalytic(ON_NODES,2,func2); + f1->checkCoherency(); + CPPUNIT_ASSERT(f1->getTypeOfField()==ON_NODES); + CPPUNIT_ASSERT(f1->getTimeDiscretization()==ONE_TIME); + CPPUNIT_ASSERT_EQUAL(2,f1->getNumberOfComponents()); + CPPUNIT_ASSERT_EQUAL(9,f1->getNumberOfTuples()); + // + MEDCouplingFieldDouble *f2=f1->clone(true); + CPPUNIT_ASSERT_THROW(f2->applyFunc(1,"a+b+c+d"),INTERP_KERNEL::Exception); + CPPUNIT_ASSERT_THROW(f2->applyFunc(1,"a/0"),INTERP_KERNEL::Exception); + CPPUNIT_ASSERT_THROW(f2->applyFunc("a/0"),INTERP_KERNEL::Exception); + f2->applyFunc("abs(u)^2.4+2*u"); + CPPUNIT_ASSERT(f1->getTypeOfField()==ON_NODES); + CPPUNIT_ASSERT(f1->getTimeDiscretization()==ONE_TIME); + CPPUNIT_ASSERT_EQUAL(2,f1->getNumberOfComponents()); + CPPUNIT_ASSERT_EQUAL(9,f1->getNumberOfTuples()); + double values2[18]={-0.9065304805418678, -0.85105859001709905, -0.19601892829446504, -0.37898777756476987, + 0.91090317490482353, 2.1853504664669781, -0.19601892829446504, -0.37898777756476987, + 0.91090317490482353, 2.1853504664669781, 2.5765725275664879, 7.6987743736515295, + 0.91090317490482353, 2.1853504664669781, 2.5765725275664879, 7.6987743736515295, + 5.0423700574830965, 17.435300118916864}; + const double *tmp=f2->getArray()->getConstPointer(); + std::transform(tmp,tmp+18,values2,values2,std::minus<double>()); + std::transform(values2,values2+18,values2,std::ptr_fun<double,double>(fabs)); + double max=*std::max_element(values2,values2+18); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.,max,1.e-12); + f2->decrRef(); + // + f1->applyFunc(1,"x+y"); + CPPUNIT_ASSERT(f1->getTypeOfField()==ON_NODES); + CPPUNIT_ASSERT(f1->getTimeDiscretization()==ONE_TIME); + CPPUNIT_ASSERT_EQUAL(1,f1->getNumberOfComponents()); + CPPUNIT_ASSERT_EQUAL(9,f1->getNumberOfTuples()); + double values1[9]={-1.8,-0.3,1.2,-0.3,1.2,2.7,1.2,2.7,4.2}; + tmp=f1->getArray()->getConstPointer(); + std::transform(tmp,tmp+9,values1,values1,std::minus<double>()); + std::transform(values1,values1+9,values1,std::ptr_fun<double,double>(fabs)); + max=*std::max_element(values1,values1+9); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.,max,1.e-12); + f1->decrRef(); + m->decrRef(); +} + +void MEDCouplingBasicsTest1::testOperationsOnFields() +{ + MEDCouplingUMesh *m=build2DTargetMesh_1(); + MEDCouplingFieldDouble *f1=m->fillFromAnalytic(ON_NODES,1,func1); + MEDCouplingFieldDouble *f2=m->fillFromAnalytic(ON_NODES,1,func1); + f1->checkCoherency(); + f2->checkCoherency(); + MEDCouplingFieldDouble *f3=(*f1)+(*f2); + f3->checkCoherency(); + CPPUNIT_ASSERT(f3->getTypeOfField()==ON_NODES); + CPPUNIT_ASSERT(f3->getTimeDiscretization()==ONE_TIME); + double values1[9]={-1.2,-0.2,0.8,-0.2,0.8,1.8,0.8,1.8,2.8}; + const double *tmp=f3->getArray()->getConstPointer(); + std::transform(tmp,tmp+9,values1,values1,std::minus<double>()); + std::transform(values1,values1+9,values1,std::ptr_fun<double,double>(fabs)); + double max=*std::max_element(values1,values1+9); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.,max,1.e-12); + f3->decrRef(); + // + f3=(*f1)*(*f2); + f3->checkCoherency(); + CPPUNIT_ASSERT(f3->getTypeOfField()==ON_NODES); + CPPUNIT_ASSERT(f3->getTimeDiscretization()==ONE_TIME); + double values2[9]={0.36,0.01,0.16,0.01,0.16,0.81,0.16,0.81,1.96}; + tmp=f3->getArray()->getConstPointer(); + std::transform(tmp,tmp+9,values2,values2,std::minus<double>()); + std::transform(values2,values2+9,values2,std::ptr_fun<double,double>(fabs)); + max=*std::max_element(values2,values2+9); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.,max,1.e-12); + f3->decrRef(); + // + f3=(*f1)+(*f2); + MEDCouplingFieldDouble *f4=(*f1)-(*f3); + f4->checkCoherency(); + CPPUNIT_ASSERT(f4->getTypeOfField()==ON_NODES); + CPPUNIT_ASSERT(f4->getTimeDiscretization()==ONE_TIME); + double values3[9]={0.6,0.1,-0.4,0.1,-0.4,-0.9,-0.4,-0.9,-1.4}; + tmp=f4->getArray()->getConstPointer(); + std::transform(tmp,tmp+9,values3,values3,std::minus<double>()); + std::transform(values3,values3+9,values3,std::ptr_fun<double,double>(fabs)); + max=*std::max_element(values3,values3+9); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.,max,1.e-12); + f3->decrRef(); + f4->decrRef(); + // + f3=(*f1)+(*f2); + f4=(*f3)/(*f2); + f4->checkCoherency(); + CPPUNIT_ASSERT(f4->getTypeOfField()==ON_NODES); + CPPUNIT_ASSERT(f4->getTimeDiscretization()==ONE_TIME); + tmp=f4->getArray()->getConstPointer(); + for(int i=0;i<9;i++) + CPPUNIT_ASSERT_DOUBLES_EQUAL(2.,tmp[i],1.e-12); + f3->decrRef(); + f4->decrRef(); + // + f4=f2->buildNewTimeReprFromThis(NO_TIME,false); + f4->checkCoherency(); + CPPUNIT_ASSERT(f4->getArray()==f2->getArray()); + CPPUNIT_ASSERT(f4->getTypeOfField()==ON_NODES); + CPPUNIT_ASSERT(f4->getTimeDiscretization()==NO_TIME); + CPPUNIT_ASSERT_THROW(f3=(*f1)+(*f4),INTERP_KERNEL::Exception); + MEDCouplingFieldDouble *f5=f4->buildNewTimeReprFromThis(ONE_TIME,false); + CPPUNIT_ASSERT(f4->getArray()==f5->getArray()); + CPPUNIT_ASSERT(f5->getTypeOfField()==ON_NODES); + CPPUNIT_ASSERT(f5->getTimeDiscretization()==ONE_TIME); + f3=(*f1)+(*f5); + tmp=f3->getArray()->getConstPointer(); + double values4[9]={-1.2,-0.2,0.8,-0.2,0.8,1.8,0.8,1.8,2.8}; + std::transform(tmp,tmp+9,values4,values4,std::minus<double>()); + std::transform(values4,values4+9,values4,std::ptr_fun<double,double>(fabs)); + max=*std::max_element(values4,values4+9); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.,max,1.e-12); + f5->decrRef(); + f4->decrRef(); + f3->decrRef(); + // + f4=f2->buildNewTimeReprFromThis(NO_TIME,true); + f4->checkCoherency(); + CPPUNIT_ASSERT(f4->getArray()!=f2->getArray()); + CPPUNIT_ASSERT(f4->getTypeOfField()==ON_NODES); + CPPUNIT_ASSERT(f4->getTimeDiscretization()==NO_TIME); + CPPUNIT_ASSERT_THROW(f3=(*f1)+(*f4),INTERP_KERNEL::Exception); + f5=f4->buildNewTimeReprFromThis(ONE_TIME,true); + CPPUNIT_ASSERT(f4->getArray()!=f5->getArray()); + CPPUNIT_ASSERT(f2->getArray()!=f5->getArray()); + CPPUNIT_ASSERT(f5->getTypeOfField()==ON_NODES); + CPPUNIT_ASSERT(f5->getTimeDiscretization()==ONE_TIME); + f3=(*f1)+(*f5); + tmp=f3->getArray()->getConstPointer(); + double values5[9]={-1.2,-0.2,0.8,-0.2,0.8,1.8,0.8,1.8,2.8}; + std::transform(tmp,tmp+9,values5,values5,std::minus<double>()); + std::transform(values5,values5+9,values5,std::ptr_fun<double,double>(fabs)); + max=*std::max_element(values5,values5+9); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.,max,1.e-12); + f5->decrRef(); + f4->decrRef(); + f3->decrRef(); + // + f1->decrRef(); + f2->decrRef(); + m->decrRef(); +} + +void MEDCouplingBasicsTest1::testOperationsOnFields2() +{ + MEDCouplingUMesh *m=build3DSurfTargetMesh_1(); + m->setTime(3.4,5,6); m->setTimeUnit("us"); + int a,b; + MEDCouplingFieldDouble *f1=m->fillFromAnalytic(ON_NODES,1,"x+y+z"); + MEDCouplingFieldDouble *f2=m->fillFromAnalytic(ON_NODES,1,"a*a+b+c*c"); + MEDCouplingFieldDouble *f3=(*f1)/(*f2); + f3->checkCoherency(); + CPPUNIT_ASSERT(f3->getTypeOfField()==ON_NODES); + CPPUNIT_ASSERT(f3->getTimeDiscretization()==ONE_TIME); + const double expected1[9]={-2.4999999999999991, 1.2162162162162162, 0.77868852459016391, + 0.7407407407407407, 1.129032258064516, 0.81632653061224492, + 0.86538461538461531, 1.0919540229885056, 0.84302325581395343}; + CPPUNIT_ASSERT_EQUAL(1,f3->getNumberOfComponents()); + CPPUNIT_ASSERT_EQUAL(9,f3->getNumberOfTuples()); + const double *val=f3->getArray()->getConstPointer(); + for(int i=0;i<9;i++) + CPPUNIT_ASSERT_DOUBLES_EQUAL(expected1[i],val[i],1.e-12); + f3->decrRef(); + f1->decrRef(); + f2->decrRef(); + // + f1=m->buildOrthogonalField(); + CPPUNIT_ASSERT_DOUBLES_EQUAL(3.4,f1->getTime(a,b),1.e-14); + CPPUNIT_ASSERT_EQUAL(5,a); CPPUNIT_ASSERT_EQUAL(6,b); + CPPUNIT_ASSERT_EQUAL(std::string(f1->getTimeUnit()),std::string("us")); + f2=m->fillFromAnalytic(ON_CELLS,1,"x"); + f3=(*f1)*(*f2); + const double expected2[15]={-0.035355339059327376,0.,0.035355339059327376, 0.2592724864350674,0.,-0.2592724864350674, 0.37712361663282529,0.,-0.37712361663282529, -0.035355339059327376,0.,0.035355339059327376, 0.31819805153394637,0.,-0.31819805153394637}; + val=f3->getArray()->getConstPointer(); + for(int i=0;i<15;i++) + CPPUNIT_ASSERT_DOUBLES_EQUAL(expected2[i],val[i],1.e-12); + f3->decrRef(); + // + f3=(*f2)*(*f1); + val=f3->getArray()->getConstPointer(); + for(int i=0;i<15;i++) + CPPUNIT_ASSERT_DOUBLES_EQUAL(expected2[i],val[i],1.e-12); + f3->decrRef(); + // + f1->decrRef(); + f2->decrRef(); + // + m->decrRef(); +} + +void MEDCouplingBasicsTest1::testOperationsOnFields3() +{ + MEDCouplingUMesh *m=build3DSurfTargetMesh_1(); + MEDCouplingFieldDouble *f1=m->fillFromAnalytic(ON_NODES,1,"x+y+z"); + MEDCouplingFieldDouble *f2=m->fillFromAnalytic(ON_NODES,1,"a*a+b+c*c"); + (*f1)/=(*f2); + f1->checkCoherency(); + CPPUNIT_ASSERT(f1->getTypeOfField()==ON_NODES); + CPPUNIT_ASSERT(f1->getTimeDiscretization()==ONE_TIME); + const double expected1[9]={-2.4999999999999991, 1.2162162162162162, 0.77868852459016391, + 0.7407407407407407, 1.129032258064516, 0.81632653061224492, + 0.86538461538461531, 1.0919540229885056, 0.84302325581395343}; + CPPUNIT_ASSERT_EQUAL(1,f1->getNumberOfComponents()); + CPPUNIT_ASSERT_EQUAL(9,f1->getNumberOfTuples()); + const double *val=f1->getArray()->getConstPointer(); + for(int i=0;i<9;i++) + CPPUNIT_ASSERT_DOUBLES_EQUAL(expected1[i],val[i],1.e-12); + f1->decrRef(); + f2->decrRef(); + // + f1=m->buildOrthogonalField(); + f2=m->fillFromAnalytic(ON_CELLS,1,"x"); + (*f1)*=(*f2); + const double expected2[15]={-0.035355339059327376,0.,0.035355339059327376, 0.2592724864350674,0.,-0.2592724864350674, 0.37712361663282529,0.,-0.37712361663282529, -0.035355339059327376,0.,0.035355339059327376, 0.31819805153394637,0.,-0.31819805153394637}; + val=f1->getArray()->getConstPointer(); + for(int i=0;i<15;i++) + CPPUNIT_ASSERT_DOUBLES_EQUAL(expected2[i],val[i],1.e-12); + f1->decrRef(); + // + f1=m->buildOrthogonalField(); + CPPUNIT_ASSERT_THROW((*f2)*=(*f1),INTERP_KERNEL::Exception); + f1->decrRef(); + f2->decrRef(); + // + m->decrRef(); +} + +/*! + * Check of LINEAR_TIME and CONST_ON_TIME_INTERVAL policies + */ +void MEDCouplingBasicsTest1::testOperationsOnFields4() +{ + MEDCouplingUMesh *m=build2DTargetMesh_1(); + int nbOfCells=m->getNumberOfCells(); + MEDCouplingFieldDouble *f1=MEDCouplingFieldDouble::New(ON_CELLS,CONST_ON_TIME_INTERVAL); + f1->setMesh(m); + DataArrayDouble *array=DataArrayDouble::New(); + array->alloc(nbOfCells,3); + f1->setArray(array); + CPPUNIT_ASSERT_THROW(f1->setEndArray(array),INTERP_KERNEL::Exception); + CPPUNIT_ASSERT_THROW(f1->getEndArray(),INTERP_KERNEL::Exception); + array->decrRef(); + double *tmp=array->getPointer(); + const double arr1[15]={0.,10.,20.,1.,11.,21.,2.,12.,22.,3.,13.,23.,4.,14.,24.}; + const double arr2[15]={5.,15.,25.,6.,16.,26.,7.,17.,27.,8.,18.,28.,9.,19.,29.}; + std::copy(arr1,arr1+15,tmp); + f1->setStartTime(2.,0,0); + f1->setEndTime(3.,0,0); + f1->checkCoherency(); + double res[3]; + const double pos[2]={0.3,-0.2}; + f1->getValueOn(pos,res); + CPPUNIT_ASSERT_DOUBLES_EQUAL(arr1[3],res[0],1.e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(arr1[4],res[1],1.e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(arr1[5],res[2],1.e-12); + std::fill(res,res+3,0.); + f1->getValueOn(pos,2.2,res); + CPPUNIT_ASSERT_DOUBLES_EQUAL(arr1[3],res[0],1.e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(arr1[4],res[1],1.e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(arr1[5],res[2],1.e-12); + std::fill(res,res+3,0.); + CPPUNIT_ASSERT_THROW(f1->getValueOn(pos,3.2,res),INTERP_KERNEL::Exception); + MEDCouplingFieldDouble *f2=MEDCouplingFieldDouble::New(ON_CELLS,LINEAR_TIME); + f2->setMesh(m); + f2->setArray(f1->getArray()); + f2->setStartTime(2.,3,0); + f2->setEndTime(4.,13,0); + CPPUNIT_ASSERT_THROW(f2->checkCoherency(),INTERP_KERNEL::Exception); + DataArrayDouble *array2=DataArrayDouble::New(); + array2->alloc(nbOfCells,3); + tmp=array2->getPointer(); + std::copy(arr2,arr2+15,tmp); + f2->setEndArray(array2); + array2->decrRef(); + f2->checkCoherency(); + // + std::fill(res,res+3,0.); + f2->getValueOn(pos,3.21,res); + CPPUNIT_ASSERT_DOUBLES_EQUAL(4.025,res[0],1.e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(14.025,res[1],1.e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(24.025,res[2],1.e-12); + MEDCouplingFieldDouble *f3=f2->clone(true); + CPPUNIT_ASSERT(f2->isEqual(f3,1e-12,1e-12)); + f3->getEndArray()->getPointer()[0]=5.001; + CPPUNIT_ASSERT(!f2->isEqual(f3,1e-12,1e-12)); + CPPUNIT_ASSERT(f2->isEqual(f3,1e-12,1e-2)); + f3->setStartTime(2.1,3,0); + CPPUNIT_ASSERT(!f2->isEqual(f3,1e-12,1e-2)); + f3->setStartTime(2.,3,0); + CPPUNIT_ASSERT(f2->isEqual(f3,1e-12,1e-2)); + f3->setStartTime(2.,4,0); + CPPUNIT_ASSERT(!f2->isEqual(f3,1e-12,1e-2)); + f3->setStartTime(2.,3,1); + CPPUNIT_ASSERT(!f2->isEqual(f3,1e-12,1e-2)); + f3->setStartTime(2.,3,0); + CPPUNIT_ASSERT(f2->isEqual(f3,1e-12,1e-2)); + f3->setEndTime(4.1,13,0); + CPPUNIT_ASSERT(!f2->isEqual(f3,1e-12,1e-2)); + f3->setEndTime(4.,13,0); + CPPUNIT_ASSERT(f2->isEqual(f3,1e-12,1e-2)); + f3->setEndTime(4.,14,0); + CPPUNIT_ASSERT(!f2->isEqual(f3,1e-12,1e-2)); + f3->setEndTime(4.,13,1); + CPPUNIT_ASSERT(!f2->isEqual(f3,1e-12,1e-2)); + f3->setEndTime(4.,13,0); + CPPUNIT_ASSERT(f2->isEqual(f3,1e-12,1e-2)); + f3->decrRef(); + MEDCouplingFieldDouble *f4=(*f2)+(*f2); + std::fill(res,res+3,0.); + f4->getValueOn(pos,3.21,res); + CPPUNIT_ASSERT_DOUBLES_EQUAL(8.05,res[0],1.e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(28.05,res[1],1.e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(48.05,res[2],1.e-12); + (*f4)+=*f2; + std::fill(res,res+3,0.); + f4->getValueOn(pos,3.21,res); + CPPUNIT_ASSERT_DOUBLES_EQUAL(12.075,res[0],1.e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(42.075,res[1],1.e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(72.075,res[2],1.e-12); + f4->decrRef(); + // + f2->decrRef(); + f1->decrRef(); + m->decrRef(); +} + +bool func4(const double *pt, double *res) +{ + res[0]=pt[0]+pt[1]+pt[2]; + return true; +} + +void MEDCouplingBasicsTest1::testMergeNodesOnField() +{ + double *tmp; + MEDCouplingUMesh *targetMesh=build3DTargetMeshMergeNode_1(); + MEDCouplingFieldDouble *f1=targetMesh->fillFromAnalytic(ON_NODES,1,func4); + f1->mergeNodes(1e-10); + f1->decrRef(); + targetMesh->decrRef(); + // + targetMesh=build3DTargetMeshMergeNode_1(); + f1=targetMesh->fillFromAnalytic(ON_NODES,1,func4); + tmp=f1->getArray()->getPointer(); + tmp[0]=1000.; + f1->mergeNodes(1e-10); + f1->decrRef(); + targetMesh->decrRef(); + // + targetMesh=build3DTargetMeshMergeNode_1(); + f1=targetMesh->fillFromAnalytic(ON_NODES,1,func4); + tmp=f1->getArray()->getPointer(); + tmp[1]=1000.; + CPPUNIT_ASSERT_THROW(f1->mergeNodes(1e-10),INTERP_KERNEL::Exception); + f1->decrRef(); + targetMesh->decrRef(); +} + +void MEDCouplingBasicsTest1::testCheckConsecutiveCellTypes() +{ + MEDCouplingUMesh *sourceMesh=build2DSourceMesh_1(); + MEDCouplingUMesh *targetMesh=build2DTargetMesh_1(); + CPPUNIT_ASSERT(sourceMesh->checkConsecutiveCellTypes()); + const INTERP_KERNEL::NormalizedCellType order1[]={INTERP_KERNEL::NORM_TRI3, INTERP_KERNEL::NORM_QUAD4}; + const INTERP_KERNEL::NormalizedCellType order2[]={INTERP_KERNEL::NORM_QUAD4, INTERP_KERNEL::NORM_TRI3}; + CPPUNIT_ASSERT(!targetMesh->checkConsecutiveCellTypes()); + CPPUNIT_ASSERT(!targetMesh->checkConsecutiveCellTypesAndOrder(order1,order1+2)); + CPPUNIT_ASSERT(!targetMesh->checkConsecutiveCellTypesAndOrder(order2,order2+2)); + DataArrayInt *da=targetMesh->getRenumArrForConsecutiveCellTypesSpec(order1,order1+2); + CPPUNIT_ASSERT_EQUAL(5,da->getNumberOfTuples()); + CPPUNIT_ASSERT_EQUAL(1,da->getNumberOfComponents()); + const int expected1[5]={2,0,1,3,4}; + CPPUNIT_ASSERT(std::equal(expected1,expected1+5,da->getConstPointer())); + da->decrRef(); + da=targetMesh->getRenumArrForConsecutiveCellTypesSpec(order2,order2+2); + CPPUNIT_ASSERT_EQUAL(5,da->getNumberOfTuples()); + CPPUNIT_ASSERT_EQUAL(1,da->getNumberOfComponents()); + const int expected2[5]={0,3,4,1,2}; + CPPUNIT_ASSERT(std::equal(expected2,expected2+5,da->getConstPointer())); + da->decrRef(); + const int renumber1[5]={4,0,1,2,3}; + targetMesh->renumberCells(renumber1,false); + CPPUNIT_ASSERT(targetMesh->checkConsecutiveCellTypes()); + CPPUNIT_ASSERT(targetMesh->checkConsecutiveCellTypesAndOrder(order1,order1+2)); + CPPUNIT_ASSERT(!targetMesh->checkConsecutiveCellTypesAndOrder(order2,order2+2)); + targetMesh->decrRef(); + sourceMesh->decrRef(); +} + +void MEDCouplingBasicsTest1::testRearrange2ConsecutiveCellTypes() +{ + MEDCouplingUMesh *m1_1=build2DSourceMesh_1(); + MEDCouplingUMesh *m2_1=build2DTargetMesh_1(); + DataArrayInt *arr1=m1_1->rearrange2ConsecutiveCellTypes(); + MEDCouplingUMesh *m1_2=build2DSourceMesh_1(); + CPPUNIT_ASSERT(m1_2->isEqual(m1_1,1e-12)); + const int expected1[2]={0,1}; + CPPUNIT_ASSERT_EQUAL(2,arr1->getNumberOfTuples()); + CPPUNIT_ASSERT_EQUAL(1,arr1->getNumberOfComponents()); + CPPUNIT_ASSERT(std::equal(expected1,expected1+2,arr1->getConstPointer())); + arr1->decrRef(); + const int expected2[5]={0,3,4,1,2}; + arr1=m2_1->rearrange2ConsecutiveCellTypes(); + CPPUNIT_ASSERT_EQUAL(5,arr1->getNumberOfTuples()); + CPPUNIT_ASSERT_EQUAL(1,arr1->getNumberOfComponents()); + CPPUNIT_ASSERT(std::equal(expected2,expected2+5,arr1->getConstPointer())); + MEDCouplingUMesh *m2_2=build2DTargetMesh_1(); + CPPUNIT_ASSERT_EQUAL(5,arr1->getNumberOfTuples()); + CPPUNIT_ASSERT_EQUAL(1,arr1->getNumberOfComponents()); + CPPUNIT_ASSERT(std::equal(expected2,expected2+5,arr1->getConstPointer())); + CPPUNIT_ASSERT(!m2_2->isEqual(m2_1,1e-12)); + m2_2->renumberCells(expected2,false); + CPPUNIT_ASSERT(m2_2->isEqual(m2_1,1e-12)); + arr1->decrRef(); + m1_1->decrRef(); + m1_2->decrRef(); + m2_1->decrRef(); + m2_2->decrRef(); +} + +void MEDCouplingBasicsTest1::testSplitByType() +{ + MEDCouplingUMesh *m1=build3DSurfTargetMesh_1(); + std::vector<MEDCouplingUMesh *> v=m1->splitByType(); + CPPUNIT_ASSERT_EQUAL(3,(int)v.size()); + std::vector<const MEDCouplingUMesh *> v2(v.begin(),v.end()); + MEDCouplingUMesh *m2=MEDCouplingUMesh::MergeUMeshesOnSameCoords(v2); + m2->setName(m1->getName().c_str()); + CPPUNIT_ASSERT(m1->isEqual(m2,1.e-12)); + for(std::vector<MEDCouplingUMesh *>::const_iterator iter=v.begin();iter!=v.end();iter++) + (*iter)->decrRef(); + m2->decrRef(); + m1->decrRef(); +} + +void MEDCouplingBasicsTest1::testFuseUMeshesOnSameCoords() +{ + std::vector<const MEDCouplingUMesh *> meshes; + MEDCouplingUMesh *m2=build2DTargetMesh_1(); + int cells1[3]={2,3,4}; + MEDCouplingPointSet *m3_1=m2->buildPartOfMySelf(cells1,cells1+3,true); + MEDCouplingUMesh *m3=dynamic_cast<MEDCouplingUMesh *>(m3_1); + CPPUNIT_ASSERT(m3); + meshes.push_back(m3); + int cells2[3]={1,2,4}; + MEDCouplingPointSet *m4_1=m2->buildPartOfMySelf(cells2,cells2+3,true); + MEDCouplingUMesh *m4=dynamic_cast<MEDCouplingUMesh *>(m4_1); + CPPUNIT_ASSERT(m4); + meshes.push_back(m4); + int cells3[2]={1,2}; + MEDCouplingPointSet *m5_1=m2->buildPartOfMySelf(cells3,cells3+2,true); + MEDCouplingUMesh *m5=dynamic_cast<MEDCouplingUMesh *>(m5_1); + CPPUNIT_ASSERT(m5); + meshes.push_back(m5); + m2->decrRef(); + // + std::vector<DataArrayInt *> corr; + MEDCouplingUMesh *m7=MEDCouplingUMesh::FuseUMeshesOnSameCoords(meshes,0,corr); + CPPUNIT_ASSERT_EQUAL(4,m7->getNumberOfCells()); + CPPUNIT_ASSERT_EQUAL(3,(int)corr.size()); + const int expectedVals1[3]={3,3,2}; + const int expectedVals2[3][3]={{0,1,2},{3,0,2},{3,0,111111}}; + for(int i=0;i<3;i++) + { + DataArrayInt *arr=corr[i]; + CPPUNIT_ASSERT_EQUAL(1,arr->getNumberOfComponents()); + int nbOfVals=expectedVals1[i]; + CPPUNIT_ASSERT_EQUAL(nbOfVals,arr->getNumberOfTuples()); + const int *vals=arr->getConstPointer(); + for(int j=0;j<nbOfVals;j++) + CPPUNIT_ASSERT_EQUAL(expectedVals2[i][j],vals[j]); + } + std::vector< std::vector<int> > fidsOfGroups; + std::vector<const DataArrayInt *> corr2(corr.begin(),corr.end()); + DataArrayInt *arr2=DataArrayInt::MakePartition(corr2,m7->getNumberOfCells(),fidsOfGroups); + const int fidExp[4]={5,1,3,4}; + const int fidsGrp[3][3]={{1,3,5},{3,4,5},{4,5,23344}}; + CPPUNIT_ASSERT_EQUAL(3,(int)fidsOfGroups.size()); + CPPUNIT_ASSERT_EQUAL(1,arr2->getNumberOfComponents()); + CPPUNIT_ASSERT_EQUAL(4,arr2->getNumberOfTuples()); + CPPUNIT_ASSERT(std::equal(fidExp,fidExp+4,arr2->getConstPointer())); + for(int i=0;i<3;i++) + { + int nbOfVals=expectedVals1[i]; + CPPUNIT_ASSERT_EQUAL(nbOfVals,(int)fidsOfGroups[i].size()); + CPPUNIT_ASSERT(std::equal(fidsOfGroups[i].begin(),fidsOfGroups[i].end(),fidsGrp[i])); + } + for(std::vector<DataArrayInt *>::iterator iter=corr.begin();iter!=corr.end();iter++) + (*iter)->decrRef(); + arr2->decrRef(); + m7->decrRef(); + // + m3->decrRef(); + m4->decrRef(); + m5->decrRef(); +} + +void MEDCouplingBasicsTest1::testFuseUMeshesOnSameCoords2() +{ + MEDCouplingUMesh *m2; + MEDCouplingUMesh *m1=build3DExtrudedUMesh_1(m2); + m2->decrRef(); + const int part1[5]={2,3,6,4,10}; + MEDCouplingUMesh *m3=(MEDCouplingUMesh *)m1->buildPartOfMySelf(part1,part1+5,true); + const int part2[4]={5,6,4,7}; + MEDCouplingUMesh *m4=(MEDCouplingUMesh *)m1->buildPartOfMySelf(part2,part2+4,true); + std::vector<const MEDCouplingUMesh *> meshes; + meshes.push_back(m1); + meshes.push_back(m3); + meshes.push_back(m3); + meshes.push_back(m4); + std::vector<DataArrayInt *> corr; + MEDCouplingUMesh *m5=MEDCouplingUMesh::FuseUMeshesOnSameCoords(meshes,0,corr); + CPPUNIT_ASSERT_EQUAL(18,m5->getNumberOfCells()); + std::vector<DataArrayInt *>::iterator it=corr.begin(); + const int exp1[4]={18,5,5,4}; + const int exp2[4][18]={ + {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17}, + {2,3,6,4,10,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1}, + {2,3,6,4,10,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1}, + {5,6,4,7,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1} + }; + int i=0; + for(;it!=corr.end();it++,i++) + { + int sz=(*it)->getNumberOfTuples(); + CPPUNIT_ASSERT_EQUAL(exp1[i],sz); + CPPUNIT_ASSERT(std::equal(exp2[i],exp2[i]+sz,(*it)->getConstPointer())); + } + for(it=corr.begin();it!=corr.end();it++) + (*it)->decrRef(); + m5->decrRef(); + m4->decrRef(); + m3->decrRef(); + m1->decrRef(); +} + +void MEDCouplingBasicsTest1::testBuildOrthogonalField() +{ + MEDCouplingUMesh *targetMesh=build3DSurfTargetMesh_1(); + MEDCouplingFieldDouble *field=targetMesh->buildOrthogonalField(); + double expected[3]={0.70710678118654746,0.,-0.70710678118654746}; + CPPUNIT_ASSERT_EQUAL(5,field->getNumberOfTuples()); + CPPUNIT_ASSERT_EQUAL(3,field->getNumberOfComponents()); + const double *vals=field->getArray()->getConstPointer(); + for(int i=0;i<15;i++) + CPPUNIT_ASSERT_DOUBLES_EQUAL(expected[i%3],vals[i],1e-12); + field->decrRef(); + targetMesh->decrRef(); + // testing + double targetCoords[12]={0.,0.,0.,0.5,0.,0.5,1.,0.,1.,0.,1.,0.}; + int targetConn[4]={0,1,2,3}; + targetMesh=MEDCouplingUMesh::New(); + targetMesh->setMeshDimension(2); + targetMesh->allocateCells(1); + targetMesh->insertNextCell(INTERP_KERNEL::NORM_QUAD4,4,targetConn); + targetMesh->finishInsertingCells(); + DataArrayDouble *myCoords=DataArrayDouble::New(); + myCoords->alloc(4,3); + std::copy(targetCoords,targetCoords+12,myCoords->getPointer()); + targetMesh->setCoords(myCoords); + myCoords->decrRef(); + field=targetMesh->buildOrthogonalField(); + CPPUNIT_ASSERT_EQUAL(1,field->getNumberOfTuples()); + CPPUNIT_ASSERT_EQUAL(3,field->getNumberOfComponents()); + vals=field->getArray()->getConstPointer(); + CPPUNIT_ASSERT_DOUBLES_EQUAL(-0.70710678118654746,vals[0],1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.,vals[1],1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.70710678118654746,vals[2],1e-12); + field->decrRef(); + targetMesh->decrRef(); +} + +void MEDCouplingBasicsTest1::testGetCellsContainingPoint() +{ + MEDCouplingUMesh *targetMesh=build2DTargetMesh_1(); + double pos[12]={0.,0.,0.4,0.4,0.,0.4,0.1,0.1,0.25,0.,0.65,0.}; + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> t1,t2; + //2D basic + targetMesh->getCellsContainingPoints(pos,6,1e-12,t1,t2); + CPPUNIT_ASSERT_EQUAL(6,(int)t1->getNbOfElems()); + CPPUNIT_ASSERT_EQUAL(7,(int)t2->getNbOfElems()); + const int expectedValues1[6]={0,4,3,0,1,2}; + const int expectedValues2[7]={0,1,2,3,4,5,6}; + CPPUNIT_ASSERT(std::equal(t1->begin(),t1->end(),expectedValues1)); + CPPUNIT_ASSERT(std::equal(t2->begin(),t2->end(),expectedValues2)); + //2D with no help of bounding box. + double center[2]={0.2,0.2}; + MEDCouplingPointSet::Rotate2DAlg(center,0.78539816339744830962,6,pos); + targetMesh->rotate(center,0,0.78539816339744830962); + targetMesh->getCellsContainingPoints(pos,6,1e-12,t1,t2); + CPPUNIT_ASSERT_EQUAL(6,(int)t1->getNbOfElems()); + CPPUNIT_ASSERT_EQUAL(7,(int)t2->getNbOfElems()); + CPPUNIT_ASSERT(std::equal(t1->begin(),t1->end(),expectedValues1)); + CPPUNIT_ASSERT(std::equal(t2->begin(),t2->end(),expectedValues2)); + //2D outside + const double pos1bis[2]={-0.3303300858899107,-0.11819805153394641}; + CPPUNIT_ASSERT_EQUAL(-1,targetMesh->getCellContainingPoint(pos1bis,1e-12)); + targetMesh->decrRef(); + //test limits 2D + targetMesh=build2DTargetMesh_1(); + const double pos2[2]={0.2,-0.05}; + std::vector<int> t11; + t11.clear(); + targetMesh->getCellsContainingPoint(pos2,1e-12,t11); + CPPUNIT_ASSERT_EQUAL(2,(int)t11.size()); + const int expectedValues3[2]={0,1}; + CPPUNIT_ASSERT(std::equal(t11.begin(),t11.end(),expectedValues3)); + const double pos3[2]={0.2,0.2}; + t11.clear(); + targetMesh->getCellsContainingPoint(pos3,1e-12,t11); + CPPUNIT_ASSERT_EQUAL(5,(int)t11.size()); + const int expectedValues4[5]={0,1,2,3,4}; + CPPUNIT_ASSERT(std::equal(t11.begin(),t11.end(),expectedValues4)); + CPPUNIT_ASSERT_EQUAL(0,targetMesh->getCellContainingPoint(pos3,1e-12)); + targetMesh->decrRef(); + //3D + targetMesh=build3DTargetMesh_1(); + const double pos4[3]={25.,25.,25.}; + CPPUNIT_ASSERT_EQUAL(0,targetMesh->getCellContainingPoint(pos4,1e-12)); + const double pos5[3]={50.,50.,50.}; + t11.clear(); + targetMesh->getCellsContainingPoint(pos5,1e-12,t11); + CPPUNIT_ASSERT_EQUAL(8,(int)t11.size()); + const int expectedValues5[8]={0,1,2,3,4,5,6,7}; + CPPUNIT_ASSERT(std::equal(t11.begin(),t11.end(),expectedValues5)); + const double pos6[3]={0., 50., 0.}; + t11.clear(); + targetMesh->getCellsContainingPoint(pos6,1e-12,t11); + CPPUNIT_ASSERT_EQUAL(2,(int)t11.size()); + const int expectedValues6[2]={0,2}; + CPPUNIT_ASSERT(std::equal(t11.begin(),t11.end(),expectedValues6)); + //3D outside + const double pos7[3]={-1.0,-1.0,0.}; + CPPUNIT_ASSERT_EQUAL(-1,targetMesh->getCellContainingPoint(pos7,1e-12)); + //3D outside 2 + const double center2[3]={0.,0.,0.}; + const double vec2[3]={0.,-1.,0.}; + targetMesh->rotate(center2,vec2,0.78539816339744830962); + const double pos8[3]={-25,25.,12.}; + CPPUNIT_ASSERT_EQUAL(-1,targetMesh->getCellContainingPoint(pos8,1e-12)); + // + targetMesh->decrRef(); +} + +void MEDCouplingBasicsTest1::testGetValueOn1() +{ + MEDCouplingUMesh *targetMesh=build2DTargetMesh_1(); + MEDCouplingFieldDouble *fieldOnCells=MEDCouplingFieldDouble::New(ON_CELLS); + int nbOfCells=targetMesh->getNumberOfCells(); + fieldOnCells->setMesh(targetMesh); + DataArrayDouble *array=DataArrayDouble::New(); + array->alloc(nbOfCells,2); + fieldOnCells->setArray(array); + double *tmp=array->getPointer(); + for(int i=0;i<nbOfCells;i++) + { tmp[2*i]=7.+(double)i; tmp[2*i+1]=17.+(double)i; } + array->decrRef(); + // + const double pos1[2]={0.25,0.}; + double res[2]; + fieldOnCells->getValueOn(pos1,res); + CPPUNIT_ASSERT_DOUBLES_EQUAL(8.,res[0],1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(18.,res[1],1e-12); + // + fieldOnCells->decrRef(); + targetMesh->decrRef(); + // + targetMesh=build2DSourceMesh_1(); + MEDCouplingFieldDouble *fieldOnNodes=MEDCouplingFieldDouble::New(ON_NODES); + int nbOfNodes=targetMesh->getNumberOfNodes(); + fieldOnNodes->setMesh(targetMesh); + array=DataArrayDouble::New(); + array->alloc(nbOfNodes,2); + fieldOnNodes->setArray(array); + tmp=array->getPointer(); + for(int i=0;i<nbOfNodes;i++) + { tmp[2*i]=17.+(double)i; tmp[2*i+1]=27.+(double)i; } + array->decrRef(); + // + const double pos2[2]={-0.13333333333333333,-0.13333333333333333}; + fieldOnNodes->getValueOn(pos2,res); + CPPUNIT_ASSERT_DOUBLES_EQUAL(17.5,res[0],1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(27.5,res[1],1e-12); + const double pos3[2]={0.033333333333333326,0.36666666666666664}; + fieldOnNodes->getValueOn(pos3,res); + CPPUNIT_ASSERT_DOUBLES_EQUAL(18.666666666666667,res[0],1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(28.666666666666667,res[1],1e-12); + // + fieldOnNodes->decrRef(); + targetMesh->decrRef(); +} + +void MEDCouplingBasicsTest1::testCMesh0() +{ + MEDCouplingCMesh* mesh=MEDCouplingCMesh::New(); + MEDCouplingCMesh* meshEmpty=mesh->clone(true); + CPPUNIT_ASSERT(meshEmpty->isEqual(mesh,1e-12)); + + DataArrayDouble* coordsX=DataArrayDouble::New(); + double arrX[4] = { -1., 1., 2., 4. }; + coordsX->useArray(arrX,false, CPP_DEALLOC,4,1); + DataArrayDouble* coordsY=DataArrayDouble::New(); + double arrY[4] = { -2., 2., 4., 8. }; + coordsY->useArray(arrY,false, CPP_DEALLOC,4,1); + DataArrayDouble* coordsZ=DataArrayDouble::New(); + double arrZ[4] = { -3., 3., 6., 12. }; + coordsZ->useArray(arrZ,false, CPP_DEALLOC,4,1); + mesh->setCoords(coordsX,coordsY,coordsZ); + coordsX->decrRef(); + coordsY->decrRef(); + coordsZ->decrRef(); + // + MEDCouplingFieldDouble *fieldOnNodes=mesh->fillFromAnalytic(ON_NODES,1,"x+y/2.+z/3."); + CPPUNIT_ASSERT_EQUAL(1,fieldOnNodes->getNumberOfComponents()); + CPPUNIT_ASSERT_EQUAL(64,fieldOnNodes->getNumberOfTuples()); + const double expected1[64]={-3., -1., 0., 2., -1., 1., 2., 4., 0., 2., 3., 5., 2., 4., 5., 7., -1., 1., 2., + 4., 1., 3., 4., 6., 2., 4., 5., 7., 4., 6., 7., 9., 0., 2., 3., 5., 2., 4., 5., + 7., 3., 5., 6., 8., 5., 7., 8., 10., 2., 4., 5., + 7., 4., 6., 7., 9., 5., 7., 8., 10., 7., 9., 10., 12.}; + const double *val=fieldOnNodes->getArray()->getConstPointer(); + for(int i=0;i<64;i++) + CPPUNIT_ASSERT_DOUBLES_EQUAL(expected1[i],val[i],1e-12); + double res[1]; //size fieldOnNodes->getNumberOfComponents() + fieldOnNodes->getValueOnPos(1,3,2,&res[0]); + CPPUNIT_ASSERT_DOUBLES_EQUAL(7.,res[0],1e-12); + fieldOnNodes->decrRef(); + // + MEDCouplingFieldDouble *fieldOnCells=mesh->fillFromAnalytic(ON_CELLS,1,"x+y/2.+z/3."); + CPPUNIT_ASSERT_EQUAL(1,fieldOnCells->getNumberOfComponents()); + CPPUNIT_ASSERT_EQUAL(27,fieldOnCells->getNumberOfTuples()); + val=fieldOnCells->getArray()->getConstPointer(); + const double expected2[27]={0, 1.5, 3, 1.5, 3, 4.5, 3, 4.5, 6, 1.5, 3, 4.5, 3, 4.5, + 6, 4.5, 6, 7.5, 3, 4.5, 6, 4.5, 6, 7.5, 6, 7.5, 9}; + for(int i=0;i<27;i++) + CPPUNIT_ASSERT_DOUBLES_EQUAL(expected2[i],val[i],1e-12); + fieldOnCells->getValueOnPos(1,2,1,&res[0]); + CPPUNIT_ASSERT_DOUBLES_EQUAL(6.,res[0],1e-12); + fieldOnCells->decrRef(); + // + MEDCouplingMesh* meshDeepCopy=mesh->deepCpy(); + MEDCouplingCMesh* meshClone=mesh->clone(false); + + CPPUNIT_ASSERT_THROW(meshEmpty->copyTinyStringsFrom(0),INTERP_KERNEL::Exception); + meshEmpty->copyTinyStringsFrom(mesh); + //no data in meshEmpty, expected false + CPPUNIT_ASSERT(!meshEmpty->isEqual(mesh,1e-12)); + + CPPUNIT_ASSERT(meshDeepCopy->isEqual(mesh,1e-12)); + meshDeepCopy->copyTinyStringsFrom(mesh); + CPPUNIT_ASSERT(meshDeepCopy->isEqual(mesh,1e-12)); + CPPUNIT_ASSERT(meshClone->isEqual(mesh,1e-12)); + + CPPUNIT_ASSERT_EQUAL(CARTESIAN,mesh->getType()); + CPPUNIT_ASSERT_EQUAL(CARTESIAN,meshEmpty->getType()); + CPPUNIT_ASSERT_EQUAL(CARTESIAN,meshDeepCopy->getType()); + CPPUNIT_ASSERT_EQUAL(CARTESIAN,meshClone->getType()); + + mesh->decrRef(); + meshEmpty->decrRef(); + meshDeepCopy->decrRef(); + meshClone->decrRef(); +} + +void MEDCouplingBasicsTest1::testCMesh1() +{ + MEDCouplingCMesh *mesh1,*mesh2,*mesh3; + mesh1=MEDCouplingCMesh::New(); + DataArrayDouble* coordsX1=DataArrayDouble::New(); + double arrX1[4] = { -1., 1., 2., 4. }; + coordsX1->useArray(arrX1,false, CPP_DEALLOC,4,1); + DataArrayDouble* coordsY1=DataArrayDouble::New(); + double arrY1[4] = { -2., 2., 4., 8. }; + coordsY1->useArray(arrY1,false, CPP_DEALLOC,4,1); + DataArrayDouble* coordsZ1=DataArrayDouble::New(); + double arrZ1[4] = { -3., 3., 6., 12. }; + coordsZ1->useArray(arrZ1,false, CPP_DEALLOC,4,1); + mesh1->setCoords(coordsX1,coordsY1,coordsZ1); + + mesh2=MEDCouplingCMesh::New(); + DataArrayDouble* coordsX2=DataArrayDouble::New(); + double arrX2[4] = { -1., 1., 2., 4. }; + coordsX2->useArray(arrX2,false, CPP_DEALLOC,4,1); + DataArrayDouble* coordsY2=DataArrayDouble::New(); + double arrY2[4] = { -2., 2., 4., 8. }; + coordsY2->useArray(arrY2,false, CPP_DEALLOC,4,1); + DataArrayDouble* coordsZ2=DataArrayDouble::New(); + double arrZ2[4] = { -3., 3., 6., 12.+1e-6 }; //here is not equal + coordsZ2->useArray(arrZ2,false, CPP_DEALLOC,4,1); + mesh2->setCoords(coordsX2,coordsY2,coordsZ2); + + mesh3=MEDCouplingCMesh::New(); + DataArrayDouble* coordsX3=DataArrayDouble::New(); + double arrX3[1] = { -1.}; + coordsX3->useArray(arrX3,false, CPP_DEALLOC,1,1); + DataArrayDouble* coordsY3=DataArrayDouble::New(); + double arrY3[1] = { -2.}; + coordsY3->useArray(arrY3,false, CPP_DEALLOC,1,1); + DataArrayDouble* coordsZ3=DataArrayDouble::New(); + double arrZ3[1] = { -3.}; + coordsZ3->useArray(arrZ3,false, CPP_DEALLOC,1,1); + mesh3->setCoords(coordsX3,coordsY3,coordsZ3); + + CPPUNIT_ASSERT_EQUAL(3,mesh1->getSpaceDimension()); + CPPUNIT_ASSERT_EQUAL(3,mesh1->getMeshDimension()); + + CPPUNIT_ASSERT(!mesh1->isEqual(mesh2,1e-12)); + CPPUNIT_ASSERT(!mesh2->isEqual(mesh1,1e-12)); + CPPUNIT_ASSERT(!mesh2->isEqualWithoutConsideringStr(mesh1,1e-12)); + CPPUNIT_ASSERT(mesh1->isEqual(mesh2,1e-5)); + CPPUNIT_ASSERT(!mesh1->isEqual(mesh2,1e-7)); + + CPPUNIT_ASSERT_THROW(mesh3->checkCoherency1(1e-12),INTERP_KERNEL::Exception); + mesh1->checkCoherency2(1e-12); + CPPUNIT_ASSERT_EQUAL(INTERP_KERNEL::NORM_HEXA8,mesh1->getTypeOfCell(1)); + + CPPUNIT_ASSERT_EQUAL(INTERP_KERNEL::NORM_HEXA8,*((mesh1->getAllGeoTypes()).begin())); + CPPUNIT_ASSERT_EQUAL(27,mesh1->getNumberOfCellsWithType(INTERP_KERNEL::NORM_HEXA8)); + CPPUNIT_ASSERT_THROW(mesh1->getNumberOfCellsWithType(INTERP_KERNEL::NORM_QUAD4),INTERP_KERNEL::Exception); + + std::vector<double> coo; + mesh1->getCoordinatesOfNode(0, coo); + CPPUNIT_ASSERT_EQUAL(3,(int) coo.size()); + CPPUNIT_ASSERT_DOUBLES_EQUAL(-1.,coo[0],1e-14); + CPPUNIT_ASSERT_DOUBLES_EQUAL(-2.,coo[1],1e-14); + CPPUNIT_ASSERT_DOUBLES_EQUAL(-3.,coo[2],1e-14); + coo.clear(); + mesh1->getCoordinatesOfNode(63, coo); + CPPUNIT_ASSERT_EQUAL(3,(int) coo.size()); + CPPUNIT_ASSERT_DOUBLES_EQUAL(4.,coo[0],1e-14); + CPPUNIT_ASSERT_DOUBLES_EQUAL(8.,coo[1],1e-14); + CPPUNIT_ASSERT_DOUBLES_EQUAL(12.,coo[2],1e-14); + + std::string repr; + repr=mesh1->simpleRepr(); + repr=mesh1->advancedRepr(); + CPPUNIT_ASSERT(!(repr.find("Cartesian")==std::string::npos)); + CPPUNIT_ASSERT(!(repr.find("Number of components : 1")==std::string::npos)); + CPPUNIT_ASSERT(!(repr.find("Number of tuples : 4")==std::string::npos)); + CPPUNIT_ASSERT(!(repr.find("Z Array :")==std::string::npos)); + coordsX1->decrRef(); + coordsY1->decrRef(); + coordsZ1->decrRef(); + coordsX2->decrRef(); + coordsY2->decrRef(); + coordsZ2->decrRef(); + coordsX3->decrRef(); + coordsY3->decrRef(); + coordsZ3->decrRef(); + mesh1->decrRef(); + mesh2->decrRef(); + mesh3->decrRef(); +} + +void MEDCouplingBasicsTest1::testCMesh2() +{ + MEDCouplingCMesh *mesh1; + mesh1=MEDCouplingCMesh::New(); + DataArrayDouble* coordsX1=DataArrayDouble::New(); + double arrX1[4] = { -1., 1., 2., 4. }; + coordsX1->useArray(arrX1,false, CPP_DEALLOC,4,1); + DataArrayDouble* coordsY1=DataArrayDouble::New(); + double arrY1[4] = { -2., 2., 4., 8. }; + coordsY1->useArray(arrY1,false, CPP_DEALLOC,4,1); + DataArrayDouble* coordsZ1=DataArrayDouble::New(); + double arrZ1[4] = { -3., 3., 6., 12. }; + coordsZ1->useArray(arrZ1,false, CPP_DEALLOC,4,1); + mesh1->setCoords(coordsX1,coordsY1,coordsZ1); + + std::vector<int> dis=mesh1->getDistributionOfTypes(); + CPPUNIT_ASSERT_EQUAL(3,(int) dis.size()); + CPPUNIT_ASSERT_EQUAL((int) INTERP_KERNEL::NORM_HEXA8,dis[0]); + CPPUNIT_ASSERT_EQUAL(27,dis[1]); + CPPUNIT_ASSERT_EQUAL(-1,dis[2]); + + std::vector<const DataArrayInt *> idsPerType; + CPPUNIT_ASSERT(!(mesh1->checkTypeConsistencyAndContig(dis, idsPerType))); + dis[0]=(int) INTERP_KERNEL::NORM_QUAD4; + CPPUNIT_ASSERT_THROW(mesh1->checkTypeConsistencyAndContig(dis, idsPerType),INTERP_KERNEL::Exception); + + dis[0]=(int) INTERP_KERNEL::NORM_HEXA8; + dis[2]=0; + DataArrayInt *ids=DataArrayInt::New(); + ids->alloc(10,1); + ids->fillWithValue(23); + idsPerType.push_back(ids); + DataArrayInt* check=mesh1->checkTypeConsistencyAndContig(dis, idsPerType); + CPPUNIT_ASSERT(check); + CPPUNIT_ASSERT(check->isEqual(*ids)); + + std::vector<int> code; + std::vector<DataArrayInt *> idsInPflPerType; + std::vector<DataArrayInt *> pfls; + mesh1->splitProfilePerType(ids,code,idsInPflPerType,pfls); + CPPUNIT_ASSERT_EQUAL(3,(int)code.size()); + CPPUNIT_ASSERT_EQUAL((int) INTERP_KERNEL::NORM_HEXA8,code[0]); + CPPUNIT_ASSERT_EQUAL(10,code[1]); + CPPUNIT_ASSERT_EQUAL(0,code[2]); + CPPUNIT_ASSERT_EQUAL(1,(int)idsInPflPerType.size()); + CPPUNIT_ASSERT_EQUAL(1,(int)pfls.size()); + DataArrayInt *exp=DataArrayInt::New(); exp->alloc(10,1); exp->iota(0); + CPPUNIT_ASSERT(idsInPflPerType[0]->isEqual(*exp)); + exp->decrRef(); + CPPUNIT_ASSERT(pfls[0]->isEqual(*ids)); + idsInPflPerType[0]->decrRef(); + pfls[0]->decrRef(); + + ids->decrRef(); + check->decrRef(); + int cells1[4]={0,1,25,26}; + MEDCouplingUMesh *partMesh1= + dynamic_cast<MEDCouplingUMesh *>(mesh1->buildPart(cells1,cells1+4)); + CPPUNIT_ASSERT(partMesh1); + CPPUNIT_ASSERT_EQUAL(4,partMesh1->getNumberOfCellsWithType(INTERP_KERNEL::NORM_HEXA8)); + CPPUNIT_ASSERT_EQUAL(64,mesh1->getNumberOfNodes()); + CPPUNIT_ASSERT_EQUAL(64,partMesh1->getNumberOfNodes()); + + int cells2[2]={25,26}; + DataArrayInt* arr1; + MEDCouplingCMesh *partMesh2= + dynamic_cast<MEDCouplingCMesh *>(mesh1->buildPartAndReduceNodes(cells2,cells2+2,arr1)); + CPPUNIT_ASSERT(partMesh2); + CPPUNIT_ASSERT_EQUAL(2,partMesh2->getNumberOfCellsWithType(INTERP_KERNEL::NORM_HEXA8)); + CPPUNIT_ASSERT_EQUAL(12,partMesh2->getNumberOfNodes()); + + int cells3[2]={2,3}; + DataArrayInt* arr2; + MEDCouplingUMesh *partMesh3= + dynamic_cast<MEDCouplingUMesh *>(partMesh1->buildPartAndReduceNodes(cells3,cells3+2,arr2)); + CPPUNIT_ASSERT(partMesh3); + CPPUNIT_ASSERT_EQUAL(2,partMesh3->getNumberOfCellsWithType(INTERP_KERNEL::NORM_HEXA8)); + CPPUNIT_ASSERT_EQUAL(12,partMesh3->getNumberOfNodes()); + + CPPUNIT_ASSERT_THROW(mesh1->simplexize(0),INTERP_KERNEL::Exception); + CPPUNIT_ASSERT_THROW(mesh1->getMeasureFieldOnNode(true),INTERP_KERNEL::Exception); + + double bbox1[6]; + double bbox2[6]; + mesh1->getBoundingBox(bbox1); + partMesh1->getBoundingBox(bbox2); + for(int i=0;i<6;i++) + CPPUNIT_ASSERT_DOUBLES_EQUAL(bbox1[i],bbox2[i],1e-12); + partMesh3->getBoundingBox(bbox1); + partMesh2->getBoundingBox(bbox2); + for(int i=0;i<6;i++) + CPPUNIT_ASSERT_DOUBLES_EQUAL(bbox1[i],bbox2[i],1e-12); + + CPPUNIT_ASSERT_THROW(mesh1->buildOrthogonalField(),INTERP_KERNEL::Exception); + MEDCouplingCMesh *mesh2d=MEDCouplingCMesh::New(); + mesh2d->setCoords(coordsX1,coordsY1); + MEDCouplingFieldDouble *f1=mesh2d->buildOrthogonalField(); + + std::vector<double> tinyInfoD; + std::vector<int> tinyInfo; + std::vector<std::string> littleStrings; + mesh2d->getTinySerializationInformation(tinyInfoD, tinyInfo, littleStrings); + CPPUNIT_ASSERT_EQUAL(5,(int)tinyInfo.size()); + CPPUNIT_ASSERT_EQUAL(4,(int)tinyInfo[0]); //x + CPPUNIT_ASSERT_EQUAL(4,(int)tinyInfo[1]); //y + CPPUNIT_ASSERT_EQUAL(-1,(int)tinyInfo[2]); //z + CPPUNIT_ASSERT_EQUAL(-1,(int)tinyInfo[3]); //it + CPPUNIT_ASSERT_EQUAL(-1,(int)tinyInfo[4]); //order + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.,tinyInfoD[0],1e-14); //time + DataArrayInt* d1=DataArrayInt::New(); + DataArrayDouble* d2=DataArrayDouble::New(); + mesh2d->resizeForUnserialization(tinyInfo, d1, d2, littleStrings); + CPPUNIT_ASSERT_EQUAL(0,d1->getNumberOfTuples()); + CPPUNIT_ASSERT_EQUAL(8,d2->getNumberOfTuples()); + + partMesh1->decrRef(); + partMesh2->decrRef(); + partMesh3->decrRef(); + mesh2d->decrRef(); + arr1->decrRef(); + arr2->decrRef(); + f1->decrRef(); + d1->decrRef(); + d2->decrRef(); + coordsX1->decrRef(); + coordsY1->decrRef(); + coordsZ1->decrRef(); + mesh1->decrRef(); +} + +void MEDCouplingBasicsTest1::testScale() +{ + MEDCouplingUMesh *mesh=build2DTargetMesh_1(); + const double pos[2]={0.2,0.2}; + mesh->scale(pos,0.5); + const double expected1[18]={-0.05,-0.05, 0.2,-0.05, 0.45,-0.05, -0.05,0.2, 0.2,0.2, 0.45,0.2, + -0.05,0.45, 0.2,0.45, 0.45,0.45}; + const double *val=mesh->getCoords()->getConstPointer(); + for(int i=0;i<18;i++) + CPPUNIT_ASSERT_DOUBLES_EQUAL(expected1[i],val[i],1e-12); + // + mesh->decrRef(); +} + +void MEDCouplingBasicsTest1::testTryToShareSameCoords() +{ + MEDCouplingUMesh *m1=build2DTargetMesh_1(); + MEDCouplingUMesh *m2=build2DTargetMesh_1(); + CPPUNIT_ASSERT(m1->getCoords()!=m2->getCoords()); + m1->tryToShareSameCoords(*m2,1e-12); + CPPUNIT_ASSERT(m1->getCoords()==m2->getCoords()); + m1->tryToShareSameCoords(*m2,1e-12); + CPPUNIT_ASSERT(m1->getCoords()==m2->getCoords()); + m2->tryToShareSameCoords(*m1,1e-12); + CPPUNIT_ASSERT(m1->getCoords()==m2->getCoords()); + m1->decrRef(); + m2->decrRef(); + // + m1=build2DTargetMesh_1(); + m2=build2DTargetMesh_2(); + CPPUNIT_ASSERT(m1->getCoords()!=m2->getCoords()); + m1->tryToShareSameCoords(*m2,1e-12); + CPPUNIT_ASSERT(m1->getCoords()==m2->getCoords()); + m1->tryToShareSameCoords(*m2,1e-12); + CPPUNIT_ASSERT(m1->getCoords()==m2->getCoords()); + m2->tryToShareSameCoords(*m1,1e-12); + CPPUNIT_ASSERT(m1->getCoords()==m2->getCoords()); + m1->decrRef(); + m2->decrRef(); + // + m1=build2DTargetMesh_1(); + m2=build2DSourceMesh_1(); + CPPUNIT_ASSERT(m1->getCoords()!=m2->getCoords()); + CPPUNIT_ASSERT_THROW(m1->tryToShareSameCoords(*m2,1e-12),INTERP_KERNEL::Exception); + m1->decrRef(); + m2->decrRef(); +} + +void MEDCouplingBasicsTest1::testFindNodeOnPlane() +{ + MEDCouplingUMesh *mesh=build3DTargetMesh_1(); + std::vector<int> n; + double pt[3]={300.,300.,0.}; + double v[3]={0.,0.,2.}; + mesh->findNodesOnPlane(pt,v,1e-12,n); + CPPUNIT_ASSERT_EQUAL(9,(int)n.size()); + MEDCouplingUMesh *m3dSurf=(MEDCouplingUMesh *)mesh->buildFacePartOfMySelfNode(&n[0],&n[0]+n.size(),true); + MEDCouplingExtrudedMesh *me=MEDCouplingExtrudedMesh::New(mesh,m3dSurf,0); + const DataArrayInt *da=me->getMesh3DIds(); + CPPUNIT_ASSERT_EQUAL(8,me->getNumberOfCells()); + const int expected[8]={0,1,2,3,4,5,6,7}; + const int *val=da->getConstPointer(); + for(int i=0;i<8;i++) + CPPUNIT_ASSERT_EQUAL(expected[i],val[i]); + me->decrRef(); + m3dSurf->decrRef(); + mesh->decrRef(); +} + +void MEDCouplingBasicsTest1::testRenumberCells() +{ + MEDCouplingUMesh *m=build3DSurfTargetMesh_1(); + MEDCouplingUMesh *m2=build3DSurfTargetMesh_1(); + CPPUNIT_ASSERT(m->isEqual(m2,0)); + const int arr[5]={12,3,25,2,26}; + m->renumberCells(arr,true); + CPPUNIT_ASSERT(!m->isEqual(m2,0)); + CPPUNIT_ASSERT_EQUAL(INTERP_KERNEL::NORM_QUAD4,m->getTypeOfCell(0)); + CPPUNIT_ASSERT_EQUAL(INTERP_KERNEL::NORM_TRI3,m->getTypeOfCell(1)); + CPPUNIT_ASSERT_EQUAL(INTERP_KERNEL::NORM_QUAD4,m->getTypeOfCell(2)); + CPPUNIT_ASSERT_EQUAL(INTERP_KERNEL::NORM_TRI3,m->getTypeOfCell(3)); + CPPUNIT_ASSERT_EQUAL(INTERP_KERNEL::NORM_QUAD4,m->getTypeOfCell(4)); + const int arr2[5]={5,-1,-5,4,8}; + m->renumberCells(arr2,true); + CPPUNIT_ASSERT(m->isEqual(m2,0)); + m->decrRef(); + m2->decrRef(); +} + +void MEDCouplingBasicsTest1::testChangeSpaceDimension() +{ + MEDCouplingUMesh *m1=build3DSurfTargetMesh_1(); + MEDCouplingUMesh *m2=build2DTargetMesh_1(); + // + CPPUNIT_ASSERT_EQUAL(3,m1->getSpaceDimension()); + m1->changeSpaceDimension(2); + CPPUNIT_ASSERT_EQUAL(2,m1->getSpaceDimension()); + m1->setName(m2->getName().c_str()); + CPPUNIT_ASSERT(m1->isEqual(m2,1e-12)); + m1->changeSpaceDimension(3); + CPPUNIT_ASSERT_EQUAL(3,m1->getSpaceDimension()); + const double expected[27]={-0.3,-0.3,0., 0.2,-0.3,0., 0.7,-0.3,0., -0.3,0.2,0., 0.2,0.2,0., 0.7,0.2,0., -0.3,0.7,0., 0.2,0.7,0., 0.7,0.7,0.}; + const double *val=m1->getCoords()->getConstPointer(); + for(int i=0;i<27;i++) + CPPUNIT_ASSERT_DOUBLES_EQUAL(expected[i],val[i],1e-14); + // + m1->decrRef(); + m2->decrRef(); +} + +void MEDCouplingBasicsTest1::testSetConnectivity() +{ + MEDCouplingUMesh *m1 = build1DTargetMesh_1(); + + DataArrayInt * conn = DataArrayInt::New(); + DataArrayInt * connI = DataArrayInt::New(); + m1->setConnectivity(conn, connI, true); // was SEG-Faulting with empty arrays + conn->decrRef(); + connI->decrRef(); + m1->decrRef(); +} diff --git a/src/medtool/src/MEDCoupling/Test/MEDCouplingBasicsTest1.hxx b/src/medtool/src/MEDCoupling/Test/MEDCouplingBasicsTest1.hxx new file mode 100644 index 000000000..8372492b7 --- /dev/null +++ b/src/medtool/src/MEDCoupling/Test/MEDCouplingBasicsTest1.hxx @@ -0,0 +1,156 @@ +// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 +// 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 __MEDCOUPLINGBASICSTEST1_HXX__ +#define __MEDCOUPLINGBASICSTEST1_HXX__ + +#include "MEDCouplingBasicsTest.hxx" + +#include <map> +#include <vector> + +namespace ParaMEDMEM +{ + class DataArrayDouble; + class MEDCouplingUMesh; + class MEDCouplingFieldDouble; + class MEDCouplingMultiFields; + + class MEDCouplingBasicsTest1 : public MEDCouplingBasicsTest + { + CPPUNIT_TEST_SUITE(MEDCouplingBasicsTest1); + CPPUNIT_TEST( testArray ); + CPPUNIT_TEST( testArray2 ); + CPPUNIT_TEST( testArray3 ); + CPPUNIT_TEST( testMesh ); + CPPUNIT_TEST( testMeshPointsCloud ); + CPPUNIT_TEST( testMeshM1D ); + CPPUNIT_TEST( testDeepCopy ); + CPPUNIT_TEST( testRevNodal ); + CPPUNIT_TEST( testConvertToPolyTypes ); + CPPUNIT_TEST( testDescConn2D ); + CPPUNIT_TEST( testDescConn3D ); + CPPUNIT_TEST( testFindBoundaryNodes ); + CPPUNIT_TEST( testBoundaryMesh ); + CPPUNIT_TEST( testBuildPartOfMySelf ); + CPPUNIT_TEST( testBuildPartOfMySelfNode ); + CPPUNIT_TEST( testZipCoords ); + CPPUNIT_TEST( testZipConnectivity ); + CPPUNIT_TEST( testEqualMesh ); + CPPUNIT_TEST( testEqualFieldDouble ); + CPPUNIT_TEST( testNatureChecking ); + CPPUNIT_TEST( testBuildSubMeshData ); + CPPUNIT_TEST( testExtrudedMesh1 ); + CPPUNIT_TEST( testExtrudedMesh2 ); + CPPUNIT_TEST( testExtrudedMesh3 ); + CPPUNIT_TEST( testExtrudedMesh4 ); + CPPUNIT_TEST( testFindCommonNodes ); + CPPUNIT_TEST( testCheckButterflyCells ); + CPPUNIT_TEST( testMergeMesh1 ); + CPPUNIT_TEST( testMergeMeshOnSameCoords1 ); + CPPUNIT_TEST( testMergeField1 ); + CPPUNIT_TEST( testFillFromAnalytic ); + CPPUNIT_TEST( testFillFromAnalytic2 ); + CPPUNIT_TEST( testApplyFunc ); + CPPUNIT_TEST( testApplyFunc2 ); + CPPUNIT_TEST( testOperationsOnFields ); + CPPUNIT_TEST( testOperationsOnFields2 ); + CPPUNIT_TEST( testOperationsOnFields3 ); + CPPUNIT_TEST( testOperationsOnFields4 ); + CPPUNIT_TEST( testMergeNodesOnField ); + CPPUNIT_TEST( testCheckConsecutiveCellTypes ); + CPPUNIT_TEST( testRearrange2ConsecutiveCellTypes ); + CPPUNIT_TEST( testSplitByType ); + CPPUNIT_TEST( testFuseUMeshesOnSameCoords ); + CPPUNIT_TEST( testFuseUMeshesOnSameCoords2 ); + CPPUNIT_TEST( testBuildOrthogonalField ); + CPPUNIT_TEST( testGetCellsContainingPoint ); + CPPUNIT_TEST( testGetValueOn1 ); + CPPUNIT_TEST( testCMesh0 ); + CPPUNIT_TEST( testCMesh1 ); + CPPUNIT_TEST( testCMesh2 ); + CPPUNIT_TEST( testScale ); + CPPUNIT_TEST( testTryToShareSameCoords ); + CPPUNIT_TEST( testFindNodeOnPlane ); + CPPUNIT_TEST( testRenumberCells ); + CPPUNIT_TEST( testChangeSpaceDimension ); + CPPUNIT_TEST( testSetConnectivity ); + CPPUNIT_TEST_SUITE_END(); + public: + void testArray(); + void testArray2(); + void testArray3(); + void testMesh(); + void testMeshPointsCloud(); + void testMeshM1D(); + void testDeepCopy(); + void testRevNodal(); + void testConvertToPolyTypes(); + void testDescConn2D(); + void testDescConn3D(); + void testFindBoundaryNodes(); + void testBoundaryMesh(); + void testBuildPartOfMySelf(); + void testBuildPartOfMySelfNode(); + void testZipCoords(); + void testZipConnectivity(); + void testEqualMesh(); + void testEqualFieldDouble(); + void testNatureChecking(); + void testBuildSubMeshData(); + void testExtrudedMesh1(); + void testExtrudedMesh2(); + void testExtrudedMesh3(); + void testExtrudedMesh4(); + void testFindCommonNodes(); + void testCheckButterflyCells(); + void testMergeMesh1(); + void testMergeMeshOnSameCoords1(); + void testMergeField1(); + void testFillFromAnalytic(); + void testFillFromAnalytic2(); + void testApplyFunc(); + void testApplyFunc2(); + void testOperationsOnFields(); + void testOperationsOnFields2(); + void testOperationsOnFields3(); + void testOperationsOnFields4(); + void testMergeNodesOnField(); + void testCheckConsecutiveCellTypes(); + void testRearrange2ConsecutiveCellTypes(); + void testSplitByType(); + void testFuseUMeshesOnSameCoords(); + void testFuseUMeshesOnSameCoords2(); + void testBuildOrthogonalField(); + void testGetCellsContainingPoint(); + void testGetValueOn1(); + void testCMesh0(); + void testCMesh1(); + void testCMesh2(); + void testScale(); + void testTryToShareSameCoords(); + void testFindNodeOnPlane(); + void testRenumberCells(); + void testChangeSpaceDimension(); + void testSetConnectivity(); + }; +} + +#endif diff --git a/src/medtool/src/MEDCoupling/Test/MEDCouplingBasicsTest2.cxx b/src/medtool/src/MEDCoupling/Test/MEDCouplingBasicsTest2.cxx new file mode 100644 index 000000000..4e52b0046 --- /dev/null +++ b/src/medtool/src/MEDCoupling/Test/MEDCouplingBasicsTest2.cxx @@ -0,0 +1,2277 @@ +// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 +// 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 "MEDCouplingBasicsTest2.hxx" +#include "MEDCouplingUMesh.hxx" +#include "MEDCouplingCMesh.hxx" +#include "MEDCouplingExtrudedMesh.hxx" +#include "MEDCouplingFieldDouble.hxx" +#include "MEDCouplingMemArray.hxx" +#include "MEDCouplingGaussLocalization.hxx" + +#include <cmath> +#include <algorithm> +#include <functional> +#include <iterator> + +using namespace ParaMEDMEM; + +void MEDCouplingBasicsTest2::testGaussPointField1() +{ + const double _a=0.446948490915965; + const double _b=0.091576213509771; + const double _p1=0.11169079483905; + const double _p2=0.0549758718227661; + const double refCoo1[6]={ 0.,0., 1.,0., 0.,1. }; + const double gsCoo1[12]={ 2*_b-1, 1-4*_b, 2*_b-1, 2.07*_b-1, 1-4*_b, + 2*_b-1, 1-4*_a, 2*_a-1, 2*_a-1, 1-4*_a, 2*_a-1, 2*_a-1 }; + const double wg1[6]={ 4*_p2, 4*_p2, 4*_p2, 4*_p1, 4*_p1, 4*_p1 }; + std::vector<double> _refCoo1(refCoo1,refCoo1+6); + std::vector<double> _gsCoo1(gsCoo1,gsCoo1+12); + std::vector<double> _wg1(wg1,wg1+6); + // + MEDCouplingUMesh *m=build2DTargetMesh_1(); + MEDCouplingFieldDouble *f=MEDCouplingFieldDouble::New(ON_GAUSS_PT,NO_TIME); + CPPUNIT_ASSERT_THROW(f->getNumberOfTuples(), INTERP_KERNEL::Exception); // Sanity check! + f->setMesh(m); + CPPUNIT_ASSERT_EQUAL(5,f->getNumberOfMeshPlacesExpected()); + CPPUNIT_ASSERT_EQUAL(0,f->getNbOfGaussLocalization()); + f->setGaussLocalizationOnType(INTERP_KERNEL::NORM_TRI3,_refCoo1,_gsCoo1,_wg1); + f->setGaussLocalizationOnType(INTERP_KERNEL::NORM_TRI3,_refCoo1,_gsCoo1,_wg1); // not a bug only to check that it works well + CPPUNIT_ASSERT_THROW(f->setGaussLocalizationOnType(INTERP_KERNEL::NORM_QUAD4,_refCoo1,_gsCoo1,_wg1),INTERP_KERNEL::Exception); + CPPUNIT_ASSERT_EQUAL(1,f->getNbOfGaussLocalization()); + const double refCoo2[8]={ 0.,0., 1.,0., 1.,1., 0.,1. }; + std::vector<double> _refCoo2(refCoo2,refCoo2+8); + _gsCoo1.resize(4); _wg1.resize(2); + f->setGaussLocalizationOnType(INTERP_KERNEL::NORM_QUAD4,_refCoo2,_gsCoo1,_wg1); + CPPUNIT_ASSERT_EQUAL(2,f->getNbOfGaussLocalization()); + DataArrayDouble *array=DataArrayDouble::New(); + array->alloc(18,2); + double *ptr=array->getPointer(); + for(int i=0;i<18*2;i++) + ptr[i]=(double)(i+1); + f->setArray(array); + f->setName("MyFirstFieldOnGaussPoint"); + array->decrRef(); + f->checkCoherency(); + CPPUNIT_ASSERT_DOUBLES_EQUAL(27.,f->getIJK(2,5,0),1e-14); + CPPUNIT_ASSERT_DOUBLES_EQUAL(16.,f->getIJK(1,5,1),1e-14); + // + f->clearGaussLocalizations(); + CPPUNIT_ASSERT_EQUAL(0,f->getNbOfGaussLocalization()); + CPPUNIT_ASSERT_THROW(f->checkCoherency(),INTERP_KERNEL::Exception); + int ids1[4]={0,1,3,4}; + CPPUNIT_ASSERT_THROW(f->setGaussLocalizationOnCells(ids1,ids1+4,_refCoo2,_gsCoo1,_wg1),INTERP_KERNEL::Exception); + CPPUNIT_ASSERT_EQUAL(0,f->getNbOfGaussLocalization()); + int ids2[2]={0,4}; + f->setGaussLocalizationOnCells(ids2,ids2+2,_refCoo2,_gsCoo1,_wg1); + CPPUNIT_ASSERT_EQUAL(1,f->getNbOfGaussLocalization()); + CPPUNIT_ASSERT_EQUAL(0,f->getGaussLocalizationIdOfOneCell(0)); + CPPUNIT_ASSERT_THROW(f->getGaussLocalizationIdOfOneCell(1),INTERP_KERNEL::Exception); + int ids3[2]={1,2}; + f->setGaussLocalizationOnCells(ids3,ids3+2,_refCoo1,_gsCoo1,_wg1); + CPPUNIT_ASSERT_EQUAL(2,f->getNbOfGaussLocalization()); + CPPUNIT_ASSERT_EQUAL(0,f->getGaussLocalizationIdOfOneCell(0)); + CPPUNIT_ASSERT_EQUAL(1,f->getGaussLocalizationIdOfOneCell(1)); + CPPUNIT_ASSERT_EQUAL(1,f->getGaussLocalizationIdOfOneCell(2)); + CPPUNIT_ASSERT_THROW(f->checkCoherency(),INTERP_KERNEL::Exception);//<- cell 3 has no localization + int ids4[1]={3}; + std::vector<double> _gsCoo2(_gsCoo1); + std::vector<double> _wg2(_wg1); + _gsCoo2[0]=0.8888777776666; _wg2[0]=0.1234567892377; + f->setGaussLocalizationOnCells(ids4,ids4+1,_refCoo2,_gsCoo2,_wg2); + CPPUNIT_ASSERT_EQUAL(3,f->getNbOfGaussLocalization()); + std::vector<int> tmpIds; + f->getCellIdsHavingGaussLocalization(0,tmpIds); + CPPUNIT_ASSERT_EQUAL(2,(int)tmpIds.size()); + CPPUNIT_ASSERT(std::equal(ids2,ids2+2,tmpIds.begin())); + CPPUNIT_ASSERT_THROW(f->checkCoherency(),INTERP_KERNEL::Exception);//<- it's always not ok because undelying array not with the good size. + DataArrayDouble *array2=f->getArray()->substr(0,10); + f->setArray(array2); + array2->decrRef(); + f->checkCoherency();//<- here it is OK + MEDCouplingFieldDouble *f2=f->clone(true); + CPPUNIT_ASSERT(f->isEqual(f2,1e-14,1e-14)); + MEDCouplingGaussLocalization& gl1=f2->getGaussLocalization(0); + double tmp=gl1.getGaussCoord(1,1); + CPPUNIT_ASSERT_DOUBLES_EQUAL(2.07*_b-1,tmp,1e-14); + gl1.setGaussCoord(1,1,0.07); + CPPUNIT_ASSERT(!f->isEqual(f2,1e-14,1e-14)); + gl1.setGaussCoord(1,1,tmp); + CPPUNIT_ASSERT(f->isEqual(f2,1e-14,1e-14)); + f->decrRef(); + f2->checkCoherency(); + // + f2->decrRef(); + m->decrRef(); +} + +void MEDCouplingBasicsTest2::testGaussPointNEField1() +{ + MEDCouplingUMesh *m=build2DTargetMesh_1(); + MEDCouplingFieldDouble *f=MEDCouplingFieldDouble::New(ON_GAUSS_NE,NO_TIME); + f->setMesh(m); + CPPUNIT_ASSERT_EQUAL(5,f->getNumberOfMeshPlacesExpected()); + f->setName("MyFirstFieldOnNE"); + f->setDescription("MyDescriptionNE"); + DataArrayDouble *array=DataArrayDouble::New(); + array->alloc(18,2); + double *ptr=array->getPointer(); + for(int i=0;i<18*2;i++) + ptr[i]=(double)(i+7); + f->setArray(array); + array->decrRef(); + // + f->checkCoherency(); + MEDCouplingFieldDouble *f2=f->clone(true); + CPPUNIT_ASSERT(f->isEqual(f2,1e-14,1e-14)); + CPPUNIT_ASSERT_DOUBLES_EQUAL(21.,f->getIJK(2,0,0),1e-14); + CPPUNIT_ASSERT_DOUBLES_EQUAL(18.,f->getIJK(1,1,1),1e-14); + f2->decrRef(); + // + f->decrRef(); + m->decrRef(); +} + +void MEDCouplingBasicsTest2::testCellOrientation1() +{ + MEDCouplingUMesh *m=build2DTargetMesh_1(); + double vec[3]={0.,0.,-1.}; + std::vector<int> res1; + CPPUNIT_ASSERT_THROW(m->are2DCellsNotCorrectlyOriented(vec,false,res1),INTERP_KERNEL::Exception); + m->changeSpaceDimension(3); + res1.clear(); + m->are2DCellsNotCorrectlyOriented(vec,false,res1); + CPPUNIT_ASSERT(res1.empty()); + vec[2]=1; + m->are2DCellsNotCorrectlyOriented(vec,false,res1); + CPPUNIT_ASSERT_EQUAL(5,(int)res1.size()); + res1.clear(); + // + vec[2]=-1.; + // connectivity inversion + int *conn=m->getNodalConnectivity()->getPointer(); + int tmp=conn[11]; + conn[11]=conn[12]; + conn[12]=tmp; + m->are2DCellsNotCorrectlyOriented(vec,false,res1); + CPPUNIT_ASSERT_EQUAL(1,(int)res1.size()); + CPPUNIT_ASSERT_EQUAL(2,res1[0]); + res1.clear(); + m->orientCorrectly2DCells(vec,false); + m->are2DCellsNotCorrectlyOriented(vec,false,res1); + CPPUNIT_ASSERT(res1.empty()); + MEDCouplingUMesh *m2=build2DTargetMesh_1(); + m2->changeSpaceDimension(3); + CPPUNIT_ASSERT(m->isEqual(m2,1e-12)); + m2->decrRef(); + // + m->decrRef(); +} + +void MEDCouplingBasicsTest2::testCellOrientation2() +{ + MEDCouplingUMesh *m1=0; + MEDCouplingUMesh *m2=build3DExtrudedUMesh_1(m1); + m1->decrRef(); + std::vector<int> res1; + m2->arePolyhedronsNotCorrectlyOriented(res1); + CPPUNIT_ASSERT_EQUAL(6,(int)res1.size()); + m2->orientCorrectlyPolyhedrons(); + res1.clear(); + m2->arePolyhedronsNotCorrectlyOriented(res1); + CPPUNIT_ASSERT(res1.empty()); + m2->checkCoherency(); + CPPUNIT_ASSERT_EQUAL(18,m2->getNumberOfCells()); + int cellIds[3]={0,6,12}; + std::vector<int> cellIds2(cellIds,cellIds+3); + m2->convertToPolyTypes(&cellIds2[0],&cellIds2[0]+cellIds2.size()); + m2->orientCorrectlyPolyhedrons(); + res1.clear(); + m2->arePolyhedronsNotCorrectlyOriented(res1); + CPPUNIT_ASSERT(res1.empty()); + MEDCouplingFieldDouble *f2=m2->getMeasureField(false); + //Test to check global reverse in MEDCouplingUMesh::tryToCorrectPolyhedronOrientation + MEDCouplingUMesh *m3=build2DTargetMesh_1(); + double vec[3]={0.,0.,1.}; + m3->changeSpaceDimension(3); + const int ids1[5]={0,1,2,3,4}; + std::vector<int> ids2(ids1,ids1+5); + m3->convertToPolyTypes(&ids2[0],&ids2[0]+ids2.size()); + m3->orientCorrectly2DCells(vec,false); + MEDCouplingUMesh *m4=buildCU1DMesh_U(); + m4->changeSpaceDimension(3); + double center[3]={0.,0.,0.}; + double vector[3]={0.,1.,0.}; + m4->rotate(center,vector,-M_PI/2.); + MEDCouplingUMesh *m5=m3->buildExtrudedMesh(m4,0); + res1.clear(); + m5->arePolyhedronsNotCorrectlyOriented(res1); + CPPUNIT_ASSERT_EQUAL(15,(int)res1.size()); + m5->orientCorrectlyPolyhedrons(); + res1.clear(); + m5->arePolyhedronsNotCorrectlyOriented(res1); + CPPUNIT_ASSERT(res1.empty()); + MEDCouplingFieldDouble *f3=m5->getMeasureField(false); + CPPUNIT_ASSERT_EQUAL(15,f3->getArray()->getNumberOfTuples()); + CPPUNIT_ASSERT_EQUAL(1,f3->getNumberOfComponents()); + const double *f3Ptr=f3->getArray()->getConstPointer(); + const double expected1[15]={ + 0.075,0.0375,0.0375,0.075,0.075, + 0.1125,0.05625,0.05625,0.1125,0.1125, + 0.0625,0.03125,0.03125,0.0625,0.0625 + }; + for(int i=0;i<15;i++) + CPPUNIT_ASSERT_DOUBLES_EQUAL(std::abs(expected1[i]),f3Ptr[i],1e-12); + f3->decrRef(); + DataArrayDouble *f4=m5->getBarycenterAndOwner(); + CPPUNIT_ASSERT_EQUAL(15,f4->getNumberOfTuples()); + CPPUNIT_ASSERT_EQUAL(3,f4->getNumberOfComponents()); + const double *f4Ptr=f4->getConstPointer(); + const double expected2[45]={ + -0.05,-0.05,0.15, 0.3666666666666667,-0.13333333333333333,0.15, 0.53333333333333333,0.033333333333333333,0.15, -0.05,0.45,0.15, 0.45,0.45,0.15, + -0.05,-0.05,0.525, 0.3666666666666667,-0.13333333333333333,0.525, 0.53333333333333333,0.033333333333333333,0.525, -0.05,0.45,0.525, 0.45,0.45,0.525, + -0.05,-0.05,0.875, 0.3666666666666667,-0.13333333333333333,0.875, 0.53333333333333333,0.033333333333333333,0.875, -0.05,0.45,0.875, 0.45,0.45,0.875 + }; + for(int i=0;i<45;i++) + CPPUNIT_ASSERT_DOUBLES_EQUAL(expected2[i],f4Ptr[i],1e-12); + f4->decrRef(); + m5->decrRef(); + m3->decrRef(); + m4->decrRef(); + // + f2->decrRef(); + m2->decrRef(); +} + +void MEDCouplingBasicsTest2::testCellOrientation3() +{ + MEDCouplingUMesh *m = MEDCouplingUMesh::New("circle", 2); + + double coords[8]={ 0.,0., 0.,0., 0.,0., 0.,0.}; + coords[0] = cos(-M_PI/4.0); coords[1] = sin(-M_PI/4.0); + coords[2] = cos(3*M_PI/4.0); coords[3] = sin(3*M_PI/4.0); + coords[4] = cos(5*M_PI/4.0); coords[5] = sin(5*M_PI/4.0); + coords[6] = cos(M_PI/4.0); coords[7] = sin(M_PI/4.0); + + int conn[4]= { 0,1,2,3 }; + double vec[3]={0.,0.,-1.}; + m->allocateCells(1); + m->insertNextCell(INTERP_KERNEL::NORM_QPOLYG,4,conn); + m->finishInsertingCells(); + DataArrayDouble *myCoords=DataArrayDouble::New(); + myCoords->alloc(4,2); + std::copy(coords,coords+8,myCoords->getPointer()); + m->setCoords(myCoords); + myCoords->decrRef(); + m->changeSpaceDimension(3); + + std::vector<int> res1; + m->are2DCellsNotCorrectlyOriented(vec,false,res1); + CPPUNIT_ASSERT(res1.empty()); + vec[2] = 1.0; + res1.clear(); + m->are2DCellsNotCorrectlyOriented(vec,false,res1); + CPPUNIT_ASSERT_EQUAL(1,(int)res1.size()); + m->decrRef(); +} + +/*! + * This test check polyhedron true barycenter computation. + */ +void MEDCouplingBasicsTest2::testPolyhedronBarycenter() +{ + int connN[]={0,3,2,1, -1, 4,5,6,7, -1, 0,4,7,3, -1, 3,7,6,2, -1, 2,6,5,1, -1, 1,5,4,0}; + double coords[]={0.,0.,0., 1.,0.,0., 1.,1.,0., 0.,1.,0., 0.,0.,1., 1.,0.,1., 1.,1.,1., 0.,1.,1., 0.5, 0.5, 0.5}; + MEDCouplingUMesh *meshN=MEDCouplingUMesh::New(); + meshN->setName("ForBary"); + meshN->setMeshDimension(3); + meshN->allocateCells(4); + meshN->insertNextCell(INTERP_KERNEL::NORM_POLYHED,29,connN); + meshN->finishInsertingCells(); + DataArrayDouble *myCoords=DataArrayDouble::New(); + myCoords->alloc(9,3); + std::copy(coords,coords+27,myCoords->getPointer()); + meshN->setCoords(myCoords); + myCoords->decrRef(); + meshN->checkCoherency(); + // + std::vector<int> res1; + meshN->arePolyhedronsNotCorrectlyOriented(res1); + meshN->orientCorrectlyPolyhedrons(); + CPPUNIT_ASSERT(res1.empty()); + const double *ref,*daPtr; + DataArrayDouble *da=meshN->getBarycenterAndOwner(); + CPPUNIT_ASSERT_EQUAL(1,da->getNumberOfTuples()); + CPPUNIT_ASSERT_EQUAL(3,da->getNumberOfComponents()); + daPtr=da->getConstPointer(); + ref=meshN->getCoords()->getConstPointer()+24; + for(int i=0;i<3;i++) + CPPUNIT_ASSERT_DOUBLES_EQUAL(ref[i],daPtr[i],1e-12); + da->decrRef(); + // + const double center[]={0.,0.,0.}; + const double vec[]={0.,2.78,0.}; + da=meshN->getBarycenterAndOwner(); + daPtr=da->getConstPointer(); + ref=meshN->getCoords()->getConstPointer()+24; + for(int i=0;i<3;i++) + CPPUNIT_ASSERT_DOUBLES_EQUAL(ref[i],daPtr[i],1e-12); + da->decrRef(); + // + meshN->rotate(center,vec,M_PI/7.); + meshN->translate(vec); + da=meshN->getBarycenterAndOwner(); + daPtr=da->getConstPointer(); + ref=meshN->getCoords()->getConstPointer()+24; + for(int i=0;i<3;i++) + CPPUNIT_ASSERT_DOUBLES_EQUAL(ref[i],daPtr[i],1e-12); + da->decrRef(); + // + const double center2[]={1.12,3.45,6.78}; + const double vec2[]={4.5,9.3,2.8}; + meshN->rotate(center2,vec2,M_E); + meshN->translate(vec2); + da=meshN->getBarycenterAndOwner(); + daPtr=da->getConstPointer(); + ref=meshN->getCoords()->getConstPointer()+24; + for(int i=0;i<3;i++) + CPPUNIT_ASSERT_DOUBLES_EQUAL(ref[i],daPtr[i],1e-10); + da->decrRef(); + // + meshN->decrRef(); +} + +void MEDCouplingBasicsTest2::testNormL12Integ1D() +{ + MEDCouplingUMesh *m1=build1DTargetMesh_3(); + MEDCouplingFieldDouble *f1=MEDCouplingFieldDouble::New(ON_CELLS,NO_TIME); + f1->setMesh(m1); + DataArrayDouble *array=DataArrayDouble::New(); + array->alloc(m1->getNumberOfCells(),3); + const double arr[12]={-5.23,15.45,-25.56,6.67,-16.78,26.89,-7.91,17.23,-27.43,8.21,-18.63,28.72}; + std::copy(arr,arr+12,array->getPointer()); + f1->setArray(array); + array->decrRef(); + // + const double *ptr; + DataArrayDouble *f3=m1->getBarycenterAndOwner(); + CPPUNIT_ASSERT_EQUAL(4,f3->getNumberOfTuples()); + CPPUNIT_ASSERT_EQUAL(1,f3->getNumberOfComponents()); + double expected9[4]={0.75,5.105,0.8,5.155}; + ptr=f3->getConstPointer(); + for(int i=0;i<4;i++) + CPPUNIT_ASSERT_DOUBLES_EQUAL(expected9[i],ptr[i],1e-12); + f3->decrRef(); + // + MEDCouplingFieldDouble *f2=m1->getMeasureField(false); + CPPUNIT_ASSERT_EQUAL(4,f2->getArray()->getNumberOfTuples()); + CPPUNIT_ASSERT_EQUAL(1,f2->getNumberOfComponents()); + double expected1[4]={0.5,0.21,-0.6,-0.31}; + ptr=f2->getArray()->getConstPointer(); + for(int i=0;i<4;i++) + CPPUNIT_ASSERT_DOUBLES_EQUAL(expected1[i],ptr[i],1e-12); + f2->decrRef(); + double expected2[4]={0.5,0.21,0.6,0.31}; + f2=m1->getMeasureField(true); + ptr=f2->getArray()->getConstPointer(); + for(int i=0;i<4;i++) + CPPUNIT_ASSERT_DOUBLES_EQUAL(expected2[i],ptr[i],1e-12); + f2->decrRef(); + //integral + double res[3]; + f1->integral(false,res); + double expected3[3]={0.9866,-0.3615,0.4217}; + for(int i=0;i<3;i++) + CPPUNIT_ASSERT_DOUBLES_EQUAL(expected3[i],res[i],1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(expected3[0],f1->integral(0,false),1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(expected3[1],f1->integral(1,false),1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(expected3[2],f1->integral(2,false),1e-12); + f1->integral(true,res); + double expected4[3]={-3.4152,8.7639,-14.6879}; + for(int i=0;i<3;i++) + CPPUNIT_ASSERT_DOUBLES_EQUAL(expected4[i],res[i],1e-12); + //normL1 + f1->normL1(res); + double expected5[3]={6.979506172839505, 16.89018518518518, 27.02969135802469}; + for(int i=0;i<3;i++) + CPPUNIT_ASSERT_DOUBLES_EQUAL(expected5[i],res[i],1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(expected5[0],f1->normL1(0),1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(expected5[1],f1->normL1(1),1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(expected5[2],f1->normL1(2),1e-12); + //normL2 + f1->normL2(res); + double expected7[3]={7.090910979452395, 16.9275542960123, 27.053271464160858}; + for(int i=0;i<3;i++) + CPPUNIT_ASSERT_DOUBLES_EQUAL(expected7[i],res[i],1e-9); + CPPUNIT_ASSERT_DOUBLES_EQUAL(expected7[0],f1->normL2(0),1e-9); + CPPUNIT_ASSERT_DOUBLES_EQUAL(expected7[1],f1->normL2(1),1e-9); + CPPUNIT_ASSERT_DOUBLES_EQUAL(expected7[2],f1->normL2(2),1e-9); + //buildMeasureField + MEDCouplingFieldDouble *f4=f1->buildMeasureField(false); + CPPUNIT_ASSERT_DOUBLES_EQUAL(-0.2,f4->accumulate(0),1e-12); + f4->decrRef(); + f4=f1->buildMeasureField(true); + CPPUNIT_ASSERT_DOUBLES_EQUAL(1.62,f4->accumulate(0),1e-12); + f4->decrRef(); + // + f1->decrRef(); + m1->decrRef(); + // Testing with 2D Curve + m1=build2DCurveTargetMesh_3(); + f2=m1->getMeasureField(false); + CPPUNIT_ASSERT_EQUAL(4,f2->getArray()->getNumberOfTuples()); + CPPUNIT_ASSERT_EQUAL(1,f2->getNumberOfComponents()); + ptr=f2->getArray()->getConstPointer(); + for(int i=0;i<4;i++) + CPPUNIT_ASSERT_DOUBLES_EQUAL(sqrt(2.)*expected2[i],ptr[i],1e-12); + f2->decrRef(); + f2=m1->getMeasureField(true); + CPPUNIT_ASSERT_EQUAL(4,f2->getArray()->getNumberOfTuples()); + CPPUNIT_ASSERT_EQUAL(1,f2->getNumberOfComponents()); + ptr=f2->getArray()->getConstPointer(); + for(int i=0;i<4;i++) + CPPUNIT_ASSERT_DOUBLES_EQUAL(expected2[i]*sqrt(2.),ptr[i],1e-12); + f2->decrRef(); + //bary + f3=m1->getBarycenterAndOwner(); + CPPUNIT_ASSERT_EQUAL(4,f3->getNumberOfTuples()); + CPPUNIT_ASSERT_EQUAL(2,f3->getNumberOfComponents()); + double expected10[8]={0.75,0.75,5.105,5.105,0.8,0.8,5.155,5.155}; + ptr=f3->getConstPointer(); + for(int i=0;i<8;i++) + CPPUNIT_ASSERT_DOUBLES_EQUAL(expected10[i],ptr[i],1e-12); + f3->decrRef(); + // + f1=MEDCouplingFieldDouble::New(ON_CELLS,NO_TIME); + f1->setMesh(m1); + array=DataArrayDouble::New(); + array->alloc(m1->getNumberOfCells(),3); + std::copy(arr,arr+12,array->getPointer()); + f1->setArray(array); + array->decrRef(); + f1->integral(false,res); + for(int i=0;i<3;i++) + CPPUNIT_ASSERT_DOUBLES_EQUAL(sqrt(2.)*expected4[i],res[i],1e-12); + f1->integral(true,res); + for(int i=0;i<3;i++) + CPPUNIT_ASSERT_DOUBLES_EQUAL(sqrt(2.)*expected4[i],res[i],1e-12); + f1->normL1(res); + for(int i=0;i<3;i++) + CPPUNIT_ASSERT_DOUBLES_EQUAL(expected5[i],res[i],1e-12); + f1->normL2(res); + for(int i=0;i<3;i++) + CPPUNIT_ASSERT_DOUBLES_EQUAL(expected7[i],res[i],1e-12); + // + f1->decrRef(); + m1->decrRef(); +} + +void MEDCouplingBasicsTest2::testAreaBary2D() +{ + MEDCouplingUMesh *m1=build2DTargetMesh_3(); + MEDCouplingFieldDouble *f1=m1->getMeasureField(false); + CPPUNIT_ASSERT_EQUAL(10,f1->getArray()->getNumberOfTuples()); + CPPUNIT_ASSERT_EQUAL(1,f1->getNumberOfComponents()); + double expected1[10]={-0.5,-1,-1.5,-0.5,-1, 0.5,1,1.5,0.5,1}; + const double *ptr=f1->getArray()->getConstPointer(); + for(int i=0;i<10;i++) + CPPUNIT_ASSERT_DOUBLES_EQUAL(expected1[i],ptr[i],1e-12); + f1->decrRef(); + f1=m1->getMeasureField(true); + ptr=f1->getArray()->getConstPointer(); + for(int i=0;i<10;i++) + CPPUNIT_ASSERT_DOUBLES_EQUAL(std::abs(expected1[i]),ptr[i],1e-12); + f1->decrRef(); + DataArrayDouble *f2=m1->getBarycenterAndOwner(); + CPPUNIT_ASSERT_EQUAL(10,f2->getNumberOfTuples()); + CPPUNIT_ASSERT_EQUAL(2,f2->getNumberOfComponents()); + double expected2[20]={ + 0.5,0.3333333333333333,0.5,0.5,0.5,0.77777777777777777,0.5,0.3333333333333333,0.5,0.5, + 0.5,0.3333333333333333,0.5,0.5,0.5,0.77777777777777777,0.5,0.3333333333333333,0.5,0.5, + }; + ptr=f2->getConstPointer(); + for(int i=0;i<20;i++) + CPPUNIT_ASSERT_DOUBLES_EQUAL(expected2[i],ptr[i],1e-12); + f2->decrRef(); + m1->changeSpaceDimension(3); + f1=m1->getMeasureField(false); + CPPUNIT_ASSERT_EQUAL(10,f1->getArray()->getNumberOfTuples()); + CPPUNIT_ASSERT_EQUAL(1,f1->getNumberOfComponents()); + ptr=f1->getArray()->getConstPointer(); + for(int i=0;i<10;i++) + CPPUNIT_ASSERT_DOUBLES_EQUAL(std::abs(expected1[i]),ptr[i],1e-12); + f1->decrRef(); + f2=m1->getBarycenterAndOwner(); + CPPUNIT_ASSERT_EQUAL(10,f2->getNumberOfTuples()); + CPPUNIT_ASSERT_EQUAL(3,f2->getNumberOfComponents()); + ptr=f2->getConstPointer(); + double expected3[30]={ + 0.5,0.3333333333333333,0.,0.5,0.5,0.,0.5,0.77777777777777777,0.,0.5,0.3333333333333333,0.,0.5,0.5,0., + 0.5,0.3333333333333333,0.,0.5,0.5,0.,0.5,0.77777777777777777,0.,0.5,0.3333333333333333,0.,0.5,0.5,0. + }; + for(int i=0;i<30;i++) + CPPUNIT_ASSERT_DOUBLES_EQUAL(expected3[i],ptr[i],1e-12); + f2->decrRef(); + m1->decrRef(); +} + +/*! + * This test check polyhedron true barycenter computation 2. + */ +void MEDCouplingBasicsTest2::testAreaBary3D() +{ + double coords [] = { 0.241310763507 , 0.0504777305619 , 0.0682283524903 , 0.252501053866 , -0.0625176732937 , 0.137272639894 , + 0.152262663601 , 0.241816569527 , 0.133812556197 , 0.18047750211 , -0.0789949051358 , 0.339098173401 , + 0.151741971857 , 0.238885278571 , 0.137715037333 , 0.242532155481 , -0.0928169086456 , 0.0678043417367 , + 0.240941965335 , -0.015461491464 , 0.0617186345825 , 0.24127650112 , 0.0499427876717 , 0.0679634099148 , + -0.145828917428 , 0.206291632565 , 0.0310071927543 , 0.0125651775307 , 0.266262085828 , 0.105228430543 , + -0.0994066533286 , 0.233224271238 , 0.0572213839567 , -0.0951345338317 , 0.234819509426 , 0.0592126284538 , + 0.136580574205 , -0.205486212579 , 0.0572866072014 , 0.0637270784978 , -0.168886355238 , 0.446614057077 , + 0.041337157151 , -0.213402568198 , 0.372407095999 , 0.0411601970268 , -0.202387875756 , 0.411334979491 , + -0.108355701857 , 0.193636239335 , 0.204886756738 , 0.00639779029829 , 0.155296981517 , 0.252585892979 , + 0.0262473111702 , -0.112919732543 , 0.424286639249 ,-0.224103052733 , -0.139430015438 , -0.0122352295701 , + -0.0312760589481 , -0.274272003594 , 0.0323959636568 , -0.166663422532 , -0.217754445175 , 0.00392109070364 , + -0.30586619777 , -0.0475168041091 , -0.0144585228182 , -0.280881480586 , 0.135571293538 , 0.00623923647986 , + -0.25548538234 , 0.156819217766 , 0.0645277879769 , -0.131567009284 , 0.184133752309 , 0.206021802753 , + -0.196204010965 , 0.151602971681 , 0.212974777736 , -0.183713879463 , 0.0802946639531 , 0.260115662599 , + -0.244241178767 , -0.0738873389604 , 0.144590565817 , -0.155804057829 , -0.164892720025 , 0.210613950558 , + -0.170950800428 , -0.215099334026 , 0.00610122860092 , -0.30552634869 , -0.0490020791904 , -0.0132786533145 , + 0.271831011884 , 0.15105657296 , 0.0230534827908 , 0.281919192283 , 0.0898544306288 , -0.0625201489143 , + 0.260240727276 , -0.0120688706637 , -0.0532316588626 , 0.244947737722 , 0.0197984684293 , 0.0309341209233 , + 0.23439631578 , 0.229825279875 , 0.0508520585381 , 0.160921316875 , 0.265078502128 , 0.121716560626 , + -0.315088694175 , 0.0747700471918 , -0.245836615071 , -0.327728781776 , 0.0857114674649 , -0.239431905957 , + -0.308385460634 , 0.145142997084 , -0.149886828433 , 0.0488236045164 , 0.309462801914 , 0.0849169148265 , + -0.0244964803395 , 0.33145611751 , -0.0476415818061 , 0.0060567994229 , 0.32418412014 , 0.0367779543812 , + -0.0950221448063 , 0.236675326003 , 0.0572594453983 , 0.248723023186 , 0.0886648784791 , -0.176629430538 , + 0.116796984 , 0.256596599567 , -0.292863523603 , 0.118024552914 , 0.229154257843 , -0.34233232501 , + 0.217507892549 , -0.0417822335742 , -0.176771782888 , -0.224429321304 , 0.0125595300114 , -0.362064725588 , + 0.0937301100955 , -0.0500824832657 , -0.299713548444 , -0.244162220397 , 0.0383853931293 , -0.389856984411 , + -0.0281989366102 , 0.097392811563 , -0.458244577284 , -0.385010847162 , 0.10122766194 , -0.140052859922 , + -0.377936358012 , 0.110875172128 , -0.176207095463 , 0.244483045556 , -0.0991073977045 , 0.0575134372934 , + 0.262605120167 , -0.100243191645 , -0.0495620806935 , 0.240306880972 , -0.136153701579 , -0.114745281696 , + 0.215763176129 , -0.0836766059189 , -0.183249640616 , 0.237870396603 , -0.132449578286 , -0.121598854639 , + -0.0637683083097 , -0.27921020214 , -0.149112321992 , -0.0856211014977 , -0.2973233473 , -0.0446878139589 , + 0.104675342288 , -0.0625908305324 , -0.290346256534 , 0.0248264249186 , -0.247797708548 , -0.165830884019 , + 0.0719302438309 , -0.178468260473 , -0.211432157345 , 0.142871843159 , -0.208769948542 , 0.0454101128246 , + 0.167803379307 , -0.207851396623 , -0.088802726124 , 0.12868717152 , -0.230920439715 , 0.00760508389036 , + -0.0372812069535 , -0.286740286332 , 0.00963701291166 }; + + int connN [] = { /*polyhedron 0*/ + 0 , 1 , 3 , 4 , 2 , -1 , 1 , 5 , 6 , 7 , 0 , -1 , 0 , 7 , 8 , 10 , 11 , 9 , 2 , -1 , 1 , 5 , 12 , 14 , 15 , 13 , 3 , -1 , 16 , 9 , 2 , 4 , 17 , -1 + , 4 , 3 , 13 , 18 , 17 , -1 , 5 , 6 , 19 , 21 , 20 , 12 , -1 , 6 , 7 , 8 , 23 , 22 , 19 , -1 , 23 , 24 , 10 , 8 , -1 , 25 , 11 , 9 , 16 , -1 + , 24 , 26 , 25 , 11 , 10 , -1 , 12 , 14 , 20 , -1 , 27 , 28 , 29 , 15 , 13 , 18 , -1 , 14 , 15 , 29 , 30 , 21 , 20 , -1 , 26 , 27 , 18 , 17 , 16 , 25 , -1 + , 22 , 19 , 21 , 30 , 31 , -1 , 22 , 31 , 28 , 27 , 26 , 24 , 23 , -1 , 31 , 30 , 29 , 28, + /* polyhedron 1*/ + 0 , 7 , 8 , 10 , 11 , 9 , 2 , -1 , 32 , 0 , 7 , 35 , 34 , 33 , -1 , 32 , 0 , 2 , 37 , 36 , -1 , 35 , 7 , 8 , 40 , 39 , 38 , -1 + , 2 , 37 , 41 , 9 , -1 , 40 , 8 , 10 , 44 , 43 , 42 , -1 , 41 , 9 , 11 , 44 , 43 , -1 , 44 , 11 , 10 , -1 , 32 , 33 , 45 , 47 , 46 , 36 , -1 + , 33 , 34 , 48 , 45 , -1 , 35 , 34 , 48 , 50 , 49 , 38 , -1 , 41 , 43 , 42 , 46 , 36 , 37 , -1 , 38 , 39 , 51 , 49 , -1 + , 39 , 40 , 42 , 46 , 47 , 52 , 51 , -1 , 45 , 47 , 52 , 50 , 48 , -1 , 52 , 51 , 49 , 50, + /* polyhedron 2*/ + 6 , 7 , 8 , 23 , 22 , 19 , -1 , 6 , 35 , 7 , -1 , 6 , 35 , 38 , 19 , -1 , 35 , 7 , 8 , 40 , 39 , 38 , -1 , 53 , 22 , 19 , 38 , 39 , 54 , -1 + , 23 , 53 , 54 , 40 , 8 , -1 , 53 , 22 , 23 , -1 , 39 , 54 , 40, + /*polyhedron 3*/ + 35 , 34 , 48 , 50 , 49 , 38 , -1 , 6 , 35 , 34 , 56 , 55 , 5 , -1 , 6 , 35 , 38 , 19 , -1 , 34 , 56 , 57 , 59 , 58 , 48 , -1 + , 60 , 61 , 21 , 19 , 38 , 49 , -1 , 62 , 50 , 48 , 58 , -1 , 60 , 63 , 64 , 62 , 50 , 49 , -1 , 5 , 6 , 19 , 21 , 20 , 12 , -1 + , 55 , 5 , 12 , 65 , -1 , 66 , 67 , 65 , 55 , 56 , 57 , -1 , 63 , 66 , 57 , 59 , 64 , -1 , 64 , 62 , 58 , 59 , -1 + , 60 , 63 , 66 , 67 , 68 , 61 , -1 , 61 , 68 , 20 , 21 , -1 , 67 , 68 , 20 , 12 , 65}; + + double barys[]={ -0.0165220465527 , -0.0190922868195 , 0.158882733414 , + 0.0287618656076 , 0.135874379934 , -0.14601588119 , + -0.147128055553 , 0.0465995097041 , -0.049391174453 , + -0.00142506732317 , -0.0996953090351 , -0.115159183132 }; + MEDCouplingUMesh *meshN=MEDCouplingUMesh::New(); + meshN->setName("ForBary"); + meshN->setMeshDimension(3); + meshN->allocateCells(4); + meshN->insertNextCell(INTERP_KERNEL::NORM_POLYHED,113,connN); + meshN->insertNextCell(INTERP_KERNEL::NORM_POLYHED,99,connN+113); + meshN->insertNextCell(INTERP_KERNEL::NORM_POLYHED,43,connN+212); + meshN->insertNextCell(INTERP_KERNEL::NORM_POLYHED,92,connN+255); + meshN->finishInsertingCells(); + DataArrayDouble *myCoords=DataArrayDouble::New(); + myCoords->alloc(69,3); + std::copy(coords,coords+207,myCoords->getPointer()); + meshN->setCoords(myCoords); + myCoords->decrRef(); + meshN->checkCoherency(); + std::vector<int> res1; + meshN->arePolyhedronsNotCorrectlyOriented(res1); + meshN->orientCorrectlyPolyhedrons(); + res1.clear(); + meshN->arePolyhedronsNotCorrectlyOriented(res1); + CPPUNIT_ASSERT(res1.empty()); + // + DataArrayDouble *da=meshN->getBarycenterAndOwner(); + CPPUNIT_ASSERT_EQUAL(4,da->getNumberOfTuples()); + CPPUNIT_ASSERT_EQUAL(3,da->getNumberOfComponents()); + const double *daPtr=da->getConstPointer(); + for(int i=0;i<12;i++) + CPPUNIT_ASSERT_DOUBLES_EQUAL(barys[i],daPtr[i],1e-12); + da->decrRef(); + // + meshN->decrRef(); +} + +void MEDCouplingBasicsTest2::testRenumberCellsForFields() +{ + MEDCouplingUMesh *m=build2DTargetMesh_1(); + MEDCouplingFieldDouble *f=MEDCouplingFieldDouble::New(ON_CELLS,NO_TIME); + f->setMesh(m); + DataArrayDouble *arr=DataArrayDouble::New(); + int nbOfCells=m->getNumberOfCells(); + arr->alloc(nbOfCells,3); + f->setArray(arr); + arr->decrRef(); + const double values1[15]={7.,107.,10007.,8.,108.,10008.,9.,109.,10009.,10.,110.,10010.,11.,111.,10011.}; + std::copy(values1,values1+15,arr->getPointer()); + const int renumber1[5]={3,1,0,4,2}; + double res[3]; + const double loc[]={-0.05,-0.05, 0.55,-0.25, 0.55,0.15, -0.05,0.45, 0.45,0.45}; + for(int j=0;j<5;j++) + { + f->getValueOn(loc+2*j,res); + for(int i=0;i<3;i++) + CPPUNIT_ASSERT_DOUBLES_EQUAL(values1[i+3*j],res[i],1e-12); + } + f->renumberCells(renumber1,false); + const double *ptr=f->getArray()->getConstPointer(); + const double expected1[15]={9.,109.,10009.,8.,108.,10008.,11.,111.,10011.,7.,107.,10007.,10.,110.,10010.}; + for(int i=0;i<15;i++) + CPPUNIT_ASSERT_DOUBLES_EQUAL(expected1[i],ptr[i],1e-12); + //check that fields remains the same geometrically + for(int j=0;j<5;j++) + { + f->getValueOn(loc+2*j,res); + for(int i=0;i<3;i++) + CPPUNIT_ASSERT_DOUBLES_EQUAL(values1[i+3*j],res[i],1e-12); + } + f->decrRef(); + //On gauss + f=MEDCouplingFieldDouble::New(ON_GAUSS_PT,NO_TIME); + f->setMesh(m); + const double _a=0.446948490915965; + const double _b=0.091576213509771; + const double _p1=0.11169079483905; + const double _p2=0.0549758718227661; + const double refCoo1[6]={ 0.,0., 1.,0., 0.,1. }; + const double gsCoo1[12]={ 2*_b-1, 1-4*_b, 2*_b-1, 2.07*_b-1, 1-4*_b, + 2*_b-1, 1-4*_a, 2*_a-1, 2*_a-1, 1-4*_a, 2*_a-1, 2*_a-1 }; + const double wg1[6]={ 4*_p2, 4*_p2, 4*_p2, 4*_p1, 4*_p1, 4*_p1 }; + std::vector<double> _refCoo1(refCoo1,refCoo1+6); + std::vector<double> _gsCoo1(gsCoo1,gsCoo1+12); + std::vector<double> _wg1(wg1,wg1+6); + f->setGaussLocalizationOnType(INTERP_KERNEL::NORM_TRI3,_refCoo1,_gsCoo1,_wg1); + const double refCoo2[8]={ 0.,0., 1.,0., 1.,1., 0.,1. }; + std::vector<double> _refCoo2(refCoo2,refCoo2+8); + _gsCoo1.resize(4); _wg1.resize(2); + f->setGaussLocalizationOnType(INTERP_KERNEL::NORM_QUAD4,_refCoo2,_gsCoo1,_wg1); + arr=DataArrayDouble::New(); + arr->alloc(18,2); + const double values2[36]={1.,1001.,2.,1002., 11.,1011.,12.,1012.,13.,1013.,14.,1014.,15.,1015.,16.,1016., 21.,1021.,22.,1022.,23.,1023.,24.,1024.,25.,1025.,26.,1026., 31.,1031.,32.,1032., 41.,1041.,42.,1042.}; + std::copy(values2,values2+36,arr->getPointer()); + f->setArray(arr); + arr->decrRef(); + f->checkCoherency(); + MEDCouplingFieldDouble *fCpy=f->clone(true); + CPPUNIT_ASSERT(f->isEqual(fCpy,1e-12,1e-12)); + f->renumberCells(renumber1,false); + CPPUNIT_ASSERT(!f->isEqual(fCpy,1e-12,1e-12)); + double expected2[36]={21.,1021.,22.,1022.,23.,1023.,24.,1024.,25.,1025.,26.,1026., 11.,1011.,12.,1012.,13.,1013.,14.,1014.,15.,1015.,16.,1016., 41.,1041.,42.,1042., 1.,1001.,2.,1002., 31.,1031.,32.,1032.}; + ptr=f->getArray()->getConstPointer(); + for(int i=0;i<36;i++) + CPPUNIT_ASSERT_DOUBLES_EQUAL(expected2[i],ptr[i],1e-12); + const int renumber2[5]={2,1,4,0,3};//reverse renumber1 + f->renumberCells(renumber2,false); + CPPUNIT_ASSERT(f->isEqual(fCpy,1e-12,1e-12)); + fCpy->decrRef(); + f->decrRef(); + //GaussNE + f=MEDCouplingFieldDouble::New(ON_GAUSS_NE,NO_TIME); + f->setMesh(m); + arr=DataArrayDouble::New(); + arr->alloc(18,2); + const double values3[36]={1.,1001.,2.,1002.,3.,1003.,4.,1004., 11.,1011.,12.,1012.,13.,1013., 21.,1021.,22.,1022.,23.,1023., 31.,1031.,32.,1032.,33.,1033.,34.,1034., 41.,1041.,42.,1042.,43.,1043.,44.,1044.}; + std::copy(values3,values3+36,arr->getPointer()); + f->setArray(arr); + arr->decrRef(); + f->checkCoherency(); + fCpy=f->clone(true); + CPPUNIT_ASSERT(f->isEqual(fCpy,1e-12,1e-12)); + f->renumberCells(renumber1,false); + CPPUNIT_ASSERT(!f->isEqual(fCpy,1e-12,1e-12)); + double expected3[36]={21.,1021.,22.,1022.,23.,1023.,11.,1011.,12.,1012.,13.,1013.,41.,1041.,42.,1042.,43.,1043.,44.,1044.,1.,1001.,2.,1002.,3.,1003.,4.,1004.,31.,1031.,32.,1032.,33.,1033.,34.,1034.}; + ptr=f->getArray()->getConstPointer(); + for(int i=0;i<36;i++) + CPPUNIT_ASSERT_DOUBLES_EQUAL(expected3[i],ptr[i],1e-12); + f->renumberCells(renumber2,false);//perform reverse operation of renumbering to check that the resulting field is equal. + CPPUNIT_ASSERT(f->isEqual(fCpy,1e-12,1e-12)); + fCpy->decrRef(); + f->decrRef(); + // + m->decrRef(); +} + +void MEDCouplingBasicsTest2::testRenumberNodesForFields() +{ + MEDCouplingUMesh *m=build2DTargetMesh_1(); + MEDCouplingFieldDouble *f=MEDCouplingFieldDouble::New(ON_NODES,NO_TIME); + f->setMesh(m); + CPPUNIT_ASSERT_EQUAL(9,f->getNumberOfMeshPlacesExpected()); + DataArrayDouble *arr=DataArrayDouble::New(); + int nbOfNodes=m->getNumberOfNodes(); + arr->alloc(nbOfNodes,3); + f->setArray(arr); + arr->decrRef(); + const double values1[27]={7.,107.,10007.,8.,108.,10008.,9.,109.,10009.,10.,110.,10010.,11.,111.,10011.,12.,112.,10012.,13.,113.,10013.,14.,114.,10014.,15.,115.,10015.}; + std::copy(values1,values1+27,arr->getPointer()); + f->checkCoherency(); + const int renumber1[9]={0,4,1,3,5,2,6,7,8}; + double res[3]; + const double loc[]={0.5432,-0.2432, 0.5478,0.1528}; + const double expected1[6]={9.0272, 109.0272, 10009.0272, 11.4124,111.4124,10011.4124}; + for(int j=0;j<2;j++) + { + f->getValueOn(loc+2*j,res); + for(int i=0;i<3;i++) + CPPUNIT_ASSERT_DOUBLES_EQUAL(expected1[i+3*j],res[i],1e-12); + } + MEDCouplingFieldDouble *fCpy=f->clone(true); + CPPUNIT_ASSERT(f->isEqual(fCpy,1e-12,1e-12)); + f->renumberNodes(renumber1); + CPPUNIT_ASSERT(!f->isEqual(fCpy,1e-12,1e-12)); + for(int j=0;j<2;j++) + { + f->getValueOn(loc+2*j,res); + for(int i=0;i<3;i++) + CPPUNIT_ASSERT_DOUBLES_EQUAL(expected1[i+3*j],res[i],1e-12); + } + const double expected2[27]={7.,107.,10007.,9.,109.,10009.,12.,112.,10012.,10.,110.,10010.,8.,108.,10008.,11.,111.,10011.,13.,113.,10013.,14.,114.,10014.,15.,115.,10015.}; + for(int i=0;i<27;i++) + CPPUNIT_ASSERT_DOUBLES_EQUAL(expected2[i],f->getArray()->getConstPointer()[i],1e-12); + const int renumber2[9]={0,2,5,3,1,4,6,7,8};//reverse of renumber2 + f->renumberNodes(renumber2); + CPPUNIT_ASSERT(f->isEqual(fCpy,1e-12,1e-12)); + fCpy->decrRef(); + // + m->decrRef(); + f->decrRef(); +} + +void MEDCouplingBasicsTest2::testConvertQuadraticCellsToLinear() +{ + MEDCouplingUMesh *mesh=build2DTargetMesh_3(); + mesh->checkCoherency(); + std::set<INTERP_KERNEL::NormalizedCellType> types=mesh->getAllGeoTypes(); + CPPUNIT_ASSERT_EQUAL(5,(int)types.size()); + INTERP_KERNEL::NormalizedCellType expected1[5]={INTERP_KERNEL::NORM_POLYGON, INTERP_KERNEL::NORM_TRI3, INTERP_KERNEL::NORM_QUAD4, INTERP_KERNEL::NORM_TRI6, INTERP_KERNEL::NORM_QUAD8}; + std::set<INTERP_KERNEL::NormalizedCellType> expected1Bis(expected1,expected1+5); + CPPUNIT_ASSERT(expected1Bis==types); + CPPUNIT_ASSERT(mesh->isPresenceOfQuadratic()); + CPPUNIT_ASSERT_EQUAL(62,mesh->getMeshLength()); + MEDCouplingFieldDouble *f1=mesh->getMeasureField(false); + // + mesh->convertQuadraticCellsToLinear(); + CPPUNIT_ASSERT(!mesh->isPresenceOfQuadratic()); + // + mesh->checkCoherency(); + MEDCouplingFieldDouble *f2=mesh->getMeasureField(false); + CPPUNIT_ASSERT(f1->getArray()->isEqual(*f2->getArray(),1e-12)); + CPPUNIT_ASSERT_EQUAL(48,mesh->getMeshLength()); + std::set<INTERP_KERNEL::NormalizedCellType> types2=mesh->getAllGeoTypes(); + CPPUNIT_ASSERT_EQUAL(3,(int)types2.size()); + INTERP_KERNEL::NormalizedCellType expected2[3]={INTERP_KERNEL::NORM_POLYGON, INTERP_KERNEL::NORM_TRI3, INTERP_KERNEL::NORM_QUAD4}; + std::set<INTERP_KERNEL::NormalizedCellType> expected2Bis(expected2,expected2+3); + CPPUNIT_ASSERT(expected2Bis==types2); + // + f1->decrRef(); + f2->decrRef(); + mesh->decrRef(); +} + +void MEDCouplingBasicsTest2::testCheckGeoEquivalWith() +{ + MEDCouplingUMesh *mesh1=build2DTargetMesh_3(); + MEDCouplingUMesh *mesh2=build2DTargetMesh_3(); + DataArrayInt *cellCor,*nodeCor; + //First test mesh1 + mesh1->checkGeoEquivalWith(mesh1,0,1e-12,cellCor,nodeCor);//deepEqual + CPPUNIT_ASSERT(cellCor==0); + CPPUNIT_ASSERT(nodeCor==0); + mesh1->checkGeoEquivalWith(mesh1,1,1e-12,cellCor,nodeCor);//fastEqual + CPPUNIT_ASSERT(cellCor==0); + CPPUNIT_ASSERT(nodeCor==0); + mesh1->checkGeoEquivalWith(mesh1,10,1e-12,cellCor,nodeCor);//deepEqual with geo permutations + CPPUNIT_ASSERT(cellCor==0); + CPPUNIT_ASSERT(nodeCor==0); + //Second test mesh1 and mesh2 are 2 different meshes instance + mesh1->checkGeoEquivalWith(mesh2,0,1e-12,cellCor,nodeCor);//deepEqual + CPPUNIT_ASSERT(cellCor==0); + CPPUNIT_ASSERT(nodeCor==0); + mesh1->checkGeoEquivalWith(mesh2,1,1e-12,cellCor,nodeCor);//fastEqual + CPPUNIT_ASSERT(cellCor==0); + CPPUNIT_ASSERT(nodeCor==0); + mesh1->checkGeoEquivalWith(mesh2,10,1e-12,cellCor,nodeCor);//deepEqual with geo permutations + CPPUNIT_ASSERT(cellCor==0); + CPPUNIT_ASSERT(nodeCor==0); + //Third test : cell permutation by keeping the first the middle and the last as it is. + const int renum[]={0,2,1,3,4,5,6,8,7,9}; + mesh2->renumberCells(renum,false); + CPPUNIT_ASSERT_THROW(mesh1->checkGeoEquivalWith(mesh2,0,1e-12,cellCor,nodeCor),INTERP_KERNEL::Exception);//deepEqual fails + CPPUNIT_ASSERT(cellCor==0); + CPPUNIT_ASSERT(nodeCor==0); + mesh1->checkGeoEquivalWith(mesh2,1,1e-12,cellCor,nodeCor);//fastEqual do not see anything + CPPUNIT_ASSERT(cellCor==0); + CPPUNIT_ASSERT(nodeCor==0); + mesh1->checkGeoEquivalWith(mesh2,10,1e-12,cellCor,nodeCor);//deepEqual with geo permutations + CPPUNIT_ASSERT(cellCor); + CPPUNIT_ASSERT_EQUAL(10,cellCor->getNumberOfTuples()); + CPPUNIT_ASSERT_EQUAL(1,cellCor->getNumberOfComponents()); + CPPUNIT_ASSERT(std::equal(renum,renum+10,cellCor->getConstPointer())); + CPPUNIT_ASSERT(nodeCor==0); + cellCor->decrRef(); + cellCor=0; + CPPUNIT_ASSERT(nodeCor==0); + //4th test : cell and node permutation by keeping the first the middle and the last as it is. + mesh2->decrRef(); + mesh2=build2DTargetMesh_3(); + const int renum2[]={0,2,1,3,4,5,6,8,7,9,10}; + mesh2->renumberCells(renum,false); + mesh2->renumberNodes(renum2,11); + CPPUNIT_ASSERT_THROW(mesh1->checkGeoEquivalWith(mesh2,0,1e-12,cellCor,nodeCor),INTERP_KERNEL::Exception);//deepEqual fails + CPPUNIT_ASSERT(cellCor==0); + CPPUNIT_ASSERT(nodeCor==0); + mesh1->checkGeoEquivalWith(mesh2,1,1e-12,cellCor,nodeCor);//fastEqual do not see anything + CPPUNIT_ASSERT(cellCor==0); + CPPUNIT_ASSERT(nodeCor==0); + mesh1->checkGeoEquivalWith(mesh2,10,1e-12,cellCor,nodeCor);//deepEqual with geo permutations + CPPUNIT_ASSERT(cellCor); + CPPUNIT_ASSERT_EQUAL(10,cellCor->getNumberOfTuples()); + CPPUNIT_ASSERT_EQUAL(1,cellCor->getNumberOfComponents()); + CPPUNIT_ASSERT(std::equal(renum,renum+10,cellCor->getConstPointer())); + CPPUNIT_ASSERT(nodeCor); + CPPUNIT_ASSERT_EQUAL(11,nodeCor->getNumberOfTuples()); + CPPUNIT_ASSERT_EQUAL(1,nodeCor->getNumberOfComponents()); + CPPUNIT_ASSERT(std::equal(renum2,renum2+11,nodeCor->getConstPointer())); + cellCor->decrRef(); + cellCor=0; + nodeCor->decrRef(); + nodeCor=0; + //5th test : modification of the last cell to check fastCheck detection. + mesh2->decrRef(); + mesh2=build2DTargetMesh_3(); + const int renum3[]={0,2,1,3,4,5,6,8,9,7}; + mesh2->renumberCells(renum3,false); + mesh2->renumberNodes(renum2,11); + bool isExcep=false; + try { mesh1->checkGeoEquivalWith(mesh2,0,1e-12,cellCor,nodeCor);//deepEqual fails + } + catch(INTERP_KERNEL::Exception& e) { isExcep=true; } + CPPUNIT_ASSERT(isExcep); isExcep=false; + CPPUNIT_ASSERT(cellCor==0); + CPPUNIT_ASSERT(nodeCor==0); + try { mesh1->checkGeoEquivalWith(mesh2,1,1e-12,cellCor,nodeCor);//fastEqual has detected something + } + catch(INTERP_KERNEL::Exception& e) { isExcep=true; } + CPPUNIT_ASSERT(isExcep); isExcep=false; + CPPUNIT_ASSERT(cellCor==0); + CPPUNIT_ASSERT(nodeCor==0); + mesh2->checkGeoEquivalWith(mesh1,10,1e-12,cellCor,nodeCor);//deepEqual with geo permutations + CPPUNIT_ASSERT(cellCor); + CPPUNIT_ASSERT_EQUAL(10,cellCor->getNumberOfTuples()); + CPPUNIT_ASSERT_EQUAL(1,cellCor->getNumberOfComponents()); + CPPUNIT_ASSERT(std::equal(renum3,renum3+10,cellCor->getConstPointer())); + CPPUNIT_ASSERT(nodeCor); + CPPUNIT_ASSERT_EQUAL(11,nodeCor->getNumberOfTuples()); + CPPUNIT_ASSERT_EQUAL(1,nodeCor->getNumberOfComponents()); + CPPUNIT_ASSERT(std::equal(renum2,renum2+11,nodeCor->getConstPointer())); + cellCor->decrRef(); + cellCor=0; + nodeCor->decrRef(); + nodeCor=0; + // + mesh1->decrRef(); + mesh2->decrRef(); +} + +void MEDCouplingBasicsTest2::testCheckGeoEquivalWith2() +{ + MEDCouplingUMesh *mesh1=build2DTargetMesh_4(); + MEDCouplingUMesh *mesh2=build2DTargetMesh_1(); + DataArrayInt *cellCor,*nodeCor; + mesh1->checkGeoEquivalWith(mesh2,10,1e-12,cellCor,nodeCor); + CPPUNIT_ASSERT(cellCor==0); + CPPUNIT_ASSERT(nodeCor!=0); + const int expected1[9]={0, 1, 3, 4, 5, 6, 7, 8, 9}; + for(int i=0;i<9;i++) + CPPUNIT_ASSERT_EQUAL(expected1[i],nodeCor->getIJ(i,0)); + nodeCor->decrRef(); + // + mesh1->decrRef(); + mesh2->decrRef(); +} + +void MEDCouplingBasicsTest2::testCopyTinyStringsFromOnFields() +{ + MEDCouplingUMesh *m=build3DSurfTargetMesh_1(); + int nbOfCells=m->getNumberOfCells(); + MEDCouplingFieldDouble *f=MEDCouplingFieldDouble::New(ON_CELLS,LINEAR_TIME); + f->setMesh(m); + CPPUNIT_ASSERT_EQUAL(5,f->getNumberOfMeshPlacesExpected()); + f->setName("a"); + f->setDescription("b"); + DataArrayDouble *a1=DataArrayDouble::New(); + a1->alloc(nbOfCells,2); + a1->fillWithZero(); + a1->setInfoOnComponent(0,"c"); + a1->setInfoOnComponent(1,"d"); + DataArrayDouble *a2=a1->deepCpy(); + a2->setInfoOnComponent(0,"e"); + a2->setInfoOnComponent(1,"f"); + f->setArray(a1); + f->setEndArray(a2); + f->setEndTime(3.,3,4); + a2->decrRef(); + a1->decrRef(); + m->setName("g"); + m->getCoords()->setInfoOnComponent(0,"h"); + m->getCoords()->setInfoOnComponent(1,"i"); + m->getCoords()->setInfoOnComponent(2,"j"); + // + f->checkCoherency(); + MEDCouplingFieldDouble *f2=f->clone(true); + CPPUNIT_ASSERT(f2->isEqual(f,1e-12,1e-12)); + f2->setName("smth"); + CPPUNIT_ASSERT(!f2->isEqual(f,1e-12,1e-12)); + f2->copyTinyStringsFrom(f); + CPPUNIT_ASSERT(f2->isEqual(f,1e-12,1e-12)); + f2->setDescription("GGG"); + CPPUNIT_ASSERT(!f2->isEqual(f,1e-12,1e-12)); + f2->copyTinyStringsFrom(f); + CPPUNIT_ASSERT(f2->isEqual(f,1e-12,1e-12)); + f2->getArray()->setInfoOnComponent(0,"mmmm"); + CPPUNIT_ASSERT(!f2->isEqual(f,1e-12,1e-12)); + f2->copyTinyStringsFrom(f); + CPPUNIT_ASSERT(f2->isEqual(f,1e-12,1e-12)); + f2->getEndArray()->setInfoOnComponent(1,"mmmm"); + CPPUNIT_ASSERT(!f2->isEqual(f,1e-12,1e-12)); + f2->copyTinyStringsFrom(f); + CPPUNIT_ASSERT(f2->isEqual(f,1e-12,1e-12)); + f2->decrRef(); + MEDCouplingUMesh *m2=m->clone(true); + CPPUNIT_ASSERT(m2->isEqual(m,1e-12)); + m2->setName("123"); + CPPUNIT_ASSERT(!m2->isEqual(m,1e-12)); + m2->copyTinyStringsFrom(m); + CPPUNIT_ASSERT(m2->isEqual(m,1e-12)); + m2->getCoords()->setInfoOnComponent(1,"eee"); + CPPUNIT_ASSERT(!m2->isEqual(m,1e-12)); + m2->copyTinyStringsFrom(m); + CPPUNIT_ASSERT(m2->isEqual(m,1e-12)); + m2->decrRef(); + // + f->decrRef(); + m->decrRef(); +} + +void MEDCouplingBasicsTest2::testTryToShareSameCoordsPermute() +{ + MEDCouplingUMesh *m=build3DSurfTargetMesh_1(); + MEDCouplingUMesh *m2=build3DSurfTargetMesh_1(); + CPPUNIT_ASSERT(m->getCoords()!=m2->getCoords()); + m->tryToShareSameCoordsPermute(*m2,1e-12); + CPPUNIT_ASSERT(m->getCoords()==m2->getCoords()); + CPPUNIT_ASSERT(m2->isEqual(m,1e-12)); + const int renum1[9]={1,2,0,5,8,7,4,3,6}; + m->renumberNodes(renum1,9); + CPPUNIT_ASSERT(m->getCoords()!=m2->getCoords()); + CPPUNIT_ASSERT(!m2->isEqual(m,1e-12)); + m->tryToShareSameCoordsPermute(*m2,1e-12); + CPPUNIT_ASSERT(m->getCoords()==m2->getCoords()); + CPPUNIT_ASSERT(m2->isEqual(m,1e-12)); + m2->decrRef(); + m->decrRef(); +} + +void MEDCouplingBasicsTest2::testTryToShareSameCoordsPermute2() +{ + MEDCouplingUMesh *m1=build2DTargetMesh_4(); + double targetCoords[8]={-0.3,-0.3, 0.2,-0.3, -0.3,0.2, 0.2,0.2 }; + int targetConn[4]={0,2,3,1}; + MEDCouplingUMesh *m2=MEDCouplingUMesh::New(); + m2->setMeshDimension(2); + m2->allocateCells(1); + m2->insertNextCell(INTERP_KERNEL::NORM_QUAD4,4,targetConn); + m2->finishInsertingCells(); + DataArrayDouble *myCoords=DataArrayDouble::New(); + myCoords->alloc(4,2); + std::copy(targetCoords,targetCoords+8,myCoords->getPointer()); + m2->setCoords(myCoords); + myCoords->decrRef(); + m2->checkCoherency(); + m1->checkCoherency(); + // + const double expected1[5]={0.25,0.125,0.125,0.25,0.25}; + MEDCouplingFieldDouble *f1=m1->getMeasureField(false); + MEDCouplingFieldDouble *f2=m2->getMeasureField(false); + CPPUNIT_ASSERT_EQUAL(5,f1->getArray()->getNumberOfTuples()); + CPPUNIT_ASSERT_EQUAL(1,f2->getArray()->getNumberOfTuples()); + for(int i=0;i<5;i++) + CPPUNIT_ASSERT_DOUBLES_EQUAL(expected1[i],f1->getIJ(i,0),1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(expected1[0],f2->getIJ(0,0),1e-12); + f2->decrRef(); + f1->decrRef(); + CPPUNIT_ASSERT_THROW(m1->tryToShareSameCoordsPermute(*m2,1e-12),INTERP_KERNEL::Exception);// <- here in this order the sharing is impossible. + // Let's go for deeper test of tryToShareSameCoordsPermute + m2->tryToShareSameCoordsPermute(*m1,1e-12); + f1=m1->getMeasureField(false); + f2=m2->getMeasureField(false); + CPPUNIT_ASSERT_EQUAL(5,f1->getArray()->getNumberOfTuples()); + CPPUNIT_ASSERT_EQUAL(1,f2->getArray()->getNumberOfTuples()); + for(int i=0;i<5;i++) + CPPUNIT_ASSERT_DOUBLES_EQUAL(expected1[i],f1->getIJ(i,0),1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(expected1[0],f2->getIJ(0,0),1e-12); + // + f2->decrRef(); + f1->decrRef(); + // + m1->decrRef(); + m2->decrRef(); +} + +void MEDCouplingBasicsTest2::testChangeUnderlyingMesh1() +{ + MEDCouplingUMesh *mesh1=build2DTargetMesh_3(); + MEDCouplingUMesh *mesh2=build2DTargetMesh_3(); + MEDCouplingFieldDouble *f1=MEDCouplingFieldDouble::New(ON_CELLS,NO_TIME); + f1->setMesh(mesh1); + DataArrayDouble *array=DataArrayDouble::New(); + array->alloc(mesh1->getNumberOfCells(),2); + const double arr[20]={7.,107.,8.,108.,9.,109.,10.,110.,11.,111.,12.,112.,13.,113.,14.,114.,15.,115.,16.,116.}; + std::copy(arr,arr+20,array->getPointer()); + f1->setArray(array); + array->decrRef(); + // + const int renum[]={0,2,1,3,4,5,6,8,7,9}; + mesh2->renumberCells(renum,false); + CPPUNIT_ASSERT(f1->getMesh()==mesh1); + f1->changeUnderlyingMesh(mesh1,10,1e-12);// nothing done only to check that nothing done. + CPPUNIT_ASSERT(f1->getMesh()==mesh1); + f1->changeUnderlyingMesh(mesh2,10,1e-12); + CPPUNIT_ASSERT(f1->getMesh()==mesh2); + const double expected1[20]={7.,107.,9.,109.,8.,108.,10.,110.,11.,111.,12.,112.,13.,113.,15.,115.,14.,114.,16.,116.}; + for(int i=0;i<20;i++) + CPPUNIT_ASSERT_DOUBLES_EQUAL(expected1[i],f1->getArray()->getIJ(0,i),1e-12); + f1->decrRef(); + // + f1=MEDCouplingFieldDouble::New(ON_NODES,NO_TIME); + f1->setMesh(mesh1); + array=DataArrayDouble::New(); + array->alloc(mesh1->getNumberOfNodes(),2); + const double arr2[22]={7.,107.,8.,108.,9.,109.,10.,110.,11.,111.,12.,112.,13.,113.,14.,114.,15.,115.,16.,116.,17.,117.}; + std::copy(arr2,arr2+22,array->getPointer()); + f1->setArray(array); + array->decrRef(); + // + const int renum2[]={0,2,10,3,4,5,6,8,7,9,1}; + mesh2->renumberNodes(renum2,11); + CPPUNIT_ASSERT(f1->getMesh()==mesh1); + f1->changeUnderlyingMesh(mesh2,10,1e-12); + CPPUNIT_ASSERT(f1->getMesh()==mesh2); + const double expected2[22]={7.,107.,17.,117.,8.,108.,10.,110.,11.,111.,12.,112.,13.,113.,15.,115.,14.,114.,16.,116.,9.,109.}; + for(int i=0;i<22;i++) + CPPUNIT_ASSERT_DOUBLES_EQUAL(expected2[i],f1->getArray()->getIJ(0,i),1e-12); + f1->decrRef(); + // + mesh1->decrRef(); + mesh2->decrRef(); +} + +void MEDCouplingBasicsTest2::testGetMaxValue1() +{ + MEDCouplingUMesh *m=build3DSurfTargetMesh_1(); + int nbOfCells=m->getNumberOfCells(); + MEDCouplingFieldDouble *f=MEDCouplingFieldDouble::New(ON_CELLS,LINEAR_TIME); + f->setMesh(m); + DataArrayDouble *a1=DataArrayDouble::New(); + a1->alloc(nbOfCells,1); + const double val1[5]={3.,4.,5.,6.,7.}; + std::copy(val1,val1+5,a1->getPointer()); + DataArrayDouble *a2=DataArrayDouble::New(); + a2->alloc(nbOfCells,1); + const double val2[5]={0.,1.,2.,8.,7.}; + std::copy(val2,val2+5,a2->getPointer()); + f->setArray(a1); + f->setEndArray(a2); + f->setEndTime(3.,3,4); + f->checkCoherency(); + // + CPPUNIT_ASSERT_DOUBLES_EQUAL(8.,f->getMaxValue(),1e-14); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.,f->getMinValue(),1e-14); + CPPUNIT_ASSERT_DOUBLES_EQUAL(5.,f->getAverageValue(),1e-14); + CPPUNIT_ASSERT_DOUBLES_EQUAL(5.125,f->getWeightedAverageValue(0),1e-14); + a1->setIJ(0,2,9.5); + CPPUNIT_ASSERT_DOUBLES_EQUAL(9.5,f->getMaxValue(),1e-14); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.,f->getMinValue(),1e-14); + a2->setIJ(0,0,9.); + CPPUNIT_ASSERT_DOUBLES_EQUAL(9.5,f->getMaxValue(),1e-14); + CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,f->getMinValue(),1e-14); + // + a2->decrRef(); + a1->decrRef(); + m->decrRef(); + f->decrRef(); +} + +void MEDCouplingBasicsTest2::testSubstractInPlaceDM1() +{ + MEDCouplingUMesh *mesh1=build2DTargetMesh_3(); + MEDCouplingUMesh *mesh2=build2DTargetMesh_3(); + MEDCouplingFieldDouble *f1=MEDCouplingFieldDouble::New(ON_CELLS,NO_TIME); + f1->setMesh(mesh1); + DataArrayDouble *array=DataArrayDouble::New(); + array->alloc(mesh1->getNumberOfCells(),2); + const double arr[20]={7.,107.,8.,108.,9.,109.,10.,110.,11.,111.,12.,112.,13.,113.,14.,114.,15.,115.,16.,116.}; + std::copy(arr,arr+20,array->getPointer()); + f1->setArray(array); + array->decrRef(); + // + CPPUNIT_ASSERT_EQUAL(10,f1->getNumberOfTuples()); + CPPUNIT_ASSERT_EQUAL(2,f1->getNumberOfComponents()); + CPPUNIT_ASSERT_EQUAL(20,f1->getNumberOfValues()); + // + const int renum[]={0,2,3,1,4,5,6,8,7,9}; + mesh2->renumberCells(renum,false); + // + MEDCouplingFieldDouble *f2=MEDCouplingFieldDouble::New(ON_CELLS,NO_TIME); + f2->setMesh(mesh2); + array=DataArrayDouble::New(); + array->alloc(mesh2->getNumberOfCells(),2); + const double arr2[20]={7.1,107.1,10.1,110.1,8.1,108.1,9.1,109.1,11.1,111.1,12.1,112.1,13.1,113.1,15.1,115.1,14.1,114.1,16.1,116.1}; + std::copy(arr2,arr2+20,array->getPointer()); + f2->setArray(array); + array->decrRef(); + // + f1->substractInPlaceDM(f2,10,1e-12); + f1->applyFunc(1,"abs(x+y+0.2)"); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.,f1->getMaxValue(),1e-14); + // + f1->decrRef(); + f2->decrRef(); + mesh1->decrRef(); + mesh2->decrRef(); +} + +void MEDCouplingBasicsTest2::testDotCrossProduct1() +{ + MEDCouplingUMesh *mesh1=build2DTargetMesh_3(); + MEDCouplingFieldDouble *f1=MEDCouplingFieldDouble::New(ON_CELLS,ONE_TIME); + f1->setTime(2.3,5,6); + f1->setMesh(mesh1); + DataArrayDouble *array=DataArrayDouble::New(); + array->alloc(mesh1->getNumberOfCells(),3); + const double arr1[30]={7.,107.,207.,8.,108.,208.,9.,109.,209.,10.,110.,210.,11.,111.,211.,12.,112.,212.,13.,113.,213.,14.,114.,214.,15.,115.,215.,16.,116.,216.}; + std::copy(arr1,arr1+30,array->getPointer()); + f1->setArray(array); + array->decrRef(); + MEDCouplingFieldDouble *f2=MEDCouplingFieldDouble::New(ON_CELLS,ONE_TIME); + f2->setTime(7.8,4,5); + f2->setMesh(mesh1); + array=DataArrayDouble::New(); + array->alloc(mesh1->getNumberOfCells(),3); + const double arr2[30]={1.,2.,3.,4.,5.,6.,7.,8.,9.,10.,11.,12.,13.,14.,15.,16.,17.,18.,19.,20.,21.,22.,23.,24.,25.,26.,27.,28.,29.,30.}; + std::copy(arr2,arr2+30,array->getPointer()); + f2->setArray(array); + array->decrRef(); + // + MEDCouplingFieldDouble *f3=f1->dot(*f2); + const double expected1[10]={842.,1820.,2816.,3830.,4862.,5912.,6980.,8066.,9170.,10292.}; + for(int i=0;i<10;i++) + CPPUNIT_ASSERT_DOUBLES_EQUAL(expected1[i],f3->getIJ(i,0),1e-9); + f3->decrRef(); + // + MEDCouplingFieldDouble *f4=f1->crossProduct(*f2); + const double expected2[30]={-93., 186., -93., -392., 784., -392., -691., 1382., -691., -990., 1980., -990., -1289., 2578., -1289., -1588., 3176., -1588., -1887., 3774., -1887., -2186., 4372., -2186., -2485., 4970., -2485., -2784., 5568., -2784.}; + for(int i=0;i<30;i++) + CPPUNIT_ASSERT_DOUBLES_EQUAL(expected2[i],f4->getIJ(0,i),1e-9); + f4->decrRef(); + // + f2->decrRef(); + f1->decrRef(); + mesh1->decrRef(); +} + +void MEDCouplingBasicsTest2::testMinMaxFields1() +{ + MEDCouplingUMesh *mesh1=build2DTargetMesh_3(); + MEDCouplingFieldDouble *f1=MEDCouplingFieldDouble::New(ON_CELLS,ONE_TIME); + f1->setTime(2.3,5,6); + f1->setMesh(mesh1); + DataArrayDouble *array=DataArrayDouble::New(); + array->alloc(mesh1->getNumberOfCells(),3); + const double arr1[30]={7.,107.,207.,8.,108.,208.,9.,109.,209.,10.,110.,210.,11.,111.,211.,12.,112.,212.,13.,113.,213.,14.,114.,214.,15.,115.,215.,16.,116.,216.}; + std::copy(arr1,arr1+30,array->getPointer()); + f1->setArray(array); + array->decrRef(); + MEDCouplingFieldDouble *f2=MEDCouplingFieldDouble::New(ON_CELLS,ONE_TIME); + f2->setTime(7.8,4,5); + f2->setMesh(mesh1); + array=DataArrayDouble::New(); + array->alloc(mesh1->getNumberOfCells(),3); + const double arr2[30]={6.,108.,206.,9.,107.,209.,8.,110.,208.,11.,109.,211.,10.,112.,210.,13.,111.,213.,12.,114.,212.,15.,113.,215.,14.,116.,214.,17.,115.,217.}; + std::copy(arr2,arr2+30,array->getPointer()); + f2->setArray(array); + array->decrRef(); + // + MEDCouplingFieldDouble *f3=f1->max(*f2); + const double expected1[30]={7.,108.,207.,9.,108.,209.,9.,110.,209.,11.,110.,211.,11.,112.,211.,13.,112.,213.,13.,114.,213.,15.,114.,215.,15.,116.,215.,17.,116.,217.}; + for(int i=0;i<30;i++) + CPPUNIT_ASSERT_DOUBLES_EQUAL(expected1[i],f3->getIJ(0,i),1e-9); + f3->decrRef(); + // + MEDCouplingFieldDouble *f4=f1->min(*f2); + const double expected2[30]={6.,107.,206.,8.,107.,208.,8.,109.,208.,10.,109.,210.,10.,111.,210.,12.,111.,212.,12.,113.,212.,14.,113.,214.,14.,115.,214.,16.,115.,216.}; + for(int i=0;i<30;i++) + CPPUNIT_ASSERT_DOUBLES_EQUAL(expected2[i],f4->getIJ(0,i),1e-9); + f4->decrRef(); + // + f2->decrRef(); + f1->decrRef(); + mesh1->decrRef(); +} + +void MEDCouplingBasicsTest2::testApplyLin1() +{ + MEDCouplingUMesh *mesh1=build2DTargetMesh_3(); + MEDCouplingFieldDouble *f1=MEDCouplingFieldDouble::New(ON_CELLS,LINEAR_TIME); + f1->setMesh(mesh1); + DataArrayDouble *array=DataArrayDouble::New(); + array->alloc(mesh1->getNumberOfCells(),2); + const double arr[20]={7.,107.,8.,108.,9.,109.,10.,110.,11.,111.,12.,112.,13.,113.,14.,114.,15.,115.,16.,116.}; + std::copy(arr,arr+20,array->getPointer()); + f1->setArray(array); + array->decrRef(); + // + f1->applyLin(2.,3.,0); + const double expected1[20]={17.,107.,19.,108.,21.,109.,23.,110.,25.,111.,27.,112.,29.,113.,31.,114.,33.,115.,35.,116.}; + for(int i=0;i<20;i++) + CPPUNIT_ASSERT_DOUBLES_EQUAL(expected1[i],f1->getIJ(0,i),1e-9); + // + const double arr2[20]={2.,102.,3.,103.,4.,104.,5.,105.,6.,106.,7.,107.,8.,108.,9.,109.,10.,110.,11.,111.}; + array=DataArrayDouble::New(); + array->alloc(mesh1->getNumberOfCells(),2); + std::copy(arr2,arr2+20,array->getPointer()); + f1->setEndArray(array); + array->decrRef(); + // + f1->applyLin(4.,5.,1); + // + const double expected2[20]={17.,433.,19.,437.,21.,441.,23.,445.,25.,449.,27.,453.,29.,457.,31.,461.,33.,465.,35.,469.}; + for(int i=0;i<20;i++) + CPPUNIT_ASSERT_DOUBLES_EQUAL(expected2[i],f1->getIJ(0,i),1e-9); + const double expected3[20]={2.,413.,3.,417.,4.,421.,5.,425.,6.,429.,7.,433.,8.,437.,9.,441.,10.,445.,11.,449.}; + for(int i=0;i<20;i++) + CPPUNIT_ASSERT_DOUBLES_EQUAL(expected3[i],f1->getEndArray()->getIJ(0,i),1e-9); + // + mesh1->decrRef(); + f1->decrRef(); +} + +void MEDCouplingBasicsTest2::testGetIdsInRange1() +{ + MEDCouplingUMesh *mesh1=build2DTargetMesh_3(); + MEDCouplingFieldDouble *f1=MEDCouplingFieldDouble::New(ON_CELLS,ONE_TIME); + f1->setTime(2.3,5,6); + f1->setMesh(mesh1); + DataArrayDouble *array=DataArrayDouble::New(); + array->alloc(mesh1->getNumberOfCells(),1); + const double arr1[10]={2.,8.,6.,5.,11.,7.,9.,3.,10.,4.}; + std::copy(arr1,arr1+10,array->getPointer()); + f1->setArray(array); + array->decrRef(); + // + f1->checkCoherency(); + DataArrayInt *da=f1->getIdsInRange(2.9,7.1); + CPPUNIT_ASSERT_EQUAL((std::size_t)5,da->getNbOfElems()); + const int expected1[5]={2,3,5,7,9}; + CPPUNIT_ASSERT(std::equal(expected1,expected1+5,da->getConstPointer())); + da->decrRef(); + da=f1->getIdsInRange(8.,12.); + CPPUNIT_ASSERT_EQUAL((std::size_t)4,da->getNbOfElems()); + const int expected2[4]={1,4,6,8}; + CPPUNIT_ASSERT(std::equal(expected2,expected2+4,da->getConstPointer())); + da->decrRef(); + // + f1->decrRef(); + mesh1->decrRef(); +} + +void MEDCouplingBasicsTest2::testBuildSubPart1() +{ + MEDCouplingUMesh *mesh1=build2DTargetMesh_1(); + MEDCouplingFieldDouble *f1=MEDCouplingFieldDouble::New(ON_CELLS,ONE_TIME); + f1->setTime(2.3,5,6); + f1->setMesh(mesh1); + DataArrayDouble *array=DataArrayDouble::New(); + array->alloc(mesh1->getNumberOfCells(),2); + const double arr1[10]={3.,103.,4.,104.,5.,105.,6.,106.,7.,107.}; + std::copy(arr1,arr1+10,array->getPointer()); + f1->setArray(array); + array->decrRef(); + // + const int part1[3]={2,1,4}; + MEDCouplingFieldDouble *f2=f1->buildSubPart(part1,part1+3); + f2->zipCoords(); + CPPUNIT_ASSERT_EQUAL(3,f2->getNumberOfTuples()); + CPPUNIT_ASSERT_EQUAL(2,f2->getNumberOfComponents()); + const double expected1[6]={5.,105.,4.,104.,7.,107.}; + for(int i=0;i<6;i++) + CPPUNIT_ASSERT_DOUBLES_EQUAL(f2->getIJ(0,i),expected1[i],1e-12); + CPPUNIT_ASSERT_EQUAL(3,f2->getMesh()->getNumberOfCells()); + CPPUNIT_ASSERT_EQUAL(6,f2->getMesh()->getNumberOfNodes()); + CPPUNIT_ASSERT_EQUAL(2,f2->getMesh()->getSpaceDimension()); + CPPUNIT_ASSERT_EQUAL(2,f2->getMesh()->getMeshDimension()); + MEDCouplingUMesh *m2C=dynamic_cast<MEDCouplingUMesh *>(const_cast<MEDCouplingMesh *>(f2->getMesh())); + CPPUNIT_ASSERT_EQUAL(13,m2C->getMeshLength()); + const double expected2[12]={0.2, -0.3, 0.7, -0.3, 0.2, 0.2, 0.7, 0.2, 0.2, 0.7, 0.7, 0.7}; + for(int i=0;i<12;i++) + CPPUNIT_ASSERT_DOUBLES_EQUAL(expected2[i],m2C->getCoords()->getIJ(0,i),1.e-12); + const double expected3[13]={3,2,3,1,3,0,2,1,4,4,5,3,2}; + CPPUNIT_ASSERT(std::equal(expected3,expected3+13,m2C->getNodalConnectivity()->getConstPointer())); + const double expected4[4]={0,4,8,13}; + CPPUNIT_ASSERT(std::equal(expected4,expected4+4,m2C->getNodalConnectivityIndex()->getConstPointer())); + f2->decrRef(); + f1->decrRef(); + // Test with field on nodes. + f1=MEDCouplingFieldDouble::New(ON_NODES,ONE_TIME); + f1->setTime(2.3,5,6); + f1->setMesh(mesh1); + array=DataArrayDouble::New(); + array->alloc(mesh1->getNumberOfNodes(),2); + const double arr2[18]={3.,103.,4.,104.,5.,105.,6.,106.,7.,107.,8.,108.,9.,109.,10.,110.,11.,111.}; + std::copy(arr2,arr2+18,array->getPointer()); + f1->setArray(array); + array->decrRef(); + const int part2[2]={1,2}; + f2=f1->buildSubPart(part2,part2+2); + CPPUNIT_ASSERT_EQUAL(4,f2->getNumberOfTuples()); + CPPUNIT_ASSERT_EQUAL(2,f2->getNumberOfComponents()); + const double expected5[8]={4.,104.,5.,105.,7.,107.,8.,108.}; + for(int i=0;i<8;i++) + CPPUNIT_ASSERT_DOUBLES_EQUAL(f2->getIJ(0,i),expected5[i],1e-12); + CPPUNIT_ASSERT_EQUAL(2,f2->getMesh()->getNumberOfCells()); + CPPUNIT_ASSERT_EQUAL(4,f2->getMesh()->getNumberOfNodes()); + CPPUNIT_ASSERT_EQUAL(2,f2->getMesh()->getSpaceDimension()); + CPPUNIT_ASSERT_EQUAL(2,f2->getMesh()->getMeshDimension()); + m2C=dynamic_cast<MEDCouplingUMesh *>(const_cast<MEDCouplingMesh *>(f2->getMesh())); + CPPUNIT_ASSERT_EQUAL(8,m2C->getMeshLength()); + for(int i=0;i<8;i++)//8 is not an error + CPPUNIT_ASSERT_DOUBLES_EQUAL(expected2[i],m2C->getCoords()->getIJ(0,i),1.e-12); + CPPUNIT_ASSERT(std::equal(expected3,expected3+4,m2C->getNodalConnectivity()->getConstPointer()+4)); + CPPUNIT_ASSERT(std::equal(expected3+4,expected3+8,m2C->getNodalConnectivity()->getConstPointer())); + CPPUNIT_ASSERT(std::equal(expected4,expected4+3,m2C->getNodalConnectivityIndex()->getConstPointer())); + f2->decrRef(); + //idem previous because nodes of cell#4 are not fully present in part3 + const int part3[2]={1,2}; + DataArrayInt *arrr=DataArrayInt::New(); + arrr->alloc(2,1); + std::copy(part3,part3+2,arrr->getPointer()); + f2=f1->buildSubPart(arrr); + arrr->decrRef(); + CPPUNIT_ASSERT_EQUAL(4,f2->getNumberOfTuples()); + CPPUNIT_ASSERT_EQUAL(2,f2->getNumberOfComponents()); + for(int i=0;i<8;i++) + CPPUNIT_ASSERT_DOUBLES_EQUAL(f2->getIJ(0,i),expected5[i],1e-12); + CPPUNIT_ASSERT_EQUAL(2,f2->getMesh()->getNumberOfCells()); + CPPUNIT_ASSERT_EQUAL(4,f2->getMesh()->getNumberOfNodes()); + CPPUNIT_ASSERT_EQUAL(2,f2->getMesh()->getSpaceDimension()); + CPPUNIT_ASSERT_EQUAL(2,f2->getMesh()->getMeshDimension()); + m2C=dynamic_cast<MEDCouplingUMesh *>(const_cast<MEDCouplingMesh *>(f2->getMesh())); + CPPUNIT_ASSERT_EQUAL(8,m2C->getMeshLength()); + for(int i=0;i<8;i++)//8 is not an error + CPPUNIT_ASSERT_DOUBLES_EQUAL(expected2[i],m2C->getCoords()->getIJ(0,i),1.e-12); + CPPUNIT_ASSERT(std::equal(expected3,expected3+4,m2C->getNodalConnectivity()->getConstPointer()+4)); + CPPUNIT_ASSERT(std::equal(expected3+4,expected3+8,m2C->getNodalConnectivity()->getConstPointer())); + CPPUNIT_ASSERT(std::equal(expected4,expected4+3,m2C->getNodalConnectivityIndex()->getConstPointer())); + f2->decrRef(); + // + const int part4[3]={1,2,4}; + f2=f1->buildSubPart(part4,part4+3); + CPPUNIT_ASSERT_EQUAL(6,f2->getNumberOfTuples()); + CPPUNIT_ASSERT_EQUAL(2,f2->getNumberOfComponents()); + const double expected6[12]={4.,104.,5.,105.,7.,107.,8.,108.,10.,110.,11.,111.}; + for(int i=0;i<12;i++) + CPPUNIT_ASSERT_DOUBLES_EQUAL(f2->getIJ(0,i),expected6[i],1e-12); + CPPUNIT_ASSERT_EQUAL(3,f2->getMesh()->getNumberOfCells()); + CPPUNIT_ASSERT_EQUAL(6,f2->getMesh()->getNumberOfNodes()); + CPPUNIT_ASSERT_EQUAL(2,f2->getMesh()->getSpaceDimension()); + CPPUNIT_ASSERT_EQUAL(2,f2->getMesh()->getMeshDimension()); + m2C=dynamic_cast<MEDCouplingUMesh *>(const_cast<MEDCouplingMesh *>(f2->getMesh())); + CPPUNIT_ASSERT_EQUAL(13,m2C->getMeshLength()); + for(int i=0;i<12;i++) + CPPUNIT_ASSERT_DOUBLES_EQUAL(expected2[i],m2C->getCoords()->getIJ(0,i),1.e-12); + CPPUNIT_ASSERT(std::equal(expected3,expected3+4,m2C->getNodalConnectivity()->getConstPointer()+4)); + CPPUNIT_ASSERT(std::equal(expected3+4,expected3+8,m2C->getNodalConnectivity()->getConstPointer())); + CPPUNIT_ASSERT(std::equal(expected3+8,expected3+13,m2C->getNodalConnectivity()->getConstPointer()+8)); + CPPUNIT_ASSERT(std::equal(expected4,expected4+4,m2C->getNodalConnectivityIndex()->getConstPointer())); + f2->decrRef(); + // + f1->decrRef(); + mesh1->decrRef(); +} + +void MEDCouplingBasicsTest2::testDoublyContractedProduct1() +{ + MEDCouplingUMesh *mesh1=build2DTargetMesh_1(); + MEDCouplingFieldDouble *f1=MEDCouplingFieldDouble::New(ON_CELLS,NO_TIME); + f1->setMesh(mesh1); + DataArrayDouble *array=DataArrayDouble::New(); + array->alloc(mesh1->getNumberOfCells(),6); + const double arr1[30]={7.8,8.9,9.1,10.2,23.4,34.5, 7.8,8.9,9.1,10.2,23.4,34.5, 7.8,8.9,9.1,10.2,23.4,34.5, 7.8,8.9,9.1,10.2,23.4,34.5, 7.8,8.9,9.1,10.2,23.4,34.5}; + std::copy(arr1,arr1+30,array->getPointer()); + f1->setArray(array); + array->decrRef(); + f1->checkCoherency(); + // + MEDCouplingFieldDouble *f2=f1->doublyContractedProduct(); + f2->checkCoherency(); + CPPUNIT_ASSERT_EQUAL(1,f2->getNumberOfComponents()); + CPPUNIT_ASSERT_EQUAL(5,f2->getNumberOfTuples()); + for(int i=0;i<5;i++) + CPPUNIT_ASSERT_DOUBLES_EQUAL(3906.56,f2->getIJ(i,0),1e-9); + f2->decrRef(); + // + mesh1->decrRef(); + f1->decrRef(); +} + +void MEDCouplingBasicsTest2::testDeterminant1() +{ + MEDCouplingUMesh *mesh1=build2DTargetMesh_1(); + MEDCouplingFieldDouble *f1=MEDCouplingFieldDouble::New(ON_CELLS,CONST_ON_TIME_INTERVAL); + f1->setTime(2.3,5,6); + f1->setEndTime(3.8,7,3); + f1->setMesh(mesh1); + DataArrayDouble *array=DataArrayDouble::New(); + array->alloc(mesh1->getNumberOfCells(),4); + const double arr1[20]={1.2,2.3,3.4,4.5, 1.2,2.3,3.4,4.5, 1.2,2.3,3.4,4.5, 1.2,2.3,3.4,4.5, 1.2,2.3,3.4,4.5}; + std::copy(arr1,arr1+20,array->getPointer()); + f1->setArray(array); + array->decrRef(); + //4 components + f1->checkCoherency(); + MEDCouplingFieldDouble *f2=f1->determinant(); + f2->checkCoherency(); + CPPUNIT_ASSERT_EQUAL(CONST_ON_TIME_INTERVAL,f2->getTimeDiscretization()); + CPPUNIT_ASSERT_EQUAL(1,f2->getNumberOfComponents()); + CPPUNIT_ASSERT_EQUAL(5,f2->getNumberOfValues()); + for(int i=0;i<5;i++) + CPPUNIT_ASSERT_DOUBLES_EQUAL(-2.42,f2->getIJ(i,0),1e-13); + f2->decrRef(); + f1->decrRef(); + //6 components multi arrays with end array not defined + f1=MEDCouplingFieldDouble::New(ON_NODES,LINEAR_TIME); + f1->setTime(2.3,5,6); + f1->setEndTime(3.8,7,3); + f1->setMesh(mesh1); + array=DataArrayDouble::New(); + array->alloc(mesh1->getNumberOfNodes(),6); + const double arr2[54]={1.2,2.3,3.4,4.5,5.6,6.7, 1.2,2.3,3.4,4.5,5.6,6.7, 1.2,2.3,3.4,4.5,5.6,6.7, 1.2,2.3,3.4,4.5,5.6,6.7, 1.2,2.3,3.4,4.5,5.6,6.7, + 1.2,2.3,3.4,4.5,5.6,6.7, 1.2,2.3,3.4,4.5,5.6,6.7, 1.2,2.3,3.4,4.5,5.6,6.7, 1.2,2.3,3.4,4.5,5.6,6.7}; + std::copy(arr2,arr2+54,array->getPointer()); + f1->setArray(array); + array->decrRef(); + CPPUNIT_ASSERT_THROW(f1->checkCoherency(),INTERP_KERNEL::Exception);//no end array specified ! + // + f2=f1->determinant(); + CPPUNIT_ASSERT_EQUAL(LINEAR_TIME,f2->getTimeDiscretization()); + CPPUNIT_ASSERT_EQUAL(1,f2->getArray()->getNumberOfComponents()); + CPPUNIT_ASSERT_EQUAL(9,f2->getNumberOfTuples()); + for(int i=0;i<9;i++) + CPPUNIT_ASSERT_DOUBLES_EQUAL(137.335,f2->getIJ(i,0),1e-10); + f2->decrRef(); + //6 components multi arrays with end array defined + array=DataArrayDouble::New(); + array->alloc(mesh1->getNumberOfNodes(),6); + const double arr3[54]={7.8,8.9,9.1,10.2,23.4,34.5, 7.8,8.9,9.1,10.2,23.4,34.5, 7.8,8.9,9.1,10.2,23.4,34.5, 7.8,8.9,9.1,10.2,23.4,34.5, 7.8,8.9,9.1,10.2,23.4,34.5, + 7.8,8.9,9.1,10.2,23.4,34.5, 7.8,8.9,9.1,10.2,23.4,34.5, 7.8,8.9,9.1,10.2,23.4,34.5, 7.8,8.9,9.1,10.2,23.4,34.5}; + std::copy(arr3,arr3+54,array->getPointer()); + f1->setEndArray(array); + array->decrRef(); + f1->checkCoherency(); + f2=f1->determinant(); + f2->checkCoherency(); + CPPUNIT_ASSERT_EQUAL(LINEAR_TIME,f2->getTimeDiscretization()); + CPPUNIT_ASSERT_EQUAL(1,f2->getNumberOfComponents()); + CPPUNIT_ASSERT_EQUAL(9,f2->getNumberOfTuples()); + int it,order; + CPPUNIT_ASSERT_DOUBLES_EQUAL(2.3,f2->getTime(it,order),1e-12); + CPPUNIT_ASSERT_EQUAL(5,it); CPPUNIT_ASSERT_EQUAL(6,order); + CPPUNIT_ASSERT_DOUBLES_EQUAL(3.8,f2->getEndTime(it,order),1e-12); + CPPUNIT_ASSERT_EQUAL(7,it); CPPUNIT_ASSERT_EQUAL(3,order); + for(int i=0;i<9;i++) + { + CPPUNIT_ASSERT_DOUBLES_EQUAL(137.335,f2->getIJ(i,0),1e-10); + CPPUNIT_ASSERT_DOUBLES_EQUAL(1289.685,f2->getEndArray()->getIJ(i,0),1e-9); + } + f2->decrRef(); + f1->decrRef(); + //9 components + f1=MEDCouplingFieldDouble::New(ON_CELLS,ONE_TIME); + f1->setTime(7.8,10,2); + f1->setMesh(mesh1); + array=DataArrayDouble::New(); + array->alloc(mesh1->getNumberOfCells(),9); + const double arr4[45]={1.2,2.3,3.4,4.5,5.6,6.7,7.8,8.9,9.1, 1.2,2.3,3.4,4.5,5.6,6.7,7.8,8.9,9.1, 1.2,2.3,3.4,4.5,5.6,6.7,7.8,8.9,9.1, 1.2,2.3,3.4,4.5,5.6,6.7,7.8,8.9,9.1, 1.2,2.3,3.4,4.5,5.6,6.7,7.8,8.9,9.1}; + std::copy(arr4,arr4+45,array->getPointer()); + f1->setArray(array); + array->decrRef(); + // + f1->checkCoherency(); + f2=f1->determinant(); + f2->checkCoherency(); + CPPUNIT_ASSERT_EQUAL(ONE_TIME,f2->getTimeDiscretization()); + CPPUNIT_ASSERT_EQUAL(1,f2->getNumberOfComponents()); + CPPUNIT_ASSERT_EQUAL(5,f2->getNumberOfTuples()); + CPPUNIT_ASSERT_DOUBLES_EQUAL(7.8,f2->getTime(it,order),1e-12); + CPPUNIT_ASSERT_EQUAL(10,it); CPPUNIT_ASSERT_EQUAL(2,order); + for(int i=0;i<5;i++) + CPPUNIT_ASSERT_DOUBLES_EQUAL(3.267,f2->getIJ(i,0),1e-13); + f2->decrRef(); + // + mesh1->decrRef(); + f1->decrRef(); +} + +void MEDCouplingBasicsTest2::testEigenValues1() +{ + MEDCouplingUMesh *mesh1=build2DTargetMesh_1(); + MEDCouplingFieldDouble *f1=MEDCouplingFieldDouble::New(ON_CELLS,NO_TIME); + f1->setMesh(mesh1); + DataArrayDouble *array=DataArrayDouble::New(); + array->alloc(mesh1->getNumberOfCells(),6); + const double arr1[30]={1.2,2.3,3.4,4.5,5.6,6.7, 1.2,2.3,3.4,4.5,5.6,6.7, 1.2,2.3,3.4,4.5,5.6,6.7, 1.2,2.3,3.4,4.5,5.6,6.7, 1.2,2.3,3.4,4.5,5.6,6.7}; + std::copy(arr1,arr1+30,array->getPointer()); + f1->setArray(array); + array->decrRef(); + f1->checkCoherency(); + // + MEDCouplingFieldDouble *f2=f1->eigenValues(); + f2->checkCoherency(); + CPPUNIT_ASSERT_EQUAL(3,f2->getNumberOfComponents()); + CPPUNIT_ASSERT_EQUAL(5,f2->getNumberOfTuples()); + const double expected1[3]={13.638813677891717,-4.502313844635971,-2.2364998332557486}; + for(int i=0;i<5;i++) + { + CPPUNIT_ASSERT_DOUBLES_EQUAL(expected1[0],f2->getIJ(i,0),1e-13); + CPPUNIT_ASSERT_DOUBLES_EQUAL(expected1[1],f2->getIJ(i,1),1e-13); + CPPUNIT_ASSERT_DOUBLES_EQUAL(expected1[2],f2->getIJ(i,2),1e-13); + } + f2->decrRef(); + // + mesh1->decrRef(); + f1->decrRef(); +} + +void MEDCouplingBasicsTest2::testEigenVectors1() +{ + MEDCouplingUMesh *mesh1=build2DTargetMesh_1(); + MEDCouplingFieldDouble *f1=MEDCouplingFieldDouble::New(ON_CELLS,NO_TIME); + f1->setMesh(mesh1); + DataArrayDouble *array=DataArrayDouble::New(); + array->alloc(mesh1->getNumberOfCells(),6); + const double arr1[30]={1.2,2.3,3.4,4.5,5.6,6.7, 1.2,2.3,3.4,4.5,5.6,6.7, 1.2,2.3,3.4,4.5,5.6,6.7, 1.2,2.3,3.4,4.5,5.6,6.7, 1.2,2.3,3.4,4.5,5.6,6.7}; + std::copy(arr1,arr1+30,array->getPointer()); + f1->setArray(array); + array->decrRef(); + f1->checkCoherency(); + // + MEDCouplingFieldDouble *f2=f1->eigenVectors(); + f2->checkCoherency(); + CPPUNIT_ASSERT_EQUAL(9,f2->getNumberOfComponents()); + CPPUNIT_ASSERT_EQUAL(5,f2->getNumberOfTuples()); + const double expected1[9]={ + 0.5424262364180696, 0.5351201064614425, 0.6476266283176001,//eigenvect 0 + 0.7381111277307373, 0.06458838384003074, -0.6715804522117897,//eigenvect 1 + -0.4012053603397987, 0.8423032781211455, -0.3599436712889738//eigenvect 2 + }; + for(int i=0;i<5;i++) + { + CPPUNIT_ASSERT_DOUBLES_EQUAL(expected1[0],f2->getIJ(i,0),1e-13); + CPPUNIT_ASSERT_DOUBLES_EQUAL(expected1[1],f2->getIJ(i,1),1e-13); + CPPUNIT_ASSERT_DOUBLES_EQUAL(expected1[2],f2->getIJ(i,2),1e-13); + CPPUNIT_ASSERT_DOUBLES_EQUAL(expected1[3],f2->getIJ(i,3),1e-13); + CPPUNIT_ASSERT_DOUBLES_EQUAL(expected1[4],f2->getIJ(i,4),1e-13); + CPPUNIT_ASSERT_DOUBLES_EQUAL(expected1[5],f2->getIJ(i,5),1e-13); + CPPUNIT_ASSERT_DOUBLES_EQUAL(expected1[6],f2->getIJ(i,6),1e-13); + CPPUNIT_ASSERT_DOUBLES_EQUAL(expected1[7],f2->getIJ(i,7),1e-13); + CPPUNIT_ASSERT_DOUBLES_EQUAL(expected1[8],f2->getIJ(i,8),1e-13); + } + f2->decrRef(); + // + mesh1->decrRef(); + f1->decrRef(); +} + +void MEDCouplingBasicsTest2::testInverse1() +{ + MEDCouplingUMesh *mesh1=build2DTargetMesh_1(); + MEDCouplingFieldDouble *f1=MEDCouplingFieldDouble::New(ON_CELLS,NO_TIME); + f1->setMesh(mesh1); + DataArrayDouble *array=DataArrayDouble::New(); + array->alloc(mesh1->getNumberOfCells(),9); + const double arr1[45]={1.2,2.3,3.4,4.5,5.6,6.7,7.8,8.9,9.1, 1.2,2.3,3.4,4.5,5.6,6.7,7.8,8.9,9.1, 1.2,2.3,3.4,4.5,5.6,6.7,7.8,8.9,9.1, 1.2,2.3,3.4,4.5,5.6,6.7,7.8,8.9,9.1, 1.2,2.3,3.4,4.5,5.6,6.7,7.8,8.9,9.1}; + std::copy(arr1,arr1+45,array->getPointer()); + f1->setArray(array); + array->decrRef(); + f1->checkCoherency(); + // + MEDCouplingFieldDouble *f2=f1->inverse(); + f2->checkCoherency(); + CPPUNIT_ASSERT_EQUAL(9,f2->getNumberOfComponents()); + CPPUNIT_ASSERT_EQUAL(5,f2->getNumberOfTuples()); + const double expected1[9]={-2.6538108356290113, 2.855831037649208, -1.1111111111111067, 3.461891643709813, -4.775022956841121, 2.2222222222222143, -1.1111111111111054, 2.222222222222214, -1.1111111111111072}; + for(int i=0;i<5;i++) + { + CPPUNIT_ASSERT_DOUBLES_EQUAL(expected1[0],f2->getIJ(i,0),1e-13); + CPPUNIT_ASSERT_DOUBLES_EQUAL(expected1[1],f2->getIJ(i,1),1e-13); + CPPUNIT_ASSERT_DOUBLES_EQUAL(expected1[2],f2->getIJ(i,2),1e-13); + CPPUNIT_ASSERT_DOUBLES_EQUAL(expected1[3],f2->getIJ(i,3),1e-13); + CPPUNIT_ASSERT_DOUBLES_EQUAL(expected1[4],f2->getIJ(i,4),1e-13); + CPPUNIT_ASSERT_DOUBLES_EQUAL(expected1[5],f2->getIJ(i,5),1e-13); + CPPUNIT_ASSERT_DOUBLES_EQUAL(expected1[6],f2->getIJ(i,6),1e-13); + CPPUNIT_ASSERT_DOUBLES_EQUAL(expected1[7],f2->getIJ(i,7),1e-13); + CPPUNIT_ASSERT_DOUBLES_EQUAL(expected1[8],f2->getIJ(i,8),1e-13); + } + f2->decrRef(); + // + array=DataArrayDouble::New(); + array->alloc(mesh1->getNumberOfCells(),6); + const double arr3[30]={7.8,8.9,9.1,10.2,23.4,34.5, 7.8,8.9,9.1,10.2,23.4,34.5, 7.8,8.9,9.1,10.2,23.4,34.5, 7.8,8.9,9.1,10.2,23.4,34.5, 7.8,8.9,9.1,10.2,23.4,34.5}; + std::copy(arr3,arr3+30,array->getPointer()); + f1->setArray(array); + array->decrRef(); + f1->checkCoherency(); + // + f2=f1->inverse(); + f2->checkCoherency(); + CPPUNIT_ASSERT_EQUAL(6,f2->getNumberOfComponents()); + CPPUNIT_ASSERT_EQUAL(5,f2->getNumberOfTuples()); + const double expected3[6]={-0.3617705098531818, -0.8678630828458127, -0.026843764174972983, 0.5539957431465833, 0.13133439560823013, -0.05301294502145887}; + for(int i=0;i<5;i++) + { + CPPUNIT_ASSERT_DOUBLES_EQUAL(expected3[0],f2->getIJ(i,0),1e-13); + CPPUNIT_ASSERT_DOUBLES_EQUAL(expected3[1],f2->getIJ(i,1),1e-13); + CPPUNIT_ASSERT_DOUBLES_EQUAL(expected3[2],f2->getIJ(i,2),1e-13); + CPPUNIT_ASSERT_DOUBLES_EQUAL(expected3[3],f2->getIJ(i,3),1e-13); + CPPUNIT_ASSERT_DOUBLES_EQUAL(expected3[4],f2->getIJ(i,4),1e-13); + CPPUNIT_ASSERT_DOUBLES_EQUAL(expected3[5],f2->getIJ(i,5),1e-13); + } + f2->decrRef(); + // + array=DataArrayDouble::New(); + array->alloc(mesh1->getNumberOfCells(),4); + const double arr2[20]={1.2,2.3,3.4,4.5, 1.2,2.3,3.4,4.5, 1.2,2.3,3.4,4.5, 1.2,2.3,3.4,4.5, 1.2,2.3,3.4,4.5}; + std::copy(arr2,arr2+20,array->getPointer()); + f1->setArray(array); + array->decrRef(); + f1->checkCoherency(); + // + f2=f1->inverse(); + f2->checkCoherency(); + CPPUNIT_ASSERT_EQUAL(4,f2->getNumberOfComponents()); + CPPUNIT_ASSERT_EQUAL(5,f2->getNumberOfTuples()); + const double expected2[4]={-1.8595041322314059, 0.9504132231404963, 1.404958677685951, -0.49586776859504156}; + for(int i=0;i<5;i++) + { + CPPUNIT_ASSERT_DOUBLES_EQUAL(expected2[0],f2->getIJ(i,0),1e-13); + CPPUNIT_ASSERT_DOUBLES_EQUAL(expected2[1],f2->getIJ(i,1),1e-13); + CPPUNIT_ASSERT_DOUBLES_EQUAL(expected2[2],f2->getIJ(i,2),1e-13); + CPPUNIT_ASSERT_DOUBLES_EQUAL(expected2[3],f2->getIJ(i,3),1e-13); + } + f2->decrRef(); + // + mesh1->decrRef(); + f1->decrRef(); +} + +void MEDCouplingBasicsTest2::testTrace1() +{ + MEDCouplingUMesh *mesh1=build2DTargetMesh_1(); + MEDCouplingFieldDouble *f1=MEDCouplingFieldDouble::New(ON_CELLS,NO_TIME); + f1->setMesh(mesh1); + DataArrayDouble *array=DataArrayDouble::New(); + array->alloc(mesh1->getNumberOfCells(),9); + const double arr1[45]={1.2,2.3,3.4,4.5,5.6,6.7,7.8,8.9,9.1, 1.2,2.3,3.4,4.5,5.6,6.7,7.8,8.9,9.1, 1.2,2.3,3.4,4.5,5.6,6.7,7.8,8.9,9.1, 1.2,2.3,3.4,4.5,5.6,6.7,7.8,8.9,9.1, 1.2,2.3,3.4,4.5,5.6,6.7,7.8,8.9,9.1}; + std::copy(arr1,arr1+45,array->getPointer()); + f1->setArray(array); + array->decrRef(); + f1->checkCoherency(); + // + MEDCouplingFieldDouble *f2=f1->trace(); + f2->checkCoherency(); + CPPUNIT_ASSERT_EQUAL(1,f2->getNumberOfComponents()); + CPPUNIT_ASSERT_EQUAL(5,f2->getNumberOfTuples()); + for(int i=0;i<5;i++) + CPPUNIT_ASSERT_DOUBLES_EQUAL(15.9,f2->getIJ(i,0),1e-13); + f2->decrRef(); + // + array=DataArrayDouble::New(); + array->alloc(mesh1->getNumberOfCells(),6); + const double arr3[30]={7.8,8.9,9.1,10.2,23.4,34.5, 7.8,8.9,9.1,10.2,23.4,34.5, 7.8,8.9,9.1,10.2,23.4,34.5, 7.8,8.9,9.1,10.2,23.4,34.5, 7.8,8.9,9.1,10.2,23.4,34.5}; + std::copy(arr3,arr3+30,array->getPointer()); + f1->setArray(array); + array->decrRef(); + f1->checkCoherency(); + // + f2=f1->trace(); + f2->checkCoherency(); + CPPUNIT_ASSERT_EQUAL(1,f2->getNumberOfComponents()); + CPPUNIT_ASSERT_EQUAL(5,f2->getNumberOfTuples()); + for(int i=0;i<5;i++) + CPPUNIT_ASSERT_DOUBLES_EQUAL(25.8,f2->getIJ(i,0),1e-13); + f2->decrRef(); + // + array=DataArrayDouble::New(); + array->alloc(mesh1->getNumberOfCells(),4); + const double arr2[20]={1.2,2.3,3.4,4.5, 1.2,2.3,3.4,4.5, 1.2,2.3,3.4,4.5, 1.2,2.3,3.4,4.5, 1.2,2.3,3.4,4.5}; + std::copy(arr2,arr2+20,array->getPointer()); + f1->setArray(array); + array->decrRef(); + f1->checkCoherency(); + // + f2=f1->trace(); + f2->checkCoherency(); + CPPUNIT_ASSERT_EQUAL(1,f2->getNumberOfComponents()); + CPPUNIT_ASSERT_EQUAL(5,f2->getNumberOfTuples()); + for(int i=0;i<5;i++) + CPPUNIT_ASSERT_DOUBLES_EQUAL(5.7,f2->getIJ(i,0),1e-13); + f2->decrRef(); + // + mesh1->decrRef(); + f1->decrRef(); +} + +void MEDCouplingBasicsTest2::testDeviator1() +{ + MEDCouplingUMesh *mesh1=build2DTargetMesh_1(); + MEDCouplingFieldDouble *f1=MEDCouplingFieldDouble::New(ON_CELLS,NO_TIME); + f1->setMesh(mesh1); + DataArrayDouble *array=DataArrayDouble::New(); + array->alloc(mesh1->getNumberOfCells(),6); + const double arr1[30]={1.2,2.3,3.4,4.5,5.6,6.7, 1.2,2.3,3.4,4.5,5.6,6.7, 1.2,2.3,3.4,4.5,5.6,6.7, 1.2,2.3,3.4,4.5,5.6,6.7, 1.2,2.3,3.4,4.5,5.6,6.7}; + std::copy(arr1,arr1+30,array->getPointer()); + f1->setArray(array); + array->decrRef(); + f1->checkCoherency(); + // + MEDCouplingFieldDouble *f2=f1->deviator(); + f2->checkCoherency(); + CPPUNIT_ASSERT_EQUAL(6,f2->getNumberOfComponents()); + CPPUNIT_ASSERT_EQUAL(5,f2->getNumberOfTuples()); + const double expected1[6]={-1.1,0.,1.1,4.5,5.6,6.7}; + for(int i=0;i<5;i++) + { + CPPUNIT_ASSERT_DOUBLES_EQUAL(expected1[0],f2->getIJ(i,0),1e-13); + CPPUNIT_ASSERT_DOUBLES_EQUAL(expected1[1],f2->getIJ(i,1),1e-13); + CPPUNIT_ASSERT_DOUBLES_EQUAL(expected1[2],f2->getIJ(i,2),1e-13); + CPPUNIT_ASSERT_DOUBLES_EQUAL(expected1[3],f2->getIJ(i,3),1e-13); + CPPUNIT_ASSERT_DOUBLES_EQUAL(expected1[4],f2->getIJ(i,4),1e-13); + CPPUNIT_ASSERT_DOUBLES_EQUAL(expected1[5],f2->getIJ(i,5),1e-13); + } + f2->decrRef(); + // + mesh1->decrRef(); + f1->decrRef(); +} + +void MEDCouplingBasicsTest2::testMagnitude1() +{ + MEDCouplingUMesh *mesh1=build2DTargetMesh_1(); + MEDCouplingFieldDouble *f1=MEDCouplingFieldDouble::New(ON_CELLS,NO_TIME); + f1->setMesh(mesh1); + DataArrayDouble *array=DataArrayDouble::New(); + array->alloc(mesh1->getNumberOfCells(),5); + const double arr1[25]={1.2,2.3,3.4,4.5,5.6, 1.2,2.3,3.4,4.5,5.6, 1.2,2.3,3.4,4.5,5.6, 1.2,2.3,3.4,4.5,5.6, 1.2,2.3,3.4,4.5,5.6}; + std::copy(arr1,arr1+25,array->getPointer()); + f1->setArray(array); + array->decrRef(); + f1->checkCoherency(); + // + MEDCouplingFieldDouble *f2=f1->magnitude(); + f2->checkCoherency(); + CPPUNIT_ASSERT_EQUAL(1,f2->getNumberOfComponents()); + CPPUNIT_ASSERT_EQUAL(5,f2->getNumberOfTuples()); + for(int i=0;i<5;i++) + CPPUNIT_ASSERT_DOUBLES_EQUAL(8.3606219864313918,f2->getIJ(i,0),1e-13); + f2->decrRef(); + // + mesh1->decrRef(); + f1->decrRef(); +} + +void MEDCouplingBasicsTest2::testMaxPerTuple1() +{ + MEDCouplingUMesh *mesh1=build2DTargetMesh_1(); + MEDCouplingFieldDouble *f1=MEDCouplingFieldDouble::New(ON_CELLS,NO_TIME); + f1->setMesh(mesh1); + DataArrayDouble *array=DataArrayDouble::New(); + array->alloc(mesh1->getNumberOfCells(),5); + const double arr1[25]={1.2,2.3,3.4,4.5,5.6, 1.2,3.4,4.5,5.6,2.3, 3.4,4.5,5.6,1.2,2.3, 5.6,1.2,2.3,3.4,4.5, 4.5,5.6,1.2,2.3,3.4}; + std::copy(arr1,arr1+25,array->getPointer()); + f1->setArray(array); + array->decrRef(); + f1->checkCoherency(); + // + MEDCouplingFieldDouble *f2=f1->maxPerTuple(); + f2->checkCoherency(); + CPPUNIT_ASSERT_EQUAL(1,f2->getNumberOfComponents()); + CPPUNIT_ASSERT_EQUAL(5,f2->getNumberOfTuples()); + for(int i=0;i<5;i++) + CPPUNIT_ASSERT_DOUBLES_EQUAL(5.6,f2->getIJ(i,0),1e-13); + f2->decrRef(); + // + DataArrayInt *d2I=0; + DataArrayDouble *d2=array->maxPerTupleWithCompoId(d2I); + CPPUNIT_ASSERT_EQUAL(1,d2->getNumberOfComponents()); + CPPUNIT_ASSERT_EQUAL(5,d2->getNumberOfTuples()); + const int expected2[5]={4,3,2,0,1}; + for(int i=0;i<5;i++) + { + CPPUNIT_ASSERT_DOUBLES_EQUAL(5.6,d2->getIJ(i,0),1e-13); + CPPUNIT_ASSERT_EQUAL(expected2[i],d2I->getIJ(i,0)); + } + d2->decrRef(); d2I->decrRef(); + // + mesh1->decrRef(); + f1->decrRef(); +} + +void MEDCouplingBasicsTest2::testChangeNbOfComponents() +{ + MEDCouplingUMesh *mesh1=build2DTargetMesh_1(); + MEDCouplingFieldDouble *f1=MEDCouplingFieldDouble::New(ON_CELLS,NO_TIME); + f1->setMesh(mesh1); + DataArrayDouble *array=DataArrayDouble::New(); + array->alloc(mesh1->getNumberOfCells(),5); + const double arr1[25]={1.2,2.3,3.4,4.5,5.6, 1.2,3.4,4.5,5.6,2.3, 3.4,4.5,5.6,1.2,2.3, 5.6,1.2,2.3,3.4,4.5, 4.5,5.6,1.2,2.3,3.4}; + std::copy(arr1,arr1+25,array->getPointer()); + f1->setArray(array); + array->decrRef(); + f1->checkCoherency(); + // + f1->changeNbOfComponents(3,7.77); + f1->checkCoherency(); + CPPUNIT_ASSERT_EQUAL(3,f1->getNumberOfComponents()); + CPPUNIT_ASSERT_EQUAL(5,f1->getNumberOfTuples()); + const double expected1[15]={1.2,2.3,3.4, 1.2,3.4,4.5, 3.4,4.5,5.6, 5.6,1.2,2.3, 4.5,5.6,1.2}; + for(int i=0;i<15;i++) + CPPUNIT_ASSERT_DOUBLES_EQUAL(expected1[i],f1->getIJ(0,i),1e-13); + f1->changeNbOfComponents(4,7.77); + f1->checkCoherency(); + CPPUNIT_ASSERT_EQUAL(4,f1->getNumberOfComponents()); + CPPUNIT_ASSERT_EQUAL(5,f1->getNumberOfTuples()); + const double expected2[20]={1.2,2.3,3.4,7.77, 1.2,3.4,4.5,7.77, 3.4,4.5,5.6,7.77, 5.6,1.2,2.3,7.77, 4.5,5.6,1.2,7.77}; + for(int i=0;i<20;i++) + CPPUNIT_ASSERT_DOUBLES_EQUAL(expected2[i],f1->getIJ(0,i),1e-13); + // + mesh1->decrRef(); + f1->decrRef(); +} + +void MEDCouplingBasicsTest2::testSortPerTuple1() +{ + MEDCouplingUMesh *mesh1=build2DTargetMesh_1(); + MEDCouplingFieldDouble *f1=MEDCouplingFieldDouble::New(ON_CELLS,NO_TIME); + f1->setMesh(mesh1); + DataArrayDouble *array=DataArrayDouble::New(); + array->alloc(mesh1->getNumberOfCells(),5); + const double arr1[25]={1.2,2.3,3.4,4.5,5.6, 1.2,3.4,4.5,5.6,2.3, 3.4,4.5,5.6,1.2,2.3, 5.6,1.2,2.3,3.4,4.5, 4.5,5.6,1.2,2.3,3.4}; + std::copy(arr1,arr1+25,array->getPointer()); + f1->setArray(array); + array->decrRef(); + f1->checkCoherency(); + // + f1->sortPerTuple(true); + f1->checkCoherency(); + CPPUNIT_ASSERT_EQUAL(5,f1->getNumberOfComponents()); + CPPUNIT_ASSERT_EQUAL(5,f1->getNumberOfTuples()); + for(int i=0;i<5;i++) + { + CPPUNIT_ASSERT_DOUBLES_EQUAL(arr1[0],f1->getIJ(i,0),1e-13); + CPPUNIT_ASSERT_DOUBLES_EQUAL(arr1[1],f1->getIJ(i,1),1e-13); + CPPUNIT_ASSERT_DOUBLES_EQUAL(arr1[2],f1->getIJ(i,2),1e-13); + CPPUNIT_ASSERT_DOUBLES_EQUAL(arr1[3],f1->getIJ(i,3),1e-13); + CPPUNIT_ASSERT_DOUBLES_EQUAL(arr1[4],f1->getIJ(i,4),1e-13); + } + // + f1->sortPerTuple(false); + f1->checkCoherency(); + CPPUNIT_ASSERT_EQUAL(5,f1->getNumberOfComponents()); + CPPUNIT_ASSERT_EQUAL(5,f1->getNumberOfTuples()); + for(int i=0;i<5;i++) + { + CPPUNIT_ASSERT_DOUBLES_EQUAL(arr1[4],f1->getIJ(i,0),1e-13); + CPPUNIT_ASSERT_DOUBLES_EQUAL(arr1[3],f1->getIJ(i,1),1e-13); + CPPUNIT_ASSERT_DOUBLES_EQUAL(arr1[2],f1->getIJ(i,2),1e-13); + CPPUNIT_ASSERT_DOUBLES_EQUAL(arr1[1],f1->getIJ(i,3),1e-13); + CPPUNIT_ASSERT_DOUBLES_EQUAL(arr1[0],f1->getIJ(i,4),1e-13); + } + // + mesh1->decrRef(); + f1->decrRef(); +} + +void MEDCouplingBasicsTest2::testIsEqualWithoutConsideringStr1() +{ + MEDCouplingUMesh *mesh1=build2DTargetMesh_1(); + MEDCouplingUMesh *mesh2=build2DTargetMesh_1(); + DataArrayInt *da1,*da2; + // + CPPUNIT_ASSERT(mesh1->isEqual(mesh2,1e-12)); + CPPUNIT_ASSERT(mesh1->isEqualWithoutConsideringStr(mesh2,1e-12)); + mesh2->setName("rr"); + CPPUNIT_ASSERT(!mesh1->isEqual(mesh2,1e-12)); + CPPUNIT_ASSERT(mesh1->isEqualWithoutConsideringStr(mesh2,1e-12)); + mesh1->checkDeepEquivalWith(mesh2,2,1e-12,da1,da2); + CPPUNIT_ASSERT_THROW(mesh1->checkGeoEquivalWith(mesh2,0,1e-12,da1,da2),INTERP_KERNEL::Exception); + mesh2->setName(""); + CPPUNIT_ASSERT(mesh1->isEqual(mesh2,1e-12)); + CPPUNIT_ASSERT(mesh1->isEqualWithoutConsideringStr(mesh2,1e-12)); + mesh2->getCoords()->setInfoOnComponent(0,"tty"); + CPPUNIT_ASSERT(!mesh1->isEqual(mesh2,1e-12)); + CPPUNIT_ASSERT(mesh1->isEqualWithoutConsideringStr(mesh2,1e-12)); + mesh2->getCoords()->setInfoOnComponent(0,""); + CPPUNIT_ASSERT(mesh1->isEqual(mesh2,1e-12)); + CPPUNIT_ASSERT(mesh1->isEqualWithoutConsideringStr(mesh2,1e-12)); + mesh2->getCoords()->setInfoOnComponent(1,"tty"); + CPPUNIT_ASSERT(!mesh1->isEqual(mesh2,1e-12)); + CPPUNIT_ASSERT(mesh1->isEqualWithoutConsideringStr(mesh2,1e-12)); + mesh2->getCoords()->setInfoOnComponent(1,""); + CPPUNIT_ASSERT(mesh1->isEqual(mesh2,1e-12)); + CPPUNIT_ASSERT(mesh1->isEqualWithoutConsideringStr(mesh2,1e-12)); + double tmp=mesh2->getCoords()->getIJ(0,3); + mesh2->getCoords()->setIJ(0,3,9999.); + CPPUNIT_ASSERT(!mesh1->isEqual(mesh2,1e-12)); + CPPUNIT_ASSERT(!mesh1->isEqualWithoutConsideringStr(mesh2,1e-12)); + mesh2->getCoords()->setIJ(0,3,tmp); + CPPUNIT_ASSERT(mesh1->isEqual(mesh2,1e-12)); + CPPUNIT_ASSERT(mesh1->isEqualWithoutConsideringStr(mesh2,1e-12)); + int tmp2=mesh2->getNodalConnectivity()->getIJ(0,4); + mesh2->getNodalConnectivity()->setIJ(0,4,0); + CPPUNIT_ASSERT(!mesh1->isEqual(mesh2,1e-12)); + CPPUNIT_ASSERT(!mesh1->isEqualWithoutConsideringStr(mesh2,1e-12)); + mesh2->getNodalConnectivity()->setIJ(0,4,tmp2); + CPPUNIT_ASSERT(mesh1->isEqual(mesh2,1e-12)); + CPPUNIT_ASSERT(mesh1->isEqualWithoutConsideringStr(mesh2,1e-12)); + // + MEDCouplingFieldDouble *f1=mesh1->getMeasureField(true); + MEDCouplingFieldDouble *f2=mesh2->getMeasureField(true); + CPPUNIT_ASSERT(f1->isEqual(f2,1e-12,1e-12)); + CPPUNIT_ASSERT(f1->isEqualWithoutConsideringStr(f2,1e-12,1e-12)); + f2->setName("ftest"); + CPPUNIT_ASSERT(!f1->isEqual(f2,1e-12,1e-12)); + CPPUNIT_ASSERT(f1->isEqualWithoutConsideringStr(f2,1e-12,1e-12)); + f1->setName("ftest"); + CPPUNIT_ASSERT(f1->isEqual(f2,1e-12,1e-12)); + CPPUNIT_ASSERT(f1->isEqualWithoutConsideringStr(f2,1e-12,1e-12)); + // + f2->getArray()->setInfoOnComponent(0,"eee"); + CPPUNIT_ASSERT(!f1->isEqual(f2,1e-12,1e-12)); + CPPUNIT_ASSERT(f1->isEqualWithoutConsideringStr(f2,1e-12,1e-12)); + f2->getArray()->setInfoOnComponent(0,""); + CPPUNIT_ASSERT(f1->isEqual(f2,1e-12,1e-12)); + CPPUNIT_ASSERT(f1->isEqualWithoutConsideringStr(f2,1e-12,1e-12)); + // + f2->getArray()->setIJ(1,0,0.123); + CPPUNIT_ASSERT(!f1->isEqual(f2,1e-12,1e-12)); + CPPUNIT_ASSERT(!f1->isEqualWithoutConsideringStr(f2,1e-12,1e-12)); + f2->getArray()->setIJ(1,0,0.125); + CPPUNIT_ASSERT(f1->isEqual(f2,1e-12,1e-12)); + CPPUNIT_ASSERT(f1->isEqualWithoutConsideringStr(f2,1e-12,1e-12)); + // + f1->decrRef(); + f2->decrRef(); + // + mesh1->decrRef(); + mesh2->decrRef(); +} + +void MEDCouplingBasicsTest2::testGetNodeIdsOfCell1() +{ + MEDCouplingUMesh *mesh1=build2DTargetMesh_1(); + std::vector<int> nodeIds; + mesh1->getNodeIdsOfCell(1,nodeIds); + CPPUNIT_ASSERT_EQUAL(3,(int)nodeIds.size()); + CPPUNIT_ASSERT_EQUAL(1,nodeIds[0]); + CPPUNIT_ASSERT_EQUAL(4,nodeIds[1]); + CPPUNIT_ASSERT_EQUAL(2,nodeIds[2]); + std::vector<double> coords; + mesh1->getCoordinatesOfNode(4,coords); + CPPUNIT_ASSERT_EQUAL(2,(int)coords.size()); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.2,coords[0],1e-13); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.2,coords[1],1e-13); + mesh1->decrRef(); +} + +void MEDCouplingBasicsTest2::testGetEdgeRatioField1() +{ + MEDCouplingUMesh *m1=build2DTargetMesh_1(); + m1->setTime(3.4,5,6); m1->setTimeUnit("us"); + int a,b; + MEDCouplingFieldDouble *f1=m1->getEdgeRatioField(); + CPPUNIT_ASSERT_DOUBLES_EQUAL(3.4,f1->getTime(a,b),1.e-14); + CPPUNIT_ASSERT_EQUAL(5,a); CPPUNIT_ASSERT_EQUAL(6,b); + CPPUNIT_ASSERT_EQUAL(std::string(f1->getTimeUnit()),std::string("us")); + CPPUNIT_ASSERT_EQUAL(m1->getNumberOfCells(),f1->getNumberOfTuples()); + CPPUNIT_ASSERT_EQUAL(5,f1->getNumberOfTuples()); + CPPUNIT_ASSERT_EQUAL(1,f1->getNumberOfComponents()); + const double expected1[5]={1.,1.4142135623730951, 1.4142135623730951,1.,1.}; + for(int i=0;i<5;i++) + CPPUNIT_ASSERT_DOUBLES_EQUAL(expected1[i],f1->getIJ(i,0),1e-14); + f1->decrRef(); + m1->decrRef(); + // + m1=build3DSurfTargetMesh_1(); + f1=m1->getEdgeRatioField(); + CPPUNIT_ASSERT_EQUAL(m1->getNumberOfCells(),f1->getNumberOfTuples()); + CPPUNIT_ASSERT_EQUAL(5,f1->getNumberOfTuples()); + CPPUNIT_ASSERT_EQUAL(1,f1->getNumberOfComponents()); + const double expected2[5]={1.4142135623730951, 1.7320508075688772, 1.7320508075688772, 1.4142135623730951, 1.4142135623730951}; + for(int i=0;i<5;i++) + CPPUNIT_ASSERT_DOUBLES_EQUAL(expected2[i],f1->getIJ(i,0),1e-14); + f1->decrRef(); + m1->decrRef(); +} + +void MEDCouplingBasicsTest2::testFillFromAnalytic3() +{ + MEDCouplingUMesh *m=build2DTargetMesh_1(); + MEDCouplingFieldDouble *f1=MEDCouplingFieldDouble::New(ON_CELLS,ONE_TIME); + CPPUNIT_ASSERT_THROW(f1->fillFromAnalytic(1,"y+x"),INTERP_KERNEL::Exception); + f1->setMesh(m); + f1->setName("myField"); + f1->fillFromAnalytic(1,"y+x"); + f1->checkCoherency(); + CPPUNIT_ASSERT(std::string(f1->getName())=="myField"); + CPPUNIT_ASSERT(f1->getTypeOfField()==ON_CELLS); + CPPUNIT_ASSERT(f1->getTimeDiscretization()==ONE_TIME); + CPPUNIT_ASSERT_EQUAL(1,f1->getNumberOfComponents()); + CPPUNIT_ASSERT_EQUAL(5,f1->getNumberOfTuples()); + double values1[5]={-0.1,0.23333333333333336,0.56666666666666665,0.4,0.9}; + const double *tmp=f1->getArray()->getConstPointer(); + std::transform(tmp,tmp+5,values1,values1,std::minus<double>()); + std::transform(values1,values1+5,values1,std::ptr_fun<double,double>(fabs)); + double max=*std::max_element(values1,values1+5); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.,max,1.e-12); + f1->decrRef(); + // + f1=MEDCouplingFieldDouble::New(ON_NODES,CONST_ON_TIME_INTERVAL); + f1->setMesh(m); + f1->setEndTime(1.2,3,4); + f1->fillFromAnalytic(1,"y+2*x"); + f1->checkCoherency(); + CPPUNIT_ASSERT(f1->getTypeOfField()==ON_NODES); + CPPUNIT_ASSERT(f1->getTimeDiscretization()==CONST_ON_TIME_INTERVAL); + CPPUNIT_ASSERT_EQUAL(1,f1->getNumberOfComponents()); + CPPUNIT_ASSERT_EQUAL(9,f1->getNumberOfTuples()); + double values2[9]={-0.9,0.1,1.1,-0.4,0.6,1.6,0.1,1.1,2.1}; + tmp=f1->getArray()->getConstPointer(); + std::transform(tmp,tmp+9,values2,values2,std::minus<double>()); + std::transform(values2,values2+9,values2,std::ptr_fun<double,double>(fabs)); + max=*std::max_element(values2,values2+9); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.,max,1.e-12); + f1->decrRef(); + f1=MEDCouplingFieldDouble::New(ON_NODES,LINEAR_TIME); + f1->setMesh(m); + f1->setEndTime(1.2,3,4); + f1->fillFromAnalytic(1,"2.*x+y"); + f1->checkCoherency(); + CPPUNIT_ASSERT(f1->getTypeOfField()==ON_NODES); + CPPUNIT_ASSERT(f1->getTimeDiscretization()==LINEAR_TIME); + CPPUNIT_ASSERT_EQUAL(1,f1->getNumberOfComponents()); + CPPUNIT_ASSERT_EQUAL(9,f1->getNumberOfTuples()); + tmp=f1->getArray()->getConstPointer(); + double values2Bis[9]={-0.9,0.1,1.1,-0.4,0.6,1.6,0.1,1.1,2.1}; + double values2BisBis[9]; + std::transform(tmp,tmp+9,values2Bis,values2BisBis,std::minus<double>()); + std::transform(values2,values2+9,values2BisBis,std::ptr_fun<double,double>(fabs)); + max=*std::max_element(values2BisBis,values2BisBis+9); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.,max,1.e-12); + tmp=f1->getEndArray()->getConstPointer(); + std::transform(tmp,tmp+9,values2Bis,values2BisBis,std::minus<double>()); + std::transform(values2,values2+9,values2BisBis,std::ptr_fun<double,double>(fabs)); + max=*std::max_element(values2BisBis,values2BisBis+9); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.,max,1.e-12); + f1->decrRef(); + // + f1=MEDCouplingFieldDouble::New(ON_NODES,NO_TIME); + f1->setMesh(m); + f1->fillFromAnalytic(2,"(x+y)*IVec+2*(x+y)*JVec"); + f1->checkCoherency(); + CPPUNIT_ASSERT(f1->getTypeOfField()==ON_NODES); + CPPUNIT_ASSERT(f1->getTimeDiscretization()==NO_TIME); + CPPUNIT_ASSERT_EQUAL(2,f1->getNumberOfComponents()); + CPPUNIT_ASSERT_EQUAL(9,f1->getNumberOfTuples()); + double values3[18]={-0.6,-1.2,-0.1,-0.2,0.4,0.8,-0.1,-0.2,0.4,0.8,0.9,1.8,0.4,0.8,0.9,1.8,1.4,2.8}; + tmp=f1->getArray()->getConstPointer(); + std::transform(tmp,tmp+18,values3,values3,std::minus<double>()); + std::transform(values3,values3+18,values3,std::ptr_fun<double,double>(fabs)); + max=*std::max_element(values3,values3+18); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.,max,1.e-12); + double values4[2]; + f1->accumulate(values4); + CPPUNIT_ASSERT_DOUBLES_EQUAL(3.6,values4[0],1.e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(7.2,values4[1],1.e-12); + f1->integral(true,values4); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.5,values4[0],1.e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,values4[1],1.e-12); + f1->decrRef(); + // + f1=MEDCouplingFieldDouble::New(ON_NODES,NO_TIME); + f1->setMesh(m); + CPPUNIT_ASSERT_THROW(f1->fillFromAnalytic(1,"1./(x-0.2)"),INTERP_KERNEL::Exception); + // + m->decrRef(); + f1->decrRef(); +} + +void MEDCouplingBasicsTest2::testFieldDoubleOpEqual1() +{ + MEDCouplingUMesh *m=build2DTargetMesh_1(); + MEDCouplingFieldDouble *f1=MEDCouplingFieldDouble::New(ON_CELLS,ONE_TIME); + CPPUNIT_ASSERT_THROW((*f1)=0.07,INTERP_KERNEL::Exception); + f1->setMesh(m); + (*f1)=0.07; + f1->checkCoherency(); + CPPUNIT_ASSERT_EQUAL(1,f1->getNumberOfComponents()); + CPPUNIT_ASSERT_EQUAL(5,f1->getNumberOfTuples()); + for(int i=0;i<5;i++) + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.07,f1->getIJ(i,0),1e-16); + (*f1)=0.09; + f1->checkCoherency(); + CPPUNIT_ASSERT_EQUAL(1,f1->getNumberOfComponents()); + CPPUNIT_ASSERT_EQUAL(5,f1->getNumberOfTuples()); + for(int i=0;i<5;i++) + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.09,f1->getIJ(i,0),1e-16); + f1->decrRef(); + // + f1=MEDCouplingFieldDouble::New(ON_NODES,LINEAR_TIME); + f1->setEndTime(4.5,2,3); + f1->setMesh(m); + (*f1)=0.08; + f1->checkCoherency(); + CPPUNIT_ASSERT_EQUAL(1,f1->getNumberOfComponents()); + CPPUNIT_ASSERT_EQUAL(9,f1->getNumberOfTuples()); + for(int i=0;i<9;i++) + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.08,f1->getIJ(i,0),1e-16); + CPPUNIT_ASSERT_EQUAL(1,f1->getEndArray()->getNumberOfComponents()); + CPPUNIT_ASSERT_EQUAL(9,f1->getEndArray()->getNumberOfTuples()); + for(int i=0;i<9;i++) + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.08,f1->getEndArray()->getIJ(i,0),1e-16); + f1->decrRef(); + // + m->decrRef(); +} + +void MEDCouplingBasicsTest2::testAreaBary3D2() +{ + const double coordsForHexa8[24]={ + -75.45749305371, 180.95495078401, 39.515472018008, + -9.755591679144, 23.394927935279, 5.108794294848, + 14.337630157832, 61.705351002702, 160.42422501908, + -27.273893776752, 167.567731083961, 192.830034145464, + // + 99.857193154796,264.499264735586,-8.287335493412, + 144.939882761126,156.38626563134,-31.896173894226, + 161.34096835726,182.4654895809,73.832387065572, + 132.680430393685,255.37973247196,96.15235602819 + }; + const double volHexa8=3258520.29637466; + const double baryHexa8[3]={43.925705821778, 155.31893955289, 65.874418109644}; + + const double coordsForPenta6[18]={ + -68.199829618726,178.938498373416,62.608505919588, + 8.461744647847,76.653979804423,165.00018874933, + -27.273893776752,167.567731083961,192.830034145464, + // + 106.586501038965,262.629609408327,13.124533008813, + 155.465082847275,197.414118382622,78.408350795821, + 132.680430393685,255.37973247196,96.15235602819 + }; + const double volPenta6=944849.868507338; + const double baryPenta6[3]={39.631002313543,182.692711783428,106.98540473964}; + + const double coordsForPyra5[15]={ + 132.680430393685,255.37973247196,96.15235602819, + -27.273893776752,167.567731083961,192.830034145464, + 8.461744647847,76.653979804423,165.00018874933, + 155.465082847275,197.414118382622,78.408350795821, + // + -68.199829618726,178.938498373416,62.608505919588 + }; + const double volPyra5=756943.92980254; + const double baryPyra5[3]={29.204294116618,172.540129749156,118.01035951483}; + MEDCouplingUMesh *mesh=MEDCouplingUMesh::New("Bary3D2",3); + DataArrayDouble *coo=DataArrayDouble::New(); + coo->alloc(19,3); + double *tmp=std::copy(coordsForHexa8,coordsForHexa8+24,coo->getPointer()); + tmp=std::copy(coordsForPenta6,coordsForPenta6+18,tmp); + std::copy(coordsForPyra5,coordsForPyra5+15,tmp); + mesh->setCoords(coo); + coo->decrRef(); + // + int tmpConn[8]={0,1,2,3,4,5,6,7}; + mesh->allocateCells(3); + mesh->insertNextCell(INTERP_KERNEL::NORM_HEXA8,8,tmpConn); + std::transform(tmpConn,tmpConn+8,tmpConn,std::bind2nd(std::plus<int>(),8)); + mesh->insertNextCell(INTERP_KERNEL::NORM_PENTA6,6,tmpConn); + std::transform(tmpConn,tmpConn+8,tmpConn,std::bind2nd(std::plus<int>(),6)); + mesh->insertNextCell(INTERP_KERNEL::NORM_PYRA5,5,tmpConn); + mesh->finishInsertingCells(); + mesh->checkCoherency(); + bool isMerged; + int newNebOfNodes; + DataArrayInt *da=mesh->mergeNodes(1e-7,isMerged,newNebOfNodes); + da->decrRef(); + CPPUNIT_ASSERT_EQUAL(12,newNebOfNodes); + MEDCouplingFieldDouble *vols=mesh->getMeasureField(true); + CPPUNIT_ASSERT_EQUAL(3,vols->getNumberOfTuples()); + CPPUNIT_ASSERT_EQUAL(1,vols->getNumberOfComponents()); + CPPUNIT_ASSERT_DOUBLES_EQUAL(volHexa8,vols->getIJ(0,0),1e-6); + CPPUNIT_ASSERT_DOUBLES_EQUAL(volPenta6,vols->getIJ(1,0),1e-7); + CPPUNIT_ASSERT_DOUBLES_EQUAL(volPyra5,vols->getIJ(2,0),1e-7); + vols->decrRef(); + DataArrayDouble *bary=mesh->getBarycenterAndOwner(); + CPPUNIT_ASSERT_EQUAL(3,bary->getNumberOfTuples()); + CPPUNIT_ASSERT_EQUAL(3,bary->getNumberOfComponents()); + CPPUNIT_ASSERT_DOUBLES_EQUAL(baryHexa8[0],bary->getIJ(0,0),1e-11); + CPPUNIT_ASSERT_DOUBLES_EQUAL(baryHexa8[1],bary->getIJ(0,1),1e-11); + CPPUNIT_ASSERT_DOUBLES_EQUAL(baryHexa8[2],bary->getIJ(0,2),1e-11); + CPPUNIT_ASSERT_DOUBLES_EQUAL(baryPenta6[0],bary->getIJ(1,0),1e-11); + CPPUNIT_ASSERT_DOUBLES_EQUAL(baryPenta6[1],bary->getIJ(1,1),1e-11); + CPPUNIT_ASSERT_DOUBLES_EQUAL(baryPenta6[2],bary->getIJ(1,2),1e-11); + CPPUNIT_ASSERT_DOUBLES_EQUAL(baryPyra5[0],bary->getIJ(2,0),1e-11); + CPPUNIT_ASSERT_DOUBLES_EQUAL(baryPyra5[1],bary->getIJ(2,1),1e-11); + CPPUNIT_ASSERT_DOUBLES_EQUAL(baryPyra5[2],bary->getIJ(2,2),1e-11); + bary->decrRef(); + // + mesh->decrRef(); +} diff --git a/src/medtool/src/MEDCoupling/Test/MEDCouplingBasicsTest2.hxx b/src/medtool/src/MEDCoupling/Test/MEDCouplingBasicsTest2.hxx new file mode 100644 index 000000000..f514d7b31 --- /dev/null +++ b/src/medtool/src/MEDCoupling/Test/MEDCouplingBasicsTest2.hxx @@ -0,0 +1,128 @@ +// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 +// 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 __MEDCOUPLINGBASICSTEST2_HXX__ +#define __MEDCOUPLINGBASICSTEST2_HXX__ + +#include "MEDCouplingBasicsTest.hxx" + +#include <map> +#include <vector> + +namespace ParaMEDMEM +{ + class DataArrayDouble; + class MEDCouplingUMesh; + class MEDCouplingFieldDouble; + class MEDCouplingMultiFields; + + class MEDCouplingBasicsTest2 : public MEDCouplingBasicsTest + { + CPPUNIT_TEST_SUITE(MEDCouplingBasicsTest2); + CPPUNIT_TEST( testGaussPointField1 ); + CPPUNIT_TEST( testGaussPointNEField1 ); + CPPUNIT_TEST( testCellOrientation1 ); + CPPUNIT_TEST( testCellOrientation2 ); + CPPUNIT_TEST( testCellOrientation3 ); + CPPUNIT_TEST( testPolyhedronBarycenter ); + CPPUNIT_TEST( testNormL12Integ1D ); + CPPUNIT_TEST( testAreaBary2D ); + CPPUNIT_TEST( testAreaBary3D ); + CPPUNIT_TEST( testRenumberCellsForFields ); + CPPUNIT_TEST( testRenumberNodesForFields ); + CPPUNIT_TEST( testConvertQuadraticCellsToLinear ); + CPPUNIT_TEST( testCheckGeoEquivalWith ); + CPPUNIT_TEST( testCheckGeoEquivalWith2 ); + CPPUNIT_TEST( testCopyTinyStringsFromOnFields ); + CPPUNIT_TEST( testTryToShareSameCoordsPermute ); + CPPUNIT_TEST( testTryToShareSameCoordsPermute2 ); + CPPUNIT_TEST( testChangeUnderlyingMesh1 ); + CPPUNIT_TEST( testGetMaxValue1 ); + CPPUNIT_TEST( testSubstractInPlaceDM1 ); + CPPUNIT_TEST( testDotCrossProduct1 ); + CPPUNIT_TEST( testMinMaxFields1 ); + CPPUNIT_TEST( testApplyLin1 ); + CPPUNIT_TEST( testGetIdsInRange1 ); + CPPUNIT_TEST( testBuildSubPart1 ); + CPPUNIT_TEST( testDoublyContractedProduct1 ); + CPPUNIT_TEST( testDeterminant1 ); + CPPUNIT_TEST( testEigenValues1 ); + CPPUNIT_TEST( testEigenVectors1 ); + CPPUNIT_TEST( testInverse1 ); + CPPUNIT_TEST( testTrace1 ); + CPPUNIT_TEST( testDeviator1 ); + CPPUNIT_TEST( testMagnitude1 ); + CPPUNIT_TEST( testMaxPerTuple1 ); + CPPUNIT_TEST( testChangeNbOfComponents ); + CPPUNIT_TEST( testSortPerTuple1 ); + CPPUNIT_TEST( testIsEqualWithoutConsideringStr1 ); + CPPUNIT_TEST( testGetNodeIdsOfCell1 ); + CPPUNIT_TEST( testGetEdgeRatioField1 ); + CPPUNIT_TEST( testFillFromAnalytic3 ); + CPPUNIT_TEST( testFieldDoubleOpEqual1 ); + CPPUNIT_TEST( testAreaBary3D2 ); + CPPUNIT_TEST_SUITE_END(); + public: + void testGaussPointField1(); + void testGaussPointNEField1(); + void testCellOrientation1(); + void testCellOrientation2(); + void testCellOrientation3(); + void testPolyhedronBarycenter(); + void testNormL12Integ1D(); + void testAreaBary2D(); + void testAreaBary3D(); + void testRenumberCellsForFields(); + void testRenumberNodesForFields(); + void testConvertQuadraticCellsToLinear(); + void testCheckGeoEquivalWith(); + void testCheckGeoEquivalWith2(); + void testCopyTinyStringsFromOnFields(); + void testTryToShareSameCoordsPermute(); + void testTryToShareSameCoordsPermute2(); + void testChangeUnderlyingMesh1(); + void testGetMaxValue1(); + void testSubstractInPlaceDM1(); + void testDotCrossProduct1(); + void testMinMaxFields1(); + void testApplyLin1(); + void testGetIdsInRange1(); + void testBuildSubPart1(); + void testDoublyContractedProduct1(); + void testDeterminant1(); + void testEigenValues1(); + void testEigenVectors1(); + void testInverse1(); + void testTrace1(); + void testDeviator1(); + void testMagnitude1(); + void testMaxPerTuple1(); + void testChangeNbOfComponents(); + void testSortPerTuple1(); + void testIsEqualWithoutConsideringStr1(); + void testGetNodeIdsOfCell1(); + void testGetEdgeRatioField1(); + void testFillFromAnalytic3(); + void testFieldDoubleOpEqual1(); + void testAreaBary3D2(); + }; +} + +#endif diff --git a/src/medtool/src/MEDCoupling/Test/MEDCouplingBasicsTest3.cxx b/src/medtool/src/MEDCoupling/Test/MEDCouplingBasicsTest3.cxx new file mode 100644 index 000000000..358d1c4a1 --- /dev/null +++ b/src/medtool/src/MEDCoupling/Test/MEDCouplingBasicsTest3.cxx @@ -0,0 +1,2467 @@ +// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 +// 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 "MEDCouplingBasicsTest3.hxx" +#include "MEDCouplingUMesh.hxx" +#include "MEDCouplingCMesh.hxx" +#include "MEDCouplingExtrudedMesh.hxx" +#include "MEDCouplingFieldDouble.hxx" +#include "MEDCouplingMemArray.hxx" +#include "MEDCouplingGaussLocalization.hxx" + +#include <cmath> +#include <functional> +#include <iterator> + +using namespace ParaMEDMEM; + +void MEDCouplingBasicsTest3::testGetMeasureFieldCMesh1() +{ + MEDCouplingCMesh *m=MEDCouplingCMesh::New(); + DataArrayDouble *da=DataArrayDouble::New(); + const double discX[4]={2.3,3.4,5.8,10.2}; + const double discY[3]={12.3,23.4,45.8}; + const double discZ[5]={-0.7,1.2,1.25,2.13,2.67}; + da->alloc(4,1); + std::copy(discX,discX+4,da->getPointer()); + m->setCoordsAt(0,da); + da->decrRef(); + m->checkCoherency(); + CPPUNIT_ASSERT_EQUAL(4,m->getNumberOfNodes()); + CPPUNIT_ASSERT_EQUAL(3,m->getNumberOfCells()); + CPPUNIT_ASSERT_EQUAL(1,m->getSpaceDimension()); + MEDCouplingFieldDouble *f=m->getMeasureField(true); + CPPUNIT_ASSERT_EQUAL(3,f->getNumberOfTuples()); + CPPUNIT_ASSERT_EQUAL(1,f->getNumberOfComponents()); + const double expected1[3]={1.1,2.4,4.4}; + for(int i=0;i<3;i++) + CPPUNIT_ASSERT_DOUBLES_EQUAL(expected1[i],f->getIJ(i,0),1e-12); + f->decrRef(); + DataArrayDouble *coords=m->getCoordinatesAndOwner(); + CPPUNIT_ASSERT_EQUAL(4,coords->getNumberOfTuples()); + CPPUNIT_ASSERT_EQUAL(1,coords->getNumberOfComponents()); + for(int i=0;i<4;i++) + CPPUNIT_ASSERT_DOUBLES_EQUAL(discX[i],coords->getIJ(i,0),1e-12); + coords->decrRef(); + coords=m->getBarycenterAndOwner(); + CPPUNIT_ASSERT_EQUAL(3,coords->getNumberOfTuples()); + CPPUNIT_ASSERT_EQUAL(1,coords->getNumberOfComponents()); + const double expected1_3[3]={2.85,4.6,8.}; + for(int i=0;i<3;i++) + CPPUNIT_ASSERT_DOUBLES_EQUAL(expected1_3[i],coords->getIJ(i,0),1e-12); + coords->decrRef(); + // + da=DataArrayDouble::New(); + da->alloc(3,1); + std::copy(discY,discY+3,da->getPointer()); + m->setCoordsAt(1,da); + da->decrRef(); + m->checkCoherency(); + CPPUNIT_ASSERT_EQUAL(12,m->getNumberOfNodes()); + CPPUNIT_ASSERT_EQUAL(6,m->getNumberOfCells()); + CPPUNIT_ASSERT_EQUAL(2,m->getSpaceDimension()); + f=m->getMeasureField(true); + CPPUNIT_ASSERT_EQUAL(6,f->getNumberOfTuples()); + CPPUNIT_ASSERT_EQUAL(1,f->getNumberOfComponents()); + const double expected2[6]={12.21,26.64,48.84,24.64,53.76,98.56}; + for(int i=0;i<6;i++) + CPPUNIT_ASSERT_DOUBLES_EQUAL(expected2[i],f->getIJ(i,0),1e-12); + f->decrRef(); + coords=m->getCoordinatesAndOwner(); + CPPUNIT_ASSERT_EQUAL(12,coords->getNumberOfTuples()); + CPPUNIT_ASSERT_EQUAL(2,coords->getNumberOfComponents()); + const double expected2_2[24]={2.3,12.3,3.4,12.3,5.8,12.3,10.2,12.3, 2.3,23.4,3.4,23.4,5.8,23.4,10.2,23.4, 2.3,45.8,3.4,45.8,5.8,45.8,10.2,45.8}; + for(int i=0;i<24;i++) + CPPUNIT_ASSERT_DOUBLES_EQUAL(expected2_2[i],coords->getIJ(0,i),1e-12); + coords->decrRef(); + coords=m->getBarycenterAndOwner(); + CPPUNIT_ASSERT_EQUAL(6,coords->getNumberOfTuples()); + CPPUNIT_ASSERT_EQUAL(2,coords->getNumberOfComponents()); + const double expected2_3[12]={2.85,17.85,4.6,17.85,8.,17.85, 2.85,34.6,4.6,34.6,8.,34.6}; + for(int i=0;i<12;i++) + CPPUNIT_ASSERT_DOUBLES_EQUAL(expected2_3[i],coords->getIJ(0,i),1e-12); + coords->decrRef(); + // + da=DataArrayDouble::New(); + da->alloc(5,1); + std::copy(discZ,discZ+5,da->getPointer()); + m->setCoordsAt(2,da); + da->decrRef(); + m->checkCoherency(); + CPPUNIT_ASSERT_EQUAL(60,m->getNumberOfNodes()); + CPPUNIT_ASSERT_EQUAL(24,m->getNumberOfCells()); + CPPUNIT_ASSERT_EQUAL(3,m->getSpaceDimension()); + f=m->getMeasureField(true); + CPPUNIT_ASSERT_EQUAL(24,f->getNumberOfTuples()); + CPPUNIT_ASSERT_EQUAL(1,f->getNumberOfComponents()); + const double expected3[24]={23.199, 50.616, 92.796, 46.816, 102.144, 187.264, 0.6105, 1.332, 2.442, 1.232, 2.688, 4.928, 10.7448, 23.4432, 42.9792, 21.6832, 47.3088, 86.7328, 6.5934, 14.3856, 26.3736, 13.3056, 29.0304, 53.2224}; + for(int i=0;i<24;i++) + CPPUNIT_ASSERT_DOUBLES_EQUAL(expected3[i],f->getIJ(i,0),1e-12); + f->decrRef(); + coords=m->getCoordinatesAndOwner(); + CPPUNIT_ASSERT_EQUAL(60,coords->getNumberOfTuples()); + CPPUNIT_ASSERT_EQUAL(3,coords->getNumberOfComponents()); + const double expected3_2[180]={ + 2.3,12.3,-0.7, 3.4,12.3,-0.7, 5.8,12.3,-0.7, 10.2,12.3,-0.7, 2.3,23.4,-0.7, 3.4,23.4,-0.7, 5.8,23.4,-0.7, 10.2,23.4,-0.7, 2.3,45.8,-0.7, 3.4,45.8,-0.7, 5.8,45.8,-0.7, 10.2,45.8,-0.7, + 2.3,12.3,1.2, 3.4,12.3,1.2, 5.8,12.3,1.2, 10.2,12.3,1.2, 2.3,23.4,1.2, 3.4,23.4,1.2, 5.8,23.4,1.2, 10.2,23.4,1.2, 2.3,45.8,1.2, 3.4,45.8,1.2, 5.8,45.8,1.2, 10.2,45.8,1.2, + 2.3,12.3,1.25, 3.4,12.3,1.25, 5.8,12.3,1.25, 10.2,12.3,1.25, 2.3,23.4,1.25, 3.4,23.4,1.25, 5.8,23.4,1.25, 10.2,23.4,1.25, 2.3,45.8,1.25, 3.4,45.8,1.25, 5.8,45.8,1.25, 10.2,45.8,1.25, + 2.3,12.3,2.13, 3.4,12.3,2.13, 5.8,12.3,2.13, 10.2,12.3,2.13, 2.3,23.4,2.13, 3.4,23.4,2.13, 5.8,23.4,2.13, 10.2,23.4,2.13, 2.3,45.8,2.13, 3.4,45.8,2.13, 5.8,45.8,2.13, 10.2,45.8,2.13, + 2.3,12.3,2.67, 3.4,12.3,2.67, 5.8,12.3,2.67, 10.2,12.3,2.67, 2.3,23.4,2.67, 3.4,23.4,2.67, 5.8,23.4,2.67, 10.2,23.4,2.67, 2.3,45.8,2.67, 3.4,45.8,2.67, 5.8,45.8,2.67, 10.2,45.8,2.67 + }; + for(int i=0;i<180;i++) + CPPUNIT_ASSERT_DOUBLES_EQUAL(expected3_2[i],coords->getIJ(0,i),1e-12); + coords->decrRef(); + coords=m->getBarycenterAndOwner(); + CPPUNIT_ASSERT_EQUAL(24,coords->getNumberOfTuples()); + CPPUNIT_ASSERT_EQUAL(3,coords->getNumberOfComponents()); + const double expected3_3[72]={ + 2.85,17.85,0.25,4.6,17.85,0.25,8.,17.85,0.25, 2.85,34.6,0.25,4.6,34.6,0.25,8.,34.6,0.25, + 2.85,17.85,1.225,4.6,17.85,1.225,8.,17.85,1.225, 2.85,34.6,1.225,4.6,34.6,1.225,8.,34.6,1.225, + 2.85,17.85,1.69,4.6,17.85,1.69,8.,17.85,1.69, 2.85,34.6,1.69,4.6,34.6,1.69,8.,34.6,1.69, + 2.85,17.85,2.4,4.6,17.85,2.4,8.,17.85,2.4, 2.85,34.6,2.4,4.6,34.6,2.4,8.,34.6,2.4 + }; + for(int i=0;i<72;i++) + CPPUNIT_ASSERT_DOUBLES_EQUAL(expected3_3[i],coords->getIJ(0,i),1e-12); + coords->decrRef(); + // + m->decrRef(); +} + +void MEDCouplingBasicsTest3::testFieldDoubleZipCoords1() +{ + MEDCouplingUMesh *m=build2DTargetMeshMergeNode_1(); + MEDCouplingFieldDouble *f=m->fillFromAnalytic(ON_NODES,2,"x*2."); + f->getArray()->setInfoOnComponent(0,"titi"); + f->getArray()->setInfoOnComponent(1,"tutu"); + f->checkCoherency(); + CPPUNIT_ASSERT_EQUAL(18,f->getNumberOfTuples()); + CPPUNIT_ASSERT_EQUAL(2,f->getNumberOfComponents()); + const double expected1[36]={-0.6, -0.6, 0.4, 0.4, 1.4, 1.4, -0.6, -0.6, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 1.4, 1.4, -0.6, -0.6, 0.4, 0.4, 1.4, 1.4, -0.6, -0.6, 1.4, 1.4, -0.6, -0.6, 0.4, 0.4, 1.4, 1.4, 0.4, 0.4}; + for(int i=0;i<36;i++) + CPPUNIT_ASSERT_DOUBLES_EQUAL(expected1[i],f->getIJ(0,i),1e-12); + CPPUNIT_ASSERT(f->zipCoords()); + f->checkCoherency(); + const double expected2[30]={-0.6, -0.6, 1.4, 1.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 1.4, 1.4, -0.6, -0.6, 0.4, 0.4, 1.4, 1.4, 1.4, 1.4, -0.6, -0.6, 0.4, 0.4, 1.4, 1.4, 0.4, 0.4}; + for(int i=0;i<30;i++) + CPPUNIT_ASSERT_DOUBLES_EQUAL(expected2[i],f->getIJ(0,i),1e-12); + CPPUNIT_ASSERT(!f->zipCoords()); + f->checkCoherency(); + for(int i=0;i<30;i++) + CPPUNIT_ASSERT_DOUBLES_EQUAL(expected2[i],f->getIJ(0,i),1e-12); + CPPUNIT_ASSERT(std::string(f->getArray()->getInfoOnComponent(0))=="titi"); + CPPUNIT_ASSERT(std::string(f->getArray()->getInfoOnComponent(1))=="tutu"); + f->decrRef(); + m->decrRef(); +} + +void MEDCouplingBasicsTest3::testFieldDoubleZipConnectivity1() +{ + MEDCouplingUMesh *m1=build2DTargetMesh_1(); + MEDCouplingUMesh *m2=build2DTargetMesh_1(); + const int cells1[3]={2,3,4}; + MEDCouplingPointSet *m3_1=m2->buildPartOfMySelf(cells1,cells1+3,true); + MEDCouplingUMesh *m3=dynamic_cast<MEDCouplingUMesh *>(m3_1); + CPPUNIT_ASSERT(m3); + m2->decrRef(); + MEDCouplingUMesh *m4=build2DSourceMesh_1(); + MEDCouplingUMesh *m5=MEDCouplingUMesh::MergeUMeshes(m1,m3); + m1->decrRef(); + m3->decrRef(); + MEDCouplingUMesh *m6=MEDCouplingUMesh::MergeUMeshes(m5,m4); + m4->decrRef(); + m5->decrRef(); + // + CPPUNIT_ASSERT_EQUAL(10,m6->getNumberOfCells()); + CPPUNIT_ASSERT_EQUAL(22,m6->getNumberOfNodes()); + bool areNodesMerged; + int newNbOfNodes; + DataArrayInt *arr=m6->mergeNodes(1e-13,areNodesMerged,newNbOfNodes); + CPPUNIT_ASSERT_EQUAL(9,m6->getNumberOfNodes()); + arr->decrRef(); + MEDCouplingFieldDouble *f=m6->fillFromAnalytic(ON_CELLS,2,"x"); + MEDCouplingFieldDouble *f2=m6->fillFromAnalytic(ON_NODES,2,"x"); + CPPUNIT_ASSERT_EQUAL(10,f->getNumberOfTuples()); + CPPUNIT_ASSERT_EQUAL(2,f->getNumberOfComponents()); + const double expected1[20]={-0.05, -0.05, 0.3666666666666667, 0.3666666666666667, 0.53333333333333321, 0.53333333333333321, + -0.05, -0.05, 0.45, 0.45, 0.53333333333333321, 0.53333333333333321, -0.05, -0.05, 0.45, 0.45, + 0.36666666666666659, 0.36666666666666659, 0.033333333333333326, 0.033333333333333326}; + for(int i=0;i<20;i++) + CPPUNIT_ASSERT_DOUBLES_EQUAL(expected1[i],f->getIJ(0,i),1e-12); + f->getArray()->setInfoOnComponent(0,"titi"); + f->getArray()->setInfoOnComponent(1,"tutu"); + f->checkCoherency(); + CPPUNIT_ASSERT(f->zipConnectivity(0)); + const double expected2[14]={-0.05, -0.05, 0.3666666666666667, 0.3666666666666667, 0.53333333333333321, 0.53333333333333321, + -0.05, -0.05, 0.45, 0.45, 0.36666666666666659, 0.36666666666666659, 0.033333333333333326, 0.033333333333333326}; + CPPUNIT_ASSERT_EQUAL(7,f->getNumberOfTuples()); + CPPUNIT_ASSERT_EQUAL(2,f->getNumberOfComponents()); + for(int i=0;i<14;i++) + CPPUNIT_ASSERT_DOUBLES_EQUAL(expected2[i],f->getIJ(0,i),1e-12); + CPPUNIT_ASSERT(std::string(f->getArray()->getInfoOnComponent(0))=="titi"); + CPPUNIT_ASSERT(std::string(f->getArray()->getInfoOnComponent(1))=="tutu"); + CPPUNIT_ASSERT(!f->zipConnectivity(0)); + f->decrRef(); + // + const double expected3[18]={-0.3, -0.3, 0.2, 0.2, 0.7, 0.7, -0.3, -0.3, 0.2, 0.2, 0.7, 0.7, + -0.3, -0.3, 0.2, 0.2, 0.7, 0.7}; + CPPUNIT_ASSERT_EQUAL(9,f2->getNumberOfTuples()); + CPPUNIT_ASSERT_EQUAL(2,f2->getNumberOfComponents()); + for(int i=0;i<18;i++) + CPPUNIT_ASSERT_DOUBLES_EQUAL(expected3[i],f2->getIJ(0,i),1e-12); + CPPUNIT_ASSERT(f2->zipConnectivity(0)); + CPPUNIT_ASSERT_EQUAL(9,f2->getNumberOfTuples()); + CPPUNIT_ASSERT_EQUAL(2,f2->getNumberOfComponents()); + for(int i=0;i<18;i++) + CPPUNIT_ASSERT_DOUBLES_EQUAL(expected3[i],f2->getIJ(0,i),1e-12); + f2->decrRef(); + // + m6->decrRef(); +} + +void MEDCouplingBasicsTest3::testDaDoubleRenumber1() +{ + DataArrayDouble *a=DataArrayDouble::New(); + a->alloc(7,2); + a->setInfoOnComponent(0,"toto"); + a->setInfoOnComponent(1,"tata"); + const double arr1[14]={1.1,11.1,2.1,12.1,3.1,13.1,4.1,14.1,5.1,15.1,6.1,16.1,7.1,17.1}; + std::copy(arr1,arr1+14,a->getPointer()); + // + const int arr2[7]={3,1,0,6,5,4,2}; + DataArrayDouble *b=a->renumber(arr2); + CPPUNIT_ASSERT_EQUAL(7,b->getNumberOfTuples()); + CPPUNIT_ASSERT_EQUAL(2,b->getNumberOfComponents()); + CPPUNIT_ASSERT(std::string(b->getInfoOnComponent(0))=="toto"); + CPPUNIT_ASSERT(std::string(b->getInfoOnComponent(1))=="tata"); + const double expected1[14]={3.1, 13.1, 2.1, 12.1, 7.1, 17.1, 1.1, 11.1, 6.1, 16.1, 5.1, 15.1, 4.1, 14.1}; + for(int i=0;i<14;i++) + CPPUNIT_ASSERT_DOUBLES_EQUAL(expected1[i],b->getIJ(0,i),1e-14); + b->decrRef(); + a->decrRef(); + // + DataArrayInt *c=DataArrayInt::New(); + c->alloc(7,2); + c->setInfoOnComponent(0,"toto"); + c->setInfoOnComponent(1,"tata"); + const int arr3[14]={1,11,2,12,3,13,4,14,5,15,6,16,7,17}; + std::copy(arr3,arr3+14,c->getPointer()); + DataArrayInt *d=c->renumber(arr2); + CPPUNIT_ASSERT_EQUAL(7,d->getNumberOfTuples()); + CPPUNIT_ASSERT_EQUAL(2,d->getNumberOfComponents()); + CPPUNIT_ASSERT(std::string(d->getInfoOnComponent(0))=="toto"); + CPPUNIT_ASSERT(std::string(d->getInfoOnComponent(1))=="tata"); + const int expected2[14]={3, 13, 2, 12, 7, 17, 1, 11, 6, 16, 5, 15, 4, 14}; + for(int i=0;i<14;i++) + CPPUNIT_ASSERT_EQUAL(expected2[i],d->getIJ(0,i)); + c->decrRef(); + d->decrRef(); +} + +void MEDCouplingBasicsTest3::testDaDoubleRenumberAndReduce1() +{ + DataArrayDouble *a=DataArrayDouble::New(); + a->alloc(7,2); + a->setInfoOnComponent(0,"toto"); + a->setInfoOnComponent(1,"tata"); + const double arr1[14]={1.1,11.1,2.1,12.1,3.1,13.1,4.1,14.1,5.1,15.1,6.1,16.1,7.1,17.1}; + std::copy(arr1,arr1+14,a->getPointer()); + // + const int arr2[7]={2,-1,1,-1,0,4,3}; + DataArrayDouble *b=a->renumberAndReduce(arr2,5); + CPPUNIT_ASSERT_EQUAL(5,b->getNumberOfTuples()); + CPPUNIT_ASSERT_EQUAL(2,b->getNumberOfComponents()); + CPPUNIT_ASSERT(std::string(b->getInfoOnComponent(0))=="toto"); + CPPUNIT_ASSERT(std::string(b->getInfoOnComponent(1))=="tata"); + const double expected1[10]={5.1,15.1,3.1,13.1,1.1,11.1,7.1,17.1,6.1,16.1}; + for(int i=0;i<10;i++) + CPPUNIT_ASSERT_DOUBLES_EQUAL(expected1[i],b->getIJ(0,i),1e-14); + b->decrRef(); + a->decrRef(); + // + DataArrayInt *c=DataArrayInt::New(); + c->alloc(7,2); + c->setInfoOnComponent(0,"toto"); + c->setInfoOnComponent(1,"tata"); + const int arr3[14]={1,11,2,12,3,13,4,14,5,15,6,16,7,17}; + std::copy(arr3,arr3+14,c->getPointer()); + DataArrayInt *d=c->renumberAndReduce(arr2,5); + CPPUNIT_ASSERT_EQUAL(5,d->getNumberOfTuples()); + CPPUNIT_ASSERT_EQUAL(2,d->getNumberOfComponents()); + CPPUNIT_ASSERT(std::string(d->getInfoOnComponent(0))=="toto"); + CPPUNIT_ASSERT(std::string(d->getInfoOnComponent(1))=="tata"); + const int expected2[10]={5,15,3,13,1,11,7,17,6,16}; + for(int i=0;i<10;i++) + CPPUNIT_ASSERT_EQUAL(expected2[i],d->getIJ(0,i)); + c->decrRef(); + d->decrRef(); +} + +void MEDCouplingBasicsTest3::testDaDoubleRenumberInPlace1() +{ + DataArrayDouble *a=DataArrayDouble::New(); + a->alloc(7,2); + const double arr1[14]={1.1,11.1,2.1,12.1,3.1,13.1,4.1,14.1,5.1,15.1,6.1,16.1,7.1,17.1}; + std::copy(arr1,arr1+14,a->getPointer()); + // + const int arr2[7]={3,1,0,6,5,4,2}; + a->renumberInPlace(arr2); + CPPUNIT_ASSERT_EQUAL(7,a->getNumberOfTuples()); + CPPUNIT_ASSERT_EQUAL(2,a->getNumberOfComponents()); + const double expected1[14]={3.1, 13.1, 2.1, 12.1, 7.1, 17.1, 1.1, 11.1, 6.1, 16.1, 5.1, 15.1, 4.1, 14.1}; + for(int i=0;i<14;i++) + CPPUNIT_ASSERT_DOUBLES_EQUAL(expected1[i],a->getIJ(0,i),1e-14); + a->decrRef(); + // + DataArrayInt *c=DataArrayInt::New(); + c->alloc(7,2); + const int arr3[14]={1,11,2,12,3,13,4,14,5,15,6,16,7,17}; + std::copy(arr3,arr3+14,c->getPointer()); + c->renumberInPlace(arr2); + CPPUNIT_ASSERT_EQUAL(7,c->getNumberOfTuples()); + CPPUNIT_ASSERT_EQUAL(2,c->getNumberOfComponents()); + const int expected2[14]={3, 13, 2, 12, 7, 17, 1, 11, 6, 16, 5, 15, 4, 14}; + for(int i=0;i<14;i++) + CPPUNIT_ASSERT_EQUAL(expected2[i],c->getIJ(0,i)); + c->decrRef(); +} + +void MEDCouplingBasicsTest3::testDaDoubleRenumberR1() +{ + DataArrayDouble *a=DataArrayDouble::New(); + a->alloc(7,2); + a->setInfoOnComponent(0,"toto"); + a->setInfoOnComponent(1,"tata"); + const double arr1[14]={1.1,11.1,2.1,12.1,3.1,13.1,4.1,14.1,5.1,15.1,6.1,16.1,7.1,17.1}; + std::copy(arr1,arr1+14,a->getPointer()); + // + const int arr2[7]={3,1,0,6,5,4,2}; + DataArrayDouble *b=a->renumberR(arr2); + CPPUNIT_ASSERT_EQUAL(7,b->getNumberOfTuples()); + CPPUNIT_ASSERT_EQUAL(2,b->getNumberOfComponents()); + CPPUNIT_ASSERT(std::string(b->getInfoOnComponent(0))=="toto"); + CPPUNIT_ASSERT(std::string(b->getInfoOnComponent(1))=="tata"); + const double expected1[14]={4.1, 14.1, 2.1, 12.1, 1.1, 11.1, 7.1, 17.1, 6.1, 16.1, 5.1, 15.1, 3.1, 13.1}; + for(int i=0;i<14;i++) + CPPUNIT_ASSERT_DOUBLES_EQUAL(expected1[i],b->getIJ(0,i),1e-14); + b->decrRef(); + a->decrRef(); + // + DataArrayInt *c=DataArrayInt::New(); + c->alloc(7,2); + c->setInfoOnComponent(0,"toto"); + c->setInfoOnComponent(1,"tata"); + const int arr3[14]={1,11,2,12,3,13,4,14,5,15,6,16,7,17}; + std::copy(arr3,arr3+14,c->getPointer()); + DataArrayInt *d=c->renumberR(arr2); + CPPUNIT_ASSERT_EQUAL(7,d->getNumberOfTuples()); + CPPUNIT_ASSERT_EQUAL(2,d->getNumberOfComponents()); + CPPUNIT_ASSERT(std::string(d->getInfoOnComponent(0))=="toto"); + CPPUNIT_ASSERT(std::string(d->getInfoOnComponent(1))=="tata"); + const int expected2[14]={4, 14, 2, 12, 1, 11, 7, 17, 6, 16, 5, 15, 3, 13}; + for(int i=0;i<14;i++) + CPPUNIT_ASSERT_EQUAL(expected2[i],d->getIJ(0,i)); + c->decrRef(); + d->decrRef(); +} + +void MEDCouplingBasicsTest3::testDaDoubleRenumberInPlaceR1() +{ + DataArrayDouble *a=DataArrayDouble::New(); + a->alloc(7,2); + const double arr1[14]={1.1,11.1,2.1,12.1,3.1,13.1,4.1,14.1,5.1,15.1,6.1,16.1,7.1,17.1}; + std::copy(arr1,arr1+14,a->getPointer()); + // + const int arr2[7]={3,1,0,6,5,4,2}; + a->renumberInPlaceR(arr2); + CPPUNIT_ASSERT_EQUAL(7,a->getNumberOfTuples()); + CPPUNIT_ASSERT_EQUAL(2,a->getNumberOfComponents()); + const double expected1[14]={4.1, 14.1, 2.1, 12.1, 1.1, 11.1, 7.1, 17.1, 6.1, 16.1, 5.1, 15.1, 3.1, 13.1}; + for(int i=0;i<14;i++) + CPPUNIT_ASSERT_DOUBLES_EQUAL(expected1[i],a->getIJ(0,i),1e-14); + a->decrRef(); + // + DataArrayInt *c=DataArrayInt::New(); + c->alloc(7,2); + const int arr3[14]={1,11,2,12,3,13,4,14,5,15,6,16,7,17}; + std::copy(arr3,arr3+14,c->getPointer()); + c->renumberInPlaceR(arr2); + CPPUNIT_ASSERT_EQUAL(7,c->getNumberOfTuples()); + CPPUNIT_ASSERT_EQUAL(2,c->getNumberOfComponents()); + const int expected2[14]={4, 14, 2, 12, 1, 11, 7, 17, 6, 16, 5, 15, 3, 13}; + for(int i=0;i<14;i++) + CPPUNIT_ASSERT_EQUAL(expected2[i],c->getIJ(0,i)); + c->decrRef(); +} + +void MEDCouplingBasicsTest3::testDaDoubleSelectByTupleId1() +{ + DataArrayDouble *a=DataArrayDouble::New(); + a->alloc(7,2); + a->setInfoOnComponent(0,"toto"); + a->setInfoOnComponent(1,"tata"); + const double arr1[14]={1.1,11.1,2.1,12.1,3.1,13.1,4.1,14.1,5.1,15.1,6.1,16.1,7.1,17.1}; + std::copy(arr1,arr1+14,a->getPointer()); + // + const int arr2[7]={4,2,0,6,5}; + DataArrayDouble *b=a->selectByTupleId(arr2,arr2+5); + CPPUNIT_ASSERT_EQUAL(5,b->getNumberOfTuples()); + CPPUNIT_ASSERT_EQUAL(2,b->getNumberOfComponents()); + CPPUNIT_ASSERT(std::string(b->getInfoOnComponent(0))=="toto"); + CPPUNIT_ASSERT(std::string(b->getInfoOnComponent(1))=="tata"); + const double expected1[10]={5.1,15.1,3.1,13.1,1.1,11.1,7.1,17.1,6.1,16.1}; + for(int i=0;i<10;i++) + CPPUNIT_ASSERT_DOUBLES_EQUAL(expected1[i],b->getIJ(0,i),1e-14); + b->decrRef(); + a->decrRef(); + // + DataArrayInt *c=DataArrayInt::New(); + c->alloc(7,2); + c->setInfoOnComponent(0,"toto"); + c->setInfoOnComponent(1,"tata"); + const int arr3[14]={1,11,2,12,3,13,4,14,5,15,6,16,7,17}; + std::copy(arr3,arr3+14,c->getPointer()); + DataArrayInt *d=c->selectByTupleId(arr2,arr2+5); + CPPUNIT_ASSERT_EQUAL(5,d->getNumberOfTuples()); + CPPUNIT_ASSERT_EQUAL(2,d->getNumberOfComponents()); + CPPUNIT_ASSERT(std::string(d->getInfoOnComponent(0))=="toto"); + CPPUNIT_ASSERT(std::string(d->getInfoOnComponent(1))=="tata"); + const int expected2[10]={5,15,3,13,1,11,7,17,6,16}; + for(int i=0;i<10;i++) + CPPUNIT_ASSERT_EQUAL(expected2[i],d->getIJ(0,i)); + c->decrRef(); + d->decrRef(); +} + +void MEDCouplingBasicsTest3::testDaDoubleGetMinMaxValues1() +{ + DataArrayDouble *a=DataArrayDouble::New(); + a->alloc(9,1); + const double arr1[9]={2.34,4.56,-6.77,4.55,4.56,2.24,2.34,1.02,4.56}; + std::copy(arr1,arr1+9,a->getPointer()); + int where; + double m=a->getMaxValue(where); + CPPUNIT_ASSERT_EQUAL(1,where); + CPPUNIT_ASSERT_DOUBLES_EQUAL(4.56,m,1e-12); + DataArrayInt *ws; + m=a->getMaxValue2(ws); + CPPUNIT_ASSERT_DOUBLES_EQUAL(4.56,m,1e-12); + CPPUNIT_ASSERT_EQUAL(3,ws->getNumberOfTuples()); + CPPUNIT_ASSERT_EQUAL(1,ws->getNumberOfComponents()); + const int expected1[3]={1,4,8}; + for(int i=0;i<3;i++) + CPPUNIT_ASSERT_EQUAL(expected1[i],ws->getIJ(i,0)); + ws->decrRef(); + a->decrRef(); + a=DataArrayDouble::New(); + const double arr2[9]={-2.34,-4.56,6.77,-4.55,-4.56,-2.24,-2.34,-1.02,-4.56}; + a->alloc(9,1); + std::copy(arr2,arr2+9,a->getPointer()); + where=-2; + m=a->getMinValue(where); + CPPUNIT_ASSERT_EQUAL(1,where); + CPPUNIT_ASSERT_DOUBLES_EQUAL(-4.56,m,1e-12); + m=a->getMinValue2(ws); + CPPUNIT_ASSERT_DOUBLES_EQUAL(-4.56,m,1e-12); + CPPUNIT_ASSERT_EQUAL(3,ws->getNumberOfTuples()); + CPPUNIT_ASSERT_EQUAL(1,ws->getNumberOfComponents()); + for(int i=0;i<3;i++) + CPPUNIT_ASSERT_EQUAL(expected1[i],ws->getIJ(i,0)); + ws->decrRef(); + a->decrRef(); +} + +void MEDCouplingBasicsTest3::testFieldDoubleGetMinMaxValues2() +{ + MEDCouplingUMesh *m1=0; + MEDCouplingUMesh *m2=build3DExtrudedUMesh_1(m1); + m1->decrRef(); + CPPUNIT_ASSERT_EQUAL(18,m2->getNumberOfCells()); + const double arr1[18]={8.71,4.53,-12.41,8.71,-8.71,8.7099,4.55,8.71,5.55,6.77,-1e-200,4.55,8.7099,0.,1.23,0.,2.22,8.71}; + MEDCouplingFieldDouble *f=MEDCouplingFieldDouble::New(ON_CELLS,NO_TIME); + DataArrayDouble *a=DataArrayDouble::New(); + a->alloc(18,1); + std::copy(arr1,arr1+18,a->getPointer()); + f->setArray(a); + a->decrRef(); + f->setMesh(m2); + // + f->checkCoherency(); + double m=f->getMaxValue(); + CPPUNIT_ASSERT_DOUBLES_EQUAL(8.71,m,1e-12); + DataArrayInt *ws; + m=f->getMaxValue2(ws); + CPPUNIT_ASSERT_DOUBLES_EQUAL(8.71,m,1e-12); + CPPUNIT_ASSERT_EQUAL(4,ws->getNumberOfTuples()); + CPPUNIT_ASSERT_EQUAL(1,ws->getNumberOfComponents()); + const int expected1[4]={0,3,7,17}; + for(int i=0;i<4;i++) + CPPUNIT_ASSERT_EQUAL(expected1[i],ws->getIJ(i,0)); + ws->decrRef(); + // + const double arr2[18]={-8.71,-4.53,12.41,-8.71,8.71,-8.7099,-4.55,-8.71,-5.55,-6.77,1e-200,-4.55,-8.7099,0.,-1.23,0.,-2.22,-8.71}; + std::copy(arr2,arr2+18,a->getPointer()); + f->checkCoherency(); + m=f->getMinValue(); + CPPUNIT_ASSERT_DOUBLES_EQUAL(-8.71,m,1e-12); + m=f->getMinValue2(ws); + CPPUNIT_ASSERT_DOUBLES_EQUAL(-8.71,m,1e-12); + CPPUNIT_ASSERT_EQUAL(4,ws->getNumberOfTuples()); + CPPUNIT_ASSERT_EQUAL(1,ws->getNumberOfComponents()); + for(int i=0;i<4;i++) + CPPUNIT_ASSERT_EQUAL(expected1[i],ws->getIJ(i,0)); + ws->decrRef(); + // + f->decrRef(); + m2->decrRef(); +} + +void MEDCouplingBasicsTest3::testBuildUnstructuredCMesh1() +{ + MEDCouplingCMesh *m=MEDCouplingCMesh::New(); + DataArrayDouble *da=DataArrayDouble::New(); + const double discX[4]={2.3,3.4,5.8,10.2}; + const double discY[3]={12.3,23.4,45.8}; + const double discZ[5]={-0.7,1.2,1.25,2.13,2.67}; + da->alloc(4,1); + std::copy(discX,discX+4,da->getPointer()); + m->setCoordsAt(0,da); + da->decrRef(); + m->checkCoherency(); + double pos=2.4; + CPPUNIT_ASSERT_EQUAL(0,m->getCellContainingPoint(&pos,1e-12)); + pos=3.7; + CPPUNIT_ASSERT_EQUAL(1,m->getCellContainingPoint(&pos,1e-12)); + pos=5.9; + CPPUNIT_ASSERT_EQUAL(2,m->getCellContainingPoint(&pos,1e-12)); + pos=10.3; + CPPUNIT_ASSERT_EQUAL(-1,m->getCellContainingPoint(&pos,1e-12)); + pos=1.3; + CPPUNIT_ASSERT_EQUAL(-1,m->getCellContainingPoint(&pos,1e-12)); + // + MEDCouplingUMesh *m2=m->buildUnstructured(); + m2->checkCoherency(); + MEDCouplingFieldDouble *f1=m->getMeasureField(false); + MEDCouplingFieldDouble *f2=m2->getMeasureField(false); + CPPUNIT_ASSERT_EQUAL(f1->getNumberOfTuples(),3); + CPPUNIT_ASSERT_EQUAL(f2->getNumberOfTuples(),3); + CPPUNIT_ASSERT_EQUAL(1,m2->getMeshDimension()); + CPPUNIT_ASSERT_EQUAL(1,m2->getSpaceDimension()); + for(int i=0;i<3;i++) + CPPUNIT_ASSERT_DOUBLES_EQUAL(f1->getIJ(i,0),f2->getIJ(i,0),1e-10); + da=DataArrayDouble::New(); + da->alloc(3,1); + std::copy(discY,discY+3,da->getPointer()); + m->setCoordsAt(1,da); + da->decrRef(); + m2->decrRef(); + f1->decrRef(); + f2->decrRef(); + // + m2=m->buildUnstructured(); + m2->checkCoherency(); + f1=m->getMeasureField(false); + f2=m2->getMeasureField(false); + CPPUNIT_ASSERT_EQUAL(f1->getNumberOfTuples(),6); + CPPUNIT_ASSERT_EQUAL(f2->getNumberOfTuples(),6); + CPPUNIT_ASSERT_EQUAL(2,m2->getMeshDimension()); + CPPUNIT_ASSERT_EQUAL(2,m2->getSpaceDimension()); + for(int i=0;i<6;i++) + CPPUNIT_ASSERT_DOUBLES_EQUAL(f1->getIJ(i,0),f2->getIJ(i,0),1e-10); + f1->decrRef(); + f2->decrRef(); + m2->decrRef(); + // + da=DataArrayDouble::New(); + da->alloc(5,1); + std::copy(discZ,discZ+5,da->getPointer()); + m->setCoordsAt(2,da); + da->decrRef(); + m2=m->buildUnstructured(); + m2->checkCoherency(); + f1=m->getMeasureField(false); + f2=m2->getMeasureField(false); + CPPUNIT_ASSERT_EQUAL(f1->getNumberOfTuples(),24); + CPPUNIT_ASSERT_EQUAL(f2->getNumberOfTuples(),24); + CPPUNIT_ASSERT_EQUAL(3,m2->getMeshDimension()); + CPPUNIT_ASSERT_EQUAL(3,m2->getSpaceDimension()); + for(int i=0;i<24;i++) + CPPUNIT_ASSERT_DOUBLES_EQUAL(f1->getIJ(i,0),f2->getIJ(i,0),1e-10); + f1->decrRef(); + f2->decrRef(); + // + double pos1[3]={5.,30.,2.}; + CPPUNIT_ASSERT_EQUAL(16,m->getCellContainingPoint(pos1,1e-12)); + // + const double pt[3]={2.4,12.7,-3.4}; + m->scale(pt,3.7); + MEDCouplingUMesh *m3=m->buildUnstructured(); + m2->scale(pt,3.7); + CPPUNIT_ASSERT(m3->isEqual(m2,1e-12)); + m2->decrRef(); + m3->decrRef(); + // + m->decrRef(); +} + +void MEDCouplingBasicsTest3::testDataArrayIntInvertO2NNO21() +{ + const int arr1[6]={2,0,4,1,5,3}; + DataArrayInt *da=DataArrayInt::New(); + da->alloc(6,1); + std::copy(arr1,arr1+6,da->getPointer()); + DataArrayInt *da2=da->invertArrayO2N2N2O(6); + CPPUNIT_ASSERT_EQUAL(6,da2->getNumberOfTuples()); + CPPUNIT_ASSERT_EQUAL(1,da2->getNumberOfComponents()); + const int expected1[6]={1,3,0,5,2,4}; + for(int i=0;i<6;i++) + CPPUNIT_ASSERT_EQUAL(expected1[i],da2->getIJ(i,0)); + DataArrayInt *da3=da2->invertArrayN2O2O2N(6); + for(int i=0;i<6;i++) + CPPUNIT_ASSERT_EQUAL(arr1[i],da3->getIJ(i,0)); + da3->decrRef(); + da2->decrRef(); + da->decrRef(); + // + const int arr2[10]={3,-1,5,4,-1,0,-1,1,2,-1}; + da=DataArrayInt::New(); + da->alloc(10,1); + std::copy(arr2,arr2+10,da->getPointer()); + da2=da->invertArrayO2N2N2O(6); + CPPUNIT_ASSERT_EQUAL(6,da2->getNumberOfTuples()); + CPPUNIT_ASSERT_EQUAL(1,da2->getNumberOfComponents()); + const int expected2[10]={5,7,8,0,3,2}; + for(int i=0;i<6;i++) + CPPUNIT_ASSERT_EQUAL(expected2[i],da2->getIJ(i,0)); + da3=da2->invertArrayN2O2O2N(10); + for(int i=0;i<10;i++) + CPPUNIT_ASSERT_EQUAL(arr2[i],da3->getIJ(i,0)); + da3->decrRef(); + da2->decrRef(); + da->decrRef(); +} + +void MEDCouplingBasicsTest3::testKeepSetSelectedComponent1() +{ + const double arr1[20]={1.,2.,3.,4., 11.,12.,13.,14., 21.,22.,23.,24., 31.,32.,33.,34., 41.,42.,43.,44.}; + DataArrayDouble *a1=DataArrayDouble::New(); + a1->alloc(5,4); + std::copy(arr1,arr1+20,a1->getPointer()); + a1->setInfoOnComponent(0,"aaaa"); + a1->setInfoOnComponent(1,"bbbb"); + a1->setInfoOnComponent(2,"cccc"); + a1->setInfoOnComponent(3,"dddd"); + const int arr2[6]={1,2,1,2,0,0}; + std::vector<int> arr2V(arr2,arr2+6); + DataArrayDouble *a2=static_cast<DataArrayDouble *>(a1->keepSelectedComponents(arr2V)); + CPPUNIT_ASSERT_EQUAL(6,a2->getNumberOfComponents()); + CPPUNIT_ASSERT_EQUAL(5,a2->getNumberOfTuples()); + CPPUNIT_ASSERT(std::string(a2->getInfoOnComponent(0))=="bbbb"); + CPPUNIT_ASSERT(std::string(a2->getInfoOnComponent(1))=="cccc"); + CPPUNIT_ASSERT(std::string(a2->getInfoOnComponent(2))=="bbbb"); + CPPUNIT_ASSERT(std::string(a2->getInfoOnComponent(3))=="cccc"); + CPPUNIT_ASSERT(std::string(a2->getInfoOnComponent(4))=="aaaa"); + CPPUNIT_ASSERT(std::string(a2->getInfoOnComponent(5))=="aaaa"); + const double expected1[30]={2.,3.,2.,3.,1.,1., 12.,13.,12.,13.,11.,11., 22.,23.,22.,23.,21.,21., 32.,33.,32.,33.,31.,31., 42.,43.,42.,43.,41.,41.}; + for(int i=0;i<30;i++) + CPPUNIT_ASSERT_DOUBLES_EQUAL(expected1[i],a2->getIJ(0,i),1e-14); + DataArrayInt *a3=a1->convertToIntArr(); + DataArrayInt *a4=static_cast<DataArrayInt *>(a3->keepSelectedComponents(arr2V)); + CPPUNIT_ASSERT_EQUAL(6,a4->getNumberOfComponents()); + CPPUNIT_ASSERT_EQUAL(5,a4->getNumberOfTuples()); + CPPUNIT_ASSERT(std::string(a4->getInfoOnComponent(0))=="bbbb"); + CPPUNIT_ASSERT(std::string(a4->getInfoOnComponent(1))=="cccc"); + CPPUNIT_ASSERT(std::string(a4->getInfoOnComponent(2))=="bbbb"); + CPPUNIT_ASSERT(std::string(a4->getInfoOnComponent(3))=="cccc"); + CPPUNIT_ASSERT(std::string(a4->getInfoOnComponent(4))=="aaaa"); + CPPUNIT_ASSERT(std::string(a4->getInfoOnComponent(5))=="aaaa"); + for(int i=0;i<30;i++) + CPPUNIT_ASSERT_EQUAL(int(expected1[i]),a4->getIJ(0,i)); + // setSelectedComponents + const int arr3[2]={3,2}; + std::vector<int> arr3V(arr3,arr3+2); + DataArrayDouble *a5=static_cast<DataArrayDouble *>(a1->keepSelectedComponents(arr3V)); + a5->setInfoOnComponent(0,"eeee"); + a5->setInfoOnComponent(1,"ffff"); + const int arr4[2]={1,2}; + std::vector<int> arr4V(arr4,arr4+2); + a2->setSelectedComponents(a5,arr4V); + CPPUNIT_ASSERT_EQUAL(6,a2->getNumberOfComponents()); + CPPUNIT_ASSERT_EQUAL(5,a2->getNumberOfTuples()); + CPPUNIT_ASSERT(std::string(a2->getInfoOnComponent(0))=="bbbb"); + CPPUNIT_ASSERT(std::string(a2->getInfoOnComponent(1))=="eeee"); + CPPUNIT_ASSERT(std::string(a2->getInfoOnComponent(2))=="ffff"); + CPPUNIT_ASSERT(std::string(a2->getInfoOnComponent(3))=="cccc"); + CPPUNIT_ASSERT(std::string(a2->getInfoOnComponent(4))=="aaaa"); + CPPUNIT_ASSERT(std::string(a2->getInfoOnComponent(5))=="aaaa"); + const double expected2[30]={2.,4.,3.,3.,1.,1., 12.,14.,13.,13.,11.,11., 22.,24.,23.,23.,21.,21., 32.,34.,33.,33.,31.,31., 42.,44.,43.,43.,41.,41.}; + for(int i=0;i<30;i++) + CPPUNIT_ASSERT_DOUBLES_EQUAL(expected2[i],a2->getIJ(0,i),1e-14); + DataArrayInt *a6=a5->convertToIntArr(); + a6->setInfoOnComponent(0,"eeee"); + a6->setInfoOnComponent(1,"ffff"); + a4->setSelectedComponents(a6,arr4V); + CPPUNIT_ASSERT_EQUAL(6,a4->getNumberOfComponents()); + CPPUNIT_ASSERT_EQUAL(5,a4->getNumberOfTuples()); + CPPUNIT_ASSERT(std::string(a4->getInfoOnComponent(0))=="bbbb"); + CPPUNIT_ASSERT(std::string(a4->getInfoOnComponent(1))=="eeee"); + CPPUNIT_ASSERT(std::string(a4->getInfoOnComponent(2))=="ffff"); + CPPUNIT_ASSERT(std::string(a4->getInfoOnComponent(3))=="cccc"); + CPPUNIT_ASSERT(std::string(a4->getInfoOnComponent(4))=="aaaa"); + CPPUNIT_ASSERT(std::string(a4->getInfoOnComponent(5))=="aaaa"); + for(int i=0;i<30;i++) + CPPUNIT_ASSERT_EQUAL(int(expected2[i]),a4->getIJ(0,i)); + // test of throw + const int arr5[3]={2,3,6}; + const int arr6[3]={2,7,5}; + const int arr7[4]={2,1,4,6}; + std::vector<int> arr5V(arr5,arr5+3); + std::vector<int> arr6V(arr6,arr6+3); + std::vector<int> arr7V(arr7,arr7+4); + CPPUNIT_ASSERT_THROW(a2->keepSelectedComponents(arr5V),INTERP_KERNEL::Exception); + CPPUNIT_ASSERT_THROW(a2->keepSelectedComponents(arr6V),INTERP_KERNEL::Exception); + CPPUNIT_ASSERT_THROW(a2->setSelectedComponents(a1,arr7V),INTERP_KERNEL::Exception); + arr7V.resize(3); + CPPUNIT_ASSERT_THROW(a2->setSelectedComponents(a1,arr7V),INTERP_KERNEL::Exception); + // + a6->decrRef(); + a5->decrRef(); + a4->decrRef(); + a3->decrRef(); + a2->decrRef(); + a1->decrRef(); +} + +void MEDCouplingBasicsTest3::testKeepSetSelectedComponent2() +{ + MEDCouplingUMesh *m1=build2DTargetMesh_1(); + const double arr1[20]={1.,2.,3.,4., 11.,12.,13.,14., 21.,22.,23.,24., 31.,32.,33.,34., 41.,42.,43.,44.}; + DataArrayDouble *a1=DataArrayDouble::New(); + a1->alloc(5,4); + std::copy(arr1,arr1+20,a1->getPointer()); + a1->setInfoOnComponent(0,"aaaa"); + a1->setInfoOnComponent(1,"bbbb"); + a1->setInfoOnComponent(2,"cccc"); + a1->setInfoOnComponent(3,"dddd"); + MEDCouplingFieldDouble *f1=MEDCouplingFieldDouble::New(ON_CELLS,ONE_TIME); + f1->setTime(2.3,4,5); + f1->setMesh(m1); + f1->setName("f1"); + f1->setArray(a1); + f1->checkCoherency(); + // + const int arr2[6]={1,2,1,2,0,0}; + std::vector<int> arr2V(arr2,arr2+6); + MEDCouplingFieldDouble *f2=f1->keepSelectedComponents(arr2V); + CPPUNIT_ASSERT(f2->getMesh()==f1->getMesh()); + CPPUNIT_ASSERT(f2->getTimeDiscretization()==ONE_TIME); + int dt,it; + CPPUNIT_ASSERT_DOUBLES_EQUAL(2.3,f2->getTime(dt,it),1e-13); + CPPUNIT_ASSERT_EQUAL(4,dt); + CPPUNIT_ASSERT_EQUAL(5,it); + f2->checkCoherency(); + CPPUNIT_ASSERT_EQUAL(6,f2->getNumberOfComponents()); + CPPUNIT_ASSERT_EQUAL(5,f2->getNumberOfTuples()); + CPPUNIT_ASSERT(std::string(f2->getArray()->getInfoOnComponent(0))=="bbbb"); + CPPUNIT_ASSERT(std::string(f2->getArray()->getInfoOnComponent(1))=="cccc"); + CPPUNIT_ASSERT(std::string(f2->getArray()->getInfoOnComponent(2))=="bbbb"); + CPPUNIT_ASSERT(std::string(f2->getArray()->getInfoOnComponent(3))=="cccc"); + CPPUNIT_ASSERT(std::string(f2->getArray()->getInfoOnComponent(4))=="aaaa"); + CPPUNIT_ASSERT(std::string(f2->getArray()->getInfoOnComponent(5))=="aaaa"); + const double expected1[30]={2.,3.,2.,3.,1.,1., 12.,13.,12.,13.,11.,11., 22.,23.,22.,23.,21.,21., 32.,33.,32.,33.,31.,31., 42.,43.,42.,43.,41.,41.}; + for(int i=0;i<30;i++) + CPPUNIT_ASSERT_DOUBLES_EQUAL(expected1[i],f2->getIJ(0,i),1e-14); + //setSelectedComponents + const int arr3[2]={3,2}; + std::vector<int> arr3V(arr3,arr3+2); + MEDCouplingFieldDouble *f5=f1->keepSelectedComponents(arr3V); + f5->setTime(6.7,8,9); + f5->getArray()->setInfoOnComponent(0,"eeee"); + f5->getArray()->setInfoOnComponent(1,"ffff"); + f5->checkCoherency(); + const int arr4[2]={1,2}; + std::vector<int> arr4V(arr4,arr4+2); + f2->setSelectedComponents(f5,arr4V); + CPPUNIT_ASSERT_EQUAL(6,f2->getNumberOfComponents()); + CPPUNIT_ASSERT_EQUAL(5,f2->getNumberOfTuples()); + f2->checkCoherency(); + CPPUNIT_ASSERT_DOUBLES_EQUAL(2.3,f2->getTime(dt,it),1e-13); + CPPUNIT_ASSERT_EQUAL(4,dt); + CPPUNIT_ASSERT_EQUAL(5,it); + CPPUNIT_ASSERT(std::string(f2->getArray()->getInfoOnComponent(0))=="bbbb"); + CPPUNIT_ASSERT(std::string(f2->getArray()->getInfoOnComponent(1))=="eeee"); + CPPUNIT_ASSERT(std::string(f2->getArray()->getInfoOnComponent(2))=="ffff"); + CPPUNIT_ASSERT(std::string(f2->getArray()->getInfoOnComponent(3))=="cccc"); + CPPUNIT_ASSERT(std::string(f2->getArray()->getInfoOnComponent(4))=="aaaa"); + CPPUNIT_ASSERT(std::string(f2->getArray()->getInfoOnComponent(5))=="aaaa"); + const double expected2[30]={2.,4.,3.,3.,1.,1., 12.,14.,13.,13.,11.,11., 22.,24.,23.,23.,21.,21., 32.,34.,33.,33.,31.,31., 42.,44.,43.,43.,41.,41.}; + for(int i=0;i<30;i++) + CPPUNIT_ASSERT_DOUBLES_EQUAL(expected2[i],f2->getIJ(0,i),1e-14); + f5->decrRef(); + f1->decrRef(); + f2->decrRef(); + a1->decrRef(); + m1->decrRef(); +} + +void MEDCouplingBasicsTest3::testElementaryDAThrowAndSpecialCases() +{ + DataArrayInt *da=DataArrayInt::New(); + CPPUNIT_ASSERT_THROW(da->checkAllocated(),INTERP_KERNEL::Exception); + CPPUNIT_ASSERT_THROW(da->fillWithValue(1),INTERP_KERNEL::Exception); + CPPUNIT_ASSERT_THROW(da->iota(1),INTERP_KERNEL::Exception); + da->alloc(7,1); + da->fillWithValue(11); //11,11,11,11... + da->iota(10); //10,11,12,13... + + DataArrayInt *db=DataArrayInt::New(); + db->alloc(7,2); + + DataArrayDouble *dbl2=DataArrayDouble::New(); + dbl2->alloc(7,2); + CPPUNIT_ASSERT_THROW(dbl2->isUniform(10.,1e-15),INTERP_KERNEL::Exception); + CPPUNIT_ASSERT_THROW(dbl2->sort(),INTERP_KERNEL::Exception); + CPPUNIT_ASSERT_THROW(dbl2->iota(10.),INTERP_KERNEL::Exception); + + DataArrayDouble *dbl=DataArrayDouble::New(); + //DataArrayDouble not allocated yet + CPPUNIT_ASSERT_THROW(dbl->iota(10.),INTERP_KERNEL::Exception); + CPPUNIT_ASSERT_THROW(dbl->isUniform(10.,1e-15),INTERP_KERNEL::Exception); + CPPUNIT_ASSERT_THROW(dbl->sort(),INTERP_KERNEL::Exception); + CPPUNIT_ASSERT_THROW(dbl->reverse(),INTERP_KERNEL::Exception); + CPPUNIT_ASSERT_THROW(dbl->fromNoInterlace(),INTERP_KERNEL::Exception); + CPPUNIT_ASSERT_THROW(dbl->toNoInterlace(),INTERP_KERNEL::Exception); + + dbl->alloc(7,1); + dbl->iota(10.); + CPPUNIT_ASSERT(!dbl->isUniform(10.,1e-15)); + dbl->sort(); + CPPUNIT_ASSERT(dbl->isMonotonic(true, .99)); + CPPUNIT_ASSERT(dbl->isMonotonic(true, -.99)); + CPPUNIT_ASSERT(!dbl->isMonotonic(true, 1.1)); + CPPUNIT_ASSERT(!dbl->isMonotonic(true, -1.1)); + dbl->reverse(); + CPPUNIT_ASSERT(dbl->isMonotonic(false, .99)); + CPPUNIT_ASSERT(!dbl->isMonotonic(false, 1.1)); + CPPUNIT_ASSERT(!dbl->isMonotonic(false, -1.1)); + + DataArrayInt *dc=DataArrayInt::New(); + dc->alloc(14,1); + + DataArrayDouble *dd=DataArrayDouble::New(); + CPPUNIT_ASSERT_THROW(dd->checkAllocated(),INTERP_KERNEL::Exception); + CPPUNIT_ASSERT_THROW(dd->fillWithValue(1.),INTERP_KERNEL::Exception); + CPPUNIT_ASSERT_THROW(dd->iota(1.),INTERP_KERNEL::Exception); + CPPUNIT_ASSERT(!((dd->repr().find("No data"))==std::string::npos)); + + dd->alloc(0,1); //Allocated but nbOfElements==0! + CPPUNIT_ASSERT(!((dd->repr().find("Number of tuples : 0"))==std::string::npos)); + CPPUNIT_ASSERT(!((dd->repr().find("Empty Data"))==std::string::npos)); + dd->fillWithValue(11); //?!... + dd->iota(10); //?!... + CPPUNIT_ASSERT(dd->isMonotonic(true, 1.)); + CPPUNIT_ASSERT(dd->isMonotonic(false, 1.)); + + CPPUNIT_ASSERT_THROW(db->copyStringInfoFrom(*da),INTERP_KERNEL::Exception); + CPPUNIT_ASSERT_THROW(db->copyStringInfoFrom(*da),INTERP_KERNEL::Exception); + std::vector<int> cIds(2,2); + CPPUNIT_ASSERT_THROW(da->copyPartOfStringInfoFrom(*db,cIds),INTERP_KERNEL::Exception); + cIds[0]=1; + cIds[0]=-1; + CPPUNIT_ASSERT_THROW(da->copyPartOfStringInfoFrom(*db,cIds),INTERP_KERNEL::Exception); + + std::vector<std::string> info(2,"infoOfOneComponent"); + CPPUNIT_ASSERT_THROW(da->setInfoOnComponents(info),INTERP_KERNEL::Exception); + CPPUNIT_ASSERT_THROW(da->setInfoOnComponent(1,info[0].c_str()),INTERP_KERNEL::Exception); + db->setInfoOnComponents(info); + + CPPUNIT_ASSERT_THROW(da->getInfoOnComponent(-1),INTERP_KERNEL::Exception); + CPPUNIT_ASSERT_THROW(da->getInfoOnComponent(2),INTERP_KERNEL::Exception); + CPPUNIT_ASSERT(db->getInfoOnComponent(1)==db->getInfoOnComponent(0)); + CPPUNIT_ASSERT_THROW(db->getVarOnComponent(-1),INTERP_KERNEL::Exception); + CPPUNIT_ASSERT_THROW(db->getVarOnComponent(2),INTERP_KERNEL::Exception); + CPPUNIT_ASSERT_THROW(db->getUnitOnComponent(-1),INTERP_KERNEL::Exception); + CPPUNIT_ASSERT_THROW(db->getUnitOnComponent(2),INTERP_KERNEL::Exception); + + CPPUNIT_ASSERT(da->GetVarNameFromInfo(std::string("varname unit "))==std::string("varname unit ")); + CPPUNIT_ASSERT(da->GetVarNameFromInfo(std::string("varname]unit["))==std::string("varname]unit[")); + CPPUNIT_ASSERT(da->GetVarNameFromInfo(std::string("[unit]"))==std::string()); + CPPUNIT_ASSERT(da->GetVarNameFromInfo(std::string("varname [unit]"))==std::string("varname")); + + CPPUNIT_ASSERT(da->GetUnitFromInfo(std::string("varname unit "))==std::string()); + CPPUNIT_ASSERT(da->GetUnitFromInfo(std::string("varname]unit["))==std::string()); + CPPUNIT_ASSERT(da->GetUnitFromInfo(std::string("[unit]"))==std::string("unit")); + CPPUNIT_ASSERT(da->GetUnitFromInfo(std::string("varname [unit]"))==std::string("unit")); + + CPPUNIT_ASSERT_THROW(da->checkNbOfTuplesAndComp(*db,"theMessageInThrow"),INTERP_KERNEL::Exception); + CPPUNIT_ASSERT_THROW(da->checkNbOfTuplesAndComp(*dc,"theMessageInThrow"),INTERP_KERNEL::Exception); + CPPUNIT_ASSERT_THROW(db->checkNbOfTuplesAndComp(*dc,"theMessageInThrow"),INTERP_KERNEL::Exception); + + CPPUNIT_ASSERT_THROW(da->checkNbOfTuplesAndComp(7,2,"theMessageInThrow"),INTERP_KERNEL::Exception); + da->checkNbOfTuplesAndComp(7,1,"theMessageInThrow"); + + CPPUNIT_ASSERT_THROW(db->checkNbOfElems(7*2+1,"theMessageInThrow"),INTERP_KERNEL::Exception); + db->checkNbOfElems(7*2,"theMessageInThrow"); + + CPPUNIT_ASSERT_THROW(db->GetNumberOfItemGivenBES(10,9,1,"theMessageInThrow"),INTERP_KERNEL::Exception); + CPPUNIT_ASSERT_THROW(db->GetNumberOfItemGivenBES(0,1,-1,"theMessageInThrow"),INTERP_KERNEL::Exception); + CPPUNIT_ASSERT_EQUAL(10,db->GetNumberOfItemGivenBES(0,10,1,"theMessageInThrow")); + CPPUNIT_ASSERT_EQUAL(5,db->GetNumberOfItemGivenBES(0,10,2,"theMessageInThrow")); + CPPUNIT_ASSERT_EQUAL(6,db->GetNumberOfItemGivenBES(0,11,2,"theMessageInThrow")); + + //std::cout<<"\n!!!!!!!!!\n"<<dd->repr()<<"\n!!!!!!!!!\n"; + CPPUNIT_ASSERT(!((da->repr().find("Number of components : 1"))==std::string::npos)); + CPPUNIT_ASSERT(!((dd->repr().find("Number of components : 1"))==std::string::npos)); + CPPUNIT_ASSERT(!((dbl->repr().find("Number of components : 1"))==std::string::npos)); + + CPPUNIT_ASSERT(!((da->reprZip().find("Number of components : 1"))==std::string::npos)); + CPPUNIT_ASSERT(!((dd->reprZip().find("Number of components : 1"))==std::string::npos)); + CPPUNIT_ASSERT(!((dbl->reprZip().find("Number of components : 1"))==std::string::npos)); + + std::ostringstream ret; + dbl->writeVTK(ret,2,"file.tmp",0); + CPPUNIT_ASSERT(!((ret.str().find("<DataArray"))==std::string::npos)); + CPPUNIT_ASSERT(!((ret.str().find("Float32"))==std::string::npos)); + CPPUNIT_ASSERT(!((ret.str().find("16 15 14 13 12 11 10"))==std::string::npos)); + + CPPUNIT_ASSERT_THROW(dbl->selectByTupleId2(0,1,-1),INTERP_KERNEL::Exception); + CPPUNIT_ASSERT_THROW(dbl->substr(-1,1),INTERP_KERNEL::Exception); + CPPUNIT_ASSERT_THROW(dbl->substr(8,1),INTERP_KERNEL::Exception); + CPPUNIT_ASSERT_THROW(dbl->substr(0,8),INTERP_KERNEL::Exception); + CPPUNIT_ASSERT_THROW(dbl->meldWith(dd),INTERP_KERNEL::Exception); + + CPPUNIT_ASSERT_THROW(dbl->setPartOfValuesAdv(dbl2,da),INTERP_KERNEL::Exception); //dbl dbl2 not have the same number of components + CPPUNIT_ASSERT_THROW(dbl->setPartOfValuesAdv(dd,da),INTERP_KERNEL::Exception); //da tuple selector DataArrayInt instance not have exactly 2 components + + DataArrayDouble *dbl3=DataArrayDouble::New(); + dbl3->alloc(6,2); + dbl3->fillWithValue(11.); + int tupleId; + //bad number of components + CPPUNIT_ASSERT_THROW(dbl3->getMaxValue(tupleId),INTERP_KERNEL::Exception); + CPPUNIT_ASSERT_THROW(dd->getMaxValue(tupleId),INTERP_KERNEL::Exception); + CPPUNIT_ASSERT_THROW(dbl3->getMinValue(tupleId),INTERP_KERNEL::Exception); + CPPUNIT_ASSERT_THROW(dd->getMinValue(tupleId),INTERP_KERNEL::Exception); + CPPUNIT_ASSERT_THROW(dbl3->getAverageValue(),INTERP_KERNEL::Exception); + CPPUNIT_ASSERT_THROW(dd->getAverageValue(),INTERP_KERNEL::Exception); + CPPUNIT_ASSERT_THROW(dd->accumulate(100),INTERP_KERNEL::Exception); + CPPUNIT_ASSERT_THROW(dbl->fromPolarToCart(),INTERP_KERNEL::Exception); + CPPUNIT_ASSERT_THROW(dbl3->fromCylToCart(),INTERP_KERNEL::Exception); + CPPUNIT_ASSERT_THROW(dbl3->fromSpherToCart(),INTERP_KERNEL::Exception); + CPPUNIT_ASSERT_THROW(dbl3->doublyContractedProduct(),INTERP_KERNEL::Exception); + CPPUNIT_ASSERT_THROW(dbl3->determinant(),INTERP_KERNEL::Exception); + CPPUNIT_ASSERT_THROW(dbl3->eigenValues(),INTERP_KERNEL::Exception); + CPPUNIT_ASSERT_THROW(dbl3->eigenVectors(),INTERP_KERNEL::Exception); + CPPUNIT_ASSERT_THROW(dbl3->inverse(),INTERP_KERNEL::Exception); + CPPUNIT_ASSERT_THROW(dbl3->trace(),INTERP_KERNEL::Exception); + CPPUNIT_ASSERT_THROW(dbl3->deviator(),INTERP_KERNEL::Exception); + + dbl3->setIJ(5,1,12.); + CPPUNIT_ASSERT(dbl3->getMaxValueInArray()==12.); + CPPUNIT_ASSERT(dbl3->getMinValueInArray()==11.); + + db->fillWithValue(100); //bad Ids + CPPUNIT_ASSERT_THROW(dbl3->setPartOfValuesAdv(dbl2,db),INTERP_KERNEL::Exception); + db->fillWithValue(-1); //bad Ids + CPPUNIT_ASSERT_THROW(dbl3->setPartOfValuesAdv(dbl2,db),INTERP_KERNEL::Exception); + db->fillWithValue(6); //bad Ids for dbl3 + CPPUNIT_ASSERT_THROW(dbl3->setPartOfValuesAdv(dbl2,db),INTERP_KERNEL::Exception); + + DataArrayDouble::SetArrayIn(dbl,dbl3); //dbl->dbl3 memLeaks? + dbl3->checkNoNullValues(); + dbl3->setIJ(6,0,0.); + CPPUNIT_ASSERT_THROW(dbl3->checkNoNullValues(),INTERP_KERNEL::Exception); + CPPUNIT_ASSERT_THROW(dbl3->applyInv(1.),INTERP_KERNEL::Exception); //div by zero + CPPUNIT_ASSERT_THROW(dbl2->getIdsInRange(1.,2.),INTERP_KERNEL::Exception); + std::vector<const DataArrayDouble *> a(0); //input list must be NON EMPTY + CPPUNIT_ASSERT_THROW(DataArrayDouble::Aggregate(a),INTERP_KERNEL::Exception); + CPPUNIT_ASSERT_THROW(DataArrayDouble::Meld(a),INTERP_KERNEL::Exception); + + a.push_back(dbl2); + a.push_back(dbl); //Nb of components mismatch + CPPUNIT_ASSERT_THROW(DataArrayDouble::Aggregate(a),INTERP_KERNEL::Exception); + + CPPUNIT_ASSERT_THROW(DataArrayDouble::Dot(dbl2,dbl),INTERP_KERNEL::Exception); + + CPPUNIT_ASSERT_THROW(DataArrayDouble::CrossProduct(dbl2,dbl),INTERP_KERNEL::Exception); //Nb of components mismatch + CPPUNIT_ASSERT_THROW(DataArrayDouble::CrossProduct(dbl2,dbl2),INTERP_KERNEL::Exception); //Nb of components must be equal to 3 + DataArrayDouble *dbl4=DataArrayDouble::New(); + dbl4->alloc(6,3); + DataArrayDouble *dbl5=DataArrayDouble::New(); + dbl5->alloc(7,3); + CPPUNIT_ASSERT_THROW(DataArrayDouble::CrossProduct(dbl4,dbl5),INTERP_KERNEL::Exception); //Nb of tuples mismatch + + a[0]=dbl4; //Nb of tuple mismatch + a[1]=dbl5; //Nb of tuple mismatch + CPPUNIT_ASSERT_THROW(DataArrayDouble::Meld(a),INTERP_KERNEL::Exception); + CPPUNIT_ASSERT_THROW(DataArrayDouble::Dot(dbl4,dbl5),INTERP_KERNEL::Exception); + + da->decrRef(); + db->decrRef(); + dbl->decrRef(); + dbl2->decrRef(); + dbl3->decrRef(); + dbl4->decrRef(); + dbl5->decrRef(); + dc->decrRef(); + dd->decrRef(); +} + +void MEDCouplingBasicsTest3::testDAIGetIdsEqual1() +{ + const int tab1[7]={5,-2,-4,-2,3,2,-2}; + DataArrayInt *da=DataArrayInt::New(); + da->alloc(7,1); + std::copy(tab1,tab1+7,da->getPointer()); + DataArrayInt *da2=da->getIdsEqual(-2); + CPPUNIT_ASSERT_EQUAL(3,da2->getNumberOfTuples()); + CPPUNIT_ASSERT_EQUAL(1,da2->getNumberOfComponents()); + const int expected1[3]={1,3,6}; + CPPUNIT_ASSERT(std::equal(expected1,expected1+3,da2->getConstPointer())); + da2->decrRef(); + da->decrRef(); +} + +void MEDCouplingBasicsTest3::testDAIGetIdsEqualList1() +{ + const int tab1[7]={5,-2,-4,-2,3,2,-2}; + DataArrayInt *da=DataArrayInt::New(); + da->alloc(7,1); + std::copy(tab1,tab1+7,da->getPointer()); + const int tab2[3]={3,-2,0}; + std::vector<int> tab2V(tab2,tab2+3); + DataArrayInt *da2=da->getIdsEqualList(&tab2V[0],&tab2V[0]+tab2V.size()); + CPPUNIT_ASSERT_EQUAL(4,da2->getNumberOfTuples()); + CPPUNIT_ASSERT_EQUAL(1,da2->getNumberOfComponents()); + const int expected1[4]={1,3,4,6}; + CPPUNIT_ASSERT(std::equal(expected1,expected1+4,da2->getConstPointer())); + da2->decrRef(); + da->decrRef(); +} + +void MEDCouplingBasicsTest3::testDAFromNoInterlace1() +{ + const int tab1[15]={1,11,21,31,41,2,12,22,32,42,3,13,23,33,43}; + DataArrayInt *da=DataArrayInt::New(); + da->alloc(5,3); + std::copy(tab1,tab1+15,da->getPointer()); + DataArrayInt *da2=da->fromNoInterlace(); + const int expected1[15]={1,2,3,11,12,13,21,22,23,31,32,33,41,42,43}; + CPPUNIT_ASSERT_EQUAL(5,da2->getNumberOfTuples()); + CPPUNIT_ASSERT_EQUAL(3,da2->getNumberOfComponents());// it's not a bug. Avoid to have 1 million components ! + CPPUNIT_ASSERT(std::equal(expected1,expected1+15,da2->getConstPointer())); + DataArrayDouble *da3=da->convertToDblArr(); + DataArrayDouble *da4=da3->fromNoInterlace(); + CPPUNIT_ASSERT_EQUAL(5,da4->getNumberOfTuples()); + CPPUNIT_ASSERT_EQUAL(3,da4->getNumberOfComponents());// it's not a bug. Avoid to have 1 million components ! + for(int i=0;i<15;i++) + CPPUNIT_ASSERT_DOUBLES_EQUAL((double)expected1[i],da4->getIJ(0,i),1e-14); + da4->decrRef(); + da3->decrRef(); + da2->decrRef(); + da->decrRef(); +} + +void MEDCouplingBasicsTest3::testDAToNoInterlace1() +{ + const int tab1[15]={1,2,3,11,12,13,21,22,23,31,32,33,41,42,43}; + DataArrayInt *da=DataArrayInt::New(); + da->alloc(5,3); + std::copy(tab1,tab1+15,da->getPointer()); + DataArrayInt *da2=da->toNoInterlace(); + const int expected1[15]={1,11,21,31,41,2,12,22,32,42,3,13,23,33,43}; + CPPUNIT_ASSERT_EQUAL(5,da2->getNumberOfTuples()); + CPPUNIT_ASSERT_EQUAL(3,da2->getNumberOfComponents());// it's not a bug. Avoid to have 1 million components ! + CPPUNIT_ASSERT(std::equal(expected1,expected1+15,da2->getConstPointer())); + DataArrayDouble *da3=da->convertToDblArr(); + DataArrayDouble *da4=da3->toNoInterlace(); + CPPUNIT_ASSERT_EQUAL(5,da4->getNumberOfTuples()); + CPPUNIT_ASSERT_EQUAL(3,da4->getNumberOfComponents());// it's not a bug. Avoid to have 1 million components ! + for(int i=0;i<15;i++) + CPPUNIT_ASSERT_DOUBLES_EQUAL((double)expected1[i],da4->getIJ(0,i),1e-14); + da4->decrRef(); + da3->decrRef(); + da2->decrRef(); + da->decrRef(); +} + +void MEDCouplingBasicsTest3::testDAIsUniform1() +{ + const int tab1[5]={1,1,1,1,1}; + DataArrayInt *da=DataArrayInt::New(); + da->alloc(5,1); + std::copy(tab1,tab1+5,da->getPointer()); + CPPUNIT_ASSERT(da->isUniform(1)); + da->setIJ(2,0,2); + CPPUNIT_ASSERT(!da->isUniform(1)); + da->setIJ(2,0,1); + CPPUNIT_ASSERT(da->isUniform(1)); + DataArrayDouble *da2=da->convertToDblArr(); + CPPUNIT_ASSERT(da2->isUniform(1.,1e-12)); + da2->setIJ(1,0,1.+1.e-13); + CPPUNIT_ASSERT(da2->isUniform(1.,1e-12)); + da2->setIJ(1,0,1.+1.e-11); + CPPUNIT_ASSERT(!da2->isUniform(1.,1e-12)); + da2->decrRef(); + da->decrRef(); +} + +void MEDCouplingBasicsTest3::testDADFromPolarToCart1() +{ + const double tab1[4]={2.,0.2,2.5,0.7}; + DataArrayDouble *da=DataArrayDouble::New(); + da->alloc(2,2); + std::copy(tab1,tab1+4,da->getPointer()); + DataArrayDouble *da2=da->fromPolarToCart(); + const double expected1[4]={1.9601331556824833,0.39733866159012243, 1.9121054682112213,1.6105442180942275}; + for(int i=0;i<4;i++) + CPPUNIT_ASSERT_DOUBLES_EQUAL(expected1[i],da2->getIJ(0,i),1e-13); + da2->decrRef(); + da->decrRef(); +} + +void MEDCouplingBasicsTest3::testDADFromCylToCart1() +{ + const double tab1[6]={2.,0.2,4.,2.5,0.7,9.}; + DataArrayDouble *da=DataArrayDouble::New(); + da->alloc(2,3); + std::copy(tab1,tab1+6,da->getPointer()); + DataArrayDouble *da2=da->fromCylToCart(); + const double expected1[6]={1.9601331556824833,0.39733866159012243,4., 1.9121054682112213,1.6105442180942275,9.}; + for(int i=0;i<6;i++) + CPPUNIT_ASSERT_DOUBLES_EQUAL(expected1[i],da2->getIJ(0,i),1e-13); + da2->decrRef(); + da->decrRef(); +} + +void MEDCouplingBasicsTest3::testDADFromSpherToCart1() +{ + const double tab1[6]={2.,0.2,0.3,2.5,0.7,0.8}; + DataArrayDouble *da=DataArrayDouble::New(); + da->alloc(2,3); + std::copy(tab1,tab1+6,da->getPointer()); + DataArrayDouble *da2=da->fromSpherToCart(); + const double expected1[6]={0.37959212195737485,0.11742160338765303,1.9601331556824833, 1.1220769624465328,1.1553337045129035,1.9121054682112213}; + for(int i=0;i<6;i++) + CPPUNIT_ASSERT_DOUBLES_EQUAL(expected1[i],da2->getIJ(0,i),1e-13); + da2->decrRef(); + da->decrRef(); +} + +void MEDCouplingBasicsTest3::testUnPolyze1() +{ + const int elts[8]={0,1,2,3,4,5,6,7}; + std::vector<int> eltsV(elts,elts+8); + MEDCouplingUMesh *mesh=build3DTargetMesh_1(); + mesh->convertToPolyTypes(&eltsV[0],&eltsV[0]+eltsV.size()); + mesh->unPolyze(); + MEDCouplingUMesh *mesh2=build3DTargetMesh_1(); + mesh->checkCoherency(); + CPPUNIT_ASSERT(mesh->isEqual(mesh2,1e-12)); + mesh->convertToPolyTypes(&eltsV[0],&eltsV[0]+eltsV.size()); + CPPUNIT_ASSERT(!mesh->isEqual(mesh2,1e-12)); + mesh->getNodalConnectivity()->setIJ(0,6,10); + mesh->getNodalConnectivity()->setIJ(0,7,9); + mesh->getNodalConnectivity()->setIJ(0,8,12); + mesh->getNodalConnectivity()->setIJ(0,9,13); + mesh->unPolyze(); + CPPUNIT_ASSERT(mesh->isEqual(mesh2,1e-12)); + mesh->convertToPolyTypes(&eltsV[0],&eltsV[0]+eltsV.size()); + mesh->getNodalConnectivity()->setIJ(0,6,12); + mesh->getNodalConnectivity()->setIJ(0,7,13); + mesh->getNodalConnectivity()->setIJ(0,8,10); + mesh->getNodalConnectivity()->setIJ(0,9,9); + mesh->unPolyze(); + CPPUNIT_ASSERT(mesh->isEqual(mesh2,1e-12)); + mesh->convertToPolyTypes(&eltsV[0],&eltsV[0]+eltsV.size()); + mesh->getNodalConnectivity()->setIJ(0,6,12); + mesh->getNodalConnectivity()->setIJ(0,7,10); + mesh->getNodalConnectivity()->setIJ(0,8,13); + mesh->getNodalConnectivity()->setIJ(0,9,9); + mesh->unPolyze(); + CPPUNIT_ASSERT(!mesh->isEqual(mesh2,1e-12)); + mesh->decrRef(); + mesh2->decrRef(); + // Test for 2D mesh + mesh=build2DTargetMesh_1(); + mesh2=build2DTargetMesh_1(); + eltsV.resize(5); + mesh->convertToPolyTypes(&eltsV[0],&eltsV[0]+eltsV.size()); + CPPUNIT_ASSERT(!mesh->isEqual(mesh2,1e-12)); + mesh->unPolyze(); + CPPUNIT_ASSERT(mesh->isEqual(mesh2,1e-12)); + mesh->decrRef(); + mesh2->decrRef(); +} + +void MEDCouplingBasicsTest3::testConvertDegeneratedCells1() +{ + MEDCouplingUMesh *mesh=build3DTargetMesh_1(); + int conn[32]={0,1,3,3,9,10,12,12, 0,1,3,4,9,9,9,9, 1,1,1,1,10,12,9,10, 10,11,12,9,1,1,1,1}; + mesh->allocateCells(4); + mesh->insertNextCell(INTERP_KERNEL::NORM_HEXA8,8,conn); + mesh->insertNextCell(INTERP_KERNEL::NORM_HEXA8,8,conn+8); + mesh->insertNextCell(INTERP_KERNEL::NORM_HEXA8,8,conn+16); + mesh->insertNextCell(INTERP_KERNEL::NORM_HEXA8,8,conn+24); + mesh->finishInsertingCells(); + mesh->checkCoherency(); + CPPUNIT_ASSERT_EQUAL(4,mesh->getNumberOfCells()); + CPPUNIT_ASSERT_EQUAL(INTERP_KERNEL::NORM_HEXA8,mesh->getTypeOfCell(0)); + CPPUNIT_ASSERT_EQUAL(INTERP_KERNEL::NORM_HEXA8,mesh->getTypeOfCell(1)); + CPPUNIT_ASSERT_EQUAL(INTERP_KERNEL::NORM_HEXA8,mesh->getTypeOfCell(2)); + CPPUNIT_ASSERT_EQUAL(INTERP_KERNEL::NORM_HEXA8,mesh->getTypeOfCell(3)); + MEDCouplingFieldDouble *f1=mesh->getMeasureField(true); + mesh->convertDegeneratedCells(); + mesh->checkCoherency(); + MEDCouplingFieldDouble *f2=mesh->getMeasureField(true); + CPPUNIT_ASSERT_EQUAL(4,mesh->getNumberOfCells()); + CPPUNIT_ASSERT_EQUAL(INTERP_KERNEL::NORM_PENTA6,mesh->getTypeOfCell(0)); + CPPUNIT_ASSERT_EQUAL(INTERP_KERNEL::NORM_PYRA5,mesh->getTypeOfCell(1)); + CPPUNIT_ASSERT_EQUAL(INTERP_KERNEL::NORM_TETRA4,mesh->getTypeOfCell(2)); + CPPUNIT_ASSERT_EQUAL(INTERP_KERNEL::NORM_PYRA5,mesh->getTypeOfCell(3)); + for(int i=0;i<4;i++) + CPPUNIT_ASSERT_DOUBLES_EQUAL(f1->getArray()->getIJ(0,i),f2->getArray()->getIJ(0,i),1e-5); + f1->decrRef(); + f2->decrRef(); + mesh->decrRef(); +} + +void MEDCouplingBasicsTest3::testGetNodeIdsNearPoints1() +{ + MEDCouplingUMesh *mesh=build2DTargetMesh_1(); + DataArrayDouble *coords=mesh->getCoords(); + DataArrayDouble *tmp=DataArrayDouble::New(); + tmp->alloc(3,2); + const double vals[6]={0.2,0.2,0.1,0.2,0.2,0.2}; + std::copy(vals,vals+6,tmp->getPointer()); + DataArrayDouble *tmp2=DataArrayDouble::Aggregate(coords,tmp); + tmp->decrRef(); + mesh->setCoords(tmp2); + tmp2->decrRef(); + const double pts[6]={0.2,0.2,0.1,0.3,-0.3,0.7}; + DataArrayInt *c=mesh->getNodeIdsNearPoint(pts,1e-7); + CPPUNIT_ASSERT_EQUAL(3,c->getNumberOfTuples()); + CPPUNIT_ASSERT_EQUAL(4,c->getIJ(0,0)); + CPPUNIT_ASSERT_EQUAL(9,c->getIJ(1,0)); + CPPUNIT_ASSERT_EQUAL(11,c->getIJ(2,0)); + c->decrRef(); + DataArrayInt *cI=0; + mesh->getNodeIdsNearPoints(pts,3,1e-7,c,cI); + CPPUNIT_ASSERT_EQUAL(4,cI->getNumberOfTuples()); + CPPUNIT_ASSERT_EQUAL(4,c->getNumberOfTuples()); + CPPUNIT_ASSERT_EQUAL(4,c->getIJ(0,0)); + CPPUNIT_ASSERT_EQUAL(9,c->getIJ(1,0)); + CPPUNIT_ASSERT_EQUAL(11,c->getIJ(2,0)); + CPPUNIT_ASSERT_EQUAL(6,c->getIJ(3,0)); + CPPUNIT_ASSERT_EQUAL(0,cI->getIJ(0,0)); + CPPUNIT_ASSERT_EQUAL(3,cI->getIJ(1,0)); + CPPUNIT_ASSERT_EQUAL(3,cI->getIJ(2,0)); + CPPUNIT_ASSERT_EQUAL(4,cI->getIJ(3,0)); + c->decrRef(); + cI->decrRef(); + mesh->decrRef(); +} + +void MEDCouplingBasicsTest3::testFieldCopyTinyAttrFrom1() +{ + MEDCouplingFieldDouble *f1=MEDCouplingFieldDouble::New(ON_CELLS,ONE_TIME); + f1->setName("f1"); + f1->setTimeTolerance(1.e-5); + f1->setDescription("f1Desc"); + f1->setTime(1.23,4,5); + MEDCouplingFieldDouble *f2=MEDCouplingFieldDouble::New(ON_CELLS,ONE_TIME); + f2->setName("f2"); + f2->setDescription("f2Desc"); + f2->setTime(6.78,9,10); + f2->setTimeTolerance(4.556e-12); + // + int dt,it; + f1->copyTinyAttrFrom(f2); + CPPUNIT_ASSERT_DOUBLES_EQUAL(4.556e-12,f1->getTimeTolerance(),1e-24); + CPPUNIT_ASSERT_DOUBLES_EQUAL(6.78,f1->getTime(dt,it),1e-12); + CPPUNIT_ASSERT_EQUAL(9,dt); + CPPUNIT_ASSERT_EQUAL(10,it); + CPPUNIT_ASSERT(std::string(f1->getName())=="f1");//name unchanged + CPPUNIT_ASSERT(std::string(f1->getDescription())=="f1Desc");//description unchanged + f1->decrRef(); + f2->decrRef(); + // + f1=MEDCouplingFieldDouble::New(ON_CELLS,NO_TIME); + f1->setName("f1"); + f1->setTimeTolerance(1.e-5); + f1->setDescription("f1Desc"); + f2=MEDCouplingFieldDouble::New(ON_CELLS,NO_TIME); + f2->setName("f2"); + f2->setDescription("f2Desc"); + f2->setTimeTolerance(4.556e-12); + // + f1->copyTinyAttrFrom(f2); + CPPUNIT_ASSERT_DOUBLES_EQUAL(4.556e-12,f1->getTimeTolerance(),1e-24); + CPPUNIT_ASSERT(std::string(f1->getName())=="f1");//name unchanged + CPPUNIT_ASSERT(std::string(f1->getDescription())=="f1Desc");//description unchanged + f1->decrRef(); + f2->decrRef(); + // + f1=MEDCouplingFieldDouble::New(ON_CELLS,CONST_ON_TIME_INTERVAL); + f1->setName("f1"); + f1->setTimeTolerance(1.e-5); + f1->setDescription("f1Desc"); + f1->setTime(1.23,4,5); + f1->setEndTime(5.43,2,1); + f2=MEDCouplingFieldDouble::New(ON_CELLS,CONST_ON_TIME_INTERVAL); + f2->setName("f2"); + f2->setDescription("f2Desc"); + f2->setTimeTolerance(4.556e-12); + f2->setTime(6.78,9,10); + f2->setEndTime(10.98,7,6); + // + f1->copyTinyAttrFrom(f2); + CPPUNIT_ASSERT_DOUBLES_EQUAL(4.556e-12,f1->getTimeTolerance(),1e-24); + CPPUNIT_ASSERT(std::string(f1->getName())=="f1");//name unchanged + CPPUNIT_ASSERT(std::string(f1->getDescription())=="f1Desc");//description unchanged + CPPUNIT_ASSERT_DOUBLES_EQUAL(6.78,f1->getTime(dt,it),1e-12); + CPPUNIT_ASSERT_EQUAL(9,dt); + CPPUNIT_ASSERT_EQUAL(10,it); + CPPUNIT_ASSERT_DOUBLES_EQUAL(10.98,f1->getEndTime(dt,it),1e-12); + CPPUNIT_ASSERT_EQUAL(7,dt); + CPPUNIT_ASSERT_EQUAL(6,it); + f1->decrRef(); + f2->decrRef(); + // + f1=MEDCouplingFieldDouble::New(ON_CELLS,LINEAR_TIME); + f1->setName("f1"); + f1->setTimeTolerance(1.e-5); + f1->setDescription("f1Desc"); + f1->setTime(1.23,4,5); + f1->setEndTime(5.43,2,1); + f2=MEDCouplingFieldDouble::New(ON_CELLS,LINEAR_TIME); + f2->setName("f2"); + f2->setDescription("f2Desc"); + f2->setTimeTolerance(4.556e-12); + f2->setTime(6.78,9,10); + f2->setEndTime(10.98,7,6); + // + f1->copyTinyAttrFrom(f2); + CPPUNIT_ASSERT_DOUBLES_EQUAL(4.556e-12,f1->getTimeTolerance(),1e-24); + CPPUNIT_ASSERT(std::string(f1->getName())=="f1");//name unchanged + CPPUNIT_ASSERT(std::string(f1->getDescription())=="f1Desc");//description unchanged + CPPUNIT_ASSERT_DOUBLES_EQUAL(6.78,f1->getTime(dt,it),1e-12); + CPPUNIT_ASSERT_EQUAL(9,dt); + CPPUNIT_ASSERT_EQUAL(10,it); + CPPUNIT_ASSERT_DOUBLES_EQUAL(10.98,f1->getEndTime(dt,it),1e-12); + CPPUNIT_ASSERT_EQUAL(7,dt); + CPPUNIT_ASSERT_EQUAL(6,it); + f1->decrRef(); + f2->decrRef(); +} + +/*! + * 1D -> 2D extrusion with rotation + */ +void MEDCouplingBasicsTest3::testExtrudedMesh5() +{ + const double coo1[4]={0.,1.,2.,3.5}; + DataArrayDouble *a=DataArrayDouble::New(); + a->alloc(4,1); + std::copy(coo1,coo1+4,a->getPointer()); + MEDCouplingCMesh *b=MEDCouplingCMesh::New(); + b->setCoordsAt(0,a); + MEDCouplingUMesh *c=b->buildUnstructured(); + CPPUNIT_ASSERT_EQUAL(1,c->getSpaceDimension()); + c->changeSpaceDimension(2); + // + DataArrayDouble *d=DataArrayDouble::New(); + d->alloc(13,1); + d->iota(); + MEDCouplingCMesh *ee=MEDCouplingCMesh::New(); + ee->setCoordsAt(0,d); + MEDCouplingUMesh *f=ee->buildUnstructured(); + DataArrayDouble *g=f->getCoords()->applyFunc(2,"3.5*IVec+x/6*3.14159265359*JVec"); + CPPUNIT_ASSERT_THROW(f->getCoords()->applyFunc(2,"3.5*IVec+x/6*3.14159265359*KVec"),INTERP_KERNEL::Exception); // KVec refers to component #2 and there is only 2 components ! + DataArrayDouble *h=g->fromPolarToCart(); + f->setCoords(h); + MEDCouplingUMesh *i=c->buildExtrudedMesh(f,1); + CPPUNIT_ASSERT_EQUAL(52,i->getNumberOfNodes()); + bool tmp2; + int tmp3; + DataArrayInt *tmp=i->mergeNodes(1e-9,tmp2,tmp3); + CPPUNIT_ASSERT(tmp2); + CPPUNIT_ASSERT_EQUAL(37,tmp3); + tmp->decrRef(); + i->convertDegeneratedCells(); + i->checkCoherency(); + CPPUNIT_ASSERT_EQUAL(36,i->getNumberOfCells()); + CPPUNIT_ASSERT_EQUAL(37,i->getNumberOfNodes()); + CPPUNIT_ASSERT_EQUAL(12,i->getNumberOfCellsWithType(INTERP_KERNEL::NORM_TRI3)); + CPPUNIT_ASSERT_EQUAL(24,i->getNumberOfCellsWithType(INTERP_KERNEL::NORM_QUAD4)); + const double expected1[3]={0.25,0.75,2.0625}; + MEDCouplingFieldDouble *j=i->getMeasureField(true); + for(int ii=0;ii<12;ii++) + for(int k=0;k<3;k++) + CPPUNIT_ASSERT_DOUBLES_EQUAL(expected1[k],j->getIJ(0,ii*3+k),1e-10); + const double expected2[72]={0.62200846792814113, 0.16666666666681595, 1.4513530918323276, 0.38888888888923495, 2.6293994326053212, 0.7045454545460802, 0.45534180126145435, 0.45534180126150181, 1.0624642029433926, 1.0624642029435025, 1.9248539780597826, 1.9248539780599816, 0.16666666666661334, 0.62200846792815856, 0.38888888888876294, 1.4513530918323678, 0.70454545454522521, 2.629399432605394, -0.16666666666674007, 0.62200846792812436, -0.38888888888906142, 1.4513530918322881, -0.70454545454576778, 2.6293994326052488, -0.45534180126154766, 0.45534180126140844, -1.0624642029436118, 1.0624642029432834, -1.9248539780601803, 1.9248539780595841, -0.62200846792817499, 0.1666666666665495, -1.451353091832408, 0.388888888888613, -2.6293994326054668, 0.70454545454495332, -0.62200846792810593, -0.16666666666680507, -1.451353091832247, -0.38888888888921297, -2.6293994326051746, -0.70454545454604123, -0.45534180126135926, -0.45534180126159562, -1.0624642029431723, -1.0624642029437235, -1.9248539780593836, -1.9248539780603811, -0.1666666666664828, -0.62200846792819242, -0.38888888888846079, -1.4513530918324489, -0.70454545454467987, -2.6293994326055397, 0.16666666666687083, -0.62200846792808862, 0.38888888888936374, -1.4513530918322073, 0.70454545454631357, -2.6293994326051022, 0.45534180126164348, -0.45534180126131207, 1.0624642029438327, -1.0624642029430627, 1.9248539780605791, -1.9248539780591853, 0.62200846792821063, -0.16666666666641802, 1.4513530918324888, -0.38888888888831086, 2.6293994326056125, -0.70454545454440853}; + DataArrayDouble *m=i->getBarycenterAndOwner(); + for(int ii=0;ii<72;ii++) + CPPUNIT_ASSERT_DOUBLES_EQUAL(expected2[ii],m->getIJ(0,ii),1e-10); + // + m->decrRef(); + j->decrRef(); + i->decrRef(); + h->decrRef(); + g->decrRef(); + f->decrRef(); + ee->decrRef(); + d->decrRef(); + c->decrRef(); + b->decrRef(); + a->decrRef(); +} + +/*! + * 1D -> 2D extrusion without rotation + */ +void MEDCouplingBasicsTest3::testExtrudedMesh6() +{ + const double coo1[4]={0.,1.,2.,3.5}; + DataArrayDouble *a=DataArrayDouble::New(); + a->alloc(4,1); + std::copy(coo1,coo1+4,a->getPointer()); + MEDCouplingCMesh *b=MEDCouplingCMesh::New(); + b->setCoordsAt(0,a); + MEDCouplingUMesh *c=b->buildUnstructured(); + CPPUNIT_ASSERT_EQUAL(1,c->getSpaceDimension()); + c->changeSpaceDimension(2); + // + DataArrayDouble *d=DataArrayDouble::New(); + d->alloc(5,1); + d->iota(); + MEDCouplingCMesh *e=MEDCouplingCMesh::New(); + e->setCoordsAt(0,d); + MEDCouplingUMesh *f=e->buildUnstructured(); + DataArrayDouble *d2=f->getCoords()->applyFunc("x*x/2"); + f->setCoords(d2); + f->changeSpaceDimension(2); + // + const double center[2]={0.,0.}; + f->rotate(center,0,M_PI/3); + MEDCouplingUMesh *g=c->buildExtrudedMesh(f,0); + g->checkCoherency(); + const double expected1[]={ 0.4330127018922193, 0.4330127018922193, 0.649519052838329, 1.2990381056766578, 1.299038105676658, 1.948557158514987, 2.1650635094610955, 2.1650635094610964, 3.2475952641916446, 3.031088913245533, 3.0310889132455352, 4.546633369868303 }; + MEDCouplingFieldDouble *f1=g->getMeasureField(true); + for(int i=0;i<12;i++) + CPPUNIT_ASSERT_DOUBLES_EQUAL(expected1[i],f1->getIJ(0,i),1e-12); + + const double expected2[]={0.625, 0.21650635094610962, 1.625, 0.21650635094610959, 2.8750000000000004, 0.21650635094610965, 1.1250000000000002, 1.0825317547305482, 2.125, 1.0825317547305482, 3.3750000000000004, 1.0825317547305484, 2.125, 2.8145825622994254, 3.125, 2.8145825622994254, 4.375, 2.8145825622994254, 3.6250000000000009, 5.4126587736527414, 4.625, 5.4126587736527414, 5.875, 5.4126587736527414}; + DataArrayDouble *f2=g->getBarycenterAndOwner(); + for(int i=0;i<24;i++) + CPPUNIT_ASSERT_DOUBLES_EQUAL(expected2[i],f2->getIJ(0,i),1e-12); + // + f1->decrRef(); + f2->decrRef(); + g->decrRef(); + f->decrRef(); + e->decrRef(); + d->decrRef(); + d2->decrRef(); + c->decrRef(); + b->decrRef(); + a->decrRef(); +} + +/*! + * 2D -> 3D extrusion with rotation + */ +void MEDCouplingBasicsTest3::testExtrudedMesh7() +{ + const double coo1[4]={0.,1.,2.,3.5}; + DataArrayDouble *a=DataArrayDouble::New(); + a->alloc(4,1); + std::copy(coo1,coo1+4,a->getPointer()); + MEDCouplingCMesh *b=MEDCouplingCMesh::New(); + b->setCoordsAt(0,a); + MEDCouplingUMesh *c=b->buildUnstructured(); + CPPUNIT_ASSERT_EQUAL(1,c->getSpaceDimension()); + c->changeSpaceDimension(2); + // + DataArrayDouble *d=DataArrayDouble::New(); + d->alloc(13,1); + d->iota(); + MEDCouplingCMesh *e=MEDCouplingCMesh::New(); + e->setCoordsAt(0,d); + MEDCouplingUMesh *f=e->buildUnstructured(); + DataArrayDouble *g=f->getCoords()->applyFunc(2,"3.5*IVec+x/6*3.14159265359*JVec"); + DataArrayDouble *h=g->fromPolarToCart(); + f->setCoords(h); + MEDCouplingUMesh *i=c->buildExtrudedMesh(f,1); + CPPUNIT_ASSERT_EQUAL(52,i->getNumberOfNodes()); + bool tmp2; + int tmp3; + DataArrayInt *tmp=i->mergeNodes(1e-9,tmp2,tmp3); + CPPUNIT_ASSERT(tmp2); + CPPUNIT_ASSERT_EQUAL(37,tmp3); + tmp->decrRef(); + i->convertDegeneratedCells(); + const double vec1[3]={10.,0.,0.}; + i->translate(vec1); + DataArrayDouble *g2=h->applyFunc(3,"13.5/3.5*x*IVec+0*JVec+13.5/3.5*y*KVec"); + f->setCoords(g2); + i->changeSpaceDimension(3); + MEDCouplingUMesh *i3=i->buildExtrudedMesh(f,1); + MEDCouplingFieldDouble *f2=i3->getMeasureField(true); + tmp=i->mergeNodes(1e-9,tmp2,tmp3); + CPPUNIT_ASSERT(tmp2); + CPPUNIT_ASSERT_EQUAL(444,tmp3); + tmp->decrRef(); + const double expected1[36]={1.327751058489274, 4.2942574094314701, 13.024068164857139, 1.3069177251569044, 4.1484240761012954, 12.297505664866796, 1.270833333332571, 3.8958333333309674, 11.039062499993179, 1.2291666666659207, 3.6041666666644425, 9.585937499993932, 1.1930822748415895, 3.3515759238941376, 8.3274943351204556, 1.1722489415082769, 3.2057425905609289, 7.6009318351210622, 1.1722489415082862, 3.2057425905609884, 7.6009318351213713, 1.1930822748416161, 3.3515759238943001, 8.3274943351212727, 1.2291666666659564, 3.6041666666646734, 9.5859374999950777, 1.2708333333326081, 3.8958333333311868, 11.039062499994293, 1.3069177251569224, 4.1484240761014384, 12.297505664867627, 1.3277510584902354, 4.2942574094346071, 13.024068164866796}; + int kk=0; + for(int ii=0;ii<12;ii++) + for(int jj=0;jj<36;jj++,kk++) + CPPUNIT_ASSERT_DOUBLES_EQUAL(expected1[jj],f2->getIJ(0,kk),1e-9); + // + f2->decrRef(); + i3->decrRef(); + g2->decrRef(); + i->decrRef(); + h->decrRef(); + g->decrRef(); + f->decrRef(); + e->decrRef(); + d->decrRef(); + c->decrRef(); + b->decrRef(); + a->decrRef(); +} + +void MEDCouplingBasicsTest3::testSimplexize1() +{ + MEDCouplingUMesh *m=build3DSurfTargetMesh_1(); + std::vector<int> v(1); + v[0]=3; + m->convertToPolyTypes(&v[0],&v[0]+v.size()); + DataArrayInt *da=m->simplexize(0); + CPPUNIT_ASSERT_EQUAL(7,da->getNumberOfTuples()); + CPPUNIT_ASSERT_EQUAL(1,da->getNumberOfComponents()); + const int expected2[7]={0,0,1,2,3,4,4}; + for(int i=0;i<7;i++) + CPPUNIT_ASSERT_EQUAL(expected2[i],da->getIJ(i,0)); + m->checkCoherency(); + CPPUNIT_ASSERT_EQUAL(7,m->getNumberOfCells()); + CPPUNIT_ASSERT_EQUAL(INTERP_KERNEL::NORM_TRI3,m->getTypeOfCell(0)); + CPPUNIT_ASSERT_EQUAL(INTERP_KERNEL::NORM_TRI3,m->getTypeOfCell(1)); + CPPUNIT_ASSERT_EQUAL(INTERP_KERNEL::NORM_TRI3,m->getTypeOfCell(2)); + CPPUNIT_ASSERT_EQUAL(INTERP_KERNEL::NORM_TRI3,m->getTypeOfCell(3)); + CPPUNIT_ASSERT_EQUAL(INTERP_KERNEL::NORM_POLYGON,m->getTypeOfCell(4)); + CPPUNIT_ASSERT_EQUAL(INTERP_KERNEL::NORM_TRI3,m->getTypeOfCell(5)); + CPPUNIT_ASSERT_EQUAL(INTERP_KERNEL::NORM_TRI3,m->getTypeOfCell(6)); + const double expected1[7]={0.125,0.125,0.125,0.125,0.25,0.125,0.125}; + MEDCouplingFieldDouble *f=m->getMeasureField(false); + for(int i=0;i<7;i++) + CPPUNIT_ASSERT_DOUBLES_EQUAL(expected1[i]*sqrt(2.),f->getIJ(i,0),1e-10); + std::set<INTERP_KERNEL::NormalizedCellType> types=m->getAllGeoTypes(); + CPPUNIT_ASSERT_EQUAL(2,(int)types.size()); + CPPUNIT_ASSERT_EQUAL(INTERP_KERNEL::NORM_TRI3,*(types.begin())); + CPPUNIT_ASSERT_EQUAL(INTERP_KERNEL::NORM_POLYGON,*(++(types.begin()))); + f->decrRef(); + da->decrRef(); + m->decrRef(); + // + m=build3DSurfTargetMesh_1(); + v[0]=3; + m->convertToPolyTypes(&v[0],&v[0]+v.size()); + da=m->simplexize(1); + CPPUNIT_ASSERT_EQUAL(7,da->getNumberOfTuples()); + CPPUNIT_ASSERT_EQUAL(1,da->getNumberOfComponents()); + for(int i=0;i<7;i++) + CPPUNIT_ASSERT_EQUAL(expected2[i],da->getIJ(i,0)); + m->checkCoherency(); + types=m->getAllGeoTypes(); + CPPUNIT_ASSERT_EQUAL(2,(int)types.size()); + CPPUNIT_ASSERT_EQUAL(INTERP_KERNEL::NORM_TRI3,*(types.begin())); + CPPUNIT_ASSERT_EQUAL(INTERP_KERNEL::NORM_POLYGON,*(++(types.begin()))); + CPPUNIT_ASSERT_EQUAL(7,m->getNumberOfCells()); + CPPUNIT_ASSERT_EQUAL(INTERP_KERNEL::NORM_TRI3,m->getTypeOfCell(0)); + CPPUNIT_ASSERT_EQUAL(INTERP_KERNEL::NORM_TRI3,m->getTypeOfCell(1)); + CPPUNIT_ASSERT_EQUAL(INTERP_KERNEL::NORM_TRI3,m->getTypeOfCell(2)); + CPPUNIT_ASSERT_EQUAL(INTERP_KERNEL::NORM_TRI3,m->getTypeOfCell(3)); + CPPUNIT_ASSERT_EQUAL(INTERP_KERNEL::NORM_POLYGON,m->getTypeOfCell(4)); + CPPUNIT_ASSERT_EQUAL(INTERP_KERNEL::NORM_TRI3,m->getTypeOfCell(5)); + CPPUNIT_ASSERT_EQUAL(INTERP_KERNEL::NORM_TRI3,m->getTypeOfCell(6)); + f=m->getMeasureField(false); + for(int i=0;i<7;i++) + CPPUNIT_ASSERT_DOUBLES_EQUAL(expected1[i]*sqrt(2.),f->getIJ(i,0),1e-10); + f->decrRef(); + da->decrRef(); + m->decrRef(); +} + +void MEDCouplingBasicsTest3::testSimplexize2() +{ + MEDCouplingUMesh *m=build3DSurfTargetMesh_1(); + std::vector<int> v(1); + v[0]=3; + m->convertToPolyTypes(&v[0],&v[0]+v.size()); + MEDCouplingFieldDouble *f1=MEDCouplingFieldDouble::New(ON_CELLS,ONE_TIME); + f1->setMesh(m); + DataArrayDouble *arr=DataArrayDouble::New(); + const double arr1[10]={10.,110.,20.,120.,30.,130.,40.,140.,50.,150.}; + arr->alloc(5,2); + std::copy(arr1,arr1+10,arr->getPointer()); + f1->setArray(arr); + arr->decrRef(); + // + f1->checkCoherency(); + CPPUNIT_ASSERT(f1->simplexize(0)); + f1->checkCoherency(); + const double expected1[14]={10.,110.,10.,110.,20.,120.,30.,130.,40.,140.,50.,150.,50.,150.}; + for(int i=0;i<14;i++) + CPPUNIT_ASSERT_DOUBLES_EQUAL(expected1[i],f1->getIJ(0,i),1e-10); + CPPUNIT_ASSERT(!f1->simplexize(0)); + for(int i=0;i<14;i++) + CPPUNIT_ASSERT_DOUBLES_EQUAL(expected1[i],f1->getIJ(0,i),1e-10); + // + f1->decrRef(); + m->decrRef(); +} + +void MEDCouplingBasicsTest3::testDAMeld1() +{ + DataArrayDouble *da1=DataArrayDouble::New(); + da1->alloc(7,2); + DataArrayDouble *da2=DataArrayDouble::New(); + da2->alloc(7,1); + // + da1->fillWithValue(7.); + da2->iota(0.); + DataArrayDouble *da3=da2->applyFunc(3,"10*x*IVec+100*x*JVec+1000*x*KVec"); + // + da1->setInfoOnComponent(0,"c0da1"); + da1->setInfoOnComponent(1,"c1da1"); + da3->setInfoOnComponent(0,"c0da3"); + da3->setInfoOnComponent(1,"c1da3"); + da3->setInfoOnComponent(2,"c2da3"); + // + DataArrayDouble *da1C=da1->deepCpy(); + da1->meldWith(da3); + CPPUNIT_ASSERT_EQUAL(5,da1->getNumberOfComponents()); + CPPUNIT_ASSERT_EQUAL(7,da1->getNumberOfTuples()); + CPPUNIT_ASSERT(da1->getInfoOnComponent(0)=="c0da1"); + CPPUNIT_ASSERT(da1->getInfoOnComponent(1)=="c1da1"); + CPPUNIT_ASSERT(da1->getInfoOnComponent(2)=="c0da3"); + CPPUNIT_ASSERT(da1->getInfoOnComponent(3)=="c1da3"); + CPPUNIT_ASSERT(da1->getInfoOnComponent(4)=="c2da3"); + // + const double expected1[35]={7.,7.,0.,0.,0., 7.,7.,10.,100.,1000., 7.,7.,20.,200.,2000., 7.,7.,30.,300.,3000., 7.,7.,40.,400.,4000.,7.,7.,50.,500.,5000.,7.,7.,60.,600.,6000.}; + for(int i=0;i<35;i++) + CPPUNIT_ASSERT_DOUBLES_EQUAL(expected1[i],da1->getIJ(0,i),1e-10); + // + DataArrayInt *dai1=da1C->convertToIntArr(); + DataArrayInt *dai3=da3->convertToIntArr(); + dai1->meldWith(dai3); + CPPUNIT_ASSERT_EQUAL(5,dai1->getNumberOfComponents()); + CPPUNIT_ASSERT_EQUAL(7,dai1->getNumberOfTuples()); + CPPUNIT_ASSERT(dai1->getInfoOnComponent(0)=="c0da1"); + CPPUNIT_ASSERT(dai1->getInfoOnComponent(1)=="c1da1"); + CPPUNIT_ASSERT(dai1->getInfoOnComponent(2)=="c0da3"); + CPPUNIT_ASSERT(dai1->getInfoOnComponent(3)=="c1da3"); + CPPUNIT_ASSERT(dai1->getInfoOnComponent(4)=="c2da3"); + for(int i=0;i<35;i++) + CPPUNIT_ASSERT_EQUAL((int)expected1[i],dai1->getIJ(0,i)); + // test of static method DataArrayDouble::meld + DataArrayDouble *da4=DataArrayDouble::Meld(da1C,da3); + CPPUNIT_ASSERT_EQUAL(5,da4->getNumberOfComponents()); + CPPUNIT_ASSERT_EQUAL(7,da4->getNumberOfTuples()); + CPPUNIT_ASSERT(da4->getInfoOnComponent(0)=="c0da1"); + CPPUNIT_ASSERT(da4->getInfoOnComponent(1)=="c1da1"); + CPPUNIT_ASSERT(da4->getInfoOnComponent(2)=="c0da3"); + CPPUNIT_ASSERT(da4->getInfoOnComponent(3)=="c1da3"); + CPPUNIT_ASSERT(da4->getInfoOnComponent(4)=="c2da3"); + for(int i=0;i<35;i++) + CPPUNIT_ASSERT_DOUBLES_EQUAL(expected1[i],da4->getIJ(0,i),1e-10); + // test of static method DataArrayInt::meld + dai1->decrRef(); + dai1=da1C->convertToIntArr(); + DataArrayInt *dai4=DataArrayInt::Meld(dai1,dai3); + CPPUNIT_ASSERT_EQUAL(5,dai4->getNumberOfComponents()); + CPPUNIT_ASSERT_EQUAL(7,dai4->getNumberOfTuples()); + CPPUNIT_ASSERT(dai4->getInfoOnComponent(0)=="c0da1"); + CPPUNIT_ASSERT(dai4->getInfoOnComponent(1)=="c1da1"); + CPPUNIT_ASSERT(dai4->getInfoOnComponent(2)=="c0da3"); + CPPUNIT_ASSERT(dai4->getInfoOnComponent(3)=="c1da3"); + CPPUNIT_ASSERT(dai4->getInfoOnComponent(4)=="c2da3"); + for(int i=0;i<35;i++) + CPPUNIT_ASSERT_EQUAL((int)expected1[i],dai4->getIJ(0,i)); + // + dai4->decrRef(); + da4->decrRef(); + dai3->decrRef(); + dai1->decrRef(); + da1C->decrRef(); + da1->decrRef(); + da2->decrRef(); + da3->decrRef(); +} + +void MEDCouplingBasicsTest3::testFieldMeld1() +{ + MEDCouplingUMesh *m=build3DSurfTargetMesh_1(); + MEDCouplingFieldDouble *f1=MEDCouplingFieldDouble::New(ON_CELLS,ONE_TIME); + f1->setMesh(m); + DataArrayDouble *da1=DataArrayDouble::New(); + const double arr1[5]={12.,23.,34.,45.,56.}; + da1->alloc(5,1); + std::copy(arr1,arr1+5,da1->getPointer()); + da1->setInfoOnComponent(0,"aaa"); + f1->setArray(da1); + f1->setTime(3.4,2,1); + f1->checkCoherency(); + // + MEDCouplingFieldDouble *f2=f1->deepCpy(); + f2->setMesh(f1->getMesh()); + f2->checkCoherency(); + f2->changeNbOfComponents(2,5.); + (*f2)=5.; + f2->getArray()->setInfoOnComponent(0,"bbb"); + f2->getArray()->setInfoOnComponent(1,"ccc"); + f2->checkCoherency(); + // + MEDCouplingFieldDouble *f3=MEDCouplingFieldDouble::MeldFields(f2,f1); + f3->checkCoherency(); + CPPUNIT_ASSERT_EQUAL(5,f3->getNumberOfTuples()); + CPPUNIT_ASSERT_EQUAL(3,f3->getNumberOfComponents()); + CPPUNIT_ASSERT(f3->getArray()->getInfoOnComponent(0)=="bbb"); + CPPUNIT_ASSERT(f3->getArray()->getInfoOnComponent(1)=="ccc"); + CPPUNIT_ASSERT(f3->getArray()->getInfoOnComponent(2)=="aaa"); + const double expected1[15]={5.,5.,12.,5.,5.,23.,5.,5.,34.,5.,5.,45.,5.,5.,56.}; + for(int i=0;i<15;i++) + CPPUNIT_ASSERT_DOUBLES_EQUAL(expected1[i],f3->getIJ(0,i),1e-12); + int dt,it; + double time=f3->getTime(dt,it); + CPPUNIT_ASSERT_DOUBLES_EQUAL(3.4,time,1e-14); + CPPUNIT_ASSERT_EQUAL(2,dt); + CPPUNIT_ASSERT_EQUAL(1,it); + // + MEDCouplingFieldDouble *f4=f2->buildNewTimeReprFromThis(NO_TIME,false); + MEDCouplingFieldDouble *f5=f1->buildNewTimeReprFromThis(NO_TIME,false); + MEDCouplingFieldDouble *f6=MEDCouplingFieldDouble::MeldFields(f4,f5); + f6->checkCoherency(); + CPPUNIT_ASSERT_EQUAL(5,f6->getNumberOfTuples()); + CPPUNIT_ASSERT_EQUAL(3,f6->getNumberOfComponents()); + CPPUNIT_ASSERT(f6->getArray()->getInfoOnComponent(0)=="bbb"); + CPPUNIT_ASSERT(f6->getArray()->getInfoOnComponent(1)=="ccc"); + CPPUNIT_ASSERT(f6->getArray()->getInfoOnComponent(2)=="aaa"); + for(int i=0;i<15;i++) + CPPUNIT_ASSERT_DOUBLES_EQUAL(expected1[i],f6->getIJ(0,i),1e-12); + // + f6->decrRef(); + f4->decrRef(); + f5->decrRef(); + f3->decrRef(); + da1->decrRef(); + f2->decrRef(); + f1->decrRef(); + m->decrRef(); +} + +void MEDCouplingBasicsTest3::testMergeNodes2() +{ + MEDCouplingUMesh *m1=build2DTargetMesh_1(); + MEDCouplingUMesh *m2=build2DTargetMesh_1(); + const double vec[2]={0.002,0.}; + m2->translate(vec); + // + std::vector<const MEDCouplingUMesh *> tmp(2); + tmp[0]=m1; + tmp[1]=m2; + MEDCouplingUMesh *m3=MEDCouplingUMesh::MergeUMeshes(tmp); + bool b; + int newNbOfNodes; + DataArrayInt *da=m3->mergeNodes2(0.01,b,newNbOfNodes); + CPPUNIT_ASSERT_EQUAL(9,m3->getNumberOfNodes()); + const double expected1[18]={-0.299,-0.3, 0.201,-0.3, 0.701,-0.3, -0.299,0.2, 0.201,0.2, 0.701,0.2, -0.299,0.7, 0.201,0.7, 0.701,0.7}; + for(int i=0;i<18;i++) + CPPUNIT_ASSERT_DOUBLES_EQUAL(expected1[i],m3->getCoords()->getIJ(0,i),1e-13); + // + da->decrRef(); + m3->decrRef(); + m1->decrRef(); + m2->decrRef(); +} + +void MEDCouplingBasicsTest3::testMergeField2() +{ + MEDCouplingUMesh *m=build2DTargetMesh_1(); + MEDCouplingFieldDouble *f1=MEDCouplingFieldDouble::New(ON_CELLS,ONE_TIME); + f1->setMesh(m); + DataArrayDouble *arr=DataArrayDouble::New(); + arr->alloc(5,2); + arr->fillWithValue(2.); + f1->setArray(arr); + arr->decrRef(); + MEDCouplingFieldDouble *f2=MEDCouplingFieldDouble::New(ON_CELLS,ONE_TIME); + f2->setMesh(m); + arr=DataArrayDouble::New(); + arr->alloc(5,2); + arr->fillWithValue(5.); + f2->setArray(arr); + arr->decrRef(); + MEDCouplingFieldDouble *f3=MEDCouplingFieldDouble::New(ON_CELLS,ONE_TIME); + f3->setMesh(m); + arr=DataArrayDouble::New(); + arr->alloc(5,2); + arr->fillWithValue(7.); + f3->setArray(arr); + arr->decrRef(); + // + std::vector<const MEDCouplingFieldDouble *> tmp(3); + tmp[0]=f1; tmp[1]=f2; tmp[2]=f3; + MEDCouplingFieldDouble *f4=MEDCouplingFieldDouble::MergeFields(tmp); + CPPUNIT_ASSERT_EQUAL(15,f4->getMesh()->getNumberOfCells()); + const double expected1[30]={2.,2.,2.,2.,2.,2.,2.,2.,2.,2., 5.,5.,5.,5.,5.,5.,5.,5.,5.,5., 7.,7.,7.,7.,7.,7.,7.,7.,7.,7.}; + for(int i=0;i<30;i++) + CPPUNIT_ASSERT_DOUBLES_EQUAL(expected1[i],f4->getIJ(0,i),1.e-13); + // + f4->decrRef(); + f1->decrRef(); + f2->decrRef(); + f3->decrRef(); + m->decrRef(); +} + +void MEDCouplingBasicsTest3::testDAIBuildComplement1() +{ + DataArrayInt *a=DataArrayInt::New(); + const int tab[4]={3,1,7,8}; + a->alloc(4,1); + std::copy(tab,tab+4,a->getPointer()); + DataArrayInt *b=a->buildComplement(12); + CPPUNIT_ASSERT_EQUAL(8,b->getNumberOfTuples()); + CPPUNIT_ASSERT_EQUAL(1,b->getNumberOfComponents()); + const int expected1[8]={0,2,4,5,6,9,10,11}; + for(int i=0;i<8;i++) + CPPUNIT_ASSERT_EQUAL(expected1[i],b->getIJ(0,i)); + b->decrRef(); + a->decrRef(); +} + +void MEDCouplingBasicsTest3::testDAIBuildUnion1() +{ + DataArrayInt *a=DataArrayInt::New(); + const int tab1[4]={3,1,7,8}; + a->alloc(4,1); + std::copy(tab1,tab1+4,a->getPointer()); + DataArrayInt *c=DataArrayInt::New(); + const int tab2[5]={5,3,0,18,8}; + c->alloc(5,1); + std::copy(tab2,tab2+5,c->getPointer()); + DataArrayInt *b=a->buildUnion(c); + CPPUNIT_ASSERT_EQUAL(7,b->getNumberOfTuples()); + CPPUNIT_ASSERT_EQUAL(1,b->getNumberOfComponents()); + const int expected1[7]={0,1,3,5,7,8,18}; + for(int i=0;i<7;i++) + CPPUNIT_ASSERT_EQUAL(expected1[i],b->getIJ(0,i)); + c->decrRef(); + b->decrRef(); + a->decrRef(); +} + +void MEDCouplingBasicsTest3::testDAIBuildIntersection1() +{ + DataArrayInt *a=DataArrayInt::New(); + const int tab1[4]={3,1,7,8}; + a->alloc(4,1); + std::copy(tab1,tab1+4,a->getPointer()); + DataArrayInt *c=DataArrayInt::New(); + const int tab2[5]={5,3,0,18,8}; + c->alloc(5,1); + std::copy(tab2,tab2+5,c->getPointer()); + DataArrayInt *b=a->buildIntersection(c); + CPPUNIT_ASSERT_EQUAL(2,b->getNumberOfTuples()); + CPPUNIT_ASSERT_EQUAL(1,b->getNumberOfComponents()); + const int expected1[2]={3,8}; + for(int i=0;i<2;i++) + CPPUNIT_ASSERT_EQUAL(expected1[i],b->getIJ(0,i)); + c->decrRef(); + b->decrRef(); + a->decrRef(); +} + +void MEDCouplingBasicsTest3::testDAIDeltaShiftIndex1() +{ + DataArrayInt *a=DataArrayInt::New(); + const int tab[7]={1,3,6,7,7,9,15}; + a->alloc(7,1); + std::copy(tab,tab+7,a->getPointer()); + DataArrayInt *b=a->deltaShiftIndex(); + CPPUNIT_ASSERT_EQUAL(6,b->getNumberOfTuples()); + CPPUNIT_ASSERT_EQUAL(1,b->getNumberOfComponents()); + const int expected1[6]={2,3,1,0,2,6}; + for(int i=0;i<6;i++) + CPPUNIT_ASSERT_EQUAL(expected1[i],b->getIJ(0,i)); + b->decrRef(); + a->decrRef(); +} + +void MEDCouplingBasicsTest3::testDaDoubleSelectByTupleIdSafe1() +{ + DataArrayDouble *a=DataArrayDouble::New(); + a->alloc(7,2); + a->setInfoOnComponent(0,"toto"); + a->setInfoOnComponent(1,"tata"); + const double arr1[14]={1.1,11.1,2.1,12.1,3.1,13.1,4.1,14.1,5.1,15.1,6.1,16.1,7.1,17.1}; + std::copy(arr1,arr1+14,a->getPointer()); + // + const int arr2[7]={4,2,0,6,5}; + DataArrayDouble *b=a->selectByTupleIdSafe(arr2,arr2+5); + CPPUNIT_ASSERT_EQUAL(5,b->getNumberOfTuples()); + CPPUNIT_ASSERT_EQUAL(2,b->getNumberOfComponents()); + CPPUNIT_ASSERT(std::string(b->getInfoOnComponent(0))=="toto"); + CPPUNIT_ASSERT(std::string(b->getInfoOnComponent(1))=="tata"); + const double expected1[10]={5.1,15.1,3.1,13.1,1.1,11.1,7.1,17.1,6.1,16.1}; + for(int i=0;i<10;i++) + CPPUNIT_ASSERT_DOUBLES_EQUAL(expected1[i],b->getIJ(0,i),1e-14); + const int arr4[5]={4,-1,0,6,5}; + CPPUNIT_ASSERT_THROW(a->selectByTupleIdSafe(arr4,arr4+5),INTERP_KERNEL::Exception); + const int arr5[5]={4,2,0,6,7}; + CPPUNIT_ASSERT_THROW(a->selectByTupleIdSafe(arr5,arr5+5),INTERP_KERNEL::Exception); + b->decrRef(); + a->decrRef(); + // + DataArrayInt *c=DataArrayInt::New(); + c->alloc(7,2); + c->setInfoOnComponent(0,"toto"); + c->setInfoOnComponent(1,"tata"); + const int arr3[14]={1,11,2,12,3,13,4,14,5,15,6,16,7,17}; + std::copy(arr3,arr3+14,c->getPointer()); + DataArrayInt *d=c->selectByTupleIdSafe(arr2,arr2+5); + CPPUNIT_ASSERT_EQUAL(5,d->getNumberOfTuples()); + CPPUNIT_ASSERT_EQUAL(2,d->getNumberOfComponents()); + CPPUNIT_ASSERT(std::string(d->getInfoOnComponent(0))=="toto"); + CPPUNIT_ASSERT(std::string(d->getInfoOnComponent(1))=="tata"); + const int expected2[10]={5,15,3,13,1,11,7,17,6,16}; + for(int i=0;i<10;i++) + CPPUNIT_ASSERT_EQUAL(expected2[i],d->getIJ(0,i)); + CPPUNIT_ASSERT_THROW(c->selectByTupleIdSafe(arr4,arr4+5),INTERP_KERNEL::Exception); + CPPUNIT_ASSERT_THROW(c->selectByTupleIdSafe(arr5,arr5+5),INTERP_KERNEL::Exception); + c->decrRef(); + d->decrRef(); +} + +void MEDCouplingBasicsTest3::testAreCellsIncludedIn1() +{ + MEDCouplingUMesh *m=build3DSurfTargetMesh_1(); + const int pt[2]={1,3}; + MEDCouplingUMesh *m2=(MEDCouplingUMesh *)m->buildPartOfMySelf(pt,pt+2,true); + DataArrayInt *tmp; + CPPUNIT_ASSERT(m->areCellsIncludedIn(m2,0,tmp)); + CPPUNIT_ASSERT_EQUAL(2,tmp->getNumberOfTuples()); + CPPUNIT_ASSERT_EQUAL(1,tmp->getNumberOfComponents()); + CPPUNIT_ASSERT_EQUAL(pt[0],tmp->getIJ(0,0)); + CPPUNIT_ASSERT_EQUAL(pt[1],tmp->getIJ(0,1)); + tmp->decrRef(); + CPPUNIT_ASSERT(!m2->areCellsIncludedIn(m,0,tmp)); + tmp->decrRef(); + m2->decrRef(); + m->decrRef(); +} + +void MEDCouplingBasicsTest3::testDAIBuildSubstraction1() +{ + DataArrayInt *a=DataArrayInt::New(); + const int aa[]={2,3,6,8,9}; + a->alloc(5,1); + std::copy(aa,aa+5,a->getPointer()); + DataArrayInt *b=DataArrayInt::New(); + const int bb[]={1,3,5,9,11}; + b->alloc(5,1); + std::copy(bb,bb+5,b->getPointer()); + // + DataArrayInt *c=a->buildSubstraction(b); + CPPUNIT_ASSERT_EQUAL(3,c->getNumberOfTuples()); + CPPUNIT_ASSERT_EQUAL(1,c->getNumberOfComponents()); + const int expected1[3]={2,6,8}; + CPPUNIT_ASSERT(std::equal(expected1,expected1+3,c->getConstPointer())); + // + c->decrRef(); + b->decrRef(); + a->decrRef(); +} + +void MEDCouplingBasicsTest3::testBuildOrthogonalField2() +{ + MEDCouplingUMesh *m=build2DTargetMesh_1(); + DataArrayInt *d1=DataArrayInt::New(); + DataArrayInt *d2=DataArrayInt::New(); + DataArrayInt *d3=DataArrayInt::New(); + DataArrayInt *d4=DataArrayInt::New(); + MEDCouplingUMesh *m1=m->buildDescendingConnectivity(d1,d2,d3,d4); + // + MEDCouplingFieldDouble *f1=m1->buildOrthogonalField(); + DataArrayDouble *da1=f1->getArray(); + CPPUNIT_ASSERT_EQUAL(2,da1->getNumberOfComponents()); + CPPUNIT_ASSERT_EQUAL(13,da1->getNumberOfTuples()); + // + const double expected1[26]={-1.,0.,0.,1.,1.,0.,0.,-1.,0.707106781186548,0.707106781186548,0.,-1.,0.,1.,1.,0.,0.,1.,1.,0.,-1.,0.,0.,1.,1.,0.}; + for(int i=0;i<26;i++) + CPPUNIT_ASSERT_DOUBLES_EQUAL(expected1[i],da1->getIJ(0,i),1e-14); + // + f1->decrRef(); + m1->decrRef(); + d1->decrRef(); + d2->decrRef(); + d3->decrRef(); + d4->decrRef(); + m->decrRef(); +} + +void MEDCouplingBasicsTest3::testUMInsertNextCell1() +{ + double targetCoords[18]={-0.3,-0.3, 0.2,-0.3, 0.7,-0.3, -0.3,0.2, 0.2,0.2, 0.7,0.2, -0.3,0.7, 0.2,0.7, 0.7,0.7 }; + int targetConn[18]={0,3,4,1, 1,4,2, 4,5,2, 6,7,4,3, 7,8,5,4}; + MEDCouplingUMesh *targetMesh=MEDCouplingUMesh::New(); + targetMesh->allocateCells(5); + CPPUNIT_ASSERT_THROW(targetMesh->insertNextCell(INTERP_KERNEL::NORM_QUAD4,4,targetConn),INTERP_KERNEL::Exception); + targetMesh->setMeshDimension(2); + targetMesh->insertNextCell(INTERP_KERNEL::NORM_QUAD4,4,targetConn); + CPPUNIT_ASSERT_THROW(targetMesh->insertNextCell(INTERP_KERNEL::NORM_TETRA4,4,targetConn),INTERP_KERNEL::Exception); + CPPUNIT_ASSERT_THROW(targetMesh->insertNextCell(INTERP_KERNEL::NORM_SEG2,2,targetConn),INTERP_KERNEL::Exception); + CPPUNIT_ASSERT_THROW(targetMesh->insertNextCell(INTERP_KERNEL::NORM_POINT1,1,targetConn),INTERP_KERNEL::Exception); + targetMesh->insertNextCell(INTERP_KERNEL::NORM_TRI3,3,targetConn+4); + targetMesh->insertNextCell(INTERP_KERNEL::NORM_TRI3,3,targetConn+7); + targetMesh->insertNextCell(INTERP_KERNEL::NORM_QUAD4,4,targetConn+10); + targetMesh->insertNextCell(INTERP_KERNEL::NORM_QUAD4,4,targetConn+14); + targetMesh->finishInsertingCells(); + DataArrayDouble *myCoords=DataArrayDouble::New(); + myCoords->alloc(9,2); + std::copy(targetCoords,targetCoords+18,myCoords->getPointer()); + targetMesh->setCoords(myCoords); + myCoords->decrRef(); + targetMesh->checkCoherency(); + targetMesh->decrRef(); +} + +void MEDCouplingBasicsTest3::testFieldOperatorDivDiffComp1() +{ + MEDCouplingUMesh *m=build2DTargetMesh_1(); + DataArrayInt *d1=DataArrayInt::New(); + DataArrayInt *d2=DataArrayInt::New(); + DataArrayInt *d3=DataArrayInt::New(); + DataArrayInt *d4=DataArrayInt::New(); + MEDCouplingUMesh *m1=m->buildDescendingConnectivity(d1,d2,d3,d4); + // + MEDCouplingFieldDouble *f1=m1->buildOrthogonalField(); + const double arr1[13]={2.,3.,4.,5.,6.,7.,8.,9.,10.,11.,12.,13.,14.}; + DataArrayDouble *arr=DataArrayDouble::New(); + arr->alloc(13,1); + std::copy(arr1,arr1+13,arr->getPointer()); + MEDCouplingFieldDouble *f2=MEDCouplingFieldDouble::New(ON_CELLS); + f2->setArray(arr); + f2->setMesh(m1); + f2->checkCoherency(); + // + MEDCouplingFieldDouble *f3=(*f1)/(*f2); + CPPUNIT_ASSERT_THROW((*f2)/(*f1),INTERP_KERNEL::Exception); + f3->checkCoherency(); + (*f1)/=(*f2); + CPPUNIT_ASSERT(f1->isEqual(f3,1e-10,1e-10)); + CPPUNIT_ASSERT_THROW((*f2)/=(*f1),INTERP_KERNEL::Exception); + const double expected1[26]={-0.5, 0.0, 0.0, 0.33333333333333331, 0.25, 0.0, 0.0, -0.20000000000000001, 0.117851130197758, 0.117851130197758, 0.0, -0.14285714285714285, 0.0, 0.125, 0.1111111111111111, 0.0, 0.0, 0.10000000000000001, 0.090909090909090912, 0.0, -0.083333333333333329, 0.0, 0.0, 0.076923076923076927, 0.071428571428571425, 0.0}; + for(int i=0;i<26;i++) + CPPUNIT_ASSERT_DOUBLES_EQUAL(expected1[i],f3->getIJ(0,i),1e-10); + // + f3->decrRef(); + f2->decrRef(); + arr->decrRef(); + f1->decrRef(); + m1->decrRef(); + d1->decrRef(); + d2->decrRef(); + d3->decrRef(); + d4->decrRef(); + m->decrRef(); +} + +void MEDCouplingBasicsTest3::testDARearrange1() +{ + DataArrayInt *da1=DataArrayInt::New(); + da1->alloc(12,1); + da1->iota(0); + const int *ptr=da1->getConstPointer(); + // + CPPUNIT_ASSERT_EQUAL((std::size_t)12,da1->getNbOfElems()); + CPPUNIT_ASSERT_EQUAL(1,da1->getNumberOfComponents()); + CPPUNIT_ASSERT_EQUAL(12,da1->getNumberOfTuples()); + da1->rearrange(4); + CPPUNIT_ASSERT(ptr==da1->getConstPointer()); + CPPUNIT_ASSERT_EQUAL((std::size_t)12,da1->getNbOfElems()); + CPPUNIT_ASSERT_EQUAL(4,da1->getNumberOfComponents()); + CPPUNIT_ASSERT_EQUAL(3,da1->getNumberOfTuples()); + for(int i=0;i<12;i++) + CPPUNIT_ASSERT_EQUAL(i,da1->getIJ(0,i)); + // + da1->rearrange(6); + CPPUNIT_ASSERT(ptr==da1->getConstPointer()); + CPPUNIT_ASSERT_EQUAL((std::size_t)12,da1->getNbOfElems()); + CPPUNIT_ASSERT_EQUAL(6,da1->getNumberOfComponents()); + CPPUNIT_ASSERT_EQUAL(2,da1->getNumberOfTuples()); + for(int i=0;i<12;i++) + CPPUNIT_ASSERT_EQUAL(i,da1->getIJ(0,i)); + // + CPPUNIT_ASSERT_THROW(da1->rearrange(7),INTERP_KERNEL::Exception); + // + da1->rearrange(12); + CPPUNIT_ASSERT(ptr==da1->getConstPointer()); + CPPUNIT_ASSERT_EQUAL((std::size_t)12,da1->getNbOfElems()); + CPPUNIT_ASSERT_EQUAL(12,da1->getNumberOfComponents()); + CPPUNIT_ASSERT_EQUAL(1,da1->getNumberOfTuples()); + for(int i=0;i<12;i++) + CPPUNIT_ASSERT_EQUAL(i,da1->getIJ(0,i)); + // + da1->rearrange(3); + CPPUNIT_ASSERT(ptr==da1->getConstPointer()); + CPPUNIT_ASSERT_EQUAL((std::size_t)12,da1->getNbOfElems()); + CPPUNIT_ASSERT_EQUAL(3,da1->getNumberOfComponents()); + CPPUNIT_ASSERT_EQUAL(4,da1->getNumberOfTuples()); + for(int i=0;i<12;i++) + CPPUNIT_ASSERT_EQUAL(i,da1->getIJ(0,i)); + //double + DataArrayDouble *da2=da1->convertToDblArr(); + da1->decrRef(); + const double *ptr2=da2->getConstPointer(); + // + CPPUNIT_ASSERT_EQUAL((std::size_t)12,da2->getNbOfElems()); + CPPUNIT_ASSERT_EQUAL(3,da2->getNumberOfComponents()); + CPPUNIT_ASSERT_EQUAL(4,da2->getNumberOfTuples()); + da2->rearrange(4); + CPPUNIT_ASSERT(ptr2==da2->getConstPointer()); + CPPUNIT_ASSERT_EQUAL((std::size_t)12,da2->getNbOfElems()); + CPPUNIT_ASSERT_EQUAL(4,da2->getNumberOfComponents()); + CPPUNIT_ASSERT_EQUAL(3,da2->getNumberOfTuples()); + for(int i=0;i<12;i++) + CPPUNIT_ASSERT_DOUBLES_EQUAL((double)i,da2->getIJ(0,i),1e-14); + // + da2->rearrange(6); + CPPUNIT_ASSERT(ptr2==da2->getConstPointer()); + CPPUNIT_ASSERT_EQUAL((std::size_t)12,da2->getNbOfElems()); + CPPUNIT_ASSERT_EQUAL(6,da2->getNumberOfComponents()); + CPPUNIT_ASSERT_EQUAL(2,da2->getNumberOfTuples()); + for(int i=0;i<12;i++) + CPPUNIT_ASSERT_DOUBLES_EQUAL((double)i,da2->getIJ(0,i),1e-14); + // + CPPUNIT_ASSERT_THROW(da2->rearrange(7),INTERP_KERNEL::Exception); + // + da2->rearrange(1); + CPPUNIT_ASSERT(ptr2==da2->getConstPointer()); + CPPUNIT_ASSERT_EQUAL((std::size_t)12,da2->getNbOfElems()); + CPPUNIT_ASSERT_EQUAL(1,da2->getNumberOfComponents()); + CPPUNIT_ASSERT_EQUAL(12,da2->getNumberOfTuples()); + for(int i=0;i<12;i++) + CPPUNIT_ASSERT_DOUBLES_EQUAL((double)i,da2->getIJ(0,i),1e-14); + // + da2->rearrange(3); + CPPUNIT_ASSERT(ptr2==da2->getConstPointer()); + CPPUNIT_ASSERT_EQUAL((std::size_t)12,da2->getNbOfElems()); + CPPUNIT_ASSERT_EQUAL(3,da2->getNumberOfComponents()); + CPPUNIT_ASSERT_EQUAL(4,da2->getNumberOfTuples()); + for(int i=0;i<12;i++) + CPPUNIT_ASSERT_DOUBLES_EQUAL((double)i,da2->getIJ(0,i),1e-14); + da2->decrRef(); +} + +void MEDCouplingBasicsTest3::testGetDifferentValues1() +{ + DataArrayInt *da1=DataArrayInt::New(); + const int arr[12]={1,2,3,2,2,3,5,1,5,5,2,2}; + da1->alloc(4,3); + std::copy(arr,arr+12,da1->getPointer()); + DataArrayInt *s=da1->getDifferentValues(); + const int expected1[4]={1,2,3,5}; + CPPUNIT_ASSERT_EQUAL(4,s->getNumberOfTuples()); + CPPUNIT_ASSERT(std::equal(expected1,expected1+4,s->begin())); + da1->decrRef(); + s->decrRef(); +} + +void MEDCouplingBasicsTest3::testDAIBuildPermutationArr1() +{ + DataArrayInt *a=DataArrayInt::New(); + const int vala[5]={4,5,6,7,8}; + a->alloc(5,1); + std::copy(vala,vala+5,a->getPointer()); + DataArrayInt *b=DataArrayInt::New(); + const int valb[5]={5,4,8,6,7}; + b->alloc(5,1); + std::copy(valb,valb+5,b->getPointer()); + DataArrayInt *c=a->buildPermutationArr(*b); + const int expect1[5]={1,0,4,2,3}; + CPPUNIT_ASSERT_EQUAL(5,c->getNumberOfTuples()); + CPPUNIT_ASSERT_EQUAL(1,c->getNumberOfComponents()); + CPPUNIT_ASSERT(std::equal(expect1,expect1+5,c->getConstPointer())); + CPPUNIT_ASSERT(a->isEqualWithoutConsideringStrAndOrder(*b)); + b->setIJ(0,0,9); + CPPUNIT_ASSERT(!a->isEqualWithoutConsideringStrAndOrder(*b)); + CPPUNIT_ASSERT_THROW(a->buildPermutationArr(*b),INTERP_KERNEL::Exception); + a->setIJ(3,0,4); + b->setIJ(0,0,5); + b->setIJ(4,0,4);//;a==[4,5,6,4,8] and b==[5,4,8,6,4] + CPPUNIT_ASSERT(a->isEqualWithoutConsideringStrAndOrder(*b)); + c->decrRef(); + c=a->buildPermutationArr(*b); + const int expect2[5]={1,3,4,2,3}; + CPPUNIT_ASSERT(std::equal(expect2,expect2+5,c->getConstPointer())); + DataArrayDouble *d=b->convertToDblArr(); + b->sort(); + const int expect3[5]={4,4,5,6,8}; + CPPUNIT_ASSERT(std::equal(expect3,expect3+5,b->getConstPointer())); + d->sort(); + CPPUNIT_ASSERT_EQUAL(5,d->getNumberOfTuples()); + CPPUNIT_ASSERT_EQUAL(1,d->getNumberOfComponents()); + for(int i=0;i<5;i++) + CPPUNIT_ASSERT_DOUBLES_EQUAL(double(expect3[i]),d->getIJ(i,0),1e-14); + // + d->decrRef(); + c->decrRef(); + a->decrRef(); + b->decrRef(); +} + +void MEDCouplingBasicsTest3::testAreCellsIncludedIn2() +{ + const char myName[]="Vitoo"; + MEDCouplingUMesh *m=build3DSurfTargetMesh_1(); + MEDCouplingUMesh *m2=(MEDCouplingUMesh *)m->buildPartOfMySelf(0,0,true); + CPPUNIT_ASSERT_EQUAL(0,m2->getNumberOfCells()); + CPPUNIT_ASSERT_EQUAL(3,m2->getSpaceDimension()); + CPPUNIT_ASSERT_EQUAL(2,m2->getMeshDimension()); + m2->setName(myName); + DataArrayInt *tmp; + CPPUNIT_ASSERT(m->areCellsIncludedIn(m2,0,tmp)); + CPPUNIT_ASSERT(std::string(myName)==tmp->getName()); + CPPUNIT_ASSERT_EQUAL(0,tmp->getNumberOfTuples()); + CPPUNIT_ASSERT_EQUAL(1,tmp->getNumberOfComponents()); + m->decrRef(); + m2->decrRef(); + tmp->decrRef(); +} + +void MEDCouplingBasicsTest3::testUMeshGetPartBarycenterAndOwner1() +{ + MEDCouplingUMesh *m1=build2DTargetMesh_1(); + const int part[3]={1,0,4}; + DataArrayDouble *b=m1->getPartBarycenterAndOwner(part,part+3); + CPPUNIT_ASSERT_EQUAL(2,b->getNumberOfComponents()); + CPPUNIT_ASSERT_EQUAL(3,b->getNumberOfTuples()); + const double expected1[6]={0.36666666666666665,-0.13333333333333333,-0.05,-0.05,0.45,0.45}; + for(int i=0;i<6;i++) + CPPUNIT_ASSERT_DOUBLES_EQUAL(expected1[i],b->getIJ(0,i),1e-14); + b->decrRef(); + m1->decrRef(); +} + +void MEDCouplingBasicsTest3::testUMeshGetPartMeasureField1() +{ + MEDCouplingUMesh *m1=build2DTargetMesh_1(); + const int part[3]={1,0,4}; + DataArrayDouble *b=m1->getPartMeasureField(true,part,part+3); + CPPUNIT_ASSERT_EQUAL(1,b->getNumberOfComponents()); + CPPUNIT_ASSERT_EQUAL(3,b->getNumberOfTuples()); + const double expected1[3]={0.125,0.25,0.25}; + for(int i=0;i<3;i++) + CPPUNIT_ASSERT_DOUBLES_EQUAL(expected1[i],b->getIJ(0,i),1e-14); + b->decrRef(); + m1->decrRef(); +} + +void MEDCouplingBasicsTest3::testUMeshBuildPartOrthogonalField1() +{ + MEDCouplingUMesh *m1=build2DTargetMesh_1(); + m1->changeSpaceDimension(3); + const int part[3]={1,0,4}; + MEDCouplingFieldDouble *b=m1->buildPartOrthogonalField(part,part+3); + CPPUNIT_ASSERT_EQUAL(3,b->getArray()->getNumberOfComponents()); + CPPUNIT_ASSERT_EQUAL(3,b->getArray()->getNumberOfTuples()); + const double expected1[9]={0.,0.,-1.,0.,0.,-1.,0.,0.,-1.}; + for(int i=0;i<9;i++) + CPPUNIT_ASSERT_DOUBLES_EQUAL(expected1[i],b->getArray()->getIJ(0,i),1e-14); + b->decrRef(); + m1->decrRef(); +} + +void MEDCouplingBasicsTest3::testUMeshGetTypesOfPart1() +{ + MEDCouplingUMesh *m1=build2DTargetMesh_1(); + const int part1[]={0,3,4}; + std::set<INTERP_KERNEL::NormalizedCellType> s; + s=m1->getTypesOfPart(part1,part1+3); + CPPUNIT_ASSERT(s.size()==1); + CPPUNIT_ASSERT(*s.begin()==INTERP_KERNEL::NORM_QUAD4); + const int part2[]={2,2,2,1}; + s=m1->getTypesOfPart(part2,part2+4); + CPPUNIT_ASSERT(s.size()==1); + CPPUNIT_ASSERT(*s.begin()==INTERP_KERNEL::NORM_TRI3); + const int part3[]={3,2,1}; + s=m1->getTypesOfPart(part3,part3+3); + CPPUNIT_ASSERT(s.size()==2); + CPPUNIT_ASSERT(*s.begin()==INTERP_KERNEL::NORM_TRI3); + CPPUNIT_ASSERT(*(++s.begin())==INTERP_KERNEL::NORM_QUAD4); + m1->decrRef(); +} + +void MEDCouplingBasicsTest3::testUMeshKeepCellIdsByType1() +{ + MEDCouplingUMesh *m1=build2DTargetMesh_1(); + const int part1[3]={0,3,4}; + DataArrayInt *a=m1->keepCellIdsByType(INTERP_KERNEL::NORM_TRI3,part1,part1+3); + CPPUNIT_ASSERT_EQUAL(1,a->getNumberOfComponents()); + CPPUNIT_ASSERT_EQUAL(0,a->getNumberOfTuples()); + a->decrRef(); + // + const int part2[5]={3,2,0,2,4}; + a=m1->keepCellIdsByType(INTERP_KERNEL::NORM_TRI3,part2,part2+5); + CPPUNIT_ASSERT_EQUAL(1,a->getNumberOfComponents()); + CPPUNIT_ASSERT_EQUAL(2,a->getNumberOfTuples()); + CPPUNIT_ASSERT_EQUAL(2,a->getIJ(0,0)); + CPPUNIT_ASSERT_EQUAL(2,a->getIJ(1,0)); + a->decrRef(); + // + a=m1->keepCellIdsByType(INTERP_KERNEL::NORM_QUAD4,part2,part2+5); + CPPUNIT_ASSERT_EQUAL(1,a->getNumberOfComponents()); + CPPUNIT_ASSERT_EQUAL(3,a->getNumberOfTuples()); + CPPUNIT_ASSERT_EQUAL(3,a->getIJ(0,0)); + CPPUNIT_ASSERT_EQUAL(0,a->getIJ(1,0)); + CPPUNIT_ASSERT_EQUAL(4,a->getIJ(2,0)); + // + a->decrRef(); + m1->decrRef(); +} + +void MEDCouplingBasicsTest3::testDAIAggregateMulti1() +{ + DataArrayInt *a=DataArrayInt::New(); + a->setName("aa"); + a->alloc(4,1); + a->iota(0); + a->rearrange(2); + DataArrayInt *b=DataArrayInt::New(); + b->setName("bb"); + b->alloc(6,1); + b->iota(0); + b->rearrange(2); + // + std::vector<const DataArrayInt *> v(2); + v[0]=a; v[1]=b; + DataArrayInt *c=DataArrayInt::Aggregate(v); + CPPUNIT_ASSERT_EQUAL(5,c->getNumberOfTuples()); + CPPUNIT_ASSERT_EQUAL(2,c->getNumberOfComponents()); + CPPUNIT_ASSERT(c->getName()=="aa"); + const int expect1[10]={0,1,2,3,0,1,2,3,4,5}; + for(int i=0;i<10;i++) + CPPUNIT_ASSERT_EQUAL(expect1[i],c->getIJ(0,i)); + // + c->decrRef(); + a->decrRef(); + b->decrRef(); +} + +void MEDCouplingBasicsTest3::testMergeUMeshes2() +{ + MEDCouplingUMesh *m1=build3DSurfTargetMesh_1(); + MEDCouplingUMesh *m2=build3DSurfTargetMesh_1(); + MEDCouplingUMesh *m3=build3DSurfTargetMesh_1(); + // + const int vec1[3]={0,2,3}; + MEDCouplingUMesh *m2_2=(MEDCouplingUMesh *)m2->buildPartOfMySelf(vec1,vec1+3,false); + const int vec2[2]={1,1}; + MEDCouplingUMesh *m3_2=(MEDCouplingUMesh *)m3->buildPartOfMySelf(vec2,vec2+2,false); + // + std::vector<const MEDCouplingUMesh *> ms(3); + std::vector<const MEDCouplingMesh *> ms2(3); + ms[0]=m1; ms[1]=m2_2; ms[2]=m3_2; + ms2[0]=m1; ms2[1]=m2_2; ms2[2]=m3_2; + // + MEDCouplingUMesh *m4=MEDCouplingUMesh::MergeUMeshes(ms); + m4->checkCoherency(); + CPPUNIT_ASSERT_EQUAL(10,m4->getNumberOfCells()); + CPPUNIT_ASSERT_EQUAL(20,m4->getNumberOfNodes()); + CPPUNIT_ASSERT_EQUAL(45,m4->getMeshLength()); + // + MEDCouplingMesh *m4bis=MEDCouplingMesh::MergeMeshes(ms2); + CPPUNIT_ASSERT(m4->isEqual(m4bis,1e-12)); + m4bis->decrRef(); + // + const int vec3[5]={0,1,2,3,4}; + MEDCouplingUMesh *m4_1=(MEDCouplingUMesh *)m4->buildPartOfMySelf(vec3,vec3+5,false); + m4_1->setName(m1->getName().c_str()); + CPPUNIT_ASSERT(m4_1->isEqual(m1,1e-12)); + m4_1->decrRef(); + // + const int vec4[3]={5,6,7}; + MEDCouplingUMesh *m4_2=(MEDCouplingUMesh *)m4->buildPartOfMySelf(vec4,vec4+3,false); + DataArrayInt *cellCor=0; + DataArrayInt *nodeCor=0; + m4_2->checkGeoEquivalWith(m2_2,10,1e-12,cellCor,nodeCor); + CPPUNIT_ASSERT(cellCor==0); + CPPUNIT_ASSERT(nodeCor==0); + m4_2->decrRef(); + // + const int vec5[2]={8,9}; + MEDCouplingUMesh *m4_3=(MEDCouplingUMesh *)m4->buildPartOfMySelf(vec5,vec5+2,false); + CPPUNIT_ASSERT_EQUAL(2,m4_3->getNumberOfCells()); + CPPUNIT_ASSERT_EQUAL(3,m4_3->getNumberOfNodes()); + m3_2->zipCoords(); + m4_3->setName(m3_2->getName().c_str()); + CPPUNIT_ASSERT(m4_3->isEqual(m3_2,1e-12)); + m4_3->decrRef(); + // + m4->decrRef(); + m1->decrRef(); + m2->decrRef(); + m2_2->decrRef(); + m3->decrRef(); + m3_2->decrRef(); +} + +void MEDCouplingBasicsTest3::testBuild0DMeshFromCoords1() +{ + const double sourceCoords[12]={-0.3,-0.3,0., 0.7,-0.3,0., -0.3,0.7,0., 0.7,0.7,0.}; + DataArrayDouble *coo=DataArrayDouble::New(); + coo->alloc(4,3); + coo->setName("My0D"); + std::copy(sourceCoords,sourceCoords+12,coo->getPointer()); + MEDCouplingUMesh *m=MEDCouplingUMesh::Build0DMeshFromCoords(coo); + m->checkCoherency(); + CPPUNIT_ASSERT_EQUAL(4,m->getNumberOfNodes()); + CPPUNIT_ASSERT_EQUAL(4,m->getNumberOfCells()); + CPPUNIT_ASSERT_EQUAL(3,m->getSpaceDimension()); + CPPUNIT_ASSERT_EQUAL(0,m->getMeshDimension()); + std::set<INTERP_KERNEL::NormalizedCellType> types=m->getAllGeoTypes(); + CPPUNIT_ASSERT_EQUAL(1,(int)types.size()); + CPPUNIT_ASSERT_EQUAL(INTERP_KERNEL::NORM_POINT1,*types.begin()); + for(int i=0;i<4;i++) + { + std::vector<int> conn; + m->getNodeIdsOfCell(i,conn); + CPPUNIT_ASSERT_EQUAL(1,(int)conn.size()); + CPPUNIT_ASSERT_EQUAL(i,conn[0]); + CPPUNIT_ASSERT(INTERP_KERNEL::NORM_POINT1==m->getTypeOfCell(i)); + } + CPPUNIT_ASSERT(std::string(m->getName())=="My0D"); + m->decrRef(); + coo->decrRef(); +} + diff --git a/src/medtool/src/MEDCoupling/Test/MEDCouplingBasicsTest3.hxx b/src/medtool/src/MEDCoupling/Test/MEDCouplingBasicsTest3.hxx new file mode 100644 index 000000000..df3197d90 --- /dev/null +++ b/src/medtool/src/MEDCoupling/Test/MEDCouplingBasicsTest3.hxx @@ -0,0 +1,162 @@ +// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 +// 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 __MEDCOUPLINGBASICSTEST3_HXX__ +#define __MEDCOUPLINGBASICSTEST3_HXX__ + +#include "MEDCouplingBasicsTest.hxx" + +#include <map> +#include <vector> + +namespace ParaMEDMEM +{ + class DataArrayDouble; + class MEDCouplingUMesh; + class MEDCouplingFieldDouble; + class MEDCouplingMultiFields; + + class MEDCouplingBasicsTest3 : public MEDCouplingBasicsTest + { + CPPUNIT_TEST_SUITE(MEDCouplingBasicsTest3); + CPPUNIT_TEST( testGetMeasureFieldCMesh1 ); + CPPUNIT_TEST( testFieldDoubleZipCoords1 ); + CPPUNIT_TEST( testFieldDoubleZipConnectivity1 ); + CPPUNIT_TEST( testDaDoubleRenumber1 ); + CPPUNIT_TEST( testDaDoubleRenumberAndReduce1 ); + CPPUNIT_TEST( testDaDoubleRenumberInPlace1 ); + CPPUNIT_TEST( testDaDoubleSelectByTupleId1 ); + CPPUNIT_TEST( testDaDoubleRenumberR1 ); + CPPUNIT_TEST( testDaDoubleRenumberInPlaceR1 ); + CPPUNIT_TEST( testDaDoubleGetMinMaxValues1 ); + CPPUNIT_TEST( testFieldDoubleGetMinMaxValues2 ); + CPPUNIT_TEST( testBuildUnstructuredCMesh1 ); + CPPUNIT_TEST( testDataArrayIntInvertO2NNO21 ); + CPPUNIT_TEST( testKeepSetSelectedComponent1 ); + CPPUNIT_TEST( testKeepSetSelectedComponent2 ); + CPPUNIT_TEST( testElementaryDAThrowAndSpecialCases ); + CPPUNIT_TEST( testDAIGetIdsEqual1 ); + CPPUNIT_TEST( testDAIGetIdsEqualList1 ); + CPPUNIT_TEST( testDAFromNoInterlace1 ); + CPPUNIT_TEST( testDAToNoInterlace1 ); + CPPUNIT_TEST( testDAIsUniform1 ); + CPPUNIT_TEST( testDADFromPolarToCart1 ); + CPPUNIT_TEST( testDADFromCylToCart1 ); + CPPUNIT_TEST( testDADFromSpherToCart1 ); + CPPUNIT_TEST( testUnPolyze1 ); + CPPUNIT_TEST( testConvertDegeneratedCells1 ); + CPPUNIT_TEST( testGetNodeIdsNearPoints1 ); + CPPUNIT_TEST( testFieldCopyTinyAttrFrom1 ); + CPPUNIT_TEST( testExtrudedMesh5 ); + CPPUNIT_TEST( testExtrudedMesh6 ); + CPPUNIT_TEST( testExtrudedMesh7 ); + CPPUNIT_TEST( testSimplexize1 ); + CPPUNIT_TEST( testSimplexize2 ); + CPPUNIT_TEST( testDAMeld1 ); + CPPUNIT_TEST( testFieldMeld1 ); + CPPUNIT_TEST( testMergeNodes2 ); + CPPUNIT_TEST( testMergeField2 ); + CPPUNIT_TEST( testDAIBuildComplement1 ); + CPPUNIT_TEST( testDAIBuildUnion1 ); + CPPUNIT_TEST( testDAIBuildIntersection1 ); + CPPUNIT_TEST( testDAIDeltaShiftIndex1 ); + CPPUNIT_TEST( testDaDoubleSelectByTupleIdSafe1 ); + CPPUNIT_TEST( testAreCellsIncludedIn1 ); + CPPUNIT_TEST( testDAIBuildSubstraction1 ); + CPPUNIT_TEST( testBuildOrthogonalField2 ); + CPPUNIT_TEST( testUMInsertNextCell1 ); + CPPUNIT_TEST( testFieldOperatorDivDiffComp1 ); + CPPUNIT_TEST( testDARearrange1 ); + CPPUNIT_TEST( testGetDifferentValues1 ); + CPPUNIT_TEST( testDAIBuildPermutationArr1 ); + CPPUNIT_TEST( testAreCellsIncludedIn2 ); + CPPUNIT_TEST( testUMeshGetPartBarycenterAndOwner1 ); + CPPUNIT_TEST( testUMeshGetPartMeasureField1 ); + CPPUNIT_TEST( testUMeshBuildPartOrthogonalField1 ); + CPPUNIT_TEST( testUMeshGetTypesOfPart1 ); + CPPUNIT_TEST( testUMeshKeepCellIdsByType1 ); + CPPUNIT_TEST( testDAIAggregateMulti1 ); + CPPUNIT_TEST( testMergeUMeshes2 ); + CPPUNIT_TEST( testBuild0DMeshFromCoords1 ); + CPPUNIT_TEST_SUITE_END(); + public: + void testGetMeasureFieldCMesh1(); + void testFieldDoubleZipCoords1(); + void testFieldDoubleZipConnectivity1(); + void testDaDoubleRenumber1(); + void testDaDoubleRenumberAndReduce1(); + void testDaDoubleRenumberInPlace1(); + void testDaDoubleSelectByTupleId1(); + void testDaDoubleRenumberR1(); + void testDaDoubleRenumberInPlaceR1(); + void testDaDoubleGetMinMaxValues1(); + void testFieldDoubleGetMinMaxValues2(); + void testBuildUnstructuredCMesh1(); + void testDataArrayIntInvertO2NNO21(); + void testKeepSetSelectedComponent1(); + void testKeepSetSelectedComponent2(); + void testElementaryDAThrowAndSpecialCases(); + void testDAIGetIdsEqual1(); + void testDAIGetIdsEqualList1(); + void testDAFromNoInterlace1(); + void testDAToNoInterlace1(); + void testDAIsUniform1(); + void testDADFromPolarToCart1(); + void testDADFromCylToCart1(); + void testDADFromSpherToCart1(); + void testUnPolyze1(); + void testConvertDegeneratedCells1(); + void testGetNodeIdsNearPoints1(); + void testFieldCopyTinyAttrFrom1(); + void testExtrudedMesh5(); + void testExtrudedMesh6(); + void testExtrudedMesh7(); + void testSimplexize1(); + void testSimplexize2(); + void testDAMeld1(); + void testFieldMeld1(); + void testMergeNodes2(); + void testMergeField2(); + void testDAIBuildComplement1(); + void testDAIBuildUnion1(); + void testDAIBuildIntersection1(); + void testDAIDeltaShiftIndex1(); + void testDaDoubleSelectByTupleIdSafe1(); + void testAreCellsIncludedIn1(); + void testDAIBuildSubstraction1(); + void testBuildOrthogonalField2(); + void testUMInsertNextCell1(); + void testFieldOperatorDivDiffComp1(); + void testDARearrange1(); + void testGetDifferentValues1(); + void testDAIBuildPermutationArr1(); + void testAreCellsIncludedIn2(); + void testUMeshGetPartBarycenterAndOwner1(); + void testUMeshGetPartMeasureField1(); + void testUMeshBuildPartOrthogonalField1(); + void testUMeshGetTypesOfPart1(); + void testUMeshKeepCellIdsByType1(); + void testDAIAggregateMulti1(); + void testMergeUMeshes2(); + void testBuild0DMeshFromCoords1(); + }; +} + +#endif diff --git a/src/medtool/src/MEDCoupling/Test/MEDCouplingBasicsTest4.cxx b/src/medtool/src/MEDCoupling/Test/MEDCouplingBasicsTest4.cxx new file mode 100644 index 000000000..8b547fe08 --- /dev/null +++ b/src/medtool/src/MEDCoupling/Test/MEDCouplingBasicsTest4.cxx @@ -0,0 +1,2223 @@ +// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 +// 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 "MEDCouplingBasicsTest4.hxx" +#include "MEDCouplingUMesh.hxx" +#include "MEDCouplingCMesh.hxx" +#include "MEDCouplingExtrudedMesh.hxx" +#include "MEDCouplingFieldDouble.hxx" +#include "MEDCouplingMemArray.hxx" +#include "MEDCouplingGaussLocalization.hxx" +#include "MEDCouplingMultiFields.hxx" +#include "MEDCouplingFieldOverTime.hxx" + +#include <cmath> +#include <functional> +#include <iterator> + +using namespace ParaMEDMEM; + +void MEDCouplingBasicsTest4::testDescriptionInMeshTimeUnit1() +{ + static const char text1[]="totoTTEDD"; + MEDCouplingUMesh *m=build2DTargetMesh_1(); + m->setDescription(text1); + CPPUNIT_ASSERT(std::string(m->getDescription())==text1); + MEDCouplingUMesh *m2=(MEDCouplingUMesh *)m->deepCpy(); + CPPUNIT_ASSERT(m->isEqual(m2,1e-12)); + CPPUNIT_ASSERT(std::string(m2->getDescription())==text1); + m2->setDescription("ggg"); + CPPUNIT_ASSERT(!m->isEqual(m2,1e-12)); + m2->decrRef(); + // + MEDCouplingFieldDouble *f=MEDCouplingFieldDouble::New(ON_CELLS,ONE_TIME); + f->setTimeUnit(text1); + CPPUNIT_ASSERT(std::string(f->getTimeUnit())==text1); + MEDCouplingFieldDouble *f2=f->deepCpy(); + CPPUNIT_ASSERT(std::string(f2->getTimeUnit())==text1); + f2->decrRef(); + // + f->decrRef(); + m->decrRef(); +} + +void MEDCouplingBasicsTest4::testMultiFields1() +{ + MEDCouplingMultiFields *mfs=buildMultiFields_1(); + std::vector<MEDCouplingMesh *> ms=mfs->getMeshes(); + std::vector<int> refs; + std::vector<MEDCouplingMesh *> dms=mfs->getDifferentMeshes(refs); + std::vector<DataArrayDouble *> das=mfs->getArrays(); + std::vector< std::vector<int> > refs2; + std::vector<DataArrayDouble *> das2=mfs->getDifferentArrays(refs2); + // + CPPUNIT_ASSERT_EQUAL(5,(int)ms.size()); + CPPUNIT_ASSERT_EQUAL(2,(int)dms.size()); + CPPUNIT_ASSERT_EQUAL(6,(int)das.size()); + CPPUNIT_ASSERT_EQUAL(5,(int)das2.size()); + // + MEDCouplingMultiFields *mfs2=mfs->deepCpy(); + CPPUNIT_ASSERT(mfs->isEqual(mfs2,1e-12,1e-12)); + mfs2->decrRef(); + // + mfs->decrRef(); +} + +void MEDCouplingBasicsTest4::testFieldOverTime1() +{ + std::vector<MEDCouplingFieldDouble *> fs=buildMultiFields_2(); + CPPUNIT_ASSERT_THROW(MEDCouplingFieldOverTime::New(fs),INTERP_KERNEL::Exception); + MEDCouplingFieldDouble *f4bis=fs[4]->buildNewTimeReprFromThis(ONE_TIME,false); + fs[4]->decrRef(); + fs[4]=f4bis; + CPPUNIT_ASSERT_THROW(MEDCouplingFieldOverTime::New(fs),INTERP_KERNEL::Exception); + f4bis->setTime(2.7,20,21); + MEDCouplingFieldOverTime *fot=MEDCouplingFieldOverTime::New(fs); + MEDCouplingDefinitionTime dt=fot->getDefinitionTimeZone(); + std::vector<double> hs=dt.getHotSpotsTime(); + CPPUNIT_ASSERT_EQUAL(6,(int)hs.size()); + const double expected1[]={0.2,0.7,1.2,1.35,1.7,2.7}; + for(int i=0;i<6;i++) + CPPUNIT_ASSERT_DOUBLES_EQUAL(expected1[i],hs[i],1e-12); + int meshId,arrId,arrIdInField,fieldId; + dt.getIdsOnTimeRight(0.2,meshId,arrId,arrIdInField,fieldId); + CPPUNIT_ASSERT_EQUAL(0,meshId); + CPPUNIT_ASSERT_EQUAL(0,arrId); + CPPUNIT_ASSERT_EQUAL(0,arrIdInField); + CPPUNIT_ASSERT_EQUAL(0,fieldId); + // + dt.getIdsOnTimeRight(0.7,meshId,arrId,arrIdInField,fieldId); + CPPUNIT_ASSERT_EQUAL(0,meshId); + CPPUNIT_ASSERT_EQUAL(1,arrId); + CPPUNIT_ASSERT_EQUAL(0,arrIdInField); + CPPUNIT_ASSERT_EQUAL(1,fieldId); + // + dt.getIdsOnTimeLeft(1.2,meshId,arrId,arrIdInField,fieldId);//**** WARNING left here + CPPUNIT_ASSERT_EQUAL(0,meshId); + CPPUNIT_ASSERT_EQUAL(2,arrId); + CPPUNIT_ASSERT_EQUAL(1,arrIdInField); + CPPUNIT_ASSERT_EQUAL(1,fieldId); + // + dt.getIdsOnTimeRight(1.2,meshId,arrId,arrIdInField,fieldId);//**** WARNING right again here + CPPUNIT_ASSERT_EQUAL(1,meshId); + CPPUNIT_ASSERT_EQUAL(3,arrId); + CPPUNIT_ASSERT_EQUAL(0,arrIdInField); + CPPUNIT_ASSERT_EQUAL(2,fieldId); + // + dt.getIdsOnTimeRight(1.35,meshId,arrId,arrIdInField,fieldId); + CPPUNIT_ASSERT_EQUAL(1,meshId); + CPPUNIT_ASSERT_EQUAL(3,arrId); + CPPUNIT_ASSERT_EQUAL(0,arrIdInField); + CPPUNIT_ASSERT_EQUAL(2,fieldId); + // + dt.getIdsOnTimeRight(1.7,meshId,arrId,arrIdInField,fieldId); + CPPUNIT_ASSERT_EQUAL(0,meshId); + CPPUNIT_ASSERT_EQUAL(3,arrId); + CPPUNIT_ASSERT_EQUAL(0,arrIdInField); + CPPUNIT_ASSERT_EQUAL(3,fieldId); + // + dt.getIdsOnTimeRight(2.7,meshId,arrId,arrIdInField,fieldId); + CPPUNIT_ASSERT_EQUAL(1,meshId); + CPPUNIT_ASSERT_EQUAL(4,arrId); + CPPUNIT_ASSERT_EQUAL(0,arrIdInField); + CPPUNIT_ASSERT_EQUAL(4,fieldId); + // + MEDCouplingDefinitionTime dt2; + CPPUNIT_ASSERT(!dt2.isEqual(dt)); + dt2.assign(dt); + dt2.assign(dt);//to check memory management + CPPUNIT_ASSERT(dt2.isEqual(dt)); + // + MEDCouplingDefinitionTime dt3; + std::vector<int> tmp1; + std::vector<double> tmp2; + CPPUNIT_ASSERT(!dt2.isEqual(dt3)); + dt2.getTinySerializationInformation(tmp1,tmp2); + dt3.unserialize(tmp1,tmp2); + CPPUNIT_ASSERT(dt2.isEqual(dt3)); + // + for(std::vector<MEDCouplingFieldDouble *>::iterator it=fs.begin();it!=fs.end();it++) + (*it)->decrRef(); + fot->decrRef(); +} + +void MEDCouplingBasicsTest4::testDAICheckAndPreparePermutation1() +{ + const int vals1[]={9,10,0,6,4,11,3,7}; + const int expect1[]={5,6,0,3,2,7,1,4}; + const int vals2[]={9,10,0,6,10,11,3,7}; + DataArrayInt *da=DataArrayInt::New(); + da->alloc(8,1); + std::copy(vals1,vals1+8,da->getPointer()); + DataArrayInt *da2=da->checkAndPreparePermutation(); + CPPUNIT_ASSERT_EQUAL(8,da2->getNumberOfTuples()); + CPPUNIT_ASSERT_EQUAL(1,da2->getNumberOfComponents()); + for(int i=0;i<8;i++) + CPPUNIT_ASSERT_EQUAL(expect1[i],da2->getIJ(i,0)); + da2->decrRef(); + da->decrRef(); + // + da=DataArrayInt::New(); + da->alloc(8,1); + da->iota(0); + da2=da->checkAndPreparePermutation(); + CPPUNIT_ASSERT_EQUAL(8,da2->getNumberOfTuples()); + CPPUNIT_ASSERT_EQUAL(1,da2->getNumberOfComponents()); + CPPUNIT_ASSERT(da2->isIdentity()); + da2->decrRef(); + da->decrRef(); + // + da=DataArrayInt::New(); + da->alloc(8,1); + std::copy(vals2,vals2+8,da->getPointer()); + CPPUNIT_ASSERT_THROW(da->checkAndPreparePermutation(),INTERP_KERNEL::Exception); + da->decrRef(); +} + +void MEDCouplingBasicsTest4::testDAIChangeSurjectiveFormat1() +{ + const int vals1[8]={0,3,2,3,2,2,1,2}; + const int expected1[5]={0,1,2,6,8}; + const int expected2[8]={0, 6, 2,4,5,7, 1,3}; + DataArrayInt *da=DataArrayInt::New(); + da->alloc(8,1); + std::copy(vals1,vals1+8,da->getPointer()); + // + DataArrayInt *da2,*da2I; + da->changeSurjectiveFormat(4,da2,da2I); + CPPUNIT_ASSERT_EQUAL(5,da2I->getNumberOfTuples()); + CPPUNIT_ASSERT_EQUAL(8,da2->getNumberOfTuples()); + CPPUNIT_ASSERT(std::equal(expected1,expected1+5,da2I->getConstPointer())); + CPPUNIT_ASSERT(std::equal(expected2,expected2+8,da2->getConstPointer())); + da2->decrRef(); + da2I->decrRef(); + // + CPPUNIT_ASSERT_THROW(da->changeSurjectiveFormat(3,da2,da2I),INTERP_KERNEL::Exception); + // + da->decrRef(); +} + +void MEDCouplingBasicsTest4::testUMeshGetCellIdsLyingOnNodes1() +{ + MEDCouplingUMesh *m=build3DSurfTargetMesh_1(); + const int nodeIds1[5]={1,2,3,4,6}; + const int nodeIds2[2]={6,7}; + DataArrayInt *da=m->getCellIdsLyingOnNodes(nodeIds1,nodeIds1+5,true); + CPPUNIT_ASSERT_EQUAL(1,da->getNumberOfTuples()); + CPPUNIT_ASSERT_EQUAL(1,da->getNumberOfComponents()); + CPPUNIT_ASSERT_EQUAL(1,da->getIJ(0,0)); + da->decrRef(); + da=m->getCellIdsLyingOnNodes(nodeIds2,nodeIds2+2,false); + CPPUNIT_ASSERT_EQUAL(2,da->getNumberOfTuples()); + CPPUNIT_ASSERT_EQUAL(1,da->getNumberOfComponents()); + CPPUNIT_ASSERT_EQUAL(3,da->getIJ(0,0)); + CPPUNIT_ASSERT_EQUAL(4,da->getIJ(1,0)); + da->decrRef(); + // + m->decrRef(); +} + +void MEDCouplingBasicsTest4::testUMeshFindCellIdsOnBoundary1() +{ + MEDCouplingUMesh *m=build3DSurfTargetMesh_1(); + DataArrayInt *da5=m->findCellIdsOnBoundary(); + CPPUNIT_ASSERT_EQUAL(5,da5->getNumberOfTuples()); + CPPUNIT_ASSERT(da5->isIdentity()); + // + da5->decrRef(); + m->decrRef(); +} + +void MEDCouplingBasicsTest4::testMeshSetTime1() +{ + MEDCouplingUMesh *m1=build3DSurfTargetMesh_1(); + MEDCouplingUMesh *m2=build3DSurfTargetMesh_1(); + // + CPPUNIT_ASSERT(m1->isEqual(m2,1e-12)); + m1->setTime(3.14,6,7); + int tmp1,tmp2; + double tmp3=m1->getTime(tmp1,tmp2); + CPPUNIT_ASSERT_EQUAL(6,tmp1); + CPPUNIT_ASSERT_EQUAL(7,tmp2); + CPPUNIT_ASSERT_DOUBLES_EQUAL(3.14,tmp3,1e-12); + CPPUNIT_ASSERT(!m1->isEqual(m2,1e-12)); + m2->setTime(3.14,6,7); + CPPUNIT_ASSERT(m1->isEqual(m2,1e-12)); + m1->setTimeUnit("ms"); + CPPUNIT_ASSERT(std::string(m1->getTimeUnit())=="ms"); + m1->setTimeUnit("us"); + CPPUNIT_ASSERT(std::string(m1->getTimeUnit())=="us"); + CPPUNIT_ASSERT(!m1->isEqual(m2,1e-12)); + m2->setTimeUnit("us"); + CPPUNIT_ASSERT(m1->isEqual(m2,1e-12)); + m2->setTime(3.14,6,8); + CPPUNIT_ASSERT(!m1->isEqual(m2,1e-12)); + m2->setTime(3.14,7,7); + CPPUNIT_ASSERT(!m1->isEqual(m2,1e-12)); + m2->setTime(3.15,6,7); + CPPUNIT_ASSERT(!m1->isEqual(m2,1e-12)); + // + m1->setTime(10.34,55,12); + MEDCouplingUMesh *m3=(MEDCouplingUMesh *)m1->deepCpy(); + CPPUNIT_ASSERT(m1->isEqual(m3,1e-12)); + tmp3=m3->getTime(tmp1,tmp2); + CPPUNIT_ASSERT_EQUAL(55,tmp1); + CPPUNIT_ASSERT_EQUAL(12,tmp2); + CPPUNIT_ASSERT_DOUBLES_EQUAL(10.34,tmp3,1e-12); + // + m3->decrRef(); + m1->decrRef(); + m2->decrRef(); + // testing CMesh + const double coo1[4]={0.,1.,2.,3.5}; + DataArrayDouble *a=DataArrayDouble::New(); + a->alloc(4,1); + std::copy(coo1,coo1+4,a->getPointer()); + MEDCouplingCMesh *b=MEDCouplingCMesh::New(); + b->setCoordsAt(0,a); + a->decrRef(); + // + b->setTime(5.67,8,100); + tmp3=b->getTime(tmp1,tmp2); + CPPUNIT_ASSERT_EQUAL(8,tmp1); + CPPUNIT_ASSERT_EQUAL(100,tmp2); + CPPUNIT_ASSERT_DOUBLES_EQUAL(5.67,tmp3,1e-12); + MEDCouplingCMesh *c=(MEDCouplingCMesh *)b->deepCpy(); + CPPUNIT_ASSERT(c->isEqual(b,1e-12)); + tmp3=c->getTime(tmp1,tmp2); + CPPUNIT_ASSERT_EQUAL(8,tmp1); + CPPUNIT_ASSERT_EQUAL(100,tmp2); + CPPUNIT_ASSERT_DOUBLES_EQUAL(5.67,tmp3,1e-12); + c->decrRef(); + b->decrRef(); +} + +void MEDCouplingBasicsTest4::testApplyFuncTwo1() +{ + MEDCouplingUMesh *m1=build3DSurfTargetMesh_1(); + MEDCouplingFieldDouble *f1=MEDCouplingFieldDouble::New(ON_CELLS,ONE_TIME); + f1->setMesh(m1); + // + const double vals[15]={1.,11.,21.,2.,12.,22.,3.,13.,23.,4.,14.,24.,5.,15.,25.}; + DataArrayDouble *da=DataArrayDouble::New(); + da->alloc(5,3); + std::copy(vals,vals+15,da->getPointer()); + f1->setArray(da); + // + CPPUNIT_ASSERT_THROW(da->applyFunc2(1,"y+z"),INTERP_KERNEL::Exception); + da->setInfoOnComponent(0,"x [m]"); + da->setInfoOnComponent(1,"y [mm]"); + da->setInfoOnComponent(2,"z [km]"); + + CPPUNIT_ASSERT_THROW(da->applyFunc2(1,"x+y+zz+zzz"),INTERP_KERNEL::Exception); + CPPUNIT_ASSERT_THROW(da->applyFunc2(1,"toto(x+y)"),INTERP_KERNEL::Exception); + CPPUNIT_ASSERT_THROW(da->applyFunc2(1,"x/0"),INTERP_KERNEL::Exception); + + DataArrayDouble *da2=da->applyFunc2(1,"y+z"); + CPPUNIT_ASSERT_EQUAL(1,da2->getNumberOfComponents()); + CPPUNIT_ASSERT_EQUAL(5,da2->getNumberOfTuples()); + const double expected1[5]={32.,34.,36.,38.,40.}; + for(int i=0;i<5;i++) + CPPUNIT_ASSERT_DOUBLES_EQUAL(expected1[i],da2->getIJ(0,i),1e-12); + da2->decrRef(); + da2=da->applyFunc(1,"y+z"); + const double expected2[5]={12.,14.,16.,18.,20.}; + for(int i=0;i<5;i++) + CPPUNIT_ASSERT_DOUBLES_EQUAL(expected2[i],da2->getIJ(0,i),1e-12); + da2->decrRef(); + // + CPPUNIT_ASSERT_EQUAL(3,f1->getNumberOfComponents()); + CPPUNIT_ASSERT_EQUAL(5,f1->getNumberOfTuples()); + f1->applyFunc2(1,"y+z"); + CPPUNIT_ASSERT_EQUAL(1,f1->getNumberOfComponents()); + CPPUNIT_ASSERT_EQUAL(5,f1->getNumberOfTuples()); + for(int i=0;i<5;i++) + CPPUNIT_ASSERT_DOUBLES_EQUAL(expected1[i],f1->getArray()->getIJ(0,i),1e-12); + // + da->decrRef(); + f1->decrRef(); + m1->decrRef(); +} + +void MEDCouplingBasicsTest4::testApplyFuncThree1() +{ + MEDCouplingUMesh *m1=build3DSurfTargetMesh_1(); + MEDCouplingFieldDouble *f1=MEDCouplingFieldDouble::New(ON_CELLS,ONE_TIME); + f1->setMesh(m1); + // + const double vals[15]={1.,11.,21.,2.,12.,22.,3.,13.,23.,4.,14.,24.,5.,15.,25.}; + DataArrayDouble *da=DataArrayDouble::New(); + da->alloc(5,3); + std::copy(vals,vals+15,da->getPointer()); + f1->setArray(da); + // + std::vector<std::string> vs(3); + vs[0]="x"; vs[1]="Y"; vs[2]="z"; + CPPUNIT_ASSERT_THROW(da->applyFunc3(1,vs,"y+z"),INTERP_KERNEL::Exception); + CPPUNIT_ASSERT_THROW(da->applyFunc3(1,vs,"x+Y+z+zz+zzz"),INTERP_KERNEL::Exception); + CPPUNIT_ASSERT_THROW(da->applyFunc3(1,vs,"x/0."),INTERP_KERNEL::Exception); + vs[1]="y"; + DataArrayDouble *da2=da->applyFunc3(1,vs,"y+z"); + const double expected1[5]={32.,34.,36.,38.,40.}; + for(int i=0;i<5;i++) + CPPUNIT_ASSERT_DOUBLES_EQUAL(expected1[i],da2->getIJ(0,i),1e-12); + da2->decrRef(); + std::vector<std::string> vs2(4); vs2[0]="x"; vs2[1]="y"; vs2[2]="z"; vs2[3]="a"; + CPPUNIT_ASSERT_THROW(da->applyFunc3(1,vs2,"x+a"),INTERP_KERNEL::Exception); + f1->setArray(da); + CPPUNIT_ASSERT_EQUAL(3,f1->getNumberOfComponents()); + CPPUNIT_ASSERT_EQUAL(5,f1->getNumberOfTuples()); + f1->applyFunc3(1,vs,"y+z"); + CPPUNIT_ASSERT_EQUAL(1,f1->getNumberOfComponents()); + CPPUNIT_ASSERT_EQUAL(5,f1->getNumberOfTuples()); + for(int i=0;i<5;i++) + CPPUNIT_ASSERT_DOUBLES_EQUAL(expected1[i],f1->getArray()->getIJ(0,i),1e-12); + // + da->decrRef(); + f1->decrRef(); + m1->decrRef(); +} + +void MEDCouplingBasicsTest4::testFillFromAnalyticTwo1() +{ + MEDCouplingUMesh *m1=build3DSurfTargetMesh_1(); + m1->setTime(3.4,5,6); m1->setTimeUnit("us"); + int a,b; + CPPUNIT_ASSERT_THROW(m1->fillFromAnalytic2(ON_NODES,1,"y+z"),INTERP_KERNEL::Exception); + m1->getCoords()->setInfoOnComponent(0,"x [m]"); + m1->getCoords()->setInfoOnComponent(1,"y"); + m1->getCoords()->setInfoOnComponent(2,"z"); + MEDCouplingFieldDouble *f1=m1->fillFromAnalytic2(ON_NODES,1,"y+z"); + CPPUNIT_ASSERT_DOUBLES_EQUAL(3.4,f1->getTime(a,b),1.e-14); + CPPUNIT_ASSERT_EQUAL(5,a); CPPUNIT_ASSERT_EQUAL(6,b); + CPPUNIT_ASSERT_EQUAL(std::string(f1->getTimeUnit()),std::string("us")); + CPPUNIT_ASSERT_EQUAL(1,f1->getNumberOfComponents()); + CPPUNIT_ASSERT_EQUAL(9,f1->getNumberOfTuples()); + const double expected1[9]={0.2, 0.7, 1.2, 0.7, 1.2, 1.7, 1.2, 1.7, 2.2}; + for(int i=0;i<9;i++) + CPPUNIT_ASSERT_DOUBLES_EQUAL(expected1[i],f1->getArray()->getIJ(0,i),1e-12); + f1->decrRef(); + m1->decrRef(); +} + +void MEDCouplingBasicsTest4::testFillFromAnalyticThree1() +{ + MEDCouplingUMesh *m1=build3DSurfTargetMesh_1(); + m1->setTime(3.4,5,6); m1->setTimeUnit("us"); + int a,b; + std::vector<std::string> vs(3); + vs[0]="x"; vs[1]="Y"; vs[2]="z"; + CPPUNIT_ASSERT_THROW(m1->fillFromAnalytic3(ON_NODES,1,vs,"y+z"),INTERP_KERNEL::Exception); + vs[1]="y"; + MEDCouplingFieldDouble *f1=m1->fillFromAnalytic3(ON_NODES,1,vs,"y+z"); + CPPUNIT_ASSERT_DOUBLES_EQUAL(3.4,f1->getTime(a,b),1.e-14); + CPPUNIT_ASSERT_EQUAL(5,a); CPPUNIT_ASSERT_EQUAL(6,b); + CPPUNIT_ASSERT_EQUAL(std::string(f1->getTimeUnit()),std::string("us")); + CPPUNIT_ASSERT_EQUAL(1,f1->getNumberOfComponents()); + CPPUNIT_ASSERT_EQUAL(9,f1->getNumberOfTuples()); + const double expected1[9]={0.2, 0.7, 1.2, 0.7, 1.2, 1.7, 1.2, 1.7, 2.2}; + for(int i=0;i<9;i++) + CPPUNIT_ASSERT_DOUBLES_EQUAL(expected1[i],f1->getArray()->getIJ(0,i),1e-12); + f1->decrRef(); + m1->decrRef(); +} + +void MEDCouplingBasicsTest4::testDAUnitVar1() +{ + DataArrayDouble *da=DataArrayDouble::New(); + da->alloc(1,3); + da->setInfoOnComponent(0,"XPS [m]"); + std::string st1,st2; + st1=da->getVarOnComponent(0); + CPPUNIT_ASSERT(st1=="XPS"); + st2=da->getUnitOnComponent(0); + CPPUNIT_ASSERT(st2=="m"); + // + da->setInfoOnComponent(0,"XPS [m]"); + st1=da->getVarOnComponent(0); + CPPUNIT_ASSERT(st1=="XPS"); + st2=da->getUnitOnComponent(0); + CPPUNIT_ASSERT(st2=="m"); + // + da->setInfoOnComponent(0,"XPP [m]"); + st1=da->getVarOnComponent(0); + CPPUNIT_ASSERT(st1=="XPP"); + st2=da->getUnitOnComponent(0); + CPPUNIT_ASSERT(st2=="m"); + // + da->setInfoOnComponent(0,"XPP kdep kefer [ m ]"); + st1=da->getVarOnComponent(0); + CPPUNIT_ASSERT(st1=="XPP kdep kefer"); + st2=da->getUnitOnComponent(0); + CPPUNIT_ASSERT(st2==" m "); + // + da->setInfoOnComponent(0," XPP k[ dep k]efer [ m^ 2/s^3*kJ ]"); + st1=da->getVarOnComponent(0); + CPPUNIT_ASSERT(st1==" XPP k[ dep k]efer"); + st2=da->getUnitOnComponent(0); + CPPUNIT_ASSERT(st2==" m^ 2/s^3*kJ "); + // + da->setInfoOnComponent(0," XPP kefer "); + st1=da->getVarOnComponent(0); + CPPUNIT_ASSERT(st1==" XPP kefer "); + st2=da->getUnitOnComponent(0); + CPPUNIT_ASSERT(st2==""); + // + da->setInfoOnComponent(0,"temperature( bof)"); + st1=da->getVarOnComponent(0); + CPPUNIT_ASSERT(st1=="temperature( bof)"); + st2=da->getUnitOnComponent(0); + CPPUNIT_ASSERT(st2==""); + // + da->setInfoOnComponent(0,"kkk [m]"); + da->setInfoOnComponent(1,"ppp [m^2/kJ]"); + da->setInfoOnComponent(2,"abcde [MW/s]"); + // + std::vector<std::string> vs; + vs=da->getVarsOnComponent(); + CPPUNIT_ASSERT_EQUAL(3,(int)vs.size()); + CPPUNIT_ASSERT(vs[0]=="kkk"); + CPPUNIT_ASSERT(vs[1]=="ppp"); + CPPUNIT_ASSERT(vs[2]=="abcde"); + vs=da->getUnitsOnComponent(); + CPPUNIT_ASSERT_EQUAL(3,(int)vs.size()); + CPPUNIT_ASSERT(vs[0]=="m"); + CPPUNIT_ASSERT(vs[1]=="m^2/kJ"); + CPPUNIT_ASSERT(vs[2]=="MW/s"); + // + da->decrRef(); +} + +void MEDCouplingBasicsTest4::testGaussCoordinates1() +{ + //Testing 1D cell types + MEDCouplingUMesh *m1=build1DMultiTypes_1(); + MEDCouplingFieldDouble *f=MEDCouplingFieldDouble::New(ON_GAUSS_PT,ONE_TIME); + f->setMesh(m1); + std::vector<double> wg1(1); wg1[0]=0.3; + std::vector<double> gsCoo1(1); gsCoo1[0]=0.2; + std::vector<double> refCoo1(2); refCoo1[0]=-1.0; refCoo1[1]=1.0; + f->setGaussLocalizationOnType(INTERP_KERNEL::NORM_SEG2,refCoo1,gsCoo1,wg1); + std::vector<double> wg2(wg1); + std::vector<double> gsCoo2(1); gsCoo2[0]=0.2; + std::vector<double> refCoo2(3); refCoo2[0]=-1.0; refCoo2[1]=1.0; refCoo2[2]=0.0; + f->setGaussLocalizationOnType(INTERP_KERNEL::NORM_SEG3,refCoo2,gsCoo2,wg2); + // + DataArrayDouble *resToTest=f->getLocalizationOfDiscr(); + CPPUNIT_ASSERT_EQUAL(3,resToTest->getNumberOfComponents()); + CPPUNIT_ASSERT_EQUAL(2,resToTest->getNumberOfTuples()); + const double expected1[6]={0.6,0.6,0.6, 0.6,0.6,0.6}; + for(int i=0;i<6;i++) + CPPUNIT_ASSERT_DOUBLES_EQUAL(expected1[i],resToTest->getIJ(0,i),1e-14); + resToTest->decrRef(); + // + m1->decrRef(); + f->decrRef(); + //Testing 2D cell types + MEDCouplingUMesh *m2=build2DMultiTypes_1(); + f=MEDCouplingFieldDouble::New(ON_GAUSS_PT,ONE_TIME); + f->setMesh(m2); + std::vector<double> wg3(2); wg3[0]=0.3; wg3[1]=0.3; + const double tria3CooGauss[4]={ 0.1, 0.8, 0.2, 0.7 }; + std::vector<double> gsCoo3(tria3CooGauss,tria3CooGauss+4); + const double tria3CooRef[6]={ 0.0, 0.0, 1.0 , 0.0, 0.0, 1.0 }; + std::vector<double> refCoo3(tria3CooRef,tria3CooRef+6); + f->setGaussLocalizationOnType(INTERP_KERNEL::NORM_TRI3,refCoo3,gsCoo3,wg3); + std::vector<double> wg4(3); wg4[0]=0.3; wg4[1]=0.3; wg4[2]=0.3; + const double tria6CooGauss[6]={ 0.3, 0.2, 0.2, 0.1, 0.2, 0.4 }; + std::vector<double> gsCoo4(tria6CooGauss,tria6CooGauss+6); + const double tria6CooRef[12]={0.0, 0.0, 1.0, 0.0, 0.0, 1.0, 0.5, 0.0, 0.5, 0.5, 0.0, 0.5}; + std::vector<double> refCoo4(tria6CooRef,tria6CooRef+12); + f->setGaussLocalizationOnType(INTERP_KERNEL::NORM_TRI6,refCoo4,gsCoo4,wg4); + std::vector<double> wg5(4); wg5[0]=0.3; wg5[1]=0.3; wg5[2]=0.3; wg5[3]=0.3; + const double quad4CooGauss[8]={ 0.3, 0.2, 0.2, 0.1, 0.2, 0.4, 0.15, 0.27 }; + std::vector<double> gsCoo5(quad4CooGauss,quad4CooGauss+8); + const double quad4CooRef[8]={-1.0, 1.0, -1.0, -1.0, 1.0, -1.0, 1.0, 1.0}; + std::vector<double> refCoo5(quad4CooRef,quad4CooRef+8); + f->setGaussLocalizationOnType(INTERP_KERNEL::NORM_QUAD4,refCoo5,gsCoo5,wg5); + std::vector<double> wg6(4); wg6[0]=0.3; wg6[1]=0.3; wg6[2]=0.3; wg6[3]=0.3; + const double quad8CooGauss[8]={ 0.34, 0.16, 0.21, 0.3, 0.23, 0.4, 0.14, 0.37 }; + std::vector<double> gsCoo6(quad8CooGauss,quad8CooGauss+8); + const double quad8CooRef[16]={ -1.0, -1.0, 1.0, -1.0, 1.0, 1.0, -1.0, 1.0, 0.0, -1.0, 1.0, 0.0, 0.0, 1.0, -1.0, 0.0}; + std::vector<double> refCoo6(quad8CooRef,quad8CooRef+16); + f->setGaussLocalizationOnType(INTERP_KERNEL::NORM_QUAD8,refCoo6,gsCoo6,wg6); + // + resToTest=f->getLocalizationOfDiscr(); + CPPUNIT_ASSERT_EQUAL(3,resToTest->getNumberOfComponents()); + CPPUNIT_ASSERT_EQUAL(13,resToTest->getNumberOfTuples());//2+3+4+4 gauss points for resp TRI3,TRI6,QUAD4,QUAD8 + const double expected2[39]={5.1,1.55,0.0, 4.7,1.65,0.0, //TRI3 + 2.32,1.52,0.0, 1.6,1.32,0.0, 3.52,1.26,0.0,//TRI6 + 2.6,1.6,0.0, 2.4,1.8,0.0, 2.4,1.2,0.0, 2.3,1.46,0.0,//QUAD4 + 2.32,2.68,0.0, 2.6,2.42,0.0, 2.8,2.46,0.0, 2.74,2.28,0.0 };//QUAD8 + for(int i=0;i<39;i++) + CPPUNIT_ASSERT_DOUBLES_EQUAL(expected2[i],resToTest->getIJ(0,i),1e-14); + resToTest->decrRef(); + // + m2->decrRef(); + f->decrRef(); + //Testing 3D cell types + MEDCouplingUMesh *m3=build3DMultiTypes_1(); + f=MEDCouplingFieldDouble::New(ON_GAUSS_PT,ONE_TIME); + f->setMesh(m3); + // + std::vector<double> wg7(1); wg7[0]=0.3; + const double tetra4CooGauss[3]={0.34, 0.16, 0.21}; + std::vector<double> gsCoo7(tetra4CooGauss,tetra4CooGauss+3); + const double tetra4CooRef[12]={0.0,1.0,0.0, 0.0,0.0,1.0, 0.0,0.0,0.0, 1.0,0.0,0.0}; + std::vector<double> refCoo7(tetra4CooRef,tetra4CooRef+12); + f->setGaussLocalizationOnType(INTERP_KERNEL::NORM_TETRA4,refCoo7,gsCoo7,wg7); + std::vector<double> wg8(1); wg8[0]=0.3; + const double tetra10CooGauss[3]={0.2, 0.3, 0.1}; + std::vector<double> gsCoo8(tetra10CooGauss,tetra10CooGauss+3); + const double tetra10CooRef[30]={0.0,1.0,0.0, 0.0,0.0,0.0, 0.0,0.0,1.0, 1.0,0.0,0.0, 0.0,0.5,0.0, 0.0,0.0,0.5, 0.0,0.5,0.5, 0.5,0.5,0.0, 0.5,0.0,0.0, 0.5,0.0,0.5}; + std::vector<double> refCoo8(tetra10CooRef,tetra10CooRef+30); + f->setGaussLocalizationOnType(INTERP_KERNEL::NORM_TETRA10,refCoo8,gsCoo8,wg8); + std::vector<double> wg9(1); wg9[0]=0.3; + const double pyra5CooGauss[3]={0.2, 0.3, 0.1}; + std::vector<double> gsCoo9(pyra5CooGauss,pyra5CooGauss+3); + const double pyra5CooRef[15]={1.0,0.0,0.0, 0.0,1.0,0.0, -1.0,0.0,0.0, 0.0,-1.0,0.0, 0.0,0.0,1.0}; + std::vector<double> refCoo9(pyra5CooRef,pyra5CooRef+15); + f->setGaussLocalizationOnType(INTERP_KERNEL::NORM_PYRA5,refCoo9,gsCoo9,wg9); + std::vector<double> wg10(1); wg10[0]=0.3; + const double pyra13CooGauss[3]={0.1, 0.2, 0.7}; + std::vector<double> gsCoo10(pyra13CooGauss,pyra13CooGauss+3); + const double pyra13CooRef[39]={1.0,0.0,0.0, 0.0,1.0,0.0,-1.0,0.0,0.0,0.0,-1.0,0.0,0.0,0.0,1.0,0.5,0.5,0.0,-0.5,0.5,0.0,-0.5,-0.5,0.0,0.5,-0.5,0.0,0.5,0.0,0.5,0.0,0.5,0.5,-0.5,0.0,0.5,0.0,-0.5,0.5}; + std::vector<double> refCoo10(pyra13CooRef,pyra13CooRef+39); + f->setGaussLocalizationOnType(INTERP_KERNEL::NORM_PYRA13,refCoo10,gsCoo10,wg10); + std::vector<double> wg11(1); wg11[0]=0.3; + const double penta6CooGauss[3]={0.2, 0.3, 0.1}; + std::vector<double> gsCoo11(penta6CooGauss,penta6CooGauss+3); + const double penta6CooRef[18]={-1.0,1.0,0.0,-1.0,-0.0,1.0,-1.0,0.0,0.0,1.0,1.0,0.0,1.0,0.0,1.0,1.0,0.0,0.0}; + std::vector<double> refCoo11(penta6CooRef,penta6CooRef+18); + f->setGaussLocalizationOnType(INTERP_KERNEL::NORM_PENTA6,refCoo11,gsCoo11,wg11); + std::vector<double> wg12(1); wg12[0]=0.3; + const double penta15CooGauss[3]={0.2, 0.3,0.15}; + std::vector<double> gsCoo12(penta15CooGauss,penta15CooGauss+3); + const double penta15CooRef[45]={-1.0,1.0,0.0,-1.0,0.0,1.0,-1.0,0.0,0.0,1.0,1.0,0.0,1.0,0.0,1.0,1.0,0.0,0.0,-1.0,0.5,0.5,-1.0,0.0,0.5,-1.0,0.5,0.0,0.0,1.0,0.0,0.0,0.0,1.0,0.0,0.0,0.0,1.0,0.5,0.5,1.0,0.0, 0.5,1.0,0.5,0.0}; + std::vector<double> refCoo12(penta15CooRef,penta15CooRef+45); + f->setGaussLocalizationOnType(INTERP_KERNEL::NORM_PENTA15,refCoo12,gsCoo12,wg12); + std::vector<double> wg13(1); wg13[0]=0.3; + const double hexa8CooGauss[3]={0.2,0.3,0.15}; + std::vector<double> gsCoo13(hexa8CooGauss,hexa8CooGauss+3); + const double hexa8CooRef[24]={-1.0,-1.0,-1.0,1.0,-1.0,-1.0,1.0,1.0,-1.0,-1.0,1.0,-1.0,-1.0,-1.0,1.0,1.0,-1.0,1.0,1.0,1.0,1.0,-1.0,1.0,1.0}; + std::vector<double> refCoo13(hexa8CooRef,hexa8CooRef+24); + f->setGaussLocalizationOnType(INTERP_KERNEL::NORM_HEXA8,refCoo13,gsCoo13,wg13); + std::vector<double> wg14(1); wg14[0]=0.3; + const double hexa20CooGauss[3]={0.11,0.3,0.55}; + std::vector<double> gsCoo14(hexa20CooGauss,hexa20CooGauss+3); + const double hexa20CooRef[60]={-1.0,-1.0,-1.0,1.0,-1.0,-1.0,1.0,1.0,-1.0,-1.0,1.0,-1.0,-1.0,-1.0,1.0,1.0,-1.0,1.0,1.0,1.0,1.0,-1.0,1.0,1.0,0.0,-1.0,-1.0,1.0,0.0,-1.0,0.0,1.0,-1.0,-1.0,0.0,-1.0,-1.0,-1.0,0.0,1.0,-1.0,0.0,1.0,1.0,0.0,-1.0,1.0,0.0,0.0,-1.0,1.0,1.0,0.0,1.0,0.0,1.0,1.0,-1.0,0.0,1.0}; + std::vector<double> refCoo14(hexa20CooRef,hexa20CooRef+60); + f->setGaussLocalizationOnType(INTERP_KERNEL::NORM_HEXA20,refCoo14,gsCoo14,wg14); + // + resToTest=f->getLocalizationOfDiscr(); + CPPUNIT_ASSERT_EQUAL(3,resToTest->getNumberOfComponents()); + CPPUNIT_ASSERT_EQUAL(8,resToTest->getNumberOfTuples());//2+3+4+4 gauss points for resp TRI3,TRI6,QUAD4,QUAD8 + const double expected3[24]={1.312,3.15,1.02, 0.56,3.3,0.6, 2.18,1.1,0.2, 1.18,1.54,0.98, 1.56,0.3,3.6, 1.613,0.801,4.374, 2.6,2.4,2.3, 2.31232,2.3933985,1.553255}; + for(int i=0;i<24;i++) + CPPUNIT_ASSERT_DOUBLES_EQUAL(expected3[i],resToTest->getIJ(0,i),1e-14); + resToTest->decrRef(); + // + m3->decrRef(); + f->decrRef(); +} + +/*! + * Not activated test ! To be implemented ! + */ +void MEDCouplingBasicsTest4::testQ1Localization1() +{ + MEDCouplingUMesh *m=buildHexa8Mesh_1(); + MEDCouplingFieldDouble *f=MEDCouplingFieldDouble::New(ON_NODES,ONE_TIME); + DataArrayDouble *da=DataArrayDouble::New(); + const double vals1[27]={1.0,3.0,4.0,1.0,3.0,4.0,3.0,2.0,5.0,1.0,3.0,4.0,1.0,3.0,4.0,3.0,2.0,5.0,1.0,3.0,4.0,1.0,3.0,4.0,3.0,2.0,5.0}; + da->alloc(27,1); + std::copy(vals1,vals1+27,da->getPointer()); + f->setMesh(m); + f->setArray(da); + da->decrRef(); + // + const double point1[3]={0.25,0.75,0.25}; + //const double points1[6]={0.25,0.75,0.25,1.0,1.0,1.0}; + double res1[3]; + f->getValueOn(point1,res1); + // + f->decrRef(); + m->decrRef(); +} + +void MEDCouplingBasicsTest4::testP2Localization1() +{ + MEDCouplingUMesh *m=MEDCouplingUMesh::New("testP2",2); + const double coords[12]={0.,2.,3.5,0.,4.5,1.5,1.2,0.32,3.4,1.,2.1,2.4}; + const int conn[6]={0,1,2,3,4,5}; + DataArrayDouble *coo=DataArrayDouble::New(); + coo->alloc(6,2); + std::copy(coords,coords+12,coo->getPointer()); + m->setCoords(coo); + coo->decrRef(); + m->allocateCells(1); + m->insertNextCell(INTERP_KERNEL::NORM_TRI6,6,conn); + m->finishInsertingCells(); + // + MEDCouplingFieldDouble *f=MEDCouplingFieldDouble::New(ON_NODES,ONE_TIME); + f->setMesh(m); + DataArrayDouble *da=DataArrayDouble::New(); + da->alloc(6,3); + const double vals1[18]={1.2,2.3,3.4, 2.2,3.3,4.4, 3.2,4.3,5.4, 4.2,5.3,6.4, 5.2,6.3,7.4, 6.2,7.3,8.4}; + std::copy(vals1,vals1+18,da->getPointer()); + f->setArray(da); + da->decrRef(); + // + const double loc[2]={2.27,1.3}; + DataArrayDouble *locs=f->getValueOnMulti(loc,1); + const double expected1[3]={6.0921164547752236, 7.1921164547752232, 8.2921164547752255}; + for(int i=0;i<3;i++) + CPPUNIT_ASSERT_DOUBLES_EQUAL(expected1[i],locs->getIJ(0,i),1e-12); + locs->decrRef(); + // + m->decrRef(); + f->decrRef(); +} + +void MEDCouplingBasicsTest4::testP2Localization2() +{ + MEDCouplingUMesh *m=MEDCouplingUMesh::New("testP2_2",3); + const double coords[30]={0.33312787792955395, -0.35155740179580952, -0.03567564825034563, 1.307146326477638, -0.57234557776250305, -0.08608044208272235, 0.5551834466499993, 0.62324964668794192, -0.014638951108536295, 0.37761817224442129, -0.38324019806913578, 0.96283164472856886, 0.79494856035658679, -0.40628057809270046, 0.0021004190225864614, 1.023740446371799, 0.07665912970471335, -0.072889657161871096, 0.54564584619517376, 0.11132872093429744, 0.039647326652013051, 0.27164784387819052, -0.42018012100866675, 0.46563376500745146, 0.89501965094896418, -0.56148455362735061, 0.43337469695473035, 0.49118025152924394, 0.093884938060727313, 0.47216346905220891}; + const int conn[10]={0,1,2,3,4,5,6,7,8,9}; + DataArrayDouble *coo=DataArrayDouble::New(); + coo->alloc(10,3); + std::copy(coords,coords+30,coo->getPointer()); + m->setCoords(coo); + coo->decrRef(); + m->allocateCells(1); + m->insertNextCell(INTERP_KERNEL::NORM_TETRA10,10,conn); + m->finishInsertingCells(); + // + MEDCouplingFieldDouble *f=MEDCouplingFieldDouble::New(ON_NODES,ONE_TIME); + f->setMesh(m); + DataArrayDouble *da=DataArrayDouble::New(); + da->alloc(10,1); + const double vals1[10]={1.1,2.1,3.1,4.1,5.2,6.2,7.2,8.2,9.2,10.2}; + std::copy(vals1,vals1+10,da->getPointer()); + f->setArray(da); + da->decrRef(); + // + const double loc[3]={0.64637931739890486, -0.16185896817550552, 0.22678966365273748}; + DataArrayDouble *locs=f->getValueOnMulti(loc,1); + const double expected1[1]={10.0844021968047}; + for(int i=0;i<1;i++) + CPPUNIT_ASSERT_DOUBLES_EQUAL(expected1[i],locs->getIJ(0,i),1e-12); + locs->decrRef(); + // + m->decrRef(); + f->decrRef(); +} + +void MEDCouplingBasicsTest4::testGetValueOn2() +{ + MEDCouplingUMesh *m=build2DTargetMesh_1(); + MEDCouplingFieldDouble *f=MEDCouplingFieldDouble::New(ON_CELLS,NO_TIME); + f->setMesh(m); + DataArrayDouble *arr=DataArrayDouble::New(); + int nbOfCells=m->getNumberOfCells(); + arr->alloc(nbOfCells,3); + f->setArray(arr); + arr->decrRef(); + const double values1[15]={7.,107.,10007.,8.,108.,10008.,9.,109.,10009.,10.,110.,10010.,11.,111.,10011.}; + std::copy(values1,values1+15,arr->getPointer()); + const double loc[10]={-0.05,-0.05, 0.55,-0.25, 0.55,0.15, -0.05,0.45, 0.45,0.45}; + f->checkCoherency(); + DataArrayDouble *locs=f->getValueOnMulti(loc,5); + CPPUNIT_ASSERT_EQUAL(5,locs->getNumberOfTuples()); + CPPUNIT_ASSERT_EQUAL(3,locs->getNumberOfComponents()); + for(int j=0;j<15;j++) + CPPUNIT_ASSERT_DOUBLES_EQUAL(values1[j],locs->getIJ(0,j),1e-12); + locs->decrRef(); + f->decrRef(); + // Testing ON_NODES + f=MEDCouplingFieldDouble::New(ON_NODES,NO_TIME); + f->setMesh(m); + arr=DataArrayDouble::New(); + int nbOfNodes=m->getNumberOfNodes(); + arr->alloc(nbOfNodes,3); + f->setArray(arr); + arr->decrRef(); + const double values2[27]={7.,107.,10007.,8.,108.,10008.,9.,109.,10009.,10.,110.,10010.,11.,111.,10011.,12.,112.,10012.,13.,113.,10013.,14.,114.,10014.,15.,115.,10015.}; + std::copy(values2,values2+27,arr->getPointer()); + const double loc2[8]={0.5432,-0.2432, 0.5478,0.1528, 0.5432,-0.2432, 0.5432,-0.2432}; + const double expected2[12]={9.0272, 109.0272, 10009.0272, 11.4124,111.4124,10011.4124, 9.0272, 109.0272, 10009.0272, 9.0272, 109.0272, 10009.0272}; + f->checkCoherency(); + locs=f->getValueOnMulti(loc2,4); + CPPUNIT_ASSERT_EQUAL(4,locs->getNumberOfTuples()); + CPPUNIT_ASSERT_EQUAL(3,locs->getNumberOfComponents()); + for(int i=0;i<12;i++) + CPPUNIT_ASSERT_DOUBLES_EQUAL(expected2[i],locs->getIJ(0,i),1e-12); + f->decrRef(); + locs->decrRef(); + // + m->decrRef(); +} + +void MEDCouplingBasicsTest4::testDAIGetIdsNotEqual1() +{ + DataArrayInt *d=DataArrayInt::New(); + const int vals1[10]={2,3,5,6,8,5,5,6,1,-5}; + d->alloc(10,1); + std::copy(vals1,vals1+10,d->getPointer()); + DataArrayInt *d2=d->getIdsNotEqual(5); + CPPUNIT_ASSERT_EQUAL(7,d2->getNumberOfTuples()); + CPPUNIT_ASSERT_EQUAL(1,d2->getNumberOfComponents()); + const int expected1[7]={0,1,3,4,7,8,9}; + for(int i=0;i<7;i++) + CPPUNIT_ASSERT_EQUAL(expected1[i],d2->getIJ(0,i)); + d->rearrange(2); + CPPUNIT_ASSERT_THROW(d->getIdsNotEqual(5),INTERP_KERNEL::Exception); + const int vals2[3]={-4,5,6}; + std::vector<int> vals3(vals2,vals2+3); + d->rearrange(1); + DataArrayInt *d3=d->getIdsNotEqualList(&vals3[0],&vals3[0]+vals3.size()); + CPPUNIT_ASSERT_EQUAL(5,d3->getNumberOfTuples()); + CPPUNIT_ASSERT_EQUAL(1,d3->getNumberOfComponents()); + const int expected2[5]={0,1,4,8,9}; + for(int i=0;i<5;i++) + CPPUNIT_ASSERT_EQUAL(expected2[i],d3->getIJ(0,i)); + d3->decrRef(); + d->decrRef(); + d2->decrRef(); +} + +void MEDCouplingBasicsTest4::testDAIComputeOffsets1() +{ + DataArrayInt *d=DataArrayInt::New(); + const int vals1[6]={3,5,1,2,0,8}; + const int expected1[6]={0,3,8,9,11,11}; + d->alloc(6,1); + std::copy(vals1,vals1+6,d->getPointer()); + d->computeOffsets(); + CPPUNIT_ASSERT_EQUAL(6,d->getNumberOfTuples()); + CPPUNIT_ASSERT_EQUAL(1,d->getNumberOfComponents()); + for(int i=0;i<6;i++) + CPPUNIT_ASSERT_EQUAL(expected1[i],d->getIJ(0,i)); + d->decrRef(); +} + +void MEDCouplingBasicsTest4::testUMeshHexagonPrism1() +{ + const double coords[36]={ + 0.8660254037844386, 0.5, 0.0, 0.0, 1.0, 0.0, -0.8660254037844386, 0.5, 0.0, -0.8660254037844386, -0.5, 0.0, 0.0, -1.0, 0.0, 0.8660254037844386, -0.5, 0.0, + 0.8660254037844386, 0.5, 2.0, 0.0, 1.0, 2.0, -0.8660254037844386, 0.5, 2.0, -0.8660254037844386, -0.5, 2.0, 0.0, -1.0, 2.0, 0.8660254037844386, -0.5, 2.0 + }; + const int conn[12]={1,2,3,4,5,0,7,8,9,10,11,6}; + MEDCouplingUMesh *mesh=MEDCouplingUMesh::New("MyFirstHexagonalPrism",3); + DataArrayDouble *coo=DataArrayDouble::New(); + coo->alloc(12,3); + std::copy(coords,coords+36,coo->getPointer()); + mesh->setCoords(coo); + mesh->allocateCells(1); + mesh->insertNextCell(INTERP_KERNEL::NORM_HEXGP12,12,conn); + mesh->finishInsertingCells(); + coo->decrRef(); + // + mesh->checkCoherency(); + MEDCouplingFieldDouble *vols=mesh->getMeasureField(false); + CPPUNIT_ASSERT_EQUAL(1,vols->getNumberOfTuples()); + CPPUNIT_ASSERT_EQUAL(1,vols->getNumberOfComponents()); + CPPUNIT_ASSERT_DOUBLES_EQUAL(-5.196152422706632,vols->getIJ(0,0),1e-12); + DataArrayDouble *bary=mesh->getBarycenterAndOwner(); + CPPUNIT_ASSERT_EQUAL(1,bary->getNumberOfTuples()); + CPPUNIT_ASSERT_EQUAL(3,bary->getNumberOfComponents()); + const double expected1[3]={0.,0.,1.}; + for(int i=0;i<3;i++) + CPPUNIT_ASSERT_DOUBLES_EQUAL(expected1[i],bary->getIJ(0,i),1e-12); + DataArrayInt *d1=DataArrayInt::New(); + DataArrayInt *d2=DataArrayInt::New(); + DataArrayInt *d3=DataArrayInt::New(); + DataArrayInt *d4=DataArrayInt::New(); + MEDCouplingUMesh *m2=mesh->buildDescendingConnectivity(d1,d2,d3,d4); + CPPUNIT_ASSERT_EQUAL(8,m2->getNumberOfCells()); + const int expected4[8][6]={{1,2,3,4,5,0},{7,6,11,10,9,8},{1,7,8,2},{2,8,9,3},{3,9,10,4},{4,10,11,5},{5,11,6,0},{0,6,7,1}}; + const INTERP_KERNEL::NormalizedCellType expected2[8]={INTERP_KERNEL::NORM_POLYGON, INTERP_KERNEL::NORM_POLYGON, INTERP_KERNEL::NORM_QUAD4, INTERP_KERNEL::NORM_QUAD4, INTERP_KERNEL::NORM_QUAD4, INTERP_KERNEL::NORM_QUAD4, INTERP_KERNEL::NORM_QUAD4, INTERP_KERNEL::NORM_QUAD4}; + const int expected3[8]={6,6,4,4,4,4,4,4}; + for(int i=0;i<8;i++) + { + CPPUNIT_ASSERT(m2->getTypeOfCell(i)==expected2[i]); + std::vector<int> v; + m2->getNodeIdsOfCell(i,v); + CPPUNIT_ASSERT((int)v.size()==expected3[i]); + CPPUNIT_ASSERT(std::equal(expected4[i],expected4[i]+expected3[i],v.begin())); + } + d1->decrRef(); + d2->decrRef(); + d3->decrRef(); + d4->decrRef(); + m2->decrRef(); + // + mesh->convertAllToPoly(); + CPPUNIT_ASSERT(INTERP_KERNEL::NORM_POLYHED==mesh->getTypeOfCell(0)); + mesh->unPolyze(); + CPPUNIT_ASSERT(INTERP_KERNEL::NORM_HEXGP12==mesh->getTypeOfCell(0)); + CPPUNIT_ASSERT_EQUAL(13,mesh->getMeshLength()); + // + vols->decrRef(); + bary->decrRef(); + mesh->decrRef(); +} + +void MEDCouplingBasicsTest4::testDADCheckIsMonotonic() +{ + DataArrayDouble *da=DataArrayDouble::New(); + const double vals[4]={-1.,1.01,2.03,6.}; + da->alloc(2,2); + std::copy(vals,vals+4,da->getPointer()); + CPPUNIT_ASSERT_THROW(da->isMonotonic(true, 1e-12),INTERP_KERNEL::Exception); + da->rearrange(1); + CPPUNIT_ASSERT(da->isMonotonic(true, 1e-12)); + da->checkMonotonic(true, 1e-12); + da->setIJ(2,0,6.1); + CPPUNIT_ASSERT(!da->isMonotonic(true, 1e-12)); + CPPUNIT_ASSERT_THROW(da->checkMonotonic(true, 1e-12),INTERP_KERNEL::Exception); + CPPUNIT_ASSERT_THROW(da->checkMonotonic(false, 1e-12),INTERP_KERNEL::Exception); + da->setIJ(2,0,5.99); + CPPUNIT_ASSERT(da->isMonotonic(true, 1e-12)); + CPPUNIT_ASSERT(!da->isMonotonic(true, 1e-1)); + da->decrRef(); +} + +void MEDCouplingBasicsTest4::testCheckCoherencyDeeper1() +{ + MEDCouplingUMesh *m=build3DSourceMesh_1(); + m->checkCoherency(); + m->checkCoherency1(); + m->getNodalConnectivity()->setIJ(8,0,-1); + m->checkCoherency(); + CPPUNIT_ASSERT_THROW(m->checkCoherency1(),INTERP_KERNEL::Exception); + m->getNodalConnectivity()->setIJ(8,0,-6); + m->checkCoherency(); + CPPUNIT_ASSERT_THROW(m->checkCoherency1(),INTERP_KERNEL::Exception); + m->getNodalConnectivity()->setIJ(8,0,9);//9>=NbOfNodes + m->checkCoherency(); + CPPUNIT_ASSERT_THROW(m->checkCoherency1(),INTERP_KERNEL::Exception); + m->getNodalConnectivity()->setIJ(8,0,8);//OK + m->checkCoherency(); + m->checkCoherency1(); + const int elts[2]={1,5}; + std::vector<int> eltsV(elts,elts+2); + m->convertToPolyTypes(&eltsV[0],&eltsV[0]+eltsV.size()); + m->checkCoherency(); + m->checkCoherency1(); + m->getNodalConnectivity()->setIJ(2,0,9);//9>=NbOfNodes + m->checkCoherency(); + CPPUNIT_ASSERT_THROW(m->checkCoherency1(),INTERP_KERNEL::Exception); + m->getNodalConnectivity()->setIJ(2,0,-3); + m->checkCoherency(); + CPPUNIT_ASSERT_THROW(m->checkCoherency1(),INTERP_KERNEL::Exception); + m->getNodalConnectivity()->setIJ(2,0,-1); + m->checkCoherency(); + CPPUNIT_ASSERT_THROW(m->checkCoherency1(),INTERP_KERNEL::Exception);//Throw because cell#0 is not a polyhedron + m->getNodalConnectivity()->setIJ(2,0,4); + m->checkCoherency(); + m->checkCoherency1(); + m->getNodalConnectivity()->setIJ(7,0,-1); + m->checkCoherency(); + m->checkCoherency1();//OK because we are in polyhedron connec + m->getNodalConnectivity()->setIJ(36,0,14); + m->checkCoherency(); + CPPUNIT_ASSERT_THROW(m->checkCoherency1(),INTERP_KERNEL::Exception);//Throw beacause now cell 5 is a TETRA4 (14) so mimatch of number index and static type. + m->decrRef(); +} + +void MEDCouplingBasicsTest4::testUnPolyze2() +{ + MEDCouplingUMesh *m=MEDCouplingUMesh::New("jjj",3); + DataArrayDouble *coo=DataArrayDouble::New(); + coo->alloc(4,3); + coo->rearrange(1); + coo->iota(0); + coo->rearrange(3); + m->setCoords(coo); + coo->decrRef(); + m->allocateCells(2); + const int conn[4]={0,1,2,3}; + m->insertNextCell(INTERP_KERNEL::NORM_TETRA4,4,conn); + m->insertNextCell(INTERP_KERNEL::NORM_TETRA4,4,conn); + m->finishInsertingCells(); + std::vector<const MEDCouplingUMesh *> ms(4,m); + MEDCouplingUMesh *m2=MEDCouplingUMesh::MergeUMeshesOnSameCoords(ms); + std::vector<int> temp(1,2); + m2->convertToPolyTypes(&temp[0],&temp[0]+temp.size()); + m2->unPolyze(); + CPPUNIT_ASSERT(INTERP_KERNEL::NORM_TETRA4==m2->getTypeOfCell(2)); + CPPUNIT_ASSERT_EQUAL(40,m2->getMeshLength()); + std::vector<int> temp2; + m2->getNodeIdsOfCell(2,temp2); + CPPUNIT_ASSERT(4==(int)temp2.size()); + CPPUNIT_ASSERT(std::equal(conn,conn+4,temp2.begin())); + m2->checkCoherency1(); + MEDCouplingMesh *m3=m2->deepCpy(); + m2->unPolyze(); + CPPUNIT_ASSERT(m3->isEqual(m2,1e-12)); + m3->decrRef(); + m->decrRef(); + m2->decrRef(); +} + +void MEDCouplingBasicsTest4::testDACpyFrom1() +{ + DataArrayDouble *d=DataArrayDouble::New(); + d->alloc(12,1); + d->iota(14.); + d->rearrange(3); + d->setName("Toto"); + d->setInfoOnComponent(0,"X [m]"); + d->setInfoOnComponent(1,"Y [m]"); + d->setInfoOnComponent(2,"Z [m]"); + // + DataArrayDouble *d1=DataArrayDouble::New(); + CPPUNIT_ASSERT(!d->isEqual(*d1,1e-12)); + d1->cpyFrom(*d); + CPPUNIT_ASSERT(d->isEqual(*d1,1e-12)); + d1->cpyFrom(*d); + CPPUNIT_ASSERT(d->isEqual(*d1,1e-12)); + d1->rearrange(2); + CPPUNIT_ASSERT(!d->isEqual(*d1,1e-12)); + d1->cpyFrom(*d); + CPPUNIT_ASSERT(d->isEqual(*d1,1e-12)); + // + DataArrayInt *d2=d->convertToIntArr(); + DataArrayInt *d4=DataArrayInt::New(); + CPPUNIT_ASSERT(!d2->isEqual(*d4)); + d4->cpyFrom(*d2); + CPPUNIT_ASSERT(d2->isEqual(*d4)); + d4->cpyFrom(*d2); + CPPUNIT_ASSERT(d2->isEqual(*d4)); + d4->rearrange(2); + CPPUNIT_ASSERT(!d2->isEqual(*d4)); + d4->cpyFrom(*d2); + CPPUNIT_ASSERT(d2->isEqual(*d4)); + // + d->decrRef(); + d1->decrRef(); + d2->decrRef(); + d4->decrRef(); +} + +void MEDCouplingBasicsTest4::testDAITransformWithIndArr1() +{ + const int tab1[4]={17,18,22,19}; + const int tab2[12]={0,1,1,3,3,0,1,3,2,2,3,0}; + const int expected[12]={17,18,18,19,19,17,18,19,22,22,19,17}; + DataArrayInt *d=DataArrayInt::New(); + d->alloc(4,1); + std::copy(tab1,tab1+4,d->getPointer()); + DataArrayInt *d1=DataArrayInt::New(); + d1->alloc(12,1); + std::copy(tab2,tab2+12,d1->getPointer()); + // + d1->transformWithIndArr(d->getConstPointer(),d->getConstPointer()+d->getNbOfElems()); + CPPUNIT_ASSERT_EQUAL(12,d1->getNumberOfTuples()); + CPPUNIT_ASSERT_EQUAL(1,d1->getNumberOfComponents()); + for(int i=0;i<12;i++) + CPPUNIT_ASSERT_EQUAL(expected[i],d1->getIJ(i,0)); + // + d->decrRef(); + d1->decrRef(); +} + +void MEDCouplingBasicsTest4::testDAIBuildPermArrPerLevel1() +{ + const int arr[12]={2,0,1,1,0,1,2,0,1,1,0,0}; + const int expected1[12]={10,0,5,6,1,7,11,2,8,9,3,4}; + DataArrayInt *da=DataArrayInt::New(); + da->alloc(12,1); + std::copy(arr,arr+12,da->getPointer()); + DataArrayInt *da2=da->buildPermArrPerLevel(); + CPPUNIT_ASSERT_EQUAL(12,da2->getNumberOfTuples()); + CPPUNIT_ASSERT_EQUAL(1,da2->getNumberOfComponents()); + for(int i=0;i<12;i++) + CPPUNIT_ASSERT_EQUAL(expected1[i],da2->getIJ(i,0)); + da->decrRef(); + da2->decrRef(); +} + +void MEDCouplingBasicsTest4::testDAIOperations1() +{ + const int arr1[12]={-1,-2,4,7,3,2,6,6,4,3,0,1}; + DataArrayInt *da=DataArrayInt::New(); + da->alloc(4,3); + std::copy(arr1,arr1+12,da->getPointer()); + DataArrayInt *da1=DataArrayInt::New(); + da1->alloc(12,1); + da1->iota(2); + CPPUNIT_ASSERT_THROW(DataArrayInt::Add(da,da1),INTERP_KERNEL::Exception);//not same number of tuples/Components + da1->rearrange(3); + DataArrayInt *da2=DataArrayInt::Add(da,da1); + CPPUNIT_ASSERT_EQUAL(4,da2->getNumberOfTuples()); + CPPUNIT_ASSERT_EQUAL(3,da2->getNumberOfComponents()); + const int expected1[12]={1,1,8,12,9,9,14,15,14,14,12,14}; + for(int i=0;i<12;i++) + CPPUNIT_ASSERT_EQUAL(expected1[i],da2->getIJ(0,i)); + da2->decrRef(); + da1->substractEqual(da); + const int expected2[12]={3,5,0,-2,3,5,2,3,6,8,12,12}; + for(int i=0;i<12;i++) + CPPUNIT_ASSERT_EQUAL(expected2[i],da1->getIJ(0,i)); + da1->rearrange(1); da1->iota(2); da1->rearrange(3); + da1->addEqual(da); + for(int i=0;i<12;i++) + CPPUNIT_ASSERT_EQUAL(expected1[i],da1->getIJ(0,i)); + da1->rearrange(1); da1->iota(2); da1->rearrange(3); + da2=DataArrayInt::Multiply(da,da1); + CPPUNIT_ASSERT_EQUAL(4,da2->getNumberOfTuples()); + CPPUNIT_ASSERT_EQUAL(3,da2->getNumberOfComponents()); + const int expected3[12]={-2,-6,16,35,18,14,48,54,40,33,0,13}; + for(int i=0;i<12;i++) + CPPUNIT_ASSERT_EQUAL(expected3[i],da2->getIJ(0,i)); + da2->decrRef(); + da->divideEqual(da1); + CPPUNIT_ASSERT_EQUAL(4,da->getNumberOfTuples()); + CPPUNIT_ASSERT_EQUAL(3,da->getNumberOfComponents()); + const int expected4[12]={0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0}; + for(int i=0;i<12;i++) + CPPUNIT_ASSERT_EQUAL(expected4[i],da->getIJ(0,i)); + std::copy(arr1,arr1+12,da->getPointer()); + da1->multiplyEqual(da); + CPPUNIT_ASSERT_EQUAL(4,da1->getNumberOfTuples()); + CPPUNIT_ASSERT_EQUAL(3,da1->getNumberOfComponents()); + for(int i=0;i<12;i++) + CPPUNIT_ASSERT_EQUAL(expected3[i],da1->getIJ(0,i)); + da1->rearrange(1); da1->iota(2); da1->rearrange(3); + da2=DataArrayInt::Divide(da,da1); + CPPUNIT_ASSERT_EQUAL(4,da2->getNumberOfTuples()); + CPPUNIT_ASSERT_EQUAL(3,da2->getNumberOfComponents()); + for(int i=0;i<12;i++) + CPPUNIT_ASSERT_EQUAL(expected4[i],da2->getIJ(0,i)); + da2->decrRef(); + da1->applyInv(321); + CPPUNIT_ASSERT_EQUAL(4,da1->getNumberOfTuples()); + CPPUNIT_ASSERT_EQUAL(3,da1->getNumberOfComponents()); + const int expected5[12]={160,107,80,64,53,45,40,35,32,29,26,24}; + for(int i=0;i<12;i++) + CPPUNIT_ASSERT_EQUAL(expected5[i],da1->getIJ(0,i)); + da1->applyDivideBy(2); + CPPUNIT_ASSERT_EQUAL(4,da1->getNumberOfTuples()); + CPPUNIT_ASSERT_EQUAL(3,da1->getNumberOfComponents()); + const int expected6[12]={80,53,40,32,26,22,20,17,16,14,13,12}; + for(int i=0;i<12;i++) + CPPUNIT_ASSERT_EQUAL(expected6[i],da1->getIJ(0,i)); + const int expected7[12]={3,4,5,4,5,1,6,3,2,0,6,5}; + da1->applyModulus(7); + for(int i=0;i<12;i++) + CPPUNIT_ASSERT_EQUAL(expected7[i],da1->getIJ(0,i)); + da1->applyLin(1,1); + const int expected8[12]={3,3,3,3,3,1,3,3,0,0,3,3}; + da1->applyRModulus(3); + for(int i=0;i<12;i++) + CPPUNIT_ASSERT_EQUAL(expected8[i],da1->getIJ(0,i)); + // + da1->decrRef(); + da->decrRef(); +} + +void MEDCouplingBasicsTest4::testEmulateMEDMEMBDC1() +{ + MEDCouplingUMesh *m1=0; + MEDCouplingUMesh *m=buildPointe_1(m1); + DataArrayInt *da1=DataArrayInt::New(); + DataArrayInt *da2=DataArrayInt::New(); + DataArrayInt *da3=0; + DataArrayInt *da4=0; + DataArrayInt *da5=0; + DataArrayInt *da0=0; + MEDCouplingUMesh *m2=m->emulateMEDMEMBDC(m1,da1,da2,da3,da4,da5,da0); + const int expected0[47]={0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,36,37,32,33,34,35,38,39,40,41,42,43,44,45,46}; + const int expected1[6]={1,32,29,23,41,36}; + CPPUNIT_ASSERT_EQUAL(47,da0->getNumberOfTuples()); + CPPUNIT_ASSERT_EQUAL(1,da0->getNumberOfComponents()); + for(int i=0;i<47;i++) + CPPUNIT_ASSERT_EQUAL(expected0[i],da0->getIJ(0,i)); + CPPUNIT_ASSERT_EQUAL(6,da5->getNumberOfTuples()); + CPPUNIT_ASSERT_EQUAL(1,da5->getNumberOfComponents()); + for(int i=0;i<6;i++) + CPPUNIT_ASSERT_EQUAL(expected1[i],da5->getIJ(0,i)); + const int expected2[70]={0,1,2,3,4,0,5,6,7,4,8,9,1,7,10,11,12,13,14,5,15,16,17,8,18,19,20,10,21,22,23,2,13,24,25,21,16,26,27,12,19,28,29,15,22,30,31,18,36,26,28,30,24,37,32,33,34,35,38,36,39,40,41,42,37,38,43,44,45,46}; + CPPUNIT_ASSERT_EQUAL(70,da1->getNumberOfTuples()); + CPPUNIT_ASSERT_EQUAL(1,da1->getNumberOfComponents()); + for(int i=0;i<70;i++) + CPPUNIT_ASSERT_EQUAL(expected2[i],da1->getIJ(0,i)); + const int expected3[17]={0,4,8,12,16,20,24,28,32,36,40,44,48,53,58,64,70}; + CPPUNIT_ASSERT_EQUAL(17,da2->getNumberOfTuples()); + CPPUNIT_ASSERT_EQUAL(1,da2->getNumberOfComponents()); + for(int i=0;i<17;i++) + CPPUNIT_ASSERT_EQUAL(expected3[i],da2->getIJ(0,i)); + const int expected4[48]={0,2,4,6,7,9,11,12,14,16,17,19,20,22,24,25,27,29,30,32,34,35,37,39,40,42,43,45,46,48,49,51,52,53,54,55,56,58,60,62,63,64,65,66,67,68,69,70}; + //const int expected4[48]={0,2,4,6,7,9,11,12,14,16,17,19,20,22,24,25,27,29,30,32,34,35,37,39,40,42,43,45,46,48,49,51,52,54,56,57,58,59,60,62,63,64,65,66,67,68,69,70}; + CPPUNIT_ASSERT_EQUAL(48,da4->getNumberOfTuples()); + CPPUNIT_ASSERT_EQUAL(1,da4->getNumberOfComponents()); + for(int i=0;i<48;i++) + CPPUNIT_ASSERT_EQUAL(expected4[i],da4->getIJ(0,i)); + const int expected5[70]={0,1,0,3,0,7,0,1,2,1,4,1,2,3,2,5,2,3,6,3,4,9,4,8,4,5,10,5,9,5,6,11,6,10,6,7,8,7,11,7,8,12,8,9,12,9,10,12,10,11,12,11,13,13,13,13,12,14,13,15,14,15,14,14,14,14,15,15,15,15}; + CPPUNIT_ASSERT_EQUAL(70,da3->getNumberOfTuples()); + CPPUNIT_ASSERT_EQUAL(1,da3->getNumberOfComponents()); + for(int i=0;i<70;i++) + CPPUNIT_ASSERT_EQUAL(expected5[i],da3->getIJ(0,i)); + // + da0->decrRef(); + da1->decrRef(); + da2->decrRef(); + da3->decrRef(); + da4->decrRef(); + da5->decrRef(); + // + m2->decrRef(); + m1->decrRef(); + m->decrRef(); +} + +void MEDCouplingBasicsTest4::testGetLevArrPerCellTypes1() +{ + MEDCouplingUMesh *m1=0; + MEDCouplingUMesh *m=buildPointe_1(m1); + m1->decrRef(); + DataArrayInt *d0=DataArrayInt::New(); + DataArrayInt *d1=DataArrayInt::New(); + DataArrayInt *d2=DataArrayInt::New(); + DataArrayInt *d3=DataArrayInt::New(); + m1=m->buildDescendingConnectivity(d0,d1,d2,d3); + d0->decrRef(); d1->decrRef(); d2->decrRef(); d3->decrRef(); + INTERP_KERNEL::NormalizedCellType order[2]={INTERP_KERNEL::NORM_TRI3,INTERP_KERNEL::NORM_QUAD4}; + DataArrayInt *da1=0; + DataArrayInt *da0=m1->getLevArrPerCellTypes(order,order+2,da1); + const int expected0[47]={0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,1,1,1,1,1,1,1,1,1}; + const int expected1[47]={0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,36,37,32,33,34,35,38,39,40,41,42,43,44,45,46}; + CPPUNIT_ASSERT_EQUAL(47,da0->getNumberOfTuples()); + CPPUNIT_ASSERT_EQUAL(1,da0->getNumberOfComponents()); + for(int i=0;i<47;i++) + CPPUNIT_ASSERT_EQUAL(expected0[i],da0->getIJ(0,i)); + CPPUNIT_ASSERT_EQUAL(2,da1->getNumberOfTuples()); + CPPUNIT_ASSERT_EQUAL(1,da1->getNumberOfComponents()); + CPPUNIT_ASSERT_EQUAL(36,da1->getIJ(0,0));//36 TRI3 + CPPUNIT_ASSERT_EQUAL(11,da1->getIJ(1,0));//11 QUAD4 + // + DataArrayInt *da2=da0->buildPermArrPerLevel(); + // + CPPUNIT_ASSERT_EQUAL(47,da2->getNumberOfTuples()); + CPPUNIT_ASSERT_EQUAL(1,da2->getNumberOfComponents()); + for(int i=0;i<47;i++) + CPPUNIT_ASSERT_EQUAL(expected1[i],da2->getIJ(0,i)); + da2->decrRef(); + da0->decrRef(); + da1->decrRef(); + // + m->decrRef(); + m1->decrRef(); +} + +void MEDCouplingBasicsTest4::testSortCellsInMEDFileFrmt1() +{ + MEDCouplingUMesh *m1=0; + MEDCouplingUMesh *m=buildPointe_1(m1); + MEDCouplingUMesh *m2=(MEDCouplingUMesh *)m->deepCpy(); + m->setCoords(0); + const int vals[16]={0,1,2,14,3,12,4,5,15,6,7,8,9,10,11,13}; + DataArrayInt *da=DataArrayInt::New(); + da->alloc(16,1); + std::copy(vals,vals+16,da->getPointer()); + DataArrayInt *daa=da->invertArrayN2O2O2N(16); + m->renumberCells(daa->getConstPointer(),false); + daa->decrRef(); + DataArrayInt *da2=m->sortCellsInMEDFileFrmt(); + CPPUNIT_ASSERT(m2->isEqual(m2,1e-12)); + CPPUNIT_ASSERT(da->isEqual(*da2)); + m2->decrRef(); + da2->decrRef(); + da->decrRef(); + m1->decrRef(); + m->decrRef(); +} + +void MEDCouplingBasicsTest4::testBuildPartAndReduceNodes1() +{ + MEDCouplingMesh *m=build2DTargetMesh_1(); + const int arr[2]={1,0}; + DataArrayInt *da; + MEDCouplingMesh *m2=m->buildPartAndReduceNodes(arr,arr+2,da); + CPPUNIT_ASSERT_EQUAL(5,m2->getNumberOfNodes()); + CPPUNIT_ASSERT_EQUAL(2,m2->getNumberOfCells()); + MEDCouplingFieldDouble *f=m2->getMeasureField(true); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.125,f->getArray()->getIJ(0,0),1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.25,f->getArray()->getIJ(1,0),1e-12); + f->decrRef(); + da->decrRef(); + m2->decrRef(); + m->decrRef(); +} + +void MEDCouplingBasicsTest4::testDAITransformWithIndArrR1() +{ + const int tab1[6]={2,4,5,3,6,7}; + const int tab2[12]={-1,-1,0,1,2,3,4,5,-1,-1,-1,-1}; + const int expected[6]={0,3,1,2,4,5}; + DataArrayInt *d=DataArrayInt::New(); + d->alloc(6,1); + std::copy(tab1,tab1+6,d->getPointer()); + DataArrayInt *d1=DataArrayInt::New(); + d1->alloc(12,1); + std::copy(tab2,tab2+12,d1->getPointer()); + // + DataArrayInt *d3=d->transformWithIndArrR(d1->getConstPointer(),d1->getConstPointer()+d1->getNbOfElems()); + CPPUNIT_ASSERT_EQUAL(6,d3->getNumberOfTuples()); + CPPUNIT_ASSERT_EQUAL(1,d3->getNumberOfComponents()); + for(int i=0;i<6;i++) + CPPUNIT_ASSERT_EQUAL(expected[i],d3->getIJ(i,0)); + d3->decrRef(); + // + d->decrRef(); + d1->decrRef(); +} + +void MEDCouplingBasicsTest4::testDAISplitByValueRange1() +{ + const int val1[9]={6,5,0,3,2,7,8,1,4}; + const int val2[3]={0,4,9}; + DataArrayInt *d=DataArrayInt::New(); + d->alloc(9,1); + std::copy(val1,val1+9,d->getPointer()); + DataArrayInt *ee=0,*f=0,*g=0; + d->splitByValueRange(val2,val2+3,ee,f,g); + CPPUNIT_ASSERT_EQUAL(9,ee->getNumberOfTuples()); + CPPUNIT_ASSERT_EQUAL(1,ee->getNumberOfComponents()); + CPPUNIT_ASSERT_EQUAL(9,f->getNumberOfTuples()); + CPPUNIT_ASSERT_EQUAL(1,f->getNumberOfComponents()); + CPPUNIT_ASSERT_EQUAL(2,g->getNumberOfTuples()); + CPPUNIT_ASSERT_EQUAL(1,g->getNumberOfComponents()); + // + const int expected1[9]={1,1,0,0,0,1,1,0,1}; + const int expected2[9]={2,1,0,3,2,3,4,1,0}; + for(int i=0;i<9;i++) + { + CPPUNIT_ASSERT_EQUAL(expected1[i],ee->getIJ(i,0)); + CPPUNIT_ASSERT_EQUAL(expected2[i],f->getIJ(i,0)); + } + CPPUNIT_ASSERT_EQUAL(0,g->getIJ(0,0)); + CPPUNIT_ASSERT_EQUAL(1,g->getIJ(1,0)); + // + ee->decrRef(); + f->decrRef(); + g->decrRef(); + // + d->setIJ(6,0,9); + CPPUNIT_ASSERT_THROW(d->splitByValueRange(val2,val2+3,ee,f,g),INTERP_KERNEL::Exception); + // + d->decrRef(); +} + +void MEDCouplingBasicsTest4::testUMeshSplitProfilePerType1() +{ + const int val0[5]={2,0,1,3,4}; + MEDCouplingUMesh *m=build2DTargetMesh_1(); + m->renumberCells(val0,false); + std::vector<int> code; + std::vector<DataArrayInt *> idsInPflPerType; + std::vector<DataArrayInt *> pfls; + // + const int val1[3]={0,2,3}; + DataArrayInt *d=DataArrayInt::New(); + d->alloc(3,1); + d->setName("sup"); + std::copy(val1,val1+3,d->getPointer()); + m->splitProfilePerType(d,code,idsInPflPerType,pfls); + CPPUNIT_ASSERT_EQUAL(6,(int)code.size()); + CPPUNIT_ASSERT_EQUAL(2,(int)idsInPflPerType.size()); + const int expected1[6]={3,1,0, 4,2,1}; + for(int i=0;i<6;i++) + CPPUNIT_ASSERT_EQUAL(expected1[i],code[i]); + CPPUNIT_ASSERT_EQUAL(1,idsInPflPerType[0]->getNumberOfTuples()); + CPPUNIT_ASSERT_EQUAL(0,idsInPflPerType[0]->getIJ(0,0)); + CPPUNIT_ASSERT_EQUAL(2,idsInPflPerType[1]->getNumberOfTuples()); + CPPUNIT_ASSERT_EQUAL(1,idsInPflPerType[1]->getIJ(0,0)); + CPPUNIT_ASSERT_EQUAL(2,idsInPflPerType[1]->getIJ(1,0)); + idsInPflPerType[0]->decrRef(); + idsInPflPerType[1]->decrRef(); + CPPUNIT_ASSERT_EQUAL(2,(int)pfls.size()); + CPPUNIT_ASSERT(std::string("sup")==pfls[0]->getName()); + CPPUNIT_ASSERT_EQUAL(1,pfls[0]->getNumberOfTuples()); + CPPUNIT_ASSERT_EQUAL(0,pfls[0]->getIJ(0,0)); + CPPUNIT_ASSERT(std::string("sup")==pfls[1]->getName()); + CPPUNIT_ASSERT_EQUAL(2,pfls[1]->getNumberOfTuples()); + CPPUNIT_ASSERT_EQUAL(0,pfls[1]->getIJ(0,0)); + CPPUNIT_ASSERT_EQUAL(1,pfls[1]->getIJ(1,0)); + pfls[0]->decrRef(); + pfls[1]->decrRef(); + d->decrRef(); + idsInPflPerType.clear(); + pfls.clear(); + code.clear(); + // + const int val2[4]={0,2,3,4};// all quad4 are selected here ! So no profile for Quads + d=DataArrayInt::New(); + d->alloc(4,1); + std::copy(val2,val2+4,d->getPointer()); + m->splitProfilePerType(d,code,idsInPflPerType,pfls); + CPPUNIT_ASSERT_EQUAL(6,(int)code.size()); + CPPUNIT_ASSERT_EQUAL(2,(int)idsInPflPerType.size()); + const int expected2[6]={3,1,0, 4,3,-1}; + for(int i=0;i<6;i++) + CPPUNIT_ASSERT_EQUAL(expected2[i],code[i]); + CPPUNIT_ASSERT_EQUAL(1,idsInPflPerType[0]->getNumberOfTuples()); + CPPUNIT_ASSERT_EQUAL(0,idsInPflPerType[0]->getIJ(0,0)); + CPPUNIT_ASSERT_EQUAL(3,idsInPflPerType[1]->getNumberOfTuples()); + CPPUNIT_ASSERT_EQUAL(1,idsInPflPerType[1]->getIJ(0,0)); + CPPUNIT_ASSERT_EQUAL(2,idsInPflPerType[1]->getIJ(1,0)); + CPPUNIT_ASSERT_EQUAL(3,idsInPflPerType[1]->getIJ(2,0)); + idsInPflPerType[0]->decrRef(); + idsInPflPerType[1]->decrRef(); + CPPUNIT_ASSERT_EQUAL(1,(int)pfls.size()); + CPPUNIT_ASSERT_EQUAL(1,pfls[0]->getNumberOfTuples()); + CPPUNIT_ASSERT_EQUAL(0,pfls[0]->getIJ(0,0)); + pfls[0]->decrRef(); + d->decrRef(); + idsInPflPerType.clear(); + pfls.clear(); + code.clear(); + // + const int val3[3]={1,0,2};// all tri3 are selected here but not in the same order ! Profile requested for Tri3 + d=DataArrayInt::New(); + d->alloc(3,1); + std::copy(val3,val3+3,d->getPointer()); + m->splitProfilePerType(d,code,idsInPflPerType,pfls); + CPPUNIT_ASSERT_EQUAL(6,(int)code.size()); + CPPUNIT_ASSERT_EQUAL(2,(int)idsInPflPerType.size()); + const int expected3[6]={3,2,0, 4,1,1}; + for(int i=0;i<6;i++) + CPPUNIT_ASSERT_EQUAL(expected3[i],code[i]); + CPPUNIT_ASSERT_EQUAL(2,idsInPflPerType[0]->getNumberOfTuples()); + CPPUNIT_ASSERT_EQUAL(0,idsInPflPerType[0]->getIJ(0,0)); + CPPUNIT_ASSERT_EQUAL(1,idsInPflPerType[0]->getIJ(1,0)); + CPPUNIT_ASSERT_EQUAL(1,idsInPflPerType[1]->getNumberOfTuples()); + CPPUNIT_ASSERT_EQUAL(2,idsInPflPerType[1]->getIJ(0,0)); + idsInPflPerType[0]->decrRef(); + idsInPflPerType[1]->decrRef(); + CPPUNIT_ASSERT_EQUAL(2,(int)pfls.size()); + CPPUNIT_ASSERT_EQUAL(2,pfls[0]->getNumberOfTuples()); + CPPUNIT_ASSERT_EQUAL(1,pfls[0]->getIJ(0,0)); + CPPUNIT_ASSERT_EQUAL(0,pfls[0]->getIJ(1,0)); + CPPUNIT_ASSERT_EQUAL(0,pfls[1]->getIJ(0,0)); + pfls[0]->decrRef(); + pfls[1]->decrRef(); + d->decrRef(); + idsInPflPerType.clear(); + pfls.clear(); + code.clear(); + // + const int val4[2]={3,4};// all tri3 are selected here but not in the same order ! Profile requested for Tri3 + d=DataArrayInt::New(); + d->alloc(2,1); + std::copy(val4,val4+2,d->getPointer()); + m->splitProfilePerType(d,code,idsInPflPerType,pfls); + CPPUNIT_ASSERT_EQUAL(3,(int)code.size()); + CPPUNIT_ASSERT_EQUAL(1,(int)idsInPflPerType.size()); + const int expected4[3]={4,2,0}; + for(int i=0;i<3;i++) + CPPUNIT_ASSERT_EQUAL(expected4[i],code[i]); + CPPUNIT_ASSERT_EQUAL(2,idsInPflPerType[0]->getNumberOfTuples()); + CPPUNIT_ASSERT_EQUAL(0,idsInPflPerType[0]->getIJ(0,0)); + CPPUNIT_ASSERT_EQUAL(1,idsInPflPerType[0]->getIJ(1,0)); + idsInPflPerType[0]->decrRef(); + CPPUNIT_ASSERT_EQUAL(1,(int)pfls.size()); + CPPUNIT_ASSERT_EQUAL(2,pfls[0]->getNumberOfTuples()); + CPPUNIT_ASSERT_EQUAL(1,pfls[0]->getIJ(0,0)); + CPPUNIT_ASSERT_EQUAL(2,pfls[0]->getIJ(1,0)); + pfls[0]->decrRef(); + d->decrRef(); + idsInPflPerType.clear(); + pfls.clear(); + code.clear(); + // + m->decrRef(); +} + +void MEDCouplingBasicsTest4::testDAIBuildExplicitArrByRanges1() +{ + DataArrayInt *d=DataArrayInt::New(); + d->alloc(3,1); + const int vals1[3]={0,2,3}; + std::copy(vals1,vals1+3,d->getPointer()); + DataArrayInt *e=DataArrayInt::New(); + e->alloc(6,1); + const int vals2[6]={0,3,6,10,14,20}; + std::copy(vals2,vals2+6,e->getPointer()); + // + DataArrayInt *f=d->buildExplicitArrByRanges(e); + CPPUNIT_ASSERT_EQUAL(11,f->getNumberOfTuples()); + CPPUNIT_ASSERT_EQUAL(1,f->getNumberOfComponents()); + const int expected1[11]={0,1,2,6,7,8,9,10,11,12,13}; + for(int i=0;i<11;i++) + CPPUNIT_ASSERT_EQUAL(expected1[i],f->getIJ(i,0)); + // + f->decrRef(); + e->decrRef(); + d->decrRef(); +} + +void MEDCouplingBasicsTest4::testDAIComputeOffsets2() +{ + DataArrayInt *d=DataArrayInt::New(); + const int vals1[6]={3,5,1,2,0,8}; + const int expected1[7]={0,3,8,9,11,11,19}; + d->alloc(6,1); + std::copy(vals1,vals1+6,d->getPointer()); + d->computeOffsets2(); + CPPUNIT_ASSERT_EQUAL(7,d->getNumberOfTuples()); + CPPUNIT_ASSERT_EQUAL(1,d->getNumberOfComponents()); + for(int i=0;i<7;i++) + CPPUNIT_ASSERT_EQUAL(expected1[i],d->getIJ(0,i)); + d->decrRef(); +} + +void MEDCouplingBasicsTest4::testMergeField3() +{ + MEDCouplingUMesh *m=build2DTargetMesh_1(); + m->getCoords()->setInfoOnComponent(0,"x [m]"); + m->getCoords()->setInfoOnComponent(1,"z [km]"); + m->setName("m"); + m->setDescription("desc"); + MEDCouplingFieldDouble *f1=MEDCouplingFieldDouble::New(ON_CELLS,ONE_TIME); + f1->setName("f1"); + f1->setMesh(m); + DataArrayDouble *arr=DataArrayDouble::New(); + arr->alloc(5,2); + arr->setInfoOnComponent(0,"X [m]"); + arr->setInfoOnComponent(1,"YY [mm]"); + arr->fillWithValue(2.); + f1->setArray(arr); + arr->decrRef(); + m->decrRef(); + // + std::vector<const MEDCouplingFieldDouble *> tmp(1); + tmp[0]=f1; + MEDCouplingFieldDouble *f2=MEDCouplingFieldDouble::MergeFields(tmp); + CPPUNIT_ASSERT(f1->isEqual(f2,1e-12,1e-12)); + // + f1->decrRef(); + f2->decrRef(); +} + +void MEDCouplingBasicsTest4::testGetDistributionOfTypes1() +{ + MEDCouplingUMesh *m=build2DTargetMesh_1(); + const int tab1[5]={2,0,1,3,4}; + CPPUNIT_ASSERT_THROW(m->getDistributionOfTypes(),INTERP_KERNEL::Exception); + m->renumberCells(tab1,false); + std::vector<int> code=m->getDistributionOfTypes(); + CPPUNIT_ASSERT_EQUAL(6,(int)code.size()); + CPPUNIT_ASSERT_EQUAL(3,code[0]); + CPPUNIT_ASSERT_EQUAL(2,code[1]); + CPPUNIT_ASSERT_EQUAL(-1,code[2]); + CPPUNIT_ASSERT_EQUAL(4,code[3]); + CPPUNIT_ASSERT_EQUAL(3,code[4]); + CPPUNIT_ASSERT_EQUAL(-1,code[5]); + m->decrRef(); +} + +void MEDCouplingBasicsTest4::testNorm2_1() +{ + MEDCouplingUMesh *m=build2DTargetMesh_1(); + MEDCouplingFieldDouble *f=MEDCouplingFieldDouble::New(ON_CELLS,ONE_TIME); + f->setMesh(m); + m->decrRef(); + // + DataArrayDouble *d=DataArrayDouble::New(); + const double tab[10]={1.2,1.3,2.2,2.3,3.2,3.3,4.2,4.3,5.2,5.3}; + d->alloc(5,2); + std::copy(tab,tab+10,d->getPointer()); + f->setArray(d); + d->decrRef(); + f->checkCoherency(); + // + CPPUNIT_ASSERT_DOUBLES_EQUAL(11.209371079592289,f->norm2(),1e-14); + // + f->decrRef(); +} + +void MEDCouplingBasicsTest4::testNormMax1() +{ + MEDCouplingUMesh *m=build2DTargetMesh_1(); + MEDCouplingFieldDouble *f=MEDCouplingFieldDouble::New(ON_CELLS,ONE_TIME); + f->setMesh(m); + m->decrRef(); + // + DataArrayDouble *d=DataArrayDouble::New(); + const double tab[10]={2.3,-1.2,6.3,-7.8,2.9,7.7,2.1,0.,3.6,-7.6}; + d->alloc(5,2); + std::copy(tab,tab+10,d->getPointer()); + f->setArray(d); + d->decrRef(); + f->checkCoherency(); + // + CPPUNIT_ASSERT_DOUBLES_EQUAL(7.8,f->normMax(),1e-14); + // + f->decrRef(); +} + +void MEDCouplingBasicsTest4::testFindAndCorrectBadOriented3DExtrudedCells1() +{ + const double coords[38*3]={0.0011180339887498999, -0.0011755705045849499, 0.0, -0.0012331070204200001, -0.0011755705045849499, 0.0, -0.00067557050458494599, -0.00145964954842536, 0.0, -0.00050000000000000001, -0.00086602540378443902, 0.0, 0.00140211303259031, -0.00061803398874989504, 0.0, 0.00086602540378443902, -0.00050000000000000001, 0.0, 0.001, 0.0, 0.0, 0.00034561537182258202, 0.000269164072574575, 0.0, 0.0, 0.001, 0.0, -0.00050000000000000001, 0.00086602540378443902, 0.0, -0.000269164072574575, 0.00034561537182258202, 0.0, -0.001, 0.0, 0.0, -0.00086602540378443902, -0.00050000000000000001, 0.0, -0.00034561537182258202, -0.000269164072574575, 0.0, 0.0, -0.001, 0.0, 0.00050000000000000001, -0.00086602540378443902, 0.0, 0.000269164072574575, -0.00034561537182258202, 0.0, 0.0015, -6.01853107621011e-36, 0.0, 0.00056049747291484397, -0.00145964954842536, 0.0, 0.0011180339887498999, -0.0011755705045849499, 0.00050000000000000001, -0.0012331070204200001, -0.0011755705045849499, 0.00050000000000000001, -0.00067557050458494599, -0.00145964954842536, 0.00050000000000000001, -0.00050000000000000001, -0.00086602540378443902, 0.00050000000000000001, 0.00140211303259031, -0.00061803398874989504, 0.00050000000000000001, 0.00086602540378443902, -0.00050000000000000001, 0.00050000000000000001, 0.001, 0.0, 0.00050000000000000001, 0.00034561537182258202, 0.000269164072574575, 0.00050000000000000001, 0.0, 0.001, 0.00050000000000000001, -0.00050000000000000001, 0.00086602540378443902, 0.00050000000000000001, -0.000269164072574575, 0.00034561537182258202, 0.00050000000000000001, -0.001, 0.0, 0.00050000000000000001, -0.00086602540378443902, -0.00050000000000000001, 0.00050000000000000001, -0.00034561537182258202, -0.000269164072574575, 0.00050000000000000001, 0.0, -0.001, 0.00050000000000000001, 0.00050000000000000001, -0.00086602540378443902, 0.00050000000000000001, 0.000269164072574575, -0.00034561537182258202, 0.00050000000000000001, 0.0015, -6.01853107621011e-36, 0.00050000000000000001, 0.00056049747291484397, -0.00145964954842536, 0.00050000000000000001}; + const int conn[56]={2, 1, 3, 21, 20, 22, 4, 0, 5, 23, 19, 24, 8, 9, 10, 27, 28, 29, 11, 12, 13, 30, 31, 32, 0, 18, 15, 5, 19, 37, 34, 24, 6, 17, 4, 5, 25, 36, 23, 24, 3, 14, 16, 13, 22, 33, 35, 32, 13, 16, 7, 10, 32, 35, 26, 29}; + const int connExp[64]={16, 2, 1, 3, 21, 20, 22, 16, 4, 0, 5, 23, 19, 24, 16, 8, 10, 9, 27, 29, 28, 16, 11, 13, 12, 30, 32, 31, 18, 0, 18, 15, 5, 19, 37, 34, 24,18, 6, 17, 4, 5, 25, 36, 23, 24, 18, 3, 13, 16, 14, 22, 32, 35, 33, 18, 13, 10, 7, 16, 32, 29, 26, 35}; + const int invalidCells[4]={2,3,6,7}; + MEDCouplingUMesh *m=MEDCouplingUMesh::New("Example",3); + DataArrayDouble *coo=DataArrayDouble::New(); + coo->alloc(38,3); + std::copy(coords,coords+114,coo->getPointer()); + m->setCoords(coo); + coo->decrRef(); + m->allocateCells(8); + m->insertNextCell(INTERP_KERNEL::NORM_PENTA6,6,conn); + m->insertNextCell(INTERP_KERNEL::NORM_PENTA6,6,conn+6); + m->insertNextCell(INTERP_KERNEL::NORM_PENTA6,6,conn+12); + m->insertNextCell(INTERP_KERNEL::NORM_PENTA6,6,conn+18); + m->insertNextCell(INTERP_KERNEL::NORM_HEXA8,8,conn+24); + m->insertNextCell(INTERP_KERNEL::NORM_HEXA8,8,conn+32); + m->insertNextCell(INTERP_KERNEL::NORM_HEXA8,8,conn+40); + m->insertNextCell(INTERP_KERNEL::NORM_HEXA8,8,conn+48); + m->finishInsertingCells(); + // + DataArrayInt *v=m->findAndCorrectBadOriented3DExtrudedCells(); + CPPUNIT_ASSERT_EQUAL(4,v->getNumberOfTuples()); + CPPUNIT_ASSERT(std::equal(v->begin(),v->end(),invalidCells)); + CPPUNIT_ASSERT(std::equal(connExp,connExp+64,m->getNodalConnectivity()->getConstPointer())); + v->decrRef(); + // + m->decrRef(); +} + +void MEDCouplingBasicsTest4::testConvertExtrudedPolyhedra1() +{ + const int conn[72]={1,2,3,4, 5,6,7,8,9,10,11,12, 13,14,15,16, 17,18,19,20,21,22, 23,24,25,26,27,28, 29,30,31,32,33,34,35,36,37,38, 39,40,41,42,43,44,45,46, 47,48,49,50,51,52,53,54,55,56,57,58, 59,60,61,62,63,64,65,66,67,68,69,70,71,72}; + MEDCouplingUMesh *m=MEDCouplingUMesh::New("Example",3); + DataArrayDouble *coo=DataArrayDouble::New(); + coo->alloc(73,3); + coo->rearrange(1); coo->iota(0); coo->rearrange(3); + m->setCoords(coo); + coo->decrRef(); + m->allocateCells(9); + m->insertNextCell(INTERP_KERNEL::NORM_TETRA4,4,conn); + m->insertNextCell(INTERP_KERNEL::NORM_HEXA8,8,conn+4); + m->insertNextCell(INTERP_KERNEL::NORM_TETRA4,4,conn+12); + m->insertNextCell(INTERP_KERNEL::NORM_POLYHED,6,conn+16); + m->insertNextCell(INTERP_KERNEL::NORM_PENTA6,6,conn+22); + m->insertNextCell(INTERP_KERNEL::NORM_POLYHED,10,conn+28); + m->insertNextCell(INTERP_KERNEL::NORM_HEXA8,8,conn+38); + m->insertNextCell(INTERP_KERNEL::NORM_HEXGP12,12,conn+46); + m->insertNextCell(INTERP_KERNEL::NORM_POLYHED,14,conn+58); + m->finishInsertingCells(); + // + m->convertExtrudedPolyhedra(); + DataArrayInt *da=m->getNodalConnectivity(); + DataArrayInt *dai=m->getNodalConnectivityIndex(); + CPPUNIT_ASSERT_EQUAL((std::size_t)10,dai->getNbOfElems()); + CPPUNIT_ASSERT_EQUAL((std::size_t)159,da->getNbOfElems()); + // + const int expected1[159]={14,1,2,3,4, + 18,5,6,7,8,9,10,11,12, + 14,13,14,15,16, + 31,17,18,19,-1,20,22,21,-1,17,20,21,18,-1,18,21,22,19,-1,19,22,20,17, + 16,23,24,25,26,27,28, + 31,29,30,31,32,33,-1,34,38,37,36,35,-1,29,34,35,30,-1,30,35,36,31,-1,31,36,37,32,-1,32,37,38,33,-1,33,38,34,29, + 18,39,40,41,42,43,44,45,46, + 22,47,48,49,50,51,52,53,54,55,56,57,58, + 31,59,60,61,62,63,64,65,-1,66,72,71,70,69,68,67,-1,59,66,67,60,-1,60,67,68,61,-1,61,68,69,62,-1,62,69,70,63,-1,63,70,71,64,-1,64,71,72,65,-1,65,72,66,59}; + const int expected2[10]={0,5,14,19,42,49,86,95,108,159}; + CPPUNIT_ASSERT(std::equal(expected1,expected1+159,da->getConstPointer())); + CPPUNIT_ASSERT(std::equal(expected2,expected2+10,dai->getConstPointer())); + m->checkCoherency2(); + // + m->decrRef(); +} + +void MEDCouplingBasicsTest4::testNonRegressionCopyTinyStrings() +{ + MEDCouplingUMesh *m=build2DTargetMesh_1(); + MEDCouplingFieldDouble *f1=m->getMeasureField(true); + f1->getArray()->setInfoOnComponent(0,"P [N/m^2]"); + DataArrayDouble *bary=m->getBarycenterAndOwner(); + MEDCouplingFieldDouble *f2=f1->buildNewTimeReprFromThis(NO_TIME,false); + f2->setArray(bary); + CPPUNIT_ASSERT_THROW(f1->copyTinyAttrFrom(f2),INTERP_KERNEL::Exception); + m->decrRef(); + f1->decrRef(); + bary->decrRef(); + f2->decrRef(); +} + +void MEDCouplingBasicsTest4::testDaDSetPartOfValuesAdv1() +{ + const double tab1[18]={3.,4.,5., 13.,14.,15., 23.,24.,25., 33.,34.,35., 43.,44.,45., 53.,54.,55.}; + const double tab2[9]={6.,7.,8., 16.,17.,18., 26.,27.,28.}; + const int tab3[6]={4,1, 2,2, 3,0}; + DataArrayDouble *a=DataArrayDouble::New(); + a->alloc(6,3); + std::copy(tab1,tab1+18,a->getPointer()); + DataArrayDouble *b=DataArrayDouble::New(); + b->alloc(3,3); + std::copy(tab2,tab2+9,b->getPointer()); + DataArrayInt *c=DataArrayInt::New(); + c->alloc(3,2); + std::copy(tab3,tab3+6,c->getPointer()); + // + a->setPartOfValuesAdv(b,c); + const double expected1[18]={3.,4.,5., 13.,14.,15., 26.,27.,28., 6.,7.,8., 16.,17.,18., 53.,54.,55.}; + std::equal(expected1,expected1+18,a->getConstPointer()); + // + a->decrRef(); + b->decrRef(); + c->decrRef(); +} + +void MEDCouplingBasicsTest4::testUMeshBuildSetInstanceFromThis1() +{ + MEDCouplingUMesh *m=build3DSurfTargetMesh_1(); + MEDCouplingUMesh *m2=m->buildSetInstanceFromThis(3); + CPPUNIT_ASSERT_EQUAL(m->getNodalConnectivity(),m2->getNodalConnectivity()); + CPPUNIT_ASSERT_EQUAL(m->getNodalConnectivityIndex(),m2->getNodalConnectivityIndex()); + CPPUNIT_ASSERT_EQUAL(m->getCoords(),m2->getCoords()); + m2->decrRef(); + m->decrRef(); + // + m=MEDCouplingUMesh::New("toto",2); + m2=m->buildSetInstanceFromThis(3); + CPPUNIT_ASSERT_EQUAL(0,m2->getNumberOfNodes()); + CPPUNIT_ASSERT_EQUAL(0,m2->getNumberOfCells()); + m->decrRef(); + m2->decrRef(); +} + +void MEDCouplingBasicsTest4::testUMeshMergeMeshesCVW1() +{ + MEDCouplingUMesh *m=build3DSurfTargetMesh_1(); + MEDCouplingUMesh *m2=MEDCouplingUMesh::New("toto",2); + MEDCouplingUMesh *m3=MEDCouplingUMesh::MergeUMeshes(m,m2); + m3->setName(m->getName().c_str()); + CPPUNIT_ASSERT(m->isEqual(m3,1e-12)); + m3->decrRef(); + m->decrRef(); + m2->decrRef(); +} + +void MEDCouplingBasicsTest4::testChangeUnderlyingMeshWithCMesh1() +{ + MEDCouplingCMesh* mesh=MEDCouplingCMesh::New(); + DataArrayDouble* coordsX=DataArrayDouble::New(); + double arrX[4] = { -1., 1., 2., 4. }; + coordsX->useArray(arrX,false, CPP_DEALLOC,4,1); + DataArrayDouble* coordsY=DataArrayDouble::New(); + double arrY[4] = { -2., 2., 4., 8. }; + coordsY->useArray(arrY,false, CPP_DEALLOC,4,1); + DataArrayDouble* coordsZ=DataArrayDouble::New(); + double arrZ[4] = { -3., 3., 6., 12. }; + coordsZ->useArray(arrZ,false, CPP_DEALLOC,4,1); + mesh->setCoords(coordsX,coordsY,coordsZ); + coordsX->decrRef(); + coordsY->decrRef(); + coordsZ->decrRef(); + MEDCouplingMesh *mesh2=mesh->deepCpy(); + // + static const int ids1[9]={0,1,2,10,11,12,20,21,22}; + for(const int *myId=ids1;myId!=ids1+9;myId++) + { + MEDCouplingFieldDouble *f=mesh->getMeasureField(true); + f->changeUnderlyingMesh(mesh2,*myId,1e-12); + f->decrRef(); + } + mesh2->setName("uuuu"); + for(const int *myId=ids1+1;myId!=ids1+9;myId++) + { + MEDCouplingFieldDouble *f=mesh->getMeasureField(true); + f->changeUnderlyingMesh(mesh2,*myId,1e-12); + f->decrRef(); + } + // + mesh2->decrRef(); + mesh->decrRef(); +} + +void MEDCouplingBasicsTest4::testDADFindCommonTuples1() +{ + DataArrayDouble *da=DataArrayDouble::New(); + da->alloc(6,1); + const double array1[6]={2.3,1.2,1.3,2.3,2.301,0.8}; + std::copy(array1,array1+6,da->getPointer()); + DataArrayInt *c=0,*cI=0; + // nbOftuples=1 + da->findCommonTuples(1e-2,-1,c,cI); + const int expected1[3]={0,3,4}; + const int expected2[2]={0,3}; + CPPUNIT_ASSERT_EQUAL((std::size_t)3,c->getNbOfElems()); + CPPUNIT_ASSERT_EQUAL((std::size_t)2,cI->getNbOfElems()); + CPPUNIT_ASSERT(std::equal(expected1,expected1+3,c->getConstPointer())); + CPPUNIT_ASSERT(std::equal(expected2,expected2+2,cI->getConstPointer())); + c->decrRef(); + cI->decrRef(); + // + da->findCommonTuples(2e-1,-1,c,cI); + const int expected3[5]={0,3,4,1,2}; + const int expected4[3]={0,3,5}; + CPPUNIT_ASSERT_EQUAL((std::size_t)5,c->getNbOfElems()); + CPPUNIT_ASSERT_EQUAL((std::size_t)3,cI->getNbOfElems()); + CPPUNIT_ASSERT(std::equal(expected3,expected3+5,c->getConstPointer())); + CPPUNIT_ASSERT(std::equal(expected4,expected4+3,cI->getConstPointer())); + c->decrRef(); + cI->decrRef(); + // nbOftuples=2 + da->alloc(6,2); + const double array2[12]={2.3,2.3,1.2,1.2,1.3,1.3,2.3,2.3,2.301,2.301,0.8,0.8}; + std::copy(array2,array2+12,da->getPointer()); + da->findCommonTuples(1e-2,-1,c,cI); + CPPUNIT_ASSERT_EQUAL((std::size_t)3,c->getNbOfElems()); + CPPUNIT_ASSERT_EQUAL((std::size_t)2,cI->getNbOfElems()); + CPPUNIT_ASSERT(std::equal(expected1,expected1+3,c->getConstPointer())); + CPPUNIT_ASSERT(std::equal(expected2,expected2+2,cI->getConstPointer())); + c->decrRef(); + cI->decrRef(); + // + da->findCommonTuples(2e-1,-1,c,cI); + CPPUNIT_ASSERT_EQUAL((std::size_t)5,c->getNbOfElems()); + CPPUNIT_ASSERT_EQUAL((std::size_t)3,cI->getNbOfElems()); + CPPUNIT_ASSERT(std::equal(expected3,expected3+5,c->getConstPointer())); + CPPUNIT_ASSERT(std::equal(expected4,expected4+3,cI->getConstPointer())); + c->decrRef(); + cI->decrRef(); + // nbOftuples=3 + da->alloc(6,3); + const double array3[18]={2.3,2.3,2.3,1.2,1.2,1.2,1.3,1.3,1.3,2.3,2.3,2.3,2.301,2.301,2.301,0.8,0.8,0.8}; + std::copy(array3,array3+18,da->getPointer()); + da->findCommonTuples(1e-2,-1,c,cI); + CPPUNIT_ASSERT_EQUAL((std::size_t)3,c->getNbOfElems()); + CPPUNIT_ASSERT_EQUAL((std::size_t)2,cI->getNbOfElems()); + CPPUNIT_ASSERT(std::equal(expected1,expected1+3,c->getConstPointer())); + CPPUNIT_ASSERT(std::equal(expected2,expected2+2,cI->getConstPointer())); + c->decrRef(); + cI->decrRef(); + // + da->findCommonTuples(2e-1,-1,c,cI); + CPPUNIT_ASSERT_EQUAL((std::size_t)5,c->getNbOfElems()); + CPPUNIT_ASSERT_EQUAL((std::size_t)3,cI->getNbOfElems()); + CPPUNIT_ASSERT(std::equal(expected3,expected3+5,c->getConstPointer())); + CPPUNIT_ASSERT(std::equal(expected4,expected4+3,cI->getConstPointer())); + c->decrRef(); + cI->decrRef(); + // + const double array11[6]={2.3,1.2,1.3,2.4,2.5,0.8}; + da->alloc(6,1); + std::copy(array11,array11+6,da->getPointer()); + // nbOftuples=1, no common groups + da->findCommonTuples(1e-2,-1,c,cI); + CPPUNIT_ASSERT_EQUAL((std::size_t)0,c->getNbOfElems()); + CPPUNIT_ASSERT_EQUAL((std::size_t)1,cI->getNbOfElems()); + CPPUNIT_ASSERT_EQUAL(0,cI->getIJ(0,0)); + + da->alloc(6,5); //bad NumberOfComponents + CPPUNIT_ASSERT_THROW(da->findCommonTuples(1e-2,-1,c,cI),INTERP_KERNEL::Exception); + + c->decrRef(); + cI->decrRef(); + da->decrRef(); +} + +void MEDCouplingBasicsTest4::testDABack1() +{ + DataArrayDouble *da=DataArrayDouble::New(); + da->alloc(6,1); + const double array1[6]={2.3,1.2,1.3,2.3,2.301,0.8}; + std::copy(array1,array1+6,da->getPointer()); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.8,da->back(),1e-14); + da->rearrange(2); + CPPUNIT_ASSERT_THROW(da->back(),INTERP_KERNEL::Exception); + da->alloc(0,1); + CPPUNIT_ASSERT_THROW(da->back(),INTERP_KERNEL::Exception); + da->decrRef(); + // + DataArrayInt *da2=DataArrayInt::New(); + da2->alloc(4,1); + const int array2[4]={4,7,8,2}; + std::copy(array2,array2+4,da2->getPointer()); + CPPUNIT_ASSERT_EQUAL(2,da2->back()); + da2->rearrange(2); + CPPUNIT_ASSERT_THROW(da2->back(),INTERP_KERNEL::Exception); + da2->alloc(0,1); + CPPUNIT_ASSERT_THROW(da2->back(),INTERP_KERNEL::Exception); + da2->decrRef(); +} + +void MEDCouplingBasicsTest4::testDADGetDifferentValues1() +{ + DataArrayDouble *da=DataArrayDouble::New(); + da->alloc(6,1); + const double array1[6]={2.3,1.2,1.3,2.3,2.301,0.8}; + std::copy(array1,array1+6,da->getPointer()); + // + const double expected1[4]={2.301,1.2,1.3,0.8}; + DataArrayDouble *dv=da->getDifferentValues(1e-2); + CPPUNIT_ASSERT_EQUAL((std::size_t)4,dv->getNbOfElems()); + for(int i=0;i<4;i++) + CPPUNIT_ASSERT_DOUBLES_EQUAL(expected1[i],dv->getIJ(i,0),1e-14); + dv->decrRef(); + // + dv=da->getDifferentValues(2e-1); + const double expected2[3]={2.301,1.3,0.8}; + CPPUNIT_ASSERT_EQUAL((std::size_t)3,dv->getNbOfElems()); + for(int i=0;i<3;i++) + CPPUNIT_ASSERT_DOUBLES_EQUAL(expected2[i],dv->getIJ(i,0),1e-14); + dv->decrRef(); + da->decrRef(); +} + +void MEDCouplingBasicsTest4::testDAIBuildOld2NewArrayFromSurjectiveFormat2() +{ + const int arr[5]={0,3, 5,7,9}; + const int arrI[3]={0,2,5}; + DataArrayInt *a=DataArrayInt::New(); + a->alloc(5,1); + std::copy(arr,arr+5,a->getPointer()); + DataArrayInt *b=DataArrayInt::New(); + b->alloc(3,1); + std::copy(arrI,arrI+3,b->getPointer()); + int newNbTuple=-1; + DataArrayInt *ret=DataArrayInt::BuildOld2NewArrayFromSurjectiveFormat2(10,a->begin(),b->begin(),b->end(),newNbTuple); + const int expected[10]={0,1,2,0,3,4,5,4,6,4}; + CPPUNIT_ASSERT_EQUAL((std::size_t)10,ret->getNbOfElems()); + CPPUNIT_ASSERT_EQUAL(7,newNbTuple); + CPPUNIT_ASSERT_EQUAL(1,ret->getNumberOfComponents()); + CPPUNIT_ASSERT(std::equal(expected,expected+10,ret->getConstPointer())); + CPPUNIT_ASSERT_THROW(DataArrayInt::BuildOld2NewArrayFromSurjectiveFormat2(9,a->begin(),b->begin(),b->end(),newNbTuple),INTERP_KERNEL::Exception); + ret->decrRef(); + b->decrRef(); + a->decrRef(); +} + +void MEDCouplingBasicsTest4::testDADIReverse1() +{ + const int arr[6]={0,3,5,7,9,2}; + DataArrayInt *a=DataArrayInt::New(); + a->alloc(6,1); + std::copy(arr,arr+6,a->getPointer()); + CPPUNIT_ASSERT_EQUAL(2,a->back()); + a->reverse(); + for(int i=0;i<6;i++) + CPPUNIT_ASSERT_EQUAL(arr[5-i],a->getIJ(i,0)); + a->alloc(5,1); + std::copy(arr,arr+5,a->getPointer()); + a->reverse(); + for(int i=0;i<5;i++) + CPPUNIT_ASSERT_EQUAL(arr[4-i],a->getIJ(i,0)); + a->decrRef(); + // + const double arr2[6]={0.,3.,5.,7.,9.,2.}; + DataArrayDouble *b=DataArrayDouble::New(); + b->alloc(6,1); + std::copy(arr2,arr2+6,b->getPointer()); + b->reverse(); + for(int i=0;i<6;i++) + CPPUNIT_ASSERT_DOUBLES_EQUAL(arr2[5-i],b->getIJ(i,0),1e-14); + b->alloc(5,1); + std::copy(arr,arr+5,b->getPointer()); + CPPUNIT_ASSERT_DOUBLES_EQUAL(9.,b->back(),1e-14); + b->reverse(); + for(int i=0;i<5;i++) + CPPUNIT_ASSERT_DOUBLES_EQUAL(arr2[4-i],b->getIJ(i,0),1e-14); + b->decrRef(); +} + +void MEDCouplingBasicsTest4::testGetNodeIdsInUse1() +{ + MEDCouplingUMesh *m0=build2DTargetMesh_1(); + const int CellIds[2]={1,2}; + MEDCouplingUMesh *m1=static_cast<MEDCouplingUMesh *>(m0->buildPartOfMySelf(CellIds,CellIds+2,true)); + int newNbOfNodes=-1; + DataArrayInt *arr=m1->getNodeIdsInUse(newNbOfNodes); + const int expected[9]={-1,0,1,-1,2,3,-1,-1,-1}; + CPPUNIT_ASSERT_EQUAL(4,newNbOfNodes); + CPPUNIT_ASSERT_EQUAL((std::size_t)9,arr->getNbOfElems()); + CPPUNIT_ASSERT(std::equal(expected,expected+9,arr->getConstPointer())); + DataArrayInt *arr2=arr->invertArrayO2N2N2O(newNbOfNodes); + CPPUNIT_ASSERT_EQUAL((std::size_t)4,arr2->getNbOfElems()); + const int expected2[4]={1,2,4,5}; + CPPUNIT_ASSERT(std::equal(expected2,expected2+4,arr2->getConstPointer())); + arr2->decrRef(); + arr->decrRef(); + m1->decrRef(); + m0->decrRef(); +} + +void MEDCouplingBasicsTest4::testBuildDescendingConnec2() +{ + MEDCouplingUMesh *mesh=build2DTargetMesh_1(); + DataArrayInt *desc=DataArrayInt::New(); + DataArrayInt *descIndx=DataArrayInt::New(); + DataArrayInt *revDesc=DataArrayInt::New(); + DataArrayInt *revDescIndx=DataArrayInt::New(); + // + MEDCouplingUMesh *mesh2=mesh->buildDescendingConnectivity2(desc,descIndx,revDesc,revDescIndx); + mesh2->checkCoherency(); + CPPUNIT_ASSERT_EQUAL(1,mesh2->getMeshDimension()); + CPPUNIT_ASSERT_EQUAL(13,mesh2->getNumberOfCells()); + CPPUNIT_ASSERT_EQUAL((std::size_t)14,revDescIndx->getNbOfElems()); CPPUNIT_ASSERT_EQUAL(14,revDescIndx->getNumberOfTuples()); + CPPUNIT_ASSERT_EQUAL((std::size_t)6,descIndx->getNbOfElems()); CPPUNIT_ASSERT_EQUAL(6,descIndx->getNumberOfTuples()); + CPPUNIT_ASSERT_EQUAL((std::size_t)18,desc->getNbOfElems()); CPPUNIT_ASSERT_EQUAL(18,desc->getNumberOfTuples()); + CPPUNIT_ASSERT_EQUAL((std::size_t)18,revDesc->getNbOfElems()); CPPUNIT_ASSERT_EQUAL(18,revDesc->getNumberOfTuples()); + const int expected1[18]={1,2,3,4,-3,5,6, 7,8,-5,9,10,-2,11, 12,13,-7,-10}; + CPPUNIT_ASSERT(std::equal(expected1,expected1+18,desc->getConstPointer())); + const int expected2[6]={0,4,7,10,14,18}; + CPPUNIT_ASSERT(std::equal(expected2,expected2+6,descIndx->getConstPointer())); + const int expected3[14]={0,1,3,5,6,8,9,11,12,13,15,16,17,18}; + CPPUNIT_ASSERT(std::equal(expected3,expected3+14,revDescIndx->getConstPointer())); + const int expected4[18]={0, 0,3, 0,1, 0, 1,2, 1, 2,4, 2, 3, 3,4, 3, 4, 4}; + CPPUNIT_ASSERT(std::equal(expected4,expected4+18,revDesc->getConstPointer())); + DataArrayInt *conn=mesh2->getNodalConnectivity(); + DataArrayInt *connIndex=mesh2->getNodalConnectivityIndex(); + const int expected5[14]={0,3,6,9,12,15,18,21,24,27,30,33,36,39}; + CPPUNIT_ASSERT(std::equal(expected5,expected5+14,connIndex->getConstPointer())); + const int expected6[39]={1, 0, 3, 1, 3, 4, 1, 4, 1, 1, 1, 0, 1, 4, 2, 1, 2, 1, 1, 4, 5, 1, 5, 2, 1, 6, 7, 1, 7, 4, 1, 3, 6, 1, 7, 8, 1, 8, 5}; + CPPUNIT_ASSERT(std::equal(expected6,expected6+39,conn->getConstPointer())); + // + desc->decrRef(); + descIndx->decrRef(); + revDesc->decrRef(); + revDescIndx->decrRef(); + mesh2->decrRef(); + mesh->decrRef(); +} + +void MEDCouplingBasicsTest4::testIntersect2DMeshesTmp1() +{ + MEDCouplingCMesh *m1c=MEDCouplingCMesh::New(); + DataArrayDouble *coordX=DataArrayDouble::New(); + const double arrX[4]={-1., 1., 2., 4.}; + coordX->alloc(4,1); + std::copy(arrX,arrX+4,coordX->getPointer()); + m1c->setCoordsAt(0,coordX); + DataArrayDouble *coordY=DataArrayDouble::New(); + const double arrY[4]={-2., 2., 4., 8.}; + coordY->alloc(4,1); + std::copy(arrY,arrY+4,coordY->getPointer()); + m1c->setCoordsAt(1,coordY); + MEDCouplingUMesh *m1=m1c->buildUnstructured(); + const int subPart1[3]={3,4,5}; + MEDCouplingUMesh *m1bis=static_cast<MEDCouplingUMesh *>(m1->buildPartOfMySelf(subPart1,subPart1+3,false)); + MEDCouplingUMesh *m2tmp=static_cast<MEDCouplingUMesh *>(m1->deepCpy()); + const int subPart2[3]={0,1,2}; + MEDCouplingUMesh *m2=static_cast<MEDCouplingUMesh *>(m2tmp->buildPartOfMySelf(subPart2,subPart2+3,false)); + const double vec[2]={0.5,0.5}; + m2->translate(vec); + // End of construction of input meshes m1bis and m2 -> start of specific part of the test + DataArrayInt *d1=0,*d2=0; + MEDCouplingUMesh *m3=MEDCouplingUMesh::Intersect2DMeshes(m1bis,m2,1e-10,d1,d2); + const int expected1[8]={0,0,1,1,1,2,2,2}; + const int expected2[8]={0,-1,0,1,-1,1,2,-1}; + CPPUNIT_ASSERT_EQUAL(8,d1->getNumberOfTuples()); + CPPUNIT_ASSERT_EQUAL(8,d2->getNumberOfTuples()); + CPPUNIT_ASSERT_EQUAL(8,m3->getNumberOfCells()); + CPPUNIT_ASSERT_EQUAL(22,m3->getNumberOfNodes()); + CPPUNIT_ASSERT_EQUAL(2,m3->getSpaceDimension()); + CPPUNIT_ASSERT(std::equal(expected1,expected1+8,d1->getConstPointer())); + CPPUNIT_ASSERT(std::equal(expected2,expected2+8,d2->getConstPointer())); + const int expected3[44]={5,17,1,16,12,5,16,0,4,5,17,12,5,18,1,17,13,5,19,2,18,13,5,17,5,6,19,13,5,20,2,19,14,5,21,3,20,14,5,19,6,7,21,14}; + const int expected4[9]={0,5,12,17,22,28,33,38,44}; + const double expected5[44]={-1.0,2.0,1.0,2.0,2.0,2.0,4.0,2.0,-1.0,4.0,1.0,4.0,2.0,4.0,4.0,4.0,-0.5,-1.5,1.5,-1.5,2.5,-1.5,4.5,-1.5,-0.5,2.5,1.5,2.5,2.5,2.5,4.5,2.5,-0.5,2.0,1.0,2.5,1.5,2.0,2.0,2.5,2.5,2.0,4.0,2.5}; + CPPUNIT_ASSERT_EQUAL(44,m3->getNodalConnectivity()->getNumberOfTuples()); + CPPUNIT_ASSERT_EQUAL(9,m3->getNodalConnectivityIndex()->getNumberOfTuples()); + CPPUNIT_ASSERT(std::equal(expected3,expected3+44,m3->getNodalConnectivity()->getConstPointer())); + CPPUNIT_ASSERT(std::equal(expected4,expected4+9,m3->getNodalConnectivityIndex()->getConstPointer())); + for(int i=0;i<44;i++) + CPPUNIT_ASSERT_DOUBLES_EQUAL(expected5[i],m3->getCoords()->getIJ(0,i),1e-12); + d1->decrRef(); + d2->decrRef(); + m3->decrRef(); + // + m2->decrRef(); + m2tmp->decrRef(); + m1bis->decrRef(); + m1->decrRef(); + coordX->decrRef(); + coordY->decrRef(); + m1c->decrRef(); +} + +void MEDCouplingBasicsTest4::testFindNodesOnLine1() +{ + MEDCouplingUMesh *mesh=build2DTargetMesh_1(); + const double pt[2]={-0.3,-0.3}; + const double pt2[3]={0.,0.,0.}; + const double pt3[3]={-0.3,0.,0.}; + const double vec[2]={0.,1.}; + const double vec2[3]={1.,0.,0.}; + const double vec3[3]={0.,1.,1.}; + const int expected1[3]={0,3,6}; + std::vector<int> res; + mesh->findNodesOnLine(pt,vec,1e-12,res); + CPPUNIT_ASSERT_EQUAL(3,(int)res.size()); + CPPUNIT_ASSERT(std::equal(expected1,expected1+3,res.begin())); + res.clear(); + // + mesh->changeSpaceDimension(3); + mesh->rotate(pt2,vec2,M_PI/4.); + mesh->findNodesOnLine(pt3,vec3,1e-12,res); + CPPUNIT_ASSERT_EQUAL(3,(int)res.size()); + CPPUNIT_ASSERT(std::equal(expected1,expected1+3,res.begin())); + // + mesh->decrRef(); +} + +void MEDCouplingBasicsTest4::testIntersect2DMeshesTmp2() +{ + MEDCouplingCMesh *m1c=MEDCouplingCMesh::New(); + DataArrayDouble *coordsX1=DataArrayDouble::New(); + const double arrX1[4]={ 0., 1., 1.5, 2. }; + coordsX1->alloc(4,1); + std::copy(arrX1,arrX1+4,coordsX1->getPointer()); + m1c->setCoordsAt(0,coordsX1); + DataArrayDouble *coordsY1=DataArrayDouble::New(); + const double arrY1[3]={ 0., 1.5, 3.}; + coordsY1->alloc(3,1); + std::copy(arrY1,arrY1+3,coordsY1->getPointer()); + m1c->setCoordsAt(1,coordsY1); + MEDCouplingUMesh *m1=m1c->buildUnstructured(); + // + MEDCouplingCMesh *m2c=MEDCouplingCMesh::New(); + DataArrayDouble *coordsX2=DataArrayDouble::New(); + const double arrX2[3]={ 0., 1., 2. }; + coordsX2->alloc(3,1); + std::copy(arrX2,arrX2+3,coordsX2->getPointer()); + m2c->setCoordsAt(0,coordsX2); + DataArrayDouble *coordsY2=DataArrayDouble::New(); + coordsY2->alloc(3,1); + const double arrY2[3]={ 0., 1., 3.}; + std::copy(arrY2,arrY2+3,coordsY2->getPointer()); + m2c->setCoordsAt(1,coordsY2); + MEDCouplingUMesh *m2=m2c->buildUnstructured(); + // + DataArrayInt *d1=0,*d2=0; + MEDCouplingUMesh *m3=MEDCouplingUMesh::Intersect2DMeshes(m1,m2,1e-10,d1,d2); + const int expected1[9]={0,0,1,1,2,2,3,4,5}; + const int expected2[9]={0,2,1,3,1,3,2,3,3}; + CPPUNIT_ASSERT_EQUAL(9,d1->getNumberOfTuples()); + CPPUNIT_ASSERT_EQUAL(9,d2->getNumberOfTuples()); + CPPUNIT_ASSERT_EQUAL(9,m3->getNumberOfCells()); + CPPUNIT_ASSERT_EQUAL(22,m3->getNumberOfNodes()); + CPPUNIT_ASSERT_EQUAL(2,m3->getSpaceDimension()); + CPPUNIT_ASSERT(std::equal(expected1,expected1+9,d1->getConstPointer())); + CPPUNIT_ASSERT(std::equal(expected2,expected2+9,d2->getConstPointer())); + const int expected3[45]={5,16,13,12,15,5,15,4,5,16,5,21,2,13,16,5,16,5,6,21,5,17,14,2,21,5,21,6,7,17,5,4,18,19,5,5,5,19,10,6,5,6,10,20,7}; + const int expected4[10]={0,5,10,15,20,25,30,35,40,45}; + const double expected5[44]={0.0,0.0,1.0,0.0,1.5,0.0,2.0,0.0,0.0,1.5,1.0,1.5,1.5,1.5,2.0,1.5,0.0,3.0,1.0,3.0,1.5,3.0,2.0,3.0,0.0,0.0,1.0,0.0,2.0,0.0,0.0,1.0,1.0,1.0,2.0,1.0,0.0,3.0,1.0,3.0,2.0,3.0,1.5,1.0}; + CPPUNIT_ASSERT_EQUAL(45,m3->getNodalConnectivity()->getNumberOfTuples()); + CPPUNIT_ASSERT_EQUAL(10,m3->getNodalConnectivityIndex()->getNumberOfTuples()); + CPPUNIT_ASSERT(std::equal(expected3,expected3+45,m3->getNodalConnectivity()->getConstPointer())); + CPPUNIT_ASSERT(std::equal(expected4,expected4+10,m3->getNodalConnectivityIndex()->getConstPointer())); + for(int i=0;i<44;i++) + CPPUNIT_ASSERT_DOUBLES_EQUAL(expected5[i],m3->getCoords()->getIJ(0,i),1e-12); + d1->decrRef(); + d2->decrRef(); + m3->decrRef(); + // + m1c->decrRef(); + coordsX1->decrRef(); + coordsY1->decrRef(); + m1->decrRef(); + m2c->decrRef(); + coordsX2->decrRef(); + coordsY2->decrRef(); + m2->decrRef(); +} + +void MEDCouplingBasicsTest4::testBuildPartOfMySelfSafe1() +{ + MEDCouplingUMesh *mesh=build2DTargetMesh_1(); + const int input1[4]={0,-1,4,2}; + const int input2[4]={0,4,5,4}; + CPPUNIT_ASSERT_THROW(mesh->buildPartOfMySelf(input1,input1+4,true),INTERP_KERNEL::Exception); + CPPUNIT_ASSERT_THROW(mesh->buildPartOfMySelf(input2,input2+4,true),INTERP_KERNEL::Exception); + mesh->decrRef(); +} + +void MEDCouplingBasicsTest4::testIntersect2DMeshesTmp3() +{ + double m1Coords[50]={0.,0.,1.,0.,1.5,0.,0.,1.,0.,1.5,-1.,0.,-1.5,0.,0.,-1,0.,-1.5,0.5,0.,1.25,0.,0.70710678118654757,0.70710678118654757,1.0606601717798214,1.0606601717798214,0.,0.5,0.,1.25,-0.70710678118654757,0.70710678118654757,-1.0606601717798214,1.0606601717798214,-0.5,0.,-1.25,0.,-0.70710678118654757,-0.70710678118654757,-1.0606601717798214,-1.0606601717798214,0.,-0.5,0.,-1.25,0.70710678118654757,-0.70710678118654757,1.0606601717798214,-1.0606601717798214}; + int m1Conn[56]={0,3,1,13,11,9, 3,4,2,1,14,12,10,11, 5,3,0,15,13,17, 6,4,3,5,16,14,15,18, 5,0,7,17,21,19, 6,5,7,8,18,19,22,20, 0,1,7,9,23,21, 1,2,8,7,10,24,22,23}; + MEDCouplingUMesh *m1=MEDCouplingUMesh::New(); + m1->setMeshDimension(2); + m1->allocateCells(8); + m1->insertNextCell(INTERP_KERNEL::NORM_TRI6,6,m1Conn); + m1->insertNextCell(INTERP_KERNEL::NORM_QUAD8,8,m1Conn+6); + m1->insertNextCell(INTERP_KERNEL::NORM_TRI6,6,m1Conn+14); + m1->insertNextCell(INTERP_KERNEL::NORM_QUAD8,8,m1Conn+20); + m1->insertNextCell(INTERP_KERNEL::NORM_TRI6,6,m1Conn+28); + m1->insertNextCell(INTERP_KERNEL::NORM_QUAD8,8,m1Conn+34); + m1->insertNextCell(INTERP_KERNEL::NORM_TRI6,6,m1Conn+42); + m1->insertNextCell(INTERP_KERNEL::NORM_QUAD8,8,m1Conn+48); + m1->finishInsertingCells(); + DataArrayDouble *myCoords1=DataArrayDouble::New(); + myCoords1->alloc(25,2); + std::copy(m1Coords,m1Coords+50,myCoords1->getPointer()); + m1->setCoords(myCoords1); + myCoords1->decrRef(); + // + double m2Coords[30]={0.,0.,1.1,0.,1.1,1.,0.,1.,1.7,0.,1.7,1.,-1.1,1.,-1.1,0.,-1.7,0.,-1.7,1.,-1.7,-1,-1.1,-1.,0.,-1.,1.1,-1,1.7,-1.}; + int m2Conn[32]={0,3,2,1, 1,2,5,4, 7,6,3,0, 8,9,6,7, 7,0,12,11, 8,7,11,10, 0,1,13,12, 1,4,14,13}; + MEDCouplingUMesh *m2=MEDCouplingUMesh::New(); + m2->setMeshDimension(2); + m2->allocateCells(8); + for(int i=0;i<8;i++) + m2->insertNextCell(INTERP_KERNEL::NORM_QUAD4,4,m2Conn+4*i); + m2->finishInsertingCells(); + DataArrayDouble *myCoords2=DataArrayDouble::New(); + myCoords2->alloc(15,2); + std::copy(m2Coords,m2Coords+30,myCoords2->getPointer()); + m2->setCoords(myCoords2); + myCoords2->decrRef(); + // + DataArrayInt *d1=0,*d2=0; + MEDCouplingUMesh *m3=MEDCouplingUMesh::Intersect2DMeshes(m1,m2,1e-10,d1,d2); + m3->unPolyze(); + const int expected1[16]={0,1,1,1,2,3,3,3,4,5,5,5,6,7,7,7}; + const int expected2[16]={0,0,1,-1,2,2,3,-1,4,4,5,-1,6,6,7,-1}; + CPPUNIT_ASSERT_EQUAL(16,d1->getNumberOfTuples()); + CPPUNIT_ASSERT_EQUAL(16,d2->getNumberOfTuples()); + CPPUNIT_ASSERT_EQUAL(16,m3->getNumberOfCells()); + CPPUNIT_ASSERT_EQUAL(104,m3->getNumberOfNodes()); + CPPUNIT_ASSERT_EQUAL(2,m3->getSpaceDimension()); + CPPUNIT_ASSERT(std::equal(expected1,expected1+16,d1->getConstPointer())); + CPPUNIT_ASSERT(std::equal(expected2,expected2+16,d2->getConstPointer())); + const int expected3[136]={6,28,1,25,44,45,46,8,26,1,28,27,47,48,49,50,8,40,2,26,27,51,52,53,54,8,28,4,40,27,55,56,57,58,6,28,25,5,59,60,61,8,28,5,32,31,62,63,64,65,8,32,6,41,31,66,67,68,69,8,41,4,28,31,70,71,72,73,6,25,37,5,74,75,76,8,32,5,37,36,77,78,79,80,8,42,6,32,36,81,82,83,84,8,37,8,42,36,85,86,87,88,6,1,37,25,89,90,91,8,37,1,26,38,92,93,94,95,8,26,2,43,38,96,97,98,99,8,43,8,37,38,100,101,102,103}; + const int expected4[17]={0,7,16,25,34,41,50,59,68,75,84,93,102,109,118,127,136}; + const double expected5[208]={0.,0.,1.,0.,1.5,0.,0.,1.,0.,1.5,-1.,0.,-1.5,0.,0.,-1.,0.,-1.5,0.5,0.,1.25,0.,0.7071067811865476,0.7071067811865476,1.0606601717798214,1.0606601717798214,0.,0.5,0.,1.25,-0.7071067811865476,0.7071067811865476,-1.0606601717798214,1.0606601717798214,-0.5,0.,-1.25,0.,-0.7071067811865476,-0.7071067811865476,-1.0606601717798214,-1.0606601717798214,0.,-0.5,0.,-1.25,0.7071067811865476,-0.7071067811865476,1.0606601717798214,-1.0606601717798214,0.,0.,1.1,0.,1.1,1.,0.,1.,1.7,0.,1.7,1.,-1.1,1.,-1.1,0.,-1.7,0.,-1.7,1.,-1.7,-1.,-1.1,-1.,0.,-1.,1.1,-1.,1.7,-1.,1.118033988749895,1.,-1.118033988749895,1.,-1.118033988749895,-1.,1.118033988749895,-1.,0.7071067811865477,0.7071067811865476,0.5,0.,0.,0.5,1.05,0.,0.7071067811865475,0.7071067811865477,0.55,1.,1.1,0.5,1.4012585384440737,0.535233134659635,1.3,0.,1.1,0.5,1.1090169943749475,1.,0.,1.25,0.6123724356957946,1.369306393762915,1.1090169943749475,1.,0.55,1.,0.,0.5,-0.5,0.,-0.7071067811865477,0.7071067811865476,-0.7071067811865475,0.7071067811865477,-1.05,0.,-1.1,0.5,-0.55,1.,-1.3,0.,-1.4012585384440737,0.5352331346596344,-1.1090169943749475,1.,-1.1,0.5,-0.6123724356957941,1.3693063937629155,0.,1.25,-0.55,1.,-1.1090169943749475,1.,0.,-0.5,-0.7071067811865475,-0.7071067811865477,-0.5,0.,-1.05,0.,-0.7071067811865478,-0.7071067811865475,-0.55,-1.,-1.1,-0.5,-1.4012585384440734,-0.5352331346596354,-1.3,0.,-1.1,-0.5,-1.1090169943749475,-1.,0.,-1.25,-0.6123724356957945,-1.369306393762915,-1.1090169943749475,-1.,-0.55,-1.,0.7071067811865475,-0.7071067811865477,0.,-0.5,0.5,0.,0.7071067811865477,-0.7071067811865475,1.05,0.,1.1,-0.5,0.55,-1.,1.3,0.,1.4012585384440737,-0.535233134659635,1.1090169943749475,-1.,1.1,-0.5,0.6123724356957946,-1.369306393762915,0.,-1.25,0.55,-1.,1.1090169943749475,-1.0}; + CPPUNIT_ASSERT_EQUAL(136,m3->getNodalConnectivity()->getNumberOfTuples()); + CPPUNIT_ASSERT_EQUAL(17,m3->getNodalConnectivityIndex()->getNumberOfTuples()); + CPPUNIT_ASSERT(std::equal(expected3,expected3+136,m3->getNodalConnectivity()->getConstPointer())); + CPPUNIT_ASSERT(std::equal(expected4,expected4+17,m3->getNodalConnectivityIndex()->getConstPointer())); + for(int i=0;i<208;i++) + CPPUNIT_ASSERT_DOUBLES_EQUAL(expected5[i],m3->getCoords()->getIJ(0,i),1e-12); + d1->decrRef(); + d2->decrRef(); + m3->decrRef(); + // + m1->decrRef(); + m2->decrRef(); +} diff --git a/src/medtool/src/MEDCoupling/Test/MEDCouplingBasicsTest4.hxx b/src/medtool/src/MEDCoupling/Test/MEDCouplingBasicsTest4.hxx new file mode 100644 index 000000000..3e8738255 --- /dev/null +++ b/src/medtool/src/MEDCoupling/Test/MEDCouplingBasicsTest4.hxx @@ -0,0 +1,162 @@ +// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 +// 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 __MEDCOUPLINGBASICSTEST4_HXX__ +#define __MEDCOUPLINGBASICSTEST4_HXX__ + +#include "MEDCouplingBasicsTest.hxx" + +#include <map> +#include <vector> + +namespace ParaMEDMEM +{ + class DataArrayDouble; + class MEDCouplingUMesh; + class MEDCouplingFieldDouble; + class MEDCouplingMultiFields; + + class MEDCouplingBasicsTest4 : public MEDCouplingBasicsTest + { + CPPUNIT_TEST_SUITE(MEDCouplingBasicsTest4); + CPPUNIT_TEST( testDescriptionInMeshTimeUnit1 ); + CPPUNIT_TEST( testMultiFields1 ); + CPPUNIT_TEST( testFieldOverTime1 ); + CPPUNIT_TEST( testDAICheckAndPreparePermutation1 ); + CPPUNIT_TEST( testDAIChangeSurjectiveFormat1 ); + CPPUNIT_TEST( testUMeshGetCellIdsLyingOnNodes1 ); + CPPUNIT_TEST( testUMeshFindCellIdsOnBoundary1 ); + CPPUNIT_TEST( testMeshSetTime1 ); + CPPUNIT_TEST( testApplyFuncTwo1 ); + CPPUNIT_TEST( testApplyFuncThree1 ); + CPPUNIT_TEST( testFillFromAnalyticTwo1 ); + CPPUNIT_TEST( testFillFromAnalyticThree1 ); + CPPUNIT_TEST( testDAUnitVar1 ); + CPPUNIT_TEST( testGaussCoordinates1 ); + CPPUNIT_TEST( testP2Localization1 ); + CPPUNIT_TEST( testP2Localization2 ); + CPPUNIT_TEST( testGetValueOn2 ); + CPPUNIT_TEST( testDAIGetIdsNotEqual1 ); + CPPUNIT_TEST( testDAIComputeOffsets1 ); + CPPUNIT_TEST( testUMeshHexagonPrism1 ); + CPPUNIT_TEST( testDADCheckIsMonotonic ); + CPPUNIT_TEST( testCheckCoherencyDeeper1 ); + CPPUNIT_TEST( testUnPolyze2 ); + CPPUNIT_TEST( testDACpyFrom1 ); + CPPUNIT_TEST( testDAITransformWithIndArr1 ); + CPPUNIT_TEST( testDAIBuildPermArrPerLevel1 ); + CPPUNIT_TEST( testDAIOperations1 ); + CPPUNIT_TEST( testEmulateMEDMEMBDC1 ); + CPPUNIT_TEST( testGetLevArrPerCellTypes1 ); + CPPUNIT_TEST( testSortCellsInMEDFileFrmt1 ); + CPPUNIT_TEST( testBuildPartAndReduceNodes1 ); + CPPUNIT_TEST( testDAITransformWithIndArrR1 ); + CPPUNIT_TEST( testDAISplitByValueRange1 ); + CPPUNIT_TEST( testUMeshSplitProfilePerType1 ); + CPPUNIT_TEST( testDAIBuildExplicitArrByRanges1 ); + CPPUNIT_TEST( testDAIComputeOffsets2 ); + CPPUNIT_TEST( testMergeField3 ); + CPPUNIT_TEST( testGetDistributionOfTypes1 ); + CPPUNIT_TEST( testNorm2_1 ); + CPPUNIT_TEST( testNormMax1 ); + CPPUNIT_TEST( testFindAndCorrectBadOriented3DExtrudedCells1 ); + CPPUNIT_TEST( testConvertExtrudedPolyhedra1 ); + CPPUNIT_TEST( testNonRegressionCopyTinyStrings ); + CPPUNIT_TEST( testDaDSetPartOfValuesAdv1 ); + CPPUNIT_TEST( testUMeshBuildSetInstanceFromThis1 ); + CPPUNIT_TEST( testUMeshMergeMeshesCVW1 ); + CPPUNIT_TEST( testDADFindCommonTuples1 ); + CPPUNIT_TEST( testDABack1 ); + CPPUNIT_TEST( testDADGetDifferentValues1 ); + CPPUNIT_TEST( testDAIBuildOld2NewArrayFromSurjectiveFormat2 ); + CPPUNIT_TEST( testDADIReverse1 ); + CPPUNIT_TEST( testGetNodeIdsInUse1 ); + CPPUNIT_TEST( testBuildDescendingConnec2 ); + CPPUNIT_TEST( testIntersect2DMeshesTmp1 ); + CPPUNIT_TEST( testFindNodesOnLine1 ); + CPPUNIT_TEST( testIntersect2DMeshesTmp2 ); + CPPUNIT_TEST( testBuildPartOfMySelfSafe1 ); + CPPUNIT_TEST( testIntersect2DMeshesTmp3 ); + CPPUNIT_TEST_SUITE_END(); + public: + void testDescriptionInMeshTimeUnit1(); + void testMultiFields1(); + void testFieldOverTime1(); + void testDAICheckAndPreparePermutation1(); + void testDAIChangeSurjectiveFormat1(); + void testUMeshGetCellIdsLyingOnNodes1(); + void testUMeshFindCellIdsOnBoundary1(); + void testMeshSetTime1(); + void testApplyFuncTwo1(); + void testApplyFuncThree1(); + void testFillFromAnalyticTwo1(); + void testFillFromAnalyticThree1(); + void testDAUnitVar1(); + void testGaussCoordinates1(); + void testQ1Localization1(); + void testP2Localization1(); + void testP2Localization2(); + void testGetValueOn2(); + void testDAIGetIdsNotEqual1(); + void testDAIComputeOffsets1(); + void testUMeshHexagonPrism1(); + void testDADCheckIsMonotonic(); + void testCheckCoherencyDeeper1(); + void testUnPolyze2(); + void testDACpyFrom1(); + void testDAITransformWithIndArr1(); + void testDAIBuildPermArrPerLevel1(); + void testDAIOperations1(); + void testEmulateMEDMEMBDC1(); + void testGetLevArrPerCellTypes1(); + void testSortCellsInMEDFileFrmt1(); + void testBuildPartAndReduceNodes1(); + void testDAITransformWithIndArrR1(); + void testDAISplitByValueRange1(); + void testUMeshSplitProfilePerType1(); + void testDAIBuildExplicitArrByRanges1(); + void testDAIComputeOffsets2(); + void testMergeField3(); + void testGetDistributionOfTypes1(); + void testNorm2_1(); + void testNormMax1(); + void testFindAndCorrectBadOriented3DExtrudedCells1(); + void testConvertExtrudedPolyhedra1(); + void testNonRegressionCopyTinyStrings(); + void testDaDSetPartOfValuesAdv1(); + void testUMeshBuildSetInstanceFromThis1(); + void testUMeshMergeMeshesCVW1(); + void testChangeUnderlyingMeshWithCMesh1(); + void testDADFindCommonTuples1(); + void testDABack1(); + void testDADGetDifferentValues1(); + void testDAIBuildOld2NewArrayFromSurjectiveFormat2(); + void testDADIReverse1(); + void testGetNodeIdsInUse1(); + void testBuildDescendingConnec2(); + void testIntersect2DMeshesTmp1(); + void testFindNodesOnLine1(); + void testIntersect2DMeshesTmp2(); + void testBuildPartOfMySelfSafe1(); + void testIntersect2DMeshesTmp3(); + }; +} + +#endif diff --git a/src/medtool/src/MEDCoupling/Test/MEDCouplingBasicsTest5.cxx b/src/medtool/src/MEDCoupling/Test/MEDCouplingBasicsTest5.cxx new file mode 100644 index 000000000..0dc0e8c01 --- /dev/null +++ b/src/medtool/src/MEDCoupling/Test/MEDCouplingBasicsTest5.cxx @@ -0,0 +1,2059 @@ +// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 +// 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 "MEDCouplingBasicsTest5.hxx" +#include "MEDCouplingUMesh.hxx" +#include "MEDCouplingCMesh.hxx" +#include "MEDCouplingExtrudedMesh.hxx" +#include "MEDCouplingFieldDouble.hxx" +#include "MEDCouplingMemArray.hxx" +#include "MEDCouplingGaussLocalization.hxx" +#include "MEDCouplingMultiFields.hxx" +#include "MEDCouplingFieldOverTime.hxx" + +#include <cmath> +#include <functional> +#include <iterator> + +using namespace ParaMEDMEM; + +void MEDCouplingBasicsTest5::testUMeshTessellate2D1() +{ + double m1Coords[50]={0.,0.,1.,0.,1.5,0.,0.,1.,0.,1.5,-1.,0.,-1.5,0.,0.,-1,0.,-1.5,0.5,0.,1.25,0.,0.70710678118654757,0.70710678118654757,1.0606601717798214,1.0606601717798214,0.,0.5,0.,1.25,-0.70710678118654757,0.70710678118654757,-1.0606601717798214,1.0606601717798214,-0.5,0.,-1.25,0.,-0.70710678118654757,-0.70710678118654757,-1.0606601717798214,-1.0606601717798214,0.,-0.5,0.,-1.25,0.70710678118654757,-0.70710678118654757,1.0606601717798214,-1.0606601717798214}; + int m1Conn[56]={0,3,1,13,11,9, 3,4,2,1,14,12,10,11, 5,3,0,15,13,17, 6,4,3,5,16,14,15,18, 5,0,7,17,21,19, 6,5,7,8,18,19,22,20, 0,1,7,9,23,21, 1,2,8,7,10,24,22,23}; + MEDCouplingUMesh *m1=MEDCouplingUMesh::New(); + m1->setMeshDimension(2); + m1->allocateCells(8); + m1->insertNextCell(INTERP_KERNEL::NORM_TRI6,6,m1Conn); + m1->insertNextCell(INTERP_KERNEL::NORM_QUAD8,8,m1Conn+6); + m1->insertNextCell(INTERP_KERNEL::NORM_TRI6,6,m1Conn+14); + m1->insertNextCell(INTERP_KERNEL::NORM_QUAD8,8,m1Conn+20); + m1->insertNextCell(INTERP_KERNEL::NORM_TRI6,6,m1Conn+28); + m1->insertNextCell(INTERP_KERNEL::NORM_QUAD8,8,m1Conn+34); + m1->insertNextCell(INTERP_KERNEL::NORM_TRI6,6,m1Conn+42); + m1->insertNextCell(INTERP_KERNEL::NORM_QUAD8,8,m1Conn+48); + m1->finishInsertingCells(); + DataArrayDouble *myCoords1=DataArrayDouble::New(); + myCoords1->alloc(25,2); + std::copy(m1Coords,m1Coords+50,myCoords1->getPointer()); + m1->setCoords(myCoords1); + myCoords1->decrRef(); + // + MEDCouplingUMesh *m11=static_cast<MEDCouplingUMesh *>(m1->deepCpy()); + m11->tessellate2D(1.); + CPPUNIT_ASSERT(m11->getCoords()->isEqual(*m11->getCoords(),1e-12)); + const int expected1[48]={5,0,3,11,1,5,3,4,12,2,1,11,5,5,15,3,0,5,6,16,4,3,15,5,5,5,0,7,19,5,6,5,19,7,8,20,5,0,1,23,7,5,1,2,24,8,7,23}; + const int expected2[9]={0,5,12,17,24,29,36,41,48}; + CPPUNIT_ASSERT_EQUAL(48,m11->getNodalConnectivity()->getNumberOfTuples()); + CPPUNIT_ASSERT_EQUAL(9,m11->getNodalConnectivityIndex()->getNumberOfTuples()); + CPPUNIT_ASSERT(std::equal(expected1,expected1+48,m11->getNodalConnectivity()->getConstPointer())); + CPPUNIT_ASSERT(std::equal(expected2,expected2+9,m11->getNodalConnectivityIndex()->getConstPointer())); + m11->decrRef(); + // + MEDCouplingUMesh *m12=static_cast<MEDCouplingUMesh *>(m1->deepCpy()); + m12->tessellate2D(0.5); + CPPUNIT_ASSERT_EQUAL(41,m12->getNumberOfNodes()); + const int expected3[60]={5,0,3,25,26,1,5,3,4,27,28,2,1,26,25,5,5,29,30,3,0,5,6,31,32,4,3,30,29,5,5,5,0,7,33,34,5,6,5,34,33,7,8,35,36,5,0,1,37,38,7,5,1,2,39,40,8,7,38,37}; + const int expected4[9]={0,6,15,21,30,36,45,51,60}; + const double expected5[82]={0.,0.,1.,0.,1.5,0.,0.,1.,0.,1.5,-1.,0.,-1.5,0.,0.,-1.,0.,-1.5,0.5,0.,1.25,0.,0.7071067811865476,0.7071067811865476,1.0606601717798214,1.0606601717798214,0.,0.5,0.,1.25,-0.7071067811865476,0.7071067811865476,-1.0606601717798214,1.0606601717798214,-0.5,0.,-1.25,0.,-0.7071067811865476,-0.7071067811865476,-1.0606601717798214,-1.0606601717798214,0.,-0.5,0.,-1.25,0.7071067811865476,-0.7071067811865476,1.0606601717798214,-1.0606601717798214,0.479425538604203,0.8775825618903728,0.8414709848078964,0.54030230586814,0.7191383079063044,1.3163738428355591,1.2622064772118446,0.8104534588022099,-0.877582561890373,0.4794255386042027,-0.5403023058681399,0.8414709848078964,-1.3163738428355596,0.7191383079063038,-0.8104534588022098,1.2622064772118446,-0.4794255386042031,-0.8775825618903728,-0.8414709848078965,-0.5403023058681399,-0.7191383079063045,-1.3163738428355591,-1.2622064772118449,-0.8104534588022098,0.8775825618903729,-0.47942553860420295,0.54030230586814,-0.8414709848078964,1.3163738428355594,-0.7191383079063043,0.8104534588022099,-1.2622064772118446}; + for(int i=0;i<82;i++) + CPPUNIT_ASSERT_DOUBLES_EQUAL(expected5[i],m12->getCoords()->getIJ(0,i),1e-12); + CPPUNIT_ASSERT_EQUAL(60,m12->getNodalConnectivity()->getNumberOfTuples()); + CPPUNIT_ASSERT_EQUAL(9,m12->getNodalConnectivityIndex()->getNumberOfTuples()); + CPPUNIT_ASSERT(std::equal(expected3,expected3+60,m12->getNodalConnectivity()->getConstPointer())); + CPPUNIT_ASSERT(std::equal(expected4,expected4+9,m12->getNodalConnectivityIndex()->getConstPointer())); + m12->decrRef(); + // + m1->decrRef(); +} + +void MEDCouplingBasicsTest5::testUMeshTessellate2DCurve1() +{ + // A quarter of circle: + double mcoords[6] = {0.4,0.0, 0.0,-0.4, 0.283,-0.283}; + int mconnec[3] = {0,1,2}; + + MEDCouplingUMesh *m1 = MEDCouplingUMesh::New(); + m1->setMeshDimension(1); + m1->allocateCells(1); + m1->insertNextCell(INTERP_KERNEL::NORM_SEG3, 3, mconnec); + + DataArrayDouble *myCoords = DataArrayDouble::New(); + myCoords->alloc(3,2); + std::copy(mcoords,mcoords+6,myCoords->getPointer()); + m1->setCoords(myCoords); + myCoords->decrRef(); + + MEDCouplingUMesh *m2 = static_cast<MEDCouplingUMesh *>(m1->deepCpy()); + m2->tessellate2DCurve(0.1); + CPPUNIT_ASSERT_NO_THROW(m2->checkCoherency1(0.0)); // eps param not used + m1->decrRef(); + m2->decrRef(); +} + +/*! + * idem MEDCouplingBasicsTest4::testIntersect2DMeshesTmp3 except that m1 and m2 are permuted on call to MEDCouplingUMesh::Intersect2DMeshes + */ +void MEDCouplingBasicsTest5::testIntersect2DMeshesTmp4() +{ + double m1Coords[50]={0.,0.,1.,0.,1.5,0.,0.,1.,0.,1.5,-1.,0.,-1.5,0.,0.,-1,0.,-1.5,0.5,0.,1.25,0.,0.70710678118654757,0.70710678118654757,1.0606601717798214,1.0606601717798214,0.,0.5,0.,1.25,-0.70710678118654757,0.70710678118654757,-1.0606601717798214,1.0606601717798214,-0.5,0.,-1.25,0.,-0.70710678118654757,-0.70710678118654757,-1.0606601717798214,-1.0606601717798214,0.,-0.5,0.,-1.25,0.70710678118654757,-0.70710678118654757,1.0606601717798214,-1.0606601717798214}; + int m1Conn[56]={0,3,1,13,11,9, 3,4,2,1,14,12,10,11, 5,3,0,15,13,17, 6,4,3,5,16,14,15,18, 5,0,7,17,21,19, 6,5,7,8,18,19,22,20, 0,1,7,9,23,21, 1,2,8,7,10,24,22,23}; + MEDCouplingUMesh *m1=MEDCouplingUMesh::New(); + m1->setMeshDimension(2); + m1->allocateCells(8); + m1->insertNextCell(INTERP_KERNEL::NORM_TRI6,6,m1Conn); + m1->insertNextCell(INTERP_KERNEL::NORM_QUAD8,8,m1Conn+6); + m1->insertNextCell(INTERP_KERNEL::NORM_TRI6,6,m1Conn+14); + m1->insertNextCell(INTERP_KERNEL::NORM_QUAD8,8,m1Conn+20); + m1->insertNextCell(INTERP_KERNEL::NORM_TRI6,6,m1Conn+28); + m1->insertNextCell(INTERP_KERNEL::NORM_QUAD8,8,m1Conn+34); + m1->insertNextCell(INTERP_KERNEL::NORM_TRI6,6,m1Conn+42); + m1->insertNextCell(INTERP_KERNEL::NORM_QUAD8,8,m1Conn+48); + m1->finishInsertingCells(); + DataArrayDouble *myCoords1=DataArrayDouble::New(); + myCoords1->alloc(25,2); + std::copy(m1Coords,m1Coords+50,myCoords1->getPointer()); + m1->setCoords(myCoords1); + myCoords1->decrRef(); + // + double m2Coords[30]={0.,0.,1.1,0.,1.1,1.,0.,1.,1.7,0.,1.7,1.,-1.1,1.,-1.1,0.,-1.7,0.,-1.7,1.,-1.7,-1,-1.1,-1.,0.,-1.,1.1,-1,1.7,-1.}; + int m2Conn[32]={0,3,2,1, 1,2,5,4, 7,6,3,0, 8,9,6,7, 7,0,12,11, 8,7,11,10, 0,1,13,12, 1,4,14,13}; + MEDCouplingUMesh *m2=MEDCouplingUMesh::New(); + m2->setMeshDimension(2); + m2->allocateCells(8); + for(int i=0;i<8;i++) + m2->insertNextCell(INTERP_KERNEL::NORM_QUAD4,4,m2Conn+4*i); + m2->finishInsertingCells(); + DataArrayDouble *myCoords2=DataArrayDouble::New(); + myCoords2->alloc(15,2); + std::copy(m2Coords,m2Coords+30,myCoords2->getPointer()); + m2->setCoords(myCoords2); + myCoords2->decrRef(); + // + DataArrayInt *d1=0,*d2=0; + MEDCouplingUMesh *m3=MEDCouplingUMesh::Intersect2DMeshes(m2,m1,1e-10,d1,d2); + m3->unPolyze(); + const int expected1[16]={0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7}; + const int expected2[16]={0,1,1,-1,2,3,3,-1,4,5,5,-1,6,7,7,-1}; + CPPUNIT_ASSERT_EQUAL(16,d1->getNumberOfTuples()); + CPPUNIT_ASSERT_EQUAL(16,d2->getNumberOfTuples()); + CPPUNIT_ASSERT_EQUAL(16,m3->getNumberOfCells()); + CPPUNIT_ASSERT_EQUAL(104,m3->getNumberOfNodes()); + CPPUNIT_ASSERT_EQUAL(2,m3->getSpaceDimension()); + CPPUNIT_ASSERT(std::equal(expected1,expected1+16,d1->getConstPointer())); + CPPUNIT_ASSERT(std::equal(expected2,expected2+16,d2->getConstPointer())); + const int expected3[136]={6,16,15,18,44,45,46,8,18,2,1,16,47,48,49,50,8,17,1,2,40,51,52,53,54,8,40,5,4,17,55,56,57,58,6,18,15,20,59,60,61,8,20,7,6,18,62,63,64,65,8,41,6,7,21,66,67,68,69,8,21,8,9,41,70,71,72,73,6,20,15,22,74,75,76,8,22,11,7,20,77,78,79,80,8,21,7,11,42,81,82,83,84,8,42,10,8,21,85,86,87,88,6,22,15,16,89,90,91,8,16,1,13,22,92,93,94,95,8,43,13,1,17,96,97,98,99,8,17,4,14,43,100,101,102,103}; + const int expected4[17]={0,7,16,25,34,41,50,59,68,75,84,93,102,109,118,127,136}; + const double expected5[208]={0.,0.,1.1, 0.,1.1,1.,0.,1.,1.7,0.,1.7,1.,-1.1,1.,-1.1,0.,-1.7,0.,-1.7,1.,-1.7,-1.,-1.1,-1.,0.,-1.,1.1,-1.,1.7,-1.,0.,0.,1.,0.,1.5,0.,0.,1.,0.,1.5,-1.,0.,-1.5,0.,0.,-1.,0.,-1.5,0.5,0.,1.25,0.,0.7071067811865476,0.7071067811865476,1.0606601717798214,1.0606601717798214,0.,0.5,0.,1.25,-0.7071067811865476,0.7071067811865476,-1.0606601717798214,1.0606601717798214,-0.5,0.,-1.25,0.,-0.7071067811865476,-0.7071067811865476,-1.0606601717798214,-1.0606601717798214,0.,-0.5,0.,-1.25,0.7071067811865476,-0.7071067811865476,1.0606601717798214,-1.0606601717798214,1.1180339887498951,1.,-1.1180339887498951,1.,-1.1180339887498951,-1.,1.1180339887498951,-1.,0.5,0.,0.,0.5,0.7071067811865477,0.7071067811865476,0.55,1.,1.1,0.5,1.05,0.,0.7071067811865477,0.7071067811865475,1.3,0.,1.1,0.5,1.1090169943749475,1.,1.4012585384440737,0.535233134659635,1.4090169943749475,1.,1.7,0.5,1.6,0.,1.4012585384440737,0.535233134659635,0.,0.5,-0.5,0.,-0.7071067811865477,0.7071067811865476,-1.05,0.,-1.1,0.5,-0.55,1.,-0.7071067811865478,0.7071067811865475,-1.1090169943749475,1.,-1.1,0.5,-1.3,0.,-1.4012585384440737,0.5352331346596344,-1.6,0.,-1.7,0.5,-1.4090169943749475,1.,-1.4012585384440737,0.5352331346596344,-0.5,0.,0.,-0.5,-0.7071067811865475,-0.7071067811865477,-0.55,-1.,-1.1,-0.5,-1.05,0.,-0.7071067811865475,-0.7071067811865477,-1.3,0.,-1.1,-0.5,-1.1090169943749475,-1.,-1.4012585384440734,-0.5352331346596354,-1.4090169943749475,-1.,-1.7,-0.5,-1.6,0.,-1.4012585384440732,-0.5352331346596354,0.,-0.5,0.5,0.,0.7071067811865475,-0.7071067811865477,1.05,0.,1.1,-0.5,0.55,-1.,0.7071067811865475,-0.7071067811865477,1.1090169943749475,-1.,1.1,-0.5,1.3,0.,1.4012585384440737,-0.535233134659635,1.6,0.,1.7,-0.5,1.4090169943749475,-1.,1.4012585384440737,-0.535233134659635}; + CPPUNIT_ASSERT_EQUAL(136,m3->getNodalConnectivity()->getNumberOfTuples()); + CPPUNIT_ASSERT_EQUAL(17,m3->getNodalConnectivityIndex()->getNumberOfTuples()); + CPPUNIT_ASSERT(std::equal(expected3,expected3+136,m3->getNodalConnectivity()->getConstPointer())); + CPPUNIT_ASSERT(std::equal(expected4,expected4+17,m3->getNodalConnectivityIndex()->getConstPointer())); + for(int i=0;i<208;i++) + CPPUNIT_ASSERT_DOUBLES_EQUAL(expected5[i],m3->getCoords()->getIJ(0,i),1e-12); + d1->decrRef(); + d2->decrRef(); + m3->decrRef(); + // + m1->decrRef(); + m2->decrRef(); +} + +void MEDCouplingBasicsTest5::testGetCellIdsCrossingPlane1() +{ + MEDCouplingUMesh *mesh2D=0; + MEDCouplingUMesh *mesh3D=build3DExtrudedUMesh_1(mesh2D); + const double vec[3]={-0.07,1.,0.07}; + const double origin[3]={1.524,1.4552,1.74768}; + DataArrayInt *ids1=mesh3D->getCellIdsCrossingPlane(origin,vec,1e-10); + CPPUNIT_ASSERT_EQUAL(9,ids1->getNumberOfTuples()); + const int expected1[9]={1,3,4,7,9,10,13,15,16}; + CPPUNIT_ASSERT(std::equal(expected1,expected1+9,ids1->getConstPointer())); + const double vec2[3]={0.,0.,1.}; + DataArrayInt *ids2=mesh3D->getCellIdsCrossingPlane(origin,vec2,1e-10); + const int expected2[6]={6,7,8,9,10,11}; + CPPUNIT_ASSERT_EQUAL(6,ids2->getNumberOfTuples()); + CPPUNIT_ASSERT(std::equal(expected2,expected2+6,ids2->getConstPointer())); + ids1->decrRef(); + ids2->decrRef(); + mesh3D->decrRef(); + mesh2D->decrRef(); +} + +void MEDCouplingBasicsTest5::testBuildSlice3D1() +{ + MEDCouplingUMesh *mesh2D=0; + MEDCouplingUMesh *mesh3D=build3DExtrudedUMesh_1(mesh2D); + mesh2D->decrRef(); + // First slice in the middle of 3D cells + const double vec1[3]={-0.07,1.,0.07}; + const double origin1[3]={1.524,1.4552,1.74768}; + DataArrayInt *ids=0; + MEDCouplingUMesh *slice1=mesh3D->buildSlice3D(origin1,vec1,1e-10,ids); + const int expected1[9]={1,3,4,7,9,10,13,15,16}; + const int expected2[47]={5,42,41,40,43,44,5,42,46,45,41,5,44,43,40,47,48,5,49,42,44,50,5,49,51,46,42,5,50,44,48,52,5,53,49,50,54,5,53,55,51,49,5,54,50,52,56}; + const int expected3[10]={0,6,11,17,22,27,32,37,42,47}; + const double expected4[171]={1.,1.,0.,1.,1.25,0.,1.,1.5,0.,2.,1.,0.,1.,2.,0.,0.,2.,0.,3.,1.,0.,3.,2.,0.,0.,1.,0.,2.,2.,0.,1.,1.,1.,1.,1.25,1.,1.,1.5,1.,2.,1.,1.,1.,2.,1.,0.,2.,1.,3.,1.,1.,3.,2.,1.,0.,1.,1.,2.,2.,1.,1.,1.,2.,1.,1.25,2.,1.,1.5,2.,2.,1.,2.,1.,2.,2.,0.,2.,2.,3.,1.,2.,3.,2.,2.,0.,1.,2.,2.,2.,2.,1.,1.,3.,1.,1.25,3.,1.,1.5,3.,2.,1.,3.,1.,2.,3.,0.,2.,3.,3.,1.,3.,3.,2.,3.,0.,1.,3.,2.,2.,3.,1.,1.5408576,0.,2.,1.6108576000000001,0.,2.,1.5408576,1.,1.,1.5,0.5836800000000008,1.,1.4708576,1.,3.,1.6808576,0.,3.,1.6108576000000001,1.,0.,1.4708576,0.,0.,1.4008576,1.,2.,1.4708576,2.,1.,1.4008576000000001,2.,3.,1.5408575999999998,2.,0.,1.3308575999999999,2.,2.,1.4008576,3.,1.,1.3308576,3.,3.,1.4708576,3.,0.,1.2608576,3.}; + CPPUNIT_ASSERT_EQUAL(2,slice1->getMeshDimension()); + CPPUNIT_ASSERT_EQUAL(3,slice1->getSpaceDimension()); + CPPUNIT_ASSERT_EQUAL(57,slice1->getNumberOfNodes()); + CPPUNIT_ASSERT_EQUAL(9,slice1->getNumberOfCells()); + CPPUNIT_ASSERT_EQUAL(9,ids->getNumberOfTuples()); + CPPUNIT_ASSERT_EQUAL(47,slice1->getNodalConnectivity()->getNumberOfTuples()); + CPPUNIT_ASSERT_EQUAL(10,slice1->getNodalConnectivityIndex()->getNumberOfTuples()); + CPPUNIT_ASSERT(std::equal(expected1,expected1+9,ids->getConstPointer())); + CPPUNIT_ASSERT(std::equal(expected2,expected2+47,slice1->getNodalConnectivity()->getConstPointer())); + CPPUNIT_ASSERT(std::equal(expected3,expected3+10,slice1->getNodalConnectivityIndex()->getConstPointer())); + for(int i=0;i<171;i++) + CPPUNIT_ASSERT_DOUBLES_EQUAL(expected4[i],slice1->getCoords()->getIJ(0,i),1e-12); + ids->decrRef(); + slice1->decrRef(); + // 2nd slice based on already existing nodes of mesh3D. + const double vec2[3]={0.,3.,1.}; + const double origin2[3]={2.5,1.,3.}; + slice1=mesh3D->buildSlice3D(origin2,vec2,1e-10,ids); + const int expected5[49]={5,50,10,4,51,5,50,52,7,10,5,51,4,5,53,5,54,50,51,55,56,5,54,57,52,50,5,56,55,51,53,58,5,38,59,56,54,43,5,54,57,46,43,5,38,59,56,58,48}; + const int expected6[10]={0,5,10,15,21,26,32,38,43,49}; + const double expected7[180]={1.,1.,0.,1.,1.25,0.,1.,1.5,0.,2.,1.,0.,1.,2.,0.,0.,2.,0.,3.,1.,0.,3.,2.,0.,0.,1.,0.,1.,3.,0.,2.,2.,0.,2.,3.,0.,1.,1.,1.,1.,1.25,1.,1.,1.5,1.,2.,1.,1.,1.,2.,1.,0.,2.,1.,3.,1.,1.,3.,2.,1.,0.,1.,1.,1.,3.,1.,2.,2.,1.,2.,3.,1.,0.,0.,2.,1.,1.,2.,1.,1.25,2.,1.,0.,2.,1.,1.5,2.,2.,0.,2.,2.,1.,2.,1.,2.,2.,0.,2.,2.,3.,1.,2.,3.,2.,2.,0.,1.,2.,2.,2.,2.,0.,0.,3.,1.,1.,3.,1.,1.25,3.,1.,0.,3.,1.,1.5,3.,2.,0.,3.,2.,1.,3.,1.,2.,3.,0.,2.,3.,3.,1.,3.,3.,2.,3.,0.,1.,3.,2.,2.,3.,2.,1.6666666666666667,1.,1.,1.6666666666666667,1.,3.,1.6666666666666667,1.,0.,1.6666666666666667,1.,2.,1.3333333333333335,2.,1.,1.5,1.5,1.,1.3333333333333333,2.,3.,1.3333333333333335,2.,0.,1.3333333333333335,2.,1.,1.25,2.25}; + CPPUNIT_ASSERT_EQUAL(2,slice1->getMeshDimension()); + CPPUNIT_ASSERT_EQUAL(3,slice1->getSpaceDimension()); + CPPUNIT_ASSERT_EQUAL(60,slice1->getNumberOfNodes()); + CPPUNIT_ASSERT_EQUAL(9,slice1->getNumberOfCells()); + CPPUNIT_ASSERT_EQUAL(9,ids->getNumberOfTuples()); + CPPUNIT_ASSERT_EQUAL(49,slice1->getNodalConnectivity()->getNumberOfTuples()); + CPPUNIT_ASSERT_EQUAL(10,slice1->getNodalConnectivityIndex()->getNumberOfTuples()); + CPPUNIT_ASSERT(std::equal(expected1,expected1+9,ids->getConstPointer())); + CPPUNIT_ASSERT(std::equal(expected5,expected5+49,slice1->getNodalConnectivity()->getConstPointer())); + CPPUNIT_ASSERT(std::equal(expected6,expected6+10,slice1->getNodalConnectivityIndex()->getConstPointer())); + for(int i=0;i<180;i++) + CPPUNIT_ASSERT_DOUBLES_EQUAL(expected7[i],slice1->getCoords()->getIJ(0,i),1e-12); + ids->decrRef(); + slice1->decrRef(); + // 3rd slice based on shared face of mesh3D. + const double vec3[3]={0.,0.,1.}; + const double origin3[3]={2.5,1.,2.}; + slice1=mesh3D->buildSlice3D(origin3,vec3,1e-10,ids); + const int expected8[12]={6,7,8,9,10,11,12,13,14,15,16,17}; + const int expected9[68]={5,15,26,16,18,5,16,21,28,22,19,17,5,18,20,21,16,5,21,24,25,28,5,26,16,17,19,22,23,5,22,27,29,28,5,15,26,16,18,5,16,21,28,22,19,17,5,18,20,21,16,5,21,24,25,28,5,26,16,17,19,22,23,5,22,27,29,28}; + const int expected10[13]={0,5,12,17,22,29,34,39,46,51,56,63,68}; + const double expected11[135]={0.,0.,1.,1.,1.,1.,1.,1.25, 1.,1.,0.,1.,1.,1.5, 1.,2.,0.,1.,2.,1.,1.,1.,2.,1.,0.,2.,1.,3.,1.,1.,3.,2.,1.,0.,1.,1.,1.,3.,1.,2.,2.,1.,2.,3.,1.,0.,0.,2.,1.,1.,2.,1.,1.25, 2.,1.,0.,2.,1.,1.5, 2.,2.,0.,2.,2.,1.,2.,1.,2.,2.,0.,2.,2.,3.,1.,2.,3.,2.,2.,0.,1.,2.,1.,3.,2.,2.,2.,2.,2.,3.,2.,0.,0.,3.,1.,1.,3.,1.,1.25, 3.,1.,0.,3.,1.,1.5, 3.,2.,0.,3.,2.,1.,3.,1.,2.,3.,0.,2.,3.,3.,1.,3.,3.,2.,3.,0.,1.,3.,1.,3.,3.,2.,2.,3.,2.,3.,3.}; + CPPUNIT_ASSERT_EQUAL(2,slice1->getMeshDimension()); + CPPUNIT_ASSERT_EQUAL(3,slice1->getSpaceDimension()); + CPPUNIT_ASSERT_EQUAL(45,slice1->getNumberOfNodes()); + CPPUNIT_ASSERT_EQUAL(12,slice1->getNumberOfCells()); + CPPUNIT_ASSERT_EQUAL(12,ids->getNumberOfTuples()); + CPPUNIT_ASSERT_EQUAL(68,slice1->getNodalConnectivity()->getNumberOfTuples()); + CPPUNIT_ASSERT_EQUAL(13,slice1->getNodalConnectivityIndex()->getNumberOfTuples()); + CPPUNIT_ASSERT(std::equal(expected8,expected8+12,ids->getConstPointer())); + CPPUNIT_ASSERT(std::equal(expected9,expected9+68,slice1->getNodalConnectivity()->getConstPointer())); + CPPUNIT_ASSERT(std::equal(expected10,expected10+13,slice1->getNodalConnectivityIndex()->getConstPointer())); + for(int i=0;i<135;i++) + CPPUNIT_ASSERT_DOUBLES_EQUAL(expected11[i],slice1->getCoords()->getIJ(0,i),1e-12); + ids->decrRef(); + slice1->decrRef(); + // + mesh3D->decrRef(); +} + +void MEDCouplingBasicsTest5::testBuildSlice3DSurf1() +{ + MEDCouplingUMesh *mesh2D=0; + MEDCouplingUMesh *mesh3D=build3DExtrudedUMesh_1(mesh2D); + mesh2D->decrRef(); + DataArrayInt *a=DataArrayInt::New(),*b=DataArrayInt::New(),*c=DataArrayInt::New(),*d=DataArrayInt::New(); + mesh2D=mesh3D->buildDescendingConnectivity(a,b,c,d); + a->decrRef(); b->decrRef(); c->decrRef(); d->decrRef(); + mesh3D->decrRef(); + // + const double vec1[3]={-0.07,1.,0.07}; + const double origin1[3]={1.524,1.4552,1.74768}; + DataArrayInt *ids=0; + MEDCouplingUMesh *slice1=mesh2D->buildSlice3DSurf(origin1,vec1,1e-10,ids); + const int expected1[25]={6,8,10,11,13,18,19,21,23,25,26,38,41,43,47,49,52,53,64,67,69,73,75,78,79}; + const int expected2[75]={1,40,41,1,42,41,1,40,43,1,44,43,1,42,44,1,45,41,1,42,46,1,46,45,1,47,40,1,47,48,1,44,48,1,49,42,1,44,50,1,49,50,1,49,51,1,51,46,1,48,52,1,50,52,1,53,49,1,50,54,1,53,54,1,53,55,1,55,51,1,52,56,1,54,56}; + const int expected3[26]={0,3,6,9,12,15,18,21,24,27,30,33,36,39,42,45,48,51,54,57,60,63,66,69,72,75}; + const double expected4[171]={1.,1.,0.,1.,1.25,0.,1.,1.5,0.,2.,1.,0.,1.,2.,0.,0.,2.,0.,3.,1.,0.,3.,2.,0.,0.,1.,0.,2.,2.,0.,1.,1.,1.,1.,1.25,1.,1.,1.5,1.,2.,1.,1.,1.,2.,1.,0.,2.,1.,3.,1.,1.,3.,2.,1.,0.,1.,1.,2.,2.,1.,1.,1.,2.,1.,1.25,2.,1.,1.5,2.,2.,1.,2.,1.,2.,2.,0.,2.,2.,3.,1.,2.,3.,2.,2.,0.,1.,2.,2.,2.,2.,1.,1.,3.,1.,1.25,3.,1.,1.5,3.,2.,1.,3.,1.,2.,3.,0.,2.,3.,3.,1.,3.,3.,2.,3.,0.,1.,3.,2.,2.,3.,1.,1.5408576,0.,2.,1.6108576000000001,0.,2.,1.5408576,1.,1.,1.5,0.5836800000000008,1.,1.4708576,1.,3.,1.6808576,0.,3.,1.6108576000000001,1.,0.,1.4708576,0.,0.,1.4008576,1.,2.,1.4708576,2.,1.,1.4008576000000001,2.,3.,1.5408575999999998,2.,0.,1.3308575999999999,2.,2.,1.4008576,3.,1.,1.3308576,3.,3.,1.4708576,3.,0.,1.2608576,3.}; + CPPUNIT_ASSERT_EQUAL(1,slice1->getMeshDimension()); + CPPUNIT_ASSERT_EQUAL(3,slice1->getSpaceDimension()); + CPPUNIT_ASSERT_EQUAL(57,slice1->getNumberOfNodes()); + CPPUNIT_ASSERT_EQUAL(25,slice1->getNumberOfCells()); + CPPUNIT_ASSERT_EQUAL(25,ids->getNumberOfTuples()); + CPPUNIT_ASSERT_EQUAL(75,slice1->getNodalConnectivity()->getNumberOfTuples()); + CPPUNIT_ASSERT_EQUAL(26,slice1->getNodalConnectivityIndex()->getNumberOfTuples()); + CPPUNIT_ASSERT(std::equal(expected1,expected1+25,ids->getConstPointer())); + CPPUNIT_ASSERT(std::equal(expected2,expected2+47,slice1->getNodalConnectivity()->getConstPointer())); + CPPUNIT_ASSERT(std::equal(expected3,expected3+26,slice1->getNodalConnectivityIndex()->getConstPointer())); + for(int i=0;i<171;i++) + CPPUNIT_ASSERT_DOUBLES_EQUAL(expected4[i],slice1->getCoords()->getIJ(0,i),1e-12); + ids->decrRef(); + slice1->decrRef(); + // + const double vec2[3]={0.,0.,1.}; + const double origin2[3]={2.5,1.,2.}; + slice1=mesh2D->buildSlice3DSurf(origin2,vec2,1e-10,ids); + const int expected5[68]={32,32,32,32,33,34,35,36,37,38,39,40,41,42,43,43,43,43,43,43,44,44,44,44,45,46,47,47,47,47,48,49,50,51,52,53,53,53,53,53,53,54,54,54,54,55,56,57,59,60,61,62,63,64,65,66,67,68,71,72,74,75,76,77,78,81,82,83}; + const int expected6[204]={1,15,18,1,18,16,1,16,26,1,26,15,1,26,15,1,16,26,1,18,16,1,15,18,1,16,21,1,21,28,1,22,28,1,19,22,1,17,19,1,16,17,1,16,21,1,21,28,1,28,22,1,22,19,1,19,17,1,17,16,1,16,18,1,18,20,1,20,21,1,21,16,1,20,21,1,18,20,1,28,21,1,21,24,1,24,25,1,25,28,1,25,28,1,24,25,1,21,24,1,23,22,1,26,23,1,26,16,1,16,17,1,17,19,1,19,22,1,22,23,1,23,26,1,22,28,1,28,29,1,29,27,1,27,22,1,27,22,1,29,27,1,28,29,1,26,15,1,16,26,1,18,16,1,15,18,1,16,21,1,21,28,1,22,28,1,19,22,1,17,19,1,16,17,1,20,21,1,18,20,1,25,28,1,24,25,1,21,24,1,23,22,1,26,23,1,27,22,1,29,27,1,28,29}; + const int expected7[69]={0,3,6,9,12,15,18,21,24,27,30,33,36,39,42,45,48,51,54,57,60,63,66,69,72,75,78,81,84,87,90,93,96,99,102,105,108,111,114,117,120,123,126,129,132,135,138,141,144,147,150,153,156,159,162,165,168,171,174,177,180,183,186,189,192,195,198,201,204}; + const double expected8[135]={0.,0.,1.,1.,1.,1.,1.,1.25, 1.,1.,0.,1.,1.,1.5, 1.,2.,0.,1.,2.,1.,1.,1.,2.,1.,0.,2.,1.,3.,1.,1.,3.,2.,1.,0.,1.,1.,1.,3.,1.,2.,2.,1.,2.,3.,1.,0.,0.,2.,1.,1.,2.,1.,1.25, 2.,1.,0.,2.,1.,1.5, 2.,2.,0.,2.,2.,1.,2.,1.,2.,2.,0.,2.,2.,3.,1.,2.,3.,2.,2.,0.,1.,2.,1.,3.,2.,2.,2.,2.,2.,3.,2.,0.,0.,3.,1.,1.,3.,1.,1.25, 3.,1.,0.,3.,1.,1.5, 3.,2.,0.,3.,2.,1.,3.,1.,2.,3.,0.,2.,3.,3.,1.,3.,3.,2.,3.,0.,1.,3.,1.,3.,3.,2.,2.,3.,2.,3.,3.}; + CPPUNIT_ASSERT_EQUAL(1,slice1->getMeshDimension()); + CPPUNIT_ASSERT_EQUAL(3,slice1->getSpaceDimension()); + CPPUNIT_ASSERT_EQUAL(45,slice1->getNumberOfNodes()); + CPPUNIT_ASSERT_EQUAL(68,slice1->getNumberOfCells()); + CPPUNIT_ASSERT_EQUAL(68,ids->getNumberOfTuples()); + CPPUNIT_ASSERT_EQUAL(204,slice1->getNodalConnectivity()->getNumberOfTuples()); + CPPUNIT_ASSERT_EQUAL(69,slice1->getNodalConnectivityIndex()->getNumberOfTuples()); + CPPUNIT_ASSERT(std::equal(expected5,expected5+68,ids->getConstPointer())); + CPPUNIT_ASSERT(std::equal(expected6,expected6+171,slice1->getNodalConnectivity()->getConstPointer())); + CPPUNIT_ASSERT(std::equal(expected7,expected7+69,slice1->getNodalConnectivityIndex()->getConstPointer())); + for(int i=0;i<135;i++) + CPPUNIT_ASSERT_DOUBLES_EQUAL(expected8[i],slice1->getCoords()->getIJ(0,i),1e-12); + ids->decrRef(); + slice1->decrRef(); + // + mesh2D->decrRef(); +} + +void MEDCouplingBasicsTest5::testDataArrayDoubleAdvSetting1() +{ + const double data1[14]={1.,11.,2.,12.,3.,13.,4.,14.,5.,15.,6.,16.,7.,17.}; + const double data2[10]={8.,38.,9.,39.,0.,30.,11.,41.,12.,42.}; + const char *comps[2]={"comp1","comp2"}; + std::vector<std::string> compsCpp(comps,comps+2); + DataArrayDouble *da=DataArrayDouble::New(); + DataArrayDouble *tmp=0; + da->setInfoAndChangeNbOfCompo(compsCpp); + da->setName("da"); + da->alloc(7,2); + compsCpp.pop_back(); + CPPUNIT_ASSERT_THROW(da->setInfoAndChangeNbOfCompo(compsCpp),INTERP_KERNEL::Exception); + std::copy(data1,data1+14,da->getPointer()); + // + std::vector<std::pair<int,int> > p(3); + p[0].first=0; p[0].second=3; p[1].first=3; p[1].second=5; p[2].first=5; p[2].second=7; + tmp=dynamic_cast<DataArrayDouble *>(da->selectByTupleRanges(p)); + CPPUNIT_ASSERT(tmp->isEqual(*da,1e-14)); + tmp->decrRef(); + p[0].first=0; p[0].second=2; p[1].first=3; p[1].second=4; p[2].first=5; p[2].second=7; + tmp=dynamic_cast<DataArrayDouble *>(da->selectByTupleRanges(p)); + const double expected1[10]={1.,11.,2.,12.,4.,14.,6.,16.,7.,17.}; + CPPUNIT_ASSERT_EQUAL(5,tmp->getNumberOfTuples()); + CPPUNIT_ASSERT_EQUAL(2,tmp->getNumberOfComponents()); + for(int i=0;i<10;i++) + CPPUNIT_ASSERT_DOUBLES_EQUAL(expected1[i],tmp->getIJ(0,i),1e-14); + tmp->decrRef(); + p[0].first=0; p[0].second=2; p[1].first=0; p[1].second=2; p[2].first=5; p[2].second=6; + tmp=dynamic_cast<DataArrayDouble *>(da->selectByTupleRanges(p)); + const double expected2[10]={1.,11.,2.,12.,1.,11.,2.,12.,6.,16.}; + CPPUNIT_ASSERT_EQUAL(5,tmp->getNumberOfTuples()); + CPPUNIT_ASSERT_EQUAL(2,tmp->getNumberOfComponents()); + for(int i=0;i<10;i++) + CPPUNIT_ASSERT_DOUBLES_EQUAL(expected2[i],tmp->getIJ(0,i),1e-14); + tmp->decrRef(); + p[0].first=0; p[0].second=2; p[1].first=-1; p[1].second=2; p[2].first=5; p[2].second=6; + CPPUNIT_ASSERT_THROW(da->selectByTupleRanges(p),INTERP_KERNEL::Exception); + p[0].first=0; p[0].second=2; p[1].first=0; p[1].second=2; p[2].first=5; p[2].second=8; + CPPUNIT_ASSERT_THROW(da->selectByTupleRanges(p),INTERP_KERNEL::Exception); + // + DataArrayDouble *da2=DataArrayDouble::New(); + da2->alloc(5,2); + std::copy(data2,data2+10,da2->getPointer()); + // + DataArrayDouble *dac=da->deepCpy(); + dac->setContigPartOfSelectedValues2(1,da2,2,4,1); + const double expected3[14]={1.,11.,0.,30.,11.,41.,4.,14.,5.,15.,6.,16.,7.,17.}; + for(int i=0;i<14;i++) + CPPUNIT_ASSERT_DOUBLES_EQUAL(expected3[i],dac->getIJ(0,i),1e-14); + dac->decrRef(); + // + dac=da->deepCpy(); + CPPUNIT_ASSERT_THROW(dac->setContigPartOfSelectedValues2(3,da2,0,5,1),INTERP_KERNEL::Exception); + CPPUNIT_ASSERT_THROW(dac->setContigPartOfSelectedValues2(0,da2,4,6,1),INTERP_KERNEL::Exception); + CPPUNIT_ASSERT_THROW(dac->setContigPartOfSelectedValues2(3,da2,5,0,1),INTERP_KERNEL::Exception); + dac->setContigPartOfSelectedValues2(3,da2,1,5,1); + const double expected4[14]={1.,11.,2.,12.,3.,13.,9.,39.,0.,30.,11.,41.,12.,42.}; + for(int i=0;i<14;i++) + CPPUNIT_ASSERT_DOUBLES_EQUAL(expected4[i],dac->getIJ(0,i),1e-14); + dac->decrRef(); + // + DataArrayInt *ids=DataArrayInt::New(); + ids->alloc(3,1); + dac=da->deepCpy(); + ids->setIJ(0,0,2); ids->setIJ(1,0,0); ids->setIJ(2,0,4); + dac->setContigPartOfSelectedValues(2,da2,ids); + const double expected5[14]={1.,11.,2.,12.,0.,30.,8.,38.,12.,42.,6.,16.,7.,17.}; + for(int i=0;i<14;i++) + CPPUNIT_ASSERT_DOUBLES_EQUAL(expected5[i],dac->getIJ(0,i),1e-14); + dac->decrRef(); + // + dac=da->deepCpy(); + ids->setIJ(0,0,2); ids->setIJ(1,0,5); ids->setIJ(2,0,4); + CPPUNIT_ASSERT_THROW(dac->setContigPartOfSelectedValues(1,da2,ids),INTERP_KERNEL::Exception); + ids->setIJ(0,0,2); ids->setIJ(1,0,2); ids->setIJ(2,0,-1); + CPPUNIT_ASSERT_THROW(dac->setContigPartOfSelectedValues(1,da2,ids),INTERP_KERNEL::Exception); + ids->setIJ(0,0,2); ids->setIJ(1,0,2); ids->setIJ(2,0,1); + CPPUNIT_ASSERT_THROW(dac->setContigPartOfSelectedValues(5,da2,ids),INTERP_KERNEL::Exception); + dac->decrRef(); + // + ids->setIJ(0,0,2); ids->setIJ(1,0,2); ids->setIJ(2,0,1); + dac=da->deepCpy(); + dac->setContigPartOfSelectedValues(4,da2,ids); + const double expected6[14]={1.,11.,2.,12.,3.,13.,4.,14.,0.,30.,0.,30.,9.,39.}; + for(int i=0;i<14;i++) + CPPUNIT_ASSERT_DOUBLES_EQUAL(expected6[i],dac->getIJ(0,i),1e-14); + dac->decrRef(); + ids->decrRef(); + // + da2->decrRef(); + da->decrRef(); +} + +void MEDCouplingBasicsTest5::testDataArrayIntAdvSetting1() +{ + const int data1[14]={1,11,2,12,3,13,4,14,5,15,6,16,7,17}; + const int data2[10]={8,38,9,39,0,30,11,41,12,42}; + const char *comps[2]={"comp1","comp2"}; + std::vector<std::string> compsCpp(comps,comps+2); + DataArrayInt *da=DataArrayInt::New(); + DataArrayInt *tmp=0; + da->setInfoAndChangeNbOfCompo(compsCpp); + da->setName("da"); + da->alloc(7,2); + compsCpp.pop_back(); + CPPUNIT_ASSERT_THROW(da->setInfoAndChangeNbOfCompo(compsCpp),INTERP_KERNEL::Exception); + std::copy(data1,data1+14,da->getPointer()); + // + std::vector<std::pair<int,int> > p(3); + p[0].first=0; p[0].second=3; p[1].first=3; p[1].second=5; p[2].first=5; p[2].second=7; + tmp=dynamic_cast<DataArrayInt *>(da->selectByTupleRanges(p)); + CPPUNIT_ASSERT(tmp->isEqual(*da)); + tmp->decrRef(); + p[0].first=0; p[0].second=2; p[1].first=3; p[1].second=4; p[2].first=5; p[2].second=7; + tmp=dynamic_cast<DataArrayInt *>(da->selectByTupleRanges(p)); + const int expected1[10]={1,11,2,12,4,14,6,16,7,17}; + CPPUNIT_ASSERT_EQUAL(5,tmp->getNumberOfTuples()); + CPPUNIT_ASSERT_EQUAL(2,tmp->getNumberOfComponents()); + for(int i=0;i<10;i++) + CPPUNIT_ASSERT_EQUAL(expected1[i],tmp->getIJ(0,i)); + tmp->decrRef(); + p[0].first=0; p[0].second=2; p[1].first=0; p[1].second=2; p[2].first=5; p[2].second=6; + tmp=dynamic_cast<DataArrayInt *>(da->selectByTupleRanges(p)); + const int expected2[10]={1,11,2,12,1,11,2,12,6,16}; + CPPUNIT_ASSERT_EQUAL(5,tmp->getNumberOfTuples()); + CPPUNIT_ASSERT_EQUAL(2,tmp->getNumberOfComponents()); + for(int i=0;i<10;i++) + CPPUNIT_ASSERT_EQUAL(expected2[i],tmp->getIJ(0,i)); + tmp->decrRef(); + p[0].first=0; p[0].second=2; p[1].first=-1; p[1].second=2; p[2].first=5; p[2].second=6; + CPPUNIT_ASSERT_THROW(da->selectByTupleRanges(p),INTERP_KERNEL::Exception); + p[0].first=0; p[0].second=2; p[1].first=0; p[1].second=2; p[2].first=5; p[2].second=8; + CPPUNIT_ASSERT_THROW(da->selectByTupleRanges(p),INTERP_KERNEL::Exception); + // + DataArrayInt *da2=DataArrayInt::New(); + da2->alloc(5,2); + std::copy(data2,data2+10,da2->getPointer()); + // + DataArrayInt *dac=da->deepCpy(); + dac->setContigPartOfSelectedValues2(1,da2,2,4,1); + const int expected3[14]={1,11,0,30,11,41,4,14,5,15,6,16,7,17}; + for(int i=0;i<14;i++) + CPPUNIT_ASSERT_EQUAL(expected3[i],dac->getIJ(0,i)); + dac->decrRef(); + // + dac=da->deepCpy(); + CPPUNIT_ASSERT_THROW(dac->setContigPartOfSelectedValues2(3,da2,0,5,1),INTERP_KERNEL::Exception); + CPPUNIT_ASSERT_THROW(dac->setContigPartOfSelectedValues2(0,da2,4,6,1),INTERP_KERNEL::Exception); + CPPUNIT_ASSERT_THROW(dac->setContigPartOfSelectedValues2(3,da2,5,0,1),INTERP_KERNEL::Exception); + dac->setContigPartOfSelectedValues2(3,da2,1,5,1); + const int expected4[14]={1,11,2,12,3,13,9,39,0,30,11,41,12,42}; + for(int i=0;i<14;i++) + CPPUNIT_ASSERT_EQUAL(expected4[i],dac->getIJ(0,i)); + dac->decrRef(); + // + DataArrayInt *ids=DataArrayInt::New(); + ids->alloc(3,1); + dac=da->deepCpy(); + ids->setIJ(0,0,2); ids->setIJ(1,0,0); ids->setIJ(2,0,4); + dac->setContigPartOfSelectedValues(2,da2,ids); + const int expected5[14]={1,11,2,12,0,30,8,38,12,42,6,16,7,17}; + for(int i=0;i<14;i++) + CPPUNIT_ASSERT_EQUAL(expected5[i],dac->getIJ(0,i)); + dac->decrRef(); + // + dac=da->deepCpy(); + ids->setIJ(0,0,2); ids->setIJ(1,0,5); ids->setIJ(2,0,4); + CPPUNIT_ASSERT_THROW(dac->setContigPartOfSelectedValues(1,da2,ids),INTERP_KERNEL::Exception); + ids->setIJ(0,0,2); ids->setIJ(1,0,2); ids->setIJ(2,0,-1); + CPPUNIT_ASSERT_THROW(dac->setContigPartOfSelectedValues(1,da2,ids),INTERP_KERNEL::Exception); + ids->setIJ(0,0,2); ids->setIJ(1,0,2); ids->setIJ(2,0,1); + CPPUNIT_ASSERT_THROW(dac->setContigPartOfSelectedValues(5,da2,ids),INTERP_KERNEL::Exception); + dac->decrRef(); + // + ids->setIJ(0,0,2); ids->setIJ(1,0,2); ids->setIJ(2,0,1); + dac=da->deepCpy(); + dac->setContigPartOfSelectedValues(4,da2,ids); + const int expected6[14]={1,11,2,12,3,13,4,14,0,30,0,30,9,39}; + for(int i=0;i<14;i++) + CPPUNIT_ASSERT_EQUAL(expected6[i],dac->getIJ(0,i)); + dac->decrRef(); + ids->decrRef(); + // + da2->decrRef(); + da->decrRef(); +} + +void MEDCouplingBasicsTest5::testBuildDescendingConnec2Of3DMesh1() +{ + MEDCouplingUMesh *mesh=build3DSourceMesh_1(); + DataArrayInt *desc=DataArrayInt::New(); + DataArrayInt *descIndx=DataArrayInt::New(); + DataArrayInt *revDesc=DataArrayInt::New(); + DataArrayInt *revDescIndx=DataArrayInt::New(); + // + MEDCouplingUMesh *mesh2=mesh->buildDescendingConnectivity2(desc,descIndx,revDesc,revDescIndx); + mesh2->checkCoherency(); + CPPUNIT_ASSERT_EQUAL(2,mesh2->getMeshDimension()); + CPPUNIT_ASSERT_EQUAL(30,mesh2->getNumberOfCells()); + CPPUNIT_ASSERT_EQUAL((std::size_t)31,revDescIndx->getNbOfElems()); CPPUNIT_ASSERT_EQUAL(31,revDescIndx->getNumberOfTuples()); + CPPUNIT_ASSERT_EQUAL((std::size_t)13,descIndx->getNbOfElems()); CPPUNIT_ASSERT_EQUAL(13,descIndx->getNumberOfTuples()); + CPPUNIT_ASSERT_EQUAL((std::size_t)48,desc->getNbOfElems()); CPPUNIT_ASSERT_EQUAL(48,desc->getNumberOfTuples()); + CPPUNIT_ASSERT_EQUAL((std::size_t)48,revDesc->getNbOfElems()); CPPUNIT_ASSERT_EQUAL(48,revDesc->getNumberOfTuples()); + const int expected1[48]={1,2,3,4,5,6,7,8,9,10,11,12,13,14,-10,15,-5,-13,16,17,-14,18,-4,19,-2,20,21,22,23,24,25,-11,26,-1,-12,-25,-22,27,28,-7,-20,-24,29,-16,-18,30,-8,-28}; + CPPUNIT_ASSERT(std::equal(expected1,expected1+48,desc->getConstPointer())); + const int expected2[13]={0,4,8,12,16,20,24,28,32,36,40,44,48}; + CPPUNIT_ASSERT(std::equal(expected2,expected2+13,descIndx->getConstPointer())); + const int expected3[31]={0,2,4,5,7,9,10,12,14,15,17,19,21,23,25,26,28,29,31,32,34,35,37,38,40,42,43,44,46,47,48}; + CPPUNIT_ASSERT(std::equal(expected3,expected3+31,revDescIndx->getConstPointer())); + const int expected4[48]={0,8,0,6,0,0,5,1,4,1,1,9,1,11,2,2,3,2,7,2,8,3,4,3,5,3,4,10,4,5,11,5,6,10,6,6,9,7,7,10,7,8,8,9,9,11,10,11}; + CPPUNIT_ASSERT(std::equal(expected4,expected4+48,revDesc->getConstPointer())); + DataArrayInt *conn=mesh2->getNodalConnectivity(); + DataArrayInt *connIndex=mesh2->getNodalConnectivityIndex(); + const int expected5[31]={0,4,8,12,16,20,24,28,32,36,40,44,48,52,56,60,64,68,72,76,80,84,88,92,96,100,104,108,112,116,120}; + CPPUNIT_ASSERT(std::equal(expected5,expected5+31,connIndex->getConstPointer())); + const int expected6[120]={3,8,1,7,3,8,3,1,3,1,3,7,3,7,3,8,3,6,0,8,3,6,2,0,3,0,2,8,3,8,2,6,3,7,4,5,3,7,8,4,3,4,8,5,3,5,8,7,3,6,8,4,3,6,7,8,3,4,7,6,3,8,4,0,3,0,4,6,3,6,3,8,3,7,3,6,3,8,0,1,3,1,0,3,3,3,0,8,3,4,1,5,3,4,8,1,3,1,8,5,3,1,7,5,3,0,2,3,3,3,2,8,3,1,4,0,3,3,2,6}; + CPPUNIT_ASSERT(std::equal(expected6,expected6+120,conn->getConstPointer())); + // + desc->decrRef(); + descIndx->decrRef(); + revDesc->decrRef(); + revDescIndx->decrRef(); + mesh2->decrRef(); + mesh->decrRef(); +} + +void MEDCouplingBasicsTest5::testAre2DCellsNotCorrectlyOriented1() +{ + double m1Coords[8]={1.,1.,-1.,-1.,-1.,-1.,1.,-1.}; + int m1Conn[4]={0,3,1,2}; + MEDCouplingUMesh *m1=MEDCouplingUMesh::New(); + m1->setMeshDimension(2); + m1->allocateCells(1); + m1->insertNextCell(INTERP_KERNEL::NORM_QUAD4,4,m1Conn); + m1->finishInsertingCells(); + DataArrayDouble *myCoords1=DataArrayDouble::New(); + myCoords1->alloc(4,2); + std::copy(m1Coords,m1Coords+8,myCoords1->getPointer()); + m1->setCoords(myCoords1); + myCoords1->decrRef(); + // + double vec1[3]={0.,0.,1.}; + double *vec2=new double[2]; + for(int i=0;i<18;i++) + { + vec2[0]=3.*cos(M_PI/9.*i); + vec2[1]=3.*sin(M_PI/9.*i); + MEDCouplingUMesh *m1Cpy=static_cast<MEDCouplingUMesh *>(m1->deepCpy()); + m1Cpy->translate(vec2); + std::vector<int> res; + CPPUNIT_ASSERT_THROW(m1Cpy->are2DCellsNotCorrectlyOriented(vec1,false,res),INTERP_KERNEL::Exception); + res.clear(); + m1Cpy->changeSpaceDimension(3); + m1Cpy->are2DCellsNotCorrectlyOriented(vec1,false,res); + CPPUNIT_ASSERT_EQUAL(1,(int)res.size()); + CPPUNIT_ASSERT_EQUAL(0,res[0]); + m1Cpy->decrRef(); + } + delete [] vec2; + // + m1->decrRef(); +} + +void MEDCouplingBasicsTest5::testDataArrayAbs1() +{ + DataArrayDouble *d1=DataArrayDouble::New(); + const double val1[12]={2.,-3.,-5.,6.,-7.,-8.,9.,10.,-11.,-12.,-13.,-15.}; + const double expected1[12]={2.,3.,5.,6.,7.,8.,9.,10.,11.,12.,13.,15.}; + d1->alloc(6,2); + std::copy(val1,val1+12,d1->getPointer()); + DataArrayInt *d2=d1->convertToIntArr(); + // + d1->abs(); + for(int i=0;i<12;i++) + CPPUNIT_ASSERT_DOUBLES_EQUAL(expected1[i],d1->getIJ(0,i),1e-14); + // + const int expected2[12]={2,3,5,6,7,8,9,10,11,12,13,15}; + d2->abs(); + for(int i=0;i<12;i++) + CPPUNIT_ASSERT_EQUAL(expected2[i],d2->getIJ(0,i)); + // + d2->decrRef(); + d1->decrRef(); +} + +void MEDCouplingBasicsTest5::testGetValueOn3() +{ + const double v[4]={0.,1.,1.5,2.}; + const double v2[5]={0.7,1.25,0.,2.,1.5}; + const double disp[12]={5.,50.,500.,6.,60.,600.,7.,70.,700.,8.,80.,800.}; + MEDCouplingUMesh *m=MEDCouplingUMesh::New("myMesh",1); + const int nbNodes=4; + const int nbCells=nbNodes-1; + m->allocateCells(nbCells); + DataArrayDouble *coords=DataArrayDouble::New(); + coords->alloc(nbNodes,1); + std::copy(v,v+nbNodes,coords->getPointer()); + m->setCoords(coords); + coords->decrRef(); + const int conn[6]={0,1,2,1,2,3}; + m->insertNextCell(INTERP_KERNEL::NORM_SEG2,2,conn); + m->insertNextCell(INTERP_KERNEL::NORM_SEG2,2,conn+2); + m->insertNextCell(INTERP_KERNEL::NORM_SEG2,2,conn+4); + m->finishInsertingCells(); + MEDCouplingFieldDouble *f=MEDCouplingFieldDouble::New(ON_NODES); + f->setMesh(m); + DataArrayDouble *array=DataArrayDouble::New(); + array->alloc(m->getNumberOfNodes(),3); + std::copy(disp,disp+12,array->getPointer()); + f->setArray(array); + array->decrRef(); + DataArrayDouble *arr1=f->getValueOnMulti(v2,5); + CPPUNIT_ASSERT_EQUAL(5,arr1->getNumberOfTuples()); + CPPUNIT_ASSERT_EQUAL(3,arr1->getNumberOfComponents()); + const double expected1[15]={5.7,57.,570.,6.5,65.,650.,5.,50.,500.,8.,80.,800.,7.,70.,700.}; + for(int i=0;i<15;i++) + CPPUNIT_ASSERT_DOUBLES_EQUAL(expected1[i],arr1->getIJ(0,i),1e-14); + arr1->decrRef(); + f->decrRef(); + m->decrRef(); +} + +void MEDCouplingBasicsTest5::testGetNodeIdsOfCell2() +{ + MEDCouplingCMesh *m1c=MEDCouplingCMesh::New(); + DataArrayDouble *coordsX=DataArrayDouble::New(); + double arrX[5] = { -1., 1., 2., 4., 4.5 }; + coordsX->useArray(arrX,false, CPP_DEALLOC,5,1); + DataArrayDouble *coordsY=DataArrayDouble::New(); + double arrY[4] = { -2., 2., 4., 8. }; + coordsY->useArray(arrY,false, CPP_DEALLOC,4,1); + DataArrayDouble *coordsZ=DataArrayDouble::New(); + double arrZ[3] = { -2., 2., 4. }; + coordsZ->useArray(arrZ,false, CPP_DEALLOC,3,1); + // test in 1D + m1c->setCoordsAt(0,coordsX); + CPPUNIT_ASSERT_EQUAL(4,m1c->getNumberOfCells()); + const int expected1[4][2]={{0,1},{1,2},{2,3},{3,4}}; + for(int i=0;i<4;i++) + { + std::vector<int> v; + m1c->getNodeIdsOfCell(i,v); + CPPUNIT_ASSERT((int)v.size()==2); + std::equal(v.begin(),v.end(),expected1[i]); + } + // test in 2D + m1c->setCoordsAt(1,coordsY); + CPPUNIT_ASSERT_EQUAL(12,m1c->getNumberOfCells()); + const int expected2[12][4]={{0,1,6,5},{1,2,7,6},{2,3,8,7},{3,4,9,8},{4,5,11,10},{5,6,12,11},{6,7,13,12},{7,8,14,13},{8,9,16,15},{9,10,17,16},{10,11,18,17},{11,12,19,18}}; + for(int i=0;i<12;i++) + { + std::vector<int> v; + m1c->getNodeIdsOfCell(i,v); + CPPUNIT_ASSERT((int)v.size()==4); + std::equal(v.begin(),v.end(),expected2[i]); + } + // test in 3D + m1c->setCoordsAt(2,coordsZ); + CPPUNIT_ASSERT_EQUAL(24,m1c->getNumberOfCells()); + const int expected3[24][8]={{0,1,6,5,20,21,26,25},{1,2,7,6,21,22,27,26},{2,3,8,7,22,23,28,27},{3,4,9,8,23,24,29,28},{4,5,11,10,24,25,31,30},{5,6,12,11,25,26,32,31},{6,7,13,12,26,27,33,32},{7,8,14,13,27,28,34,33},{8,9,16,15,28,29,36,35},{9,10,17,16,29,30,37,36},{10,11,18,17,30,31,38,37},{11,12,19,18,31,32,39,38},{20,21,26,25,40,41,46,45},{21,22,27,26,41,42,47,46},{22,23,28,27,42,43,48,47},{23,24,29,28,43,44,49,48},{24,25,31,30,44,45,51,50},{25,26,32,31,45,46,52,51},{26,27,33,32,46,47,53,52},{27,28,34,33,47,48,54,53},{28,29,36,35,48,49,56,55},{29,30,37,36,49,50,57,56},{30,31,38,37,50,51,58,57},{31,32,39,38,51,52,59,58}}; + for(int i=0;i<12;i++) + { + std::vector<int> v; + m1c->getNodeIdsOfCell(i,v); + CPPUNIT_ASSERT((int)v.size()==8); + std::equal(v.begin(),v.end(),expected3[i]); + } + // + coordsX->decrRef(); + coordsY->decrRef(); + coordsZ->decrRef(); + m1c->decrRef(); +} + +void MEDCouplingBasicsTest5::testRenumberNodesInConn1() +{ + double mesh2DCoords[27]={-0.3,-0.3,0., 0.2,-0.3,0., 0.7,-0.3,0., -0.3,0.2,0., 0.2,0.2,0., 0.7,0.2,0., -0.3,0.7,0., 0.2,0.7,0., 0.7,0.7,0. }; + int mesh2DConn[18]={1,4,2, 4,5,2, 0,3,4,1, 6,7,4,3, 7,8,5,4}; + MEDCouplingUMesh *mesh2D=MEDCouplingUMesh::New("mesh",2); + mesh2D->allocateCells(5); + mesh2D->insertNextCell(INTERP_KERNEL::NORM_TRI3,3,mesh2DConn); + mesh2D->insertNextCell(INTERP_KERNEL::NORM_TRI3,3,mesh2DConn+3); + mesh2D->insertNextCell(INTERP_KERNEL::NORM_QUAD4,4,mesh2DConn+6); + mesh2D->insertNextCell(INTERP_KERNEL::NORM_QUAD4,4,mesh2DConn+10); + mesh2D->insertNextCell(INTERP_KERNEL::NORM_QUAD4,4,mesh2DConn+14); + mesh2D->finishInsertingCells(); + DataArrayDouble *myCoords=DataArrayDouble::New(); + myCoords->alloc(9,3); + std::copy(mesh2DCoords,mesh2DCoords+27,myCoords->getPointer()); + mesh2D->setCoords(myCoords); + myCoords->decrRef(); + mesh2D->checkCoherency(); + // + double mesh3DCoords[24]={-0.3,-0.3,0., -0.3,0.2,0., 0.2,0.2,0., 0.2,-0.3,0., -0.3,-0.3,1., -0.3,0.2,1., 0.2,0.2,1., 0.2,-0.3,1. }; + int mesh3DConn[8]={0,1,2,3,4,5,6,7}; + MEDCouplingUMesh *mesh3D=MEDCouplingUMesh::New("mesh",3); + mesh3D->allocateCells(1); + mesh3D->insertNextCell(INTERP_KERNEL::NORM_HEXA8,8,mesh3DConn); + mesh3D->finishInsertingCells(); + DataArrayDouble *myCoords3D=DataArrayDouble::New(); + myCoords3D->alloc(8,3); + std::copy(mesh3DCoords,mesh3DCoords+24,myCoords3D->getPointer()); + mesh3D->setCoords(myCoords3D); + myCoords3D->decrRef(); + mesh3D->checkCoherency(); + // + MEDCouplingUMesh *mesh3D_2=dynamic_cast<MEDCouplingUMesh *>(mesh3D->deepCpy()); + MEDCouplingUMesh *mesh2D_2=dynamic_cast<MEDCouplingUMesh *>(mesh2D->deepCpy()); + MEDCouplingUMesh *mesh3D_4=dynamic_cast<MEDCouplingUMesh *>(mesh3D->deepCpy()); + MEDCouplingUMesh *mesh2D_4=dynamic_cast<MEDCouplingUMesh *>(mesh2D->deepCpy()); + DataArrayInt *renumNodes=DataArrayInt::New(); + int oldNbOf3DNodes=mesh3D->getNumberOfNodes(); + renumNodes->alloc(mesh2D->getNumberOfNodes(),1); + renumNodes->iota(oldNbOf3DNodes); + DataArrayDouble *coo=DataArrayDouble::Aggregate(mesh3D->getCoords(),mesh2D->getCoords()); + mesh3D->setCoords(coo); + mesh2D->setCoords(coo); + coo->decrRef(); + MEDCouplingUMesh *mesh2D_3=dynamic_cast<MEDCouplingUMesh *>(mesh2D->deepCpy()); + mesh2D_3->shiftNodeNumbersInConn(oldNbOf3DNodes); + mesh2D->renumberNodesInConn(renumNodes->getConstPointer()); + renumNodes->decrRef(); + CPPUNIT_ASSERT(mesh2D_3->isEqual(mesh2D,1e-12)); + mesh2D_3->decrRef(); + // + DataArrayInt *da1,*da2; + mesh3D->checkGeoEquivalWith(mesh3D_2,10,1e-12,da1,da2); + CPPUNIT_ASSERT(da1==0); + CPPUNIT_ASSERT_EQUAL(8,da2->getNumberOfTuples()); + CPPUNIT_ASSERT_EQUAL(1,da2->getNumberOfComponents()); + const int expected1[8]={8,11,12,9,4,5,6,7}; + for(int i=0;i<8;i++) + CPPUNIT_ASSERT_EQUAL(expected1[i],da2->getIJ(i,0)); + da2->decrRef(); + // + mesh2D->checkGeoEquivalWith(mesh2D_2,10,1e-12,da1,da2); + CPPUNIT_ASSERT(da1==0); + CPPUNIT_ASSERT_EQUAL(9,da2->getNumberOfTuples()); + CPPUNIT_ASSERT_EQUAL(1,da2->getNumberOfComponents()); + for(int i=0;i<9;i++) + CPPUNIT_ASSERT_EQUAL(8+i,da2->getIJ(i,0)); + da2->decrRef(); + // + const double vect[3]={1.,0.,0.}; + MEDCouplingUMesh *mesh2D_5=dynamic_cast<MEDCouplingUMesh *>(mesh2D_4->deepCpy()); + mesh2D_5->translate(vect); + std::vector<MEDCouplingUMesh *> meshes(3); + meshes[0]=mesh3D_4; meshes[1]=mesh2D_4; meshes[2]=mesh2D_5; + MEDCouplingUMesh::PutUMeshesOnSameAggregatedCoords(meshes); + CPPUNIT_ASSERT(mesh3D_4->getCoords()==mesh2D_4->getCoords()); + CPPUNIT_ASSERT(mesh2D_4->getCoords()==mesh2D_5->getCoords()); + mesh3D_4->checkCoherency(); mesh2D_4->checkCoherency(); mesh2D_5->checkCoherency(); + CPPUNIT_ASSERT_EQUAL(26,mesh3D_4->getNumberOfNodes()); + CPPUNIT_ASSERT_EQUAL(3,mesh3D_4->getSpaceDimension()); + CPPUNIT_ASSERT_EQUAL(9,mesh3D_4->getNodalConnectivity()->getNumberOfTuples()); + CPPUNIT_ASSERT_EQUAL(23,mesh2D_4->getNodalConnectivity()->getNumberOfTuples()); + CPPUNIT_ASSERT_EQUAL(23,mesh2D_5->getNodalConnectivity()->getNumberOfTuples()); + const int expected2[9]={18,0,1,2,3,4,5,6,7}; + const int expected3[23]={3,9,12,10, 3,12,13,10, 4,8,11,12,9, 4,14,15,12,11, 4,15,16,13,12}; + const int expected4[23]={3,18,21,19, 3,21,22,19, 4,17,20,21,18, 4,23,24,21,20, 4,24,25,22,21}; + const double expected5[78]={-0.3,-0.3,0., -0.3,0.2,0., 0.2,0.2,0., 0.2,-0.3,0., -0.3,-0.3,1., -0.3,0.2,1., 0.2,0.2,1., 0.2,-0.3,1., -0.3,-0.3,0., 0.2,-0.3,0., 0.7,-0.3,0., -0.3,0.2,0., 0.2,0.2,0., 0.7,0.2,0., -0.3,0.7,0., 0.2,0.7,0., 0.7,0.7,0., 0.7, -0.3, 0.0, 1.2, -0.3, 0.0, 1.7, -0.3, 0.0, 0.7, 0.2, 0.0, 1.2, 0.2, 0.0, 1.7, 0.2, 0.0, 0.7, 0.7, 0.0, 1.2, 0.7, 0.0, 1.7, 0.7, 0.0}; + CPPUNIT_ASSERT(std::equal(expected2,expected2+9,mesh3D_4->getNodalConnectivity()->getConstPointer())); + CPPUNIT_ASSERT(std::equal(expected3,expected3+23,mesh2D_4->getNodalConnectivity()->getConstPointer())); + CPPUNIT_ASSERT(std::equal(expected4,expected4+23,mesh2D_5->getNodalConnectivity()->getConstPointer())); + for(int i=0;i<78;i++) + CPPUNIT_ASSERT_DOUBLES_EQUAL(expected5[i],mesh3D_4->getCoords()->getIJ(0,i),1e-12); + // + MEDCouplingUMesh::MergeNodesOnUMeshesSharingSameCoords(meshes,1e-12); + mesh3D_4->checkCoherency(); mesh2D_4->checkCoherency(); mesh2D_5->checkCoherency(); + CPPUNIT_ASSERT(mesh3D_4->getCoords()==mesh2D_4->getCoords()); + CPPUNIT_ASSERT(mesh2D_4->getCoords()==mesh2D_5->getCoords()); + CPPUNIT_ASSERT_EQUAL(19,mesh3D_4->getNumberOfNodes()); + CPPUNIT_ASSERT_EQUAL(3,mesh3D_4->getSpaceDimension()); + CPPUNIT_ASSERT_EQUAL(9,mesh3D_4->getNodalConnectivity()->getNumberOfTuples()); + CPPUNIT_ASSERT_EQUAL(23,mesh2D_4->getNodalConnectivity()->getNumberOfTuples()); + CPPUNIT_ASSERT_EQUAL(23,mesh2D_5->getNodalConnectivity()->getNumberOfTuples()); + const int expected6[9]={18,0,1,2,3,4,5,6,7}; + const int expected7[23]={3,3,2,8, 3,2,9,8, 4,0,1,2,3, 4,10,11,2,1, 4,11,12,9,2}; + const int expected8[23]={3,13,15,14, 3,15,16,14, 4,8,9,15,13, 4,12,17,15,9, 4,17,18,16,15}; + const double expected9[57]={-0.3, -0.3, 0., -0.3, 0.2, 0., 0.2, 0.2, 0., 0.2, -0.3, 0., -0.3, -0.3, 1., -0.3, 0.2, 1., + 0.2, 0.2, 1., 0.2, -0.3, 1., 0.7, -0.3, 0., 0.7, 0.2, 0., -0.3, 0.7, 0., 0.2, 0.7, 0., + 0.7, 0.7, 0., 1.2, -0.3, 0., 1.7, -0.3, 0., 1.2, 0.2, 0., 1.7, 0.2, 0., 1.2, 0.7, 0., 1.7, 0.7, 0.}; + CPPUNIT_ASSERT(std::equal(expected6,expected6+9,mesh3D_4->getNodalConnectivity()->getConstPointer())); + CPPUNIT_ASSERT(std::equal(expected7,expected7+23,mesh2D_4->getNodalConnectivity()->getConstPointer())); + CPPUNIT_ASSERT(std::equal(expected8,expected8+23,mesh2D_5->getNodalConnectivity()->getConstPointer())); + for(int i=0;i<57;i++) + CPPUNIT_ASSERT_DOUBLES_EQUAL(expected9[i],mesh3D_4->getCoords()->getIJ(0,i),1e-12); + mesh2D_5->decrRef(); + // + mesh3D_4->decrRef(); + mesh2D_4->decrRef(); + mesh3D_2->decrRef(); + mesh2D_2->decrRef(); + // + mesh3D->decrRef(); + mesh2D->decrRef(); +} + +void MEDCouplingBasicsTest5::testComputeNeighborsOfCells1() +{ + MEDCouplingUMesh *m=build2DTargetMesh_1(); + DataArrayInt *d1=0,*d2=0; + m->computeNeighborsOfCells(d1,d2); + CPPUNIT_ASSERT_EQUAL(6,d2->getNumberOfTuples()); + CPPUNIT_ASSERT_EQUAL(10,d1->getNumberOfTuples()); + const int expected1[6]={0,2,4,6,8,10}; + const int expected2[10]={3,1,0,2,4,1,4,0,2,3}; + CPPUNIT_ASSERT(std::equal(expected1,expected1+6,d2->getConstPointer())); + CPPUNIT_ASSERT(std::equal(expected2,expected2+10,d1->getConstPointer())); + d1->decrRef(); + d2->decrRef(); + m->decrRef(); +} + +void MEDCouplingBasicsTest5::testCheckButterflyCellsBug1() +{ + double mesh2DCoords[10]={323.85,120.983748908684,317.5,131.982271536747,336.55,120.983748908686,330.2,131.982271536751,323.85,142.98079416481}; + int mesh2DConn[5]={4,1,0,2,3}; + MEDCouplingUMesh *mesh2D=MEDCouplingUMesh::New("mesh",2); + mesh2D->allocateCells(1); + mesh2D->insertNextCell(INTERP_KERNEL::NORM_POLYGON,5,mesh2DConn); + mesh2D->finishInsertingCells(); + DataArrayDouble *myCoords=DataArrayDouble::New(); + myCoords->alloc(5,2); + std::copy(mesh2DCoords,mesh2DCoords+10,myCoords->getPointer()); + mesh2D->setCoords(myCoords); + myCoords->decrRef(); + mesh2D->checkCoherency(); + // + std::vector<int> v; + mesh2D->checkButterflyCells(v); + CPPUNIT_ASSERT_EQUAL(0,(int)v.size()); + // + mesh2D->decrRef(); +} + +void MEDCouplingBasicsTest5::testDataArrayIntRange1() +{ + DataArrayInt *d=DataArrayInt::Range(2,17,7); + const int expected1[3]={2,9,16}; + CPPUNIT_ASSERT_EQUAL(3,d->getNumberOfTuples()); + CPPUNIT_ASSERT_EQUAL(1,d->getNumberOfComponents()); + CPPUNIT_ASSERT(std::equal(expected1,expected1+3,d->getConstPointer())); + d->decrRef(); + // + d=DataArrayInt::Range(2,23,7); + CPPUNIT_ASSERT_EQUAL(3,d->getNumberOfTuples()); + CPPUNIT_ASSERT_EQUAL(1,d->getNumberOfComponents()); + CPPUNIT_ASSERT(std::equal(expected1,expected1+3,d->getConstPointer())); + d->decrRef(); + // + d=DataArrayInt::Range(2,24,7); + const int expected2[4]={2,9,16,23}; + CPPUNIT_ASSERT_EQUAL(4,d->getNumberOfTuples()); + CPPUNIT_ASSERT_EQUAL(1,d->getNumberOfComponents()); + CPPUNIT_ASSERT(std::equal(expected2,expected2+4,d->getConstPointer())); + d->decrRef(); + // + d=DataArrayInt::Range(24,2,-7); + const int expected3[4]={24,17,10,3}; + CPPUNIT_ASSERT_EQUAL(4,d->getNumberOfTuples()); + CPPUNIT_ASSERT_EQUAL(1,d->getNumberOfComponents()); + CPPUNIT_ASSERT(std::equal(expected3,expected3+4,d->getConstPointer())); + d->decrRef(); + // + d=DataArrayInt::Range(23,2,-7); + const int expected4[3]={23,16,9}; + CPPUNIT_ASSERT_EQUAL(3,d->getNumberOfTuples()); + CPPUNIT_ASSERT_EQUAL(1,d->getNumberOfComponents()); + CPPUNIT_ASSERT(std::equal(expected4,expected4+3,d->getConstPointer())); + d->decrRef(); + // + d=DataArrayInt::Range(23,22,-7); + CPPUNIT_ASSERT_EQUAL(1,d->getNumberOfTuples()); + CPPUNIT_ASSERT_EQUAL(1,d->getNumberOfComponents()); + CPPUNIT_ASSERT_EQUAL(23,d->getIJ(0,0)); + d->decrRef(); + // + d=DataArrayInt::Range(22,23,7); + CPPUNIT_ASSERT_EQUAL(1,d->getNumberOfTuples()); + CPPUNIT_ASSERT_EQUAL(1,d->getNumberOfComponents()); + CPPUNIT_ASSERT_EQUAL(22,d->getIJ(0,0)); + d->decrRef(); + // + d=DataArrayInt::Range(22,22,7); + CPPUNIT_ASSERT_EQUAL(0,d->getNumberOfTuples()); + CPPUNIT_ASSERT_EQUAL(1,d->getNumberOfComponents()); + d->decrRef(); + // + d=DataArrayInt::Range(22,22,-7); + CPPUNIT_ASSERT_EQUAL(0,d->getNumberOfTuples()); + CPPUNIT_ASSERT_EQUAL(1,d->getNumberOfComponents()); + d->decrRef(); + // + CPPUNIT_ASSERT_THROW(DataArrayInt::Range(22,23,-7),INTERP_KERNEL::Exception); + CPPUNIT_ASSERT_THROW(DataArrayInt::Range(23,22,7),INTERP_KERNEL::Exception); + CPPUNIT_ASSERT_THROW(DataArrayInt::Range(23,22,0),INTERP_KERNEL::Exception); + CPPUNIT_ASSERT_THROW(DataArrayInt::Range(22,23,0),INTERP_KERNEL::Exception); +} + +void MEDCouplingBasicsTest5::testDataArrayDoubleGetMinMaxPerComponent1() +{ + const double values1[12]={1.,2.,3.,-0.9,2.1,3.,1.3,1.7,3.,1.,1.8,3.}; + DataArrayDouble *d1=DataArrayDouble::New(); + double *res=new double[2*3]; + CPPUNIT_ASSERT_THROW(d1->getMinMaxPerComponent(res),INTERP_KERNEL::Exception); + d1->alloc(4,3); + std::copy(values1,values1+12,d1->getPointer()); + d1->getMinMaxPerComponent(res); + const double expected1[6]={-0.9,1.3,1.7,2.1,3.,3.}; + for(int i=0;i<6;i++) + CPPUNIT_ASSERT_DOUBLES_EQUAL(expected1[i],res[i],1e-14); + delete [] res; + // + d1->rearrange(2); + res=new double[2*2]; + d1->getMinMaxPerComponent(res); + const double expected2[4]={1.,3.,-0.9,3.}; + for(int i=0;i<4;i++) + CPPUNIT_ASSERT_DOUBLES_EQUAL(expected2[i],res[i],1e-14); + delete [] res; + // + d1->rearrange(1); + res=new double[2*1]; + d1->getMinMaxPerComponent(res); + const double expected3[2]={-0.9,3.}; + for(int i=0;i<2;i++) + CPPUNIT_ASSERT_DOUBLES_EQUAL(expected3[i],res[i],1e-14); + delete [] res; + d1->decrRef(); +} + +void MEDCouplingBasicsTest5::testDataArrayIntGetHashCode1() +{ + DataArrayInt *d1=DataArrayInt::New(); d1->alloc(3545,1); d1->iota(0); + DataArrayInt *d2=DataArrayInt::New(); d2->alloc(3545,1); d2->iota(0); + // + CPPUNIT_ASSERT_EQUAL(d1->getHashCode(),d2->getHashCode()); + CPPUNIT_ASSERT_EQUAL(232341068,d1->getHashCode()); + d1->setIJ(886,0,6); + CPPUNIT_ASSERT_EQUAL(232340188,d1->getHashCode()); + // + d1->decrRef(); + d2->decrRef(); +} + +void MEDCouplingBasicsTest5::testZipConnectivityPol1() +{ + MEDCouplingUMesh *m1=build2DTargetMesh_1(); + const int cells1[3]={2,3,4}; + MEDCouplingPointSet *m2_1=m1->buildPartOfMySelf(cells1,cells1+3,true); + MEDCouplingUMesh *m2=dynamic_cast<MEDCouplingUMesh *>(m2_1); + DataArrayInt *arr=0; + CPPUNIT_ASSERT(m2); + // no permutation policy 0 + CPPUNIT_ASSERT(m1->areCellsIncludedIn(m2,0,arr)); + CPPUNIT_ASSERT_EQUAL(3,arr->getNumberOfTuples()); + CPPUNIT_ASSERT_EQUAL(1,arr->getNumberOfComponents()); + CPPUNIT_ASSERT(std::equal(cells1,cells1+3,arr->getConstPointer())); + arr->decrRef(); + // no permutation policy 1 + CPPUNIT_ASSERT(m1->areCellsIncludedIn(m2,1,arr)); + CPPUNIT_ASSERT_EQUAL(3,arr->getNumberOfTuples()); + CPPUNIT_ASSERT_EQUAL(1,arr->getNumberOfComponents()); + CPPUNIT_ASSERT(std::equal(cells1,cells1+3,arr->getConstPointer())); + arr->decrRef(); + // no permutation policy 2 + CPPUNIT_ASSERT(m1->areCellsIncludedIn(m2,2,arr)); + CPPUNIT_ASSERT_EQUAL(3,arr->getNumberOfTuples()); + CPPUNIT_ASSERT_EQUAL(1,arr->getNumberOfComponents()); + CPPUNIT_ASSERT(std::equal(cells1,cells1+3,arr->getConstPointer())); + arr->decrRef(); + // some modification into m2 + const int modif1[3]={2,4,5}; + std::copy(modif1,modif1+3,m2->getNodalConnectivity()->getPointer()+1); + //policy 0 fails because cell0 in m2 has same orientation be not same connectivity + const int expected1[3]={5,3,4}; + CPPUNIT_ASSERT(!m1->areCellsIncludedIn(m2,0,arr)); + CPPUNIT_ASSERT_EQUAL(3,arr->getNumberOfTuples()); + CPPUNIT_ASSERT_EQUAL(1,arr->getNumberOfComponents()); + CPPUNIT_ASSERT(std::equal(expected1,expected1+3,arr->getConstPointer())); + arr->decrRef(); + //policy 1 succeeds because cell0 in m2 has not exactly the same conn + CPPUNIT_ASSERT(m1->areCellsIncludedIn(m2,1,arr)); + CPPUNIT_ASSERT_EQUAL(3,arr->getNumberOfTuples()); + CPPUNIT_ASSERT_EQUAL(1,arr->getNumberOfComponents()); + CPPUNIT_ASSERT(std::equal(cells1,cells1+3,arr->getConstPointer())); + arr->decrRef(); + //policy 2 succeeds because cell0 in m2 has same nodes in connectivity + CPPUNIT_ASSERT(m1->areCellsIncludedIn(m2,2,arr)); + CPPUNIT_ASSERT_EQUAL(3,arr->getNumberOfTuples()); + CPPUNIT_ASSERT_EQUAL(1,arr->getNumberOfComponents()); + CPPUNIT_ASSERT(std::equal(cells1,cells1+3,arr->getConstPointer())); + arr->decrRef(); + //some new modification into m2 + const int modif2[3]={2,5,4}; + std::copy(modif2,modif2+3,m2->getNodalConnectivity()->getPointer()+1); + //policy 0 fails because cell0 in m2 has not exactly the same conn + CPPUNIT_ASSERT(!m1->areCellsIncludedIn(m2,0,arr)); + CPPUNIT_ASSERT_EQUAL(3,arr->getNumberOfTuples()); + CPPUNIT_ASSERT_EQUAL(1,arr->getNumberOfComponents()); + CPPUNIT_ASSERT(std::equal(expected1,expected1+3,arr->getConstPointer())); + arr->decrRef(); + //policy 1 fails too because cell0 in m2 has not same orientation + CPPUNIT_ASSERT(!m1->areCellsIncludedIn(m2,1,arr)); + CPPUNIT_ASSERT_EQUAL(3,arr->getNumberOfTuples()); + CPPUNIT_ASSERT_EQUAL(1,arr->getNumberOfComponents()); + CPPUNIT_ASSERT(std::equal(expected1,expected1+3,arr->getConstPointer())); + arr->decrRef(); + //policy 2 succeeds because cell0 in m2 has same nodes in connectivity + CPPUNIT_ASSERT(m1->areCellsIncludedIn(m2,2,arr)); + CPPUNIT_ASSERT_EQUAL(3,arr->getNumberOfTuples()); + CPPUNIT_ASSERT_EQUAL(1,arr->getNumberOfComponents()); + CPPUNIT_ASSERT(std::equal(cells1,cells1+3,arr->getConstPointer())); + arr->decrRef(); + m1->decrRef(); + m2->decrRef(); + // Now 1D + const int cells2[2]={3,2}; + m1=build1DSourceMesh_2(); + m2_1=m1->buildPartOfMySelf(cells2,cells2+2,true); + m2=dynamic_cast<MEDCouplingUMesh *>(m2_1); + CPPUNIT_ASSERT(m2); + arr=0; + // no permutation policy 0 + CPPUNIT_ASSERT(m1->areCellsIncludedIn(m2,0,arr)); + CPPUNIT_ASSERT_EQUAL(2,arr->getNumberOfTuples()); + CPPUNIT_ASSERT_EQUAL(1,arr->getNumberOfComponents()); + CPPUNIT_ASSERT(std::equal(cells2,cells2+2,arr->getConstPointer())); + arr->decrRef(); + // no permutation policy 1 + CPPUNIT_ASSERT(m1->areCellsIncludedIn(m2,1,arr)); + CPPUNIT_ASSERT_EQUAL(2,arr->getNumberOfTuples()); + CPPUNIT_ASSERT_EQUAL(1,arr->getNumberOfComponents()); + CPPUNIT_ASSERT(std::equal(cells2,cells2+2,arr->getConstPointer())); + arr->decrRef(); + // no permutation policy 2 + CPPUNIT_ASSERT(m1->areCellsIncludedIn(m2,2,arr)); + CPPUNIT_ASSERT_EQUAL(2,arr->getNumberOfTuples()); + CPPUNIT_ASSERT_EQUAL(1,arr->getNumberOfComponents()); + CPPUNIT_ASSERT(std::equal(cells2,cells2+2,arr->getConstPointer())); + arr->decrRef(); + // some modification into m2 + const int modif3[2]={4,3}; + std::copy(modif3,modif3+2,m2->getNodalConnectivity()->getPointer()+1); + //policy 0 fails because cell0 in m2 has not exactly the same conn + const int expected2[2]={4,2}; + CPPUNIT_ASSERT(!m1->areCellsIncludedIn(m2,0,arr)); + CPPUNIT_ASSERT_EQUAL(2,arr->getNumberOfTuples()); + CPPUNIT_ASSERT_EQUAL(1,arr->getNumberOfComponents()); + CPPUNIT_ASSERT(std::equal(expected2,expected2+2,arr->getConstPointer())); + arr->decrRef(); + //policy 1 fails too because cell0 in m2 has not same orientation + CPPUNIT_ASSERT(!m1->areCellsIncludedIn(m2,1,arr)); + CPPUNIT_ASSERT_EQUAL(2,arr->getNumberOfTuples()); + CPPUNIT_ASSERT_EQUAL(1,arr->getNumberOfComponents()); + CPPUNIT_ASSERT(std::equal(expected2,expected2+2,arr->getConstPointer())); + arr->decrRef(); + //policy 2 succeeds because cell0 in m2 has same nodes in connectivity + CPPUNIT_ASSERT(m1->areCellsIncludedIn(m2,2,arr)); + CPPUNIT_ASSERT_EQUAL(2,arr->getNumberOfTuples()); + CPPUNIT_ASSERT_EQUAL(1,arr->getNumberOfComponents()); + CPPUNIT_ASSERT(std::equal(cells2,cells2+2,arr->getConstPointer())); + arr->decrRef(); + m1->decrRef(); + m2->decrRef(); +} + +void MEDCouplingBasicsTest5::testConvexEnvelop2D1() +{ + const double coords[662]={7.54758495819e-14,-1.12270326253e-12,8.43143594193,-1.02835845055e-12,4.21571797096,7.30183771609,-4.21571797097,7.30183771609,-8.43143594193,-1.09439981894e-12,-4.21571797097,-7.30183771609,4.21571797097,-7.30183771609,16.8628718839,-1.02835845055e-12,12.6471539129,7.30183771609,8.43143594193,14.6036754322,2.26427548746e-13,14.6036754322,-8.43143594193,14.6036754322,-12.6471539129,7.30183771609,-16.8628718839,-1.39630321727e-12,-12.6471539129,-7.30183771609,-8.43143594193,-14.6036754322,3.7737924791e-14,-14.6036754322,8.43143594193,-14.6036754322,12.6471539129,-7.30183771609,25.2943078258,-1.07553085654e-12,21.0785898548,7.30183771609,16.8628718839,14.6036754322,12.6471539129,21.9055131483,4.21571797096,21.9055131483,-4.21571797097,21.9055131483,-12.6471539129,21.9055131483,-16.8628718839,14.6036754322,-21.0785898548,7.30183771609,-25.2943078258,-1.02835845055e-12,-21.0785898548,-7.30183771609,-16.8628718839,-14.6036754322,-12.6471539129,-21.9055131483,-4.21571797097,-21.9055131483,4.21571797097,-21.9055131483,12.6471539129,-21.9055131483,16.8628718839,-14.6036754322,21.0785898548,-7.30183771609,33.7257437677,-7.45324014622e-13,29.5100257968,7.30183771609,25.2943078258,14.6036754322,21.0785898548,21.9055131483,16.8628718839,29.2073508644,8.43143594193,29.2073508644,-1.20761359331e-12,29.2073508644,-8.43143594193,29.2073508644,-16.8628718839,29.2073508644,-21.0785898548,21.9055131483,-25.2943078258,14.6036754322,-29.5100257968,7.30183771609,-33.7257437677,-7.26455052226e-13,-29.5100257968,-7.30183771609,-25.2943078258,-14.6036754322,-21.0785898548,-21.9055131483,-16.8628718839,-29.2073508644,-8.43143594193,-29.2073508644,4.15117172701e-13,-29.2073508644,8.43143594193,-29.2073508644,16.8628718839,-29.2073508644,21.0785898548,-21.9055131483,25.2943078258,-14.6036754322,29.5100257968,-7.30183771609,42.1571797097,-1.86802727715e-12,37.9414617387,7.30183771609,33.7257437677,14.6036754322,29.5100257968,21.9055131483,25.2943078258,29.2073508644,21.0785898548,36.5091885805,12.6471539129,36.5091885805,4.21571797096,36.5091885805,-4.21571797096,36.5091885805,-12.6471539129,36.5091885805,-21.0785898548,36.5091885805,-25.2943078258,29.2073508644,-29.5100257968,21.9055131483,-33.7257437677,14.6036754322,-37.9414617387,7.30183771609,-42.1571797097,-9.81186044565e-13,-37.9414617387,-7.30183771609,-33.7257437677,-14.6036754322,-29.5100257968,-21.9055131483,-25.2943078258,-29.2073508644,-21.0785898548,-36.5091885805,-12.6471539129,-36.5091885805,-4.21571797097,-36.5091885805,4.21571797097,-36.5091885805,12.6471539129,-36.5091885805,21.0785898548,-36.5091885805,25.2943078258,-29.2073508644,29.5100257968,-21.9055131483,33.7257437677,-14.6036754322,37.9414617387,-7.30183771609,50.5886156516,-6.98151608633e-13,46.3728976806,7.30183771609,42.1571797097,14.6036754322,37.9414617387,21.9055131483,33.7257437677,29.2073508644,29.5100257968,36.5091885805,25.2943078258,43.8110262966,16.8628718839,43.8110262966,8.43143594193,43.8110262966,-1.84915831476e-12,43.8110262966,-8.43143594193,43.8110262966,-16.8628718839,43.8110262966,-25.2943078258,43.8110262966,-29.5100257968,36.5091885805,-33.7257437677,29.2073508644,-37.9414617387,21.9055131483,-42.1571797097,14.6036754322,-46.3728976806,7.30183771609,-50.5886156516,-1.47177906685e-12,-46.3728976806,-7.30183771609,-42.1571797097,-14.6036754322,-37.9414617387,-21.9055131483,-33.7257437677,-29.2073508644,-29.5100257968,-36.5091885805,-25.2943078258,-43.8110262966,-16.8628718839,-43.8110262966,-8.43143594193,-43.8110262966,7.54758495819e-14,-43.8110262966,8.43143594193,-43.8110262966,16.8628718839,-43.8110262966,25.2943078258,-43.8110262966,29.5100257968,-36.5091885805,33.7257437677,-29.2073508644,37.9414617387,-21.9055131483,42.1571797097,-14.6036754322,46.3728976806,-7.30183771609,59.0200515935,-7.9249642061e-13,54.8043336225,7.30183771609,50.5886156516,14.6036754322,46.3728976806,21.9055131483,42.1571797097,29.2073508644,37.9414617387,36.5091885805,33.7257437677,43.8110262966,29.5100257968,51.1128640127,21.0785898548,51.1128640127,12.6471539129,51.1128640127,4.21571797096,51.1128640127,-4.21571797096,51.1128640127,-12.6471539129,51.1128640127,-21.0785898548,51.1128640127,-29.5100257968,51.1128640127,-33.7257437677,43.8110262966,-37.9414617387,36.5091885805,-42.1571797097,29.2073508644,-46.3728976806,21.9055131483,-50.5886156516,14.6036754322,-54.8043336226,7.30183771609,-59.0200515935,-1.31139288649e-12,-54.8043336226,-7.30183771609,-50.5886156516,-14.6036754322,-46.3728976806,-21.9055131483,-42.1571797097,-29.2073508644,-37.9414617387,-36.5091885805,-33.7257437677,-43.8110262966,-29.5100257968,-51.1128640127,-21.0785898548,-51.1128640127,-12.6471539129,-51.1128640127,-4.21571797097,-51.1128640127,4.21571797097,-51.1128640127,12.6471539129,-51.1128640127,21.0785898548,-51.1128640127,29.5100257968,-51.1128640127,33.7257437677,-43.8110262966,37.9414617387,-36.5091885805,42.1571797097,-29.2073508644,46.3728976806,-21.9055131483,50.5886156516,-14.6036754322,54.8043336225,-7.30183771609,67.4514875354,-2.14162723189e-12,63.2357695645,7.30183771609,59.0200515935,14.6036754322,54.8043336226,21.9055131483,50.5886156516,29.2073508644,46.3728976806,36.5091885805,42.1571797097,43.8110262966,37.9414617387,51.1128640127,33.7257437677,58.4147017287,25.2943078258,58.4147017287,16.8628718839,58.4147017287,8.43143594193,58.4147017287,6.79282646237e-13,58.4147017287,-8.43143594193,58.4147017287,-16.8628718839,58.4147017287,-25.2943078258,58.4147017287,-33.7257437677,58.4147017287,-37.9414617387,51.1128640127,-42.1571797097,43.8110262966,-46.3728976806,36.5091885805,-50.5886156516,29.2073508644,-54.8043336226,21.9055131483,-59.0200515935,14.6036754322,-63.2357695645,7.30183771609,-67.4514875354,-1.16044118732e-12,-63.2357695645,-7.30183771609,-59.0200515935,-14.6036754322,-54.8043336226,-21.9055131483,-50.5886156516,-29.2073508644,-46.3728976806,-36.5091885805,-42.1571797097,-43.8110262966,-37.9414617387,-51.1128640127,-33.7257437677,-58.4147017287,-25.2943078258,-58.4147017287,-16.8628718839,-58.4147017287,-8.43143594193,-58.4147017287,-5.66068871864e-14,-58.4147017287,8.43143594193,-58.4147017287,16.8628718839,-58.4147017287,25.2943078258,-58.4147017287,33.7257437677,-58.4147017287,37.9414617387,-51.1128640127,42.1571797097,-43.8110262966,46.3728976806,-36.5091885805,50.5886156516,-29.2073508644,54.8043336226,-21.9055131483,59.0200515935,-14.6036754322,63.2357695645,-7.30183771609,75.8829234774,-2.29257893105e-12,71.6672055064,7.30183771609,67.4514875354,14.6036754322,63.2357695645,21.9055131483,59.0200515935,29.2073508644,54.8043336226,36.5091885805,50.5886156516,43.8110262966,46.3728976806,51.1128640127,42.1571797097,58.4147017287,37.9414617387,65.7165394448,29.5100257968,65.7165394448,21.0785898548,65.7165394448,12.6471539129,65.7165394448,4.21571797097,65.7165394448,-4.21571797096,65.7165394448,-12.6471539129,65.7165394448,-21.0785898548,65.7165394448,-29.5100257968,65.7165394448,-37.9414617387,65.7165394448,-42.1571797097,58.4147017287,-46.3728976806,51.1128640127,-50.5886156516,43.8110262966,-54.8043336226,36.5091885805,-59.0200515935,29.2073508644,-63.2357695645,21.9055131483,-67.4514875354,14.6036754322,-71.6672055064,7.30183771609,-75.8829234774,-1.31139288649e-12,-71.6672055064,-7.30183771609,-67.4514875354,-14.6036754322,-63.2357695645,-21.9055131483,-59.0200515935,-29.2073508644,-54.8043336226,-36.5091885805,-50.5886156516,-43.8110262966,-46.3728976806,-51.1128640127,-42.1571797097,-58.4147017287,-37.9414617387,-65.7165394448,-29.5100257968,-65.7165394448,-21.0785898548,-65.7165394448,-12.6471539129,-65.7165394448,-4.21571797097,-65.7165394448,4.21571797097,-65.7165394448,12.6471539129,-65.7165394448,21.0785898548,-65.7165394448,29.5100257968,-65.7165394448,37.9414617387,-65.7165394448,42.1571797097,-58.4147017287,46.3728976806,-51.1128640127,50.5886156516,-43.8110262966,54.8043336226,-36.5091885805,59.0200515935,-29.2073508644,63.2357695645,-21.9055131483,67.4514875354,-14.6036754322,71.6672055064,-7.30183771609,84.3143594193,-1.49064802924e-12,80.0986414483,7.30183771609,75.8829234774,14.6036754322,71.6672055064,21.9055131483,67.4514875354,29.2073508644,63.2357695645,36.5091885805,59.0200515935,43.8110262966,54.8043336226,51.1128640127,50.5886156516,58.4147017287,46.3728976806,65.7165394448,42.1571797097,73.0183771609,33.7257437677,73.0183771609,25.2943078258,73.0183771609,16.8628718839,73.0183771609,8.43143594193,73.0183771609,2.0755858635e-12,73.0183771609,-8.43143594193,73.0183771609,-16.8628718839,73.0183771609,-25.2943078258,73.0183771609,-33.7257437677,73.0183771609,-42.1571797097,73.0183771609,-46.3728976806,65.7165394448,-50.5886156516,58.4147017287,-54.8043336226,51.1128640127,-59.0200515935,43.8110262966,-63.2357695645,36.5091885805,-67.4514875354,29.2073508644,-71.6672055064,21.9055131483,-75.8829234774,14.6036754322,-80.0986414483,7.30183771609,-84.3143594193,-1.11326878133e-12,-80.0986414483,-7.30183771609,-75.8829234774,-14.6036754322,-71.6672055064,-21.9055131483,-67.4514875354,-29.2073508644,-63.2357695645,-36.5091885805,-59.0200515935,-43.8110262966,-54.8043336226,-51.1128640127,-50.5886156516,-58.4147017287,-46.3728976806,-65.7165394448,-42.1571797097,-73.0183771609,-33.7257437677,-73.0183771609,-25.2943078258,-73.0183771609,-16.8628718839,-73.0183771609,-8.43143594193,-73.0183771609,-5.66068871864e-14,-73.0183771609,8.43143594193,-73.0183771609,16.8628718839,-73.0183771609,25.2943078258,-73.0183771609,33.7257437677,-73.0183771609,42.1571797097,-73.0183771609,46.3728976806,-65.7165394448,50.5886156516,-58.4147017287,54.8043336226,-51.1128640127,59.0200515935,-43.8110262966,63.2357695645,-36.5091885805,67.4514875354,-29.2073508644,71.6672055064,-21.9055131483,75.8829234774,-14.6036754322,80.0986414483,-7.3018377161}; + const int conn[2137]={0,2,3,4,5,6,1,1,8,2,0,6,18,7,2,9,10,3,0,1,8,3,10,11,12,4,0,2,4,3,12,13,14,5,0,5,0,4,14,15,16,6,6,1,0,5,16,17,18,7,20,8,1,18,36,19,8,21,9,2,1,7,20,9,22,23,10,2,8,21,10,23,24,11,3,2,9,11,24,25,26,12,3,10,12,11,26,27,13,4,3,13,12,27,28,29,14,4,14,4,13,29,30,15,5,15,5,14,30,31,32,16,16,6,5,15,32,33,17,17,18,6,16,33,34,35,18,7,1,6,17,35,36,19,38,20,7,36,60,37,20,39,21,8,7,19,38,21,40,22,9,8,20,39,22,41,42,23,9,21,40,23,42,43,24,10,9,22,24,43,44,25,11,10,23,25,44,45,46,26,11,24,26,25,46,47,27,12,11,27,26,47,48,28,13,12,28,27,48,49,50,29,13,29,13,28,50,51,30,14,30,14,29,51,52,31,15,31,15,30,52,53,54,32,32,16,15,31,54,55,33,33,17,16,32,55,56,34,34,35,17,33,56,57,58,35,36,18,17,34,58,59,36,19,7,18,35,59,60,37,62,38,19,60,90,61,38,63,39,20,19,37,62,39,64,40,21,20,38,63,40,65,41,22,21,39,64,41,66,67,42,22,40,65,42,67,68,43,23,22,41,43,68,69,44,24,23,42,44,69,70,45,25,24,43,45,70,71,72,46,25,44,46,45,72,73,47,26,25,47,46,73,74,48,27,26,48,47,74,75,49,28,27,49,48,75,76,77,50,28,50,28,49,77,78,51,29,51,29,50,78,79,52,30,52,30,51,79,80,53,31,53,31,52,80,81,82,54,54,32,31,53,82,83,55,55,33,32,54,83,84,56,56,34,33,55,84,85,57,57,58,34,56,85,86,87,58,59,35,34,57,87,88,59,60,36,35,58,88,89,60,37,19,36,59,89,90,61,92,62,37,90,126,91,62,93,63,38,37,61,92,63,94,64,39,38,62,93,64,95,65,40,39,63,94,65,96,66,41,40,64,95,66,97,98,67,41,65,96,67,98,99,68,42,41,66,68,99,100,69,43,42,67,69,100,101,70,44,43,68,70,101,102,71,45,44,69,71,102,103,104,72,45,70,72,71,104,105,73,46,45,73,72,105,106,74,47,46,74,73,106,107,75,48,47,75,74,107,108,76,49,48,76,75,108,109,110,77,49,77,49,76,110,111,78,50,78,50,77,111,112,79,51,79,51,78,112,113,80,52,80,52,79,113,114,81,53,81,53,80,114,115,116,82,82,54,53,81,116,117,83,83,55,54,82,117,118,84,84,56,55,83,118,119,85,85,57,56,84,119,120,86,86,87,57,85,120,121,122,87,88,58,57,86,122,123,88,89,59,58,87,123,124,89,90,60,59,88,124,125,90,61,37,60,89,125,126,91,128,92,61,126,168,127,92,129,93,62,61,91,128,93,130,94,63,62,92,129,94,131,95,64,63,93,130,95,132,96,65,64,94,131,96,133,97,66,65,95,132,97,134,135,98,66,96,133,98,135,136,99,67,66,97,99,136,137,100,68,67,98,100,137,138,101,69,68,99,101,138,139,102,70,69,100,102,139,140,103,71,70,101,103,140,141,142,104,71,102,104,103,142,143,105,72,71,105,104,143,144,106,73,72,106,105,144,145,107,74,73,107,106,145,146,108,75,74,108,107,146,147,109,76,75,109,108,147,148,149,110,76,110,76,109,149,150,111,77,111,77,110,150,151,112,78,112,78,111,151,152,113,79,113,79,112,152,153,114,80,114,80,113,153,154,115,81,115,81,114,154,155,156,116,116,82,81,115,156,157,117,117,83,82,116,157,158,118,118,84,83,117,158,159,119,119,85,84,118,159,160,120,120,86,85,119,160,161,121,121,122,86,120,161,162,163,122,123,87,86,121,163,164,123,124,88,87,122,164,165,124,125,89,88,123,165,166,125,126,90,89,124,166,167,126,91,61,90,125,167,168,127,170,128,91,168,216,169,128,171,129,92,91,127,170,129,172,130,93,92,128,171,130,173,131,94,93,129,172,131,174,132,95,94,130,173,132,175,133,96,95,131,174,133,176,134,97,96,132,175,134,177,178,135,97,133,176,135,178,179,136,98,97,134,136,179,180,137,99,98,135,137,180,181,138,100,99,136,138,181,182,139,101,100,137,139,182,183,140,102,101,138,140,183,184,141,103,102,139,141,184,185,186,142,103,140,142,141,186,187,143,104,103,143,142,187,188,144,105,104,144,143,188,189,145,106,105,145,144,189,190,146,107,106,146,145,190,191,147,108,107,147,146,191,192,148,109,108,148,147,192,193,194,149,109,149,109,148,194,195,150,110,150,110,149,195,196,151,111,151,111,150,196,197,152,112,152,112,151,197,198,153,113,153,113,152,198,199,154,114,154,114,153,199,200,155,115,155,115,154,200,201,202,156,156,116,115,155,202,203,157,157,117,116,156,203,204,158,158,118,117,157,204,205,159,159,119,118,158,205,206,160,160,120,119,159,206,207,161,161,121,120,160,207,208,162,162,163,121,161,208,209,210,163,164,122,121,162,210,211,164,165,123,122,163,211,212,165,166,124,123,164,212,213,166,167,125,124,165,213,214,167,168,126,125,166,214,215,168,127,91,126,167,215,216,169,218,170,127,216,270,217,170,219,171,128,127,169,218,171,220,172,129,128,170,219,172,221,173,130,129,171,220,173,222,174,131,130,172,221,174,223,175,132,131,173,222,175,224,176,133,132,174,223,176,225,177,134,133,175,224,177,226,227,178,134,176,225,178,227,228,179,135,134,177,179,228,229,180,136,135,178,180,229,230,181,137,136,179,181,230,231,182,138,137,180,182,231,232,183,139,138,181,183,232,233,184,140,139,182,184,233,234,185,141,140,183,185,234,235,236,186,141,184,186,185,236,237,187,142,141,187,186,237,238,188,143,142,188,187,238,239,189,144,143,189,188,239,240,190,145,144,190,189,240,241,191,146,145,191,190,241,242,192,147,146,192,191,242,243,193,148,147,193,192,243,244,245,194,148,194,148,193,245,246,195,149,195,149,194,246,247,196,150,196,150,195,247,248,197,151,197,151,196,248,249,198,152,198,152,197,249,250,199,153,199,153,198,250,251,200,154,200,154,199,251,252,201,155,201,155,200,252,253,254,202,202,156,155,201,254,255,203,203,157,156,202,255,256,204,204,158,157,203,256,257,205,205,159,158,204,257,258,206,206,160,159,205,258,259,207,207,161,160,206,259,260,208,208,162,161,207,260,261,209,209,210,162,208,261,262,263,210,211,163,162,209,263,264,211,212,164,163,210,264,265,212,213,165,164,211,265,266,213,214,166,165,212,266,267,214,215,167,166,213,267,268,215,216,168,167,214,268,269,216,169,127,168,215,269,270,217,272,218,169,270,330,271,218,273,219,170,169,217,272,219,274,220,171,170,218,273,220,275,221,172,171,219,274,221,276,222,173,172,220,275,222,277,223,174,173,221,276,223,278,224,175,174,222,277,224,279,225,176,175,223,278,225,280,226,177,176,224,279,226,281,282,227,177,225,280,227,282,283,228,178,177,226,228,283,284,229,179,178,227,229,284,285,230,180,179,228,230,285,286,231,181,180,229,231,286,287,232,182,181,230,232,287,288,233,183,182,231,233,288,289,234,184,183,232,234,289,290,235,185,184,233,235,290,291,292,236,185,234,236,235,292,293,237,186,185,237,236,293,294,238,187,186,238,237,294,295,239,188,187,239,238,295,296,240,189,188,240,239,296,297,241,190,189,241,240,297,298,242,191,190,242,241,298,299,243,192,191,243,242,299,300,244,193,192,244,243,300,301,302,245,193,245,193,244,302,303,246,194,246,194,245,303,304,247,195,247,195,246,304,305,248,196,248,196,247,305,306,249,197,249,197,248,306,307,250,198,250,198,249,307,308,251,199,251,199,250,308,309,252,200,252,200,251,309,310,253,201,253,201,252,310,311,312,254,254,202,201,253,312,313,255,255,203,202,254,313,314,256,256,204,203,255,314,315,257,257,205,204,256,315,316,258,258,206,205,257,316,317,259,259,207,206,258,317,318,260,260,208,207,259,318,319,261,261,209,208,260,319,320,262,262,263,209,261,320,321,322,263,264,210,209,262,322,323,264,265,211,210,263,323,324,265,266,212,211,264,324,325,266,267,213,212,265,325,326,267,268,214,213,266,326,327,268,269,215,214,267,327,328,269,270,216,215,268,328,329,270,217,169,216,269,329,330,271,272,217,330,273,218,217,271,274,219,218,272,275,220,219,273,276,221,220,274,277,222,221,275,278,223,222,276,279,224,223,277,280,225,224,278,281,226,225,279,281,282,226,280,283,227,226,281,284,228,227,282,285,229,228,283,286,230,229,284,287,231,230,285,288,232,231,286,289,233,232,287,290,234,233,288,291,235,234,289,291,292,235,290,291,293,236,235,292,294,237,236,293,295,238,237,294,296,239,238,295,297,240,239,296,298,241,240,297,299,242,241,298,300,243,242,299,301,244,243,301,300,302,244,244,301,303,245,245,302,304,246,246,303,305,247,247,304,306,248,248,305,307,249,249,306,308,250,250,307,309,251,251,308,310,252,252,309,311,253,311,253,310,312,254,253,311,313,255,254,312,314,256,255,313,315,257,256,314,316,258,257,315,317,259,258,316,318,260,259,317,319,261,260,318,320,262,261,319,321,321,322,262,320,323,263,262,321,324,264,263,322,325,265,264,323,326,266,265,324,327,267,266,325,328,268,267,326,329,269,268,327,330,270,269,328,271,217,270,329}; + const int connI[332]={0,7,14,21,28,35,42,49,56,63,70,77,84,91,98,105,112,119,126,133,140,147,154,161,168,175,182,189,196,203,210,217,224,231,238,245,252,259,266,273,280,287,294,301,308,315,322,329,336,343,350,357,364,371,378,385,392,399,406,413,420,427,434,441,448,455,462,469,476,483,490,497,504,511,518,525,532,539,546,553,560,567,574,581,588,595,602,609,616,623,630,637,644,651,658,665,672,679,686,693,700,707,714,721,728,735,742,749,756,763,770,777,784,791,798,805,812,819,826,833,840,847,854,861,868,875,882,889,896,903,910,917,924,931,938,945,952,959,966,973,980,987,994,1001,1008,1015,1022,1029,1036,1043,1050,1057,1064,1071,1078,1085,1092,1099,1106,1113,1120,1127,1134,1141,1148,1155,1162,1169,1176,1183,1190,1197,1204,1211,1218,1225,1232,1239,1246,1253,1260,1267,1274,1281,1288,1295,1302,1309,1316,1323,1330,1337,1344,1351,1358,1365,1372,1379,1386,1393,1400,1407,1414,1421,1428,1435,1442,1449,1456,1463,1470,1477,1484,1491,1498,1505,1512,1519,1526,1533,1540,1547,1554,1561,1568,1575,1582,1589,1596,1603,1610,1617,1624,1631,1638,1645,1652,1659,1666,1673,1680,1687,1694,1701,1708,1715,1722,1729,1736,1743,1750,1757,1764,1771,1778,1785,1792,1799,1806,1813,1820,1827,1834,1841,1848,1855,1862,1869,1876,1883,1890,1897,1901,1905,1909,1913,1917,1921,1925,1929,1933,1937,1941,1945,1949,1953,1957,1961,1965,1969,1973,1977,1981,1985,1989,1993,1997,2001,2005,2009,2013,2017,2021,2025,2029,2033,2037,2041,2045,2049,2053,2057,2061,2065,2069,2073,2077,2081,2085,2089,2093,2097,2101,2105,2109,2113,2117,2121,2125,2129,2133,2137}; + // + MEDCouplingUMesh *m=MEDCouplingUMesh::New("convexhull",2); + m->allocateCells(331); + for(int i=0;i<331;i++) + m->insertNextCell(INTERP_KERNEL::NORM_POLYGON,connI[i+1]-connI[i],conn+connI[i]); + m->finishInsertingCells(); + DataArrayDouble *coordsDa=DataArrayDouble::New(); + coordsDa->alloc(331,2); + std::copy(coords,coords+662,coordsDa->getPointer()); + m->setCoords(coordsDa); + coordsDa->decrRef(); + m->checkCoherency(); + // + DataArrayInt *da=m->convexEnvelop2D(); + m->checkCoherency(); + CPPUNIT_ASSERT(coordsDa==m->getCoords()); + DataArrayInt *daC=da->buildComplement(331); + da->decrRef(); + const int expected[58]={271,272,273,274,275,276,277,278,279,280,281,282,283,284,285,286,287,288,289,290,291,292,293,294,295,296,297,298,299,300,302,303,304,305,306,307,308,309,310,312,313,314,315,316,317,318,319,320,321,322,323,324,325,326,327,328,329,330}; + DataArrayInt *expected2=DataArrayInt::New(); + expected2->alloc(58,1); + std::copy(expected,expected+58,expected2->getPointer()); + CPPUNIT_ASSERT(expected2->isEqual(*daC)); + // + expected2->decrRef(); + daC->decrRef(); + // + MEDCouplingFieldDouble *valsF=m->getMeasureField(ON_CELLS); + DataArrayDouble *vals=valsF->getArray(); + const double ref[331]={184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,184.69493088478035,-61.564976961404426,-92.34746544254946,-92.34746544259811,-92.34746544253488,-92.3474654425349,-92.34746544180479,-92.34746544253493,-92.3474654419026,-92.34746544190256,-92.34746544253491,-61.564976961404426,-92.34746544254946,-92.34746544259811,-92.34746544253488,-92.3474654425349,-92.34746544180479,-92.34746544253493,-92.3474654419026,-92.34746544190256,-92.34746544253491,-61.564976961404426,-92.34746544254946,-92.34746544259811,-92.34746544253488,-92.3474654425349,-92.34746544180479,-92.34746544253493,-92.3474654419026,-92.34746544190256,-92.34746544253491,61.564976961404426,-92.34746544254946,-92.34746544259811,-92.34746544253488,-92.3474654425349,-92.34746544180479,-92.34746544253493,-92.3474654419026,-92.34746544190256,-92.34746544253491,61.564976961404426,-92.34746544254946,-92.34746544259811,-92.34746544253488,-92.3474654425349,-92.34746544180479,-92.34746544253493,-92.3474654419026,-92.34746544190256,-92.34746544253491,-61.564976961404426,-92.34746544254946,-92.34746544259811,-92.34746544253488,-92.3474654425349,-92.34746544180479,-92.34746544253493,-92.3474654419026,-92.34746544190256,-92.34746544253491}; + DataArrayDouble *ref2=DataArrayDouble::New(); ref2->alloc(331,1); std::copy(ref,ref+331,ref2->getPointer()); + vals->substractEqual(ref2); + ref2->decrRef(); + vals->abs(); + DataArrayInt *theTest=vals->getIdsInRange(-1.,1e-7); + CPPUNIT_ASSERT(theTest->isIdentity()); + CPPUNIT_ASSERT_EQUAL(331,theTest->getNumberOfTuples()); + theTest->decrRef(); + valsF->decrRef(); + // + m->decrRef(); +} + +void MEDCouplingBasicsTest5::testDataArraySort1() +{ + DataArrayInt *arr=DataArrayInt::New(); + CPPUNIT_ASSERT_THROW(arr->sort(true),INTERP_KERNEL::Exception);//no allocation + CPPUNIT_ASSERT_THROW(arr->sort(false),INTERP_KERNEL::Exception);//no allocation + const int values[6]={2,1,6,5,4,7}; + arr->alloc(3,2); + CPPUNIT_ASSERT_THROW(arr->sort(true),INTERP_KERNEL::Exception);//no one component + CPPUNIT_ASSERT_THROW(arr->sort(false),INTERP_KERNEL::Exception);//no one component + arr->rearrange(1); + std::copy(values,values+6,arr->getPointer()); + DataArrayInt *arr1=arr->deepCpy(); + DataArrayInt *arr2=arr->deepCpy(); + arr1->sort(true); + const int expected1[6]={1,2,4,5,6,7}; + CPPUNIT_ASSERT_EQUAL(6,arr1->getNumberOfTuples()); + CPPUNIT_ASSERT_EQUAL(1,arr1->getNumberOfComponents()); + CPPUNIT_ASSERT(std::equal(expected1,expected1+6,arr1->begin())); + arr2->sort(false); + const int expected2[6]={7,6,5,4,2,1}; + CPPUNIT_ASSERT_EQUAL(6,arr2->getNumberOfTuples()); + CPPUNIT_ASSERT_EQUAL(1,arr2->getNumberOfComponents()); + CPPUNIT_ASSERT(std::equal(expected2,expected2+6,arr2->begin())); + arr1->decrRef(); + arr2->decrRef(); + arr->decrRef(); + // + DataArrayDouble *ard=DataArrayDouble::New(); + CPPUNIT_ASSERT_THROW(ard->sort(true),INTERP_KERNEL::Exception);//no allocation + CPPUNIT_ASSERT_THROW(ard->sort(false),INTERP_KERNEL::Exception);//no allocation + const double valuesD[6]={2.,1.,6.,5.,4.,7.}; + ard->alloc(3,2); + CPPUNIT_ASSERT_THROW(ard->sort(true),INTERP_KERNEL::Exception);//no one component + CPPUNIT_ASSERT_THROW(ard->sort(false),INTERP_KERNEL::Exception);//no one component + ard->rearrange(1); + std::copy(valuesD,valuesD+6,ard->getPointer()); + DataArrayDouble *ard1=ard->deepCpy(); + DataArrayDouble *ard2=ard->deepCpy(); + ard1->sort(true); + const double expected3[6]={1.,2.,4.,5.,6.,7.}; + CPPUNIT_ASSERT_EQUAL(6,ard1->getNumberOfTuples()); + CPPUNIT_ASSERT_EQUAL(1,ard1->getNumberOfComponents()); + for(int i=0;i<6;i++) + CPPUNIT_ASSERT_DOUBLES_EQUAL(expected3[i],ard1->getIJ(i,0),1e-12); + ard2->sort(false); + const double expected4[6]={7.,6.,5.,4.,2.,1.}; + CPPUNIT_ASSERT_EQUAL(6,ard2->getNumberOfTuples()); + CPPUNIT_ASSERT_EQUAL(1,ard2->getNumberOfComponents()); + for(int i=0;i<6;i++) + CPPUNIT_ASSERT_DOUBLES_EQUAL(expected4[i],ard2->getIJ(i,0),1e-12); + ard1->decrRef(); + ard2->decrRef(); + ard->decrRef(); +} + +void MEDCouplingBasicsTest5::testPartitionBySpreadZone1() +{ + MEDCouplingUMesh *m=build2DTargetMesh_1(); + const int part0[3]={2,3,4}; + const int part1[2]={0,1}; + MEDCouplingUMesh *m1=static_cast<MEDCouplingUMesh *>(m->buildPartOfMySelf(part0,part0+3)); + MEDCouplingUMesh *m2=static_cast<MEDCouplingUMesh *>(m->buildPartOfMySelf(part1,part1+2)); + std::vector<const MEDCouplingUMesh *> v(3); v[0]=m; v[1]=m1; v[2]=m2; + MEDCouplingUMesh *m4=MEDCouplingUMesh::MergeUMeshes(v); + const int renum[10]={5,2,9,6,4,7,0,1,3,8}; + m4->renumberCells(renum); + // + std::vector<DataArrayInt *> v2=m4->partitionBySpreadZone(); + CPPUNIT_ASSERT_EQUAL(3,(int)v2.size()); + const int expected0[3]={0,1,7}; + const int expected1[5]={2,4,5,6,9}; + const int expected2[2]={3,8}; + CPPUNIT_ASSERT_EQUAL(3,v2[0]->getNumberOfTuples()); + CPPUNIT_ASSERT_EQUAL(1,v2[0]->getNumberOfComponents()); + CPPUNIT_ASSERT_EQUAL(5,v2[1]->getNumberOfTuples()); + CPPUNIT_ASSERT_EQUAL(1,v2[1]->getNumberOfComponents()); + CPPUNIT_ASSERT_EQUAL(2,v2[2]->getNumberOfTuples()); + CPPUNIT_ASSERT_EQUAL(1,v2[2]->getNumberOfComponents()); + // + CPPUNIT_ASSERT(std::equal(expected0,expected0+3,v2[0]->getConstPointer())); + CPPUNIT_ASSERT(std::equal(expected1,expected1+5,v2[1]->getConstPointer())); + CPPUNIT_ASSERT(std::equal(expected2,expected2+2,v2[2]->getConstPointer())); + v2[0]->decrRef(); + v2[1]->decrRef(); + v2[2]->decrRef(); + // + MEDCouplingUMesh *m5=m4->buildSpreadZonesWithPoly(); + CPPUNIT_ASSERT_EQUAL(3,m5->getNumberOfCells()); + CPPUNIT_ASSERT(m5->getCoords()==m4->getCoords()); + const int expected3[23]={5,15,16,17,14,11,13,12,5,2,1,0,3,6,7,8,5,5,18,21,22,20,19}; + const int expected4[4]={0,8,17,23}; + CPPUNIT_ASSERT_EQUAL(23,m5->getNodalConnectivity()->getNumberOfTuples()); + CPPUNIT_ASSERT(std::equal(expected3,expected3+23,m5->getNodalConnectivity()->getConstPointer())); + CPPUNIT_ASSERT_EQUAL(4,m5->getNodalConnectivityIndex()->getNumberOfTuples()); + CPPUNIT_ASSERT(std::equal(expected4,expected4+4,m5->getNodalConnectivityIndex()->getConstPointer())); + // + m->decrRef(); + m1->decrRef(); + m2->decrRef(); + m4->decrRef(); + m5->decrRef(); +} + +void MEDCouplingBasicsTest5::testGiveCellsWithType1() +{ + const int expected0[2]={1,2}; + const int expected1[3]={0,3,4}; + MEDCouplingUMesh *m=build2DTargetMesh_1(); + DataArrayInt *da=m->giveCellsWithType(INTERP_KERNEL::NORM_TRI3); + CPPUNIT_ASSERT_EQUAL(2,da->getNumberOfTuples()); + CPPUNIT_ASSERT_EQUAL(1,da->getNumberOfComponents()); + CPPUNIT_ASSERT(std::equal(expected0,expected0+2,da->getConstPointer())); + da->decrRef(); + // + da=m->giveCellsWithType(INTERP_KERNEL::NORM_QUAD4); + CPPUNIT_ASSERT_EQUAL(3,da->getNumberOfTuples()); + CPPUNIT_ASSERT_EQUAL(1,da->getNumberOfComponents()); + CPPUNIT_ASSERT(std::equal(expected1,expected1+3,da->getConstPointer())); + da->decrRef(); + // + da=m->giveCellsWithType(INTERP_KERNEL::NORM_TRI6); + CPPUNIT_ASSERT_EQUAL(0,da->getNumberOfTuples()); + CPPUNIT_ASSERT_EQUAL(1,da->getNumberOfComponents()); + da->decrRef(); + // + CPPUNIT_ASSERT_THROW(m->giveCellsWithType(INTERP_KERNEL::NORM_SEG2),INTERP_KERNEL::Exception); + CPPUNIT_ASSERT_THROW(m->giveCellsWithType(INTERP_KERNEL::NORM_HEXA8),INTERP_KERNEL::Exception); + // + m->decrRef(); +} + +void MEDCouplingBasicsTest5::testBuildSlice3D2() +{ + MEDCouplingUMesh *mesh2D=0; + MEDCouplingUMesh *mesh3D=build3DExtrudedUMesh_1(mesh2D); + mesh2D->decrRef(); + // First slice in the middle of 3D cells + const double vec1[3]={-0.07,1.,0.07}; + const double origin1[3]={1.524,1.4552,1.74768}; + DataArrayInt *ids=0; + MEDCouplingUMesh *slice1=mesh3D->buildSlice3D(origin1,vec1,1e-10,ids); + // + MEDCouplingFieldDouble *f=MEDCouplingFieldDouble::New(ON_CELLS,ONE_TIME); + f->setTime(4.5,6,7) ; f->setMesh(mesh3D); + DataArrayDouble *arr=DataArrayDouble::New(); arr->alloc(mesh3D->getNumberOfCells(),2); + arr->rearrange(1); arr->iota(2.); arr->rearrange(2); + f->setArray(arr); + f->checkCoherency(); + const int exp1[9]={1,3,4,7,9,10,13,15,16}; + DataArrayInt *expected1=DataArrayInt::New(); expected1->alloc(9,1); std::copy(exp1,exp1+9,expected1->getPointer()); + CPPUNIT_ASSERT(expected1->isEqual(*ids)); + DataArrayDouble *arr2=arr->selectByTupleIdSafe(expected1->begin(),expected1->end()); + // + MEDCouplingFieldDouble *f2=f->extractSlice3D(origin1,vec1,1e-10); + CPPUNIT_ASSERT(f2->getArray()->isEqual(*arr2,1e-12)); + CPPUNIT_ASSERT(slice1->isEqual(f2->getMesh(),1e-12)); + int a,b; + double c=f2->getTime(a,b); + CPPUNIT_ASSERT_EQUAL(6,a); + CPPUNIT_ASSERT_EQUAL(7,b); + CPPUNIT_ASSERT_DOUBLES_EQUAL(4.5,c,1e-12); + // + ids->decrRef(); + slice1->decrRef(); + arr2->decrRef(); + arr->decrRef(); + f2->decrRef(); + f->decrRef(); + mesh3D->decrRef(); + expected1->decrRef(); +} + +void MEDCouplingBasicsTest5::testComputeTupleIdsToSelectFromCellIds1() +{ + MEDCouplingUMesh *m=build2DTargetMesh_3(); + MEDCouplingFieldDouble *f=MEDCouplingFieldDouble::New(ON_GAUSS_NE,NO_TIME); + f->setMesh(m); + DataArrayDouble *arr=DataArrayDouble::New(); arr->alloc(52,2) ; arr->rearrange(1) ; arr->iota(7.); arr->rearrange(2); + f->setArray(arr); + // + const int subPart1[3]={1,5,9}; + MEDCouplingFieldDouble *f2=f->buildSubPart(subPart1,subPart1+3); + f2->checkCoherency(); + DataArrayInt *cI=m->computeNbOfNodesPerCell(); + cI->computeOffsets2(); + const int sel1[3]={1,5,9}; + DataArrayInt *sel=DataArrayInt::New(); sel->useArray(sel1,false,CPP_DEALLOC,3,1); + DataArrayInt *res=sel->buildExplicitArrByRanges(cI); + DataArrayDouble *arr2=arr->selectByTupleIdSafe(res->begin(),res->end()); + const double expected1[30]={13.,14.,15.,16.,17.,18.,19.,20.,59.,60.,61.,62.,63.,64.,95.,96.,97.,98.,99.,100.,101.,102.,103.,104.,105.,106.,107.,108.,109.,110.}; + DataArrayDouble *arr3=DataArrayDouble::New(); arr3->useArray(expected1,false,CPP_DEALLOC,15,2); + CPPUNIT_ASSERT(arr2->isEqual(*arr3,1e-12)); + CPPUNIT_ASSERT(arr2->isEqual(*f2->getArray(),1e-12)); + // + cI->decrRef(); + arr3->decrRef(); + arr2->decrRef(); + arr->decrRef(); + m->decrRef(); + f->decrRef(); + f2->decrRef(); + sel->decrRef(); + res->decrRef(); +} + +void MEDCouplingBasicsTest5::testComputeSkin1() +{ + const double input1[5]={2.,3.4,5.6,7.7,8.0}; + const double input2[6]={2.,3.4,5.6,7.7,9.0,14.2}; + DataArrayDouble *arrX=DataArrayDouble::New(); arrX->alloc(5,1); std::copy(input1,input1+5,arrX->getPointer()); + DataArrayDouble *arrY=DataArrayDouble::New(); arrY->alloc(6,1); std::copy(input2,input2+6,arrY->getPointer()); + MEDCouplingCMesh *cmesh=MEDCouplingCMesh::New() ; cmesh->setCoordsAt(0,arrX) ; cmesh->setCoordsAt(1,arrY); + MEDCouplingUMesh *umesh=cmesh->buildUnstructured(); + cmesh->decrRef(); arrX->decrRef(); arrY->decrRef(); + // + MEDCouplingUMesh *skin=umesh->computeSkin(); + CPPUNIT_ASSERT_EQUAL(18,skin->getNumberOfCells()); + CPPUNIT_ASSERT_EQUAL(1,skin->getMeshDimension()); + CPPUNIT_ASSERT(skin->getCoords()==umesh->getCoords()); + const int expected1[19]={0,3,6,9,12,15,18,21,24,27,30,33,36,39,42,45,48,51,54}; + const int expected2[54]={1,1,0,1,0,5,1,2,1,1,3,2,1,4,3,1,9,4,1,5,10,1,14,9,1,10,15,1,19,14,1,15,20,1,24,19,1,20,25,1,25,26,1,26,27,1,27,28,1,28,29,1,29,24}; + CPPUNIT_ASSERT_EQUAL((std::size_t)19,skin->getNodalConnectivityIndex()->getNbOfElems()); + CPPUNIT_ASSERT(std::equal(expected1,expected1+19,skin->getNodalConnectivityIndex()->getConstPointer())); + CPPUNIT_ASSERT_EQUAL((std::size_t)54,skin->getNodalConnectivity()->getNbOfElems()); + CPPUNIT_ASSERT(std::equal(expected2,expected2+54,skin->getNodalConnectivity()->getConstPointer())); + DataArrayInt *ids=skin->computeFetchedNodeIds(); + const int expected3[18]={0,1,2,3,4,5,9,10,14,15,19,20,24,25,26,27,28,29}; + CPPUNIT_ASSERT_EQUAL((std::size_t)18,ids->getNbOfElems()); + CPPUNIT_ASSERT(std::equal(expected3,expected3+18,ids->getConstPointer())); + MEDCouplingUMesh *part=dynamic_cast<MEDCouplingUMesh *>(umesh->buildFacePartOfMySelfNode(ids->begin(),ids->end(),true)); + part->setName(skin->getName().c_str()); + CPPUNIT_ASSERT(part->isEqual(skin,1e-12)); + MEDCouplingUMesh *part2=dynamic_cast<MEDCouplingUMesh *>(part->buildPartOfMySelf2(1,18,2,true)); + DataArrayInt *ids2=DataArrayInt::Range(0,18,2); + part->setPartOfMySelf(ids2->begin(),ids2->end(),*part2); + ids2->decrRef(); + CPPUNIT_ASSERT(!part->isEqual(skin,1e-12)); + DataArrayInt *trad=part->zipConnectivityTraducer(0); + CPPUNIT_ASSERT_EQUAL(9,part->getNumberOfCells()); + const int expected4[18]={0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8}; + CPPUNIT_ASSERT(std::equal(expected4,expected4+18,trad->getConstPointer())); + CPPUNIT_ASSERT_EQUAL((std::size_t)18,trad->getNbOfElems()); + trad->decrRef(); + part->decrRef(); + part2->decrRef(); + // + ids->decrRef(); + umesh->decrRef(); + skin->decrRef(); +} + +void MEDCouplingBasicsTest5::testUMeshSetPartOfMySelf2() +{ + // resize with explicit ids list + MEDCouplingUMesh *m=build2DTargetMesh_1(); + std::set<INTERP_KERNEL::NormalizedCellType> s; s.insert(INTERP_KERNEL::NORM_TRI3); s.insert(INTERP_KERNEL::NORM_QUAD4); + CPPUNIT_ASSERT(s==m->getAllGeoTypes()); + const int ids1[3]={0,3,4}; + MEDCouplingUMesh *part=static_cast<MEDCouplingUMesh *>(m->buildPartOfMySelf(ids1,ids1+3,true)); + part->simplexize(0)->decrRef(); + const int ids2[3]={1,2,5}; + MEDCouplingUMesh *part2=static_cast<MEDCouplingUMesh *>(part->buildPartOfMySelf(ids2,ids2+3,true)); + m->setPartOfMySelf(ids1,ids1+3,*part2); + const int expected1[20]={3,0,4,1,3,1,4,2,3,4,5,2,3,6,7,4,3,7,5,4}; + CPPUNIT_ASSERT(std::equal(expected1,expected1+20,m->getNodalConnectivity()->getConstPointer())); + CPPUNIT_ASSERT_EQUAL((std::size_t)20,m->getNodalConnectivity()->getNbOfElems()); + const int expected2[6]={0,4,8,12,16,20}; + CPPUNIT_ASSERT(std::equal(expected2,expected2+6,m->getNodalConnectivityIndex()->getConstPointer())); + CPPUNIT_ASSERT_EQUAL((std::size_t)6,m->getNodalConnectivityIndex()->getNbOfElems()); + s.clear(); s.insert(INTERP_KERNEL::NORM_TRI3); + CPPUNIT_ASSERT(s==m->getAllGeoTypes()); + m->decrRef(); part->decrRef(); part2->decrRef(); + // no resize with explicit ids list + m=build2DTargetMesh_1(); + part=static_cast<MEDCouplingUMesh *>(m->buildPartOfMySelf(ids1,ids1+2,true)); + part->convertAllToPoly(); + m->setPartOfMySelf(ids1+1,ids1+3,*part); + const int expected3[23]={4,0,3,4,1,3,1,4,2,3,4,5,2,5,0,3,4,1,5,6,7,4,3}; + CPPUNIT_ASSERT(std::equal(expected3,expected3+23,m->getNodalConnectivity()->getConstPointer())); + CPPUNIT_ASSERT_EQUAL((std::size_t)23,m->getNodalConnectivity()->getNbOfElems()); + const int expected4[6]={0,5,9,13,18,23}; + CPPUNIT_ASSERT(std::equal(expected4,expected4+6,m->getNodalConnectivityIndex()->getConstPointer())); + CPPUNIT_ASSERT_EQUAL((std::size_t)6,m->getNodalConnectivityIndex()->getNbOfElems()); + s.clear(); s.insert(INTERP_KERNEL::NORM_TRI3); s.insert(INTERP_KERNEL::NORM_QUAD4); s.insert(INTERP_KERNEL::NORM_POLYGON); + CPPUNIT_ASSERT(s==m->getAllGeoTypes()); + m->decrRef(); part->decrRef(); + // resize with range ids + m=build2DTargetMesh_1(); + part=static_cast<MEDCouplingUMesh *>(m->buildPartOfMySelf2(3,5,1,true)); + m->setPartOfMySelf2(1,3,1,*part); + const int expected5[25]={4,0,3,4,1,4,6,7,4,3,4,7,8,5,4,4,6,7,4,3,4,7,8,5,4}; + CPPUNIT_ASSERT(std::equal(expected5,expected5+25,m->getNodalConnectivity()->getConstPointer())); + CPPUNIT_ASSERT_EQUAL((std::size_t)25,m->getNodalConnectivity()->getNbOfElems()); + const int expected6[6]={0,5,10,15,20,25}; + CPPUNIT_ASSERT(std::equal(expected6,expected6+6,m->getNodalConnectivityIndex()->getConstPointer())); + CPPUNIT_ASSERT_EQUAL((std::size_t)6,m->getNodalConnectivityIndex()->getNbOfElems()); + s.clear(); s.insert(INTERP_KERNEL::NORM_QUAD4); + CPPUNIT_ASSERT(s==m->getAllGeoTypes()); + m->decrRef(); part->decrRef(); + // no resize with range ids + m=build2DTargetMesh_1(); + part=static_cast<MEDCouplingUMesh *>(m->buildPartOfMySelf2(0,5,3,true)); + part->convertAllToPoly(); + m->setPartOfMySelf2(3,5,1,*part); + const int expected7[23]={4,0,3,4,1,3,1,4,2,3,4,5,2,5,0,3,4,1,5,6,7,4,3}; + CPPUNIT_ASSERT(std::equal(expected7,expected7+23,m->getNodalConnectivity()->getConstPointer())); + CPPUNIT_ASSERT_EQUAL((std::size_t)23,m->getNodalConnectivity()->getNbOfElems()); + const int expected8[6]={0,5,9,13,18,23}; + CPPUNIT_ASSERT(std::equal(expected8,expected8+6,m->getNodalConnectivityIndex()->getConstPointer())); + CPPUNIT_ASSERT_EQUAL((std::size_t)6,m->getNodalConnectivityIndex()->getNbOfElems()); +s.clear(); s.insert(INTERP_KERNEL::NORM_TRI3); s.insert(INTERP_KERNEL::NORM_QUAD4); s.insert(INTERP_KERNEL::NORM_POLYGON); + CPPUNIT_ASSERT(s==m->getAllGeoTypes()); + m->decrRef(); part->decrRef(); + // no resize with range ids negative direction + m=build2DTargetMesh_1(); + part=static_cast<MEDCouplingUMesh *>(m->buildPartOfMySelf2(3,-1,-3,true)); + part->convertAllToPoly(); + m->setPartOfMySelf2(4,2,-1,*part); + const int expected9[23]={4,0,3,4,1,3,1,4,2,3,4,5,2,5,0,3,4,1,5,6,7,4,3}; + CPPUNIT_ASSERT(std::equal(expected9,expected9+23,m->getNodalConnectivity()->getConstPointer())); + CPPUNIT_ASSERT_EQUAL((std::size_t)23,m->getNodalConnectivity()->getNbOfElems()); + const int expected10[6]={0,5,9,13,18,23}; + CPPUNIT_ASSERT(std::equal(expected10,expected10+6,m->getNodalConnectivityIndex()->getConstPointer())); + CPPUNIT_ASSERT_EQUAL((std::size_t)6,m->getNodalConnectivityIndex()->getNbOfElems()); + s.clear(); s.insert(INTERP_KERNEL::NORM_TRI3); s.insert(INTERP_KERNEL::NORM_QUAD4); s.insert(INTERP_KERNEL::NORM_POLYGON); + CPPUNIT_ASSERT(s==m->getAllGeoTypes()); + part->decrRef(); + m->decrRef(); +} + +void MEDCouplingBasicsTest5::testUnPolyze3() +{ + const double coord[18]={0.0,0.5,-0.5,-0.5,-0.5,-0.5,0.5,-0.5,-0.5,0.0,0.5,0.5,-0.5,-0.5,0.5,0.5,-0.5,0.5}; + const int conn[22]={1,2,5,4,-1,4,3,0,1,-1,2,0,3,5,-1,0,2,1,-1,4,5,3}; + MEDCouplingUMesh *m=MEDCouplingUMesh::New("a mesh",3); + m->allocateCells(1); + m->insertNextCell(INTERP_KERNEL::NORM_POLYHED,22,conn); + m->finishInsertingCells(); + DataArrayDouble *coords=DataArrayDouble::New(); + coords->alloc(6,3); + std::copy(coord,coord+18,coords->getPointer()); + m->setCoords(coords); + coords->decrRef(); + m->checkCoherency(); + // + MEDCouplingFieldDouble *vol=m->getMeasureField(ON_CELLS); + CPPUNIT_ASSERT_EQUAL(1,vol->getArray()->getNumberOfTuples()); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.5,vol->getArray()->getIJ(0,0),1e-12); + vol->decrRef(); + // + m->unPolyze(); + CPPUNIT_ASSERT_EQUAL(1,m->getNumberOfCells()); + std::set<INTERP_KERNEL::NormalizedCellType> s; s.insert(INTERP_KERNEL::NORM_PENTA6); + CPPUNIT_ASSERT(s==m->getAllGeoTypes()); + // + const int expected1[2]={0,7}; + const int expected2[7]={16,0,2,1,3,5,4}; + CPPUNIT_ASSERT_EQUAL(2,m->getNodalConnectivityIndex()->getNumberOfTuples()); + CPPUNIT_ASSERT(std::equal(expected1,expected1+2,m->getNodalConnectivityIndex()->getConstPointer())); + CPPUNIT_ASSERT_EQUAL(7,m->getNodalConnectivity()->getNumberOfTuples()); + CPPUNIT_ASSERT(std::equal(expected2,expected2+7,m->getNodalConnectivity()->getConstPointer())); + // + vol=m->getMeasureField(ON_CELLS); + CPPUNIT_ASSERT_EQUAL(1,vol->getArray()->getNumberOfTuples()); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.5,vol->getArray()->getIJ(0,0),1e-12); + vol->decrRef(); + // + m->decrRef(); +} + +void MEDCouplingBasicsTest5::testKrSpatialDiscretization1() +{ + const double srcPointCoordsX[10]={0.8401877171547095, 0.7830992237586059, 0.9116473579367843, 0.335222755714889, 0.2777747108031878, 0.4773970518621602, 0.3647844727918433, 0.9522297251747128, 0.6357117279599009, 0.1416025553558034}; + const double srcFieldValsOnPoints[10]={2.129892434968836, 2.295320474540621, 1.931948594981134, 2.728013590937196, 2.715603240418478, 2.661778472822935, 2.695696990104364, 1.893710234970982, 2.529628016549284, 2.728432341300668}; + const double targetPointCoordsX[40]={-0.5,-0.45,-0.4,-0.35,-0.3,-0.25,-0.2,-0.15,-0.1,-0.05,-6.93889390391e-17,0.05,0.1,0.15,0.2,0.25,0.3,0.35,0.4,0.45,0.5,0.55,0.6,0.65,0.7,0.75,0.8,0.85,0.9,0.95,1.0,1.05,1.1,1.15,1.2,1.25,1.3,1.35,1.4,1.45}; + const double targetFieldValsExpected[40]={2.975379475824351, 2.95613491917003, 2.936890362515361, 2.917645805861018, 2.898401249206574, 2.879156692552137, 2.859912135897732, 2.840667579243201, 2.821423022588731, 2.802178465934342, 2.78293390927989, 2.763689352625457, 2.744444795971001, 2.725209522098197, 2.709077577124666, 2.706677252549218, 2.727467797847971, 2.713338094723676, 2.671342424824244, 2.664877370146978, 2.653840141412181, 2.619607861392791, 2.569777214476479, 2.513263929794591, 2.450732752808528, 2.368313560985155, 2.250909795670307, 2.098194272085416, 1.954257891732065, 1.895040660973802, 1.865256788315972, 1.835475248687992, 1.80569370905998, 1.775912169431971, 1.746130629803976, 1.716349090175918, 1.686567550547855, 1.656786010919941, 1.627004471291988, 1.597222931663817}; + // + int nbOfInputPoints=10; + MEDCouplingFieldDouble *f=MEDCouplingFieldDouble::New(ON_NODES_KR,ONE_TIME); + DataArrayDouble *srcArrX=DataArrayDouble::New(); + srcArrX->alloc(nbOfInputPoints,1); + std::copy(srcPointCoordsX,srcPointCoordsX+nbOfInputPoints,srcArrX->getPointer()); + MEDCouplingCMesh *cmesh=MEDCouplingCMesh::New("aMesh"); + cmesh->setCoordsAt(0,srcArrX); + MEDCouplingUMesh *umesh=cmesh->buildUnstructured(); + f->setMesh(umesh); + DataArrayDouble *srcVals=DataArrayDouble::New(); + srcVals->alloc(nbOfInputPoints,1); + std::copy(srcFieldValsOnPoints,srcFieldValsOnPoints+nbOfInputPoints,srcVals->getPointer()); + f->setArray(srcVals); + f->checkCoherency(); + // + double *res0=new double[1]; + f->getValueOn(targetPointCoordsX,res0); + CPPUNIT_ASSERT_DOUBLES_EQUAL(targetFieldValsExpected[0],res0[0],1e-10); + delete [] res0; + // + DataArrayDouble *valuesToTest=f->getValueOnMulti(targetPointCoordsX,40); + CPPUNIT_ASSERT_EQUAL(40,valuesToTest->getNumberOfTuples()); + CPPUNIT_ASSERT_EQUAL(1,valuesToTest->getNumberOfComponents()); + for(int i=0;i<40;i++) + CPPUNIT_ASSERT_DOUBLES_EQUAL(targetFieldValsExpected[i],valuesToTest->getIJ(i,0),1e-10); + valuesToTest->decrRef(); + // + cmesh->decrRef(); + umesh->decrRef(); + srcArrX->decrRef(); + srcVals->decrRef(); + f->decrRef(); +} + +void MEDCouplingBasicsTest5::testDuplicateEachTupleNTimes1() +{ + const double vals0[4]={9.,8.,7.,6.}; + DataArrayDouble *d=DataArrayDouble::New(); d->useArray(vals0,false,CPP_DEALLOC,4,1); d->setInfoOnComponent(0,"mass [kg]"); d->setName("aname"); + DataArrayDouble *d2=d->duplicateEachTupleNTimes(3); + const double vals1[12]={9.,9.,9.,8.,8.,8.,7.,7.,7.,6.,6.,6.}; + DataArrayDouble *d3=DataArrayDouble::New(); d3->useArray(vals1,false,CPP_DEALLOC,4*3,1); d3->setName("aname"); d3->setInfoOnComponent(0,"mass [kg]"); + CPPUNIT_ASSERT(d2->isEqual(*d2,1e-14)); d3->decrRef(); + d->decrRef(); + d2->decrRef(); + // + const int vals2[4]={9,8,7,6}; + DataArrayInt *d4=DataArrayInt::New(); d4->useArray(vals2,false,CPP_DEALLOC,4,1); d4->setInfoOnComponent(0,"mass [kg]") ; d4->setName("aname"); + DataArrayInt *d5=d4->duplicateEachTupleNTimes(3); + const int vals3[12]={9,9,9,8,8,8,7,7,7,6,6,6}; + DataArrayInt *d6=DataArrayInt::New(); d6->useArray(vals3,false,CPP_DEALLOC,4*3,1); d6->setName("aname"); d6->setInfoOnComponent(0,"mass [kg]"); + CPPUNIT_ASSERT(d5->isEqual(*d6)); d6->decrRef(); + d4->decrRef(); + d5->decrRef(); +} + +void MEDCouplingBasicsTest5::testIntersect2DMeshesTmp5() +{ + // coordinates + DataArrayDouble *coords=DataArrayDouble::New(); + const double coordsData[376]={41,0,42,0,0,42,0,41,41.5,0,29.698484809834998,29.698484809834994,0,41.5,28.991378028648452,28.991378028648445,-42,0,-41,0,-29.698484809834994,29.698484809834998,-41.5,0,-28.991378028648445,28.991378028648452,0,-42,0,-41,-29.698484809835001,-29.698484809834994,0,-41.5,-28.991378028648455,-28.991378028648445,29.698484809834987,-29.698484809835001,28.991378028648441,-28.991378028648455,43,0,0,43,42.5,0,30.405591591021544,30.40559159102154,0,42.5,-43,0,-30.40559159102154,30.405591591021544,-42.5,0,0,-43,-30.405591591021551,-30.40559159102154,0,-42.5,30.405591591021537,-30.405591591021551,44,0,0,44,43.5,0,31.112698372208094,31.112698372208087,0,43.5,-44,0,-31.112698372208087,31.112698372208094,-43.5,0,0,-44,-31.112698372208097,-31.112698372208087,0,-43.5,31.112698372208083,-31.112698372208097,45,0,0,45,44.5,0,31.81980515339464,31.819805153394636,0,44.5,-45,0,-31.819805153394636,31.81980515339464,-44.5,0,0,-45,-31.819805153394647,-31.819805153394636,0,-44.5,31.819805153394629,-31.819805153394647,47,0,0,47,46,0,33.234018715767739,33.234018715767732,0,46,-47,0,-33.234018715767732,33.234018715767739,-46,0,0,-47,-33.234018715767739,-33.234018715767732,0,-46,33.234018715767725,-33.234018715767739,49,0,0,49,48,0,34.648232278140831,34.648232278140824,0,48,-49,0,-34.648232278140824,34.648232278140831,-48,0,0,-49,-34.648232278140839,-34.648232278140824,0,-48,34.648232278140817,-34.648232278140839,51,0,0,51,50,0,36.062445840513924,36.062445840513924,0,50,-51,0,-36.062445840513924,36.062445840513924,-50,0,0,-51,-36.062445840513931,-36.062445840513924,0,-50,36.062445840513917,-36.062445840513931,53,0,0,53,52,0,37.476659402887023,37.476659402887016,0,52,-53,0,-37.476659402887016,37.476659402887023,-52,0,0,-53,-37.47665940288703,-37.476659402887016,0,-52,37.476659402887009,-37.47665940288703,55,0,0,55,54,0,38.890872965260115,38.890872965260108,0,54,-55,0,-38.890872965260108,38.890872965260115,-54,0,0,-55,-38.890872965260122,-38.890872965260108,0,-54,38.890872965260101,-38.890872965260122,59,0,0,59,57,0,41.719300090006307,41.7193000900063,0,57,-59,0,-41.7193000900063,41.719300090006307,-57,0,0,-59,-41.719300090006314,-41.7193000900063,0,-57,41.719300090006293,-41.719300090006314,63,0,0,63,61,0,44.547727214752499,44.547727214752491,0,61,-63,0,-44.547727214752491,44.547727214752499,-61,0,0,-63,-44.547727214752506,-44.547727214752491,0,-61,44.547727214752484,-44.547727214752506,67,0,0,67,65,0,47.37615433949869,47.376154339498683,0,65,-67,0,-47.376154339498683,47.37615433949869,-65,0,0,-67,-47.376154339498697,-47.376154339498683,0,-65,47.376154339498676,-47.376154339498697,71,0,0,71,69,0,50.204581464244875,50.204581464244868,0,69,-71,0,-50.204581464244868,50.204581464244875,-69,0,0,-71,-50.204581464244889,-50.204581464244868,0,-69,50.20458146424486,-50.204581464244889,75,0,0,75,73,0,53.033008588991066,53.033008588991059,0,73,-75,0,-53.033008588991059,53.033008588991066,-73,0,0,-75,-53.033008588991073,-53.033008588991059,0,-73,53.033008588991052,-53.033008588991073,80,0,0,80,77.5,0,56.568542494923804,56.568542494923797,0,77.5,-80,0,-56.568542494923797,56.568542494923804,-77.5,0,0,-80,-56.568542494923818,-56.568542494923797,0,-77.5,56.56854249492379,-56.568542494923818}; + coords->useArray(coordsData,false,CPP_DEALLOC,188,2); + coords->setName(""); + DataArrayInt *conn=DataArrayInt::New(); + const int connData[540]={8,0,1,2,3,4,5,6,7,8,3,2,8,9,6,10,11,12,8,9,8,13,14,11,15,16,17,8,14,13,1,0,16,18,4,19,8,1,20,21,2,22,23,24,5,8,2,21,25,8,24,26,27,10,8,8,25,28,13,27,29,30,15,8,13,28,20,1,30,31,22,18,8,20,32,33,21,34,35,36,23,8,21,33,37,25,36,38,39,26,8,25,37,40,28,39,41,42,29,8,28,40,32,20,42,43,34,31,8,32,44,45,33,46,47,48,35,8,33,45,49,37,48,50,51,38,8,37,49,52,40,51,53,54,41,8,40,52,44,32,54,55,46,43,8,44,56,57,45,58,59,60,47,8,45,57,61,49,60,62,63,50,8,49,61,64,52,63,65,66,53,8,52,64,56,44,66,67,58,55,8,56,68,69,57,70,71,72,59,8,57,69,73,61,72,74,75,62,8,61,73,76,64,75,77,78,65,8,64,76,68,56,78,79,70,67,8,68,80,81,69,82,83,84,71,8,69,81,85,73,84,86,87,74,8,73,85,88,76,87,89,90,77,8,76,88,80,68,90,91,82,79,8,80,92,93,81,94,95,96,83,8,81,93,97,85,96,98,99,86,8,85,97,100,88,99,101,102,89,8,88,100,92,80,102,103,94,91,8,92,104,105,93,106,107,108,95,8,93,105,109,97,108,110,111,98,8,97,109,112,100,111,113,114,101,8,100,112,104,92,114,115,106,103,8,104,116,117,105,118,119,120,107,8,105,117,121,109,120,122,123,110,8,109,121,124,112,123,125,126,113,8,112,124,116,104,126,127,118,115,8,116,128,129,117,130,131,132,119,8,117,129,133,121,132,134,135,122,8,121,133,136,124,135,137,138,125,8,124,136,128,116,138,139,130,127,8,128,140,141,129,142,143,144,131,8,129,141,145,133,144,146,147,134,8,133,145,148,136,147,149,150,137,8,136,148,140,128,150,151,142,139,8,140,152,153,141,154,155,156,143,8,141,153,157,145,156,158,159,146,8,145,157,160,148,159,161,162,149,8,148,160,152,140,162,163,154,151,8,152,164,165,153,166,167,168,155,8,153,165,169,157,168,170,171,158,8,157,169,172,160,171,173,174,161,8,160,172,164,152,174,175,166,163,8,164,176,177,165,178,179,180,167,8,165,177,181,169,180,182,183,170,8,169,181,184,172,183,185,186,173,8,172,184,176,164,186,187,178,175}; + conn->useArray(connData,false,CPP_DEALLOC,540,1); + conn->setName(""); + DataArrayInt *connI=DataArrayInt::New(); + const int connIData[61]={0,9,18,27,36,45,54,63,72,81,90,99,108,117,126,135,144,153,162,171,180,189,198,207,216,225,234,243,252,261,270,279,288,297,306,315,324,333,342,351,360,369,378,387,396,405,414,423,432,441,450,459,468,477,486,495,504,513,522,531,540}; + connI->useArray(connIData,false,CPP_DEALLOC,61,1); + connI->setName(""); + // + MEDCouplingUMesh *m1=MEDCouplingUMesh::New("Fix",2); + m1->setCoords(coords); + m1->setConnectivity(conn,connI,true); + coords->decrRef(); conn->decrRef(); connI->decrRef(); + // + coords=DataArrayDouble::New(); + const double coordsData2[84]={46.5,-2.5,53.5,-2.5,53.5,2.5,46.5,2.5,50,-2.5,53.5,0,50,2.5,46.5,0,60.5,-2.5,60.5,2.5,57,-2.5,60.5,0,57,2.5,53.5,7.5,46.5,7.5,53.5,5,50,7.5,46.5,5,60.5,7.5,60.5,5,57,7.5,-2,47,2,47,2,53,-2,53,0,47,2,50,0,53,-2,50,6,47,6,53,4,47,6,50,4,53,2,59,-2,59,2,56,0,59,-2,56,6,59,6,56,4,59}; + coords->useArray(coordsData2,false,CPP_DEALLOC,42,2); + coords->setName(""); + // connectivity + conn=DataArrayInt::New(); + const int connData2[72]={8,0,1,2,3,4,5,6,7,8,1,8,9,2,10,11,12,5,8,3,2,13,14,6,15,16,17,8,2,9,18,13,12,19,20,15,8,21,22,23,24,25,26,27,28,8,22,29,30,23,31,32,33,26,8,24,23,34,35,27,36,37,38,8,23,30,39,34,33,40,41,36}; + conn->useArray(connData2,false,CPP_DEALLOC,72,1); + conn->setName(""); + connI=DataArrayInt::New(); + const int connIData2[9]={0,9,18,27,36,45,54,63,72}; + connI->useArray(connIData2,false,CPP_DEALLOC,9,1); + connI->setName(""); + MEDCouplingUMesh *m2=MEDCouplingUMesh::New("Mobile",2); + m2->setCoords(coords); + m2->setConnectivity(conn,connI,true); + coords->decrRef(); conn->decrRef(); connI->decrRef(); + // + DataArrayInt *d1=0,*d2=0; + MEDCouplingUMesh *m3=MEDCouplingUMesh::Intersect2DMeshes(m1,m2,1e-10,d1,d2); + CPPUNIT_ASSERT_EQUAL(105,m3->getNumberOfCells()); + CPPUNIT_ASSERT_EQUAL(105,d1->getNumberOfTuples()); + CPPUNIT_ASSERT_EQUAL(105,d2->getNumberOfTuples()); + CPPUNIT_ASSERT_EQUAL(704,m3->getNumberOfNodes()); + // + const double areaExpected[105]={-65.18804756198824,-65.18804756198824,-65.18804756198824,-65.18804756198824,-66.75884388878285,-66.75884388878285,-66.7588438887833,-66.75884388878308,-68.32964021557768,-68.32964021557768,-68.32964021557814,-68.32964021557791,-69.9004365423732,-69.9004365423732,-69.90043654237297,-69.90043654237297,-1.194568659706448,-1.0869994447159463,-142.2316939607081,-144.51326206513068,-144.5132620651309,-1.1945686597064424,-143.3186934054243,-5.002264310862817,-10.0261332846393,-3.9727823117092953,-7.290862524642649,-124.504404940456,-3.9727823117093237,-146.82366506060032,-150.79644737231024,-5.002264310862776,-145.79418306144626,-5.00208651738126,-10.054764051268958,-4.001067863263231,-8.027932154428669,-129.99378209314813,-4.001067863263216,-153.07856481622616,-157.0796326794898,-5.0020865173811915,-152.07754616210832,-5.001928880064381,-10.050590216368969,-4.00098721602491,-8.025810856794209,-136.28350081741684,-4.000987216024939,-159.36183077064402,-163.36281798667005,-5.0019288800643285,-158.36088910660442,-1.2991516319851801,-3.702636830195414,-3.7815130030068254,-6.265364371195623,-0.02516260900254963,-0.6553944641345026,-3.975752765070567,-7.368528340442765,-142.57249927881398,-0.02516260900254963,-3.9757527650706095,-165.64508791977525,-169.64600329384803,-1.299151631985167,-3.7026368301953885,-164.6442148316677,-10.00321285677458,-20.08414323176165,-8.001644468035863,-16.042954878437143,-304.0096070742277,-8.00164446803587,-350.1399180412005,-358.1415625092368,-10.003212856774468,-348.13834965246224,-3.794150313030109,-8.65049239704272,-0.02260276689354157,-0.5885167811200915,-370.2185414798688,-0.022602766893559393,-383.2517009710623,-383.2743037379555,-3.7941503130300576,-379.48015342492505,-408.40704496667513,-408.4070449666742,-408.4070449666742,-408.4070449666742,-433.53978619538975,-433.5397861953902,-433.5397861953911,-433.53978619539066,-458.67252742410983,-458.6725274241094,-458.67252742410983,-458.6725274241089,-608.6835766330232,-608.6835766330232,-608.6835766330232,-608.6835766330241}; + const int expected1[105]={0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,16,16,17,18,19,19,20,20,20,20,20,21,21,22,23,23,24,24,24,24,24,25,25,26,27,27,28,28,28,28,28,29,29,30,31,31,32,32,32,32,32,32,32,32,32,33,33,33,34,35,35,35,36,36,36,36,36,37,37,38,39,39,40,40,40,40,40,41,41,42,43,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59}; + const int expected2[105]={-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,0,2,-1,-1,-1,0,-1,0,2,4,5,-1,4,-1,-1,0,-1,0,2,4,5,-1,4,-1,-1,0,-1,0,2,4,5,-1,4,-1,-1,0,-1,0,1,2,3,4,5,6,7,-1,4,6,-1,-1,0,1,-1,1,3,6,7,-1,6,-1,-1,1,-1,1,3,6,7,-1,6,-1,-1,1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1}; + MEDCouplingFieldDouble *f3f=m3->getMeasureField(ON_CELLS); + const double *f3=f3f->getArray()->getConstPointer(); + for(int i=0;i<105;i++) + { + CPPUNIT_ASSERT_DOUBLES_EQUAL(areaExpected[i],f3[i],1e-10); + CPPUNIT_ASSERT_EQUAL(expected1[i],d1->getIJ(i,0)); + CPPUNIT_ASSERT_EQUAL(expected2[i],d2->getIJ(i,0)); + } + // + f3f->decrRef(); + m3->decrRef(); + d1->decrRef(); + d2->decrRef(); + m2->decrRef(); + m1->decrRef(); +} + +void MEDCouplingBasicsTest5::testDAIBuildUnique1() +{ + DataArrayInt *d=DataArrayInt::New(); + const int dData[14]={1,2,2,3,3,3,3,4,5,5,7,7,7,19}; + d->useArray(dData,false,CPP_DEALLOC,14,1); + const int expectedData[7]={1,2,3,4,5,7,19}; + // + DataArrayInt *e=d->buildUnique(); + CPPUNIT_ASSERT_EQUAL(7,e->getNumberOfTuples()); + CPPUNIT_ASSERT_EQUAL(1,e->getNumberOfComponents()); + for(int i=0;i<7;i++) + CPPUNIT_ASSERT_EQUAL(expectedData[i],e->getIJ(i,0)); + // + e->decrRef(); + d->decrRef(); +} + +void MEDCouplingBasicsTest5::testDAIPartitionByDifferentValues1() +{ + const int data[9]={1,0,1,2,0,2,2,-3,2}; + const int expected1[4]={-3,0,1,2}; + const int expected2_0[1]={7}; + const int expected2_1[2]={1,4}; + const int expected2_2[2]={0,2}; + const int expected2_3[4]={3,5,6,8}; + DataArrayInt *d=DataArrayInt::New(); + d->useArray(data,false,CPP_DEALLOC,9,1); + std::vector<int> f; + static const int nbOfOutputsExpected=4; + std::vector<DataArrayInt *> e=d->partitionByDifferentValues(f); + d->decrRef(); + CPPUNIT_ASSERT_EQUAL(nbOfOutputsExpected,(int)e.size()); + CPPUNIT_ASSERT_EQUAL(nbOfOutputsExpected,(int)f.size()); + for(int i=0;i<nbOfOutputsExpected;i++) + { + CPPUNIT_ASSERT_EQUAL(expected1[i],f[i]); + } + CPPUNIT_ASSERT_EQUAL((std::size_t)1,e[0]->getNbOfElems()); + CPPUNIT_ASSERT_EQUAL((std::size_t)2,e[1]->getNbOfElems()); + CPPUNIT_ASSERT_EQUAL((std::size_t)2,e[2]->getNbOfElems()); + CPPUNIT_ASSERT_EQUAL((std::size_t)4,e[3]->getNbOfElems()); + CPPUNIT_ASSERT_EQUAL(1,e[0]->getNumberOfComponents()); + CPPUNIT_ASSERT_EQUAL(1,e[1]->getNumberOfComponents()); + CPPUNIT_ASSERT_EQUAL(1,e[2]->getNumberOfComponents()); + CPPUNIT_ASSERT_EQUAL(1,e[3]->getNumberOfComponents()); + CPPUNIT_ASSERT(std::equal(expected2_0,expected2_0+1,e[0]->begin())); + CPPUNIT_ASSERT(std::equal(expected2_1,expected2_1+2,e[1]->begin())); + CPPUNIT_ASSERT(std::equal(expected2_2,expected2_2+2,e[2]->begin())); + CPPUNIT_ASSERT(std::equal(expected2_3,expected2_3+4,e[3]->begin())); + e[0]->decrRef(); e[1]->decrRef(); e[2]->decrRef(); e[3]->decrRef(); +} + +void MEDCouplingBasicsTest5::testDAICheckMonotonic1() +{ + const int data1[6]={-1,0,2,2,4,5}; + const int data2[6]={6,2,0,-8,-9,-56}; + const int data3[6]={-1,0,3,2,4,6}; + const int data4[6]={7,5,2,3,0,-6}; + DataArrayInt *d=DataArrayInt::New(); + d->useArray(data1,false,CPP_DEALLOC,6,1); + CPPUNIT_ASSERT(d->isMonotonic(true)); + CPPUNIT_ASSERT(!d->isMonotonic(false)); + d->checkMonotonic(true); + CPPUNIT_ASSERT_THROW(d->checkMonotonic(false),INTERP_KERNEL::Exception); + d->useArray(data2,false,CPP_DEALLOC,6,1); + CPPUNIT_ASSERT(d->isMonotonic(false)); + CPPUNIT_ASSERT(!d->isMonotonic(true)); + d->checkMonotonic(false); + CPPUNIT_ASSERT_THROW(d->checkMonotonic(true),INTERP_KERNEL::Exception); + d->useArray(data3,false,CPP_DEALLOC,6,1); + CPPUNIT_ASSERT(!d->isMonotonic(false)); + CPPUNIT_ASSERT(!d->isMonotonic(true)); + CPPUNIT_ASSERT_THROW(d->checkMonotonic(true),INTERP_KERNEL::Exception); + CPPUNIT_ASSERT_THROW(d->checkMonotonic(false),INTERP_KERNEL::Exception); + d->useArray(data4,false,CPP_DEALLOC,6,1); + CPPUNIT_ASSERT(!d->isMonotonic(false)); + CPPUNIT_ASSERT(!d->isMonotonic(true)); + CPPUNIT_ASSERT_THROW(d->checkMonotonic(true),INTERP_KERNEL::Exception); + CPPUNIT_ASSERT_THROW(d->checkMonotonic(false),INTERP_KERNEL::Exception); + d->useArray(data4,false,CPP_DEALLOC,0,1); + CPPUNIT_ASSERT(d->isMonotonic(true)); + CPPUNIT_ASSERT(d->isMonotonic(false)); + d->checkMonotonic(true); + d->checkMonotonic(false); + d->useArray(data4,false,CPP_DEALLOC,3,2);//throw because nbComp!=1 + CPPUNIT_ASSERT_THROW(d->isMonotonic(true),INTERP_KERNEL::Exception); + CPPUNIT_ASSERT_THROW(d->isMonotonic(false),INTERP_KERNEL::Exception); + CPPUNIT_ASSERT_THROW(d->checkMonotonic(true),INTERP_KERNEL::Exception); + CPPUNIT_ASSERT_THROW(d->checkMonotonic(false),INTERP_KERNEL::Exception); + d->decrRef(); +} + +void MEDCouplingBasicsTest5::testIntersect2DMeshesTmp6() +{ + // coordinates + DataArrayDouble *coords=DataArrayDouble::New(); + const double coordsData[16]={2.7554552980815448e-15,45,-45,5.5109105961630896e-15,-31.819805153394636,31.81980515339464,2.8779199779962799e-15,47,2.8166876380389124e-15,46,-47,5.7558399559925599e-15,-33.234018715767732,33.234018715767739,-46,5.6333752760778247e-15}; + coords->useArray(coordsData,false,CPP_DEALLOC,8,2); + // connectivity + DataArrayInt *conn=DataArrayInt::New(); + const int connData[9]={8,0,3,5,1,4,6,7,2}; + conn->useArray(connData,false,CPP_DEALLOC,9,1); + DataArrayInt *connI=DataArrayInt::New(); + const int connIData[2]={0,9}; + connI->useArray(connIData,false,CPP_DEALLOC,2,1); + MEDCouplingUMesh *m1=MEDCouplingUMesh::New("Fixe",2); + m1->setCoords(coords); + m1->setConnectivity(conn,connI,true); + coords->decrRef(); conn->decrRef(); connI->decrRef(); + // + coords=DataArrayDouble::New(); + const double coordsData2[26]={-7.3800475508445391,41.854329503018846,-3.7041190667754655,42.338274668899189,-3.7041190667754655,45.338274668899189,-7.3800475508445382,44.854329503018839,-5.5473631693521845,42.136406608386956,-3.7041190667754655,43.838274668899189,-5.5420833088100014,45.09630208595901,-7.3800475508445382,43.354329503018839,-3.7041190667754651,52.338274668899189,-7.3800475508445382,51.854329503018839,-3.7041190667754655,48.838274668899189,-5.5420833088100014,52.09630208595901,-7.3800475508445382,48.354329503018839}; + coords->useArray(coordsData2,false,CPP_DEALLOC,13,2); + // connectivity + conn=DataArrayInt::New(); + const int connData2[18]={8,0,1,2,3,4,5,6,7,8,3,2,8,9,6,10,11,12}; + conn->useArray(connData2,false,CPP_DEALLOC,18,1); + connI=DataArrayInt::New(); + const int connIData2[3]={0,9,18}; + connI->useArray(connIData2,false,CPP_DEALLOC,3,1); + // + MEDCouplingUMesh *m2=MEDCouplingUMesh::New("Mobile",2); + m2->setCoords(coords); + m2->setConnectivity(conn,connI,true); + coords->decrRef(); conn->decrRef(); connI->decrRef(); + // + DataArrayInt *d1=0,*d2=0; + MEDCouplingUMesh *m3=MEDCouplingUMesh::Intersect2DMeshes(m1,m2,1e-10,d1,d2); + CPPUNIT_ASSERT_EQUAL(4,m3->getNumberOfCells()); + CPPUNIT_ASSERT_EQUAL(4,d1->getNumberOfTuples()); + CPPUNIT_ASSERT_EQUAL(4,d2->getNumberOfTuples()); + CPPUNIT_ASSERT_EQUAL(43,m3->getNumberOfNodes()); + bool areMerged=false; + int newNbOfNodes=-1; + m3->mergeNodes(1e-12,areMerged,newNbOfNodes)->decrRef(); + CPPUNIT_ASSERT_EQUAL(35,m3->getNumberOfNodes()); + m3->zipCoords(); + CPPUNIT_ASSERT_EQUAL(23,m3->getNumberOfNodes()); + // + MEDCouplingFieldDouble *f=m3->getMeasureField(true); + const double *vals=f->getArray()->getConstPointer(); + const double valuesExpected[4]={1.6603638692585716,5.747555728471923,129.68907101754394,7.4162714498559694}; + for(int i=0;i<4;i++) + CPPUNIT_ASSERT_DOUBLES_EQUAL(valuesExpected[i],vals[i],1e-12); + f->decrRef(); + // + m1->decrRef(); + m2->decrRef(); + m3->decrRef(); + d1->decrRef(); + d2->decrRef(); +} + +void MEDCouplingBasicsTest5::testIntersect2DMeshesTmp7() +{ + double eps = 1.0e-8; + // coordinates circle - SEE getCircle() on the Python side + DataArrayDouble *coords1=DataArrayDouble::New(); + const double coordsData1[16]={0.5328427124746189, -0.08284271247461905, -0.03284271247461901, 0.4828427124746191, -0.03284271247461906, -0.082842712474619, 0.5328427124746191, 0.482842712474619}; + coords1->useArray(coordsData1,false,CPP_DEALLOC,8,2); + // connectivity + DataArrayInt *conn1=DataArrayInt::New(); + const int connData1[5]={INTERP_KERNEL::NORM_QPOLYG,0,1,2,3}; + conn1->useArray(connData1,false,CPP_DEALLOC,5,1); + DataArrayInt *connI1=DataArrayInt::New(); + const int connIData1[2]={0,5}; + connI1->useArray(connIData1,false,CPP_DEALLOC,2,1); + MEDCouplingUMesh *m1=MEDCouplingUMesh::New("circle",2); + m1->setCoords(coords1); + m1->setConnectivity(conn1,connI1,true); + coords1->decrRef(); conn1->decrRef(); connI1->decrRef(); + + // square + DataArrayDouble *coords2=DataArrayDouble::New(); + const double coordsData2[8]={-0.5,-0.5, -0.5, 0.5, 0.5, 0.5, 0.5,-0.5}; + coords2->useArray(coordsData2,false,CPP_DEALLOC,4,2); + // connectivity + DataArrayInt *conn2=DataArrayInt::New(); + const int connData2[5]={INTERP_KERNEL::NORM_POLYGON, 0,1,2,3}; + conn2->useArray(connData2,false,CPP_DEALLOC,5,1); + DataArrayInt *connI2=DataArrayInt::New(); + const int connIData2[2]={0,5}; + connI2->useArray(connIData2,false,CPP_DEALLOC,2,1); + MEDCouplingUMesh *m2=MEDCouplingUMesh::New("square",2); + m2->setCoords(coords2); + m2->setConnectivity(conn2,connI2,true); + coords2->decrRef(); conn2->decrRef(); connI2->decrRef(); + + DataArrayInt * resToM1 = 0, * resToM2 = 0; + MEDCouplingUMesh *m_intersec=MEDCouplingUMesh::Intersect2DMeshes(m2, m1, eps, resToM1, resToM2); + m_intersec->zipCoords(); + + const double coo_tgt[34]={-0.5, -0.5, -0.5, 0.5, 0.5, 0.5, 0.5, -0.5, -0.03284271247461901, 0.4828427124746191, \ + -0.014575131106459124, 0.5000000000000001, 0.5, -0.11224989991991996, 0.24271243444677046, 0.5, 0.5, 0.19387505004004, \ + -0.04799910280454185, -0.06682678787499614, -0.023843325638122054, 0.4915644577163915, 0.5, -0.30612494995996, 0.0, -0.5,\ + -0.5, 0.0, -0.25728756555322957, 0.5, -0.023843325638122026, 0.49156445771639157, -0.04799910280454181, -0.06682678787499613}; + const int conn_tgt[22]={32, 5, 2, 6, 4, 7, 8, 9, 10, 32, 6, 3, 0, 1, 5, 4, 11, 12, 13, 14, 15, 16}; + const int connI_tgt[3]={0, 9, 22}; + const int res1_tgt[2] = {0, 0}; + const int res2_tgt[2] = {0, -1}; + + CPPUNIT_ASSERT(std::equal(conn_tgt,conn_tgt+22,m_intersec->getNodalConnectivity()->getConstPointer())); + CPPUNIT_ASSERT(std::equal(connI_tgt,connI_tgt+3,m_intersec->getNodalConnectivityIndex()->getConstPointer())); + CPPUNIT_ASSERT(std::equal(res1_tgt,res1_tgt+2,resToM1->getConstPointer())); + CPPUNIT_ASSERT(std::equal(res2_tgt,res2_tgt+2,resToM2->getConstPointer())); + for(int i=0;i<34;i++) + CPPUNIT_ASSERT_DOUBLES_EQUAL(coo_tgt[i],m_intersec->getCoords()->getIJ(0,i),1e-12); + m1->decrRef(); m2->decrRef(); m_intersec->decrRef(); + resToM1->decrRef(); resToM2->decrRef(); +} + +void MEDCouplingBasicsTest5::testDAIBuildSubstractionOptimized1() +{ + const int tab1[7]={1,3,5,6,7,9,13}; + const int tab2[3]={3,5,9}; + const int tab3[3]={1,3,5}; + DataArrayInt *da1=DataArrayInt::New(); da1->useArray(tab1,false,CPP_DEALLOC,7,1); + DataArrayInt *da2=DataArrayInt::New(); da2->useArray(tab2,false,CPP_DEALLOC,3,1); + DataArrayInt *da3=DataArrayInt::New(); da3->useArray(tab3,false,CPP_DEALLOC,3,1); + DataArrayInt *da4=DataArrayInt::New(); da4->useArray(tab1,false,CPP_DEALLOC,7,1); + // + DataArrayInt *a=0; + a=da1->buildSubstractionOptimized(da2); + CPPUNIT_ASSERT_EQUAL(4,a->getNumberOfTuples()); + CPPUNIT_ASSERT_EQUAL(1,a->getNumberOfComponents()); + const int expected1_0[4]={1,6,7,13}; + CPPUNIT_ASSERT(std::equal(expected1_0,expected1_0+4,a->begin())); + a->decrRef(); + // + a=da1->buildSubstractionOptimized(da3); + CPPUNIT_ASSERT_EQUAL(4,a->getNumberOfTuples()); + CPPUNIT_ASSERT_EQUAL(1,a->getNumberOfComponents()); + const int expected2_0[4]={6,7,9,13}; + CPPUNIT_ASSERT(std::equal(expected2_0,expected2_0+4,a->begin())); + a->decrRef(); + // + a=da1->buildSubstractionOptimized(da4); + CPPUNIT_ASSERT_EQUAL(0,a->getNumberOfTuples()); + CPPUNIT_ASSERT_EQUAL(1,a->getNumberOfComponents()); + a->decrRef(); + // + da1->decrRef(); + da2->decrRef(); + da3->decrRef(); + da4->decrRef(); +} + +void MEDCouplingBasicsTest5::testDAIIsStrictlyMonotonic1() +{ + const int tab1[7]={1,3,5,6,7,9,13}; + DataArrayInt *da1=DataArrayInt::New(); da1->useArray(tab1,false,CPP_DEALLOC,7,1); + CPPUNIT_ASSERT(da1->isStrictlyMonotonic(true)); + da1->checkStrictlyMonotonic(true); + CPPUNIT_ASSERT(da1->isMonotonic(true)); + da1->checkMonotonic(true); + CPPUNIT_ASSERT(!da1->isStrictlyMonotonic(false)); + CPPUNIT_ASSERT_THROW(da1->checkStrictlyMonotonic(false),INTERP_KERNEL::Exception); + CPPUNIT_ASSERT(!da1->isMonotonic(false)); + CPPUNIT_ASSERT_THROW(da1->checkMonotonic(false),INTERP_KERNEL::Exception); + da1->decrRef(); + // + int tab2[7]={1,3,5,6,6,9,13}; + da1=DataArrayInt::New(); da1->useArray(tab2,false,CPP_DEALLOC,7,1); + CPPUNIT_ASSERT(!da1->isStrictlyMonotonic(true)); + CPPUNIT_ASSERT_THROW(da1->checkStrictlyMonotonic(true),INTERP_KERNEL::Exception); + CPPUNIT_ASSERT(da1->isMonotonic(true)); + da1->checkMonotonic(true); + CPPUNIT_ASSERT(!da1->isStrictlyMonotonic(false)); + CPPUNIT_ASSERT_THROW(da1->checkStrictlyMonotonic(false),INTERP_KERNEL::Exception); + CPPUNIT_ASSERT(!da1->isMonotonic(false)); + CPPUNIT_ASSERT_THROW(da1->checkMonotonic(false),INTERP_KERNEL::Exception); + da1->decrRef(); + // + const int tab3[7]={1,3,5,6,5,9,13}; + da1=DataArrayInt::New(); da1->useArray(tab3,false,CPP_DEALLOC,7,1); + CPPUNIT_ASSERT(!da1->isStrictlyMonotonic(true)); + CPPUNIT_ASSERT_THROW(da1->checkStrictlyMonotonic(true),INTERP_KERNEL::Exception); + CPPUNIT_ASSERT(!da1->isMonotonic(true)); + CPPUNIT_ASSERT_THROW(da1->checkMonotonic(true),INTERP_KERNEL::Exception); + CPPUNIT_ASSERT(!da1->isStrictlyMonotonic(false)); + CPPUNIT_ASSERT_THROW(da1->checkStrictlyMonotonic(false),INTERP_KERNEL::Exception); + CPPUNIT_ASSERT(!da1->isMonotonic(false)); + CPPUNIT_ASSERT_THROW(da1->checkMonotonic(false),INTERP_KERNEL::Exception); + da1->decrRef(); + // + const int tab4[7]={13,9,7,6,5,3,1}; + da1=DataArrayInt::New(); da1->useArray(tab4,false,CPP_DEALLOC,7,1); + CPPUNIT_ASSERT(!da1->isStrictlyMonotonic(true)); + CPPUNIT_ASSERT_THROW(da1->checkStrictlyMonotonic(true),INTERP_KERNEL::Exception); + CPPUNIT_ASSERT(!da1->isMonotonic(true)); + CPPUNIT_ASSERT_THROW(da1->checkMonotonic(true),INTERP_KERNEL::Exception); + CPPUNIT_ASSERT(da1->isStrictlyMonotonic(false)); + da1->checkStrictlyMonotonic(false); + CPPUNIT_ASSERT(da1->isMonotonic(false)); + da1->checkMonotonic(false); + da1->decrRef(); + // + const int tab5[7]={13,9,6,6,5,3,1}; + da1=DataArrayInt::New(); da1->useArray(tab5,false,CPP_DEALLOC,7,1); + CPPUNIT_ASSERT(!da1->isStrictlyMonotonic(true)); + CPPUNIT_ASSERT_THROW(da1->checkStrictlyMonotonic(true),INTERP_KERNEL::Exception); + CPPUNIT_ASSERT(!da1->isMonotonic(true)); + CPPUNIT_ASSERT_THROW(da1->checkMonotonic(true),INTERP_KERNEL::Exception); + CPPUNIT_ASSERT(!da1->isStrictlyMonotonic(false)); + CPPUNIT_ASSERT_THROW(da1->checkStrictlyMonotonic(false),INTERP_KERNEL::Exception); + CPPUNIT_ASSERT(da1->isMonotonic(false)); + da1->checkMonotonic(false); + da1->decrRef(); + // + const int tab6[7]={13,9,5,6,5,3,1}; + da1=DataArrayInt::New(); da1->useArray(tab6,false,CPP_DEALLOC,7,1); + CPPUNIT_ASSERT(!da1->isStrictlyMonotonic(true)); + CPPUNIT_ASSERT_THROW(da1->checkStrictlyMonotonic(true),INTERP_KERNEL::Exception); + CPPUNIT_ASSERT(!da1->isMonotonic(true)); + CPPUNIT_ASSERT_THROW(da1->checkMonotonic(true),INTERP_KERNEL::Exception); + CPPUNIT_ASSERT(!da1->isStrictlyMonotonic(false)); + CPPUNIT_ASSERT_THROW(da1->checkStrictlyMonotonic(false),INTERP_KERNEL::Exception); + CPPUNIT_ASSERT(!da1->isMonotonic(false)); + CPPUNIT_ASSERT_THROW(da1->checkMonotonic(false),INTERP_KERNEL::Exception); + da1->decrRef(); + // + da1=DataArrayInt::New(); da1->useArray(tab1,false,CPP_DEALLOC,0,1); + CPPUNIT_ASSERT(da1->isStrictlyMonotonic(true)); + da1->checkStrictlyMonotonic(true); + CPPUNIT_ASSERT(da1->isMonotonic(true)); + da1->checkMonotonic(true); + CPPUNIT_ASSERT(da1->isStrictlyMonotonic(false)); + da1->checkStrictlyMonotonic(false); + CPPUNIT_ASSERT(da1->isMonotonic(false)); + da1->checkMonotonic(false); + da1->decrRef(); + // + da1=DataArrayInt::New(); da1->useArray(tab1,false,CPP_DEALLOC,1,1); + CPPUNIT_ASSERT(da1->isStrictlyMonotonic(true)); + da1->checkStrictlyMonotonic(true); + CPPUNIT_ASSERT(da1->isMonotonic(true)); + da1->checkMonotonic(true); + CPPUNIT_ASSERT(da1->isStrictlyMonotonic(false)); + da1->checkStrictlyMonotonic(false); + CPPUNIT_ASSERT(da1->isMonotonic(false)); + da1->checkMonotonic(false); + da1->decrRef(); +} + +void MEDCouplingBasicsTest5::testSimplexize3() +{ + const int conn[24]={0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23}; + MEDCouplingUMesh *m=MEDCouplingUMesh::New("toto",3); + m->allocateCells(0); + m->insertNextCell(INTERP_KERNEL::NORM_TETRA4,4,conn+0); + m->insertNextCell(INTERP_KERNEL::NORM_HEXA8,8,conn+4); + m->insertNextCell(INTERP_KERNEL::NORM_HEXA8,8,conn+12); + m->insertNextCell(INTERP_KERNEL::NORM_TETRA4,4,conn+20); + const double coords[72]={0.,0.,0.,0.,1.,0.,1.,0.,0.,0.,0.,1.,2.,0.,0.,2.,1.,0.,3.,1.,0.,3.,0.,0.,2.,0.,1.,2.,1.,1.,3.,1.,1.,3.,0.,1.,4.,0.,0.,4.,1.,0.,5.,1.,0.,5.,0.,0.,4.,0.,1.,4.,1.,1.,5.,1.,1.,5.,0.,1.,6.,0.,0.,6.,1.,0.,7.,0.,0.,6.,0.,1.}; + DataArrayDouble *c=DataArrayDouble::New(); + c->useArray(coords,false,CPP_DEALLOC,24,3); + m->setCoords(c); + c->decrRef(); + m->checkCoherency2(); + // + MEDCouplingUMesh *m1=static_cast<MEDCouplingUMesh *>(m->deepCpy()); + DataArrayInt *d1=m1->simplexize(INTERP_KERNEL::PLANAR_FACE_5); + m1->checkCoherency2(); + MEDCouplingFieldDouble *f1=m1->getMeasureField(ON_CELLS); + const double vol1Expected[12]={1./6, 1./6, 1./6,1./6, 1./6, 1./3,1./6, 1./6, 1./6, 1./6, 1./3, 1./6}; + CPPUNIT_ASSERT_EQUAL(1,f1->getArray()->getNumberOfComponents()); + CPPUNIT_ASSERT_EQUAL(12,f1->getArray()->getNumberOfTuples()); + for(int i=0;i<12;i++) + CPPUNIT_ASSERT_DOUBLES_EQUAL(vol1Expected[i],f1->getIJ(i,0),1e-12); + const int connExpected1[60]={14,0,1,2,3,14,4,9,5,6,14,4,8,9,11,14,4,7,11,6,14,9,11,10,6,14,4,9,6,11,14,12,17,13,14,14,12,16,17,19,14,12,15,19,14,14,17,19,18,14,14,12,17,14,19,14,20,21,22,23}; + const int connIExpected1[13]={0,5,10,15,20,25,30,35,40,45,50,55,60}; + const int n2o1[12]={0,1,1,1,1,1,2,2,2,2,2,3}; + CPPUNIT_ASSERT_EQUAL(1,m1->getNodalConnectivity()->getNumberOfComponents()); + CPPUNIT_ASSERT_EQUAL(60,m1->getNodalConnectivity()->getNumberOfTuples()); + CPPUNIT_ASSERT_EQUAL(1,m1->getNodalConnectivityIndex()->getNumberOfComponents()); + CPPUNIT_ASSERT_EQUAL(13,m1->getNodalConnectivityIndex()->getNumberOfTuples()); + CPPUNIT_ASSERT(std::equal(connExpected1,connExpected1+60,m1->getNodalConnectivity()->begin())); + CPPUNIT_ASSERT(std::equal(connIExpected1,connIExpected1+13,m1->getNodalConnectivityIndex()->begin())); + CPPUNIT_ASSERT_EQUAL(1,d1->getNumberOfComponents()); + CPPUNIT_ASSERT_EQUAL(12,d1->getNumberOfTuples()); + CPPUNIT_ASSERT(std::equal(n2o1,n2o1+12,d1->begin())); + f1->decrRef(); + m1->decrRef(); + d1->decrRef(); + // + MEDCouplingUMesh *m2=static_cast<MEDCouplingUMesh *>(m->deepCpy()); + DataArrayInt *d2=m2->simplexize(INTERP_KERNEL::PLANAR_FACE_6); + m2->checkCoherency2(); + MEDCouplingFieldDouble *f2=m2->getMeasureField(ON_CELLS); + const double vol2Expected[14]={1./6, 1./6, 1./6,1./6, 1./6, 1./6,1./6,1./6, 1./6, 1./6, 1./6, 1./6,1./6,1./6}; + CPPUNIT_ASSERT_EQUAL(1,f2->getArray()->getNumberOfComponents()); + CPPUNIT_ASSERT_EQUAL(14,f2->getArray()->getNumberOfTuples()); + for(int i=0;i<14;i++) + CPPUNIT_ASSERT_DOUBLES_EQUAL(vol2Expected[i],f2->getIJ(i,0),1e-12); + const int connExpected2[70]={14,0,1,2,3,14,4,9,5,10,14,4,5,6,10,14,4,8,9,10,14,4,11,8,10,14,4,6,7,10,14,4,7,11,10,14,12,17,13,18,14,12,13,14,18,14,12,16,17,18,14,12,19,16,18,14,12,14,15,18,14,12,15,19,18,14,20,21,22,23}; + const int connIExpected2[15]={0,5,10,15,20,25,30,35,40,45,50,55,60,65,70}; + const int n2o2[14]={0,1,1,1,1,1,1,2,2,2,2,2,2,3}; + CPPUNIT_ASSERT_EQUAL(1,m2->getNodalConnectivity()->getNumberOfComponents()); + CPPUNIT_ASSERT_EQUAL(70,m2->getNodalConnectivity()->getNumberOfTuples()); + CPPUNIT_ASSERT_EQUAL(1,m2->getNodalConnectivityIndex()->getNumberOfComponents()); + CPPUNIT_ASSERT_EQUAL(15,m2->getNodalConnectivityIndex()->getNumberOfTuples()); + CPPUNIT_ASSERT(std::equal(connExpected2,connExpected2+70,m2->getNodalConnectivity()->begin())); + CPPUNIT_ASSERT(std::equal(connIExpected2,connIExpected2+15,m2->getNodalConnectivityIndex()->begin())); + CPPUNIT_ASSERT_EQUAL(1,d2->getNumberOfComponents()); + CPPUNIT_ASSERT_EQUAL(14,d2->getNumberOfTuples()); + CPPUNIT_ASSERT(std::equal(n2o2,n2o2+14,d2->begin())); + f2->decrRef(); + m2->decrRef(); + d2->decrRef(); + // + m->decrRef(); +} diff --git a/src/medtool/src/MEDCoupling/Test/MEDCouplingBasicsTest5.hxx b/src/medtool/src/MEDCoupling/Test/MEDCouplingBasicsTest5.hxx new file mode 100644 index 000000000..a4cedd497 --- /dev/null +++ b/src/medtool/src/MEDCoupling/Test/MEDCouplingBasicsTest5.hxx @@ -0,0 +1,124 @@ +// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 +// 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 __MEDCOUPLINGBASICSTEST5_HXX__ +#define __MEDCOUPLINGBASICSTEST5_HXX__ + +#include "MEDCouplingBasicsTest.hxx" + +#include <map> +#include <vector> + +namespace ParaMEDMEM +{ + class DataArrayDouble; + class MEDCouplingUMesh; + class MEDCouplingFieldDouble; + class MEDCouplingMultiFields; + + class MEDCouplingBasicsTest5 : public MEDCouplingBasicsTest + { + CPPUNIT_TEST_SUITE(MEDCouplingBasicsTest5); + CPPUNIT_TEST( testUMeshTessellate2D1 ); + CPPUNIT_TEST( testUMeshTessellate2DCurve1 ); + CPPUNIT_TEST( testIntersect2DMeshesTmp4 ); + CPPUNIT_TEST( testGetCellIdsCrossingPlane1 ); + CPPUNIT_TEST( testBuildSlice3D1 ); + CPPUNIT_TEST( testBuildSlice3DSurf1 ); + CPPUNIT_TEST( testDataArrayDoubleAdvSetting1 ); + CPPUNIT_TEST( testDataArrayIntAdvSetting1 ); + CPPUNIT_TEST( testBuildDescendingConnec2Of3DMesh1 ); + CPPUNIT_TEST( testAre2DCellsNotCorrectlyOriented1 ); + CPPUNIT_TEST( testDataArrayAbs1 ); + CPPUNIT_TEST( testGetValueOn3 ); + CPPUNIT_TEST( testGetNodeIdsOfCell2 ); + CPPUNIT_TEST( testRenumberNodesInConn1 ); + CPPUNIT_TEST( testComputeNeighborsOfCells1 ); + CPPUNIT_TEST( testCheckButterflyCellsBug1 ); + CPPUNIT_TEST( testDataArrayIntRange1 ); + CPPUNIT_TEST( testDataArrayDoubleGetMinMaxPerComponent1 ); + CPPUNIT_TEST( testDataArrayIntGetHashCode1 ); + CPPUNIT_TEST( testZipConnectivityPol1 ); + CPPUNIT_TEST( testConvexEnvelop2D1 ); + CPPUNIT_TEST( testDataArraySort1 ); + CPPUNIT_TEST( testPartitionBySpreadZone1 ); + CPPUNIT_TEST( testGiveCellsWithType1 ); + CPPUNIT_TEST( testBuildSlice3D2 ); + CPPUNIT_TEST( testComputeTupleIdsToSelectFromCellIds1 ); + CPPUNIT_TEST( testComputeSkin1 ); + CPPUNIT_TEST( testUMeshSetPartOfMySelf2 ); + CPPUNIT_TEST( testUnPolyze3 ); + CPPUNIT_TEST( testKrSpatialDiscretization1 ); + CPPUNIT_TEST( testDuplicateEachTupleNTimes1 ); + CPPUNIT_TEST( testIntersect2DMeshesTmp5 ); + CPPUNIT_TEST( testDAIBuildUnique1 ); + CPPUNIT_TEST( testDAIPartitionByDifferentValues1 ); + CPPUNIT_TEST( testDAICheckMonotonic1 ); + CPPUNIT_TEST( testIntersect2DMeshesTmp6 ); + CPPUNIT_TEST( testIntersect2DMeshesTmp7 ); + CPPUNIT_TEST( testDAIBuildSubstractionOptimized1 ); + CPPUNIT_TEST( testDAIIsStrictlyMonotonic1 ); + CPPUNIT_TEST( testSimplexize3 ); + CPPUNIT_TEST_SUITE_END(); + public: + void testUMeshTessellate2D1(); + void testUMeshTessellate2DCurve1(); + void testIntersect2DMeshesTmp4(); + void testGetCellIdsCrossingPlane1(); + void testBuildSlice3D1(); + void testBuildSlice3DSurf1(); + void testDataArrayDoubleAdvSetting1(); + void testDataArrayIntAdvSetting1(); + void testBuildDescendingConnec2Of3DMesh1(); + void testAre2DCellsNotCorrectlyOriented1(); + void testDataArrayAbs1(); + void testGetValueOn3(); + void testGetNodeIdsOfCell2(); + void testRenumberNodesInConn1(); + void testComputeNeighborsOfCells1(); + void testCheckButterflyCellsBug1(); + void testDataArrayIntRange1(); + void testDataArrayDoubleGetMinMaxPerComponent1(); + void testDataArrayIntGetHashCode1(); + void testZipConnectivityPol1(); + void testConvexEnvelop2D1(); + void testDataArraySort1(); + void testPartitionBySpreadZone1(); + void testGiveCellsWithType1(); + void testBuildSlice3D2(); + void testComputeTupleIdsToSelectFromCellIds1(); + void testComputeSkin1(); + void testUMeshSetPartOfMySelf2(); + void testUnPolyze3(); + void testKrSpatialDiscretization1(); + void testDuplicateEachTupleNTimes1(); + void testIntersect2DMeshesTmp5(); + void testDAIBuildUnique1(); + void testDAIPartitionByDifferentValues1(); + void testDAICheckMonotonic1(); + void testIntersect2DMeshesTmp6(); + void testIntersect2DMeshesTmp7(); + void testDAIBuildSubstractionOptimized1(); + void testDAIIsStrictlyMonotonic1(); + void testSimplexize3(); + }; +} + +#endif diff --git a/src/medtool/src/MEDCoupling/Test/MEDCouplingBasicsTestData1.hxx b/src/medtool/src/MEDCoupling/Test/MEDCouplingBasicsTestData1.hxx new file mode 100644 index 000000000..fde75b35c --- /dev/null +++ b/src/medtool/src/MEDCoupling/Test/MEDCouplingBasicsTestData1.hxx @@ -0,0 +1,1167 @@ +// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 +// 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) + +int connITT[201]={0, 50, 100, 150, 200, 250, 300, 350, 400, 450, 500, 550, 600, 650, 700, 750, 800, 850, 900, 950, 1000, 1029, 1058, 1087, 1116, 1145, 1174, 1203, + 1232, 1261, 1290, 1319, 1348, 1377, 1406, 1435, 1464, 1493, 1522, 1551, 1580, 1609, 1638, 1667, 1696, 1725, 1754, 1783, 1812, 1841, 1870, 1899, + 1928, 1957, 1986, 2015, 2044, 2073, 2102, 2131, 2160, 2189, 2218, 2247, 2276, 2305, 2334, 2363, 2392, 2421, 2450, 2479, 2508, 2537, 2566, 2595, + 2624, 2653, 2682, 2711, 2740, 2769, 2798, 2827, 2856, 2885, 2914, 2943, 2972, 3001, 3030, 3059, 3088, 3117, 3146, 3175, 3204, 3233, 3262, 3291, + 3320, 3349, 3378, 3407, 3436, 3465, 3494, 3523, 3552, 3581, 3610, 3639, 3668, 3697, 3726, 3755, 3784, 3813, 3842, 3871, 3900, 3929, 3958, 3987, + 4016, 4045, 4074, 4103, 4132, 4161, 4190, 4219, 4248, 4277, 4306, 4335, 4364, 4393, 4422, 4451, 4480, 4509, 4538, 4567, 4596, 4625, 4654, 4683, + 4712, 4741, 4770, 4799, 4828, 4857, 4886, 4915, 4944, 4973, 5002, 5031, 5060, 5089, 5118, 5147, 5176, 5205, 5234, 5263, 5292, 5321, 5350, 5379, + 5408, 5437, 5466, 5495, 5524, 5553, 5582, 5611, 5640, 5669, 5698, 5727, 5756, 5785, 5814, 5843, 5872, 5901, 5930, 5959, 5988, 6017, 6046, 6075, + 6104, 6133, 6162, 6191, 6220}; + int connTT[6220]={0, 1, 2, 3, 4, 5, 6, -1, 0, 7, 8, 1, -1, 1, 8, 9, 2, -1, 2, 9, 10, 3, -1, 3, 10, 11, 4, -1, 4, 11, 12, 5, -1, 5, 12, 13, 6, -1, 6, 13, 7, 0, -1, 7, 13, 12, 11, 10, 9, 8, 14, 15, 16, 17, 18, 19, + 20, -1, 14, 21, 22, 15, -1, 15, 22, 23, 16, -1, 16, 23, 24, 17, -1, 17, 24, 25, 18, -1, 18, 25, 26, 19, -1, 19, 26, 27, 20, -1, 20, 27, 21, 14, -1, 21, 27, 26, 25, 24, 23, 22, 28, 29, 30, 31, 32, + 33, 34, -1, 28, 35, 36, 29, -1, 29, 36, 37, 30, -1, 30, 37, 38, 31, -1, 31, 38, 39, 32, -1, 32, 39, 40, 33, -1, 33, 40, 41, 34, -1, 34, 41, 35, 28, -1, 35, 41, 40, 39, 38, 37, 36, 42, 43, 44, 45, + 46, 47, 48, -1, 42, 49, 50, 43, -1, 43, 50, 51, 44, -1, 44, 51, 52, 45, -1, 45, 52, 53, 46, -1, 46, 53, 54, 47, -1, 47, 54, 55, 48, -1, 48, 55, 49, 42, -1, 49, 55, 54, 53, 52, 51, 50, 56, 57, 58, + 59, 60, 61, 62, -1, 56, 63, 64, 57, -1, 57, 64, 65, 58, -1, 58, 65, 66, 59, -1, 59, 66, 67, 60, -1, 60, 67, 68, 61, -1, 61, 68, 69, 62, -1, 62, 69, 63, 56, -1, 63, 69, 68, 67, 66, 65, 64, 70, 71, + 72, 73, 74, 75, 76, -1, 70, 77, 78, 71, -1, 71, 78, 79, 72, -1, 72, 79, 80, 73, -1, 73, 80, 81, 74, -1, 74, 81, 82, 75, -1, 75, 82, 83, 76, -1, 76, 83, 77, 70, -1, 77, 83, 82, 81, 80, 79, 78, 84, + 85, 86, 87, 88, 89, 90, -1, 84, 91, 92, 85, -1, 85, 92, 93, 86, -1, 86, 93, 94, 87, -1, 87, 94, 95, 88, -1, 88, 95, 96, 89, -1, 89, 96, 97, 90, -1, 90, 97, 91, 84, -1, 91, 97, 96, 95, 94, 93, 92, + 98, 99, 100, 101, 102, 103, 104, -1, 98, 105, 106, 99, -1, 99, 106, 107, 100, -1, 100, 107, 108, 101, -1, 101, 108, 109, 102, -1, 102, 109, 110, 103, -1, 103, 110, 111, 104, -1, 104, 111, 105, 98, + -1, 105, 111, 110, 109, 108, 107, 106, 112, 113, 114, 115, 116, 117, 118, -1, 112, 119, 120, 113, -1, 113, 120, 121, 114, -1, 114, 121, 122, 115, -1, 115, 122, 123, 116, -1, 116, 123, 124, 117, -1, + 117, 124, 125, 118, -1, 118, 125, 119, 112, -1, 119, 125, 124, 123, 122, 121, 120, 126, 127, 128, 129, 130, 131, 132, -1, 126, 133, 134, 127, -1, 127, 134, 135, 128, -1, 128, 135, 136, 129, -1, 129, + 136, 137, 130, -1, 130, 137, 138, 131, -1, 131, 138, 139, 132, -1, 132, 139, 133, 126, -1, 133, 139, 138, 137, 136, 135, 134, 140, 141, 142, 143, 144, 145, 146, -1, 140, 147, 148, 141, -1, 141, 148, + 149, 142, -1, 142, 149, 150, 143, -1, 143, 150, 151, 144, -1, 144, 151, 152, 145, -1, 145, 152, 153, 146, -1, 146, 153, 147, 140, -1, 147, 153, 152, 151, 150, 149, 148, 154, 155, 156, 157, 158, 159, + 160, -1, 154, 161, 162, 155, -1, 155, 162, 163, 156, -1, 156, 163, 164, 157, -1, 157, 164, 165, 158, -1, 158, 165, 166, 159, -1, 159, 166, 167, 160, -1, 160, 167, 161, 154, -1, 161, 167, 166, 165, + 164, 163, 162, 168, 169, 170, 171, 172, 173, 174, -1, 168, 175, 176, 169, -1, 169, 176, 177, 170, -1, 170, 177, 178, 171, -1, 171, 178, 179, 172, -1, 172, 179, 180, 173, -1, 173, 180, 181, 174, -1, + 174, 181, 175, 168, -1, 175, 181, 180, 179, 178, 177, 176, 182, 183, 184, 185, 186, 187, 188, -1, 182, 189, 190, 183, -1, 183, 190, 191, 184, -1, 184, 191, 192, 185, -1, 185, 192, 193, 186, -1, 186, + 193, 194, 187, -1, 187, 194, 195, 188, -1, 188, 195, 189, 182, -1, 189, 195, 194, 193, 192, 191, 190, 196, 197, 198, 199, 200, 201, 202, -1, 196, 203, 204, 197, -1, 197, 204, 205, 198, -1, 198, 205, + 206, 199, -1, 199, 206, 207, 200, -1, 200, 207, 208, 201, -1, 201, 208, 209, 202, -1, 202, 209, 203, 196, -1, 203, 209, 208, 207, 206, 205, 204, 210, 211, 212, 213, 214, 215, 216, -1, 210, 217, 218, + 211, -1, 211, 218, 219, 212, -1, 212, 219, 220, 213, -1, 213, 220, 221, 214, -1, 214, 221, 222, 215, -1, 215, 222, 223, 216, -1, 216, 223, 217, 210, -1, 217, 223, 222, 221, 220, 219, 218, 224, 225, + 226, 227, 228, 229, 230, -1, 224, 231, 232, 225, -1, 225, 232, 233, 226, -1, 226, 233, 234, 227, -1, 227, 234, 235, 228, -1, 228, 235, 236, 229, -1, 229, 236, 237, 230, -1, 230, 237, 231, 224, -1, + 231, 237, 236, 235, 234, 233, 232, 238, 239, 240, 241, 242, 243, 244, -1, 238, 245, 246, 239, -1, 239, 246, 247, 240, -1, 240, 247, 248, 241, -1, 241, 248, 249, 242, -1, 242, 249, 250, 243, -1, 243, + 250, 251, 244, -1, 244, 251, 245, 238, -1, 245, 251, 250, 249, 248, 247, 246, 252, 253, 254, 255, 256, 257, 258, -1, 252, 259, 260, 253, -1, 253, 260, 261, 254, -1, 254, 261, 262, 255, -1, 255, 262, + 263, 256, -1, 256, 263, 264, 257, -1, 257, 264, 265, 258, -1, 258, 265, 259, 252, -1, 259, 265, 264, 263, 262, 261, 260, 266, 267, 268, 269, 270, 271, 272, -1, 266, 273, 274, 267, -1, 267, 274, 275, + 268, -1, 268, 275, 276, 269, -1, 269, 276, 277, 270, -1, 270, 277, 278, 271, -1, 271, 278, 279, 272, -1, 272, 279, 273, 266, -1, 273, 279, 278, 277, 276, 275, 274, 280, 281, 282, 283, -1, 280, 284, + 285, 281, -1, 281, 285, 286, 282, -1, 282, 286, 287, 283, -1, 283, 287, 284, 280, -1, 284, 287, 286, 285, 288, 289, 290, 291, -1, 288, 292, 293, 289, -1, 289, 293, 294, 290, -1, 290, 294, 295, 291, + -1, 291, 295, 292, 288, -1, 292, 295, 294, 293, 296, 297, 298, 299, -1, 296, 300, 301, 297, -1, 297, 301, 302, 298, -1, 298, 302, 303, 299, -1, 299, 303, 300, 296, -1, 300, 303, 302, 301, 304, 305, + 306, 307, -1, 304, 308, 309, 305, -1, 305, 309, 310, 306, -1, 306, 310, 311, 307, -1, 307, 311, 308, 304, -1, 308, 311, 310, 309, 312, 313, 314, 315, -1, 312, 316, 317, 313, -1, 313, 317, 318, 314, + -1, 314, 318, 319, 315, -1, 315, 319, 316, 312, -1, 316, 319, 318, 317, 320, 321, 322, 323, -1, 320, 324, 325, 321, -1, 321, 325, 326, 322, -1, 322, 326, 327, 323, -1, 323, 327, 324, 320, -1, 324, + 327, 326, 325, 328, 329, 330, 331, -1, 328, 332, 333, 329, -1, 329, 333, 334, 330, -1, 330, 334, 335, 331, -1, 331, 335, 332, 328, -1, 332, 335, 334, 333, 336, 337, 338, 339, -1, 336, 340, 341, 337, + -1, 337, 341, 342, 338, -1, 338, 342, 343, 339, -1, 339, 343, 340, 336, -1, 340, 343, 342, 341, 344, 345, 346, 347, -1, 344, 348, 349, 345, -1, 345, 349, 350, 346, -1, 346, 350, 351, 347, -1, 347, + 351, 348, 344, -1, 348, 351, 350, 349, 352, 353, 354, 355, -1, 352, 356, 357, 353, -1, 353, 357, 358, 354, -1, 354, 358, 359, 355, -1, 355, 359, 356, 352, -1, 356, 359, 358, 357, 360, 361, 362, 363, + -1, 360, 364, 365, 361, -1, 361, 365, 366, 362, -1, 362, 366, 367, 363, -1, 363, 367, 364, 360, -1, 364, 367, 366, 365, 368, 369, 370, 371, -1, 368, 372, 373, 369, -1, 369, 373, 374, 370, -1, 370, + 374, 375, 371, -1, 371, 375, 372, 368, -1, 372, 375, 374, 373, 376, 377, 378, 379, -1, 376, 380, 381, 377, -1, 377, 381, 382, 378, -1, 378, 382, 383, 379, -1, 379, 383, 380, 376, -1, 380, 383, 382, + 381, 384, 385, 386, 387, -1, 384, 388, 389, 385, -1, 385, 389, 390, 386, -1, 386, 390, 391, 387, -1, 387, 391, 388, 384, -1, 388, 391, 390, 389, 392, 393, 394, 395, -1, 392, 396, 397, 393, -1, 393, + 397, 398, 394, -1, 394, 398, 399, 395, -1, 395, 399, 396, 392, -1, 396, 399, 398, 397, 400, 401, 402, 403, -1, 400, 404, 405, 401, -1, 401, 405, 406, 402, -1, 402, 406, 407, 403, -1, 403, 407, 404, + 400, -1, 404, 407, 406, 405, 408, 409, 410, 411, -1, 408, 412, 413, 409, -1, 409, 413, 414, 410, -1, 410, 414, 415, 411, -1, 411, 415, 412, 408, -1, 412, 415, 414, 413, 416, 417, 418, 419, -1, 416, + 420, 421, 417, -1, 417, 421, 422, 418, -1, 418, 422, 423, 419, -1, 419, 423, 420, 416, -1, 420, 423, 422, 421, 424, 425, 426, 427, -1, 424, 428, 429, 425, -1, 425, 429, 430, 426, -1, 426, 430, 431, + 427, -1, 427, 431, 428, 424, -1, 428, 431, 430, 429, 432, 433, 434, 435, -1, 432, 436, 437, 433, -1, 433, 437, 438, 434, -1, 434, 438, 439, 435, -1, 435, 439, 436, 432, -1, 436, 439, 438, 437, 440, + 441, 442, 443, -1, 440, 444, 445, 441, -1, 441, 445, 446, 442, -1, 442, 446, 447, 443, -1, 443, 447, 444, 440, -1, 444, 447, 446, 445, 448, 449, 450, 451, -1, 448, 452, 453, 449, -1, 449, 453, 454, + 450, -1, 450, 454, 455, 451, -1, 451, 455, 452, 448, -1, 452, 455, 454, 453, 456, 457, 458, 459, -1, 456, 460, 461, 457, -1, 457, 461, 462, 458, -1, 458, 462, 463, 459, -1, 459, 463, 460, 456, -1, + 460, 463, 462, 461, 464, 465, 466, 467, -1, 464, 468, 469, 465, -1, 465, 469, 470, 466, -1, 466, 470, 471, 467, -1, 467, 471, 468, 464, -1, 468, 471, 470, 469, 472, 473, 474, 475, -1, 472, 476, 477, + 473, -1, 473, 477, 478, 474, -1, 474, 478, 479, 475, -1, 475, 479, 476, 472, -1, 476, 479, 478, 477, 480, 481, 482, 483, -1, 480, 484, 485, 481, -1, 481, 485, 486, 482, -1, 482, 486, 487, 483, -1, + 483, 487, 484, 480, -1, 484, 487, 486, 485, 488, 489, 490, 491, -1, 488, 492, 493, 489, -1, 489, 493, 494, 490, -1, 490, 494, 495, 491, -1, 491, 495, 492, 488, -1, 492, 495, 494, 493, 496, 497, 498, + 499, -1, 496, 500, 501, 497, -1, 497, 501, 502, 498, -1, 498, 502, 503, 499, -1, 499, 503, 500, 496, -1, 500, 503, 502, 501, 504, 505, 506, 507, -1, 504, 508, 509, 505, -1, 505, 509, 510, 506, -1, 506, + 510, 511, 507, -1, 507, 511, 508, 504, -1, 508, 511, 510, 509, 512, 513, 514, 515, -1, 512, 516, 517, 513, -1, 513, 517, 518, 514, -1, 514, 518, 519, 515, -1, 515, 519, 516, 512, -1, 516, 519, 518, 517, + 520, 521, 522, 523, -1, 520, 524, 525, 521, -1, 521, 525, 526, 522, -1, 522, 526, 527, 523, -1, 523, 527, 524, 520, -1, 524, 527, 526, 525, 528, 529, 530, 531, -1, 528, 532, 533, 529, -1, 529, 533, + 534, 530, -1, 530, 534, 535, 531, -1, 531, 535, 532, 528, -1, 532, 535, 534, 533, 536, 537, 538, 539, -1, 536, 540, 541, 537, -1, 537, 541, 542, 538, -1, 538, 542, 543, 539, -1, 539, 543, 540, 536, + -1, 540, 543, 542, 541, 544, 545, 546, 547, -1, 544, 548, 549, 545, -1, 545, 549, 550, 546, -1, 546, 550, 551, 547, -1, 547, 551, 548, 544, -1, 548, 551, 550, 549, 552, 553, 554, 555, -1, 552, 556, + 557, 553, -1, 553, 557, 558, 554, -1, 554, 558, 559, 555, -1, 555, 559, 556, 552, -1, 556, 559, 558, 557, 560, 561, 562, 563, -1, 560, 564, 565, 561, -1, 561, 565, 566, 562, -1, 562, 566, 567, 563, + -1, 563, 567, 564, 560, -1, 564, 567, 566, 565, 568, 569, 570, 571, -1, 568, 572, 573, 569, -1, 569, 573, 574, 570, -1, 570, 574, 575, 571, -1, 571, 575, 572, 568, -1, 572, 575, 574, 573, 576, 577, + 578, 579, -1, 576, 580, 581, 577, -1, 577, 581, 582, 578, -1, 578, 582, 583, 579, -1, 579, 583, 580, 576, -1, 580, 583, 582, 581, 584, 585, 586, 587, -1, 584, 588, 589, 585, -1, 585, 589, 590, 586, + -1, 586, 590, 591, 587, -1, 587, 591, 588, 584, -1, 588, 591, 590, 589, 592, 593, 594, 595, -1, 592, 596, 597, 593, -1, 593, 597, 598, 594, -1, 594, 598, 599, 595, -1, 595, 599, 596, 592, -1, 596, + 599, 598, 597, 600, 601, 602, 603, -1, 600, 604, 605, 601, -1, 601, 605, 606, 602, -1, 602, 606, 607, 603, -1, 603, 607, 604, 600, -1, 604, 607, 606, 605, 608, 609, 610, 611, -1, 608, 612, 613, 609, + -1, 609, 613, 614, 610, -1, 610, 614, 615, 611, -1, 611, 615, 612, 608, -1, 612, 615, 614, 613, 616, 617, 618, 619, -1, 616, 620, 621, 617, -1, 617, 621, 622, 618, -1, 618, 622, 623, 619, -1, 619, + 623, 620, 616, -1, 620, 623, 622, 621, 624, 625, 626, 627, -1, 624, 628, 629, 625, -1, 625, 629, 630, 626, -1, 626, 630, 631, 627, -1, 627, 631, 628, 624, -1, 628, 631, 630, 629, 632, 633, 634, 635, + -1, 632, 636, 637, 633, -1, 633, 637, 638, 634, -1, 634, 638, 639, 635, -1, 635, 639, 636, 632, -1, 636, 639, 638, 637, 640, 641, 642, 643, -1, 640, 644, 645, 641, -1, 641, 645, 646, 642, -1, 642, + 646, 647, 643, -1, 643, 647, 644, 640, -1, 644, 647, 646, 645, 648, 649, 650, 651, -1, 648, 652, 653, 649, -1, 649, 653, 654, 650, -1, 650, 654, 655, 651, -1, 651, 655, 652, 648, -1, 652, 655, 654, + 653, 656, 657, 658, 659, -1, 656, 660, 661, 657, -1, 657, 661, 662, 658, -1, 658, 662, 663, 659, -1, 659, 663, 660, 656, -1, 660, 663, 662, 661, 664, 665, 666, 667, -1, 664, 668, 669, 665, -1, 665, + 669, 670, 666, -1, 666, 670, 671, 667, -1, 667, 671, 668, 664, -1, 668, 671, 670, 669, 672, 673, 674, 675, -1, 672, 676, 677, 673, -1, 673, 677, 678, 674, -1, 674, 678, 679, 675, -1, 675, 679, 676, + 672, -1, 676, 679, 678, 677, 680, 681, 682, 683, -1, 680, 684, 685, 681, -1, 681, 685, 686, 682, -1, 682, 686, 687, 683, -1, 683, 687, 684, 680, -1, 684, 687, 686, 685, 688, 689, 690, 691, -1, 688, + 692, 693, 689, -1, 689, 693, 694, 690, -1, 690, 694, 695, 691, -1, 691, 695, 692, 688, -1, 692, 695, 694, 693, 696, 697, 698, 699, -1, 696, 700, 701, 697, -1, 697, 701, 702, 698, -1, 698, 702, 703, + 699, -1, 699, 703, 700, 696, -1, 700, 703, 702, 701, 704, 705, 706, 707, -1, 704, 708, 709, 705, -1, 705, 709, 710, 706, -1, 706, 710, 711, 707, -1, 707, 711, 708, 704, -1, 708, 711, 710, 709, 712, + 713, 714, 715, -1, 712, 716, 717, 713, -1, 713, 717, 718, 714, -1, 714, 718, 719, 715, -1, 715, 719, 716, 712, -1, 716, 719, 718, 717, 720, 721, 722, 723, -1, 720, 724, 725, 721, -1, 721, 725, 726, + 722, -1, 722, 726, 727, 723, -1, 723, 727, 724, 720, -1, 724, 727, 726, 725, 728, 729, 730, 731, -1, 728, 732, 733, 729, -1, 729, 733, 734, 730, -1, 730, 734, 735, 731, -1, 731, 735, 732, 728, -1, + 732, 735, 734, 733, 736, 737, 738, 739, -1, 736, 740, 741, 737, -1, 737, 741, 742, 738, -1, 738, 742, 743, 739, -1, 739, 743, 740, 736, -1, 740, 743, 742, 741, 744, 745, 746, 747, -1, 744, 748, 749, + 745, -1, 745, 749, 750, 746, -1, 746, 750, 751, 747, -1, 747, 751, 748, 744, -1, 748, 751, 750, 749, 752, 753, 754, 755, -1, 752, 756, 757, 753, -1, 753, 757, 758, 754, -1, 754, 758, 759, 755, -1, + 755, 759, 756, 752, -1, 756, 759, 758, 757, 760, 761, 762, 763, -1, 760, 764, 765, 761, -1, 761, 765, 766, 762, -1, 762, 766, 767, 763, -1, 763, 767, 764, 760, -1, 764, 767, 766, 765, 768, 769, 770, + 771, -1, 768, 772, 773, 769, -1, 769, 773, 774, 770, -1, 770, 774, 775, 771, -1, 771, 775, 772, 768, -1, 772, 775, 774, 773, 776, 777, 778, 779, -1, 776, 780, 781, 777, -1, 777, 781, 782, 778, -1, + 778, 782, 783, 779, -1, 779, 783, 780, 776, -1, 780, 783, 782, 781, 784, 785, 786, 787, -1, 784, 788, 789, 785, -1, 785, 789, 790, 786, -1, 786, 790, 791, 787, -1, 787, 791, 788, 784, -1, 788, 791, + 790, 789, 792, 793, 794, 795, -1, 792, 796, 797, 793, -1, 793, 797, 798, 794, -1, 794, 798, 799, 795, -1, 795, 799, 796, 792, -1, 796, 799, 798, 797, 800, 801, 802, 803, -1, 800, 804, 805, 801, -1, + 801, 805, 806, 802, -1, 802, 806, 807, 803, -1, 803, 807, 804, 800, -1, 804, 807, 806, 805, 808, 809, 810, 811, -1, 808, 812, 813, 809, -1, 809, 813, 814, 810, -1, 810, 814, 815, 811, -1, 811, 815, + 812, 808, -1, 812, 815, 814, 813, 816, 817, 818, 819, -1, 816, 820, 821, 817, -1, 817, 821, 822, 818, -1, 818, 822, 823, 819, -1, 819, 823, 820, 816, -1, 820, 823, 822, 821, 824, 825, 826, 827, -1, + 824, 828, 829, 825, -1, 825, 829, 830, 826, -1, 826, 830, 831, 827, -1, 827, 831, 828, 824, -1, 828, 831, 830, 829, 832, 833, 834, 835, -1, 832, 836, 837, 833, -1, 833, 837, 838, 834, -1, 834, 838, + 839, 835, -1, 835, 839, 836, 832, -1, 836, 839, 838, 837, 840, 841, 842, 843, -1, 840, 844, 845, 841, -1, 841, 845, 846, 842, -1, 842, 846, 847, 843, -1, 843, 847, 844, 840, -1, 844, 847, 846, 845, + 848, 849, 850, 851, -1, 848, 852, 853, 849, -1, 849, 853, 854, 850, -1, 850, 854, 855, 851, -1, 851, 855, 852, 848, -1, 852, 855, 854, 853, 856, 857, 858, 859, -1, 856, 860, 861, 857, -1, 857, 861, + 862, 858, -1, 858, 862, 863, 859, -1, 859, 863, 860, 856, -1, 860, 863, 862, 861, 864, 865, 866, 867, -1, 864, 868, 869, 865, -1, 865, 869, 870, 866, -1, 866, 870, 871, 867, -1, 867, 871, 868, 864, + -1, 868, 871, 870, 869, 872, 873, 874, 875, -1, 872, 876, 877, 873, -1, 873, 877, 878, 874, -1, 874, 878, 879, 875, -1, 875, 879, 876, 872, -1, 876, 879, 878, 877, 880, 881, 882, 883, -1, 880, 884, + 885, 881, -1, 881, 885, 886, 882, -1, 882, 886, 887, 883, -1, 883, 887, 884, 880, -1, 884, 887, 886, 885, 888, 889, 890, 891, -1, 888, 892, 893, 889, -1, 889, 893, 894, 890, -1, 890, 894, 895, 891, + -1, 891, 895, 892, 888, -1, 892, 895, 894, 893, 896, 897, 898, 899, -1, 896, 900, 901, 897, -1, 897, 901, 902, 898, -1, 898, 902, 903, 899, -1, 899, 903, 900, 896, -1, 900, 903, 902, 901, 904, 905, + 906, 907, -1, 904, 908, 909, 905, -1, 905, 909, 910, 906, -1, 906, 910, 911, 907, -1, 907, 911, 908, 904, -1, 908, 911, 910, 909, 912, 913, 914, 915, -1, 912, 916, 917, 913, -1, 913, 917, 918, 914, + -1, 914, 918, 919, 915, -1, 915, 919, 916, 912, -1, 916, 919, 918, 917, 920, 921, 922, 923, -1, 920, 924, 925, 921, -1, 921, 925, 926, 922, -1, 922, 926, 927, 923, -1, 923, 927, 924, 920, -1, 924, + 927, 926, 925, 928, 929, 930, 931, -1, 928, 932, 933, 929, -1, 929, 933, 934, 930, -1, 930, 934, 935, 931, -1, 931, 935, 932, 928, -1, 932, 935, 934, 933, 936, 937, 938, 939, -1, 936, 940, 941, 937, + -1, 937, 941, 942, 938, -1, 938, 942, 943, 939, -1, 939, 943, 940, 936, -1, 940, 943, 942, 941, 944, 945, 946, 947, -1, 944, 948, 949, 945, -1, 945, 949, 950, 946, -1, 946, 950, 951, 947, -1, 947, + 951, 948, 944, -1, 948, 951, 950, 949, 952, 953, 954, 955, -1, 952, 956, 957, 953, -1, 953, 957, 958, 954, -1, 954, 958, 959, 955, -1, 955, 959, 956, 952, -1, 956, 959, 958, 957, 960, 961, 962, 963, + -1, 960, 964, 965, 961, -1, 961, 965, 966, 962, -1, 962, 966, 967, 963, -1, 963, 967, 964, 960, -1, 964, 967, 966, 965, 968, 969, 970, 971, -1, 968, 972, 973, 969, -1, 969, 973, 974, 970, -1, 970, + 974, 975, 971, -1, 971, 975, 972, 968, -1, 972, 975, 974, 973, 976, 977, 978, 979, -1, 976, 980, 981, 977, -1, 977, 981, 982, 978, -1, 978, 982, 983, 979, -1, 979, 983, 980, 976, -1, 980, 983, 982, + 981, 984, 985, 986, 987, -1, 984, 988, 989, 985, -1, 985, 989, 990, 986, -1, 986, 990, 991, 987, -1, 987, 991, 988, 984, -1, 988, 991, 990, 989, 992, 993, 994, 995, -1, 992, 996, 997, 993, -1, 993, + 997, 998, 994, -1, 994, 998, 999, 995, -1, 995, 999, 996, 992, -1, 996, 999, 998, 997, 1000, 1001, 1002, 1003, -1, 1000, 1004, 1005, 1001, -1, 1001, 1005, 1006, 1002, -1, 1002, 1006, 1007, 1003, + -1, 1003, 1007, 1004, 1000, -1, 1004, 1007, 1006, 1005, 1008, 1009, 1010, 1011, -1, 1008, 1012, 1013, 1009, -1, 1009, 1013, 1014, 1010, -1, 1010, 1014, 1015, 1011, -1, 1011, 1015, 1012, 1008, -1, + 1012, 1015, 1014, 1013, 1016, 1017, 1018, 1019, -1, 1016, 1020, 1021, 1017, -1, 1017, 1021, 1022, 1018, -1, 1018, 1022, 1023, 1019, -1, 1019, 1023, 1020, 1016, -1, 1020, 1023, 1022, 1021, 1024, + 1025, 1026, 1027, -1, 1024, 1028, 1029, 1025, -1, 1025, 1029, 1030, 1026, -1, 1026, 1030, 1031, 1027, -1, 1027, 1031, 1028, 1024, -1, 1028, 1031, 1030, 1029, 1032, 1033, 1034, 1035, -1, 1032, + 1036, 1037, 1033, -1, 1033, 1037, 1038, 1034, -1, 1034, 1038, 1039, 1035, -1, 1035, 1039, 1036, 1032, -1, 1036, 1039, 1038, 1037, 1040, 1041, 1042, 1043, -1, 1040, 1044, 1045, 1041, -1, 1041, + 1045, 1046, 1042, -1, 1042, 1046, 1047, 1043, -1, 1043, 1047, 1044, 1040, -1, 1044, 1047, 1046, 1045, 1048, 1049, 1050, 1051, -1, 1048, 1052, 1053, 1049, -1, 1049, 1053, 1054, 1050, -1, 1050, + 1054, 1055, 1051, -1, 1051, 1055, 1052, 1048, -1, 1052, 1055, 1054, 1053, 1056, 1057, 1058, 1059, -1, 1056, 1060, 1061, 1057, -1, 1057, 1061, 1062, 1058, -1, 1058, 1062, 1063, 1059, -1, 1059, + 1063, 1060, 1056, -1, 1060, 1063, 1062, 1061, 1064, 1065, 1066, 1067, -1, 1064, 1068, 1069, 1065, -1, 1065, 1069, 1070, 1066, -1, 1066, 1070, 1071, 1067, -1, 1067, 1071, 1068, 1064, -1, 1068, + 1071, 1070, 1069, 1072, 1073, 1074, 1075, -1, 1072, 1076, 1077, 1073, -1, 1073, 1077, 1078, 1074, -1, 1074, 1078, 1079, 1075, -1, 1075, 1079, 1076, 1072, -1, 1076, 1079, 1078, 1077, 1080, 1081, + 1082, 1083, -1, 1080, 1084, 1085, 1081, -1, 1081, 1085, 1086, 1082, -1, 1082, 1086, 1087, 1083, -1, 1083, 1087, 1084, 1080, -1, 1084, 1087, 1086, 1085, 1088, 1089, 1090, 1091, -1, 1088, 1092, + 1093, 1089, -1, 1089, 1093, 1094, 1090, -1, 1090, 1094, 1095, 1091, -1, 1091, 1095, 1092, 1088, -1, 1092, 1095, 1094, 1093, 1096, 1097, 1098, 1099, -1, 1096, 1100, 1101, 1097, -1, 1097, 1101, + 1102, 1098, -1, 1098, 1102, 1103, 1099, -1, 1099, 1103, 1100, 1096, -1, 1100, 1103, 1102, 1101, 1104, 1105, 1106, 1107, -1, 1104, 1108, 1109, 1105, -1, 1105, 1109, 1110, 1106, -1, 1106, 1110, + 1111, 1107, -1, 1107, 1111, 1108, 1104, -1, 1108, 1111, 1110, 1109, 1112, 1113, 1114, 1115, -1, 1112, 1116, 1117, 1113, -1, 1113, 1117, 1118, 1114, -1, 1114, 1118, 1119, 1115, -1, 1115, 1119, + 1116, 1112, -1, 1116, 1119, 1118, 1117, 1120, 1121, 1122, 1123, -1, 1120, 1124, 1125, 1121, -1, 1121, 1125, 1126, 1122, -1, 1122, 1126, 1127, 1123, -1, 1123, 1127, 1124, 1120, -1, 1124, 1127, + 1126, 1125, 1128, 1129, 1130, 1131, -1, 1128, 1132, 1133, 1129, -1, 1129, 1133, 1134, 1130, -1, 1130, 1134, 1135, 1131, -1, 1131, 1135, 1132, 1128, -1, 1132, 1135, 1134, 1133, 1136, 1137, 1138, + 1139, -1, 1136, 1140, 1141, 1137, -1, 1137, 1141, 1142, 1138, -1, 1138, 1142, 1143, 1139, -1, 1139, 1143, 1140, 1136, -1, 1140, 1143, 1142, 1141, 1144, 1145, 1146, 1147, -1, 1144, 1148, 1149, + 1145, -1, 1145, 1149, 1150, 1146, -1, 1146, 1150, 1151, 1147, -1, 1147, 1151, 1148, 1144, -1, 1148, 1151, 1150, 1149, 1152, 1153, 1154, 1155, -1, 1152, 1156, 1157, 1153, -1, 1153, 1157, 1158, + 1154, -1, 1154, 1158, 1159, 1155, -1, 1155, 1159, 1156, 1152, -1, 1156, 1159, 1158, 1157, 1160, 1161, 1162, 1163, -1, 1160, 1164, 1165, 1161, -1, 1161, 1165, 1166, 1162, -1, 1162, 1166, 1167, + 1163, -1, 1163, 1167, 1164, 1160, -1, 1164, 1167, 1166, 1165, 1168, 1169, 1170, 1171, -1, 1168, 1172, 1173, 1169, -1, 1169, 1173, 1174, 1170, -1, 1170, 1174, 1175, 1171, -1, 1171, 1175, 1172, + 1168, -1, 1172, 1175, 1174, 1173, 1176, 1177, 1178, 1179, -1, 1176, 1180, 1181, 1177, -1, 1177, 1181, 1182, 1178, -1, 1178, 1182, 1183, 1179, -1, 1179, 1183, 1180, 1176, -1, 1180, 1183, 1182, + 1181, 1184, 1185, 1186, 1187, -1, 1184, 1188, 1189, 1185, -1, 1185, 1189, 1190, 1186, -1, 1186, 1190, 1191, 1187, -1, 1187, 1191, 1188, 1184, -1, 1188, 1191, 1190, 1189, 1192, 1193, 1194, 1195, + -1, 1192, 1196, 1197, 1193, -1, 1193, 1197, 1198, 1194, -1, 1194, 1198, 1199, 1195, -1, 1195, 1199, 1196, 1192, -1, 1196, 1199, 1198, 1197, 1200, 1201, 1202, 1203, -1, 1200, 1204, 1205, 1201, + -1, 1201, 1205, 1206, 1202, -1, 1202, 1206, 1207, 1203, -1, 1203, 1207, 1204, 1200, -1, 1204, 1207, 1206, 1205, 1208, 1209, 1210, 1211, -1, 1208, 1212, 1213, 1209, -1, 1209, 1213, 1214, 1210, + -1, 1210, 1214, 1215, 1211, -1, 1211, 1215, 1212, 1208, -1, 1212, 1215, 1214, 1213, 1216, 1217, 1218, 1219, -1, 1216, 1220, 1221, 1217, -1, 1217, 1221, 1222, 1218, -1, 1218, 1222, 1223, 1219, + -1, 1219, 1223, 1220, 1216, -1, 1220, 1223, 1222, 1221, 1224, 1225, 1226, 1227, -1, 1224, 1228, 1229, 1225, -1, 1225, 1229, 1230, 1226, -1, 1226, 1230, 1231, 1227, -1, 1227, 1231, 1228, 1224, + -1, 1228, 1231, 1230, 1229, 1232, 1233, 1234, 1235, -1, 1232, 1236, 1237, 1233, -1, 1233, 1237, 1238, 1234, -1, 1234, 1238, 1239, 1235, -1, 1235, 1239, 1236, 1232, -1, 1236, 1239, 1238, 1237, + 1240, 1241, 1242, 1243, -1, 1240, 1244, 1245, 1241, -1, 1241, 1245, 1246, 1242, -1, 1242, 1246, 1247, 1243, -1, 1243, 1247, 1244, 1240, -1, 1244, 1247, 1246, 1245, 1248, 1249, 1250, 1251, -1, + 1248, 1252, 1253, 1249, -1, 1249, 1253, 1254, 1250, -1, 1250, 1254, 1255, 1251, -1, 1251, 1255, 1252, 1248, -1, 1252, 1255, 1254, 1253, 1256, 1257, 1258, 1259, -1, 1256, 1260, 1261, 1257, -1, + 1257, 1261, 1262, 1258, -1, 1258, 1262, 1263, 1259, -1, 1259, 1263, 1260, 1256, -1, 1260, 1263, 1262, 1261, 1264, 1265, 1266, 1267, -1, 1264, 1268, 1269, 1265, -1, 1265, 1269, 1270, 1266, -1, + 1266, 1270, 1271, 1267, -1, 1267, 1271, 1268, 1264, -1, 1268, 1271, 1270, 1269, 1272, 1273, 1274, 1275, -1, 1272, 1276, 1277, 1273, -1, 1273, 1277, 1278, 1274, -1, 1274, 1278, 1279, 1275, -1, + 1275, 1279, 1276, 1272, -1, 1276, 1279, 1278, 1277, 1280, 1281, 1282, 1283, -1, 1280, 1284, 1285, 1281, -1, 1281, 1285, 1286, 1282, -1, 1282, 1286, 1287, 1283, -1, 1283, 1287, 1284, 1280, -1, + 1284, 1287, 1286, 1285, 1288, 1289, 1290, 1291, -1, 1288, 1292, 1293, 1289, -1, 1289, 1293, 1294, 1290, -1, 1290, 1294, 1295, 1291, -1, 1291, 1295, 1292, 1288, -1, 1292, 1295, 1294, 1293, 1296, + 1297, 1298, 1299, -1, 1296, 1300, 1301, 1297, -1, 1297, 1301, 1302, 1298, -1, 1298, 1302, 1303, 1299, -1, 1299, 1303, 1300, 1296, -1, 1300, 1303, 1302, 1301, 1304, 1305, 1306, 1307, -1, 1304, + 1308, 1309, 1305, -1, 1305, 1309, 1310, 1306, -1, 1306, 1310, 1311, 1307, -1, 1307, 1311, 1308, 1304, -1, 1308, 1311, 1310, 1309, 1312, 1313, 1314, 1315, -1, 1312, 1316, 1317, 1313, -1, 1313, + 1317, 1318, 1314, -1, 1314, 1318, 1319, 1315, -1, 1315, 1319, 1316, 1312, -1, 1316, 1319, 1318, 1317, 1320, 1321, 1322, 1323, -1, 1320, 1324, 1325, 1321, -1, 1321, 1325, 1326, 1322, -1, 1322, + 1326, 1327, 1323, -1, 1323, 1327, 1324, 1320, -1, 1324, 1327, 1326, 1325, 1328, 1329, 1330, 1331, -1, 1328, 1332, 1333, 1329, -1, 1329, 1333, 1334, 1330, -1, 1330, 1334, 1335, 1331, -1, 1331, + 1335, 1332, 1328, -1, 1332, 1335, 1334, 1333, 1336, 1337, 1338, 1339, -1, 1336, 1340, 1341, 1337, -1, 1337, 1341, 1342, 1338, -1, 1338, 1342, 1343, 1339, -1, 1339, 1343, 1340, 1336, -1, 1340, + 1343, 1342, 1341, 1344, 1345, 1346, 1347, -1, 1344, 1348, 1349, 1345, -1, 1345, 1349, 1350, 1346, -1, 1346, 1350, 1351, 1347, -1, 1347, 1351, 1348, 1344, -1, 1348, 1351, 1350, 1349, 1352, 1353, + 1354, 1355, -1, 1352, 1356, 1357, 1353, -1, 1353, 1357, 1358, 1354, -1, 1354, 1358, 1359, 1355, -1, 1355, 1359, 1356, 1352, -1, 1356, 1359, 1358, 1357, 1360, 1361, 1362, 1363, -1, 1360, 1364, + 1365, 1361, -1, 1361, 1365, 1366, 1362, -1, 1362, 1366, 1367, 1363, -1, 1363, 1367, 1364, 1360, -1, 1364, 1367, 1366, 1365, 1368, 1369, 1370, 1371, -1, 1368, 1372, 1373, 1369, -1, 1369, 1373, + 1374, 1370, -1, 1370, 1374, 1375, 1371, -1, 1371, 1375, 1372, 1368, -1, 1372, 1375, 1374, 1373, 1376, 1377, 1378, 1379, -1, 1376, 1380, 1381, 1377, -1, 1377, 1381, 1382, 1378, -1, 1378, 1382, + 1383, 1379, -1, 1379, 1383, 1380, 1376, -1, 1380, 1383, 1382, 1381, 1384, 1385, 1386, 1387, -1, 1384, 1388, 1389, 1385, -1, 1385, 1389, 1390, 1386, -1, 1386, 1390, 1391, 1387, -1, 1387, 1391, + 1388, 1384, -1, 1388, 1391, 1390, 1389, 1392, 1393, 1394, 1395, -1, 1392, 1396, 1397, 1393, -1, 1393, 1397, 1398, 1394, -1, 1394, 1398, 1399, 1395, -1, 1395, 1399, 1396, 1392, -1, 1396, 1399, + 1398, 1397, 1400, 1401, 1402, 1403, -1, 1400, 1404, 1405, 1401, -1, 1401, 1405, 1406, 1402, -1, 1402, 1406, 1407, 1403, -1, 1403, 1407, 1404, 1400, -1, 1404, 1407, 1406, 1405, 1408, 1409, + 1410, 1411, -1, 1408, 1412, 1413, 1409, -1, 1409, 1413, 1414, 1410, -1, 1410, 1414, 1415, 1411, -1, 1411, 1415, 1412, 1408, -1, 1412, 1415, 1414, 1413, 1416, 1417, 1418, 1419, -1, 1416, + 1420, 1421, 1417, -1, 1417, 1421, 1422, 1418, -1, 1418, 1422, 1423, 1419, -1, 1419, 1423, 1420, 1416, -1, 1420, 1423, 1422, 1421, 1424, 1425, 1426, 1427, -1, 1424, 1428, 1429, 1425, -1, + 1425, 1429, 1430, 1426, -1, 1426, 1430, 1431, 1427, -1, 1427, 1431, 1428, 1424, -1, 1428, 1431, 1430, 1429, 1432, 1433, 1434, 1435, -1, 1432, 1436, 1437, 1433, -1, 1433, 1437, 1438, 1434, + -1, 1434, 1438, 1439, 1435, -1, 1435, 1439, 1436, 1432, -1, 1436, 1439, 1438, 1437, 1440, 1441, 1442, 1443, -1, 1440, 1444, 1445, 1441, -1, 1441, 1445, 1446, 1442, -1, 1442, 1446, 1447, 1443, + -1, 1443, 1447, 1444, 1440, -1, 1444, 1447, 1446, 1445, 1448, 1449, 1450, 1451, -1, 1448, 1452, 1453, 1449, -1, 1449, 1453, 1454, 1450, -1, 1450, 1454, 1455, 1451, -1, 1451, 1455, 1452, 1448, + -1, 1452, 1455, 1454, 1453, 1456, 1457, 1458, 1459, -1, 1456, 1460, 1461, 1457, -1, 1457, 1461, 1462, 1458, -1, 1458, 1462, 1463, 1459, -1, 1459, 1463, 1460, 1456, -1, 1460, 1463, 1462, 1461, + 1464, 1465, 1466, 1467, -1, 1464, 1468, 1469, 1465, -1, 1465, 1469, 1470, 1466, -1, 1466, 1470, 1471, 1467, -1, 1467, 1471, 1468, 1464, -1, 1468, 1471, 1470, 1469, 1472, 1473, 1474, 1475, -1, + 1472, 1476, 1477, 1473, -1, 1473, 1477, 1478, 1474, -1, 1474, 1478, 1479, 1475, -1, 1475, 1479, 1476, 1472, -1, 1476, 1479, 1478, 1477, 1480, 1481, 1482, 1483, -1, 1480, 1484, 1485, 1481, -1, + 1481, 1485, 1486, 1482, -1, 1482, 1486, 1487, 1483, -1, 1483, 1487, 1484, 1480, -1, 1484, 1487, 1486, 1485, 1488, 1489, 1490, 1491, -1, 1488, 1492, 1493, 1489, -1, 1489, 1493, 1494, 1490, -1, + 1490, 1494, 1495, 1491, -1, 1491, 1495, 1492, 1488, -1, 1492, 1495, 1494, 1493, 1496, 1497, 1498, 1499, -1, 1496, 1500, 1501, 1497, -1, 1497, 1501, 1502, 1498, -1, 1498, 1502, 1503, 1499, -1, + 1499, 1503, 1500, 1496, -1, 1500, 1503, 1502, 1501, 1504, 1505, 1506, 1507, -1, 1504, 1508, 1509, 1505, -1, 1505, 1509, 1510, 1506, -1, 1506, 1510, 1511, 1507, -1, 1507, 1511, 1508, 1504, -1, + 1508, 1511, 1510, 1509, 1512, 1513, 1514, 1515, -1, 1512, 1516, 1517, 1513, -1, 1513, 1517, 1518, 1514, -1, 1514, 1518, 1519, 1515, -1, 1515, 1519, 1516, 1512, -1, 1516, 1519, 1518, 1517, 1520, + 1521, 1522, 1523, -1, 1520, 1524, 1525, 1521, -1, 1521, 1525, 1526, 1522, -1, 1522, 1526, 1527, 1523, -1, 1523, 1527, 1524, 1520, -1, 1524, 1527, 1526, 1525, 1528, 1529, 1530, 1531, -1, 1528, 1532, + 1533, 1529, -1, 1529, 1533, 1534, 1530, -1, 1530, 1534, 1535, 1531, -1, 1531, 1535, 1532, 1528, -1, 1532, 1535, 1534, 1533, 1536, 1537, 1538, 1539, -1, 1536, 1540, 1541, 1537, -1, 1537, 1541, 1542, + 1538, -1, 1538, 1542, 1543, 1539, -1, 1539, 1543, 1540, 1536, -1, 1540, 1543, 1542, 1541, 1544, 1545, 1546, 1547, -1, 1544, 1548, 1549, 1545, -1, 1545, 1549, 1550, 1546, -1, 1546, 1550, 1551, 1547, + -1, 1547, 1551, 1548, 1544, -1, 1548, 1551, 1550, 1549, 1552, 1553, 1554, 1555, -1, 1552, 1556, 1557, 1553, -1, 1553, 1557, 1558, 1554, -1, 1554, 1558, 1559, 1555, -1, 1555, 1559, 1556, 1552, -1, 1556, + 1559, 1558, 1557, 1560, 1561, 1562, 1563, -1, 1560, 1564, 1565, 1561, -1, 1561, 1565, 1566, 1562, -1, 1562, 1566, 1567, 1563, -1, 1563, 1567, 1564, 1560, -1, 1564, 1567, 1566, 1565, 1568, 1569, 1570, 1571, + -1, 1568, 1572, 1573, 1569, -1, 1569, 1573, 1574, 1570, -1, 1570, 1574, 1575, 1571, -1, 1571, 1575, 1572, 1568, -1, 1572, 1575, 1574, 1573, 1576, 1577, 1578, 1579, -1, 1576, 1580, 1581, 1577, -1, + 1577, 1581, 1582, 1578, -1, 1578, 1582, 1583, 1579, -1, 1579, 1583, 1580, 1576, -1, 1580, 1583, 1582, 1581, 1584, 1585, 1586, 1587, -1, 1584, 1588, 1589, 1585, -1, 1585, 1589, 1590, 1586, -1, + 1586, 1590, 1591, 1587, -1, 1587, 1591, 1588, 1584, -1, 1588, 1591, 1590, 1589, 1592, 1593, 1594, 1595, -1, 1592, 1596, 1597, 1593, -1, 1593, 1597, 1598, 1594, -1, 1594, 1598, 1599, 1595, -1, + 1595, 1599, 1596, 1592, -1, 1596, 1599, 1598, 1597, 1600, 1601, 1602, 1603, -1, 1600, 1604, 1605, 1601, -1, 1601, 1605, 1606, 1602, -1, 1602, 1606, 1607, 1603, -1, 1603, 1607, 1604, 1600, -1, + 1604, 1607, 1606, 1605, 1608, 1609, 1610, 1611, -1, 1608, 1612, 1613, 1609, -1, 1609, 1613, 1614, 1610, -1, 1610, 1614, 1615, 1611, -1, 1611, 1615, 1612, 1608, -1, 1612, 1615, 1614, 1613, 1616, + 1617, 1618, 1619, -1, 1616, 1620, 1621, 1617, -1, 1617, 1621, 1622, 1618, -1, 1618, 1622, 1623, 1619, -1, 1619, 1623, 1620, 1616, -1, 1620, 1623, 1622, 1621, 1624, 1625, 1626, 1627, -1, 1624, + 1628, 1629, 1625, -1, 1625, 1629, 1630, 1626, -1, 1626, 1630, 1631, 1627, -1, 1627, 1631, 1628, 1624, -1, 1628, 1631, 1630, 1629, 1632, 1633, 1634, 1635, -1, 1632, 1636, 1637, 1633, -1, 1633, + 1637, 1638, 1634, -1, 1634, 1638, 1639, 1635, -1, 1635, 1639, 1636, 1632, -1, 1636, 1639, 1638, 1637, 1640, 1641, 1642, 1643, -1, 1640, 1644, 1645, 1641, -1, 1641, 1645, 1646, 1642, -1, 1642, + 1646, 1647, 1643, -1, 1643, 1647, 1644, 1640, -1, 1644, 1647, 1646, 1645, 1648, 1649, 1650, 1651, -1, 1648, 1652, 1653, 1649, -1, 1649, 1653, 1654, 1650, -1, 1650, 1654, 1655, 1651, -1, 1651, + 1655, 1652, 1648, -1, 1652, 1655, 1654, 1653, 1656, 1657, 1658, 1659, -1, 1656, 1660, 1661, 1657, -1, 1657, 1661, 1662, 1658, -1, 1658, 1662, 1663, 1659, -1, 1659, 1663, 1660, 1656, -1, 1660, + 1663, 1662, 1661, 1664, 1665, 1666, 1667, -1, 1664, 1668, 1669, 1665, -1, 1665, 1669, 1670, 1666, -1, 1666, 1670, 1671, 1667, -1, 1667, 1671, 1668, 1664, -1, 1668, 1671, 1670, 1669, 1672, 1673, + 1674, 1675, -1, 1672, 1676, 1677, 1673, -1, 1673, 1677, 1678, 1674, -1, 1674, 1678, 1679, 1675, -1, 1675, 1679, 1676, 1672, -1, 1676, 1679, 1678, 1677, 1680, 1681, 1682, 1683, -1, 1680, 1684, + 1685, 1681, -1, 1681, 1685, 1686, 1682, -1, 1682, 1686, 1687, 1683, -1, 1683, 1687, 1684, 1680, -1, 1684, 1687, 1686, 1685, 1688, 1689, 1690, 1691, -1, 1688, 1692, 1693, 1689, -1, 1689, 1693, + 1694, 1690, -1, 1690, 1694, 1695, 1691, -1, 1691, 1695, 1692, 1688, -1, 1692, 1695, 1694, 1693, 1696, 1697, 1698, 1699, -1, 1696, 1700, 1701, 1697, -1, 1697, 1701, 1702, 1698, -1, 1698, 1702, + 1703, 1699, -1, 1699, 1703, 1700, 1696, -1, 1700, 1703, 1702, 1701, 1704, 1705, 1706, 1707, -1, 1704, 1708, 1709, 1705, -1, 1705, 1709, 1710, 1706, -1, 1706, 1710, 1711, 1707, -1, 1707, 1711, + 1708, 1704, -1, 1708, 1711, 1710, 1709, 1712, 1713, 1714, 1715, -1, 1712, 1716, 1717, 1713, -1, 1713, 1717, 1718, 1714, -1, 1714, 1718, 1719, 1715, -1, 1715, 1719, 1716, 1712, -1, 1716, 1719, 1718, 1717}; + +double coordsTT[5160]={ + 0.0054015000000000044, 0.0054015000000000053, 0, 0.2106585, 0.0054015000000000053, 0, 0.2106585, 0.039611, 0, 0.2106585, 0.10803, 0, 0.2106585, + 0.17644899999999999, 0, 0.2106585, 0.2106585, 0, 0.0054015000000000044, 0.2106585, 0, 0.0054015000000000044, 0.0054015000000000053, 0.21364999999999998, + 0.2106585, 0.0054015000000000053, 0.21364999999999998, 0.2106585, 0.039611, 0.21364999999999998, 0.2106585, 0.10803, 0.21364999999999998, 0.2106585, + 0.17644899999999999, 0.21364999999999998, 0.2106585, 0.2106585, 0.21364999999999998, 0.0054015000000000044, 0.2106585, 0.21364999999999998, + 0.0054015000000000044, 0.0054015000000000053, 0.21364999999999998, 0.2106585, 0.0054015000000000053, 0.21364999999999998, 0.2106585, 0.039611, + 0.21364999999999998, 0.2106585, 0.10803, 0.21364999999999998, 0.2106585, 0.17644899999999999, 0.21364999999999998, 0.2106585, 0.2106585, 0.21364999999999998, + 0.0054015000000000044, 0.2106585, 0.21364999999999998, 0.0054015000000000044, 0.0054015000000000053, 0.42729999999999996, 0.2106585, 0.0054015000000000053, + 0.42729999999999996, 0.2106585, 0.039611, 0.42729999999999996, 0.2106585, 0.10803, 0.42729999999999996, 0.2106585, 0.17644899999999999, 0.42729999999999996, + 0.2106585, 0.2106585, 0.42729999999999996, 0.0054015000000000044, 0.2106585, 0.42729999999999996, 0.0054015000000000044, 0.0054015000000000053, + 0.42729999999999996, 0.2106585, 0.0054015000000000053, 0.42729999999999996, 0.2106585, 0.039611, 0.42729999999999996, 0.2106585, 0.10803, 0.42729999999999996, + 0.2106585, 0.17644899999999999, 0.42729999999999996, 0.2106585, 0.2106585, 0.42729999999999996, 0.0054015000000000044, 0.2106585, 0.42729999999999996, + 0.0054015000000000044, 0.0054015000000000053, 0.64094999999999991, 0.2106585, 0.0054015000000000053, 0.64094999999999991, 0.2106585, 0.039611, + 0.64094999999999991, 0.2106585, 0.10803, 0.64094999999999991, 0.2106585, 0.17644899999999999, 0.64094999999999991, 0.2106585, 0.2106585, 0.64094999999999991, + 0.0054015000000000044, 0.2106585, 0.64094999999999991, 0.0054015000000000044, 0.0054015000000000053, 0.64094999999999991, 0.2106585, 0.0054015000000000053, + 0.64094999999999991, 0.2106585, 0.039611, 0.64094999999999991, 0.2106585, 0.10803, 0.64094999999999991, 0.2106585, 0.17644899999999999, 0.64094999999999991, + 0.2106585, 0.2106585, 0.64094999999999991, 0.0054015000000000044, 0.2106585, 0.64094999999999991, 0.0054015000000000044, 0.0054015000000000053, + 0.85459999999999992, 0.2106585, 0.0054015000000000053, 0.85459999999999992, 0.2106585, 0.039611, 0.85459999999999992, 0.2106585, 0.10803, 0.85459999999999992, + 0.2106585, 0.17644899999999999, 0.85459999999999992, 0.2106585, 0.2106585, 0.85459999999999992, 0.0054015000000000044, 0.2106585, 0.85459999999999992, + 0.0054015000000000044, 0.0054015000000000053, 0.85459999999999992, 0.2106585, 0.0054015000000000053, 0.85459999999999992, 0.2106585, 0.039611, + 0.85459999999999992, 0.2106585, 0.10803, 0.85459999999999992, 0.2106585, 0.17644899999999999, 0.85459999999999992, 0.2106585, 0.2106585, 0.85459999999999992, + 0.0054015000000000044, 0.2106585, 0.85459999999999992, 0.0054015000000000044, 0.0054015000000000053, 1.0682499999999999, 0.2106585, 0.0054015000000000053, + 1.0682499999999999, 0.2106585, 0.039611, 1.0682499999999999, 0.2106585, 0.10803, + 1.0682499999999999, 0.2106585, 0.17644899999999999, 1.0682499999999999, 0.2106585, 0.2106585, 1.0682499999999999, 0.0054015000000000044, 0.2106585, + 1.0682499999999999, 0.0054015000000000044, 0.0054015000000000053, 1.0682499999999999, 0.2106585, 0.0054015000000000053, 1.0682499999999999, 0.2106585, 0.039611, + 1.0682499999999999, 0.2106585, 0.10803, 1.0682499999999999, 0.2106585, 0.17644899999999999, 1.0682499999999999, 0.2106585, 0.2106585, 1.0682499999999999, + 0.0054015000000000044, 0.2106585, 1.0682499999999999, 0.0054015000000000044, 0.0054015000000000053, 1.2818999999999998, 0.2106585, 0.0054015000000000053, + 1.2818999999999998, 0.2106585, 0.039611, 1.2818999999999998, 0.2106585, 0.10803, 1.2818999999999998, 0.2106585, 0.17644899999999999, 1.2818999999999998, + 0.2106585, 0.2106585, 1.2818999999999998, 0.0054015000000000044, 0.2106585, 1.2818999999999998, 0.0054015000000000044, 0.0054015000000000053, 1.2818999999999998, + 0.2106585, 0.0054015000000000053, 1.2818999999999998, 0.2106585, 0.039611, 1.2818999999999998, 0.2106585, 0.10803, 1.2818999999999998, 0.2106585, + 0.17644899999999999, 1.2818999999999998, 0.2106585, 0.2106585, 1.2818999999999998, 0.0054015000000000044, 0.2106585, 1.2818999999999998, 0.0054015000000000044, + 0.0054015000000000053, 1.4955499999999999, 0.2106585, 0.0054015000000000053, 1.4955499999999999, 0.2106585, 0.039611, 1.4955499999999999, 0.2106585, 0.10803, + 1.4955499999999999, 0.2106585, 0.17644899999999999, 1.4955499999999999, 0.2106585, 0.2106585, 1.4955499999999999, 0.0054015000000000044, 0.2106585, + 1.4955499999999999, 0.0054015000000000044, 0.0054015000000000053, 1.4955499999999999, 0.2106585, 0.0054015000000000053, 1.4955499999999999, 0.2106585, 0.039611, + 1.4955499999999999, 0.2106585, 0.10803, 1.4955499999999999, 0.2106585, 0.17644899999999999, 1.4955499999999999, 0.2106585, 0.2106585, 1.4955499999999999, + 0.0054015000000000044, 0.2106585, 1.4955499999999999, 0.0054015000000000044, 0.0054015000000000053, 1.7091999999999998, 0.2106585, 0.0054015000000000053, + 1.7091999999999998, 0.2106585, 0.039611, 1.7091999999999998, 0.2106585, 0.10803, 1.7091999999999998, 0.2106585, 0.17644899999999999, 1.7091999999999998, + 0.2106585, 0.2106585, 1.7091999999999998, 0.0054015000000000044, 0.2106585, 1.7091999999999998, 0.0054015000000000044, 0.0054015000000000053, 1.7091999999999998, + 0.2106585, 0.0054015000000000053, 1.7091999999999998, 0.2106585, 0.039611, 1.7091999999999998, 0.2106585, 0.10803, 1.7091999999999998, 0.2106585, + 0.17644899999999999, 1.7091999999999998, 0.2106585, 0.2106585, 1.7091999999999998, 0.0054015000000000044, 0.2106585, 1.7091999999999998, 0.0054015000000000044, + 0.0054015000000000053, 1.9228499999999997, 0.2106585, 0.0054015000000000053, 1.9228499999999997, 0.2106585, 0.039611, 1.9228499999999997, 0.2106585, 0.10803, + 1.9228499999999997, 0.2106585, 0.17644899999999999, 1.9228499999999997, 0.2106585, 0.2106585, 1.9228499999999997, 0.0054015000000000044, 0.2106585, + 1.9228499999999997, 0.0054015000000000044, 0.0054015000000000053, 1.9228499999999997, 0.2106585, 0.0054015000000000053, 1.9228499999999997, 0.2106585, 0.039611, + 1.9228499999999997, 0.2106585, 0.10803, 1.9228499999999997, 0.2106585, 0.17644899999999999, 1.9228499999999997, 0.2106585, 0.2106585, 1.9228499999999997, + 0.0054015000000000044, 0.2106585, 1.9228499999999997, 0.0054015000000000044, + 0.0054015000000000053, 2.1364999999999998, 0.2106585, 0.0054015000000000053, 2.1364999999999998, 0.2106585, 0.039611, 2.1364999999999998, 0.2106585, + 0.10803, 2.1364999999999998, 0.2106585, 0.17644899999999999, 2.1364999999999998, 0.2106585, 0.2106585, 2.1364999999999998, 0.0054015000000000044, 0.2106585, + 2.1364999999999998, 0.0054015000000000044, 0.0054015000000000053, 2.1364999999999998, 0.2106585, 0.0054015000000000053, 2.1364999999999998, 0.2106585, 0.039611, + 2.1364999999999998, 0.2106585, 0.10803, 2.1364999999999998, 0.2106585, 0.17644899999999999, 2.1364999999999998, 0.2106585, 0.2106585, 2.1364999999999998, + 0.0054015000000000044, 0.2106585, 2.1364999999999998, 0.0054015000000000044, 0.0054015000000000053, 2.3501499999999997, 0.2106585, 0.0054015000000000053, + 2.3501499999999997, 0.2106585, 0.039611, 2.3501499999999997, 0.2106585, 0.10803, 2.3501499999999997, 0.2106585, 0.17644899999999999, 2.3501499999999997, + 0.2106585, 0.2106585, 2.3501499999999997, 0.0054015000000000044, 0.2106585, 2.3501499999999997, 0.0054015000000000044, 0.0054015000000000053, 2.3501499999999997, + 0.2106585, 0.0054015000000000053, 2.3501499999999997, 0.2106585, 0.039611, 2.3501499999999997, 0.2106585, 0.10803, 2.3501499999999997, 0.2106585, + 0.17644899999999999, 2.3501499999999997, 0.2106585, 0.2106585, 2.3501499999999997, 0.0054015000000000044, 0.2106585, 2.3501499999999997, 0.0054015000000000044, + 0.0054015000000000053, 2.5637999999999996, 0.2106585, 0.0054015000000000053, 2.5637999999999996, 0.2106585, 0.039611, 2.5637999999999996, 0.2106585, 0.10803, + 2.5637999999999996, 0.2106585, 0.17644899999999999, 2.5637999999999996, 0.2106585, 0.2106585, 2.5637999999999996, 0.0054015000000000044, 0.2106585, + 2.5637999999999996, 0.0054015000000000044, 0.0054015000000000053, 2.5637999999999996, 0.2106585, 0.0054015000000000053, 2.5637999999999996, 0.2106585, 0.039611, + 2.5637999999999996, 0.2106585, 0.10803, 2.5637999999999996, 0.2106585, 0.17644899999999999, 2.5637999999999996, 0.2106585, 0.2106585, 2.5637999999999996, + 0.0054015000000000044, 0.2106585, 2.5637999999999996, 0.0054015000000000044, 0.0054015000000000053, 2.7774499999999995, 0.2106585, 0.0054015000000000053, + 2.7774499999999995, 0.2106585, 0.039611, 2.7774499999999995, 0.2106585, 0.10803, 2.7774499999999995, 0.2106585, 0.17644899999999999, 2.7774499999999995, + 0.2106585, 0.2106585, 2.7774499999999995, 0.0054015000000000044, 0.2106585, 2.7774499999999995, 0.0054015000000000044, 0.0054015000000000053, 2.7774499999999995, + 0.2106585, 0.0054015000000000053, 2.7774499999999995, 0.2106585, 0.039611, 2.7774499999999995, 0.2106585, 0.10803, 2.7774499999999995, 0.2106585, + 0.17644899999999999, 2.7774499999999995, 0.2106585, 0.2106585, 2.7774499999999995, 0.0054015000000000044, 0.2106585, 2.7774499999999995, 0.0054015000000000044, + 0.0054015000000000053, 2.9910999999999999, 0.2106585, 0.0054015000000000053, 2.9910999999999999, 0.2106585, 0.039611, 2.9910999999999999, 0.2106585, 0.10803, + 2.9910999999999999, 0.2106585, 0.17644899999999999, 2.9910999999999999, 0.2106585, 0.2106585, 2.9910999999999999, 0.0054015000000000044, 0.2106585, + 2.9910999999999999, 0.0054015000000000044, 0.0054015000000000053, 2.9910999999999999, 0.2106585, 0.0054015000000000053, 2.9910999999999999, 0.2106585, 0.039611, + 2.9910999999999999, 0.2106585, 0.10803, 2.9910999999999999, + 0.2106585, 0.17644899999999999, 2.9910999999999999, 0.2106585, 0.2106585, 2.9910999999999999, 0.0054015000000000044, 0.2106585, 2.9910999999999999, + 0.0054015000000000044, 0.0054015000000000053, 3.2047499999999998, 0.2106585, 0.0054015000000000053, 3.2047499999999998, 0.2106585, 0.039611, 3.2047499999999998, + 0.2106585, 0.10803, 3.2047499999999998, 0.2106585, 0.17644899999999999, 3.2047499999999998, 0.2106585, 0.2106585, 3.2047499999999998, 0.0054015000000000044, + 0.2106585, 3.2047499999999998, 0.0054015000000000044, 0.0054015000000000053, 3.2047499999999998, 0.2106585, 0.0054015000000000053, 3.2047499999999998, 0.2106585, + 0.039611, 3.2047499999999998, 0.2106585, 0.10803, 3.2047499999999998, 0.2106585, 0.17644899999999999, 3.2047499999999998, 0.2106585, 0.2106585, + 3.2047499999999998, 0.0054015000000000044, 0.2106585, 3.2047499999999998, 0.0054015000000000044, 0.0054015000000000053, 3.4183999999999997, 0.2106585, + 0.0054015000000000053, 3.4183999999999997, 0.2106585, 0.039611, 3.4183999999999997, 0.2106585, 0.10803, 3.4183999999999997, 0.2106585, 0.17644899999999999, + 3.4183999999999997, 0.2106585, 0.2106585, 3.4183999999999997, 0.0054015000000000044, 0.2106585, 3.4183999999999997, 0.0054015000000000044, 0.0054015000000000053, + 3.4183999999999997, 0.2106585, 0.0054015000000000053, 3.4183999999999997, 0.2106585, 0.039611, 3.4183999999999997, 0.2106585, 0.10803, 3.4183999999999997, + 0.2106585, 0.17644899999999999, 3.4183999999999997, 0.2106585, 0.2106585, 3.4183999999999997, 0.0054015000000000044, 0.2106585, 3.4183999999999997, + 0.0054015000000000044, 0.0054015000000000053, 3.6320499999999996, 0.2106585, 0.0054015000000000053, 3.6320499999999996, 0.2106585, 0.039611, 3.6320499999999996, + 0.2106585, 0.10803, 3.6320499999999996, 0.2106585, 0.17644899999999999, 3.6320499999999996, 0.2106585, 0.2106585, 3.6320499999999996, 0.0054015000000000044, + 0.2106585, 3.6320499999999996, 0.0054015000000000044, 0.0054015000000000053, 3.6320499999999996, 0.2106585, 0.0054015000000000053, 3.6320499999999996, 0.2106585, + 0.039611, 3.6320499999999996, 0.2106585, 0.10803, 3.6320499999999996, 0.2106585, 0.17644899999999999, 3.6320499999999996, 0.2106585, 0.2106585, + 3.6320499999999996, 0.0054015000000000044, 0.2106585, 3.6320499999999996, 0.0054015000000000044, 0.0054015000000000053, 3.8456999999999995, 0.2106585, + 0.0054015000000000053, 3.8456999999999995, 0.2106585, 0.039611, 3.8456999999999995, 0.2106585, 0.10803, 3.8456999999999995, 0.2106585, 0.17644899999999999, + 3.8456999999999995, 0.2106585, 0.2106585, 3.8456999999999995, 0.0054015000000000044, 0.2106585, 3.8456999999999995, 0.0054015000000000044, 0.0054015000000000053, + 3.8456999999999995, 0.2106585, 0.0054015000000000053, 3.8456999999999995, 0.2106585, 0.039611, 3.8456999999999995, 0.2106585, 0.10803, 3.8456999999999995, + 0.2106585, 0.17644899999999999, 3.8456999999999995, 0.2106585, 0.2106585, 3.8456999999999995, 0.0054015000000000044, 0.2106585, 3.8456999999999995, + 0.0054015000000000044, 0.0054015000000000053, 4.0593499999999993, 0.2106585, 0.0054015000000000053, 4.0593499999999993, 0.2106585, 0.039611, 4.0593499999999993, + 0.2106585, 0.10803, 4.0593499999999993, 0.2106585, 0.17644899999999999, 4.0593499999999993, 0.2106585, 0.2106585, 4.0593499999999993, 0.0054015000000000044, + 0.2106585, 4.0593499999999993, 0.0054015000000000044, 0.0054015000000000053, + 4.0593499999999993, 0.2106585, 0.0054015000000000053, 4.0593499999999993, 0.2106585, 0.039611, 4.0593499999999993, 0.2106585, 0.10803, 4.0593499999999993, + 0.2106585, 0.17644899999999999, 4.0593499999999993, 0.2106585, 0.2106585, 4.0593499999999993, 0.0054015000000000044, 0.2106585, 4.0593499999999993, + 0.0054015000000000044, 0.0054015000000000053, 4.2729999999999997, 0.2106585, 0.0054015000000000053, 4.2729999999999997, 0.2106585, 0.039611, 4.2729999999999997, + 0.2106585, 0.10803, 4.2729999999999997, 0.2106585, 0.17644899999999999, 4.2729999999999997, 0.2106585, 0.2106585, 4.2729999999999997, 0.0054015000000000044, + 0.2106585, 4.2729999999999997, 0.24197569714517145, 0.025915697145171439, 0, 0.26483839536511933, 0.025915697145171439, 0, 0.26483839536511933, + 0.048778395365119298, 0, 0.24197569714517145, 0.048778395365119298, 0, 0.24197569714517145, 0.025915697145171439, 0.21364999999999998, 0.26483839536511933, + 0.025915697145171439, 0.21364999999999998, 0.26483839536511933, 0.048778395365119298, 0.21364999999999998, 0.24197569714517145, 0.048778395365119298, + 0.21364999999999998, 0.24197569714517145, 0.025915697145171439, 0.21364999999999998, 0.26483839536511933, 0.025915697145171439, 0.21364999999999998, + 0.26483839536511933, 0.048778395365119298, 0.21364999999999998, 0.24197569714517145, 0.048778395365119298, 0.21364999999999998, 0.24197569714517145, + 0.025915697145171439, 0.42729999999999996, 0.26483839536511933, 0.025915697145171439, 0.42729999999999996, 0.26483839536511933, 0.048778395365119298, + 0.42729999999999996, 0.24197569714517145, 0.048778395365119298, 0.42729999999999996, 0.24197569714517145, 0.025915697145171439, 0.42729999999999996, + 0.26483839536511933, 0.025915697145171439, 0.42729999999999996, 0.26483839536511933, 0.048778395365119298, 0.42729999999999996, 0.24197569714517145, + 0.048778395365119298, 0.42729999999999996, 0.24197569714517145, 0.025915697145171439, 0.64094999999999991, 0.26483839536511933, 0.025915697145171439, + 0.64094999999999991, 0.26483839536511933, 0.048778395365119298, 0.64094999999999991, 0.24197569714517145, 0.048778395365119298, 0.64094999999999991, + 0.24197569714517145, 0.025915697145171439, 0.64094999999999991, 0.26483839536511933, 0.025915697145171439, 0.64094999999999991, 0.26483839536511933, + 0.048778395365119298, 0.64094999999999991, 0.24197569714517145, 0.048778395365119298, 0.64094999999999991, 0.24197569714517145, 0.025915697145171439, + 0.85459999999999992, 0.26483839536511933, 0.025915697145171439, 0.85459999999999992, 0.26483839536511933, 0.048778395365119298, 0.85459999999999992, + 0.24197569714517145, 0.048778395365119298, 0.85459999999999992, 0.24197569714517145, 0.025915697145171439, 0.85459999999999992, 0.26483839536511933, + 0.025915697145171439, 0.85459999999999992, 0.26483839536511933, 0.048778395365119298, 0.85459999999999992, 0.24197569714517145, 0.048778395365119298, + 0.85459999999999992, 0.24197569714517145, 0.025915697145171439, 1.0682499999999999, 0.26483839536511933, 0.025915697145171439, 1.0682499999999999, + 0.26483839536511933, 0.048778395365119298, 1.0682499999999999, 0.24197569714517145, 0.048778395365119298, 1.0682499999999999, 0.24197569714517145, + 0.025915697145171439, 1.0682499999999999, 0.26483839536511933, 0.025915697145171439, 1.0682499999999999, 0.26483839536511933, 0.048778395365119298, + 1.0682499999999999, 0.24197569714517145, 0.048778395365119298, 1.0682499999999999, 0.24197569714517145, 0.025915697145171439, 1.2818999999999998, + 0.26483839536511933, 0.025915697145171439, 1.2818999999999998, 0.26483839536511933, 0.048778395365119298, 1.2818999999999998, 0.24197569714517145, + 0.048778395365119298, 1.2818999999999998, 0.24197569714517145, 0.025915697145171439, 1.2818999999999998, 0.26483839536511933, 0.025915697145171439, + 1.2818999999999998, 0.26483839536511933, 0.048778395365119298, 1.2818999999999998, 0.24197569714517145, 0.048778395365119298, 1.2818999999999998, + 0.24197569714517145, 0.025915697145171439, 1.4955499999999999, 0.26483839536511933,0.025915697145171439, 1.4955499999999999, 0.26483839536511933, + 0.048778395365119298, 1.4955499999999999, 0.24197569714517145, 0.048778395365119298, + 1.4955499999999999, 0.24197569714517145, 0.025915697145171439, 1.4955499999999999, 0.26483839536511933, 0.025915697145171439, 1.4955499999999999, + 0.26483839536511933, 0.048778395365119298, 1.4955499999999999, 0.24197569714517145, 0.048778395365119298, 1.4955499999999999, 0.24197569714517145, + 0.025915697145171439, 1.7091999999999998, 0.26483839536511933, 0.025915697145171439, 1.7091999999999998, 0.26483839536511933, 0.048778395365119298, + 1.7091999999999998, 0.24197569714517145, 0.048778395365119298, 1.7091999999999998, 0.24197569714517145, 0.025915697145171439, 1.7091999999999998, + 0.26483839536511933, 0.025915697145171439, 1.7091999999999998, 0.26483839536511933, 0.048778395365119298, 1.7091999999999998, 0.24197569714517145, + 0.048778395365119298, 1.7091999999999998, 0.24197569714517145, 0.025915697145171439, 1.9228499999999997, 0.26483839536511933, 0.025915697145171439, + 1.9228499999999997, 0.26483839536511933, 0.048778395365119298, 1.9228499999999997, 0.24197569714517145, 0.048778395365119298, 1.9228499999999997, + 0.24197569714517145, 0.025915697145171439, 1.9228499999999997, 0.26483839536511933, 0.025915697145171439, 1.9228499999999997, 0.26483839536511933, + 0.048778395365119298, 1.9228499999999997, 0.24197569714517145, 0.048778395365119298, 1.9228499999999997, 0.24197569714517145, 0.025915697145171439, + 2.1364999999999998, 0.26483839536511933, 0.025915697145171439, 2.1364999999999998, 0.26483839536511933, 0.048778395365119298, 2.1364999999999998, + 0.24197569714517145, 0.048778395365119298, 2.1364999999999998, 0.24197569714517145, 0.025915697145171439, 2.1364999999999998, 0.26483839536511933, + 0.025915697145171439, 2.1364999999999998, 0.26483839536511933, 0.048778395365119298, 2.1364999999999998, 0.24197569714517145, 0.048778395365119298, + 2.1364999999999998, 0.24197569714517145, 0.025915697145171439, 2.3501499999999997, 0.26483839536511933, 0.025915697145171439, 2.3501499999999997, + 0.26483839536511933, 0.048778395365119298, 2.3501499999999997, 0.24197569714517145, 0.048778395365119298, 2.3501499999999997, 0.24197569714517145, + 0.025915697145171439, 2.3501499999999997, 0.26483839536511933, 0.025915697145171439, 2.3501499999999997, 0.26483839536511933, 0.048778395365119298, + 2.3501499999999997, 0.24197569714517145, 0.048778395365119298, 2.3501499999999997, 0.24197569714517145, 0.025915697145171439, 2.5637999999999996, + 0.26483839536511933, 0.025915697145171439, 2.5637999999999996, 0.26483839536511933, 0.048778395365119298, 2.5637999999999996, 0.24197569714517145, + 0.048778395365119298, 2.5637999999999996, 0.24197569714517145, 0.025915697145171439, 2.5637999999999996, 0.26483839536511933, 0.025915697145171439, + 2.5637999999999996, 0.26483839536511933, 0.048778395365119298, 2.5637999999999996, 0.24197569714517145, 0.048778395365119298, 2.5637999999999996, + 0.24197569714517145, 0.025915697145171439, 2.7774499999999995, 0.26483839536511933, 0.025915697145171439, 2.7774499999999995, 0.26483839536511933, + 0.048778395365119298, 2.7774499999999995, 0.24197569714517145, 0.048778395365119298, 2.7774499999999995, 0.24197569714517145, 0.025915697145171439, + 2.7774499999999995, 0.26483839536511933, 0.025915697145171439, 2.7774499999999995, 0.26483839536511933, 0.048778395365119298, 2.7774499999999995, + 0.24197569714517145, 0.048778395365119298, 2.7774499999999995, 0.24197569714517145, 0.025915697145171439, 2.9910999999999999, 0.26483839536511933, + 0.025915697145171439, 2.9910999999999999, 0.26483839536511933, 0.048778395365119298, 2.9910999999999999, 0.24197569714517145, 0.048778395365119298, + 2.9910999999999999, 0.24197569714517145, 0.025915697145171439, 2.9910999999999999, 0.26483839536511933, 0.025915697145171439, 2.9910999999999999, + 0.26483839536511933, 0.048778395365119298, 2.9910999999999999, 0.24197569714517145, 0.048778395365119298, 2.9910999999999999, 0.24197569714517145, + 0.025915697145171439, 3.2047499999999998, 0.26483839536511933, 0.025915697145171439, 3.2047499999999998, 0.26483839536511933, 0.048778395365119298, + 3.2047499999999998, 0.24197569714517145, 0.048778395365119298, 3.2047499999999998, + 0.24197569714517145, 0.025915697145171439, 3.2047499999999998, 0.26483839536511933, 0.025915697145171439, 3.2047499999999998, 0.26483839536511933, + 0.048778395365119298, 3.2047499999999998, 0.24197569714517145, 0.048778395365119298, 3.2047499999999998, 0.24197569714517145, 0.025915697145171439, + 3.4183999999999997, 0.26483839536511933, 0.025915697145171439, 3.4183999999999997, 0.26483839536511933, 0.048778395365119298, 3.4183999999999997, + 0.24197569714517145, 0.048778395365119298, 3.4183999999999997, 0.24197569714517145, 0.025915697145171439, 3.4183999999999997, 0.26483839536511933, + 0.025915697145171439, 3.4183999999999997, 0.26483839536511933, 0.048778395365119298, 3.4183999999999997, 0.24197569714517145, 0.048778395365119298, + 3.4183999999999997, 0.24197569714517145, 0.025915697145171439, 3.6320499999999996, 0.26483839536511933, 0.025915697145171439, 3.6320499999999996, + 0.26483839536511933, 0.048778395365119298, 3.6320499999999996, 0.24197569714517145, 0.048778395365119298, 3.6320499999999996, 0.24197569714517145, + 0.025915697145171439, 3.6320499999999996, 0.26483839536511933, 0.025915697145171439, 3.6320499999999996, 0.26483839536511933, 0.048778395365119298, + 3.6320499999999996, 0.24197569714517145, 0.048778395365119298, 3.6320499999999996, 0.24197569714517145, 0.025915697145171439, 3.8456999999999995, + 0.26483839536511933, 0.025915697145171439, 3.8456999999999995, 0.26483839536511933, 0.048778395365119298, 3.8456999999999995, 0.24197569714517145, + 0.048778395365119298, 3.8456999999999995, 0.24197569714517145, 0.025915697145171439, 3.8456999999999995, 0.26483839536511933, 0.025915697145171439, + 3.8456999999999995, 0.26483839536511933, 0.048778395365119298, 3.8456999999999995, 0.24197569714517145, 0.048778395365119298, 3.8456999999999995, + 0.24197569714517145, 0.025915697145171439, 4.0593499999999993, 0.26483839536511933, 0.025915697145171439, 4.0593499999999993, 0.26483839536511933, + 0.048778395365119298, 4.0593499999999993, 0.24197569714517145, 0.048778395365119298, 4.0593499999999993, 0.24197569714517145, 0.025915697145171439, + 4.0593499999999993, 0.26483839536511933, 0.025915697145171439, 4.0593499999999993, 0.26483839536511933, 0.048778395365119298, 4.0593499999999993, + 0.24197569714517145, 0.048778395365119298, 4.0593499999999993, 0.24197569714517145, 0.025915697145171439, 4.2729999999999997, 0.26483839536511933, + 0.025915697145171439, 4.2729999999999997, 0.26483839536511933, 0.048778395365119298, 4.2729999999999997, 0.24197569714517145, 0.048778395365119298, + 4.2729999999999997, 0.31132160463488068, 0.029625802317440348, 0, 0.3368583953651193, 0.029625802317440348, 0, 0.3368583953651193, 0.046104302854828562, 0, + 0.31132160463488068, 0.046104302854828562, 0, 0.31132160463488068, 0.029625802317440348, 0.21364999999999998, 0.3368583953651193, 0.029625802317440348, + 0.21364999999999998, 0.3368583953651193, 0.046104302854828562, 0.21364999999999998, 0.31132160463488068, 0.046104302854828562, 0.21364999999999998, + 0.31132160463488068, 0.029625802317440348, 0.21364999999999998, 0.3368583953651193, 0.029625802317440348, 0.21364999999999998, 0.3368583953651193, + 0.046104302854828562, 0.21364999999999998, 0.31132160463488068, 0.046104302854828562, 0.21364999999999998, 0.31132160463488068, 0.029625802317440348, + 0.42729999999999996, 0.3368583953651193, 0.029625802317440348, 0.42729999999999996, 0.3368583953651193, 0.046104302854828562, 0.42729999999999996, + 0.31132160463488068, 0.046104302854828562, 0.42729999999999996, 0.31132160463488068, 0.029625802317440348, 0.42729999999999996, 0.3368583953651193, + 0.029625802317440348, 0.42729999999999996, 0.3368583953651193, 0.046104302854828562, 0.42729999999999996, 0.31132160463488068, 0.046104302854828562, + 0.42729999999999996, 0.31132160463488068, 0.029625802317440348, 0.64094999999999991, 0.3368583953651193, 0.029625802317440348, 0.64094999999999991, + 0.3368583953651193, 0.046104302854828562, 0.64094999999999991, 0.31132160463488068, 0.046104302854828562, 0.64094999999999991, 0.31132160463488068, + 0.029625802317440348, 0.64094999999999991, 0.3368583953651193, 0.029625802317440348, 0.64094999999999991, 0.3368583953651193, 0.046104302854828562, + 0.64094999999999991, 0.31132160463488068, 0.046104302854828562, 0.64094999999999991, 0.31132160463488068, 0.029625802317440348, 0.85459999999999992, + 0.3368583953651193, 0.029625802317440348, 0.85459999999999992, 0.3368583953651193, 0.046104302854828562, 0.85459999999999992, 0.31132160463488068, + 0.046104302854828562, 0.85459999999999992, 0.31132160463488068, 0.029625802317440348, 0.85459999999999992, 0.3368583953651193, 0.029625802317440348, + 0.85459999999999992, 0.3368583953651193, 0.046104302854828562, 0.85459999999999992, 0.31132160463488068, 0.046104302854828562, 0.85459999999999992, + 0.31132160463488068, 0.029625802317440348, 1.0682499999999999, 0.3368583953651193, 0.029625802317440348, 1.0682499999999999, 0.3368583953651193, + 0.046104302854828562, 1.0682499999999999, 0.31132160463488068, 0.046104302854828562, 1.0682499999999999, 0.31132160463488068, 0.029625802317440348, + 1.0682499999999999, 0.3368583953651193, 0.029625802317440348, 1.0682499999999999, 0.3368583953651193, 0.046104302854828562, 1.0682499999999999, + 0.31132160463488068, 0.046104302854828562, 1.0682499999999999, 0.31132160463488068, 0.029625802317440348, 1.2818999999999998, 0.3368583953651193, + 0.029625802317440348, 1.2818999999999998, 0.3368583953651193, 0.046104302854828562, 1.2818999999999998, 0.31132160463488068, 0.046104302854828562, + 1.2818999999999998, 0.31132160463488068, 0.029625802317440348, 1.2818999999999998, 0.3368583953651193, 0.029625802317440348, 1.2818999999999998, + 0.3368583953651193, 0.046104302854828562, 1.2818999999999998, 0.31132160463488068, 0.046104302854828562, 1.2818999999999998, 0.31132160463488068, + 0.029625802317440348, 1.4955499999999999, 0.3368583953651193, 0.029625802317440348, 1.4955499999999999, 0.3368583953651193, 0.046104302854828562, + 1.4955499999999999, 0.31132160463488068, 0.046104302854828562, 1.4955499999999999, 0.31132160463488068, 0.029625802317440348, 1.4955499999999999, + 0.3368583953651193, 0.029625802317440348, 1.4955499999999999, 0.3368583953651193, 0.046104302854828562, 1.4955499999999999, 0.31132160463488068, + 0.046104302854828562, 1.4955499999999999, 0.31132160463488068, 0.029625802317440348, 1.7091999999999998, 0.3368583953651193, 0.029625802317440348, + 1.7091999999999998, 0.3368583953651193, 0.046104302854828562, 1.7091999999999998, 0.31132160463488068, 0.046104302854828562, 1.7091999999999998, + 0.31132160463488068, 0.029625802317440348, 1.7091999999999998, 0.3368583953651193, 0.029625802317440348, 1.7091999999999998, 0.3368583953651193, + 0.046104302854828562, 1.7091999999999998, 0.31132160463488068, 0.046104302854828562, 1.7091999999999998, 0.31132160463488068, 0.029625802317440348, + 1.9228499999999997, 0.3368583953651193, 0.029625802317440348, 1.9228499999999997, 0.3368583953651193, 0.046104302854828562, 1.9228499999999997, + 0.31132160463488068, 0.046104302854828562, 1.9228499999999997, 0.31132160463488068, 0.029625802317440348, 1.9228499999999997, 0.3368583953651193, + 0.029625802317440348, 1.9228499999999997, 0.3368583953651193, 0.046104302854828562, 1.9228499999999997, 0.31132160463488068, 0.046104302854828562, + 1.9228499999999997, 0.31132160463488068, 0.029625802317440348, 2.1364999999999998, 0.3368583953651193, 0.029625802317440348, 2.1364999999999998, + 0.3368583953651193, 0.046104302854828562, 2.1364999999999998, 0.31132160463488068, 0.046104302854828562, 2.1364999999999998, 0.31132160463488068, + 0.029625802317440348, 2.1364999999999998, 0.3368583953651193, 0.029625802317440348, 2.1364999999999998, 0.3368583953651193, 0.046104302854828562, + 2.1364999999999998, 0.31132160463488068, 0.046104302854828562, 2.1364999999999998, 0.31132160463488068, 0.029625802317440348, 2.3501499999999997, + 0.3368583953651193, 0.029625802317440348, 2.3501499999999997, 0.3368583953651193, 0.046104302854828562, 2.3501499999999997, 0.31132160463488068, + 0.046104302854828562, 2.3501499999999997, 0.31132160463488068, 0.029625802317440348, 2.3501499999999997, 0.3368583953651193, 0.029625802317440348, + 2.3501499999999997, 0.3368583953651193, 0.046104302854828562, 2.3501499999999997, 0.31132160463488068, 0.046104302854828562, 2.3501499999999997, + 0.31132160463488068, 0.029625802317440348, 2.5637999999999996, 0.3368583953651193, + 0.029625802317440348, 2.5637999999999996, 0.3368583953651193, 0.046104302854828562, 2.5637999999999996, 0.31132160463488068, 0.046104302854828562, + 2.5637999999999996, 0.31132160463488068, 0.029625802317440348, 2.5637999999999996, 0.3368583953651193, 0.029625802317440348, 2.5637999999999996, + 0.3368583953651193, 0.046104302854828562, 2.5637999999999996, 0.31132160463488068, 0.046104302854828562, 2.5637999999999996, 0.31132160463488068, + 0.029625802317440348, 2.7774499999999995, 0.3368583953651193, 0.029625802317440348, 2.7774499999999995, 0.3368583953651193, 0.046104302854828562, + 2.7774499999999995, 0.31132160463488068, 0.046104302854828562, 2.7774499999999995, 0.31132160463488068, 0.029625802317440348, 2.7774499999999995, + 0.3368583953651193, 0.029625802317440348, 2.7774499999999995, 0.3368583953651193, 0.046104302854828562, 2.7774499999999995, 0.31132160463488068, + 0.046104302854828562, 2.7774499999999995, 0.31132160463488068, 0.029625802317440348, 2.9910999999999999, 0.3368583953651193, 0.029625802317440348, + 2.9910999999999999, 0.3368583953651193, 0.046104302854828562, 2.9910999999999999, 0.31132160463488068, 0.046104302854828562, 2.9910999999999999, + 0.31132160463488068, 0.029625802317440348, 2.9910999999999999, 0.3368583953651193, 0.029625802317440348, 2.9910999999999999, 0.3368583953651193, + 0.046104302854828562, 2.9910999999999999, 0.31132160463488068, 0.046104302854828562, 2.9910999999999999, 0.31132160463488068, 0.029625802317440348, + 3.2047499999999998, 0.3368583953651193, 0.029625802317440348, 3.2047499999999998, 0.3368583953651193, 0.046104302854828562, 3.2047499999999998, + 0.31132160463488068, 0.046104302854828562, 3.2047499999999998, 0.31132160463488068, 0.029625802317440348, 3.2047499999999998, 0.3368583953651193, + 0.029625802317440348, 3.2047499999999998, 0.3368583953651193, 0.046104302854828562, 3.2047499999999998, 0.31132160463488068, 0.046104302854828562, + 3.2047499999999998, 0.31132160463488068, 0.029625802317440348, 3.4183999999999997, 0.3368583953651193, 0.029625802317440348, 3.4183999999999997, + 0.3368583953651193, 0.046104302854828562, 3.4183999999999997, 0.31132160463488068, 0.046104302854828562, 3.4183999999999997, 0.31132160463488068, + 0.029625802317440348, 3.4183999999999997, 0.3368583953651193, 0.029625802317440348, 3.4183999999999997, 0.3368583953651193, 0.046104302854828562, + 3.4183999999999997, 0.31132160463488068, 0.046104302854828562, 3.4183999999999997, 0.31132160463488068, 0.029625802317440348, 3.6320499999999996, + 0.3368583953651193, 0.029625802317440348, 3.6320499999999996, 0.3368583953651193, 0.046104302854828562, 3.6320499999999996, 0.31132160463488068, + 0.046104302854828562, 3.6320499999999996, 0.31132160463488068, 0.029625802317440348, 3.6320499999999996, 0.3368583953651193, 0.029625802317440348, + 3.6320499999999996, 0.3368583953651193, 0.046104302854828562, 3.6320499999999996, 0.31132160463488068, 0.046104302854828562, 3.6320499999999996, + 0.31132160463488068, 0.029625802317440348, 3.8456999999999995, 0.3368583953651193, 0.029625802317440348, 3.8456999999999995, 0.3368583953651193, + 0.046104302854828562, 3.8456999999999995, 0.31132160463488068, 0.046104302854828562, 3.8456999999999995, 0.31132160463488068, 0.029625802317440348, + 3.8456999999999995, 0.3368583953651193, 0.029625802317440348, 3.8456999999999995, 0.3368583953651193, 0.046104302854828562, 3.8456999999999995, + 0.31132160463488068, 0.046104302854828562, 3.8456999999999995, 0.31132160463488068, 0.029625802317440348, 4.0593499999999993, 0.3368583953651193, + 0.029625802317440348, 4.0593499999999993, 0.3368583953651193, 0.046104302854828562, 4.0593499999999993, 0.31132160463488068, 0.046104302854828562, + 4.0593499999999993, 0.31132160463488068, 0.029625802317440348, 4.0593499999999993, 0.3368583953651193, 0.029625802317440348, 4.0593499999999993, + 0.3368583953651193, 0.046104302854828562, 4.0593499999999993, 0.31132160463488068, 0.046104302854828562, 4.0593499999999993, 0.31132160463488068, + 0.029625802317440348, 4.2729999999999997, 0.3368583953651193, 0.029625802317440348, 4.2729999999999997, 0.3368583953651193, 0.046104302854828562, + 4.2729999999999997, 0.31132160463488068, 0.046104302854828562, 4.2729999999999997, + 0.38334160463488065, 0.025915697145171453, 0, 0.40620430285482856, 0.025915697145171453, 0, 0.40620430285482856, 0.048778395365119291, 0, + 0.38334160463488065, 0.048778395365119291, 0, 0.38334160463488065, 0.025915697145171453, 0.21364999999999998, 0.40620430285482856, 0.025915697145171453, + 0.21364999999999998, 0.40620430285482856, 0.048778395365119291, 0.21364999999999998, 0.38334160463488065, 0.048778395365119291, 0.21364999999999998, + 0.38334160463488065, 0.025915697145171453, 0.21364999999999998, 0.40620430285482856, 0.025915697145171453, 0.21364999999999998, 0.40620430285482856, + 0.048778395365119291, 0.21364999999999998, 0.38334160463488065, 0.048778395365119291, 0.21364999999999998, 0.38334160463488065, 0.025915697145171453, + 0.42729999999999996, 0.40620430285482856, 0.025915697145171453, 0.42729999999999996, 0.40620430285482856, 0.048778395365119291, 0.42729999999999996, + 0.38334160463488065, 0.048778395365119291, 0.42729999999999996, 0.38334160463488065, 0.025915697145171453, 0.42729999999999996, 0.40620430285482856, + 0.025915697145171453, 0.42729999999999996, 0.40620430285482856, 0.048778395365119291, 0.42729999999999996, 0.38334160463488065, 0.048778395365119291, + 0.42729999999999996, 0.38334160463488065, 0.025915697145171453, 0.64094999999999991, 0.40620430285482856, 0.025915697145171453, 0.64094999999999991, + 0.40620430285482856, 0.048778395365119291, 0.64094999999999991, 0.38334160463488065, 0.048778395365119291, 0.64094999999999991, 0.38334160463488065, + 0.025915697145171453, 0.64094999999999991, 0.40620430285482856, 0.025915697145171453, 0.64094999999999991, 0.40620430285482856, 0.048778395365119291, + 0.64094999999999991, 0.38334160463488065, 0.048778395365119291, 0.64094999999999991, 0.38334160463488065, 0.025915697145171453, 0.85459999999999992, + 0.40620430285482856, 0.025915697145171453, 0.85459999999999992, 0.40620430285482856, 0.048778395365119291, 0.85459999999999992, 0.38334160463488065, + 0.048778395365119291, 0.85459999999999992, 0.38334160463488065, 0.025915697145171453, 0.85459999999999992, 0.40620430285482856, 0.025915697145171453, + 0.85459999999999992, 0.40620430285482856, 0.048778395365119291, 0.85459999999999992, 0.38334160463488065, 0.048778395365119291, 0.85459999999999992, + 0.38334160463488065, 0.025915697145171453, 1.0682499999999999, 0.40620430285482856, 0.025915697145171453, 1.0682499999999999, 0.40620430285482856, + 0.048778395365119291, 1.0682499999999999, 0.38334160463488065, 0.048778395365119291, 1.0682499999999999, 0.38334160463488065, 0.025915697145171453, + 1.0682499999999999, 0.40620430285482856, 0.025915697145171453, 1.0682499999999999, 0.40620430285482856, 0.048778395365119291, 1.0682499999999999, + 0.38334160463488065, 0.048778395365119291, 1.0682499999999999, 0.38334160463488065, 0.025915697145171453, 1.2818999999999998, 0.40620430285482856, + 0.025915697145171453, 1.2818999999999998, 0.40620430285482856, 0.048778395365119291, 1.2818999999999998, 0.38334160463488065, 0.048778395365119291, + 1.2818999999999998, 0.38334160463488065, 0.025915697145171453, 1.2818999999999998, 0.40620430285482856, 0.025915697145171453, 1.2818999999999998, + 0.40620430285482856, 0.048778395365119291, 1.2818999999999998, 0.38334160463488065, 0.048778395365119291, 1.2818999999999998, 0.38334160463488065, + 0.025915697145171453, 1.4955499999999999, 0.40620430285482856, 0.025915697145171453, 1.4955499999999999, 0.40620430285482856, 0.048778395365119291, + 1.4955499999999999, 0.38334160463488065, 0.048778395365119291, 1.4955499999999999, 0.38334160463488065, 0.025915697145171453, 1.4955499999999999, + 0.40620430285482856, 0.025915697145171453, 1.4955499999999999, 0.40620430285482856, 0.048778395365119291, 1.4955499999999999, 0.38334160463488065, + 0.048778395365119291, 1.4955499999999999, 0.38334160463488065, 0.025915697145171453, 1.7091999999999998, 0.40620430285482856, 0.025915697145171453, + 1.7091999999999998, 0.40620430285482856, 0.048778395365119291, 1.7091999999999998, 0.38334160463488065, 0.048778395365119291, 1.7091999999999998, + 0.38334160463488065, 0.025915697145171453, 1.7091999999999998, 0.40620430285482856, 0.025915697145171453, 1.7091999999999998, 0.40620430285482856, + 0.048778395365119291, + 1.7091999999999998, 0.38334160463488065, 0.048778395365119291, 1.7091999999999998, 0.38334160463488065, 0.025915697145171453, 1.9228499999999997, + 0.40620430285482856, 0.025915697145171453, 1.9228499999999997, 0.40620430285482856, 0.048778395365119291, 1.9228499999999997, 0.38334160463488065, + 0.048778395365119291, 1.9228499999999997, 0.38334160463488065, 0.025915697145171453, 1.9228499999999997, 0.40620430285482856, 0.025915697145171453, + 1.9228499999999997, 0.40620430285482856, 0.048778395365119291, 1.9228499999999997, 0.38334160463488065, 0.048778395365119291, 1.9228499999999997, + 0.38334160463488065, 0.025915697145171453, 2.1364999999999998, 0.40620430285482856, 0.025915697145171453, 2.1364999999999998, 0.40620430285482856, + 0.048778395365119291, 2.1364999999999998, 0.38334160463488065, 0.048778395365119291, 2.1364999999999998, 0.38334160463488065, 0.025915697145171453, + 2.1364999999999998, 0.40620430285482856, 0.025915697145171453, 2.1364999999999998, 0.40620430285482856, 0.048778395365119291, 2.1364999999999998, + 0.38334160463488065, 0.048778395365119291, 2.1364999999999998, 0.38334160463488065, 0.025915697145171453, 2.3501499999999997, 0.40620430285482856, + 0.025915697145171453, 2.3501499999999997, 0.40620430285482856, 0.048778395365119291, 2.3501499999999997, 0.38334160463488065, 0.048778395365119291, + 2.3501499999999997, 0.38334160463488065, 0.025915697145171453, 2.3501499999999997, 0.40620430285482856, 0.025915697145171453, 2.3501499999999997, + 0.40620430285482856, 0.048778395365119291, 2.3501499999999997, 0.38334160463488065, 0.048778395365119291, 2.3501499999999997, 0.38334160463488065, + 0.025915697145171453, 2.5637999999999996, 0.40620430285482856, 0.025915697145171453, 2.5637999999999996, 0.40620430285482856, 0.048778395365119291, + 2.5637999999999996, 0.38334160463488065, 0.048778395365119291, 2.5637999999999996, 0.38334160463488065, 0.025915697145171453, 2.5637999999999996, + 0.40620430285482856, 0.025915697145171453, 2.5637999999999996, 0.40620430285482856, 0.048778395365119291, 2.5637999999999996, 0.38334160463488065, + 0.048778395365119291, 2.5637999999999996, 0.38334160463488065, 0.025915697145171453, 2.7774499999999995, 0.40620430285482856, 0.025915697145171453, + 2.7774499999999995, 0.40620430285482856, 0.048778395365119291, 2.7774499999999995, 0.38334160463488065, 0.048778395365119291, 2.7774499999999995, + 0.38334160463488065, 0.025915697145171453, 2.7774499999999995, 0.40620430285482856, 0.025915697145171453, 2.7774499999999995, 0.40620430285482856, + 0.048778395365119291, 2.7774499999999995, 0.38334160463488065, 0.048778395365119291, 2.7774499999999995, 0.38334160463488065, 0.025915697145171453, + 2.9910999999999999, 0.40620430285482856, 0.025915697145171453, 2.9910999999999999, 0.40620430285482856, 0.048778395365119291, 2.9910999999999999, + 0.38334160463488065, 0.048778395365119291, 2.9910999999999999, 0.38334160463488065, 0.025915697145171453, 2.9910999999999999, 0.40620430285482856, + 0.025915697145171453, 2.9910999999999999, 0.40620430285482856, 0.048778395365119291, 2.9910999999999999, 0.38334160463488065, 0.048778395365119291, + 2.9910999999999999, 0.38334160463488065, 0.025915697145171453, 3.2047499999999998, 0.40620430285482856, 0.025915697145171453, 3.2047499999999998, + 0.40620430285482856, 0.048778395365119291, 3.2047499999999998, 0.38334160463488065, 0.048778395365119291, 3.2047499999999998, 0.38334160463488065, + 0.025915697145171453, 3.2047499999999998, 0.40620430285482856, 0.025915697145171453, 3.2047499999999998, 0.40620430285482856, 0.048778395365119291, + 3.2047499999999998, 0.38334160463488065, 0.048778395365119291, 3.2047499999999998, 0.38334160463488065, 0.025915697145171453, 3.4183999999999997, + 0.40620430285482856, 0.025915697145171453, 3.4183999999999997, 0.40620430285482856, 0.048778395365119291, 3.4183999999999997, 0.38334160463488065, + 0.048778395365119291, 3.4183999999999997, 0.38334160463488065, 0.025915697145171453, 3.4183999999999997, 0.40620430285482856, 0.025915697145171453, + 3.4183999999999997, 0.40620430285482856, 0.048778395365119291, 3.4183999999999997, 0.38334160463488065, 0.048778395365119291, 3.4183999999999997, + 0.38334160463488065, 0.025915697145171453, 3.6320499999999996, 0.40620430285482856, + 0.025915697145171453, 3.6320499999999996, 0.40620430285482856, 0.048778395365119291, 3.6320499999999996, 0.38334160463488065, 0.048778395365119291, + 3.6320499999999996, 0.38334160463488065, 0.025915697145171453, 3.6320499999999996, 0.40620430285482856, 0.025915697145171453, 3.6320499999999996, + 0.40620430285482856, 0.048778395365119291, 3.6320499999999996, 0.38334160463488065, 0.048778395365119291, 3.6320499999999996, 0.38334160463488065, + 0.025915697145171453, 3.8456999999999995, 0.40620430285482856, 0.025915697145171453, 3.8456999999999995, 0.40620430285482856, 0.048778395365119291, + 3.8456999999999995, 0.38334160463488065, 0.048778395365119291, 3.8456999999999995, 0.38334160463488065, 0.025915697145171453, 3.8456999999999995, + 0.40620430285482856, 0.025915697145171453, 3.8456999999999995, 0.40620430285482856, 0.048778395365119291, 3.8456999999999995, 0.38334160463488065, + 0.048778395365119291, 3.8456999999999995, 0.38334160463488065, 0.025915697145171453, 4.0593499999999993, 0.40620430285482856, 0.025915697145171453, + 4.0593499999999993, 0.40620430285482856, 0.048778395365119291, 4.0593499999999993, 0.38334160463488065, 0.048778395365119291, 4.0593499999999993, + 0.38334160463488065, 0.025915697145171453, 4.0593499999999993, 0.40620430285482856, 0.025915697145171453, 4.0593499999999993, 0.40620430285482856, + 0.048778395365119291, 4.0593499999999993, 0.38334160463488065, 0.048778395365119291, 4.0593499999999993, 0.38334160463488065, 0.025915697145171453, + 4.2729999999999997, 0.40620430285482856, 0.025915697145171453, 4.2729999999999997, 0.40620430285482856, 0.048778395365119291, 4.2729999999999997, + 0.38334160463488065, 0.048778395365119291, 4.2729999999999997, 0.24568580231744036, 0.095261604634880703, 0, 0.26216430285482856, 0.095261604634880703, 0, + 0.26216430285482856, 0.1207983953651193, 0, 0.24568580231744036, 0.1207983953651193, 0, 0.24568580231744036, 0.095261604634880703, 0.21364999999999998, + 0.26216430285482856, 0.095261604634880703, 0.21364999999999998, 0.26216430285482856, 0.1207983953651193, 0.21364999999999998, 0.24568580231744036, + 0.1207983953651193, 0.21364999999999998, 0.24568580231744036, 0.095261604634880703, 0.21364999999999998, 0.26216430285482856, 0.095261604634880703, + 0.21364999999999998, 0.26216430285482856, 0.1207983953651193, 0.21364999999999998, 0.24568580231744036, 0.1207983953651193, 0.21364999999999998, + 0.24568580231744036, 0.095261604634880703, 0.42729999999999996, 0.26216430285482856, 0.095261604634880703, 0.42729999999999996, 0.26216430285482856, + 0.1207983953651193, 0.42729999999999996, 0.24568580231744036, 0.1207983953651193, 0.42729999999999996, 0.24568580231744036, 0.095261604634880703, + 0.42729999999999996, 0.26216430285482856, 0.095261604634880703, 0.42729999999999996, 0.26216430285482856, 0.1207983953651193, 0.42729999999999996, + 0.24568580231744036, 0.1207983953651193, 0.42729999999999996, 0.24568580231744036, 0.095261604634880703, 0.64094999999999991, 0.26216430285482856, + 0.095261604634880703, 0.64094999999999991, 0.26216430285482856, 0.1207983953651193, 0.64094999999999991, 0.24568580231744036, 0.1207983953651193, + 0.64094999999999991, 0.24568580231744036, 0.095261604634880703, 0.64094999999999991, 0.26216430285482856, 0.095261604634880703, 0.64094999999999991, + 0.26216430285482856, 0.1207983953651193, 0.64094999999999991, 0.24568580231744036, 0.1207983953651193, 0.64094999999999991, 0.24568580231744036, + 0.095261604634880703, 0.85459999999999992, 0.26216430285482856, 0.095261604634880703, 0.85459999999999992, 0.26216430285482856, 0.1207983953651193, + 0.85459999999999992, 0.24568580231744036, 0.1207983953651193, 0.85459999999999992, 0.24568580231744036, 0.095261604634880703, 0.85459999999999992, + 0.26216430285482856, 0.095261604634880703, 0.85459999999999992, 0.26216430285482856, 0.1207983953651193, 0.85459999999999992, 0.24568580231744036, + 0.1207983953651193, 0.85459999999999992, 0.24568580231744036, 0.095261604634880703, 1.0682499999999999, 0.26216430285482856, 0.095261604634880703, + 1.0682499999999999, 0.26216430285482856, 0.1207983953651193, 1.0682499999999999, 0.24568580231744036, 0.1207983953651193, 1.0682499999999999, + 0.24568580231744036, 0.095261604634880703, 1.0682499999999999, 0.26216430285482856, 0.095261604634880703, 1.0682499999999999, 0.26216430285482856, + 0.1207983953651193, 1.0682499999999999, 0.24568580231744036, 0.1207983953651193, 1.0682499999999999, 0.24568580231744036, 0.095261604634880703, + 1.2818999999999998, 0.26216430285482856, 0.095261604634880703, 1.2818999999999998, 0.26216430285482856, 0.1207983953651193, 1.2818999999999998, + 0.24568580231744036, 0.1207983953651193, 1.2818999999999998, 0.24568580231744036, 0.095261604634880703, 1.2818999999999998, 0.26216430285482856, + 0.095261604634880703, 1.2818999999999998, 0.26216430285482856, 0.1207983953651193, 1.2818999999999998, 0.24568580231744036, 0.1207983953651193, + 1.2818999999999998, 0.24568580231744036, 0.095261604634880703, 1.4955499999999999, 0.26216430285482856, 0.095261604634880703, 1.4955499999999999, + 0.26216430285482856, 0.1207983953651193, 1.4955499999999999, 0.24568580231744036, 0.1207983953651193, 1.4955499999999999, 0.24568580231744036, + 0.095261604634880703, 1.4955499999999999, 0.26216430285482856, 0.095261604634880703, 1.4955499999999999, 0.26216430285482856, 0.1207983953651193, + 1.4955499999999999, 0.24568580231744036, 0.1207983953651193, 1.4955499999999999, 0.24568580231744036, 0.095261604634880703, 1.7091999999999998, + 0.26216430285482856, 0.095261604634880703, 1.7091999999999998, 0.26216430285482856, 0.1207983953651193, 1.7091999999999998, 0.24568580231744036, + 0.1207983953651193, 1.7091999999999998, 0.24568580231744036, 0.095261604634880703, 1.7091999999999998, 0.26216430285482856, 0.095261604634880703, + 1.7091999999999998, 0.26216430285482856, 0.1207983953651193, 1.7091999999999998, 0.24568580231744036, 0.1207983953651193, 1.7091999999999998, + 0.24568580231744036, 0.095261604634880703, 1.9228499999999997, 0.26216430285482856, 0.095261604634880703, 1.9228499999999997, 0.26216430285482856, + 0.1207983953651193, 1.9228499999999997, 0.24568580231744036, 0.1207983953651193, 1.9228499999999997, 0.24568580231744036, 0.095261604634880703, + 1.9228499999999997, 0.26216430285482856, 0.095261604634880703, 1.9228499999999997, 0.26216430285482856, 0.1207983953651193, 1.9228499999999997, + 0.24568580231744036, 0.1207983953651193, 1.9228499999999997, 0.24568580231744036, 0.095261604634880703, 2.1364999999999998, 0.26216430285482856, + 0.095261604634880703, 2.1364999999999998, 0.26216430285482856, 0.1207983953651193, 2.1364999999999998, 0.24568580231744036, 0.1207983953651193, + 2.1364999999999998, 0.24568580231744036, 0.095261604634880703, 2.1364999999999998, 0.26216430285482856, 0.095261604634880703, 2.1364999999999998, + 0.26216430285482856, 0.1207983953651193, 2.1364999999999998, 0.24568580231744036, 0.1207983953651193, 2.1364999999999998, 0.24568580231744036, + 0.095261604634880703, 2.3501499999999997, 0.26216430285482856, 0.095261604634880703, 2.3501499999999997, 0.26216430285482856, 0.1207983953651193, + 2.3501499999999997, 0.24568580231744036, 0.1207983953651193, 2.3501499999999997, 0.24568580231744036, 0.095261604634880703, 2.3501499999999997, + 0.26216430285482856, 0.095261604634880703, 2.3501499999999997, 0.26216430285482856, 0.1207983953651193, 2.3501499999999997, 0.24568580231744036, + 0.1207983953651193, 2.3501499999999997, 0.24568580231744036, 0.095261604634880703, 2.5637999999999996, 0.26216430285482856, 0.095261604634880703, + 2.5637999999999996, 0.26216430285482856, 0.1207983953651193, 2.5637999999999996, 0.24568580231744036, 0.1207983953651193, 2.5637999999999996, + 0.24568580231744036, 0.095261604634880703, 2.5637999999999996, 0.26216430285482856, 0.095261604634880703, 2.5637999999999996, 0.26216430285482856, + 0.1207983953651193, 2.5637999999999996, 0.24568580231744036, 0.1207983953651193, 2.5637999999999996, 0.24568580231744036, 0.095261604634880703, + 2.7774499999999995, 0.26216430285482856, 0.095261604634880703, 2.7774499999999995, 0.26216430285482856, 0.1207983953651193, 2.7774499999999995, + 0.24568580231744036, 0.1207983953651193, 2.7774499999999995, 0.24568580231744036, 0.095261604634880703, 2.7774499999999995, 0.26216430285482856, + 0.095261604634880703, 2.7774499999999995, 0.26216430285482856, 0.1207983953651193, + 2.7774499999999995, 0.24568580231744036, 0.1207983953651193, 2.7774499999999995, 0.24568580231744036, 0.095261604634880703, 2.9910999999999999, + 0.26216430285482856, 0.095261604634880703, 2.9910999999999999, 0.26216430285482856, 0.1207983953651193, 2.9910999999999999, 0.24568580231744036, + 0.1207983953651193, 2.9910999999999999, 0.24568580231744036, 0.095261604634880703, 2.9910999999999999, 0.26216430285482856, 0.095261604634880703, + 2.9910999999999999, 0.26216430285482856, 0.1207983953651193, 2.9910999999999999, 0.24568580231744036, 0.1207983953651193, 2.9910999999999999, + 0.24568580231744036, 0.095261604634880703, 3.2047499999999998, 0.26216430285482856, 0.095261604634880703, 3.2047499999999998, 0.26216430285482856, + 0.1207983953651193, 3.2047499999999998, 0.24568580231744036, 0.1207983953651193, 3.2047499999999998, 0.24568580231744036, 0.095261604634880703, + 3.2047499999999998, 0.26216430285482856, 0.095261604634880703, 3.2047499999999998, 0.26216430285482856, 0.1207983953651193, 3.2047499999999998, + 0.24568580231744036, 0.1207983953651193, 3.2047499999999998, 0.24568580231744036, 0.095261604634880703, 3.4183999999999997, 0.26216430285482856, + 0.095261604634880703, 3.4183999999999997, 0.26216430285482856, 0.1207983953651193, 3.4183999999999997, 0.24568580231744036, 0.1207983953651193, + 3.4183999999999997, 0.24568580231744036, 0.095261604634880703, 3.4183999999999997, 0.26216430285482856, 0.095261604634880703, 3.4183999999999997, + 0.26216430285482856, 0.1207983953651193, 3.4183999999999997, 0.24568580231744036, 0.1207983953651193, 3.4183999999999997, 0.24568580231744036, + 0.095261604634880703, 3.6320499999999996, 0.26216430285482856, 0.095261604634880703, 3.6320499999999996, 0.26216430285482856, 0.1207983953651193, + 3.6320499999999996, 0.24568580231744036, 0.1207983953651193, 3.6320499999999996, 0.24568580231744036, 0.095261604634880703, 3.6320499999999996, + 0.26216430285482856, 0.095261604634880703, 3.6320499999999996, 0.26216430285482856, 0.1207983953651193, 3.6320499999999996, 0.24568580231744036, + 0.1207983953651193, 3.6320499999999996, 0.24568580231744036, 0.095261604634880703, 3.8456999999999995, 0.26216430285482856, 0.095261604634880703, + 3.8456999999999995, 0.26216430285482856, 0.1207983953651193, 3.8456999999999995, 0.24568580231744036, 0.1207983953651193, 3.8456999999999995, + 0.24568580231744036, 0.095261604634880703, 3.8456999999999995, 0.26216430285482856, 0.095261604634880703, 3.8456999999999995, 0.26216430285482856, + 0.1207983953651193, 3.8456999999999995, 0.24568580231744036, 0.1207983953651193, 3.8456999999999995, 0.24568580231744036, 0.095261604634880703, + 4.0593499999999993, 0.26216430285482856, 0.095261604634880703, 4.0593499999999993, 0.26216430285482856, 0.1207983953651193, 4.0593499999999993, + 0.24568580231744036, 0.1207983953651193, 4.0593499999999993, 0.24568580231744036, 0.095261604634880703, 4.0593499999999993, 0.26216430285482856, + 0.095261604634880703, 4.0593499999999993, 0.26216430285482856, 0.1207983953651193, 4.0593499999999993, 0.24568580231744036, 0.1207983953651193, + 4.0593499999999993, 0.24568580231744036, 0.095261604634880703, 4.2729999999999997, 0.26216430285482856, 0.095261604634880703, 4.2729999999999997, + 0.26216430285482856, 0.1207983953651193, 4.2729999999999997, 0.24568580231744036, 0.1207983953651193, 4.2729999999999997, 0.31399569714517145, + 0.097935697145171446, 0, 0.33418430285482853, 0.097935697145171446, 0, 0.33418430285482853, 0.11812430285482856, 0, 0.31399569714517145, 0.11812430285482856, 0, + 0.31399569714517145, 0.097935697145171446, 0.21364999999999998, 0.33418430285482853, 0.097935697145171446, 0.21364999999999998, 0.33418430285482853, + 0.11812430285482856, 0.21364999999999998, 0.31399569714517145, 0.11812430285482856, 0.21364999999999998, 0.31399569714517145, 0.097935697145171446, + 0.21364999999999998, 0.33418430285482853, 0.097935697145171446, 0.21364999999999998, 0.33418430285482853, 0.11812430285482856, 0.21364999999999998, + 0.31399569714517145, 0.11812430285482856, 0.21364999999999998, 0.31399569714517145, 0.097935697145171446, 0.42729999999999996, 0.33418430285482853, + 0.097935697145171446, 0.42729999999999996, 0.33418430285482853, 0.11812430285482856, 0.42729999999999996, 0.31399569714517145, 0.11812430285482856, + 0.42729999999999996, 0.31399569714517145, 0.097935697145171446, 0.42729999999999996, 0.33418430285482853, 0.097935697145171446, 0.42729999999999996, + 0.33418430285482853, 0.11812430285482856, 0.42729999999999996, 0.31399569714517145, 0.11812430285482856, 0.42729999999999996, 0.31399569714517145, + 0.097935697145171446, 0.64094999999999991, 0.33418430285482853, 0.097935697145171446, 0.64094999999999991, 0.33418430285482853, 0.11812430285482856, + 0.64094999999999991, 0.31399569714517145, 0.11812430285482856, 0.64094999999999991, 0.31399569714517145, 0.097935697145171446, 0.64094999999999991, + 0.33418430285482853, 0.097935697145171446, 0.64094999999999991, 0.33418430285482853, 0.11812430285482856, 0.64094999999999991, 0.31399569714517145, + 0.11812430285482856, 0.64094999999999991, 0.31399569714517145, 0.097935697145171446, 0.85459999999999992, 0.33418430285482853, 0.097935697145171446, + 0.85459999999999992, 0.33418430285482853, 0.11812430285482856, 0.85459999999999992, 0.31399569714517145, 0.11812430285482856, 0.85459999999999992, + 0.31399569714517145, 0.097935697145171446, 0.85459999999999992, 0.33418430285482853, 0.097935697145171446, 0.85459999999999992, 0.33418430285482853, + 0.11812430285482856, 0.85459999999999992, 0.31399569714517145, 0.11812430285482856, 0.85459999999999992, 0.31399569714517145, 0.097935697145171446, + 1.0682499999999999, 0.33418430285482853, 0.097935697145171446, 1.0682499999999999, 0.33418430285482853, 0.11812430285482856, 1.0682499999999999, + 0.31399569714517145, 0.11812430285482856, 1.0682499999999999, 0.31399569714517145, 0.097935697145171446, 1.0682499999999999, 0.33418430285482853, + 0.097935697145171446, 1.0682499999999999, 0.33418430285482853, 0.11812430285482856, 1.0682499999999999, 0.31399569714517145, 0.11812430285482856, + 1.0682499999999999, 0.31399569714517145, 0.097935697145171446, 1.2818999999999998, 0.33418430285482853, 0.097935697145171446, 1.2818999999999998, + 0.33418430285482853, 0.11812430285482856, 1.2818999999999998, 0.31399569714517145, 0.11812430285482856, 1.2818999999999998, 0.31399569714517145, + 0.097935697145171446, 1.2818999999999998, 0.33418430285482853, 0.097935697145171446, 1.2818999999999998, 0.33418430285482853, 0.11812430285482856, + 1.2818999999999998, 0.31399569714517145, 0.11812430285482856, 1.2818999999999998, 0.31399569714517145, 0.097935697145171446, 1.4955499999999999, + 0.33418430285482853, 0.097935697145171446, 1.4955499999999999, 0.33418430285482853, 0.11812430285482856, 1.4955499999999999, 0.31399569714517145, + 0.11812430285482856, 1.4955499999999999, 0.31399569714517145, 0.097935697145171446, 1.4955499999999999, 0.33418430285482853, 0.097935697145171446, + 1.4955499999999999, 0.33418430285482853, 0.11812430285482856, 1.4955499999999999, 0.31399569714517145, 0.11812430285482856, 1.4955499999999999, + 0.31399569714517145, 0.097935697145171446, 1.7091999999999998, 0.33418430285482853, 0.097935697145171446, 1.7091999999999998, 0.33418430285482853, + 0.11812430285482856, 1.7091999999999998, 0.31399569714517145, 0.11812430285482856, 1.7091999999999998, 0.31399569714517145, 0.097935697145171446, + 1.7091999999999998, 0.33418430285482853, 0.097935697145171446, 1.7091999999999998, 0.33418430285482853, 0.11812430285482856, 1.7091999999999998, + 0.31399569714517145, 0.11812430285482856, 1.7091999999999998, 0.31399569714517145, 0.097935697145171446, 1.9228499999999997, 0.33418430285482853, + 0.097935697145171446, 1.9228499999999997, 0.33418430285482853, 0.11812430285482856, 1.9228499999999997, 0.31399569714517145, 0.11812430285482856, + 1.9228499999999997, 0.31399569714517145, 0.097935697145171446, 1.9228499999999997, 0.33418430285482853, 0.097935697145171446, 1.9228499999999997, + 0.33418430285482853, 0.11812430285482856, 1.9228499999999997, 0.31399569714517145, 0.11812430285482856, 1.9228499999999997, 0.31399569714517145, + 0.097935697145171446, 2.1364999999999998, 0.33418430285482853, 0.097935697145171446, 2.1364999999999998, 0.33418430285482853, 0.11812430285482856, + 2.1364999999999998, 0.31399569714517145, 0.11812430285482856, 2.1364999999999998, + 0.31399569714517145, 0.097935697145171446, 2.1364999999999998, 0.33418430285482853, 0.097935697145171446, 2.1364999999999998, 0.33418430285482853, + 0.11812430285482856, 2.1364999999999998, 0.31399569714517145, 0.11812430285482856, 2.1364999999999998, 0.31399569714517145, 0.097935697145171446, + 2.3501499999999997, 0.33418430285482853, 0.097935697145171446, 2.3501499999999997, 0.33418430285482853, 0.11812430285482856, 2.3501499999999997, + 0.31399569714517145, 0.11812430285482856, 2.3501499999999997, 0.31399569714517145, 0.097935697145171446, 2.3501499999999997, 0.33418430285482853, + 0.097935697145171446, 2.3501499999999997, 0.33418430285482853, 0.11812430285482856, 2.3501499999999997, 0.31399569714517145, 0.11812430285482856, + 2.3501499999999997, 0.31399569714517145, 0.097935697145171446, 2.5637999999999996, 0.33418430285482853, 0.097935697145171446, 2.5637999999999996, + 0.33418430285482853, 0.11812430285482856, 2.5637999999999996, 0.31399569714517145, 0.11812430285482856, 2.5637999999999996, 0.31399569714517145, + 0.097935697145171446, 2.5637999999999996, 0.33418430285482853, 0.097935697145171446, 2.5637999999999996, 0.33418430285482853, 0.11812430285482856, + 2.5637999999999996, 0.31399569714517145, 0.11812430285482856, 2.5637999999999996, 0.31399569714517145, 0.097935697145171446, 2.7774499999999995, + 0.33418430285482853, 0.097935697145171446, 2.7774499999999995, 0.33418430285482853, 0.11812430285482856, 2.7774499999999995, 0.31399569714517145, + 0.11812430285482856, 2.7774499999999995, 0.31399569714517145, 0.097935697145171446, 2.7774499999999995, 0.33418430285482853, 0.097935697145171446, + 2.7774499999999995, 0.33418430285482853, 0.11812430285482856, 2.7774499999999995, 0.31399569714517145, 0.11812430285482856, 2.7774499999999995, + 0.31399569714517145, 0.097935697145171446, 2.9910999999999999, 0.33418430285482853, 0.097935697145171446, 2.9910999999999999, 0.33418430285482853, + 0.11812430285482856, 2.9910999999999999, 0.31399569714517145, 0.11812430285482856, 2.9910999999999999, 0.31399569714517145, 0.097935697145171446, + 2.9910999999999999, 0.33418430285482853, 0.097935697145171446, 2.9910999999999999, 0.33418430285482853, 0.11812430285482856, 2.9910999999999999, + 0.31399569714517145, 0.11812430285482856, 2.9910999999999999, 0.31399569714517145, 0.097935697145171446, 3.2047499999999998, 0.33418430285482853, + 0.097935697145171446, 3.2047499999999998, 0.33418430285482853, 0.11812430285482856, 3.2047499999999998, 0.31399569714517145, 0.11812430285482856, + 3.2047499999999998, 0.31399569714517145, 0.097935697145171446, 3.2047499999999998, 0.33418430285482853, 0.097935697145171446, 3.2047499999999998, + 0.33418430285482853, 0.11812430285482856, 3.2047499999999998, 0.31399569714517145, 0.11812430285482856, 3.2047499999999998, 0.31399569714517145, + 0.097935697145171446, 3.4183999999999997, 0.33418430285482853, 0.097935697145171446, 3.4183999999999997, 0.33418430285482853, 0.11812430285482856, + 3.4183999999999997, 0.31399569714517145, 0.11812430285482856, 3.4183999999999997, 0.31399569714517145, 0.097935697145171446, 3.4183999999999997, + 0.33418430285482853, 0.097935697145171446, 3.4183999999999997, 0.33418430285482853, 0.11812430285482856, 3.4183999999999997, 0.31399569714517145, + 0.11812430285482856, 3.4183999999999997, 0.31399569714517145, 0.097935697145171446, 3.6320499999999996, 0.33418430285482853, 0.097935697145171446, + 3.6320499999999996, 0.33418430285482853, 0.11812430285482856, 3.6320499999999996, 0.31399569714517145, 0.11812430285482856, 3.6320499999999996, + 0.31399569714517145, 0.097935697145171446, 3.6320499999999996, 0.33418430285482853, 0.097935697145171446, 3.6320499999999996, 0.33418430285482853, + 0.11812430285482856, 3.6320499999999996, 0.31399569714517145, 0.11812430285482856, 3.6320499999999996, 0.31399569714517145, 0.097935697145171446, + 3.8456999999999995, 0.33418430285482853, 0.097935697145171446, 3.8456999999999995, 0.33418430285482853, 0.11812430285482856, 3.8456999999999995, + 0.31399569714517145, 0.11812430285482856, 3.8456999999999995, 0.31399569714517145, 0.097935697145171446, 3.8456999999999995, 0.33418430285482853, + 0.097935697145171446, 3.8456999999999995, 0.33418430285482853, 0.11812430285482856, + 3.8456999999999995, 0.31399569714517145, 0.11812430285482856, 3.8456999999999995, 0.31399569714517145, 0.097935697145171446, 4.0593499999999993, + 0.33418430285482853, 0.097935697145171446, 4.0593499999999993, 0.33418430285482853, 0.11812430285482856, 4.0593499999999993, 0.31399569714517145, + 0.11812430285482856, 4.0593499999999993, 0.31399569714517145, 0.097935697145171446, 4.0593499999999993, 0.33418430285482853, 0.097935697145171446, + 4.0593499999999993, 0.33418430285482853, 0.11812430285482856, 4.0593499999999993, 0.31399569714517145, 0.11812430285482856, 4.0593499999999993, + 0.31399569714517145, 0.097935697145171446, 4.2729999999999997, 0.33418430285482853, 0.097935697145171446, 4.2729999999999997, 0.33418430285482853, + 0.11812430285482856, 4.2729999999999997, 0.31399569714517145, 0.11812430285482856, 4.2729999999999997, 0.38601569714517142, 0.095261604634880703, 0, + 0.40249419768255962, 0.095261604634880703, 0, 0.40249419768255962, 0.1207983953651193, 0, 0.38601569714517142, 0.1207983953651193, 0, 0.38601569714517142, + 0.095261604634880703, 0.21364999999999998, 0.40249419768255962, 0.095261604634880703, 0.21364999999999998, 0.40249419768255962, 0.1207983953651193, + 0.21364999999999998, 0.38601569714517142, 0.1207983953651193, 0.21364999999999998, 0.38601569714517142, 0.095261604634880703, 0.21364999999999998, + 0.40249419768255962, 0.095261604634880703, 0.21364999999999998, 0.40249419768255962, 0.1207983953651193, 0.21364999999999998, 0.38601569714517142, + 0.1207983953651193, 0.21364999999999998, 0.38601569714517142, 0.095261604634880703, 0.42729999999999996, 0.40249419768255962, 0.095261604634880703, + 0.42729999999999996, 0.40249419768255962, 0.1207983953651193, 0.42729999999999996, 0.38601569714517142, 0.1207983953651193, 0.42729999999999996, + 0.38601569714517142, 0.095261604634880703, 0.42729999999999996, 0.40249419768255962, 0.095261604634880703, 0.42729999999999996, 0.40249419768255962, + 0.1207983953651193, 0.42729999999999996, 0.38601569714517142, 0.1207983953651193, 0.42729999999999996, 0.38601569714517142, 0.095261604634880703, + 0.64094999999999991, 0.40249419768255962, 0.095261604634880703, 0.64094999999999991, 0.40249419768255962, 0.1207983953651193, 0.64094999999999991, + 0.38601569714517142, 0.1207983953651193, 0.64094999999999991, 0.38601569714517142, 0.095261604634880703, 0.64094999999999991, 0.40249419768255962, + 0.095261604634880703, 0.64094999999999991, 0.40249419768255962, 0.1207983953651193, 0.64094999999999991, 0.38601569714517142, 0.1207983953651193, + 0.64094999999999991, 0.38601569714517142, 0.095261604634880703, 0.85459999999999992, 0.40249419768255962, 0.095261604634880703, 0.85459999999999992, + 0.40249419768255962, 0.1207983953651193, 0.85459999999999992, 0.38601569714517142, 0.1207983953651193, 0.85459999999999992, 0.38601569714517142, + 0.095261604634880703, 0.85459999999999992, 0.40249419768255962, 0.095261604634880703, 0.85459999999999992, 0.40249419768255962, 0.1207983953651193, + 0.85459999999999992, 0.38601569714517142, 0.1207983953651193, 0.85459999999999992, 0.38601569714517142, 0.095261604634880703, 1.0682499999999999, + 0.40249419768255962, 0.095261604634880703, 1.0682499999999999, 0.40249419768255962, 0.1207983953651193, 1.0682499999999999, 0.38601569714517142, + 0.1207983953651193, 1.0682499999999999, 0.38601569714517142, 0.095261604634880703, 1.0682499999999999, 0.40249419768255962, 0.095261604634880703, + 1.0682499999999999, 0.40249419768255962, 0.1207983953651193, 1.0682499999999999, 0.38601569714517142, 0.1207983953651193, 1.0682499999999999, + 0.38601569714517142, 0.095261604634880703, 1.2818999999999998, 0.40249419768255962, 0.095261604634880703, 1.2818999999999998, 0.40249419768255962, + 0.1207983953651193, 1.2818999999999998, 0.38601569714517142, 0.1207983953651193, 1.2818999999999998, 0.38601569714517142, 0.095261604634880703, + 1.2818999999999998, 0.40249419768255962, 0.095261604634880703, 1.2818999999999998, 0.40249419768255962, 0.1207983953651193, 1.2818999999999998, + 0.38601569714517142, 0.1207983953651193, 1.2818999999999998, 0.38601569714517142, 0.095261604634880703, 1.4955499999999999, 0.40249419768255962, + 0.095261604634880703, 1.4955499999999999, 0.40249419768255962, 0.1207983953651193, 1.4955499999999999, 0.38601569714517142, 0.1207983953651193, + 1.4955499999999999, 0.38601569714517142, 0.095261604634880703, 1.4955499999999999, 0.40249419768255962, 0.095261604634880703, 1.4955499999999999, + 0.40249419768255962, 0.1207983953651193, 1.4955499999999999, 0.38601569714517142, 0.1207983953651193, 1.4955499999999999, 0.38601569714517142, + 0.095261604634880703, 1.7091999999999998, 0.40249419768255962, 0.095261604634880703, 1.7091999999999998, 0.40249419768255962, 0.1207983953651193, + 1.7091999999999998, 0.38601569714517142, 0.1207983953651193, 1.7091999999999998, 0.38601569714517142, 0.095261604634880703, 1.7091999999999998, + 0.40249419768255962, 0.095261604634880703, 1.7091999999999998, 0.40249419768255962, 0.1207983953651193, 1.7091999999999998, 0.38601569714517142, + 0.1207983953651193, 1.7091999999999998, 0.38601569714517142, 0.095261604634880703, 1.9228499999999997, 0.40249419768255962, 0.095261604634880703, + 1.9228499999999997, 0.40249419768255962, 0.1207983953651193, 1.9228499999999997, 0.38601569714517142, 0.1207983953651193, 1.9228499999999997, + 0.38601569714517142, 0.095261604634880703, 1.9228499999999997, 0.40249419768255962, 0.095261604634880703, 1.9228499999999997, 0.40249419768255962, + 0.1207983953651193, 1.9228499999999997, 0.38601569714517142, 0.1207983953651193, 1.9228499999999997, 0.38601569714517142, 0.095261604634880703, + 2.1364999999999998, 0.40249419768255962, 0.095261604634880703, 2.1364999999999998, 0.40249419768255962, 0.1207983953651193, 2.1364999999999998, + 0.38601569714517142, 0.1207983953651193, 2.1364999999999998, 0.38601569714517142, 0.095261604634880703, 2.1364999999999998, 0.40249419768255962, + 0.095261604634880703, 2.1364999999999998, 0.40249419768255962, 0.1207983953651193, 2.1364999999999998, 0.38601569714517142, 0.1207983953651193, + 2.1364999999999998, 0.38601569714517142, 0.095261604634880703, 2.3501499999999997, 0.40249419768255962, 0.095261604634880703, 2.3501499999999997, + 0.40249419768255962, 0.1207983953651193, 2.3501499999999997, 0.38601569714517142, 0.1207983953651193, 2.3501499999999997, 0.38601569714517142, + 0.095261604634880703, 2.3501499999999997, 0.40249419768255962, 0.095261604634880703, 2.3501499999999997, 0.40249419768255962, 0.1207983953651193, + 2.3501499999999997, 0.38601569714517142, 0.1207983953651193, 2.3501499999999997, 0.38601569714517142, 0.095261604634880703, 2.5637999999999996, + 0.40249419768255962, 0.095261604634880703, 2.5637999999999996, 0.40249419768255962, 0.1207983953651193, 2.5637999999999996, 0.38601569714517142, + 0.1207983953651193, 2.5637999999999996, 0.38601569714517142, 0.095261604634880703, 2.5637999999999996, 0.40249419768255962, 0.095261604634880703, + 2.5637999999999996, 0.40249419768255962, 0.1207983953651193, 2.5637999999999996, 0.38601569714517142, 0.1207983953651193, 2.5637999999999996, + 0.38601569714517142, 0.095261604634880703, 2.7774499999999995, 0.40249419768255962, 0.095261604634880703, 2.7774499999999995, 0.40249419768255962, + 0.1207983953651193, 2.7774499999999995, 0.38601569714517142, 0.1207983953651193, 2.7774499999999995, 0.38601569714517142, 0.095261604634880703, + 2.7774499999999995, 0.40249419768255962, 0.095261604634880703, 2.7774499999999995, 0.40249419768255962, 0.1207983953651193, 2.7774499999999995, + 0.38601569714517142, 0.1207983953651193, 2.7774499999999995, 0.38601569714517142, 0.095261604634880703, 2.9910999999999999, 0.40249419768255962, + 0.095261604634880703, 2.9910999999999999, 0.40249419768255962, 0.1207983953651193, 2.9910999999999999, 0.38601569714517142, 0.1207983953651193, + 2.9910999999999999, 0.38601569714517142, 0.095261604634880703, 2.9910999999999999, 0.40249419768255962, 0.095261604634880703, 2.9910999999999999, + 0.40249419768255962, 0.1207983953651193, 2.9910999999999999, 0.38601569714517142, 0.1207983953651193, 2.9910999999999999, 0.38601569714517142, + 0.095261604634880703, 3.2047499999999998, 0.40249419768255962, 0.095261604634880703, 3.2047499999999998, 0.40249419768255962, 0.1207983953651193, + 3.2047499999999998, 0.38601569714517142, 0.1207983953651193, 3.2047499999999998, + 0.38601569714517142, 0.095261604634880703, 3.2047499999999998, 0.40249419768255962, 0.095261604634880703, 3.2047499999999998, 0.40249419768255962, + 0.1207983953651193, 3.2047499999999998, 0.38601569714517142, 0.1207983953651193, 3.2047499999999998, 0.38601569714517142, 0.095261604634880703, + 3.4183999999999997, 0.40249419768255962, 0.095261604634880703, 3.4183999999999997, 0.40249419768255962, 0.1207983953651193, 3.4183999999999997, + 0.38601569714517142, 0.1207983953651193, 3.4183999999999997, 0.38601569714517142, 0.095261604634880703, 3.4183999999999997, 0.40249419768255962, + 0.095261604634880703, 3.4183999999999997, 0.40249419768255962, 0.1207983953651193, 3.4183999999999997, 0.38601569714517142, 0.1207983953651193, + 3.4183999999999997, 0.38601569714517142, 0.095261604634880703, 3.6320499999999996, 0.40249419768255962, 0.095261604634880703, 3.6320499999999996, + 0.40249419768255962, 0.1207983953651193, 3.6320499999999996, 0.38601569714517142, 0.1207983953651193, 3.6320499999999996, 0.38601569714517142, + 0.095261604634880703, 3.6320499999999996, 0.40249419768255962, 0.095261604634880703, 3.6320499999999996, 0.40249419768255962, 0.1207983953651193, + 3.6320499999999996, 0.38601569714517142, 0.1207983953651193, 3.6320499999999996, 0.38601569714517142, 0.095261604634880703, 3.8456999999999995, + 0.40249419768255962, 0.095261604634880703, 3.8456999999999995, 0.40249419768255962, 0.1207983953651193, 3.8456999999999995, 0.38601569714517142, + 0.1207983953651193, 3.8456999999999995, 0.38601569714517142, 0.095261604634880703, 3.8456999999999995, 0.40249419768255962, 0.095261604634880703, + 3.8456999999999995, 0.40249419768255962, 0.1207983953651193, 3.8456999999999995, 0.38601569714517142, 0.1207983953651193, 3.8456999999999995, + 0.38601569714517142, 0.095261604634880703, 4.0593499999999993, 0.40249419768255962, 0.095261604634880703, 4.0593499999999993, 0.40249419768255962, + 0.1207983953651193, 4.0593499999999993, 0.38601569714517142, 0.1207983953651193, 4.0593499999999993, 0.38601569714517142, 0.095261604634880703, + 4.0593499999999993, 0.40249419768255962, 0.095261604634880703, 4.0593499999999993, 0.40249419768255962, 0.1207983953651193, 4.0593499999999993, + 0.38601569714517142, 0.1207983953651193, 4.0593499999999993, 0.38601569714517142, 0.095261604634880703, 4.2729999999999997, 0.40249419768255962, + 0.095261604634880703, 4.2729999999999997, 0.40249419768255962, 0.1207983953651193, 4.2729999999999997, 0.38601569714517142, 0.1207983953651193, + 4.2729999999999997, 0.24197569714517148, 0.16728160463488068, 0, 0.26483839536511933, 0.16728160463488068, 0, 0.26483839536511933, 0.19014430285482856, 0, + 0.24197569714517148, 0.19014430285482856, 0, 0.24197569714517148, 0.16728160463488068, 0.21364999999999998, 0.26483839536511933, 0.16728160463488068, + 0.21364999999999998, 0.26483839536511933, 0.19014430285482856, 0.21364999999999998, 0.24197569714517148, 0.19014430285482856, 0.21364999999999998, + 0.24197569714517148, 0.16728160463488068, 0.21364999999999998, 0.26483839536511933, 0.16728160463488068, 0.21364999999999998, 0.26483839536511933, + 0.19014430285482856, 0.21364999999999998, 0.24197569714517148, 0.19014430285482856, 0.21364999999999998, 0.24197569714517148, 0.16728160463488068, + 0.42729999999999996, 0.26483839536511933, 0.16728160463488068, 0.42729999999999996, 0.26483839536511933, 0.19014430285482856, 0.42729999999999996, + 0.24197569714517148, 0.19014430285482856, 0.42729999999999996, 0.24197569714517148, 0.16728160463488068, 0.42729999999999996, 0.26483839536511933, + 0.16728160463488068, 0.42729999999999996, 0.26483839536511933, 0.19014430285482856, 0.42729999999999996, 0.24197569714517148, 0.19014430285482856, + 0.42729999999999996, 0.24197569714517148, 0.16728160463488068, 0.64094999999999991, 0.26483839536511933, 0.16728160463488068, 0.64094999999999991, + 0.26483839536511933, 0.19014430285482856, 0.64094999999999991, 0.24197569714517148, 0.19014430285482856, 0.64094999999999991, 0.24197569714517148, + 0.16728160463488068, 0.64094999999999991, 0.26483839536511933, 0.16728160463488068, 0.64094999999999991, 0.26483839536511933, 0.19014430285482856, + 0.64094999999999991, 0.24197569714517148, 0.19014430285482856, 0.64094999999999991, 0.24197569714517148, 0.16728160463488068, 0.85459999999999992, + 0.26483839536511933, 0.16728160463488068, 0.85459999999999992, 0.26483839536511933, 0.19014430285482856, 0.85459999999999992, 0.24197569714517148, + 0.19014430285482856, 0.85459999999999992, 0.24197569714517148, 0.16728160463488068, 0.85459999999999992, 0.26483839536511933, 0.16728160463488068, + 0.85459999999999992, 0.26483839536511933, 0.19014430285482856, 0.85459999999999992, 0.24197569714517148, 0.19014430285482856, 0.85459999999999992, + 0.24197569714517148, 0.16728160463488068, 1.0682499999999999, 0.26483839536511933, 0.16728160463488068, 1.0682499999999999, 0.26483839536511933, + 0.19014430285482856, 1.0682499999999999, 0.24197569714517148, 0.19014430285482856, 1.0682499999999999, 0.24197569714517148, 0.16728160463488068, + 1.0682499999999999, 0.26483839536511933, 0.16728160463488068, 1.0682499999999999, 0.26483839536511933, 0.19014430285482856, 1.0682499999999999, + 0.24197569714517148, 0.19014430285482856, 1.0682499999999999, 0.24197569714517148, 0.16728160463488068, 1.2818999999999998, 0.26483839536511933, + 0.16728160463488068, 1.2818999999999998, 0.26483839536511933, 0.19014430285482856, 1.2818999999999998, 0.24197569714517148, 0.19014430285482856, + 1.2818999999999998, 0.24197569714517148, 0.16728160463488068, 1.2818999999999998, 0.26483839536511933, 0.16728160463488068, 1.2818999999999998, + 0.26483839536511933, 0.19014430285482856, 1.2818999999999998, 0.24197569714517148, 0.19014430285482856, 1.2818999999999998, 0.24197569714517148, + 0.16728160463488068, 1.4955499999999999, 0.26483839536511933, 0.16728160463488068, 1.4955499999999999, 0.26483839536511933, 0.19014430285482856, + 1.4955499999999999, 0.24197569714517148, 0.19014430285482856, 1.4955499999999999, 0.24197569714517148, 0.16728160463488068, 1.4955499999999999, + 0.26483839536511933, 0.16728160463488068, 1.4955499999999999, 0.26483839536511933, 0.19014430285482856, 1.4955499999999999, 0.24197569714517148, + 0.19014430285482856, 1.4955499999999999, 0.24197569714517148, 0.16728160463488068, 1.7091999999999998, 0.26483839536511933, 0.16728160463488068, + 1.7091999999999998, 0.26483839536511933, 0.19014430285482856, 1.7091999999999998, 0.24197569714517148, 0.19014430285482856, 1.7091999999999998, + 0.24197569714517148, 0.16728160463488068, 1.7091999999999998, 0.26483839536511933, 0.16728160463488068, 1.7091999999999998, 0.26483839536511933, + 0.19014430285482856, 1.7091999999999998, 0.24197569714517148, 0.19014430285482856, 1.7091999999999998, 0.24197569714517148, 0.16728160463488068, + 1.9228499999999997, 0.26483839536511933, 0.16728160463488068, 1.9228499999999997, 0.26483839536511933, 0.19014430285482856, 1.9228499999999997, + 0.24197569714517148, 0.19014430285482856, 1.9228499999999997, 0.24197569714517148, 0.16728160463488068, 1.9228499999999997, 0.26483839536511933, + 0.16728160463488068, 1.9228499999999997, 0.26483839536511933, 0.19014430285482856, 1.9228499999999997, 0.24197569714517148, 0.19014430285482856, + 1.9228499999999997, 0.24197569714517148, 0.16728160463488068, 2.1364999999999998, 0.26483839536511933, 0.16728160463488068, 2.1364999999999998, + 0.26483839536511933, 0.19014430285482856, 2.1364999999999998, 0.24197569714517148, 0.19014430285482856, 2.1364999999999998, 0.24197569714517148, + 0.16728160463488068, 2.1364999999999998, 0.26483839536511933, 0.16728160463488068, 2.1364999999999998, 0.26483839536511933, 0.19014430285482856, + 2.1364999999999998, 0.24197569714517148, 0.19014430285482856, 2.1364999999999998, 0.24197569714517148, 0.16728160463488068, 2.3501499999999997, + 0.26483839536511933, 0.16728160463488068, 2.3501499999999997, 0.26483839536511933, 0.19014430285482856, 2.3501499999999997, 0.24197569714517148, + 0.19014430285482856, 2.3501499999999997, 0.24197569714517148, 0.16728160463488068, 2.3501499999999997, 0.26483839536511933, 0.16728160463488068, + 2.3501499999999997, 0.26483839536511933, 0.19014430285482856, 2.3501499999999997, 0.24197569714517148, 0.19014430285482856, 2.3501499999999997, + 0.24197569714517148, 0.16728160463488068, 2.5637999999999996, 0.26483839536511933, + 0.16728160463488068, 2.5637999999999996, 0.26483839536511933, 0.19014430285482856, 2.5637999999999996, 0.24197569714517148, 0.19014430285482856, + 2.5637999999999996, 0.24197569714517148, 0.16728160463488068, 2.5637999999999996, 0.26483839536511933, 0.16728160463488068, 2.5637999999999996, + 0.26483839536511933, 0.19014430285482856, 2.5637999999999996, 0.24197569714517148, 0.19014430285482856, 2.5637999999999996, 0.24197569714517148, + 0.16728160463488068, 2.7774499999999995, 0.26483839536511933, 0.16728160463488068, 2.7774499999999995, 0.26483839536511933, 0.19014430285482856, + 2.7774499999999995, 0.24197569714517148, 0.19014430285482856, 2.7774499999999995, 0.24197569714517148, 0.16728160463488068, 2.7774499999999995, + 0.26483839536511933, 0.16728160463488068, 2.7774499999999995, 0.26483839536511933, 0.19014430285482856, 2.7774499999999995, 0.24197569714517148, + 0.19014430285482856, 2.7774499999999995, 0.24197569714517148, 0.16728160463488068, 2.9910999999999999, 0.26483839536511933, 0.16728160463488068, + 2.9910999999999999, 0.26483839536511933, 0.19014430285482856, 2.9910999999999999, 0.24197569714517148, 0.19014430285482856, 2.9910999999999999, + 0.24197569714517148, 0.16728160463488068, 2.9910999999999999, 0.26483839536511933, 0.16728160463488068, 2.9910999999999999, 0.26483839536511933, + 0.19014430285482856, 2.9910999999999999, 0.24197569714517148, 0.19014430285482856, 2.9910999999999999, 0.24197569714517148, 0.16728160463488068, + 3.2047499999999998, 0.26483839536511933, 0.16728160463488068, 3.2047499999999998, 0.26483839536511933, 0.19014430285482856, 3.2047499999999998, + 0.24197569714517148, 0.19014430285482856, 3.2047499999999998, 0.24197569714517148, 0.16728160463488068, 3.2047499999999998, 0.26483839536511933, + 0.16728160463488068, 3.2047499999999998, 0.26483839536511933, 0.19014430285482856, 3.2047499999999998, 0.24197569714517148, 0.19014430285482856, + 3.2047499999999998, 0.24197569714517148, 0.16728160463488068, 3.4183999999999997, 0.26483839536511933, 0.16728160463488068, 3.4183999999999997, + 0.26483839536511933, 0.19014430285482856, 3.4183999999999997, 0.24197569714517148, 0.19014430285482856, 3.4183999999999997, 0.24197569714517148, + 0.16728160463488068, 3.4183999999999997, 0.26483839536511933, 0.16728160463488068, 3.4183999999999997, 0.26483839536511933, 0.19014430285482856, + 3.4183999999999997, 0.24197569714517148, 0.19014430285482856, 3.4183999999999997, 0.24197569714517148, 0.16728160463488068, 3.6320499999999996, + 0.26483839536511933, 0.16728160463488068, 3.6320499999999996, 0.26483839536511933, 0.19014430285482856, 3.6320499999999996, 0.24197569714517148, + 0.19014430285482856, 3.6320499999999996, 0.24197569714517148, 0.16728160463488068, 3.6320499999999996, 0.26483839536511933, 0.16728160463488068, + 3.6320499999999996, 0.26483839536511933, 0.19014430285482856, 3.6320499999999996, 0.24197569714517148, 0.19014430285482856, 3.6320499999999996, + 0.24197569714517148, 0.16728160463488068, 3.8456999999999995, 0.26483839536511933, 0.16728160463488068, 3.8456999999999995, 0.26483839536511933, + 0.19014430285482856, 3.8456999999999995, 0.24197569714517148, 0.19014430285482856, 3.8456999999999995, 0.24197569714517148, 0.16728160463488068, + 3.8456999999999995, 0.26483839536511933, 0.16728160463488068, 3.8456999999999995, 0.26483839536511933, 0.19014430285482856, 3.8456999999999995, + 0.24197569714517148, 0.19014430285482856, 3.8456999999999995, 0.24197569714517148, 0.16728160463488068, 4.0593499999999993, 0.26483839536511933, + 0.16728160463488068, 4.0593499999999993, 0.26483839536511933, 0.19014430285482856, 4.0593499999999993, 0.24197569714517148, 0.19014430285482856, + 4.0593499999999993, 0.24197569714517148, 0.16728160463488068, 4.0593499999999993, 0.26483839536511933, 0.16728160463488068, 4.0593499999999993, + 0.26483839536511933, 0.19014430285482856, 4.0593499999999993, 0.24197569714517148, 0.19014430285482856, 4.0593499999999993, 0.24197569714517148, + 0.16728160463488068, 4.2729999999999997, 0.26483839536511933, 0.16728160463488068, 4.2729999999999997, 0.26483839536511933, 0.19014430285482856, + 4.2729999999999997, 0.24197569714517148, 0.19014430285482856, 4.2729999999999997, + 0.31132160463488068, 0.16995569714517142, 0, 0.3368583953651193, 0.16995569714517142, 0, 0.3368583953651193, 0.18643419768255964, 0, 0.31132160463488068, + 0.18643419768255964, 0, 0.31132160463488068, 0.16995569714517142, 0.21364999999999998, 0.3368583953651193, 0.16995569714517142, 0.21364999999999998, + 0.3368583953651193, 0.18643419768255964, 0.21364999999999998, 0.31132160463488068, 0.18643419768255964, 0.21364999999999998, 0.31132160463488068, + 0.16995569714517142, 0.21364999999999998, 0.3368583953651193, 0.16995569714517142, 0.21364999999999998, 0.3368583953651193, 0.18643419768255964, + 0.21364999999999998, 0.31132160463488068, 0.18643419768255964, 0.21364999999999998, 0.31132160463488068, 0.16995569714517142, 0.42729999999999996, + 0.3368583953651193, 0.16995569714517142, 0.42729999999999996, 0.3368583953651193, 0.18643419768255964, 0.42729999999999996, 0.31132160463488068, + 0.18643419768255964, 0.42729999999999996, 0.31132160463488068, 0.16995569714517142, 0.42729999999999996, 0.3368583953651193, 0.16995569714517142, + 0.42729999999999996, 0.3368583953651193, 0.18643419768255964, 0.42729999999999996, 0.31132160463488068, 0.18643419768255964, 0.42729999999999996, + 0.31132160463488068, 0.16995569714517142, 0.64094999999999991, 0.3368583953651193, 0.16995569714517142, 0.64094999999999991, 0.3368583953651193, + 0.18643419768255964, 0.64094999999999991, 0.31132160463488068, 0.18643419768255964, 0.64094999999999991, 0.31132160463488068, 0.16995569714517142, + 0.64094999999999991, 0.3368583953651193, 0.16995569714517142, 0.64094999999999991, 0.3368583953651193, 0.18643419768255964, 0.64094999999999991, + 0.31132160463488068, 0.18643419768255964, 0.64094999999999991, 0.31132160463488068, 0.16995569714517142, 0.85459999999999992, 0.3368583953651193, + 0.16995569714517142, 0.85459999999999992, 0.3368583953651193, 0.18643419768255964, 0.85459999999999992, 0.31132160463488068, 0.18643419768255964, + 0.85459999999999992, 0.31132160463488068, 0.16995569714517142, 0.85459999999999992, 0.3368583953651193, 0.16995569714517142, 0.85459999999999992, + 0.3368583953651193, 0.18643419768255964, 0.85459999999999992, 0.31132160463488068, 0.18643419768255964, 0.85459999999999992, 0.31132160463488068, + 0.16995569714517142, 1.0682499999999999, 0.3368583953651193, 0.16995569714517142, 1.0682499999999999, 0.3368583953651193, 0.18643419768255964, + 1.0682499999999999, 0.31132160463488068, 0.18643419768255964, 1.0682499999999999, 0.31132160463488068, 0.16995569714517142, 1.0682499999999999, + 0.3368583953651193, 0.16995569714517142, 1.0682499999999999, 0.3368583953651193, 0.18643419768255964, 1.0682499999999999, 0.31132160463488068, + 0.18643419768255964, 1.0682499999999999, 0.31132160463488068, 0.16995569714517142, 1.2818999999999998, 0.3368583953651193, 0.16995569714517142, + 1.2818999999999998, 0.3368583953651193, 0.18643419768255964, 1.2818999999999998, 0.31132160463488068, 0.18643419768255964, 1.2818999999999998, + 0.31132160463488068, 0.16995569714517142, 1.2818999999999998, 0.3368583953651193, 0.16995569714517142, 1.2818999999999998, 0.3368583953651193, + 0.18643419768255964, 1.2818999999999998, 0.31132160463488068, 0.18643419768255964, 1.2818999999999998, 0.31132160463488068, 0.16995569714517142, + 1.4955499999999999, 0.3368583953651193, 0.16995569714517142, 1.4955499999999999, 0.3368583953651193, 0.18643419768255964, 1.4955499999999999, + 0.31132160463488068, 0.18643419768255964, 1.4955499999999999, 0.31132160463488068, 0.16995569714517142, 1.4955499999999999, 0.3368583953651193, + 0.16995569714517142, 1.4955499999999999, 0.3368583953651193, 0.18643419768255964, 1.4955499999999999, 0.31132160463488068, 0.18643419768255964, + 1.4955499999999999, 0.31132160463488068, 0.16995569714517142, 1.7091999999999998, 0.3368583953651193, 0.16995569714517142, 1.7091999999999998, + 0.3368583953651193, 0.18643419768255964, 1.7091999999999998, 0.31132160463488068, 0.18643419768255964, 1.7091999999999998, 0.31132160463488068, + 0.16995569714517142, 1.7091999999999998, 0.3368583953651193, 0.16995569714517142, 1.7091999999999998, 0.3368583953651193, 0.18643419768255964, + 1.7091999999999998, 0.31132160463488068, 0.18643419768255964, 1.7091999999999998, 0.31132160463488068, 0.16995569714517142, 1.9228499999999997, + 0.3368583953651193, 0.16995569714517142, 1.9228499999999997, 0.3368583953651193, 0.18643419768255964, 1.9228499999999997, 0.31132160463488068, + 0.18643419768255964, 1.9228499999999997, 0.31132160463488068, 0.16995569714517142, 1.9228499999999997, 0.3368583953651193, 0.16995569714517142, + 1.9228499999999997, 0.3368583953651193, 0.18643419768255964, 1.9228499999999997, 0.31132160463488068, 0.18643419768255964, 1.9228499999999997, + 0.31132160463488068, 0.16995569714517142, 2.1364999999999998, 0.3368583953651193, 0.16995569714517142, 2.1364999999999998, 0.3368583953651193, + 0.18643419768255964, 2.1364999999999998, 0.31132160463488068, 0.18643419768255964, 2.1364999999999998, 0.31132160463488068, 0.16995569714517142, + 2.1364999999999998, 0.3368583953651193, 0.16995569714517142, 2.1364999999999998, 0.3368583953651193, 0.18643419768255964, 2.1364999999999998, + 0.31132160463488068, 0.18643419768255964, 2.1364999999999998, 0.31132160463488068, 0.16995569714517142, 2.3501499999999997, 0.3368583953651193, + 0.16995569714517142, 2.3501499999999997, 0.3368583953651193, 0.18643419768255964, 2.3501499999999997, 0.31132160463488068, 0.18643419768255964, + 2.3501499999999997, 0.31132160463488068, 0.16995569714517142, 2.3501499999999997, 0.3368583953651193, 0.16995569714517142, 2.3501499999999997, + 0.3368583953651193, 0.18643419768255964, 2.3501499999999997, 0.31132160463488068, 0.18643419768255964, 2.3501499999999997, 0.31132160463488068, + 0.16995569714517142, 2.5637999999999996, 0.3368583953651193, 0.16995569714517142, 2.5637999999999996, 0.3368583953651193, 0.18643419768255964, + 2.5637999999999996, 0.31132160463488068, 0.18643419768255964, 2.5637999999999996, 0.31132160463488068, 0.16995569714517142, 2.5637999999999996, + 0.3368583953651193, 0.16995569714517142, 2.5637999999999996, 0.3368583953651193, 0.18643419768255964, 2.5637999999999996, 0.31132160463488068, + 0.18643419768255964, 2.5637999999999996, 0.31132160463488068, 0.16995569714517142, 2.7774499999999995, 0.3368583953651193, 0.16995569714517142, + 2.7774499999999995, 0.3368583953651193, 0.18643419768255964, 2.7774499999999995, 0.31132160463488068, 0.18643419768255964, 2.7774499999999995, + 0.31132160463488068, 0.16995569714517142, 2.7774499999999995, 0.3368583953651193, 0.16995569714517142, 2.7774499999999995, 0.3368583953651193, + 0.18643419768255964, 2.7774499999999995, 0.31132160463488068, 0.18643419768255964, 2.7774499999999995, 0.31132160463488068, 0.16995569714517142, + 2.9910999999999999, 0.3368583953651193, 0.16995569714517142, 2.9910999999999999, 0.3368583953651193, 0.18643419768255964, 2.9910999999999999, + 0.31132160463488068, 0.18643419768255964, 2.9910999999999999, 0.31132160463488068, 0.16995569714517142, 2.9910999999999999, 0.3368583953651193, + 0.16995569714517142, 2.9910999999999999, 0.3368583953651193, 0.18643419768255964, 2.9910999999999999, 0.31132160463488068, 0.18643419768255964, + 2.9910999999999999, 0.31132160463488068, 0.16995569714517142, 3.2047499999999998, 0.3368583953651193, 0.16995569714517142, 3.2047499999999998, + 0.3368583953651193, 0.18643419768255964, 3.2047499999999998, 0.31132160463488068, 0.18643419768255964, 3.2047499999999998, 0.31132160463488068, + 0.16995569714517142, 3.2047499999999998, 0.3368583953651193, 0.16995569714517142, 3.2047499999999998, 0.3368583953651193, 0.18643419768255964, + 3.2047499999999998, 0.31132160463488068, 0.18643419768255964, 3.2047499999999998, 0.31132160463488068, 0.16995569714517142, 3.4183999999999997, + 0.3368583953651193, 0.16995569714517142, 3.4183999999999997, 0.3368583953651193, 0.18643419768255964, 3.4183999999999997, 0.31132160463488068, + 0.18643419768255964, 3.4183999999999997, 0.31132160463488068, 0.16995569714517142, 3.4183999999999997, 0.3368583953651193, 0.16995569714517142, + 3.4183999999999997, 0.3368583953651193, 0.18643419768255964, 3.4183999999999997, 0.31132160463488068, 0.18643419768255964, 3.4183999999999997, + 0.31132160463488068, 0.16995569714517142, 3.6320499999999996, 0.3368583953651193, + 0.16995569714517142, 3.6320499999999996, 0.3368583953651193, 0.18643419768255964, 3.6320499999999996, 0.31132160463488068, 0.18643419768255964, + 3.6320499999999996, 0.31132160463488068, 0.16995569714517142, 3.6320499999999996, 0.3368583953651193, 0.16995569714517142, 3.6320499999999996, + 0.3368583953651193, 0.18643419768255964, 3.6320499999999996, 0.31132160463488068, 0.18643419768255964, 3.6320499999999996, 0.31132160463488068, + 0.16995569714517142, 3.8456999999999995, 0.3368583953651193, 0.16995569714517142, 3.8456999999999995, 0.3368583953651193, 0.18643419768255964, + 3.8456999999999995, 0.31132160463488068, 0.18643419768255964, 3.8456999999999995, 0.31132160463488068, 0.16995569714517142, 3.8456999999999995, + 0.3368583953651193, 0.16995569714517142, 3.8456999999999995, 0.3368583953651193, 0.18643419768255964, 3.8456999999999995, 0.31132160463488068, + 0.18643419768255964, 3.8456999999999995, 0.31132160463488068, 0.16995569714517142, 4.0593499999999993, 0.3368583953651193, 0.16995569714517142, + 4.0593499999999993, 0.3368583953651193, 0.18643419768255964, 4.0593499999999993, 0.31132160463488068, 0.18643419768255964, 4.0593499999999993, + 0.31132160463488068, 0.16995569714517142, 4.0593499999999993, 0.3368583953651193, 0.16995569714517142, 4.0593499999999993, 0.3368583953651193, + 0.18643419768255964, 4.0593499999999993, 0.31132160463488068, 0.18643419768255964, 4.0593499999999993, 0.31132160463488068, 0.16995569714517142, + 4.2729999999999997, 0.3368583953651193, 0.16995569714517142, 4.2729999999999997, 0.3368583953651193, 0.18643419768255964, 4.2729999999999997, + 0.31132160463488068, 0.18643419768255964, 4.2729999999999997, 0.38334160463488065, 0.1672816046348807, 0, 0.40620430285482856, 0.1672816046348807, 0, + 0.40620430285482856, 0.19014430285482853, 0, 0.38334160463488065, 0.19014430285482853, 0, 0.38334160463488065, 0.1672816046348807, 0.21364999999999998, + 0.40620430285482856, 0.1672816046348807, 0.21364999999999998, 0.40620430285482856, 0.19014430285482853, 0.21364999999999998, 0.38334160463488065, + 0.19014430285482853, 0.21364999999999998, 0.38334160463488065, 0.1672816046348807, 0.21364999999999998, 0.40620430285482856, 0.1672816046348807, + 0.21364999999999998, 0.40620430285482856, 0.19014430285482853, 0.21364999999999998, 0.38334160463488065, 0.19014430285482853, 0.21364999999999998, + 0.38334160463488065, 0.1672816046348807, 0.42729999999999996, 0.40620430285482856, 0.1672816046348807, 0.42729999999999996, 0.40620430285482856, + 0.19014430285482853, 0.42729999999999996, 0.38334160463488065, 0.19014430285482853, 0.42729999999999996, 0.38334160463488065, 0.1672816046348807, + 0.42729999999999996, 0.40620430285482856, 0.1672816046348807, 0.42729999999999996, 0.40620430285482856, 0.19014430285482853, 0.42729999999999996, + 0.38334160463488065, 0.19014430285482853, 0.42729999999999996, 0.38334160463488065, 0.1672816046348807, 0.64094999999999991, 0.40620430285482856, + 0.1672816046348807, 0.64094999999999991, 0.40620430285482856, 0.19014430285482853, 0.64094999999999991, 0.38334160463488065, 0.19014430285482853, + 0.64094999999999991, 0.38334160463488065, 0.1672816046348807, 0.64094999999999991, 0.40620430285482856, 0.1672816046348807, 0.64094999999999991, + 0.40620430285482856, 0.19014430285482853, 0.64094999999999991, 0.38334160463488065, 0.19014430285482853, 0.64094999999999991, 0.38334160463488065, + 0.1672816046348807, 0.85459999999999992, 0.40620430285482856, 0.1672816046348807, 0.85459999999999992, 0.40620430285482856, 0.19014430285482853, + 0.85459999999999992, 0.38334160463488065, 0.19014430285482853, 0.85459999999999992, 0.38334160463488065, 0.1672816046348807, 0.85459999999999992, + 0.40620430285482856, 0.1672816046348807, 0.85459999999999992, 0.40620430285482856, 0.19014430285482853, 0.85459999999999992, 0.38334160463488065, + 0.19014430285482853, 0.85459999999999992, 0.38334160463488065, 0.1672816046348807, 1.0682499999999999, 0.40620430285482856, 0.1672816046348807, + 1.0682499999999999, 0.40620430285482856, 0.19014430285482853, 1.0682499999999999, 0.38334160463488065, 0.19014430285482853, 1.0682499999999999, + 0.38334160463488065, 0.1672816046348807, 1.0682499999999999, 0.40620430285482856, 0.1672816046348807, 1.0682499999999999, 0.40620430285482856, + 0.19014430285482853, 1.0682499999999999, 0.38334160463488065, 0.19014430285482853, 1.0682499999999999, 0.38334160463488065, 0.1672816046348807, + 1.2818999999999998, 0.40620430285482856, 0.1672816046348807, 1.2818999999999998, 0.40620430285482856, 0.19014430285482853, 1.2818999999999998, + 0.38334160463488065, 0.19014430285482853, 1.2818999999999998, 0.38334160463488065, 0.1672816046348807, 1.2818999999999998, 0.40620430285482856, + 0.1672816046348807, 1.2818999999999998, 0.40620430285482856, 0.19014430285482853, 1.2818999999999998, 0.38334160463488065, 0.19014430285482853, + 1.2818999999999998, 0.38334160463488065, 0.1672816046348807, 1.4955499999999999, 0.40620430285482856, 0.1672816046348807, 1.4955499999999999, + 0.40620430285482856, 0.19014430285482853, 1.4955499999999999, 0.38334160463488065, 0.19014430285482853, 1.4955499999999999, 0.38334160463488065, + 0.1672816046348807, 1.4955499999999999, 0.40620430285482856, 0.1672816046348807, 1.4955499999999999, 0.40620430285482856, 0.19014430285482853, + 1.4955499999999999, 0.38334160463488065, 0.19014430285482853, 1.4955499999999999, 0.38334160463488065, 0.1672816046348807, 1.7091999999999998, + 0.40620430285482856, 0.1672816046348807, 1.7091999999999998, 0.40620430285482856, 0.19014430285482853, 1.7091999999999998, 0.38334160463488065, + 0.19014430285482853, 1.7091999999999998, 0.38334160463488065, 0.1672816046348807, 1.7091999999999998, 0.40620430285482856, 0.1672816046348807, + 1.7091999999999998, 0.40620430285482856, 0.19014430285482853, 1.7091999999999998, 0.38334160463488065, 0.19014430285482853, 1.7091999999999998, + 0.38334160463488065, 0.1672816046348807, 1.9228499999999997, 0.40620430285482856, 0.1672816046348807, 1.9228499999999997, 0.40620430285482856, + 0.19014430285482853, 1.9228499999999997, 0.38334160463488065, 0.19014430285482853, 1.9228499999999997, 0.38334160463488065, 0.1672816046348807, + 1.9228499999999997, 0.40620430285482856, 0.1672816046348807, 1.9228499999999997, 0.40620430285482856, 0.19014430285482853, 1.9228499999999997, + 0.38334160463488065, 0.19014430285482853, 1.9228499999999997, 0.38334160463488065, 0.1672816046348807, 2.1364999999999998, 0.40620430285482856, + 0.1672816046348807, 2.1364999999999998, 0.40620430285482856, 0.19014430285482853, 2.1364999999999998, 0.38334160463488065, 0.19014430285482853, + 2.1364999999999998, 0.38334160463488065, 0.1672816046348807, 2.1364999999999998, 0.40620430285482856, 0.1672816046348807, 2.1364999999999998, + 0.40620430285482856, 0.19014430285482853, 2.1364999999999998, 0.38334160463488065, 0.19014430285482853, 2.1364999999999998, 0.38334160463488065, + 0.1672816046348807, 2.3501499999999997, 0.40620430285482856, 0.1672816046348807, 2.3501499999999997, 0.40620430285482856, 0.19014430285482853, + 2.3501499999999997, 0.38334160463488065, 0.19014430285482853, 2.3501499999999997, 0.38334160463488065, 0.1672816046348807, 2.3501499999999997, + 0.40620430285482856, 0.1672816046348807, 2.3501499999999997, 0.40620430285482856, 0.19014430285482853, 2.3501499999999997, 0.38334160463488065, + 0.19014430285482853, 2.3501499999999997, 0.38334160463488065, 0.1672816046348807, 2.5637999999999996, 0.40620430285482856, 0.1672816046348807, + 2.5637999999999996, 0.40620430285482856, 0.19014430285482853, 2.5637999999999996, 0.38334160463488065, 0.19014430285482853, 2.5637999999999996, + 0.38334160463488065, 0.1672816046348807, 2.5637999999999996, 0.40620430285482856, 0.1672816046348807, 2.5637999999999996, 0.40620430285482856, + 0.19014430285482853, 2.5637999999999996, 0.38334160463488065, 0.19014430285482853, 2.5637999999999996, 0.38334160463488065, 0.1672816046348807, + 2.7774499999999995, 0.40620430285482856, 0.1672816046348807, 2.7774499999999995, 0.40620430285482856, 0.19014430285482853, 2.7774499999999995, + 0.38334160463488065, 0.19014430285482853, 2.7774499999999995, 0.38334160463488065, 0.1672816046348807, 2.7774499999999995, 0.40620430285482856, + 0.1672816046348807, 2.7774499999999995, 0.40620430285482856, 0.19014430285482853, + 2.7774499999999995, 0.38334160463488065, 0.19014430285482853, 2.7774499999999995, 0.38334160463488065, 0.1672816046348807, 2.9910999999999999, + 0.40620430285482856, 0.1672816046348807, 2.9910999999999999, 0.40620430285482856, 0.19014430285482853, 2.9910999999999999, 0.38334160463488065, + 0.19014430285482853, 2.9910999999999999, 0.38334160463488065, 0.1672816046348807, 2.9910999999999999, 0.40620430285482856, 0.1672816046348807, + 2.9910999999999999, 0.40620430285482856, 0.19014430285482853, 2.9910999999999999, 0.38334160463488065, 0.19014430285482853, 2.9910999999999999, + 0.38334160463488065, 0.1672816046348807, 3.2047499999999998, 0.40620430285482856, 0.1672816046348807, 3.2047499999999998, 0.40620430285482856, + 0.19014430285482853, 3.2047499999999998, 0.38334160463488065, 0.19014430285482853, 3.2047499999999998, 0.38334160463488065, 0.1672816046348807, + 3.2047499999999998, 0.40620430285482856, 0.1672816046348807, 3.2047499999999998, 0.40620430285482856, 0.19014430285482853, 3.2047499999999998, + 0.38334160463488065, 0.19014430285482853, 3.2047499999999998, 0.38334160463488065, 0.1672816046348807, 3.4183999999999997, 0.40620430285482856, + 0.1672816046348807, 3.4183999999999997, 0.40620430285482856, 0.19014430285482853, 3.4183999999999997, 0.38334160463488065, 0.19014430285482853, + 3.4183999999999997, 0.38334160463488065, 0.1672816046348807, 3.4183999999999997, 0.40620430285482856, 0.1672816046348807, 3.4183999999999997, + 0.40620430285482856, 0.19014430285482853, 3.4183999999999997, 0.38334160463488065, 0.19014430285482853, 3.4183999999999997, 0.38334160463488065, + 0.1672816046348807, 3.6320499999999996, 0.40620430285482856, 0.1672816046348807, 3.6320499999999996, 0.40620430285482856, 0.19014430285482853, + 3.6320499999999996, 0.38334160463488065, 0.19014430285482853, 3.6320499999999996, 0.38334160463488065, 0.1672816046348807, 3.6320499999999996, + 0.40620430285482856, 0.1672816046348807, 3.6320499999999996, 0.40620430285482856, 0.19014430285482853, 3.6320499999999996, 0.38334160463488065, + 0.19014430285482853, 3.6320499999999996, 0.38334160463488065, 0.1672816046348807, 3.8456999999999995, 0.40620430285482856, 0.1672816046348807, + 3.8456999999999995, 0.40620430285482856, 0.19014430285482853, 3.8456999999999995, 0.38334160463488065, 0.19014430285482853, 3.8456999999999995, + 0.38334160463488065, 0.1672816046348807, 3.8456999999999995, 0.40620430285482856, 0.1672816046348807, 3.8456999999999995, 0.40620430285482856, + 0.19014430285482853, 3.8456999999999995, 0.38334160463488065, 0.19014430285482853, 3.8456999999999995, 0.38334160463488065, 0.1672816046348807, + 4.0593499999999993, 0.40620430285482856, 0.1672816046348807, 4.0593499999999993, 0.40620430285482856, 0.19014430285482853, 4.0593499999999993, + 0.38334160463488065, 0.19014430285482853, 4.0593499999999993, 0.38334160463488065, 0.1672816046348807, 4.0593499999999993, 0.40620430285482856, + 0.1672816046348807, 4.0593499999999993, 0.40620430285482856, 0.19014430285482853, 4.0593499999999993, 0.38334160463488065, 0.19014430285482853, + 4.0593499999999993, 0.38334160463488065, 0.1672816046348807, 4.2729999999999997, 0.40620430285482856, 0.1672816046348807, 4.2729999999999997, + 0.40620430285482856, 0.19014430285482853, 4.2729999999999997, 0.38334160463488065, 0.19014430285482853, 4.2729999999999997 + }; + + +const int connTFH8[2560]={ + 1, 2, 7, 6, 28, 29, 34, 33, 2, 3, 8, 7, 29, 30, 35, 34, 3, 4, 9, 8, 30, 31, 36, 35, 4, 5, 10, 9, 31, 32, 37, 36, 6, 7, 12, 11, 33, 34, 39, 38, 7, 8, 13, 12, 34, 35, 40, 39, + 8, 9, 14, 13, 35, 36, 41, 40, 9, 10, 15, 14, 36, 37, 42, 41, 11, 12, 17, 16, 38, 39, 44, 43, 12, 13, 18, 17, 39, 40, 45, 44, 13, 14, 19, 18, 40, 41, 46, 45, 14, 15, 20, 19, + 41, 42, 47, 46, 16, 17, 21, 26, 43, 44, 48, 53, 17, 18, 22, 21, 44, 45, 49, 48, 18, 19, 23, 22, 45, 46, 50, 49, 19, 20, 24, 23, 46, 47, 51, 50, 28, 29, 34, 33, 55, 56, 61, 60, + 29, 30, 35, 34, 56, 57, 62, 61, 30, 31, 36, 35, 57, 58, 63, 62, 31, 32, 37, 36, 58, 59, 64, 63, 33, 34, 39, 38, 60, 61, 66, 65, 34, 35, 40, 39, 61, 62, 67, 66, 35, 36, 41, 40, + 62, 63, 68, 67, 36, 37, 42, 41, 63, 64, 69, 68, 38, 39, 44, 43, 65, 66, 71, 70, 39, 40, 45, 44, 66, 67, 72, 71, 40, 41, 46, 45, 67, 68, 73, 72, 41, 42, 47, 46, 68, 69, 74, 73, + 43, 44, 48, 53, 70, 71, 75, 80, 44, 45, 49, 48, 71, 72, 76, 75, 45, 46, 50, 49, 72, 73, 77, 76, 46, 47, 51, 50, 73, 74, 78, 77, 55, 56, 61, 60, 82, 83, 88, 87, 56, 57, 62, 61, + 83, 84, 89, 88, 57, 58, 63, 62, 84, 85, 90, 89, 58, 59, 64, 63, 85, 86, 91, 90, 60, 61, 66, 65, 87, 88, 93, 92, 61, 62, 67, 66, 88, 89, 94, 93, 62, 63, 68, 67, 89, 90, 95, 94, + 63, 64, 69, 68, 90, 91, 96, 95, 65, 66, 71, 70, 92, 93, 98, 97, 66, 67, 72, 71, 93, 94, 99, 98, 67, 68, 73, 72, 94, 95, 100, 99, 68, 69, 74, 73, 95, 96, 101, 100, 70, 71, 75, + 80, 97, 98, 102, 107, 71, 72, 76, 75, 98, 99, 103, 102, 72, 73, 77, 76, 99, 100, 104, 103, 73, 74, 78, 77, 100, 101, 105, 104, 82, 83, 88, 87, 109, 110, 115, 114, 83, 84, 89, + 88, 110, 111, 116, 115, 84, 85, 90, 89, 111, 112, 117, 116, 85, 86, 91, 90, 112, 113, 118, 117, 87, 88, 93, 92, 114, 115, 120, 119, 88, 89, 94, 93, 115, 116, 121, 120, 89, 90, + 95, 94, 116, 117, 122, 121, 90, 91, 96, 95, 117, 118, 123, 122, 92, 93, 98, 97, 119, 120, 125, 124, 93, 94, 99, 98, 120, 121, 126, 125, 94, 95, 100, 99, 121, 122, 127, 126, 95, + 96, 101, 100, 122, 123, 128, 127, 97, 98, 102, 107, 124, 125, 129, 134, 98, 99, 103, 102, 125, 126, 130, 129, 99, 100, 104, 103, 126, 127, 131, 130, 100, 101, 105, 104, 127, 128, + 132, 131, 109, 110, 115, 114, 136, 137, 142, 141, 110, 111, 116, 115, 137, 138, 143, 142, 111, 112, 117, 116, 138, 139, 144, 143, 112, 113, 118, 117, 139, 140, 145, 144, 114, 115, + 120, 119, 141, 142, 147, 146, 115, 116, 121, 120, 142, 143, 148, 147, 116, 117, 122, 121, 143, 144, 149, 148, 117, 118, 123, 122, 144, 145, 150, 149, 119, 120, 125, 124, 146, 147, + 152, 151, 120, 121, 126, 125, 147, 148, 153, 152, 121, 122, 127, 126, 148, 149, 154, 153, 122, 123, 128, 127, 149, 150, 155, 154, 124, 125, 129, 134, 151, 152, 156, 161, 125, 126, 130, + 129, 152, 153, 157, 156, 126, 127, 131, 130, 153, 154, 158, 157, 127, 128, 132, 131, 154, 155, 159, 158, 136, 137, 142, 141, 163, 164, 169, 168, 137, 138, 143, 142, 164, 165, 170, 169, 138, 139, 144, 143, 165, 166, 171, 170, 139, + 140, 145, 144, 166, 167, 172, 171, 141, 142, 147, 146, 168, 169, 174, 173, 142, 143, 148, 147, 169, 170, 175, 174, 143, 144, 149, 148, 170, 171, 176, 175, 144, 145, 150, 149, 171, 172, 177, 176, 146, 147, 152, 151, 173, 174, 179, + 178, 147, 148, 153, 152, 174, 175, 180, 179, 148, 149, 154, 153, 175, 176, 181, 180, 149, 150, 155, 154, 176, 177, 182, 181, 151, 152, 156, 161, 178, 179, 183, 188, 152, 153, 157, 156, 179, 180, 184, 183, 153, 154, 158, 157, 180, + 181, 185, 184, 154, 155, 159, 158, 181, 182, 186, 185, 163, 164, 169, 168, 190, 191, 196, 195, 164, 165, 170, 169, 191, 192, 197, 196, 165, 166, 171, 170, 192, 193, 198, 197, 166, 167, 172, 171, 193, 194, 199, 198, 168, 169, 174, + 173, 195, 196, 201, 200, 169, 170, 175, 174, 196, 197, 202, 201, 170, 171, 176, 175, 197, 198, 203, 202, 171, 172, 177, 176, 198, 199, 204, 203, 173, 174, 179, 178, 200, 201, 206, 205, 174, 175, 180, 179, 201, 202, 207, 206, 175, + 176, 181, 180, 202, 203, 208, 207, 176, 177, 182, 181, 203, 204, 209, 208, 178, 179, 183, 188, 205, 206, 210, 215, 179, 180, 184, 183, 206, 207, 211, 210, 180, 181, 185, 184, 207, 208, 212, 211, 181, 182, 186, 185, 208, 209, 213, + 212, 190, 191, 196, 195, 217, 218, 223, 222, 191, 192, 197, 196, 218, 219, 224, 223, 192, 193, 198, 197, 219, 220, 225, 224, 193, 194, 199, 198, 220, 221, 226, 225, 195, 196, 201, 200, 222, 223, 228, 227, 196, 197, 202, 201, 223, + 224, 229, 228, 197, 198, 203, 202, 224, 225, 230, 229, 198, 199, 204, 203, 225, 226, 231, 230, 200, 201, 206, 205, 227, 228, 233, 232, 201, 202, 207, 206, 228, 229, 234, 233, 202, 203, 208, 207, 229, 230, 235, 234, 203, 204, 209, + 208, 230, 231, 236, 235, 205, 206, 210, 215, 232, 233, 237, 242, 206, 207, 211, 210, 233, 234, 238, 237, 207, 208, 212, 211, 234, 235, 239, 238, 208, 209, 213, 212, 235, 236, 240, 239, 217, 218, 223, 222, 244, 245, 250, 249, 218, + 219, 224, 223, 245, 246, 251, 250, 219, 220, 225, 224, 246, 247, 252, 251, 220, 221, 226, 225, 247, 248, 253, 252, 222, 223, 228, 227, 249, 250, 255, 254, 223, 224, 229, 228, 250, 251, 256, 255, 224, 225, 230, 229, 251, 252, 257, + 256, 225, 226, 231, 230, 252, 253, 258, 257, 227, 228, 233, 232, 254, 255, 260, 259, 228, 229, 234, 233, 255, 256, 261, 260, 229, 230, 235, 234, 256, 257, 262, 261, 230, 231, 236, 235, 257, 258, 263, 262, 232, 233, 237, 242, 259, + 260, 264, 269, 233, 234, 238, 237, 260, 261, 265, 264, 234, 235, 239, 238, 261, 262, 266, 265, 235, 236, 240, 239, 262, 263, 267, 266, 244, 245, 250, 249, 271, 272, 277, 276, 245, 246, 251, 250, 272, 273, 278, 277, 246, 247, 252, + 251, 273, 274, 279, 278, 247, 248, 253, 252, 274, 275, 280, 279, 249, 250, 255, 254, 276, 277, 282, 281, 250, 251, 256, 255, 277, 278, 283, 282, 251, 252, 257, 256, 278, 279, 284, 283, 252, 253, 258, 257, 279, 280, 285, 284, 254, + 255, 260, 259, 281, 282, 287, 286, 255, 256, 261, 260, 282, 283, 288, 287, 256, 257, 262, 261, 283, 284, 289, 288, 257, 258, 263, 262, 284, 285, 290, 289, 259, 260, 264, 269, 286, 287, 291, 296, 260, 261, 265, 264, 287, 288, 292, + 291, 261, 262, 266, 265, 288, 289, 293, 292, 262, 263, 267, 266, 289, 290, 294, 293, 271, 272, 277, 276, 298, 299, 304, 303, 272, 273, 278, 277, 299, 300, 305, 304, 273, 274, 279, 278, 300, 301, 306, 305, 274, 275, 280, 279, 301, + 302, 307, 306, 276, 277, 282, 281, 303, 304, 309, 308, 277, 278, 283, 282, 304, 305, 310, 309, 278, 279, 284, 283, 305, 306, 311, 310, 279, 280, 285, 284, 306, 307, 312, 311, 281, 282, 287, 286, 308, 309, 314, 313, 282, 283, 288, + 287, 309, 310, 315, 314, 283, 284, 289, 288, 310, 311, 316, 315, 284, 285, 290, 289, 311, 312, 317, 316, 286, 287, 291, 296, 313, 314, 318, 323, 287, 288, 292, 291, 314, 315, 319, 318, 288, 289, 293, 292, 315, 316, 320, 319, 289, + 290, 294, 293, 316, 317, 321, 320, 298, 299, 304, 303, 325, 326, 331, 330, 299, 300, 305, 304, 326, 327, 332, 331, 300, 301, 306, 305, 327, 328, 333, 332, 301, 302, 307, 306, 328, 329, 334, 333, 303, 304, 309, 308, 330, 331, 336, + 335, 304, 305, 310, 309, 331, 332, 337, 336, 305, 306, 311, 310, 332, 333, 338, 337, 306, 307, 312, 311, 333, 334, 339, 338, 308, 309, 314, 313, 335, 336, 341, 340, 309, 310, 315, 314, 336, 337, 342, 341, 310, 311, 316, 315, 337, + 338, 343, 342, 311, 312, 317, 316, 338, 339, 344, 343, 313, 314, 318, 323, 340, 341, 345, 350, 314, 315, 319, 318, 341, 342, 346, 345, 315, 316, 320, 319, 342, 343, 347, 346, 316, 317, 321, 320, 343, 344, 348, 347, 325, 326, 331, + 330, 352, 353, 358, 357, 326, 327, 332, 331, 353, 354, 359, 358, 327, 328, 333, 332, 354, 355, 360, 359, 328, 329, 334, 333, 355, 356, 361, 360, 330, 331, 336, 335, 357, 358, 363, 362, 331, 332, 337, 336, 358, 359, 364, 363, 332, + 333, 338, 337, 359, 360, 365, 364, 333, 334, 339, 338, 360, 361, 366, 365, 335, 336, 341, 340, 362, 363, 368, 367, 336, 337, 342, 341, 363, 364, 369, 368, 337, 338, 343, 342, 364, 365, 370, 369, 338, 339, 344, 343, 365, 366, 371, + 370, 340, 341, 345, 350, 367, 368, 372, 377, 341, 342, 346, 345, 368, 369, 373, 372, 342, 343, 347, 346, 369, 370, 374, 373, 343, 344, 348, 347, 370, 371, 375, 374, 352, 353, 358, 357, 379, 380, 385, 384, 353, 354, 359, 358, 380, + 381, 386, 385, 354, 355, 360, 359, 381, 382, 387, 386, 355, 356, 361, 360, 382, 383, 388, 387, 357, 358, 363, 362, 384, 385, 390, 389, 358, 359, 364, 363, 385, 386, 391, 390, 359, 360, 365, 364, 386, 387, 392, 391, 360, 361, 366, + 365, 387, 388, 393, 392, 362, 363, 368, 367, 389, 390, 395, 394, 363, 364, 369, 368, 390, 391, 396, 395, 364, 365, 370, 369, 391, 392, 397, 396, 365, 366, 371, 370, 392, 393, 398, 397, 367, 368, 372, 377, 394, 395, 399, 404, 368, + 369, 373, 372, 395, 396, 400, 399, 369, 370, 374, 373, 396, 397, 401, 400, 370, 371, 375, 374, 397, 398, 402, 401, 379, 380, 385, 384, 406, 407, 412, 411, 380, 381, 386, 385, 407, 408, 413, 412, 381, 382, 387, 386, 408, 409, 414, + 413, 382, 383, 388, 387, 409, 410, 415, 414, 384, 385, 390, 389, 411, 412, 417, 416, 385, 386, 391, 390, 412, 413, 418, 417, 386, 387, 392, 391, 413, 414, 419, 418, 387, 388, 393, 392, 414, 415, 420, 419, 389, 390, 395, 394, 416, + 417, 422, 421, 390, 391, 396, 395, 417, 418, 423, 422, 391, 392, 397, 396, 418, 419, 424, 423, 392, 393, 398, 397, 419, 420, 425, 424, 394, 395, 399, 404, 421, 422, 426, 431, 395, 396, 400, 399, 422, 423, 427, 426, 396, 397, 401, + 400, 423, 424, 428, 427, 397, 398, 402, 401, 424, 425, 429, 428, 406, 407, 412, 411, 433, 434, 439, 438, 407, 408, 413, 412, 434, 435, 440, 439, 408, 409, 414, 413, 435, 436, 441, 440, 409, 410, 415, 414, 436, 437, 442, 441, 411, + 412, 417, 416, 438, 439, 444, 443, 412, 413, 418, 417, 439, 440, 445, 444, 413, 414, 419, 418, 440, 441, 446, 445, 414, 415, 420, 419, 441, 442, 447, 446, 416, 417, 422, 421, 443, 444, 449, 448, 417, 418, 423, 422, 444, 445, 450, + 449, 418, 419, 424, 423, 445, 446, 451, 450, 419, 420, 425, 424, 446, 447, 452, 451, 421, 422, 426, 431, 448, 449, 453, 458, 422, 423, 427, 426, 449, 450, 454, 453, 423, 424, 428, 427, 450, 451, 455, 454, 424, 425, 429, 428, 451, + 452, 456, 455, 433, 434, 439, 438, 460, 461, 466, 465, 434, 435, 440, 439, 461, 462, 467, 466, 435, 436, 441, 440, 462, 463, 468, 467, 436, 437, 442, 441, 463, 464, 469, 468, 438, 439, 444, 443, 465, 466, 471, 470, 439, 440, 445, + 444, 466, 467, 472, 471, 440, 441, 446, 445, 467, 468, 473, 472, 441, 442, 447, 446, 468, 469, 474, 473, 443, 444, 449, 448, 470, 471, 476, 475, 444, 445, 450, 449, 471, 472, 477, 476, 445, 446, 451, 450, 472, 473, 478, 477, 446, + 447, 452, 451, 473, 474, 479, 478, 448, 449, 453, 458, 475, 476, 480, 485, 449, 450, 454, 453, 476, 477, 481, 480, 450, 451, 455, 454, 477, 478, 482, 481, 451, 452, 456, 455, 478, 479, 483, 482, 460, 461, 466, 465, 487, 488, 493, + 492, 461, 462, 467, 466, 488, 489, 494, 493, 462, 463, 468, 467, 489, 490, 495, 494, 463, 464, 469, 468, 490, 491, 496, 495, 465, 466, 471, 470, 492, 493, 498, 497, 466, 467, 472, 471, 493, 494, 499, 498, 467, 468, 473, 472, 494, + 495, 500, 499, 468, 469, 474, 473, 495, 496, 501, 500, 470, 471, 476, 475, 497, 498, 503, 502, 471, 472, 477, 476, 498, 499, 504, 503, 472, 473, 478, 477, 499, 500, 505, 504, 473, 474, 479, 478, 500, 501, 506, 505, 475, 476, 480, + 485, 502, 503, 507, 512, 476, 477, 481, 480, 503, 504, 508, 507, 477, 478, 482, 481, 504, 505, 509, 508, 478, 479, 483, 482, 505, 506, 510, 509, 487, 488, 493, 492, 514, 515, 520, 519, 488, 489, 494, 493, 515, 516, 521, 520, 489, + 490, 495, 494, 516, 517, 522, 521, 490, 491, 496, 495, 517, 518, 523, 522, 492, 493, 498, 497, 519, 520, 525, 524, 493, 494, 499, 498, 520, 521, 526, 525, 494, 495, 500, 499, 521, 522, 527, 526, 495, 496, 501, 500, 522, 523, 528, + 527, 497, 498, 503, 502, 524, 525, 530, 529, 498, 499, 504, 503, 525, 526, 531, 530, 499, 500, 505, 504, 526, 527, 532, 531, 500, 501, 506, 505, 527, 528, 533, 532, 502, 503, 507, 512, 529, 530, 534, 539, 503, 504, 508, 507, 530, + 531, 535, 534, 504, 505, 509, 508, 531, 532, 536, 535, 505, 506, 510, 509, 532, 533, 537, 536, 514, 515, 520, 519, 541, 542, 547, 546, 515, 516, 521, 520, 542, 543, 548, 547, 516, 517, 522, 521, 543, 544, 549, 548, 517, 518, 523, + 522, 544, 545, 550, 549, 519, 520, 525, 524, 546, 547, 552, 551, 520, 521, 526, 525, 547, 548, 553, 552, 521, 522, 527, 526, 548, 549, 554, 553, 522, 523, 528, 527, 549, 550, 555, 554, 524, 525, 530, 529, 551, 552, 557, 556, 525, + 526, 531, 530, 552, 553, 558, 557, 526, 527, 532, 531, 553, 554, 559, 558, 527, 528, 533, 532, 554, 555, 560, 559, 529, 530, 534, 539, 556, 557, 561, 566, 530, 531, 535, 534, 557, 558, 562, 561, 531, 532, 536, 535, 558, 559, 563, + 562, 532, 533, 537, 536, 559, 560, 564, 563}; + +const int connTFPOLH[1000]={ + 0, 25, 26, 16, 11, 6, 1, -1, 27, 28, 33, 38, 43, 53, 52, -1, 0, 1, 28, 27, -1, 1, 6, 33, 28, -1, 6, 11, 38, 33, -1, 11, 16, 43, 38, -1, 16, 26, 53, 43, -1, 26, 25, 52, 53, -1, 25, 0, 27, 52, 27, 52, 53, 43, 38, 33, 28, -1, 54, 55, + 60, 65, 70, 80, 79, -1, 27, 28, 55, 54, -1, 28, 33, 60, 55, -1, 33, 38, 65, 60, -1, 38, 43, 70, 65, -1, 43, 53, 80, 70, -1, 53, 52, 79, 80, -1, 52, 27, 54, 79, 54, 79, 80, 70, 65, 60, 55, -1, 81, 82, 87, 92, 97, 107, 106, -1, 54, + 55, 82, 81, -1, 55, 60, 87, 82, -1, 60, 65, 92, 87, -1, 65, 70, 97, 92, -1, 70, 80, 107, 97, -1, 80, 79, 106, 107, -1, 79, 54, 81, 106, 81, 106, 107, 97, 92, 87, 82, -1, 108, 109, 114, 119, 124, 134, 133, -1, 81, 82, 109, 108, -1, + 82, 87, 114, 109, -1, 87, 92, 119, 114, -1, 92, 97, 124, 119, -1, 97, 107, 134, 124, -1, 107, 106, 133, 134, -1, 106, 81, 108, 133, 108, 133, 134, 124, 119, 114, 109, -1, 135, 136, 141, 146, 151, 161, 160, -1, 108, 109, 136, 135, + -1, 109, 114, 141, 136, -1, 114, 119, 146, 141, -1, 119, 124, 151, 146, -1, 124, 134, 161, 151, -1, 134, 133, 160, 161, -1, 133, 108, 135, 160, 135, 160, 161, 151, 146, 141, 136, -1, 162, 163, 168, 173, 178, 188, 187, -1, 135, 136, + 163, 162, -1, 136, 141, 168, 163, -1, 141, 146, 173, 168, -1, 146, 151, 178, 173, -1, 151, 161, 188, 178, -1, 161, 160, 187, 188, -1, 160, 135, 162, 187, 162, 187, 188, 178, 173, 168, 163, -1, 189, 190, 195, 200, 205, 215, 214, -1, + 162, 163, 190, 189, -1, 163, 168, 195, 190, -1, 168, 173, 200, 195, -1, 173, 178, 205, 200, -1, 178, 188, 215, 205, -1, 188, 187, 214, 215, -1, 187, 162, 189, 214, 189, 214, 215, 205, 200, 195, 190, -1, 216, 217, 222, 227, 232, 242, + 241, -1, 189, 190, 217, 216, -1, 190, 195, 222, 217, -1, 195, 200, 227, 222, -1, 200, 205, 232, 227, -1, 205, 215, 242, 232, -1, 215, 214, 241, 242, -1, 214, 189, 216, 241, 216, 241, 242, 232, 227, 222, 217, -1, 243, 244, 249, 254, +259, 269, 268, -1, 216, 217, 244, 243, -1, 217, 222, 249, 244, -1, 222, 227, 254, 249, -1, 227, 232, 259, 254, -1, 232, 242, 269, 259, -1, 242, 241, 268, 269, -1, 241, 216, 243, 268, 243, 268, 269, 259, 254, 249, 244, -1, 270, 271, 276, + 281, 286, 296, 295, -1, 243, 244, 271, 270, -1, 244, 249, 276, 271, -1, 249, 254, 281, 276, -1, 254, 259, 286, 281, -1, 259, 269, 296, 286, -1, 269, 268, 295, 296, -1, 268, 243, 270, 295, 270, 295, 296, 286, 281, 276, 271, -1, 297, 298, + 303, 308, 313, 323, 322, -1, 270, 271, 298, 297, -1, 271, 276, 303, 298, -1, 276, 281, 308, 303, -1, 281, 286, 313, 308, -1, 286, 296, 323, 313, -1, 296, 295, 322, 323, -1, 295, 270, 297, 322, 297, 322, 323, 313, 308, 303, 298, -1, 324, + 325, 330, 335, 340, 350, 349, -1, 297, 298, 325, 324, -1, 298, 303, 330, 325, -1, 303, 308, 335, 330, -1, 308, 313, 340, 335, -1, 313, 323, 350, 340, -1, 323, 322, 349, 350, -1, 322, 297, 324, 349, 324, 349, 350, 340, 335, 330, 325, -1, + 351, 352, 357, 362, 367, 377, 376, -1, 324, 325, 352, 351, -1, 325, 330, 357, 352, -1, 330, 335, 362, 357, -1, 335, 340, 367, 362, -1, 340, 350, 377, 367, -1, 350, 349, 376, 377, -1, 349, 324, 351, 376, 351, 376, 377, 367, 362, 357, 352, + -1, 378, 379, 384, 389, 394, 404, 403, -1, 351, 352, 379, 378, -1, 352, 357, 384, 379, -1, 357, 362, 389, 384, -1, 362, 367, 394, 389, -1, 367, 377, 404, 394, -1, 377, 376, 403, 404, -1, 376, 351, 378, 403, 378, 403, 404, 394, 389, 384, + 379, -1, 405, 406, 411, 416, 421, 431, 430, -1, 378, 379, 406, 405, -1, 379, 384, 411, 406, -1, 384, 389, 416, 411, -1, 389, 394, 421, 416, -1, 394, 404, 431, 421, -1, 404, 403, 430, 431, -1, 403, 378, 405, 430, 405, 430, 431, 421, 416, + 411, 406, -1, 432, 433, 438, 443, 448, 458, 457, -1, 405, 406, 433, 432, -1, 406, 411, 438, 433, -1, 411, 416, 443, 438, -1, 416, 421, 448, 443, -1, 421, 431, 458, 448, -1, 431, 430, 457, 458, -1, 430, 405, 432, 457, 432, 457, 458, 448, + 443, 438, 433, -1, 459, 460, 465, 470, 475, 485, 484, -1, 432, 433, 460, 459, -1, 433, 438, 465, 460, -1, 438, 443, 470, 465, -1, 443, 448, 475, 470, -1, 448, 458, 485, 475, -1, 458, 457, 484, 485, -1, 457, 432, 459, 484, 459, 484, 485, + 475, 470, 465, 460, -1, 486, 487, 492, 497, 502, 512, 511, -1, 459, 460, 487, 486, -1, 460, 465, 492, 487, -1, 465, 470, 497, 492, -1, 470, 475, 502, 497, -1, 475, 485, 512, 502, -1, 485, 484, 511, 512, -1, 484, 459, 486, 511, 486, 511, + 512, 502, 497, 492, 487, -1, 513, 514, 519, 524, 529, 539, 538, -1, 486, 487, 514, 513, -1, 487, 492, 519, 514, -1, 492, 497, 524, 519, -1, 497, 502, 529, 524, -1, 502, 512, 539, 529, -1, 512, 511, 538, 539, -1, 511, 486, 513, 538, 513, + 538, 539, 529, 524, 519, 514, -1, 540, 541, 546, 551, 556, 566, 565, -1, 513, 514, 541, 540, -1, 514, 519, 546, 541, -1, 519, 524, 551, 546, -1, 524, 529, 556, 551, -1, 529, 539, 566, 556, -1, 539, 538, 565, 566, -1, 538, 513, 540, 565 +}; + +const double coordsTF[1701]={ + 0, 0, 0, 0.21606, 0, 0, 0.25207000000000002, 0, 0, 0.32408999999999999, 0, 0, 0.39610999999999996, 0, 0, 0.43212, 0, 0, 0.21606, 0.03601, 0, + 0.25207000000000002, 0.03601, 0, 0.32408999999999999, 0.03601, 0, 0.39610999999999996, 0.03601, 0, 0.43212, 0.03601, 0, 0.21606, 0.10803, 0, 0.25207000000000002, + 0.10803, 0, 0.32408999999999999, 0.10803, 0, 0.39610999999999996, 0.10803, 0, 0.43212, 0.10803, 0, 0.21606, 0.18004999999999999, 0, 0.25207000000000002, + 0.18004999999999999, 0, 0.32408999999999999, 0.18004999999999999, 0, 0.39610999999999996, 0.18004999999999999, 0, 0.43212, 0.18004999999999999, 0, + 0.25207000000000002, 0.21605999999999997, 0, 0.32408999999999999, 0.21605999999999997, 0, 0.39610999999999996, 0.21605999999999997, 0, 0.43212, + 0.21605999999999997, 0, 0, 0.21606, 0, 0.21606, 0.21606, 0, 0, 0, 0.21364999999999998, 0.21606, 0, 0.21364999999999998, 0.25207000000000002, 0, + 0.21364999999999998, 0.32408999999999999, 0, 0.21364999999999998, 0.39610999999999996, 0, 0.21364999999999998, 0.43212, 0, 0.21364999999999998, 0.21606, 0.03601, + 0.21364999999999998, 0.25207000000000002, 0.03601, 0.21364999999999998, 0.32408999999999999, 0.03601, 0.21364999999999998, 0.39610999999999996, 0.03601, + 0.21364999999999998, 0.43212, 0.03601, 0.21364999999999998, 0.21606, 0.10803, 0.21364999999999998, 0.25207000000000002, 0.10803, 0.21364999999999998, + 0.32408999999999999, 0.10803, 0.21364999999999998, 0.39610999999999996, 0.10803, 0.21364999999999998, 0.43212, 0.10803, 0.21364999999999998, 0.21606, + 0.18004999999999999, 0.21364999999999998, 0.25207000000000002, 0.18004999999999999, 0.21364999999999998, 0.32408999999999999, 0.18004999999999999, + 0.21364999999999998, 0.39610999999999996, 0.18004999999999999, 0.21364999999999998, 0.43212, 0.18004999999999999, 0.21364999999999998, 0.25207000000000002, + 0.21605999999999997, 0.21364999999999998, 0.32408999999999999, 0.21605999999999997, 0.21364999999999998, 0.39610999999999996, 0.21605999999999997, + 0.21364999999999998, 0.43212, 0.21605999999999997, 0.21364999999999998, 0, 0.21606, 0.21364999999999998, 0.21606, 0.21606, 0.21364999999999998, 0, 0, + 0.42729999999999996, 0.21606, 0, 0.42729999999999996, 0.25207000000000002, 0, 0.42729999999999996, 0.32408999999999999, 0, 0.42729999999999996, + 0.39610999999999996, 0, 0.42729999999999996, 0.43212, 0, 0.42729999999999996, 0.21606, 0.03601, 0.42729999999999996, 0.25207000000000002, 0.03601, + 0.42729999999999996, 0.32408999999999999, 0.03601, 0.42729999999999996, 0.39610999999999996, 0.03601, 0.42729999999999996, 0.43212, 0.03601, 0.42729999999999996, + 0.21606, 0.10803, 0.42729999999999996, 0.25207000000000002, 0.10803,0.42729999999999996, 0.32408999999999999, 0.10803, 0.42729999999999996, 0.39610999999999996, 0.10803, 0.42729999999999996, 0.43212, 0.10803, + 0.42729999999999996, 0.21606, 0.18004999999999999, 0.42729999999999996, 0.25207000000000002, 0.18004999999999999, 0.42729999999999996, 0.32408999999999999, + 0.18004999999999999, 0.42729999999999996, 0.39610999999999996, 0.18004999999999999, 0.42729999999999996, 0.43212, 0.18004999999999999, 0.42729999999999996, + 0.25207000000000002, 0.21605999999999997, 0.42729999999999996, 0.32408999999999999, 0.21605999999999997, 0.42729999999999996, 0.39610999999999996, + 0.21605999999999997, 0.42729999999999996, 0.43212, 0.21605999999999997, 0.42729999999999996, 0, 0.21606, 0.42729999999999996, 0.21606, 0.21606, + 0.42729999999999996, 0, 0, 0.64094999999999991, 0.21606, 0, 0.64094999999999991, 0.25207000000000002, 0, 0.64094999999999991, 0.32408999999999999, 0, + 0.64094999999999991, 0.39610999999999996, 0, 0.64094999999999991, 0.43212, 0, 0.64094999999999991, 0.21606, 0.03601, 0.64094999999999991, 0.25207000000000002, + 0.03601, 0.64094999999999991, 0.32408999999999999, 0.03601, 0.64094999999999991, 0.39610999999999996, 0.03601, 0.64094999999999991, 0.43212, 0.03601, + 0.64094999999999991, 0.21606, 0.10803, 0.64094999999999991, 0.25207000000000002, 0.10803, 0.64094999999999991, 0.32408999999999999, 0.10803, 0.64094999999999991, + 0.39610999999999996, 0.10803, 0.64094999999999991, 0.43212, 0.10803, 0.64094999999999991, 0.21606, 0.18004999999999999, 0.64094999999999991, 0.25207000000000002, + 0.18004999999999999, 0.64094999999999991, 0.32408999999999999, 0.18004999999999999, 0.64094999999999991, 0.39610999999999996, 0.18004999999999999, + 0.64094999999999991, 0.43212, 0.18004999999999999, 0.64094999999999991, 0.25207000000000002, 0.21605999999999997, 0.64094999999999991, 0.32408999999999999, + 0.21605999999999997, 0.64094999999999991, 0.39610999999999996, 0.21605999999999997, 0.64094999999999991, 0.43212, 0.21605999999999997, 0.64094999999999991, 0, + 0.21606, 0.64094999999999991, 0.21606, 0.21606, 0.64094999999999991, 0, 0, 0.85459999999999992, 0.21606, 0, 0.85459999999999992, 0.25207000000000002, 0, + 0.85459999999999992, 0.32408999999999999, 0, 0.85459999999999992, 0.39610999999999996, 0, 0.85459999999999992, 0.43212, 0, 0.85459999999999992, 0.21606, 0.03601, + 0.85459999999999992, 0.25207000000000002, 0.03601, 0.85459999999999992, 0.32408999999999999, 0.03601, 0.85459999999999992, 0.39610999999999996, 0.03601, + 0.85459999999999992, 0.43212, 0.03601, 0.85459999999999992, 0.21606, 0.10803, 0.85459999999999992, 0.25207000000000002, 0.10803, 0.85459999999999992, + 0.32408999999999999, 0.10803, 0.85459999999999992, 0.39610999999999996, 0.10803, 0.85459999999999992, 0.43212, 0.10803, 0.85459999999999992, 0.21606, + 0.18004999999999999, 0.85459999999999992, 0.25207000000000002, 0.18004999999999999, 0.85459999999999992, 0.32408999999999999, 0.18004999999999999, + 0.85459999999999992, 0.39610999999999996, 0.18004999999999999, 0.85459999999999992, 0.43212, 0.18004999999999999, 0.85459999999999992, 0.25207000000000002, + 0.21605999999999997, 0.85459999999999992, 0.32408999999999999, 0.21605999999999997, 0.85459999999999992, 0.39610999999999996, 0.21605999999999997, + 0.85459999999999992, 0.43212, 0.21605999999999997, 0.85459999999999992, 0,0.21606, 0.85459999999999992, 0.21606, 0.21606, 0.85459999999999992, 0, 0, 1.0682499999999999, 0.21606, 0, 1.0682499999999999, 0.25207000000000002, 0, + 1.0682499999999999, 0.32408999999999999, 0, 1.0682499999999999, 0.39610999999999996, 0, 1.0682499999999999, 0.43212, 0, 1.0682499999999999, 0.21606, 0.03601, + 1.0682499999999999, 0.25207000000000002, 0.03601, 1.0682499999999999, 0.32408999999999999, 0.03601, 1.0682499999999999, 0.39610999999999996, 0.03601, + 1.0682499999999999, 0.43212, 0.03601, 1.0682499999999999, 0.21606, 0.10803, 1.0682499999999999, 0.25207000000000002, 0.10803, 1.0682499999999999, + 0.32408999999999999, 0.10803, 1.0682499999999999, 0.39610999999999996, 0.10803, 1.0682499999999999, 0.43212, 0.10803, 1.0682499999999999, 0.21606, + 0.18004999999999999, 1.0682499999999999, 0.25207000000000002, 0.18004999999999999, 1.0682499999999999, 0.32408999999999999, 0.18004999999999999, + 1.0682499999999999, 0.39610999999999996, 0.18004999999999999, 1.0682499999999999, 0.43212, 0.18004999999999999, 1.0682499999999999, 0.25207000000000002, + 0.21605999999999997, 1.0682499999999999, 0.32408999999999999, 0.21605999999999997, 1.0682499999999999, 0.39610999999999996, 0.21605999999999997, + 1.0682499999999999, 0.43212, 0.21605999999999997, 1.0682499999999999, 0, 0.21606, 1.0682499999999999, 0.21606, 0.21606, 1.0682499999999999, 0, 0, + 1.2818999999999998, 0.21606, 0, 1.2818999999999998, 0.25207000000000002, 0, 1.2818999999999998, 0.32408999999999999, 0, 1.2818999999999998, 0.39610999999999996, + 0, 1.2818999999999998, 0.43212, 0, 1.2818999999999998, 0.21606, 0.03601, 1.2818999999999998, 0.25207000000000002, 0.03601, 1.2818999999999998, + 0.32408999999999999, 0.03601, 1.2818999999999998, 0.39610999999999996, 0.03601, 1.2818999999999998, 0.43212, 0.03601, 1.2818999999999998, 0.21606, 0.10803, + 1.2818999999999998, 0.25207000000000002, 0.10803, 1.2818999999999998, 0.32408999999999999, 0.10803, 1.2818999999999998, 0.39610999999999996, 0.10803, + 1.2818999999999998, 0.43212, 0.10803, 1.2818999999999998, 0.21606, 0.18004999999999999, 1.2818999999999998, 0.25207000000000002, 0.18004999999999999, + 1.2818999999999998, 0.32408999999999999, 0.18004999999999999, 1.2818999999999998, 0.39610999999999996, 0.18004999999999999, 1.2818999999999998, 0.43212, + 0.18004999999999999, 1.2818999999999998, 0.25207000000000002, 0.21605999999999997, 1.2818999999999998, 0.32408999999999999, 0.21605999999999997, + 1.2818999999999998, 0.39610999999999996, 0.21605999999999997, 1.2818999999999998, 0.43212, 0.21605999999999997, 1.2818999999999998, 0, 0.21606, + 1.2818999999999998, 0.21606, 0.21606, 1.2818999999999998, 0, 0, 1.4955499999999999, 0.21606, 0, 1.4955499999999999, 0.25207000000000002, 0, 1.4955499999999999, + 0.32408999999999999, 0, 1.4955499999999999, 0.39610999999999996, 0, 1.4955499999999999, 0.43212, 0, 1.4955499999999999, 0.21606, 0.03601, 1.4955499999999999, + 0.25207000000000002, 0.03601, 1.4955499999999999, 0.32408999999999999, 0.03601, 1.4955499999999999, 0.39610999999999996, 0.03601, 1.4955499999999999, 0.43212, + 0.03601, 1.4955499999999999,0.21606, 0.10803, 1.4955499999999999, 0.25207000000000002, 0.10803, 1.4955499999999999, 0.32408999999999999, 0.10803, 1.4955499999999999, + 0.39610999999999996, 0.10803, 1.4955499999999999, 0.43212, 0.10803, 1.4955499999999999, 0.21606, 0.18004999999999999, 1.4955499999999999, 0.25207000000000002, + 0.18004999999999999, 1.4955499999999999, 0.32408999999999999, 0.18004999999999999, 1.4955499999999999, 0.39610999999999996, 0.18004999999999999, + 1.4955499999999999, 0.43212, 0.18004999999999999, 1.4955499999999999, 0.25207000000000002, 0.21605999999999997, 1.4955499999999999, 0.32408999999999999, + 0.21605999999999997, 1.4955499999999999, 0.39610999999999996, 0.21605999999999997, 1.4955499999999999, 0.43212, 0.21605999999999997, 1.4955499999999999, 0, + 0.21606, 1.4955499999999999, 0.21606, 0.21606, 1.4955499999999999, 0, 0, 1.7091999999999998, 0.21606, 0, 1.7091999999999998, 0.25207000000000002, 0, + 1.7091999999999998, 0.32408999999999999, 0, 1.7091999999999998, 0.39610999999999996, 0, 1.7091999999999998, 0.43212, 0, 1.7091999999999998, 0.21606, 0.03601, + 1.7091999999999998, 0.25207000000000002, 0.03601, 1.7091999999999998, 0.32408999999999999, 0.03601, 1.7091999999999998, 0.39610999999999996, 0.03601, + 1.7091999999999998, 0.43212, 0.03601, 1.7091999999999998, 0.21606, 0.10803, 1.7091999999999998, 0.25207000000000002, 0.10803, 1.7091999999999998, + 0.32408999999999999, 0.10803, 1.7091999999999998, 0.39610999999999996, 0.10803, 1.7091999999999998, 0.43212, 0.10803, 1.7091999999999998, 0.21606, + 0.18004999999999999, 1.7091999999999998, 0.25207000000000002, 0.18004999999999999, 1.7091999999999998, 0.32408999999999999, 0.18004999999999999, + 1.7091999999999998, 0.39610999999999996, 0.18004999999999999, 1.7091999999999998, 0.43212, 0.18004999999999999, 1.7091999999999998, 0.25207000000000002, + 0.21605999999999997, 1.7091999999999998, 0.32408999999999999, 0.21605999999999997, 1.7091999999999998, 0.39610999999999996, 0.21605999999999997, + 1.7091999999999998, 0.43212, 0.21605999999999997, 1.7091999999999998, 0, 0.21606, 1.7091999999999998, 0.21606, 0.21606, 1.7091999999999998, 0, 0, + 1.9228499999999997, 0.21606, 0, 1.9228499999999997, 0.25207000000000002, 0, 1.9228499999999997, 0.32408999999999999, 0, 1.9228499999999997, 0.39610999999999996, + 0, 1.9228499999999997, 0.43212, 0, 1.9228499999999997, 0.21606, 0.03601, 1.9228499999999997, 0.25207000000000002, 0.03601, 1.9228499999999997, + 0.32408999999999999, 0.03601, 1.9228499999999997, 0.39610999999999996, 0.03601, 1.9228499999999997, 0.43212, 0.03601, 1.9228499999999997, 0.21606, 0.10803, + 1.9228499999999997, 0.25207000000000002, 0.10803, 1.9228499999999997, 0.32408999999999999, 0.10803, 1.9228499999999997, 0.39610999999999996, 0.10803, + 1.9228499999999997, 0.43212, 0.10803, 1.9228499999999997, 0.21606, 0.18004999999999999, 1.9228499999999997, 0.25207000000000002, 0.18004999999999999, + 1.9228499999999997, 0.32408999999999999, 0.18004999999999999, 1.9228499999999997, 0.39610999999999996, 0.18004999999999999, 1.9228499999999997, 0.43212, + 0.18004999999999999, 1.9228499999999997, 0.25207000000000002, 0.21605999999999997, 1.9228499999999997, 0.32408999999999999, 0.21605999999999997, + 1.9228499999999997, 0.39610999999999996, 0.21605999999999997,1.9228499999999997, 0.43212, 0.21605999999999997, 1.9228499999999997, 0, 0.21606, 1.9228499999999997, 0.21606, 0.21606, 1.9228499999999997, 0, 0, + 2.1364999999999998, 0.21606, 0, 2.1364999999999998, 0.25207000000000002, 0, 2.1364999999999998, 0.32408999999999999, 0, 2.1364999999999998, 0.39610999999999996, + 0, 2.1364999999999998, 0.43212, 0, 2.1364999999999998, 0.21606, 0.03601, 2.1364999999999998, 0.25207000000000002, 0.03601, 2.1364999999999998, + 0.32408999999999999, 0.03601, 2.1364999999999998, 0.39610999999999996, 0.03601, 2.1364999999999998, 0.43212, 0.03601, 2.1364999999999998, 0.21606, 0.10803, + 2.1364999999999998, 0.25207000000000002, 0.10803, 2.1364999999999998, 0.32408999999999999, 0.10803, 2.1364999999999998, 0.39610999999999996, 0.10803, + 2.1364999999999998, 0.43212, 0.10803, 2.1364999999999998, 0.21606, 0.18004999999999999, 2.1364999999999998, 0.25207000000000002, 0.18004999999999999, + 2.1364999999999998, 0.32408999999999999, 0.18004999999999999, 2.1364999999999998, 0.39610999999999996, 0.18004999999999999, 2.1364999999999998, 0.43212, + 0.18004999999999999, 2.1364999999999998, 0.25207000000000002, 0.21605999999999997, 2.1364999999999998, 0.32408999999999999, 0.21605999999999997, + 2.1364999999999998, 0.39610999999999996, 0.21605999999999997, 2.1364999999999998, 0.43212, 0.21605999999999997, 2.1364999999999998, 0, 0.21606, + 2.1364999999999998, 0.21606, 0.21606, 2.1364999999999998, 0, 0, 2.3501499999999997, 0.21606, 0, 2.3501499999999997, 0.25207000000000002, 0, 2.3501499999999997, + 0.32408999999999999, 0, 2.3501499999999997, 0.39610999999999996, 0, 2.3501499999999997, 0.43212, 0, 2.3501499999999997, 0.21606, 0.03601, 2.3501499999999997, + 0.25207000000000002, 0.03601, 2.3501499999999997, 0.32408999999999999, 0.03601, 2.3501499999999997, 0.39610999999999996, 0.03601, 2.3501499999999997, 0.43212, + 0.03601, 2.3501499999999997, 0.21606, 0.10803, 2.3501499999999997, 0.25207000000000002, 0.10803, 2.3501499999999997, 0.32408999999999999, 0.10803, + 2.3501499999999997, 0.39610999999999996, 0.10803, 2.3501499999999997, 0.43212, 0.10803, 2.3501499999999997, 0.21606, 0.18004999999999999, 2.3501499999999997, + 0.25207000000000002, 0.18004999999999999, 2.3501499999999997, 0.32408999999999999, 0.18004999999999999, 2.3501499999999997, 0.39610999999999996, + 0.18004999999999999, 2.3501499999999997, 0.43212, 0.18004999999999999, 2.3501499999999997, 0.25207000000000002, 0.21605999999999997, 2.3501499999999997, + 0.32408999999999999, 0.21605999999999997, 2.3501499999999997, 0.39610999999999996, 0.21605999999999997, 2.3501499999999997, 0.43212, 0.21605999999999997, + 2.3501499999999997, 0, 0.21606, 2.3501499999999997, 0.21606, 0.21606, 2.3501499999999997, 0, 0, 2.5637999999999996, 0.21606, 0, 2.5637999999999996, + 0.25207000000000002, 0, 2.5637999999999996, 0.32408999999999999, 0, 2.5637999999999996, 0.39610999999999996, 0, 2.5637999999999996, 0.43212, 0, + 2.5637999999999996, 0.21606, 0.03601, 2.5637999999999996, 0.25207000000000002, 0.03601, 2.5637999999999996, 0.32408999999999999, 0.03601, 2.5637999999999996, + 0.39610999999999996,0.03601, 2.5637999999999996, 0.43212, 0.03601, 2.5637999999999996, 0.21606, 0.10803, 2.5637999999999996, 0.25207000000000002, 0.10803, 2.5637999999999996, + 0.32408999999999999, 0.10803, 2.5637999999999996, 0.39610999999999996, 0.10803, 2.5637999999999996, 0.43212, 0.10803, 2.5637999999999996, 0.21606, + 0.18004999999999999, 2.5637999999999996, 0.25207000000000002, 0.18004999999999999, 2.5637999999999996, 0.32408999999999999, 0.18004999999999999, + 2.5637999999999996, 0.39610999999999996, 0.18004999999999999, 2.5637999999999996, 0.43212, 0.18004999999999999, 2.5637999999999996, 0.25207000000000002, + 0.21605999999999997, 2.5637999999999996, 0.32408999999999999, 0.21605999999999997, 2.5637999999999996, 0.39610999999999996, 0.21605999999999997, + 2.5637999999999996, 0.43212, 0.21605999999999997, 2.5637999999999996, 0, 0.21606, 2.5637999999999996, 0.21606, 0.21606, 2.5637999999999996, 0, 0, + 2.7774499999999995, 0.21606, 0, 2.7774499999999995, 0.25207000000000002, 0, 2.7774499999999995, 0.32408999999999999, 0, 2.7774499999999995, 0.39610999999999996, + 0, 2.7774499999999995, 0.43212, 0, 2.7774499999999995, 0.21606, 0.03601, 2.7774499999999995, 0.25207000000000002, 0.03601, 2.7774499999999995, + 0.32408999999999999, 0.03601, 2.7774499999999995, 0.39610999999999996, 0.03601, 2.7774499999999995, 0.43212, 0.03601, 2.7774499999999995, 0.21606, 0.10803, + 2.7774499999999995, 0.25207000000000002, 0.10803, 2.7774499999999995, 0.32408999999999999, 0.10803, 2.7774499999999995, 0.39610999999999996, 0.10803, + 2.7774499999999995, 0.43212, 0.10803, 2.7774499999999995, 0.21606, 0.18004999999999999, 2.7774499999999995, 0.25207000000000002, 0.18004999999999999, + 2.7774499999999995, 0.32408999999999999, 0.18004999999999999, 2.7774499999999995, 0.39610999999999996, 0.18004999999999999, 2.7774499999999995, 0.43212, + 0.18004999999999999, 2.7774499999999995, 0.25207000000000002, 0.21605999999999997, 2.7774499999999995, 0.32408999999999999, 0.21605999999999997, + 2.7774499999999995, 0.39610999999999996, 0.21605999999999997, 2.7774499999999995, 0.43212, 0.21605999999999997, 2.7774499999999995, 0, 0.21606, + 2.7774499999999995, 0.21606, 0.21606, 2.7774499999999995, 0, 0, 2.9910999999999999, 0.21606, 0, 2.9910999999999999, 0.25207000000000002, 0, 2.9910999999999999, + 0.32408999999999999, 0, 2.9910999999999999, 0.39610999999999996, 0, 2.9910999999999999, 0.43212, 0, 2.9910999999999999, 0.21606, 0.03601, 2.9910999999999999, + 0.25207000000000002, 0.03601, 2.9910999999999999, 0.32408999999999999, 0.03601, 2.9910999999999999, 0.39610999999999996, 0.03601, 2.9910999999999999, 0.43212, + 0.03601, 2.9910999999999999, 0.21606, 0.10803, 2.9910999999999999, 0.25207000000000002, 0.10803, 2.9910999999999999, 0.32408999999999999, 0.10803, + 2.9910999999999999, 0.39610999999999996, 0.10803, 2.9910999999999999, 0.43212, 0.10803, 2.9910999999999999, 0.21606, 0.18004999999999999, 2.9910999999999999, + 0.25207000000000002, 0.18004999999999999, 2.9910999999999999, 0.32408999999999999, 0.18004999999999999, 2.9910999999999999, 0.39610999999999996, + 0.18004999999999999, 2.9910999999999999, 0.43212, 0.18004999999999999, 2.9910999999999999, 0.25207000000000002, 0.21605999999999997, 2.9910999999999999, + 0.32408999999999999, 0.21605999999999997, 2.9910999999999999, 0.39610999999999996, 0.21605999999999997, 2.9910999999999999, 0.43212, 0.21605999999999997, + 2.9910999999999999, 0, 0.21606, 2.9910999999999999, 0.21606, 0.21606, 2.9910999999999999, 0, 0, 3.2047499999999998, 0.21606, 0, 3.2047499999999998, + 0.25207000000000002, 0, 3.2047499999999998, 0.32408999999999999, 0, 3.2047499999999998, 0.39610999999999996, 0, 3.2047499999999998, 0.43212, 0, + 3.2047499999999998, 0.21606, 0.03601, 3.2047499999999998, 0.25207000000000002, 0.03601, 3.2047499999999998, 0.32408999999999999, 0.03601, 3.2047499999999998, + 0.39610999999999996, 0.03601, 3.2047499999999998, 0.43212, 0.03601, 3.2047499999999998, 0.21606, 0.10803, 3.2047499999999998, 0.25207000000000002, 0.10803, + 3.2047499999999998, 0.32408999999999999, 0.10803, 3.2047499999999998, 0.39610999999999996, 0.10803, 3.2047499999999998, 0.43212, 0.10803, 3.2047499999999998, + 0.21606, 0.18004999999999999, 3.2047499999999998, 0.25207000000000002, 0.18004999999999999, 3.2047499999999998, 0.32408999999999999, 0.18004999999999999, + 3.2047499999999998, 0.39610999999999996, 0.18004999999999999, 3.2047499999999998, 0.43212, 0.18004999999999999, 3.2047499999999998, 0.25207000000000002, + 0.21605999999999997, 3.2047499999999998, 0.32408999999999999, 0.21605999999999997, 3.2047499999999998, 0.39610999999999996, 0.21605999999999997, + 3.2047499999999998, 0.43212, 0.21605999999999997, 3.2047499999999998, 0, 0.21606, 3.2047499999999998, 0.21606, 0.21606, 3.2047499999999998, 0, 0, + 3.4183999999999997, 0.21606, 0, 3.4183999999999997, 0.25207000000000002, 0, 3.4183999999999997, 0.32408999999999999, 0, 3.4183999999999997, 0.39610999999999996, + 0, 3.4183999999999997, 0.43212, 0, 3.4183999999999997, 0.21606, 0.03601, 3.4183999999999997, 0.25207000000000002, 0.03601, 3.4183999999999997, + 0.32408999999999999, 0.03601, 3.4183999999999997, 0.39610999999999996, 0.03601, 3.4183999999999997, 0.43212, 0.03601, 3.4183999999999997, 0.21606, 0.10803, + 3.4183999999999997, 0.25207000000000002, 0.10803, 3.4183999999999997, 0.32408999999999999, 0.10803, 3.4183999999999997, 0.39610999999999996, 0.10803, + 3.4183999999999997, 0.43212, 0.10803, 3.4183999999999997, 0.21606, 0.18004999999999999, 3.4183999999999997, 0.25207000000000002, 0.18004999999999999, + 3.4183999999999997, 0.32408999999999999, 0.18004999999999999, 3.4183999999999997, 0.39610999999999996, 0.18004999999999999, 3.4183999999999997, 0.43212, + 0.18004999999999999, 3.4183999999999997, 0.25207000000000002, 0.21605999999999997, 3.4183999999999997, 0.32408999999999999, 0.21605999999999997, + 3.4183999999999997, 0.39610999999999996, 0.21605999999999997, 3.4183999999999997, 0.43212, 0.21605999999999997, 3.4183999999999997, 0, 0.21606, + 3.4183999999999997, 0.21606, 0.21606, 3.4183999999999997, 0, 0, 3.6320499999999996, 0.21606, 0, 3.6320499999999996, 0.25207000000000002, 0, 3.6320499999999996, + 0.32408999999999999, 0, 3.6320499999999996, 0.39610999999999996, 0, 3.6320499999999996, 0.43212, 0, 3.6320499999999996, 0.21606, 0.03601, 3.6320499999999996, + 0.25207000000000002, 0.03601, 3.6320499999999996, 0.32408999999999999, 0.03601, 3.6320499999999996, 0.39610999999999996, 0.03601, 3.6320499999999996, 0.43212, 0.03601, + 3.6320499999999996, 0.21606, 0.10803, 3.6320499999999996, 0.25207000000000002, 0.10803, 3.6320499999999996, 0.32408999999999999, 0.10803, 3.6320499999999996, + 0.39610999999999996, 0.10803, 3.6320499999999996, 0.43212, 0.10803, 3.6320499999999996, 0.21606, 0.18004999999999999, 3.6320499999999996, 0.25207000000000002, + 0.18004999999999999, 3.6320499999999996, 0.32408999999999999, 0.18004999999999999, 3.6320499999999996, 0.39610999999999996, 0.18004999999999999, + 3.6320499999999996, 0.43212, 0.18004999999999999, 3.6320499999999996, 0.25207000000000002, 0.21605999999999997, 3.6320499999999996, 0.32408999999999999, + 0.21605999999999997, 3.6320499999999996, 0.39610999999999996, 0.21605999999999997, 3.6320499999999996, 0.43212, 0.21605999999999997, 3.6320499999999996, 0, + 0.21606, 3.6320499999999996, 0.21606, 0.21606, 3.6320499999999996, 0, 0, 3.8456999999999995, 0.21606, 0, 3.8456999999999995, 0.25207000000000002, 0, + 3.8456999999999995, 0.32408999999999999, 0, 3.8456999999999995, 0.39610999999999996, 0, 3.8456999999999995, 0.43212, 0, 3.8456999999999995, 0.21606, 0.03601, + 3.8456999999999995, 0.25207000000000002, 0.03601, 3.8456999999999995, 0.32408999999999999, 0.03601, 3.8456999999999995, 0.39610999999999996, 0.03601, + 3.8456999999999995, 0.43212, 0.03601, 3.8456999999999995, 0.21606, 0.10803, 3.8456999999999995, 0.25207000000000002, 0.10803, 3.8456999999999995, + 0.32408999999999999, 0.10803, 3.8456999999999995, 0.39610999999999996, 0.10803, 3.8456999999999995, 0.43212, 0.10803, 3.8456999999999995, 0.21606, + 0.18004999999999999, 3.8456999999999995, 0.25207000000000002, 0.18004999999999999, 3.8456999999999995, 0.32408999999999999, 0.18004999999999999, + 3.8456999999999995, 0.39610999999999996, 0.18004999999999999, 3.8456999999999995, 0.43212, 0.18004999999999999, 3.8456999999999995, 0.25207000000000002, + 0.21605999999999997, 3.8456999999999995, 0.32408999999999999, 0.21605999999999997, 3.8456999999999995, 0.39610999999999996, 0.21605999999999997, + 3.8456999999999995, 0.43212, 0.21605999999999997, 3.8456999999999995, 0, 0.21606, 3.8456999999999995, 0.21606, 0.21606, 3.8456999999999995, 0, 0, + 4.0593499999999993, 0.21606, 0, 4.0593499999999993, 0.25207000000000002, 0, 4.0593499999999993, 0.32408999999999999, 0, 4.0593499999999993, 0.39610999999999996, + 0, 4.0593499999999993, 0.43212, 0, 4.0593499999999993, 0.21606, 0.03601, 4.0593499999999993, 0.25207000000000002, 0.03601, 4.0593499999999993, + 0.32408999999999999, 0.03601, 4.0593499999999993, 0.39610999999999996, 0.03601, 4.0593499999999993, 0.43212, 0.03601, 4.0593499999999993, 0.21606, 0.10803, + 4.0593499999999993, 0.25207000000000002, 0.10803, 4.0593499999999993, 0.32408999999999999, 0.10803, 4.0593499999999993, 0.39610999999999996, 0.10803, + 4.0593499999999993, 0.43212, 0.10803, 4.0593499999999993, 0.21606, 0.18004999999999999, 4.0593499999999993, 0.25207000000000002, 0.18004999999999999, + 4.0593499999999993, 0.32408999999999999, 0.18004999999999999, 4.0593499999999993, 0.39610999999999996, 0.18004999999999999, 4.0593499999999993, 0.43212, + 0.18004999999999999, 4.0593499999999993, 0.25207000000000002, 0.21605999999999997, 4.0593499999999993, 0.32408999999999999, 0.21605999999999997, + 4.0593499999999993, 0.39610999999999996, 0.21605999999999997, 4.0593499999999993, 0.43212, 0.21605999999999997, 4.0593499999999993, 0, 0.21606, + 4.0593499999999993, 0.21606, 0.21606, 4.0593499999999993, 0, 0, 4.2729999999999997, 0.21606, 0, 4.2729999999999997, 0.25207000000000002, 0, 4.2729999999999997, + 0.32408999999999999, 0, 4.2729999999999997, 0.39610999999999996, 0, 4.2729999999999997, 0.43212, 0, 4.2729999999999997, 0.21606, 0.03601, 4.2729999999999997, + 0.25207000000000002, 0.03601, 4.2729999999999997, 0.32408999999999999, 0.03601, 4.2729999999999997, 0.39610999999999996, 0.03601, 4.2729999999999997, 0.43212, + 0.03601, 4.2729999999999997, 0.21606, 0.10803, 4.2729999999999997, 0.25207000000000002, 0.10803, 4.2729999999999997, 0.32408999999999999, 0.10803, + 4.2729999999999997, 0.39610999999999996, 0.10803, 4.2729999999999997, 0.43212, 0.10803, 4.2729999999999997, 0.21606, 0.18004999999999999, 4.2729999999999997, + 0.25207000000000002, 0.18004999999999999, 4.2729999999999997, 0.32408999999999999, 0.18004999999999999, 4.2729999999999997, 0.39610999999999996, + 0.18004999999999999, 4.2729999999999997, 0.43212, 0.18004999999999999, 4.2729999999999997, 0.25207000000000002, 0.21605999999999997, 4.2729999999999997, + 0.32408999999999999, 0.21605999999999997, 4.2729999999999997, 0.39610999999999996, 0.21605999999999997, 4.2729999999999997, 0.43212, 0.21605999999999997, + 4.2729999999999997, 0, 0.21606, 4.2729999999999997, 0.21606, 0.21606, 4.2729999999999997 +}; + +const int connTFPOLH_I[21]={0, 50, 100, 150, 200, 250, 300, 350, 400, 450, 500, 550, 600, 650, 700, 750, 800, 850, 900, 950, 1000}; diff --git a/src/medtool/src/MEDCoupling/Test/MEDCouplingBasicsTestInterp.cxx b/src/medtool/src/MEDCoupling/Test/MEDCouplingBasicsTestInterp.cxx new file mode 100644 index 000000000..f50b74de9 --- /dev/null +++ b/src/medtool/src/MEDCoupling/Test/MEDCouplingBasicsTestInterp.cxx @@ -0,0 +1,2694 @@ +// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 +// 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 "MEDCouplingBasicsTestInterp.hxx" +#include "MEDCouplingUMesh.hxx" +#include "MEDCouplingExtrudedMesh.hxx" +#include "MEDCouplingFieldDouble.hxx" +#include "MEDCouplingMemArray.hxx" +#include "Interpolation2D.txx" +#include "Interpolation3DSurf.hxx" +#include "Interpolation3D.txx" +#include "Interpolation2D1D.txx" +#include "Interpolation3D2D.txx" +#include "InterpolationCC.txx" +#include "InterpolationCU.txx" +#include "Interpolation2DCurve.hxx" +#include "Interpolation1D.txx" + +#include "MEDCouplingNormalizedUnstructuredMesh.txx" +#include "MEDCouplingNormalizedCartesianMesh.txx" + +#include <cmath> +#include <functional> + +using namespace ParaMEDMEM; + +typedef std::vector<std::map<int,double> > IntersectionMatrix; + +void MEDCouplingBasicsTestInterp::test2DInterpP0P0_1() +{ + MEDCouplingUMesh *sourceMesh=build2DSourceMesh_1(); + MEDCouplingUMesh *targetMesh=build2DTargetMesh_1(); + // + MEDCouplingNormalizedUnstructuredMesh<2,2> sourceWrapper(sourceMesh); + MEDCouplingNormalizedUnstructuredMesh<2,2> targetWrapper(targetMesh); + INTERP_KERNEL::Interpolation2D myInterpolator; + std::vector<std::map<int,double> > res; + INTERP_KERNEL::IntersectionType types[3]={INTERP_KERNEL::Triangulation, INTERP_KERNEL::Convex, INTERP_KERNEL::Geometric2D}; + for(int i=0;i<3;i++) + { + myInterpolator.setPrecision(1e-12); + myInterpolator.setIntersectionType(types[i]); + myInterpolator.interpolateMeshes(sourceWrapper,targetWrapper,res,"P0P0"); + CPPUNIT_ASSERT_EQUAL(5,(int)res.size()); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.125,res[0][0],1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.125,res[0][1],1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.125,res[1][0],1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.125,res[2][0],1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.25,res[3][1],1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.125,res[4][0],1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.125,res[4][1],1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,sumAll(res),1e-12); + res.clear(); + } + //clean up + sourceMesh->decrRef(); + targetMesh->decrRef(); +} + +void MEDCouplingBasicsTestInterp::test2DInterpP0P0PL_1() +{ + MEDCouplingUMesh *sourceMesh=build2DSourceMesh_1(); + MEDCouplingUMesh *targetMesh=build2DTargetMesh_1(); + // + MEDCouplingNormalizedUnstructuredMesh<2,2> sourceWrapper(sourceMesh); + MEDCouplingNormalizedUnstructuredMesh<2,2> targetWrapper(targetMesh); + INTERP_KERNEL::Interpolation2D myInterpolator; + std::vector<std::map<int,double> > res; + // + myInterpolator.setIntersectionType(INTERP_KERNEL::PointLocator); + myInterpolator.interpolateMeshes(sourceWrapper,targetWrapper,res,"P0P0"); + CPPUNIT_ASSERT_EQUAL(5,(int)res.size()); + CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[0][0],1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[0][1],1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[1][0],1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[2][0],1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[3][1],1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[4][0],1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[4][1],1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(7.,sumAll(res),1e-12); + // + sourceMesh->decrRef(); + targetMesh->decrRef(); +} + +void MEDCouplingBasicsTestInterp::test2DInterpP0P0PL_2() +{ + MEDCouplingUMesh *sourceMesh=build2DSourceMesh_1(); + MEDCouplingUMesh *targetMesh=build2DTargetMesh_1(); + // + std::vector<int> cellsIds(targetMesh->getNumberOfCells()); + for(int i=0;i<targetMesh->getNumberOfCells();i++) + cellsIds[i]=i; + targetMesh->convertToPolyTypes(&cellsIds[0],&cellsIds[0]+cellsIds.size()); + // + MEDCouplingNormalizedUnstructuredMesh<2,2> sourceWrapper(sourceMesh); + MEDCouplingNormalizedUnstructuredMesh<2,2> targetWrapper(targetMesh); + INTERP_KERNEL::Interpolation2D myInterpolator; + std::vector<std::map<int,double> > res; + // + myInterpolator.setIntersectionType(INTERP_KERNEL::PointLocator); + myInterpolator.interpolateMeshes(sourceWrapper,targetWrapper,res,"P0P0"); + CPPUNIT_ASSERT_EQUAL(5,(int)res.size()); + CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[0][0],1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[0][1],1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[1][0],1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[2][0],1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[3][1],1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[4][0],1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[4][1],1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(7.,sumAll(res),1e-12); + // + sourceMesh->decrRef(); + targetMesh->decrRef(); +} + +void MEDCouplingBasicsTestInterp::test2DInterpP0P0PL_3() +{ + MEDCouplingUMesh *sourceMesh=build2DSourceMesh_1(); + MEDCouplingUMesh *targetMesh=build2DTargetMesh_1(); + // + std::vector<int> cellsIds(sourceMesh->getNumberOfCells()); + for(int i=0;i<sourceMesh->getNumberOfCells();i++) + cellsIds[i]=i; + sourceMesh->convertToPolyTypes(&cellsIds[0],&cellsIds[0]+cellsIds.size()); + // + MEDCouplingNormalizedUnstructuredMesh<2,2> sourceWrapper(sourceMesh); + MEDCouplingNormalizedUnstructuredMesh<2,2> targetWrapper(targetMesh); + INTERP_KERNEL::Interpolation2D myInterpolator; + std::vector<std::map<int,double> > res; + // + myInterpolator.setIntersectionType(INTERP_KERNEL::PointLocator); + myInterpolator.interpolateMeshes(sourceWrapper,targetWrapper,res,"P0P0"); + CPPUNIT_ASSERT_EQUAL(5,(int)res.size()); + CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[0][0],1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[0][1],1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[1][0],1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[2][0],1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[3][1],1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[4][0],1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[4][1],1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(7.,sumAll(res),1e-12); + // + sourceMesh->decrRef(); + targetMesh->decrRef(); +} + +void MEDCouplingBasicsTestInterp::test2DInterpP0P0PL_4() +{ + MEDCouplingUMesh *sourceMesh=build2DSourceMesh_1(); + MEDCouplingUMesh *targetMesh=build2DTargetMesh_1(); + // + std::vector<int> cellsIds(sourceMesh->getNumberOfCells()); + for(int i=0;i<sourceMesh->getNumberOfCells();i++) + cellsIds[i]=i; + sourceMesh->convertToPolyTypes(&cellsIds[0],&cellsIds[0]+cellsIds.size()); + cellsIds.resize(targetMesh->getNumberOfCells()); + for(int i=0;i<targetMesh->getNumberOfCells();i++) + cellsIds[i]=i; + targetMesh->convertToPolyTypes(&cellsIds[0],&cellsIds[0]+cellsIds.size()); + // + MEDCouplingNormalizedUnstructuredMesh<2,2> sourceWrapper(sourceMesh); + MEDCouplingNormalizedUnstructuredMesh<2,2> targetWrapper(targetMesh); + INTERP_KERNEL::Interpolation2D myInterpolator; + std::vector<std::map<int,double> > res; + // + myInterpolator.setIntersectionType(INTERP_KERNEL::PointLocator); + myInterpolator.interpolateMeshes(sourceWrapper,targetWrapper,res,"P0P0"); + CPPUNIT_ASSERT_EQUAL(5,(int)res.size()); + CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[0][0],1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[0][1],1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[1][0],1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[2][0],1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[3][1],1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[4][0],1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[4][1],1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(7.,sumAll(res),1e-12); + // + sourceMesh->decrRef(); + targetMesh->decrRef(); +} + +void MEDCouplingBasicsTestInterp::test2DInterpP0P1_1() +{ + MEDCouplingUMesh *sourceMesh=build2DSourceMesh_1(); + MEDCouplingUMesh *targetMesh=build2DTargetMesh_1(); + // + MEDCouplingNormalizedUnstructuredMesh<2,2> sourceWrapper(sourceMesh); + MEDCouplingNormalizedUnstructuredMesh<2,2> targetWrapper(targetMesh); + INTERP_KERNEL::Interpolation2D myInterpolator; + std::vector<std::map<int,double> > res; + INTERP_KERNEL::IntersectionType types[2]={INTERP_KERNEL::Triangulation, INTERP_KERNEL::Geometric2D}; + for(int i=0;i<2;i++) + { + myInterpolator.setPrecision(1e-12); + myInterpolator.setIntersectionType(types[i]); + myInterpolator.interpolateMeshes(sourceWrapper,targetWrapper,res,"P0P1"); + CPPUNIT_ASSERT_EQUAL(9,(int)res.size()); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.041666666666666664,res[0][0],1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.041666666666666664,res[0][1],1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.125,res[1][0],1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.083333333333333329,res[2][0],1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.16666666666666666,res[3][1],1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.16666666666666666,res[4][0],1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.16666666666666666,res[4][1],1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.125,res[5][0],1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.083333333333333329,res[6][1],1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.16666666666666666,res[7][1],1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.041666666666666664,res[8][0],1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.041666666666666664,res[8][1],1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(1.25,sumAll(res),1e-12); + res.clear(); + } + //clean up + sourceMesh->decrRef(); + targetMesh->decrRef(); +} + +void MEDCouplingBasicsTestInterp::test2DInterpP0P1PL_1() +{ + MEDCouplingUMesh *sourceMesh=build2DSourceMesh_1(); + MEDCouplingUMesh *targetMesh=build2DTargetMesh_1(); + // + MEDCouplingNormalizedUnstructuredMesh<2,2> sourceWrapper(sourceMesh); + MEDCouplingNormalizedUnstructuredMesh<2,2> targetWrapper(targetMesh); + INTERP_KERNEL::Interpolation2D myInterpolator; + std::vector<std::map<int,double> > res; + myInterpolator.setPrecision(1e-12); + myInterpolator.setIntersectionType(INTERP_KERNEL::PointLocator); + myInterpolator.interpolateMeshes(sourceWrapper,targetWrapper,res,"P0P1"); + CPPUNIT_ASSERT_EQUAL(9,(int)res.size()); + CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[0][0],1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[0][1],1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[1][0],1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[2][0],1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[3][1],1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[4][0],1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[4][1],1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[5][0],1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[6][1],1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[7][1],1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[8][0],1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[8][1],1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(12.,sumAll(res),1e-12); + res.clear(); + //clean up + sourceMesh->decrRef(); + targetMesh->decrRef(); +} + +void MEDCouplingBasicsTestInterp::test2DInterpP0P1PL_2() +{ + MEDCouplingUMesh *sourceMesh=build2DSourceMesh_1(); + MEDCouplingUMesh *targetMesh=build2DTargetMesh_1(); + // + std::vector<int> cellsIds(sourceMesh->getNumberOfCells()); + for(int i=0;i<sourceMesh->getNumberOfCells();i++) + cellsIds[i]=i; + sourceMesh->convertToPolyTypes(&cellsIds[0],&cellsIds[0]+cellsIds.size()); + // + cellsIds.resize(targetMesh->getNumberOfCells()); + for(int i=0;i<targetMesh->getNumberOfCells();i++) + cellsIds[i]=i; + targetMesh->convertToPolyTypes(&cellsIds[0],&cellsIds[0]+cellsIds.size()); + // + MEDCouplingNormalizedUnstructuredMesh<2,2> sourceWrapper(sourceMesh); + MEDCouplingNormalizedUnstructuredMesh<2,2> targetWrapper(targetMesh); + INTERP_KERNEL::Interpolation2D myInterpolator; + std::vector<std::map<int,double> > res; + myInterpolator.setPrecision(1e-12); + myInterpolator.setIntersectionType(INTERP_KERNEL::PointLocator); + myInterpolator.interpolateMeshes(sourceWrapper,targetWrapper,res,"P0P1"); + CPPUNIT_ASSERT_EQUAL(9,(int)res.size()); + CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[0][0],1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[0][1],1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[1][0],1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[2][0],1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[3][1],1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[4][0],1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[4][1],1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[5][0],1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[6][1],1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[7][1],1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[8][0],1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[8][1],1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(12.,sumAll(res),1e-12); + res.clear(); + //clean up + sourceMesh->decrRef(); + targetMesh->decrRef(); +} + +void MEDCouplingBasicsTestInterp::test2DInterpP1P0_1() +{ + MEDCouplingUMesh *sourceMesh=build2DSourceMesh_1(); + MEDCouplingUMesh *targetMesh=build2DTargetMesh_1(); + // + MEDCouplingNormalizedUnstructuredMesh<2,2> sourceWrapper(sourceMesh); + MEDCouplingNormalizedUnstructuredMesh<2,2> targetWrapper(targetMesh); + INTERP_KERNEL::Interpolation2D myInterpolator; + std::vector<std::map<int,double> > res; + INTERP_KERNEL::IntersectionType types[2]={INTERP_KERNEL::Triangulation, INTERP_KERNEL::Geometric2D}; + for(int i=0;i<2;i++) + { + myInterpolator.setPrecision(1e-12); + myInterpolator.setIntersectionType(types[i]); + myInterpolator.interpolateMeshes(sourceWrapper,targetWrapper,res,"P1P0"); + CPPUNIT_ASSERT_EQUAL(5,(int)res.size()); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.25,res[0][0],1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.041666666666666664,res[1][0],1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.041666666666666664,res[3][0],1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.083333333333333333,res[1][1],1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.083333333333333333,res[2][1],1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.166666666666666667,res[3][2],1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.041666666666666664,res[2][3],1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.041666666666666664,res[3][3],1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.25,res[4][3],1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,sumAll(res),1e-12); + res.clear(); + } + //clean up + sourceMesh->decrRef(); + targetMesh->decrRef(); +} + +void MEDCouplingBasicsTestInterp::test2DInterpP1P0PL_1() +{ + MEDCouplingUMesh *sourceMesh=build2DSourceMesh_1(); + MEDCouplingUMesh *targetMesh=build2DTargetMesh_1(); + // + MEDCouplingNormalizedUnstructuredMesh<2,2> sourceWrapper(sourceMesh); + MEDCouplingNormalizedUnstructuredMesh<2,2> targetWrapper(targetMesh); + INTERP_KERNEL::Interpolation2D myInterpolator; + std::vector<std::map<int,double> > res; + myInterpolator.setPrecision(1e-12); + myInterpolator.setIntersectionType(INTERP_KERNEL::PointLocator); + myInterpolator.interpolateMeshes(sourceWrapper,targetWrapper,res,"P1P0"); + CPPUNIT_ASSERT_EQUAL(5,(int)res.size()); + CPPUNIT_ASSERT_DOUBLES_EQUAL(1.5,res[0][0],1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.,res[0][1],1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.,res[0][2],1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.5,res[0][3],1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.333333333333333333,res[1][0],1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.5,res[1][1],1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.166666666666666666,res[1][3],1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.166666666666666666,res[2][0],1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.5,res[2][1],1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.333333333333333333,res[2][3],1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.25,res[3][0],1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.5,res[3][2],1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.25,res[3][3],1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.5,res[4][0],1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.,res[4][1],1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.,res[4][2],1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(1.5,res[4][3],1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(7.,sumAll(res),1e-12); + res.clear(); + //clean up + sourceMesh->decrRef(); + targetMesh->decrRef(); +} + +void MEDCouplingBasicsTestInterp::test2DInterpP1P0PL_2() +{ + MEDCouplingUMesh *sourceMesh=build2DSourceMesh_1(); + MEDCouplingUMesh *targetMesh=build2DTargetMesh_1(); + // + std::vector<int >cellsIds(targetMesh->getNumberOfCells()); + for(int i=0;i<targetMesh->getNumberOfCells();i++) + cellsIds[i]=i; + targetMesh->convertToPolyTypes(&cellsIds[0],&cellsIds[0]+cellsIds.size()); + // + MEDCouplingNormalizedUnstructuredMesh<2,2> sourceWrapper(sourceMesh); + MEDCouplingNormalizedUnstructuredMesh<2,2> targetWrapper(targetMesh); + INTERP_KERNEL::Interpolation2D myInterpolator; + std::vector<std::map<int,double> > res; + myInterpolator.setPrecision(1e-12); + myInterpolator.setIntersectionType(INTERP_KERNEL::PointLocator); + myInterpolator.interpolateMeshes(sourceWrapper,targetWrapper,res,"P1P0"); + CPPUNIT_ASSERT_EQUAL(5,(int)res.size()); + CPPUNIT_ASSERT_DOUBLES_EQUAL(1.5,res[0][0],1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.,res[0][1],1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.,res[0][2],1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.5,res[0][3],1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.333333333333333333,res[1][0],1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.5,res[1][1],1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.166666666666666666,res[1][3],1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.166666666666666666,res[2][0],1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.5,res[2][1],1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.333333333333333333,res[2][3],1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.25,res[3][0],1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.5,res[3][2],1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.25,res[3][3],1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.5,res[4][0],1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.,res[4][1],1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.,res[4][2],1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(1.5,res[4][3],1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(7.,sumAll(res),1e-12); + res.clear(); + //clean up + sourceMesh->decrRef(); + targetMesh->decrRef(); +} + +void MEDCouplingBasicsTestInterp::test2DInterpP1P1_1() +{ + MEDCouplingUMesh *sourceMesh=build2DSourceMesh_1(); + MEDCouplingUMesh *targetMesh=build2DTargetMesh_2(); + // + MEDCouplingNormalizedUnstructuredMesh<2,2> sourceWrapper(sourceMesh); + MEDCouplingNormalizedUnstructuredMesh<2,2> targetWrapper(targetMesh); + INTERP_KERNEL::Interpolation2D myInterpolator; + std::vector<std::map<int,double> > res; + INTERP_KERNEL::IntersectionType types[2]={INTERP_KERNEL::Triangulation, INTERP_KERNEL::Geometric2D}; + for(int i=0;i<2;i++) + { + myInterpolator.setPrecision(1e-12); + myInterpolator.setIntersectionType(types[i]); + myInterpolator.interpolateMeshes(sourceWrapper,targetWrapper,res,"P1P1"); + CPPUNIT_ASSERT_EQUAL(9,(int)res.size()); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.08333333333333334,res[0][0],1.e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.05416666666666665,res[1][0],1.e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.02916666666666666,res[1][1],1.e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.08333333333333334,res[2][1],1.e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.05416666666666665,res[3][0],1.e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.02916666666666668,res[3][2],1.e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.1416666666666666,res[4][0],1.e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.02499999999999999,res[4][1],1.e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.02499999999999999,res[4][2],1.e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.09999999999999999,res[4][3],1.e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.02916666666666666,res[5][1],1.e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.09583333333333333,res[5][3],1.e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.08333333333333333,res[6][2],1.e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.02916666666666667,res[7][2],1.e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.09583333333333331,res[7][3],1.e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.04166666666666668,res[8][3],1.e-12); + res.clear(); + } + //clean up + sourceMesh->decrRef(); + targetMesh->decrRef(); +} + +void MEDCouplingBasicsTestInterp::test2DInterpP1P1PL_1() +{ + MEDCouplingUMesh *sourceMesh=build2DSourceMesh_1(); + MEDCouplingUMesh *targetMesh=build2DTargetMesh_1(); + // + MEDCouplingNormalizedUnstructuredMesh<2,2> sourceWrapper(sourceMesh); + MEDCouplingNormalizedUnstructuredMesh<2,2> targetWrapper(targetMesh); + INTERP_KERNEL::Interpolation2D myInterpolator; + std::vector<std::map<int,double> > res; + myInterpolator.setPrecision(1e-12); + myInterpolator.setIntersectionType(INTERP_KERNEL::PointLocator); + myInterpolator.interpolateMeshes(sourceWrapper,targetWrapper,res,"P1P1"); + CPPUNIT_ASSERT_EQUAL(9,(int)res.size()); + CPPUNIT_ASSERT_DOUBLES_EQUAL(2.,res[0][0],1.e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[1][0],1.e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[1][1],1.e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(2.,res[2][1],1.e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[3][0],1.e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[3][2],1.e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(5.,res[4][0],1.e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(5.,res[4][3],1.e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[5][1],1.e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[5][3],1.e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[6][2],1.e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[7][2],1.e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[7][3],1.e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(2.,res[8][3],1.e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(25.,sumAll(res),1e-12); + res.clear(); + //clean up + sourceMesh->decrRef(); + targetMesh->decrRef(); +} + +void MEDCouplingBasicsTestInterp::test3DSurfInterpP0P0_1() +{ + MEDCouplingUMesh *sourceMesh=build3DSurfSourceMesh_1(); + MEDCouplingUMesh *targetMesh=build3DSurfTargetMesh_1(); + // + MEDCouplingNormalizedUnstructuredMesh<3,2> sourceWrapper(sourceMesh); + MEDCouplingNormalizedUnstructuredMesh<3,2> targetWrapper(targetMesh); + INTERP_KERNEL::Interpolation3DSurf myInterpolator; + std::vector<std::map<int,double> > res; + INTERP_KERNEL::IntersectionType types[3]={INTERP_KERNEL::Triangulation, INTERP_KERNEL::Geometric2D}; + for(int i=0;i<2;i++) + { + myInterpolator.setPrecision(1e-12); + myInterpolator.setIntersectionType(types[i]); + myInterpolator.interpolateMeshes(sourceWrapper,targetWrapper,res,"P0P0"); + CPPUNIT_ASSERT_EQUAL(5,(int)res.size()); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.125*sqrt(2.),res[0][0],1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.125*sqrt(2.),res[0][1],1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.125*sqrt(2.),res[1][0],1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.125*sqrt(2.),res[2][0],1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.25*sqrt(2.),res[3][1],1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.125*sqrt(2.),res[4][0],1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.125*sqrt(2.),res[4][1],1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(1.*sqrt(2.),sumAll(res),1e-12); + res.clear(); + } + //clean up + sourceMesh->decrRef(); + targetMesh->decrRef(); +} + +void MEDCouplingBasicsTestInterp::test3DSurfInterpP0P0PL_1() +{ + MEDCouplingUMesh *sourceMesh=build3DSurfSourceMesh_1(); + MEDCouplingUMesh *targetMesh=build3DSurfTargetMesh_1(); + // + MEDCouplingNormalizedUnstructuredMesh<3,2> sourceWrapper(sourceMesh); + MEDCouplingNormalizedUnstructuredMesh<3,2> targetWrapper(targetMesh); + INTERP_KERNEL::Interpolation3DSurf myInterpolator; + std::vector<std::map<int,double> > res; + myInterpolator.setPrecision(1e-12); + myInterpolator.setIntersectionType(INTERP_KERNEL::PointLocator); + myInterpolator.interpolateMeshes(sourceWrapper,targetWrapper,res,"P0P0"); + CPPUNIT_ASSERT_EQUAL(5,(int)res.size()); + CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[0][0],1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[0][1],1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[1][0],1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[2][0],1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[3][1],1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[4][0],1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[4][1],1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(7.,sumAll(res),1e-12); + res.clear(); + //clean up + sourceMesh->decrRef(); + targetMesh->decrRef(); +} + +void MEDCouplingBasicsTestInterp::test3DSurfInterpP0P1_1() +{ + MEDCouplingUMesh *sourceMesh=build3DSurfSourceMesh_1(); + MEDCouplingUMesh *targetMesh=build3DSurfTargetMesh_1(); + // + MEDCouplingNormalizedUnstructuredMesh<3,2> sourceWrapper(sourceMesh); + MEDCouplingNormalizedUnstructuredMesh<3,2> targetWrapper(targetMesh); + INTERP_KERNEL::Interpolation3DSurf myInterpolator; + std::vector<std::map<int,double> > res; + INTERP_KERNEL::IntersectionType types[2]={INTERP_KERNEL::Triangulation, INTERP_KERNEL::Geometric2D}; + for(int i=0;i<2;i++) + { + myInterpolator.setPrecision(1e-12); + myInterpolator.setIntersectionType(types[i]); + myInterpolator.interpolateMeshes(sourceWrapper,targetWrapper,res,"P0P1"); + CPPUNIT_ASSERT_EQUAL(9,(int)res.size()); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.041666666666666664*sqrt(2.),res[0][0],1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.041666666666666664*sqrt(2.),res[0][1],1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.125*sqrt(2.),res[1][0],1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.083333333333333329*sqrt(2.),res[2][0],1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.16666666666666666*sqrt(2.),res[3][1],1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.16666666666666666*sqrt(2.),res[4][0],1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.16666666666666666*sqrt(2.),res[4][1],1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.125*sqrt(2.),res[5][0],1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.083333333333333329*sqrt(2.),res[6][1],1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.16666666666666666*sqrt(2.),res[7][1],1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.041666666666666664*sqrt(2.),res[8][0],1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.041666666666666664*sqrt(2.),res[8][1],1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(1.25*sqrt(2.),sumAll(res),1e-12); + res.clear(); + } + //clean up + sourceMesh->decrRef(); + targetMesh->decrRef(); +} + +void MEDCouplingBasicsTestInterp::test3DSurfInterpP0P1PL_1() +{ + MEDCouplingUMesh *sourceMesh=build3DSurfSourceMesh_1(); + MEDCouplingUMesh *targetMesh=build3DSurfTargetMesh_1(); + // + MEDCouplingNormalizedUnstructuredMesh<3,2> sourceWrapper(sourceMesh); + MEDCouplingNormalizedUnstructuredMesh<3,2> targetWrapper(targetMesh); + INTERP_KERNEL::Interpolation3DSurf myInterpolator; + std::vector<std::map<int,double> > res; + myInterpolator.setPrecision(1e-12); + myInterpolator.setIntersectionType(INTERP_KERNEL::PointLocator); + myInterpolator.interpolateMeshes(sourceWrapper,targetWrapper,res,"P0P1"); + CPPUNIT_ASSERT_EQUAL(9,(int)res.size()); + CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[0][0],1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[0][1],1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[1][0],1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[2][0],1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[3][1],1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[4][0],1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[4][1],1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[5][0],1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[6][1],1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[7][1],1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[8][0],1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[8][1],1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(12.,sumAll(res),1e-12); + res.clear(); + //clean up + sourceMesh->decrRef(); + targetMesh->decrRef(); +} + +void MEDCouplingBasicsTestInterp::test3DSurfInterpP1P0_1() +{ + MEDCouplingUMesh *sourceMesh=build3DSurfSourceMesh_1(); + MEDCouplingUMesh *targetMesh=build3DSurfTargetMesh_1(); + // + MEDCouplingNormalizedUnstructuredMesh<3,2> sourceWrapper(sourceMesh); + MEDCouplingNormalizedUnstructuredMesh<3,2> targetWrapper(targetMesh); + INTERP_KERNEL::Interpolation3DSurf myInterpolator; + std::vector<std::map<int,double> > res; + INTERP_KERNEL::IntersectionType types[2]={INTERP_KERNEL::Triangulation, INTERP_KERNEL::Geometric2D}; + for(int i=0;i<2;i++) + { + myInterpolator.setPrecision(1e-12); + myInterpolator.setIntersectionType(types[i]); + myInterpolator.interpolateMeshes(sourceWrapper,targetWrapper,res,"P1P0"); + CPPUNIT_ASSERT_EQUAL(5,(int)res.size()); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.25*sqrt(2.),res[0][0],1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.041666666666666664*sqrt(2.),res[1][0],1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.041666666666666664*sqrt(2.),res[3][0],1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.083333333333333333*sqrt(2.),res[1][1],1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.083333333333333333*sqrt(2.),res[2][1],1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.166666666666666667*sqrt(2.),res[3][2],1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.041666666666666664*sqrt(2.),res[2][3],1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.041666666666666664*sqrt(2.),res[3][3],1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.25*sqrt(2.),res[4][3],1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(1.*sqrt(2.),sumAll(res),1e-12); + res.clear(); + } + //clean up + sourceMesh->decrRef(); + targetMesh->decrRef(); +} + +void MEDCouplingBasicsTestInterp::test3DSurfInterpP1P0PL_1() +{ + MEDCouplingUMesh *sourceMesh=build3DSurfSourceMesh_1(); + MEDCouplingUMesh *targetMesh=build3DSurfTargetMesh_1(); + // + MEDCouplingNormalizedUnstructuredMesh<3,2> sourceWrapper(sourceMesh); + MEDCouplingNormalizedUnstructuredMesh<3,2> targetWrapper(targetMesh); + INTERP_KERNEL::Interpolation3DSurf myInterpolator; + std::vector<std::map<int,double> > res; + myInterpolator.setPrecision(1e-12); + myInterpolator.setIntersectionType(INTERP_KERNEL::PointLocator); + myInterpolator.interpolateMeshes(sourceWrapper,targetWrapper,res,"P1P0"); + CPPUNIT_ASSERT_EQUAL(5,(int)res.size()); + CPPUNIT_ASSERT_DOUBLES_EQUAL(1.5,res[0][0],1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.,res[0][1],1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.,res[0][2],1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.5,res[0][3],1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.333333333333333333,res[1][0],1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.5,res[1][1],1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.166666666666666666,res[1][3],1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.166666666666666666,res[2][0],1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.5,res[2][1],1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.333333333333333333,res[2][3],1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.25,res[3][0],1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.5,res[3][2],1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.25,res[3][3],1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.5,res[4][0],1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.,res[4][1],1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.,res[4][2],1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(1.5,res[4][3],1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(7.,sumAll(res),1e-12); + res.clear(); + //clean up + sourceMesh->decrRef(); + targetMesh->decrRef(); +} + +void MEDCouplingBasicsTestInterp::test3DSurfInterpP1P1_1() +{ + MEDCouplingUMesh *sourceMesh=build3DSurfSourceMesh_1(); + MEDCouplingUMesh *targetMesh=build3DSurfTargetMesh_2(); + // + MEDCouplingNormalizedUnstructuredMesh<3,2> sourceWrapper(sourceMesh); + MEDCouplingNormalizedUnstructuredMesh<3,2> targetWrapper(targetMesh); + INTERP_KERNEL::Interpolation3DSurf myInterpolator; + std::vector<std::map<int,double> > res; + INTERP_KERNEL::IntersectionType types[2]={INTERP_KERNEL::Triangulation, INTERP_KERNEL::Geometric2D}; + for(int i=0;i<2;i++) + { + myInterpolator.setPrecision(1e-12); + myInterpolator.setIntersectionType(types[i]); + myInterpolator.interpolateMeshes(sourceWrapper,targetWrapper,res,"P1P1"); + CPPUNIT_ASSERT_EQUAL(9,(int)res.size()); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.08333333333333334*sqrt(2.),res[0][0],1.e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.05416666666666665*sqrt(2.),res[1][0],1.e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.02916666666666666*sqrt(2.),res[1][1],1.e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.08333333333333334*sqrt(2.),res[2][1],1.e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.05416666666666665*sqrt(2.),res[3][0],1.e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.02916666666666668*sqrt(2.),res[3][2],1.e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.1416666666666666*sqrt(2.),res[4][0],1.e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.02499999999999999*sqrt(2.),res[4][1],1.e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.02499999999999999*sqrt(2.),res[4][2],1.e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.09999999999999999*sqrt(2.),res[4][3],1.e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.02916666666666666*sqrt(2.),res[5][1],1.e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.09583333333333333*sqrt(2.),res[5][3],1.e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.08333333333333333*sqrt(2.),res[6][2],1.e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.02916666666666667*sqrt(2.),res[7][2],1.e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.09583333333333331*sqrt(2.),res[7][3],1.e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.04166666666666668*sqrt(2.),res[8][3],1.e-12); + res.clear(); + } + // + sourceMesh->decrRef(); + targetMesh->decrRef(); +} + +void MEDCouplingBasicsTestInterp::test3DSurfInterpP1P1PL_1() +{ + MEDCouplingUMesh *sourceMesh=build3DSurfSourceMesh_1(); + MEDCouplingUMesh *targetMesh=build3DSurfTargetMesh_1(); + // + MEDCouplingNormalizedUnstructuredMesh<3,2> sourceWrapper(sourceMesh); + MEDCouplingNormalizedUnstructuredMesh<3,2> targetWrapper(targetMesh); + INTERP_KERNEL::Interpolation3DSurf myInterpolator; + std::vector<std::map<int,double> > res; + myInterpolator.setPrecision(1e-12); + myInterpolator.setIntersectionType(INTERP_KERNEL::PointLocator); + myInterpolator.interpolateMeshes(sourceWrapper,targetWrapper,res,"P1P1"); + CPPUNIT_ASSERT_EQUAL(9,(int)res.size()); + CPPUNIT_ASSERT_DOUBLES_EQUAL(2.,res[0][0],1.e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[1][0],1.e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[1][1],1.e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(2.,res[2][1],1.e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[3][0],1.e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[3][2],1.e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(5.,res[4][0],1.e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(5.,res[4][3],1.e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[5][1],1.e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[5][3],1.e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[6][2],1.e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[7][2],1.e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[7][3],1.e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(2.,res[8][3],1.e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(25.,sumAll(res),1e-12); + res.clear(); + //clean up + sourceMesh->decrRef(); + targetMesh->decrRef(); +} + +void MEDCouplingBasicsTestInterp::test3DSurfInterpP0P0_2() +{ + MEDCouplingUMesh *sourceMesh=build3DSurfSourceMesh_1(); + MEDCouplingUMesh *targetMesh=build3DSurfTargetMeshPerm_1(); + // + MEDCouplingNormalizedUnstructuredMesh<3,2> sourceWrapper(sourceMesh); + MEDCouplingNormalizedUnstructuredMesh<3,2> targetWrapper(targetMesh); + INTERP_KERNEL::Interpolation3DSurf myInterpolator; + std::vector<std::map<int,double> > res; + myInterpolator.setPrecision(1e-12); + myInterpolator.setIntersectionType(INTERP_KERNEL::Triangulation); + { + myInterpolator.setOrientation(2); + myInterpolator.interpolateMeshes(sourceWrapper,targetWrapper,res,"P0P0"); + CPPUNIT_ASSERT_EQUAL(5,(int)res.size()); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.125*sqrt(2.),res[0][0],1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.125*sqrt(2.),res[0][1],1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.125*sqrt(2.),res[1][0],1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.125*sqrt(2.),res[2][0],1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.25*sqrt(2.),res[3][1],1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.125*sqrt(2.),res[4][0],1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.125*sqrt(2.),res[4][1],1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(1.*sqrt(2.),sumAll(res),1e-12); + res.clear(); + } + { + myInterpolator.setOrientation(0); + myInterpolator.interpolateMeshes(sourceWrapper,targetWrapper,res,"P0P0"); + CPPUNIT_ASSERT_EQUAL(5,(int)res.size()); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.125*sqrt(2.),res[0][0],1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.125*sqrt(2.),res[0][1],1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.125*sqrt(2.),res[1][0],1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(-0.125*sqrt(2.),res[2][0],1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.25*sqrt(2.),res[3][1],1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.125*sqrt(2.),res[4][0],1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.125*sqrt(2.),res[4][1],1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.75*sqrt(2.),sumAll(res),1e-12); + res.clear(); + } + { + myInterpolator.setOrientation(1); + myInterpolator.interpolateMeshes(sourceWrapper,targetWrapper,res,"P0P0"); + CPPUNIT_ASSERT_EQUAL(5,(int)res.size()); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.125*sqrt(2.),res[0][0],1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.125*sqrt(2.),res[0][1],1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.125*sqrt(2.),res[1][0],1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.25*sqrt(2.),res[3][1],1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.125*sqrt(2.),res[4][0],1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.125*sqrt(2.),res[4][1],1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.875*sqrt(2.),sumAll(res),1e-12); + res.clear(); + } + { + myInterpolator.setOrientation(-1); + myInterpolator.interpolateMeshes(sourceWrapper,targetWrapper,res,"P0P0"); + CPPUNIT_ASSERT_EQUAL(5,(int)res.size()); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.125*sqrt(2.),res[2][0],1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.125*sqrt(2.),sumAll(res),1e-12); + res.clear(); + } + //clean up + sourceMesh->decrRef(); + targetMesh->decrRef(); +} + +/*! + * Test of precision option implemented by Fabien that represents distance of "barycenter" to the other cell. + */ +void MEDCouplingBasicsTestInterp::test3DSurfInterpP0P0_3() +{ + INTERP_KERNEL::Interpolation3DSurf myInterpolator; + std::vector<std::map<int,double> > res; + double vecTrans[3]={0.,0.,1.e-10}; + double vec[3]={0.,-1.,0.}; + double pt[3]={-0.3,-0.3,5.e-11}; + const int N=32; + const double deltaA=M_PI/N; + myInterpolator.setPrecision(1e-12); + myInterpolator.setIntersectionType(INTERP_KERNEL::Triangulation); + myInterpolator.setMaxDistance3DSurfIntersect(1e-9); + for(int i=0;i<N;i++) + { + res.clear(); + MEDCouplingUMesh *sourceMesh=build3DSurfSourceMesh_2(); + sourceMesh->rotate(pt,vec,i*deltaA); + MEDCouplingUMesh *targetMesh=build3DSurfSourceMesh_2(); + targetMesh->translate(vecTrans); + targetMesh->rotate(pt,vec,i*deltaA); + MEDCouplingNormalizedUnstructuredMesh<3,2> sourceWrapper(sourceMesh); + MEDCouplingNormalizedUnstructuredMesh<3,2> targetWrapper(targetMesh); + myInterpolator.interpolateMeshes(sourceWrapper,targetWrapper,res,"P0P0"); + CPPUNIT_ASSERT_EQUAL(2,(int)res.size()); + CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,sumAll(res),1e-12); + sourceMesh->decrRef(); + targetMesh->decrRef(); + } + // + myInterpolator.setMaxDistance3DSurfIntersect(1e-11); + for(int i=0;i<N;i++) + { + res.clear(); + MEDCouplingUMesh *sourceMesh=build3DSurfSourceMesh_2(); + sourceMesh->rotate(pt,vec,i*deltaA); + MEDCouplingUMesh *targetMesh=build3DSurfSourceMesh_2(); + targetMesh->translate(vecTrans); + targetMesh->rotate(pt,vec,i*deltaA); + MEDCouplingNormalizedUnstructuredMesh<3,2> sourceWrapper(sourceMesh); + MEDCouplingNormalizedUnstructuredMesh<3,2> targetWrapper(targetMesh); + myInterpolator.interpolateMeshes(sourceWrapper,targetWrapper,res,"P0P0"); + CPPUNIT_ASSERT_EQUAL(2,(int)res.size()); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.,sumAll(res),1e-12); + sourceMesh->decrRef(); + targetMesh->decrRef(); + } + // + res.clear(); + myInterpolator.setMaxDistance3DSurfIntersect(-1.);//unactivate fabien lookup + MEDCouplingUMesh *sourceMesh=build3DSurfSourceMesh_2(); + MEDCouplingUMesh *targetMesh=build3DSurfSourceMesh_2(); + targetMesh->translate(vecTrans); + myInterpolator.setBoundingBoxAdjustment(1e-11); + MEDCouplingNormalizedUnstructuredMesh<3,2> sourceWrapper0(sourceMesh); + MEDCouplingNormalizedUnstructuredMesh<3,2> targetWrapper0(targetMesh); + myInterpolator.interpolateMeshes(sourceWrapper0,targetWrapper0,res,"P0P0"); + CPPUNIT_ASSERT_EQUAL(2,(int)res.size()); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.,sumAll(res),1e-12); + sourceMesh->decrRef(); + targetMesh->decrRef(); + // + res.clear(); + sourceMesh=build3DSurfSourceMesh_2(); + targetMesh=build3DSurfSourceMesh_2(); + targetMesh->translate(vecTrans); + myInterpolator.setBoundingBoxAdjustment(1e-9); + MEDCouplingNormalizedUnstructuredMesh<3,2> sourceWrapper1(sourceMesh); + MEDCouplingNormalizedUnstructuredMesh<3,2> targetWrapper1(targetMesh); + myInterpolator.interpolateMeshes(sourceWrapper1,targetWrapper1,res,"P0P0"); + CPPUNIT_ASSERT_EQUAL(2,(int)res.size()); + CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,sumAll(res),1e-12); + sourceMesh->decrRef(); + targetMesh->decrRef(); + //keeping the same bbox adj == 1.e-11 but trying rotation + res.clear(); + sourceMesh=build3DSurfSourceMesh_2(); + sourceMesh->rotate(pt,vec,M_PI/4.); + targetMesh=build3DSurfSourceMesh_2(); + targetMesh->translate(vecTrans); + targetMesh->rotate(pt,vec,M_PI/4.); + myInterpolator.setBoundingBoxAdjustment(1e-11); + MEDCouplingNormalizedUnstructuredMesh<3,2> sourceWrapper2(sourceMesh); + MEDCouplingNormalizedUnstructuredMesh<3,2> targetWrapper2(targetMesh); + myInterpolator.interpolateMeshes(sourceWrapper2,targetWrapper2,res,"P0P0"); + CPPUNIT_ASSERT_EQUAL(2,(int)res.size()); + CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,sumAll(res),1e-12); + sourceMesh->decrRef(); + targetMesh->decrRef(); +} + +void MEDCouplingBasicsTestInterp::test3DInterpP0P0_1() +{ + MEDCouplingUMesh *sourceMesh=build3DSourceMesh_1(); + MEDCouplingUMesh *targetMesh=build3DTargetMesh_1(); + // + MEDCouplingNormalizedUnstructuredMesh<3,3> sourceWrapper(sourceMesh); + MEDCouplingNormalizedUnstructuredMesh<3,3> targetWrapper(targetMesh); + INTERP_KERNEL::Interpolation3D myInterpolator; + std::vector<std::map<int,double> > res; + myInterpolator.setPrecision(1e-12); + INTERP_KERNEL::SplittingPolicy sp[] = { INTERP_KERNEL::PLANAR_FACE_5, INTERP_KERNEL::PLANAR_FACE_6, INTERP_KERNEL::GENERAL_24, INTERP_KERNEL::GENERAL_48 }; + for ( int i = 0; i < 4; ++i ) + { + myInterpolator.setSplittingPolicy( sp[i] ); + res.clear(); + myInterpolator.interpolateMeshes(sourceWrapper,targetWrapper,res,"P0P0"); + CPPUNIT_ASSERT_EQUAL(8,(int)res.size()); + CPPUNIT_ASSERT_DOUBLES_EQUAL(8.e6,sumAll(res),1e-7); + CPPUNIT_ASSERT_DOUBLES_EQUAL(20833.33333333333,res[0][0],1e-7); + CPPUNIT_ASSERT_DOUBLES_EQUAL(41666.66666666667,res[0][6],1e-7); + CPPUNIT_ASSERT_DOUBLES_EQUAL(20833.33333333333,res[0][7],1e-7); + CPPUNIT_ASSERT_DOUBLES_EQUAL(20833.33333333333,res[0][8],1e-7); + CPPUNIT_ASSERT_DOUBLES_EQUAL(20833.33333333333,res[0][10],1e-7); + CPPUNIT_ASSERT_DOUBLES_EQUAL(41666.66666666667,res[1][2],1e-7); + CPPUNIT_ASSERT_DOUBLES_EQUAL(166666.6666666667,res[1][7],1e-7); + CPPUNIT_ASSERT_DOUBLES_EQUAL(166666.6666666667,res[1][8],1e-7); + CPPUNIT_ASSERT_DOUBLES_EQUAL(166666.6666666667,res[2][0],1e-7); + CPPUNIT_ASSERT_DOUBLES_EQUAL(20833.33333333333,res[2][5],1e-7); + CPPUNIT_ASSERT_DOUBLES_EQUAL(145833.3333333333,res[2][6],1e-7); + CPPUNIT_ASSERT_DOUBLES_EQUAL(20833.33333333333,res[2][9],1e-7); + CPPUNIT_ASSERT_DOUBLES_EQUAL(20833.33333333333,res[2][11],1e-7); + CPPUNIT_ASSERT_DOUBLES_EQUAL(395833.3333333333,res[3][0],1e-7); + CPPUNIT_ASSERT_DOUBLES_EQUAL(145833.3333333333,res[3][2],1e-7); + CPPUNIT_ASSERT_DOUBLES_EQUAL(20833.33333333331,res[3][3],1e-7); + CPPUNIT_ASSERT_DOUBLES_EQUAL(166666.6666666667,res[3][5],1e-7); + CPPUNIT_ASSERT_DOUBLES_EQUAL(395833.3333333333,res[3][8],1e-7); + CPPUNIT_ASSERT_DOUBLES_EQUAL(20833.33333333333,res[4][1],1e-7); + CPPUNIT_ASSERT_DOUBLES_EQUAL(20833.33333333333,res[4][4],1e-7); + CPPUNIT_ASSERT_DOUBLES_EQUAL(145833.3333333333,res[4][6],1e-7); + CPPUNIT_ASSERT_DOUBLES_EQUAL(20833.33333333333,res[4][9],1e-7); + CPPUNIT_ASSERT_DOUBLES_EQUAL(166666.6666666667,res[4][10],1e-7); + CPPUNIT_ASSERT_DOUBLES_EQUAL(145833.3333333333,res[5][2],1e-7); + CPPUNIT_ASSERT_DOUBLES_EQUAL(20833.33333333331,res[5][3],1e-7); + CPPUNIT_ASSERT_DOUBLES_EQUAL(166666.6666666667,res[5][4],1e-7); + CPPUNIT_ASSERT_DOUBLES_EQUAL(395833.3333333333,res[5][7],1e-7); + CPPUNIT_ASSERT_DOUBLES_EQUAL(395833.3333333333,res[5][10],1e-7); + CPPUNIT_ASSERT_DOUBLES_EQUAL(166666.6666666667,res[6][1],1e-7); + CPPUNIT_ASSERT_DOUBLES_EQUAL(250000,res[6][6],1e-7); + CPPUNIT_ASSERT_DOUBLES_EQUAL(541666.6666666667,res[6][9],1e-7); + CPPUNIT_ASSERT_DOUBLES_EQUAL(166666.6666666667,res[6][11],1e-7); + CPPUNIT_ASSERT_DOUBLES_EQUAL(83333.33333333331,res[7][0],1e-7); + CPPUNIT_ASSERT_DOUBLES_EQUAL(479166.6666666667,res[7][1],1e-7); + CPPUNIT_ASSERT_DOUBLES_EQUAL(333333.3333333333,res[7][2],1e-7); + CPPUNIT_ASSERT_DOUBLES_EQUAL(624999.9999999997,res[7][3],1e-7); + CPPUNIT_ASSERT_DOUBLES_EQUAL(479166.6666666667,res[7][4],1e-7); + CPPUNIT_ASSERT_DOUBLES_EQUAL(479166.6666666667,res[7][5],1e-7); + CPPUNIT_ASSERT_DOUBLES_EQUAL(83333.33333333333,res[7][6],1e-7); + CPPUNIT_ASSERT_DOUBLES_EQUAL(83333.33333333331,res[7][7],1e-7); + CPPUNIT_ASSERT_DOUBLES_EQUAL(83333.33333333333,res[7][8],1e-7); + CPPUNIT_ASSERT_DOUBLES_EQUAL(83333.33333333333,res[7][9],1e-7); + CPPUNIT_ASSERT_DOUBLES_EQUAL(83333.33333333331,res[7][10],1e-7); + CPPUNIT_ASSERT_DOUBLES_EQUAL(479166.6666666667,res[7][11],1e-7); + } + //clean up + sourceMesh->decrRef(); + targetMesh->decrRef(); +} + +void MEDCouplingBasicsTestInterp::test3DInterpP0P0PL_1() +{ + MEDCouplingUMesh *sourceMesh=build3DSourceMesh_1(); + MEDCouplingUMesh *targetMesh=build3DTargetMesh_1(); + // + MEDCouplingNormalizedUnstructuredMesh<3,3> sourceWrapper(sourceMesh); + MEDCouplingNormalizedUnstructuredMesh<3,3> targetWrapper(targetMesh); + INTERP_KERNEL::Interpolation3D myInterpolator; + std::vector<std::map<int,double> > res; + myInterpolator.setPrecision(1e-12); + myInterpolator.setIntersectionType(INTERP_KERNEL::PointLocator); + INTERP_KERNEL::SplittingPolicy sp[] = { INTERP_KERNEL::PLANAR_FACE_5, INTERP_KERNEL::PLANAR_FACE_6, INTERP_KERNEL::GENERAL_24, INTERP_KERNEL::GENERAL_48 }; + for ( int i = 0; i < 4; ++i ) + { + myInterpolator.setSplittingPolicy( sp[i] ); + res.clear(); + myInterpolator.interpolateMeshes(sourceWrapper,targetWrapper,res,"P0P0"); + CPPUNIT_ASSERT_EQUAL(8,(int)res.size()); + CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[0][0],1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[0][6],1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[0][7],1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[0][8],1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[0][10],1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[1][7],1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[1][8],1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[2][0],1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[2][6],1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[3][0],1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[3][8],1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[4][6],1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[4][10],1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[5][7],1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[5][10],1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[6][9],1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[7][1],1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[7][3],1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[7][4],1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[7][5],1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[7][11],1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(21.,sumAll(res),1e-12); + } + //clean up + sourceMesh->decrRef(); + targetMesh->decrRef(); +} + +void MEDCouplingBasicsTestInterp::test3DInterpP0P0PL_2() +{ + MEDCouplingUMesh *sourceMesh=build3DSourceMesh_1(); + MEDCouplingUMesh *targetMesh=build3DTargetMesh_1(); + std::vector<int> cellsIds(targetMesh->getNumberOfCells()); + for(int i=0;i<targetMesh->getNumberOfCells();i++) + cellsIds[i]=i; + targetMesh->convertToPolyTypes(&cellsIds[0],&cellsIds[0]+cellsIds.size()); + // + MEDCouplingNormalizedUnstructuredMesh<3,3> sourceWrapper(sourceMesh); + MEDCouplingNormalizedUnstructuredMesh<3,3> targetWrapper(targetMesh); + INTERP_KERNEL::Interpolation3D myInterpolator; + std::vector<std::map<int,double> > res; + myInterpolator.setPrecision(1e-12); + myInterpolator.setIntersectionType(INTERP_KERNEL::PointLocator); + INTERP_KERNEL::SplittingPolicy sp[] = { INTERP_KERNEL::PLANAR_FACE_5, INTERP_KERNEL::PLANAR_FACE_6, INTERP_KERNEL::GENERAL_24, INTERP_KERNEL::GENERAL_48 }; + for ( int i = 0; i < 4; ++i ) + { + myInterpolator.setSplittingPolicy( sp[i] ); + res.clear(); + myInterpolator.interpolateMeshes(sourceWrapper,targetWrapper,res,"P0P0"); + CPPUNIT_ASSERT_EQUAL(8,(int)res.size()); + CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[0][0],1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[0][6],1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[0][7],1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[0][8],1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[0][10],1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[1][7],1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[1][8],1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[2][0],1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[2][6],1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[3][0],1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[3][8],1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[4][6],1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[4][10],1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[5][7],1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[5][10],1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[6][9],1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[7][1],1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[7][3],1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[7][4],1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[7][5],1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[7][11],1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(21.,sumAll(res),1e-12); + } + //clean up + sourceMesh->decrRef(); + targetMesh->decrRef(); +} + +void MEDCouplingBasicsTestInterp::test3DInterpP0P0PL_3() +{ + MEDCouplingUMesh *sourceMesh=build3DSourceMesh_1(); + MEDCouplingUMesh *targetMesh=build3DTargetMesh_1(); + std::vector<int> cellsIds(sourceMesh->getNumberOfCells()); + for(int i=0;i<sourceMesh->getNumberOfCells();i++) + cellsIds[i]=i; + sourceMesh->convertToPolyTypes(&cellsIds[0],&cellsIds[0]+cellsIds.size()); + // + MEDCouplingNormalizedUnstructuredMesh<3,3> sourceWrapper(sourceMesh); + MEDCouplingNormalizedUnstructuredMesh<3,3> targetWrapper(targetMesh); + INTERP_KERNEL::Interpolation3D myInterpolator; + std::vector<std::map<int,double> > res; + myInterpolator.setPrecision(1e-12); + myInterpolator.setIntersectionType(INTERP_KERNEL::PointLocator); + INTERP_KERNEL::SplittingPolicy sp[] = { INTERP_KERNEL::PLANAR_FACE_5, INTERP_KERNEL::PLANAR_FACE_6, INTERP_KERNEL::GENERAL_24, INTERP_KERNEL::GENERAL_48 }; + for ( int i = 0; i < 4; ++i ) + { + myInterpolator.setSplittingPolicy( sp[i] ); + res.clear(); + myInterpolator.interpolateMeshes(sourceWrapper,targetWrapper,res,"P0P0"); + CPPUNIT_ASSERT_EQUAL(8,(int)res.size()); + CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[0][0],1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[0][6],1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[0][7],1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[0][8],1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[0][10],1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[1][7],1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[1][8],1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[2][0],1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[2][6],1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[3][0],1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[3][8],1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[4][6],1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[4][10],1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[5][7],1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[5][10],1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[6][9],1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[7][1],1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[7][3],1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[7][4],1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[7][5],1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[7][11],1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(21.,sumAll(res),1e-12); + } + //clean up + sourceMesh->decrRef(); + targetMesh->decrRef(); +} + +void MEDCouplingBasicsTestInterp::test3DInterpP0P0PL_4() +{ + MEDCouplingUMesh *sourceMesh=build3DSourceMesh_1(); + MEDCouplingUMesh *targetMesh=build3DTargetMesh_1(); + std::vector<int> cellsIds(sourceMesh->getNumberOfCells()); + for(int i=0;i<sourceMesh->getNumberOfCells();i++) + cellsIds[i]=i; + sourceMesh->convertToPolyTypes(&cellsIds[0],&cellsIds[0]+cellsIds.size()); + cellsIds.resize(targetMesh->getNumberOfCells()); + for(int j=0;j<targetMesh->getNumberOfCells();j++) + cellsIds[j]=j; + targetMesh->convertToPolyTypes(&cellsIds[0],&cellsIds[0]+cellsIds.size()); + // + MEDCouplingNormalizedUnstructuredMesh<3,3> sourceWrapper(sourceMesh); + MEDCouplingNormalizedUnstructuredMesh<3,3> targetWrapper(targetMesh); + INTERP_KERNEL::Interpolation3D myInterpolator; + std::vector<std::map<int,double> > res; + myInterpolator.setPrecision(1e-12); + myInterpolator.setIntersectionType(INTERP_KERNEL::PointLocator); + INTERP_KERNEL::SplittingPolicy sp[] = { INTERP_KERNEL::PLANAR_FACE_5, INTERP_KERNEL::PLANAR_FACE_6, INTERP_KERNEL::GENERAL_24, INTERP_KERNEL::GENERAL_48 }; + for ( int i = 0; i < 4; ++i ) + { + myInterpolator.setSplittingPolicy( sp[i] ); + res.clear(); + myInterpolator.interpolateMeshes(sourceWrapper,targetWrapper,res,"P0P0"); + CPPUNIT_ASSERT_EQUAL(8,(int)res.size()); + CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[0][0],1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[0][6],1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[0][7],1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[0][8],1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[0][10],1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[1][7],1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[1][8],1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[2][0],1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[2][6],1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[3][0],1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[3][8],1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[4][6],1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[4][10],1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[5][7],1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[5][10],1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[6][9],1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[7][1],1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[7][3],1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[7][4],1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[7][5],1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[7][11],1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(21.,sumAll(res),1e-12); + } + //clean up + sourceMesh->decrRef(); + targetMesh->decrRef(); +} + +void MEDCouplingBasicsTestInterp::test3DInterpP0P1_1() +{ + MEDCouplingUMesh *sourceMesh=build3DTargetMesh_1(); + MEDCouplingUMesh *targetMesh=build3DSourceMesh_1(); + // + MEDCouplingNormalizedUnstructuredMesh<3,3> sourceWrapper(sourceMesh); + MEDCouplingNormalizedUnstructuredMesh<3,3> targetWrapper(targetMesh); + INTERP_KERNEL::Interpolation3D myInterpolator; + std::vector<std::map<int,double> > res; + myInterpolator.setPrecision(1e-12); + INTERP_KERNEL::SplittingPolicy sp[] = { INTERP_KERNEL::PLANAR_FACE_5, INTERP_KERNEL::PLANAR_FACE_6, INTERP_KERNEL::GENERAL_24, INTERP_KERNEL::GENERAL_48 }; + for ( int i = 0; i < 4; ++i ) + { + myInterpolator.setSplittingPolicy( sp[i] ); + res.clear(); + myInterpolator.interpolateMeshes(sourceWrapper,targetWrapper,res,"P0P1"); + CPPUNIT_ASSERT_EQUAL(9,(int)res.size()); + CPPUNIT_ASSERT_DOUBLES_EQUAL(244444.4444444445,res[0][4],1e-7); + CPPUNIT_ASSERT_DOUBLES_EQUAL(145833.3333333333,res[0][5],1e-7); + CPPUNIT_ASSERT_DOUBLES_EQUAL(291666.6666666666,res[0][6],1e-7); + CPPUNIT_ASSERT_DOUBLES_EQUAL(151388.8888888889,res[0][7],1e-7); + CPPUNIT_ASSERT_DOUBLES_EQUAL(125000,res[1][0],1e-7); + CPPUNIT_ASSERT_DOUBLES_EQUAL(140277.7777777778,res[1][1],1e-7); + CPPUNIT_ASSERT_DOUBLES_EQUAL(119444.4444444444,res[1][2],1e-7); + CPPUNIT_ASSERT_DOUBLES_EQUAL(151388.8888888889,res[1][3],1e-7); + CPPUNIT_ASSERT_DOUBLES_EQUAL(119444.4444444444,res[1][4],1e-7); + CPPUNIT_ASSERT_DOUBLES_EQUAL(151388.8888888889,res[1][5],1e-7); + CPPUNIT_ASSERT_DOUBLES_EQUAL(26388.88888888889,res[1][6],1e-7); + CPPUNIT_ASSERT_DOUBLES_EQUAL(348611.1111111111,res[2][6],1e-7); + CPPUNIT_ASSERT_DOUBLES_EQUAL(151388.8888888888,res[2][7],1e-7); + CPPUNIT_ASSERT_DOUBLES_EQUAL(244444.4444444444,res[3][2],1e-7); + CPPUNIT_ASSERT_DOUBLES_EQUAL(145833.3333333334,res[3][3],1e-7); + CPPUNIT_ASSERT_DOUBLES_EQUAL(291666.6666666666,res[3][6],1e-7); + CPPUNIT_ASSERT_DOUBLES_EQUAL(151388.8888888889,res[3][7],1e-7); + CPPUNIT_ASSERT_DOUBLES_EQUAL(536111.111111111,res[4][5],1e-7); + CPPUNIT_ASSERT_DOUBLES_EQUAL(297222.2222222221,res[4][7],1e-7); + CPPUNIT_ASSERT_DOUBLES_EQUAL(223611.1111111111,res[5][1],1e-7); + CPPUNIT_ASSERT_DOUBLES_EQUAL(125000,res[5][3],1e-7); + CPPUNIT_ASSERT_DOUBLES_EQUAL(125000,res[5][5],1e-7); + CPPUNIT_ASSERT_DOUBLES_EQUAL(26388.88888888892,res[5][7],1e-7); + CPPUNIT_ASSERT_DOUBLES_EQUAL(833333.333333333,res[6][7],1e-7); + CPPUNIT_ASSERT_DOUBLES_EQUAL(536111.1111111109,res[7][3],1e-7); + CPPUNIT_ASSERT_DOUBLES_EQUAL(297222.2222222221,res[7][7],1e-7); + CPPUNIT_ASSERT_DOUBLES_EQUAL(11111.1111111111,res[8][1],1e-7); + CPPUNIT_ASSERT_DOUBLES_EQUAL(11111.11111111111,res[8][2],1e-7); + CPPUNIT_ASSERT_DOUBLES_EQUAL(166666.6666666666,res[8][3],1e-7); + CPPUNIT_ASSERT_DOUBLES_EQUAL(11111.11111111111,res[8][4],1e-7); + CPPUNIT_ASSERT_DOUBLES_EQUAL(166666.6666666667,res[8][5],1e-7); + CPPUNIT_ASSERT_DOUBLES_EQUAL(166666.6666666667,res[8][6],1e-7); + CPPUNIT_ASSERT_DOUBLES_EQUAL(1466666.666666668,res[8][7],1e-7); + } + //clean up + sourceMesh->decrRef(); + targetMesh->decrRef(); +} + +void MEDCouplingBasicsTestInterp::test3DInterpP0P1PL_1() +{ + MEDCouplingUMesh *sourceMesh=build3DTargetMesh_1(); + MEDCouplingUMesh *targetMesh=build3DSourceMesh_1(); + // + MEDCouplingNormalizedUnstructuredMesh<3,3> sourceWrapper(sourceMesh); + MEDCouplingNormalizedUnstructuredMesh<3,3> targetWrapper(targetMesh); + INTERP_KERNEL::Interpolation3D myInterpolator; + std::vector<std::map<int,double> > res; + myInterpolator.setPrecision(1e-12); + myInterpolator.setIntersectionType(INTERP_KERNEL::PointLocator); + INTERP_KERNEL::SplittingPolicy sp[] = { INTERP_KERNEL::PLANAR_FACE_5, INTERP_KERNEL::PLANAR_FACE_6, INTERP_KERNEL::GENERAL_24, INTERP_KERNEL::GENERAL_48 }; + for ( int i = 0; i < 4; ++i ) + { + myInterpolator.setSplittingPolicy( sp[i] ); + res.clear(); + myInterpolator.interpolateMeshes(sourceWrapper,targetWrapper,res,"P0P1"); + CPPUNIT_ASSERT_EQUAL(9,(int)res.size()); + CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[0][4],1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[1][0],1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[2][6],1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[3][2],1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[4][5],1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[5][1],1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[6][7],1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[7][3],1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[8][7],1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(9.,sumAll(res),1e-12); + } + //clean up + sourceMesh->decrRef(); + targetMesh->decrRef(); +} + +void MEDCouplingBasicsTestInterp::test3DInterpP1P0_1() +{ + MEDCouplingUMesh *sourceMesh=build3DSourceMesh_1(); + MEDCouplingUMesh *targetMesh=build3DTargetMesh_1(); + // + MEDCouplingNormalizedUnstructuredMesh<3,3> sourceWrapper(sourceMesh); + MEDCouplingNormalizedUnstructuredMesh<3,3> targetWrapper(targetMesh); + INTERP_KERNEL::Interpolation3D myInterpolator; + std::vector<std::map<int,double> > res; + myInterpolator.setPrecision(1e-12); + INTERP_KERNEL::SplittingPolicy sp[] = { INTERP_KERNEL::PLANAR_FACE_5, INTERP_KERNEL::PLANAR_FACE_6, INTERP_KERNEL::GENERAL_24, INTERP_KERNEL::GENERAL_48 }; + for ( int i = 0; i < 4; ++i ) + { + myInterpolator.setSplittingPolicy( sp[i] ); + res.clear(); + myInterpolator.interpolateMeshes(sourceWrapper,targetWrapper,res,"P1P0"); + CPPUNIT_ASSERT_EQUAL(8,(int)res.size()); + CPPUNIT_ASSERT_DOUBLES_EQUAL(125000,res[0][1],1e-7); + CPPUNIT_ASSERT_DOUBLES_EQUAL(140277.7777777778,res[1][1],1e-7); + CPPUNIT_ASSERT_DOUBLES_EQUAL(223611.1111111111,res[1][5],1e-7); + CPPUNIT_ASSERT_DOUBLES_EQUAL(11111.1111111111,res[1][8],1e-7); + CPPUNIT_ASSERT_DOUBLES_EQUAL(119444.4444444444,res[2][1],1e-7); + CPPUNIT_ASSERT_DOUBLES_EQUAL(244444.4444444445,res[2][3],1e-7); + CPPUNIT_ASSERT_DOUBLES_EQUAL(11111.11111111111,res[2][8],1e-7); + CPPUNIT_ASSERT_DOUBLES_EQUAL(151388.8888888889,res[3][1],1e-7); + CPPUNIT_ASSERT_DOUBLES_EQUAL(145833.3333333333,res[3][3],1e-7); + CPPUNIT_ASSERT_DOUBLES_EQUAL(125000,res[3][5],1e-7); + CPPUNIT_ASSERT_DOUBLES_EQUAL(536111.1111111109,res[3][7],1e-7); + CPPUNIT_ASSERT_DOUBLES_EQUAL(166666.6666666667,res[3][8],1e-7); + CPPUNIT_ASSERT_DOUBLES_EQUAL(244444.4444444445,res[4][0],1e-7); + CPPUNIT_ASSERT_DOUBLES_EQUAL(119444.4444444445,res[4][1],1e-7); + CPPUNIT_ASSERT_DOUBLES_EQUAL(11111.11111111111,res[4][8],1e-7); + CPPUNIT_ASSERT_DOUBLES_EQUAL(145833.3333333333,res[5][0],1e-7); + CPPUNIT_ASSERT_DOUBLES_EQUAL(151388.8888888889,res[5][1],1e-7); + CPPUNIT_ASSERT_DOUBLES_EQUAL(536111.1111111109,res[5][4],1e-7); + CPPUNIT_ASSERT_DOUBLES_EQUAL(125000,res[5][5],1e-7); + CPPUNIT_ASSERT_DOUBLES_EQUAL(166666.6666666666,res[5][8],1e-7); + CPPUNIT_ASSERT_DOUBLES_EQUAL(291666.6666666666,res[6][0],1e-7); + CPPUNIT_ASSERT_DOUBLES_EQUAL(26388.88888888889,res[6][1],1e-7); + CPPUNIT_ASSERT_DOUBLES_EQUAL(348611.1111111112,res[6][2],1e-7); + CPPUNIT_ASSERT_DOUBLES_EQUAL(291666.6666666667,res[6][3],1e-7); + CPPUNIT_ASSERT_DOUBLES_EQUAL(166666.6666666666,res[6][8],1e-7); + CPPUNIT_ASSERT_DOUBLES_EQUAL(151388.8888888889,res[7][0],1e-7); + CPPUNIT_ASSERT_DOUBLES_EQUAL(151388.8888888889,res[7][2],1e-7); + CPPUNIT_ASSERT_DOUBLES_EQUAL(151388.8888888889,res[7][3],1e-7); + CPPUNIT_ASSERT_DOUBLES_EQUAL(297222.2222222221,res[7][4],1e-7); + CPPUNIT_ASSERT_DOUBLES_EQUAL(26388.88888888892,res[7][5],1e-7); + CPPUNIT_ASSERT_DOUBLES_EQUAL(833333.333333333,res[7][6],1e-7); + CPPUNIT_ASSERT_DOUBLES_EQUAL(297222.2222222222,res[7][7],1e-7); + CPPUNIT_ASSERT_DOUBLES_EQUAL(1466666.666666668,res[7][8],1e-7); + } + //clean up + sourceMesh->decrRef(); + targetMesh->decrRef(); +} + +void MEDCouplingBasicsTestInterp::test3DInterpP1P0PL_1() +{ + MEDCouplingUMesh *sourceMesh=build3DSourceMesh_1(); + MEDCouplingUMesh *targetMesh=build3DTargetMesh_1(); + // + MEDCouplingNormalizedUnstructuredMesh<3,3> sourceWrapper(sourceMesh); + MEDCouplingNormalizedUnstructuredMesh<3,3> targetWrapper(targetMesh); + INTERP_KERNEL::Interpolation3D myInterpolator; + std::vector<std::map<int,double> > res; + myInterpolator.setPrecision(1e-12); + myInterpolator.setIntersectionType(INTERP_KERNEL::PointLocator); + INTERP_KERNEL::SplittingPolicy sp[] = { INTERP_KERNEL::PLANAR_FACE_5, INTERP_KERNEL::PLANAR_FACE_6, INTERP_KERNEL::GENERAL_24, INTERP_KERNEL::GENERAL_48 }; + for ( int i = 0; i < 4; ++i ) + { + myInterpolator.setSplittingPolicy( sp[i] ); + res.clear(); + myInterpolator.interpolateMeshes(sourceWrapper,targetWrapper,res,"P1P0"); + CPPUNIT_ASSERT_EQUAL(8,(int)res.size()); + CPPUNIT_ASSERT_DOUBLES_EQUAL(3.75,res[0][1],1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(1.25,res[0][8],1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.5,res[1][1],1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[1][5],1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.5,res[1][8],1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.5,res[2][1],1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[2][3],1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.5,res[2][8],1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.5,res[3][1],1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[3][7],1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.5,res[3][8],1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[4][0],1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.5,res[4][1],1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.5,res[4][8],1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.5,res[5][1],1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[5][4],1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.5,res[5][8],1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.25,res[6][0],1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.25,res[6][2],1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.25,res[6][3],1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.25,res[6][8],1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(1.25,res[7][6],1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(3.75,res[7][8],1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(21.,sumAll(res),1e-12); + } + //clean up + sourceMesh->decrRef(); + targetMesh->decrRef(); +} + +void MEDCouplingBasicsTestInterp::test3DInterpP1P1_1() +{ + MEDCouplingUMesh *sourceMesh=build3DSourceMesh_2(); + MEDCouplingUMesh *targetMesh=build3DTargetMesh_2(); + // + MEDCouplingNormalizedUnstructuredMesh<3,3> sourceWrapper(sourceMesh); + MEDCouplingNormalizedUnstructuredMesh<3,3> targetWrapper(targetMesh); + INTERP_KERNEL::Interpolation3D myInterpolator; + std::vector<std::map<int,double> > res; + myInterpolator.setPrecision(1e-12); + myInterpolator.interpolateMeshes(sourceWrapper,targetWrapper,res,"P1P1"); + CPPUNIT_ASSERT_EQUAL(8,(int)res.size()); + double res3D[8][28]= {{124999.999883775978, 245370.370390364464, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 203703.703634892299, 187500.000094145857, 0.0, 0.0, 4629.6296266718, 0.0, 215277.777751402784, 209722.222322299582, 0.0, 0.0, 0.0, 0.0, 104166.666590829205, 121296.296368812196, 0.0, 250000.000003472145}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 120370.370368827047, 0.0, 0.0, 38888.888897777797, 0.0, 0.0, 45370.3703701697596, 0.0, 0.0, 45370.3703701697596, 83333.3333263888926, 0.0}, + {0.0, 0.0, 0.0, 97222.2222222221753, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 97222.2222222221608, 0.0, 97222.2222222222044, 41666.6666666666642, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 277777.777787084982, 199074.074074073927, 0.0, 0.0, 0.0, 4629.62962962962774, 0.0, 321759.259254934732, 83333.3333333333139, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 4629.62962667180363, 0.0, 0.0, 251388.88888319055, 194444.444454861077, 0.0, 79629.6296194135939, 250000.000003472145, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 85185.1851851851534, 4629.62962962962774, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 118518.518518518511, 0.0, 41666.6666666666642, 83333.3333333333285, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 324074.07407629228, 0.0, 0.0, 0.0, 247685.185185184964, 6481.48148148147993, 0.0, 173611.11111196311, 0.0, 164814.814814814832, 0.0, 4629.62962962962865, 208333.33333418527, 0.0, 83333.3333333333285, 203703.703697273799, 249999.999999999767, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {125000.000000000015, 423611.111111110775, 134259.259259259241, 194444.444444444351, 164814.814814814745, 164351.851851851825, 203703.703703703592, 249999.999999999825, 0.0, 0.0, 0.0, 0.0, 6481.48148148147902, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 118518.518518518453, 0.0, 4629.62962962962956, 83333.3333333333139, 85185.1851851851825, 41666.6666666666642, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}}; + int i=0; + double sum = 0; + //cout.precision(18); + for(std::vector<std::map<int,double> >::const_iterator iter1=res.begin();iter1!=res.end();iter1++,i++) + { + //cout<< "res3D[" <<i<< "][]={"; + for(int j=0;j<28;j++) + { + std::map<int,double>::const_iterator iter2=(*iter1).find(j); + if(iter2!=(*iter1).end()) + { + //cout<< iter2->second<< ", "; + sum += iter2->second; + CPPUNIT_ASSERT_DOUBLES_EQUAL(res3D[i][j],(*iter2).second,1.e-5); + } + else + { + //cout << "0.0, "; + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.,res3D[i][j],1e-14); + } + } + //cout << "}" << endl; + } + //cout << "Sum = " << sum << endl; + CPPUNIT_ASSERT_DOUBLES_EQUAL(8000000,sum,1.e-5); + //clean-up + sourceMesh->decrRef(); + targetMesh->decrRef(); +} + +void MEDCouplingBasicsTestInterp::test3DInterpP1P1PL_1() +{ + MEDCouplingUMesh *sourceMesh=build3DSourceMesh_2(); + MEDCouplingUMesh *targetMesh=build3DTargetMesh_2(); + // + MEDCouplingNormalizedUnstructuredMesh<3,3> sourceWrapper(sourceMesh); + MEDCouplingNormalizedUnstructuredMesh<3,3> targetWrapper(targetMesh); + INTERP_KERNEL::Interpolation3D myInterpolator; + std::vector<std::map<int,double> > res; + myInterpolator.setPrecision(1e-12); + myInterpolator.setIntersectionType(INTERP_KERNEL::PointLocator); + myInterpolator.interpolateMeshes(sourceWrapper,targetWrapper,res,"P1P1"); + CPPUNIT_ASSERT_EQUAL(8,(int)res.size()); + CPPUNIT_ASSERT_DOUBLES_EQUAL(20.,res[0][24],1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(2.,res[1][26],1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[2][21],1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(24.,res[3][23],1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[4][14],1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(24.,res[5][17],1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(24.,res[6][7],1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[7][11],1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(97.,sumAll(res),1e-12); + //clean-up + sourceMesh->decrRef(); + targetMesh->decrRef(); +} + +void MEDCouplingBasicsTestInterp::test3DInterpP0P0Empty() +{ + MEDCouplingUMesh *sourceMesh=MEDCouplingUMesh::New(); + sourceMesh->setMeshDimension(2); + sourceMesh->allocateCells(0); + sourceMesh->finishInsertingCells(); + DataArrayDouble *myCoords=DataArrayDouble::New(); + myCoords->alloc(0,0); + sourceMesh->setCoords(myCoords); + myCoords->decrRef(); + MEDCouplingUMesh *targetMesh=MEDCouplingUMesh::New(); + targetMesh->setMeshDimension(2); + targetMesh->allocateCells(0); + targetMesh->finishInsertingCells(); + myCoords=DataArrayDouble::New(); + myCoords->alloc(0,2); + targetMesh->setCoords(myCoords); + myCoords->decrRef(); + MEDCouplingNormalizedUnstructuredMesh<2,2> sourceWrapper(sourceMesh); + MEDCouplingNormalizedUnstructuredMesh<2,2> targetWrapper(targetMesh); + INTERP_KERNEL::Interpolation2D myInterpolator; + std::vector<std::map<int,double> > res; + myInterpolator.setPrecision(1e-12); + myInterpolator.interpolateMeshes(sourceWrapper,targetWrapper,res,"P0P0"); + //clean up + sourceMesh->decrRef(); + targetMesh->decrRef(); +} + +void MEDCouplingBasicsTestInterp::testInterpolationCC() +{ + double arr1[3] = { 0/2., 1/2., 2/2. }; + double arr2[4] = { 0/3, 1/3., 2/3., 3/3. }; + MEDCouplingCMesh* mesh[2]; + for ( int i = 0; i < 2; ++i ) + { + const double* arr = i ? arr1 : arr2; + const int nb_coord = i ? 3 : 4; + DataArrayDouble* coords = DataArrayDouble::New(); + coords->useArray( arr, /*ownership=*/false, CPP_DEALLOC, nb_coord, 1 ); + + mesh[i] = MEDCouplingCMesh::New(); + mesh[i]->setCoords( coords, coords, coords ); + coords->decrRef(); + } + MEDCouplingNormalizedCartesianMesh<3> targetWrapper(mesh[1]); + MEDCouplingNormalizedCartesianMesh<3> sourceWrapper(mesh[0]); + CPPUNIT_ASSERT_EQUAL( 27,int( sourceWrapper.getNumberOfElements())); + CPPUNIT_ASSERT_EQUAL( 3, int( sourceWrapper.nbCellsAlongAxis(0))); + CPPUNIT_ASSERT_EQUAL( 3, int( sourceWrapper.nbCellsAlongAxis(1))); + CPPUNIT_ASSERT_EQUAL( 3, int( sourceWrapper.nbCellsAlongAxis(2))); + CPPUNIT_ASSERT_THROW( sourceWrapper.nbCellsAlongAxis(3), INTERP_KERNEL::Exception); + + INTERP_KERNEL::InterpolationCC myInterpolator; + std::vector<std::map<int,double> > res; + myInterpolator.interpolateMeshes(sourceWrapper,targetWrapper,res,"P0P0"); + + CPPUNIT_ASSERT_EQUAL(8,int( res.size())); + CPPUNIT_ASSERT_EQUAL(8,int( res[0].size())); + const double precis = 1e-7; + std::set<double> vals; + double sum = 0; + for ( int i = 0; i < (int)res.size(); ++i ) + for ( std::map<int,double>::iterator s_v = res[i].begin(); s_v != res[i].end(); ++s_v) + { + sum += s_v->second; + double vvv; +#ifdef WIN32 + double vv = s_v->second / precis; + if(vv>=0.0) + { + vvv = floor(vv+0.5); + } + else + { + vvv = ceil(vv-0.5); + } +#else + vvv = round( s_v->second / precis ); +#endif + vals.insert( precis * vvv ); + } + //cout << "tgt: " << i << " src: " << s_v->first << " - w: " << s_v->second << endl; + CPPUNIT_ASSERT_DOUBLES_EQUAL( 1.0, sum, precis ); + + std::set<double>::iterator v = vals.begin(); + CPPUNIT_ASSERT_EQUAL( 4, int( vals.size()) ); + CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.00462963, *v++, precis ); + CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.00925926, *v++, precis ); + CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.01851850, *v++, precis ); + CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.03703700, *v++, precis ); + + mesh[0]->decrRef(); + mesh[1]->decrRef(); +} + +void MEDCouplingBasicsTestInterp::testInterpolationCU1D() +{ + MEDCouplingCMesh* meshC = MEDCouplingCMesh::New(); + DataArrayDouble* coords = DataArrayDouble::New(); + double arr[4] = { -1/3., 1/3., 2/3., 4/3. }; + coords->useArray( arr, /*ownership=*/false, CPP_DEALLOC, 4, 1 ); + meshC->setCoords( coords ); + coords->decrRef(); + + MEDCouplingUMesh * meshU = buildCU1DMesh_U(); + + MEDCouplingNormalizedCartesianMesh<1> sourceWrapper(meshC); + MEDCouplingNormalizedUnstructuredMesh<1,1> targetWrapper(meshU); + INTERP_KERNEL::InterpolationCU myInterpolator; + std::vector<std::map<int,double> > res; + const double precis = 1e-13; + myInterpolator.setPrecision(precis); + myInterpolator.interpolateMeshes(sourceWrapper,targetWrapper,res,"P0P0"); + +// std::cout.precision(18); +// for ( int i = 0; i < (int)res.size(); ++i ) +// for ( std::map<int,double>::iterator s_v = res[i].begin(); s_v != res[i].end(); ++s_v) +// { +// std::cout << "CPPUNIT_ASSERT_DOUBLES_EQUAL( "<<s_v->second<<" ,res["<<i<<"]["<<s_v->first<<"],precis);"<<std::endl; +// } + + double sum = sumAll(res); + CPPUNIT_ASSERT_EQUAL(3,int( res.size())); + CPPUNIT_ASSERT_DOUBLES_EQUAL( 1, sum, precis ); + CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.03333333333333 ,res[1][0],precis); + CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.33333333333333 ,res[1][1],precis); + CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.08333333333333 ,res[1][2],precis); + CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.25000000000000 ,res[2][2],precis); + + meshC->decrRef(); + meshU->decrRef(); +} + +void MEDCouplingBasicsTestInterp::testInterpolationCU2D() +{ + MEDCouplingCMesh* meshC = MEDCouplingCMesh::New(); + DataArrayDouble* coords = DataArrayDouble::New(); + double arr[4] = { -1/3., 1/3., 2/3., 4/3. }; + coords->useArray( arr, /*ownership=*/false, CPP_DEALLOC, 4, 1 ); + meshC->setCoords( coords, coords ); + coords->decrRef(); + + MEDCouplingUMesh * meshU = buildCU2DMesh_U(); + + MEDCouplingNormalizedCartesianMesh<2> sourceWrapper(meshC); + MEDCouplingNormalizedUnstructuredMesh<2,2> targetWrapper(meshU); + INTERP_KERNEL::InterpolationCU myInterpolator; + std::vector<std::map<int,double> > res; + myInterpolator.setPrecision(1e-12); + myInterpolator.interpolateMeshes(sourceWrapper,targetWrapper,res,"P0P0"); + + const double precis = 1e-7; + double sum = sumAll(res); + CPPUNIT_ASSERT_EQUAL(5,int( res.size())); + CPPUNIT_ASSERT_DOUBLES_EQUAL( 1, sum, precis ); + CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.1111111 ,res[0][0],precis); + CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.0555556 ,res[0][1],precis); + CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.0555556 ,res[0][3],precis); + CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.0277778 ,res[0][4],precis); + CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.0555556 ,res[1][3],precis); + CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.0277778 ,res[1][4],precis); + CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.1111111 ,res[1][6],precis); + CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.0555556 ,res[1][7],precis); + CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.0277778 ,res[2][4],precis); + CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.0555556 ,res[2][5],precis); + CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.0555556 ,res[2][7],precis); + CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.1111111 ,res[2][8],precis); + CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.0416667 ,res[3][1],precis); + CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.0138889 ,res[3][2],precis); + CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.0277778 ,res[3][4],precis); + CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.0416667 ,res[3][5],precis); + CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.0138889 ,res[4][1],precis); + CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.0972222 ,res[4][2],precis); + CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.0138889 ,res[4][5],precis); + + std::vector<std::map<int,double> > resRev; + myInterpolator.interpolateMeshesRev(targetWrapper,sourceWrapper,resRev,"P0P0"); + + CPPUNIT_ASSERT_DOUBLES_EQUAL( res[0][0] ,resRev[0][0],precis); + CPPUNIT_ASSERT_DOUBLES_EQUAL( res[0][1] ,resRev[1][0],precis); + CPPUNIT_ASSERT_DOUBLES_EQUAL( res[3][1] ,resRev[1][3],precis); + CPPUNIT_ASSERT_DOUBLES_EQUAL( res[4][1] ,resRev[1][4],precis); + CPPUNIT_ASSERT_DOUBLES_EQUAL( res[3][2] ,resRev[2][3],precis); + CPPUNIT_ASSERT_DOUBLES_EQUAL( res[4][2] ,resRev[2][4],precis); + CPPUNIT_ASSERT_DOUBLES_EQUAL( res[0][3] ,resRev[3][0],precis); + CPPUNIT_ASSERT_DOUBLES_EQUAL( res[1][3] ,resRev[3][1],precis); + CPPUNIT_ASSERT_DOUBLES_EQUAL( res[0][4] ,resRev[4][0],precis); + CPPUNIT_ASSERT_DOUBLES_EQUAL( res[1][4] ,resRev[4][1],precis); + CPPUNIT_ASSERT_DOUBLES_EQUAL( res[2][4] ,resRev[4][2],precis); + CPPUNIT_ASSERT_DOUBLES_EQUAL( res[3][4] ,resRev[4][3],precis); + CPPUNIT_ASSERT_DOUBLES_EQUAL( res[2][5] ,resRev[5][2],precis); + CPPUNIT_ASSERT_DOUBLES_EQUAL( res[3][5] ,resRev[5][3],precis); + CPPUNIT_ASSERT_DOUBLES_EQUAL( res[4][5] ,resRev[5][4],precis); + CPPUNIT_ASSERT_DOUBLES_EQUAL( res[1][6] ,resRev[6][1],precis); + CPPUNIT_ASSERT_DOUBLES_EQUAL( res[1][7] ,resRev[7][1],precis); + CPPUNIT_ASSERT_DOUBLES_EQUAL( res[2][7] ,resRev[7][2],precis); + CPPUNIT_ASSERT_DOUBLES_EQUAL( res[2][8] ,resRev[8][2],precis); + + meshC->decrRef(); + meshU->decrRef(); +} + +void MEDCouplingBasicsTestInterp::testInterpolationCU3D() +{ + MEDCouplingCMesh* meshC = MEDCouplingCMesh::New(); + DataArrayDouble* coords = DataArrayDouble::New(); + double arr[4] = { -1/3., 1/3., 2/3., 4/3. }; + coords->useArray( arr, /*ownership=*/false, CPP_DEALLOC, 4, 1 ); + meshC->setCoords( coords, coords, coords ); + coords->decrRef(); + + MEDCouplingUMesh * meshU = buildCU3DMesh_U(); + + MEDCouplingNormalizedCartesianMesh<3> sourceWrapper(meshC); + MEDCouplingNormalizedUnstructuredMesh<3,3> targetWrapper(meshU); + INTERP_KERNEL::InterpolationCU myInterpolator; + std::vector<std::map<int,double> > res; + const double precis = 1e-13; + myInterpolator.setPrecision(precis); + myInterpolator.interpolateMeshes(sourceWrapper,targetWrapper,res,"P0P0"); + + double sum = sumAll(res); + CPPUNIT_ASSERT_EQUAL(8,int( res.size())); + CPPUNIT_ASSERT_DOUBLES_EQUAL( 1, sum, precis ); + CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.02700000000000 ,res[0][0],precis); + CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.00299999999999 ,res[1][0],precis); + CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.02999999999999 ,res[1][1],precis); + CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.03000000000000 ,res[1][2],precis); + CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.00300000000000 ,res[2][0],precis); + CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.02999999999999 ,res[2][3],precis); + CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.02999999999999 ,res[2][6],precis); + CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.00033333333333 ,res[3][0],precis); + CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.00333333333333 ,res[3][1],precis); + CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.00333333333333 ,res[3][2],precis); + CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.00333333333333 ,res[3][3],precis); + CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.03333333333333 ,res[3][4],precis); + CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.03333333333333 ,res[3][5],precis); + CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.00333333333333 ,res[3][6],precis); + CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.03333333333333 ,res[3][7],precis); + CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.03333333333333 ,res[3][8],precis); + CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.00299999999999 ,res[4][0],precis); + CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.02999999999999 ,res[4][9],precis); + CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.03000000000000 ,res[4][18],precis); + CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.00033333333333 ,res[5][0],precis); + CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.00333333333333 ,res[5][1],precis); + CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.00333333333333 ,res[5][2],precis); + CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.00333333333333 ,res[5][9],precis); + CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.03333333333333 ,res[5][10],precis); + CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.03333333333333 ,res[5][11],precis); + CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.00333333333333 ,res[5][18],precis); + CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.03333333333333 ,res[5][19],precis); + CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.03333333333333 ,res[5][20],precis); + CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.00033333333333 ,res[6][0],precis); + CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.00333333333333 ,res[6][3],precis); + CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.00333333333333 ,res[6][6],precis); + CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.00333333333333 ,res[6][9],precis); + CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.03333333333333 ,res[6][12],precis); + CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.03333333333333 ,res[6][15],precis); + CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.00333333333333 ,res[6][18],precis); + CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.03333333333333 ,res[6][21],precis); + CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.03333333333333 ,res[6][24],precis); + CPPUNIT_ASSERT_DOUBLES_EQUAL( 3.7037037037e-05 ,res[7][0],precis); + CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.00037037037037 ,res[7][1],precis); + CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.00037037037037 ,res[7][2],precis); + CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.00037037037037 ,res[7][3],precis); + CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.00370370370370 ,res[7][4],precis); + CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.00370370370370 ,res[7][5],precis); + CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.00037037037037 ,res[7][6],precis); + CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.00370370370370 ,res[7][7],precis); + CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.00370370370370 ,res[7][8],precis); + CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.00037037037037 ,res[7][9],precis); + CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.00370370370370 ,res[7][10],precis); + CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.00370370370370 ,res[7][11],precis); + CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.00370370370370 ,res[7][12],precis); + CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.03703703703703 ,res[7][13],precis); + CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.03703703703703 ,res[7][14],precis); + CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.00370370370370 ,res[7][15],precis); + CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.03703703703703 ,res[7][16],precis); + CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.03703703703703 ,res[7][17],precis); + CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.00037037037037 ,res[7][18],precis); + CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.00370370370370 ,res[7][19],precis); + CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.00370370370370 ,res[7][20],precis); + CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.00370370370370 ,res[7][21],precis); + CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.03703703703703 ,res[7][22],precis); + CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.03703703703703 ,res[7][23],precis); + CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.00370370370370 ,res[7][24],precis); + CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.03703703703703 ,res[7][25],precis); + CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.03703703703703 ,res[7][26],precis); + + + meshC->decrRef(); + meshU->decrRef(); +} + +void MEDCouplingBasicsTestInterp::test2DInterpP0IntegralUniform() +{ + MEDCouplingUMesh *targetMesh=build2DTargetMesh_1(); + // + MEDCouplingNormalizedUnstructuredMesh<2,2> targetWrapper(targetMesh); + INTERP_KERNEL::Interpolation2D myInterpolator; + std::vector<std::map<int,double> > res; + CPPUNIT_ASSERT_EQUAL(5,myInterpolator.toIntegralUniform(targetWrapper,res,"P0")); + CPPUNIT_ASSERT_EQUAL(1,(int)res.size()); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.25,res[0][0],1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.125,res[0][1],1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.125,res[0][2],1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.25,res[0][3],1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.25,res[0][4],1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,sumAll(res),1e-12); + res.clear(); + CPPUNIT_ASSERT_EQUAL(1,myInterpolator.fromIntegralUniform(targetWrapper,res,"P0")); + CPPUNIT_ASSERT_EQUAL(5,(int)res.size()); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.25,res[0][0],1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.125,res[1][0],1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.125,res[2][0],1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.25,res[3][0],1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.25,res[4][0],1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,sumAll(res),1e-12); + res.clear(); + targetMesh->decrRef(); + // + targetMesh=build2DTargetMeshPerm_1(); + MEDCouplingNormalizedUnstructuredMesh<2,2> targetWrapper2(targetMesh); + INTERP_KERNEL::Interpolation2D myInterpolator2; + CPPUNIT_ASSERT(myInterpolator2.getMeasureAbsStatus()); + CPPUNIT_ASSERT_EQUAL(5,myInterpolator2.toIntegralUniform(targetWrapper2,res,"P0")); + CPPUNIT_ASSERT_EQUAL(1,(int)res.size()); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.25,res[0][0],1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.125,res[0][1],1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.125,res[0][2],1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.25,res[0][3],1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.25,res[0][4],1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,sumAll(res),1e-12); + res.clear(); + myInterpolator2.setMeasureAbsStatus(false); + CPPUNIT_ASSERT(!myInterpolator2.getMeasureAbsStatus()); + CPPUNIT_ASSERT_EQUAL(5,myInterpolator2.toIntegralUniform(targetWrapper2,res,"P0")); + CPPUNIT_ASSERT_EQUAL(1,(int)res.size()); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.25,res[0][0],1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(-0.125,res[0][1],1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.125,res[0][2],1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.25,res[0][3],1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.25,res[0][4],1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.75,sumAll(res),1e-12); + targetMesh->decrRef(); +} + +void MEDCouplingBasicsTestInterp::test3DSurfInterpP0IntegralUniform() +{ + MEDCouplingUMesh *targetMesh=build3DSurfTargetMesh_1(); + INTERP_KERNEL::Interpolation3DSurf myInterpolator; + MEDCouplingNormalizedUnstructuredMesh<3,2> targetWrapper(targetMesh); + std::vector<std::map<int,double> > res; + CPPUNIT_ASSERT_EQUAL(5,myInterpolator.toIntegralUniform(targetWrapper,res,"P0")); + CPPUNIT_ASSERT_EQUAL(1,(int)res.size()); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.25*sqrt(2.),res[0][0],1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.125*sqrt(2.),res[0][1],1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.125*sqrt(2.),res[0][2],1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.25*sqrt(2.),res[0][3],1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.25*sqrt(2.),res[0][4],1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(1.*sqrt(2.),sumAll(res),1e-12); + res.clear(); + CPPUNIT_ASSERT_EQUAL(1,myInterpolator.fromIntegralUniform(targetWrapper,res,"P0")); + CPPUNIT_ASSERT_EQUAL(5,(int)res.size()); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.25*sqrt(2.),res[0][0],1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.125*sqrt(2.),res[1][0],1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.125*sqrt(2.),res[2][0],1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.25*sqrt(2.),res[3][0],1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.25*sqrt(2.),res[4][0],1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(1.*sqrt(2.),sumAll(res),1e-12); + targetMesh->decrRef(); +} + +void MEDCouplingBasicsTestInterp::test3DInterpP0IntegralUniform() +{ + MEDCouplingUMesh *targetMesh=build3DTargetMesh_1(); + INTERP_KERNEL::Interpolation3D myInterpolator; + MEDCouplingNormalizedUnstructuredMesh<3,3> targetWrapper(targetMesh); + std::vector<std::map<int,double> > res; + CPPUNIT_ASSERT_EQUAL(8,myInterpolator.toIntegralUniform(targetWrapper,res,"P0")); + CPPUNIT_ASSERT_EQUAL(1,(int)res.size()); + CPPUNIT_ASSERT_DOUBLES_EQUAL(125000.,res[0][0],1e-6); + CPPUNIT_ASSERT_DOUBLES_EQUAL(375000.,res[0][1],1e-6); + CPPUNIT_ASSERT_DOUBLES_EQUAL(375000.,res[0][2],1e-6); + CPPUNIT_ASSERT_DOUBLES_EQUAL(1125000.,res[0][3],1e-6); + CPPUNIT_ASSERT_DOUBLES_EQUAL(375000.,res[0][4],1e-6); + CPPUNIT_ASSERT_DOUBLES_EQUAL(1125000.,res[0][5],1e-6); + CPPUNIT_ASSERT_DOUBLES_EQUAL(1125000.,res[0][6],1e-6); + CPPUNIT_ASSERT_DOUBLES_EQUAL(3375000.,res[0][7],1e-6); + CPPUNIT_ASSERT_DOUBLES_EQUAL(8000000.,sumAll(res),1e-6); + res.clear(); + CPPUNIT_ASSERT_EQUAL(1,myInterpolator.fromIntegralUniform(targetWrapper,res,"P0")); + CPPUNIT_ASSERT_EQUAL(8,(int)res.size()); + CPPUNIT_ASSERT_DOUBLES_EQUAL(125000.,res[0][0],1e-6); + CPPUNIT_ASSERT_DOUBLES_EQUAL(375000.,res[1][0],1e-6); + CPPUNIT_ASSERT_DOUBLES_EQUAL(375000.,res[2][0],1e-6); + CPPUNIT_ASSERT_DOUBLES_EQUAL(1125000.,res[3][0],1e-6); + CPPUNIT_ASSERT_DOUBLES_EQUAL(375000.,res[4][0],1e-6); + CPPUNIT_ASSERT_DOUBLES_EQUAL(1125000.,res[5][0],1e-6); + CPPUNIT_ASSERT_DOUBLES_EQUAL(1125000.,res[6][0],1e-6); + CPPUNIT_ASSERT_DOUBLES_EQUAL(3375000.,res[7][0],1e-6); + CPPUNIT_ASSERT_DOUBLES_EQUAL(8000000.,sumAll(res),1e-6); + res.clear(); + targetMesh->decrRef(); +} + +void MEDCouplingBasicsTestInterp::test2DInterpP1IntegralUniform() +{ + MEDCouplingUMesh *targetMesh=build2DSourceMesh_1(); + // + MEDCouplingNormalizedUnstructuredMesh<2,2> targetWrapper(targetMesh); + INTERP_KERNEL::Interpolation2D myInterpolator; + std::vector<std::map<int,double> > res; + CPPUNIT_ASSERT_EQUAL(4,myInterpolator.toIntegralUniform(targetWrapper,res,"P1")); + CPPUNIT_ASSERT_EQUAL(1,(int)res.size()); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.33333333333333331,res[0][0],1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.16666666666666666,res[0][1],1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.16666666666666666,res[0][2],1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.33333333333333331,res[0][3],1e-12); + res.clear(); + CPPUNIT_ASSERT_EQUAL(1,myInterpolator.fromIntegralUniform(targetWrapper,res,"P1")); + CPPUNIT_ASSERT_EQUAL(4,(int)res.size()); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.33333333333333331,res[0][0],1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.16666666666666666,res[1][0],1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.16666666666666666,res[2][0],1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.33333333333333331,res[3][0],1e-12); + res.clear(); + targetMesh->decrRef(); +} + +void MEDCouplingBasicsTestInterp::test3DInterpP1IntegralUniform() +{ + MEDCouplingUMesh *sourceMesh=build3DSourceMesh_1(); + // + MEDCouplingNormalizedUnstructuredMesh<3,3> targetWrapper(sourceMesh); + INTERP_KERNEL::Interpolation3D myInterpolator; + std::vector<std::map<int,double> > res; + CPPUNIT_ASSERT_EQUAL(9,myInterpolator.toIntegralUniform(targetWrapper,res,"P1")); + CPPUNIT_ASSERT_EQUAL(1,(int)res.size()); + CPPUNIT_ASSERT_DOUBLES_EQUAL(833333.333333333,res[0][0],1e-6); + CPPUNIT_ASSERT_DOUBLES_EQUAL(833333.333333333,res[0][1],1e-6); + CPPUNIT_ASSERT_DOUBLES_EQUAL(500000.,res[0][2],1e-6); + CPPUNIT_ASSERT_DOUBLES_EQUAL(833333.333333333,res[0][3],1e-6); + CPPUNIT_ASSERT_DOUBLES_EQUAL(833333.333333333,res[0][4],1e-6); + CPPUNIT_ASSERT_DOUBLES_EQUAL(500000.,res[0][5],1e-6); + CPPUNIT_ASSERT_DOUBLES_EQUAL(833333.333333333,res[0][6],1e-6); + CPPUNIT_ASSERT_DOUBLES_EQUAL(833333.333333333,res[0][7],1e-6); + CPPUNIT_ASSERT_DOUBLES_EQUAL(2000000.,res[0][8],1e-6); + CPPUNIT_ASSERT_DOUBLES_EQUAL(8000000.,sumAll(res),1e-6); + res.clear(); + CPPUNIT_ASSERT_EQUAL(1,myInterpolator.fromIntegralUniform(targetWrapper,res,"P1")); + CPPUNIT_ASSERT_EQUAL(9,(int)res.size()); + CPPUNIT_ASSERT_DOUBLES_EQUAL(833333.333333333,res[0][0],1e-6); + CPPUNIT_ASSERT_DOUBLES_EQUAL(833333.333333333,res[1][0],1e-6); + CPPUNIT_ASSERT_DOUBLES_EQUAL(500000.,res[2][0],1e-6); + CPPUNIT_ASSERT_DOUBLES_EQUAL(833333.333333333,res[3][0],1e-6); + CPPUNIT_ASSERT_DOUBLES_EQUAL(833333.333333333,res[4][0],1e-6); + CPPUNIT_ASSERT_DOUBLES_EQUAL(500000.,res[5][0],1e-6); + CPPUNIT_ASSERT_DOUBLES_EQUAL(833333.333333333,res[6][0],1e-6); + CPPUNIT_ASSERT_DOUBLES_EQUAL(833333.333333333,res[7][0],1e-6); + CPPUNIT_ASSERT_DOUBLES_EQUAL(2000000.,res[8][0],1e-6); + CPPUNIT_ASSERT_DOUBLES_EQUAL(8000000.,sumAll(res),1e-6); + sourceMesh->decrRef(); +} + +void MEDCouplingBasicsTestInterp::test2DInterpP1P0Bary_1() +{ + MEDCouplingUMesh *sourceMesh=build2DSourceMesh_1(); + MEDCouplingUMesh *targetMesh=build2DTargetMesh_1(); + // + MEDCouplingNormalizedUnstructuredMesh<2,2> sourceWrapper(sourceMesh); + MEDCouplingNormalizedUnstructuredMesh<2,2> targetWrapper(targetMesh); + INTERP_KERNEL::Interpolation2D myInterpolator; + std::vector<std::map<int,double> > res; + INTERP_KERNEL::IntersectionType types[2]={INTERP_KERNEL::Barycentric,INTERP_KERNEL::BarycentricGeo2D}; + for(int i=0;i<2;i++) + { + myInterpolator.setPrecision(1e-12); + myInterpolator.setIntersectionType(types[i]); + myInterpolator.interpolateMeshes(sourceWrapper,targetWrapper,res,"P1P0"); + CPPUNIT_ASSERT_EQUAL(5,(int)res.size()); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.16666666666666669,res[0][0],1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.020833333333333343,res[0][1],1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.020833333333333343,res[0][2],1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.041666666666666664,res[0][3],1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.041666666666666664,res[1][0],1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.0625,res[1][1],1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.020833333333333343,res[1][3],1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.020833333333333343,res[2][0],1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.0625,res[2][1],1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.041666666666666664,res[2][3],1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.0625,res[3][0],1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.125,res[3][2],1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.0625,res[3][3],1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.041666666666666664,res[4][0],1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.020833333333333343,res[4][1],1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.020833333333333343,res[4][2],1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.16666666666666666,res[4][3],1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,sumAll(res),1e-12); + res.clear(); + } + //clean up + sourceMesh->decrRef(); + targetMesh->decrRef(); +} + +void MEDCouplingBasicsTestInterp::test3DSurfInterpP1P0Bary_1() +{ + MEDCouplingUMesh *sourceMesh=build3DSurfSourceMesh_1(); + MEDCouplingUMesh *targetMesh=build3DSurfTargetMesh_1(); + // + MEDCouplingNormalizedUnstructuredMesh<3,2> sourceWrapper(sourceMesh); + MEDCouplingNormalizedUnstructuredMesh<3,2> targetWrapper(targetMesh); + INTERP_KERNEL::Interpolation3DSurf myInterpolator; + std::vector<std::map<int,double> > res; + INTERP_KERNEL::IntersectionType types[2]={INTERP_KERNEL::Barycentric,INTERP_KERNEL::BarycentricGeo2D}; + for(int i=0;i<2;i++) + { + myInterpolator.setPrecision(1e-12); + myInterpolator.setIntersectionType(types[i]); + myInterpolator.interpolateMeshes(sourceWrapper,targetWrapper,res,"P1P0"); + CPPUNIT_ASSERT_EQUAL(5,(int)res.size()); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.16666666666666669*sqrt(2.),res[0][0],1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.020833333333333343*sqrt(2.),res[0][1],1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.020833333333333343*sqrt(2.),res[0][2],1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.041666666666666664*sqrt(2.),res[0][3],1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.041666666666666664*sqrt(2.),res[1][0],1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.0625*sqrt(2.),res[1][1],1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.020833333333333343*sqrt(2.),res[1][3],1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.020833333333333343*sqrt(2.),res[2][0],1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.0625*sqrt(2.),res[2][1],1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.041666666666666664*sqrt(2.),res[2][3],1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.0625*sqrt(2.),res[3][0],1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.125*sqrt(2.),res[3][2],1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.0625*sqrt(2.),res[3][3],1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.041666666666666664*sqrt(2.),res[4][0],1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.020833333333333343*sqrt(2.),res[4][1],1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.020833333333333343*sqrt(2.),res[4][2],1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.16666666666666666*sqrt(2.),res[4][3],1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(1.*sqrt(2.),sumAll(res),1e-12); + res.clear(); + } + //clean up + sourceMesh->decrRef(); + targetMesh->decrRef(); +} + +#include <iomanip> +void MEDCouplingBasicsTestInterp::test3DInterpP1P0Bary_1() +{ + MEDCouplingUMesh *sourceMesh=build3DSourceMesh_2(); + MEDCouplingUMesh *targetMesh=build3DTargetMesh_2(); + // + MEDCouplingNormalizedUnstructuredMesh<3,3> sourceWrapper(sourceMesh); + MEDCouplingNormalizedUnstructuredMesh<3,3> targetWrapper(targetMesh); + INTERP_KERNEL::Interpolation3D myInterpolator; + std::vector<std::map<int,double> > res; + myInterpolator.setPrecision(1e-12); + myInterpolator.setIntersectionType(INTERP_KERNEL::Barycentric); + myInterpolator.interpolateMeshes(sourceWrapper,targetWrapper,res,"P1P0"); + CPPUNIT_ASSERT_EQUAL(5,(int)res.size()); + + double res3D[5][28]={{104166.66658918398, 885416.666685817763, 135416.666666666541, 36458.3333333335031, 31249.9999999999018, 145833.333333333256, 41666.6666666667516, 124999.999999999971, 177083.333326388849, 0.0, 31249.9999999999636, 0.0, 41666.666620792399, 159722.22229009436, 0.0, 0.0, 41666.6666631944681, 125000, 43499.2283723790752, 164351.851924000395, 36458.3333372396883, 0.0, 0.0, 125000.000001736029, 34722.2221800900952, 13599.5370788455439, 0.0, 167438.27159690368}, + {0.0, 41666.6664479170649, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 125000.000161457952, 0.0, 0.0, 0.0, 0.0, 111111.11112005508, 0.0, 0.0, 291666.666656249959, 41666.6666666666933, 6944.4444415638809, 270833.333520485845, 0.0, 0.0, 124999.999989583303, 41666.6665798612958, 20833.3333186342825, 145833.333354303701, 83333.3333263888198, 27777.7777501651799}, + {0.0, 93750.0000000000728, 125000.000000000058, 0.0, 0.0, 72916.666666666526, 291666.666666666628, 41666.6666666667152, 197916.66666666657, 166666.666666666802, 218750.000000000116, 41666.6666666665697, 0.0, 0.0, 0.0, 0.0, 0.0, 41666.6666666666861, 0.0, 0.0, 0.0, 0.0, 0.0, 41666.6666666666642, 0.0, 0.0, 0.0, 0.0}, + {72916.6666484848247, 82465.2777799315081, 0.0, 0.0, 217447.916666666686, 197916.666666666802, 0.0, 41666.6666666666715, 0.0, 0.0, 0.0, 0.0, 290364.583310396119, 125000.000018181803, 41666.6666666666351, 166666.666666666599, 0.0, 41666.6666666665551, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 27777.7777734705051, 0.0, 0.0, 27777.7778028684952}, + {72916.6666461071727, 172309.027782170655, 70312.5000000000437, 253906.250000000029, 0.0, 0.0, 0.0, 41666.666666666657, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 258246.527775988478, 71180.5555571812583, 253906.250006944378, 41666.6666666666861, 0.0, 41666.6666649305407, 20833.3333186342534, 6944.44445267237552, 0.0, 27777.7777953707919}}; + + double sum = 0; + int i=0; + for(std::vector<std::map<int,double> >::const_iterator iter1=res.begin();iter1!=res.end();iter1++,i++) + { + for(int j=0;j<28;j++) + { + std::map<int,double>::const_iterator iter2=(*iter1).find(j); + if(iter2!=(*iter1).end()) + { + sum += iter2->second; + CPPUNIT_ASSERT_DOUBLES_EQUAL(res3D[i][j],(*iter2).second,1.e-5); + } + else + { + CPPUNIT_ASSERT_DOUBLES_EQUAL(0.,res3D[i][j],1e-14); + } + } + } + CPPUNIT_ASSERT_DOUBLES_EQUAL(8000000,sum,1.e-5); + //clean up + sourceMesh->decrRef(); + targetMesh->decrRef(); +} + +void MEDCouplingBasicsTestInterp::test3DTo1DInterpP0P0PL_1() +{ + MEDCouplingUMesh *sourceMesh=build3DTargetMesh_1(); + MEDCouplingUMesh *targetMesh=build1DTargetMesh_1(); + // + MEDCouplingNormalizedUnstructuredMesh<3,3> sourceWrapper(sourceMesh); + MEDCouplingNormalizedUnstructuredMesh<3,3> targetWrapper(targetMesh); + INTERP_KERNEL::Interpolation3D myInterpolator; + std::vector<std::map<int,double> > res; + myInterpolator.setPrecision(1e-12); + myInterpolator.setIntersectionType(INTERP_KERNEL::PointLocator); + myInterpolator.interpolateMeshes(sourceWrapper,targetWrapper,res,"P0P0"); + CPPUNIT_ASSERT_EQUAL(8,(int)res.size()); + CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[0][0],1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[1][4],1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[2][1],1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[3][5],1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[4][2],1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[5][6],1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[6][3],1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(1.,res[7][7],1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(8.,sumAll(res),1e-12); + // + sourceMesh->decrRef(); + targetMesh->decrRef(); +} + +void MEDCouplingBasicsTestInterp::test1DInterp_1() +{ + // c1 c0 c2 - pay attention to cell order! + // S: o---o------o---o + // T: o---o------o---o + // n0 n1 n2 n3 + // + // ---+---+------+---+---> X + // 0. 1. 3. 4. + MEDCouplingUMesh *sourceMesh=build1DMesh(0); + MEDCouplingUMesh *targetMesh=build1DMesh(0.5); + // + MEDCouplingNormalizedUnstructuredMesh<1,1> sourceWrapper(sourceMesh); + MEDCouplingNormalizedUnstructuredMesh<1,1> targetWrapper(targetMesh); + INTERP_KERNEL::Interpolation1D myInterpolator; + const double precis = 1e-13; + myInterpolator.setPrecision(precis); + + // P0P0 + std::vector<std::map<int,double> > res; + myInterpolator.interpolateMeshes(sourceWrapper,targetWrapper,res,"P0P0"); + CPPUNIT_ASSERT_EQUAL( 3, int( res.size()) ); + CPPUNIT_ASSERT_DOUBLES_EQUAL( 1.5, res[0][0], precis); + CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.5, res[0][2], precis); + CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.5, res[1][0], precis); + CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.5, res[1][1], precis); + CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.5, res[2][2], precis); + CPPUNIT_ASSERT_DOUBLES_EQUAL( 3.5, sumAll(res), precis); + + // P1P0 + res.clear(); + myInterpolator.interpolateMeshes(sourceWrapper,targetWrapper,res,"P1P0"); + CPPUNIT_ASSERT_EQUAL( 3, int( res.size()) ); + CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.5, res[0][1], precis); + CPPUNIT_ASSERT_DOUBLES_EQUAL( 1.5, res[0][2], precis); + CPPUNIT_ASSERT_DOUBLES_EQUAL( 1.0, res[1][1], precis); + CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.5, res[2][3], precis); + CPPUNIT_ASSERT_DOUBLES_EQUAL( 3.5, sumAll(res), precis); + + // P0P1 + res.clear(); + myInterpolator.interpolateMeshes(sourceWrapper,targetWrapper,res,"P0P1"); + + CPPUNIT_ASSERT_EQUAL( 4, int( res.size()) ); + CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.5, res[0][1], precis); + CPPUNIT_ASSERT_DOUBLES_EQUAL( 1.5, res[1][0], precis); + CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.5, res[2][0], precis); + CPPUNIT_ASSERT_DOUBLES_EQUAL( 1.0, res[2][2], precis); + CPPUNIT_ASSERT_DOUBLES_EQUAL( 3.5, sumAll(res), precis); + + // P1P1 + res.clear(); + myInterpolator.interpolateMeshes(sourceWrapper,targetWrapper,res,"P1P1"); + CPPUNIT_ASSERT_EQUAL( 4, int( res.size()) ); + CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.5, res[0][1], precis); + CPPUNIT_ASSERT_DOUBLES_EQUAL( 1.0, res[1][1], precis); + CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.5, res[1][2], precis); + CPPUNIT_ASSERT_DOUBLES_EQUAL( 1.0, res[2][2], precis); + CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.5, res[2][3], precis); + CPPUNIT_ASSERT_DOUBLES_EQUAL( 3.5, sumAll(res), precis); + + sourceMesh->decrRef(); + targetMesh->decrRef(); +} + +void MEDCouplingBasicsTestInterp::test2DCurveInterpP0P0_1() +{ + // coincident meshes + MEDCouplingUMesh *sourceMesh=build2DCurveMesh(0,0); + MEDCouplingUMesh *targetMesh=build2DCurveMesh(0,0); + // + MEDCouplingNormalizedUnstructuredMesh<2,1> sourceWrapper(sourceMesh); + MEDCouplingNormalizedUnstructuredMesh<2,1> targetWrapper(targetMesh); + INTERP_KERNEL::Interpolation2DCurve myInterpolator; + const double precis = 1e-13; + myInterpolator.setPrecision(precis); + std::vector<std::map<int,double> > res; + myInterpolator.interpolateMeshes(sourceWrapper,targetWrapper,res,"P0P0"); + + CPPUNIT_ASSERT_EQUAL( 2, int( res.size()) ); + CPPUNIT_ASSERT_DOUBLES_EQUAL( sqrt(2.),res[0][0], precis); + CPPUNIT_ASSERT_DOUBLES_EQUAL( 1., res[1][1], precis); + CPPUNIT_ASSERT_DOUBLES_EQUAL( 1.+sqrt(2.), sumAll(res), precis); + + sourceMesh->decrRef(); + targetMesh->decrRef(); +} + +void MEDCouplingBasicsTestInterp::test2DCurveInterpP0P0_2() +{ + // equal meshes shifted one from another along X by 0.5 + MEDCouplingUMesh *sourceMesh=build2DCurveMesh(0.5,0); + MEDCouplingUMesh *targetMesh=build2DCurveMesh(0,0); + // + MEDCouplingNormalizedUnstructuredMesh<2,1> sourceWrapper(sourceMesh); + MEDCouplingNormalizedUnstructuredMesh<2,1> targetWrapper(targetMesh); + INTERP_KERNEL::Interpolation2DCurve myInterpolator; + const double precis = 1e-13; + myInterpolator.setPrecision(precis); + myInterpolator.setMedianPlane(1.);// median line on target + std::vector<std::map<int,double> > res; + myInterpolator.interpolateMeshes(sourceWrapper,targetWrapper,res,"P0P0"); + + double tolInters = myInterpolator.getBoundingBoxAdjustmentAbs() * sqrt(2.); + CPPUNIT_ASSERT_EQUAL( 2, int( res.size()) ); + CPPUNIT_ASSERT_DOUBLES_EQUAL( 0,res[0][0], precis); + CPPUNIT_ASSERT_DOUBLES_EQUAL( tolInters,res[0][1], precis); + CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.5, res[1][1], precis); + CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.5+tolInters, sumAll(res), precis); + + sourceMesh->decrRef(); + targetMesh->decrRef(); +} + +void MEDCouplingBasicsTestInterp::test2DCurveInterpP0P1_1() +{ + // coincident meshes + MEDCouplingUMesh *sourceMesh=build2DCurveMesh(0,0); + MEDCouplingUMesh *targetMesh=build2DCurveMesh(0,0); + // + MEDCouplingNormalizedUnstructuredMesh<2,1> sourceWrapper(sourceMesh); + MEDCouplingNormalizedUnstructuredMesh<2,1> targetWrapper(targetMesh); + INTERP_KERNEL::Interpolation2DCurve myInterpolator; + const double precis = 1e-13; + myInterpolator.setPrecision(precis); + std::vector<std::map<int,double> > res; + myInterpolator.interpolateMeshes(sourceWrapper,targetWrapper,res,"P0P1"); + + const double len1 = 1., len0 = sqrt(2.); + CPPUNIT_ASSERT_EQUAL( 3, int( res.size()) ); + CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.5*len1, res[0][1], precis); + CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.5*len0, res[1][0], precis); + CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.5*len1, res[1][1], precis); + CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.5*len0, res[2][0], precis); + CPPUNIT_ASSERT_DOUBLES_EQUAL( len0+len1, sumAll(res), precis); + + sourceMesh->decrRef(); + targetMesh->decrRef(); +} + +void MEDCouplingBasicsTestInterp::test2DCurveInterpP1P0_1() +{ + // coincident meshes + MEDCouplingUMesh *sourceMesh=build2DCurveMesh(0,0); + MEDCouplingUMesh *targetMesh=build2DCurveMesh(0,0); + // + MEDCouplingNormalizedUnstructuredMesh<2,1> sourceWrapper(sourceMesh); + MEDCouplingNormalizedUnstructuredMesh<2,1> targetWrapper(targetMesh); + INTERP_KERNEL::Interpolation2DCurve myInterpolator; + const double precis = 1e-13; + myInterpolator.setPrecision(precis); + std::vector<std::map<int,double> > res; + myInterpolator.interpolateMeshes(sourceWrapper,targetWrapper,res,"P1P0"); + + const double len1 = 1., len0 = sqrt(2.); + CPPUNIT_ASSERT_EQUAL( 2, int( res.size()) ); + CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.5*len1, res[1][0], precis); + CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.5*len0, res[0][1], precis); + CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.5*len1, res[1][1], precis); + CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.5*len0, res[0][2], precis); + CPPUNIT_ASSERT_DOUBLES_EQUAL( len0+len1, sumAll(res), precis); + + sourceMesh->decrRef(); + targetMesh->decrRef(); +} + +void MEDCouplingBasicsTestInterp::test2DCurveInterpP1P1_1() +{ + // coincident meshes + MEDCouplingUMesh *sourceMesh=build2DCurveMesh(0,0); + MEDCouplingUMesh *targetMesh=build2DCurveMesh(0,0); + // + MEDCouplingNormalizedUnstructuredMesh<2,1> sourceWrapper(sourceMesh); + MEDCouplingNormalizedUnstructuredMesh<2,1> targetWrapper(targetMesh); + INTERP_KERNEL::Interpolation2DCurve myInterpolator; + const double precis = 1e-13; + myInterpolator.setPrecision(precis); + std::vector<std::map<int,double> > res; + myInterpolator.interpolateMeshes(sourceWrapper,targetWrapper,res,"P1P1"); + + const double len1 = 1., len0 = sqrt(2.); + CPPUNIT_ASSERT_EQUAL( 3, int( res.size()) ); + CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.5*len1, res[0][0], precis); + CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.5*(len0+len1), res[1][1], precis); + CPPUNIT_ASSERT_DOUBLES_EQUAL( 0.5*len0, res[2][2], precis); + CPPUNIT_ASSERT_DOUBLES_EQUAL( len0+len1, sumAll(res), precis); + + sourceMesh->decrRef(); + targetMesh->decrRef(); +} + +void MEDCouplingBasicsTestInterp::test2D1DBasicInterpP0P0() +{ + MEDCouplingUMesh *sourceMesh=build2D1DSourceMesh(); + MEDCouplingUMesh *targetMesh=build2D1DTargetMesh(); + + MEDCouplingNormalizedUnstructuredMesh<2,2> sourceWrapper(sourceMesh); + MEDCouplingNormalizedUnstructuredMesh<2,2> targetWrapper(targetMesh); + INTERP_KERNEL::Interpolation2D1D myInterpolator; + myInterpolator.setPrecision(1e-12); + myInterpolator.setIntersectionType(INTERP_KERNEL::Geometric2D); + std::vector<std::map<int,double> > matrix; + myInterpolator.interpolateMeshes(sourceWrapper,targetWrapper,matrix,"P0P0"); + + CPPUNIT_ASSERT_EQUAL(2,(int)matrix.size()); + + CPPUNIT_ASSERT_DOUBLES_EQUAL(3., matrix[0][0],1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0., matrix[0][1],1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0., matrix[0][2],1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(8., matrix[0][3],1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0., matrix[0][4],1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(5., matrix[0][5],1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(6., matrix[0][6],1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0., matrix[0][7],1e-12); + + CPPUNIT_ASSERT_DOUBLES_EQUAL(0., matrix[1][0],1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0., matrix[1][1],1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0., matrix[1][2],1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(4., matrix[1][3],1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(5., matrix[1][4],1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0., matrix[1][5],1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(6., matrix[1][6],1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(3., matrix[1][7],1e-12); + + INTERP_KERNEL::Interpolation3D2D::DuplicateFacesType duplicateFaces = myInterpolator.retrieveDuplicateFaces(); + CPPUNIT_ASSERT_EQUAL(1,(int)duplicateFaces.size()); + + INTERP_KERNEL::Interpolation3D2D::DuplicateFacesType correctDuplicateFaces; + std::set<int> face6; + face6.insert(0); + face6.insert(1); + correctDuplicateFaces[6] = face6; + + CPPUNIT_ASSERT(correctDuplicateFaces == duplicateFaces); + + //clean up + sourceMesh->decrRef(); + targetMesh->decrRef(); +} + +void MEDCouplingBasicsTestInterp::test2D1DSegQuadInterpP0P0_1() +{ + MEDCouplingUMesh *sourceMesh=build2D1DSegSourceMesh(); + MEDCouplingUMesh *targetMesh=build2D1DQuadTargetMesh(); + test2D1DMeshesIntersection(sourceMesh, targetMesh, 16., 0, 4); +} + +void MEDCouplingBasicsTestInterp::test2D1DSegQuadInterpP0P0_2() +{ + const double shiftX = 3.; + MEDCouplingUMesh *sourceMesh=build2D1DSegSourceMesh(shiftX); + MEDCouplingUMesh *targetMesh=build2D1DQuadTargetMesh(); + test2D1DMeshesIntersection(sourceMesh, targetMesh, 2. * 16., 4, 2 * 4); +} + +void MEDCouplingBasicsTestInterp::test2D1DSegQuadInterpP0P0_3() +{ + const double shiftX = 1.5; + const double inclinationX = 3.; + MEDCouplingUMesh *sourceMesh=build2D1DSegSourceMesh(shiftX, inclinationX); + MEDCouplingUMesh *targetMesh=build2D1DQuadTargetMesh(inclinationX); + test2D1DMeshesIntersection(sourceMesh, targetMesh, 20., 0, 4); +} + +void MEDCouplingBasicsTestInterp::test2D1DSegQuadInterpP0P0_4() +{ + const double shiftX = 3.; + const double inclinationX = 3.; + MEDCouplingUMesh *sourceMesh=build2D1DSegSourceMesh(shiftX, inclinationX); + MEDCouplingUMesh *targetMesh=build2D1DQuadTargetMesh(inclinationX); + test2D1DMeshesIntersection(sourceMesh, targetMesh, 2. * 20., 4, 2 * 4); +} + +void MEDCouplingBasicsTestInterp::test2D1DSegQuadInterpP0P0_5() +{ + const double shiftX = 9.; + const double inclinationX = 3.; + MEDCouplingUMesh *sourceMesh=build2D1DSegSourceMesh(shiftX); + MEDCouplingUMesh *targetMesh=build2D1DQuadTargetMesh(inclinationX); + test2D1DMeshesIntersection(sourceMesh, targetMesh, 12., 0, 3); +} + +void MEDCouplingBasicsTestInterp::test2D1DSegQuadInterpP0P0_6() +{ + const double shiftX = 9.; + const double inclinationX = 3.; + MEDCouplingUMesh *sourceMesh=build2D1DSegSourceMesh(shiftX, inclinationX); + MEDCouplingUMesh *targetMesh=build2D1DQuadTargetMesh(); + test2D1DMeshesIntersection(sourceMesh, targetMesh, 10., 0, 2); +} + +void MEDCouplingBasicsTestInterp::test2D1DSegTriInterpP0P0_1() +{ + MEDCouplingUMesh *sourceMesh=build2D1DSegSourceMesh(); + MEDCouplingUMesh *targetMesh=build2D1DTriTargetMesh(); + test2D1DMeshesIntersection(sourceMesh, targetMesh, 16., 0, 4); +} + +void MEDCouplingBasicsTestInterp::test2D1DSegTriInterpP0P0_2() +{ + const double shiftX = 3.; + MEDCouplingUMesh *sourceMesh=build2D1DSegSourceMesh(shiftX); + MEDCouplingUMesh *targetMesh=build2D1DTriTargetMesh(); + test2D1DMeshesIntersection(sourceMesh, targetMesh, 2. * 16., 4, 2 * 4); +} + +void MEDCouplingBasicsTestInterp::test2D1DSegTriInterpP0P0_3() +{ + const double shiftX = 1.5; + const double inclinationX = 3.; + MEDCouplingUMesh *sourceMesh=build2D1DSegSourceMesh(shiftX, inclinationX); + MEDCouplingUMesh *targetMesh=build2D1DTriTargetMesh(inclinationX); + test2D1DMeshesIntersection(sourceMesh, targetMesh, 20., 0, 8); +} + +void MEDCouplingBasicsTestInterp::test2D1DSegTriInterpP0P0_4() +{ + const double shiftX = 3.; + const double inclinationX = 3.; + MEDCouplingUMesh *sourceMesh=build2D1DSegSourceMesh(shiftX, inclinationX); + MEDCouplingUMesh *targetMesh=build2D1DTriTargetMesh(inclinationX); + test2D1DMeshesIntersection(sourceMesh, targetMesh, 2. * 20., 4, 8); +} + +void MEDCouplingBasicsTestInterp::test2D1DSegTriInterpP0P0_5() +{ + const double shiftX = 9.; + const double inclinationX = 3.; + MEDCouplingUMesh *sourceMesh=build2D1DSegSourceMesh(shiftX); + MEDCouplingUMesh *targetMesh=build2D1DTriTargetMesh(inclinationX); + test2D1DMeshesIntersection(sourceMesh, targetMesh, 12., 0, 6); +} + +void MEDCouplingBasicsTestInterp::test2D1DSegTriInterpP0P0_6() +{ + const double shiftX = 9.; + const double inclinationX = 3.; + MEDCouplingUMesh *sourceMesh=build2D1DSegSourceMesh(shiftX, inclinationX); + MEDCouplingUMesh *targetMesh=build2D1DTriTargetMesh(); + test2D1DMeshesIntersection(sourceMesh, targetMesh, 20., 2, 4); +} + +void MEDCouplingBasicsTestInterp::test3D2DBasicInterpP0P0() +{ + MEDCouplingUMesh *sourceMesh=build3D2DSourceMesh(); + MEDCouplingUMesh *targetMesh=build3D2DTargetMesh(); + + MEDCouplingNormalizedUnstructuredMesh<3,3> sourceWrapper(sourceMesh); + MEDCouplingNormalizedUnstructuredMesh<3,3> targetWrapper(targetMesh); + INTERP_KERNEL::Interpolation3D2D myInterpolator; + myInterpolator.setPrecision(1e-12); + std::vector<std::map<int,double> > matrix; + INTERP_KERNEL::SplittingPolicy sp[] = { INTERP_KERNEL::PLANAR_FACE_5, INTERP_KERNEL::PLANAR_FACE_6, INTERP_KERNEL::GENERAL_24, INTERP_KERNEL::GENERAL_48 }; + for ( size_t i = 0; i < sizeof(sp)/sizeof(sp[0]); ++i ) + { + myInterpolator.setSplittingPolicy( sp[i] ); + matrix.clear(); + myInterpolator.interpolateMeshes(sourceWrapper,targetWrapper,matrix,"P0P0"); + + CPPUNIT_ASSERT_EQUAL(3,(int)matrix.size()); + + CPPUNIT_ASSERT_DOUBLES_EQUAL(0. ,matrix[0][0],1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0. ,matrix[0][1],1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(40. ,matrix[0][2],1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(8. ,matrix[0][3],1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(2.5 ,matrix[0][4],1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0. ,matrix[0][5],1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(32. ,matrix[0][6],1e-12); + + CPPUNIT_ASSERT_DOUBLES_EQUAL(8.*sqrt(3.),matrix[1][0],1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0. ,matrix[1][1],1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(40. ,matrix[1][2],1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(80. ,matrix[1][3],1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0. ,matrix[1][4],1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(80. ,matrix[1][5],1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(80. ,matrix[1][6],1e-12); + + CPPUNIT_ASSERT_DOUBLES_EQUAL(0. ,matrix[2][0],1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(32. ,matrix[2][1],1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0. ,matrix[2][2],1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0. ,matrix[2][3],1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(0. ,matrix[2][4],1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(80. ,matrix[2][5],1e-12); + CPPUNIT_ASSERT_DOUBLES_EQUAL(112. ,matrix[2][6],1e-12); + + INTERP_KERNEL::Interpolation3D2D::DuplicateFacesType duplicateFaces = myInterpolator.retrieveDuplicateFaces(); + CPPUNIT_ASSERT_EQUAL(3,(int)duplicateFaces.size()); + + INTERP_KERNEL::Interpolation3D2D::DuplicateFacesType correctDuplicateFaces; + std::set<int> face2; + face2.insert(0); + face2.insert(1); + correctDuplicateFaces[2] = face2; + std::set<int> face5; + face5.insert(1); + face5.insert(2); + correctDuplicateFaces[5] = face5; + std::set<int> face6; + face6.insert(0); + face6.insert(1); + face6.insert(2); + correctDuplicateFaces[6] = face6; + + CPPUNIT_ASSERT(correctDuplicateFaces == duplicateFaces); + } + //clean up + sourceMesh->decrRef(); + targetMesh->decrRef(); +} + +void MEDCouplingBasicsTestInterp::test3D2DQuadHexaInterpP0P0_1() +{ + MEDCouplingUMesh *sourceMesh=build3D2DQuadSourceMesh(); + MEDCouplingUMesh *targetMesh=build3D2DHexaTargetMesh(); + test3D2DMeshesIntersection(sourceMesh, targetMesh, 240., 0, 20); +} + +void MEDCouplingBasicsTestInterp::test3D2DQuadHexaInterpP0P0_2() +{ + const double shiftX = 3.; + MEDCouplingUMesh *sourceMesh=build3D2DQuadSourceMesh(shiftX); + MEDCouplingUMesh *targetMesh=build3D2DHexaTargetMesh(); + test3D2DMeshesIntersection(sourceMesh, targetMesh, 2. * 240., 20, 2 * 20); +} + +void MEDCouplingBasicsTestInterp::test3D2DQuadHexaInterpP0P0_3() +{ + const double shiftX = 1.5; + const double inclinationX = 3.; + MEDCouplingUMesh *sourceMesh=build3D2DQuadSourceMesh(shiftX, inclinationX); + MEDCouplingUMesh *targetMesh=build3D2DHexaTargetMesh(inclinationX); + test3D2DMeshesIntersection(sourceMesh, targetMesh, 300., 0, 20); +} + +void MEDCouplingBasicsTestInterp::test3D2DQuadHexaInterpP0P0_4() +{ + const double shiftX = 3.; + const double inclinationX = 3.; + MEDCouplingUMesh *sourceMesh=build3D2DQuadSourceMesh(shiftX, inclinationX); + MEDCouplingUMesh *targetMesh=build3D2DHexaTargetMesh(inclinationX); + test3D2DMeshesIntersection(sourceMesh, targetMesh, 2. * 300., 20, 2 * 20); +} + +void MEDCouplingBasicsTestInterp::test3D2DQuadHexaInterpP0P0_5() +{ + const double shiftX = 9.; + const double inclinationX = 3.; + MEDCouplingUMesh *sourceMesh=build3D2DQuadSourceMesh(shiftX); + MEDCouplingUMesh *targetMesh=build3D2DHexaTargetMesh(inclinationX); + test3D2DMeshesIntersection(sourceMesh, targetMesh, 180., 0, 15); +} + +void MEDCouplingBasicsTestInterp::test3D2DQuadHexaInterpP0P0_6() +{ + const double shiftX = 9.; + const double inclinationX = 3.; + MEDCouplingUMesh *sourceMesh=build3D2DQuadSourceMesh(shiftX, inclinationX); + MEDCouplingUMesh *targetMesh=build3D2DHexaTargetMesh(); + test3D2DMeshesIntersection(sourceMesh, targetMesh, 150., 0, 10); +} + +void MEDCouplingBasicsTestInterp::test3D2DTriHexaInterpP0P0_1() +{ + MEDCouplingUMesh *sourceMesh=build3D2DTriSourceMesh(); + MEDCouplingUMesh *targetMesh=build3D2DHexaTargetMesh(); + test3D2DMeshesIntersection(sourceMesh, targetMesh, 240., 0, 40); +} + +void MEDCouplingBasicsTestInterp::test3D2DTriHexaInterpP0P0_2() +{ + const double shiftX = 3.; + MEDCouplingUMesh *sourceMesh=build3D2DTriSourceMesh(shiftX); + MEDCouplingUMesh *targetMesh=build3D2DHexaTargetMesh(); + test3D2DMeshesIntersection(sourceMesh, targetMesh, 2. * 240., 40, 2 * 40); +} + +void MEDCouplingBasicsTestInterp::test3D2DTriHexaInterpP0P0_3() +{ + const double shiftX = 1.5; + const double inclinationX = 3.; + MEDCouplingUMesh *sourceMesh=build3D2DTriSourceMesh(shiftX, inclinationX); + MEDCouplingUMesh *targetMesh=build3D2DHexaTargetMesh(inclinationX); + test3D2DMeshesIntersection(sourceMesh, targetMesh, 300., 0, 40); +} + +void MEDCouplingBasicsTestInterp::test3D2DTriHexaInterpP0P0_4() +{ + const double shiftX = 3.; + const double inclinationX = 3.; + MEDCouplingUMesh *sourceMesh=build3D2DTriSourceMesh(shiftX, inclinationX); + MEDCouplingUMesh *targetMesh=build3D2DHexaTargetMesh(inclinationX); + test3D2DMeshesIntersection(sourceMesh, targetMesh, 2. * 300., 40, 2 * 40); +} + +void MEDCouplingBasicsTestInterp::test3D2DTriHexaInterpP0P0_5() +{ + const double shiftX = 9.; + const double inclinationX = 3.; + MEDCouplingUMesh *sourceMesh=build3D2DTriSourceMesh(shiftX); + MEDCouplingUMesh *targetMesh=build3D2DHexaTargetMesh(inclinationX); + test3D2DMeshesIntersection(sourceMesh, targetMesh, 180., 0, 30); +} + +void MEDCouplingBasicsTestInterp::test3D2DTriHexaInterpP0P0_6() +{ + const double shiftX = 9.; + const double inclinationX = 3.; + MEDCouplingUMesh *sourceMesh=build3D2DTriSourceMesh(shiftX, inclinationX); + MEDCouplingUMesh *targetMesh=build3D2DHexaTargetMesh(); + test3D2DMeshesIntersection(sourceMesh, targetMesh, 150., 0, 20); +} + +void MEDCouplingBasicsTestInterp::test3D2DQuadTetraInterpP0P0_1() +{ + MEDCouplingUMesh *sourceMesh=build3D2DQuadSourceMesh(); + MEDCouplingUMesh *targetMesh=build3D2DTetraTargetMesh(); + test3D2DMeshesIntersection(sourceMesh, targetMesh, 240., 20, 40); +} + +void MEDCouplingBasicsTestInterp::test3D2DQuadTetraInterpP0P0_2() +{ + const double shiftX = 3.; + MEDCouplingUMesh *sourceMesh=build3D2DQuadSourceMesh(shiftX); + MEDCouplingUMesh *targetMesh=build3D2DTetraTargetMesh(); + test3D2DMeshesIntersection(sourceMesh, targetMesh, 2. * 240., 20, 2 * 40); +} + +void MEDCouplingBasicsTestInterp::test3D2DQuadTetraInterpP0P0_3() +{ + const double shiftX = 1.5; + const double inclinationX = 3.; + MEDCouplingUMesh *sourceMesh=build3D2DQuadSourceMesh(shiftX, inclinationX); + MEDCouplingUMesh *targetMesh=build3D2DTetraTargetMesh(inclinationX); + test3D2DMeshesIntersection(sourceMesh, targetMesh, 300., 0, 100); +} + +void MEDCouplingBasicsTestInterp::test3D2DQuadTetraInterpP0P0_4() +{ + const double shiftX = 3.; + const double inclinationX = 3.; + MEDCouplingUMesh *sourceMesh=build3D2DQuadSourceMesh(shiftX, inclinationX); + MEDCouplingUMesh *targetMesh=build3D2DTetraTargetMesh(inclinationX); + test3D2DMeshesIntersection(sourceMesh, targetMesh, 2. * 300., 20, 2 * 40); +} + +void MEDCouplingBasicsTestInterp::test3D2DQuadTetraInterpP0P0_5() +{ + const double shiftX = 9.; + const double inclinationX = 3.; + MEDCouplingUMesh *sourceMesh=build3D2DQuadSourceMesh(shiftX); + MEDCouplingUMesh *targetMesh=build3D2DTetraTargetMesh(inclinationX); + test3D2DMeshesIntersection(sourceMesh, targetMesh, 180., 0, 45); +} + +void MEDCouplingBasicsTestInterp::test3D2DQuadTetraInterpP0P0_6() +{ + const double shiftX = 9.; + const double inclinationX = 3.; + MEDCouplingUMesh *sourceMesh=build3D2DQuadSourceMesh(shiftX, inclinationX); + MEDCouplingUMesh *targetMesh=build3D2DTetraTargetMesh(); + test3D2DMeshesIntersection(sourceMesh, targetMesh, 150., 0, 30); +} + +void MEDCouplingBasicsTestInterp::test3D2DTriTetraInterpP0P0_1() +{ + MEDCouplingUMesh *sourceMesh=build3D2DTriSourceMesh(); + MEDCouplingUMesh *targetMesh=build3D2DTetraTargetMesh(); + test3D2DMeshesIntersection(sourceMesh, targetMesh, 240., 0, 40); +} + +void MEDCouplingBasicsTestInterp::test3D2DTriTetraInterpP0P0_2() +{ + const double shiftX = 3.; + MEDCouplingUMesh *sourceMesh=build3D2DTriSourceMesh(shiftX); + MEDCouplingUMesh *targetMesh=build3D2DTetraTargetMesh(); + test3D2DMeshesIntersection(sourceMesh, targetMesh, 2. * 240., 40, 40 + 80); +} + +void MEDCouplingBasicsTestInterp::test3D2DTriTetraInterpP0P0_3() +{ + const double shiftX = 1.5; + const double inclinationX = 3.; + MEDCouplingUMesh *sourceMesh=build3D2DTriSourceMesh(shiftX, inclinationX); + MEDCouplingUMesh *targetMesh=build3D2DTetraTargetMesh(inclinationX); + test3D2DMeshesIntersection(sourceMesh, targetMesh, 300., 0); +} + +void MEDCouplingBasicsTestInterp::test3D2DTriTetraInterpP0P0_4() +{ + const double shiftX = 3.; + const double inclinationX = 3.; + MEDCouplingUMesh *sourceMesh=build3D2DTriSourceMesh(shiftX, inclinationX); + MEDCouplingUMesh *targetMesh=build3D2DTetraTargetMesh(inclinationX); + test3D2DMeshesIntersection(sourceMesh, targetMesh, 2. * 300., 40, 40 + 80); +} + +void MEDCouplingBasicsTestInterp::test3D2DTriTetraInterpP0P0_5() +{ + const double shiftX = 9.; + const double inclinationX = 3.; + MEDCouplingUMesh *sourceMesh=build3D2DTriSourceMesh(shiftX); + MEDCouplingUMesh *targetMesh=build3D2DTetraTargetMesh(inclinationX); + test3D2DMeshesIntersection(sourceMesh, targetMesh, 180., 0); +} + +void MEDCouplingBasicsTestInterp::test3D2DTriTetraInterpP0P0_6() +{ + const double shiftX = 9.; + const double inclinationX = 3.; + MEDCouplingUMesh *sourceMesh=build3D2DTriSourceMesh(shiftX, inclinationX); + MEDCouplingUMesh *targetMesh=build3D2DTetraTargetMesh(); + test3D2DMeshesIntersection(sourceMesh, targetMesh, 150., 0); +} + diff --git a/src/medtool/src/MEDCoupling/Test/MEDCouplingBasicsTestInterp.hxx b/src/medtool/src/MEDCoupling/Test/MEDCouplingBasicsTestInterp.hxx new file mode 100644 index 000000000..a10bd00b3 --- /dev/null +++ b/src/medtool/src/MEDCoupling/Test/MEDCouplingBasicsTestInterp.hxx @@ -0,0 +1,236 @@ +// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 +// 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 __MEDCOUPLINGBASICSTESTINTERP_HXX__ +#define __MEDCOUPLINGBASICSTESTINTERP_HXX__ + +#include "MEDCouplingBasicsTest.hxx" + +#include <map> +#include <vector> + +namespace ParaMEDMEM +{ + class DataArrayDouble; + class MEDCouplingUMesh; + class MEDCouplingFieldDouble; + class MEDCouplingMultiFields; + + class MEDCouplingBasicsTestInterp : public MEDCouplingBasicsTest + { + CPPUNIT_TEST_SUITE(MEDCouplingBasicsTestInterp); + CPPUNIT_TEST( test2DInterpP0P0_1 ); + CPPUNIT_TEST( test2DInterpP0P0PL_1 ); + CPPUNIT_TEST( test2DInterpP0P0PL_2 ); + CPPUNIT_TEST( test2DInterpP0P0PL_3 ); + CPPUNIT_TEST( test2DInterpP0P0PL_4 ); + CPPUNIT_TEST( test2DInterpP0P1_1 ); + CPPUNIT_TEST( test2DInterpP0P1PL_1 ); + CPPUNIT_TEST( test2DInterpP0P1PL_2 ); + CPPUNIT_TEST( test2DInterpP1P0_1 ); + CPPUNIT_TEST( test2DInterpP1P0PL_1 ); + CPPUNIT_TEST( test2DInterpP1P0PL_2 ); + CPPUNIT_TEST( test2DInterpP1P1_1 ); + CPPUNIT_TEST( test2DInterpP1P1PL_1 ); + CPPUNIT_TEST( test3DSurfInterpP0P0_1 ); + CPPUNIT_TEST( test3DSurfInterpP0P0PL_1 ); + CPPUNIT_TEST( test3DSurfInterpP0P1_1 ); + CPPUNIT_TEST( test3DSurfInterpP0P1PL_1 ); + CPPUNIT_TEST( test3DSurfInterpP1P0_1 ); + CPPUNIT_TEST( test3DSurfInterpP1P0PL_1 ); + CPPUNIT_TEST( test3DSurfInterpP1P1_1 ); + CPPUNIT_TEST( test3DSurfInterpP1P1PL_1 ); + CPPUNIT_TEST( test3DSurfInterpP0P0_2 ); + CPPUNIT_TEST( test3DSurfInterpP0P0_3 ); + + CPPUNIT_TEST( testInterpolationCC ); + CPPUNIT_TEST( testInterpolationCU1D ); + CPPUNIT_TEST( testInterpolationCU2D ); + CPPUNIT_TEST( testInterpolationCU3D ); + + CPPUNIT_TEST( test3DInterpP0P0_1 ); + CPPUNIT_TEST( test3DInterpP0P0PL_1 ); + CPPUNIT_TEST( test3DInterpP0P0PL_2 ); + CPPUNIT_TEST( test3DInterpP0P0PL_3 ); + CPPUNIT_TEST( test3DInterpP0P0PL_4 ); + CPPUNIT_TEST( test3DInterpP0P1_1 ); + CPPUNIT_TEST( test3DInterpP0P1PL_1 ); + CPPUNIT_TEST( test3DInterpP1P0_1 ); + CPPUNIT_TEST( test3DInterpP1P0PL_1 ); + CPPUNIT_TEST( test3DInterpP1P1_1 ); + CPPUNIT_TEST( test3DInterpP1P1PL_1 ); + CPPUNIT_TEST( test3DInterpP0P0Empty ); + CPPUNIT_TEST( test2DInterpP0IntegralUniform ); + CPPUNIT_TEST( test3DSurfInterpP0IntegralUniform ); + CPPUNIT_TEST( test3DInterpP0IntegralUniform ); + CPPUNIT_TEST( test2DInterpP1IntegralUniform ); + CPPUNIT_TEST( test3DInterpP1IntegralUniform ); + CPPUNIT_TEST( test2DInterpP1P0Bary_1 ); + CPPUNIT_TEST( test3DSurfInterpP1P0Bary_1 ); + CPPUNIT_TEST( test3DInterpP1P0Bary_1 ); + CPPUNIT_TEST( test3DTo1DInterpP0P0PL_1 ); + + CPPUNIT_TEST( test2D1DBasicInterpP0P0 ); + CPPUNIT_TEST( test2D1DSegQuadInterpP0P0_1 ); + CPPUNIT_TEST( test2D1DSegQuadInterpP0P0_2 ); + CPPUNIT_TEST( test2D1DSegQuadInterpP0P0_3 ); + CPPUNIT_TEST( test2D1DSegQuadInterpP0P0_4 ); + CPPUNIT_TEST( test2D1DSegQuadInterpP0P0_5 ); + CPPUNIT_TEST( test2D1DSegQuadInterpP0P0_6 ); + CPPUNIT_TEST( test2D1DSegTriInterpP0P0_1 ); + CPPUNIT_TEST( test2D1DSegTriInterpP0P0_2 ); + CPPUNIT_TEST( test2D1DSegTriInterpP0P0_3 ); + CPPUNIT_TEST( test2D1DSegTriInterpP0P0_4 ); + CPPUNIT_TEST( test2D1DSegTriInterpP0P0_5 ); + CPPUNIT_TEST( test2D1DSegTriInterpP0P0_6 ); + CPPUNIT_TEST( test3D2DBasicInterpP0P0 ); + CPPUNIT_TEST( test3D2DQuadHexaInterpP0P0_1 ); + CPPUNIT_TEST( test3D2DQuadHexaInterpP0P0_2 ); + CPPUNIT_TEST( test3D2DQuadHexaInterpP0P0_3 ); + CPPUNIT_TEST( test3D2DQuadHexaInterpP0P0_4 ); + CPPUNIT_TEST( test3D2DQuadHexaInterpP0P0_5 ); + CPPUNIT_TEST( test3D2DQuadHexaInterpP0P0_6 ); + CPPUNIT_TEST( test3D2DTriHexaInterpP0P0_1 ); + CPPUNIT_TEST( test3D2DTriHexaInterpP0P0_2 ); + CPPUNIT_TEST( test3D2DTriHexaInterpP0P0_3 ); + CPPUNIT_TEST( test3D2DTriHexaInterpP0P0_4 ); + CPPUNIT_TEST( test3D2DTriHexaInterpP0P0_5 ); + CPPUNIT_TEST( test3D2DTriHexaInterpP0P0_6 ); + CPPUNIT_TEST( test3D2DQuadTetraInterpP0P0_1 ); + CPPUNIT_TEST( test3D2DQuadTetraInterpP0P0_2 ); + CPPUNIT_TEST( test3D2DQuadTetraInterpP0P0_3 ); + CPPUNIT_TEST( test3D2DQuadTetraInterpP0P0_4 ); + CPPUNIT_TEST( test3D2DQuadTetraInterpP0P0_5 ); + CPPUNIT_TEST( test3D2DQuadTetraInterpP0P0_6 ); + CPPUNIT_TEST( test3D2DTriTetraInterpP0P0_1 ); + CPPUNIT_TEST( test3D2DTriTetraInterpP0P0_2 ); + CPPUNIT_TEST( test3D2DTriTetraInterpP0P0_3 ); + CPPUNIT_TEST( test3D2DTriTetraInterpP0P0_4 ); + CPPUNIT_TEST( test3D2DTriTetraInterpP0P0_5 ); + CPPUNIT_TEST( test3D2DTriTetraInterpP0P0_6 ); + + CPPUNIT_TEST( test1DInterp_1 ); + CPPUNIT_TEST( test2DCurveInterpP0P0_1 ); + CPPUNIT_TEST( test2DCurveInterpP0P0_2 ); + CPPUNIT_TEST( test2DCurveInterpP0P1_1 ); + CPPUNIT_TEST( test2DCurveInterpP1P0_1 ); + CPPUNIT_TEST( test2DCurveInterpP1P1_1 ); + CPPUNIT_TEST_SUITE_END(); + public: + void test2DInterpP0P0_1(); + void test2DInterpP0P0PL_1(); + void test2DInterpP0P0PL_2(); + void test2DInterpP0P0PL_3(); + void test2DInterpP0P0PL_4(); + void test2DInterpP0P1_1(); + void test2DInterpP0P1PL_1(); + void test2DInterpP0P1PL_2(); + void test2DInterpP1P0_1(); + void test2DInterpP1P0PL_1(); + void test2DInterpP1P0PL_2(); + void test2DInterpP1P1_1(); + void test2DInterpP1P1PL_1(); + void test3DSurfInterpP0P0_1(); + void test3DSurfInterpP0P0PL_1(); + void test3DSurfInterpP0P1_1(); + void test3DSurfInterpP0P1PL_1(); + void test3DSurfInterpP1P0_1(); + void test3DSurfInterpP1P0PL_1(); + void test3DSurfInterpP1P1_1(); + void test3DSurfInterpP1P1PL_1(); + void test3DSurfInterpP0P0_2(); + void test3DSurfInterpP0P0_3(); + void test3DInterpP0P0_1(); + void test3DInterpP0P0PL_1(); + void test3DInterpP0P0PL_2(); + void test3DInterpP0P0PL_3(); + void test3DInterpP0P0PL_4(); + void test3DInterpP0P1_1(); + void test3DInterpP0P1PL_1(); + void test3DInterpP1P0_1(); + void test3DInterpP1P0PL_1(); + void test3DInterpP1P1_1(); + void test3DInterpP1P1PL_1(); + + void testInterpolationCC(); + void testInterpolationCU1D(); + void testInterpolationCU2D(); + void testInterpolationCU3D(); + + void test3DInterpP0P0Empty(); + void test2DInterpP0IntegralUniform(); + void test3DSurfInterpP0IntegralUniform(); + void test3DInterpP0IntegralUniform(); + void test2DInterpP1IntegralUniform(); + void test3DInterpP1IntegralUniform(); + void test2DInterpP1P0Bary_1(); + void test3DSurfInterpP1P0Bary_1(); + void test3DInterpP1P0Bary_1(); + void test3DTo1DInterpP0P0PL_1(); + + void test2D1DBasicInterpP0P0(); + void test2D1DSegQuadInterpP0P0_1(); + void test2D1DSegQuadInterpP0P0_2(); + void test2D1DSegQuadInterpP0P0_3(); + void test2D1DSegQuadInterpP0P0_4(); + void test2D1DSegQuadInterpP0P0_5(); + void test2D1DSegQuadInterpP0P0_6(); + void test2D1DSegTriInterpP0P0_1(); + void test2D1DSegTriInterpP0P0_2(); + void test2D1DSegTriInterpP0P0_3(); + void test2D1DSegTriInterpP0P0_4(); + void test2D1DSegTriInterpP0P0_5(); + void test2D1DSegTriInterpP0P0_6(); + void test3D2DBasicInterpP0P0(); + void test3D2DQuadHexaInterpP0P0_1(); + void test3D2DQuadHexaInterpP0P0_2(); + void test3D2DQuadHexaInterpP0P0_3(); + void test3D2DQuadHexaInterpP0P0_4(); + void test3D2DQuadHexaInterpP0P0_5(); + void test3D2DQuadHexaInterpP0P0_6(); + void test3D2DTriHexaInterpP0P0_1(); + void test3D2DTriHexaInterpP0P0_2(); + void test3D2DTriHexaInterpP0P0_3(); + void test3D2DTriHexaInterpP0P0_4(); + void test3D2DTriHexaInterpP0P0_5(); + void test3D2DTriHexaInterpP0P0_6(); + void test3D2DQuadTetraInterpP0P0_1(); + void test3D2DQuadTetraInterpP0P0_2(); + void test3D2DQuadTetraInterpP0P0_3(); + void test3D2DQuadTetraInterpP0P0_4(); + void test3D2DQuadTetraInterpP0P0_5(); + void test3D2DQuadTetraInterpP0P0_6(); + void test3D2DTriTetraInterpP0P0_1(); + void test3D2DTriTetraInterpP0P0_2(); + void test3D2DTriTetraInterpP0P0_3(); + void test3D2DTriTetraInterpP0P0_4(); + void test3D2DTriTetraInterpP0P0_5(); + void test3D2DTriTetraInterpP0P0_6(); + + void test1DInterp_1(); + void test2DCurveInterpP0P0_1(); + void test2DCurveInterpP0P0_2(); + void test2DCurveInterpP0P1_1(); + void test2DCurveInterpP1P0_1(); + void test2DCurveInterpP1P1_1(); + }; +} + +#endif diff --git a/src/medtool/src/MEDCoupling/Test/MEDCouplingExamplesTest.cxx b/src/medtool/src/MEDCoupling/Test/MEDCouplingExamplesTest.cxx new file mode 100644 index 000000000..f749b2f4b --- /dev/null +++ b/src/medtool/src/MEDCoupling/Test/MEDCouplingExamplesTest.cxx @@ -0,0 +1,2579 @@ +// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 +// 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 "MEDCouplingBasicsTest.hxx" +#include "MEDCouplingUMesh.hxx" +#include "MEDCouplingCMesh.hxx" +#include "MEDCouplingExtrudedMesh.hxx" +#include "MEDCouplingFieldDouble.hxx" +#include "MEDCouplingMemArray.hxx" +#include "MEDCouplingMultiFields.hxx" + + +void CppExample_MEDCouplingFieldDouble_WriteVTK() +{ + using namespace ParaMEDMEM; + //! [CppSnippet_MEDCouplingFieldDouble_WriteVTK_1] + // mesh1 + const double coords[3] = {0.,2.,4.}; + MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> coordsArr = DataArrayDouble::New(); + coordsArr->useExternalArrayWithRWAccess( coords, 3, 1 ); + MEDCouplingAutoRefCountObjectPtr<MEDCouplingCMesh> mesh1 = MEDCouplingCMesh::New(); + mesh1->setCoords(coordsArr,coordsArr); // mesh becomes a 2D one + + // 3 fields (lying on the same mesh!) + MEDCouplingAutoRefCountObjectPtr<MEDCouplingFieldDouble> field1 = + mesh1->getMeasureField( true ); + MEDCouplingAutoRefCountObjectPtr<MEDCouplingFieldDouble> field2 = + mesh1->buildOrthogonalField(); + MEDCouplingAutoRefCountObjectPtr<MEDCouplingFieldDouble> field3 = + mesh1->fillFromAnalytic( ON_CELLS, 1, "x"); + field2->setName( "Normal" ); // name is necessary! + field3->setName( "Barycenter" ); // name is necessary! + + // WriteVTK + const char fileName[] = "testExample_MEDCouplingFieldDouble_WriteVTK.vtk"; + std::vector<const MEDCouplingFieldDouble *> fs( 3 ); // field series + fs[0] = field1; + fs[1] = field2; + fs[2] = field3; + MEDCouplingFieldDouble::WriteVTK( fileName, fs ); + //! [CppSnippet_MEDCouplingFieldDouble_WriteVTK_1] + remove(fileName); +} + +void CppExample_MEDCouplingFieldDouble_MaxFields() +{ + using namespace ParaMEDMEM; + //! [CppSnippet_MEDCouplingFieldDouble_MaxFields_1] + const double vals1[4] = {0.,2., 4.,6.}; // for field 1 + const double vals2[4] = {2.,0., 6.,4.}; // for field 2 + const double valsMax[4] = {2.,2., 6.,6.}; // expected max field + const double valsMin[4] = {0.,0., 4.,4.}; // expected min field + // field 1 + MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> valsArr1 = DataArrayDouble::New(); + valsArr1->useExternalArrayWithRWAccess( vals1, 2,2 ); // 2 tuples per 2 components + MEDCouplingAutoRefCountObjectPtr<MEDCouplingFieldDouble> field1 = MEDCouplingFieldDouble::New( ON_NODES ); + field1->setArray( valsArr1 ); + // field 2 + MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> valsArr2 = DataArrayDouble::New(); + valsArr2->useExternalArrayWithRWAccess( vals2, 2,2 ); // 2 tuples per 2 components + MEDCouplingAutoRefCountObjectPtr<MEDCouplingFieldDouble> field2 = MEDCouplingFieldDouble::New( ON_NODES ); + field2->setArray( valsArr2 ); + // max field + MEDCouplingAutoRefCountObjectPtr<MEDCouplingFieldDouble> fieldMax = MEDCouplingFieldDouble::MaxFields( field1, field2 ); + CPPUNIT_ASSERT( std::equal( valsMax, valsMax+4, fieldMax->getArray()->getConstPointer() )); // fieldMax == valsMax + // min field + MEDCouplingAutoRefCountObjectPtr<MEDCouplingFieldDouble> fieldMin = MEDCouplingFieldDouble::MinFields( field1, field2 ); + CPPUNIT_ASSERT( std::equal( valsMin, valsMin+4, fieldMin->getArray()->getConstPointer() )); // fieldMin == valsMin + //! [CppSnippet_MEDCouplingFieldDouble_MaxFields_1] +} + +void CppExample_MEDCouplingFieldDouble_MergeFields() +{ + using namespace ParaMEDMEM; + //! [CppSnippet_MEDCouplingFieldDouble_MergeFields_1] + // mesh1 + const double coords[3] = {0.,2.,4.}; + MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> coordsArr = DataArrayDouble::New(); + coordsArr->useExternalArrayWithRWAccess( coords, 3, 1 ); + MEDCouplingAutoRefCountObjectPtr<MEDCouplingCMesh> mesh1 = MEDCouplingCMesh::New(); + mesh1->setCoords(coordsArr); // mesh becomes a 1D + // field1 + MEDCouplingAutoRefCountObjectPtr<MEDCouplingFieldDouble> field1 = + mesh1->fillFromAnalytic( ON_CELLS, 1, "x"); + + // mesh2 and field2 + MEDCouplingAutoRefCountObjectPtr<MEDCouplingFieldDouble> field2 = + field1->cloneWithMesh( true ); + double vec[1] = { 5. }; + (const_cast<ParaMEDMEM::MEDCouplingMesh *>(field2->getMesh()))->translate(vec); // translate mesh2 + field2->applyFunc("x + 5"); // "translate" field2 + + // concatenate field1 and field2 + MEDCouplingAutoRefCountObjectPtr<MEDCouplingFieldDouble> field3 = + MEDCouplingFieldDouble::MergeFields( field1, field2 ); + std::vector<const MEDCouplingFieldDouble *> fields( 2 ); + fields[0] = field1; + fields[1] = field2; + MEDCouplingAutoRefCountObjectPtr<MEDCouplingFieldDouble> field4 = + MEDCouplingFieldDouble::MergeFields( fields ); + //! [CppSnippet_MEDCouplingFieldDouble_MergeFields_1] +} + +void CppExample_MEDCouplingFieldDouble_substractInPlaceDM() +{ + using namespace ParaMEDMEM; + //! [CppSnippet_MEDCouplingFieldDouble_substractInPlaceDM_1] + const double coords1[4] = {0.,1.,2.,3.}; + const double coords2[4] = {2.,1.,0.,3.}; // #0 <==> #2 + // mesh 1 + MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> mesh1 = MEDCouplingUMesh::New(); + MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> coordsArr = DataArrayDouble::New(); + coordsArr->useExternalArrayWithRWAccess( coords1, 4, 1 ); + mesh1->setCoords(coordsArr); + mesh1->setMeshDimension(0); + mesh1->allocateCells(0); + mesh1->finishInsertingCells(); + // mesh 2 + MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> mesh2 = + (MEDCouplingUMesh*) mesh1->deepCpy(); + mesh2->getCoords()->useExternalArrayWithRWAccess( coords2, 4, 1 ); + //! [CppSnippet_MEDCouplingFieldDouble_substractInPlaceDM_1] + //! [CppSnippet_MEDCouplingFieldDouble_substractInPlaceDM_2] + MEDCouplingAutoRefCountObjectPtr<MEDCouplingFieldDouble> field1 = + mesh1->fillFromAnalytic( ParaMEDMEM::ON_NODES,1,"x"); // field1 values == coords1 + MEDCouplingAutoRefCountObjectPtr<MEDCouplingFieldDouble> field2 = + mesh2->fillFromAnalytic( ParaMEDMEM::ON_NODES,1,"x"); // field2 values == coords2 + const double levOfCheck = 10; // nodes can be permuted + field1->substractInPlaceDM( field2, levOfCheck, 1e-13, 0 ); // values #0 and #2 must swap + //! [CppSnippet_MEDCouplingFieldDouble_substractInPlaceDM_2] + //! [CppSnippet_MEDCouplingFieldDouble_substractInPlaceDM_3] + field2->applyFunc( 1, 0.0 ); // all field2 values == 0.0 + CPPUNIT_ASSERT( field1->isEqual( field2, 1e-13, 1e-13 )); // field1 == field2 == 0.0 + //! [CppSnippet_MEDCouplingFieldDouble_substractInPlaceDM_3] +} + +void CppExample_MEDCouplingFieldDouble_changeUnderlyingMesh() +{ + using namespace ParaMEDMEM; + //! [CppSnippet_MEDCouplingFieldDouble_changeUnderlyingMesh_1] + const double coords1[4] = {0.,1.,2.,3.}; + const double coords2[4] = {2.,1.,0.,3.}; // #0 <==> #2 + // mesh 1 + MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> mesh1 = MEDCouplingUMesh::New(); + MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> coordsArr = DataArrayDouble::New(); + coordsArr->useExternalArrayWithRWAccess( coords1, 4, 1 ); + mesh1->setCoords(coordsArr); + mesh1->setMeshDimension(0); + mesh1->allocateCells(0); + mesh1->finishInsertingCells(); + // mesh 2 + MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> mesh2 = + (MEDCouplingUMesh*) mesh1->deepCpy(); + mesh2->getCoords()->useExternalArrayWithRWAccess( coords2, 4, 1 ); + //! [CppSnippet_MEDCouplingFieldDouble_changeUnderlyingMesh_1] + //! [CppSnippet_MEDCouplingFieldDouble_changeUnderlyingMesh_2] + MEDCouplingAutoRefCountObjectPtr<MEDCouplingFieldDouble> field = + mesh1->fillFromAnalytic( ParaMEDMEM::ON_NODES,1,"x"); // field values == coords1 + const double levOfCheck = 10; // nodes can be permuted + field->changeUnderlyingMesh( mesh2, levOfCheck, 1e-13, 0 ); // values #0 and #2 must swap + CPPUNIT_ASSERT( std::equal( coords2, coords2+4, field->getArray()->getConstPointer() )); + //! [CppSnippet_MEDCouplingFieldDouble_changeUnderlyingMesh_2] +} + +void CppExample_MEDCouplingFieldDouble_applyFunc_same_nb_comp() +{ + using namespace ParaMEDMEM; + //! [CppSnippet_MEDCouplingFieldDouble_applyFunc_same_nb_comp_1] + const double v[4] = {1.,2., 3.,4.}; + MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> array = DataArrayDouble::New(); + array->useExternalArrayWithRWAccess( v, 2, 2 ); // 2 tuples per 2 components + MEDCouplingAutoRefCountObjectPtr<MEDCouplingFieldDouble> field = + MEDCouplingFieldDouble::New( ParaMEDMEM::ON_CELLS ); + field->setArray( array ); + const char func[] = "IVec * v + JVec * w*w + 10"; + field->applyFunc( 2, func ); + CPPUNIT_ASSERT( field->getNumberOfComponents() == 2 ); // 2 components remains + //! [CppSnippet_MEDCouplingFieldDouble_applyFunc_same_nb_comp_1] + //! [CppSnippet_MEDCouplingFieldDouble_applyFunc_same_nb_comp_2] + const double* v2 = field->getArray()->getConstPointer(); + CPPUNIT_ASSERT_DOUBLES_EQUAL( v2[0], 10 + v[0], 13 ); // "10 + IVec * v" + CPPUNIT_ASSERT_DOUBLES_EQUAL( v2[1], 10 + v[1]*v[1], 13 ); // "10 + JVec * v*v" + CPPUNIT_ASSERT_DOUBLES_EQUAL( v2[2], 10 + v[2], 13 ); // "10 + IVec * v" + CPPUNIT_ASSERT_DOUBLES_EQUAL( v2[3], 10 + v[3]*v[3], 13 ); // "10 + JVec * v*v" + //! [CppSnippet_MEDCouplingFieldDouble_applyFunc_same_nb_comp_2] +} + +void CppExample_MEDCouplingFieldDouble_applyFunc3() +{ + using namespace ParaMEDMEM; + //! [CppSnippet_MEDCouplingFieldDouble_applyFunc3_1] + // create a 2D vector field + const double values[4] = {1.,1., 2.,1.}; + MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> array = DataArrayDouble::New(); + array->useExternalArrayWithRWAccess( values, 2, 2 ); // 2 tuples per 2 components + MEDCouplingAutoRefCountObjectPtr<MEDCouplingFieldDouble> field = + MEDCouplingFieldDouble::New( ParaMEDMEM::ON_CELLS ); + field->setArray( array ); + // transform the field to a 3D vector field + const char func[] = "IVec * b + JVec * a + KVec * sqrt( a*a + b*b ) + 10"; + const char* varNames[2] = { "a", "b" }; // names used to refer to X and Y components + std::vector<std::string> varNamesVec( varNames, varNames+2 ); + field->applyFunc3( 3, varNamesVec, func ); // require 3 components + CPPUNIT_ASSERT( field->getNumberOfComponents() == 3 ); // 3 components as required + //! [CppSnippet_MEDCouplingFieldDouble_applyFunc3_1] + //! [CppSnippet_MEDCouplingFieldDouble_applyFunc3_2] + double vec1[3]; // vector #1 + field->getArray()->getTuple( 1, vec1 ); + const double a = values[2], b = values[3]; // initial components of the vector #1 + CPPUNIT_ASSERT_DOUBLES_EQUAL( vec1[0], 10 + b, 13 ); // "10 + IVec * b" + CPPUNIT_ASSERT_DOUBLES_EQUAL( vec1[1], 10 + a, 13 ); // "10 + JVec * a" + CPPUNIT_ASSERT_DOUBLES_EQUAL( vec1[2], 10 + sqrt(a*a+b*b), 13 ); // "10 + KVec * sqrt( a*a + b*b )" + //! [CppSnippet_MEDCouplingFieldDouble_applyFunc3_2] +} + +void CppExample_MEDCouplingFieldDouble_applyFunc2() +{ + using namespace ParaMEDMEM; + //! [CppSnippet_MEDCouplingFieldDouble_applyFunc2_1] + // create a 2D vector field + const double values[4] = {1.,1., 2.,1.}; + MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> array = DataArrayDouble::New(); + array->useExternalArrayWithRWAccess( values, 2, 2 ); // 2 tuples per 2 components + array->setInfoOnComponent(0,"a"); // name used to refer to X component within a function + array->setInfoOnComponent(1,"b"); // name used to refer to Y component within a function + MEDCouplingAutoRefCountObjectPtr<MEDCouplingFieldDouble> field = + MEDCouplingFieldDouble::New( ParaMEDMEM::ON_CELLS ); + field->setArray( array ); + // transform the field to a 3D vector field + const char func[] = "IVec * b + JVec * a + KVec * sqrt( a*a + b*b ) + 10"; + field->applyFunc2( 3, func ); // require 3 components + CPPUNIT_ASSERT( field->getNumberOfComponents() == 3 ); // 3 components as required + //! [CppSnippet_MEDCouplingFieldDouble_applyFunc2_1] + //! [CppSnippet_MEDCouplingFieldDouble_applyFunc2_2] + double vec1[3]; // vector #1 + field->getArray()->getTuple( 1, vec1 ); + const double a = values[2], b = values[3]; // initial components of the vector #1 + CPPUNIT_ASSERT_DOUBLES_EQUAL( vec1[0], 10 + b, 13 ); // "10 + IVec * b" + CPPUNIT_ASSERT_DOUBLES_EQUAL( vec1[1], 10 + a, 13 ); // "10 + JVec * a" + CPPUNIT_ASSERT_DOUBLES_EQUAL( vec1[2], 10 + sqrt(a*a+b*b), 13 ); // "10 + KVec * sqrt( a*a + b*b )" + //! [CppSnippet_MEDCouplingFieldDouble_applyFunc2_2] +} + +void CppExample_MEDCouplingFieldDouble_applyFunc() +{ + using namespace ParaMEDMEM; + //! [CppSnippet_MEDCouplingFieldDouble_applyFunc_1] + // create a 2D vector field + const double values[4] = {1.,1., 2.,1.}; + MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> array = DataArrayDouble::New(); + array->useExternalArrayWithRWAccess( values, 2, 2 ); // 2 tuples per 2 components + MEDCouplingAutoRefCountObjectPtr<MEDCouplingFieldDouble> field = + MEDCouplingFieldDouble::New( ParaMEDMEM::ON_CELLS ); + field->setArray( array ); + // transform the field to a 3D vector field + const char func[] = "IVec * b + JVec * a + KVec * sqrt( a*a + b*b ) + 10"; + field->applyFunc( 3, func ); // require 3 components + CPPUNIT_ASSERT( field->getNumberOfComponents() == 3 ); // 3 components as required + //! [CppSnippet_MEDCouplingFieldDouble_applyFunc_1] + //! [CppSnippet_MEDCouplingFieldDouble_applyFunc_2] + double vec1[3]; // vector #1 + field->getArray()->getTuple( 1, vec1 ); + const double a = values[2], b = values[3]; // initial components of the vector #1 + CPPUNIT_ASSERT_DOUBLES_EQUAL( vec1[0], 10 + b, 13 ); // "10 + IVec * b" + CPPUNIT_ASSERT_DOUBLES_EQUAL( vec1[1], 10 + a, 13 ); // "10 + JVec * a" + CPPUNIT_ASSERT_DOUBLES_EQUAL( vec1[2], 10 + sqrt(a*a+b*b), 13 ); // "10 + KVec * sqrt( a*a + b*b )" + //! [CppSnippet_MEDCouplingFieldDouble_applyFunc_2] +} + +void CppExample_MEDCouplingFieldDouble_applyFunc_val() +{ + using namespace ParaMEDMEM; + //! [Snippet_MEDCouplingFieldDouble_applyFunc_val_1] + // mesh + const double coords[4] = {0.,2.,4.}; + MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> coordsArr = DataArrayDouble::New(); + coordsArr->useExternalArrayWithRWAccess( coords, 3, 1 ); + MEDCouplingAutoRefCountObjectPtr<MEDCouplingCMesh> mesh = MEDCouplingCMesh::New(); + mesh->setCoords(coordsArr,coordsArr); // mesh becomes a 2D structured mesh + // field + MEDCouplingAutoRefCountObjectPtr<MEDCouplingFieldDouble> field = + MEDCouplingFieldDouble::New( ParaMEDMEM::ON_CELLS ); + field->setMesh( mesh ); + field->fillFromAnalytic(2,"IVec * x + JVec * y"); // 2 components + //! [Snippet_MEDCouplingFieldDouble_applyFunc_val_1] + //! [Snippet_MEDCouplingFieldDouble_applyFunc_val_2] + const double newValue = 7.; + field->applyFunc( 3, newValue ); // # 3 components are required + CPPUNIT_ASSERT( field->getIJ(1,0) == newValue ); // a value is as expected + CPPUNIT_ASSERT( field->getNumberOfComponents() == 3 ); + CPPUNIT_ASSERT( field->getNumberOfTuples() == mesh->getNumberOfCells() ); + //! [Snippet_MEDCouplingFieldDouble_applyFunc_val_2] +} + +void CppExample_MEDCouplingFieldDouble_fillFromAnalytic3() +{ + using namespace ParaMEDMEM; + //! [CppSnippet_MEDCouplingFieldDouble_fillFromAnalytic3_1] + const double coords[4] = {0.,2.,4.,6.}; // 6. is not used + MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> x = DataArrayDouble::New(); + x->useExternalArrayWithRWAccess( coords, 3, 1 ); + MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> y = DataArrayDouble::New(); + y->useExternalArrayWithRWAccess( coords, 2, 1 ); + MEDCouplingAutoRefCountObjectPtr<MEDCouplingCMesh> mesh=MEDCouplingCMesh::New(); + mesh->setCoords(x,y); + //! [CppSnippet_MEDCouplingFieldDouble_fillFromAnalytic3_1] + //! [CppSnippet_MEDCouplingFieldDouble_fillFromAnalytic3_2] + MEDCouplingAutoRefCountObjectPtr<MEDCouplingFieldDouble> field = + MEDCouplingFieldDouble::New( ParaMEDMEM::ON_CELLS ); + field->setMesh( mesh ); + const char func[] = "IVec * b + JVec * a + KVec * sqrt( a*a + b*b ) + 10"; + const char* varNames[2] = { "a", "b" }; // names used to refer to X and Y coord components + std::vector<std::string> varNamesVec( varNames, varNames+2 ); + field->fillFromAnalytic3( 3, varNamesVec, func ); + //! [CppSnippet_MEDCouplingFieldDouble_fillFromAnalytic3_2] + //! [CppSnippet_MEDCouplingFieldDouble_fillFromAnalytic3_3] + double val1[3]; // a value (vector) of the cell #1 + CPPUNIT_ASSERT( field->getNumberOfComponents() == 3 ); // 3 components in the field + field->getArray()->getTuple( 1, val1 ); + // + MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> bc = + mesh->getBarycenterAndOwner(); // func is applied to barycenters of cells + double bc1[2]; // coordinates of the second point + bc->getTuple( 1, bc1 ); + // + double dist = sqrt( bc1[0]*bc1[0] + bc1[1]*bc1[1] ); // "sqrt( a*a + b*b )" + CPPUNIT_ASSERT_DOUBLES_EQUAL( val1[0], 10 + bc1[1], 13 ); // "10 + IVec * b" + CPPUNIT_ASSERT_DOUBLES_EQUAL( val1[1], 10 + bc1[0], 13 ); // "10 + JVec * a" + CPPUNIT_ASSERT_DOUBLES_EQUAL( val1[2], 10 + dist , 13 ); // "10 + KVec * sqrt( a*a + b*b )" + //! [CppSnippet_MEDCouplingFieldDouble_fillFromAnalytic3_3] +} + +void CppExample_MEDCouplingFieldDouble_fillFromAnalytic2() +{ + using namespace ParaMEDMEM; + //! [CppSnippet_MEDCouplingFieldDouble_fillFromAnalytic2_1] + const double coords[4] = {0.,2.,4.}; + MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> x = DataArrayDouble::New(); + x->useExternalArrayWithRWAccess( coords, 3, 1 ); + MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> y = DataArrayDouble::New(); + y->useExternalArrayWithRWAccess( coords, 2, 1 ); + x->setInfoOnComponent(0,"a"); // name used to refer to X coordinate within a function + y->setInfoOnComponent(0,"b"); // name used to refer to Y coordinate within a function + MEDCouplingAutoRefCountObjectPtr<MEDCouplingCMesh> mesh=MEDCouplingCMesh::New(); + mesh->setCoords(x,y); + //! [CppSnippet_MEDCouplingFieldDouble_fillFromAnalytic2_1] + //! [CppSnippet_MEDCouplingFieldDouble_fillFromAnalytic2_2] + MEDCouplingAutoRefCountObjectPtr<MEDCouplingFieldDouble> field = + MEDCouplingFieldDouble::New( ParaMEDMEM::ON_CELLS ); + field->setMesh( mesh ); + const char func[] = "IVec * b + JVec * a + KVec * sqrt( a*a + b*b ) + 10"; + field->fillFromAnalytic( 3, func ); + //! [CppSnippet_MEDCouplingFieldDouble_fillFromAnalytic2_2] + //! [CppSnippet_MEDCouplingFieldDouble_fillFromAnalytic2_3] + double val1[3]; // a value (vector) of the cell #1 + CPPUNIT_ASSERT( field->getNumberOfComponents() == 3 ); // 3 components in the field + field->getArray()->getTuple( 1, val1 ); + // + MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> bc = + mesh->getBarycenterAndOwner(); // func is applied to barycenters of cells + double bc1[2]; // coordinates of the second point + bc->getTuple( 1, bc1 ); + // + double dist = sqrt( bc1[0]*bc1[0] + bc1[1]*bc1[1] ); // "sqrt( a*a + b*b )" + CPPUNIT_ASSERT_DOUBLES_EQUAL( val1[0], 10 + bc1[1], 13 ); // "10 + IVec * b" + CPPUNIT_ASSERT_DOUBLES_EQUAL( val1[1], 10 + bc1[0], 13 ); // "10 + JVec * a" + CPPUNIT_ASSERT_DOUBLES_EQUAL( val1[2], 10 + dist , 13 ); // "10 + KVec * sqrt( a*a + b*b )" + //! [CppSnippet_MEDCouplingFieldDouble_fillFromAnalytic2_3] +} + +void CppExample_MEDCouplingFieldDouble_fillFromAnalytic() +{ + using namespace ParaMEDMEM; + //! [CppSnippet_MEDCouplingFieldDouble_fillFromAnalytic_1] + const double coords[3] = {0.,2.,4}; + MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> x = DataArrayDouble::New(); + x->useExternalArrayWithRWAccess( coords, 3, 1 ); + MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> y = DataArrayDouble::New(); + y->useExternalArrayWithRWAccess( coords, 2, 1 ); + MEDCouplingAutoRefCountObjectPtr<MEDCouplingCMesh> mesh=MEDCouplingCMesh::New(); + mesh->setCoords(x,y); + //! [CppSnippet_MEDCouplingFieldDouble_fillFromAnalytic_1] + //! [CppSnippet_MEDCouplingFieldDouble_fillFromAnalytic_2] + const char func[] = "IVec * b + JVec * a + KVec * sqrt( a*a + b*b ) + 10"; + MEDCouplingAutoRefCountObjectPtr<MEDCouplingFieldDouble> field = + MEDCouplingFieldDouble::New( ParaMEDMEM::ON_CELLS ); + field->setMesh( mesh ); + field->fillFromAnalytic( 3, func ); + //! [CppSnippet_MEDCouplingFieldDouble_fillFromAnalytic_2] + //! [CppSnippet_MEDCouplingFieldDouble_fillFromAnalytic_3] + double val1[3]; // a value (vector) of the cell #1 + CPPUNIT_ASSERT( field->getNumberOfComponents() == 3 ); // 3 components in the field + field->getArray()->getTuple( 1, val1 ); + // + MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> bc = + mesh->getBarycenterAndOwner(); // func is applied to barycenters of cells + double bc1[2]; // coordinates of the second point + bc->getTuple( 1, bc1 ); + // + double dist = sqrt( bc1[0]*bc1[0] + bc1[1]*bc1[1] ); // "sqrt( a*a + b*b )" + CPPUNIT_ASSERT_DOUBLES_EQUAL( val1[0], 10 + bc1[1], 13 ); // "10 + IVec * b" + CPPUNIT_ASSERT_DOUBLES_EQUAL( val1[1], 10 + bc1[0], 13 ); // "10 + JVec * a" + CPPUNIT_ASSERT_DOUBLES_EQUAL( val1[2], 10 + dist , 13 ); // "10 + KVec * sqrt( a*a + b*b )" + //! [CppSnippet_MEDCouplingFieldDouble_fillFromAnalytic_3] +} + +//! [Snippet_MEDCouplingFieldDouble_fillFromAnalytic_c_func_0] +bool getNewValue(const double *pos, double *res) +{ + res[0] = pos[0]; + res[1] = pos[1]; + res[2] = sqrt( pos[0]*pos[0] + pos[1]*pos[1] ); + return true; +} +//! [Snippet_MEDCouplingFieldDouble_fillFromAnalytic_c_func_0] + +void CppExample_MEDCouplingFieldDouble_fillFromAnalytic_c_func() +{ + using namespace ParaMEDMEM; + //! [Snippet_MEDCouplingFieldDouble_fillFromAnalytic_c_func_1] + // mesh + const double coords[4] = {0.,2.,4.}; + MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> coordsArr = DataArrayDouble::New(); + coordsArr->useExternalArrayWithRWAccess( coords, 3, 1 ); + MEDCouplingAutoRefCountObjectPtr<MEDCouplingCMesh> mesh = MEDCouplingCMesh::New(); + mesh->setCoords(coordsArr,coordsArr); // mesh becomes a 2D structured mesh + // field + MEDCouplingAutoRefCountObjectPtr<MEDCouplingFieldDouble> field = + MEDCouplingFieldDouble::New( ParaMEDMEM::ON_CELLS ); + field->setMesh( mesh ); + field->fillFromAnalytic( 3, &getNewValue ); // 3 components are required + CPPUNIT_ASSERT( field->getNumberOfComponents() == 3 ); + CPPUNIT_ASSERT( field->getNumberOfTuples() == mesh->getNumberOfCells() ); + //! [Snippet_MEDCouplingFieldDouble_fillFromAnalytic_c_func_1] +} + +void CppExample_MEDCouplingFieldDouble_applyFunc_c_func() +{ + using namespace ParaMEDMEM; + //! [Snippet_MEDCouplingFieldDouble_applyFunc_c_func_1] + // mesh + const double coords[4] = {0.,2.,4.}; + MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> coordsArr = DataArrayDouble::New(); + coordsArr->useExternalArrayWithRWAccess( coords, 3, 1 ); + MEDCouplingAutoRefCountObjectPtr<MEDCouplingCMesh> mesh = MEDCouplingCMesh::New(); + mesh->setCoords(coordsArr,coordsArr); // mesh becomes a 2D structured mesh + // field + MEDCouplingAutoRefCountObjectPtr<MEDCouplingFieldDouble> field = + MEDCouplingFieldDouble::New( ParaMEDMEM::ON_CELLS ); + field->setMesh( mesh ); + MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> bc = mesh->getBarycenterAndOwner(); + field->setArray( bc ); // 2 components here as the mesh is 2D + //! [Snippet_MEDCouplingFieldDouble_applyFunc_c_func_1] + //! [Snippet_MEDCouplingFieldDouble_applyFunc_c_func_2] + field->applyFunc( 3, &getNewValue ); // 3 components are required + CPPUNIT_ASSERT( field->getNumberOfComponents() == 3 ); + CPPUNIT_ASSERT( field->getNumberOfTuples() == mesh->getNumberOfCells() ); + //! [Snippet_MEDCouplingFieldDouble_applyFunc_c_func_2] +} + +void CppExample_MEDCouplingFieldDouble_getValueOn_time() +{ + using namespace ParaMEDMEM; + //! [CppSnippet_MEDCouplingFieldDouble_getValueOn_time_1] + const double coords[4] = {0.,2.,4.}; + MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> coordsArr = DataArrayDouble::New(); + coordsArr->useExternalArrayWithRWAccess( coords, 3, 1 ); + MEDCouplingAutoRefCountObjectPtr<MEDCouplingCMesh> mesh = MEDCouplingCMesh::New(); + mesh->setCoords(coordsArr,coordsArr); + //! [CppSnippet_MEDCouplingFieldDouble_getValueOn_time_1] + //! [CppSnippet_MEDCouplingFieldDouble_getValueOn_time_2] + MEDCouplingAutoRefCountObjectPtr<MEDCouplingFieldDouble> field = + MEDCouplingFieldDouble::New( ParaMEDMEM::ON_CELLS, ParaMEDMEM::LINEAR_TIME ); + field->setMesh( mesh ); + field->fillFromAnalytic( 1,"10"); // all values == 10. + MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> array2 = + DataArrayDouble::Add( field->getArray(), field->getArray() ); // == 2 * field->getArray() + field->setEndArray( array2 ); // all values == 20. + const double time1 = 1.1, time2 = 22.; + field->setStartTime( time1, 0, 0 ); + field->setEndTime ( time2, 0, 0 ); + //! [CppSnippet_MEDCouplingFieldDouble_getValueOn_time_2] + //! [CppSnippet_MEDCouplingFieldDouble_getValueOn_time_3] + const double pos[2] = { 1., 1. }; // we are in 2D space + double value[1]; // the field is scalar <-> 1 component + field->getValueOn( pos, 0.5*( time1 + time2 ), value ); + CPPUNIT_ASSERT( fabs( value[0] - 0.5*( 10. + 20. )) < 1e-13 ); + //! [CppSnippet_MEDCouplingFieldDouble_getValueOn_time_3] +} + +void CppExample_MEDCouplingFieldDouble_getValueOnMulti() +{ + using namespace ParaMEDMEM; + //! [CppSnippet_MEDCouplingFieldDouble_getValueOnMulti_1] + const double coords[4] = {0.,2.,4.}; + MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> coordsArr = DataArrayDouble::New(); + coordsArr->useExternalArrayWithRWAccess( coords, 3, 1 ); + MEDCouplingAutoRefCountObjectPtr<MEDCouplingCMesh> mesh = MEDCouplingCMesh::New(); + mesh->setCoords(coordsArr,coordsArr); + MEDCouplingAutoRefCountObjectPtr<MEDCouplingFieldDouble> field = + mesh->fillFromAnalytic( ParaMEDMEM::ON_CELLS,1,"x+y"); + //! [CppSnippet_MEDCouplingFieldDouble_getValueOnMulti_1] + //! [CppSnippet_MEDCouplingFieldDouble_getValueOnMulti_2] + // field values are located at cell barycenters + MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> bc = mesh->getBarycenterAndOwner(); + MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> valArray = + field->getValueOnMulti( bc->getConstPointer(), bc->getNumberOfTuples() ); + CPPUNIT_ASSERT( valArray->isEqual( * field->getArray(), 1e-13 )); + //! [CppSnippet_MEDCouplingFieldDouble_getValueOnMulti_2] +} + +void CppExample_MEDCouplingFieldDouble_getValueOn() +{ + using namespace ParaMEDMEM; + //! [CppSnippet_MEDCouplingFieldDouble_getValueOn_1] + const double coords[4] = {0.,2.,4.}; + MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> coordsArr = DataArrayDouble::New(); + coordsArr->useExternalArrayWithRWAccess( coords, 3, 1 ); + MEDCouplingAutoRefCountObjectPtr<MEDCouplingCMesh> mesh = MEDCouplingCMesh::New(); + mesh->setCoords(coordsArr,coordsArr); + MEDCouplingAutoRefCountObjectPtr<MEDCouplingFieldDouble> field = + mesh->fillFromAnalytic( ParaMEDMEM::ON_CELLS,1,"x+y"); + //! [CppSnippet_MEDCouplingFieldDouble_getValueOn_1] + //! [CppSnippet_MEDCouplingFieldDouble_getValueOn_2] + // field values are located at cell barycenters + MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> bc = mesh->getBarycenterAndOwner(); + std::vector<double> vals( field->getNumberOfTuples() ); // array to collect values returned by getValueOn() + double cellBC[2]; // we are in 2D space + for ( int i = 0; i < bc->getNumberOfTuples(); ++i ) + { + bc->getTuple( i, cellBC ); + field->getValueOn( cellBC, & vals[i] ); + } + CPPUNIT_ASSERT( std::equal( vals.begin(), vals.end(), field->getArray()->getConstPointer() )); + //! [CppSnippet_MEDCouplingFieldDouble_getValueOn_2] +} + +void CppExample_MEDCouplingFieldDouble_getValueOnPos() +{ + using namespace ParaMEDMEM; + //! [CppSnippet_MEDCouplingFieldDouble_getValueOnPos_1] + const double coords[4] = {0.,2.,4.}; + MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> coordsArr = DataArrayDouble::New(); + coordsArr->useExternalArrayWithRWAccess( coords, 3, 1 ); + MEDCouplingAutoRefCountObjectPtr<MEDCouplingCMesh> mesh = MEDCouplingCMesh::New(); + mesh->setCoords(coordsArr,coordsArr); + MEDCouplingAutoRefCountObjectPtr<MEDCouplingFieldDouble> field = + mesh->fillFromAnalytic( ParaMEDMEM::ON_CELLS,1,"x+y"); + //! [CppSnippet_MEDCouplingFieldDouble_getValueOnPos_1] + //! [CppSnippet_MEDCouplingFieldDouble_getValueOnPos_2] + double val11[1]; // 1 == field->getNumberOfComponents() + field->getValueOnPos( 1,1,-1, val11 ); + // field values are located at cell barycenters + MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> bc = mesh->getBarycenterAndOwner(); + CPPUNIT_ASSERT( val11[0] == bc->getIJ(3,0) + bc->getIJ(3,1) ); + //! [CppSnippet_MEDCouplingFieldDouble_getValueOnPos_2] +} + +void CppExample_MEDCouplingFieldDouble_renumberNodes() +{ + using namespace ParaMEDMEM; + //! [CppSnippet_MEDCouplingFieldDouble_renumberNodes_1] + const double coords[4] = {0.,2.,4.}; + MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> coordsArr = DataArrayDouble::New(); + coordsArr->useExternalArrayWithRWAccess( coords, 3, 1 ); + MEDCouplingAutoRefCountObjectPtr<MEDCouplingCMesh> cmesh = MEDCouplingCMesh::New(); + cmesh->setCoords(coordsArr,coordsArr); + MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> mesh = cmesh->buildUnstructured(); + //! [CppSnippet_MEDCouplingFieldDouble_renumberNodes_1] + //! [CppSnippet_MEDCouplingFieldDouble_renumberNodes_2] + MEDCouplingAutoRefCountObjectPtr<MEDCouplingFieldDouble> field = + mesh->fillFromAnalytic( ParaMEDMEM::ON_NODES,2,"IVec*x+JVec*y"); + const DataArrayDouble* values = field->getArray(); + const DataArrayDouble* nodeCoords = mesh->getCoords(); + CPPUNIT_ASSERT( values->isEqualWithoutConsideringStr( *nodeCoords, 1e-13 )); + //! [CppSnippet_MEDCouplingFieldDouble_renumberNodes_2] + //! [CppSnippet_MEDCouplingFieldDouble_renumberNodes_3] + const int renumber[9] = { 8, 7, 6, 5, 4, 3, 2, 1, 0 }; + field->renumberNodes(renumber,false); + const MEDCouplingMesh* mesh2 = field->getMesh(); // field now refers to another mesh + values = field->getArray(); + nodeCoords = (static_cast<const MEDCouplingUMesh*>(mesh2))->getCoords(); + CPPUNIT_ASSERT( values->isEqualWithoutConsideringStr( *nodeCoords, 1e-13 )); + //! [CppSnippet_MEDCouplingFieldDouble_renumberNodes_3] +} + +void CppExample_MEDCouplingFieldDouble_renumberCells() +{ + using namespace ParaMEDMEM; + //! [CppSnippet_MEDCouplingFieldDouble_renumberCells_1] + const double coords[4] = {0.,2.,4.}; + MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> coordsArr = DataArrayDouble::New(); + coordsArr->useExternalArrayWithRWAccess( coords, 3, 1 ); + MEDCouplingAutoRefCountObjectPtr<MEDCouplingCMesh> cmesh = MEDCouplingCMesh::New(); + cmesh->setCoords(coordsArr,coordsArr); + MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> mesh = cmesh->buildUnstructured(); + //! [CppSnippet_MEDCouplingFieldDouble_renumberCells_1] + //! [CppSnippet_MEDCouplingFieldDouble_renumberCells_2] + MEDCouplingAutoRefCountObjectPtr<MEDCouplingFieldDouble> field = + mesh->fillFromAnalytic( ParaMEDMEM::ON_CELLS,2,"IVec*x+JVec*y"); + const DataArrayDouble* values = field->getArray(); + MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> bc = mesh->getBarycenterAndOwner(); + CPPUNIT_ASSERT( values->isEqualWithoutConsideringStr( *bc, 1e-13 )); + //! [CppSnippet_MEDCouplingFieldDouble_renumberCells_2] + //! [CppSnippet_MEDCouplingFieldDouble_renumberCells_3] + const int renumber[4] = { 3, 2, 1, 0 }; + field->renumberCells(renumber,false); + const MEDCouplingMesh* mesh2 = field->getMesh(); // field now refers to another mesh + values = field->getArray(); + bc = mesh2->getBarycenterAndOwner(); + CPPUNIT_ASSERT( values->isEqualWithoutConsideringStr( *bc, 1e-13 )); + //! [CppSnippet_MEDCouplingFieldDouble_renumberCells_3] +} + +void CppExample_MEDCouplingFieldDouble_buildNewTimeReprFromThis() +{ + using namespace ParaMEDMEM; + //! [CppSnippet_MEDCouplingFieldDouble_buildNewTimeReprFromThis_1] + const double coords[4] = {0.,2.,4.}; + MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> coordsArr = DataArrayDouble::New(); + coordsArr->useExternalArrayWithRWAccess( coords, 3, 1 ); + MEDCouplingAutoRefCountObjectPtr<MEDCouplingCMesh> mesh = MEDCouplingCMesh::New(); + mesh->setCoords(coordsArr,coordsArr); + MEDCouplingAutoRefCountObjectPtr<MEDCouplingFieldDouble> field1 = + mesh->fillFromAnalytic( ParaMEDMEM::ON_NODES,1,"x+y"); + CPPUNIT_ASSERT( field1->getTimeDiscretization() == ParaMEDMEM::ONE_TIME ); + //! [CppSnippet_MEDCouplingFieldDouble_buildNewTimeReprFromThis_1] + //! [CppSnippet_MEDCouplingFieldDouble_buildNewTimeReprFromThis_2] + MEDCouplingAutoRefCountObjectPtr<MEDCouplingFieldDouble> field2 = + field1->buildNewTimeReprFromThis( ParaMEDMEM::NO_TIME, false ); + CPPUNIT_ASSERT( field2->getTimeDiscretization() == ParaMEDMEM::NO_TIME ); + //! [CppSnippet_MEDCouplingFieldDouble_buildNewTimeReprFromThis_2] +} + +void CppExample_MEDCouplingMesh_fillFromAnalytic3() +{ + using namespace ParaMEDMEM; + //! [CppSnippet_MEDCouplingMesh_fillFromAnalytic3_1] + const double coords[4] = {0.,2.,4.,6.}; // 6. is not used + MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> x = DataArrayDouble::New(); + x->useExternalArrayWithRWAccess( coords, 3, 1 ); + MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> y = DataArrayDouble::New(); + y->useExternalArrayWithRWAccess( coords, 2, 1 ); + MEDCouplingAutoRefCountObjectPtr<MEDCouplingCMesh> mesh=MEDCouplingCMesh::New(); + mesh->setCoords(x,y); + //! [CppSnippet_MEDCouplingMesh_fillFromAnalytic3_1] + //! [CppSnippet_MEDCouplingMesh_fillFromAnalytic3_2] + const char func[] = "IVec * b + JVec * a + KVec * sqrt( a*a + b*b ) + 10"; + const char* varNames[2] = { "a", "b" }; // names used to refer to X and Y coord components + std::vector<std::string> varNamesVec( varNames, varNames+2 ); + MEDCouplingAutoRefCountObjectPtr<MEDCouplingFieldDouble> field = + mesh->fillFromAnalytic3( ParaMEDMEM::ON_CELLS, 3, varNamesVec, func ); + //! [CppSnippet_MEDCouplingMesh_fillFromAnalytic3_2] + //! [CppSnippet_MEDCouplingMesh_fillFromAnalytic3_3] + double val1[3]; // a value (vector) of the cell #1 + CPPUNIT_ASSERT( field->getNumberOfComponents() == 3 ); // 3 components in the field + field->getArray()->getTuple( 1, val1 ); + // + MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> bc = + mesh->getBarycenterAndOwner(); // func is applied to barycenters of cells + double bc1[2]; // coordinates of the second point + bc->getTuple( 1, bc1 ); + // + double dist = sqrt( bc1[0]*bc1[0] + bc1[1]*bc1[1] ); // "sqrt( a*a + b*b )" + CPPUNIT_ASSERT_DOUBLES_EQUAL( val1[0], 10 + bc1[1], 13 ); // "10 + IVec * b" + CPPUNIT_ASSERT_DOUBLES_EQUAL( val1[1], 10 + bc1[0], 13 ); // "10 + JVec * a" + CPPUNIT_ASSERT_DOUBLES_EQUAL( val1[2], 10 + dist , 13 ); // "10 + KVec * sqrt( a*a + b*b )" + //! [CppSnippet_MEDCouplingMesh_fillFromAnalytic3_3] +} + +void CppExample_MEDCouplingMesh_fillFromAnalytic2() +{ + using namespace ParaMEDMEM; + //! [CppSnippet_MEDCouplingMesh_fillFromAnalytic2_1] + const double coords[4] = {0.,2.,4.,6.}; // 6. is not used + MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> x = DataArrayDouble::New(); + x->useExternalArrayWithRWAccess( coords, 3, 1 ); + MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> y = DataArrayDouble::New(); + y->useExternalArrayWithRWAccess( coords, 2, 1 ); + x->setInfoOnComponent(0,"a"); // name used to refer to X coordinate within a function + y->setInfoOnComponent(0,"b"); // name used to refer to Y coordinate within a function + MEDCouplingAutoRefCountObjectPtr<MEDCouplingCMesh> mesh=MEDCouplingCMesh::New(); + mesh->setCoords(x,y); + //! [CppSnippet_MEDCouplingMesh_fillFromAnalytic2_1] + //! [CppSnippet_MEDCouplingMesh_fillFromAnalytic2_2] + const char func[] = "IVec * b + JVec * a + KVec * sqrt( a*a + b*b ) + 10"; + MEDCouplingAutoRefCountObjectPtr<MEDCouplingFieldDouble> field = + mesh->fillFromAnalytic2( ParaMEDMEM::ON_CELLS, 3, func ); + //! [CppSnippet_MEDCouplingMesh_fillFromAnalytic2_2] + //! [CppSnippet_MEDCouplingMesh_fillFromAnalytic2_3] + double val1[3]; // a value (vector) of the cell #1 + CPPUNIT_ASSERT( field->getNumberOfComponents() == 3 ); // 3 components in the field + field->getArray()->getTuple( 1, val1 ); + // + MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> bc = + mesh->getBarycenterAndOwner(); // func is applied to barycenters of cells + double bc1[2]; // coordinates of the second point + bc->getTuple( 1, bc1 ); + // + double dist = sqrt( bc1[0]*bc1[0] + bc1[1]*bc1[1] ); // "sqrt( a*a + b*b )" + CPPUNIT_ASSERT_DOUBLES_EQUAL( val1[0], 10 + bc1[1], 13 ); // "10 + IVec * b" + CPPUNIT_ASSERT_DOUBLES_EQUAL( val1[1], 10 + bc1[0], 13 ); // "10 + JVec * a" + CPPUNIT_ASSERT_DOUBLES_EQUAL( val1[2], 10 + dist , 13 ); // "10 + KVec * sqrt( a*a + b*b )" + //! [CppSnippet_MEDCouplingMesh_fillFromAnalytic2_3] +} + +void CppExample_MEDCouplingMesh_fillFromAnalytic() +{ + using namespace ParaMEDMEM; + //! [CppSnippet_MEDCouplingMesh_fillFromAnalytic_1] + const double coords[4] = {0.,2.,4.,6.}; // 6. is not used + MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> x = DataArrayDouble::New(); + x->useExternalArrayWithRWAccess( coords, 3, 1 ); + MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> y = DataArrayDouble::New(); + y->useExternalArrayWithRWAccess( coords, 2, 1 ); + MEDCouplingAutoRefCountObjectPtr<MEDCouplingCMesh> mesh=MEDCouplingCMesh::New(); + mesh->setCoords(x,y); + //! [CppSnippet_MEDCouplingMesh_fillFromAnalytic_1] + //! [CppSnippet_MEDCouplingMesh_fillFromAnalytic_2] + const char func[] = "IVec * b + JVec * a + KVec * sqrt( a*a + b*b ) + 10"; + MEDCouplingAutoRefCountObjectPtr<MEDCouplingFieldDouble> field = + mesh->fillFromAnalytic( ParaMEDMEM::ON_CELLS, 3, func ); + //! [CppSnippet_MEDCouplingMesh_fillFromAnalytic_2] + //! [CppSnippet_MEDCouplingMesh_fillFromAnalytic_3] + double val1[3]; // a value (vector) of the cell #1 + CPPUNIT_ASSERT( field->getNumberOfComponents() == 3 ); // 3 components in the field + field->getArray()->getTuple( 1, val1 ); + // + MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> bc = + mesh->getBarycenterAndOwner(); // func is applied to barycenters of cells + double bc1[2]; // coordinates of the second point + bc->getTuple( 1, bc1 ); + // + double dist = sqrt( bc1[0]*bc1[0] + bc1[1]*bc1[1] ); // "sqrt( a*a + b*b )" + CPPUNIT_ASSERT_DOUBLES_EQUAL( val1[0], 10 + bc1[1], 13 ); // "10 + IVec * b" + CPPUNIT_ASSERT_DOUBLES_EQUAL( val1[1], 10 + bc1[0], 13 ); // "10 + JVec * a" + CPPUNIT_ASSERT_DOUBLES_EQUAL( val1[2], 10 + dist , 13 ); // "10 + KVec * sqrt( a*a + b*b )" + //! [CppSnippet_MEDCouplingMesh_fillFromAnalytic_3] +} + +void CppExample_MEDCouplingCMesh_getCoordsAt() +{ + using namespace ParaMEDMEM; + //! [CppSnippet_MEDCouplingCMesh_getCoordsAt_1] + const double coords[3] = {1.,2.,4.}; + MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> x = DataArrayDouble::New(); + x->useExternalArrayWithRWAccess( coords, 3, 1 ); + MEDCouplingAutoRefCountObjectPtr<MEDCouplingCMesh> mesh=MEDCouplingCMesh::New(); + mesh->setCoordsAt(0,x); + const DataArrayDouble* x2=mesh->getCoordsAt(0); + CPPUNIT_ASSERT( x2->isEqual( *x, 1e-13 )); + //! [CppSnippet_MEDCouplingCMesh_getCoordsAt_1] +} + +void CppExample_MEDCouplingUMesh_areCellsIncludedIn() +{ + using namespace ParaMEDMEM; + //! [CppSnippet_MEDCouplingUMesh_areCellsIncludedIn_1] + MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> mesh1=MEDCouplingUMesh::New(); + mesh1->setMeshDimension(2); + mesh1->allocateCells(5); + const int conn[18]={0,3,4,1, 1,4,2, 4,5,2, 6,7,4,3, 7,8,5,4}; + mesh1->insertNextCell(INTERP_KERNEL::NORM_QUAD4,4,conn); // #0 + mesh1->insertNextCell(INTERP_KERNEL::NORM_TRI3,3, conn+4); // #1 + mesh1->insertNextCell(INTERP_KERNEL::NORM_TRI3,3, conn+7); // #2 + mesh1->insertNextCell(INTERP_KERNEL::NORM_QUAD4,4,conn+10); // #3 + mesh1->insertNextCell(INTERP_KERNEL::NORM_QUAD4,4,conn+14); // #4 + mesh1->finishInsertingCells(); + MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> coordsArr=DataArrayDouble::New(); + coordsArr->alloc(9,2); + const double coords[18]={-0.3,-0.3, 0.2,-0.3, 0.7,-0.3, -0.3,0.2, 0.2,0.2, 0.7,0.2, -0.3,0.7, 0.2,0.7, 0.7,0.7 }; + std::copy(coords,coords+18,coordsArr->getPointer()); + mesh1->setCoords(coordsArr); + //! [CppSnippet_MEDCouplingUMesh_areCellsIncludedIn_1] + //! [CppSnippet_MEDCouplingUMesh_areCellsIncludedIn_2] + const int cells2[3] = { 4,2,0 }; // even cells selected + MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> mesh2 = + (MEDCouplingUMesh*) mesh1->buildPartOfMySelf( cells2, cells2+3, true ); + //! [CppSnippet_MEDCouplingUMesh_areCellsIncludedIn_2] + //! [CppSnippet_MEDCouplingUMesh_areCellsIncludedIn_3] + int compType = 0; // the strongest policy + DataArrayInt *corr2to1, *corr1to2; + // a larger mesh1 includes a smaller mesh2 + CPPUNIT_ASSERT( mesh1->areCellsIncludedIn( mesh2, compType, corr2to1 )); + CPPUNIT_ASSERT( std::equal( cells2, cells2+3, corr2to1->getConstPointer() )); + //! [CppSnippet_MEDCouplingUMesh_areCellsIncludedIn_3] + //! [CppSnippet_MEDCouplingUMesh_areCellsIncludedIn_4] + // the smaller mesh2 does NOT include the larger mesh1 + CPPUNIT_ASSERT( ! mesh2->areCellsIncludedIn( mesh1, compType, corr1to2 )); + const int corr1to2Expected[5] = {2, 3, 1, 4, 0}; + CPPUNIT_ASSERT(std::equal( corr1to2Expected, corr1to2Expected+5, corr1to2->getConstPointer() )); + //! [CppSnippet_MEDCouplingUMesh_areCellsIncludedIn_4] + corr2to1->decrRef(); + corr1to2->decrRef(); +} + +void CppExample_MEDCouplingUMesh_findAndCorrectBadOriented3DExtrudedCells() +{ + using namespace ParaMEDMEM; + //! [CppSnippet_MEDCouplingUMesh_findAndCorrectBadOriented3DExtrudedCells_1] + // 2D coordinates of 5 base nodes + const double coords[5*2]={-0.3,-0.3, 0.2,-0.3, 0.7,-0.3, -0.3,0.2, 0.2,0.2 }; + MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> coordsArr=DataArrayDouble::New(); + coordsArr->useExternalArrayWithRWAccess( coords, 5, 2 ); + // coordinates of 5 top nodes + MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> coordsArr2 = coordsArr->deepCpy(); + // 3D coordinates of base + top nodes + coordsArr = coordsArr-> changeNbOfComponents( 3, 0 ); + coordsArr2 = coordsArr2->changeNbOfComponents( 3, 1 ); + coordsArr = DataArrayDouble::Aggregate( coordsArr, coordsArr2 ); + // mesh + MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> mesh=MEDCouplingUMesh::New(); + mesh->setCoords(coordsArr); + mesh->setMeshDimension(3); + mesh->allocateCells(2); + // connectivity of reversed HEXA8 and PENTA6 + const int conn[8+6]={0,1,4,3, 5,6,9,8, 1,2,4, 6,7,9}; + mesh->insertNextCell(INTERP_KERNEL::NORM_HEXA8, 8,conn+0); + mesh->insertNextCell(INTERP_KERNEL::NORM_PENTA6,6,conn+8); + mesh->finishInsertingCells(); + //! [CppSnippet_MEDCouplingUMesh_findAndCorrectBadOriented3DExtrudedCells_1] + //! [CppSnippet_MEDCouplingUMesh_findAndCorrectBadOriented3DExtrudedCells_2] + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> fixedCells = + mesh->findAndCorrectBadOriented3DExtrudedCells(); + CPPUNIT_ASSERT( fixedCells->getNumberOfTuples() == 2 ); // 2 cells fixed + fixedCells = mesh->findAndCorrectBadOriented3DExtrudedCells(); + CPPUNIT_ASSERT( fixedCells->getNumberOfTuples() == 0 ); // no bad cells + //! [CppSnippet_MEDCouplingUMesh_findAndCorrectBadOriented3DExtrudedCells_2] +} + +void CppExample_MEDCouplingUMesh_arePolyhedronsNotCorrectlyOriented() +{ + using namespace ParaMEDMEM; + //! [CppSnippet_MEDCouplingUMesh_arePolyhedronsNotCorrectlyOriented_1] + // 2D coordinates of 5 base nodes + const double coords[5*2]={-0.3,-0.3, 0.2,-0.3, 0.7,-0.3, -0.3,0.2, 0.2,0.2 }; + MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> coordsArr=DataArrayDouble::New(); + coordsArr->useExternalArrayWithRWAccess( coords, 5, 2 ); + // coordinates of 5 top nodes + MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> coordsArr2 = coordsArr->deepCpy(); + // 3D coordinates of base + top nodes + coordsArr = coordsArr-> changeNbOfComponents( 3, 0 ); + coordsArr2 = coordsArr2->changeNbOfComponents( 3, 1 ); + coordsArr = DataArrayDouble::Aggregate( coordsArr, coordsArr2 ); + // mesh + MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> mesh=MEDCouplingUMesh::New(); + mesh->setCoords(coordsArr); + mesh->setMeshDimension(3); + mesh->allocateCells(2); + // connectivity of a HEXA8 + a reversed PENTA6 + const int conn[8+6]={0,3,4,1, 5,8,9,6, 1,2,4, 6,7,9}; + mesh->insertNextCell(INTERP_KERNEL::NORM_POLYHED,8,conn); // "extruded" polyhedron + mesh->insertNextCell(INTERP_KERNEL::NORM_POLYHED,6,conn+8); + mesh->finishInsertingCells(); + // fix connectivity of NORM_POLYHED's + mesh->convertExtrudedPolyhedra(); + //! [CppSnippet_MEDCouplingUMesh_arePolyhedronsNotCorrectlyOriented_1] + //! [CppSnippet_MEDCouplingUMesh_arePolyhedronsNotCorrectlyOriented_2] + std::vector<int> badCellIds; + mesh->arePolyhedronsNotCorrectlyOriented( badCellIds ); + CPPUNIT_ASSERT( badCellIds.size() == 1 ); // one polyhedron is KO + // fix invalid rolyherdons + mesh->orientCorrectlyPolyhedrons(); + // re-check orientation + badCellIds.clear(); // as badCellIds is not cleared by arePolyhedronsNotCorrectlyOriented() + mesh->arePolyhedronsNotCorrectlyOriented( badCellIds ); + CPPUNIT_ASSERT( badCellIds.size() == 0 ); // connectivity is OK + //! [CppSnippet_MEDCouplingUMesh_arePolyhedronsNotCorrectlyOriented_2] +} + +void CppExample_MEDCouplingUMesh_are2DCellsNotCorrectlyOriented() +{ + using namespace ParaMEDMEM; + //! [CppSnippet_MEDCouplingUMesh_are2DCellsNotCorrectlyOriented_1] + MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> mesh=MEDCouplingUMesh::New(); + mesh->setMeshDimension(2); + mesh->allocateCells(5); + const int conn[18]={0,3,4,1, 1,2,4, 4,5,2, 6,7,4,3, 7,8,5,4}; + mesh->insertNextCell(INTERP_KERNEL::NORM_QUAD4,4,conn); // 0 + mesh->insertNextCell(INTERP_KERNEL::NORM_TRI3,3, conn+4); // 1 + mesh->insertNextCell(INTERP_KERNEL::NORM_TRI3,3, conn+7); // 2 + mesh->insertNextCell(INTERP_KERNEL::NORM_QUAD4,4,conn+10); // 3 + mesh->insertNextCell(INTERP_KERNEL::NORM_QUAD4,4,conn+14); // 4 + mesh->finishInsertingCells(); + MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> coordsArr=DataArrayDouble::New(); + coordsArr->alloc(9,2); + const double coords[18]={-0.3,-0.3, 0.2,-0.3, 0.7,-0.3, -0.3,0.2, 0.2,0.2, 0.7,0.2, -0.3,0.7, 0.2,0.7, 0.7,0.7 }; + std::copy(coords,coords+18,coordsArr->getPointer()); + mesh->setCoords(coordsArr); + mesh->changeSpaceDimension(3); + //! [CppSnippet_MEDCouplingUMesh_are2DCellsNotCorrectlyOriented_1] + //! [CppSnippet_MEDCouplingUMesh_are2DCellsNotCorrectlyOriented_2] + const double vec[3] = {0.,0.,-1.}; + std::vector<int> badCellIds; + mesh->are2DCellsNotCorrectlyOriented( vec, false, badCellIds ); + CPPUNIT_ASSERT( badCellIds.size() == 1 ); // one cell is reversed + // fix orientation + mesh->orientCorrectly2DCells( vec, false ); + // re-check orientation + badCellIds.clear(); // as badCellIds is not cleared by are2DCellsNotCorrectlyOriented() + mesh->are2DCellsNotCorrectlyOriented( vec, false, badCellIds ); + CPPUNIT_ASSERT( badCellIds.size() == 0 ); // the orientation is OK + //! [CppSnippet_MEDCouplingUMesh_are2DCellsNotCorrectlyOriented_2] +} + +void CppExample_MEDCouplingUMesh_getCellsContainingPoints() +{ + using namespace ParaMEDMEM; + //! [CppSnippet_MEDCouplingUMesh_getCellsContainingPoints_1] + MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> mesh=MEDCouplingUMesh::New(); + mesh->setMeshDimension(2); + mesh->allocateCells(5); + const int conn[18]={0,3,4,1, 1,4,2, 4,5,2, 6,7,4,3, 7,8,5,4}; + mesh->insertNextCell(INTERP_KERNEL::NORM_QUAD4,4,conn); + mesh->insertNextCell(INTERP_KERNEL::NORM_TRI3,3, conn+4); + mesh->insertNextCell(INTERP_KERNEL::NORM_TRI3,3, conn+7); + mesh->insertNextCell(INTERP_KERNEL::NORM_QUAD4,4,conn+10); + mesh->insertNextCell(INTERP_KERNEL::NORM_QUAD4,4,conn+14); + mesh->finishInsertingCells(); + MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> coordsArr=DataArrayDouble::New(); + coordsArr->alloc(9,2); + const double coords[18]={-0.3,-0.3, 0.2,-0.3, 0.7,-0.3, -0.3,0.2, 0.2,0.2, 0.7,0.2, -0.3,0.7, 0.2,0.7, 0.7,0.7 }; + std::copy(coords,coords+18,coordsArr->getPointer()); + mesh->setCoords(coordsArr); + //! [CppSnippet_MEDCouplingUMesh_getCellsContainingPoints_1] + //! [CppSnippet_MEDCouplingUMesh_getCellsContainingPoints_2] + const double pos[3*2] = { 10., 10, // point out of the mesh + 0.3, 0.3, // point located somewhere inside the mesh + coords[2], coords[3]}; // point at the node #1 + const double eps = 1e-4; // ball radius + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> cells, cellsIndex; + mesh->getCellsContainingPoints( pos, 3, eps, cells, cellsIndex ); + const int cellsExpected[3]={4, 0, 1}; + const int cellsIndexExpected[4]={0, 0, 1, 3}; + CPPUNIT_ASSERT(std::equal( cellsExpected, cellsExpected+3, cells->begin())); + CPPUNIT_ASSERT(std::equal( cellsIndexExpected, cellsIndexExpected+4, cellsIndex->begin())); + //! [CppSnippet_MEDCouplingUMesh_getCellsContainingPoints_2] +} + +void CppExample_MEDCouplingUMesh_getCellsContainingPoint() +{ + using namespace ParaMEDMEM; + //! [CppSnippet_MEDCouplingUMesh_getCellsContainingPoint_1] + MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> mesh=MEDCouplingUMesh::New(); + mesh->setMeshDimension(2); + mesh->allocateCells(5); + const int conn[18]={0,3,4,1, 1,4,2, 4,5,2, 6,7,4,3, 7,8,5,4}; + mesh->insertNextCell(INTERP_KERNEL::NORM_QUAD4,4,conn); // 0 + mesh->insertNextCell(INTERP_KERNEL::NORM_TRI3,3, conn+4); // 1 + mesh->insertNextCell(INTERP_KERNEL::NORM_TRI3,3, conn+7); // 2 + mesh->insertNextCell(INTERP_KERNEL::NORM_QUAD4,4,conn+10); // 3 + mesh->insertNextCell(INTERP_KERNEL::NORM_QUAD4,4,conn+14); // 4 + mesh->finishInsertingCells(); + MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> coordsArr=DataArrayDouble::New(); + coordsArr->alloc(9,2); + const double coords[18]={-0.3,-0.3, 0.2,-0.3, 0.7,-0.3, -0.3,0.2, 0.2,0.2, 0.7,0.2, -0.3,0.7, 0.2,0.7, 0.7,0.7 }; + std::copy(coords,coords+18,coordsArr->getPointer()); + mesh->setCoords(coordsArr); + //! [CppSnippet_MEDCouplingUMesh_getCellsContainingPoint_1] + //! [CppSnippet_MEDCouplingUMesh_getCellsContainingPoint_2] + const double* coords4 = coords + 4*2; // coordinates of the node #4 + const double eps = 1e-4; // ball radius + const double pos[2] = { coords4[0] + eps, coords4[1] - eps }; // ball center + std::vector<int> cellIds; + mesh->getCellsContainingPoint( pos, eps, cellIds ); + CPPUNIT_ASSERT ( (int)cellIds.size() == mesh->getNumberOfCells() ); + //! [CppSnippet_MEDCouplingUMesh_getCellsContainingPoint_2] +} + +void CppExample_MEDCouplingUMesh_buildPartOrthogonalField() +{ + using namespace ParaMEDMEM; + //! [CppSnippet_MEDCouplingUMesh_buildPartOrthogonalField_1] + MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> mesh=MEDCouplingUMesh::New(); + mesh->setMeshDimension(2); + mesh->allocateCells(5); + const int conn[18]={0,3,4,1, 1,4,2, 4,5,2, 6,7,4,3, 7,8,5,4}; + mesh->insertNextCell(INTERP_KERNEL::NORM_QUAD4,4,conn); // 0 + mesh->insertNextCell(INTERP_KERNEL::NORM_TRI3,3, conn+4); // 1 + mesh->insertNextCell(INTERP_KERNEL::NORM_TRI3,3, conn+7); // 2 + mesh->insertNextCell(INTERP_KERNEL::NORM_QUAD4,4,conn+10); // 3 + mesh->insertNextCell(INTERP_KERNEL::NORM_QUAD4,4,conn+14); // 4 + mesh->finishInsertingCells(); + MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> coordsArr=DataArrayDouble::New(); + coordsArr->alloc(9,2); + const double coords[18]={-0.3,-0.3, 0.2,-0.3, 0.7,-0.3, -0.3,0.2, 0.2,0.2, 0.7,0.2, -0.3,0.7, 0.2,0.7, 0.7,0.7 }; + std::copy(coords,coords+18,coordsArr->getPointer()); + mesh->setCoords(coordsArr); + //! [CppSnippet_MEDCouplingUMesh_buildPartOrthogonalField_1] + //! [CppSnippet_MEDCouplingUMesh_buildPartOrthogonalField_2] + const int part[4] = {1,2,3,4}; // cell #0 is omitted + MEDCouplingAutoRefCountObjectPtr<MEDCouplingFieldDouble> vecField= + mesh->buildPartOrthogonalField( part, part+4 ); + CPPUNIT_ASSERT ( vecField->getArray()->getNumberOfTuples() == 4 ); + CPPUNIT_ASSERT ( vecField->getArray()->getNumberOfComponents() == 3 ); + //! [CppSnippet_MEDCouplingUMesh_buildPartOrthogonalField_2] +} + +void CppExample_MEDCouplingUMesh_getPartMeasureField() +{ + using namespace ParaMEDMEM; + //! [CppSnippet_MEDCouplingUMesh_getPartMeasureField_1] + MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> mesh=MEDCouplingUMesh::New(); + mesh->setMeshDimension(2); + mesh->allocateCells(5); + const int conn[18]={0,3,4,1, 1,2,4, 4,5,2, 6,7,4,3, 7,8,5,4}; + mesh->insertNextCell(INTERP_KERNEL::NORM_QUAD4,4,conn); // 0 + mesh->insertNextCell(INTERP_KERNEL::NORM_TRI3,3, conn+4); // 1 + mesh->insertNextCell(INTERP_KERNEL::NORM_TRI3,3, conn+7); // 2 + mesh->insertNextCell(INTERP_KERNEL::NORM_QUAD4,4,conn+10); // 3 + mesh->insertNextCell(INTERP_KERNEL::NORM_QUAD4,4,conn+14); // 4 + mesh->finishInsertingCells(); + MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> coordsArr=DataArrayDouble::New(); + coordsArr->alloc(9,2); + const double coords[18]={-0.3,-0.3, 0.2,-0.3, 0.7,-0.3, -0.3,0.2, 0.2,0.2, 0.7,0.2, -0.3,0.7, 0.2,0.7, 0.7,0.7 }; + std::copy(coords,coords+18,coordsArr->getPointer()); + mesh->setCoords(coordsArr); + //! [CppSnippet_MEDCouplingUMesh_getPartMeasureField_1] + //! [CppSnippet_MEDCouplingUMesh_getPartMeasureField_2] + const bool isAbs = true; + const int part[4] = {1,2,3,4}; // cell #0 is omitted + MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> areaArr= + mesh->getPartMeasureField( isAbs, part, part+4 ); + CPPUNIT_ASSERT( areaArr->getIJ(0,0) > 0 ); // orientation ignored + areaArr=mesh->getPartMeasureField( !isAbs, part, part+4 ); + CPPUNIT_ASSERT( areaArr->getIJ(0,0) < 0 ); // orientation considered + CPPUNIT_ASSERT ( areaArr->getNumberOfTuples() == 4 ); + //! [CppSnippet_MEDCouplingUMesh_getPartMeasureField_2] + //! [CppSnippet_MEDCouplingUMesh_getPartMeasureField_3] + const int cellIds[4] = {1,2,3,4}; // cell #0 is omitted + MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> baryCenters= + mesh->getPartBarycenterAndOwner( cellIds, cellIds+4 ); + CPPUNIT_ASSERT( baryCenters->getNumberOfTuples() == 4 ); + CPPUNIT_ASSERT( baryCenters->getNumberOfComponents() == mesh->getSpaceDimension() ); + //! [CppSnippet_MEDCouplingUMesh_getPartMeasureField_3] +} + +void CppExample_MEDCouplingUMesh_getCellsInBoundingBox() +{ + using namespace ParaMEDMEM; + //! [CppSnippet_MEDCouplingUMesh_getCellsInBoundingBox_1] + MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> mesh=MEDCouplingUMesh::New(); + mesh->setMeshDimension(2); + mesh->allocateCells(1); + const double coords[3*2]={0.,0., 0.,1., 1.,1}; + MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> coordsArr=DataArrayDouble::New(); + coordsArr->useExternalArrayWithRWAccess(coords, 3,2); + mesh->setCoords(coordsArr); + mesh->allocateCells(1); + const int conn[3]={0,1,2}; + mesh->insertNextCell(INTERP_KERNEL::NORM_TRI3,3,conn); + mesh->finishInsertingCells(); + //! [CppSnippet_MEDCouplingUMesh_getCellsInBoundingBox_1] + //! [CppSnippet_MEDCouplingUMesh_getCellsInBoundingBox_2] + const double bbox[] = {1., 1., 1.001,1.001}; // xMin, xMax, yMin, yMax + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> cellIdsArr = + mesh->getCellsInBoundingBox( bbox, 0.0 ); + CPPUNIT_ASSERT( cellIdsArr->getNumberOfTuples() == 0 ); + cellIdsArr = mesh->getCellsInBoundingBox( bbox, 0.1 ); + CPPUNIT_ASSERT( cellIdsArr->getNumberOfTuples() == 1 ); + //! [CppSnippet_MEDCouplingUMesh_getCellsInBoundingBox_2] +} + +void CppExample_MEDCouplingUMesh_renumberNodesInConn() +{ + using namespace ParaMEDMEM; + //! [CppSnippet_MEDCouplingUMesh_renumberNodesInConn_1] + MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> mesh=MEDCouplingUMesh::New(); + mesh->setMeshDimension(2); + mesh->allocateCells(1); + const int conn[4]={4,3,2,1}; + mesh->insertNextCell(INTERP_KERNEL::NORM_QUAD4,4,conn); + mesh->finishInsertingCells(); + //! [CppSnippet_MEDCouplingUMesh_renumberNodesInConn_1] + //! [CppSnippet_MEDCouplingUMesh_renumberNodesInConn_2] + const int old2newIds[] = {-1,3,2,1,0}; + mesh->renumberNodesInConn( old2newIds ); + const int nodes0Expected[] = {0,1,2,3}; + std::vector<int> nodes0; + mesh->getNodeIdsOfCell( 0, nodes0 ); + CPPUNIT_ASSERT(std::equal( nodes0Expected, nodes0Expected+4, &nodes0[0] )); + //! [CppSnippet_MEDCouplingUMesh_renumberNodesInConn_2] +} + +void CppExample_MEDCouplingUMesh_renumberNodes() +{ + using namespace ParaMEDMEM; + //! [CppSnippet_MEDCouplingUMesh_renumberNodes_1] + MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> mesh=MEDCouplingUMesh::New(); + mesh->setMeshDimension(2); + const double coords[4*2]={-0.3,-0.3, 0.2,-0.3, 0.7,-0.3, -0.3,0.3}; + MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> coordsArr=DataArrayDouble::New(); + coordsArr->useExternalArrayWithRWAccess(coords, 4,2); + mesh->setCoords(coordsArr); + mesh->allocateCells(0); + mesh->finishInsertingCells(); + //! [CppSnippet_MEDCouplingUMesh_renumberNodes_1] + //! [CppSnippet_MEDCouplingUMesh_renumberNodes_2] + const int newIds[] = { 2,1,0,-1 }; + mesh->renumberNodes(newIds, 3); + coordsArr = mesh->getCoordinatesAndOwner(); // get a shorten array + const double coordsExpected[3*2]={0.7,-0.3, 0.2,-0.3, -0.3,-0.3}; + MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> coordsExpectedArr=DataArrayDouble::New(); + coordsExpectedArr->useExternalArrayWithRWAccess(coordsExpected, 3,2); + CPPUNIT_ASSERT( coordsExpectedArr->isEqual( *coordsArr, 1e-13 )); + //! [CppSnippet_MEDCouplingUMesh_renumberNodes_2] + //! [CppSnippet_MEDCouplingUMesh_renumberNodes_3] + coordsArr->useExternalArrayWithRWAccess(coords, 4,2); // restore old nodes + const int newIds2[] = { 2,1,0,2 }; + mesh->renumberNodes2(newIds2, 3); + coordsArr = mesh->getCoordinatesAndOwner(); // get a shorten array + const double coordsExpected2[3*2]={0.7,-0.3, 0.2,-0.3, -0.3, 0.0}; + MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> coordsExpectedArr2=DataArrayDouble::New(); + coordsExpectedArr2->useExternalArrayWithRWAccess(coordsExpected2, 3,2); + CPPUNIT_ASSERT( coordsExpectedArr2->isEqual( *coordsArr, 1e-13 )); + //! [CppSnippet_MEDCouplingUMesh_renumberNodes_3] +} + +void CppExample_MEDCouplingUMesh_findBoundaryNodes() +{ + using namespace ParaMEDMEM; + //! [CppSnippet_MEDCouplingUMesh_findBoundaryNodes_1] + MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> mesh=MEDCouplingUMesh::New(); + mesh->setMeshDimension(2); + mesh->allocateCells(5); + const int conn[18]={0,3,4,1, 1,4,2, 4,5,2, 6,7,4,3, 7,8,5,4}; + mesh->insertNextCell(INTERP_KERNEL::NORM_QUAD4,4,conn); + mesh->insertNextCell(INTERP_KERNEL::NORM_TRI3,3, conn+4); + mesh->insertNextCell(INTERP_KERNEL::NORM_TRI3,3, conn+7); + mesh->insertNextCell(INTERP_KERNEL::NORM_QUAD4,4,conn+10); + mesh->insertNextCell(INTERP_KERNEL::NORM_QUAD4,4,conn+14); + mesh->finishInsertingCells(); + MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> coordsArr=DataArrayDouble::New(); + coordsArr->alloc(9,2); + const double coords[18]={-0.3,-0.3, 0.2,-0.3, 0.7,-0.3, -0.3,0.2, 0.2,0.2, 0.7,0.2, -0.3,0.7, 0.2,0.7, 0.7,0.7 }; + std::copy(coords,coords+18,coordsArr->getPointer()); + mesh->setCoords(coordsArr); + //! [CppSnippet_MEDCouplingUMesh_findBoundaryNodes_1] + //! [CppSnippet_MEDCouplingUMesh_findBoundaryNodes_2] + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> nodeIdsArr=mesh->findBoundaryNodes(); + CPPUNIT_ASSERT( nodeIdsArr->getNumberOfTuples() == mesh->getNumberOfNodes() - 1 ); + //! [CppSnippet_MEDCouplingUMesh_findBoundaryNodes_2] +} + +void CppExample_MEDCouplingUMesh_buildBoundaryMesh() +{ + using namespace ParaMEDMEM; + //! [CppSnippet_MEDCouplingUMesh_buildBoundaryMesh_1] + MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> mesh=MEDCouplingUMesh::New(); + mesh->setMeshDimension(2); + mesh->allocateCells(5); + const int conn[18]={0,3,4,1, 1,4,2, 4,5,2, 6,7,4,3, 7,8,5,4}; + mesh->insertNextCell(INTERP_KERNEL::NORM_QUAD4,4,conn); + mesh->insertNextCell(INTERP_KERNEL::NORM_TRI3,3, conn+4); + mesh->insertNextCell(INTERP_KERNEL::NORM_TRI3,3, conn+7); + mesh->insertNextCell(INTERP_KERNEL::NORM_QUAD4,4,conn+10); + mesh->insertNextCell(INTERP_KERNEL::NORM_QUAD4,4,conn+14); + mesh->finishInsertingCells(); + MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> coordsArr=DataArrayDouble::New(); + coordsArr->alloc(9,2); + const double coords[18]={-0.3,-0.3, 0.2,-0.3, 0.7,-0.3, -0.3,0.2, 0.2,0.2, 0.7,0.2, -0.3,0.7, 0.2,0.7, 0.7,0.7 }; + std::copy(coords,coords+18,coordsArr->getPointer()); + mesh->setCoords(coordsArr); + //! [CppSnippet_MEDCouplingUMesh_buildBoundaryMesh_1] + //! [CppSnippet_MEDCouplingUMesh_buildBoundaryMesh_2] + MEDCouplingAutoRefCountObjectPtr<MEDCouplingPointSet> mesh1=mesh->buildBoundaryMesh(true); + MEDCouplingAutoRefCountObjectPtr<MEDCouplingPointSet> mesh2=mesh->buildBoundaryMesh(false); + CPPUNIT_ASSERT( coordsArr->isEqual( *mesh1->getCoords(), 1e-13 )); // same nodes + CPPUNIT_ASSERT( !coordsArr->isEqual( *mesh2->getCoords(), 1e-13 )); // different nodes + //! [CppSnippet_MEDCouplingUMesh_buildBoundaryMesh_2] +} + +void CppExample_MEDCouplingUMesh_buildFacePartOfMySelfNode() +{ + using namespace ParaMEDMEM; + //! [CppSnippet_MEDCouplingUMesh_buildFacePartOfMySelfNode_1] + MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> mesh=MEDCouplingUMesh::New(); + mesh->setMeshDimension(2); + mesh->allocateCells(5); + const int conn[18]={0,3,4,1, 1,4,2, 4,5,2, 6,7,4,3, 7,8,5,4}; + mesh->insertNextCell(INTERP_KERNEL::NORM_QUAD4,4,conn); // 0 + mesh->insertNextCell(INTERP_KERNEL::NORM_TRI3,3, conn+4); // 1 + mesh->insertNextCell(INTERP_KERNEL::NORM_TRI3,3, conn+7); // 2 + mesh->insertNextCell(INTERP_KERNEL::NORM_QUAD4,4,conn+10); // 3 + mesh->insertNextCell(INTERP_KERNEL::NORM_QUAD4,4,conn+14); // 4 + mesh->finishInsertingCells(); + MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> coordsArr=DataArrayDouble::New(); + coordsArr->alloc(9,2); + const double coords[18]={-0.3,-0.3, 0.2,-0.3, 0.7,-0.3, -0.3,0.2, 0.2,0.2, 0.7,0.2, -0.3,0.7, 0.2,0.7, 0.7,0.7 }; + std::copy(coords,coords+18,coordsArr->getPointer()); + mesh->setCoords(coordsArr); + //! [CppSnippet_MEDCouplingUMesh_buildFacePartOfMySelfNode_1] + //! [CppSnippet_MEDCouplingUMesh_buildFacePartOfMySelfNode_2] + std::vector<int> nodes; + mesh->getNodeIdsOfCell( 0, nodes ); + const bool allNodes = true; + MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> mesh1 = + (MEDCouplingUMesh*)mesh->buildFacePartOfMySelfNode( &nodes[0],&nodes[0]+nodes.size(),allNodes); + CPPUNIT_ASSERT( mesh1->getNumberOfCells() == 4 ); // 4 segments bounding QUAD4 #0 only + MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> mesh2 = + (MEDCouplingUMesh*)mesh->buildFacePartOfMySelfNode( &nodes[0],&nodes[0]+nodes.size(),!allNodes); + CPPUNIT_ASSERT( mesh2->getNumberOfCells() == 9 ); // more segments added + //! [CppSnippet_MEDCouplingUMesh_buildFacePartOfMySelfNode_2] +} + +void CppExample_MEDCouplingUMesh_buildPartOfMySelfNode() +{ + using namespace ParaMEDMEM; + //! [CppSnippet_MEDCouplingUMesh_buildPartOfMySelfNode_1] + MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> mesh=MEDCouplingUMesh::New(); + mesh->setMeshDimension(2); + mesh->allocateCells(5); + const int conn[18]={0,3,4,1, 1,4,2, 4,5,2, 6,7,4,3, 7,8,5,4}; + mesh->insertNextCell(INTERP_KERNEL::NORM_QUAD4,4,conn); // 0 + mesh->insertNextCell(INTERP_KERNEL::NORM_TRI3,3, conn+4); // 1 + mesh->insertNextCell(INTERP_KERNEL::NORM_TRI3,3, conn+7); // 2 + mesh->insertNextCell(INTERP_KERNEL::NORM_QUAD4,4,conn+10); // 3 + mesh->insertNextCell(INTERP_KERNEL::NORM_QUAD4,4,conn+14); // 4 + mesh->finishInsertingCells(); + MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> coordsArr=DataArrayDouble::New(); + coordsArr->alloc(9,2); + const double coords[18]={-0.3,-0.3, 0.2,-0.3, 0.7,-0.3, -0.3,0.2, 0.2,0.2, 0.7,0.2, -0.3,0.7, 0.2,0.7, 0.7,0.7 }; + std::copy(coords,coords+18,coordsArr->getPointer()); + mesh->setCoords(coordsArr); + //! [CppSnippet_MEDCouplingUMesh_buildPartOfMySelfNode_1] + //! [CppSnippet_MEDCouplingUMesh_buildPartOfMySelfNode_2] + std::vector<int> nodes; + mesh->getNodeIdsOfCell( 0, nodes ); + const bool allNodes = true; + MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> mesh1 = + (MEDCouplingUMesh*)mesh->buildPartOfMySelfNode( &nodes[0], &nodes[0]+nodes.size(), allNodes); + MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> mesh2 = + (MEDCouplingUMesh*)mesh->buildPartOfMySelfNode( &nodes[0], &nodes[0]+nodes.size(),!allNodes); + CPPUNIT_ASSERT_EQUAL( mesh1->getNumberOfCells(), 1 ); + CPPUNIT_ASSERT_EQUAL( mesh2->getNumberOfCells(), mesh->getNumberOfCells() ); + //! [CppSnippet_MEDCouplingUMesh_buildPartOfMySelfNode_2] +} + +void CppExample_MEDCouplingUMesh_getCellIdsLyingOnNodes() +{ + using namespace ParaMEDMEM; + //! [CppSnippet_MEDCouplingUMesh_getCellIdsLyingOnNodes_1] + MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> mesh=MEDCouplingUMesh::New(); + mesh->setMeshDimension(2); + mesh->allocateCells(5); + const int conn[18]={0,3,4,1, 1,4,2, 4,5,2, 6,7,4,3, 7,8,5,4}; + mesh->insertNextCell(INTERP_KERNEL::NORM_QUAD4,4,conn); // 0 + mesh->insertNextCell(INTERP_KERNEL::NORM_TRI3,3, conn+4); // 1 + mesh->insertNextCell(INTERP_KERNEL::NORM_TRI3,3, conn+7); // 2 + mesh->insertNextCell(INTERP_KERNEL::NORM_QUAD4,4,conn+10); // 3 + mesh->insertNextCell(INTERP_KERNEL::NORM_QUAD4,4,conn+14); // 4 + mesh->finishInsertingCells(); + MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> coordsArr=DataArrayDouble::New(); + coordsArr->alloc(9,2); + const double coords[18]={-0.3,-0.3, 0.2,-0.3, 0.7,-0.3, -0.3,0.2, 0.2,0.2, 0.7,0.2, -0.3,0.7, 0.2,0.7, 0.7,0.7 }; + std::copy(coords,coords+18,coordsArr->getPointer()); + mesh->setCoords(coordsArr); + //! [CppSnippet_MEDCouplingUMesh_getCellIdsLyingOnNodes_1] + //! [CppSnippet_MEDCouplingUMesh_getCellIdsLyingOnNodes_2] + std::vector<int> nodes; + mesh->getNodeIdsOfCell( 0, nodes ); + const bool allNodes = true; + DataArrayInt* cellIdsArr1 = mesh->getCellIdsLyingOnNodes( &nodes[0], &nodes[0]+nodes.size(), allNodes); + DataArrayInt* cellIdsArr2 = mesh->getCellIdsLyingOnNodes( &nodes[0], &nodes[0]+nodes.size(),!allNodes); + CPPUNIT_ASSERT_EQUAL( cellIdsArr1->getNumberOfTuples(), 1 ); + CPPUNIT_ASSERT_EQUAL( cellIdsArr2->getNumberOfTuples(), mesh->getNumberOfCells() ); + //! [CppSnippet_MEDCouplingUMesh_getCellIdsLyingOnNodes_2] + cellIdsArr1->decrRef(); + cellIdsArr2->decrRef(); +} + +void CppExample_MEDCouplingUMesh_getCellIdsFullyIncludedInNodeIds() +{ + using namespace ParaMEDMEM; + //! [CppSnippet_MEDCouplingUMesh_getCellIdsFullyIncludedInNodeIds_1] + MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> mesh=MEDCouplingUMesh::New(); + mesh->setMeshDimension(2); + mesh->allocateCells(5); + const int conn[18]={0,3,4,1, 1,4,2, 4,5,2, 6,7,4,3, 7,8,5,4}; + mesh->insertNextCell(INTERP_KERNEL::NORM_QUAD4,4,conn); + mesh->insertNextCell(INTERP_KERNEL::NORM_TRI3,3, conn+4); + mesh->insertNextCell(INTERP_KERNEL::NORM_TRI3,3, conn+7); + mesh->insertNextCell(INTERP_KERNEL::NORM_QUAD4,4,conn+10); + mesh->insertNextCell(INTERP_KERNEL::NORM_QUAD4,4,conn+14); + mesh->finishInsertingCells(); + MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> coordsArr=DataArrayDouble::New(); + coordsArr->alloc(9,2); + const double coords[18]={-0.3,-0.3, 0.2,-0.3, 0.7,-0.3, -0.3,0.2, 0.2,0.2, 0.7,0.2, -0.3,0.7, 0.2,0.7, 0.7,0.7 }; + std::copy(coords,coords+18,coordsArr->getPointer()); + mesh->setCoords(coordsArr); + //! [CppSnippet_MEDCouplingUMesh_getCellIdsFullyIncludedInNodeIds_1] + //! [CppSnippet_MEDCouplingUMesh_getCellIdsFullyIncludedInNodeIds_2] + const int cellIds[2]={1,2}; + std::vector<int> nodes; + mesh->getNodeIdsOfCell( cellIds[0], nodes ); + mesh->getNodeIdsOfCell( cellIds[1], nodes ); + DataArrayInt* cellIdsArr = mesh->getCellIdsFullyIncludedInNodeIds( &nodes[0], &nodes[0]+nodes.size()); + CPPUNIT_ASSERT(std::equal( cellIds, cellIds+2, cellIdsArr->getPointer() )); + //! [CppSnippet_MEDCouplingUMesh_getCellIdsFullyIncludedInNodeIds_2] + cellIdsArr->decrRef(); +} + +void CppExample_MEDCouplingUMesh_buildPartOfMySelf() +{ + using namespace ParaMEDMEM; + //! [CppSnippet_MEDCouplingUMesh_buildPartOfMySelf_1] + MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> mesh=MEDCouplingUMesh::New(); + mesh->setMeshDimension(2); + mesh->allocateCells(5); + const int conn[18]={0,3,4,1, 1,4,2, 4,5,2, 6,7,4,3, 7,8,5,4}; + mesh->insertNextCell(INTERP_KERNEL::NORM_QUAD4,4,conn); // 0 + mesh->insertNextCell(INTERP_KERNEL::NORM_TRI3,3, conn+4); // 1 + mesh->insertNextCell(INTERP_KERNEL::NORM_TRI3,3, conn+7); // 2 + mesh->insertNextCell(INTERP_KERNEL::NORM_QUAD4,4,conn+10); // 3 + mesh->insertNextCell(INTERP_KERNEL::NORM_QUAD4,4,conn+14); // 4 + mesh->finishInsertingCells(); + MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> coordsArr=DataArrayDouble::New(); + coordsArr->alloc(9,2); + const double coords[18]={-0.3,-0.3, 0.2,-0.3, 0.7,-0.3, -0.3,0.2, 0.2,0.2, 0.7,0.2, -0.3,0.7, 0.2,0.7, 0.7,0.7 }; + std::copy(coords,coords+18,coordsArr->getPointer()); + mesh->setCoords(coordsArr); + //! [CppSnippet_MEDCouplingUMesh_buildPartOfMySelf_1] + //! [CppSnippet_MEDCouplingUMesh_buildPartOfMySelf_2] + const int cellIds[2]={1,2}; + MEDCouplingUMesh* mesh2=(MEDCouplingUMesh*)mesh->buildPartOfMySelf(cellIds,cellIds+2,true); + MEDCouplingUMesh* mesh3=(MEDCouplingUMesh*)mesh->buildPartOfMySelf(cellIds,cellIds+2,false); + CPPUNIT_ASSERT( coordsArr->isEqual( *mesh2->getCoords(), 1e-13 )); // same nodes + CPPUNIT_ASSERT( !coordsArr->isEqual( *mesh3->getCoords(), 1e-13 )); // different nodes + for ( int i = 0; i < 2; ++i ) + { + std::vector<int> nodes1, nodes2; + mesh ->getNodeIdsOfCell(cellIds[i], nodes1); + mesh2->getNodeIdsOfCell(i, nodes2); + CPPUNIT_ASSERT( nodes1 == nodes2 ); // cell #cellIds[i] was copied + } + //! [CppSnippet_MEDCouplingUMesh_buildPartOfMySelf_2] + mesh2->decrRef(); + mesh3->decrRef(); +} + +void CppExample_MEDCouplingUMesh_mergeNodes() +{ + using namespace ParaMEDMEM; + //! [CppSnippet_MEDCouplingUMesh_mergeNodes_1] + MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> mesh=MEDCouplingUMesh::New(); + mesh->setMeshDimension(2); + mesh->allocateCells(5); + const int conn[18]={0,3,4,1, 1,4,2, 4,5,2}; + mesh->insertNextCell(INTERP_KERNEL::NORM_QUAD4,4,conn); + mesh->insertNextCell(INTERP_KERNEL::NORM_TRI3,3, conn+4); + mesh->insertNextCell(INTERP_KERNEL::NORM_TRI3,3, conn+7); + mesh->finishInsertingCells(); + const double coords[6*2]={0.3,-0.301, // #0 + 0.2,-0.3, // #1 + 0.3,-0.302, // #2 ~~ #0 + 1.1,0.0, // #3 + 1.1,0.0, // #4 == #3 + 0.3,-0.303}; // #5 ~~ #0 + MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> coordsArr=DataArrayDouble::New(); + coordsArr->alloc(6,2); + std::copy(coords,coords+6*2,coordsArr->getPointer()); + mesh->setCoords(coordsArr); + //! [CppSnippet_MEDCouplingUMesh_mergeNodes_1] + //! [CppSnippet_MEDCouplingUMesh_mergeNodes_2] + bool areNodesMerged; int newNbOfNodes; + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> arr= + mesh->mergeNodes(0.004,areNodesMerged,newNbOfNodes); + const int idsExpected[6] = {0, 1, 0, 2, 2, 0}; + CPPUNIT_ASSERT(std::equal(idsExpected,idsExpected+6,arr->getPointer())); + CPPUNIT_ASSERT( areNodesMerged ); + CPPUNIT_ASSERT_EQUAL( 3, newNbOfNodes ); + //! [CppSnippet_MEDCouplingUMesh_mergeNodes_2] + //! [CppSnippet_MEDCouplingUMesh_mergeNodes_3] + const double* baryCoords2 = coords + 2*2; // initial coordinates of node #2 + coordsArr=mesh->getCoordinatesAndOwner(); // retrieve a new shorten coord array + CPPUNIT_ASSERT( fabs( baryCoords2[1] - coordsArr->getIJ(0,1)) > 1e-4 ); // Y of node #0 differs from that of baryCoords2 + // restore coordinates + coordsArr->alloc(6,2); + std::copy(coords,coords+6*2,coordsArr->getPointer()); + mesh->setCoords(coordsArr); + // call mergeNodes2() + arr = mesh->mergeNodes2(0.004,areNodesMerged,newNbOfNodes); + coordsArr=mesh->getCoordinatesAndOwner(); // retrieve a new shorten coord array + CPPUNIT_ASSERT_DOUBLES_EQUAL( baryCoords2[1], coordsArr->getIJ(0,1), 13 ); // Y of node #0 equals to that of baryCoords2 + //! [CppSnippet_MEDCouplingUMesh_mergeNodes_3] +} + +void CppExample_MEDCouplingUMesh_zipConnectivityTraducer() +{ + using namespace ParaMEDMEM; + //! [CppSnippet_MEDCouplingUMesh_zipConnectivityTraducer_1] + MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> mesh=MEDCouplingUMesh::New(); + mesh->setMeshDimension(2); + mesh->allocateCells(5); + const int conn[11]={0,3,4,1, 1,4,2, 4,1,0,3}; + mesh->insertNextCell(INTERP_KERNEL::NORM_QUAD4,4,conn+0); // 0 + mesh->insertNextCell(INTERP_KERNEL::NORM_TRI3,3, conn+4); // 1 + mesh->insertNextCell(INTERP_KERNEL::NORM_TRI3,3, conn+4); // 2 == 1 + mesh->insertNextCell(INTERP_KERNEL::NORM_QUAD4,4,conn+0); // 3 == 0 + mesh->insertNextCell(INTERP_KERNEL::NORM_QUAD4,4,conn+7); // 4 ~~ 0 + mesh->finishInsertingCells(); + MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> coordsArr=DataArrayDouble::New(); + coordsArr->alloc(9,2); + const double coords[18]={-0.3,-0.3, 0.2,-0.3, 0.7,-0.3, -0.3,0.2, 0.2,0.2, 0.7,0.2, -0.3,0.7, 0.2,0.7, 0.7,0.7 }; + std::copy(coords,coords+18,coordsArr->getPointer()); + mesh->setCoords(coordsArr); + //! [CppSnippet_MEDCouplingUMesh_zipConnectivityTraducer_1] + //! [CppSnippet_MEDCouplingUMesh_zipConnectivityTraducer_2] + const int oldNbCells = mesh->getNumberOfCells(); + DataArrayInt *arr = mesh->zipConnectivityTraducer(0); + CPPUNIT_ASSERT_EQUAL( oldNbCells-2, mesh->getNumberOfCells() ); + const int idsExpected[5] = {0, 1, 1, 0, 2}; + CPPUNIT_ASSERT(std::equal(idsExpected,idsExpected+5,arr->getPointer())); + //! [CppSnippet_MEDCouplingUMesh_zipConnectivityTraducer_2] + arr->decrRef(); +} + +void CppExample_MEDCouplingUMesh_zipCoordsTraducer() +{ + using namespace ParaMEDMEM; + //! [CppSnippet_MEDCouplingUMesh_zipCoordsTraducer_1] + MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> mesh=MEDCouplingUMesh::New(); + mesh->setMeshDimension(2); + mesh->allocateCells(5); + const int conn[18]={0,3,4,1, 1,4,2, 4,5,2, 6,7,4,3, 7,8,5,4}; + mesh->insertNextCell(INTERP_KERNEL::NORM_QUAD4,4,conn); + mesh->insertNextCell(INTERP_KERNEL::NORM_TRI3,3, conn+4); + mesh->insertNextCell(INTERP_KERNEL::NORM_TRI3,3, conn+7); + mesh->insertNextCell(INTERP_KERNEL::NORM_QUAD4,4,conn+10); + mesh->insertNextCell(INTERP_KERNEL::NORM_QUAD4,4,conn+14); + mesh->finishInsertingCells(); + MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> coordsArr=DataArrayDouble::New(); + coordsArr->alloc(9,2); + const double coords[18]={-0.3,-0.3, 0.2,-0.3, 0.7,-0.3, -0.3,0.2, 0.2,0.2, 0.7,0.2, -0.3,0.7, 0.2,0.7, 0.7,0.7 }; + std::copy(coords,coords+18,coordsArr->getPointer()); + mesh->setCoords(coordsArr); + //! [CppSnippet_MEDCouplingUMesh_zipCoordsTraducer_1] + //! [CppSnippet_MEDCouplingUMesh_zipCoordsTraducer_2] + const int cellIds[2]={1,2}; + MEDCouplingUMesh* mesh2=(MEDCouplingUMesh*)mesh->buildPartOfMySelf(cellIds,cellIds+2,true); + DataArrayInt *arr=mesh2->zipCoordsTraducer(); + CPPUNIT_ASSERT_EQUAL( 4, mesh2->getNumberOfNodes() ); // nb of nodes decreased + CPPUNIT_ASSERT_EQUAL( mesh->getNumberOfNodes(), arr->getNumberOfTuples() ); + const int idsExpected[9] = {-1,0,1,-1,2,3,-1,-1,-1}; // -1 for unused nodes + CPPUNIT_ASSERT(std::equal(idsExpected,idsExpected+9,arr->getPointer())); + //! [CppSnippet_MEDCouplingUMesh_zipCoordsTraducer_2] + mesh2->decrRef(); + arr->decrRef(); +} + +void CppExample_MEDCouplingUMesh_getNodeIdsInUse() +{ + using namespace ParaMEDMEM; + //! [CppSnippet_MEDCouplingUMesh_getNodeIdsInUse_1] + MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> mesh=MEDCouplingUMesh::New(); + mesh->setMeshDimension(2); + mesh->allocateCells(5); + const int conn[18]={0,3,4,1, 1,4,2, 4,5,2, 6,7,4,3, 7,8,5,4}; + mesh->insertNextCell(INTERP_KERNEL::NORM_QUAD4,4,conn); + mesh->insertNextCell(INTERP_KERNEL::NORM_TRI3,3, conn+4); + mesh->insertNextCell(INTERP_KERNEL::NORM_TRI3,3, conn+7); + mesh->insertNextCell(INTERP_KERNEL::NORM_QUAD4,4,conn+10); + mesh->insertNextCell(INTERP_KERNEL::NORM_QUAD4,4,conn+14); + mesh->finishInsertingCells(); + MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> coordsArr=DataArrayDouble::New(); + coordsArr->alloc(9,2); + const double coords[18]={-0.3,-0.3, 0.2,-0.3, 0.7,-0.3, -0.3,0.2, 0.2,0.2, 0.7,0.2, -0.3,0.7, 0.2,0.7, 0.7,0.7 }; + std::copy(coords,coords+18,coordsArr->getPointer()); + mesh->setCoords(coordsArr); + //! [CppSnippet_MEDCouplingUMesh_getNodeIdsInUse_1] + //! [CppSnippet_MEDCouplingUMesh_getNodeIdsInUse_2] + const int cellIds[2]={1,2}; + MEDCouplingUMesh* mesh2=(MEDCouplingUMesh*)mesh->buildPartOfMySelf(cellIds,cellIds+2,true); + int newNbOfNodes = 0; + DataArrayInt *arr=mesh2->getNodeIdsInUse( newNbOfNodes ); + const int idsExpected[9] = {-1,0,1,-1,2,3,-1,-1,-1}; + CPPUNIT_ASSERT(std::equal(idsExpected,idsExpected+9,arr->getPointer())); + //! [CppSnippet_MEDCouplingUMesh_getNodeIdsInUse_2] + //! [CppSnippet_MEDCouplingUMesh_getNodeIdsInUse_3] + DataArrayInt *arr2=arr->invertArrayO2N2N2O(newNbOfNodes); + const int idsExpected2[4] = {1,2,4,5}; + CPPUNIT_ASSERT(std::equal(idsExpected2,idsExpected2+4,arr2->getPointer())); + //! [CppSnippet_MEDCouplingUMesh_getNodeIdsInUse_3] + mesh2->decrRef(); + arr->decrRef(); + arr2->decrRef(); +} + +void CppExample_MEDCouplingUMesh_convertToPolyTypes() +{ + using namespace ParaMEDMEM; + //! [CppSnippet_MEDCouplingUMesh_convertToPolyTypes_1] + MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> mesh=MEDCouplingUMesh::New(); + mesh->setMeshDimension(2); + mesh->allocateCells(5); + const int conn[18]={0,3,4,1, 1,4,2, 4,5,2, 6,7,4,3, 7,8,5,4}; + mesh->insertNextCell(INTERP_KERNEL::NORM_QUAD4,4,conn); // 0 + mesh->insertNextCell(INTERP_KERNEL::NORM_TRI3,3, conn+4); // 1 + mesh->insertNextCell(INTERP_KERNEL::NORM_TRI3,3, conn+7); // 2 + mesh->insertNextCell(INTERP_KERNEL::NORM_QUAD4,4,conn+10); // 3 + mesh->insertNextCell(INTERP_KERNEL::NORM_QUAD4,4,conn+14); // 4 + mesh->finishInsertingCells(); + MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> coordsArr=DataArrayDouble::New(); + coordsArr->alloc(9,2); + const double coords[18]={-0.3,-0.3, 0.2,-0.3, 0.7,-0.3, -0.3,0.2, 0.2,0.2, 0.7,0.2, -0.3,0.7, 0.2,0.7, 0.7,0.7 }; + std::copy(coords,coords+18,coordsArr->getPointer()); + mesh->setCoords(coordsArr); + //! [CppSnippet_MEDCouplingUMesh_convertToPolyTypes_1] + //! [CppSnippet_MEDCouplingUMesh_convertToPolyTypes_2] + const int cells[2]={1,3}; + mesh->convertToPolyTypes(cells, cells+2); + CPPUNIT_ASSERT( mesh->getTypeOfCell(0) == INTERP_KERNEL::NORM_QUAD4 ); + CPPUNIT_ASSERT( mesh->getTypeOfCell(1) == INTERP_KERNEL::NORM_POLYGON ); + CPPUNIT_ASSERT( mesh->getTypeOfCell(2) == INTERP_KERNEL::NORM_TRI3 ); + CPPUNIT_ASSERT( mesh->getTypeOfCell(3) == INTERP_KERNEL::NORM_POLYGON ); + //! [CppSnippet_MEDCouplingUMesh_convertToPolyTypes_2] +} + +void CppExample_MEDCouplingUMesh_buildDescendingConnectivity2() +{ + using namespace ParaMEDMEM; + //! [CppSnippet_MEDCouplingUMesh_buildDescendingConnectivity2_1] + MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> mesh=MEDCouplingUMesh::New(); + mesh->setMeshDimension(2); + mesh->allocateCells(5); + const int conn[18]={0,3,4,1, 1,4,2, 4,5,2, 6,7,4,3, 7,8,5,4}; + mesh->insertNextCell(INTERP_KERNEL::NORM_QUAD4,4,conn); // 0 + mesh->insertNextCell(INTERP_KERNEL::NORM_TRI3,3, conn+4); // 1 + mesh->insertNextCell(INTERP_KERNEL::NORM_TRI3,3, conn+7); // 2 + mesh->insertNextCell(INTERP_KERNEL::NORM_QUAD4,4,conn+10); // 3 + mesh->insertNextCell(INTERP_KERNEL::NORM_QUAD4,4,conn+14); // 4 + mesh->finishInsertingCells(); + MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> coordsArr=DataArrayDouble::New(); + coordsArr->alloc(9,2); + const double coords[18]={-0.3,-0.3, 0.2,-0.3, 0.7,-0.3, -0.3,0.2, 0.2,0.2, 0.7,0.2, -0.3,0.7, 0.2,0.7, 0.7,0.7 }; + std::copy(coords,coords+18,coordsArr->getPointer()); + mesh->setCoords(coordsArr); + //! [CppSnippet_MEDCouplingUMesh_buildDescendingConnectivity2_1] + //! [CppSnippet_MEDCouplingUMesh_buildDescendingConnectivity2_2] + DataArrayInt *desc =DataArrayInt::New(); + DataArrayInt *descIndx =DataArrayInt::New(); + DataArrayInt *revDesc =DataArrayInt::New(); + DataArrayInt *revDescIndx=DataArrayInt::New(); + MEDCouplingUMesh * mesh2 = mesh->buildDescendingConnectivity2(desc,descIndx,revDesc,revDescIndx); + const int descExpected[] = {1,2,3,4,-3,5,6,7,8,-5,9,10,-2,11,12,13,-7,-10}; + const int descIndxExpected[] = {0,4,7,10,14,18}; + const int revDescExpected[] = {0, 0,3, 0,1, 0, 1,2, 1, 2,4, 2, 3, 3,4, 3, 4, 4}; + const int revDescIndxExpected[] = {0,1,3,5,6,8,9,11,12,13,15,16,17,18}; + CPPUNIT_ASSERT(std::equal(descExpected,descExpected+18,desc->getPointer())); + CPPUNIT_ASSERT(std::equal(descIndxExpected,descIndxExpected+6,descIndx->getPointer())); + CPPUNIT_ASSERT(std::equal(revDescExpected,revDescExpected+18,revDesc->getPointer())); + CPPUNIT_ASSERT(std::equal(revDescIndxExpected,revDescIndxExpected+14,revDescIndx->getPointer())); + //! [CppSnippet_MEDCouplingUMesh_buildDescendingConnectivity2_2] + //! [CppSnippet_MEDCouplingUMesh_buildDescendingConnectivity2_3] + const int cell2ConnExpect[] = {4,1}; + std::vector<int> cell2Conn; + mesh2->getNodeIdsOfCell( 3-1, cell2Conn ); // cell #3 in FORTRAN mode + CPPUNIT_ASSERT(std::equal(cell2ConnExpect,cell2ConnExpect+2,&cell2Conn[0])); + //! [CppSnippet_MEDCouplingUMesh_buildDescendingConnectivity2_3] + desc->decrRef(); + descIndx->decrRef(); + revDesc->decrRef(); + revDescIndx->decrRef(); + mesh2->decrRef(); +} + +void CppExample_MEDCouplingUMesh_buildDescendingConnectivity() +{ + using namespace ParaMEDMEM; + //! [CppSnippet_MEDCouplingUMesh_buildDescendingConnectivity_1] + MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> mesh=MEDCouplingUMesh::New(); + mesh->setMeshDimension(2); + mesh->allocateCells(5); + const int conn[18]={0,3,4,1, 1,4,2, 4,5,2, 6,7,4,3, 7,8,5,4}; + mesh->insertNextCell(INTERP_KERNEL::NORM_QUAD4,4,conn); // 0 + mesh->insertNextCell(INTERP_KERNEL::NORM_TRI3,3, conn+4); // 1 + mesh->insertNextCell(INTERP_KERNEL::NORM_TRI3,3, conn+7); // 2 + mesh->insertNextCell(INTERP_KERNEL::NORM_QUAD4,4,conn+10); // 3 + mesh->insertNextCell(INTERP_KERNEL::NORM_QUAD4,4,conn+14); // 4 + mesh->finishInsertingCells(); + MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> coordsArr=DataArrayDouble::New(); + coordsArr->alloc(9,2); + const double coords[18]={-0.3,-0.3, 0.2,-0.3, 0.7,-0.3, -0.3,0.2, 0.2,0.2, 0.7,0.2, -0.3,0.7, 0.2,0.7, 0.7,0.7 }; + std::copy(coords,coords+18,coordsArr->getPointer()); + mesh->setCoords(coordsArr); + //! [CppSnippet_MEDCouplingUMesh_buildDescendingConnectivity_1] + //! [CppSnippet_MEDCouplingUMesh_buildDescendingConnectivity_2] + DataArrayInt *desc =DataArrayInt::New(); + DataArrayInt *descIndx =DataArrayInt::New(); + DataArrayInt *revDesc =DataArrayInt::New(); + DataArrayInt *revDescIndx=DataArrayInt::New(); + MEDCouplingUMesh * mesh2 = mesh->buildDescendingConnectivity(desc,descIndx,revDesc,revDescIndx); + const int descExpected[] = {0,1,2,3, 2,4,5, 6,7,4, 8,9,1,10, 11,12,6,9}; + const int descIndxExpected[] = {0,4,7,10,14,18}; + const int revDescExpected[] = {0, 0,3, 0,1, 0, 1,2, 1, 2,4, 2, 3, 3,4, 3, 4, 4}; + const int revDescIndxExpected[] = {0,1,3,5,6,8,9,11,12,13,15,16,17,18}; + CPPUNIT_ASSERT(std::equal(descExpected,descExpected+18,desc->getPointer())); + CPPUNIT_ASSERT(std::equal(descIndxExpected,descIndxExpected+6,descIndx->getPointer())); + CPPUNIT_ASSERT(std::equal(revDescExpected,revDescExpected+18,revDesc->getPointer())); + CPPUNIT_ASSERT(std::equal(revDescIndxExpected,revDescIndxExpected+14,revDescIndx->getPointer())); + //! [CppSnippet_MEDCouplingUMesh_buildDescendingConnectivity_2] + desc->decrRef(); + descIndx->decrRef(); + revDesc->decrRef(); + revDescIndx->decrRef(); + mesh2->decrRef(); +} + +void CppExample_MEDCouplingUMesh_getReverseNodalConnectivity() +{ + using namespace ParaMEDMEM; + //! [CppSnippet_MEDCouplingUMesh_getReverseNodalConnectivity_1] + MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> mesh=MEDCouplingUMesh::New(); + mesh->setMeshDimension(2); + mesh->allocateCells(5); + const int conn[18]={0,3,4,1, 1,4,2, 4,5,2, 6,7,4,3, 7,8,5,4}; + mesh->insertNextCell(INTERP_KERNEL::NORM_QUAD4,4,conn); // 0 + mesh->insertNextCell(INTERP_KERNEL::NORM_TRI3,3, conn+4); // 1 + mesh->insertNextCell(INTERP_KERNEL::NORM_TRI3,3, conn+7); // 2 + mesh->insertNextCell(INTERP_KERNEL::NORM_QUAD4,4,conn+10); // 3 + mesh->insertNextCell(INTERP_KERNEL::NORM_QUAD4,4,conn+14); // 4 + mesh->finishInsertingCells(); + MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> coordsArr=DataArrayDouble::New(); + coordsArr->alloc(9,2); + const double coords[18]={-0.3,-0.3, 0.2,-0.3, 0.7,-0.3, -0.3,0.2, 0.2,0.2, 0.7,0.2, -0.3,0.7, 0.2,0.7, 0.7,0.7 }; + std::copy(coords,coords+18,coordsArr->getPointer()); + mesh->setCoords(coordsArr); + //! [CppSnippet_MEDCouplingUMesh_getReverseNodalConnectivity_1] + //! [CppSnippet_MEDCouplingUMesh_getReverseNodalConnectivity_2] + DataArrayInt *revNodal=DataArrayInt::New(); + DataArrayInt *revNodalIndx=DataArrayInt::New(); + mesh->getReverseNodalConnectivity(revNodal,revNodalIndx); + const int revNodalExpected[18]={0,0,1,1,2,0,3,0,1,2,3,4,2,4,3,3,4,4}; + const int revNodalIndexExpected[10]={0,1,3,5,7,12,14,15,17,18}; + CPPUNIT_ASSERT(std::equal(revNodalExpected,revNodalExpected+18,revNodal->getPointer())); + CPPUNIT_ASSERT(std::equal(revNodalIndexExpected,revNodalIndexExpected+10,revNodalIndx->getPointer())); + //! [CppSnippet_MEDCouplingUMesh_getReverseNodalConnectivity_2] + revNodal->decrRef(); + revNodalIndx->decrRef(); +} + +void CppExample_MEDCouplingUMesh_checkDeepEquivalWith() +{ + using namespace ParaMEDMEM; + //! [CppSnippet_MEDCouplingUMesh_checkDeepEquivalWith_1] + // mesh 1 + MEDCouplingUMesh *mesh1=MEDCouplingUMesh::New(); + const double coords[4*2]={0.0,0.0, // #0 + 1.0,0.0, // #1 + 1.0,1.0, // #2 + 0.0,1.0}; // #3 + { + mesh1->setMeshDimension(2); + MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> coordsArr=DataArrayDouble::New(); + coordsArr->useExternalArrayWithRWAccess( coords, 4, 2 ); + mesh1->setCoords(coordsArr); + mesh1->allocateCells(2); + const int conn[6]={0,1,2, 1,2,3}; + mesh1->insertNextCell(INTERP_KERNEL::NORM_TRI3,3, conn+0); // #0 + mesh1->insertNextCell(INTERP_KERNEL::NORM_TRI3,3, conn+3); // #1 + mesh1->finishInsertingCells(); + } + // mesh 2 + MEDCouplingUMesh *mesh2=MEDCouplingUMesh::New(); + const double coords2[4*2]={0.0,1.0, // #0 = #3 + 0.0,0.0, // #1 = #0 + 1.0,0.0, // #2 = #1 + 1.0,1.001}; // #3 ~ #2 + { + mesh2->setMeshDimension(2); + MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> coordsArr=DataArrayDouble::New(); + coordsArr->useExternalArrayWithRWAccess( coords2, 4, 2 ); + mesh2->setCoords(coordsArr); + mesh2->allocateCells(2); + const int conn[6]={2,3,0, 3,1,2}; + mesh2->insertNextCell(INTERP_KERNEL::NORM_TRI3,3, conn+0); // #0 = #1 + mesh2->insertNextCell(INTERP_KERNEL::NORM_TRI3,3, conn+3); // #1 ~ #0 + mesh2->finishInsertingCells(); + } + //! [CppSnippet_MEDCouplingUMesh_checkDeepEquivalWith_1] + //! [CppSnippet_MEDCouplingUMesh_checkDeepEquivalWith_2] + int cellCompPol = 1; // "permuted same orientation" - policy of medium severity + DataArrayInt *nOld2New, *cOld2New; + mesh1->checkDeepEquivalWith( mesh2, cellCompPol, 0.002, cOld2New, nOld2New ); + const int nOld2NewExpected[4] = { 3, 0, 1, 2 }; + const int cOld2NewExpected[2] = { 1, 0 }; + CPPUNIT_ASSERT(std::equal(nOld2NewExpected,nOld2NewExpected+4,nOld2New->getConstPointer())); + CPPUNIT_ASSERT(std::equal(cOld2NewExpected,cOld2NewExpected+2,cOld2New->getConstPointer())); + //! [CppSnippet_MEDCouplingUMesh_checkDeepEquivalWith_2] + //! [CppSnippet_MEDCouplingUMesh_checkDeepEquivalWith_3] + cOld2New->decrRef(); // else memory leaks + CPPUNIT_ASSERT_THROW ( mesh1->checkDeepEquivalOnSameNodesWith( mesh2, cellCompPol, 0.002, cOld2New ), INTERP_KERNEL::Exception ); + mesh2->setCoords( mesh1->getCoords() ); // make meshes share the same coordinates array + mesh2->allocateCells(2); + const int conn[6]={1,2,3, 1,0,2}; + mesh2->insertNextCell(INTERP_KERNEL::NORM_TRI3,3,conn+0); // #0 = #1 + mesh2->insertNextCell(INTERP_KERNEL::NORM_TRI3,3,conn+3); // #1 ~ #0 + mesh2->finishInsertingCells(); + cellCompPol = 2; // the weakest policy + mesh1->checkDeepEquivalOnSameNodesWith( mesh2, cellCompPol, 0, cOld2New ); + //! [CppSnippet_MEDCouplingUMesh_checkDeepEquivalWith_3] + nOld2New->decrRef(); + cOld2New->decrRef(); + mesh1->decrRef(); + mesh2->decrRef(); +} + +void CppExample_MEDCouplingPointSet_scale() +{ + using namespace ParaMEDMEM; + //! [CppSnippet_MEDCouplingPointSet_scale_1] + double coords[4*2]={0.0,0.0, 1.0,0.0, 1.0,1.0, 0.0,1.0}; // 2D coordinates of 4 nodes + MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> coordsArr=DataArrayDouble::New(); + coordsArr->useExternalArrayWithRWAccess(coords, 4,2); + MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> mesh=MEDCouplingUMesh::New(); + mesh->setCoords(coordsArr); + DataArrayDouble *initCoords = coordsArr->deepCpy(); + //! [CppSnippet_MEDCouplingPointSet_scale_1] + //! [CppSnippet_MEDCouplingPointSet_scale_2] + const double center[2] = {0.,0.}; + const double factor = 2.; + mesh->scale( center, factor ); + //! [CppSnippet_MEDCouplingPointSet_scale_2] + //! [CppSnippet_MEDCouplingPointSet_scale_3] + const DataArrayDouble * coordsArr2 = mesh->getCoords(); + CPPUNIT_ASSERT( coordsArr2->isEqualWithoutConsideringStr( *initCoords, 1.0 )); + CPPUNIT_ASSERT( !coordsArr2->isEqualWithoutConsideringStr( *initCoords, 0.9 )); + // release data + initCoords->decrRef(); + //! [CppSnippet_MEDCouplingPointSet_scale_3] +} + +void CppExample_MEDCouplingPointSet_translate() +{ + using namespace ParaMEDMEM; + //! [CppSnippet_MEDCouplingPointSet_translate_1] + double coords[4*2]={0.0,0.0, 1.0,0.0, 1.0,1.0, 0.0,1.0}; // 2D coordinates of 4 nodes + MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> coordsArr=DataArrayDouble::New(); + coordsArr->useExternalArrayWithRWAccess(coords, 4,2); + MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> mesh=MEDCouplingUMesh::New(); + mesh->setCoords(coordsArr); + DataArrayDouble *initCoords = coordsArr->deepCpy(); + //! [CppSnippet_MEDCouplingPointSet_translate_1] + //! [CppSnippet_MEDCouplingPointSet_translate_2] + double vector[2] = {1.,1.}; + mesh->translate( vector ); + //! [CppSnippet_MEDCouplingPointSet_translate_2] + //! [CppSnippet_MEDCouplingPointSet_translate_3] + const DataArrayDouble * coordsArr2 = mesh->getCoords(); + CPPUNIT_ASSERT( coordsArr2->isEqualWithoutConsideringStr( *initCoords, 1.0 )); + CPPUNIT_ASSERT( !coordsArr2->isEqualWithoutConsideringStr( *initCoords, 0.9 )); + // release data + initCoords->decrRef(); + //! [CppSnippet_MEDCouplingPointSet_translate_3] +} + +void CppExample_MEDCouplingPointSet_rotate() +{ + using namespace ParaMEDMEM; + //! [CppSnippet_MEDCouplingPointSet_rotate_1] + double coords[4*2]={0.0,0.0, 0.1,0.0, 0.1,0.1, 0.0,0.1}; // 2D coordinates of 4 nodes + double coordsOrig[4*2]; + std::copy(coords,coords+sizeof(coords)/sizeof(double),coordsOrig);//keep tracks of initial values + MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> coordsArr=DataArrayDouble::New(); + coordsArr->useExternalArrayWithRWAccess(coords, 4,2); + MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> mesh=MEDCouplingUMesh::New(); + mesh->setCoords(coordsArr); + //! [CppSnippet_MEDCouplingPointSet_rotate_1] + //! [CppSnippet_MEDCouplingPointSet_rotate_2] + double center[3] = {0.,0.,0.}; // it suits for 2D as well + double vector[3] = {0.,0.,1.}; // it is not used in 2D + mesh->rotate( center, vector, -M_PI/2); // warning here C++ 'coords' array (defined above) has been modified ! + //! [CppSnippet_MEDCouplingPointSet_rotate_2] + //! [CppSnippet_MEDCouplingPointSet_rotate_3] + mesh->changeSpaceDimension(3); + mesh->rotate( center, vector, +M_PI/2); + //! [CppSnippet_MEDCouplingPointSet_rotate_3] + //! [CppSnippet_MEDCouplingPointSet_rotate_4] + mesh->changeSpaceDimension(2); + const DataArrayDouble * coordsArr2 = mesh->getCoords(); + coordsArr->useExternalArrayWithRWAccess(coordsOrig, 4,2); + CPPUNIT_ASSERT( coordsArr2->isEqualWithoutConsideringStr( *coordsArr, 1e-13 )); + //! [CppSnippet_MEDCouplingPointSet_rotate_4] +} + +void CppExample_MEDCouplingPointSet_getBoundingBox() +{ + using namespace ParaMEDMEM; + //! [CppSnippet_MEDCouplingPointSet_getBoundingBox_1] + double cc[2*3]={0.0, 0.1, 0.2, // 3D coordinates of 2 nodes + 2.0, 2.1, 2.2}; + MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> coordsArr=DataArrayDouble::New(); + coordsArr->useExternalArrayWithRWAccess(cc, 2,3); + MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> mesh=MEDCouplingUMesh::New(); + mesh->setCoords(coordsArr); + //! [CppSnippet_MEDCouplingPointSet_getBoundingBox_1] + //! [CppSnippet_MEDCouplingPointSet_getBoundingBox_2] + double bbox[3][2]; + mesh->getBoundingBox( (double*) bbox ); + + // check the returned coordinates of extremum points of the bounding box + for ( int i = 0; i < 2; ++i ) // point id + for ( int j = 0; j < 3; ++j ) // component + CPPUNIT_ASSERT_DOUBLES_EQUAL( cc[ i*3 + j ], bbox[j][i], 1e-13); + //! [CppSnippet_MEDCouplingPointSet_getBoundingBox_2] +} + +void CppExample_MEDCouplingPointSet_getNodeIdsNearPoint() +{ + using namespace ParaMEDMEM; + //! [CppSnippet_MEDCouplingPointSet_getNodeIdsNearPoint_1] + // 2D coordinates of 5 nodes + double coords[5*2]={0.3,-0.30001, // #0 + 0.2,-0.3, // #1 + 0.3,-0.30002, // #2 + 1.1,0.0, // #3 + 0.3,-0.30003};// #4 + MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> coordsArr=DataArrayDouble::New(); + coordsArr->useExternalArrayWithRWAccess(coords, 5,2); + MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> mesh=MEDCouplingUMesh::New(); + mesh->setCoords(coordsArr); + //! [CppSnippet_MEDCouplingPointSet_getNodeIdsNearPoint_1] + //! [CppSnippet_MEDCouplingPointSet_getNodeIdsNearPoint_2] + double point [2]={0.3, -0.3}; // point close to nodes #0, #2 and #4 + DataArrayInt *ids = mesh->getNodeIdsNearPoint(point, 1e-2); + + // check found ids + const int expectedIDs[3] = {0,2,4}; + DataArrayInt * okIDs = ids->getIdsEqualList ( expectedIDs, expectedIDs+3 ); + CPPUNIT_ASSERT_EQUAL(3, okIDs->getNumberOfTuples()); + + // release data + ids->decrRef(); + okIDs->decrRef(); + //! [CppSnippet_MEDCouplingPointSet_getNodeIdsNearPoint_2] +} +void CppExample_MEDCouplingPointSet_getNodeIdsNearPoints() +{ + using namespace ParaMEDMEM; + //! [CppSnippet_MEDCouplingPointSet_getNodeIdsNearPoints_1] + // 2D coordinates of 7 nodes + double coords[7*2]={0.3,-0.301, // #0 + 0.2,-0.3, // #1 + 0.3,-0.302, // #2 + 1.1,0.0, // #3 + 1.1,0.0, // #4 + 1.1,0.002, // #5 + 0.3,-0.303};// #6 + MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> coordsArr=DataArrayDouble::New(); + coordsArr->useExternalArrayWithRWAccess(coords, 7,2); + MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> mesh=MEDCouplingUMesh::New(); + mesh->setCoords(coordsArr); + //! [CppSnippet_MEDCouplingPointSet_getNodeIdsNearPoints_1] + //! [CppSnippet_MEDCouplingPointSet_getNodeIdsNearPoints_2] + const int nbOfPoints = 3; + double points [nbOfPoints*2]={0.2,-0.30001, // ~ node #1 + 0.0, 0.0, + 1.1, 0.002}; // ~ nodes #3, #4 and #5 + DataArrayInt *ids, *idsIndex; + mesh->getNodeIdsNearPoints(points, nbOfPoints, 1e-1,ids,idsIndex); + + // check found ids (i.e. contents of 'ids' array) + const int expectedIDs[4] = {1, 3, 4, 5}; + DataArrayInt * okIDs = ids->getIdsEqualList ( expectedIDs, expectedIDs+4 ); + CPPUNIT_ASSERT_EQUAL(4, okIDs->getNumberOfTuples()); + + // release data + ids->decrRef(); + idsIndex->decrRef(); + okIDs->decrRef(); + //! [CppSnippet_MEDCouplingPointSet_getNodeIdsNearPoints_2] +} + +void CppExample_MEDCouplingPointSet_findCommonNodes() +{ + using namespace ParaMEDMEM; + //! [CppSnippet_MEDCouplingPointSet_findCommonNodes_1] + double coords[6*2]={0.3,-0.301, // 0 + 0.2,-0.3, // 1 + 0.3,-0.302, // 2 + 1.1,0.0, // 3 + 1.1,0.0, // 4 + 0.3,-0.303};// 5 + MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> coordsArr=DataArrayDouble::New(); + coordsArr->useExternalArrayWithRWAccess(coords, 6,2); + MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> mesh=MEDCouplingUMesh::New(); + mesh->setCoords(coordsArr); + //! [CppSnippet_MEDCouplingPointSet_findCommonNodes_1] + //! [CppSnippet_MEDCouplingPointSet_findCommonNodes_2] + DataArrayInt *com, *comI; + mesh->findCommonNodes(1e-13,-1,com,comI); + CPPUNIT_ASSERT_EQUAL(2, com->getNumberOfTuples()); + com->decrRef(); comI->decrRef(); + mesh->findCommonNodes(0.004,-1,com,comI); + CPPUNIT_ASSERT_EQUAL(5, com->getNumberOfTuples()); + //! [CppSnippet_MEDCouplingPointSet_findCommonNodes_2] + com->decrRef(); comI->decrRef(); +} + +void CppExample_MEDCouplingPointSet_getCoordinatesOfNode() +{ + using namespace ParaMEDMEM; + //! [CppSnippet_MEDCouplingPointSet_getCoordinatesOfNode_1] + double coords[18]={-0.3,-0.3, 0.2,-0.3, 0.7,-0.3}; + MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> coordsArr=DataArrayDouble::New(); + coordsArr->useExternalArrayWithRWAccess(coords, 3,2); + MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> mesh=MEDCouplingUMesh::New(); + mesh->setCoords(coordsArr); + //! [CppSnippet_MEDCouplingPointSet_getCoordinatesOfNode_1] + //! [CppSnippet_MEDCouplingPointSet_getCoordinatesOfNode_2] + std::vector<double> coords2; + mesh->getCoordinatesOfNode(1,coords2); + CPPUNIT_ASSERT_DOUBLES_EQUAL(coords[2],coords2[0],1e-13); + CPPUNIT_ASSERT_DOUBLES_EQUAL(coords[3],coords2[1],1e-13); + //! [CppSnippet_MEDCouplingPointSet_getCoordinatesOfNode_2] +} + +void CppExample_DataArrayInt_buildPermutationArr() +{ + using namespace ParaMEDMEM; + //! [CppSnippet_DataArrayInt_buildPermutationArr_1] + DataArrayInt *a=DataArrayInt::New(); + const int vala[5]={4,5,6,7,8}; + a->alloc(5,1); + std::copy(vala,vala+5,a->getPointer()); + DataArrayInt *b=DataArrayInt::New(); + const int valb[5]={5,4,8,6,7}; + b->alloc(5,1); + std::copy(valb,valb+5,b->getPointer()); + DataArrayInt *c=a->buildPermutationArr(*b); + //! [CppSnippet_DataArrayInt_buildPermutationArr_1] + const int expect1[5]={1,0,4,2,3}; + CPPUNIT_ASSERT_EQUAL(5,c->getNumberOfTuples()); + CPPUNIT_ASSERT_EQUAL(1,c->getNumberOfComponents()); + CPPUNIT_ASSERT(std::equal(expect1,expect1+5,c->getConstPointer())); + CPPUNIT_ASSERT(a->isEqualWithoutConsideringStrAndOrder(*b)); + a->decrRef(); + b->decrRef(); + c->decrRef(); +} + +void CppExample_DataArrayInt_invertArrayO2N2N2O() +{ + using namespace ParaMEDMEM; + //! [CppSnippet_DataArrayInt_invertArrayO2N2N2O_1] + const int arr1[6]={2,0,4,1,5,3}; + DataArrayInt *da=DataArrayInt::New(); + da->alloc(6,1); + std::copy(arr1,arr1+6,da->getPointer()); + DataArrayInt *da2=da->invertArrayO2N2N2O(6); + const int expected1[6]={1,3,0,5,2,4}; + for(int i=0;i<6;i++) + CPPUNIT_ASSERT_EQUAL(expected1[i],da2->getIJ(i,0)); + //! [CppSnippet_DataArrayInt_invertArrayO2N2N2O_1] + da->decrRef(); + da2->decrRef(); +} + +void CppExample_DataArrayInt_invertArrayN2O2O2N() +{ + using namespace ParaMEDMEM; + //! [CppSnippet_DataArrayInt_invertArrayN2O2O2N_1] + const int arr1[6]={2,0,4,1,5,3}; + DataArrayInt *da=DataArrayInt::New(); + da->alloc(6,1); + std::copy(arr1,arr1+6,da->getPointer()); + DataArrayInt *da2=da->invertArrayN2O2O2N(6); + const int expected1[6]={1,3,0,5,2,4}; + for(int i=0;i<6;i++) + CPPUNIT_ASSERT_EQUAL(expected1[i],da2->getIJ(i,0)); + //! [CppSnippet_DataArrayInt_invertArrayN2O2O2N_1] + da->decrRef(); + da2->decrRef(); +} + +void CppExample_DataArrayDouble_getIdsInRange() +{ + using namespace ParaMEDMEM; + //! [CppSnippet_DataArrayDouble_getIdsInRange_1] + DataArrayDouble *da=DataArrayDouble::New(); + da->alloc(10,1); + da->iota(); + + DataArrayInt* da2 = da->getIdsInRange( 2.5, 6 ); + //! [CppSnippet_DataArrayDouble_getIdsInRange_1] + da->decrRef(); + da2->decrRef(); +} + +void CppExample_DataArrayDouble_findCommonTuples() +{ + using namespace ParaMEDMEM; + //! [CppSnippet_DataArrayDouble_findCommonTuples1] + DataArrayDouble *da=DataArrayDouble::New(); + da->alloc(6,2); + const double array2[12]={2.3,2.3, // 0 + 1.2,1.2, // 1 + 1.3,1.3, // 2 + 2.3,2.3, // 3 + 2.301, // 4 + 2.301, // 5 + 0.8,0.8};// 6 + std::copy(array2,array2+12,da->getPointer()); + //! [CppSnippet_DataArrayDouble_findCommonTuples1] + //! [CppSnippet_DataArrayDouble_findCommonTuples2] + DataArrayInt *c=0,*cI=0; + da->findCommonTuples(1.01e-1,-1,c,cI); + + const int expected3[5]={0,3,4,1,2}; + const int expected4[3]={0,3,5}; + CPPUNIT_ASSERT(std::equal(expected3,expected3+5,c->getConstPointer())); + CPPUNIT_ASSERT(std::equal(expected4,expected4+3,cI->getConstPointer())); + c->decrRef(); + cI->decrRef(); + da->decrRef(); + //! [CppSnippet_DataArrayDouble_findCommonTuples2] +} + +void CppExample_DataArrayDouble_Meld1() +{ + using namespace ParaMEDMEM; + //! [CppSnippet_DataArrayDouble_Meld1_1] + const int sameNbTuples = 7; + + DataArrayDouble *da1=DataArrayDouble::New(); + da1->alloc(sameNbTuples,2); + da1->fillWithValue(7.); + da1->setInfoOnComponent(0,"c0da1"); + da1->setInfoOnComponent(1,"c1da1"); + + DataArrayDouble *da2=DataArrayDouble::New(); + da2->alloc(sameNbTuples,1); + da2->iota(0.); + da2->setInfoOnComponent(0,"c0da2"); + + da1->meldWith(da2); + //! [CppSnippet_DataArrayDouble_Meld1_1] + //! [CppSnippet_DataArrayDouble_Meld1_2] + da1->decrRef(); + da2->decrRef(); + //! [CppSnippet_DataArrayDouble_Meld1_2] +} + +void CppExample_DataArrayInt_Meld1() +{ + using namespace ParaMEDMEM; + //! [CppSnippet_DataArrayInt_Meld1_1] + const int sameNbTuples = 7; + + DataArrayInt *da1=DataArrayInt::New(); + da1->alloc(sameNbTuples,2); + da1->fillWithValue(7); + da1->setInfoOnComponent(0,"c0da1"); + da1->setInfoOnComponent(1,"c1da1"); + + DataArrayInt *da2=DataArrayInt::New(); + da2->alloc(sameNbTuples,1); + da2->iota(0); + da2->setInfoOnComponent(0,"c0da2"); + + da1->meldWith(da2); + //! [CppSnippet_DataArrayInt_Meld1_1] + //! [CppSnippet_DataArrayInt_Meld1_2] + da1->decrRef(); + da2->decrRef(); + //! [CppSnippet_DataArrayInt_Meld1_2] +} + +void CppExampleFieldDoubleBuildSubPart1() +{ + //! [CppSnippetFieldDoubleBuildSubPart1_1] + ParaMEDMEM::MEDCouplingUMesh *mesh1=ParaMEDMEM::MEDCouplingBasicsTest::build2DTargetMesh_1(); + ParaMEDMEM::MEDCouplingFieldDouble *f1=ParaMEDMEM::MEDCouplingFieldDouble::New(ParaMEDMEM::ON_CELLS,ParaMEDMEM::ONE_TIME); + f1->setTime(2.3,5,6); + f1->setMesh(mesh1); + ParaMEDMEM::DataArrayDouble *array=ParaMEDMEM::DataArrayDouble::New(); + array->alloc(mesh1->getNumberOfCells(),2); + const double arr1[10]={3.,103.,4.,104.,5.,105.,6.,106.,7.,107.}; + std::copy(arr1,arr1+10,array->getPointer()); + f1->setArray(array); + array->decrRef(); + //! [CppSnippetFieldDoubleBuildSubPart1_1] + //! [CppSnippetFieldDoubleBuildSubPart1_2] + const int part1[3]={2,1,4}; + ParaMEDMEM::MEDCouplingFieldDouble *f2=f1->buildSubPart(part1,part1+3); + //! [CppSnippetFieldDoubleBuildSubPart1_2] + f2->zipCoords(); + CPPUNIT_ASSERT_EQUAL(3,f2->getMesh()->getNumberOfCells()); + CPPUNIT_ASSERT_EQUAL(6,f2->getMesh()->getNumberOfNodes()); + CPPUNIT_ASSERT_EQUAL(2,f2->getMesh()->getSpaceDimension()); + CPPUNIT_ASSERT_EQUAL(2,f2->getMesh()->getMeshDimension()); + ParaMEDMEM::MEDCouplingUMesh *m2C=dynamic_cast<ParaMEDMEM::MEDCouplingUMesh *>(const_cast<ParaMEDMEM::MEDCouplingMesh *>(f2->getMesh())); + CPPUNIT_ASSERT_EQUAL(13,m2C->getMeshLength()); + const double expected2[12]={0.2, -0.3, 0.7, -0.3, 0.2, 0.2, 0.7, 0.2, 0.2, 0.7, 0.7, 0.7}; + for(int i=0;i<12;i++) + CPPUNIT_ASSERT_DOUBLES_EQUAL(expected2[i],m2C->getCoords()->getIJ(0,i),1.e-12); + const double expected3[13]={3,2,3,1,3,0,2,1,4,4,5,3,2}; + CPPUNIT_ASSERT(std::equal(expected3,expected3+13,m2C->getNodalConnectivity()->getConstPointer())); + const double expected4[4]={0,4,8,13}; + CPPUNIT_ASSERT(std::equal(expected4,expected4+4,m2C->getNodalConnectivityIndex()->getConstPointer())); + f2->decrRef(); + f1->decrRef(); + //! [CppSnippetFieldDoubleBuildSubPart1_3] + f1=ParaMEDMEM::MEDCouplingFieldDouble::New(ParaMEDMEM::ON_NODES,ParaMEDMEM::ONE_TIME); + f1->setTime(2.3,5,6); + f1->setMesh(mesh1); + array=ParaMEDMEM::DataArrayDouble::New(); + array->alloc(mesh1->getNumberOfNodes(),2); + const double arr2[18]={3.,103.,4.,104.,5.,105.,6.,106.,7.,107.,8.,108.,9.,109.,10.,110.,11.,111.}; + std::copy(arr2,arr2+18,array->getPointer()); + f1->setArray(array); + array->decrRef(); + //! [CppSnippetFieldDoubleBuildSubPart1_3] + //! [CppSnippetFieldDoubleBuildSubPart1_4] + const int part2[2]={1,2}; + f2=f1->buildSubPart(part2,part2+2); + //! [CppSnippetFieldDoubleBuildSubPart1_4] + f2->decrRef(); + //idem previous because nodes of cell#4 are not fully present in part3 + const int part3[2]={1,2}; + ParaMEDMEM::DataArrayInt *arrr=ParaMEDMEM::DataArrayInt::New(); + arrr->alloc(2,1); + std::copy(part3,part3+2,arrr->getPointer()); + f2=f1->buildSubPart(arrr); + arrr->decrRef(); + f2->decrRef(); + // + const int part4[3]={1,2,4}; + f2=f1->buildSubPart(part4,part4+3); + f2->decrRef(); + // + f1->decrRef(); + mesh1->decrRef(); + return; +} + +void CppSnippetUMeshStdBuild1() +{ + //! [CppSnippetUMeshStdBuild1_1] + double coords[27]={-0.3,-0.3,0., 0.2,-0.3,0., 0.7,-0.3,0., -0.3,0.2,0., 0.2,0.2,0., + 0.7,0.2,0., -0.3,0.7,0., 0.2,0.7,0., 0.7,0.7,0. }; + int nodalConnPerCell[18]={0,3,4,1, 1,4,2, 4,5,2, 6,7,4,3, 7,8,5,4}; + //! [CppSnippetUMeshStdBuild1_1] + //! [CppSnippetUMeshStdBuild1_2] + ParaMEDMEM::MEDCouplingUMesh *mesh=ParaMEDMEM::MEDCouplingUMesh::New("My2DMesh",2); + //! [CppSnippetUMeshStdBuild1_2] + //! [CppSnippetUMeshStdBuild1_3] + mesh->allocateCells(5);//You can put more than 5 if you want but not less. + mesh->insertNextCell(INTERP_KERNEL::NORM_QUAD4,4,nodalConnPerCell); + mesh->insertNextCell(INTERP_KERNEL::NORM_TRI3,3,nodalConnPerCell+4); + mesh->insertNextCell(INTERP_KERNEL::NORM_TRI3,3,nodalConnPerCell+7); + mesh->insertNextCell(INTERP_KERNEL::NORM_QUAD4,4,nodalConnPerCell+10); + mesh->insertNextCell(INTERP_KERNEL::NORM_QUAD4,4,nodalConnPerCell+14); + mesh->finishInsertingCells(); + //! [CppSnippetUMeshStdBuild1_3] + //! [CppSnippetUMeshStdBuild1_4] + ParaMEDMEM::DataArrayDouble *coordsArr=ParaMEDMEM::DataArrayDouble::New(); + coordsArr->alloc(9,3);//here coordsArr are declared to have 3 components, mesh will deduce that its spaceDim==3. + std::copy(coords,coords+27,coordsArr->getPointer()); + mesh->setCoords(coordsArr);//coordsArr contains 9 tuples, that is to say mesh contains 9 nodes. + coordsArr->decrRef(); + //! [CppSnippetUMeshStdBuild1_4] + mesh->checkCoherency(); + //! [CppSnippetUMeshStdBuild1_5] + mesh->decrRef(); + //! [CppSnippetUMeshStdBuild1_5] +} + +void CppSnippetCMeshStdBuild1() +{ + //! [CppSnippetCMeshStdBuild1_1] + double XCoords[9]={-0.3,0.,0.1,0.3,0.45,0.47,0.49,1.,1.22}; + double YCoords[7]={0.,0.1,0.37,0.45,0.47,0.49,1.007}; + ParaMEDMEM::DataArrayDouble *arrX=ParaMEDMEM::DataArrayDouble::New(); + arrX->alloc(9,1); + std::copy(XCoords,XCoords+9,arrX->getPointer()); + arrX->setInfoOnComponent(0,"X [m]"); + ParaMEDMEM::DataArrayDouble *arrY=ParaMEDMEM::DataArrayDouble::New(); + arrY->alloc(7,1); + std::copy(YCoords,YCoords+7,arrY->getPointer()); + arrY->setInfoOnComponent(0,"Y [m]"); + //! [CppSnippetCMeshStdBuild1_1] + //! [CppSnippetCMeshStdBuild1_2] + ParaMEDMEM::MEDCouplingCMesh *mesh=ParaMEDMEM::MEDCouplingCMesh::New("My2D_CMesh"); + mesh->setCoords(arrX,arrY); + arrX->decrRef(); + arrY->decrRef(); + //! [CppSnippetCMeshStdBuild1_2] + //! [CppSnippetCMeshStdBuild1_3] + CPPUNIT_ASSERT_EQUAL(8*6,mesh->getNumberOfCells()); + CPPUNIT_ASSERT_EQUAL(9*7,mesh->getNumberOfNodes()); + CPPUNIT_ASSERT_EQUAL(2,mesh->getSpaceDimension()); + CPPUNIT_ASSERT_EQUAL(2,mesh->getMeshDimension()); + //! [CppSnippetCMeshStdBuild1_3] + mesh->decrRef(); + mesh=ParaMEDMEM::MEDCouplingCMesh::New("My2D_CMesh"); + arrX=ParaMEDMEM::DataArrayDouble::New(); arrX->alloc(9,1); std::copy(XCoords,XCoords+9,arrX->getPointer()); arrX->setInfoOnComponent(0,"X [m]"); + arrY=ParaMEDMEM::DataArrayDouble::New(); arrY->alloc(7,1); std::copy(YCoords,YCoords+7,arrY->getPointer()); arrY->setInfoOnComponent(0,"Y [m]"); + //! [CppSnippetCMeshStdBuild1_2bis] + mesh->setCoordsAt(0,arrX); + arrX->decrRef(); + mesh->setCoordsAt(1,arrY); + arrY->decrRef(); + //! [CppSnippetCMeshStdBuild1_2bis] + CPPUNIT_ASSERT_EQUAL(8*6,mesh->getNumberOfCells()); + CPPUNIT_ASSERT_EQUAL(9*7,mesh->getNumberOfNodes()); + CPPUNIT_ASSERT_EQUAL(2,mesh->getSpaceDimension()); + CPPUNIT_ASSERT_EQUAL(2,mesh->getMeshDimension()); + //! [CppSnippetCMeshStdBuild1_4] + mesh->decrRef(); + //! [CppSnippetCMeshStdBuild1_4] +} + +void CppSnippetUMeshAdvBuild1() +{ + //! [CppSnippetUMeshAdvBuild1_1] + double coords[27]={-0.3,-0.3,0., 0.2,-0.3,0., 0.7,-0.3,0., -0.3,0.2,0., 0.2,0.2,0., + 0.7,0.2,0., -0.3,0.7,0., 0.2,0.7,0., 0.7,0.7,0. }; + int nodalConnPerCell[23]={4,0,3,4,1, 3,1,4,2, 3,4,5,2, 4,6,7,4,3, 4,7,8,5,4}; + int nodalConnPerCellIndex[6]={0,5,9,13,18,23}; + //! [CppSnippetUMeshAdvBuild1_1] + //! [CppSnippetUMeshAdvBuild1_2] + ParaMEDMEM::MEDCouplingUMesh *mesh=ParaMEDMEM::MEDCouplingUMesh::New("My2DMesh",2); + //! [CppSnippetUMeshAdvBuild1_2] + //! [CppSnippetUMeshAdvBuild1_3] + ParaMEDMEM::DataArrayInt *nodalConn=ParaMEDMEM::DataArrayInt::New(); + nodalConn->alloc(23,1); + std::copy(nodalConnPerCell,nodalConnPerCell+23,nodalConn->getPointer()); + ParaMEDMEM::DataArrayInt *nodalConnI=ParaMEDMEM::DataArrayInt::New(); + nodalConnI->alloc(6,1); + std::copy(nodalConnPerCellIndex,nodalConnPerCellIndex+6,nodalConnI->getPointer()); + mesh->setConnectivity(nodalConn,nodalConnI,true); + nodalConn->decrRef();// nodalConn DataArrayInt instance is owned by mesh after call to setConnectivity method. No more need here -> decrRef() + nodalConnI->decrRef();// nodalConnI DataArrayInt instance is owned by mesh after call to setConnectivity method. No more need here -> decrRef() + //! [CppSnippetUMeshAdvBuild1_3] + //! [CppSnippetUMeshAdvBuild1_4] + ParaMEDMEM::DataArrayDouble *coordsArr=ParaMEDMEM::DataArrayDouble::New(); + coordsArr->alloc(9,3);//here coordsArr are declared to have 3 components, mesh will deduce that its spaceDim==3. + std::copy(coords,coords+27,coordsArr->getPointer()); + mesh->setCoords(coordsArr);//coordsArr contains 9 tuples, that is to say mesh contains 9 nodes. + coordsArr->decrRef(); + //! [CppSnippetUMeshAdvBuild1_4] + mesh->checkCoherency(); + //! [CppSnippetUMeshAdvBuild1_5] + mesh->decrRef(); + //! [CppSnippetUMeshAdvBuild1_5] +} + +void CppSnippetDataArrayBuild1() +{ + //! [CppSnippetDataArrayBuild1_0] + const int nbOfNodes=12; + double coords[3*nbOfNodes]={2.,3.,4.,3.,4.,5.,4.,5.,6.,5.,6.,7.,6.,7.,8.,7.,8.,9.,8.,9.,10.,9.,10.,11.,10.,11.,12.,11.,12.,13.,12.,13.,14.,13.,14.,15.}; + // + ParaMEDMEM::DataArrayDouble *coordsArr=0; + double *tmp=0; + //! [CppSnippetDataArrayBuild1_0] + // + //! [CppSnippetDataArrayBuild1_1] + coordsArr=ParaMEDMEM::DataArrayDouble::New(); + coordsArr->useArray(coords,false,ParaMEDMEM::CPP_DEALLOC,nbOfNodes,3); + //now use coordsArr as you need + //... + //coordsArr is no more useful here : release it + coordsArr->decrRef(); + //! [CppSnippetDataArrayBuild1_1] + //! [CppSnippetDataArrayBuild1_2] + coordsArr=ParaMEDMEM::DataArrayDouble::New(); + tmp=new double[3*nbOfNodes]; + std::copy(coords,coords+3*nbOfNodes,tmp); + coordsArr->useArray(tmp,true,ParaMEDMEM::CPP_DEALLOC,nbOfNodes,3); + //now use coordsArr as you need + //... + //coordsArr is no more useful, release it + coordsArr->decrRef(); + //! [CppSnippetDataArrayBuild1_2] + //! [CppSnippetDataArrayBuild1_3] + coordsArr=ParaMEDMEM::DataArrayDouble::New(); + tmp=(double *)malloc(3*nbOfNodes*sizeof(double)); + std::copy(coords,coords+3*nbOfNodes,tmp); + coordsArr->useArray(tmp,true,ParaMEDMEM::C_DEALLOC,nbOfNodes,3); + //now use coordsArr as you need + //... + //coordsArr is no more useful here : release it + coordsArr->decrRef(); + //! [CppSnippetDataArrayBuild1_3] + //! [CppSnippetDataArrayBuild1_4] + coordsArr=ParaMEDMEM::DataArrayDouble::New(); + coordsArr->alloc(nbOfNodes,3); + tmp=coordsArr->getPointer(); + std::copy(coords,coords+3*nbOfNodes,tmp); + coordsArr->declareAsNew();//you have modified data pointed by internal pointer notify object + //now use coordsArr as you need + //... + //coordsArr is no more useful here : release it + coordsArr->decrRef(); + //! [CppSnippetDataArrayBuild1_4] + coordsArr=ParaMEDMEM::DataArrayDouble::New(); + coordsArr->alloc(nbOfNodes,3); + tmp=coordsArr->getPointer(); + std::copy(coords,coords+3*nbOfNodes,tmp); + ParaMEDMEM::DataArrayDouble *coordsArrCpy=0; + //! [CppSnippetDataArrayBuild1_5] + coordsArrCpy=coordsArr->deepCpy(); + //! [CppSnippetDataArrayBuild1_5] + //! [CppSnippetDataArrayBuild1_6] + CPPUNIT_ASSERT(coordsArrCpy->isEqual(*coordsArr,1e-12)); + coordsArrCpy->setIJ(0,0,1000.); + CPPUNIT_ASSERT(!coordsArrCpy->isEqual(*coordsArr,1e-12));//coordsArrCpy only has been modified + //! [CppSnippetDataArrayBuild1_6] + //! [CppSnippetDataArrayBuild1_7] + coordsArrCpy->decrRef(); + //! [CppSnippetDataArrayBuild1_7] + //! [CppSnippetDataArrayBuild1_5bis] + coordsArrCpy=coordsArr->performCpy(true); + //! [CppSnippetDataArrayBuild1_5bis] + CPPUNIT_ASSERT(coordsArrCpy->isEqual(*coordsArr,1e-12)); + coordsArrCpy->setIJ(0,0,1000.); + CPPUNIT_ASSERT(!coordsArrCpy->isEqual(*coordsArr,1e-12));//coordsArrCpy only has been modified + coordsArrCpy->decrRef(); + //! [CppSnippetDataArrayBuild1_8] + coordsArrCpy=coordsArr->performCpy(false); + //! [CppSnippetDataArrayBuild1_8] + //! [CppSnippetDataArrayBuild1_9] + CPPUNIT_ASSERT(coordsArrCpy->isEqual(*coordsArr,1e-12)); + coordsArrCpy->setIJ(0,0,1000.); + CPPUNIT_ASSERT(coordsArrCpy->isEqual(*coordsArr,1e-12));//coordsArr and coordsArrCpy have been modified simultaneously + //! [CppSnippetDataArrayBuild1_9] + //! [CppSnippetDataArrayBuild1_10] + coordsArrCpy->decrRef(); + //! [CppSnippetDataArrayBuild1_10] + //! [CppSnippetDataArrayBuild1_11] + coordsArrCpy=ParaMEDMEM::DataArrayDouble::New(); + //! [CppSnippetDataArrayBuild1_11] + //! [CppSnippetDataArrayBuild1_12] + coordsArrCpy->cpyFrom(*coordsArr); + //! [CppSnippetDataArrayBuild1_12] + //! [CppSnippetDataArrayBuild1_13] + CPPUNIT_ASSERT(coordsArrCpy->isEqual(*coordsArr,1e-12)); + coordsArrCpy->setIJ(0,0,2000.); + CPPUNIT_ASSERT(!coordsArrCpy->isEqual(*coordsArr,1e-12));//coordsArrCpy only has been modified + //! [CppSnippetDataArrayBuild1_13] + //! [CppSnippetDataArrayBuild1_14] + coordsArrCpy->decrRef(); + //! [CppSnippetDataArrayBuild1_14] + coordsArr->decrRef(); + //! [CppSnippetDataArrayBuild1_14] +} + +void CppSnippetFieldDoubleBuild1() +{ + double XCoords[9]={-0.3,0.07,0.1,0.3,0.45,0.47,0.49,1.,1.22}; + double YCoords[7]={0.07,0.1,0.37,0.45,0.47,0.49,1.007}; + ParaMEDMEM::DataArrayDouble *arrX=ParaMEDMEM::DataArrayDouble::New(); arrX->alloc(9,1); std::copy(XCoords,XCoords+9,arrX->getPointer()); arrX->setInfoOnComponent(0,"X [m]"); + ParaMEDMEM::DataArrayDouble *arrY=ParaMEDMEM::DataArrayDouble::New(); arrY->alloc(7,1); std::copy(YCoords,YCoords+7,arrY->getPointer()); arrY->setInfoOnComponent(0,"Y [m]"); + ParaMEDMEM::MEDCouplingCMesh *mesh=ParaMEDMEM::MEDCouplingCMesh::New("My2D_CMesh"); + mesh->setCoords(arrX,arrY); arrX->decrRef(); arrY->decrRef(); + //! [CppSnippetFieldDoubleBuild1_1] + ParaMEDMEM::MEDCouplingFieldDouble* fieldOnCells=ParaMEDMEM::MEDCouplingFieldDouble::New(ParaMEDMEM::ON_CELLS,ParaMEDMEM::NO_TIME); + fieldOnCells->setName("MyTensorFieldOnCellNoTime"); + fieldOnCells->setMesh(mesh); + mesh->decrRef(); // no more need of mesh because mesh has been attached to fieldOnCells + ParaMEDMEM::DataArrayDouble *array=ParaMEDMEM::DataArrayDouble::New(); + array->alloc(fieldOnCells->getMesh()->getNumberOfCells(),9);//Implicitely fieldOnCells will be a 9 components field. + array->fillWithValue(7.); + fieldOnCells->setArray(array); + array->decrRef(); + // fieldOnCells is now usable + // ... + // fieldOnCells is no more useful here : release it + fieldOnCells->decrRef(); + //! [CppSnippetFieldDoubleBuild1_1] + arrX=ParaMEDMEM::DataArrayDouble::New(); arrX->alloc(9,1); std::copy(XCoords,XCoords+9,arrX->getPointer()); arrX->setInfoOnComponent(0,"X [m]"); + arrY=ParaMEDMEM::DataArrayDouble::New(); arrY->alloc(7,1); std::copy(YCoords,YCoords+7,arrY->getPointer()); arrY->setInfoOnComponent(0,"Y [m]"); + mesh=ParaMEDMEM::MEDCouplingCMesh::New("My2D_CMesh"); + mesh->setCoords(arrX,arrY); arrX->decrRef(); arrY->decrRef(); + //! [CppSnippetFieldDoubleBuild1_2] + ParaMEDMEM::MEDCouplingFieldDouble *f1=mesh->fillFromAnalytic(ParaMEDMEM::ON_CELLS,1,"x*x+y*y*3+2.*x");//f1 is scalar + ParaMEDMEM::MEDCouplingFieldDouble *f2=mesh->fillFromAnalytic(ParaMEDMEM::ON_CELLS,1,"cos(x+y/x)");//f2 is scalar too + ParaMEDMEM::MEDCouplingFieldDouble *f2bis=mesh->fillFromAnalytic(ParaMEDMEM::ON_CELLS,2,"x*x*IVec+3*y*JVec");//f2bis is a vectors field + ParaMEDMEM::MEDCouplingFieldDouble *f3=(*f1)+(*f2);//f3 scalar + ParaMEDMEM::MEDCouplingFieldDouble *f4=(*f3)/(*f2);//f4 scalar + f2bis->applyFunc(1,"sqrt(x*x+y*y)");//f2bis becomes scalar + ParaMEDMEM::MEDCouplingFieldDouble *f5=(*f2bis)*(*f4);//f5 scalar + const double pos1[2]={0.48,0.38}; + double res; + f4->getValueOn(pos1,&res);//f4 is scalar so the returned value is of size 1. + // ... + //! [CppSnippetFieldDoubleBuild1_2] + mesh->decrRef(); + //! [CppSnippetFieldDoubleBuild1_3] + // f1, f2, f2bis, f3, f4, f5 are no more useful here : release them + f1->decrRef(); + f2->decrRef(); + f2bis->decrRef(); + f3->decrRef(); + f4->decrRef(); + f5->decrRef(); + //! [CppSnippetFieldDoubleBuild1_3] +} + +void CppSnippetFieldDoubleBuild2() +{ + double XCoords[9]={-0.3,0.,0.1,0.3,0.45,0.47,0.49,1.,1.22}; + double YCoords[7]={0.,0.1,0.37,0.45,0.47,0.49,1.007}; + ParaMEDMEM::DataArrayDouble *arrX=ParaMEDMEM::DataArrayDouble::New(); arrX->alloc(9,1); std::copy(XCoords,XCoords+9,arrX->getPointer()); arrX->setInfoOnComponent(0,"X [m]"); + ParaMEDMEM::DataArrayDouble *arrY=ParaMEDMEM::DataArrayDouble::New(); arrY->alloc(7,1); std::copy(YCoords,YCoords+7,arrY->getPointer()); arrY->setInfoOnComponent(0,"Y [m]"); + ParaMEDMEM::MEDCouplingCMesh *mesh=ParaMEDMEM::MEDCouplingCMesh::New("My2D_CMesh"); + mesh->setCoords(arrX,arrY); arrX->decrRef(); arrY->decrRef(); + //! [CppSnippetFieldDoubleBuild2_1] + ParaMEDMEM::MEDCouplingFieldDouble* fieldOnNodes=ParaMEDMEM::MEDCouplingFieldDouble::New(ParaMEDMEM::ON_NODES,ParaMEDMEM::NO_TIME); + fieldOnNodes->setName("MyScalarFieldOnNodeNoTime"); + fieldOnNodes->setMesh(mesh); + mesh->decrRef(); // no more need of mesh because mesh has been attached to fieldOnNodes + ParaMEDMEM::DataArrayDouble *array=ParaMEDMEM::DataArrayDouble::New(); + array->alloc(fieldOnNodes->getMesh()->getNumberOfNodes(),1);//Implicitely fieldOnNodes will be a 1 component field. + array->fillWithValue(8.); + fieldOnNodes->setArray(array); + array->decrRef(); + // fieldOnNodes is now usable + // ... + // fieldOnNodes is no more useful here : release it + fieldOnNodes->decrRef(); + //! [CppSnippetFieldDoubleBuild2_1] +} + +void CppSnippetFieldDoubleBuild3() +{ + double XCoords[9]={-0.3,0.,0.1,0.3,0.45,0.47,0.49,1.,1.22}; + double YCoords[7]={0.,0.1,0.37,0.45,0.47,0.49,1.007}; + ParaMEDMEM::DataArrayDouble *arrX=ParaMEDMEM::DataArrayDouble::New(); arrX->alloc(9,1); std::copy(XCoords,XCoords+9,arrX->getPointer()); arrX->setInfoOnComponent(0,"X [m]"); + ParaMEDMEM::DataArrayDouble *arrY=ParaMEDMEM::DataArrayDouble::New(); arrY->alloc(7,1); std::copy(YCoords,YCoords+7,arrY->getPointer()); arrY->setInfoOnComponent(0,"Y [m]"); + ParaMEDMEM::MEDCouplingCMesh *mesh=ParaMEDMEM::MEDCouplingCMesh::New("My2D_CMesh"); + mesh->setCoords(arrX,arrY); arrX->decrRef(); arrY->decrRef(); + //! [CppSnippetFieldDoubleBuild3_1] + ParaMEDMEM::MEDCouplingFieldDouble* fieldOnCells=ParaMEDMEM::MEDCouplingFieldDouble::New(ParaMEDMEM::ON_CELLS,ParaMEDMEM::ONE_TIME); + fieldOnCells->setName("MyTensorFieldOnCellNoTime"); + fieldOnCells->setTimeUnit("ms"); // Time unit is ms. + fieldOnCells->setTime(4.22,2,-1); // Time attached is 4.22 ms, iteration id is 2 and order id (or sub iteration id) is -1 + fieldOnCells->setMesh(mesh); + mesh->decrRef(); // no more need of mesh because mesh has been attached to fieldOnCells + ParaMEDMEM::DataArrayDouble *array=ParaMEDMEM::DataArrayDouble::New(); + array->alloc(fieldOnCells->getMesh()->getNumberOfCells(),2);//Implicitely fieldOnCells will be a 2 components field. + array->fillWithValue(7.); + fieldOnCells->setArray(array); + array->decrRef(); + // fieldOnCells is now usable + // ... + // fieldOnCells is no more useful here : release it + fieldOnCells->decrRef(); + //! [CppSnippetFieldDoubleBuild3_1] +} + +void CppSnippetFieldDoubleBuild4() +{ + double XCoords[9]={-0.3,0.,0.1,0.3,0.45,0.47,0.49,1.,1.22}; + double YCoords[7]={0.,0.1,0.37,0.45,0.47,0.49,1.007}; + ParaMEDMEM::DataArrayDouble *arrX=ParaMEDMEM::DataArrayDouble::New(); arrX->alloc(9,1); std::copy(XCoords,XCoords+9,arrX->getPointer()); arrX->setInfoOnComponent(0,"X [m]"); + ParaMEDMEM::DataArrayDouble *arrY=ParaMEDMEM::DataArrayDouble::New(); arrY->alloc(7,1); std::copy(YCoords,YCoords+7,arrY->getPointer()); arrY->setInfoOnComponent(0,"Y [m]"); + ParaMEDMEM::MEDCouplingCMesh *mesh=ParaMEDMEM::MEDCouplingCMesh::New("My2D_CMesh"); + mesh->setCoords(arrX,arrY); arrX->decrRef(); arrY->decrRef(); + //! [CppSnippetFieldDoubleBuild4_1] + ParaMEDMEM::MEDCouplingFieldDouble* fieldOnNodes=ParaMEDMEM::MEDCouplingFieldDouble::New(ParaMEDMEM::ON_NODES,ParaMEDMEM::CONST_ON_TIME_INTERVAL); + fieldOnNodes->setName("MyVecFieldOnNodeWithConstTime"); + fieldOnNodes->setTimeUnit("ms"); // Time unit is ms. + fieldOnNodes->setStartTime(4.22,2,-1); + fieldOnNodes->setEndTime(6.44,4,-1); // fieldOnNodes is defined in interval [4.22 ms,6.44 ms] + fieldOnNodes->setMesh(mesh); + mesh->decrRef(); // no more need of mesh because mesh has been attached to fieldOnNodes + ParaMEDMEM::DataArrayDouble *array=ParaMEDMEM::DataArrayDouble::New(); + array->alloc(fieldOnNodes->getMesh()->getNumberOfNodes(),3);//Implicitely fieldOnNodes will be a 3 components field. + array->fillWithValue(8.); + fieldOnNodes->setArray(array); + array->decrRef(); + // fieldOnNodes is now usable + // ... + // fieldOnNodes is no more useful here : release it + fieldOnNodes->decrRef(); + //! [CppSnippetFieldDoubleBuild4_1] +} + +int main(int argc, char *argv[]) +{ + CppExample_MEDCouplingFieldDouble_WriteVTK(); + CppExample_MEDCouplingFieldDouble_MaxFields(); + CppExample_MEDCouplingFieldDouble_MergeFields(); + CppExample_MEDCouplingFieldDouble_substractInPlaceDM(); + CppExample_MEDCouplingFieldDouble_changeUnderlyingMesh(); + CppExample_MEDCouplingFieldDouble_applyFunc_same_nb_comp(); + CppExample_MEDCouplingFieldDouble_applyFunc3(); + CppExample_MEDCouplingFieldDouble_applyFunc2(); + CppExample_MEDCouplingFieldDouble_applyFunc(); + CppExample_MEDCouplingFieldDouble_applyFunc_val(); + CppExample_MEDCouplingFieldDouble_fillFromAnalytic3(); + CppExample_MEDCouplingFieldDouble_fillFromAnalytic2(); + CppExample_MEDCouplingFieldDouble_fillFromAnalytic(); + CppExample_MEDCouplingFieldDouble_fillFromAnalytic_c_func(); + CppExample_MEDCouplingFieldDouble_applyFunc_c_func(); + CppExample_MEDCouplingFieldDouble_getValueOn_time(); + CppExample_MEDCouplingFieldDouble_getValueOnMulti(); + CppExample_MEDCouplingFieldDouble_getValueOn(); + CppExample_MEDCouplingFieldDouble_getValueOnPos(); + CppExample_MEDCouplingFieldDouble_renumberNodes(); + CppExample_MEDCouplingFieldDouble_renumberCells(); + CppExample_MEDCouplingFieldDouble_buildNewTimeReprFromThis(); + CppExample_MEDCouplingMesh_fillFromAnalytic3(); + CppExample_MEDCouplingMesh_fillFromAnalytic2(); + CppExample_MEDCouplingMesh_fillFromAnalytic(); + CppExample_MEDCouplingCMesh_getCoordsAt(); + CppExample_MEDCouplingUMesh_areCellsIncludedIn(); + CppExample_MEDCouplingUMesh_findAndCorrectBadOriented3DExtrudedCells(); + CppExample_MEDCouplingUMesh_arePolyhedronsNotCorrectlyOriented(); + CppExample_MEDCouplingUMesh_are2DCellsNotCorrectlyOriented(); + CppExample_MEDCouplingUMesh_getCellsContainingPoints(); + CppExample_MEDCouplingUMesh_getCellsContainingPoint(); + CppExample_MEDCouplingUMesh_buildPartOrthogonalField(); + CppExample_MEDCouplingUMesh_getPartMeasureField(); + CppExample_MEDCouplingUMesh_getCellsInBoundingBox(); + CppExample_MEDCouplingUMesh_renumberNodesInConn(); + CppExample_MEDCouplingUMesh_renumberNodes(); + CppExample_MEDCouplingUMesh_findBoundaryNodes(); + CppExample_MEDCouplingUMesh_buildBoundaryMesh(); + CppExample_MEDCouplingUMesh_buildFacePartOfMySelfNode(); + CppExample_MEDCouplingUMesh_buildPartOfMySelfNode(); + CppExample_MEDCouplingUMesh_getCellIdsLyingOnNodes(); + CppExample_MEDCouplingUMesh_getCellIdsFullyIncludedInNodeIds(); + CppExample_MEDCouplingUMesh_buildPartOfMySelf(); + CppExample_MEDCouplingUMesh_mergeNodes(); + CppExample_MEDCouplingUMesh_zipConnectivityTraducer(); + CppExample_MEDCouplingUMesh_zipCoordsTraducer(); + CppExample_MEDCouplingUMesh_getNodeIdsInUse(); + CppExample_MEDCouplingUMesh_convertToPolyTypes(); + CppExample_MEDCouplingUMesh_buildDescendingConnectivity2(); + CppExample_MEDCouplingUMesh_buildDescendingConnectivity(); + CppExample_MEDCouplingUMesh_getReverseNodalConnectivity(); + CppExample_MEDCouplingUMesh_checkDeepEquivalWith(); + CppExample_MEDCouplingPointSet_scale(); + CppExample_MEDCouplingPointSet_translate(); + CppExample_MEDCouplingPointSet_rotate(); + CppExample_MEDCouplingPointSet_getBoundingBox(); + CppExample_MEDCouplingPointSet_getNodeIdsNearPoint(); + CppExample_MEDCouplingPointSet_getNodeIdsNearPoints(); + CppExample_MEDCouplingPointSet_findCommonNodes(); + CppExample_MEDCouplingPointSet_getCoordinatesOfNode(); + CppExample_DataArrayInt_buildPermutationArr(); + CppExample_DataArrayInt_invertArrayO2N2N2O(); + CppExample_DataArrayInt_invertArrayN2O2O2N(); + CppExample_DataArrayDouble_getIdsInRange(); + CppExample_DataArrayDouble_findCommonTuples(); + CppExample_DataArrayDouble_Meld1(); + CppExampleFieldDoubleBuildSubPart1(); + CppSnippetUMeshStdBuild1(); + CppSnippetUMeshAdvBuild1(); + CppSnippetDataArrayBuild1(); + CppSnippetCMeshStdBuild1(); + CppSnippetFieldDoubleBuild1(); + CppSnippetFieldDoubleBuild2(); + CppSnippetFieldDoubleBuild3(); + CppSnippetFieldDoubleBuild4(); + + return 0; +} diff --git a/src/medtool/src/MEDCoupling/Test/MEDCouplingRemapperTest.cxx b/src/medtool/src/MEDCoupling/Test/MEDCouplingRemapperTest.cxx new file mode 100644 index 000000000..f8a2e37ba --- /dev/null +++ b/src/medtool/src/MEDCoupling/Test/MEDCouplingRemapperTest.cxx @@ -0,0 +1,1318 @@ +// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 +// 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 "MEDCouplingRemapperTest.hxx" +#include "MEDCouplingUMesh.hxx" +#include "MEDCouplingExtrudedMesh.hxx" +#include "MEDCouplingFieldDouble.hxx" +#include "MEDCouplingFieldTemplate.hxx" +#include "MEDCouplingMemArray.hxx" +#include "MEDCouplingRemapper.hxx" + +#include "MEDCouplingBasicsTest.hxx" + +#include <cmath> +#include <numeric> + +using namespace ParaMEDMEM; + +void MEDCouplingRemapperTest::test2DInterpP0P0_1() +{ + MEDCouplingUMesh *sourceMesh=MEDCouplingBasicsTest::build2DSourceMesh_1(); + MEDCouplingUMesh *targetMesh=MEDCouplingBasicsTest::build2DTargetMesh_1(); + // + MEDCouplingRemapper remapper; + remapper.setPrecision(1e-12); + remapper.setIntersectionType(INTERP_KERNEL::Triangulation); + CPPUNIT_ASSERT_EQUAL(1,remapper.prepare(sourceMesh,targetMesh,"P0P0")); + + MEDCouplingFieldDouble *srcField=MEDCouplingFieldDouble::New(ON_CELLS); + srcField->setNature(ConservativeVolumic); + srcField->setMesh(sourceMesh); + DataArrayDouble *array=DataArrayDouble::New(); + array->alloc(sourceMesh->getNumberOfCells(),1); + srcField->setArray(array); + double *ptr=array->getPointer(); + for(int i=0;i<sourceMesh->getNumberOfCells();i++) + ptr[i]=(double)(i+7); + array->decrRef(); + MEDCouplingFieldDouble *trgfield=remapper.transferField(srcField,4.57); + const double *values=trgfield->getArray()->getConstPointer(); + const double valuesExpected[5]={7.5 ,7. ,7.,8.,7.5}; + CPPUNIT_ASSERT_EQUAL(5,trgfield->getArray()->getNumberOfTuples()); + CPPUNIT_ASSERT_EQUAL(1,trgfield->getArray()->getNumberOfComponents()); + for(int i0=0;i0<5;i0++) + CPPUNIT_ASSERT_DOUBLES_EQUAL(valuesExpected[i0],values[i0],1e-12); + trgfield->decrRef(); + // + srcField->setNature(IntegralGlobConstraint); + trgfield=remapper.transferField(srcField,4.57); + values=trgfield->getArray()->getConstPointer(); + const double valuesExpected2[5]={3.75 ,1.75 ,1.75,4.,3.75}; + CPPUNIT_ASSERT_EQUAL(5,trgfield->getArray()->getNumberOfTuples()); + CPPUNIT_ASSERT_EQUAL(1,trgfield->getArray()->getNumberOfComponents()); + for(int i0=0;i0<5;i0++) + CPPUNIT_ASSERT_DOUBLES_EQUAL(valuesExpected2[i0],values[i0],1e-12); + trgfield->decrRef(); + // + srcField->setNature(ConservativeVolumic); + trgfield=remapper.transferField(srcField,4.57); + values=trgfield->getArray()->getConstPointer(); + CPPUNIT_ASSERT_EQUAL(5,trgfield->getArray()->getNumberOfTuples()); + CPPUNIT_ASSERT_EQUAL(1,trgfield->getArray()->getNumberOfComponents()); + for(int i0=0;i0<5;i0++) + CPPUNIT_ASSERT_DOUBLES_EQUAL(valuesExpected[i0],values[i0],1e-12); + trgfield->decrRef(); + // + srcField->setNature(IntegralGlobConstraint); + trgfield=remapper.transferField(srcField,4.57); + values=trgfield->getArray()->getConstPointer(); + CPPUNIT_ASSERT_EQUAL(5,trgfield->getArray()->getNumberOfTuples()); + CPPUNIT_ASSERT_EQUAL(1,trgfield->getArray()->getNumberOfComponents()); + for(int i0=0;i0<5;i0++) + CPPUNIT_ASSERT_DOUBLES_EQUAL(valuesExpected2[i0],values[i0],1e-12); + trgfield->decrRef(); + // + srcField->setNature(Integral); + trgfield=remapper.transferField(srcField,4.57); + values=trgfield->getArray()->getConstPointer(); + CPPUNIT_ASSERT_EQUAL(5,trgfield->getArray()->getNumberOfTuples()); + CPPUNIT_ASSERT_EQUAL(1,trgfield->getArray()->getNumberOfComponents()); + for(int i0=0;i0<5;i0++) + CPPUNIT_ASSERT_DOUBLES_EQUAL(valuesExpected2[i0],values[i0],1e-12); + trgfield->decrRef(); + // + srcField->setNature(RevIntegral); + trgfield=remapper.transferField(srcField,4.57); + values=trgfield->getArray()->getConstPointer(); + CPPUNIT_ASSERT_EQUAL(5,trgfield->getArray()->getNumberOfTuples()); + CPPUNIT_ASSERT_EQUAL(1,trgfield->getArray()->getNumberOfComponents()); + for(int i0=0;i0<5;i0++) + CPPUNIT_ASSERT_DOUBLES_EQUAL(valuesExpected[i0],values[i0],1e-12); + trgfield->decrRef(); + // + srcField->decrRef(); + //clean up + sourceMesh->decrRef(); + targetMesh->decrRef(); +} + +void MEDCouplingRemapperTest::test2DInterpP0P0R_1() +{ + MEDCouplingUMesh *sourceMesh=MEDCouplingBasicsTest::build2DSourceMesh_1(); + MEDCouplingUMesh *targetMesh=MEDCouplingBasicsTest::build2DTargetMesh_1(); + // + MEDCouplingRemapper remapper; + remapper.setPrecision(1e-12); + remapper.setIntersectionType(INTERP_KERNEL::Triangulation); + CPPUNIT_ASSERT_EQUAL(1,remapper.prepare(sourceMesh,targetMesh,"P0P0")); + + MEDCouplingFieldDouble *targetField=MEDCouplingFieldDouble::New(ON_CELLS); + targetField->setNature(ConservativeVolumic); + targetField->setMesh(targetMesh); + DataArrayDouble *array=DataArrayDouble::New(); + array->alloc(targetMesh->getNumberOfCells(),1); + targetField->setArray(array); + double *ptr=array->getPointer(); + for(int i=0;i<targetMesh->getNumberOfCells();i++) + ptr[i]=(double)(i+7); + array->decrRef(); + // + MEDCouplingFieldDouble *srcfield=remapper.reverseTransferField(targetField,4.57); + const double *values=srcfield->getArray()->getConstPointer(); + const double valuesExpected[2]={8.75 ,9.5}; + CPPUNIT_ASSERT_EQUAL(2,srcfield->getArray()->getNumberOfTuples()); + CPPUNIT_ASSERT_EQUAL(1,srcfield->getArray()->getNumberOfComponents()); + for(int i0=0;i0<2;i0++) + CPPUNIT_ASSERT_DOUBLES_EQUAL(valuesExpected[i0],values[i0],1e-12); + srcfield->decrRef(); + // + targetField->setNature(IntegralGlobConstraint); + srcfield=remapper.reverseTransferField(targetField,4.57); + values=srcfield->getArray()->getConstPointer(); + const double valuesExpected2[2]={26., 19.}; + CPPUNIT_ASSERT_EQUAL(2,srcfield->getArray()->getNumberOfTuples()); + CPPUNIT_ASSERT_EQUAL(1,srcfield->getArray()->getNumberOfComponents()); + for(int i0=0;i0<2;i0++) + CPPUNIT_ASSERT_DOUBLES_EQUAL(valuesExpected2[i0],values[i0],1e-12); + srcfield->decrRef(); + // + targetField->decrRef(); + //clean up + sourceMesh->decrRef(); + targetMesh->decrRef(); +} + +void MEDCouplingRemapperTest::test1DInterp_1() +{ + MEDCouplingUMesh *sourceMesh=MEDCouplingBasicsTest::build1DSourceMesh_2(); + MEDCouplingUMesh *targetMesh=MEDCouplingBasicsTest::build1DTargetMesh_2(); + // + MEDCouplingRemapper remapper; + CPPUNIT_ASSERT_EQUAL(1,remapper.prepare(sourceMesh,targetMesh,"P0P0")); + MEDCouplingFieldDouble *srcField=MEDCouplingFieldDouble::New(ON_CELLS); + srcField->setNature(ConservativeVolumic); + srcField->setMesh(sourceMesh); + DataArrayDouble *array=DataArrayDouble::New(); + array->alloc(sourceMesh->getNumberOfCells(),1); + srcField->setArray(array); + double *ptr=array->getPointer(); + for(int i=0;i<sourceMesh->getNumberOfCells();i++) + ptr[i]=(double)(i+7); + array->decrRef(); + // + MEDCouplingFieldDouble *trgfield=remapper.transferField(srcField,4.57); + const double *values=trgfield->getArray()->getConstPointer(); + const double valuesExpected1[2]={9.0540540540540526,7.4}; + CPPUNIT_ASSERT_EQUAL(2,trgfield->getArray()->getNumberOfTuples()); + CPPUNIT_ASSERT_EQUAL(1,trgfield->getArray()->getNumberOfComponents()); + for(int i0=0;i0<2;i0++) + CPPUNIT_ASSERT_DOUBLES_EQUAL(valuesExpected1[i0],values[i0],1e-12); + trgfield->decrRef(); + const double valuesExpected2[2]={24.75,5.75}; + srcField->setNature(Integral); + trgfield=remapper.transferField(srcField,4.57); + values=trgfield->getArray()->getConstPointer(); + CPPUNIT_ASSERT_EQUAL(2,trgfield->getArray()->getNumberOfTuples()); + CPPUNIT_ASSERT_EQUAL(1,trgfield->getArray()->getNumberOfComponents()); + for(int i0=0;i0<2;i0++) + CPPUNIT_ASSERT_DOUBLES_EQUAL(valuesExpected2[i0],values[i0],1e-12); + trgfield->decrRef(); + // + const double valuesExpected3[2]={24.75,9.25}; + srcField->setNature(IntegralGlobConstraint); + trgfield=remapper.transferField(srcField,4.57); + values=trgfield->getArray()->getConstPointer(); + CPPUNIT_ASSERT_EQUAL(2,trgfield->getArray()->getNumberOfTuples()); + CPPUNIT_ASSERT_EQUAL(1,trgfield->getArray()->getNumberOfComponents()); + for(int i0=0;i0<2;i0++) + CPPUNIT_ASSERT_DOUBLES_EQUAL(valuesExpected3[i0],values[i0],1e-12); + trgfield->decrRef(); + // + const double valuesExpected4[2]={7.4444444444444446,7.4}; + srcField->setNature(RevIntegral); + trgfield=remapper.transferField(srcField,4.57); + values=trgfield->getArray()->getConstPointer(); + CPPUNIT_ASSERT_EQUAL(2,trgfield->getArray()->getNumberOfTuples()); + CPPUNIT_ASSERT_EQUAL(1,trgfield->getArray()->getNumberOfComponents()); + for(int i0=0;i0<2;i0++) + CPPUNIT_ASSERT_DOUBLES_EQUAL(valuesExpected4[i0],values[i0],1e-12); + trgfield->decrRef(); + // + srcField->decrRef(); + sourceMesh->decrRef(); + targetMesh->decrRef(); + //2D Curve + sourceMesh=MEDCouplingBasicsTest::build2DCurveSourceMesh_2(); + targetMesh=MEDCouplingBasicsTest::build2DCurveTargetMesh_2(); + CPPUNIT_ASSERT_EQUAL(1,remapper.prepare(sourceMesh,targetMesh,"P0P0")); + srcField=MEDCouplingFieldDouble::New(ON_CELLS); + srcField->setNature(ConservativeVolumic); + srcField->setMesh(sourceMesh); + array=DataArrayDouble::New(); + array->alloc(sourceMesh->getNumberOfCells(),1); + srcField->setArray(array); + ptr=array->getPointer(); + for(int i=0;i<sourceMesh->getNumberOfCells();i++) + ptr[i]=(double)(i+7); + array->decrRef(); + // + trgfield=remapper.transferField(srcField,4.57); + values=trgfield->getArray()->getConstPointer(); + CPPUNIT_ASSERT_EQUAL(2,trgfield->getArray()->getNumberOfTuples()); + CPPUNIT_ASSERT_EQUAL(1,trgfield->getArray()->getNumberOfComponents()); + for(int i0=0;i0<2;i0++) + CPPUNIT_ASSERT_DOUBLES_EQUAL(valuesExpected1[i0],values[i0],1e-12); + trgfield->decrRef(); + srcField->setNature(Integral); + trgfield=remapper.transferField(srcField,4.57); + values=trgfield->getArray()->getConstPointer(); + CPPUNIT_ASSERT_EQUAL(2,trgfield->getArray()->getNumberOfTuples()); + CPPUNIT_ASSERT_EQUAL(1,trgfield->getArray()->getNumberOfComponents()); + for(int i0=0;i0<2;i0++) + CPPUNIT_ASSERT_DOUBLES_EQUAL(valuesExpected2[i0],values[i0],1e-12); + trgfield->decrRef(); + // + srcField->setNature(IntegralGlobConstraint); + trgfield=remapper.transferField(srcField,4.57); + values=trgfield->getArray()->getConstPointer(); + CPPUNIT_ASSERT_EQUAL(2,trgfield->getArray()->getNumberOfTuples()); + CPPUNIT_ASSERT_EQUAL(1,trgfield->getArray()->getNumberOfComponents()); + for(int i0=0;i0<2;i0++) + CPPUNIT_ASSERT_DOUBLES_EQUAL(valuesExpected3[i0],values[i0],1e-12); + trgfield->decrRef(); + // + srcField->setNature(RevIntegral); + trgfield=remapper.transferField(srcField,4.57); + values=trgfield->getArray()->getConstPointer(); + CPPUNIT_ASSERT_EQUAL(2,trgfield->getArray()->getNumberOfTuples()); + CPPUNIT_ASSERT_EQUAL(1,trgfield->getArray()->getNumberOfComponents()); + for(int i0=0;i0<2;i0++) + CPPUNIT_ASSERT_DOUBLES_EQUAL(valuesExpected4[i0],values[i0],1e-12); + trgfield->decrRef(); + // + srcField->decrRef(); + sourceMesh->decrRef(); + targetMesh->decrRef(); +} + +void MEDCouplingRemapperTest::test2DInterpMultiMethods() +{ + MEDCouplingUMesh *sourceMesh=MEDCouplingBasicsTest::build2DSourceMesh_1(); + MEDCouplingUMesh *targetMesh=MEDCouplingBasicsTest::build2DTargetMesh_1(); + // + MEDCouplingRemapper remapper; + remapper.setPrecision(1e-12); + remapper.setIntersectionType(INTERP_KERNEL::Triangulation); + CPPUNIT_ASSERT_EQUAL(1,remapper.prepare(sourceMesh,targetMesh,"P0P0")); + + MEDCouplingFieldDouble *srcField=MEDCouplingFieldDouble::New(ON_CELLS); + srcField->setNature(ConservativeVolumic); + srcField->setMesh(sourceMesh); + DataArrayDouble *array=DataArrayDouble::New(); + array->alloc(sourceMesh->getNumberOfCells(),1); + srcField->setArray(array); + double *ptr=array->getPointer(); + for(int i=0;i<sourceMesh->getNumberOfCells();i++) + ptr[i]=(double)(i+7); + array->decrRef(); + MEDCouplingFieldDouble *trgfield=remapper.transferField(srcField,4.57); + const double *values=trgfield->getArray()->getConstPointer(); + const double valuesExpected[5]={7.5 ,7. ,7.,8.,7.5}; + CPPUNIT_ASSERT_EQUAL(5,trgfield->getArray()->getNumberOfTuples()); + CPPUNIT_ASSERT_EQUAL(1,trgfield->getArray()->getNumberOfComponents()); + for(int i0=0;i0<5;i0++) + CPPUNIT_ASSERT_DOUBLES_EQUAL(valuesExpected[i0],values[i0],1e-12); + trgfield->decrRef(); + srcField->decrRef(); + // + CPPUNIT_ASSERT_EQUAL(1,remapper.prepare(sourceMesh,targetMesh,"P1P0")); + srcField=MEDCouplingFieldDouble::New(ON_NODES); + srcField->setNature(ConservativeVolumic); + srcField->setMesh(sourceMesh); + array=DataArrayDouble::New(); + array->alloc(sourceMesh->getNumberOfNodes(),1); + srcField->setArray(array); + ptr=array->getPointer(); + for(int i=0;i<sourceMesh->getNumberOfNodes();i++) + ptr[i]=(double)(i+7); + array->decrRef(); + trgfield=remapper.transferField(srcField,4.57); + values=trgfield->getArray()->getConstPointer(); + const double valuesExpected2[5]={7.,7.666666666666667,8.6666666666666661,8.8333333333333339,10.}; + CPPUNIT_ASSERT_EQUAL(5,trgfield->getArray()->getNumberOfTuples()); + CPPUNIT_ASSERT_EQUAL(1,trgfield->getArray()->getNumberOfComponents()); + for(int i0=0;i0<5;i0++) + CPPUNIT_ASSERT_DOUBLES_EQUAL(valuesExpected2[i0],values[i0],1e-12); + trgfield->decrRef(); + srcField->decrRef(); + // + CPPUNIT_ASSERT_EQUAL(1,remapper.prepare(targetMesh,sourceMesh,"P0P1")); + srcField=MEDCouplingFieldDouble::New(ON_CELLS); + srcField->setNature(ConservativeVolumic); + srcField->setMesh(targetMesh); + array=DataArrayDouble::New(); + array->alloc(targetMesh->getNumberOfCells(),1); + srcField->setArray(array); + ptr=array->getPointer(); + for(int i=0;i<targetMesh->getNumberOfCells();i++) + ptr[i]=(double)(i+7); + array->decrRef(); + trgfield=remapper.transferField(srcField,4.57); + values=trgfield->getArray()->getConstPointer(); + const double valuesExpected3[4]={7.5,8.5,10.,10.625}; + CPPUNIT_ASSERT_EQUAL(4,trgfield->getArray()->getNumberOfTuples()); + CPPUNIT_ASSERT_EQUAL(1,trgfield->getArray()->getNumberOfComponents()); + for(int i0=0;i0<4;i0++) + CPPUNIT_ASSERT_DOUBLES_EQUAL(valuesExpected3[i0],values[i0],1e-12); + trgfield->decrRef(); + srcField->decrRef(); + //clean up + sourceMesh->decrRef(); + targetMesh->decrRef(); + // + sourceMesh=MEDCouplingBasicsTest::build2DSourceMesh_1(); + targetMesh=MEDCouplingBasicsTest::build2DTargetMesh_2(); + CPPUNIT_ASSERT_EQUAL(1,remapper.prepare(sourceMesh,targetMesh,"P1P1")); + srcField=MEDCouplingFieldDouble::New(ON_NODES); + srcField->setNature(ConservativeVolumic); + srcField->setMesh(sourceMesh); + array=DataArrayDouble::New(); + array->alloc(sourceMesh->getNumberOfNodes(),1); + srcField->setArray(array); + ptr=array->getPointer(); + for(int i=0;i<sourceMesh->getNumberOfNodes();i++) + ptr[i]=(double)(i+7); + array->decrRef(); + trgfield=remapper.transferField(srcField,4.57); + values=trgfield->getArray()->getConstPointer(); + const double valuesExpected4[9]={ 7.,7.35,8.,7.7,8.2857142857142865, + 9.5333333333333332,9.,9.7666666666666657,10.}; + CPPUNIT_ASSERT_EQUAL(9,trgfield->getArray()->getNumberOfTuples()); + CPPUNIT_ASSERT_EQUAL(1,trgfield->getArray()->getNumberOfComponents()); + for(int i0=0;i0<9;i0++) + CPPUNIT_ASSERT_DOUBLES_EQUAL(valuesExpected4[i0],values[i0],1e-12); + trgfield->decrRef(); + srcField->decrRef(); + //clean up + sourceMesh->decrRef(); + targetMesh->decrRef(); +} + +void MEDCouplingRemapperTest::testMultiDimCombi() +{ + // ------------- 2D + MEDCouplingUMesh *sourceMesh=MEDCouplingBasicsTest::build2DSourceMesh_1(); + MEDCouplingUMesh *targetMesh=MEDCouplingBasicsTest::build2DTargetMesh_1(); + // + MEDCouplingRemapper remapper; + remapper.setPrecision(1e-12); + remapper.setIntersectionType(INTERP_KERNEL::Triangulation); + CPPUNIT_ASSERT_EQUAL(1,remapper.prepare(sourceMesh,targetMesh,"P0P0")); + MEDCouplingFieldDouble *srcField=MEDCouplingFieldDouble::New(ON_CELLS); + srcField->setNature(ConservativeVolumic); + srcField->setMesh(sourceMesh); + DataArrayDouble *array=DataArrayDouble::New(); + array->alloc(sourceMesh->getNumberOfCells(),1); + srcField->setArray(array); + double *ptr=array->getPointer(); + for(int i=0;i<sourceMesh->getNumberOfCells();i++) + ptr[i]=(double)(i+7); + array->decrRef(); + MEDCouplingFieldDouble *trgField=remapper.transferField(srcField,4.57); + const double *values=trgField->getArray()->getConstPointer(); + const double valuesExpected[5]={7.5 ,7. ,7.,8.,7.5}; + CPPUNIT_ASSERT_EQUAL(5,trgField->getArray()->getNumberOfTuples()); + CPPUNIT_ASSERT_EQUAL(1,trgField->getArray()->getNumberOfComponents()); + for(int i0=0;i0<5;i0++) + CPPUNIT_ASSERT_DOUBLES_EQUAL(valuesExpected[i0],values[i0],1e-12); + trgField->decrRef(); + srcField->decrRef(); + sourceMesh->decrRef(); + targetMesh->decrRef(); + // ------------- 3D Surf + sourceMesh=MEDCouplingBasicsTest::build3DSurfSourceMesh_1(); + targetMesh=MEDCouplingBasicsTest::build3DSurfTargetMesh_1(); + CPPUNIT_ASSERT_EQUAL(1,remapper.prepare(sourceMesh,targetMesh,"P0P0")); + srcField=MEDCouplingFieldDouble::New(ON_CELLS); + srcField->setNature(ConservativeVolumic); + srcField->setMesh(sourceMesh); + array=DataArrayDouble::New(); + array->alloc(sourceMesh->getNumberOfCells(),1); + srcField->setArray(array); + ptr=array->getPointer(); + for(int i=0;i<sourceMesh->getNumberOfCells();i++) + ptr[i]=(double)(i+8); + array->decrRef(); + trgField=remapper.transferField(srcField,4.57); + CPPUNIT_ASSERT_EQUAL(5,trgField->getArray()->getNumberOfTuples()); + CPPUNIT_ASSERT_EQUAL(1,trgField->getArray()->getNumberOfComponents()); + const double valuesExpected2[5]={8.5,8.,8.,9.,8.5}; + values=trgField->getArray()->getConstPointer(); + for(int i0=0;i0<5;i0++) + CPPUNIT_ASSERT_DOUBLES_EQUAL(valuesExpected2[i0],values[i0],1e-12); + trgField->decrRef(); + srcField->decrRef(); + sourceMesh->decrRef(); + targetMesh->decrRef(); + // ------------- 3D + sourceMesh=MEDCouplingBasicsTest::build3DSourceMesh_1(); + targetMesh=MEDCouplingBasicsTest::build3DTargetMesh_1(); + CPPUNIT_ASSERT_EQUAL(1,remapper.prepare(sourceMesh,targetMesh,"P0P0")); + srcField=MEDCouplingFieldDouble::New(ON_CELLS); + srcField->setNature(ConservativeVolumic); + srcField->setMesh(sourceMesh); + array=DataArrayDouble::New(); + array->alloc(sourceMesh->getNumberOfCells(),1); + srcField->setArray(array); + ptr=array->getPointer(); + for(int i=0;i<sourceMesh->getNumberOfCells();i++) + ptr[i]=(double)(i+7); + array->decrRef(); + trgField=remapper.transferField(srcField,4.57); + CPPUNIT_ASSERT_EQUAL(8,trgField->getArray()->getNumberOfTuples()); + CPPUNIT_ASSERT_EQUAL(1,trgField->getArray()->getNumberOfComponents()); + const double valuesExpected3[8]={13.166666666666668, 13.888888888888888, 10.722222222222223, 10.870370370370372, + 14.555555555555555, 13.888888888888889, 14.444444444444443, 11.72222222222222}; + values=trgField->getArray()->getConstPointer(); + for(int i0=0;i0<8;i0++) + CPPUNIT_ASSERT_DOUBLES_EQUAL(valuesExpected3[i0],values[i0],1e-12); + trgField->decrRef(); + srcField->decrRef(); + sourceMesh->decrRef(); + targetMesh->decrRef(); + // ------------- 3D -> 1D + sourceMesh=MEDCouplingBasicsTest::build3DTargetMesh_1(); + targetMesh=MEDCouplingBasicsTest::build1DTargetMesh_1(); + remapper.setIntersectionType(INTERP_KERNEL::PointLocator); + CPPUNIT_ASSERT_EQUAL(1,remapper.prepare(sourceMesh,targetMesh,"P0P0")); + srcField=MEDCouplingFieldDouble::New(ON_CELLS); + srcField->setNature(ConservativeVolumic); + srcField->setMesh(sourceMesh); + array=DataArrayDouble::New(); + array->alloc(sourceMesh->getNumberOfCells(),1); + srcField->setArray(array); + ptr=array->getPointer(); + for(int i=0;i<sourceMesh->getNumberOfCells();i++) + ptr[i]=(double)(i+7); + array->decrRef(); + trgField=remapper.transferField(srcField,4.57); + CPPUNIT_ASSERT_EQUAL(8,trgField->getArray()->getNumberOfTuples()); + CPPUNIT_ASSERT_EQUAL(1,trgField->getArray()->getNumberOfComponents()); + const double valuesExpected4[8]={7.,11.,8.,12.,9.,13.,10.,14.}; + values=trgField->getArray()->getConstPointer(); + for(int i0=0;i0<8;i0++) + CPPUNIT_ASSERT_DOUBLES_EQUAL(valuesExpected4[i0],values[i0],1e-12); + trgField->decrRef(); + srcField->decrRef(); + sourceMesh->decrRef(); + targetMesh->decrRef(); + // ------------- 1D -> 3D + sourceMesh=MEDCouplingBasicsTest::build1DTargetMesh_1(); + targetMesh=MEDCouplingBasicsTest::build3DTargetMesh_1(); + remapper.setIntersectionType(INTERP_KERNEL::PointLocator); + CPPUNIT_ASSERT_EQUAL(1,remapper.prepare(sourceMesh,targetMesh,"P0P0")); + srcField=MEDCouplingFieldDouble::New(ON_CELLS); + srcField->setNature(ConservativeVolumic); + srcField->setMesh(sourceMesh); + array=DataArrayDouble::New(); + array->alloc(sourceMesh->getNumberOfCells(),1); + srcField->setArray(array); + ptr=array->getPointer(); + for(int i=0;i<sourceMesh->getNumberOfCells();i++) + ptr[i]=(double)(i+7); + array->decrRef(); + trgField=remapper.transferField(srcField,4.57); + CPPUNIT_ASSERT_EQUAL(8,trgField->getArray()->getNumberOfTuples()); + CPPUNIT_ASSERT_EQUAL(1,trgField->getArray()->getNumberOfComponents()); + const double valuesExpected5[8]={7.,9.,11.,13.,8.,10.,12.,14.}; + values=trgField->getArray()->getConstPointer(); + for(int i0=0;i0<8;i0++) + CPPUNIT_ASSERT_DOUBLES_EQUAL(valuesExpected5[i0],values[i0],1e-12); + trgField->decrRef(); + srcField->decrRef(); + sourceMesh->decrRef(); + targetMesh->decrRef(); + // ------------- 2D -> 1D + sourceMesh=MEDCouplingBasicsTest::build2DTargetMesh_1(); + targetMesh=build1DTargetMesh_2(); + remapper.setIntersectionType(INTERP_KERNEL::PointLocator); + CPPUNIT_ASSERT_EQUAL(1,remapper.prepare(sourceMesh,targetMesh,"P0P0")); + srcField=MEDCouplingFieldDouble::New(ON_CELLS); + srcField->setNature(ConservativeVolumic); + srcField->setMesh(sourceMesh); + array=DataArrayDouble::New(); + array->alloc(sourceMesh->getNumberOfCells(),1); + srcField->setArray(array); + ptr=array->getPointer(); + for(int i=0;i<sourceMesh->getNumberOfCells();i++) + ptr[i]=(double)(i+7); + array->decrRef(); + trgField=remapper.transferField(srcField,4.57); + const double valuesExpected8[5]={9.,8.,11.,7.,11.}; + values=trgField->getArray()->getConstPointer(); + for(int i0=0;i0<5;i0++) + CPPUNIT_ASSERT_DOUBLES_EQUAL(valuesExpected8[i0],values[i0],1e-12); + trgField->decrRef(); + srcField->decrRef(); + sourceMesh->decrRef(); + targetMesh->decrRef(); + // ------------- 1D -> 2D + sourceMesh=build1DTargetMesh_2(); + targetMesh=MEDCouplingBasicsTest::build2DTargetMesh_1(); + remapper.setIntersectionType(INTERP_KERNEL::PointLocator); + CPPUNIT_ASSERT_EQUAL(1,remapper.prepare(sourceMesh,targetMesh,"P0P0")); + srcField=MEDCouplingFieldDouble::New(ON_CELLS); + srcField->setNature(ConservativeVolumic); + srcField->setMesh(sourceMesh); + array=DataArrayDouble::New(); + array->alloc(sourceMesh->getNumberOfCells(),1); + srcField->setArray(array); + ptr=array->getPointer(); + for(int i=0;i<sourceMesh->getNumberOfCells();i++) + ptr[i]=(double)(i+7); + array->decrRef(); + trgField=remapper.transferField(srcField,4.57); + const double valuesExpected9[5]={10.,8.,7.,4.57,10.}; + values=trgField->getArray()->getConstPointer(); + for(int i0=0;i0<5;i0++) + CPPUNIT_ASSERT_DOUBLES_EQUAL(valuesExpected9[i0],values[i0],1e-12); + trgField->decrRef(); + srcField->decrRef(); + sourceMesh->decrRef(); + targetMesh->decrRef(); + // ------------- 2D -> -1D + sourceMesh=MEDCouplingBasicsTest::build2DTargetMesh_1(); + targetMesh=MEDCouplingUMesh::New("an example of -1 D mesh",-1); + srcField=MEDCouplingFieldDouble::New(ON_CELLS); + srcField->setNature(ConservativeVolumic); + srcField->setMesh(sourceMesh); + array=DataArrayDouble::New(); + array->alloc(sourceMesh->getNumberOfCells(),1); + srcField->setArray(array); + ptr=array->getPointer(); + for(int i=0;i<sourceMesh->getNumberOfCells();i++) + ptr[i]=(double)(i+7); + array->decrRef(); + CPPUNIT_ASSERT_EQUAL(1,remapper.prepare(sourceMesh,targetMesh,"P0P0")); + trgField=remapper.transferField(srcField,4.57); + values=trgField->getArray()->getConstPointer(); + CPPUNIT_ASSERT_EQUAL(1,trgField->getNumberOfTuples()); + CPPUNIT_ASSERT_EQUAL(1,trgField->getNumberOfComponents()); + CPPUNIT_ASSERT_DOUBLES_EQUAL(9.125,values[0],1e-14); + srcField->decrRef(); + srcField=remapper.reverseTransferField(trgField,4.220173); + CPPUNIT_ASSERT_EQUAL(5,srcField->getNumberOfTuples()); + CPPUNIT_ASSERT_EQUAL(1,srcField->getNumberOfComponents()); + values=srcField->getArray()->getConstPointer(); + for(int i0=0;i0<5;i0++) + CPPUNIT_ASSERT_DOUBLES_EQUAL(9.125,values[i0],1e-14); + srcField->decrRef(); + trgField->setNature(Integral); + srcField=remapper.reverseTransferField(trgField,4.220173); + CPPUNIT_ASSERT_EQUAL(5,srcField->getNumberOfTuples()); + CPPUNIT_ASSERT_EQUAL(1,srcField->getNumberOfComponents()); + values=srcField->getArray()->getConstPointer(); + const double valuesExpected6[5]={2.28125,1.140625,1.140625,2.28125,2.28125}; + for(int i0=0;i0<5;i0++) + CPPUNIT_ASSERT_DOUBLES_EQUAL(valuesExpected6[i0],values[i0],1e-14); + srcField->decrRef(); + trgField->decrRef(); + // ------------- -1D -> 2D + CPPUNIT_ASSERT_EQUAL(1,remapper.prepare(targetMesh,sourceMesh,"P0P0")); + trgField=MEDCouplingFieldDouble::New(ON_CELLS); + trgField->setNature(ConservativeVolumic); + trgField->setMesh(targetMesh); + array=DataArrayDouble::New(); + array->alloc(targetMesh->getNumberOfCells(),1); + trgField->setArray(array); + ptr=array->getPointer(); + ptr[0]=7.; + array->decrRef(); + srcField=remapper.transferField(trgField,4.221073); + values=srcField->getArray()->getConstPointer(); + for(int i0=0;i0<5;i0++) + CPPUNIT_ASSERT_DOUBLES_EQUAL(7.,values[i0],1e-14); + srcField->decrRef(); + trgField->setNature(IntegralGlobConstraint); + srcField=remapper.transferField(trgField,4.221073); + values=srcField->getArray()->getConstPointer(); + const double valuesExpected7[5]={1.75,0.875,0.875,1.75,1.75}; + for(int i0=0;i0<5;i0++) + CPPUNIT_ASSERT_DOUBLES_EQUAL(valuesExpected7[i0],values[i0],1e-14); + srcField->decrRef(); + trgField->setNature(Integral); + srcField=remapper.transferField(trgField,4.221073); + values=srcField->getArray()->getConstPointer(); + for(int i0=0;i0<5;i0++) + CPPUNIT_ASSERT_DOUBLES_EQUAL(valuesExpected7[i0],values[i0],1e-14); + srcField->decrRef(); + trgField->decrRef(); + sourceMesh->decrRef(); + targetMesh->decrRef(); + //------------- 1D -> 2D + const int conn[8]={0,1,1,2,2,3,3,0}; + const int conn2[12]={6,7,5,4,2,7,6,3,0,4,5,1}; + const double coords1[]={0.17,0.93,0.56,0.93,0.56,0.25,0.17,0.52}; + const double coords2[]={0.,0.,1.,0.,1.,1.,0.,1.,0.,0.5,1.,0.5,0.,0.8,1.,0.8}; + sourceMesh=MEDCouplingUMesh::New("src1D",1); + sourceMesh->allocateCells(4); + sourceMesh->insertNextCell(INTERP_KERNEL::NORM_SEG2,2,conn); + sourceMesh->insertNextCell(INTERP_KERNEL::NORM_SEG2,2,conn+2); + sourceMesh->insertNextCell(INTERP_KERNEL::NORM_SEG2,2,conn+4); + sourceMesh->insertNextCell(INTERP_KERNEL::NORM_SEG2,2,conn+6); + sourceMesh->finishInsertingCells(); + array=DataArrayDouble::New(); array->alloc(4,2); + std::copy(coords1,coords1+8,array->getPointer()); + sourceMesh->setCoords(array); array->decrRef(); + targetMesh=MEDCouplingUMesh::New("trg2D",2); + targetMesh->allocateCells(3); + targetMesh->insertNextCell(INTERP_KERNEL::NORM_QUAD4,4,conn2); + targetMesh->insertNextCell(INTERP_KERNEL::NORM_QUAD4,4,conn2+4); + targetMesh->insertNextCell(INTERP_KERNEL::NORM_QUAD4,4,conn2+8); + targetMesh->finishInsertingCells(); + array=DataArrayDouble::New(); array->alloc(8,2); + std::copy(coords2,coords2+16,array->getPointer()); + targetMesh->setCoords(array); array->decrRef(); + remapper.setPrecision(1e-12); + remapper.setIntersectionType(INTERP_KERNEL::Geometric2D); + CPPUNIT_ASSERT_EQUAL(1,remapper.prepare(sourceMesh,targetMesh,"P0P0")); + srcField=MEDCouplingFieldDouble::New(ON_CELLS); + srcField->setNature(ConservativeVolumic); + srcField->setMesh(sourceMesh); + array=DataArrayDouble::New(); + array->alloc(4,1); array->iota(2.); + srcField->setArray(array); array->decrRef(); + trgField=remapper.transferField(srcField,4.57); + const double valuesExpected10[3]={3.9674868868103834, 2.8, 3.6372633449255796}; + CPPUNIT_ASSERT_EQUAL(3,trgField->getNumberOfTuples()); + CPPUNIT_ASSERT_EQUAL(1,trgField->getNumberOfComponents()); + for(int i=0;i<3;i++) + CPPUNIT_ASSERT_DOUBLES_EQUAL(valuesExpected10[i],trgField->getIJ(i,0),1e-13); + srcField->decrRef(); + trgField->decrRef(); + //------------- 2D -> 1D + remapper.setPrecision(1e-12); + remapper.setIntersectionType(INTERP_KERNEL::Geometric2D); + CPPUNIT_ASSERT_EQUAL(1,remapper.prepare(targetMesh,sourceMesh,"P0P0")); + srcField=MEDCouplingFieldDouble::New(ON_CELLS); + srcField->setNature(ConservativeVolumic); + srcField->setMesh(targetMesh); + array=DataArrayDouble::New(); + array->alloc(3,1); array->iota(2.); + srcField->setArray(array); array->decrRef(); + trgField=remapper.transferField(srcField,4.57); + const double valuesExpected11[4]={3., 2.9264705882352944, 3.8518518518518516, 2.3170731707317076}; + CPPUNIT_ASSERT_EQUAL(4,trgField->getNumberOfTuples()); + CPPUNIT_ASSERT_EQUAL(1,trgField->getNumberOfComponents()); + for(int i=0;i<4;i++) + CPPUNIT_ASSERT_DOUBLES_EQUAL(valuesExpected11[i],trgField->getIJ(i,0),1e-13); + srcField->decrRef(); + trgField->decrRef(); + sourceMesh->decrRef(); + targetMesh->decrRef(); + //------------- 2D -> 3D + sourceMesh=MEDCouplingBasicsTest::build3D2DSourceMesh(); + targetMesh=MEDCouplingBasicsTest::build3D2DTargetMesh(); + remapper.setIntersectionType(INTERP_KERNEL::Triangulation); + CPPUNIT_ASSERT_EQUAL(1,remapper.prepare(sourceMesh,targetMesh,"P0P0")); + srcField=MEDCouplingFieldDouble::New(ON_CELLS); + srcField->setNature(ConservativeVolumic); + srcField->setMesh(sourceMesh); + array=DataArrayDouble::New(); + array->alloc(7,1); array->iota(2.); + srcField->setArray(array); array->decrRef(); + trgField=remapper.transferField(srcField,4.57); + const double valuesExpected12[3]={5.70909090909091, 6.08362715128042, 6.92857142857143}; + CPPUNIT_ASSERT_EQUAL(3,trgField->getNumberOfTuples()); + CPPUNIT_ASSERT_EQUAL(1,trgField->getNumberOfComponents()); + for(int i=0;i<3;i++) + CPPUNIT_ASSERT_DOUBLES_EQUAL(valuesExpected12[i],trgField->getIJ(i,0),1e-13); + srcField->decrRef(); + trgField->decrRef(); + //------------- 3D -> 2D + CPPUNIT_ASSERT_EQUAL(1,remapper.prepare(targetMesh,sourceMesh,"P0P0")); + srcField=MEDCouplingFieldDouble::New(ON_CELLS); + srcField->setNature(ConservativeVolumic); + srcField->setMesh(targetMesh); + array=DataArrayDouble::New(); + array->alloc(3,1); array->iota(2.); + srcField->setArray(array); array->decrRef(); + trgField=remapper.transferField(srcField,4.57); + const double valuesExpected13[7]={3., 4., 2.5, 2.909090909090909, 2., 3.5, 3.3571428571428572}; + CPPUNIT_ASSERT_EQUAL(7,trgField->getNumberOfTuples()); + CPPUNIT_ASSERT_EQUAL(1,trgField->getNumberOfComponents()); + for(int i=0;i<7;i++) + CPPUNIT_ASSERT_DOUBLES_EQUAL(valuesExpected13[i],trgField->getIJ(i,0),1e-13); + srcField->decrRef(); + trgField->decrRef(); + sourceMesh->decrRef(); + targetMesh->decrRef(); +} + +void MEDCouplingRemapperTest::testNatureOfField() +{ + MEDCouplingUMesh *sourceMesh=MEDCouplingBasicsTest::build2DSourceMesh_1(); + MEDCouplingUMesh *targetMesh=build2DTargetMesh_3(); + // + MEDCouplingRemapper remapper; + remapper.setPrecision(1e-12); + remapper.setIntersectionType(INTERP_KERNEL::Triangulation); + CPPUNIT_ASSERT_EQUAL(1,remapper.prepare(sourceMesh,targetMesh,"P0P0")); + MEDCouplingFieldDouble *srcField=MEDCouplingFieldDouble::New(ON_CELLS); + srcField->setNature(ConservativeVolumic); + srcField->setMesh(sourceMesh); + DataArrayDouble *array=DataArrayDouble::New(); + array->alloc(sourceMesh->getNumberOfCells(),1); + srcField->setArray(array); + double *ptr=array->getPointer(); + for(int i=0;i<sourceMesh->getNumberOfCells();i++) + ptr[i]=(double)(i+7); + array->decrRef(); + MEDCouplingFieldDouble *trgfield=remapper.transferField(srcField,4.220173); + const double *values=trgfield->getArray()->getConstPointer(); + const double valuesExpected[4]={7.75, 7.0625, 4.220173,8.0}; + CPPUNIT_ASSERT_EQUAL(4,trgfield->getArray()->getNumberOfTuples()); + CPPUNIT_ASSERT_EQUAL(1,trgfield->getArray()->getNumberOfComponents()); + for(int i0=0;i0<4;i0++) + CPPUNIT_ASSERT_DOUBLES_EQUAL(valuesExpected[i0],values[i0],1e-12); + trgfield->decrRef(); + // + srcField->setNature(IntegralGlobConstraint); + trgfield=remapper.transferField(srcField,4.220173); + values=trgfield->getArray()->getConstPointer(); + const double valuesExpected2[4]={2.8374999999999999, 7.3624999999999998, 4.220173, 4.7999999999999998}; + CPPUNIT_ASSERT_EQUAL(4,trgfield->getArray()->getNumberOfTuples()); + CPPUNIT_ASSERT_EQUAL(1,trgfield->getArray()->getNumberOfComponents()); + for(int i0=0;i0<4;i0++) + CPPUNIT_ASSERT_DOUBLES_EQUAL(valuesExpected2[i0],values[i0],1e-12); + trgfield->decrRef(); + // + srcField->setNature(Integral); + trgfield=remapper.transferField(srcField,4.220173); + values=trgfield->getArray()->getConstPointer(); + const double valuesExpected3[4]={1.24, 4.5199999999999996, 4.220173, 1.9199999999999999}; + CPPUNIT_ASSERT_EQUAL(4,trgfield->getArray()->getNumberOfTuples()); + CPPUNIT_ASSERT_EQUAL(1,trgfield->getArray()->getNumberOfComponents()); + for(int i0=0;i0<4;i0++) + CPPUNIT_ASSERT_DOUBLES_EQUAL(valuesExpected3[i0],values[i0],1e-12); + trgfield->decrRef(); + // + srcField->setNature(RevIntegral); + trgfield=remapper.transferField(srcField,4.220173); + values=trgfield->getArray()->getConstPointer(); + const double valuesExpected9[4]={2.48, 3.766666666666666, 4.220173, 1.9199999999999999}; + CPPUNIT_ASSERT_EQUAL(4,trgfield->getArray()->getNumberOfTuples()); + CPPUNIT_ASSERT_EQUAL(1,trgfield->getArray()->getNumberOfComponents()); + for(int i0=0;i0<4;i0++) + CPPUNIT_ASSERT_DOUBLES_EQUAL(valuesExpected9[i0],values[i0],1e-12); + trgfield->decrRef(); + // + srcField->decrRef(); + // REVERSE *********** + trgfield=MEDCouplingFieldDouble::New(ON_CELLS); + trgfield->setNature(ConservativeVolumic); + trgfield->setMesh(targetMesh); + array=DataArrayDouble::New(); + array->alloc(targetMesh->getNumberOfCells(),1); + trgfield->setArray(array); + ptr=array->getPointer(); + for(int i=0;i<targetMesh->getNumberOfCells();i++) + ptr[i]=(double)(i+7); + array->decrRef(); + srcField=remapper.reverseTransferField(trgfield,4.220173); + values=srcField->getArray()->getConstPointer(); + const double valuesExpected4[2]={7.9375, 8.9}; + CPPUNIT_ASSERT_EQUAL(2,srcField->getArray()->getNumberOfTuples()); + CPPUNIT_ASSERT_EQUAL(1,srcField->getArray()->getNumberOfComponents()); + for(int i0=0;i0<2;i0++) + CPPUNIT_ASSERT_DOUBLES_EQUAL(valuesExpected4[i0],values[i0],1e-12); + srcField->decrRef(); + // + trgfield->decrRef(); + // + sourceMesh->decrRef(); + targetMesh->decrRef(); + // REVERSE ALL + sourceMesh=build2DTargetMesh_3(); + targetMesh=MEDCouplingBasicsTest::build2DSourceMesh_1(); + // + CPPUNIT_ASSERT_EQUAL(1,remapper.prepare(sourceMesh,targetMesh,"P0P0")); + srcField=MEDCouplingFieldDouble::New(ON_CELLS); + srcField->setNature(ConservativeVolumic); + srcField->setMesh(sourceMesh); + array=DataArrayDouble::New(); + array->alloc(sourceMesh->getNumberOfCells(),1); + srcField->setArray(array); + ptr=array->getPointer(); + for(int i=0;i<sourceMesh->getNumberOfCells();i++) + ptr[i]=(double)(i+7); + array->decrRef(); + trgfield=remapper.transferField(srcField,4.220173); + values=trgfield->getArray()->getConstPointer(); + const double valuesExpected5[2]={7.9375, 8.9}; + CPPUNIT_ASSERT_EQUAL(2,trgfield->getArray()->getNumberOfTuples()); + CPPUNIT_ASSERT_EQUAL(1,trgfield->getArray()->getNumberOfComponents()); + for(int i0=0;i0<2;i0++) + CPPUNIT_ASSERT_DOUBLES_EQUAL(valuesExpected5[i0],values[i0],1e-12); + trgfield->decrRef(); + // + srcField->setNature(IntegralGlobConstraint); + trgfield=remapper.transferField(srcField,4.220173); + values=trgfield->getArray()->getConstPointer(); + const double valuesExpected6[4]={9.25, 15.75}; + CPPUNIT_ASSERT_EQUAL(2,trgfield->getArray()->getNumberOfTuples()); + CPPUNIT_ASSERT_EQUAL(1,trgfield->getArray()->getNumberOfComponents()); + for(int i0=0;i0<2;i0++) + CPPUNIT_ASSERT_DOUBLES_EQUAL(valuesExpected6[i0],values[i0],1e-12); + trgfield->decrRef(); + // + srcField->setNature(Integral); + trgfield=remapper.transferField(srcField,4.220173); + values=trgfield->getArray()->getConstPointer(); + const double valuesExpected7[2]={4.56, 4.3466666666666667}; + CPPUNIT_ASSERT_EQUAL(2,trgfield->getArray()->getNumberOfTuples()); + CPPUNIT_ASSERT_EQUAL(1,trgfield->getArray()->getNumberOfComponents()); + for(int i0=0;i0<2;i0++) + CPPUNIT_ASSERT_DOUBLES_EQUAL(valuesExpected7[i0],values[i0],1e-12); + trgfield->decrRef(); + // + srcField->setNature(RevIntegral); + trgfield=remapper.transferField(srcField,4.220173); + values=trgfield->getArray()->getConstPointer(); + const double valuesExpected10[2]={5.08, 3.56}; + CPPUNIT_ASSERT_EQUAL(2,trgfield->getArray()->getNumberOfTuples()); + CPPUNIT_ASSERT_EQUAL(1,trgfield->getArray()->getNumberOfComponents()); + for(int i0=0;i0<2;i0++) + CPPUNIT_ASSERT_DOUBLES_EQUAL(valuesExpected10[i0],values[i0],1e-12); + trgfield->decrRef(); + // + srcField->decrRef(); + // REVERSE *********** + trgfield=MEDCouplingFieldDouble::New(ON_CELLS); + trgfield->setNature(ConservativeVolumic); + trgfield->setMesh(targetMesh); + array=DataArrayDouble::New(); + array->alloc(targetMesh->getNumberOfCells(),1); + trgfield->setArray(array); + ptr=array->getPointer(); + for(int i=0;i<targetMesh->getNumberOfCells();i++) + ptr[i]=(double)(i+7); + array->decrRef(); + srcField=remapper.reverseTransferField(trgfield,4.220173); + values=srcField->getArray()->getConstPointer(); + const double valuesExpected8[4]={7.75, 7.0625,4.220173, 8.0}; + CPPUNIT_ASSERT_EQUAL(4,srcField->getArray()->getNumberOfTuples()); + CPPUNIT_ASSERT_EQUAL(1,srcField->getArray()->getNumberOfComponents()); + for(int i0=0;i0<4;i0++) + CPPUNIT_ASSERT_DOUBLES_EQUAL(valuesExpected8[i0],values[i0],1e-12); + srcField->decrRef(); + // + trgfield->decrRef(); + // + sourceMesh->decrRef(); + targetMesh->decrRef(); +} + +void MEDCouplingRemapperTest::testExtruded() +{ + MEDCouplingUMesh *mesh2DS=0; + MEDCouplingUMesh *mesh3DS=build3DExtrudedUMesh_1(mesh2DS); + MEDCouplingExtrudedMesh *extS=MEDCouplingExtrudedMesh::New(mesh3DS,mesh2DS,1); + mesh3DS->decrRef(); + mesh2DS->decrRef(); + MEDCouplingUMesh *mesh2DT=0; + MEDCouplingUMesh *mesh3DT=build3DExtrudedUMesh_1(mesh2DT); + MEDCouplingExtrudedMesh *extT=MEDCouplingExtrudedMesh::New(mesh3DT,mesh2DT,1); + // + // + mesh3DT->decrRef(); + mesh2DT->decrRef(); + // + extS->decrRef(); + extT->decrRef(); +} + +void MEDCouplingRemapperTest::testExtruded2() +{ + MEDCouplingUMesh *meshN,*meshTT,*meshTF; + MEDCouplingBasicsTest::build3DExtrudedUMesh_2(meshN,meshTT,meshTF); + std::vector<int> n; + double pt[3]={300.,300.,0.}; + double v[3]={0.,0.,2.}; + meshN->findNodesOnPlane(pt,v,1e-12,n); + MEDCouplingUMesh *meshN2D=(MEDCouplingUMesh *)meshN->buildFacePartOfMySelfNode(&n[0],&n[0]+n.size(),true); + n.clear(); + bool b=false; + int newNbOfNodes; + DataArrayInt *da=meshTT->mergeNodes(1e-12,b,newNbOfNodes); + CPPUNIT_ASSERT(b); + da->decrRef(); + meshTT->findNodesOnPlane(pt,v,1e-12,n); + MEDCouplingUMesh *meshTT2D=(MEDCouplingUMesh *)meshTT->buildFacePartOfMySelfNode(&n[0],&n[0]+n.size(),true); + n.clear(); + meshTF->findNodesOnPlane(pt,v,1e-12,n); + MEDCouplingUMesh *meshTF2D=(MEDCouplingUMesh *)meshTF->buildFacePartOfMySelfNode(&n[0],&n[0]+n.size(),true); + n.clear(); + // + MEDCouplingExtrudedMesh *meshNE=MEDCouplingExtrudedMesh::New(meshN,meshN2D,0); + MEDCouplingExtrudedMesh *meshTTE=MEDCouplingExtrudedMesh::New(meshTT,meshTT2D,0); + MEDCouplingExtrudedMesh *meshTFE=MEDCouplingExtrudedMesh::New(meshTF,meshTF2D,0); + // + MEDCouplingRemapper remapper; + remapper.setPrecision(1e-12); + remapper.setIntersectionType(INTERP_KERNEL::Triangulation); + CPPUNIT_ASSERT_EQUAL(1,remapper.prepare(meshNE,meshTTE,"P0P0")); + MEDCouplingFieldDouble *srcField=MEDCouplingFieldDouble::New(ON_CELLS); + srcField->setNature(IntegralGlobConstraint); + srcField->setMesh(meshNE); + DataArrayDouble *array=DataArrayDouble::New(); + array->alloc(meshNE->getNumberOfCells(),1); + srcField->setArray(array); + double vals1[40]={ + 1000.,1000.,1020.,1030.,1040.,1000.,1000.,1070.,1080.,1090.,1000.,1000.,1120.,1130.,1140.,1000.,1000.,1170.,1180.,1190., + 2000.,2000.,2020.,2030.,2040.,2000.,2000.,2070.,2080.,2090.,2000.,2000.,2120.,2130.,2140.,2000.,2000.,2170.,2180.,2190., + }; + CPPUNIT_ASSERT_EQUAL((int)(sizeof(vals1)/sizeof(double)),meshNE->getNumberOfCells()); + std::copy(vals1,vals1+meshNE->getNumberOfCells(),array->getPointer()); + array->decrRef(); + MEDCouplingFieldDouble *trgField=remapper.transferField(srcField,4.220173); + double expected1[200]={ + 800.,800.,800.,800.,800.,800.,800.,800.,800.,800.,1600.,1600.,1600.,1600.,1600.,1600.,1600.,1600.,1600.,1600., + 102.,102.,102.,102.,102.,102.,102.,102.,102.,102.,202.,202.,202.,202.,202.,202.,202.,202.,202.,202., + 103.,103.,103.,103.,103.,103.,103.,103.,103.,103.,203.,203.,203.,203.,203.,203.,203.,203.,203.,203., + 104.,104.,104.,104.,104.,104.,104.,104.,104.,104.,204.,204.,204.,204.,204.,204.,204.,204.,204.,204., + 219.,219.,219.,219.,219.,219.,219.,219.,219.,219.,419.,419.,419.,419.,419.,419.,419.,419.,419.,419., + 221.,221.,221.,221.,221.,221.,221.,221.,221.,221.,421.,421.,421.,421.,421.,421.,421.,421.,421.,421., + 223.,223.,223.,223.,223.,223.,223.,223.,223.,223.,423.,423.,423.,423.,423.,423.,423.,423.,423.,423., + 117.,117.,117.,117.,117.,117.,117.,117.,117.,117.,217.,217.,217.,217.,217.,217.,217.,217.,217.,217., + 118.,118.,118.,118.,118.,118.,118.,118.,118.,118.,218.,218.,218.,218.,218.,218.,218.,218.,218.,218., + 119.,119.,119.,119.,119.,119.,119.,119.,119.,119.,219.,219.,219.,219.,219.,219.,219.,219.,219.,219. + }; + for(int i=0;i<200;i++) + CPPUNIT_ASSERT_DOUBLES_EQUAL(expected1[i],trgField->getArray()->getConstPointer()[i],1e-3);//1e-3 precision due to non coincidence in 1D mesh + CPPUNIT_ASSERT_DOUBLES_EQUAL(std::accumulate(expected1,expected1+200,0.),std::accumulate(vals1,vals1+40,0.),1e-10); + CPPUNIT_ASSERT_DOUBLES_EQUAL(std::accumulate(expected1,expected1+200,0.),std::accumulate(trgField->getArray()->getConstPointer(),trgField->getArray()->getConstPointer()+200,0.),1e-10); + trgField->decrRef(); + // + CPPUNIT_ASSERT_EQUAL(1,remapper.prepare(meshNE,meshTFE,"P0P0")); + trgField=remapper.transferField(srcField,4.220173); + double expected2[340]={25.5, 51.25, 51.75, 26., 79., 158.75, 160.25, 80.5, 85.25, 171.25, 172.75, 86.75, 29.25, 58.75, 59.25, 29.75, 25.5, 51.25, 51.75, 26., 79., 158.75, + 160.25, 80.5, 85.25, 171.25, 172.75, 86.75, 29.25, 58.75, 59.25, 29.75, 25.5, 51.25, 51.75, 26., 79., 158.75, 160.25, 80.5, 85.25, 171.25, 172.75, 86.75, + 29.25, 58.75, 59.25, 29.75, 25.5, 51.25, 51.75, 26., 79., 158.75, 160.25, 80.5, 85.25, 171.25, 172.75, 86.75, 29.25, 58.75, 59.25, 29.75, 25.5, 51.25, 51.75, + 26., 79., 158.75, 160.25, 80.5, 85.25, 171.25, 172.75, 86.75, 29.25, 58.75, 59.25, 29.75, 25.5, 51.25, 51.75, 26., 79., 158.75, 160.25, 80.5, 85.25, 171.25, + 172.75, 86.75, 29.25, 58.75, 59.25, 29.75, 25.5, 51.25, 51.75, 26., 79., 158.75, 160.25, 80.5, 85.25, 171.25, 172.75, 86.75, 29.25, 58.75, 59.25, 29.75, 25.5, + 51.25, 51.75, 26., 79., 158.75, 160.25, 80.5, 85.25, 171.25, 172.75, 86.75, 29.25, 58.75, 59.25, 29.75, 25.5, 51.25, 51.75, 26., 79., 158.75, 160.25, 80.5, + 85.25, 171.25, 172.75, 86.75, 29.25, 58.75, 59.25, 29.75, 25.5, 51.25, 51.75, 26., 79., 158.75, 160.25, 80.5, 85.25, 171.25, 172.75, 86.75, 29.25, 58.75, 59.25, + 29.75, 50.5, 101.25, 101.75, 51., 154., 308.75, 310.25, 155.5, 160.25, 321.25, 322.75, 161.75, 54.25, 108.75, 109.25, 54.75, 50.5, 101.25, 101.75, 51., 154., + 308.75, 310.25, 155.5, 160.25, 321.25, 322.75, 161.75, 54.25, 108.75, 109.25, 54.75, 50.5, 101.25, 101.75, 51., 154., 308.75, 310.25, 155.5, 160.25, 321.25, 322.75, + 161.75, 54.25, 108.75, 109.25, 54.75, 50.5, 101.25, 101.75, 51., 154., 308.75, 310.25, 155.5, 160.25, 321.25, 322.75, 161.75, 54.25, 108.75, 109.25, 54.75, 50.5, + 101.25, 101.75, 51., 154., 308.75, 310.25, 155.5, 160.25, 321.25, 322.75, 161.75, 54.25, 108.75, 109.25, 54.75, 50.5, 101.25, 101.75, 51., 154., 308.75, 310.25, + 155.5, 160.25, 321.25, 322.75, 161.75, 54.25, 108.75, 109.25, 54.75, 50.5, 101.25, 101.75, 51., 154., 308.75, 310.25, 155.5, 160.25, 321.25, 322.75, 161.75, 54.25, + 108.75, 109.25, 54.75, 50.5, 101.25, 101.75, 51., 154., 308.75, 310.25, 155.5, 160.25, 321.25, 322.75, 161.75, 54.25, 108.75, 109.25, 54.75, 50.5, 101.25, 101.75, + 51., 154., 308.75, 310.25, 155.5, 160.25, 321.25, 322.75, 161.75, 54.25, 108.75, 109.25, 54.75, 50.5, 101.25, 101.75, 51., 154., 308.75, 310.25, 155.5, 160.25, 321.25, + 322.75, 161.75, 54.25, 108.75, 109.25, 54.75, 800., 800., 800., 800., 800., 800., 800., 800., 800., 800., 1600., 1600., 1600., 1600., 1600., 1600., 1600., + 1600., 1600., 1600.}; + for(int i=0;i<340;i++) + CPPUNIT_ASSERT_DOUBLES_EQUAL(expected2[i],trgField->getArray()->getConstPointer()[i],1e-3);//1e-3 precision due to non coincidence in 1D mesh + CPPUNIT_ASSERT_DOUBLES_EQUAL(std::accumulate(expected2,expected2+340,0.),std::accumulate(vals1,vals1+40,0.),1e-10); + CPPUNIT_ASSERT_DOUBLES_EQUAL(std::accumulate(expected2,expected2+340,0.),std::accumulate(trgField->getArray()->getConstPointer(),trgField->getArray()->getConstPointer()+340,0.),1e-10); + trgField->decrRef(); + srcField->decrRef(); + // + double vals2[200]={ + 100., 200., 300., 400., 500., 600., 700., 800., 900., 1000., 1100., 1200., 1300., 1400., 1500., 1600., 1700., 1800., 1900., 2000, + 101., 201., 301., 401., 501., 601., 701., 801., 901., 1001., 1101., 1201., 1301., 1401., 1501., 1601., 1701., 1801., 1901., 2001, + 102., 202., 302., 402., 502., 602., 702., 802., 902., 1002., 1102., 1202., 1302., 1402., 1502., 1602., 1702., 1802., 1902., 2002, + 103., 203., 303., 403., 503., 603., 703., 803., 903., 1003., 1103., 1203., 1303., 1403., 1503., 1603., 1703., 1803., 1903., 2003, + 104., 204., 304., 404., 504., 604., 704., 804., 904., 1004., 1104., 1204., 1304., 1404., 1504., 1604., 1704., 1804., 1904., 2004, + 105., 205., 305., 405., 505., 605., 705., 805., 905., 1005., 1105., 1205., 1305., 1405., 1505., 1605., 1705., 1805., 1905., 2005, + 106., 206., 306., 406., 506., 606., 706., 806., 906., 1006., 1106., 1206., 1306., 1406., 1506., 1606., 1706., 1806., 1906., 2006, + 107., 207., 307., 407., 507., 607., 707., 807., 907., 1007., 1107., 1207., 1307., 1407., 1507., 1607., 1707., 1807., 1907., 2007, + 108., 208., 308., 408., 508., 608., 708., 808., 908., 1008., 1108., 1208., 1308., 1408., 1508., 1608., 1708., 1808., 1908., 2008, + 109., 209., 309., 409., 509., 609., 709., 809., 909., 1009., 1109., 1209., 1309., 1409., 1509., 1609., 1709., 1809., 1909., 2009. + }; + CPPUNIT_ASSERT_EQUAL(1,remapper.prepare(meshNE,meshTTE,"P0P0")); + trgField=MEDCouplingFieldDouble::New(ON_CELLS); + trgField->setNature(ConservativeVolumic); + trgField->setMesh(meshTTE); + array=DataArrayDouble::New(); + array->alloc(meshTTE->getNumberOfCells(),1); + trgField->setArray(array); + std::copy(vals2,vals2+meshTTE->getNumberOfCells(),array->getPointer()); + array->decrRef(); + srcField=remapper.reverseTransferField(trgField,4.220173); + double expected3[40]={ + 550.,550.,551.,552.,553.,550.,550.,554.,555.,556.,550.,550.,554.,555.,556.,550.,550.,557.,558.,559., + 1550.,1550.,1551.,1552.,1553.,1550.,1550.,1554.,1555.,1556.,1550.,1550.,1554.,1555.,1556.,1550.,1550.,1557.,1558.,1559. + }; + for(int i=0;i<40;i++) + CPPUNIT_ASSERT_DOUBLES_EQUAL(expected3[i],srcField->getArray()->getConstPointer()[i],1e-3);//1e-3 precision due to non coincidence in 1D mesh + srcField->decrRef(); + trgField->decrRef(); + // + double vals3[340]={ + 100., 101., 102., 103., 104., 105., 106., 107., 108., 109., 110., 111., 112., 113., 114., 115., + 200., 201., 202., 203., 204., 205., 206., 207., 208., 209., 210., 211., 212., 213., 214., 215., + 300., 301., 302., 303., 304., 305., 306., 307., 308., 309., 310., 311., 312., 313., 314., 315., + 400., 401., 402., 403., 404., 405., 406., 407., 408., 409., 410., 411., 412., 413., 414., 415., + 500., 501., 502., 503., 504., 505., 506., 507., 508., 509., 510., 511., 512., 513., 514., 515., + 600., 601., 602., 603., 604., 605., 606., 607., 608., 609., 610., 611., 612., 613., 614., 615., + 700., 701., 702., 703., 704., 705., 706., 707., 708., 709., 710., 711., 712., 713., 714., 715., + 800., 801., 802., 803., 804., 805., 806., 807., 808., 809., 810., 811., 812., 813., 814., 815., + 900., 901., 902., 903., 904., 905., 906., 907., 908., 909., 910., 911., 912., 913., 914., 915., + 1000., 1001., 1002., 1003., 1004., 1005., 1006., 1007., 1008., 1009., 1010., 1011., 1012., 1013., 1014., 1015., + 1100., 1101., 1102., 1103., 1104., 1105., 1106., 1107., 1108., 1109., 1110., 1111., 1112., 1113., 1114., 1115., + 1200., 1201., 1202., 1203., 1204., 1205., 1206., 1207., 1208., 1209., 1210., 1211., 1212., 1213., 1214., 1215., + 1300., 1301., 1302., 1303., 1304., 1305., 1306., 1307., 1308., 1309., 1310., 1311., 1312., 1313., 1314., 1315., + 1400., 1401., 1402., 1403., 1404., 1405., 1406., 1407., 1408., 1409., 1410., 1411., 1412., 1413., 1414., 1415., + 1500., 1501., 1502., 1503., 1504., 1505., 1506., 1507., 1508., 1509., 1510., 1511., 1512., 1513., 1514., 1515., + 1600., 1601., 1602., 1603., 1604., 1605., 1606., 1607., 1608., 1609., 1610., 1611., 1612., 1613., 1614., 1615., + 1700., 1701., 1702., 1703., 1704., 1705., 1706., 1707., 1708., 1709., 1710., 1711., 1712., 1713., 1714., 1715., + 1800., 1801., 1802., 1803., 1804., 1805., 1806., 1807., 1808., 1809., 1810., 1811., 1812., 1813., 1814., 1815., + 1900., 1901., 1902., 1903., 1904., 1905., 1906., 1907., 1908., 1909., 1910., 1911., 1912., 1913., 1914., 1915., + 2000., 2001., 2002., 2003., 2004., 2005., 2006., 2007., 2008., 2009., 2010., 2011., 2012., 2013., 2014., 2015., + 116.,216.,316.,416.,516.,616.,716.,816.,916.,1016.,1116.,1216.,1316.,1416.,1516.,1616.,1716.,1816.,1916.,2016. + }; + CPPUNIT_ASSERT_EQUAL(1,remapper.prepare(meshNE,meshTFE,"P0P0")); + trgField=MEDCouplingFieldDouble::New(ON_CELLS); + trgField->setNature(ConservativeVolumic); + trgField->setMesh(meshTFE); + array=DataArrayDouble::New(); + array->alloc(meshTFE->getNumberOfCells(),1); + trgField->setArray(array); + std::copy(vals3,vals3+meshTFE->getNumberOfCells(),array->getPointer()); + array->decrRef(); + srcField=remapper.reverseTransferField(trgField,4.220173); + double expected4[40]={ + 566.,566.,552.5,553.5,554.5,566.,566.,554.5,555.5,556.5,566.,566.,558.5,559.5,560.5,566.,566.,560.5,561.5,562.5, + 1566.,1566.,1552.5,1553.5,1554.5,1566.,1566.,1554.5,1555.5,1556.5,1566.,1566.,1558.5,1559.5,1560.5,1566.,1566.,1560.5,1561.5,1562.5 + }; + for(int i=0;i<40;i++) + CPPUNIT_ASSERT_DOUBLES_EQUAL(expected4[i],srcField->getArray()->getConstPointer()[i],1e-3);//1e-3 precision due to non coincidence in 1D mesh + srcField->decrRef(); + trgField->decrRef(); + // + meshN2D->decrRef(); + meshTT2D->decrRef(); + meshTF2D->decrRef(); + meshNE->decrRef(); + meshTTE->decrRef(); + meshTFE->decrRef(); + meshN->decrRef(); + meshTT->decrRef(); + meshTF->decrRef(); +} + +void MEDCouplingRemapperTest::testPrepareEx1() +{ + MEDCouplingUMesh *sourceMesh=MEDCouplingBasicsTest::build2DSourceMesh_1(); + MEDCouplingUMesh *targetMesh=build2DTargetMesh_3(); + // + MEDCouplingRemapper remapper; + remapper.setPrecision(1e-12); + remapper.setIntersectionType(INTERP_KERNEL::Triangulation); + MEDCouplingFieldTemplate *srcFt=MEDCouplingFieldTemplate::New(ON_CELLS); + MEDCouplingFieldTemplate *trgFt=MEDCouplingFieldTemplate::New(ON_CELLS); + srcFt->setMesh(sourceMesh); + trgFt->setMesh(targetMesh); + CPPUNIT_ASSERT_EQUAL(1,remapper.prepareEx(srcFt,trgFt)); + srcFt->decrRef(); + trgFt->decrRef(); + MEDCouplingFieldDouble *srcField=MEDCouplingFieldDouble::New(ON_CELLS); + srcField->setNature(ConservativeVolumic); + srcField->setMesh(sourceMesh); + DataArrayDouble *array=DataArrayDouble::New(); + array->alloc(sourceMesh->getNumberOfCells(),1); + srcField->setArray(array); + double *ptr=array->getPointer(); + for(int i=0;i<sourceMesh->getNumberOfCells();i++) + ptr[i]=(double)(i+7); + array->decrRef(); + MEDCouplingFieldDouble *trgfield=remapper.transferField(srcField,4.220173); + const double *values=trgfield->getArray()->getConstPointer(); + const double valuesExpected[4]={7.75, 7.0625, 4.220173,8.0}; + CPPUNIT_ASSERT_EQUAL(4,trgfield->getArray()->getNumberOfTuples()); + CPPUNIT_ASSERT_EQUAL(1,trgfield->getArray()->getNumberOfComponents()); + for(int i0=0;i0<4;i0++) + CPPUNIT_ASSERT_DOUBLES_EQUAL(valuesExpected[i0],values[i0],1e-12); + trgfield->decrRef(); + srcField->decrRef(); + sourceMesh->decrRef(); + targetMesh->decrRef(); +} + +MEDCouplingUMesh *MEDCouplingRemapperTest::build1DTargetMesh_2() +{ + double targetCoords[20]={ + 0.59,0.09, 0.69,0.19, 0.21,-0.29,0.31,-0.19, 0.45,0.25,0.65,0.45, + -0.2,-0.2,0.11,0.11, 0.25,0.25, 0.45,0.45 + }; + int targetConn[10]={0,1, 2,3, 4,5, 6,7, 8,9}; + + MEDCouplingUMesh *targetMesh=MEDCouplingUMesh::New("my name of mesh 1D 2",1); + targetMesh->allocateCells(5); + for(int i=0;i<5;i++) + targetMesh->insertNextCell(INTERP_KERNEL::NORM_SEG2,2,targetConn+2*i); + targetMesh->finishInsertingCells(); + DataArrayDouble *myCoords=DataArrayDouble::New(); + myCoords->alloc(10,2); + std::copy(targetCoords,targetCoords+20,myCoords->getPointer()); + targetMesh->setCoords(myCoords); + myCoords->decrRef(); + return targetMesh; +} + +MEDCouplingUMesh *MEDCouplingRemapperTest::build2DTargetMesh_3() +{ + double targetCoords[20]={-0.6,-0.4, -0.1,-0.4, 1.1,-0.4, 2.1,-0.4, + -0.6,0.1, -0.1,0.1, 1.1,0.1, 2.1,0.1, + -0.6,1.1, -0.1,1.1}; + int targetConn[16]={0,4,5,1, 1,5,6,2, 2,6,7,3, 4,8,9,5}; + MEDCouplingUMesh *targetMesh=MEDCouplingUMesh::New(); + targetMesh->setMeshDimension(2); + targetMesh->allocateCells(4); + for(int i=0;i<4;i++) + targetMesh->insertNextCell(INTERP_KERNEL::NORM_QUAD4,4,targetConn+4*i); + targetMesh->finishInsertingCells(); + DataArrayDouble *myCoords=DataArrayDouble::New(); + myCoords->alloc(10,2); + std::copy(targetCoords,targetCoords+20,myCoords->getPointer()); + targetMesh->setCoords(myCoords); + myCoords->decrRef(); + return targetMesh; +} + +MEDCouplingUMesh *MEDCouplingRemapperTest::build3DExtrudedUMesh_1(MEDCouplingUMesh *&mesh2D) +{ + double coords[180]={ + 0.,0.,0., 1.,1.,0., 1.,1.25,0., 0.,1.,0., 1.,1.5,0., 2.,0.,0., 2.,1.,0., 1.,2.,0., 0.,2.,0., 3.,1.,0., + 3.,2.,0., 0.,1.,0., 1.,3.,0., 2.,2.,0., 2.,3.,0., + 0.,0.,1., 1.,1.,1., 1.,1.25,1., 0.,1.,1., 1.,1.5,1., 2.,0.,1., 2.,1.,1., 1.,2.,1., 0.,2.,1., 3.,1.,1., + 3.,2.,1., 0.,1.,1., 1.,3.,1., 2.,2.,1., 2.,3.,1., + 0.,0.,2., 1.,1.,2., 1.,1.25,2., 0.,1.,2., 1.,1.5,2., 2.,0.,2., 2.,1.,2., 1.,2.,2., 0.,2.,2., 3.,1.,2., + 3.,2.,2., 0.,1.,2., 1.,3.,2., 2.,2.,2., 2.,3.,2., + 0.,0.,3., 1.,1.,3., 1.,1.25,3., 0.,1.,3., 1.,1.5,3., 2.,0.,3., 2.,1.,3., 1.,2.,3., 0.,2.,3., 3.,1.,3., + 3.,2.,3., 0.,1.,3., 1.,3.,3., 2.,2.,3., 2.,3.,3.}; + + int conn[354]={ + // 0 + 0,11,1,3,15,26,16,18, 1,2,4,7,13,6,-1,1,16,21,6,-1,6,21,28,13,-1,13,7,22,28,-1,7,4,19,22,-1,4,2,17,19,-1,2,1,16,17,-1,16,21,28,22,19,17, + 1,6,5,3,16,21,20,18, 13,10,9,6,28,25,24,21, + 11,8,7,4,2,1,-1,11,26,16,1,-1,1,16,17,2,-1,2,17,19,4,-1,4,19,22,7,-1,7,8,23,22,-1,8,11,26,23,-1,26,16,17,19,22,23, + 7,12,14,13,22,27,29,28, + // 1 + 15,26,16,18,30,41,31,33, 16,17,19,22,28,21,-1,16,31,36,21,-1,21,36,43,28,-1,28,22,37,43,-1,22,19,34,37,-1,19,17,32,34,-1,17,16,31,32,-1,31,36,43,37,34,32, + 16,21,20,18,31,36,35,33, 28,25,24,21,43,40,39,36, + 26,23,22,19,17,16,-1,26,41,31,16,-1,16,31,32,17,-1,17,32,34,19,-1,19,34,37,22,-1,22,23,38,37,-1,23,26,41,38,-1,41,31,32,34,37,38, + 22,27,29,28,37,42,44,43, + // 2 + 30,41,31,33,45,56,46,48, 31,32,34,37,43,36,-1,31,46,51,36,-1,36,51,58,43,-1,43,37,52,58,-1,37,34,49,52,-1,34,32,47,49,-1,32,31,46,47,-1,46,51,58,52,49,47, + 31,36,35,33,46,51,50,48, 43,40,39,36,58,55,54,51, + 41,38,37,34,32,31,-1,41,56,46,31,-1,31,46,47,32,-1,32,47,49,34,-1,34,49,52,37,-1,37,38,53,52,-1,38,41,56,53,-1,56,46,47,49,52,53, + 37,42,44,43,52,57,59,58 + }; + int conn2[28]={7,12,14,13, 11,8,7,4,2,1, 13,10,9,6, 1,6,5,3, 1,2,4,7,13,6, 0,11,1,3}; + // + MEDCouplingUMesh *ret=MEDCouplingUMesh::New(); + ret->setMeshDimension(3); + ret->allocateCells(18); + // + ret->insertNextCell(INTERP_KERNEL::NORM_HEXA8,8,conn); + ret->insertNextCell(INTERP_KERNEL::NORM_POLYHED,43,conn+8); + ret->insertNextCell(INTERP_KERNEL::NORM_HEXA8,8,conn+51); + ret->insertNextCell(INTERP_KERNEL::NORM_HEXA8,8,conn+59); + ret->insertNextCell(INTERP_KERNEL::NORM_POLYHED,43,conn+67); + ret->insertNextCell(INTERP_KERNEL::NORM_HEXA8,8,conn+110); + // + ret->insertNextCell(INTERP_KERNEL::NORM_HEXA8,8,conn+118); + ret->insertNextCell(INTERP_KERNEL::NORM_POLYHED,43,conn+126); + ret->insertNextCell(INTERP_KERNEL::NORM_HEXA8,8,conn+169); + ret->insertNextCell(INTERP_KERNEL::NORM_HEXA8,8,conn+177); + ret->insertNextCell(INTERP_KERNEL::NORM_POLYHED,43,conn+185); + ret->insertNextCell(INTERP_KERNEL::NORM_HEXA8,8,conn+228); + // + ret->insertNextCell(INTERP_KERNEL::NORM_HEXA8,8,conn+236); + ret->insertNextCell(INTERP_KERNEL::NORM_POLYHED,43,conn+244); + ret->insertNextCell(INTERP_KERNEL::NORM_HEXA8,8,conn+287); + ret->insertNextCell(INTERP_KERNEL::NORM_HEXA8,8,conn+295); + ret->insertNextCell(INTERP_KERNEL::NORM_POLYHED,43,conn+303); + ret->insertNextCell(INTERP_KERNEL::NORM_HEXA8,8,conn+346); + // + ret->finishInsertingCells(); + DataArrayDouble *myCoords=DataArrayDouble::New(); + myCoords->alloc(60,3); + std::copy(coords,coords+180,myCoords->getPointer()); + ret->setCoords(myCoords); + // + mesh2D=MEDCouplingUMesh::New(); + mesh2D->setMeshDimension(2); + mesh2D->allocateCells(6); + mesh2D->insertNextCell(INTERP_KERNEL::NORM_QUAD4,4,conn2); + mesh2D->insertNextCell(INTERP_KERNEL::NORM_POLYGON,6,conn2+4); + mesh2D->insertNextCell(INTERP_KERNEL::NORM_QUAD4,4,conn2+10); + mesh2D->insertNextCell(INTERP_KERNEL::NORM_QUAD4,4,conn2+14); + mesh2D->insertNextCell(INTERP_KERNEL::NORM_POLYGON,6,conn2+18); + mesh2D->insertNextCell(INTERP_KERNEL::NORM_QUAD4,4,conn2+24); + mesh2D->setCoords(myCoords); + myCoords->decrRef(); + return ret; +} + +void MEDCouplingRemapperTest::testPartialTransfer1() +{ + MEDCouplingRemapper remapper; + MEDCouplingUMesh *sourceMesh=build1DTargetMesh_2(); + MEDCouplingUMesh *targetMesh=MEDCouplingBasicsTest::build2DTargetMesh_1(); + remapper.setIntersectionType(INTERP_KERNEL::PointLocator); + CPPUNIT_ASSERT_EQUAL(1,remapper.prepare(sourceMesh,targetMesh,"P0P0")); + MEDCouplingFieldDouble *srcField=MEDCouplingFieldDouble::New(ON_CELLS); + srcField->setNature(ConservativeVolumic); + srcField->setMesh(sourceMesh); + DataArrayDouble *array=DataArrayDouble::New(); + array->alloc(sourceMesh->getNumberOfCells(),1); + srcField->setArray(array); + double *ptr=array->getPointer(); + for(int i=0;i<sourceMesh->getNumberOfCells();i++) + ptr[i]=(double)(i+7); + array->decrRef(); + MEDCouplingFieldDouble *trgField=MEDCouplingFieldDouble::New(ON_CELLS); + trgField->setNature(ConservativeVolumic); + trgField->setMesh(targetMesh); + array=DataArrayDouble::New(); + array->alloc(targetMesh->getNumberOfCells(),1); + ptr=array->getPointer(); + std::fill(ptr,ptr+targetMesh->getNumberOfCells(),96.3); + trgField->setArray(array); + array->decrRef(); + remapper.partialTransfer(srcField,trgField); + const double valuesExpected9[5]={10.,8.,7.,96.3,10.}; + const double *values=trgField->getArray()->getConstPointer(); + for(int i0=0;i0<5;i0++) + CPPUNIT_ASSERT_DOUBLES_EQUAL(valuesExpected9[i0],values[i0],1e-12); + trgField->decrRef(); + srcField->decrRef(); + sourceMesh->decrRef(); + targetMesh->decrRef(); +} + +void MEDCouplingRemapperTest::testBugNonRegression1() +{ + // source + DataArrayDouble *coordsSrc(DataArrayDouble::New()); + const double coordsSrcData[18]={-6.25,3.6084391824351605,264.85199999999998,-6.25,3.6084391824351605,289.05200000000002,-6.2499999999999991,-3.6084391824351618,264.85199999999998,-6.2499999999999991,-3.6084391824351618,289.05200000000002,-1.7763568394002505e-15,4.4408920985006262e-15,264.85199999999998,-1.7763568394002505e-15,4.4408920985006262e-15,289.05200000000002}; + coordsSrc->useArray(coordsSrcData,false,CPP_DEALLOC,6,3); + DataArrayInt *connSrc(DataArrayInt::New()),*connISrc(DataArrayInt::New()); + const int connSrcData[7]={16,2,0,4,3,1,5}; + connSrc->useArray(connSrcData,false,CPP_DEALLOC,7,1); + const int connISrcData[2]={0,7}; + connISrc->useArray(connISrcData,false,CPP_DEALLOC,2,1); + MEDCouplingUMesh *srcMesh(MEDCouplingUMesh::New("source",3)); + srcMesh->setCoords(coordsSrc); + srcMesh->setConnectivity(connSrc,connISrc,true); + coordsSrc->decrRef(); connSrc->decrRef(); connISrc->decrRef(); + // target + DataArrayDouble *coordsTrg(DataArrayDouble::New()); +const double coordsTrgData[36]={-2,1.1547005383792521,264.85199999999998,-2,0.57735026918962618,264.85199999999998,-2.5,0.2886751345948132,264.85199999999998,-2.5,1.443375672974065,264.85199999999998,-3.0000000000000004,1.1547005383792526,264.85199999999998,-3.0000000000000004,0.57735026918962662,264.85199999999998,-2,1.1547005383792521,289.05200000000002,-2,0.57735026918962618,289.05200000000002,-2.5,0.2886751345948132,289.05200000000002,-2.5,1.443375672974065,289.05200000000002,-3.0000000000000004,1.1547005383792526,289.05200000000002,-3.0000000000000004,0.57735026918962662,289.05200000000002}; + coordsTrg->useArray(coordsTrgData,false,CPP_DEALLOC,12,3); + DataArrayInt *connTrg=DataArrayInt::New(); + const int connTrgData[44]={31,0,1,2,5,4,3,-1,7,6,9,10,11,8,-1,3,9,6,0,-1,4,10,9,3,-1,5,11,10,4,-1,2,8,11,5,-1,1,7,8,2,-1,0,6,7,1}; + connTrg->useArray(connTrgData,false,CPP_DEALLOC,44,1); + DataArrayInt *connITrg=DataArrayInt::New(); + const int connITrgData[2]={0,44}; + connITrg->useArray(connITrgData,false,CPP_DEALLOC,2,1); + MEDCouplingUMesh *trgMesh=MEDCouplingUMesh::New("target",3); + trgMesh->setCoords(coordsTrg); + trgMesh->setConnectivity(connTrg,connITrg,true); + coordsTrg->decrRef(); connTrg->decrRef(); connITrg->decrRef(); + // Go ! + const double valExpected(20.957814771583468); + MEDCouplingRemapper remapper; + remapper.setPrecision(1e-12); + remapper.setIntersectionType(INTERP_KERNEL::Triangulation); + CPPUNIT_ASSERT_EQUAL(1,remapper.prepare(srcMesh,trgMesh,"P0P0")); + std::vector<std::map<int,double> > matrx(remapper.getCrudeMatrix()); + CPPUNIT_ASSERT_EQUAL(1,(int)matrx.size()); + CPPUNIT_ASSERT_EQUAL(1,(int)matrx[0].size()); + CPPUNIT_ASSERT_DOUBLES_EQUAL(valExpected,matrx[0][0],1e-13); + // + srcMesh->decrRef(); trgMesh->decrRef(); +} + diff --git a/src/medtool/src/MEDCoupling/Test/MEDCouplingRemapperTest.hxx b/src/medtool/src/MEDCoupling/Test/MEDCouplingRemapperTest.hxx new file mode 100644 index 000000000..72a4f45fc --- /dev/null +++ b/src/medtool/src/MEDCoupling/Test/MEDCouplingRemapperTest.hxx @@ -0,0 +1,68 @@ +// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 +// 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 __MEDCOUPLINGREMAPPERTEST_HXX__ +#define __MEDCOUPLINGREMAPPERTEST_HXX__ + +#include <cppunit/extensions/HelperMacros.h> + +#include <map> +#include <vector> + +namespace ParaMEDMEM +{ + class MEDCouplingUMesh; + + class MEDCouplingRemapperTest : public CppUnit::TestFixture + { + CPPUNIT_TEST_SUITE(MEDCouplingRemapperTest); + CPPUNIT_TEST( test2DInterpP0P0_1 ); + CPPUNIT_TEST( test2DInterpP0P0R_1 ); + CPPUNIT_TEST( test1DInterp_1 ); + CPPUNIT_TEST( test2DInterpMultiMethods ); + CPPUNIT_TEST( testMultiDimCombi ); + CPPUNIT_TEST( testNatureOfField ); + CPPUNIT_TEST( testExtruded ); + CPPUNIT_TEST( testExtruded2 ); + CPPUNIT_TEST( testPrepareEx1 ); + CPPUNIT_TEST( testPartialTransfer1 ); + CPPUNIT_TEST( testBugNonRegression1 ); + CPPUNIT_TEST_SUITE_END(); + public: + void test2DInterpP0P0_1(); + void test2DInterpP0P0R_1(); + void test1DInterp_1(); + void test2DInterpMultiMethods(); + void testMultiDimCombi(); + void testNatureOfField(); + void testExtruded(); + void testExtruded2(); + void testPrepareEx1(); + void testPartialTransfer1(); + // + void testBugNonRegression1(); + private: + static MEDCouplingUMesh *build1DTargetMesh_2(); + static MEDCouplingUMesh *build2DTargetMesh_3(); + static MEDCouplingUMesh *build3DExtrudedUMesh_1(MEDCouplingUMesh *&mesh2D); + }; +} + +#endif diff --git a/src/medtool/src/MEDCoupling/Test/TestMEDCoupling.cxx b/src/medtool/src/MEDCoupling/Test/TestMEDCoupling.cxx new file mode 100644 index 000000000..0d017ae0d --- /dev/null +++ b/src/medtool/src/MEDCoupling/Test/TestMEDCoupling.cxx @@ -0,0 +1,35 @@ +// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 +// 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 "MEDCouplingBasicsTest1.hxx" +#include "MEDCouplingBasicsTest2.hxx" +#include "MEDCouplingBasicsTest3.hxx" +#include "MEDCouplingBasicsTest4.hxx" +#include "MEDCouplingBasicsTest5.hxx" +#include "MEDCouplingBasicsTestInterp.hxx" + +CPPUNIT_TEST_SUITE_REGISTRATION( ParaMEDMEM::MEDCouplingBasicsTest1 ); +CPPUNIT_TEST_SUITE_REGISTRATION( ParaMEDMEM::MEDCouplingBasicsTest2 ); +CPPUNIT_TEST_SUITE_REGISTRATION( ParaMEDMEM::MEDCouplingBasicsTest3 ); +CPPUNIT_TEST_SUITE_REGISTRATION( ParaMEDMEM::MEDCouplingBasicsTest4 ); +CPPUNIT_TEST_SUITE_REGISTRATION( ParaMEDMEM::MEDCouplingBasicsTest5 ); +CPPUNIT_TEST_SUITE_REGISTRATION( ParaMEDMEM::MEDCouplingBasicsTestInterp ); + +#include "BasicMainTest.hxx" diff --git a/src/medtool/src/MEDCoupling/Test/TestMEDCouplingRemapper.cxx b/src/medtool/src/MEDCoupling/Test/TestMEDCouplingRemapper.cxx new file mode 100644 index 000000000..cbcb2d22b --- /dev/null +++ b/src/medtool/src/MEDCoupling/Test/TestMEDCouplingRemapper.cxx @@ -0,0 +1,25 @@ +// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 +// 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 "MEDCouplingRemapperTest.hxx" + +CPPUNIT_TEST_SUITE_REGISTRATION( ParaMEDMEM::MEDCouplingRemapperTest ); + +#include "BasicMainTest.hxx" diff --git a/src/medtool/src/MEDCoupling_Swig/CMakeLists.txt b/src/medtool/src/MEDCoupling_Swig/CMakeLists.txt new file mode 100644 index 000000000..e0186342a --- /dev/null +++ b/src/medtool/src/MEDCoupling_Swig/CMakeLists.txt @@ -0,0 +1,115 @@ +# Copyright (C) 2012-2015 CEA/DEN, EDF 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, 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 +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +# +# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +# + +INCLUDE(${SWIG_USE_FILE}) + +ADD_DEFINITIONS(${PYTHON_DEFINITIONS}) + +SET_SOURCE_FILES_PROPERTIES(MEDCoupling.i PROPERTIES CPLUSPLUS ON) +SET_SOURCE_FILES_PROPERTIES(MEDCoupling.i PROPERTIES SWIG_DEFINITIONS "-shadow") +SET(SWIG_MODULE_MEDCoupling_EXTRA_FLAGS ${SWIG_EXTRA_FLAGS_FOR_NUMPYANDSCIPY}) + +SET (MEDCoupling_SWIG_DPYS_FILES + MEDCouplingCommon.i + MEDCouplingMemArray.i + MEDCouplingFieldDiscretization.i + MEDCouplingFinalize.i + MEDCouplingTypemaps.i) + +INCLUDE_DIRECTORIES( + ${PYTHON_INCLUDE_DIRS} + ${PTHREAD_INCLUDE_DIR} # pthread dependancy due to python2.7 library + ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_CURRENT_BINARY_DIR} + ${CMAKE_CURRENT_SOURCE_DIR}/../MEDCoupling + ${CMAKE_CURRENT_SOURCE_DIR}/../INTERP_KERNEL + ${CMAKE_CURRENT_SOURCE_DIR}/../INTERP_KERNEL/Bases + ${CMAKE_CURRENT_SOURCE_DIR}/../INTERP_KERNEL/Geometric2D + ${CMAKE_CURRENT_SOURCE_DIR}/../INTERP_KERNEL/ExprEval + ${CMAKE_CURRENT_SOURCE_DIR}/../INTERP_KERNEL/GaussPoints + ${PROJECT_BINARY_DIR}/doc + ) + +# _ABR_ Ensure dependency mechanism on all SWIG files and headers +SET (SWIG_MODULE_MEDCoupling_EXTRA_DEPS ${MEDCoupling_SWIG_DPYS_FILES} + ${medcoupling_HEADERS_HXX} ${medcoupling_HEADERS_TXX} + ${interpkernel_HEADERS_HXX} ${interpkernel_HEADERS_TXX}) + +# SWIG must run after the doc if we want to have the docstrings extracted from Doxygen +# into the Python module: +IF(SALOME_BUILD_DOC) + LIST(APPEND SWIG_MODULE_MEDCoupling_EXTRA_FLAGS -DWITH_DOCSTRINGS) + LIST(APPEND SWIG_MODULE_MEDCoupling_EXTRA_DEPS + ${PROJECT_BINARY_DIR}/doc/MEDCoupling_doc.i + swig_ready) +ENDIF() + +SWIG_ADD_MODULE(MEDCoupling python MEDCoupling.i) +SWIG_LINK_LIBRARIES(MEDCoupling ${PYTHON_LIBRARIES} ${PLATFORM_LIBS} medcoupling) + +SET_SOURCE_FILES_PROPERTIES(MEDCouplingRemapper.i PROPERTIES CPLUSPLUS ON) +SET_SOURCE_FILES_PROPERTIES(MEDCouplingRemapper.i PROPERTIES SWIG_DEFINITIONS "-shadow") +SET(SWIG_MODULE_MEDCouplingRemapper_EXTRA_FLAGS ${SWIG_EXTRA_FLAGS_FOR_NUMPYANDSCIPY}) + +# _ABR_ Ensure dependency mechanism on all SWIG files and headers +SET (SWIG_MODULE_MEDCouplingRemapper_EXTRA_DEPS ${MEDCoupling_SWIG_DPYS_FILES} + ${medcoupling_HEADERS_HXX} ${medcoupling_HEADERS_TXX} + ${interpkernel_HEADERS_HXX} ${interpkernel_HEADERS_TXX}) + +SWIG_ADD_MODULE(MEDCouplingRemapper python MEDCouplingRemapper.i) +SWIG_LINK_LIBRARIES(MEDCouplingRemapper ${PYTHON_LIBRARIES} medcouplingremapper) + +IF(WIN32) + SET_TARGET_PROPERTIES(_MEDCouplingRemapper PROPERTIES DEBUG_OUTPUT_NAME _MEDCouplingRemapper_d) + SET_TARGET_PROPERTIES(_MEDCoupling PROPERTIES DEBUG_OUTPUT_NAME _MEDCoupling_d) +ENDIF(WIN32) +INSTALL(TARGETS ${SWIG_MODULE_MEDCoupling_REAL_NAME} ${SWIG_MODULE_MEDCouplingRemapper_REAL_NAME} DESTINATION ${MEDTOOL_INSTALL_PYTHON}) + +#SET(PYFILES_TO_INSTALL ${CMAKE_CURRENT_BINARY_DIR}/MEDCoupling.py ${CMAKE_CURRENT_BINARY_DIR}/MEDCouplingRemapper.py) +#SALOME_INSTALL_SCRIPTS("${PYFILES_TO_INSTALL}" ${SALOME_INSTALL_PYTHON}) +INSTALL(FILES ${CMAKE_CURRENT_BINARY_DIR}/MEDCoupling.py ${CMAKE_CURRENT_BINARY_DIR}/MEDCouplingRemapper.py DESTINATION ${MEDTOOL_INSTALL_PYTHON}) + +INSTALL(FILES MEDCoupling.i MEDCouplingCommon.i MEDCouplingRefCountObject.i MEDCouplingMemArray.i MEDCouplingFieldDiscretization.i MEDCouplingTimeDiscretization.i MEDCouplingFinalize.i MEDCouplingRemapper.i MEDCouplingTypemaps.i MEDCouplingDataArrayTypemaps.i DESTINATION ${MEDTOOL_INSTALL_HEADERS}) +INSTALL(FILES MEDCouplingBasicsTest.py MEDCouplingRemapperTest.py MEDCouplingDataForTest.py MEDCouplingNumPyTest.py MEDCouplingPickleTest.py DESTINATION ${MEDTOOL_INSTALL_SCRIPT_PYTHON}) +INSTALL(FILES MEDCouplingExamplesTest.py DESTINATION ${MEDTOOL_INSTALL_SCRIPT_PYTHON}) + +#SALOME_GENERATE_TESTS_ENVIRONMENT(tests_env) + +ADD_TEST(MEDCouplingBasicsTest ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/MEDCouplingBasicsTest.py) +SET_TESTS_PROPERTIES(MEDCouplingBasicsTest PROPERTIES ENVIRONMENT "${tests_env}") +ADD_TEST(MEDCouplingExamplesTest ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/MEDCouplingExamplesTest.py) +SET_TESTS_PROPERTIES(MEDCouplingExamplesTest PROPERTIES ENVIRONMENT "${tests_env}") +ADD_TEST(MEDCouplingRemapperTest ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/MEDCouplingRemapperTest.py) +SET_TESTS_PROPERTIES(MEDCouplingRemapperTest PROPERTIES ENVIRONMENT "${tests_env}") + +IF(NUMPY_FOUND) + ADD_TEST(MEDCouplingNumPyTest ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/MEDCouplingNumPyTest.py) + SET_TESTS_PROPERTIES(MEDCouplingNumPyTest PROPERTIES ENVIRONMENT "${tests_env}") + ADD_TEST(MEDCouplingPickleTest ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/MEDCouplingPickleTest.py) + SET_TESTS_PROPERTIES(MEDCouplingPickleTest PROPERTIES ENVIRONMENT "${tests_env}") +ENDIF(NUMPY_FOUND) + +# Application tests + +SET(TEST_INSTALL_DIRECTORY ${MEDTOOL_INSTALL_SCRIPT_SCRIPTS}/test/MEDCoupling/MEDCoupling_Swig) +INSTALL(FILES MEDCouplingBasicsTest.py MEDCouplingRemapperTest.py MEDCouplingDataForTest.py MEDCouplingNumPyTest.py MEDCouplingPickleTest.py MEDCouplingExamplesTest.py DESTINATION ${TEST_INSTALL_DIRECTORY}) + +INSTALL(FILES CTestTestfileInstall.cmake + DESTINATION ${TEST_INSTALL_DIRECTORY} + RENAME CTestTestfile.cmake) diff --git a/src/medtool/src/MEDCoupling_Swig/CTestTestfileInstall.cmake b/src/medtool/src/MEDCoupling_Swig/CTestTestfileInstall.cmake new file mode 100644 index 000000000..c1f34cca8 --- /dev/null +++ b/src/medtool/src/MEDCoupling_Swig/CTestTestfileInstall.cmake @@ -0,0 +1,34 @@ +# Copyright (C) 2015 CEA/DEN, EDF 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, 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 +# 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_TEST(MEDCouplingBasicsTest python MEDCouplingBasicsTest.py) +SET_TESTS_PROPERTIES(MEDCouplingBasicsTest PROPERTIES LABELS "${COMPONENT_NAME}") + +ADD_TEST(MEDCouplingExamplesTest python MEDCouplingExamplesTest.py) +SET_TESTS_PROPERTIES(MEDCouplingExamplesTest PROPERTIES LABELS "${COMPONENT_NAME}") + +ADD_TEST(MEDCouplingRemapperTest python MEDCouplingRemapperTest.py) +SET_TESTS_PROPERTIES(MEDCouplingRemapperTest PROPERTIES LABELS "${COMPONENT_NAME}") + +# if numpy is used +ADD_TEST(MEDCouplingNumPyTest python MEDCouplingNumPyTest.py) +SET_TESTS_PROPERTIES(MEDCouplingNumPyTest PROPERTIES LABELS "${COMPONENT_NAME}") + +ADD_TEST(MEDCouplingPickleTest python MEDCouplingPickleTest.py) +SET_TESTS_PROPERTIES(MEDCouplingPickleTest PROPERTIES LABELS "${COMPONENT_NAME}") diff --git a/src/medtool/src/MEDCoupling_Swig/MEDCoupling.i b/src/medtool/src/MEDCoupling_Swig/MEDCoupling.i new file mode 100644 index 000000000..d6450452e --- /dev/null +++ b/src/medtool/src/MEDCoupling_Swig/MEDCoupling.i @@ -0,0 +1,136 @@ +// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// + +%include "MEDCouplingCommon.i" + +%pythoncode %{ +def ParaMEDMEMDataArrayDoublenew(cls,*args): + import _MEDCoupling + return _MEDCoupling.DataArrayDouble____new___(cls,args) +def ParaMEDMEMDataArrayDoubleIadd(self,*args): + import _MEDCoupling + return _MEDCoupling.DataArrayDouble____iadd___(self, self, *args) +def ParaMEDMEMDataArrayDoubleIsub(self,*args): + import _MEDCoupling + return _MEDCoupling.DataArrayDouble____isub___(self, self, *args) +def ParaMEDMEMDataArrayDoubleImul(self,*args): + import _MEDCoupling + return _MEDCoupling.DataArrayDouble____imul___(self, self, *args) +def ParaMEDMEMDataArrayDoubleIdiv(self,*args): + import _MEDCoupling + return _MEDCoupling.DataArrayDouble____idiv___(self, self, *args) +def ParaMEDMEMDataArrayDoubleIpow(self,*args): + import _MEDCoupling + return _MEDCoupling.DataArrayDouble____ipow___(self, self, *args) +def ParaMEDMEMMEDCouplingFieldDoublenew(cls,*args): + import _MEDCoupling + return _MEDCoupling.MEDCouplingFieldDouble____new___(cls,args) +def ParaMEDMEMMEDCouplingFieldDoubleIadd(self,*args): + import _MEDCoupling + return _MEDCoupling.MEDCouplingFieldDouble____iadd___(self, self, *args) +def ParaMEDMEMMEDCouplingFieldDoubleIsub(self,*args): + import _MEDCoupling + return _MEDCoupling.MEDCouplingFieldDouble____isub___(self, self, *args) +def ParaMEDMEMMEDCouplingFieldDoubleImul(self,*args): + import _MEDCoupling + return _MEDCoupling.MEDCouplingFieldDouble____imul___(self, self, *args) +def ParaMEDMEMMEDCouplingFieldDoubleIdiv(self,*args): + import _MEDCoupling + return _MEDCoupling.MEDCouplingFieldDouble____idiv___(self, self, *args) +def ParaMEDMEMMEDCouplingFieldDoubleIpow(self,*args): + import _MEDCoupling + return _MEDCoupling.MEDCouplingFieldDouble____ipow___(self, self, *args) +def ParaMEDMEMDataArrayIntnew(cls,*args): + import _MEDCoupling + return _MEDCoupling.DataArrayInt____new___(cls,args) +def ParaMEDMEMDataArrayIntIadd(self,*args): + import _MEDCoupling + return _MEDCoupling.DataArrayInt____iadd___(self, self, *args) +def ParaMEDMEMDataArrayIntIsub(self,*args): + import _MEDCoupling + return _MEDCoupling.DataArrayInt____isub___(self, self, *args) +def ParaMEDMEMDataArrayIntImul(self,*args): + import _MEDCoupling + return _MEDCoupling.DataArrayInt____imul___(self, self, *args) +def ParaMEDMEMDataArrayIntIdiv(self,*args): + import _MEDCoupling + return _MEDCoupling.DataArrayInt____idiv___(self, self, *args) +def ParaMEDMEMDataArrayIntImod(self,*args): + import _MEDCoupling + return _MEDCoupling.DataArrayInt____imod___(self, self, *args) +def ParaMEDMEMDataArrayIntIpow(self,*args): + import _MEDCoupling + return _MEDCoupling.DataArrayInt____ipow___(self, self, *args) +def ParaMEDMEMDataArrayDoubleTupleIadd(self,*args): + import _MEDCoupling + return _MEDCoupling.DataArrayDoubleTuple____iadd___(self, self, *args) +def ParaMEDMEMDataArrayDoubleTupleIsub(self,*args): + import _MEDCoupling + return _MEDCoupling.DataArrayDoubleTuple____isub___(self, self, *args) +def ParaMEDMEMDataArrayDoubleTupleImul(self,*args): + import _MEDCoupling + return _MEDCoupling.DataArrayDoubleTuple____imul___(self, self, *args) +def ParaMEDMEMDataArrayDoubleTupleIdiv(self,*args): + import _MEDCoupling + return _MEDCoupling.DataArrayDoubleTuple____idiv___(self, self, *args) +def ParaMEDMEMDataArrayIntTupleIadd(self,*args): + import _MEDCoupling + return _MEDCoupling.DataArrayIntTuple____iadd___(self, self, *args) +def ParaMEDMEMDataArrayIntTupleIsub(self,*args): + import _MEDCoupling + return _MEDCoupling.DataArrayIntTuple____isub___(self, self, *args) +def ParaMEDMEMDataArrayIntTupleImul(self,*args): + import _MEDCoupling + return _MEDCoupling.DataArrayIntTuple____imul___(self, self, *args) +def ParaMEDMEMDataArrayIntTupleIdiv(self,*args): + import _MEDCoupling + return _MEDCoupling.DataArrayIntTuple____idiv___(self, self, *args) +def ParaMEDMEMDataArrayIntTupleImod(self,*args): + import _MEDCoupling + return _MEDCoupling.DataArrayIntTuple____imod___(self, self, *args) +def ParaMEDMEMDenseMatrixIadd(self,*args): + import _MEDCoupling + return _MEDCoupling.DenseMatrix____iadd___(self, self, *args) +def ParaMEDMEMDenseMatrixIsub(self,*args): + import _MEDCoupling + return _MEDCoupling.DenseMatrix____isub___(self, self, *args) +def ParaMEDMEMMEDCouplingUMeshnew(cls,*args): + import _MEDCoupling + return _MEDCoupling.MEDCouplingUMesh____new___(cls,args) +def ParaMEDMEMMEDCoupling1DGTUMeshnew(cls,*args): + import _MEDCoupling + return _MEDCoupling.MEDCoupling1DGTUMesh____new___(cls,args) +def ParaMEDMEMMEDCoupling1SGTUMeshnew(cls,*args): + import _MEDCoupling + return _MEDCoupling.MEDCoupling1SGTUMesh____new___(cls,args) +def ParaMEDMEMMEDCouplingCurveLinearMeshnew(cls,*args): + import _MEDCoupling + return _MEDCoupling.MEDCouplingCurveLinearMesh____new___(cls,args) +def ParaMEDMEMMEDCouplingCMeshnew(cls,*args): + import _MEDCoupling + return _MEDCoupling.MEDCouplingCMesh____new___(cls,args) +def ParaMEDMEMMEDCouplingIMeshnew(cls,*args): + import _MEDCoupling + return _MEDCoupling.MEDCouplingIMesh____new___(cls,args) +def ParaMEDMEMMEDCouplingExtrudedMeshnew(cls,*args): + import _MEDCoupling + return _MEDCoupling.MEDCouplingExtrudedMesh____new___(cls,args) +%} + +%include "MEDCouplingFinalize.i" diff --git a/src/medtool/src/MEDCoupling_Swig/MEDCouplingBasicsTest.py b/src/medtool/src/MEDCoupling_Swig/MEDCouplingBasicsTest.py new file mode 100644 index 000000000..18118dc75 --- /dev/null +++ b/src/medtool/src/MEDCoupling_Swig/MEDCouplingBasicsTest.py @@ -0,0 +1,16776 @@ +# -*- coding: iso-8859-1 -*- +# Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 +# 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 +# + +from MEDCoupling import * +import unittest +from math import pi,e,sqrt,cos,sin +from datetime import datetime +from MEDCouplingDataForTest import MEDCouplingDataForTest +import rlcompleter,readline # this line has to be here, to ensure a usability of MEDCoupling/MEDLoader. B4 removing it please notify to anthony.geay@cea.fr + +class MEDCouplingBasicsTest(unittest.TestCase): + def testArray2(self): + arr=DataArrayDouble.New() + arr.setValues([12.,11.,10.,9.,8.,7.,6.,5.,4.,3.,2.,1.],3,4) + arr.setInfoOnComponent(0,"ggg"); + arr.setInfoOnComponent(1,"hhhh"); + arr.setInfoOnComponent(2,"jj"); + arr.setInfoOnComponent(3,"kkkkkk"); + arr2=arr.convertToIntArr(); + arr3=arr2.convertToDblArr(); + self.assertTrue(arr.isEqual(arr3,1e-14)) + pass + + def testArray3(self): + arr1=DataArrayInt.New(); + arr1Ref=[0,10,1,11,2,12,3,13,4,14,5,15,6,16] + arr1.setValues(arr1Ref,7,2); + self.assertEqual(7,arr1.getNumberOfTuples()); + self.assertEqual(2,arr1.getNumberOfComponents()); + self.assertEqual(arr1Ref,list(arr1.getValues())); + arr2=arr1.substr(3); + self.assertEqual(4,arr2.getNumberOfTuples()); + self.assertEqual(2,arr2.getNumberOfComponents()); + self.assertEqual(arr1Ref[6:],list(arr2.getValues())); + arr3=arr1.substr(2,5); + self.assertEqual(3,arr3.getNumberOfTuples()); + self.assertEqual(2,arr3.getNumberOfComponents()); + self.assertEqual(arr1Ref[4:10],list(arr3.getValues())); + # + arr4=DataArrayDouble.New(); + arr4Ref=[0.8,10.8,1.9,11.9,2.1,12.1,3.2,13.2,4.3,14.3,5.4,15.4,6.5,16.5] + arr4.setValues(arr4Ref,7,2); + self.assertEqual(7,arr4.getNumberOfTuples()); + self.assertEqual(2,arr4.getNumberOfComponents()); + tmp=arr4.getValues() + for i in xrange(14): + self.assertTrue(abs(arr4Ref[i]-tmp[i])<1e-14); + pass + arr5=arr4.substr(3); + self.assertEqual(4,arr5.getNumberOfTuples()); + self.assertEqual(2,arr5.getNumberOfComponents()); + tmp=arr5.getValues() + for i in xrange(8): + self.assertTrue(abs(arr4Ref[6+i]-tmp[i])<1e-14); + pass + arr6=arr4.substr(2,5); + self.assertEqual(3,arr6.getNumberOfTuples()); + self.assertEqual(2,arr6.getNumberOfComponents()); + tmp=arr6.getValues() + for i in xrange(6): + self.assertTrue(abs(arr4Ref[4+i]-tmp[i])<1e-14); + pass + pass + + def testMesh(self): + tab4=[1, 2, 8, 7, 2, 3, 9, 8, 3, + 4, 10, 9, 4, 5, 11, 10, 5, + 0, 6, 11, 0, 1, 7, 6 ] + nbOfNodes=12 + nbOfCells=6 + coords=[ 0.024155, 0.04183768725682622, -0.305, 0.04831000000000001, -1.015761910347357e-17, + -0.305, 0.09662000000000001, -1.832979297858306e-18, -0.305, 0.120775, 0.04183768725682623, + -0.305, 0.09662000000000001, 0.08367537451365245, -0.305, 0.04831000000000001, 0.08367537451365246, + -0.305, 0.024155, 0.04183768725682622, -0.2863, 0.04831000000000001, -1.015761910347357e-17, -0.2863, + 0.09662000000000001, -1.832979297858306e-18, -0.2863, 0.120775, 0.04183768725682623, -0.2863, 0.09662000000000001, + 0.08367537451365245, -0.2863, 0.04831000000000001, 0.08367537451365246, -0.2863 ] + self.assertEqual(MEDCouplingMesh.GetNumberOfNodesOfGeometricType(NORM_TRI3),3) + self.assertTrue(MEDCouplingMesh.IsStaticGeometricType(NORM_TRI3)) + self.assertTrue(MEDCouplingMesh.IsLinearGeometricType(NORM_TRI3)) + self.assertEqual(MEDCouplingMesh.GetDimensionOfGeometricType(NORM_TRI3),2) + self.assertEqual(MEDCouplingMesh.GetReprOfGeometricType(NORM_TRI3),"NORM_TRI3") + self.assertRaises(InterpKernelException,MEDCouplingMesh.GetNumberOfNodesOfGeometricType,NORM_POLYGON) + self.assertTrue(not MEDCouplingMesh.IsStaticGeometricType(NORM_POLYGON)) + self.assertTrue(MEDCouplingMesh.IsLinearGeometricType(NORM_POLYGON)) + self.assertEqual(MEDCouplingMesh.GetDimensionOfGeometricType(NORM_POLYGON),2) + self.assertEqual(MEDCouplingMesh.GetReprOfGeometricType(NORM_POLYGON),"NORM_POLYGON") + self.assertEqual(MEDCouplingMesh.GetNumberOfNodesOfGeometricType(NORM_TRI6),6) + self.assertTrue(MEDCouplingMesh.IsStaticGeometricType(NORM_TRI6)) + self.assertTrue(not MEDCouplingMesh.IsLinearGeometricType(NORM_TRI6)) + self.assertEqual(MEDCouplingMesh.GetDimensionOfGeometricType(NORM_TRI6),2) + self.assertEqual(MEDCouplingMesh.GetReprOfGeometricType(NORM_TRI6),"NORM_TRI6") + mesh=MEDCouplingUMesh.New() + mesh.setMeshDimension(2) + mesh.allocateCells(8); + mesh.setName("mesh1") + self.assertTrue(mesh.getName()=="mesh1") + for i in range(nbOfCells): + mesh.insertNextCell(NORM_QUAD4,4,tab4[4*i:4*(i+1)]); + pass + mesh.finishInsertingCells() + self.assertTrue(mesh.getNumberOfCells()==nbOfCells) + self.assertTrue(mesh.getNodalConnectivity().getNbOfElems()==30) + self.assertTrue(mesh.getNodalConnectivityIndex().getNbOfElems()==nbOfCells+1) + myCoords=DataArrayDouble.New() + myCoords.setValues(coords,nbOfNodes,3); + self.assertTrue(myCoords.getIJ(3,2)==-0.305) + mesh.setCoords(myCoords); + mesh.checkCoherency(); + self.assertTrue(mesh.getAllGeoTypes()==[4]) + myFalseConn=DataArrayInt.New() + myFalseConn.setValues(tab4,6,4) + self.assertTrue(myFalseConn.getIJ(1,1)==3) + # + field=MEDCouplingFieldDouble.New(ON_CELLS) + field.setMesh(mesh) + field.setNature(Integral) + myCoords=DataArrayDouble.New() + sampleTab=[] + for i in range(nbOfCells*9): + sampleTab.append(float(i)) + myCoords.setValues(sampleTab,nbOfCells,9); + field.setArray(myCoords) + self.assertTrue(3==mesh.getSpaceDimension()) + field.checkCoherency() + mesh2=mesh.clone(False) + mesh3=mesh.clone(True) + mesh3=0 + mesh2=0 + ## deep full recursively copy of field -> both field and mesh underneath copied + field2=field.clone(True) + field2.setMesh(field.getMesh().clone(True)) + mesh3=mesh.clone(True) + field3=mesh3.fillFromAnalytic(ON_CELLS,2,"x*IVec+(y+z)*JVec") + field3.applyFunc("u*u*u+cos(u)") + pass + + def testMeshPointsCloud(self): + targetCoords=[-0.3,-0.3,0.5, 0.2,-0.3,1., 0.7,-0.3,1.5, + -0.3,0.2,0.5, 0.2,0.2,1., 0.7,0.2,1.5, -0.3,0.7,0.5, 0.2,0.7,1., 0.7,0.7,1.5] + targetMesh=MEDCouplingUMesh.New(); + targetMesh.setMeshDimension(0); + targetMesh.allocateCells(8); + targetMesh.insertNextCell(NORM_POINT1,1,[0]); + targetMesh.insertNextCell(NORM_POINT1,1,[1]); + targetMesh.insertNextCell(NORM_POINT1,1,[2]); + targetMesh.insertNextCell(NORM_POINT1,1,[3]); + targetMesh.insertNextCell(NORM_POINT1,1,[4]); + targetMesh.insertNextCell(NORM_POINT1,1,[5]); + targetMesh.insertNextCell(NORM_POINT1,1,[7]); + targetMesh.insertNextCell(NORM_POINT1,1,[6]); + targetMesh.finishInsertingCells(); + self.assertRaises(InterpKernelException,targetMesh.checkCoherency); + myCoords=DataArrayDouble.New(); + myCoords.setValues(targetCoords,9,3); + targetMesh.setCoords(myCoords); + self.assertEqual(targetMesh.getSpaceDimension(),3) + self.assertEqual(targetMesh.getNumberOfCells(),8) + self.assertEqual(targetMesh.getNumberOfNodes(),9) + self.assertEqual(targetMesh.getMeshDimension(),0) + pass + + def testMeshM1D(self): + meshM1D=MEDCouplingUMesh.New(); + self.assertRaises(InterpKernelException,meshM1D.getMeshDimension); + self.assertRaises(InterpKernelException,meshM1D.getNumberOfNodes); + self.assertRaises(InterpKernelException,meshM1D.getNumberOfCells); + self.assertRaises(InterpKernelException,meshM1D.setMeshDimension,-2) + self.assertRaises(InterpKernelException,meshM1D.setMeshDimension,-10) + meshM1D.setMeshDimension(-1); + meshM1D.checkCoherency(); + self.assertEqual(meshM1D.getMeshDimension(),-1); + self.assertEqual(meshM1D.getNumberOfCells(),1); + self.assertRaises(InterpKernelException,meshM1D.getNumberOfNodes); + self.assertRaises(InterpKernelException,meshM1D.getSpaceDimension); + cpy=meshM1D.clone(True); + self.assertTrue(cpy.isEqual(meshM1D,1e-12)); + fieldOnCells=MEDCouplingFieldDouble.New(ON_CELLS); + fieldOnCells.setMesh(meshM1D); + array=DataArrayDouble.New(); + array.setValues(6*[7.],1,6); + fieldOnCells.setArray(array); + fieldOnCells.checkCoherency(); + pass + + def testDeepCopy(self): + array=DataArrayDouble.New(); + array.setValues(5*3*[7.],5,3); + self.assertEqual(array.getIJ(3,2),7.); + array2=array.deepCpy(); + self.assertEqual(array2.getIJ(3,2),7.) + # + array3=DataArrayInt.New(); + array3.setValues(5*3*[17],5,3); + self.assertEqual(array3.getIJ(3,2),17); + array4=array3.deepCpy(); + self.assertEqual(array4.getIJ(3,2),17); + pass + + def testRevNodal(self): + mesh=MEDCouplingDataForTest.build2DTargetMesh_1() + revNodal,revNodalIndx=mesh.getReverseNodalConnectivity(); + revNodalExpected=[0,0,1,1,2,0,3,0,1,2,3,4,2,4,3,3,4,4]; + revNodalIndexExpected=[0,1,3,5,7,12,14,15,17,18]; + self.assertEqual(revNodal.getNbOfElems(),18) + self.assertEqual(revNodalIndx.getNbOfElems(),10) + self.assertEqual(list(revNodal.getValues()),revNodalExpected) + self.assertEqual(list(revNodalIndx.getValues()),revNodalIndexExpected) + pass + + def testConvertToPolyTypes(self): + mesh=MEDCouplingDataForTest.build2DTargetMesh_1(); + elts=[1,3]; + mesh.convertToPolyTypes(elts); + mesh.checkCoherency(); + self.assertEqual(5,mesh.getNumberOfCells()); + self.assertEqual(23,mesh.getNodalConnectivity().getNumberOfTuples()); + expected1=[4, 0, 3, 4, 1, 5, 1, 4, 2, 3, 4, 5, 2, 5, 6, 7, 4, 3, 4, 7, 8, 5, 4] + self.assertEqual(expected1,list(mesh.getNodalConnectivity().getValues())); + # + mesh=MEDCouplingDataForTest.build3DTargetMesh_1(); + mesh.convertToPolyTypes(elts); + mesh.checkCoherency(); + self.assertEqual(8,mesh.getNumberOfCells()); + self.assertEqual(114,mesh.getNodalConnectivity().getNumberOfTuples()); + mesh.convertToPolyTypes(elts); + mesh.checkCoherency(); + self.assertEqual(8,mesh.getNumberOfCells()); + self.assertEqual(114,mesh.getNodalConnectivity().getNumberOfTuples()); + pass + + def testDescConn2D(self): + mesh=MEDCouplingDataForTest.build2DTargetMesh_1(); + desc=DataArrayInt.New(); + descIndx=DataArrayInt.New(); + revDesc=DataArrayInt.New(); + revDescIndx=DataArrayInt.New(); + mesh2=mesh.buildDescendingConnectivity(desc,descIndx,revDesc,revDescIndx); + mesh2.checkCoherency(); + self.assertEqual(1,mesh2.getMeshDimension()); + self.assertEqual(13,mesh2.getNumberOfCells()); + self.assertEqual(14,revDescIndx.getNbOfElems()); self.assertEqual(14,revDescIndx.getNumberOfTuples()); + self.assertEqual(6,descIndx.getNbOfElems()); self.assertEqual(6,descIndx.getNumberOfTuples()); + self.assertEqual(18,desc.getNbOfElems()); self.assertEqual(18,desc.getNumberOfTuples()); + self.assertEqual(18,revDesc.getNbOfElems()); self.assertEqual(18,revDesc.getNumberOfTuples()); + expected1=[0,1,2,3, 2,4,5, 6,7,4, 8,9,1,10, 11,12,6,9]; + self.assertEqual(expected1,list(desc.getValues())); + expected2=[0,4,7,10,14,18]; + self.assertEqual(expected2,list(descIndx.getValues())); + expected3=[0,1,3,5,6,8,9,11,12,13,15,16,17,18]; + self.assertEqual(expected3,list(revDescIndx.getValues())); + expected4=[0, 0,3, 0,1, 0, 1,2, 1, 2,4, 2, 3, 3,4, 3, 4, 4]; + self.assertEqual(expected4,list(revDesc.getValues())); + conn=mesh2.getNodalConnectivity(); + connIndex=mesh2.getNodalConnectivityIndex(); + expected5=[0,3,6,9,12,15,18,21,24,27,30,33,36,39]; + self.assertEqual(expected5,list(connIndex.getValues())); + expected6=[1, 0, 3, 1, 3, 4, 1, 4, 1, 1, 1, 0, 1, 4, 2, 1, 2, 1, 1, 4, 5, 1, 5, 2, 1, 6, 7, 1, 7, 4, 1, 3, 6, 1, 7, 8, 1, 8, 5]; + self.assertEqual(expected6,list(conn.getValues())); + # + eltsV=[1,3]; + mesh.convertToPolyTypes(eltsV); + mesh.checkCoherency(); + # + desc=DataArrayInt.New(); + descIndx=DataArrayInt.New(); + revDesc=DataArrayInt.New(); + revDescIndx=DataArrayInt.New(); + # + mesh2=mesh.buildDescendingConnectivity(desc,descIndx,revDesc,revDescIndx); + mesh2.checkCoherency(); + self.assertEqual(1,mesh2.getMeshDimension()); + self.assertEqual(13,mesh2.getNumberOfCells()); + self.assertEqual(14,revDescIndx.getNbOfElems()); self.assertEqual(14,revDescIndx.getNumberOfTuples()); + self.assertEqual(6,descIndx.getNbOfElems()); self.assertEqual(6,descIndx.getNumberOfTuples()); + self.assertEqual(18,desc.getNbOfElems()); self.assertEqual(18,desc.getNumberOfTuples()); + self.assertEqual(18,revDesc.getNbOfElems()); self.assertEqual(18,revDesc.getNumberOfTuples()); + self.assertEqual(expected1,list(desc.getValues())); + self.assertEqual(expected2,list(descIndx.getValues())); + self.assertEqual(expected3,list(revDescIndx.getValues())); + self.assertEqual(expected4,list(revDesc.getValues())); + conn=mesh2.getNodalConnectivity(); + connIndex=mesh2.getNodalConnectivityIndex(); + self.assertEqual(expected5,list(connIndex.getValues())); + self.assertEqual(expected6,list(conn.getValues())); + pass + + def testDescConn3D(self): + mesh=MEDCouplingDataForTest.build3DTargetMesh_1(); + desc=DataArrayInt.New(); + descIndx=DataArrayInt.New(); + revDesc=DataArrayInt.New(); + revDescIndx=DataArrayInt.New(); + # + mesh2=mesh.buildDescendingConnectivity(desc,descIndx,revDesc,revDescIndx); + mesh2.checkCoherency(); + self.assertEqual(2,mesh2.getMeshDimension()); + self.assertEqual(36,mesh2.getNumberOfCells()); + self.assertEqual(37,revDescIndx.getNbOfElems()); self.assertEqual(37,revDescIndx.getNumberOfTuples()); + self.assertEqual(9,descIndx.getNbOfElems()); self.assertEqual(9,descIndx.getNumberOfTuples()); + self.assertEqual(48,desc.getNbOfElems()); self.assertEqual(48,desc.getNumberOfTuples()); + self.assertEqual(48,revDesc.getNbOfElems()); self.assertEqual(48,revDesc.getNumberOfTuples()); + expected1=[0, 6, 12, 18, 24, 30, 36, 42, 48] + expected2=[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 3, 11, 12, 4, 13, 14, 15, 16, 17, 10, 18, 19, 13, 1, 20, 21, 22, 23, 24, 7, 25, 26, 27, 28, 22, 12, 29, 23, 30, 31, 32, 17, 33, 28, 34, 35, 30] + expected3=[0, 1, 3, 4, 6, 8, 9, 10, 12, 13, 14, 16, 17, 19, 21, 22, 23, 24, 26, 27, 28, 29, 30, 32, 34, 35, 36, 37, 38, 40, 41, 43, 44, 45, 46, 47, 48] + expected4=[0, 0, 4, 0, 0, 1, 0, 2, 0, 1, 1, 5, 1, 1, 1, 3, 2, 2, 6, 2, 3, 2, 2, 3, 3, 7, 3, 3, 4, 4, 4, 5, 4, 6, 4, 5, 5, 5, 5, 7, 6, 6, 7, 6, 6, 7, 7, 7] + expected5=[0, 5, 10, 15, 20, 25, 30, 35, 40, 45, 50, 55, 60, 65, 70, 75, 80, 85, 90, 95, 100, 105, 110, 115, 120, 125, 130, 135, 140, 145, 150, 155, 160, 165, 170, 175, 180] + expected6=[4, 0, 1, 4, 3, 4, 9, 12, 13, 10, 4, 0, 9, 10, 1, 4, 1, 10, 13, 4, 4, 4, 13, 12, 3, 4, 3, 12, 9, 0, 4, 1, 2, 5, 4, 4, 10, 13, 14, 11, 4, 1, 10, 11, 2, 4, 2, 11, 14, + 5, 4, 5, 14, 13, 4, 4, 3, 4, 7, 6, 4, 12, 15, 16, 13, 4, 4, 13, 16, 7, 4, 7, 16, 15, 6, 4, 6, 15, 12, 3, 4, 4, 5, 8, 7, 4, 13, 16, 17, 14, 4, 5, 14, 17, 8, 4, 8, + 17, 16, 7, 4, 18, 21, 22, 19, 4, 9, 18, 19, 10, 4, 10, 19, 22, 13, 4, 13, 22, 21, 12, 4, 12, 21, 18, 9, 4, 19, 22, 23, 20, 4, 10, 19, 20, 11, 4, 11, 20, 23, 14, 4, + 14, 23, 22, 13, 4, 21, 24, 25, 22, 4, 13, 22, 25, 16, 4, 16, 25, 24, 15, 4, 15, 24, 21, 12, 4, 22, 25, 26, 23, 4, 14, 23, 26, 17, 4, 17, 26, 25, 16] + expected7=[4, 0, 1, 4, 3, 4, 9, 12, 13, 10, 4, 0, 9, 10, 1, 4, 1, 10, 13, 4, 4, 4, 13, 12, 3, 4, 3, 12, 9, 0, 5, 1, 2, 5, 4, 5, 10, 13, 14, 11, 5, 1, 10, 11, 2, 5, 2, 11, 14, + 5, 5, 5, 14, 13, 4, 4, 3, 4, 7, 6, 4, 12, 15, 16, 13, 4, 4, 13, 16, 7, 4, 7, 16, 15, 6, 4, 6, 15, 12, 3, 5, 4, 5, 8, 7, 5, 13, 16, 17, 14, 5, 5, 14, 17, 8, 5, 8, + 17, 16, 7, 4, 18, 21, 22, 19, 4, 9, 18, 19, 10, 4, 10, 19, 22, 13, 4, 13, 22, 21, 12, 4, 12, 21, 18, 9, 4, 19, 22, 23, 20, 4, 10, 19, 20, 11, 4, 11, 20, 23, 14, 4, + 14, 23, 22, 13, 4, 21, 24, 25, 22, 4, 13, 22, 25, 16, 4, 16, 25, 24, 15, 4, 15, 24, 21, 12, 4, 22, 25, 26, 23, 4, 14, 23, 26, 17, 4, 17, 26, 25, 16] + + self.assertEqual(expected1,list(descIndx.getValues())); + self.assertEqual(expected2,list(desc.getValues())); + self.assertEqual(expected3,list(revDescIndx.getValues())); + self.assertEqual(expected4,list(revDesc.getValues())); + self.assertEqual(expected5,list(mesh2.getNodalConnectivityIndex().getValues())); + self.assertEqual(expected6,list(mesh2.getNodalConnectivity().getValues())); + # + eltsV=[1,3] + mesh.convertToPolyTypes(eltsV); + mesh.checkCoherency(); + desc=DataArrayInt.New(); + descIndx=DataArrayInt.New(); + revDesc=DataArrayInt.New(); + revDescIndx=DataArrayInt.New(); + mesh2=mesh.buildDescendingConnectivity(desc,descIndx,revDesc,revDescIndx); + mesh2.checkCoherency(); + self.assertEqual(2,mesh2.getMeshDimension()); + self.assertEqual(36,mesh2.getNumberOfCells()); + self.assertEqual(37,revDescIndx.getNbOfElems()); self.assertEqual(37,revDescIndx.getNumberOfTuples()); + self.assertEqual(9,descIndx.getNbOfElems()); self.assertEqual(9,descIndx.getNumberOfTuples()); + self.assertEqual(48,desc.getNbOfElems()); self.assertEqual(48,desc.getNumberOfTuples()); + self.assertEqual(48,revDesc.getNbOfElems()); self.assertEqual(48,revDesc.getNumberOfTuples()); + self.assertEqual(expected1,list(descIndx.getValues())); + self.assertEqual(expected2,list(desc.getValues())); + self.assertEqual(expected3,list(revDescIndx.getValues())); + self.assertEqual(expected4,list(revDesc.getValues())); + self.assertEqual(expected5,list(mesh2.getNodalConnectivityIndex().getValues())); + self.assertEqual(expected7,list(mesh2.getNodalConnectivity().getValues())); + pass + + def testFindBoundaryNodes(self): + mesh=MEDCouplingDataForTest.build3DTargetMesh_1(); + boundaryNodes=mesh.findBoundaryNodes(); + expected1=[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26]; + self.assertEqual(expected1,boundaryNodes.getValues()); + pass + + def testBoundaryMesh(self): + mesh=MEDCouplingDataForTest.build3DTargetMesh_1(); + mesh2=mesh.buildBoundaryMesh(False); + self.assertEqual(24,mesh2.getNumberOfCells()); + self.assertEqual(26,mesh2.getNumberOfNodes()); + pass + + def testBuildPartOfMySelf(self): + mesh=MEDCouplingDataForTest.build2DTargetMesh_1(); + mesh.setName("Toto"); + tab1=[0,4] + tab2=[0,2,3] + # + subMesh=mesh.buildPart(tab1) + self.assertTrue(isinstance(subMesh,MEDCouplingUMesh)) + subMesh=mesh.buildPartOfMySelf(tab1,True); + self.assertTrue(isinstance(subMesh,MEDCouplingUMesh)) + name=subMesh.getName(); + self.assertEqual(2,len(mesh.getAllGeoTypes())); + self.assertEqual(NORM_TRI3,mesh.getAllGeoTypes()[0]); + self.assertEqual(NORM_QUAD4,mesh.getAllGeoTypes()[1]); + self.assertEqual(1,len(subMesh.getAllGeoTypes())); + self.assertEqual(NORM_QUAD4,subMesh.getAllGeoTypes()[0]); + self.assertEqual(name,"Toto"); + self.assertEqual(2,subMesh.getNumberOfCells()); + subConn=[4,0,3,4,1,4,7,8,5,4]; + subConnIndex=[0,5,10]; + self.assertEqual(10,subMesh.getNodalConnectivity().getNbOfElems()); + self.assertEqual(3,subMesh.getNodalConnectivityIndex().getNbOfElems()); + self.assertEqual(subConn[0:10],list(subMesh.getNodalConnectivity().getValues())); + self.assertEqual(subConnIndex[0:3],list(subMesh.getNodalConnectivityIndex().getValues())); + # + subMesh=mesh.buildPartOfMySelf(tab2[0:3],True); + self.assertTrue(isinstance(subMesh,MEDCouplingUMesh)); + name=subMesh.getName(); + self.assertEqual(2,len(subMesh.getAllGeoTypes())); + self.assertEqual(NORM_TRI3,subMesh.getAllGeoTypes()[0]); + self.assertEqual(NORM_QUAD4,subMesh.getAllGeoTypes()[1]); + self.assertEqual(name,"Toto"); + self.assertEqual(3,subMesh.getNumberOfCells()); + subConn2=[4,0,3,4,1,3,4,5,2,4,6,7,4,3] + subConnIndex2=[0,5,9,14] + self.assertEqual(14,subMesh.getNodalConnectivity().getNbOfElems()); + self.assertEqual(4,subMesh.getNodalConnectivityIndex().getNbOfElems()); + self.assertEqual(subConn2[0:14],list(subMesh.getNodalConnectivity().getValues())); + self.assertEqual(subConnIndex2[0:4],list(subMesh.getNodalConnectivityIndex().getValues())); + dd=DataArrayInt.New() + dd.alloc(3,1) + dd.iota(0) + dd.setName("coucou") + subMesh=subMesh.buildPartOfMySelf(dd,True); + self.assertEqual("coucou",subMesh.getName()); + pass + + def testBuildPartOfMySelfNode(self): + mesh=MEDCouplingDataForTest.build2DTargetMesh_1(); + tab1=[5,7,8,4] + subMesh=mesh.buildPartOfMySelfNode(tab1[0:4],True); + self.assertTrue(isinstance(subMesh,MEDCouplingUMesh)) + self.assertEqual(1,len(subMesh.getAllGeoTypes())); + self.assertEqual(NORM_QUAD4,subMesh.getAllGeoTypes()[0]); + self.assertEqual(1,subMesh.getNumberOfCells()); + self.assertEqual(5,subMesh.getNodalConnectivity().getNbOfElems()); + self.assertEqual(2,subMesh.getNodalConnectivityIndex().getNbOfElems()); + subConn=[4,7,8,5,4] + subConnIndex=[0,5] + self.assertEqual(subConn[0:5],list(subMesh.getNodalConnectivity().getValues())); + self.assertEqual(subConnIndex[0:2],list(subMesh.getNodalConnectivityIndex().getValues())); + # + ddd=DataArrayInt.New() + ddd.setValues(tab1[0:2],2,1) + ddd.setName("ddd") + subMesh=mesh.buildPartOfMySelfNode(ddd,False); + self.assertEqual("ddd",subMesh.getName()) + self.assertTrue(isinstance(subMesh,MEDCouplingUMesh)) + self.assertEqual(2,len(subMesh.getAllGeoTypes())); + self.assertEqual(NORM_TRI3,subMesh.getAllGeoTypes()[0]); + self.assertEqual(NORM_QUAD4,subMesh.getAllGeoTypes()[1]); + self.assertEqual(3,subMesh.getNumberOfCells()); + self.assertEqual(14,subMesh.getNodalConnectivity().getNbOfElems()); + self.assertEqual(4,subMesh.getNodalConnectivityIndex().getNbOfElems()); + subConn2=[3,4,5,2,4,6,7,4,3,4,7,8,5,4] + subConnIndex2=[0,4,9,14] + self.assertEqual(subConn2[0:14],list(subMesh.getNodalConnectivity().getValues())); + self.assertEqual(subConnIndex2[0:4],list(subMesh.getNodalConnectivityIndex().getValues())); + #testing the case where length of tab2 is greater than max number of node per cell. + tab2=[0,3,2,1,4,5,6] + subMesh=mesh.buildPartOfMySelfNode(tab2[0:7],True); + self.assertTrue(isinstance(subMesh,MEDCouplingUMesh)) + self.assertEqual(2,len(subMesh.getAllGeoTypes())); + self.assertEqual(NORM_TRI3,subMesh.getAllGeoTypes()[0]); + self.assertEqual(NORM_QUAD4,subMesh.getAllGeoTypes()[1]); + self.assertEqual(3,subMesh.getNumberOfCells()); + pass + + def testZipCoords(self): + mesh=MEDCouplingDataForTest.build2DTargetMesh_1(); + self.assertEqual(2,len(mesh.getAllGeoTypes())); + self.assertEqual(2,mesh.getSpaceDimension()); + self.assertEqual(9,mesh.getNumberOfNodes()); + self.assertEqual(5,mesh.getNumberOfCells()); + oldConn=mesh.getNodalConnectivity().getValues()[0:mesh.getNodalConnectivity().getNbOfElems()]; + oldConnIndex=mesh.getNodalConnectivityIndex().getValues()[0:mesh.getNumberOfCells()+1] + oldCoords=mesh.getCoords(); + mesh.zipCoords(); + self.assertEqual(2,len(mesh.getAllGeoTypes())); + self.assertEqual(2,mesh.getSpaceDimension()); + self.assertEqual(9,mesh.getNumberOfNodes()); + self.assertEqual(5,mesh.getNumberOfCells()); + self.assertEqual(mesh.getCoords().getValues()[0:2*9],oldCoords.getValues()); + self.assertEqual(list(oldConn),list(mesh.getNodalConnectivity().getValues())); + self.assertEqual(list(oldConnIndex),list(mesh.getNodalConnectivityIndex().getValues())); + # + tab1=[0,4] + subMesh=mesh.buildPartOfMySelf(tab1,True); + self.assertTrue(isinstance(subMesh,MEDCouplingUMesh)) + traducer=subMesh.zipCoordsTraducer(); + expectedTraducer=[0, 1, -1, 2, 3, 4, -1, 5, 6] + self.assertEqual(expectedTraducer,list(traducer.getValues())); + self.assertEqual(NORM_QUAD4,subMesh.getAllGeoTypes()[0]); + self.assertEqual(2,subMesh.getNumberOfCells()); + subConn=[4,0,2,3,1,4,5,6,4,3] + subConnIndex=[0,5,10] + self.assertEqual(7,subMesh.getNumberOfNodes()); + self.assertEqual(10,subMesh.getNodalConnectivity().getNbOfElems()); + self.assertEqual(3,subMesh.getNodalConnectivityIndex().getNbOfElems()); + self.assertEqual(subConn,list(subMesh.getNodalConnectivity().getValues())); + self.assertEqual(subConnIndex,list(subMesh.getNodalConnectivityIndex().getValues())); + # + subMesh=mesh.buildPartOfMySelf(tab1,False); + self.assertTrue(isinstance(subMesh,MEDCouplingUMesh)) + self.assertEqual(NORM_QUAD4,subMesh.getAllGeoTypes()[0]); + self.assertEqual(2,subMesh.getNumberOfCells()); + self.assertEqual(7,subMesh.getNumberOfNodes()); + self.assertEqual(10,subMesh.getNodalConnectivity().getNbOfElems()); + self.assertEqual(3,subMesh.getNodalConnectivityIndex().getNbOfElems()); + self.assertEqual(subConn,list(subMesh.getNodalConnectivity().getValues())); + self.assertEqual(subConnIndex,list(subMesh.getNodalConnectivityIndex().getValues())); + pass + + def testZipConnectivity(self): + m1=MEDCouplingDataForTest.build2DTargetMesh_1(); + m2=MEDCouplingDataForTest.build2DTargetMesh_1(); + cells1=[2,3,4] + m3=m2.buildPartOfMySelf(cells1,True); + self.assertTrue(isinstance(m3,MEDCouplingUMesh)) + m4=MEDCouplingDataForTest.build2DSourceMesh_1(); + m5=MEDCouplingUMesh.MergeUMeshes(m1,m3); + m6=MEDCouplingUMesh.MergeUMeshes(m5,m4); + # + self.assertEqual(10,m6.getNumberOfCells()); + self.assertEqual(22,m6.getNumberOfNodes()); + (arr,areNodesMerged,newNbOfNodes)=m6.mergeNodes(1e-13); + self.assertTrue(areNodesMerged); + self.assertEqual(10,m6.getNumberOfCells()); + self.assertEqual(9,m6.getNumberOfNodes()); + # + arr=m6.zipConnectivityTraducer(0); + self.assertEqual(7,m6.getNumberOfCells()); + m7=m6.clone(True); + arr=m6.zipConnectivityTraducer(0); + self.assertTrue(m7.isEqual(m6,1e-12)); + self.assertEqual(7,m6.getNumberOfCells()); + pass + + def testEqualMesh(self): + mesh1=MEDCouplingDataForTest.build2DTargetMesh_1(); + mesh2=MEDCouplingDataForTest.build2DTargetMesh_1(); + # + self.assertTrue(mesh1.isEqual(mesh1,1e-12)); + # + self.assertTrue(mesh1.isEqual(mesh2,1e-12)); + self.assertTrue(mesh2.isEqual(mesh1,1e-12)); + pt=mesh2.getCoords().getValues(); + tmp=pt[1] + mesh2.getCoords().setIJ(0,1,5.999); + self.assertTrue(not mesh1.isEqual(mesh2,1e-12)); + self.assertTrue(not mesh2.isEqual(mesh1,1e-12)); + mesh2.getCoords().setIJ(0,1,tmp); + self.assertTrue(mesh1.isEqual(mesh2,1e-12)); + self.assertTrue(mesh2.isEqual(mesh1,1e-12)); + # + pt2=mesh1.getNodalConnectivity().getValues(); + mesh1.getNodalConnectivity().setIJ(5,0,int(pt2[5])+1); + self.assertTrue(not mesh1.isEqual(mesh2,1e-12)); + self.assertTrue(not mesh2.isEqual(mesh1,1e-12)); + mesh1.getNodalConnectivity().setIJ(5,0,int(pt2[5])); + self.assertTrue(mesh1.isEqual(mesh2,1e-12)); + self.assertTrue(mesh2.isEqual(mesh1,1e-12)); + # + pt2=mesh1.getNodalConnectivityIndex().getValues(); + mesh1.getNodalConnectivityIndex().setIJ(1,0,int(pt2[1]+1)); + self.assertTrue(not mesh1.isEqual(mesh2,1e-12)); + self.assertTrue(not mesh2.isEqual(mesh1,1e-12)); + mesh1.getNodalConnectivityIndex().setIJ(1,0,int(pt2[1])); + self.assertTrue(mesh1.isEqual(mesh2,1e-12)); + self.assertTrue(mesh2.isEqual(mesh1,1e-12)); + # + tmp3=mesh1.getName(); + mesh1.setName("lllll"); + self.assertTrue(not mesh1.isEqual(mesh2,1e-12)); + self.assertTrue(not mesh2.isEqual(mesh1,1e-12)); + mesh1.setName(tmp3); + self.assertTrue(mesh1.isEqual(mesh2,1e-12)); + self.assertTrue(mesh2.isEqual(mesh1,1e-12)); + # + tmp3=mesh2.getCoords().getInfoOnComponent(1); + mesh2.getCoords().setInfoOnComponent(1,"kkkkkk"); + self.assertTrue(not mesh1.isEqual(mesh2,1e-12)); + self.assertTrue(not mesh2.isEqual(mesh1,1e-12)); + mesh2.getCoords().setInfoOnComponent(1,tmp3); + self.assertTrue(mesh1.isEqual(mesh2,1e-12)); + self.assertTrue(mesh2.isEqual(mesh1,1e-12)); + pass + + def testEqualFieldDouble(self): + mesh1=MEDCouplingDataForTest.build2DTargetMesh_1(); + mesh2=MEDCouplingDataForTest.build2DTargetMesh_1(); + # + fieldOnCells1=MEDCouplingFieldDouble.New(ON_CELLS,NO_TIME); + fieldOnCells1.setMesh(mesh1); + fieldOnCells2=MEDCouplingFieldDouble.New(ON_CELLS,NO_TIME); + fieldOnCells2.setMesh(mesh2); + # + self.assertTrue(fieldOnCells1.isEqual(fieldOnCells2,1e-12,1e-15)); + self.assertTrue(fieldOnCells2.isEqual(fieldOnCells1,1e-12,1e-15)); + # + fieldOnNodes1=MEDCouplingFieldDouble.New(ON_CELLS,NO_TIME); + self.assertTrue(not fieldOnCells1.isEqual(fieldOnNodes1,1e-12,1e-15)); + self.assertTrue(not fieldOnNodes1.isEqual(fieldOnCells1,1e-12,1e-15)); + # + fieldOnCells2=MEDCouplingFieldDouble.New(ON_CELLS,ONE_TIME); + self.assertEqual(fieldOnCells2.getMesh(),None) # to check that convertMesh wrapping do not raise but return Py_None + self.assertTrue(not fieldOnCells1.isEqual(fieldOnCells2,1e-12,1e-15)); + self.assertTrue(not fieldOnCells2.isEqual(fieldOnCells1,1e-12,1e-15)); + fieldOnCells1=MEDCouplingFieldDouble.New(ON_CELLS,ONE_TIME); + self.assertTrue(fieldOnCells1.isEqual(fieldOnCells2,1e-12,1e-15)); + self.assertTrue(fieldOnCells2.isEqual(fieldOnCells1,1e-12,1e-15)); + fieldOnCells1.setTime(4.,6,7); + self.assertTrue(not fieldOnCells1.isEqual(fieldOnCells2,1e-12,1e-15)); + self.assertTrue(not fieldOnCells2.isEqual(fieldOnCells1,1e-12,1e-15)); + fieldOnCells2.setTime(4.,6,7); + self.assertTrue(fieldOnCells1.isEqual(fieldOnCells2,1e-12,1e-15)); + self.assertTrue(fieldOnCells2.isEqual(fieldOnCells1,1e-12,1e-15)); + fieldOnCells1.setName("Power"); + self.assertTrue(not fieldOnCells1.isEqual(fieldOnCells2,1e-12,1e-15)); + self.assertTrue(not fieldOnCells2.isEqual(fieldOnCells1,1e-12,1e-15)); + fieldOnCells2.setName("Power"); + self.assertTrue(fieldOnCells1.isEqual(fieldOnCells2,1e-12,1e-15)); + self.assertTrue(fieldOnCells2.isEqual(fieldOnCells1,1e-12,1e-15)); + # + fieldOnCells1.setMesh(mesh1); + self.assertTrue(not fieldOnCells1.isEqual(fieldOnCells2,1e-12,1e-15)); + self.assertTrue(not fieldOnCells2.isEqual(fieldOnCells1,1e-12,1e-15)); + fieldOnCells2.setMesh(mesh1); + self.assertTrue(fieldOnCells1.isEqual(fieldOnCells2,1e-12,1e-15)); + self.assertTrue(fieldOnCells2.isEqual(fieldOnCells1,1e-12,1e-15)); + arr=DataArrayDouble.New(); + arr.setName("popo"); + arr.setValues(mesh1.getNumberOfCells()*3*[6.],mesh1.getNumberOfCells(),3); + fieldOnCells1.setArray(arr); + self.assertTrue(not fieldOnCells1.isEqual(fieldOnCells2,1e-12,1e-15)); + self.assertTrue(not fieldOnCells2.isEqual(fieldOnCells1,1e-12,1e-15)); + fieldOnCells2.setArray(arr); + self.assertTrue(fieldOnCells1.isEqual(fieldOnCells2,1e-12,1e-15)); + self.assertTrue(fieldOnCells2.isEqual(fieldOnCells1,1e-12,1e-15)); + # + arr2=arr.deepCpy(); + fieldOnCells2.setArray(arr2); + self.assertTrue(fieldOnCells1.isEqual(fieldOnCells2,1e-12,1e-15)); + self.assertTrue(fieldOnCells2.isEqual(fieldOnCells1,1e-12,1e-15)); + arr.setIJ(1,2,6.1); + self.assertTrue(not fieldOnCells1.isEqual(fieldOnCells2,1e-12,1e-15)); + self.assertTrue(not fieldOnCells2.isEqual(fieldOnCells1,1e-12,1e-15)); + arr.setIJ(1,2,6.); + self.assertTrue(fieldOnCells1.isEqual(fieldOnCells2,1e-12,1e-15)); + self.assertTrue(fieldOnCells2.isEqual(fieldOnCells1,1e-12,1e-15)); + arr2.setName("popo2"); + self.assertTrue(not fieldOnCells1.isEqual(fieldOnCells2,1e-12,1e-15)); + self.assertTrue(not fieldOnCells2.isEqual(fieldOnCells1,1e-12,1e-15)); + # + arr2.setName("popo"); + self.assertTrue(fieldOnCells1.isEqual(fieldOnCells2,1e-12,1e-15)); + self.assertTrue(fieldOnCells2.isEqual(fieldOnCells1,1e-12,1e-15)); + # + arr2.setInfoOnComponent(2,"jjj"); + self.assertTrue(not fieldOnCells1.isEqual(fieldOnCells2,1e-12,1e-15)); + self.assertTrue(not fieldOnCells2.isEqual(fieldOnCells1,1e-12,1e-15)); + arr.setInfoOnComponent(2,"jjj"); + self.assertTrue(fieldOnCells1.isEqual(fieldOnCells2,1e-12,1e-15)); + self.assertTrue(fieldOnCells2.isEqual(fieldOnCells1,1e-12,1e-15)); + pass + + def testNatureChecking(self): + field=MEDCouplingFieldDouble.New(ON_CELLS,NO_TIME); + field.setNature(Integral); + field.setNature(ConservativeVolumic); + field.setNature(IntegralGlobConstraint); + field=MEDCouplingFieldDouble.New(ON_NODES,NO_TIME); + field.setNature(ConservativeVolumic); + self.assertRaises(InterpKernelException,field.setNature,Integral); + self.assertRaises(InterpKernelException,field.setNature,IntegralGlobConstraint); + pass + + def testNatureOperations(self): + """ Check nature constraints on field operations """ + m = MEDCouplingCMesh() + m.setCoordsAt(0, DataArrayDouble([1.0,2.0,3.0])) + m.setCoordsAt(1, DataArrayDouble([1.0,2.0,3.0])) + m = m.buildUnstructured() + f1, f2 = MEDCouplingFieldDouble.New(ON_CELLS, NO_TIME), MEDCouplingFieldDouble.New(ON_CELLS, NO_TIME) + f1.setNature(Integral) + f2.setNature(ConservativeVolumic) + self.assertEqual(Integral, f1.getNature()) + self.assertEqual(ConservativeVolumic, f2.getNature()) + + da = DataArrayDouble([1.0,2.0,3.0,4.0]) + f1.setMesh(m); f2.setMesh(m) + f1.setArray(da); f2.setArray(da.deepCpy()) + # All this should complain about nature: + self.assertRaises(InterpKernelException, f1.__add__, f2) + self.assertRaises(InterpKernelException, f1.__iadd__, f2) + self.assertRaises(InterpKernelException, f1.__sub__, f2) + self.assertRaises(InterpKernelException, f1.__isub__, f2) + self.assertRaises(InterpKernelException, f1.__radd__, f2) + self.assertRaises(InterpKernelException, f1.__rsub__, f2) + self.assertRaises(InterpKernelException, MEDCouplingFieldDouble.AddFields, f1, f2) + self.assertRaises(InterpKernelException, MEDCouplingFieldDouble.SubstractFields, f1, f2) + self.assertRaises(InterpKernelException, MEDCouplingFieldDouble.MaxFields, f1, f2) + self.assertRaises(InterpKernelException, MEDCouplingFieldDouble.MinFields, f1, f2) + # Not those ones: + f3 = MEDCouplingFieldDouble.MultiplyFields(f1,f2) + self.assertEqual(NoNature, f3.getNature()) + f3 = f1*f2 + self.assertEqual(NoNature, f3.getNature()) + f1Tmp = f1.deepCpy(); f1Tmp.setMesh(m); f1Tmp *= f2 + self.assertEqual(NoNature, f1Tmp.getNature()) + f3 = MEDCouplingFieldDouble.DivideFields(f1,f2) + self.assertEqual(NoNature, f3.getNature()) + f3 = f1/f2 + self.assertEqual(NoNature, f3.getNature()) + f1Tmp = f1.deepCpy(); f1Tmp.setMesh(m); f1Tmp /= f2 + self.assertEqual(NoNature, f1Tmp.getNature()) +# f3 = MEDCouplingFieldDouble.PowFields(f1,f2) +# self.assertEqual(NoNature, f3.getNature()) + f3 = f1**f2 + self.assertEqual(NoNature, f3.getNature()) + f1Tmp = f1.deepCpy(); f1Tmp.setMesh(m); f1Tmp **= f2 + self.assertEqual(NoNature, f1Tmp.getNature()) + f3 = MEDCouplingFieldDouble.DotFields(f1,f2) + self.assertEqual(NoNature, f3.getNature()) + f3 = f1.dot(f2) + self.assertEqual(NoNature, f3.getNature()) + + da = DataArrayDouble.Meld([da, da, da]) + f1.setArray(da); f2.setArray(da.deepCpy()) + f3 = MEDCouplingFieldDouble.CrossProductFields(f1,f2) + self.assertEqual(NoNature, f3.getNature()) + f3 = f1.crossProduct(f2) + + def testBuildSubMeshData(self): + targetMesh=MEDCouplingDataForTest.build2DTargetMesh_1() + #check buildSubMesh on field on cells + fieldCells=MEDCouplingFieldDouble.New(ON_CELLS,NO_TIME); + fieldCells.setMesh(targetMesh); + elts=[1,2,4] + ret1,di=fieldCells.buildSubMeshData(elts); + self.assertTrue(isinstance(ret1,MEDCouplingUMesh)) + self.assertEqual(3,ret1.getNumberOfCells()); + self.assertEqual(9,ret1.getNumberOfNodes()); + self.assertEqual(3,di.getNumberOfTuples()); + self.assertEqual(1,di.getNumberOfComponents()); + toCheck=di.getValues(); + self.assertTrue(elts,toCheck); + #check buildSubMesh on field on nodes + fieldNodes=MEDCouplingFieldDouble.New(ON_NODES,NO_TIME); + fieldNodes.setMesh(targetMesh); + ret2,di=fieldNodes.buildSubMeshData(elts); + self.assertTrue(isinstance(ret2,MEDCouplingUMesh)) + self.assertEqual(3,ret2.getNumberOfCells()); + self.assertEqual(6,ret2.getNumberOfNodes()); + self.assertEqual(6,di.getNumberOfTuples()); + self.assertEqual(1,di.getNumberOfComponents()); + toCheck=di.getValues(); + expected=[1,2,4,5,7,8] + self.assertEqual(expected,list(toCheck)); + pass + + def testExtrudedMesh1(self): + mesh3D,mesh2D=MEDCouplingDataForTest.build3DExtrudedUMesh_1(); + ext=MEDCouplingExtrudedMesh.New(mesh3D,mesh2D,1); + self.assertEqual(18,ext.getNumberOfCells()); + self.assertEqual(60,ext.getNumberOfNodes()); + ids3D=ext.getMesh3DIds(); + ids3DExpected=[5,4,3,2,1,0, 11,10,9,8,7,6, 17,16,15,14,13,12] + self.assertEqual(18,ids3D.getNumberOfTuples()); + self.assertEqual(1,ids3D.getNumberOfComponents()); + self.assertEqual(ids3DExpected,list(ids3D.getValues())); + mesh1D=ext.getMesh1D(); + self.assertEqual(4,mesh1D.getNumberOfNodes()); + self.assertEqual(3,mesh1D.getNumberOfCells()); + mesh1DExpected=[0.66666666666666663, 1.4583333333333333, 0, 0.66666666666666663, + 1.4583333333333333, 1, 0.66666666666666663, 1.4583333333333333, + 2, 0.66666666666666663, 1.4583333333333333, 3] + mesh1DCoords=mesh1D.getCoords(); + self.assertEqual(4,mesh1DCoords.getNumberOfTuples()); + self.assertEqual(3,mesh1DCoords.getNumberOfComponents()); + self.assertEqual(mesh1DExpected,mesh1DCoords.getValues()); + conn1D=mesh1D.getNodalConnectivity(); + self.assertEqual(9,conn1D.getNumberOfTuples()); + self.assertEqual(1,conn1D.getNumberOfComponents()); + conn1DExpected=[1,0,1,1,1,2,1,2,3] + self.assertEqual(conn1DExpected,list(conn1D.getValues())); + pass + + def testExtrudedMesh3(self): + m1=MEDCouplingDataForTest.build2DTargetMesh_1(); + m1.changeSpaceDimension(3); + m2=MEDCouplingDataForTest.buildCU1DMesh_U(); + m2.changeSpaceDimension(3); + center=[0.,0.,0.] + vector=[0.,1.,0.] + m2.rotate(center,vector,-pi/2.); + m3=m1.buildExtrudedMesh(m2,0); + # + m4=MEDCouplingExtrudedMesh.New(m3,m1,0); + self.assertEqual(15,m4.getNumberOfCells()); + self.assertEqual(5,m4.getMesh2D().getNumberOfCells()); + self.assertEqual(3,m4.getMesh1D().getNumberOfCells()); + m3DIds=m4.getMesh3DIds().getValues(); + self.assertEqual(range(15),list(m3DIds)); + #some random in cells to check that extrusion alg find it correctly + expected1=[1,3,2,0,6,5,7,10,11,8,12,9,14,13,4] + m3.renumberCells(expected1,False); + m4=MEDCouplingExtrudedMesh.New(m3,m1,0); + self.assertEqual(15,m4.getNumberOfCells()); + self.assertEqual(5,m4.getMesh2D().getNumberOfCells()); + self.assertEqual(3,m4.getMesh1D().getNumberOfCells()); + m3DIds=m4.getMesh3DIds().getValues(); + self.assertEqual(expected1,list(m3DIds)); + #play with polygons and polyedrons + cells=[2,3] + m1.convertToPolyTypes(cells); + m3=m1.buildExtrudedMesh(m2,0); + self.assertEqual(NORM_HEXA8,m3.getTypeOfCell(0)); + self.assertEqual(NORM_PENTA6,m3.getTypeOfCell(1)); + self.assertEqual(NORM_POLYHED,m3.getTypeOfCell(2)); + self.assertEqual(NORM_POLYHED,m3.getTypeOfCell(3)); + self.assertEqual(NORM_HEXA8,m3.getTypeOfCell(4)); + m3.renumberCells(expected1,False); + m4=MEDCouplingExtrudedMesh.New(m3,m1,0); + self.assertEqual(15,m4.getNumberOfCells()); + self.assertEqual(5,m4.getMesh2D().getNumberOfCells()); + self.assertEqual(3,m4.getMesh1D().getNumberOfCells()); + m3DIds=m4.getMesh3DIds().getValues(); + self.assertEqual(expected1,list(m3DIds)); + pass + + def testExtrudedMesh4(self): + m1=MEDCouplingDataForTest.build2DTargetMesh_1(); + cells=[2,4]; + m1.convertToPolyTypes(cells); + m1.changeSpaceDimension(3); + m2=MEDCouplingDataForTest.buildCU1DMesh_U(); + m2.changeSpaceDimension(3); + center=[0.,0.,0.] + vector=[0.,1.,0.] + m2.rotate(center,vector,-pi/2.); + m1.zipCoords() + m3=m1.buildExtrudedMesh(m2,0); + expected1=[1,3,2,0,6,5,7,10,11,8,12,9,14,13,4] + rexpected1=[3, 0, 2, 1, 14, 5, 4, 6, 9, 11, 7, 8, 10, 13, 12] + m3.renumberCells(expected1,False); + m4=MEDCouplingExtrudedMesh.New(m3,m1,0); + self.assertEqual(NORM_HEXA8,m4.getTypeOfCell(0)); + self.assertEqual(NORM_HEXA8,m4.getTypeOfCell(1)); + self.assertEqual(NORM_POLYHED,m4.getTypeOfCell(2)); + self.assertEqual(NORM_PENTA6,m4.getTypeOfCell(7)); + f=m4.getMeasureField(True); + arr=f.getArray(); + self.assertEqual(15,arr.getNumberOfTuples()); + self.assertEqual(1,arr.getNumberOfComponents()); + arrPtr=arr.getValues(); + expected2=[0.075,0.0375,0.0375,0.075,0.075, + 0.1125,0.05625,0.05625,0.1125,0.1125, + 0.0625,0.03125,0.03125,0.0625,0.0625] + for i in xrange(15): + self.assertAlmostEqual(expected2[rexpected1[i]],arrPtr[i],16); + pass + m5=m4.build3DUnstructuredMesh(); + m5.zipCoords() + self.assertTrue(m5.isEqual(m3,1e-12)); + f=m5.getMeasureField(True); + f.setMesh(m4) + self.assertTrue(isinstance(f.getMesh(),MEDCouplingExtrudedMesh)) + arr=f.getArray(); + arrPtr=arr.getValues(); + for i in xrange(15): + self.assertAlmostEqual(expected2[rexpected1[i]],arrPtr[i],15); + pass + pass + + def testFindCommonNodes(self): + targetMesh=MEDCouplingDataForTest.build3DTargetMesh_1(); + comm,commI=targetMesh.findCommonNodes(1e-10,-1); + self.assertEqual(1,commI.getNumberOfTuples()); + self.assertEqual(0,comm.getNumberOfTuples()); + o2n,newNbOfNodes=targetMesh.buildNewNumberingFromCommonNodesFormat(comm,commI); + self.assertEqual(27,newNbOfNodes); + self.assertEqual(27,o2n.getNumberOfTuples()); + o2nExp1=range(27) + self.assertEqual(o2nExp1,list(o2n.getValues())); + # + targetMesh=MEDCouplingDataForTest.build3DTargetMeshMergeNode_1(); + self.assertEqual(31,targetMesh.getNumberOfNodes()); + comm,commI=targetMesh.findCommonNodes(1e-10);# testing default parameter + self.assertEqual(3,commI.getNumberOfTuples()); + self.assertEqual(6,comm.getNumberOfTuples()); + commExpected=[1,27,28,29,23,30] + commIExpected=[0,4,6] + self.assertEqual(commExpected,list(comm.getValues())); + self.assertEqual(commIExpected,list(commI.getValues())); + o2n,newNbOfNodes=targetMesh.buildNewNumberingFromCommonNodesFormat(comm,commI); + self.assertEqual(31,o2n.getNumberOfTuples()); + self.assertEqual(27,newNbOfNodes); + o2nExp2=[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20, + 21,22,23,24,25,26,1,1,1,23] + self.assertEqual(o2nExp2,list(o2n.getValues())); + # + targetMesh=MEDCouplingDataForTest.build3DTargetMesh_1(); + time=targetMesh.getTimeOfThis(); + o2n,areNodesMerged,newNbOfNodes=targetMesh.mergeNodes(1e-10); + targetMesh.updateTime(); + self.assertEqual(time,targetMesh.getTimeOfThis()); + self.assertTrue(not areNodesMerged); + # + targetMesh=MEDCouplingDataForTest.build3DTargetMeshMergeNode_1(); + time=targetMesh.getTimeOfThis(); + o2n,areNodesMerged,newNbOfNodes=targetMesh.mergeNodes(1e-10); + targetMesh.updateTime(); + self.assertTrue(time!=targetMesh.getTimeOfThis()); + self.assertTrue(areNodesMerged); + connExp=[18,0,1,4,3,9,10,13,12, 18,1,2,5,4,10,11,14,13, 18,3,4,7,6,12,13,16,15, + 18,4,5,8,7,13,14,17,16, + 18,9,10,13,12,18,19,22,21, 18,10,11,14,13,19,20,23,22, 18,12,13,16,15,21,22,25,24, + 18,13,14,17,16,22,23,26,25] + self.assertEqual(72,targetMesh.getNodalConnectivity().getNumberOfTuples()); + self.assertEqual(connExp,list(targetMesh.getNodalConnectivity().getValues())); + self.assertEqual(27,targetMesh.getCoords().getNumberOfTuples()); + coordsExp=[ 0., 0., 0., 50., 0., 0. , 200., 0., 0. , 0., 50., 0., 50., 50., 0. , + 200., 50., 0., 0., 200., 0., 50., 200., 0. , 200., 200., 0. , + 0., 0., 50., 50., 0., 50. , 200., 0., 50. , 0., 50., 50., 50., + 50., 50. , 200., 50., 50., 0., 200., 50., 50., 200., 50. , + 200., 200., 50. , 0., 0., 200., 50., 0., 200. , 200., 0., 200. + , 0., 50., 200., 50., 50., 200. , 200., 50., 200., + 0., 200., 200., 50., 200., 200. , 200., 200., 200. ] + self.assertEqual(coordsExp,targetMesh.getCoords().getValues()); + # 2D + targetMesh=MEDCouplingDataForTest.build2DTargetMeshMergeNode_1(); + self.assertEqual(18,targetMesh.getNumberOfNodes()); + time=targetMesh.getTimeOfThis(); + o2n,areNodesMerged,newNbOfNodes=targetMesh.mergeNodes(1e-10); + self.assertTrue(time!=targetMesh.getTimeOfThis()); + self.assertTrue(areNodesMerged); + self.assertEqual(9,targetMesh.getNumberOfNodes()); + connExp2=[4,0,4,3,1, 3,1,3,2, 3,3,5,2, 4,4,6,7,3, 4,7,8,5,3] + self.assertEqual(23,targetMesh.getNodalConnectivity().getNumberOfTuples()); + self.assertEqual(connExp2,list(targetMesh.getNodalConnectivity().getValues())); + coordsExp2=[-0.3,-0.3, 0.2,-0.3, 0.7,-0.3, 0.2,0.2, -0.3,0.2, 0.7,0.2, -0.3,0.7, 0.2,0.7, 0.7,0.7] + self.assertEqual(9,targetMesh.getCoords().getNumberOfTuples()); + self.assertEqual(coordsExp2,targetMesh.getCoords().getValues()); + pass + + def testCheckButterflyCells(self): + sourceMesh=MEDCouplingDataForTest.build2DTargetMesh_1(); + cells=sourceMesh.checkButterflyCells(); + self.assertEqual(0,len(cells)); + conn=sourceMesh.getNodalConnectivity() + tmp=conn.getIJ(15,0) + conn.setIJ(15,0,conn.getIJ(16,0)) + conn.setIJ(16,0,tmp) + cells=sourceMesh.checkButterflyCells(); + self.assertEqual(1,len(cells)); + self.assertEqual([3],cells.getValues()); + tmp=conn.getIJ(15,0) + conn.setIJ(15,0,conn.getIJ(16,0)) + conn.setIJ(16,0,tmp) + cells=sourceMesh.checkButterflyCells(); + self.assertEqual(0,len(cells)); + # 3D surf + sourceMesh=MEDCouplingDataForTest.build3DSurfTargetMesh_1(); + cells=sourceMesh.checkButterflyCells(); + self.assertEqual(0,len(cells)); + conn=sourceMesh.getNodalConnectivity() + tmp=conn.getIJ(15,0) + conn.setIJ(15,0,conn.getIJ(16,0)) + conn.setIJ(16,0,tmp) + cells=sourceMesh.checkButterflyCells(); + self.assertEqual(1,len(cells)); + self.assertEqual([3],cells.getValues()); + tmp=conn.getIJ(15,0) + conn.setIJ(15,0,conn.getIJ(16,0)) + conn.setIJ(16,0,tmp) + cells=sourceMesh.checkButterflyCells(); + self.assertEqual(0,len(cells)); + pass + + def testMergeMesh1(self): + m1=MEDCouplingDataForTest.build2DTargetMesh_1(); + m2=MEDCouplingDataForTest.build2DSourceMesh_1(); + vec=[1.,0.] + m2.translate(vec); + m3=m1.mergeMyselfWith(m2); + self.assertTrue(isinstance(m3,MEDCouplingUMesh)); + m3.checkCoherency(); + m4=MEDCouplingDataForTest.build2DTargetMeshMerged_1(); + self.assertTrue(m3.isEqual(m4,1.e-12)); + da,isMerged,newNbOfNodes=m3.mergeNodes(1.e-12); + self.assertEqual(11,m3.getNumberOfNodes()); + self.assertTrue(isMerged); + pass + + def testMergeMeshOnSameCoords1(self): + m1=MEDCouplingDataForTest.build2DTargetMesh_1(); + m2=MEDCouplingDataForTest.build2DTargetMesh_1(); + cells=range(5); + m2.convertToPolyTypes(cells); + m1.tryToShareSameCoords(m2,1e-12); + m3=MEDCouplingDataForTest.build2DTargetMesh_1(); + m3.tryToShareSameCoords(m2,1e-12); + meshes=[m1,m2,m3] + m4=MEDCouplingUMesh.MergeUMeshesOnSameCoords(meshes); + m4.checkCoherency(); + self.assertEqual(15,m4.getNumberOfCells()); + cells1=[0,1,2,3,4] + m1_1=m4.buildPartOfMySelf(cells1,True); + m1_1.setName(m1.getName()); + self.assertTrue(m1.isEqual(m1_1,1e-12)); + cells2=[5,6,7,8,9] + m2_1=m4.buildPartOfMySelf(cells2,True); + m2_1.setName(m2.getName()); + self.assertTrue(m2.isEqual(m2_1,1e-12)); + cells3=[10,11,12,13,14] + m3_1=m4.buildPartOfMySelf(cells3,True); + m3_1.setName(m3.getName()); + self.assertTrue(m3.isEqual(m3_1,1e-12)); + pass + + def testMergeField1(self): + m1=MEDCouplingDataForTest.build2DTargetMesh_1(); + m2=MEDCouplingDataForTest.build2DSourceMesh_1(); + vec=[1.,0.] + m2.translate(vec); + f1=m1.getMeasureField(True); + f2=m2.getMeasureField(True); + f3=MEDCouplingFieldDouble.MergeFields(f1,f2); + f3.checkCoherency(); + m4=MEDCouplingDataForTest.build2DTargetMeshMerged_1(); + self.assertTrue(f3.getMesh().isEqual(m4,1.e-12)); + name=f3.getName(); + self.assertEqual(name,"MeasureOfMesh_"); + self.assertEqual(f3.getTypeOfField(),ON_CELLS); + self.assertEqual(f3.getTimeDiscretization(),ONE_TIME); + self.assertEqual(1,f3.getNumberOfComponents()); + self.assertEqual(7,f3.getNumberOfTuples()); + values=[0.25,0.125,0.125,0.25,0.25,0.5,0.5] + tmp=f3.getArray().getValues(); + self.assertEqual(len(values),len(tmp)) + for i in xrange(7): + self.assertTrue(abs(values[i]-tmp[i])<1e-12) + pass + pass + + def testFillFromAnalytic(self): + m=MEDCouplingDataForTest.build2DTargetMesh_1(); + m.setTime(3.4,5,6); m.setTimeUnit("us"); + f1=m.fillFromAnalytic(ON_CELLS,1,"x+y"); + self.assertAlmostEqual(3.4,f1.getTime()[0],12) ; self.assertEqual(5,f1.getTime()[1]) ; self.assertEqual(6,f1.getTime()[2]) + self.assertEqual("us",f1.getTimeUnit()) + f1.checkCoherency(); + self.assertEqual(f1.getTypeOfField(),ON_CELLS); + self.assertEqual(f1.getTimeDiscretization(),ONE_TIME); + self.assertEqual(1,f1.getNumberOfComponents()); + self.assertEqual(5,f1.getNumberOfTuples()); + values1=[-0.1,0.23333333333333336,0.56666666666666665,0.4,0.9] + tmp=f1.getArray().getValues(); + self.assertEqual(len(values1),len(tmp)) + for i in xrange(len(tmp)): + self.assertTrue(abs(tmp[i]-values1[i])<1.e-12) + pass + # + f1=m.fillFromAnalytic(ON_NODES,1,"x+y"); + f1.checkCoherency(); + self.assertEqual(f1.getTypeOfField(),ON_NODES); + self.assertEqual(f1.getTimeDiscretization(),ONE_TIME); + self.assertEqual(1,f1.getNumberOfComponents()); + self.assertEqual(9,f1.getNumberOfTuples()); + values2=[-0.6,-0.1,0.4,-0.1,0.4,0.9,0.4,0.9,1.4] + tmp=f1.getArray().getValues(); + self.assertEqual(len(values2),len(tmp)) + for i in xrange(len(tmp)): + self.assertTrue(abs(tmp[i]-values2[i])<1.e-12) + pass + # + f1=m.fillFromAnalytic(ON_NODES,2,"(x+y)*IVec+(2*(x+y))*JVec"); + f1.checkCoherency(); + self.assertEqual(f1.getTypeOfField(),ON_NODES); + self.assertEqual(f1.getTimeDiscretization(),ONE_TIME); + self.assertEqual(2,f1.getNumberOfComponents()); + self.assertEqual(9,f1.getNumberOfTuples()); + values3=[-0.6,-1.2,-0.1,-0.2,0.4,0.8,-0.1,-0.2,0.4,0.8,0.9,1.8,0.4,0.8,0.9,1.8,1.4,2.8] + tmp=f1.getArray().getValues(); + self.assertEqual(len(values3),len(tmp)) + for i in xrange(len(tmp)): + self.assertTrue(abs(tmp[i]-values3[i])<1.e-12) + pass + values4=f1.accumulate(); + self.assertEqual(2,len(values4)) + self.assertTrue(abs(3.6-values4[0])<1.e-12); + self.assertTrue(abs(7.2-values4[1])<1.e-12); + values4=f1.integral(True); + self.assertEqual(2,len(values4)) + self.assertTrue(abs(0.5-values4[0])<1.e-12); + self.assertTrue(abs(1.-values4[1])<1.e-12); + # + self.assertRaises(InterpKernelException,m.fillFromAnalytic,ON_NODES,1,"1./(x-0.2)"); + pass + + def testFillFromAnalytic2(self): + m=MEDCouplingDataForTest.build2DTargetMesh_1(); + f1=m.fillFromAnalytic(ON_CELLS,1,"y+x"); + f1.checkCoherency(); + self.assertEqual(f1.getTypeOfField(),ON_CELLS); + self.assertEqual(f1.getTimeDiscretization(),ONE_TIME); + self.assertEqual(1,f1.getNumberOfComponents()); + self.assertEqual(5,f1.getNumberOfTuples()); + values1=[-0.1,0.23333333333333336,0.56666666666666665,0.4,0.9] + tmp=f1.getArray().getValues(); + self.assertEqual(len(values1),len(tmp)) + for i in xrange(len(values1)): + self.assertTrue(abs(values1[i]-tmp[i])<1.e-12); + pass + # + f1=m.fillFromAnalytic(ON_NODES,1,"y+2*x"); + f1.checkCoherency(); + self.assertEqual(f1.getTypeOfField(),ON_NODES); + self.assertEqual(f1.getTimeDiscretization(),ONE_TIME); + self.assertEqual(1,f1.getNumberOfComponents()); + self.assertEqual(9,f1.getNumberOfTuples()); + values2=[-0.9,0.1,1.1,-0.4,0.6,1.6,0.1,1.1,2.1] + tmp=f1.getArray().getValues(); + self.assertEqual(len(values2),len(tmp)) + for i in xrange(len(values2)): + self.assertTrue(abs(values2[i]-tmp[i])<1.e-12); + pass + f1=m.fillFromAnalytic(ON_NODES,1,"2.*x+y"); + f1.checkCoherency(); + self.assertEqual(f1.getTypeOfField(),ON_NODES); + self.assertEqual(f1.getTimeDiscretization(),ONE_TIME); + self.assertEqual(1,f1.getNumberOfComponents()); + self.assertEqual(9,f1.getNumberOfTuples()); + tmp=f1.getArray().getValues(); + values2Bis=[-0.9,0.1,1.1,-0.4,0.6,1.6,0.1,1.1,2.1] + self.assertEqual(len(values2Bis),len(tmp)) + for i in xrange(len(values2Bis)): + self.assertTrue(abs(values2Bis[i]-tmp[i])<1.e-12); + pass + # + f1=m.fillFromAnalytic(ON_NODES,2,"(x+y)*IVec+2*(x+y)*JVec"); + f1.checkCoherency(); + self.assertEqual(f1.getTypeOfField(),ON_NODES); + self.assertEqual(f1.getTimeDiscretization(),ONE_TIME); + self.assertEqual(2,f1.getNumberOfComponents()); + self.assertEqual(9,f1.getNumberOfTuples()); + values3=[-0.6,-1.2,-0.1,-0.2,0.4,0.8,-0.1,-0.2,0.4,0.8,0.9,1.8,0.4,0.8,0.9,1.8,1.4,2.8] + tmp=f1.getArray().getValues(); + self.assertEqual(len(values3),len(tmp)) + for i in xrange(len(values3)): + self.assertTrue(abs(values3[i]-tmp[i])<1.e-12); + pass + values4=f1.accumulate(); + self.assertTrue(abs(3.6-values4[0])<1.e-12); + self.assertTrue(abs(7.2-values4[1])<1.e-12); + values4=f1.integral(True); + self.assertTrue(abs(0.5-values4[0])<1.e-12); + self.assertTrue(abs(1.-values4[1])<1.e-12); + pass + + def testApplyFunc(self): + m=MEDCouplingDataForTest.build2DTargetMesh_1(); + f1=m.fillFromAnalytic(ON_NODES,2,"(x+y)*IVec+(2*(x+y))*JVec"); + f1.checkCoherency(); + self.assertEqual(f1.getTypeOfField(),ON_NODES); + self.assertEqual(f1.getTimeDiscretization(),ONE_TIME); + self.assertEqual(2,f1.getNumberOfComponents()); + self.assertEqual(9,f1.getNumberOfTuples()); + f1.applyFunc(1,"x+y"); + self.assertEqual(f1.getTypeOfField(),ON_NODES); + self.assertEqual(f1.getTimeDiscretization(),ONE_TIME); + self.assertEqual(1,f1.getNumberOfComponents()); + self.assertEqual(9,f1.getNumberOfTuples()); + values1=[-1.8,-0.3,1.2,-0.3,1.2,2.7,1.2,2.7,4.2] + tmp=f1.getArray().getValues(); + self.assertEqual(len(values1),len(tmp)) + for i in xrange(len(tmp)): + self.assertTrue(abs(tmp[i]-values1[i])<1.e-12) + pass + pass + + def testApplyFunc2(self): + m=MEDCouplingDataForTest.build2DTargetMesh_1(); + f1=m.fillFromAnalytic(ON_NODES,2,"(x+y)*IVec+2*(x+y)*JVec"); + f1.checkCoherency(); + self.assertEqual(f1.getTypeOfField(),ON_NODES); + self.assertEqual(f1.getTimeDiscretization(),ONE_TIME); + self.assertEqual(2,f1.getNumberOfComponents()); + self.assertEqual(9,f1.getNumberOfTuples()); + # + f2=f1.clone(True); + self.assertRaises(InterpKernelException, f2.applyFunc, 1, "a+b+c+d"); + self.assertRaises(InterpKernelException, f2.applyFunc, 1, "a/0"); + self.assertRaises(InterpKernelException, f2.applyFunc, "a/0"); + f2.applyFunc("abs(u)^2.4+2*u"); + self.assertEqual(f1.getTypeOfField(),ON_NODES); + self.assertEqual(f1.getTimeDiscretization(),ONE_TIME); + self.assertEqual(2,f1.getNumberOfComponents()); + self.assertEqual(9,f1.getNumberOfTuples()); + values2=[-0.9065304805418678, -0.85105859001709905, -0.19601892829446504, -0.37898777756476987, + 0.91090317490482353, 2.1853504664669781, -0.19601892829446504, -0.37898777756476987, + 0.91090317490482353, 2.1853504664669781, 2.5765725275664879, 7.6987743736515295, + 0.91090317490482353, 2.1853504664669781, 2.5765725275664879, 7.6987743736515295, + 5.0423700574830965, 17.435300118916864] + tmp=f2.getArray().getValues(); + self.assertEqual(len(tmp),len(values2)) + for i in xrange(len(tmp)): + self.assertTrue(abs(tmp[i]-values2[i])<1.e-12) + pass + # + f1.applyFunc(1,"x+y"); + self.assertEqual(f1.getTypeOfField(),ON_NODES); + self.assertEqual(f1.getTimeDiscretization(),ONE_TIME); + self.assertEqual(1,f1.getNumberOfComponents()); + self.assertEqual(9,f1.getNumberOfTuples()); + values1=[-1.8,-0.3,1.2,-0.3,1.2,2.7,1.2,2.7,4.2] + tmp=f1.getArray().getValues(); + self.assertEqual(len(tmp),len(values1)) + for i in xrange(len(tmp)): + self.assertTrue(abs(tmp[i]-values1[i])<1.e-12) + pass + pass + + def testOperationsOnFields(self): + m=MEDCouplingDataForTest.build2DTargetMesh_1(); + f1=m.fillFromAnalytic(ON_NODES,1,"x+y"); + f2=m.fillFromAnalytic(ON_NODES,1,"x+y"); + f1.checkCoherency(); + f2.checkCoherency(); + f3=f1+f2; + f3.checkCoherency(); + self.assertEqual(f3.getTypeOfField(),ON_NODES); + self.assertEqual(f3.getTimeDiscretization(),ONE_TIME); + values1=[-1.2,-0.2,0.8,-0.2,0.8,1.8,0.8,1.8,2.8] + tmp=f3.getArray().getValues(); + self.assertEqual(len(values1),len(tmp)) + for i in xrange(len(tmp)): + self.assertTrue(abs(tmp[i]-values1[i])<1.e-12) + pass + # + f3=f1*f2; + f3.checkCoherency(); + self.assertEqual(f3.getTypeOfField(),ON_NODES); + self.assertEqual(f3.getTimeDiscretization(),ONE_TIME); + values2=[0.36,0.01,0.16,0.01,0.16,0.81,0.16,0.81,1.96] + tmp=f3.getArray().getValues(); + self.assertEqual(len(values2),len(tmp)) + for i in xrange(len(tmp)): + self.assertTrue(abs(tmp[i]-values2[i])<1.e-12) + pass + # + f3=f1+f2; + f4=f1-f3; + f4.checkCoherency(); + self.assertEqual(f4.getTypeOfField(),ON_NODES); + self.assertEqual(f4.getTimeDiscretization(),ONE_TIME); + values3=[0.6,0.1,-0.4,0.1,-0.4,-0.9,-0.4,-0.9,-1.4] + tmp=f4.getArray().getValues(); + self.assertEqual(len(values3),len(tmp)) + for i in xrange(len(tmp)): + self.assertTrue(abs(tmp[i]-values3[i])<1.e-12) + pass + # + f3=f1+f2; + f4=f3/f2; + f4.checkCoherency(); + self.assertEqual(f4.getTypeOfField(),ON_NODES); + self.assertEqual(f4.getTimeDiscretization(),ONE_TIME); + tmp=f4.getArray().getValues(); + for i in xrange(len(tmp)): + self.assertTrue(abs(tmp[i]-2.)<1.e-12) + pass + # + f4=f2.buildNewTimeReprFromThis(NO_TIME,False); + f4.checkCoherency(); + self.assertEqual(f4.getTypeOfField(),ON_NODES); + self.assertEqual(f4.getTimeDiscretization(),NO_TIME); + self.assertRaises(InterpKernelException,f1.__add__,f4); + f5=f4.buildNewTimeReprFromThis(ONE_TIME,False); + self.assertEqual(f5.getTypeOfField(),ON_NODES); + self.assertEqual(f5.getTimeDiscretization(),ONE_TIME); + f3=f1+f5; + tmp=f3.getArray().getValues(); + values4=[-1.2,-0.2,0.8,-0.2,0.8,1.8,0.8,1.8,2.8] + self.assertEqual(len(values3),len(tmp)) + for i in xrange(len(tmp)): + self.assertTrue(abs(tmp[i]-values4[i])<1.e-12) + pass + # + f4=f2.buildNewTimeReprFromThis(NO_TIME,True); + f4.checkCoherency(); + self.assertEqual(f4.getTypeOfField(),ON_NODES); + self.assertEqual(f4.getTimeDiscretization(),NO_TIME); + self.assertRaises(InterpKernelException,f1.__add__,f4); + f5=f4.buildNewTimeReprFromThis(ONE_TIME,True); + self.assertEqual(f5.getTypeOfField(),ON_NODES); + self.assertEqual(f5.getTimeDiscretization(),ONE_TIME); + f3=f1+f5; + tmp=f3.getArray().getValues(); + values5=[-1.2,-0.2,0.8,-0.2,0.8,1.8,0.8,1.8,2.8] + self.assertEqual(len(values5),len(tmp)) + for i in xrange(len(tmp)): + self.assertTrue(abs(tmp[i]-values5[i])<1.e-12) + pass + pass + + def testOperationsOnFields2(self): + m=MEDCouplingDataForTest.build3DSurfTargetMesh_1(); + m.setTime(3.4,5,6); m.setTimeUnit("us"); + f1=m.fillFromAnalytic(ON_NODES,1,"x+y+z"); + f2=m.fillFromAnalytic(ON_NODES,1,"a*a+b+c*c"); + f3=f1/f2; + f3.checkCoherency(); + self.assertEqual(f3.getTypeOfField(),ON_NODES); + self.assertEqual(f3.getTimeDiscretization(),ONE_TIME); + expected1=[-2.4999999999999991, 1.2162162162162162, 0.77868852459016391, + 0.7407407407407407, 1.129032258064516, 0.81632653061224492, + 0.86538461538461531, 1.0919540229885056, 0.84302325581395343] + self.assertEqual(1,f3.getNumberOfComponents()); + self.assertEqual(9,f3.getNumberOfTuples()); + val=f3.getArray().getValues(); + for i in xrange(9): + self.assertTrue(abs(expected1[i]-val[i])<1.e-12); + # + f1=m.buildOrthogonalField(); + self.assertAlmostEqual(3.4,f1.getTime()[0],12) ; self.assertEqual(5,f1.getTime()[1]) ; self.assertEqual(6,f1.getTime()[2]) + self.assertEqual("us",f1.getTimeUnit()) + f2=m.fillFromAnalytic(ON_CELLS,1,"x"); + f3=f1*f2; + expected2=[-0.035355339059327376,0.,0.035355339059327376, 0.2592724864350674,0.,-0.2592724864350674, 0.37712361663282529,0.,-0.37712361663282529, -0.035355339059327376,0.,0.035355339059327376, 0.31819805153394637,0.,-0.31819805153394637] + val=f3.getArray().getValues(); + for i in xrange(15): + self.assertTrue(abs(expected2[i]-val[i])<1.e-12); + pass + # + f3=f2*f1; + val=f3.getArray().getValues(); + for i in xrange(15): + self.assertTrue(abs(expected2[i]-val[i])<1.e-12); + pass + pass + + def testOperationsOnFields3(self): + m=MEDCouplingDataForTest.build3DSurfTargetMesh_1(); + f1=m.fillFromAnalytic(ON_NODES,1,"x+y+z"); + f2=m.fillFromAnalytic(ON_NODES,1,"a*a+b+c*c"); + f1/=f2 + f1.checkCoherency(); + self.assertEqual(f1.getTypeOfField(),ON_NODES); + self.assertEqual(f1.getTimeDiscretization(),ONE_TIME); + expected1=[-2.4999999999999991, 1.2162162162162162, 0.77868852459016391, + 0.7407407407407407, 1.129032258064516, 0.81632653061224492, + 0.86538461538461531, 1.0919540229885056, 0.84302325581395343] + self.assertEqual(1,f1.getNumberOfComponents()); + self.assertEqual(9,f1.getNumberOfTuples()); + val=f1.getArray().getValues(); + for i in xrange(9): + self.assertTrue(abs(expected1[i]-val[i])<1.e-12); + pass + # + f1=m.buildOrthogonalField(); + f2=m.fillFromAnalytic(ON_CELLS,1,"x"); + f1*=f2 + expected2=[-0.035355339059327376,0.,0.035355339059327376, 0.2592724864350674,0.,-0.2592724864350674, 0.37712361663282529,0.,-0.37712361663282529, -0.035355339059327376,0.,0.035355339059327376, 0.31819805153394637,0.,-0.31819805153394637] + val=f1.getArray().getValues(); + for i in xrange(15): + self.assertTrue(abs(expected2[i]-val[i])<1.e-12); + pass + # + f1=m.buildOrthogonalField(); + # to avoid valgrind leaks + # self.assertRaises(InterpKernelException,f2.__imul__,f1); + pass + + def testOperationsOnFields4(self): + m=MEDCouplingDataForTest.build2DTargetMesh_1(); + nbOfCells=m.getNumberOfCells(); + f1=MEDCouplingFieldDouble.New(ON_CELLS,CONST_ON_TIME_INTERVAL); + f1.setMesh(m); + array=DataArrayDouble.New(); + f1.setArray(array); + self.assertRaises(InterpKernelException,f1.setEndArray,array); + self.assertRaises(InterpKernelException,f1.getEndArray); + arr1=[0.,10.,20.,1.,11.,21.,2.,12.,22.,3.,13.,23.,4.,14.,24.] + arr2=[5.,15.,25.,6.,16.,26.,7.,17.,27.,8.,18.,28.,9.,19.,29.] + array.setValues(arr1,nbOfCells,3); + f1.setStartTime(2.,0,0); + f1.setEndTime(3.,0,0); + f1.checkCoherency(); + pos=[0.3,-0.2] + res=f1.getValueOn(pos); + self.assertTrue(abs(arr1[3]-res[0])<1.e-12); + self.assertTrue(abs(arr1[4]-res[1])<1.e-12); + self.assertTrue(abs(arr1[5]-res[2])<1.e-12); + res=None + res=f1.getValueOn(pos,2.2); + self.assertTrue(abs(arr1[3]-res[0])<1.e-12); + self.assertTrue(abs(arr1[4]-res[1])<1.e-12); + self.assertTrue(abs(arr1[5]-res[2])<1.e-12); + res=None + self.assertRaises(InterpKernelException,f1.getValueOn,pos,3.2) + f2=MEDCouplingFieldDouble.New(ON_CELLS,LINEAR_TIME); + f2.setMesh(m); + f2.setArray(f1.getArray()); + f2.setStartTime(2.,3,0); + f2.setEndTime(4.,13,0); + self.assertRaises(InterpKernelException,f2.checkCoherency) + array2=DataArrayDouble.New(); + array2.setValues(arr2,nbOfCells,3); + f2.setEndArray(array2); + f2.checkCoherency(); + # + res=None + res=f2.getValueOn(pos,3.21); + self.assertTrue(abs(4.025-res[0])<1.e-12); + self.assertTrue(abs(14.025-res[1])<1.e-12); + self.assertTrue(abs(24.025-res[2])<1.e-12); + f3=f2.clone(True); + self.assertTrue(f2.isEqual(f3,1e-12,1e-12)); + f3.getEndArray().setIJ(0,0,5.001); + self.assertTrue(not f2.isEqual(f3,1e-12,1e-12)); + self.assertTrue(f2.isEqual(f3,1e-12,1e-2)); + f3.setStartTime(2.1,3,0); + self.assertTrue(not f2.isEqual(f3,1e-12,1e-2)); + f3.setStartTime(2.,3,0); + self.assertTrue(f2.isEqual(f3,1e-12,1e-2)); + f3.setStartTime(2.,4,0); + self.assertTrue(not f2.isEqual(f3,1e-12,1e-2)); + f3.setStartTime(2.,3,1); + self.assertTrue(not f2.isEqual(f3,1e-12,1e-2)); + f3.setStartTime(2.,3,0); + self.assertTrue(f2.isEqual(f3,1e-12,1e-2)); + f3.setEndTime(4.1,13,0); + self.assertTrue(not f2.isEqual(f3,1e-12,1e-2)); + f3.setEndTime(4.,13,0); + self.assertTrue(f2.isEqual(f3,1e-12,1e-2)); + f3.setEndTime(4.,14,0); + self.assertTrue(not f2.isEqual(f3,1e-12,1e-2)); + f3.setEndTime(4.,13,1); + self.assertTrue(not f2.isEqual(f3,1e-12,1e-2)); + f3.setEndTime(4.,13,0); + self.assertTrue(f2.isEqual(f3,1e-12,1e-2)); + f4=f2+f2 + res=None + res=f4.getValueOn(pos,3.21); + self.assertTrue(abs(8.05-res[0])<1.e-12); + self.assertTrue(abs(28.05-res[1])<1.e-12); + self.assertTrue(abs(48.05-res[2])<1.e-12); + f4+=f2; + res=None + res=f4.getValueOn(pos,3.21); + self.assertTrue(abs(12.075-res[0])<1.e-12); + self.assertTrue(abs(42.075-res[1])<1.e-12); + self.assertTrue(abs(72.075-res[2])<1.e-12); + pass + + def testMergeNodesOnField(self): + targetMesh=MEDCouplingDataForTest.build3DTargetMeshMergeNode_1(); + f1=targetMesh.fillFromAnalytic(ON_NODES,1,"x+y+z"); + f1.mergeNodes(1e-10); + # + targetMesh=MEDCouplingDataForTest.build3DTargetMeshMergeNode_1(); + f1=targetMesh.fillFromAnalytic(ON_NODES,1,"x+y+z"); + tmp=f1.getArray() + tmp.setIJ(0,0,1000.); + f1.mergeNodes(1e-10); + # + targetMesh=MEDCouplingDataForTest.build3DTargetMeshMergeNode_1(); + f1=targetMesh.fillFromAnalytic(ON_NODES,1,"x+y+z"); + tmp=f1.getArray() + tmp.setIJ(1,0,1000.); + self.assertRaises(InterpKernelException,f1.mergeNodes,1.e-10) + pass + + def testCheckConsecutiveCellTypes(self): + sourceMesh=MEDCouplingDataForTest.build2DSourceMesh_1(); + targetMesh=MEDCouplingDataForTest.build2DTargetMesh_1(); + self.assertTrue(sourceMesh.checkConsecutiveCellTypes()); + order1=[NORM_TRI3,NORM_QUAD4] + order2=[NORM_QUAD4,NORM_TRI3] + self.assertTrue(not targetMesh.checkConsecutiveCellTypes()); + self.assertTrue(not targetMesh.checkConsecutiveCellTypesAndOrder(order1)); + self.assertTrue(not targetMesh.checkConsecutiveCellTypesAndOrder(order2)); + da=targetMesh.getRenumArrForConsecutiveCellTypesSpec(order1); + self.assertEqual(5,da.getNumberOfTuples()); + self.assertEqual(1,da.getNumberOfComponents()); + expected1=[2,0,1,3,4] + self.assertTrue(expected1==list(da.getValues())); + da=targetMesh.getRenumArrForConsecutiveCellTypesSpec(order2); + self.assertEqual(5,da.getNumberOfTuples()); + self.assertEqual(1,da.getNumberOfComponents()); + expected2=[0,3,4,1,2] + self.assertTrue(expected2==list(da.getValues())); + renumber1=[4,0,1,2,3] + targetMesh.renumberCells(renumber1,False); + self.assertTrue(targetMesh.checkConsecutiveCellTypes()); + self.assertTrue(targetMesh.checkConsecutiveCellTypesAndOrder(order1)); + self.assertTrue(not targetMesh.checkConsecutiveCellTypesAndOrder(order2)); + pass + + def testRearrange2ConsecutiveCellTypes(self): + m1_1=MEDCouplingDataForTest.build2DSourceMesh_1(); + m2_1=MEDCouplingDataForTest.build2DTargetMesh_1(); + arr1=m1_1.rearrange2ConsecutiveCellTypes(); + m1_2=MEDCouplingDataForTest.build2DSourceMesh_1(); + self.assertTrue(m1_2.isEqual(m1_1,1e-12)); + expected1=[0,1] + self.assertEqual(2,arr1.getNumberOfTuples()); + self.assertEqual(1,arr1.getNumberOfComponents()); + self.assertEqual(expected1,arr1.getValues()); + expected2=[0,3,4,1,2] + arr1=m2_1.rearrange2ConsecutiveCellTypes(); + self.assertEqual(5,arr1.getNumberOfTuples()); + self.assertEqual(1,arr1.getNumberOfComponents()); + self.assertEqual(expected2,list(arr1.getValues())); + m2_2=MEDCouplingDataForTest.build2DTargetMesh_1(); + self.assertEqual(5,arr1.getNumberOfTuples()); + self.assertEqual(1,arr1.getNumberOfComponents()); + self.assertEqual(expected2,list(arr1.getValues())); + self.assertTrue(not m2_2.isEqual(m2_1,1e-12)); + m2_2.renumberCells(expected2,False); + self.assertTrue(m2_2.isEqual(m2_1,1e-12)); + pass + + def testSplitByType(self): + m1=MEDCouplingDataForTest.build3DSurfTargetMesh_1(); + v=m1.splitByType(); + self.assertEqual(3,len(v)); + m2=MEDCouplingUMesh.MergeUMeshesOnSameCoords(v); + m2.setName(m1.getName()); + self.assertTrue(m1.isEqual(m2,1.e-12)); + pass + + def testFuseUMeshesOnSameCoords(self): + m2=MEDCouplingDataForTest.build2DTargetMesh_1(); + cells1=[2,3,4] + m3=m2.buildPartOfMySelf(cells1,True); + self.assertTrue(isinstance(m3,MEDCouplingUMesh)) + cells2=[1,2,4] + m4=m2.buildPartOfMySelf(cells2,True); + self.assertTrue(isinstance(m4,MEDCouplingUMesh)) + cells3=[1,2] + m5=m2.buildPartOfMySelf(cells3,True); + self.assertTrue(isinstance(m5,MEDCouplingUMesh)) + meshes=[m3,m4,m5] + # + m7,corr=MEDCouplingUMesh.FuseUMeshesOnSameCoords(meshes,0); + self.assertEqual(4,m7.getNumberOfCells()); + self.assertEqual(3,len(corr)); + expectedVals1=[3,3,2] + expectedVals2=[[0,1,2],[3,0,2],[3,0]] + for i in xrange(3): + arr=corr[i]; + self.assertEqual(1,arr.getNumberOfComponents()); + nbOfVals=expectedVals1[i]; + self.assertEqual(nbOfVals,arr.getNumberOfTuples()); + vals=arr.getValues(); + self.assertEqual(expectedVals2[i],list(vals)); + pass + arr2,fidsOfGroups=DataArrayInt.MakePartition(corr,m7.getNumberOfCells()); + fidExp=[5,1,3,4] + fidsGrp=[[1,3,5],[3,4,5],[4,5]] + self.assertEqual(3,len(fidsOfGroups)); + self.assertEqual(1,arr2.getNumberOfComponents()); + self.assertEqual(4,arr2.getNumberOfTuples()); + self.assertEqual(fidExp,list(arr2.getValues())); + for i in xrange(3): + nbOfVals=expectedVals1[i]; + self.assertEqual(list(fidsOfGroups[i]),fidsGrp[i]); + pass + pass + + def testFuseUMeshesOnSameCoords2(self): + m1,m2=MEDCouplingDataForTest.build3DExtrudedUMesh_1(); + part1=[2,3,6,4,10] + m3=m1.buildPartOfMySelf(part1,True); + part2=[5,6,4,7] + m4=m1.buildPartOfMySelf(part2,True); + meshes=[m1,m3,m3,m4] + m5,corr=MEDCouplingUMesh.FuseUMeshesOnSameCoords(meshes,0); + self.assertEqual(18,m5.getNumberOfCells()); + exp2=[ + [0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17], + [2,3,6,4,10], + [2,3,6,4,10], + [5,6,4,7]] + i=0; + for it in corr: + self.assertEqual(exp2[i],list(it.getValues())); + i+=1 + pass + pass + + def testBuildOrthogonalField(self): + targetMesh=MEDCouplingDataForTest.build3DSurfTargetMesh_1(); + field=targetMesh.buildOrthogonalField(); + expected=[0.70710678118654746,0.,-0.70710678118654746] + self.assertEqual(5,field.getNumberOfTuples()); + self.assertEqual(3,field.getNumberOfComponents()); + vals=field.getArray().getValues(); + for i in xrange(15): + self.assertTrue(abs(expected[i%3]-vals[i])<1e-12); + # testing + targetCoords=[0.,0.,0.,0.5,0.,0.5,1.,0.,1.,0.,1.,0.] + targetConn=[0,1,2,3] + targetMesh=MEDCouplingUMesh.New(); + targetMesh.setMeshDimension(2); + targetMesh.allocateCells(1); + targetMesh.insertNextCell(NORM_QUAD4,targetConn[0:4]) + targetMesh.finishInsertingCells(); + myCoords=DataArrayDouble.New(); + myCoords.setValues(targetCoords,4,3); + targetMesh.setCoords(myCoords); + field=targetMesh.buildOrthogonalField(); + self.assertEqual(1,field.getNumberOfTuples()); + self.assertEqual(3,field.getNumberOfComponents()); + vals=field.getArray().getValues(); + self.assertTrue(abs(-0.70710678118654746-vals[0])<1e-12); + self.assertTrue(abs(0.-vals[1])<1e-12); + self.assertTrue(abs(0.70710678118654746-vals[2])<1e-12); + pass + + def testGetCellsContainingPoint(self): + targetMesh=MEDCouplingDataForTest.build2DTargetMesh_1(); + pos=[0.,0.,0.4,0.4,0.,0.4,0.1,0.1,0.25,0.,0.65,0.] + #2D basic + t1,t2=targetMesh.getCellsContainingPoints(pos,6,1e-12); + self.assertEqual(6,t1.getNumberOfTuples()); + self.assertEqual(1,t1.getNumberOfComponents()); + self.assertEqual(7,t2.getNumberOfTuples()); + self.assertEqual(1,t2.getNumberOfComponents()); + expectedValues1=[0,4,3,0,1,2] + expectedValues2=[0,1,2,3,4,5,6] + self.assertEqual(list(t1.getValues()),expectedValues1); + self.assertEqual(list(t2.getValues()),expectedValues2); + #2D with no help of bounding box. + center=[0.2,0.2] + MEDCouplingPointSet.Rotate2DAlg(center,0.78539816339744830962,6,pos); + targetMesh.rotate(center,0.78539816339744830962); + t1=None + t2=None + t1,t2=targetMesh.getCellsContainingPoints(pos,1e-12); + self.assertEqual(6,t1.getNumberOfTuples()); + self.assertEqual(7,t2.getNumberOfTuples()); + self.assertEqual(list(t1.getValues()),expectedValues1); + self.assertEqual(list(t2.getValues()),expectedValues2); + t1,t2=targetMesh.getCellsContainingPoints(DataArrayDouble.New(pos,6,2),1e-12); + self.assertEqual(6,t1.getNumberOfTuples()); + self.assertEqual(7,t2.getNumberOfTuples()); + self.assertEqual(list(t1.getValues()),expectedValues1); + self.assertEqual(list(t2.getValues()),expectedValues2); + self.assertRaises(InterpKernelException,targetMesh.getCellsContainingPoints,DataArrayDouble.New(pos,4,3),1e-12); + #2D outside + pos1bis=[-0.3303300858899107,-0.11819805153394641] + self.assertEqual(-1,targetMesh.getCellContainingPoint(pos1bis,1e-12)); + #test limits 2D + targetMesh=MEDCouplingDataForTest.build2DTargetMesh_1(); + pos2=[0.2,-0.05] + t1=None + t1=targetMesh.getCellsContainingPoint(pos2,1e-12) + self.assertEqual(2,len(t1)); + expectedValues3=[0,1] + self.assertEqual(list(t1.getValues()),expectedValues3); + pos3=[0.2,0.2] + t1=None + t1=targetMesh.getCellsContainingPoint(pos3,1e-12); + self.assertEqual(5,len(t1)); + expectedValues4=[0,1,2,3,4] + self.assertEqual(list(t1.getValues()),expectedValues4); + self.assertEqual(0,targetMesh.getCellContainingPoint(pos3,1e-12)); + #3D + targetMesh=MEDCouplingDataForTest.build3DTargetMesh_1(); + pos4=[25.,25.,25.] + self.assertEqual(0,targetMesh.getCellContainingPoint(pos4,1e-12)); + pos5=[50.,50.,50.] + t1=None + t1=targetMesh.getCellsContainingPoint(pos5,1e-12); + self.assertEqual(8,len(t1)); + expectedValues5=[0,1,2,3,4,5,6,7] + self.assertEqual(list(t1.getValues()),expectedValues5); + pos6=[0., 50., 0.] + t1=None + t1=targetMesh.getCellsContainingPoint(pos6,1e-12); + self.assertEqual(2,len(t1)); + expectedValues6=[0,2] + self.assertEqual(list(t1.getValues()),expectedValues6); + #3D outside + pos7=[-1.0,-1.0,0.] + self.assertEqual(-1,targetMesh.getCellContainingPoint(pos7,1e-12)); + #3D outside 2 + center2=[0.,0.,0.] + vec2=[0.,-1.,0.] + targetMesh.rotate(center2,vec2,0.78539816339744830962); + pos8=[-25.,25.,12.] + self.assertEqual(-1,targetMesh.getCellContainingPoint(pos8,1e-12)); + pass + + def testGetValueOn1(self): + targetMesh=MEDCouplingDataForTest.build2DTargetMesh_1(); + fieldOnCells=MEDCouplingFieldDouble.New(ON_CELLS); + nbOfCells=targetMesh.getNumberOfCells(); + fieldOnCells.setMesh(targetMesh); + array=DataArrayDouble.New(); + tmp=2*nbOfCells*[None] + for i in xrange(nbOfCells): + tmp[2*i]=7.+float(i); + tmp[2*i+1]=17.+float(i) + pass + array.setValues(tmp,nbOfCells,2); + fieldOnCells.setArray(array); + # + pos1=[0.25,0.] + res=fieldOnCells.getValueOn(pos1); + self.assertEqual(2,len(res)) + self.assertTrue(abs(8.-res[0])<1e-12); + self.assertTrue(abs(18.-res[1])<1e-12); + # + # + targetMesh=MEDCouplingDataForTest.build2DSourceMesh_1(); + fieldOnNodes=MEDCouplingFieldDouble.New(ON_NODES); + nbOfNodes=targetMesh.getNumberOfNodes(); + fieldOnNodes.setMesh(targetMesh); + array=DataArrayDouble.New(); + tmp=2*nbOfNodes*[None] + for i in xrange(nbOfNodes): + tmp[2*i]=17.+float(i); + tmp[2*i+1]=27.+float(i) + pass + array.setValues(tmp,nbOfNodes,2); + fieldOnNodes.setArray(array); + # + pos2=[-0.13333333333333333,-0.13333333333333333] + res=None + res=fieldOnNodes.getValueOn(pos2); + self.assertEqual(2,len(res)) + self.assertTrue(abs(17.5-res[0])<1e-12); + self.assertTrue(abs(27.5-res[1])<1e-12); + pos3=[0.033333333333333326,0.36666666666666664] + res=None + res=fieldOnNodes.getValueOn(pos3); + self.assertEqual(2,len(res)) + self.assertTrue(abs(18.666666666666667-res[0])<1e-12); + self.assertTrue(abs(28.666666666666667-res[1])<1e-12); + pass + + def testCMesh0(self): + mesh=MEDCouplingCMesh.New(); + meshEmpty=mesh.clone(True); + self.assertTrue(meshEmpty.isEqual(mesh, 1e-12)); + + coordsX=DataArrayDouble.New(); + arrX=[ -1., 1., 2., 4. ] + coordsX.setValues(arrX, 4, 1); + coordsY=DataArrayDouble.New(); + arrY=[ -2., 2., 4., 8. ] + coordsY.setValues(arrY, 4, 1); + coordsZ=DataArrayDouble.New(); + arrZ=[ -3., 3., 6., 12. ] + coordsZ.setValues(arrZ, 4, 1); + mesh.setCoords(coordsX, coordsY, coordsZ); + # + fieldOnNodes=mesh.fillFromAnalytic(ON_NODES, 1, "x+y/2.+z/3."); + self.assertEqual(1, fieldOnNodes.getNumberOfComponents()); + self.assertEqual(64, fieldOnNodes.getNumberOfTuples()); + expected1=[-3., -1., 0., 2., -1., 1., 2., 4., 0., 2., 3., 5., 2., 4., 5., 7., -1., 1., 2., + 4., 1., 3., 4., 6., 2., 4., 5., 7., 4., 6., 7., 9., 0., 2., 3., 5., 2., 4., 5., + 7., 3., 5., 6., 8., 5., 7., 8., 10., 2., 4., 5., + 7., 4., 6., 7., 9., 5., 7., 8., 10., 7., 9., 10., 12.]; + + val=fieldOnNodes.getArray().getValues(); + for i in xrange(64): + self.assertAlmostEqual(expected1[i], val[i], 12) + res=fieldOnNodes.getValueOnPos(1, 3, 2); + self.assertAlmostEqual(7., res[0], 12); + # + fieldOnCells=mesh.fillFromAnalytic(ON_CELLS, 1, "x+y/2.+z/3."); + self.assertEqual(1, fieldOnCells.getNumberOfComponents()); + self.assertEqual(27, fieldOnCells.getNumberOfTuples()); + val=fieldOnCells.getArray().getValues(); + expected2=[0, 1.5, 3, 1.5, 3, 4.5, 3, 4.5, 6, 1.5, 3, 4.5, 3, 4.5, + 6, 4.5, 6, 7.5, 3, 4.5, 6, 4.5, 6, 7.5, 6, 7.5, 9]; + for i in xrange(27): + self.assertAlmostEqual(expected2[i], val[i], 12); + #res=fieldOnCells.getValueOnPos(1,2,1); + #self.assertAlmostEqual(6.,res,12); + # + meshDeepCopy=mesh.deepCpy(); + meshClone=mesh.clone(False); + + meshEmpty.copyTinyStringsFrom(mesh); + #no data in meshEmpty, expected False + self.assertTrue(not meshEmpty.isEqual(mesh, 1e-12)); + + self.assertTrue(meshDeepCopy.isEqual(mesh, 1e-12)); + meshDeepCopy.copyTinyStringsFrom(mesh); + self.assertTrue(meshDeepCopy.isEqual(mesh, 1e-12)); + self.assertTrue(meshClone.isEqual(mesh, 1e-12)); + + self.assertEqual(CARTESIAN, mesh.getType()); + self.assertEqual(CARTESIAN, meshEmpty.getType()); + self.assertEqual(CARTESIAN, meshDeepCopy.getType()); + self.assertEqual(CARTESIAN, meshClone.getType()); + pass + + def testCMesh1(self): + mesh1=MEDCouplingCMesh.New(); + coordsX1=DataArrayDouble.New(); + arrX1=[ -1., 1., 2., 4. ] + coordsX1.setValues(arrX1, 4, 1); + coordsY1=DataArrayDouble.New(); + arrY1=[ -2., 2., 4., 8. ] + coordsY1.setValues(arrY1, 4, 1); + coordsZ1=DataArrayDouble.New(); + arrZ1=[ -3., 3., 6., 12. ] + coordsZ1.setValues(arrZ1, 4, 1); + mesh1.setCoords(coordsX1, coordsY1, coordsZ1); + + mesh2=MEDCouplingCMesh.New(); + coordsX2=DataArrayDouble.New(); + arrX2=[ -1., 1., 2., 4. ] + coordsX2.setValues(arrX2, 4, 1); + coordsY2=DataArrayDouble.New(); + arrY2=[ -2., 2., 4., 8. ] + coordsY2.setValues(arrY2, 4, 1); + coordsZ2=DataArrayDouble.New(); + arrZ2=[ -3., 3., 6., 12.+1e-6 ] + coordsZ2.setValues(arrZ2, 4, 1); + mesh2.setCoords(coordsX2, coordsY2, coordsZ2); + + mesh3=MEDCouplingCMesh.New(); + coordsX3=DataArrayDouble.New(); + arrX3=[-1.] + coordsX3.setValues(arrX3, 1, 1); + coordsY3=DataArrayDouble.New(); + arrY3=[-2.] + coordsY3.setValues(arrY3, 1, 1); + coordsZ3=DataArrayDouble.New(); + arrZ3=[-3.] + coordsZ3.setValues(arrZ3, 1, 1); + mesh3.setCoords(coordsX3, coordsY3, coordsZ3); + + self.assertEqual(3, mesh1.getSpaceDimension()); + self.assertEqual(3, mesh1.getMeshDimension()); + + self.assertTrue(not mesh1.isEqual(mesh2, 1e-12)); + self.assertTrue(not mesh2.isEqual(mesh1, 1e-12)); + self.assertTrue(not mesh2.isEqualWithoutConsideringStr(mesh1, 1e-12)); + self.assertTrue(mesh1.isEqual(mesh2, 1e-5)); + self.assertTrue(not mesh1.isEqual(mesh2, 1e-7)); + + self.assertRaises(InterpKernelException, mesh3.checkCoherency1, 1e-12); + mesh1.checkCoherency2(1e-12); + self.assertEqual(NORM_HEXA8, mesh1.getTypeOfCell(1)); + + self.assertEqual(NORM_HEXA8, mesh1.getAllGeoTypes()[0]); + self.assertEqual(27, mesh1.getNumberOfCellsWithType(NORM_HEXA8)); + self.assertRaises(InterpKernelException, mesh1.getNumberOfCellsWithType, NORM_QUAD4); + + coo=mesh1.getCoordinatesOfNode(0); + self.assertEqual(3, len(coo)); + self.assertAlmostEqual(-1., coo[0], 14); + self.assertAlmostEqual(-2., coo[1], 14); + self.assertAlmostEqual(-3., coo[2], 14); + coo=mesh1.getCoordinatesOfNode(63); + self.assertEqual(3, len(coo)); + self.assertAlmostEqual(4., coo[0], 14); + self.assertAlmostEqual(8., coo[1], 14); + self.assertAlmostEqual(12., coo[2], 14); + + a=str(mesh1) + repr=mesh1.simpleRepr(); + repr=mesh1.advancedRepr(); + self.assertTrue("Cartesian" in repr); + self.assertTrue("Number of components : 1" in repr); + self.assertTrue("Number of tuples : 4" in repr); + self.assertTrue("Z Array :" in repr); + pass + + def testCMesh2(self): + mesh1=MEDCouplingCMesh.New(); + coordsX1=DataArrayDouble.New(); + arrX1=[ -1., 1., 2., 4. ] + coordsX1.setValues(arrX1, 4, 1); + coordsY1=DataArrayDouble.New(); + arrY1=[ -2., 2., 4., 8. ] + coordsY1.setValues(arrY1, 4, 1); + coordsZ1=DataArrayDouble.New(); + arrZ1=[ -3., 3., 6., 12. ] + coordsZ1.setValues(arrZ1, 4, 1); + mesh1.setCoords(coordsX1, coordsY1, coordsZ1); + + dis=mesh1.getDistributionOfTypes(); + self.assertEqual(1, len(dis)); + self.assertEqual(NORM_HEXA8, dis[0][0]); + self.assertEqual(27, dis[0][1]); + self.assertEqual(-1, dis[0][2]); + + idsPerType=[] + self.assertTrue(not mesh1.checkTypeConsistencyAndContig(dis, idsPerType)); + dis[0][0]=NORM_QUAD4; + self.assertRaises(InterpKernelException, mesh1.checkTypeConsistencyAndContig, dis, idsPerType); + dis[0][0]=NORM_HEXA8; + dis[0][2]=0; + ids=DataArrayInt.New(); + ids.alloc(10, 1); + ids.fillWithValue(23); + idsPerType=[ids]; + check=mesh1.checkTypeConsistencyAndContig(dis, idsPerType); + self.assertTrue(check); + self.assertTrue(check.isEqual(ids)); + + code, idsInPflPerType, pfls=mesh1.splitProfilePerType(ids); + self.assertEqual(1, len(code)); + self.assertEqual(NORM_HEXA8, code[0][0]); + self.assertEqual(10, code[0][1]); + self.assertEqual(0, code[0][2]); + self.assertEqual(1, len(idsInPflPerType)); + self.assertEqual(1, len(pfls)); + self.assertTrue(idsInPflPerType[0].isEqual(DataArrayInt([0,1,2,3,4,5,6,7,8,9]))); + self.assertTrue(pfls[0].isEqual(ids)); + + cells1=[0, 1, 25, 26] + partMesh1=mesh1.buildPart(cells1) + self.assertTrue(isinstance(partMesh1,MEDCouplingMesh)) + self.assertEqual(4, partMesh1.getNumberOfCellsWithType(NORM_HEXA8)); + self.assertEqual(64, mesh1.getNumberOfNodes()); + self.assertEqual(64, partMesh1.getNumberOfNodes()); + + cells2=[25, 26] + partMesh2, arr1=mesh1.buildPartAndReduceNodes(cells2) + self.assertTrue(isinstance(partMesh2,MEDCouplingCMesh)) + self.assertEqual(2,partMesh2.getNumberOfCellsWithType(NORM_HEXA8)); + self.assertEqual(12,partMesh2.getNumberOfNodes()); + + cells3=[2, 3] + partMesh3, arr2=partMesh1.buildPartAndReduceNodes(cells3) + self.assertTrue(isinstance(partMesh3,MEDCouplingUMesh)) + self.assertEqual(2, partMesh3.getNumberOfCellsWithType(NORM_HEXA8)); + self.assertEqual(12, partMesh3.getNumberOfNodes()); + + self.assertRaises(InterpKernelException, mesh1.simplexize, 0); + self.assertRaises(InterpKernelException, mesh1.getMeasureFieldOnNode, True); + + #double bbox1[6]; + #double bbox2[6]; + bbox1=mesh1.getBoundingBox(); #[(-1.0, 4.0), (-2.0, 8.0), (-3.0, 12.0)] + bbox2=partMesh1.getBoundingBox(); + self.assertTrue(bbox1==bbox2); + bbox1=partMesh3.getBoundingBox(); + bbox2=partMesh2.getBoundingBox(); + self.assertTrue(bbox1==bbox2); + + self.assertRaises(InterpKernelException, mesh1.buildOrthogonalField); + mesh2d=MEDCouplingCMesh.New(); + mesh2d.setCoords(coordsX1, coordsY1); + f1=mesh2d.buildOrthogonalField(); + + pass + + def testScale(self): + mesh=MEDCouplingDataForTest.build2DTargetMesh_1(); + pos=[0.2,0.2] + mesh.scale(pos,0.5); + expected1=[-0.05,-0.05, 0.2,-0.05, 0.45,-0.05, -0.05,0.2, 0.2,0.2, 0.45,0.2, + -0.05,0.45, 0.2,0.45, 0.45,0.45] + val=mesh.getCoords().getValues(); + self.assertEqual(18,len(val)) + for i in xrange(18): + self.assertTrue(abs(expected1[i]-val[i])<1e-12); + pass + pass + + def testTryToShareSameCoords(self): + m1=MEDCouplingDataForTest.build2DTargetMesh_1(); + m2=MEDCouplingDataForTest.build2DTargetMesh_1(); + self.assertTrue(m1.getCoords().getHiddenCppPointer()!=m2.getCoords().getHiddenCppPointer()); + m1.tryToShareSameCoords(m2,1e-12); + self.assertTrue(m1.getCoords().getHiddenCppPointer()==m2.getCoords().getHiddenCppPointer()); + m1.tryToShareSameCoords(m2,1e-12); + self.assertTrue(m1.getCoords().getHiddenCppPointer()==m2.getCoords().getHiddenCppPointer()); + m2.tryToShareSameCoords(m1,1e-12); + self.assertTrue(m1.getCoords().getHiddenCppPointer()==m2.getCoords().getHiddenCppPointer()); + # + m1=MEDCouplingDataForTest.build2DTargetMesh_1(); + m2=MEDCouplingDataForTest.build2DTargetMesh_2(); + self.assertTrue(m1.getCoords().getHiddenCppPointer()!=m2.getCoords().getHiddenCppPointer()); + m1.tryToShareSameCoords(m2,1e-12); + self.assertTrue(m1.getCoords().getHiddenCppPointer()==m2.getCoords().getHiddenCppPointer()); + m1.tryToShareSameCoords(m2,1e-12); + self.assertTrue(m1.getCoords().getHiddenCppPointer()==m2.getCoords().getHiddenCppPointer()); + m2.tryToShareSameCoords(m1,1e-12); + self.assertTrue(m1.getCoords().getHiddenCppPointer()==m2.getCoords().getHiddenCppPointer()); + # + m1=MEDCouplingDataForTest.build2DTargetMesh_1(); + m2=MEDCouplingDataForTest.build2DSourceMesh_1(); + self.assertTrue(m1.getCoords().getHiddenCppPointer()!=m2.getCoords().getHiddenCppPointer()); + self.assertRaises(InterpKernelException,m1.tryToShareSameCoords,m2,1e-12) + pass + + def testFindNodeOnPlane(self): + mesh=MEDCouplingDataForTest.build3DTargetMesh_1(); + pt=[300.,300.,0.] + v=[0.,0.,2.] + n=mesh.findNodesOnPlane(pt,v,1e-12); + self.assertEqual(9,len(n)); + m3dSurf=mesh.buildFacePartOfMySelfNode(n,True); + self.assertTrue(isinstance(m3dSurf,MEDCouplingUMesh)) + me=MEDCouplingExtrudedMesh.New(mesh,m3dSurf,0); + da=me.getMesh3DIds(); + self.assertEqual(8,me.getNumberOfCells()); + expected=[0,1,2,3,4,5,6,7] + val=da.getValues(); + self.assertEqual(expected,list(val)); + # + m3dSurf=mesh.buildFacePartOfMySelfNode(n,True); + self.assertTrue(isinstance(m3dSurf,MEDCouplingUMesh)) + me=MEDCouplingExtrudedMesh.New(mesh,m3dSurf,0); + da=me.getMesh3DIds(); + self.assertEqual(8,me.getNumberOfCells()); + expected=[0,1,2,3,4,5,6,7] + val=da.getValues(); + self.assertEqual(expected,list(val)); + pass + + def testRenumberCells(self): + m=MEDCouplingDataForTest.build3DSurfTargetMesh_1(); + m2=MEDCouplingDataForTest.build3DSurfTargetMesh_1(); + self.assertTrue(m.isEqual(m2,0)); + arr=[12,3,25,2,26] + m.renumberCells(arr,True); + self.assertTrue(not m.isEqual(m2,0)); + self.assertEqual(NORM_QUAD4,m.getTypeOfCell(0)); + self.assertEqual(NORM_TRI3,m.getTypeOfCell(1)); + self.assertEqual(NORM_QUAD4,m.getTypeOfCell(2)); + self.assertEqual(NORM_TRI3,m.getTypeOfCell(3)); + self.assertEqual(NORM_QUAD4,m.getTypeOfCell(4)); + arr2=[5,-1,-5,4,8] + m.renumberCells(arr2,True); + self.assertTrue(m.isEqual(m2,0)); + pass + + def testChangeSpaceDimension(self): + m1=MEDCouplingDataForTest.build3DSurfTargetMesh_1(); + m2=MEDCouplingDataForTest.build2DTargetMesh_1(); + # + self.assertEqual(3,m1.getSpaceDimension()); + m1.changeSpaceDimension(2); + self.assertEqual(2,m1.getSpaceDimension()); + m1.setName(m2.getName()); + self.assertTrue(m1.isEqual(m2,1e-12)); + m1.changeSpaceDimension(3); + self.assertEqual(3,m1.getSpaceDimension()); + expected=[-0.3,-0.3,0., 0.2,-0.3,0., 0.7,-0.3,0., -0.3,0.2,0., 0.2,0.2,0., 0.7,0.2,0., -0.3,0.7,0., 0.2,0.7,0., 0.7,0.7,0.] + val=m1.getCoords().getValues(); + for i in xrange(27): + self.assertTrue(abs(expected[i]-val[i])<1e-14); + pass + pass + + def testGaussPointField1(self): + _a=0.446948490915965; + _b=0.091576213509771; + _p1=0.11169079483905; + _p2=0.0549758718227661; + refCoo1=[ 0.,0., 1.,0., 0.,1. ] + gsCoo1=[ 2*_b-1, 1-4*_b, 2*_b-1, 2.07*_b-1, 1-4*_b, + 2*_b-1, 1-4*_a, 2*_a-1, 2*_a-1, 1-4*_a, 2*_a-1, 2*_a-1 ] + wg1=[ 4*_p2, 4*_p2, 4*_p2, 4*_p1, 4*_p1, 4*_p1 ] + _refCoo1=refCoo1 + _gsCoo1=gsCoo1 + _wg1=wg1 + # + m=MEDCouplingDataForTest.build2DTargetMesh_1(); + f=MEDCouplingFieldDouble.New(ON_GAUSS_PT,NO_TIME); + f.setMesh(m); + self.assertEqual(5,f.getNumberOfMeshPlacesExpected()); + self.assertEqual(0,f.getNbOfGaussLocalization()); + f.setGaussLocalizationOnType(NORM_TRI3,_refCoo1,_gsCoo1,_wg1); + f.setGaussLocalizationOnType(NORM_TRI3,_refCoo1,_gsCoo1,_wg1); # not a bug only to check that it works well + self.assertRaises(InterpKernelException,f.setGaussLocalizationOnType,NORM_QUAD4,_refCoo1,_gsCoo1,_wg1) + self.assertEqual(1,f.getNbOfGaussLocalization()); + refCoo2=[ 0.,0., 1.,0., 1.,1., 0.,1. ] + _refCoo2=refCoo2 + _gsCoo1=_gsCoo1[0:4] + _wg1=_wg1[0:2] + f.setGaussLocalizationOnType(NORM_QUAD4,_refCoo2,_gsCoo1,_wg1); + self.assertEqual(2,f.getNbOfGaussLocalization()); + array=DataArrayDouble.New(); + ptr=18*2*[None] + for i in xrange(18*2): + ptr[i]=float(i+1) + array.setValues(ptr,18,2); + ptr=array.getPointer(); + f.setArray(array); + f.setName("MyFirstFieldOnGaussPoint"); + f.checkCoherency(); + self.assertAlmostEqual(27.,f.getIJK(2,5,0),14); + self.assertAlmostEqual(16.,f.getIJK(1,5,1),14); + # + f.clearGaussLocalizations(); + self.assertEqual(0,f.getNbOfGaussLocalization()); + self.assertRaises(InterpKernelException,f.checkCoherency); + ids1=[0,1,3,4] + self.assertRaises(InterpKernelException,f.setGaussLocalizationOnCells,ids1,_refCoo2,_gsCoo1,_wg1); + self.assertEqual(0,f.getNbOfGaussLocalization()); + ids2=[0,4] + f.setGaussLocalizationOnCells(ids2,_refCoo2,_gsCoo1,_wg1); + self.assertEqual(1,f.getNbOfGaussLocalization()); + self.assertEqual(0,f.getGaussLocalizationIdOfOneCell(0)); + self.assertRaises(InterpKernelException,f.getGaussLocalizationIdOfOneCell,1); + ids3=[1,2] + f.setGaussLocalizationOnCells(ids3,_refCoo1,_gsCoo1,_wg1); + self.assertEqual(2,f.getNbOfGaussLocalization()); + self.assertEqual(0,f.getGaussLocalizationIdOfOneCell(0)); + self.assertEqual(1,f.getGaussLocalizationIdOfOneCell(1)); + self.assertEqual(1,f.getGaussLocalizationIdOfOneCell(2)); + self.assertRaises(InterpKernelException,f.checkCoherency);#<- cell 3 has no localization + ids4=[3] + _gsCoo2=_gsCoo1; + _wg2=_wg1; + _gsCoo2[0]=0.8888777776666; + _wg2[0]=0.1234567892377; + f.setGaussLocalizationOnCells(ids4,_refCoo2,_gsCoo2,_wg2); + self.assertEqual(3,f.getNbOfGaussLocalization()); + tmpIds=f.getCellIdsHavingGaussLocalization(0); + self.assertEqual(ids2,list(tmpIds.getValues())); + self.assertRaises(InterpKernelException,f.checkCoherency);#<- it's always not ok because undelying array not with the good size. + array2=f.getArray().substr(0,10); + f.setArray(array2); + f.checkCoherency();#<- here it is OK + f2=f.clone(True); + self.assertTrue(f.isEqual(f2,1e-14,1e-14)); + gl1=f2.getGaussLocalization(0); + tmp=gl1.getGaussCoord(1,1); + self.assertAlmostEqual(2.07*_b-1,tmp,14); + gl1.setGaussCoord(1,1,0.07); + self.assertTrue(not f.isEqual(f2,1e-14,1e-14)); + gl1.setGaussCoord(1,1,tmp); + self.assertTrue(f.isEqual(f2,1e-14,1e-14)); + f2.checkCoherency(); + pass + + def testGaussPointNEField1(self): + m=MEDCouplingDataForTest.build2DTargetMesh_1(); + f=MEDCouplingFieldDouble.New(ON_GAUSS_NE,NO_TIME); + f.setMesh(m); + self.assertEqual(5,f.getNumberOfMeshPlacesExpected()); + f.setName("MyFirstFieldOnNE"); + f.setDescription("MyDescriptionNE"); + array=DataArrayDouble.New(); + tmp=18*2*[None] + for i in xrange(18*2): + tmp[i]=float(i+7) + pass + array.setValues(tmp,18,2); + ptr=array.getPointer(); + f.setArray(array); + # + f.checkCoherency(); + f2=f.clone(True); + self.assertTrue(f.isEqual(f2,1e-14,1e-14)); + self.assertAlmostEqual(21.,f.getIJK(2,0,0),14); + self.assertAlmostEqual(18.,f.getIJK(1,1,1),14); + pass + + def testCellOrientation1(self): + m=MEDCouplingDataForTest.build2DTargetMesh_1(); + vec=[0.,0.,-1.] + self.assertRaises(InterpKernelException,m.are2DCellsNotCorrectlyOriented,vec,False); + m.changeSpaceDimension(3); + res1=m.are2DCellsNotCorrectlyOriented(vec,False); + self.assertTrue(len(res1)==0); + vec[2]=1.; + res1=m.are2DCellsNotCorrectlyOriented(vec,False); + self.assertEqual(5,len(res1)); + # + vec[2]=-1.; + # connectivity inversion + conn=m.getNodalConnectivity().getValues(); + tmp=conn[11]; + conn[11]=conn[12]; + conn[12]=tmp; + m.getNodalConnectivity().setValues(conn,len(conn),1) + res1=m.are2DCellsNotCorrectlyOriented(vec,False); + self.assertEqual(1,len(res1)); + self.assertEqual(2,res1.getValues()[0]); + m.orientCorrectly2DCells(vec,False); + res1=m.are2DCellsNotCorrectlyOriented(vec,False); + self.assertTrue(len(res1)==0); + m2=MEDCouplingDataForTest.build2DTargetMesh_1(); + m2.changeSpaceDimension(3); + self.assertTrue(m.isEqual(m2,1e-12)); + pass + + def testCellOrientation2(self): + m2,m1=MEDCouplingDataForTest.build3DExtrudedUMesh_1(); + res1=m2.arePolyhedronsNotCorrectlyOriented(); + self.assertEqual(6,len(res1)); + m2.orientCorrectlyPolyhedrons(); + res1=m2.arePolyhedronsNotCorrectlyOriented(); + self.assertTrue(len(res1)==0); + m2.checkCoherency(); + self.assertEqual(18,m2.getNumberOfCells()); + cellIds2=[0,6,12] + m2.convertToPolyTypes(cellIds2); + m2.orientCorrectlyPolyhedrons(); + res1=m2.arePolyhedronsNotCorrectlyOriented(); + self.assertTrue(len(res1)==0); + f2=m2.getMeasureField(False); + f2Ptr=f2.getArray().getValues(); + #Test to check global reverse in MEDCouplingUMesh::tryToCorrectPolyhedronOrientation + m3=MEDCouplingDataForTest.build2DTargetMesh_1(); + vec=[0.,0.,1.] + m3.changeSpaceDimension(3); + ids2=[0,1,2,3,4] + m3.convertToPolyTypes(ids2); + m3.orientCorrectly2DCells(vec,False); + m4=MEDCouplingDataForTest.buildCU1DMesh_U(); + m4.changeSpaceDimension(3); + center=[0.,0.,0.] + vector=[0.,1.,0.] + m4.rotate(center,vector,-pi/2.); + m5=m3.buildExtrudedMesh(m4,0); + res1=m5.arePolyhedronsNotCorrectlyOriented(); + self.assertEqual(15,len(res1)); + m5.orientCorrectlyPolyhedrons(); + res1=m5.arePolyhedronsNotCorrectlyOriented(); + self.assertTrue(len(res1)==0); + f3=m5.getMeasureField(False); + self.assertEqual(15,f3.getArray().getNumberOfTuples()); + self.assertEqual(1,f3.getNumberOfComponents()); + f3Ptr=f3.getArray().getValues(); + expected1=[0.075,0.0375,0.0375,0.075,0.075, 0.1125,0.05625,0.05625,0.1125,0.1125, 0.0625,0.03125,0.03125,0.0625,0.0625]; + for i in xrange(15): + self.assertTrue(abs(expected1[i]-f3Ptr[i])<1e-12); + pass + f4=m5.getBarycenterAndOwner(); + self.assertEqual(15,f4.getNumberOfTuples()); + self.assertEqual(3,f4.getNumberOfComponents()); + f4Ptr=f4.getValues(); + expected2=[-0.05,-0.05,0.15, 0.3666666666666667,-0.13333333333333333,0.15, 0.53333333333333333,0.033333333333333333,0.15, -0.05,0.45,0.15, 0.45,0.45,0.15,-0.05,-0.05,0.525, 0.3666666666666667,-0.13333333333333333,0.525, 0.53333333333333333,0.033333333333333333,0.525, -0.05,0.45,0.525, 0.45,0.45,0.525,-0.05,-0.05,0.875, 0.3666666666666667,-0.13333333333333333,0.875, 0.53333333333333333,0.033333333333333333,0.875, -0.05,0.45,0.875, 0.45,0.45,0.875]; + for i in xrange(45): + self.assertTrue(abs(expected2[i]-f4Ptr[i])<1e-12); + pass + pass + + def testCellOrientation3(self): + from cmath import rect + + c = [rect(1.0, i*pi/4.0) for i in range(8)] + coords = [c[-1].real,c[-1].imag, c[3].real,c[3].imag, + c[5].real,c[5].imag, c[1].real,c[1].imag] + connec = [0,1,2,3] + baseMesh = MEDCouplingUMesh.New("circle", 2) + baseMesh.allocateCells(1) + meshCoords = DataArrayDouble.New(coords, 4, 2) + baseMesh.setCoords(meshCoords) + baseMesh.insertNextCell(NORM_QPOLYG, connec) # a circle + baseMesh.finishInsertingCells() + baseMesh.changeSpaceDimension(3) + Oz = [0.0, 0.0, -1.0] + cell_lst = baseMesh.are2DCellsNotCorrectlyOriented(Oz, False) + self.assertEqual(cell_lst.getNumberOfTuples(), 0) + Oz[2] = 1.0 + cell_lst = baseMesh.are2DCellsNotCorrectlyOriented(Oz, False) + self.assertEqual(cell_lst.getNumberOfTuples(), 1) + + def testPolyhedronBarycenter(self): + connN=[0,3,2,1, -1, 4,5,6,7, -1, 0,4,7,3, -1, 3,7,6,2, -1, 2,6,5,1, -1, 1,5,4,0]; + coords=[0.,0.,0., 1.,0.,0., 1.,1.,0., 0.,1.,0., 0.,0.,1., 1.,0.,1., 1.,1.,1., 0.,1.,1., 0.5, 0.5, 0.5]; + meshN=MEDCouplingUMesh.New(); + meshN.setName("ForBary"); + meshN.setMeshDimension(3); + meshN.allocateCells(4); + meshN.insertNextCell(NORM_POLYHED,29,connN[0:29]) + meshN.finishInsertingCells(); + myCoords=DataArrayDouble.New(); + myCoords.setValues(coords,9,3); + meshN.setCoords(myCoords); + meshN.checkCoherency(); + # + res1=meshN.arePolyhedronsNotCorrectlyOriented(); + meshN.orientCorrectlyPolyhedrons(); + self.assertTrue(len(res1)==0); + da=meshN.getBarycenterAndOwner(); + self.assertEqual(1,da.getNumberOfTuples()); + self.assertEqual(3,da.getNumberOfComponents()); + daPtr=da.getValues(); + ref=meshN.getCoords().getValues()[24:]; + for i in xrange(3): + self.assertTrue(abs(ref[i]-daPtr[i])<1e-12); + pass + # + center=[0.,0.,0.] + vec=[0.,2.78,0.] + da=meshN.getBarycenterAndOwner(); + daPtr=da.getValues(); + ref=meshN.getCoords().getValues()[24:]; + for i in xrange(3): + self.assertTrue(abs(ref[i]-daPtr[i])<1e-12); + pass + # + meshN.rotate(center,vec,pi/7.); + meshN.translate(vec); + da=meshN.getBarycenterAndOwner(); + daPtr=da.getValues(); + ref=meshN.getCoords().getValues()[24:]; + for i in xrange(3): + self.assertTrue(abs(ref[i]-daPtr[i])<1e-12); + pass + # + center2=[1.12,3.45,6.78] + vec2=[4.5,9.3,2.8] + meshN.rotate(center2,vec2,e); + meshN.translate(vec2); + da=meshN.getBarycenterAndOwner(); + daPtr=da.getValues(); + ref=meshN.getCoords().getValues()[24:]; + for i in xrange(3): + self.assertTrue(abs(ref[i]-daPtr[i])<1e-10); + pass + pass + + def testNormL12Integ1D(self): + m1=MEDCouplingDataForTest.build1DTargetMesh_3(); + f1=MEDCouplingFieldDouble.New(ON_CELLS,NO_TIME); + f1.setMesh(m1); + array=DataArrayDouble.New(); + arr=[-5.23,15.45,-25.56,6.67,-16.78,26.89,-7.91,17.23,-27.43,8.21,-18.63,28.72] + array.setValues(arr,m1.getNumberOfCells(),3); + f1.setArray(array); + # + f3=m1.getBarycenterAndOwner(); + self.assertEqual(4,f3.getNumberOfTuples()); + self.assertEqual(1,f3.getNumberOfComponents()); + expected9=[0.75,5.105,0.8,5.155] + ptr=f3.getValues(); + for i in xrange(4): + self.assertTrue(abs(expected9[i]-ptr[i])<1e-12); + pass + # + f2=m1.getMeasureField(False); + self.assertEqual(4,f2.getArray().getNumberOfTuples()); + self.assertEqual(1,f2.getNumberOfComponents()); + expected1=[0.5,0.21,-0.6,-0.31] + ptr=f2.getArray().getValues(); + for i in xrange(4): + self.assertTrue(abs(expected1[i]-ptr[i])<1e-12); + pass + expected2=[0.5,0.21,0.6,0.31] + f2=m1.getMeasureField(True); + ptr=f2.getArray().getValues(); + for i in xrange(4): + self.assertTrue(abs(expected2[i]-ptr[i])<1e-12); + pass + #integral + self.assertTrue(4,f1.getNumberOfTuples()) + res=f1.integral(False); + self.assertTrue(3,len(res)) + expected3=[0.9866,-0.3615,0.4217] + for i in xrange(3): + self.assertTrue(abs(expected3[i]-res[i])<1e-12); + pass + self.assertTrue(abs(expected3[0]-f1.integral(0,False))<1e-12); + self.assertTrue(abs(expected3[1]-f1.integral(1,False))<1e-12); + self.assertTrue(abs(expected3[2]-f1.integral(2,False))<1e-12); + res=f1.integral(True); + expected4=[-3.4152,8.7639,-14.6879] + for i in xrange(3): + self.assertTrue(abs(expected4[i]-res[i])<1e-12); + pass + #normL1 + res=f1.normL1(); + self.assertTrue(3,len(res)) + expected5=[6.979506172839505, 16.89018518518518, 27.02969135802469] + for i in xrange(3): + self.assertTrue(abs(expected5[i]-res[i])<1e-12); + pass + self.assertTrue(abs(expected5[0]-f1.normL1(0))<1e-12); + self.assertTrue(abs(expected5[1]-f1.normL1(1))<1e-12); + self.assertTrue(abs(expected5[2]-f1.normL1(2))<1e-12); + #normL2 + res=f1.normL2(); + self.assertTrue(3,len(res)) + expected7=[7.090910979452395, 16.9275542960123, 27.053271464160858] + for i in xrange(3): + self.assertTrue(abs(expected7[i]-res[i])<1e-9); + pass + self.assertTrue(abs(expected7[0]-f1.normL2(0))<1e-9); + self.assertTrue(abs(expected7[1]-f1.normL2(1))<1e-9); + self.assertTrue(abs(expected7[2]-f1.normL2(2))<1e-9); + #buildMeasureField + f4=f1.buildMeasureField(False); + self.assertTrue(abs(-0.2-f4.accumulate(0))<1e-12); + f4=f1.buildMeasureField(True); + self.assertTrue(abs(1.62-f4.accumulate(0))<1e-12); + # Testing with 2D Curve + m1=MEDCouplingDataForTest.build2DCurveTargetMesh_3(); + f2=m1.getMeasureField(False); + self.assertEqual(4,f2.getArray().getNumberOfTuples()); + self.assertEqual(1,f2.getNumberOfComponents()); + ptr=f2.getArray().getValues(); + for i in xrange(4): + self.assertTrue(abs(sqrt(2.)*expected2[i]-ptr[i])<1e-12); + pass + f2=m1.getMeasureField(True); + self.assertEqual(4,f2.getArray().getNumberOfTuples()); + self.assertEqual(1,f2.getNumberOfComponents()); + ptr=f2.getArray().getValues(); + for i in xrange(4): + self.assertTrue(abs(expected2[i]*sqrt(2.)-ptr[i])<1e-12); + pass + #bary + f3=m1.getBarycenterAndOwner(); + self.assertEqual(4,f3.getNumberOfTuples()); + self.assertEqual(2,f3.getNumberOfComponents()); + expected10=[0.75,0.75,5.105,5.105,0.8,0.8,5.155,5.155] + ptr=f3.getValues(); + for i in xrange(8): + self.assertTrue(abs(expected10[i]-ptr[i])<1e-12); + pass + # + f1=MEDCouplingFieldDouble.New(ON_CELLS,NO_TIME); + f1.setMesh(m1); + array=DataArrayDouble.New(); + array.setValues(arr,m1.getNumberOfCells(),3); + f1.setArray(array); + res=f1.integral(False); + for i in xrange(3): + self.assertTrue(abs(sqrt(2.)*expected4[i]-res[i])<1e-12); + pass + res=f1.integral(True); + for i in xrange(3): + self.assertTrue(abs(sqrt(2.)*expected4[i]-res[i])<1e-12); + pass + res=f1.normL1(); + for i in xrange(3): + self.assertTrue(abs(expected5[i]-res[i])<1e-12); + pass + res=f1.normL2(); + for i in xrange(3): + self.assertTrue(abs(expected7[i]-res[i])<1e-12); + pass + pass + + def testAreaBary2D(self): + m1=MEDCouplingDataForTest.build2DTargetMesh_3(); + f1=m1.getMeasureField(False); + self.assertEqual(10,f1.getArray().getNumberOfTuples()); + self.assertEqual(1,f1.getNumberOfComponents()); + expected1=[-0.5,-1,-1.5,-0.5,-1, 0.5,1,1.5,0.5,1] + ptr=f1.getArray().getValues(); + for i in xrange(10): + self.assertTrue(abs(expected1[i]-ptr[i])<1e-12); + pass + f1=m1.getMeasureField(True); + ptr=f1.getArray().getValues(); + for i in xrange(10): + self.assertTrue(abs(abs(expected1[i])-ptr[i])<1e-12); + pass + f2=m1.getBarycenterAndOwner(); + self.assertEqual(10,f2.getNumberOfTuples()); + self.assertEqual(2,f2.getNumberOfComponents()); + expected2=[0.5,0.3333333333333333,0.5,0.5,0.5,0.77777777777777777,0.5,0.3333333333333333,0.5,0.5,0.5,0.3333333333333333,0.5,0.5,0.5,0.77777777777777777,0.5,0.3333333333333333,0.5,0.5] + ptr=f2.getValues(); + for i in xrange(20): + self.assertTrue(abs(expected2[i]-ptr[i])<1e-12); + pass + m1.changeSpaceDimension(3); + f1=m1.getMeasureField(False); + self.assertEqual(10,f1.getArray().getNumberOfTuples()); + self.assertEqual(1,f1.getNumberOfComponents()); + ptr=f1.getArray().getValues(); + for i in xrange(10): + self.assertTrue(abs(abs(expected1[i])-ptr[i])<1e-12); + pass + f2=m1.getBarycenterAndOwner(); + self.assertEqual(10,f2.getNumberOfTuples()); + self.assertEqual(3,f2.getNumberOfComponents()); + ptr=f2.getValues(); + expected3=[0.5,0.3333333333333333,0.,0.5,0.5,0.,0.5,0.77777777777777777,0.,0.5,0.3333333333333333,0.,0.5,0.5,0., 0.5,0.3333333333333333,0.,0.5,0.5,0.,0.5,0.77777777777777777,0.,0.5,0.3333333333333333,0.,0.5,0.5,0.] + for i in xrange(30): + self.assertTrue(abs(expected3[i]-ptr[i])<1e-12); + pass + pass + + def testAreaBary3D(self): + coords=[ 0.241310763507 , 0.0504777305619 , 0.0682283524903 , 0.252501053866 , -0.0625176732937 , 0.137272639894 , + 0.152262663601 , 0.241816569527 , 0.133812556197 , 0.18047750211 , -0.0789949051358 , 0.339098173401 , + 0.151741971857 , 0.238885278571 , 0.137715037333 , 0.242532155481 , -0.0928169086456 , 0.0678043417367 , + 0.240941965335 , -0.015461491464 , 0.0617186345825 , 0.24127650112 , 0.0499427876717 , 0.0679634099148 , + -0.145828917428 , 0.206291632565 , 0.0310071927543 , 0.0125651775307 , 0.266262085828 , 0.105228430543 , + -0.0994066533286 , 0.233224271238 , 0.0572213839567 , -0.0951345338317 , 0.234819509426 , 0.0592126284538 , + 0.136580574205 , -0.205486212579 , 0.0572866072014 , 0.0637270784978 , -0.168886355238 , 0.446614057077 , + 0.041337157151 , -0.213402568198 , 0.372407095999 , 0.0411601970268 , -0.202387875756 , 0.411334979491 , + -0.108355701857 , 0.193636239335 , 0.204886756738 , 0.00639779029829 , 0.155296981517 , 0.252585892979 , + 0.0262473111702 , -0.112919732543 , 0.424286639249 ,-0.224103052733 , -0.139430015438 , -0.0122352295701 , + -0.0312760589481 , -0.274272003594 , 0.0323959636568 , -0.166663422532 , -0.217754445175 , 0.00392109070364 , + -0.30586619777 , -0.0475168041091 , -0.0144585228182 , -0.280881480586 , 0.135571293538 , 0.00623923647986 , + -0.25548538234 , 0.156819217766 , 0.0645277879769 , -0.131567009284 , 0.184133752309 , 0.206021802753 , + -0.196204010965 , 0.151602971681 , 0.212974777736 , -0.183713879463 , 0.0802946639531 , 0.260115662599 , + -0.244241178767 , -0.0738873389604 , 0.144590565817 , -0.155804057829 , -0.164892720025 , 0.210613950558 , + -0.170950800428 , -0.215099334026 , 0.00610122860092 , -0.30552634869 , -0.0490020791904 , -0.0132786533145 , + 0.271831011884 , 0.15105657296 , 0.0230534827908 , 0.281919192283 , 0.0898544306288 , -0.0625201489143 , + 0.260240727276 , -0.0120688706637 , -0.0532316588626 , 0.244947737722 , 0.0197984684293 , 0.0309341209233 , + 0.23439631578 , 0.229825279875 , 0.0508520585381 , 0.160921316875 , 0.265078502128 , 0.121716560626 , + -0.315088694175 , 0.0747700471918 , -0.245836615071 , -0.327728781776 , 0.0857114674649 , -0.239431905957 , + -0.308385460634 , 0.145142997084 , -0.149886828433 , 0.0488236045164 , 0.309462801914 , 0.0849169148265 , + -0.0244964803395 , 0.33145611751 , -0.0476415818061 , 0.0060567994229 , 0.32418412014 , 0.0367779543812 , + -0.0950221448063 , 0.236675326003 , 0.0572594453983 , 0.248723023186 , 0.0886648784791 , -0.176629430538 , + 0.116796984 , 0.256596599567 , -0.292863523603 , 0.118024552914 , 0.229154257843 , -0.34233232501 , + 0.217507892549 , -0.0417822335742 , -0.176771782888 , -0.224429321304 , 0.0125595300114 , -0.362064725588 , + 0.0937301100955 , -0.0500824832657 , -0.299713548444 , -0.244162220397 , 0.0383853931293 , -0.389856984411 , + -0.0281989366102 , 0.097392811563 , -0.458244577284 , -0.385010847162 , 0.10122766194 , -0.140052859922 , + -0.377936358012 , 0.110875172128 , -0.176207095463 , 0.244483045556 , -0.0991073977045 , 0.0575134372934 , + 0.262605120167 , -0.100243191645 , -0.0495620806935 , 0.240306880972 , -0.136153701579 , -0.114745281696 , + 0.215763176129 , -0.0836766059189 , -0.183249640616 , 0.237870396603 , -0.132449578286 , -0.121598854639 , + -0.0637683083097 , -0.27921020214 , -0.149112321992 , -0.0856211014977 , -0.2973233473 , -0.0446878139589 , + 0.104675342288 , -0.0625908305324 , -0.290346256534 , 0.0248264249186 , -0.247797708548 , -0.165830884019 , + 0.0719302438309 , -0.178468260473 , -0.211432157345 , 0.142871843159 , -0.208769948542 , 0.0454101128246 , + 0.167803379307 , -0.207851396623 , -0.088802726124 , 0.12868717152 , -0.230920439715 , 0.00760508389036 , + -0.0372812069535 , -0.286740286332 , 0.00963701291166 ] + + connN = [ #polyhedron 0 + 0 , 1 , 3 , 4 , 2 , -1 , 1 , 5 , 6 , 7 , 0 , -1 , 0 , 7 , 8 , 10 , 11 , 9 , 2 , -1 , 1 , 5 , 12 , 14 , 15 , 13 , 3 , -1 , 16 , 9 , 2 , 4 , 17 , -1 + , 4 , 3 , 13 , 18 , 17 , -1 , 5 , 6 , 19 , 21 , 20 , 12 , -1 , 6 , 7 , 8 , 23 , 22 , 19 , -1 , 23 , 24 , 10 , 8 , -1 , 25 , 11 , 9 , 16 , -1 + , 24 , 26 , 25 , 11 , 10 , -1 , 12 , 14 , 20 , -1 , 27 , 28 , 29 , 15 , 13 , 18 , -1 , 14 , 15 , 29 , 30 , 21 , 20 , -1 , 26 , 27 , 18 , 17 , 16 , 25 , -1 + , 22 , 19 , 21 , 30 , 31 , -1 , 22 , 31 , 28 , 27 , 26 , 24 , 23 , -1 , 31 , 30 , 29 , 28, + # polyhedron 1 + 0 , 7 , 8 , 10 , 11 , 9 , 2 , -1 , 32 , 0 , 7 , 35 , 34 , 33 , -1 , 32 , 0 , 2 , 37 , 36 , -1 , 35 , 7 , 8 , 40 , 39 , 38 , -1 + , 2 , 37 , 41 , 9 , -1 , 40 , 8 , 10 , 44 , 43 , 42 , -1 , 41 , 9 , 11 , 44 , 43 , -1 , 44 , 11 , 10 , -1 , 32 , 33 , 45 , 47 , 46 , 36 , -1 + , 33 , 34 , 48 , 45 , -1 , 35 , 34 , 48 , 50 , 49 , 38 , -1 , 41 , 43 , 42 , 46 , 36 , 37 , -1 , 38 , 39 , 51 , 49 , -1 + , 39 , 40 , 42 , 46 , 47 , 52 , 51 , -1 , 45 , 47 , 52 , 50 , 48 , -1 , 52 , 51 , 49 , 50, + # polyhedron 2 + 6 , 7 , 8 , 23 , 22 , 19 , -1 , 6 , 35 , 7 , -1 , 6 , 35 , 38 , 19 , -1 , 35 , 7 , 8 , 40 , 39 , 38 , -1 , 53 , 22 , 19 , 38 , 39 , 54 , -1 + , 23 , 53 , 54 , 40 , 8 , -1 , 53 , 22 , 23 , -1 , 39 , 54 , 40, + # polyhedron 3 + 35 , 34 , 48 , 50 , 49 , 38 , -1 , 6 , 35 , 34 , 56 , 55 , 5 , -1 , 6 , 35 , 38 , 19 , -1 , 34 , 56 , 57 , 59 , 58 , 48 , -1 + , 60 , 61 , 21 , 19 , 38 , 49 , -1 , 62 , 50 , 48 , 58 , -1 , 60 , 63 , 64 , 62 , 50 , 49 , -1 , 5 , 6 , 19 , 21 , 20 , 12 , -1 + , 55 , 5 , 12 , 65 , -1 , 66 , 67 , 65 , 55 , 56 , 57 , -1 , 63 , 66 , 57 , 59 , 64 , -1 , 64 , 62 , 58 , 59 , -1 + , 60 , 63 , 66 , 67 , 68 , 61 , -1 , 61 , 68 , 20 , 21 , -1 , 67 , 68 , 20 , 12 , 65] + + barys = [ -0.0165220465527 , -0.0190922868195 , 0.158882733414 , + 0.0287618656076 , 0.135874379934 , -0.14601588119 , + -0.147128055553 , 0.0465995097041 , -0.049391174453 , + -0.00142506732317 , -0.0996953090351 , -0.115159183132 ] + meshN=MEDCouplingUMesh.New(); + meshN.setName("ForBary"); + meshN.setMeshDimension(3); + meshN.allocateCells(4); + meshN.insertNextCell(NORM_POLYHED,113,connN); + meshN.insertNextCell(NORM_POLYHED,99,connN[113:]); + meshN.insertNextCell(NORM_POLYHED,43,connN[212:]); + meshN.insertNextCell(NORM_POLYHED,92,connN[255:]); + meshN.finishInsertingCells(); + myCoords=DataArrayDouble.New(); + myCoords.setValues(coords,69,3); + meshN.setCoords(myCoords); + meshN.checkCoherency(); + res1=meshN.arePolyhedronsNotCorrectlyOriented(); + meshN.orientCorrectlyPolyhedrons(); + res1=meshN.arePolyhedronsNotCorrectlyOriented(); + self.assertTrue(len(res1)==0); + # + da=meshN.getBarycenterAndOwner(); + self.assertEqual(4,da.getNumberOfTuples()); + self.assertEqual(3,da.getNumberOfComponents()); + daPtr=da.getValues(); + for i in xrange(12): + self.assertTrue(abs(barys[i]-daPtr[i])<1e-12); + pass + pass + + def testRenumberCellsForFields(self): + m=MEDCouplingDataForTest.build2DTargetMesh_1(); + f=MEDCouplingFieldDouble.New(ON_CELLS,NO_TIME); + f.setMesh(m); + arr=DataArrayDouble.New(); + nbOfCells=m.getNumberOfCells(); + values1=[7.,107.,10007.,8.,108.,10008.,9.,109.,10009.,10.,110.,10010.,11.,111.,10011.] + arr.setValues(values1,nbOfCells,3); + f.setArray(arr); + renumber1=[3,1,0,4,2] + loc=[-0.05,-0.05, 0.55,-0.25, 0.55,0.15, -0.05,0.45, 0.45,0.45] + for j in xrange(5): + res=f.getValueOn(loc[2*j:2*j+2]); + for i in xrange(3): + self.assertTrue(abs(values1[i+3*j]-res[i])<1e-12); + pass + pass + f.renumberCells(renumber1,False); + ptr=f.getArray().getValues(); + expected1=[9.,109.,10009.,8.,108.,10008.,11.,111.,10011.,7.,107.,10007.,10.,110.,10010.] + for i in xrange(15): + self.assertTrue(abs(expected1[i]-ptr[i])<1e-12); + pass + #check that fields remains the same geometrically + for j in xrange(5): + res=f.getValueOn(loc[2*j:2*(j+1)]); + for i in xrange(3): + self.assertTrue(abs(values1[i+3*j]-res[i])<1e-12); + pass + pass + #On gauss + f=MEDCouplingFieldDouble.New(ON_GAUSS_PT,NO_TIME); + f.setMesh(m); + _a=0.446948490915965; + _b=0.091576213509771; + _p1=0.11169079483905; + _p2=0.0549758718227661; + refCoo1=[ 0.,0., 1.,0., 0.,1. ] + gsCoo1=[ 2*_b-1, 1-4*_b, 2*_b-1, 2.07*_b-1, 1-4*_b, 2*_b-1, 1-4*_a, 2*_a-1, 2*_a-1, 1-4*_a, 2*_a-1, 2*_a-1 ]; + wg1=[ 4*_p2, 4*_p2, 4*_p2, 4*_p1, 4*_p1, 4*_p1 ] + _refCoo1=refCoo1[0:6]; + _gsCoo1=gsCoo1[0:12]; + _wg1=wg1[0:6]; + f.setGaussLocalizationOnType(NORM_TRI3,_refCoo1,_gsCoo1,_wg1); + refCoo2=[ 0.,0., 1.,0., 1.,1., 0.,1. ] + _refCoo2=refCoo2[0:8]; + _gsCoo1=_gsCoo1[0:4] + _wg1=_wg1[0:2] + f.setGaussLocalizationOnType(NORM_QUAD4,_refCoo2,_gsCoo1,_wg1); + arr=DataArrayDouble.New(); + values2=[1.,1001.,2.,1002., 11.,1011.,12.,1012.,13.,1013.,14.,1014.,15.,1015.,16.,1016., 21.,1021.,22.,1022.,23.,1023.,24.,1024.,25.,1025.,26.,1026., 31.,1031.,32.,1032., 41.,1041.,42.,1042.] + arr.setValues(values2,18,2); + f.setArray(arr); + f.checkCoherency(); + fCpy=f.clone(True); + self.assertTrue(f.isEqual(fCpy,1e-12,1e-12)); + f.renumberCells(renumber1,False); + self.assertTrue(not f.isEqual(fCpy,1e-12,1e-12)); + expected2=[21.,1021.,22.,1022.,23.,1023.,24.,1024.,25.,1025.,26.,1026., 11.,1011.,12.,1012.,13.,1013.,14.,1014.,15.,1015.,16.,1016., 41.,1041.,42.,1042., 1.,1001.,2.,1002., 31.,1031.,32.,1032.] + ptr=f.getArray().getValues(); + for i in xrange(36): + self.assertTrue(abs(expected2[i]-ptr[i])<1e-12); + pass + renumber2=[2,1,4,0,3] + f.renumberCells(renumber2,False); + self.assertTrue(f.isEqual(fCpy,1e-12,1e-12)); + #GaussNE + f=MEDCouplingFieldDouble.New(ON_GAUSS_NE,NO_TIME); + f.setMesh(m); + arr=DataArrayDouble.New(); + values3=[1.,1001.,2.,1002.,3.,1003.,4.,1004., 11.,1011.,12.,1012.,13.,1013., 21.,1021.,22.,1022.,23.,1023., 31.,1031.,32.,1032.,33.,1033.,34.,1034., 41.,1041.,42.,1042.,43.,1043.,44.,1044.] + arr.setValues(values3,18,2); + f.setArray(arr); + f.checkCoherency(); + fCpy=f.clone(True); + self.assertTrue(f.isEqual(fCpy,1e-12,1e-12)); + f.renumberCells(renumber1,False); + self.assertTrue(not f.isEqual(fCpy,1e-12,1e-12)); + expected3=[21.,1021.,22.,1022.,23.,1023.,11.,1011.,12.,1012.,13.,1013.,41.,1041.,42.,1042.,43.,1043.,44.,1044.,1.,1001.,2.,1002.,3.,1003.,4.,1004.,31.,1031.,32.,1032.,33.,1033.,34.,1034.] + ptr=f.getArray().getValues(); + for i in xrange(36): + self.assertTrue(abs(expected3[i]-ptr[i])<1e-12); + pass + f.renumberCells(renumber2,False);#perform reverse operation of renumbering to check that the resulting field is equal. + self.assertTrue(f.isEqual(fCpy,1e-12,1e-12)); + # + pass + + def testRenumberNodesForFields(self): + m=MEDCouplingDataForTest.build2DTargetMesh_1(); + f=MEDCouplingFieldDouble.New(ON_NODES,NO_TIME); + f.setMesh(m); + self.assertEqual(9,f.getNumberOfMeshPlacesExpected()); + arr=DataArrayDouble.New(); + nbOfNodes=m.getNumberOfNodes(); + values1=[7.,107.,10007.,8.,108.,10008.,9.,109.,10009.,10.,110.,10010.,11.,111.,10011.,12.,112.,10012.,13.,113.,10013.,14.,114.,10014.,15.,115.,10015.] + arr.setValues(values1,nbOfNodes,3); + f.setArray(arr); + f.checkCoherency(); + renumber1=[0,4,1,3,5,2,6,7,8] + loc=[0.5432,-0.2432, 0.5478,0.1528] + expected1=[9.0272, 109.0272, 10009.0272, 11.4124,111.4124,10011.4124] + for j in xrange(2): + res=f.getValueOn(loc[2*j:2*j+2]); + for i in xrange(3): + self.assertTrue(abs(expected1[i+3*j]-res[i])<1e-12); + pass + pass + fCpy=f.clone(True); + self.assertTrue(f.isEqual(fCpy,1e-12,1e-12)); + f.renumberNodes(renumber1); + self.assertTrue(not f.isEqual(fCpy,1e-12,1e-12)); + for j in xrange(2): + res=f.getValueOn(loc[2*j:2*j+2]); + for i in xrange(3): + self.assertTrue(abs(expected1[i+3*j]-res[i])<1e-12); + pass + pass + expected2=[7.,107.,10007.,9.,109.,10009.,12.,112.,10012.,10.,110.,10010.,8.,108.,10008.,11.,111.,10011.,13.,113.,10013.,14.,114.,10014.,15.,115.,10015.] + for i in xrange(27): + self.assertTrue(abs(expected2[i]-f.getArray().getValues()[i])<1e-12); + pass + renumber2=[0,2,5,3,1,4,6,7,8] + f.renumberNodes(renumber2); + self.assertTrue(f.isEqual(fCpy,1e-12,1e-12)); + pass + + def testConvertQuadraticCellsToLinear(self): + mesh=MEDCouplingDataForTest.build2DTargetMesh_3(); + mesh.checkCoherency(); + types=mesh.getAllGeoTypes(); + types.sort() + self.assertEqual(5,len(types)); + expected1=[NORM_POLYGON, NORM_TRI3, NORM_QUAD4, NORM_TRI6, NORM_QUAD8] + expected1.sort() + self.assertEqual(expected1,types); + self.assertTrue(mesh.isPresenceOfQuadratic()); + self.assertEqual(62,mesh.getMeshLength()); + f1=mesh.getMeasureField(False); + # + mesh.convertQuadraticCellsToLinear(); + self.assertTrue(not mesh.isPresenceOfQuadratic()); + # + mesh.checkCoherency(); + f2=mesh.getMeasureField(False); + self.assertTrue(f1.getArray().isEqual(f2.getArray(),1e-12)); + self.assertEqual(48,mesh.getMeshLength()); + types2=mesh.getAllGeoTypes(); + types2.sort() + self.assertEqual(3,len(types2)); + expected2=[NORM_POLYGON, NORM_TRI3, NORM_QUAD4] + expected2.sort() + self.assertEqual(expected2,types2); + pass + + def testCheckGeoEquivalWith(self): + mesh1=MEDCouplingDataForTest.build2DTargetMesh_3(); + mesh2=MEDCouplingDataForTest.build2DTargetMesh_3(); + #First test mesh1 + cellCor,nodeCor=mesh1.checkGeoEquivalWith(mesh1,0,1e-12);#deepEqual + self.assertTrue(cellCor==None); + self.assertTrue(nodeCor==None); + cellCor,nodeCor=mesh1.checkGeoEquivalWith(mesh1,1,1e-12);#fastEqual + self.assertTrue(cellCor==None); + self.assertTrue(nodeCor==None); + cellCor,nodeCor=mesh1.checkGeoEquivalWith(mesh1,10,1e-12);#deepEqual with geo permutations + self.assertTrue(cellCor==None); + self.assertTrue(nodeCor==None); + #Second test mesh1 and mesh2 are 2 different meshes instance + cellCor,nodeCor=mesh1.checkGeoEquivalWith(mesh2,0,1e-12);#deepEqual + self.assertTrue(cellCor==None); + self.assertTrue(nodeCor==None); + cellCor,nodeCor=mesh1.checkGeoEquivalWith(mesh2,1,1e-12);#fastEqual + self.assertTrue(cellCor==None); + self.assertTrue(nodeCor==None); + cellCor,nodeCor=mesh1.checkGeoEquivalWith(mesh2,10,1e-12);#deepEqual with geo permutations + self.assertTrue(cellCor==None); + self.assertTrue(nodeCor==None); + #Third test : cell permutation by keeping the first the middle and the last as it is. + renum=[0,2,1,3,4,5,6,8,7,9] + mesh2.renumberCells(renum,False); + self.assertRaises(InterpKernelException,mesh1.checkGeoEquivalWith,mesh2,0,1e-12);#deepEqual fails + self.assertTrue(cellCor==None); + self.assertTrue(nodeCor==None); + cellCor,nodeCor=mesh1.checkGeoEquivalWith(mesh2,1,1e-12);#fastEqual do not see anything + self.assertTrue(cellCor==None); + self.assertTrue(nodeCor==None); + cellCor,nodeCor=mesh1.checkGeoEquivalWith(mesh2,10,1e-12);#deepEqual with geo permutations + self.assertTrue(cellCor); + self.assertEqual(10,cellCor.getNumberOfTuples()); + self.assertEqual(1,cellCor.getNumberOfComponents()); + self.assertEqual(renum,list(cellCor.getValues())) + self.assertTrue(nodeCor==None); + cellCor=0; + self.assertTrue(nodeCor==None); + a,b=mesh1.checkDeepEquivalWith(mesh2,0,1e-12); + self.assertEqual(renum,list(a.getValues())) + self.assertTrue(b==None); + mesh2.setCoords(mesh1.getCoords()) + a=mesh1.checkDeepEquivalOnSameNodesWith(mesh2,0,1e-12); + self.assertEqual(renum,list(a.getValues())) + #4th test : cell and node permutation by keeping the first the middle and the last as it is. + mesh2=MEDCouplingDataForTest.build2DTargetMesh_3(); + renum2=[0,2,1,3,4,5,6,8,7,9,10] + mesh2.renumberCells(renum,False); + mesh2.renumberNodes(renum2,11); + cellCor=None + nodeCor=None + self.assertRaises(InterpKernelException,mesh1.checkGeoEquivalWith,mesh2,0,1e-12);#deepEqual fails + self.assertTrue(cellCor==None); + self.assertTrue(nodeCor==None); + cellCor,nodeCor=mesh1.checkGeoEquivalWith(mesh2,1,1e-12);#fastEqual do not see anything + self.assertTrue(cellCor==None); + self.assertTrue(nodeCor==None); + cellCor,nodeCor=mesh1.checkGeoEquivalWith(mesh2,10,1e-12);#deepEqual with geo permutations + self.assertTrue(cellCor); + self.assertEqual(10,cellCor.getNumberOfTuples()); + self.assertEqual(1,cellCor.getNumberOfComponents()); + self.assertEqual(renum,list(cellCor.getValues())) + self.assertTrue(nodeCor); + self.assertEqual(11,nodeCor.getNumberOfTuples()); + self.assertEqual(1,nodeCor.getNumberOfComponents()); + self.assertEqual(renum2,list(nodeCor.getValues())) + cellCor=0; + nodeCor=0; + #5th test : modification of the last cell to check fastCheck detection. + mesh2=MEDCouplingDataForTest.build2DTargetMesh_3(); + renum3=[0,2,1,3,4,5,6,8,9,7] + mesh2.renumberCells(renum3,False); + mesh2.renumberNodes(renum2,11); + cellCor=None + nodeCor=None + self.assertRaises(InterpKernelException,mesh1.checkGeoEquivalWith,mesh2,0,1e-12) + self.assertTrue(cellCor==None); + self.assertTrue(nodeCor==None); + self.assertRaises(InterpKernelException,mesh1.checkGeoEquivalWith,mesh2,1,1e-12) + self.assertTrue(cellCor==None); + self.assertTrue(nodeCor==None); + cellCor,nodeCor=mesh2.checkGeoEquivalWith(mesh1,10,1e-12);#deepEqual with geo permutations + self.assertTrue(cellCor!=None); + self.assertEqual(10,cellCor.getNumberOfTuples()); + self.assertEqual(1,cellCor.getNumberOfComponents()); + self.assertEqual(renum3,list(cellCor.getValues())) + self.assertTrue(nodeCor!=None); + self.assertEqual(11,nodeCor.getNumberOfTuples()); + self.assertEqual(1,nodeCor.getNumberOfComponents()); + self.assertEqual(renum2,list(nodeCor.getValues())); + pass + + def testCheckGeoEquivalWith2(self): + mesh1=MEDCouplingDataForTest.build2DTargetMesh_4(); + mesh2=MEDCouplingDataForTest.build2DTargetMesh_1(); + cellCor,nodeCor=mesh1.checkGeoEquivalWith(mesh2,10,1e-12); + self.assertEqual(None,cellCor); + self.assertNotEqual(None,nodeCor); + expected1=[0, 1, 3, 4, 5, 6, 7, 8, 9] + for i in xrange(9): + self.assertEqual(expected1[i],nodeCor.getIJ(i,0)); + pass + pass + + def testSwig2CheckDeepEquivalWith1(self): + eps = 1.0e-8 + mcart = MEDCouplingCMesh() + mcart.setCoordsAt(0, DataArrayDouble([0.0,1.5,2.0])) + mcart.setCoordsAt(1, DataArrayDouble([1.0,2.5,3.0,4.0])) + m = mcart.buildUnstructured() + m2 = m[1:m.getNumberOfCells()] + self.assertRaises(InterpKernelException, m.checkDeepEquivalWith, m2, 0, eps) + self.assertRaises(InterpKernelException, m.checkDeepEquivalWith, m2, 1, eps) + self.assertRaises(InterpKernelException, m.checkDeepEquivalWith, m2, 2, eps) + pass + + def testSwig2CheckDeepEquivalWith2(self): + eps = 1.0e-8 + m = MEDCouplingUMesh("tst", 2) + m.setCoords(DataArrayDouble([], 0,2)) + m.setConnectivity(DataArrayInt([]), DataArrayInt([0])) + m2 = m.deepCpy() + m.checkDeepEquivalWith(m2, 0, eps) # Should not raise! + pass + + def testCopyTinyStringsFromOnFields(self): + m=MEDCouplingDataForTest.build3DSurfTargetMesh_1(); + nbOfCells=m.getNumberOfCells(); + f=MEDCouplingFieldDouble.New(ON_CELLS,LINEAR_TIME); + f.setMesh(m); + self.assertEqual(5,f.getNumberOfMeshPlacesExpected()); + f.setName("a"); + f.setDescription("b"); + a1=DataArrayDouble.New(); + a1.alloc(nbOfCells,2); + a1.fillWithZero(); + a1.setInfoOnComponent(0,"c"); + a1.setInfoOnComponent(1,"d"); + a2=a1.deepCpy(); + a2.setInfoOnComponent(0,"e"); + a2.setInfoOnComponent(1,"f"); + f.setArray(a1); + f.setEndArray(a2); + f.setEndTime(3.,3,4); + m.setName("g"); + m.getCoords().setInfoOnComponent(0,"h"); + m.getCoords().setInfoOnComponent(1,"i"); + m.getCoords().setInfoOnComponent(2,"j"); + # + f.checkCoherency(); + f2=f.clone(True); + self.assertTrue(f2.isEqual(f,1e-12,1e-12)); + f2.setName("smth"); + self.assertTrue(not f2.isEqual(f,1e-12,1e-12)); + f2.copyTinyStringsFrom(f); + self.assertTrue(f2.isEqual(f,1e-12,1e-12)); + f2.setDescription("GGG"); + self.assertTrue(not f2.isEqual(f,1e-12,1e-12)); + f2.copyTinyStringsFrom(f); + self.assertTrue(f2.isEqual(f,1e-12,1e-12)); + f2.getArray().setInfoOnComponent(0,"mmmm"); + self.assertTrue(not f2.isEqual(f,1e-12,1e-12)); + f2.copyTinyStringsFrom(f); + self.assertTrue(f2.isEqual(f,1e-12,1e-12)); + f2.getEndArray().setInfoOnComponent(1,"mmmm"); + self.assertTrue(not f2.isEqual(f,1e-12,1e-12)); + f2.copyTinyStringsFrom(f); + self.assertTrue(f2.isEqual(f,1e-12,1e-12)); + m2=m.clone(True); + self.assertTrue(m2.isEqual(m,1e-12)); + m2.setName("123"); + self.assertTrue(not m2.isEqual(m,1e-12)); + m2.copyTinyStringsFrom(m); + self.assertTrue(m2.isEqual(m,1e-12)); + m2.getCoords().setInfoOnComponent(1,"eee"); + self.assertTrue(not m2.isEqual(m,1e-12)); + m2.copyTinyStringsFrom(m); + self.assertTrue(m2.isEqual(m,1e-12)); + pass + + def testTryToShareSameCoordsPermute(self): + m=MEDCouplingDataForTest.build3DSurfTargetMesh_1(); + m2=MEDCouplingDataForTest.build3DSurfTargetMesh_1(); + #self.assertTrue(m.getCoords()!=m2.getCoords()); + m.tryToShareSameCoordsPermute(m2,1e-12); + #self.assertTrue(m.getCoords()==m2.getCoords()); + self.assertTrue(m2.isEqual(m,1e-12)); + renum1=[1,2,0,5,8,7,4,3,6] + r1=DataArrayInt.New() + r1.setValues(renum1,len(renum1),1) + m.renumberNodes(r1,9); + #self.assertTrue(m.getCoords()!=m2.getCoords()); + self.assertTrue(not m2.isEqual(m,1e-12)); + m.tryToShareSameCoordsPermute(m2,1e-12); + #self.assertTrue(m.getCoords()==m2.getCoords()); + self.assertTrue(m2.isEqual(m,1e-12)); + pass + + def testTryToShareSameCoordsPermute2(self): + m1=MEDCouplingDataForTest.build2DTargetMesh_4(); + targetCoords=[-0.3,-0.3, 0.2,-0.3, -0.3,0.2, 0.2,0.2 ] + targetConn=[0,2,3,1] + m2=MEDCouplingUMesh.New(); + m2.setMeshDimension(2); + m2.allocateCells(1); + m2.insertNextCell(NORM_QUAD4,targetConn[0:4]) + m2.finishInsertingCells(); + myCoords=DataArrayDouble.New(); + myCoords.setValues(targetCoords,4,2); + m2.setCoords(myCoords); + m2.checkCoherency(); + m1.checkCoherency(); + # + expected1=[0.25,0.125,0.125,0.25,0.25] + f1=m1.getMeasureField(False); + f2=m2.getMeasureField(False); + self.assertEqual(5,f1.getArray().getNumberOfTuples()); + self.assertEqual(1,f2.getArray().getNumberOfTuples()); + for i in xrange(5): + self.assertAlmostEqual(expected1[i],f1.getIJ(i,0),12); + pass + self.assertAlmostEqual(expected1[0],f2.getIJ(0,0),12); + self.assertRaises(InterpKernelException,m1.tryToShareSameCoordsPermute,m2,1e-12);# <- here in this order the sharing is impossible. + # Let's go for deeper test of tryToShareSameCoordsPermute + m2.tryToShareSameCoordsPermute(m1,1e-12); + f1=m1.getMeasureField(False); + f2=m2.getMeasureField(False); + self.assertEqual(5,f1.getArray().getNumberOfTuples()); + self.assertEqual(1,f2.getArray().getNumberOfTuples()); + for i in xrange(5): + self.assertAlmostEqual(expected1[i],f1.getIJ(i,0),12); + pass + self.assertAlmostEqual(expected1[0],f2.getIJ(0,0),12); + pass + + def testChangeUnderlyingMesh1(self): + mesh1=MEDCouplingDataForTest.build2DTargetMesh_3(); + mesh2=MEDCouplingDataForTest.build2DTargetMesh_3(); + f1=MEDCouplingFieldDouble.New(ON_CELLS,NO_TIME); + f1.setMesh(mesh1); + array=DataArrayDouble.New(); + arr=[7., 107., 8., 108., 9., 109., 10., 110., 11., 111., 12., 112., 13., 113., 14., 114., 15., 115., 16., 116.] + array.setValues(arr,mesh1.getNumberOfCells(),2); + f1.setArray(array); + # + renum=[0,2,1,3,4,5,6,8,7,9] + mesh2.renumberCells(renum,False); + #self.assertTrue(f1.getMesh()==mesh1); + f1.changeUnderlyingMesh(mesh1,10,1e-12);# nothing done only to check that nothing done. + #self.assertTrue(f1.getMesh()==mesh1); + f1.changeUnderlyingMesh(mesh2,10,1e-12); + #self.assertTrue(f1.getMesh()==mesh2); + expected1=[7.,107.,9.,109.,8.,108.,10.,110.,11.,111.,12.,112.,13.,113.,15.,115.,14.,114.,16.,116.] + for i in xrange(20): + self.assertAlmostEqual(expected1[i],f1.getArray().getIJ(0,i),12); + pass + # + f1=MEDCouplingFieldDouble.New(ON_NODES,NO_TIME); + f1.setMesh(mesh1); + array=DataArrayDouble.New(); + arr2=[7.,107.,8.,108.,9.,109.,10.,110.,11.,111.,12.,112.,13.,113.,14.,114.,15.,115.,16.,116.,17.,117.] + array.setValues(arr2,mesh1.getNumberOfNodes(),2); + f1.setArray(array); + # + renum2=[0,2,10,3,4,5,6,8,7,9,1] + mesh2.renumberNodes(renum2,11); + #self.assertTrue(f1.getMesh()==mesh1); + f1.changeUnderlyingMesh(mesh2,10,1e-12); + #self.assertTrue(f1.getMesh()==mesh2); + expected2=[7.,107.,17.,117.,8.,108.,10.,110.,11.,111.,12.,112.,13.,113.,15.,115.,14.,114.,16.,116.,9.,109.] + for i in xrange(22): + self.assertAlmostEqual(expected2[i],f1.getArray().getIJ(0,i),12); + pass + pass + + def testGetMaxValue1(self): + m=MEDCouplingDataForTest.build3DSurfTargetMesh_1(); + nbOfCells=m.getNumberOfCells(); + f=MEDCouplingFieldDouble.New(ON_CELLS,LINEAR_TIME); + f.setMesh(m); + a1=DataArrayDouble.New(); + val1=[3.,4.,5.,6.,7.] + a1.setValues(val1,nbOfCells,1); + a2=DataArrayDouble.New(); + val2=[0.,1.,2.,8.,7.] + a2.setValues(val2,nbOfCells,1); + f.setArray(a1); + f.setEndArray(a2); + f.setEndTime(3.,3,4); + f.checkCoherency(); + # + self.assertAlmostEqual(8.,f.getMaxValue(),14); + self.assertAlmostEqual(0.,f.getMinValue(),14); + self.assertAlmostEqual(5.,f.getAverageValue(),14); + self.assertAlmostEqual(5.125,f.getWeightedAverageValue(0,True),14); + a1.setIJ(0,2,9.5); + self.assertAlmostEqual(9.5,f.getMaxValue(),14); + self.assertAlmostEqual(0.,f.getMinValue(),14); + a2.setIJ(0,0,9.); + self.assertAlmostEqual(9.5,f.getMaxValue(),14); + self.assertAlmostEqual(1.,f.getMinValue(),14); + pass + + def testSubstractInPlaceDM1(self): + mesh1=MEDCouplingDataForTest.build2DTargetMesh_3(); + mesh2=MEDCouplingDataForTest.build2DTargetMesh_3(); + f1=MEDCouplingFieldDouble.New(ON_CELLS,NO_TIME); + f1.setMesh(mesh1); + array=DataArrayDouble.New(); + arr=[7.,107.,8.,108.,9.,109.,10.,110.,11.,111.,12.,112.,13.,113.,14.,114.,15.,115.,16.,116.] + array.setValues(arr,mesh1.getNumberOfCells(),2); + f1.setArray(array); + # + self.assertEqual(10,f1.getNumberOfTuples()); + self.assertEqual(2,f1.getNumberOfComponents()); + self.assertEqual(20,f1.getNumberOfValues()); + # + renum=[0,2,3,1,4,5,6,8,7,9] + mesh2.renumberCells(renum,False); + # + f2=MEDCouplingFieldDouble.New(ON_CELLS,NO_TIME); + f2.setMesh(mesh2); + array=DataArrayDouble.New(); + arr2=[7.1,107.1,10.1,110.1,8.1,108.1,9.1,109.1,11.1,111.1,12.1,112.1,13.1,113.1,15.1,115.1,14.1,114.1,16.1,116.1] + array.setValues(arr2,mesh2.getNumberOfCells(),2); + f2.setArray(array); + # + f1.substractInPlaceDM(f2,10,1e-12); + f1.applyFunc(1,"abs(x+y+0.2)"); + self.assertAlmostEqual(0.,f1.getMaxValue(),13); + pass + + def testDotCrossProduct1(self): + mesh1=MEDCouplingDataForTest.build2DTargetMesh_3(); + f1=MEDCouplingFieldDouble.New(ON_CELLS,ONE_TIME); + f1.setTime(2.3,5,6); + f1.setMesh(mesh1); + array=DataArrayDouble.New(); + arr1=[7.,107.,207.,8.,108.,208.,9.,109.,209.,10.,110.,210.,11.,111.,211.,12.,112.,212.,13.,113.,213.,14.,114.,214.,15.,115.,215.,16.,116.,216.] + array.setValues(arr1,mesh1.getNumberOfCells(),3); + f1.setArray(array); + f2=MEDCouplingFieldDouble.New(ON_CELLS,ONE_TIME); + f2.setTime(7.8,4,5); + f2.setMesh(mesh1); + array=DataArrayDouble.New(); + arr2=[1.,2.,3.,4.,5.,6.,7.,8.,9.,10.,11.,12.,13.,14.,15.,16.,17.,18.,19.,20.,21.,22.,23.,24.,25.,26.,27.,28.,29.,30.] + array.setValues(arr2,mesh1.getNumberOfCells(),3); + f2.setArray(array); + # + f3=f1.dot(f2); + expected1=[842.,1820.,2816.,3830.,4862.,5912.,6980.,8066.,9170.,10292.] + for i in xrange(10): + self.assertAlmostEqual(expected1[i],f3.getIJ(i,0),9); + pass + # + f4=f1.crossProduct(f2); + expected2=[-93., 186., -93., -392., 784., -392., -691., 1382., -691., -990., 1980., -990., -1289., 2578., -1289., -1588., 3176., -1588., -1887., 3774., -1887., -2186., 4372., -2186., -2485., 4970., -2485., -2784., 5568., -2784.] + for i in xrange(30): + self.assertAlmostEqual(expected2[i],f4.getIJ(0,i),9); + pass + pass + + def testMinMaxFields1(self): + mesh1=MEDCouplingDataForTest.build2DTargetMesh_3(); + f1=MEDCouplingFieldDouble.New(ON_CELLS,ONE_TIME); + f1.setTime(2.3,5,6); + f1.setMesh(mesh1); + array=DataArrayDouble.New(); + arr1=[7.,107.,207.,8.,108.,208.,9.,109.,209.,10.,110.,210.,11.,111.,211.,12.,112.,212.,13.,113.,213.,14.,114.,214.,15.,115.,215.,16.,116.,216.] + array.setValues(arr1,mesh1.getNumberOfCells(),3); + f1.setArray(array); + f2=MEDCouplingFieldDouble.New(ON_CELLS,ONE_TIME); + f2.setTime(7.8,4,5); + f2.setMesh(mesh1); + array=DataArrayDouble.New(); + arr2=[6.,108.,206.,9.,107.,209.,8.,110.,208.,11.,109.,211.,10.,112.,210.,13.,111.,213.,12.,114.,212.,15.,113.,215.,14.,116.,214.,17.,115.,217.] + array.setValues(arr2,mesh1.getNumberOfCells(),3); + f2.setArray(array); + # + f3=f1.max(f2); + expected1=[7.,108.,207.,9.,108.,209.,9.,110.,209.,11.,110.,211.,11.,112.,211.,13.,112.,213.,13.,114.,213.,15.,114.,215.,15.,116.,215.,17.,116.,217.] + for i in xrange(30): + self.assertAlmostEqual(expected1[i],f3.getIJ(0,i),9); + pass + # + f4=f1.min(f2); + expected2=[6.,107.,206.,8.,107.,208.,8.,109.,208.,10.,109.,210.,10.,111.,210.,12.,111.,212.,12.,113.,212.,14.,113.,214.,14.,115.,214.,16.,115.,216.] + for i in xrange(30): + self.assertAlmostEqual(expected2[i],f4.getIJ(0,i),9); + pass + # + pass + + def testApplyLin1(self): + mesh1=MEDCouplingDataForTest.build2DTargetMesh_3(); + f1=MEDCouplingFieldDouble.New(ON_CELLS,LINEAR_TIME); + f1.setMesh(mesh1); + array=DataArrayDouble.New(); + arr=[7.,107.,8.,108.,9.,109.,10.,110.,11.,111.,12.,112.,13.,113.,14.,114.,15.,115.,16.,116.] + array.setValues(arr,mesh1.getNumberOfCells(),2); + f1.setArray(array); + # + f1.applyLin(2.,3.,0); + expected1=[17.,107.,19.,108.,21.,109.,23.,110.,25.,111.,27.,112.,29.,113.,31.,114.,33.,115.,35.,116.] + for i in xrange(20): + self.assertAlmostEqual(expected1[i],f1.getIJ(0,i),9); + pass + # + arr2=[2.,102.,3.,103.,4.,104.,5.,105.,6.,106.,7.,107.,8.,108.,9.,109.,10.,110.,11.,111.] + array=DataArrayDouble.New(); + array.setValues(arr2,mesh1.getNumberOfCells(),2); + f1.setEndArray(array); + # + f1.applyLin(4.,5.,1); + # + expected2=[17.,433.,19.,437.,21.,441.,23.,445.,25.,449.,27.,453.,29.,457.,31.,461.,33.,465.,35.,469.] + for i in xrange(20): + self.assertAlmostEqual(expected2[i],f1.getIJ(0,i),9); + pass + expected3=[2.,413.,3.,417.,4.,421.,5.,425.,6.,429.,7.,433.,8.,437.,9.,441.,10.,445.,11.,449.] + for i in xrange(20): + self.assertAlmostEqual(expected3[i],f1.getEndArray().getIJ(0,i),9); + pass + # + pass + + def testGetIdsInRange1(self): + mesh1=MEDCouplingDataForTest.build2DTargetMesh_3(); + f1=MEDCouplingFieldDouble.New(ON_CELLS,ONE_TIME); + f1.setTime(2.3,5,6); + f1.setMesh(mesh1); + array=DataArrayDouble.New(); + arr1=[2.,8.,6.,5.,11.,7.,9.,3.,10.,4.] + array.setValues(arr1,mesh1.getNumberOfCells(),1); + f1.setArray(array); + # + f1.checkCoherency(); + da=f1.getIdsInRange(2.9,7.1); + self.failUnlessEqual(5,da.getNbOfElems()); + expected1=[2,3,5,7,9] + self.failUnlessEqual(expected1,list(da.getValues())); + da=f1.getIdsInRange(8.,12.); + self.failUnlessEqual(4,da.getNbOfElems()); + expected2=[1,4,6,8] + self.failUnlessEqual(expected2,list(da.getValues())); + # + pass + + def testBuildSubPart1(self): + mesh1=MEDCouplingDataForTest.build2DTargetMesh_1(); + f1=MEDCouplingFieldDouble.New(ON_CELLS,ONE_TIME); + f1.setTime(2.3,5,6); + f1.setMesh(mesh1); + array=DataArrayDouble.New(); + arr1=[3.,103.,4.,104.,5.,105.,6.,106.,7.,107.] + array.setValues(arr1,mesh1.getNumberOfCells(),2); + f1.setArray(array); + # + part1=[2,1,4] + f2=f1[part1]; + f2.zipCoords() + self.failUnlessEqual(3,f2.getNumberOfTuples()); + self.failUnlessEqual(2,f2.getNumberOfComponents()); + expected1=[5.,105.,4.,104.,7.,107.] + for i in xrange(6): + self.assertAlmostEqual(f2.getIJ(0,i),expected1[i],12); + pass + self.failUnlessEqual(3,f2.getMesh().getNumberOfCells()); + self.failUnlessEqual(6,f2.getMesh().getNumberOfNodes()); + self.failUnlessEqual(2,f2.getMesh().getSpaceDimension()); + self.failUnlessEqual(2,f2.getMesh().getMeshDimension()); + m2C=f2.getMesh(); + self.failUnlessEqual(13,m2C.getMeshLength()); + expected2=[0.2, -0.3, 0.7, -0.3, 0.2, 0.2, 0.7, 0.2, 0.2, 0.7, 0.7, 0.7] + for i in xrange(12): + self.assertAlmostEqual(expected2[i],m2C.getCoords().getIJ(0,i),12); + pass + expected3=[3,2,3,1,3,0,2,1,4,4,5,3,2] + self.failUnlessEqual(expected3,list(m2C.getNodalConnectivity().getValues())); + expected4=[0,4,8,13] + self.failUnlessEqual(expected4,list(m2C.getNodalConnectivityIndex().getValues())); + # Test with field on nodes. + f1=MEDCouplingFieldDouble.New(ON_NODES,ONE_TIME); + f1.setTime(2.3,5,6); + f1.setMesh(mesh1); + array=DataArrayDouble.New(); + arr2=[3.,103.,4.,104.,5.,105.,6.,106.,7.,107.,8.,108.,9.,109.,10.,110.,11.,111.] + array.setValues(arr2,mesh1.getNumberOfNodes(),2); + f1.setArray(array); + part2=[1,2] + f2=f1.buildSubPart(part2); + self.failUnlessEqual(4,f2.getNumberOfTuples()); + self.failUnlessEqual(2,f2.getNumberOfComponents()); + expected5=[4.,104.,5.,105.,7.,107.,8.,108.] + for i in xrange(8): + self.assertAlmostEqual(f2.getIJ(0,i),expected5[i],12); + pass + self.failUnlessEqual(2,f2.getMesh().getNumberOfCells()); + self.failUnlessEqual(4,f2.getMesh().getNumberOfNodes()); + self.failUnlessEqual(2,f2.getMesh().getSpaceDimension()); + self.failUnlessEqual(2,f2.getMesh().getMeshDimension()); + m2C=f2.getMesh(); + self.failUnlessEqual(8,m2C.getMeshLength()); + for i in xrange(8):#8 is not an error + self.assertAlmostEqual(expected2[i],m2C.getCoords().getIJ(0,i),12); + pass + self.failUnlessEqual(expected3[:4],list(m2C.getNodalConnectivity().getValues())[4:]); + self.failUnlessEqual(expected3[4:8],list(m2C.getNodalConnectivity().getValues())[:4]); + self.failUnlessEqual(expected4[:3],list(m2C.getNodalConnectivityIndex().getValues())); + #idem previous because nodes of cell#4 are not fully present in part3 + part3=[1,2] + arrr=DataArrayInt.New(); + arrr.setValues(part3,2,1); + f2=f1.buildSubPart(arrr); + self.failUnlessEqual(4,f2.getNumberOfTuples()); + self.failUnlessEqual(2,f2.getNumberOfComponents()); + for i in xrange(8): + self.assertAlmostEqual(f2.getIJ(0,i),expected5[i],12); + pass + self.failUnlessEqual(2,f2.getMesh().getNumberOfCells()); + self.failUnlessEqual(4,f2.getMesh().getNumberOfNodes()); + self.failUnlessEqual(2,f2.getMesh().getSpaceDimension()); + self.failUnlessEqual(2,f2.getMesh().getMeshDimension()); + m2C=f2.getMesh(); + self.failUnlessEqual(8,m2C.getMeshLength()); + for i in xrange(8):#8 is not an error + self.assertAlmostEqual(expected2[i],m2C.getCoords().getIJ(0,i),12); + pass + self.failUnlessEqual(expected3[:4],list(m2C.getNodalConnectivity().getValues())[4:8]); + self.failUnlessEqual(expected3[4:8],list(m2C.getNodalConnectivity().getValues())[:4]); + self.failUnlessEqual(expected4[:3],list(m2C.getNodalConnectivityIndex().getValues())); + # + part4=[1,2,4] + f2=f1.buildSubPart(part4); + self.failUnlessEqual(6,f2.getNumberOfTuples()); + self.failUnlessEqual(2,f2.getNumberOfComponents()); + expected6=[4.,104.,5.,105.,7.,107.,8.,108.,10.,110.,11.,111.] + for i in xrange(12): + self.assertAlmostEqual(f2.getIJ(0,i),expected6[i],12); + pass + self.failUnlessEqual(3,f2.getMesh().getNumberOfCells()); + self.failUnlessEqual(6,f2.getMesh().getNumberOfNodes()); + self.failUnlessEqual(2,f2.getMesh().getSpaceDimension()); + self.failUnlessEqual(2,f2.getMesh().getMeshDimension()); + m2C=f2.getMesh(); + self.failUnlessEqual(13,m2C.getMeshLength()); + for i in xrange(12): + self.assertAlmostEqual(expected2[i],m2C.getCoords().getIJ(0,i),12); + pass + self.failUnlessEqual(expected3[0:4],list(m2C.getNodalConnectivity().getValues())[4:8]); + self.failUnlessEqual(expected3[4:8],list(m2C.getNodalConnectivity().getValues())[0:4]); + self.failUnlessEqual(expected3[8:13],list(m2C.getNodalConnectivity().getValues())[8:13]); + self.failUnlessEqual(expected4,list(m2C.getNodalConnectivityIndex().getValues())); + pass + + def testDoublyContractedProduct1(self): + mesh1=MEDCouplingDataForTest.build2DTargetMesh_1(); + f1=MEDCouplingFieldDouble.New(ON_CELLS,NO_TIME); + f1.setMesh(mesh1); + array=DataArrayDouble.New(); + arr1=[7.8,8.9,9.1,10.2,23.4,34.5, 7.8,8.9,9.1,10.2,23.4,34.5, 7.8,8.9,9.1,10.2,23.4,34.5, 7.8,8.9,9.1,10.2,23.4,34.5, 7.8,8.9,9.1,10.2,23.4,34.5] + array.setValues(arr1,mesh1.getNumberOfCells(),6); + f1.setArray(array); + f1.checkCoherency(); + # + f2=f1.doublyContractedProduct(); + f2.checkCoherency(); + self.assertEqual(1,f2.getNumberOfComponents()); + self.assertEqual(5,f2.getNumberOfTuples()); + for i in xrange(5): + self.assertAlmostEqual(3906.56,f2.getIJ(i,0),9); + pass + # + pass + + def testDeterminant1(self): + mesh1=MEDCouplingDataForTest.build2DTargetMesh_1(); + f1=MEDCouplingFieldDouble.New(ON_CELLS,CONST_ON_TIME_INTERVAL); + f1.setTime(2.3,5,6); + f1.setEndTime(3.8,7,3); + f1.setMesh(mesh1); + array=DataArrayDouble.New(); + arr1=[1.2,2.3,3.4,4.5, 1.2,2.3,3.4,4.5, 1.2,2.3,3.4,4.5, 1.2,2.3,3.4,4.5, 1.2,2.3,3.4,4.5] + array.setValues(arr1,mesh1.getNumberOfCells(),4); + f1.setArray(array); + #4 components + f1.checkCoherency(); + f2=f1.determinant(); + f2.checkCoherency(); + self.assertEqual(CONST_ON_TIME_INTERVAL,f2.getTimeDiscretization()); + self.assertEqual(1,f2.getNumberOfComponents()); + self.assertEqual(5,f2.getNumberOfValues()); + for i in xrange(5): + self.assertAlmostEqual(-2.42,f2.getIJ(i,0),13); + pass + #6 components multi arrays with end array not defined + f1=MEDCouplingFieldDouble.New(ON_NODES,LINEAR_TIME); + f1.setTime(2.3,5,6); + f1.setEndTime(3.8,7,3); + f1.setMesh(mesh1); + array=DataArrayDouble.New(); + arr2=[1.2,2.3,3.4,4.5,5.6,6.7, 1.2,2.3,3.4,4.5,5.6,6.7, 1.2,2.3,3.4,4.5,5.6,6.7, 1.2,2.3,3.4,4.5,5.6,6.7, 1.2,2.3,3.4,4.5,5.6,6.7, + 1.2,2.3,3.4,4.5,5.6,6.7, 1.2,2.3,3.4,4.5,5.6,6.7, 1.2,2.3,3.4,4.5,5.6,6.7, 1.2,2.3,3.4,4.5,5.6,6.7] + array.setValues(arr2,mesh1.getNumberOfNodes(),6); + f1.setArray(array); + self.assertRaises(InterpKernelException,f1.checkCoherency);#no end array specified ! + # + f2=f1.determinant(); + self.assertEqual(LINEAR_TIME,f2.getTimeDiscretization()); + self.assertEqual(1,f2.getArray().getNumberOfComponents()); + self.assertEqual(9,f2.getNumberOfTuples()); + for i in xrange(9): + self.assertAlmostEqual(137.335,f2.getIJ(i,0),10); + pass + #6 components multi arrays with end array defined + array=DataArrayDouble.New(); + arr3=[7.8,8.9,9.1,10.2,23.4,34.5, 7.8,8.9,9.1,10.2,23.4,34.5, 7.8,8.9,9.1,10.2,23.4,34.5, 7.8,8.9,9.1,10.2,23.4,34.5, 7.8,8.9,9.1,10.2,23.4,34.5, + 7.8,8.9,9.1,10.2,23.4,34.5, 7.8,8.9,9.1,10.2,23.4,34.5, 7.8,8.9,9.1,10.2,23.4,34.5, 7.8,8.9,9.1,10.2,23.4,34.5] + array.setValues(arr3,mesh1.getNumberOfNodes(),6); + f1.setEndArray(array); + f1.checkCoherency(); + f2=f1.determinant(); + f2.checkCoherency(); + self.assertEqual(LINEAR_TIME,f2.getTimeDiscretization()); + self.assertEqual(1,f2.getNumberOfComponents()); + self.assertEqual(9,f2.getNumberOfTuples()); + time2,it,order=f2.getTime() + self.assertAlmostEqual(2.3,time2,12); + self.assertEqual(5,it); + self.assertEqual(6,order); + time2,it,order=f2.getEndTime() + self.assertAlmostEqual(3.8,time2,12); + self.assertEqual(7,it); + self.assertEqual(3,order); + for i in xrange(9): + self.assertAlmostEqual(137.335,f2.getIJ(i,0),10); + self.assertAlmostEqual(1289.685,f2.getEndArray().getIJ(i,0),9); + pass + #9 components + f1=MEDCouplingFieldDouble.New(ON_CELLS,ONE_TIME); + f1.setTime(7.8,10,2); + f1.setMesh(mesh1); + array=DataArrayDouble.New(); + arr4=[1.2,2.3,3.4,4.5,5.6,6.7,7.8,8.9,9.1, 1.2,2.3,3.4,4.5,5.6,6.7,7.8,8.9,9.1, 1.2,2.3,3.4,4.5,5.6,6.7,7.8,8.9,9.1, 1.2,2.3,3.4,4.5,5.6,6.7,7.8,8.9,9.1, 1.2,2.3,3.4,4.5,5.6,6.7,7.8,8.9,9.1] + array.setValues(arr4,mesh1.getNumberOfCells(),9); + f1.setArray(array); + # + f1.checkCoherency(); + f2=f1.determinant(); + f2.checkCoherency(); + self.assertEqual(ONE_TIME,f2.getTimeDiscretization()); + self.assertEqual(1,f2.getNumberOfComponents()); + self.assertEqual(5,f2.getNumberOfTuples()); + time2,it,order=f2.getTime() + self.assertAlmostEqual(7.8,time2,12); + self.assertEqual(10,it); + self.assertEqual(2,order); + for i in xrange(5): + self.assertAlmostEqual(3.267,f2.getIJ(i,0),13); + pass + pass + + def testEigenValues1(self): + mesh1=MEDCouplingDataForTest.build2DTargetMesh_1(); + f1=MEDCouplingFieldDouble.New(ON_CELLS,NO_TIME); + f1.setMesh(mesh1); + array=DataArrayDouble.New(); + arr1=[1.2,2.3,3.4,4.5,5.6,6.7, 1.2,2.3,3.4,4.5,5.6,6.7, 1.2,2.3,3.4,4.5,5.6,6.7, 1.2,2.3,3.4,4.5,5.6,6.7, 1.2,2.3,3.4,4.5,5.6,6.7] + array.setValues(arr1,mesh1.getNumberOfCells(),6); + f1.setArray(array); + f1.checkCoherency(); + # + f2=f1.eigenValues(); + f2.checkCoherency(); + self.assertEqual(3,f2.getNumberOfComponents()); + self.assertEqual(5,f2.getNumberOfTuples()); + expected1=[13.638813677891717,-4.502313844635971,-2.2364998332557486] + for i in xrange(5): + self.assertAlmostEqual(expected1[0],f2.getIJ(i,0),13); + self.assertAlmostEqual(expected1[1],f2.getIJ(i,1),13); + self.assertAlmostEqual(expected1[2],f2.getIJ(i,2),13); + pass + pass + + def testEigenVectors1(self): + mesh1=MEDCouplingDataForTest.build2DTargetMesh_1(); + f1=MEDCouplingFieldDouble.New(ON_CELLS,NO_TIME); + f1.setMesh(mesh1); + array=DataArrayDouble.New(); + arr1=[1.2,2.3,3.4,4.5,5.6,6.7, 1.2,2.3,3.4,4.5,5.6,6.7, 1.2,2.3,3.4,4.5,5.6,6.7, 1.2,2.3,3.4,4.5,5.6,6.7, 1.2,2.3,3.4,4.5,5.6,6.7] + array.setValues(arr1,mesh1.getNumberOfCells(),6); + f1.setArray(array); + f1.checkCoherency(); + # + f2=f1.eigenVectors(); + f2.checkCoherency(); + self.assertEqual(9,f2.getNumberOfComponents()); + self.assertEqual(5,f2.getNumberOfTuples()); + expected1=[0.5424262364180696, 0.5351201064614425, 0.6476266283176001,#eigenvect 0 + 0.7381111277307373, 0.06458838384003074, -0.6715804522117897,#eigenvect 1 + -0.4012053603397987, 0.8423032781211455, -0.3599436712889738#eigenvect 2 + ] + for i in xrange(5): + self.assertAlmostEqual(expected1[0],f2.getIJ(i,0),13); + self.assertAlmostEqual(expected1[1],f2.getIJ(i,1),13); + self.assertAlmostEqual(expected1[2],f2.getIJ(i,2),13); + self.assertAlmostEqual(expected1[3],f2.getIJ(i,3),13); + self.assertAlmostEqual(expected1[4],f2.getIJ(i,4),13); + self.assertAlmostEqual(expected1[5],f2.getIJ(i,5),13); + self.assertAlmostEqual(expected1[6],f2.getIJ(i,6),13); + self.assertAlmostEqual(expected1[7],f2.getIJ(i,7),13); + self.assertAlmostEqual(expected1[8],f2.getIJ(i,8),13); + pass + # + pass + + def testInverse1(self): + mesh1=MEDCouplingDataForTest.build2DTargetMesh_1(); + f1=MEDCouplingFieldDouble.New(ON_CELLS,NO_TIME); + f1.setMesh(mesh1); + array=DataArrayDouble.New(); + arr1=[1.2,2.3,3.4,4.5,5.6,6.7,7.8,8.9,9.1, 1.2,2.3,3.4,4.5,5.6,6.7,7.8,8.9,9.1, 1.2,2.3,3.4,4.5,5.6,6.7,7.8,8.9,9.1, 1.2,2.3,3.4,4.5,5.6,6.7,7.8,8.9,9.1, 1.2,2.3,3.4,4.5,5.6,6.7,7.8,8.9,9.1] + array.setValues(arr1,mesh1.getNumberOfCells(),9); + f1.setArray(array); + f1.checkCoherency(); + # + f2=f1.inverse(); + f2.checkCoherency(); + self.assertEqual(9,f2.getNumberOfComponents()); + self.assertEqual(5,f2.getNumberOfTuples()); + expected1=[-2.6538108356290113, 2.855831037649208, -1.1111111111111067, 3.461891643709813, -4.775022956841121, 2.2222222222222143, -1.1111111111111054, 2.222222222222214, -1.1111111111111072] + for i in xrange(5): + self.assertAlmostEqual(expected1[0],f2.getIJ(i,0),13); + self.assertAlmostEqual(expected1[1],f2.getIJ(i,1),13); + self.assertAlmostEqual(expected1[2],f2.getIJ(i,2),13); + self.assertAlmostEqual(expected1[3],f2.getIJ(i,3),13); + self.assertAlmostEqual(expected1[4],f2.getIJ(i,4),13); + self.assertAlmostEqual(expected1[5],f2.getIJ(i,5),13); + self.assertAlmostEqual(expected1[6],f2.getIJ(i,6),13); + self.assertAlmostEqual(expected1[7],f2.getIJ(i,7),13); + self.assertAlmostEqual(expected1[8],f2.getIJ(i,8),13); + pass + # + array=DataArrayDouble.New(); + arr3=[7.8,8.9,9.1,10.2,23.4,34.5, 7.8,8.9,9.1,10.2,23.4,34.5, 7.8,8.9,9.1,10.2,23.4,34.5, 7.8,8.9,9.1,10.2,23.4,34.5, 7.8,8.9,9.1,10.2,23.4,34.5] + array.setValues(arr3,mesh1.getNumberOfCells(),6); + f1.setArray(array); + f1.checkCoherency(); + # + f2=f1.inverse(); + f2.checkCoherency(); + self.assertEqual(6,f2.getNumberOfComponents()); + self.assertEqual(5,f2.getNumberOfTuples()); + expected3=[-0.3617705098531818, -0.8678630828458127, -0.026843764174972983, 0.5539957431465833, 0.13133439560823013, -0.05301294502145887] + for i in xrange(5): + self.assertAlmostEqual(expected3[0],f2.getIJ(i,0),13); + self.assertAlmostEqual(expected3[1],f2.getIJ(i,1),13); + self.assertAlmostEqual(expected3[2],f2.getIJ(i,2),13); + self.assertAlmostEqual(expected3[3],f2.getIJ(i,3),13); + self.assertAlmostEqual(expected3[4],f2.getIJ(i,4),13); + self.assertAlmostEqual(expected3[5],f2.getIJ(i,5),13); + pass + # + array=DataArrayDouble.New(); + arr2=[1.2,2.3,3.4,4.5, 1.2,2.3,3.4,4.5, 1.2,2.3,3.4,4.5, 1.2,2.3,3.4,4.5, 1.2,2.3,3.4,4.5] + array.setValues(arr2,mesh1.getNumberOfCells(),4); + f1.setArray(array); + f1.checkCoherency(); + # + f2=f1.inverse(); + f2.checkCoherency(); + self.assertEqual(4,f2.getNumberOfComponents()); + self.assertEqual(5,f2.getNumberOfTuples()); + expected2=[-1.8595041322314059, 0.9504132231404963, 1.404958677685951, -0.49586776859504156] + for i in xrange(5): + self.assertAlmostEqual(expected2[0],f2.getIJ(i,0),13); + self.assertAlmostEqual(expected2[1],f2.getIJ(i,1),13); + self.assertAlmostEqual(expected2[2],f2.getIJ(i,2),13); + self.assertAlmostEqual(expected2[3],f2.getIJ(i,3),13); + pass + # + pass + + def testTrace1(self): + mesh1=MEDCouplingDataForTest.build2DTargetMesh_1(); + f1=MEDCouplingFieldDouble.New(ON_CELLS,NO_TIME); + f1.setMesh(mesh1); + array=DataArrayDouble.New(); + arr1=[1.2,2.3,3.4,4.5,5.6,6.7,7.8,8.9,9.1, 1.2,2.3,3.4,4.5,5.6,6.7,7.8,8.9,9.1, 1.2,2.3,3.4,4.5,5.6,6.7,7.8,8.9,9.1, 1.2,2.3,3.4,4.5,5.6,6.7,7.8,8.9,9.1, 1.2,2.3,3.4,4.5,5.6,6.7,7.8,8.9,9.1] + array.setValues(arr1,mesh1.getNumberOfCells(),9); + f1.setArray(array); + f1.checkCoherency(); + # + f2=f1.trace(); + f2.checkCoherency(); + self.assertEqual(1,f2.getNumberOfComponents()); + self.assertEqual(5,f2.getNumberOfTuples()); + for i in xrange(5): + self.assertAlmostEqual(15.9,f2.getIJ(i,0),13); + pass + # + array=DataArrayDouble.New(); + arr3=[7.8,8.9,9.1,10.2,23.4,34.5, 7.8,8.9,9.1,10.2,23.4,34.5, 7.8,8.9,9.1,10.2,23.4,34.5, 7.8,8.9,9.1,10.2,23.4,34.5, 7.8,8.9,9.1,10.2,23.4,34.5] + array.setValues(arr3,mesh1.getNumberOfCells(),6); + f1.setArray(array); + f1.checkCoherency(); + # + f2=f1.trace(); + f2.checkCoherency(); + self.assertEqual(1,f2.getNumberOfComponents()); + self.assertEqual(5,f2.getNumberOfTuples()); + for i in xrange(5): + self.assertAlmostEqual(25.8,f2.getIJ(i,0),13); + pass + # + array=DataArrayDouble.New(); + arr2=[1.2,2.3,3.4,4.5, 1.2,2.3,3.4,4.5, 1.2,2.3,3.4,4.5, 1.2,2.3,3.4,4.5, 1.2,2.3,3.4,4.5] + array.setValues(arr2,mesh1.getNumberOfCells(),4); + f1.setArray(array); + f1.checkCoherency(); + # + f2=f1.trace(); + f2.checkCoherency(); + self.assertEqual(1,f2.getNumberOfComponents()); + self.assertEqual(5,f2.getNumberOfTuples()); + for i in xrange(5): + self.assertAlmostEqual(5.7,f2.getIJ(i,0),13); + pass + # + pass + + def testDeviator1(self): + mesh1=MEDCouplingDataForTest.build2DTargetMesh_1(); + f1=MEDCouplingFieldDouble.New(ON_CELLS,NO_TIME); + f1.setMesh(mesh1); + array=DataArrayDouble.New(); + arr1=[1.2,2.3,3.4,4.5,5.6,6.7, 1.2,2.3,3.4,4.5,5.6,6.7, 1.2,2.3,3.4,4.5,5.6,6.7, 1.2,2.3,3.4,4.5,5.6,6.7, 1.2,2.3,3.4,4.5,5.6,6.7] + array.setValues(arr1,mesh1.getNumberOfCells(),6); + f1.setArray(array); + f1.checkCoherency(); + # + f2=f1.deviator(); + f2.checkCoherency(); + self.assertEqual(6,f2.getNumberOfComponents()); + self.assertEqual(5,f2.getNumberOfTuples()); + expected1=[-1.1,0.,1.1,4.5,5.6,6.7] + for i in xrange(5): + self.assertAlmostEqual(expected1[0],f2.getIJ(i,0),13); + self.assertAlmostEqual(expected1[1],f2.getIJ(i,1),13); + self.assertAlmostEqual(expected1[2],f2.getIJ(i,2),13); + self.assertAlmostEqual(expected1[3],f2.getIJ(i,3),13); + self.assertAlmostEqual(expected1[4],f2.getIJ(i,4),13); + self.assertAlmostEqual(expected1[5],f2.getIJ(i,5),13); + pass + # + pass + + def testMagnitude1(self): + mesh1=MEDCouplingDataForTest.build2DTargetMesh_1(); + f1=MEDCouplingFieldDouble.New(ON_CELLS,NO_TIME); + f1.setMesh(mesh1); + array=DataArrayDouble.New(); + arr1=[1.2,2.3,3.4,4.5,5.6, 1.2,2.3,3.4,4.5,5.6, 1.2,2.3,3.4,4.5,5.6, 1.2,2.3,3.4,4.5,5.6, 1.2,2.3,3.4,4.5,5.6] + array.setValues(arr1,mesh1.getNumberOfCells(),5); + f1.setArray(array); + f1.checkCoherency(); + # + f2=f1.magnitude(); + f2.checkCoherency(); + self.assertEqual(1,f2.getNumberOfComponents()); + self.assertEqual(5,f2.getNumberOfTuples()); + for i in xrange(5): + self.assertAlmostEqual(8.3606219864313918,f2.getIJ(i,0),13); + pass + # + pass + + def testMaxPerTuple1(self): + mesh1=MEDCouplingDataForTest.build2DTargetMesh_1(); + f1=MEDCouplingFieldDouble.New(ON_CELLS,NO_TIME); + f1.setMesh(mesh1); + array=DataArrayDouble.New(); + arr1=[1.2,2.3,3.4,4.5,5.6, 1.2,3.4,4.5,5.6,2.3, 3.4,4.5,5.6,1.2,2.3, 5.6,1.2,2.3,3.4,4.5, 4.5,5.6,1.2,2.3,3.4] + array.setValues(arr1,mesh1.getNumberOfCells(),5); + f1.setArray(array); + f1.checkCoherency(); + # + f2=f1.maxPerTuple(); + f2.checkCoherency(); + self.assertEqual(1,f2.getNumberOfComponents()); + self.assertEqual(5,f2.getNumberOfTuples()); + for i in xrange(5): + self.assertAlmostEqual(5.6,f2.getIJ(i,0),13); + pass + # + d2,d2I=array.maxPerTupleWithCompoId() + self.assertEqual(1,d2.getNumberOfComponents()); + self.assertEqual(5,d2.getNumberOfTuples()); + for i in xrange(5): + self.assertAlmostEqual(5.6,d2.getIJ(i,0),13); + pass + self.assertTrue(d2I.isEqual(DataArrayInt([4,3,2,0,1]))) + pass + + def testChangeNbOfComponents(self): + mesh1=MEDCouplingDataForTest.build2DTargetMesh_1(); + f1=MEDCouplingFieldDouble.New(ON_CELLS,NO_TIME); + f1.setMesh(mesh1); + array=DataArrayDouble.New(); + arr1=[1.2,2.3,3.4,4.5,5.6, 1.2,3.4,4.5,5.6,2.3, 3.4,4.5,5.6,1.2,2.3, 5.6,1.2,2.3,3.4,4.5, 4.5,5.6,1.2,2.3,3.4] + array.setValues(arr1,mesh1.getNumberOfCells(),5); + f1.setArray(array); + f1.checkCoherency(); + # + f1.changeNbOfComponents(3,7.77); + f1.checkCoherency(); + self.assertEqual(3,f1.getNumberOfComponents()); + self.assertEqual(5,f1.getNumberOfTuples()); + expected1=[1.2,2.3,3.4, 1.2,3.4,4.5, 3.4,4.5,5.6, 5.6,1.2,2.3, 4.5,5.6,1.2] + for i in xrange(15): + self.assertAlmostEqual(expected1[i],f1.getIJ(0,i),13); + pass + f1.changeNbOfComponents(4,7.77); + f1.checkCoherency(); + self.assertEqual(4,f1.getNumberOfComponents()); + self.assertEqual(5,f1.getNumberOfTuples()); + expected2=[1.2,2.3,3.4,7.77, 1.2,3.4,4.5,7.77, 3.4,4.5,5.6,7.77, 5.6,1.2,2.3,7.77, 4.5,5.6,1.2,7.77] + for i in xrange(20): + self.assertAlmostEqual(expected2[i],f1.getIJ(0,i),13); + pass + # + pass + + def testSortPerTuple1(self): + mesh1=MEDCouplingDataForTest.build2DTargetMesh_1(); + f1=MEDCouplingFieldDouble.New(ON_CELLS,NO_TIME); + f1.setMesh(mesh1); + array=DataArrayDouble.New(); + arr1=[1.2,2.3,3.4,4.5,5.6, 1.2,3.4,4.5,5.6,2.3, 3.4,4.5,5.6,1.2,2.3, 5.6,1.2,2.3,3.4,4.5, 4.5,5.6,1.2,2.3,3.4] + array.setValues(arr1,mesh1.getNumberOfCells(),5); + f1.setArray(array); + f1.checkCoherency(); + # + f1.sortPerTuple(True); + f1.checkCoherency(); + self.assertEqual(5,f1.getNumberOfComponents()); + self.assertEqual(5,f1.getNumberOfTuples()); + for i in xrange(5): + self.assertAlmostEqual(arr1[0],f1.getIJ(i,0),13); + self.assertAlmostEqual(arr1[1],f1.getIJ(i,1),13); + self.assertAlmostEqual(arr1[2],f1.getIJ(i,2),13); + self.assertAlmostEqual(arr1[3],f1.getIJ(i,3),13); + self.assertAlmostEqual(arr1[4],f1.getIJ(i,4),13); + pass + # + f1.sortPerTuple(False); + f1.checkCoherency(); + self.assertEqual(5,f1.getNumberOfComponents()); + self.assertEqual(5,f1.getNumberOfTuples()); + for i in xrange(5): + self.assertAlmostEqual(arr1[4],f1.getIJ(i,0),13); + self.assertAlmostEqual(arr1[3],f1.getIJ(i,1),13); + self.assertAlmostEqual(arr1[2],f1.getIJ(i,2),13); + self.assertAlmostEqual(arr1[1],f1.getIJ(i,3),13); + self.assertAlmostEqual(arr1[0],f1.getIJ(i,4),13); + pass + # + pass + + def testIsEqualWithoutConsideringStr1(self): + mesh1=MEDCouplingDataForTest.build2DTargetMesh_1(); + mesh2=MEDCouplingDataForTest.build2DTargetMesh_1(); + # + self.assertTrue(mesh1.isEqual(mesh2,1e-12)); + self.assertTrue(mesh1.isEqualWithoutConsideringStr(mesh2,1e-12)); + mesh2.setName("rr"); + self.assertTrue(not mesh1.isEqual(mesh2,1e-12)); + self.assertTrue(mesh1.isEqualWithoutConsideringStr(mesh2,1e-12)); + da1,da2=mesh1.checkGeoEquivalWith(mesh2,2,1e-12); + self.assertRaises(InterpKernelException,mesh1.checkGeoEquivalWith,mesh2,0,1e-12); + mesh2.setName(""); + self.assertTrue(mesh1.isEqual(mesh2,1e-12)); + self.assertTrue(mesh1.isEqualWithoutConsideringStr(mesh2,1e-12)); + mesh2.getCoords().setInfoOnComponent(0,"tty"); + self.assertTrue(not mesh1.isEqual(mesh2,1e-12)); + self.assertTrue(mesh1.isEqualWithoutConsideringStr(mesh2,1e-12)); + mesh2.getCoords().setInfoOnComponent(0,""); + self.assertTrue(mesh1.isEqual(mesh2,1e-12)); + self.assertTrue(mesh1.isEqualWithoutConsideringStr(mesh2,1e-12)); + mesh2.getCoords().setInfoOnComponent(1,"tty"); + self.assertTrue(not mesh1.isEqual(mesh2,1e-12)); + self.assertTrue(mesh1.isEqualWithoutConsideringStr(mesh2,1e-12)); + mesh2.getCoords().setInfoOnComponent(1,""); + self.assertTrue(mesh1.isEqual(mesh2,1e-12)); + self.assertTrue(mesh1.isEqualWithoutConsideringStr(mesh2,1e-12)); + tmp=mesh2.getCoords().getIJ(0,3); + mesh2.getCoords().setIJ(0,3,9999.); + self.assertTrue(not mesh1.isEqual(mesh2,1e-12)); + self.assertTrue(not mesh1.isEqualWithoutConsideringStr(mesh2,1e-12)); + mesh2.getCoords().setIJ(0,3,tmp); + self.assertTrue(mesh1.isEqual(mesh2,1e-12)); + self.assertTrue(mesh1.isEqualWithoutConsideringStr(mesh2,1e-12)); + tmp2=mesh2.getNodalConnectivity().getIJ(0,4); + mesh2.getNodalConnectivity().setIJ(0,4,0); + self.assertTrue(not mesh1.isEqual(mesh2,1e-12)); + self.assertTrue(not mesh1.isEqualWithoutConsideringStr(mesh2,1e-12)); + mesh2.getNodalConnectivity().setIJ(0,4,tmp2); + self.assertTrue(mesh1.isEqual(mesh2,1e-12)); + self.assertTrue(mesh1.isEqualWithoutConsideringStr(mesh2,1e-12)); + # + f1=mesh1.getMeasureField(True); + f2=mesh2.getMeasureField(True); + self.assertTrue(f1.isEqual(f2,1e-12,1e-12)); + self.assertTrue(f1.isEqualWithoutConsideringStr(f2,1e-12,1e-12)); + f2.setName("ftest"); + self.assertTrue(not f1.isEqual(f2,1e-12,1e-12)); + self.assertTrue(f1.isEqualWithoutConsideringStr(f2,1e-12,1e-12)); + f1.setName("ftest"); + self.assertTrue(f1.isEqual(f2,1e-12,1e-12)); + self.assertTrue(f1.isEqualWithoutConsideringStr(f2,1e-12,1e-12)); + # + f2.getArray().setInfoOnComponent(0,"eee"); + self.assertTrue(not f1.isEqual(f2,1e-12,1e-12)); + self.assertTrue(f1.isEqualWithoutConsideringStr(f2,1e-12,1e-12)); + f2.getArray().setInfoOnComponent(0,""); + self.assertTrue(f1.isEqual(f2,1e-12,1e-12)); + self.assertTrue(f1.isEqualWithoutConsideringStr(f2,1e-12,1e-12)); + # + f2.getArray().setIJ(1,0,0.123); + self.assertTrue(not f1.isEqual(f2,1e-12,1e-12)); + self.assertTrue(not f1.isEqualWithoutConsideringStr(f2,1e-12,1e-12)); + f2.getArray().setIJ(1,0,0.125); + self.assertTrue(f1.isEqual(f2,1e-12,1e-12)); + self.assertTrue(f1.isEqualWithoutConsideringStr(f2,1e-12,1e-12)); + # + pass + + def testGetNodeIdsOfCell1(self): + mesh1=MEDCouplingDataForTest.build2DTargetMesh_1(); + li=mesh1.getNodeIdsOfCell(1) + expected1=[1, 4, 2] + self.assertEqual(expected1,list(li)) + li=mesh1.getCoordinatesOfNode(4) + self.assertEqual(2,len(li)) + self.assertAlmostEqual(0.2,li[0],13); + self.assertAlmostEqual(0.2,li[1],13); + li=mesh1.getCoords().getValuesAsTuple() + self.assertEqual(9,len(li)) + li2=mesh1.getNodalConnectivityIndex().getValuesAsTuple() + self.assertEqual(6,len(li2)) + pass + + def testGetEdgeRatioField1(self): + m1=MEDCouplingDataForTest.build2DTargetMesh_1(); + m1.setTime(3.4,5,6); m1.setTimeUnit("us"); + f1=m1.getEdgeRatioField(); + self.assertAlmostEqual(3.4,f1.getTime()[0],12) ; self.assertEqual(5,f1.getTime()[1]) ; self.assertEqual(6,f1.getTime()[2]) + self.assertEqual("us",f1.getTimeUnit()) + self.assertEqual(m1.getNumberOfCells(),f1.getNumberOfTuples()); + self.assertEqual(5,f1.getNumberOfTuples()); + self.assertEqual(1,f1.getNumberOfComponents()); + expected1=[1.,1.4142135623730951, 1.4142135623730951,1.,1.] + for i in xrange(5): + self.assertAlmostEqual(expected1[i],f1.getIJ(i,0),14); + pass + # + m1=MEDCouplingDataForTest.build3DSurfTargetMesh_1(); + f1=m1.getEdgeRatioField(); + self.assertEqual(m1.getNumberOfCells(),f1.getNumberOfTuples()); + self.assertEqual(5,f1.getNumberOfTuples()); + self.assertEqual(1,f1.getNumberOfComponents()); + expected2=[1.4142135623730951, 1.7320508075688772, 1.7320508075688772, 1.4142135623730951, 1.4142135623730951] + for i in xrange(5): + self.assertAlmostEqual(expected2[i],f1.getIJ(i,0),14); + pass + pass + + def testFillFromAnalytic3(self): + m=MEDCouplingDataForTest.build2DTargetMesh_1() + f1=MEDCouplingFieldDouble.New(ON_CELLS,ONE_TIME) + self.assertRaises(InterpKernelException,f1.fillFromAnalytic,1,"y+x"); + f1.setMesh(m) + f1.setName("myField"); + f1.fillFromAnalytic(1,"y+x"); + f1.checkCoherency(); + self.assertEqual(f1.getName(),"myField"); + self.assertEqual(f1.getTypeOfField(),ON_CELLS); + self.assertEqual(f1.getTimeDiscretization(),ONE_TIME); + self.assertEqual(1,f1.getNumberOfComponents()); + self.assertEqual(5,f1.getNumberOfTuples()); + values1=[-0.1,0.23333333333333336,0.56666666666666665,0.4,0.9] + tmp=f1.getArray().getValues(); + self.assertEqual(len(values1),len(tmp)) + for i in xrange(len(values1)): + self.assertTrue(abs(values1[i]-tmp[i])<1.e-12); + pass + # + f1=MEDCouplingFieldDouble.New(ON_NODES,CONST_ON_TIME_INTERVAL) + f1.setMesh(m) + f1.fillFromAnalytic(1,"y+2*x"); + f1.setEndTime(1.2,3,4); + f1.checkCoherency(); + self.assertEqual(f1.getTypeOfField(),ON_NODES); + self.assertEqual(f1.getTimeDiscretization(),CONST_ON_TIME_INTERVAL); + self.assertEqual(1,f1.getNumberOfComponents()); + self.assertEqual(9,f1.getNumberOfTuples()); + values2=[-0.9,0.1,1.1,-0.4,0.6,1.6,0.1,1.1,2.1] + tmp=f1.getArray().getValues(); + self.assertEqual(len(values2),len(tmp)) + for i in xrange(len(values2)): + self.assertTrue(abs(values2[i]-tmp[i])<1.e-12); + pass + f1=MEDCouplingFieldDouble.New(ON_NODES,LINEAR_TIME); + f1.setMesh(m) + f1.fillFromAnalytic(1,"2.*x+y"); + f1.setEndTime(1.2,3,4); + f1.checkCoherency(); + self.assertEqual(f1.getTypeOfField(),ON_NODES); + self.assertEqual(f1.getTimeDiscretization(),LINEAR_TIME); + self.assertEqual(1,f1.getNumberOfComponents()); + self.assertEqual(9,f1.getNumberOfTuples()); + tmp=f1.getArray().getValues(); + values2Bis=[-0.9,0.1,1.1,-0.4,0.6,1.6,0.1,1.1,2.1] + self.assertEqual(len(values2Bis),len(tmp)) + for i in xrange(len(values2Bis)): + self.assertTrue(abs(values2Bis[i]-tmp[i])<1.e-12); + pass + tmp=f1.getEndArray().getValues(); + self.assertEqual(len(values2Bis),len(tmp)) + for i in xrange(len(values2Bis)): + self.assertTrue(abs(values2Bis[i]-tmp[i])<1.e-12); + pass + # + f1=MEDCouplingFieldDouble.New(ON_NODES,ONE_TIME); + f1.setMesh(m) + f1.fillFromAnalytic(2,"(x+y)*IVec+2*(x+y)*JVec"); + f1.checkCoherency(); + self.assertEqual(f1.getTypeOfField(),ON_NODES); + self.assertEqual(f1.getTimeDiscretization(),ONE_TIME); + self.assertEqual(2,f1.getNumberOfComponents()); + self.assertEqual(9,f1.getNumberOfTuples()); + values3=[-0.6,-1.2,-0.1,-0.2,0.4,0.8,-0.1,-0.2,0.4,0.8,0.9,1.8,0.4,0.8,0.9,1.8,1.4,2.8] + tmp=f1.getArray().getValues(); + self.assertEqual(len(values3),len(tmp)) + for i in xrange(len(values3)): + self.assertTrue(abs(values3[i]-tmp[i])<1.e-12); + pass + values4=f1.accumulate(); + self.assertTrue(abs(3.6-values4[0])<1.e-12); + self.assertTrue(abs(7.2-values4[1])<1.e-12); + values4=f1.integral(True); + self.assertTrue(abs(0.5-values4[0])<1.e-12); + self.assertTrue(abs(1.-values4[1])<1.e-12); + # + f1=MEDCouplingFieldDouble.New(ON_NODES,NO_TIME); + f1.setMesh(m); + self.assertRaises(InterpKernelException,f1.fillFromAnalytic,1,"1./(x-0.2)"); + pass + + def testFieldDoubleOpEqual1(self): + m=MEDCouplingDataForTest.build2DTargetMesh_1(); + f1=MEDCouplingFieldDouble.New(ON_CELLS,ONE_TIME); + self.assertRaises(InterpKernelException,f1.assign,0.07); + f1.setMesh(m); + f1.assign(0.07); + f1.checkCoherency(); + self.assertEqual(1,f1.getNumberOfComponents()); + self.assertEqual(5,f1.getNumberOfTuples()); + for i in xrange(5): + self.assertAlmostEqual(0.07,f1.getIJ(i,0),16); + pass + f1.assign(0.09); + f1.checkCoherency(); + self.assertEqual(1,f1.getNumberOfComponents()); + self.assertEqual(5,f1.getNumberOfTuples()); + for i in xrange(5): + self.assertAlmostEqual(0.09,f1.getIJ(i,0),16); + pass + # + f1=MEDCouplingFieldDouble.New(ON_NODES,LINEAR_TIME); + f1.setEndTime(4.5,2,3); + f1.setMesh(m); + f1.assign(0.08); + f1.checkCoherency(); + self.assertEqual(1,f1.getNumberOfComponents()); + self.assertEqual(9,f1.getNumberOfTuples()); + for i in xrange(9): + self.assertAlmostEqual(0.08,f1.getIJ(i,0),16); + pass + self.assertEqual(1,f1.getEndArray().getNumberOfComponents()); + self.assertEqual(9,f1.getEndArray().getNumberOfTuples()); + for i in xrange(9): + self.assertAlmostEqual(0.08,f1.getEndArray().getIJ(i,0),16); + pass + pass + + def testAreaBary3D2(self): + coordsForHexa8=[-75.45749305371, 180.95495078401, 39.515472018008, + -9.755591679144, 23.394927935279, 5.108794294848, + 14.337630157832, 61.705351002702, 160.42422501908, + -27.273893776752, 167.567731083961, 192.830034145464, + 99.857193154796,264.499264735586,-8.287335493412, + 144.939882761126,156.38626563134,-31.896173894226, + 161.34096835726,182.4654895809,73.832387065572, + 132.680430393685,255.37973247196,96.15235602819]; + volHexa8=3258520.29637466; + baryHexa8=[43.925705821778, 155.31893955289, 65.874418109644] + + coordsForPenta6=[-68.199829618726,178.938498373416,62.608505919588, + 8.461744647847,76.653979804423,165.00018874933, + -27.273893776752,167.567731083961,192.830034145464, + 106.586501038965,262.629609408327,13.124533008813, + 155.465082847275,197.414118382622,78.408350795821, + 132.680430393685,255.37973247196,96.15235602819]; + volPenta6=944849.868507338; + baryPenta6=[39.631002313543,182.692711783428,106.98540473964] + + coordsForPyra5=[132.680430393685,255.37973247196,96.15235602819, + -27.273893776752,167.567731083961,192.830034145464, + 8.461744647847,76.653979804423,165.00018874933, + 155.465082847275,197.414118382622,78.408350795821, + -68.199829618726,178.938498373416,62.608505919588]; + volPyra5=756943.92980254; + baryPyra5=[29.204294116618,172.540129749156,118.01035951483] + mesh=MEDCouplingUMesh.New("Bary3D2",3); + coo=DataArrayDouble.New(); + tmp=coordsForHexa8+coordsForPenta6+coordsForPyra5 + coo.setValues(tmp,19,3); + mesh.setCoords(coo); + # + tmpConn=[0,1,2,3,4,5,6,7] + mesh.allocateCells(3); + self.assertRaises(InterpKernelException,mesh.insertNextCell,NORM_HEXA8,9,tmpConn[0:8]) + mesh.insertNextCell(NORM_HEXA8,tmpConn[0:8]) + mesh.insertNextCell(NORM_PENTA6,6,[i+8 for i in tmpConn]) + mesh.insertNextCell(NORM_PYRA5,5,[i+14 for i in tmpConn]) + mesh.finishInsertingCells(); + mesh.checkCoherency(); + mesh.mergeNodes(1e-7) + self.assertEqual(12,mesh.getNumberOfNodes()); + vols=mesh.getMeasureField(True); + self.assertEqual(3,vols.getNumberOfTuples()); + self.assertEqual(1,vols.getNumberOfComponents()); + self.assertAlmostEqual(volHexa8,vols.getIJ(0,0),6); + self.assertAlmostEqual(volPenta6,vols.getIJ(1,0),7); + self.assertAlmostEqual(volPyra5,vols.getIJ(2,0),7); + bary=mesh.getBarycenterAndOwner(); + self.assertEqual(3,bary.getNumberOfTuples()); + self.assertEqual(3,bary.getNumberOfComponents()); + self.assertAlmostEqual(baryHexa8[0],bary.getIJ(0,0),11); + self.assertAlmostEqual(baryHexa8[1],bary.getIJ(0,1),11); + self.assertAlmostEqual(baryHexa8[2],bary.getIJ(0,2),11); + self.assertAlmostEqual(baryPenta6[0],bary.getIJ(1,0),11); + self.assertAlmostEqual(baryPenta6[1],bary.getIJ(1,1),11); + self.assertAlmostEqual(baryPenta6[2],bary.getIJ(1,2),11); + self.assertAlmostEqual(baryPyra5[0],bary.getIJ(2,0),11); + self.assertAlmostEqual(baryPyra5[1],bary.getIJ(2,1),11); + self.assertAlmostEqual(baryPyra5[2],bary.getIJ(2,2),11); + pass + + def testGetMeasureFieldCMesh1(self): + m=MEDCouplingCMesh.New(); + da=DataArrayDouble.New(); + discX=[2.3,3.4,5.8,10.2] + discY=[12.3,23.4,45.8] + discZ=[-0.7,1.2,1.25,2.13,2.67] + da.setValues(discX,4,1); + m.setCoordsAt(0,da); + m.checkCoherency(); + self.assertEqual(4,m.getNumberOfNodes()); + self.assertEqual(3,m.getNumberOfCells()); + self.assertEqual(1,m.getSpaceDimension()); + f=m.getMeasureField(True); + self.assertEqual(3,f.getNumberOfTuples()); + self.assertEqual(1,f.getNumberOfComponents()); + expected1=[1.1,2.4,4.4] + for i in xrange(3): + self.assertAlmostEqual(expected1[i],f.getIJ(i,0),12); + pass + coords=m.getCoordinatesAndOwner(); + self.assertEqual(4,coords.getNumberOfTuples()); + self.assertEqual(1,coords.getNumberOfComponents()); + for i in xrange(4): + self.assertAlmostEqual(discX[i],coords.getIJ(i,0),12); + pass + coords=m.getBarycenterAndOwner(); + self.assertEqual(3,coords.getNumberOfTuples()); + self.assertEqual(1,coords.getNumberOfComponents()); + expected1_3=[2.85,4.6,8.] + for i in xrange(3): + self.assertAlmostEqual(expected1_3[i],coords.getIJ(i,0),12); + pass + # + da=DataArrayDouble.New(); + da.setValues(discY,3,1); + m.setCoordsAt(1,da); + m.checkCoherency(); + self.assertEqual(12,m.getNumberOfNodes()); + self.assertEqual(6,m.getNumberOfCells()); + self.assertEqual(2,m.getSpaceDimension()); + f=m.getMeasureField(True); + self.assertEqual(6,f.getNumberOfTuples()); + self.assertEqual(1,f.getNumberOfComponents()); + expected2=[12.21,26.64,48.84,24.64,53.76,98.56] + for i in xrange(6): + self.assertAlmostEqual(expected2[i],f.getIJ(i,0),12); + pass + coords=m.getCoordinatesAndOwner(); + self.assertEqual(12,coords.getNumberOfTuples()); + self.assertEqual(2,coords.getNumberOfComponents()); + expected2_2=[2.3,12.3,3.4,12.3,5.8,12.3,10.2,12.3, 2.3,23.4,3.4,23.4,5.8,23.4,10.2,23.4, 2.3,45.8,3.4,45.8,5.8,45.8,10.2,45.8] + for i in xrange(24): + self.assertAlmostEqual(expected2_2[i],coords.getIJ(0,i),12); + pass + coords=m.getBarycenterAndOwner(); + self.assertEqual(6,coords.getNumberOfTuples()); + self.assertEqual(2,coords.getNumberOfComponents()); + expected2_3=[2.85,17.85,4.6,17.85,8.,17.85, 2.85,34.6,4.6,34.6,8.,34.6] + for i in xrange(12): + self.assertAlmostEqual(expected2_3[i],coords.getIJ(0,i),12); + pass + # + da=DataArrayDouble.New(); + da.setValues(discZ,5,1); + m.setCoordsAt(2,da); + m.checkCoherency(); + self.assertEqual(60,m.getNumberOfNodes()); + self.assertEqual(24,m.getNumberOfCells()); + self.assertEqual(3,m.getSpaceDimension()); + f=m.getMeasureField(True); + self.assertEqual(24,f.getNumberOfTuples()); + self.assertEqual(1,f.getNumberOfComponents()); + expected3=[23.199, 50.616, 92.796, 46.816, 102.144, 187.264, 0.6105, 1.332, 2.442, 1.232, 2.688, 4.928, 10.7448, 23.4432, 42.9792, 21.6832, 47.3088, 86.7328, 6.5934, 14.3856, 26.3736, 13.3056, 29.0304, 53.2224] + for i in xrange(24): + self.assertAlmostEqual(expected3[i],f.getIJ(i,0),12); + pass + coords=m.getCoordinatesAndOwner(); + self.assertEqual(60,coords.getNumberOfTuples()); + self.assertEqual(3,coords.getNumberOfComponents()); + expected3_2=[ + 2.3,12.3,-0.7, 3.4,12.3,-0.7, 5.8,12.3,-0.7, 10.2,12.3,-0.7, 2.3,23.4,-0.7, 3.4,23.4,-0.7, 5.8,23.4,-0.7, 10.2,23.4,-0.7, 2.3,45.8,-0.7, 3.4,45.8,-0.7, 5.8,45.8,-0.7, 10.2,45.8,-0.7, + 2.3,12.3,1.2, 3.4,12.3,1.2, 5.8,12.3,1.2, 10.2,12.3,1.2, 2.3,23.4,1.2, 3.4,23.4,1.2, 5.8,23.4,1.2, 10.2,23.4,1.2, 2.3,45.8,1.2, 3.4,45.8,1.2, 5.8,45.8,1.2, 10.2,45.8,1.2, + 2.3,12.3,1.25, 3.4,12.3,1.25, 5.8,12.3,1.25, 10.2,12.3,1.25, 2.3,23.4,1.25, 3.4,23.4,1.25, 5.8,23.4,1.25, 10.2,23.4,1.25, 2.3,45.8,1.25, 3.4,45.8,1.25, 5.8,45.8,1.25, 10.2,45.8,1.25, + 2.3,12.3,2.13, 3.4,12.3,2.13, 5.8,12.3,2.13, 10.2,12.3,2.13, 2.3,23.4,2.13, 3.4,23.4,2.13, 5.8,23.4,2.13, 10.2,23.4,2.13, 2.3,45.8,2.13, 3.4,45.8,2.13, 5.8,45.8,2.13, 10.2,45.8,2.13, + 2.3,12.3,2.67, 3.4,12.3,2.67, 5.8,12.3,2.67, 10.2,12.3,2.67, 2.3,23.4,2.67, 3.4,23.4,2.67, 5.8,23.4,2.67, 10.2,23.4,2.67, 2.3,45.8,2.67, 3.4,45.8,2.67, 5.8,45.8,2.67, 10.2,45.8,2.67]; + for i in xrange(180): + self.assertAlmostEqual(expected3_2[i],coords.getIJ(0,i),12); + pass + coords=m.getBarycenterAndOwner(); + self.assertEqual(24,coords.getNumberOfTuples()); + self.assertEqual(3,coords.getNumberOfComponents()); + expected3_3=[ + 2.85,17.85,0.25,4.6,17.85,0.25,8.,17.85,0.25, 2.85,34.6,0.25,4.6,34.6,0.25,8.,34.6,0.25, + 2.85,17.85,1.225,4.6,17.85,1.225,8.,17.85,1.225, 2.85,34.6,1.225,4.6,34.6,1.225,8.,34.6,1.225, + 2.85,17.85,1.69,4.6,17.85,1.69,8.,17.85,1.69, 2.85,34.6,1.69,4.6,34.6,1.69,8.,34.6,1.69, + 2.85,17.85,2.4,4.6,17.85,2.4,8.,17.85,2.4, 2.85,34.6,2.4,4.6,34.6,2.4,8.,34.6,2.4]; + for i in xrange(72): + self.assertAlmostEqual(expected3_3[i],coords.getIJ(0,i),12); + pass + pass + + def testFieldDoubleZipCoords1(self): + m=MEDCouplingDataForTest.build2DTargetMeshMergeNode_1(); + f=m.fillFromAnalytic(ON_NODES,2,"x*2."); + f.getArray().setInfoOnComponent(0,"titi"); + f.getArray().setInfoOnComponent(1,"tutu"); + f.checkCoherency(); + self.assertEqual(18,f.getNumberOfTuples()); + self.assertEqual(2,f.getNumberOfComponents()); + expected1=[-0.6, -0.6, 0.4, 0.4, 1.4, 1.4, -0.6, -0.6, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 1.4, 1.4, -0.6, -0.6, 0.4, 0.4, 1.4, 1.4, -0.6, -0.6, 1.4, 1.4, -0.6, -0.6, 0.4, 0.4, 1.4, 1.4, 0.4, 0.4] + for i in xrange(36): + self.assertAlmostEqual(expected1[i],f.getIJ(0,i),12); + pass + self.assertTrue(f.zipCoords()); + f.checkCoherency(); + expected2=[-0.6, -0.6, 1.4, 1.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 0.4, 1.4, 1.4, -0.6, -0.6, 0.4, 0.4, 1.4, 1.4, 1.4, 1.4, -0.6, -0.6, 0.4, 0.4, 1.4, 1.4, 0.4, 0.4] + for i in xrange(30): + self.assertAlmostEqual(expected2[i],f.getIJ(0,i),12); + pass + self.assertTrue(not f.zipCoords()); + f.checkCoherency(); + for i in xrange(30): + self.assertAlmostEqual(expected2[i],f.getIJ(0,i),12); + pass + self.assertTrue(f.getArray().getInfoOnComponent(0)=="titi"); + self.assertTrue(f.getArray().getInfoOnComponent(1)=="tutu"); + pass + + def testFieldDoubleZipConnectivity1(self): + m1=MEDCouplingDataForTest.build2DTargetMesh_1(); + m2=MEDCouplingDataForTest.build2DTargetMesh_1(); + cells1=[2,3,4] + m3_1=m2.buildPartOfMySelf(cells1,True); + m3=m3_1; + m4=MEDCouplingDataForTest.build2DSourceMesh_1(); + m5=MEDCouplingUMesh.MergeUMeshes(m1,m3); + m6=MEDCouplingUMesh.MergeUMeshes(m5,m4); + # + self.assertEqual(10,m6.getNumberOfCells()); + self.assertEqual(22,m6.getNumberOfNodes()); + arr,areNodesMerged,newNbOfNodes=m6.mergeNodes(1e-13); + self.assertEqual(9,m6.getNumberOfNodes()); + f=m6.fillFromAnalytic(ON_CELLS,2,"x"); + f2=m6.fillFromAnalytic(ON_NODES,2,"x"); + self.assertEqual(10,f.getNumberOfTuples()); + self.assertEqual(2,f.getNumberOfComponents()); + expected1=[-0.05, -0.05, 0.3666666666666667, 0.3666666666666667, 0.53333333333333321, 0.53333333333333321, + -0.05, -0.05, 0.45, 0.45, 0.53333333333333321, 0.53333333333333321, -0.05, -0.05, 0.45, 0.45, + 0.36666666666666659, 0.36666666666666659, 0.033333333333333326, 0.033333333333333326]; + for i in xrange(20): + self.assertAlmostEqual(expected1[i],f.getIJ(0,i),12); + pass + f.getArray().setInfoOnComponent(0,"titi"); + f.getArray().setInfoOnComponent(1,"tutu"); + f.checkCoherency(); + self.assertTrue(f.zipConnectivity(0)); + expected2=[-0.05, -0.05, 0.3666666666666667, 0.3666666666666667, 0.53333333333333321, 0.53333333333333321, + -0.05, -0.05, 0.45, 0.45, 0.36666666666666659, 0.36666666666666659, 0.033333333333333326, 0.033333333333333326]; + self.assertEqual(7,f.getNumberOfTuples()); + self.assertEqual(2,f.getNumberOfComponents()); + for i in xrange(14): + self.assertAlmostEqual(expected2[i],f.getIJ(0,i),12); + pass + self.assertTrue(f.getArray().getInfoOnComponent(0)=="titi"); + self.assertTrue(f.getArray().getInfoOnComponent(1)=="tutu"); + self.assertTrue(not f.zipConnectivity(0)); + # + expected3=[-0.3, -0.3, 0.2, 0.2, 0.7, 0.7, -0.3, -0.3, 0.2, 0.2, 0.7, 0.7, + -0.3, -0.3, 0.2, 0.2, 0.7, 0.7]; + self.assertEqual(9,f2.getNumberOfTuples()); + self.assertEqual(2,f2.getNumberOfComponents()); + for i in xrange(18): + self.assertAlmostEqual(expected3[i],f2.getIJ(0,i),12); + pass + self.assertTrue(f2.zipConnectivity(0)); + self.assertEqual(9,f2.getNumberOfTuples()); + self.assertEqual(2,f2.getNumberOfComponents()); + for i in xrange(18): + self.assertAlmostEqual(expected3[i],f2.getIJ(0,i),12); + pass + pass + + def testDaDoubleRenumber1(self): + a=DataArrayDouble.New(); + arr1=[1.1,11.1,2.1,12.1,3.1,13.1,4.1,14.1,5.1,15.1,6.1,16.1,7.1,17.1] + a.setValues(arr1,7,2); + a.setInfoOnComponent(0,"toto"); + a.setInfoOnComponent(1,"tata"); + # + arr2=[3,1,0,6,5,4,2] + b=a.renumber(arr2); + self.assertEqual(7,b.getNumberOfTuples()); + self.assertEqual(2,b.getNumberOfComponents()); + self.assertTrue(b.getInfoOnComponent(0)=="toto"); + self.assertTrue(b.getInfoOnComponent(1)=="tata"); + expected1=[3.1, 13.1, 2.1, 12.1, 7.1, 17.1, 1.1, 11.1, 6.1, 16.1, 5.1, 15.1, 4.1, 14.1] + for i in xrange(14): + self.assertAlmostEqual(expected1[i],b.getIJ(0,i),14); + pass + # + c=DataArrayInt.New(); + arr3=[1,11,2,12,3,13,4,14,5,15,6,16,7,17] + c.setValues(arr3,7,2); + c.setInfoOnComponent(0,"toto"); + c.setInfoOnComponent(1,"tata"); + d=c.renumber(arr2); + self.assertEqual(7,d.getNumberOfTuples()); + self.assertEqual(2,d.getNumberOfComponents()); + self.assertTrue(d.getInfoOnComponent(0)=="toto"); + self.assertTrue(d.getInfoOnComponent(1)=="tata"); + expected2=[3, 13, 2, 12, 7, 17, 1, 11, 6, 16, 5, 15, 4, 14] + for i in xrange(14): + self.assertEqual(expected2[i],d.getIJ(0,i)); + pass + pass + + def testDaDoubleRenumberAndReduce1(self): + a=DataArrayDouble.New(); + arr1=[1.1,11.1,2.1,12.1,3.1,13.1,4.1,14.1,5.1,15.1,6.1,16.1,7.1,17.1] + a.setValues(arr1,7,2); + a.setInfoOnComponent(0,"toto"); + a.setInfoOnComponent(1,"tata"); + # + arr2=[2,-1,1,-1,0,4,3] + b=a.renumberAndReduce(arr2,5); + self.assertEqual(5,b.getNumberOfTuples()); + self.assertEqual(2,b.getNumberOfComponents()); + self.assertTrue(b.getInfoOnComponent(0)=="toto"); + self.assertTrue(b.getInfoOnComponent(1)=="tata"); + expected1=[5.1,15.1,3.1,13.1,1.1,11.1,7.1,17.1,6.1,16.1] + for i in xrange(10): + self.assertAlmostEqual(expected1[i],b.getIJ(0,i),14); + pass + # + c=DataArrayInt.New(); + arr3=[1,11,2,12,3,13,4,14,5,15,6,16,7,17] + c.setValues(arr3,7,2); + c.setInfoOnComponent(0,"toto"); + c.setInfoOnComponent(1,"tata"); + d=c.renumberAndReduce(arr2,5); + self.assertEqual(5,d.getNumberOfTuples()); + self.assertEqual(2,d.getNumberOfComponents()); + self.assertTrue(d.getInfoOnComponent(0)=="toto"); + self.assertTrue(d.getInfoOnComponent(1)=="tata"); + expected2=[5,15,3,13,1,11,7,17,6,16] + for i in xrange(10): + self.assertEqual(expected2[i],d.getIJ(0,i)); + pass + pass + + def testDaDoubleRenumberInPlace1(self): + a=DataArrayDouble.New(); + arr1=[1.1,11.1,2.1,12.1,3.1,13.1,4.1,14.1,5.1,15.1,6.1,16.1,7.1,17.1] + a.setValues(arr1,7,2); + # + arr2=[3,1,0,6,5,4,2] + a.renumberInPlace(arr2); + self.assertEqual(7,a.getNumberOfTuples()); + self.assertEqual(2,a.getNumberOfComponents()); + expected1=[3.1, 13.1, 2.1, 12.1, 7.1, 17.1, 1.1, 11.1, 6.1, 16.1, 5.1, 15.1, 4.1, 14.1] + for i in xrange(14): + self.assertAlmostEqual(expected1[i],a.getIJ(0,i),14); + pass + # + c=DataArrayInt.New(); + arr3=[1,11,2,12,3,13,4,14,5,15,6,16,7,17] + c.setValues(arr3,7,2); + c.renumberInPlace(arr2); + self.assertEqual(7,c.getNumberOfTuples()); + self.assertEqual(2,c.getNumberOfComponents()); + expected2=[3, 13, 2, 12, 7, 17, 1, 11, 6, 16, 5, 15, 4, 14] + for i in xrange(14): + self.assertEqual(expected2[i],c.getIJ(0,i)); + pass + pass + + def testDaDoubleRenumberR1(self): + a=DataArrayDouble.New(); + arr1=[1.1,11.1,2.1,12.1,3.1,13.1,4.1,14.1,5.1,15.1,6.1,16.1,7.1,17.1] + a.setValues(arr1,7,2); + a.setInfoOnComponent(0,"toto"); + a.setInfoOnComponent(1,"tata"); + # + arr2=[3,1,0,6,5,4,2] + b=a.renumberR(arr2); + self.assertEqual(7,b.getNumberOfTuples()); + self.assertEqual(2,b.getNumberOfComponents()); + self.assertTrue(b.getInfoOnComponent(0)=="toto"); + self.assertTrue(b.getInfoOnComponent(1)=="tata"); + expected1=[4.1, 14.1, 2.1, 12.1, 1.1, 11.1, 7.1, 17.1, 6.1, 16.1, 5.1, 15.1, 3.1, 13.1] + for i in xrange(14): + self.assertAlmostEqual(expected1[i],b.getIJ(0,i),14); + pass + # + c=DataArrayInt.New(); + arr3=[1,11,2,12,3,13,4,14,5,15,6,16,7,17] + c.setValues(arr3,7,2); + c.setInfoOnComponent(0,"toto"); + c.setInfoOnComponent(1,"tata"); + d=c.renumberR(arr2); + self.assertEqual(7,d.getNumberOfTuples()); + self.assertEqual(2,d.getNumberOfComponents()); + self.assertTrue(d.getInfoOnComponent(0)=="toto"); + self.assertTrue(d.getInfoOnComponent(1)=="tata"); + expected2=[4, 14, 2, 12, 1, 11, 7, 17, 6, 16, 5, 15, 3, 13] + for i in xrange(14): + self.assertEqual(expected2[i],d.getIJ(0,i)); + pass + pass + + def testDaDoubleRenumberInPlaceR1(self): + a=DataArrayDouble.New(); + arr1=[1.1,11.1,2.1,12.1,3.1,13.1,4.1,14.1,5.1,15.1,6.1,16.1,7.1,17.1] + a.setValues(arr1,7,2); + # + arr2=[3,1,0,6,5,4,2] + a.renumberInPlaceR(arr2); + self.assertEqual(7,a.getNumberOfTuples()); + self.assertEqual(2,a.getNumberOfComponents()); + expected1=[4.1, 14.1, 2.1, 12.1, 1.1, 11.1, 7.1, 17.1, 6.1, 16.1, 5.1, 15.1, 3.1, 13.1] + for i in xrange(14): + self.assertAlmostEqual(expected1[i],a.getIJ(0,i),14); + pass + # + c=DataArrayInt.New(); + arr3=[1,11,2,12,3,13,4,14,5,15,6,16,7,17] + c.setValues(arr3,7,2); + c.renumberInPlaceR(arr2); + self.assertEqual(7,c.getNumberOfTuples()); + self.assertEqual(2,c.getNumberOfComponents()); + expected2=[4, 14, 2, 12, 1, 11, 7, 17, 6, 16, 5, 15, 3, 13] + for i in xrange(14): + self.assertEqual(expected2[i],c.getIJ(0,i)); + pass + pass + + def testDaDoubleSelectByTupleId1(self): + a=DataArrayDouble.New(); + arr1=[1.1,11.1,2.1,12.1,3.1,13.1,4.1,14.1,5.1,15.1,6.1,16.1,7.1,17.1] + a.setValues(arr1,7,2); + a.setInfoOnComponent(0,"toto"); + a.setInfoOnComponent(1,"tata"); + # + arr2=[4,2,0,6,5] + b=a.selectByTupleId(arr2); + self.assertEqual(5,b.getNumberOfTuples()); + self.assertEqual(2,b.getNumberOfComponents()); + self.assertTrue(b.getInfoOnComponent(0)=="toto"); + self.assertTrue(b.getInfoOnComponent(1)=="tata"); + expected1=[5.1,15.1,3.1,13.1,1.1,11.1,7.1,17.1,6.1,16.1] + for i in xrange(10): + self.assertAlmostEqual(expected1[i],b.getIJ(0,i),14); + pass + # + c=DataArrayInt.New(); + arr3=[1,11,2,12,3,13,4,14,5,15,6,16,7,17] + c.setValues(arr3,7,2); + c.setInfoOnComponent(0,"toto"); + c.setInfoOnComponent(1,"tata"); + d=c.selectByTupleId(arr2); + self.assertEqual(5,d.getNumberOfTuples()); + self.assertEqual(2,d.getNumberOfComponents()); + self.assertTrue(d.getInfoOnComponent(0)=="toto"); + self.assertTrue(d.getInfoOnComponent(1)=="tata"); + expected2=[5,15,3,13,1,11,7,17,6,16] + for i in xrange(10): + self.assertEqual(expected2[i],d.getIJ(0,i)); + pass + pass + + def testDaDoubleGetMinMaxValues1(self): + a=DataArrayDouble.New(); + arr1=[2.34,4.56,-6.77,4.55,4.56,2.24,2.34,1.02,4.56] + a.setValues(arr1,9,1); + m,where=a.getMaxValue(); + self.assertEqual(1,where); + self.assertAlmostEqual(4.56,m,12); + m,ws=a.getMaxValue2(); + self.assertAlmostEqual(4.56,m,12); + self.assertEqual(3,ws.getNumberOfTuples()); + self.assertEqual(1,ws.getNumberOfComponents()); + expected1=[1,4,8] + for i in xrange(3): + self.assertEqual(expected1[i],ws.getIJ(i,0)); + pass + a=DataArrayDouble.New(); + arr2=[-2.34,-4.56,6.77,-4.55,-4.56,-2.24,-2.34,-1.02,-4.56] + a.setValues(arr2,9,1); + m,where=a.getMinValue(); + self.assertEqual(1,where); + self.assertAlmostEqual(-4.56,m,12); + m,ws=a.getMinValue2(); + self.assertAlmostEqual(-4.56,m,12); + self.assertEqual(3,ws.getNumberOfTuples()); + self.assertEqual(1,ws.getNumberOfComponents()); + for i in xrange(3): + self.assertEqual(expected1[i],ws.getIJ(i,0)); + pass + pass + + def testFieldDoubleGetMinMaxValues2(self): + m2,m1=MEDCouplingDataForTest.build3DExtrudedUMesh_1(); + self.assertEqual(18,m2.getNumberOfCells()); + arr1=[8.71,4.53,-12.41,8.71,-8.71,8.7099,4.55,8.71,5.55,6.77,-1e-200,4.55,8.7099,0.,1.23,0.,2.22,8.71] + f=MEDCouplingFieldDouble.New(ON_CELLS,NO_TIME); + a=DataArrayDouble.New(); + a.setValues(arr1,18,1); + f.setArray(a); + f.setMesh(m2); + # + f.checkCoherency(); + m=f.getMaxValue(); + self.assertAlmostEqual(8.71,m,12); + m,ws=f.getMaxValue2(); + self.assertAlmostEqual(8.71,m,12); + self.assertEqual(4,ws.getNumberOfTuples()); + self.assertEqual(1,ws.getNumberOfComponents()); + expected1=[0,3,7,17] + for i in xrange(4): + self.assertEqual(expected1[i],ws.getIJ(i,0)); + pass + # + arr2=[-8.71,-4.53,12.41,-8.71,8.71,-8.7099,-4.55,-8.71,-5.55,-6.77,1e-200,-4.55,-8.7099,0.,-1.23,0.,-2.22,-8.71] + a.setValues(arr2,18,1); + f.checkCoherency(); + m=f.getMinValue(); + self.assertAlmostEqual(-8.71,m,12); + m,ws=f.getMinValue2(); + self.assertAlmostEqual(-8.71,m,12); + self.assertEqual(4,ws.getNumberOfTuples()); + self.assertEqual(1,ws.getNumberOfComponents()); + for i in xrange(4): + self.assertEqual(expected1[i],ws.getIJ(i,0)); + pass + pass + + def testBuildUnstructuredCMesh1(self): + m=MEDCouplingCMesh.New(); + da=DataArrayDouble.New(); + discX=[2.3,3.4,5.8,10.2] + discY=[12.3,23.4,45.8] + discZ=[-0.7,1.2,1.25,2.13,2.67] + da.setValues(discX,4,1); + m.setCoordsAt(0,da); + m.checkCoherency(); + self.assertEqual(0,m.getCellContainingPoint([2.4],1e-12)); + self.assertEqual(1,m.getCellContainingPoint([3.7],1e-12)); + self.assertEqual(2,m.getCellContainingPoint([5.9],1e-12)); + self.assertEqual(-1,m.getCellContainingPoint([10.3],1e-12)); + self.assertEqual(-1,m.getCellContainingPoint([1.3],1e-12)); + # + m2=m.buildUnstructured(); + m2.checkCoherency(); + f1=m.getMeasureField(False); + f2=m2.getMeasureField(False); + self.assertTrue(isinstance(f1.getMesh(),MEDCouplingCMesh)) + self.assertEqual(f1.getNumberOfTuples(),3); + self.assertEqual(f2.getNumberOfTuples(),3); + self.assertEqual(1,m2.getMeshDimension()); + self.assertEqual(1,m2.getSpaceDimension()); + for i in xrange(3): + self.assertAlmostEqual(f1.getIJ(i,0),f2.getIJ(i,0),10); + pass + da=DataArrayDouble.New(); + da.setValues(discY,3,1); + m.setCoordsAt(1,da); + # + m2=m.buildUnstructured(); + m2.checkCoherency(); + f1=m.getMeasureField(False); + f2=m2.getMeasureField(False); + self.assertEqual(f1.getNumberOfTuples(),6); + self.assertEqual(f2.getNumberOfTuples(),6); + self.assertEqual(2,m2.getMeshDimension()); + self.assertEqual(2,m2.getSpaceDimension()); + for i in xrange(6): + self.assertAlmostEqual(f1.getIJ(i,0),f2.getIJ(i,0),10); + pass + # + da=DataArrayDouble.New(); + da.setValues(discZ,5,1); + m.setCoordsAt(2,da); + m2=m.buildUnstructured(); + m2.checkCoherency(); + f1=m.getMeasureField(False); + f2=m2.getMeasureField(False); + self.assertEqual(f1.getNumberOfTuples(),24); + self.assertEqual(f2.getNumberOfTuples(),24); + self.assertEqual(3,m2.getMeshDimension()); + self.assertEqual(3,m2.getSpaceDimension()); + for i in xrange(24): + self.assertAlmostEqual(f1.getIJ(i,0),f2.getIJ(i,0),10); + pass + # + pos1=[5.,30.,2.] + self.assertEqual(16,m.getCellContainingPoint(pos1,1e-12)); + # + elems=m2.getCellsInBoundingBox([3.5,6.,12.2,25.,0.,1.5],1e-7) + self.assertEqual([1, 2, 4, 5, 7, 8, 10, 11, 13, 14, 16, 17],elems.getValues()) + # + pt=[2.4,12.7,-3.4] + m.scale(pt,3.7); + m3=m.buildUnstructured(); + m2.scale(pt,3.7); + self.assertTrue(m3.isEqual(m2,1e-12)); + pass + + def testDataArrayIntInvertO2NNO21(self): + arr1=[2,0,4,1,5,3] + da=DataArrayInt.New(); + da.setValues(arr1,6,1); + da2=da.invertArrayO2N2N2O(6); + self.assertEqual(6,da2.getNumberOfTuples()); + self.assertEqual(1,da2.getNumberOfComponents()); + expected1=[1,3,0,5,2,4] + for i in xrange(6): + self.assertEqual(expected1[i],da2.getIJ(i,0)); + pass + da3=da2.invertArrayN2O2O2N(6); + for i in xrange(6): + self.assertEqual(arr1[i],da3.getIJ(i,0)); + pass + # + arr2=[3,-1,5,4,-1,0,-1,1,2,-1] + da=DataArrayInt.New(); + da.setValues(arr2,10,1); + da2=da.invertArrayO2N2N2O(6); + self.assertEqual(6,da2.getNumberOfTuples()); + self.assertEqual(1,da2.getNumberOfComponents()); + expected2=[5,7,8,0,3,2] + for i in xrange(6): + self.assertEqual(expected2[i],da2.getIJ(i,0)); + pass + da3=da2.invertArrayN2O2O2N(10); + for i in xrange(10): + self.assertEqual(arr2[i],da3.getIJ(i,0)); + pass + pass + + def testKeepSetSelectedComponent1(self): + arr1=[1.,2.,3.,4., 11.,12.,13.,14., 21.,22.,23.,24., 31.,32.,33.,34., 41.,42.,43.,44.] + a1=DataArrayDouble.New(); + a1.setValues(arr1,5,4); + expp=[21.,22.,23.,24.] + self.assertEqual(4,len(a1.getTuple(2))); + for i in xrange(4): + self.assertAlmostEqual(expp[i],a1.getTuple(2)[i],12) + pass + a1.setInfoOnComponent(0,"aaaa"); + a1.setInfoOnComponent(1,"bbbb"); + a1.setInfoOnComponent(2,"cccc"); + a1.setInfoOnComponent(3,"dddd"); + arr2V=[1,2,1,2,0,0] + a2=a1.keepSelectedComponents(arr2V); + self.assertEqual(6,a2.getNumberOfComponents()); + self.assertEqual(5,a2.getNumberOfTuples()); + self.assertTrue(a2.getInfoOnComponent(0)=="bbbb"); + self.assertTrue(a2.getInfoOnComponent(1)=="cccc"); + self.assertTrue(a2.getInfoOnComponent(2)=="bbbb"); + self.assertTrue(a2.getInfoOnComponent(3)=="cccc"); + self.assertTrue(a2.getInfoOnComponent(4)=="aaaa"); + self.assertTrue(a2.getInfoOnComponent(5)=="aaaa"); + expected1=[2.,3.,2.,3.,1.,1., 12.,13.,12.,13.,11.,11., 22.,23.,22.,23.,21.,21., 32.,33.,32.,33.,31.,31., 42.,43.,42.,43.,41.,41.] + for i in xrange(30): + self.assertAlmostEqual(expected1[i],a2.getIJ(0,i),14); + pass + a3=a1.convertToIntArr(); + self.assertEqual([21,22,23,24],a3.getTuple(2)) + a4=a3.keepSelectedComponents(arr2V); + self.assertEqual(6,a4.getNumberOfComponents()); + self.assertEqual(5,a4.getNumberOfTuples()); + self.assertTrue(a4.getInfoOnComponent(0)=="bbbb"); + self.assertTrue(a4.getInfoOnComponent(1)=="cccc"); + self.assertTrue(a4.getInfoOnComponent(2)=="bbbb"); + self.assertTrue(a4.getInfoOnComponent(3)=="cccc"); + self.assertTrue(a4.getInfoOnComponent(4)=="aaaa"); + self.assertTrue(a4.getInfoOnComponent(5)=="aaaa"); + for i in xrange(30): + self.assertEqual(int(expected1[i]),a4.getIJ(0,i)); + pass + # setSelectedComponents + arr3V=[3,2] + a5=a1.keepSelectedComponents(arr3V); + a5.setInfoOnComponent(0,"eeee"); + a5.setInfoOnComponent(1,"ffff"); + arr4V=[1,2] + a2.setSelectedComponents(a5,arr4V); + self.assertEqual(6,a2.getNumberOfComponents()); + self.assertEqual(5,a2.getNumberOfTuples()); + self.assertTrue(a2.getInfoOnComponent(0)=="bbbb"); + self.assertTrue(a2.getInfoOnComponent(1)=="eeee"); + self.assertTrue(a2.getInfoOnComponent(2)=="ffff"); + self.assertTrue(a2.getInfoOnComponent(3)=="cccc"); + self.assertTrue(a2.getInfoOnComponent(4)=="aaaa"); + self.assertTrue(a2.getInfoOnComponent(5)=="aaaa"); + expected2=[2.,4.,3.,3.,1.,1., 12.,14.,13.,13.,11.,11., 22.,24.,23.,23.,21.,21., 32.,34.,33.,33.,31.,31., 42.,44.,43.,43.,41.,41.] + for i in xrange(30): + self.assertAlmostEqual(expected2[i],a2.getIJ(0,i),14); + pass + a6=a5.convertToIntArr(); + a6.setInfoOnComponent(0,"eeee"); + a6.setInfoOnComponent(1,"ffff"); + a4.setSelectedComponents(a6,arr4V); + self.assertEqual(6,a4.getNumberOfComponents()); + self.assertEqual(5,a4.getNumberOfTuples()); + self.assertTrue(a4.getInfoOnComponent(0)=="bbbb"); + self.assertTrue(a4.getInfoOnComponent(1)=="eeee"); + self.assertTrue(a4.getInfoOnComponent(2)=="ffff"); + self.assertTrue(a4.getInfoOnComponent(3)=="cccc"); + self.assertTrue(a4.getInfoOnComponent(4)=="aaaa"); + self.assertTrue(a4.getInfoOnComponent(5)=="aaaa"); + for i in xrange(30): + self.assertEqual(int(expected2[i]),a4.getIJ(0,i)); + pass + # test of throw + arr5V=[2,3,6] + arr6V=[2,7,5] + arr7V=[2,1,4,6] + self.assertRaises(InterpKernelException,a2.keepSelectedComponents,arr5V); + self.assertRaises(InterpKernelException,a2.keepSelectedComponents,arr6V); + self.assertRaises(InterpKernelException,a2.setSelectedComponents,a1,arr7V); + arr7V=arr7V[0:3] + self.assertRaises(InterpKernelException,a2.setSelectedComponents,a1,arr7V); + # + pass + + def testKeepSetSelectedComponent2(self): + m1=MEDCouplingDataForTest.build2DTargetMesh_1(); + arr1=[1.,2.,3.,4., 11.,12.,13.,14., 21.,22.,23.,24., 31.,32.,33.,34., 41.,42.,43.,44.] + a1=DataArrayDouble.New(); + a1.setValues(arr1,5,4); + a1.setInfoOnComponent(0,"aaaa"); + a1.setInfoOnComponent(1,"bbbb"); + a1.setInfoOnComponent(2,"cccc"); + a1.setInfoOnComponent(3,"dddd"); + f1=MEDCouplingFieldDouble.New(ON_CELLS,ONE_TIME); + f1.setTime(2.3,4,5); + f1.setMesh(m1); + f1.setName("f1"); + f1.setArray(a1); + f1.checkCoherency(); + # + arr2V=[1,2,1,2,0,0] + f2=f1.keepSelectedComponents(arr2V); + self.assertTrue(f2.getTimeDiscretization()==ONE_TIME); + t,dt,it=f2.getTime() + self.assertAlmostEqual(2.3,t,13); + self.assertEqual(4,dt); + self.assertEqual(5,it); + f2.checkCoherency(); + self.assertEqual(6,f2.getNumberOfComponents()); + self.assertEqual(5,f2.getNumberOfTuples()); + self.assertTrue(f2.getArray().getInfoOnComponent(0)=="bbbb"); + self.assertTrue(f2.getArray().getInfoOnComponent(1)=="cccc"); + self.assertTrue(f2.getArray().getInfoOnComponent(2)=="bbbb"); + self.assertTrue(f2.getArray().getInfoOnComponent(3)=="cccc"); + self.assertTrue(f2.getArray().getInfoOnComponent(4)=="aaaa"); + self.assertTrue(f2.getArray().getInfoOnComponent(5)=="aaaa"); + expected1=[2.,3.,2.,3.,1.,1., 12.,13.,12.,13.,11.,11., 22.,23.,22.,23.,21.,21., 32.,33.,32.,33.,31.,31., 42.,43.,42.,43.,41.,41.] + for i in xrange(30): + self.assertAlmostEqual(expected1[i],f2.getIJ(0,i),14); + pass + #setSelectedComponents + arr3V=[3,2] + f5=f1.keepSelectedComponents(arr3V); + f5.setTime(6.7,8,9); + f5.getArray().setInfoOnComponent(0,"eeee"); + f5.getArray().setInfoOnComponent(1,"ffff"); + f5.checkCoherency(); + arr4V=[1,2] + f2.setSelectedComponents(f5,arr4V); + self.assertEqual(6,f2.getNumberOfComponents()); + self.assertEqual(5,f2.getNumberOfTuples()); + f2.checkCoherency(); + t,dt,it=f2.getTime() + self.assertAlmostEqual(2.3,t,13); + self.assertEqual(4,dt); + self.assertEqual(5,it); + self.assertTrue(f2.getArray().getInfoOnComponent(0)=="bbbb"); + self.assertTrue(f2.getArray().getInfoOnComponent(1)=="eeee"); + self.assertTrue(f2.getArray().getInfoOnComponent(2)=="ffff"); + self.assertTrue(f2.getArray().getInfoOnComponent(3)=="cccc"); + self.assertTrue(f2.getArray().getInfoOnComponent(4)=="aaaa"); + self.assertTrue(f2.getArray().getInfoOnComponent(5)=="aaaa"); + expected2=[2.,4.,3.,3.,1.,1., 12.,14.,13.,13.,11.,11., 22.,24.,23.,23.,21.,21., 32.,34.,33.,33.,31.,31., 42.,44.,43.,43.,41.,41.] + for i in xrange(30): + self.assertAlmostEqual(expected2[i],f2.getIJ(0,i),14); + pass + # + pass + + def testElementaryDAThrowAndSpecialCases(self): + da=DataArrayInt.New(); + self.assertRaises(InterpKernelException, da.checkAllocated); + self.assertRaises(InterpKernelException, da.fillWithValue, 1); + self.assertRaises(InterpKernelException, da.iota, 1); + da.alloc(7,1); + da.fillWithValue(11); #11,11,11,11... + da.iota(10); #10,11,12,13... + + db=DataArrayInt.New(); + db.alloc(7,2); + + dbl2=DataArrayDouble.New(); + dbl2.alloc(7,2); + self.assertRaises(InterpKernelException, dbl2.isUniform, 10., 1e-15); + self.assertRaises(InterpKernelException, dbl2.sort); + self.assertRaises(InterpKernelException, dbl2.iota, 10.); + + dbl=DataArrayDouble.New(); + #DataArrayDouble not allocated yet + self.assertRaises(InterpKernelException, dbl.iota, 10.); + self.assertRaises(InterpKernelException, dbl.isUniform, 10., 1e-15); + self.assertRaises(InterpKernelException, dbl.sort); + self.assertRaises(InterpKernelException, dbl.fromNoInterlace); + self.assertRaises(InterpKernelException, dbl.toNoInterlace); + + dbl.alloc(7,1); + dbl.iota(10.); + self.assertTrue(not dbl.isUniform(10.,1e-15)); + dbl.sort(); + self.assertTrue(dbl.isMonotonic(True, .99)); + self.assertTrue(dbl.isMonotonic(True, -.99)); + self.assertTrue(not dbl.isMonotonic(True, 1.1)); + self.assertTrue(not dbl.isMonotonic(True, -1.1)); + dbl.reverse(); + self.assertTrue(dbl.isMonotonic(False, .99)); + self.assertTrue(not dbl.isMonotonic(False, 1.1)); + self.assertTrue(not dbl.isMonotonic(False, -1.1)); + + dc=DataArrayInt.New(); + dc.alloc(14,1); + + dd=DataArrayDouble.New(); + self.assertRaises(InterpKernelException, dd.checkAllocated); + self.assertRaises(InterpKernelException, dd.fillWithValue, 1.); + self.assertRaises(InterpKernelException, dd.iota, 1.); + self.assertTrue(not ((dd.repr().find("No data"))==-1)); + + dd.alloc(0,1); #Allocated but nbOfElements==0! + self.assertTrue(not ((dd.repr().find("Number of tuples : 0"))==-1)); + self.assertTrue(not ((dd.repr().find("Empty Data"))==-1)); + dd.fillWithValue(11); #?!...ok + dd.iota(10); #?!...ok + self.assertTrue(dd.isMonotonic(True, 1.)); #nothing is monotonic + self.assertTrue(dd.isMonotonic(False, 1.)); + + self.assertRaises(InterpKernelException, db.copyStringInfoFrom, da); + self.assertRaises(InterpKernelException, db.copyStringInfoFrom, da); + cIds=[2,2] + self.assertRaises(InterpKernelException, da.copyPartOfStringInfoFrom, db, cIds); + cIds[0]=1; + cIds[0]=-1; + self.assertRaises(InterpKernelException, da.copyPartOfStringInfoFrom, db, cIds); + + info=["infoOfOneComponent"]*2; + self.assertRaises(InterpKernelException, da.setInfoOnComponents, info); + self.assertRaises(InterpKernelException, da.setInfoOnComponent, 1, info[0]); + db.setInfoOnComponents(info); + + self.assertRaises(InterpKernelException, da.getInfoOnComponent, -1); + self.assertRaises(InterpKernelException, da.getInfoOnComponent, 2); + self.assertTrue(db.getInfoOnComponent(1)==db.getInfoOnComponent(0)); + self.assertRaises(InterpKernelException, db.getVarOnComponent, -1); + self.assertRaises(InterpKernelException, db.getVarOnComponent, 2); + self.assertRaises(InterpKernelException, db.getUnitOnComponent, -1); + self.assertRaises(InterpKernelException, db.getUnitOnComponent, 2); + + self.assertTrue(da.GetVarNameFromInfo("varname unit ")=="varname unit "); + self.assertTrue(da.GetVarNameFromInfo("varname]unit[")=="varname]unit["); + self.assertTrue(da.GetVarNameFromInfo("[unit]")==""); + self.assertTrue(da.GetVarNameFromInfo("varname [unit]")=="varname"); + + self.assertTrue(da.GetUnitFromInfo("varname unit ")==""); + self.assertTrue(da.GetUnitFromInfo("varname]unit[")==""); + self.assertTrue(da.GetUnitFromInfo("[unit]")=="unit"); + self.assertTrue(da.GetUnitFromInfo("varname [unit]")=="unit"); + + self.assertRaises(InterpKernelException, da.checkNbOfTuplesAndComp, db, "theMessageInThrow"); + self.assertRaises(InterpKernelException, da.checkNbOfTuplesAndComp, dc, "theMessageInThrow"); + self.assertRaises(InterpKernelException, db.checkNbOfTuplesAndComp, dc, "theMessageInThrow"); + + self.assertRaises(InterpKernelException, da.checkNbOfTuplesAndComp, 7, 2, "theMessageInThrow"); + da.checkNbOfTuplesAndComp(7,1,"theMessageInThrow"); + + self.assertRaises(InterpKernelException, db.checkNbOfElems, 7*2+1, "theMessageInThrow"); + db.checkNbOfElems(7*2,"theMessageInThrow"); + + self.assertRaises(InterpKernelException, db.GetNumberOfItemGivenBES, 10, 9, 1, "theMessageInThrow"); + self.assertRaises(InterpKernelException, db.GetNumberOfItemGivenBES, 0, 1, -1, "theMessageInThrow"); + self.assertEqual(10,db.GetNumberOfItemGivenBES(0,10,1,"theMessageInThrow")); + self.assertEqual(5,db.GetNumberOfItemGivenBES(0,10,2,"theMessageInThrow")); + self.assertEqual(6,db.GetNumberOfItemGivenBES(0,11,2,"theMessageInThrow")); + + self.assertTrue(not ((da.repr().find("Number of components : 1"))==-1)); + self.assertTrue(not ((dd.repr().find("Number of components : 1"))==-1)); + self.assertTrue(not ((dbl.repr().find("Number of components : 1"))==-1)); + + self.assertTrue(not ((da.reprZip().find("Number of components : 1"))==-1)); + self.assertTrue(not ((dd.reprZip().find("Number of components : 1"))==-1)); + self.assertTrue(not ((dbl.reprZip().find("Number of components : 1"))==-1)); + + self.assertRaises(InterpKernelException, dbl.selectByTupleId2, 0, 1, -1); + self.assertRaises(InterpKernelException, dbl.substr, -1, 1); + self.assertRaises(InterpKernelException, dbl.substr, 8, 1); + self.assertRaises(InterpKernelException, dbl.substr, 0, 8); + self.assertRaises(InterpKernelException, dbl.meldWith, dd); + + self.assertRaises(InterpKernelException, dbl.setPartOfValuesAdv, dbl2, da); #dbl dbl2 not have the same number of components + self.assertRaises(InterpKernelException, dbl.setPartOfValuesAdv, dd, da); #da tuple selector DataArrayInt instance not have exactly 2 components + + dbl3=DataArrayDouble.New(); + dbl3.alloc(6,2); + dbl3.fillWithValue(11.); + #bad number of components + self.assertRaises(InterpKernelException, dbl3.getMaxValue); + self.assertRaises(InterpKernelException, dd.getMaxValue); + self.assertRaises(InterpKernelException, dbl3.getMinValue); + self.assertRaises(InterpKernelException, dd.getMinValue); + self.assertRaises(InterpKernelException, dbl3.getAverageValue); + self.assertRaises(InterpKernelException, dd.getAverageValue); + self.assertRaises(InterpKernelException, dd.accumulate, 100); + self.assertRaises(InterpKernelException, dbl.fromPolarToCart); + self.assertRaises(InterpKernelException, dbl3.fromCylToCart); + self.assertRaises(InterpKernelException, dbl3.fromSpherToCart); + self.assertRaises(InterpKernelException, dbl3.doublyContractedProduct); + self.assertRaises(InterpKernelException, dbl3.determinant); + self.assertRaises(InterpKernelException, dbl3.eigenValues); + self.assertRaises(InterpKernelException, dbl3.eigenVectors); + self.assertRaises(InterpKernelException, dbl3.inverse); + self.assertRaises(InterpKernelException, dbl3.trace); + self.assertRaises(InterpKernelException, dbl3.deviator); + + dbl3.setIJ(5,1,12.); + self.assertTrue(dbl3.getMaxValueInArray()==12.); + self.assertTrue(dbl3.getMinValueInArray()==11.); + + db.fillWithValue(100); #bad Ids + self.assertRaises(InterpKernelException, dbl3.setPartOfValuesAdv, dbl2, db); + db.fillWithValue(-1); #bad Ids + self.assertRaises(InterpKernelException, dbl3.setPartOfValuesAdv, dbl2, db); + db.fillWithValue(6); #bad Ids for dbl3 + self.assertRaises(InterpKernelException, dbl3.setPartOfValuesAdv, dbl2, db); + + dbl3.checkNoNullValues(); + dbl3.setIJ(5,0,0.); + self.assertRaises(InterpKernelException, dbl3.checkNoNullValues); + self.assertRaises(InterpKernelException, dbl3.applyInv, 1.); #div by zero + self.assertRaises(InterpKernelException, dbl2.getIdsInRange, 1., 2.); + a=[] + self.assertRaises(InterpKernelException, DataArrayDouble_Aggregate, a); + self.assertRaises(InterpKernelException, DataArrayDouble_Meld, a); + + a=[dbl2,dbl]; #Nb of components mismatch + self.assertRaises(InterpKernelException, DataArrayDouble_Aggregate, a); + + self.assertRaises(InterpKernelException, DataArrayDouble_Dot, dbl2, dbl); + + self.assertRaises(InterpKernelException, DataArrayDouble_CrossProduct, dbl2, dbl); #Nb of components mismatch + self.assertRaises(InterpKernelException, DataArrayDouble_CrossProduct, dbl2, dbl2); #Nb of components must be equal to 3 + dbl4=DataArrayDouble.New(); + dbl4.alloc(6,3); + dbl5=DataArrayDouble.New(); + dbl5.alloc(7,3); + self.assertRaises(InterpKernelException, DataArrayDouble_CrossProduct, dbl4, dbl5); #Nb of tuples mismatch + + a[0]=dbl4; #Nb of tuple mismatch + a[1]=dbl5; #Nb of tuple mismatch + self.assertRaises(InterpKernelException, DataArrayDouble_Meld, a); + self.assertRaises(InterpKernelException, DataArrayDouble_Dot, dbl4, dbl5); + pass + + def testDAIGetIdsEqual1(self): + tab1=[5,-2,-4,-2,3,2,-2]; + da=DataArrayInt.New(); + da.setValues(tab1,7,1); + da2=da.getIdsEqual(-2); + self.assertEqual(3,da2.getNumberOfTuples()); + self.assertEqual(1,da2.getNumberOfComponents()); + expected1=[1,3,6]; + self.assertEqual(expected1,da2.getValues()); + pass + + def testDAIGetIdsEqualList1(self): + tab1=[5,-2,-4,-2,3,2,-2]; + da=DataArrayInt.New(); + da.setValues(tab1,7,1); + da2=da.getIdsEqualList([3,-2,0]); + self.assertEqual(4,da2.getNumberOfTuples()); + self.assertEqual(1,da2.getNumberOfComponents()); + expected1=[1,3,4,6]; + self.assertEqual(expected1,da2.getValues()); + pass + + def testDAFromNoInterlace1(self): + tab1=[1,11,21,31,41,2,12,22,32,42,3,13,23,33,43] + da=DataArrayInt.New(); + da.setValues(tab1,5,3); + da2=da.fromNoInterlace(); + expected1=[1,2,3,11,12,13,21,22,23,31,32,33,41,42,43] + self.assertEqual(5,da2.getNumberOfTuples()); + self.assertEqual(3,da2.getNumberOfComponents());# it's not a bug. Avoid to have 1 million components ! + self.assertEqual(expected1,da2.getValues()); + da3=da.convertToDblArr(); + da4=da3.fromNoInterlace(); + self.assertEqual(5,da4.getNumberOfTuples()); + self.assertEqual(3,da4.getNumberOfComponents());# it's not a bug. Avoid to have 1 million components ! + for i in xrange(15): + self.assertAlmostEqual(expected1[i],da4.getIJ(0,i),14); + pass + pass + + def testDAToNoInterlace1(self): + tab1=[1,2,3,11,12,13,21,22,23,31,32,33,41,42,43] + da=DataArrayInt.New(); + da.setValues(tab1,5,3); + da2=da.toNoInterlace(); + expected1=[1,11,21,31,41,2,12,22,32,42,3,13,23,33,43] + self.assertEqual(5,da2.getNumberOfTuples()); + self.assertEqual(3,da2.getNumberOfComponents());# it's not a bug. Avoid to have 1 million components ! + self.assertEqual(expected1,da2.getValues()); + da3=da.convertToDblArr(); + da4=da3.toNoInterlace(); + self.assertEqual(5,da4.getNumberOfTuples()); + self.assertEqual(3,da4.getNumberOfComponents());# it's not a bug. Avoid to have 1 million components ! + for i in xrange(15): + self.assertAlmostEqual(expected1[i],da4.getIJ(0,i),14); + pass + pass + + def testDAIsUniform1(self): + tab1=[1,1,1,1,1] + da=DataArrayInt.New(); + da.setValues(tab1,5,1); + self.assertTrue(da.isUniform(1)); + da.setIJ(2,0,2); + self.assertTrue(not da.isUniform(1)); + da.setIJ(2,0,1); + self.assertTrue(da.isUniform(1)); + da2=da.convertToDblArr(); + self.assertTrue(da2.isUniform(1.,1.e-12)); + da2.setIJ(1,0,1.+1.e-13); + self.assertTrue(da2.isUniform(1.,1.e-12)); + da2.setIJ(1,0,1.+1.e-11); + self.assertTrue(not da2.isUniform(1.,1.e-12)); + pass + + def testDADFromPolarToCart1(self): + tab1=[2.,0.2,2.5,0.7] + da=DataArrayDouble.New(); + da.setValues(tab1,2,2); + da2=da.fromPolarToCart(); + expected1=[1.9601331556824833,0.39733866159012243, 1.9121054682112213,1.6105442180942275] + for i in xrange(4): + self.assertAlmostEqual(expected1[i],da2.getIJ(0,i),13); + pass + pass + + def testDADFromCylToCart1(self): + tab1=[2.,0.2,4.,2.5,0.7,9.] + da=DataArrayDouble.New(); + da.setValues(tab1,2,3); + da2=da.fromCylToCart(); + expected1=[1.9601331556824833,0.39733866159012243,4., 1.9121054682112213,1.6105442180942275,9.] + for i in xrange(6): + self.assertAlmostEqual(expected1[i],da2.getIJ(0,i),13); + pass + pass + + def testDADFromSpherToCart1(self): + tab1=[2.,0.2,0.3,2.5,0.7,0.8] + da=DataArrayDouble.New(); + da.setValues(tab1,2,3); + da2=da.fromSpherToCart(); + expected1=[0.37959212195737485,0.11742160338765303,1.9601331556824833, 1.1220769624465328,1.1553337045129035,1.9121054682112213] + for i in xrange(6): + self.assertAlmostEqual(expected1[i],da2.getIJ(0,i),13); + pass + pass + + def testUnPolyze1(self): + elts=[0,1,2,3,4,5,6,7] + eltsV=elts; + mesh=MEDCouplingDataForTest.build3DTargetMesh_1(); + mesh.convertToPolyTypes(eltsV); + mesh.unPolyze(); + mesh2=MEDCouplingDataForTest.build3DTargetMesh_1(); + mesh.checkCoherency(); + self.assertTrue(mesh.isEqual(mesh2,1e-12)); + mesh.convertToPolyTypes(eltsV); + self.assertTrue(not mesh.isEqual(mesh2,1e-12)); + mesh.getNodalConnectivity().setIJ(0,6,10); + mesh.getNodalConnectivity().setIJ(0,7,9); + mesh.getNodalConnectivity().setIJ(0,8,12); + mesh.getNodalConnectivity().setIJ(0,9,13); + mesh.unPolyze(); + self.assertTrue(mesh.isEqual(mesh2,1e-12)); + mesh.convertToPolyTypes(eltsV); + mesh.getNodalConnectivity().setIJ(0,6,12); + mesh.getNodalConnectivity().setIJ(0,7,13); + mesh.getNodalConnectivity().setIJ(0,8,10); + mesh.getNodalConnectivity().setIJ(0,9,9); + mesh.unPolyze(); + self.assertTrue(mesh.isEqual(mesh2,1e-12)); + mesh.convertToPolyTypes(eltsV); + mesh.getNodalConnectivity().setIJ(0,6,12); + mesh.getNodalConnectivity().setIJ(0,7,10); + mesh.getNodalConnectivity().setIJ(0,8,13); + mesh.getNodalConnectivity().setIJ(0,9,9); + mesh.unPolyze(); + self.assertTrue(not mesh.isEqual(mesh2,1e-12)); + # Test for 2D mesh + mesh=MEDCouplingDataForTest.build2DTargetMesh_1(); + mesh2=MEDCouplingDataForTest.build2DTargetMesh_1(); + eltsV=eltsV[:5]; + mesh.convertToPolyTypes(eltsV); + self.assertTrue(not mesh.isEqual(mesh2,1e-12)); + mesh.unPolyze(); + self.assertTrue(mesh.isEqual(mesh2,1e-12)); + pass + + def testConvertDegeneratedCells1(self): + mesh=MEDCouplingDataForTest.build3DTargetMesh_1(); + conn=[0,1,3,3,9,10,12,12, 0,1,3,4,9,9,9,9, 1,1,1,1,10,12,9,10, 10,11,12,9,1,1,1,1] + mesh.allocateCells(4); + mesh.insertNextCell(NORM_HEXA8,8,conn[0:8]) + mesh.insertNextCell(NORM_HEXA8,8,conn[8:16]) + mesh.insertNextCell(NORM_HEXA8,8,conn[16:24]) + mesh.insertNextCell(NORM_HEXA8,8,conn[24:32]) + mesh.finishInsertingCells(); + mesh.checkCoherency(); + self.assertEqual(4,mesh.getNumberOfCells()); + self.assertEqual(NORM_HEXA8,mesh.getTypeOfCell(0)); + self.assertEqual(NORM_HEXA8,mesh.getTypeOfCell(1)); + self.assertEqual(NORM_HEXA8,mesh.getTypeOfCell(2)); + self.assertEqual(NORM_HEXA8,mesh.getTypeOfCell(3)); + f1=mesh.getMeasureField(True); + mesh.convertDegeneratedCells(); + mesh.checkCoherency(); + f2=mesh.getMeasureField(True); + self.assertEqual(4,mesh.getNumberOfCells()); + self.assertEqual(NORM_PENTA6,mesh.getTypeOfCell(0)); + self.assertEqual(NORM_PYRA5,mesh.getTypeOfCell(1)); + self.assertEqual(NORM_TETRA4,mesh.getTypeOfCell(2)); + self.assertEqual(NORM_PYRA5,mesh.getTypeOfCell(3)); + for i in xrange(4): + self.assertAlmostEqual(f1.getArray().getIJ(0,i),f2.getArray().getIJ(0,i),5); + pass + pass + + def testGetNodeIdsNearPoints1(self): + mesh=MEDCouplingDataForTest.build2DTargetMesh_1(); + coords=mesh.getCoords(); + tmp=DataArrayDouble.New(); + vals=[0.2,0.2,0.1,0.2,0.2,0.2] + tmp.setValues(vals,3,2); + tmp2=DataArrayDouble.Aggregate(coords,tmp); + mesh.setCoords(tmp2); + pts=[0.2,0.2,0.1,0.3,-0.3,0.7] + c=mesh.getNodeIdsNearPoint(pts[:2],1e-7); + self.assertEqual([4,9,11],c.getValues()); + c,cI=mesh.getNodeIdsNearPoints(pts,3,1e-7); + self.assertEqual([0,3,3,4],cI.getValues()); + self.assertEqual([4,9,11,6],c.getValues()); + c,cI=mesh.getNodeIdsNearPoints(pts,1e-7); + self.assertEqual([0,3,3,4],cI.getValues()); + self.assertEqual([4,9,11,6],c.getValues()); + c,cI=mesh.getNodeIdsNearPoints(DataArrayDouble.New(pts,3,2),1e-7); + self.assertEqual([0,3,3,4],cI.getValues()); + self.assertEqual([4,9,11,6],c.getValues()); + self.assertRaises(InterpKernelException,mesh.getNodeIdsNearPoints,DataArrayDouble.New(pts,2,3),1e-7); + pass + + def testFieldCopyTinyAttrFrom1(self): + f1=MEDCouplingFieldDouble.New(ON_CELLS,ONE_TIME); + f1.setName("f1"); + f1.setTimeTolerance(1.e-5); + f1.setDescription("f1Desc"); + f1.setTime(1.23,4,5); + f2=MEDCouplingFieldDouble.New(ON_CELLS,ONE_TIME); + f2.setName("f2"); + f2.setDescription("f2Desc"); + f2.setTime(6.78,9,10); + f2.setTimeTolerance(4.556e-12); + # + f1.copyTinyAttrFrom(f2); + self.assertAlmostEqual(4.556e-12,f1.getTimeTolerance(),24); + t,dt,it=f1.getTime() + self.assertAlmostEqual(6.78,t,12); + self.assertEqual(9,dt); + self.assertEqual(10,it); + self.assertTrue(f1.getName()=="f1");#name unchanged + self.assertTrue(f1.getDescription()=="f1Desc");#description unchanged + # + f1=MEDCouplingFieldDouble.New(ON_CELLS,NO_TIME); + f1.setName("f1"); + f1.setTimeTolerance(1.e-5); + f1.setDescription("f1Desc"); + f2=MEDCouplingFieldDouble.New(ON_CELLS,NO_TIME); + f2.setName("f2"); + f2.setDescription("f2Desc"); + f2.setTimeTolerance(4.556e-12); + # + f1.copyTinyAttrFrom(f2); + self.assertAlmostEqual(4.556e-12,f1.getTimeTolerance(),24); + self.assertTrue(f1.getName()=="f1");#name unchanged + self.assertTrue(f1.getDescription()=="f1Desc");#description unchanged + # + f1=MEDCouplingFieldDouble.New(ON_CELLS,CONST_ON_TIME_INTERVAL); + f1.setName("f1"); + f1.setTimeTolerance(1.e-5); + f1.setDescription("f1Desc"); + f1.setTime(1.23,4,5); + f1.setEndTime(5.43,2,1); + f2=MEDCouplingFieldDouble.New(ON_CELLS,CONST_ON_TIME_INTERVAL); + f2.setName("f2"); + f2.setDescription("f2Desc"); + f2.setTimeTolerance(4.556e-12); + f2.setTime(6.78,9,10); + f2.setEndTime(10.98,7,6); + # + f1.copyTinyAttrFrom(f2); + self.assertAlmostEqual(4.556e-12,f1.getTimeTolerance(),24); + self.assertTrue(f1.getName()=="f1");#name unchanged + self.assertTrue(f1.getDescription()=="f1Desc");#description unchanged + t,dt,it=f1.getTime() + self.assertAlmostEqual(6.78,t,12); + self.assertEqual(9,dt); + self.assertEqual(10,it); + t,dt,it=f1.getEndTime() + self.assertAlmostEqual(10.98,t,12); + self.assertEqual(7,dt); + self.assertEqual(6,it); + # + f1=MEDCouplingFieldDouble.New(ON_CELLS,LINEAR_TIME); + f1.setName("f1"); + f1.setTimeTolerance(1.e-5); + f1.setDescription("f1Desc"); + f1.setTime(1.23,4,5); + f1.setEndTime(5.43,2,1); + f2=MEDCouplingFieldDouble.New(ON_CELLS,LINEAR_TIME); + f2.setName("f2"); + f2.setDescription("f2Desc"); + f2.setTimeTolerance(4.556e-12); + f2.setTime(6.78,9,10); + f2.setEndTime(10.98,7,6); + # + f1.copyTinyAttrFrom(f2); + self.assertAlmostEqual(4.556e-12,f1.getTimeTolerance(),24); + self.assertTrue(f1.getName()=="f1");#name unchanged + self.assertTrue(f1.getDescription()=="f1Desc");#description unchanged + t,dt,it=f1.getTime() + self.assertAlmostEqual(6.78,t,12); + self.assertEqual(9,dt); + self.assertEqual(10,it); + t,dt,it=f1.getEndTime() + self.assertAlmostEqual(10.98,t,12); + self.assertEqual(7,dt); + self.assertEqual(6,it); + pass + + def testExtrudedMesh5(self): + coo1=[0.,1.,2.,3.5] + a=DataArrayDouble.New(); + a.setValues(coo1,4,1); + b=MEDCouplingCMesh.New(); + b.setCoordsAt(0,a); + c=b.buildUnstructured(); + self.assertEqual(1,c.getSpaceDimension()); + c.changeSpaceDimension(2); + # + d=DataArrayDouble.New(); + d.alloc(13,1); + d.iota(); + e=MEDCouplingCMesh.New(); + e.setCoordsAt(0,d); + f=e.buildUnstructured(); + g=f.getCoords().applyFunc(2,"3.5*IVec+x/6*3.14159265359*JVec"); + self.assertRaises(InterpKernelException,f.getCoords().applyFunc,2,"3.5*IVec+x/6*3.14159265359*KVec"); # KVec refers to component #2 and there is only 2 components ! + h=g.fromPolarToCart(); + f.setCoords(h); + i=c.buildExtrudedMesh(f,1); + self.assertEqual(52,i.getNumberOfNodes()); + tmp,tmp2,tmp3=i.mergeNodes(1e-9); + self.assertTrue(tmp2); + self.assertEqual(37,tmp3); + i.convertDegeneratedCells(); + i.checkCoherency(); + self.assertEqual(36,i.getNumberOfCells()); + self.assertEqual(37,i.getNumberOfNodes()); + self.assertEqual(12,i.getNumberOfCellsWithType(NORM_TRI3)); + self.assertEqual(24,i.getNumberOfCellsWithType(NORM_QUAD4)); + expected1=[0.25,0.75,2.0625] + j=i.getMeasureField(True); + for ii in xrange(12): + for k in xrange(3): + self.assertAlmostEqual(expected1[k],j.getIJ(0,ii*3+k),10); + pass + pass + expected2=[0.62200846792814113, 0.16666666666681595, 1.4513530918323276, 0.38888888888923495, 2.6293994326053212, 0.7045454545460802, 0.45534180126145435, 0.45534180126150181, 1.0624642029433926, 1.0624642029435025, 1.9248539780597826, 1.9248539780599816, 0.16666666666661334, 0.62200846792815856, 0.38888888888876294, 1.4513530918323678, 0.70454545454522521, 2.629399432605394, -0.16666666666674007, 0.62200846792812436, -0.38888888888906142, 1.4513530918322881, -0.70454545454576778, 2.6293994326052488, -0.45534180126154766, 0.45534180126140844, -1.0624642029436118, 1.0624642029432834, -1.9248539780601803, 1.9248539780595841, -0.62200846792817499, 0.1666666666665495, -1.451353091832408, 0.388888888888613, -2.6293994326054668, 0.70454545454495332, -0.62200846792810593, -0.16666666666680507, -1.451353091832247, -0.38888888888921297, -2.6293994326051746, -0.70454545454604123, -0.45534180126135926, -0.45534180126159562, -1.0624642029431723, -1.0624642029437235, -1.9248539780593836, -1.9248539780603811, -0.1666666666664828, -0.62200846792819242, -0.38888888888846079, -1.4513530918324489, -0.70454545454467987, -2.6293994326055397, 0.16666666666687083, -0.62200846792808862, 0.38888888888936374, -1.4513530918322073, 0.70454545454631357, -2.6293994326051022, 0.45534180126164348, -0.45534180126131207, 1.0624642029438327, -1.0624642029430627, 1.9248539780605791, -1.9248539780591853, 0.62200846792821063, -0.16666666666641802, 1.4513530918324888, -0.38888888888831086, 2.6293994326056125, -0.70454545454440853] + m=i.getBarycenterAndOwner(); + for i in xrange(72): + self.assertAlmostEqual(expected2[i],m.getIJ(0,i),10); + pass + # + pass + + def testExtrudedMesh6(self): + coo1=[0.,1.,2.,3.5] + a=DataArrayDouble.New(); + a.setValues(coo1,4,1); + b=MEDCouplingCMesh.New(); + b.setCoordsAt(0,a); + c=b.buildUnstructured(); + self.assertEqual(1,c.getSpaceDimension()); + c.changeSpaceDimension(2); + # + d=DataArrayDouble.New(); + d.alloc(5); + d.iota(); + e=MEDCouplingCMesh.New(); + e.setCoordsAt(0,d); + f=e.buildUnstructured(); + d2=f.getCoords().applyFunc("x*x/2"); + f.setCoords(d2); + f.changeSpaceDimension(2); + # + center=[0.,0.] + f.rotate(center,None,pi/3); + g=c.buildExtrudedMesh(f,0); + g.checkCoherency(); + expected1=[ 0.4330127018922193, 0.4330127018922193, 0.649519052838329, 1.2990381056766578, 1.299038105676658, 1.948557158514987, 2.1650635094610955, 2.1650635094610964, 3.2475952641916446, 3.031088913245533, 3.0310889132455352, 4.546633369868303 ] + f1=g.getMeasureField(True); + for i in xrange(12): + self.assertAlmostEqual(expected1[i],f1.getIJ(0,i),12); + pass + expected2=[0.625, 0.21650635094610962, 1.625, 0.21650635094610959, 2.8750000000000004, 0.21650635094610965, 1.1250000000000002, 1.0825317547305482, 2.125, 1.0825317547305482, 3.3750000000000004, 1.0825317547305484, 2.125, 2.8145825622994254, 3.125, 2.8145825622994254, 4.375, 2.8145825622994254, 3.6250000000000009, 5.4126587736527414, 4.625, 5.4126587736527414, 5.875, 5.4126587736527414] + f2=g.getBarycenterAndOwner(); + for i in xrange(24): + self.assertAlmostEqual(expected2[i],f2.getIJ(0,i),12); + pass + pass + + def testExtrudedMesh7(self): + coo1=[0.,1.,2.,3.5] + a=DataArrayDouble.New(); + a.setValues(coo1,4,1); + b=MEDCouplingCMesh.New(); + b.setCoordsAt(0,a); + c=b.buildUnstructured(); + self.assertEqual(1,c.getSpaceDimension()); + c.changeSpaceDimension(2); + # + d=DataArrayDouble.New(); + d.alloc(13,1); + d.iota(); + e=MEDCouplingCMesh.New(); + e.setCoordsAt(0,d); + f=e.buildUnstructured(); + g=f.getCoords().applyFunc(2,"3.5*IVec+x/6*3.14159265359*JVec"); + h=g.fromPolarToCart(); + f.setCoords(h); + i=c.buildExtrudedMesh(f,1); + self.assertEqual(52,i.getNumberOfNodes()); + tmp,tmp2,tmp3=i.mergeNodes(1e-9); + self.assertTrue(tmp2); + self.assertEqual(37,tmp3); + i.convertDegeneratedCells(); + vec1=[10.,0] + i.translate(vec1); + g2=h.applyFunc(3,"13.5/3.5*x*IVec+0*JVec+13.5/3.5*y*KVec"); + f.setCoords(g2); + i.changeSpaceDimension(3); + i3=i.buildExtrudedMesh(f,1); + f2=i3.getMeasureField(True); + tmp,tmp2,tmp3=i.mergeNodes(1e-9); + self.assertTrue(tmp2); + self.assertEqual(444,tmp3); + expected1=[1.327751058489274, 4.2942574094314701, 13.024068164857139, 1.3069177251569044, 4.1484240761012954, 12.297505664866796, 1.270833333332571, 3.8958333333309674, 11.039062499993179, 1.2291666666659207, 3.6041666666644425, 9.585937499993932, 1.1930822748415895, 3.3515759238941376, 8.3274943351204556, 1.1722489415082769, 3.2057425905609289, 7.6009318351210622, 1.1722489415082862, 3.2057425905609884, 7.6009318351213713, 1.1930822748416161, 3.3515759238943001, 8.3274943351212727, 1.2291666666659564, 3.6041666666646734, 9.5859374999950777, 1.2708333333326081, 3.8958333333311868, 11.039062499994293, 1.3069177251569224, 4.1484240761014384, 12.297505664867627, 1.3277510584902354, 4.2942574094346071, 13.024068164866796] + for ii in xrange(12): + for jj in xrange(36): + self.assertAlmostEqual(expected1[jj],f2.getIJ(0,ii*36+jj),9); + pass + # + pass + + def testSimplexize1(self): + m=MEDCouplingDataForTest.build3DSurfTargetMesh_1(); + m.convertToPolyTypes([3]); + da=m.simplexize(0); + self.assertEqual(7,da.getNumberOfTuples()); + self.assertEqual(1,da.getNumberOfComponents()); + expected2=[0,0,1,2,3,4,4] + for i in xrange(7): + self.assertEqual(expected2[i],da.getIJ(i,0)); + pass + m.checkCoherency(); + self.assertEqual(7,m.getNumberOfCells()); + self.assertEqual(NORM_TRI3,m.getTypeOfCell(0)); + self.assertEqual(NORM_TRI3,m.getTypeOfCell(1)); + self.assertEqual(NORM_TRI3,m.getTypeOfCell(2)); + self.assertEqual(NORM_TRI3,m.getTypeOfCell(3)); + self.assertEqual(NORM_POLYGON,m.getTypeOfCell(4)); + self.assertEqual(NORM_TRI3,m.getTypeOfCell(5)); + self.assertEqual(NORM_TRI3,m.getTypeOfCell(6)); + expected1=[0.125,0.125,0.125,0.125,0.25,0.125,0.125] + f=m.getMeasureField(False); + for i in xrange(7): + self.assertAlmostEqual(expected1[i]*sqrt(2.),f.getIJ(i,0),10); + pass + types=m.getAllGeoTypes(); + self.assertEqual([NORM_TRI3,NORM_POLYGON],types); + # + m=MEDCouplingDataForTest.build3DSurfTargetMesh_1(); + m.convertToPolyTypes([3]); + da=m.simplexize(1); + self.assertEqual(7,da.getNumberOfTuples()); + self.assertEqual(1,da.getNumberOfComponents()); + for i in xrange(7): + self.assertEqual(expected2[i],da.getIJ(i,0)); + pass + m.checkCoherency(); + types=m.getAllGeoTypes(); + self.assertEqual([NORM_TRI3,NORM_POLYGON],types); + self.assertEqual(7,m.getNumberOfCells()); + self.assertEqual(NORM_TRI3,m.getTypeOfCell(0)); + self.assertEqual(NORM_TRI3,m.getTypeOfCell(1)); + self.assertEqual(NORM_TRI3,m.getTypeOfCell(2)); + self.assertEqual(NORM_TRI3,m.getTypeOfCell(3)); + self.assertEqual(NORM_POLYGON,m.getTypeOfCell(4)); + self.assertEqual(NORM_TRI3,m.getTypeOfCell(5)); + self.assertEqual(NORM_TRI3,m.getTypeOfCell(6)); + f=m.getMeasureField(False); + for i in xrange(7): + self.assertAlmostEqual(expected1[i]*sqrt(2.),f.getIJ(i,0),10); + pass + pass + + def testSimplexize2(self): + m=MEDCouplingDataForTest.build3DSurfTargetMesh_1(); + m.convertToPolyTypes([3]); + f1=MEDCouplingFieldDouble.New(ON_CELLS,ONE_TIME); + f1.setMesh(m); + arr=DataArrayDouble.New(); + arr1=[10.,110.,20.,120.,30.,130.,40.,140.,50.,150.] + arr.setValues(arr1,5,2); + f1.setArray(arr); + # + f1.checkCoherency(); + self.assertTrue(f1.simplexize(0)); + f1.checkCoherency(); + expected1=[10.,110.,10.,110.,20.,120.,30.,130.,40.,140.,50.,150.,50.,150.] + for i in xrange(14): + self.assertAlmostEqual(expected1[i],f1.getIJ(0,i),10); + pass + self.assertTrue(not f1.simplexize(0)); + for i in xrange(14): + self.assertAlmostEqual(expected1[i],f1.getIJ(0,i),10); + pass + # + pass + + def testDAMeld1(self): + da1=DataArrayDouble.New(); + da1.alloc(7,2); + da2=DataArrayDouble.New(); + da2.alloc(7,1); + # + da1.fillWithValue(7.); + da2.iota(0.); + da3=da2.applyFunc(3,"10*x*IVec+100*x*JVec+1000*x*KVec"); + # + da1.setInfoOnComponent(0,"c0da1"); + da1.setInfoOnComponent(1,"c1da1"); + da3.setInfoOnComponent(0,"c0da3"); + da3.setInfoOnComponent(1,"c1da3"); + da3.setInfoOnComponent(2,"c2da3"); + # + da1C=da1.deepCpy(); + da1.meldWith(da3); + self.assertEqual(5,da1.getNumberOfComponents()); + self.assertEqual(7,da1.getNumberOfTuples()); + self.assertTrue(da1.getInfoOnComponent(0)=="c0da1"); + self.assertTrue(da1.getInfoOnComponent(1)=="c1da1"); + self.assertTrue(da1.getInfoOnComponent(2)=="c0da3"); + self.assertTrue(da1.getInfoOnComponent(3)=="c1da3"); + self.assertTrue(da1.getInfoOnComponent(4)=="c2da3"); + # + expected1=[7.,7.,0.,0.,0., 7.,7.,10.,100.,1000., 7.,7.,20.,200.,2000., 7.,7.,30.,300.,3000., 7.,7.,40.,400.,4000.,7.,7.,50.,500.,5000.,7.,7.,60.,600.,6000.] + for i in xrange(35): + self.assertAlmostEqual(expected1[i],da1.getIJ(0,i),10); + pass + # + dai1=da1C.convertToIntArr(); + dai3=da3.convertToIntArr(); + dai1.meldWith(dai3); + self.assertEqual(5,dai1.getNumberOfComponents()); + self.assertEqual(7,dai1.getNumberOfTuples()); + self.assertTrue(dai1.getInfoOnComponent(0)=="c0da1"); + self.assertTrue(dai1.getInfoOnComponent(1)=="c1da1"); + self.assertTrue(dai1.getInfoOnComponent(2)=="c0da3"); + self.assertTrue(dai1.getInfoOnComponent(3)=="c1da3"); + self.assertTrue(dai1.getInfoOnComponent(4)=="c2da3"); + for i in xrange(35): + self.assertEqual(int(expected1[i]),dai1.getIJ(0,i)); + pass + # test of static method DataArrayDouble::meld + da4=DataArrayDouble.Meld(da1C,da3); + tmp=DataArrayDouble.Meld([da1C,da3]); + self.assertTrue(da4.isEqual(tmp,1e-10)) + self.assertEqual(5,da4.getNumberOfComponents()); + self.assertEqual(7,da4.getNumberOfTuples()); + self.assertTrue(da4.getInfoOnComponent(0)=="c0da1"); + self.assertTrue(da4.getInfoOnComponent(1)=="c1da1"); + self.assertTrue(da4.getInfoOnComponent(2)=="c0da3"); + self.assertTrue(da4.getInfoOnComponent(3)=="c1da3"); + self.assertTrue(da4.getInfoOnComponent(4)=="c2da3"); + for i in xrange(35): + self.assertAlmostEqual(expected1[i],da4.getIJ(0,i),10); + pass + # test of static method DataArrayInt::meld + dai1=da1C.convertToIntArr(); + dai4=DataArrayInt.Meld(dai1,dai3); + tmp=DataArrayInt.Meld([dai1,dai3]); + self.assertTrue(dai4.isEqual(tmp)) + self.assertEqual(5,dai4.getNumberOfComponents()); + self.assertEqual(7,dai4.getNumberOfTuples()); + self.assertTrue(dai4.getInfoOnComponent(0)=="c0da1"); + self.assertTrue(dai4.getInfoOnComponent(1)=="c1da1"); + self.assertTrue(dai4.getInfoOnComponent(2)=="c0da3"); + self.assertTrue(dai4.getInfoOnComponent(3)=="c1da3"); + self.assertTrue(dai4.getInfoOnComponent(4)=="c2da3"); + for i in xrange(35): + self.assertEqual(int(expected1[i]),dai4.getIJ(0,i)); + pass + pass + + def testFieldMeld1(self): + m=MEDCouplingDataForTest.build3DSurfTargetMesh_1(); + f1=MEDCouplingFieldDouble.New(ON_CELLS,ONE_TIME); + f1.setMesh(m); + da1=DataArrayDouble.New(); + arr1=[12.,23.,34.,45.,56.] + da1.setValues(arr1,5,1); + da1.setInfoOnComponent(0,"aaa"); + f1.setArray(da1); + f1.setTime(3.4,2,1); + f1.checkCoherency(); + # + f2=f1.deepCpy(); + f2.setMesh(f1.getMesh()); + f2.checkCoherency(); + f2.changeNbOfComponents(2,5.); + f2.assign(5.); + f2.getArray().setInfoOnComponent(0,"bbb"); + f2.getArray().setInfoOnComponent(1,"ccc"); + f2.checkCoherency(); + # + f3=MEDCouplingFieldDouble.MeldFields(f2,f1); + f3.checkCoherency(); + self.assertEqual(5,f3.getNumberOfTuples()); + self.assertEqual(3,f3.getNumberOfComponents()); + self.assertTrue(f3.getArray().getInfoOnComponent(0)=="bbb"); + self.assertTrue(f3.getArray().getInfoOnComponent(1)=="ccc"); + self.assertTrue(f3.getArray().getInfoOnComponent(2)=="aaa"); + expected1=[5.,5.,12.,5.,5.,23.,5.,5.,34.,5.,5.,45.,5.,5.,56.] + for i in xrange(15): + self.assertAlmostEqual(expected1[i],f3.getIJ(0,i),12); + pass + time,dt,it=f3.getTime(); + self.assertAlmostEqual(3.4,time,14); + self.assertEqual(2,dt); + self.assertEqual(1,it); + # + f4=f2.buildNewTimeReprFromThis(NO_TIME,False); + f5=f1.buildNewTimeReprFromThis(NO_TIME,False); + f6=MEDCouplingFieldDouble.MeldFields(f4,f5); + f6.checkCoherency(); + self.assertEqual(5,f6.getNumberOfTuples()); + self.assertEqual(3,f6.getNumberOfComponents()); + self.assertTrue(f6.getArray().getInfoOnComponent(0)=="bbb"); + self.assertTrue(f6.getArray().getInfoOnComponent(1)=="ccc"); + self.assertTrue(f6.getArray().getInfoOnComponent(2)=="aaa"); + for i in xrange(15): + self.assertAlmostEqual(expected1[i],f6.getIJ(0,i),12); + pass + # + pass + + def testMergeNodes2(self): + m1=MEDCouplingDataForTest.build2DTargetMesh_1(); + m2=MEDCouplingDataForTest.build2DTargetMesh_1(); + vec=[0.002,0.] + m2.translate(vec); + # + m3=MEDCouplingUMesh.MergeUMeshes([m1,m2]); + da,b,newNbOfNodes=m3.mergeNodes2(0.01); + self.assertEqual(9,m3.getNumberOfNodes()); + expected1=[-0.299,-0.3, 0.201,-0.3, 0.701,-0.3, -0.299,0.2, 0.201,0.2, 0.701,0.2, -0.299,0.7, 0.201,0.7, 0.701,0.7] + for i in xrange(18): + self.assertAlmostEqual(expected1[i],m3.getCoords().getIJ(0,i),13); + pass + # + pass + + def testMergeField2(self): + m=MEDCouplingDataForTest.build2DTargetMesh_1(); + f1=MEDCouplingFieldDouble.New(ON_CELLS,ONE_TIME); + f1.setMesh(m); + arr=DataArrayDouble.New(); + arr.alloc(5,2); + arr.fillWithValue(2.); + f1.setArray(arr); + f2=MEDCouplingFieldDouble.New(ON_CELLS,ONE_TIME); + f2.setMesh(m); + arr=DataArrayDouble.New(); + arr.alloc(5,2); + arr.fillWithValue(5.); + f2.setArray(arr); + f3=MEDCouplingFieldDouble.New(ON_CELLS,ONE_TIME); + f3.setMesh(m); + arr=DataArrayDouble.New(); + arr.alloc(5,2); + arr.fillWithValue(7.); + f3.setArray(arr); + # + f4=MEDCouplingFieldDouble.MergeFields([f1,f2,f3]); + self.assertEqual(15,f4.getMesh().getNumberOfCells()); + expected1=[2.,2.,2.,2.,2.,2.,2.,2.,2.,2., 5.,5.,5.,5.,5.,5.,5.,5.,5.,5., 7.,7.,7.,7.,7.,7.,7.,7.,7.,7.] + for i in xrange(30): + self.assertAlmostEqual(expected1[i],f4.getIJ(0,i),13); + pass + # + pass + + def testDAIBuildComplement1(self): + a=DataArrayInt.New(); + tab=[3,1,7,8] + a.setValues(tab,4,1); + b=a.buildComplement(12); + self.assertEqual(8,b.getNumberOfTuples()); + self.assertEqual(1,b.getNumberOfComponents()); + expected1=[0,2,4,5,6,9,10,11] + for i in xrange(8): + self.assertEqual(expected1[i],b.getIJ(0,i)); + pass + pass + + def testDAIBuildUnion1(self): + a=DataArrayInt.New(); + tab1=[3,1,7,8] + a.setValues(tab1,4,1); + c=DataArrayInt.New(); + tab2=[5,3,0,18,8] + c.setValues(tab2,5,1); + b=a.buildUnion(c); + self.assertEqual(7,b.getNumberOfTuples()); + self.assertEqual(1,b.getNumberOfComponents()); + expected1=[0,1,3,5,7,8,18] + for i in xrange(7): + self.assertEqual(expected1[i],b.getIJ(0,i)); + pass + b=DataArrayInt.BuildUnion([a,c]); + self.assertEqual(7,b.getNumberOfTuples()); + self.assertEqual(1,b.getNumberOfComponents()); + expected1=[0,1,3,5,7,8,18] + for i in xrange(7): + self.assertEqual(expected1[i],b.getIJ(0,i)); + pass + pass + + def testDAIBuildIntersection1(self): + a=DataArrayInt.New(); + tab1=[3,1,7,8] + a.setValues(tab1,4,1); + c=DataArrayInt.New(); + tab2=[5,3,0,18,8] + c.setValues(tab2,5,1); + b=a.buildIntersection(c); + self.assertEqual(2,b.getNumberOfTuples()); + self.assertEqual(1,b.getNumberOfComponents()); + expected1=[3,8] + for i in xrange(2): + self.assertEqual(expected1[i],b.getIJ(0,i)); + pass + b=DataArrayInt.BuildIntersection([a,c]); + self.assertEqual(2,b.getNumberOfTuples()); + self.assertEqual(1,b.getNumberOfComponents()); + expected1=[3,8] + for i in xrange(2): + self.assertEqual(expected1[i],b.getIJ(0,i)); + pass + pass + + def testDAIDeltaShiftIndex1(self): + a=DataArrayInt.New(); + tab=[1,3,6,7,7,9,15] + a.setValues(tab,7,1); + b=a.deltaShiftIndex(); + self.assertEqual(6,b.getNumberOfTuples()); + self.assertEqual(1,b.getNumberOfComponents()); + expected1=[2,3,1,0,2,6] + for i in xrange(6): + self.assertEqual(expected1[i],b.getIJ(0,i)); + pass + pass + + def testDaDoubleSelectByTupleIdSafe1(self): + a=DataArrayDouble.New(); + arr1=[1.1,11.1,2.1,12.1,3.1,13.1,4.1,14.1,5.1,15.1,6.1,16.1,7.1,17.1] + a.setValues(arr1,7,2); + a.setInfoOnComponent(0,"toto"); + a.setInfoOnComponent(1,"tata"); + # + arr2=[4,2,0,6,5] + b=a.selectByTupleIdSafe(arr2); + self.assertEqual(5,b.getNumberOfTuples()); + self.assertEqual(2,b.getNumberOfComponents()); + self.assertTrue(b.getInfoOnComponent(0)=="toto"); + self.assertTrue(b.getInfoOnComponent(1)=="tata"); + expected1=[5.1,15.1,3.1,13.1,1.1,11.1,7.1,17.1,6.1,16.1] + for i in xrange(10): + self.assertAlmostEqual(expected1[i],b.getIJ(0,i),14); + pass + arr4=[4,-1,0,6,5] + self.assertRaises(InterpKernelException,a.selectByTupleIdSafe,arr4); + arr5=[4,2,0,6,7] + self.assertRaises(InterpKernelException,a.selectByTupleIdSafe,arr5); + # + c=DataArrayInt.New(); + arr3=[1,11,2,12,3,13,4,14,5,15,6,16,7,17] + c.setValues(arr3,7,2); + c.setInfoOnComponent(0,"toto"); + c.setInfoOnComponent(1,"tata"); + d=c.selectByTupleIdSafe(arr2); + self.assertEqual(5,d.getNumberOfTuples()); + self.assertEqual(2,d.getNumberOfComponents()); + self.assertTrue(d.getInfoOnComponent(0)=="toto"); + self.assertTrue(d.getInfoOnComponent(1)=="tata"); + expected2=[5,15,3,13,1,11,7,17,6,16] + for i in xrange(10): + self.assertEqual(expected2[i],d.getIJ(0,i)); + pass + self.assertRaises(InterpKernelException,c.selectByTupleIdSafe,arr4); + self.assertRaises(InterpKernelException,c.selectByTupleIdSafe,arr5); + pass + + def testAreCellsIncludedIn1(self): + m=MEDCouplingDataForTest.build3DSurfTargetMesh_1(); + pt=[1,3] + m2=m.buildPartOfMySelf(pt,True); + ret,tmp=m.areCellsIncludedIn(m2,0) + self.assertTrue(ret); + self.assertEqual(2,tmp.getNumberOfTuples()); + self.assertEqual(1,tmp.getNumberOfComponents()); + self.assertEqual(pt[0],tmp.getIJ(0,0)); + self.assertEqual(pt[1],tmp.getIJ(0,1)); + ret,tmp=m2.areCellsIncludedIn(m,0) + self.assertTrue(not ret); + m3=MEDCouplingUMesh.MergeUMeshesOnSameCoords(m,m2) + c,cI=m3.findCommonCells(2,m.getNumberOfCells()) + self.assertTrue(c.isEqual(DataArrayInt([1,5,3,6]))) + self.assertTrue(cI.isEqual(DataArrayInt([0,2,4]))) + pass + + def testSwigErrorProtection1(self): + m=MEDCouplingDataForTest.build3DTargetMesh_1(); + m.rotate([0.,0.,0.],[0.3,0.6,1.2],0.37) + m.rotate([0.,0.,0.],[0.3,6,1.2],0.37) + self.assertRaises(InterpKernelException,m.rotate,[0.,0.,0.],(0.3,6,"1.2"),0.37) + self.assertRaises(InterpKernelException,m.rotate,[0.,"0.",0.],[0.3,0.6,1.2],0.37) + self.assertRaises(InterpKernelException,m.rotate,[0.,0.,0.],[0.3,'0.6',1.2],0.37) + m2=m.buildPartOfMySelf([2,5],True) + m3=m.buildPartOfMySelf((2,5),True) + self.assertTrue(m2.isEqual(m3,1e-12)) + self.assertRaises(InterpKernelException,m.buildPartOfMySelf,[2,5.],True) + da1=m.getCoords().keepSelectedComponents([1]) + da2=m.getCoords().keepSelectedComponents((1,)) + self.assertTrue(da1.isEqual(da2,1e-12)) + self.assertRaises(InterpKernelException,m.getCoords().keepSelectedComponents,["1"]) + pass + + def testDAIBuildSubstraction1(self): + a=DataArrayInt.New() + aa=[2,3,6,8,9] + a.setValues(aa,5,1) + b=DataArrayInt.New() + bb=[1,3,5,9,11] + b.setValues(bb,5,1) + self.assertEqual([2,6,8],a.buildSubstraction(b).getValues()) + pass + + def testBuildOrthogonalField2(self): + m=MEDCouplingDataForTest.build2DTargetMesh_1(); + d1=DataArrayInt.New(); + d2=DataArrayInt.New(); + d3=DataArrayInt.New(); + d4=DataArrayInt.New(); + m1=m.buildDescendingConnectivity(d1,d2,d3,d4); + # + f1=m1.buildOrthogonalField(); + da1=f1.getArray(); + self.assertEqual(2,da1.getNumberOfComponents()); + self.assertEqual(13,da1.getNumberOfTuples()); + # + expected1=[-1.,0.,0.,1.,1.,0.,0.,-1.,0.707106781186548,0.707106781186548,0.,-1.,0.,1.,1.,0.,0.,1.,1.,0.,-1.,0.,0.,1.,1.,0.]; + for i in xrange(26): + self.assertAlmostEqual(expected1[i],da1.getIJ(0,i),14); + pass + pass + + def testSwigErrorProtection2(self): + m=MEDCouplingDataForTest.build2DTargetMesh_1(); + coo=m.getCoords() + c=m.getNodalConnectivity() + ci=m.getNodalConnectivityIndex() + del m + self.assertEqual(2,coo.getNumberOfComponents()); + self.assertEqual(6,ci.getNumberOfTuples()); + self.assertEqual(23,c.getNumberOfTuples()); + m=MEDCouplingDataForTest.build2DTargetMesh_1(); + f=m.getMeasureField(True) + c=f.getArray() + del f + self.assertEqual(1,c.getNumberOfComponents()); + m=MEDCouplingCMesh.New() + x=DataArrayDouble.New() + x.setValues([1.,2.,4.],3,1) + m.setCoordsAt(0,x) + del x + xx=m.getCoordsAt(0) + del m + self.assertEqual(3,xx.getNumberOfTuples()); + # + m=MEDCouplingDataForTest.build2DTargetMesh_1(); + f=m.getMeasureField(True) + m2=f.getMesh() + del m + del f + self.assertEqual(5,m2.getNumberOfCells()); + pass + + def testUMInsertNextCell1(self): + targetCoords=[-0.3,-0.3, 0.2,-0.3, 0.7,-0.3, -0.3,0.2, 0.2,0.2, 0.7,0.2, -0.3,0.7, 0.2,0.7, 0.7,0.7 ] + targetConn=[0,3,4,1, 1,4,2, 4,5,2, 6,7,4,3, 7,8,5,4] + targetMesh=MEDCouplingUMesh.New(); + targetMesh.allocateCells(5); + self.assertRaises(InterpKernelException,targetMesh.insertNextCell,NORM_QUAD4,4,targetConn[0:4]) + targetMesh.setMeshDimension(2); + targetMesh.insertNextCell(NORM_QUAD4,4,targetConn[0:4]) + self.assertRaises(InterpKernelException,targetMesh.insertNextCell,NORM_TETRA4,4,targetConn[0:4]) + self.assertRaises(InterpKernelException,targetMesh.insertNextCell,NORM_SEG2,2,targetConn[0:2]) + self.assertRaises(InterpKernelException,targetMesh.insertNextCell,NORM_POINT1,1,targetConn[0:1]) + targetMesh.insertNextCell(NORM_TRI3,3,targetConn[4:7]) + targetMesh.insertNextCell(NORM_TRI3,3,targetConn[7:10]) + targetMesh.insertNextCell(NORM_QUAD4,4,targetConn[10:14]) + targetMesh.insertNextCell(NORM_QUAD4,4,targetConn[14:18]) + targetMesh.finishInsertingCells(); + myCoords=DataArrayDouble.New(); + myCoords.setValues(targetCoords,9,2); + targetMesh.setCoords(myCoords); + targetMesh.checkCoherency(); + pass + + def testFieldOperatorDivDiffComp1(self): + m=MEDCouplingDataForTest.build2DTargetMesh_1(); + m1,d0,d1,d2,d3=m.buildDescendingConnectivity(); + # + f1=m1.buildOrthogonalField(); + arr1=[2.,3.,4.,5.,6.,7.,8.,9.,10.,11.,12.,13.,14.] + arr=DataArrayDouble.New(); + arr.setValues(arr1,13,1); + f2=MEDCouplingFieldDouble.New(ON_CELLS); + f2.setArray(arr); + f2.setMesh(m1); + f2.checkCoherency(); + # + f3=f1/f2; + self.assertRaises(InterpKernelException,f2.__div__,f1) + f3.checkCoherency(); + f1/=f2; + #self.assertRaises(InterpKernelException,f2.__idiv__,f1) # mem leaks + self.assertTrue(f1.isEqual(f3,1e-10,1e-10)); + expected1=[-0.5, 0.0, 0.0, 0.33333333333333331, 0.25, 0.0, 0.0, -0.20000000000000001, 0.117851130197758, 0.117851130197758, 0.0, -0.14285714285714285, 0.0, 0.125, 0.1111111111111111, 0.0, 0.0, 0.10000000000000001, 0.090909090909090912, 0.0, -0.083333333333333329, 0.0, 0.0, 0.076923076923076927, 0.071428571428571425, 0.0] + for i in xrange(26): + self.assertAlmostEqual(expected1[i],f3.getIJ(0,i),10); + pass + pass + + def testDARearrange1(self): + da1=DataArrayInt.New(); + da1.alloc(12,1); + da1.iota(0); + # + self.assertEqual(12,da1.getNbOfElems()); + self.assertEqual(1,da1.getNumberOfComponents()); + self.assertEqual(12,da1.getNumberOfTuples()); + da1.rearrange(4); + self.assertEqual(12,da1.getNbOfElems()); + self.assertEqual(4,da1.getNumberOfComponents()); + self.assertEqual(3,da1.getNumberOfTuples()); + for i in xrange(12): + self.assertEqual(i,da1.getIJ(0,i)); + # + da1.rearrange(6); + self.assertEqual(12,da1.getNbOfElems()); + self.assertEqual(6,da1.getNumberOfComponents()); + self.assertEqual(2,da1.getNumberOfTuples()); + for i in xrange(12): + self.assertEqual(i,da1.getIJ(0,i)); + # + self.assertRaises(InterpKernelException,da1.rearrange,7); + # + da1.rearrange(12); + self.assertEqual(12,da1.getNbOfElems()); + self.assertEqual(12,da1.getNumberOfComponents()); + self.assertEqual(1,da1.getNumberOfTuples()); + for i in xrange(12): + self.assertEqual(i,da1.getIJ(0,i)); + # + da1.rearrange(3); + self.assertEqual(12,da1.getNbOfElems()); + self.assertEqual(3,da1.getNumberOfComponents()); + self.assertEqual(4,da1.getNumberOfTuples()); + for i in xrange(12): + self.assertEqual(i,da1.getIJ(0,i)); + #double + da2=da1.convertToDblArr(); + st=da2.getHiddenCppPointer() + # + self.assertEqual(12,da2.getNbOfElems()); + self.assertEqual(3,da2.getNumberOfComponents()); + self.assertEqual(4,da2.getNumberOfTuples()); + da2.rearrange(4); + self.assertEqual(12,da2.getNbOfElems()); + self.assertEqual(4,da2.getNumberOfComponents()); + self.assertEqual(3,da2.getNumberOfTuples()); + for i in xrange(12): + self.assertAlmostEqual(float(i),da2.getIJ(0,i),14); + # + da2.rearrange(6); + self.assertEqual(12,da2.getNbOfElems()); + self.assertEqual(6,da2.getNumberOfComponents()); + self.assertEqual(2,da2.getNumberOfTuples()); + for i in xrange(12): + self.assertAlmostEqual(float(i),da2.getIJ(0,i),14); + # + self.assertRaises(InterpKernelException,da2.rearrange,7); + # + da2.rearrange(1); + self.assertEqual(st,da2.getHiddenCppPointer()) + self.assertEqual(12,da2.getNbOfElems()); + self.assertEqual(1,da2.getNumberOfComponents()); + self.assertEqual(12,da2.getNumberOfTuples()); + for i in xrange(12): + self.assertAlmostEqual(float(i),da2.getIJ(0,i),14); + # + da2.rearrange(3); + self.assertEqual(12,da2.getNbOfElems()); + self.assertEqual(3,da2.getNumberOfComponents()); + self.assertEqual(4,da2.getNumberOfTuples()); + for i in xrange(12): + self.assertAlmostEqual(float(i),da2.getIJ(0,i),14); + pass + + def testDARearrange2(self): + da1=DataArrayInt.New(); + arr=[1,2,3,2,2,3,5,1,5,5,2,2] + da1.setValues(arr,4,3); + s=da1.getDifferentValues(); + expected1=DataArrayInt([1,2,3,5]) + self.assertTrue(expected1.isEqual(s)); + pass + + def testSwigErrorProtection3(self): + da=DataArrayInt.New() + da.setValues([1,2,3,4,0,0,0,0,0,0,0,0],4,3) + self.assertEqual([1, 2, 3, 4, 0, 0, 0, 0, 0, 0, 0, 0],da.getValues()) + self.assertEqual(3,da.getNumberOfComponents()); + self.assertEqual(4,da.getNumberOfTuples()); + da=DataArrayInt.New() + da.setValues(((1,2,3),(4,4,3),(0,0,0),(0,0,0)),4,3) + self.assertEqual([1, 2, 3, 4, 4, 3, 0, 0, 0, 0, 0, 0],da.getValues()) + self.assertEqual(3,da.getNumberOfComponents()); + self.assertEqual(4,da.getNumberOfTuples()); + da.setValues((10*[1]+290*[2])[:12],4,3) + self.assertEqual(10*[1]+[2,2],da.getValues()) + self.assertEqual(3,da.getNumberOfComponents()); + self.assertEqual(4,da.getNumberOfTuples()); + # + da=DataArrayDouble.New() + da.setValues([1,2,3.,4,0,0,0,0,0,0,0,0],4,3) + self.assertEqual([1., 2., 3., 4., 0., 0., 0., 0., 0., 0., 0., 0.],da.getValues()) + self.assertEqual(3,da.getNumberOfComponents()); + self.assertEqual(4,da.getNumberOfTuples()); + da=DataArrayDouble.New() + da.setValues(((1,2,3),(4.,4,3),(0,0,0),(0,0,0)),4,3) + self.assertEqual([1., 2., 3., 4., 4., 3., 0., 0., 0., 0., 0., 0.],da.getValues()) + self.assertEqual(3,da.getNumberOfComponents()); + self.assertEqual(4,da.getNumberOfTuples()); + da.setValues((10*[1]+290*[2])[:12],4,3) + self.assertEqual(10*[1.]+[2.,2.],da.getValues()) + self.assertEqual(3,da.getNumberOfComponents()); + self.assertEqual(4,da.getNumberOfTuples()); + pass + + def testDAIBuildPermutationArr1(self): + a=DataArrayInt.New() + a.setValues([4,5,6,7,8],5,1) + b=DataArrayInt.New() + b.setValues([5,4,8,6,7],5,1) + c=a.buildPermutationArr(b) + self.assertEqual([1,0,4,2,3],c.getValues()) + self.assertTrue(a.isEqualWithoutConsideringStrAndOrder(b)) + b.setIJ(0,0,9) + self.assertTrue(not a.isEqualWithoutConsideringStrAndOrder(b)) + self.assertRaises(InterpKernelException,a.buildPermutationArr,b) + a.setIJ(3,0,4) + b.setIJ(0,0,5) + b.setIJ(4,0,4)#a==[4,5,6,4,8] and b==[5,4,8,6,4] + self.assertTrue(a.isEqualWithoutConsideringStrAndOrder(b)) + c=a.buildPermutationArr(b) + self.assertEqual([1,3,4,2,3],c.getValues()) + d=b.convertToDblArr() + expect3=[4,4,5,6,8] + b.sort() + self.assertEqual(expect3,b.getValues()) + d.sort() + self.assertEqual(5,d.getNumberOfTuples()); + self.assertEqual(1,d.getNumberOfComponents()); + for i in xrange(5): + self.assertAlmostEqual(float(expect3[i]),d.getIJ(i,0),14); + pass + pass + + def testAreCellsIncludedIn2(self): + myName="Vitoo"; + m=MEDCouplingDataForTest.build3DSurfTargetMesh_1(); + m2=m.buildPartOfMySelf([],True); + self.assertEqual(0,m2.getNumberOfCells()); + self.assertEqual(3,m2.getSpaceDimension()); + self.assertEqual(2,m2.getMeshDimension()); + m2.setName(myName); + test,tmp=m.areCellsIncludedIn(m2,0) + self.assertTrue(test); + self.assertEqual(myName,tmp.getName()); + self.assertEqual(0,tmp.getNumberOfTuples()) + self.assertEqual(1,tmp.getNumberOfComponents()) + pass + + def testUMeshGetPartBarycenterAndOwner1(self): + m1=MEDCouplingDataForTest.build2DTargetMesh_1(); + part1=[1,0,4]; + part=DataArrayInt.New(); + part.setValues(part1,3,1); + b=m1.getPartBarycenterAndOwner(part); + self.assertEqual(2,b.getNumberOfComponents()); + self.assertEqual(3,b.getNumberOfTuples()); + expected1=[0.36666666666666665,-0.13333333333333333,-0.05,-0.05,0.45,0.45]; + for i in xrange(6): + self.assertAlmostEqual(expected1[i],b.getIJ(0,i),14); + pass + pass + + def testUMeshGetPartMeasureField1(self): + m1=MEDCouplingDataForTest.build2DTargetMesh_1(); + part1=[1,0,4]; + part=DataArrayInt.New(); + part.setValues(part1,3,1); + b=m1.getPartMeasureField(True,part); + self.assertEqual(1,b.getNumberOfComponents()); + self.assertEqual(3,b.getNumberOfTuples()); + expected1=[0.125,0.25,0.25]; + for i in xrange(3): + self.assertAlmostEqual(expected1[i],b.getIJ(0,i),14); + pass + pass + + def testUMeshBuildPartOrthogonalField1(self): + m1=MEDCouplingDataForTest.build2DTargetMesh_1(); + m1.changeSpaceDimension(3); + part1=[1,0,4]; + part=DataArrayInt.New(); + part.setValues(part1,3,1); + b=m1.buildPartOrthogonalField(part); + self.assertEqual(3,b.getArray().getNumberOfComponents()); + self.assertEqual(3,b.getArray().getNumberOfTuples()); + expected1=[0.,0.,-1.,0.,0.,-1.,0.,0.,-1.]; + for i in xrange(9): + self.assertAlmostEqual(expected1[i],b.getArray().getIJ(0,i),14); + pass + pass + + def testUMeshGetTypesOfPart1(self): + m1=MEDCouplingDataForTest.build2DTargetMesh_1(); + part1=[0,3,4]; + p1=DataArrayInt.New() + p1.setValues(part1,3,1) + s=m1.getTypesOfPart(p1); + self.assertEqual([NORM_QUAD4],s); + part2=[2,2,2,1]; + p2=DataArrayInt.New() + p2.setValues(part2,4,1) + s=m1.getTypesOfPart(p2); + self.assertEqual([NORM_TRI3],s); + part3=[3,2,1]; + p3=DataArrayInt.New() + p3.setValues(part3,3,1) + s=m1.getTypesOfPart(p3); + self.assertEqual(s,[NORM_TRI3,NORM_QUAD4]); + pass + + def testUMeshKeepCellIdsByType1(self): + m1=MEDCouplingDataForTest.build2DTargetMesh_1(); + part1=[0,3,4] + p1=DataArrayInt.New() + p1.setValues(part1,3,1) + p1.setName("p1") + a=m1.keepCellIdsByType(NORM_TRI3,p1); + self.assertEqual("p1",a.getName()) + self.assertEqual(1,a.getNumberOfComponents()); + self.assertEqual(0,a.getNumberOfTuples()); + # + part2=[3,2,0,2,4] + p2=DataArrayInt.New() + p2.setValues(part2,5,1) + p2.setName("p2") + a=m1.keepCellIdsByType(NORM_TRI3,p2); + self.assertEqual("p2",a.getName()) + self.assertEqual(1,a.getNumberOfComponents()); + self.assertEqual(2,a.getNumberOfTuples()); + self.assertEqual(2,a.getIJ(0,0)); + self.assertEqual(2,a.getIJ(1,0)); + # + a=m1.keepCellIdsByType(NORM_QUAD4,p2); + self.assertEqual("p2",a.getName()) + self.assertEqual(1,a.getNumberOfComponents()); + self.assertEqual(3,a.getNumberOfTuples()); + self.assertEqual(3,a.getIJ(0,0)); + self.assertEqual(0,a.getIJ(1,0)); + self.assertEqual(4,a.getIJ(2,0)); + pass + + def testSwigErrorDaIntSelectByTupleId1(self): + a=DataArrayInt.New(); + arr1=[1,11,2,12,3,13,4,14,5,15,6,16,7,17] + a.setValues(arr1,7,2); + a.setInfoOnComponent(0,"toto"); + a.setInfoOnComponent(1,"tata"); + # + arr2=[4,2,0,6,5] + b=a.selectByTupleId(arr2); + self.assertEqual(5,b.getNumberOfTuples()); + self.assertEqual(2,b.getNumberOfComponents()); + self.assertTrue(b.getInfoOnComponent(0)=="toto"); + self.assertTrue(b.getInfoOnComponent(1)=="tata"); + expected1=[5,15,3,13,1,11,7,17,6,16] + self.assertEqual(expected1,b.getValues()) + # + a2=DataArrayInt.New() + a2.setValues(arr2,5,1) + b=a.selectByTupleId(a2); + self.assertEqual(5,b.getNumberOfTuples()); + self.assertEqual(2,b.getNumberOfComponents()); + self.assertTrue(b.getInfoOnComponent(0)=="toto"); + self.assertTrue(b.getInfoOnComponent(1)=="tata"); + expected1=[5,15,3,13,1,11,7,17,6,16] + self.assertEqual(expected1,b.getValues()) + pass + + def testSwigErrorRenum(self): + da=DataArrayDouble.New() + da.setValues([7.,107.,8.,108.,9.,109.,10.,110.,11.,111.,12.,112.,13.,113.,14.,114.,15.,115.,16.,116.],10,2) + d=DataArrayInt.New() + d.setValues([0,2,3,1,4,5,6,8,7,9],10,1) + da.renumberInPlace(d) + da.renumber(d) + pass + + def testSwigGetItem1(self): + da=DataArrayInt.New() + da.alloc(16,3) + da.rearrange(1) + da.iota(7) + da.rearrange(3) + da.setInfoOnComponent(0,"X [m]") + da.setInfoOnComponent(1,"Y [m]") + da.setInfoOnComponent(2,"Z [km]") + da2=da[5:-1] + self.assertEqual([22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51],da2.getValues()) + da2=da[4] + self.assertEqual([19, 20, 21],da2.getValues()) + try: + da2=da[4:17] + except InterpKernelException as e: + self.assertTrue(True) + else: + self.assertTrue(False) + pass + da2=da[5:-2,2] + self.assertEqual([24, 27, 30, 33, 36, 39, 42, 45, 48],da2.getValues()) + da2=da[5:8,:] + self.assertEqual([22, 23, 24, 25, 26, 27, 28, 29, 30],da2.getValues()) + da2=da[:] + self.assertTrue(da2.isEqual(da)) + da2=da[:,:] + self.assertTrue(da2.isEqual(da)) + try: + da2=da[:,:,:] + except InterpKernelException as e: + self.assertTrue(True) + else: + self.assertTrue(False) + pass + self.assertTrue(da[5:8,-2].isEqualWithoutConsideringStr(DataArrayInt([23,26,29]))) + da2=da[5:8,:-2] + self.assertEqual([22, 25, 28],da2.getValues()) + try: + da2=da[5:-18,2] + except InterpKernelException as e: + self.assertTrue(True) + else: + self.assertTrue(False) + pass + da2=da[5:5,2] + self.assertEqual([],da2.getValues()) + pass + + def testSwigGetItem2(self): + da=DataArrayDouble.New() + da.alloc(16,3) + da.rearrange(1) + da.iota(7) + da.rearrange(3) + da.setInfoOnComponent(0,"X [m]") + da.setInfoOnComponent(1,"Y [m]") + da.setInfoOnComponent(2,"Z [km]") + da2=da[5:-1] + self.assertEqual([22., 23., 24., 25., 26., 27., 28., 29., 30., 31., 32., 33., 34., 35., 36., 37., 38., 39., 40., 41., 42., 43., 44., 45., 46., 47., 48., 49., 50., 51.],da2.getValues()) + da2=da[4] + self.assertEqual([19., 20., 21],da2.getValues()) + try: + da2=da[4:17] + except InterpKernelException as e: + self.assertTrue(True) + else: + self.assertTrue(False) + pass + da2=da[5:-2,2] + self.assertEqual([24., 27., 30., 33., 36., 39., 42., 45., 48.],da2.getValues()) + da2=da[5:8,:] + self.assertEqual([22., 23., 24., 25., 26., 27., 28., 29., 30.],da2.getValues()) + da2=da[:] + self.assertTrue(da2.isEqual(da,1e-12)) + da2=da[:,:] + self.assertTrue(da2.isEqual(da,1e-12)) + try: + da2=da[:,:,:] + except InterpKernelException as e: + self.assertTrue(True) + else: + self.assertTrue(False) + pass + self.assertTrue(da[5:8,-2].isEqualWithoutConsideringStr(DataArrayDouble([23.,26.,29.]),1e-12)) + da2=da[5:8,:-2] + self.assertEqual([22., 25., 28.],da2.getValues()) + try: + da2=da[5:-18,2] + except InterpKernelException as e: + self.assertTrue(True) + else: + self.assertTrue(False) + pass + da2=da[5:5,2] + self.assertEqual([],da2.getValues()) + pass + + def testSwigSetItem1(self): + da=DataArrayInt.New() + da.alloc(20,1) + da.iota(7) + da.rearrange(5) + da.setInfoOnComponent(0,"X [m]") ; da.setInfoOnComponent(1,"Y [km]") ; da.setInfoOnComponent(2,"Y [m]") + da.setInfoOnComponent(3,"Z [W]") ; da.setInfoOnComponent(4,"ZZ [km]") ; + da[:,2]=3 + self.assertEqual([7, 8, 3, 10, 11, 12, 13, 3, 15, 16, 17, 18, 3, 20, 21, 22, 23, 3, 25, 26],da.getValues()) + da.rearrange(1) ; da.iota(7) ; da.rearrange(5) + da[2]=3 + self.assertEqual([7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 3, 3, 3, 3, 3, 22, 23, 24, 25, 26],da.getValues()) + da.rearrange(1) ; da.iota(7) ; da.rearrange(5) + da[[0,3]]=-1 + self.assertEqual([-1, -1, -1, -1, -1, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, -1, -1, -1, -1, -1],da.getValues()) + da.rearrange(1) ; da.iota(7) ; da.rearrange(5) + da[:,[1,3,4]]=-3 + self.assertEqual([7, -3, 9, -3, -3, 12, -3, 14, -3, -3, 17, -3, 19, -3, -3, 22, -3, 24, -3, -3],da.getValues()) + da.rearrange(1) ; da.iota(7) ; da.rearrange(5) + da2=DataArrayInt.New() ; da2.setValues([0,2,3],3,1) + da[da2]=-7 + self.assertEqual([-7, -7, -7, -7, -7, 12, 13, 14, 15, 16, -7, -7, -7, -7, -7, -7, -7, -7, -7, -7],da.getValues()) + da.rearrange(1) ; da.iota(7) ; da.rearrange(5) + da[da2,-2:]=-7 + self.assertEqual([7, 8, 9, -7, -7, 12, 13, 14, 15, 16, 17, 18, 19, -7, -7, 22, 23, 24, -7, -7],da.getValues()) + # Let's test with DAI right hand side + da1=DataArrayInt.New() + da1.setValues([25,26,27,125,126,127],2,3) + # + da.rearrange(1) ; da.iota(7) ; da.rearrange(5) + da[-2:,1:4]=da1 + self.assertEqual([7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 25, 26, 27, 21, 22, 125, 126, 127, 26],da.getValues()) + da.rearrange(1) ; da.iota(7) ; da.rearrange(5) + da[1:,3]=[225,226,227] + self.assertEqual([7, 8, 9, 10, 11, 12, 13, 14, 225, 16, 17, 18, 19, 226, 21, 22, 23, 24, 227, 26],da.getValues()) + da.rearrange(1) ; da.iota(7) ; da.rearrange(5) + da[1,2:]=[225,226,227] + self.assertEqual([7, 8, 9, 10, 11, 12, 13, 225, 226, 227, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26],da.getValues()) + da.rearrange(1) ; da.iota(7) ; da.rearrange(5) + da[da2,-2:]=[88,99,1010,1111,1212,1313] + self.assertEqual([7, 8, 9, 88, 99, 12, 13, 14, 15, 16, 17, 18, 19, 1010, 1111, 22, 23, 24, 1212, 1313],da.getValues()) + da.rearrange(1) ; da.iota(7) ; da.rearrange(5) + da3=DataArrayInt.New(); da3.setValues([88,99,1010,1111,1212,1313],3,2) + da[da2,-2:]=da3 + self.assertEqual([7, 8, 9, 88, 99, 12, 13, 14, 15, 16, 17, 18, 19, 1010, 1111, 22, 23, 24, 1212, 1313],da.getValues()) + da.rearrange(1) ; da.iota(7) ; da.rearrange(5) + da[da2,[0,2]]=da3 + self.assertEqual([88, 8, 99, 10, 11, 12, 13, 14, 15, 16, 1010, 18, 1111, 20, 21, 1212, 23, 1313, 25, 26],da.getValues()) + da.rearrange(1) ; da.iota(7) ; da.rearrange(5) + da[da2,0:3:2]=da3 + self.assertEqual([88, 8, 99, 10, 11, 12, 13, 14, 15, 16, 1010, 18, 1111, 20, 21, 1212, 23, 1313, 25, 26],da.getValues()) + da.rearrange(1) ; da.iota(7) ; da.rearrange(5) + da[da2,0:3:2]=-8 + self.assertEqual([-8, 8, -8, 10, 11, 12, 13, 14, 15, 16, -8, 18, -8, 20, 21, -8, 23, -8, 25, 26],da.getValues()) + pass + + def testSwigSetItem2(self): + da=DataArrayDouble.New() + da.alloc(20,1) + da.iota(7) + da.rearrange(5) + da.setInfoOnComponent(0,"X [m]") ; da.setInfoOnComponent(1,"Y [km]") ; da.setInfoOnComponent(2,"Y [m]") + da.setInfoOnComponent(3,"Z [W]") ; da.setInfoOnComponent(4,"ZZ [km]") ; + da[:,2]=3. + self.assertEqual([7., 8., 3., 10., 11., 12., 13., 3., 15., 16., 17., 18., 3., 20., 21., 22., 23., 3., 25., 26.],da.getValues()) + da.rearrange(1) ; da.iota(7) ; da.rearrange(5) + da[2]=3. + self.assertEqual([7., 8., 9., 10., 11., 12., 13., 14., 15., 16., 3., 3., 3., 3., 3., 22., 23., 24., 25., 26.],da.getValues()) + da.rearrange(1) ; da.iota(7) ; da.rearrange(5) + da[[0,3]]=-1. + self.assertEqual([-1., -1., -1., -1., -1., 12., 13., 14., 15., 16., 17., 18., 19., 20., 21., -1., -1., -1., -1., -1.],da.getValues()) + da.rearrange(1) ; da.iota(7) ; da.rearrange(5) + da[:,[1,3,4]]=-3. + self.assertEqual([7., -3., 9., -3., -3., 12., -3., 14., -3., -3., 17., -3., 19., -3., -3., 22., -3., 24., -3., -3.],da.getValues()) + da.rearrange(1) ; da.iota(7) ; da.rearrange(5) + da2=DataArrayInt.New() ; da2.setValues([0,2,3],3,1) + da[da2]=-7. + self.assertEqual([-7., -7., -7., -7., -7., 12., 13., 14., 15., 16., -7., -7., -7., -7., -7., -7., -7., -7., -7., -7.],da.getValues()) + da.rearrange(1) ; da.iota(7) ; da.rearrange(5) + da[da2,-2:]=-7 + self.assertEqual([7., 8., 9., -7., -7., 12., 13., 14., 15., 16., 17., 18., 19., -7., -7., 22., 23., 24., -7., -7.],da.getValues()) + # Let's test with DAI right hand side + da1=DataArrayDouble.New() + da1.setValues([25,26,27,125,126,127],2,3) + # + da.rearrange(1) ; da.iota(7) ; da.rearrange(5) + da[-2:,1:4]=da1 + self.assertEqual([7., 8., 9., 10., 11., 12., 13., 14., 15., 16., 17., 25., 26., 27., 21., 22., 125., 126., 127., 26.],da.getValues()) + da.rearrange(1) ; da.iota(7) ; da.rearrange(5) + da[1:,3]=[225.,226.,227.] + self.assertEqual([7., 8., 9., 10., 11., 12., 13., 14., 225., 16., 17., 18., 19., 226., 21., 22., 23., 24., 227., 26.],da.getValues()) + da.rearrange(1) ; da.iota(7) ; da.rearrange(5) + da[1,2:]=[225,226,227] + self.assertEqual([7., 8., 9., 10., 11., 12., 13., 225., 226., 227., 17., 18., 19., 20., 21., 22., 23., 24., 25., 26.],da.getValues()) + da.rearrange(1) ; da.iota(7) ; da.rearrange(5) + da[da2,-2:]=[88,99,1010,1111,1212,1313] + self.assertEqual([7., 8., 9., 88., 99., 12., 13., 14., 15., 16., 17., 18., 19., 1010., 1111., 22., 23., 24., 1212., 1313.],da.getValues()) + da.rearrange(1) ; da.iota(7) ; da.rearrange(5) + da3=DataArrayDouble.New(); da3.setValues([88,99,1010,1111,1212,1313],3,2) + da[da2,-2:]=da3 + self.assertEqual([7., 8., 9., 88., 99., 12., 13., 14., 15., 16., 17., 18., 19., 1010., 1111., 22., 23., 24., 1212., 1313.],da.getValues()) + da.rearrange(1) ; da.iota(7) ; da.rearrange(5) + da[da2,[0,2]]=da3 + self.assertEqual([88., 8., 99., 10., 11., 12., 13., 14., 15., 16., 1010., 18., 1111., 20., 21., 1212., 23., 1313., 25., 26.],da.getValues()) + da.rearrange(1) ; da.iota(7) ; da.rearrange(5) + da[da2,0:3:2]=da3 + self.assertEqual([88., 8., 99., 10., 11., 12., 13., 14., 15., 16., 1010., 18., 1111., 20., 21., 1212., 23., 1313., 25., 26.],da.getValues()) + da.rearrange(1) ; da.iota(7) ; da.rearrange(5) + da[da2,0:3:2]=-8. + self.assertEqual([-8., 8., -8., 10., 11., 12., 13., 14., 15., 16., -8., 18., -8., 20., 21., -8., 23., -8., 25., 26.],da.getValues()) + pass + + def testSwigDADOp(self): + da=DataArrayDouble.New() + da.alloc(12,1) + da.iota(7.) + da1=DataArrayDouble.New() + da1.alloc(12,1) + da1.iota(8.) + da2=da+da1 + self.assertEqual([15., 17., 19., 21., 23., 25., 27., 29., 31., 33., 35., 37.],da2.getValues()) + da2=da+3 + da3=3+da + self.assertTrue(da2.isEqual(da3,1e-12)) + da2=da-1. + self.assertEqual([6.0, 7.0, 8.0, 9.0, 10.0, 11.0, 12.0, 13.0, 14.0, 15.0, 16.0, 17.0],da2.getValues()) + da2=1-da + self.assertEqual([-6.0, -7.0, -8.0, -9.0, -10.0, -11.0, -12.0, -13.0, -14.0, -15.0, -16.0, -17.0],da2.getValues()) + da2=da*3 + self.assertEqual([21.0, 24.0, 27.0, 30.0, 33.0, 36.0, 39.0, 42.0, 45.0, 48.0, 51.0, 54.0],da2.getValues()) + da2=3.*da + self.assertEqual([21.0, 24.0, 27.0, 30.0, 33.0, 36.0, 39.0, 42.0, 45.0, 48.0, 51.0, 54.0],da2.getValues()) + da2=da*da1 + self.assertEqual([56.0, 72.0, 90.0, 110.0, 132.0, 156.0, 182.0, 210.0, 240.0, 272.0, 306.0, 342.0],da2.getValues()) + da2=da/4. + self.assertEqual([1.75, 2.0, 2.25, 2.5, 2.75, 3.0, 3.25, 3.5, 3.75, 4.0, 4.25, 4.5],da2.getValues()) + da3=4./da + da4=da3*da2 + self.assertTrue(da4.isUniform(1.,1e-12)) + st1=da.getHiddenCppPointer() + da+=1 + st2=da.getHiddenCppPointer() + self.assertEqual(st1,st2) + self.assertTrue(da.isEqual(da1,1e-12)) + da-=8 + st2=da.getHiddenCppPointer() + self.assertEqual(st1,st2) + self.assertEqual(range(12),da.getValues()) + da+=da1 + st2=da.getHiddenCppPointer() + self.assertEqual(st1,st2) + self.assertEqual([8.0, 10.0, 12.0, 14.0, 16.0, 18.0, 20.0, 22.0, 24.0, 26.0, 28.0, 30.0],da.getValues()) + da*=0.5 + st2=da.getHiddenCppPointer() + self.assertEqual(st1,st2) + self.assertEqual([4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0, 11.0, 12.0, 13.0, 14.0, 15.0],da.getValues()) + da*=da1 + st2=da.getHiddenCppPointer() + self.assertEqual(st1,st2) + self.assertEqual([32.0, 45.0, 60.0, 77.0, 96.0, 117.0, 140.0, 165.0, 192.0, 221.0, 252.0, 285.0],da.getValues()) + da/=da1 + self.assertEqual(st1,st2) + self.assertEqual([4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0, 11.0, 12.0, 13.0, 14.0, 15.0],da.getValues()) + da/=2 + st2=da.getHiddenCppPointer() + self.assertEqual(st1,st2) + self.assertEqual([2.0, 2.5, 3.0, 3.5, 4.0, 4.5, 5.0, 5.5, 6.0, 6.5, 7.0, 7.5],da.getValues()) + da.rearrange(3) + da5=DataArrayDouble.New() + da5.setValues([5.,4.,3.,2.],4,1) + da*=da5 # it works with unmathing number of compo + st2=da.getHiddenCppPointer() + self.assertEqual(st1,st2) + self.assertEqual([10.0, 12.5, 15.0, 14.0, 16.0, 18.0, 15.0, 16.5, 18.0, 13.0, 14.0, 15.0],da.getValues()) + # + da.alloc(30,1) + da.iota(7.) + da.rearrange(3) + ids=DataArrayInt.New() + ids.setValues([3,4,7],3,1) + da[ids,:]=[5.,8.,9.] + self.assertEqual([7.,8.,9.,10.,11.,12.,13.,14.,15.,5.,8.,9.,5.,8.,9.,22.,23.,24.,25.,26.,27.,5.,8.,9.,31.,32.,33.,34.,35.,36.0],da.getValues()) + # + da.rearrange(1) ; da.iota(7) ; da.rearrange(3) + da[ids,[1,2]]=[5,8] + self.assertEqual([7.,8.,9.,10.,11.,12.,13.,14.,15.,16.,5.,8.,19.,5.,8.,22.,23.,24.,25.,26.,27.,28.,5.,8.,31.,32.,33.,34.,35.,36.],da.getValues()) + pass + + def testSwigDAIOp(self): + da=DataArrayInt.New() + da.alloc(12,1) + da.iota(7) + da1=DataArrayInt.New() + da1.alloc(12,1) + da1.iota(8) + da2=da+da1 + self.assertEqual([15,17,19,21,23,25,27,29,31,33,35,37],da2.getValues()) + da2=da+3 + da3=3+da + self.assertTrue(da2.isEqual(da3)) + da2=da-1 + self.assertEqual([6,7,8,9,10,11,12,13,14,15,16,17],da2.getValues()) + da2=1-da + self.assertEqual([-6,-7,-8,-9,-10,-11,-12,-13,-14,-15,-16,-17],da2.getValues()) + da2=da*3 + self.assertEqual([21,24,27,30,33,36,39,42,45,48,51,54.0],da2.getValues()) + da2=3*da + self.assertEqual([21,24,27,30,33,36,39,42,45,48,51,54.0],da2.getValues()) + da2=da*da1 + self.assertEqual([56,72,90,110,132,156,182,210,240,272,306,342.0],da2.getValues()) + da2=da/4 + self.assertEqual([1,2,2,2,2,3,3,3,3,4,4,4],da2.getValues()) + da3=4/da + da4=da3*da2 + self.assertTrue(da4.isUniform(0)) + st1=da.getHiddenCppPointer() + da+=1 + st2=da.getHiddenCppPointer() + self.assertEqual(st1,st2) + self.assertTrue(da.isEqual(da1)) + da-=8 + st2=da.getHiddenCppPointer() + self.assertEqual(st1,st2) + self.assertEqual(range(12),da.getValues()) + da+=da1 + st2=da.getHiddenCppPointer() + self.assertEqual(st1,st2) + self.assertEqual([8,10,12,14,16,18,20,22,24,26,28,30],da.getValues()) + da/=2 + st2=da.getHiddenCppPointer() + self.assertEqual(st1,st2) + self.assertEqual([4,5,6,7,8,9,10,11,12,13,14,15],da.getValues()) + da*=da1 + st2=da.getHiddenCppPointer() + self.assertEqual(st1,st2) + self.assertEqual([32,45,60,77,96,117,140,165,192,221,252,285],da.getValues()) + da/=da1 + self.assertEqual(st1,st2) + self.assertEqual([4,5,6,7,8,9,10,11,12,13,14,15],da.getValues()) + da/=2 + st2=da.getHiddenCppPointer() + self.assertEqual(st1,st2) + self.assertEqual([2,2, 3,3, 4,4, 5,5, 6,6, 7,7],da.getValues()) + da.rearrange(3) + da5=DataArrayInt.New() + da5.setValues([5,4,3,2],4,1) + da*=da5 # it works with unmathing number of compo + st2=da.getHiddenCppPointer() + self.assertEqual(st1,st2) + self.assertEqual([10,10, 15,12,16,16,15,15, 18,12,14,14],da.getValues()) + da%=6 + st2=da.getHiddenCppPointer() + self.assertEqual(st1,st2) + self.assertEqual([4,4,3,0,4,4,3,3,0,0,2,2],da.getValues()) + # + da.alloc(30,1) + da.iota(7) + da.rearrange(3) + ids=DataArrayInt.New() + ids.setValues([3,4,7],3,1) + da[ids,:]=[5,8,9] + self.assertEqual([7,8,9,10,11,12,13,14,15,5,8,9,5,8,9,22,23,24,25,26,27,5,8,9,31,32,33,34,35,36],da.getValues()) + # + da.rearrange(1) ; da.iota(7) ; da.rearrange(3) + da[ids,[1,2]]=[5,8] + self.assertEqual([7,8,9,10,11,12,13,14,15,16,5,8,19,5,8,22,23,24,25,26,27,28,5,8,31,32,33,34,35,36],da.getValues()) + pass + + def testSwigDAIOp2(self): + da=DataArrayInt.New() + st=da.getHiddenCppPointer() + da.alloc(10,3) + da.rearrange(1) + da.iota(0) + da.rearrange(3) + da[:,1]+=4 + da[-2:,2]+=10 + da[-2:,2]+=10 + da[:,2]+=da[:,0] + da[da[0],:]=7 + self.assertEqual(st,da.getHiddenCppPointer()) + self.assertEqual(da.getValues(),[7,7,7,3,8,8,7,7,7,9,14,20,12,17,26,7,7,7,18,23,38,21,26,44,24,29,70,27,32,76]) + pass + + def testSwigDAIOp3(self): + da=DataArrayInt.New() + self.assertRaises(InterpKernelException,da.__len__) + self.assertRaises(InterpKernelException,da.__int__) + for elt in da: + self.assertTrue(False) + pass + da.alloc(12,3) + da.rearrange(1) ; da.fillWithZero() + l1=list(da) + self.assertEqual(36,len(da)); + da.rearrange(3) + tmp=da[0] + self.assertRaises(InterpKernelException,tmp.__int__) + self.assertEqual(12,len(da)); + l=list(da) + for elt in enumerate(l): + elt[1][2]=elt[0] + pass + ref=[0,0,0,0,0,1,0,0,2,0,0,3,0,0,4,0,0,5,0,0,6,0,0,7,0,0,8,0,0,9,0,0,10,0,0,11] + self.assertEqual(ref,da.getValues()); + da.rearrange(1) + l=[int(elt) for elt in l1] + self.assertEqual(ref,da.getValues()); + self.assertEqual(11,int(da[-1:])) + pass + + def testSwigDADOp3(self): + da=DataArrayDouble.New() + self.assertRaises(InterpKernelException,da.__len__) + self.assertRaises(InterpKernelException,da.__float__) + for elt in da: + self.assertTrue(False) + pass + da.alloc(12,3) + da.rearrange(1) ; da.fillWithZero() + l1=list(da) + self.assertEqual(36,len(da)); + da.rearrange(3) + tmp=da[0] + self.assertRaises(InterpKernelException,tmp.__float__) + self.assertEqual(12,len(da)); + l=list(da) + for elt in enumerate(l): + elt[1][2]=elt[0] + pass + ref=[0.,0.,0.,0.,0.,1.,0.,0.,2.,0.,0.,3.,0.,0.,4.,0.,0.,5.,0.,0.,6.,0.,0.,7.,0.,0.,8.,0.,0.,9.,0.,0.,10.,0.,0.,11.] + self.assertEqual(ref,da.getValues()); + da.rearrange(1) + l=[float(elt) for elt in l1] + self.assertEqual(ref,da.getValues()); + self.assertEqual(11.,float(da[-1:])) + pass + + def testSwigDataArrayIntIterator1(self): + da=DataArrayInt.New() + da.alloc(12,1) + da.iota(2) + da.rearrange(3) + # __getitem__ testing + li=[] + for it in da: + li+=it[1:] + pass + self.assertEqual([3, 4, 6, 7, 9, 10, 12, 13],li) + li=[] + for it in da: + li+=[it[-1]] + pass + self.assertEqual([4, 7, 10, 13],li) + li=[] + for it in da: + li+=it[[2,1,0]] + pass + self.assertEqual([4, 3, 2, 7, 6, 5, 10, 9, 8, 13, 12, 11],li) + # __setitem__ testing + da3=da.deepCpy() + da2=DataArrayInt.New() + da2.alloc(12,1) + da2.iota(2002) + da2.rearrange(3) + it2=da2.__iter__() + i=0 + for it in da: + pt=it2.next() + it[:]=pt + pass + self.assertTrue(da.isEqual(da2)) + da=da3 + da3=da.deepCpy() + # + for it in da: + it[:]=5 + pass + da.rearrange(1) + self.assertTrue(da.isUniform(5)) + da=da3 + da3=da.deepCpy() + # + for it in da: + it[:]=[8,9,12] + pass + self.assertEqual([8, 9, 12, 8, 9, 12, 8, 9, 12, 8, 9, 12],da.getValues()) + da=da3 + da3=da.deepCpy() + # + for it in da: + it[2]=[7] + pass + self.assertEqual([2, 3, 7, 5, 6, 7, 8, 9, 7, 11, 12, 7],da.getValues()) + pass + + def testSwigDataArrayDoubleIterator1(self): + da=DataArrayDouble.New() + da.alloc(12,1) + da.iota(2) + da.rearrange(3) + # __getitem__ testing + li=[] + for it in da: + li+=it[1:] + pass + self.assertEqual([3, 4, 6, 7, 9, 10, 12, 13],li) + li=[] + for it in da: + li+=[it[-1]] + pass + self.assertEqual([4, 7, 10, 13],li) + li=[] + for it in da: + li+=it[[2,1,0]] + pass + self.assertEqual([4, 3, 2, 7, 6, 5, 10, 9, 8, 13, 12, 11],li) + # __setitem__ testing + da3=da.deepCpy() + da2=DataArrayDouble.New() + da2.alloc(12,1) + da2.iota(2002) + da2.rearrange(3) + it2=da2.__iter__() + i=0 + for it in da: + pt=it2.next() + it[:]=pt + pass + self.assertTrue(da.isEqual(da2,1e-12)) + da=da3 + da3=da.deepCpy() + # + for it in da: + it[:]=5 + pass + da.rearrange(1) + self.assertTrue(da.isUniform(5,1e-12)) + da=da3 + da3=da.deepCpy() + # + for it in da: + it[:]=[8,9,12] + pass + self.assertEqual([8, 9, 12, 8, 9, 12, 8, 9, 12, 8, 9, 12],da.getValues()) + da=da3 + da3=da.deepCpy() + # + for it in da: + it[2]=[7] + pass + self.assertEqual([2, 3, 7, 5, 6, 7, 8, 9, 7, 11, 12, 7],da.getValues()) + pass + + def testSwigUMeshIterator1(self): + m=MEDCouplingDataForTest.build2DTargetMesh_1() + li1=[] + li2=[] + for cell in m: + li1+=cell.getAllConn()[1:] + li2+=[cell.getType()] + pass + self.assertEqual(li1,[0, 3, 4, 1, 1, 4, 2, 4, 5, 2, 6, 7, 4, 3, 7, 8, 5, 4]) + self.assertEqual(li2,[4, 3, 3, 4, 4]) + pass + + def testSwigUMeshIterator2(self): + m=MEDCouplingDataForTest.build2DTargetMesh_1() + self.assertRaises(InterpKernelException,m.cellsByType); + m.rearrange2ConsecutiveCellTypes() + li1=[] + li2=[] + li3=[] + for cellsByType in m.cellsByType(): + li1.append(cellsByType.getType()) + li2.append(cellsByType.getNumberOfElems()) + temp=[] + for cell in cellsByType: + t=[None,None] + t[0]=cell.getType() + t[1]=cell.getAllConn()[1:] + temp.append(t) + pass + li3.append(temp) + pass + self.assertEqual(li1,[4, 3]) + self.assertEqual(li2,[3, 2]) + self.assertEqual(li3,[[[4, (0, 3, 4, 1)], [4, (6, 7, 4, 3)], [4, (7, 8, 5, 4)]], [[3, (1, 4, 2)], [3, (4, 5, 2)]]]) + pass + + def testDAIAggregateMulti1(self): + a=DataArrayInt.New() + a.setValues(range(4),2,2) + a.setName("aa") + b=DataArrayInt.New() + b.setValues(range(6),3,2) + c=DataArrayInt.Aggregate([a,b]) + self.assertEqual(range(4)+range(6),c.getValues()) + self.assertEqual("aa",c.getName()) + self.assertEqual(5,c.getNumberOfTuples()) + self.assertEqual(2,c.getNumberOfComponents()) + pass + + def testMergeUMeshes2(self): + m1=MEDCouplingDataForTest.build3DSurfTargetMesh_1(); + m2=MEDCouplingDataForTest.build3DSurfTargetMesh_1(); + m3=MEDCouplingDataForTest.build3DSurfTargetMesh_1(); + # + vec1=[0,2,3] + m2_2=m2.buildPartOfMySelf(vec1,False); + vec2=[1,1] + m3_2=m3.buildPartOfMySelf(vec2,False); + # + ms=[m1,m2_2,m3_2]; + # + self.assertRaises(InterpKernelException,MEDCouplingUMesh.MergeUMeshes,ms+[None]); + self.assertRaises(InterpKernelException,MEDCouplingUMesh.MergeUMeshes,ms+[3.4]) + m4=MEDCouplingUMesh.MergeUMeshes(ms); + m4.checkCoherency(); + self.assertEqual(10,m4.getNumberOfCells()); + self.assertEqual(20,m4.getNumberOfNodes()); + self.assertEqual(45,m4.getMeshLength()); + m4bis=MEDCouplingMesh.MergeMeshes(ms); + self.assertTrue(m4.isEqual(m4bis,1e-12)) + del m4bis + # + vec3=[0,1,2,3,4] + m4_1=m4.buildPartOfMySelf(vec3,False); + m4_1.setName(m1.getName()); + self.assertTrue(m4_1.isEqual(m1,1e-12)); + # + vec4=[5,6,7] + m4_2=m4.buildPartOfMySelf(vec4,False); + cellCor,nodeCor=m4_2.checkGeoEquivalWith(m2_2,10,1e-12); + # + vec5=[8,9] + m4_3=m4.buildPartOfMySelf(vec5,False); + self.assertEqual(2,m4_3.getNumberOfCells()); + self.assertEqual(3,m4_3.getNumberOfNodes()); + m3_2.zipCoords(); + m4_3.setName(m3_2.getName()); + self.assertTrue(m4_3.isEqual(m3_2,1e-12)); + # + pass + + def testBuild0DMeshFromCoords1(self): + sourceCoords=[-0.3,-0.3,0., 0.7,-0.3,0., -0.3,0.7,0., 0.7,0.7,0.] + coo=DataArrayDouble.New(); + coo.setValues(sourceCoords,4,3); + coo.setName("My0D"); + m=MEDCouplingUMesh.Build0DMeshFromCoords(coo); + m.checkCoherency(); + self.assertEqual(4,m.getNumberOfNodes()); + self.assertEqual(4,m.getNumberOfCells()); + self.assertEqual(3,m.getSpaceDimension()); + self.assertEqual(0,m.getMeshDimension()); + types1=m.getAllGeoTypes(); + self.assertEqual([NORM_POINT1],types1); + for i in xrange(4): + conn=m.getNodeIdsOfCell(i); + self.assertEqual([i],conn); + self.assertTrue(NORM_POINT1==m.getTypeOfCell(i)); + pass + self.assertEqual(m.getName(),"My0D"); + pass + + def testDescriptionInMeshTimeUnit1(self): + text1="totoTTEDD"; + m=MEDCouplingDataForTest.build2DTargetMesh_1(); + m.setDescription(text1); + self.assertEqual(m.getDescription(),text1); + m2=m.deepCpy(); + self.assertTrue(m.isEqual(m2,1e-12)); + self.assertEqual(m2.getDescription(),text1); + m2.setDescription("ggg"); + self.assertTrue(not m.isEqual(m2,1e-12)); + # + f=MEDCouplingFieldDouble.New(ON_CELLS,ONE_TIME); + f.setTimeUnit(text1); + self.assertEqual(f.getTimeUnit(),text1); + f2=f.deepCpy(); + self.assertEqual(f2.getTimeUnit(),text1); + # + pass + + def testMultiFields1(self): + mfs=MEDCouplingDataForTest.buildMultiFields_1(); + ms=mfs.getMeshes(); + dms,refs=mfs.getDifferentMeshes() + das=mfs.getArrays(); + das2,refs2=mfs.getDifferentArrays() + self.assertEqual(5,len(mfs.getFields())) + self.assertEqual(1,len(mfs.getFields()[0].getArrays())); + self.assertEqual(2,len(mfs.getFields()[1].getArrays())); + self.assertEqual(1,len(mfs.getFields()[2].getArrays())); + self.assertEqual(1,len(mfs.getFields()[3].getArrays())); + self.assertEqual(1,len(mfs.getFields()[4].getArrays())); + self.assertEqual(5,len(ms)); + self.assertEqual(2,len(dms)); + self.assertEqual(6,len(das)); + self.assertEqual(5,len(das2)); + mfs2=mfs.deepCpy(); + self.assertTrue(mfs.isEqual(mfs2,1e-12,1e-12)) + pass + + def testFieldOverTime1(self): + fs=MEDCouplingDataForTest.buildMultiFields_2(); + self.assertRaises(InterpKernelException,MEDCouplingFieldOverTime.New,fs); + f4bis=fs[4].buildNewTimeReprFromThis(ONE_TIME,False); + fs[4]=f4bis; + self.assertRaises(InterpKernelException,MEDCouplingFieldOverTime.New,fs); + f4bis.setTime(2.7,20,21); + fot=MEDCouplingFieldOverTime.New(fs); + dt=fot.getDefinitionTimeZone(); + hs=dt.getHotSpotsTime(); + self.assertEqual(6,len(hs)); + expected1=[0.2,0.7,1.2,1.35,1.7,2.7] + for i in xrange(6): + self.assertAlmostEqual(expected1[i],hs[i],12); + pass + meshId,arrId,arrIdInField,fieldId=dt.getIdsOnTimeRight(0.2); + self.assertEqual(0,meshId); + self.assertEqual(0,arrId); + self.assertEqual(0,arrIdInField); + self.assertEqual(0,fieldId); + # + meshId,arrId,arrIdInField,fieldId=dt.getIdsOnTimeRight(0.7); + self.assertEqual(0,meshId); + self.assertEqual(1,arrId); + self.assertEqual(0,arrIdInField); + self.assertEqual(1,fieldId); + # + meshId,arrId,arrIdInField,fieldId=dt.getIdsOnTimeLeft(1.2);#**** WARNING left here + self.assertEqual(0,meshId); + self.assertEqual(2,arrId); + self.assertEqual(1,arrIdInField); + self.assertEqual(1,fieldId); + # + meshId,arrId,arrIdInField,fieldId=dt.getIdsOnTimeRight(1.2);#**** WARNING right again here + self.assertEqual(1,meshId); + self.assertEqual(3,arrId); + self.assertEqual(0,arrIdInField); + self.assertEqual(2,fieldId); + # + meshId,arrId,arrIdInField,fieldId=dt.getIdsOnTimeRight(1.35); + self.assertEqual(1,meshId); + self.assertEqual(3,arrId); + self.assertEqual(0,arrIdInField); + self.assertEqual(2,fieldId); + # + meshId,arrId,arrIdInField,fieldId=dt.getIdsOnTimeRight(1.7); + self.assertEqual(0,meshId); + self.assertEqual(3,arrId); + self.assertEqual(0,arrIdInField); + self.assertEqual(3,fieldId); + # + meshId,arrId,arrIdInField,fieldId=dt.getIdsOnTimeRight(2.7); + self.assertEqual(1,meshId); + self.assertEqual(4,arrId); + self.assertEqual(0,arrIdInField); + self.assertEqual(4,fieldId); + # + dt2=MEDCouplingDefinitionTime(); + self.assertTrue(not dt2.isEqual(dt)); + dt2.assign(dt); + dt2.assign(dt);#to check memory management + self.assertTrue(dt2.isEqual(dt)); + # + dt3=MEDCouplingDefinitionTime(); + # + pass + + def testDAICheckAndPreparePermutation1(self): + vals1=[9,10,0,6,4,11,3,7]; + expect1=[5,6,0,3,2,7,1,4]; + vals2=[9,10,0,6,10,11,3,7]; + da=DataArrayInt.New(); + da.setValues(vals1,8,1); + da2=da.checkAndPreparePermutation(); + self.assertEqual(8,da2.getNumberOfTuples()); + self.assertEqual(1,da2.getNumberOfComponents()); + for i in xrange(8): + self.assertEqual(expect1[i],da2.getIJ(i,0)); + pass + # + da=DataArrayInt.New(); + da.alloc(8,1); + da.iota(0); + da2=da.checkAndPreparePermutation(); + self.assertEqual(8,da2.getNumberOfTuples()); + self.assertEqual(1,da2.getNumberOfComponents()); + self.assertTrue(da2.isIdentity()); + # + da=DataArrayInt.New(); + da.alloc(8,1); + da.setValues(vals2,8,1); + self.assertRaises(InterpKernelException,da.checkAndPreparePermutation); + pass + + def testDAIChangeSurjectiveFormat1(self): + vals1=[0,3,2,3,2,2,1,2] + expected1=[0,1,2,6,8] + expected2=[0, 6, 2,4,5,7, 1,3] + da=DataArrayInt.New(); + da.setValues(vals1,8,1); + # + da2,da2I=da.changeSurjectiveFormat(4); + self.assertEqual(5,da2I.getNumberOfTuples()); + self.assertEqual(8,da2.getNumberOfTuples()); + self.assertEqual(expected1,da2I.getValues()); + self.assertEqual(expected2,da2.getValues()); + # + self.assertRaises(InterpKernelException,da.changeSurjectiveFormat,3); + # + pass + + def testUMeshGetCellIdsLyingOnNodes1(self): + m=MEDCouplingDataForTest.build3DSurfTargetMesh_1(); + nodeIds1=[1,2,3,4,6] + nodeIds2=[6,7] + da=m.getCellIdsLyingOnNodes(nodeIds1,True); + self.assertEqual(1,da.getNumberOfTuples()); + self.assertEqual(1,da.getNumberOfComponents()); + self.assertEqual(1,da.getIJ(0,0)); + da2=DataArrayInt.New() + da2.setValues(nodeIds2,2,1) + da=m.getCellIdsLyingOnNodes(da2,False); + self.assertEqual(2,da.getNumberOfTuples()); + self.assertEqual(1,da.getNumberOfComponents()); + self.assertEqual(3,da.getIJ(0,0)); + self.assertEqual(4,da.getIJ(1,0)); + pass + + def testUMeshFindCellIdsOnBoundary1(self): + m=MEDCouplingDataForTest.build3DSurfTargetMesh_1(); + da5=m.findCellIdsOnBoundary(); + self.assertEqual(5,da5.getNumberOfTuples()); + self.assertTrue(da5.isIdentity()); + pass + + def testMeshSetTime1(self): + m1=MEDCouplingDataForTest.build3DSurfTargetMesh_1(); + m2=MEDCouplingDataForTest.build3DSurfTargetMesh_1(); + # + self.assertTrue(m1.isEqual(m2,1e-12)); + m1.setTime(3.14,6,7); + tmp3,tmp1,tmp2=m1.getTime(); + self.assertEqual(6,tmp1); + self.assertEqual(7,tmp2); + self.assertAlmostEqual(3.14,tmp3,12); + self.assertTrue(not m1.isEqual(m2,1e-12)); + m2.setTime(3.14,6,7); + self.assertTrue(m1.isEqual(m2,1e-12)); + m1.setTimeUnit("ms"); + self.assertTrue(m1.getTimeUnit()=="ms"); + m1.setTimeUnit("us"); + self.assertTrue(m1.getTimeUnit()=="us"); + self.assertTrue(not m1.isEqual(m2,1e-12)); + m2.setTimeUnit("us"); + self.assertTrue(m1.isEqual(m2,1e-12)); + m2.setTime(3.14,6,8); + self.assertTrue(not m1.isEqual(m2,1e-12)); + m2.setTime(3.14,7,7); + self.assertTrue(not m1.isEqual(m2,1e-12)); + m2.setTime(3.15,6,7); + self.assertTrue(not m1.isEqual(m2,1e-12)); + # + m1.setTime(10.34,55,12); + m3=m1.deepCpy(); + self.assertTrue(m1.isEqual(m3,1e-12)); + tmp3,tmp1,tmp2=m3.getTime(); + self.assertEqual(55,tmp1); + self.assertEqual(12,tmp2); + self.assertAlmostEqual(10.34,tmp3,12); + # + # testing CMesh + coo1=[0.,1.,2.,3.5] + a=DataArrayDouble.New(); + a.setValues(coo1,4,1); + b=MEDCouplingCMesh.New(); + b.setCoordsAt(0,a); + # + b.setTime(5.67,8,100); + tmp3,tmp1,tmp2=b.getTime(); + self.assertEqual(8,tmp1); + self.assertEqual(100,tmp2); + self.assertAlmostEqual(5.67,tmp3,12); + c=b.deepCpy(); + self.assertTrue(c.isEqual(b,1e-12)); + tmp3,tmp1,tmp2=c.getTime(); + self.assertEqual(8,tmp1); + self.assertEqual(100,tmp2); + self.assertAlmostEqual(5.67,tmp3,12); + pass + + def testApplyFuncTwo1(self): + m1=MEDCouplingDataForTest.build3DSurfTargetMesh_1(); + f1=MEDCouplingFieldDouble.New(ON_CELLS,ONE_TIME); + f1.setMesh(m1); + # + vals=[1.,11.,21.,2.,12.,22.,3.,13.,23.,4.,14.,24.,5.,15.,25.] + da=DataArrayDouble.New(); + da.setValues(vals,5,3); + f1.setArray(da); + # + self.assertRaises(InterpKernelException,da.applyFunc2,1,"y+z"); + da.setInfoOnComponent(0,"x [m]"); + da.setInfoOnComponent(1,"y [mm]"); + da.setInfoOnComponent(2,"z [km]"); + + self.assertRaises(InterpKernelException, da.applyFunc2, 1, "x+y+zz+zzz"); + self.assertRaises(InterpKernelException, da.applyFunc2, 1, "toto(x+y)"); + self.assertRaises(InterpKernelException, da.applyFunc2, 1, "x/0"); + + da2=da.applyFunc2(1,"y+z"); + self.assertEqual(1,da2.getNumberOfComponents()); + self.assertEqual(5,da2.getNumberOfTuples()); + expected1=[32.,34.,36.,38.,40.] + for i in xrange(5): + self.assertAlmostEqual(expected1[i],da2.getIJ(0,i),12); + pass + da2=da.applyFunc(1,"y+z"); + expected2=[12.,14.,16.,18.,20.] + for i in xrange(5): + self.assertAlmostEqual(expected2[i],da2.getIJ(0,i),12); + pass + # + self.assertEqual(3,f1.getNumberOfComponents()); + self.assertEqual(5,f1.getNumberOfTuples()); + f1.applyFunc2(1,"y+z"); + self.assertEqual(1,f1.getNumberOfComponents()); + self.assertEqual(5,f1.getNumberOfTuples()); + for i in xrange(5): + self.assertAlmostEqual(expected1[i],f1.getArray().getIJ(0,i),12); + pass + # + pass + + def testApplyFuncThree1(self): + m1=MEDCouplingDataForTest.build3DSurfTargetMesh_1(); + f1=MEDCouplingFieldDouble.New(ON_CELLS,ONE_TIME); + f1.setMesh(m1); + # + vals=[1.,11.,21.,2.,12.,22.,3.,13.,23.,4.,14.,24.,5.,15.,25.] + da=DataArrayDouble.New(); + da.setValues(vals,5,3); + f1.setArray(da); + # + vs=3*[None]; + vs[0]="x"; vs[1]="Y"; vs[2]="z"; + self.assertRaises(InterpKernelException, da.applyFunc3, 1, vs, "y+z"); + self.assertRaises(InterpKernelException, da.applyFunc3, 1, vs, "x+Y+z+zz+zzz"); + self.assertRaises(InterpKernelException, da.applyFunc3, 1, vs, "x/0"); + vs[1]="y"; + da2=da.applyFunc3(1,vs,"y+z"); + expected1=[32.,34.,36.,38.,40.] + for i in xrange(5): + self.assertAlmostEqual(expected1[i],da2.getIJ(0,i),12); + pass + self.assertRaises(InterpKernelException, da.applyFunc3, 1, ["x","y","z","a"],"x+a") + f1.setArray(da); + self.assertEqual(3,f1.getNumberOfComponents()); + self.assertEqual(5,f1.getNumberOfTuples()); + f1.applyFunc3(1,vs,"y+z"); + self.assertEqual(1,f1.getNumberOfComponents()); + self.assertEqual(5,f1.getNumberOfTuples()); + for i in xrange(5): + self.assertAlmostEqual(expected1[i],f1.getArray().getIJ(0,i),12); + pass + pass + + def testFillFromAnalyticTwo1(self): + m1=MEDCouplingDataForTest.build3DSurfTargetMesh_1(); + m1.setTime(3.4,5,6); m1.setTimeUnit("us"); + self.assertRaises(InterpKernelException,m1.fillFromAnalytic2,ON_NODES,1,"y+z"); + m1.getCoords().setInfoOnComponent(0,"x [m]"); + m1.getCoords().setInfoOnComponent(1,"y"); + m1.getCoords().setInfoOnComponent(2,"z"); + f1=m1.fillFromAnalytic2(ON_NODES,1,"y+z"); + self.assertAlmostEqual(3.4,f1.getTime()[0],12) ; self.assertEqual(5,f1.getTime()[1]) ; self.assertEqual(6,f1.getTime()[2]) + self.assertEqual("us",f1.getTimeUnit()) + self.assertEqual(1,f1.getNumberOfComponents()); + self.assertEqual(9,f1.getNumberOfTuples()); + expected1=[0.2, 0.7, 1.2, 0.7, 1.2, 1.7, 1.2, 1.7, 2.2] + for i in xrange(9): + self.assertAlmostEqual(expected1[i],f1.getArray().getIJ(0,i),12); + pass + pass + + def testFillFromAnalyticThree1(self): + m1=MEDCouplingDataForTest.build3DSurfTargetMesh_1(); + m1.setTime(3.4,5,6); m1.setTimeUnit("us"); + vs=3*[None]; + vs[0]="x"; vs[1]="Y"; vs[2]="z"; + self.assertRaises(InterpKernelException,m1.fillFromAnalytic3,ON_NODES,1,vs,"y+z"); + vs[1]="y"; + f1=m1.fillFromAnalytic3(ON_NODES,1,vs,"y+z"); + self.assertAlmostEqual(3.4,f1.getTime()[0],12) ; self.assertEqual(5,f1.getTime()[1]) ; self.assertEqual(6,f1.getTime()[2]) + self.assertEqual("us",f1.getTimeUnit()) + self.assertEqual(1,f1.getNumberOfComponents()); + self.assertEqual(9,f1.getNumberOfTuples()); + expected1=[0.2, 0.7, 1.2, 0.7, 1.2, 1.7, 1.2, 1.7, 2.2] + for i in xrange(9): + self.assertAlmostEqual(expected1[i],f1.getArray().getIJ(0,i),12); + pass + pass + + def testDAUnitVar1(self): + da=DataArrayDouble.New(); + da.alloc(1,3); + da.setInfoOnComponent(0,"XPS [m]"); + st1=da.getVarOnComponent(0); + self.assertTrue(st1=="XPS"); + st2=da.getUnitOnComponent(0); + self.assertTrue(st2=="m"); + # + da.setInfoOnComponent(0,"XPS [m]"); + st1=da.getVarOnComponent(0); + self.assertTrue(st1=="XPS"); + st2=da.getUnitOnComponent(0); + self.assertTrue(st2=="m"); + # + da.setInfoOnComponent(0,"XPP [m]"); + st1=da.getVarOnComponent(0); + self.assertTrue(st1=="XPP"); + st2=da.getUnitOnComponent(0); + self.assertTrue(st2=="m"); + # + da.setInfoOnComponent(0,"XPP kdep kefer [ m ]"); + st1=da.getVarOnComponent(0); + self.assertTrue(st1=="XPP kdep kefer"); + st2=da.getUnitOnComponent(0); + self.assertTrue(st2==" m "); + # + da.setInfoOnComponent(0," XPP k[ dep k]efer [ m^ 2/s^3*kJ ]"); + st1=da.getVarOnComponent(0); + self.assertTrue(st1==" XPP k[ dep k]efer"); + st2=da.getUnitOnComponent(0); + self.assertTrue(st2==" m^ 2/s^3*kJ "); + # + da.setInfoOnComponent(0," XPP kefer "); + st1=da.getVarOnComponent(0); + self.assertTrue(st1==" XPP kefer "); + st2=da.getUnitOnComponent(0); + self.assertTrue(st2==""); + # + da.setInfoOnComponent(0,"temperature( bof)"); + st1=da.getVarOnComponent(0); + self.assertTrue(st1=="temperature( bof)"); + st2=da.getUnitOnComponent(0); + self.assertTrue(st2==""); + # + da.setInfoOnComponent(0,"kkk [m]"); + da.setInfoOnComponent(1,"ppp [m^2/kJ]"); + da.setInfoOnComponent(2,"abcde [MW/s]"); + # + vs=da.getVarsOnComponent(); + self.assertEqual(3,len(vs)); + self.assertTrue(vs[0]=="kkk"); + self.assertTrue(vs[1]=="ppp"); + self.assertTrue(vs[2]=="abcde"); + vs=da.getUnitsOnComponent(); + self.assertEqual(3,len(vs)); + self.assertTrue(vs[0]=="m"); + self.assertTrue(vs[1]=="m^2/kJ"); + self.assertTrue(vs[2]=="MW/s"); + pass + + def testGaussCoordinates1(self): + #Testing 1D cell types + m1=MEDCouplingDataForTest.build1DMultiTypes_1(); + f=MEDCouplingFieldDouble.New(ON_GAUSS_PT,ONE_TIME); + f.setMesh(m1); + wg1=[0.3]; + gsCoo1=[0.2]; + refCoo1=[-1.0,1.0]; + f.setGaussLocalizationOnType(NORM_SEG2,refCoo1,gsCoo1,wg1); + wg2=wg1; + gsCoo2=[0.2]; + refCoo2=[-1.0,1.0,0.0]; + f.setGaussLocalizationOnType(NORM_SEG3,refCoo2,gsCoo2,wg2); + # + resToTest=f.getLocalizationOfDiscr(); + self.assertEqual(3,resToTest.getNumberOfComponents()); + self.assertEqual(2,resToTest.getNumberOfTuples()); + expected1=[0.6,0.6,0.6, 0.6,0.6,0.6] + for i in xrange(6): + self.assertAlmostEqual(expected1[i],resToTest.getIJ(0,i),14); + pass + # + #Testing 2D cell types + m2=MEDCouplingDataForTest.build2DMultiTypes_1(); + f=MEDCouplingFieldDouble.New(ON_GAUSS_PT,ONE_TIME); + f.setMesh(m2); + wg3=[0.3,0.3]; + tria3CooGauss=[ 0.1, 0.8, 0.2, 0.7 ] + gsCoo3=tria3CooGauss + tria3CooRef=[ 0.0, 0.0, 1.0 , 0.0, 0.0, 1.0 ] + refCoo3=tria3CooRef; + f.setGaussLocalizationOnType(NORM_TRI3,refCoo3,gsCoo3,wg3); + wg4=[0.3,0.3,0.3]; + tria6CooGauss=[ 0.3, 0.2, 0.2, 0.1, 0.2, 0.4 ] + gsCoo4=tria6CooGauss; + tria6CooRef=[0.0, 0.0, 1.0, 0.0, 0.0, 1.0, 0.5, 0.0, 0.5, 0.5, 0.0, 0.5] + refCoo4=tria6CooRef; + f.setGaussLocalizationOnType(NORM_TRI6,refCoo4,gsCoo4,wg4); + wg5=[0.3,0.3,0.3,0.3]; + quad4CooGauss=[ 0.3, 0.2, 0.2, 0.1, 0.2, 0.4, 0.15, 0.27 ] + gsCoo5=quad4CooGauss; + quad4CooRef=[-1.0, 1.0, -1.0, -1.0, 1.0, -1.0, 1.0, 1.0] + refCoo5=quad4CooRef; + f.setGaussLocalizationOnType(NORM_QUAD4,refCoo5,gsCoo5,wg5); + wg6=[0.3,0.3,0.3,0.3]; + quad8CooGauss=[ 0.34, 0.16, 0.21, 0.3, 0.23, 0.4, 0.14, 0.37 ] + gsCoo6=quad8CooGauss; + quad8CooRef=[ -1.0, -1.0, 1.0, -1.0, 1.0, 1.0, -1.0, 1.0, 0.0, -1.0, 1.0, 0.0, 0.0, 1.0, -1.0, 0.0] + refCoo6=quad8CooRef; + f.setGaussLocalizationOnType(NORM_QUAD8,refCoo6,gsCoo6,wg6); + # + resToTest=f.getLocalizationOfDiscr(); + self.assertEqual(3,resToTest.getNumberOfComponents()); + self.assertEqual(13,resToTest.getNumberOfTuples());#2+3+4+4 gauss points for resp TRI3,TRI6,QUAD4,QUAD8 + expected2=[5.1,1.55,0.0, 4.7,1.65,0.0, + 2.32,1.52,0.0, 1.6,1.32,0.0, 3.52,1.26,0.0,#TRI6 + 2.6,1.6,0.0, 2.4,1.8,0.0, 2.4,1.2,0.0, 2.3,1.46,0.0,#QUAD4 + 2.32,2.68,0.0, 2.6,2.42,0.0, 2.8,2.46,0.0, 2.74,2.28,0.0 ];#QUAD8 + for i in xrange(39): + self.assertAlmostEqual(expected2[i],resToTest.getIJ(0,i),14); + pass + # + #Testing 3D cell types + m3=MEDCouplingDataForTest.build3DMultiTypes_1(); + f=MEDCouplingFieldDouble.New(ON_GAUSS_PT,ONE_TIME); + f.setMesh(m3); + # + wg7=[0.3]; + tetra4CooGauss=[0.34, 0.16, 0.21] + gsCoo7=tetra4CooGauss; + tetra4CooRef=[0.0,1.0,0.0, 0.0,0.0,1.0, 0.0,0.0,0.0, 1.0,0.0,0.0] + refCoo7=tetra4CooRef; + f.setGaussLocalizationOnType(NORM_TETRA4,refCoo7,gsCoo7,wg7); + wg8=[0.3]; + tetra10CooGauss=[0.2, 0.3, 0.1] + gsCoo8=tetra10CooGauss; + tetra10CooRef=[0.0,1.0,0.0, 0.0,0.0,0.0, 0.0,0.0,1.0, 1.0,0.0,0.0, 0.0,0.5,0.0, 0.0,0.0,0.5, 0.0,0.5,0.5, 0.5,0.5,0.0, 0.5,0.0,0.0, 0.5,0.0,0.5] + refCoo8=tetra10CooRef; + f.setGaussLocalizationOnType(NORM_TETRA10,refCoo8,gsCoo8,wg8); + wg9=[0.3]; + pyra5CooGauss=[0.2, 0.3, 0.1] + gsCoo9=pyra5CooGauss; + pyra5CooRef=[1.0,0.0,0.0, 0.0,1.0,0.0, -1.0,0.0,0.0, 0.0,-1.0,0.0, 0.0,0.0,1.0] + refCoo9=pyra5CooRef; + f.setGaussLocalizationOnType(NORM_PYRA5,refCoo9,gsCoo9,wg9); + wg10=[0.3]; + pyra13CooGauss=[0.1, 0.2, 0.7] + gsCoo10=pyra13CooGauss; + pyra13CooRef=[1.0,0.0,0.0, 0.0,1.0,0.0,-1.0,0.0,0.0,0.0,-1.0,0.0,0.0,0.0,1.0,0.5,0.5,0.0,-0.5,0.5,0.0,-0.5,-0.5,0.0,0.5,-0.5,0.0,0.5,0.0,0.5,0.0,0.5,0.5,-0.5,0.0,0.5,0.0,-0.5,0.5] + refCoo10=pyra13CooRef; + f.setGaussLocalizationOnType(NORM_PYRA13,refCoo10,gsCoo10,wg10); + wg11=[0.3]; + penta6CooGauss=[0.2, 0.3, 0.1] + gsCoo11=penta6CooGauss; + penta6CooRef=[-1.0,1.0,0.0,-1.0,-0.0,1.0,-1.0,0.0,0.0,1.0,1.0,0.0,1.0,0.0,1.0,1.0,0.0,0.0] + refCoo11=penta6CooRef; + f.setGaussLocalizationOnType(NORM_PENTA6,refCoo11,gsCoo11,wg11); + wg12=[0.3]; + penta15CooGauss=[0.2, 0.3,0.15] + gsCoo12=penta15CooGauss; + penta15CooRef=[-1.0,1.0,0.0,-1.0,0.0,1.0,-1.0,0.0,0.0,1.0,1.0,0.0,1.0,0.0,1.0,1.0,0.0,0.0,-1.0,0.5,0.5,-1.0,0.0,0.5,-1.0,0.5,0.0,0.0,1.0,0.0,0.0,0.0,1.0,0.0,0.0,0.0,1.0,0.5,0.5,1.0,0.0, 0.5,1.0,0.5,0.0] + refCoo12=penta15CooRef; + f.setGaussLocalizationOnType(NORM_PENTA15,refCoo12,gsCoo12,wg12); + wg13=[0.3]; + hexa8CooGauss=[0.2,0.3,0.15] + gsCoo13=hexa8CooGauss; + hexa8CooRef=[-1.0,-1.0,-1.0,1.0,-1.0,-1.0,1.0,1.0,-1.0,-1.0,1.0,-1.0,-1.0,-1.0,1.0,1.0,-1.0,1.0,1.0,1.0,1.0,-1.0,1.0,1.0] + refCoo13=hexa8CooRef; + f.setGaussLocalizationOnType(NORM_HEXA8,refCoo13,gsCoo13,wg13); + wg14=[0.3]; + hexa20CooGauss=[0.11,0.3,0.55] + gsCoo14=hexa20CooGauss; + hexa20CooRef=[-1.0,-1.0,-1.0,1.0,-1.0,-1.0,1.0,1.0,-1.0,-1.0,1.0,-1.0,-1.0,-1.0,1.0,1.0,-1.0,1.0,1.0,1.0,1.0,-1.0,1.0,1.0,0.0,-1.0,-1.0,1.0,0.0,-1.0,0.0,1.0,-1.0,-1.0,0.0,-1.0,-1.0,-1.0,0.0,1.0,-1.0,0.0,1.0,1.0,0.0,-1.0,1.0,0.0,0.0,-1.0,1.0,1.0,0.0,1.0,0.0,1.0,1.0,-1.0,0.0,1.0] + refCoo14=hexa20CooRef; + f.setGaussLocalizationOnType(NORM_HEXA20,refCoo14,gsCoo14,wg14); + # + resToTest=f.getLocalizationOfDiscr(); + self.assertEqual(3,resToTest.getNumberOfComponents()); + self.assertEqual(8,resToTest.getNumberOfTuples());#2+3+4+4 gauss points for resp TRI3,TRI6,QUAD4,QUAD8 + expected3=[1.312,3.15,1.02, 0.56,3.3,0.6, 2.18,1.1,0.2, 1.18,1.54,0.98, 1.56,0.3,3.6, 1.613,0.801,4.374, 2.6,2.4,2.3, 2.31232,2.3933985,1.553255] + for i in xrange(24): + self.assertAlmostEqual(expected3[i],resToTest.getIJ(0,i),14); + pass + # + pass + + def testP2Localization1(self): + m=MEDCouplingUMesh.New("testP2",2); + coords=[0.,2.,3.5,0.,4.5,1.5,1.2,0.32,3.4,1.,2.1,2.4] + conn=[0,1,2,3,4,5] + coo=DataArrayDouble.New(); + coo.setValues(coords,6,2); + m.setCoords(coo); + m.allocateCells(1); + m.insertNextCell(NORM_TRI6,6,conn[0:6]) + m.finishInsertingCells(); + # + f=MEDCouplingFieldDouble.New(ON_NODES,ONE_TIME); + f.setMesh(m); + da=DataArrayDouble.New(); + vals1=[1.2,2.3,3.4, 2.2,3.3,4.4, 3.2,4.3,5.4, 4.2,5.3,6.4, 5.2,6.3,7.4, 6.2,7.3,8.4] + da.setValues(vals1,6,3); + f.setArray(da); + # + loc=[2.27,1.3] + locs=f.getValueOnMulti(loc); + expected1=[6.0921164547752236, 7.1921164547752232, 8.2921164547752255] + for i in xrange(3): + self.assertAlmostEqual(expected1[i],locs.getIJ(0,i),12); + pass + pass + + def testP2Localization2(self): + m=MEDCouplingUMesh.New("testP2_2",3); + coords=[0.33312787792955395, -0.35155740179580952, -0.03567564825034563, 1.307146326477638, -0.57234557776250305, -0.08608044208272235, 0.5551834466499993, 0.62324964668794192, -0.014638951108536295, 0.37761817224442129, -0.38324019806913578, 0.96283164472856886, 0.79494856035658679, -0.40628057809270046, 0.0021004190225864614, 1.023740446371799, 0.07665912970471335, -0.072889657161871096, 0.54564584619517376, 0.11132872093429744, 0.039647326652013051, 0.27164784387819052, -0.42018012100866675, 0.46563376500745146, 0.89501965094896418, -0.56148455362735061, 0.43337469695473035, 0.49118025152924394, 0.093884938060727313, 0.47216346905220891] + conn=[0,1,2,3,4,5,6,7,8,9] + coo=DataArrayDouble.New(); + coo.setValues(coords,10,3); + m.setCoords(coo); + m.allocateCells(1); + m.insertNextCell(NORM_TETRA10,10,conn[0:10]) + m.finishInsertingCells(); + # + f=MEDCouplingFieldDouble.New(ON_NODES,ONE_TIME); + f.setMesh(m); + da=DataArrayDouble.New(); + vals1=[1.1,2.1,3.1,4.1,5.2,6.2,7.2,8.2,9.2,10.2] + da.setValues(vals1,10,1); + f.setArray(da); + # + loc=[0.64637931739890486, -0.16185896817550552, 0.22678966365273748] + locs=f.getValueOnMulti(loc); + expected1=[10.0844021968047] + for i in xrange(1): + self.assertAlmostEqual(expected1[i],locs.getIJ(0,i),12); + pass + pass + + def testGetValueOn2(self): + m=MEDCouplingDataForTest.build2DTargetMesh_1(); + f=MEDCouplingFieldDouble.New(ON_CELLS,NO_TIME); + f.setMesh(m); + arr=DataArrayDouble.New(); + nbOfCells=m.getNumberOfCells(); + f.setArray(arr); + values1=[7.,107.,10007.,8.,108.,10008.,9.,109.,10009.,10.,110.,10010.,11.,111.,10011.] + arr.setValues(values1,nbOfCells,3); + loc=[-0.05,-0.05, 0.55,-0.25, 0.55,0.15, -0.05,0.45, 0.45,0.45] + f.checkCoherency(); + locs=f.getValueOnMulti(loc); + self.assertEqual(5,locs.getNumberOfTuples()); + self.assertEqual(3,locs.getNumberOfComponents()); + for j in xrange(15): + self.assertAlmostEqual(values1[j],locs.getIJ(0,j),12); + pass + # Testing ON_NODES + f=MEDCouplingFieldDouble.New(ON_NODES,NO_TIME); + f.setMesh(m); + arr=DataArrayDouble.New(); + nbOfNodes=m.getNumberOfNodes(); + f.setArray(arr); + values2=[7.,107.,10007.,8.,108.,10008.,9.,109.,10009.,10.,110.,10010.,11.,111.,10011.,12.,112.,10012.,13.,113.,10013.,14.,114.,10014.,15.,115.,10015.] + arr.setValues(values2,nbOfNodes,3); + loc2=[0.5432,-0.2432, 0.5478,0.1528, 0.5432,-0.2432, 0.5432,-0.2432] + expected2=[9.0272, 109.0272, 10009.0272, 11.4124,111.4124,10011.4124, 9.0272, 109.0272, 10009.0272, 9.0272, 109.0272, 10009.0272] + f.checkCoherency(); + loc3=DataArrayDouble.New() + loc3.setValues(loc2,4,2); + locs=f.getValueOnMulti(loc3); + self.assertEqual(4,locs.getNumberOfTuples()); + self.assertEqual(3,locs.getNumberOfComponents()); + for i in xrange(12): + self.assertAlmostEqual(expected2[i],locs.getIJ(0,i),12); + pass + # + pass + + def testDAIGetIdsNotEqual1(self): + d=DataArrayInt.New(); + vals1=[2,3,5,6,8,5,5,6,1,-5] + d.setValues(vals1,10,1); + d2=d.getIdsNotEqual(5); + self.assertEqual(7,d2.getNumberOfTuples()); + self.assertEqual(1,d2.getNumberOfComponents()); + expected1=[0,1,3,4,7,8,9] + for i in xrange(7): + self.assertEqual(expected1[i],d2.getIJ(0,i)); + pass + d.rearrange(2); + self.assertRaises(InterpKernelException,d.getIdsNotEqual,5); + vals2=[-4,5,6] + vals3=vals2; + d.rearrange(1); + d3=d.getIdsNotEqualList(vals3); + self.assertEqual(5,d3.getNumberOfTuples()); + self.assertEqual(1,d3.getNumberOfComponents()); + expected2=[0,1,4,8,9] + for i in xrange(5): + self.assertEqual(expected2[i],d3.getIJ(0,i)); + pass + pass + + def testDAIComputeOffsets1(self): + d=DataArrayInt.New(); + vals1=[3,5,1,2,0,8] + expected1=[0,3,8,9,11,11] + d.setValues(vals1,6,1); + d.computeOffsets(); + self.assertEqual(6,d.getNumberOfTuples()); + self.assertEqual(1,d.getNumberOfComponents()); + for i in xrange(6): + self.assertEqual(expected1[i],d.getIJ(0,i)); + pass + pass + + def testUMeshHexagonPrism1(self): + coords=[0.8660254037844386, 0.5, 0.0, 0.0, 1.0, 0.0, -0.8660254037844386, 0.5, 0.0, -0.8660254037844386, -0.5, 0.0, 0.0, -1.0, 0.0, 0.8660254037844386, -0.5, 0.0, + 0.8660254037844386, 0.5, 2.0, 0.0, 1.0, 2.0, -0.8660254037844386, 0.5, 2.0, -0.8660254037844386, -0.5, 2.0, 0.0, -1.0, 2.0, 0.8660254037844386, -0.5, 2.0]; + conn=[1,2,3,4,5,0,7,8,9,10,11,6] + mesh=MEDCouplingUMesh.New("MyFirstHexagonalPrism",3); + coo=DataArrayDouble.New(); + coo.setValues(coords,12,3); + mesh.setCoords(coo); + mesh.allocateCells(1); + mesh.insertNextCell(NORM_HEXGP12,12,conn[0:12]) + mesh.finishInsertingCells(); + # + mesh.checkCoherency(); + vols=mesh.getMeasureField(False); + self.assertEqual(1,vols.getNumberOfTuples()); + self.assertEqual(1,vols.getNumberOfComponents()); + self.assertAlmostEqual(-5.196152422706632,vols.getIJ(0,0),12); + bary=mesh.getBarycenterAndOwner(); + self.assertEqual(1,bary.getNumberOfTuples()); + self.assertEqual(3,bary.getNumberOfComponents()); + expected1=[0.,0.,1.] + for i in xrange(3): + self.assertAlmostEqual(expected1[i],bary.getIJ(0,i),12); + pass + d1=DataArrayInt.New(); + d2=DataArrayInt.New(); + d3=DataArrayInt.New(); + d4=DataArrayInt.New(); + m2=mesh.buildDescendingConnectivity(d1,d2,d3,d4); + self.assertEqual(8,m2.getNumberOfCells()); + expected4=[[1,2,3,4,5,0],[7,6,11,10,9,8],[1,7,8,2],[2,8,9,3],[3,9,10,4],[4,10,11,5],[5,11,6,0],[0,6,7,1]]; + expected2=[NORM_POLYGON, NORM_POLYGON, NORM_QUAD4, NORM_QUAD4, NORM_QUAD4, NORM_QUAD4, NORM_QUAD4, NORM_QUAD4]; + expected3=[6,6,4,4,4,4,4,4] + for i in xrange(8): + self.assertTrue(m2.getTypeOfCell(i)==expected2[i]); + v=m2.getNodeIdsOfCell(i); + self.assertTrue(len(v)==expected3[i]); + self.assertEqual(expected4[i],v); + # + mesh.convertAllToPoly(); + self.assertTrue(NORM_POLYHED==mesh.getTypeOfCell(0)); + mesh.unPolyze(); + self.assertTrue(NORM_HEXGP12==mesh.getTypeOfCell(0)); + self.assertEqual(13,mesh.getMeshLength()); + # + pass + + def testDADCheckIsMonotonic(self): + da=DataArrayDouble.New(); + da.setValues([-1.,1.01,2.03,6.],2,2); + self.assertRaises(InterpKernelException,da.isMonotonic,True,1e-12); + da.rearrange(1); + self.assertTrue(da.isMonotonic(True,1e-12)); + da.checkMonotonic(True,1e-12); + da.setIJ(2,0,6.1); + self.assertTrue(not da.isMonotonic(True,1e-12)); + self.assertRaises(InterpKernelException,da.checkMonotonic,True,1e-12); + da.setIJ(2,0,5.99); + self.assertTrue(da.isMonotonic(True,1e-12)); + self.assertTrue(not da.isMonotonic(True,1e-1)); + pass + + def testCheckCoherencyDeeper1(self): + m=MEDCouplingDataForTest.build3DSourceMesh_1(); + m.checkCoherency(); + m.checkCoherency1(); + m.getNodalConnectivity().setIJ(8,0,-1); + m.checkCoherency(); + self.assertRaises(InterpKernelException,m.checkCoherency1); + m.getNodalConnectivity().setIJ(8,0,-6); + m.checkCoherency(); + self.assertRaises(InterpKernelException,m.checkCoherency1); + m.getNodalConnectivity().setIJ(8,0,9);#9>=NbOfNodes + m.checkCoherency(); + self.assertRaises(InterpKernelException,m.checkCoherency1); + m.getNodalConnectivity().setIJ(8,0,8);#OK + m.checkCoherency(); + m.checkCoherency1(); + elts=[1,5] + m.convertToPolyTypes(elts); + m.checkCoherency(); + m.checkCoherency1(); + m.getNodalConnectivity().setIJ(2,0,9);#9>=NbOfNodes + m.checkCoherency(); + self.assertRaises(InterpKernelException,m.checkCoherency1); + m.getNodalConnectivity().setIJ(2,0,-3); + m.checkCoherency(); + self.assertRaises(InterpKernelException,m.checkCoherency1); + m.getNodalConnectivity().setIJ(2,0,-1); + m.checkCoherency(); + self.assertRaises(InterpKernelException,m.checkCoherency1);#Throw because cell#0 is not a polyhedron + m.getNodalConnectivity().setIJ(2,0,4); + m.checkCoherency(); + m.checkCoherency1(); + m.getNodalConnectivity().setIJ(7,0,-1); + m.checkCoherency(); + m.checkCoherency1();#OK because we are in polyhedron connec + m.getNodalConnectivity().setIJ(36,0,14); + m.checkCoherency(); + self.assertRaises(InterpKernelException,m.checkCoherency1);#Throw beacause now cell 5 is a TETRA4 (14) so mimatch of number index and static type. + pass + + def testUnPolyze2(self): + m=MEDCouplingUMesh.New("jjj",3); + coo=DataArrayDouble.New(); + coo.alloc(4,3); + coo.rearrange(1); + coo.iota(0); + coo.rearrange(3); + m.setCoords(coo); + m.allocateCells(2); + m.insertNextCell(NORM_TETRA4,4,[0,1,2,3]); + m.insertNextCell(NORM_TETRA4,4,[0,1,2,3]); + m.finishInsertingCells(); + m2=MEDCouplingUMesh.MergeUMeshesOnSameCoords(4*[m]); + m2.convertToPolyTypes([2]); + m2.unPolyze(); + self.assertEqual(NORM_TETRA4,m2.getTypeOfCell(2)); + self.assertEqual(40,m2.getMeshLength()); + temp2=m2.getNodeIdsOfCell(2); + self.assertEqual(temp2,[0,1,2,3]); + m2.checkCoherency1(); + m3=m2.deepCpy(); + m2.unPolyze(); + self.assertTrue(m3.isEqual(m2,1e-12)); + pass + + def testDACpyFrom1(self): + d=DataArrayDouble.New(); + d.alloc(12,1); + d.iota(14.); + d.rearrange(3); + d.setName("Toto"); + d.setInfoOnComponent(0,"X [m]"); + d.setInfoOnComponent(1,"Y [m]"); + d.setInfoOnComponent(2,"Z [m]"); + # + d1=DataArrayDouble.New(); + self.assertTrue(not d.isEqual(d1,1e-12)); + d1.cpyFrom(d); + self.assertTrue(d.isEqual(d1,1e-12)); + d1.cpyFrom(d); + self.assertTrue(d.isEqual(d1,1e-12)); + d1.rearrange(2); + self.assertTrue(not d.isEqual(d1,1e-12)); + d1.cpyFrom(d); + self.assertTrue(d.isEqual(d1,1e-12)); + # + d2=d.convertToIntArr(); + d4=DataArrayInt.New(); + self.assertTrue(not d2.isEqual(d4)); + d4.cpyFrom(d2); + self.assertTrue(d2.isEqual(d4)); + d4.cpyFrom(d2); + self.assertTrue(d2.isEqual(d4)); + d4.rearrange(2); + self.assertTrue(not d2.isEqual(d4)); + d4.cpyFrom(d2); + self.assertTrue(d2.isEqual(d4)); + pass + + def testDAITransformWithIndArr1(self): + tab1=[17,18,22,19] + tab2=[0,1,1,3,3,0,1,3,2,2,3,0] + expected=[17,18,18,19,19,17,18,19,22,22,19,17] + d=DataArrayInt.New(); + d.setValues(tab1,4,1); + d1=DataArrayInt.New(); + d1.setValues(tab2,12,1); + d2=d1[:] + # + d1.transformWithIndArr(d); + self.assertEqual(12,d1.getNumberOfTuples()); + self.assertEqual(1,d1.getNumberOfComponents()); + for i in xrange(12): + self.assertEqual(expected[i],d1.getIJ(i,0)); + pass + # + d1=d2 + d1.transformWithIndArr(tab1) + self.assertEqual(12,d1.getNumberOfTuples()); + self.assertEqual(1,d1.getNumberOfComponents()); + for i in xrange(12): + self.assertEqual(expected[i],d1.getIJ(i,0)); + pass + pass + + def testDAIBuildPermArrPerLevel1(self): + arr=[2,0,1,1,0,1,2,0,1,1,0,0] + expected1=[10,0,5,6,1,7,11,2,8,9,3,4] + da=DataArrayInt.New(); + da.setValues(arr,12,1); + da2=da.buildPermArrPerLevel(); + self.assertEqual(12,da2.getNumberOfTuples()); + self.assertEqual(1,da2.getNumberOfComponents()); + for i in xrange(12): + self.assertEqual(expected1[i],da2.getIJ(i,0)); + pass + pass + + def testDAIOperations1(self): + arr1=[-1,-2,4,7,3,2,6,6,4,3,0,1] + da=DataArrayInt.New(); + da.setValues(arr1,4,3); + da1=DataArrayInt.New(); + da1.alloc(12,1); + da1.iota(2); + self.assertRaises(InterpKernelException,DataArrayInt.Add,da,da1);#not same number of tuples/Components + da1.rearrange(3); + da2=DataArrayInt.Add(da,da1); + self.assertEqual(4,da2.getNumberOfTuples()); + self.assertEqual(3,da2.getNumberOfComponents()); + expected1=[1,1,8,12,9,9,14,15,14,14,12,14] + for i in xrange(12): + self.assertEqual(expected1[i],da2.getIJ(0,i)); + pass + da1.substractEqual(da); + expected2=[3,5,0,-2,3,5,2,3,6,8,12,12] + for i in xrange(12): + self.assertEqual(expected2[i],da1.getIJ(0,i)); + pass + da1.rearrange(1); da1.iota(2); da1.rearrange(3); + da1.addEqual(da); + for i in xrange(12): + self.assertEqual(expected1[i],da1.getIJ(0,i)); + pass + da1.rearrange(1); da1.iota(2); da1.rearrange(3); + da2=DataArrayInt.Multiply(da,da1); + self.assertEqual(4,da2.getNumberOfTuples()); + self.assertEqual(3,da2.getNumberOfComponents()); + expected3=[-2,-6,16,35,18,14,48,54,40,33,0,13] + for i in xrange(12): + self.assertEqual(expected3[i],da2.getIJ(0,i)); + pass + da.divideEqual(da1); + self.assertEqual(4,da.getNumberOfTuples()); + self.assertEqual(3,da.getNumberOfComponents()); + expected4=[0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0] + for i in xrange(12): + self.assertEqual(expected4[i],da.getIJ(0,i)); + pass + da.setValues(arr1,4,3); + da1.multiplyEqual(da); + self.assertEqual(4,da1.getNumberOfTuples()); + self.assertEqual(3,da1.getNumberOfComponents()); + for i in xrange(12): + self.assertEqual(expected3[i],da1.getIJ(0,i)); + pass + da1.rearrange(1); da1.iota(2); da1.rearrange(3); + da2=DataArrayInt.Divide(da,da1); + self.assertEqual(4,da2.getNumberOfTuples()); + self.assertEqual(3,da2.getNumberOfComponents()); + for i in xrange(12): + self.assertEqual(expected4[i],da2.getIJ(0,i)); + pass + da1.applyInv(321); + self.assertEqual(4,da1.getNumberOfTuples()); + self.assertEqual(3,da1.getNumberOfComponents()); + expected5=[160,107,80,64,53,45,40,35,32,29,26,24] + for i in xrange(12): + self.assertEqual(expected5[i],da1.getIJ(0,i)); + pass + da1.applyDivideBy(2); + self.assertEqual(4,da1.getNumberOfTuples()); + self.assertEqual(3,da1.getNumberOfComponents()); + expected6=[80,53,40,32,26,22,20,17,16,14,13,12] + for i in xrange(12): + self.assertEqual(expected6[i],da1.getIJ(0,i)); + pass + expected7=[3,4,5,4,5,1,6,3,2,0,6,5] + da1.applyModulus(7); + for i in xrange(12): + self.assertEqual(expected7[i],da1.getIJ(0,i)); + pass + da1.applyLin(1,1); + expected8=[3,3,3,3,3,1,3,3,0,0,3,3] + da1.applyRModulus(3); + for i in xrange(12): + self.assertEqual(expected8[i],da1.getIJ(0,i)); + pass + pass + + def testEmulateMEDMEMBDC1(self): + m,m1=MEDCouplingDataForTest.buildPointe_1(); + m2,da1,da2,da3,da4,da5,da0=m.emulateMEDMEMBDC(m1) + expected0=[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,36,37,32,33,34,35,38,39,40,41,42,43,44,45,46] + expected1=[1,32,29,23,41,36] + self.assertEqual(47,da0.getNumberOfTuples()); + self.assertEqual(1,da0.getNumberOfComponents()); + for i in xrange(47): + self.assertEqual(expected0[i],da0.getIJ(0,i)); + pass + self.assertEqual(6,da5.getNumberOfTuples()); + self.assertEqual(1,da5.getNumberOfComponents()); + for i in xrange(6): + self.assertEqual(expected1[i],da5.getIJ(0,i)); + pass + expected2=[0,1,2,3,4,0,5,6,7,4,8,9,1,7,10,11,12,13,14,5,15,16,17,8,18,19,20,10,21,22,23,2,13,24,25,21,16,26,27,12,19,28,29,15,22,30,31,18,36,26,28,30,24,37,32,33,34,35,38,36,39,40,41,42,37,38,43,44,45,46] + self.assertEqual(70,da1.getNumberOfTuples()); + self.assertEqual(1,da1.getNumberOfComponents()); + for i in xrange(70): + self.assertEqual(expected2[i],da1.getIJ(0,i)); + pass + expected3=[0,4,8,12,16,20,24,28,32,36,40,44,48,53,58,64,70] + self.assertEqual(17,da2.getNumberOfTuples()); + self.assertEqual(1,da2.getNumberOfComponents()); + for i in xrange(17): + self.assertEqual(expected3[i],da2.getIJ(0,i)); + pass + expected4=[0,2,4,6,7,9,11,12,14,16,17,19,20,22,24,25,27,29,30,32,34,35,37,39,40,42,43,45,46,48,49,51,52,53,54,55,56,58,60,62,63,64,65,66,67,68,69,70] + #expected4=[0,2,4,6,7,9,11,12,14,16,17,19,20,22,24,25,27,29,30,32,34,35,37,39,40,42,43,45,46,48,49,51,52,54,56,57,58,59,60,62,63,64,65,66,67,68,69,70]; + self.assertEqual(48,da4.getNumberOfTuples()); + self.assertEqual(1,da4.getNumberOfComponents()); + for i in xrange(48): + self.assertEqual(expected4[i],da4.getIJ(0,i)); + pass + expected5=[0,1,0,3,0,7,0,1,2,1,4,1,2,3,2,5,2,3,6,3,4,9,4,8,4,5,10,5,9,5,6,11,6,10,6,7,8,7,11,7,8,12,8,9,12,9,10,12,10,11,12,11,13,13,13,13,12,14,13,15,14,15,14,14,14,14,15,15,15,15] + self.assertEqual(70,da3.getNumberOfTuples()); + self.assertEqual(1,da3.getNumberOfComponents()); + for i in xrange(70): + self.assertEqual(expected5[i],da3.getIJ(0,i)); + pass + pass + + def testGetLevArrPerCellTypes1(self): + m,m1=MEDCouplingDataForTest.buildPointe_1(); + m1,d0,d1,d2,d3=m.buildDescendingConnectivity(); + order=[NORM_TRI3,NORM_QUAD4]; + da0,da1=m1.getLevArrPerCellTypes(order); + expected0=[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,1,1,1,1,1,1,1,1,1] + expected1=[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,36,37,32,33,34,35,38,39,40,41,42,43,44,45,46] + self.assertEqual(47,da0.getNumberOfTuples()); + self.assertEqual(1,da0.getNumberOfComponents()); + for i in xrange(47): + self.assertEqual(expected0[i],da0.getIJ(0,i)); + pass + self.assertEqual(2,da1.getNumberOfTuples()); + self.assertEqual(1,da1.getNumberOfComponents()); + self.assertEqual(36,da1.getIJ(0,0));#36 TRI3 + self.assertEqual(11,da1.getIJ(1,0));#11 QUAD4 + # + da2=da0.buildPermArrPerLevel(); + # + self.assertEqual(47,da2.getNumberOfTuples()); + self.assertEqual(1,da2.getNumberOfComponents()); + for i in xrange(47): + self.assertEqual(expected1[i],da2.getIJ(0,i)); + pass + pass + + def testSortCellsInMEDFileFrmt1(self): + m,m1=MEDCouplingDataForTest.buildPointe_1(); + m2=m.deepCpy() + da=DataArrayInt.New() + da.setValues([0,1,2,14,3,12,4,5,15,6,7,8,9,10,11,13],16,1) + daa=da.invertArrayN2O2O2N(16) + m.renumberCells(daa,False) + da2=m.sortCellsInMEDFileFrmt() + self.assertEqual(da2.getValues(),[0,1,2,14,3,12,4,5,15,6,7,8,9,10,11,13]) + self.assertTrue(m.isEqual(m2,1e-12)) + self.assertTrue(da.isEqual(da2)) + pass + + def testBuildPartAndReduceNodes1(self): + m=MEDCouplingDataForTest.build2DTargetMesh_1(); + arr=[1,0] + m2,da=m.buildPartAndReduceNodes(arr); + self.assertEqual(5,m2.getNumberOfNodes()); + self.assertEqual(2,m2.getNumberOfCells()); + f=m2.getMeasureField(True); + self.assertAlmostEqual(0.125,f.getArray().getIJ(0,0),12); + self.assertAlmostEqual(0.25,f.getArray().getIJ(1,0),12); + # + arr2=DataArrayInt.New() + arr2.setValues(arr,2,1) + m2,da=m.buildPartAndReduceNodes(arr2); + self.assertEqual(5,m2.getNumberOfNodes()); + self.assertEqual(2,m2.getNumberOfCells()); + f=m2.getMeasureField(True); + self.assertAlmostEqual(0.125,f.getArray().getIJ(0,0),12); + self.assertAlmostEqual(0.25,f.getArray().getIJ(1,0),12); + pass + + def testDAITransformWithIndArrR1(self): + tab1=[2,4,5,3,6,7] + tab2=[-1,-1,0,1,2,3,4,5,-1,-1,-1,-1] + expected=[0,3,1,2,4,5] + d=DataArrayInt.New(); + d.setValues(tab1,6,1); + d1=DataArrayInt.New(); + d1.setValues(tab2,12,1); + d2=d1[:] + # + d3=d.transformWithIndArrR(d1); + self.assertEqual(6,d3.getNumberOfTuples()); + self.assertEqual(1,d3.getNumberOfComponents()); + for i in xrange(6): + self.assertEqual(expected[i],d3.getIJ(i,0)); + pass + # + d1=d2 + d3=d.transformWithIndArrR(tab2) + self.assertEqual(6,d3.getNumberOfTuples()); + self.assertEqual(1,d3.getNumberOfComponents()); + for i in xrange(6): + self.assertEqual(expected[i],d3.getIJ(i,0)); + pass + pass + + def testDAISplitByValueRange1(self): + val1=[6,5,0,3,2,7,8,1,4] + val2=[0,4,9] + d=DataArrayInt.New(); + d.setValues(val1,9,1); + e,f,g=d.splitByValueRange(val2); + self.assertEqual(9,e.getNumberOfTuples()); + self.assertEqual(1,e.getNumberOfComponents()); + self.assertEqual(9,f.getNumberOfTuples()); + self.assertEqual(1,f.getNumberOfComponents()); + self.assertEqual(2,g.getNumberOfTuples()); + self.assertEqual(1,g.getNumberOfComponents()); + # + expected1=[1,1,0,0,0,1,1,0,1] + expected2=[2,1,0,3,2,3,4,1,0] + for i in xrange(9): + self.assertEqual(expected1[i],e.getIJ(i,0)); + self.assertEqual(expected2[i],f.getIJ(i,0)); + pass + self.assertEqual(0,g.getIJ(0,0)); + self.assertEqual(1,g.getIJ(1,0)); + # + d.setIJ(6,0,9); + self.assertRaises(InterpKernelException,d.splitByValueRange,val2); + pass + + def testUMeshSplitProfilePerType1(self): + val0=[2,0,1,3,4] + m=MEDCouplingDataForTest.build2DTargetMesh_1(); + m.renumberCells(val0,False); + # + val1=[0,2,3] + d=DataArrayInt.New(); + d.setValues(val1,3,1); + d.setName("sup") + code,idsInPflPerType,pfls=m.splitProfilePerType(d); + self.assertEqual(2,len(code)); + self.assertEqual(2,len(idsInPflPerType)); + expected1=[[3,1,0], [4,2,1]] + self.assertEqual(expected1,code) + self.assertEqual(2,len(idsInPflPerType)); + self.assertEqual(1,idsInPflPerType[0].getNumberOfTuples()); + self.assertEqual(0,idsInPflPerType[0].getIJ(0,0)); + self.assertEqual(2,idsInPflPerType[1].getNumberOfTuples()); + self.assertEqual(1,idsInPflPerType[1].getIJ(0,0)); + self.assertEqual(2,idsInPflPerType[1].getIJ(1,0)); + # + self.assertEqual(2,len(pfls)); + self.assertEqual("sup",pfls[0].getName()) + self.assertEqual(1,pfls[0].getNumberOfTuples()); + self.assertEqual(0,pfls[0].getIJ(0,0)); + self.assertEqual("sup",pfls[1].getName()) + self.assertEqual(2,pfls[1].getNumberOfTuples()); + self.assertEqual(0,pfls[1].getIJ(0,0)); + self.assertEqual(1,pfls[1].getIJ(1,0)); + # + val2=[0,2,3,4] + d=DataArrayInt.New(); + d.setValues(val2,4,1); + code,idsInPflPerType,pfls=m.splitProfilePerType(d); + self.assertEqual(2,len(code)); + self.assertEqual(2,len(idsInPflPerType)); + expected2=[[3,1,0], [4,3,-1]] + self.assertEqual(expected2,code); + self.assertEqual(2,len(idsInPflPerType)); + self.assertEqual(1,idsInPflPerType[0].getNumberOfTuples()); + self.assertEqual(0,idsInPflPerType[0].getIJ(0,0)); + self.assertEqual(3,idsInPflPerType[1].getNumberOfTuples()); + self.assertEqual(1,idsInPflPerType[1].getIJ(0,0)); + self.assertEqual(2,idsInPflPerType[1].getIJ(1,0)); + self.assertEqual(3,idsInPflPerType[1].getIJ(2,0)); + # + self.assertEqual(1,len(pfls)); + self.assertEqual(1,pfls[0].getNumberOfTuples()); + self.assertEqual(0,pfls[0].getIJ(0,0)); + # + val3=[1,0,2] + d=DataArrayInt.New(); + d.setValues(val3,3,1); + code,idsInPflPerType,pfls=m.splitProfilePerType(d); + self.assertEqual(2,len(code)); + self.assertEqual(2,len(idsInPflPerType)); + expected3=[[3,2,0], [4,1,1]] + self.assertEqual(expected3,code); + self.assertEqual(2,len(idsInPflPerType)); + self.assertEqual(2,idsInPflPerType[0].getNumberOfTuples()); + self.assertEqual(0,idsInPflPerType[0].getIJ(0,0)); + self.assertEqual(1,idsInPflPerType[0].getIJ(1,0)); + self.assertEqual(1,idsInPflPerType[1].getNumberOfTuples()); + self.assertEqual(2,idsInPflPerType[1].getIJ(0,0)); + # + self.assertEqual(2,len(pfls)); + self.assertEqual(2,pfls[0].getNumberOfTuples()); + self.assertEqual(1,pfls[0].getIJ(0,0)); + self.assertEqual(0,pfls[0].getIJ(1,0)); + self.assertEqual(0,pfls[1].getIJ(0,0)); + # + val4=[3,4] + d=DataArrayInt.New(); + d.setValues(val4,2,1); + code,idsInPflPerType,pfls=m.splitProfilePerType(d); + self.assertEqual(1,len(code)); + self.assertEqual(1,len(idsInPflPerType)); + expected4=[[4,2,0]] + self.assertEqual(expected4,code); + self.assertEqual(1,len(idsInPflPerType)); + self.assertEqual(2,idsInPflPerType[0].getNumberOfTuples()); + self.assertEqual(0,idsInPflPerType[0].getIJ(0,0)); + self.assertEqual(1,idsInPflPerType[0].getIJ(1,0)); + # + self.assertEqual(1,len(pfls)); + self.assertEqual(2,pfls[0].getNumberOfTuples()); + self.assertEqual(1,pfls[0].getIJ(0,0)); + self.assertEqual(2,pfls[0].getIJ(1,0)); + pass + + def testDAIBuildExplicitArrByRanges1(self): + d=DataArrayInt.New(); + vals1=[0,2,3] + d.setValues(vals1,3,1); + e=DataArrayInt.New(); + vals2=[0,3,6,10,14,20] + e.setValues(vals2,6,1); + # + f=d.buildExplicitArrByRanges(e); + self.assertEqual(11,f.getNumberOfTuples()); + self.assertEqual(1,f.getNumberOfComponents()); + expected1=[0,1,2,6,7,8,9,10,11,12,13] + for i in xrange(11): + self.assertEqual(expected1[i],f.getIJ(i,0)); + pass + pass + + def testDAIComputeOffsets2(self): + d=DataArrayInt.New(); + vals1=[3,5,1,2,0,8] + expected1=[0,3,8,9,11,11,19] + d.setValues(vals1,6,1); + d.computeOffsets2(); + self.assertEqual(7,d.getNumberOfTuples()); + self.assertEqual(1,d.getNumberOfComponents()); + for i in xrange(7): + self.assertEqual(expected1[i],d.getIJ(0,i)); + pass + pass + + def testMergeField3(self): + m=MEDCouplingDataForTest.build2DTargetMesh_1(); + m.getCoords().setInfoOnComponent(0,"x [m]"); + m.getCoords().setInfoOnComponent(1,"z [km]"); + m.setName("m"); + m.setDescription("desc"); + f1=MEDCouplingFieldDouble.New(ON_CELLS,ONE_TIME); + f1.setName("f1"); + f1.setMesh(m); + arr=DataArrayDouble.New(); + arr.alloc(5,2); + arr.setInfoOnComponent(0,"X [m]"); + arr.setInfoOnComponent(1,"YY [mm]"); + arr.fillWithValue(2.); + f1.setArray(arr); + # + f2=MEDCouplingFieldDouble.MergeFields([f1]); + self.assertTrue(f1.isEqual(f2,1e-12,1e-12)); + # + pass + + def testGetDistributionOfTypes1(self): + m=MEDCouplingDataForTest.build2DTargetMesh_1(); + tab1=[2,0,1,3,4] + self.assertRaises(InterpKernelException,m.getDistributionOfTypes); + m.renumberCells(tab1,False); + code=m.getDistributionOfTypes(); + self.assertEqual(2,len(code)); + self.assertEqual(3,code[0][0]); + self.assertEqual(2,code[0][1]); + self.assertEqual(-1,code[0][2]); + self.assertEqual(4,code[1][0]); + self.assertEqual(3,code[1][1]); + self.assertEqual(-1,code[1][2]); + pass + + def testNorm2_1(self): + m=MEDCouplingDataForTest.build2DTargetMesh_1(); + f=MEDCouplingFieldDouble.New(ON_CELLS,ONE_TIME); + f.setMesh(m); + # + d=DataArrayDouble.New(); + tab=[1.2,1.3,2.2,2.3,3.2,3.3,4.2,4.3,5.2,5.3] + d.setValues(tab,5,2); + f.setArray(d); + f.checkCoherency(); + # + self.assertAlmostEqual(11.209371079592289,f.norm2(),14); + # + pass + + def testNormMax1(self): + m=MEDCouplingDataForTest.build2DTargetMesh_1(); + f=MEDCouplingFieldDouble.New(ON_CELLS,ONE_TIME); + f.setMesh(m); + # + d=DataArrayDouble.New(); + tab=[2.3,-1.2,6.3,-7.8,2.9,7.7,2.1,0.,3.6,-7.6] + d.setValues(tab,5,2); + f.setArray(d); + f.checkCoherency(); + # + self.assertAlmostEqual(7.8,f.normMax(),14); + # + pass + + def testFindAndCorrectBadOriented3DExtrudedCells1(self): + coords=[0.0011180339887498999, -0.0011755705045849499, 0.0, -0.0012331070204200001, -0.0011755705045849499, 0.0, -0.00067557050458494599, -0.00145964954842536, 0.0, -0.00050000000000000001, -0.00086602540378443902, 0.0, 0.00140211303259031, -0.00061803398874989504, 0.0, 0.00086602540378443902, -0.00050000000000000001, 0.0, 0.001, 0.0, 0.0, 0.00034561537182258202, 0.000269164072574575, 0.0, 0.0, 0.001, 0.0, -0.00050000000000000001, 0.00086602540378443902, 0.0, -0.000269164072574575, 0.00034561537182258202, 0.0, -0.001, 0.0, 0.0, -0.00086602540378443902, -0.00050000000000000001, 0.0, -0.00034561537182258202, -0.000269164072574575, 0.0, 0.0, -0.001, 0.0, 0.00050000000000000001, -0.00086602540378443902, 0.0, 0.000269164072574575, -0.00034561537182258202, 0.0, 0.0015, -6.01853107621011e-36, 0.0, 0.00056049747291484397, -0.00145964954842536, 0.0, 0.0011180339887498999, -0.0011755705045849499, 0.00050000000000000001, -0.0012331070204200001, -0.0011755705045849499, 0.00050000000000000001, -0.00067557050458494599, -0.00145964954842536, 0.00050000000000000001, -0.00050000000000000001, -0.00086602540378443902, 0.00050000000000000001, 0.00140211303259031, -0.00061803398874989504, 0.00050000000000000001, 0.00086602540378443902, -0.00050000000000000001, 0.00050000000000000001, 0.001, 0.0, 0.00050000000000000001, 0.00034561537182258202, 0.000269164072574575, 0.00050000000000000001, 0.0, 0.001, 0.00050000000000000001, -0.00050000000000000001, 0.00086602540378443902, 0.00050000000000000001, -0.000269164072574575, 0.00034561537182258202, 0.00050000000000000001, -0.001, 0.0, 0.00050000000000000001, -0.00086602540378443902, -0.00050000000000000001, 0.00050000000000000001, -0.00034561537182258202, -0.000269164072574575, 0.00050000000000000001, 0.0, -0.001, 0.00050000000000000001, 0.00050000000000000001, -0.00086602540378443902, 0.00050000000000000001, 0.000269164072574575, -0.00034561537182258202, 0.00050000000000000001, 0.0015, -6.01853107621011e-36, 0.00050000000000000001, 0.00056049747291484397, -0.00145964954842536, 0.00050000000000000001]; + conn=[2, 1, 3, 21, 20, 22, 4, 0, 5, 23, 19, 24, 8, 9, 10, 27, 28, 29, 11, 12, 13, 30, 31, 32, 0, 18, 15, 5, 19, 37, 34, 24, 6, 17, 4, 5, 25, 36, 23, 24, 3, 14, 16, 13, 22, 33, 35, 32, 13, 16, 7, 10, 32, 35, 26, 29] + connExp=[16, 2, 1, 3, 21, 20, 22, 16, 4, 0, 5, 23, 19, 24, 16, 8, 10, 9, 27, 29, 28, 16, 11, 13, 12, 30, 32, 31, 18, 0, 18, 15, 5, 19, 37, 34, 24,18, 6, 17, 4, 5, 25, 36, 23, 24, 18, 3, 13, 16, 14, 22, 32, 35, 33, 18, 13, 10, 7, 16, 32, 29, 26, 35] + invalidCells=[2,3,6,7] + m=MEDCouplingUMesh.New("Example",3); + coo=DataArrayDouble.New(); + coo.setValues(coords,38,3); + m.setCoords(coo); + m.allocateCells(8); + m.insertNextCell(NORM_PENTA6,6,conn[0:6]) + m.insertNextCell(NORM_PENTA6,6,conn[6:12]) + m.insertNextCell(NORM_PENTA6,6,conn[12:18]) + m.insertNextCell(NORM_PENTA6,6,conn[18:24]) + m.insertNextCell(NORM_HEXA8,8,conn[24:32]) + m.insertNextCell(NORM_HEXA8,8,conn[32:40]) + m.insertNextCell(NORM_HEXA8,8,conn[40:48]) + m.insertNextCell(NORM_HEXA8,8,conn[48:56]) + m.finishInsertingCells(); + # + v=m.findAndCorrectBadOriented3DExtrudedCells(); + self.assertEqual(4,len(v)); + self.assertEqual(v.getValues(),invalidCells); + self.assertEqual(connExp,m.getNodalConnectivity().getValues()); + self.assertTrue(m.findAndCorrectBadOriented3DExtrudedCells().empty()) + # + pass + + def testConvertExtrudedPolyhedra1(self): + conn=[1,2,3,4, 5,6,7,8,9,10,11,12, 13,14,15,16, 17,18,19,20,21,22, 23,24,25,26,27,28, 29,30,31,32,33,34,35,36,37,38, 39,40,41,42,43,44,45,46, 47,48,49,50,51,52,53,54,55,56,57,58, 59,60,61,62,63,64,65,66,67,68,69,70,71,72] + m=MEDCouplingUMesh.New("Example",3); + coo=DataArrayDouble.New(); + coo.alloc(73,3); + coo.rearrange(1); coo.iota(0); coo.rearrange(3); + m.setCoords(coo); + m.allocateCells(9); + m.insertNextCell(NORM_TETRA4,4,conn[0:4]) + m.insertNextCell(NORM_HEXA8,8,conn[4:12]) + m.insertNextCell(NORM_TETRA4,4,conn[12:16]) + m.insertNextCell(NORM_POLYHED,6,conn[16:22]) + m.insertNextCell(NORM_PENTA6,6,conn[22:28]) + m.insertNextCell(NORM_POLYHED,10,conn[28:38]) + m.insertNextCell(NORM_HEXA8,8,conn[38:46]) + m.insertNextCell(NORM_HEXGP12,12,conn[46:58]) + m.insertNextCell(NORM_POLYHED,14,conn[58:72]) + m.finishInsertingCells(); + # + m.convertExtrudedPolyhedra(); + da=m.getNodalConnectivity(); + dai=m.getNodalConnectivityIndex(); + self.assertEqual(10,dai.getNbOfElems()); + self.assertEqual(159,da.getNbOfElems()); + # + expected1=[14,1,2,3,4,18,5,6,7,8,9,10,11,12,14,13,14,15,16,31,17,18,19,-1,20,22,21,-1,17,20,21,18,-1,18,21,22,19,-1,19,22,20,17,16,23,24,25,26,27,28,31,29,30,31,32,33,-1,34,38,37,36,35,-1,29,34,35,30,-1,30,35,36,31,-1,31,36,37,32,-1,32,37,38,33,-1,33,38,34,29,18,39,40,41,42,43,44,45,46,22,47,48,49,50,51,52,53,54,55,56,57,58,31,59,60,61,62,63,64,65,-1,66,72,71,70,69,68,67,-1,59,66,67,60,-1,60,67,68,61,-1,61,68,69,62,-1,62,69,70,63,-1,63,70,71,64,-1,64,71,72,65,-1,65,72,66,59]; + expected2=[0,5,14,19,42,49,86,95,108,159] + self.assertEqual(expected1,da.getValues()); + self.assertEqual(expected2,dai.getValues()); + m.checkCoherency2() + pass + + def testNonRegressionCopyTinyStrings(self): + m=MEDCouplingDataForTest.build2DTargetMesh_1() + f1=m.getMeasureField(True) + f1.getArray().setInfoOnComponent(0,"P [N/m^2]") + bary=m.getBarycenterAndOwner() + f2=f1.buildNewTimeReprFromThis(NO_TIME,False) + f2.setArray(bary) + self.assertRaises(InterpKernelException,f1.copyTinyAttrFrom,f2) + pass + + def testDaDSetPartOfValuesAdv1(self): + tab1=[3.,4.,5., 13.,14.,15., 23.,24.,25., 33.,34.,35., 43.,44.,45., 53.,54.,55.] + tab2=[6.,7.,8., 16.,17.,18., 26.,27.,28.] + tab3=[4,1, 2,2, 3,0] + a=DataArrayDouble.New(); + a.setValues(tab1,6,3); + b=DataArrayDouble.New(); + b.setValues(tab2,3,3); + c=DataArrayInt.New(); + c.setValues(tab3,3,2); + # + a.setPartOfValuesAdv(b,c); + expected1=[3.,4.,5., 13.,14.,15., 26.,27.,28., 6.,7.,8., 16.,17.,18., 53.,54.,55.] + self.assertEqual(expected1,a.getValues()); + pass + + def testUMeshBuildSetInstanceFromThis1(self): + m=MEDCouplingDataForTest.build3DSurfTargetMesh_1(); + m2=m.buildSetInstanceFromThis(3); + self.assertTrue(m.isEqual(m2,1e-12)); + # + m=MEDCouplingUMesh.New("toto",2); + m2=m.buildSetInstanceFromThis(3); + self.assertEqual(0,m2.getNumberOfNodes()); + self.assertEqual(0,m2.getNumberOfCells()); + pass + + def testUMeshMergeMeshesCVW1(self): + m=MEDCouplingDataForTest.build3DSurfTargetMesh_1(); + m2=MEDCouplingUMesh.New("toto",2); + m3=MEDCouplingUMesh.MergeUMeshes([m,m2]); + m3.setName(m.getName()); + self.assertTrue(m.isEqual(m3,1e-12)); + pass + + def testChangeUnderlyingMeshWithCMesh1(self): + mesh=MEDCouplingCMesh.New(); + coordsX=DataArrayDouble.New(); + arrX=[ -1., 1., 2., 4. ] + coordsX.setValues(arrX,4,1); + coordsY=DataArrayDouble.New(); + arrY=[ -2., 2., 4., 8. ] + coordsY.setValues(arrY,4,1); + coordsZ=DataArrayDouble.New(); + arrZ=[ -3., 3., 6., 12. ] + coordsZ.setValues(arrZ,4,1); + mesh.setCoords(coordsX,coordsY,coordsZ); + f=mesh.getMeasureField(True) + mesh2=mesh.deepCpy() + for myId in [0,1,2,10,11,12,20,21,22]: + f=mesh.getMeasureField(True) + f.changeUnderlyingMesh(mesh2,myId,1e-12); + pass + mesh2.setName("uuuu") + for myId in [1,2,10,11,12,20,21,22]: + f=mesh.getMeasureField(True) + f.changeUnderlyingMesh(mesh2,myId,1e-12); + pass + pass + + def testDADFindCommonTuples1(self): + da=DataArrayDouble.New(); + # nbOftuples=1 + array1=[2.3,1.2,1.3,2.3,2.301,0.8] + da.setValues(array1,6,1) + c,cI=da.findCommonTuples(1e-2); + expected1=[0,3,4] + expected2=[0,3] + self.assertEqual(3,c.getNbOfElems()); + self.assertEqual(2,cI.getNbOfElems()); + self.assertEqual(expected1,c.getValues()) + self.assertEqual(expected2,cI.getValues()) + c,cI=da.findCommonTuples(2e-1) + expected3=[0,3,4,1,2] + expected4=[0,3,5] + self.assertEqual(5,c.getNbOfElems()); + self.assertEqual(3,cI.getNbOfElems()); + self.assertEqual(expected3,c.getValues()) + self.assertEqual(expected4,cI.getValues()) + # nbOftuples=2 + array2=[2.3,2.3,1.2,1.2,1.3,1.3,2.3,2.3,2.301,2.301,0.8,0.8] + da.setValues(array2,6,2) + c,cI=da.findCommonTuples(1e-2); + self.assertEqual(3,c.getNbOfElems()); + self.assertEqual(2,cI.getNbOfElems()); + self.assertEqual(expected1,c.getValues()) + self.assertEqual(expected2,cI.getValues()) + c,cI=da.findCommonTuples(2e-1) + self.assertEqual(5,c.getNbOfElems()); + self.assertEqual(3,cI.getNbOfElems()); + self.assertEqual(expected3,c.getValues()) + self.assertEqual(expected4,cI.getValues()) + # nbOftuples=3 + array3=[2.3,2.3,2.3,1.2,1.2,1.2,1.3,1.3,1.3,2.3,2.3,2.3,2.301,2.301,2.301,0.8,0.8,0.8] + da.setValues(array3,6,3) + c,cI=da.findCommonTuples(1e-2); + self.assertEqual(3,c.getNbOfElems()); + self.assertEqual(2,cI.getNbOfElems()); + self.assertEqual(expected1,c.getValues()) + self.assertEqual(expected2,cI.getValues()) + c,cI=da.findCommonTuples(2e-1) + self.assertEqual(5,c.getNbOfElems()); + self.assertEqual(3,cI.getNbOfElems()); + self.assertEqual(expected3,c.getValues()) + self.assertEqual(expected4,cI.getValues()) + # nbOftuples=1, no common groups + array11=[2.3,1.2,1.3,2.4,2.5,0.8] + da.setValues(array11,6,1) + c,cI=da.findCommonTuples(1e-2); + self.assertEqual(0,c.getNbOfElems()); + self.assertEqual(1,cI.getNbOfElems()); + self.assertEqual([0],cI.getValues()) + + array12=[0.]*(6*5) + da.setValues(array12,6,5) #bad NumberOfComponents + self.assertRaises(InterpKernelException, da.findCommonTuples, 1e-2); + pass + + def testDABack1(self): + da=DataArrayDouble.New(); + array1=[2.3,1.2,1.3,2.3,2.301,0.8] + da.setValues(array1,6,1); + self.assertAlmostEqual(0.8,da.back(),14); + da.rearrange(2); + self.assertRaises(InterpKernelException,da.back); + da.alloc(0,1); + self.assertRaises(InterpKernelException,da.back); + # + da=DataArrayInt.New(); + array2=[4,7,8,2] + da.setValues(array2,4,1); + self.assertEqual(2,da.back()); + da.rearrange(2); + self.assertRaises(InterpKernelException,da.back); + da.alloc(0,1); + self.assertRaises(InterpKernelException,da.back); + pass + + def testDADGetDifferentValues1(self): + da=DataArrayDouble.New(); + array1=[2.3,1.2,1.3,2.3,2.301,0.8] + da.setValues(array1,6,1) + # + expected1=[2.301,1.2,1.3,0.8] + dv=da.getDifferentValues(1e-2); + self.assertEqual(4,dv.getNbOfElems()); + for i in xrange(4): + self.assertAlmostEqual(expected1[i],dv.getIJ(i,0),14); + pass + # + dv=da.getDifferentValues(2e-1); + expected2=[2.301,1.3,0.8] + self.assertEqual(3,dv.getNbOfElems()); + for i in xrange(3): + self.assertAlmostEqual(expected2[i],dv.getIJ(i,0),14); + pass + pass + + def testDAIBuildOld2NewArrayFromSurjectiveFormat2(self): + arr=[0,3, 5,7,9] + arrI=[0,2,5] + a=DataArrayInt.New(); + a.setValues(arr,5,1); + b=DataArrayInt.New(); + b.setValues(arrI,3,1); + ret,newNbTuple=DataArrayInt.BuildOld2NewArrayFromSurjectiveFormat2(10,a,b); + expected=[0,1,2,0,3,4,5,4,6,4] + self.assertEqual(10,ret.getNbOfElems()); + self.assertEqual(7,newNbTuple); + self.assertEqual(1,ret.getNumberOfComponents()); + self.assertEqual(expected,ret.getValues()); + self.assertRaises(InterpKernelException,DataArrayInt.BuildOld2NewArrayFromSurjectiveFormat2,9,a,b); + pass + + def testDADIReverse1(self): + arr=[0,3,5,7,9,2] + a=DataArrayInt.New(); + a.setValues(arr,6,1); + self.assertEqual(2,a.back()); + a.reverse(); + for i in xrange(6): + self.assertEqual(arr[5-i],a.getIJ(i,0)); + pass + a.setValues(arr[:-1],5,1); + a.reverse(); + for i in xrange(5): + self.assertEqual(arr[4-i],a.getIJ(i,0)); + pass + # + arr2=[0.,3.,5.,7.,9.,2.] + b=DataArrayDouble.New(); + b.setValues(arr2,6,1); + b.reverse(); + for i in xrange(6): + self.assertAlmostEqual(arr2[5-i],b.getIJ(i,0),14); + pass + b.setValues(arr2[:5],5,1); + self.assertAlmostEqual(9.,b.back(),14) + b.reverse(); + for i in xrange(5): + self.assertAlmostEqual(arr2[4-i],b.getIJ(i,0),14); + pass + pass + + def testGetNodeIdsInUse1(self): + m0=MEDCouplingDataForTest.build2DTargetMesh_1(); + CellIds=[1,2] + m1=m0.buildPartOfMySelf(CellIds,True); + arr,newNbOfNodes=m1.getNodeIdsInUse(); + expected=[-1,0,1,-1,2,3,-1,-1,-1] + self.assertEqual(4,newNbOfNodes); + self.assertEqual(9,arr.getNbOfElems()); + self.assertEqual(expected,arr.getValues()); + arr2=arr.invertArrayO2N2N2O(newNbOfNodes); + self.assertEqual(4,arr2.getNbOfElems()); + expected2=[1,2,4,5] + self.assertEqual(expected2,arr2.getValues()); + pass + + def testBuildDescendingConnec2(self): + mesh=MEDCouplingDataForTest.build2DTargetMesh_1(); + # + mesh2,desc,descIndx,revDesc,revDescIndx=mesh.buildDescendingConnectivity2(); + mesh2.checkCoherency(); + self.assertEqual(1,mesh2.getMeshDimension()); + self.assertEqual(13,mesh2.getNumberOfCells()); + self.assertEqual(14,revDescIndx.getNbOfElems()); self.assertEqual(14,revDescIndx.getNumberOfTuples()); + self.assertEqual(6,descIndx.getNbOfElems()); self.assertEqual(6,descIndx.getNumberOfTuples()); + self.assertEqual(18,desc.getNbOfElems()); self.assertEqual(18,desc.getNumberOfTuples()); + self.assertEqual(18,revDesc.getNbOfElems()); self.assertEqual(18,revDesc.getNumberOfTuples()); + expected1=[1,2,3,4,-3,5,6, 7,8,-5,9,10,-2,11, 12,13,-7,-10] + self.assertEqual(expected1,desc.getValues()); + expected2=[0,4,7,10,14,18] + self.assertEqual(expected2,descIndx.getValues()); + expected3=[0,1,3,5,6,8,9,11,12,13,15,16,17,18] + self.assertEqual(expected3,revDescIndx.getValues()); + expected4=[0, 0,3, 0,1, 0, 1,2, 1, 2,4, 2, 3, 3,4, 3, 4, 4] + self.assertEqual(expected4,revDesc.getValues()); + conn=mesh2.getNodalConnectivity(); + connIndex=mesh2.getNodalConnectivityIndex(); + expected5=[0,3,6,9,12,15,18,21,24,27,30,33,36,39] + self.assertEqual(expected5,connIndex.getValues()); + expected6=[1, 0, 3, 1, 3, 4, 1, 4, 1, 1, 1, 0, 1, 4, 2, 1, 2, 1, 1, 4, 5, 1, 5, 2, 1, 6, 7, 1, 7, 4, 1, 3, 6, 1, 7, 8, 1, 8, 5] + self.assertEqual(expected6,conn.getValues()); + pass + + def testIntersect2DMeshesTmp1(self): + m1c=MEDCouplingCMesh.New(); + coordsX=DataArrayDouble.New(); + arrX=[ -1., 1., 2., 4. ] + coordsX.setValues(arrX,4,1); + m1c.setCoordsAt(0,coordsX); + coordsY=DataArrayDouble.New(); + arrY=[ -2., 2., 4., 8. ] + coordsY.setValues(arrY,4,1); + m1c.setCoordsAt(1,coordsY); + m1=m1c.buildUnstructured() + m1bis=m1.buildPartOfMySelf([3,4,5],False) + m2=m1.deepCpy() + m2=m2.buildPartOfMySelf([0,1,2],False) + m2.translate([0.5,0.5]) + # + m3,d1,d2=MEDCouplingUMesh.Intersect2DMeshes(m1bis,m2,1e-10) + expected1=[0,0,1,1,1,2,2,2] + expected2=[0,-1,0,1,-1,1,2,-1] + self.assertEqual(8,d1.getNumberOfTuples()); + self.assertEqual(8,d2.getNumberOfTuples()); + self.assertEqual(8,m3.getNumberOfCells()); + self.assertEqual(22,m3.getNumberOfNodes()); + self.assertEqual(2,m3.getSpaceDimension()); + self.assertEqual(expected1,d1.getValues()); + self.assertEqual(expected2,d2.getValues()); + expected3=[5,17,1,16,12,5,16,0,4,5,17,12,5,18,1,17,13,5,19,2,18,13,5,17,5,6,19,13,5,20,2,19,14,5,21,3,20,14,5,19,6,7,21,14] + expected4=[0,5,12,17,22,28,33,38,44] + expected5=[-1.0,2.0,1.0,2.0,2.0,2.0,4.0,2.0,-1.0,4.0,1.0,4.0,2.0,4.0,4.0,4.0,-0.5,-1.5,1.5,-1.5,2.5,-1.5,4.5,-1.5,-0.5,2.5,1.5,2.5,2.5,2.5,4.5,2.5,-0.5,2.0,1.0,2.5,1.5,2.0,2.0,2.5,2.5,2.0,4.0,2.5] + self.assertEqual(44,m3.getNodalConnectivity().getNumberOfTuples()); + self.assertEqual(9,m3.getNodalConnectivityIndex().getNumberOfTuples()); + self.assertEqual(expected3,m3.getNodalConnectivity().getValues()); + self.assertEqual(expected4,m3.getNodalConnectivityIndex().getValues()); + for i in xrange(44): + self.assertAlmostEqual(expected5[i],m3.getCoords().getIJ(0,i),12); + pass + pass + + def testFindNodesOnLine1(self): + mesh=MEDCouplingDataForTest.build2DTargetMesh_1(); + pt=[-0.3,-0.3] + pt2=[0.,0.,0.] + pt3=[-0.3,0.,0.] + vec=[0.,1.] + vec2=[1.,0.,0.] + vec3=[0.,1.,1.] + expected1=[0,3,6] + res=mesh.findNodesOnLine(pt,vec,1e-12); + self.assertEqual(3,len(res)); + self.assertEqual(expected1,res.getValues()); + # + mesh.changeSpaceDimension(3); + mesh.rotate(pt2,vec2,pi/4.); + res=mesh.findNodesOnLine(pt3,vec3,1e-12); + self.assertEqual(3,len(res)); + self.assertEqual(expected1,res.getValues()); + pass + + def testIntersect2DMeshesTmp2(self): + m1c=MEDCouplingCMesh.New(); + coordsX1=DataArrayDouble.New(); + arrX1=[ 0., 1., 1.5, 2. ] + coordsX1.setValues(arrX1,4,1); + m1c.setCoordsAt(0,coordsX1); + coordsY1=DataArrayDouble.New(); + arrY1=[ 0., 1.5, 3.] + coordsY1.setValues(arrY1,3,1); + m1c.setCoordsAt(1,coordsY1); + m1=m1c.buildUnstructured(); + m2c=MEDCouplingCMesh.New(); + coordsX2=DataArrayDouble.New(); + arrX2=[ 0., 1., 2. ] + coordsX2.setValues(arrX2,3,1); + m2c.setCoordsAt(0,coordsX2); + coordsY2=DataArrayDouble.New(); + arrY2=[ 0., 1., 3.] + coordsY2.setValues(arrY2,3,1); + m2c.setCoordsAt(1,coordsY2); + m2=m2c.buildUnstructured(); + # + m3,d1,d2=MEDCouplingUMesh.Intersect2DMeshes(m1,m2,1e-10) + # + expected1=[0,0,1,1,2,2,3,4,5] + expected2=[0,2,1,3,1,3,2,3,3] + self.assertEqual(9,d1.getNumberOfTuples()); + self.assertEqual(9,d2.getNumberOfTuples()); + self.assertEqual(9,m3.getNumberOfCells()); + self.assertEqual(22,m3.getNumberOfNodes()); + self.assertEqual(2,m3.getSpaceDimension()); + self.assertEqual(expected1,d1.getValues()); + self.assertEqual(expected2,d2.getValues()); + expected3=[5,16,13,12,15,5,15,4,5,16,5,21,2,13,16,5,16,5,6,21,5,17,14,2,21,5,21,6,7,17,5,4,18,19,5,5,5,19,10,6,5,6,10,20,7] + expected4=[0,5,10,15,20,25,30,35,40,45] + expected5=[0.0,0.0,1.0,0.0,1.5,0.0,2.0,0.0,0.0,1.5,1.0,1.5,1.5,1.5,2.0,1.5,0.0,3.0,1.0,3.0,1.5,3.0,2.0,3.0,0.0,0.0,1.0,0.0,2.0,0.0,0.0,1.0,1.0,1.0,2.0,1.0,0.0,3.0,1.0,3.0,2.0,3.0,1.5,1.0] + self.assertEqual(45,m3.getNodalConnectivity().getNumberOfTuples()); + self.assertEqual(10,m3.getNodalConnectivityIndex().getNumberOfTuples()); + self.assertEqual(expected3,m3.getNodalConnectivity().getValues()); + self.assertEqual(expected4,m3.getNodalConnectivityIndex().getValues()); + for i in xrange(44): + self.assertAlmostEqual(expected5[i],m3.getCoords().getIJ(0,i),12); + pass + pass + + def testBuildPartOfMySelfSafe1(self): + mesh=MEDCouplingDataForTest.build2DTargetMesh_1() + self.assertRaises(InterpKernelException,mesh.buildPartOfMySelf,[0,-1,4,2],True) + self.assertRaises(InterpKernelException,mesh.buildPartOfMySelf,[0,4,5,4],True) + pass + + def testIntersect2DMeshesTmp3(self): + m1Coords=[0.,0.,1.,0.,1.5,0.,0.,1.,0.,1.5,-1.,0.,-1.5,0.,0.,-1,0.,-1.5,0.5,0.,1.25,0.,0.70710678118654757,0.70710678118654757,1.0606601717798214,1.0606601717798214,0.,0.5,0.,1.25,-0.70710678118654757,0.70710678118654757,-1.0606601717798214,1.0606601717798214,-0.5,0.,-1.25,0.,-0.70710678118654757,-0.70710678118654757,-1.0606601717798214,-1.0606601717798214,0.,-0.5,0.,-1.25,0.70710678118654757,-0.70710678118654757,1.0606601717798214,-1.0606601717798214]; + m1Conn=[0,3,1,13,11,9, 3,4,2,1,14,12,10,11, 5,3,0,15,13,17, 6,4,3,5,16,14,15,18, 5,0,7,17,21,19, 6,5,7,8,18,19,22,20, 0,1,7,9,23,21, 1,2,8,7,10,24,22,23]; + m1=MEDCouplingUMesh.New(); + m1.setMeshDimension(2); + m1.allocateCells(8); + m1.insertNextCell(NORM_TRI6,6,m1Conn[0:6]); + m1.insertNextCell(NORM_QUAD8,8,m1Conn[6:14]); + m1.insertNextCell(NORM_TRI6,6,m1Conn[14:20]); + m1.insertNextCell(NORM_QUAD8,8,m1Conn[20:28]); + m1.insertNextCell(NORM_TRI6,6,m1Conn[28:34]); + m1.insertNextCell(NORM_QUAD8,8,m1Conn[34:42]); + m1.insertNextCell(NORM_TRI6,6,m1Conn[42:48]); + m1.insertNextCell(NORM_QUAD8,8,m1Conn[48:56]); + m1.finishInsertingCells(); + myCoords1=DataArrayDouble.New(); + myCoords1.setValues(m1Coords,25,2); + m1.setCoords(myCoords1); + # + m2Coords=[0.,0.,1.1,0.,1.1,1.,0.,1.,1.7,0.,1.7,1.,-1.1,1.,-1.1,0.,-1.7,0.,-1.7,1.,-1.7,-1,-1.1,-1.,0.,-1.,1.1,-1,1.7,-1.] + m2Conn=[0,3,2,1, 1,2,5,4, 7,6,3,0, 8,9,6,7, 7,0,12,11, 8,7,11,10, 0,1,13,12, 1,4,14,13] + m2=MEDCouplingUMesh.New(); + m2.setMeshDimension(2); + m2.allocateCells(8); + for i in xrange(8): + m2.insertNextCell(NORM_QUAD4,4,m2Conn[4*i:4*(i+1)]) + pass + m2.finishInsertingCells(); + myCoords2=DataArrayDouble.New(); + myCoords2.setValues(m2Coords,15,2); + m2.setCoords(myCoords2); + # + m3,d1,d2=MEDCouplingUMesh.Intersect2DMeshes(m1,m2,1e-10) + m3.unPolyze() + # + expected1=[0,1,1,1,2,3,3,3,4,5,5,5,6,7,7,7] + expected2=[0,0,1,-1,2,2,3,-1,4,4,5,-1,6,6,7,-1] + self.assertEqual(16,d1.getNumberOfTuples()); + self.assertEqual(16,d2.getNumberOfTuples()); + self.assertEqual(16,m3.getNumberOfCells()); + self.assertEqual(104,m3.getNumberOfNodes()); + self.assertEqual(2,m3.getSpaceDimension()); + self.assertEqual(expected1,d1.getValues()); + self.assertEqual(expected2,d2.getValues()); + expected3=[6,28,1,25,44,45,46,8,26,1,28,27,47,48,49,50,8,40,2,26,27,51,52,53,54,8,28,4,40,27,55,56,57,58,6,28,25,5,59,60,61,8,28,5,32,31,62,63,64,65,8,32,6,41,31,66,67,68,69,8,41,4,28,31,70,71,72,73,6,25,37,5,74,75,76,8,32,5,37,36,77,78,79,80,8,42,6,32,36,81,82,83,84,8,37,8,42,36,85,86,87,88,6,1,37,25,89,90,91,8,37,1,26,38,92,93,94,95,8,26,2,43,38,96,97,98,99,8,43,8,37,38,100,101,102,103] + expected4=[0,7,16,25,34,41,50,59,68,75,84,93,102,109,118,127,136] + expected5=[0.,0.,1.,0.,1.5,0.,0.,1.,0.,1.5,-1.,0.,-1.5,0.,0.,-1.,0.,-1.5,0.5,0.,1.25,0.,0.7071067811865476,0.7071067811865476,1.0606601717798214,1.0606601717798214,0.,0.5,0.,1.25,-0.7071067811865476,0.7071067811865476,-1.0606601717798214,1.0606601717798214,-0.5,0.,-1.25,0.,-0.7071067811865476,-0.7071067811865476,-1.0606601717798214,-1.0606601717798214,0.,-0.5,0.,-1.25,0.7071067811865476,-0.7071067811865476,1.0606601717798214,-1.0606601717798214,0.,0.,1.1,0.,1.1,1.,0.,1.,1.7,0.,1.7,1.,-1.1,1.,-1.1,0.,-1.7,0.,-1.7,1.,-1.7,-1.,-1.1,-1.,0.,-1.,1.1,-1.,1.7,-1.,1.118033988749895,1.,-1.118033988749895,1.,-1.118033988749895,-1.,1.118033988749895,-1.,0.7071067811865477,0.7071067811865476,0.5,0.,0.,0.5,1.05,0.,0.7071067811865475,0.7071067811865477,0.55,1.,1.1,0.5,1.4012585384440737,0.535233134659635,1.3,0.,1.1,0.5,1.1090169943749475,1.,0.,1.25,0.6123724356957946,1.369306393762915,1.1090169943749475,1.,0.55,1.,0.,0.5,-0.5,0.,-0.7071067811865477,0.7071067811865476,-0.7071067811865475,0.7071067811865477,-1.05,0.,-1.1,0.5,-0.55,1.,-1.3,0.,-1.4012585384440737,0.5352331346596344,-1.1090169943749475,1.,-1.1,0.5,-0.6123724356957941,1.3693063937629155,0.,1.25,-0.55,1.,-1.1090169943749475,1.,0.,-0.5,-0.7071067811865475,-0.7071067811865477,-0.5,0.,-1.05,0.,-0.7071067811865478,-0.7071067811865475,-0.55,-1.,-1.1,-0.5,-1.4012585384440734,-0.5352331346596354,-1.3,0.,-1.1,-0.5,-1.1090169943749475,-1.,0.,-1.25,-0.6123724356957945,-1.369306393762915,-1.1090169943749475,-1.,-0.55,-1.,0.7071067811865475,-0.7071067811865477,0.,-0.5,0.5,0.,0.7071067811865477,-0.7071067811865475,1.05,0.,1.1,-0.5,0.55,-1.,1.3,0.,1.4012585384440737,-0.535233134659635,1.1090169943749475,-1.,1.1,-0.5,0.6123724356957946,-1.369306393762915,0.,-1.25,0.55,-1.,1.1090169943749475,-1.0] + self.assertEqual(136,m3.getNodalConnectivity().getNumberOfTuples()); + self.assertEqual(17,m3.getNodalConnectivityIndex().getNumberOfTuples()); + self.assertEqual(expected3,m3.getNodalConnectivity().getValues()); + self.assertEqual(expected4,m3.getNodalConnectivityIndex().getValues()); + for i in xrange(208): + self.assertAlmostEqual(expected5[i],m3.getCoords().getIJ(0,i),12); + pass + pass + + def testUMeshTessellate2D1(self): + m1Coords=[0.,0.,1.,0.,1.5,0.,0.,1.,0.,1.5,-1.,0.,-1.5,0.,0.,-1,0.,-1.5,0.5,0.,1.25,0.,0.70710678118654757,0.70710678118654757,1.0606601717798214,1.0606601717798214,0.,0.5,0.,1.25,-0.70710678118654757,0.70710678118654757,-1.0606601717798214,1.0606601717798214,-0.5,0.,-1.25,0.,-0.70710678118654757,-0.70710678118654757,-1.0606601717798214,-1.0606601717798214,0.,-0.5,0.,-1.25,0.70710678118654757,-0.70710678118654757,1.0606601717798214,-1.0606601717798214]; + m1Conn=[0,3,1,13,11,9, 3,4,2,1,14,12,10,11, 5,3,0,15,13,17, 6,4,3,5,16,14,15,18, 5,0,7,17,21,19, 6,5,7,8,18,19,22,20, 0,1,7,9,23,21, 1,2,8,7,10,24,22,23]; + m1=MEDCouplingUMesh.New(); + m1.setMeshDimension(2); + m1.allocateCells(8); + m1.insertNextCell(NORM_TRI6,6,m1Conn[0:6]); + m1.insertNextCell(NORM_QUAD8,8,m1Conn[6:14]); + m1.insertNextCell(NORM_TRI6,6,m1Conn[14:20]); + m1.insertNextCell(NORM_QUAD8,8,m1Conn[20:28]); + m1.insertNextCell(NORM_TRI6,6,m1Conn[28:34]); + m1.insertNextCell(NORM_QUAD8,8,m1Conn[34:42]); + m1.insertNextCell(NORM_TRI6,6,m1Conn[42:48]); + m1.insertNextCell(NORM_QUAD8,8,m1Conn[48:56]); + m1.finishInsertingCells(); + myCoords1=DataArrayDouble.New(); + myCoords1.setValues(m1Coords,25,2); + m1.setCoords(myCoords1); + # + m11=m1.deepCpy(); + m11.tessellate2D(1.); + self.assertTrue(m11.getCoords().isEqual(m11.getCoords(),1e-12)); + expected1=[5,0,3,11,1,5,3,4,12,2,1,11,5,5,15,3,0,5,6,16,4,3,15,5,5,5,0,7,19,5,6,5,19,7,8,20,5,0,1,23,7,5,1,2,24,8,7,23] + expected2=[0,5,12,17,24,29,36,41,48] + self.assertEqual(48,m11.getNodalConnectivity().getNumberOfTuples()); + self.assertEqual(9,m11.getNodalConnectivityIndex().getNumberOfTuples()); + self.assertEqual(expected1,m11.getNodalConnectivity().getValues()); + self.assertEqual(expected2,m11.getNodalConnectivityIndex().getValues()); + # + m12=m1.deepCpy(); + m12.tessellate2D(0.5); + self.assertEqual(41,m12.getNumberOfNodes()); + expected3=[5,0,3,25,26,1,5,3,4,27,28,2,1,26,25,5,5,29,30,3,0,5,6,31,32,4,3,30,29,5,5,5,0,7,33,34,5,6,5,34,33,7,8,35,36,5,0,1,37,38,7,5,1,2,39,40,8,7,38,37] + expected4=[0,6,15,21,30,36,45,51,60] + expected5=[0.,0.,1.,0.,1.5,0.,0.,1.,0.,1.5,-1.,0.,-1.5,0.,0.,-1.,0.,-1.5,0.5,0.,1.25,0.,0.7071067811865476,0.7071067811865476,1.0606601717798214,1.0606601717798214,0.,0.5,0.,1.25,-0.7071067811865476,0.7071067811865476,-1.0606601717798214,1.0606601717798214,-0.5,0.,-1.25,0.,-0.7071067811865476,-0.7071067811865476,-1.0606601717798214,-1.0606601717798214,0.,-0.5,0.,-1.25,0.7071067811865476,-0.7071067811865476,1.0606601717798214,-1.0606601717798214,0.479425538604203,0.8775825618903728,0.8414709848078964,0.54030230586814,0.7191383079063044,1.3163738428355591,1.2622064772118446,0.8104534588022099,-0.877582561890373,0.4794255386042027,-0.5403023058681399,0.8414709848078964,-1.3163738428355596,0.7191383079063038,-0.8104534588022098,1.2622064772118446,-0.4794255386042031,-0.8775825618903728,-0.8414709848078965,-0.5403023058681399,-0.7191383079063045,-1.3163738428355591,-1.2622064772118449,-0.8104534588022098,0.8775825618903729,-0.47942553860420295,0.54030230586814,-0.8414709848078964,1.3163738428355594,-0.7191383079063043,0.8104534588022099,-1.2622064772118446] + for i in xrange(82): + self.assertAlmostEqual(expected5[i],m12.getCoords().getIJ(0,i),12); + pass + self.assertEqual(60,m12.getNodalConnectivity().getNumberOfTuples()); + self.assertEqual(9,m12.getNodalConnectivityIndex().getNumberOfTuples()); + self.assertEqual(expected3,m12.getNodalConnectivity().getValues()); + self.assertEqual(expected4,m12.getNodalConnectivityIndex().getValues()); + pass + + def testUMeshTessellate2DCurve1(self): + # A quarter of circle: + mcoords = [0.4,0.0, 0.0,-0.4, 0.283,-0.283] + mconnec = [0,1,2] + + m1 = MEDCouplingUMesh.New() + m1.setMeshDimension(1) + m1.allocateCells(1) + m1.insertNextCell(NORM_SEG3, mconnec) + + myCoords = DataArrayDouble.New(mcoords, 3, 2) + m1.setCoords(myCoords) + + m2 = m1.deepCpy() + m2.tessellate2DCurve(0.1) + # If the following raises, the test will fail automatically: + m2.checkCoherency1(0.0) # eps param not used + + def testIntersect2DMeshesTmp4(self): + m1Coords=[0.,0.,1.,0.,1.5,0.,0.,1.,0.,1.5,-1.,0.,-1.5,0.,0.,-1,0.,-1.5,0.5,0.,1.25,0.,0.70710678118654757,0.70710678118654757,1.0606601717798214,1.0606601717798214,0.,0.5,0.,1.25,-0.70710678118654757,0.70710678118654757,-1.0606601717798214,1.0606601717798214,-0.5,0.,-1.25,0.,-0.70710678118654757,-0.70710678118654757,-1.0606601717798214,-1.0606601717798214,0.,-0.5,0.,-1.25,0.70710678118654757,-0.70710678118654757,1.0606601717798214,-1.0606601717798214]; + m1Conn=[0,3,1,13,11,9, 3,4,2,1,14,12,10,11, 5,3,0,15,13,17, 6,4,3,5,16,14,15,18, 5,0,7,17,21,19, 6,5,7,8,18,19,22,20, 0,1,7,9,23,21, 1,2,8,7,10,24,22,23]; + m1=MEDCouplingUMesh.New(); + m1.setMeshDimension(2); + m1.allocateCells(8); + m1.insertNextCell(NORM_TRI6,6,m1Conn[0:6]); + m1.insertNextCell(NORM_QUAD8,8,m1Conn[6:14]); + m1.insertNextCell(NORM_TRI6,6,m1Conn[14:20]); + m1.insertNextCell(NORM_QUAD8,8,m1Conn[20:28]); + m1.insertNextCell(NORM_TRI6,6,m1Conn[28:34]); + m1.insertNextCell(NORM_QUAD8,8,m1Conn[34:42]); + m1.insertNextCell(NORM_TRI6,6,m1Conn[42:48]); + m1.insertNextCell(NORM_QUAD8,8,m1Conn[48:56]); + m1.finishInsertingCells(); + myCoords1=DataArrayDouble.New(); + myCoords1.setValues(m1Coords,25,2); + m1.setCoords(myCoords1); + # + m2Coords=[0.,0.,1.1,0.,1.1,1.,0.,1.,1.7,0.,1.7,1.,-1.1,1.,-1.1,0.,-1.7,0.,-1.7,1.,-1.7,-1,-1.1,-1.,0.,-1.,1.1,-1,1.7,-1.] + m2Conn=[0,3,2,1, 1,2,5,4, 7,6,3,0, 8,9,6,7, 7,0,12,11, 8,7,11,10, 0,1,13,12, 1,4,14,13] + m2=MEDCouplingUMesh.New(); + m2.setMeshDimension(2); + m2.allocateCells(8); + for i in xrange(8): + m2.insertNextCell(NORM_QUAD4,4,m2Conn[4*i:4*(i+1)]) + pass + m2.finishInsertingCells(); + myCoords2=DataArrayDouble.New(); + myCoords2.setValues(m2Coords,15,2); + m2.setCoords(myCoords2); + # + m3,d1,d2=MEDCouplingUMesh.Intersect2DMeshes(m2,m1,1e-10) + m3.unPolyze() + # + expected1=[0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7] + expected2=[0,1,1,-1,2,3,3,-1,4,5,5,-1,6,7,7,-1] + self.assertEqual(16,d1.getNumberOfTuples()); + self.assertEqual(16,d2.getNumberOfTuples()); + self.assertEqual(16,m3.getNumberOfCells()); + self.assertEqual(104,m3.getNumberOfNodes()); + self.assertEqual(2,m3.getSpaceDimension()); + self.assertEqual(expected1,d1.getValues()); + self.assertEqual(expected2,d2.getValues()); + expected3=[6,16,15,18,44,45,46,8,18,2,1,16,47,48,49,50,8,17,1,2,40,51,52,53,54,8,40,5,4,17,55,56,57,58,6,18,15,20,59,60,61,8,20,7,6,18,62,63,64,65,8,41,6,7,21,66,67,68,69,8,21,8,9,41,70,71,72,73,6,20,15,22,74,75,76,8,22,11,7,20,77,78,79,80,8,21,7,11,42,81,82,83,84,8,42,10,8,21,85,86,87,88,6,22,15,16,89,90,91,8,16,1,13,22,92,93,94,95,8,43,13,1,17,96,97,98,99,8,17,4,14,43,100,101,102,103] + expected4=[0,7,16,25,34,41,50,59,68,75,84,93,102,109,118,127,136] + expected5=[0.,0.,1.1, 0.,1.1,1.,0.,1.,1.7,0.,1.7,1.,-1.1,1.,-1.1,0.,-1.7,0.,-1.7,1.,-1.7,-1.,-1.1,-1.,0.,-1.,1.1,-1.,1.7,-1.,0.,0.,1.,0.,1.5,0.,0.,1.,0.,1.5,-1.,0.,-1.5,0.,0.,-1.,0.,-1.5,0.5,0.,1.25,0.,0.7071067811865476,0.7071067811865476,1.0606601717798214,1.0606601717798214,0.,0.5,0.,1.25,-0.7071067811865476,0.7071067811865476,-1.0606601717798214,1.0606601717798214,-0.5,0.,-1.25,0.,-0.7071067811865476,-0.7071067811865476,-1.0606601717798214,-1.0606601717798214,0.,-0.5,0.,-1.25,0.7071067811865476,-0.7071067811865476,1.0606601717798214,-1.0606601717798214,1.1180339887498951,1.,-1.1180339887498951,1.,-1.1180339887498951,-1.,1.1180339887498951,-1.,0.5,0.,0.,0.5,0.7071067811865477,0.7071067811865476,0.55,1.,1.1,0.5,1.05,0.,0.7071067811865477,0.7071067811865475,1.3,0.,1.1,0.5,1.1090169943749475,1.,1.4012585384440737,0.535233134659635,1.4090169943749475,1.,1.7,0.5,1.6,0.,1.4012585384440737,0.535233134659635,0.,0.5,-0.5,0.,-0.7071067811865477,0.7071067811865476,-1.05,0.,-1.1,0.5,-0.55,1.,-0.7071067811865478,0.7071067811865475,-1.1090169943749475,1.,-1.1,0.5,-1.3,0.,-1.4012585384440737,0.5352331346596344,-1.6,0.,-1.7,0.5,-1.4090169943749475,1.,-1.4012585384440737,0.5352331346596344,-0.5,0.,0.,-0.5,-0.7071067811865475,-0.7071067811865477,-0.55,-1.,-1.1,-0.5,-1.05,0.,-0.7071067811865475,-0.7071067811865477,-1.3,0.,-1.1,-0.5,-1.1090169943749475,-1.,-1.4012585384440734,-0.5352331346596354,-1.4090169943749475,-1.,-1.7,-0.5,-1.6,0.,-1.4012585384440732,-0.5352331346596354,0.,-0.5,0.5,0.,0.7071067811865475,-0.7071067811865477,1.05,0.,1.1,-0.5,0.55,-1.,0.7071067811865475,-0.7071067811865477,1.1090169943749475,-1.,1.1,-0.5,1.3,0.,1.4012585384440737,-0.535233134659635,1.6,0.,1.7,-0.5,1.4090169943749475,-1.,1.4012585384440737,-0.535233134659635] + self.assertEqual(136,m3.getNodalConnectivity().getNumberOfTuples()); + self.assertEqual(17,m3.getNodalConnectivityIndex().getNumberOfTuples()); + self.assertEqual(expected3,m3.getNodalConnectivity().getValues()); + self.assertEqual(expected4,m3.getNodalConnectivityIndex().getValues()); + for i in xrange(208): + self.assertAlmostEqual(expected5[i],m3.getCoords().getIJ(0,i),12); + pass + pass + + def testGetCellIdsCrossingPlane1(self): + mesh3D,mesh2D=MEDCouplingDataForTest.build3DExtrudedUMesh_1(); + vec=[-0.07,1.,0.07] + origin=[1.524,1.4552,1.74768] + ids1=mesh3D.getCellIdsCrossingPlane(origin,vec,1e-10) + self.assertEqual([1,3,4,7,9,10,13,15,16],ids1.getValues()) + vec2=[0.,0.,1.] + ids2=mesh3D.getCellIdsCrossingPlane(origin,vec2,1e-10) + self.assertEqual([6,7,8,9,10,11],ids2.getValues()) + pass + + def testBuildSlice3D1(self): + mesh3D,mesh2D=MEDCouplingDataForTest.build3DExtrudedUMesh_1(); + vec1=[-0.07,1.,0.07] + origin1=[1.524,1.4552,1.74768] + slice1,ids=mesh3D.buildSlice3D(origin1,vec1,1e-10); + expected1=[1,3,4,7,9,10,13,15,16] + expected2=[5,42,41,40,43,44,5,42,46,45,41,5,44,43,40,47,48,5,49,42,44,50,5,49,51,46,42,5,50,44,48,52,5,53,49,50,54,5,53,55,51,49,5,54,50,52,56] + expected3=[0,6,11,17,22,27,32,37,42,47] + expected4=[1.,1.,0.,1.,1.25,0.,1.,1.5,0.,2.,1.,0.,1.,2.,0.,0.,2.,0.,3.,1.,0.,3.,2.,0.,0.,1.,0.,2.,2.,0.,1.,1.,1.,1.,1.25,1.,1.,1.5,1.,2.,1.,1.,1.,2.,1.,0.,2.,1.,3.,1.,1.,3.,2.,1.,0.,1.,1.,2.,2.,1.,1.,1.,2.,1.,1.25,2.,1.,1.5,2.,2.,1.,2.,1.,2.,2.,0.,2.,2.,3.,1.,2.,3.,2.,2.,0.,1.,2.,2.,2.,2.,1.,1.,3.,1.,1.25,3.,1.,1.5,3.,2.,1.,3.,1.,2.,3.,0.,2.,3.,3.,1.,3.,3.,2.,3.,0.,1.,3.,2.,2.,3.,1.,1.5408576,0.,2.,1.6108576000000001,0.,2.,1.5408576,1.,1.,1.5,0.5836800000000008,1.,1.4708576,1.,3.,1.6808576,0.,3.,1.6108576000000001,1.,0.,1.4708576,0.,0.,1.4008576,1.,2.,1.4708576,2.,1.,1.4008576000000001,2.,3.,1.5408575999999998,2.,0.,1.3308575999999999,2.,2.,1.4008576,3.,1.,1.3308576,3.,3.,1.4708576,3.,0.,1.2608576,3.] + self.assertEqual(2,slice1.getMeshDimension()); + self.assertEqual(3,slice1.getSpaceDimension()); + self.assertEqual(57,slice1.getNumberOfNodes()); + self.assertEqual(9,slice1.getNumberOfCells()); + self.assertEqual(9,ids.getNumberOfTuples()); + self.assertEqual(47,slice1.getNodalConnectivity().getNumberOfTuples()); + self.assertEqual(10,slice1.getNodalConnectivityIndex().getNumberOfTuples()); + self.assertEqual(expected1,ids.getValues()); + self.assertEqual(expected2,slice1.getNodalConnectivity().getValues()); + self.assertEqual(expected3,slice1.getNodalConnectivityIndex().getValues()); + for i in xrange(171): + self.assertAlmostEqual(expected4[i],slice1.getCoords().getIJ(0,i),12); + pass + # 2nd slice based on already existing nodes of mesh3D. + vec2=[0.,3.,1.] + origin2=[2.5,1.,3.] + slice1,ids=mesh3D.buildSlice3D(origin2,vec2,1e-10); + expected5=[5,50,10,4,51,5,50,52,7,10,5,51,4,5,53,5,54,50,51,55,56,5,54,57,52,50,5,56,55,51,53,58,5,38,59,56,54,43,5,54,57,46,43,5,38,59,56,58,48] + expected6=[0,5,10,15,21,26,32,38,43,49] + expected7=[1.,1.,0.,1.,1.25,0.,1.,1.5,0.,2.,1.,0.,1.,2.,0.,0.,2.,0.,3.,1.,0.,3.,2.,0.,0.,1.,0.,1.,3.,0.,2.,2.,0.,2.,3.,0.,1.,1.,1.,1.,1.25,1.,1.,1.5,1.,2.,1.,1.,1.,2.,1.,0.,2.,1.,3.,1.,1.,3.,2.,1.,0.,1.,1.,1.,3.,1.,2.,2.,1.,2.,3.,1.,0.,0.,2.,1.,1.,2.,1.,1.25,2.,1.,0.,2.,1.,1.5,2.,2.,0.,2.,2.,1.,2.,1.,2.,2.,0.,2.,2.,3.,1.,2.,3.,2.,2.,0.,1.,2.,2.,2.,2.,0.,0.,3.,1.,1.,3.,1.,1.25,3.,1.,0.,3.,1.,1.5,3.,2.,0.,3.,2.,1.,3.,1.,2.,3.,0.,2.,3.,3.,1.,3.,3.,2.,3.,0.,1.,3.,2.,2.,3.,2.,1.6666666666666667,1.,1.,1.6666666666666667,1.,3.,1.6666666666666667,1.,0.,1.6666666666666667,1.,2.,1.3333333333333335,2.,1.,1.5,1.5,1.,1.3333333333333333,2.,3.,1.3333333333333335,2.,0.,1.3333333333333335,2.,1.,1.25,2.25] + self.assertEqual(2,slice1.getMeshDimension()); + self.assertEqual(3,slice1.getSpaceDimension()); + self.assertEqual(60,slice1.getNumberOfNodes()); + self.assertEqual(9,slice1.getNumberOfCells()); + self.assertEqual(9,ids.getNumberOfTuples()); + self.assertEqual(49,slice1.getNodalConnectivity().getNumberOfTuples()); + self.assertEqual(10,slice1.getNodalConnectivityIndex().getNumberOfTuples()); + self.assertEqual(expected1,ids.getValues()); + self.assertEqual(expected5,slice1.getNodalConnectivity().getValues()); + self.assertEqual(expected6,slice1.getNodalConnectivityIndex().getValues()); + for i in xrange(180): + self.assertAlmostEqual(expected7[i],slice1.getCoords().getIJ(0,i),12); + pass + # 3rd slice based on shared face of mesh3D. + vec3=[0.,0.,1.] + origin3=[2.5,1.,2.] + slice1,ids=mesh3D.buildSlice3D(origin3,vec3,1e-10); + expected8=[6,7,8,9,10,11,12,13,14,15,16,17] + expected9=[5,15,26,16,18,5,16,21,28,22,19,17,5,18,20,21,16,5,21,24,25,28,5,26,16,17,19,22,23,5,22,27,29,28,5,15,26,16,18,5,16,21,28,22,19,17,5,18,20,21,16,5,21,24,25,28,5,26,16,17,19,22,23,5,22,27,29,28] + expected10=[0,5,12,17,22,29,34,39,46,51,56,63,68] + expected11=[0.,0.,1.,1.,1.,1.,1.,1.25,1.,1.,0.,1.,1.,1.5,1.,2.,0.,1.,2.,1.,1.,1.,2.,1.,0.,2.,1.,3.,1.,1.,3.,2.,1.,0.,1.,1.,1.,3.,1.,2.,2.,1.,2.,3.,1.,0.,0.,2.,1.,1.,2.,1.,1.25,2.,1.,0.,2.,1.,1.5,2.,2.,0.,2.,2.,1.,2.,1.,2.,2.,0.,2.,2.,3.,1.,2.,3.,2.,2.,0.,1.,2.,1.,3.,2.,2.,2.,2.,2.,3.,2.,0.,0.,3.,1.,1.,3.,1.,1.25,3.,1.,0.,3.,1.,1.5,3.,2.,0.,3.,2.,1.,3.,1.,2.,3.,0.,2.,3.,3.,1.,3.,3.,2.,3.,0.,1.,3.,1.,3.,3.,2.,2.,3.,2.,3.,3.] + self.assertEqual(2,slice1.getMeshDimension()); + self.assertEqual(3,slice1.getSpaceDimension()); + self.assertEqual(45,slice1.getNumberOfNodes()); + self.assertEqual(12,slice1.getNumberOfCells()); + self.assertEqual(12,ids.getNumberOfTuples()); + self.assertEqual(68,slice1.getNodalConnectivity().getNumberOfTuples()); + self.assertEqual(13,slice1.getNodalConnectivityIndex().getNumberOfTuples()); + self.assertEqual(expected8,ids.getValues()); + self.assertEqual(expected9,slice1.getNodalConnectivity().getValues()); + self.assertEqual(expected10,slice1.getNodalConnectivityIndex().getValues()); + for i in xrange(135): + self.assertAlmostEqual(expected11[i],slice1.getCoords().getIJ(0,i),12); + pass + pass + + def testBuildSlice3DSurf1(self): + mesh3D,mesh2D=MEDCouplingDataForTest.build3DExtrudedUMesh_1(); + mesh2D=mesh3D.buildDescendingConnectivity()[0]; + vec1=[-0.07,1.,0.07] + origin1=[1.524,1.4552,1.74768] + slice1,ids=mesh2D.buildSlice3DSurf(origin1,vec1,1e-10); + expected1=[6,8,10,11,13,18,19,21,23,25,26,38,41,43,47,49,52,53,64,67,69,73,75,78,79] + expected2=[1,40,41,1,42,41,1,40,43,1,44,43,1,42,44,1,45,41,1,42,46,1,46,45,1,47,40,1,47,48,1,44,48,1,49,42,1,44,50,1,49,50,1,49,51,1,51,46,1,48,52,1,50,52,1,53,49,1,50,54,1,53,54,1,53,55,1,55,51,1,52,56,1,54,56] + expected3=[0,3,6,9,12,15,18,21,24,27,30,33,36,39,42,45,48,51,54,57,60,63,66,69,72,75]; + expected4=[1.,1.,0.,1.,1.25,0.,1.,1.5,0.,2.,1.,0.,1.,2.,0.,0.,2.,0.,3.,1.,0.,3.,2.,0.,0.,1.,0.,2.,2.,0.,1.,1.,1.,1.,1.25,1.,1.,1.5,1.,2.,1.,1.,1.,2.,1.,0.,2.,1.,3.,1.,1.,3.,2.,1.,0.,1.,1.,2.,2.,1.,1.,1.,2.,1.,1.25,2.,1.,1.5,2.,2.,1.,2.,1.,2.,2.,0.,2.,2.,3.,1.,2.,3.,2.,2.,0.,1.,2.,2.,2.,2.,1.,1.,3.,1.,1.25,3.,1.,1.5,3.,2.,1.,3.,1.,2.,3.,0.,2.,3.,3.,1.,3.,3.,2.,3.,0.,1.,3.,2.,2.,3.,1.,1.5408576,0.,2.,1.6108576000000001,0.,2.,1.5408576,1.,1.,1.5,0.5836800000000008,1.,1.4708576,1.,3.,1.6808576,0.,3.,1.6108576000000001,1.,0.,1.4708576,0.,0.,1.4008576,1.,2.,1.4708576,2.,1.,1.4008576000000001,2.,3.,1.5408575999999998,2.,0.,1.3308575999999999,2.,2.,1.4008576,3.,1.,1.3308576,3.,3.,1.4708576,3.,0.,1.2608576,3.] + self.assertEqual(1,slice1.getMeshDimension()); + self.assertEqual(3,slice1.getSpaceDimension()); + self.assertEqual(57,slice1.getNumberOfNodes()); + self.assertEqual(25,slice1.getNumberOfCells()); + self.assertEqual(25,ids.getNumberOfTuples()); + self.assertEqual(75,slice1.getNodalConnectivity().getNumberOfTuples()); + self.assertEqual(26,slice1.getNodalConnectivityIndex().getNumberOfTuples()); + self.assertEqual(expected1,ids.getValues()); + self.assertEqual(expected2,slice1.getNodalConnectivity().getValues()); + self.assertEqual(expected3,slice1.getNodalConnectivityIndex().getValues()); + for i in xrange(171): + self.assertAlmostEqual(expected4[i],slice1.getCoords().getIJ(0,i),12); + pass + # + vec2=[0.,0.,1.] + origin2=[2.5,1.,2.] + slice1,ids=mesh2D.buildSlice3DSurf(origin2,vec2,1e-10); + expected5=[32,32,32,32,33,34,35,36,37,38,39,40,41,42,43,43,43,43,43,43,44,44,44,44,45,46,47,47,47,47,48,49,50,51,52,53,53,53,53,53,53,54,54,54,54,55,56,57,59,60,61,62,63,64,65,66,67,68,71,72,74,75,76,77,78,81,82,83] + expected6=[1,15,18,1,18,16,1,16,26,1,26,15,1,26,15,1,16,26,1,18,16,1,15,18,1,16,21,1,21,28,1,22,28,1,19,22,1,17,19,1,16,17,1,16,21,1,21,28,1,28,22,1,22,19,1,19,17,1,17,16,1,16,18,1,18,20,1,20,21,1,21,16,1,20,21,1,18,20,1,28,21,1,21,24,1,24,25,1,25,28,1,25,28,1,24,25,1,21,24,1,23,22,1,26,23,1,26,16,1,16,17,1,17,19,1,19,22,1,22,23,1,23,26,1,22,28,1,28,29,1,29,27,1,27,22,1,27,22,1,29,27,1,28,29,1,26,15,1,16,26,1,18,16,1,15,18,1,16,21,1,21,28,1,22,28,1,19,22,1,17,19,1,16,17,1,20,21,1,18,20,1,25,28,1,24,25,1,21,24,1,23,22,1,26,23,1,27,22,1,29,27,1,28,29] + expected7=[0,3,6,9,12,15,18,21,24,27,30,33,36,39,42,45,48,51,54,57,60,63,66,69,72,75,78,81,84,87,90,93,96,99,102,105,108,111,114,117,120,123,126,129,132,135,138,141,144,147,150,153,156,159,162,165,168,171,174,177,180,183,186,189,192,195,198,201,204]; + expected8=[0.,0.,1.,1.,1.,1.,1.,1.25, 1.,1.,0.,1.,1.,1.5, 1.,2.,0.,1.,2.,1.,1.,1.,2.,1.,0.,2.,1.,3.,1.,1.,3.,2.,1.,0.,1.,1.,1.,3.,1.,2.,2.,1.,2.,3.,1.,0.,0.,2.,1.,1.,2.,1.,1.25, 2.,1.,0.,2.,1.,1.5, 2.,2.,0.,2.,2.,1.,2.,1.,2.,2.,0.,2.,2.,3.,1.,2.,3.,2.,2.,0.,1.,2.,1.,3.,2.,2.,2.,2.,2.,3.,2.,0.,0.,3.,1.,1.,3.,1.,1.25, 3.,1.,0.,3.,1.,1.5, 3.,2.,0.,3.,2.,1.,3.,1.,2.,3.,0.,2.,3.,3.,1.,3.,3.,2.,3.,0.,1.,3.,1.,3.,3.,2.,2.,3.,2.,3.,3.] + self.assertEqual(1,slice1.getMeshDimension()); + self.assertEqual(3,slice1.getSpaceDimension()); + self.assertEqual(45,slice1.getNumberOfNodes()); + self.assertEqual(68,slice1.getNumberOfCells()); + self.assertEqual(68,ids.getNumberOfTuples()); + self.assertEqual(204,slice1.getNodalConnectivity().getNumberOfTuples()); + self.assertEqual(69,slice1.getNodalConnectivityIndex().getNumberOfTuples()); + self.assertEqual(expected5,ids.getValues()); + self.assertEqual(expected6,slice1.getNodalConnectivity().getValues()); + self.assertEqual(expected7,slice1.getNodalConnectivityIndex().getValues()); + for i in xrange(135): + self.assertAlmostEqual(expected8[i],slice1.getCoords().getIJ(0,i),12); + pass + pass + + def testDataArrayDoubleAdvSetting1(self): + data1=[1.,11.,2.,12.,3.,13.,4.,14.,5.,15.,6.,16.,7.,17.] + data2=[8.,38.,9.,39.,0.,30.,11.,41.,12.,42.] + compsCpp=["comp1","comp2"] + da=DataArrayDouble.New(); + da.setInfoAndChangeNbOfCompo(compsCpp); + da.setName("da"); + da.alloc(7,2); + compsCpp=compsCpp[:-1] + self.assertRaises(InterpKernelException,da.setInfoAndChangeNbOfCompo,compsCpp); + da.setValues(data1,7,2) + # + p=[(0,3),(3,5),(5,7)] + tmp=da.selectByTupleRanges(p); + self.assertTrue(tmp.isEqual(da,1e-14)); + p=[(0,2),(3,4),(5,7)] + tmp=da.selectByTupleRanges(p); + expected1=[1.,11.,2.,12.,4.,14.,6.,16.,7.,17.] + self.assertEqual(5,tmp.getNumberOfTuples()); + self.assertEqual(2,tmp.getNumberOfComponents()); + for i in xrange(10): + self.assertAlmostEqual(expected1[i],tmp.getIJ(0,i),14); + pass + p=[(0,2),(0,2),(5,6)] + tmp=da.selectByTupleRanges(p); + expected2=[1.,11.,2.,12.,1.,11.,2.,12.,6.,16.] + self.assertEqual(5,tmp.getNumberOfTuples()); + self.assertEqual(2,tmp.getNumberOfComponents()); + for i in xrange(10): + self.assertAlmostEqual(expected2[i],tmp.getIJ(0,i),14); + pass + p=[(0,2),(-1,2),(5,6)] + self.assertRaises(InterpKernelException,da.selectByTupleRanges,p); + p=[(0,2),(0,2),(5,8)] + self.assertRaises(InterpKernelException,da.selectByTupleRanges,p); + # + da2=DataArrayDouble.New(); + da2.setValues(data2,5,2); + # + dac=da.deepCpy(); + dac.setContigPartOfSelectedValues2(1,da2,2,4,1); + expected3=[1.,11.,0.,30.,11.,41.,4.,14.,5.,15.,6.,16.,7.,17.] + for i in xrange(14): + self.assertAlmostEqual(expected3[i],dac.getIJ(0,i),14); + pass + # + dac=da.deepCpy(); + self.assertRaises(InterpKernelException,dac.setContigPartOfSelectedValues2,3,da2,0,5,1); + self.assertRaises(InterpKernelException,dac.setContigPartOfSelectedValues2,0,da2,4,6,1); + self.assertRaises(InterpKernelException,dac.setContigPartOfSelectedValues2,3,da2,5,0,1); + dac.setContigPartOfSelectedValues2(3,da2,1,5,1); + expected4=[1.,11.,2.,12.,3.,13.,9.,39.,0.,30.,11.,41.,12.,42.] + for i in xrange(14): + self.assertAlmostEqual(expected4[i],dac.getIJ(0,i),14); + pass + # + ids=DataArrayInt.New(); + ids.alloc(3,1); + dac=da.deepCpy(); + ids.setIJ(0,0,2); ids.setIJ(1,0,0); ids.setIJ(2,0,4); + dac.setContigPartOfSelectedValues(2,da2,ids); + expected5=[1.,11.,2.,12.,0.,30.,8.,38.,12.,42.,6.,16.,7.,17.] + for i in xrange(14): + self.assertAlmostEqual(expected5[i],dac.getIJ(0,i),14); + pass + # + dac=da.deepCpy(); + ids.setIJ(0,0,2); ids.setIJ(1,0,5); ids.setIJ(2,0,4); + self.assertRaises(InterpKernelException,dac.setContigPartOfSelectedValues,1,da2,ids); + ids.setIJ(0,0,2); ids.setIJ(1,0,2); ids.setIJ(2,0,-1); + self.assertRaises(InterpKernelException,dac.setContigPartOfSelectedValues,1,da2,ids); + ids.setIJ(0,0,2); ids.setIJ(1,0,2); ids.setIJ(2,0,1); + self.assertRaises(InterpKernelException,dac.setContigPartOfSelectedValues,5,da2,ids); + # + ids.setIJ(0,0,2); ids.setIJ(1,0,2); ids.setIJ(2,0,1); + dac=da.deepCpy(); + dac.setContigPartOfSelectedValues(4,da2,ids); + expected6=[1.,11.,2.,12.,3.,13.,4.,14.,0.,30.,0.,30.,9.,39.] + for i in xrange(14): + self.assertAlmostEqual(expected6[i],dac.getIJ(0,i),14); + pass + pass + + def testDataArrayIntAdvSetting1(self): + data1=[1,11,2,12,3,13,4,14,5,15,6,16,7,17] + data2=[8,38,9,39,0,30,11,41,12,42] + compsCpp=["comp1","comp2"] + da=DataArrayInt.New(); + da.setInfoAndChangeNbOfCompo(compsCpp); + da.setName("da"); + da.alloc(7,2); + compsCpp=compsCpp[:-1] + self.assertRaises(InterpKernelException,da.setInfoAndChangeNbOfCompo,compsCpp); + da.setValues(data1,7,2) + # + p=[(0,3),(3,5),(5,7)] + tmp=da.selectByTupleRanges(p); + self.assertTrue(tmp.isEqual(da)); + p=[(0,2),(3,4),(5,7)] + tmp=da.selectByTupleRanges(p); + expected1=[1,11,2,12,4,14,6,16,7,17] + self.assertEqual(5,tmp.getNumberOfTuples()); + self.assertEqual(2,tmp.getNumberOfComponents()); + for i in xrange(10): + self.assertEqual(expected1[i],tmp.getIJ(0,i)); + pass + p=[(0,2),(0,2),(5,6)] + tmp=da.selectByTupleRanges(p); + expected2=[1,11,2,12,1,11,2,12,6,16] + self.assertEqual(5,tmp.getNumberOfTuples()); + self.assertEqual(2,tmp.getNumberOfComponents()); + for i in xrange(10): + self.assertEqual(expected2[i],tmp.getIJ(0,i)); + pass + p=[(0,2),(-1,2),(5,6)] + self.assertRaises(InterpKernelException,da.selectByTupleRanges,p); + p=[(0,2),(0,2),(5,8)] + self.assertRaises(InterpKernelException,da.selectByTupleRanges,p); + # + da2=DataArrayInt.New(); + da2.setValues(data2,5,2); + # + dac=da.deepCpy(); + dac.setContigPartOfSelectedValues2(1,da2,2,4,1); + expected3=[1,11,0,30,11,41,4,14,5,15,6,16,7,17] + for i in xrange(14): + self.assertEqual(expected3[i],dac.getIJ(0,i)); + pass + # + dac=da.deepCpy(); + self.assertRaises(InterpKernelException,dac.setContigPartOfSelectedValues2,3,da2,0,5,1); + self.assertRaises(InterpKernelException,dac.setContigPartOfSelectedValues2,0,da2,4,6,1); + self.assertRaises(InterpKernelException,dac.setContigPartOfSelectedValues2,3,da2,5,0,1); + dac.setContigPartOfSelectedValues2(3,da2,1,5,1); + expected4=[1,11,2,12,3,13,9,39,0,30,11,41,12,42] + for i in xrange(14): + self.assertEqual(expected4[i],dac.getIJ(0,i)); + pass + # + ids=DataArrayInt.New(); + ids.alloc(3,1); + dac=da.deepCpy(); + ids.setIJ(0,0,2); ids.setIJ(1,0,0); ids.setIJ(2,0,4); + dac.setContigPartOfSelectedValues(2,da2,ids); + expected5=[1,11,2,12,0,30,8,38,12,42,6,16,7,17] + for i in xrange(14): + self.assertEqual(expected5[i],dac.getIJ(0,i)); + pass + # + dac=da.deepCpy(); + ids.setIJ(0,0,2); ids.setIJ(1,0,5); ids.setIJ(2,0,4); + self.assertRaises(InterpKernelException,dac.setContigPartOfSelectedValues,1,da2,ids); + ids.setIJ(0,0,2); ids.setIJ(1,0,2); ids.setIJ(2,0,-1); + self.assertRaises(InterpKernelException,dac.setContigPartOfSelectedValues,1,da2,ids); + ids.setIJ(0,0,2); ids.setIJ(1,0,2); ids.setIJ(2,0,1); + self.assertRaises(InterpKernelException,dac.setContigPartOfSelectedValues,5,da2,ids); + # + ids.setIJ(0,0,2); ids.setIJ(1,0,2); ids.setIJ(2,0,1); + dac=da.deepCpy(); + dac.setContigPartOfSelectedValues(4,da2,ids); + expected6=[1,11,2,12,3,13,4,14,0,30,0,30,9,39] + for i in xrange(14): + self.assertEqual(expected6[i],dac.getIJ(0,i)); + pass + pass + + def testBuildDescendingConnec2Of3DMesh1(self): + mesh=MEDCouplingDataForTest.build3DSourceMesh_1(); + # + mesh2,desc,descIndx,revDesc,revDescIndx=mesh.buildDescendingConnectivity2(); + mesh2.checkCoherency(); + self.assertEqual(2,mesh2.getMeshDimension()); + self.assertEqual(30,mesh2.getNumberOfCells()); + self.assertEqual(31,revDescIndx.getNbOfElems()); self.assertEqual(31,revDescIndx.getNumberOfTuples()); + self.assertEqual(13,descIndx.getNbOfElems()); self.assertEqual(13,descIndx.getNumberOfTuples()); + self.assertEqual(48,desc.getNbOfElems()); self.assertEqual(48,desc.getNumberOfTuples()); + self.assertEqual(48,revDesc.getNbOfElems()); self.assertEqual(48,revDesc.getNumberOfTuples()); + expected1=[1,2,3,4,5,6,7,8,9,10,11,12,13,14,-10,15,-5,-13,16,17,-14,18,-4,19,-2,20,21,22,23,24,25,-11,26,-1,-12,-25,-22,27,28,-7,-20,-24,29,-16,-18,30,-8,-28] + self.assertEqual(expected1,desc.getValues()); + expected2=[0,4,8,12,16,20,24,28,32,36,40,44,48] + self.assertEqual(expected2,descIndx.getValues()); + expected3=[0,2,4,5,7,9,10,12,14,15,17,19,21,23,25,26,28,29,31,32,34,35,37,38,40,42,43,44,46,47,48] + self.assertEqual(expected3,revDescIndx.getValues()); + expected4=[0,8,0,6,0,0,5,1,4,1,1,9,1,11,2,2,3,2,7,2,8,3,4,3,5,3,4,10,4,5,11,5,6,10,6,6,9,7,7,10,7,8,8,9,9,11,10,11] + self.assertEqual(expected4,revDesc.getValues()); + conn=mesh2.getNodalConnectivity(); + connIndex=mesh2.getNodalConnectivityIndex(); + expected5=[0,4,8,12,16,20,24,28,32,36,40,44,48,52,56,60,64,68,72,76,80,84,88,92,96,100,104,108,112,116,120] + self.assertEqual(expected5,connIndex.getValues()); + expected6=[3,8,1,7,3,8,3,1,3,1,3,7,3,7,3,8,3,6,0,8,3,6,2,0,3,0,2,8,3,8,2,6,3,7,4,5,3,7,8,4,3,4,8,5,3,5,8,7,3,6,8,4,3,6,7,8,3,4,7,6,3,8,4,0,3,0,4,6,3,6,3,8,3,7,3,6,3,8,0,1,3,1,0,3,3,3,0,8,3,4,1,5,3,4,8,1,3,1,8,5,3,1,7,5,3,0,2,3,3,3,2,8,3,1,4,0,3,3,2,6] + self.assertEqual(expected6,conn.getValues()); + pass + + def testAre2DCellsNotCorrectlyOriented1(self): + m1Coords=[1.,1.,-1.,-1.,-1.,-1.,1.,-1.] + m1Conn=[0,3,1,2] + m1=MEDCouplingUMesh.New(); + m1.setMeshDimension(2); + m1.allocateCells(1); + m1.insertNextCell(NORM_QUAD4,4,m1Conn[0:4]) + m1.finishInsertingCells(); + myCoords1=DataArrayDouble.New(); + myCoords1.setValues(m1Coords,4,2); + m1.setCoords(myCoords1); + # + vec1=[0.,0.,1.] + for i in xrange(18): + vec2=[3.*cos(pi/9.*i),3.*sin(pi/9.*i)]; + m1Cpy=m1.deepCpy(); + m1Cpy.translate(vec2); + self.assertRaises(InterpKernelException,m1Cpy.are2DCellsNotCorrectlyOriented,vec1,False); + m1Cpy.changeSpaceDimension(3); + res=m1Cpy.are2DCellsNotCorrectlyOriented(vec1,False) + self.assertEqual([0],res.getValues()); + pass + pass + + def testDataArrayAbs1(self): + d1=DataArrayDouble.New(); + val1=[2.,-3.,-5.,6.,-7.,-8.,9.,10.,-11.,-12.,-13.,-15.] + expected1=[2.,3.,5.,6.,7.,8.,9.,10.,11.,12.,13.,15.] + d1.setValues(val1,6,2); + d2=d1.convertToIntArr(); + # + d1.abs(); + for i in xrange(12): + self.assertAlmostEqual(expected1[i],d1.getIJ(0,i),14); + pass + # + expected2=[2,3,5,6,7,8,9,10,11,12,13,15] + d2.abs(); + for i in xrange(12): + self.assertEqual(expected2[i],d2.getIJ(0,i)); + pass + # + pass + + # test on 1D + def testGetValueOn3(self): + v=[0.,1.,1.5,2.] + v2=[0.7,1.25,0.,2.,1.5] + disp=[5.,50.,500.,6.,60.,600.,7.,70.,700.,8.,80.,800.] + m=MEDCouplingUMesh.New("myMesh",1) + nbNodes=len(v) + nbCells=nbNodes-1 + m.allocateCells(nbCells) + coords=DataArrayDouble.New() ; coords.setValues(v,nbNodes,1) + m.setCoords(coords) + m.insertNextCell(NORM_SEG2,2,[0,1]) + m.insertNextCell(NORM_SEG2,2,[2,1]) + m.insertNextCell(NORM_SEG2,2,[2,3]) + m.finishInsertingCells() + f=MEDCouplingFieldDouble.New(ON_NODES) + f.setMesh(m) + array=DataArrayDouble.New(); array.setValues(disp,m.getNumberOfNodes(),3) + f.setArray(array) + arr1=f.getValueOnMulti(v2) + self.assertEqual(5,arr1.getNumberOfTuples()); + self.assertEqual(3,arr1.getNumberOfComponents()); + expected1=[5.7,57.,570.,6.5,65.,650.,5.,50.,500.,8.,80.,800.,7.,70.,700.] + for i in xrange(15): + self.assertAlmostEqual(expected1[i],arr1.getIJ(0,i),14); + pass + pass + + def testGetNodeIdsOfCell2(self): + m1c=MEDCouplingCMesh.New(); + coordsX=DataArrayDouble.New(); + arrX=[ -1., 1., 2., 4., 4.5 ] + coordsX.setValues(arrX,5,1); + coordsY=DataArrayDouble.New(); + arrY=[ -2., 2., 4., 8.] + coordsY.setValues(arrY,4,1); + coordsZ=DataArrayDouble.New(); + arrZ=[ -2., 2., 4.] + coordsZ.setValues(arrZ,3,1); + # test in 1D + m1c.setCoordsAt(0,coordsX); + expected1=[[0,1],[1,2],[2,3],[3,4]] + self.assertEqual(4,m1c.getNumberOfCells()) + for i in xrange(m1c.getNumberOfCells()): + self.assertEqual(expected1[i],m1c.getNodeIdsOfCell(i)) + pass + # test in 2D + m1c.setCoordsAt(1,coordsY); + self.assertEqual(12,m1c.getNumberOfCells()) + self.assertEqual(20,m1c.getNumberOfNodes()) + expected2=[[0,1,6,5],[1,2,7,6],[2,3,8,7],[3,4,9,8],[5,6,11,10],[6,7,12,11],[7,8,13,12],[8,9,14,13],[10,11,16,15],[11,12,17,16],[12,13,18,17],[13,14,19,18]] + for i in xrange(m1c.getNumberOfCells()): + self.assertEqual(expected2[i],m1c.getNodeIdsOfCell(i)) + pass + # test in 3D + m1c.setCoordsAt(2,coordsZ); + self.assertEqual(24,m1c.getNumberOfCells()) + self.assertEqual(60,m1c.getNumberOfNodes()) + expected3=[[0,1,6,5,20,21,26,25],[1,2,7,6,21,22,27,26],[2,3,8,7,22,23,28,27],[3,4,9,8,23,24,29,28],[5,6,11,10,25,26,31,30],[6,7,12,11,26,27,32,31],[7,8,13,12,27,28,33,32],[8,9,14,13,28,29,34,33],[10,11,16,15,30,31,36,35],[11,12,17,16,31,32,37,36],[12,13,18,17,32,33,38,37],[13,14,19,18,33,34,39,38],[20,21,26,25,40,41,46,45],[21,22,27,26,41,42,47,46],[22,23,28,27,42,43,48,47],[23,24,29,28,43,44,49,48],[25,26,31,30,45,46,51,50],[26,27,32,31,46,47,52,51],[27,28,33,32,47,48,53,52],[28,29,34,33,48,49,54,53],[30,31,36,35,50,51,56,55],[31,32,37,36,51,52,57,56],[32,33,38,37,52,53,58,57],[33,34,39,38,53,54,59,58]] + self.assertEqual(24,m1c.getNumberOfCells()) + for i in xrange(m1c.getNumberOfCells()): + self.assertEqual(expected3[i],m1c.getNodeIdsOfCell(i)) + pass + pass + + def testSwigDADOp4(self): + da=DataArrayDouble.New(range(6,30),12,2) + self.assertEqual(12,da.getNumberOfTuples()); + self.assertEqual(2,da.getNumberOfComponents()); + for i in xrange(24): + self.assertAlmostEqual(da.getIJ(0,i),float(i+6),13) + pass + # operator transpose + da.transpose() + self.assertEqual(2,da.getNumberOfTuples()); + self.assertEqual(12,da.getNumberOfComponents()); + for i in xrange(24): + self.assertAlmostEqual(da.getIJ(0,i),float(i+6),13) + pass + da.transpose() + # operator __neg__ + da2=DataArrayDouble.New(12,1) + da2.iota(0.) + dabis=-da + for i in xrange(24): + self.assertAlmostEqual(dabis.getIJ(0,i),-float(i+6),13) + pass + # operator+= + da+=da2 + expected1=[6.,7.,9.,10.,12.,13.,15.,16.,18.,19.,21.,22.,24.,25.,27.,28.,30.,31.,33.,34.,36.,37.,39.,40.] + for i in xrange(24): + self.assertAlmostEqual(da.getIJ(0,i),expected1[i],13) + pass + da=-dabis + da+=[100.,101.] + expected2=[106.,108.,108.,110.,110.,112.,112.,114.,114.,116.,116.,118.,118.,120.,120.,122.,122.,124.,124.,126.,126.,128.,128.,130.] + self.assertEqual(12,da.getNumberOfTuples()); + self.assertEqual(2,da.getNumberOfComponents()); + for i in xrange(24): + self.assertAlmostEqual(da.getIJ(0,i),expected2[i],13) + pass + for pos,elt in enumerate(dabis): + da[pos]+=elt + pass + self.assertEqual(12,da.getNumberOfTuples()); + self.assertEqual(2,da.getNumberOfComponents()); + for elt in da: + li=elt[:] + self.assertAlmostEqual(li[0],100.,13) ; self.assertAlmostEqual(li[1],101.,13) + pass + # operator-= + da=DataArrayDouble.New(range(6,30),12,2) + da2=DataArrayDouble.New(range(12),12,1) + dabis=-da + da-=da2 + expected1=[6.,7.,7.,8.,8.,9.,9.,10.,10.,11.,11.,12.,12.,13.,13.,14.,14.,15.,15.,16.,16.,17.,17.,18.] + for i in xrange(24): + self.assertAlmostEqual(da.getIJ(0,i),expected1[i],13) + pass + da=-dabis + da-=[100.,101.] + expected2=[-94.,-94.,-92.,-92.,-90.,-90.,-88.,-88.,-86.,-86.,-84.,-84.,-82.,-82.,-80.,-80.,-78.,-78.,-76.,-76.,-74.,-74.,-72.,-72.] + self.assertEqual(12,da.getNumberOfTuples()); + self.assertEqual(2,da.getNumberOfComponents()); + for i in xrange(24): + self.assertAlmostEqual(da.getIJ(0,i),expected2[i],13) + pass + for pos,elt in enumerate(dabis): + da[pos]-=elt + pass + self.assertEqual(12,da.getNumberOfTuples()); + self.assertEqual(2,da.getNumberOfComponents()); + expected3=[-88.,-87.,-84.,-83.,-80.,-79.,-76.,-75.,-72.,-71.,-68.,-67.,-64.,-63.,-60.,-59.,-56.,-55.,-52.,-51.,-48.,-47.,-44.,-43.] + for i in xrange(24): + self.assertAlmostEqual(da.getIJ(0,i),expected3[i],13) + pass + # operator*= + da=DataArrayDouble.New(range(6,30),12,2) + da2=DataArrayDouble.New(range(12),12,1) + dabis=-da + da*=da2 + expected1=[0.,0.,8.,9.,20.,22.,36.,39.,56.,60.,80.,85.,108.,114.,140.,147.,176.,184.,216.,225.,260.,270.,308.,319.] + for i in xrange(24): + self.assertAlmostEqual(da.getIJ(0,i),expected1[i],13) + pass + da=-dabis + da*=[100.,101.] + expected2=[600.,707.,800.,909.,1000.,1111.,1200.,1313.,1400.,1515.,1600.,1717.,1800.,1919.,2000.,2121.,2200.,2323.,2400.,2525.,2600.,2727.,2800.,2929.] + self.assertEqual(12,da.getNumberOfTuples()); + self.assertEqual(2,da.getNumberOfComponents()); + for i in xrange(24): + self.assertAlmostEqual(da.getIJ(0,i),expected2[i],13) + pass + for pos,elt in enumerate(dabis): + da[pos]*=elt + pass + self.assertEqual(12,da.getNumberOfTuples()); + self.assertEqual(2,da.getNumberOfComponents()); + expected3=[-3600.,-4949.,-6400.,-8181.,-10000.,-12221.,-14400.,-17069.,-19600.,-22725.,-25600.,-29189.,-32400.,-36461.,-40000.,-44541.,-48400.,-53429.,-57600.,-63125.,-67600.,-73629.,-78400.,-84941.0] + for i in xrange(24): + self.assertAlmostEqual(da.getIJ(0,i),expected3[i],13) + pass + # operator/= + da=DataArrayDouble.New(range(6,30),12,2) + da2=DataArrayDouble.New(range(1,13),12,1) + dabis=-da + da/=da2 + expected1=[6.0,7.0,4.0,4.5,3.3333333333333335,3.6666666666666665,3.0,3.25,2.8,3.0,2.6666666666666665,2.8333333333333335,2.5714285714285716,2.7142857142857144,2.5,2.625,2.4444444444444446,2.5555555555555554,2.4,2.5,2.3636363636363638,2.4545454545454546,2.3333333333333335,2.4166666666666665] + for i in xrange(24): + self.assertAlmostEqual(da.getIJ(0,i),expected1[i],13) + pass + da=-dabis + da/=[100.,101.] + expected2=[0.06,0.06930693069306931,0.08,0.0891089108910891,0.1,0.10891089108910891,0.12,0.12871287128712872,0.14,0.1485148514851485,0.16,0.16831683168316833,0.18,0.18811881188118812,0.2,0.2079207920792079,0.22,0.22772277227722773,0.24,0.24752475247524752,0.26,0.26732673267326734,0.28,0.2871287128712871] + self.assertEqual(12,da.getNumberOfTuples()); + self.assertEqual(2,da.getNumberOfComponents()); + for i in xrange(24): + self.assertAlmostEqual(da.getIJ(0,i),expected2[i],13) + pass + for pos,elt in enumerate(dabis): + da[pos]/=elt + pass + self.assertEqual(12,da.getNumberOfTuples()); + self.assertEqual(2,da.getNumberOfComponents()); + expected3=[-0.01, -0.009900990099009901, -0.01, -0.009900990099009901, -0.01, -0.009900990099009901, -0.01, -0.009900990099009901, -0.01, -0.009900990099009901, -0.01, -0.009900990099009901, -0.01, -0.009900990099009901, -0.01, -0.009900990099009901, -0.01, -0.009900990099009901, -0.01, -0.009900990099009901, -0.01, -0.009900990099009901, -0.01, -0.0099009900990099] + for i in xrange(24): + self.assertAlmostEqual(da.getIJ(0,i),expected3[i],13) + pass + pass + + def testSwigDAIOp4(self): + da=DataArrayInt.New(range(6,30),12,2) + self.assertEqual(12,da.getNumberOfTuples()); + self.assertEqual(2,da.getNumberOfComponents()); + for i in xrange(24): + self.assertEqual(da.getIJ(0,i),i+6) + pass + # operator transpose + da.transpose() + self.assertEqual(2,da.getNumberOfTuples()); + self.assertEqual(12,da.getNumberOfComponents()); + for i in xrange(24): + self.assertEqual(da.getIJ(0,i),i+6) + pass + da.transpose() + # operator __neg__ + da2=DataArrayInt.New(12,1) + da2.iota(0) + dabis=-da + for i in xrange(24): + self.assertEqual(dabis.getIJ(0,i),-(i+6)) + pass + # operator+= + da+=da2 + expected1=[6,7,9,10,12,13,15,16,18,19,21,22,24,25,27,28,30,31,33,34,36,37,39,40] + for i in xrange(24): + self.assertEqual(da.getIJ(0,i),expected1[i]) + pass + da=-dabis + da+=[100,101] + expected2=[106,108,108,110,110,112,112,114,114,116,116,118,118,120,120,122,122,124,124,126,126,128,128,130] + self.assertEqual(12,da.getNumberOfTuples()); + self.assertEqual(2,da.getNumberOfComponents()); + for i in xrange(24): + self.assertEqual(da.getIJ(0,i),expected2[i]) + pass + for pos,elt in enumerate(dabis): + da[pos]+=elt + pass + self.assertEqual(12,da.getNumberOfTuples()); + self.assertEqual(2,da.getNumberOfComponents()); + for elt in da: + li=elt[:] + self.assertEqual(li[0],100) ; self.assertEqual(li[1],101) + pass + # operator-= + da=DataArrayInt.New(range(6,30),12,2) + da2=DataArrayInt.New(range(12),12,1) + dabis=-da + da-=da2 + expected1=[6,7,7,8,8,9,9,10,10,11,11,12,12,13,13,14,14,15,15,16,16,17,17,18] + for i in xrange(24): + self.assertEqual(da.getIJ(0,i),expected1[i]) + pass + da=-dabis + da-=[100,101] + expected2=[-94,-94,-92,-92,-90,-90,-88,-88,-86,-86,-84,-84,-82,-82,-80,-80,-78,-78,-76,-76,-74,-74,-72,-72] + self.assertEqual(12,da.getNumberOfTuples()); + self.assertEqual(2,da.getNumberOfComponents()); + for i in xrange(24): + self.assertEqual(da.getIJ(0,i),expected2[i]) + pass + for pos,elt in enumerate(dabis): + da[pos]-=elt + pass + self.assertEqual(12,da.getNumberOfTuples()); + self.assertEqual(2,da.getNumberOfComponents()); + expected3=[-88,-87,-84,-83,-80,-79,-76,-75,-72,-71,-68,-67,-64,-63,-60,-59,-56,-55,-52,-51,-48,-47,-44,-43] + for i in xrange(24): + self.assertEqual(da.getIJ(0,i),expected3[i]) + pass + # operator*= + da=DataArrayInt.New(range(6,30),12,2) + da2=DataArrayInt.New(range(12),12,1) + dabis=-da + da*=da2 + expected1=[0,0,8,9,20,22,36,39,56,60,80,85,108,114,140,147,176,184,216,225,260,270,308,319] + for i in xrange(24): + self.assertEqual(da.getIJ(0,i),expected1[i]) + pass + da=-dabis + da*=[100,101] + expected2=[600,707,800,909,1000,1111,1200,1313,1400,1515,1600,1717,1800,1919,2000,2121,2200,2323,2400,2525,2600,2727,2800,2929] + self.assertEqual(12,da.getNumberOfTuples()); + self.assertEqual(2,da.getNumberOfComponents()); + for i in xrange(24): + self.assertEqual(da.getIJ(0,i),expected2[i]) + pass + for pos,elt in enumerate(dabis): + da[pos]*=elt + pass + self.assertEqual(12,da.getNumberOfTuples()); + self.assertEqual(2,da.getNumberOfComponents()); + expected3=[-3600,-4949,-6400,-8181,-10000,-12221,-14400,-17069,-19600,-22725,-25600,-29189,-32400,-36461,-40000,-44541,-48400,-53429,-57600,-63125,-67600,-73629,-78400,-84941.0] + for i in xrange(24): + self.assertEqual(da.getIJ(0,i),expected3[i]) + pass + # operator/= + da=DataArrayInt.New(range(6,30),12,2) + da2=DataArrayInt.New(range(1,13),12,1) + dabis=-da + da/=da2 + expected1=[6,7,4,4,3,3,3,3,2,3,2,2,2,2,2,2,2,2,2,2,2,2,2,2] + for i in xrange(24): + self.assertEqual(da.getIJ(0,i),expected1[i]) + pass + da=-dabis + da/=DataArrayInt.New([2,3],1,2) + self.assertEqual(12,da.getNumberOfTuples()); + self.assertEqual(2,da.getNumberOfComponents()); + expected2=[3,2,4,3,5,3,6,4,7,5,8,5,9,6,10,7,11,7,12,8,13,9,14,9] + for i in xrange(24): + self.assertEqual(da.getIJ(0,i),expected2[i]) + pass + pass + + def testSwigDADOp5(self): + da=DataArrayDouble.New([5,6,7,8,9,6,7,-2,3,9,8,10]) + da.rearrange(3) + da2=DataArrayDouble.New([5.,8.,10.,12]) + self.assertEqual(4,da2.getNumberOfTuples()); + self.assertEqual(1,da2.getNumberOfComponents()); + da3=da+da2 + self.assertEqual(4,da3.getNumberOfTuples()); + self.assertEqual(3,da3.getNumberOfComponents()); + expected1=[10.,11.,12.,16.,17.,14.,17.,8.,13.,21.,20.,22.] + for i in xrange(12): + self.assertAlmostEqual(da3.getIJ(0,i),expected1[i],13) + pass + da3=da2+da + self.assertEqual(4,da3.getNumberOfTuples()); + self.assertEqual(3,da3.getNumberOfComponents()); + for i in xrange(12): + self.assertAlmostEqual(da3.getIJ(0,i),expected1[i],13) + pass + # Test new API of classmethod DataArrayDouble.New + vals=[5,6,7,8,9,6,7,-2,3,9,8,10] + da=DataArrayDouble.New(vals) + self.assertEqual(12,da.getNumberOfTuples()); + self.assertEqual(1,da.getNumberOfComponents()); + for i in xrange(12): + self.assertAlmostEqual(da.getIJ(0,i),vals[i],13) + pass + da=DataArrayDouble.New(vals,12) + self.assertEqual(12,da.getNumberOfTuples()); + self.assertEqual(1,da.getNumberOfComponents()); + for i in xrange(12): + self.assertAlmostEqual(da.getIJ(0,i),vals[i],13) + pass + da=DataArrayDouble.New(vals,1,12) + self.assertEqual(1,da.getNumberOfTuples()); + self.assertEqual(12,da.getNumberOfComponents()); + for i in xrange(12): + self.assertAlmostEqual(da.getIJ(0,i),vals[i],13) + pass + da=DataArrayDouble.New(vals,6,2) + self.assertEqual(6,da.getNumberOfTuples()); + self.assertEqual(2,da.getNumberOfComponents()); + for i in xrange(12): + self.assertAlmostEqual(da.getIJ(0,i),vals[i],13) + pass + da=DataArrayDouble.New(vals,4,3) + self.assertEqual(4,da.getNumberOfTuples()); + self.assertEqual(3,da.getNumberOfComponents()); + for i in xrange(12): + self.assertAlmostEqual(da.getIJ(0,i),vals[i],13) + pass + self.assertRaises(InterpKernelException,DataArrayDouble.New,vals,11); + self.assertRaises(InterpKernelException,DataArrayDouble.New,vals,13); + self.assertRaises(InterpKernelException,DataArrayDouble.New,vals,5,2); + self.assertRaises(InterpKernelException,DataArrayDouble.New,vals,7,2); + pass + + def testSwigDADOp6(self): + da=DataArrayInt.New([5,6,7,8,9,6,7,-2,3,9,8,10]) + da.rearrange(3) + da2=DataArrayInt.New([5,8,10,12]) + self.assertEqual(4,da2.getNumberOfTuples()); + self.assertEqual(1,da2.getNumberOfComponents()); + da3=da+da2 + self.assertEqual(4,da3.getNumberOfTuples()); + self.assertEqual(3,da3.getNumberOfComponents()); + expected1=[10,11,12,16,17,14,17,8,13,21,20,22] + for i in xrange(12): + self.assertEqual(da3.getIJ(0,i),expected1[i]) + pass + da3=da2+da + self.assertEqual(4,da3.getNumberOfTuples()); + self.assertEqual(3,da3.getNumberOfComponents()); + for i in xrange(12): + self.assertEqual(da3.getIJ(0,i),expected1[i]) + pass + da3=da+DataArrayInt.New(da2.getValues()) + # Test new API of classmethod DataArrayInt.New + vals=[5,6,7,8,9,6,7,-2,3,9,8,10] + da=DataArrayDouble.New(vals) + self.assertEqual(12,da.getNumberOfTuples()); + self.assertEqual(1,da.getNumberOfComponents()); + for i in xrange(12): + self.assertEqual(da.getIJ(0,i),vals[i]) + pass + da=DataArrayDouble.New(vals,12) + self.assertEqual(12,da.getNumberOfTuples()); + self.assertEqual(1,da.getNumberOfComponents()); + for i in xrange(12): + self.assertEqual(da.getIJ(0,i),vals[i]) + pass + da=DataArrayDouble.New(vals,1,12) + self.assertEqual(1,da.getNumberOfTuples()); + self.assertEqual(12,da.getNumberOfComponents()); + for i in xrange(12): + self.assertEqual(da.getIJ(0,i),vals[i]) + pass + da=DataArrayDouble.New(vals,6,2) + self.assertEqual(6,da.getNumberOfTuples()); + self.assertEqual(2,da.getNumberOfComponents()); + for i in xrange(12): + self.assertEqual(da.getIJ(0,i),vals[i]) + pass + da=DataArrayDouble.New(vals,4,3) + self.assertEqual(4,da.getNumberOfTuples()); + self.assertEqual(3,da.getNumberOfComponents()); + for i in xrange(12): + self.assertEqual(da.getIJ(0,i),vals[i]) + pass + self.assertRaises(InterpKernelException,DataArrayDouble.New,vals,11); + self.assertRaises(InterpKernelException,DataArrayDouble.New,vals,13); + self.assertRaises(InterpKernelException,DataArrayDouble.New,vals,5,2); + self.assertRaises(InterpKernelException,DataArrayDouble.New,vals,7,2); + pass + + def testSwigDADOp9(self): + l1=[(1.,2.,3),(4.,5.,6.),(7.,8.,9.),[10.,11.,12.]] + da1=DataArrayDouble(l1,4,3) + self.assertEqual(4,da1.getNumberOfTuples()); + self.assertEqual(3,da1.getNumberOfComponents()); + da2=DataArrayDouble(12) ; da2.iota(1.) ; da2.rearrange(3) + self.assertTrue(da2.isEqual(da1,1e-12)) + self.assertRaises(InterpKernelException,DataArrayDouble.New,l1,3,4); + da3=DataArrayDouble(l1,4) + self.assertTrue(da3.isEqual(da1,1e-12)) + self.assertRaises(InterpKernelException,DataArrayDouble.New,l1,3); + self.assertRaises(InterpKernelException,DataArrayDouble.New,l1,5); + l1=[(1.,2.,3),(4.,(5.),((6.))),(7.,8.,9.),[10.,11.,12.]] + da1=DataArrayDouble(l1,4,3) + self.assertEqual(4,da1.getNumberOfTuples()); + self.assertEqual(3,da1.getNumberOfComponents()); + da2=DataArrayDouble(12) ; da2.iota(1.) ; da2.rearrange(3) + self.assertTrue(da2.isEqual(da1,1e-12)) + self.assertRaises(InterpKernelException,DataArrayDouble.New,l1,3,4); + da3=DataArrayDouble(l1,4) + self.assertTrue(da3.isEqual(da1,1e-12)) + self.assertRaises(InterpKernelException,DataArrayDouble.New,l1,3); + self.assertRaises(InterpKernelException,DataArrayDouble.New,l1,5); + # + l1=[(1,2,3),(4,5,6),(7,8,9),[10,11,12]] + da1=DataArrayInt(l1,4,3) + self.assertEqual(4,da1.getNumberOfTuples()); + self.assertEqual(3,da1.getNumberOfComponents()); + da2=DataArrayInt(12) ; da2.iota(1) ; da2.rearrange(3) + self.assertTrue(da2.isEqual(da1)) + self.assertRaises(InterpKernelException,DataArrayInt.New,l1,3,4); + da3=DataArrayInt(l1,4) + self.assertTrue(da3.isEqual(da1)) + self.assertRaises(InterpKernelException,DataArrayInt.New,l1,3); + self.assertRaises(InterpKernelException,DataArrayInt.New,l1,5); + l1=[(1,[2],3),(4,[(5)],6),((([7])),8,9),[10,11,12]] + da1=DataArrayInt(l1,4,3) + self.assertEqual(4,da1.getNumberOfTuples()); + self.assertEqual(3,da1.getNumberOfComponents()); + da2=DataArrayInt(12) ; da2.iota(1) ; da2.rearrange(3) + self.assertTrue(da2.isEqual(da1)) + self.assertRaises(InterpKernelException,DataArrayInt.New,l1,3,4); + da3=DataArrayInt(l1,4) + self.assertTrue(da3.isEqual(da1)) + self.assertRaises(InterpKernelException,DataArrayInt.New,l1,3); + self.assertRaises(InterpKernelException,DataArrayInt.New,l1,5); + pass + + def testRenumberNodesInConn1(self): + mesh2DCoords=[-0.3,-0.3,0., 0.2,-0.3,0., 0.7,-0.3,0., -0.3,0.2,0., 0.2,0.2,0., 0.7,0.2,0., -0.3,0.7,0., 0.2,0.7,0., 0.7,0.7,0. ] + mesh2DConn=[1,4,2, 4,5,2, 0,3,4,1, 6,7,4,3, 7,8,5,4] + mesh2D=MEDCouplingUMesh.New("mesh",2); + mesh2D.allocateCells(5); + mesh2D.insertNextCell(NORM_TRI3,3,mesh2DConn[0:3]) + mesh2D.insertNextCell(NORM_TRI3,3,mesh2DConn[3:6]) + mesh2D.insertNextCell(NORM_QUAD4,4,mesh2DConn[6:10]) + mesh2D.insertNextCell(NORM_QUAD4,4,mesh2DConn[10:14]) + mesh2D.insertNextCell(NORM_QUAD4,4,mesh2DConn[14:18]) + mesh2D.finishInsertingCells(); + myCoords=DataArrayDouble.New(mesh2DCoords,9,3); + mesh2D.setCoords(myCoords); + mesh2D.checkCoherency(); + # + mesh3DCoords=[-0.3,-0.3,0., -0.3,0.2,0., 0.2,0.2,0., 0.2,-0.3,0., -0.3,-0.3,1., -0.3,0.2,1., 0.2,0.2,1., 0.2,-0.3,1. ] + mesh3DConn=[0,1,2,3,4,5,6,7] + mesh3D=MEDCouplingUMesh.New("mesh",3); + mesh3D.allocateCells(1); + mesh3D.insertNextCell(NORM_HEXA8,8,mesh3DConn[:]) + mesh3D.finishInsertingCells(); + myCoords3D=DataArrayDouble.New(mesh3DCoords,8,3); + mesh3D.setCoords(myCoords3D); + mesh3D.checkCoherency(); + # + mesh3D_2=mesh3D.deepCpy(); + mesh2D_2=mesh2D.deepCpy(); + mesh3D_4=mesh3D.deepCpy(); + mesh2D_4=mesh2D.deepCpy(); + oldNbOf3DNodes=mesh3D.getNumberOfNodes(); + renumNodes=DataArrayInt.New(); + renumNodes.alloc(mesh2D.getNumberOfNodes(),1); + renumNodes.iota(oldNbOf3DNodes); + coo=DataArrayDouble.Aggregate(mesh3D.getCoords(),mesh2D.getCoords()); + mesh3D.setCoords(coo); + mesh2D.setCoords(coo); + mesh2DCpy=mesh2D.deepCpy() + mesh2D_3=mesh2D.deepCpy(); + mesh2D_3.shiftNodeNumbersInConn(oldNbOf3DNodes); + mesh2D.renumberNodesInConn(renumNodes); + mesh2DCpy.renumberNodesInConn(renumNodes.getValues()); + self.assertTrue(mesh2D.isEqual(mesh2DCpy,1e-12)) + self.assertTrue(mesh2D.isEqual(mesh2D_3,1e-12)) + # + da1,da2=mesh3D.checkGeoEquivalWith(mesh3D_2,10,1e-12); + self.assertTrue(da1==None); + self.assertEqual(8,da2.getNumberOfTuples()); + self.assertEqual(1,da2.getNumberOfComponents()); + expected1=[8,11,12,9,4,5,6,7] + for i in xrange(8): + self.assertEqual(expected1[i],da2.getIJ(i,0)); + pass + # + da1,da2=mesh2D.checkGeoEquivalWith(mesh2D_2,10,1e-12); + self.assertTrue(da1==None); + self.assertEqual(9,da2.getNumberOfTuples()); + self.assertEqual(1,da2.getNumberOfComponents()); + for i in xrange(9): + self.assertEqual(8+i,da2.getIJ(i,0)); + pass + # + mesh2D_5=mesh2D_4.deepCpy(); + mesh2D_5.translate([1.,0.,0.]); + meshes=[mesh3D_4,mesh2D_4,mesh2D_5]; + MEDCouplingUMesh.PutUMeshesOnSameAggregatedCoords(meshes); + self.assertTrue(mesh3D_4.getCoords().getHiddenCppPointer()==mesh2D_4.getCoords().getHiddenCppPointer()); + self.assertTrue(mesh2D_4.getCoords().getHiddenCppPointer()==mesh2D_5.getCoords().getHiddenCppPointer()); + mesh3D_4.checkCoherency(); mesh2D_4.checkCoherency(); mesh2D_5.checkCoherency(); + self.assertEqual(26,mesh3D_4.getNumberOfNodes()); + self.assertEqual(3,mesh3D_4.getSpaceDimension()); + self.assertEqual(9,mesh3D_4.getNodalConnectivity().getNumberOfTuples()); + self.assertEqual(23,mesh2D_4.getNodalConnectivity().getNumberOfTuples()); + self.assertEqual(23,mesh2D_5.getNodalConnectivity().getNumberOfTuples()); + expected2=[18,0,1,2,3,4,5,6,7] + expected3=[3,9,12,10, 3,12,13,10, 4,8,11,12,9, 4,14,15,12,11, 4,15,16,13,12] + expected4=[3,18,21,19, 3,21,22,19, 4,17,20,21,18, 4,23,24,21,20, 4,24,25,22,21] + expected5=[-0.3,-0.3,0., -0.3,0.2,0., 0.2,0.2,0., 0.2,-0.3,0., -0.3,-0.3,1., -0.3,0.2,1., 0.2,0.2,1., 0.2,-0.3,1., -0.3,-0.3,0., 0.2,-0.3,0., 0.7,-0.3,0., -0.3,0.2,0., 0.2,0.2,0., 0.7,0.2,0., -0.3,0.7,0., 0.2,0.7,0., 0.7,0.7,0., 0.7, -0.3, 0.0, 1.2, -0.3, 0.0, 1.7, -0.3, 0.0, 0.7, 0.2, 0.0, 1.2, 0.2, 0.0, 1.7, 0.2, 0.0, 0.7, 0.7, 0.0, 1.2, 0.7, 0.0, 1.7, 0.7, 0.0] + self.assertEqual(expected2,mesh3D_4.getNodalConnectivity().getValues()); + self.assertEqual(expected3,mesh2D_4.getNodalConnectivity().getValues()); + self.assertEqual(expected4,mesh2D_5.getNodalConnectivity().getValues()); + for i in xrange(78): + self.assertAlmostEqual(expected5[i],mesh3D_4.getCoords().getIJ(0,i),12); + pass + # + MEDCouplingUMesh.MergeNodesOnUMeshesSharingSameCoords(meshes,1e-12); + mesh3D_4.checkCoherency(); mesh2D_4.checkCoherency(); mesh2D_5.checkCoherency(); + self.assertTrue(mesh3D_4.getCoords().getHiddenCppPointer()==mesh2D_4.getCoords().getHiddenCppPointer()); + self.assertTrue(mesh2D_4.getCoords().getHiddenCppPointer()==mesh2D_5.getCoords().getHiddenCppPointer()); + self.assertEqual(19,mesh3D_4.getNumberOfNodes()); + self.assertEqual(3,mesh3D_4.getSpaceDimension()); + self.assertEqual(9,mesh3D_4.getNodalConnectivity().getNumberOfTuples()); + self.assertEqual(23,mesh2D_4.getNodalConnectivity().getNumberOfTuples()); + self.assertEqual(23,mesh2D_5.getNodalConnectivity().getNumberOfTuples()); + expected6=[18,0,1,2,3,4,5,6,7] + expected7=[3,3,2,8, 3,2,9,8, 4,0,1,2,3, 4,10,11,2,1, 4,11,12,9,2] + expected8=[3,13,15,14, 3,15,16,14, 4,8,9,15,13, 4,12,17,15,9, 4,17,18,16,15] + expected9=[-0.3, -0.3, 0., -0.3, 0.2, 0., 0.2, 0.2, 0., 0.2, -0.3, 0., -0.3, -0.3, 1., -0.3, 0.2, 1., + 0.2, 0.2, 1., 0.2, -0.3, 1., 0.7, -0.3, 0., 0.7, 0.2, 0., -0.3, 0.7, 0., 0.2, 0.7, 0., + 0.7, 0.7, 0., 1.2, -0.3, 0., 1.7, -0.3, 0., 1.2, 0.2, 0., 1.7, 0.2, 0., 1.2, 0.7, 0., 1.7, 0.7, 0.] + self.assertEqual(expected6,mesh3D_4.getNodalConnectivity().getValues()); + self.assertEqual(expected7,mesh2D_4.getNodalConnectivity().getValues()); + self.assertEqual(expected8,mesh2D_5.getNodalConnectivity().getValues()); + for i in xrange(57): + self.assertAlmostEqual(expected9[i],mesh3D_4.getCoords().getIJ(0,i),12); + pass + # + pass + + def testComputeNeighborsOfCells1(self): + m=MEDCouplingDataForTest.build2DTargetMesh_1(); + d1,d2=m.computeNeighborsOfCells(); + self.assertEqual(6,d2.getNumberOfTuples()); + self.assertEqual(10,d1.getNumberOfTuples()); + expected1=[0,2,4,6,8,10] + expected2=[3,1,0,2,4,1,4,0,2,3] + self.assertEqual(expected1,d2.getValues()); + self.assertEqual(expected2,d1.getValues()); + pass + + def testCheckButterflyCellsBug1(self): + mesh2DCoords=[323.85,120.983748908684,317.5,131.982271536747,336.55,120.983748908686,330.2,131.982271536751,323.85,142.98079416481] + mesh2DConn=[4,1,0,2,3] + mesh2D=MEDCouplingUMesh.New("mesh",2); + mesh2D.allocateCells(1); + mesh2D.insertNextCell(NORM_POLYGON,5,mesh2DConn[0:5]) + mesh2D.finishInsertingCells(); + myCoords=DataArrayDouble.New(mesh2DCoords,5,2); + mesh2D.setCoords(myCoords); + mesh2D.checkCoherency(); + # + v=mesh2D.checkButterflyCells(); + self.assertTrue(v.empty()); + pass + + def testDataArrayIntRange1(self): + d=DataArrayInt.Range(2,17,7); + expected1=[2,9,16] + self.assertEqual(3,d.getNumberOfTuples()); + self.assertEqual(1,d.getNumberOfComponents()); + self.assertEqual(expected1,d.getValues()); + # + d=DataArrayInt.Range(2,23,7); + self.assertEqual(3,d.getNumberOfTuples()); + self.assertEqual(1,d.getNumberOfComponents()); + self.assertEqual(expected1,d.getValues()); + # + d=DataArrayInt.Range(2,24,7); + expected2=[2,9,16,23] + self.assertEqual(4,d.getNumberOfTuples()); + self.assertEqual(1,d.getNumberOfComponents()); + self.assertEqual(expected2,d.getValues()); + # + d=DataArrayInt.Range(24,2,-7); + expected3=[24,17,10,3] + self.assertEqual(4,d.getNumberOfTuples()); + self.assertEqual(1,d.getNumberOfComponents()); + self.assertEqual(expected3,d.getValues()); + # + d=DataArrayInt.Range(23,2,-7); + expected4=[23,16,9] + self.assertEqual(3,d.getNumberOfTuples()); + self.assertEqual(1,d.getNumberOfComponents()); + self.assertEqual(expected4,d.getValues()); + # + d=DataArrayInt.Range(23,22,-7); + self.assertEqual(1,d.getNumberOfTuples()); + self.assertEqual(1,d.getNumberOfComponents()); + self.assertEqual(23,d.getIJ(0,0)); + # + d=DataArrayInt.Range(22,23,7); + self.assertEqual(1,d.getNumberOfTuples()); + self.assertEqual(1,d.getNumberOfComponents()); + self.assertEqual(22,d.getIJ(0,0)); + # + d=DataArrayInt.Range(22,22,7); + self.assertEqual(0,d.getNumberOfTuples()); + self.assertEqual(1,d.getNumberOfComponents()); + # + d=DataArrayInt.Range(22,22,-7); + self.assertEqual(0,d.getNumberOfTuples()); + self.assertEqual(1,d.getNumberOfComponents()); + # + self.assertRaises(InterpKernelException,DataArrayInt.Range,22,23,-7); + self.assertRaises(InterpKernelException,DataArrayInt.Range,23,22,7); + self.assertRaises(InterpKernelException,DataArrayInt.Range,23,22,0); + self.assertRaises(InterpKernelException,DataArrayInt.Range,22,23,0); + pass + + def testSwigUMeshGetItem1(self): + m=MEDCouplingDataForTest.build2DTargetMesh_1(); + subMesh=m.buildPartOfMySelf([1,3],True); + self.assertTrue(isinstance(subMesh,MEDCouplingUMesh)) + m1=m[[1,3]] + self.assertTrue(isinstance(m1,MEDCouplingUMesh)) + m2=m[(1,3)] + self.assertTrue(isinstance(m2,MEDCouplingUMesh)) + m3=m[1::2] + self.assertTrue(isinstance(m3,MEDCouplingUMesh)) + m4=m[DataArrayInt.New([1,3])] + m5_1=m[1] + self.assertTrue(isinstance(m5_1,MEDCouplingUMesh)) + m5_2=m[3] + self.assertTrue(isinstance(m5_2,MEDCouplingUMesh)) + m5=MEDCouplingUMesh.MergeUMeshesOnSameCoords([m5_1,m5_2]); + m5.setName(subMesh.getName()) + self.assertTrue(isinstance(m4,MEDCouplingUMesh)) + self.assertTrue(subMesh.isEqual(m1,1e-12)) + self.assertTrue(subMesh.isEqual(m2,1e-12)) + self.assertTrue(subMesh.isEqual(m3,1e-12)) + self.assertTrue(subMesh.isEqual(m4,1e-12)) + self.assertTrue(subMesh.isEqual(m5,1e-12)) + self.assertRaises(InterpKernelException,m.buildPartOfMySelf,[1,5],True); + pass + + def testSwigGetItem3(self): + da=DataArrayInt.New([4,5,6]) + self.assertEqual(5,da[1]) + self.assertEqual(6,da[-1]) + self.assertRaises(InterpKernelException,da.__getitem__,3) + da=DataArrayInt.New([4,5,6,7,8,9],2,3) + self.assertEqual(9,da[1,2]) + da=DataArrayDouble.New([4.1,5.2,6.3]) + self.assertAlmostEqual(5.2,da[1],12) + self.assertAlmostEqual(6.3,da[-1],12) + self.assertRaises(InterpKernelException,da.__getitem__,3) + da=DataArrayDouble.New([4.12,5.12,6.12,7.12,8.12,9.12],2,3) + self.assertAlmostEqual(9.12,da[1,2],12) + pass + + def testSwigDADISub1(self): + mesh3D,mesh2D=MEDCouplingDataForTest.build3DExtrudedUMesh_1(); + bary=mesh3D.getBarycenterAndOwner() + bary=bary[:,:2] + pts=bary.getDifferentValues(1e-12) + expected=[[0,6,12],[1,7,13],[2,8,14],[3,9,15],[4,10,16],[5,11,17]] + for pos,pt in enumerate(pts): + bary2=bary[:,:2] + bary2[:]-=pt + norm=bary2.magnitude() + self.assertEqual(expected[pos],norm.getIdsInRange(-1.,1e-5).getValues()) + pass + expected2=[[3.,54.],[-141.,180.],[21.,54.],[39.,72.],[-15.,90.],[21.,90.]] + for pos,pt in enumerate(pts): + bary2=bary[:,:2] + bary2[:]+=pt + self.assertAlmostEqual(expected2[pos][0],bary2.accumulate()[0],12); + self.assertAlmostEqual(expected2[pos][1],bary2.accumulate()[1],12); + pass + expected3=[[-3.,22.5],[45.,337.5],[-9., 22.5],[-15.,67.5],[3.,112.5],[-9.,112.5]] + for pos,pt in enumerate(pts): + bary2=bary[:,:2] + bary2[:]*=pt + self.assertAlmostEqual(expected3[pos][0],bary2.accumulate()[0],12); + self.assertAlmostEqual(expected3[pos][1],bary2.accumulate()[1],12); + pass + expected4=[[-12.,90.],[0.8,6.],[-4,90.],[-2.4,30.],[12.,18],[-4,18.]] + for pos,pt in enumerate(pts): + bary2=bary[:,:2] + bary2[:]/=pt + self.assertAlmostEqual(expected4[pos][0],bary2.accumulate()[0],12); + self.assertAlmostEqual(expected4[pos][1],bary2.accumulate()[1],12); + pass + # + d=DataArrayInt.New([1,2,0,1,0,2],3,2) + e=DataArrayInt.New([1,11,101,2,12,102,3,13,103,4,14,104],4,3) + expected5=[[1,11,101,77,77,77,77,77,77,4,14,104],[77,77,77,77,77,77,3,13,103,4,14,104],[77,77,77,2,12,102,77,77,77,4,14,104]] + expected6=[[1,77,77,2,77,77,3,77,77,4,77,77],[77,77,101,77,77,102,77,77,103,77,77,104],[77,11,77,77,12,77,77,13,77,77,14,77]] + for pos,tup in enumerate(d): + f=e[:] + self.assertTrue(isinstance(f,DataArrayInt)) + f[tup]=77 + self.assertEqual(expected5[pos],f.getValues()) + self.assertEqual(6*[77],f[tup].getValues()) + f=e[:] + f[:,tup]=77 + self.assertEqual(expected6[pos],f.getValues()) + self.assertEqual(8*[77],f[:,tup].getValues()) + pass + # + e=e.convertToDblArr() + for pos,tup in enumerate(d): + f=e[:] + self.assertTrue(isinstance(f,DataArrayDouble)) + f[tup]=77. + self.assertEqual(expected5[pos],f.convertToIntArr().getValues()) + self.assertEqual(6*[77],f[tup].convertToIntArr().getValues()) + f=e[:] + f[:,tup]=77. + self.assertEqual(expected6[pos],f.convertToIntArr().getValues()) + self.assertEqual(8*[77],f[:,tup].convertToIntArr().getValues()) + pass + pass + + def testDataArrayDoubleGetMinMaxPerComponent1(self): + values1=[1.,2.,3.,-0.9,2.1,3.,1.3,1.7,3.,1.,1.8,3.] + d1=DataArrayDouble.New(); + self.assertRaises(InterpKernelException,d1.getMinMaxPerComponent) + d1=DataArrayDouble.New(values1,4,3); + res=d1.getMinMaxPerComponent(); + self.assertTrue(isinstance(res,list)) + self.assertEqual(3,len(res)) + for i in xrange(3): + self.assertTrue(isinstance(res[i],tuple)) + self.assertEqual(2,len(res[i])) + pass + expected1=[-0.9,1.3,1.7,2.1,3.,3.] + for i in xrange(6): + self.assertAlmostEqual(expected1[i],res[i/2][i%2],14) + pass + # + d1.rearrange(2); + res=d1.getMinMaxPerComponent(); + self.assertTrue(isinstance(res,list)) + self.assertEqual(2,len(res)) + for i in xrange(2): + self.assertTrue(isinstance(res[i],tuple)) + self.assertEqual(2,len(res[i])) + pass + expected2=[1.,3.,-0.9,3.] + for i in xrange(4): + self.assertAlmostEqual(expected2[i],res[i/2][i%2],14) + pass + # + d1.rearrange(1); + res=d1.getMinMaxPerComponent(); + self.assertTrue(isinstance(res,list)) + self.assertEqual(1,len(res)) + for i in xrange(1): + self.assertTrue(isinstance(res[i],tuple)) + self.assertEqual(2,len(res[i])) + pass + expected3=[-0.9,3.] + for i in xrange(2): + self.assertAlmostEqual(expected3[i],res[i/2][i%2],14) + pass + pass + + def testDataArrayIntGetHashCode1(self): + d1=DataArrayInt.New(range(3545)) + d2=DataArrayInt.New(range(3545)) + self.assertEqual(d2.getHashCode(),d1.getHashCode()) + self.assertEqual(232341068,d1.getHashCode()) + d1[886]=6 + self.assertEqual(232340188,d1.getHashCode()) + pass + + def testZipConnectivityPol1(self): + m1=MEDCouplingDataForTest.build2DTargetMesh_1(); + cells1=[2,3,4] + m2_1=m1.buildPartOfMySelf(cells1,True); + m2=m2_1 + self.assertTrue(isinstance(m2,MEDCouplingUMesh)) + # no permutation policy 0 + isOk,arr=m1.areCellsIncludedIn(m2,0) + self.assertTrue(isOk); + self.assertEqual(3,arr.getNumberOfTuples()); + self.assertEqual(1,arr.getNumberOfComponents()); + self.assertEqual(cells1,arr.getValues()) + # no permutation policy 1 + isOk,arr=m1.areCellsIncludedIn(m2,1) + self.assertTrue(isOk); + self.assertEqual(3,arr.getNumberOfTuples()); + self.assertEqual(1,arr.getNumberOfComponents()); + self.assertEqual(cells1,arr.getValues()) + # no permutation policy 2 + isOk,arr=m1.areCellsIncludedIn(m2,2) + self.assertTrue(isOk); + self.assertEqual(3,arr.getNumberOfTuples()); + self.assertEqual(1,arr.getNumberOfComponents()); + self.assertEqual(cells1,arr.getValues()) + # some modification into m2 + modif1=[2,4,5] + m2.getNodalConnectivity()[1:4]=modif1 + #policy 0 fails because cell0 in m2 has same orientation be not same connectivity + expected1=[5,3,4] + isOk,arr=m1.areCellsIncludedIn(m2,0) + self.assertTrue(not isOk); + self.assertEqual(3,arr.getNumberOfTuples()); + self.assertEqual(1,arr.getNumberOfComponents()); + self.assertEqual(expected1,arr.getValues()) + #policy 1 succeeds because cell0 in m2 has not exactly the same conn + isOk,arr=m1.areCellsIncludedIn(m2,1) + self.assertTrue(isOk); + self.assertEqual(3,arr.getNumberOfTuples()); + self.assertEqual(1,arr.getNumberOfComponents()); + self.assertEqual(cells1,arr.getValues()) + #policy 2 succeeds because cell0 in m2 has same nodes in connectivity + isOk,arr=m1.areCellsIncludedIn(m2,2) + self.assertTrue(isOk); + self.assertEqual(3,arr.getNumberOfTuples()); + self.assertEqual(1,arr.getNumberOfComponents()); + self.assertEqual(cells1,arr.getValues()) + #some new modification into m2 + modif2=[2,5,4] + m2.getNodalConnectivity()[1:4]=modif2 + #policy 0 fails because cell0 in m2 has not exactly the same conn + isOk,arr=m1.areCellsIncludedIn(m2,0) + self.assertTrue(not isOk); + self.assertEqual(3,arr.getNumberOfTuples()); + self.assertEqual(1,arr.getNumberOfComponents()); + self.assertEqual(expected1,arr.getValues()) + #policy 1 fails too because cell0 in m2 has not same orientation + isOk,arr=m1.areCellsIncludedIn(m2,1) + self.assertTrue(not isOk); + self.assertEqual(3,arr.getNumberOfTuples()); + self.assertEqual(1,arr.getNumberOfComponents()); + self.assertEqual(expected1,arr.getValues()) + #policy 2 succeeds because cell0 in m2 has same nodes in connectivity + isOk,arr=m1.areCellsIncludedIn(m2,2) + self.assertTrue(isOk); + self.assertEqual(3,arr.getNumberOfTuples()); + self.assertEqual(1,arr.getNumberOfComponents()); + self.assertEqual(cells1,arr.getValues()) + # Now 1D + cells2=[3,2] + m1=MEDCouplingDataForTest.build1DSourceMesh_2(); + m2_1=m1.buildPartOfMySelf(cells2,True); + m2=m2_1 + self.assertTrue(isinstance(m2,MEDCouplingUMesh)) + # no permutation policy 0 + isOk,arr=m1.areCellsIncludedIn(m2,0) + self.assertTrue(isOk); + self.assertEqual(2,arr.getNumberOfTuples()); + self.assertEqual(1,arr.getNumberOfComponents()); + self.assertEqual(cells2,arr.getValues()) + # no permutation policy 1 + isOk,arr=m1.areCellsIncludedIn(m2,1) + self.assertTrue(isOk); + self.assertEqual(2,arr.getNumberOfTuples()); + self.assertEqual(1,arr.getNumberOfComponents()); + self.assertEqual(cells2,arr.getValues()) + # no permutation policy 2 + isOk,arr=m1.areCellsIncludedIn(m2,2) + self.assertTrue(isOk); + self.assertEqual(2,arr.getNumberOfTuples()); + self.assertEqual(1,arr.getNumberOfComponents()); + self.assertEqual(cells2,arr.getValues()) + # some modification into m2 + modif3=[4,3] + m2.getNodalConnectivity()[1:3]=modif3 + #policy 0 fails because cell0 in m2 has not exactly the same conn + expected2=[4,2] + isOk,arr=m1.areCellsIncludedIn(m2,0) + self.assertTrue(not isOk); + self.assertEqual(2,arr.getNumberOfTuples()); + self.assertEqual(1,arr.getNumberOfComponents()); + self.assertEqual(expected2,arr.getValues()) + #policy 1 fails too because cell0 in m2 has not same orientation + isOk,arr=m1.areCellsIncludedIn(m2,1) + self.assertTrue(not isOk); + self.assertEqual(2,arr.getNumberOfTuples()); + self.assertEqual(1,arr.getNumberOfComponents()); + self.assertEqual(expected2,arr.getValues()) + #policy 2 succeeds because cell0 in m2 has same nodes in connectivity + isOk,arr=m1.areCellsIncludedIn(m2,2) + self.assertTrue(isOk); + self.assertEqual(2,arr.getNumberOfTuples()); + self.assertEqual(1,arr.getNumberOfComponents()); + self.assertEqual(cells2,arr.getValues()) + pass + + def toSeeIfDaIIopsAreOK(self,d): + d+=5 + d*=6 + d/=3 + d-=2 + d%=7 + pass + + def testSwigDAIOp5(self): + d=DataArrayInt.New([4,5,6,10,3,-1],2,3) + self.toSeeIfDaIIopsAreOK(d) + dExp=DataArrayInt.New([2,4,6,0,0,6],2,3) + self.assertTrue(d.isEqual(dExp)); + pass + + def toSeeIfDaDIopsAreOK(self,d): + d+=5 + d*=6 + d/=3 + d-=2 + pass + + def testSwigDADOp7(self): + d=DataArrayDouble.New([4.,5.,6.,10.,3.,-1.],2,3) + self.toSeeIfDaDIopsAreOK(d) + dExp=DataArrayDouble.New([16.,18.,20.,28.,14.,6.],2,3) + self.assertTrue(d.isEqual(dExp,1e-14)); + pass + + def testConvexEnvelop2D1(self): + coords=[7.54758495819e-14,-1.12270326253e-12,8.43143594193,-1.02835845055e-12,4.21571797096,7.30183771609,-4.21571797097,7.30183771609,-8.43143594193,-1.09439981894e-12,-4.21571797097,-7.30183771609,4.21571797097,-7.30183771609,16.8628718839,-1.02835845055e-12,12.6471539129,7.30183771609,8.43143594193,14.6036754322,2.26427548746e-13,14.6036754322,-8.43143594193,14.6036754322,-12.6471539129,7.30183771609,-16.8628718839,-1.39630321727e-12,-12.6471539129,-7.30183771609,-8.43143594193,-14.6036754322,3.7737924791e-14,-14.6036754322,8.43143594193,-14.6036754322,12.6471539129,-7.30183771609,25.2943078258,-1.07553085654e-12,21.0785898548,7.30183771609,16.8628718839,14.6036754322,12.6471539129,21.9055131483,4.21571797096,21.9055131483,-4.21571797097,21.9055131483,-12.6471539129,21.9055131483,-16.8628718839,14.6036754322,-21.0785898548,7.30183771609,-25.2943078258,-1.02835845055e-12,-21.0785898548,-7.30183771609,-16.8628718839,-14.6036754322,-12.6471539129,-21.9055131483,-4.21571797097,-21.9055131483,4.21571797097,-21.9055131483,12.6471539129,-21.9055131483,16.8628718839,-14.6036754322,21.0785898548,-7.30183771609,33.7257437677,-7.45324014622e-13,29.5100257968,7.30183771609,25.2943078258,14.6036754322,21.0785898548,21.9055131483,16.8628718839,29.2073508644,8.43143594193,29.2073508644,-1.20761359331e-12,29.2073508644,-8.43143594193,29.2073508644,-16.8628718839,29.2073508644,-21.0785898548,21.9055131483,-25.2943078258,14.6036754322,-29.5100257968,7.30183771609,-33.7257437677,-7.26455052226e-13,-29.5100257968,-7.30183771609,-25.2943078258,-14.6036754322,-21.0785898548,-21.9055131483,-16.8628718839,-29.2073508644,-8.43143594193,-29.2073508644,4.15117172701e-13,-29.2073508644,8.43143594193,-29.2073508644,16.8628718839,-29.2073508644,21.0785898548,-21.9055131483,25.2943078258,-14.6036754322,29.5100257968,-7.30183771609,42.1571797097,-1.86802727715e-12,37.9414617387,7.30183771609,33.7257437677,14.6036754322,29.5100257968,21.9055131483,25.2943078258,29.2073508644,21.0785898548,36.5091885805,12.6471539129,36.5091885805,4.21571797096,36.5091885805,-4.21571797096,36.5091885805,-12.6471539129,36.5091885805,-21.0785898548,36.5091885805,-25.2943078258,29.2073508644,-29.5100257968,21.9055131483,-33.7257437677,14.6036754322,-37.9414617387,7.30183771609,-42.1571797097,-9.81186044565e-13,-37.9414617387,-7.30183771609,-33.7257437677,-14.6036754322,-29.5100257968,-21.9055131483,-25.2943078258,-29.2073508644,-21.0785898548,-36.5091885805,-12.6471539129,-36.5091885805,-4.21571797097,-36.5091885805,4.21571797097,-36.5091885805,12.6471539129,-36.5091885805,21.0785898548,-36.5091885805,25.2943078258,-29.2073508644,29.5100257968,-21.9055131483,33.7257437677,-14.6036754322,37.9414617387,-7.30183771609,50.5886156516,-6.98151608633e-13,46.3728976806,7.30183771609,42.1571797097,14.6036754322,37.9414617387,21.9055131483,33.7257437677,29.2073508644,29.5100257968,36.5091885805,25.2943078258,43.8110262966,16.8628718839,43.8110262966,8.43143594193,43.8110262966,-1.84915831476e-12,43.8110262966,-8.43143594193,43.8110262966,-16.8628718839,43.8110262966,-25.2943078258,43.8110262966,-29.5100257968,36.5091885805,-33.7257437677,29.2073508644,-37.9414617387,21.9055131483,-42.1571797097,14.6036754322,-46.3728976806,7.30183771609,-50.5886156516,-1.47177906685e-12,-46.3728976806,-7.30183771609,-42.1571797097,-14.6036754322,-37.9414617387,-21.9055131483,-33.7257437677,-29.2073508644,-29.5100257968,-36.5091885805,-25.2943078258,-43.8110262966,-16.8628718839,-43.8110262966,-8.43143594193,-43.8110262966,7.54758495819e-14,-43.8110262966,8.43143594193,-43.8110262966,16.8628718839,-43.8110262966,25.2943078258,-43.8110262966,29.5100257968,-36.5091885805,33.7257437677,-29.2073508644,37.9414617387,-21.9055131483,42.1571797097,-14.6036754322,46.3728976806,-7.30183771609,59.0200515935,-7.9249642061e-13,54.8043336225,7.30183771609,50.5886156516,14.6036754322,46.3728976806,21.9055131483,42.1571797097,29.2073508644,37.9414617387,36.5091885805,33.7257437677,43.8110262966,29.5100257968,51.1128640127,21.0785898548,51.1128640127,12.6471539129,51.1128640127,4.21571797096,51.1128640127,-4.21571797096,51.1128640127,-12.6471539129,51.1128640127,-21.0785898548,51.1128640127,-29.5100257968,51.1128640127,-33.7257437677,43.8110262966,-37.9414617387,36.5091885805,-42.1571797097,29.2073508644,-46.3728976806,21.9055131483,-50.5886156516,14.6036754322,-54.8043336226,7.30183771609,-59.0200515935,-1.31139288649e-12,-54.8043336226,-7.30183771609,-50.5886156516,-14.6036754322,-46.3728976806,-21.9055131483,-42.1571797097,-29.2073508644,-37.9414617387,-36.5091885805,-33.7257437677,-43.8110262966,-29.5100257968,-51.1128640127,-21.0785898548,-51.1128640127,-12.6471539129,-51.1128640127,-4.21571797097,-51.1128640127,4.21571797097,-51.1128640127,12.6471539129,-51.1128640127,21.0785898548,-51.1128640127,29.5100257968,-51.1128640127,33.7257437677,-43.8110262966,37.9414617387,-36.5091885805,42.1571797097,-29.2073508644,46.3728976806,-21.9055131483,50.5886156516,-14.6036754322,54.8043336225,-7.30183771609,67.4514875354,-2.14162723189e-12,63.2357695645,7.30183771609,59.0200515935,14.6036754322,54.8043336226,21.9055131483,50.5886156516,29.2073508644,46.3728976806,36.5091885805,42.1571797097,43.8110262966,37.9414617387,51.1128640127,33.7257437677,58.4147017287,25.2943078258,58.4147017287,16.8628718839,58.4147017287,8.43143594193,58.4147017287,6.79282646237e-13,58.4147017287,-8.43143594193,58.4147017287,-16.8628718839,58.4147017287,-25.2943078258,58.4147017287,-33.7257437677,58.4147017287,-37.9414617387,51.1128640127,-42.1571797097,43.8110262966,-46.3728976806,36.5091885805,-50.5886156516,29.2073508644,-54.8043336226,21.9055131483,-59.0200515935,14.6036754322,-63.2357695645,7.30183771609,-67.4514875354,-1.16044118732e-12,-63.2357695645,-7.30183771609,-59.0200515935,-14.6036754322,-54.8043336226,-21.9055131483,-50.5886156516,-29.2073508644,-46.3728976806,-36.5091885805,-42.1571797097,-43.8110262966,-37.9414617387,-51.1128640127,-33.7257437677,-58.4147017287,-25.2943078258,-58.4147017287,-16.8628718839,-58.4147017287,-8.43143594193,-58.4147017287,-5.66068871864e-14,-58.4147017287,8.43143594193,-58.4147017287,16.8628718839,-58.4147017287,25.2943078258,-58.4147017287,33.7257437677,-58.4147017287,37.9414617387,-51.1128640127,42.1571797097,-43.8110262966,46.3728976806,-36.5091885805,50.5886156516,-29.2073508644,54.8043336226,-21.9055131483,59.0200515935,-14.6036754322,63.2357695645,-7.30183771609,75.8829234774,-2.29257893105e-12,71.6672055064,7.30183771609,67.4514875354,14.6036754322,63.2357695645,21.9055131483,59.0200515935,29.2073508644,54.8043336226,36.5091885805,50.5886156516,43.8110262966,46.3728976806,51.1128640127,42.1571797097,58.4147017287,37.9414617387,65.7165394448,29.5100257968,65.7165394448,21.0785898548,65.7165394448,12.6471539129,65.7165394448,4.21571797097,65.7165394448,-4.21571797096,65.7165394448,-12.6471539129,65.7165394448,-21.0785898548,65.7165394448,-29.5100257968,65.7165394448,-37.9414617387,65.7165394448,-42.1571797097,58.4147017287,-46.3728976806,51.1128640127,-50.5886156516,43.8110262966,-54.8043336226,36.5091885805,-59.0200515935,29.2073508644,-63.2357695645,21.9055131483,-67.4514875354,14.6036754322,-71.6672055064,7.30183771609,-75.8829234774,-1.31139288649e-12,-71.6672055064,-7.30183771609,-67.4514875354,-14.6036754322,-63.2357695645,-21.9055131483,-59.0200515935,-29.2073508644,-54.8043336226,-36.5091885805,-50.5886156516,-43.8110262966,-46.3728976806,-51.1128640127,-42.1571797097,-58.4147017287,-37.9414617387,-65.7165394448,-29.5100257968,-65.7165394448,-21.0785898548,-65.7165394448,-12.6471539129,-65.7165394448,-4.21571797097,-65.7165394448,4.21571797097,-65.7165394448,12.6471539129,-65.7165394448,21.0785898548,-65.7165394448,29.5100257968,-65.7165394448,37.9414617387,-65.7165394448,42.1571797097,-58.4147017287,46.3728976806,-51.1128640127,50.5886156516,-43.8110262966,54.8043336226,-36.5091885805,59.0200515935,-29.2073508644,63.2357695645,-21.9055131483,67.4514875354,-14.6036754322,71.6672055064,-7.30183771609,84.3143594193,-1.49064802924e-12,80.0986414483,7.30183771609,75.8829234774,14.6036754322,71.6672055064,21.9055131483,67.4514875354,29.2073508644,63.2357695645,36.5091885805,59.0200515935,43.8110262966,54.8043336226,51.1128640127,50.5886156516,58.4147017287,46.3728976806,65.7165394448,42.1571797097,73.0183771609,33.7257437677,73.0183771609,25.2943078258,73.0183771609,16.8628718839,73.0183771609,8.43143594193,73.0183771609,2.0755858635e-12,73.0183771609,-8.43143594193,73.0183771609,-16.8628718839,73.0183771609,-25.2943078258,73.0183771609,-33.7257437677,73.0183771609,-42.1571797097,73.0183771609,-46.3728976806,65.7165394448,-50.5886156516,58.4147017287,-54.8043336226,51.1128640127,-59.0200515935,43.8110262966,-63.2357695645,36.5091885805,-67.4514875354,29.2073508644,-71.6672055064,21.9055131483,-75.8829234774,14.6036754322,-80.0986414483,7.30183771609,-84.3143594193,-1.11326878133e-12,-80.0986414483,-7.30183771609,-75.8829234774,-14.6036754322,-71.6672055064,-21.9055131483,-67.4514875354,-29.2073508644,-63.2357695645,-36.5091885805,-59.0200515935,-43.8110262966,-54.8043336226,-51.1128640127,-50.5886156516,-58.4147017287,-46.3728976806,-65.7165394448,-42.1571797097,-73.0183771609,-33.7257437677,-73.0183771609,-25.2943078258,-73.0183771609,-16.8628718839,-73.0183771609,-8.43143594193,-73.0183771609,-5.66068871864e-14,-73.0183771609,8.43143594193,-73.0183771609,16.8628718839,-73.0183771609,25.2943078258,-73.0183771609,33.7257437677,-73.0183771609,42.1571797097,-73.0183771609,46.3728976806,-65.7165394448,50.5886156516,-58.4147017287,54.8043336226,-51.1128640127,59.0200515935,-43.8110262966,63.2357695645,-36.5091885805,67.4514875354,-29.2073508644,71.6672055064,-21.9055131483,75.8829234774,-14.6036754322,80.0986414483,-7.3018377161] + conn=[0,2,3,4,5,6,1,1,8,2,0,6,18,7,2,9,10,3,0,1,8,3,10,11,12,4,0,2,4,3,12,13,14,5,0,5,0,4,14,15,16,6,6,1,0,5,16,17,18,7,20,8,1,18,36,19,8,21,9,2,1,7,20,9,22,23,10,2,8,21,10,23,24,11,3,2,9,11,24,25,26,12,3,10,12,11,26,27,13,4,3,13,12,27,28,29,14,4,14,4,13,29,30,15,5,15,5,14,30,31,32,16,16,6,5,15,32,33,17,17,18,6,16,33,34,35,18,7,1,6,17,35,36,19,38,20,7,36,60,37,20,39,21,8,7,19,38,21,40,22,9,8,20,39,22,41,42,23,9,21,40,23,42,43,24,10,9,22,24,43,44,25,11,10,23,25,44,45,46,26,11,24,26,25,46,47,27,12,11,27,26,47,48,28,13,12,28,27,48,49,50,29,13,29,13,28,50,51,30,14,30,14,29,51,52,31,15,31,15,30,52,53,54,32,32,16,15,31,54,55,33,33,17,16,32,55,56,34,34,35,17,33,56,57,58,35,36,18,17,34,58,59,36,19,7,18,35,59,60,37,62,38,19,60,90,61,38,63,39,20,19,37,62,39,64,40,21,20,38,63,40,65,41,22,21,39,64,41,66,67,42,22,40,65,42,67,68,43,23,22,41,43,68,69,44,24,23,42,44,69,70,45,25,24,43,45,70,71,72,46,25,44,46,45,72,73,47,26,25,47,46,73,74,48,27,26,48,47,74,75,49,28,27,49,48,75,76,77,50,28,50,28,49,77,78,51,29,51,29,50,78,79,52,30,52,30,51,79,80,53,31,53,31,52,80,81,82,54,54,32,31,53,82,83,55,55,33,32,54,83,84,56,56,34,33,55,84,85,57,57,58,34,56,85,86,87,58,59,35,34,57,87,88,59,60,36,35,58,88,89,60,37,19,36,59,89,90,61,92,62,37,90,126,91,62,93,63,38,37,61,92,63,94,64,39,38,62,93,64,95,65,40,39,63,94,65,96,66,41,40,64,95,66,97,98,67,41,65,96,67,98,99,68,42,41,66,68,99,100,69,43,42,67,69,100,101,70,44,43,68,70,101,102,71,45,44,69,71,102,103,104,72,45,70,72,71,104,105,73,46,45,73,72,105,106,74,47,46,74,73,106,107,75,48,47,75,74,107,108,76,49,48,76,75,108,109,110,77,49,77,49,76,110,111,78,50,78,50,77,111,112,79,51,79,51,78,112,113,80,52,80,52,79,113,114,81,53,81,53,80,114,115,116,82,82,54,53,81,116,117,83,83,55,54,82,117,118,84,84,56,55,83,118,119,85,85,57,56,84,119,120,86,86,87,57,85,120,121,122,87,88,58,57,86,122,123,88,89,59,58,87,123,124,89,90,60,59,88,124,125,90,61,37,60,89,125,126,91,128,92,61,126,168,127,92,129,93,62,61,91,128,93,130,94,63,62,92,129,94,131,95,64,63,93,130,95,132,96,65,64,94,131,96,133,97,66,65,95,132,97,134,135,98,66,96,133,98,135,136,99,67,66,97,99,136,137,100,68,67,98,100,137,138,101,69,68,99,101,138,139,102,70,69,100,102,139,140,103,71,70,101,103,140,141,142,104,71,102,104,103,142,143,105,72,71,105,104,143,144,106,73,72,106,105,144,145,107,74,73,107,106,145,146,108,75,74,108,107,146,147,109,76,75,109,108,147,148,149,110,76,110,76,109,149,150,111,77,111,77,110,150,151,112,78,112,78,111,151,152,113,79,113,79,112,152,153,114,80,114,80,113,153,154,115,81,115,81,114,154,155,156,116,116,82,81,115,156,157,117,117,83,82,116,157,158,118,118,84,83,117,158,159,119,119,85,84,118,159,160,120,120,86,85,119,160,161,121,121,122,86,120,161,162,163,122,123,87,86,121,163,164,123,124,88,87,122,164,165,124,125,89,88,123,165,166,125,126,90,89,124,166,167,126,91,61,90,125,167,168,127,170,128,91,168,216,169,128,171,129,92,91,127,170,129,172,130,93,92,128,171,130,173,131,94,93,129,172,131,174,132,95,94,130,173,132,175,133,96,95,131,174,133,176,134,97,96,132,175,134,177,178,135,97,133,176,135,178,179,136,98,97,134,136,179,180,137,99,98,135,137,180,181,138,100,99,136,138,181,182,139,101,100,137,139,182,183,140,102,101,138,140,183,184,141,103,102,139,141,184,185,186,142,103,140,142,141,186,187,143,104,103,143,142,187,188,144,105,104,144,143,188,189,145,106,105,145,144,189,190,146,107,106,146,145,190,191,147,108,107,147,146,191,192,148,109,108,148,147,192,193,194,149,109,149,109,148,194,195,150,110,150,110,149,195,196,151,111,151,111,150,196,197,152,112,152,112,151,197,198,153,113,153,113,152,198,199,154,114,154,114,153,199,200,155,115,155,115,154,200,201,202,156,156,116,115,155,202,203,157,157,117,116,156,203,204,158,158,118,117,157,204,205,159,159,119,118,158,205,206,160,160,120,119,159,206,207,161,161,121,120,160,207,208,162,162,163,121,161,208,209,210,163,164,122,121,162,210,211,164,165,123,122,163,211,212,165,166,124,123,164,212,213,166,167,125,124,165,213,214,167,168,126,125,166,214,215,168,127,91,126,167,215,216,169,218,170,127,216,270,217,170,219,171,128,127,169,218,171,220,172,129,128,170,219,172,221,173,130,129,171,220,173,222,174,131,130,172,221,174,223,175,132,131,173,222,175,224,176,133,132,174,223,176,225,177,134,133,175,224,177,226,227,178,134,176,225,178,227,228,179,135,134,177,179,228,229,180,136,135,178,180,229,230,181,137,136,179,181,230,231,182,138,137,180,182,231,232,183,139,138,181,183,232,233,184,140,139,182,184,233,234,185,141,140,183,185,234,235,236,186,141,184,186,185,236,237,187,142,141,187,186,237,238,188,143,142,188,187,238,239,189,144,143,189,188,239,240,190,145,144,190,189,240,241,191,146,145,191,190,241,242,192,147,146,192,191,242,243,193,148,147,193,192,243,244,245,194,148,194,148,193,245,246,195,149,195,149,194,246,247,196,150,196,150,195,247,248,197,151,197,151,196,248,249,198,152,198,152,197,249,250,199,153,199,153,198,250,251,200,154,200,154,199,251,252,201,155,201,155,200,252,253,254,202,202,156,155,201,254,255,203,203,157,156,202,255,256,204,204,158,157,203,256,257,205,205,159,158,204,257,258,206,206,160,159,205,258,259,207,207,161,160,206,259,260,208,208,162,161,207,260,261,209,209,210,162,208,261,262,263,210,211,163,162,209,263,264,211,212,164,163,210,264,265,212,213,165,164,211,265,266,213,214,166,165,212,266,267,214,215,167,166,213,267,268,215,216,168,167,214,268,269,216,169,127,168,215,269,270,217,272,218,169,270,330,271,218,273,219,170,169,217,272,219,274,220,171,170,218,273,220,275,221,172,171,219,274,221,276,222,173,172,220,275,222,277,223,174,173,221,276,223,278,224,175,174,222,277,224,279,225,176,175,223,278,225,280,226,177,176,224,279,226,281,282,227,177,225,280,227,282,283,228,178,177,226,228,283,284,229,179,178,227,229,284,285,230,180,179,228,230,285,286,231,181,180,229,231,286,287,232,182,181,230,232,287,288,233,183,182,231,233,288,289,234,184,183,232,234,289,290,235,185,184,233,235,290,291,292,236,185,234,236,235,292,293,237,186,185,237,236,293,294,238,187,186,238,237,294,295,239,188,187,239,238,295,296,240,189,188,240,239,296,297,241,190,189,241,240,297,298,242,191,190,242,241,298,299,243,192,191,243,242,299,300,244,193,192,244,243,300,301,302,245,193,245,193,244,302,303,246,194,246,194,245,303,304,247,195,247,195,246,304,305,248,196,248,196,247,305,306,249,197,249,197,248,306,307,250,198,250,198,249,307,308,251,199,251,199,250,308,309,252,200,252,200,251,309,310,253,201,253,201,252,310,311,312,254,254,202,201,253,312,313,255,255,203,202,254,313,314,256,256,204,203,255,314,315,257,257,205,204,256,315,316,258,258,206,205,257,316,317,259,259,207,206,258,317,318,260,260,208,207,259,318,319,261,261,209,208,260,319,320,262,262,263,209,261,320,321,322,263,264,210,209,262,322,323,264,265,211,210,263,323,324,265,266,212,211,264,324,325,266,267,213,212,265,325,326,267,268,214,213,266,326,327,268,269,215,214,267,327,328,269,270,216,215,268,328,329,270,217,169,216,269,329,330,271,272,217,330,273,218,217,271,274,219,218,272,275,220,219,273,276,221,220,274,277,222,221,275,278,223,222,276,279,224,223,277,280,225,224,278,281,226,225,279,281,282,226,280,283,227,226,281,284,228,227,282,285,229,228,283,286,230,229,284,287,231,230,285,288,232,231,286,289,233,232,287,290,234,233,288,291,235,234,289,291,292,235,290,291,293,236,235,292,294,237,236,293,295,238,237,294,296,239,238,295,297,240,239,296,298,241,240,297,299,242,241,298,300,243,242,299,301,244,243,301,300,302,244,244,301,303,245,245,302,304,246,246,303,305,247,247,304,306,248,248,305,307,249,249,306,308,250,250,307,309,251,251,308,310,252,252,309,311,253,311,253,310,312,254,253,311,313,255,254,312,314,256,255,313,315,257,256,314,316,258,257,315,317,259,258,316,318,260,259,317,319,261,260,318,320,262,261,319,321,321,322,262,320,323,263,262,321,324,264,263,322,325,265,264,323,326,266,265,324,327,267,266,325,328,268,267,326,329,269,268,327,330,270,269,328,271,217,270,329] + connI=[0,7,14,21,28,35,42,49,56,63,70,77,84,91,98,105,112,119,126,133,140,147,154,161,168,175,182,189,196,203,210,217,224,231,238,245,252,259,266,273,280,287,294,301,308,315,322,329,336,343,350,357,364,371,378,385,392,399,406,413,420,427,434,441,448,455,462,469,476,483,490,497,504,511,518,525,532,539,546,553,560,567,574,581,588,595,602,609,616,623,630,637,644,651,658,665,672,679,686,693,700,707,714,721,728,735,742,749,756,763,770,777,784,791,798,805,812,819,826,833,840,847,854,861,868,875,882,889,896,903,910,917,924,931,938,945,952,959,966,973,980,987,994,1001,1008,1015,1022,1029,1036,1043,1050,1057,1064,1071,1078,1085,1092,1099,1106,1113,1120,1127,1134,1141,1148,1155,1162,1169,1176,1183,1190,1197,1204,1211,1218,1225,1232,1239,1246,1253,1260,1267,1274,1281,1288,1295,1302,1309,1316,1323,1330,1337,1344,1351,1358,1365,1372,1379,1386,1393,1400,1407,1414,1421,1428,1435,1442,1449,1456,1463,1470,1477,1484,1491,1498,1505,1512,1519,1526,1533,1540,1547,1554,1561,1568,1575,1582,1589,1596,1603,1610,1617,1624,1631,1638,1645,1652,1659,1666,1673,1680,1687,1694,1701,1708,1715,1722,1729,1736,1743,1750,1757,1764,1771,1778,1785,1792,1799,1806,1813,1820,1827,1834,1841,1848,1855,1862,1869,1876,1883,1890,1897,1901,1905,1909,1913,1917,1921,1925,1929,1933,1937,1941,1945,1949,1953,1957,1961,1965,1969,1973,1977,1981,1985,1989,1993,1997,2001,2005,2009,2013,2017,2021,2025,2029,2033,2037,2041,2045,2049,2053,2057,2061,2065,2069,2073,2077,2081,2085,2089,2093,2097,2101,2105,2109,2113,2117,2121,2125,2129,2133,2137] + # + m=MEDCouplingUMesh.New("convexhull",2); + m.allocateCells(331); + for i in xrange(331): + m.insertNextCell(NORM_POLYGON,conn[connI[i]:connI[i+1]]); + pass + m.finishInsertingCells(); + coordsDa=DataArrayDouble.New(coords,331,2); + m.setCoords(coordsDa); + m.checkCoherency(); + # + da=m.convexEnvelop2D(); + m.checkCoherency() + self.assertEqual(coordsDa.getHiddenCppPointer(),m.getCoords().getHiddenCppPointer()) + daC=da.buildComplement(m.getNumberOfCells()); + expected2=DataArrayInt.New([271,272,273,274,275,276,277,278,279,280,281,282,283,284,285,286,287,288,289,290,291,292,293,294,295,296,297,298,299,300,302,303,304,305,306,307,308,309,310,312,313,314,315,316,317,318,319,320,321,322,323,324,325,326,327,328,329,330]); + self.assertTrue(expected2.isEqual(daC)); + # + vals=m.getMeasureField(ON_CELLS).getArray() + ref=271*[184.69493088478035]+3*[-61.564976961404426,-92.34746544254946,-92.34746544259811,-92.34746544253488,-92.3474654425349,-92.34746544180479,-92.34746544253493,-92.3474654419026,-92.34746544190256,-92.34746544253491]+2*[61.564976961404426,-92.34746544254946,-92.34746544259811,-92.34746544253488,-92.3474654425349,-92.34746544180479,-92.34746544253493,-92.3474654419026,-92.34746544190256,-92.34746544253491]+[-61.564976961404426,-92.34746544254946,-92.34746544259811,-92.34746544253488,-92.3474654425349,-92.34746544180479,-92.34746544253493,-92.3474654419026,-92.34746544190256,-92.34746544253491] + vals-=DataArrayDouble.New(ref) + vals.abs() + theTest=vals.getIdsInRange(-1.,1e-7) + self.assertTrue(theTest.isIdentity()) + self.assertEqual(331,len(theTest)) + pass + + def testSwigDAIOp8(self): + da=DataArrayInt.New([7,5,6,7,8,9,9,10,12,13,47,15]) + self.assertTrue(7 in da) + self.assertTrue(47 in da) + self.assertTrue(15 in da) + self.assertEqual(0,da.index(7)) + self.assertEqual(10,da.index(47)) + self.assertTrue(14 not in da) + self.assertEqual(5,da.search([9,9])) + self.assertEqual(-1,da.search([5,8])) + da.rearrange(2) + self.assertTrue([47,16] not in da) + self.assertTrue([5,6] not in da) + self.assertTrue([6,7] in da) + self.assertEqual(4,da.index([12,13])) + pass + + def testDataArraySort1(self): + arr=DataArrayInt.New(); + self.assertRaises(InterpKernelException,arr.sort,True) + self.assertRaises(InterpKernelException,arr.sort,False) + values=[2,1,6,5,4,7] + arr.alloc(3,2); + self.assertRaises(InterpKernelException,arr.sort,True) + self.assertRaises(InterpKernelException,arr.sort,False) + arr.rearrange(1); + arr.setValues(values,6,1) + arr1=arr.deepCpy(); + arr2=arr.deepCpy(); + arr1.sort(True); + expected1=[1,2,4,5,6,7] + self.assertEqual(6,arr1.getNumberOfTuples()); + self.assertEqual(1,arr1.getNumberOfComponents()); + self.assertEqual(expected1,arr1.getValues()); + arr2.sort(False); + expected2=[7,6,5,4,2,1] + self.assertEqual(6,arr2.getNumberOfTuples()); + self.assertEqual(1,arr2.getNumberOfComponents()); + self.assertTrue(expected2,arr2.getValues()); + # + ard=DataArrayDouble.New(); + self.assertRaises(InterpKernelException,ard.sort,True) + self.assertRaises(InterpKernelException,ard.sort,False) + valuesD=[2.,1.,6.,5.,4.,7.] + ard.alloc(3,2); + self.assertRaises(InterpKernelException,ard.sort,True) + self.assertRaises(InterpKernelException,ard.sort,False) + ard.rearrange(1); + ard.setValues(valuesD,6,1) + ard1=ard.deepCpy(); + ard2=ard.deepCpy(); + ard1.sort(True); + expected3=[1.,2.,4.,5.,6.,7.] + self.assertEqual(6,ard1.getNumberOfTuples()); + self.assertEqual(1,ard1.getNumberOfComponents()); + for i in xrange(6): + self.assertAlmostEqual(expected3[i],ard1.getIJ(i,0),12) + pass + ard2.sort(False); + expected4=[7.,6.,5.,4.,2.,1.] + self.assertEqual(6,ard2.getNumberOfTuples()); + self.assertEqual(1,ard2.getNumberOfComponents()); + for i in xrange(6): + self.assertAlmostEqual(expected4[i],ard2.getIJ(i,0),12) + pass + pass + + def testPartitionBySpreadZone1(self): + m=MEDCouplingDataForTest.build2DTargetMesh_1(); + m4=MEDCouplingUMesh.MergeUMeshes([m,m[-3:],m[0:2]]); + m4.renumberCells([5,2,9,6,4,7,0,1,3,8]); + # + v2=m4.partitionBySpreadZone(); + self.assertTrue(3,len(v2)); + self.assertTrue(v2[0].isEqual(DataArrayInt.New([0,1,7]))) + self.assertTrue(v2[1].isEqual(DataArrayInt.New([2,4,5,6,9]))) + self.assertTrue(v2[2].isEqual(DataArrayInt.New([3,8]))) + # + m5=m4.buildSpreadZonesWithPoly(); + self.assertEqual(3,m5.getNumberOfCells()); + self.assertTrue(m5.getCoords().getHiddenCppPointer()==m4.getCoords().getHiddenCppPointer()); + self.assertEqual([5,15,16,17,14,11,13,12,5,2,1,0,3,6,7,8,5,5,18,21,22,20,19],m5.getNodalConnectivity().getValues()) + self.assertEqual([0,8,17,23],m5.getNodalConnectivityIndex().getValues()) + # + pass + + def testGiveCellsWithType1(self): + expected0=[1,2] + expected1=[0,3,4] + m=MEDCouplingDataForTest.build2DTargetMesh_1(); + da=m.giveCellsWithType(NORM_TRI3); + self.assertEqual(2,da.getNumberOfTuples()); + self.assertEqual(1,da.getNumberOfComponents()); + self.assertEqual(expected0,da.getValues()) + # + da=m.giveCellsWithType(NORM_QUAD4); + self.assertEqual(3,da.getNumberOfTuples()); + self.assertEqual(1,da.getNumberOfComponents()); + self.assertEqual(expected1,da.getValues()) + # + da=m.giveCellsWithType(NORM_TRI6); + self.assertEqual(0,da.getNumberOfTuples()); + self.assertEqual(1,da.getNumberOfComponents()); + # + self.assertRaises(InterpKernelException,m.giveCellsWithType,NORM_SEG2) + self.assertRaises(InterpKernelException,m.giveCellsWithType,NORM_HEXA8) + pass + + def testSwigDAOp1(self): + d=DataArrayDouble.New(5,2) + d.rearrange(1) ; d.iota(2.) ; d.rearrange(2) + d.setInfoOnComponents(["X [m]","Y [m]"]) + d.setName("AName") + # + d1=d+[8,9] + self.assertTrue(d1.isEqualWithoutConsideringStr(DataArrayDouble.New([10.0,12.0,12.0,14.0,14.0,16.0,16.0,18.0,18.0,20.0]),1e-12)) + d1bis=DataArrayDouble.New([8,9],1,2)+d + self.assertTrue(d1bis.isEqual(d1,1e-12)) + d1ter=[8,9]+d + self.assertTrue(d1ter.isEqual(d1,1e-12)) + # + d2=d1-[8,9] + self.assertTrue(d2.isEqual(d,1e-12)) + self.assertRaises(InterpKernelException,d1.__rsub__,[8,9])#[8,9]-d1 + # + d3=d*[8,9] + self.assertTrue(d3.isEqualWithoutConsideringStr(DataArrayDouble.New([16.0,27.0,32.0,45.0,48.0,63.0,64.0,81.0,80.0,99.0]),1e-12)) + d3bis=DataArrayDouble.New([8,9],1,2)*d + self.assertTrue(d3bis.isEqual(d3,1e-12)) + d3ter=[8,9]*d + self.assertTrue(d3ter.isEqual(d3,1e-12)) + # + d4=d3/[8,9] + self.assertTrue(d4.isEqual(d,1e-12)) + # + d=DataArrayInt.New(5,2) + d.rearrange(1) ; d.iota(2) ; d.rearrange(2) + d.setInfoOnComponents(["X [m]","Y [m]"]) + d.setName("AName") + # + d1=d+[8,9] + self.assertEqual(d1.getValues(),[10,12,12,14,14,16,16,18,18,20]) + d1bis=DataArrayInt.New([8,9],1,2)+d + self.assertTrue(d1bis.isEqual(d1)) + d1ter=[8,9]+d + self.assertTrue(d1ter.isEqual(d1)) + # + d2=d1-[8,9] + self.assertTrue(d2.isEqual(d)) + self.assertRaises(InterpKernelException,d1.__rsub__,[8,9]) + # + d3=d*[8,9] + self.assertEqual(d3.getValues(),[16,27,32,45,48,63,64,81,80,99]) + d3bis=DataArrayInt.New([8,9],1,2)*d + self.assertTrue(d3bis.isEqual(d3)) + d3ter=[8,9]*d + self.assertTrue(d3ter.isEqual(d3)) + # + d4=d3/[8,9] + self.assertTrue(d4.isEqual(d)) + # + d5=d%[4,5] + self.assertEqual(d5.getValues(),[2,3,0,0,2,2,0,4,2,1]) + pass + + def testSwigSelectTupleId2DAIBug1(self): + da=DataArrayInt.New([0,1,2,3,12,13,4,5,6,7,14,15,8,9,10,11,16,17]) + self.assertEqual([2,6,10],da[2::6].getValues()) + self.assertEqual([0,4,8],da[::6].getValues()) + self.assertEqual([5,9],da[7::6].getValues()) + self.assertEqual([5],da[7:-5:6].getValues()) + pass + + def testSwigCpp5Safe1(self): + m=MEDCouplingUMesh.New("toto",2) + coords=DataArrayDouble.New([0.,0.,1.,0.,1.,1.,0.,1.],4,2) + m.setCoords(coords) + vecs=DataArrayDouble.New([2.,3.,4.,5.,6.,7.],3,2) + expected1=[[2.,3.,3.,3.,3.,4.,2.,4.0],[4.,5.,5.,5.,5.,6.,4.,6.0],[6.,7.,7.,7.,7.,8.,6.,8.0]] + for pos,vec in enumerate(vecs): + m2=m.deepCpy() + m2.translate(vec) + self.assertTrue(m2.getCoords().isEqual(DataArrayDouble.New(expected1[pos],4,2),1e-12)) + pass + for pos,vec in enumerate(vecs): + m2=m.deepCpy() + m2.translate(vec.buildDADouble()) + self.assertTrue(m2.getCoords().isEqual(DataArrayDouble.New(expected1[pos],4,2),1e-12)) + pass + pass + + def testSwigBugNonRegressionZipDA(self): + angles=map(lambda x:pi/3*x,xrange(6)) + radius=3 + # + dad=DataArrayDouble.New(6, 2) + dad[:,0]=radius + dad[:,1]=angles + # + dad2=dad.fromPolarToCart() + dads=[dad2.deepCpy() for elt in 7*[None]] + # + translationToPerform=[[0.01,0.02],[3./2.*radius,-radius*sqrt(3.)/2],[3./2.*radius,radius*sqrt(3.)/2],[0.,radius*sqrt(3.)],[-3./2.*radius,radius*sqrt(3.)/2],[-3./2.*radius,-radius*sqrt(3.)/2],[0.,-radius*sqrt(3.)]] + for d,t in zip(dads,translationToPerform): + d+=t + pass + for elt in dads: + self.assertTrue(not dad2.isEqual(elt,1e-12)) + pass + for d,t in zip(dads,translationToPerform): + d-=t + pass + for elt in dads: + self.assertTrue(dad2.isEqual(elt,1e-12)) + pass + pass + + def testBuildSlice3D2(self): + mesh3D,mesh2D=MEDCouplingDataForTest.build3DExtrudedUMesh_1(); + vec1=[-0.07,1.,0.07] + origin1=[1.524,1.4552,1.74768] + slice1,ids=mesh3D.buildSlice3D(origin1,vec1,1e-10); + f=MEDCouplingFieldDouble(ON_CELLS,ONE_TIME) + f.setTime(4.5,6,7) ; f.setMesh(mesh3D) + arr=DataArrayDouble(mesh3D.getNumberOfCells(),2) + arr.rearrange(1) ; arr.iota(2.) ; arr.rearrange(2) + f.setArray(arr) + f.checkCoherency() + expected1=DataArrayInt([1,3,4,7,9,10,13,15,16]) + self.assertTrue(expected1.isEqual(ids)) + arr2=arr[expected1] + # + f2=f.extractSlice3D(origin1,vec1,1e-10) + self.assertTrue(f2.getArray().isEqual(arr2,1e-12)); + self.assertTrue(slice1.isEqual(f2.getMesh(),1e-12)) + self.assertEqual(6,f2.getTime()[1]) ; self.assertEqual(7,f2.getTime()[2]) + self.assertAlmostEqual(4.5,f2.getTime()[0],12); + pass + + def testComputeTupleIdsToSelectFromCellIds1(self): + m=MEDCouplingDataForTest.build2DTargetMesh_3() + f=MEDCouplingFieldDouble.New(ON_GAUSS_NE,NO_TIME); + f.setMesh(m); + arr=DataArrayDouble(52,2) ; arr.rearrange(1) ; arr.iota(7.) ; arr.rearrange(2) + f.setArray(arr) + # + f2=f.buildSubPart([1,5,9]) + f2.checkCoherency() + cI=m.computeNbOfNodesPerCell() + cI.computeOffsets2() + sel=DataArrayInt([1,5,9]) + res=sel.buildExplicitArrByRanges(cI) + arr2=arr[res] + self.assertTrue(arr2.isEqual(DataArrayDouble([13,14,15,16,17,18,19,20,59,60,61,62,63,64,95,96,97,98,99,100,101,102,103,104,105,106,107,108,109,110],15,2),1e-12)) + self.assertTrue(arr2.isEqual(f2.getArray(),1e-12)) + pass + + def testComputeSkin1(self): + arrX=DataArrayDouble([2.,3.4,5.6,7.7,8.0]) ; arrY=DataArrayDouble([2.,3.4,5.6,7.7,9.0,14.2]) + cmesh=MEDCouplingCMesh() ; cmesh.setCoordsAt(0,arrX) ; cmesh.setCoordsAt(1,arrY) + umesh=cmesh.buildUnstructured() + # + skin=umesh.computeSkin() + self.assertEqual(18,skin.getNumberOfCells()) + self.assertEqual(1,skin.getMeshDimension()) + self.assertTrue(skin.getCoords().getHiddenCppPointer()==umesh.getCoords().getHiddenCppPointer()) + self.assertEqual([0,3,6,9,12,15,18,21,24,27,30,33,36,39,42,45,48,51,54],skin.getNodalConnectivityIndex().getValues()) + self.assertEqual([1,1,0,1,0,5,1,2,1,1,3,2,1,4,3,1,9,4,1,5,10,1,14,9,1,10,15,1,19,14,1,15,20,1,24,19,1,20,25,1,25,26,1,26,27,1,27,28,1,28,29,1,29,24],skin.getNodalConnectivity().getValues()) + ids=skin.computeFetchedNodeIds() + self.assertEqual([0,1,2,3,4,5,9,10,14,15,19,20,24,25,26,27,28,29],ids.getValues()) + part=umesh.buildFacePartOfMySelfNode(ids,True) + part.setName(skin.getName()); + self.assertTrue(part.isEqual(skin,1e-12)) + part2=part[1::2] + part[::2]=part2 + self.assertTrue(not part.isEqual(skin,1e-12)) + trad=part.zipConnectivityTraducer(0) + self.assertEqual(9,part.getNumberOfCells()) + self.assertEqual([0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8],trad.getValues()) + pass + + def testUMeshSetPartOfMySelf2(self): + # resize with explicit ids list + m=MEDCouplingDataForTest.build2DTargetMesh_1() + self.assertEqual([3,4],m.getAllGeoTypes()) + part=m[[0,3,4]] + part.simplexize(0) + part2=part[[1,2,5]] + m[[0,3,4]]=part2 + self.assertEqual([3,0,4,1,3,1,4,2,3,4,5,2,3,6,7,4,3,7,5,4],m.getNodalConnectivity().getValues()) + self.assertEqual([0,4,8,12,16,20],m.getNodalConnectivityIndex().getValues()) + self.assertEqual([3],m.getAllGeoTypes()) + # no resize with explicit ids list + m=MEDCouplingDataForTest.build2DTargetMesh_1() + part=m[[0,3]] + part.convertAllToPoly() + m[[3,4]]=part + self.assertEqual([4,0,3,4,1,3,1,4,2,3,4,5,2,5,0,3,4,1,5,6,7,4,3],m.getNodalConnectivity().getValues()) + self.assertEqual([0,5,9,13,18,23],m.getNodalConnectivityIndex().getValues()) + self.assertEqual([3,4,5],m.getAllGeoTypes()) + # resize with range ids + m=MEDCouplingDataForTest.build2DTargetMesh_1() + part=m[3:] + m[1:3]=part + self.assertEqual([4,0,3,4,1,4,6,7,4,3,4,7,8,5,4,4,6,7,4,3,4,7,8,5,4],m.getNodalConnectivity().getValues()) + self.assertEqual([0,5,10,15,20,25],m.getNodalConnectivityIndex().getValues()) + self.assertEqual([4],m.getAllGeoTypes()) + # no resize with range ids + m=MEDCouplingDataForTest.build2DTargetMesh_1() + part=m[0::3] + part.convertAllToPoly() + m[3:]=part + self.assertEqual([4,0,3,4,1,3,1,4,2,3,4,5,2,5,0,3,4,1,5,6,7,4,3],m.getNodalConnectivity().getValues()) + self.assertEqual([0,5,9,13,18,23],m.getNodalConnectivityIndex().getValues()) + self.assertEqual([3,4,5],m.getAllGeoTypes()) + # no resize with range ids negative direction + m=MEDCouplingDataForTest.build2DTargetMesh_1() + part=m[3::-3] + part.convertAllToPoly() + m[:-3:-1]=part + self.assertEqual([4,0,3,4,1,3,1,4,2,3,4,5,2,5,0,3,4,1,5,6,7,4,3],m.getNodalConnectivity().getValues()) + self.assertEqual([0,5,9,13,18,23],m.getNodalConnectivityIndex().getValues()) + self.assertEqual([3,4,5],m.getAllGeoTypes()) + pass + + def testUnPolyze3(self): + coord=[0.0,0.5,-0.5,-0.5,-0.5,-0.5,0.5,-0.5,-0.5,0.0,0.5,0.5,-0.5,-0.5,0.5,0.5,-0.5,0.5] + conn=[1,2,5,4,-1,4,3,0,1,-1,2,0,3,5,-1,0,2,1,-1,4,5,3] + m=MEDCouplingUMesh.New("a mesh",3); + m.allocateCells(1); + m.insertNextCell(NORM_POLYHED,22,conn[0:22]) + m.finishInsertingCells(); + coords=DataArrayDouble(coord,6,3); + m.setCoords(coords); + m.checkCoherency(); + # + vol=m.getMeasureField(ON_CELLS); + self.assertEqual(1,vol.getArray().getNumberOfTuples()); + self.assertAlmostEqual(0.5,vol.getArray().getIJ(0,0),12) + # + m.unPolyze(); + # + self.assertEqual([NORM_PENTA6],m.getAllGeoTypes()) + self.assertTrue(DataArrayInt([0,7]).isEqual(m.getNodalConnectivityIndex())) + self.assertTrue(DataArrayInt([16,0,2,1,3,5,4]).isEqual(m.getNodalConnectivity())) + # + vol=m.getMeasureField(ON_CELLS); + self.assertEqual(1,vol.getArray().getNumberOfTuples()); + self.assertAlmostEqual(0.5,vol.getArray().getIJ(0,0),12) + pass + + def testKrSpatialDiscretization1(self): + srcPointCoordsX=[0.8401877171547095, 0.7830992237586059, 0.9116473579367843, 0.335222755714889, 0.2777747108031878, 0.4773970518621602, 0.3647844727918433, 0.9522297251747128, 0.6357117279599009, 0.1416025553558034] + srcFieldValsOnPoints=[2.129892434968836, 2.295320474540621, 1.931948594981134, 2.728013590937196, 2.715603240418478, 2.661778472822935, 2.695696990104364, 1.893710234970982, 2.529628016549284, 2.728432341300668] + targetPointCoordsX=[-0.5,-0.45,-0.4,-0.35,-0.3,-0.25,-0.2,-0.15,-0.1,-0.05,-6.93889390391e-17,0.05,0.1,0.15,0.2,0.25,0.3,0.35,0.4,0.45,0.5,0.55,0.6,0.65,0.7,0.75,0.8,0.85,0.9,0.95,1.0,1.05,1.1,1.15,1.2,1.25,1.3,1.35,1.4,1.45] + targetFieldValsExpected=[2.975379475824351, 2.95613491917003, 2.936890362515361, 2.917645805861018, 2.898401249206574, 2.879156692552137, 2.859912135897732, 2.840667579243201, 2.821423022588731, 2.802178465934342, 2.78293390927989, 2.763689352625457, 2.744444795971001, 2.725209522098197, 2.709077577124666, 2.706677252549218, 2.727467797847971, 2.713338094723676, 2.671342424824244, 2.664877370146978, 2.653840141412181, 2.619607861392791, 2.569777214476479, 2.513263929794591, 2.450732752808528, 2.368313560985155, 2.250909795670307, 2.098194272085416, 1.954257891732065, 1.895040660973802, 1.865256788315972, 1.835475248687992, 1.80569370905998, 1.775912169431971, 1.746130629803976, 1.716349090175918, 1.686567550547855, 1.656786010919941, 1.627004471291988, 1.597222931663817] + coeffsExpected=DataArrayDouble.New([52.238272642008695, 26.186513281350948, -173.42106377948534, 324.56733663875184, -104.64968873410248, 34.375030568158316, -256.12372208190425, 105.2292032463934, -16.239907618144965, 7.838025836978943, 2.621910745077291, -0.4902609628247241]) + # + nbOfInputPoints=10; + f=MEDCouplingFieldDouble.New(ON_NODES_KR,ONE_TIME); + srcArrX=DataArrayDouble.New(srcPointCoordsX,nbOfInputPoints,1); + cmesh=MEDCouplingCMesh.New("aMesh"); + cmesh.setCoordsAt(0,srcArrX); + umesh=cmesh.buildUnstructured(); + f.setMesh(umesh); + srcVals=DataArrayDouble.New(srcFieldValsOnPoints,nbOfInputPoints,1); + f.setArray(srcVals); + f.checkCoherency(); + # + res0=f.getValueOn(targetPointCoordsX[:1]); + self.assertAlmostEqual(targetFieldValsExpected[0],res0[0],10) + # + valuesToTest=f.getValueOnMulti(targetPointCoordsX); + self.assertEqual(40,valuesToTest.getNumberOfTuples()); + self.assertEqual(1,valuesToTest.getNumberOfComponents()); + for i in xrange(40): + self.assertAlmostEqual(targetFieldValsExpected[i],valuesToTest.getIJ(i,0),10) + pass + fd=f.getDiscretization() + del f + self.assertTrue(isinstance(fd,MEDCouplingFieldDiscretizationKriging)) + coeffs,isDrift=fd.computeVectorOfCoefficients(umesh,srcVals) + self.assertEqual(2,isDrift) + self.assertTrue(coeffsExpected.isEqual(coeffs,1e-8)) + # + pass + + def testDuplicateEachTupleNTimes1(self): + d=DataArrayDouble.New([9.,8.,7.,6.],4,1) ; d.setInfoOnComponents(["mass [kg]"]) ; d.setName("aname") + d2=d.duplicateEachTupleNTimes(3) + self.assertTrue(d2.isEqualWithoutConsideringStr(DataArrayDouble.New([9.,9.,9.,8.,8.,8.,7.,7.,7.,6.,6.,6.],4*3,1),1e-14)) + self.assertEqual("aname",d2.getName()) + self.assertEqual(["mass [kg]"],d2.getInfoOnComponents()) + # + d=DataArrayInt.New([9,8,7,6],4,1) ; d.setInfoOnComponents(["mass [kg]"]) ; d.setName("aname") + d2=d.duplicateEachTupleNTimes(3) + self.assertTrue(d2.isEqualWithoutConsideringStr(DataArrayInt.New([9,9,9,8,8,8,7,7,7,6,6,6],4*3,1))) + self.assertEqual("aname",d2.getName()) + self.assertEqual(["mass [kg]"],d2.getInfoOnComponents()) + pass + + def testSwigComputeTupleIdsNearTuples1(self): + da=DataArrayDouble([5.,6.,-5.,-6.,5.,-6.,-5.,6.,5.,6.],5,2) + arr,arrI=da.computeTupleIdsNearTuples(DataArrayDouble([5.,-6.,5.,6.,-5.,-6.],3,2),1e-10) + self.assertEqual([2,0,4,1],arr.getValues()) + self.assertEqual([0,1,3,4],arrI.getValues()) + arr,arrI=da.computeTupleIdsNearTuples([5.,-6.,5.,6.,-5.,-6.],1e-10) + self.assertEqual([2,0,4,1],arr.getValues()) + self.assertEqual([0,1,3,4],arrI.getValues()) + expected0=[[2],[0,4],[1]] + expected1=[[0,1],[0,2],[0,1]] + for pos,it in enumerate(DataArrayDouble([5.,-6.,5.,6.,-5.,-6.],3,2)): + arr,arrI=da.computeTupleIdsNearTuples(it,1e-10) + self.assertEqual(expected0[pos],arr.getValues()) + self.assertEqual(expected1[pos],arrI.getValues()) + pass + pass + + def testSwigDataTupleIOp1(self): + d=DataArrayDouble(10,1) + d.iota(7.) + for elt in d: + elt+=2. + pass + toTest=DataArrayDouble([9.0,10.0,11.0,12.0,13.0,14.0,15.0,16.0,17.0,18.0]) + self.assertTrue(toTest.isEqual(d,1e-12)) + for elt in d: + elt-=2. + pass + toTest=DataArrayDouble([7.0,8.0,9.0,10.0,11.0,12.0,13.0,14.0,15.0,16.0]) + self.assertTrue(toTest.isEqual(d,1e-12)) + for elt in d: + elt*=2. + pass + toTest=DataArrayDouble([14.0,16.0,18.0,20.0,22.0,24.0,26.0,28.0,30.0,32.0]) + self.assertTrue(toTest.isEqual(d,1e-12)) + for elt in d: + elt/=2. + pass + toTest=DataArrayDouble([7.0,8.0,9.0,10.0,11.0,12.0,13.0,14.0,15.0,16.0]) + self.assertTrue(toTest.isEqual(d,1e-12)) + # + d=DataArrayInt(10,1) + d.iota(7) + for elt in d: + elt+=2 + pass + self.assertEqual(d.getValues(),[9,10,11,12,13,14,15,16,17,18]) + for elt in d: + elt-=2 + pass + self.assertEqual(d.getValues(),[7,8,9,10,11,12,13,14,15,16]) + for elt in d: + elt*=2 + pass + self.assertEqual(d.getValues(),[14,16,18,20,22,24,26,28,30,32]) + for elt in d: + elt/=2 + pass + self.assertEqual(d.getValues(),[7,8,9,10,11,12,13,14,15,16]) + for elt in d: + elt%=3 + pass + self.assertEqual(d.getValues(),[1,2,0,1,2,0,1,2,0,1]) + pass + + def testIntersect2DMeshesTmp5(self): + coords=DataArrayDouble.New([41,0,42,0,0,42,0,41,41.5,0,29.698484809834998,29.698484809834994,0,41.5,28.991378028648452,28.991378028648445,-42,0,-41,0,-29.698484809834994,29.698484809834998,-41.5,0,-28.991378028648445,28.991378028648452,0,-42,0,-41,-29.698484809835001,-29.698484809834994,0,-41.5,-28.991378028648455,-28.991378028648445,29.698484809834987,-29.698484809835001,28.991378028648441,-28.991378028648455,43,0,0,43,42.5,0,30.405591591021544,30.40559159102154,0,42.5,-43,0,-30.40559159102154,30.405591591021544,-42.5,0,0,-43,-30.405591591021551,-30.40559159102154,0,-42.5,30.405591591021537,-30.405591591021551,44,0,0,44,43.5,0,31.112698372208094,31.112698372208087,0,43.5,-44,0,-31.112698372208087,31.112698372208094,-43.5,0,0,-44,-31.112698372208097,-31.112698372208087,0,-43.5,31.112698372208083,-31.112698372208097,45,0,0,45,44.5,0,31.81980515339464,31.819805153394636,0,44.5,-45,0,-31.819805153394636,31.81980515339464,-44.5,0,0,-45,-31.819805153394647,-31.819805153394636,0,-44.5,31.819805153394629,-31.819805153394647,47,0,0,47,46,0,33.234018715767739,33.234018715767732,0,46,-47,0,-33.234018715767732,33.234018715767739,-46,0,0,-47,-33.234018715767739,-33.234018715767732,0,-46,33.234018715767725,-33.234018715767739,49,0,0,49,48,0,34.648232278140831,34.648232278140824,0,48,-49,0,-34.648232278140824,34.648232278140831,-48,0,0,-49,-34.648232278140839,-34.648232278140824,0,-48,34.648232278140817,-34.648232278140839,51,0,0,51,50,0,36.062445840513924,36.062445840513924,0,50,-51,0,-36.062445840513924,36.062445840513924,-50,0,0,-51,-36.062445840513931,-36.062445840513924,0,-50,36.062445840513917,-36.062445840513931,53,0,0,53,52,0,37.476659402887023,37.476659402887016,0,52,-53,0,-37.476659402887016,37.476659402887023,-52,0,0,-53,-37.47665940288703,-37.476659402887016,0,-52,37.476659402887009,-37.47665940288703,55,0,0,55,54,0,38.890872965260115,38.890872965260108,0,54,-55,0,-38.890872965260108,38.890872965260115,-54,0,0,-55,-38.890872965260122,-38.890872965260108,0,-54,38.890872965260101,-38.890872965260122,59,0,0,59,57,0,41.719300090006307,41.7193000900063,0,57,-59,0,-41.7193000900063,41.719300090006307,-57,0,0,-59,-41.719300090006314,-41.7193000900063,0,-57,41.719300090006293,-41.719300090006314,63,0,0,63,61,0,44.547727214752499,44.547727214752491,0,61,-63,0,-44.547727214752491,44.547727214752499,-61,0,0,-63,-44.547727214752506,-44.547727214752491,0,-61,44.547727214752484,-44.547727214752506,67,0,0,67,65,0,47.37615433949869,47.376154339498683,0,65,-67,0,-47.376154339498683,47.37615433949869,-65,0,0,-67,-47.376154339498697,-47.376154339498683,0,-65,47.376154339498676,-47.376154339498697,71,0,0,71,69,0,50.204581464244875,50.204581464244868,0,69,-71,0,-50.204581464244868,50.204581464244875,-69,0,0,-71,-50.204581464244889,-50.204581464244868,0,-69,50.20458146424486,-50.204581464244889,75,0,0,75,73,0,53.033008588991066,53.033008588991059,0,73,-75,0,-53.033008588991059,53.033008588991066,-73,0,0,-75,-53.033008588991073,-53.033008588991059,0,-73,53.033008588991052,-53.033008588991073,80,0,0,80,77.5,0,56.568542494923804,56.568542494923797,0,77.5,-80,0,-56.568542494923797,56.568542494923804,-77.5,0,0,-80,-56.568542494923818,-56.568542494923797,0,-77.5,56.56854249492379,-56.568542494923818],188,2) + conn=DataArrayInt.New([8,0,1,2,3,4,5,6,7,8,3,2,8,9,6,10,11,12,8,9,8,13,14,11,15,16,17,8,14,13,1,0,16,18,4,19,8,1,20,21,2,22,23,24,5,8,2,21,25,8,24,26,27,10,8,8,25,28,13,27,29,30,15,8,13,28,20,1,30,31,22,18,8,20,32,33,21,34,35,36,23,8,21,33,37,25,36,38,39,26,8,25,37,40,28,39,41,42,29,8,28,40,32,20,42,43,34,31,8,32,44,45,33,46,47,48,35,8,33,45,49,37,48,50,51,38,8,37,49,52,40,51,53,54,41,8,40,52,44,32,54,55,46,43,8,44,56,57,45,58,59,60,47,8,45,57,61,49,60,62,63,50,8,49,61,64,52,63,65,66,53,8,52,64,56,44,66,67,58,55,8,56,68,69,57,70,71,72,59,8,57,69,73,61,72,74,75,62,8,61,73,76,64,75,77,78,65,8,64,76,68,56,78,79,70,67,8,68,80,81,69,82,83,84,71,8,69,81,85,73,84,86,87,74,8,73,85,88,76,87,89,90,77,8,76,88,80,68,90,91,82,79,8,80,92,93,81,94,95,96,83,8,81,93,97,85,96,98,99,86,8,85,97,100,88,99,101,102,89,8,88,100,92,80,102,103,94,91,8,92,104,105,93,106,107,108,95,8,93,105,109,97,108,110,111,98,8,97,109,112,100,111,113,114,101,8,100,112,104,92,114,115,106,103,8,104,116,117,105,118,119,120,107,8,105,117,121,109,120,122,123,110,8,109,121,124,112,123,125,126,113,8,112,124,116,104,126,127,118,115,8,116,128,129,117,130,131,132,119,8,117,129,133,121,132,134,135,122,8,121,133,136,124,135,137,138,125,8,124,136,128,116,138,139,130,127,8,128,140,141,129,142,143,144,131,8,129,141,145,133,144,146,147,134,8,133,145,148,136,147,149,150,137,8,136,148,140,128,150,151,142,139,8,140,152,153,141,154,155,156,143,8,141,153,157,145,156,158,159,146,8,145,157,160,148,159,161,162,149,8,148,160,152,140,162,163,154,151,8,152,164,165,153,166,167,168,155,8,153,165,169,157,168,170,171,158,8,157,169,172,160,171,173,174,161,8,160,172,164,152,174,175,166,163,8,164,176,177,165,178,179,180,167,8,165,177,181,169,180,182,183,170,8,169,181,184,172,183,185,186,173,8,172,184,176,164,186,187,178,175],540) + connI=DataArrayInt.New([0,9,18,27,36,45,54,63,72,81,90,99,108,117,126,135,144,153,162,171,180,189,198,207,216,225,234,243,252,261,270,279,288,297,306,315,324,333,342,351,360,369,378,387,396,405,414,423,432,441,450,459,468,477,486,495,504,513,522,531,540],61) + # + m1=MEDCouplingUMesh.New("Fix",2); + m1.setCoords(coords); + m1.setConnectivity(conn,connI,True); + # + coords=DataArrayDouble([46.5,-2.5,53.5,-2.5,53.5,2.5,46.5,2.5,50,-2.5,53.5,0,50,2.5,46.5,0,60.5,-2.5,60.5,2.5,57,-2.5,60.5,0,57,2.5,53.5,7.5,46.5,7.5,53.5,5,50,7.5,46.5,5,60.5,7.5,60.5,5,57,7.5,-2,47,2,47,2,53,-2,53,0,47,2,50,0,53,-2,50,6,47,6,53,4,47,6,50,4,53,2,59,-2,59,2,56,0,59,-2,56,6,59,6,56,4,59],42,2) + # connectivity + conn=DataArrayInt([8,0,1,2,3,4,5,6,7,8,1,8,9,2,10,11,12,5,8,3,2,13,14,6,15,16,17,8,2,9,18,13,12,19,20,15,8,21,22,23,24,25,26,27,28,8,22,29,30,23,31,32,33,26,8,24,23,34,35,27,36,37,38,8,23,30,39,34,33,40,41,36],72); + conn.setName(""); + connI=DataArrayInt([0,9,18,27,36,45,54,63,72],9) + m2=MEDCouplingUMesh.New("Mobile",2); + m2.setCoords(coords); + m2.setConnectivity(conn,connI,True); + # + m3,d1,d2=MEDCouplingUMesh.Intersect2DMeshes(m1,m2,1e-10); + self.assertEqual(105,m3.getNumberOfCells()); + self.assertEqual(105,d1.getNumberOfTuples()); + self.assertEqual(105,d2.getNumberOfTuples()); + self.assertEqual(704,m3.getNumberOfNodes()); + # + areaExpected=[-65.18804756198824,-65.18804756198824,-65.18804756198824,-65.18804756198824,-66.75884388878285,-66.75884388878285,-66.7588438887833,-66.75884388878308,-68.32964021557768,-68.32964021557768,-68.32964021557814,-68.32964021557791,-69.9004365423732,-69.9004365423732,-69.90043654237297,-69.90043654237297,-1.194568659706448,-1.0869994447159463,-142.2316939607081,-144.51326206513068,-144.5132620651309,-1.1945686597064424,-143.3186934054243,-5.002264310862817,-10.0261332846393,-3.9727823117092953,-7.290862524642649,-124.504404940456,-3.9727823117093237,-146.82366506060032,-150.79644737231024,-5.002264310862776,-145.79418306144626,-5.00208651738126,-10.054764051268958,-4.001067863263231,-8.027932154428669,-129.99378209314813,-4.001067863263216,-153.07856481622616,-157.0796326794898,-5.0020865173811915,-152.07754616210832,-5.001928880064381,-10.050590216368969,-4.00098721602491,-8.025810856794209,-136.28350081741684,-4.000987216024939,-159.36183077064402,-163.36281798667005,-5.0019288800643285,-158.36088910660442,-1.2991516319851801,-3.702636830195414,-3.7815130030068254,-6.265364371195623,-0.02516260900254963,-0.6553944641345026,-3.975752765070567,-7.368528340442765,-142.57249927881398,-0.02516260900254963,-3.9757527650706095,-165.64508791977525,-169.64600329384803,-1.299151631985167,-3.7026368301953885,-164.6442148316677,-10.00321285677458,-20.08414323176165,-8.001644468035863,-16.042954878437143,-304.0096070742277,-8.00164446803587,-350.1399180412005,-358.1415625092368,-10.003212856774468,-348.13834965246224,-3.794150313030109,-8.65049239704272,-0.02260276689354157,-0.5885167811200915,-370.2185414798688,-0.022602766893559393,-383.2517009710623,-383.2743037379555,-3.7941503130300576,-379.48015342492505,-408.40704496667513,-408.4070449666742,-408.4070449666742,-408.4070449666742,-433.53978619538975,-433.5397861953902,-433.5397861953911,-433.53978619539066,-458.67252742410983,-458.6725274241094,-458.67252742410983,-458.6725274241089,-608.6835766330232,-608.6835766330232,-608.6835766330232,-608.6835766330241] + expected1=[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,16,16,17,18,19,19,20,20,20,20,20,21,21,22,23,23,24,24,24,24,24,25,25,26,27,27,28,28,28,28,28,29,29,30,31,31,32,32,32,32,32,32,32,32,32,33,33,33,34,35,35,35,36,36,36,36,36,37,37,38,39,39,40,40,40,40,40,41,41,42,43,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59] + expected2=[-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,0,2,-1,-1,-1,0,-1,0,2,4,5,-1,4,-1,-1,0,-1,0,2,4,5,-1,4,-1,-1,0,-1,0,2,4,5,-1,4,-1,-1,0,-1,0,1,2,3,4,5,6,7,-1,4,6,-1,-1,0,1,-1,1,3,6,7,-1,6,-1,-1,1,-1,1,3,6,7,-1,6,-1,-1,1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1] + f3=m3.getMeasureField(ON_CELLS).getArray().getValues(); + for i in xrange(105): + self.assertAlmostEqual(areaExpected[i],f3[i],10) + pass + self.assertEqual(expected1,d1.getValues()) + self.assertEqual(expected2,d2.getValues()) + pass + + def testSwig2Intersect2DMeshesQuadra1(self): + import cmath + def createDiagCircle(lX, lY, R, cells=[0,1]): + """ A circle in a square box, cut along the diagonal. + """ + c = [] + for i in range(8): + c.append(cmath.rect(R, i*pi/4)) + + coords = [0.0,0.0, c[3].real,c[3].imag, -lX/2.0, lY/2.0, + 0.0, lY/2.0, lX/2.0,lY/2.0, lX/2.0,0.0, + # 6 7 8 + lX/2.0,-lY/2.0, c[7].real,c[7].imag, c[1].real,c[1].imag, + # 9 10 11 + c[5].real,c[5].imag, -lX/2.0,-lY/2.0, 0.0, -lY/2.0, + # 12 13 14 + -lX/2.0,0.0, 0.0,0.0, 0.0, 0.0] + # Points 13 (reps. 14) are average of points (6,7) (resp (1,2)) + coords[13*2] = 0.5*(coords[6*2]+coords[7*2]) + coords[13*2+1] = 0.5*(coords[6*2+1]+coords[7*2+1]) + coords[14*2] = 0.5*(coords[1*2]+coords[2*2]) + coords[14*2+1] = 0.5*(coords[1*2+1]+coords[2*2+1]) + connec = [1,7,8,0] # half circle up right + connec3 = [6,7,1,2,4,13,8,14,3,5] + + baseMesh = MEDCouplingUMesh.New("box_circle", 2) + baseMesh.allocateCells(2) + meshCoords = DataArrayDouble.New(coords, len(coords)/2, 2) + meshCoords.setInfoOnComponents(["X [au]", "Y [au]"]) + baseMesh.setCoords(meshCoords) + + if 0 in cells: + baseMesh.insertNextCell(NORM_QPOLYG, connec) + if 1 in cells: + baseMesh.insertNextCell(NORM_QPOLYG, connec3) + baseMesh.finishInsertingCells() + baseMesh.checkCoherency() + return baseMesh + + eps = 1.0e-7 + m1 = createDiagCircle(1.0, 1.0, 0.5*0.90, cells=[0,1]) + m2 = createDiagCircle(1.0, 1.0, 0.5*0.95, cells=[0]) + m3, _, _= MEDCouplingUMesh.Intersect2DMeshes(m1, m2, eps) + m3.mergeNodes(eps) + m3.convertDegeneratedCells() + m3.zipCoords() + m4 = m3.deepCpy() + m5, _, _ = MEDCouplingUMesh.Intersect2DMeshes(m3, m4, eps) + m5.mergeNodes(eps) + # Check coordinates: + self.assertTrue(m3.getCoords().isEqual(m5.getCoords(), eps)) + + def testIntersect2DMeshesTmp7(self): + eps = 1.0e-8 + coords = [-0.5,-0.5, -0.5, 0.5, 0.5, 0.5, 0.5,-0.5] + connec = range(4) + m1 = MEDCouplingUMesh.New("box", 2) + m1.allocateCells(1) + meshCoords = DataArrayDouble.New(coords, len(coords)/2, 2) + m1.setCoords(meshCoords) + m1.insertNextCell(NORM_POLYGON, connec) + m1.finishInsertingCells() + + m2 = MEDCouplingDataForTest.buildCircle(0.25, 0.2, 0.4) + # Was looping indefinitly: + m_intersec, resToM1, resToM2 = MEDCouplingUMesh.Intersect2DMeshes(m1, m2, eps) + m_intersec.zipCoords() + coo_tgt = DataArrayDouble([-0.5, -0.5, -0.5, 0.5, 0.5, 0.5, 0.5, -0.5, -0.03284271247461901, 0.4828427124746191, + -0.014575131106459124, 0.5000000000000001, 0.5, -0.11224989991991996, 0.24271243444677046, 0.5, 0.5, 0.19387505004004, + -0.04799910280454185, -0.06682678787499614, -0.023843325638122054, 0.4915644577163915, 0.5, -0.30612494995996, 0.0, -0.5, + -0.5, 0.0, -0.25728756555322957, 0.5, -0.023843325638122026, 0.49156445771639157, -0.04799910280454181, -0.06682678787499613], 17 ,2) + conn_tgt = [32, 5, 2, 6, 4, 7, 8, 9, 10, 32, 6, 3, 0, 1, 5, 4, 11, 12, 13, 14, 15, 16] + connI_tgt = [0, 9, 22] + res1_tgt = [0, 0] + res2_tgt = [0, -1] + self.assert_(coo_tgt.isEqualWithoutConsideringStr(m_intersec.getCoords(), 1e-12)) + self.assertEqual(conn_tgt, m_intersec.getNodalConnectivity().getValues()) + self.assertEqual(connI_tgt, m_intersec.getNodalConnectivityIndex().getValues()) + self.assertEqual(res1_tgt, resToM1.getValues()) + self.assertEqual(res2_tgt, resToM2.getValues()) + + def testDAIBuildUnique1(self): + d=DataArrayInt([1,2,2,3,3,3,3,4,5,5,7,7,7,19]) + e=d.buildUnique() + self.assertTrue(e.isEqual(DataArrayInt([1,2,3,4,5,7,19]))) + pass + + def testDAIPartitionByDifferentValues1(self): + d=DataArrayInt([1,0,1,2,0,2,2,-3,2]) + expected=[[-3,[7]],[0,[1,4]],[1,[0,2]],[2,[3,5,6,8]]] + for i,elt in enumerate(zip(*d.partitionByDifferentValues())): + self.assertEqual(expected[i][0],elt[1]) + self.assertEqual(expected[i][1],elt[0].getValues()) + pass + pass + + def testFieldGaussMultiDiscPerType1(self): + coords=DataArrayDouble([0.,0.,0.,1.,1.,1.,1.,0.,0.,0.5,0.5,1.,1.,0.5,0.5,0.],8,2) + mQ8=MEDCouplingUMesh("",2) ; mQ8.setCoords(coords) + mQ8.allocateCells(1) + mQ8.insertNextCell(NORM_QUAD8,range(8)) + mQ8.finishInsertingCells() + mQ4=MEDCouplingUMesh("",2) ; mQ4.setCoords(coords) + mQ4.allocateCells(1) + mQ4.insertNextCell(NORM_QUAD4,range(4)) + mQ4.finishInsertingCells() + mT3=MEDCouplingUMesh("",2) ; mT3.setCoords(coords) + mT3.allocateCells(1) + mT3.insertNextCell(NORM_TRI3,range(3)) + mT3.finishInsertingCells() + + tr=[[0.,0.],[2.,0.], [0.,2.],[2.,2.],[4.,2.],[6.,2.],[8.,2.],[10.,2.],[12.,2.],[0.,4.],[2.,4.],[4.,4.],[6.,4.],[8.,4.],[10.,4.],[12.,4.],[14.,4.],[16.,4.],[18.,4.],[20.,4.],[22.,4.]] + ms=2*[mQ4]+7*[mQ8]+11*[mT3] + ms[:]=(elt.deepCpy() for elt in ms) + for m,t in zip(ms,tr): + d=m.getCoords() ; d+= t + pass + m=MEDCouplingUMesh.MergeUMeshes(ms) + f=MEDCouplingFieldDouble.New(ON_GAUSS_PT,NO_TIME) + f.setMesh(m) + # throw because cell 0,1 are QUAD4 and cell 3 is QUAD8 + self.assertRaises(InterpKernelException,f.setGaussLocalizationOnCells,[0,1,3],[0.,0.,1.,0.,1.,1.,0.,1.],[0.3,0.3,0.7,0.7],[0.8,0.2]) + f.setGaussLocalizationOnCells([0,1],[0.,0.,1.,0.,1.,1.,0.,1.],[0.3,0.3,0.7,0.7],[0.8,0.2]) + f.setGaussLocalizationOnCells([3,2,5],[0.,0.,1.,0.,1.,1.,0.,1.,0.5,0.,1.,0.5,0.5,1.,0.,0.5],[0.3,0.3,0.7,0.7,0.9,0.9],[0.8,0.05,0.15]) + f.setGaussLocalizationOnCells([4,6,8,7],[0.,0.,1.,0.,1.,1.,0.,1.,0.5,0.,1.,0.5,0.5,1.,0.,0.5],[0.3,0.3,0.7,0.7,0.9,0.9,-0.1,0.3],[0.7,0.05,0.15,0.1]) + f.setGaussLocalizationOnCells([9,10,11,12,13],[0.,0.,1.,0.,1.,1.],[0.4,0.4],[1.]) + f.setGaussLocalizationOnCells([14,15,16,17,18,19],[0.,0.,1.,0.,1.,1.],[0.4,0.4,0.14,0.16],[0.22,0.78]) + self.assertEqual(46,f.getNumberOfTuplesExpected()) + vals=DataArrayDouble.New(46*3,1) ; vals.iota(7.7) ; vals.rearrange(3) + f.setArray(vals) + f.checkCoherency() + #f.getLocalizationOfDiscr() + self.assertRaises(InterpKernelException,f.getGaussLocalizationIdOfOneType,NORM_QUAD8) #throw because several loc + self.assertEqual([1,2],f.getGaussLocalizationIdsOfOneType(NORM_QUAD8)) + self.assertEqual([0,0,1,1,2,1,2,2,2,3,3,3,3,3,4,4,4,4,4,4],f.getDiscretization().getArrayOfDiscIds().getValues()) + fc=f[[1,2,3,8]] + fc.checkCoherency() + self.assertTrue(DataArrayDouble([13.7,14.7,15.7,16.7,17.7,18.7,19.7,20.7,21.7,22.7,23.7,24.7,25.7,26.7,27.7,28.7,29.7,30.7,31.7,32.7,33.7,34.7,35.7,36.7,82.7,83.7,84.7,85.7,86.7,87.7,88.7,89.7,90.7,91.7,92.7,93.7],12,3).isEqual(fc.getArray(),1e-10)) + fc.renumberCells([3,2,0,1]) + self.assertTrue(DataArrayDouble([28.7, 29.7, 30.7, 31.7, 32.7, 33.7, 34.7, 35.7, 36.7, 82.7, 83.7, 84.7, 85.7, 86.7, 87.7, 88.7, 89.7, 90.7, 91.7, 92.7, 93.7, 19.7, 20.7, 21.7, 22.7, 23.7, 24.7, 25.7, 26.7, 27.7, 13.7, 14.7, 15.7, 16.7, 17.7, 18.7],12,3).isEqual(fc.getArray(),1e-10)) + fc.getArray() + pass + + def testSwigRotate(self): + d=DataArrayDouble([1.,2.,3.,4.,6.,5.],2,3) + MEDCouplingPointSet.Rotate3DAlg([0.,0.,0.],[0.,1.,0.],1.5707963267948966,d) + self.assertTrue(d.isEqual(DataArrayDouble([3.,2.,-1.,5.,6.,-4.],2,3),1e-12)) + d=DataArrayDouble([1.,2.,3.,4.,6.,5.],3,2) + MEDCouplingPointSet.Rotate2DAlg([0.,0.],1.5707963267948966,d) + self.assertTrue(d.isEqual(DataArrayDouble([-2.,1.,-4.,3.,-5.,6.],3,2),1e-12)) + pass + + def testSwigCMeshProtection(self): + cm=MEDCouplingCMesh() + self.assertRaises(InterpKernelException,cm.setCoordsAt,0,DataArrayDouble([4.,4.5,6.,7.],2,2)) + self.assertRaises(InterpKernelException,cm.setCoords,DataArrayDouble([4.,4.5,6.,7.],2,2)) + pass + + def testSwigCellsInBoundingBox1(self): + m3D=MEDCouplingDataForTest.build3DExtrudedUMesh_1()[0] + self.assertTrue(m3D.getCellsInBoundingBox([(0,3),(0,3),(0,1)],-1e-12).isEqual(DataArrayInt([0,1,2,3,4,5]))) + self.assertRaises(InterpKernelException,m3D.getCellsInBoundingBox,[(0,3,0),(3,0,1)],-1e-12) + pass + + def testDAICheckMonotonic1(self): + data1=[-1,0,2,2,4,5] + data2=[6,2,0,-8,-9,-56] + data3=[-1,0,3,2,4,6] + data4=[7,5,2,3,0,-6] + d=DataArrayInt.New(data1); + self.assertTrue(d.isMonotonic(True)); + self.assertTrue(not d.isMonotonic(False)); + d.checkMonotonic(True); + self.assertRaises(InterpKernelException,d.checkMonotonic,False) + d=DataArrayInt.New(data2); + self.assertTrue(d.isMonotonic(False)); + self.assertTrue(not d.isMonotonic(True)); + d.checkMonotonic(False); + self.assertRaises(InterpKernelException,d.checkMonotonic,True) + d=DataArrayInt.New(data3); + self.assertTrue(not d.isMonotonic(False)); + self.assertTrue(not d.isMonotonic(True)); + self.assertRaises(InterpKernelException,d.checkMonotonic,True) + self.assertRaises(InterpKernelException,d.checkMonotonic,False) + d=DataArrayInt.New(data4); + self.assertTrue(not d.isMonotonic(False)); + self.assertTrue(not d.isMonotonic(True)); + self.assertRaises(InterpKernelException,d.checkMonotonic,True) + self.assertRaises(InterpKernelException,d.checkMonotonic,False) + d=DataArrayInt.New(0,1) + self.assertTrue(d.isMonotonic(True)); + self.assertTrue(d.isMonotonic(False)); + d.checkMonotonic(True); + d.checkMonotonic(False); + d=DataArrayInt.New(data4,3,2);#throw because nbComp!=1 + self.assertRaises(InterpKernelException,d.isMonotonic,True) + self.assertRaises(InterpKernelException,d.isMonotonic,False) + self.assertRaises(InterpKernelException,d.checkMonotonic,True) + self.assertRaises(InterpKernelException,d.checkMonotonic,False) + pass + + def testSwigDASetItemOnEmpty1(self): + d=DataArrayInt(0,1) + isThrow=False + try: + d[0:1000:2]=4 + except InterpKernelException as e: + isThrow=True + pass + self.assertTrue(isThrow) + d[:]=4 + d[::2]=5 + # + d=DataArrayDouble(0,1) + isThrow=False + try: + d[0:1000:2]=4 + except InterpKernelException as e: + isThrow=True + pass + self.assertTrue(isThrow) + d[:]=4 + d[::2]=5 + d=DataArrayInt([],0,1) + d2=DataArrayInt(0) + self.assertTrue(d2.isEqual(d)) + d=DataArrayDouble([],0,1) + d2=DataArrayDouble(0) + self.assertTrue(d2.isEqual(d,1e-12)) + pass + + def testSwigDAITransformWithIndArr1(self): + arr=DataArrayInt([0,4,5,1]) + d=DataArrayInt([7,8,9,10]) + self.assertRaises(InterpKernelException,arr.transformWithIndArr,d) + pass + + def testIntersect2DMeshesTmp6(self): + # coordinates + coords=DataArrayDouble.New([2.7554552980815448e-15,45,-45,5.5109105961630896e-15,-31.819805153394636,31.81980515339464,2.8779199779962799e-15,47,2.8166876380389124e-15,46,-47,5.7558399559925599e-15,-33.234018715767732,33.234018715767739,-46,5.6333752760778247e-15],8,2); + # connectivity + conn=DataArrayInt.New([8,0,3,5,1,4,6,7,2]) + connI=DataArrayInt.New([0,9]); + m1=MEDCouplingUMesh.New("Fixe",2); + m1.setCoords(coords); + m1.setConnectivity(conn,connI,True); + # + coords=DataArrayDouble.New([-7.3800475508445391,41.854329503018846,-3.7041190667754655,42.338274668899189,-3.7041190667754655,45.338274668899189,-7.3800475508445382,44.854329503018839,-5.5473631693521845,42.136406608386956,-3.7041190667754655,43.838274668899189,-5.5420833088100014,45.09630208595901,-7.3800475508445382,43.354329503018839,-3.7041190667754651,52.338274668899189,-7.3800475508445382,51.854329503018839,-3.7041190667754655,48.838274668899189,-5.5420833088100014,52.09630208595901,-7.3800475508445382,48.354329503018839],13,2); + # connectivity + conn=DataArrayInt.New([8,0,1,2,3,4,5,6,7,8,3,2,8,9,6,10,11,12]); + connI=DataArrayInt.New([0,9,18]); + # + m2=MEDCouplingUMesh.New("Mobile",2); + m2.setCoords(coords); + m2.setConnectivity(conn,connI,True); + # + m3,d1,d2=MEDCouplingUMesh.Intersect2DMeshes(m1,m2,1e-10); + self.assertTrue(d1.isEqual(DataArrayInt([0,0,0,0]))); + self.assertTrue(d2.isEqual(DataArrayInt([0,1,-1,-1]))); + self.assertEqual(4,m3.getNumberOfCells()); + self.assertEqual(4,d1.getNumberOfTuples()); + self.assertEqual(4,d2.getNumberOfTuples()); + self.assertEqual(43,m3.getNumberOfNodes()); + dI,areMerged,newNbOfNodes=m3.mergeNodes(1e-12) + self.assertEqual(35,m3.getNumberOfNodes()); + m3.zipCoords(); + self.assertEqual(23,m3.getNumberOfNodes()); + # + f=m3.getMeasureField(True); + valuesExpected=DataArrayDouble([1.6603638692585716,5.747555728471923,129.68907101754394,7.4162714498559694]) + self.assertTrue(f.getArray().isEqual(valuesExpected,1e-12)) + pass + + def testDAPushBack(self): + d=DataArrayDouble(0,1) + for i in xrange(8): + d.pushBackSilent(i) + pass + self.assertEqual(d.getNumberOfTuples(),8) + self.assertEqual(d.getNbOfElemAllocated(),8) + d.pushBackSilent(4.44) + self.assertEqual(d.getNumberOfTuples(),9) + self.assertEqual(d.getNbOfElemAllocated(),16) + self.assertTrue(d.isEqual(DataArrayDouble([0.,1.,2.,3.,4.,5.,6.,7.,4.44]),1e-12)) + e=d.deepCpy() + self.assertEqual(e.getNumberOfTuples(),9) + self.assertEqual(e.getNbOfElemAllocated(),9) + self.assertTrue(e.isEqual(DataArrayDouble([0.,1.,2.,3.,4.,5.,6.,7.,4.44]),1e-12)) + self.assertAlmostEqual(d.popBackSilent(),4.44,12) + self.assertEqual(d.getNumberOfTuples(),8) + self.assertEqual(d.getNbOfElemAllocated(),16) + self.assertTrue(d.isEqual(DataArrayDouble([0.,1.,2.,3.,4.,5.,6.,7.]),1e-12)) + f=DataArrayDouble() + f.reserve(1000) + f.pushBackSilent(4.) + self.assertTrue(f.isEqual(DataArrayDouble([4.]),1e-12)) + self.assertEqual(f.getNumberOfTuples(),1) + self.assertEqual(f.getNbOfElemAllocated(),1000) + ff=f[:] + self.assertTrue(ff.isEqual(DataArrayDouble([4.]),1e-12)) + self.assertEqual(ff.getNumberOfTuples(),1) + self.assertEqual(ff.getNbOfElemAllocated(),1) + d=DataArrayDouble() + d.pushBackSilent(4.44) + d.pushBackSilent(5.55) + d.pushBackSilent(6.66) + self.assertTrue(d.isEqual(DataArrayDouble([4.44,5.55,6.66]),1e-12)) + # + d=DataArrayInt(0,1) + for i in xrange(8): + d.pushBackSilent(i) + pass + self.assertEqual(d.getNumberOfTuples(),8) + self.assertEqual(d.getNbOfElemAllocated(),8) + d.pushBackSilent(444) + self.assertEqual(d.getNumberOfTuples(),9) + self.assertEqual(d.getNbOfElemAllocated(),16) + self.assertTrue(d.isEqual(DataArrayInt([0,1,2,3,4,5,6,7,444]))) + e=d.deepCpy() + self.assertEqual(e.getNumberOfTuples(),9) + self.assertEqual(e.getNbOfElemAllocated(),9) + self.assertTrue(e.isEqual(DataArrayInt([0,1,2,3,4,5,6,7,444]))) + self.assertEqual(d.popBackSilent(),444) + self.assertEqual(d.getNumberOfTuples(),8) + self.assertEqual(d.getNbOfElemAllocated(),16) + self.assertTrue(d.isEqual(DataArrayInt([0,1,2,3,4,5,6,7]))) + f=DataArrayInt() + f.reserve(1000) + f.pushBackSilent(4) + self.assertTrue(f.isEqual(DataArrayInt([4]))) + self.assertEqual(f.getNumberOfTuples(),1) + self.assertEqual(f.getNbOfElemAllocated(),1000) + ff=f[:] + self.assertTrue(ff.isEqual(DataArrayInt([4]))) + self.assertEqual(ff.getNumberOfTuples(),1) + self.assertEqual(ff.getNbOfElemAllocated(),1) + d=DataArrayInt() + d.pushBackSilent(444) + d.pushBackSilent(555) + d.pushBackSilent(666) + self.assertTrue(d.isEqual(DataArrayInt([444,555,666]))) + # + d=DataArrayInt() + d.alloc(10,1) + d.setInfoOnComponent(0,"ABC") + d.setName("dEf") + d.iota(7) + e=DataArrayInt([7,8,9,10,11,12,13,14,15,16]) ; e.copyStringInfoFrom(d) ; self.assertTrue(d.isEqual(e)) + self.assertEqual(10,d.getNbOfElemAllocated()) + d.pushBackSilent(55) + e=DataArrayInt([7,8,9,10,11,12,13,14,15,16,55]) ; e.copyStringInfoFrom(d) ; self.assertTrue(d.isEqual(e)) + self.assertEqual(20,d.getNbOfElemAllocated()) + d.reserve(4) + e=DataArrayInt([7,8,9,10]) ; e.copyStringInfoFrom(d) ; self.assertTrue(d.isEqual(e)) + self.assertEqual(4,d.getNbOfElemAllocated()) + d.pushBackSilent(5) + e=DataArrayInt([7,8,9,10,5]) ; e.copyStringInfoFrom(d) ; self.assertTrue(d.isEqual(e)) + self.assertEqual(8,d.getNbOfElemAllocated()) + self.assertEqual(5,d.popBackSilent()) + e=DataArrayInt([7,8,9,10]) ; e.copyStringInfoFrom(d) ; self.assertTrue(d.isEqual(e)) + self.assertEqual(8,d.getNbOfElemAllocated()) + self.assertRaises(OverflowError,d.reserve,-1) + e=DataArrayInt([7,8,9,10]) ; e.copyStringInfoFrom(d) ; self.assertTrue(d.isEqual(e)) + self.assertEqual(8,d.getNbOfElemAllocated()) + d.reserve(0) + e=DataArrayInt([]) ; e.setInfoOnComponent(0,"ABC") ; e.setName("dEf") ; self.assertTrue(d.isEqual(e)) + self.assertEqual(0,d.getNbOfElemAllocated()) + # + d=DataArrayDouble() + d.alloc(10,1) + d.setInfoOnComponent(0,"ABC") + d.setName("dEf") + d.iota(7) + e=DataArrayDouble([7,8,9,10,11,12,13,14,15,16]) ; e.copyStringInfoFrom(d) ; self.assertTrue(d.isEqual(e,1e-14)) + self.assertEqual(10,d.getNbOfElemAllocated()) + d.pushBackSilent(55) + e=DataArrayDouble([7,8,9,10,11,12,13,14,15,16,55]) ; e.copyStringInfoFrom(d) ; self.assertTrue(d.isEqual(e,1e-14)) + self.assertEqual(20,d.getNbOfElemAllocated()) + d.reserve(4) + e=DataArrayDouble([7,8,9,10]) ; e.copyStringInfoFrom(d) ; self.assertTrue(d.isEqual(e,1e-14)) + self.assertEqual(4,d.getNbOfElemAllocated()) + d.pushBackSilent(5) + e=DataArrayDouble([7,8,9,10,5]) ; e.copyStringInfoFrom(d) ; self.assertTrue(d.isEqual(e,1e-14)) + self.assertEqual(8,d.getNbOfElemAllocated()) + self.assertEqual(5.,d.popBackSilent()) + e=DataArrayDouble([7,8,9,10]) ; e.copyStringInfoFrom(d) ; self.assertTrue(d.isEqual(e,1e-14)) + self.assertEqual(8,d.getNbOfElemAllocated()) + self.assertRaises(OverflowError,d.reserve,-1) + e=DataArrayDouble([7,8,9,10]) ; e.copyStringInfoFrom(d) ; self.assertTrue(d.isEqual(e,1e-14)) + self.assertEqual(8,d.getNbOfElemAllocated()) + d.reserve(0) + e=DataArrayDouble([]) ; e.setInfoOnComponent(0,"ABC") ; e.setName("dEf") ; self.assertTrue(d.isEqual(e,1e-14)) + self.assertEqual(0,d.getNbOfElemAllocated()) + pass + + def testDAIBuildSubstractionOptimized1(self): + da1=DataArrayInt.New([1,3,5,6,7,9,13]) + da2=DataArrayInt.New([3,5,9]) + da3=DataArrayInt.New([1,3,5]) + da4=DataArrayInt.New([1,3,5,6,7,9,13]) + # + a=da1.buildSubstractionOptimized(da2); + self.assertTrue(a.isEqual(DataArrayInt([1,6,7,13]))); + # + a=da1.buildSubstractionOptimized(da3); + self.assertTrue(a.isEqual(DataArrayInt([6,7,9,13]))); + # + a=da1.buildSubstractionOptimized(da4); + self.assertTrue(a.isEqual(DataArrayInt([]))); + pass + + def testDAIIsStrictlyMonotonic1(self): + da1=DataArrayInt.New([1,3,5,6,7,9,13]) + self.assertTrue(da1.isStrictlyMonotonic(True)); + da1.checkStrictlyMonotonic(True); + self.assertTrue(da1.isMonotonic(True)); + da1.checkMonotonic(True); + self.assertTrue(not da1.isStrictlyMonotonic(False)); + self.assertRaises(InterpKernelException,da1.checkStrictlyMonotonic,False) + self.assertTrue(not da1.isMonotonic(False)); + self.assertRaises(InterpKernelException,da1.checkMonotonic,False) + # + da1=DataArrayInt.New([1,3,5,6,6,9,13]) + self.assertTrue(not da1.isStrictlyMonotonic(True)); + self.assertRaises(InterpKernelException,da1.checkStrictlyMonotonic,True) + self.assertTrue(da1.isMonotonic(True)); + da1.checkMonotonic(True); + self.assertTrue(not da1.isStrictlyMonotonic(False)); + self.assertRaises(InterpKernelException,da1.checkStrictlyMonotonic,False) + self.assertTrue(not da1.isMonotonic(False)); + self.assertRaises(InterpKernelException,da1.checkMonotonic,False) + # + da1=DataArrayInt.New([1,3,5,6,5,9,13]) + self.assertTrue(not da1.isStrictlyMonotonic(True)); + self.assertRaises(InterpKernelException,da1.checkStrictlyMonotonic,True) + self.assertTrue(not da1.isMonotonic(True)); + self.assertRaises(InterpKernelException,da1.checkMonotonic,True) + self.assertTrue(not da1.isStrictlyMonotonic(False)); + self.assertRaises(InterpKernelException,da1.checkStrictlyMonotonic,False) + self.assertTrue(not da1.isMonotonic(False)); + self.assertRaises(InterpKernelException,da1.checkMonotonic,False) + # + da1=DataArrayInt.New([13,9,7,6,5,3,1]) + self.assertTrue(not da1.isStrictlyMonotonic(True)); + self.assertRaises(InterpKernelException,da1.checkStrictlyMonotonic,True) + self.assertTrue(not da1.isMonotonic(True)); + self.assertRaises(InterpKernelException,da1.checkMonotonic,True) + self.assertTrue(da1.isStrictlyMonotonic(False)); + da1.checkStrictlyMonotonic(False); + self.assertTrue(da1.isMonotonic(False)); + da1.checkMonotonic(False); + # + da1=DataArrayInt.New([13,9,6,6,5,3,1]) + self.assertTrue(not da1.isStrictlyMonotonic(True)); + self.assertRaises(InterpKernelException,da1.checkStrictlyMonotonic,True) + self.assertTrue(not da1.isMonotonic(True)); + self.assertRaises(InterpKernelException,da1.checkMonotonic,True) + self.assertTrue(not da1.isStrictlyMonotonic(False)); + self.assertRaises(InterpKernelException,da1.checkStrictlyMonotonic,False) + self.assertTrue(da1.isMonotonic(False)); + da1.checkMonotonic(False); + # + da1=DataArrayInt.New([13,9,5,6,5,3,1]) + self.assertTrue(not da1.isStrictlyMonotonic(True)); + self.assertRaises(InterpKernelException,da1.checkStrictlyMonotonic,True) + self.assertTrue(not da1.isMonotonic(True)); + self.assertRaises(InterpKernelException,da1.checkMonotonic,True) + self.assertTrue(not da1.isStrictlyMonotonic(False)); + self.assertRaises(InterpKernelException,da1.checkStrictlyMonotonic,False) + self.assertTrue(not da1.isMonotonic(False)); + self.assertRaises(InterpKernelException,da1.checkMonotonic,False) + # + da1=DataArrayInt.New([]) + self.assertTrue(da1.isStrictlyMonotonic(True)); + da1.checkStrictlyMonotonic(True); + self.assertTrue(da1.isMonotonic(True)); + da1.checkMonotonic(True); + self.assertTrue(da1.isStrictlyMonotonic(False)); + da1.checkStrictlyMonotonic(False); + self.assertTrue(da1.isMonotonic(False)); + da1.checkMonotonic(False); + # + da1=DataArrayInt.New([13]) + self.assertTrue(da1.isStrictlyMonotonic(True)); + da1.checkStrictlyMonotonic(True); + self.assertTrue(da1.isMonotonic(True)); + da1.checkMonotonic(True); + self.assertTrue(da1.isStrictlyMonotonic(False)); + da1.checkStrictlyMonotonic(False); + self.assertTrue(da1.isMonotonic(False)); + da1.checkMonotonic(False); + pass + + def testFindAndCorrectBadOriented3DCells1(self): + nbOfDisc=20 + vects=([0,0,-1],[0.3,0.7,0.2],[-0.3,0.7,0.2],[-0.3,-0.7,0.2]) + # + m0=MEDCouplingUMesh("m",3) ; m0.allocateCells(0); m0.insertNextCell(NORM_TETRA4,[0,1,2,3]); #Well oriented + m1=MEDCouplingUMesh("m",3) ; m1.allocateCells(0); m1.insertNextCell(NORM_PYRA5,[0,1,2,3,4]); #Well oriented + m2=MEDCouplingUMesh("m",3) ; m2.allocateCells(0); m2.insertNextCell(NORM_PENTA6,[0,1,2,3,4,5]); #Well oriented + m3=MEDCouplingUMesh("m",3) ; m3.allocateCells(0); m3.insertNextCell(NORM_HEXA8,[0,1,2,3,4,5,6,7]); #Well oriented + m4=MEDCouplingUMesh("m",3) ; m4.allocateCells(0) + self.assertRaises(InterpKernelException,m4.insertNextCell,NORM_HEXGP12,[0,1,2,3,4,5,6,7,8,9,10,11,12]); + m4.insertNextCell(NORM_HEXGP12,[0,1,2,3,4,5,6,7,8,9,10,11]); #Well oriented + c0=DataArrayDouble([0.,0.,0.,0.,1.,0.,1.,0.,0.,0.,0.,1.],4,3) ; m0.setCoords(c0) + c1=DataArrayDouble([0.,0.,0.,0.,1.,0.,1.,1.,0.,1.,0.,0.,0.,0.,1.],5,3) ; m1.setCoords(c1) + c2=DataArrayDouble([0.,0.,0.,0.,1.,0.,1.,0.,0., 0.,0.,1.,0.,1.,1.,1.,0.,1.],6,3) ; m2.setCoords(c2) + c3=DataArrayDouble([0.,0.,0.,0.,1.,0.,1.,1.,0.,1.,0.,0.,0.,0.,1.,0.,1.,1.,1.,1.,1.,1.,0.,1.],8,3) ; m3.setCoords(c3) + c4=DataArrayDouble([0.,0.,0.,0.,1.,0.,1.,1.,0.,1.,0.,0.,0.8,0.,0.,0.45,0.,0., 0.,0.,1.,0.,1.,1.,1.,1.,1.,1.,0.,1.,0.8,0.,1.,0.45,0.,1.],12,3) ; m4.setCoords(c4) + m=MEDCouplingMesh.MergeMeshes([m0,m1,m2,m3,m4]) + expected1=DataArrayDouble([0.16666666666666666,0.3333333333333333,0.5,1.,1.]) + for v in vects: + for i in xrange(nbOfDisc): + mm=m.deepCpy() + mm.rotate([0.,0.,0.],[0.3,0.7,0.2],float(i)/float(nbOfDisc)*2*pi) + mm2=mm.deepCpy() + self.assertTrue(mm.getMeasureField(False).getArray().isEqual(expected1,1e-14)) + self.assertTrue(mm.findAndCorrectBadOriented3DCells().empty()) + self.assertTrue(mm.isEqual(mm2,1e-14)) + self.assertTrue(mm.getMeasureField(False).getArray().isEqual(expected1,1e-14)) + mm.convertAllToPoly() + self.assertTrue(mm.getMeasureField(False).getArray().isEqual(expected1,1e-14)) + pass + pass + # + mOK=m.deepCpy() + m0=MEDCouplingUMesh("m",3) ; m0.allocateCells(0); m0.insertNextCell(NORM_TETRA4,[0,2,1,3]); #Not well oriented + m1=MEDCouplingUMesh("m",3) ; m1.allocateCells(0); m1.insertNextCell(NORM_PYRA5,[0,1,2,3,4]); #Well oriented + m2=MEDCouplingUMesh("m",3) ; m2.allocateCells(0); m2.insertNextCell(NORM_PENTA6,[0,1,2,3,4,5]); #Well oriented + m3=MEDCouplingUMesh("m",3) ; m3.allocateCells(0); m3.insertNextCell(NORM_HEXA8,[0,3,2,1,4,7,6,5]); #Not well oriented + m4=MEDCouplingUMesh("m",3) ; m4.allocateCells(0); m4.insertNextCell(NORM_HEXGP12,[0,5,4,3,2,1,6,11,10,9,8,7]); #Not well oriented + m0.setCoords(c0) ; m1.setCoords(c1) ; m2.setCoords(c2) ; m3.setCoords(c3) ; m4.setCoords(c4) + m=MEDCouplingMesh.MergeMeshes([m0,m1,m2,m3,m4]) + expected2=DataArrayDouble([-0.16666666666666666,0.3333333333333333,0.5,-1.,-1.]) + for v in vects: + for i in xrange(nbOfDisc): + mm=m.deepCpy() + mm.rotate([0.,0.,0.],[0.3,0.7,0.2],float(i)/float(nbOfDisc)*2*pi) + mm2=mm.deepCpy() ; mm3=mm.deepCpy() ; mm3.convertAllToPoly() + self.assertTrue(mm3.getMeasureField(False).getArray().isEqual(expected2,1e-14)) + self.assertTrue(mm.getMeasureField(False).getArray().isEqual(expected2,1e-14)) + self.assertTrue(mm.findAndCorrectBadOriented3DCells().isEqual(DataArrayInt([0,3,4]))) + mOK.setCoords(mm.getCoords()) + self.assertTrue(mm.isEqual(mOK,1e-14)) + self.assertTrue(mm.getMeasureField(False).getArray().isEqual(expected1,1e-14)) + mmm=mm.deepCpy() + self.assertTrue(mmm.findAndCorrectBadOriented3DCells().empty()) + mm.convertAllToPoly() + self.assertTrue(mm.getMeasureField(False).getArray().isEqual(expected1,1e-14)) + pass + pass + # + m0=MEDCouplingUMesh("m",3) ; m0.allocateCells(0); m0.insertNextCell(NORM_TETRA4,[0,1,2,3]); #Well oriented + m1=MEDCouplingUMesh("m",3) ; m1.allocateCells(0); m1.insertNextCell(NORM_PYRA5,[0,3,2,1,4]); #Not well oriented + m2=MEDCouplingUMesh("m",3) ; m2.allocateCells(0); m2.insertNextCell(NORM_PENTA6,[0,2,1,3,5,4]); #Not well oriented + m3=MEDCouplingUMesh("m",3) ; m3.allocateCells(0); m3.insertNextCell(NORM_HEXA8,[0,1,2,3,4,5,6,7]); #Well oriented + m4=MEDCouplingUMesh("m",3) ; m4.allocateCells(0); m4.insertNextCell(NORM_HEXGP12,range(12)); #Well oriented + m0.setCoords(c0) ; m1.setCoords(c1) ; m2.setCoords(c2) ; m3.setCoords(c3) ; m4.setCoords(c4) + m=MEDCouplingMesh.MergeMeshes([m0,m1,m2,m3,m4]) + expected3=DataArrayDouble([0.16666666666666666,-0.3333333333333333,-0.5,1.,1.]) + for v in vects: + for i in xrange(nbOfDisc): + mm=m.deepCpy() + mm.rotate([0.,0.,0.],[0.3,0.7,0.2],float(i)/float(nbOfDisc)*2*pi) + mm2=mm.deepCpy() ; mm3=mm.deepCpy() ; mm3.convertAllToPoly() + self.assertTrue(mm3.getMeasureField(False).getArray().isEqual(expected3,1e-14)) + self.assertTrue(mm.getMeasureField(False).getArray().isEqual(expected3,1e-14)) + self.assertTrue(mm.findAndCorrectBadOriented3DCells().isEqual(DataArrayInt([1,2]))) + mOK.setCoords(mm.getCoords()) + self.assertTrue(mm.isEqual(mOK,1e-14)) + self.assertTrue(mm.getMeasureField(False).getArray().isEqual(expected1,1e-14)) + mmm=mm.deepCpy() + self.assertTrue(mmm.findAndCorrectBadOriented3DCells().empty()) + mm.convertAllToPoly() + self.assertTrue(mm.getMeasureField(False).getArray().isEqual(expected1,1e-14)) + pass + pass + pass + + def testSwig2CellOrientation1(self): + coords=DataArrayDouble([-0.21606,-0.10803,0.29999999999999999,-0.21606,-0.10803,0.37700000000000006,0,-0.10803,0.29999999999999999,0,-0.10803,0.37700000000000006,0,0.10803,0.29999999999999999,0,0.10803,0.37700000000000006,-0.21606,0.10803,0.29999999999999999,-0.21606,0.10803,0.37700000000000006,0,0.03601,0.29999999999999999,0,0.03601,0.37700000000000006,0,-0.03601,0.29999999999999999,0,-0.03601,0.37700000000000006],12,3) + conn=[[0,2,10,8,4,6],[1,3,11,9,5,7],[0,1,3,2],[2,3,11,10],[10,11,9,8],[8,9,5,4],[4,5,7,6],[6,7,1,0]] + for i in xrange(256): + mesh=MEDCouplingUMesh("FluidMesh_1",3); + mesh.allocateCells(0) + conn2=[elt[:] for elt in conn] + code=bin(i)[2:] ; code='0'*(8-len(code))+code + for face,rev in zip(conn2,code): + if bool(int(rev)): + face.reverse() + pass + pass + conn3=[elt+[-1] for elt in conn2] + conn3=sum(conn3,[])[:-1] + mesh.insertNextCell(NORM_POLYHED,conn3) + mesh.setCoords(coords) + mesh.orientCorrectlyPolyhedrons() + self.assertTrue(mesh.getBarycenterAndOwner().isEqual(DataArrayDouble([-0.10803,0.,0.3385],1,3),1e-12)) + pass + pass + + def testSwig2CheckConsecutiveCellTypesForMEDFileFrmt1(self): + m1=MEDCouplingUMesh("",2) ; m1.allocateCells(0) + m1.insertNextCell(NORM_QUAD4,[0,1,2,3]) + m1.insertNextCell(NORM_TRI3,[0,1,2]) + d=DataArrayDouble(4,3) ; d[:]=0. + m1.setCoords(d) + self.assertTrue(m1.checkConsecutiveCellTypes()) + self.assertTrue(not m1.checkConsecutiveCellTypesForMEDFileFrmt()) + m1.renumberCells([1,0]) + self.assertTrue(m1.checkConsecutiveCellTypes()) + self.assertTrue(m1.checkConsecutiveCellTypesForMEDFileFrmt()) + pass + + def testSwig2DAAccumulate1(self): + d=DataArrayInt(10) ; d.iota(0) + self.assertEqual([45],d.accumulate()) + self.assertEqual(45,d.accumulate(0)) + d=DataArrayInt(30) ; d.iota(0) ; d.rearrange(3) + self.assertEqual([135,145,155],d.accumulate()) + self.assertEqual(135,d.accumulate(0)) + self.assertEqual(145,d.accumulate(1)) + self.assertEqual(155,d.accumulate(2)) + d=DataArrayDouble(10) ; d.iota(0.) + self.assertEqual([45.],d.accumulate()) + self.assertEqual(45.,d.accumulate(0)) + d=DataArrayDouble(30) ; d.iota(0) ; d.rearrange(3) + self.assertEqual([135.,145.,155.],d.accumulate()) + self.assertEqual(135.,d.accumulate(0)) + self.assertEqual(145.,d.accumulate(1)) + self.assertEqual(155.,d.accumulate(2)) + pass + + def testSwig2UMeshDistanceToMesh1(self): + m=MEDCouplingUMesh("toto",2) + coords=DataArrayDouble([2.3,3.4,5.6,6.5,-4.3,3.2,-9.8,7.6,-5.4],3,3) + m.setCoords(coords) + m.allocateCells(0) + m.insertNextCell(NORM_TRI3,[0,1,2]) + a,b=m.distanceToPoint([-0.335,2.27,1.21]) + self.assertEqual(0,b) + self.assertAlmostEqual(0.022360988100374124,a,14); + a,b=m.distanceToPoint(DataArrayDouble([-0.335,2.27,1.21],1,3)) + self.assertEqual(0,b) + self.assertAlmostEqual(0.022360988100374124,a,14); + a,b=coords.distanceToTuple([-0.335,2.27,1.21]) + self.assertAlmostEqual(5.243302871282566,a,14) + self.assertEqual(0,b) + # + m=MEDCouplingUMesh("toto",2) + coords=DataArrayDouble([0.,0.,0., 8.,0.,0., 8.,8.,0., 0.,8.,0.],4,3) + m.setCoords(coords) + m.allocateCells(0) + m.insertNextCell(NORM_QUAD4,[0,1,2,3]) + m.checkCoherency2() + self.assertEqual([4,0,1,2,3],m.getNodalConnectivity().getValues()) + a,b=m.distanceToPoint([5.,2.,0.1]) + self.assertAlmostEqual(0.1,a,14) ; self.assertEqual(0,b) + a,b=m.distanceToPoint([5.,-2.,4.]) + self.assertAlmostEqual(sqrt(2*2+4*4),a,14) ; self.assertEqual(0,b) + m.allocateCells(0) + m.insertNextCell(NORM_POLYGON,[0,1,2,3]) + m.checkCoherency2() + self.assertEqual([5,0,1,2,3],m.getNodalConnectivity().getValues()) + a,b=m.distanceToPoint([11.,3.,4.]) + self.assertAlmostEqual(sqrt(3*3+4*4),a,14) ; self.assertEqual(0,b) + a,b=m.distanceToPoint([4.,12.,5.]) + self.assertAlmostEqual(sqrt(4*4+5*5),a,14) ; self.assertEqual(0,b) + d=DataArrayDouble([-1.2,3.,2.],1,3) + for elt in d: + a,b=m.distanceToPoint(d) + self.assertAlmostEqual(sqrt(1.2*1.2+2*2),a,14) ; self.assertEqual(0,b) + pass + # + m=MEDCouplingUMesh("toto",1) + coords=DataArrayDouble([0.,0.,4.,0.,0.,4.],3,2) ; m.setCoords(coords) + m.allocateCells(0) ; m.insertNextCell(NORM_SEG2,[0,1]) ; m.insertNextCell(NORM_SEG2,[1,2]) + a,b=m.distanceToPoint([-0.1,4.1]) + self.assertAlmostEqual(0.14142135623730925,a,14) # b==1 self.assertEqual(2,c) + a,b=m.distanceToPoint([0.,3.9]) + self.assertAlmostEqual(0.07071067811865482,a,14) ; self.assertEqual(1,b) # self.assertEqual(2,c) + pass + + def testSwig2NonRegressionPartitionBySpreadZone1(self): + m=MEDCouplingCMesh() + arr=DataArrayDouble(6) ; arr.iota(0.) + m.setCoords(arr,arr,arr) + m=m.buildUnstructured() + mPart=m[50,80,85,87,92,122] + zones=mPart.partitionBySpreadZone() + self.assertEqual(4,len(zones)) + self.assertTrue(zones[0].isEqual(DataArrayInt([0]))) + self.assertTrue(zones[1].isEqual(DataArrayInt([1,2]))) + self.assertTrue(zones[2].isEqual(DataArrayInt([3,4]))) + self.assertTrue(zones[3].isEqual(DataArrayInt([5]))) + # + n,ni=m.computeNeighborsOfCells() + a,b=MEDCouplingUMesh.ComputeSpreadZoneGraduallyFromSeed(0,n,ni) + self.assertEqual(13,b) ; self.assertEqual(125,len(a)) ; self.assertTrue(a.isIdentity()) + a,b=MEDCouplingUMesh.ComputeSpreadZoneGraduallyFromSeed([1],n,ni) + self.assertEqual(12,b) ; self.assertEqual(125,len(a)) ; self.assertTrue(a.isIdentity()) + a,b=MEDCouplingUMesh.ComputeSpreadZoneGraduallyFromSeed((2,),n,ni) + self.assertEqual(11,b) ; self.assertEqual(125,len(a)) ; self.assertTrue(a.isIdentity()) + a,b=MEDCouplingUMesh.ComputeSpreadZoneGraduallyFromSeed(DataArrayInt([3]),n,ni) + self.assertEqual(12,b) ; self.assertEqual(125,len(a)) ; self.assertTrue(a.isIdentity()) + pass + + def testSwigUMeshInsertNextCell1(self): + m=MEDCouplingUMesh("toto",2) + # + coords=DataArrayDouble([0.,0.,1.,1.,1.,0.]) ; m.setCoords(coords) + da=DataArrayInt([0,1,2]) + m.allocateCells(0) + for i in xrange(5): + m.insertNextCell(NORM_TRI3,da) + pass + self.assertTrue(m.getNodalConnectivity().isEqual(DataArrayInt([3,0,1,2,3,0,1,2,3,0,1,2,3,0,1,2,3,0,1,2]))) + self.assertTrue(m.getNodalConnectivityIndex().isEqual(DataArrayInt([0,4,8,12,16,20]))) + # + da=DataArrayInt([0,1,2,3]) + m.allocateCells(0) + for i in xrange(5): + m.insertNextCell(NORM_TRI3,3,da) + pass + self.assertTrue(m.getNodalConnectivity().isEqual(DataArrayInt([3,0,1,2,3,0,1,2,3,0,1,2,3,0,1,2,3,0,1,2]))) + self.assertTrue(m.getNodalConnectivityIndex().isEqual(DataArrayInt([0,4,8,12,16,20]))) + # + da=DataArrayInt([0,1]) + m.allocateCells(0) + self.assertRaises(InterpKernelException,m.insertNextCell,NORM_TRI3,3,da) + # + da=DataArrayInt([0,1,2,0,1,3,0,1,4,0,1,5,0,1,6],5,3) + m.allocateCells(0) + for t in da: + m.insertNextCell(NORM_TRI3,t) + pass + self.assertTrue(m.getNodalConnectivity().isEqual(DataArrayInt([3,0,1,2,3,0,1,3,3,0,1,4,3,0,1,5,3,0,1,6]))) + self.assertTrue(m.getNodalConnectivityIndex().isEqual(DataArrayInt([0,4,8,12,16,20]))) + self.assertRaises(InterpKernelException,m.insertNextCell,NORM_TRI3,None) + pass + + def testSwigCurveLinearMesh1(self): + m=MEDCouplingCurveLinearMesh("toto") + m.setNodeGridStructure([2,3]) + coords=DataArrayDouble([0.,0., 2.,0., 0.,1., 1.9,1.1, 0.3,1.9, 2.2,2.1],6,2) + m.setCoords(coords) + m.checkCoherency() + m0=m.deepCpy() + self.assertTrue(m0.isEqual(m,1e-12)) + m.getCoords().setInfoOnComponents(["X [m]","Y [m]"]) + self.assertTrue(not m0.isEqual(m,1e-12)) + m0=m.deepCpy() + self.assertTrue(m0.isEqual(m,1e-12)) + self.assertEqual(m.getNodeGridStructure(),(2,3)) + pass + + def testSimplexize3(self): + m=MEDCouplingUMesh("toto",3) + m.allocateCells(0) + m.insertNextCell(NORM_TETRA4,[0,1,2,3]) + self.assertEqual([NORM_TETRA4],m.getAllGeoTypesSorted()) + m.insertNextCell(NORM_HEXA8,[4,5,6,7,8,9,10,11]) + self.assertEqual([NORM_TETRA4,NORM_HEXA8],m.getAllGeoTypesSorted()) + m.insertNextCell(NORM_HEXA8,[12,13,14,15,16,17,18,19]) + self.assertEqual([NORM_TETRA4,NORM_HEXA8],m.getAllGeoTypesSorted()) + m.insertNextCell(NORM_TETRA4,[20,21,22,23]) + self.assertEqual([NORM_TETRA4,NORM_HEXA8,NORM_TETRA4],m.getAllGeoTypesSorted()) + c1=DataArrayDouble([0.,0.,0.,0.,1.,0.,1.,0.,0.,0.,0.,1.],4,3) + c2=DataArrayDouble([0.,0.,0.,0.,1.,0.,1.,1.,0.,1.,0.,0., 0.,0.,1.,0.,1.,1.,1.,1.,1.,1.,0.,1.],8,3) ; c2+=[2.,0.,0.] + c3=c2+[2.,0.,0.] + c4=c1+[6.,0.,0.] + c=DataArrayDouble.Aggregate([c1,c2,c3,c4]) + m.setCoords(c) + m.checkCoherency2() + # + m1=m.deepCpy() + d1=m1.simplexize(PLANAR_FACE_5) + m1.checkCoherency2() + vol1=m1.getMeasureField(ON_CELLS).getArray() + self.assertTrue(vol1.isEqual(DataArrayDouble([1./6, 1./6, 1./6,1./6, 1./6, 1./3,1./6, 1./6, 1./6, 1./6, 1./3, 1./6]),1e-12)) + self.assertEqual(m1.getNodalConnectivity().getValues(),[14,0,1,2,3,14,4,9,5,6,14,4,8,9,11,14,4,7,11,6,14,9,11,10,6,14,4,9,6,11,14,12,17,13,14,14,12,16,17,19,14,12,15,19,14,14,17,19,18,14,14,12,17,14,19,14,20,21,22,23]) + self.assertEqual(m1.getNodalConnectivityIndex().getValues(),[0,5,10,15,20,25,30,35,40,45,50,55,60]) + self.assertTrue(d1.isEqual(DataArrayInt([0,1,1,1,1,1,2,2,2,2,2,3]))) + # + m2=m.deepCpy() + d2=m2.simplexize(PLANAR_FACE_6) + m2.checkCoherency2() + vol2=m2.getMeasureField(ON_CELLS).getArray() + self.assertTrue(vol2.isEqual(DataArrayDouble([1./6, 1./6, 1./6,1./6, 1./6, 1./6,1./6,1./6, 1./6, 1./6, 1./6, 1./6,1./6,1./6]),1e-12)) + self.assertEqual(m2.getNodalConnectivity().getValues(),[14,0,1,2,3,14,4,9,5,10,14,4,5,6,10,14,4,8,9,10,14,4,11,8,10,14,4,6,7,10,14,4,7,11,10,14,12,17,13,18,14,12,13,14,18,14,12,16,17,18,14,12,19,16,18,14,12,14,15,18,14,12,15,19,18,14,20,21,22,23]) + self.assertEqual(m2.getNodalConnectivityIndex().getValues(),[0,5,10,15,20,25,30,35,40,45,50,55,60,65,70]) + self.assertTrue(d2.isEqual(DataArrayInt([0,1,1,1,1,1,1,2,2,2,2,2,2,3]))) + pass + + def testSwig2CurveLinearMesh2(self): + c=MEDCouplingCMesh() + #2D + arr1=DataArrayDouble([0,1,3,7]) + arr2=DataArrayDouble([0,1,1.5]) + c.setCoords(arr1,arr2) + u=c.buildUnstructured() + coo=u.getCoords() + cl=MEDCouplingCurveLinearMesh() + cl.setCoords(coo) + cl.setNodeGridStructure([4,3]) + cl.checkCoherency2() + li1=[1.,2.,4.,0.5,1.,2.] + self.assertTrue(cl.getMeasureField(False).getArray().isEqual(DataArrayDouble(li1),1e-14)) + self.assertTrue(u.getMeasureField(False).getArray().isEqual(DataArrayDouble(li1),1e-14)) + li1_1=[0.5,0.5,2.,0.5,5.,0.5,0.5,1.25,2.,1.25,5.,1.25] + self.assertTrue(cl.getBarycenterAndOwner().isEqual(DataArrayDouble(li1_1,6,2),1e-14)) + self.assertTrue(u.getBarycenterAndOwner().isEqual(DataArrayDouble(li1_1,6,2),1e-14)) + #3D + c.setCoords(arr1,arr2,arr2) + u=c.buildUnstructured() + coo=u.getCoords() + cl=MEDCouplingCurveLinearMesh() + cl.setCoords(coo) + cl.setNodeGridStructure([4,3,3]) + cl.checkCoherency2() + li2=[1.,2.,4.,0.5, 1.,2.,0.5,1.,2.,0.25,0.5,1.] + li2_1=[0.5,0.5,0.5,2.,0.5,0.5,5.,0.5,0.5,0.5,1.25,0.5,2.,1.25,0.5,5.,1.25,0.5,0.5,0.5,1.25,2.,0.5,1.25,5.,0.5,1.25,0.5,1.25,1.25,2.,1.25,1.25,5.,1.25,1.25] + self.assertTrue(cl.getMeasureField(False).getArray().isEqual(DataArrayDouble(li2),1e-14)) + self.assertTrue(u.getMeasureField(False).getArray().isEqual(DataArrayDouble(li2),1e-14)) + self.assertTrue(cl.getBarycenterAndOwner().isEqual(DataArrayDouble(li2_1,12,3),1e-14)) + self.assertTrue(u.getBarycenterAndOwner().isEqual(DataArrayDouble(li2_1,12,3),1e-14)) + #1D spaceDim 1 + coo=DataArrayDouble(5) ; coo.iota(0.) + coo=coo*coo + cl.setCoords(coo) + cl.setNodeGridStructure([5]) + cl.checkCoherency2() + li3=[1.,3.,5.,7.] + li3_1=[0.5,2.5,6.5,12.5] + self.assertTrue(cl.getMeasureField(False).getArray().isEqual(DataArrayDouble(li3),1e-14)) + self.assertTrue(cl.buildUnstructured().getMeasureField(False).getArray().isEqual(DataArrayDouble(li3),1e-14)) + self.assertTrue(cl.getBarycenterAndOwner().isEqual(DataArrayDouble(li3_1),1e-14)) + self.assertTrue(cl.buildUnstructured().getBarycenterAndOwner().isEqual(DataArrayDouble(li3_1),1e-14)) + #1D spaceDim 2 + coo=DataArrayDouble.Meld(coo,coo) + cl.setCoords(coo) + cl.checkCoherency2() + li4=[sqrt(2.)*elt for elt in [1.,3.,5.,7.]] + li4_1=[0.5,0.5,2.5,2.5,6.5,6.5,12.5,12.5] + self.assertEqual(2,cl.getSpaceDimension()) + self.assertEqual(1,cl.getMeshDimension()) + self.assertEqual(4,cl.getNumberOfCells()) + self.assertEqual(5,cl.getNumberOfNodes()) + self.assertTrue(cl.getMeasureField(False).getArray().isEqual(DataArrayDouble(li4),1e-14)) + self.assertTrue(cl.buildUnstructured().getMeasureField(False).getArray().isEqual(DataArrayDouble(li4),1e-14)) + self.assertTrue(cl.getBarycenterAndOwner().isEqual(DataArrayDouble(li4_1,4,2),1e-14)) + self.assertTrue(cl.buildUnstructured().getBarycenterAndOwner().isEqual(DataArrayDouble(li4_1,4,2),1e-14)) + pass + + def testSwig2CurveLinearMeshNonRegression1(self): + coords=DataArrayDouble([0.0, 0.0, 0.10000000149011612, 0.6000000238418579, 0.10000000149011612, 0.30000001192092896, 1.100000023841858, 0.10000000149011612, 0.20000000298023224, 0.10000000149011612, 0.6000000238418579, 0.20000000298023224, 0.699999988079071, 0.6000000238418579, 0.10000000149011612, 1.2000000476837158, 0.6000000238418579, 0.30000001192092896, 0.10000000149011612, 1.100000023841858, 0.30000001192092896, 0.5, 1.100000023841858, 0.20000000298023224, 1.0, 1.2000000476837158, 0.10000000149011612, 0.0, 0.10000000149011612, 0.5, 0.5, 0.10000000149011612, 0.6000000238418579, 1.2000000476837158, 0.10000000149011612, 0.699999988079071, 0.10000000149011612, 0.6000000238418579, 0.699999988079071, 0.6000000238418579, 0.6000000238418579, 0.5, 1.100000023841858, 0.6000000238418579, 0.6000000238418579, 0.10000000149011612, 1.0, 0.6000000238418579, 0.699999988079071, 1.2000000476837158, 0.699999988079071, 0.8999999761581421, 1.0, 0.5, 0.10000000149011612, 0.10000000149011612, 1.2000000476837158, 0.699999988079071, 0.10000000149011612, 1.0, 1.0, 0.10000000149011612, 1.100000023841858, 0.10000000149011612, 0.6000000238418579, 1.100000023841858, 0.6000000238418579, 0.6000000238418579, 1.100000023841858, 1.100000023841858, 0.6000000238418579, 1.2000000476837158, 0.10000000149011612, 1.2000000476837158, 1.0, 0.5, 1.100000023841858, 1.2000000476837158, 1.2000000476837158, 1.100000023841858, 1.0],27,3) + m=MEDCouplingCurveLinearMesh("toto") + m.setCoords(coords) + m.setNodeGridStructure([3,3,3]) + # + vol=m.getMeasureField(False).getArray() + self.assertTrue(vol.isEqual(DataArrayDouble([0.11450000709295281, 0.10583334351579375,0.11149999939029423,0.08866666863113633, 0.1404166805123294,0.1250000135352219,0.1270833433481557,0.13258334288001067]),1e-12)) + self.assertTrue(vol.isEqual(m.buildUnstructured().getMeasureField(False).getArray(),1e-12)) + # + self.assertTrue(m.getBarycenterAndOwner().isEqual(m.buildUnstructured().getBarycenterAndOwner(),1e-12)) + pass + + def testSwig2NonRegressionDASetSelectedComponents1(self): + da=DataArrayDouble.New([1.,2.,3.,4.,5.,6.],3,2) + dv=DataArrayDouble.New(); + dv.alloc(4,4) + dv.fillWithZero() + # da has less tuples than dv + dv.setSelectedComponents(da,[1,0]) + # + self.assertTrue(dv.isEqual(DataArrayDouble([2.,1.,0.,0.,4.,3.,0.,0.,6.,5.,0.,0.,0.,0.,0.,0.],4,4),1e-14)) + # + da=DataArrayInt.New([1,2,3,4,5,6],3,2) + dv=DataArrayInt.New(); + dv.alloc(4,4) + dv.fillWithZero() + # da has less tuples than dv + dv.setSelectedComponents(da,[1,0]) + # + self.assertTrue(dv.isEqual(DataArrayInt([2,1,0,0,4,3,0,0,6,5,0,0,0,0,0,0],4,4))) + pass + + def testSwigSetItem3(self): + # 1-2 + d=DataArrayDouble([0,0,0,0,0,0,0,0,0,0,0,0],6,2) + d[3]=[1,2] + self.assertTrue(d.isEqual(DataArrayDouble([0,0,0,0,0,0,1,2,0,0,0,0],6,2),1e-14)) + # 2-2 false + d=DataArrayDouble([0,0,0,0,0,0,0,0,0,0,0,0],6,2) + d[[5,3,2]]=[1,2] + self.assertTrue(d.isEqual(DataArrayDouble([0,0,0,0,1,2,1,2,0,0,1,2],6,2),1e-14)) + # 3-2 false + d=DataArrayDouble([0,0,0,0,0,0,0,0,0,0,0,0],6,2) + d[:]=[1,2] + self.assertTrue(d.isEqual(DataArrayDouble([1,2,1,2,1,2,1,2,1,2,1,2],6,2),1e-14)) + # 4-2 false + d=DataArrayDouble([0,0,0,0,0,0,0,0,0,0,0,0],6,2) + d[DataArrayInt([0,3,4])]=[1,2] + self.assertTrue(d.isEqual(DataArrayDouble([1,2,0,0,0,0,1,2,1,2,0,0],6,2),1e-14)) + # 5-2 + d=DataArrayDouble([0,0,0,0,0,0,0,0,0,0,0,0],6,2) + d[5,1]=[7] + self.assertTrue(d.isEqual(DataArrayDouble([0,0,0,0,0,0,0,0,0,0,0,7],6,2),1e-14)) + # 6-2 false + d=DataArrayDouble([0,0,0,0,0,0,0,0,0,0,0,0],6,2) + d[[3,5],1]=[7] + self.assertTrue(d.isEqual(DataArrayDouble([0,0,0,0,0,0,0,7,0,0,0,7],6,2),1e-14)) + # 7-2 false + d=DataArrayDouble([0,0,0,0,0,0,0,0,0,0,0,0],6,2) + d[:-1:2,1]=[7] + self.assertTrue(d.isEqual(DataArrayDouble([0,7,0,0,0,7,0,0,0,7,0,0],6,2),1e-14)) + # 8-2 false + d=DataArrayDouble([0,0,0,0,0,0,0,0,0,0,0,0],6,2) + d[DataArrayInt([0,3,4]),1]=[7] + self.assertTrue(d.isEqual(DataArrayDouble([0,7,0,0,0,0,0,7,0,7,0,0],6,2),1e-14)) + # 9-2 + d=DataArrayDouble([0,0,0,0,0,0,0,0,0,0,0,0],6,2) + d[3,[1,0]]=[7,8] + self.assertTrue(d.isEqual(DataArrayDouble([0,0,0,0,0,0,8,7,0,0,0,0],6,2),1e-14)) + # 10-2 false + d=DataArrayDouble([0,0,0,0,0,0,0,0,0,0,0,0],6,2) + d[[1,3,4],[1,0]]=[7,8] + self.assertTrue(d.isEqual(DataArrayDouble([0,0,8,7,0,0,8,7,8,7,0,0],6,2),1e-14)) + # 11-2 false + d=DataArrayDouble([0,0,0,0,0,0,0,0,0,0,0,0],6,2) + d[1::2,[1,0]]=[7,8] + self.assertTrue(d.isEqual(DataArrayDouble([0,0,8,7,0,0,8,7,0,0,8,7],6,2),1e-14)) + # 12-2 false + d=DataArrayDouble([0,0,0,0,0,0,0,0,0,0,0,0],6,2) + d[DataArrayInt([1,4]),[1,0]]=[7,8] + self.assertTrue(d.isEqual(DataArrayDouble([0,0,8,7,0,0,0,0,8,7,0,0],6,2),1e-14)) + # 13-2 + d=DataArrayDouble([0,0,0,0,0,0,0,0,0,0,0,0],6,2) + d[1,:-1]=[9] + self.assertTrue(d.isEqual(DataArrayDouble([0,0,9,0,0,0,0,0,0,0,0,0],6,2),1e-14)) + # 14-2 false + d=DataArrayDouble([0,0,0,0,0,0,0,0,0,0,0,0],6,2) + d[[1,4,5],:]=[7,8] + self.assertTrue(d.isEqual(DataArrayDouble([0,0,7,8,0,0,0,0,7,8,7,8],6,2),1e-14)) + # 15-2 false + d=DataArrayDouble([0,0,0,0,0,0,0,0,0,0,0,0],6,2) + d[1::2,:]=[3,9] + self.assertTrue(d.isEqual(DataArrayDouble([0,0,3,9,0,0,3,9,0,0,3,9],6,2),1e-14)) + # 1-2 + d=DataArrayInt([0,0,0,0,0,0,0,0,0,0,0,0],6,2) + d[3]=[1,2] + self.assertTrue(d.isEqual(DataArrayInt([0,0,0,0,0,0,1,2,0,0,0,0],6,2))) + # 2-2 false + d=DataArrayInt([0,0,0,0,0,0,0,0,0,0,0,0],6,2) + d[[5,3,2]]=[1,2] + self.assertTrue(d.isEqual(DataArrayInt([0,0,0,0,1,2,1,2,0,0,1,2],6,2))) + # 3-2 false + d=DataArrayInt([0,0,0,0,0,0,0,0,0,0,0,0],6,2) + d[:]=[1,2] + self.assertTrue(d.isEqual(DataArrayInt([1,2,1,2,1,2,1,2,1,2,1,2],6,2))) + # 4-2 false + d=DataArrayInt([0,0,0,0,0,0,0,0,0,0,0,0],6,2) + d[DataArrayInt([0,3,4])]=[1,2] + self.assertTrue(d.isEqual(DataArrayInt([1,2,0,0,0,0,1,2,1,2,0,0],6,2))) + # 5-2 + d=DataArrayInt([0,0,0,0,0,0,0,0,0,0,0,0],6,2) + d[5,1]=[7] + self.assertTrue(d.isEqual(DataArrayInt([0,0,0,0,0,0,0,0,0,0,0,7],6,2))) + # 6-2 false + d=DataArrayInt([0,0,0,0,0,0,0,0,0,0,0,0],6,2) + d[[3,5],1]=[7] + self.assertTrue(d.isEqual(DataArrayInt([0,0,0,0,0,0,0,7,0,0,0,7],6,2))) + # 7-2 false + d=DataArrayInt([0,0,0,0,0,0,0,0,0,0,0,0],6,2) + d[:-1:2,1]=[7] + self.assertTrue(d.isEqual(DataArrayInt([0,7,0,0,0,7,0,0,0,7,0,0],6,2))) + # 8-2 false + d=DataArrayInt([0,0,0,0,0,0,0,0,0,0,0,0],6,2) + d[DataArrayInt([0,3,4]),1]=[7] + self.assertTrue(d.isEqual(DataArrayInt([0,7,0,0,0,0,0,7,0,7,0,0],6,2))) + # 9-2 + d=DataArrayInt([0,0,0,0,0,0,0,0,0,0,0,0],6,2) + d[3,[1,0]]=[7,8] + self.assertTrue(d.isEqual(DataArrayInt([0,0,0,0,0,0,8,7,0,0,0,0],6,2))) + # 10-2 false + d=DataArrayInt([0,0,0,0,0,0,0,0,0,0,0,0],6,2) + d[[1,3,4],[1,0]]=[7,8] + self.assertTrue(d.isEqual(DataArrayInt([0,0,8,7,0,0,8,7,8,7,0,0],6,2))) + # 11-2 false + d=DataArrayInt([0,0,0,0,0,0,0,0,0,0,0,0],6,2) + d[1::2,[1,0]]=[7,8] + self.assertTrue(d.isEqual(DataArrayInt([0,0,8,7,0,0,8,7,0,0,8,7],6,2))) + # 12-2 false + d=DataArrayInt([0,0,0,0,0,0,0,0,0,0,0,0],6,2) + d[DataArrayInt([1,4]),[1,0]]=[7,8] + self.assertTrue(d.isEqual(DataArrayInt([0,0,8,7,0,0,0,0,8,7,0,0],6,2))) + # 13-2 + d=DataArrayInt([0,0,0,0,0,0,0,0,0,0,0,0],6,2) + d[1,:-1]=[9] + self.assertTrue(d.isEqual(DataArrayInt([0,0,9,0,0,0,0,0,0,0,0,0],6,2))) + # 14-2 false + d=DataArrayInt([0,0,0,0,0,0,0,0,0,0,0,0],6,2) + d[[1,4,5],:]=[7,8] + self.assertTrue(d.isEqual(DataArrayInt([0,0,7,8,0,0,0,0,7,8,7,8],6,2))) + # 15-2 false + d=DataArrayInt([0,0,0,0,0,0,0,0,0,0,0,0],6,2) + d[1::2,:]=[3,9] + self.assertTrue(d.isEqual(DataArrayInt([0,0,3,9,0,0,3,9,0,0,3,9],6,2))) + pass + + def testSwig2ConvertLinearCellsToQuadratic1(self): + coordsExp=DataArrayDouble([-0.3,-0.3,0.2,-0.3,0.7,-0.3,-0.3,0.2,0.2,0.2,0.7,0.2,-0.3,0.7,0.2,0.7,0.7,0.7,-0.3,-0.05,-0.05,0.2,0.2,-0.05,-0.05,-0.3,0.45,-0.05,0.45,-0.3,0.45,0.2,0.7,-0.05,-0.05,0.7,0.2,0.45,-0.3,0.45,0.45,0.7,0.7,0.45],22,2) + # 2D + m2D=MEDCouplingDataForTest.build2DTargetMesh_1() + m2D.convertLinearCellsToQuadratic(0) + m2D.checkCoherency1() + self.assertEqual(m2D.getNodalConnectivity().getValues(),[8,0,3,4,1,9,10,11,12,6,1,4,2,11,13,14,6,4,5,2,15,16,13,8,6,7,4,3,17,18,10,19,8,7,8,5,4,20,21,15,18]) + self.assertEqual(m2D.getNodalConnectivityIndex().getValues(),[0,9,16,23,32,41]) + self.assertTrue(m2D.getCoords().isEqual(coordsExp,1e-14)) + # 1D + m1D=MEDCouplingDataForTest.build2DTargetMesh_1().buildDescendingConnectivity()[0] + m1D.convertLinearCellsToQuadratic(0) + m1D.checkCoherency1() + self.assertEqual(m1D.getNodalConnectivity().getValues(),[2,0,3,9,2,3,4,10,2,4,1,11,2,1,0,12,2,4,2,13,2,2,1,14,2,4,5,15,2,5,2,16,2,6,7,17,2,7,4,18,2,3,6,19,2,7,8,20,2,8,5,21]) + self.assertEqual(m1D.getNodalConnectivityIndex().getValues(),[0,4,8,12,16,20,24,28,32,36,40,44,48,52]) + self.assertTrue(m1D.getCoords().isEqual(coordsExp,1e-14)) + # 3D + m2D=MEDCouplingDataForTest.build2DTargetMesh_1() + m2D.changeSpaceDimension(3) + arr=DataArrayDouble(4); arr.iota(0) ; z=MEDCouplingCMesh() ; z.setCoords(arr) + m1D=z.buildUnstructured() ; m1D.setCoords(arr.changeNbOfComponents(3,0.)) + m1D.getCoords()[:]=m1D.getCoords()[:,[1,2,0]] + cooTmp=m2D.getCoords()[:] + m3D=m2D.buildExtrudedMesh(m1D,0) + m3D.convertLinearCellsToQuadratic(0) + m3D.checkCoherency1() + # check of new m3D content + coordsExp2=[coordsExp.changeNbOfComponents(3,i) for i in xrange(4)] + coordsExp3=[DataArrayDouble.Meld(cooTmp[:,[0,1]],cooTmp[:,2]+(0.5+float(i))) for i in xrange(3)] + coordsExp4=DataArrayDouble.Aggregate([coordsExp2[0],coordsExp3[0],coordsExp2[1],coordsExp3[1],coordsExp2[2],coordsExp3[2],coordsExp2[3]]) + c=DataArrayDouble.Aggregate(m3D.getCoords(),coordsExp4) + self.assertEqual(len(coordsExp4),115) + self.assertEqual(len(m3D.getCoords()),115) + a,b=c.findCommonTuples(1e-14) + self.assertEqual(len(b),len(coordsExp4)+1) + e,f=DataArrayInt.BuildOld2NewArrayFromSurjectiveFormat2(2*115,a,b) + self.assertEqual(f,115) + self.assertTrue(e.isEqual(DataArrayInt([0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97,98,99,100,101,102,103,104,105,106,107,108,109,110,111,112,113,114,0,1,2,3,4,5,6,7,8,36,37,38,39,48,49,53,54,58,59,60,66,67,44,47,52,45,46,57,64,65,70,9,10,11,12,13,14,15,16,17,40,41,42,43,50,51,55,56,61,62,63,68,69,75,78,81,76,77,84,88,89,92,18,19,20,21,22,23,24,25,26,71,72,73,74,79,80,82,83,85,86,87,90,91,97,100,103,98,99,106,110,111,114,27,28,29,30,31,32,33,34,35,93,94,95,96,101,102,104,105,107,108,109,112,113]))) + self.assertTrue(DataArrayInt([30,0,3,4,1,9,12,13,10,36,37,38,39,40,41,42,43,44,45,46,47,25,1,4,2,10,13,11,38,48,49,42,50,51,47,46,52,25,4,5,2,13,14,11,53,54,48,55,56,50,46,57,52,30,6,7,4,3,15,16,13,12,58,59,37,60,61,62,41,63,64,65,46,45,30,7,8,5,4,16,17,14,13,66,67,53,59,68,69,55,62,65,70,57,46,30,9,12,13,10,18,21,22,19,40,41,42,43,71,72,73,74,75,76,77,78,25,10,13,11,19,22,20,42,50,51,73,79,80,78,77,81,25,13,14,11,22,23,20,55,56,50,82,83,79,77,84,81,30,15,16,13,12,24,25,22,21,61,62,41,63,85,86,72,87,88,89,77,76,30,16,17,14,13,25,26,23,22,68,69,55,62,90,91,82,86,89,92,84,77,30,18,21,22,19,27,30,31,28,71,72,73,74,93,94,95,96,97,98,99,100,25,19,22,20,28,31,29,73,79,80,95,101,102,100,99,103,25,22,23,20,31,32,29,82,83,79,104,105,101,99,106,103,30,24,25,22,21,33,34,31,30,85,86,72,87,107,108,94,109,110,111,99,98,30,25,26,23,22,34,35,32,31,90,91,82,86,112,113,104,108,111,114,106,99]).isEqual(m3D.getNodalConnectivity())) + self.assertTrue(DataArrayInt([0,21,37,53,74,95,116,132,148,169,190,211,227,243,264,285]).isEqual(m3D.getNodalConnectivityIndex())) + # testing explode3DMeshTo1D + m3DSlice0=m3D[:5] + m3DSlice0.zipCoords() + a,b,c,d,e=m3DSlice0.explode3DMeshTo1D() + self.assertTrue(b.isEqual(DataArrayInt([0,1,2,3,4,5,6,7,8,9,10,11,2,12,13,6,14,15,11,10,16,17,18,12,19,20,14,10,21,16,22,23,1,24,25,26,5,27,28,29,10,9,30,31,17,23,32,33,19,26,29,34,21,10]))) + self.assertTrue(c.isEqual(DataArrayInt([0,12,21,30,42,54]))) + self.assertTrue(d.isEqual(DataArrayInt([0,0,3,0,1,0,0,0,3,0,1,0,0,0,3,0,1,2,3,4,0,1,1,2,1,1,2,1,1,2,2,4,2,2,4,2,2,4,3,3,4,3,3,3,4,3,3,3,4,4,4,4,4,4]))) + self.assertTrue(e.isEqual(DataArrayInt([0,1,3,5,6,7,9,11,12,13,15,20,22,24,25,27,28,30,32,33,35,36,38,39,41,42,43,45,46,47,49,50,51,52,53,54]))) + self.assertTrue(a.getNodalConnectivity().isEqual(DataArrayInt([2,0,3,18,2,3,4,19,2,4,1,20,2,1,0,21,2,9,12,22,2,12,13,23,2,13,10,24,2,10,9,25,2,0,9,26,2,3,12,27,2,4,13,28,2,1,10,29,2,4,2,30,2,2,1,31,2,13,11,32,2,11,10,33,2,2,11,34,2,4,5,35,2,5,2,36,2,13,14,37,2,14,11,38,2,5,14,39,2,6,7,40,2,7,4,41,2,3,6,42,2,15,16,43,2,16,13,44,2,12,15,45,2,6,15,46,2,7,16,47,2,7,8,48,2,8,5,49,2,16,17,50,2,17,14,51,2,8,17,52]))) + self.assertTrue(a.getNodalConnectivityIndex().isEqual(DataArrayInt([0,4,8,12,16,20,24,28,32,36,40,44,48,52,56,60,64,68,72,76,80,84,88,92,96,100,104,108,112,116,120,124,128,132,136,140]))) + self.assertTrue(a.getCoords().isEqual(DataArrayDouble([-0.3,-0.3,0.0,0.2,-0.3,0.0,0.7,-0.3,0.0,-0.3,0.2,0.0,0.2,0.2,0.0,0.7,0.2,0.0,-0.3,0.7,0.0,0.2,0.7,0.0,0.7,0.7,0.0,-0.3,-0.3,1.0,0.2,-0.3,1.0,0.7,-0.3,1.0,-0.3,0.2,1.0,0.2,0.2,1.0,0.7,0.2,1.0,-0.3,0.7,1.0,0.2,0.7,1.0,0.7,0.7,1.0,-0.3,-0.05,0.0,-0.05,0.2,0.0,0.2,-0.05,0.0,-0.05,-0.3,0.0,-0.3,-0.05,1.0,-0.05,0.2,1.0,0.2,-0.05,1.0,-0.05,-0.3,1.0,-0.3,-0.3,0.5,-0.3,0.2,0.5,0.2,0.2,0.5,0.2,-0.3,0.5,0.45,-0.05,0.0,0.45,-0.3,0.0,0.45,-0.05,1.0,0.45,-0.3,1.0,0.7,-0.3,0.5,0.45,0.2,0.0,0.7,-0.05,0.0,0.45,0.2,1.0,0.7,-0.05,1.0,0.7,0.2,0.5,-0.05,0.7,0.0,0.2,0.45,0.0,-0.3,0.45,0.0,-0.05,0.7,1.0,0.2,0.45,1.0,-0.3,0.45,1.0,-0.3,0.7,0.5,0.2,0.7,0.5,0.45,0.7,0.0,0.7,0.45,0.0,0.45,0.7,1.0,0.7,0.45,1.0,0.7,0.7,0.5],53,3),1e-14)) + pass + + def testSwig2DataArrayPushBackValsSilent1(self): + d=DataArrayDouble() + d.pushBackValsSilent([4,5,6]) + self.assertTrue(d.isEqual(DataArrayDouble([4.,5.,6.]),1e-14)) + e=DataArrayDouble([1,2,3],1,3) + for t in e: d.pushBackValsSilent(t) + self.assertTrue(d.isEqual(DataArrayDouble([4.,5.,6.,1.,2.,3.]),1e-14)) + d.pushBackValsSilent(DataArrayDouble([9,10.])) + self.assertTrue(d.isEqual(DataArrayDouble([4.,5.,6.,1.,2.,3.,9.,10.]),1e-14)) + d.pushBackValsSilent(DataArrayDouble(0,1)) + self.assertTrue(d.isEqual(DataArrayDouble([4.,5.,6.,1.,2.,3.,9.,10.]),1e-14)) + e=DataArrayDouble([1,2,3],3,1) + for t in e: d.pushBackValsSilent(t) + self.assertTrue(d.isEqual(DataArrayDouble([4.,5.,6.,1.,2.,3.,9.,10.,1.,2.,3.]),1e-14)) + d.pushBackValsSilent(77) + self.assertTrue(d.isEqual(DataArrayDouble([4.,5.,6.,1.,2.,3.,9.,10.,1.,2.,3.,77.]),1e-14)) + # + d=DataArrayInt() + d.pushBackValsSilent([4,5,6]) + self.assertTrue(d.isEqual(DataArrayInt([4,5,6]))) + e=DataArrayInt([1,2,3],1,3) + for t in e: d.pushBackValsSilent(t) + self.assertTrue(d.isEqual(DataArrayInt([4,5,6,1,2,3]))) + d.pushBackValsSilent(DataArrayInt([9,10])) + self.assertTrue(d.isEqual(DataArrayInt([4,5,6,1,2,3,9,10]))) + d.pushBackValsSilent(DataArrayInt(0,1)) + self.assertTrue(d.isEqual(DataArrayInt([4,5,6,1,2,3,9,10]))) + e=DataArrayInt([1,2,3],3,1) + for t in e: d.pushBackValsSilent(t) + self.assertTrue(d.isEqual(DataArrayInt([4,5,6,1,2,3,9,10,1,2,3]))) + d.pushBackValsSilent(77) + self.assertTrue(d.isEqual(DataArrayInt([4,5,6,1,2,3,9,10,1,2,3,77]))) + pass + + def testSwig2ConvertLinearCellsToQuadratic2(self): + m2D=MEDCouplingDataForTest.build2DTargetMesh_1() + ret=m2D.convertLinearCellsToQuadratic(1) + self.assertTrue(ret.isIdentity()) + self.assertEqual(5,len(ret)) + m2D.checkCoherency1() + coordsExp=DataArrayDouble([-0.3,-0.3,0.2,-0.3,0.7,-0.3,-0.3,0.2,0.2,0.2,0.7,0.2,-0.3,0.7,0.2,0.7,0.7,0.7,-0.3,-0.05,-0.05,0.2,0.2,-0.05,-0.05,-0.3,0.45,-0.05,0.45,-0.3,0.45,0.2,0.7,-0.05,-0.05,0.7,0.2,0.45,-0.3,0.45,0.45,0.7,0.7,0.45,-0.05,-0.05,0.3666666666666667,-0.1333333333333333,0.5333333333333332,0.03333333333333334,-0.05,0.45,0.45,0.45],27,2) + self.assertTrue(m2D.getCoords().isEqual(coordsExp,1e-14)) + self.assertTrue(m2D.getNodalConnectivity().isEqual(DataArrayInt([9,0,3,4,1,9,10,11,12,22,7,1,4,2,11,13,14,23,7,4,5,2,15,16,13,24,9,6,7,4,3,17,18,10,19,25,9,7,8,5,4,20,21,15,18,26]))) + self.assertTrue(m2D.getNodalConnectivityIndex().isEqual(DataArrayInt([0,10,18,26,36,46]))) + # + m2D=MEDCouplingDataForTest.build2DTargetMesh_1()[(0,3)] ; m2D.zipCoords() + m2D.changeSpaceDimension(3) + arr=DataArrayDouble(3); arr.iota(0) ; z=MEDCouplingCMesh() ; z.setCoords(arr) + m1D=z.buildUnstructured() ; m1D.setCoords(arr.changeNbOfComponents(3,0.)) + m1D.getCoords()[:]=m1D.getCoords()[:,[1,2,0]] + cooTmp=m2D.getCoords()[:] + m3D=m2D.buildExtrudedMesh(m1D,0) + ret=m3D.convertLinearCellsToQuadratic(1) + self.assertTrue(ret.isIdentity()) + self.assertEqual(4,len(ret)) + m3D.checkCoherency1() + coordsExp2=DataArrayDouble([-0.3,-0.3,0.0,0.2,-0.3,0.0,-0.3,0.2,0.0,0.2,0.2,0.0,-0.3,0.7,0.0,0.2,0.7,0.0,-0.3,-0.3,1.0,0.2,-0.3,1.0,-0.3,0.2,1.0,0.2,0.2,1.0,-0.3,0.7,1.0,0.2,0.7,1.0,-0.3,-0.3,2.0,0.2,-0.3,2.0,-0.3,0.2,2.0,0.2,0.2,2.0,-0.3,0.7,2.0,0.2,0.7,2.0,-0.3,-0.05,0.0,-0.05,0.2,0.0,0.2,-0.05,0.0,-0.05,-0.3,0.0,-0.3,-0.05,1.0,-0.05,0.2,1.0,0.2,-0.05,1.0,-0.05,-0.3,1.0,-0.3,-0.3,0.5,-0.3,0.2,0.5,0.2,0.2,0.5,0.2,-0.3,0.5,-0.05,0.7,0.0,0.2,0.45,0.0,-0.3,0.45,0.0,-0.05,0.7,1.0,0.2,0.45,1.0,-0.3,0.45,1.0,-0.3,0.7,0.5,0.2,0.7,0.5,-0.3,-0.05,2.0,-0.05,0.2,2.0,0.2,-0.05,2.0,-0.05,-0.3,2.0,-0.3,-0.3,1.5,-0.3,0.2,1.5,0.2,0.2,1.5,0.2,-0.3,1.5,-0.05,0.7,2.0,0.2,0.45,2.0,-0.3,0.45,2.0,-0.3,0.7,1.5,0.2,0.7,1.5,-0.05,-0.05,0.0,-0.3,-0.05,0.5,-0.05,0.2,0.5,0.2,-0.05,0.5,-0.05,-0.3,0.5,-0.05,-0.05,1.0,-0.05,0.45,0.0,-0.05,0.7,0.5,0.2,0.45,0.5,-0.3,0.45,0.5,-0.05,0.45,1.0,-0.3,-0.05,1.5,-0.05,0.2,1.5,0.2,-0.05,1.5,-0.05,-0.3,1.5,-0.05,-0.05,2.0,-0.05,0.7,1.5,0.2,0.45,1.5,-0.3,0.45,1.5,-0.05,0.45,2.0,-0.05,-0.05,0.5,-0.05,0.45,0.5,-0.05,-0.05,1.5,-0.05,0.45,1.5],75,3) + self.assertTrue(m3D.getCoords().isEqual(coordsExp2,1e-14)) + self.assertTrue(m3D.getNodalConnectivity().isEqual(DataArrayInt([27,0,2,3,1,6,8,9,7,18,19,20,21,22,23,24,25,26,27,28,29,51,52,53,54,55,56,71,27,4,5,3,2,10,11,9,8,30,31,19,32,33,34,23,35,36,37,28,27,57,58,59,53,60,61,72,27,6,8,9,7,12,14,15,13,22,23,24,25,38,39,40,41,42,43,44,45,56,62,63,64,65,66,73,27,10,11,9,8,16,17,15,14,33,34,23,35,46,47,39,48,49,50,44,43,61,67,68,63,69,70,74]))) + self.assertTrue(m3D.getNodalConnectivityIndex().isEqual(DataArrayInt([0,28,56,84,112]))) + pass + + def testSwig2GaussNEIntegral1(self): + m2D=MEDCouplingDataForTest.build2DTargetMesh_1() + m0=m2D[0] ; m0.zipCoords() + m1=m2D[[1,2]] ; m1.zipCoords() + m2=m2D[[3,4]] ; m2.zipCoords() + m0.convertLinearCellsToQuadratic(1) + m1.convertLinearCellsToQuadratic(0) + m2.convertLinearCellsToQuadratic(1) + m=MEDCouplingUMesh.MergeUMeshes([m0,m1,m2]) + m.mergeNodes(1e-12) + f=MEDCouplingFieldDouble(ON_GAUSS_NE) + f.setMesh(m) + arr=DataArrayDouble([1.1,2.2,3.3,4.4,5.5,6.6,7.7,8.8,9.9, + 11.1,12.2,13.3,14.4,15.5,16.6, + 21.1,22.2,23.3,24.4,25.5,26.6, + 31.1,32.2,33.3,34.4,35.5,36.6,37.7,38.8,39.9, + 41.1,42.2,43.3,44.4,45.5,46.6,47.7,48.8,49.9]) + arr2=DataArrayDouble(len(arr),2) + arr2[:,0]=arr ; arr2[:,1]=arr+100 + f.setArray(arr2) + f.checkCoherency() + res=f.integral(False) + # a=25./81 ; b=40./81 ; c=64./81 + # p1=0.11169079483905 ; p2=0.0549758718227661 + # 1st compo + # c0=(a*(1.1+2.2+3.3+4.4)+b*(5.5+6.6+7.7+8.8)+c*9.9)*0.25/3.9999999999999978 ; c0=1.5837962962962973 + # c1=(p2*(11.1+12.2+13.3)+p1*(14.4+15.5+16.6))*0.125/0.4999999999854482 ; c1=1.8014347172346943 + # c2=(p2*(21.1+22.2+23.3)+p1*(24.4+25.5+26.6))*0.125/0.4999999999854482 ; c2=3.0514347172346943 + # c3=(a*(31.1+32.2+33.3+34.4)+b*(35.5+36.6+37.7+38.8)+c*39.9)*0.25/3.9999999999999978 ; c3=9.0837962962963 + # c4=(a*(41.1+42.2+43.3+44.4)+b*(45.5+46.6+47.7+48.8)+c*49.9)*0.25/3.9999999999999978 ; c4=11.583796296296303 + # c0+c1+c2+c3+c4=27.104258323358287 + integExp0=27.104258323358287 + self.assertAlmostEqual(res[0],integExp0,13) + # 2nd compo + # c0=(a*(101.1+102.2+103.3+104.4)+b*(105.5+106.6+107.7+108.8)+c*109.9)*0.25/3.9999999999999978 ; c0=26.58379629629631 + # c1=(p2*(111.1+112.2+113.3)+p1*(114.4+115.5+116.6))*0.125/0.4999999999854482 ; c1=14.301434717234699 + # c2=(p2*(121.1+122.2+123.3)+p1*(124.4+125.5+126.6))*0.125/0.4999999999854482 ; c2=15.5514347172347 + # c3=(a*(131.1+132.2+133.3+134.4)+b*(135.5+136.6+137.7+138.8)+c*139.9)*0.25/3.9999999999999978 ; c3=34.08379629629631 + # c4=(a*(141.1+142.2+143.3+144.4)+b*(145.5+146.6+147.7+148.8)+c*149.9)*0.25/3.9999999999999978 ; c4=36.58379629629632 + # c0+c1+c2+c3+c4=127.10425832335835 + integExp1=127.10425832335835 + self.assertAlmostEqual(res[1],integExp1,12) + meas=f.getDiscretization().getMeasureField(f.getMesh(),False) + intPerTuple=meas*f + res2=intPerTuple.accumulate() + self.assertAlmostEqual(res2[0],integExp0,13) + self.assertAlmostEqual(res2[1],integExp1,12) + # + meas2=f.buildMeasureField(False) + intPerTuple=meas2*f + res3=intPerTuple.accumulate() + self.assertAlmostEqual(res3[0],integExp0,13) + self.assertAlmostEqual(res3[1],integExp1,12) + # + res4=f.getWeightedAverageValue(False) # res4==res2 because sum of area of mesh is equal to 1 + self.assertAlmostEqual(res4[0],integExp0,13) + self.assertAlmostEqual(res4[1],integExp1,12) + # + m.scale([0,0],2.) + # + res5=f.getWeightedAverageValue() # res4==res4 because weighted average is not sensitive to the scaling + self.assertAlmostEqual(res5[0],integExp0,13) + self.assertAlmostEqual(res5[1],integExp1,12) + meas3=f.buildMeasureField(False) + delta=4*meas2.getArray()-meas3.getArray() + delta.abs() + self.assertTrue(delta.isUniform(0.,1e-16)) + res6=f.integral(False) + self.assertAlmostEqual(res6[0],4.*integExp0,12) + self.assertAlmostEqual(res6[1],4.*integExp1,11) + pass + + def testSwig2SlowDADFindClosestTupleId(self): + nbPts=[10,] + for nbPt in nbPts: + d=DataArrayDouble(nbPt) ; d.iota() ; d*=1./(nbPt-1) + c=MEDCouplingCMesh() ; c.setCoords(d,d) ; m=c.buildUnstructured() ; pts=m.getCoords() ; del m + # + d0=DataArrayDouble((nbPt-1)*(nbPt-1)) ; d0.iota() ; d0*=(3./((nbPt-1)*(nbPt-1))) ; d0=d0.applyFunc("exp(x)-1") + d1=DataArrayDouble((nbPt-1)*(nbPt-1)) ; d1.iota() + d2=DataArrayDouble.Meld(d0,d1) ; d2=d2.fromPolarToCart() ; d2+=[0.32,0.73] + ids=pts.findClosestTupleId(d2) + #print "Start of costly computation" + idsExpected=DataArrayInt(len(d2)) + tmp=1e300 + for i,elt in enumerate(d2): + l,m=(pts-elt).magnitude().getMinValue() + idsExpected.setIJSilent(i,0,m) + if l<tmp: + tmp=l ; tmp1=m ; tmp2=i + pass + pass + #print "End of costly computation" + self.assertTrue(idsExpected.isEqual(ids)) + a,b,c=pts.minimalDistanceTo(d2) + self.assertEqual(tmp,a) + self.assertEqual(tmp1,b) + self.assertEqual(tmp2,c) + # + l=[d2[:,i] for i in [0,1]] + for elt in l: elt.reverse() + d2i=DataArrayDouble.Meld(l) + ids1=pts.findClosestTupleId(d2i) + idsExpectedI=idsExpected.deepCpy() ; idsExpectedI.reverse() + self.assertTrue(idsExpectedI.isEqual(ids1)) + # + l=[pts[:,i] for i in [0,1]] + for elt in l: elt.reverse() + ptsi=DataArrayDouble.Meld(l) + ids2=ptsi.findClosestTupleId(d2) + idsExpected2=nbPt*nbPt-1-ids + self.assertTrue(idsExpected2.isEqual(ids2)) + # + ids3=ptsi.findClosestTupleId(d2i) + idsExpected3=idsExpected2.deepCpy() ; idsExpected3.reverse() + self.assertTrue(idsExpected3.isEqual(ids3)) + pass + + def testSwig2DataArrayAsciiChar1(self): + alpha=DataArrayInt(26) ; alpha.iota(ord("A")) + d=DataArrayAsciiChar(alpha.getValues(),2,13) + d.setInfoOnComponents(["c%i"%(v) for v in xrange(13)]) + self.assertEqual('ABCDEFGHIJKLM',d.getTuple(0)) + self.assertEqual('NOPQRSTUVWXYZ',d.getTuple(1)) + self.assertEqual(2,d.getNumberOfTuples()) + self.assertEqual(26,d.getNbOfElems()) + self.assertEqual(13,d.getNumberOfComponents()) + dd=d.deepCpy() + self.assertTrue(d.isEqual(dd)) + dd.setIJ(0,3,'d') + self.assertTrue(not d.isEqual(dd)) + d.setIJ(0,3,ord('d')) + self.assertTrue(d.isEqual(dd)) + d.rearrange(1) + d.reserve(20) + self.assertEqual(20,d.getNumberOfTuples()) + self.assertEqual(20,d.getNbOfElems()) + self.assertEqual(1,d.getNumberOfComponents()) + # + d0=DataArrayAsciiChar([ord('a')],1,1) + self.assertEqual('a',d0.asciiCharValue()) + self.assertTrue(not d0.empty()) + d0=DataArrayAsciiChar(0,3) + self.assertTrue(d0.empty()) + d.pushBackSilent("U") ; d.pushBackSilent("V") ; d.pushBackSilent("W") + self.assertEqual("W",d.popBackSilent()) + d.rearrange(2) + self.assertEqual(['AB','Cd','EF','GH','IJ','KL','MN','OP','QR','ST','UV'],d.toStrList()) + d.fillWithZero() + self.assertEqual(11*[''],d.toStrList()) + d.fillWithValue('T') + self.assertEqual(11*["TT"],d.toStrList()) + d.rearrange(1) + self.assertTrue(d.isUniform("T")) + d.rearrange(2) + # + dd.rearrange(2) + dd2=dd.deepCpy() + dd.renumberInPlace([3,1,2,4,0,11,10,9,8,7,5,12,6]) + self.assertEqual(dd.toStrList(),['IJ','Cd','EF','AB','GH','UV','YZ','ST','QR','OP','MN','KL','WX']) + dd.renumberInPlaceR([3,1,2,4,0,11,10,9,8,7,5,12,6]) + self.assertEqual(['AB','Cd','EF','GH','IJ','KL','MN','OP','QR','ST','UV','WX','YZ'],dd.toStrList()) + e=dd.renumber([3,1,2,4,0,11,10,9,8,7,5,12,6]) + self.assertEqual(e.toStrList(),['IJ','Cd','EF','AB','GH','UV','YZ','ST','QR','OP','MN','KL','WX']) + e=dd.renumberR([3,1,2,4,0,11,10,9,8,7,5,12,6]) + self.assertEqual(e.toStrList(),['GH','Cd','EF','IJ','AB','WX','UV','ST','QR','OP','KL','YZ','MN']) + e=dd.renumberAndReduce([1,1,1,1,1,1,1,2,0,0,0,0,0],3) + self.assertEqual(['YZ','MN','OP'],e.toStrList()) + self.assertEqual(['GH','IJ'],dd.selectByTupleIdSafe([3,4]).toStrList()) + self.assertEqual(['AB','GH','MN','ST','YZ'],dd.selectByTupleId2(0,13,3).toStrList()) + dd3=dd.changeNbOfComponents(3,"G") + self.assertEqual(['ABG','CdG','EFG','GHG','IJG','KLG','MNG','OPG','QRG','STG','UVG','WXG','YZG'],dd3.toStrList()) + dd3.rearrange(1) ; self.assertEqual("G",dd3.back()) ; dd3.rearrange(3) + self.assertTrue(dd3.changeNbOfComponents(2,"\0").isEqual(dd)) + self.assertEqual(len(dd),13) + d=DataArrayAsciiChar(13,2) ; d.fillWithValue('Y') + dd3.meldWith(d) + self.assertEqual(['ABGYY','CdGYY','EFGYY','GHGYY','IJGYY','KLGYY','MNGYY','OPGYY','QRGYY','STGYY','UVGYY','WXGYY','YZGYY'],dd3.toStrList()) + self.assertEqual("d",dd3.getIJ(0,6)) + self.assertRaises(InterpKernelException,dd3.getIJSafe,0,6) + self.assertEqual("d",dd3.getIJSafe(1,1)) + dd3.rearrange(1) + e=dd3.getIdsEqual("Y") + self.assertTrue(e.isEqual(DataArrayInt([3,4,8,9,13,14,18,19,23,24,28,29,33,34,38,39,43,44,48,49,53,54,58,59,60,63,64]))) + e=dd3.getIdsNotEqual("Y") + self.assertTrue(e.isEqual(DataArrayInt([0,1,2,5,6,7,10,11,12,15,16,17,20,21,22,25,26,27,30,31,32,35,36,37,40,41,42,45,46,47,50,51,52,55,56,57,61,62]))) + self.assertEqual(("d",6),dd3.getMaxValue()) + self.assertEqual(("A",0),dd3.getMinValue()) + self.assertEqual(26,dd3.search("LGYYM")) + self.assertEqual(-1,dd3.search("LGYYN")) + dd3.rearrange(5) + self.assertEqual(7,dd3.locateTuple("OPGYY")) + self.assertTrue("OPGYY" in dd3) + self.assertEqual(7,dd3.index("OPGYY")) + self.assertEqual(-1,dd3.locateTuple("OPGYP")) + dd3.rearrange(1) + self.assertEqual(2,dd3.locateValue("OPGYY")) + self.assertTrue(dd3.presenceOfValue("OPGYY")) + self.assertTrue("O" in dd3) + self.assertTrue(not dd3.presenceOfValue("z")) + self.assertTrue("z" not in dd3) + dd3.rearrange(5) + l=list(dd3) + self.assertEqual([e.buildDAAsciiChar().toStrList()[0] for e in list(dd3)],dd3.toStrList()) + dd3.reAlloc(5) + dd4=DataArrayChar.Aggregate(dd3,dd3) + self.assertEqual(['ABGYY','CdGYY','EFGYY','GHGYY','IJGYY','ABGYY','CdGYY','EFGYY','GHGYY','IJGYY'],dd4.toStrList()) + dd5=DataArrayChar.Aggregate([dd4,dd3,dd4]) + self.assertEqual(['ABGYY','CdGYY','EFGYY','GHGYY','IJGYY','ABGYY','CdGYY','EFGYY','GHGYY','IJGYY','ABGYY','CdGYY','EFGYY','GHGYY','IJGYY','ABGYY','CdGYY','EFGYY','GHGYY','IJGYY','ABGYY','CdGYY','EFGYY','GHGYY','IJGYY'],dd5.toStrList()) + # getitem,__iter__,__setitem__ + a=list(dd3) + self.assertEqual("ABGYY",str(a[0])) + dd4=dd3[::2] + self.assertEqual(['ABGYY','EFGYY','IJGYY'],dd4.toStrList()) + dd4=dd3[(3,2,1)] + self.assertEqual(['GHGYY','EFGYY','CdGYY'],dd4.toStrList()) + dd4=dd3[:] + dd4[::2]=["12","345","67890"] + self.assertEqual(['12 ','CdGYY','345 ','GHGYY','67890'],dd4.toStrList()) + dd4=dd3[:] + dd4[[1,2]]=" " + self.assertEqual(['ABGYY',' ',' ','GHGYY','IJGYY'],dd4.toStrList()) + dd4=dd3[:] + dd4[4]='12345' + self.assertEqual(['ABGYY','CdGYY','EFGYY','GHGYY','12345'],dd4.toStrList()) + dd4[0]=dd4[1] + self.assertEqual(['CdGYY','CdGYY','EFGYY','GHGYY','12345'],dd4.toStrList()) + dd4=DataArrayAsciiChar(["abc","de","fghi"]) + self.assertEqual(['abc ','de ','fghi'],dd4.toStrList()) + dd4=DataArrayAsciiChar(["abc","de","fghi"],"t") + self.assertEqual(['abct','dett','fghi'],dd4.toStrList()) + pass + + def testSwig2GaussNELocalizationOfDiscValues(self): + m=MEDCouplingDataForTest.build2DTargetMesh_3()[[0,1,3,4,5,6,8,9]] # suppression of polygons + f=MEDCouplingFieldDouble(ON_GAUSS_NE) + f.setMesh(m) + loc=f.getLocalizationOfDiscr() + self.assertEqual(42,len(loc)) + self.assertTrue(loc.isEqual(DataArrayDouble([0.,0.,1.,0.,0.5,1.,0.,0.,1.,0.,1.,1.,0.,1.,0.,0.,1.,0.,0.5,1.,0.5,0.,0.75,0.5,0.25,0.5,0.,0.,1.,0.,1.,1.,0.,1.,0.5,0.,1.,0.5,0.5,1.,0.,0.5,0.,0.,0.5,1.,1.,0.,0.,0.,0.,1.,1.,1.,1.,0.,0.,0.,0.5,1.,1.,0.,0.25,0.5,0.75,0.5,0.5,0.,0.,0.,0.,1.,1.,1.,1.,0.,0.,0.5,0.5,1.,1.,0.5,0.5,0.],42,2),1e-13)) + m.changeSpaceDimension(3) + m.getCoords()[:,2]=7. + loc=f.getLocalizationOfDiscr() + self.assertEqual(42,len(loc)) + self.assertTrue(loc.isEqual(DataArrayDouble([0.,0.,7.,1.,0.,7.,0.5,1.,7.,0.,0.,7.,1.,0.,7.,1.,1.,7.,0.,1.,7.,0.,0.,7.,1.,0.,7.,0.5,1.,7.,0.5,0.,7.,0.75,0.5,7.,0.25,0.5,7.,0.,0.,7.,1.,0.,7.,1.,1.,7.,0.,1.,7.,0.5,0.,7.,1.,0.5,7.,0.5,1.,7.,0.,0.5,7.,0.,0.,7.,0.5,1.,7.,1.,0.,7.,0.,0.,7.,0.,1.,7.,1.,1.,7.,1.,0.,7.,0.,0.,7.,0.5,1.,7.,1.,0.,7.,0.25,0.5,7.,0.75,0.5,7.,0.5,0.,7.,0.,0.,7.,0.,1.,7.,1.,1.,7.,1.,0.,7.,0.,0.5,7.,0.5,1.,7.,1.,0.5,7.,0.5,0.,7.],42,3),1e-13)) + pass + + def testSwig2GaussMeasureAndIntegral(self): + ft=MEDCouplingDataForTest.buildFieldOnGauss_1() + mea=ft.buildMeasureField(False) + mea.checkCoherency() + self.assertTrue(mea.getArray().isEqual(DataArrayDouble([-0.08504076274779823,-0.06378057206084897,-0.08504076274779869,-0.10630095343474463,-0.12756114412169625,-0.10630095343474734,-0.0637805720608491,-0.0850407627477968,-0.1063009534347449,-0.0850407627477994,-0.10630095343474809,-0.1275611441216954,-0.037205333702161475,-0.037205333702161475,-0.037205333702161475,-0.037205333702161475,-0.047835429045636084,-0.047835429045636084,-0.047835429045636084,-0.047835429045636084,-0.05846552438911087,-0.05846552438911087,-0.05846552438911087,-0.05846552438911087,-0.037205333702161725,-0.037205333702161725,-0.037205333702161725,-0.037205333702161725,-0.047835429045635834,-0.047835429045635834,-0.047835429045635834,-0.047835429045635834,-0.05846552438911058,-0.05846552438911058,-0.05846552438911058,-0.05846552438911058,-0.03879154890291829,-0.03879154890291829,-0.03879154890291829,-0.04120270848015563,-0.04120270848015563,-0.04120270848015563,-0.03393028948486933,-0.03393028948486933,-0.03393028948486933,-0.03151955746491709,-0.03151955746491709,-0.03151955746491709,-0.02424752187358276,-0.02424752187358276,-0.02424752187358276,-0.026657914642918758,-0.026657914642918758,-0.026657914642918758,-0.04120270848015456,-0.04120270848015456,-0.04120270848015456,-0.03879154890291757,-0.03879154890291757,-0.03879154890291757,-0.031519557464916595,-0.031519557464916595,-0.031519557464916595,-0.03393028948487046,-0.03393028948487046,-0.03393028948487046,-0.0266579146429191,-0.0266579146429191,-0.0266579146429191,-0.024247521873582645,-0.024247521873582645,-0.024247521873582645,-0.01851718920904466,-0.01851718920904466,-0.01851718920904466,-0.01851718920904466,-0.029627502734471456,-0.029627502734471456,-0.029627502734471456,-0.029627502734471456,-0.04740400437515433,-0.015150427534672922,-0.015150427534672922,-0.015150427534672922,-0.015150427534672922,-0.024240684055476674,-0.024240684055476674,-0.024240684055476674,-0.024240684055476674,-0.038785094488762675,-0.011783665860301345,-0.011783665860301345,-0.011783665860301345,-0.011783665860301345,-0.018853865376482152,-0.018853865376482152,-0.018853865376482152,-0.018853865376482152,-0.030166184602371443,-0.018517189209044892,-0.018517189209044892,-0.018517189209044892,-0.018517189209044892,-0.029627502734471827,-0.029627502734471827,-0.029627502734471827,-0.029627502734471827,-0.04740400437515492,-0.015150427534672776,-0.015150427534672776,-0.015150427534672776,-0.015150427534672776,-0.02424068405547644,-0.02424068405547644,-0.02424068405547644,-0.02424068405547644,-0.03878509448876231,-0.011783665860301277,-0.011783665860301277,-0.011783665860301277,-0.011783665860301277,-0.01885386537648204,-0.01885386537648204,-0.01885386537648204,-0.01885386537648204,-0.030166184602371266]),1e-14)) + f=MEDCouplingFieldDouble(ft) + arr=DataArrayDouble(126,2) + arr[:,0]=range(126) + arr[:,1]=range(126) + arr[:,1]+=1000 + f.setArray(arr) + f.checkCoherency() + self.assertTrue(DataArrayDouble(f.integral(False)).isEqual(DataArrayDouble([-211.66121638700983,-4863.9563007698835]),1e-11)) + self.assertTrue(DataArrayDouble(f.getWeightedAverageValue()).isEqual(DataArrayDouble([45.4960858131136,1045.496085813114]),1e-11)) + self.assertTrue(DataArrayDouble(f.normL1()).isEqual(DataArrayDouble([45.49608581311362,1045.496085813114]),1e-11)) + self.assertTrue(DataArrayDouble(f.normL2()).isEqual(DataArrayDouble([58.16846378340898,1046.1241521947334]),1e-11)) + pass + + def testSwig2FieldDiscretizationComputeMeshRestrictionFromTupleIds1(self): + m=MEDCouplingDataForTest.build3DSurfTargetMesh_1() + f=MEDCouplingFieldDouble(ON_GAUSS_NE) + f.setMesh(m) + a,b=f.getDiscretization().computeMeshRestrictionFromTupleIds(f.getMesh(),[3,4,5,6,8,9,10,14,15,16,17]) + self.assertTrue(a.isEqual(DataArrayInt([1,4]))) + self.assertTrue(b.isEqual(DataArrayInt([4,5,6,14,15,16,17]))) + a,b=f.getDiscretization().computeMeshRestrictionFromTupleIds(f.getMesh(),DataArrayInt([0,1,2,3,5,7,8,9,10,11,12,18])) + self.assertTrue(a.isEqual(DataArrayInt([0,2]))) + self.assertTrue(b.isEqual(DataArrayInt([0,1,2,3,7,8,9]))) + # + f=MEDCouplingFieldDouble(ON_CELLS) + f.setMesh(m) + a,b=f.getDiscretization().computeMeshRestrictionFromTupleIds(f.getMesh(),[3,4]) + self.assertTrue(a.isEqual(DataArrayInt([3,4]))) + self.assertTrue(b.isEqual(DataArrayInt([3,4]))) + # + f=MEDCouplingFieldDouble(ON_NODES) + f.setMesh(m) + a,b=f.getDiscretization().computeMeshRestrictionFromTupleIds(f.getMesh(),[1,2,3,4]) + self.assertTrue(a.isEqual(DataArrayInt([1]))) + self.assertTrue(b.isEqual(DataArrayInt([1,2,4]))) + # + f=MEDCouplingDataForTest.buildFieldOnGauss_1() + a,b=f.getDiscretization().computeMeshRestrictionFromTupleIds(f.getMesh(),[0,11,12,13,14,15,17,18,19,36,37,38,115,117,118,119,120,121,122,123,124,125]) + self.assertTrue(a.isEqual(DataArrayInt([0,11,12,18,35]))) + self.assertTrue(b.isEqual(DataArrayInt([0,11,12,13,14,15,36,37,38,117,118,119,120,121,122,123,124,125]))) + # + d=DataArrayInt([0,3,7,9,15,18]) + e=DataArrayInt([0,1,2,3,7,8,15,16,17]) + a,b=d.searchRangesInListOfIds(e) + self.assertTrue(a.isEqual(DataArrayInt([0,2,4]))) + self.assertTrue(b.isEqual(DataArrayInt([0,1,2,7,8,15,16,17]))) + pass + + def testSwig2BigMem(self): + if MEDCouplingSizeOfVoidStar()==64: + d=DataArrayAsciiChar(223456789,16) + self.assertTrue(d.getNumberOfTuples(),223456789) + self.assertTrue(d.getNumberOfComponents(),16) + d.setIJ(223456788,5,"r") + self.assertTrue(d.getIJ(223456788,5),'r') + d[223456787]="1234567890123456" + self.assertTrue(d[223456787],'1234567890123456') + self.assertRaises(InterpKernelException,d.rearrange,1)# fails because it would lead to nb of tuples > 2147483647 + pass + pass + + def testSwig2DAReverseMultiCompo1(self): + d=DataArrayDouble(6,2) + d[:,0]=range(6) + d[:,1]=range(10,16) + d.reverse() + self.assertTrue(d.isEqual(DataArrayDouble([5.,15.,4.,14.,3.,13.,2.,12.,1.,11.,0.,10.],6,2),1e-14)) + d=DataArrayDouble(7,2) + d[:,0]=range(7) + d[:,1]=range(10,17) + d.reverse() + self.assertTrue(d.isEqual(DataArrayDouble([6.,16.,5.,15.,4.,14.,3.,13.,2.,12.,1.,11.,0.,10.],7,2),1e-14)) + # + d=DataArrayInt(6,2) + d[:,0]=range(6) + d[:,1]=range(10,16) + d.reverse() + self.assertTrue(d.isEqual(DataArrayInt([5,15,4,14,3,13,2,12,1,11,0,10],6,2))) + d=DataArrayInt(7,2) + d[:,0]=range(7) + d[:,1]=range(10,17) + d.reverse() + self.assertTrue(d.isEqual(DataArrayInt([6,16,5,15,4,14,3,13,2,12,1,11,0,10],7,2))) + pass + + def testSwigDAPow1(self): + d=DataArrayInt(10) + d.iota(0) + d1=d.deepCpy() + d.setIJ(2,0,-2) + self.assertTrue((d**2).isEqual(DataArrayInt([0,1,4,9,16,25,36,49,64,81]))) + self.assertTrue((d**3).isEqual(DataArrayInt([0,1,-8,27,64,125,216,343,512,729]))) + for elt in [d]: + elt**=2 + pass + self.assertTrue(d.isEqual(DataArrayInt([0,1,4,9,16,25,36,49,64,81]))) + self.assertTrue((d1[:4]**d1[:4]).isEqual(DataArrayInt([1,1,4,27]))) + self.assertTrue((3**d1[:4]).isEqual(DataArrayInt([1,3,9,27]))) + d2=d1[:4] + d2**=d2 + self.assertTrue(d2.isEqual(DataArrayInt([1,1,4,27]))) + self.assertRaises(InterpKernelException,d2.__pow__,-1)#non supporting negative pow in DataArrayInt.__pow__ + self.assertRaises(InterpKernelException,d2.__ipow__,-1)#non supporting negative pow in DataArrayInt.__pow__ + # + d=DataArrayDouble(10) + d.iota(0) + d1=d.deepCpy() + d.setIJ(2,0,-2.) + self.assertTrue((d**2).isEqual(DataArrayDouble([0,1,4,9,16,25,36,49,64,81]),1e-12)) + self.assertTrue((d**3).isEqual(DataArrayDouble([0,1,-8,27,64,125,216,343,512,729]),1e-12)) + self.assertRaises(InterpKernelException,d.__pow__,3.1)#3.1 is double not integer -> not supporting negative values in d + for elt in [d]: + elt**=2 + pass + self.assertTrue(d.isEqual(DataArrayDouble([0,1,4,9,16,25,36,49,64,81]),1e-12)) + self.assertTrue((d1[:4]**d1[:4]).isEqual(DataArrayDouble([1,1,4,27]),1e-12)) + self.assertTrue((3**d1[:4]).isEqual(DataArrayDouble([1,3,9,27]),1e-12)) + d2=d1[:4] + d2**=d2 + self.assertTrue(d2.isEqual(DataArrayDouble([1,1,4,27]),1e-12)) + d2**=-0.5 + self.assertTrue(d2.isEqual(DataArrayDouble([1,1,1./2,1./sqrt(27.)]),1e-14)) + d3=-1./d1[1:5] + self.assertTrue((3**d3).isEqual(DataArrayDouble([0.3333333333333333,0.5773502691896257,0.6933612743506348,0.7598356856515925]),1e-14)) + d4=d3.deepCpy() ; d4.abs() + self.assertTrue((d4**d3).isEqual(DataArrayDouble([1.,sqrt(2.),1.4422495703074083,sqrt(2.)]),1e-14)) + d4**=d3 + self.assertTrue(d4.isEqual(DataArrayDouble([1.,sqrt(2.),1.4422495703074083,sqrt(2.)]),1e-14)) + pass + + def testSwig2Baryenter3DForCellsWithVolumeZero1(self): + coo=DataArrayDouble([0.,0.,0.,1.,0.,0.,0.,1.,0.],3,3) + m2=MEDCouplingUMesh("mesh",2) + m2.allocateCells(0) + m2.insertNextCell(NORM_POLYGON,[0,1,2]) + m2.setCoords(coo) + m2.checkCoherency1() + # + coo2=DataArrayDouble([0.,0.,0.,0.,0.,0.,0.,0.,2.],3,3) + m1=MEDCouplingUMesh("mesh",1) + m1.allocateCells(0) + m1.insertNextCell(NORM_SEG2,[0,1]) + m1.insertNextCell(NORM_SEG2,[1,2]) + m1.setCoords(coo2) + m1.checkCoherency1() + # + m3=m2.buildExtrudedMesh(m1,0) + m3.insertNextCell(NORM_POLYHED,[3,4,5,-1,8,7,6,-1,4,3,6,7,-1,5,4,7,8,-1,5,4,-1,3,5,8,6])# addition of face #4 with null surface + self.assertTrue(m3.getBarycenterAndOwner().isEqual(DataArrayDouble([0.3333333333333333,0.3333333333333333,0.,0.3333333333333333,0.3333333333333333,1.,0.3333333333333333,0.3333333333333333,1.],3,3),1e-13)) + m4,a,b,c,d=m3.buildDescendingConnectivity() + self.assertTrue(m4.getBarycenterAndOwner().isEqual(DataArrayDouble([0.3333333333333333,0.3333333333333333,0.,0.3333333333333333,0.3333333333333333,0.,0.5,0.,0.,0.5,0.5,0.,0.,0.5,0.,0.3333333333333333,0.3333333333333333,2.,0.5,0.,1.,0.5,0.5,1.,0.,0.5,1.,0.5,0.5,0.],10,3),1e-13)) + pass + + def testSwigRepr1(self): + d=DataArrayDouble() + self.assertTrue(len(d.__repr__())<120) + d.alloc(1000,0) ; self.assertTrue(len(d.__repr__())<100) + for i in xrange(100): + d.alloc(i,1) ; d.iota(1.1234567890123456) ; d*=1e123 + self.assertTrue(len(d.__repr__())<500) + pass + for i in xrange(50): + d.alloc(i,2) ; d.rearrange(1) ; d.iota(1.1234567890123456) ; d.rearrange(2) ; d*=1e123 + self.assertTrue(len(d.__repr__())<500) + pass + d.alloc(4000,1) ; d.iota() ; self.assertTrue(len(d.__repr__())<500) + for i in xrange(2,4): + d.alloc(362880,1) ; d.iota() ; d.rearrange(i) ; self.assertTrue(len(d.__repr__())<500) + pass + d.alloc(0,9) + self.assertTrue(len(d.__repr__())<120) + # + d=DataArrayInt() + self.assertTrue(len(d.__repr__())<100) + d.alloc(1000,0) ; self.assertTrue(len(d.__repr__())<100) + for i in xrange(100): + d.alloc(i,1) ; d.iota(123456789) + self.assertTrue(len(d.__repr__())<500) + pass + for i in xrange(50): + d.alloc(i,2) ; d.rearrange(1) ; d.iota(123456789) ; d.rearrange(2) + self.assertTrue(len(d.__repr__())<500) + pass + d.alloc(4000,1) ; d.iota() ; self.assertTrue(len(d.__repr__())<500) + for i in xrange(2,10): + d.alloc(362880,1) ; d.iota() ; d.rearrange(i) ; self.assertTrue(len(d.__repr__())<500) + pass + d.alloc(0,9) + self.assertTrue(len(d.__repr__())<100) + # + d=DataArrayAsciiChar() + d.alloc(1000,0) ; self.assertTrue(len(d.__repr__())<100) + d.alloc(2,16) ; d[:]='1234567890ABCDEF' + self.assertTrue(len(d.__repr__())<500) + d.alloc(2000,16) ; d[:]='1234567890ABCDEF' + self.assertTrue(len(d.__repr__())<500) + d.alloc(0,16) ; d[:]='1234567890ABCDEF' + self.assertTrue(len(d.__repr__())<120) + # + d=DataArrayByte() + self.assertTrue(len(d.__repr__())<100) + d.alloc(1000,0) ; self.assertTrue(len(d.__repr__())<100) + d.alloc(0,16) ; self.assertTrue(len(d.__repr__())<100) + d.alloc(5,1) ; d.fillWithValue(127) + self.assertTrue(len(d.__repr__())<200) + d.alloc(1000,1) ; d.fillWithValue(127) + self.assertTrue(len(d.__repr__())<500) + d.alloc(1000,3) ; d.fillWithValue(127) + self.assertTrue(len(d.__repr__())<500) + pass + + def testSwig2MeshComputeIsoBarycenterOfNodesPerCell1(self): + coo=DataArrayDouble([26.17509821414239,5.0374,200.,26.175098214142388,-5.0374,200.,17.450065476094927,20.1496,200.,8.725032738047464,25.187,200.,43.62516369023732,5.0374,200.,34.90013095218986,10.0748,200.,34.900130952189855,-10.0748,200.,43.625163690237315,-5.0374,200.,26.175098214142402,25.187,200.,26.175098214142395,35.2618,200.,17.45006547609493,40.2992,200.,8.725032738047469,35.2618,200.,26.17509821414239,5.0374,200.,26.175098214142388,-5.0374,200.,17.450065476094927,20.1496,200.,8.725032738047464,25.187,200.,43.62516369023732,5.0374,200.,34.90013095218986,10.0748,200.,34.900130952189855,-10.0748,200.,43.625163690237315,-5.0374,200.,26.175098214142402,25.187,200.,26.175098214142395,35.2618,200.,17.45006547609493,40.2992,200.,8.725032738047469,35.2618,200.],24,3) + m=MEDCouplingUMesh.New("toto",3) + m.allocateCells(0) + m.insertNextCell(NORM_POLYHED,[4,5,0,1,6,7,-1,19,18,13,12,17,16,-1,5,4,16,17,-1,0,5,17,12,-1,1,0,12,13,-1,6,1,13,18,-1,7,6,18,19,-1,4,7,19,16]) + m.insertNextCell(NORM_POLYHED,[9,10,11,3,2,8,-1,20,14,15,23,22,21,-1,10,9,21,22,-1,11,10,22,23,-1,3,11,23,15,-1,2,3,15,14,-1,8,2,14,20,-1,9,8,20,21]) + m.setCoords(coo) + m.checkCoherency1() + # + dReference=DataArrayDouble([(34.900130952189848,0.,200),(17.450065476094931,30.2244,200.)]) + self.assertTrue(m.computeIsoBarycenterOfNodesPerCell().isEqual(dReference,1e-12)) + m.getNodalConnectivity().setIJ(87,0,24) + self.assertRaises(InterpKernelException,m.computeIsoBarycenterOfNodesPerCell) + m.getNodalConnectivity().setIJ(87,0,-2) + self.assertRaises(InterpKernelException,m.computeIsoBarycenterOfNodesPerCell) + m.getNodalConnectivity().setIJ(87,0,21)# put again 21 as at the beginning + # + self.assertTrue(m.unPolyze()) + self.assertEqual([NORM_HEXGP12],m.getAllGeoTypes()) + self.assertTrue(m.computeIsoBarycenterOfNodesPerCell().isEqual(dReference,1e-12)) + m.getNodalConnectivity().setIJ(25,0,24) + self.assertRaises(InterpKernelException,m.computeIsoBarycenterOfNodesPerCell) + m.getNodalConnectivity().setIJ(25,0,-1) + self.assertRaises(InterpKernelException,m.computeIsoBarycenterOfNodesPerCell) + pass + + def testSwig2NonRegressionBugDescHexa20(self): + coo=DataArrayDouble([0.,0.,0.,1.23,0.,0.,0.615,0.,0.,0.,2.1,0.,0.615,2.1,0.,1.23,2.1,0.,1.23,1.05,0.,0.,1.05,0.,0.,0.,2.16,1.23,0.,2.16,1.23,2.1,2.16,0.,2.1,2.16,0.,0.,4.32,0.615,0.,4.32,1.23,0.,4.32,1.23,1.05,4.32,1.23,2.1,4.32,0.615,2.1,4.32,0.,2.1,4.32,0.,1.05,4.32],20,3) + m=MEDCouplingUMesh('mesh',3) + m.allocateCells(0) + m.insertNextCell(NORM_HEXA20,[0,3,5,1,12,18,16,14,7,4,6,2,19,17,15,13,8,11,10,9]) + m.setCoords(coo) + m.checkCoherency1() + # + a,b,c,d,e=m.buildDescendingConnectivity() + m2=MEDCouplingUMesh('mesh',2) + m2.allocateCells(0) + m2.setCoords(coo) + conn2=[[0,3,5,1,7,4,6,2],[12,14,16,18,13,15,17,19],[0,12,18,3,8,19,11,7],[3,18,16,5,11,17,10,4],[5,16,14,1,10,15,9,6],[1,14,12,0,9,13,8,2]] + for i in xrange(6): + m2.insertNextCell(NORM_QUAD8,conn2[i]) + pass + self.assertTrue(m2.isEqual(a,1e-12)) + self.assertTrue(b.isEqual(DataArrayInt([0,1,2,3,4,5]))) + self.assertTrue(c.isEqual(DataArrayInt([0,6]))) + self.assertTrue(d.isEqual(DataArrayInt([0,0,0,0,0,0]))) + self.assertTrue(e.isEqual(DataArrayInt([0,1,2,3,4,5,6]))) + # + m.convertQuadraticCellsToLinear() ; m.zipCoords() + m.convertLinearCellsToQuadratic(1) + # + coo2=DataArrayDouble([0.,0.,0.,1.23,0.,0.,0.,2.1,0.,1.23,2.1,0.,0.,0.,4.32,1.23,0.,4.32,1.23,2.1,4.32,0.,2.1,4.32,0.,1.05,0.,0.615,2.1,0.,1.23,1.05,0.,0.615,0.,0.,0.,1.05,4.32,0.615,2.1,4.32,1.23,1.05,4.32,0.615,0.,4.32,0.,0.,2.16,0.,2.1,2.16,1.23,2.1,2.16,1.23,0.,2.16,0.615,1.05,0.,0.,1.05,2.16,0.615,2.1,2.16,1.23,1.05,2.16,0.615,0.,2.16,0.615,1.05,4.32,0.615,1.05,2.16],27,3) + m3=MEDCouplingUMesh("mesh",3) + m3.allocateCells(1) + m3.insertNextCell(NORM_HEXA27,[0,2,3,1,4,7,6,5,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26]) + m3.setCoords(coo2) + self.assertTrue(m3.isEqual(m,1e-12)) + # + a,b,c,d,e=m.buildDescendingConnectivity() + conn4=[[0,2,3,1,8,9,10,11,20],[4,5,6,7,15,14,13,12,25],[0,4,7,2,16,12,17,8,21],[2,7,6,3,17,13,18,9,22],[3,6,5,1,18,14,19,10,23],[1,5,4,0,19,15,16,11,24]] + m4=MEDCouplingUMesh("mesh",2) + m4.allocateCells(0) + for i in xrange(6): + m4.insertNextCell(NORM_QUAD9,conn4[i]) + pass + m4.setCoords(coo2) + self.assertTrue(m4.isEqual(a,1e-12)) + self.assertTrue(b.isEqual(DataArrayInt([0,1,2,3,4,5]))) + self.assertTrue(c.isEqual(DataArrayInt([0,6]))) + self.assertTrue(d.isEqual(DataArrayInt([0,0,0,0,0,0]))) + self.assertTrue(e.isEqual(DataArrayInt([0,1,2,3,4,5,6]))) + pass + + def testSwigAdvGauss(self): + f=MEDCouplingFieldTemplate(ON_GAUSS_PT) + f.setDiscretization(None) + f.__repr__() ; f.__str__() + # + f=MEDCouplingFieldTemplate(ON_GAUSS_PT) + d=f.getDiscretization() + i=DataArrayInt() ; i.alloc(10,1) ; i.iota(1) + d.setArrayOfDiscIds(i) + f.__repr__() ; f.__str__() + i2=d.getArrayOfDiscIds() + self.assertEqual(i.__repr__(),i2.__repr__()) + # + f=MEDCouplingFieldDouble(ON_GAUSS_PT) + f.setDiscretization(None) + f.__repr__() ; f.__str__() + # + f=MEDCouplingFieldDouble(ON_GAUSS_PT) + d=f.getDiscretization() + i=DataArrayInt() ; i.alloc(10,1) ; i.iota(1) + d.setArrayOfDiscIds(i) + f.__repr__() ; f.__str__() + # + gl=MEDCouplingGaussLocalization(NORM_SEG2,[0,1],[0.5],[1.]) + gl.setWeights([3.]) + gl.__repr__() ; gl.__str__() + gl=MEDCouplingGaussLocalization(NORM_ERROR) + gl.setWeights([3.]) + gl.__repr__() ; gl.__str__() + pass + + def testSwig2NonRegressionBugSubstractInPlaceDM(self): + m0=MEDCouplingCMesh() + arr=DataArrayDouble(5,1) ; arr.iota(0.) + m0.setCoords(arr,arr) + m0=m0.buildUnstructured() + m00=m0[::2] ; m00.simplexize(0) ; m01=m0[1::2] + m0=MEDCouplingUMesh.MergeUMeshes([m00,m01]) + m0.getCoords()[:]*=1/4. + m0.setName("mesh") + # + NodeField=MEDCouplingFieldDouble(ON_NODES,ONE_TIME) ; NodeField.setTime(5.6,5,6) ; NodeField.setMesh(m0) + NodeField.setName("NodeField") + NodeField.fillFromAnalytic(1,"exp(-((x-1)*(x-1)+(y-1)*(y-1)))") ; NodeField.getArray().setInfoOnComponent(0,"powernode [W]") + proc0=m0.getCellsInBoundingBox([(0.,0.4),(0.,0.4)],1e-10) + proc1=proc0.buildComplement(m0.getNumberOfCells()) + # + NodeField0=NodeField[proc0] ; NodeField0.getMesh().setName(m0.getName()) + NodeField1=NodeField[proc1] ; NodeField1.getMesh().setName(m0.getName()) + # + NodeField_read=MEDCouplingFieldDouble.MergeFields([NodeField0,NodeField1]) + NodeField_read.mergeNodes(1e-10) + NodeFieldCpy=NodeField.deepCpy() + NodeFieldCpy.mergeNodes(1e-10) + NodeField.checkCoherency() + self.assertTrue(not NodeField.getArray().isUniform(0.,1e-12)) + NodeField.substractInPlaceDM(NodeField_read,10,1e-12) + self.assertTrue(NodeField.getArray().isUniform(0.,1e-12)) + pass + + def testSwigFieldOperationOpen1(self): + ## MEDCouplingFieldDouble.__add__ + m=MEDCouplingDataForTest.build2DTargetMesh_1() + f=MEDCouplingFieldDouble(ON_CELLS) + f.setMesh(m) + arr=DataArrayDouble(5,2) + arr[:,0]=range(5) ; arr[:,1]=2*arr[:,0] + f2=f.clone(True) + self.assertRaises(InterpKernelException,f.__add__,2) + self.assertRaises(InterpKernelException,f.__add__,range(5)) + self.assertRaises(InterpKernelException,f.__add__,arr) + self.assertRaises(InterpKernelException,f.__add__,f2) + f.setArray(DataArrayDouble()) + self.assertRaises(InterpKernelException,f.__add__,2) + self.assertRaises(InterpKernelException,f.__add__,range(5)) + self.assertRaises(InterpKernelException,f.__add__,arr) + self.assertRaises(InterpKernelException,f.__add__,f2) + self.assertRaises(InterpKernelException,f.__getitem__,(slice(None),0)) + f.getArray().alloc(5,2) + f.getArray()[:,0]=range(5) ; f.getArray()[:,1]=f.getArray()[:,0]+7 + ff=f+2 + ff.checkCoherency() + self.assertTrue(ff.getArray().isEqual(DataArrayDouble([(2,9),(3,10),(4,11),(5,12),(6,13)]),1e-12)) + ff=f+arr + ff.checkCoherency() + self.assertTrue(ff.getArray().isEqual(DataArrayDouble([(0,7),(2,10),(4,13),(6,16),(8,19)]),1e-12)) + self.assertRaises(InterpKernelException,f.__add__,f2) + f2.setArray(arr) + ff=f+f2 + ff.checkCoherency() + self.assertTrue(ff.getArray().isEqual(DataArrayDouble([(0,7),(2,10),(4,13),(6,16),(8,19)]),1e-12)) + ff=f+[5,8] + self.assertTrue(ff.getArray().isEqual(DataArrayDouble([(5,15),(6,16),(7,17),(8,18),(9,19)]),1e-12)) + ### MEDCouplingFieldDouble.__sub__ + m=MEDCouplingDataForTest.build2DTargetMesh_1() + f=MEDCouplingFieldDouble(ON_CELLS) + f.setMesh(m) + arr=DataArrayDouble(5,2) + arr[:,0]=range(5) ; arr[:,1]=2*arr[:,0] + f2=f.clone(True) + self.assertRaises(InterpKernelException,f.__sub__,2) + self.assertRaises(InterpKernelException,f.__sub__,range(5)) + self.assertRaises(InterpKernelException,f.__sub__,arr) + self.assertRaises(InterpKernelException,f.__sub__,f2) + f.setArray(DataArrayDouble()) + self.assertRaises(InterpKernelException,f.__sub__,2) + self.assertRaises(InterpKernelException,f.__sub__,range(5)) + self.assertRaises(InterpKernelException,f.__sub__,arr) + self.assertRaises(InterpKernelException,f.__sub__,f2) + self.assertRaises(InterpKernelException,f.__getitem__,(slice(None),0)) + f.getArray().alloc(5,2) + f.getArray()[:,0]=range(5) ; f.getArray()[:,1]=f.getArray()[:,0]+7 + ff=f-2 + ff.checkCoherency() + self.assertTrue(ff.getArray().isEqual(DataArrayDouble([(-2,5),(-1,6),(0,7),(1,8),(2,9)]),1e-12)) + ff=f-arr + ff.checkCoherency() + self.assertTrue(ff.getArray().isEqual(DataArrayDouble([(0,7),(0,6),(0,5),(0,4),(0,3)]),1e-12)) + self.assertRaises(InterpKernelException,f.__sub__,f2) + f2.setArray(arr) + ff=f-f2 + ff.checkCoherency() + self.assertTrue(ff.getArray().isEqual(DataArrayDouble([(0,7),(0,6),(0,5),(0,4),(0,3)]),1e-12)) + ff=f-[5,8] + self.assertTrue(ff.getArray().isEqual(DataArrayDouble([(-5,-1),(-4,0),(-3,1),(-2,2),(-1,3)]),1e-12)) + ### MEDCouplingFieldDouble.__mul__ + m=MEDCouplingDataForTest.build2DTargetMesh_1() + f=MEDCouplingFieldDouble(ON_CELLS) + f.setMesh(m) + arr=DataArrayDouble(5,2) + arr[:,0]=range(5) ; arr[:,1]=2*arr[:,0] + f2=f.clone(True) + self.assertRaises(InterpKernelException,f.__mul__,2) + self.assertRaises(InterpKernelException,f.__mul__,range(5)) + self.assertRaises(InterpKernelException,f.__mul__,arr) + self.assertRaises(InterpKernelException,f.__mul__,f2) + f.setArray(DataArrayDouble()) + self.assertRaises(InterpKernelException,f.__mul__,2) + self.assertRaises(InterpKernelException,f.__mul__,range(5)) + self.assertRaises(InterpKernelException,f.__mul__,arr) + self.assertRaises(InterpKernelException,f.__mul__,f2) + self.assertRaises(InterpKernelException,f.__getitem__,(slice(None),0)) + f.getArray().alloc(5,2) + f.getArray()[:,0]=range(5) ; f.getArray()[:,1]=f.getArray()[:,0]+7 + ff=f*2 + ff.checkCoherency() + self.assertTrue(ff.getArray().isEqual(DataArrayDouble([(0,14),(2,16),(4,18),(6,20),(8,22)]),1e-12)) + ff=f*arr + ff.checkCoherency() + self.assertTrue(ff.getArray().isEqual(DataArrayDouble([(0,0),(1,16),(4,36),(9,60),(16,88)]),1e-12)) + self.assertRaises(InterpKernelException,f.__mul__,f2) + f2.setArray(arr) + ff=f*f2 + ff.checkCoherency() + self.assertTrue(ff.getArray().isEqual(DataArrayDouble([(0,0),(1,16),(4,36),(9,60),(16,88)]),1e-12)) + ff=f*[5,8] + self.assertTrue(ff.getArray().isEqual(DataArrayDouble([(0,56),(5,64),(10,72),(15,80),(20,88)]),1e-12)) + ### MEDCouplingFieldDouble.__div__ + m=MEDCouplingDataForTest.build2DTargetMesh_1() + f=MEDCouplingFieldDouble(ON_CELLS) + f.setMesh(m) + arr=DataArrayDouble(5,2) + arr[:,0]=range(1,6) ; arr[:,1]=2*arr[:,0] + f2=f.clone(True) + self.assertRaises(InterpKernelException,f.__div__,2) + self.assertRaises(InterpKernelException,f.__div__,range(5)) + self.assertRaises(InterpKernelException,f.__div__,arr) + self.assertRaises(InterpKernelException,f.__div__,f2) + f.setArray(DataArrayDouble()) + self.assertRaises(InterpKernelException,f.__div__,2) + self.assertRaises(InterpKernelException,f.__div__,range(5)) + self.assertRaises(InterpKernelException,f.__div__,arr) + self.assertRaises(InterpKernelException,f.__div__,f2) + self.assertRaises(InterpKernelException,f.__getitem__,(slice(None),0)) + f.getArray().alloc(5,2) + f.getArray()[:,0]=range(5) ; f.getArray()[:,1]=f.getArray()[:,0]+7 + self.assertRaises(InterpKernelException,f.__div__,0) + ff=f/2 + ff.checkCoherency() + self.assertTrue(ff.getArray().isEqual(DataArrayDouble([(0,3.5),(0.5,4),(1,4.5),(1.5,5),(2,5.5)]),1e-12)) + ff=f/arr + ff.checkCoherency() + self.assertTrue(ff.getArray().isEqual(DataArrayDouble([(0,3.5),(0.5,2),(0.6666666666666666,1.5),(0.75,1.25),(0.8,1.1)]),1e-12)) + self.assertRaises(InterpKernelException,f.__div__,f2) + f2.setArray(arr) + ff=f/f2 + ff.checkCoherency() + self.assertTrue(ff.getArray().isEqual(DataArrayDouble([(0,3.5),(0.5,2),(0.6666666666666666,1.5),(0.75,1.25),(0.8,1.1)]),1e-12)) + ff=f/[5,8] + self.assertTrue(ff.getArray().isEqual(DataArrayDouble([(0,0.875),(0.2,1),(0.4,1.125),(0.6,1.25),(0.8,1.375)]),1e-12)) + ### MEDCouplingFieldDouble.__pow__ + m=MEDCouplingDataForTest.build2DTargetMesh_1() + f=MEDCouplingFieldDouble(ON_CELLS) + f.setMesh(m) + arr=DataArrayDouble(5) + arr[:]=[1,1,3,2,0] + f2=f.clone(True) + self.assertRaises(InterpKernelException,f.__div__,2) + self.assertRaises(InterpKernelException,f.__div__,range(5)) + self.assertRaises(InterpKernelException,f.__div__,arr) + self.assertRaises(InterpKernelException,f.__div__,f2) + f.setArray(DataArrayDouble()) + self.assertRaises(InterpKernelException,f.__div__,2) + self.assertRaises(InterpKernelException,f.__div__,range(5)) + self.assertRaises(InterpKernelException,f.__div__,arr) + self.assertRaises(InterpKernelException,f.__div__,f2) + self.assertRaises(InterpKernelException,f.__getitem__,(slice(None),0)) + f.getArray().alloc(5,1) + f.getArray()[:]=range(2,7) + ff=f**2 + ff.checkCoherency() + self.assertTrue(ff.getArray().isEqual(DataArrayDouble([4,9,16,25,36]),1e-12)) + ff=f**arr + ff.checkCoherency() + self.assertTrue(ff.getArray().isEqual(DataArrayDouble([2,3,64,25,1]),1e-12)) + f2.setArray(arr) + ff=f**f2 + ff.checkCoherency() + self.assertTrue(ff.getArray().isEqual(DataArrayDouble([2,3,64,25,1]),1e-12)) + ## MEDCouplingFieldDouble.__iadd__ + m=MEDCouplingDataForTest.build2DTargetMesh_1() + f=MEDCouplingFieldDouble(ON_CELLS) + f.setMesh(m) + arr=DataArrayDouble(5,2) + arr[:,0]=range(5) ; arr[:,1]=2*arr[:,0] + f2=f.clone(True) + self.assertRaises(InterpKernelException,f.__iadd__,2) + self.assertRaises(InterpKernelException,f.__iadd__,range(5)) + self.assertRaises(InterpKernelException,f.__iadd__,arr) + self.assertRaises(InterpKernelException,f.__iadd__,f2) + f.setArray(DataArrayDouble()) + self.assertRaises(InterpKernelException,f.__iadd__,2) + self.assertRaises(InterpKernelException,f.__iadd__,range(5)) + self.assertRaises(InterpKernelException,f.__iadd__,arr) + self.assertRaises(InterpKernelException,f.__iadd__,f2) + f.getArray().alloc(5,2) + f.getArray()[:,0]=range(5) ; f.getArray()[:,1]=f.getArray()[:,0]+7 + f.checkCoherency() + f+=2 + f.checkCoherency() + self.assertTrue(f.getArray().isEqual(DataArrayDouble([(2,9),(3,10),(4,11),(5,12),(6,13)]),1e-12)) + f+=arr + f.checkCoherency() + self.assertTrue(f.getArray().isEqual(DataArrayDouble([(2,9),(4,12),(6,15),(8,18),(10,21)]),1e-12)) + f2.setArray(arr) + f+=f2 + f.checkCoherency() + self.assertTrue(f.getArray().isEqual(DataArrayDouble([(2,9),(5,14),(8,19),(11,24),(14,29)]),1e-12)) + f+=[0.1,0.2] + f.checkCoherency() + self.assertTrue(f.getArray().isEqual(DataArrayDouble([(2.1,9.2),(5.1,14.2),(8.1,19.2),(11.1,24.2),(14.1,29.2)]),1e-12)) + ## MEDCouplingFieldDouble.__isub__ + m=MEDCouplingDataForTest.build2DTargetMesh_1() + f=MEDCouplingFieldDouble(ON_CELLS) + f.setMesh(m) + arr=DataArrayDouble(5,2) + arr[:,0]=range(5) ; arr[:,1]=2*arr[:,0] + f2=f.clone(True) + self.assertRaises(InterpKernelException,f.__isub__,2) + self.assertRaises(InterpKernelException,f.__isub__,range(5)) + self.assertRaises(InterpKernelException,f.__isub__,arr) + self.assertRaises(InterpKernelException,f.__isub__,f2) + f.setArray(DataArrayDouble()) + self.assertRaises(InterpKernelException,f.__isub__,2) + self.assertRaises(InterpKernelException,f.__isub__,range(5)) + self.assertRaises(InterpKernelException,f.__isub__,arr) + self.assertRaises(InterpKernelException,f.__isub__,f2) + f.getArray().alloc(5,2) + f.getArray()[:,0]=range(5) ; f.getArray()[:,1]=f.getArray()[:,0]+7 + f.checkCoherency() + f-=2 + f.checkCoherency() + self.assertTrue(f.getArray().isEqual(DataArrayDouble([(-2,5),(-1,6),(0,7),(1,8),(2,9)]),1e-12)) + f-=arr + f.checkCoherency() + self.assertTrue(f.getArray().isEqual(DataArrayDouble([(-2,5),(-2,4),(-2,3),(-2,2),(-2,1)]),1e-12)) + f2.setArray(arr) + f-=f2 + f.checkCoherency() + self.assertTrue(f.getArray().isEqual(DataArrayDouble([(-2,5),(-3,2),(-4,-1),(-5,-4),(-6,-7)]),1e-12)) + f-=[0.1,0.2] + f.checkCoherency() + self.assertTrue(f.getArray().isEqual(DataArrayDouble([(-2.1,4.8),(-3.1,1.8),(-4.1,-1.2),(-5.1,-4.2),(-6.1,-7.2)]),1e-12)) + ## MEDCouplingFieldDouble.__imul__ + m=MEDCouplingDataForTest.build2DTargetMesh_1() + f=MEDCouplingFieldDouble(ON_CELLS) + f.setMesh(m) + arr=DataArrayDouble(5,2) + arr[:,0]=range(5) ; arr[:,1]=2*arr[:,0] + f2=f.clone(True) + self.assertRaises(InterpKernelException,f.__imul__,2) + self.assertRaises(InterpKernelException,f.__imul__,range(5)) + self.assertRaises(InterpKernelException,f.__imul__,arr) + self.assertRaises(InterpKernelException,f.__imul__,f2) + f.setArray(DataArrayDouble()) + self.assertRaises(InterpKernelException,f.__imul__,2) + self.assertRaises(InterpKernelException,f.__imul__,range(5)) + self.assertRaises(InterpKernelException,f.__imul__,arr) + self.assertRaises(InterpKernelException,f.__imul__,f2) + f.getArray().alloc(5,2) + f.getArray()[:,0]=range(5) ; f.getArray()[:,1]=f.getArray()[:,0]+7 + f.checkCoherency() + f*=2 + f.checkCoherency() + self.assertTrue(f.getArray().isEqual(DataArrayDouble([(0,14),(2,16),(4,18),(6,20),(8,22)]),1e-12)) + f*=arr + f.checkCoherency() + self.assertTrue(f.getArray().isEqual(DataArrayDouble([(0,0),(2,32),(8,72),(18,120),(32,176)]),1e-12)) + f2.setArray(arr) + f*=f2 + f.checkCoherency() + self.assertTrue(f.getArray().isEqual(DataArrayDouble([(0,0),(2,64),(16,288),(54,720),(128,1408)]),1e-12)) + f*=[0.1,0.2] + f.checkCoherency() + self.assertTrue(f.getArray().isEqual(DataArrayDouble([(0,0),(0.2,12.8),(1.6,57.6),(5.4,144),(12.8,281.6)]),1e-12)) + ## MEDCouplingFieldDouble.__idiv__ + m=MEDCouplingDataForTest.build2DTargetMesh_1() + f=MEDCouplingFieldDouble(ON_CELLS) + f.setMesh(m) + arr=DataArrayDouble(5,2) + arr[:,0]=range(1,6) ; arr[:,1]=2*arr[:,0] + f2=f.clone(True) + self.assertRaises(InterpKernelException,f.__idiv__,2) + self.assertRaises(InterpKernelException,f.__idiv__,range(5)) + self.assertRaises(InterpKernelException,f.__idiv__,arr) + self.assertRaises(InterpKernelException,f.__idiv__,f2) + f.setArray(DataArrayDouble()) + self.assertRaises(InterpKernelException,f.__idiv__,2) + self.assertRaises(InterpKernelException,f.__idiv__,range(5)) + self.assertRaises(InterpKernelException,f.__idiv__,arr) + self.assertRaises(InterpKernelException,f.__idiv__,f2) + f.getArray().alloc(5,2) + f.getArray()[:,0]=range(5) ; f.getArray()[:,1]=f.getArray()[:,0]+7 + f.checkCoherency() + f/=2 + f.checkCoherency() + self.assertTrue(f.getArray().isEqual(DataArrayDouble([(0,3.5),(0.5,4),(1,4.5),(1.5,5),(2,5.5)]),1e-12)) + f/=arr + f.checkCoherency() + self.assertTrue(f.getArray().isEqual(DataArrayDouble([(0,1.75),(0.25,1),(0.3333333333333333,0.75),(0.375,0.625),(0.4,0.55)]),1e-12)) + f2.setArray(arr) + f/=f2 + f.checkCoherency() + self.assertTrue(f.getArray().isEqual(DataArrayDouble([(0,0.875),(0.125,0.25),(0.1111111111111111,0.125),(0.09375,0.078125),(0.08,0.055)]),1e-12)) + f/=[0.1,0.2] + f.checkCoherency() + self.assertTrue(f.getArray().isEqual(DataArrayDouble([(0,4.375),(1.25,1.25),(1.1111111111111111,0.625),(0.9375,0.390625),(0.8,0.275)]),1e-12)) + ## MEDCouplingFieldDouble.__ipow__ + m=MEDCouplingDataForTest.build2DTargetMesh_1() + f=MEDCouplingFieldDouble(ON_CELLS) + f.setMesh(m) + arr=DataArrayDouble(5,2) + arr[:,0]=range(1,6) ; arr[:,1]=2*arr[:,0] + f2=f.clone(True) + self.assertRaises(InterpKernelException,f.__ipow__,2) + self.assertRaises(InterpKernelException,f.__ipow__,range(5)) + self.assertRaises(InterpKernelException,f.__ipow__,arr) + self.assertRaises(InterpKernelException,f.__ipow__,f2) + f.setArray(DataArrayDouble()) + self.assertRaises(InterpKernelException,f.__ipow__,2) + self.assertRaises(InterpKernelException,f.__ipow__,range(5)) + self.assertRaises(InterpKernelException,f.__ipow__,arr) + self.assertRaises(InterpKernelException,f.__ipow__,f2) + f.getArray().alloc(5,2) + f.getArray()[:,0]=range(5) ; f.getArray()[:,1]=f.getArray()[:,0]+7 + f.checkCoherency() + f**=2 + f.checkCoherency() + self.assertTrue(f.getArray().isEqual(DataArrayDouble([(0,49),(1,64),(4,81),(9,100),(16,121)]),1e-12)) + ## MEDCouplingFieldDouble.__radd__ + m=MEDCouplingDataForTest.build2DTargetMesh_1() + f=MEDCouplingFieldDouble(ON_CELLS) + f.setMesh(m) + arr=DataArrayDouble(5,2) + arr[:,0]=range(5) ; arr[:,1]=2*arr[:,0] + f2=f.clone(True) + self.assertRaises(InterpKernelException,f.__radd__,2) + self.assertRaises(InterpKernelException,f.__radd__,range(5)) + self.assertRaises(InterpKernelException,f.__radd__,arr) + self.assertRaises(InterpKernelException,f.__radd__,f2) + f.setArray(DataArrayDouble()) + self.assertRaises(InterpKernelException,f.__radd__,2) + self.assertRaises(InterpKernelException,f.__radd__,range(5)) + self.assertRaises(InterpKernelException,f.__radd__,arr) + self.assertRaises(InterpKernelException,f.__radd__,f2) + self.assertRaises(InterpKernelException,f.__getitem__,(slice(None),0)) + f.getArray().alloc(5,2) + f.getArray()[:,0]=range(5) ; f.getArray()[:,1]=f.getArray()[:,0]+7 + ff=2+f + ff.checkCoherency() + self.assertTrue(ff.getArray().isEqual(DataArrayDouble([(2,9),(3,10),(4,11),(5,12),(6,13)]),1e-12)) + ff=arr+f + ff.checkCoherency() + self.assertTrue(ff.getArray().isEqual(DataArrayDouble([(0,7),(2,10),(4,13),(6,16),(8,19)]),1e-12)) + self.assertRaises(InterpKernelException,f.__radd__,f2) + ff=[5,8]+f + self.assertTrue(ff.getArray().isEqual(DataArrayDouble([(5,15),(6,16),(7,17),(8,18),(9,19)]),1e-12)) + ### MEDCouplingFieldDouble.__rsub__ + m=MEDCouplingDataForTest.build2DTargetMesh_1() + f=MEDCouplingFieldDouble(ON_CELLS) + f.setMesh(m) + arr=DataArrayDouble(5,2) + arr[:,0]=range(5) ; arr[:,1]=2*arr[:,0] + f2=f.clone(True) + self.assertRaises(InterpKernelException,f.__rsub__,2) + self.assertRaises(InterpKernelException,f.__rsub__,range(5)) + self.assertRaises(InterpKernelException,f.__rsub__,arr) + self.assertRaises(InterpKernelException,f.__rsub__,f2) + f.setArray(DataArrayDouble()) + self.assertRaises(InterpKernelException,f.__rsub__,2) + self.assertRaises(InterpKernelException,f.__rsub__,range(5)) + self.assertRaises(InterpKernelException,f.__rsub__,arr) + self.assertRaises(InterpKernelException,f.__rsub__,f2) + self.assertRaises(InterpKernelException,f.__getitem__,(slice(None),0)) + f.getArray().alloc(5,2) + f.getArray()[:,0]=range(5) ; f.getArray()[:,1]=f.getArray()[:,0]+7 + ff=2-f + ff.checkCoherency() + self.assertTrue(ff.getArray().isEqual(DataArrayDouble([(2,-5),(1,-6),(0,-7),(-1,-8),(-2,-9)]),1e-12)) + ff=arr-f + ff.checkCoherency() + self.assertTrue(ff.getArray().isEqual(DataArrayDouble([(0,-7),(0,-6),(0,-5),(0,-4),(0,-3)]),1e-12)) + self.assertRaises(InterpKernelException,f.__rsub__,f2) + ### MEDCouplingFieldDouble.__rmul__ + m=MEDCouplingDataForTest.build2DTargetMesh_1() + f=MEDCouplingFieldDouble(ON_CELLS) + f.setMesh(m) + arr=DataArrayDouble(5,2) + arr[:,0]=range(5) ; arr[:,1]=2*arr[:,0] + f2=f.clone(True) + self.assertRaises(InterpKernelException,f.__rmul__,2) + self.assertRaises(InterpKernelException,f.__rmul__,range(5)) + self.assertRaises(InterpKernelException,f.__rmul__,arr) + self.assertRaises(InterpKernelException,f.__rmul__,f2) + f.setArray(DataArrayDouble()) + self.assertRaises(InterpKernelException,f.__rmul__,2) + self.assertRaises(InterpKernelException,f.__rmul__,range(5)) + self.assertRaises(InterpKernelException,f.__rmul__,arr) + self.assertRaises(InterpKernelException,f.__rmul__,f2) + self.assertRaises(InterpKernelException,f.__getitem__,(slice(None),0)) + f.getArray().alloc(5,2) + f.getArray()[:,0]=range(5) ; f.getArray()[:,1]=f.getArray()[:,0]+7 + ff=2*f + ff.checkCoherency() + self.assertTrue(ff.getArray().isEqual(DataArrayDouble([(0,14),(2,16),(4,18),(6,20),(8,22)]),1e-12)) + ff=arr*f + ff.checkCoherency() + self.assertTrue(ff.getArray().isEqual(DataArrayDouble([(0,0),(1,16),(4,36),(9,60),(16,88)]),1e-12)) + self.assertRaises(InterpKernelException,f.__rmul__,f2) + ff=f*[5,8] + self.assertTrue(ff.getArray().isEqual(DataArrayDouble([(0,56),(5,64),(10,72),(15,80),(20,88)]),1e-12)) + ### MEDCouplingFieldDouble.__rdiv__ + m=MEDCouplingDataForTest.build2DTargetMesh_1() + f=MEDCouplingFieldDouble(ON_CELLS) + f.setMesh(m) + arr=DataArrayDouble(5,2) + arr[:,0]=range(1,6) ; arr[:,1]=2*arr[:,0] + f2=f.clone(True) + self.assertRaises(InterpKernelException,f.__rdiv__,2) + self.assertRaises(InterpKernelException,f.__rdiv__,range(5)) + self.assertRaises(InterpKernelException,f.__rdiv__,arr) + self.assertRaises(InterpKernelException,f.__rdiv__,f2) + f.setArray(DataArrayDouble()) + self.assertRaises(InterpKernelException,f.__rdiv__,2) + self.assertRaises(InterpKernelException,f.__rdiv__,range(5)) + self.assertRaises(InterpKernelException,f.__rdiv__,arr) + self.assertRaises(InterpKernelException,f.__rdiv__,f2) + self.assertRaises(InterpKernelException,f.__getitem__,(slice(None),0)) + f.getArray().alloc(5,2) + f.getArray()[:,0]=range(1,6) ; f.getArray()[:,1]=f.getArray()[:,0]+7 + ff=2/f + ff.checkCoherency() + self.assertTrue(ff.getArray().isEqual(DataArrayDouble([(2,0.25),(1,0.22222222222222221),(0.66666666666666663,0.20000000000000001),(0.5,0.18181818181818182),(0.40000000000000002,0.16666666666666666)]),1e-12)) + ff=arr/f + ff.checkCoherency() + self.assertTrue(ff.getArray().isEqual(DataArrayDouble([(1,0.25),(1,0.44444444444444442),(1,0.59999999999999998),(1,0.72727272727272729),(1,0.83333333333333337)]),1e-12)) + self.assertRaises(InterpKernelException,f.__rdiv__,f2) + pass + + def testSwig2FieldDoubleBuildSubPartRange1(self): + #ON_CELLS + m=MEDCouplingDataForTest.build2DTargetMesh_1() + f=MEDCouplingFieldDouble(ON_CELLS) + f.setMesh(m) + arr=DataArrayDouble(5,2) ; arr[:,0]=range(7,12) ; arr[:,1]=100+arr[:,0] + f.setArray(arr) + f.checkCoherency() + ff=f[1:-1:2] + ff.checkCoherency() + self.assertTrue((m.buildPartOfMySelf([1,3],True)).isEqual(ff.getMesh(),1e-12)) + self.assertTrue(9,ff.getMesh().getNumberOfNodes()) + self.assertTrue(2,ff.getMesh().getNumberOfCells()) + self.assertTrue(ff.getArray().isEqual(arr[[1,3]],1e-12)) + # + a,b=f.buildSubMeshDataRange(2,5,1) + self.assertTrue(m.buildPartOfMySelf([2,3,4],True).isEqual(a,1e-12)) + self.assertEqual(b,slice(2,5,1)) + ff=f[2:] + ff.checkCoherency() + self.assertTrue((m.buildPartOfMySelf([2,3,4],True)).isEqual(ff.getMesh(),1e-12)) + self.assertTrue(9,ff.getMesh().getNumberOfNodes()) + self.assertTrue(3,ff.getMesh().getNumberOfCells()) + self.assertTrue(ff.getArray().isEqual(arr[[2,3,4]],1e-12)) + # + ff=f[-2:0:-1] + ff.checkCoherency() + self.assertTrue((m.buildPartOfMySelf([3,2,1],True)).isEqual(ff.getMesh(),1e-12)) + self.assertTrue(9,ff.getMesh().getNumberOfNodes()) + self.assertTrue(3,ff.getMesh().getNumberOfCells()) + self.assertTrue(ff.getArray().isEqual(arr[[3,2,1]],1e-12)) + self.assertTrue(f[-2:0:-1,1].getArray().isEqual(arr[[3,2,1],1],1e-12)) + #ON_NODES + f=MEDCouplingFieldDouble(ON_NODES) + f.setMesh(m) + arr=DataArrayDouble(9,2) ; arr[:,0]=range(7,16) ; arr[:,1]=100+arr[:,0] + f.setArray(arr) + f.checkCoherency() + ff=f[1:-1:2] + ff.checkCoherency() + self.assertTrue((m.buildPartOfMySelf([1,3],False)).isEqual(ff.getMesh(),1e-12)) + self.assertTrue(6,ff.getMesh().getNumberOfNodes()) + self.assertTrue(2,ff.getMesh().getNumberOfCells()) + self.assertTrue(ff.getArray().isEqual(arr[[1,2,3,4,6,7]],1e-12)) + # + m2=m.buildPartRange(2,5,1) + self.assertTrue(m.buildPartOfMySelf([2,3,4],True).isEqual(m2,1e-12)) + m2,b=m.buildPartRangeAndReduceNodes(2,5,1) + self.assertTrue(m.buildPartOfMySelf([2,3,4],False).isEqual(m2,1e-12)) + self.assertTrue(b.isEqual(DataArrayInt([-1,-1,0,1,2,3,4,5,6]))) + a,b=f.buildSubMeshDataRange(2,5,1) + self.assertTrue(m.buildPartOfMySelf([2,3,4],False).isEqual(a,1e-12)) + self.assertTrue(b.isEqual(DataArrayInt([2,3,4,5,6,7,8]))) + ff=f[2:] + ff.checkCoherency() + self.assertTrue((m.buildPartOfMySelf([2,3,4],False)).isEqual(ff.getMesh(),1e-12)) + self.assertTrue(7,ff.getMesh().getNumberOfNodes()) + self.assertTrue(3,ff.getMesh().getNumberOfCells()) + self.assertTrue(ff.getArray().isEqual(arr[[2,3,4,5,6,7,8]],1e-12)) + # + ff=f[-2:0:-1] + ff.checkCoherency() + self.assertTrue((m.buildPartOfMySelf([3,2,1],False)).isEqual(ff.getMesh(),1e-12)) + self.assertTrue(7,ff.getMesh().getNumberOfNodes()) + self.assertTrue(3,ff.getMesh().getNumberOfCells()) + self.assertTrue(ff.getArray().isEqual(arr[[1,2,3,4,5,6,7]],1e-12)) + self.assertTrue(f[-2:0:-1,1].getArray().isEqual(arr[[1,2,3,4,5,6,7],1],1e-12)) + #ON_GAUSS_NE + f=MEDCouplingFieldDouble(ON_GAUSS_NE) + f.setMesh(m) + arr=DataArrayDouble(18,2) ; arr[:,0]=range(7,25) ; arr[:,1]=100+arr[:,0] + f.setArray(arr) + f.checkCoherency() + ff=f[1:-1:2] + ff.checkCoherency() + self.assertTrue((m.buildPartOfMySelf([1,3],True)).isEqual(ff.getMesh(),1e-12)) + self.assertTrue(9,ff.getMesh().getNumberOfNodes()) + self.assertTrue(2,ff.getMesh().getNumberOfCells()) + self.assertTrue(ff.getArray().isEqual(arr[[4,5,6,10,11,12,13]],1e-12)) + # + a,b=f.buildSubMeshDataRange(2,5,1) + self.assertTrue(m.buildPartOfMySelf([2,3,4],True).isEqual(a,1e-12)) + self.assertEqual(b,slice(7,18,1)) + ff=f[2:] + ff.checkCoherency() + self.assertTrue((m.buildPartOfMySelf([2,3,4],True)).isEqual(ff.getMesh(),1e-12)) + self.assertTrue(9,ff.getMesh().getNumberOfNodes()) + self.assertTrue(3,ff.getMesh().getNumberOfCells()) + self.assertTrue(ff.getArray().isEqual(arr[[7,8,9,10,11,12,13,14,15,16,17]],1e-12)) + # + ff=f[-2:0:-1] + ff.checkCoherency() + self.assertTrue((m.buildPartOfMySelf([3,2,1],True)).isEqual(ff.getMesh(),1e-12)) + self.assertTrue(9,ff.getMesh().getNumberOfNodes()) + self.assertTrue(3,ff.getMesh().getNumberOfCells()) + self.assertTrue(ff.getArray().isEqual(arr[[10,11,12,13,7,8,9,4,5,6]],1e-12)) + self.assertTrue(f[-2:0:-1,1].getArray().isEqual(arr[[10,11,12,13,7,8,9,4,5,6],1],1e-12)) + #ON_GAUSS_PT + f=MEDCouplingFieldDouble(ON_GAUSS_PT) + f.setMesh(m) + f.setGaussLocalizationOnCells([0,4],[0,0,1,0,1,1,1,0],[1.1,1.1,2.2,2.2],[0.2,0.8]); + f.setGaussLocalizationOnCells([3],[0,0,1,0,1,1,1,0],[1.1,1.1,2.2,2.2,3.,3.],[0.2,0.4,0.4]); + f.setGaussLocalizationOnCells([1],[0,0,1,0,1,0],[1.1,1.1,2.2,2.2,3.,3.,4.,4.],[0.1,0.1,0.4,0.4]); + f.setGaussLocalizationOnCells([2],[0,0,1,0,1,0],[1.1,1.1,2.2,2.2,3.,3.,4.,4.,5.,5.],[0.1,0.1,0.4,0.3,0.1]); + arr=DataArrayDouble(16,2) ; arr[:,0]=range(7,23) ; arr[:,1]=100+arr[:,0] + f.setArray(arr) + f.checkCoherency() + ff=f[1:-1:2] + ff.checkCoherency() + self.assertTrue((m.buildPartOfMySelf([1,3],True)).isEqual(ff.getMesh(),1e-12)) + self.assertTrue(9,ff.getMesh().getNumberOfNodes()) + self.assertTrue(2,ff.getMesh().getNumberOfCells()) + self.assertTrue(ff.getArray().isEqual(arr[[2,3,4,5,11,12,13]],1e-12)) + # + a,b=f.buildSubMeshDataRange(2,5,1) + self.assertTrue(m.buildPartOfMySelf([2,3,4],True).isEqual(a,1e-12)) + self.assertEqual(b,slice(6,16,1)) + ff=f[2:] + ff.checkCoherency() + self.assertTrue((m.buildPartOfMySelf([2,3,4],True)).isEqual(ff.getMesh(),1e-12)) + self.assertTrue(9,ff.getMesh().getNumberOfNodes()) + self.assertTrue(3,ff.getMesh().getNumberOfCells()) + self.assertTrue(ff.getArray().isEqual(arr[[6,7,8,9,10,11,12,13,14,15]],1e-12)) + # + ff=f[-2:0:-1] + ff.checkCoherency() + self.assertTrue((m.buildPartOfMySelf([3,2,1],True)).isEqual(ff.getMesh(),1e-12)) + self.assertTrue(9,ff.getMesh().getNumberOfNodes()) + self.assertTrue(3,ff.getMesh().getNumberOfCells()) + self.assertTrue(ff.getArray().isEqual(arr[[11,12,13,6,7,8,9,10,2,3,4,5]],1e-12)) + self.assertTrue(f[-2:0:-1,0].getArray().isEqual(arr[[11,12,13,6,7,8,9,10,2,3,4,5],0],1e-12)) + pass + + def testSwig2FieldDoubleApplyFuncBug1(self): + f=MEDCouplingFieldDouble(ON_CELLS) + f.setMesh(MEDCouplingDataForTest.build2DTargetMesh_1()) + f.applyFunc(3,700.) + f.checkCoherency() + self.assertEqual(3,f.getArray().getNumberOfComponents()) + f.getArray().rearrange(1) + self.assertTrue(f.getArray().isUniform(700.,1e-10)) + f.getArray().rearrange(3) + f.checkCoherency() + f.applyFunc(4,800.) + f.checkCoherency() + self.assertEqual(4,f.getArray().getNumberOfComponents()) + f.getArray().rearrange(1) + self.assertTrue(f.getArray().isUniform(800.,1e-10)) + f.getArray().rearrange(4) + f.checkCoherency() + pass + + def testSwig2ComputeTupleIdsNearTupleBug1(self): + coords=[1.1,0.0, 1.1,0.0 ]; + coordsArr=DataArrayDouble(coords,2,2); + mesh=MEDCouplingUMesh(); + mesh.setCoords(coordsArr); + points=[1.1, 0.002] + c,cI=mesh.getNodeIdsNearPoints(points,0.00185); + self.assertTrue(c.isEqual(DataArrayInt([]))) + self.assertTrue(cI.isEqual(DataArrayInt([0,0]))) + c,cI=mesh.getNodeIdsNearPoints(points,0.00200000000000001); + self.assertTrue(c.isEqual(DataArrayInt([0,1]))) + self.assertTrue(cI.isEqual(DataArrayInt([0,2]))) + pass + + def testSwig2NonRegressionBugChangeUnderlyingWithZeroCells(self): + coords1=[0.,1.,2.,3.] + coords2=[2.,1.,0.,3.] #0 <==> #2 + # mesh 1 + mesh1=MEDCouplingUMesh.New(); + coordsArr=DataArrayDouble.New(coords1,4,1); + mesh1.setCoords(coordsArr); + mesh1.setMeshDimension(0); + mesh1.allocateCells(0); + mesh1.finishInsertingCells(); + # mesh 2 + mesh2=mesh1.deepCpy(); + coordsArr=DataArrayDouble.New(coords2,4,1); + mesh2.setCoords(coordsArr); + field = mesh1.fillFromAnalytic(ON_NODES,1,"x") + field.checkCoherency() + levOfCheck = 10 + field.changeUnderlyingMesh( mesh2, levOfCheck, 1e-13, 0 ) + self.assertTrue( field.getArray().getValues() == coords2 ) + pass + + def testSwig2UMeshDistanceToMesh2(self): + sz=5 + m=MEDCouplingCMesh() + arr=DataArrayDouble(sz+1) ; arr.iota() ; arr/=sz + m.setCoords(arr,arr,arr) + m=m.buildUnstructured() + m1=m.computeSkin() + m1.zipCoords() + c=m1.getCoords()[:] + d=2*(c-[0.5,0.5,0.5])+[0.5,0.5,0.5] + time_deb = datetime.now() + #print "go.." + a,b=m1.distanceToPoints(d) + #print 'time spent in distanceToPoints %s ' %str(datetime.now() - time_deb) + time_deb = datetime.now() + a1=DataArrayDouble(len(d)) + b1=DataArrayInt(len(d)) + m1s=[m1[i] for i in xrange(m1.getNumberOfCells())] + for j,pt in enumerate(d): + eter=1e308 + fter=-1 + for i,miter in enumerate(m1s): + e,f=miter.distanceToPoint(pt) + self.assertEqual(0,f) + if e<eter: + eter=e ; fter=i + pass + pass + a1[j]=eter + b1[j]=fter + pass + #print 'time spent in naive distanceToPoints %s ' %str(datetime.now() - time_deb) + self.assertTrue(a.isEqual(a1,1e-12)) + self.assertTrue(b.isEqual(b1)) + self.assertTrue(a.isEqual(DataArrayDouble([0.8660254037844386,0.714142842854285,0.7071067811865476,0.7071067811865476,0.714142842854285,0.8660254037844386,0.714142842854285,0.5196152422706632,0.5099019513592785,0.5099019513592785,0.5196152422706632,0.714142842854285,0.7071067811865475,0.5099019513592785,0.5,0.5,0.5099019513592785,0.7071067811865476,0.7071067811865475,0.5099019513592785,0.5,0.5,0.5099019513592785,0.7071067811865476,0.714142842854285,0.5196152422706632,0.5099019513592785,0.5099019513592785,0.5196152422706632,0.714142842854285,0.8660254037844386,0.714142842854285,0.7071067811865476,0.7071067811865476,0.714142842854285,0.8660254037844386,0.714142842854285,0.5196152422706632,0.5099019513592785,0.5099019513592785,0.5196152422706631,0.714142842854285,0.5196152422706631,0.5196152422706632,0.5099019513592784,0.5099019513592785,0.5099019513592784,0.5099019513592785,0.5196152422706631,0.5196152422706632,0.714142842854285,0.5196152422706632,0.5099019513592785,0.5099019513592785,0.5196152422706632,0.714142842854285,0.7071067811865475,0.5099019513592785,0.5,0.5,0.5099019513592784,0.7071067811865475,0.5099019513592784,0.5099019513592785,0.5,0.5,0.5,0.5,0.5099019513592785,0.5099019513592785,0.7071067811865476,0.5099019513592785,0.5,0.5,0.5099019513592785,0.7071067811865476,0.7071067811865475,0.5099019513592785,0.5,0.5,0.5099019513592784,0.7071067811865475,0.5099019513592784,0.5099019513592785,0.5,0.5,0.5,0.5,0.5099019513592785,0.5099019513592785,0.7071067811865476,0.5099019513592785,0.5,0.5,0.5099019513592785,0.7071067811865476,0.714142842854285,0.5196152422706632,0.5099019513592785,0.5099019513592785,0.5196152422706631,0.714142842854285,0.5196152422706631,0.5196152422706632,0.5099019513592784,0.5099019513592785,0.5099019513592784,0.5099019513592785,0.5196152422706631,0.5196152422706632,0.714142842854285,0.5196152422706632,0.5099019513592785,0.5099019513592785,0.5196152422706632,0.714142842854285,0.8660254037844386,0.714142842854285,0.7071067811865476,0.7071067811865476,0.714142842854285,0.8660254037844386,0.714142842854285,0.5196152422706632,0.5099019513592785,0.5099019513592785,0.5196152422706632,0.714142842854285,0.7071067811865475,0.5099019513592785,0.5,0.5,0.5099019513592785,0.7071067811865476,0.7071067811865475,0.5099019513592785,0.5,0.5,0.5099019513592785,0.7071067811865476,0.714142842854285,0.5196152422706632,0.5099019513592785,0.5099019513592785,0.5196152422706632,0.714142842854285,0.8660254037844386,0.714142842854285,0.7071067811865476,0.7071067811865476,0.714142842854285,0.8660254037844386]),1e-12)) + self.assertTrue(b.isEqual(DataArrayInt([0,0,3,7,9,9,0,0,3,7,9,9,12,12,14,16,17,17,26,26,28,30,31,31,33,33,36,40,42,42,33,33,36,40,42,42,0,0,3,7,11,9,0,9,12,17,26,31,33,42,33,33,36,40,42,42,45,45,47,49,51,51,45,50,52,53,56,57,58,63,58,58,60,62,63,63,85,85,87,89,91,91,85,90,92,93,96,97,98,103,98,98,100,102,103,103,105,105,108,112,116,114,105,114,117,122,131,136,138,147,138,138,141,145,147,147,105,105,108,112,114,114,105,105,108,112,114,114,117,117,119,121,122,122,131,131,133,135,136,136,138,138,141,145,147,147,138,138,141,145,147,147]))) + pass + + def testSwig2NonRegressionBugDistance1(self): + pt=DataArrayDouble([(8.8452994616207476,3.1547005383792515,3.1547005383792515)]) + coo=DataArrayDouble([(8,0,0),(8,0,8),(8,8,8),(8,8,0),(16,0,0),(16,0,8),(16,8,8),(16,8,0),(8,0,4),(8,4,8),(8,8,4),(8,4,0),(16,0,4),(16,4,8),(16,8,4),(16,4,0),(12,0,0),(12,0,8),(12,8,8),(12,8,0),(8,4,4),(16,4,4),(12,0,4),(12,4,8),(12,8,4),(12,4,0)]) + conn=DataArrayInt([4,15,21,12,4,16,25,15,12,22,16,4,0,8,20,11,16,0,11,25,22,8,0,16,15,7,14,21,15,25,19,7,7,19,24,14,11,20,10,3,25,11,3,19,19,3,10,24,12,21,13,5,13,23,17,5,5,17,22,12,8,1,9,20,23,9,1,17,17,1,8,22,21,14,6,13,14,24,18,6 ,6,18,23,13,20,9,2,10,24,10,2,18,18,2,9,23]) + m=MEDCouplingUMesh("mesh",2) + m.setCoords(coo) + m.allocateCells() + for i in xrange(24): + m.insertNextCell(NORM_QUAD4,conn[4*i:4*i+4]) + pass + m.checkCoherency2() + m0=m[3] ; m0.zipCoords() + expectedDist=0.8452994616207476 + a,b=m0.distanceToPoint(pt) + self.assertAlmostEqual(expectedDist,a,14) + self.assertEqual(0,b) + # + a,b=m.distanceToPoint(pt) + self.assertAlmostEqual(expectedDist,a,14) + self.assertEqual(3,b) + # + fd=MEDCouplingFieldDiscretization.New(ON_CELLS) + self.assertEqual(24,fd.getNumberOfTuples(m)) + fd=MEDCouplingFieldDiscretization.New(ON_NODES) + self.assertEqual(26,fd.getNumberOfTuples(m)) + pass + + def testSwig2AreaBarySeg3Quad8Tri6QPolyg(self): + #QUAD8 representing a circle of center zeBary and radius zeRadius + zeBary=[5,6] + zeRadius=3 + d=DataArrayDouble(8,2) + d[:,0]=zeRadius + d[:,1]=[87,-100,-170,110,5,-130,175,95] # angle in degree + d[:,1]*=pi/180. # angle in radian + d=d.fromPolarToCart() + d+=zeBary + m=MEDCouplingUMesh("quad8",2) ; m.allocateCells() ; m.insertNextCell(NORM_QUAD8,range(8)) ; m.setCoords(d) + self.assertTrue(m.getBarycenterAndOwner().isEqual(DataArrayDouble(zeBary,1,2),1e-13)) + self.assertAlmostEqual(float(m.getMeasureField(False).getArray()),pi*zeRadius*zeRadius,12) + tri32D=m.buildDescendingConnectivity()[0][0] ; tri32D.zipCoords() + # spaceDim=3 QUAD8 becomes QUAD4 ... for the moment + m.setCoords(m.getCoords().changeNbOfComponents(3,0.)) + m2=m.deepCpy() + m2.convertQuadraticCellsToLinear() + self.assertAlmostEqual(float(m.getMeasureField(False).getArray()),float(m2.getMeasureField(False).getArray()),12) + self.assertTrue(m.getBarycenterAndOwner().isEqual(m2.getBarycenterAndOwner(),1e-13)) + #TRI6 representing a circle of center zeBary and radius zeRadius + zeBary=[5,6] + zeRadius=3 + d=DataArrayDouble(6,2) + d[:,0]=zeRadius + d[:,1]=[87,-100,110,5,175,95] # angle in degree + d[:,1]*=pi/180. # angle in radian + d=d.fromPolarToCart() + d+=zeBary + m=MEDCouplingUMesh("tri6",2) ; m.allocateCells() ; m.insertNextCell(NORM_TRI6,range(6)) ; m.setCoords(d) + self.assertTrue(m.getBarycenterAndOwner().isEqual(DataArrayDouble(zeBary,1,2),1e-13)) + self.assertAlmostEqual(float(m.getMeasureField(False).getArray()),pi*zeRadius*zeRadius,12) + # spaceDim=3 TRI6 becomes TRI3 ... for the moment + m.setCoords(m.getCoords().changeNbOfComponents(3,0.)) + m2=m.deepCpy() + m2.convertQuadraticCellsToLinear() + self.assertAlmostEqual(float(m.getMeasureField(False).getArray()),float(m2.getMeasureField(False).getArray()),12) + self.assertTrue(m.getBarycenterAndOwner().isEqual(m2.getBarycenterAndOwner(),1e-13)) + # QPOLYG representing a circle of center zeBary and radius zeRadius + zeBary=[5,6] + zeRadius=3 + d=DataArrayDouble(10,2) + d[:,0]=zeRadius + d[:,1]=[87,-80,-100,-170,110,5,-90,-130,175,95] # angle in degree + d[:,1]*=pi/180. # angle in radian + d=d.fromPolarToCart() + d+=zeBary + m=MEDCouplingUMesh("qpolyg",2) ; m.allocateCells() ; m.insertNextCell(NORM_QPOLYG,range(10)) ; m.setCoords(d) + self.assertTrue(m.getBarycenterAndOwner().isEqual(DataArrayDouble(zeBary,1,2),1e-13)) + self.assertAlmostEqual(float(m.getMeasureField(False).getArray()),pi*zeRadius*zeRadius,12) + # spaceDim=3 QPOLYG becomes POLYG ... for the moment + m.setCoords(m.getCoords().changeNbOfComponents(3,0.)) + m2=m.deepCpy() + m2.convertQuadraticCellsToLinear() ; m2.checkCoherency2() + self.assertTrue(m2.getAllGeoTypes()==[NORM_POLYGON] and m2.getNodalConnectivity().getValues()==[5,0,1,2,3,4]) + self.assertAlmostEqual(float(m.getMeasureField(False).getArray()),float(m2.getMeasureField(False).getArray()),12) + self.assertTrue(m.getBarycenterAndOwner().isEqual(m2.getBarycenterAndOwner(),1e-13)) + # TRI3 + self.assertAlmostEqual(float(tri32D.getMeasureField(False).getArray()),(87+100)*pi/180*zeRadius,13) + exp=DataArrayDouble(1,2) ; exp[:,0]=3 ; exp[:,1]=(87-100)/2. ; exp[:,1]*=pi/180. ; exp=exp.fromPolarToCart() ; exp+=DataArrayDouble([5,6],1,2) + self.assertTrue(tri32D.getBarycenterAndOwner().isEqual(exp,1e-12)) + # spaceDim=3 TRI3 becomes TRI2 ... for the moment + tri32D.changeSpaceDimension(3) + tri2=tri32D.deepCpy() ; tri2.convertQuadraticCellsToLinear() + self.assertAlmostEqual(float(tri32D.getMeasureField(False).getArray()),float(tri2.getMeasureField(False).getArray()),13) + self.assertTrue(tri32D.getBarycenterAndOwner().isEqual(tri2.getBarycenterAndOwner(),1e-12)) + tri32D.changeSpaceDimension(1) + self.assertAlmostEqual(float(tri32D.getMeasureField(False).getArray()),-0.67795240172962323,12) + pass + + # this bug 5/6/2013 is swig specific + def testSwigNonRegressionBugRotate3D1(self): + m=MEDCouplingUMesh.New() + dataArray=DataArrayDouble.New(100,3) + dataArray[:]=0. + dataArray[0]=[0.,1,3] + m.setCoords(dataArray[0]) + m1=m.deepCpy() + m.rotate([0.,0.,3.],[1.,0.,0.],0.5*pi) + self.assertTrue(m.getCoords().isEqual(DataArrayDouble([0.,0.,4.],1,3),1e-15)) + # + d1=DataArrayDouble([0.,0.,3.],1,3) ; d2=DataArrayDouble([1.,0.,0.],1,3) + pts=[[0.,0.,3.],[(0.,0.,3.)],DataArrayDouble([0.,0.,3.],1,3),list(d1)[0]] + vec=[[1.,0.,0.],[(1.,0.,0.)],DataArrayDouble([1.,0.,0.],1,3),list(d2)[0]] + for p in pts: + for v in vec: + m2=m1.deepCpy() + m2.rotate(p,v,0.5*pi) + self.assertTrue(m2.getCoords().isEqual(DataArrayDouble([0.,0.,4.],1,3),1e-15)) + pass + pass + + def testSwig2DataArrayCount1(self): + d=DataArrayInt([]) + self.assertEqual(0,d.getNumberOfTuples()) + self.assertEqual(1,d.getNumberOfComponents()) + self.assertEqual(0,d.count(0)) + self.assertEqual(0,d.count(1)) + self.assertEqual(0,d.count(-1)) + d=DataArrayInt([2,1,-2,-3,2,0,0,7,2,-2,3,0]) + self.assertEqual(12,d.getNumberOfTuples()) + self.assertEqual(1,d.getNumberOfComponents()) + self.assertEqual(3,d.count(0)) + self.assertEqual(1,d.count(1)) + self.assertEqual(0,d.count(-1)) + self.assertEqual(2,d.count(-2)) + self.assertEqual(3,d.count(2)) + e=d.getDifferentValues() + f=DataArrayInt() + for it in e: + f.pushBackSilent(d.count(int(it))) + pass + self.assertEqual(12,f.accumulate()[0]) + # + eps=1e-12 + d=DataArrayDouble([]) + self.assertEqual(0,d.getNumberOfTuples()) + self.assertEqual(1,d.getNumberOfComponents()) + self.assertEqual(0,d.count(0,eps)) + self.assertEqual(0,d.count(1,eps)) + self.assertEqual(0,d.count(-1,eps)) + d=DataArrayDouble([2,1,-2,-3,2,0,eps/10,7,2+eps/10,-2,3,0]) + self.assertEqual(12,d.getNumberOfTuples()) + self.assertEqual(1,d.getNumberOfComponents()) + self.assertEqual(3,d.count(0,eps)) + self.assertEqual(1,d.count(1,eps)) + self.assertEqual(0,d.count(-1,eps)) + self.assertEqual(2,d.count(-2,eps)) + self.assertEqual(3,d.count(2,eps)) + self.assertEqual(3,d.count(2,eps)) + self.assertEqual(2,d.count(2,eps/100)) + e=d.getDifferentValues(eps) + f=DataArrayInt() + for it in e: + f.pushBackSilent(d.count(float(it),eps)) + pass + self.assertEqual(12,f.accumulate()[0]) + pass + + def testSwig2DataArrayGetSlice1(self): + s=slice(2,18,1) + self.assertEqual(DataArray.GetNumberOfItemGivenBESRelative(s),16) + self.assertEqual(DataArray.GetNumberOfItemGivenBES(s),16) + self.assertEqual(DataArray.GetSlice(s,0,4),slice(2,6,1)) + self.assertEqual(DataArray.GetSlice(s,1,4),slice(6,10,1)) + self.assertEqual(DataArray.GetSlice(s,2,4),slice(10,14,1)) + self.assertEqual(DataArray.GetSlice(s,3,4),slice(14,18,1)) + # + s=slice(2,18,2) + self.assertEqual(DataArray.GetNumberOfItemGivenBESRelative(s),8) + self.assertEqual(DataArray.GetNumberOfItemGivenBES(s),8) + self.assertEqual(DataArray.GetSlice(s,0,4),slice(2,6,2)) + self.assertEqual(DataArray.GetSlice(s,1,4),slice(6,10,2)) + self.assertEqual(DataArray.GetSlice(s,2,4),slice(10,14,2)) + self.assertEqual(DataArray.GetSlice(s,3,4),slice(14,18,2)) + # + s=slice(1,18,1) + self.assertEqual(DataArray.GetSlice(s,0,4),slice(1,5,1)) + self.assertEqual(DataArray.GetSlice(s,1,4),slice(5,9,1)) + self.assertEqual(DataArray.GetSlice(s,2,4),slice(9,13,1)) + self.assertEqual(DataArray.GetSlice(s,3,4),slice(13,18,1))# 18 not 17 + # + s=slice(1,18,2) + self.assertEqual(DataArray.GetNumberOfItemGivenBESRelative(s),9) + self.assertEqual(DataArray.GetNumberOfItemGivenBES(s),9) + self.assertEqual(DataArray.GetSlice(s,0,4),slice(1,5,2)) + self.assertEqual(DataArray.GetSlice(s,1,4),slice(5,9,2)) + self.assertEqual(DataArray.GetSlice(s,2,4),slice(9,13,2)) + self.assertEqual(DataArray.GetSlice(s,3,4),slice(13,18,2))# 18 not 17 + # + s=slice(18,2,-1) + self.assertEqual(DataArray.GetSlice(s,0,4),slice(18,14,-1)) + self.assertEqual(DataArray.GetSlice(s,1,4),slice(14,10,-1)) + self.assertEqual(DataArray.GetSlice(s,2,4),slice(10,6,-1)) + self.assertEqual(DataArray.GetSlice(s,3,4),slice(6,2,-1)) + # + s=slice(18,2,-2) + self.assertEqual(DataArray.GetSlice(s,0,4),slice(18,14,-2)) + self.assertEqual(DataArray.GetSlice(s,1,4),slice(14,10,-2)) + self.assertEqual(DataArray.GetSlice(s,2,4),slice(10,6,-2)) + self.assertEqual(DataArray.GetSlice(s,3,4),slice(6,2,-2)) + # + s=slice(18,1,-1) + self.assertEqual(DataArray.GetSlice(s,0,4),slice(18,14,-1)) + self.assertEqual(DataArray.GetSlice(s,1,4),slice(14,10,-1)) + self.assertEqual(DataArray.GetSlice(s,2,4),slice(10,6,-1)) + self.assertEqual(DataArray.GetSlice(s,3,4),slice(6,1,-1))# 1 not 2 + # + s=slice(18,1,-2) + self.assertEqual(DataArray.GetNumberOfItemGivenBESRelative(s),9) + self.assertRaises(InterpKernelException,DataArray.GetNumberOfItemGivenBES,s) + self.assertEqual(sum([DataArray.GetNumberOfItemGivenBESRelative(DataArray.GetSlice(s,i,4)) for i in xrange(4)]),DataArray.GetNumberOfItemGivenBESRelative(s)) + self.assertEqual(DataArray.GetSlice(s,0,4),slice(18,14,-2)) + self.assertEqual(DataArray.GetSlice(s,1,4),slice(14,10,-2)) + self.assertEqual(DataArray.GetSlice(s,2,4),slice(10,6,-2)) + self.assertEqual(DataArray.GetSlice(s,3,4),slice(6,1,-2))# 1 not 2 + self.assertRaises(InterpKernelException,DataArray.GetSlice,slice(0,None,2),0,4) + # + d=DataArrayInt.Range(0,18,1) + s=slice(2,None,1) + self.assertEqual(d.getNumberOfItemGivenBES(s),16) + self.assertEqual(d.getNumberOfItemGivenBESRelative(s),16) + self.assertEqual(d.getSlice(s,0,4),slice(2,6,1)) + self.assertEqual(d.getSlice(s,1,4),slice(6,10,1)) + self.assertEqual(d.getSlice(s,2,4),slice(10,14,1)) + self.assertEqual(d.getSlice(s,3,4),slice(14,18,1)) + # + d=DataArrayInt.Range(0,18,1) + s=slice(2,-2,1) + self.assertEqual(d.getSlice(s,0,4),slice(2,5,1)) + self.assertEqual(d.getSlice(s,1,4),slice(5,8,1)) + self.assertEqual(d.getSlice(s,2,4),slice(8,11,1)) + self.assertEqual(d.getSlice(s,3,4),slice(11,16,1)) + # + d=DataArrayInt.Range(0,18,1) + s=slice(None,None,1) + self.assertEqual(d.getSlice(s,0,4),slice(0,4,1)) + self.assertEqual(d.getSlice(s,1,4),slice(4,8,1)) + self.assertEqual(d.getSlice(s,2,4),slice(8,12,1)) + self.assertEqual(d.getSlice(s,3,4),slice(12,18,1)) + # + d=DataArrayInt.Range(0,18,1) + s=slice(None,2,-2) + self.assertRaises(InterpKernelException,d.getNumberOfItemGivenBES,s) + self.assertEqual(d.getNumberOfItemGivenBESRelative(s),8) + self.assertEqual(d.getSlice(s,0,4),slice(17,13,-2)) + self.assertEqual(d.getSlice(s,1,4),slice(13,9,-2)) + self.assertEqual(d.getSlice(s,2,4),slice(9,5,-2)) + self.assertEqual(d.getSlice(s,3,4),slice(5,2,-2)) + pass + + def testSwig2AccumulatePerChunk1(self): + arr=DataArrayDouble(11) ; arr.iota() + m=MEDCouplingCMesh() ; m.setCoords(arr,arr) + m=m.buildUnstructured() + m0=m[::2] ; ids0=m0.simplexize(0) ; m1=m[1::2] + m=MEDCouplingUMesh.MergeUMeshesOnSameCoords(m0,m1) ; m.setName("mesh") + m.checkConsecutiveCellTypesForMEDFileFrmt() + # + formula="7-sqrt((x-5.)*(x-5.)+(y-5.)*(y-5.))" + f=MEDCouplingFieldDouble(ON_CELLS,ONE_TIME) ; f.setMesh(m) + f.fillFromAnalytic(1,formula) + f.setName("Field1") ; f.setTime(1.1,1,-1) + f.checkCoherency() + # + arr=f.getArray() + arr2=DataArrayDouble(len(arr),2) ; arr2[:,0]=arr + arr2=DataArrayDouble(len(arr),2) ; arr2[:,0]=arr ; arr2[:,1]=2*arr + f.setArray(arr2) + f.checkCoherency() + # here the compact code to obviously put field on cell to nodes + rn,rni=f.getMesh().getReverseNodalConnectivity() + arr2=f.getArray()[rn] + arr4=arr2.accumulatePerChunck(rni) + nbOfCellsSharingNodes=rni.deltaShiftIndex() + arr4/=nbOfCellsSharingNodes.convertToDblArr() + # + maxNbCSN=nbOfCellsSharingNodes.getMaxValue()[0] + arr3=DataArrayDouble(f.getMesh().getNumberOfNodes(),f.getArray().getNumberOfComponents()) ; arr3[:]=0. + for i in xrange(1,maxNbCSN+1): + ids=nbOfCellsSharingNodes.getIdsEqual(i) + if len(ids)==0: + continue + for j in range(i): + rni2=rni[ids] ; rni2+=j + arr3[ids]+=arr2[rni2] + pass + arr3[ids]/=i + pass + fNode=MEDCouplingFieldDouble(ON_NODES,ONE_TIME) ; fNode.setMesh(m) + fNode.setName("Field1Node") ; fNode.setTime(1.1,1,-1) + fNode.setArray(arr3) ; fNode.checkCoherency() + self.assertTrue(arr3.isEqual(arr4,1e-12)) + # + d=DataArrayInt.Range(0,20,1) + self.assertTrue(d.accumulatePerChunck([2,4,12]).isEqual(DataArrayInt([5,60]))) + # + a=DataArrayDouble(12) ; a.iota() ; a.rearrange(3) + b=DataArrayDouble(12) ; b.iota(20) ; b.rearrange(3) + ids=DataArrayInt([]) + self.assertEqual(len(a[ids]),0) + self.assertEqual(len(b[ids]),0) + a2=a.deepCpy() ; a2[ids]+=b[ids] ; self.assertTrue(a2.isEqual(a,1e-15)) + a2=a.deepCpy() ; a2[ids]*=b[ids] ; self.assertTrue(a2.isEqual(a,1e-15)) + a2=a.deepCpy() ; a2[ids]/=b[ids] ; self.assertTrue(a2.isEqual(a,1e-15)) + a2=a.deepCpy() ; a2[ids]-=b[ids] ; self.assertTrue(a2.isEqual(a,1e-15)) + pass + + def testSwig2CheckAndPreparePermutation1(self): + a=DataArrayInt([10003,9999999,5,67]) + self.assertTrue(a.checkAndPreparePermutation().isEqual(DataArrayInt([2,3,0,1]))) + a=DataArrayInt([10003,-9999999,5,67]) + self.assertTrue(a.checkAndPreparePermutation().isEqual(DataArrayInt([3,0,1,2]))) + a=DataArrayInt([]) + self.assertTrue(a.checkAndPreparePermutation().isEqual(DataArrayInt([]))) + a=DataArrayInt([]) + a.iota(); + self.assertTrue(a.isEqual(DataArrayInt([]))) + pass + + def testSwig21SGTUMesh1(self): + m=MEDCoupling1GTUMesh.New("m",NORM_PENTA6) + m.__repr__() ; m.__str__() + self.assertTrue(isinstance(m,MEDCoupling1SGTUMesh)) + m.setCoords(DataArrayDouble(20,3)) + m.allocateCells() + m.__repr__() ; m.__str__() + m.insertNextCell([0,1,2,5,7,2]) + self.assertEqual(1,m.getNumberOfCells()) + self.assertTrue(DataArrayInt([6]).isEqual(m.computeNbOfNodesPerCell())) + self.assertTrue(DataArrayInt([5]).isEqual(m.computeNbOfFacesPerCell())) + m.__repr__() ; m.__str__() + m.checkCoherency() + m.checkCoherency2() + # + cm=MEDCouplingCMesh() ; cm.setName("m") + arr0=DataArrayDouble(6) ; arr0.iota() + arr1=DataArrayDouble([0,1]) + cm.setCoords(arr0,arr1,arr1) ; um=cm.buildUnstructured() + # + m=MEDCoupling1SGTUMesh("m",NORM_QUAD4) + mem_m=m.getHeapMemorySize() + m.allocateCells(5) + self.assertIn(m.getHeapMemorySize()-mem_m,xrange(5*4*4,5*4*4+32)) + self.assertEqual(m.getNodalConnectivity().getNbOfElemAllocated(),20) + m.setCoords(um.getCoords()) + m.insertNextCell([1,0,6,7]) + self.assertEqual(1,m.getNumberOfCells()) + m.insertNextCell([2,1,7,8]) + m.insertNextCell([3,2,8,9]) + m.insertNextCell([4,3,9,10]) + m.insertNextCell([5,4,10,11]) + self.assertEqual(5,m.getNumberOfCells()) + self.assertRaises(InterpKernelException,m.insertNextCell,[0,6,7]) + self.assertRaises(InterpKernelException,m.insertNextCell,[0,6,7,1,2]) + self.assertEqual(m.getNodalConnectivity().getNbOfElemAllocated(),20) + f=m.getMeasureField(ON_CELLS) + self.assertEqual(f.getMesh().getHiddenCppPointer(),m.getHiddenCppPointer()) + self.assertTrue(f.getArray().isUniform(1,1e-14)) + self.assertEqual(m.getType(),10) + self.assertEqual(m.getCellModelEnum(),NORM_QUAD4) + mo=MEDCoupling1SGTUMesh("m",NORM_QUAD4) ; mo.setCoords(m.getCoords()) + mo.setNodalConnectivity(DataArrayInt([1,0,6,7,2,1,7,8,3,2,8,9,4,3,9,10,5,4,10,11])) + self.assertTrue(m.isEqual(mo,1e-12)) + # + mo2=MEDCoupling1SGTUMesh.Merge1SGTUMeshesOnSameCoords([m[[0,1]],m[[2]],m[[3,4]]]) + mo2.setName(m.getName()) + self.assertTrue(m.isEqual(mo2,1e-12)) + # + mp0=m[[0]] ; mp0.zipCoords() ; mp1=m[2] ; mp1.zipCoords() ; mp2=m[4] ; mp2.zipCoords() + mo3=MEDCoupling1SGTUMesh.Merge1SGTUMeshes([mp0,mp1,mp2]) + self.assertTrue(isinstance(mo3,MEDCoupling1SGTUMesh)) + mo3.setName(m.getName()) + m_ref=m[(0,2,4)] ; m_ref.zipCoords() + m_ref.tryToShareSameCoordsPermute(mo3,1e-12) + self.assertTrue(m_ref.isEqual(mo3,1e-12)) + # + m1=um.buildDescendingConnectivity()[0] + ids=m1.getCellIdsFullyIncludedInNodeIds(DataArrayInt.Range(0,12,1)) + m1=m1[ids] + m1c=m1.convertIntoSingleGeoTypeMesh() + self.assertTrue(isinstance(m1c,MEDCoupling1SGTUMesh)) + self.assertEqual(m1c.getCoords().getHiddenCppPointer(),m.getCoords().getHiddenCppPointer()) + m1c.checkCoherency2() + self.assertTrue(m1c.getNodalConnectivity().isEqual(DataArrayInt([1,0,6,7,2,1,7,8,3,2,8,9,4,3,9,10,5,4,10,11]))) + self.assertEqual(20,m1c.getNodalConnectivityLength()) + self.assertTrue(m.isEqual(m1c,1e-12)) + m.getNodalConnectivity().setIJ(1,0,1) + self.assertTrue(not m.isEqual(m1c,1e-12)) + m.getNodalConnectivity().setIJ(1,0,0) + self.assertTrue(m.isEqual(m1c,1e-12)) + m1c.setCoords(m.getCoords().deepCpy()) + self.assertTrue(m.isEqual(m1c,1e-12)) + m1c.getCoords().setIJ(0,1,0.1) + self.assertTrue(not m.isEqual(m1c,1e-12)) + m1c.getCoords().setIJ(0,1,0) + self.assertTrue(m.isEqual(m1c,1e-12)) + m1c.getCoords().setInfoOnComponent(1,"X") + self.assertTrue(not m.isEqual(m1c,1e-12) and m.isEqualWithoutConsideringStr(m1c,1e-12)) + m.getCoords().setInfoOnComponent(1,"X") + self.assertTrue(m.isEqual(m1c,1e-12) and m.isEqualWithoutConsideringStr(m1c,1e-12)) + m.setName("m2") + self.assertTrue(not m.isEqual(m1c,1e-12) and m.isEqualWithoutConsideringStr(m1c,1e-12)) + # + m.checkCoherency() ; m.checkCoherency1() ; m.checkCoherency2() + self.assertEqual(m.getMeshDimension(),2) + self.assertTrue(m.giveCellsWithType(NORM_QUAD4).isEqual(DataArrayInt([0,1,2,3,4]))) + self.assertTrue(m.giveCellsWithType(NORM_TRI3).isEqual(DataArrayInt([]))) + self.assertEqual(m.getNumberOfCellsWithType(NORM_QUAD4),5) + self.assertEqual(m.getNumberOfCellsWithType(NORM_TRI3),0) + self.assertEqual(m.getTypeOfCell(3),NORM_QUAD4) + self.assertRaises(InterpKernelException,m.getTypeOfCell,5) + self.assertEqual(m.getAllGeoTypes(),[NORM_QUAD4]) + self.assertEqual(m.getDistributionOfTypes(),[[NORM_QUAD4,5,-1]]) + ## + pfl1=DataArrayInt([1,3,4]) + a,b,c=m.splitProfilePerType(pfl1) + d,e,f=m.buildUnstructured().splitProfilePerType(pfl1) + self.assertTrue(a==[[4,3,0]] and len(b)==1 and b[0].isEqual(DataArrayInt([0,1,2])) and len(c)==1 and c[0].getHiddenCppPointer()==pfl1.getHiddenCppPointer()) + self.assertTrue(a==d and len(b)==1 and b[0].isEqual(e[0]) and len(c)==1 and c[0].isEqual(f[0])) + # + pfl2=DataArrayInt([0,1,2,3]) + a,b,c=m.splitProfilePerType(pfl2) + d,e,f=m.buildUnstructured().splitProfilePerType(pfl2) + self.assertTrue(a==[[4,4,0]] and len(b)==1 and b[0].isEqual(DataArrayInt([0,1,2,3])) and len(c)==1 and c[0].getHiddenCppPointer()==pfl2.getHiddenCppPointer()) + self.assertTrue(a==d and len(b)==1 and b[0].isEqual(e[0]) and len(c)==1 and c[0].isEqual(f[0])) + # + pfl3=DataArrayInt([0,1,2,3,4]) + a,b,c=m.splitProfilePerType(pfl3) + d,e,f=m.buildUnstructured().splitProfilePerType(pfl3) + self.assertTrue(a==[[4,5,-1]] and len(b)==1 and b[0].isEqual(DataArrayInt([0,1,2,3,4])) and c==[]) + self.assertTrue(a==d and len(b)==1 and b[0].isEqual(e[0]) and c==[]) + # + invalidPfl=DataArrayInt([1,2,3,4,5]) + self.assertRaises(InterpKernelException,m.splitProfilePerType,invalidPfl) + self.assertRaises(InterpKernelException,m.buildUnstructured().splitProfilePerType,invalidPfl) + ## + pfl1=DataArrayInt([1,2,3]) + a=m.checkTypeConsistencyAndContig([NORM_QUAD4,3,0],[pfl1]) + b=m.buildUnstructured().checkTypeConsistencyAndContig([NORM_QUAD4,3,0],[pfl1]) + self.assertTrue(a.isEqual(b) and pfl1.getHiddenCppPointer(),a.getHiddenCppPointer()) + # + pfl2=DataArrayInt([0,1,2,3]) + a=m.checkTypeConsistencyAndContig([NORM_QUAD4,4,0],[pfl2]) + b=m.buildUnstructured().checkTypeConsistencyAndContig([NORM_QUAD4,4,0],[pfl2]) + self.assertTrue(a.isEqual(b) and pfl2.getHiddenCppPointer()==a.getHiddenCppPointer()) + # + pfl3=DataArrayInt([0,1,2,3,4]) + a=m.checkTypeConsistencyAndContig([NORM_QUAD4,4,0],[pfl3]) + b=m.buildUnstructured().checkTypeConsistencyAndContig([NORM_QUAD4,5,0],[pfl3]) + self.assertTrue(a.isEqual(b) and pfl3.getHiddenCppPointer()==a.getHiddenCppPointer()) + # + invalidPfl=DataArrayInt([1,2,3,4,5]) + self.assertRaises(InterpKernelException,m.checkTypeConsistencyAndContig,[NORM_QUAD4,5,0],[invalidPfl]) + self.assertRaises(InterpKernelException,m.buildUnstructured().checkTypeConsistencyAndContig,[NORM_QUAD4,5,0],[invalidPfl]) + ## + self.assertTrue(DataArrayInt([4,4,4,4,4]).isEqual(m.computeNbOfNodesPerCell())) + ## + self.assertEqual(m.getNodeIdsOfCell(1),[2,1,7,8]) + ## + self.assertTrue(m.computeIsoBarycenterOfNodesPerCell().isEqual(DataArrayDouble([(0.5,0.5,0),(1.5,0.5,0),(2.5,0.5,0),(3.5,0.5,0),(4.5,0.5,0)]),1e-13)) + ## + ref=m.getCoords().getHiddenCppPointer() + mcpy=m.deepCpy() ; mcpy.insertNextCell([1,0,6,7]) + c=m.getNodalConnectivity().deepCpy() + o2n=DataArrayInt([2,0,1,4,3]) + m.renumberCells(o2n,False) + c.rearrange(4) ; c.renumberInPlace(o2n) ; c.rearrange(1) + self.assertTrue(c.isEqual(m.getNodalConnectivity())) + self.assertEqual(ref,m.getCoords().getHiddenCppPointer()) + m2=mcpy.mergeMyselfWith(m) + self.assertTrue(isinstance(m2,MEDCoupling1SGTUMesh)) + self.assertEqual(11,m2.getNumberOfCells()) + self.assertEqual(48,m2.getNumberOfNodes()) + self.assertTrue(m2.getCoords().isEqual(DataArrayDouble.Aggregate([m.getCoords(),m.getCoords()]),1e-12)) + self.assertTrue(m2.getNodalConnectivity().isEqual(DataArrayInt([1,0,6,7,2,1,7,8,3,2,8,9,4,3,9,10,5,4,10,11,1,0,6,7,26,25,31,32,27,26,32,33,25,24,30,31,29,28,34,35,28,27,33,34]))) + ## + mu=m.buildUnstructured() + mu.checkCoherency2() + self.assertEqual(mu.getCoords().getHiddenCppPointer(),m.getCoords().getHiddenCppPointer()) + self.assertEqual(2,mu.getMeshDimension()) + self.assertEqual([NORM_QUAD4],mu.getAllGeoTypes()) + self.assertTrue(mu.getNodalConnectivity().isEqual(DataArrayInt([4,2,1,7,8,4,3,2,8,9,4,1,0,6,7,4,5,4,10,11,4,4,3,9,10]))) + self.assertTrue(mu.getNodalConnectivityIndex().isEqual(DataArrayInt([0,5,10,15,20,25]))) + ## + for typ in [0,1]: + mcpy2=m.deepCpy() ; umcpy2=mcpy2.buildUnstructured() + ids=mcpy2.simplexize(typ) ; ids2=umcpy2.simplexize(typ) + self.assertTrue(ids.isEqual(ids2)) + mcpy3=umcpy2.convertIntoSingleGeoTypeMesh() + self.assertTrue(mcpy2.isEqual(mcpy3,1e-14)) + pass + um1=um.convertIntoSingleGeoTypeMesh() + self.assertEqual(8,um1.getNumberOfNodesPerCell()) + for typ in [PLANAR_FACE_5,PLANAR_FACE_6]: + mcpy2=um1.deepCpy() ; umcpy2=mcpy2.buildUnstructured() + ids=mcpy2.simplexize(typ) ; ids2=umcpy2.simplexize(typ) + self.assertTrue(ids.isEqual(ids2)) + mcpy3=umcpy2.convertIntoSingleGeoTypeMesh() + self.assertTrue(mcpy2.isEqual(mcpy3,1e-14)) + pass + ## + self.assertRaises(InterpKernelException,mcpy.mergeMyselfWithOnSameCoords,m) + mcpy.tryToShareSameCoords(m,1e-14) + m3=mcpy.mergeMyselfWithOnSameCoords(m) + self.assertTrue(isinstance(m3,MEDCoupling1SGTUMesh)) + self.assertEqual(11,m3.getNumberOfCells()) + self.assertEqual(24,m3.getNumberOfNodes()) + self.assertEqual(m3.getCoords().getHiddenCppPointer(),mcpy.getCoords().getHiddenCppPointer()) + self.assertTrue(m3.getNodalConnectivity().isEqual(DataArrayInt([1,0,6,7,2,1,7,8,3,2,8,9,4,3,9,10,5,4,10,11,1,0,6,7,2,1,7,8,3,2,8,9,1,0,6,7,5,4,10,11,4,3,9,10]))) + ## + ref=mcpy.getCoords().deepCpy() + c3=mcpy.getNodalConnectivity()[:] + mcpy.getNodalConnectivity().setIJ(int(c3.getIdsEqual(11)),0,24) + c2=DataArrayDouble.Aggregate([mcpy.getCoords(),mcpy.getCoords()[11:]]) + mcpy.setCoords(c2) + mcpy.checkCoherency2() + a,b=mcpy.getNodeIdsInUse() + self.assertEqual(12,b) + self.assertTrue(a.isEqual(DataArrayInt([0,1,2,3,4,5,6,7,8,9,10,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,11,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1]))) + ids=mcpy.zipCoordsTraducer() + self.assertTrue(ids.isEqual(DataArrayInt([0,1,2,3,4,5,6,7,8,9,10,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,11,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1]))) + self.assertTrue(mcpy.getCoords().isEqual(ref[:12],1e-12)) + self.assertTrue(mcpy.getNodalConnectivity().isEqual(c3)) + mcpy.checkCoherency2() + ## + m4=mcpy[DataArrayInt([0,3,4])] + m5=mcpy.buildPartOfMySelfKeepCoords(DataArrayInt([0,3,4])) + self.assertTrue(isinstance(m4,MEDCoupling1SGTUMesh)) + self.assertTrue(m4.isEqual(m5,-1e-14))# < 0 not a bug it proves that coordinates pointer are equal + self.assertTrue(m4.getNodalConnectivity().isEqual(DataArrayInt([1,0,6,7,4,3,9,10,5,4,10,11]))) + m6=mcpy[::2] + self.assertTrue(isinstance(m6,MEDCoupling1SGTUMesh)) + self.assertTrue(m6.getNodalConnectivity().isEqual(DataArrayInt([1,0,6,7,3,2,8,9,5,4,10,11]))) + ## + mcpy.setCoords(DataArrayDouble.Aggregate([mcpy.getCoords(),mcpy.getCoords()])) + mcpy.checkCoherency2() + ## + mcppy=mcpy.deepCpyConnectivityOnly() + self.assertTrue(mcppy.isEqual(mcpy,1e-12)) + self.assertTrue(mcppy.getCoords().getHiddenCppPointer()==mcpy.getCoords().getHiddenCppPointer()) + self.assertTrue(mcppy.getNodalConnectivity().isEqual(mcpy.getNodalConnectivity())) + self.assertTrue(mcppy.getNodalConnectivity().getHiddenCppPointer()!=mcpy.getNodalConnectivity().getHiddenCppPointer()) + ## + a,b=mcpy.getReverseNodalConnectivity() + self.assertTrue(a.isEqual(DataArrayInt([0,5,0,1,5,1,2,2,3,3,4,4,0,5,0,1,5,1,2,2,3,3,4,4]))) + self.assertTrue(b.isEqual(DataArrayInt([0,2,5,7,9,11,12,14,17,19,21,23,24,24,24,24,24,24,24,24,24,24,24,24,24]))) + self.assertTrue(mcpy.fillCellIdsToKeepFromNodeIds([0,1,6,7],False).isEqual(DataArrayInt([0,1,5]))) + self.assertTrue(mcpy.fillCellIdsToKeepFromNodeIds([0,1,6,7],True).isEqual(DataArrayInt([0,5]))) + self.assertTrue(mcpy.getCellsInBoundingBox([(0,1),(0,1),(0,1)],1e-12).isEqual(DataArrayInt([0,1,5]))) + f=mcpy.buildOrthogonalField() + self.assertEqual(f.getMesh().getHiddenCppPointer(),mcpy.getHiddenCppPointer()) + self.assertTrue(f.getArray().isEqual(DataArrayDouble(6*[(0,0,-1)]),1e-12)) + mcpy.changeSpaceDimension(2) + self.assertEqual(1,mcpy.getCellContainingPoint([1.5,0.5],1e-12)) + ## + self.assertTrue(mcpy.fillCellIdsToKeepFromNodeIds(DataArrayInt([6,7]),False).isEqual(DataArrayInt([0,1,5]))) + ## + mcpy2=mcpy.deepCpy() + self.assertEqual([None,None],mcpy.checkGeoEquivalWith(mcpy2,1,1e-12))#fast equal + mcpy.checkFastEquivalWith(mcpy2,1e-12) + mcpy2.renumberCells([0,2,4,3,1,5]) + mcpy.checkFastEquivalWith(mcpy2,1e-12) + self.assertEqual([None,None],mcpy.checkGeoEquivalWith(mcpy2,1,1e-12))#fast equal + mcpy2.renumberCells([0,2,4,3,1,5]) + mcpy2.renumberCells([1,3,5,0,2,4]) + self.assertRaises(InterpKernelException,mcpy.checkFastEquivalWith,mcpy2,1e-12) + self.assertRaises(InterpKernelException,mcpy.checkGeoEquivalWith,mcpy2,1,1e-12)#fast equal + pass + + def testSwig21DGTUMesh1(self): + a0=DataArrayInt([0,2,3,5,6,8]) + a1=DataArrayInt([0,4,7,11,14,18,21,25]) + a2=DataArrayInt([0,1,4,5]) + self.assertTrue(DataArrayInt.AggregateIndexes([a0,a1,a2]).isEqual(DataArrayInt([0,2,3,5,6,8,12,15,19,22,26,29,33,34,37,38]))) + self.assertEqual(a1[3:].front(),11) + self.assertEqual(a1[4:].convertToDblArr().front(),14.) + a1c=DataArrayInt([5,7,1,2, 8,11,0, 5,6,3,12, 1,5,2, 13,12,11,7, 6,1,0, 20,21,19,17]) + d,e=MEDCouplingUMesh.ExtractFromIndexedArrays2(1,5,2,a1c,a1) + self.assertTrue(d.isEqual(DataArrayInt([8,11,0,1,5,2]))) + self.assertTrue(e.isEqual(DataArrayInt([0,3,6]))) + # + m=MEDCouplingDataForTest.build2DTargetMesh_1()[0,3,4] + ref=DataArrayInt([0,3,4,1,6,7,4,3,7,8,5,4]) + self.assertTrue(m.convertNodalConnectivityToStaticGeoTypeMesh().isEqual(ref)) + d,e=m.convertNodalConnectivityToDynamicGeoTypeMesh() + self.assertTrue(d.isEqual(ref)) + self.assertTrue(e.isEqual(DataArrayInt.Range(0,13,4))) + self.assertTrue(m.fillCellIdsToKeepFromNodeIds(DataArrayInt([6,7]),False).isEqual(DataArrayInt([1,2]))) + # + m=MEDCoupling1GTUMesh.New("m",NORM_POLYHED) + self.assertTrue(isinstance(m,MEDCoupling1DGTUMesh)) + m.__repr__() ; m.__str__() + m.setCoords(DataArrayDouble(20,3)) + m.allocateCells() + m.__repr__() ; m.__str__() + m.insertNextCell([0,1,2,5,7,2,-1,1,3]) + self.assertEqual(1,m.getNumberOfCells()) + self.assertTrue(DataArrayInt([8]).isEqual(m.computeNbOfNodesPerCell())) + self.assertTrue(DataArrayInt([2]).isEqual(m.computeNbOfFacesPerCell())) + m.__repr__() ; m.__str__() + m.checkCoherency() + m.checkCoherency2() + # + cm=MEDCouplingCMesh() ; cm.setName("m") + arr0=DataArrayDouble(6) ; arr0.iota() + arr1=DataArrayDouble([0,1]) + cm.setCoords(arr0,arr1,arr1) ; um=cm.buildUnstructured() ; um.convertAllToPoly() + um2=um.deepCpyConnectivityOnly() + self.assertTrue(um2.isEqual(um,1e-12)) + self.assertEqual(um2.getCoords().getHiddenCppPointer(),um.getCoords().getHiddenCppPointer()) + self.assertTrue(um2.getNodalConnectivity().isEqual(um.getNodalConnectivity())) + self.assertTrue(um2.getNodalConnectivity().getHiddenCppPointer()!=um.getNodalConnectivity().getHiddenCppPointer()) + self.assertTrue(um2.getNodalConnectivityIndex().isEqual(um.getNodalConnectivityIndex())) + self.assertTrue(um2.getNodalConnectivityIndex().getHiddenCppPointer()!=um.getNodalConnectivityIndex().getHiddenCppPointer()) + # + self.assertRaises(InterpKernelException,MEDCoupling1SGTUMesh.New,"m",NORM_POLYHED) + m=MEDCoupling1DGTUMesh("m",NORM_POLYHED) + m.allocateCells(5) + self.assertEqual(15,m.getNodalConnectivity().getNbOfElemAllocated()) + self.assertEqual(6,m.getNodalConnectivityIndex().getNbOfElemAllocated()) + m.setCoords(um.getCoords()) + m.insertNextCell([1,0,6,7,-1,7,6,1]) + self.assertEqual(1,m.getNumberOfCells()) + m.insertNextCell([2,1,7,8,-1,2,1,-1,8,-1,7]) + m.insertNextCell([3,2,8,9]) + m.insertNextCell([4,3,9,10,-1,5,3,9]) + m.insertNextCell([5,4,10,11,-1,11,10,-1,5]) + m.checkCoherency() + m.checkCoherency2() + self.assertEqual(5,m.getNumberOfCells()) + self.assertTrue(m.getNodalConnectivityIndex().isEqual(DataArrayInt([0,8,19,23,31,40]))) + self.assertTrue(m.getNodalConnectivity().isEqual(DataArrayInt([1,0,6,7,-1,7,6,1,2,1,7,8,-1,2,1,-1,8,-1,7,3,2,8,9,4,3,9,10,-1,5,3,9,5,4,10,11,-1,11,10,-1,5]))) + # + m4=m.deepCpy() + self.assertTrue(m.isEqual(m4,1e-12)) + m4.getNodalConnectivity().setIJ(2,0,5) + self.assertTrue(not m.isEqual(m4,1e-12)) + m4.getNodalConnectivity().setIJ(2,0,6) + self.assertTrue(m.isEqual(m4,1e-12)) + m4.getNodalConnectivityIndex().setIJ(2,0,21) + self.assertTrue(not m.isEqual(m4,1e-12)) + m4.getNodalConnectivityIndex().setIJ(2,0,19) + self.assertTrue(m.isEqual(m4,1e-12)) + m4.getCoords().setIJ(10,1,1.1) + self.assertTrue(not m.isEqual(m4,1e-12)) + m4.getCoords().setIJ(10,1,1.) + self.assertTrue(m.isEqual(m4,1e-12)) + m4.getNodalConnectivity().pushBackSilent(7) + self.assertTrue(not m.isEqual(m4,1e-12)) + self.assertEqual(7,m4.getNodalConnectivity().popBackSilent()) + self.assertTrue(m.isEqual(m4,1e-12)) + m4.setName("m4") + self.assertTrue(not m.isEqual(m4,1e-12)) + m4.setName("m") + self.assertTrue(m.isEqual(m4,1e-12)) + # + self.assertEqual(6,m.getNodalConnectivityIndex().getNbOfElemAllocated()) + self.assertEqual(60,m.getNodalConnectivity().getNbOfElemAllocated()) + self.assertTrue(m.computeNbOfNodesPerCell().isEqual(DataArrayInt([7,8,4,7,7]))) + self.assertTrue(m.computeNbOfFacesPerCell().isEqual(DataArrayInt([2,4,1,2,3]))) + self.assertEqual(m.getNodeIdsOfCell(1),[2,1,7,8,-1,2,1,-1,8,-1,7]) + f=m.computeIsoBarycenterOfNodesPerCell() + self.assertTrue(DataArrayDouble([(0.5714285714285714,0.5714285714285714,0),(1.5,0.5,0),(2.5,0.5,0),(3.5714285714285712,0.42857142857142855,0),(4.5714285714285712,0.5714285714285714,0)]).isEqual(f,1e-14)) + mu0=m.buildUnstructured() + o2n=[1,2,0,4,3] + m2=m.deepCpy() + m3=m.deepCpyConnectivityOnly() + self.assertTrue(m3.isEqual(m,1e-12)) + self.assertEqual(m3.getCoords().getHiddenCppPointer(),m.getCoords().getHiddenCppPointer()) + self.assertTrue(m3.getNodalConnectivity().getHiddenCppPointer()!=m.getNodalConnectivity().getHiddenCppPointer()) + self.assertTrue(m3.getNodalConnectivity().isEqual(m.getNodalConnectivity())) + self.assertTrue(m3.getNodalConnectivityIndex().getHiddenCppPointer()!=m.getNodalConnectivityIndex().getHiddenCppPointer()) + self.assertTrue(m3.getNodalConnectivityIndex().isEqual(m.getNodalConnectivityIndex())) + m.renumberCells(o2n) + mu0.renumberCells(o2n) + self.assertTrue(mu0.isEqual(m.buildUnstructured(),1e-12)) + self.assertTrue(m.getNodalConnectivityIndex().isEqual(DataArrayInt([0,4,12,23,32,40]))) + self.assertTrue(m.getNodalConnectivity().isEqual(DataArrayInt([3,2,8,9,1,0,6,7,-1,7,6,1,2,1,7,8,-1,2,1,-1,8,-1,7,5,4,10,11,-1,11,10,-1,5,4,3,9,10,-1,5,3,9]))) + # + mcpy0=m.buildUnstructured() + self.assertTrue(isinstance(mcpy0,MEDCouplingUMesh)) + self.assertTrue(mcpy0.getNodalConnectivity().isEqual(DataArrayInt([31,3,2,8,9,31,1,0,6,7,-1,7,6,1,31,2,1,7,8,-1,2,1,-1,8,-1,7,31,5,4,10,11,-1,11,10,-1,5,31,4,3,9,10,-1,5,3,9]))) + self.assertTrue(mcpy0.getNodalConnectivityIndex().isEqual(DataArrayInt([0,5,14,26,36,45]))) + self.assertEqual(mcpy0.getAllGeoTypes(),[NORM_POLYHED]) + mcpy0.checkCoherency() + mcpy0.checkCoherency2() + mcpy1=mcpy0.convertIntoSingleGeoTypeMesh() + self.assertTrue(mcpy1.isEqual(m,1e-12)) + # + m_mrg=MEDCoupling1DGTUMesh.Merge1DGTUMeshes([m2,m,m2]) + self.assertTrue(m_mrg.getNodalConnectivityIndex().isEqual(DataArrayInt([0,8,19,23,31,40,44,52,63,72,80,88,99,103,111,120]))) + self.assertTrue(m_mrg.getNodalConnectivity().isEqual(DataArrayInt([1,0,6,7,-1,7,6,1,2,1,7,8,-1,2,1,-1,8,-1,7,3,2,8,9,4,3,9,10,-1,5,3,9,5,4,10,11,-1,11,10,-1,5,27,26,32,33,25,24,30,31,-1,31,30,25,26,25,31,32,-1,26,25,-1,32,-1,31,29,28,34,35,-1,35,34,-1,29,28,27,33,34,-1,29,27,33,49,48,54,55,-1,55,54,49,50,49,55,56,-1,50,49,-1,56,-1,55,51,50,56,57,52,51,57,58,-1,53,51,57,53,52,58,59,-1,59,58,-1,53]))) + m_mrg2=MEDCoupling1DGTUMesh.Merge1DGTUMeshesOnSameCoords([m3,m,m3]) + self.assertTrue(m_mrg2.getNodalConnectivityIndex().isEqual(DataArrayInt([0,8,19,23,31,40,44,52,63,72,80,88,99,103,111,120]))) + self.assertTrue(m_mrg2.getNodalConnectivity().isEqual(DataArrayInt([1,0,6,7,-1,7,6,1,2,1,7,8,-1,2,1,-1,8,-1,7,3,2,8,9,4,3,9,10,-1,5,3,9,5,4,10,11,-1,11,10,-1,5,3,2,8,9,1,0,6,7,-1,7,6,1,2,1,7,8,-1,2,1,-1,8,-1,7,5,4,10,11,-1,11,10,-1,5,4,3,9,10,-1,5,3,9,1,0,6,7,-1,7,6,1,2,1,7,8,-1,2,1,-1,8,-1,7,3,2,8,9,4,3,9,10,-1,5,3,9,5,4,10,11,-1,11,10,-1,5]))) + a,b=m_mrg2.getReverseNodalConnectivity() + self.assertTrue(b.isEqual(DataArrayInt([0,3,15,24,33,39,48,54,66,75,84,93,99,99,99,99,99,99,99,99,99,99,99,99,99]))) + self.assertTrue(a.isEqual(DataArrayInt([0,6,10,0,0,1,1,6,6,7,7,10,10,11,11,1,1,2,5,7,7,11,11,12,2,3,3,5,9,9,12,13,13,3,4,8,9,13,14,3,4,4,8,8,9,13,14,14,0,0,6,6,10,10,0,0,1,1,6,6,7,7,10,10,11,11,1,1,2,5,7,7,11,11,12,2,3,3,5,9,9,12,13,13,3,4,4,8,8,9,13,14,14,4,4,8,8,14,14]))) + self.assertTrue(m_mrg2.fillCellIdsToKeepFromNodeIds([7],False).isEqual(DataArrayInt([0,1,6,7,10,11]))) + self.assertTrue(m_mrg2.fillCellIdsToKeepFromNodeIds([0,1,6,7],True).isEqual(DataArrayInt([0,6,10]))) + # + self.assertTrue(m_mrg2.isPacked()) + self.assertEqual(120,m_mrg2.getNodalConnectivityIndex().popBackSilent()) + self.assertEqual(m_mrg2.getNumberOfCells(),14) + m_mrg2.checkCoherency2() + self.assertTrue(not m_mrg2.isPacked()) + m_mrg4,b=m_mrg2.copyWithNodalConnectivityPacked() + self.assertTrue(not b) + m_mrg4.checkCoherency2() + self.assertEqual(m_mrg4.getNumberOfCells(),14) + self.assertTrue(m_mrg4.getNodalConnectivityIndex().isEqual(m_mrg2.getNodalConnectivityIndex())) + self.assertEqual(len(m_mrg4.getNodalConnectivity()),111) + self.assertEqual(len(m_mrg2.getNodalConnectivity()),120) + self.assertTrue(m_mrg4.getNodalConnectivity().isEqual(m_mrg2.getNodalConnectivity()[:111])) + # + m0=m_mrg2[:5] + m1=m_mrg2[[5,6,7,8,9]] + m2=m_mrg2[10:] + self.assertTrue(m1.isEqualWithoutConsideringStr(m,1e-12)) + a,b=m.checkGeoEquivalWith(m0,12,1e-12) + self.assertTrue(a.isEqual(DataArrayInt(o2n))) + self.assertTrue(b is None) + pass + + def testSwig2DADAreIncludedInMe1(self): + a=DataArrayDouble(30) ; a.iota() ; a.rearrange(3) + p=DataArrayInt([5,2,1,9]) + b,c=a.areIncludedInMe(a[p],1e-12) + self.assertTrue(b) + self.assertTrue(c.isEqual(p)) + d=a[p] + d.setIJ(3,1,28.1) + b,c=a.areIncludedInMe(d,1e-12) + self.assertTrue(not b) + self.assertTrue(c.isEqual(DataArrayInt([5,2,1,10]))) + pass + + def testSwig2DADesallocate1(self): + d=DataArrayDouble([(1,2),(6,7),(6,8)]) ; d.setInfoOnComponents(["aa","bbb"]) + self.assertTrue(d.isAllocated()) + d.checkAllocated() + self.assertEqual(d.getInfoOnComponents(),["aa","bbb"]) + ref=d.getHeapMemorySize() + d.desallocate() + self.assertEqual(ref-d.getHeapMemorySize(),6*8) + self.assertTrue(not d.isAllocated()) + self.assertEqual(d.getInfoOnComponents(),["aa","bbb"]) + self.assertRaises(InterpKernelException,d.checkAllocated) + # + d=DataArrayInt([(1,2),(6,7),(6,8)]) ; d.setInfoOnComponents(["aa","bbb"]) + self.assertTrue(d.isAllocated()) + d.checkAllocated() + self.assertEqual(d.getInfoOnComponents(),["aa","bbb"]) + ref=d.getHeapMemorySize() + d.desallocate() + self.assertEqual(ref-d.getHeapMemorySize(),6*4) + self.assertTrue(not d.isAllocated()) + self.assertEqual(d.getInfoOnComponents(),["aa","bbb"]) + self.assertRaises(InterpKernelException,d.checkAllocated) + pass + + def testSwig2IsPartStructured1(self): + #dim 1 + d10=DataArrayInt([2,3,4,5,6,7,8,9,10,11]) + a,b=MEDCouplingStructuredMesh.IsPartStructured(d10,[13]) + self.assertTrue(a) ; self.assertEqual(b,[(2,12)]) + d11=DataArrayInt([2,3,4,5,6,7,8,10,9,11]) + a,b=MEDCouplingStructuredMesh.IsPartStructured(d11,[13]) + self.assertTrue(not a) + self.assertRaises(InterpKernelException,MEDCouplingStructuredMesh.IsPartStructured,d10,[11]) + #dim 2 + st=[10,4] + d20=DataArrayInt([1,2,3,4,11,12,13,14,21,22,23,24]) + a,b=MEDCouplingStructuredMesh.IsPartStructured(d20,st) + self.assertTrue(a) ; self.assertEqual(b,[(1,5),(0,3)]) + self.assertEqual(12,MEDCouplingStructuredMesh.DeduceNumberOfGivenRangeInCompactFrmt(b)) + self.assertEqual(0,MEDCouplingStructuredMesh.DeduceNumberOfGivenRangeInCompactFrmt([(1,5),(1,3),(2,2)])) + self.assertEqual(0,MEDCouplingStructuredMesh.DeduceNumberOfGivenRangeInCompactFrmt([(5,5),(3,3),(2,2)])) + self.assertEqual(36,MEDCouplingStructuredMesh.DeduceNumberOfGivenStructure([3,2,6])) + self.assertEqual(126,MEDCouplingStructuredMesh.DeduceNumberOfGivenStructure((3,7,6))) + d20=DataArrayInt([1,2,3,4,12,11,13,14,21,22,23,24]) + a,b=MEDCouplingStructuredMesh.IsPartStructured(d20,st) + self.assertTrue(not a) + d20=DataArrayInt([1,2,3,4,11,12,13,15,21,22,23,24]) + a,b=MEDCouplingStructuredMesh.IsPartStructured(d20,st) + self.assertTrue(not a) + d21=DataArrayInt([0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39]) + a,b=MEDCouplingStructuredMesh.IsPartStructured(d21,st) + self.assertTrue(a) ; self.assertEqual(b,[(0,10),(0,4)]) + d22=DataArrayInt([1,2,3,4,11,12,13,14,21,22,23,24,31,32,33,34,41,42,43,44]) + self.assertRaises(InterpKernelException,MEDCouplingStructuredMesh.IsPartStructured,d22,st) + a,b=MEDCouplingStructuredMesh.IsPartStructured(d22,[10,5]) + self.assertTrue(a) ; self.assertEqual(b,[(1,5),(0,5)]) + #dim 3 + d30=DataArrayInt([11,12,13,14,21,22,23,24,51,52,53,54,61,62,63,64]) + a,b=MEDCouplingStructuredMesh.IsPartStructured(d30,[10,4,2]) + self.assertTrue(a) ; self.assertEqual(b,[(1,5),(1,3),(0,2)]) + d31=DataArrayInt([11,12,13,14,21,22,24,23,51,52,53,54,61,62,63,64]) + a,b=MEDCouplingStructuredMesh.IsPartStructured(d31,[10,4,2]) + self.assertTrue(not a) + self.assertRaises(InterpKernelException,MEDCouplingStructuredMesh.IsPartStructured,d30,[10,4,1]) + pass + + def testSwig2PartStructured1(self): + c=MEDCouplingCMesh() ; c.setName("toto") + arr0=DataArrayDouble(10); arr0.iota() + arr1=DataArrayDouble(4) ; arr1.iota(3) + c.setCoords(arr0,arr1) + self.assertEqual(c.getNodeGridStructure(),(10,4)) + self.assertEqual(c.getCellGridStructure(),(9,3)) + d20=DataArrayInt([1,2,3,4,10,11,12,13,19,20,21,22]) + self.assertEqual(27,c.getNumberOfCells()) + self.assertEqual(40,c.getNumberOfNodes()) + self.assertEqual(2,c.getMeshDimension()) + c.checkCoherency() + # + arr2=MEDCouplingStructuredMesh.BuildExplicitIdsFrom([9,3],[(1,5),(0,3)]) + self.assertTrue(arr2.isEqual(DataArrayInt([1,2,3,4,10,11,12,13,19,20,21,22]))) + # CMesh + c2=c.buildStructuredSubPart([(1,5),(0,3)]) + c2.checkCoherency() + self.assertTrue(isinstance(c2,MEDCouplingCMesh)) + self.assertEqual(12,c2.getNumberOfCells()) + self.assertEqual(20,c2.getNumberOfNodes()) + self.assertEqual(2,c2.getMeshDimension()) + self.assertEqual("toto",c2.getName()) + self.assertTrue(c2.getCoordsAt(0).isEqual(DataArrayDouble([1.,2.,3.,4.,5.]),1e-12)) + self.assertTrue(c2.getCoordsAt(1).isEqual(DataArrayDouble([3.,4.,5.,6.]),1e-12)) + # + a,b=c.buildPartAndReduceNodes(d20) + a.checkCoherency() + exp2=DataArrayInt([-1,0,1,2,3,4,-1,-1,-1,-1,-1,5,6,7,8,9,-1,-1,-1,-1,-1,10,11,12,13,14,-1,-1,-1,-1,-1,15,16,17,18,19,-1,-1,-1,-1]) + self.assertTrue(exp2.isEqual(b)) + self.assertTrue(isinstance(a,MEDCouplingCMesh)) + self.assertTrue(a.buildUnstructured().isEqual(c.buildUnstructured().buildPartAndReduceNodes(d20)[0],1e-12)) + # CurveLinearMesh + c2=MEDCouplingCurveLinearMesh() ; c2.setName("toto") + c2.setCoords(c.buildUnstructured().getCoords()) + c2.setNodeGridStructure([10,4]) + c2.checkCoherency() + a,b=c2.buildPartAndReduceNodes(d20) + a.checkCoherency() + self.assertTrue(exp2.isEqual(b)) + self.assertTrue(isinstance(a,MEDCouplingCurveLinearMesh)) + self.assertTrue(a.buildUnstructured().isEqual(c2.buildUnstructured().buildPartAndReduceNodes(d20)[0],1e-12)) + pass + + def testSwig2FindPermutationFromFirstToSecond1(self): + ids1=DataArrayInt([3,1,103,4,6,10,-7,205]) + ids2=DataArrayInt([-7,1,205,10,6,3,103,4]) + ids3=DataArrayInt.FindPermutationFromFirstToSecond(ids1,ids2) + self.assertTrue(ids3.isEqual(DataArrayInt([5,1,6,7,4,3,0,2]))) + ids2ToTest=ids1.renumber(ids3) + self.assertTrue(ids2ToTest.isEqual(ids2)) + self.assertRaises(InterpKernelException,DataArrayInt.FindPermutationFromFirstToSecond,DataArrayInt([3,1,103]),DataArrayInt([1,103])) + self.assertRaises(InterpKernelException,DataArrayInt.FindPermutationFromFirstToSecond,DataArrayInt([3,1,103]),DataArrayInt([1,103,2])) + self.assertRaises(InterpKernelException,DataArrayInt.FindPermutationFromFirstToSecond,DataArrayInt([3,1,103]),DataArrayInt([1,103,1])) + self.assertTrue(DataArrayInt.FindPermutationFromFirstToSecond(DataArrayInt([]),DataArrayInt([])).empty()) + pass + + def testSwig2BugStructuredMeshGetNodeIdsOfCell1(self): + m=MEDCouplingCMesh("mesh") + coordsX=DataArrayDouble([0,1.1,2.2,3.3,4.4]) ; coordsX.setInfoOnComponents(["XX [m]"]) + coordsY=DataArrayDouble([0,1.7,3.4]) ; coordsY.setInfoOnComponents(["YYY [km]"]) + m.setCoords(coordsX,coordsY) + self.assertEqual([2,3,8,7],m.getNodeIdsOfCell(2)) + self.assertEqual([3,4,9,8],m.getNodeIdsOfCell(3)) + self.assertEqual([7,8,13,12],m.getNodeIdsOfCell(6)) + self.assertEqual([8,9,14,13],m.getNodeIdsOfCell(7)) + pass + + def testSwig2ThrowOnDAIInvertN2O2ON2(self): + p1=DataArrayInt([3,5,8]) + p2=DataArrayInt([0,3,4,5,6,7,8,9,10]) + p1.transformWithIndArr(p2.invertArrayN2O2O2N(11)) + self.assertTrue(p1.isEqual(DataArrayInt([1,3,6]))) + self.assertTrue(p2.invertArrayN2O2O2N(11).isEqual(DataArrayInt([0,-1,-1,1,2,3,4,5,6,7,8]))) + self.assertRaises(InterpKernelException,p2.invertArrayN2O2O2N,10) + pass + + def testSwig2ComputeEffectiveNbOfNodesPerCell1(self): + coords=DataArrayDouble([ 0.241310763507 , 0.0504777305619 , 0.0682283524903 , 0.252501053866 , -0.0625176732937 , 0.137272639894 , + 0.152262663601 , 0.241816569527 , 0.133812556197 , 0.18047750211 , -0.0789949051358 , 0.339098173401 , + 0.151741971857 , 0.238885278571 , 0.137715037333 , 0.242532155481 , -0.0928169086456 , 0.0678043417367 , + 0.240941965335 , -0.015461491464 , 0.0617186345825 , 0.24127650112 , 0.0499427876717 , 0.0679634099148 , + -0.145828917428 , 0.206291632565 , 0.0310071927543 , 0.0125651775307 , 0.266262085828 , 0.105228430543 , + -0.0994066533286 , 0.233224271238 , 0.0572213839567 , -0.0951345338317 , 0.234819509426 , 0.0592126284538 , + 0.136580574205 , -0.205486212579 , 0.0572866072014 , 0.0637270784978 , -0.168886355238 , 0.446614057077 , + 0.041337157151 , -0.213402568198 , 0.372407095999 , 0.0411601970268 , -0.202387875756 , 0.411334979491 , + -0.108355701857 , 0.193636239335 , 0.204886756738 , 0.00639779029829 , 0.155296981517 , 0.252585892979 , + 0.0262473111702 , -0.112919732543 , 0.424286639249 ,-0.224103052733 , -0.139430015438 , -0.0122352295701 , + -0.0312760589481 , -0.274272003594 , 0.0323959636568 , -0.166663422532 , -0.217754445175 , 0.00392109070364 , + -0.30586619777 , -0.0475168041091 , -0.0144585228182 , -0.280881480586 , 0.135571293538 , 0.00623923647986 , + -0.25548538234 , 0.156819217766 , 0.0645277879769 , -0.131567009284 , 0.184133752309 , 0.206021802753 , + -0.196204010965 , 0.151602971681 , 0.212974777736 , -0.183713879463 , 0.0802946639531 , 0.260115662599 , + -0.244241178767 , -0.0738873389604 , 0.144590565817 , -0.155804057829 , -0.164892720025 , 0.210613950558 , + -0.170950800428 , -0.215099334026 , 0.00610122860092 , -0.30552634869 , -0.0490020791904 , -0.0132786533145 , + 0.271831011884 , 0.15105657296 , 0.0230534827908 , 0.281919192283 , 0.0898544306288 , -0.0625201489143 , + 0.260240727276 , -0.0120688706637 , -0.0532316588626 , 0.244947737722 , 0.0197984684293 , 0.0309341209233 , + 0.23439631578 , 0.229825279875 , 0.0508520585381 , 0.160921316875 , 0.265078502128 , 0.121716560626 , + -0.315088694175 , 0.0747700471918 , -0.245836615071 , -0.327728781776 , 0.0857114674649 , -0.239431905957 , + -0.308385460634 , 0.145142997084 , -0.149886828433 , 0.0488236045164 , 0.309462801914 , 0.0849169148265 , + -0.0244964803395 , 0.33145611751 , -0.0476415818061 , 0.0060567994229 , 0.32418412014 , 0.0367779543812 , + -0.0950221448063 , 0.236675326003 , 0.0572594453983 , 0.248723023186 , 0.0886648784791 , -0.176629430538 , + 0.116796984 , 0.256596599567 , -0.292863523603 , 0.118024552914 , 0.229154257843 , -0.34233232501 , + 0.217507892549 , -0.0417822335742 , -0.176771782888 , -0.224429321304 , 0.0125595300114 , -0.362064725588 , + 0.0937301100955 , -0.0500824832657 , -0.299713548444 , -0.244162220397 , 0.0383853931293 , -0.389856984411 , + -0.0281989366102 , 0.097392811563 , -0.458244577284 , -0.385010847162 , 0.10122766194 , -0.140052859922 , + -0.377936358012 , 0.110875172128 , -0.176207095463 , 0.244483045556 , -0.0991073977045 , 0.0575134372934 , + 0.262605120167 , -0.100243191645 , -0.0495620806935 , 0.240306880972 , -0.136153701579 , -0.114745281696 , + 0.215763176129 , -0.0836766059189 , -0.183249640616 , 0.237870396603 , -0.132449578286 , -0.121598854639 , + -0.0637683083097 , -0.27921020214 , -0.149112321992 , -0.0856211014977 , -0.2973233473 , -0.0446878139589 , + 0.104675342288 , -0.0625908305324 , -0.290346256534 , 0.0248264249186 , -0.247797708548 , -0.165830884019 , + 0.0719302438309 , -0.178468260473 , -0.211432157345 , 0.142871843159 , -0.208769948542 , 0.0454101128246 , + 0.167803379307 , -0.207851396623 , -0.088802726124 , 0.12868717152 , -0.230920439715 , 0.00760508389036 , + -0.0372812069535 , -0.286740286332 , 0.00963701291166 ], 69, 3) + connN = [ #polyhedron 0 + 0 , 1 , 3 , 4 , 2 , -1 , 1 , 5 , 6 , 7 , 0 , -1 , 0 , 7 , 8 , 10 , 11 , 9 , 2 , -1 , 1 , 5 , 12 , 14 , 15 , 13 , 3 , -1 , 16 , 9 , 2 , 4 , 17 , -1 + , 4 , 3 , 13 , 18 , 17 , -1 , 5 , 6 , 19 , 21 , 20 , 12 , -1 , 6 , 7 , 8 , 23 , 22 , 19 , -1 , 23 , 24 , 10 , 8 , -1 , 25 , 11 , 9 , 16 , -1 + , 24 , 26 , 25 , 11 , 10 , -1 , 12 , 14 , 20 , -1 , 27 , 28 , 29 , 15 , 13 , 18 , -1 , 14 , 15 , 29 , 30 , 21 , 20 , -1 , 26 , 27 , 18 , 17 , 16 , 25 , -1 + , 22 , 19 , 21 , 30 , 31 , -1 , 22 , 31 , 28 , 27 , 26 , 24 , 23 , -1 , 31 , 30 , 29 , 28, + # polyhedron 1 + 0 , 7 , 8 , 10 , 11 , 9 , 2 , -1 , 32 , 0 , 7 , 35 , 34 , 33 , -1 , 32 , 0 , 2 , 37 , 36 , -1 , 35 , 7 , 8 , 40 , 39 , 38 , -1 + , 2 , 37 , 41 , 9 , -1 , 40 , 8 , 10 , 44 , 43 , 42 , -1 , 41 , 9 , 11 , 44 , 43 , -1 , 44 , 11 , 10 , -1 , 32 , 33 , 45 , 47 , 46 , 36 , -1 + , 33 , 34 , 48 , 45 , -1 , 35 , 34 , 48 , 50 , 49 , 38 , -1 , 41 , 43 , 42 , 46 , 36 , 37 , -1 , 38 , 39 , 51 , 49 , -1 + , 39 , 40 , 42 , 46 , 47 , 52 , 51 , -1 , 45 , 47 , 52 , 50 , 48 , -1 , 52 , 51 , 49 , 50, + # polyhedron 2 + 6 , 7 , 8 , 23 , 22 , 19 , -1 , 6 , 35 , 7 , -1 , 6 , 35 , 38 , 19 , -1 , 35 , 7 , 8 , 40 , 39 , 38 , -1 , 53 , 22 , 19 , 38 , 39 , 54 , -1 + , 23 , 53 , 54 , 40 , 8 , -1 , 53 , 22 , 23 , -1 , 39 , 54 , 40, + # polyhedron 3 + 35 , 34 , 48 , 50 , 49 , 38 , -1 , 6 , 35 , 34 , 56 , 55 , 5 , -1 , 6 , 35 , 38 , 19 , -1 , 34 , 56 , 57 , 59 , 58 , 48 , -1 + , 60 , 61 , 21 , 19 , 38 , 49 , -1 , 62 , 50 , 48 , 58 , -1 , 60 , 63 , 64 , 62 , 50 , 49 , -1 , 5 , 6 , 19 , 21 , 20 , 12 , -1 + , 55 , 5 , 12 , 65 , -1 , 66 , 67 , 65 , 55 , 56 , 57 , -1 , 63 , 66 , 57 , 59 , 64 , -1 , 64 , 62 , 58 , 59 , -1 + , 60 , 63 , 66 , 67 , 68 , 61 , -1 , 61 , 68 , 20 , 21 , -1 , 67 , 68 , 20 , 12 , 65] + meshN=MEDCouplingUMesh.New() + meshN.setName("ForBary") + meshN.setMeshDimension(3) ; meshN.setCoords(coords) + meshN.allocateCells(4) + meshN.insertNextCell(NORM_POLYHED,113,connN); + meshN.insertNextCell(NORM_POLYHED,99,connN[113:]) + meshN.insertNextCell(NORM_POLYHED,43,connN[212:]) + meshN.insertNextCell(NORM_POLYHED,92,connN[255:]) + d=meshN.computeEffectiveNbOfNodesPerCell() + e=meshN.computeNbOfNodesPerCell() + self.assertTrue(d.isEqual(DataArrayInt([32,28,12,26]))) + self.assertTrue(e.isEqual(DataArrayInt([96,84,36,78]))) + m0=MEDCoupling1DGTUMesh(meshN) + c=MEDCouplingCMesh() + arr=DataArrayDouble(3) ; arr.iota(10) + c.setCoords(arr,arr,arr) + m10=c.buildUnstructured() + m11=c.build1SGTUnstructured() + m12=MEDCoupling1SGTUMesh.New(m10) + self.assertTrue(m12.isEqual(m11,1e-12)) + m12.setCoords(m0.getCoords()) # m12 is not OK geometrically but the aim of the test is only connectivity values + m3=MEDCoupling1GTUMesh.AggregateOnSameCoordsToUMesh([m12,m0]) + m3.checkCoherency() + self.assertEqual(m3.getCoords().getHiddenCppPointer(),m12.getCoords().getHiddenCppPointer()) + self.assertTrue(m3.getNodalConnectivity().isEqual(DataArrayInt([18,1,0,3,4,10,9,12,13,18,2,1,4,5,11,10,13,14,18,4,3,6,7,13,12,15,16,18,5,4,7,8,14,13,16,17,18,10,9,12,13,19,18,21,22,18,11,10,13,14,20,19,22,23,18,13,12,15,16,22,21,24,25,18,14,13,16,17,23,22,25,26,31,0,1,3,4,2,-1,1,5,6,7,0,-1,0,7,8,10,11,9,2,-1,1,5,12,14,15,13,3,-1,16,9,2,4,17,-1,4,3,13,18,17,-1,5,6,19,21,20,12,-1,6,7,8,23,22,19,-1,23,24,10,8,-1,25,11,9,16,-1,24,26,25,11,10,-1,12,14,20,-1,27,28,29,15,13,18,-1,14,15,29,30,21,20,-1,26,27,18,17,16,25,-1,22,19,21,30,31,-1,22,31,28,27,26,24,23,-1,31,30,29,28,31,0,7,8,10,11,9,2,-1,32,0,7,35,34,33,-1,32,0,2,37,36,-1,35,7,8,40,39,38,-1,2,37,41,9,-1,40,8,10,44,43,42,-1,41,9,11,44,43,-1,44,11,10,-1,32,33,45,47,46,36,-1,33,34,48,45,-1,35,34,48,50,49,38,-1,41,43,42,46,36,37,-1,38,39,51,49,-1,39,40,42,46,47,52,51,-1,45,47,52,50,48,-1,52,51,49,50,31,6,7,8,23,22,19,-1,6,35,7,-1,6,35,38,19,-1,35,7,8,40,39,38,-1,53,22,19,38,39,54,-1,23,53,54,40,8,-1,53,22,23,-1,39,54,40,31,35,34,48,50,49,38,-1,6,35,34,56,55,5,-1,6,35,38,19,-1,34,56,57,59,58,48,-1,60,61,21,19,38,49,-1,62,50,48,58,-1,60,63,64,62,50,49,-1,5,6,19,21,20,12,-1,55,5,12,65,-1,66,67,65,55,56,57,-1,63,66,57,59,64,-1,64,62,58,59,-1,60,63,66,67,68,61,-1,61,68,20,21,-1,67,68,20,12,65]))) + self.assertTrue(m3.getNodalConnectivityIndex().isEqual(DataArrayInt([0,9,18,27,36,45,54,63,72,186,286,330,423]))) + pass + + def testSwig2Tetrahedrize1(self): + d=DataArrayInt([0,3,6,10,14,20]) + d2=d.buildExplicitArrOfSliceOnScaledArr(slice(0,5,2)) + self.assertTrue(d2.isEqual(DataArrayInt([0,0,0, 2,2,2,2, 4,4,4,4,4,4]))) + m=MEDCouplingUMesh("Penta6",3) + m.setCoords(DataArrayDouble([0,0,0,0,1,0,1,0,0,0,0,2,0,1,2,1,0,2],6,3)) ; m.getCoords().setInfoOnComponents(["X","YY","ZZZ"]) + m.allocateCells() + m.insertNextCell(NORM_PENTA6,[1,2,0,4,5,3]) + st=m.getCoords().getHiddenCppPointer() + c,a,b=m.tetrahedrize(PLANAR_FACE_5) + c.checkCoherency2() + self.assertTrue(a.isEqual(DataArrayInt([0,0,0]))) + self.assertEqual(0,b) + self.assertEqual(m.getCoords().getHiddenCppPointer(),c.getCoords().getHiddenCppPointer()) + self.assertTrue(c.getNodalConnectivity().isEqual(DataArrayInt([1,2,0,4,4,3,5,0,5,0,2,4]))) + del m,c + # + m2=MEDCouplingUMesh("octa12",3) + coords=DataArrayDouble([1.,0.,0.,0.5,0.8660254037844386,0.,-0.5,0.8660254037844387,0.,-1.,1.2246467991473532e-16,0.,-0.5,-0.8660254037844384,0.,0.5,-0.866025403784439,0.,1.,0.,2.,0.5,0.8660254037844386,2.,-0.5,0.8660254037844387,2.,-1.,1.2246467991473532e-16,2.,-0.5,-0.8660254037844384,2.,0.5,-0.866025403784439,2.0],12,3) + m2.setCoords(coords) + m2.allocateCells() + m2.insertNextCell(NORM_HEXGP12,[3,2,1,0,5,4,9,8,7,6,11,10]) + c,a,b=m2.tetrahedrize(PLANAR_FACE_5) + c.checkCoherency2() + self.assertTrue(a.isEqual(DataArrayInt([0,0,0,0,0,0,0,0,0,0,0,0]))) + self.assertEqual(0,b) + self.assertEqual(c.getCoords().getHiddenCppPointer(),coords.getHiddenCppPointer()) + self.assertTrue(c.getNodalConnectivity().isEqual(DataArrayInt([3,2,4,9,9,10,8,4,8,4,2,9,2,5,4,8,8,10,11,4,11,4,5,8,2,1,5,8,8,11,7,5,7,5,1,8,1,0,5,7,7,11,6,5,6,5,0,7]))) + del m2,coords,c + # + coords=DataArrayDouble([0.,0.,0.,1.,0.,0.,1.,1.,0.,0.,1.,0.,0.,0.,2.,1.,0.,2.,1.,1.,2.,0.,1.,2.],8,3) ; coords.setInfoOnComponents(["X","YY","ZZZ"]) + m3=MEDCouplingUMesh("hexa8",3) + m3.setCoords(coords) + m3.allocateCells(0) + m3.insertNextCell(NORM_HEXA8,[3,2,1,0,7,6,5,4]) + st=m3.getCoords().getHiddenCppPointer() + c,a,b=m3.tetrahedrize(PLANAR_FACE_5) + c.checkCoherency2() + a.isEqual(DataArrayInt([0,0,0,0,0])) + self.assertEqual(0,b) + self.assertEqual(m3.getCoords().getHiddenCppPointer(),coords.getHiddenCppPointer()) + self.assertTrue(c.getNodalConnectivity().isEqual(DataArrayInt([3,6,2,1,3,7,6,4,3,0,4,1,6,4,5,1,3,6,1,4]))) + # + m4=MEDCouplingUMesh("hexa8",3) + m4.setCoords(coords) + m4.allocateCells(0) + m4.insertNextCell(NORM_HEXA8,[3,2,1,0,7,6,5,4]) + c,a,b=m4.tetrahedrize(PLANAR_FACE_6) + c.checkCoherency2() + a.isEqual(DataArrayInt([0,0,0,0,0,0])) + self.assertEqual(0,b) + self.assertEqual(c.getCoords().getHiddenCppPointer(),coords.getHiddenCppPointer()) + self.assertTrue(c.getNodalConnectivity().isEqual(DataArrayInt([3,6,2,5,3,2,1,5,3,7,6,5,3,4,7,5,3,1,0,5,3,0,4,5]))) + # + m4=MEDCouplingUMesh("hexa8",3) + m4.setCoords(coords) + m4.allocateCells(0) + m4.insertNextCell(NORM_HEXA8,[3,2,1,0,7,6,5,4]) + st=m4.getCoords().getHiddenCppPointer() + c,a,b=m4.tetrahedrize(GENERAL_24) + c.checkCoherency2() + a.isEqual(DataArrayInt([0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0])) + self.assertEqual(7,b) + self.assertTrue(c.getCoords().getHiddenCppPointer()!=coords.getHiddenCppPointer()) + self.assertTrue(c.getCoords()[:8].isEqual(coords,0)) + self.assertTrue(c.getNodalConnectivity().isEqual(DataArrayInt([3,7,8,14,7,6,8,14,6,2,8,14,2,3,8,14,3,2,9,14,2,1,9,14,1,0,9,14,0,3,9,14,3,0,10,14,0,4,10,14,4,7,10,14,7,3,10,14,2,6,11,14,6,5,11,14,5,1,11,14,1,2,11,14,7,4,12,14,4,5,12,14,5,6,12,14,6,7,12,14,1,5,13,14,5,4,13,14,4,0,13,14,0,1,13,14]))) + m4CoordsExp=DataArrayDouble([0.,0.,0.,1.,0.,0.,1.,1.,0.,0.,1.,0.,0.,0.,2.,1.,0.,2.,1.,1.,2.,0.,1.,2.,0.5,1.,1.,0.5,0.5,0.,0.,0.5,1.,1.,0.5,1.,0.5,0.5,2.,0.5,0.,1.,0.5,0.5,1.],15,3) + m4CoordsExp.setInfoOnComponents(["X","YY","ZZZ"]) + self.assertTrue(c.getCoords().isEqual(m4CoordsExp,1e-12)) + self.assertAlmostEqual(2.,c.getMeasureField(False).accumulate()[0],12) + # + m6=MEDCouplingUMesh("hexa8",3) + m6.setCoords(coords) + m6.allocateCells(0) + m6.insertNextCell(NORM_HEXA8,[3,2,1,0,7,6,5,4]) + st=m6.getCoords().getHiddenCppPointer() + c,a,b=m6.tetrahedrize(GENERAL_48) + c.checkCoherency2() + a.isEqual(DataArrayInt([0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0])) + self.assertEqual(19,b) + self.assertTrue(c.getCoords().getHiddenCppPointer()!=coords.getHiddenCppPointer()) + self.assertTrue(c.getCoords()[:8].isEqual(coords,0)) + self.assertTrue(c.getNodalConnectivity().isEqual(DataArrayInt([3,20,8,26,3,8,21,26,3,9,20,26,3,22,9,26,3,21,12,26,3,12,22,26,8,10,2,23,8,2,13,23,8,20,10,23,8,26,20,23,8,13,21,23,8,21,26,23,12,26,21,25,12,21,16,25,12,22,26,25,12,17,22,25,12,16,0,25,12,0,17,25,21,23,13,18,21,13,1,18,21,26,23,18,21,25,26,18,21,1,16,18,21,16,25,18,9,11,20,24,9,20,26,24,9,7,11,24,9,14,7,24,9,26,22,24,9,22,14,24,20,6,10,15,20,10,23,15,20,11,6,15,20,24,11,15,20,23,26,15,20,26,24,15,22,24,26,19,22,26,25,19,22,14,24,19,22,4,14,19,22,25,17,19,22,17,4,19,26,15,23,5,26,23,18,5,26,24,15,5,26,19,24,5,26,18,25,5,26,25,19,5]))) + m6CoordsExp=DataArrayDouble([0.,0.,0.,1.,0.,0.,1.,1.,0.,0.,1.,0.,0.,0.,2.,1.,0.,2.,1.,1.,2.,0.,1.,2.,0.5,1.,0.,0.,1.,1.,1.,1.,1.,0.5,1.,2.,0.,0.5,0.,1.,0.5,0.,0.,0.5,2.,1.,0.5,2.,0.5,0.,0.,0.,0.,1.,1.,0.,1.,0.5,0.,2.,0.5,1.,1.,0.5,0.5,0.,0.,0.5,1.,1.,0.5,1.,0.5,0.5,2.,0.5,0.,1.,0.5,0.5,1.],27,3) + m6CoordsExp.setInfoOnComponents(["X","YY","ZZZ"]) + self.assertTrue(c.getCoords().isEqual(m6CoordsExp,1e-12)) + self.assertAlmostEqual(2.,c.getMeasureField(False).accumulate()[0],12) + # + m7=MEDCouplingUMesh("polyhed",3) + coords=DataArrayDouble([1.,0.,0.,0.5,0.8660254037844386,0.,-0.5,0.8660254037844387,0.,-1.,0.,0.,-0.5,-0.8660254037844384,0.,0.5,-0.866025403784439,0.,1.,0.,2.,0.5,0.8660254037844386,2.,-0.5,0.8660254037844387,2.,-1.,0.,2.,-0.5,-0.8660254037844384,2.,0.5,-0.866025403784439,2.0],12,3) ; coords.setInfoOnComponents(["X","YY","ZZZ"]) + m7.setCoords(coords) + m7.allocateCells() + m7.insertNextCell(NORM_POLYHED,[3,2,1,0,5,4,-1,9,10,11,6,7,8,-1,3,9,8,2,-1,2,8,7,1,-1,1,7,6,0,-1,0,6,11,5,-1,5,11,10,4,-1,4,10,9,3]) + c,a,b=m7.tetrahedrize(PLANAR_FACE_5) + c.checkCoherency2() + self.assertTrue(a.isEqual(DataArrayInt([0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]))) + self.assertEqual(9,b) + self.assertTrue(c.getNodalConnectivity().isEqual(DataArrayInt([3,2,12,20,2,1,12,20,1,0,12,20,0,5,12,20,5,4,12,20,4,3,12,20,9,10,13,20,10,11,13,20,11,6,13,20,6,7,13,20,7,8,13,20,8,9,13,20,3,9,14,20,9,8,14,20,8,2,14,20,2,3,14,20,2,8,15,20,8,7,15,20,7,1,15,20,1,2,15,20,1,7,16,20,7,6,16,20,6,0,16,20,0,1,16,20,0,6,17,20,6,11,17,20,11,5,17,20,5,0,17,20,5,11,18,20,11,10,18,20,10,4,18,20,4,5,18,20,4,10,19,20,10,9,19,20,9,3,19,20,3,4,19,20]))) + self.assertAlmostEqual(5.196152422706635,c.getMeasureField(False).accumulate()[0],12) + m7CoordsExp=DataArrayDouble([1.0,0.0,0.0,0.5,0.8660254037844386,0.0,-0.5,0.8660254037844387,0.0,-1.0,0.,0.0,-0.5,-0.8660254037844384,0.0,0.5,-0.866025403784439,0.0,1.0,0.0,2.0,0.5,0.8660254037844386,2.0,-0.5,0.8660254037844387,2.0,-1.0,0.,2.0,-0.5,-0.8660254037844384,2.0,0.5,-0.866025403784439,2.0,0.0,0.0,0.0,0.0,0.,2.0,-0.75,0.4330127018922194,1.0,0.0,0.8660254037844386,1.0,0.75,0.4330127018922193,1.0,0.75,-0.4330127018922195,1.0,0.0,-0.8660254037844387,1.0,-0.75,-0.4330127018922191,1.0,0.0,0.,1.0],21,3) + m7CoordsExp.setInfoOnComponents(["X","YY","ZZZ"]) + self.assertTrue(c.getCoords().isEqual(m7CoordsExp,1e-12)) + del m7,coords,c + # + coords=DataArrayDouble([0.,0.,0.,1.,0.,0.,1.,1.,0.,0.,1.,0.,0.,0.,2.,1.,0.,2.,1.,1.,2.,0.,1.,2.],8,3) ; coords.setInfoOnComponents(["X","YY","ZZZ"]) + m8=MEDCouplingUMesh("pyra5",3) + m8.setCoords(coords) + m8.allocateCells(0) + m8.insertNextCell(NORM_PYRA5,[3,2,1,0,7]) + st=m8.getCoords().getHiddenCppPointer() + c,a,b=m8.tetrahedrize(PLANAR_FACE_5) + self.assertEqual(m8.getCoords().getHiddenCppPointer(),coords.getHiddenCppPointer()) + c.checkCoherency2() + self.assertTrue(a.isEqual(DataArrayInt([0,0]))) + self.assertEqual(0,b) + self.assertTrue(c.getNodalConnectivity().isEqual(DataArrayInt([3,2,1,7,3,1,0,7]))) + self.assertAlmostEqual(0.6666666666666667,c.getMeasureField(False).accumulate()[0],12) + pass + + def testDualMesh3D1(self): + arr=DataArrayDouble(2) ; arr.iota() + c=MEDCouplingCMesh() ; c.setCoords(arr,arr,arr) + m=c.buildUnstructured() + t=m.tetrahedrize(PLANAR_FACE_5)[0] + d=t.computeDualMesh() + self.assertTrue(d.getNodalConnectivityIndex().isEqual(DataArrayInt([0,29,118,207,236,325,354,383,472]))) + self.assertTrue(d.getNodalConnectivity().isEqual(DataArrayInt([26,11,42,8,-1,25,8,42,10,-1,29,10,42,11,-1,0,26,8,25,-1,0,25,10,29,-1,0,29,11,26,24,9,42,8,-1,26,8,42,11,-1,27,11,42,9,-1,1,24,8,26,-1,1,26,11,27,-1,30,13,43,12,-1,24,12,43,15,-1,32,15,43,13,-1,1,30,12,24,-1,1,32,13,30,-1,35,17,44,16,-1,32,16,44,19,-1,27,19,44,17,-1,1,35,16,32,-1,1,27,17,35,-1,24,15,46,9,-1,27,9,46,19,-1,32,19,46,15,27,9,42,11,-1,29,11,42,10,-1,28,10,42,9,-1,2,29,10,28,-1,2,27,11,29,-1,27,17,44,19,-1,38,19,44,18,-1,37,18,44,17,-1,2,37,17,27,-1,2,38,18,37,-1,28,21,45,23,-1,41,23,45,22,-1,38,22,45,21,-1,2,41,22,38,-1,2,28,23,41,-1,27,19,46,9,-1,28,9,46,21,-1,38,21,46,19,35,16,44,17,-1,36,18,44,16,-1,37,17,44,18,-1,3,36,16,35,-1,3,35,17,37,-1,3,37,18,36,24,8,42,9,-1,25,10,42,8,-1,28,9,42,10,-1,4,25,8,24,-1,4,28,10,25,-1,24,15,43,12,-1,31,12,43,14,-1,34,14,43,15,-1,4,24,12,31,-1,4,31,14,34,-1,34,21,45,20,-1,40,20,45,23,-1,28,23,45,21,-1,4,34,20,40,-1,4,40,23,28,-1,24,9,46,15,-1,28,21,46,9,-1,34,15,46,21,30,12,43,13,-1,31,14,43,12,-1,33,13,43,14,-1,5,31,12,30,-1,5,30,13,33,-1,5,33,14,31,40,23,45,20,-1,39,20,45,22,-1,41,22,45,23,-1,6,40,20,39,-1,6,39,22,41,-1,6,41,23,40,32,13,43,15,-1,34,15,43,14,-1,33,14,43,13,-1,7,33,13,32,-1,7,34,14,33,-1,32,19,44,16,-1,36,16,44,18,-1,38,18,44,19,-1,7,32,16,36,-1,7,36,18,38,-1,34,20,45,21,-1,39,22,45,20,-1,38,21,45,22,-1,7,39,20,34,-1,7,38,22,39,-1,32,15,46,19,-1,38,19,46,21,-1,34,21,46,15]))) + self.assertTrue(d.getCoords().isEqual(DataArrayDouble([0.,0.,0.,1.,0.,0.,0.,1.,0.,1.,1.,0.,0.,0.,1.,1.,0.,1.,0.,1.,1.,1.,1.,1.,0.3333333333333333,0.,0.3333333333333333,0.3333333333333333,0.3333333333333333,0.3333333333333333,0.,0.3333333333333333,0.3333333333333333,0.3333333333333333,0.3333333333333333,0.,0.6666666666666666,0.,0.6666666666666666,1.,0.3333333333333333,0.6666666666666666,0.6666666666666666,0.3333333333333333,1.,0.6666666666666666,0.3333333333333333,0.6666666666666666,1.,0.6666666666666666,0.3333333333333333,0.6666666666666666,0.6666666666666666,0.,0.6666666666666666,1.,0.3333333333333333,0.6666666666666666,0.6666666666666666,0.3333333333333333,0.3333333333333333,0.6666666666666666,1.,0.3333333333333333,0.6666666666666666,0.6666666666666666,0.3333333333333333,1.,0.6666666666666666,0.,0.6666666666666666,0.6666666666666666,0.5,0.,0.5,0.,0.,0.5,0.5,0.,0.,0.5,0.5,0.,0.,0.5,0.5,0.,0.5,0.,1.,0.,0.5,0.5,0.,1.,1.,0.5,0.5,1.,0.5,1.,0.5,0.5,1.,1.,0.5,0.,1.,1.,0.5,0.5,1.,0.,0.5,1.,0.5,0.5,1.,1.,0.,0.5,1.,0.,1.,0.5,0.25,0.25,0.25,0.75,0.25,0.75,0.75,0.75,0.25,0.25,0.75,0.75,0.5,0.5,0.5],47,3),1e-12)) + self.assertAlmostEqual(1.,d.getMeasureField(False).accumulate()[0],1e-13) + pass + + def testDualMesh2D1(self): + arr=DataArrayDouble(5) ; arr.iota() + c=MEDCouplingCMesh() ; c.setCoords(arr,arr) + m=c.buildUnstructured() + m.simplexize(0) + t=MEDCoupling1SGTUMesh(m) + d=t.computeDualMesh() + self.assertTrue(d.getNodalConnectivityIndex().isEqual(DataArrayInt([0,4,12,20,28,34,42,54,66,78,86,94,106,118,130,138,146,158,170,182,190,196,204,212,220,224]))) + self.assertTrue(d.getNodalConnectivity().isEqual(DataArrayInt([26,81,25,0,25,81,27,82,29,83,30,1,30,83,31,84,33,85,34,2,34,85,35,86,37,87,38,3,38,87,39,88,41,4,27,81,26,5,42,89,28,82,29,82,28,89,43,90,45,91,32,84,31,83,33,84,32,91,46,92,48,93,36,86,35,85,37,86,36,93,49,94,51,95,40,88,39,87,41,88,40,95,52,96,54,9,43,89,42,10,55,97,44,90,45,90,44,97,56,98,58,99,47,92,46,91,48,92,47,99,59,100,61,101,50,94,49,93,51,94,50,101,62,102,64,103,53,96,52,95,54,96,53,103,65,104,67,14,56,97,55,15,68,105,57,98,58,98,57,105,69,106,71,107,60,100,59,99,61,100,60,107,72,108,74,109,63,102,62,101,64,102,63,109,75,110,77,111,66,104,65,103,67,104,66,111,78,112,80,19,69,105,68,20,70,106,71,106,70,21,73,108,72,107,74,108,73,22,76,110,75,109,77,110,76,23,79,112,78,111,80,112,79,24]))) + self.assertTrue(d.getCoords().isEqual(DataArrayDouble([0.,0.,1.,0.,2.,0.,3.,0.,4.,0.,0.,1.,1.,1.,2.,1.,3.,1.,4.,1.,0.,2.,1.,2.,2.,2.,3.,2.,4.,2.,0.,3.,1.,3.,2.,3.,3.,3.,4.,3.,0.,4.,1.,4.,2.,4.,3.,4.,4.,4.,0.5,0.,0.,0.5,0.5,0.5,0.5,1.,1.,0.5,1.5,0.,1.5,0.5,1.5,1.,2.,0.5,2.5,0.,2.5,0.5,2.5,1.,3.,0.5,3.5,0.,3.5,0.5,3.5,1.,4.,0.5,0.,1.5,0.5,1.5,0.5,2.,1.,1.5,1.5,1.5,1.5,2.,2.,1.5,2.5,1.5,2.5,2.,3.,1.5,3.5,1.5,3.5,2.,4.,1.5,0.,2.5,0.5,2.5,0.5,3.,1.,2.5,1.5,2.5,1.5,3.,2.,2.5,2.5,2.5,2.5,3.,3.,2.5,3.5,2.5,3.5,3.,4.,2.5,0.,3.5,0.5,3.5,0.5,4.,1.,3.5,1.5,3.5,1.5,4.,2.,3.5,2.5,3.5,2.5,4.,3.,3.5,3.5,3.5,3.5,4.,4.,3.5,0.3333333333333333,0.3333333333333333,0.6666666666666666,0.6666666666666666,1.3333333333333333,0.3333333333333333,1.6666666666666665,0.6666666666666666,2.333333333333333,0.3333333333333333,2.6666666666666665,0.6666666666666666,3.333333333333333,0.3333333333333333,3.6666666666666665,0.6666666666666666,0.3333333333333333,1.3333333333333333,0.6666666666666666,1.6666666666666665,1.3333333333333333,1.3333333333333333,1.6666666666666665,1.6666666666666665,2.333333333333333,1.3333333333333333,2.6666666666666665,1.6666666666666665,3.333333333333333,1.3333333333333333,3.6666666666666665,1.6666666666666665,0.3333333333333333,2.333333333333333,0.6666666666666666,2.6666666666666665,1.3333333333333333,2.333333333333333,1.6666666666666665,2.6666666666666665,2.333333333333333,2.333333333333333,2.6666666666666665,2.6666666666666665,3.333333333333333,2.333333333333333,3.6666666666666665,2.6666666666666665,0.3333333333333333,3.333333333333333,0.6666666666666666,3.6666666666666665,1.3333333333333333,3.333333333333333,1.6666666666666665,3.6666666666666665,2.333333333333333,3.333333333333333,2.6666666666666665,3.6666666666666665,3.333333333333333,3.333333333333333,3.6666666666666665,3.6666666666666665],113,2),1e-12)) + self.assertAlmostEqual(16.,d.getMeasureField(False).accumulate()[0],1e-13) + pass + + def testSwig2LoadBalanceBBox1(self): + arr=DataArrayDouble(5) ; arr.iota() + t=MEDCouplingCMesh() ; t.setCoords(arr,arr) + arr=DataArrayDouble(16) ; arr.iota() ; arr*=2./15 + s=MEDCouplingCMesh() ; s.setCoords(arr,arr[:]) ; s.translate([2.,1.]) + # + s1=s.build1SGTUnstructured() + t1=t.build1SGTUnstructured() + w=MEDCouplingPointSet.ComputeNbOfInteractionsWithSrcCells(s1,t1,1e-12) + wExp=DataArrayInt([0,0,0,0,0,0,64,64,0,0,64,64,0,0,0,0]) + self.assertTrue(w.isEqual(wExp)) + slcs=w.splitInBalancedSlices(4) + self.assertEqual(len(slcs),4) + self.assertEqual(slcs,[slice(0,7,1),slice(7,8,1),slice(8,11,1),slice(11,16,1)]) + bbs=s1.getBoundingBoxForBBTree() + bbt=t1.getBoundingBoxForBBTree() + self.assertTrue(bbt.computeNbOfInteractionsWith(bbs,1e-12).isEqual(wExp)) + pass + + def testKrSpatialDiscretization2(self): + srcPointCoordsXY=DataArrayDouble([0.8401877171547095,0.39438292681909304,0.7830992237586059,0.7984400334760733,0.9116473579367843,0.19755136929338396,0.335222755714889,0.768229594811904,0.2777747108031878,0.5539699557954305,0.47739705186216025,0.6288709247619244,0.36478447279184334,0.5134009101956155,0.9522297251747128,0.9161950680037007,0.6357117279599009,0.7172969294326831,0.14160255535580338,0.6069688762570586,0.01630057162432958,0.24288677062973696,0.13723157678601872,0.8041767542269904,0.15667908925408455,0.4009443942461835,0.12979044678145574,0.10880880202576929,0.998924518003559,0.21825690531090688,0.5129323944043984,0.8391122346926072,0.6126398325956612,0.29603161769734304,0.6375522677030192,0.5242871900667843,0.493582986990727,0.9727750238835695,0.29251678441302703,0.7713576977939148,0.5267449792133388,0.7699138362751873,0.4002286220901779,0.8915294520051822,0.2833147460051415,0.3524583472648907,0.8077245200088827,0.9190264739650424,0.06975527623191256,0.9493270753646861,0.5259953502221011,0.08605584785624214,0.19221384599442307,0.6632269270081198,0.8902326025488938,0.3488929352485076,0.06417132078864207,0.02002304886468828,0.4577017372742769,0.06309583832653977,0.23827995417559517,0.9706341316786754,0.9022080734848082,0.8509197867712563,0.2666657493760184,0.5397603407221662,0.3752069763723793,0.7602487363667454,0.5125353641400744,0.6677237607854063,0.5316064341606602,0.039280343353413204,0.4376375965949323,0.9318350562508382,0.9308097953585953,0.7209523430657351,0.28429340305006756,0.7385343149018168,0.6399788165651163,0.3540486797476414,0.687861390266503,0.16597416632155615,0.4401045276038835,0.880075236260926,0.829201093329676,0.3303371296871161,0.22896817104377232,0.8933724145839793,0.35036017855180435,0.6866699083180492,0.9564682529105192,0.5886401331930609,0.6573040395310633,0.8586763259296661,0.4395599194986559,0.9239697889070817,0.39843666665183225,0.8147668963366965,0.6842185252738271,0.9109720307919067,0.4824906566564416,0.21582495896882609,0.9502523741453198,0.9201282537170352,0.14766001475400292,0.8810621695039152,0.641080596317109,0.43195341826973177,0.6195964839400707,0.281059412416564,0.7860020980173732,0.3074578737409124,0.44703357920378145,0.22610662515559543,0.18753310953617705,0.27623467206779617,0.5564437553083728,0.4165012805799494,0.16960708618611428,0.9068039338601771,0.10317118843233734,0.1260753390966334,0.49544406658757667,0.7604752284290619,0.9847516650262995,0.9350039865518939,0.6844450168704823,0.3831883312124705,0.7497708824229291,0.36866354167864823,0.2941603620043771,0.2322615386137094,0.5844885006474743,0.24441273568403568,0.15238979186508328,0.7321485158671385,0.12547490472228962,0.7934703881821923,0.164101933671209,0.7450713891280216,0.07452980059875632,0.9501040316885822,0.05252926240327268,0.5215633798025378,0.1762106563785163,0.24006237240511102,0.797798051870334,0.732654411686889,0.6565636529850605,0.9674051385221095,0.6394583455470663,0.7597348418830591,0.09348047715308166,0.13490241166898162,0.5202100698464597,0.07823214171371988,0.06990639775521419,0.2046550862512808,0.4614204733918516,0.8196772801781433,0.5733186283955903,0.7555808353962288,0.05193881879185271,0.1578071285774033,0.9999935710802644,0.204328610656936,0.8899556444445419,0.12546847580255405,0.9977989993047895,0.054057577650089554,0.8705398649305757,0.07232879943788462,0.004161608873010431,0.9230691273338484,0.5938921792404224,0.180372265717188,0.16313149927329806,0.3916902306450951,0.9130266774040771,0.8196951527240198,0.35909536870154335,0.552485022485482,0.5794299941414176,0.452575845854625,0.687387434620125,0.09964006352221597,0.5308079880340062,0.7572938323753392,0.30429514977349675,0.9922284614258579,0.5769711125534824,0.877613778169087,0.7478092963564253,0.6289099313453351,0.03542090674649035,0.7478028669710285,0.8332385420022712,0.9253765511910322,0.8732713427735824,0.8310375408413995],100,2) + srcFieldValsOnPoints=DataArrayDouble([0.7643742528498438,-0.023507696856211995,1.1082895131907775,0.6299357452572031,0.8892623544912389,0.72212114810697,0.9196401044320336,-0.759961711221917,0.40801932617748826,0.8441134300809151,0.982483804252809,0.6752368914020778,0.9924403977479798,1.1063334970204484,0.9403055261137516,0.3624481886322733,1.1344772505996308,0.7522965618948239,0.17077741651388564,0.6504551671311436,0.45843479588425423,0.41098905950326753,1.0681420394050904,-0.3483587903820091,0.5620151050607809,1.384969776596035,0.7948875141132845,0.7931192000237167,1.062498042490183,1.3709072529577366,0.44929346605311893,-0.4469683401788374,0.9035857424514101,0.6137249300593463,0.6355610879026966,1.4318174829507697,0.3097567072129551,-0.20515052260807165,0.6922559820922779,1.0341638749443423,1.3072652153341024,0.38511367353000436,0.9160514929274943,0.54513408530581,0.722252267913328,0.06684522818576251,0.10571899758067793,0.3193844999960903,0.5213532270828706,-0.04834998649603944,1.2408805068350615,-0.7632951295676795,0.5980054665011202,0.9064738717547436,1.1541070755096696,1.008234260272265,1.2225806960553827,1.0788560195121106,0.9818990282104452,0.5621951325841853,1.0796757508374188,0.5082872315589883,-0.9153702001062469,0.9560418838920791,0.9251098559152824,1.1603063610984021,1.2122303611181837,0.7379539363312343,0.6877611899207183,0.723966552446608,0.5596025827162566,0.8849725005989729,1.0908363665075547,0.08956512916455672,-0.10247645571248344,0.3236718069555875,1.069478546398975,1.3900071080692746,1.0322398863403262,0.45315515354558034,0.4249870238786733,1.030226761858634,0.974024629584669,1.2838885424020365,1.3451943506525155,1.4029933267831995,0.6025539675442462,1.2947650597767038,1.0006061239483002,-0.4017336259949164,0.8771165113201297,0.9158909024218246,1.403798605551443,0.4742904006425974,0.3671787905896653,0.20646491720419674,0.40739337434288925,0.7341932402033597,-0.4295893651836911,-0.3187777570661546],100,1) + targetPointCoordsXY=DataArrayDouble([-0.5,-0.5,-0.5,-0.35,-0.5,-0.2,-0.5,-0.05,-0.5,0.1,-0.5,0.25,-0.5,0.4,-0.5,0.55,-0.5,0.7,-0.5,0.85,-0.5,1.0,-0.5,1.15,-0.5,1.3,-0.5,1.45,-0.35,-0.5,-0.35,-0.35,-0.35,-0.2,-0.35,-0.05,-0.35,0.1,-0.35,0.25,-0.35,0.4,-0.35,0.55,-0.35,0.7,-0.35,0.85,-0.35,1.0,-0.35,1.15,-0.35,1.3,-0.35,1.45,-0.2,-0.5,-0.2,-0.35,-0.2,-0.2,-0.2,-0.05,-0.2,0.1,-0.2,0.25,-0.2,0.4,-0.2,0.55,-0.2,0.7,-0.2,0.85,-0.2,1.0,-0.2,1.15,-0.2,1.3,-0.2,1.45,-0.05,-0.5,-0.05,-0.35,-0.05,-0.2,-0.05,-0.05,-0.05,0.1,-0.05,0.25,-0.05,0.4,-0.05,0.55,-0.05,0.7,-0.05,0.85,-0.05,1.0,-0.05,1.15,-0.05,1.3,-0.05,1.45,0.1,-0.5,0.1,-0.35,0.1,-0.2,0.1,-0.05,0.1,0.1,0.1,0.25,0.1,0.4,0.1,0.55,0.1,0.7,0.1,0.85,0.1,1.0,0.1,1.15,0.1,1.3,0.1,1.45,0.25,-0.5,0.25,-0.35,0.25,-0.2,0.25,-0.05,0.25,0.1,0.25,0.25,0.25,0.4,0.25,0.55,0.25,0.7,0.25,0.85,0.25,1.0,0.25,1.15,0.25,1.3,0.25,1.45,0.4,-0.5,0.4,-0.35,0.4,-0.2,0.4,-0.05,0.4,0.1,0.4,0.25,0.4,0.4,0.4,0.55,0.4,0.7,0.4,0.85,0.4,1.0,0.4,1.15,0.4,1.3,0.4,1.45,0.55,-0.5,0.55,-0.35,0.55,-0.2,0.55,-0.05,0.55,0.1,0.55,0.25,0.55,0.4,0.55,0.55,0.55,0.7,0.55,0.85,0.55,1.0,0.55,1.15,0.55,1.3,0.55,1.45,0.7,-0.5,0.7,-0.35,0.7,-0.2,0.7,-0.05,0.7,0.1,0.7,0.25,0.7,0.4,0.7,0.55,0.7,0.7,0.7,0.85,0.7,1.0,0.7,1.15,0.7,1.3,0.7,1.45,0.85,-0.5,0.85,-0.35,0.85,-0.2,0.85,-0.05,0.85,0.1,0.85,0.25,0.85,0.4,0.85,0.55,0.85,0.7,0.85,0.85,0.85,1.0,0.85,1.15,0.85,1.3,0.85,1.45,1.0,-0.5,1.0,-0.35,1.0,-0.2,1.0,-0.05,1.0,0.1,1.0,0.25,1.0,0.4,1.0,0.55,1.0,0.7,1.0,0.85,1.0,1.0,1.0,1.15,1.0,1.3,1.0,1.45,1.15,-0.5,1.15,-0.35,1.15,-0.2,1.15,-0.05,1.15,0.1,1.15,0.25,1.15,0.4,1.15,0.55,1.15,0.7,1.15,0.85,1.15,1.0,1.15,1.15,1.15,1.3,1.15,1.45,1.3,-0.5,1.3,-0.35,1.3,-0.2,1.3,-0.05,1.3,0.1,1.3,0.25,1.3,0.4,1.3,0.55,1.3,0.7,1.3,0.85,1.3,1.0,1.3,1.15,1.3,1.3,1.3,1.45,1.45,-0.5,1.45,-0.35,1.45,-0.2,1.45,-0.05,1.45,0.1,1.45,0.25,1.45,0.4,1.45,0.55,1.45,0.7,1.45,0.85,1.45,1.0,1.45,1.15,1.45,1.3,1.45,1.45],196,2) + targetFieldValsExpected=DataArrayDouble([1.645976003316459, 1.454458180060204, 1.286087532859835, 1.147305389930914, 1.040143042030752, 0.9592075185603157, 0.8932542207607532, 0.8296417057622609, 0.7572539678257579, 0.6669048311361028, 0.551329882743212, 0.4064445075734602, 0.2323703965460786, 0.03253142054561309, 1.615321686989539, 1.414941300553572, 1.238383118538708, 1.096701655702075, 0.9955792747382535, 0.9271194507282707, 0.8741000712825546, 0.8201879508155141, 0.7537335933761495, 0.6656210809234322, 0.5470285414729397, 0.3927301586610237, 0.2044036897887453, -0.01181672742825013, 1.609602552867195, 1.400625195269133, 1.213287847440801, 1.065318574929208, 0.9717609562002842, 0.9182626517777217, 0.8760698972315855, 0.8258196104516153, 0.7586487405165288, 0.6686168424854784, 0.5434121624038266, 0.3741815029337978, 0.1661376046619205, -0.0704038088420833, 1.635421686625182, 1.422642113482769, 1.225977424080963, 1.066864693789366, 0.9864801043792362, 0.9486639217909161, 0.9075176697327381, 0.8471248730261529, 0.7660983406349626, 0.6675300501188994, 0.5320013361909732, 0.3404583135353376, 0.1074346390951333, -0.1520751802856468, 1.695346918429566, 1.489526279573347, 1.297678617961701, 1.139921240332637, 1.080508463804929, 1.036847769764088, 0.9687840669352359, 0.8790397822170175, 0.76938768351059, 0.6441978169925557, 0.4915328571013788, 0.2742929463574293, 0.0148214290833748, -0.2671755287427691, 1.782761788232491, 1.59423004798623, 1.422317125787222, 1.286999529473285, 1.20500638941831, 1.127058114031519, 1.022332539190471, 0.8945753999401338, 0.7469190939381181, 0.582396906110898, 0.4015920181411496, 0.1584700483835366, -0.1251860255418387, -0.4254052799545267, 1.881794862747652, 1.712890309994015, 1.557517508390291, 1.422727414977963, 1.308048056353061, 1.187569766723152, 1.03942150436647, 0.8677583087532357, 0.6766652050643343, 0.4703897480238999, 0.2497994532908829, -0.02005989176786582, -0.3224387891441491, -0.6331519303649853, 1.973114284621266, 1.820187301531605, 1.673403730111759, 1.528504440482262, 1.379693463484634, 1.207642134784147, 1.008217764780293, 0.7863328498822348, 0.5465383049529959, 0.2944879513187435, 0.03250657765404452, -0.2670900851421072, -0.5806516907976924, -0.8911331026431459, 2.038729888975378, 1.895652364645637, 1.751759791756183, 1.594035761810714, 1.403016809171641, 1.171403152610878, 0.913267035125007, 0.6343281031932027, 0.3434843176189371, 0.04195410032095204, -0.2645533663891493, -0.58577400250975, -0.8958218846257981, -1.192230697656513, 2.064018033720731, 1.922048791644444, 1.773847180028208, 1.600340336378483, 1.361620036333164, 1.060873411411508, 0.7373484802125152, 0.3868966266761109, 0.04316272760227413, -0.3009370030949727, -0.6505233805563486, -0.9669887470696283, -1.250005719852354, -1.519122595631787, 2.039938287785342, 1.887400820799651, 1.722008733683987, 1.523879290022419, 1.23834392230135, 0.8606985727866472, 0.4844892131548788, 0.08077959236877175, -0.3195742594962179, -0.726291368696764, -1.094357645641832, -1.359078900303776, -1.604725656501341, -1.845297168323687, 1.965762248218393, 1.791665198563286, 1.595056719739704, 1.353692777435502, 1.033006623003495, 0.6416349531117889, 0.2290046916364761, -0.1993180965088852, -0.6311618804827295, -1.051489875129883, -1.409404344854132, -1.681249363331096, -1.917859637689007, -2.145034400762945, 1.849053542205925, 1.648479366622312, 1.418493963148431, 1.141939527533839, 0.8042385795619003, 0.4127534639189761, -0.008572116677791453, -0.4428317297963555, -0.8745477268718713, -1.281769237471681, -1.635421857742795, -1.926210204560556, -2.175577364628722, -2.405762639746138, 1.701519686999922, 1.475879908746998, 1.219065416294153, 0.9203732349759972, 0.5740137315474942, 0.1856460506119944, -0.2298288912529738, -0.6558565521653752, -1.075391078040103, -1.469402631469075, -1.820558929095151, -2.123592211415966, -2.388177455227765, -2.628832075944413]) + coeffsExpected=DataArrayDouble([0.3953237723894342,-0.17220705170185724,0.620727139132215,-0.01938292763088709,-0.007524685306185282,0.0016277944443884584,-0.0005209587893117361,-1.8992696595839718,-0.13154330748345855,0.11248800965389728,-0.47310750305033406,0.03685741122098605,0.21362468750754374,0.8082608687799991,-0.6775548200221704,-0.027683208482275873,-0.007806877014495724,-0.013539239795959668,0.3478535665778018,0.005145793726360813,0.03708618549628136,-0.18235332489209385,-0.04517273339177797,-0.081755114492025,0.12791746560435255,0.09659355695676189,-0.024809653129318366,0.08327587452569823,-1.790380673650165,-0.10622983512164165,0.14989029282340274,0.05949513762355707,0.004548072841131278,0.011252095917834793,-0.004848057194721367,-0.2658537133108412,0.016651579133606154,-0.021640915366981317,0.008975511042160175,-0.021052213988815974,-0.09347841701844657,0.03533229488135717,-0.014556185287109863,-0.27228591670520086,0.002989987191209683,-0.5489428537951813,-0.02134456783001304,-0.22462281620064825,0.005230853443767429,-0.1894678262257301,0.0033140729457334884,5.295483062326795,-0.2724500716060311,0.026433905662192683,0.01368706308878908,-0.03014264855048227,0.053679001877659956,0.08109477254132096,-0.005004603067203444,0.016907143132293558,0.2105509502082437,0.003657404455024417,-4.904755847017426,0.01634808163992959,-0.008325515865305198,0.062188432751569676,-0.013114633511406406,0.11020519384963083,-0.008599402366091309,-0.012125149710784723,0.31723729052927313,-0.10298398036815914,-0.07250078775612204,0.39976713701763433,0.45897498107347223,0.01018626210400031,0.20163425809089347,0.19729093298588943,0.42863333455911523,0.015595097081693168,0.06060353651437489,-0.16379444813161725,-0.43290344196574165,-0.5931022701412187,1.1906610004748832,0.44418106894148945,0.06536220001548931,0.010261694323554562,-0.05943099382075491,-0.04939614579484797,0.002234505477641322,-0.011262130967449935,0.09644905007708474,-0.029518792883267808,0.41564004027396634,-0.18459770295961597,0.3100981306103734,-0.2509873737065425,0.5434321443668653,0.3009912967350914,1.9560655796099518,-0.7143435150084513,-1.5123449469879784]) + # + nbOfInputPoints=100; + f=MEDCouplingFieldDouble.New(ON_NODES_KR,ONE_TIME); + mesh=MEDCoupling1SGTUMesh.New("aMesh",NORM_POINT1); + mesh.setCoords(srcPointCoordsXY); + f.setMesh(mesh); + f.setArray(srcFieldValsOnPoints); + f.checkCoherency(); + # + res0=f.getValueOn([-0.5,-0.5]); + self.assertAlmostEqual(targetFieldValsExpected.getIJ(0,0),res0[0],10) + # + valuesToTest=f.getValueOnMulti(targetPointCoordsXY); + self.assertEqual(196,valuesToTest.getNumberOfTuples()); + self.assertEqual(1,valuesToTest.getNumberOfComponents()); + for i in xrange(40): + self.assertAlmostEqual(targetFieldValsExpected[i],valuesToTest.getIJ(i,0),10) + pass + fd=f.getDiscretization() + del f + self.assertTrue(isinstance(fd,MEDCouplingFieldDiscretizationKriging)) + coeffs,isDrift=fd.computeVectorOfCoefficients(mesh,srcFieldValsOnPoints) + self.assertEqual(3,isDrift) + self.assertTrue(coeffsExpected.isEqual(coeffs,1e-8)) + # testing matrix + pts3=[-0.5,-0.5,-0.5,-0.35,-0.35,-0.2] + mesh.setCoords(srcPointCoordsXY[:4]) + m,nbCols=fd.computeEvaluationMatrixOnGivenPts(mesh,pts3) + self.assertTrue(m.isEqual(DataArrayDouble([0.05768877688524917,-4.438982030395039,1.9495386255911573,3.431754627918642,0.11803848510231275,-4.138339658420563,1.6630742187104417,3.357226954607818,0.14630203028580618,-3.5156045565871734,1.414680070737206,2.954622455564169]),1e-12)) + if MEDCouplingHasNumPyBindings(): + import numpy as np + m0=m.toNumPyArray() ; m0=m0.reshape(3,nbCols) ; m0=np.matrix(m0) + srcFieldValsOnPoints2=DataArrayDouble(4,2) ; srcFieldValsOnPoints2[:,0]=srcFieldValsOnPoints[:4] ; srcFieldValsOnPoints2[:,1]=2*srcFieldValsOnPoints[:4] + n0=srcFieldValsOnPoints2.toNumPyArray() ; n0=n0.reshape(4,2) ; n0=np.matrix(n0) + # + f=MEDCouplingFieldDouble.New(ON_NODES_KR,ONE_TIME) ; f.setMesh(mesh) ; f.setArray(srcFieldValsOnPoints2) ; f.checkCoherency() + self.assertTrue(DataArrayDouble(np.array((m0*n0))).isEqual(f.getValueOnMulti(pts3),1e-14)) + pass + # + pass + + # test the when input slice is all the same object is return by MEDCouplingMesh.buildPartRange + def testSwig2MeshPartSlice1(self): + a=DataArrayDouble(4) ; a.iota() + c=MEDCouplingCMesh() ; c.setCoords(a,a) ; m=c.buildUnstructured() + fc0=c.getMeasureField(False) ; fc1=fc0[:] ; fc2=fc0*fc1 ; fc2.setName(fc0.getName()) + self.assertEqual(fc0.getMesh().getHiddenCppPointer(),fc1.getMesh().getHiddenCppPointer()) + self.assertEqual(fc2.getMesh().getHiddenCppPointer(),fc1.getMesh().getHiddenCppPointer()) + self.assertTrue(fc2.isEqual(fc1,1e-12,1e-12)) + # + fm0=m.getMeasureField(False) ; fm1=fm0[:] ; fm2=fm0*fm1 ; fm2.setName(fm0.getName()) + self.assertEqual(fm0.getMesh().getHiddenCppPointer(),fm1.getMesh().getHiddenCppPointer()) + self.assertEqual(fm2.getMesh().getHiddenCppPointer(),fm1.getMesh().getHiddenCppPointer()) + self.assertTrue(fm2.isEqual(fm1,1e-12,1e-12)) + pass + + # test the correct behaviour when attempting to aggregate two fields whose mesh is null + def testSwig2MergeFieldsOnFieldsHavingNoMesh(self): + a=DataArrayDouble(4) ; a.iota() ; a*=1.5 + c=MEDCouplingCMesh() ; c.setCoords(a,a) ; f1=c.getMeasureField(False) + f1.setMesh(None) ; f2=f1.deepCpy() ; f2*=2 + f3=MEDCouplingFieldDouble.MergeFields(f1,f2) + daExp=DataArrayDouble([2.25,2.25,2.25,2.25,2.25,2.25,2.25,2.25,2.25,4.5,4.5,4.5,4.5,4.5,4.5,4.5,4.5,4.5]) + self.assertTrue(f3.getArray().isEqual(daExp,1e-12)) + self.assertEqual(f3.getTypeOfField(),ON_CELLS) + self.assertEqual(f3.getMesh(),None) + f4=MEDCouplingFieldDouble.MergeFields([f1,f2]) + self.assertTrue(f4.getArray().isEqual(daExp,1e-12)) + self.assertEqual(f4.getTypeOfField(),ON_CELLS) + self.assertEqual(f4.getMesh(),None) + pass + + # test a simple node to cell convertion of a field + def testSwig2NodeToCellDiscretization1(self): + f=MEDCouplingFieldDouble(ON_NODES) ; f.setTime(1.1,2,3) + a1=DataArrayDouble(4) ; a1.iota() + a2=DataArrayDouble(3) ; a2.iota() + m=MEDCouplingCMesh() ; m.setCoords(a1,a2) + f.setMesh(m) + arr=DataArrayDouble([21.,121.,20.,120.,19.,119.,18.,118.,17.,117.,16.,116.,15.,115.,14.,114.,13.,113.,12.,112.,11.,111.,10.,110.],12,2) ; arr.setInfoOnComponents(["aa [km]","bbb [kJ]"]) + f.setArray(arr) ; f.setName("toto") + # + f2=f.nodeToCellDiscretization() + self.assertEqual(ON_CELLS,f2.getTypeOfField()) + self.assertEqual("toto",f2.getName()) + self.assertEqual([1.1,2,3],f2.getTime()) + self.assertEqual(["aa [km]","bbb [kJ]"],f2.getArray().getInfoOnComponents()) + self.assertEqual(6,f2.getArray().getNumberOfTuples()) + self.assertEqual(f.getMesh().getHiddenCppPointer(),f2.getMesh().getHiddenCppPointer()) + exp=DataArrayDouble([18.5,118.5,17.5,117.5,16.5,116.5,14.5,114.5,13.5,113.5,12.5,112.5],6,2) ; exp.setInfoOnComponents(["aa [km]","bbb [kJ]"]) + self.assertTrue(f2.getArray().isEqual(exp,1e-13)) + pass + + def testSwig2NonRegressionBugIntersectMeshes1(self): + src=MEDCouplingUMesh("src",2) + src.setCoords(DataArrayDouble([-2.5,-3,-2.5,3,2.5,3],3,2)) + src.allocateCells() + src.insertNextCell(NORM_TRI3,[0,1,2]) + # + trg=MEDCouplingUMesh("trg",2) + trg.setCoords(DataArrayDouble([-2.5,-3.,0.,-3.,0.,-2.,-2.,0.,-2.25,0.,-2.5,0.,-2.5,-1.5,0.,-2.5,-1.25,-3.,-1.414213562373095,-1.414213562373095],10,2)) + trg.allocateCells() + trg.insertNextCell(NORM_QPOLYG,[2,1,0,5,3,7,8,6,4,9]) + # + a,b,c=MEDCouplingUMesh.Intersect2DMeshes(src,trg,1.0e-8) + a.mergeNodes(1e-8) + self.assertTrue(a.getCoords().isEqual(DataArrayDouble([-2.5,-3.,-2.5,3.,2.5,3.,0.,-3.,0.,-2.,-2.,0.,-2.25,0.,-2.5,0.,-2.5,-1.5,0.,-2.5,-1.25,-3.,-1.414213562373095,-1.414213562373095,-1.2803687993289596,-1.5364425591947515,-1.8901843996644798,-2.2682212795973755,-1.81117884244736,-0.8483107924994473,-2.5,1.5,0.,3.,0.6098156003355202,0.7317787204026243],18,2),1e-12)) + self.assertTrue(a.getNodalConnectivity().isEqual(DataArrayInt([32,12,0,7,5,13,8,6,14,32,7,1,2,12,5,15,16,17,14,6]))) + self.assertTrue(a.getNodalConnectivityIndex().isEqual(DataArrayInt([0,9,20]))) + self.assertTrue(b.isEqual(DataArrayInt([0,0]))) + self.assertTrue(c.isEqual(DataArrayInt([0,-1]))) + pass + + def testSwig2MeshOrientCorrectly2DCells1(self): + m=MEDCouplingUMesh("mesh",2) + coo=DataArrayDouble([1.,0.,0.5,-0.1,0.,1.,0.,0.,0.07,0.5,0.59,0.5],6,2) + m.setCoords(coo) + m.allocateCells() + m.insertNextCell(NORM_TRI6,[3,0,2,1,5,4]) + m.insertNextCell(NORM_QPOLYG,[3,0,2,1,5,4]) + self.assertTrue(DataArrayDouble([-0.58093333350930543,-0.58093333350930543]).isEqual(m.getMeasureField(False).getArray(),1e-12)) + m.changeSpaceDimension(3) + m.orientCorrectly2DCells([0.,0.,-1.],False) + # + m.checkCoherency() + self.assertTrue(m.getNodalConnectivity().isEqual(DataArrayInt([6,3,2,0,4,5,1, 32,3,2,0,4,5,1]))) + self.assertTrue(m.getNodalConnectivityIndex().isEqual(DataArrayInt([0,7,14]))) + m.changeSpaceDimension(2) + self.assertTrue(DataArrayDouble([0.58093333350930543,0.58093333350930543]).isEqual(m.getMeasureField(False).getArray(),1e-12)) + pass + + def testSwig2Hexa8HavingFacesWarped1(self): + """ This test is bases on a "error" of interpolation detected. After investigation cell #3 of src is warped that leads to the fact that when trg is + intersected with src the sum of intersection volume is greater than the volume of the trg cell. + A test that can be done is to split the cell #3 of src into tetrohedrons and by summing all the volumes it does not fit the volume computed of cell#3 unsplitted (expect for + GENERAL_24). + """ + srcCoo=DataArrayDouble([0.15694071546650565,0.09383333333333337,6.920842121738133,0.15774332475430292,0.185486666666667,6.920682472824616,0.1585459340420992,0.27713999999999994,6.9205228239111,0.07427195882345167,0.05782666666666668,6.937285959830335,0.06343673343819695,0.11347333333333297,6.939441220162809,0.05260150805294228,0.16911999999999996,6.941596480495282,0.014076262238703396,0.04800666666666667,6.949259628344076,0.014076262238703396,0.07092000000000007,6.949259628344076,0.15407499632681992,0.09383333333333338,6.897607484780063,0.15489234394181514,0.18548666666666702,6.897567331066572,0.15570969155680933,0.27714,6.897527177353081,0.06988819198237989,0.05782666666666669,6.901743317269663,0.05885399917995321,0.11347333333333298,6.9022853924017955,0.047819806377526586,0.16912,6.902827467533927,0.0085871208577874,0.048006666666666684,6.9047548457815076,0.0085871208577874,0.07092000000000008,6.9047548457815076,0.153883333333333,0.09383333333333338,6.820902,0.154701666666667,0.18548666666666702,6.820902,0.15551999999999996,0.27714,6.820902,0.06959499999999999,0.05782666666666669,6.820902,0.058547499999999975,0.11347333333333298,6.820902,0.04749999999999999,0.16912,6.820902],22,3) + src=MEDCouplingUMesh("TBmesh3D",3) ; src.setCoords(srcCoo) + src.allocateCells() + src.insertNextCell(NORM_HEXA8,[0,1,4,3,8,9,12,11]) + src.insertNextCell(NORM_HEXA8,[1,2,5,4,9,10,13,12]) + src.insertNextCell(NORM_HEXA8,[4,5,7,6,12,13,15,14]) + src.insertNextCell(NORM_HEXA8,[8,9,12,11,16,17,20,19]) + src.insertNextCell(NORM_HEXA8,[9,10,13,12,17,18,21,20]) + src.checkCoherency2() + # trg is useless here but I keep it in case of MEDCouplingRemapper were expected to do something about warped NORM_HEXA8 + trgCoo=DataArrayDouble([0.0960891897852753,0.105088620541845,6.8598,0.0599574480546212,0.118434267436059,6.8598,0.113514510609589,0.14874473653263,6.8598,0.0831322609794463,0.167319109733883,6.8598,0.0960891897852753,0.105088620541845,6.92146666666667,0.0599574480546212,0.118434267436059,6.92146666666667,0.113514510609589,0.14874473653263,6.92146666666667,0.0831322609794463,0.167319109733883,6.92146666666667],8,3) + trg=MEDCouplingUMesh("MESH",3) ; trg.setCoords(trgCoo) + trg.allocateCells() + trg.insertNextCell(NORM_HEXA8,[0,1,3,2,4,5,7,6]) + # + srcFace=src.buildDescendingConnectivity()[0] + conn=MEDCoupling1SGTUMesh(srcFace).getNodalConnectivity() ; conn.rearrange(4) + eqFaces=srcFace.computePlaneEquationOf3DFaces() + nodeIdInCell=3 + e=(srcFace.getCoords()[conn[:,nodeIdInCell]]*eqFaces[:,:-1]).sumPerTuple()+eqFaces[:,3]# e represent the error between the expected 'a*X+b*Y+c*Z+d' in eqFaces and 0. Closer e to 0. is closer the 4th point is to the plane built with the 3 first points + lambd=-e/(eqFaces[:,:3]**2).sumPerTuple() + pts=lambd*eqFaces[:,:-1]+srcFace.getCoords()[conn[:,nodeIdInCell]]#pts represent the projection of the last points of each NORM_QUAD4 to the plane defined by the 3 first points of the NORM_QUAD4 cell + shouldBeZero=(pts*eqFaces[:,:-1]).sumPerTuple()+eqFaces[:,3]# this line is useless only to be sure that pts are on the plane. + check=(pts-srcFace.getCoords()[conn[:,nodeIdInCell]]).magnitude() # check contains the distance of the last point to its plane + idsToTest=check.getIdsNotInRange(0.,1e-10) + self.assertTrue(idsToTest.isEqual(DataArrayInt([17,18,19,20,22,23,24]))) + idsToTest2=idsToTest.getIdsNotInRange(18,22) + self.assertTrue(idsToTest2.isEqual(DataArrayInt([0,4,5,6]))) + idsToTest2.rearrange(2) + self.assertTrue(idsToTest2.sumPerTuple().isEqual(DataArrayInt([4,11]))) + pass + + def testSwig2SortHexa8EachOther1(self): + """ + testing MEDCoupling1SGTUMesh.sortHexa8EachOther method + """ + coords1=DataArrayDouble([(-0.5,0.5,-0.5),(0.5,-0.5,-0.5),(-0.5,-0.5,0.5),(-0.5,-0.5,-0.5),(0.5,-0.5,0.5),(-0.5,0.5,0.5),(0.5,0.5,0.5),(0.5,0.5,-0.5)]) + m1=MEDCouplingUMesh("m1",3) ; m1.setCoords(coords1) + m1.allocateCells() ; m1.insertNextCell(NORM_HEXA8,[7,1,3,0,6,4,2,5]) + m1.checkCoherency() + # + m2=m1.deepCpy() ; m2.setName("m2") + # + trs=[[0.,0.,-1.],[0.,0.,1.],[1.,0.,0.],[0.,-1.,0.],[-1.,0.,0.],[0.,1.,0.]] + for i,t in enumerate(trs): + for j in xrange(64): + j2=(j//16) ; j1=((j%16)//4) ; j0=(j%4) + m11=m1.deepCpy() + m11.rotate([0.,0.,0.],[0.,0.,1.],float(j0)*pi/2) + m11.rotate([0.,0.,0.],[0.,1.,0.],float(j1)*pi/2) + m11.rotate([0.,0.,0.],[1.,0.,0.],float(j2)*pi/2) + m11.translate(t) + # + m=MEDCouplingUMesh.MergeUMeshes(m2,m11) + m.mergeNodes(1e-12) + self.assertEqual(12,m.getNumberOfNodes()) + m=MEDCoupling1SGTUMesh(m) + m.sortHexa8EachOther() + tmp0=m.buildUnstructured().tetrahedrize(PLANAR_FACE_6)[0].buildUnstructured() + self.assertEqual(20,tmp0.computeSkin().getNumberOfCells()) + pass + pass + pass + + def testSwig2normMinComputeAbs1(self): + d=DataArrayDouble([4,-5,2,6.1,-7.33,1,-1,3e2,0.07,-0.009,-6,-1e30],4,3) + d.setInfoOnComponents(["XX [m]","YYY [km]","ABSJJ [MW]"]) + d0=d.computeAbs() + dExp=d.deepCpy() ; dExp.abs() + self.assertTrue(dExp.isEqual(d0,1e-12)) + e=d0-DataArrayDouble([4,5,2,6.1,7.33,1,1,3e2,0.07,0.009,6,1e30],4,3) + self.assertAlmostEqual(0.,e.normMin(),13) + self.assertAlmostEqual(0.009,d.normMin(),13) + # + di=DataArrayInt([3,-12,5,6,14,16,-23,100,23,-1,0,-6],4,3) + di.setInfoOnComponents(["XX [m]","YYY [km]","ABSJJ [MW]"]) + d0i=di.computeAbs() + diExp=di.deepCpy() ; diExp.abs() + self.assertTrue(diExp.isEqual(d0i)) + self.assertEqual([3,12,5,6,14,16,23,100,23,1,0,6],d0i.getValues()) + pass + + def testSwig2GetCellsContainingPointsForNonConvexPolygon1(self): + coo=DataArrayDouble([-0.5,-0.5,-0.5,0.5,0.5,0.5,0.5,-0.5,0.,-0.5,0.,0.,0.5,0.,],7,2) + m=MEDCouplingUMesh("Intersect2D",2) ; m.setCoords(coo) ; m.allocateCells() + m.insertNextCell(NORM_POLYGON,[6,3,4,5]) + m.insertNextCell(NORM_POLYGON,[4,0,1,2,6,5]) + m.checkCoherency2() + # + self.assertTrue(m.getCellsContainingPoint((0.4,-0.4),1e-12).isEqual(DataArrayInt([0]))) + self.assertTrue(m.getCellsContainingPoint((-0.4,-0.4),1e-12).isEqual(DataArrayInt([1]))) + self.assertTrue(m.getCellsContainingPoint((0.,-0.4),1e-12).isEqual(DataArrayInt([0,1]))) + pass + + def testSwig2GetCellsContainingPointsForNonConvexPolygon2(self): + coo=DataArrayDouble([-0.5,-0.5,-0.5,0.5,0.5,0.5,0.5,-0.5,-2.0816681711721685e-17,-2.0816681711721685e-17,-0.17677669529663687,0.1767766952966369,0.,0.5,0.5,0.,0.17677669529663684,-0.17677669529663692,0.17677669529663692,0.17677669529663684,-0.17677669529663692,-0.17677669529663687,0.,-0.5,-0.5,0.,0.33838834764831843,-0.3383883476483185,-0.33838834764831843,0.33838834764831843,-0.21213203435596423,0.21213203435596426,0.2121320343559642,-0.2121320343559643,0.21213203435596426,0.2121320343559642,-0.21213203435596423,-0.21213203435596428,0.3560660171779821,-0.35606601717798214,-0.35606601717798214,0.35606601717798214,0.19445436482630052,-0.19445436482630063,-0.19445436482630055,0.19445436482630057,0.,0.27],24,2) + m=MEDCouplingUMesh("mesh",2) ; m.setCoords(coo) ; m.allocateCells() + m.insertNextCell(NORM_QPOLYG,[8,5,4,9]) + m.insertNextCell(NORM_QPOLYG,[5,8,4,10]) + m.insertNextCell(NORM_QPOLYG,[16,8,5,15,21,9,22,17]) + m.insertNextCell(NORM_QPOLYG,[15,1,2,3,16,20,6,7,19,17]) + m.insertNextCell(NORM_QPOLYG,[15,5,8,16,22,10,21,18]) + m.insertNextCell(NORM_QPOLYG,[16,3,0,1,15,19,11,12,20,18]) + m.checkCoherency2() + self.assertTrue(m.getCellsContainingPoint([0.,0.27],1e-12).isEqual(DataArrayInt([2]))) + pass + + def testSwig2DAIGetIdsEqualTuple1(self): + da=DataArrayInt([0,7,1,2,4,1,2,1,1,2,0,1,2,1,5,1,1,2],9,2) + self.assertTrue(da.getIdsEqualTuple([1,2]).isEqual(DataArrayInt([1,4,8]))) + self.assertTrue(da.getIdsEqualTuple((1,2)).isEqual(DataArrayInt([1,4,8]))) + self.assertTrue(da.getIdsEqualTuple(DataArrayInt([1,2])).isEqual(DataArrayInt([1,4,8]))) + da.rearrange(3) + self.assertRaises(InterpKernelException,da.getIdsEqualTuple,[1,2])# mismatch nb of compo (3) and nb of elts in input tuple (2) + self.assertTrue(da.getIdsEqualTuple([2,0,1]).isEqual(DataArrayInt([3]))) + self.assertTrue(da.getIdsEqualTuple([2,0,7]).isEqual(DataArrayInt([]))) + da.rearrange(1) + self.assertTrue(da.getIdsEqualTuple(2).isEqual(DataArrayInt([3,6,9,12,17]))) + self.assertTrue(da.getIdsEqualTuple(2).isEqual(da.getIdsEqual(2))) + pass + + def testSwig2GaussNEStaticInfo1(self): + self.assertTrue(DataArrayDouble(MEDCouplingFieldDiscretizationGaussNE.GetWeightArrayFromGeometricType(NORM_TRI3)).isEqual(DataArrayDouble([0.16666666666666666,0.16666666666666666,0.16666666666666666]),1e-12)) + self.assertTrue(DataArrayDouble(MEDCouplingFieldDiscretizationGaussNE.GetRefCoordsFromGeometricType(NORM_TRI3)).isEqual(DataArrayDouble([0.,0.,1.,0.,0.,1.]),1e-12)) + self.assertTrue(DataArrayDouble(MEDCouplingFieldDiscretizationGaussNE.GetLocsFromGeometricType(NORM_TRI3)).isEqual(DataArrayDouble([0.16666666666666666,0.16666666666666666,0.6666666666666667,0.16666666666666666,0.16666666666666666,0.6666666666666667]),1e-12)) + pass + + def testSwigReverseNodalConnOnStructuredMesh(self): + # 1D - standard + c=MEDCouplingCMesh() ; arr=DataArrayDouble(10) ; arr.iota() + c.setCoordsAt(0,arr) + rn,rni=c.getReverseNodalConnectivity() + rn2,rni2=c.buildUnstructured().getReverseNodalConnectivity() + self.assertTrue(rn.isEqual(DataArrayInt([0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8]))) + self.assertTrue(rni.isEqual(DataArrayInt([0,1,3,5,7,9,11,13,15,17,18]))) + self.assertTrue(rn.isEqual(rn2)) ; self.assertTrue(rni.isEqual(rni2)) + # 1D - limit + c=MEDCouplingCMesh() ; arr=DataArrayDouble(1) ; arr.iota() + c.setCoordsAt(0,arr) + rn,rni=c.getReverseNodalConnectivity() + rn2,rni2=c.buildUnstructured().getReverseNodalConnectivity() + self.assertTrue(rn.isEqual(DataArrayInt([0]))) + self.assertTrue(rni.isEqual(DataArrayInt([0,1]))) + self.assertTrue(rn.isEqual(rn2)) ; self.assertTrue(rni.isEqual(rni2)) + # 1D - limit + c=MEDCouplingCMesh() ; arr=DataArrayDouble(0) ; arr.iota() + c.setCoordsAt(0,arr) + rn,rni=c.getReverseNodalConnectivity() + rn.isEqual(DataArrayInt([])) + rni.isEqual(DataArrayInt([0])) + # 2D - standard + c=MEDCouplingCMesh() ; arr=DataArrayDouble(5) ; arr.iota() ; arr2=DataArrayDouble(4) ; arr.iota() + c.setCoords(arr,arr2) + rn,rni=c.getReverseNodalConnectivity() + rn2,rni2=c.buildUnstructured().getReverseNodalConnectivity() + self.assertTrue(rn.isEqual(DataArrayInt([0,0,1,1,2,2,3,3,0,4,0,1,4,5,1,2,5,6,2,3,6,7,3,7,4,8,4,5,8,9,5,6,9,10,6,7,10,11,7,11,8,8,9,9,10,10,11,11]))) + self.assertTrue(rni.isEqual(DataArrayInt([0,1,3,5,7,8,10,14,18,22,24,26,30,34,38,40,41,43,45,47,48]))) + self.assertTrue(rn.isEqual(rn2)) ; self.assertTrue(rni.isEqual(rni2)) + # 2D - limit + c=MEDCouplingCMesh() ; arr=DataArrayDouble(10) ; arr.iota() ; arr2=DataArrayDouble(1) ; arr.iota() + c.setCoords(arr,arr2) + rn,rni=c.getReverseNodalConnectivity() + self.assertTrue(rn.isEqual(DataArrayInt([0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8]))) + self.assertTrue(rni.isEqual(DataArrayInt([0,1,3,5,7,9,11,13,15,17,18]))) + # 2D - limit + c=MEDCouplingCMesh() ; arr=DataArrayDouble(10) ; arr.iota() ; arr2=DataArrayDouble(1) ; arr.iota() + c.setCoords(arr2,arr) + rn,rni=c.getReverseNodalConnectivity() + self.assertTrue(rn.isEqual(DataArrayInt([0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8]))) + self.assertTrue(rni.isEqual(DataArrayInt([0,1,3,5,7,9,11,13,15,17,18]))) + # 3D - standard + c=MEDCouplingCMesh() ; arr0=DataArrayDouble(5) ; arr0.iota() ; arr1=DataArrayDouble(3) ; arr1.iota() ; arr2=DataArrayDouble(4) ; arr2.iota() + c.setCoords(arr0,arr1,arr2) + rn,rni=c.getReverseNodalConnectivity() + self.assertTrue(rn.isEqual(DataArrayInt([0,0,1,1,2,2,3,3,0,4,0,1,4,5,1,2,5,6,2,3,6,7,3,7,4,4,5,5,6,6,7,7,0,8,0,1,8,9,1,2,9,10,2,3,10,11,3,11,0,4,8,12,0,1,4,5,8,9,12,13,1,2,5,6,9,10,13,14,2,3,6,7,10,11,14,15,3,7,11,15,4,12,4,5,12,13,5,6,13,14,6,7,14,15,7,15,8,16,8,9,16,17,9,10,17,18,10,11,18,19,11,19,8,12,16,20,8,9,12,13,16,17,20,21,9,10,13,14,17,18,21,22,10,11,14,15,18,19,22,23,11,15,19,23,12,20,12,13,20,21,13,14,21,22,14,15,22,23,15,23,16,16,17,17,18,18,19,19,16,20,16,17,20,21,17,18,21,22,18,19,22,23,19,23,20,20,21,21,22,22,23,23]))) + self.assertTrue(rni.isEqual(DataArrayInt([0,1,3,5,7,8,10,14,18,22,24,25,27,29,31,32,34,38,42,46,48,52,60,68,76,80,82,86,90,94,96,98,102,106,110,112,116,124,132,140,144,146,150,154,158,160,161,163,165,167,168,170,174,178,182,184,185,187,189,191,192]))) + rn2,rni2=c.buildUnstructured().getReverseNodalConnectivity() + self.assertTrue(rn.isEqual(rn2)) ; self.assertTrue(rni.isEqual(rni2)) + pass + + def testSwig2CellToNodeDiscretization1(self): + m=MEDCouplingCMesh() ; arr0=DataArrayDouble(5) ; arr0.iota() ; arr1=DataArrayDouble(4) ; arr1.iota() ; m.setCoords(arr0,arr1) + f=MEDCouplingFieldDouble(ON_CELLS) ; f.setMesh(m) ; f.setTime(1.1,5,6) + arr=DataArrayDouble(12) ; arr.iota() + arr=DataArrayDouble.Meld(arr,arr+100.) ; arr.setInfoOnComponents(["aaa","bbb"]) + f.setArray(arr) + f.checkCoherency() + # + ref=DataArrayDouble([0.,0.5,1.5,2.5,3.,2.,2.5,3.5,4.5,5.,6.,6.5,7.5,8.5,9.,8.,8.5,9.5,10.5,11.]) + ref=DataArrayDouble.Meld(ref,ref+100.) ; ref.setInfoOnComponents(["aaa","bbb"]) + f2=f.cellToNodeDiscretization() + f2.checkCoherency() + self.assertEqual(f2.getTime()[1:],[5,6]) + self.assertAlmostEqual(f2.getTime()[0],1.1,15) + self.assertEqual(f2.getMesh().getHiddenCppPointer(),m.getHiddenCppPointer()) + self.assertTrue(f2.getArray().isEqual(ref,1e-12)) + rn,rni=m.getReverseNodalConnectivity() + rni2=(rni.deltaShiftIndex()).convertToDblArr() + arr2=(f.getArray()[rn]).accumulatePerChunck(rni)/rni2 + self.assertTrue(f2.getArray().isEqual(arr2,1e-12)) + del f2 + # + u=m.buildUnstructured() ; f.setMesh(u) ; del m + f3=f.cellToNodeDiscretization() + f3.checkCoherency() + self.assertEqual(f3.getTime()[1:],[5,6]) + self.assertAlmostEqual(f3.getTime()[0],1.1,15) + self.assertEqual(f3.getMesh().getHiddenCppPointer(),u.getHiddenCppPointer()) + self.assertTrue(f3.getArray().isEqual(ref,1e-12)) + pass + + def testSwig2GetMeshSpaceDimensionCMesh1(self): + c=MEDCouplingCMesh() + arr0=DataArrayDouble([0,1,2]) + arr1=DataArrayDouble([0]) + c.setCoords(arr0,arr0,arr0) + self.assertEqual(c.getMeshDimension(),3) + self.assertEqual(c.getSpaceDimension(),3) + # + c.setCoords(arr0,arr0,arr1) + self.assertEqual(c.getMeshDimension(),2) + self.assertEqual(c.getSpaceDimension(),3) + # + c.setCoords(arr0,arr0) + self.assertEqual(c.getMeshDimension(),2) + self.assertEqual(c.getSpaceDimension(),2) + # + c.setCoords(arr0,arr1) + self.assertEqual(c.getMeshDimension(),1) + self.assertEqual(c.getSpaceDimension(),2) + # + c.setCoords(arr0) + self.assertEqual(c.getMeshDimension(),1) + self.assertEqual(c.getSpaceDimension(),1) + # + c.setCoords(arr1) + self.assertEqual(c.getMeshDimension(),0) + self.assertEqual(c.getSpaceDimension(),1) + pass + + def testSwig2BuildSpreadZonesWithPolyOnQPolyg1(self): + nx=6 + ny=6 + m=MEDCouplingCMesh() + arr1=DataArrayDouble(nx) ; arr1.iota() + arr2=DataArrayDouble(ny) ; arr2.iota() + m.setCoords(arr1,arr2) + m=m.buildUnstructured() + da=DataArrayInt.Range(nx-1,(nx-1)*(ny-1),nx) + m2=m[da] ; m2.simplexize(0) + dan=da.buildComplement(m.getNumberOfCells()) + m1=m[dan] + m=MEDCouplingUMesh.MergeUMeshesOnSameCoords(m1,m2) + # + m.convertLinearCellsToQuadratic() + m1=m[::2] ; m2=m[1::2] ; m2.convertAllToPoly() + m=MEDCouplingUMesh.MergeUMeshesOnSameCoords(m1,m2) + p=m.buildSpreadZonesWithPoly() + self.assertTrue(p.getNodalConnectivity().isEqual(DataArrayInt([32,1,0,6,12,18,24,30,31,32,33,34,35,29,23,17,11,5,4,3,2,36,37,94,62,72,83,84,86,89,99,92,93,82,71,60,51,49,46,43,40]))) + self.assertTrue(p.getNodalConnectivityIndex().isEqual(DataArrayInt([0,41]))) + self.assertTrue(p.getCoords().isEqual(DataArrayDouble([0.,0.,1.,0.,2.,0.,3.,0.,4.,0.,5.,0.,0.,1.,1.,1.,2.,1.,3.,1.,4.,1.,5.,1.,0.,2.,1.,2.,2.,2.,3.,2.,4.,2.,5.,2.,0.,3.,1.,3.,2.,3.,3.,3.,4.,3.,5.,3.,0.,4.,1.,4.,2.,4.,3.,4.,4.,4.,5.,4.,0.,5.,1.,5.,2.,5.,3.,5.,4.,5.,5.,5.,0.5,0.,0.,0.5,0.5,1.,1.,0.5,1.5,0.,1.5,1.,2.,0.5,2.5,0.,2.5,1.,3.,0.5,3.5,0.,3.5,1.,4.,0.5,4.5,0.,4.5,1.,5.,0.5,1.,1.5,1.5,2.,2.,1.5,2.5,2.,3.,1.5,3.5,2.,4.,1.5,4.5,2.,5.,1.5,0.5,2.,0.,2.5,0.5,3.,1.,2.5,2.,2.5,2.5,3.,3.,2.5,3.5,3.,4.,2.5,4.5,3.,5.,2.5,0.,3.5,0.5,4.,1.,3.5,1.5,3.,1.5,4.,2.,3.5,3.,3.5,3.5,4.,4.,3.5,4.5,4.,5.,3.5,0.,4.5,0.5,5.,1.,4.5,1.5,5.,2.,4.5,2.5,4.,2.5,5.,3.,4.5,4.,4.5,4.5,5.,5.,4.5,0.,1.5,0.5,1.5,1.5,2.5,2.5,3.5,3.5,4.5,3.5,5.0],100,2),1e-13)) + pass + + def testSwig2Conformize2D1(self): + eps = 1.0e-8 + coo = [0.,-0.5,0.,0.,0.5,0.,0.5,-0.5,0.25, + -0.1,0.25,0.,0.5,-0.1,0.,0.5,0.5,0.5,0.25,0.4,0.25,0.5,0.5,0.4] + conn = [5,5,2,6,4,5,6,3,0,1,5,4,5,10,8,11,9,5,11,2,1,7,10,9] + connI = [0,5,12,17,24] + m = MEDCouplingUMesh("box",2) + cooArr = DataArrayDouble(coo,len(coo)/2,2) + m.setCoords(cooArr) + m.setConnectivity(DataArrayInt(conn),DataArrayInt(connI)) + m.mergeNodes(eps) + m.checkCoherency() + self.assertTrue(m.conformize2D(eps).isEqual(DataArrayInt([3]))) + self.assertEqual(m.getCoords().getHiddenCppPointer(),cooArr.getHiddenCppPointer()) # check that coordinates remain the same here + self.assertTrue(m.getNodalConnectivity().isEqual(DataArrayInt([5,5,2,6,4,5,6,3,0,1,5,4,5,10,8,11,9,5,11,2,5,1,7,10,9]))) + self.assertTrue(m.getNodalConnectivityIndex().isEqual(DataArrayInt([0,5,12,17,25]))) + pass + + def testSwig2Conformize2D2(self): + eps = 1.0e-8 + coo=DataArrayDouble([-10,-6,0,-6,0,0,7,0,-10,2,0,2,0,6,7,6,0,8,7,8,-10,12,-4,12,0,12,0,11,7,11,-4,16,0,16,7,16],18,2) + conn=DataArrayInt([2,3,7,6, 13,16,17,14, 4,10,12,5, 9,14,13,8, 8,9,7,6, 5,4,0,1, 16,12,11,15]) + m=MEDCoupling1SGTUMesh("mesh",NORM_QUAD4) + m.setCoords(coo) + m.setNodalConnectivity(conn) + m=m.buildUnstructured() + self.assertTrue(m.conformize2D(eps).isEqual(DataArrayInt([0,1,2,5]))) + self.assertEqual(m.getCoords().getHiddenCppPointer(),coo.getHiddenCppPointer()) # check that coordinates remain the same here + self.assertTrue(m.getNodalConnectivity().isEqual(DataArrayInt([5,2,3,7,6,5, 5,13,12,16,17,14, 5,4,10,11,12,13,8,6,5, 4,9,14,13,8, 4,8,9,7,6, 5,5,4,0,1,2, 4,16,12,11,15]))) + self.assertTrue(m.getNodalConnectivityIndex().isEqual(DataArrayInt([0,6,12,21,26,31,37,42]))) + pass + + def testSwigSplit2DCells1(self): + coo=DataArrayDouble([[0,0],[1,0],[1,1],[0,1],[0.5,0],[1,0.5],[0.5,1],[0.,0.5]]) + m=MEDCouplingUMesh("mesh",2) + m.setCoords(coo) + m.allocateCells() + m.insertNextCell(NORM_QUAD8,[0,1,2,3,4,5,6,7]) + _,d,di,_,_=m.buildDescendingConnectivity() + subb=DataArrayInt([5]) + subbi=DataArrayInt([0,0,1,1,1]) + mid=DataArrayInt([-1,-1]) + midi=DataArrayInt([0,0,2,2,2]) + self.assertEqual(2,m.split2DCells(d,di,subb,subbi,mid,midi)) + self.assertTrue(m.getNodalConnectivity().isEqual(DataArrayInt([32,0,1,5,2,3,4,8,9,6,7]))) + self.assertTrue(m.getNodalConnectivityIndex().isEqual(DataArrayInt([0,11]))) + self.assertTrue(m.getCoords().isEqual(DataArrayDouble([[0,0],[1,0],[1,1],[0,1],[0.5,0],[1,0.5],[0.5,1],[0.,0.5],[1.,0.25],[1.,0.75]]),1e-12)) + pass + + def testSwig2Conformize2D3(self): + eps = 1.0e-8 + coo=DataArrayDouble([-10,-6,0,-6,0,0,7,0,-10,2,0,2,0,6.5,7,6.5,0,8,7,8,-10,12,-4,12,0,12,0,11,7,11,-4,16,0,16,7,16],18,2) + conn=DataArrayInt([2,3,7,6, 13,16,17,14, 4,10,12,5, 9,14,13,8, 8,9,7,6, 5,4,0,1, 16,12,11,15]) + m=MEDCoupling1SGTUMesh("mesh",NORM_QUAD4) + m.setCoords(coo) + m.setNodalConnectivity(conn) + m=m.buildUnstructured() + m.convertLinearCellsToQuadratic() + self.assertTrue(m.conformize2D(eps).isEqual(DataArrayInt([0,1,2,5]))) + self.assertTrue(m.getCoords().getHiddenCppPointer()!=coo.getHiddenCppPointer()) # coordinates are not the same here contrary to testSwig2Conformize2D2 ... + self.assertTrue(m.getCoords()[:18].isEqual(coo,1e-12)) # but the 18 first nodes are the same + pass + + def testSwig2Conformize2D4(self): + eps = 1.0e-8 + coo=DataArrayDouble([-10,-6,0,-6,0,0,7,0,-10,2,0,2,0,6.5,7,6.5,0,8,7,8,-10,12,-4,12,0,12,0,11,7,11,-4,16,0,16,7,16],18,2) + conn=DataArrayInt([2,3,7,6, 13,16,17,14, 4,10,12,5, 9,14,13,8, 8,9,7,6, 5,4,0,1, 16,12,11,15]) + m=MEDCoupling1SGTUMesh("mesh",NORM_QUAD4) + m.setCoords(coo) + m.setNodalConnectivity(conn) + m=m.buildUnstructured() + m.convertLinearCellsToQuadratic() + self.assertEqual(42,m.getNumberOfNodes()) + oldCoo=m.getCoords().deepCpy() + m.conformize2D(eps) + self.assertTrue(m.getCoords()[:42].isEqual(oldCoo,1e-12)) + self.assertTrue(m.getNodalConnectivity().isEqual(DataArrayInt([32,2,3,7,6,5,18,19,20,42,43,32,13,12,16,17,14,44,38,23,24,25,32,4,10,11,12,13,8,6,5,26,45,39,44,31,34,42,29,8,9,14,13,8,30,25,31,32,8,8,9,7,6,32,33,20,34,32,5,4,0,1,2,29,35,36,46,43,8,16,12,11,15,38,39,40,41]))) + self.assertTrue(m.getNodalConnectivityIndex().isEqual(DataArrayInt([0,11,22,39,48,57,68,77]))) + self.assertTrue(m.getCoords().isEqual(DataArrayDouble([[-10.,-6.0],[0.,-6.0],[0.,0.0],[7.,0.0],[-10.,2.0],[0.,2.0],[0.,6.5],[7.,6.5],[0.,8.0],[7.,8.0],[-10.,12.0],[-4.,12.0],[0.,12.0],[0.,11.0],[7.,11.0],[-4.,16.0],[0.,16.0],[7.,16.0],[3.5, 0.0],[7.,3.25],[3.5, 6.5],[0.,3.25],[0.,13.5],[3.5, 16.0],[7.,13.5],[3.5, 11.0],[-10.,7.0],[-5.,12.0],[0.,7.0],[-5.,2.0],[7.,9.5],[0.,9.5],[3.5, 8.0],[7.,7.25],[0.,7.25],[-10.,-2.0],[-5.,-6.0],[0.,-2.0],[0.,14.0],[-2.,12.0],[-4.,14.0],[-2.,16.0],[0.,4.25],[0.,1.0],[0.,11.5],[-7.,12.0],[0.,-3.]]),1e-12)) + pass + + def testSwig2Conformize2D5(self): + eps=1e-8 + coo=DataArrayDouble([[2,2],[2,-6],[10,-2],[-2,-2],[6,0],[6,-4],[2,7],[2,4.5],[-1.4641016151377544,0],[-1.950753362380551,-1.3742621398390762],[-7,-3],[-0.8284271247461898,-4.82842712474619],[0.26794919243112281,3.5],[0,1.4641016151377548],[-4.4753766811902755,-2.1871310699195381],[-3.9142135623730949,-3.9142135623730949],[-1.8042260651806146,-3.23606797749979]]) + m=MEDCouplingUMesh("mesh",2) + m.allocateCells() + m.setCoords(coo) + m.insertNextCell(NORM_TRI6,[1,2,0,5,4,3]) + m.insertNextCell(NORM_TRI6,[8,6,0,12,7,13]) + m.insertNextCell(NORM_TRI6,[11,9,10,16,14,15]) + self.assertTrue(m.conformize2D(eps).isEqual(DataArrayInt([0]))) + self.assertTrue(m.getCoords().isEqual(DataArrayDouble([2.,2.,2.,-6.,10.,-2.,-2.,-2.,6.,0.,6.,-4.,2.,7.,2.,4.5,-1.4641016151377544,0.,-1.950753362380551,-1.3742621398390762,-7.,-3.,-0.8284271247461898,-4.82842712474619,0.2679491924311228,3.5,8.881784197001252e-16,1.4641016151377548,-4.4753766811902755,-2.187131069919538,-3.914213562373095,-3.914213562373095,-1.8042260651806146,-3.236067977499789,-1.7705659643687133,-0.6647725630649153,0.46926627053963865,-5.695518130045146],19,2),1e-12)) + self.assertTrue(m.getNodalConnectivity().isEqual(DataArrayInt([32,1,2,0,8,9,11,5,4,13,17,16,18,6,8,6,0,12,7,13,6,11,9,10,16,14,15]))) + self.assertTrue(m.getNodalConnectivityIndex().isEqual(DataArrayInt([0,13,20,27]))) + pass + + def testSwigExtendedSlice1(self): + d=DataArrayInt([5,6,7]) + self.assertTrue(d[2:].isEqual(DataArrayInt([7]))) + self.assertTrue(d[3:].isEqual(DataArrayInt([]))) + try: + d[4:] + except InterpKernelException as e: + self.assertTrue(True) + else: + self.assertTrue(False) + pass + d=DataArrayInt([5,6,7,8]) + self.assertEqual(d[-1],8) + self.assertEqual(d[-4],5) + try: + d[-5] + except InterpKernelException as e: + self.assertTrue(True) + else: + self.assertTrue(False) + pass + self.assertTrue(d[2::-1].isEqual(DataArrayInt([7,6,5]))) + self.assertTrue(d[0::-1].isEqual(DataArrayInt([5]))) + self.assertTrue(d[-1::-1].isEqual(DataArrayInt([8,7,6,5]))) + self.assertTrue(d[-3::-1].isEqual(DataArrayInt([6,5]))) + self.assertTrue(d[-5::-1].isEqual(DataArrayInt([]))) + try: + d[-6::-1] + except InterpKernelException as e: + self.assertTrue(True) + else: + self.assertTrue(False) + pass + d=DataArrayInt([]) + self.assertTrue(d[0:].isEqual(DataArrayInt([]))) + # + d=DataArrayDouble([5,6,7]) + self.assertTrue(d[2:].isEqual(DataArrayDouble([7]),1e-12)) + self.assertTrue(d[3:].isEqual(DataArrayDouble([]),1e-12)) + try: + d[4:] + except InterpKernelException as e: + self.assertTrue(True) + else: + self.assertTrue(False) + pass + d=DataArrayDouble([5,6,7,8]) + self.assertAlmostEqual(d[-1],8.,12) + self.assertAlmostEqual(d[-4],5.,12) + try: + d[-5] + except InterpKernelException as e: + self.assertTrue(True) + else: + self.assertTrue(False) + pass + self.assertTrue(d[2::-1].isEqual(DataArrayDouble([7,6,5]),1e-12)) + self.assertTrue(d[0::-1].isEqual(DataArrayDouble([5]),1e-12)) + self.assertTrue(d[-1::-1].isEqual(DataArrayDouble([8,7,6,5]),1e-12)) + self.assertTrue(d[-3::-1].isEqual(DataArrayDouble([6,5]),1e-12)) + self.assertTrue(d[-5::-1].isEqual(DataArrayDouble([]),1e-12)) + try: + d[-6::-1] + except InterpKernelException as e: + self.assertTrue(True) + else: + self.assertTrue(False) + pass + d=DataArrayDouble([]) + self.assertTrue(d[0:].isEqual(DataArrayDouble([]),1e-12)) + pass + + def testSwig2Hexa27GP1(self): + """ This test focused on shape functions of hexa27. + """ + coo=DataArrayDouble([[0.,2.,2.],[0.,0.,2.],[2.,0.,2.],[2.,2.,2.],[0.,2.,0.],[0.,0.,0.],[2.,0.,0.],[2.,2.,0.], [0.,1.,2.],[1.,0.,2.],[2.,1.,2.],[1.,2.,2.], [0.,1.,0.],[1.,0.,0.],[2.,1.,0.],[1.,2.,0.], [0.,2.,1.],[0.,0.,1.],[2.,0.,1.],[2.,2.,1.], [1.,1.,2.], [0.,1.,1.],[1.,0.,1.],[2.,1.,1.],[1.,2.,1.], [1.,1.,0.], [1.,1.,1.]]) + m=MEDCouplingUMesh("mesh",3) ; m.setCoords(coo) + m.allocateCells() + # the cell description is exactly those described in the description of HEXA27 in MED file 3.0.7 documentation + m.insertNextCell(NORM_HEXA27,[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26]) + refCoo=[-1.,-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.,0.,1.,-1.,1.,0.,-1.,0.,-1.,-1.,-1.,0.,1.,0.,1.,1.,1.,0.,1.,0.,-1.,1.,-1.,-1.,0.,-1.,1.,0.,1.,1.,0.,1.,-1.,0.,0.,0.,-1.,-1.,0.,0.,0.,1.,0.,1.,0.,0.,0.,-1.,0.,0.,0.,1.,0.,0.,0.] + weights=[0.1714677640603571,0.27434842249657115,0.1714677640603571,0.27434842249657115,0.43895747599451346,0.27434842249657115,0.1714677640603571,0.27434842249657115,0.1714677640603571,0.27434842249657115,0.43895747599451346,0.27434842249657115,0.43895747599451346,0.7023319615912209,0.43895747599451346,0.27434842249657115,0.43895747599451346,0.27434842249657115,0.1714677640603571,0.27434842249657115,0.1714677640603571,0.27434842249657115,0.43895747599451346,0.27434842249657115,0.1714677640603571,0.27434842249657115,0.1714677640603571] + gCoords=[-0.774596669241483,-0.774596669241483,-0.774596669241483,-0.774596669241483,-0.774596669241483,0.0,-0.774596669241483,-0.774596669241483,0.774596669241483,-0.774596669241483,0.0,-0.774596669241483,-0.774596669241483,0.0,0.0,-0.774596669241483,0.0,0.774596669241483,-0.774596669241483,0.774596669241483,-0.774596669241483,-0.774596669241483,0.774596669241483,0.0,-0.774596669241483,0.774596669241483,0.774596669241483,0.0,-0.774596669241483,-0.774596669241483,0.0,-0.774596669241483,0.0,0.0,-0.774596669241483,0.774596669241483,0.0,0.0,-0.774596669241483,0.0,0.0,0.0,0.0,0.0,0.774596669241483,0.0,0.774596669241483,-0.774596669241483,0.0,0.774596669241483,0.0,0.0,0.774596669241483,0.774596669241483,0.774596669241483,-0.774596669241483,-0.774596669241483,0.774596669241483,-0.774596669241483,0.0,0.774596669241483,-0.774596669241483,0.774596669241483,0.774596669241483,0.0,-0.774596669241483,0.774596669241483,0.0,0.0,0.774596669241483,0.0,0.774596669241483,0.774596669241483,0.774596669241483,-0.774596669241483,0.774596669241483,0.774596669241483,0.0,0.774596669241483,0.774596669241483,0.774596669241483] + fGauss=MEDCouplingFieldDouble(ON_GAUSS_PT) ; fGauss.setName("fGauss") + fGauss.setMesh(m) + fGauss.setGaussLocalizationOnType(NORM_HEXA27,refCoo,gCoords,weights) + arr=DataArrayDouble(fGauss.getNumberOfTuplesExpected()) ; arr.iota() + fGauss.setArray(arr) + arrOfDisc=fGauss.getLocalizationOfDiscr() + # the test is here + self.assertTrue(arrOfDisc.isEqual(DataArrayDouble([0.2254033307585172,1.7745966692414836,1.7745966692414834,0.22540333075851715,1.7745966692414834,1.,0.22540333075851715,1.7745966692414836,0.22540333075851715,0.22540333075851715,1.,1.7745966692414834,0.2254033307585171,1.,1.,0.22540333075851715,1.0000000000000002,0.2254033307585171,0.22540333075851715,0.22540333075851715,1.7745966692414838,0.22540333075851715,0.22540333075851715,1.,0.22540333075851715,0.22540333075851715,0.22540333075851715,1.,1.7745966692414832,1.7745966692414834,1.,1.774596669241483,1.,1.0000000000000002,1.7745966692414832,0.22540333075851712,1.,1.,1.774596669241483,1.,1.,1.,1.,1.,0.2254033307585171,1.,0.22540333075851715,1.7745966692414834,1.,0.2254033307585171,1.,1.0000000000000002,0.22540333075851715,0.2254033307585171,1.7745966692414834,1.7745966692414834,1.7745966692414836,1.7745966692414832,1.7745966692414834,1.0000000000000002,1.7745966692414834,1.7745966692414836,0.22540333075851712,1.7745966692414832,1.,1.7745966692414834,1.774596669241483,1.,1.,1.7745966692414832,1.0000000000000002,0.22540333075851712,1.7745966692414836,0.22540333075851715,1.7745966692414836,1.7745966692414832,0.22540333075851715,1.,1.7745966692414836,0.22540333075851715,0.22540333075851715],27,3),1e-12)) + # + weights=27*[1] + gCoords=refCoo + fGauss.setGaussLocalizationOnType(NORM_HEXA27,refCoo,gCoords,weights) + arrOfDisc2=fGauss.getLocalizationOfDiscr() + self.assertTrue(arrOfDisc2.isEqual(coo,1e-12)) + pass + + def testSwig2Pyra13GP1(self): + coo=DataArrayDouble([[0.,2.,0.],[2.,2.,0.],[2.,0.,0.],[0.,0.,0.],[1.,1.,2.],[1.,2.,0.],[2.,1.,0.],[1.,0.,0.],[0.,1.,0.],[0.5,1.5,1.],[1.5,1.5,1.],[1.5,0.5,1.],[0.5,0.5,1.]]) + m=MEDCouplingUMesh("mesh",3) ; m.setCoords(coo) + m.allocateCells() + # the cell description is exactly those described in the description of PYRA13 in MED file 3.0.7 documentation + m.insertNextCell(NORM_PYRA13,[0,1,2,3,4,5,6,7,8,9,10,11,12]) + refCoords=[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] + gaussCoords=[0.,0.,0.5,0.21210450275,0.21210450275,0.5,-0.21210450275,0.21210450275,0.5,-0.21210450275,-0.21210450275,0.5,0.21210450275,-0.21210450275,0.5,0.,0.,0.07579099449999999,0.,0.,0.9242090055000001,0.5394929090572634,0.,0.17359176399999998,0.,0.5394929090572634,0.17359176399999998,-0.5394929090572634,0.,0.17359176399999998,0.,-0.5394929090572634,0.17359176399999998,0.1133235629427366,0.,0.826408236,0.,0.1133235629427366,0.826408236,-0.1133235629427366,0.,0.826408236,0.,-0.1133235629427366,0.826408236,0.5826406005183961,0.5826406005183961,-0.053206449499999975,-0.5826406005183961,0.5826406005183961,-0.053206449499999975,-0.5826406005183961,-0.5826406005183961,-0.053206449499999975,0.5826406005183961,-0.5826406005183961,-0.053206449499999975,0.5532064495,0.,0.5,0.,0.5532064495,0.5,-0.5532064495,0.,0.5,0.,-0.5532064495,0.5,-0.029434151018396033,-0.029434151018396033,1.0532064495,0.029434151018396033,-0.029434151018396033,1.0532064495,0.029434151018396033,0.029434151018396033,1.0532064495,-0.029434151018396033,0.029434151018396033,1.0532064495] + weights=[0.0492545926875,0.031210562625,0.031210562625,0.031210562625,0.031210562625,0.10663554205740113,0.0007171281994273535,0.0816994048010844,0.0816994048010844,0.0816994048010844,0.0816994048010844,0.0036048554264914074,0.0036048554264914074,0.0036048554264914074,0.0036048554264914074,0.008958181586640837,0.008958181586640837,0.008958181586640837,0.008958181586640837,0.002018983875,0.002018983875,0.002018983875,0.002018983875,2.286237794882217e-05,2.286237794882217e-05,2.286237794882217e-05,2.286237794882217e-05] + fGauss=MEDCouplingFieldDouble(ON_GAUSS_PT) ; fGauss.setName("fGauss") + fGauss.setMesh(m) + fGauss.setGaussLocalizationOnType(NORM_PYRA13,refCoords,gaussCoords,weights) + arr=DataArrayDouble(fGauss.getNumberOfTuplesExpected()) ; arr.iota() + fGauss.setArray(arr) + arrOfDisc=fGauss.getLocalizationOfDiscr() + # the test is here + self.assertTrue(arrOfDisc.isEqual(DataArrayDouble([1.,1.,1.,0.5757909945,1.,1.,1.,0.5757909945,1.,1.4242090055,1.,1.,1.,1.4242090055,1.,1.,1.,0.151581989,1.,1.,1.848418011,0.4605070909427367,1.5394929090572635,0.347183528,0.4605070909427367,0.4605070909427367,0.347183528,1.5394929090572638,0.4605070909427366,0.347183528,1.5394929090572635,1.5394929090572638,0.347183528,0.8866764370572636,1.1133235629427367,1.652816472,0.8866764370572636,0.8866764370572636,1.652816472,1.1133235629427367,0.8866764370572636,1.652816472,1.1133235629427365,1.1133235629427367,1.652816472,-0.16528120103679209,1.,-0.106412899,1.,-0.1652812010367921,-0.106412899,2.1652812010367914,1.,-0.106412899,1.,2.165281201036791,-0.106412899,0.4467935505,1.5532064495,1.,0.4467935505,0.4467935505,1.,1.5532064495,0.4467935505,1.,1.5532064495,1.5532064495,1.,1.0588683020367922,1.,2.106412899,1.,1.0588683020367922,2.106412899,0.9411316979632077,1.,2.106412899,1.,0.9411316979632078,2.106412899],27,3),1e-12)) + # + weights=13*[1] + gaussCoords=refCoords[:] ; gaussCoords[14]=0.9999999999999 # change z of point #4 0.999... instead of 1. because with shape function it leads to division by 0. ! + fGauss.setGaussLocalizationOnType(NORM_PYRA13,refCoords,gaussCoords,weights) + arrOfDisc2=fGauss.getLocalizationOfDiscr() + self.assertTrue(arrOfDisc2.isEqual(coo,1e-10)) # be less exigent 1e-10 instead of 1e-12 due to shape function sensitivity arount 0.,0.,1. ! + pass + + def testSwig2Tri7GP1(self): + coo=DataArrayDouble([[0,0],[0,2],[2,0],[0,1],[1,1],[1,0],[0.6666666666666667,0.6666666666666667]]) + m=MEDCouplingUMesh("mesh",2) ; m.setCoords(coo) + m.allocateCells() + # the cell description is exactly those described in the description of TRI7 in MED file 3.0.7 documentation + m.insertNextCell(NORM_TRI7,range(7)) + refCoords=[0.,0.,1.,0.,0.,1.,0.5,0.,0.5,0.5,0.,0.5,0.3333333333333333,0.3333333333333333] + gaussCoords=[0.3333333333333333,0.3333333333333333,0.470142064105115,0.470142064105115,0.05971587178977,0.470142064105115,0.470142064105115,0.05971587178977,0.101286507323456,0.101286507323456,0.797426985353088,0.101286507323456,0.101286507323456,0.797426985353088] + weights=[0.062969590272413,0.062969590272413,0.062969590272413,0.066197076394253,0.066197076394253,0.066197076394253,0.1125] + fGauss=MEDCouplingFieldDouble(ON_GAUSS_PT) ; fGauss.setName("fGauss") + fGauss.setMesh(m) + fGauss.setGaussLocalizationOnType(NORM_TRI7,refCoords,gaussCoords,weights) + arr=DataArrayDouble(fGauss.getNumberOfTuplesExpected()) ; arr.iota() + fGauss.setArray(arr) + arrOfDisc=fGauss.getLocalizationOfDiscr() + self.assertTrue(arrOfDisc.isEqual(DataArrayDouble([0.666666666666667,0.666666666666667,0.9402841282102293,0.9402841282102293,0.9402841282102299,0.11943174357954002,0.11943174357953992,0.9402841282102299,0.20257301464691194,0.20257301464691196,0.20257301464691205,1.5948539707061757,1.5948539707061757,0.20257301464691202],7,2),1e-12)) + # + weights=7*[1] + gaussCoords=refCoords + fGauss.setGaussLocalizationOnType(NORM_TRI7,refCoords,gaussCoords,weights) + arrOfDisc2=fGauss.getLocalizationOfDiscr() + self.assertTrue(arrOfDisc2.isEqual(coo,1e-12)) + pass + + def testSwig2StructuredDesc1(self): + c=MEDCouplingCMesh() + arr0=DataArrayDouble(3) ; arr0.iota() + arr1=DataArrayDouble(4) ; arr1.iota() + arr2=DataArrayDouble(5) ; arr2.iota() + c.setCoords(arr0,arr1,arr2) + # + self.assertEqual(98,c.getNumberOfCellsOfSubLevelMesh()) + m=c.build1SGTSubLevelMesh() + self.assertTrue(m.getNodalConnectivity().isEqual(DataArrayInt([0,12,15,3,12,24,27,15,24,36,39,27,36,48,51,39,3,15,18,6,15,27,30,18,27,39,42,30,39,51,54,42,6,18,21,9,18,30,33,21,30,42,45,33,42,54,57,45,1,13,16,4,13,25,28,16,25,37,40,28,37,49,52,40,4,16,19,7,16,28,31,19,28,40,43,31,40,52,55,43,7,19,22,10,19,31,34,22,31,43,46,34,43,55,58,46,2,14,17,5,14,26,29,17,26,38,41,29,38,50,53,41,5,17,20,8,17,29,32,20,29,41,44,32,41,53,56,44,8,20,23,11,20,32,35,23,32,44,47,35,44,56,59,47,0,12,13,1,12,24,25,13,24,36,37,25,36,48,49,37,1,13,14,2,13,25,26,14,25,37,38,26,37,49,50,38,3,15,16,4,15,27,28,16,27,39,40,28,39,51,52,40,4,16,17,5,16,28,29,17,28,40,41,29,40,52,53,41,6,18,19,7,18,30,31,19,30,42,43,31,42,54,55,43,7,19,20,8,19,31,32,20,31,43,44,32,43,55,56,44,9,21,22,10,21,33,34,22,33,45,46,34,45,57,58,46,10,22,23,11,22,34,35,23,34,46,47,35,46,58,59,47,0,1,4,3,3,4,7,6,6,7,10,9,1,2,5,4,4,5,8,7,7,8,11,10,12,13,16,15,15,16,19,18,18,19,22,21,13,14,17,16,16,17,20,19,19,20,23,22,24,25,28,27,27,28,31,30,30,31,34,33,25,26,29,28,28,29,32,31,31,32,35,34,36,37,40,39,39,40,43,42,42,43,46,45,37,38,41,40,40,41,44,43,43,44,47,46,48,49,52,51,51,52,55,54,54,55,58,57,49,50,53,52,52,53,56,55,55,56,59,58]))) + self.assertEqual(NORM_QUAD4,m.getCellModelEnum()) + # + self.assertTrue(MEDCouplingStructuredMesh.Build1GTNodalConnectivityOfSubLevelMesh([3,7]).isEqual(DataArrayInt([0,3,3,6,6,9,9,12,12,15,15,18,1,4,4,7,7,10,10,13,13,16,16,19,2,5,5,8,8,11,11,14,14,17,17,20,0,1,1,2,3,4,4,5,6,7,7,8,9,10,10,11,12,13,13,14,15,16,16,17,18,19,19,20]))) + pass + + def testSwig2Colinearize2D1(self): + coo=DataArrayDouble([-5.,0.,-1.,0.,4.,3.,7.,0.,1.,6.,1.,0.,-3.,0.,6.,1.,5.,0.,3.,0.],10,2) + # + m=MEDCouplingUMesh("mesh",2) ; m.setCoords(coo) ; m.allocateCells() + m.insertNextCell(NORM_POLYGON,[5,9,8,3,7,2,4,0,6,1]) + refPtr=m.getCoords().getHiddenCppPointer() + self.assertTrue(m.colinearize2D(1e-12).isEqual(DataArrayInt([0]))) + self.assertEqual(refPtr,m.getCoords().getHiddenCppPointer()) + self.assertTrue(m.getNodalConnectivity().isEqual(DataArrayInt([5,0,3,4]))) + self.assertTrue(m.getNodalConnectivityIndex().isEqual(DataArrayInt([0,4]))) + self.assertTrue(m.colinearize2D(1e-12).isEqual(DataArrayInt([]))) + self.assertEqual(refPtr,m.getCoords().getHiddenCppPointer()) + self.assertTrue(m.getNodalConnectivity().isEqual(DataArrayInt([5,0,3,4]))) + self.assertTrue(m.getNodalConnectivityIndex().isEqual(DataArrayInt([0,4]))) + # + m=MEDCouplingUMesh("mesh",2) ; m.setCoords(coo) ; m.allocateCells() + m.insertNextCell(NORM_POLYGON,[8,3,7,2,4,0,6,1,5,9]) + refPtr=m.getCoords().getHiddenCppPointer() + self.assertTrue(m.colinearize2D(1e-12).isEqual(DataArrayInt([0]))) + self.assertEqual(refPtr,m.getCoords().getHiddenCppPointer()) + self.assertTrue(m.getNodalConnectivity().isEqual(DataArrayInt([5,0,3,4]))) + self.assertTrue(m.getNodalConnectivityIndex().isEqual(DataArrayInt([0,4]))) + # + m=MEDCouplingUMesh("mesh",2) ; m.setCoords(coo) ; m.allocateCells() + m.insertNextCell(NORM_POLYGON,[3,7,2,4,0,6,1,5,9,8]) + refPtr=m.getCoords().getHiddenCppPointer() + self.assertTrue(m.colinearize2D(1e-12).isEqual(DataArrayInt([0]))) + self.assertEqual(refPtr,m.getCoords().getHiddenCppPointer()) + self.assertTrue(m.getNodalConnectivity().isEqual(DataArrayInt([5,3,4,0]))) + self.assertTrue(m.getNodalConnectivityIndex().isEqual(DataArrayInt([0,4]))) + # + m=MEDCouplingUMesh("mesh",2) ; m.setCoords(coo) ; m.allocateCells() + m.insertNextCell(NORM_POLYGON,[4,0,6,1,5,9,8,3,7,2,]) + refPtr=m.getCoords().getHiddenCppPointer() + self.assertTrue(m.colinearize2D(1e-12).isEqual(DataArrayInt([0]))) + self.assertEqual(refPtr,m.getCoords().getHiddenCppPointer()) + self.assertTrue(m.getNodalConnectivity().isEqual(DataArrayInt([5,4,0,3]))) + self.assertTrue(m.getNodalConnectivityIndex().isEqual(DataArrayInt([0,4]))) + ## false quadratic + coo2=DataArrayDouble([(-5,0),(-1,0),(4,3),(7,0),(1,6),(1,0),(-3,0),(6,1),(5,0),(3,0),(2,0),(4,0),(6,0),(6.5,0.5),(5,2),(2.5,4.5),(-2,3),(-4,0),(-2,0),(0,0)]) + coo2.setInfoOnComponents(["aa","bbbb"]) + m=MEDCouplingUMesh("mesh",2) ; m.setCoords(coo2) ; m.allocateCells() + m.insertNextCell(NORM_QPOLYG,[5,9,8,3,7,2,4,0,6,1,10,11,12,13,14,15,16,17,18,19]) + refPtr=m.getCoords().getHiddenCppPointer() + self.assertTrue(m.colinearize2D(1e-12).isEqual(DataArrayInt([0]))) + self.assertNotEqual(refPtr,m.getCoords().getHiddenCppPointer())#not same coordinates here + self.assertEqual(["aa","bbbb"],m.getCoords().getInfoOnComponents()) + refPtr=m.getCoords().getHiddenCppPointer() + self.assertTrue(coo2.isEqual(m.getCoords()[:20],1e-12)) + self.assertTrue(m.getCoords()[20:].isEqualWithoutConsideringStr(DataArrayDouble([(1.,0.),(4.,3.)]),1e-12)) + self.assertTrue(m.getNodalConnectivity().isEqual(DataArrayInt([32,0,3,4,20,21,16]))) + self.assertTrue(m.getNodalConnectivityIndex().isEqual(DataArrayInt([0,7]))) + self.assertTrue(m.colinearize2D(1e-12).isEqual(DataArrayInt([]))) + self.assertEqual(refPtr,m.getCoords().getHiddenCppPointer()) + self.assertTrue(m.getNodalConnectivity().isEqual(DataArrayInt([32,0,3,4,20,21,16]))) + self.assertTrue(m.getNodalConnectivityIndex().isEqual(DataArrayInt([0,7]))) + # mix of quadratic and linear inside a QPOLYG cell + coo2=DataArrayDouble([(-5,0),(-1,0),(7.,6.),(7,0),(1,6),(1,0),(-3,0),(8.2426406871192839,3),(5,0),(3,0), (2,0),(4,0),(6,0),(7.9196888946291288,1.3764116995614091),(7.9196888946291288,4.6235883004385911),(4,7.2426406871192848),(-2,3),(-4,0),(-2,0),(0,0)]) + m=MEDCouplingUMesh("mesh",2) ; m.setCoords(coo2) ; m.allocateCells() + m.insertNextCell(NORM_QPOLYG,[5,9,8,3,7,2,4,0,6,1,10,11,12,13,14,15,16,17,18,19]) + refPtr=m.getCoords().getHiddenCppPointer() + self.assertTrue(m.colinearize2D(1e-12).isEqual(DataArrayInt([0]))) + self.assertNotEqual(refPtr,m.getCoords().getHiddenCppPointer())#not same coordinates here + self.assertTrue(coo2.isEqual(m.getCoords()[:20],1e-12)) + self.assertTrue(m.getCoords()[20:].isEqual(DataArrayDouble([(1.,0.),(7.,6.)]),1e-12)) + self.assertTrue(m.getNodalConnectivity().isEqual(DataArrayInt([32,0,3,4,20,21,16]))) + self.assertTrue(m.getNodalConnectivityIndex().isEqual(DataArrayInt([0,7]))) + pass + + def testSwig2BoundingBoxForBBTree1(self): + """ This test appears simple but it checks that bounding box are correctly computed for quadratic polygons. It can help a lot to reduce the amount of intersections ! + """ + coo=DataArrayDouble([-0.5,-0.5,-0.5,0.5,0.5,0.5,0.5,-0.5,0.45,0.,0.3181980515339464,0.31819805153394637,0.,0.45,-0.31819805153394637,0.3181980515339464,-0.45,0.,-0.3181980515339465,-0.31819805153394637,0.,-0.45,0.3181980515339463,-0.3181980515339465,-0.5,0.0,0.0,0.5,0.5,0.0,0.0,-0.5,-0.4090990257669732,-0.4090990257669732,0.40909902576697316,-0.4090990257669732],18,2) + m=MEDCouplingUMesh("mesh",2) ; m.setCoords(coo) + m.allocateCells() + m.insertNextCell(NORM_QPOLYG,[0,1,2,3,11,5,7,9,12,13,14,17,4,6,8,16]) + m.insertNextCell(NORM_QPOLYG,[3,0,9,11,15,16,10,17]) + self.assertTrue(m.getBoundingBoxForBBTree().isEqual(DataArrayDouble([-0.5,0.5,-0.5,0.5,-0.5,0.5,-0.5,-0.31819805153394637],2,4),1e-12)) + pass + + def testSwig2CartBuildUnstructuredOnExoticCases1(self): + """ Test focusing on traduction from cartesian to unstructured mesh when spaceDim greater than meshDim. + """ + # + m=MEDCouplingCMesh() + arrX=DataArrayDouble(3) ; arrX.iota() + arrY=DataArrayDouble(4) ; arrY.iota() + arrZ=DataArrayDouble(1) ; arrZ.iota() + m.setCoords(arrX,arrY,arrZ) + self.assertEqual(2,m.getMeshDimension()) + self.assertEqual(3,m.getSpaceDimension()) + mu=m.buildUnstructured() + self.assertTrue(mu.getNodalConnectivity().isEqual(DataArrayInt([4,1,0,3,4,4,2,1,4,5,4,4,3,6,7,4,5,4,7,8,4,7,6,9,10,4,8,7,10,11]))) + self.assertTrue(mu.getNodalConnectivityIndex().isEqual(DataArrayInt([0,5,10,15,20,25,30]))) + coo0=DataArrayDouble([(0,0,0),(1,0,0),(2,0,0),(0,1,0),(1,1,0),(2,1,0),(0,2,0),(1,2,0),(2,2,0),(0,3,0),(1,3,0),(2,3,0)]) + self.assertTrue(mu.getCoords().isEqual(coo0,1e-12)) + # + m=MEDCouplingCMesh() + arrX=DataArrayDouble(3) ; arrX.iota() + arrY=DataArrayDouble(1) ; arrY.iota() + arrZ=DataArrayDouble(4) ; arrZ.iota() + m.setCoords(arrX,arrY,arrZ) + self.assertEqual(2,m.getMeshDimension()) + self.assertEqual(3,m.getSpaceDimension()) + mu=m.buildUnstructured() + self.assertTrue(mu.getNodalConnectivity().isEqual(DataArrayInt([4,1,0,3,4,4,2,1,4,5,4,4,3,6,7,4,5,4,7,8,4,7,6,9,10,4,8,7,10,11]))) + self.assertTrue(mu.getNodalConnectivityIndex().isEqual(DataArrayInt([0,5,10,15,20,25,30]))) + coo1=DataArrayDouble([(0,0,0),(1,0,0),(2,0,0),(0,0,1),(1,0,1),(2,0,1),(0,0,2),(1,0,2),(2,0,2),(0,0,3),(1,0,3),(2,0,3)]) + self.assertTrue(mu.getCoords().isEqual(coo1,1e-12)) + # + m=MEDCouplingCMesh() + arrX=DataArrayDouble(1) ; arrX.iota() ; arrX+=9 + arrY=DataArrayDouble(3) ; arrY.iota() + arrZ=DataArrayDouble(4) ; arrZ.iota() + m.setCoords(arrX,arrY,arrZ) + self.assertEqual(2,m.getMeshDimension()) + self.assertEqual(3,m.getSpaceDimension()) + mu=m.buildUnstructured() + self.assertTrue(mu.getNodalConnectivity().isEqual(DataArrayInt([4,1,0,3,4,4,2,1,4,5,4,4,3,6,7,4,5,4,7,8,4,7,6,9,10,4,8,7,10,11]))) + self.assertTrue(mu.getNodalConnectivityIndex().isEqual(DataArrayInt([0,5,10,15,20,25,30]))) + coo2=DataArrayDouble([(9,0,0),(9,1,0),(9,2,0),(9,0,1),(9,1,1),(9,2,1),(9,0,2),(9,1,2),(9,2,2),(9,0,3),(9,1,3),(9,2,3)]) + self.assertTrue(mu.getCoords().isEqual(coo2,1e-12)) + # + m=MEDCouplingCMesh() + arrX=DataArrayDouble(3) ; arrX.iota() + arrY=DataArrayDouble(1) ; arrY.iota(7) + arrZ=DataArrayDouble(1) ; arrZ.iota(8) + m.setCoords(arrX,arrY,arrZ) + self.assertEqual(1,m.getMeshDimension()) + self.assertEqual(3,m.getSpaceDimension()) + mu=m.buildUnstructured() + self.assertTrue(mu.getNodalConnectivity().isEqual(DataArrayInt([1,0,1,1,1,2]))) + self.assertTrue(mu.getNodalConnectivityIndex().isEqual(DataArrayInt([0,3,6]))) + coo3=DataArrayDouble([(0,7,8),(1,7,8),(2,7,8)]) + self.assertTrue(mu.getCoords().isEqual(coo3,1e-12)) + # + m=MEDCouplingCMesh() + arrX=DataArrayDouble(1) ; arrX.iota(7) + arrY=DataArrayDouble(1) ; arrY.iota(8) + arrZ=DataArrayDouble(3) ; arrZ.iota() + m.setCoords(arrX,arrY,arrZ) + self.assertEqual(1,m.getMeshDimension()) + self.assertEqual(3,m.getSpaceDimension()) + mu=m.buildUnstructured() + self.assertTrue(mu.getNodalConnectivity().isEqual(DataArrayInt([1,0,1,1,1,2]))) + self.assertTrue(mu.getNodalConnectivityIndex().isEqual(DataArrayInt([0,3,6]))) + coo4=DataArrayDouble([(7,8,0),(7,8,1),(7,8,2)]) + self.assertTrue(mu.getCoords().isEqual(coo4,1e-12)) + # + m=MEDCouplingCMesh() + arrX=DataArrayDouble(3) ; arrX.iota() + arrY=DataArrayDouble(1) ; arrY.iota(7) + m.setCoords(arrX,arrY) + self.assertEqual(1,m.getMeshDimension()) + self.assertEqual(2,m.getSpaceDimension()) + mu=m.buildUnstructured() + self.assertTrue(mu.getNodalConnectivity().isEqual(DataArrayInt([1,0,1,1,1,2]))) + self.assertTrue(mu.getNodalConnectivityIndex().isEqual(DataArrayInt([0,3,6]))) + coo5=DataArrayDouble([(0,7),(1,7),(2,7)]) + self.assertTrue(mu.getCoords().isEqual(coo5,1e-12)) + # + m=MEDCouplingCMesh() + arrX=DataArrayDouble(1) ; arrX.iota(7) + arrY=DataArrayDouble(3) ; arrY.iota() + m.setCoords(arrX,arrY) + self.assertEqual(1,m.getMeshDimension()) + self.assertEqual(2,m.getSpaceDimension()) + mu=m.buildUnstructured() + self.assertTrue(mu.getNodalConnectivity().isEqual(DataArrayInt([1,0,1,1,1,2]))) + self.assertTrue(mu.getNodalConnectivityIndex().isEqual(DataArrayInt([0,3,6]))) + coo6=DataArrayDouble([(7,0),(7,1),(7,2)]) + self.assertTrue(mu.getCoords().isEqual(coo6,1e-12)) + pass + + def testSwig2Colinearize2D2(self): + """ simple non regression test but that has revealed a bug""" + coo=DataArrayDouble([(0,0),(0,0.5),(0,1),(1,1),(1,0),(0.5,0)]) + m=MEDCouplingUMesh("mesh",2) ; m.setCoords(coo) + m.allocateCells() ; m.insertNextCell(NORM_POLYGON,[0,1,2,3,4,5]) + m.checkCoherency2() + refPtr=m.getCoords().getHiddenCppPointer() + # + m.colinearize2D(1e-12) + m.checkCoherency2() + self.assertEqual(refPtr,m.getCoords().getHiddenCppPointer()) + self.assertTrue(m.getNodalConnectivity().isEqual(DataArrayInt([NORM_POLYGON,0,2,3,4]))) + self.assertTrue(m.getNodalConnectivityIndex().isEqual(DataArrayInt([0,5]))) + pass + + def testSwig2Colinearize2D3(self): + """ colinearize was too agressive, potentially producing cells with one edge """ + # Flat polygon with 3 edges - nothing should happen (min number of edges for a linear polyg) + coo = DataArrayDouble([0.0,0.0, 2.0,0.0, 1.5,0.0, 1.0,0.0, 0.5,0.0], 5,2) + m = MEDCouplingUMesh("m", 2) + c, cI = [DataArrayInt(l) for l in [[NORM_POLYGON, 0,1,2], [0,4]] ] + m.setCoords(coo); m.setConnectivity(c, cI) + m.colinearize2D(1e-10) + m.checkCoherency2() + self.assertEqual(c.getValues(), m.getNodalConnectivity().getValues()) + self.assertEqual(cI.getValues(), m.getNodalConnectivityIndex().getValues()) + + # Flat quad polygon, 2 edges - nothing should happen (min number of edges for a quad polyg) + m = MEDCouplingUMesh("m", 2) + c, cI = [DataArrayInt(l) for l in [[NORM_QPOLYG, 0,1, 2,3], [0,5]] ] + m.setCoords(coo); m.setConnectivity(c, cI) + m.colinearize2D(1e-10) + m.checkCoherency2() + self.assertEqual(c.getValues(), m.getNodalConnectivity().getValues()) + self.assertEqual(cI.getValues(), m.getNodalConnectivityIndex().getValues()) + + # Flat polygon, 4 edges - one reduction should happen + m = MEDCouplingUMesh("m", 2) + c, cI = [DataArrayInt(l) for l in [[NORM_POLYGON, 0,1,2,3], [0,5]] ] + m.setCoords(coo); m.setConnectivity(c, cI) + m.colinearize2D(1e-10) + m.checkCoherency2() + self.assertEqual([NORM_POLYGON, 3,1,2], m.getNodalConnectivity().getValues()) + self.assertEqual([0,4], m.getNodalConnectivityIndex().getValues()) + + # Flat quad polygon, 3 edges - one reduction expected + m = MEDCouplingUMesh("m", 2) + c, cI = [DataArrayInt(l) for l in [[NORM_QPOLYG, 0,1,3, 3,2,4], [0,7]] ] + m.setCoords(coo); m.setConnectivity(c, cI) + m.colinearize2D(1e-10) + m.checkCoherency2() + self.assertEqual([NORM_QPOLYG, 3,1, 5,2], m.getNodalConnectivity().getValues()) + self.assertTrue( m.getCoords()[5].isEqual( DataArrayDouble([(1.5,0.0)]), 1.0e-12 ) ) + self.assertEqual([0,5], m.getNodalConnectivityIndex().getValues()) + + # Now an actual (neutronic) case: circle made of 4 SEG3. Should be reduced to 2 SEG3 + m = MEDCouplingDataForTest.buildCircle2(0.0, 0.0, 1.0) + c, cI = [DataArrayInt(l) for l in [[NORM_QPOLYG, 7,5,3,1, 6,4,2,0], [0,9]] ] + m.colinearize2D(1e-10) + m.checkCoherency2() + self.assertEqual([NORM_QPOLYG, 3,5, 8,4], m.getNodalConnectivity().getValues()) + self.assertTrue( m.getCoords()[8].isEqual( DataArrayDouble([(1.0,0.0)]), 1.0e-12 ) ) + self.assertEqual([0,5], m.getNodalConnectivityIndex().getValues()) + + def testSwig2CheckAndPreparePermutation2(self): + a=DataArrayInt([10003,9999999,5,67]) + self.assertTrue(DataArrayInt.CheckAndPreparePermutation(a).isEqual(DataArrayInt([2,3,0,1]))) + a=DataArrayInt([10003,-9999999,5,67]) + self.assertTrue(DataArrayInt.CheckAndPreparePermutation(a).isEqual(DataArrayInt([3,0,1,2]))) + a=DataArrayInt([]) + self.assertTrue(DataArrayInt.checkAndPreparePermutation(a).isEqual(DataArrayInt([]))) + pass + + def testSwig2ComputeNeighborsOfNodes1(self): + arrX=DataArrayDouble(3) ; arrX.iota() + arrY=DataArrayDouble(4) ; arrY.iota() + arrZ=DataArrayDouble(5) ; arrZ.iota() + m=MEDCouplingCMesh() ; m.setCoords(arrX,arrY,arrZ) ; m=m.buildUnstructured() + # 3D + a,b=m.computeNeighborsOfNodes() + self.assertTrue(a.isEqual(DataArrayInt([1,3,12,0,4,13,2,1,5,14,0,4,15,6,3,1,16,5,7,4,2,17,8,3,7,18,9,6,4,19,8,10,7,5,20,11,6,10,21,9,7,22,11,10,8,23,13,15,0,24,12,16,1,14,25,13,17,2,26,12,16,3,18,27,15,13,4,17,19,28,16,14,5,20,29,15,19,6,21,30,18,16,7,20,22,31,19,17,8,23,32,18,22,9,33,21,19,10,23,34,22,20,11,35,25,27,12,36,24,28,13,26,37,25,29,14,38,24,28,15,30,39,27,25,16,29,31,40,28,26,17,32,41,27,31,18,33,42,30,28,19,32,34,43,31,29,20,35,44,30,34,21,45,33,31,22,35,46,34,32,23,47,37,39,24,48,36,40,25,38,49,37,41,26,50,36,40,27,42,51,39,37,28,41,43,52,40,38,29,44,53,39,43,30,45,54,42,40,31,44,46,55,43,41,32,47,56,42,46,33,57,45,43,34,47,58,46,44,35,59,49,51,36,48,52,37,50,49,53,38,48,52,39,54,51,49,40,53,55,52,50,41,56,51,55,42,57,54,52,43,56,58,55,53,44,59,54,58,45,57,55,46,59,58,56,47]))) + self.assertTrue(b.isEqual(DataArrayInt([0,3,7,10,14,19,23,27,32,36,39,43,46,50,55,59,64,70,75,80,86,91,95,100,104,108,113,117,122,128,133,138,144,149,153,158,162,166,171,175,180,186,191,196,202,207,211,216,220,223,227,230,234,239,243,247,252,256,259,263,266]))) + # 2D + m=MEDCouplingCMesh() ; m.setCoords(arrX,arrY) ; m=m.buildUnstructured() + a,b=m.computeNeighborsOfNodes() + self.assertTrue(a.isEqual(DataArrayInt([1,3,0,4,2,1,5,0,4,6,3,1,5,7,4,2,8,3,7,9,6,4,8,10,7,5,11,6,10,9,7,11,10,8]))) + self.assertTrue(b.isEqual(DataArrayInt([0,2,5,7,10,14,17,20,24,27,29,32,34]))) + # 1D + m=m.buildDescendingConnectivity()[0] + a,b=m.computeNeighborsOfNodes() + self.assertTrue(a.isEqual(DataArrayInt([1,3,0,4,2,1,5,0,4,6,3,1,5,7,4,2,8,3,7,9,6,4,8,10,7,5,11,6,10,9,7,11,10,8]))) + self.assertTrue(b.isEqual(DataArrayInt([0,2,5,7,10,14,17,20,24,27,29,32,34]))) + pass + + def testSwigBugOnUnpackingTuplesInDataArray1(self): + inp=DataArrayDouble([(1,2,3),(4,5,6),(7,8,9),(10,11,12)]) + it=inp.__iter__() + r=it.next() + self.assertRaises(StopIteration,r.__getitem__,4) + self.assertEqual(len(r),3) + a,b,c=r + r=it.next() + self.assertEqual(len(r),3) + d,e,f=r + r=it.next() + self.assertEqual(len(r),3) + g,h,i=r + r=it.next() + self.assertEqual(len(r),3) + j,k,l=r + self.assertTrue(inp.isEqual(DataArrayDouble([a,b,c,d,e,f,g,h,i,j,k,l],4,3),1e-12)) + ######## + inp=DataArrayInt([(1,2,3),(4,5,6),(7,8,9),(10,11,12)]) + it=inp.__iter__() + r=it.next() + self.assertRaises(StopIteration,r.__getitem__,4) + self.assertEqual(len(r),3) + a,b,c=r + r=it.next() + self.assertEqual(len(r),3) + d,e,f=r + r=it.next() + self.assertEqual(len(r),3) + g,h,i=r + r=it.next() + self.assertEqual(len(r),3) + j,k,l=r + self.assertTrue(inp.isEqual(DataArrayInt([a,b,c,d,e,f,g,h,i,j,k,l],4,3))) + pass + + def testSwig2IMesh1(self): + """ 1st test of image grid mesh. + """ + m=MEDCouplingIMesh() + self.assertEqual(m.getSpaceDimension(),-1) + self.assertEqual(1,len(m.__repr__().split("\n"))) + self.assertEqual(6,len(m.__str__().split("\n"))) + self.assertRaises(InterpKernelException,m.getNodeStruct) + self.assertRaises(InterpKernelException,m.getOrigin) + self.assertRaises(InterpKernelException,m.getDXYZ) + m.setSpaceDimension(3) + self.assertEqual(9,len(m.__str__().split("\n"))) + self.assertEqual(4,len(m.__repr__().split("\n"))) + self.assertEqual((0,0,0),m.getNodeStruct()) + self.assertEqual((0.,0.,0.),m.getOrigin()) + self.assertEqual((0.,0.,0.),m.getDXYZ()) + self.assertRaises(InterpKernelException,m.setNodeStruct,[3,4]) + m.setNodeStruct([3,4,2]) + self.assertEqual((3,4,2),m.getNodeStruct()) + m.setOrigin(DataArrayDouble([1.5,2.5,3.5])) + self.assertEqual((1.5,2.5,3.5),m.getOrigin()) + m.setDXYZ((0.5,1.,0.25)) + self.assertEqual((0.5,1.,0.25),m.getDXYZ()) + for it in DataArrayDouble([(1.5,2.5,3.5)]): + m2=MEDCouplingIMesh("",3,DataArrayInt([3,4,2]),it,DataArrayDouble((0.5,1.,0.25))) + pass + self.assertEqual(3,m.getSpaceDimension()) + self.assertEqual((3,4,2),m2.getNodeStruct()) + self.assertEqual((1.5,2.5,3.5),m2.getOrigin()) + self.assertEqual((0.5,1.,0.25),m2.getDXYZ()) + self.assertEqual(24,m2.getNumberOfNodes()) + self.assertEqual(6,m2.getNumberOfCells()) + self.assertTrue(m.isEqual(m2,1e-12)) ; self.assertTrue(m.isEqualWithoutConsideringStr(m2,1e-12)) + m2.setAxisUnit("m") + self.assertTrue(not m.isEqual(m2,1e-12)) ; self.assertTrue(m.isEqualWithoutConsideringStr(m2,1e-12)) + m.setAxisUnit("m") + self.assertTrue(m.isEqual(m2,1e-12)) ; self.assertTrue(m.isEqualWithoutConsideringStr(m2,1e-12)) + m.setName("mesh") + self.assertTrue(not m.isEqual(m2,1e-12)) ; self.assertTrue(m.isEqualWithoutConsideringStr(m2,1e-12)) + m2.setName("mesh") + self.assertTrue(m.isEqual(m2,1e-12)) ; self.assertTrue(m.isEqualWithoutConsideringStr(m2,1e-12)) + m2.setTime(1.1,0,3) + self.assertTrue(not m.isEqual(m2,1e-12)) + m.setTime(1.1,0,3) + self.assertTrue(m.isEqual(m2,1e-12)) + m.setTimeUnit("ms") + self.assertTrue(not m.isEqual(m2,1e-12)) ; self.assertTrue(m.isEqualWithoutConsideringStr(m2,1e-12)) + m2.setTimeUnit("ms") + self.assertTrue(m.isEqual(m2,1e-12)) ; self.assertTrue(m.isEqualWithoutConsideringStr(m2,1e-12)) + # + m2.setNodeStruct([3,2,4]) + self.assertTrue(not m.isEqual(m2,1e-12)) + m.setNodeStruct([3,2,4]) + self.assertTrue(m.isEqual(m2,1e-12)) + m.setOrigin(DataArrayDouble([1.5,3.5,2.5])) + self.assertTrue(not m.isEqual(m2,1e-12)) + m2.setOrigin([1.5,3.5,2.5]) + self.assertTrue(m.isEqual(m2,1e-12)) + m.setDXYZ((0.5,0.25,1.)) + self.assertTrue(not m.isEqual(m2,1e-12)) + m2.setDXYZ(DataArrayDouble((0.5,0.25,1.))) + self.assertTrue(m.isEqual(m2,1e-12)) + m2bis=m2.deepCpy() + self.assertTrue(m2bis.isEqual(m2,1e-12)) + # + self.assertEqual(6,m2bis.getNumberOfCells())#3,2,4 + m2bis.refineWithFactor([3,3,3]) + self.assertEqual(162,m2bis.getNumberOfCells()) + self.assertEqual((7,4,10),m2bis.getNodeStruct()) + self.assertEqual((1.5,3.5,2.5),m2bis.getOrigin()) + self.assertTrue(DataArrayDouble([0.16666666666666666,0.08333333333333333,0.3333333333333333]).isEqual(DataArrayDouble(m2bis.getDXYZ()),1e-12)) + # + self.assertEqual(3,m.getMeshDimension()) + self.assertAlmostEqual(0.125,m.getMeasureOfAnyCell(),16); + mu=MEDCoupling1SGTUMesh(m.buildUnstructured()) + mu.checkCoherency2() + cooExp=DataArrayDouble([(1.5,3.5,2.5),(2,3.5,2.5),(2.5,3.5,2.5),(1.5,3.75,2.5),(2,3.75,2.5),(2.5,3.75,2.5),(1.5,3.5,3.5),(2,3.5,3.5),(2.5,3.5,3.5),(1.5,3.75,3.5),(2,3.75,3.5),(2.5,3.75,3.5),(1.5,3.5,4.5),(2,3.5,4.5),(2.5,3.5,4.5),(1.5,3.75,4.5),(2,3.75,4.5),(2.5,3.75,4.5),(1.5,3.5,5.5),(2,3.5,5.5),(2.5,3.5,5.5),(1.5,3.75,5.5),(2,3.75,5.5),(2.5,3.75,5.5)]) ; cooExp.setInfoOnComponents(["X [m]","Y [m]","Z [m]"]) + self.assertTrue(isinstance(mu,MEDCoupling1SGTUMesh)) + self.assertEqual(NORM_HEXA8,mu.getCellModelEnum()) + self.assertTrue(mu.getCoords().isEqual(cooExp,1e-12)) + self.assertTrue(mu.getNodalConnectivity().isEqual(DataArrayInt([1,0,3,4,7,6,9,10,2,1,4,5,8,7,10,11,7,6,9,10,13,12,15,16,8,7,10,11,14,13,16,17,13,12,15,16,19,18,21,22,14,13,16,17,20,19,22,23]))) + bary=m.getBarycenterAndOwner() + baryExp=DataArrayDouble([(1.75,3.625,3),(2.25,3.625,3),(1.75,3.625,4),(2.25,3.625,4),(1.75,3.625,5),(2.25,3.625,5)]) ; baryExp.setInfoOnComponents(["X [m]","Y [m]","Z [m]"]) + self.assertTrue(bary.isEqual(baryExp,1e-12)) + # + c=m.convertToCartesian() + c.checkCoherency() + self.assertEqual([1.1,0,3],c.getTime()) + self.assertEqual("ms",c.getTimeUnit()) + self.assertEqual(3,c.getMeshDimension()) + self.assertEqual(3,c.getSpaceDimension()) + arrX=DataArrayDouble([1.5,2.,2.5]) ; arrX.setInfoOnComponents(["X [m]"]) + self.assertTrue(c.getCoordsAt(0).isEqual(arrX,1e-12)) + arrY=DataArrayDouble([3.5,3.75]) ; arrY.setInfoOnComponents(["Y [m]"]) + self.assertTrue(c.getCoordsAt(1).isEqual(arrY,1e-12)) + arrZ=DataArrayDouble([2.5,3.5,4.5,5.5]) ; arrZ.setInfoOnComponents(["Z [m]"]) + self.assertTrue(c.getCoordsAt(2).isEqual(arrZ,1e-12)) + self.assertTrue(c.buildUnstructured().isEqual(m.buildUnstructured(),1e-12)) + # + a,b=m.getCellsContainingPoints(baryExp,1e-12) + self.assertTrue(a.isEqual(DataArrayInt([0,1,2,3,4,5]))) + self.assertTrue(b.isEqual(DataArrayInt([0,1,2,3,4,5,6]))) + for a,b in enumerate(baryExp): + self.assertEqual(a,m.getCellContainingPoint(b,1e-12)) + pass + # + m.translate([1.,2.,4.]) + self.assertEqual((3,2,4),m.getNodeStruct()) + self.assertEqual((2.5,5.5,6.5),m.getOrigin()) + self.assertEqual((0.5,0.25,1.),m.getDXYZ()) + m.scale([0.,1.,3.],2.) + self.assertAlmostEqual(1.,m.getMeasureOfAnyCell(),16); + self.assertEqual((3,2,4),m.getNodeStruct()) + self.assertEqual((5.,10.,10.),m.getOrigin()) + self.assertEqual((1.,0.5,2.),m.getDXYZ()) + # + f=m.getMeasureField(False) + f2=MEDCouplingFieldDouble(ON_CELLS) ; f2.setTime(1.1,0,3) ; f2.setMesh(m) ; arr=DataArrayDouble(6) ; arr[:]=1. ; f2.setArray(arr) ; f2.setTimeUnit("ms") + f2.setName("MeasureOfMesh_mesh") + self.assertTrue(f.isEqual(f2,1e-12,1e-12)) + # + m3=m.buildStructuredSubPart([(1,2),(0,1),(1,3)]) + self.assertEqual((2,2,3),m3.getNodeStruct()) + self.assertEqual((6.,10.,12.),m3.getOrigin()) + self.assertEqual((1.,0.5,2.),m3.getDXYZ()) + # now playing with 3D surf + m4=MEDCouplingIMesh("",3,DataArrayInt([3,1,4]),DataArrayDouble([1.5,2.5,3.5]),DataArrayDouble((0.5,1.,0.25))) ; m4.setAxisUnit("km") + self.assertEqual([(1.5,2.5),(2.5,3.5),(3.5,4.25)],m4.getBoundingBox()) + self.assertEqual(3,m4.getSpaceDimension()) + self.assertEqual(2,m4.getMeshDimension()) + self.assertEqual(12,m4.getNumberOfNodes()) + self.assertEqual(6,m4.getNumberOfCells()) + mu=MEDCoupling1SGTUMesh(m4.buildUnstructured()) + mu.checkCoherency2() + self.assertTrue(isinstance(mu,MEDCoupling1SGTUMesh)) + self.assertEqual(NORM_QUAD4,mu.getCellModelEnum()) + coordsExp=DataArrayDouble([(1.5,2.5,3.5),(2,2.5,3.5),(2.5,2.5,3.5),(1.5,2.5,3.75),(2,2.5,3.75),(2.5,2.5,3.75),(1.5,2.5,4),(2,2.5,4),(2.5,2.5,4),(1.5,2.5,4.25),(2,2.5,4.25),(2.5,2.5,4.25)]) ; coordsExp.setInfoOnComponents(["X [km]","Y [km]","Z [km]"]) + self.assertTrue(mu.getCoords().isEqual(coordsExp,1e-12)) + self.assertTrue(mu.getNodalConnectivity().isEqual(DataArrayInt([1,0,3,4,2,1,4,5,4,3,6,7,5,4,7,8,7,6,9,10,8,7,10,11]))) + pass + + def testSwig1GetValuesAsTuple1(self): + d=DataArrayDouble() + self.assertEqual(d.getValues(),[]) + self.assertEqual(d.getValuesAsTuple(),[]) + d=DataArrayDouble(24) ; d.iota() ; d.rearrange(3) + self.assertEqual(d.getValues(),[0.,1.,2.,3.,4.,5.,6.,7.,8.,9.,10.,11.,12.,13.,14.,15.,16.,17.,18.,19.,20.,21.,22.,23.]) + self.assertEqual(d.getValuesAsTuple(),[(0.,1.,2.0),(3.,4.,5.0),(6.,7.,8.0),(9.,10.,11.0),(12.,13.,14.0),(15.,16.,17.0),(18.,19.,20.0),(21.,22.,23.)]) + d=DataArrayInt() + self.assertEqual(d.getValues(),[]) + self.assertEqual(d.getValuesAsTuple(),[]) + d=DataArrayInt(24) ; d.iota() ; d.rearrange(3) + self.assertEqual(d.getValues(),[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23]) + self.assertEqual(d.getValuesAsTuple(),[(0,1,2),(3,4,5),(6,7,8),(9,10,11),(12,13,14),(15,16,17),(18,19,20),(21,22,23)]) + pass + + def testSwig2AMR1(self): + self.assertEqual((1,3,12),MEDCouplingStructuredMesh.GetSplitVectFromStruct([3,4,5])) + self.assertEqual((3,2),MEDCouplingStructuredMesh.GetDimensionsFromCompactFrmt([(1,4),(2,4)])) + # + amr=MEDCouplingCartesianAMRMesh("",2,[3,3],[0,0],[1,1]) + self.assertEqual(4,amr.getNumberOfCellsAtCurrentLevel()) + self.assertEqual(4,amr.getNumberOfCellsRecursiveWithOverlap()) + self.assertEqual(4,amr.getNumberOfCellsRecursiveWithoutOverlap()) + self.assertEqual(0,amr.getNumberOfPatches()) + self.assertEqual(1,amr.getMaxNumberOfLevelsRelativeToThis()) + self.assertEqual(2,amr.getSpaceDimension()) + amr.addPatch([(1,2),(0,1)],[4,4]) + self.assertEqual(4,amr.getNumberOfCellsAtCurrentLevel()) + self.assertEqual(20,amr.getNumberOfCellsRecursiveWithOverlap()) + self.assertEqual(19,amr.getNumberOfCellsRecursiveWithoutOverlap()) + self.assertEqual(1,amr.getNumberOfPatches()) + self.assertEqual(2,amr.getMaxNumberOfLevelsRelativeToThis()) + self.assertEqual(2,amr.getSpaceDimension()) + amr[0].addPatch([(2,3),(1,3)],[3,2]) + self.assertEqual(amr[0].getBLTRRange(),[(1,2),(0,1)]) + self.assertEqual(4,amr.getNumberOfCellsAtCurrentLevel()) + self.assertEqual(32,amr.getNumberOfCellsRecursiveWithOverlap()) + self.assertEqual(29,amr.getNumberOfCellsRecursiveWithoutOverlap()) + self.assertEqual(1,amr.getNumberOfPatches()) + self.assertEqual(3,amr.getMaxNumberOfLevelsRelativeToThis()) + self.assertEqual(2,amr.getSpaceDimension()) + amr[0].addPatch([(0,2),(3,4)],[3,2]) + self.assertEqual(16,amr[0].getMesh().getNumberOfCellsAtCurrentLevel()) + self.assertEqual(44,amr.getNumberOfCellsRecursiveWithOverlap()) + self.assertEqual(39,amr.getNumberOfCellsRecursiveWithoutOverlap()) + self.assertEqual(2,amr[0].getMesh().getNumberOfPatches()) + self.assertEqual(3,amr.getMaxNumberOfLevelsRelativeToThis()) + self.assertEqual(2,amr.getSpaceDimension()) + del amr[0][1] + self.assertEqual(amr[0].getBLTRRange(),[(1,2),(0,1)]) + self.assertEqual(4,amr.getNumberOfCellsAtCurrentLevel()) + self.assertEqual(32,amr.getNumberOfCellsRecursiveWithOverlap()) + self.assertEqual(29,amr.getNumberOfCellsRecursiveWithoutOverlap()) + self.assertEqual(1,amr.getNumberOfPatches()) + self.assertEqual(3,amr.getMaxNumberOfLevelsRelativeToThis()) + self.assertEqual(2,amr.getSpaceDimension()) + pass + + def testSwig2NonRegressionTestPAL1164(self): + """ Test PAL1164 Protection of applyLin against error in compoId ( #CEA22584 ) """ + xarr=DataArrayDouble(3,1) + xarr.iota(0.) + cmesh=MEDCouplingCMesh() + cmesh.setCoords(xarr,xarr,xarr) + mesh=cmesh.buildUnstructured() + f=mesh.fillFromAnalytic(ON_CELLS,1,"(x-5.)*(x-5.)+(y-5.)*(y-5.)+(z-5.)*(z-5.)") + f.setName("MyField") + self.assertTrue(f.getArray().isEqual(DataArrayDouble([60.75,52.75,52.75,44.75,52.75,44.75,44.75,36.75]),1e-12)) + self.assertRaises(InterpKernelException,f.applyLin,2.,0.,1)# compoId 1 whereas f has only one component ! + self.assertTrue(f.getArray().isEqual(DataArrayDouble([60.75,52.75,52.75,44.75,52.75,44.75,44.75,36.75]),1e-12)) + f.applyLin(2.,0.,0)# here it is OK ! + self.assertTrue(f.getArray().isEqual(DataArrayDouble([121.5,105.5,105.5,89.5,105.5,89.5,89.5,73.5]),1e-12)) + f.applyLin(2.,0.) + self.assertTrue(f.getArray().isEqual(DataArrayDouble([243.,211.,211.,179.,211.,179.,179.,147.]),1e-12)) + pass + + def testSwig2StructurizeMe1(self): + arrx=DataArrayDouble(3) ; arrx.iota() ; arrx*=2. + arry=DataArrayDouble(4) ; arry.iota() ; arry+=3. + arrz=DataArrayDouble(5) ; arrz.iota() ; arrz*=0.5 ; arrz+=2. + c=MEDCouplingCMesh() ; c.setCoords(arrx,arry,arrz) + c.setName("mesh") ; c.setDescription("mesh descr") ; c.setTimeUnit("us") ; c.setTime(1.2,3,4) + u=c.buildUnstructured() + cp=DataArrayInt([3,5,6,1,0,9,8,7,12,11,16,10,17,23,22,21,19,20,18,14,13,2,4,15]) + np=DataArrayInt([3,33,5,35,6,36,1,31,0,30,9,39,8,38,7,37,12,42,11,41,16,46,10,40,17,47,23,53,22,52,21,51,19,49,20,50,18,48,14,44,13,43,2,32,4,34,15,45,29,59,28,58,27,57,26,56,25,55,24,54]) + u.renumberCells(cp) + u.renumberNodes(np,len(np)) + u=MEDCoupling1SGTUMesh(u) + # + e,d,f=u.structurizeMe() + self.assertTrue(c.isEqual(e,1e-12)) + self.assertTrue(d.isEqual(cp)) + self.assertTrue(f.isEqual(np)) + pass + + def testSwig2DenseMatrix1(self): + m0=DenseMatrix(DataArrayDouble([2,3,4,5,1,6]),2,3) + self.assertEqual(m0.getNumberOfRows(),2) + self.assertEqual(m0.getNumberOfCols(),3) + self.assertEqual(m0.getNbOfElems(),6) + ref=m0.getData().getHiddenCppPointer() + m00=m0.deepCpy() + self.assertTrue(m0.isEqual(m00,1e-12)) + m00.getData().setIJ(0,0,2.1) + self.assertTrue(not m0.isEqual(m00,1e-12)) + m00.getData().setIJ(0,0,2.) + self.assertTrue(m0.isEqual(m00,1e-12)) + self.assertTrue(m0.getData().isEqual(DataArrayDouble([2,3,4,5,1,6]),1e-12)) + # + m000=m0*DataArrayDouble([5,9,3]) + self.assertTrue(m000.getData().isEqual(DataArrayDouble([49.,52.]),1e-12)) + # + m0.reShape(3,2) + self.assertTrue(not m0.isEqual(m00,1e-12)) + self.assertEqual(m0.getNumberOfRows(),3) + self.assertEqual(m0.getNumberOfCols(),2) + self.assertEqual(ref,m0.getData().getHiddenCppPointer()) + self.assertTrue(m0.getData().isEqual(DataArrayDouble([2,3,4,5,1,6]),1e-12)) + m0.reShape(2,3) + self.assertTrue(m0.isEqual(m00,1e-12)) + self.assertEqual(ref,m0.getData().getHiddenCppPointer()) + self.assertEqual(m0.getNumberOfRows(),2) + self.assertEqual(m0.getNumberOfCols(),3) + self.assertTrue(m0.getData().isEqual(DataArrayDouble([2,3,4,5,1,6]),1e-12)) + #m0np=m0.getData().toNumPyArray() ; m0np=matrix(m0np.reshape(m0.getNumberOfRows(),m0.getNumberOfCols())) + m1=m0.deepCpy() + self.assertEqual(m1.getNumberOfRows(),2) + self.assertEqual(m1.getNumberOfCols(),3) + self.assertTrue(m1.getData().isEqual(DataArrayDouble([2,3,4,5,1,6]),1e-12)) + m11=m0.deepCpy() ; m11+=m1 + self.assertEqual(m11.getNumberOfRows(),2) + self.assertEqual(m11.getNumberOfCols(),3) + self.assertTrue(m11.getData().isEqual(DataArrayDouble([4,6,8,10,2,12]),1e-12)) + m11=m11+m1 + self.assertEqual(m11.getNumberOfRows(),2) + self.assertEqual(m11.getNumberOfCols(),3) + self.assertTrue(m11.getData().isEqual(DataArrayDouble([6,9,12,15,3,18]),1e-12)) + m11=m11-m1 + self.assertEqual(m11.getNumberOfRows(),2) + self.assertEqual(m11.getNumberOfCols(),3) + self.assertTrue(m11.getData().isEqual(DataArrayDouble([4,6,8,10,2,12]),1e-12)) + m11-=m1 + self.assertEqual(m1.getNumberOfRows(),2) + self.assertEqual(m1.getNumberOfCols(),3) + self.assertTrue(m1.getData().isEqual(DataArrayDouble([2,3,4,5,1,6]),1e-12)) + m1.transpose() + self.assertEqual(m1.getNumberOfRows(),3) + self.assertEqual(m1.getNumberOfCols(),2) + self.assertTrue(m1.getData().isEqual(DataArrayDouble([2,5,3,1,4,6]),1e-12)) + #m1np=m0np.transpose() + m2=m0*m1 + self.assertEqual(m2.getNumberOfRows(),2) + self.assertEqual(m2.getNumberOfCols(),2) + self.assertTrue(m2.getData().isEqual(DataArrayDouble([29,37,37,62]),1e-12)) + pass + + def testSwig2AMR2(self): + """ Test condensation of fine IMesh instance into a coarse one, with a factor. See testRemapperAMR1 in MEDCouplingRemapperTest.py file to see how the expected value is obtained.""" + coarse=DataArrayDouble(35) ; coarse.iota(0) #X=5,Y=7 + fine=DataArrayDouble(3*2*4*4) ; fine.iota(0) #X=3,Y=2 refined by 4 + MEDCouplingIMesh.CondenseFineToCoarse([5,7],fine,[(1,4),(2,4)],[4,4],coarse) + self.assertTrue(coarse.isEqual(DataArrayDouble([0,1,2,3,4,5,6,7,8,9,10,312,376,440,14,15,1080,1144,1208,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34]),1e-12)) + # 3D + coarse=DataArrayDouble(175) ; coarse.iota(0) #X=5,Y=7,Z=5 + fine=DataArrayDouble(3*2*3*4*4*4) ; fine.iota(0) #X=3,Y=2,Z=3 refined by 4 + MEDCouplingIMesh.CondenseFineToCoarse([5,7,5],fine,[(1,4),(2,4),(1,4)],[4,4,4],coarse) + self.assertTrue(coarse.isEqual(DataArrayDouble([0.,1.,2.,3.,4.,5.,6.,7.,8.,9.,10.,11.,12.,13.,14.,15.,16.,17.,18.,19.,20.,21.,22.,23.,24.,25.,26.,27.,28.,29.,30.,31.,32.,33.,34.,35.,36.,37.,38.,39.,40.,41.,42.,43.,44.,45.,10464.,10720.,10976.,49.,50.,13536.,13792.,14048.,54.,55.,56.,57.,58.,59.,60.,61.,62.,63.,64.,65.,66.,67.,68.,69.,70.,71.,72.,73.,74.,75.,76.,77.,78.,79.,80.,35040.,35296.,35552.,84.,85.,38112.,38368.,38624.,89.,90.,91.,92.,93.,94.,95.,96.,97.,98.,99.,100.,101.,102.,103.,104.,105.,106.,107.,108.,109.,110.,111.,112.,113.,114.,115.,59616.,59872.,60128.,119.,120.,62688.,62944.,63200.,124.,125.,126.,127.,128.,129.,130.,131.,132.,133.,134.,135.,136.,137.,138.,139.,140.,141.,142.,143.,144.,145.,146.,147.,148.,149.,150.,151.,152.,153.,154.,155.,156.,157.,158.,159.,160.,161.,162.,163.,164.,165.,166.,167.,168.,169.,170.,171.,172.,173.,174.]),1e-12)) + # 1D + coarse=DataArrayDouble(5) ; coarse.iota(0) #X=5 + fine=DataArrayDouble(3*4) ; fine.iota(0) #X=3 refined by 4 + MEDCouplingIMesh.CondenseFineToCoarse([5],fine,[(1,4)],[4],coarse) + self.assertTrue(coarse.isEqual(DataArrayDouble([0,6,22,38,4]),1e-12)) + pass + + def testSwig2AMR3(self): + """ Test spread of coarse IMesh instance into a fine one, with a factor.""" + coarse=DataArrayDouble(35) ; coarse.iota(0) #X=5,Y=7 + fine=DataArrayDouble(3*2*4*4) ; fine.iota(0) #X=3,Y=2 refined by 4 + MEDCouplingIMesh.SpreadCoarseToFine(coarse,[5,7],fine,[(1,4),(2,4)],[4,4]) + self.assertTrue(fine.isEqual(DataArrayDouble([11.,11.,11.,11.,12.,12.,12.,12.,13.,13.,13.,13.,11.,11.,11.,11.,12.,12.,12.,12.,13.,13.,13.,13.,11.,11.,11.,11.,12.,12.,12.,12.,13.,13.,13.,13.,11.,11.,11.,11.,12.,12.,12.,12.,13.,13.,13.,13.,16.,16.,16.,16.,17.,17.,17.,17.,18.,18.,18.,18.,16.,16.,16.,16.,17.,17.,17.,17.,18.,18.,18.,18.,16.,16.,16.,16.,17.,17.,17.,17.,18.,18.,18.,18.,16.,16.,16.,16.,17.,17.,17.,17.,18.,18.,18.,18.]),1e-12)) + # 3D + coarse=DataArrayDouble(175) ; coarse.iota(0) #X=5,Y=7,Z=5 + fine=DataArrayDouble(3*2*3*4*4*4) ; fine.iota(0) #X=3,Y=2,Z=3 refined by 4 + MEDCouplingIMesh.SpreadCoarseToFine(coarse,[5,7,5],fine,[(1,4),(2,4),(1,4)],[4,4,4]) + self.assertTrue(fine.isEqual(DataArrayDouble([46.,46.,46.,46.,47.,47.,47.,47.,48.,48.,48.,48.,46.,46.,46.,46.,47.,47.,47.,47.,48.,48.,48.,48.,46.,46.,46.,46.,47.,47.,47.,47.,48.,48.,48.,48.,46.,46.,46.,46.,47.,47.,47.,47.,48.,48.,48.,48.,51.,51.,51.,51.,52.,52.,52.,52.,53.,53.,53.,53.,51.,51.,51.,51.,52.,52.,52.,52.,53.,53.,53.,53.,51.,51.,51.,51.,52.,52.,52.,52.,53.,53.,53.,53.,51.,51.,51.,51.,52.,52.,52.,52.,53.,53.,53.,53.,46.,46.,46.,46.,47.,47.,47.,47.,48.,48.,48.,48.,46.,46.,46.,46.,47.,47.,47.,47.,48.,48.,48.,48.,46.,46.,46.,46.,47.,47.,47.,47.,48.,48.,48.,48.,46.,46.,46.,46.,47.,47.,47.,47.,48.,48.,48.,48.,51.,51.,51.,51.,52.,52.,52.,52.,53.,53.,53.,53.,51.,51.,51.,51.,52.,52.,52.,52.,53.,53.,53.,53.,51.,51.,51.,51.,52.,52.,52.,52.,53.,53.,53.,53.,51.,51.,51.,51.,52.,52.,52.,52.,53.,53.,53.,53.,46.,46.,46.,46.,47.,47.,47.,47.,48.,48.,48.,48.,46.,46.,46.,46.,47.,47.,47.,47.,48.,48.,48.,48.,46.,46.,46.,46.,47.,47.,47.,47.,48.,48.,48.,48.,46.,46.,46.,46.,47.,47.,47.,47.,48.,48.,48.,48.,51.,51.,51.,51.,52.,52.,52.,52.,53.,53.,53.,53.,51.,51.,51.,51.,52.,52.,52.,52.,53.,53.,53.,53.,51.,51.,51.,51.,52.,52.,52.,52.,53.,53.,53.,53.,51.,51.,51.,51.,52.,52.,52.,52.,53.,53.,53.,53.,46.,46.,46.,46.,47.,47.,47.,47.,48.,48.,48.,48.,46.,46.,46.,46.,47.,47.,47.,47.,48.,48.,48.,48.,46.,46.,46.,46.,47.,47.,47.,47.,48.,48.,48.,48.,46.,46.,46.,46.,47.,47.,47.,47.,48.,48.,48.,48.,51.,51.,51.,51.,52.,52.,52.,52.,53.,53.,53.,53.,51.,51.,51.,51.,52.,52.,52.,52.,53.,53.,53.,53.,51.,51.,51.,51.,52.,52.,52.,52.,53.,53.,53.,53.,51.,51.,51.,51.,52.,52.,52.,52.,53.,53.,53.,53.,81.,81.,81.,81.,82.,82.,82.,82.,83.,83.,83.,83.,81.,81.,81.,81.,82.,82.,82.,82.,83.,83.,83.,83.,81.,81.,81.,81.,82.,82.,82.,82.,83.,83.,83.,83.,81.,81.,81.,81.,82.,82.,82.,82.,83.,83.,83.,83.,86.,86.,86.,86.,87.,87.,87.,87.,88.,88.,88.,88.,86.,86.,86.,86.,87.,87.,87.,87.,88.,88.,88.,88.,86.,86.,86.,86.,87.,87.,87.,87.,88.,88.,88.,88.,86.,86.,86.,86.,87.,87.,87.,87.,88.,88.,88.,88.,81.,81.,81.,81.,82.,82.,82.,82.,83.,83.,83.,83.,81.,81.,81.,81.,82.,82.,82.,82.,83.,83.,83.,83.,81.,81.,81.,81.,82.,82.,82.,82.,83.,83.,83.,83.,81.,81.,81.,81.,82.,82.,82.,82.,83.,83.,83.,83.,86.,86.,86.,86.,87.,87.,87.,87.,88.,88.,88.,88.,86.,86.,86.,86.,87.,87.,87.,87.,88.,88.,88.,88.,86.,86.,86.,86.,87.,87.,87.,87.,88.,88.,88.,88.,86.,86.,86.,86.,87.,87.,87.,87.,88.,88.,88.,88.,81.,81.,81.,81.,82.,82.,82.,82.,83.,83.,83.,83.,81.,81.,81.,81.,82.,82.,82.,82.,83.,83.,83.,83.,81.,81.,81.,81.,82.,82.,82.,82.,83.,83.,83.,83.,81.,81.,81.,81.,82.,82.,82.,82.,83.,83.,83.,83.,86.,86.,86.,86.,87.,87.,87.,87.,88.,88.,88.,88.,86.,86.,86.,86.,87.,87.,87.,87.,88.,88.,88.,88.,86.,86.,86.,86.,87.,87.,87.,87.,88.,88.,88.,88.,86.,86.,86.,86.,87.,87.,87.,87.,88.,88.,88.,88.,81.,81.,81.,81.,82.,82.,82.,82.,83.,83.,83.,83.,81.,81.,81.,81.,82.,82.,82.,82.,83.,83.,83.,83.,81.,81.,81.,81.,82.,82.,82.,82.,83.,83.,83.,83.,81.,81.,81.,81.,82.,82.,82.,82.,83.,83.,83.,83.,86.,86.,86.,86.,87.,87.,87.,87.,88.,88.,88.,88.,86.,86.,86.,86.,87.,87.,87.,87.,88.,88.,88.,88.,86.,86.,86.,86.,87.,87.,87.,87.,88.,88.,88.,88.,86.,86.,86.,86.,87.,87.,87.,87.,88.,88.,88.,88.,116.,116.,116.,116.,117.,117.,117.,117.,118.,118.,118.,118.,116.,116.,116.,116.,117.,117.,117.,117.,118.,118.,118.,118.,116.,116.,116.,116.,117.,117.,117.,117.,118.,118.,118.,118.,116.,116.,116.,116.,117.,117.,117.,117.,118.,118.,118.,118.,121.,121.,121.,121.,122.,122.,122.,122.,123.,123.,123.,123.,121.,121.,121.,121.,122.,122.,122.,122.,123.,123.,123.,123.,121.,121.,121.,121.,122.,122.,122.,122.,123.,123.,123.,123.,121.,121.,121.,121.,122.,122.,122.,122.,123.,123.,123.,123.,116.,116.,116.,116.,117.,117.,117.,117.,118.,118.,118.,118.,116.,116.,116.,116.,117.,117.,117.,117.,118.,118.,118.,118.,116.,116.,116.,116.,117.,117.,117.,117.,118.,118.,118.,118.,116.,116.,116.,116.,117.,117.,117.,117.,118.,118.,118.,118.,121.,121.,121.,121.,122.,122.,122.,122.,123.,123.,123.,123.,121.,121.,121.,121.,122.,122.,122.,122.,123.,123.,123.,123.,121.,121.,121.,121.,122.,122.,122.,122.,123.,123.,123.,123.,121.,121.,121.,121.,122.,122.,122.,122.,123.,123.,123.,123.,116.,116.,116.,116.,117.,117.,117.,117.,118.,118.,118.,118.,116.,116.,116.,116.,117.,117.,117.,117.,118.,118.,118.,118.,116.,116.,116.,116.,117.,117.,117.,117.,118.,118.,118.,118.,116.,116.,116.,116.,117.,117.,117.,117.,118.,118.,118.,118.,121.,121.,121.,121.,122.,122.,122.,122.,123.,123.,123.,123.,121.,121.,121.,121.,122.,122.,122.,122.,123.,123.,123.,123.,121.,121.,121.,121.,122.,122.,122.,122.,123.,123.,123.,123.,121.,121.,121.,121.,122.,122.,122.,122.,123.,123.,123.,123.,116.,116.,116.,116.,117.,117.,117.,117.,118.,118.,118.,118.,116.,116.,116.,116.,117.,117.,117.,117.,118.,118.,118.,118.,116.,116.,116.,116.,117.,117.,117.,117.,118.,118.,118.,118.,116.,116.,116.,116.,117.,117.,117.,117.,118.,118.,118.,118.,121.,121.,121.,121.,122.,122.,122.,122.,123.,123.,123.,123.,121.,121.,121.,121.,122.,122.,122.,122.,123.,123.,123.,123.,121.,121.,121.,121.,122.,122.,122.,122.,123.,123.,123.,123.,121.,121.,121.,121.,122.,122.,122.,122.,123.,123.,123.,123.]),1e-12)) + f=MEDCouplingFieldDouble(ON_CELLS) ; f.setMesh(MEDCouplingIMesh("",3,DataArrayInt([6,8,6]),[0.,0.,0.],DataArrayDouble((1.,1.,1.)))) ; f.setArray(coarse) ; f.setName("tutu") ; f.checkCoherency() + f=MEDCouplingFieldDouble(ON_CELLS) ; f.setMesh(MEDCouplingIMesh("",3,DataArrayInt([13,9,13]),[1.,2.,1.],DataArrayDouble((0.25,0.25,0.25)))) ; f.setArray(fine) ; f.setName("tutu") ; f.checkCoherency() + # 1D + coarse=DataArrayDouble(5) ; coarse.iota(0) #X=5 + fine=DataArrayDouble(3*4) ; fine.iota(0) #X=3 refined by 4 + MEDCouplingIMesh.SpreadCoarseToFine(coarse,[5],fine,[(1,4)],[4]) + self.assertTrue(fine.isEqual(DataArrayDouble([1.,1.,1.,1.,2.,2.,2.,2.,3.,3.,3.,3.]),1e-12)) + pass + + def testSwig2AMR4(self): + """This test focuses on MEDCouplingCartesianAMRMesh.createPatchesFromCriterion method. To test it a field containing 0 everywhere except in the annulus (centered on the center of the mesh) value is 1.""" + im=MEDCouplingIMesh("mesh",2,[51,51],[0.,0.],[0.04,0.04]) + b=im.getBarycenterAndOwner() ; b-=[1.,1.] ; b=b.magnitude() + ids=b.getIdsInRange(0.4,0.7) + f=MEDCouplingFieldDouble(ON_CELLS) ; f.setMesh(im) ; f.setName("toto") ; arr=DataArrayDouble(im.getNumberOfCells()) ; arr[:]=0. ; arr[ids]=1. ; f.setArray(arr) + # f.write("test.vti") + amr=MEDCouplingCartesianAMRMesh(MEDCouplingIMesh("mesh",2,[51,51],[0.,0.],[0.04,0.04])) + arr2=DataArrayByte(im.getNumberOfCells()) ; arr2[:]=0 ; arr2[ids]=1 + bso=BoxSplittingOptions() ; bso.setEfficiencyGoal(0.5); bso.setEfficiencyThreshold(0.8) ; bso.setMaximumNbOfCellsInPatch(3000) ; bso.setMinimumPatchLength(6) ; bso.setMaximumPatchLength(11) + amr.createPatchesFromCriterion(bso,arr2,[2,2]) + m=amr.getImageMesh() ; m=m.buildUnstructured() ; m.changeSpaceDimension(3,1.) + self.assertEqual(12,amr.getNumberOfPatches()) + exp0=[[(9,19),(9,19)],[(9,19),(31,41)],[(31,41),(9,19)],[(8,17),(19,25)],[(8,17),(25,31)],[(19,25),(8,17)],[(25,31),(8,17)],[(19,25),(33,42)],[(25,31),(33,42)],[(31,41),(31,41)],[(33,42),(19,25)],[(33,42),(25,31)]] + for i,bltr in enumerate(exp0): + self.assertEqual(amr[i].getBLTRRange(),bltr) + pass + self.assertAlmostEqual(0.666666666667,amr[3].getMesh().getImageMesh().computeSquareness(),12) + # + self.assertEqual(MEDCouplingStructuredMesh.ChangeReferenceToGlobalOfCompactFrmt([(8,32),(4,17)],[(0,24),(2,12)]),[(8,32),(6,16)]) + self.assertEqual(MEDCouplingStructuredMesh.ChangeReferenceFromGlobalOfCompactFrmt([(8,32),(4,17)],[(8,32),(6,16)]),[(0,24),(2,12)]) + self.assertTrue(amr.getImageMesh().isEqual(im,1e-12)) + m=amr.getImageMesh().asSingleCell().build1SGTUnstructured() + self.assertTrue(m.getNodalConnectivity().isEqual(DataArrayInt([1,0,2,3]))) + self.assertTrue(m.getCoords().isEqualWithoutConsideringStr(DataArrayDouble([(0,0),(2,0),(0,2),(2,2)]),1e-12)) + pass + + def testSwig2AMR5(self): + """ Idem testAMR3, test spread of coarse IMesh instance into a fine one, with a factor, but here ghost is used !""" + # 1D + coarse=DataArrayDouble(5+2) ; coarse.iota(-1) #X=5 with ghostLev=1 + fine=DataArrayDouble(3*4+2) ; fine.iota(1000) #X=3 refined by 4 with ghostLev=1 + MEDCouplingIMesh.SpreadCoarseToFineGhost(coarse,[5],fine,[(1,4)],[4],1) + self.assertTrue(fine.isEqual(DataArrayDouble([0,1,1,1,1,2,2,2,2,3,3,3,3,4]),1e-12)) + coarse.iota(-1000) + MEDCouplingIMesh.CondenseFineToCoarseGhost([5],fine,[(1,4)],[4],coarse,1) + self.assertTrue(coarse.isEqual(DataArrayDouble([-1000.,-999.,4.,8.,12.,-995.,-994.]),1e-12)) + # 2D + coarse=DataArrayDouble((5+2*1)*(7+2*1)) ; coarse.iota(0) #X=5,Y=7 with ghostLev=1 + fine=DataArrayDouble((3*4+2*1)*(2*4+2*1)) ; fine.iota(1000) #X=3,Y=2 refined by 4 + MEDCouplingIMesh.SpreadCoarseToFineGhost(coarse,[5,7],fine,[(1,4),(2,4)],[4,4],1) + self.assertTrue(fine.isEqual(DataArrayDouble([15.,16.,16.,16.,16.,17.,17.,17.,17.,18.,18.,18.,18.,19.,22.,23.,23.,23.,23.,24.,24.,24.,24.,25.,25.,25.,25.,26.,22.,23.,23.,23.,23.,24.,24.,24.,24.,25.,25.,25.,25.,26.,22.,23.,23.,23.,23.,24.,24.,24.,24.,25.,25.,25.,25.,26.,22.,23.,23.,23.,23.,24.,24.,24.,24.,25.,25.,25.,25.,26.,29.,30.,30.,30.,30.,31.,31.,31.,31.,32.,32.,32.,32.,33.,29.,30.,30.,30.,30.,31.,31.,31.,31.,32.,32.,32.,32.,33.,29.,30.,30.,30.,30.,31.,31.,31.,31.,32.,32.,32.,32.,33.,29.,30.,30.,30.,30.,31.,31.,31.,31.,32.,32.,32.,32.,33.,36.,37.,37.,37.,37.,38.,38.,38.,38.,39.,39.,39.,39.,40.]),1e-12)) + f=MEDCouplingFieldDouble(ON_CELLS) ; f.setMesh(MEDCouplingIMesh("",2,DataArrayInt([8,10]),[0.,0.],DataArrayDouble((1.,1.)))) ; f.setArray(coarse) ; f.setName("tutu") ; f.checkCoherency() + coarse.iota(-1000) + fine2=DataArrayDouble.Meld(fine,3*fine) ; coarse2=DataArrayDouble.Meld(coarse,3*coarse) + MEDCouplingIMesh.CondenseFineToCoarseGhost([5,7],fine,[(1,4),(2,4)],[4,4],coarse,1) + MEDCouplingIMesh.CondenseFineToCoarseGhost([5,7],fine2,[(1,4),(2,4)],[4,4],coarse2,1) + f=MEDCouplingFieldDouble(ON_CELLS) ; f.setMesh(MEDCouplingIMesh("",2,DataArrayInt([8,10]),[0.,0.],DataArrayDouble((1.,1.)))) ; f.setArray(coarse) ; f.setName("tutu") ; f.checkCoherency() + coarseExp=DataArrayDouble([-1000.,-999.,-998.,-997.,-996.,-995.,-994.,-993.,-992.,-991.,-990.,-989.,-988.,-987.,-986.,-985.,-984.,-983.,-982.,-981.,-980.,-979.,-978.,368.,384.,400.,-974.,-973.,-972.,-971.,480.,496.,512.,-967.,-966.,-965.,-964.,-963.,-962.,-961.,-960.,-959.,-958.,-957.,-956.,-955.,-954.,-953.,-952.,-951.,-950.,-949.,-948.,-947.,-946.,-945.,-944.,-943.,-942.,-941.,-940.,-939.,-938.]) + self.assertTrue(coarse.isEqual(coarseExp,1e-12)) + self.assertTrue(coarse2[:,0].isEqual(coarseExp,1e-12)) + self.assertTrue(coarse2[:,1].isEqual(3*coarseExp,1e-12)) + pass + + def testSwig2AMR6(self): + """ Idem testSwig2AMR5, except that only 2D is considered here, and fine to fine is considered here. At the end of the test some checks about typing with AMR structs.""" + amr=MEDCouplingCartesianAMRMesh("",2,[6,6],[0,0],[1,1]) + da=DataArrayDouble((5+2)*(5+2)) ; da.iota() ; da+=0.9 + amr.addPatch([(1,4),(2,4)],[4,4]) + amr.addPatch([(0,1),(0,1)],[4,4]) + amr.addPatch([(4,5),(3,4)],[4,4]) + amr.addPatch([(4,5),(1,3)],[4,4]) + amr.addPatch([(0,1),(1,4)],[4,4]) + da0=DataArrayDouble((3*4+2)*(2*4+2)) ; da0.iota() ; da0[:]+=0.2 + da1=DataArrayDouble((1*4+2)*(1*4+2)) ; da1.iota() ; da1[:]+=0.4 + da2=DataArrayDouble((1*4+2)*(1*4+2)) ; da2.iota() ; da2[:]+=0.6 + da3=DataArrayDouble((1*4+2)*(2*4+2)) ; da3.iota() ; da3[:]+=0.7 + da4=DataArrayDouble((1*4+2)*(3*4+2)) ; da4.iota() ; da4[:]+=0.8 + self.assertEqual(5,amr.getNumberOfPatches()) + l=[da0,da1,da2,da3,da4] + lCpy=[elt.deepCpy() for elt in l] + l2=[DataArrayDouble.Meld(elt,3*elt) for elt in l] + amr.fillCellFieldOnPatchGhostAdv(0,da,1,l,False) + amr.fillCellFieldOnPatchGhostAdv(0,DataArrayDouble.Meld(da,3*da),1,l2,False) + amr.fillCellFieldOnPatchOnlyOnGhostZone(0,da,lCpy[0],1) + # + f=MEDCouplingFieldDouble(ON_CELLS) ; f.setMesh(amr.getImageMesh().buildWithGhost(1)) ; f.setArray(da) ; f.setName("all") + f0=MEDCouplingFieldDouble(ON_CELLS) ; f0.setMesh(amr[0].getMesh().getImageMesh().buildWithGhost(1)) ; f0.setArray(da0) ; f0.setName("p0") ; f0.checkCoherency() + f1=MEDCouplingFieldDouble(ON_CELLS) ; f1.setMesh(amr[1].getMesh().getImageMesh().buildWithGhost(1)) ; f1.setArray(da1) ; f1.setName("p1") ; f1.checkCoherency() + f2=MEDCouplingFieldDouble(ON_CELLS) ; f2.setMesh(amr[2].getMesh().getImageMesh().buildWithGhost(1)) ; f2.setArray(da2) ; f2.setName("p2") ; f2.checkCoherency() + f3=MEDCouplingFieldDouble(ON_CELLS) ; f3.setMesh(amr[3].getMesh().getImageMesh().buildWithGhost(1)) ; f3.setArray(da3) ; f3.setName("p3") ; f3.checkCoherency() + f4=MEDCouplingFieldDouble(ON_CELLS) ; f4.setMesh(amr[4].getMesh().getImageMesh().buildWithGhost(1)) ; f4.setArray(da4) ; f4.setName("p4") ; f4.checkCoherency() + # + da0Exp=DataArrayDouble([28.8,16.9,16.9,16.9,16.9,17.9,17.9,17.9,17.9,18.9,18.9,18.9,18.9,25.7,34.8,23.9,23.9,23.9,23.9,24.9,24.9,24.9,24.9,25.9,25.9,25.9,25.9,31.7,40.8,23.9,23.9,23.9,23.9,24.9,24.9,24.9,24.9,25.9,25.9,25.9,25.9,37.7,46.8,23.9,23.9,23.9,23.9,24.9,24.9,24.9,24.9,25.9,25.9,25.9,25.9,43.7,52.8,23.9,23.9,23.9,23.9,24.9,24.9,24.9,24.9,25.9,25.9,25.9,25.9,49.7,58.8,30.9,30.9,30.9,30.9,31.9,31.9,31.9,31.9,32.9,32.9,32.9,32.9,7.6,64.8,30.9,30.9,30.9,30.9,31.9,31.9,31.9,31.9,32.9,32.9,32.9,32.9,13.6,70.8,30.9,30.9,30.9,30.9,31.9,31.9,31.9,31.9,32.9,32.9,32.9,32.9,19.6,76.8,30.9,30.9,30.9,30.9,31.9,31.9,31.9,31.9,32.9,32.9,32.9,32.9,25.6,36.9,37.9,37.9,37.9,37.9,38.9,38.9,38.9,38.9,39.9,39.9,39.9,39.9,40.9]) + da0Exp2=DataArrayDouble([15.9,16.9,16.9,16.9,16.9,17.9,17.9,17.9,17.9,18.9,18.9,18.9,18.9,19.9,22.9,15.2,16.2,17.2,18.2,19.2,20.2,21.2,22.2,23.2,24.2,25.2,26.2,26.9,22.9,29.2,30.2,31.2,32.2,33.2,34.2,35.2,36.2,37.2,38.2,39.2,40.2,26.9,22.9,43.2,44.2,45.2,46.2,47.2,48.2,49.2,50.2,51.2,52.2,53.2,54.2,26.9,22.9,57.2,58.2,59.2,60.2,61.2,62.2,63.2,64.2,65.2,66.2,67.2,68.2,26.9,29.9,71.2,72.2,73.2,74.2,75.2,76.2,77.2,78.2,79.2,80.2,81.2,82.2,33.9,29.9,85.2,86.2,87.2,88.2,89.2,90.2,91.2,92.2,93.2,94.2,95.2,96.2,33.9,29.9,99.2,100.2,101.2,102.2,103.2,104.2,105.2,106.2,107.2,108.2,109.2,110.2,33.9,29.9,113.2,114.2,115.2,116.2,117.2,118.2,119.2,120.2,121.2,122.2,123.2,124.2,33.9,36.9,37.9,37.9,37.9,37.9,38.9,38.9,38.9,38.9,39.9,39.9,39.9,39.9,40.9]) + self.assertTrue(da0.isEqual(da0Exp,1e-12)) + self.assertTrue(l2[0][:,0].isEqual(da0Exp,1e-12)) + self.assertTrue(l2[0][:,1].isEqual(3*da0Exp,1e-12)) + self.assertTrue(lCpy[0].isEqual(da0Exp2,1e-12)) + # + g0=amr.retrieveGridsAt(0) + self.assertEqual(1,len(g0)) + self.assertTrue(isinstance(g0[0],MEDCouplingCartesianAMRPatchGF)) + g1=amr.retrieveGridsAt(1) + self.assertEqual(5,len(g1)) + for i in xrange(5): + self.assertTrue(isinstance(g1[i],MEDCouplingCartesianAMRPatch)) + pass + pass + + def testSwig2AMR7(self): + """Idem testSwig2AMR6 except that we are in 1D""" + amr=MEDCouplingCartesianAMRMesh("",1,[6],[0],[1]) + da=DataArrayDouble(5+2) ; da.iota() ; da+=0.9 + amr.addPatch([(1,4)],[4]) + amr.addPatch([(0,1)],[4]) + da0=DataArrayDouble(3*4+2) ; da0.iota() ; da0[:]+=0.2 + da1=DataArrayDouble(1*4+2) ; da1.iota() ; da1[:]+=0.4 + self.assertEqual(2,amr.getNumberOfPatches()) + l=[da0,da1] + lCpy=[elt.deepCpy() for elt in l] + l2=[DataArrayDouble.Meld(elt,3*elt) for elt in l] + amr.fillCellFieldOnPatchGhostAdv(0,da,1,l,False) + amr.fillCellFieldOnPatchGhostAdv(0,DataArrayDouble.Meld(da,3*da),1,l2,False) + amr.fillCellFieldOnPatchOnlyOnGhostZone(0,da,lCpy[0],1) + # + f=MEDCouplingFieldDouble(ON_CELLS) ; f.setMesh(amr.getImageMesh().buildWithGhost(1)) ; f.setArray(da) ; f.setName("all") + f0=MEDCouplingFieldDouble(ON_CELLS) ; f0.setMesh(amr[0].getMesh().getImageMesh().buildWithGhost(1)) ; f0.setArray(da0) ; f0.setName("p0") ; f0.checkCoherency() + f1=MEDCouplingFieldDouble(ON_CELLS) ; f1.setMesh(amr[1].getMesh().getImageMesh().buildWithGhost(1)) ; f1.setArray(da1) ; f1.setName("p1") ; f1.checkCoherency() + # + da0Exp=DataArrayDouble([4.4,2.9,2.9,2.9,2.9,3.9,3.9,3.9,3.9,4.9,4.9,4.9,4.9,5.9]) + da0Exp2=DataArrayDouble([1.9,1.2,2.2,3.2,4.2,5.2,6.2,7.2,8.2,9.2,10.2,11.2,12.2,5.9]) + self.assertTrue(da0.isEqual(da0Exp,1e-12)) + self.assertTrue(l2[0][:,0].isEqual(da0Exp,1e-12)) + self.assertTrue(l2[0][:,1].isEqual(3*da0Exp,1e-12)) + self.assertTrue(lCpy[0].isEqual(da0Exp2,1e-12)) + pass + + def testSwig2AMR8(self): + """This test checks 'basic' operations for ghost update.""" + ghostSz=1 + amr=MEDCouplingCartesianAMRMesh("",2,[6,7],[0,0],[1,1]) + amr.addPatch([(1,4),(2,4)],[4,4]) + amr.addPatch([(4,5),(3,5)],[4,4]) + amr.addPatch([(0,1),(4,6)],[4,4]) + amr[0].addPatch([(10,12),(5,8)],[2,2]) + amr[1].addPatch([(0,1),(0,5)],[2,2]) + amr[2].addPatch([(3,4),(0,3)],[2,2]) + m=amr.buildMeshFromPatchEnvelop() + self.assertTrue(m.getNodalConnectivity().isEqual(DataArrayInt([1,0,2,3,5,4,6,7,9,8,10,11]))) + self.assertTrue(m.getCoords().isEqualWithoutConsideringStr(DataArrayDouble([1.,2.,4.,2.,1.,4.,4.,4.,4.,3.,5.,3.,4.,5.,5.,5.,0.,4.,1.,4.,0.,6.,1.,6.],12,2),1e-12)) + self.assertEqual(3,amr.getMaxNumberOfLevelsRelativeToThis()) + att=MEDCouplingAMRAttribute(amr,[("Field",["X"])],ghostSz) + att.alloc() + d=att.getFieldOn(amr,"Field") + self.assertEqual(56,d.getNumberOfTuples()) + self.assertEqual(1,d.getNumberOfComponents()) + d.iota() ; d+=0.1 + d0=att.getFieldOn(amr[0].getMesh(),"Field") + self.assertEqual(140,d0.getNumberOfTuples()) + self.assertEqual(1,d0.getNumberOfComponents()) + d0.iota() ; d0+=0.2 + d1=att.getFieldOn(amr[1].getMesh(),"Field") + self.assertEqual(60,d1.getNumberOfTuples()) + self.assertEqual(1,d1.getNumberOfComponents()) + d1.iota() ; d1+=0.3 + d2=att.getFieldOn(amr[2].getMesh(),"Field") + self.assertEqual(60,d2.getNumberOfTuples()) + self.assertEqual(1,d2.getNumberOfComponents()) + d2.iota() ; d2+=0.4 + d00=att.getFieldOn(amr[0][0].getMesh(),"Field") + self.assertEqual(48,d00.getNumberOfTuples()) + self.assertEqual(1,d00.getNumberOfComponents()) + d00.iota() ; d00+=0.5 + d10=att.getFieldOn(amr[1][0].getMesh(),"Field") + self.assertEqual(48,d10.getNumberOfTuples()) + self.assertEqual(1,d10.getNumberOfComponents()) + d10.iota() ; d10+=0.6 + d20=att.getFieldOn(amr[2][0].getMesh(),"Field") + self.assertEqual(32,d20.getNumberOfTuples()) + self.assertEqual(1,d20.getNumberOfComponents()) + d20.iota() ; d20+=0.7 + f=att.buildCellFieldOnRecurseWithoutOverlapWithoutGhost(amr,"Field") + arrExp=DataArrayDouble([8.1,9.1,10.1,11.1,12.1,15.1,16.1,17.1,18.1,19.1,22.1,26.1,29.1,37.1,38.1,39.1,44.1,45.1,46.1,47.1,15.2,16.2,17.2,18.2,19.2,20.2,21.2,22.2,23.2,24.2,25.2,26.2,29.2,30.2,31.2,32.2,33.2,34.2,35.2,36.2,37.2,38.2,39.2,40.2,43.2,44.2,45.2,46.2,47.2,48.2,49.2,50.2,51.2,52.2,53.2,54.2,57.2,58.2,59.2,60.2,61.2,62.2,63.2,64.2,65.2,66.2,67.2,68.2,71.2,72.2,73.2,74.2,75.2,76.2,77.2,78.2,79.2,80.2,81.2,82.2,85.2,86.2,87.2,88.2,89.2,90.2,91.2,92.2,93.2,94.2,99.2,100.2,101.2,102.2,103.2,104.2,105.2,106.2,107.2,108.2,113.2,114.2,115.2,116.2,117.2,118.2,119.2,120.2,121.2,122.2,7.5,8.5,9.5,10.5,13.5,14.5,15.5,16.5,19.5,20.5,21.5,22.5,25.5,26.5,27.5,28.5,31.5,32.5,33.5,34.5,37.5,38.5,39.5,40.5,8.3,9.3,10.3,14.3,15.3,16.3,20.3,21.3,22.3,26.3,27.3,28.3,32.3,33.3,34.3,37.3,38.3,39.3,40.3,43.3,44.3,45.3,46.3,49.3,50.3,51.3,52.3,5.6,6.6,9.6,10.6,13.6,14.6,17.6,18.6,21.6,22.6,25.6,26.6,29.6,30.6,33.6,34.6,37.6,38.6,41.6,42.6,7.4,8.4,9.4,13.4,14.4,15.4,19.4,20.4,21.4,25.4,26.4,27.4,28.4,31.4,32.4,33.4,34.4,37.4,38.4,39.4,40.4,43.4,44.4,45.4,46.4,49.4,50.4,51.4,52.4,5.7,6.7,9.7,10.7,13.7,14.7,17.7,18.7,21.7,22.7,25.7,26.7]) + arrExp.setName("Field") ; arrExp.setInfoOnComponents(["X"]) + self.assertTrue(f.getArray().isEqual(arrExp,1e-12)) + m=MEDCoupling1SGTUMesh(f.getMesh()) + self.assertTrue(m.getNodalConnectivity().isEqual(DataArrayInt([1,0,6,7,2,1,7,8,3,2,8,9,4,3,9,10,5,4,10,11,7,6,12,13,8,7,13,14,9,8,14,15,10,9,15,16,11,10,16,17,13,12,18,19,17,16,20,21,19,18,22,23,24,23,27,28,25,24,28,29,26,25,29,30,28,27,32,33,29,28,33,34,30,29,34,35,31,30,35,36,38,37,50,51,39,38,51,52,40,39,52,53,41,40,53,54,42,41,54,55,43,42,55,56,44,43,56,57,45,44,57,58,46,45,58,59,47,46,59,60,48,47,60,61,49,48,61,62,51,50,63,64,52,51,64,65,53,52,65,66,54,53,66,67,55,54,67,68,56,55,68,69,57,56,69,70,58,57,70,71,59,58,71,72,60,59,72,73,61,60,73,74,62,61,74,75,64,63,76,77,65,64,77,78,66,65,78,79,67,66,79,80,68,67,80,81,69,68,81,82,70,69,82,83,71,70,83,84,72,71,84,85,73,72,85,86,74,73,86,87,75,74,87,88,77,76,89,90,78,77,90,91,79,78,91,92,80,79,92,93,81,80,93,94,82,81,94,95,83,82,95,96,84,83,96,97,85,84,97,98,86,85,98,99,87,86,99,100,88,87,100,101,90,89,102,103,91,90,103,104,92,91,104,105,93,92,105,106,94,93,106,107,95,94,107,108,96,95,108,109,97,96,109,110,98,97,110,111,99,98,111,112,100,99,112,113,101,100,113,114,103,102,115,116,104,103,116,117,105,104,117,118,106,105,118,119,107,106,119,120,108,107,120,121,109,108,121,122,110,109,122,123,111,110,123,124,112,111,124,125,116,115,126,127,117,116,127,128,118,117,128,129,119,118,129,130,120,119,130,131,121,120,131,132,122,121,132,133,123,122,133,134,124,123,134,135,125,124,135,136,127,126,137,138,128,127,138,139,129,128,139,140,130,129,140,141,131,130,141,142,132,131,142,143,133,132,143,144,134,133,144,145,135,134,145,146,136,135,146,147,149,148,153,154,150,149,154,155,151,150,155,156,152,151,156,157,154,153,158,159,155,154,159,160,156,155,160,161,157,156,161,162,159,158,163,164,160,159,164,165,161,160,165,166,162,161,166,167,164,163,168,169,165,164,169,170,166,165,170,171,167,166,171,172,169,168,173,174,170,169,174,175,171,170,175,176,172,171,176,177,174,173,178,179,175,174,179,180,176,175,180,181,177,176,181,182,184,183,187,188,185,184,188,189,186,185,189,190,188,187,191,192,189,188,192,193,190,189,193,194,192,191,195,196,193,192,196,197,194,193,197,198,196,195,199,200,197,196,200,201,198,197,201,202,200,199,204,205,201,200,205,206,202,201,206,207,204,203,208,209,205,204,209,210,206,205,210,211,207,206,211,212,209,208,213,214,210,209,214,215,211,210,215,216,212,211,216,217,214,213,218,219,215,214,219,220,216,215,220,221,217,216,221,222,224,223,226,227,225,224,227,228,227,226,229,230,228,227,230,231,230,229,232,233,231,230,233,234,233,232,235,236,234,233,236,237,236,235,238,239,237,236,239,240,239,238,241,242,240,239,242,243,242,241,244,245,243,242,245,246,245,244,247,248,246,245,248,249,248,247,250,251,249,248,251,252,251,250,253,254,252,251,254,255,257,256,260,261,258,257,261,262,259,258,262,263,261,260,264,265,262,261,265,266,263,262,266,267,265,264,268,269,266,265,269,270,267,266,270,271,269,268,273,274,270,269,274,275,271,270,275,276,272,271,276,277,274,273,278,279,275,274,279,280,276,275,280,281,277,276,281,282,279,278,283,284,280,279,284,285,281,280,285,286,282,281,286,287,284,283,288,289,285,284,289,290,286,285,290,291,287,286,291,292,289,288,293,294,290,289,294,295,291,290,295,296,292,291,296,297,299,298,301,302,300,299,302,303,302,301,304,305,303,302,305,306,305,304,307,308,306,305,308,309,308,307,310,311,309,308,311,312,311,310,313,314,312,311,314,315,314,313,316,317,315,314,317,318]))) + self.assertTrue(m.getCoords().isEqualWithoutConsideringStr(DataArrayDouble([0.,0.,1.,0.,2.,0.,3.,0.,4.,0.,5.,0.,0.,1.,1.,1.,2.,1.,3.,1.,4.,1.,5.,1.,0.,2.,1.,2.,2.,2.,3.,2.,4.,2.,5.,2.,0.,3.,1.,3.,4.,3.,5.,3.,0.,4.,1.,4.,2.,4.,3.,4.,4.,4.,1.,5.,2.,5.,3.,5.,4.,5.,5.,5.,1.,6.,2.,6.,3.,6.,4.,6.,5.,6.,1.,2.,1.25,2.,1.5,2.,1.75,2.,2.,2.,2.25,2.,2.5,2.,2.75,2.,3.,2.,3.25,2.,3.5,2.,3.75,2.,4.,2.,1.,2.25,1.25,2.25,1.5,2.25,1.75,2.25,2.,2.25,2.25,2.25,2.5,2.25,2.75,2.25,3.,2.25,3.25,2.25,3.5,2.25,3.75,2.25,4.,2.25,1.,2.5,1.25,2.5,1.5,2.5,1.75,2.5,2.,2.5,2.25,2.5,2.5,2.5,2.75,2.5,3.,2.5,3.25,2.5,3.5,2.5,3.75,2.5,4.,2.5,1.,2.75,1.25,2.75,1.5,2.75,1.75,2.75,2.,2.75,2.25,2.75,2.5,2.75,2.75,2.75,3.,2.75,3.25,2.75,3.5,2.75,3.75,2.75,4.,2.75,1.,3.,1.25,3.,1.5,3.,1.75,3.,2.,3.,2.25,3.,2.5,3.,2.75,3.,3.,3.,3.25,3.,3.5,3.,3.75,3.,4.,3.,1.,3.25,1.25,3.25,1.5,3.25,1.75,3.25,2.,3.25,2.25,3.25,2.5,3.25,2.75,3.25,3.,3.25,3.25,3.25,3.5,3.25,3.75,3.25,4.,3.25,1.,3.5,1.25,3.5,1.5,3.5,1.75,3.5,2.,3.5,2.25,3.5,2.5,3.5,2.75,3.5,3.,3.5,3.25,3.5,3.5,3.5,1.,3.75,1.25,3.75,1.5,3.75,1.75,3.75,2.,3.75,2.25,3.75,2.5,3.75,2.75,3.75,3.,3.75,3.25,3.75,3.5,3.75,1.,4.,1.25,4.,1.5,4.,1.75,4.,2.,4.,2.25,4.,2.5,4.,2.75,4.,3.,4.,3.25,4.,3.5,4.,3.5,3.25,3.625,3.25,3.75,3.25,3.875,3.25,4.,3.25,3.5,3.375,3.625,3.375,3.75,3.375,3.875,3.375,4.,3.375,3.5,3.5,3.625,3.5,3.75,3.5,3.875,3.5,4.,3.5,3.5,3.625,3.625,3.625,3.75,3.625,3.875,3.625,4.,3.625,3.5,3.75,3.625,3.75,3.75,3.75,3.875,3.75,4.,3.75,3.5,3.875,3.625,3.875,3.75,3.875,3.875,3.875,4.,3.875,3.5,4.,3.625,4.,3.75,4.,3.875,4.,4.,4.,4.25,3.,4.5,3.,4.75,3.,5.,3.,4.25,3.25,4.5,3.25,4.75,3.25,5.,3.25,4.25,3.5,4.5,3.5,4.75,3.5,5.,3.5,4.25,3.75,4.5,3.75,4.75,3.75,5.,3.75,4.25,4.,4.5,4.,4.75,4.,5.,4.,4.,4.25,4.25,4.25,4.5,4.25,4.75,4.25,5.,4.25,4.,4.5,4.25,4.5,4.5,4.5,4.75,4.5,5.,4.5,4.,4.75,4.25,4.75,4.5,4.75,4.75,4.75,5.,4.75,4.,5.,4.25,5.,4.5,5.,4.75,5.,5.,5.,4.,3.,4.125,3.,4.25,3.,4.,3.125,4.125,3.125,4.25,3.125,4.,3.25,4.125,3.25,4.25,3.25,4.,3.375,4.125,3.375,4.25,3.375,4.,3.5,4.125,3.5,4.25,3.5,4.,3.625,4.125,3.625,4.25,3.625,4.,3.75,4.125,3.75,4.25,3.75,4.,3.875,4.125,3.875,4.25,3.875,4.,4.,4.125,4.,4.25,4.,4.,4.125,4.125,4.125,4.25,4.125,4.,4.25,4.125,4.25,4.25,4.25,0.,4.,0.25,4.,0.5,4.,0.75,4.,0.,4.25,0.25,4.25,0.5,4.25,0.75,4.25,0.,4.5,0.25,4.5,0.5,4.5,0.75,4.5,0.,4.75,0.25,4.75,0.5,4.75,0.75,4.75,1.,4.75,0.,5.,0.25,5.,0.5,5.,0.75,5.,1.,5.,0.,5.25,0.25,5.25,0.5,5.25,0.75,5.25,1.,5.25,0.,5.5,0.25,5.5,0.5,5.5,0.75,5.5,1.,5.5,0.,5.75,0.25,5.75,0.5,5.75,0.75,5.75,1.,5.75,0.,6.,0.25,6.,0.5,6.,0.75,6.,1.,6.,0.75,4.,0.875,4.,1.,4.,0.75,4.125,0.875,4.125,1.,4.125,0.75,4.25,0.875,4.25,1.,4.25,0.75,4.375,0.875,4.375,1.,4.375,0.75,4.5,0.875,4.5,1.,4.5,0.75,4.625,0.875,4.625,1.,4.625,0.75,4.75,0.875,4.75,1.,4.75],319,2),1e-12)) + # the test is here ! To be called after iteration with no remesh + att.synchronizeAllGhostZones() + f=att.buildCellFieldOnWithGhost(amr,"Field") ; f.checkCoherency() + ftmp=att.buildCellFieldOnWithoutGhost(amr,"Field") ; ftmp.checkCoherency() ; self.assertTrue(ftmp.getArray().isEqualWithoutConsideringStr(DataArrayDouble([8.1,9.1,10.1,11.1,12.1,15.1,16.1,17.1,18.1,19.1,22.1,23.1,24.1,25.1,26.1,29.1,30.1,31.1,32.1,33.1,36.1,37.1,38.1,39.1,40.1,43.1,44.1,45.1,46.1,47.1]),1e-12)) + f0=att.buildCellFieldOnWithGhost(amr[0].getMesh(),"Field") + f1=att.buildCellFieldOnWithGhost(amr[1].getMesh(),"Field") + f2=att.buildCellFieldOnWithGhost(amr[2].getMesh(),"Field") + f00=att.buildCellFieldOnWithGhost(amr[0][0].getMesh(),"Field") + f10=att.buildCellFieldOnWithGhost(amr[1][0].getMesh(),"Field") + f20=att.buildCellFieldOnWithGhost(amr[2][0].getMesh(),"Field") + self.assertTrue(f.getArray().isEqualWithoutConsideringStr(DataArrayDouble([0.1,1.1,2.1,3.1,4.1,5.1,6.1,7.1,8.1,9.1,10.1,11.1,12.1,13.1,14.1,15.1,16.1,17.1,18.1,19.1,20.1,21.1,22.1,23.1,24.1,25.1,26.1,27.1,28.1,29.1,30.1,31.1,32.1,33.1,34.1,35.1,36.1,37.1,38.1,39.1,40.1,41.1,42.1,43.1,44.1,45.1,46.1,47.1,48.1,49.1,50.1,51.1,52.1,53.1,54.1,55.1]),1e-12)) + self.assertTrue(f0.getArray().isEqualWithoutConsideringStr(DataArrayDouble([15.1,16.1,16.1,16.1,16.1,17.1,17.1,17.1,17.1,18.1,18.1,18.1,18.1,19.1,22.1,15.2,16.2,17.2,18.2,19.2,20.2,21.2,22.2,23.2,24.2,25.2,26.2,26.1,22.1,29.2,30.2,31.2,32.2,33.2,34.2,35.2,36.2,37.2,38.2,39.2,40.2,26.1,22.1,43.2,44.2,45.2,46.2,47.2,48.2,49.2,50.2,51.2,52.2,53.2,54.2,26.1,22.1,57.2,58.2,59.2,60.2,61.2,62.2,63.2,64.2,65.2,66.2,67.2,68.2,26.1,29.1,71.2,72.2,73.2,74.2,75.2,76.2,77.2,78.2,79.2,80.2,81.2,82.2,7.3,29.1,85.2,86.2,87.2,88.2,89.2,90.2,91.2,92.2,93.2,94.2,95.2,96.2,13.3,29.1,99.2,100.2,101.2,102.2,103.2,104.2,105.2,106.2,107.2,108.2,109.2,110.2,19.3,29.1,113.2,114.2,115.2,116.2,117.2,118.2,119.2,120.2,121.2,122.2,123.2,124.2,25.3,10.4,37.1,37.1,37.1,37.1,38.1,38.1,38.1,38.1,39.1,39.1,39.1,39.1,31.3]),1e-12)) + self.assertTrue(f1.getArray().isEqualWithoutConsideringStr(DataArrayDouble([68.2,26.1,26.1,26.1,26.1,27.1,82.2,7.3,8.3,9.3,10.3,34.1,96.2,13.3,14.3,15.3,16.3,34.1,110.2,19.3,20.3,21.3,22.3,34.1,124.2,25.3,26.3,27.3,28.3,34.1,39.1,31.3,32.3,33.3,34.3,41.1,39.1,37.3,38.3,39.3,40.3,41.1,39.1,43.3,44.3,45.3,46.3,41.1,39.1,49.3,50.3,51.3,52.3,41.1,46.1,47.1,47.1,47.1,47.1,48.1]),1e-12)) + self.assertTrue(f2.getArray().isEqualWithoutConsideringStr(DataArrayDouble([28.1,29.1,29.1,29.1,29.1,113.2,35.1,7.4,8.4,9.4,10.4,37.1,35.1,13.4,14.4,15.4,16.4,37.1,35.1,19.4,20.4,21.4,22.4,37.1,35.1,25.4,26.4,27.4,28.4,37.1,42.1,31.4,32.4,33.4,34.4,44.1,42.1,37.4,38.4,39.4,40.4,44.1,42.1,43.4,44.4,45.4,46.4,44.1,42.1,49.4,50.4,51.4,52.4,44.1,49.1,50.1,50.1,50.1,50.1,51.1]),1e-12)) + self.assertTrue(f00.getArray().isEqualWithoutConsideringStr(DataArrayDouble([80.2,81.2,81.2,82.2,82.2,9.6,94.2,7.5,8.5,9.5,10.5,13.6,94.2,13.5,14.5,15.5,16.5,17.6,108.2,19.5,20.5,21.5,22.5,21.6,108.2,25.5,26.5,27.5,28.5,25.6,122.2,31.5,32.5,33.5,34.5,29.6,122.2,37.5,38.5,39.5,40.5,33.6,39.1,39.1,39.1,39.1,39.1,37.6]),1e-12)) + self.assertTrue(f10.getArray().isEqualWithoutConsideringStr(DataArrayDouble([68.2,26.1,26.1,26.1,82.2,5.6,6.6,8.3,82.2,9.6,10.6,8.3,10.5,13.6,14.6,14.3,16.5,17.6,18.6,14.3,22.5,21.6,22.6,20.3,28.5,25.6,26.6,20.3,34.5,29.6,30.6,26.3,40.5,33.6,34.6,26.3,39.1,37.6,38.6,32.3,39.1,41.6,42.6,32.3,39.1,37.3,37.3,38.3]),1e-12)) + self.assertTrue(f20.getArray().isEqualWithoutConsideringStr(DataArrayDouble([29.1,29.1,29.1,113.2,9.4,5.7,6.7,37.1,9.4,9.7,10.7,37.1,15.4,13.7,14.7,37.1,15.4,17.7,18.7,37.1,21.4,21.7,22.7,37.1,21.4,25.7,26.7,37.1,27.4,28.4,28.4,37.1]),1e-12)) + pass + + def testSwig2AMR9(self): + """ Equivalent to testSwig2AMR8 except that here the ghost level is 2 !""" + ghostSz=2 + amr=MEDCouplingCartesianAMRMesh("",2,[6,7],[0,0],[1,1]) + amr.addPatch([(1,4),(2,4)],[4,4]) + amr.addPatch([(4,5),(3,5)],[4,4]) + amr.addPatch([(0,1),(4,6)],[4,4]) + amr[0].addPatch([(10,12),(5,8)],[2,2]) + amr[1].addPatch([(0,1),(0,5)],[2,2]) + amr[2].addPatch([(3,4),(0,3)],[2,2]) + self.assertEqual(3,amr.getMaxNumberOfLevelsRelativeToThis()) + att=MEDCouplingAMRAttribute(amr,[("Field",["X"])],ghostSz) + att.alloc() + d=att.getFieldOn(amr,"Field") + self.assertEqual(90,d.getNumberOfTuples()) + self.assertEqual(1,d.getNumberOfComponents()) + d.iota() ; d+=0.1 + d0=att.getFieldOn(amr[0].getMesh(),"Field") + self.assertEqual(192,d0.getNumberOfTuples()) + self.assertEqual(1,d0.getNumberOfComponents()) + d0.iota() ; d0+=0.2 + d1=att.getFieldOn(amr[1].getMesh(),"Field") + self.assertEqual(96,d1.getNumberOfTuples()) + self.assertEqual(1,d1.getNumberOfComponents()) + d1.iota() ; d1+=0.3 + d2=att.getFieldOn(amr[2].getMesh(),"Field") + self.assertEqual(96,d2.getNumberOfTuples()) + self.assertEqual(1,d2.getNumberOfComponents()) + d2.iota() ; d2+=0.4 + d00=att.getFieldOn(amr[0][0].getMesh(),"Field") + self.assertEqual(80,d00.getNumberOfTuples()) + self.assertEqual(1,d00.getNumberOfComponents()) + d00.iota() ; d00+=0.5 + d10=att.getFieldOn(amr[1][0].getMesh(),"Field") + self.assertEqual(84,d10.getNumberOfTuples()) + self.assertEqual(1,d10.getNumberOfComponents()) + d10.iota() ; d10+=0.6 + d20=att.getFieldOn(amr[2][0].getMesh(),"Field") + self.assertEqual(60,d20.getNumberOfTuples()) + self.assertEqual(1,d20.getNumberOfComponents()) + d20.iota() ; d20+=0.7 + # the test is here ! To be called after iteration with no remesh + att.synchronizeAllGhostZones() + f=att.buildCellFieldOnWithGhost(amr,"Field") + f0=att.buildCellFieldOnWithGhost(amr[0].getMesh(),"Field") + f1=att.buildCellFieldOnWithGhost(amr[1].getMesh(),"Field") + f2=att.buildCellFieldOnWithGhost(amr[2].getMesh(),"Field") + f00=att.buildCellFieldOnWithGhost(amr[0][0].getMesh(),"Field") + f10=att.buildCellFieldOnWithGhost(amr[1][0].getMesh(),"Field") + f20=att.buildCellFieldOnWithGhost(amr[2][0].getMesh(),"Field") + self.assertTrue(f0.getArray().isEqualWithoutConsideringStr(DataArrayDouble([29.1,29.1,30.1,30.1,30.1,30.1,31.1,31.1,31.1,31.1,32.1,32.1,32.1,32.1,33.1,33.1,29.1,29.1,30.1,30.1,30.1,30.1,31.1,31.1,31.1,31.1,32.1,32.1,32.1,32.1,33.1,33.1,38.1,38.1,34.2,35.2,36.2,37.2,38.2,39.2,40.2,41.2,42.2,43.2,44.2,45.2,42.1,42.1,38.1,38.1,50.2,51.2,52.2,53.2,54.2,55.2,56.2,57.2,58.2,59.2,60.2,61.2,42.1,42.1,38.1,38.1,66.2,67.2,68.2,69.2,70.2,71.2,72.2,73.2,74.2,75.2,76.2,77.2,42.1,42.1,38.1,38.1,82.2,83.2,84.2,85.2,86.2,87.2,88.2,89.2,90.2,91.2,92.2,93.2,42.1,42.1,47.1,47.1,98.2,99.2,100.2,101.2,102.2,103.2,104.2,105.2,106.2,107.2,108.2,109.2,18.3,19.3,47.1,47.1,114.2,115.2,116.2,117.2,118.2,119.2,120.2,121.2,122.2,123.2,124.2,125.2,26.3,27.3,47.1,47.1,130.2,131.2,132.2,133.2,134.2,135.2,136.2,137.2,138.2,139.2,140.2,141.2,34.3,35.3,47.1,47.1,146.2,147.2,148.2,149.2,150.2,151.2,152.2,153.2,154.2,155.2,156.2,157.2,42.3,43.3,20.4,21.4,57.1,57.1,57.1,57.1,58.1,58.1,58.1,58.1,59.1,59.1,59.1,59.1,50.3,51.3,28.4,29.4,57.1,57.1,57.1,57.1,58.1,58.1,58.1,58.1,59.1,59.1,59.1,59.1,58.3,59.3]),1e-12)) + self.assertTrue(f1.getArray().isEqualWithoutConsideringStr(DataArrayDouble([76.2,77.2,42.1,42.1,42.1,42.1,43.1,43.1,92.2,93.2,42.1,42.1,42.1,42.1,43.1,43.1,108.2,109.2,18.3,19.3,20.3,21.3,52.1,52.1,124.2,125.2,26.3,27.3,28.3,29.3,52.1,52.1,140.2,141.2,34.3,35.3,36.3,37.3,52.1,52.1,156.2,157.2,42.3,43.3,44.3,45.3,52.1,52.1,59.1,59.1,50.3,51.3,52.3,53.3,61.1,61.1,59.1,59.1,58.3,59.3,60.3,61.3,61.1,61.1,59.1,59.1,66.3,67.3,68.3,69.3,61.1,61.1,59.1,59.1,74.3,75.3,76.3,77.3,61.1,61.1,68.1,68.1,69.1,69.1,69.1,69.1,70.1,70.1,68.1,68.1,69.1,69.1,69.1,69.1,70.1,70.1]),1e-12)) + self.assertTrue(f2.getArray().isEqualWithoutConsideringStr(DataArrayDouble([46.1,46.1,47.1,47.1,47.1,47.1,130.2,131.2,46.1,46.1,47.1,47.1,47.1,47.1,146.2,147.2,55.1,55.1,18.4,19.4,20.4,21.4,57.1,57.1,55.1,55.1,26.4,27.4,28.4,29.4,57.1,57.1,55.1,55.1,34.4,35.4,36.4,37.4,57.1,57.1,55.1,55.1,42.4,43.4,44.4,45.4,57.1,57.1,64.1,64.1,50.4,51.4,52.4,53.4,66.1,66.1,64.1,64.1,58.4,59.4,60.4,61.4,66.1,66.1,64.1,64.1,66.4,67.4,68.4,69.4,66.1,66.1,64.1,64.1,74.4,75.4,76.4,77.4,66.1,66.1,73.1,73.1,74.1,74.1,74.1,74.1,75.1,75.1,73.1,73.1,74.1,74.1,74.1,74.1,75.1,75.1]),1e-12)) + self.assertTrue(f00.getArray().isEqualWithoutConsideringStr(DataArrayDouble([107.2,107.2,108.2,108.2,109.2,109.2,14.6,15.6,107.2,107.2,108.2,108.2,109.2,109.2,20.6,21.6,123.2,123.2,18.5,19.5,20.5,21.5,26.6,27.6,123.2,123.2,26.5,27.5,28.5,29.5,32.6,33.6,139.2,139.2,34.5,35.5,36.5,37.5,38.6,39.6,139.2,139.2,42.5,43.5,44.5,45.5,44.6,45.6,155.2,155.2,50.5,51.5,52.5,53.5,50.6,51.6,155.2,155.2,58.5,59.5,60.5,61.5,56.6,57.6,59.1,59.1,59.1,59.1,59.1,59.1,62.6,63.6,59.1,59.1,59.1,59.1,59.1,59.1,68.6,69.6]),1e-12)) + self.assertTrue(f10.getArray().isEqualWithoutConsideringStr(DataArrayDouble([93.2,93.2,42.1,42.1,42.1,42.1,93.2,93.2,42.1,42.1,42.1,42.1,109.2,109.2,14.6,15.6,19.3,19.3,109.2,109.2,20.6,21.6,19.3,19.3,20.5,21.5,26.6,27.6,27.3,27.3,28.5,29.5,32.6,33.6,27.3,27.3,36.5,37.5,38.6,39.6,35.3,35.3,44.5,45.5,44.6,45.6,35.3,35.3,52.5,53.5,50.6,51.6,43.3,43.3,60.5,61.5,56.6,57.6,43.3,43.3,59.1,59.1,62.6,63.6,51.3,51.3,59.1,59.1,68.6,69.6,51.3,51.3,59.1,59.1,58.3,58.3,59.3,59.3,59.1,59.1,58.3,58.3,59.3,59.3]),1e-12)) + self.assertTrue(f20.getArray().isEqualWithoutConsideringStr(DataArrayDouble([47.1,47.1,47.1,47.1,146.2,146.2,47.1,47.1,47.1,47.1,146.2,146.2,20.4,20.4,14.7,15.7,57.1,57.1,20.4,20.4,20.7,21.7,57.1,57.1,28.4,28.4,26.7,27.7,57.1,57.1,28.4,28.4,32.7,33.7,57.1,57.1,36.4,36.4,38.7,39.7,57.1,57.1,36.4,36.4,44.7,45.7,57.1,57.1,44.4,44.4,45.4,45.4,57.1,57.1,44.4,44.4,45.4,45.4,57.1,57.1]),1e-12)) + self.assertTrue(MEDCouplingStructuredMesh.ComputeCornersGhost([3],1).isEqual(DataArrayInt([0,4]))) + self.assertTrue(MEDCouplingStructuredMesh.ComputeCornersGhost([3],2).isEqual(DataArrayInt([0,1,5,6]))) + self.assertTrue(MEDCouplingStructuredMesh.ComputeCornersGhost([5,6],1).isEqual(DataArrayInt([0,6,49,55]))) + self.assertTrue(MEDCouplingStructuredMesh.ComputeCornersGhost([5,6],2).isEqual(DataArrayInt([0,8,10,16,73,79,81,89]))) + self.assertTrue(MEDCouplingStructuredMesh.ComputeCornersGhost([5,6,3],1).isEqual(DataArrayInt([0,6,49,55,224,230,273,279]))) + self.assertTrue(MEDCouplingStructuredMesh.ComputeCornersGhost([5,6,3],2).isEqual(DataArrayInt([0,8,81,89,100,106,163,169,460,466,523,529,540,548,621,629]))) + pass + + def testSwig2AMR10(self): + """ This test, focuses on basic operations of coarse to fine and fine to coarse and ghost zone update with a ghost size set to 2 and dimension equal to 2.""" + szGhost=2 + amr=MEDCouplingCartesianAMRMesh("",2,[11,11],[0,0],[0.1,0.1]) + amr.addPatch([(3,8),(0,3)],[2,2]) + amr[0].addPatch([(0,10),(3,6)],[3,3]) + amr[0].addPatch([(2,6),(0,3)],[3,3]) + amr[0].addPatch([(6,10),(2,3)],[3,3]) + amr.addPatch([(3,8),(3,6)],[2,2]) + amr[1].addPatch([(0,4),(0,6)],[3,3]) + amr[1].addPatch([(7,10),(0,4)],[3,3]) + amr[1].addPatch([(4,7),(0,3)],[3,3]) + amr[1].addPatch([(4,7),(3,6)],[3,3]) + amr.addPatch([(0,3),(6,10)],[2,2]) + self.assertEqual(([(30,39),(27,36)],[6,6]),amr[1][3].getMesh().positionRelativeToGodFather()) + self.assertEqual(([(6,16),(6,12)],[2,2]),amr[1].getMesh().positionRelativeToGodFather()) + self.assertTrue(not MEDCouplingStructuredMesh.AreRangesIntersect([(30,39),(27,36)],[(6,16),(6,12)])) + self.assertTrue(MEDCouplingStructuredMesh.AreRangesIntersect([(30,39),(27,36)],[(28,32),(35,37)])) + da=DataArrayDouble([0.,1.,2.,3.,4.,5.,6.,7.,8.,9.,10.,11.]) + MEDCouplingStructuredMesh.AssignPartOfFieldOfDoubleUsing([3,4],da,[(1,3),(2,3)],DataArrayDouble([7.7,8.8])) + self.assertTrue(da.isEqual(DataArrayDouble([0.,1.,2.,3.,4.,5.,6.,7.7,8.8,9.,10.,11.]),1e-12)) + att=MEDCouplingAMRAttribute(amr,[("YY",1)],szGhost) + att.spillNatures([ConservativeVolumic]) + att.alloc() + yy=att.getFieldOn(amr,"YY") ; yy.iota(0.01) + yy=att.getFieldOn(amr[0].getMesh(),"YY") ; yy.iota(0.02) + yy=att.getFieldOn(amr[1].getMesh(),"YY") ; yy.iota(0.03) + yy=att.getFieldOn(amr[0][0].getMesh(),"YY") ; yy.iota(0.04) + yy=att.getFieldOn(amr[0][1].getMesh(),"YY") ; yy.iota(0.05) + yy=att.getFieldOn(amr[0][2].getMesh(),"YY") ; yy.iota(0.06) + yy=att.getFieldOn(amr[1][0].getMesh(),"YY") ; yy.iota(0.07) + yy=att.getFieldOn(amr[1][1].getMesh(),"YY") ; yy.iota(0.08) + yy=att.getFieldOn(amr[1][2].getMesh(),"YY") ; yy.iota(0.09) + yy=att.getFieldOn(amr[1][3].getMesh(),"YY") ; yy.iota(0.10) + yy=att.getFieldOn(amr[2].getMesh(),"YY") ; yy.iota(0.11) + att2=att.deepCpy() ; att3=att2.deepCpy() ; att4=att3.deepCpy() ; att5=att4.deepCpy() ; att6=att5.deepCpy() + ### + att.synchronizeFineToCoarseBetween(2,1) + ### + for pos in [(),(0,0),(0,1),(0,2),(1,0),(1,1),(1,2),(1,3)]: + self.assertTrue(att.getFieldOn(att.getMyGodFather().getMeshAtPosition(pos),"YY").isEqual(att2.getFieldOn(att2.getMyGodFather().getMeshAtPosition(pos),"YY"),1e-12)) + pass + for pos in [(0,),(1,)]: + self.assertTrue(not att.getFieldOn(att.getMyGodFather().getMeshAtPosition(pos),"YY").isEqual(att2.getFieldOn(att2.getMyGodFather().getMeshAtPosition(pos),"YY"),1e-12)) + pass + self.assertTrue(att.getFieldOn(amr[0].getMesh(),"YY").isEqualWithoutConsideringStr(DataArrayDouble([0.02,1.02,2.02,3.02,4.02,5.02,6.02,7.02,8.02,9.02,10.02,11.02,12.02,13.02,14.02,15.02,16.02,17.02,18.02,19.02,20.02,21.02,22.02,23.02,24.02,25.02,26.02,27.02,28.02,29.02,30.02,31.02,51.05,54.05,57.05,60.05,36.02,37.02,38.02,39.02,40.02,41.02,42.02,43.02,44.02,45.02,99.05,102.05,105.05,108.05,50.02,51.02,52.02,53.02,54.02,55.02,56.02,57.02,58.02,59.02,147.05,150.05,153.05,156.05,51.06,54.06,57.06,60.06,68.02,69.02,70.02,71.02,105.04,108.04,111.04,114.04,117.04,120.04,123.04,126.04,129.04,132.04,82.02,83.02,84.02,85.02,207.04,210.04,213.04,216.04,219.04,222.04,225.04,228.04,231.04,234.04,96.02,97.02,98.02,99.02,309.04,312.04,315.04,318.04,321.04,324.04,327.04,330.04,333.04,336.04,110.02,111.02,112.02,113.02,114.02,115.02,116.02,117.02,118.02,119.02,120.02,121.02,122.02,123.02,124.02,125.02,126.02,127.02,128.02,129.02,130.02,131.02,132.02,133.02,134.02,135.02,136.02,137.02,138.02,139.02]),1e-12)) + self.assertTrue(att.getFieldOn(amr[1].getMesh(),"YY").isEqualWithoutConsideringStr(DataArrayDouble([0.03,1.03,2.03,3.03,4.03,5.03,6.03,7.03,8.03,9.03,10.03,11.03,12.03,13.03,14.03,15.03,16.03,17.03,18.03,19.03,20.03,21.03,22.03,23.03,24.03,25.03,26.03,27.03,28.03,29.03,51.07,54.07,57.07,60.07,42.09,45.09,48.09,42.08,45.08,48.08,40.03,41.03,42.03,43.03,99.07,102.07,105.07,108.07,81.09,84.09,87.09,81.08,84.08,87.08,54.03,55.03,56.03,57.03,147.07,150.07,153.07,156.07,120.09,123.09,126.09,120.08,123.08,126.08,68.03,69.03,70.03,71.03,195.07,198.07,201.07,204.07,42.1,45.1,48.1,159.08,162.08,165.08,82.03,83.03,84.03,85.03,243.07,246.07,249.07,252.07,81.1,84.1,87.1,93.03,94.03,95.03,96.03,97.03,98.03,99.03,291.07,294.07,297.07,300.07,120.1,123.1,126.1,107.03,108.03,109.03,110.03,111.03,112.03,113.03,114.03,115.03,116.03,117.03,118.03,119.03,120.03,121.03,122.03,123.03,124.03,125.03,126.03,127.03,128.03,129.03,130.03,131.03,132.03,133.03,134.03,135.03,136.03,137.03,138.03,139.03]),1e-12)) + del att + #### + att2.synchronizeAllGhostZonesOfDirectChidrenOf(att2.getMyGodFather()) + ### Only the 3 (0) (1) and (2) are modified (0,0), (0,1), (0,2), (1,0), (1,1), (1,2), (1,3) are not modified. + exp2=DataArrayDouble([0.11,1.11,2.11,3.11,4.11,5.11,6.11,7.11,86.03,87.03,10.11,11.11,12.11,13.11,14.11,15.11,16.11,17.11,100.03,101.03,20.11,21.11,22.11,23.11,24.11,25.11,26.11,27.11,28.11,29.11,30.11,31.11,32.11,33.11,34.11,35.11,36.11,37.11,38.11,39.11,40.11,41.11,42.11,43.11,44.11,45.11,46.11,47.11,48.11,49.11,50.11,51.11,52.11,53.11,54.11,55.11,56.11,57.11,58.11,59.11,60.11,61.11,62.11,63.11,64.11,65.11,66.11,67.11,68.11,69.11,70.11,71.11,72.11,73.11,74.11,75.11,76.11,77.11,78.11,79.11,80.11,81.11,82.11,83.11,84.11,85.11,86.11,87.11,88.11,89.11,90.11,91.11,92.11,93.11,94.11,95.11,96.11,97.11,98.11,99.11,100.11,101.11,102.11,103.11,104.11,105.11,106.11,107.11,108.11,109.11,110.11,111.11,112.11,113.11,114.11,115.11,116.11,117.11,118.11,119.11]) + self.assertTrue(att2.getFieldOn(att2.getMyGodFather().getMeshAtPosition((2,)),"YY").isEqualWithoutConsideringStr(exp2,1e-12)) + exp3=DataArrayDouble([0.03,1.03,86.02,87.02,88.02,89.02,90.02,91.02,92.02,93.02,94.02,95.02,12.03,13.03,14.03,15.03,100.02,101.02,102.02,103.02,104.02,105.02,106.02,107.02,108.02,109.02,26.03,27.03,28.03,29.03,30.03,31.03,32.03,33.03,34.03,35.03,36.03,37.03,38.03,39.03,40.03,41.03,42.03,43.03,44.03,45.03,46.03,47.03,48.03,49.03,50.03,51.03,52.03,53.03,54.03,55.03,56.03,57.03,58.03,59.03,60.03,61.03,62.03,63.03,64.03,65.03,66.03,67.03,68.03,69.03,70.03,71.03,72.03,73.03,74.03,75.03,76.03,77.03,78.03,79.03,80.03,81.03,82.03,83.03,84.03,85.03,86.03,87.03,88.03,89.03,90.03,91.03,92.03,93.03,94.03,95.03,96.03,97.03,98.03,99.03,100.03,101.03,102.03,103.03,104.03,105.03,106.03,107.03,108.03,109.03,110.03,111.03,26.11,27.11,114.03,115.03,116.03,117.03,118.03,119.03,120.03,121.03,122.03,123.03,124.03,125.03,36.11,37.11,128.03,129.03,130.03,131.03,132.03,133.03,134.03,135.03,136.03,137.03,138.03,139.03]) + self.assertTrue(att2.getFieldOn(att2.getMyGodFather().getMeshAtPosition((1,)),"YY").isEqualWithoutConsideringStr(exp3,1e-12)) + exp4=DataArrayDouble([0.02,1.02,2.02,3.02,4.02,5.02,6.02,7.02,8.02,9.02,10.02,11.02,12.02,13.02,14.02,15.02,16.02,17.02,18.02,19.02,20.02,21.02,22.02,23.02,24.02,25.02,26.02,27.02,28.02,29.02,30.02,31.02,32.02,33.02,34.02,35.02,36.02,37.02,38.02,39.02,40.02,41.02,42.02,43.02,44.02,45.02,46.02,47.02,48.02,49.02,50.02,51.02,52.02,53.02,54.02,55.02,56.02,57.02,58.02,59.02,60.02,61.02,62.02,63.02,64.02,65.02,66.02,67.02,68.02,69.02,70.02,71.02,72.02,73.02,74.02,75.02,76.02,77.02,78.02,79.02,80.02,81.02,82.02,83.02,84.02,85.02,86.02,87.02,88.02,89.02,90.02,91.02,92.02,93.02,94.02,95.02,96.02,97.02,98.02,99.02,100.02,101.02,102.02,103.02,104.02,105.02,106.02,107.02,108.02,109.02,110.02,111.02,112.02,113.02,30.03,31.03,32.03,33.03,34.03,35.03,36.03,37.03,38.03,39.03,124.02,125.02,126.02,127.02,44.03,45.03,46.03,47.03,48.03,49.03,50.03,51.03,52.03,53.03,138.02,139.02]) + self.assertTrue(att2.getFieldOn(att2.getMyGodFather().getMeshAtPosition((0,)),"YY").isEqualWithoutConsideringStr(exp4,1e-12)) + for pos,iot in [((),0.01),((0,0),0.04),((0,1),0.05),((0,2),0.06),((1,0),0.07),((1,1),0.08),((1,2),0.09),((1,3),0.10)]: + vals=att2.getFieldOn(att2.getMyGodFather().getMeshAtPosition(pos),"YY") + l=vals.getNumberOfTuples() + exps=DataArrayDouble(l) ; exps.iota(iot) + self.assertTrue(vals.isEqualWithoutConsideringStr(exps,1e-12)) + pass + del att2 + ### + att3.synchronizeCoarseToFineBetween(1,2) + ### + for pos in [(),(0,),(1,),(2,)]: + self.assertTrue(att3.getFieldOn(att3.getMyGodFather().getMeshAtPosition(pos),"YY").isEqual(att4.getFieldOn(att4.getMyGodFather().getMeshAtPosition(pos),"YY"),1e-12)) + pass + exp5=DataArrayDouble([57.02,57.02,58.02,58.02,58.02,59.02,59.02,59.02,60.02,60.02,60.02,61.02,61.02,61.02,62.02,62.02,62.02,63.02,63.02,63.02,64.02,64.02,64.02,65.02,65.02,65.02,66.02,66.02,66.02,67.02,67.02,67.02,68.02,68.02,57.02,57.02,58.02,58.02,58.02,59.02,59.02,59.02,60.02,60.02,60.02,61.02,61.02,61.02,62.02,62.02,62.02,63.02,63.02,63.02,64.02,64.02,64.02,65.02,65.02,65.02,66.02,66.02,66.02,67.02,67.02,67.02,68.02,68.02,71.02,71.02,72.02,72.02,72.02,73.02,73.02,73.02,74.02,74.02,74.02,75.02,75.02,75.02,76.02,76.02,76.02,77.02,77.02,77.02,78.02,78.02,78.02,79.02,79.02,79.02,80.02,80.02,80.02,81.02,81.02,81.02,82.02,82.02,71.02,71.02,72.02,72.02,72.02,73.02,73.02,73.02,74.02,74.02,74.02,75.02,75.02,75.02,76.02,76.02,76.02,77.02,77.02,77.02,78.02,78.02,78.02,79.02,79.02,79.02,80.02,80.02,80.02,81.02,81.02,81.02,82.02,82.02,71.02,71.02,72.02,72.02,72.02,73.02,73.02,73.02,74.02,74.02,74.02,75.02,75.02,75.02,76.02,76.02,76.02,77.02,77.02,77.02,78.02,78.02,78.02,79.02,79.02,79.02,80.02,80.02,80.02,81.02,81.02,81.02,82.02,82.02,85.02,85.02,86.02,86.02,86.02,87.02,87.02,87.02,88.02,88.02,88.02,89.02,89.02,89.02,90.02,90.02,90.02,91.02,91.02,91.02,92.02,92.02,92.02,93.02,93.02,93.02,94.02,94.02,94.02,95.02,95.02,95.02,96.02,96.02,85.02,85.02,86.02,86.02,86.02,87.02,87.02,87.02,88.02,88.02,88.02,89.02,89.02,89.02,90.02,90.02,90.02,91.02,91.02,91.02,92.02,92.02,92.02,93.02,93.02,93.02,94.02,94.02,94.02,95.02,95.02,95.02,96.02,96.02,85.02,85.02,86.02,86.02,86.02,87.02,87.02,87.02,88.02,88.02,88.02,89.02,89.02,89.02,90.02,90.02,90.02,91.02,91.02,91.02,92.02,92.02,92.02,93.02,93.02,93.02,94.02,94.02,94.02,95.02,95.02,95.02,96.02,96.02,99.02,99.02,100.02,100.02,100.02,101.02,101.02,101.02,102.02,102.02,102.02,103.02,103.02,103.02,104.02,104.02,104.02,105.02,105.02,105.02,106.02,106.02,106.02,107.02,107.02,107.02,108.02,108.02,108.02,109.02,109.02,109.02,110.02,110.02,99.02,99.02,100.02,100.02,100.02,101.02,101.02,101.02,102.02,102.02,102.02,103.02,103.02,103.02,104.02,104.02,104.02,105.02,105.02,105.02,106.02,106.02,106.02,107.02,107.02,107.02,108.02,108.02,108.02,109.02,109.02,109.02,110.02,110.02,99.02,99.02,100.02,100.02,100.02,101.02,101.02,101.02,102.02,102.02,102.02,103.02,103.02,103.02,104.02,104.02,104.02,105.02,105.02,105.02,106.02,106.02,106.02,107.02,107.02,107.02,108.02,108.02,108.02,109.02,109.02,109.02,110.02,110.02,113.02,113.02,114.02,114.02,114.02,115.02,115.02,115.02,116.02,116.02,116.02,117.02,117.02,117.02,118.02,118.02,118.02,119.02,119.02,119.02,120.02,120.02,120.02,121.02,121.02,121.02,122.02,122.02,122.02,123.02,123.02,123.02,124.02,124.02,113.02,113.02,114.02,114.02,114.02,115.02,115.02,115.02,116.02,116.02,116.02,117.02,117.02,117.02,118.02,118.02,118.02,119.02,119.02,119.02,120.02,120.02,120.02,121.02,121.02,121.02,122.02,122.02,122.02,123.02,123.02,123.02,124.02,124.02]) + self.assertTrue(att3.getFieldOn(att3.getMyGodFather().getMeshAtPosition((0,0)),"YY").isEqualWithoutConsideringStr(exp5,1e-12)) + exp6=DataArrayDouble([17.02,17.02,18.02,18.02,18.02,19.02,19.02,19.02,20.02,20.02,20.02,21.02,21.02,21.02,22.02,22.02,17.02,17.02,18.02,18.02,18.02,19.02,19.02,19.02,20.02,20.02,20.02,21.02,21.02,21.02,22.02,22.02,31.02,31.02,32.02,32.02,32.02,33.02,33.02,33.02,34.02,34.02,34.02,35.02,35.02,35.02,36.02,36.02,31.02,31.02,32.02,32.02,32.02,33.02,33.02,33.02,34.02,34.02,34.02,35.02,35.02,35.02,36.02,36.02,31.02,31.02,32.02,32.02,32.02,33.02,33.02,33.02,34.02,34.02,34.02,35.02,35.02,35.02,36.02,36.02,45.02,45.02,46.02,46.02,46.02,47.02,47.02,47.02,48.02,48.02,48.02,49.02,49.02,49.02,50.02,50.02,45.02,45.02,46.02,46.02,46.02,47.02,47.02,47.02,48.02,48.02,48.02,49.02,49.02,49.02,50.02,50.02,45.02,45.02,46.02,46.02,46.02,47.02,47.02,47.02,48.02,48.02,48.02,49.02,49.02,49.02,50.02,50.02,59.02,59.02,60.02,60.02,60.02,61.02,61.02,61.02,62.02,62.02,62.02,63.02,63.02,63.02,64.02,64.02,59.02,59.02,60.02,60.02,60.02,61.02,61.02,61.02,62.02,62.02,62.02,63.02,63.02,63.02,64.02,64.02,59.02,59.02,60.02,60.02,60.02,61.02,61.02,61.02,62.02,62.02,62.02,63.02,63.02,63.02,64.02,64.02,73.02,73.02,74.02,74.02,74.02,75.02,75.02,75.02,76.02,76.02,76.02,77.02,77.02,77.02,78.02,78.02,73.02,73.02,74.02,74.02,74.02,75.02,75.02,75.02,76.02,76.02,76.02,77.02,77.02,77.02,78.02,78.02]) + self.assertTrue(att3.getFieldOn(att3.getMyGodFather().getMeshAtPosition((0,1)),"YY").isEqualWithoutConsideringStr(exp6,1e-12)) + exp7=DataArrayDouble([49.02,49.02,50.02,50.02,50.02,51.02,51.02,51.02,52.02,52.02,52.02,53.02,53.02,53.02,54.02,54.02,49.02,49.02,50.02,50.02,50.02,51.02,51.02,51.02,52.02,52.02,52.02,53.02,53.02,53.02,54.02,54.02,63.02,63.02,64.02,64.02,64.02,65.02,65.02,65.02,66.02,66.02,66.02,67.02,67.02,67.02,68.02,68.02,63.02,63.02,64.02,64.02,64.02,65.02,65.02,65.02,66.02,66.02,66.02,67.02,67.02,67.02,68.02,68.02,63.02,63.02,64.02,64.02,64.02,65.02,65.02,65.02,66.02,66.02,66.02,67.02,67.02,67.02,68.02,68.02,77.02,77.02,78.02,78.02,78.02,79.02,79.02,79.02,80.02,80.02,80.02,81.02,81.02,81.02,82.02,82.02,77.02,77.02,78.02,78.02,78.02,79.02,79.02,79.02,80.02,80.02,80.02,81.02,81.02,81.02,82.02,82.02]) + self.assertTrue(att3.getFieldOn(att3.getMyGodFather().getMeshAtPosition((0,2)),"YY").isEqualWithoutConsideringStr(exp7,1e-12)) + exp8=DataArrayDouble([15.03,15.03,16.03,16.03,16.03,17.03,17.03,17.03,18.03,18.03,18.03,19.03,19.03,19.03,20.03,20.03,15.03,15.03,16.03,16.03,16.03,17.03,17.03,17.03,18.03,18.03,18.03,19.03,19.03,19.03,20.03,20.03,29.03,29.03,30.03,30.03,30.03,31.03,31.03,31.03,32.03,32.03,32.03,33.03,33.03,33.03,34.03,34.03,29.03,29.03,30.03,30.03,30.03,31.03,31.03,31.03,32.03,32.03,32.03,33.03,33.03,33.03,34.03,34.03,29.03,29.03,30.03,30.03,30.03,31.03,31.03,31.03,32.03,32.03,32.03,33.03,33.03,33.03,34.03,34.03,43.03,43.03,44.03,44.03,44.03,45.03,45.03,45.03,46.03,46.03,46.03,47.03,47.03,47.03,48.03,48.03,43.03,43.03,44.03,44.03,44.03,45.03,45.03,45.03,46.03,46.03,46.03,47.03,47.03,47.03,48.03,48.03,43.03,43.03,44.03,44.03,44.03,45.03,45.03,45.03,46.03,46.03,46.03,47.03,47.03,47.03,48.03,48.03,57.03,57.03,58.03,58.03,58.03,59.03,59.03,59.03,60.03,60.03,60.03,61.03,61.03,61.03,62.03,62.03,57.03,57.03,58.03,58.03,58.03,59.03,59.03,59.03,60.03,60.03,60.03,61.03,61.03,61.03,62.03,62.03,57.03,57.03,58.03,58.03,58.03,59.03,59.03,59.03,60.03,60.03,60.03,61.03,61.03,61.03,62.03,62.03,71.03,71.03,72.03,72.03,72.03,73.03,73.03,73.03,74.03,74.03,74.03,75.03,75.03,75.03,76.03,76.03,71.03,71.03,72.03,72.03,72.03,73.03,73.03,73.03,74.03,74.03,74.03,75.03,75.03,75.03,76.03,76.03,71.03,71.03,72.03,72.03,72.03,73.03,73.03,73.03,74.03,74.03,74.03,75.03,75.03,75.03,76.03,76.03,85.03,85.03,86.03,86.03,86.03,87.03,87.03,87.03,88.03,88.03,88.03,89.03,89.03,89.03,90.03,90.03,85.03,85.03,86.03,86.03,86.03,87.03,87.03,87.03,88.03,88.03,88.03,89.03,89.03,89.03,90.03,90.03,85.03,85.03,86.03,86.03,86.03,87.03,87.03,87.03,88.03,88.03,88.03,89.03,89.03,89.03,90.03,90.03,99.03,99.03,100.03,100.03,100.03,101.03,101.03,101.03,102.03,102.03,102.03,103.03,103.03,103.03,104.03,104.03,99.03,99.03,100.03,100.03,100.03,101.03,101.03,101.03,102.03,102.03,102.03,103.03,103.03,103.03,104.03,104.03,99.03,99.03,100.03,100.03,100.03,101.03,101.03,101.03,102.03,102.03,102.03,103.03,103.03,103.03,104.03,104.03,113.03,113.03,114.03,114.03,114.03,115.03,115.03,115.03,116.03,116.03,116.03,117.03,117.03,117.03,118.03,118.03,113.03,113.03,114.03,114.03,114.03,115.03,115.03,115.03,116.03,116.03,116.03,117.03,117.03,117.03,118.03,118.03]) + self.assertTrue(att3.getFieldOn(att3.getMyGodFather().getMeshAtPosition((1,0)),"YY").isEqualWithoutConsideringStr(exp8,1e-12)) + exp9=DataArrayDouble([22.03,22.03,23.03,23.03,23.03,24.03,24.03,24.03,25.03,25.03,25.03,26.03,26.03,22.03,22.03,23.03,23.03,23.03,24.03,24.03,24.03,25.03,25.03,25.03,26.03,26.03,36.03,36.03,37.03,37.03,37.03,38.03,38.03,38.03,39.03,39.03,39.03,40.03,40.03,36.03,36.03,37.03,37.03,37.03,38.03,38.03,38.03,39.03,39.03,39.03,40.03,40.03,36.03,36.03,37.03,37.03,37.03,38.03,38.03,38.03,39.03,39.03,39.03,40.03,40.03,50.03,50.03,51.03,51.03,51.03,52.03,52.03,52.03,53.03,53.03,53.03,54.03,54.03,50.03,50.03,51.03,51.03,51.03,52.03,52.03,52.03,53.03,53.03,53.03,54.03,54.03,50.03,50.03,51.03,51.03,51.03,52.03,52.03,52.03,53.03,53.03,53.03,54.03,54.03,64.03,64.03,65.03,65.03,65.03,66.03,66.03,66.03,67.03,67.03,67.03,68.03,68.03,64.03,64.03,65.03,65.03,65.03,66.03,66.03,66.03,67.03,67.03,67.03,68.03,68.03,64.03,64.03,65.03,65.03,65.03,66.03,66.03,66.03,67.03,67.03,67.03,68.03,68.03,78.03,78.03,79.03,79.03,79.03,80.03,80.03,80.03,81.03,81.03,81.03,82.03,82.03,78.03,78.03,79.03,79.03,79.03,80.03,80.03,80.03,81.03,81.03,81.03,82.03,82.03,78.03,78.03,79.03,79.03,79.03,80.03,80.03,80.03,81.03,81.03,81.03,82.03,82.03,92.03,92.03,93.03,93.03,93.03,94.03,94.03,94.03,95.03,95.03,95.03,96.03,96.03,92.03,92.03,93.03,93.03,93.03,94.03,94.03,94.03,95.03,95.03,95.03,96.03,96.03]) + self.assertTrue(att3.getFieldOn(att3.getMyGodFather().getMeshAtPosition((1,1)),"YY").isEqualWithoutConsideringStr(exp9,1e-12)) + exp10=DataArrayDouble([19.03,19.03,20.03,20.03,20.03,21.03,21.03,21.03,22.03,22.03,22.03,23.03,23.03,19.03,19.03,20.03,20.03,20.03,21.03,21.03,21.03,22.03,22.03,22.03,23.03,23.03,33.03,33.03,34.03,34.03,34.03,35.03,35.03,35.03,36.03,36.03,36.03,37.03,37.03,33.03,33.03,34.03,34.03,34.03,35.03,35.03,35.03,36.03,36.03,36.03,37.03,37.03,33.03,33.03,34.03,34.03,34.03,35.03,35.03,35.03,36.03,36.03,36.03,37.03,37.03,47.03,47.03,48.03,48.03,48.03,49.03,49.03,49.03,50.03,50.03,50.03,51.03,51.03,47.03,47.03,48.03,48.03,48.03,49.03,49.03,49.03,50.03,50.03,50.03,51.03,51.03,47.03,47.03,48.03,48.03,48.03,49.03,49.03,49.03,50.03,50.03,50.03,51.03,51.03,61.03,61.03,62.03,62.03,62.03,63.03,63.03,63.03,64.03,64.03,64.03,65.03,65.03,61.03,61.03,62.03,62.03,62.03,63.03,63.03,63.03,64.03,64.03,64.03,65.03,65.03,61.03,61.03,62.03,62.03,62.03,63.03,63.03,63.03,64.03,64.03,64.03,65.03,65.03,75.03,75.03,76.03,76.03,76.03,77.03,77.03,77.03,78.03,78.03,78.03,79.03,79.03,75.03,75.03,76.03,76.03,76.03,77.03,77.03,77.03,78.03,78.03,78.03,79.03,79.03]) + self.assertTrue(att3.getFieldOn(att3.getMyGodFather().getMeshAtPosition((1,2)),"YY").isEqualWithoutConsideringStr(exp10,1e-12)) + exp11=DataArrayDouble([61.03,61.03,62.03,62.03,62.03,63.03,63.03,63.03,64.03,64.03,64.03,65.03,65.03,61.03,61.03,62.03,62.03,62.03,63.03,63.03,63.03,64.03,64.03,64.03,65.03,65.03,75.03,75.03,76.03,76.03,76.03,77.03,77.03,77.03,78.03,78.03,78.03,79.03,79.03,75.03,75.03,76.03,76.03,76.03,77.03,77.03,77.03,78.03,78.03,78.03,79.03,79.03,75.03,75.03,76.03,76.03,76.03,77.03,77.03,77.03,78.03,78.03,78.03,79.03,79.03,89.03,89.03,90.03,90.03,90.03,91.03,91.03,91.03,92.03,92.03,92.03,93.03,93.03,89.03,89.03,90.03,90.03,90.03,91.03,91.03,91.03,92.03,92.03,92.03,93.03,93.03,89.03,89.03,90.03,90.03,90.03,91.03,91.03,91.03,92.03,92.03,92.03,93.03,93.03,103.03,103.03,104.03,104.03,104.03,105.03,105.03,105.03,106.03,106.03,106.03,107.03,107.03,103.03,103.03,104.03,104.03,104.03,105.03,105.03,105.03,106.03,106.03,106.03,107.03,107.03,103.03,103.03,104.03,104.03,104.03,105.03,105.03,105.03,106.03,106.03,106.03,107.03,107.03,117.03,117.03,118.03,118.03,118.03,119.03,119.03,119.03,120.03,120.03,120.03,121.03,121.03,117.03,117.03,118.03,118.03,118.03,119.03,119.03,119.03,120.03,120.03,120.03,121.03,121.03]) + self.assertTrue(att3.getFieldOn(att3.getMyGodFather().getMeshAtPosition((1,3)),"YY").isEqualWithoutConsideringStr(exp11,1e-12)) + del att3 + ### + att4.synchronizeAllGhostZonesAtASpecifiedLevel(2) + for pos in [(),(0,),(1,),(2,)]: + self.assertTrue(att4.getFieldOn(att4.getMyGodFather().getMeshAtPosition(pos),"YY").isEqual(att5.getFieldOn(att5.getMyGodFather().getMeshAtPosition(pos),"YY"),1e-12)) + pass + exp12=DataArrayDouble([0.04,1.04,2.04,3.04,4.04,5.04,6.04,7.04,146.05,147.05,148.05,149.05,150.05,151.05,152.05,153.05,154.05,155.05,156.05,157.05,50.06,51.06,52.06,53.06,54.06,55.06,56.06,57.06,58.06,59.06,60.06,61.06,32.04,33.04,34.04,35.04,36.04,37.04,38.04,39.04,40.04,41.04,162.05,163.05,164.05,165.05,166.05,167.05,168.05,169.05,170.05,171.05,172.05,173.05,66.06,67.06,68.06,69.06,70.06,71.06,72.06,73.06,74.06,75.06,76.06,77.06,66.04,67.04,68.04,69.04,70.04,71.04,72.04,73.04,74.04,75.04,76.04,77.04,78.04,79.04,80.04,81.04,82.04,83.04,84.04,85.04,86.04,87.04,88.04,89.04,90.04,91.04,92.04,93.04,94.04,95.04,96.04,97.04,98.04,99.04,100.04,101.04,102.04,103.04,104.04,105.04,106.04,107.04,108.04,109.04,110.04,111.04,112.04,113.04,114.04,115.04,116.04,117.04,118.04,119.04,120.04,121.04,122.04,123.04,124.04,125.04,126.04,127.04,128.04,129.04,130.04,131.04,132.04,133.04,134.04,135.04,136.04,137.04,138.04,139.04,140.04,141.04,142.04,143.04,144.04,145.04,146.04,147.04,148.04,149.04,150.04,151.04,152.04,153.04,154.04,155.04,156.04,157.04,158.04,159.04,160.04,161.04,162.04,163.04,164.04,165.04,166.04,167.04,168.04,169.04,170.04,171.04,172.04,173.04,174.04,175.04,176.04,177.04,178.04,179.04,180.04,181.04,182.04,183.04,184.04,185.04,186.04,187.04,188.04,189.04,190.04,191.04,192.04,193.04,194.04,195.04,196.04,197.04,198.04,199.04,200.04,201.04,202.04,203.04,204.04,205.04,206.04,207.04,208.04,209.04,210.04,211.04,212.04,213.04,214.04,215.04,216.04,217.04,218.04,219.04,220.04,221.04,222.04,223.04,224.04,225.04,226.04,227.04,228.04,229.04,230.04,231.04,232.04,233.04,234.04,235.04,236.04,237.04,238.04,239.04,240.04,241.04,242.04,243.04,244.04,245.04,246.04,247.04,248.04,249.04,250.04,251.04,252.04,253.04,254.04,255.04,256.04,257.04,258.04,259.04,260.04,261.04,262.04,263.04,264.04,265.04,266.04,267.04,268.04,269.04,270.04,271.04,272.04,273.04,274.04,275.04,276.04,277.04,278.04,279.04,280.04,281.04,282.04,283.04,284.04,285.04,286.04,287.04,288.04,289.04,290.04,291.04,292.04,293.04,294.04,295.04,296.04,297.04,298.04,299.04,300.04,301.04,302.04,303.04,304.04,305.04,306.04,307.04,308.04,309.04,310.04,311.04,312.04,313.04,314.04,315.04,316.04,317.04,318.04,319.04,320.04,321.04,322.04,323.04,324.04,325.04,326.04,327.04,328.04,329.04,330.04,331.04,332.04,333.04,334.04,335.04,336.04,337.04,338.04,339.04,340.04,341.04,342.04,343.04,344.04,345.04,346.04,347.04,348.04,349.04,350.04,351.04,352.04,353.04,354.04,355.04,356.04,357.04,358.04,359.04,360.04,361.04,362.04,363.04,364.04,365.04,366.04,367.04,368.04,369.04,370.04,371.04,372.04,373.04,374.04,375.04,34.07,35.07,36.07,37.07,38.07,39.07,40.07,41.07,42.07,43.07,44.07,45.07,28.09,29.09,30.09,31.09,32.09,33.09,34.09,35.09,36.09,28.08,29.08,30.08,31.08,32.08,33.08,34.08,35.08,36.08,406.04,407.04,408.04,409.04,50.07,51.07,52.07,53.07,54.07,55.07,56.07,57.07,58.07,59.07,60.07,61.07,41.09,42.09,43.09,44.09,45.09,46.09,47.09,48.09,49.09,41.08,42.08,43.08,44.08,45.08,46.08,47.08,48.08,49.08,440.04,441.04]) + self.assertTrue(att4.getFieldOn(att4.getMyGodFather().getMeshAtPosition((0,0)),"YY").isEqualWithoutConsideringStr(exp12,1e-12)) + exp13=DataArrayDouble([[0.05,1.05,2.05,3.05,4.05,5.05,6.05,7.05,8.05,9.05,10.05,11.05,12.05,13.05,14.05,15.05,16.05,17.05,18.05,19.05,20.05,21.05,22.05,23.05,24.05,25.05,26.05,27.05,28.05,29.05,30.05,31.05,32.05,33.05,34.05,35.05,36.05,37.05,38.05,39.05,40.05,41.05,42.05,43.05,44.05,45.05,46.05,47.05,48.05,49.05,50.05,51.05,52.05,53.05,54.05,55.05,56.05,57.05,58.05,59.05,60.05,61.05,62.05,63.05,64.05,65.05,66.05,67.05,68.05,69.05,70.05,71.05,72.05,73.05,74.05,75.05,76.05,77.05,78.05,79.05,80.05,81.05,82.05,83.05,84.05,85.05,86.05,87.05,88.05,89.05,90.05,91.05,92.05,93.05,94.05,95.05,96.05,97.05,98.05,99.05,100.05,101.05,102.05,103.05,104.05,105.05,106.05,107.05,108.05,109.05,110.05,111.05,112.05,113.05,114.05,115.05,116.05,117.05,118.05,119.05,120.05,121.05,122.05,123.05,124.05,125.05,126.05,127.05,128.05,129.05,130.05,131.05,132.05,133.05,134.05,135.05,136.05,137.05,138.05,139.05,140.05,141.05,34.06,35.06,144.05,145.05,146.05,147.05,148.05,149.05,150.05,151.05,152.05,153.05,154.05,155.05,156.05,157.05,50.06,51.06,160.05,161.05,162.05,163.05,164.05,165.05,166.05,167.05,168.05,169.05,170.05,171.05,172.05,173.05,66.06,67.06,74.04,75.04,76.04,77.04,78.04,79.04,80.04,81.04,82.04,83.04,84.04,85.04,86.04,87.04,88.04,89.04,108.04,109.04,110.04,111.04,112.04,113.04,114.04,115.04,116.04,117.04,118.04,119.04,120.04,121.04,122.04,123.04]]) + self.assertTrue(att4.getFieldOn(att4.getMyGodFather().getMeshAtPosition((0,1)),"YY").isEqualWithoutConsideringStr(exp13,1e-12)) + exp14=DataArrayDouble([108.05,109.05,2.06,3.06,4.06,5.06,6.06,7.06,8.06,9.06,10.06,11.06,12.06,13.06,14.06,15.06,124.05,125.05,18.06,19.06,20.06,21.06,22.06,23.06,24.06,25.06,26.06,27.06,28.06,29.06,30.06,31.06,140.05,141.05,34.06,35.06,36.06,37.06,38.06,39.06,40.06,41.06,42.06,43.06,44.06,45.06,46.06,47.06,156.05,157.05,50.06,51.06,52.06,53.06,54.06,55.06,56.06,57.06,58.06,59.06,60.06,61.06,62.06,63.06,172.05,173.05,66.06,67.06,68.06,69.06,70.06,71.06,72.06,73.06,74.06,75.06,76.06,77.06,78.06,79.06,86.04,87.04,88.04,89.04,90.04,91.04,92.04,93.04,94.04,95.04,96.04,97.04,98.04,99.04,94.06,95.06,120.04,121.04,122.04,123.04,124.04,125.04,126.04,127.04,128.04,129.04,130.04,131.04,132.04,133.04,110.06,111.06]) + self.assertTrue(att4.getFieldOn(att4.getMyGodFather().getMeshAtPosition((0,2)),"YY").isEqualWithoutConsideringStr(exp14,1e-12)) + exp15=DataArrayDouble([0.07,1.07,308.04,309.04,310.04,311.04,312.04,313.04,314.04,315.04,316.04,317.04,318.04,319.04,320.04,321.04,16.07,17.07,342.04,343.04,344.04,345.04,346.04,347.04,348.04,349.04,350.04,351.04,352.04,353.04,354.04,355.04,32.07,33.07,34.07,35.07,36.07,37.07,38.07,39.07,40.07,41.07,42.07,43.07,44.07,45.07,28.09,29.09,48.07,49.07,50.07,51.07,52.07,53.07,54.07,55.07,56.07,57.07,58.07,59.07,60.07,61.07,41.09,42.09,64.07,65.07,66.07,67.07,68.07,69.07,70.07,71.07,72.07,73.07,74.07,75.07,76.07,77.07,54.09,55.09,80.07,81.07,82.07,83.07,84.07,85.07,86.07,87.07,88.07,89.07,90.07,91.07,92.07,93.07,67.09,68.09,96.07,97.07,98.07,99.07,100.07,101.07,102.07,103.07,104.07,105.07,106.07,107.07,108.07,109.07,80.09,81.09,112.07,113.07,114.07,115.07,116.07,117.07,118.07,119.07,120.07,121.07,122.07,123.07,124.07,125.07,93.09,94.09,128.07,129.07,130.07,131.07,132.07,133.07,134.07,135.07,136.07,137.07,138.07,139.07,140.07,141.07,106.09,107.09,144.07,145.07,146.07,147.07,148.07,149.07,150.07,151.07,152.07,153.07,154.07,155.07,156.07,157.07,119.09,120.09,160.07,161.07,162.07,163.07,164.07,165.07,166.07,167.07,168.07,169.07,170.07,171.07,172.07,173.07,132.09,133.09,176.07,177.07,178.07,179.07,180.07,181.07,182.07,183.07,184.07,185.07,186.07,187.07,188.07,189.07,28.1,29.1,192.07,193.07,194.07,195.07,196.07,197.07,198.07,199.07,200.07,201.07,202.07,203.07,204.07,205.07,41.1,42.1,208.07,209.07,210.07,211.07,212.07,213.07,214.07,215.07,216.07,217.07,218.07,219.07,220.07,221.07,54.1,55.1,224.07,225.07,226.07,227.07,228.07,229.07,230.07,231.07,232.07,233.07,234.07,235.07,236.07,237.07,67.1,68.1,240.07,241.07,242.07,243.07,244.07,245.07,246.07,247.07,248.07,249.07,250.07,251.07,252.07,253.07,80.1,81.1,256.07,257.07,258.07,259.07,260.07,261.07,262.07,263.07,264.07,265.07,266.07,267.07,268.07,269.07,93.1,94.1,272.07,273.07,274.07,275.07,276.07,277.07,278.07,279.07,280.07,281.07,282.07,283.07,284.07,285.07,106.1,107.1,288.07,289.07,290.07,291.07,292.07,293.07,294.07,295.07,296.07,297.07,298.07,299.07,300.07,301.07,119.1,120.1,304.07,305.07,306.07,307.07,308.07,309.07,310.07,311.07,312.07,313.07,314.07,315.07,316.07,317.07,132.1,133.1,320.07,321.07,322.07,323.07,324.07,325.07,326.07,327.07,328.07,329.07,330.07,331.07,332.07,333.07,334.07,335.07,336.07,337.07,338.07,339.07,340.07,341.07,342.07,343.07,344.07,345.07,346.07,347.07,348.07,349.07,350.07,351.07]) + self.assertTrue(att4.getFieldOn(att4.getMyGodFather().getMeshAtPosition((1,0)),"YY").isEqualWithoutConsideringStr(exp15,1e-12)) + exp16=DataArrayDouble([327.04,328.04,329.04,330.04,331.04,332.04,333.04,334.04,335.04,336.04,337.04,11.08,12.08,361.04,362.04,363.04,364.04,365.04,366.04,367.04,368.04,369.04,370.04,371.04,24.08,25.08,35.09,36.09,28.08,29.08,30.08,31.08,32.08,33.08,34.08,35.08,36.08,37.08,38.08,48.09,49.09,41.08,42.08,43.08,44.08,45.08,46.08,47.08,48.08,49.08,50.08,51.08,61.09,62.09,54.08,55.08,56.08,57.08,58.08,59.08,60.08,61.08,62.08,63.08,64.08,74.09,75.09,67.08,68.08,69.08,70.08,71.08,72.08,73.08,74.08,75.08,76.08,77.08,87.09,88.09,80.08,81.08,82.08,83.08,84.08,85.08,86.08,87.08,88.08,89.08,90.08,100.09,101.09,93.08,94.08,95.08,96.08,97.08,98.08,99.08,100.08,101.08,102.08,103.08,113.09,114.09,106.08,107.08,108.08,109.08,110.08,111.08,112.08,113.08,114.08,115.08,116.08,126.09,127.09,119.08,120.08,121.08,122.08,123.08,124.08,125.08,126.08,127.08,128.08,129.08,139.09,140.09,132.08,133.08,134.08,135.08,136.08,137.08,138.08,139.08,140.08,141.08,142.08,35.1,36.1,145.08,146.08,147.08,148.08,149.08,150.08,151.08,152.08,153.08,154.08,155.08,48.1,49.1,158.08,159.08,160.08,161.08,162.08,163.08,164.08,165.08,166.08,167.08,168.08,61.1,62.1,171.08,172.08,173.08,174.08,175.08,176.08,177.08,178.08,179.08,180.08,181.08,74.1,75.1,184.08,185.08,186.08,187.08,188.08,189.08,190.08,191.08,192.08,193.08,194.08,87.1,88.1,197.08,198.08,199.08,200.08,201.08,202.08,203.08,204.08,205.08,206.08,207.08]) + self.assertTrue(att4.getFieldOn(att4.getMyGodFather().getMeshAtPosition((1,1)),"YY").isEqualWithoutConsideringStr(exp16,1e-12)) + exp17=DataArrayDouble([318.04,319.04,320.04,321.04,322.04,323.04,324.04,325.04,326.04,327.04,328.04,329.04,330.04,352.04,353.04,354.04,355.04,356.04,357.04,358.04,359.04,360.04,361.04,362.04,363.04,364.04,44.07,45.07,28.09,29.09,30.09,31.09,32.09,33.09,34.09,35.09,36.09,28.08,29.08,60.07,61.07,41.09,42.09,43.09,44.09,45.09,46.09,47.09,48.09,49.09,41.08,42.08,76.07,77.07,54.09,55.09,56.09,57.09,58.09,59.09,60.09,61.09,62.09,54.08,55.08,92.07,93.07,67.09,68.09,69.09,70.09,71.09,72.09,73.09,74.09,75.09,67.08,68.08,108.07,109.07,80.09,81.09,82.09,83.09,84.09,85.09,86.09,87.09,88.09,80.08,81.08,124.07,125.07,93.09,94.09,95.09,96.09,97.09,98.09,99.09,100.09,101.09,93.08,94.08,140.07,141.07,106.09,107.09,108.09,109.09,110.09,111.09,112.09,113.09,114.09,106.08,107.08,156.07,157.07,119.09,120.09,121.09,122.09,123.09,124.09,125.09,126.09,127.09,119.08,120.08,172.07,173.07,132.09,133.09,134.09,135.09,136.09,137.09,138.09,139.09,140.09,132.08,133.08,188.07,189.07,28.1,29.1,30.1,31.1,32.1,33.1,34.1,35.1,36.1,145.08,146.08,204.07,205.07,41.1,42.1,43.1,44.1,45.1,46.1,47.1,48.1,49.1,158.08,159.08]) + self.assertTrue(att4.getFieldOn(att4.getMyGodFather().getMeshAtPosition((1,2)),"YY").isEqualWithoutConsideringStr(exp17,1e-12)) + exp18=DataArrayDouble([156.07,157.07,119.09,120.09,121.09,122.09,123.09,124.09,125.09,126.09,127.09,119.08,120.08,172.07,173.07,132.09,133.09,134.09,135.09,136.09,137.09,138.09,139.09,140.09,132.08,133.08,188.07,189.07,28.1,29.1,30.1,31.1,32.1,33.1,34.1,35.1,36.1,145.08,146.08,204.07,205.07,41.1,42.1,43.1,44.1,45.1,46.1,47.1,48.1,49.1,158.08,159.08,220.07,221.07,54.1,55.1,56.1,57.1,58.1,59.1,60.1,61.1,62.1,171.08,172.08,236.07,237.07,67.1,68.1,69.1,70.1,71.1,72.1,73.1,74.1,75.1,76.1,77.1,252.07,253.07,80.1,81.1,82.1,83.1,84.1,85.1,86.1,87.1,88.1,89.1,90.1,268.07,269.07,93.1,94.1,95.1,96.1,97.1,98.1,99.1,100.1,101.1,102.1,103.1,284.07,285.07,106.1,107.1,108.1,109.1,110.1,111.1,112.1,113.1,114.1,115.1,116.1,300.07,301.07,119.1,120.1,121.1,122.1,123.1,124.1,125.1,126.1,127.1,128.1,129.1,316.07,317.07,132.1,133.1,134.1,135.1,136.1,137.1,138.1,139.1,140.1,141.1,142.1,143.1,144.1,145.1,146.1,147.1,148.1,149.1,150.1,151.1,152.1,153.1,154.1,155.1,156.1,157.1,158.1,159.1,160.1,161.1,162.1,163.1,164.1,165.1,166.1,167.1,168.1]) + self.assertTrue(att4.getFieldOn(att4.getMyGodFather().getMeshAtPosition((1,3)),"YY").isEqualWithoutConsideringStr(exp18,1e-12)) + del att4 + ### + att5.synchronizeAllGhostZonesAtASpecifiedLevelUsingOnlyFather(2) + for pos in [(),(0,),(1,),(2,)]: + self.assertTrue(att5.getFieldOn(att5.getMyGodFather().getMeshAtPosition(pos),"YY").isEqual(att6.getFieldOn(att6.getMyGodFather().getMeshAtPosition(pos),"YY"),1e-12)) + pass + att5.buildCellFieldOnWithGhost(att5.getMyGodFather().getMeshAtPosition((0,0)),"YY") + exp19=DataArrayDouble([57.02,57.02,58.02,58.02,58.02,59.02,59.02,59.02,60.02,60.02,60.02,61.02,61.02,61.02,62.02,62.02,62.02,63.02,63.02,63.02,64.02,64.02,64.02,65.02,65.02,65.02,66.02,66.02,66.02,67.02,67.02,67.02,68.02,68.02,57.02,57.02,58.02,58.02,58.02,59.02,59.02,59.02,60.02,60.02,60.02,61.02,61.02,61.02,62.02,62.02,62.02,63.02,63.02,63.02,64.02,64.02,64.02,65.02,65.02,65.02,66.02,66.02,66.02,67.02,67.02,67.02,68.02,68.02,71.02,71.02,70.04,71.04,72.04,73.04,74.04,75.04,76.04,77.04,78.04,79.04,80.04,81.04,82.04,83.04,84.04,85.04,86.04,87.04,88.04,89.04,90.04,91.04,92.04,93.04,94.04,95.04,96.04,97.04,98.04,99.04,82.02,82.02,71.02,71.02,104.04,105.04,106.04,107.04,108.04,109.04,110.04,111.04,112.04,113.04,114.04,115.04,116.04,117.04,118.04,119.04,120.04,121.04,122.04,123.04,124.04,125.04,126.04,127.04,128.04,129.04,130.04,131.04,132.04,133.04,82.02,82.02,71.02,71.02,138.04,139.04,140.04,141.04,142.04,143.04,144.04,145.04,146.04,147.04,148.04,149.04,150.04,151.04,152.04,153.04,154.04,155.04,156.04,157.04,158.04,159.04,160.04,161.04,162.04,163.04,164.04,165.04,166.04,167.04,82.02,82.02,85.02,85.02,172.04,173.04,174.04,175.04,176.04,177.04,178.04,179.04,180.04,181.04,182.04,183.04,184.04,185.04,186.04,187.04,188.04,189.04,190.04,191.04,192.04,193.04,194.04,195.04,196.04,197.04,198.04,199.04,200.04,201.04,96.02,96.02,85.02,85.02,206.04,207.04,208.04,209.04,210.04,211.04,212.04,213.04,214.04,215.04,216.04,217.04,218.04,219.04,220.04,221.04,222.04,223.04,224.04,225.04,226.04,227.04,228.04,229.04,230.04,231.04,232.04,233.04,234.04,235.04,96.02,96.02,85.02,85.02,240.04,241.04,242.04,243.04,244.04,245.04,246.04,247.04,248.04,249.04,250.04,251.04,252.04,253.04,254.04,255.04,256.04,257.04,258.04,259.04,260.04,261.04,262.04,263.04,264.04,265.04,266.04,267.04,268.04,269.04,96.02,96.02,99.02,99.02,274.04,275.04,276.04,277.04,278.04,279.04,280.04,281.04,282.04,283.04,284.04,285.04,286.04,287.04,288.04,289.04,290.04,291.04,292.04,293.04,294.04,295.04,296.04,297.04,298.04,299.04,300.04,301.04,302.04,303.04,110.02,110.02,99.02,99.02,308.04,309.04,310.04,311.04,312.04,313.04,314.04,315.04,316.04,317.04,318.04,319.04,320.04,321.04,322.04,323.04,324.04,325.04,326.04,327.04,328.04,329.04,330.04,331.04,332.04,333.04,334.04,335.04,336.04,337.04,110.02,110.02,99.02,99.02,342.04,343.04,344.04,345.04,346.04,347.04,348.04,349.04,350.04,351.04,352.04,353.04,354.04,355.04,356.04,357.04,358.04,359.04,360.04,361.04,362.04,363.04,364.04,365.04,366.04,367.04,368.04,369.04,370.04,371.04,110.02,110.02,113.02,113.02,114.02,114.02,114.02,115.02,115.02,115.02,116.02,116.02,116.02,117.02,117.02,117.02,118.02,118.02,118.02,119.02,119.02,119.02,120.02,120.02,120.02,121.02,121.02,121.02,122.02,122.02,122.02,123.02,123.02,123.02,124.02,124.02,113.02,113.02,114.02,114.02,114.02,115.02,115.02,115.02,116.02,116.02,116.02,117.02,117.02,117.02,118.02,118.02,118.02,119.02,119.02,119.02,120.02,120.02,120.02,121.02,121.02,121.02,122.02,122.02,122.02,123.02,123.02,123.02,124.02,124.02]) + self.assertTrue(att5.getFieldOn(att5.getMyGodFather().getMeshAtPosition((0,0)),"YY").isEqualWithoutConsideringStr(exp19,1e-12)) + exp20=DataArrayDouble([17.02,17.02,18.02,18.02,18.02,19.02,19.02,19.02,20.02,20.02,20.02,21.02,21.02,21.02,22.02,22.02,17.02,17.02,18.02,18.02,18.02,19.02,19.02,19.02,20.02,20.02,20.02,21.02,21.02,21.02,22.02,22.02,31.02,31.02,34.05,35.05,36.05,37.05,38.05,39.05,40.05,41.05,42.05,43.05,44.05,45.05,36.02,36.02,31.02,31.02,50.05,51.05,52.05,53.05,54.05,55.05,56.05,57.05,58.05,59.05,60.05,61.05,36.02,36.02,31.02,31.02,66.05,67.05,68.05,69.05,70.05,71.05,72.05,73.05,74.05,75.05,76.05,77.05,36.02,36.02,45.02,45.02,82.05,83.05,84.05,85.05,86.05,87.05,88.05,89.05,90.05,91.05,92.05,93.05,50.02,50.02,45.02,45.02,98.05,99.05,100.05,101.05,102.05,103.05,104.05,105.05,106.05,107.05,108.05,109.05,50.02,50.02,45.02,45.02,114.05,115.05,116.05,117.05,118.05,119.05,120.05,121.05,122.05,123.05,124.05,125.05,50.02,50.02,59.02,59.02,130.05,131.05,132.05,133.05,134.05,135.05,136.05,137.05,138.05,139.05,140.05,141.05,64.02,64.02,59.02,59.02,146.05,147.05,148.05,149.05,150.05,151.05,152.05,153.05,154.05,155.05,156.05,157.05,64.02,64.02,59.02,59.02,162.05,163.05,164.05,165.05,166.05,167.05,168.05,169.05,170.05,171.05,172.05,173.05,64.02,64.02,73.02,73.02,74.02,74.02,74.02,75.02,75.02,75.02,76.02,76.02,76.02,77.02,77.02,77.02,78.02,78.02,73.02,73.02,74.02,74.02,74.02,75.02,75.02,75.02,76.02,76.02,76.02,77.02,77.02,77.02,78.02,78.02]) + self.assertTrue(att5.getFieldOn(att5.getMyGodFather().getMeshAtPosition((0,1)),"YY").isEqualWithoutConsideringStr(exp20,1e-12)) + exp21=DataArrayDouble([49.02,49.02,50.02,50.02,50.02,51.02,51.02,51.02,52.02,52.02,52.02,53.02,53.02,53.02,54.02,54.02,49.02,49.02,50.02,50.02,50.02,51.02,51.02,51.02,52.02,52.02,52.02,53.02,53.02,53.02,54.02,54.02,63.02,63.02,34.06,35.06,36.06,37.06,38.06,39.06,40.06,41.06,42.06,43.06,44.06,45.06,68.02,68.02,63.02,63.02,50.06,51.06,52.06,53.06,54.06,55.06,56.06,57.06,58.06,59.06,60.06,61.06,68.02,68.02,63.02,63.02,66.06,67.06,68.06,69.06,70.06,71.06,72.06,73.06,74.06,75.06,76.06,77.06,68.02,68.02,77.02,77.02,78.02,78.02,78.02,79.02,79.02,79.02,80.02,80.02,80.02,81.02,81.02,81.02,82.02,82.02,77.02,77.02,78.02,78.02,78.02,79.02,79.02,79.02,80.02,80.02,80.02,81.02,81.02,81.02,82.02,82.02]) + self.assertTrue(att5.getFieldOn(att5.getMyGodFather().getMeshAtPosition((0,2)),"YY").isEqualWithoutConsideringStr(exp21,1e-12)) + exp22=DataArrayDouble([15.03,15.03,16.03,16.03,16.03,17.03,17.03,17.03,18.03,18.03,18.03,19.03,19.03,19.03,20.03,20.03,15.03,15.03,16.03,16.03,16.03,17.03,17.03,17.03,18.03,18.03,18.03,19.03,19.03,19.03,20.03,20.03,29.03,29.03,34.07,35.07,36.07,37.07,38.07,39.07,40.07,41.07,42.07,43.07,44.07,45.07,34.03,34.03,29.03,29.03,50.07,51.07,52.07,53.07,54.07,55.07,56.07,57.07,58.07,59.07,60.07,61.07,34.03,34.03,29.03,29.03,66.07,67.07,68.07,69.07,70.07,71.07,72.07,73.07,74.07,75.07,76.07,77.07,34.03,34.03,43.03,43.03,82.07,83.07,84.07,85.07,86.07,87.07,88.07,89.07,90.07,91.07,92.07,93.07,48.03,48.03,43.03,43.03,98.07,99.07,100.07,101.07,102.07,103.07,104.07,105.07,106.07,107.07,108.07,109.07,48.03,48.03,43.03,43.03,114.07,115.07,116.07,117.07,118.07,119.07,120.07,121.07,122.07,123.07,124.07,125.07,48.03,48.03,57.03,57.03,130.07,131.07,132.07,133.07,134.07,135.07,136.07,137.07,138.07,139.07,140.07,141.07,62.03,62.03,57.03,57.03,146.07,147.07,148.07,149.07,150.07,151.07,152.07,153.07,154.07,155.07,156.07,157.07,62.03,62.03,57.03,57.03,162.07,163.07,164.07,165.07,166.07,167.07,168.07,169.07,170.07,171.07,172.07,173.07,62.03,62.03,71.03,71.03,178.07,179.07,180.07,181.07,182.07,183.07,184.07,185.07,186.07,187.07,188.07,189.07,76.03,76.03,71.03,71.03,194.07,195.07,196.07,197.07,198.07,199.07,200.07,201.07,202.07,203.07,204.07,205.07,76.03,76.03,71.03,71.03,210.07,211.07,212.07,213.07,214.07,215.07,216.07,217.07,218.07,219.07,220.07,221.07,76.03,76.03,85.03,85.03,226.07,227.07,228.07,229.07,230.07,231.07,232.07,233.07,234.07,235.07,236.07,237.07,90.03,90.03,85.03,85.03,242.07,243.07,244.07,245.07,246.07,247.07,248.07,249.07,250.07,251.07,252.07,253.07,90.03,90.03,85.03,85.03,258.07,259.07,260.07,261.07,262.07,263.07,264.07,265.07,266.07,267.07,268.07,269.07,90.03,90.03,99.03,99.03,274.07,275.07,276.07,277.07,278.07,279.07,280.07,281.07,282.07,283.07,284.07,285.07,104.03,104.03,99.03,99.03,290.07,291.07,292.07,293.07,294.07,295.07,296.07,297.07,298.07,299.07,300.07,301.07,104.03,104.03,99.03,99.03,306.07,307.07,308.07,309.07,310.07,311.07,312.07,313.07,314.07,315.07,316.07,317.07,104.03,104.03,113.03,113.03,114.03,114.03,114.03,115.03,115.03,115.03,116.03,116.03,116.03,117.03,117.03,117.03,118.03,118.03,113.03,113.03,114.03,114.03,114.03,115.03,115.03,115.03,116.03,116.03,116.03,117.03,117.03,117.03,118.03,118.03]) + self.assertTrue(att5.getFieldOn(att5.getMyGodFather().getMeshAtPosition((1,0)),"YY").isEqualWithoutConsideringStr(exp22,1e-12)) + exp23=DataArrayDouble([22.03,22.03,23.03,23.03,23.03,24.03,24.03,24.03,25.03,25.03,25.03,26.03,26.03,22.03,22.03,23.03,23.03,23.03,24.03,24.03,24.03,25.03,25.03,25.03,26.03,26.03,36.03,36.03,28.08,29.08,30.08,31.08,32.08,33.08,34.08,35.08,36.08,40.03,40.03,36.03,36.03,41.08,42.08,43.08,44.08,45.08,46.08,47.08,48.08,49.08,40.03,40.03,36.03,36.03,54.08,55.08,56.08,57.08,58.08,59.08,60.08,61.08,62.08,40.03,40.03,50.03,50.03,67.08,68.08,69.08,70.08,71.08,72.08,73.08,74.08,75.08,54.03,54.03,50.03,50.03,80.08,81.08,82.08,83.08,84.08,85.08,86.08,87.08,88.08,54.03,54.03,50.03,50.03,93.08,94.08,95.08,96.08,97.08,98.08,99.08,100.08,101.08,54.03,54.03,64.03,64.03,106.08,107.08,108.08,109.08,110.08,111.08,112.08,113.08,114.08,68.03,68.03,64.03,64.03,119.08,120.08,121.08,122.08,123.08,124.08,125.08,126.08,127.08,68.03,68.03,64.03,64.03,132.08,133.08,134.08,135.08,136.08,137.08,138.08,139.08,140.08,68.03,68.03,78.03,78.03,145.08,146.08,147.08,148.08,149.08,150.08,151.08,152.08,153.08,82.03,82.03,78.03,78.03,158.08,159.08,160.08,161.08,162.08,163.08,164.08,165.08,166.08,82.03,82.03,78.03,78.03,171.08,172.08,173.08,174.08,175.08,176.08,177.08,178.08,179.08,82.03,82.03,92.03,92.03,93.03,93.03,93.03,94.03,94.03,94.03,95.03,95.03,95.03,96.03,96.03,92.03,92.03,93.03,93.03,93.03,94.03,94.03,94.03,95.03,95.03,95.03,96.03,96.03]) + self.assertTrue(att5.getFieldOn(att5.getMyGodFather().getMeshAtPosition((1,1)),"YY").isEqualWithoutConsideringStr(exp23,1e-12)) + exp24=DataArrayDouble([19.03,19.03,20.03,20.03,20.03,21.03,21.03,21.03,22.03,22.03,22.03,23.03,23.03,19.03,19.03,20.03,20.03,20.03,21.03,21.03,21.03,22.03,22.03,22.03,23.03,23.03,33.03,33.03,28.09,29.09,30.09,31.09,32.09,33.09,34.09,35.09,36.09,37.03,37.03,33.03,33.03,41.09,42.09,43.09,44.09,45.09,46.09,47.09,48.09,49.09,37.03,37.03,33.03,33.03,54.09,55.09,56.09,57.09,58.09,59.09,60.09,61.09,62.09,37.03,37.03,47.03,47.03,67.09,68.09,69.09,70.09,71.09,72.09,73.09,74.09,75.09,51.03,51.03,47.03,47.03,80.09,81.09,82.09,83.09,84.09,85.09,86.09,87.09,88.09,51.03,51.03,47.03,47.03,93.09,94.09,95.09,96.09,97.09,98.09,99.09,100.09,101.09,51.03,51.03,61.03,61.03,106.09,107.09,108.09,109.09,110.09,111.09,112.09,113.09,114.09,65.03,65.03,61.03,61.03,119.09,120.09,121.09,122.09,123.09,124.09,125.09,126.09,127.09,65.03,65.03,61.03,61.03,132.09,133.09,134.09,135.09,136.09,137.09,138.09,139.09,140.09,65.03,65.03,75.03,75.03,76.03,76.03,76.03,77.03,77.03,77.03,78.03,78.03,78.03,79.03,79.03,75.03,75.03,76.03,76.03,76.03,77.03,77.03,77.03,78.03,78.03,78.03,79.03,79.03]) + self.assertTrue(att5.getFieldOn(att5.getMyGodFather().getMeshAtPosition((1,2)),"YY").isEqualWithoutConsideringStr(exp24,1e-12)) + exp25=DataArrayDouble([61.03,61.03,62.03,62.03,62.03,63.03,63.03,63.03,64.03,64.03,64.03,65.03,65.03,61.03,61.03,62.03,62.03,62.03,63.03,63.03,63.03,64.03,64.03,64.03,65.03,65.03,75.03,75.03,28.1,29.1,30.1,31.1,32.1,33.1,34.1,35.1,36.1,79.03,79.03,75.03,75.03,41.1,42.1,43.1,44.1,45.1,46.1,47.1,48.1,49.1,79.03,79.03,75.03,75.03,54.1,55.1,56.1,57.1,58.1,59.1,60.1,61.1,62.1,79.03,79.03,89.03,89.03,67.1,68.1,69.1,70.1,71.1,72.1,73.1,74.1,75.1,93.03,93.03,89.03,89.03,80.1,81.1,82.1,83.1,84.1,85.1,86.1,87.1,88.1,93.03,93.03,89.03,89.03,93.1,94.1,95.1,96.1,97.1,98.1,99.1,100.1,101.1,93.03,93.03,103.03,103.03,106.1,107.1,108.1,109.1,110.1,111.1,112.1,113.1,114.1,107.03,107.03,103.03,103.03,119.1,120.1,121.1,122.1,123.1,124.1,125.1,126.1,127.1,107.03,107.03,103.03,103.03,132.1,133.1,134.1,135.1,136.1,137.1,138.1,139.1,140.1,107.03,107.03,117.03,117.03,118.03,118.03,118.03,119.03,119.03,119.03,120.03,120.03,120.03,121.03,121.03,117.03,117.03,118.03,118.03,118.03,119.03,119.03,119.03,120.03,120.03,120.03,121.03,121.03]) + self.assertTrue(att5.getFieldOn(att5.getMyGodFather().getMeshAtPosition((1,3)),"YY").isEqualWithoutConsideringStr(exp25,1e-12)) + pass + + def testSwig2AMR11(self): + """ Some tests in 3D with CondenseFineToCoarseGhost and SpreadCoarseToFineGhost""" + coarse=DataArrayDouble((6+4)*(7+4)*(5+4)) ; coarse.iota() + fine=DataArrayDouble((4*2+4)*(2*3+4)*(3*4+4)) + MEDCouplingIMesh.SpreadCoarseToFineGhost(coarse,[6,7,5],fine,[(1,5),(2,4),(1,4)],[2,3,4],2) + exp0=DataArrayDouble([252.,252.,253.,253.,254.,254.,255.,255.,256.,256.,257.,257.,252.,252.,253.,253.,254.,254.,255.,255.,256.,256.,257.,257.,262.,262.,263.,263.,264.,264.,265.,265.,266.,266.,267.,267.,262.,262.,263.,263.,264.,264.,265.,265.,266.,266.,267.,267.,262.,262.,263.,263.,264.,264.,265.,265.,266.,266.,267.,267.,272.,272.,273.,273.,274.,274.,275.,275.,276.,276.,277.,277.,272.,272.,273.,273.,274.,274.,275.,275.,276.,276.,277.,277.,272.,272.,273.,273.,274.,274.,275.,275.,276.,276.,277.,277.,282.,282.,283.,283.,284.,284.,285.,285.,286.,286.,287.,287.,282.,282.,283.,283.,284.,284.,285.,285.,286.,286.,287.,287.]) + exp1=DataArrayDouble([362.,362.,363.,363.,364.,364.,365.,365.,366.,366.,367.,367.,362.,362.,363.,363.,364.,364.,365.,365.,366.,366.,367.,367.,372.,372.,373.,373.,374.,374.,375.,375.,376.,376.,377.,377.,372.,372.,373.,373.,374.,374.,375.,375.,376.,376.,377.,377.,372.,372.,373.,373.,374.,374.,375.,375.,376.,376.,377.,377.,382.,382.,383.,383.,384.,384.,385.,385.,386.,386.,387.,387.,382.,382.,383.,383.,384.,384.,385.,385.,386.,386.,387.,387.,382.,382.,383.,383.,384.,384.,385.,385.,386.,386.,387.,387.,392.,392.,393.,393.,394.,394.,395.,395.,396.,396.,397.,397.,392.,392.,393.,393.,394.,394.,395.,395.,396.,396.,397.,397.]) + exp2=DataArrayDouble([472.,472.,473.,473.,474.,474.,475.,475.,476.,476.,477.,477.,472.,472.,473.,473.,474.,474.,475.,475.,476.,476.,477.,477.,482.,482.,483.,483.,484.,484.,485.,485.,486.,486.,487.,487.,482.,482.,483.,483.,484.,484.,485.,485.,486.,486.,487.,487.,482.,482.,483.,483.,484.,484.,485.,485.,486.,486.,487.,487.,492.,492.,493.,493.,494.,494.,495.,495.,496.,496.,497.,497.,492.,492.,493.,493.,494.,494.,495.,495.,496.,496.,497.,497.,492.,492.,493.,493.,494.,494.,495.,495.,496.,496.,497.,497.,502.,502.,503.,503.,504.,504.,505.,505.,506.,506.,507.,507.,502.,502.,503.,503.,504.,504.,505.,505.,506.,506.,507.,507.]) + exp3=DataArrayDouble([582.,582.,583.,583.,584.,584.,585.,585.,586.,586.,587.,587.,582.,582.,583.,583.,584.,584.,585.,585.,586.,586.,587.,587.,592.,592.,593.,593.,594.,594.,595.,595.,596.,596.,597.,597.,592.,592.,593.,593.,594.,594.,595.,595.,596.,596.,597.,597.,592.,592.,593.,593.,594.,594.,595.,595.,596.,596.,597.,597.,602.,602.,603.,603.,604.,604.,605.,605.,606.,606.,607.,607.,602.,602.,603.,603.,604.,604.,605.,605.,606.,606.,607.,607.,602.,602.,603.,603.,604.,604.,605.,605.,606.,606.,607.,607.,612.,612.,613.,613.,614.,614.,615.,615.,616.,616.,617.,617.,612.,612.,613.,613.,614.,614.,615.,615.,616.,616.,617.,617.]) + exp4=DataArrayDouble([692.,692.,693.,693.,694.,694.,695.,695.,696.,696.,697.,697.,692.,692.,693.,693.,694.,694.,695.,695.,696.,696.,697.,697.,702.,702.,703.,703.,704.,704.,705.,705.,706.,706.,707.,707.,702.,702.,703.,703.,704.,704.,705.,705.,706.,706.,707.,707.,702.,702.,703.,703.,704.,704.,705.,705.,706.,706.,707.,707.,712.,712.,713.,713.,714.,714.,715.,715.,716.,716.,717.,717.,712.,712.,713.,713.,714.,714.,715.,715.,716.,716.,717.,717.,712.,712.,713.,713.,714.,714.,715.,715.,716.,716.,717.,717.,722.,722.,723.,723.,724.,724.,725.,725.,726.,726.,727.,727.,722.,722.,723.,723.,724.,724.,725.,725.,726.,726.,727.,727.]) + exp=DataArrayDouble.Aggregate([exp0,exp0,exp1,exp1,exp1,exp1,exp2,exp2,exp2,exp2,exp3,exp3,exp3,exp3,exp4,exp4]) + self.assertTrue(fine.isEqual(exp,1e-12)) + # + fine.iota() + coarse.iota(0.5) + MEDCouplingIMesh.CondenseFineToCoarseGhost([6,7,5],fine,[(1,5),(2,4),(1,4)],[2,3,4],coarse,2) + amr=MEDCouplingCartesianAMRMesh("mesh",3,[7,8,6],[0.,0.,0.],[1.,1.,1.]) + amr.addPatch([(1,5),(2,4),(1,4)],[2,3,4]) + att=MEDCouplingAMRAttribute(amr,[("YY",1)],2) + att.alloc() + exp1=DataArrayDouble(990) ; exp1.iota(0.5) + ids=DataArrayInt([373,374,375,376,383,384,385,386,483,484,485,486,493,494,495,496,593,594,595,596,603,604,605,606]) + vals=DataArrayDouble([11004.,11052.,11100.,11148.,11868.,11916.,11964.,12012.,22524.,22572.,22620.,22668.,23388.,23436.,23484.,23532.,34044.,34092.,34140.,34188.,34908.,34956.,35004.,35052.]) + exp1[ids]=vals + self.assertTrue(coarse.isEqual(exp1,1e-12)) + # + MEDCouplingStructuredMesh.MultiplyPartOf([10,11,9],[(3,7),(4,6),(3,6)],1/24.,coarse) + exp2=DataArrayDouble(990) ; exp2.iota(0.5) + exp2[ids]=vals/24. + self.assertTrue(coarse.isEqual(exp2,1e-12)) + # + coarse.iota(0.5) ; fine.iota(0.1) + MEDCouplingIMesh.SpreadCoarseToFineGhostZone(coarse,[6,7,5],fine,[(1,5),(2,4),(1,4)],[2,3,4],2) + # + coarse.iota(0.5) ; fine.iota(0.1) + MEDCouplingIMesh.SpreadCoarseToFineGhostZone(coarse,[6,7,5],fine,[(1,5),(2,4),(1,4)],[2,3,4],2) + exp00=DataArrayDouble.Aggregate([exp0,exp0]) ; exp00+=0.5 + self.assertTrue(fine[:240].isEqual(exp00,1e-12)) + exp44=DataArrayDouble.Aggregate([exp4,exp4]) ; exp44+=0.5 + self.assertTrue(fine[-240:].isEqual(exp44,1e-12)) + self.assertTrue(fine[240:-240].isEqual(DataArrayDouble([362.5,362.5,363.5,363.5,364.5,364.5,365.5,365.5,366.5,366.5,367.5,367.5,362.5,362.5,363.5,363.5,364.5,364.5,365.5,365.5,366.5,366.5,367.5,367.5,372.5,372.5,266.1,267.1,268.1,269.1,270.1,271.1,272.1,273.1,377.5,377.5,372.5,372.5,278.1,279.1,280.1,281.1,282.1,283.1,284.1,285.1,377.5,377.5,372.5,372.5,290.1,291.1,292.1,293.1,294.1,295.1,296.1,297.1,377.5,377.5,382.5,382.5,302.1,303.1,304.1,305.1,306.1,307.1,308.1,309.1,387.5,387.5,382.5,382.5,314.1,315.1,316.1,317.1,318.1,319.1,320.1,321.1,387.5,387.5,382.5,382.5,326.1,327.1,328.1,329.1,330.1,331.1,332.1,333.1,387.5,387.5,392.5,392.5,393.5,393.5,394.5,394.5,395.5,395.5,396.5,396.5,397.5,397.5,392.5,392.5,393.5,393.5,394.5,394.5,395.5,395.5,396.5,396.5,397.5,397.5,362.5,362.5,363.5,363.5,364.5,364.5,365.5,365.5,366.5,366.5,367.5,367.5,362.5,362.5,363.5,363.5,364.5,364.5,365.5,365.5,366.5,366.5,367.5,367.5,372.5,372.5,386.1,387.1,388.1,389.1,390.1,391.1,392.1,393.1,377.5,377.5,372.5,372.5,398.1,399.1,400.1,401.1,402.1,403.1,404.1,405.1,377.5,377.5,372.5,372.5,410.1,411.1,412.1,413.1,414.1,415.1,416.1,417.1,377.5,377.5,382.5,382.5,422.1,423.1,424.1,425.1,426.1,427.1,428.1,429.1,387.5,387.5,382.5,382.5,434.1,435.1,436.1,437.1,438.1,439.1,440.1,441.1,387.5,387.5,382.5,382.5,446.1,447.1,448.1,449.1,450.1,451.1,452.1,453.1,387.5,387.5,392.5,392.5,393.5,393.5,394.5,394.5,395.5,395.5,396.5,396.5,397.5,397.5,392.5,392.5,393.5,393.5,394.5,394.5,395.5,395.5,396.5,396.5,397.5,397.5,362.5,362.5,363.5,363.5,364.5,364.5,365.5,365.5,366.5,366.5,367.5,367.5,362.5,362.5,363.5,363.5,364.5,364.5,365.5,365.5,366.5,366.5,367.5,367.5,372.5,372.5,506.1,507.1,508.1,509.1,510.1,511.1,512.1,513.1,377.5,377.5,372.5,372.5,518.1,519.1,520.1,521.1,522.1,523.1,524.1,525.1,377.5,377.5,372.5,372.5,530.1,531.1,532.1,533.1,534.1,535.1,536.1,537.1,377.5,377.5,382.5,382.5,542.1,543.1,544.1,545.1,546.1,547.1,548.1,549.1,387.5,387.5,382.5,382.5,554.1,555.1,556.1,557.1,558.1,559.1,560.1,561.1,387.5,387.5,382.5,382.5,566.1,567.1,568.1,569.1,570.1,571.1,572.1,573.1,387.5,387.5,392.5,392.5,393.5,393.5,394.5,394.5,395.5,395.5,396.5,396.5,397.5,397.5,392.5,392.5,393.5,393.5,394.5,394.5,395.5,395.5,396.5,396.5,397.5,397.5,362.5,362.5,363.5,363.5,364.5,364.5,365.5,365.5,366.5,366.5,367.5,367.5,362.5,362.5,363.5,363.5,364.5,364.5,365.5,365.5,366.5,366.5,367.5,367.5,372.5,372.5,626.1,627.1,628.1,629.1,630.1,631.1,632.1,633.1,377.5,377.5,372.5,372.5,638.1,639.1,640.1,641.1,642.1,643.1,644.1,645.1,377.5,377.5,372.5,372.5,650.1,651.1,652.1,653.1,654.1,655.1,656.1,657.1,377.5,377.5,382.5,382.5,662.1,663.1,664.1,665.1,666.1,667.1,668.1,669.1,387.5,387.5,382.5,382.5,674.1,675.1,676.1,677.1,678.1,679.1,680.1,681.1,387.5,387.5,382.5,382.5,686.1,687.1,688.1,689.1,690.1,691.1,692.1,693.1,387.5,387.5,392.5,392.5,393.5,393.5,394.5,394.5,395.5,395.5,396.5,396.5,397.5,397.5,392.5,392.5,393.5,393.5,394.5,394.5,395.5,395.5,396.5,396.5,397.5,397.5,472.5,472.5,473.5,473.5,474.5,474.5,475.5,475.5,476.5,476.5,477.5,477.5,472.5,472.5,473.5,473.5,474.5,474.5,475.5,475.5,476.5,476.5,477.5,477.5,482.5,482.5,746.1,747.1,748.1,749.1,750.1,751.1,752.1,753.1,487.5,487.5,482.5,482.5,758.1,759.1,760.1,761.1,762.1,763.1,764.1,765.1,487.5,487.5,482.5,482.5,770.1,771.1,772.1,773.1,774.1,775.1,776.1,777.1,487.5,487.5,492.5,492.5,782.1,783.1,784.1,785.1,786.1,787.1,788.1,789.1,497.5,497.5,492.5,492.5,794.1,795.1,796.1,797.1,798.1,799.1,800.1,801.1,497.5,497.5,492.5,492.5,806.1,807.1,808.1,809.1,810.1,811.1,812.1,813.1,497.5,497.5,502.5,502.5,503.5,503.5,504.5,504.5,505.5,505.5,506.5,506.5,507.5,507.5,502.5,502.5,503.5,503.5,504.5,504.5,505.5,505.5,506.5,506.5,507.5,507.5,472.5,472.5,473.5,473.5,474.5,474.5,475.5,475.5,476.5,476.5,477.5,477.5,472.5,472.5,473.5,473.5,474.5,474.5,475.5,475.5,476.5,476.5,477.5,477.5,482.5,482.5,866.1,867.1,868.1,869.1,870.1,871.1,872.1,873.1,487.5,487.5,482.5,482.5,878.1,879.1,880.1,881.1,882.1,883.1,884.1,885.1,487.5,487.5,482.5,482.5,890.1,891.1,892.1,893.1,894.1,895.1,896.1,897.1,487.5,487.5,492.5,492.5,902.1,903.1,904.1,905.1,906.1,907.1,908.1,909.1,497.5,497.5,492.5,492.5,914.1,915.1,916.1,917.1,918.1,919.1,920.1,921.1,497.5,497.5,492.5,492.5,926.1,927.1,928.1,929.1,930.1,931.1,932.1,933.1,497.5,497.5,502.5,502.5,503.5,503.5,504.5,504.5,505.5,505.5,506.5,506.5,507.5,507.5,502.5,502.5,503.5,503.5,504.5,504.5,505.5,505.5,506.5,506.5,507.5,507.5,472.5,472.5,473.5,473.5,474.5,474.5,475.5,475.5,476.5,476.5,477.5,477.5,472.5,472.5,473.5,473.5,474.5,474.5,475.5,475.5,476.5,476.5,477.5,477.5,482.5,482.5,986.1,987.1,988.1,989.1,990.1,991.1,992.1,993.1,487.5,487.5,482.5,482.5,998.1,999.1,1000.1,1001.1,1002.1,1003.1,1004.1,1005.1,487.5,487.5,482.5,482.5,1010.1,1011.1,1012.1,1013.1,1014.1,1015.1,1016.1,1017.1,487.5,487.5,492.5,492.5,1022.1,1023.1,1024.1,1025.1,1026.1,1027.1,1028.1,1029.1,497.5,497.5,492.5,492.5,1034.1,1035.1,1036.1,1037.1,1038.1,1039.1,1040.1,1041.1,497.5,497.5,492.5,492.5,1046.1,1047.1,1048.1,1049.1,1050.1,1051.1,1052.1,1053.1,497.5,497.5,502.5,502.5,503.5,503.5,504.5,504.5,505.5,505.5,506.5,506.5,507.5,507.5,502.5,502.5,503.5,503.5,504.5,504.5,505.5,505.5,506.5,506.5,507.5,507.5,472.5,472.5,473.5,473.5,474.5,474.5,475.5,475.5,476.5,476.5,477.5,477.5,472.5,472.5,473.5,473.5,474.5,474.5,475.5,475.5,476.5,476.5,477.5,477.5,482.5,482.5,1106.1,1107.1,1108.1,1109.1,1110.1,1111.1,1112.1,1113.1,487.5,487.5,482.5,482.5,1118.1,1119.1,1120.1,1121.1,1122.1,1123.1,1124.1,1125.1,487.5,487.5,482.5,482.5,1130.1,1131.1,1132.1,1133.1,1134.1,1135.1,1136.1,1137.1,487.5,487.5,492.5,492.5,1142.1,1143.1,1144.1,1145.1,1146.1,1147.1,1148.1,1149.1,497.5,497.5,492.5,492.5,1154.1,1155.1,1156.1,1157.1,1158.1,1159.1,1160.1,1161.1,497.5,497.5,492.5,492.5,1166.1,1167.1,1168.1,1169.1,1170.1,1171.1,1172.1,1173.1,497.5,497.5,502.5,502.5,503.5,503.5,504.5,504.5,505.5,505.5,506.5,506.5,507.5,507.5,502.5,502.5,503.5,503.5,504.5,504.5,505.5,505.5,506.5,506.5,507.5,507.5,582.5,582.5,583.5,583.5,584.5,584.5,585.5,585.5,586.5,586.5,587.5,587.5,582.5,582.5,583.5,583.5,584.5,584.5,585.5,585.5,586.5,586.5,587.5,587.5,592.5,592.5,1226.1,1227.1,1228.1,1229.1,1230.1,1231.1,1232.1,1233.1,597.5,597.5,592.5,592.5,1238.1,1239.1,1240.1,1241.1,1242.1,1243.1,1244.1,1245.1,597.5,597.5,592.5,592.5,1250.1,1251.1,1252.1,1253.1,1254.1,1255.1,1256.1,1257.1,597.5,597.5,602.5,602.5,1262.1,1263.1,1264.1,1265.1,1266.1,1267.1,1268.1,1269.1,607.5,607.5,602.5,602.5,1274.1,1275.1,1276.1,1277.1,1278.1,1279.1,1280.1,1281.1,607.5,607.5,602.5,602.5,1286.1,1287.1,1288.1,1289.1,1290.1,1291.1,1292.1,1293.1,607.5,607.5,612.5,612.5,613.5,613.5,614.5,614.5,615.5,615.5,616.5,616.5,617.5,617.5,612.5,612.5,613.5,613.5,614.5,614.5,615.5,615.5,616.5,616.5,617.5,617.5,582.5,582.5,583.5,583.5,584.5,584.5,585.5,585.5,586.5,586.5,587.5,587.5,582.5,582.5,583.5,583.5,584.5,584.5,585.5,585.5,586.5,586.5,587.5,587.5,592.5,592.5,1346.1,1347.1,1348.1,1349.1,1350.1,1351.1,1352.1,1353.1,597.5,597.5,592.5,592.5,1358.1,1359.1,1360.1,1361.1,1362.1,1363.1,1364.1,1365.1,597.5,597.5,592.5,592.5,1370.1,1371.1,1372.1,1373.1,1374.1,1375.1,1376.1,1377.1,597.5,597.5,602.5,602.5,1382.1,1383.1,1384.1,1385.1,1386.1,1387.1,1388.1,1389.1,607.5,607.5,602.5,602.5,1394.1,1395.1,1396.1,1397.1,1398.1,1399.1,1400.1,1401.1,607.5,607.5,602.5,602.5,1406.1,1407.1,1408.1,1409.1,1410.1,1411.1,1412.1,1413.1,607.5,607.5,612.5,612.5,613.5,613.5,614.5,614.5,615.5,615.5,616.5,616.5,617.5,617.5,612.5,612.5,613.5,613.5,614.5,614.5,615.5,615.5,616.5,616.5,617.5,617.5,582.5,582.5,583.5,583.5,584.5,584.5,585.5,585.5,586.5,586.5,587.5,587.5,582.5,582.5,583.5,583.5,584.5,584.5,585.5,585.5,586.5,586.5,587.5,587.5,592.5,592.5,1466.1,1467.1,1468.1,1469.1,1470.1,1471.1,1472.1,1473.1,597.5,597.5,592.5,592.5,1478.1,1479.1,1480.1,1481.1,1482.1,1483.1,1484.1,1485.1,597.5,597.5,592.5,592.5,1490.1,1491.1,1492.1,1493.1,1494.1,1495.1,1496.1,1497.1,597.5,597.5,602.5,602.5,1502.1,1503.1,1504.1,1505.1,1506.1,1507.1,1508.1,1509.1,607.5,607.5,602.5,602.5,1514.1,1515.1,1516.1,1517.1,1518.1,1519.1,1520.1,1521.1,607.5,607.5,602.5,602.5,1526.1,1527.1,1528.1,1529.1,1530.1,1531.1,1532.1,1533.1,607.5,607.5,612.5,612.5,613.5,613.5,614.5,614.5,615.5,615.5,616.5,616.5,617.5,617.5,612.5,612.5,613.5,613.5,614.5,614.5,615.5,615.5,616.5,616.5,617.5,617.5,582.5,582.5,583.5,583.5,584.5,584.5,585.5,585.5,586.5,586.5,587.5,587.5,582.5,582.5,583.5,583.5,584.5,584.5,585.5,585.5,586.5,586.5,587.5,587.5,592.5,592.5,1586.1,1587.1,1588.1,1589.1,1590.1,1591.1,1592.1,1593.1,597.5,597.5,592.5,592.5,1598.1,1599.1,1600.1,1601.1,1602.1,1603.1,1604.1,1605.1,597.5,597.5,592.5,592.5,1610.1,1611.1,1612.1,1613.1,1614.1,1615.1,1616.1,1617.1,597.5,597.5,602.5,602.5,1622.1,1623.1,1624.1,1625.1,1626.1,1627.1,1628.1,1629.1,607.5,607.5,602.5,602.5,1634.1,1635.1,1636.1,1637.1,1638.1,1639.1,1640.1,1641.1,607.5,607.5,602.5,602.5,1646.1,1647.1,1648.1,1649.1,1650.1,1651.1,1652.1,1653.1,607.5,607.5,612.5,612.5,613.5,613.5,614.5,614.5,615.5,615.5,616.5,616.5,617.5,617.5,612.5,612.5,613.5,613.5,614.5,614.5,615.5,615.5,616.5,616.5,617.5,617.5]),1e-12)) + pass + + def testSwig2AMR12(self): + """ This test check the MEDCouplingAMRAttribute.projectTo method.""" + amr0=MEDCouplingCartesianAMRMesh("mesh",2,[11,11],[0.,0.],[1.,1.]) + amr0.addPatch([(3,8),(0,3)],[2,2]) + amr0.addPatch([(3,8),(3,6)],[2,2]) + att0=MEDCouplingAMRAttribute(amr0,[("YY",1)],2) + att0.alloc() + att0.getFieldOn(amr0,"YY").iota(0.01) + att0.getFieldOn(amr0[0].getMesh(),"YY").iota(0.02) + att0.getFieldOn(amr0[1].getMesh(),"YY").iota(0.03) + amr1=MEDCouplingCartesianAMRMesh("mesh",2,[11,11],[0.,0.],[1.,1.]) + amr1.addPatch([(2,5),(1,4)],[2,2]) + att1=att0.projectTo(amr1) + self.assertTrue(att1.getFieldOn(amr1,"YY").isEqualWithoutConsideringStr(att0.getFieldOn(amr0,"YY"),1e-12)) + self.assertTrue(att1.getFieldOn(amr1[0].getMesh(),"YY").isEqualWithoutConsideringStr(DataArrayDouble([31.01,31.01,32.01,32.01,33.01,33.01,34.01,34.01,35.01,35.01,31.01,31.01,32.01,32.01,33.01,33.01,34.01,34.01,35.01,35.01,45.01,45.01,46.01,46.01,58.02,59.02,60.02,61.02,49.01,49.01,45.01,45.01,46.01,46.01,72.02,73.02,74.02,75.02,49.01,49.01,59.01,59.01,60.01,60.01,86.02,87.02,88.02,89.02,63.01,63.01,59.01,59.01,60.01,60.01,100.02,101.02,102.02,103.02,63.01,63.01,73.01,73.01,74.01,74.01,30.03,31.03,32.03,33.03,77.01,77.01,73.01,73.01,74.01,74.01,44.03,45.03,46.03,47.03,77.01,77.01,87.01,87.01,88.01,88.01,89.01,89.01,90.01,90.01,91.01,91.01,87.01,87.01,88.01,88.01,89.01,89.01,90.01,90.01,91.01,91.01]),1e-12)) + # + amr0=MEDCouplingCartesianAMRMesh("mesh",2,[11,11],[0.,0.],[1.,1.]) + amr0.addPatch([(2,5),(2,7)],[2,2]) + amr0.addPatch([(5,8),(2,7)],[2,2]) + att0=MEDCouplingAMRAttribute(amr0,[("YY",1)],2) + att0.alloc() + att0.getFieldOn(amr0,"YY").iota(0.01) + att0.getFieldOn(amr0[0].getMesh(),"YY").iota(0.02) + att0.getFieldOn(amr0[1].getMesh(),"YY").iota(0.03) + amr1=MEDCouplingCartesianAMRMesh("mesh",2,[11,11],[0.,0.],[1.,1.]) + amr1.addPatch([(3,6),(2,7)],[2,2]) + amr1.addPatch([(6,9),(2,7)],[2,2]) + att1=att0.projectTo(amr1) + self.assertTrue(att1.getFieldOn(amr1,"YY").isEqual(att0.getFieldOn(amr0,"YY"),1e-12)) + self.assertTrue(att1.getFieldOn(amr1[0].getMesh(),"YY").isEqualWithoutConsideringStr(DataArrayDouble([46.01,46.01,47.01,47.01,48.01,48.01,49.01,49.01,50.01,50.01,46.01,46.01,47.01,47.01,48.01,48.01,49.01,49.01,50.01,50.01,60.01,60.01,24.02,25.02,26.02,27.02,22.03,23.03,64.01,64.01,60.01,60.01,34.02,35.02,36.02,37.02,32.03,33.03,64.01,64.01,74.01,74.01,44.02,45.02,46.02,47.02,42.03,43.03,78.01,78.01,74.01,74.01,54.02,55.02,56.02,57.02,52.03,53.03,78.01,78.01,88.01,88.01,64.02,65.02,66.02,67.02,62.03,63.03,92.01,92.01,88.01,88.01,74.02,75.02,76.02,77.02,72.03,73.03,92.01,92.01,102.01,102.01,84.02,85.02,86.02,87.02,82.03,83.03,106.01,106.01,102.01,102.01,94.02,95.02,96.02,97.02,92.03,93.03,106.01,106.01,116.01,116.01,104.02,105.02,106.02,107.02,102.03,103.03,120.01,120.01,116.01,116.01,114.02,115.02,116.02,117.02,112.03,113.03,120.01,120.01,130.01,130.01,131.01,131.01,132.01,132.01,133.01,133.01,134.01,134.01,130.01,130.01,131.01,131.01,132.01,132.01,133.01,133.01,134.01,134.01]),1e-12)) + self.assertTrue(att1.getFieldOn(amr1[1].getMesh(),"YY").isEqualWithoutConsideringStr(DataArrayDouble([49.01,49.01,50.01,50.01,51.01,51.01,52.01,52.01,53.01,53.01,49.01,49.01,50.01,50.01,51.01,51.01,52.01,52.01,53.01,53.01,63.01,63.01,24.03,25.03,26.03,27.03,66.01,66.01,67.01,67.01,63.01,63.01,34.03,35.03,36.03,37.03,66.01,66.01,67.01,67.01,77.01,77.01,44.03,45.03,46.03,47.03,80.01,80.01,81.01,81.01,77.01,77.01,54.03,55.03,56.03,57.03,80.01,80.01,81.01,81.01,91.01,91.01,64.03,65.03,66.03,67.03,94.01,94.01,95.01,95.01,91.01,91.01,74.03,75.03,76.03,77.03,94.01,94.01,95.01,95.01,105.01,105.01,84.03,85.03,86.03,87.03,108.01,108.01,109.01,109.01,105.01,105.01,94.03,95.03,96.03,97.03,108.01,108.01,109.01,109.01,119.01,119.01,104.03,105.03,106.03,107.03,122.01,122.01,123.01,123.01,119.01,119.01,114.03,115.03,116.03,117.03,122.01,122.01,123.01,123.01,133.01,133.01,134.01,134.01,135.01,135.01,136.01,136.01,137.01,137.01,133.01,133.01,134.01,134.01,135.01,135.01,136.01,136.01,137.01,137.01]),1e-12)) + pass + + def testSwig2AMR13(self): + """ non regression test""" + for fact,len1,len2 in [([2,2],64,48),([3,3],100,70),([4,4],144,96)]: + amr=MEDCouplingCartesianAMRMesh("mesh",2,[5,5],[0.,0.],[1.,1.]) + amr.addPatch([(1,3),(0,2)],fact) + amr.addPatch([(1,3),(3,4)],fact) + att=MEDCouplingAMRAttribute(amr,[("YY",1)],2) + att.alloc() + att.getFieldOn(amr,"YY").iota(0.1) + att.getFieldOn(amr[0].getMesh(),"YY").iota(0.2) + att.getFieldOn(amr[1].getMesh(),"YY").iota(0.3) + att.synchronizeAllGhostZonesOfDirectChidrenOf(amr) + exp=DataArrayDouble(64) ; exp.iota(0.1) + self.assertTrue(att.getFieldOn(amr,"YY").isEqualWithoutConsideringStr(exp,1e-12)) + exp0=DataArrayDouble(len1) ; exp0.iota(0.2) + self.assertTrue(att.getFieldOn(amr[0].getMesh(),"YY").isEqualWithoutConsideringStr(exp0,1e-12)) + exp1=DataArrayDouble(len2) ; exp1.iota(0.3) + self.assertTrue(att.getFieldOn(amr[1].getMesh(),"YY").isEqualWithoutConsideringStr(exp1,1e-12)) + pass + pass + + def testSwig2AMR14(self): + """ non regression linked to VTHB write.""" + fact=[2,2] ; fact2=[3,3] + amr=MEDCouplingCartesianAMRMesh("mesh",2,[5,5],[0.,0.],[1.,1.]) + amr.addPatch([(1,3),(0,2)],fact) + amr.addPatch([(1,3),(3,4)],fact) + amr[0].addPatch([(1,3),(1,3)],fact2) + amr[1].addPatch([(1,3),(1,2)],fact2) + att=MEDCouplingAMRAttribute(amr,[("YY",1)],2) + att.alloc() + att.getFieldOn(amr,"YY").iota(0.1) + att.getFieldOn(amr[0].getMesh(),"YY").iota(0.2) + att.getFieldOn(amr[1].getMesh(),"YY").iota(0.3) + att.getFieldOn(amr[0][0].getMesh(),"YY").iota(0.4) + att.getFieldOn(amr[1][0].getMesh(),"YY").iota(0.5) + self.assertEqual(amr[0].getBLTRRangeRelativeToGF(),[(2,6),(0,4)]) + self.assertEqual(amr[1].getBLTRRangeRelativeToGF(),[(2,6),(6,8)]) + self.assertEqual(amr[0][0].getBLTRRangeRelativeToGF(),[(9,15),(3,9)]) + self.assertEqual(amr[1][0].getBLTRRangeRelativeToGF(),[(9,15),(21,24)]) + pass + + def testSwig2Intersect2DMeshWith1DLine1(self): + """A basic test with no colinearity between m1 and m2.""" + i=MEDCouplingIMesh("mesh",2,[5,5],[0.,0.],[1.,1.]) + m1=i.buildUnstructured() + m2=MEDCouplingUMesh("mesh",1) ; m2.setCoords(DataArrayDouble([0.75,3.5,3.75,1.75],2,2)) ; m2.allocateCells() ; m2.insertNextCell(NORM_SEG2,[0,1]) + a,b,c,d=MEDCouplingUMesh.Intersect2DMeshWith1DLine(m1,m2,1e-12) + self.assertTrue(a.getNodalConnectivity().isEqual(DataArrayInt([4,1,0,5,6,4,2,1,6,7,4,3,2,7,8,4,4,3,8,9,4,6,5,10,11,4,7,6,11,12,4,8,7,12,13,4,11,10,15,16,4,18,17,22,23,4,19,18,23,24,5,16,15,20,21,31,5,21,22,17,28,31,5,16,31,28,5,17,29,28,5,12,11,16,28,29,5,17,18,30,29,5,13,12,29,30,5,18,19,14,27,30,5,13,30,27,5,9,8,13,27,14]))) + self.assertTrue(b.getNodalConnectivity().isEqual(DataArrayInt([1,25,31,1,31,28,1,28,29,1,29,30,1,30,27,1,27,26]))) + self.assertTrue(a.getNodalConnectivityIndex().isEqual(DataArrayInt([0,5,10,15,20,25,30,35,40,45,50,56,62,66,70,76,81,86,92,96,102]))) + self.assertTrue(b.getNodalConnectivityIndex().isEqual(DataArrayInt([0,3,6,9,12,15,18]))) + self.assertTrue(a.getCoords().getHiddenCppPointer()==b.getCoords().getHiddenCppPointer()) + self.assertTrue(a.getCoords()[:25].isEqual(m1.getCoords(),1e-12)) + self.assertTrue(a.getCoords()[25:25+2].isEqualWithoutConsideringStr(m2.getCoords(),1e-12)) + self.assertTrue(a.getCoords()[27:].isEqualWithoutConsideringStr(DataArrayDouble([(3.3214285714285716,2.),(1.6071428571428572,3.),(2.,2.7708333333333335),(3.,2.1875),(1.,3.354166666666667)]),1e-12)) + self.assertTrue(c.isEqual(DataArrayInt([0,1,2,3,4,5,6,8,14,15,12,13,13,9,9,10,10,11,11,7]))) + self.assertTrue(d.isEqual(DataArrayInt([(10,10),(11,12),(13,14),(15,16),(17,18),(19,19)]))) + pass + + def testSwig2Intersect2DMeshWith1DLine2(self): + """A basic test with colinearity between m1 and m2 and the last cell of m2 outside m1.""" + i=MEDCouplingIMesh("mesh",2,[5,5],[0.,0.],[1.,1.]) + m1=i.buildUnstructured() + m2=MEDCouplingUMesh("mesh",1) ; m2.setCoords(DataArrayDouble([0.5,2.,2.25,2.,2.5,2.,2.75,2.,3.,2.,4.,2.,5.,2.],7,2)) ; m2.allocateCells() + for i in xrange(6): + m2.insertNextCell(NORM_SEG2,[i,i+1]) + pass + a,b,c,d=MEDCouplingUMesh.Intersect2DMeshWith1DLine(m1,m2,1e-12) + self.assertTrue(a.getNodalConnectivity().isEqual(DataArrayInt([4,1,0,5,6,4,2,1,6,7,4,3,2,7,8,4,4,3,8,9,4,16,15,20,21,4,17,16,21,22,4,18,17,22,23,4,19,18,23,24,5,6,5,10,25,11,5,7,6,11,12,5,8,7,12,26,27,28,13,5,9,8,13,14,5,11,25,10,15,16,5,12,11,16,17,5,13,28,27,26,12,17,18,5,14,13,18,19]))) + self.assertTrue(a.getNodalConnectivityIndex().isEqual(DataArrayInt([0,5,10,15,20,25,30,35,40,46,51,59,64,70,75,83,88]))) + self.assertTrue(b.getNodalConnectivity().isEqual(DataArrayInt([1,25,11,1,11,12,1,12,26,1,26,27,1,27,28,1,28,13,1,13,14,1,14,31]))) + self.assertTrue(b.getNodalConnectivityIndex().isEqual(DataArrayInt([0,3,6,9,12,15,18,21,24]))) + self.assertTrue(a.getCoords().getHiddenCppPointer()==b.getCoords().getHiddenCppPointer()) + self.assertTrue(a.getCoords()[:25].isEqual(m1.getCoords(),1e-12)) + self.assertTrue(a.getCoords()[25:].isEqualWithoutConsideringStr(m2.getCoords(),1e-12)) + self.assertTrue(c.isEqual(DataArrayInt([0,1,2,3,12,13,14,15,4,5,6,7,8,9,10,11]))) + self.assertTrue(d.isEqual(DataArrayInt([(12,8),(13,9),(14,10),(14,10),(14,10),(14,10),(15,11),(-1,-1)]))) + pass + + def testSwig2Intersect2DMeshWith1DLine3(self): + """m2 fully included in cell #12. of m1""" + i=MEDCouplingIMesh("mesh",2,[5,5],[0.,0.],[1.,1.]) + m1=i.buildUnstructured() + m2=MEDCouplingUMesh("mesh",1) ; m2.setCoords(DataArrayDouble([(0.75,3.25),(0.5,3.5),(0.25,3.25)])) ; m2.allocateCells() + for i in xrange(2): + m2.insertNextCell(NORM_SEG2,[i,i+1]) + pass + a,b,c,d=MEDCouplingUMesh.Intersect2DMeshWith1DLine(m1,m2,1e-12) + self.assertTrue(a.getNodalConnectivity().isEqual(DataArrayInt([4,1,0,5,6,4,2,1,6,7,4,3,2,7,8,4,4,3,8,9,4,6,5,10,11,4,7,6,11,12,4,8,7,12,13,4,9,8,13,14,4,11,10,15,16,4,12,11,16,17,4,13,12,17,18,4,14,13,18,19,4,17,16,21,22,4,18,17,22,23,4,19,18,23,24,5,16,15,20,21]))) + self.assertTrue(a.getNodalConnectivityIndex().isEqual(DataArrayInt([0,5,10,15,20,25,30,35,40,45,50,55,60,65,70,75,80]))) + self.assertTrue(b.getNodalConnectivity().isEqual(DataArrayInt([1,25,26,1,26,27]))) + self.assertTrue(b.getNodalConnectivityIndex().isEqual(DataArrayInt([0,3,6]))) + self.assertTrue(a.getCoords().getHiddenCppPointer()==b.getCoords().getHiddenCppPointer()) + self.assertTrue(a.getCoords()[:25].isEqual(m1.getCoords(),1e-12)) + self.assertTrue(a.getCoords()[25:].isEqualWithoutConsideringStr(m2.getCoords(),1e-12)) + self.assertTrue(c.isEqual(DataArrayInt([0,1,2,3,4,5,6,7,8,9,10,11,13,14,15,12]))) + self.assertTrue(d.isEqual(DataArrayInt([(15,15),(15,15)]))) + pass + + def testSwig2Intersect2DMeshWith1DLine4(self): + """A special case where an edge is simultaneously a cut and colinear. This tests also checks negative values in descending edges of m1.""" + i=MEDCouplingIMesh("mesh",2,[5,5],[0.,0.],[1.,1.]) + m1=i.buildUnstructured() + part=DataArrayInt([0,1,2,3,4,7,8,11,12,13,14,15]) + m1_1=m1[part] + m1_2=m1[part.buildComplement(m1.getNumberOfCells())] + m1=MEDCouplingUMesh.MergeUMeshesOnSameCoords(m1_1,m1_2.buildSpreadZonesWithPoly()) + m1.zipCoords() + m2=MEDCouplingUMesh("mesh",1) ; m2.setCoords(DataArrayDouble([(3.5,2.),(0.5,2.)])) ; m2.allocateCells() + m2.insertNextCell(NORM_SEG2,[0,1]) + a,b,c,d=MEDCouplingUMesh.Intersect2DMeshWith1DLine(m1,m2,1e-12) + self.assertTrue(a.getNodalConnectivity().isEqual(DataArrayInt([4,1,0,5,6,4,2,1,6,7,4,3,2,7,8,4,4,3,8,9,4,15,14,19,20,4,16,15,20,21,4,17,16,21,22,4,18,17,22,23,5,6,5,10,25,11,5,9,8,12,24,13,5,11,25,10,14,15,5,13,24,12,17,18,5,8,7,6,11,12,5,15,16,17,12,11]))) + self.assertTrue(a.getNodalConnectivityIndex().isEqual(DataArrayInt([0,5,10,15,20,25,30,35,40,46,52,58,64,70,76]))) + self.assertTrue(b.getNodalConnectivity().isEqual(DataArrayInt([1,24,12,1,12,11,1,11,25]))) + self.assertTrue(b.getNodalConnectivityIndex().isEqual(DataArrayInt([0,3,6,9]))) + self.assertTrue(a.getCoords().getHiddenCppPointer()==b.getCoords().getHiddenCppPointer()) + self.assertTrue(a.getCoords()[:24].isEqual(m1.getCoords(),1e-12)) + self.assertTrue(a.getCoords()[24:].isEqualWithoutConsideringStr(m2.getCoords(),1e-12)) + self.assertTrue(c.isEqual(DataArrayInt([0,1,2,3,8,9,10,11,4,5,6,7,12,12]))) + self.assertTrue(d.isEqual(DataArrayInt([(9,11),(12,13),(8,10)]))) + pass + + def testSwig2Intersect2DMeshWith1DLine5(self): + """A test focusing on a special case for cut.""" + i=MEDCouplingIMesh("mesh",2,[5,5],[0.,0.],[1.,1.]) + m1=i.buildUnstructured() + m2=MEDCouplingUMesh("mesh",1) ; m2.setCoords(DataArrayDouble([(1.,0.),(3.,2.),(1.,4.)])) ; m2.allocateCells() + for i in xrange(2): + m2.insertNextCell(NORM_SEG2,[i,i+1]) + pass + a,b,c,d=MEDCouplingUMesh.Intersect2DMeshWith1DLine(m1,m2,1e-12) + self.assertTrue(a.getNodalConnectivity().isEqual(DataArrayInt([4,1,0,5,6,4,3,2,7,8,4,4,3,8,9,4,6,5,10,11,4,7,6,11,12,4,9,8,13,14,4,11,10,15,16,4,12,11,16,17,4,14,13,18,19,4,16,15,20,21,4,18,17,22,23,4,19,18,23,24,5,6,7,1,5,2,1,7,5,12,13,7,5,8,7,13,5,12,17,13,5,18,13,17,5,16,21,17,5,22,17,21]))) + self.assertTrue(a.getNodalConnectivityIndex().isEqual(DataArrayInt([0,5,10,15,20,25,30,35,40,45,50,55,60,64,68,72,76,80,84,88,92]))) + self.assertTrue(b.getNodalConnectivity().isEqual(DataArrayInt([1,1,7,1,7,13,1,13,17,1,17,21]))) + self.assertTrue(b.getNodalConnectivityIndex().isEqual(DataArrayInt([0,3,6,9,12]))) + self.assertTrue(a.getCoords().getHiddenCppPointer()==b.getCoords().getHiddenCppPointer()) + self.assertTrue(a.getCoords()[:25].isEqual(m1.getCoords(),1e-12)) + self.assertTrue(a.getCoords()[25:].isEqualWithoutConsideringStr(m2.getCoords(),1e-12)) + self.assertTrue(c.isEqual(DataArrayInt([0,2,3,4,5,7,8,9,11,12,14,15,1,1,6,6,10,10,13,13]))) + self.assertTrue(d.isEqual(DataArrayInt([(12,13),(14,15),(16,17),(18,19)]))) + pass + + def testIntersect2DMeshWith1DLine6(self): + """ Basic test for Intersect2DMeshWith1DLine: a vertical line intersecting a square. """ + m1c = MEDCouplingCMesh() + coordX = DataArrayDouble([-1., 1., 2]) + m1c.setCoordsAt(0,coordX) + coordY = DataArrayDouble([0., 2.]) + m1c.setCoordsAt(1,coordY); + m1 = m1c.buildUnstructured() + + # A simple line: + m2 = MEDCouplingUMesh("bla", 1) + coord2 = DataArrayDouble([0.,-1.0, 0.,1., 0.,3., 0.5,2.2], 4, 2) + conn2 = DataArrayInt([NORM_SEG2,0,1,NORM_SEG3,1,2,3]) + connI2 = DataArrayInt([0,3,7]) + m2.setCoords(coord2) + m2.setConnectivity(conn2, connI2) + + # End of construction of input meshes m1bis and m2 -> start of specific part of the test + a,b,c,d = MEDCouplingUMesh.Intersect2DMeshWith1DLine(m1, m2, 1e-10) + self.assertTrue(a.getNodalConnectivity().isEqual(DataArrayInt([4,2,1,4,5,32,0,3,11,7,10,14,15,16,17,18,32,4,1,10,7,11,19,20,21,22,23]))) + self.assertTrue(a.getNodalConnectivityIndex().isEqual(DataArrayInt([0,5,16,27]))) + self.assertTrue(b.getNodalConnectivity().isEqual(DataArrayInt([1,6,10,1,10,7,2,7,11,12,2,11,8,13]))) + self.assertTrue(b.getNodalConnectivityIndex().isEqual(DataArrayInt([0,3,6,10,14]))) + self.assertTrue(a.getCoords().getHiddenCppPointer()==b.getCoords().getHiddenCppPointer()) + self.assertTrue(a.getCoords()[:6].isEqual(m1.getCoords(),1e-12)) + self.assertTrue(a.getCoords()[6:10].isEqual(m2.getCoords(),1e-12)) + self.assertTrue(a.getCoords()[10:].isEqual(DataArrayDouble([(0.,0.),(0.5164175471673584,2.),(0.3796918047064557,1.43726403104512),(0.3796918047064557,2.56273596895488),(-1.,1.),(-0.24179122641632078,2.),(0.3796918047064558,1.4372640310451201),(0.,0.5),(-0.5,0.),(1.,1.),(0.5,0.),(0.,0.5),(0.3796918047064558,1.4372640310451201),(0.7582087735836792,2.)]),1e-12)) + self.assertTrue(c.isEqual(DataArrayInt([1,0,0]))) + self.assertTrue(d.isEqual(DataArrayInt([(-1,-1),(1,2),(1,2),(-1,-1)]))) + pass + + def testSwig2Intersect2DMeshWith1DLine7(self): + """ Star pattern (a triangle intersecting another one upside down) """ + coords1 = DataArrayDouble([-2.,1., 2.,1., 0.,-2.], 3,2) + coords2 = DataArrayDouble([0.,2., 2.,-1., -2.,-1., 0.,3.], 4,2) + m1 = MEDCouplingUMesh("triangle", 2) + m2 = MEDCouplingUMesh("tri_line", 1) + m1.setCoords(coords1) + m2.setCoords(coords2) + m1.setConnectivity(DataArrayInt([NORM_TRI3, 0,1,2]), DataArrayInt([0,4])) + m2.setConnectivity(DataArrayInt([NORM_SEG2,0,1,NORM_SEG2,1,2,NORM_SEG2,2,3]), DataArrayInt([0,3,6,9])) + # End of construction of input meshes m1bis and m2 -> start of specific part of the test + a,b,c,d = MEDCouplingUMesh.Intersect2DMeshWith1DLine(m1, m2, 1e-10) + self.assertTrue(a.getNodalConnectivity().isEqual(DataArrayInt([5,1,9,7,5,2,11,10,5,0,8,12,5,7,9,10,11,12,8]))) + self.assertTrue(a.getNodalConnectivityIndex().isEqual(DataArrayInt([0,4,8,12,19]))) + self.assertTrue(b.getNodalConnectivity().isEqual(DataArrayInt([1,3,7,1,7,9,1,9,4,1,4,10,1,10,11,1,11,5,1,5,12,1,12,8,1,8,6]))) + self.assertTrue(b.getNodalConnectivityIndex().isEqual(DataArrayInt([0,3,6,9,12,15,18,21,24,27]))) + self.assertTrue(a.getCoords()[:3].isEqual(m1.getCoords(),1e-12)) + self.assertTrue(a.getCoords()[3:7].isEqual(m2.getCoords(),1e-12)) + self.assertTrue(a.getCoords()[7:].isEqual(DataArrayDouble([(0.6666666666666666,1.),(-1.,1.),(1.3333333333333333,1.1102230246251565e-16),(0.6666666666666665,-0.9999999999999996),(-0.6666666666666667,-1.),(-1.4285714285714284,0.14285714285714302)]),1e-12)) + self.assertTrue(a.getCoords().getHiddenCppPointer()==b.getCoords().getHiddenCppPointer()) + self.assertTrue(c.isEqual(DataArrayInt([0,0,0,0]))) + self.assertTrue(d.isEqual(DataArrayInt([(-1,-1),(0,3),(-1,-1),(-1,-1),(1,3),(-1,-1),(-1,-1),(2,3),(-1,-1)]))) + pass + + def testSwig2Intersect2DMeshWith1DLine8(self): + """ Line pieces ending (or fully located) in the middle of a cell """ + m1c = MEDCouplingCMesh() + m1c.setCoordsAt(0,DataArrayDouble([-1., 1.])) + m1c.setCoordsAt(1,DataArrayDouble([-1., 1.])); + m1 = m1c.buildUnstructured() + coords2 = DataArrayDouble([0.,0., 0.,1.5, -1.5,0., 0.5,0.0, 0.0,-0.5, 1.1,-0.6], 6,2) + m2 = MEDCouplingUMesh("piecewise_line", 1) + m2.setCoords(coords2) + c = DataArrayInt([NORM_SEG2,2,1, NORM_SEG2,1,4, NORM_SEG2,4,3, NORM_SEG2,3,5]) + cI = DataArrayInt([0,3,6,9,12]) + m2.setConnectivity(c, cI) + a,b,c,d = MEDCouplingUMesh.Intersect2DMeshWith1DLine(m1, m2, 1e-10) + self.assertTrue(a.getNodalConnectivity().isEqual(DataArrayInt([5,2,11,10,5,3,13,7,8,12,5,1,0,10,11,12,8,7,13]))) + self.assertTrue(a.getNodalConnectivityIndex().isEqual(DataArrayInt([0,4,10,19]))) + self.assertTrue(b.getNodalConnectivity().isEqual(DataArrayInt([1,6,10,1,10,11,1,11,5,1,5,12,1,12,8,1,8,7,1,7,13,1,13,9]))) + self.assertTrue(b.getNodalConnectivityIndex().isEqual(DataArrayInt([0,3,6,9,12,15,18,21,24]))) + self.assertTrue(a.getCoords()[:4].isEqual(m1.getCoords(),1e-12)) + self.assertTrue(a.getCoords()[4:10].isEqual(m2.getCoords(),1e-12)) + self.assertTrue(a.getCoords()[10:].isEqual(DataArrayDouble([(-1.,0.5),(-0.5,1.),(0.,1.),(1.,-0.5)]),1e-12)) + self.assertTrue(a.getCoords().getHiddenCppPointer()==b.getCoords().getHiddenCppPointer()) + self.assertTrue(c.isEqual(DataArrayInt([0,0,0]))) + self.assertTrue(d.isEqual(DataArrayInt([(-1,-1),(0,2),(-1,-1),(-1,-1),(1,2),(1,2),(1,2),(-1,-1)]))) + pass + + def testSwig2Intersect2DMeshWith1DLine9(self): + """ Intersection with a line whose connectivity is not consecutive """ + m1c = MEDCouplingCMesh() + coordX = DataArrayDouble([-1., 1., 2]) + m1c.setCoordsAt(0,coordX) + coordY = DataArrayDouble([0., 2.]) + m1c.setCoordsAt(1,coordY); + m1 = m1c.buildUnstructured() + # A simple line: + m2 = MEDCouplingUMesh("bla", 1) + coord2 = DataArrayDouble([0.,1.5, 0.5,1., 0.0,0.5, 0.0,3.0, 0.0,-1.0], 5, 2) + conn2 = DataArrayInt([NORM_SEG2,3,0,NORM_SEG3,0,2,1,NORM_SEG2,2,4]) + connI2 = DataArrayInt([0,3,7,10]) + m2.setCoords(coord2) + m2.setConnectivity(conn2, connI2) + # End of construction of input meshes m1bis and m2 -> start of specific part of the test + a,b,c,d = MEDCouplingUMesh.Intersect2DMeshWith1DLine(m1, m2, 1e-10) + self.assertTrue(a.getNodalConnectivity().isEqual(DataArrayInt([4,2,1,4,5,32,4,1,11,8,6,12,14,15,16,17,18,19,32,0,3,12,6,8,11,20,21,22,23,24,25]))) + self.assertTrue(a.getNodalConnectivityIndex().isEqual(DataArrayInt([0,5,18,31]))) + self.assertTrue(b.getNodalConnectivity().isEqual(DataArrayInt([1,9,12,1,12,6,2,6,8,13,1,8,11,1,11,10]))) + self.assertTrue(b.getNodalConnectivityIndex().isEqual(DataArrayInt([0,3,6,10,13,16]))) + self.assertTrue(a.getCoords()[:6].isEqual(m1.getCoords(),1e-12)) + self.assertTrue(a.getCoords()[6:11].isEqual(m2.getCoords(),1e-12)) + self.assertTrue(a.getCoords()[11:].isEqual(DataArrayDouble([(0.,0.),(0.,2.),(0.5,1.),(1.,1.),(0.5,0.),(0.,0.25),(0.5,1.),(0.,1.75),(0.5,2.),(-1.,1.),(-0.5,2.),(0.,1.75),(0.5,1.),(0.,0.25),(-0.5,0.)]),1e-12)) + self.assertTrue(a.getCoords().getHiddenCppPointer()==b.getCoords().getHiddenCppPointer()) + self.assertTrue(c.isEqual(DataArrayInt([1,0,0]))) + self.assertTrue(d.isEqual(DataArrayInt([(-1,-1),(1,2),(1,2),(1,2),(-1,-1)]))) + pass + + def testSwig2Intersect2DMeshWith1DLine10(self): + """ Intersection between a circle and various lines """ + eps = 1.0e-8 + m_circ = MEDCouplingDataForTest.buildCircle2(0.0, 0.0, 2.0) + coords = [0.0,3.0,0.0,-3.0] + connec = [0,1] + m_line = MEDCouplingUMesh("seg", 1) + m_line.allocateCells(1) + meshCoords = DataArrayDouble.New(coords, len(coords)/2, 2) + m_line.setCoords(meshCoords) + m_line.insertNextCell(NORM_SEG2, connec) + a, b, c, d = MEDCouplingUMesh.Intersect2DMeshWith1DLine(m_circ, m_line, eps) + self.assertTrue(a.getCoords().getHiddenCppPointer()==b.getCoords().getHiddenCppPointer()) + self.assertTrue(a.getCoords()[:m_circ.getNumberOfNodes()].isEqual(m_circ.getCoords(),1e-12)) + self.assertTrue(a.getCoords()[m_circ.getNumberOfNodes():m_circ.getNumberOfNodes()+m_line.getNumberOfNodes()].isEqual(m_line.getCoords(),1e-12)) + self.assertTrue(a.getCoords().isEqual(DataArrayDouble([(2.,0.),(1.4142135623730951,1.414213562373095),(0.,2.),(-1.414213562373095,1.4142135623730951),(-2.,0.),(-1.4142135623730954,-1.414213562373095),(0.,-2.),(1.4142135623730947,-1.4142135623730954),(0.,3.),(0.,-3.),(0.,-2.),(0.,2.),(2.,0.),(0.7653668647301797,-1.8477590650225735),(0.,0.),(0.7653668647301797,1.8477590650225735),(-2,0.),(-0.7653668647301795,1.8477590650225735),(0.,0.),(-0.7653668647301795,-1.8477590650225735)]),1e-12)) + self.assertEqual([32,1,7,10,11,12,13,14,15,32,5,3,11,10,16,17,18,19],a.getNodalConnectivity().getValues()) + self.assertEqual([0,9,18], a.getNodalConnectivityIndex().getValues()) + self.assertEqual([1,8,11,1,11,10,1,10,9],b.getNodalConnectivity().getValues()) + self.assertEqual([0,3,6,9],b.getNodalConnectivityIndex().getValues()) + self.assertTrue(a.getCoords()[:8].isEqual(m_circ.getCoords(),1e-12)) + self.assertTrue(a.getCoords()[8:10].isEqual(m_line.getCoords(),1e-12)) + coo_tgt = DataArrayDouble([2.,0.,1.4142135623730951,1.414213562373095,1.2246467991473532e-16,2.,-1.414213562373095,1.4142135623730951,-2.,0.,-1.4142135623730954,-1.414213562373095,-3.6739403974420594e-16,-2.,1.4142135623730947,-1.4142135623730954,0.,3.,0.,-3.,0.,-2.,0.,2.,2.,0.,0.7653668647301797,-1.8477590650225735,0.,0.,0.7653668647301797,1.8477590650225735,-2.,0.,-0.7653668647301795,1.8477590650225735,0.,0.,-0.7653668647301795,-1.8477590650225735]) + self.assertTrue(a.getCoords().isEqualWithoutConsideringStr(coo_tgt,1.0e-12)) + self.assertTrue(a.getCoords().getHiddenCppPointer()==b.getCoords().getHiddenCppPointer()) + self.assertEqual([0,0],c.getValues()) + self.assertEqual([-1,-1,0,1,-1,-1],d.getValues()) + + def testSwig2Intersect2DMeshWith1DLine11(self): + """ Quad line re-entering a square cell """ + eps = 1.0e-8 + m = MEDCouplingUMesh("box", 2) + m.setCoords(DataArrayDouble([-1., -1., -1., 1., 1., 1., 1., -1.0],4,2)) + c, cI = [NORM_POLYGON, 0, 1, 2, 3], [0, 5] + m.setConnectivity(DataArrayInt(c), DataArrayInt(cI)) + m.checkCoherency() + coords2 = [0., 1.3, -1.3, 0., -0.6, 0.6, 0., -1.3, -0.5, -0.5] + connec2, cI2 = [NORM_SEG3, 0, 1, 2, NORM_SEG3, 1, 3, 4], [0,4,8] + m_line = MEDCouplingUMesh("seg", 1) + m_line.setCoords(DataArrayDouble(coords2, len(coords2)/2, 2)) + m_line.setConnectivity(DataArrayInt(connec2), DataArrayInt(cI2)) + a, b, c, d = MEDCouplingUMesh.Intersect2DMeshWith1DLine(m, m_line, eps) + self.assertTrue(a.getCoords().getHiddenCppPointer()==b.getCoords().getHiddenCppPointer()) + self.assertTrue(a.getCoords()[:m.getNumberOfNodes()].isEqual(m.getCoords(),1e-12)) + self.assertTrue(a.getCoords()[m.getNumberOfNodes():m.getNumberOfNodes()+m_line.getNumberOfNodes()].isEqual(m_line.getCoords(),1e-12)) + self.assertTrue(a.getCoords().isEqual(DataArrayDouble([(-1.,-1.),(-1.,1.),(1.,1.),(1.,-1.),(0.,1.3),(-1.3,0.),(-0.6,0.6),(0.,-1.3),(-0.5,-0.5),(-1.,0.23453685964236054),(-1.,-0.13033276368660177),(-0.2345368596423598,1.),(-0.1303327636866019,-1.),(-0.11489196370692323,1.1481421036683868),(-0.6,0.6),(-1.1481421036683859,0.11489196370692323),(-1.147455889106615,-0.0593103465193594),(-0.5,-0.5),(-0.0593103465193594,-1.147455889106615),(1.,0.),(0.4348336181566991,-1.),(-0.5651663818433009,-1.),(-1.,-0.5651663818433009),(-1.,0.05210204797787939),(-0.6,0.6),(0.3827315701788201,1.),(-0.6172684298211799,1.),(-0.6,0.6),(-1.,0.6172684298211802),(-0.6,0.6),(0.3827315701788201,1.),(1.,0.),(0.4348336181566991,-1.),(-0.5,-0.5),(-1.,0.05210204797787939),(-1.,-0.5651663818433009),(-0.5,-0.5),(-0.5651663818433009,-1.)]),1e-12)) + self.assertEqual([32,9,11,2,3,12,10,29,30,31,32,33,34,32,0,10,12,35,36,37,32,1,11,9,26,27,28],a.getNodalConnectivity().getValues()) + self.assertEqual([0,13,20,27],a.getNodalConnectivityIndex().getValues()) + self.assertEqual([2,4,11,13,2,11,9,14,2,9,5,15,2,5,10,16,2,10,12,17,2,12,7,18],b.getNodalConnectivity().getValues()) + self.assertEqual([0,4,8,12,16,20,24],b.getNodalConnectivityIndex().getValues()) + self.assertTrue(a.getCoords()[:4].isEqual(m.getCoords(),1e-12)) + self.assertTrue(a.getCoords()[4:9].isEqual(m_line.getCoords(),1e-12)) + self.assertTrue(DataArrayInt([0,0,0]).isEqual(c)) + self.assertTrue(DataArrayInt([(-1,-1),(0,2),(-1,-1),(-1,-1),(0,1),(-1,-1)]).isEqual(d)) + pass + + def testSwig2Intersect2DMeshWith1DLine12(self): + """ Two squares one in the other intersected by an horizontal line """ + eps = 1.0e-8 + m = MEDCouplingUMesh("boxbox", 2) + m.setCoords(DataArrayDouble([-0.5,-0.5,-0.5,0.5,0.5,0.5,0.5,-0.5,-0.25,-0.25,-0.25,0.25,0.25,0.25,0.25,-0.25],8,2)) + c = [NORM_POLYGON, 4, 5, 6, 7, NORM_POLYGON, 0, 1, 5, 4, NORM_POLYGON, 1, 2, 3, 0, 4, 7, 6, 5] + cI = [0, 5, 10, 19] + m.setConnectivity(DataArrayInt(c), DataArrayInt(cI)) + m.checkCoherency() + coords2 = [-1., 0.25, 1., 0.25] + connec2, cI2 = [NORM_SEG2, 0, 1], [0,3] + m_line = MEDCouplingUMesh.New("seg", 1) + m_line.setCoords(DataArrayDouble(coords2, len(coords2)/2, 2)) + m_line.setConnectivity(DataArrayInt(connec2), DataArrayInt(cI2)) + m_line2 = m_line.deepCpy() + m2 = m.deepCpy() + a, b, c, d = MEDCouplingUMesh.Intersect2DMeshWith1DLine(m, m_line, eps) + self.assertTrue(a.getCoords().getHiddenCppPointer()==b.getCoords().getHiddenCppPointer()) + self.assertTrue(a.getCoords()[:m.getNumberOfNodes()].isEqual(m.getCoords(),1e-12)) + self.assertTrue(a.getCoords()[m.getNumberOfNodes():m.getNumberOfNodes()+m_line.getNumberOfNodes()].isEqual(m_line.getCoords(),1e-12)) + self.assertTrue(a.getCoords().isEqual(DataArrayDouble([(-0.5,-0.5),(-0.5,0.5),(0.5,0.5),(0.5,-0.5),(-0.25,-0.25),(-0.25,0.25),(0.25,0.25),(0.25,-0.25),(-1.,0.25),(1.,0.25),(-0.5,0.25),(0.5,0.25)]),1e-12)) + self.assertEqual([5,4,5,6,7,5,1,5,10,5,4,0,10,5,5,5,1,2,11,6,5,3,0,4,7,6,11],a.getNodalConnectivity().getValues()) + self.assertEqual([0,5,9,14,20,27],a.getNodalConnectivityIndex().getValues()) + self.assertEqual([1,8,10,1,10,5,1,5,6,1,6,11,1,11,9],b.getNodalConnectivity().getValues()) + self.assertEqual([0,3,6,9,12,15],b.getNodalConnectivityIndex().getValues()) + self.assertTrue(c.isEqual(DataArrayInt([0,1,1,2,2]))) + self.assertTrue(d.isEqual(DataArrayInt([(-1,-1),(1,2),(3,0),(3,4),(-1,-1)]))) + pass + + def testSwig2Intersect2DMeshWith1DLine13(self): + """ A square (side length) in a circle intersected by a simple horizontal line """ + import math + eps = 1.0e-8 + m = MEDCouplingUMesh("boxcircle", 2) + sq2 = math.sqrt(2.0) + soth = (sq2+1.0)/2.0 + coo = [2., 0., sq2, sq2, 0., 2., -sq2, sq2, -2., 0., -sq2, -sq2, 0., -2., sq2, -sq2, -1., -1., -1., 1., 1., + 1., 1., -1., -1., 0., 0., 1., 1., 0., 0., -1., -soth, soth, soth,soth] + coo = DataArrayDouble(coo); coo.rearrange(2) + m.setCoords(coo) + c = [NORM_QPOLYG, 8, 9, 10, 11, 12, 13, 14, 15, NORM_QPOLYG, 3, 1, 10, 9, 2, 17, 13, 16, NORM_QPOLYG, 1, 7, 5, 3, 9, 8, 11, 10, 0, 6, 4, 16, 12, 15, 14, 17] + cI = [0, 9, 18, 35] + m.setConnectivity(DataArrayInt(c), DataArrayInt(cI)) + m.checkCoherency() + coords2 = [-2., 1., 2., 1.0] + connec2, cI2 = [NORM_SEG2, 0, 1], [0,3] + m_line = MEDCouplingUMesh("seg", 1) + m_line.setCoords(DataArrayDouble(coords2, len(coords2)/2, 2)) + m_line.setConnectivity(DataArrayInt(connec2), DataArrayInt(cI2)) + a, b, c, d = MEDCouplingUMesh.Intersect2DMeshWith1DLine(m, m_line, eps) + self.assertTrue(a.getCoords().getHiddenCppPointer()==b.getCoords().getHiddenCppPointer()) + self.assertTrue(a.getCoords()[:m.getNumberOfNodes()].isEqual(m.getCoords(),1e-12)) + self.assertTrue(a.getCoords()[m.getNumberOfNodes():m.getNumberOfNodes()+m_line.getNumberOfNodes()].isEqual(m_line.getCoords(),1e-12)) + self.assertTrue(a.getCoords().isEqual(DataArrayDouble([(2.,0.),(1.4142135623730951,1.4142135623730951),(0.,2.),(-1.4142135623730951,1.4142135623730951),(-2.,0.),(-1.4142135623730951,-1.4142135623730951),(0.,-2.),(1.4142135623730951,-1.4142135623730951),(-1.,-1.),(-1.,1.),(1.,1.),(1.,-1.),(-1.,0.),(0.,1.),(1.,0.),(0.,-1.),(-1.2071067811865475,1.2071067811865475),(1.2071067811865475,1.2071067811865475),(-2.,1.),(2.,1.),(1.7320508075688772,1.),(-1.7320508075688772,1.),(-1.2071067811865475,1.2071067811865475),(-1.3660254037844386,1.),(-1.58670668058247,1.2175228580174415),(0.,-1.),(1.,0.),(1.2071067811865475,1.2071067811865475),(1.5867066805824703,1.2175228580174413),(1.9828897227476205,-0.26105238444010315),(0.,-2.),(-1.9828897227476205,-0.2610523844401032),(-1.3660254037844386,1.),(-1.,0.),(1.5867066805824703,1.2175228580174413),(1.3660254037844386,1.),(1.2071067811865475,1.2071067811865475),(0.,-2.),(-1.9828897227476205,-0.2610523844401032),(-1.3660254037844386,1.),(-1.,0.),(0.,-1.),(1.,0.),(1.3660254037844386,1.),(1.9828897227476205,-0.26105238444010315)]),1e-12)) + self.assertEqual([32,8,9,10,11,12,13,14,15,32,3,1,10,9,2,17,13,16,32,3,9,21,22,23,24,32,1,20,10,34,35,36,32,7,5,21,9,8,11,10,20,37,38,39,40,41,42,43,44],a.getNodalConnectivity().getValues()) + self.assertEqual([0,9,18,25,32,49],a.getNodalConnectivityIndex().getValues()) + self.assertEqual([1,18,21,1,21,9,1,9,10,1,10,20,1,20,19],b.getNodalConnectivity().getValues()) + self.assertEqual([0,3,6,9,12,15],b.getNodalConnectivityIndex().getValues()) + self.assertTrue(c.isEqual(DataArrayInt([0,1,2,2,2]))) + self.assertTrue(d.isEqual(DataArrayInt([(-1,-1),(2,4),(1,0),(3,4),(-1,-1)]))) + pass + + def testSwig2Intersect2DMeshWith1DLine14(self): + """ A circle in a circle intersected by a simple horizontal line, not tangent to the circles """ + eps = 1.0e-8 + m = MEDCouplingUMesh("boxcircle", 2) + coo = [2.,0.,1.4142135623730951,1.414213562373095,0.,2.,-1.414213562373095,1.4142135623730951,-2.,0.,-1.4142135623730954,-1.414213562373095,0.,-2., + 1.4142135623730947,-1.4142135623730954,1.,0.,0.7071067811865476,0.7071067811865475,0.,1.,-0.7071067811865475,0.7071067811865476,-1.,0.,-0.7071067811865477,-0.7071067811865475, + 0.,-1.,0.7071067811865474,-0.7071067811865477,1.060660171779821,-1.0606601717798214,-1.0606601717798214,-1.0606601717798212] + coo = DataArrayDouble(coo); coo.rearrange(2) + m.setCoords(coo) + c = [NORM_QPOLYG, 15, 13, 11, 9, 14, 12, 10, 8, NORM_QPOLYG, 7, 5, 13, 15, 6, 17, 14, 16, NORM_QPOLYG, 5, 3, 1, 7, 15, 9, 11, 13, 4, 2, 0, 16, 8, 10, 12, 17] + cI = [0, 9, 18, 35] + m.setConnectivity(DataArrayInt(c), DataArrayInt(cI)) + m.checkCoherency() + coords2 = [-2., 0., 2., 0.] + connec2, cI2 = [NORM_SEG2, 0, 1], [0,3] + m_line = MEDCouplingUMesh.New("seg", 1) + m_line.setCoords(DataArrayDouble(coords2, len(coords2)/2, 2)) + m_line.setConnectivity(DataArrayInt(connec2), DataArrayInt(cI2)) + a, b, c, d = MEDCouplingUMesh.Intersect2DMeshWith1DLine(m, m_line, eps) + self.assertTrue(a.getCoords().getHiddenCppPointer()==b.getCoords().getHiddenCppPointer()) + self.assertTrue(a.getCoords()[:m.getNumberOfNodes()].isEqual(m.getCoords(),1e-12)) + self.assertTrue(a.getCoords()[m.getNumberOfNodes():m.getNumberOfNodes()+m_line.getNumberOfNodes()].isEqual(m_line.getCoords(),1e-12)) + self.assertTrue(a.getCoords().isEqual(DataArrayDouble([(2.,0.),(1.4142135623730951,1.414213562373095),(0.,2.),(-1.414213562373095,1.4142135623730951),(-2.,0.),(-1.4142135623730954,-1.414213562373095),(0.,-2.),(1.4142135623730947,-1.4142135623730954),(1.,0.),(0.7071067811865476,0.7071067811865475),(0.,1.),(-0.7071067811865475,0.7071067811865476),(-1.,0.),(-0.7071067811865477,-0.7071067811865475),(0.,-1.),(0.7071067811865474,-0.7071067811865477),(1.060660171779821,-1.0606601717798214),(-1.0606601717798214,-1.0606601717798212),(-2.,0.),(2.,0.),(-1.,0.),(1.,0.),(0.,2.),(1.8477590650225735,0.7653668647301795),(1.8477590650225735,-0.7653668647301797),(1.060660171779821,-1.0606601717798214),(0.9238795325112867,-0.38268343236508984),(0.9238795325112867,0.3826834323650897),(0.,1.),(-0.9238795325112867,0.3826834323650896),(-1.5,0.),(-1.8477590650225735,0.7653668647301792),(-1.0606601717798214,-1.0606601717798212),(-1.8477590650225733,-0.7653668647301799),(-1.5,0.),(-0.9238795325112866,-0.38268343236508995),(0.,1.),(-0.9238795325112867,0.3826834323650896),(-1.5,0.),(-1.8477590650225735,0.7653668647301792),(0.,2.),(1.8477590650225735,0.7653668647301795),(1.5,0.),(0.9238795325112867,0.3826834323650897),(1.060660171779821,-1.0606601717798214),(0.9238795325112867,-0.38268343236508984),(1.5,0.),(1.8477590650225735,-0.7653668647301797),(0.,1.),(0.9238795325112867,0.3826834323650897),(0.,0.),(-0.9238795325112867,0.3826834323650896),(0.,-1.),(-0.9238795325112866,-0.38268343236508995),(0.,0.),(0.9238795325112867,-0.38268343236508984)]),1e-12)) + self.assertEqual([32,7,5,13,15,6,17,14,16,32,9,11,20,18,3,1,19,21,36,37,38,39,40,41,42,43,32,7,15,21,19,44,45,46,47,32,13,5,18,20,32,33,34,35,32,11,9,21,20,48,49,50,51,32,15,13,20,21,52,53,54,55],a.getNodalConnectivity().getValues()) + self.assertEqual([0,9,26,35,44,53,62],a.getNodalConnectivityIndex().getValues()) + self.assertEqual([1,18,20,1,20,21,1,21,19],b.getNodalConnectivity().getValues()) + self.assertEqual([0,3,6,9],b.getNodalConnectivityIndex().getValues()) + self.assertTrue(c.isEqual(DataArrayInt([1,2,2,2,0,0]))) + self.assertTrue(d.isEqual(DataArrayInt([(1,3),(4,5),(1,2)]))) + pass + + def testSwig2Intersect2DMeshWith1DLine15(self): + """ Same as testSwig2Intersect2DMeshWith1DLine13 except that the line is colinear AND splits on of the common edge of 2D mesh.""" + import math + eps = 1.0e-8 + m = MEDCouplingUMesh("boxcircle", 2) + sq2 = math.sqrt(2.0) + soth = (sq2+1.0)/2.0 + coo = [2., 0., sq2, sq2, 0., 2., -sq2, sq2, -2., 0., -sq2, -sq2, 0., -2., sq2, -sq2, -1., -1., -1., 1., 1., + 1., 1., -1., -1., 0., 0., 1., 1., 0., 0., -1., -soth, soth, soth,soth] + coo = DataArrayDouble(coo); coo.rearrange(2) + m.setCoords(coo) + c = [NORM_QPOLYG, 8, 9, 10, 11, 12, 13, 14, 15, NORM_QPOLYG, 3, 1, 10, 9, 2, 17, 13, 16, NORM_QPOLYG, 1, 7, 5, 3, 9, 8, 11, 10, 0, 6, 4, 16, 12, 15, 14, 17] + cI = [0, 9, 18, 35] + m.setConnectivity(DataArrayInt(c), DataArrayInt(cI)) + m.checkCoherency() + coords2 = [(-2., 1.),(2.,1.),(0.,1)] + connec2, cI2 = [NORM_SEG2, 0, 2, NORM_SEG2, 2, 1], [0,3,6] + m_line = MEDCouplingUMesh("seg", 1) + m_line.setCoords(DataArrayDouble(coords2)) + m_line.setConnectivity(DataArrayInt(connec2), DataArrayInt(cI2)) + a, b, c, d = MEDCouplingUMesh.Intersect2DMeshWith1DLine(m, m_line, eps) + self.assertTrue(a.getCoords().getHiddenCppPointer()==b.getCoords().getHiddenCppPointer()) + self.assertTrue(a.getCoords()[:m.getNumberOfNodes()].isEqual(m.getCoords(),1e-12)) + self.assertTrue(a.getCoords()[m.getNumberOfNodes():m.getNumberOfNodes()+m_line.getNumberOfNodes()].isEqual(m_line.getCoords(),1e-12)) + self.assertTrue(a.getCoords().isEqual(DataArrayDouble([(2.,0.),(1.4142135623730951,1.4142135623730951),(0.,2.),(-1.4142135623730951,1.4142135623730951),(-2.,0.),(-1.4142135623730951,-1.4142135623730951),(0.,-2.),(1.4142135623730951,-1.4142135623730951),(-1.,-1.),(-1.,1.),(1.,1.),(1.,-1.),(-1.,0.),(0.,1.),(1.,0.),(0.,-1.),(-1.2071067811865475,1.2071067811865475),(1.2071067811865475,1.2071067811865475),(-2.,1.),(2.,1.),(0.,1.),(1.7320508075688776,1.),(-1.7320508075688776,1.),(-0.5,1.),(0.5,1.),(0.5,1.),(-0.5,1.),(-1.2071067811865475,1.2071067811865475),(-1.3660254037844388,1.),(-1.58670668058247,1.2175228580174415),(0.,-1.),(1.,0.),(1.2071067811865475,1.2071067811865475),(1.5867066805824703,1.2175228580174413),(1.9828897227476205,-0.26105238444010315),(0.,-2.),(-1.9828897227476205,-0.2610523844401032),(-1.3660254037844388,1.),(-1.,0.),(1.5867066805824703,1.2175228580174413),(1.3660254037844388,1.),(1.2071067811865475,1.2071067811865475),(0.,-2.),(-1.9828897227476205,-0.2610523844401032),(-1.3660254037844388,1.),(-1.,0.),(0.,-1.),(1.,0.),(1.3660254037844388,1.),(1.9828897227476205,-0.26105238444010315)]),1e-12)) + self.assertEqual([32,8,9,20,10,11,12,23,24,14,15,32,3,1,10,20,9,2,17,25,26,16,32,3,9,22,27,28,29,32,1,21,10,39,40,41,32,7,5,22,9,8,11,10,21,42,43,44,45,46,47,48,49],a.getNodalConnectivity().getValues()) + self.assertEqual([0,11,22,29,36,53],a.getNodalConnectivityIndex().getValues()) + self.assertEqual([1,18,22,1,22,9,1,9,20,1,20,10,1,10,21,1,21,19],b.getNodalConnectivity().getValues()) + self.assertEqual([0,3,6,9,12,15,18],b.getNodalConnectivityIndex().getValues()) + self.assertTrue(c.isEqual(DataArrayInt([0,1,2,2,2]))) + self.assertTrue(d.isEqual(DataArrayInt([(-1,-1),(2,4),(1,0),(1,0),(3,4),(-1,-1)]))) + pass + + def testSwig2Intersect2DMeshWith1DLine16(self): + """ Same than testSwig2Intersect2DMeshWith1DLine13 except it is a vertical line. Non regression test.""" + import math + eps = 1.0e-8 + m = MEDCouplingUMesh("boxcircle", 2) + sq2 = math.sqrt(2.0) + soth = (sq2+1.0)/2.0 + coo = [2., 0., sq2, sq2, 0., 2., -sq2, sq2, -2., 0., -sq2, -sq2, 0., -2., sq2, -sq2, -1., -1., -1., 1., 1., + 1., 1., -1., -1., 0., 0., 1., 1., 0., 0., -1., -soth, soth, soth,soth] + coo = DataArrayDouble(coo); coo.rearrange(2) + m.setCoords(coo) + c = [NORM_QPOLYG, 8, 9, 10, 11, 12, 13, 14, 15, NORM_QPOLYG, 3, 1, 10, 9, 2, 17, 13, 16, NORM_QPOLYG, 1, 7, 5, 3, 9, 8, 11, 10, 0, 6, 4, 16, 12, 15, 14, 17] + cI = [0, 9, 18, 35] + m.setConnectivity(DataArrayInt(c), DataArrayInt(cI)) + m.checkCoherency() + coords2 = [1., 2., 1., -2.] + connec2, cI2 = [NORM_SEG2, 0, 1], [0,3] + m_line = MEDCouplingUMesh("seg", 1) + m_line.setCoords(DataArrayDouble(coords2, len(coords2)/2, 2)) + m_line.setConnectivity(DataArrayInt(connec2), DataArrayInt(cI2)) + a, b, c, d = MEDCouplingUMesh.Intersect2DMeshWith1DLine(m, m_line, eps) + self.assertTrue(a.getCoords().getHiddenCppPointer()==b.getCoords().getHiddenCppPointer()) + self.assertTrue(a.getCoords()[:m.getNumberOfNodes()].isEqual(m.getCoords(),1e-12)) + self.assertTrue(a.getCoords()[m.getNumberOfNodes():m.getNumberOfNodes()+m_line.getNumberOfNodes()].isEqual(m_line.getCoords(),1e-12)) + self.assertTrue(a.getCoords().isEqual(DataArrayDouble([(2., 0.),(1.4142135623730951,1.4142135623730951),(0.,2.),(-1.4142135623730951,1.4142135623730951),(-2.,0.),(-1.4142135623730951,-1.4142135623730951),(0.,-2.),(1.4142135623730951,-1.4142135623730951),(-1.,-1.),(-1.,1.),(1.,1.),(1.,-1.),(-1.,0.),(0.,1.),(1.,0.),(0.,-1.),(-1.2071067811865475,1.2071067811865475),(1.2071067811865475,1.2071067811865475),(1.,2.),(1.,-2.),(1.,1.7320508075688772),(1.,-1.7320508075688772),(1.2071067811865475,1.2071067811865475),(1.,1.3660254037844386),(1.217522858017441,1.5867066805824703),(-1.2071067811865475,1.2071067811865475),(-0.2610523844401028,1.9828897227476208),(1.,1.3660254037844386),(0.,1.),(1.2071067811865475,1.2071067811865475),(2.,0.),(1.217522858017441,-1.5867066805824703),(1.,-1.3660254037844386),(1.,0.),(-2.,0.),(-1.2071067811865475,1.2071067811865475),(-1.,0.),(0.,-1.),(1.,-1.3660254037844386),(-0.2610523844401028,-1.9828897227476208)]),1e-12)) + self.assertEqual([32,8,9,10,11,12,13,14,15,32,1,10,20,22,23,24,32,9,3,20,10,25,26,27,28,32,10,1,7,21,11,29,30,31,32,33,32,5,3,9,8,11,21,34,35,36,37,38,39],a.getNodalConnectivity().getValues()) + self.assertEqual([0,9,16,25,36,49],a.getNodalConnectivityIndex().getValues()) + self.assertEqual([1,18,20,1,20,10,1,10,11,1,11,21,1,21,19],b.getNodalConnectivity().getValues()) + self.assertEqual([0,3,6,9,12,15],b.getNodalConnectivityIndex().getValues()) + self.assertTrue(c.isEqual(DataArrayInt([0,1,1,2,2]))) + self.assertTrue(d.isEqual(DataArrayInt([(-1,-1),(1,2),(3,0),(3,4),(-1,-1)]))) + pass + + def testOrderConsecutiveCells1D1(self): + """A line in several unconnected pieces:""" + m2 = MEDCouplingUMesh.New("bla", 1) + c = DataArrayInt([NORM_SEG2,0,1,NORM_SEG3,1,3,2, NORM_SEG2,3,4, + NORM_SEG3,5,7,6, NORM_SEG3,7,9,8, NORM_SEG2,9,10, + NORM_SEG2,11,12,NORM_SEG2,12,13, + NORM_SEG2,14,15]) + cI = DataArrayInt([0,3,7,10,14,18,21,24,27,30]) + coords2 = DataArrayDouble([float(i) for i in range(32)], 16,2) + m2.setCoords(coords2); + m2.setConnectivity(c, cI); + m2.checkCoherency2(1.0e-8); + + # Shuffle a bit :-) + m2.renumberCells(DataArrayInt([0,3,6,8,1,4,7,5,2]), True); + res = m2.orderConsecutiveCells1D() + expRes = [0,3,6,8,1,4,2,7,5] + self.assertEqual(m2.getNumberOfCells(),res.getNumberOfTuples()) + self.assertEqual(expRes, res.getValues()) + + # A closed line (should also work) + m3 = MEDCouplingUMesh.New("bla3", 1) + conn3A = DataArrayInt([NORM_SEG2,0,1,NORM_SEG3,1,3,2, NORM_SEG2,3,0]) + coord3 = coords2[0:5] + c.reAlloc(10) + cI.reAlloc(4) + + m3.setCoords(coord3) + m3.setConnectivity(conn3A, cI) + m3.checkCoherency2(1.0e-8) + res2 = m3.orderConsecutiveCells1D() + expRes2 = [0,1,2] + self.assertEqual(m3.getNumberOfCells(),res2.getNumberOfTuples()) + self.assertEqual(expRes2, res2.getValues()) + pass + + def testDADApplyFuncOnThis1(self): + d=DataArrayDouble(5) ; d.iota(0.) + d.applyFuncOnThis("2*x+1") + self.assertTrue(d.isEqual(DataArrayDouble([1.,3.,5.,7.,9.]),1e-12)) + d=DataArrayDouble(6) ; d.iota(0.) ; d.rearrange(2) + d.applyFuncOnThis("2*x+1") + self.assertTrue(d.isEqual(DataArrayDouble([1.,3.,5.,7.,9.,11.],3,2),1e-12)) + d.applyFuncOnThis("1+2*3") + self.assertTrue(d.isEqual(DataArrayDouble([(7.,7.),(7.,7.),(7.,7.)]),1e-12)) + pass + + def testSwig2PointSetComputeFetchedNodeIds1(self): + arr=DataArrayDouble(6) ; arr.iota() + m=MEDCouplingCMesh() ; m.setCoords(arr,arr,arr) + m=m.buildUnstructured() + m0=m[[0,1,5,6,25,26,30,31,124]] + ref=DataArrayInt([0,1,2,6,7,8,12,13,14,36,37,38,42,43,44,48,49,50,72,73,74,78,79,80,84,85,86,172,173,178,179,208,209,214,215]) + self.assertTrue(m0.computeFetchedNodeIds().isEqual(ref)) + self.assertTrue(MEDCoupling1SGTUMesh(m0).computeFetchedNodeIds().isEqual(ref)) + self.assertEqual(m0.getAllGeoTypes(),[NORM_HEXA8]) + m0.convertAllToPoly() + self.assertEqual(m0.getAllGeoTypes(),[NORM_POLYHED]) + self.assertTrue(MEDCoupling1DGTUMesh(m0).computeFetchedNodeIds().isEqual(ref)) + pass + + def testSwig2PartDefinition1(self): + pd=PartDefinition.New(5,22,3) + self.assertTrue(isinstance(pd,SlicePartDefinition)) + self.assertTrue(pd.toDAI().isEqual(DataArrayInt([5,8,11,14,17,20]))) + self.assertEqual(pd.getNumberOfElems(),6) + self.assertEqual(pd.getEffectiveStop(),23) + pd=PartDefinition.New(5,23,3) + self.assertTrue(isinstance(pd,SlicePartDefinition)) + self.assertTrue(pd.toDAI().isEqual(DataArrayInt([5,8,11,14,17,20]))) + self.assertEqual(pd.getNumberOfElems(),6) + self.assertEqual(pd.getEffectiveStop(),23) + self.assertEqual(pd.getSlice(),slice(5,23,3)) + pd=PartDefinition.New(5,22,1) + self.assertTrue(isinstance(pd,SlicePartDefinition)) + self.assertTrue(pd.toDAI().isEqual(DataArrayInt([5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21]))) + self.assertEqual(pd.getNumberOfElems(),17) + self.assertEqual(pd.getEffectiveStop(),22) + pd=PartDefinition.New(5,23,3)+PartDefinition.New(23,27,3) + self.assertTrue(isinstance(pd,SlicePartDefinition)) + self.assertEqual(pd.getNumberOfElems(),8) + self.assertTrue(pd.toDAI().isEqual(DataArrayInt([5,8,11,14,17,20,23,26]))) + self.assertEqual(pd.getEffectiveStop(),29) + pd=SlicePartDefinition(5,22,1) + self.assertTrue(isinstance(pd,SlicePartDefinition)) + self.assertTrue(pd.toDAI().isEqual(DataArrayInt([5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21]))) + self.assertEqual(pd.getNumberOfElems(),17) + self.assertEqual(pd.getEffectiveStop(),22) + d=DataArrayInt([2,4,5,6,10]) + pd=PartDefinition.New(d) + self.assertTrue(isinstance(pd,DataArrayPartDefinition)) + self.assertEqual(pd.toDAI().getHiddenCppPointer(),d.getHiddenCppPointer()) + pd=DataArrayPartDefinition(d) + self.assertEqual(pd.toDAI().getHiddenCppPointer(),d.getHiddenCppPointer()) + pd=DataArrayPartDefinition(d)+DataArrayPartDefinition(DataArrayInt([12,14,20])) + self.assertTrue(isinstance(pd,DataArrayPartDefinition)) + self.assertEqual(pd.getNumberOfElems(),8) + self.assertTrue(pd.toDAI().isEqual(DataArrayInt([2,4,5,6,10,12,14,20]))) + pass + + def testSwig2SortEachPairToMakeALinkedList1(self): + d=DataArrayInt([(50,49),(50,51),(51,52),(53,52),(53,54),(55,54),(55,56),(56,57),(58,57),(58,59),(60,59),(60,61),(61,62),(63,62),(63,64),(65,64),(65,66),(66,67)]) + d.sortEachPairToMakeALinkedList() + self.assertTrue(d.isEqual(DataArrayInt([(49,50),(50,51),(51,52),(52,53),(53,54),(54,55),(55,56),(56,57),(57,58),(58,59),(59,60),(60,61),(61,62),(62,63),(63,64),(64,65),(65,66),(66,67)]))) + pass + + def testSwig2DAIIsRange(self): + d=DataArrayInt([2,6,10]) + a,b=d.isRange() + self.assertTrue(a) + self.assertEqual(b,slice(2,11,4)) + self.assertTrue(DataArrayInt.Range(b.start,b.stop,b.step).isEqual(d)) + # + d=DataArrayInt([2,7,10]) + a,b=d.isRange() + self.assertTrue(not a) + self.assertTrue(b is None) + # + d=DataArrayInt([22,17,12]) + a,b=d.isRange() + self.assertTrue(a) + self.assertEqual(b,slice(22,11,-5)) + self.assertTrue(DataArrayInt.Range(b.start,b.stop,b.step).isEqual(d)) + # + d=DataArrayInt([22,16,12]) + a,b=d.isRange() + self.assertTrue(not a) + self.assertTrue(b is None) + # + d=DataArrayInt([33]) + a,b=d.isRange() + self.assertTrue(a) + self.assertEqual(b,slice(33,34,1)) + self.assertTrue(DataArrayInt.Range(b.start,b.stop,b.step).isEqual(d)) + # + d=DataArrayInt([]) + a,b=d.isRange() + self.assertTrue(a) + self.assertEqual(b,slice(0,0,1)) + self.assertTrue(DataArrayInt.Range(b.start,b.stop,b.step).isEqual(d)) + # + d=DataArrayInt([2,6,10,2]) + a,b=d.isRange() + self.assertTrue(not a) + self.assertTrue(b is None) + pass + + def testSwig2PartDefinitionComposeWith1(self): + f=PartDefinition.New(DataArrayInt([0,1,2,3,6,7,8,9])) + g=PartDefinition.New(4,14,1) + g2=g.deepCpy() + self.assertTrue(g2.isEqual(g)[0]) + h=f.composeWith(g) + self.assertTrue(isinstance(h,DataArrayPartDefinition)) + self.assertTrue(h.toDAI().isEqual(DataArrayInt([4,5,6,7,10,11,12,13]))) + f2=f.tryToSimplify() + g2=g.tryToSimplify() + self.assertEqual(f2.getHiddenCppPointer(),f.getHiddenCppPointer())# same because no simplification due to content of array + self.assertEqual(g2.getHiddenCppPointer(),g.getHiddenCppPointer())# same because no simplification linked to type of PartDef + p=PartDefinition.New(DataArrayInt([2,6,10])) + p2=p.tryToSimplify() + self.assertNotEqual(p2.getHiddenCppPointer(),p.getHiddenCppPointer()) + self.assertTrue(isinstance(p2,SlicePartDefinition)) + self.assertEqual(p2.getSlice(),slice(2,11,4)) + self.assertTrue(p2.isEqual(SlicePartDefinition(2,11,4))[0]) + self.assertTrue(p2.isEqual(p2.deepCpy())[0]) + self.assertTrue(not p2.isEqual(SlicePartDefinition(1,11,4))[0]) + self.assertTrue(not p2.isEqual(SlicePartDefinition(2,10,4))[0]) + self.assertTrue(not p2.isEqual(SlicePartDefinition(2,11,3))[0]) + pass + + def testSwig2DAIGetIdsStrictlyNegative1(self): + d=DataArrayInt([4,-5,-1,0,3,99,-7]) + self.assertTrue(d.getIdsStrictlyNegative().isEqual(DataArrayInt([1,2,6]))) + pass + + def testSwig2DAIReplaceOneValByInThis1(self): + d=DataArrayInt([4,-5,-1,0,-5,99,-7,5]) + d.replaceOneValByInThis(-5,900) + self.assertTrue(d.isEqual(DataArrayInt([4,900,-1,0,900,99,-7,5]))) + pass + + def testSwig2DAIGetMinMaxValues1(self): + d=DataArrayInt([4,-5,-1,0,3,99,-7]) + a,b=d.getMinMaxValues() + self.assertEqual(a,-7) + self.assertEqual(b,99) + pass + + def testSwig2DAIBuildUniqueNotSorted1(self): + d=DataArrayInt([-5,3,2,-1,2,3,-6,4,2,-5,3,7]) + self.assertTrue(d.buildUniqueNotSorted().isEqual(DataArrayInt([-5,3,2,-1,-6,4,7]))) + pass + + def testSwig2UMeshChangeOrientationOfCells1(self): + """ Here testing changeOrientationOfCell method on unstructured meshes lying on no coords.""" + m=MEDCouplingUMesh("mesh",1) + c=DataArrayInt([NORM_SEG2,4,5,NORM_SEG2,10,8,NORM_SEG3,20,7,33,NORM_SEG3,13,15,12,NORM_SEG2,3,2,NORM_SEG4,5,6,8,10,NORM_SEG4,34,33,3,2]) + cI=DataArrayInt([0,3,6,10,14,17,22,27]) + m.setConnectivity(c,cI) + m.changeOrientationOfCells() + self.assertTrue(m.getNodalConnectivity().isEqual(DataArrayInt([NORM_SEG2,5,4,NORM_SEG2,8,10,NORM_SEG3,7,20,33,NORM_SEG3,15,13,12,NORM_SEG2,2,3,NORM_SEG4,6,5,10,8,NORM_SEG4,33,34,2,3]))) + self.assertTrue(m.getNodalConnectivityIndex().isEqual(cI)) + # testing 2D cells + m=MEDCouplingUMesh("mesh",2) + c=DataArrayInt([NORM_TRI3,0,1,2,NORM_QUAD4,3,4,5,6,NORM_POLYGON,7,8,9,10,11,NORM_TRI6,12,13,14,15,16,17,NORM_QUAD8,18,19,20,21,22,23,24,25,NORM_QPOLYG,26,27,28,29,30,31,32,33,34,35]) + cI=DataArrayInt([0,4,9,15,22,31,42]) + m.setConnectivity(c,cI) + m.changeOrientationOfCells() + self.assertTrue(m.getNodalConnectivity().isEqual(DataArrayInt([NORM_TRI3,0,2,1,NORM_QUAD4,3,6,5,4,NORM_POLYGON,7,11,10,9,8,NORM_TRI6,12,14,13,17,16,15,NORM_QUAD8,18,21,20,19,25,24,23,22,NORM_QPOLYG,26,30,29,28,27,35,34,33,32,31]))) + self.assertTrue(m.getNodalConnectivityIndex().isEqual(cI)) + pass + + def testSwig2StructuredMeshCellLocation1(self): + # 3D + arrX=DataArrayDouble(5) ; arrX.iota() + arrY=DataArrayDouble(4) ; arrY.iota() + arrZ=DataArrayDouble(3) ; arrZ.iota() + m=MEDCouplingCMesh() ; m.setCoords(arrX,arrY,arrZ) + li=[] + liExp3D=[(0,0,0),(1,0,0),(2,0,0),(3,0,0),(0,1,0),(1,1,0),(2,1,0),(3,1,0),(0,2,0),(1,2,0),(2,2,0),(3,2,0),(0,0,1),(1,0,1),(2,0,1),(3,0,1),(0,1,1),(1,1,1),(2,1,1),(3,1,1),(0,2,1),(1,2,1),(2,2,1),(3,2,1)] + self.assertEqual(24,m.getNumberOfCells()) + for i in xrange(m.getNumberOfCells()): + li.append(m.getLocationFromCellId(i)) + pass + self.assertEqual(liExp3D,li) + self.assertRaises(InterpKernelException,m.getLocationFromCellId,24) + self.assertRaises(InterpKernelException,m.getLocationFromCellId,-1) + # 2D + arrX=DataArrayDouble(5) ; arrX.iota() + arrY=DataArrayDouble(4) ; arrY.iota() + m=MEDCouplingCMesh() ; m.setCoords(arrX,arrY) + li=[] + liExp2D=[(0,0),(1,0),(2,0),(3,0),(0,1),(1,1),(2,1),(3,1),(0,2),(1,2),(2,2),(3,2)] + self.assertEqual(12,m.getNumberOfCells()) + for i in xrange(m.getNumberOfCells()): + li.append(m.getLocationFromCellId(i)) + pass + self.assertEqual(liExp2D,li) + self.assertRaises(InterpKernelException,m.getLocationFromCellId,12) + self.assertRaises(InterpKernelException,m.getLocationFromCellId,-1) + # 1D + arrX=DataArrayDouble(5) ; arrX.iota() + m=MEDCouplingCMesh() ; m.setCoords(arrX) + self.assertEqual(4,m.getNumberOfCells()) + for i in xrange(m.getNumberOfCells()): + self.assertEqual((i,),m.getLocationFromCellId(i)) + pass + self.assertRaises(InterpKernelException,m.getLocationFromCellId,4) + self.assertRaises(InterpKernelException,m.getLocationFromCellId,-1) + pass + + def testSwig2StructuredMeshNodeLocation1(self): + # 3D + arrX=DataArrayDouble(5) ; arrX.iota() + arrY=DataArrayDouble(4) ; arrY.iota() + arrZ=DataArrayDouble(3) ; arrZ.iota() + m=MEDCouplingCMesh() ; m.setCoords(arrX,arrY,arrZ) + li=[] + liExp3D=[(0,0,0),(1,0,0),(2,0,0),(3,0,0),(4,0,0),(0,1,0),(1,1,0),(2,1,0),(3,1,0),(4,1,0),(0,2,0),(1,2,0),(2,2,0),(3,2,0),(4,2,0),(0,3,0),(1,3,0),(2,3,0),(3,3,0),(4,3,0),(0,0,1),(1,0,1),(2,0,1),(3,0,1),(4,0,1),(0,1,1),(1,1,1),(2,1,1),(3,1,1),(4,1,1),(0,2,1),(1,2,1),(2,2,1),(3,2,1),(4,2,1),(0,3,1),(1,3,1),(2,3,1),(3,3,1),(4,3,1),(0,0,2),(1,0,2),(2,0,2),(3,0,2),(4,0,2),(0,1,2),(1,1,2),(2,1,2),(3,1,2),(4,1,2),(0,2,2),(1,2,2),(2,2,2),(3,2,2),(4,2,2),(0,3,2),(1,3,2),(2,3,2),(3,3,2),(4,3,2)] + self.assertEqual(60,m.getNumberOfNodes()) + for i in xrange(m.getNumberOfNodes()): + li.append(m.getLocationFromNodeId(i)) + pass + self.assertEqual(liExp3D,li) + self.assertRaises(InterpKernelException,m.getLocationFromNodeId,60) + self.assertRaises(InterpKernelException,m.getLocationFromNodeId,-1) + # 2D + arrX=DataArrayDouble(5) ; arrX.iota() + arrY=DataArrayDouble(4) ; arrY.iota() + m=MEDCouplingCMesh() ; m.setCoords(arrX,arrY) + li=[] + liExp2D=[(0,0),(1,0),(2,0),(3,0),(4,0),(0,1),(1,1),(2,1),(3,1),(4,1),(0,2),(1,2),(2,2),(3,2),(4,2),(0,3),(1,3),(2,3),(3,3),(4,3)] + self.assertEqual(20,m.getNumberOfNodes()) + for i in xrange(m.getNumberOfNodes()): + li.append(m.getLocationFromNodeId(i)) + pass + self.assertEqual(liExp2D,li) + self.assertRaises(InterpKernelException,m.getLocationFromNodeId,20) + self.assertRaises(InterpKernelException,m.getLocationFromNodeId,-1) + # 1D + arrX=DataArrayDouble(5) ; arrX.iota() + m=MEDCouplingCMesh() ; m.setCoords(arrX) + self.assertEqual(5,m.getNumberOfNodes()) + for i in xrange(m.getNumberOfNodes()): + self.assertEqual((i,),m.getLocationFromNodeId(i)) + pass + self.assertRaises(InterpKernelException,m.getLocationFromCellId,5) + self.assertRaises(InterpKernelException,m.getLocationFromCellId,-1) + pass + + def testSwig2DataArrayPrintNotTooLong1(self): + """ Now that DataArrayDouble and DataArrayInt and pickelized they can appear in YACS ports. Avoid to have too heavy string representation of them.""" + d=DataArrayDouble(2000) ; d.iota() ; d.rearrange(2) + st0=d.repr() ; st1=str(d) ; st2=d.reprNotTooLong() + self.assertEqual(st0,st1) # 1000 tuples ( >=0 and <= 1000) -> str(d)==d.repr() + self.assertEqual(st1,st2) + # + d=DataArrayDouble(2002) ; d.iota() ; d.rearrange(2) + st0=d.repr() ; st1=str(d) ; st2=d.reprNotTooLong() + self.assertNotEqual(st0,st1) # 1001 tuples ( > 1000) -> str(d)==d.reprNotTooLong() + self.assertEqual(st1,st2) + self.assertIn(len(st2),xrange(0,1000)) # no more than 1000 characters + ## Now for DataArrayInt + d=DataArrayInt(2000) ; d.iota() ; d.rearrange(2) + st0=d.repr() ; st1=str(d) ; st2=d.reprNotTooLong() + self.assertEqual(st0,st1) # 1000 tuples ( >=0 and <= 1000) -> str(d)==d.repr() + self.assertEqual(st1,st2) + # + d=DataArrayInt(2002) ; d.iota() ; d.rearrange(2) + st0=d.repr() ; st1=str(d) ; st2=d.reprNotTooLong() + self.assertNotEqual(st0,st1) # 1001 tuples ( > 1000) -> str(d)==d.reprNotTooLong() + self.assertEqual(st1,st2) + self.assertIn(len(st2),xrange(0,1000)) # no more than 1000 characters + pass + + def testExtrudedMeshWithoutZipCoords1(self): + """This test checks that MEDCouplingUMesh.buildExtrudedMesh do not perform a zipCoords.""" + arr=DataArrayDouble([(0.,0.),(1.,0.),(2.,0.),(3.,0.)]) + m=MEDCouplingUMesh("mesh",1) ; m.setCoords(arr) + m.allocateCells() + m.insertNextCell(NORM_SEG2,[1,2]) + arr1D=DataArrayDouble([(0.,0.),(0.,1.5),(0.,2.)]) + m1D=MEDCouplingUMesh("mesh1D",1) ; m1D.setCoords(arr1D) + m1D.allocateCells() + m1D.insertNextCell(NORM_SEG2,[0,1]) + m1D.insertNextCell(NORM_SEG2,[1,2]) + m2D=m.buildExtrudedMesh(m1D,0) + self.assertEqual(m.getCoords().getHiddenCppPointer(),m2D.getCoords().getHiddenCppPointer()) + coo=DataArrayDouble([(0,0),(1,0),(2,0),(3,0),(0,1.5),(1,1.5),(2,1.5),(3,1.5),(0,2),(1,2),(2,2),(3,2)]) + self.assertTrue(m.getCoords().isEqual(coo,1e-12)) + self.assertTrue(m2D.getNodalConnectivity().isEqual(DataArrayInt([4,1,2,6,5,4,5,6,10,9]))) + self.assertTrue(m2D.getNodalConnectivityIndex().isEqual(DataArrayInt([0,5,10]))) + pass + + def testPointSetAreAllNodesFetched1(self): + m=MEDCouplingCMesh() ; arr=DataArrayDouble(10) ; arr.iota() + m.setCoords(arr,arr) + m=m.buildUnstructured() + self.assertTrue(m.areAllNodesFetched()) + m2=m[[0,2,3,4,5]] + self.assertTrue(not m2.areAllNodesFetched()) + m2.zipCoords() + self.assertTrue(m2.areAllNodesFetched()) + pass + + def testMEDCouplingPointSetComputeDiameterField1(self): + arrX=DataArrayDouble([0.,1.1,1.7,2.1]) + arrY=DataArrayDouble([0.,0.7,0.8,1.9]) + arrZ=DataArrayDouble([0.,1.3,2.1,2.4]) + m=MEDCouplingCMesh() ; m.setCoords(arrX,arrY,arrZ) ; m=m.buildUnstructured() + f=m.computeDiameterField() + f.checkCoherency() + exp=DataArrayDouble([1.8411952639521971,1.5937377450509227,1.5297058540778357,1.705872210923198,1.4352700094407325,1.3638181696985856,2.0273134932713295,1.8055470085267789,1.7492855684535902,1.5297058540778357,1.2206555615733703,1.1357816691600546,1.3638181696985856,1.004987562112089,0.9,1.7492855684535902,1.4866068747318506,1.4177446878757824,1.3379088160259651,0.9695359714832656,0.8602325267042626,1.1445523142259597,0.6782329983125266,0.5099019513592785,1.5842979517754858,1.2884098726725124,1.208304597359457]) + self.assertTrue(exp.isEqual(f.getArray(),1e-12)) + m1=m[::2] + m2=m[1::2] + m2.simplexize(PLANAR_FACE_5) + m3=MEDCouplingUMesh.MergeUMeshesOnSameCoords(m1,m2) + f=m3.computeDiameterField() + f.checkCoherency() + exp2=DataArrayDouble([1.8411952639521971,1.5297058540778357,1.4352700094407325,2.0273134932713295,1.7492855684535902,1.2206555615733703,1.3638181696985856,0.9,1.4866068747318506,1.3379088160259651,0.8602325267042626,0.6782329983125266,1.5842979517754858,1.208304597359457,1.47648230602334,1.47648230602334,1.47648230602334,1.47648230602334,1.47648230602334,1.7029386365926402,1.7029386365926402,1.7029386365926402,1.7029386365926402,1.7029386365926402,1.3601470508735445,1.3601470508735445,1.3601470508735445,1.3601470508735445,1.3601470508735445,1.70293863659264,1.70293863659264,1.70293863659264,1.70293863659264,1.70293863659264,1.3601470508735445,1.3601470508735445,1.3601470508735445,1.3601470508735445,1.3601470508735445,1.063014581273465,1.063014581273465,1.063014581273465,1.063014581273465,1.063014581273465,1.0,1.0,1.0,1.0,1.0,1.5556349186104046,1.5556349186104046,1.5556349186104046,1.5556349186104046,1.5556349186104046,1.3601470508735443,1.3601470508735443,1.3601470508735443,1.3601470508735443,1.3601470508735443,0.9219544457292886,0.9219544457292886,0.9219544457292886,0.9219544457292886,0.9219544457292886,1.140175425099138,1.140175425099138,1.140175425099138,1.140175425099138,1.140175425099138,0.5,0.5,0.5,0.5,0.5,1.2529964086141667,1.2529964086141667,1.2529964086141667,1.2529964086141667,1.2529964086141667]) + self.assertTrue(exp2.isEqual(f.getArray(),1e-12)) + # TRI3 - spacedim = 2 + coo=DataArrayDouble([(1,1),(5,1.9),(2.1,3)]) + m=MEDCoupling1SGTUMesh("mesh",NORM_TRI3) ; m.setCoords(coo) + for c in [[0,1,2],[0,2,1],[2,1,0]]: + m.setNodalConnectivity(DataArrayInt(c)) + self.assertAlmostEqual(m.computeDiameterField().getArray()[0],4.1,12) + m2=m.buildUnstructured() ; m2.convertLinearCellsToQuadratic(0) + self.assertAlmostEqual(m2.computeDiameterField().getArray()[0],4.1,12) + m3=m.buildUnstructured() ; m3.convertLinearCellsToQuadratic(1) + self.assertAlmostEqual(m3.computeDiameterField().getArray()[0],4.1,12) + # TRI3 - spacedim = 3 + coo=DataArrayDouble([(1.3198537928820775,1.0991902391274959,-0.028645697595823361),(5.2486835106806335,2.2234012799688281,0.30368935050077939),(2.2973688139447361,3.1572023778066649,0.10937756365410012)]) + m=MEDCoupling1SGTUMesh("mesh",NORM_TRI3) ; m.setCoords(coo) + for c in [[0,1,2],[0,2,1],[2,1,0]]: + m.setNodalConnectivity(DataArrayInt(c)) + self.assertAlmostEqual(m.computeDiameterField().getArray()[0],4.1,12) + m2=m.buildUnstructured() ; m2.convertLinearCellsToQuadratic(0) + self.assertAlmostEqual(m2.computeDiameterField().getArray()[0],4.1,12) + m3=m.buildUnstructured() ; m3.convertLinearCellsToQuadratic(1) + self.assertAlmostEqual(m3.computeDiameterField().getArray()[0],4.1,12) + # QUAD4 - spacedim = 2 + coo=DataArrayDouble([(0,2),(2,0),(6,4),(4,9)]) + m=MEDCoupling1SGTUMesh("mesh",NORM_QUAD4) ; m.setCoords(coo) + exp3=sqrt(85.) + for delta in xrange(4): + c=[(elt+delta)%4 for elt in xrange(4)] + m.setNodalConnectivity(DataArrayInt(c)) + self.assertAlmostEqual(m.computeDiameterField().getArray()[0],exp3,12) + m2=m.buildUnstructured() ; m2.convertLinearCellsToQuadratic(0) + self.assertAlmostEqual(m2.computeDiameterField().getArray()[0],exp3,12) + m3=m.buildUnstructured() ; m3.convertLinearCellsToQuadratic(1) + self.assertAlmostEqual(m3.computeDiameterField().getArray()[0],exp3,12) + c.reverse() + m.setNodalConnectivity(DataArrayInt(c)) + self.assertAlmostEqual(m.computeDiameterField().getArray()[0],exp3,12) + m2=m.buildUnstructured() ; m2.convertLinearCellsToQuadratic(0) + self.assertAlmostEqual(m2.computeDiameterField().getArray()[0],exp3,12) + m3=m.buildUnstructured() ; m3.convertLinearCellsToQuadratic(1) + self.assertAlmostEqual(m3.computeDiameterField().getArray()[0],exp3,12) + # QUAD4 - spacedim = 3 + coo=DataArrayDouble([(0.26570992384234871,2.0405889913271817,-0.079134238105786903),(2.3739976619218064,0.15779148692781009,0.021842842914139737),(6.1207841448393197,4.3755532938679655,0.43666375769970678),(3.8363255342943359,9.2521096041694229,0.41551170895942313)]) + m=MEDCoupling1SGTUMesh("mesh",NORM_QUAD4) ; m.setCoords(coo) + for delta in xrange(4): + c=[(elt+delta)%4 for elt in xrange(4)] + m.setNodalConnectivity(DataArrayInt(c)) + self.assertAlmostEqual(m.computeDiameterField().getArray()[0],exp3,12) + m2=m.buildUnstructured() ; m2.convertLinearCellsToQuadratic(0) + self.assertAlmostEqual(m2.computeDiameterField().getArray()[0],exp3,12) + m3=m.buildUnstructured() ; m3.convertLinearCellsToQuadratic(1) + self.assertAlmostEqual(m3.computeDiameterField().getArray()[0],exp3,12) + c.reverse() + m.setNodalConnectivity(DataArrayInt(c)) + self.assertAlmostEqual(m.computeDiameterField().getArray()[0],exp3,12) + m2=m.buildUnstructured() ; m2.convertLinearCellsToQuadratic(0) + self.assertAlmostEqual(m2.computeDiameterField().getArray()[0],exp3,12) + m3=m.buildUnstructured() ; m3.convertLinearCellsToQuadratic(1) + self.assertAlmostEqual(m3.computeDiameterField().getArray()[0],exp3,12) + # PENTA6 + # noise of coo=DataArrayDouble([(0,0,0),(1,0,0),(0,1,0),(0,0,2),(1,0,2),(0,1,2)]) + rotation([0.7,-1.2,0.6],[-4,-1,10],0.3) + coo=DataArrayDouble([(-0.28594726851554486,-0.23715005500928255,-0.10268080010083136),(0.6167364988633947,-0.008923258436324799,-0.08574087516687756),(-0.6132873463333834,0.6943403970881654,-0.2806118260037991),(-0.40705974936532896,-0.05868487929989308,1.7724055544436323),(0.5505955507861958,0.19145393798144705,1.8788156352163994),(-0.6092686217773406,0.812502961290914,1.685712743757831)]) + m=MEDCoupling1SGTUMesh("mesh",NORM_PENTA6) ; m.setCoords(coo) + exp4=2.5041256256889888 + self.assertAlmostEqual(exp4,coo.buildEuclidianDistanceDenseMatrix().getMaxValue()[0],12)# <- the definition of diameter + for delta in xrange(3): + c=[(elt+delta)%3 for elt in xrange(3)] + c+=[elt+3 for elt in c] + m.setNodalConnectivity(DataArrayInt(c)) + self.assertAlmostEqual(m.computeDiameterField().getArray()[0],exp4,12) + m2=m.buildUnstructured() ; m2.convertLinearCellsToQuadratic(0) + self.assertAlmostEqual(m2.computeDiameterField().getArray()[0],exp4,12) + c.reverse() + m.setNodalConnectivity(DataArrayInt(c)) + self.assertAlmostEqual(m.computeDiameterField().getArray()[0],exp4,12) + m2=m.buildUnstructured() ; m2.convertLinearCellsToQuadratic(0) + self.assertAlmostEqual(m2.computeDiameterField().getArray()[0],exp4,12) + # HEXA8 + # noise of coo=DataArrayDouble([(0,0,0),(1,0,0),(1,1,0),(0,1,0),(0,0,2),(1,0,2),(1,1,2),(0,1,2)]) + rotation([0.7,-1.2,0.6],[-4,-1,10],0.3) + coo=DataArrayDouble([(-0.21266406388867243,-0.3049569460042527,-0.11012394815006032),(0.7641037943272584,-0.06990814759929553,-0.0909613877456491),(0.47406560768559974,0.8681310650341907,-0.2577311403703061),(-0.5136830410871793,0.644390554940524,-0.21319015989794698),(-0.4080167737381202,-0.12853761670628505,1.7869166291979348),(0.5650318811550441,0.20476257733110748,1.8140158890821603),(0.3230844436386215,1.1660778242678538,1.7175073141333406),(-0.6656588358432984,0.918357550969698,1.7566470691880265)]) + m=MEDCoupling1SGTUMesh("mesh",NORM_HEXA8) ; m.setCoords(coo) + exp5=2.5366409441884215 + self.assertAlmostEqual(exp5,coo.buildEuclidianDistanceDenseMatrix().getMaxValue()[0],12)# <- the definition of diameter + for delta in xrange(4): + c=[(elt+delta)%4 for elt in xrange(4)] + c+=[elt+4 for elt in c] + m.setNodalConnectivity(DataArrayInt(c)) + self.assertAlmostEqual(m.computeDiameterField().getArray()[0],exp5,12) + m2=m.buildUnstructured() ; m2.convertLinearCellsToQuadratic(0) + self.assertAlmostEqual(m2.computeDiameterField().getArray()[0],exp5,12) + c.reverse() + m.setNodalConnectivity(DataArrayInt(c)) + self.assertAlmostEqual(m.computeDiameterField().getArray()[0],exp5,12) + m2=m.buildUnstructured() ; m2.convertLinearCellsToQuadratic(0) + self.assertAlmostEqual(m2.computeDiameterField().getArray()[0],exp5,12) + # PYRA5 (1) 5th node is further + # noise of coo=DataArrayDouble([(0,0,0),(1,0,0),(1,1,0),(0,1,0),(0.5,0.5,2)]) + rotation([0.7,-1.2,0.6],[-4,-1,10],0.3) + coo=DataArrayDouble([(-0.31638393672228626,-0.3157865246451914,-0.12555467233075002),(0.7281379795666488,0.03836511217237115,-0.08431662762197323),(0.4757967840735147,0.8798897996143908,-0.2680890320119049),(-0.5386339871809047,0.5933159894201252,-0.2975311238319419),(0.012042592988768974,0.534282135495012,1.7859521682027926)]) + m=MEDCoupling1SGTUMesh("mesh",NORM_PYRA5) ; m.setCoords(coo) + exp6=2.1558368027391386 + self.assertAlmostEqual(exp6,coo.buildEuclidianDistanceDenseMatrix().getMaxValue()[0],12)# <- the definition of diameter + for delta in xrange(4): + c=[(elt+delta)%4 for elt in xrange(4)] + c+=[4] + m.setNodalConnectivity(DataArrayInt(c)) + self.assertAlmostEqual(m.computeDiameterField().getArray()[0],exp6,12) + m2=m.buildUnstructured() ; m2.convertLinearCellsToQuadratic(0) + self.assertAlmostEqual(m2.computeDiameterField().getArray()[0],exp6,12) + pass + # PYRA5 (2) 5th node is closer + # noise of coo=DataArrayDouble([(0,0,0),(1,0,0),(1,1,0),(0,1,0),(0.5,0.5,0.1)]) + rotation([0.7,-1.2,0.6],[-4,-1,10],0.3) + coo=DataArrayDouble([(-0.31638393672228626,-0.3157865246451914,-0.12555467233075002),(0.7281379795666488,0.03836511217237115,-0.08431662762197323),(0.4757967840735147,0.8798897996143908,-0.2680890320119049),(-0.5386339871809047,0.5933159894201252,-0.2975311238319419),(0.092964408350795,0.33389670321297005,-0.10171764888060142)]) + m=MEDCoupling1SGTUMesh("mesh",NORM_PYRA5) ; m.setCoords(coo) + exp7=1.4413563787228953 + self.assertAlmostEqual(exp7,coo.buildEuclidianDistanceDenseMatrix().getMaxValue()[0],12)# <- the definition of diameter + for delta in xrange(4): + c=[(elt+delta)%4 for elt in xrange(4)] + c+=[4] + m.setNodalConnectivity(DataArrayInt(c)) + self.assertAlmostEqual(m.computeDiameterField().getArray()[0],exp7,12) + m2=m.buildUnstructured() ; m2.convertLinearCellsToQuadratic(0) + self.assertAlmostEqual(m2.computeDiameterField().getArray()[0],exp7,12) + pass + # TETRA4 + # noise of coo=DataArrayDouble([(0,0,0),(1,0,0),(0,1,0),(1,1,1)]) + rotation([0.7,-1.2,0.6],[-4,-1,10],0.3) + coo=DataArrayDouble([(-0.2256894071281369,-0.27631691290428106,-0.20266086543995965),(0.655458695100186,-0.08173323565551605,-0.19254662462061933),(-0.49893490718947264,0.5848097154568599,-0.3039928255382145),(0.2988102920828487,1.0582266398878504,0.7347375047372364)]) + m=MEDCoupling1SGTUMesh("mesh",NORM_TETRA4) ; m.setCoords(coo) + exp8=1.7131322579364157 + self.assertAlmostEqual(exp8,coo.buildEuclidianDistanceDenseMatrix().getMaxValue()[0],12)# <- the definition of diameter + for c in [[0,1,2,3],[0,3,2,1],[0,1,3,2],[0,2,3,1],[0,3,1,2],[0,2,1,3]]: + for i in xrange(4): + m.setNodalConnectivity(DataArrayInt([(elt+i)%4 for elt in c])) + self.assertAlmostEqual(m.computeDiameterField().getArray()[0],exp8,12) + m2=m.buildUnstructured() ; m2.convertLinearCellsToQuadratic(0) + self.assertAlmostEqual(m2.computeDiameterField().getArray()[0],exp8,12) + pass + pass + pass + + def testMEDCouplingSkyLineArray(self): + index = DataArrayInt([ 0, 3, 5, 6, 6 ]) + value = DataArrayInt([ 1, 2, 3, 2, 3, 3 ]) + + sla0 = MEDCouplingSkyLineArray() + self.assertEqual( -1, sla0.getNumberOf() ) + self.assertEqual( 0, sla0.getLength() ) + sla0.set( index, value ) + self.assertTrue( index.isEqual( sla0.getIndexArray() )) + self.assertTrue( value.isEqual( sla0.getValueArray() )) + self.assertEqual( 4, sla0.getNumberOf() ) + self.assertEqual( 6, sla0.getLength() ) + + sla1 = MEDCouplingSkyLineArray( index, value ) + self.assertTrue( index.isEqual( sla1.getIndexArray() )) + self.assertTrue( value.isEqual( sla1.getValueArray() )) + self.assertEqual( 4, sla1.getNumberOf() ) + self.assertEqual( 6, sla1.getLength() ) + + sla2 = MEDCouplingSkyLineArray( sla1 ) + self.assertTrue( index.isEqual( sla2.getIndexArray() )) + self.assertTrue( value.isEqual( sla2.getValueArray() )) + self.assertEqual( 4, sla2.getNumberOf() ) + self.assertEqual( 6, sla2.getLength() ) + + indexVec = ivec(); indexVec.reserve( len( index )) + for i in index: indexVec.push_back( i[0] ) + valueVec = ivec(); valueVec.reserve( len( value )) + for i in value: valueVec.push_back( i[0] ) + sla3 = MEDCouplingSkyLineArray( indexVec, valueVec ) + self.assertTrue( index.isEqual( sla3.getIndexArray() )) + self.assertTrue( value.isEqual( sla3.getValueArray() )) + self.assertEqual( 4, sla3.getNumberOf() ) + self.assertEqual( 6, sla3.getLength() ) + + pass + + def testMEDCouplingUMeshgenerateGraph(self): + # cartesian mesh 3x3 + arr=DataArrayDouble(4) ; arr.iota() + c=MEDCouplingCMesh() ; c.setCoords(arr,arr) + m=c.buildUnstructured() + graph = m.generateGraph() + # 0 1 2 + # 3 4 5 + # 6 7 8 + valRef=[ 0,1,3, + 0,1,2,4, + 1,2,5, + 0,3,4,6, + 1,3,4,5,7, + 2,4,5,8, + 3,6,7, + 4,6,7,8, + 5,7,8] + self.assertEqual(valRef,list(graph.getValueArray().getValues())); + + indRef=[0, 3, 7, 10, 14, 19, 23, 26, 30, 33] + self.assertEqual(indRef,list(graph.getIndexArray().getValues())); + pass + + def testSwig2MEDCouplingCurveLinearReprQuick1(self): + """Non regression test. Error in m.__str__ when m is a MEDCouplingCurveLinear with spaceDim != meshDim.""" + arr=DataArrayDouble(12) ; arr.iota() ; arr.rearrange(2) + m=MEDCouplingCurveLinearMesh() + m.setCoords(arr) + m.setNodeGridStructure([3,2]) + m.checkCoherency() + self.assertEqual(m.getMeshDimension(),2) + self.assertEqual(m.getSpaceDimension(),2) + self.assertTrue(not "mismatch" in m.__str__()) + self.assertTrue(not "mismatch" in m.__repr__()) + # + arr=DataArrayDouble(18) ; arr.iota() ; arr.rearrange(3) + m.setCoords(arr) + self.assertEqual(m.getMeshDimension(),2) + self.assertEqual(m.getSpaceDimension(),3) + self.assertTrue(not "mismatch" in m.__str__()) + self.assertTrue(not "mismatch" in m.__repr__())# bug was here ! + pass + + pass + +if __name__ == '__main__': + unittest.main() diff --git a/src/medtool/src/MEDCoupling_Swig/MEDCouplingCommon.i b/src/medtool/src/MEDCoupling_Swig/MEDCouplingCommon.i new file mode 100644 index 000000000..8f1717456 --- /dev/null +++ b/src/medtool/src/MEDCoupling_Swig/MEDCouplingCommon.i @@ -0,0 +1,5857 @@ +// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 +// 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) + +%module MEDCoupling + +#ifdef WITH_DOCSTRINGS +%include MEDCoupling_doc.i +#endif + +%include std_vector.i +%include std_string.i + +%{ +#include "MEDCouplingMemArray.hxx" +#include "MEDCouplingUMesh.hxx" +#include "MEDCouplingExtrudedMesh.hxx" +#include "MEDCouplingCMesh.hxx" +#include "MEDCouplingIMesh.hxx" +#include "MEDCouplingCurveLinearMesh.hxx" +#include "MEDCoupling1GTUMesh.hxx" +#include "MEDCouplingField.hxx" +#include "MEDCouplingFieldDouble.hxx" +#include "MEDCouplingFieldTemplate.hxx" +#include "MEDCouplingGaussLocalization.hxx" +#include "MEDCouplingAutoRefCountObjectPtr.hxx" +#include "MEDCouplingMultiFields.hxx" +#include "MEDCouplingFieldOverTime.hxx" +#include "MEDCouplingDefinitionTime.hxx" +#include "MEDCouplingFieldDiscretization.hxx" +#include "MEDCouplingCartesianAMRMesh.hxx" +#include "MEDCouplingAMRAttribute.hxx" +#include "MEDCouplingMatrix.hxx" +#include "MEDCouplingPartDefinition.hxx" +#include "MEDCouplingSkyLineArray.hxx" +#include "MEDCouplingTypemaps.i" + +#include "InterpKernelAutoPtr.hxx" +#include "BoxSplittingOptions.hxx" + +using namespace ParaMEDMEM; +using namespace INTERP_KERNEL; + +%} + +%template(ivec) std::vector<int>; +%template(dvec) std::vector<double>; +%template(svec) std::vector<std::string>; + +//////////////////// +%typemap(out) ParaMEDMEM::MEDCouplingMesh* +{ + $result=convertMesh($1,$owner); +} + +%typemap(out) MEDCouplingMesh* +{ + $result=convertMesh($1,$owner); +} +//$$$$$$$$$$$$$$$$$$ + +//////////////////// +%typemap(out) ParaMEDMEM::MEDCouplingPointSet* +{ + $result=convertMesh($1,$owner); +} + +%typemap(out) MEDCouplingPointSet* +{ + $result=convertMesh($1,$owner); +} +//$$$$$$$$$$$$$$$$$$ + +//////////////////// +%typemap(out) MEDCouplingCartesianAMRPatchGen* +{ + $result=convertCartesianAMRPatch($1,$owner); +} +//$$$$$$$$$$$$$$$$$$ + +//////////////////// +%typemap(out) MEDCouplingCartesianAMRMeshGen* +{ + $result=convertCartesianAMRMesh($1,$owner); +} +//$$$$$$$$$$$$$$$$$$ + +//////////////////// +%typemap(out) MEDCouplingDataForGodFather* +{ + $result=convertDataForGodFather($1,$owner); +} +//$$$$$$$$$$$$$$$$$$ + +//////////////////// +%typemap(out) ParaMEDMEM::MEDCoupling1GTUMesh* +{ + $result=convertMesh($1,$owner); +} + +%typemap(out) MEDCoupling1GTUMesh* +{ + $result=convertMesh($1,$owner); +} +//$$$$$$$$$$$$$$$$$$ + +//////////////////// +%typemap(out) ParaMEDMEM::MEDCouplingStructuredMesh* +{ + $result=convertMesh($1,$owner); +} + +%typemap(out) MEDCouplingStructuredMesh* +{ + $result=convertMesh($1,$owner); +} +//$$$$$$$$$$$$$$$$$$ + +//////////////////// +%typemap(out) ParaMEDMEM::MEDCouplingFieldDiscretization* +{ + $result=convertFieldDiscretization($1,$owner); +} + +%typemap(out) MEDCouplingFieldDiscretization* +{ + $result=convertFieldDiscretization($1,$owner); +} +//$$$$$$$$$$$$$$$$$$ + +//////////////////// +%typemap(out) ParaMEDMEM::MEDCouplingMultiFields* +{ + $result=convertMultiFields($1,$owner); +} + +%typemap(out) MEDCouplingMultiFields* +{ + $result=convertMultiFields($1,$owner); +} +//$$$$$$$$$$$$$$$$$$ + +//////////////////// +%typemap(out) ParaMEDMEM::PartDefinition* +{ + $result=convertPartDefinition($1,$owner); +} + +%typemap(out) PartDefinition* +{ + $result=convertPartDefinition($1,$owner); +} +//$$$$$$$$$$$$$$$$$$ + +#ifdef WITH_NUMPY +%init %{ import_array(); %} +#endif + +%feature("autodoc", "1"); +%feature("docstring"); + +%newobject ParaMEDMEM::MEDCouplingField::buildMeasureField; +%newobject ParaMEDMEM::MEDCouplingField::getLocalizationOfDiscr; +%newobject ParaMEDMEM::MEDCouplingField::computeTupleIdsToSelectFromCellIds; +%newobject ParaMEDMEM::MEDCouplingFieldDouble::New; +%newobject ParaMEDMEM::MEDCouplingFieldDouble::getArray; +%newobject ParaMEDMEM::MEDCouplingFieldDouble::getEndArray; +%newobject ParaMEDMEM::MEDCouplingFieldDouble::MergeFields; +%newobject ParaMEDMEM::MEDCouplingFieldDouble::MeldFields; +%newobject ParaMEDMEM::MEDCouplingFieldDouble::doublyContractedProduct; +%newobject ParaMEDMEM::MEDCouplingFieldDouble::determinant; +%newobject ParaMEDMEM::MEDCouplingFieldDouble::eigenValues; +%newobject ParaMEDMEM::MEDCouplingFieldDouble::eigenVectors; +%newobject ParaMEDMEM::MEDCouplingFieldDouble::inverse; +%newobject ParaMEDMEM::MEDCouplingFieldDouble::trace; +%newobject ParaMEDMEM::MEDCouplingFieldDouble::deviator; +%newobject ParaMEDMEM::MEDCouplingFieldDouble::magnitude; +%newobject ParaMEDMEM::MEDCouplingFieldDouble::maxPerTuple; +%newobject ParaMEDMEM::MEDCouplingFieldDouble::keepSelectedComponents; +%newobject ParaMEDMEM::MEDCouplingFieldDouble::extractSlice3D; +%newobject ParaMEDMEM::MEDCouplingFieldDouble::DotFields; +%newobject ParaMEDMEM::MEDCouplingFieldDouble::dot; +%newobject ParaMEDMEM::MEDCouplingFieldDouble::CrossProductFields; +%newobject ParaMEDMEM::MEDCouplingFieldDouble::crossProduct; +%newobject ParaMEDMEM::MEDCouplingFieldDouble::MaxFields; +%newobject ParaMEDMEM::MEDCouplingFieldDouble::max; +%newobject ParaMEDMEM::MEDCouplingFieldDouble::MinFields; +%newobject ParaMEDMEM::MEDCouplingFieldDouble::AddFields; +%newobject ParaMEDMEM::MEDCouplingFieldDouble::SubstractFields; +%newobject ParaMEDMEM::MEDCouplingFieldDouble::MultiplyFields; +%newobject ParaMEDMEM::MEDCouplingFieldDouble::DivideFields; +%newobject ParaMEDMEM::MEDCouplingFieldDouble::min; +%newobject ParaMEDMEM::MEDCouplingFieldDouble::negate; +%newobject ParaMEDMEM::MEDCouplingFieldDouble::getIdsInRange; +%newobject ParaMEDMEM::MEDCouplingFieldDouble::buildSubPart; +%newobject ParaMEDMEM::MEDCouplingFieldDouble::buildSubPartRange; +%newobject ParaMEDMEM::MEDCouplingFieldDouble::__getitem__; +%newobject ParaMEDMEM::MEDCouplingFieldDouble::__neg__; +%newobject ParaMEDMEM::MEDCouplingFieldDouble::__add__; +%newobject ParaMEDMEM::MEDCouplingFieldDouble::__sub__; +%newobject ParaMEDMEM::MEDCouplingFieldDouble::__mul__; +%newobject ParaMEDMEM::MEDCouplingFieldDouble::__div__; +%newobject ParaMEDMEM::MEDCouplingFieldDouble::__pow__; +%newobject ParaMEDMEM::MEDCouplingFieldDouble::__radd__; +%newobject ParaMEDMEM::MEDCouplingFieldDouble::__rsub__; +%newobject ParaMEDMEM::MEDCouplingFieldDouble::__rmul__; +%newobject ParaMEDMEM::MEDCouplingFieldDouble::__rdiv__; +%newobject ParaMEDMEM::MEDCouplingFieldDouble::clone; +%newobject ParaMEDMEM::MEDCouplingFieldDouble::cloneWithMesh; +%newobject ParaMEDMEM::MEDCouplingFieldDouble::deepCpy; +%newobject ParaMEDMEM::MEDCouplingFieldDouble::buildNewTimeReprFromThis; +%newobject ParaMEDMEM::MEDCouplingFieldDouble::nodeToCellDiscretization; +%newobject ParaMEDMEM::MEDCouplingFieldDouble::cellToNodeDiscretization; +%newobject ParaMEDMEM::MEDCouplingFieldDouble::getValueOnMulti; +%newobject ParaMEDMEM::MEDCouplingFieldTemplate::New; +%newobject ParaMEDMEM::MEDCouplingMesh::deepCpy; +%newobject ParaMEDMEM::MEDCouplingMesh::checkDeepEquivalOnSameNodesWith; +%newobject ParaMEDMEM::MEDCouplingMesh::checkTypeConsistencyAndContig; +%newobject ParaMEDMEM::MEDCouplingMesh::computeNbOfNodesPerCell; +%newobject ParaMEDMEM::MEDCouplingMesh::computeNbOfFacesPerCell; +%newobject ParaMEDMEM::MEDCouplingMesh::computeEffectiveNbOfNodesPerCell; +%newobject ParaMEDMEM::MEDCouplingMesh::buildPartRange; +%newobject ParaMEDMEM::MEDCouplingMesh::giveCellsWithType; +%newobject ParaMEDMEM::MEDCouplingMesh::getCoordinatesAndOwner; +%newobject ParaMEDMEM::MEDCouplingMesh::getBarycenterAndOwner; +%newobject ParaMEDMEM::MEDCouplingMesh::computeIsoBarycenterOfNodesPerCell; +%newobject ParaMEDMEM::MEDCouplingMesh::buildOrthogonalField; +%newobject ParaMEDMEM::MEDCouplingMesh::getCellIdsFullyIncludedInNodeIds; +%newobject ParaMEDMEM::MEDCouplingMesh::mergeMyselfWith; +%newobject ParaMEDMEM::MEDCouplingMesh::fillFromAnalytic; +%newobject ParaMEDMEM::MEDCouplingMesh::fillFromAnalytic2; +%newobject ParaMEDMEM::MEDCouplingMesh::fillFromAnalytic3; +%newobject ParaMEDMEM::MEDCouplingMesh::getMeasureField; +%newobject ParaMEDMEM::MEDCouplingMesh::simplexize; +%newobject ParaMEDMEM::MEDCouplingMesh::buildUnstructured; +%newobject ParaMEDMEM::MEDCouplingMesh::MergeMeshes; +%newobject ParaMEDMEM::MEDCouplingPointSet::zipCoordsTraducer; +%newobject ParaMEDMEM::MEDCouplingPointSet::getCellsInBoundingBox; +%newobject ParaMEDMEM::MEDCouplingPointSet::findBoundaryNodes; +%newobject ParaMEDMEM::MEDCouplingPointSet::buildBoundaryMesh; +%newobject ParaMEDMEM::MEDCouplingPointSet::MergeNodesArray; +%newobject ParaMEDMEM::MEDCouplingPointSet::buildPartOfMySelf2; +%newobject ParaMEDMEM::MEDCouplingPointSet::BuildInstanceFromMeshType; +%newobject ParaMEDMEM::MEDCouplingPointSet::zipConnectivityTraducer; +%newobject ParaMEDMEM::MEDCouplingPointSet::mergeMyselfWithOnSameCoords; +%newobject ParaMEDMEM::MEDCouplingPointSet::fillCellIdsToKeepFromNodeIds; +%newobject ParaMEDMEM::MEDCouplingPointSet::getCellIdsLyingOnNodes; +%newobject ParaMEDMEM::MEDCouplingPointSet::deepCpyConnectivityOnly; +%newobject ParaMEDMEM::MEDCouplingPointSet::getBoundingBoxForBBTree; +%newobject ParaMEDMEM::MEDCouplingPointSet::computeFetchedNodeIds; +%newobject ParaMEDMEM::MEDCouplingPointSet::ComputeNbOfInteractionsWithSrcCells; +%newobject ParaMEDMEM::MEDCouplingPointSet::computeDiameterField; +%newobject ParaMEDMEM::MEDCouplingPointSet::__getitem__; +%newobject ParaMEDMEM::MEDCouplingUMesh::New; +%newobject ParaMEDMEM::MEDCouplingUMesh::getNodalConnectivity; +%newobject ParaMEDMEM::MEDCouplingUMesh::getNodalConnectivityIndex; +%newobject ParaMEDMEM::MEDCouplingUMesh::clone; +%newobject ParaMEDMEM::MEDCouplingUMesh::__iter__; +%newobject ParaMEDMEM::MEDCouplingUMesh::cellsByType; +%newobject ParaMEDMEM::MEDCouplingUMesh::buildDescendingConnectivity; +%newobject ParaMEDMEM::MEDCouplingUMesh::buildDescendingConnectivity2; +%newobject ParaMEDMEM::MEDCouplingUMesh::explode3DMeshTo1D; +%newobject ParaMEDMEM::MEDCouplingUMesh::buildExtrudedMesh; +%newobject ParaMEDMEM::MEDCouplingUMesh::buildSpreadZonesWithPoly; +%newobject ParaMEDMEM::MEDCouplingUMesh::MergeUMeshes; +%newobject ParaMEDMEM::MEDCouplingUMesh::MergeUMeshesOnSameCoords; +%newobject ParaMEDMEM::MEDCouplingUMesh::ComputeSpreadZoneGradually; +%newobject ParaMEDMEM::MEDCouplingUMesh::ComputeSpreadZoneGraduallyFromSeed; +%newobject ParaMEDMEM::MEDCouplingUMesh::buildNewNumberingFromCommNodesFrmt; +%newobject ParaMEDMEM::MEDCouplingUMesh::conformize2D; +%newobject ParaMEDMEM::MEDCouplingUMesh::colinearize2D; +%newobject ParaMEDMEM::MEDCouplingUMesh::rearrange2ConsecutiveCellTypes; +%newobject ParaMEDMEM::MEDCouplingUMesh::sortCellsInMEDFileFrmt; +%newobject ParaMEDMEM::MEDCouplingUMesh::getRenumArrForMEDFileFrmt; +%newobject ParaMEDMEM::MEDCouplingUMesh::convertCellArrayPerGeoType; +%newobject ParaMEDMEM::MEDCouplingUMesh::getRenumArrForConsecutiveCellTypesSpec; +%newobject ParaMEDMEM::MEDCouplingUMesh::buildDirectionVectorField; +%newobject ParaMEDMEM::MEDCouplingUMesh::convertLinearCellsToQuadratic; +%newobject ParaMEDMEM::MEDCouplingUMesh::getEdgeRatioField; +%newobject ParaMEDMEM::MEDCouplingUMesh::getAspectRatioField; +%newobject ParaMEDMEM::MEDCouplingUMesh::getWarpField; +%newobject ParaMEDMEM::MEDCouplingUMesh::getSkewField; +%newobject ParaMEDMEM::MEDCouplingUMesh::getPartBarycenterAndOwner; +%newobject ParaMEDMEM::MEDCouplingUMesh::computePlaneEquationOf3DFaces; +%newobject ParaMEDMEM::MEDCouplingUMesh::getPartMeasureField; +%newobject ParaMEDMEM::MEDCouplingUMesh::buildPartOrthogonalField; +%newobject ParaMEDMEM::MEDCouplingUMesh::keepCellIdsByType; +%newobject ParaMEDMEM::MEDCouplingUMesh::Build0DMeshFromCoords; +%newobject ParaMEDMEM::MEDCouplingUMesh::findAndCorrectBadOriented3DExtrudedCells; +%newobject ParaMEDMEM::MEDCouplingUMesh::findAndCorrectBadOriented3DCells; +%newobject ParaMEDMEM::MEDCouplingUMesh::convertIntoSingleGeoTypeMesh; +%newobject ParaMEDMEM::MEDCouplingUMesh::convertNodalConnectivityToStaticGeoTypeMesh; +%newobject ParaMEDMEM::MEDCouplingUMesh::findCellIdsOnBoundary; +%newobject ParaMEDMEM::MEDCouplingUMesh::computeSkin; +%newobject ParaMEDMEM::MEDCouplingUMesh::buildSetInstanceFromThis; +%newobject ParaMEDMEM::MEDCouplingUMesh::getCellIdsCrossingPlane; +%newobject ParaMEDMEM::MEDCouplingUMesh::convexEnvelop2D; +%newobject ParaMEDMEM::MEDCouplingUMesh::ComputeRangesFromTypeDistribution; +%newobject ParaMEDMEM::MEDCouplingUMesh::buildUnionOf2DMesh; +%newobject ParaMEDMEM::MEDCouplingUMesh::buildUnionOf3DMesh; +%newobject ParaMEDMEM::MEDCouplingUMesh::generateGraph; +%newobject ParaMEDMEM::MEDCouplingUMesh::orderConsecutiveCells1D; +%newobject ParaMEDMEM::MEDCouplingUMesh::getBoundingBoxForBBTreeFast; +%newobject ParaMEDMEM::MEDCouplingUMesh::getBoundingBoxForBBTree2DQuadratic; +%newobject ParaMEDMEM::MEDCouplingUMesh::getBoundingBoxForBBTree1DQuadratic; +%newobject ParaMEDMEM::MEDCouplingUMeshCellByTypeEntry::__iter__; +%newobject ParaMEDMEM::MEDCouplingUMeshCellEntry::__iter__; +%newobject ParaMEDMEM::MEDCoupling1GTUMesh::New; +%newobject ParaMEDMEM::MEDCoupling1GTUMesh::getNodalConnectivity; +%newobject ParaMEDMEM::MEDCoupling1GTUMesh::AggregateOnSameCoordsToUMesh; +%newobject ParaMEDMEM::MEDCoupling1SGTUMesh::New; +%newobject ParaMEDMEM::MEDCoupling1SGTUMesh::buildSetInstanceFromThis; +%newobject ParaMEDMEM::MEDCoupling1SGTUMesh::computeDualMesh; +%newobject ParaMEDMEM::MEDCoupling1SGTUMesh::explodeEachHexa8To6Quad4; +%newobject ParaMEDMEM::MEDCoupling1SGTUMesh::sortHexa8EachOther; +%newobject ParaMEDMEM::MEDCoupling1SGTUMesh::Merge1SGTUMeshes; +%newobject ParaMEDMEM::MEDCoupling1SGTUMesh::Merge1SGTUMeshesOnSameCoords; +%newobject ParaMEDMEM::MEDCoupling1DGTUMesh::New; +%newobject ParaMEDMEM::MEDCoupling1DGTUMesh::getNodalConnectivityIndex; +%newobject ParaMEDMEM::MEDCoupling1DGTUMesh::buildSetInstanceFromThis; +%newobject ParaMEDMEM::MEDCoupling1DGTUMesh::Merge1DGTUMeshes; +%newobject ParaMEDMEM::MEDCoupling1DGTUMesh::Merge1DGTUMeshesOnSameCoords; +%newobject ParaMEDMEM::MEDCouplingExtrudedMesh::New; +%newobject ParaMEDMEM::MEDCouplingExtrudedMesh::build3DUnstructuredMesh; +%newobject ParaMEDMEM::MEDCouplingStructuredMesh::buildStructuredSubPart; +%newobject ParaMEDMEM::MEDCouplingStructuredMesh::build1SGTUnstructured; +%newobject ParaMEDMEM::MEDCouplingStructuredMesh::build1SGTSubLevelMesh; +%newobject ParaMEDMEM::MEDCouplingStructuredMesh::BuildExplicitIdsFrom; +%newobject ParaMEDMEM::MEDCouplingStructuredMesh::ExtractFieldOfDoubleFrom; +%newobject ParaMEDMEM::MEDCouplingStructuredMesh::Build1GTNodalConnectivity; +%newobject ParaMEDMEM::MEDCouplingStructuredMesh::Build1GTNodalConnectivityOfSubLevelMesh; +%newobject ParaMEDMEM::MEDCouplingStructuredMesh::ComputeCornersGhost; +%newobject ParaMEDMEM::MEDCouplingCMesh::New; +%newobject ParaMEDMEM::MEDCouplingCMesh::clone; +%newobject ParaMEDMEM::MEDCouplingCMesh::getCoordsAt; +%newobject ParaMEDMEM::MEDCouplingIMesh::New; +%newobject ParaMEDMEM::MEDCouplingIMesh::asSingleCell; +%newobject ParaMEDMEM::MEDCouplingIMesh::buildWithGhost; +%newobject ParaMEDMEM::MEDCouplingIMesh::convertToCartesian; +%newobject ParaMEDMEM::MEDCouplingCurveLinearMesh::New; +%newobject ParaMEDMEM::MEDCouplingCurveLinearMesh::clone; +%newobject ParaMEDMEM::MEDCouplingCurveLinearMesh::getCoords; +%newobject ParaMEDMEM::MEDCouplingMultiFields::New; +%newobject ParaMEDMEM::MEDCouplingMultiFields::deepCpy; +%newobject ParaMEDMEM::MEDCouplingFieldOverTime::New; +%newobject ParaMEDMEM::MEDCouplingCartesianAMRPatchGen::getMesh; +%newobject ParaMEDMEM::MEDCouplingCartesianAMRPatchGen::__getitem__; +%newobject ParaMEDMEM::MEDCouplingCartesianAMRMeshGen::deepCpy; +%newobject ParaMEDMEM::MEDCouplingCartesianAMRMeshGen::buildUnstructured; +%newobject ParaMEDMEM::MEDCouplingCartesianAMRMeshGen::extractGhostFrom; +%newobject ParaMEDMEM::MEDCouplingCartesianAMRMeshGen::buildMeshFromPatchEnvelop; +%newobject ParaMEDMEM::MEDCouplingCartesianAMRMeshGen::buildMeshOfDirectChildrenOnly; +%newobject ParaMEDMEM::MEDCouplingCartesianAMRMeshGen::getImageMesh; +%newobject ParaMEDMEM::MEDCouplingCartesianAMRMeshGen::getGodFather; +%newobject ParaMEDMEM::MEDCouplingCartesianAMRMeshGen::getFather; +%newobject ParaMEDMEM::MEDCouplingCartesianAMRMeshGen::getPatch; +%newobject ParaMEDMEM::MEDCouplingCartesianAMRMeshGen::createCellFieldOnPatch; +%newobject ParaMEDMEM::MEDCouplingCartesianAMRMeshGen::findPatchesInTheNeighborhoodOf; +%newobject ParaMEDMEM::MEDCouplingCartesianAMRMeshGen::getPatchAtPosition; +%newobject ParaMEDMEM::MEDCouplingCartesianAMRMeshGen::getMeshAtPosition; +%newobject ParaMEDMEM::MEDCouplingCartesianAMRMeshGen::__getitem__; +%newobject ParaMEDMEM::MEDCouplingCartesianAMRMesh::New; +%newobject ParaMEDMEM::MEDCouplingDataForGodFather::getMyGodFather; +%newobject ParaMEDMEM::MEDCouplingAMRAttribute::New; +%newobject ParaMEDMEM::MEDCouplingAMRAttribute::deepCpy; +%newobject ParaMEDMEM::MEDCouplingAMRAttribute::deepCpyWithoutGodFather; +%newobject ParaMEDMEM::MEDCouplingAMRAttribute::getFieldOn; +%newobject ParaMEDMEM::MEDCouplingAMRAttribute::projectTo; +%newobject ParaMEDMEM::MEDCouplingAMRAttribute::buildCellFieldOnRecurseWithoutOverlapWithoutGhost; +%newobject ParaMEDMEM::MEDCouplingAMRAttribute::buildCellFieldOnWithGhost; +%newobject ParaMEDMEM::MEDCouplingAMRAttribute::buildCellFieldOnWithoutGhost; +%newobject ParaMEDMEM::DenseMatrix::New; +%newobject ParaMEDMEM::DenseMatrix::deepCpy; +%newobject ParaMEDMEM::DenseMatrix::shallowCpy; +%newobject ParaMEDMEM::DenseMatrix::getData; +%newobject ParaMEDMEM::DenseMatrix::matVecMult; +%newobject ParaMEDMEM::DenseMatrix::MatVecMult; +%newobject ParaMEDMEM::DenseMatrix::__add__; +%newobject ParaMEDMEM::DenseMatrix::__sub__; +%newobject ParaMEDMEM::DenseMatrix::__mul__; +%newobject ParaMEDMEM::PartDefinition::New; +%newobject ParaMEDMEM::PartDefinition::toDAI; +%newobject ParaMEDMEM::PartDefinition::__add__; +%newobject ParaMEDMEM::PartDefinition::composeWith; +%newobject ParaMEDMEM::PartDefinition::tryToSimplify; +%newobject ParaMEDMEM::DataArrayPartDefinition::New; +%newobject ParaMEDMEM::SlicePartDefinition::New; + +%feature("unref") MEDCouplingPointSet "$this->decrRef();" +%feature("unref") MEDCouplingMesh "$this->decrRef();" +%feature("unref") MEDCouplingUMesh "$this->decrRef();" +%feature("unref") MEDCoupling1GTUMesh "$this->decrRef();" +%feature("unref") MEDCoupling1SGTUMesh "$this->decrRef();" +%feature("unref") MEDCoupling1DGTUMesh "$this->decrRef();" +%feature("unref") MEDCouplingExtrudedMesh "$this->decrRef();" +%feature("unref") MEDCouplingCMesh "$this->decrRef();" +%feature("unref") MEDCouplingIMesh "$this->decrRef();" +%feature("unref") MEDCouplingCurveLinearMesh "$this->decrRef();" +%feature("unref") MEDCouplingField "$this->decrRef();" +%feature("unref") MEDCouplingFieldDiscretizationP0 "$this->decrRef();" +%feature("unref") MEDCouplingFieldDiscretizationP1 "$this->decrRef();" +%feature("unref") MEDCouplingFieldDiscretizationGauss "$this->decrRef();" +%feature("unref") MEDCouplingFieldDiscretizationGaussNE "$this->decrRef();" +%feature("unref") MEDCouplingFieldDiscretizationKriging "$this->decrRef();" +%feature("unref") MEDCouplingFieldDouble "$this->decrRef();" +%feature("unref") MEDCouplingMultiFields "$this->decrRef();" +%feature("unref") MEDCouplingFieldTemplate "$this->decrRef();" +%feature("unref") MEDCouplingMultiFields "$this->decrRef();" +%feature("unref") MEDCouplingCartesianAMRMeshGen "$this->decrRef();" +%feature("unref") MEDCouplingCartesianAMRMesh "$this->decrRef();" +%feature("unref") MEDCouplingCartesianAMRMeshSub "$this->decrRef();" +%feature("unref") MEDCouplingCartesianAMRPatchGen "$this->decrRef();" +%feature("unref") MEDCouplingCartesianAMRPatchGF "$this->decrRef();" +%feature("unref") MEDCouplingCartesianAMRPatch "$this->decrRef();" +%feature("unref") MEDCouplingDataForGodFather "$this->decrRef();" +%feature("unref") MEDCouplingAMRAttribute "$this->decrRef();" +%feature("unref") DenseMatrix "$this->decrRef();" +%feature("unref") PartDefinition "$this->decrRef();" +%feature("unref") DataArrayPartDefinition "$this->decrRef();" +%feature("unref") SlicePartDefinition "$this->decrRef();" + +%rename(assign) *::operator=; +%ignore ParaMEDMEM::MEDCouplingGaussLocalization::pushTinySerializationIntInfo; +%ignore ParaMEDMEM::MEDCouplingGaussLocalization::pushTinySerializationDblInfo; +%ignore ParaMEDMEM::MEDCouplingGaussLocalization::fillWithValues; +%ignore ParaMEDMEM::MEDCouplingGaussLocalization::buildNewInstanceFromTinyInfo; + +%nodefaultctor; + +%rename (InterpKernelException) INTERP_KERNEL::Exception; + +%include "MEDCouplingRefCountObject.i" +%include "MEDCouplingMemArray.i" + +namespace INTERP_KERNEL +{ + /*! + * \class BoxSplittingOptions + * Class defining the options for box splitting used for AMR algorithm like creation of patches following a criterion. + */ + class BoxSplittingOptions + { + public: + BoxSplittingOptions(); + void init() throw(INTERP_KERNEL::Exception); + double getEfficiencyGoal() const throw(INTERP_KERNEL::Exception); + void setEfficiencyGoal(double efficiency) throw(INTERP_KERNEL::Exception); + double getEfficiencyThreshold() const throw(INTERP_KERNEL::Exception); + void setEfficiencyThreshold(double efficiencyThreshold) throw(INTERP_KERNEL::Exception); + int getMinimumPatchLength() const throw(INTERP_KERNEL::Exception); + void setMinimumPatchLength(int minPatchLength) throw(INTERP_KERNEL::Exception); + int getMaximumPatchLength() const throw(INTERP_KERNEL::Exception); + void setMaximumPatchLength(int maxPatchLength) throw(INTERP_KERNEL::Exception); + int getMaximumNbOfCellsInPatch() const throw(INTERP_KERNEL::Exception); + void setMaximumNbOfCellsInPatch(int maxNbCellsInPatch) throw(INTERP_KERNEL::Exception); + void copyOptions(const BoxSplittingOptions & other) throw(INTERP_KERNEL::Exception); + std::string printOptions() const throw(INTERP_KERNEL::Exception); + %extend + { + std::string __str__() const throw(INTERP_KERNEL::Exception) + { + return self->printOptions(); + } + } + }; +} + +namespace ParaMEDMEM +{ + typedef enum + { + ON_CELLS = 0, + ON_NODES = 1, + ON_GAUSS_PT = 2, + ON_GAUSS_NE = 3, + ON_NODES_KR = 4 + } TypeOfField; + + typedef enum + { + NO_TIME = 4, + ONE_TIME = 5, + LINEAR_TIME = 6, + CONST_ON_TIME_INTERVAL = 7 + } TypeOfTimeDiscretization; + + typedef enum + { + UNSTRUCTURED = 5, + CARTESIAN = 7, + EXTRUDED = 8, + CURVE_LINEAR = 9, + SINGLE_STATIC_GEO_TYPE_UNSTRUCTURED = 10, + SINGLE_DYNAMIC_GEO_TYPE_UNSTRUCTURED = 11, + IMAGE_GRID = 12 + } MEDCouplingMeshType; + + class DataArrayInt; + class DataArrayDouble; + class MEDCouplingUMesh; + class MEDCouplingFieldDouble; + + %extend RefCountObject + { + std::string getHiddenCppPointer() const + { + std::ostringstream oss; oss << "C++ Pointer address is : " << self; + return oss.str(); + } + } + + %extend MEDCouplingGaussLocalization + { + std::string __str__() const throw(INTERP_KERNEL::Exception) + { + return self->getStringRepr(); + } + + std::string __repr__() const throw(INTERP_KERNEL::Exception) + { + std::ostringstream oss; oss << "MEDCouplingGaussLocalization C++ instance at " << self << "." << std::endl; + oss << self->getStringRepr(); + return oss.str(); + } + } + + //== MEDCouplingMesh + + class MEDCouplingMesh : public RefCountObject, public TimeLabel + { + public: + void setName(const std::string& name); + std::string getName() const; + void setDescription(const std::string& descr); + std::string getDescription() const; + void setTime(double val, int iteration, int order); + void setTimeUnit(const std::string& unit); + std::string getTimeUnit() const; + virtual MEDCouplingMeshType getType() const throw(INTERP_KERNEL::Exception); + bool isStructured() const throw(INTERP_KERNEL::Exception); + virtual MEDCouplingMesh *deepCpy() const; + virtual bool isEqual(const MEDCouplingMesh *other, double prec) const throw(INTERP_KERNEL::Exception); + virtual bool isEqualWithoutConsideringStr(const MEDCouplingMesh *other, double prec) const throw(INTERP_KERNEL::Exception); + virtual void checkFastEquivalWith(const MEDCouplingMesh *other, double prec) const throw(INTERP_KERNEL::Exception); + virtual void copyTinyStringsFrom(const MEDCouplingMesh *other) throw(INTERP_KERNEL::Exception); + virtual void copyTinyInfoFrom(const MEDCouplingMesh *other) throw(INTERP_KERNEL::Exception); + virtual void checkCoherency() const throw(INTERP_KERNEL::Exception); + virtual void checkCoherency1(double eps=1e-12) const throw(INTERP_KERNEL::Exception); + virtual void checkCoherency2(double eps=1e-12) const throw(INTERP_KERNEL::Exception); + virtual int getNumberOfCells() const throw(INTERP_KERNEL::Exception); + virtual int getNumberOfNodes() const throw(INTERP_KERNEL::Exception); + virtual int getSpaceDimension() const throw(INTERP_KERNEL::Exception); + virtual int getMeshDimension() const throw(INTERP_KERNEL::Exception); + virtual DataArrayDouble *getCoordinatesAndOwner() const throw(INTERP_KERNEL::Exception); + virtual DataArrayDouble *getBarycenterAndOwner() const throw(INTERP_KERNEL::Exception); + virtual DataArrayDouble *computeIsoBarycenterOfNodesPerCell() const throw(INTERP_KERNEL::Exception); + virtual DataArrayInt *giveCellsWithType(INTERP_KERNEL::NormalizedCellType type) const throw(INTERP_KERNEL::Exception); + virtual DataArrayInt *computeNbOfNodesPerCell() const throw(INTERP_KERNEL::Exception); + virtual DataArrayInt *computeNbOfFacesPerCell() const throw(INTERP_KERNEL::Exception); + virtual DataArrayInt *computeEffectiveNbOfNodesPerCell() const throw(INTERP_KERNEL::Exception); + virtual MEDCouplingMesh *buildPartRange(int beginCellIds, int endCellIds, int stepCellIds) const throw(INTERP_KERNEL::Exception); + virtual int getNumberOfCellsWithType(INTERP_KERNEL::NormalizedCellType type) const throw(INTERP_KERNEL::Exception); + virtual INTERP_KERNEL::NormalizedCellType getTypeOfCell(int cellId) const throw(INTERP_KERNEL::Exception); + virtual std::string simpleRepr() const throw(INTERP_KERNEL::Exception); + virtual std::string advancedRepr() const throw(INTERP_KERNEL::Exception); + std::string writeVTK(const std::string& fileName, bool isBinary=true) const throw(INTERP_KERNEL::Exception); + virtual std::string getVTKFileExtension() const; + std::string getVTKFileNameOf(const std::string& fileName) const; + // tools + virtual MEDCouplingFieldDouble *getMeasureField(bool isAbs) const throw(INTERP_KERNEL::Exception); + virtual MEDCouplingFieldDouble *getMeasureFieldOnNode(bool isAbs) const throw(INTERP_KERNEL::Exception); + virtual MEDCouplingFieldDouble *fillFromAnalytic(TypeOfField t, int nbOfComp, const std::string& func) const throw(INTERP_KERNEL::Exception); + virtual MEDCouplingFieldDouble *fillFromAnalytic2(TypeOfField t, int nbOfComp, const std::string& func) const throw(INTERP_KERNEL::Exception); + virtual MEDCouplingFieldDouble *fillFromAnalytic3(TypeOfField t, int nbOfComp, const std::vector<std::string>& varsOrder, const std::string& func) const throw(INTERP_KERNEL::Exception); + virtual MEDCouplingFieldDouble *buildOrthogonalField() const throw(INTERP_KERNEL::Exception); + virtual MEDCouplingUMesh *buildUnstructured() const throw(INTERP_KERNEL::Exception); + virtual MEDCouplingMesh *mergeMyselfWith(const MEDCouplingMesh *other) const throw(INTERP_KERNEL::Exception); + virtual bool areCompatibleForMerge(const MEDCouplingMesh *other) const throw(INTERP_KERNEL::Exception); + virtual DataArrayInt *simplexize(int policy) throw(INTERP_KERNEL::Exception); + virtual void unserialization(const std::vector<double>& tinyInfoD, const std::vector<int>& tinyInfo, const DataArrayInt *a1, DataArrayDouble *a2, const std::vector<std::string>& littleStrings) throw(INTERP_KERNEL::Exception); + static MEDCouplingMesh *MergeMeshes(const MEDCouplingMesh *mesh1, const MEDCouplingMesh *mesh2) 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); + %extend + { + std::string __str__() const throw(INTERP_KERNEL::Exception) + { + return self->simpleRepr(); + } + + PyObject *getTime() throw(INTERP_KERNEL::Exception) + { + int tmp1,tmp2; + double tmp0=self->getTime(tmp1,tmp2); + PyObject *res = PyList_New(3); + PyList_SetItem(res,0,SWIG_From_double(tmp0)); + PyList_SetItem(res,1,SWIG_From_int(tmp1)); + PyList_SetItem(res,2,SWIG_From_int(tmp2)); + return res; + } + + int getCellContainingPoint(PyObject *p, double eps) const throw(INTERP_KERNEL::Exception) + { + double val; + DataArrayDouble *a; + DataArrayDoubleTuple *aa; + std::vector<double> bb; + int sw; + int spaceDim=self->getSpaceDimension(); + const char msg[]="Python wrap of MEDCouplingMesh::getCellContainingPoint : "; + const double *pos=convertObjToPossibleCpp5_Safe(p,sw,val,a,aa,bb,msg,1,spaceDim,true); + return self->getCellContainingPoint(pos,eps); + } + + PyObject *getCellsContainingPoints(PyObject *p, int nbOfPoints, double eps) const throw(INTERP_KERNEL::Exception) + { + double val; + DataArrayDouble *a; + DataArrayDoubleTuple *aa; + std::vector<double> bb; + int sw; + int spaceDim=self->getSpaceDimension(); + const char msg[]="Python wrap of MEDCouplingMesh::getCellsContainingPoint : "; + const double *pos=convertObjToPossibleCpp5_Safe(p,sw,val,a,aa,bb,msg,nbOfPoints,spaceDim,true); + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> elts,eltsIndex; + self->getCellsContainingPoints(pos,nbOfPoints,eps,elts,eltsIndex); + PyObject *ret=PyTuple_New(2); + PyTuple_SetItem(ret,0,SWIG_NewPointerObj(SWIG_as_voidptr(elts.retn()),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 )); + PyTuple_SetItem(ret,1,SWIG_NewPointerObj(SWIG_as_voidptr(eltsIndex.retn()),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 )); + return ret; + } + + PyObject *getCellsContainingPoints(PyObject *p, double eps) const throw(INTERP_KERNEL::Exception) + { + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> elts,eltsIndex; + int spaceDim=self->getSpaceDimension(); + void *da=0; + int res1=SWIG_ConvertPtr(p,&da,SWIGTYPE_p_ParaMEDMEM__DataArrayDouble, 0 | 0 ); + if (!SWIG_IsOK(res1)) + { + int size; + INTERP_KERNEL::AutoCPtr<double> tmp=convertPyToNewDblArr2(p,&size); + int nbOfPoints=size/spaceDim; + if(size%spaceDim!=0) + { + throw INTERP_KERNEL::Exception("MEDCouplingMesh::getCellsContainingPoints : Invalid list length ! Must be a multiple of self.getSpaceDimension() !"); + } + self->getCellsContainingPoints(tmp,nbOfPoints,eps,elts,eltsIndex); + } + else + { + DataArrayDouble *da2=reinterpret_cast< DataArrayDouble * >(da); + if(!da2) + throw INTERP_KERNEL::Exception("MEDCouplingMesh::getCellsContainingPoints : Not null DataArrayDouble instance expected !"); + da2->checkAllocated(); + int size=da2->getNumberOfTuples(); + int nbOfCompo=da2->getNumberOfComponents(); + if(nbOfCompo!=spaceDim) + { + throw INTERP_KERNEL::Exception("MEDCouplingMesh::getCellsContainingPoints : Invalid DataArrayDouble nb of components ! Expected same as self.getSpaceDimension() !"); + } + self->getCellsContainingPoints(da2->getConstPointer(),size,eps,elts,eltsIndex); + } + PyObject *ret=PyTuple_New(2); + PyTuple_SetItem(ret,0,SWIG_NewPointerObj(SWIG_as_voidptr(elts.retn()),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 )); + PyTuple_SetItem(ret,1,SWIG_NewPointerObj(SWIG_as_voidptr(eltsIndex.retn()),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 )); + return ret; + } + + PyObject *getCellsContainingPoint(PyObject *p, double eps) const throw(INTERP_KERNEL::Exception) + { + double val; + DataArrayDouble *a; + DataArrayDoubleTuple *aa; + std::vector<double> bb; + int sw; + int spaceDim=self->getSpaceDimension(); + const char msg[]="Python wrap of MEDCouplingUMesh::getCellsContainingPoint : "; + const double *pos=convertObjToPossibleCpp5_Safe(p,sw,val,a,aa,bb,msg,1,spaceDim,true); + std::vector<int> elts; + self->getCellsContainingPoint(pos,eps,elts); + DataArrayInt *ret=DataArrayInt::New(); + ret->alloc((int)elts.size(),1); + std::copy(elts.begin(),elts.end(),ret->getPointer()); + return SWIG_NewPointerObj(SWIG_as_voidptr(ret),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 ); + } + + virtual PyObject *getReverseNodalConnectivity() const throw(INTERP_KERNEL::Exception) + { + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> d0=DataArrayInt::New(); + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> d1=DataArrayInt::New(); + self->getReverseNodalConnectivity(d0,d1); + PyObject *ret=PyTuple_New(2); + PyTuple_SetItem(ret,0,SWIG_NewPointerObj(SWIG_as_voidptr(d0.retn()),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 )); + PyTuple_SetItem(ret,1,SWIG_NewPointerObj(SWIG_as_voidptr(d1.retn()),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 )); + return ret; + } + + void renumberCells(PyObject *li, bool check=true) throw(INTERP_KERNEL::Exception) + { + int sw,sz(-1); + int v0; std::vector<int> v1; + const int *ids(convertObjToPossibleCpp1_Safe(li,sw,sz,v0,v1)); + self->renumberCells(ids,check); + } + + PyObject *checkGeoEquivalWith(const MEDCouplingMesh *other, int levOfCheck, double prec) const throw(INTERP_KERNEL::Exception) + { + DataArrayInt *cellCor, *nodeCor; + self->checkGeoEquivalWith(other,levOfCheck,prec,cellCor,nodeCor); + PyObject *res = PyList_New(2); + PyList_SetItem(res,0,SWIG_NewPointerObj(SWIG_as_voidptr(cellCor),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, cellCor?SWIG_POINTER_OWN | 0:0 )); + PyList_SetItem(res,1,SWIG_NewPointerObj(SWIG_as_voidptr(nodeCor),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, nodeCor?SWIG_POINTER_OWN | 0:0 )); + return res; + } + + PyObject *checkDeepEquivalWith(const MEDCouplingMesh *other, int cellCompPol, double prec) const throw(INTERP_KERNEL::Exception) + { + DataArrayInt *cellCor=0,*nodeCor=0; + self->checkDeepEquivalWith(other,cellCompPol,prec,cellCor,nodeCor); + PyObject *res = PyList_New(2); + PyList_SetItem(res,0,SWIG_NewPointerObj(SWIG_as_voidptr(cellCor),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, cellCor?SWIG_POINTER_OWN | 0:0 )); + PyList_SetItem(res,1,SWIG_NewPointerObj(SWIG_as_voidptr(nodeCor),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, nodeCor?SWIG_POINTER_OWN | 0:0 )); + return res; + } + + DataArrayInt *checkDeepEquivalOnSameNodesWith(const MEDCouplingMesh *other, int cellCompPol, double prec) const throw(INTERP_KERNEL::Exception) + { + DataArrayInt *cellCor=0; + self->checkDeepEquivalOnSameNodesWith(other,cellCompPol,prec,cellCor); + return cellCor; + } + + DataArrayInt *getCellIdsFullyIncludedInNodeIds(PyObject *li) const throw(INTERP_KERNEL::Exception) + { + void *da=0; + int res1=SWIG_ConvertPtr(li,&da,SWIGTYPE_p_ParaMEDMEM__DataArrayInt, 0 | 0 ); + if (!SWIG_IsOK(res1)) + { + int size; + INTERP_KERNEL::AutoPtr<int> tmp=convertPyToNewIntArr2(li,&size); + return self->getCellIdsFullyIncludedInNodeIds(tmp,((const int *)tmp)+size); + } + else + { + DataArrayInt *da2=reinterpret_cast< DataArrayInt * >(da); + if(!da2) + throw INTERP_KERNEL::Exception("Not null DataArrayInt instance expected !"); + da2->checkAllocated(); + return self->getCellIdsFullyIncludedInNodeIds(da2->getConstPointer(),da2->getConstPointer()+da2->getNbOfElems()); + } + } + PyObject *getNodeIdsOfCell(int cellId) const throw(INTERP_KERNEL::Exception) + { + std::vector<int> conn; + self->getNodeIdsOfCell(cellId,conn); + return convertIntArrToPyList2(conn); + } + + PyObject *getCoordinatesOfNode(int nodeId) const throw(INTERP_KERNEL::Exception) + { + std::vector<double> coo; + self->getCoordinatesOfNode(nodeId,coo); + return convertDblArrToPyList2(coo); + } + + void scale(PyObject *point, double factor) throw(INTERP_KERNEL::Exception) + { + double val; + DataArrayDouble *a; + DataArrayDoubleTuple *aa; + std::vector<double> bb; + int sw; + int spaceDim=self->getSpaceDimension(); + const char msg[]="Python wrap of MEDCouplingPointSet::scale : "; + const double *pointPtr=convertObjToPossibleCpp5_Safe(point,sw,val,a,aa,bb,msg,1,spaceDim,true); + self->scale(pointPtr,factor); + } + + PyObject *getBoundingBox() const throw(INTERP_KERNEL::Exception) + { + int spaceDim=self->getSpaceDimension(); + INTERP_KERNEL::AutoPtr<double> tmp=new double[2*spaceDim]; + self->getBoundingBox(tmp); + PyObject *ret=convertDblArrToPyListOfTuple(tmp,2,spaceDim); + return ret; + } + + PyObject *isEqualIfNotWhy(const MEDCouplingMesh *other, double prec) const throw(INTERP_KERNEL::Exception) + { + std::string ret1; + bool ret0=self->isEqualIfNotWhy(other,prec,ret1); + PyObject *ret=PyTuple_New(2); + PyObject *ret0Py=ret0?Py_True:Py_False; + Py_XINCREF(ret0Py); + PyTuple_SetItem(ret,0,ret0Py); + PyTuple_SetItem(ret,1,PyString_FromString(ret1.c_str())); + return ret; + } + + PyObject *buildPart(PyObject *li) const throw(INTERP_KERNEL::Exception) + { + int szArr,sw,iTypppArr; + std::vector<int> stdvecTyyppArr; + const int *tmp=convertObjToPossibleCpp1_Safe(li,sw,szArr,iTypppArr,stdvecTyyppArr); + MEDCouplingMesh *ret=self->buildPart(tmp,tmp+szArr); + if(sw==3)//DataArrayInt + { + void *argp; SWIG_ConvertPtr(li,&argp,SWIGTYPE_p_ParaMEDMEM__DataArrayInt,0|0); + DataArrayInt *argpt=reinterpret_cast< ParaMEDMEM::DataArrayInt * >(argp); + std::string name=argpt->getName(); + if(!name.empty()) + ret->setName(name.c_str()); + } + return convertMesh(ret, SWIG_POINTER_OWN | 0 ); + } + + PyObject *buildPartAndReduceNodes(PyObject *li) const throw(INTERP_KERNEL::Exception) + { + int szArr,sw,iTypppArr; + std::vector<int> stdvecTyyppArr; + DataArrayInt *arr=0; + const int *tmp=convertObjToPossibleCpp1_Safe(li,sw,szArr,iTypppArr,stdvecTyyppArr); + MEDCouplingMesh *ret=self->buildPartAndReduceNodes(tmp,tmp+szArr,arr); + if(sw==3)//DataArrayInt + { + void *argp; SWIG_ConvertPtr(li,&argp,SWIGTYPE_p_ParaMEDMEM__DataArrayInt,0|0); + DataArrayInt *argpt=reinterpret_cast< ParaMEDMEM::DataArrayInt * >(argp); + std::string name=argpt->getName(); + if(!name.empty()) + ret->setName(name.c_str()); + } + // + PyObject *res = PyList_New(2); + PyObject *obj0=convertMesh(ret, SWIG_POINTER_OWN | 0 ); + PyObject *obj1=SWIG_NewPointerObj(SWIG_as_voidptr(arr),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 ); + PyList_SetItem(res,0,obj0); + PyList_SetItem(res,1,obj1); + return res; + } + + PyObject *buildPartRangeAndReduceNodes(int beginCellIds, int endCellIds, int stepCellIds) const throw(INTERP_KERNEL::Exception) + { + int a,b,c; + DataArrayInt *arr=0; + MEDCouplingMesh *ret=self->buildPartRangeAndReduceNodes(beginCellIds,endCellIds,stepCellIds,a,b,c,arr); + PyObject *res = PyTuple_New(2); + PyObject *obj0=convertMesh(ret, SWIG_POINTER_OWN | 0 ); + PyObject *obj1=0; + if(arr) + obj1=SWIG_NewPointerObj(SWIG_as_voidptr(arr),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 ); + else + obj1=PySlice_New(PyInt_FromLong(a),PyInt_FromLong(b),PyInt_FromLong(b)); + PyTuple_SetItem(res,0,obj0); + PyTuple_SetItem(res,1,obj1); + return res; + } + + PyObject *getDistributionOfTypes() const throw(INTERP_KERNEL::Exception) + { + std::vector<int> vals=self->getDistributionOfTypes(); + if(vals.size()%3!=0) + throw INTERP_KERNEL::Exception("Internal Error detected in wrap python ! code returned by MEDCouplingMesh::getDistributionOfTypes is not so that %3==0 !"); + PyObject *ret=PyList_New((int)vals.size()/3); + for(int j=0;j<(int)vals.size()/3;j++) + { + PyObject *ret1=PyList_New(3); + PyList_SetItem(ret1,0,SWIG_From_int(vals[3*j])); + PyList_SetItem(ret1,1,SWIG_From_int(vals[3*j+1])); + PyList_SetItem(ret1,2,SWIG_From_int(vals[3*j+2])); + PyList_SetItem(ret,j,ret1); + } + return ret; + } + + DataArrayInt *checkTypeConsistencyAndContig(PyObject *li, PyObject *li2) const throw(INTERP_KERNEL::Exception) + { + std::vector<int> code; + std::vector<const DataArrayInt *> idsPerType; + convertFromPyObjVectorOfObj<const ParaMEDMEM::DataArrayInt *>(li2,SWIGTYPE_p_ParaMEDMEM__DataArrayInt,"DataArrayInt",idsPerType); + convertPyToNewIntArr4(li,1,3,code); + return self->checkTypeConsistencyAndContig(code,idsPerType); + } + + PyObject *splitProfilePerType(const DataArrayInt *profile) const throw(INTERP_KERNEL::Exception) + { + std::vector<int> code; + std::vector<DataArrayInt *> idsInPflPerType; + std::vector<DataArrayInt *> idsPerType; + self->splitProfilePerType(profile,code,idsInPflPerType,idsPerType); + PyObject *ret=PyTuple_New(3); + // + if(code.size()%3!=0) + throw INTERP_KERNEL::Exception("Internal Error detected in wrap python ! code returned by MEDCouplingMesh::splitProfilePerType is not so that %3==0 !"); + PyObject *ret0=PyList_New((int)code.size()/3); + for(int j=0;j<(int)code.size()/3;j++) + { + PyObject *ret00=PyList_New(3); + PyList_SetItem(ret00,0,SWIG_From_int(code[3*j])); + PyList_SetItem(ret00,1,SWIG_From_int(code[3*j+1])); + PyList_SetItem(ret00,2,SWIG_From_int(code[3*j+2])); + PyList_SetItem(ret0,j,ret00); + } + PyTuple_SetItem(ret,0,ret0); + // + PyObject *ret1=PyList_New(idsInPflPerType.size()); + for(std::size_t j=0;j<idsInPflPerType.size();j++) + PyList_SetItem(ret1,j,SWIG_NewPointerObj(SWIG_as_voidptr(idsInPflPerType[j]),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 )); + PyTuple_SetItem(ret,1,ret1); + int n=idsPerType.size(); + PyObject *ret2=PyList_New(n); + for(int i=0;i<n;i++) + PyList_SetItem(ret2,i,SWIG_NewPointerObj(SWIG_as_voidptr(idsPerType[i]),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 )); + PyTuple_SetItem(ret,2,ret2); + return ret; + } + + void translate(PyObject *vector) throw(INTERP_KERNEL::Exception) + { + double val; + DataArrayDouble *a; + DataArrayDoubleTuple *aa; + std::vector<double> bb; + int sw; + int spaceDim=self->getSpaceDimension(); + const char msg[]="Python wrap of MEDCouplingPointSet::translate : "; + const double *vectorPtr=convertObjToPossibleCpp5_Safe(vector,sw,val,a,aa,bb,msg,1,spaceDim,true); + self->translate(vectorPtr); + } + + void rotate(PyObject *center, double alpha) throw(INTERP_KERNEL::Exception) + { + const char msg[]="Python wrap of MEDCouplingPointSet::rotate : "; + double val; + DataArrayDouble *a; + DataArrayDoubleTuple *aa; + std::vector<double> bb; + int sw; + int spaceDim=self->getSpaceDimension(); + const double *centerPtr=convertObjToPossibleCpp5_Safe(center,sw,val,a,aa,bb,msg,1,spaceDim,true); + self->rotate(centerPtr,0,alpha); + } + + void rotate(PyObject *center, PyObject *vector, double alpha) throw(INTERP_KERNEL::Exception) + { + const char msg[]="Python wrap of MEDCouplingPointSet::rotate : "; + double val,val2; + DataArrayDouble *a,*a2; + DataArrayDoubleTuple *aa,*aa2; + std::vector<double> bb,bb2; + int sw; + int spaceDim=self->getSpaceDimension(); + const double *centerPtr=convertObjToPossibleCpp5_Safe(center,sw,val,a,aa,bb,msg,1,spaceDim,true); + const double *vectorPtr=convertObjToPossibleCpp5_Safe(vector,sw,val2,a2,aa2,bb2,msg,1,spaceDim,false);//vectorPtr can be null in case of space dim 2 + self->rotate(centerPtr,vectorPtr,alpha); + } + + PyObject *getAllGeoTypes() const throw(INTERP_KERNEL::Exception) + { + std::set<INTERP_KERNEL::NormalizedCellType> result=self->getAllGeoTypes(); + std::set<INTERP_KERNEL::NormalizedCellType>::const_iterator iL=result.begin(); + PyObject *res=PyList_New(result.size()); + for(int i=0;iL!=result.end(); i++, iL++) + PyList_SetItem(res,i,PyInt_FromLong(*iL)); + return res; + } + + virtual PyObject *getTinySerializationInformation() const throw(INTERP_KERNEL::Exception) + { + std::vector<double> a0; + std::vector<int> a1; + std::vector<std::string> a2; + self->getTinySerializationInformation(a0,a1,a2); + PyObject *ret(PyTuple_New(3)); + PyTuple_SetItem(ret,0,convertDblArrToPyList2(a0)); + PyTuple_SetItem(ret,1,convertIntArrToPyList2(a1)); + int sz(a2.size()); + PyObject *ret2(PyList_New(sz)); + { + for(int i=0;i<sz;i++) + PyList_SetItem(ret2,i,PyString_FromString(a2[i].c_str())); + } + PyTuple_SetItem(ret,2,ret2); + return ret; + } + + virtual PyObject *serialize() const throw(INTERP_KERNEL::Exception) + { + DataArrayInt *a0Tmp(0); + DataArrayDouble *a1Tmp(0); + self->serialize(a0Tmp,a1Tmp); + PyObject *ret(PyTuple_New(2)); + PyTuple_SetItem(ret,0,SWIG_NewPointerObj(SWIG_as_voidptr(a0Tmp),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 )); + PyTuple_SetItem(ret,1,SWIG_NewPointerObj(SWIG_as_voidptr(a1Tmp),SWIGTYPE_p_ParaMEDMEM__DataArrayDouble, SWIG_POINTER_OWN | 0 )); + return ret; + } + + void resizeForUnserialization(const std::vector<int>& tinyInfo, DataArrayInt *a1, DataArrayDouble *a2) const throw(INTERP_KERNEL::Exception) + { + std::vector<std::string> littleStrings; + self->resizeForUnserialization(tinyInfo,a1,a2,littleStrings); + } + + PyObject *__getnewargs__() throw(INTERP_KERNEL::Exception) + {// put an empty dict in input to say to __new__ to call __init__... + PyObject *ret(PyTuple_New(1)); + PyObject *ret0(PyDict_New()); + PyTuple_SetItem(ret,0,ret0); + return ret; + } + + PyObject *__getstate__() const throw(INTERP_KERNEL::Exception) + { + PyObject *ret0(ParaMEDMEM_MEDCouplingMesh_getTinySerializationInformation(self)); + PyObject *ret1(ParaMEDMEM_MEDCouplingMesh_serialize(self)); + PyObject *ret(PyTuple_New(2)); + PyTuple_SetItem(ret,0,ret0); + PyTuple_SetItem(ret,1,ret1); + return ret; + } + + void __setstate__(PyObject *inp) throw(INTERP_KERNEL::Exception) + { + static const char MSG[]="MEDCouplingMesh.__setstate__ : expected input is a tuple of size 2 !"; + if(!PyTuple_Check(inp)) + throw INTERP_KERNEL::Exception(MSG); + int sz(PyTuple_Size(inp)); + if(sz!=2) + throw INTERP_KERNEL::Exception(MSG); + PyObject *elt0(PyTuple_GetItem(inp,0)); + PyObject *elt1(PyTuple_GetItem(inp,1)); + std::vector<double> a0; + std::vector<int> a1; + std::vector<std::string> a2; + DataArrayInt *b0(0); + DataArrayDouble *b1(0); + { + if(!PyTuple_Check(elt0) && PyTuple_Size(elt0)!=3) + throw INTERP_KERNEL::Exception(MSG); + PyObject *a0py(PyTuple_GetItem(elt0,0)),*a1py(PyTuple_GetItem(elt0,1)),*a2py(PyTuple_GetItem(elt0,2)); + int tmp(-1); + fillArrayWithPyListDbl3(a0py,tmp,a0); + convertPyToNewIntArr3(a1py,a1); + fillStringVector(a2py,a2); + } + { + if(!PyTuple_Check(elt1) && PyTuple_Size(elt1)!=2) + throw INTERP_KERNEL::Exception(MSG); + PyObject *b0py(PyTuple_GetItem(elt1,0)),*b1py(PyTuple_GetItem(elt1,1)); + void *argp(0); + int status(SWIG_ConvertPtr(b0py,&argp,SWIGTYPE_p_ParaMEDMEM__DataArrayInt,0|0)); + if(!SWIG_IsOK(status)) + throw INTERP_KERNEL::Exception(MSG); + b0=reinterpret_cast<DataArrayInt *>(argp); + status=SWIG_ConvertPtr(b1py,&argp,SWIGTYPE_p_ParaMEDMEM__DataArrayDouble,0|0); + if(!SWIG_IsOK(status)) + throw INTERP_KERNEL::Exception(MSG); + b1=reinterpret_cast<DataArrayDouble *>(argp); + } + // useless here to call resizeForUnserialization because arrays are well resized. + self->unserialization(a0,a1,b0,b1,a2); + } + + static MEDCouplingMesh *MergeMeshes(PyObject *li) throw(INTERP_KERNEL::Exception) + { + std::vector<const ParaMEDMEM::MEDCouplingMesh *> tmp; + convertFromPyObjVectorOfObj<const ParaMEDMEM::MEDCouplingMesh *>(li,SWIGTYPE_p_ParaMEDMEM__MEDCouplingMesh,"MEDCouplingMesh",tmp); + return MEDCouplingMesh::MergeMeshes(tmp); + } + } + }; +} + +//== MEDCouplingMesh End + +%include "NormalizedGeometricTypes" +%include "MEDCouplingNatureOfFieldEnum" +// +namespace ParaMEDMEM +{ + class MEDCouplingNatureOfField + { + public: + static const char *GetRepr(NatureOfField nat) throw(INTERP_KERNEL::Exception); + static std::string GetReprNoThrow(NatureOfField nat); + static std::string GetAllPossibilitiesStr(); + }; +} + +// the MEDCouplingTimeDiscretization classes are not swigged : in case the file can help +// include "MEDCouplingTimeDiscretization.i" + +namespace ParaMEDMEM +{ + class MEDCouplingGaussLocalization + { + public: + MEDCouplingGaussLocalization(INTERP_KERNEL::NormalizedCellType type, const std::vector<double>& refCoo, + const std::vector<double>& gsCoo, const std::vector<double>& w) throw(INTERP_KERNEL::Exception); + MEDCouplingGaussLocalization(INTERP_KERNEL::NormalizedCellType typ) throw(INTERP_KERNEL::Exception); + INTERP_KERNEL::NormalizedCellType getType() const throw(INTERP_KERNEL::Exception); + void setType(INTERP_KERNEL::NormalizedCellType typ) throw(INTERP_KERNEL::Exception); + int getNumberOfGaussPt() const throw(INTERP_KERNEL::Exception); + int getDimension() const throw(INTERP_KERNEL::Exception); + int getNumberOfPtsInRefCell() const throw(INTERP_KERNEL::Exception); + std::string getStringRepr() const throw(INTERP_KERNEL::Exception); + void checkCoherency() const throw(INTERP_KERNEL::Exception); + bool isEqual(const MEDCouplingGaussLocalization& other, double eps) const throw(INTERP_KERNEL::Exception); + // + const std::vector<double>& getRefCoords() const throw(INTERP_KERNEL::Exception); + double getRefCoord(int ptIdInCell, int comp) const throw(INTERP_KERNEL::Exception); + const std::vector<double>& getGaussCoords() const throw(INTERP_KERNEL::Exception); + double getGaussCoord(int gaussPtIdInCell, int comp) const throw(INTERP_KERNEL::Exception); + const std::vector<double>& getWeights() const throw(INTERP_KERNEL::Exception); + double getWeight(int gaussPtIdInCell, double newVal) const throw(INTERP_KERNEL::Exception); + 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<double>& refCoo) throw(INTERP_KERNEL::Exception); + void setGaussCoords(const std::vector<double>& gsCoo) throw(INTERP_KERNEL::Exception); + void setWeights(const std::vector<double>& w) throw(INTERP_KERNEL::Exception); + // + static bool AreAlmostEqual(const std::vector<double>& v1, const std::vector<double>& v2, double eps); + }; + + class MEDCouplingSkyLineArray + { + public: + MEDCouplingSkyLineArray(); + MEDCouplingSkyLineArray( const MEDCouplingSkyLineArray &myArray ); + MEDCouplingSkyLineArray( DataArrayInt* index, DataArrayInt* value ); + MEDCouplingSkyLineArray( const std::vector<int>& index, const std::vector<int>& value ); + + void set( DataArrayInt* index, DataArrayInt* value ); + int getNumberOf() const; + int getLength() const; + DataArrayInt* getIndexArray() const; + DataArrayInt* getValueArray() const; + %extend + { + std::string __str__() const throw(INTERP_KERNEL::Exception) + { + return self->simpleRepr(); + } + } + }; +} + +%include "MEDCouplingFieldDiscretization.i" + +//== MEDCouplingPointSet + +namespace ParaMEDMEM +{ + class MEDCouplingPointSet : public ParaMEDMEM::MEDCouplingMesh + { + public: + void setCoords(const DataArrayDouble *coords) throw(INTERP_KERNEL::Exception); + DataArrayDouble *getCoordinatesAndOwner() const throw(INTERP_KERNEL::Exception); + bool areCoordsEqual(const MEDCouplingPointSet& other, double prec) const throw(INTERP_KERNEL::Exception); + void zipCoords() throw(INTERP_KERNEL::Exception); + double getCaracteristicDimension() const throw(INTERP_KERNEL::Exception); + void recenterForMaxPrecision(double eps) throw(INTERP_KERNEL::Exception); + void changeSpaceDimension(int newSpaceDim, double dftVal=0.) throw(INTERP_KERNEL::Exception); + void tryToShareSameCoords(const MEDCouplingPointSet& other, double epsilon) throw(INTERP_KERNEL::Exception); + virtual void shallowCopyConnectivityFrom(const MEDCouplingPointSet *other) throw(INTERP_KERNEL::Exception); + virtual MEDCouplingPointSet *buildPartOfMySelf2(int start, int end, int step) const throw(INTERP_KERNEL::Exception); + virtual void tryToShareSameCoordsPermute(const MEDCouplingPointSet& other, double epsilon) throw(INTERP_KERNEL::Exception); + static DataArrayDouble *MergeNodesArray(const MEDCouplingPointSet *m1, const MEDCouplingPointSet *m2) throw(INTERP_KERNEL::Exception); + static MEDCouplingPointSet *BuildInstanceFromMeshType(MEDCouplingMeshType type) throw(INTERP_KERNEL::Exception); + static DataArrayInt *ComputeNbOfInteractionsWithSrcCells(const MEDCouplingPointSet *srcMesh, const MEDCouplingPointSet *trgMesh, double eps) throw(INTERP_KERNEL::Exception); + virtual DataArrayInt *computeFetchedNodeIds() const throw(INTERP_KERNEL::Exception); + virtual int getNumberOfNodesInCell(int cellId) const throw(INTERP_KERNEL::Exception); + virtual MEDCouplingPointSet *buildBoundaryMesh(bool keepCoords) const throw(INTERP_KERNEL::Exception); + virtual DataArrayInt *getCellsInBoundingBox(const INTERP_KERNEL::DirectedBoundingBox& bbox, double eps) throw(INTERP_KERNEL::Exception); + virtual DataArrayInt *zipCoordsTraducer() throw(INTERP_KERNEL::Exception); + virtual DataArrayInt *findBoundaryNodes() const; + virtual DataArrayInt *zipConnectivityTraducer(int compType, int startCellId=0) throw(INTERP_KERNEL::Exception); + virtual MEDCouplingPointSet *mergeMyselfWithOnSameCoords(const MEDCouplingPointSet *other) const throw(INTERP_KERNEL::Exception); + virtual void checkFullyDefined() const throw(INTERP_KERNEL::Exception); + virtual bool isEmptyMesh(const std::vector<int>& tinyInfo) const throw(INTERP_KERNEL::Exception); + virtual MEDCouplingPointSet *deepCpyConnectivityOnly() const throw(INTERP_KERNEL::Exception); + virtual DataArrayDouble *getBoundingBoxForBBTree(double arcDetEps=1e-12) const throw(INTERP_KERNEL::Exception); + virtual void renumberNodesWithOffsetInConn(int offset) throw(INTERP_KERNEL::Exception); + virtual bool areAllNodesFetched() const throw(INTERP_KERNEL::Exception); + virtual MEDCouplingFieldDouble *computeDiameterField() const throw(INTERP_KERNEL::Exception); + %extend + { + std::string __str__() const throw(INTERP_KERNEL::Exception) + { + return self->simpleRepr(); + } + + PyObject *buildNewNumberingFromCommonNodesFormat(const DataArrayInt *comm, const DataArrayInt *commIndex) const throw(INTERP_KERNEL::Exception) + { + int newNbOfNodes; + DataArrayInt *ret0=self->buildNewNumberingFromCommonNodesFormat(comm,commIndex,newNbOfNodes); + PyObject *res = PyList_New(2); + PyList_SetItem(res,0,SWIG_NewPointerObj(SWIG_as_voidptr(ret0),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 )); + PyList_SetItem(res,1,SWIG_From_int(newNbOfNodes)); + return res; + } + + PyObject *findCommonNodes(double prec, int limitTupleId=-1) const throw(INTERP_KERNEL::Exception) + { + DataArrayInt *comm, *commIndex; + self->findCommonNodes(prec,limitTupleId,comm,commIndex); + PyObject *res = PyList_New(2); + PyList_SetItem(res,0,SWIG_NewPointerObj(SWIG_as_voidptr(comm),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 )); + PyList_SetItem(res,1,SWIG_NewPointerObj(SWIG_as_voidptr(commIndex),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 )); + return res; + } + + PyObject *getCoords() throw(INTERP_KERNEL::Exception) + { + DataArrayDouble *ret1=self->getCoords(); + if (ret1) + ret1->incrRef(); + return SWIG_NewPointerObj((void*)ret1,SWIGTYPE_p_ParaMEDMEM__DataArrayDouble,SWIG_POINTER_OWN | 0); + } + + PyObject *buildPartOfMySelf(PyObject *li, bool keepCoords=true) const throw(INTERP_KERNEL::Exception) + { + int szArr,sw,iTypppArr; + std::vector<int> stdvecTyyppArr; + const int *tmp=convertObjToPossibleCpp1_Safe(li,sw,szArr,iTypppArr,stdvecTyyppArr); + MEDCouplingPointSet *ret=self->buildPartOfMySelf(tmp,tmp+szArr,keepCoords); + if(sw==3)//DataArrayInt + { + void *argp; SWIG_ConvertPtr(li,&argp,SWIGTYPE_p_ParaMEDMEM__DataArrayInt,0|0); + DataArrayInt *argpt=reinterpret_cast< ParaMEDMEM::DataArrayInt * >(argp); + std::string name=argpt->getName(); + if(!name.empty()) + ret->setName(name.c_str()); + } + return convertMesh(ret, SWIG_POINTER_OWN | 0 ); + } + + PyObject *buildPartOfMySelfNode(PyObject *li, bool fullyIn) const throw(INTERP_KERNEL::Exception) + { + int szArr,sw,iTypppArr; + std::vector<int> stdvecTyyppArr; + const int *tmp=convertObjToPossibleCpp1_Safe(li,sw,szArr,iTypppArr,stdvecTyyppArr); + MEDCouplingPointSet *ret=self->buildPartOfMySelfNode(tmp,tmp+szArr,fullyIn); + if(sw==3)//DataArrayInt + { + void *argp; SWIG_ConvertPtr(li,&argp,SWIGTYPE_p_ParaMEDMEM__DataArrayInt,0|0); + DataArrayInt *argpt=reinterpret_cast< ParaMEDMEM::DataArrayInt * >(argp); + std::string name=argpt->getName(); + if(!name.empty()) + ret->setName(name.c_str()); + } + return convertMesh(ret, SWIG_POINTER_OWN | 0 ); + } + + virtual PyObject *buildPartOfMySelfKeepCoords(PyObject *li) const throw(INTERP_KERNEL::Exception) + { + int szArr,sw,iTypppArr; + std::vector<int> stdvecTyyppArr; + const int *tmp=convertObjToPossibleCpp1_Safe(li,sw,szArr,iTypppArr,stdvecTyyppArr); + MEDCouplingPointSet *ret=self->buildPartOfMySelfKeepCoords(tmp,tmp+szArr); + if(sw==3)//DataArrayInt + { + void *argp; SWIG_ConvertPtr(li,&argp,SWIGTYPE_p_ParaMEDMEM__DataArrayInt,0|0); + DataArrayInt *argpt=reinterpret_cast< ParaMEDMEM::DataArrayInt * >(argp); + std::string name=argpt->getName(); + if(!name.empty()) + ret->setName(name.c_str()); + } + return convertMesh(ret, SWIG_POINTER_OWN | 0 ); + } + + virtual PyObject *buildPartOfMySelfKeepCoords2(int start, int end, int step) const throw(INTERP_KERNEL::Exception) + { + MEDCouplingPointSet *ret=self->buildPartOfMySelfKeepCoords2(start,end,step); + return convertMesh(ret, SWIG_POINTER_OWN | 0 ); + } + + PyObject *buildFacePartOfMySelfNode(PyObject *li, bool fullyIn) const throw(INTERP_KERNEL::Exception) + { + int szArr,sw,iTypppArr; + std::vector<int> stdvecTyyppArr; + const int *tmp=convertObjToPossibleCpp1_Safe(li,sw,szArr,iTypppArr,stdvecTyyppArr); + MEDCouplingPointSet *ret=self->buildFacePartOfMySelfNode(tmp,tmp+szArr,fullyIn); + if(sw==3)//DataArrayInt + { + void *argp; SWIG_ConvertPtr(li,&argp,SWIGTYPE_p_ParaMEDMEM__DataArrayInt,0|0); + DataArrayInt *argpt=reinterpret_cast< ParaMEDMEM::DataArrayInt * >(argp); + std::string name=argpt->getName(); + if(!name.empty()) + ret->setName(name.c_str()); + } + return convertMesh(ret, SWIG_POINTER_OWN | 0 ); + } + + void renumberNodes(PyObject *li, int newNbOfNodes) throw(INTERP_KERNEL::Exception) + { + int szArr,sw,iTypppArr; + std::vector<int> stdvecTyyppArr; + const int *tmp=convertObjToPossibleCpp1_Safe(li,sw,szArr,iTypppArr,stdvecTyyppArr); + self->renumberNodes(tmp,newNbOfNodes); + } + + void renumberNodes2(PyObject *li, int newNbOfNodes) throw(INTERP_KERNEL::Exception) + { + int szArr,sw,iTypppArr; + std::vector<int> stdvecTyyppArr; + const int *tmp=convertObjToPossibleCpp1_Safe(li,sw,szArr,iTypppArr,stdvecTyyppArr); + self->renumberNodes2(tmp,newNbOfNodes); + } + + PyObject *findNodesOnLine(PyObject *pt, PyObject *vec, double eps) const throw(INTERP_KERNEL::Exception) + { + int spaceDim=self->getSpaceDimension(); + double val,val2; + DataArrayDouble *a,*a2; + DataArrayDoubleTuple *aa,*aa2; + std::vector<double> bb,bb2; + int sw; + const char msg[]="Python wrap of MEDCouplingPointSet::findNodesOnLine : 1st paramater for point."; + const char msg2[]="Python wrap of MEDCouplingPointSet::findNodesOnLine : 2nd paramater for vector."; + const double *p=convertObjToPossibleCpp5_Safe(pt,sw,val,a,aa,bb,msg,1,spaceDim,true); + const double *v=convertObjToPossibleCpp5_Safe(vec,sw,val2,a2,aa2,bb2,msg2,1,spaceDim,true); + std::vector<int> nodes; + self->findNodesOnLine(p,v,eps,nodes); + DataArrayInt *ret=DataArrayInt::New(); + ret->alloc((int)nodes.size(),1); + std::copy(nodes.begin(),nodes.end(),ret->getPointer()); + return SWIG_NewPointerObj(SWIG_as_voidptr(ret),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 ); + } + PyObject *findNodesOnPlane(PyObject *pt, PyObject *vec, double eps) const throw(INTERP_KERNEL::Exception) + { + int spaceDim=self->getSpaceDimension(); + double val,val2; + DataArrayDouble *a,*a2; + DataArrayDoubleTuple *aa,*aa2; + std::vector<double> bb,bb2; + int sw; + const char msg[]="Python wrap of MEDCouplingPointSet::findNodesOnPlane : 1st paramater for point."; + const char msg2[]="Python wrap of MEDCouplingPointSet::findNodesOnPlane : 2nd paramater for vector."; + const double *p=convertObjToPossibleCpp5_Safe(pt,sw,val,a,aa,bb,msg,1,spaceDim,true); + const double *v=convertObjToPossibleCpp5_Safe(vec,sw,val2,a2,aa2,bb2,msg2,1,spaceDim,true); + std::vector<int> nodes; + self->findNodesOnPlane(p,v,eps,nodes); + DataArrayInt *ret=DataArrayInt::New(); + ret->alloc((int)nodes.size(),1); + std::copy(nodes.begin(),nodes.end(),ret->getPointer()); + return SWIG_NewPointerObj(SWIG_as_voidptr(ret),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 ); + } + + PyObject *getNodeIdsNearPoint(PyObject *pt, double eps) const throw(INTERP_KERNEL::Exception) + { + double val; + DataArrayDouble *a; + DataArrayDoubleTuple *aa; + std::vector<double> bb; + int sw; + int spaceDim=self->getSpaceDimension(); + const char msg[]="Python wrap of MEDCouplingPointSet::getNodeIdsNearPoint : "; + const double *pos=convertObjToPossibleCpp5_Safe(pt,sw,val,a,aa,bb,msg,1,spaceDim,true); + DataArrayInt *ret=self->getNodeIdsNearPoint(pos,eps); + return SWIG_NewPointerObj(SWIG_as_voidptr(ret),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 ); + } + + PyObject *getNodeIdsNearPoints(PyObject *pt, int nbOfPoints, double eps) const throw(INTERP_KERNEL::Exception) + { + DataArrayInt *c=0,*cI=0; + // + double val; + DataArrayDouble *a; + DataArrayDoubleTuple *aa; + std::vector<double> bb; + int sw; + int spaceDim=self->getSpaceDimension(); + const char msg[]="Python wrap of MEDCouplingPointSet::getNodeIdsNearPoints : "; + const double *pos=convertObjToPossibleCpp5_Safe(pt,sw,val,a,aa,bb,msg,nbOfPoints,spaceDim,true); + self->getNodeIdsNearPoints(pos,nbOfPoints,eps,c,cI); + PyObject *ret=PyTuple_New(2); + PyTuple_SetItem(ret,0,SWIG_NewPointerObj(SWIG_as_voidptr(c),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 )); + PyTuple_SetItem(ret,1,SWIG_NewPointerObj(SWIG_as_voidptr(cI),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 )); + return ret; + } + + PyObject *getNodeIdsNearPoints(PyObject *pt, double eps) const throw(INTERP_KERNEL::Exception) + { + DataArrayInt *c=0,*cI=0; + int spaceDim=self->getSpaceDimension(); + double val; + DataArrayDouble *a; + DataArrayDoubleTuple *aa; + std::vector<double> bb; + int sw; + int nbOfTuples=-1; + const double *ptPtr=convertObjToPossibleCpp5_Safe2(pt,sw,val,a,aa,bb,"Python wrap of MEDCouplingUMesh::getNodeIdsNearPoints",spaceDim,true,nbOfTuples); + self->getNodeIdsNearPoints(ptPtr,nbOfTuples,eps,c,cI); + // + PyObject *ret=PyTuple_New(2); + PyTuple_SetItem(ret,0,SWIG_NewPointerObj(SWIG_as_voidptr(c),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 )); + PyTuple_SetItem(ret,1,SWIG_NewPointerObj(SWIG_as_voidptr(cI),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 )); + return ret; + } + + PyObject *getCellsInBoundingBox(PyObject *bbox, double eps) const throw(INTERP_KERNEL::Exception) + { + double val; + DataArrayDouble *a; + DataArrayDoubleTuple *aa; + std::vector<double> bb; + int sw; + int spaceDim=self->getSpaceDimension(); + const char msg[]="Python wrap of MEDCouplingPointSet::getCellsInBoundingBox : "; + const double *tmp=convertObjToPossibleCpp5_Safe(bbox,sw,val,a,aa,bb,msg,spaceDim,2,true); + // + DataArrayInt *elems=self->getCellsInBoundingBox(tmp,eps); + return SWIG_NewPointerObj(SWIG_as_voidptr(elems),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 ); + } + + void duplicateNodesInCoords(PyObject *li) throw(INTERP_KERNEL::Exception) + { + int sw; + int singleVal; + std::vector<int> multiVal; + std::pair<int, std::pair<int,int> > slic; + ParaMEDMEM::DataArrayInt *daIntTyypp=0; + convertObjToPossibleCpp2(li,self->getNumberOfNodes(),sw,singleVal,multiVal,slic,daIntTyypp); + switch(sw) + { + case 1: + return self->duplicateNodesInCoords(&singleVal,&singleVal+1); + case 2: + return self->duplicateNodesInCoords(&multiVal[0],&multiVal[0]+multiVal.size()); + case 4: + return self->duplicateNodesInCoords(daIntTyypp->begin(),daIntTyypp->end()); + default: + throw INTERP_KERNEL::Exception("MEDCouplingPointSet::duplicateNodesInCoords : unrecognized type entered, expected list of int, tuple of int or DataArrayInt !"); + } + } + + virtual PyObject *findCommonCells(int compType, int startCellId=0) const throw(INTERP_KERNEL::Exception) + { + DataArrayInt *v0=0,*v1=0; + self->findCommonCells(compType,startCellId,v0,v1); + PyObject *res = PyList_New(2); + PyList_SetItem(res,0,SWIG_NewPointerObj(SWIG_as_voidptr(v0),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 )); + PyList_SetItem(res,1,SWIG_NewPointerObj(SWIG_as_voidptr(v1),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 )); + return res; + } + + + virtual void renumberNodesInConn(PyObject *li) throw(INTERP_KERNEL::Exception) + { + void *da=0; + int res1=SWIG_ConvertPtr(li,&da,SWIGTYPE_p_ParaMEDMEM__DataArrayInt, 0 | 0 ); + if (!SWIG_IsOK(res1)) + { + int size; + INTERP_KERNEL::AutoPtr<int> tmp=convertPyToNewIntArr2(li,&size); + self->renumberNodesInConn(tmp); + } + else + { + DataArrayInt *da2=reinterpret_cast< DataArrayInt * >(da); + if(!da2) + throw INTERP_KERNEL::Exception("Not null DataArrayInt instance expected !"); + da2->checkAllocated(); + self->renumberNodesInConn(da2->getConstPointer()); + } + } + + virtual PyObject *getNodeIdsInUse() const throw(INTERP_KERNEL::Exception) + { + int ret1=-1; + DataArrayInt *ret0=self->getNodeIdsInUse(ret1); + PyObject *ret=PyTuple_New(2); + PyTuple_SetItem(ret,0,SWIG_NewPointerObj(SWIG_as_voidptr(ret0),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 )); + PyTuple_SetItem(ret,1,PyInt_FromLong(ret1)); + return ret; + } + + virtual DataArrayInt *fillCellIdsToKeepFromNodeIds(PyObject *li, bool fullyIn) const + { + DataArrayInt *ret=0; + // + int szArr,sw,iTypppArr; + std::vector<int> stdvecTyyppArr; + const int *tmp=convertObjToPossibleCpp1_Safe(li,sw,szArr,iTypppArr,stdvecTyyppArr); + self->fillCellIdsToKeepFromNodeIds(tmp,tmp+szArr,fullyIn,ret); + return ret; + } + + virtual PyObject *mergeNodes(double precision) throw(INTERP_KERNEL::Exception) + { + bool ret1; + int ret2; + DataArrayInt *ret0=self->mergeNodes(precision,ret1,ret2); + PyObject *res = PyList_New(3); + PyList_SetItem(res,0,SWIG_NewPointerObj(SWIG_as_voidptr(ret0),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 )); + PyList_SetItem(res,1,SWIG_From_bool(ret1)); + PyList_SetItem(res,2,SWIG_From_int(ret2)); + return res; + } + + virtual PyObject *mergeNodes2(double precision) throw(INTERP_KERNEL::Exception) + { + bool ret1; + int ret2; + DataArrayInt *ret0=self->mergeNodes2(precision,ret1,ret2); + PyObject *res = PyList_New(3); + PyList_SetItem(res,0,SWIG_NewPointerObj(SWIG_as_voidptr(ret0),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 )); + PyList_SetItem(res,1,SWIG_From_bool(ret1)); + PyList_SetItem(res,2,SWIG_From_int(ret2)); + return res; + } + + DataArrayInt *getCellIdsLyingOnNodes(PyObject *li, bool fullyIn) const throw(INTERP_KERNEL::Exception) + { + void *da=0; + int res1=SWIG_ConvertPtr(li,&da,SWIGTYPE_p_ParaMEDMEM__DataArrayInt, 0 | 0 ); + if (!SWIG_IsOK(res1)) + { + int size; + INTERP_KERNEL::AutoPtr<int> tmp=convertPyToNewIntArr2(li,&size); + return self->getCellIdsLyingOnNodes(tmp,((const int *)tmp)+size,fullyIn); + } + else + { + DataArrayInt *da2=reinterpret_cast< DataArrayInt * >(da); + if(!da2) + throw INTERP_KERNEL::Exception("Not null DataArrayInt instance expected !"); + da2->checkAllocated(); + return self->getCellIdsLyingOnNodes(da2->getConstPointer(),da2->getConstPointer()+da2->getNbOfElems(),fullyIn); + } + } + + MEDCouplingPointSet *__getitem__(PyObject *listOrDataArrI) throw(INTERP_KERNEL::Exception) + { + int sw; + int singleVal; + std::vector<int> multiVal; + std::pair<int, std::pair<int,int> > slic; + ParaMEDMEM::DataArrayInt *daIntTyypp=0; + int nbc=self->getNumberOfCells(); + convertObjToPossibleCpp2(listOrDataArrI,nbc,sw,singleVal,multiVal,slic,daIntTyypp); + switch(sw) + { + case 1: + { + if(singleVal>=nbc) + { + std::ostringstream oss; + oss << "Requesting for cell id " << singleVal << " having only " << nbc << " cells !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + if(singleVal>=0) + return self->buildPartOfMySelf(&singleVal,&singleVal+1,true); + else + { + if(nbc+singleVal>0) + { + int tmp=nbc+singleVal; + return self->buildPartOfMySelf(&tmp,&tmp+1,true); + } + else + { + std::ostringstream oss; + oss << "Requesting for cell id " << singleVal << " having only " << nbc << " cells !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + } + } + case 2: + { + return static_cast<MEDCouplingPointSet *>(self->buildPartOfMySelf(&multiVal[0],&multiVal[0]+multiVal.size(),true)); + } + case 3: + { + return self->buildPartOfMySelf2(slic.first,slic.second.first,slic.second.second,true); + } + case 4: + { + if(!daIntTyypp) + throw INTERP_KERNEL::Exception("MEDCouplingUMesh::__getitem__ : null instance has been given in input !"); + daIntTyypp->checkAllocated(); + return self->buildPartOfMySelf(daIntTyypp->begin(),daIntTyypp->end(),true); + } + default: + throw INTERP_KERNEL::Exception("MEDCouplingUMesh::__getitem__ : unrecognized type in input ! Possibilities are : int, list or tuple of int DataArrayInt instance !"); + } + } + + static void Rotate2DAlg(PyObject *center, double angle, int nbNodes, PyObject *coords) throw(INTERP_KERNEL::Exception) + { + int sz; + INTERP_KERNEL::AutoCPtr<double> c=convertPyToNewDblArr2(center,&sz); + INTERP_KERNEL::AutoCPtr<double> coo=convertPyToNewDblArr2(coords,&sz); + ParaMEDMEM::MEDCouplingPointSet::Rotate2DAlg(c,angle,nbNodes,coo); + for(int i=0;i<sz;i++) + PyList_SetItem(coords,i,PyFloat_FromDouble(coo[i])); + } + + static void Rotate2DAlg(PyObject *center, double angle, PyObject *coords) throw(INTERP_KERNEL::Exception) + { + int sz; + INTERP_KERNEL::AutoCPtr<double> c=convertPyToNewDblArr2(center,&sz); + int sw,nbNodes=0; + double val0; ParaMEDMEM::DataArrayDouble *val1=0; ParaMEDMEM::DataArrayDoubleTuple *val2=0; + std::vector<double> val3; + const double *coo=convertObjToPossibleCpp5_Safe2(coords,sw,val0,val1,val2,val3, + "Rotate2DAlg",2,true,nbNodes); + if(sw!=2 && sw!=3) + throw INTERP_KERNEL::Exception("Invalid call to MEDCouplingPointSet::Rotate2DAlg : try another overload method !"); + ParaMEDMEM::MEDCouplingPointSet::Rotate2DAlg(c,angle,nbNodes,const_cast<double *>(coo)); + } + + static void Rotate3DAlg(PyObject *center, PyObject *vect, double angle, int nbNodes, PyObject *coords) throw(INTERP_KERNEL::Exception) + { + int sz,sz2; + INTERP_KERNEL::AutoCPtr<double> c=convertPyToNewDblArr2(center,&sz); + INTERP_KERNEL::AutoCPtr<double> coo=convertPyToNewDblArr2(coords,&sz); + INTERP_KERNEL::AutoCPtr<double> v=convertPyToNewDblArr2(vect,&sz2); + ParaMEDMEM::MEDCouplingPointSet::Rotate3DAlg(c,v,angle,nbNodes,coo); + for(int i=0;i<sz;i++) + PyList_SetItem(coords,i,PyFloat_FromDouble(coo[i])); + } + + static void Rotate3DAlg(PyObject *center, PyObject *vect, double angle, PyObject *coords) throw(INTERP_KERNEL::Exception) + { + int sz,sz2; + INTERP_KERNEL::AutoCPtr<double> c=convertPyToNewDblArr2(center,&sz); + int sw,nbNodes=0; + double val0; ParaMEDMEM::DataArrayDouble *val1=0; ParaMEDMEM::DataArrayDoubleTuple *val2=0; + std::vector<double> val3; + const double *coo=convertObjToPossibleCpp5_Safe2(coords,sw,val0,val1,val2,val3, + "Rotate3DAlg",3,true,nbNodes); + if(sw!=2 && sw!=3) + throw INTERP_KERNEL::Exception("Invalid call to MEDCouplingPointSet::Rotate3DAlg : try another overload method !"); + INTERP_KERNEL::AutoCPtr<double> v=convertPyToNewDblArr2(vect,&sz2); + ParaMEDMEM::MEDCouplingPointSet::Rotate3DAlg(c,v,angle,nbNodes,const_cast<double *>(coo)); + } + } + }; + + //== MEDCouplingPointSet End + + class MEDCouplingUMeshCell + { + public: + INTERP_KERNEL::NormalizedCellType getType() const; + %extend + { + std::string __str__() const throw(INTERP_KERNEL::Exception) + { + return self->repr(); + } + + PyObject *getAllConn() const throw(INTERP_KERNEL::Exception) + { + int ret2; + const int *r=self->getAllConn(ret2); + PyObject *ret=PyTuple_New(ret2); + for(int i=0;i<ret2;i++) + PyTuple_SetItem(ret,i,PyInt_FromLong(r[i])); + return ret; + } + } + }; + + class MEDCouplingUMeshCellIterator + { + public: + %extend + { + PyObject *next() + { + MEDCouplingUMeshCell *ret=self->nextt(); + if(ret) + return SWIG_NewPointerObj(SWIG_as_voidptr(ret),SWIGTYPE_p_ParaMEDMEM__MEDCouplingUMeshCell,0|0); + else + { + PyErr_SetString(PyExc_StopIteration,"No more data."); + return 0; + } + } + } + }; + + class MEDCouplingUMeshCellByTypeIterator + { + public: + ~MEDCouplingUMeshCellByTypeIterator(); + %extend + { + PyObject *next() + { + MEDCouplingUMeshCellEntry *ret=self->nextt(); + if(ret) + return SWIG_NewPointerObj(SWIG_as_voidptr(ret),SWIGTYPE_p_ParaMEDMEM__MEDCouplingUMeshCellEntry,SWIG_POINTER_OWN | 0); + else + { + PyErr_SetString(PyExc_StopIteration,"No more data."); + return 0; + } + } + } + }; + + class MEDCouplingUMeshCellByTypeEntry + { + public: + ~MEDCouplingUMeshCellByTypeEntry(); + %extend + { + MEDCouplingUMeshCellByTypeIterator *__iter__() + { + return self->iterator(); + } + } + }; + + class MEDCouplingUMeshCellEntry + { + public: + INTERP_KERNEL::NormalizedCellType getType() const; + int getNumberOfElems() const; + %extend + { + MEDCouplingUMeshCellIterator *__iter__() + { + return self->iterator(); + } + } + }; + + //== MEDCouplingUMesh + + class MEDCouplingUMesh : public ParaMEDMEM::MEDCouplingPointSet + { + public: + static MEDCouplingUMesh *New() throw(INTERP_KERNEL::Exception); + static MEDCouplingUMesh *New(const char *meshName, int meshDim) throw(INTERP_KERNEL::Exception); + MEDCouplingUMesh *clone(bool recDeepCpy) const; + void checkCoherency() const throw(INTERP_KERNEL::Exception); + void setMeshDimension(int meshDim) throw(INTERP_KERNEL::Exception); + void allocateCells(int nbOfCells=0) throw(INTERP_KERNEL::Exception); + void finishInsertingCells() throw(INTERP_KERNEL::Exception); + MEDCouplingUMeshCellByTypeEntry *cellsByType() throw(INTERP_KERNEL::Exception); + void setConnectivity(DataArrayInt *conn, DataArrayInt *connIndex, bool isComputingTypes=true) throw(INTERP_KERNEL::Exception); + INTERP_KERNEL::NormalizedCellType getTypeOfCell(int cellId) const throw(INTERP_KERNEL::Exception); + void setPartOfMySelf2(int start, int end, int step, const MEDCouplingUMesh& otherOnSameCoordsThanThis) throw(INTERP_KERNEL::Exception); + int getMeshLength() const throw(INTERP_KERNEL::Exception); + void computeTypes() throw(INTERP_KERNEL::Exception); + std::string reprConnectivityOfThis() const throw(INTERP_KERNEL::Exception); + MEDCouplingUMesh *buildSetInstanceFromThis(int spaceDim) const throw(INTERP_KERNEL::Exception); + //tools + DataArrayInt *conformize2D(double eps) throw(INTERP_KERNEL::Exception); + DataArrayInt *colinearize2D(double eps) throw(INTERP_KERNEL::Exception); + void shiftNodeNumbersInConn(int delta) throw(INTERP_KERNEL::Exception); + std::vector<bool> getQuadraticStatus() const throw(INTERP_KERNEL::Exception); + DataArrayInt *findCellIdsOnBoundary() const throw(INTERP_KERNEL::Exception); + MEDCouplingUMesh *computeSkin() const throw(INTERP_KERNEL::Exception); + bool checkConsecutiveCellTypes() const throw(INTERP_KERNEL::Exception); + bool checkConsecutiveCellTypesForMEDFileFrmt() const throw(INTERP_KERNEL::Exception); + DataArrayInt *rearrange2ConsecutiveCellTypes() throw(INTERP_KERNEL::Exception); + DataArrayInt *sortCellsInMEDFileFrmt() throw(INTERP_KERNEL::Exception); + DataArrayInt *getRenumArrForMEDFileFrmt() const throw(INTERP_KERNEL::Exception); + DataArrayInt *convertCellArrayPerGeoType(const DataArrayInt *da) const throw(INTERP_KERNEL::Exception); + MEDCouplingUMesh *buildDescendingConnectivity(DataArrayInt *desc, DataArrayInt *descIndx, DataArrayInt *revDesc, DataArrayInt *revDescIndx) const throw(INTERP_KERNEL::Exception); + MEDCouplingUMesh *buildDescendingConnectivity2(DataArrayInt *desc, DataArrayInt *descIndx, DataArrayInt *revDesc, DataArrayInt *revDescIndx) const throw(INTERP_KERNEL::Exception); + MEDCouplingUMesh *explode3DMeshTo1D(DataArrayInt *desc, DataArrayInt *descIndx, DataArrayInt *revDesc, DataArrayInt *revDescIndx) const throw(INTERP_KERNEL::Exception); + void orientCorrectlyPolyhedrons() throw(INTERP_KERNEL::Exception); + bool isPresenceOfQuadratic() const throw(INTERP_KERNEL::Exception); + bool isFullyQuadratic() const throw(INTERP_KERNEL::Exception); + MEDCouplingFieldDouble *buildDirectionVectorField() const throw(INTERP_KERNEL::Exception); + bool isContiguous1D() const throw(INTERP_KERNEL::Exception); + void tessellate2D(double eps) throw(INTERP_KERNEL::Exception); + void tessellate2DCurve(double eps) throw(INTERP_KERNEL::Exception); + void convertQuadraticCellsToLinear() throw(INTERP_KERNEL::Exception); + DataArrayInt *convertLinearCellsToQuadratic(int conversionType=0) throw(INTERP_KERNEL::Exception); + void convertDegeneratedCells() throw(INTERP_KERNEL::Exception); + bool areOnlySimplexCells() const throw(INTERP_KERNEL::Exception); + MEDCouplingFieldDouble *getEdgeRatioField() const throw(INTERP_KERNEL::Exception); + MEDCouplingFieldDouble *getAspectRatioField() const throw(INTERP_KERNEL::Exception); + MEDCouplingFieldDouble *getWarpField() const throw(INTERP_KERNEL::Exception); + MEDCouplingFieldDouble *getSkewField() const throw(INTERP_KERNEL::Exception); + DataArrayDouble *computePlaneEquationOf3DFaces() const throw(INTERP_KERNEL::Exception); + DataArrayInt *convexEnvelop2D() throw(INTERP_KERNEL::Exception); + std::string cppRepr() const throw(INTERP_KERNEL::Exception); + DataArrayInt *findAndCorrectBadOriented3DExtrudedCells() throw(INTERP_KERNEL::Exception); + DataArrayInt *findAndCorrectBadOriented3DCells() throw(INTERP_KERNEL::Exception); + ParaMEDMEM::MEDCoupling1GTUMesh *convertIntoSingleGeoTypeMesh() const throw(INTERP_KERNEL::Exception); + DataArrayInt *convertNodalConnectivityToStaticGeoTypeMesh() const throw(INTERP_KERNEL::Exception); + DataArrayInt *buildUnionOf2DMesh() const throw(INTERP_KERNEL::Exception); + DataArrayInt *buildUnionOf3DMesh() const throw(INTERP_KERNEL::Exception); + MEDCouplingSkyLineArray *generateGraph() const throw(INTERP_KERNEL::Exception); + DataArrayInt *orderConsecutiveCells1D() const throw(INTERP_KERNEL::Exception); + DataArrayDouble *getBoundingBoxForBBTreeFast() const throw(INTERP_KERNEL::Exception); + DataArrayDouble *getBoundingBoxForBBTree2DQuadratic(double arcDetEps=1e-12) const throw(INTERP_KERNEL::Exception); + DataArrayDouble *getBoundingBoxForBBTree1DQuadratic(double arcDetEps=1e-12) const throw(INTERP_KERNEL::Exception); + void changeOrientationOfCells() throw(INTERP_KERNEL::Exception); + int split2DCells(const DataArrayInt *desc, const DataArrayInt *descI, const DataArrayInt *subNodesInSeg, const DataArrayInt *subNodesInSegI, const DataArrayInt *midOpt=0, const DataArrayInt *midOptI=0) throw(INTERP_KERNEL::Exception); + static MEDCouplingUMesh *Build0DMeshFromCoords(DataArrayDouble *da) throw(INTERP_KERNEL::Exception); + static MEDCouplingUMesh *MergeUMeshes(const MEDCouplingUMesh *mesh1, const MEDCouplingUMesh *mesh2) throw(INTERP_KERNEL::Exception); + static MEDCouplingUMesh *MergeUMeshesOnSameCoords(const MEDCouplingUMesh *mesh1, const MEDCouplingUMesh *mesh2) throw(INTERP_KERNEL::Exception); + static DataArrayInt *ComputeSpreadZoneGradually(const DataArrayInt *arrIn, const DataArrayInt *arrIndxIn) throw(INTERP_KERNEL::Exception); + static DataArrayInt *ComputeRangesFromTypeDistribution(const std::vector<int>& code) throw(INTERP_KERNEL::Exception); + %extend { + MEDCouplingUMesh() throw(INTERP_KERNEL::Exception) + { + return MEDCouplingUMesh::New(); + } + + MEDCouplingUMesh(const char *meshName, int meshDim) throw(INTERP_KERNEL::Exception) + { + return MEDCouplingUMesh::New(meshName,meshDim); + } + + // serialization + static PyObject *___new___(PyObject *cls, PyObject *args) throw(INTERP_KERNEL::Exception) + { + return NewMethWrapCallInitOnlyIfEmptyDictInInput(cls,args,"MEDCouplingUMesh"); + } + + std::string __str__() const throw(INTERP_KERNEL::Exception) + { + return self->simpleRepr(); + } + + std::string __repr__() const throw(INTERP_KERNEL::Exception) + { + std::ostringstream oss; + self->reprQuickOverview(oss); + return oss.str(); + } + + MEDCouplingUMeshCellIterator *__iter__() throw(INTERP_KERNEL::Exception) + { + return self->cellIterator(); + } + + PyObject *getAllGeoTypesSorted() const throw(INTERP_KERNEL::Exception) + { + std::vector<INTERP_KERNEL::NormalizedCellType> result=self->getAllGeoTypesSorted(); + std::vector<INTERP_KERNEL::NormalizedCellType>::const_iterator iL=result.begin(); + PyObject *res=PyList_New(result.size()); + for(int i=0;iL!=result.end(); i++, iL++) + PyList_SetItem(res,i,PyInt_FromLong(*iL)); + return res; + } + + void setPartOfMySelf(PyObject *li, const MEDCouplingUMesh& otherOnSameCoordsThanThis) throw(INTERP_KERNEL::Exception) + { + int sw; + int singleVal; + std::vector<int> multiVal; + std::pair<int, std::pair<int,int> > slic; + ParaMEDMEM::DataArrayInt *daIntTyypp=0; + int nbc=self->getNumberOfCells(); + convertObjToPossibleCpp2(li,nbc,sw,singleVal,multiVal,slic,daIntTyypp); + switch(sw) + { + case 1: + { + if(singleVal>=nbc) + { + std::ostringstream oss; + oss << "Requesting for cell id " << singleVal << " having only " << nbc << " cells !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + if(singleVal>=0) + { + self->setPartOfMySelf(&singleVal,&singleVal+1,otherOnSameCoordsThanThis); + break; + } + else + { + if(nbc+singleVal>0) + { + int tmp=nbc+singleVal; + self->setPartOfMySelf(&tmp,&tmp+1,otherOnSameCoordsThanThis); + break; + } + else + { + std::ostringstream oss; + oss << "Requesting for cell id " << singleVal << " having only " << nbc << " cells !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + } + } + case 2: + { + self->setPartOfMySelf(&multiVal[0],&multiVal[0]+multiVal.size(),otherOnSameCoordsThanThis); + break; + } + case 4: + { + if(!daIntTyypp) + throw INTERP_KERNEL::Exception("MEDCouplingUMesh::setPartOfMySelf : null instance has been given in input !"); + daIntTyypp->checkAllocated(); + self->setPartOfMySelf(daIntTyypp->begin(),daIntTyypp->end(),otherOnSameCoordsThanThis); + break; + } + default: + throw INTERP_KERNEL::Exception("MEDCouplingUMesh::setPartOfMySelf : unrecognized type in input ! Possibilities are : int, list or tuple of int DataArrayInt instance !"); + } + } + + void __setitem__(PyObject *li, const MEDCouplingUMesh& otherOnSameCoordsThanThis) throw(INTERP_KERNEL::Exception) + { + int sw; + int singleVal; + std::vector<int> multiVal; + std::pair<int, std::pair<int,int> > slic; + ParaMEDMEM::DataArrayInt *daIntTyypp=0; + int nbc=self->getNumberOfCells(); + convertObjToPossibleCpp2(li,nbc,sw,singleVal,multiVal,slic,daIntTyypp); + switch(sw) + { + case 1: + { + if(singleVal>=nbc) + { + std::ostringstream oss; + oss << "Requesting for cell id " << singleVal << " having only " << nbc << " cells !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + if(singleVal>=0) + { + self->setPartOfMySelf(&singleVal,&singleVal+1,otherOnSameCoordsThanThis); + break; + } + else + { + if(nbc+singleVal>0) + { + int tmp=nbc+singleVal; + self->setPartOfMySelf(&tmp,&tmp+1,otherOnSameCoordsThanThis); + break; + } + else + { + std::ostringstream oss; + oss << "Requesting for cell id " << singleVal << " having only " << nbc << " cells !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + } + } + case 2: + { + self->setPartOfMySelf(&multiVal[0],&multiVal[0]+multiVal.size(),otherOnSameCoordsThanThis); + break; + } + case 3: + { + self->setPartOfMySelf2(slic.first,slic.second.first,slic.second.second,otherOnSameCoordsThanThis); + break; + } + case 4: + { + if(!daIntTyypp) + throw INTERP_KERNEL::Exception("MEDCouplingUMesh::__setitem__ : null instance has been given in input !"); + daIntTyypp->checkAllocated(); + self->setPartOfMySelf(daIntTyypp->begin(),daIntTyypp->end(),otherOnSameCoordsThanThis); + break; + } + default: + throw INTERP_KERNEL::Exception("MEDCouplingUMesh::__setitem__ : unrecognized type in input ! Possibilities are : int, list or tuple of int, slice, DataArrayInt instance !"); + } + } + + void insertNextCell(INTERP_KERNEL::NormalizedCellType type, int size, PyObject *li) throw(INTERP_KERNEL::Exception) + { + int szArr,sw,iTypppArr; + std::vector<int> stdvecTyyppArr; + const int *tmp=convertObjToPossibleCpp1_Safe(li,sw,szArr,iTypppArr,stdvecTyyppArr); + if(size>szArr) + { + std::ostringstream oss; oss << "Wrap of MEDCouplingUMesh::insertNextCell : request of connectivity with length " << size << " whereas the length of input is " << szArr << " !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + self->insertNextCell(type,size,tmp); + } + + void insertNextCell(INTERP_KERNEL::NormalizedCellType type, PyObject *li) throw(INTERP_KERNEL::Exception) + { + int szArr,sw,iTypppArr; + std::vector<int> stdvecTyyppArr; + const int *tmp=convertObjToPossibleCpp1_Safe(li,sw,szArr,iTypppArr,stdvecTyyppArr); + self->insertNextCell(type,szArr,tmp); + } + + DataArrayInt *getNodalConnectivity() throw(INTERP_KERNEL::Exception) + { + DataArrayInt *ret=self->getNodalConnectivity(); + if(ret) + ret->incrRef(); + return ret; + } + DataArrayInt *getNodalConnectivityIndex() throw(INTERP_KERNEL::Exception) + { + DataArrayInt *ret=self->getNodalConnectivityIndex(); + if(ret) + ret->incrRef(); + return ret; + } + + static PyObject *ComputeSpreadZoneGraduallyFromSeed(PyObject *seed, const DataArrayInt *arrIn, const DataArrayInt *arrIndxIn, int nbOfDepthPeeling=-1) throw(INTERP_KERNEL::Exception) + { + int szArr,sw,iTypppArr; + std::vector<int> stdvecTyyppArr; + const int *seedPtr=convertObjToPossibleCpp1_Safe(seed,sw,szArr,iTypppArr,stdvecTyyppArr); + int nbOfDepthPeelingPerformed=0; + DataArrayInt *ret0=MEDCouplingUMesh::ComputeSpreadZoneGraduallyFromSeed(seedPtr,seedPtr+szArr,arrIn,arrIndxIn,nbOfDepthPeeling,nbOfDepthPeelingPerformed); + PyObject *res=PyTuple_New(2); + PyTuple_SetItem(res,0,SWIG_NewPointerObj(SWIG_as_voidptr(ret0),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 )); + PyTuple_SetItem(res,1,PyInt_FromLong(nbOfDepthPeelingPerformed)); + return res; + } + + static PyObject *FindCommonCellsAlg(int compType, int startCellId, const DataArrayInt *nodal, const DataArrayInt *nodalI, const DataArrayInt *revNodal, const DataArrayInt *revNodalI) throw(INTERP_KERNEL::Exception) + { + DataArrayInt *v0=0,*v1=0; + MEDCouplingUMesh::FindCommonCellsAlg(compType,startCellId,nodal,nodalI,revNodal,revNodalI,v0,v1); + PyObject *res = PyList_New(2); + PyList_SetItem(res,0,SWIG_NewPointerObj(SWIG_as_voidptr(v0),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 )); + PyList_SetItem(res,1,SWIG_NewPointerObj(SWIG_as_voidptr(v1),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 )); + return res; + } + + PyObject *distanceToPoint(PyObject *point) const throw(INTERP_KERNEL::Exception) + { + double val; + DataArrayDouble *a; + DataArrayDoubleTuple *aa; + std::vector<double> bb; + int sw; + int nbOfCompo=self->getSpaceDimension(); + const double *pt=convertObjToPossibleCpp5_Safe(point,sw,val,a,aa,bb,"Python wrap of MEDCouplingUMesh::distanceToPoint",1,nbOfCompo,true); + // + int cellId=-1; + double ret0=self->distanceToPoint(pt,pt+nbOfCompo,cellId); + PyObject *ret=PyTuple_New(2); + PyTuple_SetItem(ret,0,PyFloat_FromDouble(ret0)); + PyTuple_SetItem(ret,1,PyInt_FromLong(cellId)); + return ret; + } + + PyObject *distanceToPoints(const DataArrayDouble *pts) const throw(INTERP_KERNEL::Exception) + { + DataArrayInt *ret1=0; + DataArrayDouble *ret0=self->distanceToPoints(pts,ret1); + PyObject *ret=PyTuple_New(2); + PyTuple_SetItem(ret,0,SWIG_NewPointerObj(SWIG_as_voidptr(ret0),SWIGTYPE_p_ParaMEDMEM__DataArrayDouble, SWIG_POINTER_OWN | 0 )); + PyTuple_SetItem(ret,1,SWIG_NewPointerObj(SWIG_as_voidptr(ret1),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 )); + return ret; + } + + PyObject *tetrahedrize(int policy) throw(INTERP_KERNEL::Exception) + { + int ret2(-1); + DataArrayInt *ret1(0); + MEDCoupling1SGTUMesh *ret0(self->tetrahedrize(policy,ret1,ret2)); + PyObject *ret=PyTuple_New(3); + PyTuple_SetItem(ret,0,SWIG_NewPointerObj(SWIG_as_voidptr(ret0),SWIGTYPE_p_ParaMEDMEM__MEDCoupling1SGTUMesh, SWIG_POINTER_OWN | 0 )); + PyTuple_SetItem(ret,1,SWIG_NewPointerObj(SWIG_as_voidptr(ret1),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 )); + PyTuple_SetItem(ret,2,PyInt_FromLong(ret2)); + return ret; + } + + PyObject *checkButterflyCells(double eps=1e-12) throw(INTERP_KERNEL::Exception) + { + std::vector<int> cells; + self->checkButterflyCells(cells,eps); + DataArrayInt *ret=DataArrayInt::New(); + ret->alloc((int)cells.size(),1); + std::copy(cells.begin(),cells.end(),ret->getPointer()); + return SWIG_NewPointerObj(SWIG_as_voidptr(ret),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 ); + } + + PyObject *splitByType() const throw(INTERP_KERNEL::Exception) + { + std::vector<MEDCouplingUMesh *> ms=self->splitByType(); + int sz=ms.size(); + PyObject *ret = PyList_New(sz); + for(int i=0;i<sz;i++) + PyList_SetItem(ret,i,SWIG_NewPointerObj(SWIG_as_voidptr(ms[i]),SWIGTYPE_p_ParaMEDMEM__MEDCouplingUMesh, SWIG_POINTER_OWN | 0 )); + return ret; + } + + PyObject *partitionBySpreadZone() const throw(INTERP_KERNEL::Exception) + { + std::vector<DataArrayInt *> retCpp=self->partitionBySpreadZone(); + int sz=retCpp.size(); + PyObject *ret=PyList_New(sz); + for(int i=0;i<sz;i++) + PyList_SetItem(ret,i,SWIG_NewPointerObj(SWIG_as_voidptr(retCpp[i]),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 )); + return ret; + } + + PyObject *keepSpecifiedCells(INTERP_KERNEL::NormalizedCellType type, PyObject *ids) const throw(INTERP_KERNEL::Exception) + { + int size; + INTERP_KERNEL::AutoPtr<int> tmp=convertPyToNewIntArr2(ids,&size); + MEDCouplingUMesh *ret=self->keepSpecifiedCells(type,tmp,tmp+size); + return SWIG_NewPointerObj(SWIG_as_voidptr(ret),SWIGTYPE_p_ParaMEDMEM__MEDCouplingUMesh, SWIG_POINTER_OWN | 0 ); + } + + bool checkConsecutiveCellTypesAndOrder(PyObject *li) const throw(INTERP_KERNEL::Exception) + { + int sz; + INTERP_KERNEL::AutoPtr<INTERP_KERNEL::NormalizedCellType> order=(INTERP_KERNEL::NormalizedCellType *)convertPyToNewIntArr2(li,&sz); + bool ret=self->checkConsecutiveCellTypesAndOrder(order,order+sz); + return ret; + } + + DataArrayInt *getRenumArrForConsecutiveCellTypesSpec(PyObject *li) const throw(INTERP_KERNEL::Exception) + { + int sz; + INTERP_KERNEL::AutoPtr<INTERP_KERNEL::NormalizedCellType> order=(INTERP_KERNEL::NormalizedCellType *)convertPyToNewIntArr2(li,&sz); + DataArrayInt *ret=self->getRenumArrForConsecutiveCellTypesSpec(order,(INTERP_KERNEL::NormalizedCellType *)order+sz); + return ret; + } + + PyObject *findNodesToDuplicate(const MEDCouplingUMesh& otherDimM1OnSameCoords) const throw(INTERP_KERNEL::Exception) + { + DataArrayInt *tmp0=0,*tmp1=0,*tmp2=0; + self->findNodesToDuplicate(otherDimM1OnSameCoords,tmp0,tmp1,tmp2); + PyObject *ret=PyTuple_New(3); + PyTuple_SetItem(ret,0,SWIG_NewPointerObj(SWIG_as_voidptr(tmp0),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 )); + PyTuple_SetItem(ret,1,SWIG_NewPointerObj(SWIG_as_voidptr(tmp1),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 )); + PyTuple_SetItem(ret,2,SWIG_NewPointerObj(SWIG_as_voidptr(tmp2),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 )); + return ret; + } + + PyObject *findCellIdsLyingOn(const MEDCouplingUMesh& otherDimM1OnSameCoords) const throw(INTERP_KERNEL::Exception) + { + DataArrayInt *tmp0=0,*tmp1=0; + self->findCellIdsLyingOn(otherDimM1OnSameCoords,tmp0,tmp1); + PyObject *ret=PyTuple_New(2); + PyTuple_SetItem(ret,0,SWIG_NewPointerObj(SWIG_as_voidptr(tmp0),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 )); + PyTuple_SetItem(ret,1,SWIG_NewPointerObj(SWIG_as_voidptr(tmp1),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 )); + return ret; + } + + void duplicateNodes(PyObject *li) throw(INTERP_KERNEL::Exception) + { + int sw; + int singleVal; + std::vector<int> multiVal; + std::pair<int, std::pair<int,int> > slic; + ParaMEDMEM::DataArrayInt *daIntTyypp=0; + convertObjToPossibleCpp2(li,self->getNumberOfNodes(),sw,singleVal,multiVal,slic,daIntTyypp); + switch(sw) + { + case 1: + return self->duplicateNodes(&singleVal,&singleVal+1); + case 2: + return self->duplicateNodes(&multiVal[0],&multiVal[0]+multiVal.size()); + case 4: + return self->duplicateNodes(daIntTyypp->begin(),daIntTyypp->end()); + default: + throw INTERP_KERNEL::Exception("MEDCouplingUMesh::duplicateNodes : unrecognized type entered, expected list of int, tuple of int or DataArrayInt !"); + } + } + + void duplicateNodesInConn(PyObject *li, int offset) throw(INTERP_KERNEL::Exception) + { + int sw; + int singleVal; + std::vector<int> multiVal; + std::pair<int, std::pair<int,int> > slic; + ParaMEDMEM::DataArrayInt *daIntTyypp=0; + convertObjToPossibleCpp2(li,self->getNumberOfNodes(),sw,singleVal,multiVal,slic,daIntTyypp); + switch(sw) + { + case 1: + return self->duplicateNodesInConn(&singleVal,&singleVal+1,offset); + case 2: + return self->duplicateNodesInConn(&multiVal[0],&multiVal[0]+multiVal.size(),offset); + case 4: + return self->duplicateNodesInConn(daIntTyypp->begin(),daIntTyypp->end(),offset); + default: + throw INTERP_KERNEL::Exception("MEDCouplingUMesh::duplicateNodesInConn : unrecognized type entered, expected list of int, tuple of int or DataArrayInt !"); + } + } + + PyObject *getLevArrPerCellTypes(PyObject *li) const throw(INTERP_KERNEL::Exception) + { + int sz; + INTERP_KERNEL::AutoPtr<INTERP_KERNEL::NormalizedCellType> order=(INTERP_KERNEL::NormalizedCellType *)convertPyToNewIntArr2(li,&sz); + DataArrayInt *tmp0,*tmp1=0; + tmp0=self->getLevArrPerCellTypes(order,(INTERP_KERNEL::NormalizedCellType *)order+sz,tmp1); + PyObject *ret=PyTuple_New(2); + PyTuple_SetItem(ret,0,SWIG_NewPointerObj(SWIG_as_voidptr(tmp0),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 )); + PyTuple_SetItem(ret,1,SWIG_NewPointerObj(SWIG_as_voidptr(tmp1),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 )); + return ret; + } + + PyObject *convertNodalConnectivityToDynamicGeoTypeMesh() const throw(INTERP_KERNEL::Exception) + { + DataArrayInt *ret0=0,*ret1=0; + self->convertNodalConnectivityToDynamicGeoTypeMesh(ret0,ret1); + PyObject *ret=PyTuple_New(2); + PyTuple_SetItem(ret,0,SWIG_NewPointerObj(SWIG_as_voidptr(ret0),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 )); + PyTuple_SetItem(ret,1,SWIG_NewPointerObj(SWIG_as_voidptr(ret1),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 )); + return ret; + } + + static PyObject *AggregateSortedByTypeMeshesOnSameCoords(PyObject *ms) throw(INTERP_KERNEL::Exception) + { + std::vector<const ParaMEDMEM::MEDCouplingUMesh *> meshes; + convertFromPyObjVectorOfObj<const ParaMEDMEM::MEDCouplingUMesh *>(ms,SWIGTYPE_p_ParaMEDMEM__MEDCouplingUMesh,"MEDCouplingUMesh",meshes); + DataArrayInt *ret1=0,*ret2=0; + MEDCouplingUMesh *ret0=MEDCouplingUMesh::AggregateSortedByTypeMeshesOnSameCoords(meshes,ret1,ret2); + PyObject *ret=PyTuple_New(3); + PyTuple_SetItem(ret,0,SWIG_NewPointerObj(SWIG_as_voidptr(ret0),SWIGTYPE_p_ParaMEDMEM__MEDCouplingUMesh, SWIG_POINTER_OWN | 0 )); + PyTuple_SetItem(ret,1,SWIG_NewPointerObj(SWIG_as_voidptr(ret1),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 )); + PyTuple_SetItem(ret,2,SWIG_NewPointerObj(SWIG_as_voidptr(ret2),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 )); + return ret; + } + + static PyObject *MergeUMeshesOnSameCoords(PyObject *ms) throw(INTERP_KERNEL::Exception) + { + std::vector<const ParaMEDMEM::MEDCouplingUMesh *> meshes; + convertFromPyObjVectorOfObj<const ParaMEDMEM::MEDCouplingUMesh *>(ms,SWIGTYPE_p_ParaMEDMEM__MEDCouplingUMesh,"MEDCouplingUMesh",meshes); + MEDCouplingUMesh *ret=MEDCouplingUMesh::MergeUMeshesOnSameCoords(meshes); + return convertMesh(ret, SWIG_POINTER_OWN | 0 ); + } + + static PyObject *FuseUMeshesOnSameCoords(PyObject *ms, int compType) throw(INTERP_KERNEL::Exception) + { + int sz; + std::vector<const MEDCouplingUMesh *> meshes; + convertFromPyObjVectorOfObj<const ParaMEDMEM::MEDCouplingUMesh *>(ms,SWIGTYPE_p_ParaMEDMEM__MEDCouplingUMesh,"MEDCouplingUMesh",meshes); + std::vector<DataArrayInt *> corr; + MEDCouplingUMesh *um=MEDCouplingUMesh::FuseUMeshesOnSameCoords(meshes,compType,corr); + sz=corr.size(); + PyObject *ret1=PyList_New(sz); + for(int i=0;i<sz;i++) + PyList_SetItem(ret1,i,SWIG_NewPointerObj(SWIG_as_voidptr(corr[i]),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 )); + PyObject *ret=PyList_New(2); + PyList_SetItem(ret,0,SWIG_NewPointerObj(SWIG_as_voidptr(um),SWIGTYPE_p_ParaMEDMEM__MEDCouplingUMesh, SWIG_POINTER_OWN | 0 )); + PyList_SetItem(ret,1,ret1); + return ret; + } + + static void PutUMeshesOnSameAggregatedCoords(PyObject *ms) throw(INTERP_KERNEL::Exception) + { + std::vector<MEDCouplingUMesh *> meshes; + convertFromPyObjVectorOfObj<ParaMEDMEM::MEDCouplingUMesh *>(ms,SWIGTYPE_p_ParaMEDMEM__MEDCouplingUMesh,"MEDCouplingUMesh",meshes); + MEDCouplingUMesh::PutUMeshesOnSameAggregatedCoords(meshes); + } + + static void MergeNodesOnUMeshesSharingSameCoords(PyObject *ms, double eps) throw(INTERP_KERNEL::Exception) + { + std::vector<MEDCouplingUMesh *> meshes; + convertFromPyObjVectorOfObj<ParaMEDMEM::MEDCouplingUMesh *>(ms,SWIGTYPE_p_ParaMEDMEM__MEDCouplingUMesh,"MEDCouplingUMesh",meshes); + MEDCouplingUMesh::MergeNodesOnUMeshesSharingSameCoords(meshes,eps); + } + + static bool RemoveIdsFromIndexedArrays(PyObject *li, DataArrayInt *arr, DataArrayInt *arrIndx, int offsetForRemoval=0) throw(INTERP_KERNEL::Exception) + { + int sw; + int singleVal; + std::vector<int> multiVal; + std::pair<int, std::pair<int,int> > slic; + ParaMEDMEM::DataArrayInt *daIntTyypp=0; + if(!arrIndx) + throw INTERP_KERNEL::Exception("MEDCouplingUMesh::RemoveIdsFromIndexedArrays : null pointer as arrIndex !"); + convertObjToPossibleCpp2(li,arrIndx->getNumberOfTuples()-1,sw,singleVal,multiVal,slic,daIntTyypp); + switch(sw) + { + case 1: + return MEDCouplingUMesh::RemoveIdsFromIndexedArrays(&singleVal,&singleVal+1,arr,arrIndx,offsetForRemoval); + case 2: + return MEDCouplingUMesh::RemoveIdsFromIndexedArrays(&multiVal[0],&multiVal[0]+multiVal.size(),arr,arrIndx,offsetForRemoval); + case 4: + return MEDCouplingUMesh::RemoveIdsFromIndexedArrays(daIntTyypp->begin(),daIntTyypp->end(),arr,arrIndx,offsetForRemoval); + default: + throw INTERP_KERNEL::Exception("MEDCouplingUMesh::RemoveIdsFromIndexedArrays : unrecognized type entered, expected list of int, tuple of int or DataArrayInt !"); + } + } + + static PyObject *ExtractFromIndexedArrays(PyObject *li, const DataArrayInt *arrIn, const DataArrayInt *arrIndxIn) throw(INTERP_KERNEL::Exception) + { + DataArrayInt *arrOut=0,*arrIndexOut=0; + int sw; + int singleVal; + std::vector<int> multiVal; + std::pair<int, std::pair<int,int> > slic; + ParaMEDMEM::DataArrayInt *daIntTyypp=0; + if(!arrIndxIn) + throw INTERP_KERNEL::Exception("MEDCouplingUMesh::ExtractFromIndexedArrays : null pointer as arrIndxIn !"); + convertObjToPossibleCpp2(li,arrIndxIn->getNumberOfTuples()-1,sw,singleVal,multiVal,slic,daIntTyypp); + switch(sw) + { + case 1: + { + MEDCouplingUMesh::ExtractFromIndexedArrays(&singleVal,&singleVal+1,arrIn,arrIndxIn,arrOut,arrIndexOut); + break; + } + case 2: + { + MEDCouplingUMesh::ExtractFromIndexedArrays(&multiVal[0],&multiVal[0]+multiVal.size(),arrIn,arrIndxIn,arrOut,arrIndexOut); + break; + } + case 4: + { + MEDCouplingUMesh::ExtractFromIndexedArrays(daIntTyypp->begin(),daIntTyypp->end(),arrIn,arrIndxIn,arrOut,arrIndexOut); + break; + } + default: + throw INTERP_KERNEL::Exception("MEDCouplingUMesh::ExtractFromIndexedArrays : unrecognized type entered, expected list of int, tuple of int or DataArrayInt !"); + } + PyObject *ret=PyTuple_New(2); + PyTuple_SetItem(ret,0,SWIG_NewPointerObj(SWIG_as_voidptr(arrOut),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 )); + PyTuple_SetItem(ret,1,SWIG_NewPointerObj(SWIG_as_voidptr(arrIndexOut),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 )); + return ret; + } + + static PyObject *ExtractFromIndexedArrays2(int strt, int stp, int step, const DataArrayInt *arrIn, const DataArrayInt *arrIndxIn) throw(INTERP_KERNEL::Exception) + { + DataArrayInt *arrOut=0,*arrIndexOut=0; + MEDCouplingUMesh::ExtractFromIndexedArrays2(strt,stp,step,arrIn,arrIndxIn,arrOut,arrIndexOut); + PyObject *ret=PyTuple_New(2); + PyTuple_SetItem(ret,0,SWIG_NewPointerObj(SWIG_as_voidptr(arrOut),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 )); + PyTuple_SetItem(ret,1,SWIG_NewPointerObj(SWIG_as_voidptr(arrIndexOut),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 )); + return ret; + } + + static PyObject *ExtractFromIndexedArrays2(PyObject *slic, const DataArrayInt *arrIn, const DataArrayInt *arrIndxIn) throw(INTERP_KERNEL::Exception) + { + if(!PySlice_Check(slic)) + throw INTERP_KERNEL::Exception("ExtractFromIndexedArrays2 (wrap) : the first param is not a pyslice !"); + Py_ssize_t strt=2,stp=2,step=2; + PySliceObject *sliC=reinterpret_cast<PySliceObject *>(slic); + if(!arrIndxIn) + throw INTERP_KERNEL::Exception("ExtractFromIndexedArrays2 (wrap) : last array is null !"); + arrIndxIn->checkAllocated(); + if(arrIndxIn->getNumberOfComponents()!=1) + throw INTERP_KERNEL::Exception("ExtractFromIndexedArrays2 (wrap) : number of components of last argument must be equal to one !"); + GetIndicesOfSlice(sliC,arrIndxIn->getNumberOfTuples(),&strt,&stp,&step,"ExtractFromIndexedArrays2 (wrap) : Invalid slice regarding nb of elements !"); + DataArrayInt *arrOut=0,*arrIndexOut=0; + MEDCouplingUMesh::ExtractFromIndexedArrays2(strt,stp,step,arrIn,arrIndxIn,arrOut,arrIndexOut); + PyObject *ret=PyTuple_New(2); + PyTuple_SetItem(ret,0,SWIG_NewPointerObj(SWIG_as_voidptr(arrOut),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 )); + PyTuple_SetItem(ret,1,SWIG_NewPointerObj(SWIG_as_voidptr(arrIndexOut),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 )); + return ret; + } + + static PyObject *SetPartOfIndexedArrays(PyObject *li, + const DataArrayInt *arrIn, const DataArrayInt *arrIndxIn, + const DataArrayInt *srcArr, const DataArrayInt *srcArrIndex) throw(INTERP_KERNEL::Exception) + { + DataArrayInt *arrOut=0,*arrIndexOut=0; + int sw; + int singleVal; + std::vector<int> multiVal; + std::pair<int, std::pair<int,int> > slic; + ParaMEDMEM::DataArrayInt *daIntTyypp=0; + if(!arrIndxIn) + throw INTERP_KERNEL::Exception("MEDCouplingUMesh::SetPartOfIndexedArrays : null pointer as arrIndex !"); + convertObjToPossibleCpp2(li,arrIndxIn->getNumberOfTuples()-1,sw,singleVal,multiVal,slic,daIntTyypp); + switch(sw) + { + case 1: + { + MEDCouplingUMesh::SetPartOfIndexedArrays(&singleVal,&singleVal+1,arrIn,arrIndxIn,srcArr,srcArrIndex,arrOut,arrIndexOut); + break; + } + case 2: + { + MEDCouplingUMesh::SetPartOfIndexedArrays(&multiVal[0],&multiVal[0]+multiVal.size(),arrIn,arrIndxIn,srcArr,srcArrIndex,arrOut,arrIndexOut); + break; + } + case 4: + { + MEDCouplingUMesh::SetPartOfIndexedArrays(daIntTyypp->begin(),daIntTyypp->end(),arrIn,arrIndxIn,srcArr,srcArrIndex,arrOut,arrIndexOut); + break; + } + default: + throw INTERP_KERNEL::Exception("MEDCouplingUMesh::SetPartOfIndexedArrays : unrecognized type entered, expected list of int, tuple of int or DataArrayInt !"); + } + PyObject *ret=PyTuple_New(2); + PyTuple_SetItem(ret,0,SWIG_NewPointerObj(SWIG_as_voidptr(arrOut),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 )); + PyTuple_SetItem(ret,1,SWIG_NewPointerObj(SWIG_as_voidptr(arrIndexOut),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 )); + return ret; + } + + static void SetPartOfIndexedArraysSameIdx(PyObject *li, DataArrayInt *arrIn, const DataArrayInt *arrIndxIn, + const DataArrayInt *srcArr, const DataArrayInt *srcArrIndex) throw(INTERP_KERNEL::Exception) + { + int sw; + int singleVal; + std::vector<int> multiVal; + std::pair<int, std::pair<int,int> > slic; + ParaMEDMEM::DataArrayInt *daIntTyypp=0; + if(!arrIndxIn) + throw INTERP_KERNEL::Exception("MEDCouplingUMesh::SetPartOfIndexedArraysSameIdx : null pointer as arrIndex !"); + convertObjToPossibleCpp2(li,arrIndxIn->getNumberOfTuples()-1,sw,singleVal,multiVal,slic,daIntTyypp); + switch(sw) + { + case 1: + { + MEDCouplingUMesh::SetPartOfIndexedArraysSameIdx(&singleVal,&singleVal+1,arrIn,arrIndxIn,srcArr,srcArrIndex); + break; + } + case 2: + { + MEDCouplingUMesh::SetPartOfIndexedArraysSameIdx(&multiVal[0],&multiVal[0]+multiVal.size(),arrIn,arrIndxIn,srcArr,srcArrIndex); + break; + } + case 4: + { + MEDCouplingUMesh::SetPartOfIndexedArraysSameIdx(daIntTyypp->begin(),daIntTyypp->end(),arrIn,arrIndxIn,srcArr,srcArrIndex); + break; + } + default: + throw INTERP_KERNEL::Exception("MEDCouplingUMesh::SetPartOfIndexedArraysSameIdx : unrecognized type entered, expected list of int, tuple of int or DataArrayInt !"); + } + } + + PyObject *are2DCellsNotCorrectlyOriented(PyObject *vec, bool polyOnly) const throw(INTERP_KERNEL::Exception) + { + double val; + DataArrayDouble *a; + DataArrayDoubleTuple *aa; + std::vector<double> bb; + int sw; + int spaceDim=self->getSpaceDimension(); + const char msg[]="Python wrap of MEDCouplingUMesh::are2DCellsNotCorrectlyOriented : "; + const double *v=convertObjToPossibleCpp5_Safe(vec,sw,val,a,aa,bb,msg,1,spaceDim,true); + // + std::vector<int> cells; + self->are2DCellsNotCorrectlyOriented(v,polyOnly,cells); + DataArrayInt *ret=DataArrayInt::New(); + ret->alloc((int)cells.size(),1); + std::copy(cells.begin(),cells.end(),ret->getPointer()); + return SWIG_NewPointerObj(SWIG_as_voidptr(ret),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 ); + } + + void orientCorrectly2DCells(PyObject *vec, bool polyOnly) throw(INTERP_KERNEL::Exception) + { + double val; + DataArrayDouble *a; + DataArrayDoubleTuple *aa; + std::vector<double> bb; + int sw; + int spaceDim=self->getSpaceDimension(); + const char msg[]="Python wrap of MEDCouplingUMesh::orientCorrectly2DCells : "; + const double *v=convertObjToPossibleCpp5_Safe(vec,sw,val,a,aa,bb,msg,1,spaceDim,true); + self->orientCorrectly2DCells(v,polyOnly); + } + + PyObject *arePolyhedronsNotCorrectlyOriented() const throw(INTERP_KERNEL::Exception) + { + std::vector<int> cells; + self->arePolyhedronsNotCorrectlyOriented(cells); + DataArrayInt *ret=DataArrayInt::New(); + ret->alloc((int)cells.size(),1); + std::copy(cells.begin(),cells.end(),ret->getPointer()); + return SWIG_NewPointerObj(SWIG_as_voidptr(ret),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 ); + } + + PyObject *getFastAveragePlaneOfThis() const throw(INTERP_KERNEL::Exception) + { + double vec[3]; + double pos[3]; + self->getFastAveragePlaneOfThis(vec,pos); + double vals[6]; + std::copy(vec,vec+3,vals); + std::copy(pos,pos+3,vals+3); + return convertDblArrToPyListOfTuple(vals,3,2); + } + + static MEDCouplingUMesh *MergeUMeshes(PyObject *li) throw(INTERP_KERNEL::Exception) + { + std::vector<const ParaMEDMEM::MEDCouplingUMesh *> tmp; + convertFromPyObjVectorOfObj<const ParaMEDMEM::MEDCouplingUMesh *>(li,SWIGTYPE_p_ParaMEDMEM__MEDCouplingUMesh,"MEDCouplingUMesh",tmp); + return MEDCouplingUMesh::MergeUMeshes(tmp); + } + + PyObject *areCellsIncludedIn(const MEDCouplingUMesh *other, int compType) const throw(INTERP_KERNEL::Exception) + { + DataArrayInt *ret1; + bool ret0=self->areCellsIncludedIn(other,compType,ret1); + PyObject *ret=PyTuple_New(2); + PyObject *ret0Py=ret0?Py_True:Py_False; + Py_XINCREF(ret0Py); + PyTuple_SetItem(ret,0,ret0Py); + PyTuple_SetItem(ret,1,SWIG_NewPointerObj(SWIG_as_voidptr(ret1),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 )); + return ret; + } + + PyObject *areCellsIncludedIn2(const MEDCouplingUMesh *other) const throw(INTERP_KERNEL::Exception) + { + DataArrayInt *ret1; + bool ret0=self->areCellsIncludedIn2(other,ret1); + PyObject *ret=PyTuple_New(2); + PyObject *ret0Py=ret0?Py_True:Py_False; + Py_XINCREF(ret0Py); + PyTuple_SetItem(ret,0,ret0Py); + PyTuple_SetItem(ret,1,SWIG_NewPointerObj(SWIG_as_voidptr(ret1),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 )); + return ret; + } + + PyObject *explode3DMeshTo1D() const throw(INTERP_KERNEL::Exception) + { + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> d0=DataArrayInt::New(); + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> d1=DataArrayInt::New(); + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> d2=DataArrayInt::New(); + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> d3=DataArrayInt::New(); + MEDCouplingUMesh *m=self->explode3DMeshTo1D(d0,d1,d2,d3); + PyObject *ret=PyTuple_New(5); + PyTuple_SetItem(ret,0,SWIG_NewPointerObj(SWIG_as_voidptr(m),SWIGTYPE_p_ParaMEDMEM__MEDCouplingUMesh, SWIG_POINTER_OWN | 0 )); + PyTuple_SetItem(ret,1,SWIG_NewPointerObj(SWIG_as_voidptr(d0.retn()),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 )); + PyTuple_SetItem(ret,2,SWIG_NewPointerObj(SWIG_as_voidptr(d1.retn()),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 )); + PyTuple_SetItem(ret,3,SWIG_NewPointerObj(SWIG_as_voidptr(d2.retn()),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 )); + PyTuple_SetItem(ret,4,SWIG_NewPointerObj(SWIG_as_voidptr(d3.retn()),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 )); + return ret; + } + + PyObject *buildDescendingConnectivity() const throw(INTERP_KERNEL::Exception) + { + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> d0=DataArrayInt::New(); + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> d1=DataArrayInt::New(); + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> d2=DataArrayInt::New(); + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> d3=DataArrayInt::New(); + MEDCouplingUMesh *m=self->buildDescendingConnectivity(d0,d1,d2,d3); + PyObject *ret=PyTuple_New(5); + PyTuple_SetItem(ret,0,SWIG_NewPointerObj(SWIG_as_voidptr(m),SWIGTYPE_p_ParaMEDMEM__MEDCouplingUMesh, SWIG_POINTER_OWN | 0 )); + PyTuple_SetItem(ret,1,SWIG_NewPointerObj(SWIG_as_voidptr(d0.retn()),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 )); + PyTuple_SetItem(ret,2,SWIG_NewPointerObj(SWIG_as_voidptr(d1.retn()),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 )); + PyTuple_SetItem(ret,3,SWIG_NewPointerObj(SWIG_as_voidptr(d2.retn()),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 )); + PyTuple_SetItem(ret,4,SWIG_NewPointerObj(SWIG_as_voidptr(d3.retn()),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 )); + return ret; + } + + PyObject *buildDescendingConnectivity2() const throw(INTERP_KERNEL::Exception) + { + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> d0=DataArrayInt::New(); + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> d1=DataArrayInt::New(); + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> d2=DataArrayInt::New(); + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> d3=DataArrayInt::New(); + MEDCouplingUMesh *m=self->buildDescendingConnectivity2(d0,d1,d2,d3); + PyObject *ret=PyTuple_New(5); + PyTuple_SetItem(ret,0,SWIG_NewPointerObj(SWIG_as_voidptr(m),SWIGTYPE_p_ParaMEDMEM__MEDCouplingUMesh, SWIG_POINTER_OWN | 0 )); + PyTuple_SetItem(ret,1,SWIG_NewPointerObj(SWIG_as_voidptr(d0.retn()),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 )); + PyTuple_SetItem(ret,2,SWIG_NewPointerObj(SWIG_as_voidptr(d1.retn()),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 )); + PyTuple_SetItem(ret,3,SWIG_NewPointerObj(SWIG_as_voidptr(d2.retn()),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 )); + PyTuple_SetItem(ret,4,SWIG_NewPointerObj(SWIG_as_voidptr(d3.retn()),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 )); + return ret; + } + + PyObject *computeNeighborsOfCells() const throw(INTERP_KERNEL::Exception) + { + DataArrayInt *neighbors=0,*neighborsIdx=0; + self->computeNeighborsOfCells(neighbors,neighborsIdx); + PyObject *ret=PyTuple_New(2); + PyTuple_SetItem(ret,0,SWIG_NewPointerObj(SWIG_as_voidptr(neighbors),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 )); + PyTuple_SetItem(ret,1,SWIG_NewPointerObj(SWIG_as_voidptr(neighborsIdx),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 )); + return ret; + } + + PyObject *computeNeighborsOfNodes() const throw(INTERP_KERNEL::Exception) + { + DataArrayInt *neighbors=0,*neighborsIdx=0; + self->computeNeighborsOfNodes(neighbors,neighborsIdx); + PyObject *ret=PyTuple_New(2); + PyTuple_SetItem(ret,0,SWIG_NewPointerObj(SWIG_as_voidptr(neighbors),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 )); + PyTuple_SetItem(ret,1,SWIG_NewPointerObj(SWIG_as_voidptr(neighborsIdx),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 )); + return ret; + } + + static PyObject *ComputeNeighborsOfCellsAdv(const DataArrayInt *desc, const DataArrayInt *descI, const DataArrayInt *revDesc, const DataArrayInt *revDescI) throw(INTERP_KERNEL::Exception) + { + DataArrayInt *neighbors=0,*neighborsIdx=0; + MEDCouplingUMesh::ComputeNeighborsOfCellsAdv(desc,descI,revDesc,revDescI,neighbors,neighborsIdx); + PyObject *ret=PyTuple_New(2); + PyTuple_SetItem(ret,0,SWIG_NewPointerObj(SWIG_as_voidptr(neighbors),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 )); + PyTuple_SetItem(ret,1,SWIG_NewPointerObj(SWIG_as_voidptr(neighborsIdx),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 )); + return ret; + } + + PyObject *emulateMEDMEMBDC(const MEDCouplingUMesh *nM1LevMesh) + { + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> d0=DataArrayInt::New(); + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> d1=DataArrayInt::New(); + DataArrayInt *d2,*d3,*d4,*dd5; + MEDCouplingUMesh *mOut=self->emulateMEDMEMBDC(nM1LevMesh,d0,d1,d2,d3,d4,dd5); + PyObject *ret=PyTuple_New(7); + PyTuple_SetItem(ret,0,SWIG_NewPointerObj(SWIG_as_voidptr(mOut),SWIGTYPE_p_ParaMEDMEM__MEDCouplingUMesh, SWIG_POINTER_OWN | 0 )); + PyTuple_SetItem(ret,1,SWIG_NewPointerObj(SWIG_as_voidptr(d0.retn()),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 )); + PyTuple_SetItem(ret,2,SWIG_NewPointerObj(SWIG_as_voidptr(d1.retn()),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 )); + PyTuple_SetItem(ret,3,SWIG_NewPointerObj(SWIG_as_voidptr(d2),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 )); + PyTuple_SetItem(ret,4,SWIG_NewPointerObj(SWIG_as_voidptr(d3),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 )); + PyTuple_SetItem(ret,5,SWIG_NewPointerObj(SWIG_as_voidptr(d4),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 )); + PyTuple_SetItem(ret,6,SWIG_NewPointerObj(SWIG_as_voidptr(dd5),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 )); + return ret; + } + + DataArrayDouble *getPartBarycenterAndOwner(DataArrayInt *da) const throw(INTERP_KERNEL::Exception) + { + if(!da) + throw INTERP_KERNEL::Exception("Not null DataArrayInt instance expected !"); + da->checkAllocated(); + return self->getPartBarycenterAndOwner(da->getConstPointer(),da->getConstPointer()+da->getNbOfElems()); + } + + DataArrayDouble *getPartMeasureField(bool isAbs, DataArrayInt *da) const throw(INTERP_KERNEL::Exception) + { + if(!da) + throw INTERP_KERNEL::Exception("Not null DataArrayInt instance expected !"); + da->checkAllocated(); + return self->getPartMeasureField(isAbs,da->getConstPointer(),da->getConstPointer()+da->getNbOfElems()); + } + + MEDCouplingFieldDouble *buildPartOrthogonalField(DataArrayInt *da) const throw(INTERP_KERNEL::Exception) + { + if(!da) + throw INTERP_KERNEL::Exception("Not null DataArrayInt instance expected !"); + da->checkAllocated(); + return self->buildPartOrthogonalField(da->getConstPointer(),da->getConstPointer()+da->getNbOfElems()); + } + + PyObject *getTypesOfPart(DataArrayInt *da) const throw(INTERP_KERNEL::Exception) + { + if(!da) + throw INTERP_KERNEL::Exception("Not null DataArrayInt instance expected !"); + da->checkAllocated(); + std::set<INTERP_KERNEL::NormalizedCellType> result=self->getTypesOfPart(da->getConstPointer(),da->getConstPointer()+da->getNbOfElems()); + std::set<INTERP_KERNEL::NormalizedCellType>::const_iterator iL=result.begin(); + PyObject *res = PyList_New(result.size()); + for (int i=0;iL!=result.end(); i++, iL++) + PyList_SetItem(res,i,PyInt_FromLong(*iL)); + return res; + } + + DataArrayInt *keepCellIdsByType(INTERP_KERNEL::NormalizedCellType type, DataArrayInt *da) const throw(INTERP_KERNEL::Exception) + { + if(!da) + throw INTERP_KERNEL::Exception("Not null DataArrayInt instance expected !"); + da->checkAllocated(); + DataArrayInt *ret=self->keepCellIdsByType(type,da->getConstPointer(),da->getConstPointer()+da->getNbOfElems()); + ret->setName(da->getName().c_str()); + return ret; + } + + static PyObject *Intersect2DMeshes(const MEDCouplingUMesh *m1, const MEDCouplingUMesh *m2, double eps) throw(INTERP_KERNEL::Exception) + { + DataArrayInt *cellNb1=0,*cellNb2=0; + MEDCouplingUMesh *mret=MEDCouplingUMesh::Intersect2DMeshes(m1,m2,eps,cellNb1,cellNb2); + PyObject *ret=PyTuple_New(3); + PyTuple_SetItem(ret,0,SWIG_NewPointerObj(SWIG_as_voidptr(mret),SWIGTYPE_p_ParaMEDMEM__MEDCouplingUMesh, SWIG_POINTER_OWN | 0 )); + PyTuple_SetItem(ret,1,SWIG_NewPointerObj(SWIG_as_voidptr(cellNb1),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 )); + PyTuple_SetItem(ret,2,SWIG_NewPointerObj(SWIG_as_voidptr(cellNb2),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 )); + return ret; + } + + static PyObject *Intersect2DMeshWith1DLine(const MEDCouplingUMesh *mesh2D, const MEDCouplingUMesh *mesh1D, double eps) throw(INTERP_KERNEL::Exception) + { + MEDCouplingUMesh *splitMesh2D(0),*splitMesh1D(0); + DataArrayInt *cellIdInMesh2D(0),*cellIdInMesh1D(0); + MEDCouplingUMesh::Intersect2DMeshWith1DLine(mesh2D,mesh1D,eps,splitMesh2D,splitMesh1D,cellIdInMesh2D,cellIdInMesh1D); + PyObject *ret(PyTuple_New(4)); + PyTuple_SetItem(ret,0,SWIG_NewPointerObj(SWIG_as_voidptr(splitMesh2D),SWIGTYPE_p_ParaMEDMEM__MEDCouplingUMesh, SWIG_POINTER_OWN | 0 )); + PyTuple_SetItem(ret,1,SWIG_NewPointerObj(SWIG_as_voidptr(splitMesh1D),SWIGTYPE_p_ParaMEDMEM__MEDCouplingUMesh, SWIG_POINTER_OWN | 0 )); + PyTuple_SetItem(ret,2,SWIG_NewPointerObj(SWIG_as_voidptr(cellIdInMesh2D),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 )); + PyTuple_SetItem(ret,3,SWIG_NewPointerObj(SWIG_as_voidptr(cellIdInMesh1D),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 )); + return ret; + } + + PyObject *buildSlice3D(PyObject *origin, PyObject *vec, double eps) const throw(INTERP_KERNEL::Exception) + { + int spaceDim=self->getSpaceDimension(); + if(spaceDim!=3) + throw INTERP_KERNEL::Exception("Python wrap of MEDCouplingUMesh::buildSlice3D : works only for spaceDim 3 !"); + double val,val2; + DataArrayDouble *a,*a2; + DataArrayDoubleTuple *aa,*aa2; + std::vector<double> bb,bb2; + int sw; + const char msg[]="Python wrap of MEDCouplingUMesh::buildSlice3D : 1st paramater for origin."; + const char msg2[]="Python wrap of MEDCouplingUMesh::buildSlice3D : 2nd paramater for vector."; + const double *orig=convertObjToPossibleCpp5_Safe(origin,sw,val,a,aa,bb,msg,1,spaceDim,true); + const double *vect=convertObjToPossibleCpp5_Safe(vec,sw,val2,a2,aa2,bb2,msg2,1,spaceDim,true); + // + DataArrayInt *cellIds=0; + MEDCouplingUMesh *ret0=self->buildSlice3D(orig,vect,eps,cellIds); + PyObject *ret=PyTuple_New(2); + PyTuple_SetItem(ret,0,SWIG_NewPointerObj(SWIG_as_voidptr(ret0),SWIGTYPE_p_ParaMEDMEM__MEDCouplingUMesh, SWIG_POINTER_OWN | 0 )); + PyTuple_SetItem(ret,1,SWIG_NewPointerObj(SWIG_as_voidptr(cellIds),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 )); + return ret; + } + + PyObject *buildSlice3DSurf(PyObject *origin, PyObject *vec, double eps) const throw(INTERP_KERNEL::Exception) + { + int spaceDim=self->getSpaceDimension(); + if(spaceDim!=3) + throw INTERP_KERNEL::Exception("Python wrap of MEDCouplingUMesh::buildSlice3DSurf : works only for spaceDim 3 !"); + double val,val2; + DataArrayDouble *a,*a2; + DataArrayDoubleTuple *aa,*aa2; + std::vector<double> bb,bb2; + int sw; + const char msg[]="Python wrap of MEDCouplingUMesh::buildSlice3DSurf : 1st paramater for origin."; + const char msg2[]="Python wrap of MEDCouplingUMesh::buildSlice3DSurf : 2nd paramater for vector."; + const double *orig=convertObjToPossibleCpp5_Safe(origin,sw,val,a,aa,bb,msg,1,spaceDim,true); + const double *vect=convertObjToPossibleCpp5_Safe(vec,sw,val2,a2,aa2,bb2,msg2,1,spaceDim,true); + // + DataArrayInt *cellIds=0; + MEDCouplingUMesh *ret0=self->buildSlice3DSurf(orig,vect,eps,cellIds); + PyObject *ret=PyTuple_New(2); + PyTuple_SetItem(ret,0,SWIG_NewPointerObj(SWIG_as_voidptr(ret0),SWIGTYPE_p_ParaMEDMEM__MEDCouplingUMesh, SWIG_POINTER_OWN | 0 )); + PyTuple_SetItem(ret,1,SWIG_NewPointerObj(SWIG_as_voidptr(cellIds),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 )); + return ret; + } + + DataArrayInt *getCellIdsCrossingPlane(PyObject *origin, PyObject *vec, double eps) const throw(INTERP_KERNEL::Exception) + { + int spaceDim=self->getSpaceDimension(); + if(spaceDim!=3) + throw INTERP_KERNEL::Exception("Python wrap of MEDCouplingUMesh::getCellIdsCrossingPlane : works only for spaceDim 3 !"); + double val,val2; + DataArrayDouble *a,*a2; + DataArrayDoubleTuple *aa,*aa2; + std::vector<double> bb,bb2; + int sw; + const char msg[]="Python wrap of MEDCouplingUMesh::getCellIdsCrossingPlane : 1st paramater for origin."; + const char msg2[]="Python wrap of MEDCouplingUMesh::getCellIdsCrossingPlane : 2nd paramater for vector."; + const double *orig=convertObjToPossibleCpp5_Safe(origin,sw,val,a,aa,bb,msg,1,spaceDim,true); + const double *vect=convertObjToPossibleCpp5_Safe(vec,sw,val2,a2,aa2,bb2,msg2,1,spaceDim,true); + return self->getCellIdsCrossingPlane(orig,vect,eps); + } + + void convertToPolyTypes(PyObject *li) throw(INTERP_KERNEL::Exception) + { + int sw; + int pos1; + std::vector<int> pos2; + DataArrayInt *pos3=0; + DataArrayIntTuple *pos4=0; + convertObjToPossibleCpp1(li,sw,pos1,pos2,pos3,pos4); + switch(sw) + { + case 1: + { + self->convertToPolyTypes(&pos1,&pos1+1); + return; + } + case 2: + { + if(pos2.empty()) + return; + self->convertToPolyTypes(&pos2[0],&pos2[0]+pos2.size()); + return ; + } + case 3: + { + self->convertToPolyTypes(pos3->begin(),pos3->end()); + return ; + } + default: + throw INTERP_KERNEL::Exception("MEDCouplingUMesh::convertToPolyTypes : unexpected input array type recognized !"); + } + } + } + void convertAllToPoly(); + void convertExtrudedPolyhedra() throw(INTERP_KERNEL::Exception); + bool unPolyze() throw(INTERP_KERNEL::Exception); + void simplifyPolyhedra(double eps) throw(INTERP_KERNEL::Exception); + MEDCouplingUMesh *buildSpreadZonesWithPoly() const throw(INTERP_KERNEL::Exception); + MEDCouplingUMesh *buildExtrudedMesh(const MEDCouplingUMesh *mesh1D, int policy) throw(INTERP_KERNEL::Exception); + }; + + //== MEDCouplingUMesh End + + //== MEDCouplingExtrudedMesh + + class MEDCouplingExtrudedMesh : public ParaMEDMEM::MEDCouplingMesh + { + public: + static MEDCouplingExtrudedMesh *New(const MEDCouplingUMesh *mesh3D, const MEDCouplingUMesh *mesh2D, int cell2DId) throw(INTERP_KERNEL::Exception); + MEDCouplingUMesh *build3DUnstructuredMesh() const throw(INTERP_KERNEL::Exception); + %extend { + MEDCouplingExtrudedMesh(const MEDCouplingUMesh *mesh3D, const MEDCouplingUMesh *mesh2D, int cell2DId) throw(INTERP_KERNEL::Exception) + { + return MEDCouplingExtrudedMesh::New(mesh3D,mesh2D,cell2DId); + } + + MEDCouplingExtrudedMesh() + { + return MEDCouplingExtrudedMesh::New(); + } + + static PyObject *___new___(PyObject *cls, PyObject *args) throw(INTERP_KERNEL::Exception) + { + return NewMethWrapCallInitOnlyIfEmptyDictInInput(cls,args,"MEDCouplingExtrudedMesh"); + } + + std::string __str__() const throw(INTERP_KERNEL::Exception) + { + return self->simpleRepr(); + } + + std::string __repr__() const throw(INTERP_KERNEL::Exception) + { + std::ostringstream oss; + self->reprQuickOverview(oss); + return oss.str(); + } + + PyObject *getMesh2D() const throw(INTERP_KERNEL::Exception) + { + MEDCouplingUMesh *ret=self->getMesh2D(); + if(ret) + ret->incrRef(); + return convertMesh(ret, SWIG_POINTER_OWN | 0 ); + } + PyObject *getMesh1D() const throw(INTERP_KERNEL::Exception) + { + MEDCouplingUMesh *ret=self->getMesh1D(); + if(ret) + ret->incrRef(); + return convertMesh(ret, SWIG_POINTER_OWN | 0 ); + } + PyObject *getMesh3DIds() const throw(INTERP_KERNEL::Exception) + { + DataArrayInt *ret=self->getMesh3DIds(); + if(ret) + ret->incrRef(); + return SWIG_NewPointerObj(SWIG_as_voidptr(ret),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 ); + } + } + }; + + //== MEDCouplingExtrudedMesh End + + class MEDCoupling1GTUMesh : public ParaMEDMEM::MEDCouplingPointSet + { + public: + static MEDCoupling1GTUMesh *New(const std::string& name, INTERP_KERNEL::NormalizedCellType type) throw(INTERP_KERNEL::Exception); + static MEDCoupling1GTUMesh *New(const MEDCouplingUMesh *m) throw(INTERP_KERNEL::Exception); + INTERP_KERNEL::NormalizedCellType getCellModelEnum() const throw(INTERP_KERNEL::Exception); + int getNodalConnectivityLength() const throw(INTERP_KERNEL::Exception); + virtual void allocateCells(int nbOfCells=0) throw(INTERP_KERNEL::Exception); + virtual void checkCoherencyOfConnectivity() const throw(INTERP_KERNEL::Exception); + %extend + { + virtual void insertNextCell(PyObject *li) throw(INTERP_KERNEL::Exception) + { + int szArr,sw,iTypppArr; + std::vector<int> stdvecTyyppArr; + const int *tmp=convertObjToPossibleCpp1_Safe(li,sw,szArr,iTypppArr,stdvecTyyppArr); + self->insertNextCell(tmp,tmp+szArr); + } + + virtual DataArrayInt *getNodalConnectivity() const throw(INTERP_KERNEL::Exception) + { + DataArrayInt *ret=self->getNodalConnectivity(); + if(ret) ret->incrRef(); + return ret; + } + + static MEDCouplingUMesh *AggregateOnSameCoordsToUMesh(PyObject *li) throw(INTERP_KERNEL::Exception) + { + std::vector< const MEDCoupling1GTUMesh *> parts; + convertFromPyObjVectorOfObj<const ParaMEDMEM::MEDCoupling1GTUMesh *>(li,SWIGTYPE_p_ParaMEDMEM__MEDCoupling1GTUMesh,"MEDCoupling1GTUMesh",parts); + return MEDCoupling1GTUMesh::AggregateOnSameCoordsToUMesh(parts); + } + } + }; + + //== MEDCoupling1SGTUMesh + + class MEDCoupling1SGTUMesh : public ParaMEDMEM::MEDCoupling1GTUMesh + { + public: + static MEDCoupling1SGTUMesh *New(const std::string& name, INTERP_KERNEL::NormalizedCellType type) throw(INTERP_KERNEL::Exception); + static MEDCoupling1SGTUMesh *New(const MEDCouplingUMesh *m) throw(INTERP_KERNEL::Exception); + void setNodalConnectivity(DataArrayInt *nodalConn) throw(INTERP_KERNEL::Exception); + int getNumberOfNodesPerCell() const throw(INTERP_KERNEL::Exception); + static MEDCoupling1SGTUMesh *Merge1SGTUMeshes(const MEDCoupling1SGTUMesh *mesh1, const MEDCoupling1SGTUMesh *mesh2) throw(INTERP_KERNEL::Exception); + MEDCoupling1SGTUMesh *buildSetInstanceFromThis(int spaceDim) const throw(INTERP_KERNEL::Exception); + MEDCoupling1GTUMesh *computeDualMesh() const throw(INTERP_KERNEL::Exception); + MEDCoupling1SGTUMesh *explodeEachHexa8To6Quad4() const throw(INTERP_KERNEL::Exception); + DataArrayInt *sortHexa8EachOther() throw(INTERP_KERNEL::Exception); + %extend + { + MEDCoupling1SGTUMesh() + { + return MEDCoupling1SGTUMesh::New(); + } + + MEDCoupling1SGTUMesh(const std::string& name, INTERP_KERNEL::NormalizedCellType type) throw(INTERP_KERNEL::Exception) + { + return MEDCoupling1SGTUMesh::New(name,type); + } + + MEDCoupling1SGTUMesh(const MEDCouplingUMesh *m) throw(INTERP_KERNEL::Exception) + { + return MEDCoupling1SGTUMesh::New(m); + } + + static PyObject *___new___(PyObject *cls, PyObject *args) throw(INTERP_KERNEL::Exception) + { + return NewMethWrapCallInitOnlyIfEmptyDictInInput(cls,args,"MEDCoupling1SGTUMesh"); + } + + std::string __str__() const throw(INTERP_KERNEL::Exception) + { + return self->simpleRepr(); + } + + std::string __repr__() const throw(INTERP_KERNEL::Exception) + { + std::ostringstream oss; + self->reprQuickOverview(oss); + return oss.str(); + } + + PyObject *structurizeMe(double eps=1e-12) const throw(INTERP_KERNEL::Exception) + { + DataArrayInt *cellPerm(0),*nodePerm(0); + MEDCouplingCMesh *retCpp(self->structurizeMe(cellPerm,nodePerm,eps)); + PyObject *ret(PyTuple_New(3)); + PyTuple_SetItem(ret,0,SWIG_NewPointerObj(SWIG_as_voidptr(retCpp),SWIGTYPE_p_ParaMEDMEM__MEDCouplingCMesh, SWIG_POINTER_OWN | 0 )); + PyTuple_SetItem(ret,1,SWIG_NewPointerObj(SWIG_as_voidptr(cellPerm),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 )); + PyTuple_SetItem(ret,2,SWIG_NewPointerObj(SWIG_as_voidptr(nodePerm),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 )); + return ret; + } + + static MEDCoupling1SGTUMesh *Merge1SGTUMeshes(PyObject *li) throw(INTERP_KERNEL::Exception) + { + std::vector<const ParaMEDMEM::MEDCoupling1SGTUMesh *> tmp; + convertFromPyObjVectorOfObj<const ParaMEDMEM::MEDCoupling1SGTUMesh *>(li,SWIGTYPE_p_ParaMEDMEM__MEDCoupling1SGTUMesh,"MEDCoupling1SGTUMesh",tmp); + return MEDCoupling1SGTUMesh::Merge1SGTUMeshes(tmp); + } + + static MEDCoupling1SGTUMesh *Merge1SGTUMeshesOnSameCoords(PyObject *li) throw(INTERP_KERNEL::Exception) + { + std::vector<const ParaMEDMEM::MEDCoupling1SGTUMesh *> tmp; + convertFromPyObjVectorOfObj<const ParaMEDMEM::MEDCoupling1SGTUMesh *>(li,SWIGTYPE_p_ParaMEDMEM__MEDCoupling1SGTUMesh,"MEDCoupling1SGTUMesh",tmp); + return MEDCoupling1SGTUMesh::Merge1SGTUMeshesOnSameCoords(tmp); + } + } + }; + + //== MEDCoupling1SGTUMesh End + + //== MEDCoupling1DGTUMesh + + class MEDCoupling1DGTUMesh : public ParaMEDMEM::MEDCoupling1GTUMesh + { + public: + static MEDCoupling1DGTUMesh *New(const std::string& name, INTERP_KERNEL::NormalizedCellType type) throw(INTERP_KERNEL::Exception); + static MEDCoupling1DGTUMesh *New(const MEDCouplingUMesh *m) throw(INTERP_KERNEL::Exception); + void setNodalConnectivity(DataArrayInt *nodalConn, DataArrayInt *nodalConnIndex) throw(INTERP_KERNEL::Exception); + MEDCoupling1DGTUMesh *buildSetInstanceFromThis(int spaceDim) const throw(INTERP_KERNEL::Exception); + bool isPacked() const throw(INTERP_KERNEL::Exception); + %extend + { + MEDCoupling1DGTUMesh() + { + return MEDCoupling1DGTUMesh::New(); + } + MEDCoupling1DGTUMesh(const std::string& name, INTERP_KERNEL::NormalizedCellType type) throw(INTERP_KERNEL::Exception) + { + return MEDCoupling1DGTUMesh::New(name,type); + } + + MEDCoupling1DGTUMesh(const MEDCouplingUMesh *m) throw(INTERP_KERNEL::Exception) + { + return MEDCoupling1DGTUMesh::New(m); + } + + static PyObject *___new___(PyObject *cls, PyObject *args) throw(INTERP_KERNEL::Exception) + { + return NewMethWrapCallInitOnlyIfEmptyDictInInput(cls,args,"MEDCoupling1DGTUMesh"); + } + + std::string __str__() const throw(INTERP_KERNEL::Exception) + { + return self->simpleRepr(); + } + + std::string __repr__() const throw(INTERP_KERNEL::Exception) + { + std::ostringstream oss; + self->reprQuickOverview(oss); + return oss.str(); + } + + DataArrayInt *getNodalConnectivityIndex() const throw(INTERP_KERNEL::Exception) + { + DataArrayInt *ret=self->getNodalConnectivityIndex(); + if(ret) ret->incrRef(); + return ret; + } + + PyObject *retrievePackedNodalConnectivity() const throw(INTERP_KERNEL::Exception) + { + DataArrayInt *ret1=0,*ret2=0; + bool ret0=self->retrievePackedNodalConnectivity(ret1,ret2); + PyObject *ret0Py=ret0?Py_True:Py_False; + Py_XINCREF(ret0Py); + PyObject *ret=PyTuple_New(3); + PyTuple_SetItem(ret,0,ret0Py); + PyTuple_SetItem(ret,1,SWIG_NewPointerObj(SWIG_as_voidptr(ret1),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 )); + PyTuple_SetItem(ret,2,SWIG_NewPointerObj(SWIG_as_voidptr(ret2),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 )); + return ret; + } + + PyObject *copyWithNodalConnectivityPacked() const throw(INTERP_KERNEL::Exception) + { + bool ret1; + MEDCoupling1DGTUMesh *ret0=self->copyWithNodalConnectivityPacked(ret1); + PyObject *ret=PyTuple_New(2); + PyObject *ret1Py=ret1?Py_True:Py_False; Py_XINCREF(ret1Py); + PyTuple_SetItem(ret,0,SWIG_NewPointerObj(SWIG_as_voidptr(ret0),SWIGTYPE_p_ParaMEDMEM__MEDCoupling1DGTUMesh, SWIG_POINTER_OWN | 0 )); + PyTuple_SetItem(ret,1,ret1Py); + return ret; + } + + static MEDCoupling1DGTUMesh *Merge1DGTUMeshes(PyObject *li) throw(INTERP_KERNEL::Exception) + { + std::vector<const ParaMEDMEM::MEDCoupling1DGTUMesh *> tmp; + convertFromPyObjVectorOfObj<const ParaMEDMEM::MEDCoupling1DGTUMesh *>(li,SWIGTYPE_p_ParaMEDMEM__MEDCoupling1DGTUMesh,"MEDCoupling1DGTUMesh",tmp); + return MEDCoupling1DGTUMesh::Merge1DGTUMeshes(tmp); + } + + static MEDCoupling1DGTUMesh *Merge1DGTUMeshesOnSameCoords(PyObject *li) throw(INTERP_KERNEL::Exception) + { + std::vector<const ParaMEDMEM::MEDCoupling1DGTUMesh *> tmp; + convertFromPyObjVectorOfObj<const ParaMEDMEM::MEDCoupling1DGTUMesh *>(li,SWIGTYPE_p_ParaMEDMEM__MEDCoupling1DGTUMesh,"MEDCoupling1DGTUMesh",tmp); + return MEDCoupling1DGTUMesh::Merge1DGTUMeshesOnSameCoords(tmp); + } + + static DataArrayInt *AggregateNodalConnAndShiftNodeIds(PyObject *li, const std::vector<int>& offsetInNodeIdsPerElt) throw(INTERP_KERNEL::Exception) + { + std::vector<const ParaMEDMEM::DataArrayInt *> tmp; + convertFromPyObjVectorOfObj<const ParaMEDMEM::DataArrayInt *>(li,SWIGTYPE_p_ParaMEDMEM__DataArrayInt,"DataArrayInt",tmp); + return MEDCoupling1DGTUMesh::AggregateNodalConnAndShiftNodeIds(tmp,offsetInNodeIdsPerElt); + } + } + }; + + //== MEDCoupling1DGTUMeshEnd + + class MEDCouplingStructuredMesh : public ParaMEDMEM::MEDCouplingMesh + { + public: + int getCellIdFromPos(int i, int j, int k) const throw(INTERP_KERNEL::Exception); + int getNodeIdFromPos(int i, int j, int k) const throw(INTERP_KERNEL::Exception); + int getNumberOfCellsOfSubLevelMesh() const throw(INTERP_KERNEL::Exception); + int getSpaceDimensionOnNodeStruct() const throw(INTERP_KERNEL::Exception); + double computeSquareness() const throw(INTERP_KERNEL::Exception); + virtual std::vector<int> getNodeGridStructure() const throw(INTERP_KERNEL::Exception); + std::vector<int> getCellGridStructure() const throw(INTERP_KERNEL::Exception); + MEDCoupling1SGTUMesh *build1SGTUnstructured() const throw(INTERP_KERNEL::Exception); + std::vector<int> getLocationFromCellId(int cellId) const throw(INTERP_KERNEL::Exception); + std::vector<int> getLocationFromNodeId(int cellId) const throw(INTERP_KERNEL::Exception); + static INTERP_KERNEL::NormalizedCellType GetGeoTypeGivenMeshDimension(int meshDim) throw(INTERP_KERNEL::Exception); + MEDCoupling1SGTUMesh *build1SGTSubLevelMesh() const throw(INTERP_KERNEL::Exception); + static int DeduceNumberOfGivenStructure(const std::vector<int>& st) throw(INTERP_KERNEL::Exception); + static DataArrayInt *ComputeCornersGhost(const std::vector<int>& st, int ghostLev) throw(INTERP_KERNEL::Exception); + static std::vector<int> GetSplitVectFromStruct(const std::vector<int>& strct) throw(INTERP_KERNEL::Exception); + %extend + { + virtual MEDCouplingStructuredMesh *buildStructuredSubPart(PyObject *cellPart) const throw(INTERP_KERNEL::Exception) + { + int tmpp1=-1,tmpp2=-1; + std::vector<int> tmp=fillArrayWithPyListInt2(cellPart,tmpp1,tmpp2); + std::vector< std::pair<int,int> > inp; + if(tmpp2==2) + { + inp.resize(tmpp1); + for(int i=0;i<tmpp1;i++) + { inp[i].first=tmp[2*i]; inp[i].second=tmp[2*i+1]; } + } + else if(tmpp2==1) + { + if(tmpp1%2!=0) + throw INTERP_KERNEL::Exception("Wrap of MEDCouplingStructuredMesh.buildStructuredSubPart : invalid input size ! Must be even size !"); + inp.resize(tmpp1/2); + for(int i=0;i<tmpp1/2;i++) + { inp[i].first=tmp[2*i]; inp[i].second=tmp[2*i+1]; } + } + else + throw INTERP_KERNEL::Exception("Wrap of MEDCouplingStructuredMesh.buildStructuredSubPart : invalid input size !"); + return self->buildStructuredSubPart(inp); + } + + static DataArrayInt *BuildExplicitIdsFrom(PyObject *st, PyObject *part) throw(INTERP_KERNEL::Exception) + { + std::vector< std::pair<int,int> > inp; + convertPyToVectorPairInt(part,inp); + // + int szArr,sw,iTypppArr; + std::vector<int> stdvecTyyppArr; + const int *tmp4=convertObjToPossibleCpp1_Safe(st,sw,szArr,iTypppArr,stdvecTyyppArr); + std::vector<int> tmp5(tmp4,tmp4+szArr); + // + return MEDCouplingStructuredMesh::BuildExplicitIdsFrom(tmp5,inp); + } + + static void MultiplyPartOf(const std::vector<int>& st, PyObject *part, double factor, DataArrayDouble *da) throw(INTERP_KERNEL::Exception) + { + std::vector< std::pair<int,int> > inp; + convertPyToVectorPairInt(part,inp); + MEDCouplingStructuredMesh::MultiplyPartOf(st,inp,factor,da); + } + + static void MultiplyPartOfByGhost(const std::vector<int>& st, PyObject *part, int ghostSize, double factor, DataArrayDouble *da) throw(INTERP_KERNEL::Exception) + { + std::vector< std::pair<int,int> > inp; + convertPyToVectorPairInt(part,inp); + MEDCouplingStructuredMesh::MultiplyPartOfByGhost(st,inp,ghostSize,factor,da); + } + + static PyObject *PutInGhostFormat(int ghostSize, const std::vector<int>& st, PyObject *part) throw(INTERP_KERNEL::Exception) + { + std::vector< std::pair<int,int> > inp; + convertPyToVectorPairInt(part,inp); + std::vector<int> stWithGhost; + std::vector< std::pair<int,int> > partWithGhost; + MEDCouplingStructuredMesh::PutInGhostFormat(ghostSize,st,inp,stWithGhost,partWithGhost); + PyObject *ret(PyTuple_New(2)); + PyTuple_SetItem(ret,0,convertIntArrToPyList2(stWithGhost)); + PyTuple_SetItem(ret,1,convertFromVectorPairInt(partWithGhost)); + return ret; + } + + static DataArrayDouble *ExtractFieldOfDoubleFrom(const std::vector<int>& st, const DataArrayDouble *fieldOfDbl, PyObject *partCompactFormat) throw(INTERP_KERNEL::Exception) + { + std::vector< std::pair<int,int> > inp; + convertPyToVectorPairInt(partCompactFormat,inp); + return MEDCouplingStructuredMesh::ExtractFieldOfDoubleFrom(st,fieldOfDbl,inp); + } + + static void AssignPartOfFieldOfDoubleUsing(const std::vector<int>& st, DataArrayDouble *fieldOfDbl, PyObject *partCompactFormat, const DataArrayDouble *other) throw(INTERP_KERNEL::Exception) + { + std::vector< std::pair<int,int> > inp; + convertPyToVectorPairInt(partCompactFormat,inp); + MEDCouplingStructuredMesh::AssignPartOfFieldOfDoubleUsing(st,fieldOfDbl,inp,other); + } + + static int DeduceNumberOfGivenRangeInCompactFrmt(PyObject *part) throw(INTERP_KERNEL::Exception) + { + std::vector< std::pair<int,int> > inp; + convertPyToVectorPairInt(part,inp); + return MEDCouplingStructuredMesh::DeduceNumberOfGivenRangeInCompactFrmt(inp); + } + + static DataArrayInt *Build1GTNodalConnectivity(PyObject *li) throw(INTERP_KERNEL::Exception) + { + int szArr,sw,iTypppArr; + std::vector<int> stdvecTyyppArr; + const int *tmp=convertObjToPossibleCpp1_Safe(li,sw,szArr,iTypppArr,stdvecTyyppArr); + return MEDCouplingStructuredMesh::Build1GTNodalConnectivity(tmp,tmp+szArr); + } + + static DataArrayInt *Build1GTNodalConnectivityOfSubLevelMesh(PyObject *li) throw(INTERP_KERNEL::Exception) + { + int szArr,sw,iTypppArr; + std::vector<int> stdvecTyyppArr; + const int *tmp(convertObjToPossibleCpp1_Safe(li,sw,szArr,iTypppArr,stdvecTyyppArr)); + return MEDCouplingStructuredMesh::Build1GTNodalConnectivityOfSubLevelMesh(tmp,tmp+szArr); + } + + static std::vector<int> GetDimensionsFromCompactFrmt(PyObject *partCompactFormat) throw(INTERP_KERNEL::Exception) + { + std::vector< std::pair<int,int> > inp; + convertPyToVectorPairInt(partCompactFormat,inp); + return MEDCouplingStructuredMesh::GetDimensionsFromCompactFrmt(inp); + } + + static PyObject *GetCompactFrmtFromDimensions(const std::vector<int>& dims) throw(INTERP_KERNEL::Exception) + { + std::vector< std::pair<int,int> > ret(MEDCouplingStructuredMesh::GetCompactFrmtFromDimensions(dims)); + PyObject *retPy=PyList_New(ret.size()); + for(std::size_t i=0;i<ret.size();i++) + { + PyObject *tmp=PyTuple_New(2); + PyTuple_SetItem(tmp,0,PyInt_FromLong(ret[i].first)); + PyTuple_SetItem(tmp,1,PyInt_FromLong(ret[i].second)); + PyList_SetItem(retPy,i,tmp); + } + return retPy; + } + + static PyObject *IntersectRanges(PyObject *r1, PyObject *r2) throw(INTERP_KERNEL::Exception) + { + std::vector< std::pair<int,int> > r1Cpp,r2Cpp; + convertPyToVectorPairInt(r1,r1Cpp); + convertPyToVectorPairInt(r2,r2Cpp); + std::vector< std::pair<int,int> > ret(MEDCouplingStructuredMesh::IntersectRanges(r1Cpp,r2Cpp)); + PyObject *retPy=PyList_New(ret.size()); + for(std::size_t i=0;i<ret.size();i++) + { + PyObject *tmp=PyTuple_New(2); + PyTuple_SetItem(tmp,0,PyInt_FromLong(ret[i].first)); + PyTuple_SetItem(tmp,1,PyInt_FromLong(ret[i].second)); + PyList_SetItem(retPy,i,tmp); + } + return retPy; + } + + static bool AreRangesIntersect(PyObject *r1, PyObject *r2) + { + std::vector< std::pair<int,int> > r1Cpp,r2Cpp; + convertPyToVectorPairInt(r1,r1Cpp); + convertPyToVectorPairInt(r2,r2Cpp); + return MEDCouplingStructuredMesh::AreRangesIntersect(r1Cpp,r2Cpp); + } + + static PyObject *IsPartStructured(PyObject *li, PyObject *st) throw(INTERP_KERNEL::Exception) + { + int szArr,sw,iTypppArr; + std::vector<int> stdvecTyyppArr; + const int *tmp=convertObjToPossibleCpp1_Safe(li,sw,szArr,iTypppArr,stdvecTyyppArr); + int szArr2,sw2,iTypppArr2; + std::vector<int> stdvecTyyppArr2; + const int *tmp2=convertObjToPossibleCpp1_Safe(st,sw2,szArr2,iTypppArr2,stdvecTyyppArr2); + std::vector<int> tmp3(tmp2,tmp2+szArr2); + std::vector< std::pair<int,int> > partCompactFormat; + bool ret0=MEDCouplingStructuredMesh::IsPartStructured(tmp,tmp+szArr,tmp3,partCompactFormat); + PyObject *ret=PyTuple_New(2); + PyObject *ret0Py=ret0?Py_True:Py_False; Py_XINCREF(ret0Py); + PyTuple_SetItem(ret,0,ret0Py); + PyObject *ret1Py=PyList_New(partCompactFormat.size()); + for(std::size_t i=0;i<partCompactFormat.size();i++) + { + PyObject *tmp4=PyTuple_New(2); + PyTuple_SetItem(tmp4,0,PyInt_FromLong(partCompactFormat[i].first)); + PyTuple_SetItem(tmp4,1,PyInt_FromLong(partCompactFormat[i].second)); + PyList_SetItem(ret1Py,i,tmp4); + } + PyTuple_SetItem(ret,1,ret1Py); + return ret; + } + + static PyObject *ChangeReferenceFromGlobalOfCompactFrmt(PyObject *bigInAbs, PyObject *partOfBigInAbs, bool check=true) throw(INTERP_KERNEL::Exception) + { + std::vector< std::pair<int,int> > param0,param1,ret; + convertPyToVectorPairInt(bigInAbs,param0); + convertPyToVectorPairInt(partOfBigInAbs,param1); + MEDCouplingStructuredMesh::ChangeReferenceFromGlobalOfCompactFrmt(param0,param1,ret,check); + PyObject *retPy(PyList_New(ret.size())); + for(std::size_t i=0;i<ret.size();i++) + { + PyObject *tmp(PyTuple_New(2)); + PyTuple_SetItem(tmp,0,PyInt_FromLong(ret[i].first)); + PyTuple_SetItem(tmp,1,PyInt_FromLong(ret[i].second)); + PyList_SetItem(retPy,i,tmp); + } + return retPy; + } + + static PyObject *TranslateCompactFrmt(PyObject *part, const std::vector<int>& translation) throw(INTERP_KERNEL::Exception) + { + std::vector< std::pair<int,int> > param0; + convertPyToVectorPairInt(part,param0); + std::vector< std::pair<int,int> > ret(MEDCouplingStructuredMesh::TranslateCompactFrmt(param0,translation)); + PyObject *retPy(PyList_New(ret.size())); + for(std::size_t i=0;i<ret.size();i++) + { + PyObject *tmp(PyTuple_New(2)); + PyTuple_SetItem(tmp,0,PyInt_FromLong(ret[i].first)); + PyTuple_SetItem(tmp,1,PyInt_FromLong(ret[i].second)); + PyList_SetItem(retPy,i,tmp); + } + return retPy; + } + + static std::vector<int> FindTranslationFrom(PyObject *startingFrom, PyObject *goingTo) throw(INTERP_KERNEL::Exception) + { + std::vector< std::pair<int,int> > param0,param1; + convertPyToVectorPairInt(startingFrom,param0); + convertPyToVectorPairInt(goingTo,param1); + return MEDCouplingStructuredMesh::FindTranslationFrom(param0,param1); + } + + static PyObject *ChangeReferenceToGlobalOfCompactFrmt(PyObject *bigInAbs, PyObject *partOfBigRelativeToBig, bool check=true) throw(INTERP_KERNEL::Exception) + { + std::vector< std::pair<int,int> > param0,param1,ret; + convertPyToVectorPairInt(bigInAbs,param0); + convertPyToVectorPairInt(partOfBigRelativeToBig,param1); + MEDCouplingStructuredMesh::ChangeReferenceToGlobalOfCompactFrmt(param0,param1,ret,check); + PyObject *retPy(PyList_New(ret.size())); + for(std::size_t i=0;i<ret.size();i++) + { + PyObject *tmp(PyTuple_New(2)); + PyTuple_SetItem(tmp,0,PyInt_FromLong(ret[i].first)); + PyTuple_SetItem(tmp,1,PyInt_FromLong(ret[i].second)); + PyList_SetItem(retPy,i,tmp); + } + return retPy; + } + } + }; + + //== MEDCouplingCMesh + + class MEDCouplingCMesh : public ParaMEDMEM::MEDCouplingStructuredMesh + { + public: + static MEDCouplingCMesh *New() throw(INTERP_KERNEL::Exception); + static MEDCouplingCMesh *New(const std::string& meshName) throw(INTERP_KERNEL::Exception); + MEDCouplingCMesh *clone(bool recDeepCpy) const; + void setCoords(const DataArrayDouble *coordsX, + const DataArrayDouble *coordsY=0, + const DataArrayDouble *coordsZ=0) throw(INTERP_KERNEL::Exception); + void setCoordsAt(int i, const DataArrayDouble *arr) throw(INTERP_KERNEL::Exception); + %extend { + MEDCouplingCMesh() throw(INTERP_KERNEL::Exception) + { + return MEDCouplingCMesh::New(); + } + MEDCouplingCMesh(const std::string& meshName) throw(INTERP_KERNEL::Exception) + { + return MEDCouplingCMesh::New(meshName); + } + // serialization + static PyObject *___new___(PyObject *cls, PyObject *args) throw(INTERP_KERNEL::Exception) + { + return NewMethWrapCallInitOnlyIfEmptyDictInInput(cls,args,"MEDCouplingCMesh"); + } + std::string __str__() const throw(INTERP_KERNEL::Exception) + { + return self->simpleRepr(); + } + std::string __repr__() const throw(INTERP_KERNEL::Exception) + { + std::ostringstream oss; + self->reprQuickOverview(oss); + return oss.str(); + } + DataArrayDouble *getCoordsAt(int i) throw(INTERP_KERNEL::Exception) + { + DataArrayDouble *ret=self->getCoordsAt(i); + if(ret) + ret->incrRef(); + return ret; + } + } + }; + + //== MEDCouplingCMesh End + + //== MEDCouplingCurveLinearMesh + + class MEDCouplingCurveLinearMesh : public ParaMEDMEM::MEDCouplingStructuredMesh + { + public: + static MEDCouplingCurveLinearMesh *New() throw(INTERP_KERNEL::Exception); + static MEDCouplingCurveLinearMesh *New(const std::string& meshName) throw(INTERP_KERNEL::Exception); + MEDCouplingCurveLinearMesh *clone(bool recDeepCpy) const; + void setCoords(const DataArrayDouble *coords) throw(INTERP_KERNEL::Exception); + %extend { + MEDCouplingCurveLinearMesh() throw(INTERP_KERNEL::Exception) + { + return MEDCouplingCurveLinearMesh::New(); + } + MEDCouplingCurveLinearMesh(const std::string& meshName) throw(INTERP_KERNEL::Exception) + { + return MEDCouplingCurveLinearMesh::New(meshName); + } + static PyObject *___new___(PyObject *cls, PyObject *args) throw(INTERP_KERNEL::Exception) + { + return NewMethWrapCallInitOnlyIfEmptyDictInInput(cls,args,"MEDCouplingCurveLinearMesh"); + } + std::string __str__() const throw(INTERP_KERNEL::Exception) + { + return self->simpleRepr(); + } + std::string __repr__() const throw(INTERP_KERNEL::Exception) + { + std::ostringstream oss; + self->reprQuickOverview(oss); + return oss.str(); + } + DataArrayDouble *getCoords() throw(INTERP_KERNEL::Exception) + { + DataArrayDouble *ret=self->getCoords(); + if(ret) + ret->incrRef(); + return ret; + } + void setNodeGridStructure(PyObject *gridStruct) throw(INTERP_KERNEL::Exception) + { + int szArr,sw,iTypppArr; + std::vector<int> stdvecTyyppArr; + const int *tmp=convertObjToPossibleCpp1_Safe(gridStruct,sw,szArr,iTypppArr,stdvecTyyppArr); + self->setNodeGridStructure(tmp,tmp+szArr); + } + } + }; + + //== MEDCouplingCurveLinearMesh End + + //== MEDCouplingIMesh + + class MEDCouplingIMesh : public ParaMEDMEM::MEDCouplingStructuredMesh + { + public: + static MEDCouplingIMesh *New() throw(INTERP_KERNEL::Exception); + // + void setSpaceDimension(int spaceDim) throw(INTERP_KERNEL::Exception); + std::vector<int> getNodeStruct() const throw(INTERP_KERNEL::Exception); + std::vector<double> getOrigin() const throw(INTERP_KERNEL::Exception); + std::vector<double> getDXYZ() const throw(INTERP_KERNEL::Exception); + void setAxisUnit(const std::string& unitName) throw(INTERP_KERNEL::Exception); + std::string getAxisUnit() const throw(INTERP_KERNEL::Exception); + double getMeasureOfAnyCell() const throw(INTERP_KERNEL::Exception); + MEDCouplingCMesh *convertToCartesian() const throw(INTERP_KERNEL::Exception); + void refineWithFactor(const std::vector<int>& factors) throw(INTERP_KERNEL::Exception); + MEDCouplingIMesh *asSingleCell() const throw(INTERP_KERNEL::Exception); + MEDCouplingIMesh *buildWithGhost(int ghostLev) const throw(INTERP_KERNEL::Exception); + %extend + { + MEDCouplingIMesh() + { + return MEDCouplingIMesh::New(); + } + static MEDCouplingIMesh *New(const std::string& meshName, int spaceDim, PyObject *nodeStrct, PyObject *origin, PyObject *dxyz) throw(INTERP_KERNEL::Exception) + { + static const char msg0[]="MEDCouplingIMesh::New : error on 'origin' parameter !"; + static const char msg1[]="MEDCouplingIMesh::New : error on 'dxyz' parameter !"; + const int *nodeStrctPtr(0); + const double *originPtr(0),*dxyzPtr(0); + int sw,sz,val0; + std::vector<int> bb0; + nodeStrctPtr=convertObjToPossibleCpp1_Safe(nodeStrct,sw,sz,val0,bb0); + // + double val,val2; + std::vector<double> bb,bb2; + int sz1,sz2; + originPtr=convertObjToPossibleCpp5_SingleCompo(origin,sw,val,bb,msg0,false,sz1); + dxyzPtr=convertObjToPossibleCpp5_SingleCompo(dxyz,sw,val2,bb2,msg1,false,sz2); + // + return MEDCouplingIMesh::New(meshName,spaceDim,nodeStrctPtr,nodeStrctPtr+sz,originPtr,originPtr+sz1,dxyzPtr,dxyzPtr+sz2); + } + + MEDCouplingIMesh(const std::string& meshName, int spaceDim, PyObject *nodeStrct, PyObject *origin, PyObject *dxyz) throw(INTERP_KERNEL::Exception) + { + return ParaMEDMEM_MEDCouplingIMesh_New__SWIG_1(meshName,spaceDim,nodeStrct,origin,dxyz); + } + + static PyObject *___new___(PyObject *cls, PyObject *args) throw(INTERP_KERNEL::Exception) + { + return NewMethWrapCallInitOnlyIfEmptyDictInInput(cls,args,"MEDCouplingIMesh"); + } + + void setNodeStruct(PyObject *nodeStrct) throw(INTERP_KERNEL::Exception) + { + int sw,sz,val0; + std::vector<int> bb0; + const int *nodeStrctPtr(convertObjToPossibleCpp1_Safe(nodeStrct,sw,sz,val0,bb0)); + self->setNodeStruct(nodeStrctPtr,nodeStrctPtr+sz); + } + + void setOrigin(PyObject *origin) throw(INTERP_KERNEL::Exception) + { + static const char msg[]="MEDCouplingIMesh::setOrigin : invalid input 'origin' parameter ! integer, float, list/tuple of float, DataArrayDouble or DataArrayDoubleTuple supported !"; + double val; + DataArrayDouble *a; + DataArrayDoubleTuple *aa; + std::vector<double> bb; + int sw,nbTuples; + const double *originPtr(convertObjToPossibleCpp5_SingleCompo(origin,sw,val,bb,msg,false,nbTuples)); + self->setOrigin(originPtr,originPtr+nbTuples); + } + + void setDXYZ(PyObject *dxyz) throw(INTERP_KERNEL::Exception) + { + static const char msg[]="MEDCouplingIMesh::setDXYZ : invalid input 'dxyz' parameter ! integer, float, list/tuple of float, DataArrayDouble or DataArrayDoubleTuple supported !"; + double val; + DataArrayDouble *a; + DataArrayDoubleTuple *aa; + std::vector<double> bb; + int sw,nbTuples; + const double *originPtr(convertObjToPossibleCpp5_SingleCompo(dxyz,sw,val,bb,msg,false,nbTuples)); + self->setDXYZ(originPtr,originPtr+nbTuples); + } + + static void CondenseFineToCoarse(const std::vector<int>& coarseSt, const DataArrayDouble *fineDA, PyObject *fineLocInCoarse, const std::vector<int>& facts, DataArrayDouble *coarseDA) throw(INTERP_KERNEL::Exception) + { + std::vector< std::pair<int,int> > inp; + convertPyToVectorPairInt(fineLocInCoarse,inp); + MEDCouplingIMesh::CondenseFineToCoarse(coarseSt,fineDA,inp,facts,coarseDA); + } + + static void CondenseFineToCoarseGhost(const std::vector<int>& coarseSt, const DataArrayDouble *fineDA, PyObject *fineLocInCoarse, const std::vector<int>& facts, DataArrayDouble *coarseDA, int ghostSize) throw(INTERP_KERNEL::Exception) + { + std::vector< std::pair<int,int> > inp; + convertPyToVectorPairInt(fineLocInCoarse,inp); + MEDCouplingIMesh::CondenseFineToCoarseGhost(coarseSt,fineDA,inp,facts,coarseDA,ghostSize); + } + + static void SpreadCoarseToFine(const DataArrayDouble *coarseDA, const std::vector<int>& coarseSt, DataArrayDouble *fineDA, PyObject *fineLocInCoarse, const std::vector<int>& facts) throw(INTERP_KERNEL::Exception) + { + std::vector< std::pair<int,int> > inp; + convertPyToVectorPairInt(fineLocInCoarse,inp); + MEDCouplingIMesh::SpreadCoarseToFine(coarseDA,coarseSt,fineDA,inp,facts); + } + + static void SpreadCoarseToFineGhost(const DataArrayDouble *coarseDA, const std::vector<int>& coarseSt, DataArrayDouble *fineDA, PyObject *fineLocInCoarse, const std::vector<int>& facts, int ghostSize) throw(INTERP_KERNEL::Exception) + { + std::vector< std::pair<int,int> > inp; + convertPyToVectorPairInt(fineLocInCoarse,inp); + MEDCouplingIMesh::SpreadCoarseToFineGhost(coarseDA,coarseSt,fineDA,inp,facts,ghostSize); + } + + static void SpreadCoarseToFineGhostZone(const DataArrayDouble *coarseDA, const std::vector<int>& coarseSt, DataArrayDouble *fineDA, PyObject *fineLocInCoarse, const std::vector<int>& facts, int ghostSize) throw(INTERP_KERNEL::Exception) + { + std::vector< std::pair<int,int> > inp; + convertPyToVectorPairInt(fineLocInCoarse,inp); + MEDCouplingIMesh::SpreadCoarseToFineGhostZone(coarseDA,coarseSt,fineDA,inp,facts,ghostSize); + } + + std::string __str__() const throw(INTERP_KERNEL::Exception) + { + return self->simpleRepr(); + } + std::string __repr__() const throw(INTERP_KERNEL::Exception) + { + std::ostringstream oss; + self->reprQuickOverview(oss); + return oss.str(); + } + } + }; + + //== MEDCouplingIMesh End + +} + +namespace ParaMEDMEM +{ + class MEDCouplingField : public ParaMEDMEM::RefCountObject, public ParaMEDMEM::TimeLabel + { + public: + virtual void checkCoherency() const throw(INTERP_KERNEL::Exception); + virtual bool areCompatibleForMerge(const MEDCouplingField *other) const throw(INTERP_KERNEL::Exception); + virtual bool isEqual(const MEDCouplingField *other, double meshPrec, double valsPrec) const throw(INTERP_KERNEL::Exception); + virtual bool isEqualWithoutConsideringStr(const MEDCouplingField *other, double meshPrec, double valsPrec) const throw(INTERP_KERNEL::Exception); + virtual void copyTinyStringsFrom(const MEDCouplingField *other) throw(INTERP_KERNEL::Exception); + void setMesh(const ParaMEDMEM::MEDCouplingMesh *mesh) throw(INTERP_KERNEL::Exception); + void setName(const char *name) throw(INTERP_KERNEL::Exception); + std::string getDescription() const throw(INTERP_KERNEL::Exception); + void setDescription(const char *desc) throw(INTERP_KERNEL::Exception); + std::string getName() const throw(INTERP_KERNEL::Exception); + TypeOfField getTypeOfField() const throw(INTERP_KERNEL::Exception); + NatureOfField getNature() const throw(INTERP_KERNEL::Exception); + virtual void setNature(NatureOfField nat) throw(INTERP_KERNEL::Exception); + DataArrayDouble *getLocalizationOfDiscr() const throw(INTERP_KERNEL::Exception); + MEDCouplingFieldDouble *buildMeasureField(bool isAbs) const throw(INTERP_KERNEL::Exception); + int getNumberOfTuplesExpected() const throw(INTERP_KERNEL::Exception); + int getNumberOfMeshPlacesExpected() const throw(INTERP_KERNEL::Exception); + void setGaussLocalizationOnType(INTERP_KERNEL::NormalizedCellType type, const std::vector<double>& refCoo, + const std::vector<double>& gsCoo, const std::vector<double>& wg) throw(INTERP_KERNEL::Exception); + void clearGaussLocalizations() 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); + const MEDCouplingGaussLocalization& getGaussLocalization(int locId) const throw(INTERP_KERNEL::Exception); + int getGaussLocalizationIdOfOneType(INTERP_KERNEL::NormalizedCellType type) const throw(INTERP_KERNEL::Exception); + void setDiscretization(MEDCouplingFieldDiscretization *newDisc); + %extend { + PyObject *getMesh() const throw(INTERP_KERNEL::Exception) + { + MEDCouplingMesh *ret1=const_cast<MEDCouplingMesh *>(self->getMesh()); + if(ret1) + ret1->incrRef(); + return convertMesh(ret1,SWIG_POINTER_OWN | 0 ); + } + + PyObject *getDiscretization() throw(INTERP_KERNEL::Exception) + { + MEDCouplingFieldDiscretization *ret=self->getDiscretization(); + if(ret) + ret->incrRef(); + return convertFieldDiscretization(ret,SWIG_POINTER_OWN | 0 ); + } + + PyObject *getGaussLocalizationIdsOfOneType(INTERP_KERNEL::NormalizedCellType type) const throw(INTERP_KERNEL::Exception) + { + std::set<int> ret=self->getGaussLocalizationIdsOfOneType(type); + return convertIntArrToPyList3(ret); + } + + PyObject *isEqualIfNotWhy(const MEDCouplingField *other, double meshPrec, double valsPrec) const throw(INTERP_KERNEL::Exception) + { + std::string ret1; + bool ret0=self->isEqualIfNotWhy(other,meshPrec,valsPrec,ret1); + PyObject *ret=PyTuple_New(2); + PyObject *ret0Py=ret0?Py_True:Py_False; + Py_XINCREF(ret0Py); + PyTuple_SetItem(ret,0,ret0Py); + PyTuple_SetItem(ret,1,PyString_FromString(ret1.c_str())); + return ret; + } + + PyObject *buildSubMeshData(PyObject *li) const throw(INTERP_KERNEL::Exception) + { + DataArrayInt *ret1=0; + MEDCouplingMesh *ret0=0; + void *da=0; + int res1=SWIG_ConvertPtr(li,&da,SWIGTYPE_p_ParaMEDMEM__DataArrayInt, 0 | 0 ); + if (!SWIG_IsOK(res1)) + { + int size; + INTERP_KERNEL::AutoPtr<int> tmp=convertPyToNewIntArr2(li,&size); + ret0=self->buildSubMeshData(tmp,tmp+size,ret1); + } + else + { + DataArrayInt *da2=reinterpret_cast< DataArrayInt * >(da); + if(!da2) + throw INTERP_KERNEL::Exception("Not null DataArrayInt instance expected !"); + da2->checkAllocated(); + ret0=self->buildSubMeshData(da2->getConstPointer(),da2->getConstPointer()+da2->getNbOfElems(),ret1); + } + PyObject *res = PyList_New(2); + PyList_SetItem(res,0,convertMesh(ret0, SWIG_POINTER_OWN | 0 )); + PyList_SetItem(res,1,SWIG_NewPointerObj((void*)ret1,SWIGTYPE_p_ParaMEDMEM__DataArrayInt,SWIG_POINTER_OWN | 0)); + return res; + } + + PyObject *buildSubMeshDataRange(int begin, int end, int step) const throw(INTERP_KERNEL::Exception) + { + DataArrayInt *ret1=0; + int bb,ee,ss; + MEDCouplingMesh *ret0=self->buildSubMeshDataRange(begin,end,step,bb,ee,ss,ret1); + PyObject *res=PyTuple_New(2); + PyTuple_SetItem(res,0,convertMesh(ret0, SWIG_POINTER_OWN | 0 )); + if(ret1) + PyTuple_SetItem(res,1,SWIG_NewPointerObj((void*)ret1,SWIGTYPE_p_ParaMEDMEM__DataArrayInt,SWIG_POINTER_OWN | 0)); + else + { + PyObject *res1=PySlice_New(PyInt_FromLong(bb),PyInt_FromLong(ee),PyInt_FromLong(ss)); + PyTuple_SetItem(res,1,res1); + } + return res; + } + + DataArrayInt *computeTupleIdsToSelectFromCellIds(PyObject *cellIds) const + { + int sw,sz(-1); + int v0; std::vector<int> v1; + const int *cellIdsBg(convertObjToPossibleCpp1_Safe(cellIds,sw,sz,v0,v1)); + return self->computeTupleIdsToSelectFromCellIds(cellIdsBg,cellIdsBg+sz); + } + + void setGaussLocalizationOnCells(PyObject *li, const std::vector<double>& refCoo, + const std::vector<double>& gsCoo, const std::vector<double>& wg) throw(INTERP_KERNEL::Exception) + { + void *da=0; + int res1=SWIG_ConvertPtr(li,&da,SWIGTYPE_p_ParaMEDMEM__DataArrayInt, 0 | 0 ); + if (!SWIG_IsOK(res1)) + { + int size; + INTERP_KERNEL::AutoPtr<int> tmp=convertPyToNewIntArr2(li,&size); + self->setGaussLocalizationOnCells(tmp,((int *)tmp)+size,refCoo,gsCoo,wg); + } + else + { + DataArrayInt *da2=reinterpret_cast< DataArrayInt * >(da); + if(!da2) + throw INTERP_KERNEL::Exception("Not null DataArrayInt instance expected !"); + da2->checkAllocated(); + self->setGaussLocalizationOnCells(da2->getConstPointer(),da2->getConstPointer()+da2->getNbOfElems(),refCoo,gsCoo,wg); + } + } + + PyObject *getCellIdsHavingGaussLocalization(int locId) const throw(INTERP_KERNEL::Exception) + { + std::vector<int> tmp; + self->getCellIdsHavingGaussLocalization(locId,tmp); + DataArrayInt *ret=DataArrayInt::New(); + ret->alloc((int)tmp.size(),1); + std::copy(tmp.begin(),tmp.end(),ret->getPointer()); + return SWIG_NewPointerObj(SWIG_as_voidptr(ret),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 ); + } + + int getNumberOfTuplesExpectedRegardingCode(PyObject *code, PyObject *idsPerType) const throw(INTERP_KERNEL::Exception) + { + std::vector<int> inp0; + convertPyToNewIntArr4(code,1,3,inp0); + std::vector<const DataArrayInt *> inp1; + convertFromPyObjVectorOfObj<const ParaMEDMEM::DataArrayInt *>(idsPerType,SWIGTYPE_p_ParaMEDMEM__DataArrayInt,"DataArrayInt",inp1); + return self->getNumberOfTuplesExpectedRegardingCode(inp0,inp1); + } + } + }; + + class MEDCouplingFieldTemplate : public ParaMEDMEM::MEDCouplingField + { + public: + static MEDCouplingFieldTemplate *New(const MEDCouplingFieldDouble& f) throw(INTERP_KERNEL::Exception); + static MEDCouplingFieldTemplate *New(TypeOfField type); + std::string simpleRepr() const throw(INTERP_KERNEL::Exception); + std::string advancedRepr() const throw(INTERP_KERNEL::Exception); + %extend + { + MEDCouplingFieldTemplate(const MEDCouplingFieldDouble& f) throw(INTERP_KERNEL::Exception) + { + return MEDCouplingFieldTemplate::New(f); + } + + MEDCouplingFieldTemplate(TypeOfField type) throw(INTERP_KERNEL::Exception) + { + return MEDCouplingFieldTemplate::New(type); + } + + std::string __str__() const throw(INTERP_KERNEL::Exception) + { + return self->simpleRepr(); + } + + std::string __repr__() const throw(INTERP_KERNEL::Exception) + { + std::ostringstream oss; + self->reprQuickOverview(oss); + return oss.str(); + } + } + }; + + class MEDCouplingFieldDouble : public ParaMEDMEM::MEDCouplingField + { + public: + static MEDCouplingFieldDouble *New(TypeOfField type, TypeOfTimeDiscretization td=ONE_TIME); + static MEDCouplingFieldDouble *New(const MEDCouplingFieldTemplate& ft, TypeOfTimeDiscretization td=ONE_TIME); + void setTimeUnit(const std::string& unit); + std::string getTimeUnit() const; + void synchronizeTimeWithSupport() 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 throw(INTERP_KERNEL::Exception); + std::string advancedRepr() const throw(INTERP_KERNEL::Exception); + std::string writeVTK(const std::string& fileName, bool isBinary=true) const throw(INTERP_KERNEL::Exception); + MEDCouplingFieldDouble *clone(bool recDeepCpy) const; + MEDCouplingFieldDouble *cloneWithMesh(bool recDeepCpy) const; + MEDCouplingFieldDouble *deepCpy() const; + MEDCouplingFieldDouble *buildNewTimeReprFromThis(TypeOfTimeDiscretization td, bool deepCpy) const throw(INTERP_KERNEL::Exception); + MEDCouplingFieldDouble *nodeToCellDiscretization() const throw(INTERP_KERNEL::Exception); + MEDCouplingFieldDouble *cellToNodeDiscretization() const throw(INTERP_KERNEL::Exception); + TypeOfTimeDiscretization getTimeDiscretization() const throw(INTERP_KERNEL::Exception); + double getIJ(int tupleId, int compoId) const throw(INTERP_KERNEL::Exception); + double getIJK(int cellId, int nodeIdInCell, int compoId) const throw(INTERP_KERNEL::Exception); + void synchronizeTimeWithMesh() throw(INTERP_KERNEL::Exception); + void setArray(DataArrayDouble *array) throw(INTERP_KERNEL::Exception); + void setEndArray(DataArrayDouble *array) throw(INTERP_KERNEL::Exception); + void setTime(double val, int iteration, int order) throw(INTERP_KERNEL::Exception); + void setStartTime(double val, int iteration, int order) throw(INTERP_KERNEL::Exception); + void setEndTime(double val, int iteration, int order) throw(INTERP_KERNEL::Exception); + void applyLin(double a, double b, int compoId) throw(INTERP_KERNEL::Exception); + void applyLin(double a, double b) throw(INTERP_KERNEL::Exception); + int getNumberOfComponents() const throw(INTERP_KERNEL::Exception); + int getNumberOfTuples() const throw(INTERP_KERNEL::Exception); + int getNumberOfValues() const throw(INTERP_KERNEL::Exception); + void setTimeTolerance(double val) throw(INTERP_KERNEL::Exception); + double getTimeTolerance() const throw(INTERP_KERNEL::Exception); + void setIteration(int it) throw(INTERP_KERNEL::Exception); + void setEndIteration(int it) throw(INTERP_KERNEL::Exception); + void setOrder(int order) throw(INTERP_KERNEL::Exception); + void setEndOrder(int order) throw(INTERP_KERNEL::Exception); + void setTimeValue(double val) throw(INTERP_KERNEL::Exception); + void setEndTimeValue(double val) 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); + bool zipConnectivity(int compType,double epsOnVals=1e-15) throw(INTERP_KERNEL::Exception); + bool simplexize(int policy) throw(INTERP_KERNEL::Exception); + MEDCouplingFieldDouble *doublyContractedProduct() const throw(INTERP_KERNEL::Exception); + MEDCouplingFieldDouble *determinant() const throw(INTERP_KERNEL::Exception); + MEDCouplingFieldDouble *eigenValues() const throw(INTERP_KERNEL::Exception); + MEDCouplingFieldDouble *eigenVectors() const throw(INTERP_KERNEL::Exception); + MEDCouplingFieldDouble *inverse() const throw(INTERP_KERNEL::Exception); + MEDCouplingFieldDouble *trace() const throw(INTERP_KERNEL::Exception); + MEDCouplingFieldDouble *deviator() const throw(INTERP_KERNEL::Exception); + MEDCouplingFieldDouble *magnitude() const throw(INTERP_KERNEL::Exception); + MEDCouplingFieldDouble *maxPerTuple() const throw(INTERP_KERNEL::Exception); + void changeNbOfComponents(int newNbOfComp, double dftValue=0.) throw(INTERP_KERNEL::Exception); + void sortPerTuple(bool asc) throw(INTERP_KERNEL::Exception); + MEDCouplingFieldDouble &operator=(double value) throw(INTERP_KERNEL::Exception); + void fillFromAnalytic(int nbOfComp, const std::string& func) throw(INTERP_KERNEL::Exception); + void fillFromAnalytic2(int nbOfComp, const std::string& func) throw(INTERP_KERNEL::Exception); + void fillFromAnalytic3(int nbOfComp, const std::vector<std::string>& varsOrder, const std::string& func) throw(INTERP_KERNEL::Exception); + void applyFunc(int nbOfComp, const std::string& func) throw(INTERP_KERNEL::Exception); + void applyFunc2(int nbOfComp, const std::string& func) throw(INTERP_KERNEL::Exception); + void applyFunc3(int nbOfComp, const std::vector<std::string>& varsOrder, const std::string& func) throw(INTERP_KERNEL::Exception); + void applyFunc(int nbOfComp, double val) throw(INTERP_KERNEL::Exception); + void applyFunc(const std::string& func) throw(INTERP_KERNEL::Exception); + void applyFuncFast32(const std::string& func) throw(INTERP_KERNEL::Exception); + void applyFuncFast64(const std::string& func) throw(INTERP_KERNEL::Exception); + double accumulate(int compId) const throw(INTERP_KERNEL::Exception); + double getMaxValue() const throw(INTERP_KERNEL::Exception); + double getMinValue() const throw(INTERP_KERNEL::Exception); + double getAverageValue() const throw(INTERP_KERNEL::Exception); + double norm2() const throw(INTERP_KERNEL::Exception); + double normMax() const throw(INTERP_KERNEL::Exception); + //do not put a default value to isWAbs because confusion in python with overloaded getWeightedAverageValue method + double getWeightedAverageValue(int compId, bool isWAbs) const throw(INTERP_KERNEL::Exception); + double integral(int compId, bool isWAbs) const throw(INTERP_KERNEL::Exception); + double normL1(int compId) const throw(INTERP_KERNEL::Exception); + double normL2(int compId) const throw(INTERP_KERNEL::Exception); + DataArrayInt *getIdsInRange(double vmin, double vmax) const throw(INTERP_KERNEL::Exception); + MEDCouplingFieldDouble *buildSubPartRange(int begin, int end, int step) const throw(INTERP_KERNEL::Exception); + static MEDCouplingFieldDouble *MergeFields(const MEDCouplingFieldDouble *f1, const MEDCouplingFieldDouble *f2) throw(INTERP_KERNEL::Exception); + static MEDCouplingFieldDouble *MeldFields(const MEDCouplingFieldDouble *f1, const MEDCouplingFieldDouble *f2) throw(INTERP_KERNEL::Exception); + static MEDCouplingFieldDouble *DotFields(const MEDCouplingFieldDouble *f1, const MEDCouplingFieldDouble *f2) throw(INTERP_KERNEL::Exception); + MEDCouplingFieldDouble *dot(const MEDCouplingFieldDouble& other) const throw(INTERP_KERNEL::Exception); + static MEDCouplingFieldDouble *CrossProductFields(const MEDCouplingFieldDouble *f1, const MEDCouplingFieldDouble *f2) throw(INTERP_KERNEL::Exception); + MEDCouplingFieldDouble *crossProduct(const MEDCouplingFieldDouble& other) const throw(INTERP_KERNEL::Exception); + static MEDCouplingFieldDouble *MaxFields(const MEDCouplingFieldDouble *f1, const MEDCouplingFieldDouble *f2) throw(INTERP_KERNEL::Exception); + MEDCouplingFieldDouble *max(const MEDCouplingFieldDouble& other) const throw(INTERP_KERNEL::Exception); + static MEDCouplingFieldDouble *MinFields(const MEDCouplingFieldDouble *f1, const MEDCouplingFieldDouble *f2) throw(INTERP_KERNEL::Exception); + static MEDCouplingFieldDouble *AddFields(const MEDCouplingFieldDouble *f1, const MEDCouplingFieldDouble *f2) throw(INTERP_KERNEL::Exception); + static MEDCouplingFieldDouble *SubstractFields(const MEDCouplingFieldDouble *f1, const MEDCouplingFieldDouble *f2) throw(INTERP_KERNEL::Exception); + static MEDCouplingFieldDouble *MultiplyFields(const MEDCouplingFieldDouble *f1, const MEDCouplingFieldDouble *f2) throw(INTERP_KERNEL::Exception); + static MEDCouplingFieldDouble *DivideFields(const MEDCouplingFieldDouble *f1, const MEDCouplingFieldDouble *f2) throw(INTERP_KERNEL::Exception); + MEDCouplingFieldDouble *min(const MEDCouplingFieldDouble& other) const throw(INTERP_KERNEL::Exception); + MEDCouplingFieldDouble *negate() const throw(INTERP_KERNEL::Exception); + %extend { + MEDCouplingFieldDouble(TypeOfField type, TypeOfTimeDiscretization td=ONE_TIME) + { + return MEDCouplingFieldDouble::New(type,td); + } + + MEDCouplingFieldDouble(const MEDCouplingFieldTemplate& ft, TypeOfTimeDiscretization td=ONE_TIME) + { + return MEDCouplingFieldDouble::New(ft,td); + } + + std::string __str__() const throw(INTERP_KERNEL::Exception) + { + return self->simpleRepr(); + } + + std::string __repr__() const throw(INTERP_KERNEL::Exception) + { + std::ostringstream oss; + self->reprQuickOverview(oss); + return oss.str(); + } + + DataArrayDouble *getArray() throw(INTERP_KERNEL::Exception) + { + DataArrayDouble *ret=self->getArray(); + if(ret) + ret->incrRef(); + return ret; + } + + PyObject *getArrays() const throw(INTERP_KERNEL::Exception) + { + std::vector<DataArrayDouble *> arrs=self->getArrays(); + for(std::vector<DataArrayDouble *>::iterator it=arrs.begin();it!=arrs.end();it++) + if(*it) + (*it)->incrRef(); + int sz=arrs.size(); + PyObject *ret=PyTuple_New(sz); + for(int i=0;i<sz;i++) + { + if(arrs[i]) + PyTuple_SetItem(ret,i,SWIG_NewPointerObj(SWIG_as_voidptr(arrs[i]),SWIGTYPE_p_ParaMEDMEM__DataArrayDouble, SWIG_POINTER_OWN | 0 )); + else + PyTuple_SetItem(ret,i,SWIG_NewPointerObj(SWIG_as_voidptr(0),SWIGTYPE_p_ParaMEDMEM__DataArrayDouble, 0 | 0 )); + } + return ret; + } + + void setArrays(PyObject *ls) throw(INTERP_KERNEL::Exception) + { + std::vector<const DataArrayDouble *> tmp; + convertFromPyObjVectorOfObj<const DataArrayDouble *>(ls,SWIGTYPE_p_ParaMEDMEM__DataArrayDouble,"DataArrayDouble",tmp); + int sz=tmp.size(); + std::vector<DataArrayDouble *> arrs(sz); + for(int i=0;i<sz;i++) + arrs[i]=const_cast<DataArrayDouble *>(tmp[i]); + self->setArrays(arrs); + } + + DataArrayDouble *getEndArray() throw(INTERP_KERNEL::Exception) + { + DataArrayDouble *ret=self->getEndArray(); + if(ret) + ret->incrRef(); + return ret; + } + + PyObject *getValueOn(PyObject *sl) const throw(INTERP_KERNEL::Exception) + { + double val; + DataArrayDouble *a; + DataArrayDoubleTuple *aa; + std::vector<double> bb; + int sw; + const MEDCouplingMesh *mesh=self->getMesh(); + if(!mesh) + throw INTERP_KERNEL::Exception("Python wrap of MEDCouplingFieldDouble::getValueOn : no underlying mesh !"); + int spaceDim=mesh->getSpaceDimension(); + const char msg[]="Python wrap of MEDCouplingFieldDouble::getValueOn : "; + const double *spaceLoc=convertObjToPossibleCpp5_Safe(sl,sw,val,a,aa,bb,msg,1,spaceDim,true); + // + int sz=self->getNumberOfComponents(); + INTERP_KERNEL::AutoPtr<double> res=new double[sz]; + self->getValueOn(spaceLoc,res); + return convertDblArrToPyList(res,sz); + } + + PyObject *getValueOnPos(int i, int j, int k) const throw(INTERP_KERNEL::Exception) + { + int sz=self->getNumberOfComponents(); + INTERP_KERNEL::AutoPtr<double> res=new double[sz]; + self->getValueOnPos(i,j,k,res); + return convertDblArrToPyList(res,sz); + } + + DataArrayDouble *getValueOnMulti(PyObject *locs) const throw(INTERP_KERNEL::Exception) + { + const MEDCouplingMesh *mesh(self->getMesh()); + if(!mesh) + throw INTERP_KERNEL::Exception("Python wrap MEDCouplingFieldDouble::getValueOnMulti : lying on a null mesh !"); + // + int sw,nbPts; + double v0; ParaMEDMEM::DataArrayDouble *v1(0); ParaMEDMEM::DataArrayDoubleTuple *v2(0); std::vector<double> v3; + const double *inp=convertObjToPossibleCpp5_Safe2(locs,sw,v0,v1,v2,v3,"wrap of MEDCouplingFieldDouble::getValueOnMulti", + mesh->getSpaceDimension(),true,nbPts); + return self->getValueOnMulti(inp,nbPts); + } + + PyObject *getValueOn(PyObject *sl, double time) const throw(INTERP_KERNEL::Exception) + { + double val; + DataArrayDouble *a; + DataArrayDoubleTuple *aa; + std::vector<double> bb; + int sw; + const MEDCouplingMesh *mesh=self->getMesh(); + if(!mesh) + throw INTERP_KERNEL::Exception("Python wrap of MEDCouplingFieldDouble::getValueOn : no underlying mesh !"); + int spaceDim=mesh->getSpaceDimension(); + const char msg[]="Python wrap of MEDCouplingFieldDouble::getValueOn : "; + const double *spaceLoc=convertObjToPossibleCpp5_Safe(sl,sw,val,a,aa,bb,msg,1,spaceDim,true); + // + // + int sz=self->getNumberOfComponents(); + INTERP_KERNEL::AutoPtr<double> res=new double[sz]; + self->getValueOn(spaceLoc,time,res); + return convertDblArrToPyList(res,sz); + } + + void setValues(PyObject *li, PyObject *nbOfTuples=0, PyObject *nbOfComp=0) throw(INTERP_KERNEL::Exception) + { + if(self->getArray()!=0) + ParaMEDMEM_DataArrayDouble_setValues__SWIG_0(self->getArray(),li,nbOfTuples,nbOfComp); + else + { + MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> arr=DataArrayDouble::New(); + ParaMEDMEM_DataArrayDouble_setValues__SWIG_0(arr,li,nbOfTuples,nbOfComp); + self->setArray(arr); + } + } + + PyObject *getTime() throw(INTERP_KERNEL::Exception) + { + int tmp1,tmp2; + double tmp0=self->getTime(tmp1,tmp2); + PyObject *res = PyList_New(3); + PyList_SetItem(res,0,SWIG_From_double(tmp0)); + PyList_SetItem(res,1,SWIG_From_int(tmp1)); + PyList_SetItem(res,2,SWIG_From_int(tmp2)); + return res; + } + + PyObject *getStartTime() throw(INTERP_KERNEL::Exception) + { + int tmp1,tmp2; + double tmp0=self->getStartTime(tmp1,tmp2); + PyObject *res = PyList_New(3); + PyList_SetItem(res,0,SWIG_From_double(tmp0)); + PyList_SetItem(res,1,SWIG_From_int(tmp1)); + PyList_SetItem(res,2,SWIG_From_int(tmp2)); + return res; + } + + PyObject *getEndTime() throw(INTERP_KERNEL::Exception) + { + int tmp1,tmp2; + double tmp0=self->getEndTime(tmp1,tmp2); + PyObject *res = PyList_New(3); + PyList_SetItem(res,0,SWIG_From_double(tmp0)); + PyList_SetItem(res,1,SWIG_From_int(tmp1)); + PyList_SetItem(res,2,SWIG_From_int(tmp2)); + return res; + } + PyObject *accumulate() const throw(INTERP_KERNEL::Exception) + { + int sz=self->getNumberOfComponents(); + INTERP_KERNEL::AutoPtr<double> tmp=new double[sz]; + self->accumulate(tmp); + return convertDblArrToPyList(tmp,sz); + } + PyObject *integral(bool isWAbs) const throw(INTERP_KERNEL::Exception) + { + int sz=self->getNumberOfComponents(); + INTERP_KERNEL::AutoPtr<double> tmp=new double[sz]; + self->integral(isWAbs,tmp); + return convertDblArrToPyList(tmp,sz); + } + PyObject *getWeightedAverageValue(bool isWAbs=true) const throw(INTERP_KERNEL::Exception) + { + int sz=self->getNumberOfComponents(); + INTERP_KERNEL::AutoPtr<double> tmp=new double[sz]; + self->getWeightedAverageValue(tmp,isWAbs); + return convertDblArrToPyList(tmp,sz); + } + PyObject *normL1() const throw(INTERP_KERNEL::Exception) + { + int sz=self->getNumberOfComponents(); + INTERP_KERNEL::AutoPtr<double> tmp=new double[sz]; + self->normL1(tmp); + return convertDblArrToPyList(tmp,sz); + } + PyObject *normL2() const throw(INTERP_KERNEL::Exception) + { + int sz=self->getNumberOfComponents(); + INTERP_KERNEL::AutoPtr<double> tmp=new double[sz]; + self->normL2(tmp); + return convertDblArrToPyList(tmp,sz); + } + void renumberCells(PyObject *li, bool check=true) throw(INTERP_KERNEL::Exception) + { + int szArr,sw,iTypppArr; + std::vector<int> stdvecTyyppArr; + const int *tmp=convertObjToPossibleCpp1_Safe(li,sw,szArr,iTypppArr,stdvecTyyppArr); + self->renumberCells(tmp,check); + } + + void renumberCellsWithoutMesh(PyObject *li, bool check=true) throw(INTERP_KERNEL::Exception) + { + int szArr,sw,iTypppArr; + std::vector<int> stdvecTyyppArr; + const int *tmp=convertObjToPossibleCpp1_Safe(li,sw,szArr,iTypppArr,stdvecTyyppArr); + self->renumberCellsWithoutMesh(tmp,check); + } + + void renumberNodes(PyObject *li, double eps=1e-15) throw(INTERP_KERNEL::Exception) + { + int szArr,sw,iTypppArr; + std::vector<int> stdvecTyyppArr; + const int *tmp=convertObjToPossibleCpp1_Safe(li,sw,szArr,iTypppArr,stdvecTyyppArr); + self->renumberNodes(tmp,eps); + } + + void renumberNodesWithoutMesh(PyObject *li, int newNbOfNodes, double eps=1e-15) throw(INTERP_KERNEL::Exception) + { + int szArr,sw,iTypppArr; + std::vector<int> stdvecTyyppArr; + const int *tmp=convertObjToPossibleCpp1_Safe(li,sw,szArr,iTypppArr,stdvecTyyppArr); + self->renumberNodesWithoutMesh(tmp,newNbOfNodes,eps); + } + + MEDCouplingFieldDouble *buildSubPart(PyObject *li) const throw(INTERP_KERNEL::Exception) + { + int sw; + int singleVal; + std::vector<int> multiVal; + std::pair<int, std::pair<int,int> > slic; + ParaMEDMEM::DataArrayInt *daIntTyypp=0; + const MEDCouplingMesh *mesh=self->getMesh(); + if(!mesh) + throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::buildSubPart : field lies on a null mesh !"); + int nbc=mesh->getNumberOfCells(); + convertObjToPossibleCpp2(li,nbc,sw,singleVal,multiVal,slic,daIntTyypp); + switch(sw) + { + case 1: + { + if(singleVal>=nbc) + { + std::ostringstream oss; + oss << "Requesting for cell id " << singleVal << " having only " << nbc << " cells !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + if(singleVal>=0) + return self->buildSubPart(&singleVal,&singleVal+1); + else + { + if(nbc+singleVal>0) + { + int tmp=nbc+singleVal; + return self->buildSubPart(&tmp,&tmp+1); + } + else + { + std::ostringstream oss; + oss << "Requesting for cell id " << singleVal << " having only " << nbc << " cells !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + } + } + case 2: + { + return self->buildSubPart(&multiVal[0],&multiVal[0]+multiVal.size()); + } + case 3: + { + return self->buildSubPartRange(slic.first,slic.second.first,slic.second.second); + } + case 4: + { + if(!daIntTyypp) + throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::buildSubPart : null instance has been given in input !"); + daIntTyypp->checkAllocated(); + return self->buildSubPart(daIntTyypp->begin(),daIntTyypp->end()); + } + default: + throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::buildSubPart : unrecognized type in input ! Possibilities are : int, list or tuple of int DataArrayInt instance !"); + } + } + + MEDCouplingFieldDouble *__getitem__(PyObject *li) const throw(INTERP_KERNEL::Exception) + { + const char msg[]="MEDCouplingFieldDouble::__getitem__ : invalid call Available API are : \n-myField[dataArrayInt]\n-myField[slice]\n-myField[pythonListOfCellIds]\n-myField[integer]\n-myField[dataArrayInt,1]\n-myField[slice,1]\n-myField[pythonListOfCellIds,1]\n-myField[integer,1]\n"; + if(PyTuple_Check(li)) + { + Py_ssize_t sz=PyTuple_Size(li); + if(sz!=2) + throw INTERP_KERNEL::Exception(msg); + PyObject *elt0=PyTuple_GetItem(li,0),*elt1=PyTuple_GetItem(li,1); + int sw; + int singleVal; + std::vector<int> multiVal; + std::pair<int, std::pair<int,int> > slic; + ParaMEDMEM::DataArrayInt *daIntTyypp=0; + if(!self->getArray()) + throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::__getitem__ : no array set on field to deduce number of components !"); + try + { convertObjToPossibleCpp2(elt1,self->getArray()->getNumberOfComponents(),sw,singleVal,multiVal,slic,daIntTyypp); } + catch(INTERP_KERNEL::Exception& e) + { std::ostringstream oss; oss << "MEDCouplingFieldDouble::__getitem__ : invalid type in 2nd parameter (compo) !" << e.what(); throw INTERP_KERNEL::Exception(oss.str().c_str()); } + MEDCouplingAutoRefCountObjectPtr<MEDCouplingFieldDouble> ret0=ParaMEDMEM_MEDCouplingFieldDouble_buildSubPart(self,elt0); + DataArrayDouble *ret0Arr=ret0->getArray(); + if(!ret0Arr) + throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble::__getitem__ : no array exists to apply restriction on component on it !"); + switch(sw) + { + case 1: + { + std::vector<int> v2(1,singleVal); + MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> aarr(ret0Arr->keepSelectedComponents(v2)); + ret0->setArray(aarr); + return ret0.retn(); + } + case 2: + { + MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> aarr(ret0Arr->keepSelectedComponents(multiVal)); + ret0->setArray(aarr); + return ret0.retn(); + } + case 3: + { + int nbOfComp=DataArray::GetNumberOfItemGivenBESRelative(slic.first,slic.second.first,slic.second.second,"MEDCouplingFieldDouble::__getitem__ : invalid range in 2nd parameter (components) !"); + std::vector<int> v2(nbOfComp); + for(int i=0;i<nbOfComp;i++) + v2[i]=slic.first+i*slic.second.second; + MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> aarr(ret0Arr->keepSelectedComponents(v2)); + ret0->setArray(aarr); + return ret0.retn(); + } + default: + throw INTERP_KERNEL::Exception(msg); + } + + } + else + return ParaMEDMEM_MEDCouplingFieldDouble_buildSubPart(self,li); + } + + PyObject *getMaxValue2() const throw(INTERP_KERNEL::Exception) + { + DataArrayInt *tmp; + double r1=self->getMaxValue2(tmp); + PyObject *ret=PyTuple_New(2); + PyTuple_SetItem(ret,0,PyFloat_FromDouble(r1)); + PyTuple_SetItem(ret,1,SWIG_NewPointerObj(SWIG_as_voidptr(tmp),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 )); + return ret; + } + + PyObject *getMinValue2() const throw(INTERP_KERNEL::Exception) + { + DataArrayInt *tmp; + double r1=self->getMinValue2(tmp); + PyObject *ret=PyTuple_New(2); + PyTuple_SetItem(ret,0,PyFloat_FromDouble(r1)); + PyTuple_SetItem(ret,1,SWIG_NewPointerObj(SWIG_as_voidptr(tmp),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 )); + return ret; + } + + MEDCouplingFieldDouble *keepSelectedComponents(PyObject *li) const throw(INTERP_KERNEL::Exception) + { + std::vector<int> tmp; + convertPyToNewIntArr3(li,tmp); + return self->keepSelectedComponents(tmp); + } + + void setSelectedComponents(const MEDCouplingFieldDouble *f, PyObject *li) throw(INTERP_KERNEL::Exception) + { + std::vector<int> tmp; + convertPyToNewIntArr3(li,tmp); + self->setSelectedComponents(f,tmp); + } + + MEDCouplingFieldDouble *extractSlice3D(PyObject *origin, PyObject *vec, double eps) const throw(INTERP_KERNEL::Exception) + { + double val,val2; + DataArrayDouble *a,*a2; + DataArrayDoubleTuple *aa,*aa2; + std::vector<double> bb,bb2; + int sw; + int spaceDim=3; + const char msg[]="Python wrap of MEDCouplingFieldDouble::extractSlice3D : 1st paramater for origin."; + const char msg2[]="Python wrap of MEDCouplingFieldDouble::extractSlice3D : 2nd paramater for vector."; + const double *orig=convertObjToPossibleCpp5_Safe(origin,sw,val,a,aa,bb,msg,1,spaceDim,true); + const double *vect=convertObjToPossibleCpp5_Safe(vec,sw,val2,a2,aa2,bb2,msg2,1,spaceDim,true); + // + return self->extractSlice3D(orig,vect,eps); + } + + MEDCouplingFieldDouble *__add__(PyObject *obj) throw(INTERP_KERNEL::Exception) + { + return ParaMEDMEM_MEDCouplingFieldDouble___add__Impl(self,obj); + } + + MEDCouplingFieldDouble *__radd__(PyObject *obj) throw(INTERP_KERNEL::Exception) + { + return ParaMEDMEM_MEDCouplingFieldDouble___radd__Impl(self,obj); + } + + MEDCouplingFieldDouble *__sub__(PyObject *obj) throw(INTERP_KERNEL::Exception) + { + const char msg[]="Unexpected situation in MEDCouplingFieldDouble.__sub__ ! Expecting a not null MEDCouplingFieldDouble or DataArrayDouble or DataArrayDoubleTuple instance, or a list of double, or a double."; + const char msg2[]="in MEDCouplingFieldDouble.__sub__ : self field has no Array of values set !"; + void *argp; + // + if(SWIG_IsOK(SWIG_ConvertPtr(obj,&argp,SWIGTYPE_p_ParaMEDMEM__MEDCouplingFieldDouble,0|0))) + { + MEDCouplingFieldDouble *other=reinterpret_cast< ParaMEDMEM::MEDCouplingFieldDouble * >(argp); + if(other) + return (*self)-(*other); + else + throw INTERP_KERNEL::Exception(msg); + } + // + double val; + DataArrayDouble *a; + DataArrayDoubleTuple *aa; + std::vector<double> bb; + int sw; + convertObjToPossibleCpp5(obj,sw,val,a,aa,bb); + switch(sw) + { + case 1: + { + if(!self->getArray()) + throw INTERP_KERNEL::Exception(msg2); + MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=self->getArray()->deepCpy(); + ret->applyLin(1.,-val); + MEDCouplingAutoRefCountObjectPtr<MEDCouplingFieldDouble> ret2=self->clone(false); + ret2->setArray(ret); + return ret2.retn(); + } + case 2: + { + if(!self->getArray()) + throw INTERP_KERNEL::Exception(msg2); + MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::Substract(self->getArray(),a); + MEDCouplingAutoRefCountObjectPtr<MEDCouplingFieldDouble> ret2=self->clone(false); + ret2->setArray(ret); + return ret2.retn(); + } + case 3: + { + if(!self->getArray()) + throw INTERP_KERNEL::Exception(msg2); + MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> aaa=aa->buildDADouble(1,self->getNumberOfComponents()); + MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::Substract(self->getArray(),aaa); + MEDCouplingAutoRefCountObjectPtr<MEDCouplingFieldDouble> ret2=self->clone(false); + ret2->setArray(ret); + return ret2.retn(); + } + case 4: + { + if(!self->getArray()) + throw INTERP_KERNEL::Exception(msg2); + MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> aaa=DataArrayDouble::New(); aaa->useArray(&bb[0],false,CPP_DEALLOC,1,(int)bb.size()); + MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::Substract(self->getArray(),aaa); + MEDCouplingAutoRefCountObjectPtr<MEDCouplingFieldDouble> ret2=self->clone(false); + ret2->setArray(ret); + return ret2.retn(); + } + default: + { throw INTERP_KERNEL::Exception(msg); } + } + } + + MEDCouplingFieldDouble *__rsub__(PyObject *obj) throw(INTERP_KERNEL::Exception) + { + return ParaMEDMEM_MEDCouplingFieldDouble___rsub__Impl(self,obj); + } + + MEDCouplingFieldDouble *__mul__(PyObject *obj) throw(INTERP_KERNEL::Exception) + { + return ParaMEDMEM_MEDCouplingFieldDouble___mul__Impl(self,obj); + } + + MEDCouplingFieldDouble *__rmul__(PyObject *obj) throw(INTERP_KERNEL::Exception) + { + return ParaMEDMEM_MEDCouplingFieldDouble___rmul__Impl(self,obj); + } + + MEDCouplingFieldDouble *__div__(PyObject *obj) throw(INTERP_KERNEL::Exception) + { + const char msg[]="Unexpected situation in MEDCouplingFieldDouble.__div__ ! Expecting a not null MEDCouplingFieldDouble or DataArrayDouble or DataArrayDoubleTuple instance, or a list of double, or a double."; + const char msg2[]="in MEDCouplingFieldDouble.__div__ : self field has no Array of values set !"; + void *argp; + // + if(SWIG_IsOK(SWIG_ConvertPtr(obj,&argp,SWIGTYPE_p_ParaMEDMEM__MEDCouplingFieldDouble,0|0))) + { + MEDCouplingFieldDouble *other=reinterpret_cast< ParaMEDMEM::MEDCouplingFieldDouble * >(argp); + if(other) + return (*self)/(*other); + else + throw INTERP_KERNEL::Exception(msg); + } + // + double val; + DataArrayDouble *a; + DataArrayDoubleTuple *aa; + std::vector<double> bb; + int sw; + convertObjToPossibleCpp5(obj,sw,val,a,aa,bb); + switch(sw) + { + case 1: + { + if(val==0.) + throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble.__div__ : trying to divide by zero !"); + if(!self->getArray()) + throw INTERP_KERNEL::Exception(msg2); + MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=self->getArray()->deepCpy(); + ret->applyLin(1./val,0); + MEDCouplingAutoRefCountObjectPtr<MEDCouplingFieldDouble> ret2=self->clone(false); + ret2->setArray(ret); + return ret2.retn(); + } + case 2: + { + if(!self->getArray()) + throw INTERP_KERNEL::Exception(msg2); + MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::Divide(self->getArray(),a); + MEDCouplingAutoRefCountObjectPtr<MEDCouplingFieldDouble> ret2=self->clone(false); + ret2->setArray(ret); + return ret2.retn(); + } + case 3: + { + if(!self->getArray()) + throw INTERP_KERNEL::Exception(msg2); + MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> aaa=aa->buildDADouble(1,self->getNumberOfComponents()); + MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::Divide(self->getArray(),aaa); + MEDCouplingAutoRefCountObjectPtr<MEDCouplingFieldDouble> ret2=self->clone(false); + ret2->setArray(ret); + return ret2.retn(); + } + case 4: + { + if(!self->getArray()) + throw INTERP_KERNEL::Exception(msg2); + MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> aaa=DataArrayDouble::New(); aaa->useArray(&bb[0],false,CPP_DEALLOC,1,(int)bb.size()); + MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::Divide(self->getArray(),aaa); + MEDCouplingAutoRefCountObjectPtr<MEDCouplingFieldDouble> ret2=self->clone(false); + ret2->setArray(ret); + return ret2.retn(); + } + default: + { throw INTERP_KERNEL::Exception(msg); } + } + } + + MEDCouplingFieldDouble *__rdiv__(PyObject *obj) throw(INTERP_KERNEL::Exception) + { + return ParaMEDMEM_MEDCouplingFieldDouble___rdiv__Impl(self,obj); + } + + MEDCouplingFieldDouble *__pow__(PyObject *obj) throw(INTERP_KERNEL::Exception) + { + const char msg[]="Unexpected situation in MEDCouplingFieldDouble.__pow__ ! Expecting a not null MEDCouplingFieldDouble or DataArrayDouble or DataArrayDoubleTuple instance, or a list of double, or a double."; + const char msg2[]="in MEDCouplingFieldDouble.__pow__ : self field has no Array of values set !"; + void *argp; + // + if(SWIG_IsOK(SWIG_ConvertPtr(obj,&argp,SWIGTYPE_p_ParaMEDMEM__MEDCouplingFieldDouble,0|0))) + { + MEDCouplingFieldDouble *other=reinterpret_cast< ParaMEDMEM::MEDCouplingFieldDouble * >(argp); + if(other) + return (*self)^(*other); + else + throw INTERP_KERNEL::Exception(msg); + } + // + double val; + DataArrayDouble *a; + DataArrayDoubleTuple *aa; + std::vector<double> bb; + int sw; + convertObjToPossibleCpp5(obj,sw,val,a,aa,bb); + switch(sw) + { + case 1: + { + if(!self->getArray()) + throw INTERP_KERNEL::Exception(msg2); + MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=self->getArray()->deepCpy(); + ret->applyPow(val); + MEDCouplingAutoRefCountObjectPtr<MEDCouplingFieldDouble> ret2=self->clone(false); + ret2->setArray(ret); + return ret2.retn(); + } + case 2: + { + if(!self->getArray()) + throw INTERP_KERNEL::Exception(msg2); + MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::Pow(self->getArray(),a); + MEDCouplingAutoRefCountObjectPtr<MEDCouplingFieldDouble> ret2=self->clone(false); + ret2->setArray(ret); + return ret2.retn(); + } + case 3: + { + if(!self->getArray()) + throw INTERP_KERNEL::Exception(msg2); + MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> aaa=aa->buildDADouble(1,self->getNumberOfComponents()); + MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::Pow(self->getArray(),aaa); + MEDCouplingAutoRefCountObjectPtr<MEDCouplingFieldDouble> ret2=self->clone(false); + ret2->setArray(ret); + return ret2.retn(); + } + case 4: + { + if(!self->getArray()) + throw INTERP_KERNEL::Exception(msg2); + MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> aaa=DataArrayDouble::New(); aaa->useArray(&bb[0],false,CPP_DEALLOC,1,(int)bb.size()); + MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::Pow(self->getArray(),aaa); + MEDCouplingAutoRefCountObjectPtr<MEDCouplingFieldDouble> ret2=self->clone(false); + ret2->setArray(ret); + return ret2.retn(); + } + default: + { throw INTERP_KERNEL::Exception(msg); } + } + } + + MEDCouplingFieldDouble *__neg__() const throw(INTERP_KERNEL::Exception) + { + return self->negate(); + } + + PyObject *___iadd___(PyObject *trueSelf, PyObject *obj) throw(INTERP_KERNEL::Exception) + { + const char msg[]="Unexpected situation in MEDCouplingFieldDouble.__iadd__ ! Expecting a not null MEDCouplingFieldDouble or DataArrayDouble or DataArrayDoubleTuple instance, or a list of double, or a double."; + const char msg2[]="in MEDCouplingFieldDouble.__iadd__ : self field has no Array of values set !"; + void *argp; + // + if(SWIG_IsOK(SWIG_ConvertPtr(obj,&argp,SWIGTYPE_p_ParaMEDMEM__MEDCouplingFieldDouble,0|0))) + { + MEDCouplingFieldDouble *other=reinterpret_cast< ParaMEDMEM::MEDCouplingFieldDouble * >(argp); + if(other) + { + *self+=*other; + Py_XINCREF(trueSelf); + return trueSelf; + } + else + throw INTERP_KERNEL::Exception(msg); + } + // + double val; + DataArrayDouble *a; + DataArrayDoubleTuple *aa; + std::vector<double> bb; + int sw; + convertObjToPossibleCpp5(obj,sw,val,a,aa,bb); + switch(sw) + { + case 1: + { + if(!self->getArray()) + throw INTERP_KERNEL::Exception(msg2); + self->getArray()->applyLin(1.,val); + Py_XINCREF(trueSelf); + return trueSelf; + } + case 2: + { + MEDCouplingAutoRefCountObjectPtr<MEDCouplingFieldDouble> ret2=self->clone(false); + ret2->setArray(a); + *self+=*ret2; + Py_XINCREF(trueSelf); + return trueSelf; + } + case 3: + { + MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> aaa=aa->buildDADouble(1,self->getNumberOfComponents()); + MEDCouplingAutoRefCountObjectPtr<MEDCouplingFieldDouble> ret2=self->clone(false); + ret2->setArray(aaa); + *self+=*ret2; + Py_XINCREF(trueSelf); + return trueSelf; + } + case 4: + { + if(!self->getArray()) + throw INTERP_KERNEL::Exception(msg2); + MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> aaa=DataArrayDouble::New(); aaa->useArray(&bb[0],false,CPP_DEALLOC,1,(int)bb.size()); + self->getArray()->addEqual(aaa); + Py_XINCREF(trueSelf); + return trueSelf; + } + default: + { throw INTERP_KERNEL::Exception(msg); } + } + } + + PyObject *___isub___(PyObject *trueSelf, PyObject *obj) throw(INTERP_KERNEL::Exception) + { + const char msg[]="Unexpected situation in MEDCouplingFieldDouble.__isub__ ! Expecting a not null MEDCouplingFieldDouble or DataArrayDouble or DataArrayDoubleTuple instance, or a list of double, or a double."; + const char msg2[]="in MEDCouplingFieldDouble.__isub__ : self field has no Array of values set !"; + void *argp; + // + if(SWIG_IsOK(SWIG_ConvertPtr(obj,&argp,SWIGTYPE_p_ParaMEDMEM__MEDCouplingFieldDouble,0|0))) + { + MEDCouplingFieldDouble *other=reinterpret_cast< ParaMEDMEM::MEDCouplingFieldDouble * >(argp); + if(other) + { + *self-=*other; + Py_XINCREF(trueSelf); + return trueSelf; + } + else + throw INTERP_KERNEL::Exception(msg); + } + // + double val; + DataArrayDouble *a; + DataArrayDoubleTuple *aa; + std::vector<double> bb; + int sw; + convertObjToPossibleCpp5(obj,sw,val,a,aa,bb); + switch(sw) + { + case 1: + { + if(!self->getArray()) + throw INTERP_KERNEL::Exception(msg2); + self->getArray()->applyLin(1.,-val); + Py_XINCREF(trueSelf); + return trueSelf; + } + case 2: + { + MEDCouplingAutoRefCountObjectPtr<MEDCouplingFieldDouble> ret2=self->clone(false); + ret2->setArray(a); + *self-=*ret2; + Py_XINCREF(trueSelf); + return trueSelf; + } + case 3: + { + MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> aaa=aa->buildDADouble(1,self->getNumberOfComponents()); + MEDCouplingAutoRefCountObjectPtr<MEDCouplingFieldDouble> ret2=self->clone(false); + ret2->setArray(aaa); + *self-=*ret2; + Py_XINCREF(trueSelf); + return trueSelf; + } + case 4: + { + if(!self->getArray()) + throw INTERP_KERNEL::Exception(msg2); + MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> aaa=DataArrayDouble::New(); aaa->useArray(&bb[0],false,CPP_DEALLOC,1,(int)bb.size()); + self->getArray()->substractEqual(aaa); + Py_XINCREF(trueSelf); + return trueSelf; + } + default: + { throw INTERP_KERNEL::Exception(msg); } + } + } + + PyObject *___imul___(PyObject *trueSelf, PyObject *obj) throw(INTERP_KERNEL::Exception) + { + const char msg[]="Unexpected situation in MEDCouplingFieldDouble.__imul__ ! Expecting a not null MEDCouplingFieldDouble or DataArrayDouble or DataArrayDoubleTuple instance, or a list of double, or a double."; + const char msg2[]="in MEDCouplingFieldDouble.__imul__ : self field has no Array of values set !"; + void *argp; + // + if(SWIG_IsOK(SWIG_ConvertPtr(obj,&argp,SWIGTYPE_p_ParaMEDMEM__MEDCouplingFieldDouble,0|0))) + { + MEDCouplingFieldDouble *other=reinterpret_cast< ParaMEDMEM::MEDCouplingFieldDouble * >(argp); + if(other) + { + *self*=*other; + Py_XINCREF(trueSelf); + return trueSelf; + } + else + throw INTERP_KERNEL::Exception(msg); + } + // + double val; + DataArrayDouble *a; + DataArrayDoubleTuple *aa; + std::vector<double> bb; + int sw; + convertObjToPossibleCpp5(obj,sw,val,a,aa,bb); + switch(sw) + { + case 1: + { + if(!self->getArray()) + throw INTERP_KERNEL::Exception(msg2); + self->getArray()->applyLin(val,0); + Py_XINCREF(trueSelf); + return trueSelf; + } + case 2: + { + MEDCouplingAutoRefCountObjectPtr<MEDCouplingFieldDouble> ret2=self->clone(false); + ret2->setArray(a); + *self*=*ret2; + Py_XINCREF(trueSelf); + return trueSelf; + } + case 3: + { + MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> aaa=aa->buildDADouble(1,self->getNumberOfComponents()); + MEDCouplingAutoRefCountObjectPtr<MEDCouplingFieldDouble> ret2=self->clone(false); + ret2->setArray(aaa); + *self*=*ret2; + Py_XINCREF(trueSelf); + return trueSelf; + } + case 4: + { + if(!self->getArray()) + throw INTERP_KERNEL::Exception(msg2); + MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> aaa=DataArrayDouble::New(); aaa->useArray(&bb[0],false,CPP_DEALLOC,1,(int)bb.size()); + self->getArray()->multiplyEqual(aaa); + Py_XINCREF(trueSelf); + return trueSelf; + } + default: + { throw INTERP_KERNEL::Exception(msg); } + } + } + + PyObject *___idiv___(PyObject *trueSelf, PyObject *obj) throw(INTERP_KERNEL::Exception) + { + const char msg[]="Unexpected situation in MEDCouplingFieldDouble.__idiv__ ! Expecting a not null MEDCouplingFieldDouble or DataArrayDouble or DataArrayDoubleTuple instance, or a list of double, or a double."; + const char msg2[]="in MEDCouplingFieldDouble.__idiv__ : self field has no Array of values set !"; + void *argp; + // + if(SWIG_IsOK(SWIG_ConvertPtr(obj,&argp,SWIGTYPE_p_ParaMEDMEM__MEDCouplingFieldDouble,0|0))) + { + MEDCouplingFieldDouble *other=reinterpret_cast< ParaMEDMEM::MEDCouplingFieldDouble * >(argp); + if(other) + { + *self/=*other; + Py_XINCREF(trueSelf); + return trueSelf; + } + else + throw INTERP_KERNEL::Exception(msg); + } + // + double val; + DataArrayDouble *a; + DataArrayDoubleTuple *aa; + std::vector<double> bb; + int sw; + convertObjToPossibleCpp5(obj,sw,val,a,aa,bb); + switch(sw) + { + case 1: + { + if(val==0.) + throw INTERP_KERNEL::Exception("MEDCouplingFieldDouble.__idiv__ : trying to divide by zero !"); + if(!self->getArray()) + throw INTERP_KERNEL::Exception(msg2); + self->getArray()->applyLin(1./val,0); + Py_XINCREF(trueSelf); + return trueSelf; + } + case 2: + { + MEDCouplingAutoRefCountObjectPtr<MEDCouplingFieldDouble> ret2=self->clone(false); + ret2->setArray(a); + *self/=*ret2; + Py_XINCREF(trueSelf); + return trueSelf; + } + case 3: + { + MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> aaa=aa->buildDADouble(1,self->getNumberOfComponents()); + MEDCouplingAutoRefCountObjectPtr<MEDCouplingFieldDouble> ret2=self->clone(false); + ret2->setArray(aaa); + *self/=*ret2; + Py_XINCREF(trueSelf); + return trueSelf; + } + case 4: + { + if(!self->getArray()) + throw INTERP_KERNEL::Exception(msg2); + MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> aaa=DataArrayDouble::New(); aaa->useArray(&bb[0],false,CPP_DEALLOC,1,(int)bb.size()); + self->getArray()->divideEqual(aaa); + Py_XINCREF(trueSelf); + return trueSelf; + } + default: + { throw INTERP_KERNEL::Exception(msg); } + } + } + + PyObject *___ipow___(PyObject *trueSelf, PyObject *obj) throw(INTERP_KERNEL::Exception) + { + const char msg[]="Unexpected situation in MEDCouplingFieldDouble.__ipow__ ! Expecting a not null MEDCouplingFieldDouble or DataArrayDouble or DataArrayDoubleTuple instance, or a list of double, or a double."; + const char msg2[]="in MEDCouplingFieldDouble.__ipow__ : self field has no Array of values set !"; + void *argp; + // + if(SWIG_IsOK(SWIG_ConvertPtr(obj,&argp,SWIGTYPE_p_ParaMEDMEM__MEDCouplingFieldDouble,0|0))) + { + MEDCouplingFieldDouble *other=reinterpret_cast< ParaMEDMEM::MEDCouplingFieldDouble * >(argp); + if(other) + { + *self^=*other; + Py_XINCREF(trueSelf); + return trueSelf; + } + else + throw INTERP_KERNEL::Exception(msg); + } + // + double val; + DataArrayDouble *a; + DataArrayDoubleTuple *aa; + std::vector<double> bb; + int sw; + convertObjToPossibleCpp5(obj,sw,val,a,aa,bb); + switch(sw) + { + case 1: + { + if(!self->getArray()) + throw INTERP_KERNEL::Exception(msg2); + self->getArray()->applyPow(val); + Py_XINCREF(trueSelf); + return trueSelf; + } + case 2: + { + MEDCouplingAutoRefCountObjectPtr<MEDCouplingFieldDouble> ret2=self->clone(false); + ret2->setArray(a); + *self^=*ret2; + Py_XINCREF(trueSelf); + return trueSelf; + } + case 3: + { + MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> aaa=aa->buildDADouble(1,self->getNumberOfComponents()); + MEDCouplingAutoRefCountObjectPtr<MEDCouplingFieldDouble> ret2=self->clone(false); + ret2->setArray(aaa); + *self^=*ret2; + Py_XINCREF(trueSelf); + return trueSelf; + } + case 4: + { + if(!self->getArray()) + throw INTERP_KERNEL::Exception(msg2); + MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> aaa=DataArrayDouble::New(); aaa->useArray(&bb[0],false,CPP_DEALLOC,1,(int)bb.size()); + self->getArray()->powEqual(aaa); + Py_XINCREF(trueSelf); + return trueSelf; + } + default: + { throw INTERP_KERNEL::Exception(msg); } + } + } + + static MEDCouplingFieldDouble *MergeFields(PyObject *li) throw(INTERP_KERNEL::Exception) + { + std::vector<const MEDCouplingFieldDouble *> tmp; + convertFromPyObjVectorOfObj<const ParaMEDMEM::MEDCouplingFieldDouble *>(li,SWIGTYPE_p_ParaMEDMEM__MEDCouplingFieldDouble,"MEDCouplingFieldDouble",tmp); + return MEDCouplingFieldDouble::MergeFields(tmp); + } + + static std::string WriteVTK(const char *fileName, PyObject *li, bool isBinary=true) throw(INTERP_KERNEL::Exception) + { + std::vector<const MEDCouplingFieldDouble *> tmp; + convertFromPyObjVectorOfObj<const ParaMEDMEM::MEDCouplingFieldDouble *>(li,SWIGTYPE_p_ParaMEDMEM__MEDCouplingFieldDouble,"MEDCouplingFieldDouble",tmp); + return MEDCouplingFieldDouble::WriteVTK(fileName,tmp,isBinary); + } + + PyObject *getTinySerializationInformation() const throw(INTERP_KERNEL::Exception) + { + std::vector<double> a0; + std::vector<int> a1; + std::vector<std::string> a2; + self->getTinySerializationDbleInformation(a0); + self->getTinySerializationIntInformation(a1); + self->getTinySerializationStrInformation(a2); + // + PyObject *ret(PyTuple_New(3)); + PyTuple_SetItem(ret,0,convertDblArrToPyList2(a0)); + PyTuple_SetItem(ret,1,convertIntArrToPyList2(a1)); + int sz(a2.size()); + PyObject *ret2(PyList_New(sz)); + { + for(int i=0;i<sz;i++) + PyList_SetItem(ret2,i,PyString_FromString(a2[i].c_str())); + } + PyTuple_SetItem(ret,2,ret2); + return ret; + } + + PyObject *serialize() const throw(INTERP_KERNEL::Exception) + { + DataArrayInt *ret0(0); + std::vector<DataArrayDouble *> ret1; + self->serialize(ret0,ret1); + if(ret0) + ret0->incrRef(); + std::size_t sz(ret1.size()); + PyObject *ret(PyTuple_New(2)); + PyTuple_SetItem(ret,0,SWIG_NewPointerObj(SWIG_as_voidptr(ret0),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 )); + PyObject *ret1Py(PyList_New(sz)); + for(std::size_t i=0;i<sz;i++) + { + if(ret1[i]) + ret1[i]->incrRef(); + PyList_SetItem(ret1Py,i,SWIG_NewPointerObj(SWIG_as_voidptr(ret1[i]),SWIGTYPE_p_ParaMEDMEM__DataArrayDouble, SWIG_POINTER_OWN | 0 )); + } + PyTuple_SetItem(ret,1,ret1Py); + return ret; + } + + static PyObject *___new___(PyObject *cls, PyObject *args) throw(INTERP_KERNEL::Exception) + { + static const char MSG[]="MEDCouplingFieldDouble.__new__ : the args in input is expected to be a tuple !"; + if(!PyTuple_Check(args)) + throw INTERP_KERNEL::Exception(MSG); + PyObject *builtinsd(PyEval_GetBuiltins());//borrowed + PyObject *obj(PyDict_GetItemString(builtinsd,"object"));//borrowed + PyObject *selfMeth(PyObject_GetAttrString(obj,"__new__")); + // + PyObject *tmp0(PyTuple_New(1)); + PyTuple_SetItem(tmp0,0,cls); Py_XINCREF(cls); + PyObject *instance(PyObject_CallObject(selfMeth,tmp0)); + Py_DECREF(tmp0); + Py_DECREF(selfMeth); + if(PyTuple_Size(args)==2 && PyDict_Check(PyTuple_GetItem(args,1)) && PyDict_Size(PyTuple_GetItem(args,1))==1 ) + {// NOT general case. only true if in unpickeling context ! call __init__. Because for all other cases, __init__ is called right after __new__ ! + PyObject *initMeth(PyObject_GetAttrString(instance,"__init__")); + //// + PyObject *a(PyInt_FromLong(0)); + PyObject *uniqueElt(PyDict_GetItem(PyTuple_GetItem(args,1),a)); + Py_DECREF(a); + if(!uniqueElt) + throw INTERP_KERNEL::Exception(MSG); + if(!PyTuple_Check(uniqueElt) || PyTuple_Size(uniqueElt)!=2) + throw INTERP_KERNEL::Exception(MSG); + PyObject *tmp2(PyObject_CallObject(initMeth,uniqueElt)); + Py_XDECREF(tmp2); + //// + Py_DECREF(initMeth); + } + return instance; + } + + PyObject *__getnewargs__() throw(INTERP_KERNEL::Exception) + {// put an empty dict in input to say to __new__ to call __init__... + self->checkCoherency(); + PyObject *ret(PyTuple_New(1)); + PyObject *ret0(PyDict_New()); + { + PyObject *a(PyInt_FromLong(0)),*b(PyInt_FromLong(self->getTypeOfField())),*c(PyInt_FromLong(self->getTimeDiscretization())); + PyObject *d(PyTuple_New(2)); PyTuple_SetItem(d,0,b); PyTuple_SetItem(d,1,c); + PyDict_SetItem(ret0,a,d); + Py_DECREF(a); Py_DECREF(d); + } + PyTuple_SetItem(ret,0,ret0); + return ret; + } + + PyObject *__getstate__() const throw(INTERP_KERNEL::Exception) + { + self->checkCoherency(); + PyObject *ret0(ParaMEDMEM_MEDCouplingFieldDouble_getTinySerializationInformation(self)); + PyObject *ret1(ParaMEDMEM_MEDCouplingFieldDouble_serialize(self)); + const MEDCouplingMesh *mesh(self->getMesh()); + if(mesh) + mesh->incrRef(); + PyObject *ret(PyTuple_New(3)); + PyTuple_SetItem(ret,0,ret0); + PyTuple_SetItem(ret,1,ret1); + PyTuple_SetItem(ret,2,convertMesh(const_cast<MEDCouplingMesh *>(mesh),SWIG_POINTER_OWN | 0 )); + return ret; + } + + void __setstate__(PyObject *inp) throw(INTERP_KERNEL::Exception) + { + static const char MSG[]="MEDCouplingFieldDouble.__setstate__ : expected input is a tuple of size 3 !"; + if(!PyTuple_Check(inp)) + throw INTERP_KERNEL::Exception(MSG); + int sz(PyTuple_Size(inp)); + if(sz!=3) + throw INTERP_KERNEL::Exception(MSG); + // mesh + PyObject *elt2(PyTuple_GetItem(inp,2)); + void *argp=0; + int status(SWIG_ConvertPtr(elt2,&argp,SWIGTYPE_p_ParaMEDMEM__MEDCouplingMesh,0|0)); + if(!SWIG_IsOK(status)) + throw INTERP_KERNEL::Exception(MSG); + self->setMesh(reinterpret_cast< const MEDCouplingUMesh * >(argp)); + // + PyObject *elt0(PyTuple_GetItem(inp,0)); + PyObject *elt1(PyTuple_GetItem(inp,1)); + std::vector<double> a0; + std::vector<int> a1; + std::vector<std::string> a2; + DataArrayInt *b0(0); + std::vector<DataArrayDouble *>b1; + { + if(!PyTuple_Check(elt0) && PyTuple_Size(elt0)!=3) + throw INTERP_KERNEL::Exception(MSG); + PyObject *a0py(PyTuple_GetItem(elt0,0)),*a1py(PyTuple_GetItem(elt0,1)),*a2py(PyTuple_GetItem(elt0,2)); + int tmp(-1); + fillArrayWithPyListDbl3(a0py,tmp,a0); + convertPyToNewIntArr3(a1py,a1); + fillStringVector(a2py,a2); + } + { + if(!PyTuple_Check(elt1) && PyTuple_Size(elt1)!=2) + throw INTERP_KERNEL::Exception(MSG); + PyObject *b0py(PyTuple_GetItem(elt1,0)),*b1py(PyTuple_GetItem(elt1,1)); + void *argp(0); + int status(SWIG_ConvertPtr(b0py,&argp,SWIGTYPE_p_ParaMEDMEM__DataArrayInt,0|0)); + if(!SWIG_IsOK(status)) + throw INTERP_KERNEL::Exception(MSG); + b0=reinterpret_cast<DataArrayInt *>(argp); + convertFromPyObjVectorOfObj<ParaMEDMEM::DataArrayDouble *>(b1py,SWIGTYPE_p_ParaMEDMEM__DataArrayDouble,"DataArrayDouble",b1); + } + self->checkForUnserialization(a1,b0,b1); + // useless here to call resizeForUnserialization because arrays are well resized. + self->finishUnserialization(a1,a0,a2); + } + } + }; + + class MEDCouplingMultiFields : public RefCountObject, public TimeLabel + { + public: + int getNumberOfFields() const; + MEDCouplingMultiFields *deepCpy() const; + virtual std::string simpleRepr() const throw(INTERP_KERNEL::Exception); + virtual std::string advancedRepr() const throw(INTERP_KERNEL::Exception); + virtual bool isEqual(const MEDCouplingMultiFields *other, double meshPrec, double valsPrec) const; + virtual bool isEqualWithoutConsideringStr(const MEDCouplingMultiFields *other, double meshPrec, double valsPrec) const; + virtual void checkCoherency() const throw(INTERP_KERNEL::Exception); + %extend + { + std::string __str__() const throw(INTERP_KERNEL::Exception) + { + return self->simpleRepr(); + } + static MEDCouplingMultiFields *New(PyObject *li) throw(INTERP_KERNEL::Exception) + { + std::vector<const ParaMEDMEM::MEDCouplingFieldDouble *> tmp; + convertFromPyObjVectorOfObj<const ParaMEDMEM::MEDCouplingFieldDouble *>(li,SWIGTYPE_p_ParaMEDMEM__MEDCouplingFieldDouble,"MEDCouplingFieldDouble",tmp); + int sz=tmp.size(); + std::vector<MEDCouplingFieldDouble *> fs(sz); + for(int i=0;i<sz;i++) + fs[i]=const_cast<MEDCouplingFieldDouble *>(tmp[i]); + return MEDCouplingMultiFields::New(fs); + } + MEDCouplingMultiFields(PyObject *li) throw(INTERP_KERNEL::Exception) + { + std::vector<const ParaMEDMEM::MEDCouplingFieldDouble *> tmp; + convertFromPyObjVectorOfObj<const ParaMEDMEM::MEDCouplingFieldDouble *>(li,SWIGTYPE_p_ParaMEDMEM__MEDCouplingFieldDouble,"MEDCouplingFieldDouble",tmp); + int sz=tmp.size(); + std::vector<MEDCouplingFieldDouble *> fs(sz); + for(int i=0;i<sz;i++) + fs[i]=const_cast<MEDCouplingFieldDouble *>(tmp[i]); + return MEDCouplingMultiFields::New(fs); + } + PyObject *getFields() const + { + std::vector<const MEDCouplingFieldDouble *> fields=self->getFields(); + int sz=fields.size(); + PyObject *res = PyList_New(sz); + for(int i=0;i<sz;i++) + { + if(fields[i]) + { + fields[i]->incrRef(); + PyList_SetItem(res,i,SWIG_NewPointerObj(SWIG_as_voidptr(fields[i]),SWIGTYPE_p_ParaMEDMEM__MEDCouplingFieldDouble, SWIG_POINTER_OWN | 0 )); + } + else + { + PyList_SetItem(res,i,SWIG_NewPointerObj(SWIG_as_voidptr(0),SWIGTYPE_p_ParaMEDMEM__MEDCouplingFieldDouble, 0 )); + } + } + return res; + } + PyObject *getFieldAtPos(int id) const throw(INTERP_KERNEL::Exception) + { + const MEDCouplingFieldDouble *ret=self->getFieldAtPos(id); + if(ret) + { + ret->incrRef(); + return SWIG_NewPointerObj(SWIG_as_voidptr(ret),SWIGTYPE_p_ParaMEDMEM__MEDCouplingFieldDouble, SWIG_POINTER_OWN | 0 ); + } + else + return SWIG_NewPointerObj(SWIG_as_voidptr(0),SWIGTYPE_p_ParaMEDMEM__MEDCouplingFieldDouble, 0 ); + } + PyObject *getMeshes() const throw(INTERP_KERNEL::Exception) + { + std::vector<MEDCouplingMesh *> ms=self->getMeshes(); + int sz=ms.size(); + PyObject *res = PyList_New(sz); + for(int i=0;i<sz;i++) + { + if(ms[i]) + { + ms[i]->incrRef(); + PyList_SetItem(res,i,convertMesh(ms[i], SWIG_POINTER_OWN | 0 )); + } + else + { + PyList_SetItem(res,i,SWIG_NewPointerObj(SWIG_as_voidptr(0),SWIGTYPE_p_ParaMEDMEM__MEDCouplingUMesh, 0 )); + } + } + return res; + } + PyObject *getDifferentMeshes() const throw(INTERP_KERNEL::Exception) + { + std::vector<int> refs; + std::vector<MEDCouplingMesh *> ms=self->getDifferentMeshes(refs); + int sz=ms.size(); + PyObject *res = PyList_New(sz); + for(int i=0;i<sz;i++) + { + if(ms[i]) + { + ms[i]->incrRef(); + PyList_SetItem(res,i,convertMesh(ms[i], SWIG_POINTER_OWN | 0 )); + } + else + { + PyList_SetItem(res,i,SWIG_NewPointerObj(SWIG_as_voidptr(0),SWIGTYPE_p_ParaMEDMEM__MEDCouplingUMesh, 0 )); + } + } + // + PyObject *ret=PyTuple_New(2); + PyTuple_SetItem(ret,0,res); + PyTuple_SetItem(ret,1,convertIntArrToPyList2(refs)); + return ret; + } + PyObject *getArrays() const throw(INTERP_KERNEL::Exception) + { + std::vector<DataArrayDouble *> ms=self->getArrays(); + int sz=ms.size(); + PyObject *res = PyList_New(sz); + for(int i=0;i<sz;i++) + { + if(ms[i]) + { + ms[i]->incrRef(); + PyList_SetItem(res,i,SWIG_NewPointerObj(SWIG_as_voidptr(ms[i]),SWIGTYPE_p_ParaMEDMEM__DataArrayDouble, SWIG_POINTER_OWN | 0 )); + } + else + { + PyList_SetItem(res,i,SWIG_NewPointerObj(SWIG_as_voidptr(0),SWIGTYPE_p_ParaMEDMEM__DataArrayDouble, 0 )); + } + } + return res; + } + PyObject *getDifferentArrays() const throw(INTERP_KERNEL::Exception) + { + std::vector< std::vector<int> > refs; + std::vector<DataArrayDouble *> ms=self->getDifferentArrays(refs); + int sz=ms.size(); + PyObject *res = PyList_New(sz); + PyObject *res2 = PyList_New(sz); + for(int i=0;i<sz;i++) + { + if(ms[i]) + { + ms[i]->incrRef(); + PyList_SetItem(res,i,SWIG_NewPointerObj(SWIG_as_voidptr(ms[i]),SWIGTYPE_p_ParaMEDMEM__DataArrayDouble, SWIG_POINTER_OWN | 0 )); + } + else + { + PyList_SetItem(res,i,SWIG_NewPointerObj(SWIG_as_voidptr(0),SWIGTYPE_p_ParaMEDMEM__DataArrayDouble, 0 )); + } + PyList_SetItem(res2,i,convertIntArrToPyList2(refs[i])); + } + // + PyObject *ret=PyTuple_New(2); + PyTuple_SetItem(ret,0,res); + PyTuple_SetItem(ret,1,res2); + return ret; + } + } + }; + + class MEDCouplingDefinitionTime + { + public: + MEDCouplingDefinitionTime(); + void assign(const MEDCouplingDefinitionTime& other); + bool isEqual(const MEDCouplingDefinitionTime& other) const; + double getTimeResolution() const; + std::vector<double> getHotSpotsTime() const; + %extend + { + std::string __str__() const throw(INTERP_KERNEL::Exception) + { + std::ostringstream oss; + self->appendRepr(oss); + return oss.str(); + } + + PyObject *getIdsOnTimeRight(double tm) const throw(INTERP_KERNEL::Exception) + { + int meshId,arrId,arrIdInField,fieldId; + self->getIdsOnTimeRight(tm,meshId,arrId,arrIdInField,fieldId); + PyObject *res=PyList_New(4); + PyList_SetItem(res,0,PyInt_FromLong(meshId)); + PyList_SetItem(res,1,PyInt_FromLong(arrId)); + PyList_SetItem(res,2,PyInt_FromLong(arrIdInField)); + PyList_SetItem(res,3,PyInt_FromLong(fieldId)); + return res; + } + + PyObject *getIdsOnTimeLeft(double tm) const throw(INTERP_KERNEL::Exception) + { + int meshId,arrId,arrIdInField,fieldId; + self->getIdsOnTimeLeft(tm,meshId,arrId,arrIdInField,fieldId); + PyObject *res=PyList_New(4); + PyList_SetItem(res,0,PyInt_FromLong(meshId)); + PyList_SetItem(res,1,PyInt_FromLong(arrId)); + PyList_SetItem(res,2,PyInt_FromLong(arrIdInField)); + PyList_SetItem(res,3,PyInt_FromLong(fieldId)); + return res; + } + } + }; + + class MEDCouplingFieldOverTime : public MEDCouplingMultiFields + { + public: + double getTimeTolerance() const throw(INTERP_KERNEL::Exception); + MEDCouplingDefinitionTime getDefinitionTimeZone() const; + + %extend + { + MEDCouplingFieldOverTime(PyObject *li) throw(INTERP_KERNEL::Exception) + { + std::vector<const ParaMEDMEM::MEDCouplingFieldDouble *> tmp; + convertFromPyObjVectorOfObj<const ParaMEDMEM::MEDCouplingFieldDouble *>(li,SWIGTYPE_p_ParaMEDMEM__MEDCouplingFieldDouble,"MEDCouplingFieldDouble",tmp); + int sz=tmp.size(); + std::vector<MEDCouplingFieldDouble *> fs(sz); + for(int i=0;i<sz;i++) + fs[i]=const_cast<MEDCouplingFieldDouble *>(tmp[i]); + return MEDCouplingFieldOverTime::New(fs); + } + std::string __str__() const throw(INTERP_KERNEL::Exception) + { + return self->simpleRepr(); + } + static MEDCouplingFieldOverTime *New(PyObject *li) throw(INTERP_KERNEL::Exception) + { + std::vector<const ParaMEDMEM::MEDCouplingFieldDouble *> tmp; + convertFromPyObjVectorOfObj<const ParaMEDMEM::MEDCouplingFieldDouble *>(li,SWIGTYPE_p_ParaMEDMEM__MEDCouplingFieldDouble,"MEDCouplingFieldDouble",tmp); + int sz=tmp.size(); + std::vector<MEDCouplingFieldDouble *> fs(sz); + for(int i=0;i<sz;i++) + fs[i]=const_cast<MEDCouplingFieldDouble *>(tmp[i]); + return MEDCouplingFieldOverTime::New(fs); + } + } + }; + + class MEDCouplingCartesianAMRMesh; + + class MEDCouplingCartesianAMRPatchGen : public RefCountObject + { + public: + int getNumberOfCellsRecursiveWithOverlap() const throw(INTERP_KERNEL::Exception); + int getNumberOfCellsRecursiveWithoutOverlap() const throw(INTERP_KERNEL::Exception); + int getMaxNumberOfLevelsRelativeToThis() const throw(INTERP_KERNEL::Exception); + %extend + { + MEDCouplingCartesianAMRMeshGen *getMesh() const throw(INTERP_KERNEL::Exception) + { + MEDCouplingCartesianAMRMeshGen *ret(const_cast<MEDCouplingCartesianAMRMeshGen *>(self->getMesh())); + if(ret) + ret->incrRef(); + return ret; + } + } + }; + + class MEDCouplingCartesianAMRPatch : public MEDCouplingCartesianAMRPatchGen + { + public: + int getNumberOfOverlapedCellsForFather() const throw(INTERP_KERNEL::Exception); + bool isInMyNeighborhood(const MEDCouplingCartesianAMRPatch *other, int ghostLev) const throw(INTERP_KERNEL::Exception); + std::vector<int> computeCellGridSt() const throw(INTERP_KERNEL::Exception); + %extend + { + PyObject *getBLTRRange() const throw(INTERP_KERNEL::Exception) + { + const std::vector< std::pair<int,int> >& ret(self->getBLTRRange()); + return convertFromVectorPairInt(ret); + } + + PyObject *getBLTRRangeRelativeToGF() const throw(INTERP_KERNEL::Exception) + { + std::vector< std::pair<int,int> > ret(self->getBLTRRangeRelativeToGF()); + return convertFromVectorPairInt(ret); + } + + void addPatch(PyObject *bottomLeftTopRight, const std::vector<int>& factors) throw(INTERP_KERNEL::Exception) + { + std::vector< std::pair<int,int> > inp; + convertPyToVectorPairInt(bottomLeftTopRight,inp); + self->addPatch(inp,factors); + } + + MEDCouplingCartesianAMRPatch *__getitem__(int patchId) const throw(INTERP_KERNEL::Exception) + { + const MEDCouplingCartesianAMRMeshGen *mesh(self->getMesh()); + if(!mesh) + throw INTERP_KERNEL::Exception("wrap MEDCouplingCartesianAMRPatchGen.__getitem__ : no underlying mesh !"); + if(patchId==mesh->getNumberOfPatches()) + { + std::ostringstream oss; + oss << "Requesting for patchId " << patchId << " having only " << mesh->getNumberOfPatches() << " patches !"; + PyErr_SetString(PyExc_StopIteration,oss.str().c_str()); + return 0; + } + MEDCouplingCartesianAMRPatch *ret(const_cast<MEDCouplingCartesianAMRPatch *>(mesh->getPatch(patchId))); + if(ret) + ret->incrRef(); + return ret; + } + + void __delitem__(int patchId) throw(INTERP_KERNEL::Exception) + { + MEDCouplingCartesianAMRMeshGen *mesh(const_cast<MEDCouplingCartesianAMRMeshGen *>(self->getMesh())); + if(!mesh) + throw INTERP_KERNEL::Exception("wrap MEDCouplingCartesianAMRPatch.__delitem__ : no underlying mesh !"); + mesh->removePatch(patchId); + } + + int __len__() const throw(INTERP_KERNEL::Exception) + { + const MEDCouplingCartesianAMRMeshGen *mesh(self->getMesh()); + if(!mesh) + throw INTERP_KERNEL::Exception("wrap MEDCouplingCartesianAMRPatch.__len__ : no underlying mesh !"); + return mesh->getNumberOfPatches(); + } + } + }; + + class MEDCouplingCartesianAMRPatchGF : public MEDCouplingCartesianAMRPatchGen + { + }; + + class MEDCouplingCartesianAMRMeshGen : public RefCountObject, public TimeLabel + { + public: + int getAbsoluteLevel() const throw(INTERP_KERNEL::Exception); + int getAbsoluteLevelRelativeTo(const MEDCouplingCartesianAMRMeshGen *ref) const throw(INTERP_KERNEL::Exception); + std::vector<int> getPositionRelativeTo(const MEDCouplingCartesianAMRMeshGen *ref) const throw(INTERP_KERNEL::Exception); + int getSpaceDimension() const throw(INTERP_KERNEL::Exception); + const std::vector<int>& getFactors() const throw(INTERP_KERNEL::Exception); + void setFactors(const std::vector<int>& newFactors) throw(INTERP_KERNEL::Exception); + int getMaxNumberOfLevelsRelativeToThis() const throw(INTERP_KERNEL::Exception); + int getNumberOfCellsAtCurrentLevel() const throw(INTERP_KERNEL::Exception); + int getNumberOfCellsAtCurrentLevelGhost(int ghostLev) const throw(INTERP_KERNEL::Exception); + int getNumberOfCellsRecursiveWithOverlap() const throw(INTERP_KERNEL::Exception); + int getNumberOfCellsRecursiveWithoutOverlap() const throw(INTERP_KERNEL::Exception); + bool isPatchInNeighborhoodOf(int patchId1, int patchId2, int ghostLev) const throw(INTERP_KERNEL::Exception); + virtual void detachFromFather() throw(INTERP_KERNEL::Exception); + // + int getNumberOfPatches() const throw(INTERP_KERNEL::Exception); + int getPatchIdFromChildMesh(const MEDCouplingCartesianAMRMeshGen *mesh) const throw(INTERP_KERNEL::Exception); + MEDCouplingUMesh *buildUnstructured() const throw(INTERP_KERNEL::Exception); + DataArrayDouble *extractGhostFrom(int ghostSz, const DataArrayDouble *arr) const throw(INTERP_KERNEL::Exception); + std::vector<int> getPatchIdsInTheNeighborhoodOf(int patchId, int ghostLev) const throw(INTERP_KERNEL::Exception); + MEDCoupling1SGTUMesh *buildMeshFromPatchEnvelop() const throw(INTERP_KERNEL::Exception); + MEDCoupling1SGTUMesh *buildMeshOfDirectChildrenOnly() const throw(INTERP_KERNEL::Exception); + void removeAllPatches() throw(INTERP_KERNEL::Exception); + void removePatch(int patchId) throw(INTERP_KERNEL::Exception); + void createPatchesFromCriterion(const INTERP_KERNEL::BoxSplittingOptions& bso, const DataArrayByte *criterion, const std::vector<int>& factors) throw(INTERP_KERNEL::Exception); + void createPatchesFromCriterion(const INTERP_KERNEL::BoxSplittingOptions& bso, const DataArrayDouble *criterion, const std::vector<int>& factors, double eps) throw(INTERP_KERNEL::Exception); + DataArrayDouble *createCellFieldOnPatch(int patchId, const DataArrayDouble *cellFieldOnThis) const throw(INTERP_KERNEL::Exception); + void fillCellFieldOnPatch(int patchId, const DataArrayDouble *cellFieldOnThis, DataArrayDouble *cellFieldOnPatch, bool isConservative=true) const throw(INTERP_KERNEL::Exception); + void fillCellFieldOnPatchGhost(int patchId, const DataArrayDouble *cellFieldOnThis, DataArrayDouble *cellFieldOnPatch, int ghostLev, bool isConservative=true) const throw(INTERP_KERNEL::Exception); + void fillCellFieldOnPatchOnlyOnGhostZone(int patchId, const DataArrayDouble *cellFieldOnThis, DataArrayDouble *cellFieldOnPatch, int ghostLev) const throw(INTERP_KERNEL::Exception); + void fillCellFieldOnPatchOnlyOnGhostZoneWith(int ghostLev, const MEDCouplingCartesianAMRPatch *patchToBeModified, const MEDCouplingCartesianAMRPatch *neighborPatch, DataArrayDouble *cellFieldOnPatch, const DataArrayDouble *cellFieldNeighbor) const; + void fillCellFieldComingFromPatch(int patchId, const DataArrayDouble *cellFieldOnPatch, DataArrayDouble *cellFieldOnThis, bool isConservative=true) const throw(INTERP_KERNEL::Exception); + void fillCellFieldComingFromPatchGhost(int patchId, const DataArrayDouble *cellFieldOnPatch, DataArrayDouble *cellFieldOnThis, int ghostLev, bool isConservative=true) const throw(INTERP_KERNEL::Exception); + DataArrayInt *findPatchesInTheNeighborhoodOf(int patchId, int ghostLev) const throw(INTERP_KERNEL::Exception); + std::string buildPythonDumpOfThis() const throw(INTERP_KERNEL::Exception); + %extend + { + void addPatch(PyObject *bottomLeftTopRight, const std::vector<int>& factors) throw(INTERP_KERNEL::Exception) + { + std::vector< std::pair<int,int> > inp; + convertPyToVectorPairInt(bottomLeftTopRight,inp); + self->addPatch(inp,factors); + } + + PyObject *getPatches() const throw(INTERP_KERNEL::Exception) + { + std::vector< const MEDCouplingCartesianAMRPatch *> ps(self->getPatches()); + int sz(ps.size()); + PyObject *ret = PyList_New(sz); + for(int i=0;i<sz;i++) + { + MEDCouplingCartesianAMRPatch *elt(const_cast<MEDCouplingCartesianAMRPatch *>(ps[i])); + if(elt) + elt->incrRef(); + PyList_SetItem(ret,i,convertCartesianAMRPatch(elt, SWIG_POINTER_OWN | 0 )); + } + return ret; + } + + // agy : don't know why typemap fails here ??? let it in the extend section + PyObject *deepCpy(MEDCouplingCartesianAMRMeshGen *father) const throw(INTERP_KERNEL::Exception) + { + return convertCartesianAMRMesh(self->deepCpy(father), SWIG_POINTER_OWN | 0 ); + } + + MEDCouplingCartesianAMRPatch *getPatchAtPosition(const std::vector<int>& pos) const throw(INTERP_KERNEL::Exception) + { + const MEDCouplingCartesianAMRPatch *ret(self->getPatchAtPosition(pos)); + MEDCouplingCartesianAMRPatch *ret2(const_cast<MEDCouplingCartesianAMRPatch *>(ret)); + if(ret2) + ret2->incrRef(); + return ret2; + } + + MEDCouplingCartesianAMRMeshGen *getMeshAtPosition(const std::vector<int>& pos) const throw(INTERP_KERNEL::Exception) + { + const MEDCouplingCartesianAMRMeshGen *ret(self->getMeshAtPosition(pos)); + MEDCouplingCartesianAMRMeshGen *ret2(const_cast<MEDCouplingCartesianAMRMeshGen *>(ret)); + if(ret2) + ret2->incrRef(); + return ret2; + } + + virtual PyObject *positionRelativeToGodFather() const throw(INTERP_KERNEL::Exception) + { + std::vector<int> out1; + std::vector< std::pair<int,int> > out0(self->positionRelativeToGodFather(out1)); + PyObject *ret(PyTuple_New(2)); + PyTuple_SetItem(ret,0,convertFromVectorPairInt(out0)); + PyTuple_SetItem(ret,1,convertIntArrToPyList2(out1)); + return ret; + } + + virtual PyObject *retrieveGridsAt(int absoluteLev) const throw(INTERP_KERNEL::Exception) + { + std::vector<MEDCouplingCartesianAMRPatchGen *> ps(self->retrieveGridsAt(absoluteLev)); + int sz(ps.size()); + PyObject *ret = PyList_New(sz); + for(int i=0;i<sz;i++) + PyList_SetItem(ret,i,convertCartesianAMRPatch(ps[i], SWIG_POINTER_OWN | 0 )); + return ret; + } + + MEDCouplingFieldDouble *buildCellFieldOnRecurseWithoutOverlapWithoutGhost(int ghostSz, PyObject *recurseArrs) const + { + std::vector<const DataArrayDouble *> inp; + convertFromPyObjVectorOfObj<const ParaMEDMEM::DataArrayDouble *>(recurseArrs,SWIGTYPE_p_ParaMEDMEM__DataArrayDouble,"DataArrayDouble",inp); + return self->buildCellFieldOnRecurseWithoutOverlapWithoutGhost(ghostSz,inp); + } + + virtual MEDCouplingCartesianAMRMeshGen *getFather() const throw(INTERP_KERNEL::Exception) + { + MEDCouplingCartesianAMRMeshGen *ret(const_cast<MEDCouplingCartesianAMRMeshGen *>(self->getFather())); + if(ret) + ret->incrRef(); + return ret; + } + + virtual MEDCouplingCartesianAMRMeshGen *getGodFather() const throw(INTERP_KERNEL::Exception) + { + MEDCouplingCartesianAMRMeshGen *ret(const_cast<MEDCouplingCartesianAMRMeshGen *>(self->getGodFather())); + if(ret) + ret->incrRef(); + return ret; + } + + MEDCouplingCartesianAMRPatch *getPatch(int patchId) const throw(INTERP_KERNEL::Exception) + { + MEDCouplingCartesianAMRPatch *ret(const_cast<MEDCouplingCartesianAMRPatch *>(self->getPatch(patchId))); + if(ret) + ret->incrRef(); + return ret; + } + + MEDCouplingIMesh *getImageMesh() const throw(INTERP_KERNEL::Exception) + { + const MEDCouplingIMesh *ret(self->getImageMesh()); + if(ret) + ret->incrRef(); + return const_cast<MEDCouplingIMesh *>(ret); + } + + MEDCouplingCartesianAMRPatch *__getitem__(int patchId) const throw(INTERP_KERNEL::Exception) + { + if(patchId==self->getNumberOfPatches()) + { + std::ostringstream oss; + oss << "Requesting for patchId " << patchId << " having only " << self->getNumberOfPatches() << " patches !"; + PyErr_SetString(PyExc_StopIteration,oss.str().c_str()); + return 0; + } + MEDCouplingCartesianAMRPatch *ret(const_cast<MEDCouplingCartesianAMRPatch *>(self->getPatch(patchId))); + if(ret) + ret->incrRef(); + return ret; + } + + void fillCellFieldOnPatchGhostAdv(int patchId, const DataArrayDouble *cellFieldOnThis, int ghostLev, PyObject *arrsOnPatches, bool isConservative=true) const throw(INTERP_KERNEL::Exception) + { + std::vector<const ParaMEDMEM::DataArrayDouble *> arrsOnPatches2; + convertFromPyObjVectorOfObj<const ParaMEDMEM::DataArrayDouble *>(arrsOnPatches,SWIGTYPE_p_ParaMEDMEM__DataArrayDouble,"DataArrayDouble",arrsOnPatches2); + self->fillCellFieldOnPatchGhostAdv(patchId,cellFieldOnThis,ghostLev,arrsOnPatches2,isConservative); + } + + void fillCellFieldOnPatchOnlyGhostAdv(int patchId, int ghostLev, PyObject *arrsOnPatches) const + { + std::vector<const ParaMEDMEM::DataArrayDouble *> arrsOnPatches2; + convertFromPyObjVectorOfObj<const ParaMEDMEM::DataArrayDouble *>(arrsOnPatches,SWIGTYPE_p_ParaMEDMEM__DataArrayDouble,"DataArrayDouble",arrsOnPatches2); + self->fillCellFieldOnPatchOnlyGhostAdv(patchId,ghostLev,arrsOnPatches2); + } + + void __delitem__(int patchId) throw(INTERP_KERNEL::Exception) + { + self->removePatch(patchId); + } + + int __len__() const throw(INTERP_KERNEL::Exception) + { + return self->getNumberOfPatches(); + } + } + }; + + class MEDCouplingCartesianAMRMeshSub : public MEDCouplingCartesianAMRMeshGen + { + }; + + class MEDCouplingCartesianAMRMesh : public MEDCouplingCartesianAMRMeshGen + { + public: + static MEDCouplingCartesianAMRMesh *New(MEDCouplingIMesh *mesh) throw(INTERP_KERNEL::Exception); + %extend + { + static MEDCouplingCartesianAMRMesh *New(const std::string& meshName, int spaceDim, PyObject *nodeStrct, PyObject *origin, PyObject *dxyz) throw(INTERP_KERNEL::Exception) + { + static const char msg0[]="MEDCouplingCartesianAMRMesh::New : error on 'origin' parameter !"; + static const char msg1[]="MEDCouplingCartesianAMRMesh::New : error on 'dxyz' parameter !"; + const int *nodeStrctPtr(0); + const double *originPtr(0),*dxyzPtr(0); + int sw,sz,val0; + std::vector<int> bb0; + nodeStrctPtr=convertObjToPossibleCpp1_Safe(nodeStrct,sw,sz,val0,bb0); + // + double val,val2; + std::vector<double> bb,bb2; + int sz1,sz2; + originPtr=convertObjToPossibleCpp5_SingleCompo(origin,sw,val,bb,msg0,false,sz1); + dxyzPtr=convertObjToPossibleCpp5_SingleCompo(dxyz,sw,val2,bb2,msg1,false,sz2); + // + return MEDCouplingCartesianAMRMesh::New(meshName,spaceDim,nodeStrctPtr,nodeStrctPtr+sz,originPtr,originPtr+sz1,dxyzPtr,dxyzPtr+sz2); + } + + void createPatchesFromCriterionML(PyObject *bso, const DataArrayDouble *criterion, PyObject *factors, double eps) throw(INTERP_KERNEL::Exception) + { + std::vector<const INTERP_KERNEL::BoxSplittingOptions *> inp0; + convertFromPyObjVectorOfObj<const INTERP_KERNEL::BoxSplittingOptions *>(bso,SWIGTYPE_p_INTERP_KERNEL__BoxSplittingOptions,"BoxSplittingOptions",inp0); + std::vector< std::vector<int> > inp2; + convertPyToVectorOfVectorOfInt(factors,inp2); + self->createPatchesFromCriterionML(inp0,criterion,inp2,eps); + } + + MEDCouplingCartesianAMRMesh(const std::string& meshName, int spaceDim, PyObject *nodeStrct, PyObject *origin, PyObject *dxyz) throw(INTERP_KERNEL::Exception) + { + return ParaMEDMEM_MEDCouplingCartesianAMRMesh_New__SWIG_1(meshName,spaceDim,nodeStrct,origin,dxyz); + } + + MEDCouplingCartesianAMRMesh(MEDCouplingIMesh *mesh) throw(INTERP_KERNEL::Exception) + { + return MEDCouplingCartesianAMRMesh::New(mesh); + } + } + }; + + class MEDCouplingDataForGodFather : public RefCountObject + { + public: + virtual void synchronizeFineToCoarse() throw(INTERP_KERNEL::Exception); + virtual void synchronizeFineToCoarseBetween(int fromLev, int toLev) throw(INTERP_KERNEL::Exception); + virtual void synchronizeCoarseToFine() throw(INTERP_KERNEL::Exception); + virtual void synchronizeCoarseToFineBetween(int fromLev, int toLev) throw(INTERP_KERNEL::Exception); + virtual void synchronizeAllGhostZones() throw(INTERP_KERNEL::Exception); + virtual void synchronizeAllGhostZonesOfDirectChidrenOf(const MEDCouplingCartesianAMRMeshGen *mesh) throw(INTERP_KERNEL::Exception); + virtual void synchronizeAllGhostZonesAtASpecifiedLevel(int level) throw(INTERP_KERNEL::Exception); + virtual void synchronizeAllGhostZonesAtASpecifiedLevelUsingOnlyFather(int level) throw(INTERP_KERNEL::Exception); + virtual void alloc() throw(INTERP_KERNEL::Exception); + virtual void dealloc() throw(INTERP_KERNEL::Exception); + %extend + { + MEDCouplingCartesianAMRMesh *getMyGodFather() throw(INTERP_KERNEL::Exception) + { + MEDCouplingCartesianAMRMesh *ret(self->getMyGodFather()); + if(ret) + ret->incrRef(); + return ret; + } + } + }; + + class MEDCouplingAMRAttribute : public MEDCouplingDataForGodFather, public TimeLabel + { + public: + int getNumberOfLevels() const throw(INTERP_KERNEL::Exception); + MEDCouplingAMRAttribute *deepCpy() const throw(INTERP_KERNEL::Exception); + MEDCouplingAMRAttribute *deepCpyWithoutGodFather() const throw(INTERP_KERNEL::Exception); + MEDCouplingFieldDouble *buildCellFieldOnRecurseWithoutOverlapWithoutGhost(MEDCouplingCartesianAMRMeshGen *mesh, const std::string& fieldName) const throw(INTERP_KERNEL::Exception); + MEDCouplingFieldDouble *buildCellFieldOnWithGhost(MEDCouplingCartesianAMRMeshGen *mesh, const std::string& fieldName) const throw(INTERP_KERNEL::Exception); + MEDCouplingFieldDouble *buildCellFieldOnWithoutGhost(MEDCouplingCartesianAMRMeshGen *mesh, const std::string& fieldName) const throw(INTERP_KERNEL::Exception); + bool changeGodFather(MEDCouplingCartesianAMRMesh *gf) throw(INTERP_KERNEL::Exception); + MEDCouplingAMRAttribute *projectTo(MEDCouplingCartesianAMRMesh *targetGF) const throw(INTERP_KERNEL::Exception); + std::string writeVTHB(const std::string& fileName) const throw(INTERP_KERNEL::Exception); + %extend + { + static MEDCouplingAMRAttribute *New(MEDCouplingCartesianAMRMesh *gf, PyObject *fieldNames, int ghostLev) throw(INTERP_KERNEL::Exception) + { + std::vector< std::pair<std::string,int> > fieldNamesCpp0; + std::vector< std::pair<std::string, std::vector<std::string> > > fieldNamesCpp1; + MEDCouplingAMRAttribute *ret(0); + try + { + convertPyToVectorPairStringInt(fieldNames,fieldNamesCpp0); + ret=MEDCouplingAMRAttribute::New(gf,fieldNamesCpp0,ghostLev); + } + catch(INTERP_KERNEL::Exception&) + { + convertPyToVectorPairStringVecString(fieldNames,fieldNamesCpp1); + ret=MEDCouplingAMRAttribute::New(gf,fieldNamesCpp1,ghostLev); + } + return ret; + } + + MEDCouplingAMRAttribute(MEDCouplingCartesianAMRMesh *gf, PyObject *fieldNames, int ghostLev) throw(INTERP_KERNEL::Exception) + { + return ParaMEDMEM_MEDCouplingAMRAttribute_New(gf,fieldNames,ghostLev); + } + + DataArrayDouble *getFieldOn(MEDCouplingCartesianAMRMeshGen *mesh, const std::string& fieldName) const throw(INTERP_KERNEL::Exception) + { + const DataArrayDouble *ret(self->getFieldOn(mesh,fieldName)); + DataArrayDouble *ret2(const_cast<DataArrayDouble *>(ret)); + if(ret2) + ret2->incrRef(); + return ret2; + } + + void spillInfoOnComponents(PyObject *compNames) throw(INTERP_KERNEL::Exception) + { + std::vector< std::vector<std::string> > compNamesCpp; + convertPyToVectorOfVectorOfString(compNames,compNamesCpp); + self->spillInfoOnComponents(compNamesCpp); + } + + void spillNatures(PyObject *nfs) throw(INTERP_KERNEL::Exception) + { + std::vector<int> inp0; + if(!fillIntVector(nfs,inp0)) + throw INTERP_KERNEL::Exception("wrap of MEDCouplingAMRAttribute::spillNatures : vector of NatureOfField enum expected !"); + std::size_t sz(inp0.size()); + std::vector<NatureOfField> inp00(sz); + for(std::size_t i=0;i<sz;i++) + inp00[i]=(NatureOfField)inp0[i]; + self->spillNatures(inp00); + } + + PyObject *retrieveFieldsOn(MEDCouplingCartesianAMRMeshGen *mesh) const throw(INTERP_KERNEL::Exception) + { + std::vector<DataArrayDouble *> ret(self->retrieveFieldsOn(mesh)); + int sz((int)ret.size()); + PyObject *retPy(PyList_New(sz)); + for(int i=0;i<sz;i++) + PyList_SetItem(retPy,i,SWIG_NewPointerObj(SWIG_as_voidptr(ret[i]),SWIGTYPE_p_ParaMEDMEM__DataArrayDouble, SWIG_POINTER_OWN | 0 )); + return retPy; + } + } + }; + + class DenseMatrix : public RefCountObject, public TimeLabel + { + public: + static DenseMatrix *New(int nbRows, int nbCols) throw(INTERP_KERNEL::Exception); + static DenseMatrix *New(DataArrayDouble *array, int nbRows, int nbCols) throw(INTERP_KERNEL::Exception); + DenseMatrix *deepCpy() const throw(INTERP_KERNEL::Exception); + DenseMatrix *shallowCpy() const throw(INTERP_KERNEL::Exception); + // + int getNumberOfRows() const throw(INTERP_KERNEL::Exception); + int getNumberOfCols() const throw(INTERP_KERNEL::Exception); + int getNbOfElems() const throw(INTERP_KERNEL::Exception); + void reBuild(DataArrayDouble *array, int nbRows=-1, int nbCols=-1) throw(INTERP_KERNEL::Exception); + void reShape(int nbRows, int nbCols) throw(INTERP_KERNEL::Exception); + void transpose() throw(INTERP_KERNEL::Exception); + // + bool isEqual(const DenseMatrix& other, double eps) const throw(INTERP_KERNEL::Exception); + DataArrayDouble *matVecMult(const DataArrayDouble *vec) const throw(INTERP_KERNEL::Exception); + static DataArrayDouble *MatVecMult(const DenseMatrix *mat, const DataArrayDouble *vec) throw(INTERP_KERNEL::Exception); + %extend + { + DenseMatrix(int nbRows, int nbCols) throw(INTERP_KERNEL::Exception) + { + return DenseMatrix::New(nbRows,nbCols); + } + + DenseMatrix(DataArrayDouble *array, int nbRows, int nbCols) throw(INTERP_KERNEL::Exception) + { + return DenseMatrix::New(array,nbRows,nbCols); + } + + PyObject *isEqualIfNotWhy(const DenseMatrix& other, double eps) const throw(INTERP_KERNEL::Exception) + { + std::string ret1; + bool ret0=self->isEqualIfNotWhy(other,eps,ret1); + PyObject *ret=PyTuple_New(2); + PyObject *ret0Py=ret0?Py_True:Py_False; + Py_XINCREF(ret0Py); + PyTuple_SetItem(ret,0,ret0Py); + PyTuple_SetItem(ret,1,PyString_FromString(ret1.c_str())); + return ret; + } + + DataArrayDouble *getData() throw(INTERP_KERNEL::Exception) + { + DataArrayDouble *ret(self->getData()); + if(ret) + ret->incrRef(); + return ret; + } + + DenseMatrix *__add__(const DenseMatrix *other) throw(INTERP_KERNEL::Exception) + { + return ParaMEDMEM::DenseMatrix::Add(self,other); + } + + DenseMatrix *__sub__(const DenseMatrix *other) throw(INTERP_KERNEL::Exception) + { + return ParaMEDMEM::DenseMatrix::Substract(self,other); + } + + DenseMatrix *__mul__(const DenseMatrix *other) throw(INTERP_KERNEL::Exception) + { + return ParaMEDMEM::DenseMatrix::Multiply(self,other); + } + + DenseMatrix *__mul__(const DataArrayDouble *other) throw(INTERP_KERNEL::Exception) + { + return ParaMEDMEM::DenseMatrix::Multiply(self,other); + } + + PyObject *___iadd___(PyObject *trueSelf, const DenseMatrix *other) throw(INTERP_KERNEL::Exception) + { + self->addEqual(other); + Py_XINCREF(trueSelf); + return trueSelf; + } + + PyObject *___isub___(PyObject *trueSelf, const DenseMatrix *other) throw(INTERP_KERNEL::Exception) + { + self->substractEqual(other); + Py_XINCREF(trueSelf); + return trueSelf; + } +#ifdef WITH_NUMPY + PyObject *toNumPyMatrix() throw(INTERP_KERNEL::Exception) // not const. It is not a bug ! + { + PyObject *obj(ToNumPyArrayUnderground<DataArrayDouble,double>(self->getData(),NPY_DOUBLE,"DataArrayDouble",self->getNumberOfRows(),self->getNumberOfCols())); + return obj; + } +#endif + } + }; + + class PartDefinition : public RefCountObject, public TimeLabel + { + public: + static PartDefinition *New(int start, int stop, int step) throw(INTERP_KERNEL::Exception); + static PartDefinition *New(DataArrayInt *listOfIds) throw(INTERP_KERNEL::Exception); + virtual DataArrayInt *toDAI() const throw(INTERP_KERNEL::Exception); + virtual int getNumberOfElems() const throw(INTERP_KERNEL::Exception); + virtual std::string getRepr() const throw(INTERP_KERNEL::Exception); + virtual PartDefinition *composeWith(const PartDefinition *other) const throw(INTERP_KERNEL::Exception); + virtual void checkCoherency() const throw(INTERP_KERNEL::Exception); + virtual PartDefinition *tryToSimplify() const throw(INTERP_KERNEL::Exception); + %extend + { + virtual PartDefinition *__add__(const PartDefinition& other) const throw(INTERP_KERNEL::Exception) + { + return (*self)+other; + } + + virtual PyObject *isEqual(const PartDefinition *other) const throw(INTERP_KERNEL::Exception) + { + std::string ret1; + bool ret0(self->isEqual(other,ret1)); + PyObject *ret=PyTuple_New(2); + PyObject *ret0Py=ret0?Py_True:Py_False; + Py_XINCREF(ret0Py); + PyTuple_SetItem(ret,0,ret0Py); + PyTuple_SetItem(ret,1,PyString_FromString(ret1.c_str())); + return ret; + } + + virtual PyObject *deepCpy() const throw(INTERP_KERNEL::Exception) + { + return convertPartDefinition(self->deepCpy(),SWIG_POINTER_OWN | 0); + } + } + protected: + virtual ~PartDefinition(); + }; + + class DataArrayPartDefinition : public PartDefinition + { + public: + static DataArrayPartDefinition *New(DataArrayInt *listOfIds) throw(INTERP_KERNEL::Exception); + %extend + { + DataArrayPartDefinition(DataArrayInt *listOfIds) throw(INTERP_KERNEL::Exception) + { + return DataArrayPartDefinition::New(listOfIds); + } + + std::string __str__() const throw(INTERP_KERNEL::Exception) + { + return self->getRepr(); + } + + std::string __repr__() const throw(INTERP_KERNEL::Exception) + { + std::ostringstream oss; oss << "DataArrayPartDefinition C++ instance at " << self << "." << std::endl; + oss << self->getRepr(); + return oss.str(); + } + } + protected: + virtual ~DataArrayPartDefinition(); + }; + + class SlicePartDefinition : public PartDefinition + { + public: + static SlicePartDefinition *New(int start, int stop, int step) throw(INTERP_KERNEL::Exception); + int getEffectiveStop() const throw(INTERP_KERNEL::Exception); + %extend + { + SlicePartDefinition(int start, int stop, int step) throw(INTERP_KERNEL::Exception) + { + return SlicePartDefinition::New(start,stop,step); + } + + PyObject *getSlice() const throw(INTERP_KERNEL::Exception) + { + int a,b,c; + self->getSlice(a,b,c); + return PySlice_New(PyInt_FromLong(a),PyInt_FromLong(b),PyInt_FromLong(c)); + } + + std::string __str__() const throw(INTERP_KERNEL::Exception) + { + return self->getRepr(); + } + + std::string __repr__() const throw(INTERP_KERNEL::Exception) + { + std::ostringstream oss; oss << "SlicePartDefinition C++ instance at " << self << "." << std::endl; + oss << self->getRepr(); + return oss.str(); + } + } + protected: + virtual ~SlicePartDefinition(); + }; +} + +%pythoncode %{ +import os +__filename=os.environ.get('PYTHONSTARTUP') +if __filename and os.path.isfile(__filename): + execfile(__filename) + pass +%} diff --git a/src/medtool/src/MEDCoupling_Swig/MEDCouplingDataArrayTypemaps.i b/src/medtool/src/MEDCoupling_Swig/MEDCouplingDataArrayTypemaps.i new file mode 100644 index 000000000..eba6b204e --- /dev/null +++ b/src/medtool/src/MEDCoupling_Swig/MEDCouplingDataArrayTypemaps.i @@ -0,0 +1,2529 @@ +// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 +// 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 "InterpKernelAutoPtr.hxx" + +/*! + * This method is an extention of PySlice_GetIndices but less + * open than PySlice_GetIndicesEx that accepts too many situations. + */ +void GetIndicesOfSlice(PySliceObject *slice, Py_ssize_t length, Py_ssize_t *start, Py_ssize_t *stop, Py_ssize_t *step, const char *msgInCaseOfFailure) +{ + int ret(PySlice_GetIndices(slice,length,start,stop,step)); + if(ret==0) + return ; + if(*step>0 && *start==*stop && length==*start) + return ; + throw INTERP_KERNEL::Exception(msgInCaseOfFailure); +} + +/*! + * This method allows to retrieve slice info from \a slice. + */ +void GetIndicesOfSliceExplicitely(PySliceObject *slice, Py_ssize_t *start, Py_ssize_t *stop, Py_ssize_t *step, const char *msgInCaseOfFailure) +{ + int ret(PySlice_GetIndices(slice,std::numeric_limits<int>::max(),start,stop,step)); + if(ret==0) + { + if(*start!=std::numeric_limits<int>::max() && *stop!=std::numeric_limits<int>::max()) + return ; + std::ostringstream oss; + oss << msgInCaseOfFailure << " The input slice contains some unknowns that can't be determined in static method ! The input slice must be explicit here !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + throw INTERP_KERNEL::Exception(msgInCaseOfFailure); +} + +int InterpreteNegativeInt(int val, int nbelem) +{ + if(val<0) + { + int newVal(nbelem+val); + if(newVal<0) + { + std::ostringstream oss; oss << "interpreteNegativeInt : request for negative int=" << val << " but number of elems is equal to " << nbelem << " !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + return newVal; + } + else + return val; +} + +#ifdef WITH_NUMPY +#include <numpy/arrayobject.h> +#if NPY_API_VERSION <= 0x00000006 +# define MED_NUMPY_OWNDATA NPY_OWNDATA +#else +# define MED_NUMPY_OWNDATA NPY_ARRAY_OWNDATA +#endif + +// specific DataArray deallocator callback. This deallocator is used both in the constructor of DataArray and in the toNumPyArr +// method. This dellocator uses weakref to determine if the linked numArr is still alive or not. If alive the ownership is given to it. +// if no more alive the "standart" DataArray deallocator is called. +void numarrdeal(void *pt, void *wron) +{ + void **wronc=(void **)wron; + PyObject *weakRefOnOwner=reinterpret_cast<PyObject *>(wronc[0]); + PyObject *obj=PyWeakref_GetObject(weakRefOnOwner); + if(obj!=Py_None) + { + Py_XINCREF(obj); + PyArrayObject *objC=reinterpret_cast<PyArrayObject *>(obj); + objC->flags|=MED_NUMPY_OWNDATA; + Py_XDECREF(weakRefOnOwner); + Py_XDECREF(obj); + } + else + { + typedef void (*MyDeallocator)(void *,void *); + MyDeallocator deall=(MyDeallocator)wronc[1]; + deall(pt,NULL); + Py_XDECREF(weakRefOnOwner); + } + delete [] wronc; +} + +template<class MCData> +struct PyCallBackDataArraySt { + PyObject_HEAD + MCData *_pt_mc; +}; + +typedef struct PyCallBackDataArraySt<ParaMEDMEM::DataArrayInt> PyCallBackDataArrayInt; +typedef struct PyCallBackDataArraySt<ParaMEDMEM::DataArrayDouble> PyCallBackDataArrayDouble; + +extern "C" +{ + static int callbackmcdataarray___init__(PyObject *self, PyObject *args, PyObject *kwargs) { return 0; } + + static PyObject *callbackmcdataarrayint___new__(PyTypeObject *type, PyObject *args, PyObject *kwargs) + { + PyCallBackDataArrayInt *self = (PyCallBackDataArrayInt *) ( type->tp_alloc(type, 0) ); + return (PyObject *)self; + } + + static PyObject *callbackmcdataarraydouble___new__(PyTypeObject *type, PyObject *args, PyObject *kwargs) + { + PyCallBackDataArrayDouble *self = (PyCallBackDataArrayDouble *) ( type->tp_alloc(type, 0) ); + return (PyObject *)self; + } + + static void callbackmcdataarray_dealloc(PyObject *self) + { + Py_TYPE(self)->tp_free(self); + } + + // real callback called when a numpy arr having more than one DataArray instance client on it is destroyed. + // In this case, all the "weak" clients, except the first one, invoke this call back that desable the content of these "weak" clients. + static PyObject *callbackmcdataarrayint_call(PyCallBackDataArrayInt *self, PyObject *args, PyObject *kw) + { + if(self->_pt_mc) + { + ParaMEDMEM::MemArray<int>& mma=self->_pt_mc->accessToMemArray(); + mma.destroy(); + } + Py_XINCREF(Py_None); + return Py_None; + } + + // real callback called when a numpy arr having more than one DataArray instance client on it is destroyed. + // In this case, all the "weak" clients, except the first one, invoke this call back that desable the content of these "weak" clients. + static PyObject *callbackmcdataarraydouble_call(PyCallBackDataArrayDouble *self, PyObject *args, PyObject *kw) + { + if(self->_pt_mc) + { + ParaMEDMEM::MemArray<double>& mma=self->_pt_mc->accessToMemArray(); + mma.destroy(); + } + Py_XINCREF(Py_None); + return Py_None; + } +} + +PyTypeObject PyCallBackDataArrayInt_RefType = { + PyVarObject_HEAD_INIT(&PyType_Type, 0) + "callbackmcdataarrayint", + sizeof(PyCallBackDataArrayInt), + 0, + callbackmcdataarray_dealloc, /*tp_dealloc*/ + 0, /*tp_print*/ + 0, /*tp_getattr*/ + 0, /*tp_setattr*/ + 0, /*tp_compare*/ + 0, /*tp_repr*/ + 0, /*tp_as_number*/ + 0, /*tp_as_sequence*/ + 0, /*tp_as_mapping*/ + 0, /*tp_hash*/ + (ternaryfunc)callbackmcdataarrayint_call, /*tp_call*/ + 0, /*tp_str*/ + 0, /*tp_getattro*/ + 0, /*tp_setattro*/ + 0, /*tp_as_buffer*/ + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_BASETYPE, /*tp_flags*/ + 0, /*tp_doc*/ + 0, /*tp_traverse*/ + 0, /*tp_clear*/ + 0, /*tp_richcompare*/ + 0, /*tp_weaklistoffset*/ + 0, /*tp_iter*/ + 0, /*tp_iternext*/ + 0, /*tp_methods*/ + 0, /*tp_members*/ + 0, /*tp_getset*/ + 0, /*tp_base*/ + 0, /*tp_dict*/ + 0, /*tp_descr_get*/ + 0, /*tp_descr_set*/ + 0, /*tp_dictoffset*/ + callbackmcdataarray___init__, /*tp_init*/ + PyType_GenericAlloc, /*tp_alloc*/ + callbackmcdataarrayint___new__, /*tp_new*/ + PyObject_GC_Del, /*tp_free*/ +}; + +PyTypeObject PyCallBackDataArrayDouble_RefType = { + PyVarObject_HEAD_INIT(&PyType_Type, 0) + "callbackmcdataarraydouble", + sizeof(PyCallBackDataArrayDouble), + 0, + callbackmcdataarray_dealloc, /*tp_dealloc*/ + 0, /*tp_print*/ + 0, /*tp_getattr*/ + 0, /*tp_setattr*/ + 0, /*tp_compare*/ + 0, /*tp_repr*/ + 0, /*tp_as_number*/ + 0, /*tp_as_sequence*/ + 0, /*tp_as_mapping*/ + 0, /*tp_hash*/ + (ternaryfunc)callbackmcdataarraydouble_call, /*tp_call*/ + 0, /*tp_str*/ + 0, /*tp_getattro*/ + 0, /*tp_setattro*/ + 0, /*tp_as_buffer*/ + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_BASETYPE, /*tp_flags*/ + 0, /*tp_doc*/ + 0, /*tp_traverse*/ + 0, /*tp_clear*/ + 0, /*tp_richcompare*/ + 0, /*tp_weaklistoffset*/ + 0, /*tp_iter*/ + 0, /*tp_iternext*/ + 0, /*tp_methods*/ + 0, /*tp_members*/ + 0, /*tp_getset*/ + 0, /*tp_base*/ + 0, /*tp_dict*/ + 0, /*tp_descr_get*/ + 0, /*tp_descr_set*/ + 0, /*tp_dictoffset*/ + callbackmcdataarray___init__, /*tp_init*/ + PyType_GenericAlloc, /*tp_alloc*/ + callbackmcdataarraydouble___new__, /*tp_new*/ + PyObject_GC_Del, /*tp_free*/ +}; + +// this is the second type of specific deallocator, only valid for the constructor of DataArrays taking numpy array +// in input when an another DataArray is already client of this. +template<class MCData> +void numarrdeal2(void *pt, void *obj) +{ + typedef struct PyCallBackDataArraySt<MCData> PyCallBackDataArray; + void **obj1=(void **)obj; + PyCallBackDataArray *cbdaic=reinterpret_cast<PyCallBackDataArray *>(obj1[0]); + PyObject *weakRefOnOwner=reinterpret_cast<PyObject *>(obj1[1]); + cbdaic->_pt_mc=0; + Py_XDECREF(weakRefOnOwner); + Py_XDECREF(cbdaic); + delete [] obj1; +} + +template<class MCData, class T> +MCData *BuildNewInstance(PyObject *elt0, int npyObjectType, PyTypeObject *pytype, const char *msg) +{ + int ndim=PyArray_NDIM(elt0); + if(ndim!=1 && ndim!=2) + throw INTERP_KERNEL::Exception("Input numpy array should have dimension equal to 1 or 2 !"); + if(PyArray_DESCR(elt0)->type_num != npyObjectType) + { + std::ostringstream oss; oss << "Input numpy array has not the type " << msg << "!"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + npy_intp sz0=PyArray_DIM(elt0,0); + npy_intp sz1=ndim==2?PyArray_DIM(elt0,1):1; + // + int itemSize=PyArray_ITEMSIZE(elt0); + if(itemSize!=sizeof(T)) + { + std::ostringstream oss; oss << "Input numpy array has not itemSize set to " << sizeof(T) << " !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + if(itemSize*sz1!=PyArray_STRIDE(elt0,0)) + throw INTERP_KERNEL::Exception("Input numpy array has stride that mismatches the item size ! Data are not packed in the right way for DataArrays !"); + if(ndim==2) + if(itemSize!=PyArray_STRIDE(elt0,1)) + throw INTERP_KERNEL::Exception("Input numpy array has stride that mismatches the item size ! Data are not packed in the right way for DataArrays for component #1 !"); + const char *data=PyArray_BYTES(elt0); + typename ParaMEDMEM::MEDCouplingAutoRefCountObjectPtr<MCData> ret=MCData::New(); + if(PyArray_ISBEHAVED(elt0))//aligned and writeable and in machine byte-order + { + PyArrayObject *elt0C=reinterpret_cast<PyArrayObject *>(elt0); + PyArrayObject *eltOwning=(PyArray_FLAGS(elt0C) & MED_NUMPY_OWNDATA)?elt0C:NULL; + int mask=MED_NUMPY_OWNDATA; mask=~mask; + elt0C->flags&=mask; + PyObject *deepestObj=elt0; + PyObject *base=elt0C->base; + if(base) deepestObj=base; + bool isSpetialCase(false); + while(base) + { + if(PyArray_Check(base)) + { + PyArrayObject *baseC=reinterpret_cast<PyArrayObject *>(base); + eltOwning=(PyArray_FLAGS(baseC) & MED_NUMPY_OWNDATA)?baseC:eltOwning; + baseC->flags&=mask; + base=baseC->base; + if(base) deepestObj=base; + } + else + { + isSpetialCase=true; + break; + } + } + if(isSpetialCase) + {// this case is present for numpy arrayint coming from load of pickelized string. The owner of elt0 is not an array -> A copy is requested. + std::size_t nbOfElems(sz0*sz1); + T *dataCpy=(T*)malloc(sizeof(T)*nbOfElems); + std::copy(reinterpret_cast<const T*>(data),reinterpret_cast<const T*>(data)+nbOfElems,dataCpy); + ret->useArray(dataCpy,true,ParaMEDMEM::C_DEALLOC,sz0,sz1); + return ret.retn(); + } + typename ParaMEDMEM::MemArray<T>& mma=ret->accessToMemArray(); + if(eltOwning==NULL) + { + PyCallBackDataArraySt<MCData> *cb=PyObject_GC_New(PyCallBackDataArraySt<MCData>,pytype); + cb->_pt_mc=ret; + ret->useArray(reinterpret_cast<const T *>(data),true,ParaMEDMEM::C_DEALLOC,sz0,sz1); + PyObject *ref=PyWeakref_NewRef(deepestObj,(PyObject *)cb); + void **objs=new void *[2]; objs[0]=cb; objs[1]=ref; + mma.setParameterForDeallocator(objs); + mma.setSpecificDeallocator(numarrdeal2<MCData>); + //"Impossible to share this numpy array chunk of data, because already shared by an another non numpy array object (maybe an another DataArrayInt instance) ! Release it, or perform a copy on the input array !"); + } + else + { + ret->useArray(reinterpret_cast<const T *>(data),true,ParaMEDMEM::C_DEALLOC,sz0,sz1); + PyObject *ref=PyWeakref_NewRef(reinterpret_cast<PyObject *>(eltOwning),NULL); + typename ParaMEDMEM::MemArray<T>::Deallocator tmp(ParaMEDMEM::MemArray<T>::CDeallocator); + void **tmp2 = reinterpret_cast<void**>(&tmp); // MSVC2010 does not support constructor() + void **objs=new void *[2]; objs[0]=ref; objs[1]=*tmp2; + mma.setParameterForDeallocator(objs); + mma.setSpecificDeallocator(numarrdeal); + } + } + else if(PyArray_ISBEHAVED_RO(elt0)) + ret->useArray(reinterpret_cast<const T *>(data),false,ParaMEDMEM::CPP_DEALLOC,sz0,sz1); + return ret.retn(); +} + + +int NumpyArrSetBaseObjectExt(PyArrayObject *arr, PyObject *obj) +{ + if (obj == NULL) { + PyErr_SetString(PyExc_ValueError, + "Cannot set the NumPy array 'base' " + "dependency to NULL after initialization"); + return -1; + } + /* + * Allow the base to be set only once. Once the object which + * owns the data is set, it doesn't make sense to change it. + */ + if (PyArray_BASE(arr) != NULL) { + Py_DECREF(obj); + PyErr_SetString(PyExc_ValueError, + "Cannot set the NumPy array 'base' " + "dependency more than once"); + return -1; + } + + /* + * Don't allow infinite chains of views, always set the base + * to the first owner of the data. + * That is, either the first object which isn't an array, + * or the first object which owns its own data. + */ + + while (PyArray_Check(obj) && (PyObject *)arr != obj) { + PyArrayObject *obj_arr = (PyArrayObject *)obj; + PyObject *tmp; + + + /* If this array owns its own data, stop collapsing */ + if (PyArray_CHKFLAGS(obj_arr, MED_NUMPY_OWNDATA )) { + break; + } + + tmp = PyArray_BASE(obj_arr); + /* If there's no base, stop collapsing */ + if (tmp == NULL) { + break; + } + /* Stop the collapse new base when the would not be of the same + * type (i.e. different subclass). + */ + if (Py_TYPE(tmp) != Py_TYPE(arr)) { + break; + } + + + Py_INCREF(tmp); + Py_DECREF(obj); + obj = tmp; + } + + /* Disallow circular references */ + if ((PyObject *)arr == obj) { + Py_DECREF(obj); + PyErr_SetString(PyExc_ValueError, + "Cannot create a circular NumPy array 'base' dependency"); + return -1; + } + + arr->base = obj; + + return 0; +} + +template<class MCData, class T> +PyObject *ToNumPyArrayUnderground(MCData *self, int npyObjectType, const char *MCDataStr, int nbTuples, int nbComp) +{ + if(!self->isAllocated()) + { + std::ostringstream oss; oss << MCDataStr << "::toNumPyArray : this is not allocated !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + ParaMEDMEM::MemArray<T>& mem=self->accessToMemArray(); + if(nbComp==0) + { + std::ostringstream oss; oss << MCDataStr << "::toNumPyArray : number of components of this is 0 ! Should be > 0 !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + int nbDims=nbComp==1?1:2; + npy_intp dim[2]; + dim[0]=(npy_intp)nbTuples; dim[1]=nbComp; + const T *bg=self->getConstPointer(); + PyObject *ret(PyArray_SimpleNewFromData(nbDims,dim,npyObjectType,const_cast<T *>(bg))); + if(mem.isDeallocatorCalled()) + { + if(mem.getDeallocator()!=numarrdeal) + {// case for the first call of toNumPyArray + PyObject *ref(PyWeakref_NewRef(ret,NULL)); + typename ParaMEDMEM::MemArray<T>::Deallocator tmp(mem.getDeallocator()); + void **tmp2 = reinterpret_cast<void**>(&tmp); // MSVC2010 does not support constructor() + void **objs=new void *[2]; objs[0]=reinterpret_cast<void*>(ref); objs[1]=*tmp2; + mem.setParameterForDeallocator(objs); + mem.setSpecificDeallocator(numarrdeal); + return ret; + } + else + {// case for the second and other call of toNumPyArray + void **objs=(void **)mem.getParameterForDeallocator(); + PyObject *weakRefOnOwner=(PyObject *)objs[0]; + PyObject *obj=PyWeakref_GetObject(weakRefOnOwner); + if(obj!=Py_None) + {//the previous numArray exists let numpy deals the numpy array each other by declaring the still alive instance as base + Py_XINCREF(obj); + NumpyArrSetBaseObjectExt((PyArrayObject*)ret,obj); + } + else + {//the previous numArray no more exists -> declare the newly created numpy array as the first one. + Py_XDECREF(weakRefOnOwner); + PyObject *ref=PyWeakref_NewRef(ret,NULL); + objs[0]=ref; + } + } + } + return ret; +} + +template<class MCData, class T> +PyObject *ToNumPyArray(MCData *self, int npyObjectType, const char *MCDataStr) +{ + return ToNumPyArrayUnderground<MCData,T>(self,npyObjectType,MCDataStr,self->getNumberOfTuples(),self->getNumberOfComponents()); +} + +SWIGINTERN PyObject *ParaMEDMEM_DataArrayInt_toNumPyArray(ParaMEDMEM::DataArrayInt *self); +SWIGINTERN PyObject *ParaMEDMEM_DataArrayDouble_toNumPyArray(ParaMEDMEM::DataArrayDouble *self); + +PyObject *ToCSRMatrix(const std::vector<std::map<int,double> >& m, int nbCols) throw(INTERP_KERNEL::Exception) +{ + int nbRows((int)m.size()); + ParaMEDMEM::MEDCouplingAutoRefCountObjectPtr<ParaMEDMEM::DataArrayInt> indPtr(ParaMEDMEM::DataArrayInt::New()),indices(ParaMEDMEM::DataArrayInt::New()); + ParaMEDMEM::MEDCouplingAutoRefCountObjectPtr<ParaMEDMEM::DataArrayDouble> data(ParaMEDMEM::DataArrayDouble::New()); + indPtr->alloc(nbRows+1,1); + int *intPtr_ptr(indPtr->getPointer()); intPtr_ptr[0]=0; intPtr_ptr++; + int sz2(0); + for(std::vector<std::map<int,double> >::const_iterator it0=m.begin();it0!=m.end();it0++,intPtr_ptr++) + { + sz2+=(int)(*it0).size(); + *intPtr_ptr=sz2; + } + indices->alloc(sz2,1); data->alloc(sz2,1); + int *indices_ptr(indices->getPointer()); + double *data_ptr(data->getPointer()); + for(std::vector<std::map<int,double> >::const_iterator it0=m.begin();it0!=m.end();it0++) + for(std::map<int,double>::const_iterator it1=(*it0).begin();it1!=(*it0).end();it1++,indices_ptr++,data_ptr++) + { + *indices_ptr=(*it1).first; + *data_ptr=(*it1).second; + } + PyObject *a(ParaMEDMEM_DataArrayDouble_toNumPyArray(data)),*b(ParaMEDMEM_DataArrayInt_toNumPyArray(indices)),*c(ParaMEDMEM_DataArrayInt_toNumPyArray(indPtr)); + // + PyObject *args(PyTuple_New(1)),*args0(PyTuple_New(3)),*kw(PyDict_New()),*kw1(PyTuple_New(2)); + PyTuple_SetItem(args0,0,a); PyTuple_SetItem(args0,1,b); PyTuple_SetItem(args0,2,c); PyTuple_SetItem(args,0,args0); + PyTuple_SetItem(kw1,0,PyInt_FromLong(nbRows)); PyTuple_SetItem(kw1,1,PyInt_FromLong(nbCols)); + PyObject *tmp1(PyString_FromString("shape")); + PyDict_SetItem(kw,tmp1,kw1); Py_DECREF(tmp1); Py_DECREF(kw1); + PyObject* pdict=PyDict_New(); + PyDict_SetItemString(pdict, "__builtins__", PyEval_GetBuiltins()); + PyObject *tmp(PyRun_String("from scipy.sparse import csr_matrix", Py_single_input, pdict, pdict)); + if(!tmp) + throw INTERP_KERNEL::Exception("Problem during loading csr_matrix in scipy.sparse ! Is Scipy module available in present ?"); + PyObject *csrMatrixCls=PyDict_GetItemString(pdict,"csr_matrix"); + if(!csrMatrixCls) + throw INTERP_KERNEL::Exception("csr_matrix not found in scipy.sparse ! Is Scipy module available in present ?"); + PyObject *ret(PyObject_Call(csrMatrixCls,args,kw)); + Py_DECREF(pdict); Py_XDECREF(tmp); Py_DECREF(args); Py_DECREF(kw); + return ret; +} + +#endif + +static PyObject *convertDataArrayChar(ParaMEDMEM::DataArrayChar *dac, int owner) throw(INTERP_KERNEL::Exception) +{ + PyObject *ret=0; + if(!dac) + { + Py_XINCREF(Py_None); + return Py_None; + } + if(dynamic_cast<ParaMEDMEM::DataArrayByte *>(dac)) + ret=SWIG_NewPointerObj((void*)dac,SWIGTYPE_p_ParaMEDMEM__DataArrayByte,owner); + if(dynamic_cast<ParaMEDMEM::DataArrayAsciiChar *>(dac)) + ret=SWIG_NewPointerObj((void*)dac,SWIGTYPE_p_ParaMEDMEM__DataArrayAsciiChar,owner); + if(!ret) + throw INTERP_KERNEL::Exception("Not recognized type of DataArrayChar on downcast !"); + return ret; +} + +static PyObject *convertDataArray(ParaMEDMEM::DataArray *dac, int owner) throw(INTERP_KERNEL::Exception) +{ + PyObject *ret=0; + if(!dac) + { + Py_XINCREF(Py_None); + return Py_None; + } + if(dynamic_cast<ParaMEDMEM::DataArrayDouble *>(dac)) + ret=SWIG_NewPointerObj((void*)dac,SWIGTYPE_p_ParaMEDMEM__DataArrayDouble,owner); + if(dynamic_cast<ParaMEDMEM::DataArrayInt *>(dac)) + ret=SWIG_NewPointerObj((void*)dac,SWIGTYPE_p_ParaMEDMEM__DataArrayInt,owner); + if(dynamic_cast<ParaMEDMEM::DataArrayByte *>(dac)) + ret=SWIG_NewPointerObj((void*)dac,SWIGTYPE_p_ParaMEDMEM__DataArrayByte,owner); + if(dynamic_cast<ParaMEDMEM::DataArrayAsciiChar *>(dac)) + ret=SWIG_NewPointerObj((void*)dac,SWIGTYPE_p_ParaMEDMEM__DataArrayAsciiChar,owner); + if(!ret) + throw INTERP_KERNEL::Exception("Not recognized type of DataArray on downcast !"); + return ret; +} + +static PyObject *convertIntArrToPyList(const int *ptr, int size) throw(INTERP_KERNEL::Exception) +{ + PyObject *ret=PyList_New(size); + for(int i=0;i<size;i++) + PyList_SetItem(ret,i,PyInt_FromLong(ptr[i])); + return ret; +} + +static PyObject *convertIntArrToPyList2(const std::vector<int>& v) throw(INTERP_KERNEL::Exception) +{ + int size=v.size(); + PyObject *ret=PyList_New(size); + for(int i=0;i<size;i++) + PyList_SetItem(ret,i,PyInt_FromLong(v[i])); + return ret; +} + +static PyObject *convertIntArrToPyList3(const std::set<int>& v) throw(INTERP_KERNEL::Exception) +{ + int size=v.size(); + PyObject *ret=PyList_New(size); + std::set<int>::const_iterator it=v.begin(); + for(int i=0;i<size;i++,it++) + PyList_SetItem(ret,i,PyInt_FromLong(*it)); + return ret; +} + +static PyObject *convertIntArrToPyListOfTuple(const int *vals, int nbOfComp, int nbOfTuples) throw(INTERP_KERNEL::Exception) +{ + PyObject *ret=PyList_New(nbOfTuples); + for(int i=0;i<nbOfTuples;i++) + { + PyObject *t=PyTuple_New(nbOfComp); + for(int j=0;j<nbOfComp;j++) + PyTuple_SetItem(t,j,PyInt_FromLong(vals[i*nbOfComp+j])); + PyList_SetItem(ret,i,t); + } + return ret; +} + +static int *convertPyToNewIntArr2(PyObject *pyLi, int *size) throw(INTERP_KERNEL::Exception) +{ + if(PyList_Check(pyLi)) + { + *size=PyList_Size(pyLi); + int *tmp=new int[*size]; + for(int i=0;i<*size;i++) + { + PyObject *o=PyList_GetItem(pyLi,i); + if(PyInt_Check(o)) + { + int val=(int)PyInt_AS_LONG(o); + tmp[i]=val; + } + else + { + delete [] tmp; + throw INTERP_KERNEL::Exception("list must contain integers only"); + } + } + return tmp; + } + else if(PyTuple_Check(pyLi)) + { + *size=PyTuple_Size(pyLi); + int *tmp=new int[*size]; + for(int i=0;i<*size;i++) + { + PyObject *o=PyTuple_GetItem(pyLi,i); + if(PyInt_Check(o)) + { + int val=(int)PyInt_AS_LONG(o); + tmp[i]=val; + } + else + { + delete [] tmp; + throw INTERP_KERNEL::Exception("tuple must contain integers only"); + } + } + return tmp; + } + else + { + throw INTERP_KERNEL::Exception("convertPyToNewIntArr2 : not a list"); + } +} + +static PyObject *convertFromVectorPairInt(const std::vector< std::pair<int,int> >& arr) throw(INTERP_KERNEL::Exception) +{ + PyObject *ret=PyList_New(arr.size()); + for(std::size_t i=0;i<arr.size();i++) + { + PyObject *t=PyTuple_New(2); + PyTuple_SetItem(t,0,PyInt_FromLong(arr[i].first)); + PyTuple_SetItem(t,1,PyInt_FromLong(arr[i].second)); + PyList_SetItem(ret,i,t); + } + return ret; +} + +static void convertPyToVectorPairInt(PyObject *pyLi, std::vector< std::pair<int,int> >& arr) throw(INTERP_KERNEL::Exception) +{ + const char msg[]="list must contain tuples of 2 integers only or tuple must contain tuples of 2 integers only !"; + if(PyList_Check(pyLi)) + { + int size=PyList_Size(pyLi); + arr.resize(size); + for(int i=0;i<size;i++) + { + PyObject *o=PyList_GetItem(pyLi,i); + if(PyTuple_Check(o)) + { + int sz2=PyTuple_Size(o); + if(sz2!=2) + throw INTERP_KERNEL::Exception(msg); + PyObject *o_0=PyTuple_GetItem(o,0); + if(!PyInt_Check(o_0)) + throw INTERP_KERNEL::Exception(msg); + PyObject *o_1=PyTuple_GetItem(o,1); + if(!PyInt_Check(o_1)) + throw INTERP_KERNEL::Exception(msg); + arr[i].first=(int)PyInt_AS_LONG(o_0); + arr[i].second=(int)PyInt_AS_LONG(o_1); + } + else + throw INTERP_KERNEL::Exception(msg); + } + } + else if(PyTuple_Check(pyLi)) + { + int size=PyTuple_Size(pyLi); + arr.resize(size); + for(int i=0;i<size;i++) + { + PyObject *o=PyTuple_GetItem(pyLi,i); + if(PyTuple_Check(o)) + { + int sz2=PyTuple_Size(o); + if(sz2!=2) + throw INTERP_KERNEL::Exception(msg); + PyObject *o_0=PyTuple_GetItem(o,0); + if(!PyInt_Check(o_0)) + throw INTERP_KERNEL::Exception(msg); + PyObject *o_1=PyTuple_GetItem(o,1); + if(!PyInt_Check(o_1)) + throw INTERP_KERNEL::Exception(msg); + arr[i].first=(int)PyInt_AS_LONG(o_0); + arr[i].second=(int)PyInt_AS_LONG(o_1); + } + else + throw INTERP_KERNEL::Exception(msg); + } + } + else + throw INTERP_KERNEL::Exception(msg); +} + +static void convertPyToVectorPairStringInt(PyObject *pyLi, std::vector< std::pair<std::string,int> >& arr) throw(INTERP_KERNEL::Exception) +{ + const char msg[]="convertPyToVectorPairStringInt : list must contain tuples of 2 integers only or tuple must contain tuples of 1 string and 1 integer only !"; + if(PyList_Check(pyLi)) + { + int size=PyList_Size(pyLi); + arr.resize(size); + for(int i=0;i<size;i++) + { + PyObject *o=PyList_GetItem(pyLi,i); + if(PyTuple_Check(o)) + { + int sz2=PyTuple_Size(o); + if(sz2!=2) + throw INTERP_KERNEL::Exception(msg); + PyObject *o_0=PyTuple_GetItem(o,0); + if(!PyString_Check(o_0)) + throw INTERP_KERNEL::Exception(msg); + PyObject *o_1=PyTuple_GetItem(o,1); + if(!PyInt_Check(o_1)) + throw INTERP_KERNEL::Exception(msg); + arr[i].first=PyString_AsString(o_0); + arr[i].second=(int)PyInt_AS_LONG(o_1); + } + else + throw INTERP_KERNEL::Exception(msg); + } + } + else if(PyTuple_Check(pyLi)) + { + int size=PyTuple_Size(pyLi); + arr.resize(size); + for(int i=0;i<size;i++) + { + PyObject *o=PyTuple_GetItem(pyLi,i); + if(PyTuple_Check(o)) + { + int sz2=PyTuple_Size(o); + if(sz2!=2) + throw INTERP_KERNEL::Exception(msg); + PyObject *o_0=PyTuple_GetItem(o,0); + if(!PyString_Check(o_0)) + throw INTERP_KERNEL::Exception(msg); + PyObject *o_1=PyTuple_GetItem(o,1); + if(!PyInt_Check(o_1)) + throw INTERP_KERNEL::Exception(msg); + arr[i].first=PyString_AsString(o_0); + arr[i].second=(int)PyInt_AS_LONG(o_1); + } + else + throw INTERP_KERNEL::Exception(msg); + } + } + else + throw INTERP_KERNEL::Exception(msg); +} + +static void convertPyToNewIntArr3(PyObject *pyLi, std::vector<int>& arr) throw(INTERP_KERNEL::Exception) +{ + if(PyList_Check(pyLi)) + { + int size=PyList_Size(pyLi); + arr.resize(size); + for(int i=0;i<size;i++) + { + PyObject *o=PyList_GetItem(pyLi,i); + if(PyInt_Check(o)) + { + int val=(int)PyInt_AS_LONG(o); + arr[i]=val; + } + else + throw INTERP_KERNEL::Exception("list must contain integers only"); + } + } + else if(PyTuple_Check(pyLi)) + { + int size=PyTuple_Size(pyLi); + arr.resize(size); + for(int i=0;i<size;i++) + { + PyObject *o=PyTuple_GetItem(pyLi,i); + if(PyInt_Check(o)) + { + int val=(int)PyInt_AS_LONG(o); + arr[i]=val; + } + else + throw INTERP_KERNEL::Exception("tuple must contain integers only"); + } + } + else + { + throw INTERP_KERNEL::Exception("convertPyToNewIntArr3 : not a list nor a tuple"); + } +} + +static void convertPyToNewIntArr4(PyObject *pyLi, int recurseLev, int nbOfSubPart, std::vector<int>& arr) throw(INTERP_KERNEL::Exception) +{ + if(recurseLev<0) + throw INTERP_KERNEL::Exception("convertPyToNewIntArr4 : invalid list of integers level of recursion !"); + arr.clear(); + if(PyList_Check(pyLi)) + { + int size=PyList_Size(pyLi); + for(int i=0;i<size;i++) + { + PyObject *o=PyList_GetItem(pyLi,i); + if(PyInt_Check(o)) + { + int val=(int)PyInt_AS_LONG(o); + arr.push_back(val); + } + else + { + std::vector<int> arr2; + convertPyToNewIntArr4(o,recurseLev-1,nbOfSubPart,arr2); + if(nbOfSubPart>=1 && nbOfSubPart!=(int)arr2.size()) + { + std::ostringstream oss; oss << "convertPyToNewIntArr4 : input list at lev " << recurseLev << " invalid nb of subpart elts expected " << nbOfSubPart << " having " << arr2.size() << " !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + arr.insert(arr.end(),arr2.begin(),arr2.end()); + } + } + } + else if(PyTuple_Check(pyLi)) + { + int size=PyTuple_Size(pyLi); + for(int i=0;i<size;i++) + { + PyObject *o=PyTuple_GetItem(pyLi,i); + if(PyInt_Check(o)) + { + int val=(int)PyInt_AS_LONG(o); + arr.push_back(val); + } + else + { + std::vector<int> arr2; + convertPyToNewIntArr4(o,recurseLev-1,nbOfSubPart,arr2); + if(nbOfSubPart>=1 && nbOfSubPart!=(int)arr2.size()) + { + std::ostringstream oss; oss << "convertPyToNewIntArr4 : input list at lev " << recurseLev << " invalid nb of subpart elts expected " << nbOfSubPart << " having " << arr2.size() << " !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + arr.insert(arr.end(),arr2.begin(),arr2.end()); + } + } + } + else + throw INTERP_KERNEL::Exception("convertPyToNewIntArr4 : not a list nor a tuple recursively !"); +} + +static void checkFillArrayWithPyList(int size1, int size2, int& nbOfTuples, int& nbOfComp) throw(INTERP_KERNEL::Exception) +{ + if(nbOfTuples==-1) + { + if(nbOfComp==-1) { nbOfTuples=size1; nbOfComp=size2; } + else { if(nbOfComp==size2) { nbOfTuples=size1; } else + { + std::ostringstream oss; oss << "fillArrayWithPyListDbl2 : mismatch between nb of elemts : Input has " << size1 << " tuples and " << size2 << " components"; + oss << " whereas nb of components expected is " << nbOfComp << " !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } } + } + else + { + if(nbOfComp!=-1) + { + if((nbOfTuples!=size1 || nbOfComp!=size2)) + { + if(size2!=1 || size1!=nbOfComp*nbOfTuples) + { + std::ostringstream oss; oss << "fillArrayWithPyListDbl2 : mismatch between nb of elemts : Input has " << size1 << " tuples and " << size2 << " components"; + oss << " whereas nb of tuples expected is " << nbOfTuples << " and number of components expected is " << nbOfComp << " !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + } + } + else + { + if(nbOfTuples==size1) + nbOfComp=size2; + else + { + std::ostringstream oss; oss << "fillArrayWithPyListDbl2 : mismatch between nb of elemts : Input has " << size1 << " tuples and " << size2 << " components"; + oss << " whereas nb of tuples expected is " << nbOfTuples << " !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + } + } +} + +static void fillArrayWithPyListInt3(PyObject *pyLi, int& nbOfElt, std::vector<int>& ret) +{ + static const char MSG[]="fillArrayWithPyListInt3 : It appears that the input list or tuple is composed by elts having different sizes !"; + if(PyInt_Check(pyLi)) + { + long val=PyInt_AS_LONG(pyLi); + if(nbOfElt==-1) + nbOfElt=1; + else + if(nbOfElt!=1) + throw INTERP_KERNEL::Exception(MSG); + ret.push_back(val); + } + else if(PyList_Check(pyLi)) + { + int size=PyList_Size(pyLi); + int tmp=0; + for(int i=0;i<size;i++) + { + PyObject *o=PyList_GetItem(pyLi,i); + int tmp1=-1; + fillArrayWithPyListInt3(o,tmp1,ret); + tmp+=tmp1; + } + if(nbOfElt==-1) + nbOfElt=tmp; + else + { + if(nbOfElt!=tmp) + throw INTERP_KERNEL::Exception(MSG); + } + } + else if(PyTuple_Check(pyLi)) + { + int size=PyTuple_Size(pyLi); + int tmp=0; + for(int i=0;i<size;i++) + { + PyObject *o=PyTuple_GetItem(pyLi,i); + int tmp1=-1; + fillArrayWithPyListInt3(o,tmp1,ret); + tmp+=tmp1; + } + if(nbOfElt==-1) + nbOfElt=tmp; + else + { + if(nbOfElt!=tmp) + throw INTERP_KERNEL::Exception(MSG); + } + } + else + throw INTERP_KERNEL::Exception("fillArrayWithPyListInt3 : Unrecognized type ! Should be a composition of tuple,list,int !"); +} + +static std::vector<int> fillArrayWithPyListInt2(PyObject *pyLi, int& nbOfTuples, int& nbOfComp) throw(INTERP_KERNEL::Exception) +{ + std::vector<int> ret; + int size1=-1,size2=-1; + if(PyList_Check(pyLi)) + { + size1=PyList_Size(pyLi); + for(int i=0;i<size1;i++) + { + PyObject *o=PyList_GetItem(pyLi,i); + fillArrayWithPyListInt3(o,size2,ret); + } + if(size1==0) + size2=1; + } + else if(PyTuple_Check(pyLi)) + { + size1=PyTuple_Size(pyLi); + for(int i=0;i<size1;i++) + { + PyObject *o=PyTuple_GetItem(pyLi,i); + fillArrayWithPyListInt3(o,size2,ret); + } + if(size1==0) + size2=1; + } + else + throw INTERP_KERNEL::Exception("fillArrayWithPyListInt2 : Unrecognized type ! Should be a tuple or a list !"); + // + checkFillArrayWithPyList(size1,size2,nbOfTuples,nbOfComp); + return ret; +} + +static bool fillStringVector(PyObject *pyLi, std::vector<std::string>& vec) throw(INTERP_KERNEL::Exception) +{ + if(PyList_Check(pyLi)) + { + Py_ssize_t sz=PyList_Size(pyLi); + vec.resize(sz); + for(int i=0;i<sz;i++) + { + PyObject *o=PyList_GetItem(pyLi,i); + if(PyString_Check(o)) + vec[i]=PyString_AsString(o); + else + return false; + } + return true; + } + else if(PyTuple_Check(pyLi)) + { + Py_ssize_t sz=PyTuple_Size(pyLi); + vec.resize(sz); + for(int i=0;i<sz;i++) + { + PyObject *o=PyTuple_GetItem(pyLi,i); + if(PyString_Check(o)) + vec[i]=PyString_AsString(o); + else + return false; + } + return true; + } + else + return false; +} +static void convertPyToVectorOfVectorOfString(PyObject *pyLi, std::vector< std::vector<std::string> >& arr) throw(INTERP_KERNEL::Exception) +{ + const char msg[]="convertPyToVectorOfVectorOfString : expecting list of list of strings !"; + if(PyList_Check(pyLi)) + { + Py_ssize_t sz=PyList_Size(pyLi); + arr.resize(sz); + for(int i=0;i<sz;i++) + { + PyObject *o=PyList_GetItem(pyLi,i); + if(!fillStringVector(o,arr[i])) + throw INTERP_KERNEL::Exception(msg); + } + } + else if(PyTuple_Check(pyLi)) + { + Py_ssize_t sz=PyTuple_Size(pyLi); + arr.resize(sz); + for(int i=0;i<sz;i++) + { + PyObject *o=PyTuple_GetItem(pyLi,i); + if(!fillStringVector(o,arr[i])) + throw INTERP_KERNEL::Exception(msg); + } + } + else + throw INTERP_KERNEL::Exception(msg); +} + +static bool fillIntVector(PyObject *pyLi, std::vector<int>& vec) throw(INTERP_KERNEL::Exception) +{ + if(PyList_Check(pyLi)) + { + Py_ssize_t sz=PyList_Size(pyLi); + vec.resize(sz); + for(int i=0;i<sz;i++) + { + PyObject *o=PyList_GetItem(pyLi,i); + if(PyInt_Check(o)) + vec[i]=PyInt_AS_LONG(o); + else + return false; + } + return true; + } + else if(PyTuple_Check(pyLi)) + { + Py_ssize_t sz=PyTuple_Size(pyLi); + vec.resize(sz); + for(int i=0;i<sz;i++) + { + PyObject *o=PyTuple_GetItem(pyLi,i); + if(PyInt_Check(o)) + vec[i]=PyInt_AS_LONG(o); + else + return false; + } + return true; + } + else + return false; +} + +static void convertPyToVectorOfVectorOfInt(PyObject *pyLi, std::vector< std::vector<int> >& arr) throw(INTERP_KERNEL::Exception) +{ + const char msg[]="convertPyToVectorOfVectorOfInt : expecting list of list of strings !"; + if(PyList_Check(pyLi)) + { + Py_ssize_t sz=PyList_Size(pyLi); + arr.resize(sz); + for(int i=0;i<sz;i++) + { + PyObject *o=PyList_GetItem(pyLi,i); + if(!fillIntVector(o,arr[i])) + throw INTERP_KERNEL::Exception(msg); + } + } + else if(PyTuple_Check(pyLi)) + { + Py_ssize_t sz=PyTuple_Size(pyLi); + arr.resize(sz); + for(int i=0;i<sz;i++) + { + PyObject *o=PyTuple_GetItem(pyLi,i); + if(!fillIntVector(o,arr[i])) + throw INTERP_KERNEL::Exception(msg); + } + } + else + throw INTERP_KERNEL::Exception(msg); +} + +static void convertPyToVectorPairStringVecString(PyObject *pyLi, std::vector< std::pair<std::string, std::vector<std::string> > >& arr) throw(INTERP_KERNEL::Exception) +{ + const char msg[]="convertPyToVectorPairStringVecString : expecting list of tuples containing each exactly 2 items : one string and one vector of string !"; + if(PyList_Check(pyLi)) + { + Py_ssize_t sz=PyList_Size(pyLi); + arr.resize(sz); + for(int i=0;i<sz;i++) + { + PyObject *o=PyList_GetItem(pyLi,i); + if(PyTuple_Check(o)) + { + int sz2=PyTuple_Size(o); + if(sz2!=2) + throw INTERP_KERNEL::Exception(msg); + std::pair<std::string, std::vector<std::string> > item; + PyObject *o_0=PyTuple_GetItem(o,0); + if(!PyString_Check(o_0)) + throw INTERP_KERNEL::Exception(msg); + item.first=PyString_AsString(o_0); + PyObject *o_1=PyTuple_GetItem(o,1); + if(!fillStringVector(o_1,item.second)) + throw INTERP_KERNEL::Exception(msg); + arr[i]=item; + } + else + throw INTERP_KERNEL::Exception(msg); + } + } + else if(PyTuple_Check(pyLi)) + { + Py_ssize_t sz=PyTuple_Size(pyLi); + arr.resize(sz); + for(int i=0;i<sz;i++) + { + PyObject *o=PyTuple_GetItem(pyLi,i); + if(PyTuple_Check(o)) + { + int sz2=PyTuple_Size(o); + if(sz2!=2) + throw INTERP_KERNEL::Exception(msg); + std::pair<std::string, std::vector<std::string> > item; + PyObject *o_0=PyTuple_GetItem(o,0); + if(!PyString_Check(o_0)) + throw INTERP_KERNEL::Exception(msg); + item.first=PyString_AsString(o_0); + PyObject *o_1=PyTuple_GetItem(o,1); + if(!fillStringVector(o_1,item.second)) + throw INTERP_KERNEL::Exception(msg); + arr[i]=item; + } + else + throw INTERP_KERNEL::Exception(msg); + } + } + else + throw INTERP_KERNEL::Exception(msg); +} + +static PyObject *convertDblArrToPyList(const double *ptr, int size) throw(INTERP_KERNEL::Exception) +{ + PyObject *ret=PyList_New(size); + for(int i=0;i<size;i++) + PyList_SetItem(ret,i,PyFloat_FromDouble(ptr[i])); + return ret; +} + +static PyObject *convertDblArrToPyList2(const std::vector<double>& v) throw(INTERP_KERNEL::Exception) +{ + int size=v.size(); + PyObject *ret=PyList_New(size); + for(int i=0;i<size;i++) + PyList_SetItem(ret,i,PyFloat_FromDouble(v[i])); + return ret; +} + +static PyObject *convertDblArrToPyListOfTuple(const double *vals, int nbOfComp, int nbOfTuples) throw(INTERP_KERNEL::Exception) +{ + PyObject *ret=PyList_New(nbOfTuples); + for(int i=0;i<nbOfTuples;i++) + { + PyObject *t=PyTuple_New(nbOfComp); + for(int j=0;j<nbOfComp;j++) + PyTuple_SetItem(t,j,PyFloat_FromDouble(vals[i*nbOfComp+j])); + PyList_SetItem(ret,i,t); + } + return ret; +} + +static PyObject *convertCharArrToPyListOfTuple(const char *vals, int nbOfComp, int nbOfTuples) throw(INTERP_KERNEL::Exception) +{ + PyObject *ret=PyList_New(nbOfTuples); + INTERP_KERNEL::AutoPtr<char> tmp=new char[nbOfComp+1]; tmp[nbOfComp]='\0'; + for(int i=0;i<nbOfTuples;i++) + { + std::copy(vals+i*nbOfComp,vals+(i+1)*nbOfComp,(char *)tmp); + PyList_SetItem(ret,i,PyString_FromString(tmp)); + } + return ret; +} + +static double *convertPyToNewDblArr2(PyObject *pyLi, int *size) throw(INTERP_KERNEL::Exception) +{ + if(PyList_Check(pyLi)) + { + *size=PyList_Size(pyLi); + double *tmp=(double *)malloc((*size)*sizeof(double)); + for(int i=0;i<*size;i++) + { + PyObject *o=PyList_GetItem(pyLi,i); + if(PyFloat_Check(o)) + { + double val=PyFloat_AS_DOUBLE(o); + tmp[i]=val; + } + else if(PyInt_Check(o)) + { + long val0=PyInt_AS_LONG(o); + double val=val0; + tmp[i]=val; + } + else + { + free(tmp); + throw INTERP_KERNEL::Exception("convertPyToNewDblArr2 : list must contain floats/integers only"); + } + } + return tmp; + } + else if(PyTuple_Check(pyLi)) + { + *size=PyTuple_Size(pyLi); + double *tmp=(double *)malloc((*size)*sizeof(double)); + for(int i=0;i<*size;i++) + { + PyObject *o=PyTuple_GetItem(pyLi,i); + if(PyFloat_Check(o)) + { + double val=PyFloat_AS_DOUBLE(o); + tmp[i]=val; + } + else if(PyInt_Check(o)) + { + long val0=PyInt_AS_LONG(o); + double val=val0; + tmp[i]=val; + } + else + { + free(tmp); + throw INTERP_KERNEL::Exception("convertPyToNewDblArr2 : tuple must contain floats/integers only"); + } + } + return tmp; + } + else + throw INTERP_KERNEL::Exception("convertPyToNewDblArr2 : not a list"); +} + +static void fillArrayWithPyListDbl3(PyObject *pyLi, int& nbOfElt, std::vector<double>& ret) +{ + static const char MSG[]="fillArrayWithPyListDbl3 : It appears that the input list or tuple is composed by elts having different sizes !"; + if(PyFloat_Check(pyLi)) + { + if(nbOfElt==-1) + nbOfElt=1; + else + if(nbOfElt!=1) + throw INTERP_KERNEL::Exception(MSG); + double val=PyFloat_AS_DOUBLE(pyLi); + ret.push_back(val); + } + else if(PyInt_Check(pyLi)) + { + long val0=PyInt_AS_LONG(pyLi); + double val=val0; + if(nbOfElt==-1) + nbOfElt=1; + else + if(nbOfElt!=1) + throw INTERP_KERNEL::Exception(MSG); + ret.push_back(val); + } + else if(PyList_Check(pyLi)) + { + int size=PyList_Size(pyLi); + int tmp=0; + for(int i=0;i<size;i++) + { + PyObject *o=PyList_GetItem(pyLi,i); + int tmp1=-1; + fillArrayWithPyListDbl3(o,tmp1,ret); + tmp+=tmp1; + } + if(nbOfElt==-1) + nbOfElt=tmp; + else + { + if(nbOfElt!=tmp) + throw INTERP_KERNEL::Exception(MSG); + } + } + else if(PyTuple_Check(pyLi)) + { + int size=PyTuple_Size(pyLi); + int tmp=0; + for(int i=0;i<size;i++) + { + PyObject *o=PyTuple_GetItem(pyLi,i); + int tmp1=-1; + fillArrayWithPyListDbl3(o,tmp1,ret); + tmp+=tmp1; + } + if(nbOfElt==-1) + nbOfElt=tmp; + else + { + if(nbOfElt!=tmp) + throw INTERP_KERNEL::Exception(MSG); + } + } + else + throw INTERP_KERNEL::Exception("fillArrayWithPyListDbl3 : Unrecognized type ! Should be a composition of tuple,list,int and float !"); +} + +static std::vector<double> fillArrayWithPyListDbl2(PyObject *pyLi, int& nbOfTuples, int& nbOfComp) throw(INTERP_KERNEL::Exception) +{ + std::vector<double> ret; + int size1=-1,size2=-1; + if(PyList_Check(pyLi)) + { + size1=PyList_Size(pyLi); + for(int i=0;i<size1;i++) + { + PyObject *o=PyList_GetItem(pyLi,i); + fillArrayWithPyListDbl3(o,size2,ret); + } + if(size1==0) + size2=1; + } + else if(PyTuple_Check(pyLi)) + { + size1=PyTuple_Size(pyLi); + for(int i=0;i<size1;i++) + { + PyObject *o=PyTuple_GetItem(pyLi,i); + fillArrayWithPyListDbl3(o,size2,ret); + } + if(size1==0) + size2=1; + } + else + throw INTERP_KERNEL::Exception("fillArrayWithPyListDbl2 : Unrecognized type ! Should be a tuple or a list !"); + // + checkFillArrayWithPyList(size1,size2,nbOfTuples,nbOfComp); + return ret; +} + +//convertFromPyObjVectorOfObj<const ParaMEDMEM::MEDCouplingUMesh *>(pyLi,SWIGTYPE_p_ParaMEDMEM__MEDCouplingUMesh,"MEDCouplingUMesh") +template<class T> +static void convertFromPyObjVectorOfObj(PyObject *pyLi, swig_type_info *ty, const char *typeStr, typename std::vector<T>& ret) +{ + void *argp=0; + if(PyList_Check(pyLi)) + { + int size=PyList_Size(pyLi); + ret.resize(size); + for(int i=0;i<size;i++) + { + PyObject *obj=PyList_GetItem(pyLi,i); + int status=SWIG_ConvertPtr(obj,&argp,ty,0|0); + if(!SWIG_IsOK(status)) + { + std::ostringstream oss; oss << "convertFromPyObjVectorOfObj : list is excepted to contain only " << typeStr << " instances !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + T arg=reinterpret_cast< T >(argp); + ret[i]=arg; + } + } + else if(PyTuple_Check(pyLi)) + { + int size=PyTuple_Size(pyLi); + ret.resize(size); + for(int i=0;i<size;i++) + { + PyObject *obj=PyTuple_GetItem(pyLi,i); + int status=SWIG_ConvertPtr(obj,&argp,ty,0|0); + if(!SWIG_IsOK(status)) + { + std::ostringstream oss; oss << "convertFromPyObjVectorOfObj : tuple is excepted to contain only " << typeStr << " instances !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + T arg=reinterpret_cast< T >(argp); + ret[i]=arg; + } + } + else if(SWIG_IsOK(SWIG_ConvertPtr(pyLi,&argp,ty,0|0))) + { + ret.resize(1); + T arg=reinterpret_cast< T >(argp); + ret[0]=arg; + } + else + throw INTERP_KERNEL::Exception("convertFromPyObjVectorOfObj : not a list nor a tuple"); +} + +/*! + * if python int -> cpp int sw=1 + * if python list[int] -> cpp vector<int> sw=2 + * if python tuple[int] -> cpp vector<int> sw=2 + * if python DataArrayInt -> cpp DataArrayInt sw=3 + * if python DataArrayIntTuple -> cpp DataArrayIntTuple sw=4 + * + * switch between (int,vector<int>,DataArrayInt) + */ +static void convertObjToPossibleCpp1(PyObject *value, int& sw, int& iTyypp, std::vector<int>& stdvecTyypp, ParaMEDMEM::DataArrayInt *& daIntTyypp, ParaMEDMEM::DataArrayIntTuple *&daIntTuple) throw(INTERP_KERNEL::Exception) +{ + sw=-1; + if(PyInt_Check(value)) + { + iTyypp=(int)PyInt_AS_LONG(value); + sw=1; + return; + } + if(PyTuple_Check(value)) + { + int size=PyTuple_Size(value); + stdvecTyypp.resize(size); + for(int i=0;i<size;i++) + { + PyObject *o=PyTuple_GetItem(value,i); + if(PyInt_Check(o)) + stdvecTyypp[i]=(int)PyInt_AS_LONG(o); + else + { + std::ostringstream oss; oss << "Tuple as been detected but element #" << i << " is not integer ! only tuples of integers accepted !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + } + sw=2; + return; + } + if(PyList_Check(value)) + { + int size=PyList_Size(value); + stdvecTyypp.resize(size); + for(int i=0;i<size;i++) + { + PyObject *o=PyList_GetItem(value,i); + if(PyInt_Check(o)) + stdvecTyypp[i]=(int)PyInt_AS_LONG(o); + else + { + std::ostringstream oss; oss << "List as been detected but element #" << i << " is not integer ! only lists of integers accepted !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + } + sw=2; + return; + } + void *argp; + int status=SWIG_ConvertPtr(value,&argp,SWIGTYPE_p_ParaMEDMEM__DataArrayInt,0|0); + if(SWIG_IsOK(status)) + { + daIntTyypp=reinterpret_cast< ParaMEDMEM::DataArrayInt * >(argp); + sw=3; + return; + } + status=SWIG_ConvertPtr(value,&argp,SWIGTYPE_p_ParaMEDMEM__DataArrayIntTuple,0|0); + if(SWIG_IsOK(status)) + { + daIntTuple=reinterpret_cast< ParaMEDMEM::DataArrayIntTuple * >(argp); + sw=4; + return ; + } + throw INTERP_KERNEL::Exception("5 types accepted : integer, tuple of integer, list of integer, DataArrayInt, DataArrayIntTuple"); +} + +/*! + * if python double -> cpp double sw=1 + * if python int -> cpp double sw=1 + * if python list[double] -> cpp vector<double> sw=2 + * if python list[int] -> cpp vector<double> sw=2 + * if python tuple[double] -> cpp vector<double> sw=2 + * if python tuple[int] -> cpp vector<double> sw=2 + * if python DataArrayDouble -> cpp DataArrayDouble sw=3 + * + * switch between (int,vector<int>,DataArrayInt) + */ +static void convertObjToPossibleCpp4(PyObject *value, int& sw, double& iTyypp, std::vector<double>& stdvecTyypp, ParaMEDMEM::DataArrayDouble *& daIntTyypp) throw(INTERP_KERNEL::Exception) +{ + sw=-1; + if(PyFloat_Check(value)) + { + iTyypp=PyFloat_AS_DOUBLE(value); + sw=1; + return; + } + if(PyInt_Check(value)) + { + iTyypp=(double)PyInt_AS_LONG(value); + sw=1; + return; + } + if(PyTuple_Check(value)) + { + int size=PyTuple_Size(value); + stdvecTyypp.resize(size); + for(int i=0;i<size;i++) + { + PyObject *o=PyTuple_GetItem(value,i); + if(PyFloat_Check(o)) + stdvecTyypp[i]=PyFloat_AS_DOUBLE(o); + else if(PyInt_Check(o)) + stdvecTyypp[i]=(double)PyInt_AS_LONG(o); + else + { + std::ostringstream oss; oss << "Tuple as been detected but element #" << i << " is not double ! only tuples of doubles accepted or integer !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + } + sw=2; + return; + } + if(PyList_Check(value)) + { + int size=PyList_Size(value); + stdvecTyypp.resize(size); + for(int i=0;i<size;i++) + { + PyObject *o=PyList_GetItem(value,i); + if(PyFloat_Check(o)) + stdvecTyypp[i]=PyFloat_AS_DOUBLE(o); + else if(PyInt_Check(o)) + stdvecTyypp[i]=(double)PyInt_AS_LONG(o); + else + { + std::ostringstream oss; oss << "List as been detected but element #" << i << " is not double ! only lists of doubles accepted or integer !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + } + sw=2; + return; + } + void *argp; + int status=SWIG_ConvertPtr(value,&argp,SWIGTYPE_p_ParaMEDMEM__DataArrayDouble,0|0); + if(!SWIG_IsOK(status)) + throw INTERP_KERNEL::Exception("5 types accepted : double float, integer, tuple of double float or int, list of double float or int, DataArrayDouble"); + daIntTyypp=reinterpret_cast< ParaMEDMEM::DataArrayDouble * >(argp); + sw=3; +} + +/*! + * if python double -> cpp double sw=1 + * if python int -> cpp double sw=1 + * if python list[double] -> cpp vector<double> sw=2 + * if python list[int] -> cpp vector<double> sw=2 + * if python tuple[double] -> cpp vector<double> sw=2 + * if python tuple[int] -> cpp vector<double> sw=2 + * if python DataArrayDoubleTuple -> cpp DataArrayDoubleTuple sw=3 + * + * switch between (int,vector<int>,DataArrayInt) + */ +static void convertObjToPossibleCpp44(PyObject *value, int& sw, double& iTyypp, std::vector<double>& stdvecTyypp, ParaMEDMEM::DataArrayDoubleTuple *& daIntTyypp) throw(INTERP_KERNEL::Exception) +{ + sw=-1; + if(PyFloat_Check(value)) + { + iTyypp=PyFloat_AS_DOUBLE(value); + sw=1; + return; + } + if(PyInt_Check(value)) + { + iTyypp=(double)PyInt_AS_LONG(value); + sw=1; + return; + } + if(PyTuple_Check(value)) + { + int size=PyTuple_Size(value); + stdvecTyypp.resize(size); + for(int i=0;i<size;i++) + { + PyObject *o=PyTuple_GetItem(value,i); + if(PyFloat_Check(o)) + stdvecTyypp[i]=PyFloat_AS_DOUBLE(o); + else if(PyInt_Check(o)) + stdvecTyypp[i]=(double)PyInt_AS_LONG(o); + else + { + std::ostringstream oss; oss << "Tuple as been detected but element #" << i << " is not double ! only tuples of doubles accepted or integer !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + } + sw=2; + return; + } + if(PyList_Check(value)) + { + int size=PyList_Size(value); + stdvecTyypp.resize(size); + for(int i=0;i<size;i++) + { + PyObject *o=PyList_GetItem(value,i); + if(PyFloat_Check(o)) + stdvecTyypp[i]=PyFloat_AS_DOUBLE(o); + else if(PyInt_Check(o)) + stdvecTyypp[i]=(double)PyInt_AS_LONG(o); + else + { + std::ostringstream oss; oss << "List as been detected but element #" << i << " is not double ! only lists of doubles accepted or integer !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + } + sw=2; + return; + } + void *argp; + int status=SWIG_ConvertPtr(value,&argp,SWIGTYPE_p_ParaMEDMEM__DataArrayDoubleTuple,0|0); + if(!SWIG_IsOK(status)) + throw INTERP_KERNEL::Exception("5 types accepted : double float, integer, tuple of double float or int, list of double float or int, DataArrayDoubleTuple"); + daIntTyypp=reinterpret_cast< ParaMEDMEM::DataArrayDoubleTuple * >(argp); + sw=3; +} + +/*! + * if python int -> cpp int sw=1 + * if python list[int] -> cpp vector<int> sw=2 + * if python tuple[int] -> cpp vector<int> sw=2 + * if python slicp -> cpp pair sw=3 (begin,end,step) + * if python DataArrayInt -> cpp DataArrayInt sw=4 . The returned pointer cannot be the null pointer ! If null an exception is thrown. + * + * switch between (int,vector<int>,DataArrayInt) + */ +static void convertObjToPossibleCpp2(PyObject *value, int nbelem, int& sw, int& iTyypp, std::vector<int>& stdvecTyypp, std::pair<int, std::pair<int,int> >& p, ParaMEDMEM::DataArrayInt *& daIntTyypp) throw(INTERP_KERNEL::Exception) +{ + const char *msg="5 types accepted : integer, tuple of integer, list of integer, slice, DataArrayInt, DataArrayIntTuple"; + sw=-1; + if(PyInt_Check(value)) + { + iTyypp=(int)PyInt_AS_LONG(value); + sw=1; + return; + } + if(PyTuple_Check(value)) + { + int size=PyTuple_Size(value); + stdvecTyypp.resize(size); + for(int i=0;i<size;i++) + { + PyObject *o=PyTuple_GetItem(value,i); + if(PyInt_Check(o)) + stdvecTyypp[i]=(int)PyInt_AS_LONG(o); + else + { + std::ostringstream oss; oss << "Tuple as been detected but element #" << i << " is not integer ! only tuples of integers accepted !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + } + sw=2; + return; + } + if(PyList_Check(value)) + { + int size=PyList_Size(value); + stdvecTyypp.resize(size); + for(int i=0;i<size;i++) + { + PyObject *o=PyList_GetItem(value,i); + if(PyInt_Check(o)) + stdvecTyypp[i]=(int)PyInt_AS_LONG(o); + else + { + std::ostringstream oss; oss << "List as been detected but element #" << i << " is not integer ! only lists of integers accepted !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + } + sw=2; + return; + } + if(PySlice_Check(value)) + { + Py_ssize_t strt=2,stp=2,step=2; + PySliceObject *oC=reinterpret_cast<PySliceObject *>(value); + GetIndicesOfSlice(oC,nbelem,&strt,&stp,&step,"Slice in subscriptable object DataArray invalid !"); + p.first=strt; + p.second.first=stp; + p.second.second=step; + sw=3; + return ; + } + void *argp; + int status=SWIG_ConvertPtr(value,&argp,SWIGTYPE_p_ParaMEDMEM__DataArrayInt,0|0); + if(SWIG_IsOK(status)) + { + daIntTyypp=reinterpret_cast< ParaMEDMEM::DataArrayInt * >(argp); + if(!daIntTyypp) + { + std::ostringstream oss; oss << msg << " Instance in null !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + sw=4; + return ; + } + status=SWIG_ConvertPtr(value,&argp,SWIGTYPE_p_ParaMEDMEM__DataArrayIntTuple,0|0); + if(SWIG_IsOK(status)) + { + ParaMEDMEM::DataArrayIntTuple *tmp=reinterpret_cast< ParaMEDMEM::DataArrayIntTuple * >(argp); + if(!tmp) + { + std::ostringstream oss; oss << msg << " Instance in null !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + stdvecTyypp.resize(tmp->getNumberOfCompo()); + std::copy(tmp->getConstPointer(),tmp->getConstPointer()+tmp->getNumberOfCompo(),stdvecTyypp.begin()); + sw=2; + return ; + } + throw INTERP_KERNEL::Exception(msg); +} + +/*! + * Idem than convertObjToPossibleCpp2 + */ +static void convertObjToPossibleCpp2WithNegIntInterp(PyObject *value, int nbelem, int& sw, int& iTyypp, std::vector<int>& stdvecTyypp, std::pair<int, std::pair<int,int> >& p, ParaMEDMEM::DataArrayInt *& daIntTyypp) throw(INTERP_KERNEL::Exception) +{ + convertObjToPossibleCpp2(value,nbelem,sw,iTyypp,stdvecTyypp,p,daIntTyypp); + if(sw==1) + { + iTyypp=InterpreteNegativeInt(iTyypp,nbelem); + } +} + +/*! + * if python int -> cpp int sw=1 + * if python tuple[int] -> cpp vector<int> sw=2 + * if python list[int] -> cpp vector<int> sw=2 + * if python slice -> cpp pair sw=3 + * if python DataArrayIntTuple -> cpp DataArrayIntTuple sw=4 . WARNING The returned pointer can be the null pointer ! + */ +static void convertObjToPossibleCpp22(PyObject *value, int nbelem, int& sw, int& iTyypp, std::vector<int>& stdvecTyypp, std::pair<int, std::pair<int,int> >& p, ParaMEDMEM::DataArrayIntTuple *& daIntTyypp) throw(INTERP_KERNEL::Exception) +{ + sw=-1; + if(PyInt_Check(value)) + { + iTyypp=(int)PyInt_AS_LONG(value); + sw=1; + return; + } + if(PyTuple_Check(value)) + { + int size=PyTuple_Size(value); + stdvecTyypp.resize(size); + for(int i=0;i<size;i++) + { + PyObject *o=PyTuple_GetItem(value,i); + if(PyInt_Check(o)) + stdvecTyypp[i]=(int)PyInt_AS_LONG(o); + else + { + std::ostringstream oss; oss << "Tuple as been detected but element #" << i << " is not integer ! only tuples of integers accepted !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + } + sw=2; + return; + } + if(PyList_Check(value)) + { + int size=PyList_Size(value); + stdvecTyypp.resize(size); + for(int i=0;i<size;i++) + { + PyObject *o=PyList_GetItem(value,i); + if(PyInt_Check(o)) + stdvecTyypp[i]=(int)PyInt_AS_LONG(o); + else + { + std::ostringstream oss; oss << "List as been detected but element #" << i << " is not integer ! only lists of integers accepted !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + } + sw=2; + return; + } + if(PySlice_Check(value)) + { + Py_ssize_t strt=2,stp=2,step=2; + PySliceObject *oC=reinterpret_cast<PySliceObject *>(value); + GetIndicesOfSlice(oC,nbelem,&strt,&stp,&step,"Slice in subscriptable object DataArray invalid !"); + p.first=strt; + p.second.first=stp; + p.second.second=step; + sw=3; + return ; + } + void *argp; + int status=SWIG_ConvertPtr(value,&argp,SWIGTYPE_p_ParaMEDMEM__DataArrayIntTuple,0|0); + if(!SWIG_IsOK(status)) + throw INTERP_KERNEL::Exception("4 types accepted : integer, tuple of integer, list of integer, slice, DataArrayIntTuple"); + daIntTyypp=reinterpret_cast< ParaMEDMEM::DataArrayIntTuple * >(argp); + sw=4; +} + +/*! + * if python string with size one -> cpp char sw=1 + * if python string with size different from one -> cpp string sw=2 + * if python tuple[string] or list[string] -> vector<string> sw=3 + * if python not null pointer of DataArrayChar -> cpp DataArrayChar sw=4 + * switch between (int,string,vector<string>,DataArrayChar) + */ +static void convertObjToPossibleCpp6(PyObject *value, int& sw, char& cTyp, std::string& sType, std::vector<std::string>& vsType, ParaMEDMEM::DataArrayChar *& dacType) throw(INTERP_KERNEL::Exception) +{ + const char *msg="4 types accepted : string, list or tuple of strings having same size, not null DataArrayChar instance."; + sw=-1; + if(PyString_Check(value)) + { + const char *pt=PyString_AsString(value); + Py_ssize_t sz=PyString_Size(value); + if(sz==1) + { + cTyp=pt[0]; + sw=1; + return; + } + else + { + sType=pt; + sw=2; + return; + } + } + if(PyTuple_Check(value)) + { + int size=PyTuple_Size(value); + vsType.resize(size); + for(int i=0;i<size;i++) + { + PyObject *o=PyTuple_GetItem(value,i); + if(PyString_Check(o)) + vsType[i]=PyString_AsString(o); + else + { + std::ostringstream oss; oss << "Tuple as been detected but element #" << i << " is not a string ! only tuples of strings accepted !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + } + sw=3; + return; + } + if(PyList_Check(value)) + { + int size=PyList_Size(value); + vsType.resize(size); + for(int i=0;i<size;i++) + { + PyObject *o=PyList_GetItem(value,i); + if(PyString_Check(o)) + vsType[i]=PyString_AsString(o); + else + { + std::ostringstream oss; oss << "List as been detected but element #" << i << " is not string ! only lists of strings accepted !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + } + sw=3; + return; + } + void *argp; + int status=SWIG_ConvertPtr(value,&argp,SWIGTYPE_p_ParaMEDMEM__DataArrayChar,0|0); + if(SWIG_IsOK(status)) + { + dacType=reinterpret_cast< ParaMEDMEM::DataArrayChar * >(argp); + if(!dacType) + { + std::ostringstream oss; oss << msg << " Instance in null !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + sw=4; + return ; + } + throw INTERP_KERNEL::Exception(msg); +} + +/*! + * if value int -> cpp it sw=1 + * if value list[int] -> vt sw=2 + * if value tuple[int] -> vt sw=2 + * if value slice -> pt sw=3 + * if value DataArrayInt -> dt sw=4 + * if value tuple [int,int] -> cpp it,ip sw=5 + * if value tuple [list[int],int] -> cpp vt,ip sw=6 + * if value tuple [tuple[int],int] -> cpp vt,ip sw=6 + * if value tuple [slice,int] -> cpp pt,ip sw=7 + * if value tuple [DaI,int] -> cpp dt,ip sw=8 + * if value tuple [int,list[int]] -> cpp it,vc sw=9 + * if value tuple [list[int],list[int]] -> cpp vt,vc sw=10 + * if value tuple [tuple[int],list[int]] -> cpp vt,vc sw=10 + * if value tuple [slice,list[int]] -> cpp pt,vc sw=11 + * if value tuple [DaI,list[int]] -> cpp dt,vc sw=12 + * if value tuple [int,tuple[int]] -> cpp it,vc sw=9 + * if value tuple [list[int],tuple[int]] -> cpp vt,vc sw=10 + * if value tuple [tuple[int],tuple[int]] -> cpp vt,vc sw=10 + * if value tuple [slice,tuple[int]] -> cpp pt,vc sw=11 + * if value tuple [DaI,tuple[int]] -> cpp dt,vc sw=12 + * if value tuple [int,slice] -> cpp it,pc sw=13 + * if value tuple [list[int],slice] -> cpp vt,pc sw=14 + * if value tuple [tuple[int],slice] -> cpp vt,pc sw=14 + * if value tuple [slice,slice] -> cpp pt,pc sw=15 + * if value tuple [DaI,slice] -> cpp dt,pc sw=16 + * + * switch between (int,vector<int>,DataArrayInt) + */ +static void convertObjToPossibleCpp3(PyObject *value, int nbTuple, int nbCompo, int& sw, int& it, int& ic, std::vector<int>& vt, std::vector<int>& vc, + std::pair<int, std::pair<int,int> >& pt, std::pair<int, std::pair<int,int> >& pc, + ParaMEDMEM::DataArrayInt *&dt, ParaMEDMEM::DataArrayInt *&dc) throw(INTERP_KERNEL::Exception) +{ + if(!PyTuple_Check(value)) + { + convertObjToPossibleCpp2WithNegIntInterp(value,nbTuple,sw,it,vt,pt,dt); + return ; + } + else + { + int sz=PyTuple_Size(value); + if(sz!=2) + throw INTERP_KERNEL::Exception("Unexpected nb of slice element : 1 or 2 expected !\n1st is for tuple selection, 2nd for component selection !"); + PyObject *ob0=PyTuple_GetItem(value,0); + int sw1,sw2; + convertObjToPossibleCpp2WithNegIntInterp(ob0,nbTuple,sw1,it,vt,pt,dt); + PyObject *ob1=PyTuple_GetItem(value,1); + convertObjToPossibleCpp2WithNegIntInterp(ob1,nbCompo,sw2,ic,vc,pc,dc); + sw=4*sw2+sw1; + } +} + +/*! + * if value int -> cpp val sw=1 + * if value double -> cpp val sw=1 + * if value DataArrayDouble -> cpp DataArrayDouble sw=2 + * if value DataArrayDoubleTuple -> cpp DataArrayDoubleTuple sw=3 + * if value list[int,double] -> cpp std::vector<double> sw=4 + * if value tuple[int,double] -> cpp std::vector<double> sw=4 + */ +static void convertObjToPossibleCpp5(PyObject *value, int& sw, double& val, ParaMEDMEM::DataArrayDouble *&d, ParaMEDMEM::DataArrayDoubleTuple *&e, std::vector<double>& f) +{ + sw=-1; + if(PyFloat_Check(value)) + { + val=PyFloat_AS_DOUBLE(value); + sw=1; + return; + } + if(PyInt_Check(value)) + { + val=(double)PyInt_AS_LONG(value); + sw=1; + return; + } + if(PyTuple_Check(value)) + { + int size=PyTuple_Size(value); + f.resize(size); + for(int i=0;i<size;i++) + { + PyObject *o=PyTuple_GetItem(value,i); + if(PyFloat_Check(o)) + f[i]=PyFloat_AS_DOUBLE(o); + else if(PyInt_Check(o)) + f[i]=(double)PyInt_AS_LONG(o); + else + { + std::ostringstream oss; oss << "Tuple as been detected but element #" << i << " is not double ! only tuples of doubles accepted or integer !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + } + sw=4; + return; + } + if(PyList_Check(value)) + { + int size=PyList_Size(value); + f.resize(size); + for(int i=0;i<size;i++) + { + PyObject *o=PyList_GetItem(value,i); + if(PyFloat_Check(o)) + f[i]=PyFloat_AS_DOUBLE(o); + else if(PyInt_Check(o)) + f[i]=(double)PyInt_AS_LONG(o); + else + { + std::ostringstream oss; oss << "List as been detected but element #" << i << " is not double ! only lists of doubles accepted or integer !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + } + sw=4; + return; + } + void *argp; + int status=SWIG_ConvertPtr(value,&argp,SWIGTYPE_p_ParaMEDMEM__DataArrayDouble,0|0); + if(SWIG_IsOK(status)) + { + d=reinterpret_cast< ParaMEDMEM::DataArrayDouble * >(argp); + sw=2; + return ; + } + status=SWIG_ConvertPtr(value,&argp,SWIGTYPE_p_ParaMEDMEM__DataArrayDoubleTuple,0|0); + if(SWIG_IsOK(status)) + { + e=reinterpret_cast< ParaMEDMEM::DataArrayDoubleTuple * >(argp); + sw=3; + return ; + } + throw INTERP_KERNEL::Exception("4 types accepted : integer, double, DataArrayDouble, DataArrayDoubleTuple"); +} + +/*! + * if value int -> cpp val sw=1 + * if value double -> cpp val sw=1 + * if value DataArrayDouble -> cpp DataArrayDouble sw=2 + * if value DataArrayDoubleTuple -> cpp DataArrayDoubleTuple sw=3 + * if value list[int,double] -> cpp std::vector<double> sw=4 + * if value tuple[int,double] -> cpp std::vector<double> sw=4 + */ +static const double *convertObjToPossibleCpp5_Safe(PyObject *value, int& sw, double& val, ParaMEDMEM::DataArrayDouble *&d, ParaMEDMEM::DataArrayDoubleTuple *&e, std::vector<double>& f, + const char *msg, int nbTuplesExpected, int nbCompExpected, bool throwIfNullPt) throw(INTERP_KERNEL::Exception) +{ + sw=-1; + if(PyFloat_Check(value)) + { + val=PyFloat_AS_DOUBLE(value); + sw=1; + if(nbTuplesExpected*nbCompExpected!=1) + { + std::ostringstream oss; oss << msg << "dimension expected to be " << nbTuplesExpected*nbCompExpected << " , and your data in input has dimension one (single PyFloat) !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + return &val; + } + if(PyInt_Check(value)) + { + val=(double)PyInt_AS_LONG(value); + sw=1; + if(nbTuplesExpected*nbCompExpected!=1) + { + std::ostringstream oss; oss << msg << "dimension expected to be " << nbTuplesExpected*nbCompExpected << " , and your data in input has dimension one (single PyInt) !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + return &val; + } + if(PyTuple_Check(value) || PyList_Check(value)) + { + try + { + int tmp1=nbTuplesExpected,tmp2=nbCompExpected; + std::vector<double> ret=fillArrayWithPyListDbl2(value,tmp1,tmp2); + sw=4; + f=ret; + return &f[0]; + } + catch(INTERP_KERNEL::Exception& exc) { throw exc; } + } + void *argp; + int status=SWIG_ConvertPtr(value,&argp,SWIGTYPE_p_ParaMEDMEM__DataArrayDouble,0|0); + if(SWIG_IsOK(status)) + { + d=reinterpret_cast< ParaMEDMEM::DataArrayDouble * >(argp); + sw=2; + if(d) + { + if(d->getNumberOfTuples()==nbTuplesExpected) + { + if(d->getNumberOfComponents()==nbCompExpected) + { + return d->getConstPointer(); + } + else + { + std::ostringstream oss; oss << msg << "nb of components expected to be " << nbCompExpected << " , and input has " << d->getNumberOfComponents() << " components !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + } + else + { + std::ostringstream oss; oss << msg << " input DataArrayDouble should have a number of tuples equal to " << nbTuplesExpected << " and there are " << d->getNumberOfTuples() << " tuples !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + } + else + { + if(throwIfNullPt) + { + std::ostringstream oss; oss << msg << " null pointer not accepted!"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + else + return 0; + } + } + status=SWIG_ConvertPtr(value,&argp,SWIGTYPE_p_ParaMEDMEM__DataArrayDoubleTuple,0|0); + if(SWIG_IsOK(status)) + { + e=reinterpret_cast< ParaMEDMEM::DataArrayDoubleTuple * >(argp); + sw=3; + if(e->getNumberOfCompo()==nbCompExpected) + { + if(nbTuplesExpected==1) + return e->getConstPointer(); + else + { + std::ostringstream oss; oss << msg << "nb of tuples expected to be " << nbTuplesExpected << " , and input DataArrayDoubleTuple has always one tuple by contruction !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + } + else + { + std::ostringstream oss; oss << msg << "nb of components expected to be " << nbCompExpected << " , and input DataArrayDoubleTuple has " << e->getNumberOfCompo() << " components !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + } + throw INTERP_KERNEL::Exception("4 types accepted : integer, double, DataArrayDouble, DataArrayDoubleTuple"); +} + +/*! + * if value int -> cpp val sw=1 + * if value double -> cpp val sw=1 + * if value DataArrayDouble -> cpp DataArrayDouble sw=2 + * if value DataArrayDoubleTuple -> cpp DataArrayDoubleTuple sw=3 + * if value list[int,double] -> cpp std::vector<double> sw=4 + * if value tuple[int,double] -> cpp std::vector<double> sw=4 + */ +static const double *convertObjToPossibleCpp5_Safe2(PyObject *value, int& sw, double& val, ParaMEDMEM::DataArrayDouble *&d, ParaMEDMEM::DataArrayDoubleTuple *&e, std::vector<double>& f, + const char *msg, int nbCompExpected, bool throwIfNullPt, int& nbTuples) throw(INTERP_KERNEL::Exception) +{ + sw=-1; + if(PyFloat_Check(value)) + { + val=PyFloat_AS_DOUBLE(value); + sw=1; + if(nbCompExpected!=1) + { + std::ostringstream oss; oss << msg << "dimension expected to be " << nbCompExpected << " , and your data in input has dimension one (single PyFloat) !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + nbTuples=1; + return &val; + } + if(PyInt_Check(value)) + { + val=(double)PyInt_AS_LONG(value); + sw=1; + if(nbCompExpected!=1) + { + std::ostringstream oss; oss << msg << "dimension expected to be " << nbCompExpected << " , and your data in input has dimension one (single PyInt) !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + nbTuples=1; + return &val; + } + if(PyTuple_Check(value)) + { + int size=PyTuple_Size(value); + f.resize(size); + for(int i=0;i<size;i++) + { + PyObject *o=PyTuple_GetItem(value,i); + if(PyFloat_Check(o)) + f[i]=PyFloat_AS_DOUBLE(o); + else if(PyInt_Check(o)) + f[i]=(double)PyInt_AS_LONG(o); + else + { + std::ostringstream oss; oss << "Tuple as been detected but element #" << i << " is not double ! only tuples of doubles accepted or integer !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + } + sw=4; + if(size%nbCompExpected!=0) + { + std::ostringstream oss; oss << msg << "dimension expected to be a multiple of " << nbCompExpected << " , and your data in input has dimension " << f.size() << " !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + nbTuples=size/nbCompExpected; + return &f[0]; + } + if(PyList_Check(value)) + { + int size=PyList_Size(value); + f.resize(size); + for(int i=0;i<size;i++) + { + PyObject *o=PyList_GetItem(value,i); + if(PyFloat_Check(o)) + f[i]=PyFloat_AS_DOUBLE(o); + else if(PyInt_Check(o)) + f[i]=(double)PyInt_AS_LONG(o); + else + { + std::ostringstream oss; oss << "List as been detected but element #" << i << " is not double ! only lists of doubles accepted or integer !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + } + sw=4; + if(size%nbCompExpected!=0) + { + std::ostringstream oss; oss << msg << "dimension expected to be a multiple of " << nbCompExpected << " , and your data in input has dimension " << f.size() << " !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + nbTuples=size/nbCompExpected; + return &f[0]; + } + void *argp; + int status=SWIG_ConvertPtr(value,&argp,SWIGTYPE_p_ParaMEDMEM__DataArrayDouble,0|0); + if(SWIG_IsOK(status)) + { + d=reinterpret_cast< ParaMEDMEM::DataArrayDouble * >(argp); + sw=2; + if(d) + { + if(d->getNumberOfComponents()==nbCompExpected) + { + nbTuples=d->getNumberOfTuples(); + return d->getConstPointer(); + } + else + { + std::ostringstream oss; oss << msg << "nb of components expected to be a multiple of " << nbCompExpected << " , and input has " << d->getNumberOfComponents() << " components !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + } + else + { + if(throwIfNullPt) + { + std::ostringstream oss; oss << msg << " null pointer not accepted!"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + else + { nbTuples=0; return 0; } + } + } + status=SWIG_ConvertPtr(value,&argp,SWIGTYPE_p_ParaMEDMEM__DataArrayDoubleTuple,0|0); + if(SWIG_IsOK(status)) + { + e=reinterpret_cast< ParaMEDMEM::DataArrayDoubleTuple * >(argp); + sw=3; + if(e) + { + if(e->getNumberOfCompo()==nbCompExpected) + { + nbTuples=1; + return e->getConstPointer(); + } + else + { + std::ostringstream oss; oss << msg << "nb of components expected to be " << nbCompExpected << " , and input DataArrayDoubleTuple has " << e->getNumberOfCompo() << " components !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + } + else + { + if(throwIfNullPt) + { + std::ostringstream oss; oss << msg << " null pointer not accepted!"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + else + { nbTuples=0; return 0; } + } + } + throw INTERP_KERNEL::Exception("4 types accepted : integer, double, DataArrayDouble, DataArrayDoubleTuple"); +} + +/*! + * if value int -> cpp val sw=1 + * if value double -> cpp val sw=1 + * if value DataArrayDouble -> cpp DataArrayDouble sw=2 + * if value DataArrayDoubleTuple -> cpp DataArrayDoubleTuple sw=3 + * if value list[int,double] -> cpp std::vector<double> sw=4 + * if value tuple[int,double] -> cpp std::vector<double> sw=4 + */ +static const double *convertObjToPossibleCpp5_SingleCompo(PyObject *value, int& sw, double& val, std::vector<double>& f, + const char *msg, bool throwIfNullPt, int& nbTuples) throw(INTERP_KERNEL::Exception) +{ + ParaMEDMEM::DataArrayDouble *d=0; + ParaMEDMEM::DataArrayDoubleTuple *e=0; + sw=-1; + if(PyFloat_Check(value)) + { + val=PyFloat_AS_DOUBLE(value); + sw=1; + nbTuples=1; + return &val; + } + if(PyInt_Check(value)) + { + val=(double)PyInt_AS_LONG(value); + sw=1; + nbTuples=1; + return &val; + } + if(PyTuple_Check(value)) + { + int size=PyTuple_Size(value); + f.resize(size); + for(int i=0;i<size;i++) + { + PyObject *o=PyTuple_GetItem(value,i); + if(PyFloat_Check(o)) + f[i]=PyFloat_AS_DOUBLE(o); + else if(PyInt_Check(o)) + f[i]=(double)PyInt_AS_LONG(o); + else + { + std::ostringstream oss; oss << "Tuple as been detected but element #" << i << " is not double ! only tuples of doubles accepted or integer !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + } + sw=4; + nbTuples=size; + return &f[0]; + } + if(PyList_Check(value)) + { + int size=PyList_Size(value); + f.resize(size); + for(int i=0;i<size;i++) + { + PyObject *o=PyList_GetItem(value,i); + if(PyFloat_Check(o)) + f[i]=PyFloat_AS_DOUBLE(o); + else if(PyInt_Check(o)) + f[i]=(double)PyInt_AS_LONG(o); + else + { + std::ostringstream oss; oss << "List as been detected but element #" << i << " is not double ! only lists of doubles accepted or integer !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + } + sw=4; + nbTuples=size; + return &f[0]; + } + void *argp; + int status=SWIG_ConvertPtr(value,&argp,SWIGTYPE_p_ParaMEDMEM__DataArrayDouble,0|0); + if(SWIG_IsOK(status)) + { + d=reinterpret_cast< ParaMEDMEM::DataArrayDouble * >(argp); + sw=2; + if(d) + { + if(d->getNumberOfComponents()==1) + { + nbTuples=d->getNumberOfTuples(); + return d->getConstPointer(); + } + else + { + std::ostringstream oss; oss << msg << "nb of components expected to be one, and input has " << d->getNumberOfComponents() << " components !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + } + else + { + if(throwIfNullPt) + { + std::ostringstream oss; oss << msg << " null pointer not accepted!"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + else + { nbTuples=0; return 0; } + } + } + status=SWIG_ConvertPtr(value,&argp,SWIGTYPE_p_ParaMEDMEM__DataArrayDoubleTuple,0|0); + if(SWIG_IsOK(status)) + { + e=reinterpret_cast< ParaMEDMEM::DataArrayDoubleTuple * >(argp); + sw=3; + if(e) + { + nbTuples=e->getNumberOfCompo(); + return e->getConstPointer(); + } + else + { + if(throwIfNullPt) + { + std::ostringstream oss; oss << msg << " null pointer not accepted!"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + else + { nbTuples=0; return 0; } + } + } + throw INTERP_KERNEL::Exception("4 types accepted : integer, double, DataArrayDouble, DataArrayDoubleTuple"); +} + +/*! + * if python int -> cpp int sw=1 + * if python list[int] -> cpp vector<int> sw=2 + * if python tuple[int] -> cpp vector<int> sw=2 + * if python DataArrayInt -> cpp DataArrayInt sw=3 + * if python DataArrayIntTuple -> cpp DataArrayIntTuple sw=4 + * + * switch between (int,vector<int>,DataArrayInt) + */ +static const int *convertObjToPossibleCpp1_Safe(PyObject *value, int& sw, int& sz, int& iTyypp, std::vector<int>& stdvecTyypp) throw(INTERP_KERNEL::Exception) +{ + sw=-1; + if(PyInt_Check(value)) + { + iTyypp=(int)PyInt_AS_LONG(value); + sw=1; sz=1; + return &iTyypp; + } + if(PyTuple_Check(value)) + { + int size=PyTuple_Size(value); + stdvecTyypp.resize(size); + for(int i=0;i<size;i++) + { + PyObject *o=PyTuple_GetItem(value,i); + if(PyInt_Check(o)) + stdvecTyypp[i]=(int)PyInt_AS_LONG(o); + else + { + std::ostringstream oss; oss << "Tuple as been detected but element #" << i << " is not integer ! only tuples of integers accepted !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + } + sw=2; sz=size; + return &stdvecTyypp[0]; + } + if(PyList_Check(value)) + { + int size=PyList_Size(value); + stdvecTyypp.resize(size); + for(int i=0;i<size;i++) + { + PyObject *o=PyList_GetItem(value,i); + if(PyInt_Check(o)) + stdvecTyypp[i]=(int)PyInt_AS_LONG(o); + else + { + std::ostringstream oss; oss << "List as been detected but element #" << i << " is not integer ! only lists of integers accepted !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + } + sw=2; sz=size; + return &stdvecTyypp[0]; + } + void *argp; + int status=SWIG_ConvertPtr(value,&argp,SWIGTYPE_p_ParaMEDMEM__DataArrayInt,0|0); + if(SWIG_IsOK(status)) + { + ParaMEDMEM::DataArrayInt *daIntTyypp=reinterpret_cast< ParaMEDMEM::DataArrayInt * >(argp); + if(daIntTyypp) + { + sw=3; sz=daIntTyypp->getNbOfElems(); + return daIntTyypp->begin(); + } + else + { + sz=0; + return 0; + } + } + status=SWIG_ConvertPtr(value,&argp,SWIGTYPE_p_ParaMEDMEM__DataArrayIntTuple,0|0); + if(SWIG_IsOK(status)) + { + ParaMEDMEM::DataArrayIntTuple *daIntTuple=reinterpret_cast< ParaMEDMEM::DataArrayIntTuple * >(argp); + sw=4; sz=daIntTuple->getNumberOfCompo(); + return daIntTuple->getConstPointer(); + } + throw INTERP_KERNEL::Exception("5 types accepted : integer, tuple of integer, list of integer, DataArrayInt, DataArrayIntTuple"); +} + +static ParaMEDMEM::DataArray *CheckAndRetrieveDataArrayInstance(PyObject *obj, const char *msg) +{ + void *aBasePtrVS=0; + int status=SWIG_ConvertPtr(obj,&aBasePtrVS,SWIGTYPE_p_ParaMEDMEM__DataArray,0|0); + if(!SWIG_IsOK(status)) + { + status=SWIG_ConvertPtr(obj,&aBasePtrVS,SWIGTYPE_p_ParaMEDMEM__DataArrayDouble,0|0); + if(!SWIG_IsOK(status)) + { + status=SWIG_ConvertPtr(obj,&aBasePtrVS,SWIGTYPE_p_ParaMEDMEM__DataArrayInt,0|0); + if(!SWIG_IsOK(status)) + { + status=SWIG_ConvertPtr(obj,&aBasePtrVS,SWIGTYPE_p_ParaMEDMEM__DataArrayAsciiChar,0|0); + if(!SWIG_IsOK(status)) + { + status=SWIG_ConvertPtr(obj,&aBasePtrVS,SWIGTYPE_p_ParaMEDMEM__DataArrayByte,0|0); + std::ostringstream oss; oss << msg << " ! Accepted instances are DataArrayDouble, DataArrayInt, DataArrayAsciiChar, DataArrayByte !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + } + } + } + return reinterpret_cast< ParaMEDMEM::DataArray * >(aBasePtrVS); +} diff --git a/src/medtool/src/MEDCoupling_Swig/MEDCouplingDataForTest.py b/src/medtool/src/MEDCoupling_Swig/MEDCouplingDataForTest.py new file mode 100644 index 000000000..f88aad244 --- /dev/null +++ b/src/medtool/src/MEDCoupling_Swig/MEDCouplingDataForTest.py @@ -0,0 +1,756 @@ +# -*- coding: iso-8859-1 -*- +# Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 +# 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 +# + +from MEDCoupling import * + +class MEDCouplingDataForTest: + def build2DTargetMesh_1(cls): + targetCoords=[-0.3,-0.3, 0.2,-0.3, 0.7,-0.3, -0.3,0.2, 0.2,0.2, 0.7,0.2, -0.3,0.7, 0.2,0.7, 0.7,0.7 ]; + targetConn=[0,3,4,1, 1,4,2, 4,5,2, 6,7,4,3, 7,8,5,4]; + targetMesh=MEDCouplingUMesh.New(); + targetMesh.setMeshDimension(2); + targetMesh.allocateCells(5); + targetMesh.insertNextCell(NORM_QUAD4,4,targetConn[0:4]); + targetMesh.insertNextCell(NORM_TRI3,3,targetConn[4:7]); + targetMesh.insertNextCell(NORM_TRI3,3,targetConn[7:10]); + targetMesh.insertNextCell(NORM_QUAD4,4,targetConn[10:14]); + targetMesh.insertNextCell(NORM_QUAD4,4,targetConn[14:18]); + targetMesh.finishInsertingCells(); + myCoords=DataArrayDouble.New(); + myCoords.setValues(targetCoords,9,2); + targetMesh.setCoords(myCoords); + return targetMesh; + + def build2DSourceMesh_1(cls): + sourceCoords=[-0.3,-0.3, 0.7,-0.3, -0.3,0.7, 0.7,0.7] + sourceConn=[0,3,1,0,2,3] + sourceMesh=MEDCouplingUMesh.New("my name of mesh 2D",2); + sourceMesh.allocateCells(2); + sourceMesh.insertNextCell(NORM_TRI3,3,sourceConn[0:3]); + sourceMesh.insertNextCell(NORM_TRI3,3,sourceConn[3:6]); + sourceMesh.finishInsertingCells(); + myCoords=DataArrayDouble.New(); + myCoords.setValues(sourceCoords,4,2); + sourceMesh.setCoords(myCoords); + return sourceMesh; + + def build3DTargetMesh_1(cls): + targetCoords=[ 0., 0., 0., 50., 0., 0. , 200., 0., 0. , 0., 50., 0., 50., 50., 0. , 200., 50., 0., 0., 200., 0., 50., 200., 0. , 200., 200., 0. , + 0., 0., 50., 50., 0., 50. , 200., 0., 50. , 0., 50., 50., 50., 50., 50. , 200., 50., 50., 0., 200., 50., 50., 200., 50. , 200., 200., 50. , + 0., 0., 200., 50., 0., 200. , 200., 0., 200. , 0., 50., 200., 50., 50., 200. , 200., 50., 200., 0., 200., 200., 50., 200., 200. , 200., 200., 200. ]; + targetConn=[0,1,4,3,9,10,13,12, 1,2,5,4,10,11,14,13, 3,4,7,6,12,13,16,15, 4,5,8,7,13,14,17,16, + 9,10,13,12,18,19,22,21, 10,11,14,13,19,20,23,22, 12,13,16,15,21,22,25,24, 13,14,17,16,22,23,26,25]; + targetMesh=MEDCouplingUMesh.New(); + targetMesh.setMeshDimension(3); + targetMesh.allocateCells(12); + for i in xrange(8): + targetMesh.insertNextCell(NORM_HEXA8,8,targetConn[8*i:8*i+8]); + pass + targetMesh.finishInsertingCells(); + myCoords=DataArrayDouble.New(); + myCoords.setValues(targetCoords,27,3); + targetMesh.setCoords(myCoords); + return targetMesh + + def build3DSourceMesh_1(self): + sourceCoords=[ 0.0, 0.0, 200.0, 0.0, 0.0, 0.0, 0.0, 200.0, 200.0, 0.0, 200.0, 0.0, 200.0, 0.0, 200.0, + 200.0, 0.0, 0.0, 200.0, 200.0, 200.0, 200.0, 200.0, 0.0, 100.0, 100.0, 100.0] + sourceConn=[8,1,7,3, 6,0,8,2, 7,4,5,8, 6,8,4,7, 6,8,0,4, 6,8,7,3, 8,1,3,0, 4,1,5,8, 1,7,5,8, 0,3,8,2, 8,1,0,4, 3,6,8,2] + sourceMesh=MEDCouplingUMesh.New(); + sourceMesh.setMeshDimension(3); + sourceMesh.allocateCells(12); + sourceMesh.insertNextCell(NORM_TETRA4,4,sourceConn[0:4]) + sourceMesh.insertNextCell(NORM_TETRA4,4,sourceConn[4:8]) + sourceMesh.insertNextCell(NORM_TETRA4,4,sourceConn[8:12]) + sourceMesh.insertNextCell(NORM_TETRA4,4,sourceConn[12:16]) + sourceMesh.insertNextCell(NORM_TETRA4,4,sourceConn[16:20]) + sourceMesh.insertNextCell(NORM_TETRA4,4,sourceConn[20:24]) + sourceMesh.insertNextCell(NORM_TETRA4,4,sourceConn[24:28]) + sourceMesh.insertNextCell(NORM_TETRA4,4,sourceConn[28:32]) + sourceMesh.insertNextCell(NORM_TETRA4,4,sourceConn[32:36]) + sourceMesh.insertNextCell(NORM_TETRA4,4,sourceConn[36:40]) + sourceMesh.insertNextCell(NORM_TETRA4,4,sourceConn[40:44]) + sourceMesh.insertNextCell(NORM_TETRA4,4,sourceConn[44:48]) + sourceMesh.finishInsertingCells(); + myCoords=DataArrayDouble.New(); + myCoords.setValues(sourceCoords,9,3); + sourceMesh.setCoords(myCoords); + return sourceMesh; + + + def build3DSurfTargetMesh_1(self): + targetCoords=[-0.3,-0.3,0.5, 0.2,-0.3,1., 0.7,-0.3,1.5, -0.3,0.2,0.5, 0.2,0.2,1., 0.7,0.2,1.5, -0.3,0.7,0.5, 0.2,0.7,1., 0.7,0.7,1.5] + targetConn=[0,3,4,1, 1,4,2, 4,5,2, 6,7,4,3, 7,8,5,4] + targetMesh=MEDCouplingUMesh.New(); + targetMesh.setMeshDimension(2); + targetMesh.allocateCells(5); + targetMesh.insertNextCell(NORM_QUAD4,4,targetConn[0:4]) + targetMesh.insertNextCell(NORM_TRI3,3,targetConn[4:7]) + targetMesh.insertNextCell(NORM_TRI3,3,targetConn[7:10]) + targetMesh.insertNextCell(NORM_QUAD4,4,targetConn[10:14]) + targetMesh.insertNextCell(NORM_QUAD4,4,targetConn[14:18]) + targetMesh.finishInsertingCells(); + myCoords=DataArrayDouble.New(); + myCoords.setValues(targetCoords,9,3); + targetMesh.setCoords(myCoords); + return targetMesh; + + def build3DExtrudedUMesh_1(self): + coords=[ + 0.,0.,0., 1.,1.,0., 1.,1.25,0., 1.,0.,0., 1.,1.5,0., 2.,0.,0., 2.,1.,0., 1.,2.,0., 0.,2.,0., 3.,1.,0., + 3.,2.,0., 0.,1.,0., 1.,3.,0., 2.,2.,0., 2.,3.,0., + 0.,0.,1., 1.,1.,1., 1.,1.25,1., 1.,0.,1., 1.,1.5,1., 2.,0.,1., 2.,1.,1., 1.,2.,1., 0.,2.,1., 3.,1.,1., + 3.,2.,1., 0.,1.,1., 1.,3.,1., 2.,2.,1., 2.,3.,1., + 0.,0.,2., 1.,1.,2., 1.,1.25,2., 1.,0.,2., 1.,1.5,2., 2.,0.,2., 2.,1.,2., 1.,2.,2., 0.,2.,2., 3.,1.,2., + 3.,2.,2., 0.,1.,2., 1.,3.,2., 2.,2.,2., 2.,3.,2., + 0.,0.,3., 1.,1.,3., 1.,1.25,3., 1.,0.,3., 1.,1.5,3., 2.,0.,3., 2.,1.,3., 1.,2.,3., 0.,2.,3., 3.,1.,3., + 3.,2.,3., 0.,1.,3., 1.,3.,3., 2.,2.,3., 2.,3.,3.] + + conn=[ + # 0 + 0,11,1,3,15,26,16,18, 1,2,4,7,13,6,-1,1,16,21,6,-1,6,21,28,13,-1,13,7,22,28,-1,7,4,19,22,-1,4,2,17,19,-1,2,1,16,17,-1,16,21,28,22,19,17, + 1,6,5,3,16,21,20,18, 13,10,9,6,28,25,24,21, + 11,8,7,4,2,1,-1,11,26,16,1,-1,1,16,17,2,-1,2,17,19,4,-1,4,19,22,7,-1,7,8,23,22,-1,8,11,26,23,-1,26,16,17,19,22,23, + 7,12,14,13,22,27,29,28, + # 1 + 15,26,16,18,30,41,31,33, 16,17,19,22,28,21,-1,16,31,36,21,-1,21,36,43,28,-1,28,22,37,43,-1,22,19,34,37,-1,19,17,32,34,-1,17,16,31,32,-1,31,36,43,37,34,32, + 16,21,20,18,31,36,35,33, 28,25,24,21,43,40,39,36, + 26,23,22,19,17,16,-1,26,41,31,16,-1,16,31,32,17,-1,17,32,34,19,-1,19,34,37,22,-1,22,23,38,37,-1,23,26,41,38,-1,41,31,32,34,37,38, + 22,27,29,28,37,42,44,43, + # 2 + 30,41,31,33,45,56,46,48, 31,32,34,37,43,36,-1,31,46,51,36,-1,36,51,58,43,-1,43,37,52,58,-1,37,34,49,52,-1,34,32,47,49,-1,32,31,46,47,-1,46,51,58,52,49,47, + 31,36,35,33,46,51,50,48, 43,40,39,36,58,55,54,51, + 41,38,37,34,32,31,-1,41,56,46,31,-1,31,46,47,32,-1,32,47,49,34,-1,34,49,52,37,-1,37,38,53,52,-1,38,41,56,53,-1,56,46,47,49,52,53, + 37,42,44,43,52,57,59,58] + conn2=[7,12,14,13, 11,8,7,4,2,1, 13,10,9,6, 1,6,5,3, 1,2,4,7,13,6, 0,11,1,3] + # + ret=MEDCouplingUMesh.New(); + ret.setMeshDimension(3); + ret.allocateCells(18); + # + ret.insertNextCell(NORM_HEXA8,8,conn[0:8]); + ret.insertNextCell(NORM_POLYHED,43,conn[8:51]); + ret.insertNextCell(NORM_HEXA8,8,conn[51:59]); + ret.insertNextCell(NORM_HEXA8,8,conn[59:67]); + ret.insertNextCell(NORM_POLYHED,43,conn[67:110]); + ret.insertNextCell(NORM_HEXA8,8,conn[110:118]); + # + ret.insertNextCell(NORM_HEXA8,8,conn[118:126]); + ret.insertNextCell(NORM_POLYHED,43,conn[126:169]); + ret.insertNextCell(NORM_HEXA8,8,conn[169:177]); + ret.insertNextCell(NORM_HEXA8,8,conn[177:185]); + ret.insertNextCell(NORM_POLYHED,43,conn[185:228]); + ret.insertNextCell(NORM_HEXA8,8,conn[228:236]); + # + ret.insertNextCell(NORM_HEXA8,8,conn[236:244]); + ret.insertNextCell(NORM_POLYHED,43,conn[244:287]); + ret.insertNextCell(NORM_HEXA8,8,conn[287:295]); + ret.insertNextCell(NORM_HEXA8,8,conn[295:303]); + ret.insertNextCell(NORM_POLYHED,43,conn[303:346]); + ret.insertNextCell(NORM_HEXA8,8,conn[346:354]); + # + ret.finishInsertingCells(); + myCoords=DataArrayDouble.New(); + myCoords.setValues(coords,60,3); + ret.setCoords(myCoords); + # + mesh2D=MEDCouplingUMesh.New(); + mesh2D.setMeshDimension(2); + mesh2D.allocateCells(6); + mesh2D.insertNextCell(NORM_QUAD4,4,conn2[0:4]); + mesh2D.insertNextCell(NORM_POLYGON,6,conn2[4:10]); + mesh2D.insertNextCell(NORM_QUAD4,4,conn2[10:14]); + mesh2D.insertNextCell(NORM_QUAD4,4,conn2[14:18]); + mesh2D.insertNextCell(NORM_POLYGON,6,conn2[18:24]); + mesh2D.insertNextCell(NORM_QUAD4,4,conn2[24:28]); + mesh2D.finishInsertingCells(); + mesh2D.setCoords(myCoords); + return ret,mesh2D + + def buildCU1DMesh_U(self): + coords=[ 0.0, 0.3, 0.75, 1.0 ] + conn=[ 0,1, 1,2, 2,3 ] + mesh=MEDCouplingUMesh.New(); + mesh.setMeshDimension(1); + mesh.allocateCells(3); + mesh.insertNextCell(NORM_SEG2,2,conn[0:2]); + mesh.insertNextCell(NORM_SEG2,2,conn[2:4]); + mesh.insertNextCell(NORM_SEG2,2,conn[4:6]); + mesh.finishInsertingCells(); + myCoords=DataArrayDouble.New(); + myCoords.setValues(coords,4,1); + mesh.setCoords(myCoords); + return mesh; + + def build2DTargetMeshMergeNode_1(self): + targetCoords=[-0.3,-0.3, 0.2,-0.3, 0.7,-0.3, -0.3,-0.3, 0.2,-0.3, 0.2,-0.3, 0.2,0.2, 0.2,0.2, 0.7,-0.3, -0.3,0.2, 0.2,0.2, 0.7,0.2, -0.3,0.7, 0.7,0.2, -0.3,0.7, 0.2,0.7, 0.7,0.7, 0.2,0.7 ] + targetConn=[0,9,7,5, 4,6,2, 10,11,8, 9,14,15,7, 17,16,13,6] + targetMesh=MEDCouplingUMesh.New(); + targetMesh.setMeshDimension(2); + targetMesh.allocateCells(5); + targetMesh.insertNextCell(NORM_QUAD4,4,targetConn[0:4]); + targetMesh.insertNextCell(NORM_TRI3,3,targetConn[4:7]); + targetMesh.insertNextCell(NORM_TRI3,3,targetConn[7:10]); + targetMesh.insertNextCell(NORM_QUAD4,4,targetConn[10:14]); + targetMesh.insertNextCell(NORM_QUAD4,4,targetConn[14:18]); + targetMesh.finishInsertingCells(); + myCoords=DataArrayDouble.New(); + myCoords.setValues(targetCoords,18,2); + targetMesh.setCoords(myCoords); + return targetMesh; + + def build3DTargetMeshMergeNode_1(self): + targetCoords=[ 0., 0., 0., 50., 0., 0. , 200., 0., 0. , 0., 50., 0., 50., 50., 0. , 200., 50., 0., 0., 200., 0., 50., 200., 0. , 200., 200., 0. , + 0., 0., 50., 50., 0., 50. , 200., 0., 50. , 0., 50., 50., 50., 50., 50. , 200., 50., 50., 0., 200., 50., 50., 200., 50. , 200., 200., 50. , + 0., 0., 200., 50., 0., 200. , 200., 0., 200. , 0., 50., 200., 50., 50., 200. , 200., 50., 200., 0., 200., 200., 50., 200., 200. , 200., 200., 200., 50.,0.,0., 50.,0.,0., 50.,0.,0., 200., 50., 200.] + targetConn=[0,29,4,3,9,10,13,12, 28,2,5,4,10,11,14,13, 3,4,7,6,12,13,16,15, 4,5,8,7,13,14,17,16, + 9,10,13,12,18,19,22,21, 10,11,14,13,19,20,23,22, 12,13,16,15,21,22,25,24, 13,14,17,16,22,30,26,25] + targetMesh=MEDCouplingUMesh.New(); + targetMesh.setMeshDimension(3); + targetMesh.allocateCells(12); + for i in xrange(8): + targetMesh.insertNextCell(NORM_HEXA8,8,targetConn[8*i:8*(i+1)]); + pass + targetMesh.finishInsertingCells(); + myCoords=DataArrayDouble.New(); + myCoords.setValues(targetCoords,31,3); + targetMesh.setCoords(myCoords); + return targetMesh; + + def build2DTargetMeshMerged_1(self): + targetCoords=[ + -0.3,-0.3, 0.2,-0.3, 0.7,-0.3, -0.3,0.2, 0.2,0.2, 0.7,0.2, -0.3,0.7, 0.2,0.7, 0.7,0.7, + 0.7,-0.3, 1.7,-0.3, 0.7,0.7, 1.7,0.7 + ] + targetConn=[ + 0,3,4,1, 1,4,2, 4,5,2, 6,7,4,3, 7,8,5,4, + 9,12,10,9,11,12 + ] + targetMesh=MEDCouplingUMesh.New(); + targetMesh.setName("merge"); + targetMesh.setMeshDimension(2); + targetMesh.allocateCells(10); + targetMesh.insertNextCell(NORM_QUAD4,4,targetConn[0:4]) + targetMesh.insertNextCell(NORM_TRI3,3,targetConn[4:7]) + targetMesh.insertNextCell(NORM_TRI3,3,targetConn[7:10]) + targetMesh.insertNextCell(NORM_QUAD4,4,targetConn[10:14]) + targetMesh.insertNextCell(NORM_QUAD4,4,targetConn[14:18]) + targetMesh.insertNextCell(NORM_TRI3,3,targetConn[18:21]) + targetMesh.insertNextCell(NORM_TRI3,3,targetConn[21:24]) + targetMesh.finishInsertingCells(); + myCoords=DataArrayDouble.New(); + myCoords.setValues(targetCoords,13,2); + targetMesh.setCoords(myCoords); + return targetMesh; + + def build2DTargetMesh_2(cls): + targetCoords=[-0.3,-0.3, 0.2,-0.3, 0.7,-0.3, -0.3,0.2, 0.2,0.2, 0.7,0.2, -0.3,0.7, 0.2,0.7, 0.7,0.7 ] + targetConn=[0,3,4, 0,4,1, 1,4,2, 4,5,2, 3,6,4, 6,7,4, 4,7,5, 7,8,5 ] + targetMesh=MEDCouplingUMesh.New(); + targetMesh.setMeshDimension(2); + targetMesh.allocateCells(8); + targetMesh.insertNextCell(NORM_TRI3,3,targetConn[0:3]) + targetMesh.insertNextCell(NORM_TRI3,3,targetConn[3:6]) + targetMesh.insertNextCell(NORM_TRI3,3,targetConn[6:9]) + targetMesh.insertNextCell(NORM_TRI3,3,targetConn[9:12]) + targetMesh.insertNextCell(NORM_TRI3,3,targetConn[12:15]) + targetMesh.insertNextCell(NORM_TRI3,3,targetConn[15:18]) + targetMesh.insertNextCell(NORM_TRI3,3,targetConn[18:21]) + targetMesh.insertNextCell(NORM_TRI3,3,targetConn[21:24]) + targetMesh.finishInsertingCells(); + myCoords=DataArrayDouble.New(); + myCoords.setValues(targetCoords,9,2); + targetMesh.setCoords(myCoords); + return targetMesh; + + def build1DSourceMesh_2(cls): + ret=MEDCouplingUMesh.New("1DSourceMesh",1); + ret.allocateCells(4); + conn=[0,1,2,3,1,2,3,4] + for i in xrange(4): + ret.insertNextCell(NORM_SEG2,2,conn[2*i:2*i+2]); + pass + ret.finishInsertingCells(); + myCoords=DataArrayDouble.New([0.3,0.7,0.9,1.0,1.12],5,1); + ret.setCoords(myCoords); + return ret + + def build1DTargetMesh_3(cls): + ret=MEDCouplingUMesh.New("1DMesh_3",1); + ret.allocateCells(4); + conn=[0,1,2, 3,4, 6,5,7 ,9,8] + ret.insertNextCell(NORM_SEG3,3,conn[0:3]) + ret.insertNextCell(NORM_SEG2,2,conn[3:5]) + ret.insertNextCell(NORM_SEG3,3,conn[5:8]) + ret.insertNextCell(NORM_SEG2,2,conn[8:10]) + ret.finishInsertingCells(); + coords=[0.5,1.,0.8,5.,5.21,0.5,1.1,0.7,5.,5.31] + myCoords=DataArrayDouble.New(); + myCoords.setValues(coords,10,1); + ret.setCoords(myCoords); + return ret; + + def build2DCurveTargetMesh_3(cls): + ret=MEDCouplingUMesh.New("2DCurveMesh_3",1); + ret.allocateCells(4); + conn=[0,1,2, 3,4, 6,5,7 ,9,8] + ret.insertNextCell(NORM_SEG3,3,conn[0:3]) + ret.insertNextCell(NORM_SEG2,2,conn[3:5]) + ret.insertNextCell(NORM_SEG3,3,conn[5:8]) + ret.insertNextCell(NORM_SEG2,2,conn[8:10]) + ret.finishInsertingCells(); + coords=[0.5,0.5,1.,1.,0.8,0.8,5.,5.,5.21,5.21,0.5,0.5,1.1,1.1,0.7,0.7,5.,5.,5.31,5.31] + myCoords=DataArrayDouble.New(); + myCoords.setValues(coords,10,2); + ret.setCoords(myCoords); + return ret; + + def build2DTargetMesh_3(cls): + ret=MEDCouplingUMesh.New("2DMesh_3",2); + ret.allocateCells(10); + conn=[0,1,2, 0,1,3,4, 0,1,3,5,4, 0,1,2,6,7,8, 0,1,3,4,6,9,2,10, 0,2,1, 0,4,3,1, 0,4,5,3,1, 0,2,1,8,7,6, 0,4,3,1,10,2,9,6] + ret.insertNextCell(NORM_TRI3,3,conn[0:3]) + ret.insertNextCell(NORM_QUAD4,4,conn[3:7]) + ret.insertNextCell(NORM_POLYGON,5,conn[7:12]) + ret.insertNextCell(NORM_TRI6,6,conn[12:18]) + ret.insertNextCell(NORM_QUAD8,8,conn[18:26]) + ret.insertNextCell(NORM_TRI3,3,conn[26:29]) + ret.insertNextCell(NORM_QUAD4,4,conn[29:33]) + ret.insertNextCell(NORM_POLYGON,5,conn[33:38]) + ret.insertNextCell(NORM_TRI6,6,conn[38:44]) + ret.insertNextCell(NORM_QUAD8,8,conn[44:52]) + ret.finishInsertingCells(); + coords=[0.,0.,1.,0.,0.5,1.,1.,1.,0.,1.,0.5,2.,0.5,0.,0.75,0.5,0.25,0.5,1.,0.5,0.,0.5] + myCoords=DataArrayDouble.New(); + myCoords.setValues(coords,11,2); + ret.setCoords(myCoords); + ret.checkCoherency(); + return ret; + + def build2DTargetMesh_4(cls): + targetCoords=[-0.3,-0.3, 0.2,-0.3, 0.7,-0.3, 0.7,-0.3, -0.3,0.2, 0.2,0.2, 0.7,0.2, -0.3,0.7, 0.2,0.7, 0.7,0.7 ] + targetConn=[0,4,5,1, 1,5,3, 5,6,2, 7,8,5,4, 8,9,6,5] + targetMesh=MEDCouplingUMesh.New(); + targetMesh.setMeshDimension(2); + targetMesh.allocateCells(5); + targetMesh.insertNextCell(NORM_QUAD4,4,targetConn[0:4]) + targetMesh.insertNextCell(NORM_TRI3,3,targetConn[4:7]) + targetMesh.insertNextCell(NORM_TRI3,3,targetConn[7:10]) + targetMesh.insertNextCell(NORM_QUAD4,4,targetConn[10:14]) + targetMesh.insertNextCell(NORM_QUAD4,4,targetConn[14:18]) + targetMesh.finishInsertingCells(); + myCoords=DataArrayDouble.New(); + myCoords.setValues(targetCoords,10,2); + targetMesh.setCoords(myCoords); + return targetMesh; + + def buildMultiFields_1(cls): + m1=MEDCouplingDataForTest.build2DTargetMesh_1(); + m1.setName("m1"); + m2=MEDCouplingDataForTest.build2DTargetMesh_1(); + m2.setName("m2"); + vals0=[-0.7,-1.,-2.,-3.,-4.]; + vals1=[0.,1.,2.,3.,4.,0.1,0.2,0.3,0.4]; + vals1_1=[170.,171.,172.,173.,174.,170.1,170.2,170.3,170.4]; + vals2=[5.,6.,7.,8.,9.]; + vals4=[15.,16.,17.,18.,19.]; + d0=DataArrayDouble.New(); + d0.setValues(vals0,5,1); + d1=DataArrayDouble.New(); + d1.setValues(vals1,9,1); + d1_1=DataArrayDouble.New(); + d1_1.setValues(vals1_1,9,1); + d2=DataArrayDouble.New(); + d2.setValues(vals2,5,1); + d4=DataArrayDouble.New(); + d4.setValues(vals4,5,1); + d0.setName("d0"); d1.setName("d1"); d1_1.setName("d1_1"); d2.setName("d2"); d4.setName("d4"); + d0.setInfoOnComponent(0,"c1"); + d1.setInfoOnComponent(0,"c6"); + d1_1.setInfoOnComponent(0,"c9"); + d2.setInfoOnComponent(0,"c5"); + d4.setInfoOnComponent(0,"c7"); + f0=MEDCouplingFieldDouble.New(ON_CELLS,ONE_TIME); + f0.setMesh(m1); + f0.setArray(d0); + f0.setTime(0.2,5,6); + f0.setName("f0"); + f1=MEDCouplingFieldDouble.New(ON_NODES,LINEAR_TIME); + f1.setMesh(m1); + f1.setArrays([d1,d1_1]); + f1.setStartTime(0.7,7,8); + f1.setEndTime(1.2,9,10); + f1.setName("f1"); + f2=MEDCouplingFieldDouble.New(ON_CELLS,CONST_ON_TIME_INTERVAL); + f2.setMesh(m2); + f2.setArray(d2); + f2.setTime(1.2,11,12); + f2.setEndTime(1.5,13,14); + f2.setName("f2"); + f3=MEDCouplingFieldDouble.New(ON_CELLS,ONE_TIME); + f3.setMesh(m1); + f3.setArray(d2); + f3.setTime(1.7,15,16); + f3.setName("f3"); + f4=MEDCouplingFieldDouble.New(ON_CELLS,NO_TIME); + f4.setMesh(m2); + f4.setArray(d4); + f4.setName("f4"); + ret=MEDCouplingMultiFields.New([f0,f1,f2,f3,f4]); + return ret; + + def buildMultiFields_2(cls): + m1=MEDCouplingDataForTest.build2DTargetMesh_1(); + m1.setName("m1"); + m2=MEDCouplingDataForTest.build2DTargetMesh_1(); + m2.setName("m2"); + vals0=[-0.7,-1.,-2.,-3.,-4.]; + vals1=[0.,1.,2.,3.,4.]; + vals1_1=[170.,171.,172.,173.,174.]; + vals2=[5.,6.,7.,8.,9.]; + vals4=[15.,16.,17.,18.,19.]; + d0=DataArrayDouble.New(); + d0.setValues(vals0,5,1); + d1=DataArrayDouble.New(); + d1.setValues(vals1,5,1); + d1_1=DataArrayDouble.New(); + d1_1.setValues(vals1_1,5,1); + d2=DataArrayDouble.New(); + d2.setValues(vals2,5,1); + d4=DataArrayDouble.New(); + d4.setValues(vals4,5,1); + d0.setName("d0"); d1.setName("d1"); d1_1.setName("d1_1"); d2.setName("d2"); d4.setName("d4"); + d0.setInfoOnComponent(0,"c1"); + d1.setInfoOnComponent(0,"c6"); + d1_1.setInfoOnComponent(0,"c9"); + d2.setInfoOnComponent(0,"c5"); + d4.setInfoOnComponent(0,"c7"); + f0=MEDCouplingFieldDouble.New(ON_CELLS,ONE_TIME); + f0.setMesh(m1); + f0.setArray(d0); + f0.setTime(0.2,5,6); + f0.setName("f0"); + f1=MEDCouplingFieldDouble.New(ON_CELLS,LINEAR_TIME); + f1.setMesh(m1); + f1.setArrays([d1,d1_1]); + f1.setStartTime(0.7,7,8); + f1.setEndTime(1.2,9,10); + f1.setName("f1"); + f2=MEDCouplingFieldDouble.New(ON_CELLS,CONST_ON_TIME_INTERVAL); + f2.setMesh(m2); + f2.setArray(d2); + f2.setTime(1.2,11,12); + f2.setEndTime(1.5,13,14); + f2.setName("f2"); + f3=MEDCouplingFieldDouble.New(ON_CELLS,ONE_TIME); + f3.setMesh(m1); + f3.setArray(d2); + f3.setTime(1.7,15,16); + f3.setName("f3"); + f4=MEDCouplingFieldDouble.New(ON_CELLS,NO_TIME); + f4.setMesh(m2); + f4.setArray(d4); + f4.setName("f4"); + return [f0,f1,f2,f3,f4] + + def build1DMultiTypes_1(self): + mesh=MEDCouplingUMesh.New("Multi1DMesh",1); + coo=MEDCouplingDataForTest.buildCoordsForMultiTypes_1(); + conn=[0,2, 0,2,1] + mesh.allocateCells(2); + mesh.insertNextCell(NORM_SEG2,2,conn[0:2]) + mesh.insertNextCell(NORM_SEG3,3,conn[2:5]) + mesh.finishInsertingCells(); + mesh.setCoords(coo); + return mesh; + + def build2DMultiTypes_1(self): + mesh=MEDCouplingUMesh.New("Multi2DMesh",2); + coo=MEDCouplingDataForTest.buildCoordsForMultiTypes_1(); + conn=[3,4,5, 3,4,5,6,7,8, 0,9,10,11, 0,9,10,11,12,13,14,15] + mesh.allocateCells(4); + mesh.insertNextCell(NORM_TRI3,3,conn[0:3]) + mesh.insertNextCell(NORM_TRI6,6,conn[3:9]) + mesh.insertNextCell(NORM_QUAD4,4,conn[9:13]) + mesh.insertNextCell(NORM_QUAD8,8,conn[13:21]) + mesh.finishInsertingCells(); + mesh.setCoords(coo); + return mesh; + + def build3DMultiTypes_1(self): + mesh=MEDCouplingUMesh.New("Multi3DMesh",3); + coo=MEDCouplingDataForTest.buildCoordsForMultiTypes_1(); + conn=[0,16,17,18, + 0,16,17,18,19,20,21,22,23,24, + 0,11,10,9,25, + 0,11,10,9,25,15,14,13,12,26,27,28,29, + 0,30,31,32,33,34, + 0,30,31,32,33,34,35,36,37,38,39,40,41,42,43, + 0,9,10,11,44,45,46,47, + 0,9,10,11,44,45,46,47,12,13,14,15,48,49,50,51,52,53,54,55 ]; + mesh.allocateCells(8); + mesh.insertNextCell(NORM_TETRA4,4,conn[0:4]) + mesh.insertNextCell(NORM_TETRA10,10,conn[4:14]) + mesh.insertNextCell(NORM_PYRA5,5,conn[14:19]) + mesh.insertNextCell(NORM_PYRA13,13,conn[19:32]) + mesh.insertNextCell(NORM_PENTA6,6,conn[32:38]) + mesh.insertNextCell(NORM_PENTA15,15,conn[38:53]) + mesh.insertNextCell(NORM_HEXA8,8,conn[53:61]) + mesh.insertNextCell(NORM_HEXA20,20,conn[61:81]) + mesh.finishInsertingCells(); + mesh.setCoords(coo); + return mesh; + + def buildCoordsForMultiTypes_1(self): + coords=DataArrayDouble.New(); + data=[0.0,0.0,0.0, 0.5,0.5,0.5, 1.0,1.0,1.0, 1.0,1.0,0.0, 2.0,2.5,0.0, 6.0,1.5,0.0, 1.0,2.0,0.0, 4.5,2.5,0.0, 4.0,0.5,0.0, 0.0,4.0,0.0, 4.0,4.0,0.0, 4.0,0.0,0.0, 0.0,2.0,0.0, 2.0,4.0,0.0, 4.0,2.0,0.0, 2.0,0.0,0.0, 0.0,6.0,0.0, 3.0,3.0,0.0, 1.3,3.0,3.0, 0.0,3.0,0.0, 1.5,4.5,0.0, 1.5,1.5,0.0, 0.65,1.5,1.5, 0.65,4.5,1.5, 2.15,3.0,1.5, 2.0,2.0,2.0, 3.0,1.0,1.0, 3.0,3.0,1.0, 1.0,3.0,1.0, 1.0,1.0,1.0, 0.0,3.0,0.0, 2.0,0.0,0.0, 0.0,0.0,6.0, 0.0,3.0,6.0, 3.0,0.0,6.0, 0.0,1.5,0.0, 1.5,1.5,0.0, 1.5,0.0,0.0, 0.0,1.5,6.0, 1.5,1.5,6.0, 1.5,0.0,6.0, 0.0,0.0,3.0, 0.0,3.0,3.0, 3.0,0.0,3.0, 0.0,0.0,4.0, 0.0,4.0,4.0, 4.0,4.0,4.0, 4.0,0.0,4.0, 0.0,2.0,4.0, 2.0,4.0,4.0, 4.0,2.0,4.0, 2.0,0.0,4.0, 0.0,0.0,2.0, 0.0,4.0,2.0, 4.0,4.0,2.0, 4.0,0.0,2.0] + coords.setValues(data,56,3); + coords.setInfoOnComponent(0,"X (cm)"); + coords.setInfoOnComponent(1,"Y (cm)"); + coords.setInfoOnComponent(2,"Z (cm)"); + return coords + + def buildHexa8Mesh_1(self): + mesh=MEDCouplingUMesh.New("Hexa8Only",3); + coo=DataArrayDouble.New(); + coords=[0.0, 0.0, 0.0, 0.5, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.5, 0.0, 0.5, 0.5, 0.0, 1.0, 0.5, 0.0, 0.0, 1.0, 0.0, 0.5, 1.0, 0.0, 1.0, 1.0, 0.0, 0.0, 0.0, 0.5, 0.5, 0.0, 0.5, 1.0, 0.0, 0.5, 0.0, 0.5, 0.5, 0.5, 0.5, 0.5, 1.0, 0.5, 0.5, 0.0, 1.0, 0.5, 0.5, 1.0, 0.5, 1.0, 1.0, 0.5, 0.0, 0.0, 1.0, 0.5, 0.0, 1.0, 1.0, 0.0, 1.0, 0.0, 0.5, 1.0, 0.5, 0.5, 1.0, 1.0, 0.5, 1.0, 0.0, 1.0, 1.0, 0.5, 1.0, 1.0, 1.0, 1.0, 1.0] + coo.setValues(coords,27,3); + conn=[3,12,13,4,0,9,10,1, + 4,13,14,5,1,10,11,2, + 6,15,16,7,3,12,13,4, + 7,16,17,8,4,13,14,5, + 12,21,22,13,9,18,19,10, + 13,22,23,14,10,19,20,11, + 15,24,25,16,12,21,22,13, + 16,25,26,17,13,22,23,14]; + mesh.allocateCells(8); + for i in xrange(8): + mesh.insertNextCell(NORM_HEXA8,8,conn[8*i:8*(i+1)]) + pass + mesh.finishInsertingCells(); + mesh.setCoords(coo); + return mesh; + + def buildPointe_1(self): + mesh=MEDCouplingUMesh.New("Pointe.med",3); + mesh2=MEDCouplingUMesh.New("Pointe.med",2); + coords=[0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 2.0, 0.0, 1.0, 0.0, 2.0, 1.0, -2.0, 0.0, 1.0, 0.0, -2.0, 1.0, 1.0, 1.0, 2.0, -1.0, 1.0, 2.0, -1.0, -1.0, 2.0, 1.0, -1.0, 2.0, 1.0, 1.0, 3.0, -1.0, 1.0, 3.0, -1.0, -1.0, 3.0, 1.0, -1.0, 3.0, 1.0, 1.0, 4.0, -1.0, 1.0, 4.0, -1.0, -1.0, 4.0, 1.0, -1.0, 4.0, 0.0, 0.0, 5.0] + conn=[0,1,2,5,0,1,3,2,0,1,4,3,0,1,5,4,1,6,3,2,1,7,4,3,1,8,5,4,1,9,2,5,1,6,2,9,1,7,3,6,1,8,4,7,1,9,5,8, 6,7,8,9,1,14,17,16,15,18, 10,11,12,13,6,7,8,9,14,15,16,17,10,11,12,13] + coo=DataArrayDouble.New(); + coo.setValues(coords,19,3); + mesh.setCoords(coo); + mesh2.setCoords(coo); + mesh.allocateCells(16); + for i in xrange(12): + mesh.insertNextCell(NORM_TETRA4,4,conn[4*i:4*i+4]) + pass + mesh.insertNextCell(NORM_PYRA5,5,conn[48:53]) + mesh.insertNextCell(NORM_PYRA5,5,conn[53:58]) + mesh.insertNextCell(NORM_HEXA8,8,conn[58:66]) + mesh.insertNextCell(NORM_HEXA8,8,conn[66:74]) + mesh.finishInsertingCells(); + #[1,34,29,23,41,32] + conn2=[0,5,1,14,18,17,8,7,4,9,5,2, 12,8,9,13,6,7,8,9] + mesh2.allocateCells(6); + for i in xrange(4): + mesh2.insertNextCell(NORM_TRI3,3,conn2[3*i:3*i+3]) + pass + mesh2.insertNextCell(NORM_QUAD4,4,conn2[12:16]) + mesh2.insertNextCell(NORM_QUAD4,4,conn2[16:20]) + mesh2.finishInsertingCells(); + return [mesh,mesh2] + + # 2D usecase1 for interpolation Gauss Pt-> Gauss Pt. Coming from ASTER : Please, do not touch + def buildFieldOnGauss_1(self): + coo=DataArrayDouble([1.0,0.0,1.33333333333333,0.0,1.66666666666667,0.0,0.923879532511287,0.38268343236509006,1.23183937668172,0.510244576486786,1.53979922085214,0.6378057206084831,2.0,0.0,1.8477590650225701,0.7653668647301801,0.9428090415820631,0.9428090415820631,1.1785113019775801,1.1785113019775801,1.4142135623731,1.41421356237309,0.707106781186548,0.707106781186547,0.38268343236509006,0.923879532511287,0.510244576486786,1.23183937668172,0.6378057206084831,1.53979922085214,0.7653668647301801,1.8477590650225701,3.1550283219328204e-17,1.33333333333333,1.16009632455949e-17,1.66666666666667,-2.7620050344068196e-16,2.0,-1.3810025172034098e-16,1.0,-2.0,0.0,-1.53979922085214,0.6378057206084831,-1.66666666666667,0.0,-1.33333333333333,0.0,-0.923879532511287,0.38268343236509006,-1.8477590650225701,0.7653668647301801,-0.9428090415820631,0.9428090415820631,-1.23183937668172,0.510244576486786,-1.83333333333333,0.0,-1.6937791429373599,0.701586292669331,-1.5,0.0,-1.30771370720431,0.26012042935483803,-1.16666666666667,0.0,-1.0778594545965,0.44646400442593803,-1.38578268717091,0.9259503883660041,-1.38581929876693,0.574025148547635,-1.06066017177982,1.06066017177982,-0.8314696123025451,0.5555702330196021,-1.0,0.0,-1.1785113019775801,1.1785113019775801,-0.707106781186548,0.707106781186547,-1.63464213400538,0.325150536693547,-1.9615705608064598,0.390180644032256,-1.47117792060485,0.292635483024192,-0.9807852804032301,0.19509032201612803,-1.524360955888,1.0185454272026,-1.2963624321753402,1.2963624321753402,-1.10862614973673,0.740760310692803,-0.970047881019636,0.6481652718562021,-0.824957911384305,0.824957911384305,-1.4142135623731,1.41421356237309,-1.7981063474059198,0.357665590362902,-1.1442494938037702,0.227605375685483,-1.66293922460509,1.1111404660392,-1.24720441845382,0.833355349529403,-0.7653668647301801,1.8477590650225701,-0.6378057206084831,1.53979922085214,-0.510244576486786,1.23183937668172,-0.701586292669331,1.6937791429373599,-0.574025148547635,1.38581929876693,-0.44646400442593803,1.0778594545965,-0.38268343236509006,0.923879532511287,-0.9259503883660041,1.38578268717091,-0.740760310692803,1.10862614973673,-0.5555702330196021,0.8314696123025451,-0.325150536693547,1.63464213400538,-0.26012042935483803,1.30771370720431,-0.19509032201612803,0.9807852804032301,1.6805133673525298e-18,1.83333333333333,-2.4643915380595496e-16,1.5,-1.4799359654427099e-16,1.16666666666667,-1.1111404660392,1.66293922460509,-0.39018064403225705,1.9615705608064598],73,2) + coo.setInfoOnComponents(["X [INCONNUE]","Y [INCONNUE]"]) + m=MEDCouplingUMesh("MA1",2) + m.setDescription("CREE PAR CODE_ASTER") ; m.setTimeUnit("SANS UNITES") ; m.setTime(-1.,-1,-1) + m.setCoords(coo) + m.allocateCells() + conn=[[11,8,13],[11,13,12],[8,9,13],[9,14,13],[9,10,15],[9,15,14],[12,13,19],[13,16,19],[13,14,17],[13,17,16],[14,15,17],[15,18,17],[0,1,4,3],[1,2,5,4],[2,6,7,5],[3,4,8,11],[4,5,9,8],[5,7,10,9],[20,22,21,28,41,51],[21,25,20,29,42,51],[22,23,21,30,43,41],[23,27,21,31,35,43],[23,38,24,32,44,52],[24,27,23,33,31,52],[25,21,50,29,45,53],[21,39,50,34,46,45],[21,27,26,35,47,54],[26,39,21,36,34,54],[27,24,26,33,48,47],[24,40,26,37,49,48],[50,39,56,55,46,62,58,71],[39,26,57,56,36,63,59,62],[26,40,61,57,49,64,60,63],[55,56,17,18,58,65,68,72],[56,57,16,17,59,66,69,65],[57,61,19,16,60,67,70,66]] + for i in xrange(0,12): + m.insertNextCell(NORM_TRI3,conn[i]) + pass + for i in xrange(12,18): + m.insertNextCell(NORM_QUAD4,conn[i]) + pass + for i in xrange(18,30): + m.insertNextCell(NORM_TRI6,conn[i]) + pass + for i in xrange(30,36): + m.insertNextCell(NORM_QUAD8,conn[i]) + pass + fff=MEDCouplingFieldDouble.New(ON_GAUSS_PT) ; fff.setName("CH1RB") ; fff.setNature(ConservativeVolumic) + fff.setMesh(m) + fff.setGaussLocalizationOnCells(range(0,12),[0.,0.,1.,0.,0.,1.],[0.3333333333333333,0.3333333333333333],[0.5]) + fff.setGaussLocalizationOnCells(range(12,18),[-1.,-1.,1.,-1.,1.,1.,-1.,1.],[-0.577350269189626,-0.577350269189626,0.577350269189626,-0.577350269189626,0.577350269189626,0.577350269189626,-0.577350269189626,0.577350269189626],[1.,1.,1.,1.]) + fff.setGaussLocalizationOnCells(range(18,30),[0.,0.,1.,0.,0.,1.,0.5, 0.,0.5, 0.5, 0.,0.5],[0.16666666666666666,0.16666666666666666,0.6666666666666666,0.16666666666666666,0.16666666666666666,0.6666666666666666],[0.16666666666666666,0.16666666666666666,0.16666666666666666]) + fff.setGaussLocalizationOnCells(range(30,36),[-1.,-1.,1.,-1.,1.,1.,-1.,1.,0.,-1.,1.,0.,0.,1.,-1.,0.],[-0.774596669241483,-0.774596669241483,0.774596669241483,-0.774596669241483,0.774596669241483,0.774596669241483,-0.774596669241483,0.774596669241483,0.0,-0.774596669241483,0.774596669241483,0.0,0.0,0.774596669241483,-0.774596669241483,0.0,0.0,0.0],[0.30864197530864196,0.30864197530864196,0.30864197530864196,0.30864197530864196,0.49382716049382713,0.49382716049382713,0.49382716049382713,0.49382716049382713,0.7901234567901234]) + return MEDCouplingFieldTemplate(fff) + + # 2D usecase2 for interpolation Gauss Pt-> Gauss Pt. Coming from ASTER : Please, do not touch + def buildFieldOnGauss_2(self): + coo=DataArrayDouble([1.0,0.0,1.24068268955165,0.15233667925643402,1.25,0.0,1.5,0.0,1.73695576537231,0.21327135095900804,1.75,0.0,2.0,0.0,0.9925461516413221,0.12186934340514702,1.212869657845,0.302402369499585,1.48881922746198,0.182804015107721,1.6980175209829897,0.423363317299419,1.9850923032826397,0.243738686810295,0.9702957262759959,0.241921895599668,1.1669755331215,0.447959936931625,1.4554435894139899,0.362882843399502,1.6337657463701,0.627143911704275,1.94059145255199,0.483843791199335,0.9335804264972021,0.35836794954530005,1.10368449107366,0.586839453482364,1.4003706397458,0.5375519243179501,1.5451582875031202,0.8215752348753091,1.8671608529944002,0.716735899090601,0.882947592858927,0.46947156278589103,1.02394005536124,0.716970545438808,1.32442138928839,0.704207344178836,1.43351607750574,1.00375876361433,1.76589518571785,0.9389431255717821,1.125,0.0,1.11661442059649,0.137103011330791,1.375,0.0,1.4972021976328,0.09157280930228531,1.625,0.0,1.61288749641715,0.198037683033365,1.875,0.0,1.9962695968437298,0.12209707906971401,1.0915826920605,0.272162132549626,1.36475095850682,0.167570347182078,1.47488236134593,0.27335328823822097,1.5767305551984903,0.39312308034946003,1.8610240343274802,0.228505018884652,1.96650981512791,0.364471050984295,1.05027797980935,0.403163943238463,1.3341566236295,0.332642606449543,1.43057542612234,0.45105869925641007,1.5170681930579497,0.5823479180111131,1.8193044867674901,0.45360355424937704,1.9074339014964499,0.601411599008546,0.993316041966293,0.528155508134127,1.28367308643365,0.492755930624788,1.36494190631481,0.6220398639843591,1.43478983839576,0.7628912895270731,1.7504632996822498,0.671939905397438,1.81992254175309,0.8293864853124782,0.921546049825116,0.645273490894927,1.21405294018102,0.6455233988306001,1.27896024653114,0.783747847073923,1.33112207196961,0.93206170907045,1.65552673661049,0.8802591802235451,1.70528032870818,1.0449971294319,0.8191520442889921,0.5735764363510459,1.22872806643349,0.8603646545265691,1.6383040885779798,1.14715287270209,1.24766849802733,0.0763106744185711,0.9981347984218671,0.0610485395348569,1.37243534783007,0.0839417418604282,1.74673589723827,0.106834944186,1.871502747041,0.114466011627857,1.22906863445494,0.227794406865184,0.9832549075639551,0.18223552549214703,1.3519754979004401,0.25057384755170303,1.7206960882369198,0.318912169611258,1.84360295168241,0.341691610297777,1.19214618843528,0.37588224938034104,0.953716950748227,0.300705799504273,1.31136080727881,0.413470474318376,1.6690046638094,0.526235149132478,1.7882192826529297,0.563823374070512,1.13745158859568,0.518366553320299,0.9099612708765431,0.4146932426562391,1.25119674745525,0.570203208652329,1.5924322240339497,0.725713174648418,1.7061773828935198,0.777549829980448,1.06580020544262,0.6531232058949361,0.8526401643540921,0.522498564715949,1.17238022598688,0.7184355264844301,1.12633406089736,0.7886675999826881,1.49212028761966,0.91437248825291,1.59870030816392,0.979684808842404,1.53591008304186,1.07545581815821,1.1229016482246,0.068679606976714,1.6219690474355302,0.0992038767441424,1.10616177100945,0.205014966178666,1.59778922479143,0.29613272892474,1.07293156959176,0.338294024442307,1.5497900449658701,0.488646924194444,1.02370642973611,0.466529897988269,1.47868706517438,0.673876519316388,0.9592201848983541,0.587810885305442,1.3855402670754,0.8490601676634171,0.743144825477394,0.669130606358858,0.9289310318467431,0.836413257948573,1.11471723821609,1.00369590953829,1.30050344458544,1.170978561128,0.656059028990507,0.7547095802227721,0.820073786238134,0.943386975278465,0.984088543485761,1.13206437033416,1.14810330073339,1.32074176538985,0.559192903470747,0.8290375725550421,0.6989911293384331,1.0362969656938,0.8387893552061201,1.24355635883256,0.978587581073807,1.45081575197132,0.453990499739547,0.8910065241883681,0.567488124674433,1.11375815523546,0.6809857496093201,1.3365097862825501,0.794483374544207,1.55926141732964,0.8360379286620679,0.7527719321537151,1.0218241350314199,0.92005458374343,1.20761034140077,1.08733723533314,1.39339654777011,1.25461988692286,0.7380664076143211,0.8490482777506181,0.902081164861948,1.03772567280631,1.06609592210957,1.226403067862,1.2301106793572,1.4150804629177,0.6290920164045901,0.932667269124422,0.7688902422722771,1.13992666226318,0.9086884681399641,1.34718605540194,1.04848669400765,1.5544454485407,0.51073931220699,1.00238233971191,0.624236937141877,1.22513397075901,0.737734562076764,1.4478856018061,0.85123218701165,1.6706372328531902,1.48628965095479,1.33826121271772,1.31211805798101,1.5094191604455398,1.11838580694149,1.6580751451100801,0.907980999479094,1.7820130483767398,0.978260196065517,0.778143295797024,1.17391223527862,0.9337719549564292,1.36956427449172,1.08940061411583,1.56521631370483,1.24502927327524,0.876136580374814,0.891563061442727,1.05136389644978,1.06987567373127,1.22659121252474,1.2481882860198201,1.4018185285997,1.42650089830836,0.7609517862609011,0.991691675364044,0.913142143513081,1.19003001043685,1.06533250076526,1.38836834550966,1.21752285801744,1.5867066805824699,0.6344229537008801,1.07703645055191,0.7613075444410561,1.29244374066229,0.8881921351812321,1.50785103077267,1.01507672592141,1.7232583208830499,0.498436336156558,1.1463250929814,0.5981236033878691,1.37559011157769,0.697810870619181,1.60485513017397,0.7974981378504931,1.8341201487702499,0.42752517915708604,1.17461577598239,0.513030214988503,1.4095389311788602,0.59853525081992,1.6444620863753399,0.6840402866513371,1.87938524157182,0.38477266124137705,1.05715419838415,0.470277697072795,1.29207735358062,0.5557827329042121,1.5270005087771,0.6412877687356291,1.76192366397358,0.34202014332566905,0.9396926207859091,0.782608156852414,0.6225146366376201,0.7009092642998511,0.713250449154182,0.608761429008721,0.7933533402912349,0.507538362960704,0.861629160441526,0.398749068925246,0.917060074385124,-2.0,0.0,-1.75,0.0,-1.5,0.0,-1.25,0.0,-1.9632543668953297,0.38161799075309005,-1.71784757103341,0.333915741908953,-1.4724407751715,0.286213493064817,-1.22703397930958,0.23851124422068104,-1.85436770913357,0.749213186831824,-1.62257174549188,0.655561538477846,-1.39077578185018,0.561909890123868,-1.15897981820848,0.46825824176988995,-1.6773411358908499,1.08927807003005,-1.4676734939044902,0.953118311276297,-1.25800585191814,0.816958552522541,-1.04833820993178,0.680798793768784,-1.4386796006773,1.38931674091799,-1.25884465059264,1.21565214830325,-1.07900970050798,1.0419875556885,-0.8991747504233141,0.868322963073747,-1.0,0.0,-0.981627183447664,0.19080899537654503,-0.9271838545667871,0.374606593415912,-0.838670567945424,0.544639035015027,-0.7193398003386511,0.694658370458997,-1.00375876361433,1.43351607750574,-0.8603646545265691,1.22872806643349,-0.716970545438808,1.02394005536124,-0.5735764363510459,0.8191520442889921,-1.14715287270209,1.6383040885779798,-0.8134732861516011,1.8270909152852002,-0.71178912538265,1.59870455087455,-0.6101049646137,1.3703181864639,-0.50842080384475,1.14193182205325,-0.4067366430758,0.9135454576426011,-0.44990210868773,1.9487401295704703,-0.39366434510176407,1.70514761337416,-0.337426581515798,1.4615550971778501,-0.281188817929831,1.21796258098154,-0.224951054343865,0.974370064785235,-0.06979899340500181,1.9987816540381902,-0.0610741192293767,1.74893394728342,-0.0523492450537515,1.49908624052864,-0.0436243708781263,1.24923853377387,-0.03489949670250091,0.9993908270190961,0.312868930080462,1.97537668119028,0.27376031382040406,1.72845459604149,0.23465169756034704,1.48153251089271,0.19554308130028902,1.23461042574392,0.156434465040231,0.9876883405951381],219,2) + coo.setInfoOnComponents(["X [INCONNUE]","Y [INCONNUE]"]) + m=MEDCouplingUMesh("MA2",2) + m.setDescription("CREE PAR CODE_ASTER") ; m.setTimeUnit("SANS UNITES") ; m.setTime(-1.,-1,-1) + m.setCoords(coo) + m.allocateCells(0) + conn=[[198,194,200],[198,200,199],[194,195,200],[195,201,200],[195,196,202],[195,202,201],[196,197,202],[197,203,202],[199,200,205],[199,205,204],[200,201,205],[201,206,205],[201,202,207],[201,207,206],[202,203,207],[203,208,207],[204,205,210],[204,210,209],[205,206,210],[206,211,210],[206,207,212],[206,212,211],[207,208,212],[208,213,212],[209,210,215],[209,215,214],[210,211,215],[211,216,215],[211,212,217],[211,217,216],[212,213,217],[213,218,217],[214,215,157],[214,157,158],[215,216,157],[216,156,157],[216,217,155],[216,155,156],[217,218,155],[218,163,155],[169,170,174,173],[170,171,175,174],[171,172,176,175],[172,189,190,176],[173,174,178,177],[174,175,179,178],[175,176,180,179],[176,190,191,180],[177,178,182,181],[178,179,183,182],[179,180,184,183],[180,191,192,184],[181,182,186,185],[182,183,187,186],[183,184,188,187],[184,192,193,188],[185,186,194,198],[186,187,195,194],[187,188,196,195],[188,193,197,196],[0,2,1,27,62,89],[1,7,0,28,63,89],[2,3,1,29,64,62],[3,9,1,30,36,64],[3,5,4,31,65,90],[4,9,3,32,30,90],[5,6,4,33,66,65],[6,11,4,34,39,66],[7,1,8,28,67,91],[8,12,7,35,68,91],[1,9,8,36,69,67],[9,14,8,37,42,69],[9,4,10,32,70,92],[10,14,9,38,37,92],[4,11,10,39,71,70],[11,16,10,40,45,71],[12,8,13,35,72,93],[13,17,12,41,73,93],[8,14,13,42,74,72],[14,19,13,43,48,74],[14,10,15,38,75,94],[15,19,14,44,43,94],[10,16,15,45,76,75],[16,21,15,46,51,76],[17,13,18,41,77,95],[18,22,17,47,78,95],[13,19,18,48,79,77],[19,24,18,49,54,79],[19,15,20,44,80,96],[20,24,19,50,49,96],[15,21,20,51,81,80],[21,26,20,52,57,81],[22,18,23,47,82,97],[23,59,22,53,83,97],[18,24,23,54,84,82],[24,60,23,55,85,84],[24,20,25,50,86,98],[25,60,24,56,55,98],[20,26,25,57,87,86],[26,61,25,58,88,87],[59,23,100,99,53,135,115,164],[23,60,101,100,85,136,116,135],[60,25,102,101,56,137,117,136],[25,61,131,102,88,138,118,137],[99,100,104,103,115,139,119,165],[100,101,105,104,116,140,120,139],[101,102,106,105,117,141,121,140],[102,131,132,106,118,142,122,141],[103,104,108,107,119,143,123,166],[104,105,109,108,120,144,124,143],[105,106,110,109,121,145,125,144],[106,132,133,110,122,146,126,145],[107,108,112,111,123,147,127,167],[108,109,113,112,124,148,128,147],[109,110,114,113,125,149,129,148],[110,133,134,114,126,150,130,149],[111,112,155,163,127,151,159,168],[112,113,156,155,128,152,160,151],[113,114,157,156,129,153,161,152],[114,134,158,157,130,154,162,153]] + for i in xrange(0,40): + m.insertNextCell(NORM_TRI3,conn[i]) + pass + for i in xrange(40,60): + m.insertNextCell(NORM_QUAD4,conn[i]) + pass + for i in xrange(60,100): + m.insertNextCell(NORM_TRI6,conn[i]) + pass + for i in xrange(100,120): + m.insertNextCell(NORM_QUAD8,conn[i]) + pass + fff=MEDCouplingFieldDouble.New(ON_GAUSS_PT) ; fff.setName("CH2RB") ; fff.setNature(ConservativeVolumic) + fff.setMesh(m) + fff.setGaussLocalizationOnCells(range(0,40),[0.,0.,1.,0.,0.,1.],[0.3333333333333333,0.3333333333333333],[0.5]) + fff.setGaussLocalizationOnCells(range(40,60),[-1.,-1.,1.,-1.,1.,1.,-1.,1.],[-0.577350269189626,-0.577350269189626,0.577350269189626,-0.577350269189626,0.577350269189626,0.577350269189626,-0.577350269189626,0.577350269189626],[1.,1.,1.,1.]) + fff.setGaussLocalizationOnCells(range(60,100),[0.,0.,1.,0.,0.,1.,0.5, 0.,0.5, 0.5, 0.,0.5],[0.16666666666666666,0.16666666666666666,0.6666666666666666,0.16666666666666666,0.16666666666666666,0.6666666666666666],[0.16666666666666666,0.16666666666666666,0.16666666666666666]) + fff.setGaussLocalizationOnCells(range(100,120),[-1.,-1.,1.,-1.,1.,1.,-1.,1.,0.,-1.,1.,0.,0.,1.,-1.,0.],[-0.774596669241483,-0.774596669241483,0.774596669241483,-0.774596669241483,0.774596669241483,0.774596669241483,-0.774596669241483,0.774596669241483,0.0,-0.774596669241483,0.774596669241483,0.0,0.0,0.774596669241483,-0.774596669241483,0.0,0.0,0.0],[0.30864197530864196,0.30864197530864196,0.30864197530864196,0.30864197530864196,0.49382716049382713,0.49382716049382713,0.49382716049382713,0.49382716049382713,0.7901234567901234]) + return MEDCouplingFieldTemplate(fff) + + # 3D usecase1 for interpolation Gauss Pt-> Gauss Pt. Coming from ASTER : Please, do not touch + def buildFieldOnGauss_3(self): + coo=DataArrayDouble([0.,1.,0.,0.,2.,0.,0.,3.,0.,1.,1.,0.,1.,2.,0.,1.,3.,0.,0.,1.,1.,0.,3.,1.,0.5,1.,1.,0.5,3.,1.,1.,1.,1.,1.,3.,1.,0.,0.,0.,0.,1.,0.,1.,0.,0.,1.,1.,0.,0.,0.,1.,0.,0.5,1.,0.,1.,1.,0.5,0.,1.,0.5,0.5,1.,0.5,1.,1.,1.,0.,1.,1.,0.5,1.,1.,1.,1.0],25,3) + coo.setInfoOnComponents(["X [INCONNUE]","Y [INCONNUE]","Z [INCONNUE]"]) + m=MEDCouplingUMesh("MA1",3) + m.setDescription("CREE PAR CODE_ASTER") ; m.setTimeUnit("SANS UNITES") ; m.setTime(-1.,-1,-1) + m.setCoords(coo) + m.allocateCells(0) + conn=[[3,10,8,4],[19,22,23,20,14],[0,6,1,3,8,4],[4,8,10,5,9,11],[12,16,17,14,19,20],[14,20,23,15,21,24],[1,2,5,4,6,7,9,8],[12,13,15,14,17,18,21,20]] + m.insertNextCell(NORM_TETRA4,conn[0]) + m.insertNextCell(NORM_PYRA5,conn[1]) + for i in xrange(2,6): + m.insertNextCell(NORM_PENTA6,conn[i]) + pass + m.insertNextCell(NORM_HEXA8,conn[6]) + m.insertNextCell(NORM_HEXA8,conn[7]) + fff=MEDCouplingFieldDouble.New(ON_GAUSS_PT) ; fff.setName("CH13") ; fff.setNature(ConservativeVolumic) + fff.setMesh(m) + fff.setGaussLocalizationOnCells([0],[0.,1.,0.,0.,0.,0.,0.,0.,1.,1.,0.,0.],[0.25,0.25,0.25],[0.16666666666666666]) + fff.setGaussLocalizationOnCells([1],[1.,0.,0.,0.,-1.,0.,-1.,0.,0.,0.,1.,0.,0.,0.,1.],[0.5,0.,0.1531754163448146,0.,0.5,0.1531754163448146,-0.5,0.,0.1531754163448146,0.,-0.5,0.1531754163448146,0.,0.,0.6372983346207416],[0.1333333333333333,0.1333333333333333,0.1333333333333333,0.1333333333333333,0.1333333333333333]) + fff.setGaussLocalizationOnCells([2,3,4,5],[-1.,1.,0.,-1.,0.,0.,-1.,0.,1.,1.,1.,0.,1.,0.,0.,1.,0.,1.],[-0.577350269189626,0.5,0.5,-0.577350269189626,0.,0.5,-0.577350269189626,0.5,0.,0.577350269189626,0.5,0.5,0.577350269189626,0.,0.5,0.577350269189626,0.5,0.],[0.16666666666666666,0.16666666666666666,0.16666666666666666,0.16666666666666666,0.16666666666666666,0.16666666666666666]) + fff.setGaussLocalizationOnCells([6,7],[-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.577350269189626,-0.577350269189626,-0.577350269189626,-0.577350269189626,-0.577350269189626,0.577350269189626,-0.577350269189626,0.577350269189626,-0.577350269189626,-0.577350269189626,0.577350269189626,0.577350269189626,0.577350269189626,-0.577350269189626,-0.577350269189626,0.577350269189626,-0.577350269189626,0.577350269189626,0.577350269189626,0.577350269189626,-0.577350269189626,0.577350269189626,0.577350269189626,0.577350269189626],[1.,1.,1.,1.,1.,1.,1.,1.]) + return MEDCouplingFieldTemplate(fff) + + # 3D usecase2 for interpolation Gauss Pt-> Gauss Pt. Coming from ASTER : Please, do not touch + def buildFieldOnGauss_4(self): + coo=DataArrayDouble([0.,2.,0.,0.,1.,0.,0.,0.,0.,1.,2.,0.,1.,1.,0.,1.,0.,0.,0.,2.,1.,0.,0.,1.,0.5, 2.,1.,0.5, 0.,1.,1.,2.,1.,1.,0.,1.,0.,3.,0.,0.,2.,0.,1.,3.,0.,1.,2.,0.,0.,3.,1.,0.,2.5, 1.,0.,2.,1.,0.5, 3.,1.,0.5, 2.5, 1.,0.5, 2.,1.,1.,3.,1.,1.,2.5, 1.,1.,2.,1.0],25,3) + coo.setInfoOnComponents(["X [INCONNUE]","Y [INCONNUE]","Z [INCONNUE]"]) + m=MEDCouplingUMesh("MA2",3) + m.setDescription("CREE PAR CODE_ASTER") ; m.setTimeUnit("SANS UNITES") ; m.setTime(-1.,-1,-1) + m.setCoords(coo) + m.allocateCells(0) + conn=[[3,10,8,4],[19,22,23,20,14],[0,6,1,3,8,4],[4,8,10,5,9,11],[12,16,17,14,19,20],[14,20,23,15,21,24],[1,2,5,4,6,7,9,8],[12,13,15,14,17,18,21,20]] + m.insertNextCell(NORM_TETRA4,conn[0]) + m.insertNextCell(NORM_PYRA5,conn[1]) + for i in xrange(2,6): + m.insertNextCell(NORM_PENTA6,conn[i]) + pass + m.insertNextCell(NORM_HEXA8,conn[6]) + m.insertNextCell(NORM_HEXA8,conn[7]) + fff=MEDCouplingFieldDouble.New(ON_GAUSS_PT) ; fff.setName("CH23") ; fff.setNature(ConservativeVolumic) + fff.setMesh(m) + fff.setGaussLocalizationOnCells([0],[0.,1.,0.,0.,0.,0.,0.,0.,1.,1.,0.,0.],[0.25,0.25,0.25],[0.16666666666666666]) + fff.setGaussLocalizationOnCells([1],[1.,0.,0.,0.,-1.,0.,-1.,0.,0.,0.,1.,0.,0.,0.,1.],[0.5,0.,0.1531754163448146,0.,0.5,0.1531754163448146,-0.5,0.,0.1531754163448146,0.,-0.5,0.1531754163448146,0.,0.,0.6372983346207416],[0.1333333333333333,0.1333333333333333,0.1333333333333333,0.1333333333333333,0.1333333333333333]) + fff.setGaussLocalizationOnCells([2,3,4,5],[-1.,1.,0.,-1.,0.,0.,-1.,0.,1.,1.,1.,0.,1.,0.,0.,1.,0.,1.],[-0.577350269189626,0.5,0.5,-0.577350269189626,0.,0.5,-0.577350269189626,0.5,0.,0.577350269189626,0.5,0.5,0.577350269189626,0.,0.5,0.577350269189626,0.5,0.],[0.16666666666666666,0.16666666666666666,0.16666666666666666,0.16666666666666666,0.16666666666666666,0.16666666666666666]) + fff.setGaussLocalizationOnCells([6,7],[-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.577350269189626,-0.577350269189626,-0.577350269189626,-0.577350269189626,-0.577350269189626,0.577350269189626,-0.577350269189626,0.577350269189626,-0.577350269189626,-0.577350269189626,0.577350269189626,0.577350269189626,0.577350269189626,-0.577350269189626,-0.577350269189626,0.577350269189626,-0.577350269189626,0.577350269189626,0.577350269189626,0.577350269189626,-0.577350269189626,0.577350269189626,0.577350269189626,0.577350269189626],[1.,1.,1.,1.,1.,1.,1.,1.]) + return MEDCouplingFieldTemplate(fff) + + def buildCircle(self, center_X, center_Y, radius): + from cmath import rect + from math import pi + + c = [rect(radius, i*pi/4.0) for i in range(8)] + coords = [c[-1].real,c[-1].imag, c[3].real,c[3].imag, + c[5].real,c[5].imag, c[1].real,c[1].imag] + connec = range(4) + baseMesh = MEDCouplingUMesh.New("circle", 2) + baseMesh.allocateCells(1) + meshCoords = DataArrayDouble.New(coords, len(coords)/2, 2) + meshCoords += (center_X, center_Y) + baseMesh.setCoords(meshCoords) + + baseMesh.insertNextCell(NORM_QPOLYG, connec) + baseMesh.finishInsertingCells() + return baseMesh + + def buildCircle2(self, center_X, center_Y, radius): + from cmath import rect + from math import pi + + c = [rect(radius, i*pi/4.0) for i in range(8)] + coords = [] + for i in range(8): + coords.extend([c[i].real,c[i].imag]) + connec = [7,5,3,1, 6,4,2,0] + baseMesh = MEDCouplingUMesh.New("circle", 2) + baseMesh.allocateCells(1) + meshCoords = DataArrayDouble.New(coords, len(coords)/2, 2) + meshCoords += (center_X, center_Y) + baseMesh.setCoords(meshCoords) + + baseMesh.insertNextCell(NORM_QPOLYG, connec) + baseMesh.finishInsertingCells() + return baseMesh + + build2DTargetMesh_1=classmethod(build2DTargetMesh_1) + build2DSourceMesh_1=classmethod(build2DSourceMesh_1) + build3DTargetMesh_1=classmethod(build3DTargetMesh_1) + build3DSourceMesh_1=classmethod(build3DSourceMesh_1) + build3DSurfTargetMesh_1=classmethod(build3DSurfTargetMesh_1) + build3DExtrudedUMesh_1=classmethod(build3DExtrudedUMesh_1) + buildCU1DMesh_U=classmethod(buildCU1DMesh_U) + build2DTargetMeshMergeNode_1=classmethod(build2DTargetMeshMergeNode_1) + build3DTargetMeshMergeNode_1=classmethod(build3DTargetMeshMergeNode_1) + build2DTargetMeshMerged_1=classmethod(build2DTargetMeshMerged_1) + build2DTargetMesh_2=classmethod(build2DTargetMesh_2) + build1DSourceMesh_2=classmethod(build1DSourceMesh_2) + build1DTargetMesh_3=classmethod(build1DTargetMesh_3) + build2DCurveTargetMesh_3=classmethod(build2DCurveTargetMesh_3) + build2DTargetMesh_3=classmethod(build2DTargetMesh_3) + build2DTargetMesh_4=classmethod(build2DTargetMesh_4) + buildMultiFields_1=classmethod(buildMultiFields_1) + buildMultiFields_2=classmethod(buildMultiFields_2) + build1DMultiTypes_1=classmethod(build1DMultiTypes_1) + build2DMultiTypes_1=classmethod(build2DMultiTypes_1) + build3DMultiTypes_1=classmethod(build3DMultiTypes_1) + buildCoordsForMultiTypes_1=classmethod(buildCoordsForMultiTypes_1) + buildHexa8Mesh_1=classmethod(buildHexa8Mesh_1) + buildPointe_1=classmethod(buildPointe_1) + buildFieldOnGauss_1=classmethod(buildFieldOnGauss_1) + buildFieldOnGauss_2=classmethod(buildFieldOnGauss_2) + buildFieldOnGauss_3=classmethod(buildFieldOnGauss_3) + buildFieldOnGauss_4=classmethod(buildFieldOnGauss_4) + buildCircle=classmethod(buildCircle) + buildCircle2=classmethod(buildCircle2) + pass + + + diff --git a/src/medtool/src/MEDCoupling_Swig/MEDCouplingExamplesTest.py b/src/medtool/src/MEDCoupling_Swig/MEDCouplingExamplesTest.py new file mode 100644 index 000000000..3ebd2170d --- /dev/null +++ b/src/medtool/src/MEDCoupling_Swig/MEDCouplingExamplesTest.py @@ -0,0 +1,2343 @@ +# -*- coding: iso-8859-1 -*- +# Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 +# 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 +# + +from MEDCoupling import * +import unittest +from math import pi, sqrt + +class MEDCouplingBasicsTest(unittest.TestCase): + + def testExample_MEDCouplingFieldDouble_WriteVTK(self): + #! [PySnippet_MEDCouplingFieldDouble_WriteVTK_1] + # mesh + coords = [0.,2.,4.] + coordsArr=DataArrayDouble(coords,3,1) + mesh=MEDCouplingCMesh() + mesh.setCoords(coordsArr,coordsArr) # mesh becomes a 2D one + + # 3 fields (lying on the same mesh!) + field1 = mesh.getMeasureField( True ) + field2 = mesh.buildOrthogonalField() + field3 = mesh.fillFromAnalytic( ON_CELLS, 2, "IVec * x + JVec * y" ) + field2.setName( "Normal" ) # name is necessary! + field3.setName( "Barycenter" ) # name is necessary! + + # WriteVTK + fileName = "testExample_MEDCouplingFieldDouble_WriteVTK" + fs = [ field1, field2, field3 ] # field series + writtenFileName=MEDCouplingFieldDouble.WriteVTK( fileName, fs ) + print "The file name with correct extension is : %s"%(writtenFileName) + #! [PySnippet_MEDCouplingFieldDouble_WriteVTK_1] + import os + os.remove( writtenFileName ) + + return + + def testExample_MEDCouplingFieldDouble_MaxFields(self): + #! [PySnippet_MEDCouplingFieldDouble_MaxFields_1] + vals1 = [0.,2., 4.,6.] # for field 1 + vals2 = [2.,0., 6.,4.] # for field 2 + valsMax = [2.,2., 6.,6.] # expected max field + valsMin = [0.,0., 4.,4.] # expected min field + + # field 1 + valsArr1=DataArrayDouble(vals1,2,2) # 2 tuples per 2 components + field1 = MEDCouplingFieldDouble( ON_NODES ) + field1.setArray( valsArr1 ) + + # field 2 + valsArr2=DataArrayDouble(vals2,2,2) # 2 tuples per 2 components + field2 = MEDCouplingFieldDouble( ON_NODES ) + field2.setArray( valsArr2 ) + + # max field + fieldMax = MEDCouplingFieldDouble.MaxFields( field1, field2 ) + self.assertTrue( fieldMax.getArray().getValues() == valsMax ) + + # min field + fieldMin = MEDCouplingFieldDouble.MinFields( field1, field2 ) + self.assertTrue( fieldMin.getArray().getValues() == valsMin ) + #! [PySnippet_MEDCouplingFieldDouble_MaxFields_1] + + def testExample_MEDCouplingFieldDouble_MergeFields(self): + #! [PySnippet_MEDCouplingFieldDouble_MergeFields_1] + # mesh 1 + coords = [0.,2.,4.] + coordsArr=DataArrayDouble(coords,3,1) + mesh1=MEDCouplingCMesh() + mesh1.setCoords(coordsArr) + # field 1 + field1 = mesh1.fillFromAnalytic( ON_CELLS, 1, "x") + + # mesh 2 and field 2 + field2 = field1.cloneWithMesh( True ) + vec = [5.] + field2.getMesh().translate(vec) # translate mesh2 + field2.applyFunc("x + 5") # "translate" field2 + + # concatenate field1 and field2 + field3 = MEDCouplingFieldDouble.MergeFields( field1, field2 ) + field4 = MEDCouplingFieldDouble.MergeFields( [ field1, field2] ) + #! [PySnippet_MEDCouplingFieldDouble_MergeFields_1] + return + + def testExample_MEDCouplingFieldDouble_substractInPlaceDM(self): + #! [PySnippet_MEDCouplingFieldDouble_substractInPlaceDM_1] + coords1=[0.,1.,2.,3.] + coords2=[2.,1.,0.,3.] #0 <==> #2 + # mesh 1 + mesh1=MEDCouplingUMesh() + coordsArr=DataArrayDouble(coords1, 4, 1) + mesh1.setCoords(coordsArr) + mesh1.setMeshDimension(0) + mesh1.allocateCells(0) + mesh1.finishInsertingCells() + # mesh 2 + mesh2=mesh1.deepCpy() + mesh2.getCoords().setValues(coords2, 4, 1) + #! [PySnippet_MEDCouplingFieldDouble_substractInPlaceDM_1] + #! [PySnippet_MEDCouplingFieldDouble_substractInPlaceDM_2] + field1 = mesh1.fillFromAnalytic(ON_NODES,1,"x") # field1 values == coords1 + field2 = mesh2.fillFromAnalytic(ON_NODES,1,"x") # field2 values == coords2 + levOfCheck = 10 # nodes can be permuted + field1.substractInPlaceDM( field2, levOfCheck, 1e-13, 0 ) # values #0 and #2 must swap + #! [PySnippet_MEDCouplingFieldDouble_substractInPlaceDM_2] + #! [PySnippet_MEDCouplingFieldDouble_substractInPlaceDM_3] + field2.applyFunc( 1, 0.0 ) # all field2 values == 0.0 + self.assertTrue( field1.isEqual( field2, 1e-13, 1e-13 )) # field1 == field2 == 0.0 + #! [PySnippet_MEDCouplingFieldDouble_substractInPlaceDM_3] + return + + def testExample_MEDCouplingFieldDouble_changeUnderlyingMesh(self): + #! [PySnippet_MEDCouplingFieldDouble_changeUnderlyingMesh_1] + coords1=[0.,1.,2.,3.] + coords2=[2.,1.,0.,3.] #0 <==> #2 + # mesh 1 + mesh1=MEDCouplingUMesh() + coordsArr=DataArrayDouble(coords1, 4, 1) + mesh1.setCoords(coordsArr) + mesh1.setMeshDimension(0) + mesh1.allocateCells(0) + mesh1.finishInsertingCells() + # mesh 2 + mesh2=mesh1.deepCpy() + mesh2.getCoords().setValues(coords2, 4, 1) + #! [PySnippet_MEDCouplingFieldDouble_changeUnderlyingMesh_1] + #! [PySnippet_MEDCouplingFieldDouble_changeUnderlyingMesh_2] + field = mesh1.fillFromAnalytic(ON_NODES,1,"x") # field values == coords1 + levOfCheck = 10 # nodes can be permuted + field.changeUnderlyingMesh( mesh2, levOfCheck, 1e-13, 0 ) # values #0 and #2 must swap + self.assertTrue( field.getArray().getValues() == coords2 ) + #! [PySnippet_MEDCouplingFieldDouble_changeUnderlyingMesh_2] + return + + def testExample_MEDCouplingFieldDouble_applyFunc_same_nb_comp(self): + #! [PySnippet_MEDCouplingFieldDouble_applyFunc_same_nb_comp_1] + v = [1.,2., 3.,4.] + array = DataArrayDouble( v, 2, 2 ) # 2 tuples per 2 components + field = MEDCouplingFieldDouble( ON_CELLS ) + field.setArray( array ) + func = "IVec * v + JVec * w*w + 10" + field.applyFunc( 2, func ) + self.assertTrue( field.getNumberOfComponents() == 2 ) # 2 components remains + #! [PySnippet_MEDCouplingFieldDouble_applyFunc_same_nb_comp_1] + #! [PySnippet_MEDCouplingFieldDouble_applyFunc_same_nb_comp_2] + v2 = field.getArray().getValues() + self.assertAlmostEqual( v2[0], 10 + v[0], 13 ) # "10 + IVec * v" + self.assertAlmostEqual( v2[1], 10 + v[1]*v[1], 13 ) # "10 + JVec * v*v" + self.assertAlmostEqual( v2[2], 10 + v[2], 13 ) # "10 + IVec * v" + self.assertAlmostEqual( v2[3], 10 + v[3]*v[3], 13 ) # "10 + JVec * v*v" + #! [PySnippet_MEDCouplingFieldDouble_applyFunc_same_nb_comp_2] + return + + def testExample_MEDCouplingFieldDouble_applyFunc3(self): + #! [PySnippet_MEDCouplingFieldDouble_applyFunc3_1] + # create a 2D vector field + values = [1.,1., 2.,1.] + array = DataArrayDouble( values, 2, 2 ) # 2 tuples per 2 components + field = MEDCouplingFieldDouble( ON_CELLS ) + field.setArray( array ) + # transform the field to a 3D vector field + func = "IVec * b + JVec * a + KVec * sqrt( a*a + b*b ) + 10" + varNames=["a","b"] # names used to refer to X and Y components + field.applyFunc3( 3, varNames, func ) # require 3 components + self.assertTrue( field.getNumberOfComponents() == 3 ) # 3 components as required + #! [PySnippet_MEDCouplingFieldDouble_applyFunc3_1] + #! [PySnippet_MEDCouplingFieldDouble_applyFunc3_2] + vec1 = field.getArray().getTuple(1) # vector #1 + a,b = values[2], values[3] # initial components of the vector #1 + self.assertAlmostEqual( vec1[0], 10 + b, 13 ) # "10 + IVec * b" + self.assertAlmostEqual( vec1[1], 10 + a, 13 ) # "10 + JVec * a" + self.assertAlmostEqual( vec1[2], 10 + sqrt(a*a+b*b), 13 ) # "10 + KVec * sqrt( a*a + b*b )" + #! [PySnippet_MEDCouplingFieldDouble_applyFunc3_2] + return + + def testExample_MEDCouplingFieldDouble_applyFunc2(self): + #! [PySnippet_MEDCouplingFieldDouble_applyFunc2_1] + # create a 2D vector field + values = [1.,1., 2.,1.] + array = DataArrayDouble( values, 2, 2 ) # 2 tuples per 2 components + array.setInfoOnComponent(0,"a") # name used to refer to X component within a function + array.setInfoOnComponent(1,"b") # name used to refer to Y component within a function + field = MEDCouplingFieldDouble( ON_CELLS ) + field.setArray( array ) + # transform the field to a 3D vector field + func = "IVec * b + JVec * a + KVec * sqrt( a*a + b*b ) + 10" + field.applyFunc2( 3, func ) # require 3 components + self.assertTrue( field.getNumberOfComponents() == 3 ) # 3 components as required + #! [PySnippet_MEDCouplingFieldDouble_applyFunc2_1] + #! [PySnippet_MEDCouplingFieldDouble_applyFunc2_2] + vec1 = field.getArray().getTuple(1) # vector #1 + a,b = values[2], values[3] # initial components of the vector #1 + self.assertAlmostEqual( vec1[0], 10 + b, 13 ) # "10 + IVec * b" + self.assertAlmostEqual( vec1[1], 10 + a, 13 ) # "10 + JVec * a" + self.assertAlmostEqual( vec1[2], 10 + sqrt(a*a+b*b), 13 ) # "10 + KVec * sqrt( a*a + b*b )" + #! [PySnippet_MEDCouplingFieldDouble_applyFunc2_2] + return + + def testExample_MEDCouplingFieldDouble_applyFunc(self): + #! [PySnippet_MEDCouplingFieldDouble_applyFunc_1] + # create a 2D vector field + values = [1.,1., 2.,1.] + array = DataArrayDouble( values, 2, 2 ) # 2 tuples per 2 components + field = MEDCouplingFieldDouble( ON_CELLS ) + field.setArray( array ) + # transform the field to a 3D vector field + func = "IVec * b + JVec * a + KVec * sqrt( a*a + b*b ) + 10" + field.applyFunc( 3, func ) # require 3 components + self.assertTrue( field.getNumberOfComponents() == 3 ) # 3 components as required + #! [PySnippet_MEDCouplingFieldDouble_applyFunc_1] + #! [PySnippet_MEDCouplingFieldDouble_applyFunc_2] + vec1 = field.getArray().getTuple(1) # vector #1 + a,b = values[2], values[3] # initial components of the vector #1 + self.assertAlmostEqual( vec1[0], 10 + b, 13 ) # "10 + IVec * b" + self.assertAlmostEqual( vec1[1], 10 + a, 13 ) # "10 + JVec * a" + self.assertAlmostEqual( vec1[2], 10 + sqrt(a*a+b*b), 13 ) # "10 + KVec * sqrt( a*a + b*b )" + #! [PySnippet_MEDCouplingFieldDouble_applyFunc_2] + return + + def testExample_MEDCouplingFieldDouble_applyFunc_val(self): + #! [PySnippet_MEDCouplingFieldDouble_applyFunc_val_1] + coords = [0.,2.,4.] + coordsArr=DataArrayDouble(coords,3,1) + mesh=MEDCouplingCMesh() + mesh.setCoords(coordsArr,coordsArr) + field = MEDCouplingFieldDouble( ON_CELLS ) + field.setMesh( mesh ) + field.fillFromAnalytic(2,"IVec * x + JVec * y") # 2 components + #! [PySnippet_MEDCouplingFieldDouble_applyFunc_val_1] + #! [PySnippet_MEDCouplingFieldDouble_applyFunc_val_2] + newValue = 7. + field.applyFunc( 3, newValue ) # 3 components are required + self.assertTrue( field.getIJ(1,0) == newValue ) # a value is as expected + self.assertTrue( field.getNumberOfComponents() == 3 ) + self.assertTrue( field.getNumberOfTuples() == mesh.getNumberOfCells() ) + #! [PySnippet_MEDCouplingFieldDouble_applyFunc_val_2] + return + + def testExample_MEDCouplingFieldDouble_fillFromAnalytic3(self): + #! [PySnippet_MEDCouplingFieldDouble_fillFromAnalytic3_1] + coords = [0.,2.,4.,6.] # 6. is not used + x=DataArrayDouble(coords[:3],3,1) + y=DataArrayDouble(coords[:2],2,1) + mesh=MEDCouplingCMesh() + mesh.setCoords(x,y) + #! [PySnippet_MEDCouplingFieldDouble_fillFromAnalytic3_1] + #! [PySnippet_MEDCouplingFieldDouble_fillFromAnalytic3_2] + field = MEDCouplingFieldDouble( ON_CELLS ) + field.setMesh( mesh ) + func = "IVec * b + JVec * a + KVec * sqrt( a*a + b*b ) + 10" + varNames=["a","b"] # names used to refer to X and Y coord components + field.fillFromAnalytic3(3,varNames,func) + #! [PySnippet_MEDCouplingFieldDouble_fillFromAnalytic3_2] + #! [PySnippet_MEDCouplingFieldDouble_fillFromAnalytic3_3] + vals1 = field.getArray().getTuple(1) # values of the cell #1 + assert len( vals1 ) == 3 # 3 components in the field + # + bc = mesh.getBarycenterAndOwner() # func is applied to barycenters of cells + bc1 = bc.getTuple(1) # coordinates of the second point + # + dist = sqrt( bc1[0]*bc1[0] + bc1[1]*bc1[1] ) # "sqrt( a*a + b*b )" + self.assertAlmostEqual( vals1[0], 10 + bc1[1], 13 ) # "10 + IVec * b" + self.assertAlmostEqual( vals1[1], 10 + bc1[0], 13 ) # "10 + JVec * a" + self.assertAlmostEqual( vals1[2], 10 + dist , 13 ) # "10 + KVec * sqrt( a*a + b*b )" + #! [PySnippet_MEDCouplingFieldDouble_fillFromAnalytic3_3] + return + + def testExample_MEDCouplingFieldDouble_fillFromAnalytic2(self): + #! [PySnippet_MEDCouplingFieldDouble_fillFromAnalytic2_1] + coords = [0.,2.,4.] + x=DataArrayDouble(coords[:3],3,1) + y=DataArrayDouble(coords[:2],2,1) + x.setInfoOnComponent(0,"a") # name used to refer to X coordinate within a function + y.setInfoOnComponent(0,"b") # name used to refer to Y coordinate within a function + mesh=MEDCouplingCMesh() + mesh.setCoords(x,y) + #! [PySnippet_MEDCouplingFieldDouble_fillFromAnalytic2_1] + #! [PySnippet_MEDCouplingFieldDouble_fillFromAnalytic2_2] + field = MEDCouplingFieldDouble( ON_CELLS ) + field.setMesh( mesh ) + func = "IVec * b + JVec * a + KVec * sqrt( a*a + b*b ) + 10" + field.fillFromAnalytic2(3,func) + #! [PySnippet_MEDCouplingFieldDouble_fillFromAnalytic2_2] + #! [PySnippet_MEDCouplingFieldDouble_fillFromAnalytic2_3] + vals1 = field.getArray().getTuple(1) # values of the cell #1 + assert len( vals1 ) == 3 # 3 components in the field + # + bc = mesh.getBarycenterAndOwner() # func is applied to barycenters of cells + bc1 = bc.getTuple(1) # coordinates of the second point + # + dist = sqrt( bc1[0]*bc1[0] + bc1[1]*bc1[1] ) # "sqrt( a*a + b*b )" + self.assertAlmostEqual( vals1[0], 10 + bc1[1], 13 ) # "10 + IVec * b" + self.assertAlmostEqual( vals1[1], 10 + bc1[0], 13 ) # "10 + JVec * a" + self.assertAlmostEqual( vals1[2], 10 + dist , 13 ) # "10 + KVec * sqrt( a*a + b*b )" + #! [PySnippet_MEDCouplingFieldDouble_fillFromAnalytic2_3] + return + + def testExample_MEDCouplingFieldDouble_fillFromAnalytic(self): + #! [PySnippet_MEDCouplingFieldDouble_fillFromAnalytic_1] + coords = [0.,2.,4.] + x=DataArrayDouble(coords[:3],3,1) + y=DataArrayDouble(coords[:2],2,1) + mesh=MEDCouplingCMesh() + mesh.setCoords(x,y) + #! [PySnippet_MEDCouplingFieldDouble_fillFromAnalytic_1] + #! [PySnippet_MEDCouplingFieldDouble_fillFromAnalytic_2] + field = MEDCouplingFieldDouble( ON_CELLS ) + field.setMesh( mesh ) + func = "IVec * b + JVec * a + KVec * sqrt( a*a + b*b ) + 10" + field.fillFromAnalytic(3,func) + #! [PySnippet_MEDCouplingFieldDouble_fillFromAnalytic_2] + #! [PySnippet_MEDCouplingFieldDouble_fillFromAnalytic_3] + vals1 = field.getArray().getTuple(1) # values of the cell #1 + assert len( vals1 ) == 3 # 3 components in the field + # + bc = mesh.getBarycenterAndOwner() # func is applied to barycenters of cells + bc1 = bc.getTuple(1) # coordinates of the second point + # + dist = sqrt( bc1[0]*bc1[0] + bc1[1]*bc1[1] ) # "sqrt( a*a + b*b )" + self.assertAlmostEqual( vals1[0], 10 + bc1[1], 13 ) # "10 + IVec * b" + self.assertAlmostEqual( vals1[1], 10 + bc1[0], 13 ) # "10 + JVec * a" + self.assertAlmostEqual( vals1[2], 10 + dist , 13 ) # "10 + KVec * sqrt( a*a + b*b )" + #! [PySnippet_MEDCouplingFieldDouble_fillFromAnalytic_3] + return + + def testExample_MEDCouplingFieldDouble_getValueOn_time(self): + #! [PySnippet_MEDCouplingFieldDouble_getValueOn_time_1] + coords = [0.,2.,4.] + coordsArr=DataArrayDouble(coords,3,1) + mesh=MEDCouplingCMesh() + mesh.setCoords(coordsArr,coordsArr) + #! [PySnippet_MEDCouplingFieldDouble_getValueOn_time_1] + #! [PySnippet_MEDCouplingFieldDouble_getValueOn_time_2] + field = MEDCouplingFieldDouble( ON_CELLS, LINEAR_TIME ) + field.setMesh( mesh ) + field.fillFromAnalytic(1,"10") # all values == 10. + field.setEndArray( field.getArray() + field.getArray() ) # all values == 20. + time1, time2 = 1.1, 22. + field.setStartTime( time1, 0, 0 ) + field.setEndTime ( time2, 0, 0 ) + #! [PySnippet_MEDCouplingFieldDouble_getValueOn_time_2] + #! [PySnippet_MEDCouplingFieldDouble_getValueOn_time_3] + pos = [ 1., 1. ] # we are in 2D space + value = field.getValueOn( pos, 0.5*( time1 + time2 )) + self.assertTrue( value[0] == 0.5*( 10. + 20.)) + #! [PySnippet_MEDCouplingFieldDouble_getValueOn_time_3] + return + + def testExample_MEDCouplingFieldDouble_getValueOnMulti(self): + #! [PySnippet_MEDCouplingFieldDouble_getValueOnMulti_1] + coords = [0.,2.,4.] + coordsArr=DataArrayDouble(coords,3,1) + mesh=MEDCouplingCMesh() + mesh.setCoords(coordsArr,coordsArr) + field = mesh.fillFromAnalytic(ON_CELLS,1,"x+y") + #! [PySnippet_MEDCouplingFieldDouble_getValueOnMulti_1] + #! [PySnippet_MEDCouplingFieldDouble_getValueOnMulti_2] + bc = mesh.getBarycenterAndOwner() # field values are located at cell barycenters + valArray = field.getValueOnMulti( bc ) + self.assertTrue( valArray.isEqual( field.getArray(), 1e-13 )) + #! [PySnippet_MEDCouplingFieldDouble_getValueOnMulti_2] + return + + def testExample_MEDCouplingFieldDouble_getValueOn(self): + #! [PySnippet_MEDCouplingFieldDouble_getValueOn_1] + coords = [0.,2.,4.] + coordsArr=DataArrayDouble(coords,3,1) + mesh=MEDCouplingCMesh() + mesh.setCoords(coordsArr,coordsArr) + field = mesh.fillFromAnalytic(ON_CELLS,1,"x+y") + #! [PySnippet_MEDCouplingFieldDouble_getValueOn_1] + #! [PySnippet_MEDCouplingFieldDouble_getValueOn_2] + bc = mesh.getBarycenterAndOwner() # field values are located at cell barycenters + vals = [] # array to collect values returned by getValueOn() + for i,tupl in enumerate( bc ): + vals.extend( field.getValueOn( tupl ) ) + self.assertTrue( vals == field.getArray().getValues() ) + #! [PySnippet_MEDCouplingFieldDouble_getValueOn_2] + return + + def testExample_MEDCouplingFieldDouble_getValueOnPos(self): + #! [PySnippet_MEDCouplingFieldDouble_getValueOnPos_1] + coords = [0.,2.,4.] + coordsArr=DataArrayDouble(coords,3,1) + mesh=MEDCouplingCMesh() + mesh.setCoords(coordsArr,coordsArr) + field = mesh.fillFromAnalytic(ON_CELLS,1,"x+y") + #! [PySnippet_MEDCouplingFieldDouble_getValueOnPos_1] + #! [PySnippet_MEDCouplingFieldDouble_getValueOnPos_2] + val11 = field.getValueOnPos( 1,1,-1) + bc = mesh.getBarycenterAndOwner() # field values are located at cell barycenters + self.assertTrue( val11[0] == bc[3,0] + bc[3,1] ) + #! [PySnippet_MEDCouplingFieldDouble_getValueOnPos_2] + return + + def testExample_MEDCouplingFieldDouble_renumberNodes(self): + #! [PySnippet_MEDCouplingFieldDouble_renumberNodes_1] + coords = [0.,2.,4.] + coordsArr=DataArrayDouble(coords,3,1) + mesh=MEDCouplingCMesh() + mesh.setCoords(coordsArr,coordsArr) + mesh=mesh.buildUnstructured() + #! [PySnippet_MEDCouplingFieldDouble_renumberNodes_1] + #! [PySnippet_MEDCouplingFieldDouble_renumberNodes_2] + field = mesh.fillFromAnalytic(ON_NODES,2,"IVec*x+JVec*y") + values = field.getArray() + nodeCoords = mesh.getCoords() + self.assertTrue( values.isEqualWithoutConsideringStr( nodeCoords, 1e-13 )) + #! [PySnippet_MEDCouplingFieldDouble_renumberNodes_2] + #! [PySnippet_MEDCouplingFieldDouble_renumberNodes_3] + renumber = [8, 7, 6, 5, 4, 3, 2, 1, 0] + field.renumberNodes(renumber,False) + mesh2 = field.getMesh() # field now refers to another mesh + values = field.getArray() + nodeCoords = mesh2.getCoords() + self.assertTrue( values.isEqualWithoutConsideringStr( nodeCoords, 1e-13 )) + #! [PySnippet_MEDCouplingFieldDouble_renumberNodes_3] + return + + + def testExample_MEDCouplingFieldDouble_renumberCells(self): + #! [PySnippet_MEDCouplingFieldDouble_renumberCells_1] + coords = [0.,2.,4.] + coordsArr=DataArrayDouble(coords,3,1) + mesh=MEDCouplingCMesh() + mesh.setCoords(coordsArr,coordsArr) + mesh=mesh.buildUnstructured() + #! [PySnippet_MEDCouplingFieldDouble_renumberCells_1] + #! [PySnippet_MEDCouplingFieldDouble_renumberCells_2] + field = mesh.fillFromAnalytic(ON_CELLS,2,"IVec*x+JVec*y") + values = field.getArray() + bc = mesh.getBarycenterAndOwner() + self.assertTrue( values.isEqualWithoutConsideringStr( bc, 1e-13 )) + #! [PySnippet_MEDCouplingFieldDouble_renumberCells_2] + #! [PySnippet_MEDCouplingFieldDouble_renumberCells_3] + renumber = [ 3, 2, 1, 0 ] + field.renumberCells(renumber,False) + mesh2 = field.getMesh() # field now refers to another mesh + values = field.getArray() + bc = mesh2.getBarycenterAndOwner() + self.assertTrue( values.isEqualWithoutConsideringStr( bc, 1e-13 )) + #! [PySnippet_MEDCouplingFieldDouble_renumberCells_3] + return + + def testExample_MEDCouplingFieldDouble_buildNewTimeReprFromThis(self): + #! [PySnippet_MEDCouplingFieldDouble_buildNewTimeReprFromThis_1] + coords = [0.,2.,4.] + coordsArr=DataArrayDouble(coords,3,1) + mesh=MEDCouplingCMesh() + mesh.setCoords(coordsArr,coordsArr) + field1 = mesh.fillFromAnalytic(ON_NODES,1,"x+y") + self.assertTrue( field1.getTimeDiscretization() == ONE_TIME ) + #! [PySnippet_MEDCouplingFieldDouble_buildNewTimeReprFromThis_1] + #! [PySnippet_MEDCouplingFieldDouble_buildNewTimeReprFromThis_2] + field2 = field1.buildNewTimeReprFromThis(NO_TIME,False) + self.assertTrue( field2.getTimeDiscretization() == NO_TIME ) + #! [PySnippet_MEDCouplingFieldDouble_buildNewTimeReprFromThis_2] + return + + def testExample_MEDCouplingMesh_fillFromAnalytic3(self): + #! [PySnippet_MEDCouplingMesh_fillFromAnalytic3_1] + coords = [0.,2.,4.,6.] # 6. is not used + x=DataArrayDouble(coords[:3],3,1) + y=DataArrayDouble(coords[:2],2,1) + mesh=MEDCouplingCMesh() + mesh.setCoords(x,y) + #! [PySnippet_MEDCouplingMesh_fillFromAnalytic3_1] + #! [PySnippet_MEDCouplingMesh_fillFromAnalytic3_2] + func = "IVec * b + JVec * a + KVec * sqrt( a*a + b*b ) + 10" + varNames=["a","b"] # names used to refer to X and Y coord components + field=mesh.fillFromAnalytic3(ON_CELLS,3,varNames,func) + #! [PySnippet_MEDCouplingMesh_fillFromAnalytic3_2] + #! [PySnippet_MEDCouplingMesh_fillFromAnalytic3_3] + vals1 = field.getArray().getTuple(1) # values of the cell #1 + assert len( vals1 ) == 3 # 3 components in the field + # + bc = mesh.getBarycenterAndOwner() # func is applied to barycenters of cells + bc1 = bc.getTuple(1) # coordinates of the second point + # + dist = sqrt( bc1[0]*bc1[0] + bc1[1]*bc1[1] ) # "sqrt( a*a + b*b )" + self.assertAlmostEqual( vals1[0], 10 + bc1[1], 13 ) # "10 + IVec * b" + self.assertAlmostEqual( vals1[1], 10 + bc1[0], 13 ) # "10 + JVec * a" + self.assertAlmostEqual( vals1[2], 10 + dist , 13 ) # "10 + KVec * sqrt( a*a + b*b )" + #! [PySnippet_MEDCouplingMesh_fillFromAnalytic3_3] + return + + def testExample_MEDCouplingMesh_fillFromAnalytic2(self): + #! [PySnippet_MEDCouplingMesh_fillFromAnalytic2_1] + coords = [0.,2.,4.,6.] # 6. is not used + x=DataArrayDouble(coords[:3],3,1) + y=DataArrayDouble(coords[:2],2,1) + x.setInfoOnComponent(0,"a") # name used to refer to X coordinate within a function + y.setInfoOnComponent(0,"b") # name used to refer to Y coordinate within a function + mesh=MEDCouplingCMesh() + mesh.setCoords(x,y) + #! [PySnippet_MEDCouplingMesh_fillFromAnalytic2_1] + #! [PySnippet_MEDCouplingMesh_fillFromAnalytic2_2] + func = "IVec * b + JVec * a + KVec * sqrt( a*a + b*b ) + 10" + field=mesh.fillFromAnalytic2(ON_CELLS,3,func) + #! [PySnippet_MEDCouplingMesh_fillFromAnalytic2_2] + #! [PySnippet_MEDCouplingMesh_fillFromAnalytic2_3] + vals1 = field.getArray().getTuple(1) # values of the cell #1 + assert len( vals1 ) == 3 # 3 components in the field + # + bc = mesh.getBarycenterAndOwner() # func is applied to barycenters of cells + bc1 = bc.getTuple(1) # coordinates of the second point + # + dist = sqrt( bc1[0]*bc1[0] + bc1[1]*bc1[1] ) # "sqrt( a*a + b*b )" + self.assertAlmostEqual( vals1[0], 10 + bc1[1], 13 ) # "10 + IVec * b" + self.assertAlmostEqual( vals1[1], 10 + bc1[0], 13 ) # "10 + JVec * a" + self.assertAlmostEqual( vals1[2], 10 + dist , 13 ) # "10 + KVec * sqrt( a*a + b*b )" + #! [PySnippet_MEDCouplingMesh_fillFromAnalytic2_3] + return + + def testExample_MEDCouplingMesh_fillFromAnalytic(self): + #! [PySnippet_MEDCouplingMesh_fillFromAnalytic_1] + coords = [0.,2.,4.,6.] # 6. is not used + x=DataArrayDouble(coords[:3],3,1) + y=DataArrayDouble(coords[:2],2,1) + mesh=MEDCouplingCMesh() + mesh.setCoords(x,y) + #! [PySnippet_MEDCouplingMesh_fillFromAnalytic_1] + #! [PySnippet_MEDCouplingMesh_fillFromAnalytic_2] + func = "IVec * b + JVec * a + KVec * sqrt( a*a + b*b ) + 10" + field=mesh.fillFromAnalytic(ON_CELLS,3,func) + #! [PySnippet_MEDCouplingMesh_fillFromAnalytic_2] + #! [PySnippet_MEDCouplingMesh_fillFromAnalytic_3] + vals1 = field.getArray().getTuple(1) # values of the cell #1 + assert len( vals1 ) == 3 # 3 components in the field + # + bc = mesh.getBarycenterAndOwner() # func is applied to barycenters of cells + bc1 = bc.getTuple(1) # coordinates of the second point + # + dist = sqrt( bc1[0]*bc1[0] + bc1[1]*bc1[1] ) # "sqrt( a*a + b*b )" + self.assertAlmostEqual( vals1[0], 10 + bc1[1], 13 ) # "10 + IVec * b" + self.assertAlmostEqual( vals1[1], 10 + bc1[0], 13 ) # "10 + JVec * a" + self.assertAlmostEqual( vals1[2], 10 + dist , 13 ) # "10 + KVec * sqrt( a*a + b*b )" + #! [PySnippet_MEDCouplingMesh_fillFromAnalytic_3] + return + + def testExample_MEDCouplingCMesh_getCoordsAt(self): + #! [PySnippet_MEDCouplingCMesh_getCoordsAt_1] + coords = [1.,2.,4.] + x=DataArrayDouble(coords,3,1) + mesh=MEDCouplingCMesh() + mesh.setCoordsAt(0,x) + x2=mesh.getCoordsAt(0) + assert coords == x2.getValues() + #! [PySnippet_MEDCouplingCMesh_getCoordsAt_1] + return + + def testExample_MEDCouplingUMesh_areCellsIncludedIn(self): + #! [PySnippet_MEDCouplingUMesh_areCellsIncludedIn_1] + mesh1=MEDCouplingUMesh() + mesh1.setMeshDimension(2) + mesh1.allocateCells(5) + conn=[0,3,4,1, 1,2,4, 4,5,2, 6,7,4,3, 7,8,5,4] + mesh1.insertNextCell(NORM_QUAD4,4,conn[0:4]) # 0 + mesh1.insertNextCell(NORM_TRI3,3, conn[4:7]) # 1 + mesh1.insertNextCell(NORM_TRI3,3, conn[7:10]) # 2 + mesh1.insertNextCell(NORM_QUAD4,4,conn[10:14]) # 3 + mesh1.insertNextCell(NORM_QUAD4,4,conn[14:18]) # 4 + mesh1.finishInsertingCells() + coords=[-0.3,-0.3, 0.2,-0.3, 0.7,-0.3, -0.3,0.2, 0.2,0.2, 0.7,0.2, -0.3,0.7, 0.2,0.7, 0.7,0.7 ] + coordsArr=DataArrayDouble(coords,9,2) + mesh1.setCoords(coordsArr) + #! [PySnippet_MEDCouplingUMesh_areCellsIncludedIn_1] + #! [PySnippet_MEDCouplingUMesh_areCellsIncludedIn_2] + cells2 = [ 4,2,0 ] + mesh2 = mesh1.buildPartOfMySelf(cells2, True ) # even cells selected + #! [PySnippet_MEDCouplingUMesh_areCellsIncludedIn_2] + #! [PySnippet_MEDCouplingUMesh_areCellsIncludedIn_3] + compType = 0 # the strongest policy + isOk, corr2to1 = mesh1.areCellsIncludedIn( mesh2, compType ) + assert isOk # a larger mesh1 includes a smaller mesh2 + assert corr2to1.getValues() == cells2 + #! [PySnippet_MEDCouplingUMesh_areCellsIncludedIn_3] + #! [PySnippet_MEDCouplingUMesh_areCellsIncludedIn_4] + isOk, corr1to2 = mesh2.areCellsIncludedIn( mesh1, compType ) + assert not isOk # the smaller mesh2 does NOT include the larger mesh1 + assert corr1to2.getValues() == [2, 3, 1, 4, 0] + #! [PySnippet_MEDCouplingUMesh_areCellsIncludedIn_4] + + def testExample_MEDCouplingUMesh_findAndCorrectBadOriented3DExtrudedCells(self): + #! [PySnippet_MEDCouplingUMesh_findAndCorrectBadOriented3DExtrudedCells_1] + # 2D coordinates of 5 base nodes + coords=[-0.3,-0.3, 0.2,-0.3, 0.7,-0.3, -0.3,0.2, 0.2,0.2] + coordsArr=DataArrayDouble(coords,5,2) + # coordinates of 5 top nodes + coordsArr2 = coordsArr.deepCpy() + # 3D coordinates of base + top nodes + coordsArr = coordsArr.changeNbOfComponents( 3, 0 ) + coordsArr2 = coordsArr2.changeNbOfComponents( 3, 1 ) + coordsArr = DataArrayDouble.Aggregate([coordsArr,coordsArr2]) + # mesh + mesh=MEDCouplingUMesh() + mesh.setCoords(coordsArr) + mesh.setMeshDimension(3) + mesh.allocateCells(2) + # connectivity of reversed HEXA8 and PENTA6 + conn=[0,1,4,3, 5,6,9,8, 1,2,4, 6,7,9] + mesh.insertNextCell(NORM_HEXA8, 8,conn[0:0+8]) + mesh.insertNextCell(NORM_PENTA6,6,conn[8:8+6]) + mesh.finishInsertingCells() + #! [PySnippet_MEDCouplingUMesh_findAndCorrectBadOriented3DExtrudedCells_1] + #! [PySnippet_MEDCouplingUMesh_findAndCorrectBadOriented3DExtrudedCells_2] + fixedCells = mesh.findAndCorrectBadOriented3DExtrudedCells() + assert len( fixedCells ) == 2 # 2 cells fixed + fixedCells = mesh.findAndCorrectBadOriented3DExtrudedCells() + assert len( fixedCells ) == 0 # no bad cells + #! [PySnippet_MEDCouplingUMesh_findAndCorrectBadOriented3DExtrudedCells_2] + return + + def testExample_MEDCouplingUMesh_arePolyhedronsNotCorrectlyOriented(self): + #! [PySnippet_MEDCouplingUMesh_arePolyhedronsNotCorrectlyOriented_1] + # 2D coordinates of 5 base nodes + coords=[-0.3,-0.3, 0.2,-0.3, 0.7,-0.3, -0.3,0.2, 0.2,0.2] + coordsArr=DataArrayDouble(coords,5,2) + # coordinates of 5 top nodes + coordsArr2 = coordsArr.deepCpy() + # 3D coordinates of base + top nodes + coordsArr = coordsArr.changeNbOfComponents( 3, 0 ) + coordsArr2 = coordsArr2.changeNbOfComponents( 3, 1 ) + coordsArr = DataArrayDouble.Aggregate([coordsArr,coordsArr2]) + # mesh + mesh=MEDCouplingUMesh() + mesh.setCoords(coordsArr) + mesh.setMeshDimension(3) + mesh.allocateCells(2) + # connectivity of a HEXA8 + a reversed PENTA6 + conn=[0,3,4,1, 5,8,9,6, 1,2,4, 6,7,9] + mesh.insertNextCell(NORM_POLYHED, 8,conn[0:0+8]) # "extruded" polyhedron + mesh.insertNextCell(NORM_POLYHED,6,conn[8:8+6]) + mesh.finishInsertingCells() + # fix connectivity of NORM_POLYHED's + mesh.convertExtrudedPolyhedra() + #! [PySnippet_MEDCouplingUMesh_arePolyhedronsNotCorrectlyOriented_1] + #! [PySnippet_MEDCouplingUMesh_arePolyhedronsNotCorrectlyOriented_2] + badCells = mesh.arePolyhedronsNotCorrectlyOriented() + assert len( badCells ) == 1 # one polyhedron is KO + # fix invalid rolyherdons + mesh.orientCorrectlyPolyhedrons() + # re-check the orientation + badCells = mesh.arePolyhedronsNotCorrectlyOriented() + assert len( badCells ) == 0 # connectivity is OK + #! [PySnippet_MEDCouplingUMesh_arePolyhedronsNotCorrectlyOriented_2] + return + + def testExample_MEDCouplingUMesh_are2DCellsNotCorrectlyOriented(self): + #! [PySnippet_MEDCouplingUMesh_are2DCellsNotCorrectlyOriented_1] + mesh=MEDCouplingUMesh() + mesh.setMeshDimension(2) + mesh.allocateCells(5) + conn=[0,3,4,1, 1,2,4, 4,5,2, 6,7,4,3, 7,8,5,4] + mesh.insertNextCell(NORM_QUAD4,4,conn[0:4]) # 0 + mesh.insertNextCell(NORM_TRI3,3, conn[4:7]) # 1 + mesh.insertNextCell(NORM_TRI3,3, conn[7:10]) # 2 + mesh.insertNextCell(NORM_QUAD4,4,conn[10:14]) # 3 + mesh.insertNextCell(NORM_QUAD4,4,conn[14:18]) # 4 + mesh.finishInsertingCells() + coords=[-0.3,-0.3, 0.2,-0.3, 0.7,-0.3, -0.3,0.2, 0.2,0.2, 0.7,0.2, -0.3,0.7, 0.2,0.7, 0.7,0.7 ] + coordsArr=DataArrayDouble(coords,9,2) + mesh.setCoords(coordsArr) + mesh.changeSpaceDimension(3) + #! [PySnippet_MEDCouplingUMesh_are2DCellsNotCorrectlyOriented_1] + #! [PySnippet_MEDCouplingUMesh_are2DCellsNotCorrectlyOriented_2] + vec = [0.,0.,-1.] + badCellIds=mesh.are2DCellsNotCorrectlyOriented( vec, False ) + assert len( badCellIds ) == 1 # one cell is reversed + # fix orientation + mesh.orientCorrectly2DCells( vec, False ) + # re-check orientation + badCellIds=mesh.are2DCellsNotCorrectlyOriented( vec, False ) + assert len( badCellIds ) == 0 # the orientation is OK + #! [PySnippet_MEDCouplingUMesh_are2DCellsNotCorrectlyOriented_2] + return + + def testExample_MEDCouplingUMesh_getCellsContainingPoints(self): + #! [PySnippet_MEDCouplingUMesh_getCellsContainingPoints_1] + mesh=MEDCouplingUMesh() + mesh.setMeshDimension(2) + mesh.allocateCells(5) + conn=[0,3,4,1, 1,2,4, 4,5,2, 6,7,4,3, 7,8,5,4] + mesh.insertNextCell(NORM_QUAD4,4,conn[0:4]) # 0 + mesh.insertNextCell(NORM_TRI3,3, conn[4:7]) # 1 + mesh.insertNextCell(NORM_TRI3,3, conn[7:10]) # 2 + mesh.insertNextCell(NORM_QUAD4,4,conn[10:14]) # 3 + mesh.insertNextCell(NORM_QUAD4,4,conn[14:18]) # 4 + mesh.finishInsertingCells() + coords=[-0.3,-0.3, 0.2,-0.3, 0.7,-0.3, -0.3,0.2, 0.2,0.2, 0.7,0.2, -0.3,0.7, 0.2,0.7, 0.7,0.7 ] + coordsArr=DataArrayDouble(coords,9,2) + mesh.setCoords(coordsArr) + #! [PySnippet_MEDCouplingUMesh_getCellsContainingPoints_1] + #! [PySnippet_MEDCouplingUMesh_getCellsContainingPoints_2] + pos = [ 10., 10, # point out of the mesh + 0.3, 0.3, # point located somewhere inside the mesh + coords[2], coords[3]] # point at the node #1 + eps = 1e-4 # ball radius + cells,cellsIndex=mesh.getCellsContainingPoints( pos, 3, eps ) + assert cells.getValues() == [4, 0, 1] + assert cellsIndex.getValues() == [0, 0, 1, 3] + #! [PySnippet_MEDCouplingUMesh_getCellsContainingPoints_2] + return + + + def testExample_MEDCouplingUMesh_getCellsContainingPoint(self): + #! [PySnippet_MEDCouplingUMesh_getCellsContainingPoint_1] + mesh=MEDCouplingUMesh() + mesh.setMeshDimension(2) + mesh.allocateCells(5) + conn=[0,3,4,1, 1,2,4, 4,5,2, 6,7,4,3, 7,8,5,4] + mesh.insertNextCell(NORM_QUAD4,4,conn[0:4]) + mesh.insertNextCell(NORM_TRI3,3, conn[4:7]) + mesh.insertNextCell(NORM_TRI3,3, conn[7:10]) + mesh.insertNextCell(NORM_QUAD4,4,conn[10:14]) + mesh.insertNextCell(NORM_QUAD4,4,conn[14:18]) + mesh.finishInsertingCells() + coords=[-0.3,-0.3, 0.2,-0.3, 0.7,-0.3, -0.3,0.2, 0.2,0.2, 0.7,0.2, -0.3,0.7, 0.2,0.7, 0.7,0.7 ] + coordsArr=DataArrayDouble(coords,9,2) + mesh.setCoords(coordsArr) + #! [PySnippet_MEDCouplingUMesh_getCellsContainingPoint_1] + #! [PySnippet_MEDCouplingUMesh_getCellsContainingPoint_2] + pos4 = coords[ 4*2 : ] # coordinates of the node #4 + eps = 1e-4 # ball radius + pos = [ pos4[0]+eps, pos4[1]-eps ] # ball center + cellIds=mesh.getCellsContainingPoint( pos, eps ) + assert len( cellIds ) == mesh.getNumberOfCells() + #! [PySnippet_MEDCouplingUMesh_getCellsContainingPoint_2] + return + + + def testExample_MEDCouplingUMesh_buildPartOrthogonalField(self): + #! [PySnippet_MEDCouplingUMesh_buildPartOrthogonalField_1] + mesh=MEDCouplingUMesh() + mesh.setMeshDimension(2) + mesh.allocateCells(5) + conn=[0,3,4,1, 1,2,4, 4,5,2, 6,7,4,3, 7,8,5,4] + mesh.insertNextCell(NORM_QUAD4,4,conn[0:4]) # 0 + mesh.insertNextCell(NORM_TRI3,3, conn[4:7]) # 1 + mesh.insertNextCell(NORM_TRI3,3, conn[7:10]) # 2 + mesh.insertNextCell(NORM_QUAD4,4,conn[10:14]) # 3 + mesh.insertNextCell(NORM_QUAD4,4,conn[14:18]) # 4 + mesh.finishInsertingCells() + coords=[-0.3,-0.3, 0.2,-0.3, 0.7,-0.3, -0.3,0.2, 0.2,0.2, 0.7,0.2, -0.3,0.7, 0.2,0.7, 0.7,0.7 ] + coordsArr=DataArrayDouble(coords,9,2) + mesh.setCoords(coordsArr) + #! [PySnippet_MEDCouplingUMesh_buildPartOrthogonalField_1] + #! [PySnippet_MEDCouplingUMesh_buildPartOrthogonalField_2] + part = DataArrayInt([1,2,3,4],4,1) # cell #0 is omitted + vecField=mesh.buildPartOrthogonalField( part ) + vecArr = vecField.getArray() + assert len( vecArr ) == len( part ) + assert vecArr.getNumberOfComponents() == 3 + #! [PySnippet_MEDCouplingUMesh_buildPartOrthogonalField_2] + return + + def testExample_MEDCouplingUMesh_getPartMeasureField(self): + #! [PySnippet_MEDCouplingUMesh_getPartMeasureField_1] + mesh=MEDCouplingUMesh() + mesh.setMeshDimension(2) + mesh.allocateCells(5) + conn=[0,3,4,1, 1,2,4, 4,5,2, 6,7,4,3, 7,8,5,4] + mesh.insertNextCell(NORM_QUAD4,4,conn[0:4]) # 0 + mesh.insertNextCell(NORM_TRI3,3, conn[4:7]) # 1 + mesh.insertNextCell(NORM_TRI3,3, conn[7:10]) # 2 + mesh.insertNextCell(NORM_QUAD4,4,conn[10:14]) # 3 + mesh.insertNextCell(NORM_QUAD4,4,conn[14:18]) # 4 + mesh.finishInsertingCells() + coords=[-0.3,-0.3, 0.2,-0.3, 0.7,-0.3, -0.3,0.2, 0.2,0.2, 0.7,0.2, -0.3,0.7, 0.2,0.7, 0.7,0.7 ] + coordsArr=DataArrayDouble(coords,9,2) + mesh.setCoords(coordsArr) + #! [PySnippet_MEDCouplingUMesh_getPartMeasureField_1] + #! [PySnippet_MEDCouplingUMesh_getPartMeasureField_2] + isAbs = True + part = DataArrayInt([1,2,3,4],4,1) # cell #0 is omitted + areaArr=mesh.getPartMeasureField( isAbs, part ) + assert areaArr[0] > 0 # orientation ignored + areaArr=mesh.getPartMeasureField( not isAbs, part ) + assert areaArr[0] < 0 # orientation considered + assert len( areaArr ) == len( part ) + #! [PySnippet_MEDCouplingUMesh_getPartMeasureField_2] + #! [PySnippet_MEDCouplingUMesh_getPartMeasureField_3] + part = DataArrayInt([1,2,3,4],4,1) # cell #0 is omitted + baryCenters = mesh.getPartBarycenterAndOwner( part ) + assert len( baryCenters ) == len( part ) + assert baryCenters.getNumberOfComponents() == mesh.getSpaceDimension() + #! [PySnippet_MEDCouplingUMesh_getPartMeasureField_3] + return + + def testExample_MEDCouplingUMesh_getCellsInBoundingBox(self): + #! [PySnippet_MEDCouplingUMesh_getCellsInBoundingBox_1] + mesh=MEDCouplingUMesh() + mesh.setMeshDimension(2) + coords=[0.,0., 0.,1., 1.,1] + coordsArr=DataArrayDouble(coords,3,2) + mesh.setCoords(coordsArr) + mesh.allocateCells(1) + conn=[0,1,2] + mesh.insertNextCell(NORM_TRI3,3,conn) + mesh.finishInsertingCells() + #! [PySnippet_MEDCouplingUMesh_getCellsInBoundingBox_1] + #! [PySnippet_MEDCouplingUMesh_getCellsInBoundingBox_2] + bbox = [1., 1., 1.001,1.001] # xMin, xMax, yMin, yMax + cellsInBox = mesh.getCellsInBoundingBox( bbox, 0.0 ) + assert cellsInBox.getValues() == [] + cellsInBox = mesh.getCellsInBoundingBox( bbox, 0.1 ) + assert cellsInBox.getValues() == [0] + #! [PySnippet_MEDCouplingUMesh_getCellsInBoundingBox_2] + + + def testExample_MEDCouplingUMesh_renumberNodesInConn(self): + #! [PySnippet_MEDCouplingUMesh_renumberNodesInConn_1] + mesh=MEDCouplingUMesh() + mesh.setMeshDimension(2) + mesh.allocateCells(1) + conn=[4,3,2,1] + mesh.insertNextCell(NORM_QUAD4,4,conn[0:4]) + mesh.finishInsertingCells() + #! [PySnippet_MEDCouplingUMesh_renumberNodesInConn_1] + #! [PySnippet_MEDCouplingUMesh_renumberNodesInConn_2] + old2newIds = [-1,3,2,1,0] + mesh.renumberNodesInConn( old2newIds ) + nodes0 = mesh.getNodeIdsOfCell( 0 ) + assert nodes0 == [0,1,2,3] + #! [PySnippet_MEDCouplingUMesh_renumberNodesInConn_2] + return + + + def testExample_MEDCouplingUMesh_renumberNodes(self): + #! [PySnippet_MEDCouplingUMesh_renumberNodes_1] + mesh=MEDCouplingUMesh() + mesh.setMeshDimension(2) + coords=[-0.3,-0.3, 0.2,-0.3, 0.7,-0.3, -0.3,0.3] + coordsArr=DataArrayDouble(coords,4,2) + mesh.setCoords(coordsArr) + mesh.allocateCells(0) + mesh.finishInsertingCells() + #! [PySnippet_MEDCouplingUMesh_renumberNodes_1] + #! [PySnippet_MEDCouplingUMesh_renumberNodes_2] + mesh.renumberNodes([ 2,1,0,-1 ], 3) + coordsArr = mesh.getCoords() # get a shorten array + assert coordsArr.getValues() == [0.7,-0.3, 0.2,-0.3, -0.3,-0.3] + #! [PySnippet_MEDCouplingUMesh_renumberNodes_2] + #! [PySnippet_MEDCouplingUMesh_renumberNodes_3] + coordsArr.setValues(coords,4,2) # restore old nodes + mesh.renumberNodes2([ 2,1,0,2 ], 3) + coordsArr = mesh.getCoords() # get a shorten array + assert coordsArr.getValues() == [0.7,-0.3, 0.2,-0.3, -0.3,0.0] + #! [PySnippet_MEDCouplingUMesh_renumberNodes_3] + return + + def testExample_MEDCouplingUMesh_findBoundaryNodes(self): + #! [PySnippet_MEDCouplingUMesh_findBoundaryNodes_1] + mesh=MEDCouplingUMesh() + mesh.setMeshDimension(2) + mesh.allocateCells(5) + conn=[0,3,4,1, 1,4,2, 4,5,2, 6,7,4,3, 7,8,5,4] + mesh.insertNextCell(NORM_QUAD4,4,conn[0:4]) + mesh.insertNextCell(NORM_TRI3,3, conn[4:7]) + mesh.insertNextCell(NORM_TRI3,3, conn[7:10]) + mesh.insertNextCell(NORM_QUAD4,4,conn[10:14]) + mesh.insertNextCell(NORM_QUAD4,4,conn[14:18]) + mesh.finishInsertingCells() + coords=[-0.3,-0.3, 0.2,-0.3, 0.7,-0.3, -0.3,0.2, 0.2,0.2, 0.7,0.2, -0.3,0.7, 0.2,0.7, 0.7,0.7 ] + coordsArr=DataArrayDouble(coords,9,2) + mesh.setCoords(coordsArr) + #! [PySnippet_MEDCouplingUMesh_findBoundaryNodes_1] + #! [PySnippet_MEDCouplingUMesh_findBoundaryNodes_2] + nodeIdsArr=mesh.findBoundaryNodes() + assert nodeIdsArr.getNumberOfTuples() == mesh.getNumberOfNodes() - 1 + #! [PySnippet_MEDCouplingUMesh_findBoundaryNodes_2] + return + + def testExample_MEDCouplingUMesh_buildBoundaryMesh(self): + #! [PySnippet_MEDCouplingUMesh_buildBoundaryMesh_1] + mesh=MEDCouplingUMesh() + mesh.setMeshDimension(2) + mesh.allocateCells(5) + conn=[0,3,4,1, 1,4,2, 4,5,2, 6,7,4,3, 7,8,5,4] + mesh.insertNextCell(NORM_QUAD4,4,conn[0:4]) + mesh.insertNextCell(NORM_TRI3,3, conn[4:7]) + mesh.insertNextCell(NORM_TRI3,3, conn[7:10]) + mesh.insertNextCell(NORM_QUAD4,4,conn[10:14]) + mesh.insertNextCell(NORM_QUAD4,4,conn[14:18]) + mesh.finishInsertingCells() + coords=[-0.3,-0.3, 0.2,-0.3, 0.7,-0.3, -0.3,0.2, 0.2,0.2, 0.7,0.2, -0.3,0.7, 0.2,0.7, 0.7,0.7 ] + coordsArr=DataArrayDouble(coords,9,2) + mesh.setCoords(coordsArr) + #! [PySnippet_MEDCouplingUMesh_buildBoundaryMesh_1] + #! [PySnippet_MEDCouplingUMesh_buildBoundaryMesh_2] + mesh1=mesh.buildBoundaryMesh(True) + mesh2=mesh.buildBoundaryMesh(False) + assert coordsArr.isEqual( mesh1.getCoords(), 1e-13 ) # same nodes + assert not coordsArr.isEqual( mesh2.getCoords(), 1e-13 ) # different nodes + #! [PySnippet_MEDCouplingUMesh_buildBoundaryMesh_2] + return + + def testExample_MEDCouplingUMesh_buildFacePartOfMySelfNode(self): + #! [PySnippet_MEDCouplingUMesh_buildFacePartOfMySelfNode_1] + mesh=MEDCouplingUMesh() + mesh.setMeshDimension(2) + mesh.allocateCells(5) + conn=[0,3,4,1, 1,4,2, 4,5,2, 6,7,4,3, 7,8,5,4] + mesh.insertNextCell(NORM_QUAD4,4,conn[0:4]) # 0 + mesh.insertNextCell(NORM_TRI3,3, conn[4:7]) # 1 + mesh.insertNextCell(NORM_TRI3,3, conn[7:10]) # 2 + mesh.insertNextCell(NORM_QUAD4,4,conn[10:14]) # 3 + mesh.insertNextCell(NORM_QUAD4,4,conn[14:18]) # 4 + mesh.finishInsertingCells() + coords=[-0.3,-0.3, 0.2,-0.3, 0.7,-0.3, -0.3,0.2, 0.2,0.2, 0.7,0.2, -0.3,0.7, 0.2,0.7, 0.7,0.7 ] + coordsArr=DataArrayDouble(coords,9,2) + mesh.setCoords(coordsArr) + #! [PySnippet_MEDCouplingUMesh_buildFacePartOfMySelfNode_1] + #! [PySnippet_MEDCouplingUMesh_buildFacePartOfMySelfNode_2] + nodeIds = mesh.getNodeIdsOfCell( 0 ) + allNodes = True + mesh1 = mesh.buildFacePartOfMySelfNode( nodeIds, allNodes ) + assert mesh1.getNumberOfCells() == 4 # 4 segments bounding QUAD4 #0 only + mesh2 = mesh.buildFacePartOfMySelfNode( nodeIds, not allNodes ) + assert mesh2.getNumberOfCells() > 4 # more segments added + #! [PySnippet_MEDCouplingUMesh_buildFacePartOfMySelfNode_2] + return + + + def testExample_MEDCouplingUMesh_buildPartOfMySelfNode(self): + #! [PySnippet_MEDCouplingUMesh_buildPartOfMySelfNode_1] + mesh=MEDCouplingUMesh() + mesh.setMeshDimension(2) + mesh.allocateCells(5) + conn=[0,3,4,1, 1,4,2, 4,5,2, 6,7,4,3, 7,8,5,4] + mesh.insertNextCell(NORM_QUAD4,4,conn[0:4]) # 0 + mesh.insertNextCell(NORM_TRI3,3, conn[4:7]) # 1 + mesh.insertNextCell(NORM_TRI3,3, conn[7:10]) # 2 + mesh.insertNextCell(NORM_QUAD4,4,conn[10:14]) # 3 + mesh.insertNextCell(NORM_QUAD4,4,conn[14:18]) # 4 + mesh.finishInsertingCells() + coords=[-0.3,-0.3, 0.2,-0.3, 0.7,-0.3, -0.3,0.2, 0.2,0.2, 0.7,0.2, -0.3,0.7, 0.2,0.7, 0.7,0.7 ] + coordsArr=DataArrayDouble(coords,9,2) + mesh.setCoords(coordsArr) + #! [PySnippet_MEDCouplingUMesh_buildPartOfMySelfNode_1] + #! [PySnippet_MEDCouplingUMesh_buildPartOfMySelfNode_2] + nodeIds = mesh.getNodeIdsOfCell( 0 ) + allNodes = True + mesh1 = mesh.buildPartOfMySelfNode( nodeIds, allNodes ) + mesh2 = mesh.buildPartOfMySelfNode( nodeIds, not allNodes ) + assert mesh1.getNumberOfCells() == 1 # cell #0 is found only + assert mesh2.getNumberOfCells() == mesh.getNumberOfCells() # all cells are found + #! [PySnippet_MEDCouplingUMesh_buildPartOfMySelfNode_2] + return + + + def testExample_MEDCouplingUMesh_getCellIdsLyingOnNodes(self): + #! [PySnippet_MEDCouplingUMesh_getCellIdsLyingOnNodes_1] + mesh=MEDCouplingUMesh() + mesh.setMeshDimension(2) + mesh.allocateCells(5) + conn=[0,3,4,1, 1,4,2, 4,5,2, 6,7,4,3, 7,8,5,4] + mesh.insertNextCell(NORM_QUAD4,4,conn[0:4]) # 0 + mesh.insertNextCell(NORM_TRI3,3, conn[4:7]) # 1 + mesh.insertNextCell(NORM_TRI3,3, conn[7:10]) # 2 + mesh.insertNextCell(NORM_QUAD4,4,conn[10:14]) # 3 + mesh.insertNextCell(NORM_QUAD4,4,conn[14:18]) # 4 + mesh.finishInsertingCells() + coords=[-0.3,-0.3, 0.2,-0.3, 0.7,-0.3, -0.3,0.2, 0.2,0.2, 0.7,0.2, -0.3,0.7, 0.2,0.7, 0.7,0.7 ] + coordsArr=DataArrayDouble(coords,9,2) + mesh.setCoords(coordsArr) + #! [PySnippet_MEDCouplingUMesh_getCellIdsLyingOnNodes_1] + #! [PySnippet_MEDCouplingUMesh_getCellIdsLyingOnNodes_2] + nodeIds = mesh.getNodeIdsOfCell( 0 ) + allNodes = True + cellIdsArr1 = mesh.getCellIdsLyingOnNodes( nodeIds, allNodes ) + cellIdsArr2 = mesh.getCellIdsLyingOnNodes( nodeIds, not allNodes ) + assert cellIdsArr1.getNumberOfTuples() == 1 # cell #0 is found only + assert cellIdsArr2.getNumberOfTuples() == mesh.getNumberOfCells() # all cells are found + #! [PySnippet_MEDCouplingUMesh_getCellIdsLyingOnNodes_2] + return + + + def testExample_MEDCouplingUMesh_getCellIdsFullyIncludedInNodeIds(self): + #! [PySnippet_MEDCouplingUMesh_getCellIdsFullyIncludedInNodeIds_1] + mesh=MEDCouplingUMesh() + mesh.setMeshDimension(2) + mesh.allocateCells(5) + conn=[0,3,4,1, 1,4,2, 4,5,2, 6,7,4,3, 7,8,5,4] + mesh.insertNextCell(NORM_QUAD4,4,conn[0:4]) + mesh.insertNextCell(NORM_TRI3,3, conn[4:7]) + mesh.insertNextCell(NORM_TRI3,3, conn[7:10]) + mesh.insertNextCell(NORM_QUAD4,4,conn[10:14]) + mesh.insertNextCell(NORM_QUAD4,4,conn[14:18]) + mesh.finishInsertingCells() + coords=[-0.3,-0.3, 0.2,-0.3, 0.7,-0.3, -0.3,0.2, 0.2,0.2, 0.7,0.2, -0.3,0.7, 0.2,0.7, 0.7,0.7 ] + coordsArr=DataArrayDouble(coords,9,2) + mesh.setCoords(coordsArr) + #! [PySnippet_MEDCouplingUMesh_getCellIdsFullyIncludedInNodeIds_1] + #! [PySnippet_MEDCouplingUMesh_getCellIdsFullyIncludedInNodeIds_2] + cellIds = [1,2] + nodeIds = mesh.getNodeIdsOfCell( cellIds[0] ) + nodeIds += mesh.getNodeIdsOfCell( cellIds[1] ) + cellIdsArr = mesh.getCellIdsFullyIncludedInNodeIds( nodeIds ) + assert cellIdsArr.getValues() == cellIds + #! [PySnippet_MEDCouplingUMesh_getCellIdsFullyIncludedInNodeIds_2] + return + + + def testExample_MEDCouplingUMesh_buildPartOfMySelf(self): + #! [PySnippet_MEDCouplingUMesh_buildPartOfMySelf_1] + mesh=MEDCouplingUMesh() + mesh.setMeshDimension(2) + mesh.allocateCells(5) + conn=[0,3,4,1, 1,4,2, 4,5,2, 6,7,4,3, 7,8,5,4] + mesh.insertNextCell(NORM_QUAD4,4,conn[0:4]) # 0 + mesh.insertNextCell(NORM_TRI3,3, conn[4:7]) # 1 + mesh.insertNextCell(NORM_TRI3,3, conn[7:10]) # 2 + mesh.insertNextCell(NORM_QUAD4,4,conn[10:14]) # 3 + mesh.insertNextCell(NORM_QUAD4,4,conn[14:18]) # 4 + mesh.finishInsertingCells() + coords=[-0.3,-0.3, 0.2,-0.3, 0.7,-0.3, -0.3,0.2, 0.2,0.2, 0.7,0.2, -0.3,0.7, 0.2,0.7, 0.7,0.7 ] + coordsArr=DataArrayDouble(coords,9,2) + mesh.setCoords(coordsArr) + #! [PySnippet_MEDCouplingUMesh_buildPartOfMySelf_1] + #! [PySnippet_MEDCouplingUMesh_buildPartOfMySelf_2] + cellIds=[1,2] + mesh2=mesh.buildPartOfMySelf(cellIds, True) + mesh3=mesh.buildPartOfMySelf(cellIds, False) + coordsArr2 = mesh2.getCoords() + assert coordsArr.isEqual( coordsArr2, 1e-13 ) # same nodes + coordsArr3 = mesh3.getCoords() + assert not coordsArr.isEqual( coordsArr3, 1e-13 ) # different nodes + assert mesh2.getNodeIdsOfCell(0) == mesh.getNodeIdsOfCell( cellIds[0]) # cell #1 was copied + assert mesh2.getNodeIdsOfCell(1) == mesh.getNodeIdsOfCell( cellIds[1]) # cell #2 was copied + #! [PySnippet_MEDCouplingUMesh_buildPartOfMySelf_2] + return + + def testExample_MEDCouplingUMesh_mergeNodes(self): + #! [PySnippet_MEDCouplingUMesh_mergeNodes_1] + mesh=MEDCouplingUMesh() + mesh.setMeshDimension(2) + mesh.allocateCells(5) + conn=[0,3,4,1, 1,4,2, 4,5,2] + mesh.insertNextCell(NORM_QUAD4,4,conn[0:4]) + mesh.insertNextCell(NORM_TRI3,3, conn[4:7]) + mesh.insertNextCell(NORM_TRI3,3, conn[7:10]) + mesh.finishInsertingCells() + coords=[0.3,-0.301, # 0 + 0.2,-0.3, # 1 + 0.3,-0.302, # 2 ~~ 0 + 1.1,0.0, # 3 + 1.1,0.0, # 4 == 3 + 0.3,-0.303]# 5 ~~ 0 + coordsArr=DataArrayDouble(coords,6,2) + mesh.setCoords(coordsArr) + #! [PySnippet_MEDCouplingUMesh_mergeNodes_1] + #! [PySnippet_MEDCouplingUMesh_mergeNodes_2] + arr,areNodesMerged,newNbOfNodes=mesh.mergeNodes(0.004) + assert arr.getValues() == [0, 1, 0, 2, 2, 0] + assert areNodesMerged + assert newNbOfNodes == 3 + #! [PySnippet_MEDCouplingUMesh_mergeNodes_2] + #! [PySnippet_MEDCouplingUMesh_mergeNodes_3] + baryCoords2 = coords[2*2:] # initial coordinates of node #2 + coordsArr = mesh.getCoords() # retrieve a new shorten coord array + self.assertNotAlmostEqual( baryCoords2[1], coordsArr.getIJ(0,1), 13 ) # Y of node #0 differs from that of baryCoords2 + # restore coordinates + coordsArr = DataArrayDouble(coords,6,2) + mesh.setCoords(coordsArr) + # call mergeNodes2() + mesh.mergeNodes2(0.004) + coordsArr = mesh.getCoords() # retrieve a new shorten coord array + self.assertAlmostEqual( baryCoords2[1], coordsArr.getIJ(0,1), 13 ) # Y of node #0 equals to that of baryCoords2 + #! [PySnippet_MEDCouplingUMesh_mergeNodes_3] + return + + def testExample_MEDCouplingUMesh_zipConnectivityTraducer(self): + #! [PySnippet_MEDCouplingUMesh_zipConnectivityTraducer_1] + mesh=MEDCouplingUMesh() + mesh.setMeshDimension(2) + mesh.allocateCells(5) + conn=[0,3,4,1, 1,4,2] + mesh.insertNextCell(NORM_QUAD4,4,conn[0:4]) # 0 + mesh.insertNextCell(NORM_TRI3,3, conn[4:7]) # 1 + mesh.insertNextCell(NORM_TRI3,3, conn[4:7]) # 2 == 1 + mesh.insertNextCell(NORM_QUAD4,4,conn[0:4]) # 3 == 0 + mesh.insertNextCell(NORM_QUAD4,4,conn[2:4]+conn[0:2]) # 4 ~~ 0 + mesh.finishInsertingCells() + coords=[-0.3,-0.3, 0.2,-0.3, 0.7,-0.3, -0.3,0.2, 0.2,0.2, 0.7,0.2, -0.3,0.7, 0.2,0.7, 0.7,0.7 ] + coordsArr=DataArrayDouble(coords,9,2) + mesh.setCoords(coordsArr) + #! [PySnippet_MEDCouplingUMesh_zipConnectivityTraducer_1] + #! [PySnippet_MEDCouplingUMesh_zipConnectivityTraducer_2] + oldNbCells = mesh.getNumberOfCells() + arr = mesh.zipConnectivityTraducer(0) + assert mesh.getNumberOfCells() == oldNbCells-2 + assert arr.getValues() == [0, 1, 1, 0, 2] + #! [PySnippet_MEDCouplingUMesh_zipConnectivityTraducer_2] + return + + def testExample_MEDCouplingUMesh_zipCoordsTraducer(self): + #! [PySnippet_MEDCouplingUMesh_zipCoordsTraducer_1] + mesh=MEDCouplingUMesh() + mesh.setMeshDimension(2) + mesh.allocateCells(5) + conn=[0,3,4,1, 1,4,2, 4,5,2, 6,7,4,3, 7,8,5,4] + mesh.insertNextCell(NORM_QUAD4,4,conn[0:4]) + mesh.insertNextCell(NORM_TRI3,3, conn[4:7]) + mesh.insertNextCell(NORM_TRI3,3, conn[7:10]) + mesh.insertNextCell(NORM_QUAD4,4,conn[10:14]) + mesh.insertNextCell(NORM_QUAD4,4,conn[14:18]) + mesh.finishInsertingCells() + coords=[-0.3,-0.3, 0.2,-0.3, 0.7,-0.3, -0.3,0.2, 0.2,0.2, 0.7,0.2, -0.3,0.7, 0.2,0.7, 0.7,0.7 ] + coordsArr=DataArrayDouble(coords,9,2) + mesh.setCoords(coordsArr) + #! [PySnippet_MEDCouplingUMesh_zipCoordsTraducer_1] + #! [PySnippet_MEDCouplingUMesh_zipCoordsTraducer_2] + cellIds=[1,2] + mesh2=mesh.buildPartOfMySelf(cellIds,True) + arr=mesh2.zipCoordsTraducer() + assert mesh2.getNumberOfNodes() == 4 # nb of nodes decreased + assert arr.getValues() == [-1,0,1,-1,2,3,-1,-1,-1] # -1 for unused nodes + #! [PySnippet_MEDCouplingUMesh_zipCoordsTraducer_2] + return + + def testExample_MEDCouplingUMesh_getNodeIdsInUse(self): + #! [PySnippet_MEDCouplingUMesh_getNodeIdsInUse_1] + mesh=MEDCouplingUMesh() + mesh.setMeshDimension(2) + mesh.allocateCells(5) + conn=[0,3,4,1, 1,4,2, 4,5,2, 6,7,4,3, 7,8,5,4] + mesh.insertNextCell(NORM_QUAD4,4,conn[0:4]) + mesh.insertNextCell(NORM_TRI3,3, conn[4:7]) + mesh.insertNextCell(NORM_TRI3,3, conn[7:10]) + mesh.insertNextCell(NORM_QUAD4,4,conn[10:14]) + mesh.insertNextCell(NORM_QUAD4,4,conn[14:18]) + mesh.finishInsertingCells() + coords=[-0.3,-0.3, 0.2,-0.3, 0.7,-0.3, -0.3,0.2, 0.2,0.2, 0.7,0.2, -0.3,0.7, 0.2,0.7, 0.7,0.7 ] + coordsArr=DataArrayDouble(coords,9,2) + mesh.setCoords(coordsArr) + #! [PySnippet_MEDCouplingUMesh_getNodeIdsInUse_1] + #! [PySnippet_MEDCouplingUMesh_getNodeIdsInUse_2] + cellIds=[1,2] + mesh2=mesh.buildPartOfMySelf(cellIds,True) + arr,newNbOfNodes=mesh2.getNodeIdsInUse() + assert arr.getValues() == [-1,0,1,-1,2,3,-1,-1,-1] + #! [PySnippet_MEDCouplingUMesh_getNodeIdsInUse_2] + #! [PySnippet_MEDCouplingUMesh_getNodeIdsInUse_3] + arr2=arr.invertArrayO2N2N2O(newNbOfNodes) + assert arr2.getValues() == [1,2,4,5] + #! [PySnippet_MEDCouplingUMesh_getNodeIdsInUse_3] + return + + def testExample_MEDCouplingUMesh_convertToPolyTypes(self): + #! [PySnippet_MEDCouplingUMesh_convertToPolyTypes_1] + mesh=MEDCouplingUMesh() + mesh.setMeshDimension(2) + mesh.allocateCells(5) + conn=[0,3,4,1, 1,4,2, 4,5,2, 6,7,4,3, 7,8,5,4] + mesh.insertNextCell(NORM_QUAD4,4,conn[0:4]) # 0 + mesh.insertNextCell(NORM_TRI3,3, conn[4:7]) # 1 + mesh.insertNextCell(NORM_TRI3,3, conn[7:10]) # 2 + mesh.insertNextCell(NORM_QUAD4,4,conn[10:14]) # 3 + mesh.insertNextCell(NORM_QUAD4,4,conn[14:18]) # 4 + mesh.finishInsertingCells() + coords=[-0.3,-0.3, 0.2,-0.3, 0.7,-0.3, -0.3,0.2, 0.2,0.2, 0.7,0.2, -0.3,0.7, 0.2,0.7, 0.7,0.7 ] + coordsArr=DataArrayDouble(coords,9,2) + mesh.setCoords(coordsArr) + #! [PySnippet_MEDCouplingUMesh_convertToPolyTypes_1] + #! [PySnippet_MEDCouplingUMesh_convertToPolyTypes_2] + cells=[1,3] + mesh.convertToPolyTypes(cells) + assert mesh.getTypeOfCell(0) == NORM_QUAD4 + assert mesh.getTypeOfCell(1) == NORM_POLYGON, mesh.getTypeOfCell(1) + assert mesh.getTypeOfCell(2) == NORM_TRI3 + assert mesh.getTypeOfCell(3) == NORM_POLYGON + #! [PySnippet_MEDCouplingUMesh_convertToPolyTypes_2] + return + + def testExample_MEDCouplingUMesh_buildDescendingConnectivity2(self): + #! [PySnippet_MEDCouplingUMesh_buildDescendingConnectivity2_1] + mesh=MEDCouplingUMesh() + mesh.setMeshDimension(2) + mesh.allocateCells(5) + conn=[0,3,4,1, 1,4,2, 4,5,2, 6,7,4,3, 7,8,5,4] + mesh.insertNextCell(NORM_QUAD4,4,conn[0:4]) # 0 + mesh.insertNextCell(NORM_TRI3,3, conn[4:7]) # 1 + mesh.insertNextCell(NORM_TRI3,3, conn[7:10]) # 2 + mesh.insertNextCell(NORM_QUAD4,4,conn[10:14]) # 3 + mesh.insertNextCell(NORM_QUAD4,4,conn[14:18]) # 4 + mesh.finishInsertingCells() + coords=[-0.3,-0.3, 0.2,-0.3, 0.7,-0.3, -0.3,0.2, 0.2,0.2, 0.7,0.2, -0.3,0.7, 0.2,0.7, 0.7,0.7 ] + coordsArr=DataArrayDouble(coords,9,2) + mesh.setCoords(coordsArr) + #! [PySnippet_MEDCouplingUMesh_buildDescendingConnectivity2_1] + #! [PySnippet_MEDCouplingUMesh_buildDescendingConnectivity2_2] + mesh2,desc,descIndx,revDesc,revDescIndx=mesh.buildDescendingConnectivity2() + assert desc.getValues() == [1,2,3,4,-3,5,6, 7,8,-5,9,10,-2,11, 12,13,-7,-10] + assert descIndx.getValues() == [0,4,7,10,14,18] + assert revDesc.getValues() == [0, 0,3, 0,1, 0, 1,2, 1, 2,4, 2, 3, 3,4, 3, 4, 4] + assert revDescIndx.getValues() == [0,1,3,5,6,8,9,11,12,13,15,16,17,18] + #! [PySnippet_MEDCouplingUMesh_buildDescendingConnectivity2_2] + #! [PySnippet_MEDCouplingUMesh_buildDescendingConnectivity2_3] + assert mesh2.getNodeIdsOfCell( 3-1 ) == [4, 1] # cell #3 in FORTRAN mode + #! [PySnippet_MEDCouplingUMesh_buildDescendingConnectivity2_3] + return + + def testExample_MEDCouplingUMesh_buildDescendingConnectivity(self): + #! [PySnippet_MEDCouplingUMesh_buildDescendingConnectivity_1] + mesh=MEDCouplingUMesh() + mesh.setMeshDimension(2) + mesh.allocateCells(5) + conn=[0,3,4,1, 1,4,2, 4,5,2, 6,7,4,3, 7,8,5,4] + mesh.insertNextCell(NORM_QUAD4,4,conn[0:4]) # 0 + mesh.insertNextCell(NORM_TRI3,3, conn[4:7]) # 1 + mesh.insertNextCell(NORM_TRI3,3, conn[7:10]) # 2 + mesh.insertNextCell(NORM_QUAD4,4,conn[10:14]) # 3 + mesh.insertNextCell(NORM_QUAD4,4,conn[14:18]) # 4 + mesh.finishInsertingCells() + coords=[-0.3,-0.3, 0.2,-0.3, 0.7,-0.3, -0.3,0.2, 0.2,0.2, 0.7,0.2, -0.3,0.7, 0.2,0.7, 0.7,0.7 ] + coordsArr=DataArrayDouble(coords,9,2) + mesh.setCoords(coordsArr) + #! [PySnippet_MEDCouplingUMesh_buildDescendingConnectivity_1] + #! [PySnippet_MEDCouplingUMesh_buildDescendingConnectivity_2] + mesh2,desc,descIndx,revDesc,revDescIndx=mesh.buildDescendingConnectivity() + assert desc.getValues() == [0,1,2,3, 2,4,5, 6,7,4, 8,9,1,10, 11,12,6,9] + assert descIndx.getValues() == [0,4,7,10,14,18] + assert revDesc.getValues() == [0, 0,3, 0,1, 0, 1,2, 1, 2,4, 2, 3, 3,4, 3, 4, 4] + assert revDescIndx.getValues() == [0,1,3,5,6,8,9,11,12,13,15,16,17,18] + #! [PySnippet_MEDCouplingUMesh_buildDescendingConnectivity_2] + return + + def testExample_MEDCouplingUMesh_getReverseNodalConnectivity(self): + #! [PySnippet_MEDCouplingUMesh_getReverseNodalConnectivity_1] + mesh=MEDCouplingUMesh() + mesh.setMeshDimension(2) + mesh.allocateCells(5) + conn=[0,3,4,1, 1,4,2, 4,5,2, 6,7,4,3, 7,8,5,4] + mesh.insertNextCell(NORM_QUAD4,4,conn[0:4]) # 0 + mesh.insertNextCell(NORM_TRI3,3, conn[4:7]) # 1 + mesh.insertNextCell(NORM_TRI3,3, conn[7:10]) # 2 + mesh.insertNextCell(NORM_QUAD4,4,conn[10:14]) # 3 + mesh.insertNextCell(NORM_QUAD4,4,conn[14:18]) # 4 + mesh.finishInsertingCells() + coords=[-0.3,-0.3, 0.2,-0.3, 0.7,-0.3, -0.3,0.2, 0.2,0.2, 0.7,0.2, -0.3,0.7, 0.2,0.7, 0.7,0.7 ] + coordsArr=DataArrayDouble(coords,9,2) + mesh.setCoords(coordsArr) + #! [PySnippet_MEDCouplingUMesh_getReverseNodalConnectivity_1] + #! [PySnippet_MEDCouplingUMesh_getReverseNodalConnectivity_2] + revNodal,revNodalIndx=mesh.getReverseNodalConnectivity() + assert revNodal.getValues() == [0,0,1,1,2,0,3,0,1,2,3,4,2,4,3,3,4,4] + assert revNodalIndx.getValues() == [0,1,3,5,7,12,14,15,17,18] + #! [PySnippet_MEDCouplingUMesh_getReverseNodalConnectivity_2] + return + + def testExample_MEDCouplingUMesh_checkDeepEquivalWith(self): + #! [PySnippet_MEDCouplingUMesh_checkDeepEquivalWith_1] + # mesh 1 + mesh1=MEDCouplingUMesh() + mesh1.setMeshDimension(2) + coords=[0.0,0.0, #0 + 1.0,0.0, #1 + 1.0,1.0, #2 + 0.0,1.0] #3 + coordsArr=DataArrayDouble(coords,4,2) + mesh1.setCoords(coordsArr) + mesh1.allocateCells(2) + mesh1.insertNextCell(NORM_TRI3,3,[0,1,2]) #0 + mesh1.insertNextCell(NORM_TRI3,3,[1,2,3]) #1 + mesh1.finishInsertingCells() + # mesh 2 + mesh2=MEDCouplingUMesh() + mesh2.setMeshDimension(2) + coords=[0.0,1.0, #0 = #3 + 0.0,0.0, #1 = #0 + 1.0,0.0, #2 = #1 + 1.0,1.001] #3 ~ #2 + coordsArr2=DataArrayDouble(coords,4,2) + mesh2.setCoords(coordsArr2) + mesh2.allocateCells(2) + mesh2.insertNextCell(NORM_TRI3,3,[2,3,0]) #0 = #1 + mesh2.insertNextCell(NORM_TRI3,3,[3,1,2]) #1 ~ #0 + mesh2.finishInsertingCells() + #! [PySnippet_MEDCouplingUMesh_checkDeepEquivalWith_1] + #! [PySnippet_MEDCouplingUMesh_checkDeepEquivalWith_2] + cellCompPol = 1 # "permuted same orientation" - policy of medium severity + cOld2New, nOld2New = mesh1.checkDeepEquivalWith( mesh2, cellCompPol, 0.002 ) + assert nOld2New.getValues() == [3, 0, 1, 2] + assert cOld2New.getValues() == [1, 0] + #! [PySnippet_MEDCouplingUMesh_checkDeepEquivalWith_2] + #! [PySnippet_MEDCouplingUMesh_checkDeepEquivalWith_3] + self.assertRaises( InterpKernelException, mesh1.checkDeepEquivalOnSameNodesWith, mesh2, cellCompPol, 0.002) + mesh2.setCoords(coordsArr) # make meshes share the same coordinates array + mesh2.allocateCells(2) + mesh2.insertNextCell(NORM_TRI3,3,[1,2,3]) #0 = #1 + mesh2.insertNextCell(NORM_TRI3,3,[1,0,2]) #1 ~ #0 + mesh2.finishInsertingCells() + cellCompPol = 2 # the weakest policy + mesh1.checkDeepEquivalOnSameNodesWith( mesh2, cellCompPol, 0 ) + #! [PySnippet_MEDCouplingUMesh_checkDeepEquivalWith_3] + return + + def testExample_MEDCouplingPointSet_scale(self): + #! [PySnippet_MEDCouplingPointSet_scale_1] + coords=[0.0,0.0, 1.0,0.0, 1.0,1.0, 0.0,1.0] # 2D coordinates of 4 nodes + coordsArr=DataArrayDouble(coords,4,2) + mesh=MEDCouplingUMesh() + mesh.setCoords(coordsArr) + initCoords = coordsArr.deepCpy() + #! [PySnippet_MEDCouplingPointSet_scale_1] + #! [PySnippet_MEDCouplingPointSet_scale_2] + center = [0.,0.] + factor = 2. + mesh.scale(center,factor) + #! [PySnippet_MEDCouplingPointSet_scale_2] + #! [PySnippet_MEDCouplingPointSet_scale_3] + coords2 = mesh.getCoords() + assert coords2.isEqualWithoutConsideringStr( initCoords, 1.0 ) + assert not coords2.isEqualWithoutConsideringStr( initCoords, 0.9 ) + #! [PySnippet_MEDCouplingPointSet_scale_3] + return + + def testExample_MEDCouplingPointSet_translate(self): + #! [PySnippet_MEDCouplingPointSet_translate_1] + coords=[0.0,0.0, 1.0,0.0, 1.0,1.0, 0.0,1.0] # 2D coordinates of 4 nodes + coordsArr=DataArrayDouble(coords,4,2) + mesh=MEDCouplingUMesh() + mesh.setCoords(coordsArr) + initCoords = coordsArr.deepCpy() + #! [PySnippet_MEDCouplingPointSet_translate_1] + #! [PySnippet_MEDCouplingPointSet_translate_2] + vector = [1.,1.] + mesh.translate(vector) + #! [PySnippet_MEDCouplingPointSet_translate_2] + #! [PySnippet_MEDCouplingPointSet_translate_3] + coords2 = mesh.getCoords() + assert coords2.isEqualWithoutConsideringStr( initCoords, 1 ) + assert not coords2.isEqualWithoutConsideringStr( initCoords, 0.9 ) + #! [PySnippet_MEDCouplingPointSet_translate_3] + return + + def testExample_MEDCouplingPointSet_rotate(self): + #! [PySnippet_MEDCouplingPointSet_rotate_1] + coords=[0.0,0.0, 0.1,0.0, 0.1,0.1, 0.0,0.1] # 2D coordinates of 4 nodes + coordsArr=DataArrayDouble(coords,4,2) + mesh=MEDCouplingUMesh() + mesh.setCoords(coordsArr) + #! [PySnippet_MEDCouplingPointSet_rotate_1] + #! [PySnippet_MEDCouplingPointSet_rotate_2] + center = [0.,0.] + mesh.rotate(center,-pi/2) + #! [PySnippet_MEDCouplingPointSet_rotate_2] + #! [PySnippet_MEDCouplingPointSet_rotate_3] + mesh.changeSpaceDimension(3) + center = [0.,0.,0.] + vector = [0.,0.,1.] + mesh.rotate(center,vector,pi/2) + #! [PySnippet_MEDCouplingPointSet_rotate_3] + #! [PySnippet_MEDCouplingPointSet_rotate_4] + mesh.changeSpaceDimension(2) + coords2 = mesh.getCoords() + for i,c in enumerate( coords ): + self.assertAlmostEqual( c, coords2.getIJ(0,i), 13 ) + #! [PySnippet_MEDCouplingPointSet_rotate_4] + return + + def testExample_MEDCouplingPointSet_getBoundingBox(self): + #! [PySnippet_MEDCouplingPointSet_getBoundingBox_1] + cc=[0.0, 0.1, 0.2, # 3D coordinates of 2 nodes + 2.0, 2.1, 2.2] + coordsArr=DataArrayDouble(cc,2,3) + mesh=MEDCouplingUMesh() + mesh.setCoords(coordsArr) + #! [PySnippet_MEDCouplingPointSet_getBoundingBox_1] + #! [PySnippet_MEDCouplingPointSet_getBoundingBox_2] + bbox=mesh.getBoundingBox() + assert bbox == [( cc[0], cc[3] ), # NOTE: list of 3 tuples is retirned! + ( cc[1], cc[4] ), + ( cc[2], cc[5] )] + #! [PySnippet_MEDCouplingPointSet_getBoundingBox_2] + + def testExample_MEDCouplingPointSet_getNodeIdsNearPoint(self): + #! [PySnippet_MEDCouplingPointSet_getNodeIdsNearPoint_1] + # 2D coordinates of 5 nodes + coords=[0.3,-0.301, # 0 + 0.2,-0.3, # 1 + 0.3,-0.302, # 2 + 1.1,0.0, # 3 + 0.3,-0.30299999999999]# 4 + coordsArr=DataArrayDouble(coords,5,2) + mesh=MEDCouplingUMesh() + mesh.setCoords(coordsArr) + #! [PySnippet_MEDCouplingPointSet_getNodeIdsNearPoint_1] + #! [PySnippet_MEDCouplingPointSet_getNodeIdsNearPoint_2] + point=[0.3, -0.3] # point close to nodes #0, #2 and #4 + ids=mesh.getNodeIdsNearPoint(point,0.003) + assert ids.getValues() == [0,2,4] + #! [PySnippet_MEDCouplingPointSet_getNodeIdsNearPoint_2] + return + + def testExample_MEDCouplingPointSet_getNodeIdsNearPoints(self): + #! [PySnippet_MEDCouplingPointSet_getNodeIdsNearPoints_1] + # 2D coordinates of 7 nodes + coords=[0.3,-0.301, # 0 + 0.2,-0.3, # 1 + 0.3,-0.302, # 2 + 1.1,0.0, # 3 + 1.1,0.0, # 4 + 1.1,0.002, # 5 + 0.3,-0.303]# 6 + coordsArr=DataArrayDouble(coords,7,2) + mesh=MEDCouplingUMesh() + mesh.setCoords(coordsArr) + #! [PySnippet_MEDCouplingPointSet_getNodeIdsNearPoints_1] + #! [PySnippet_MEDCouplingPointSet_getNodeIdsNearPoints_2] + points=[0.2,-0.301, # ~ node #1 + 0.0, 0.0, + 1.1, 0.002] # ~ nodes #3, #4 and #5 + ids,idsIndex=mesh.getNodeIdsNearPoints(points,3,0.003) + assert ids.getValues() == [1, 3, 4, 5] + assert idsIndex.getValues() == [0, 1, 1, 4] + #! [PySnippet_MEDCouplingPointSet_getNodeIdsNearPoints_2] + return + + def testExample_MEDCouplingPointSet_findCommonNodes(self): + #! [PySnippet_MEDCouplingPointSet_findCommonNodes_1] + coords=[0.3,-0.301, # 0 + 0.2,-0.3, # 1 + 0.3,-0.302, # 2 + 1.1,0.0, # 3 + 1.1,0.0, # 4 + 0.3,-0.303]# 5 + coordsArr=DataArrayDouble(coords,6,2) + mesh=MEDCouplingUMesh() + mesh.setCoords(coordsArr) + #! [PySnippet_MEDCouplingPointSet_findCommonNodes_1] + #! [PySnippet_MEDCouplingPointSet_findCommonNodes_2] + comm,commI=mesh.findCommonNodes(1e-13) + assert comm.getValues() == [3,4] + comm,commI=mesh.findCommonNodes(0.004) + assert comm.getValues() == [0,2,5,3,4] + #! [PySnippet_MEDCouplingPointSet_findCommonNodes_2] + return + + def testExample_MEDCouplingPointSet_getCoordinatesOfNode(self): + #! [PySnippet_MEDCouplingPointSet_getCoordinatesOfNode_1] + coords=[-0.3,-0.3, 0.2,-0.3, 0.7,-0.3] + coordsArr=DataArrayDouble(coords,3,2) + mesh=MEDCouplingUMesh() + mesh.setCoords(coordsArr) +#! [PySnippet_MEDCouplingPointSet_getCoordinatesOfNode_1] +#! [PySnippet_MEDCouplingPointSet_getCoordinatesOfNode_2] + nodeCoords=mesh.getCoordinatesOfNode(1) + self.assertAlmostEqual(0.2, nodeCoords[0],13) + self.assertAlmostEqual(-0.3,nodeCoords[1],13) +#! [PySnippet_MEDCouplingPointSet_getCoordinatesOfNode_2] + return + + def testExample_DataArrayInt_getTuple(self): +#! [Snippet_DataArrayInt_getTuple_1] + dv=DataArrayInt() + dv.alloc( 6, 1 ) + dv.iota(7) + dv.rearrange( 2 ) + assert dv.getTuple( 1 ) == [9,10] +#! [Snippet_DataArrayInt_getTuple_1] +#! [Snippet_DataArrayInt_getTuple_2] + for tpl in dv: + print tpl +#! [Snippet_DataArrayInt_getTuple_2] + return + + def testExample_DataArrayInt_buildPermutationArr(self): +#! [PySnippet_DataArrayInt_buildPermutationArr_1] + a=DataArrayInt() + a.setValues([4,5,6,7,8],5,1) + b=DataArrayInt() + b.setValues([5,4,8,6,7],5,1) + c=a.buildPermutationArr(b) +#! [PySnippet_DataArrayInt_buildPermutationArr_1] + self.assertEqual([1,0,4,2,3],c.getValues()) + return + + def testExample_DataArrayInt_invertArrayO2N2N2O(self): +#! [PySnippet_DataArrayInt_invertArrayO2N2N2O_1] + arr1=[2,0,4,1,5,3] + da=DataArrayInt() + da.setValues(arr1,6,1) + da2=da.invertArrayO2N2N2O(6) + expected1=[1,3,0,5,2,4] + for i in xrange(6): + self.assertEqual(expected1[i],da2.getIJ(i,0)) + pass +#! [PySnippet_DataArrayInt_invertArrayO2N2N2O_1] + return + + def testExample_DataArrayInt_invertArrayN2O2O2N(self): +#! [PySnippet_DataArrayInt_invertArrayN2O2O2N_1] + arr1=[2,0,4,1,5,3] + da=DataArrayInt() + da.setValues(arr1,6,1) + da2=da.invertArrayN2O2O2N(7) + expected1=[1,3,0,5,2,4,-1] + for i in xrange(6): + self.assertEqual(expected1[i],da2.getIJ(i,0)) + pass +#! [PySnippet_DataArrayInt_invertArrayN2O2O2N_1] + return + + + def testExample_DataArrayDouble_getIdsInRange(self): +#! [PySnippet_DataArrayDouble_getIdsInRange_1] + da=DataArrayDouble() + da.alloc( 10, 1 ) + da[ :, :] = range(10) + da2 = da.getIdsInRange( 2.5, 6 ) +#! [PySnippet_DataArrayDouble_getIdsInRange_1] + return + + def testExample_DataArrayDouble_setPartOfValues2(self): +#! [Snippet_DataArrayDouble_setPartOfValues2_1] + da=DataArrayDouble() + da.alloc( 4, 7 ) + # + dv=DataArrayDouble() + dv.alloc( 6, 1 ) + dv.iota(7) + dv.rearrange( 2 ) +#! [Snippet_DataArrayDouble_setPartOfValues2_1] +#! [Snippet_DataArrayDouble_setPartOfValues2_2] + da.fillWithZero() + da[ [0,1,2], [1,3] ] = dv +#! [Snippet_DataArrayDouble_setPartOfValues2_2] +#! [Snippet_DataArrayDouble_setPartOfValues2_3] + da.fillWithZero() + dv.rearrange( 6 ) + da[ [0,2,3], [0,2,3,4,5,6]] = dv +#! [Snippet_DataArrayDouble_setPartOfValues2_3] + return + + def testExample_DataArrayInt_setPartOfValues2(self): +#! [Snippet_DataArrayInt_setPartOfValues2_1] + da=DataArrayInt() + da.alloc( 4, 7 ) + # + dv=DataArrayInt() + dv.alloc( 6, 1 ) + dv.iota(7) + dv.rearrange( 2 ) +#! [Snippet_DataArrayInt_setPartOfValues2_1] +#! [Snippet_DataArrayInt_setPartOfValues2_2] + da.fillWithZero() + da[ [0,1,2], [1,3] ] = dv +#! [Snippet_DataArrayInt_setPartOfValues2_2] +#! [Snippet_DataArrayInt_setPartOfValues2_3] + da.fillWithZero() + dv.rearrange( 6 ) + da[ [0,2,3], [0,2,3,4,5,6]] = dv +#! [Snippet_DataArrayInt_setPartOfValues2_3] + return + + def testExample_DataArrayDouble_setPartOfValues3(self): +#! [Snippet_DataArrayDouble_setPartOfValues3_1] + da=DataArrayDouble() + da.alloc( 4, 7 ) + # + dv=DataArrayDouble() + dv.alloc( 6, 1 ) + dv.iota(7) + dv.rearrange( 2 ) +#! [Snippet_DataArrayDouble_setPartOfValues3_1] +#! [Snippet_DataArrayDouble_setPartOfValues3_2] + da.fillWithZero() + da[ 0:3, [1,3] ] = dv +#! [Snippet_DataArrayDouble_setPartOfValues3_2] +#! [Snippet_DataArrayDouble_setPartOfValues3_3] + da.fillWithZero() + dv.rearrange( 6 ) + da[ 0:4:2, [0,2,3,4,5,6]] = dv +#! [Snippet_DataArrayDouble_setPartOfValues3_3] + return + + def testExample_DataArrayInt_setPartOfValues3(self): +#! [Snippet_DataArrayInt_setPartOfValues3_1] + da=DataArrayInt() + da.alloc( 4, 7 ) + # + dv=DataArrayInt() + dv.alloc( 6, 1 ) + dv.iota(7) + dv.rearrange( 2 ) +#! [Snippet_DataArrayInt_setPartOfValues3_1] +#! [Snippet_DataArrayInt_setPartOfValues3_2] + da.fillWithZero() + da[ 0:3, [1,3] ] = dv +#! [Snippet_DataArrayInt_setPartOfValues3_2] +#! [Snippet_DataArrayInt_setPartOfValues3_3] + da.fillWithZero() + dv.rearrange( 6 ) + da[ 0:4:2, [0,2,3,4,5,6]] = dv +#! [Snippet_DataArrayInt_setPartOfValues3_3] + return + + def testExample_DataArrayDouble_setPartOfValues1(self): +#! [Snippet_DataArrayDouble_setPartOfValues1_1] + da=DataArrayDouble() + da.alloc( 4, 4 ) + da.setInfoOnComponents( ["v1","v2","v3","v4"]) + # + dv=DataArrayDouble() + dv.alloc( 4, 1 ) + dv.iota(7) + dv.rearrange( 2 ) + dv.setInfoOnComponents( ["a1","a2"]) +#! [Snippet_DataArrayDouble_setPartOfValues1_1] +#! [Snippet_DataArrayDouble_setPartOfValues1_2] + da.fillWithZero() + da.setPartOfValues1( dv, 1,3,1, 1,3,1, True ) +#! [Snippet_DataArrayDouble_setPartOfValues1_2] +#! [Snippet_DataArrayDouble_setPartOfValues1_3] + da.fillWithZero() + da.setPartOfValues1( dv, 0,4,1, 1,2,1, False ) +#! [Snippet_DataArrayDouble_setPartOfValues1_3] +#! [Snippet_DataArrayDouble_setPartOfValues1_4] + da.fillWithZero() + da.setPartOfValues1( dv, 1,2,1, 0,4,1, False ) +#! [Snippet_DataArrayDouble_setPartOfValues1_4] +#! [Snippet_DataArrayDouble_setPartOfValues1_5] + da.fillWithZero() + da.setPartOfValues1( dv, 0,3,2, 1,4,2, True ) +#! [Snippet_DataArrayDouble_setPartOfValues1_5] +#! [Snippet_DataArrayDouble_setPartOfValues1_6] + da2 = da.deepCpy() + da2.fillWithZero() + da2[ 0:3:2, 1:4:2 ] = dv + self.assertTrue( da.isEqual( da2, 1e-20 )) +#! [Snippet_DataArrayDouble_setPartOfValues1_6] + return + + def testExample_DataArrayInt_setPartOfValues1(self): +#! [Snippet_DataArrayInt_setPartOfValues1_1] + da=DataArrayInt() + da.alloc( 4, 4 ) + da.setInfoOnComponents( ["v1","v2","v3","v4"]) + # + dv=DataArrayInt() + dv.alloc( 4, 1 ) + dv.iota(7) + dv.rearrange( 2 ) + dv.setInfoOnComponents( ["a1","a2"]) +#! [Snippet_DataArrayInt_setPartOfValues1_1] +#! [Snippet_DataArrayInt_setPartOfValues1_2] + da.fillWithZero() + da.setPartOfValues1( dv, 1,3,1, 1,3,1, True ) +#! [Snippet_DataArrayInt_setPartOfValues1_2] +#! [Snippet_DataArrayInt_setPartOfValues1_3] + da.fillWithZero() + da.setPartOfValues1( dv, 0,4,1, 1,2,1, False ) +#! [Snippet_DataArrayInt_setPartOfValues1_3] +#! [Snippet_DataArrayInt_setPartOfValues1_4] + da.fillWithZero() + da.setPartOfValues1( dv, 1,2,1, 0,4,1, False ) +#! [Snippet_DataArrayInt_setPartOfValues1_4] +#! [Snippet_DataArrayInt_setPartOfValues1_5] + da.fillWithZero() + da.setPartOfValues1( dv, 0,3,2, 1,4,2, True ) +#! [Snippet_DataArrayInt_setPartOfValues1_5] +#! [Snippet_DataArrayInt_setPartOfValues1_6] + da2 = da.deepCpy() + da2.fillWithZero() + da2[ 0:3:2, 1:4:2 ] = dv + self.assertTrue( da.isEqual( da2 )) +#! [Snippet_DataArrayInt_setPartOfValues1_6] + return + + def testExample_DataArrayDouble_setPartOfValuesSimple1(self): +#! [Snippet_DataArrayDouble_setPartOfValuesSimple1_1] + da=DataArrayDouble() + da.alloc( 4, 4 ) + dv = 7 +#! [Snippet_DataArrayDouble_setPartOfValuesSimple1_1] +#! [Snippet_DataArrayDouble_setPartOfValuesSimple1_2] + da.fillWithZero() + da.setPartOfValuesSimple1( dv, 1,3,1, 1,3,1 ) +#! [Snippet_DataArrayDouble_setPartOfValuesSimple1_2] +#! [Snippet_DataArrayDouble_setPartOfValuesSimple1_3] + da.fillWithZero() + da.setPartOfValuesSimple1( dv, 0,4,1, 1,2,1 ) +#! [Snippet_DataArrayDouble_setPartOfValuesSimple1_3] +#! [Snippet_DataArrayDouble_setPartOfValuesSimple1_4] + da.fillWithZero() + da.setPartOfValuesSimple1( dv, 1,2,1, 0,4,1 ) +#! [Snippet_DataArrayDouble_setPartOfValuesSimple1_4] +#! [Snippet_DataArrayDouble_setPartOfValuesSimple1_5] + da.fillWithZero() + da.setPartOfValuesSimple1( dv, 0,3,2, 1,4,2 ) +#! [Snippet_DataArrayDouble_setPartOfValuesSimple1_5] +#! [Snippet_DataArrayDouble_setPartOfValuesSimple1_6] + da2 = da.deepCpy() + da2.fillWithZero() + da2[ 0:3:2, 1:4:2 ] = dv + self.assertTrue( da.isEqual( da2, 1e-20 )) +#! [Snippet_DataArrayDouble_setPartOfValuesSimple1_6] + return + + def testExample_DataArrayInt_setPartOfValuesSimple1(self): +#! [Snippet_DataArrayInt_setPartOfValuesSimple1_1] + da=DataArrayInt() + da.alloc( 4, 4 ) + dv = 7 +#! [Snippet_DataArrayInt_setPartOfValuesSimple1_1] +#! [Snippet_DataArrayInt_setPartOfValuesSimple1_2] + da.fillWithZero() + da.setPartOfValuesSimple1( dv, 1,3,1, 1,3,1 ) +#! [Snippet_DataArrayInt_setPartOfValuesSimple1_2] +#! [Snippet_DataArrayInt_setPartOfValuesSimple1_3] + da.fillWithZero() + da.setPartOfValuesSimple1( dv, 0,4,1, 1,2,1 ) +#! [Snippet_DataArrayInt_setPartOfValuesSimple1_3] +#! [Snippet_DataArrayInt_setPartOfValuesSimple1_4] + da.fillWithZero() + da.setPartOfValuesSimple1( dv, 1,2,1, 0,4,1 ) +#! [Snippet_DataArrayInt_setPartOfValuesSimple1_4] +#! [Snippet_DataArrayInt_setPartOfValuesSimple1_5] + da.fillWithZero() + da.setPartOfValuesSimple1( dv, 0,3,2, 1,4,2 ) +#! [Snippet_DataArrayInt_setPartOfValuesSimple1_5] +#! [Snippet_DataArrayInt_setPartOfValuesSimple1_6] + da2 = da.deepCpy() + da2.fillWithZero() + da2[ 0:3:2, 1:4:2 ] = dv + self.assertTrue( da.isEqual( da2 )) +#! [Snippet_DataArrayInt_setPartOfValuesSimple1_6] + return + + def testExample_DataArrayDouble_setPartOfValuesSimple2(self): +#! [Snippet_DataArrayDouble_setPartOfValuesSimple2_1] + da=DataArrayDouble() + da.alloc( 4, 4 ) + dv = 7 +#! [Snippet_DataArrayDouble_setPartOfValuesSimple2_1] +#! [Snippet_DataArrayDouble_setPartOfValuesSimple2_2] + da.fillWithZero() + da[[1,2], [1,2]] = dv +#! [Snippet_DataArrayDouble_setPartOfValuesSimple2_2] +#! [Snippet_DataArrayDouble_setPartOfValuesSimple2_3] + da.fillWithZero() + da[[0,1,2,3], [1]] = dv +#! [Snippet_DataArrayDouble_setPartOfValuesSimple2_3] +#! [Snippet_DataArrayDouble_setPartOfValuesSimple2_4] + da.fillWithZero() + da[[1], [0,1,2,3]] = dv +#! [Snippet_DataArrayDouble_setPartOfValuesSimple2_4] +#! [Snippet_DataArrayDouble_setPartOfValuesSimple2_5] + da.fillWithZero() + da[[0,2], [1,3]] = dv +#! [Snippet_DataArrayDouble_setPartOfValuesSimple2_5] + return + + def testExample_DataArrayInt_setPartOfValuesSimple2(self): +#! [Snippet_DataArrayInt_setPartOfValuesSimple2_1] + da=DataArrayInt() + da.alloc( 4, 4 ) + dv = 7 +#! [Snippet_DataArrayInt_setPartOfValuesSimple2_1] +#! [Snippet_DataArrayInt_setPartOfValuesSimple2_2] + da.fillWithZero() + da[[1,2], [1,2]] = dv +#! [Snippet_DataArrayInt_setPartOfValuesSimple2_2] +#! [Snippet_DataArrayInt_setPartOfValuesSimple2_3] + da.fillWithZero() + da[[0,1,2,3], [1]] = dv +#! [Snippet_DataArrayInt_setPartOfValuesSimple2_3] +#! [Snippet_DataArrayInt_setPartOfValuesSimple2_4] + da.fillWithZero() + da[[1], [0,1,2,3]] = dv +#! [Snippet_DataArrayInt_setPartOfValuesSimple2_4] +#! [Snippet_DataArrayInt_setPartOfValuesSimple2_5] + da.fillWithZero() + da[[0,2], [1,3]] = dv +#! [Snippet_DataArrayInt_setPartOfValuesSimple2_5] + return + + def testExample_DataArrayDouble_setPartOfValuesSimple3(self): +#! [Snippet_DataArrayDouble_setPartOfValuesSimple3_1] + da=DataArrayDouble() + da.alloc( 4, 4 ) + dv = 7 +#! [Snippet_DataArrayDouble_setPartOfValuesSimple3_1] +#! [Snippet_DataArrayDouble_setPartOfValuesSimple3_2] + da.fillWithZero() + da[[1,2], 1:3] = dv +#! [Snippet_DataArrayDouble_setPartOfValuesSimple3_2] +#! [Snippet_DataArrayDouble_setPartOfValuesSimple3_3] + da.fillWithZero() + da[[0,1,2,3], 1:2] = dv +#! [Snippet_DataArrayDouble_setPartOfValuesSimple3_3] +#! [Snippet_DataArrayDouble_setPartOfValuesSimple3_4] + da.fillWithZero() + da[[1], 0:4] = dv +#! [Snippet_DataArrayDouble_setPartOfValuesSimple3_4] +#! [Snippet_DataArrayDouble_setPartOfValuesSimple3_5] + da.fillWithZero() + da[[0,2], 1:4:2] = dv +#! [Snippet_DataArrayDouble_setPartOfValuesSimple3_5] + return + + def testExample_DataArrayInt_setPartOfValuesSimple3(self): +#! [Snippet_DataArrayInt_setPartOfValuesSimple3_1] + da=DataArrayInt() + da.alloc( 4, 4 ) + dv = 7 +#! [Snippet_DataArrayInt_setPartOfValuesSimple3_1] +#! [Snippet_DataArrayInt_setPartOfValuesSimple3_2] + da.fillWithZero() + da[[1,2], 1:3] = dv +#! [Snippet_DataArrayInt_setPartOfValuesSimple3_2] +#! [Snippet_DataArrayInt_setPartOfValuesSimple3_3] + da.fillWithZero() + da[[0,1,2,3], 1:2] = dv +#! [Snippet_DataArrayInt_setPartOfValuesSimple3_3] +#! [Snippet_DataArrayInt_setPartOfValuesSimple3_4] + da.fillWithZero() + da[[1], 0:4] = dv +#! [Snippet_DataArrayInt_setPartOfValuesSimple3_4] +#! [Snippet_DataArrayInt_setPartOfValuesSimple3_5] + da.fillWithZero() + da[[0,2], 1:4:2] = dv +#! [Snippet_DataArrayInt_setPartOfValuesSimple3_5] + return + + def testExample_DataArrayDouble_setSelectedComponents(self): +#! [Snippet_DataArrayDouble_setSelectedComponents1] + array1=[1.,2., 3.,4., 5.,6.] + da=DataArrayDouble(array1,3,2) + da.setInfoOnComponents( ["a1","a2"]) +#! [Snippet_DataArrayDouble_setSelectedComponents1] +#! [Snippet_DataArrayDouble_setSelectedComponents2] + dv=DataArrayDouble() + dv.alloc( 4, 4 ) + dv.fillWithZero() + dv.setInfoOnComponents( ["v1","v2","v3","v4"]) + dv2 = dv.deepCpy() + dv.setSelectedComponents( da, [1,0] ) +#! [Snippet_DataArrayDouble_setSelectedComponents2] +#! [Snippet_DataArrayDouble_setSelectedComponents3] + dv2[:3,[1,0]] = da + self.assertTrue( dv.isEqualWithoutConsideringStr( dv2, 1e-20 )) +#! [Snippet_DataArrayDouble_setSelectedComponents3] + return + + def testExample_DataArrayInt_setSelectedComponents(self): +#! [Snippet_DataArrayInt_setSelectedComponents1] + da=DataArrayInt() + array1=[1,2, 3,4, 5,6] + da.setValues(array1,3,2) + da.setInfoOnComponents( ["a1","a2"]) +#! [Snippet_DataArrayInt_setSelectedComponents1] +#! [Snippet_DataArrayInt_setSelectedComponents2] + dv=DataArrayInt() + dv.alloc( 4, 4 ) + dv.fillWithZero() + dv.setInfoOnComponents( ["v1","v2","v3","v4"]) + dv2 = dv.deepCpy() + dv.setSelectedComponents( da, [1,0] ) +#! [Snippet_DataArrayInt_setSelectedComponents2] +#! [Snippet_DataArrayInt_setSelectedComponents3] + dv2[:3,[1,0]] = da + self.assertTrue( dv.isEqualWithoutConsideringStr( dv2 )) +#! [Snippet_DataArrayInt_setSelectedComponents3] + return + + def testExample_DataArrayDouble_getDifferentValues(self): +#! [Snippet_DataArrayDouble_getDifferentValues1] + array1=[2.3,1.2,1.3,2.3,2.301,0.8] + da=DataArrayDouble(array1,6,1) + # + dv=da.getDifferentValues(2e-1) + expected2=[2.301,1.3,0.8] + self.assertEqual(3,dv.getNbOfElems()) + for i in xrange(3): + self.assertAlmostEqual(expected2[i],dv.getIJ(i,0),14) + pass +#! [Snippet_DataArrayDouble_getDifferentValues1] + return + + def testExample_DataArrayDouble_findCommonTuples1(self): +#! [PySnippet_DataArrayDouble_findCommonTuples1] + array2=[2.3,2.3, 1.2,1.2, 1.3,1.3, 2.3,2.3, 2.301,2.301, 0.8,0.8] + da=DataArrayDouble(array2,6,2) +#! [PySnippet_DataArrayDouble_findCommonTuples1] +#! [PySnippet_DataArrayDouble_findCommonTuples2] + c,cI=da.findCommonTuples(1.01e-1) + expected3=[0,3,4,1,2] + expected4=[0,3,5] + self.assertEqual(expected3,c.getValues()) + self.assertEqual(expected4,cI.getValues()) +#! [PySnippet_DataArrayDouble_findCommonTuples2] + return + + def testExampleDataArrayDoubleMeldWith(self): +#! [PySnippet_DataArrayDouble_Meld1_1] + da1=DataArrayDouble() + da1.alloc(7,2) + da2=DataArrayDouble() + da2.alloc(7,1) + # + da1.fillWithValue(7.) + da2.iota(0.) + da3=da2.applyFunc(3,"10*x*IVec+100*x*JVec+1000*x*KVec") + # + da1.setInfoOnComponent(0,"c0da1") + da1.setInfoOnComponent(1,"c1da1") + da3.setInfoOnComponent(0,"c0da3") + da3.setInfoOnComponent(1,"c1da3") + da3.setInfoOnComponent(2,"c2da3") + # + da1C=da1.deepCpy() + da1.meldWith(da3) +#! [PySnippet_DataArrayDouble_Meld1_1] + + def testExampleDataArrayIntMeldWith(self): +#! [PySnippet_DataArrayInt_Meld1_1] + da1=DataArrayInt() + da1.alloc(7,2) + da2=DataArrayInt() + da2.alloc(7,1) + # + da1.fillWithValue(7) + da2.iota(0) + # + da1.setInfoOnComponent(0,"c0da1") + da1.setInfoOnComponent(1,"c1da1") + da2.setInfoOnComponent(0,"c0da2") + # + da1.meldWith(da2) +#! [PySnippet_DataArrayInt_Meld1_1] + + def testExampleDataArrayDoubleKeepSelectedComponents1(self): +#! [SnippeDataArrayDoubleKeepSelectedComponents1_1] + arr1=[1.,2.,3.,4., # tuple 0 + 11.,12.,13.,14., # tuple 1 + 21.,22.,23.,24., # ... + 31.,32.,33.,34., + 41.,42.,43.,44.] + a1=DataArrayDouble(arr1,5,4) + a1.setInfoOnComponent(0,"a") + a1.setInfoOnComponent(1,"b") + a1.setInfoOnComponent(2,"c") + a1.setInfoOnComponent(3,"d") +#! [SnippeDataArrayDoubleKeepSelectedComponents1_1] +#! [SnippeDataArrayDoubleKeepSelectedComponents1_2] + arr2V=[1,2,1,2,0,0] + a2=a1.keepSelectedComponents(arr2V) +#! [SnippeDataArrayDoubleKeepSelectedComponents1_2] + return + + def testExampleDataArrayIntKeepSelectedComponents1(self): +#! [SnippeDataArrayIntKeepSelectedComponents1_1] + arr1=[1,2,3,4, # tuple 0 + 11,12,13,14, # tuple 1 + 21,22,23,24, # + 31,32,33,34, + 41,42,43,44] + a1=DataArrayInt() + a1.setValues(arr1,5,4) + a1.setInfoOnComponent(0,"a") + a1.setInfoOnComponent(1,"b") + a1.setInfoOnComponent(2,"c") + a1.setInfoOnComponent(3,"d") +#! [SnippeDataArrayIntKeepSelectedComponents1_1] +#! [SnippeDataArrayIntKeepSelectedComponents1_2] + arr2V=[1,2,1,2,0,0] + a2=a1.keepSelectedComponents(arr2V) +#! [SnippeDataArrayIntKeepSelectedComponents1_2] +#! [SnippeDataArrayIntKeepSelectedComponents1_3] + a3=a1[:,arr2V ] +#! [SnippeDataArrayIntKeepSelectedComponents1_3] + return + + def testExampleFieldDoubleBuildSubPart1(self): + from MEDCouplingDataForTest import MEDCouplingDataForTest +#! [PySnippetFieldDoubleBuildSubPart1_1] + mesh1=MEDCouplingDataForTest.build2DTargetMesh_1() + f1=MEDCouplingFieldDouble(ON_CELLS,ONE_TIME) + f1.setTime(2.3,5,6) + f1.setMesh(mesh1) + arr1=[3.,103.,4.,104.,5.,105.,6.,106.,7.,107.] + array=DataArrayDouble(arr1,mesh1.getNumberOfCells(),2) + f1.setArray(array) +# ! [PySnippetFieldDoubleBuildSubPart1_1] +# ! [PySnippetFieldDoubleBuildSubPart1_2] + part1=[2,1,4] + f2=f1.buildSubPart(part1) +# ! [PySnippetFieldDoubleBuildSubPart1_2] + f2.zipCoords() + self.assertEqual(3,f2.getNumberOfTuples()) + self.assertEqual(2,f2.getNumberOfComponents()) + expected1=[5.,105.,4.,104.,7.,107.] + for i in xrange(6): + self.assertAlmostEqual(f2.getIJ(0,i),expected1[i],12) + pass + self.assertEqual(3,f2.getMesh().getNumberOfCells()) + self.assertEqual(6,f2.getMesh().getNumberOfNodes()) + self.assertEqual(2,f2.getMesh().getSpaceDimension()) + self.assertEqual(2,f2.getMesh().getMeshDimension()) + m2C=f2.getMesh() + self.assertEqual(13,m2C.getMeshLength()) + expected2=[0.2, -0.3, 0.7, -0.3, 0.2, 0.2, 0.7, 0.2, 0.2, 0.7, 0.7, 0.7] + for i in xrange(12): + self.assertAlmostEqual(expected2[i],m2C.getCoords().getIJ(0,i),12) + pass + expected3=[3,2,3,1,3,0,2,1,4,4,5,3,2] + self.assertEqual(expected3,list(m2C.getNodalConnectivity().getValues())) + expected4=[0,4,8,13] + self.assertEqual(expected4,list(m2C.getNodalConnectivityIndex().getValues())) + # Test with field on nodes. +# ! [PySnippetFieldDoubleBuildSubPart1_3] + f1=MEDCouplingFieldDouble(ON_NODES,ONE_TIME) + f1.setTime(2.3,5,6) + f1.setMesh(mesh1) + arr2=[3.,103.,4.,104.,5.,105.,6.,106.,7.,107.,8.,108.,9.,109.,10.,110.,11.,111.] + array=DataArrayDouble(arr2,mesh1.getNumberOfNodes(),2) + f1.setArray(array) +# ! [PySnippetFieldDoubleBuildSubPart1_3] +# ! [PySnippetFieldDoubleBuildSubPart1_4] + part2=[1,2] + f2=f1.buildSubPart(part2) +# ! [PySnippetFieldDoubleBuildSubPart1_4] + self.assertEqual(4,f2.getNumberOfTuples()) + self.assertEqual(2,f2.getNumberOfComponents()) + expected5=[4.,104.,5.,105.,7.,107.,8.,108.] + for i in xrange(8): + self.assertAlmostEqual(f2.getIJ(0,i),expected5[i],12) + pass + self.assertEqual(2,f2.getMesh().getNumberOfCells()) + self.assertEqual(4,f2.getMesh().getNumberOfNodes()) + self.assertEqual(2,f2.getMesh().getSpaceDimension()) + self.assertEqual(2,f2.getMesh().getMeshDimension()) + m2C=f2.getMesh() + self.assertEqual(8,m2C.getMeshLength()) + for i in xrange(8):#8 is not an error + self.assertAlmostEqual(expected2[i],m2C.getCoords().getIJ(0,i),12) + pass + self.assertEqual(expected3[:4],[int(i) for i in m2C.getNodalConnectivity()][4:]) + self.assertEqual(expected3[4:8],[int(i) for i in m2C.getNodalConnectivity()][:4]) + self.assertEqual(expected4[:3],[int(i) for i in m2C.getNodalConnectivityIndex()]) + #idem previous because nodes of cell#4 are not fully present in part3 + part3=[1,2] + arrr=DataArrayInt() + arrr.setValues(part3,2,1) + f2=f1.buildSubPart(arrr) + self.assertEqual(4,f2.getNumberOfTuples()) + self.assertEqual(2,f2.getNumberOfComponents()) + for i in xrange(8): + self.assertAlmostEqual(f2.getIJ(0,i),expected5[i],12) + pass + self.assertEqual(2,f2.getMesh().getNumberOfCells()) + self.assertEqual(4,f2.getMesh().getNumberOfNodes()) + self.assertEqual(2,f2.getMesh().getSpaceDimension()) + self.assertEqual(2,f2.getMesh().getMeshDimension()) + m2C=f2.getMesh() + self.assertEqual(8,m2C.getMeshLength()) + for i in xrange(8):#8 is not an error + self.assertAlmostEqual(expected2[i],m2C.getCoords().getIJ(0,i),12) + pass + self.assertEqual(expected3[:4],[int(i) for i in m2C.getNodalConnectivity()][4:8]) + self.assertEqual(expected3[4:8],[int(i) for i in m2C.getNodalConnectivity()][:4]) + self.assertEqual(expected4[:3],m2C.getNodalConnectivityIndex().getValues()) + part4=[1,2,4] + f2=f1.buildSubPart(part4) + self.assertEqual(6,f2.getNumberOfTuples()) + self.assertEqual(2,f2.getNumberOfComponents()) + expected6=[4.,104.,5.,105.,7.,107.,8.,108.,10.,110.,11.,111.] + for i in xrange(12): + self.assertAlmostEqual(f2.getIJ(0,i),expected6[i],12) + pass + self.assertEqual(3,f2.getMesh().getNumberOfCells()) + self.assertEqual(6,f2.getMesh().getNumberOfNodes()) + self.assertEqual(2,f2.getMesh().getSpaceDimension()) + self.assertEqual(2,f2.getMesh().getMeshDimension()) + m2C=f2.getMesh() + self.assertEqual(13,m2C.getMeshLength()) + for i in xrange(12): + self.assertAlmostEqual(expected2[i],m2C.getCoords().getIJ(0,i),12) + pass + self.assertEqual(expected3[0:4],m2C.getNodalConnectivity().getValues()[4:8]) + self.assertEqual(expected3[4:8],m2C.getNodalConnectivity().getValues()[0:4]) + self.assertEqual(expected3[8:13],m2C.getNodalConnectivity().getValues()[8:13]) + self.assertEqual(expected4,m2C.getNodalConnectivityIndex().getValues()) + # previous line equivalent to + self.assertEqual(expected4,[int(i) for i in m2C.getNodalConnectivityIndex()]) + return + + def testExampleUMeshStdBuild1(self): +# ! [PySnippetUMeshStdBuild1_1] + coords=[-0.3,-0.3,0., 0.2,-0.3,0., 0.7,-0.3,0., -0.3,0.2,0., 0.2,0.2,0., + 0.7,0.2,0., -0.3,0.7,0., 0.2,0.7,0., 0.7,0.7,0. ] + nodalConnPerCell=[0,3,4,1, 1,4,2, 4,5,2, 6,7,4,3, 7,8,5,4] +# ! [PySnippetUMeshStdBuild1_1] +# ! [PySnippetUMeshStdBuild1_2] + mesh=MEDCouplingUMesh("My2DMesh",2) +# ! [PySnippetUMeshStdBuild1_2] +# ! [PySnippetUMeshStdBuild1_3] + mesh.allocateCells(5)#You can put more than 5 if you want but not less. + mesh.insertNextCell(NORM_QUAD4,nodalConnPerCell[:4]) + mesh.insertNextCell(NORM_TRI3,nodalConnPerCell[4:7]) + mesh.insertNextCell(NORM_TRI3,nodalConnPerCell[7:10]) + mesh.insertNextCell(NORM_QUAD4,nodalConnPerCell[10:14]) + mesh.insertNextCell(NORM_QUAD4,nodalConnPerCell[14:]) + mesh.finishInsertingCells() +# ! [PySnippetUMeshStdBuild1_3] +# ! [PySnippetUMeshStdBuild1_4] + coordsArr=DataArrayDouble(coords,9,3)#here coordsArr are declared to have 3 components, mesh will deduce that its spaceDim==3. + mesh.setCoords(coordsArr)#coordsArr contains 9 tuples, that is to say mesh contains 9 nodes. +# ! [PySnippetUMeshStdBuild1_4] +# ! [PySnippetUMeshStdBuild1_5] +# ! [PySnippetUMeshStdBuild1_5] + mesh.checkCoherency() + return + + def testExampleCMeshStdBuild1(self): +# ! [PySnippetCMeshStdBuild1_1] + XCoords=[-0.3,0.,0.1,0.3,0.45,0.47,0.49,1.,1.22] # 9 values along X + YCoords=[0.,0.1,0.37,0.45,0.47,0.49,1.007] # 7 values along Y + arrX=DataArrayDouble(XCoords) + arrX.setInfoOnComponent(0,"X [m]") + arrY=DataArrayDouble(YCoords) + arrY.setInfoOnComponent(0,"Y [m]") +# ! [PySnippetCMeshStdBuild1_1] +# ! [PySnippetCMeshStdBuild1_2] + mesh=MEDCouplingCMesh("My2D_CMesh") + mesh.setCoords(arrX,arrY) +# ! [PySnippetCMeshStdBuild1_2] +# ! [PySnippetCMeshStdBuild1_3] + self.assertEqual(8*6,mesh.getNumberOfCells()) + self.assertEqual(9*7,mesh.getNumberOfNodes()) + self.assertEqual(2,mesh.getSpaceDimension()) + self.assertEqual(2,mesh.getMeshDimension()) +# ! [PySnippetCMeshStdBuild1_3] + mesh=MEDCouplingCMesh("My2D_CMesh") +# ! [PySnippetCMeshStdBuild1_2bis] + mesh.setCoordsAt(0,arrX) + mesh.setCoordsAt(1,arrY) +# ! [PySnippetCMeshStdBuild1_2bis] + self.assertEqual(8*6,mesh.getNumberOfCells()) + self.assertEqual(9*7,mesh.getNumberOfNodes()) + self.assertEqual(2,mesh.getSpaceDimension()) + self.assertEqual(2,mesh.getMeshDimension()) + return + + def testExampleUMeshAdvBuild1(self): +# ! [PySnippetUMeshAdvBuild1_1] + coords=[-0.3,-0.3,0., 0.2,-0.3,0., 0.7,-0.3,0., -0.3,0.2,0., 0.2,0.2,0., + 0.7,0.2,0., -0.3,0.7,0., 0.2,0.7,0., 0.7,0.7,0. ] + nodalConnPerCell=[4,0,3,4,1, 3,1,4,2, 3,4,5,2, 4,6,7,4,3, 4,7,8,5,4] + nodalConnPerCellIndex=[0,5,9,13,18,23] +# ! [PySnippetUMeshAdvBuild1_1] +# ! [PySnippetUMeshAdvBuild1_2] + mesh=MEDCouplingUMesh("My2DMesh",2) +# ! [PySnippetUMeshAdvBuild1_2] +# ! [PySnippetUMeshAdvBuild1_3] + nodalConn=DataArrayInt(nodalConnPerCell,23,1) + nodalConnI=DataArrayInt(nodalConnPerCellIndex,6,1) + mesh.setConnectivity(nodalConn,nodalConnI,True) +# ! [PySnippetUMeshAdvBuild1_3] +# ! [PySnippetUMeshAdvBuild1_4] + coordsArr=DataArrayDouble(coords,9,3)#here coordsArr are declared to have 3 components, mesh will deduce that its spaceDim==3. + mesh.setCoords(coordsArr)#coordsArr contains 9 tuples, that is to say mesh contains 9 nodes. +# ! [PySnippetUMeshAdvBuild1_4] +# ! [PySnippetUMeshAdvBuild1_5] +# ! [PySnippetUMeshAdvBuild1_5] + mesh.checkCoherency() + return + + def testExampleDataArrayBuild1(self): +# ! [PySnippetDataArrayBuild1_0] + dataDouble=[0.,10.,20.,1.,11.,21.,2.,12.,22.,3.,13.,23.,4.,14.,24.] +# ! [PySnippetDataArrayBuild1_0] +# ! [PySnippetDataArrayBuild1_1] + arrayDouble=DataArrayDouble() + arrayDouble.setValues(dataDouble,5,3)# 5 tuples containing each 3 components +# ! [PySnippetDataArrayBuild1_1] +# ! [PySnippetDataArrayBuild1_1bis] + arrayDouble=DataArrayDouble(dataDouble,5,3) +# ! [PySnippetDataArrayBuild1_1bis] +# ! [PySnippetDataArrayBuild1_2] + dataInt=[0, 10, 20, 1, 11, 21, 2, 12, 22, 3, 13, 23, 4, 14, 24] +# ! [PySnippetDataArrayBuild1_2] +# ! [PySnippetDataArrayBuild1_3] + arrayInt=DataArrayInt() + arrayInt.setValues(dataInt,5,3)# 5 tuples containing each 3 components +# ! [PySnippetDataArrayBuild1_3] +# ! [PySnippetDataArrayBuild1_3bis] + arrayInt=DataArrayInt(dataInt,5,3) +# ! [PySnippetDataArrayBuild1_3bis] + return + + def testExampleFieldDoubleBuild1(self): + XCoords=[-0.3,0.07,0.1,0.3,0.45,0.47,0.49,1.,1.22]; arrX=DataArrayDouble(XCoords) + YCoords=[0.07,0.1,0.37,0.45,0.47,0.49,1.007]; arrY=DataArrayDouble(YCoords) + mesh=MEDCouplingCMesh("My2D_CMesh") + mesh.setCoords(arrX,arrY) +# ! [PySnippetFieldDoubleBuild1_1] + fieldOnCells=MEDCouplingFieldDouble(ON_CELLS,NO_TIME) + fieldOnCells.setName("MyTensorFieldOnCellNoTime") + fieldOnCells.setMesh(mesh) + array=DataArrayDouble() + array.alloc(fieldOnCells.getMesh().getNumberOfCells(),9) # Implicitely fieldOnCells will be a 9 components field. + array.fillWithValue(7.) + fieldOnCells.setArray(array) + # fieldOnCells is now usable + # ... +# ! [PySnippetFieldDoubleBuild1_1] +# ! [PySnippetFieldDoubleBuild1_2] + f1=mesh.fillFromAnalytic(ON_CELLS,1,"x*x+y*y*3+2.*x") # f1 is scalar + f2=mesh.fillFromAnalytic(ON_CELLS,1,"cos(x+y/x)") # f2 is scalar too + f2bis=mesh.fillFromAnalytic(ON_CELLS,2,"x*x*IVec+3*y*JVec") # f2bis is a vectors field + f3=f1+f2 # f3 scalar + f4=f3/f2 # f4 scalar + f2bis.applyFunc(1,"sqrt(x*x+y*y)") # f2bis becomes scalar + f5=f2bis*f4 # f5 scalar + pos1=[0.48,0.38] + res=f4.getValueOn(pos1) # f4 is scalar so the returned value is of size 1. + # ... +# ! [PySnippetFieldDoubleBuild1_2] +# ! [PySnippetFieldDoubleBuild1_3] +# ! [PySnippetFieldDoubleBuild1_3] + return + + def testExampleFieldDoubleBuild2(self): + XCoords=[-0.3,0.,0.1,0.3,0.45,0.47,0.49,1.,1.22]; arrX=DataArrayDouble(XCoords) + YCoords=[0.,0.1,0.37,0.45,0.47,0.49,1.007]; arrY=DataArrayDouble(YCoords) + mesh=MEDCouplingCMesh("My2D_CMesh") + mesh.setCoords(arrX,arrY) +# ! [PySnippetFieldDoubleBuild2_1] + fieldOnNodes=MEDCouplingFieldDouble(ON_NODES,NO_TIME) + fieldOnNodes.setName("MyScalarFieldOnNodeNoTime") + fieldOnNodes.setMesh(mesh) + array=DataArrayDouble() + array.alloc(fieldOnNodes.getMesh().getNumberOfNodes(),1) # Implicitely fieldOnNodes will be a 1 component field. + array.fillWithValue(7.) + fieldOnNodes.setArray(array) + # fieldOnNodes is now usable + # ... +# ! [PySnippetFieldDoubleBuild2_1] + return + + def testExampleFieldDoubleBuild3(self): + XCoords=[-0.3,0.,0.1,0.3,0.45,0.47,0.49,1.,1.22]; arrX=DataArrayDouble(XCoords) + YCoords=[0.,0.1,0.37,0.45,0.47,0.49,1.007]; arrY=DataArrayDouble(YCoords) + mesh=MEDCouplingCMesh("My2D_CMesh") + mesh.setCoords(arrX,arrY) +# ! [PySnippetFieldDoubleBuild3_1] + fieldOnCells=MEDCouplingFieldDouble(ON_CELLS,ONE_TIME) + fieldOnCells.setName("MyTensorFieldOnCellNoTime") + fieldOnCells.setTimeUnit("ms") # Time unit is ms. + fieldOnCells.setTime(4.22,2,-1) # Time attached is 4.22 ms, iteration id is 2 and order id (or sub iteration id) is -1 + fieldOnCells.setMesh(mesh) + array=DataArrayDouble() + array.alloc(fieldOnCells.getMesh().getNumberOfCells(),2) # Implicitely fieldOnCells will be a 2 components field. + array.fillWithValue(7.) + fieldOnCells.setArray(array) + # fieldOnCells is now usable + # ... +# ! [PySnippetFieldDoubleBuild3_1] + return + + def testExampleFieldDoubleBuild4(self): + XCoords=[-0.3,0.,0.1,0.3,0.45,0.47,0.49,1.,1.22]; arrX=DataArrayDouble(XCoords) + YCoords=[0.,0.1,0.37,0.45,0.47,0.49,1.007]; arrY=DataArrayDouble(YCoords) + mesh=MEDCouplingCMesh("My2D_CMesh") + mesh.setCoords(arrX,arrY) +# ! [PySnippetFieldDoubleBuild4_1] + fieldOnNodes=MEDCouplingFieldDouble(ON_NODES,CONST_ON_TIME_INTERVAL) + fieldOnNodes.setName("MyVecFieldOnNodeWithConstTime") + fieldOnNodes.setTimeUnit("ms") # Time unit is ms. + fieldOnNodes.setStartTime(4.22,2,-1) + fieldOnNodes.setEndTime(6.44,4,-1)# fieldOnNodes is defined in interval [4.22 ms,6.44 ms] + fieldOnNodes.setMesh(mesh) + array=DataArrayDouble() + array.alloc(fieldOnNodes.getMesh().getNumberOfNodes(),3) # Implicitely fieldOnNodes will be a 3 components field. + array.fillWithValue(7.) + fieldOnNodes.setArray(array) + # fieldOnNodes is now usable + # ... +# ! [PySnippetFieldDoubleBuild4_1] + return + + def testExampleDataArrayApplyFunc1(self): +# ! [PySnippetDataArrayApplyFunc1_1] + d=DataArrayDouble([1.,2.,11.,12.,21.,22.,31.,41.],4,2) + self.assertRaises(InterpKernelException,d.applyFunc,"x*y") +# ! [PySnippetDataArrayApplyFunc1_1] +# ! [PySnippetDataArrayApplyFunc1_2] + d=DataArrayDouble([1.,2.,11.,12.,21.,22.,31.,41.],4,2) + d1=d.applyFunc("smth*smth") + self.assertTrue(d1.isEqual(DataArrayDouble([1.,4.,121.,144.,441.,484.,961.,1681.],4,2),1e-12)) +# ! [PySnippetDataArrayApplyFunc1_2] +# ! [PySnippetDataArrayApplyFunc1_3] + d2=d.applyFunc(2,"smth1*IVec+2*smth2*JVec") + self.assertTrue(d2.isEqual(DataArrayDouble([1.,4.,11.,24.,21.,44.,31.,82.],4,2),1e-12)) +# ! [PySnippetDataArrayApplyFunc1_3] +# ! [PySnippetDataArrayApplyFunc1_4] + dd=DataArrayDouble([1.,4.,3.,11.,144.,13.,21.,484.,23.,31.,1024.,33.],4,3) +# ! [PySnippetDataArrayApplyFunc1_4] +# ! [PySnippetDataArrayApplyFunc1_5] + dd1=dd.applyFunc(1,"f+sqrt(g)+h") + self.assertTrue(dd1.isEqual(DataArrayDouble([6.,36.,66.,96.],4,1),1e-12)) +# ! [PySnippetDataArrayApplyFunc1_5] +# ! [PySnippetDataArrayApplyFunc1_6] + dd2=dd.applyFunc(1,"a+0.*b+c") + self.assertTrue(dd2.isEqual(DataArrayDouble([4.,24.,44.,64.],4,1),1e-12)) +# ! [PySnippetDataArrayApplyFunc1_6] +# ! [PySnippetDataArrayApplyFunc1_7] + ddd=DataArrayDouble([1.,4.,3.,11.,144.,13.,21.,484.,23.,31.,1024.,33.],4,3) + ddd.setInfoOnComponents(["Y [m]","AA [m/s]","GG [MW]"]) +# ! [PySnippetDataArrayApplyFunc1_7] +# ! [PySnippetDataArrayApplyFunc1_8] + ddd1=ddd.applyFunc2(1,"Y+GG") + self.assertTrue(ddd1.isEqual(DataArrayDouble([4.,24.,44.,64.],4,1),1e-12)) +# ! [PySnippetDataArrayApplyFunc1_8] +# ! [PySnippetDataArrayApplyFunc1_9] + ddd1=ddd.applyFunc3(1,["X","Y","Z"],"X+Z") + self.assertTrue(ddd1.isEqual(DataArrayDouble([4.,24.,44.,64.],4,1),1e-12)) +# ! [PySnippetDataArrayApplyFunc1_9] + return + + pass + +unittest.main() diff --git a/src/medtool/src/MEDCoupling_Swig/MEDCouplingFieldDiscretization.i b/src/medtool/src/MEDCoupling_Swig/MEDCouplingFieldDiscretization.i new file mode 100644 index 000000000..bf4732b14 --- /dev/null +++ b/src/medtool/src/MEDCoupling_Swig/MEDCouplingFieldDiscretization.i @@ -0,0 +1,472 @@ +// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 +// 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) + +%newobject ParaMEDMEM::MEDCouplingFieldDiscretization::New; +%newobject ParaMEDMEM::MEDCouplingFieldDiscretization::deepCpy; +%newobject ParaMEDMEM::MEDCouplingFieldDiscretization::clone; +%newobject ParaMEDMEM::MEDCouplingFieldDiscretization::clonePartRange; +%newobject ParaMEDMEM::MEDCouplingFieldDiscretization::getOffsetArr; +%newobject ParaMEDMEM::MEDCouplingFieldDiscretization::getLocalizationOfDiscValues; +%newobject ParaMEDMEM::MEDCouplingFieldDiscretization::getMeasureField; +%newobject ParaMEDMEM::MEDCouplingFieldDiscretization::clonePart; +%newobject ParaMEDMEM::MEDCouplingFieldDiscretization::getValueOnMulti; +%newobject ParaMEDMEM::MEDCouplingFieldDiscretization::computeTupleIdsToSelectFromCellIds; +%newobject ParaMEDMEM::MEDCouplingFieldDiscretizationKriging::PerformDriftOfVec; + +namespace ParaMEDMEM +{ + class MEDCouplingFieldDiscretization : public RefCountObject, public TimeLabel + { + public: + static MEDCouplingFieldDiscretization *New(TypeOfField type) throw(INTERP_KERNEL::Exception); + double getPrecision() const throw(INTERP_KERNEL::Exception); + void setPrecision(double val) throw(INTERP_KERNEL::Exception); + static TypeOfField GetTypeOfFieldFromStringRepr(const std::string& repr) throw(INTERP_KERNEL::Exception); + virtual TypeOfField getEnum() const throw(INTERP_KERNEL::Exception); + virtual bool isEqual(const MEDCouplingFieldDiscretization *other, double eps) const throw(INTERP_KERNEL::Exception); + virtual bool isEqualIfNotWhy(const MEDCouplingFieldDiscretization *other, double eps, std::string& reason) const throw(INTERP_KERNEL::Exception); + virtual bool isEqualWithoutConsideringStr(const MEDCouplingFieldDiscretization *other, double eps) const throw(INTERP_KERNEL::Exception); + virtual MEDCouplingFieldDiscretization *deepCpy() const throw(INTERP_KERNEL::Exception); + virtual MEDCouplingFieldDiscretization *clone() const throw(INTERP_KERNEL::Exception); + virtual MEDCouplingFieldDiscretization *clonePartRange(int beginCellIds, int endCellIds, int stepCellIds) const throw(INTERP_KERNEL::Exception); + virtual std::string getStringRepr() const throw(INTERP_KERNEL::Exception); + virtual const char *getRepr() const throw(INTERP_KERNEL::Exception); + virtual int getNumberOfTuples(const MEDCouplingMesh *mesh) const throw(INTERP_KERNEL::Exception); + virtual int getNumberOfMeshPlaces(const MEDCouplingMesh *mesh) const throw(INTERP_KERNEL::Exception); + virtual DataArrayInt *getOffsetArr(const MEDCouplingMesh *mesh) const throw(INTERP_KERNEL::Exception); + virtual DataArrayDouble *getLocalizationOfDiscValues(const MEDCouplingMesh *mesh) const throw(INTERP_KERNEL::Exception); + virtual void checkCompatibilityWithNature(NatureOfField nat) const throw(INTERP_KERNEL::Exception); + 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 DataArray *da) const throw(INTERP_KERNEL::Exception); + virtual MEDCouplingFieldDouble *getMeasureField(const MEDCouplingMesh *mesh, bool isAbs) const throw(INTERP_KERNEL::Exception); + virtual void setGaussLocalizationOnType(const MEDCouplingMesh *m, INTERP_KERNEL::NormalizedCellType type, const std::vector<double>& refCoo, + const std::vector<double>& gsCoo, const std::vector<double>& wg) throw(INTERP_KERNEL::Exception); + virtual void clearGaussLocalizations() throw(INTERP_KERNEL::Exception); + virtual MEDCouplingGaussLocalization& getGaussLocalization(int locId) throw(INTERP_KERNEL::Exception); + virtual int getNbOfGaussLocalization() const throw(INTERP_KERNEL::Exception); + virtual int getGaussLocalizationIdOfOneCell(int cellId) const throw(INTERP_KERNEL::Exception); + virtual int getGaussLocalizationIdOfOneType(INTERP_KERNEL::NormalizedCellType type) const throw(INTERP_KERNEL::Exception); + %extend + { + virtual MEDCouplingFieldDiscretization *clonePart(PyObject *li) + { + int sz=0,sw=-1,val1=-1; + std::vector<int> val2; + const int *inp=convertObjToPossibleCpp1_Safe(li,sw,sz,val1,val2); + return self->clonePart(inp,inp+sz); + } + + virtual PyObject *buildSubMeshDataRange(const MEDCouplingMesh *mesh, int beginCellIds, int endCellIds, int stepCellIds, int& beginOut, int& endOut, int& stepOut, DataArrayInt *&di) const throw(INTERP_KERNEL::Exception) + { + DataArrayInt *ret1=0; + int bb,ee,ss; + MEDCouplingMesh *ret0=self->buildSubMeshDataRange(mesh,beginCellIds,endCellIds,stepCellIds,bb,ee,ss,ret1); + PyObject *res=PyTuple_New(2); + PyTuple_SetItem(res,0,convertMesh(ret0, SWIG_POINTER_OWN | 0 )); + if(ret1) + PyTuple_SetItem(res,1,SWIG_NewPointerObj((void*)ret1,SWIGTYPE_p_ParaMEDMEM__DataArrayInt,SWIG_POINTER_OWN | 0)); + else + { + PyObject *res1=PySlice_New(PyInt_FromLong(bb),PyInt_FromLong(ee),PyInt_FromLong(ss)); + PyTuple_SetItem(res,1,res1); + } + return res; + } + + virtual int getNumberOfTuplesExpectedRegardingCode(PyObject *code, PyObject *idsPerType) const throw(INTERP_KERNEL::Exception) + { + std::vector<int> inp0; + convertPyToNewIntArr4(code,1,3,inp0); + std::vector<const DataArrayInt *> inp1; + convertFromPyObjVectorOfObj<const ParaMEDMEM::DataArrayInt *>(idsPerType,SWIGTYPE_p_ParaMEDMEM__DataArrayInt,"DataArrayInt",inp1); + return self->getNumberOfTuplesExpectedRegardingCode(inp0,inp1); + } + + virtual PyObject *computeMeshRestrictionFromTupleIds(const MEDCouplingMesh *mesh, PyObject *tupleIds) const throw(INTERP_KERNEL::Exception) + { + std::vector<int> vVal; int iVal=-1; + int sz=-1,sw=0; + const int *tupleIdsBg=convertObjToPossibleCpp1_Safe(tupleIds,sw,sz,iVal,vVal); + if(sw==0) + throw INTERP_KERNEL::Exception("MEDCouplingFieldDiscretization::computeMeshRestrictionFromTupleIds : none parameter in input !"); + DataArrayInt *ret0=0,*ret1=0; + self->computeMeshRestrictionFromTupleIds(mesh,tupleIdsBg,tupleIdsBg+sz,ret0,ret1); + PyObject *pyRet=PyTuple_New(2); + PyTuple_SetItem(pyRet,0,SWIG_NewPointerObj(SWIG_as_voidptr(ret0),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 )); + PyTuple_SetItem(pyRet,1,SWIG_NewPointerObj(SWIG_as_voidptr(ret1),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 )); + return pyRet; + } + + virtual PyObject *normL1(const MEDCouplingMesh *mesh, const DataArrayDouble *arr) const throw(INTERP_KERNEL::Exception) + { + if(!arr) + throw INTERP_KERNEL::Exception("wrap of MEDCouplingFieldDiscretization::normL1 : input array is null !"); + int sz(arr->getNumberOfComponents()); + INTERP_KERNEL::AutoPtr<double> tmp=new double[sz]; + self->normL1(mesh,arr,tmp); + return convertDblArrToPyList(tmp,sz); + } + + virtual PyObject *normL2(const MEDCouplingMesh *mesh, const DataArrayDouble *arr) const throw(INTERP_KERNEL::Exception) + { + if(!arr) + throw INTERP_KERNEL::Exception("wrap of MEDCouplingFieldDiscretization::normL2 : input array is null !"); + int sz(arr->getNumberOfComponents()); + INTERP_KERNEL::AutoPtr<double> tmp=new double[sz]; + self->normL2(mesh,arr,tmp); + return convertDblArrToPyList(tmp,sz); + } + + virtual PyObject *integral(const MEDCouplingMesh *mesh, const DataArrayDouble *arr, bool isWAbs) const throw(INTERP_KERNEL::Exception) + { + if(!arr) + throw INTERP_KERNEL::Exception("wrap of MEDCouplingFieldDiscretization::integral : input array is null !"); + int sz(arr->getNumberOfComponents()); + INTERP_KERNEL::AutoPtr<double> tmp=new double[sz]; + self->integral(mesh,arr,isWAbs,tmp); + return convertDblArrToPyList(tmp,sz); + } + + virtual PyObject *getCellIdsHavingGaussLocalization(int locId) const throw(INTERP_KERNEL::Exception) + { + std::vector<int> tmp; + self->getCellIdsHavingGaussLocalization(locId,tmp); + DataArrayInt *ret=DataArrayInt::New(); + ret->alloc((int)tmp.size(),1); + std::copy(tmp.begin(),tmp.end(),ret->getPointer()); + return SWIG_NewPointerObj(SWIG_as_voidptr(ret),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 ); + } + + virtual void setGaussLocalizationOnCells(const MEDCouplingMesh *m, PyObject *li, const std::vector<double>& refCoo, + const std::vector<double>& gsCoo, const std::vector<double>& wg) throw(INTERP_KERNEL::Exception) + { + void *da=0; + int res1=SWIG_ConvertPtr(li,&da,SWIGTYPE_p_ParaMEDMEM__DataArrayInt, 0 | 0 ); + if (!SWIG_IsOK(res1)) + { + int size; + INTERP_KERNEL::AutoPtr<int> tmp=convertPyToNewIntArr2(li,&size); + self->setGaussLocalizationOnCells(m,tmp,((int *)tmp)+size,refCoo,gsCoo,wg); + } + else + { + DataArrayInt *da2=reinterpret_cast< DataArrayInt * >(da); + if(!da2) + throw INTERP_KERNEL::Exception("Not null DataArrayInt instance expected !"); + da2->checkAllocated(); + self->setGaussLocalizationOnCells(m,da2->getConstPointer(),da2->getConstPointer()+da2->getNbOfElems(),refCoo,gsCoo,wg); + } + } + + virtual PyObject *getGaussLocalizationIdsOfOneType(INTERP_KERNEL::NormalizedCellType type) const throw(INTERP_KERNEL::Exception) + { + std::set<int> ret=self->getGaussLocalizationIdsOfOneType(type); + return convertIntArrToPyList3(ret); + } + + virtual PyObject *getValueOn(const DataArrayDouble *arr, const MEDCouplingMesh *mesh, PyObject *sl) const throw(INTERP_KERNEL::Exception) + { + double val; + DataArrayDouble *a; + DataArrayDoubleTuple *aa; + std::vector<double> bb; + int sw; + if(!mesh) + throw INTERP_KERNEL::Exception("Python wrap of MEDCouplingFieldDiscretization::getValueOn : no underlying mesh !"); + int spaceDim=mesh->getSpaceDimension(); + const char msg[]="Python wrap of MEDCouplingFieldDiscretization::getValueOn : "; + const double *spaceLoc=convertObjToPossibleCpp5_Safe(sl,sw,val,a,aa,bb,msg,1,spaceDim,true); + // + INTERP_KERNEL::AutoPtr<double> res(new double[spaceDim]); + self->getValueOn(arr,mesh,spaceLoc,res); + return convertDblArrToPyList(res,spaceDim); + } + + virtual PyObject *getValueOnPos(const DataArrayDouble *arr, const MEDCouplingMesh *mesh, int i, int j, int k) const throw(INTERP_KERNEL::Exception) + { + if(!arr) + throw INTERP_KERNEL::Exception("wrap of MEDCouplingFieldDiscretization::getValueOnPos : input array is null !"); + int sz(arr->getNumberOfComponents()); + INTERP_KERNEL::AutoPtr<double> res=new double[sz]; + self->getValueOnPos(arr,mesh,i,j,k,res); + return convertDblArrToPyList(res,sz); + } + + virtual DataArrayDouble *getValueOnMulti(const DataArrayDouble *arr, const MEDCouplingMesh *mesh, PyObject *loc) const throw(INTERP_KERNEL::Exception) + { + if(!mesh) + throw INTERP_KERNEL::Exception("Python wrap MEDCouplingFieldDiscretization::getValueOnMulti : null input mesh !"); + // + int sw,nbPts; + double v0; ParaMEDMEM::DataArrayDouble *v1(0); ParaMEDMEM::DataArrayDoubleTuple *v2(0); std::vector<double> v3; + const double *inp=convertObjToPossibleCpp5_Safe2(loc,sw,v0,v1,v2,v3,"wrap of MEDCouplingFieldDouble::getValueOnMulti", + mesh->getSpaceDimension(),true,nbPts); + return self->getValueOnMulti(arr,mesh,inp,nbPts); + } + + virtual void renumberCells(PyObject *li, bool check=true) throw(INTERP_KERNEL::Exception) + { + int sw,sz(-1); + int v0; std::vector<int> v1; + const int *ids(convertObjToPossibleCpp1_Safe(li,sw,sz,v0,v1)); + self->renumberCells(ids,check); + } + + virtual void renumberArraysForCell(const MEDCouplingMesh *mesh, PyObject *arrays, + PyObject *old2New, bool check) throw(INTERP_KERNEL::Exception) + { + std::vector<DataArray *> input1; + convertFromPyObjVectorOfObj<ParaMEDMEM::DataArray *>(arrays,SWIGTYPE_p_ParaMEDMEM__DataArray,"DataArray",input1); + // + int sw,sz(-1); + int v0; std::vector<int> v1; + const int *old2NewBg(convertObjToPossibleCpp1_Safe(old2New,sw,sz,v0,v1)); + // + self->renumberArraysForCell(mesh,input1,old2NewBg,check); + } + + virtual DataArrayInt *computeTupleIdsToSelectFromCellIds(const MEDCouplingMesh *mesh, PyObject *cellIds) const throw(INTERP_KERNEL::Exception) + { + int sw,sz(-1); + int v0; std::vector<int> v1; + const int *cellIdsBg(convertObjToPossibleCpp1_Safe(cellIds,sw,sz,v0,v1)); + return self->computeTupleIdsToSelectFromCellIds(mesh,cellIdsBg,cellIdsBg+sz); + } + + virtual PyObject *buildSubMeshData(const MEDCouplingMesh *mesh, PyObject *ids) const throw(INTERP_KERNEL::Exception) + { + int sw,sz(-1); + int v0; std::vector<int> v1; + const int *idsBg(convertObjToPossibleCpp1_Safe(ids,sw,sz,v0,v1)); + DataArrayInt *di(0); + MEDCouplingMesh *ret0=self->buildSubMeshData(mesh,idsBg,idsBg+sz,di); + PyObject *ret=PyTuple_New(2); + PyTuple_SetItem(ret,0,convertMesh(ret0, SWIG_POINTER_OWN | 0 )); + PyTuple_SetItem(ret,1,SWIG_NewPointerObj(SWIG_as_voidptr(di),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 )); + return ret; + } + + virtual void renumberValuesOnNodes(double epsOnVals, PyObject *old2New, int newNbOfNodes, DataArrayDouble *arr) const throw(INTERP_KERNEL::Exception) + { + int sw,sz(-1); + int v0; std::vector<int> v1; + const int *old2NewBg(convertObjToPossibleCpp1_Safe(old2New,sw,sz,v0,v1)); + self->renumberValuesOnNodes(epsOnVals,old2NewBg,newNbOfNodes,arr); + } + + virtual void renumberValuesOnCells(double epsOnVals, const MEDCouplingMesh *mesh, PyObject *old2New, int newSz, DataArrayDouble *arr) const throw(INTERP_KERNEL::Exception) + { + int sw,sz(-1); + int v0; std::vector<int> v1; + const int *old2NewBg(convertObjToPossibleCpp1_Safe(old2New,sw,sz,v0,v1)); + self->renumberValuesOnCells(epsOnVals,mesh,old2NewBg,newSz,arr); + } + + virtual void renumberValuesOnCellsR(const MEDCouplingMesh *mesh, PyObject *new2old, int newSz, DataArrayDouble *arr) const throw(INTERP_KERNEL::Exception) + { + int sw,sz(-1); + int v0; std::vector<int> v1; + const int *new2oldBg(convertObjToPossibleCpp1_Safe(new2old,sw,sz,v0,v1)); + self->renumberValuesOnCellsR(mesh,new2oldBg,newSz,arr); + } + } + }; + + class MEDCouplingFieldDiscretizationP0 : public MEDCouplingFieldDiscretization + { + }; + + class MEDCouplingFieldDiscretizationOnNodes : public MEDCouplingFieldDiscretization + { + }; + + class MEDCouplingFieldDiscretizationP1 : public MEDCouplingFieldDiscretizationOnNodes + { + }; + + class MEDCouplingFieldDiscretizationPerCell : public MEDCouplingFieldDiscretization + { + public: + void setArrayOfDiscIds(const DataArrayInt *adids) throw(INTERP_KERNEL::Exception); + void checkNoOrphanCells() const throw(INTERP_KERNEL::Exception); + %extend + { + PyObject *getArrayOfDiscIds() const + { + DataArrayInt *ret=const_cast<DataArrayInt *>(self->getArrayOfDiscIds()); + if(ret) + ret->incrRef(); + return SWIG_NewPointerObj(SWIG_as_voidptr(ret),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 ); + } + + PyObject *splitIntoSingleGaussDicrPerCellType() const throw(INTERP_KERNEL::Exception) + { + std::vector<int> ret1; + std::vector<DataArrayInt *> ret0=self->splitIntoSingleGaussDicrPerCellType(ret1); + std::size_t sz=ret0.size(); + PyObject *pyRet=PyTuple_New(2); + PyObject *pyRet0=PyList_New((int)sz); + PyObject *pyRet1=PyList_New((int)sz); + for(std::size_t i=0;i<sz;i++) + { + PyList_SetItem(pyRet0,i,SWIG_NewPointerObj(SWIG_as_voidptr(ret0[i]),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 )); + PyList_SetItem(pyRet1,i,PyInt_FromLong(ret1[i])); + } + PyTuple_SetItem(pyRet,0,pyRet0); + PyTuple_SetItem(pyRet,1,pyRet1); + return pyRet; + } + } + protected: + ~MEDCouplingFieldDiscretizationPerCell(); + }; + + class MEDCouplingFieldDiscretizationGauss : public MEDCouplingFieldDiscretizationPerCell + { + public: + MEDCouplingFieldDiscretizationGauss(); + }; + + class MEDCouplingFieldDiscretizationGaussNE : public MEDCouplingFieldDiscretization + { + public: + %extend + { + static PyObject *GetWeightArrayFromGeometricType(INTERP_KERNEL::NormalizedCellType geoType) throw(INTERP_KERNEL::Exception) + { + std::size_t sz(0); + const double *ret(MEDCouplingFieldDiscretizationGaussNE::GetWeightArrayFromGeometricType(geoType,sz)); + return convertDblArrToPyList(ret,sz); + } + + static PyObject *GetRefCoordsFromGeometricType(INTERP_KERNEL::NormalizedCellType geoType) throw(INTERP_KERNEL::Exception) + { + std::size_t sz(0); + const double *ret(MEDCouplingFieldDiscretizationGaussNE::GetRefCoordsFromGeometricType(geoType,sz)); + return convertDblArrToPyList(ret,sz); + } + + static PyObject *GetLocsFromGeometricType(INTERP_KERNEL::NormalizedCellType geoType) throw(INTERP_KERNEL::Exception) + { + std::size_t sz(0); + const double *ret(MEDCouplingFieldDiscretizationGaussNE::GetLocsFromGeometricType(geoType,sz)); + return convertDblArrToPyList(ret,sz); + } + } + }; + + class MEDCouplingFieldDiscretizationKriging : public MEDCouplingFieldDiscretizationOnNodes + { + public: + static DataArrayDouble *PerformDriftOfVec(const DataArrayDouble *arr, int isDrift) throw(INTERP_KERNEL::Exception); + %extend + { + PyObject *computeVectorOfCoefficients(const MEDCouplingMesh *mesh, const DataArrayDouble *arr) const throw(INTERP_KERNEL::Exception) + { + int ret1; + DataArrayDouble *ret0=self->computeVectorOfCoefficients(mesh,arr,ret1); + PyObject *ret=PyTuple_New(2); + PyTuple_SetItem(ret,0,SWIG_NewPointerObj(SWIG_as_voidptr(ret0),SWIGTYPE_p_ParaMEDMEM__DataArrayDouble, SWIG_POINTER_OWN | 0 )); + PyTuple_SetItem(ret,1,PyInt_FromLong(ret1)); + return ret; + } + + PyObject *computeInverseMatrix(const MEDCouplingMesh *mesh) const throw(INTERP_KERNEL::Exception) + { + int ret1(-1),ret2(-1); + DataArrayDouble *ret0=self->computeInverseMatrix(mesh,ret1,ret2); + PyObject *ret=PyTuple_New(3); + PyTuple_SetItem(ret,0,SWIG_NewPointerObj(SWIG_as_voidptr(ret0),SWIGTYPE_p_ParaMEDMEM__DataArrayDouble, SWIG_POINTER_OWN | 0 )); + PyTuple_SetItem(ret,1,PyInt_FromLong(ret1)); + PyTuple_SetItem(ret,2,PyInt_FromLong(ret2)); + return ret; + } + + PyObject *computeMatrix(const MEDCouplingMesh *mesh) const throw(INTERP_KERNEL::Exception) + { + int ret1(-1),ret2(-1); + DataArrayDouble *ret0=self->computeMatrix(mesh,ret1,ret2); + PyObject *ret=PyTuple_New(3); + PyTuple_SetItem(ret,0,SWIG_NewPointerObj(SWIG_as_voidptr(ret0),SWIGTYPE_p_ParaMEDMEM__DataArrayDouble, SWIG_POINTER_OWN | 0 )); + PyTuple_SetItem(ret,1,PyInt_FromLong(ret1)); + PyTuple_SetItem(ret,2,PyInt_FromLong(ret2)); + return ret; + } + + PyObject *computeEvaluationMatrixOnGivenPts(const MEDCouplingMesh *mesh, PyObject *locs) const throw(INTERP_KERNEL::Exception) + { + if(!mesh) + throw INTERP_KERNEL::Exception("wrap of MEDCouplingFieldDiscretizationKriging::computeEvaluationMatrixOnGivenPts : input mesh is empty !"); + int sw,nbPts; + double v0; ParaMEDMEM::DataArrayDouble *v1(0); ParaMEDMEM::DataArrayDoubleTuple *v2(0); std::vector<double> v3; + const double *inp=convertObjToPossibleCpp5_Safe2(locs,sw,v0,v1,v2,v3,"wrap of MEDCouplingFieldDiscretizationKriging::computeEvaluationMatrixOnGivenPts", + mesh->getSpaceDimension(),true,nbPts); + // + int ret1(-1); + DataArrayDouble *ret0=self->computeEvaluationMatrixOnGivenPts(mesh,inp,nbPts,ret1); + PyObject *ret=PyTuple_New(2); + PyTuple_SetItem(ret,0,SWIG_NewPointerObj(SWIG_as_voidptr(ret0),SWIGTYPE_p_ParaMEDMEM__DataArrayDouble, SWIG_POINTER_OWN | 0 )); + PyTuple_SetItem(ret,1,PyInt_FromLong(ret1)); + return ret; + } + + void operateOnDenseMatrix(int spaceDimension, DataArrayDouble *myMatrix) const throw(INTERP_KERNEL::Exception) + { + if(!myMatrix || !myMatrix->isAllocated() || myMatrix->getNumberOfComponents()!=1) + throw INTERP_KERNEL::Exception("Wrap of MEDCouplingFieldDiscretizationKriging::operateOnDenseMatrix : invalid input matrix as DataArrayDouble ! Must be allocated with one component !"); + self->operateOnDenseMatrix(spaceDimension,myMatrix->getNumberOfTuples(),myMatrix->getPointer()); + } + + PyObject *performDrift(const DataArrayDouble *matr, const DataArrayDouble *arr) const throw(INTERP_KERNEL::Exception) + { + int ret1(-1); + DataArrayDouble *ret0(self->performDrift(matr,arr,ret1)); + PyObject *res(PyTuple_New(2)); + PyTuple_SetItem(res,0,SWIG_NewPointerObj((void*)ret0,SWIGTYPE_p_ParaMEDMEM__DataArrayDouble,SWIG_POINTER_OWN | 0)); + PyTuple_SetItem(res,1,PyInt_FromLong(ret1)); + return res; + } + + static PyObject *PerformDriftRect(const DataArrayDouble *matr, const DataArrayDouble *arr) throw(INTERP_KERNEL::Exception) + { + int ret1(-1); + DataArrayDouble *ret0(MEDCouplingFieldDiscretizationKriging::PerformDriftRect(matr,arr,ret1)); + PyObject *res(PyTuple_New(2)); + PyTuple_SetItem(res,0,SWIG_NewPointerObj((void*)ret0,SWIGTYPE_p_ParaMEDMEM__DataArrayDouble,SWIG_POINTER_OWN | 0)); + PyTuple_SetItem(res,1,PyInt_FromLong(ret1)); + return res; + } + + static void OperateOnDenseMatrixH3(DataArrayDouble *myMatrix) throw(INTERP_KERNEL::Exception) + { + if(!myMatrix || !myMatrix->isAllocated() || myMatrix->getNumberOfComponents()!=1) + throw INTERP_KERNEL::Exception("Wrap of MEDCouplingFieldDiscretizationKriging::OperateOnDenseMatrixH3 : invalid input matrix as DataArrayDouble ! Must be allocated with one component !"); + MEDCouplingFieldDiscretizationKriging::OperateOnDenseMatrixH3(myMatrix->getNumberOfTuples(),myMatrix->getPointer()); + } + + static void OperateOnDenseMatrixH2Ln(DataArrayDouble *myMatrix) throw(INTERP_KERNEL::Exception) + { + if(!myMatrix || !myMatrix->isAllocated() || myMatrix->getNumberOfComponents()!=1) + throw INTERP_KERNEL::Exception("Wrap of MEDCouplingFieldDiscretizationKriging::OperateOnDenseMatrixH2Ln : invalid input matrix as DataArrayDouble ! Must be allocated with one component !"); + MEDCouplingFieldDiscretizationKriging::OperateOnDenseMatrixH2Ln(myMatrix->getNumberOfTuples(),myMatrix->getPointer()); + } + } + }; +} diff --git a/src/medtool/src/MEDCoupling_Swig/MEDCouplingFinalize.i b/src/medtool/src/MEDCoupling_Swig/MEDCouplingFinalize.i new file mode 100644 index 000000000..393dec9c8 --- /dev/null +++ b/src/medtool/src/MEDCoupling_Swig/MEDCouplingFinalize.i @@ -0,0 +1,102 @@ +// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 +// 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 +// + +%pythoncode %{ +InterpKernelException.__reduce__=INTERPKERNELExceptionReduce +DataArrayDouble.__new__=classmethod(ParaMEDMEMDataArrayDoublenew) +DataArrayDouble.__iadd__=ParaMEDMEMDataArrayDoubleIadd +DataArrayDouble.__isub__=ParaMEDMEMDataArrayDoubleIsub +DataArrayDouble.__imul__=ParaMEDMEMDataArrayDoubleImul +DataArrayDouble.__idiv__=ParaMEDMEMDataArrayDoubleIdiv +DataArrayDouble.__ipow__=ParaMEDMEMDataArrayDoubleIpow + +DataArrayInt.__new__=classmethod(ParaMEDMEMDataArrayIntnew) +DataArrayInt.__iadd__=ParaMEDMEMDataArrayIntIadd +DataArrayInt.__isub__=ParaMEDMEMDataArrayIntIsub +DataArrayInt.__imul__=ParaMEDMEMDataArrayIntImul +DataArrayInt.__idiv__=ParaMEDMEMDataArrayIntIdiv +DataArrayInt.__imod__=ParaMEDMEMDataArrayIntImod +DataArrayInt.__ipow__=ParaMEDMEMDataArrayIntIpow + +MEDCouplingFieldDouble.__iadd__=ParaMEDMEMMEDCouplingFieldDoubleIadd +MEDCouplingFieldDouble.__isub__=ParaMEDMEMMEDCouplingFieldDoubleIsub +MEDCouplingFieldDouble.__imul__=ParaMEDMEMMEDCouplingFieldDoubleImul +MEDCouplingFieldDouble.__idiv__=ParaMEDMEMMEDCouplingFieldDoubleIdiv +MEDCouplingFieldDouble.__ipow__=ParaMEDMEMMEDCouplingFieldDoubleIpow + +DataArrayDoubleTuple.__iadd__=ParaMEDMEMDataArrayDoubleTupleIadd +DataArrayDoubleTuple.__isub__=ParaMEDMEMDataArrayDoubleTupleIsub +DataArrayDoubleTuple.__imul__=ParaMEDMEMDataArrayDoubleTupleImul +DataArrayDoubleTuple.__idiv__=ParaMEDMEMDataArrayDoubleTupleIdiv + +DataArrayIntTuple.__iadd__=ParaMEDMEMDataArrayIntTupleIadd +DataArrayIntTuple.__isub__=ParaMEDMEMDataArrayIntTupleIsub +DataArrayIntTuple.__imul__=ParaMEDMEMDataArrayIntTupleImul +DataArrayIntTuple.__idiv__=ParaMEDMEMDataArrayIntTupleIdiv +DataArrayIntTuple.__imod__=ParaMEDMEMDataArrayIntTupleImod + +DenseMatrix.__iadd__=ParaMEDMEMDenseMatrixIadd +DenseMatrix.__isub__=ParaMEDMEMDenseMatrixIsub + +MEDCouplingUMesh.__new__=classmethod(ParaMEDMEMMEDCouplingUMeshnew) +MEDCoupling1DGTUMesh.__new__=classmethod(ParaMEDMEMMEDCoupling1DGTUMeshnew) +MEDCoupling1SGTUMesh.__new__=classmethod(ParaMEDMEMMEDCoupling1SGTUMeshnew) +MEDCouplingCurveLinearMesh.__new__=classmethod(ParaMEDMEMMEDCouplingCurveLinearMeshnew) +MEDCouplingCMesh.__new__=classmethod(ParaMEDMEMMEDCouplingCMeshnew) +MEDCouplingIMesh.__new__=classmethod(ParaMEDMEMMEDCouplingIMeshnew) +MEDCouplingExtrudedMesh.__new__=classmethod(ParaMEDMEMMEDCouplingExtrudedMeshnew) +MEDCouplingFieldDouble.__new__=classmethod(ParaMEDMEMMEDCouplingFieldDoublenew) + +del INTERPKERNELExceptionReduce +del ParaMEDMEMDataArrayDoublenew +del ParaMEDMEMDataArrayDoubleIadd +del ParaMEDMEMDataArrayDoubleIsub +del ParaMEDMEMDataArrayDoubleImul +del ParaMEDMEMDataArrayDoubleIdiv +del ParaMEDMEMMEDCouplingFieldDoubleIadd +del ParaMEDMEMMEDCouplingFieldDoubleIsub +del ParaMEDMEMMEDCouplingFieldDoubleImul +del ParaMEDMEMMEDCouplingFieldDoubleIdiv +del ParaMEDMEMMEDCouplingFieldDoubleIpow +del ParaMEDMEMDataArrayIntnew +del ParaMEDMEMDataArrayIntIadd +del ParaMEDMEMDataArrayIntIsub +del ParaMEDMEMDataArrayIntImul +del ParaMEDMEMDataArrayIntIdiv +del ParaMEDMEMDataArrayIntImod +del ParaMEDMEMDataArrayDoubleTupleIadd +del ParaMEDMEMDataArrayDoubleTupleIsub +del ParaMEDMEMDataArrayDoubleTupleImul +del ParaMEDMEMDataArrayDoubleTupleIdiv +del ParaMEDMEMDataArrayIntTupleIadd +del ParaMEDMEMDataArrayIntTupleIsub +del ParaMEDMEMDataArrayIntTupleImul +del ParaMEDMEMDataArrayIntTupleIdiv +del ParaMEDMEMDataArrayIntTupleImod +del ParaMEDMEMDenseMatrixIadd +del ParaMEDMEMDenseMatrixIsub +del ParaMEDMEMMEDCouplingUMeshnew +del ParaMEDMEMMEDCoupling1DGTUMeshnew +del ParaMEDMEMMEDCoupling1SGTUMeshnew +del ParaMEDMEMMEDCouplingCurveLinearMeshnew +del ParaMEDMEMMEDCouplingCMeshnew +del ParaMEDMEMMEDCouplingIMeshnew +del ParaMEDMEMMEDCouplingExtrudedMeshnew +del ParaMEDMEMMEDCouplingFieldDoublenew +%} diff --git a/src/medtool/src/MEDCoupling_Swig/MEDCouplingMemArray.i b/src/medtool/src/MEDCoupling_Swig/MEDCouplingMemArray.i new file mode 100644 index 000000000..3e4010867 --- /dev/null +++ b/src/medtool/src/MEDCoupling_Swig/MEDCouplingMemArray.i @@ -0,0 +1,6160 @@ +// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 +// 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) + +//////////////////// +%typemap(out) ParaMEDMEM::DataArray* +{ + $result=convertDataArray($1,$owner); +} + +%typemap(out) DataArray* +{ + $result=convertDataArray($1,$owner); +} +//$$$$$$$$$$$$$$$$$$ + +//////////////////// +%typemap(out) ParaMEDMEM::DataArrayChar* +{ + $result=convertDataArrayChar($1,$owner); +} + +%typemap(out) DataArrayChar* +{ + $result=convertDataArrayChar($1,$owner); +} +//$$$$$$$$$$$$$$$$$$ + +%newobject ParaMEDMEM::DataArray::deepCpy; +%newobject ParaMEDMEM::DataArray::selectByTupleRanges; +%newobject ParaMEDMEM::DataArray::selectByTupleId; +%newobject ParaMEDMEM::DataArray::selectByTupleIdSafe; +%newobject ParaMEDMEM::DataArray::selectByTupleId2; +%newobject ParaMEDMEM::DataArray::Aggregate; +%newobject ParaMEDMEM::DataArrayInt::New; +%newobject ParaMEDMEM::DataArrayInt::__iter__; +%newobject ParaMEDMEM::DataArrayInt::convertToDblArr; +%newobject ParaMEDMEM::DataArrayInt::performCpy; +%newobject ParaMEDMEM::DataArrayInt::substr; +%newobject ParaMEDMEM::DataArrayInt::changeNbOfComponents; +%newobject ParaMEDMEM::DataArrayInt::accumulatePerChunck; +%newobject ParaMEDMEM::DataArrayInt::checkAndPreparePermutation; +%newobject ParaMEDMEM::DataArrayInt::transformWithIndArrR; +%newobject ParaMEDMEM::DataArrayInt::renumber; +%newobject ParaMEDMEM::DataArrayInt::renumberR; +%newobject ParaMEDMEM::DataArrayInt::renumberAndReduce; +%newobject ParaMEDMEM::DataArrayInt::invertArrayO2N2N2O; +%newobject ParaMEDMEM::DataArrayInt::invertArrayN2O2O2N; +%newobject ParaMEDMEM::DataArrayInt::invertArrayO2N2N2OBis; +%newobject ParaMEDMEM::DataArrayInt::getIdsEqual; +%newobject ParaMEDMEM::DataArrayInt::getIdsNotEqual; +%newobject ParaMEDMEM::DataArrayInt::getIdsEqualList; +%newobject ParaMEDMEM::DataArrayInt::getIdsNotEqualList; +%newobject ParaMEDMEM::DataArrayInt::getIdsEqualTuple; +%newobject ParaMEDMEM::DataArrayInt::sumPerTuple; +%newobject ParaMEDMEM::DataArrayInt::negate; +%newobject ParaMEDMEM::DataArrayInt::computeAbs; +%newobject ParaMEDMEM::DataArrayInt::getIdsInRange; +%newobject ParaMEDMEM::DataArrayInt::getIdsNotInRange; +%newobject ParaMEDMEM::DataArrayInt::getIdsStrictlyNegative; +%newobject ParaMEDMEM::DataArrayInt::Aggregate; +%newobject ParaMEDMEM::DataArrayInt::AggregateIndexes; +%newobject ParaMEDMEM::DataArrayInt::Meld; +%newobject ParaMEDMEM::DataArrayInt::Add; +%newobject ParaMEDMEM::DataArrayInt::Substract; +%newobject ParaMEDMEM::DataArrayInt::Multiply; +%newobject ParaMEDMEM::DataArrayInt::Divide; +%newobject ParaMEDMEM::DataArrayInt::Pow; +%newobject ParaMEDMEM::DataArrayInt::BuildUnion; +%newobject ParaMEDMEM::DataArrayInt::BuildIntersection; +%newobject ParaMEDMEM::DataArrayInt::Range; +%newobject ParaMEDMEM::DataArrayInt::fromNoInterlace; +%newobject ParaMEDMEM::DataArrayInt::toNoInterlace; +%newobject ParaMEDMEM::DataArrayInt::buildComplement; +%newobject ParaMEDMEM::DataArrayInt::buildUnion; +%newobject ParaMEDMEM::DataArrayInt::buildSubstraction; +%newobject ParaMEDMEM::DataArrayInt::buildSubstractionOptimized; +%newobject ParaMEDMEM::DataArrayInt::buildIntersection; +%newobject ParaMEDMEM::DataArrayInt::buildUnique; +%newobject ParaMEDMEM::DataArrayInt::buildUniqueNotSorted; +%newobject ParaMEDMEM::DataArrayInt::deltaShiftIndex; +%newobject ParaMEDMEM::DataArrayInt::buildExplicitArrByRanges; +%newobject ParaMEDMEM::DataArrayInt::buildExplicitArrOfSliceOnScaledArr; +%newobject ParaMEDMEM::DataArrayInt::findRangeIdForEachTuple; +%newobject ParaMEDMEM::DataArrayInt::findIdInRangeForEachTuple; +%newobject ParaMEDMEM::DataArrayInt::duplicateEachTupleNTimes; +%newobject ParaMEDMEM::DataArrayInt::buildPermutationArr; +%newobject ParaMEDMEM::DataArrayInt::buildPermArrPerLevel; +%newobject ParaMEDMEM::DataArrayInt::getDifferentValues; +%newobject ParaMEDMEM::DataArrayInt::FindPermutationFromFirstToSecond; +%newobject ParaMEDMEM::DataArrayInt::CheckAndPreparePermutation; +%newobject ParaMEDMEM::DataArrayInt::__neg__; +%newobject ParaMEDMEM::DataArrayInt::__add__; +%newobject ParaMEDMEM::DataArrayInt::__radd__; +%newobject ParaMEDMEM::DataArrayInt::__sub__; +%newobject ParaMEDMEM::DataArrayInt::__rsub__; +%newobject ParaMEDMEM::DataArrayInt::__mul__; +%newobject ParaMEDMEM::DataArrayInt::__rmul__; +%newobject ParaMEDMEM::DataArrayInt::__div__; +%newobject ParaMEDMEM::DataArrayInt::__rdiv__; +%newobject ParaMEDMEM::DataArrayInt::__mod__; +%newobject ParaMEDMEM::DataArrayInt::__rmod__; +%newobject ParaMEDMEM::DataArrayInt::__pow__; +%newobject ParaMEDMEM::DataArrayInt::__rpow__; +%newobject ParaMEDMEM::DataArrayIntTuple::buildDAInt; +%newobject ParaMEDMEM::DataArrayChar::convertToIntArr; +%newobject ParaMEDMEM::DataArrayChar::renumber; +%newobject ParaMEDMEM::DataArrayChar::renumberR; +%newobject ParaMEDMEM::DataArrayChar::renumberAndReduce; +%newobject ParaMEDMEM::DataArrayChar::changeNbOfComponents; +%newobject ParaMEDMEM::DataArrayChar::getIdsEqual; +%newobject ParaMEDMEM::DataArrayChar::getIdsNotEqual; +%newobject ParaMEDMEM::DataArrayChar::Aggregate; +%newobject ParaMEDMEM::DataArrayChar::Meld; +%newobject ParaMEDMEM::DataArrayByte::New; +%newobject ParaMEDMEM::DataArrayByte::__iter__; +%newobject ParaMEDMEM::DataArrayByte::performCpy; +%newobject ParaMEDMEM::DataArrayByteTuple::buildDAByte; +%newobject ParaMEDMEM::DataArrayChar::substr; +%newobject ParaMEDMEM::DataArrayAsciiChar::New; +%newobject ParaMEDMEM::DataArrayAsciiChar::__iter__; +%newobject ParaMEDMEM::DataArrayAsciiChar::performCpy; +%newobject ParaMEDMEM::DataArrayAsciiCharTuple::buildDAAsciiChar; +%newobject ParaMEDMEM::DataArrayDouble::New; +%newobject ParaMEDMEM::DataArrayDouble::__iter__; +%newobject ParaMEDMEM::DataArrayDouble::convertToIntArr; +%newobject ParaMEDMEM::DataArrayDouble::performCpy; +%newobject ParaMEDMEM::DataArrayDouble::Aggregate; +%newobject ParaMEDMEM::DataArrayDouble::Meld; +%newobject ParaMEDMEM::DataArrayDouble::Dot; +%newobject ParaMEDMEM::DataArrayDouble::CrossProduct; +%newobject ParaMEDMEM::DataArrayDouble::Add; +%newobject ParaMEDMEM::DataArrayDouble::Substract; +%newobject ParaMEDMEM::DataArrayDouble::Multiply; +%newobject ParaMEDMEM::DataArrayDouble::Divide; +%newobject ParaMEDMEM::DataArrayDouble::Pow; +%newobject ParaMEDMEM::DataArrayDouble::substr; +%newobject ParaMEDMEM::DataArrayDouble::changeNbOfComponents; +%newobject ParaMEDMEM::DataArrayDouble::accumulatePerChunck; +%newobject ParaMEDMEM::DataArrayDouble::getIdsInRange; +%newobject ParaMEDMEM::DataArrayDouble::getIdsNotInRange; +%newobject ParaMEDMEM::DataArrayDouble::negate; +%newobject ParaMEDMEM::DataArrayDouble::computeAbs; +%newobject ParaMEDMEM::DataArrayDouble::applyFunc; +%newobject ParaMEDMEM::DataArrayDouble::applyFunc2; +%newobject ParaMEDMEM::DataArrayDouble::applyFunc3; +%newobject ParaMEDMEM::DataArrayDouble::doublyContractedProduct; +%newobject ParaMEDMEM::DataArrayDouble::determinant; +%newobject ParaMEDMEM::DataArrayDouble::eigenValues; +%newobject ParaMEDMEM::DataArrayDouble::eigenVectors; +%newobject ParaMEDMEM::DataArrayDouble::inverse; +%newobject ParaMEDMEM::DataArrayDouble::trace; +%newobject ParaMEDMEM::DataArrayDouble::deviator; +%newobject ParaMEDMEM::DataArrayDouble::magnitude; +%newobject ParaMEDMEM::DataArrayDouble::maxPerTuple; +%newobject ParaMEDMEM::DataArrayDouble::sumPerTuple; +%newobject ParaMEDMEM::DataArrayDouble::computeBBoxPerTuple; +%newobject ParaMEDMEM::DataArrayDouble::buildEuclidianDistanceDenseMatrix; +%newobject ParaMEDMEM::DataArrayDouble::buildEuclidianDistanceDenseMatrixWith; +%newobject ParaMEDMEM::DataArrayDouble::renumber; +%newobject ParaMEDMEM::DataArrayDouble::renumberR; +%newobject ParaMEDMEM::DataArrayDouble::renumberAndReduce; +%newobject ParaMEDMEM::DataArrayDouble::fromNoInterlace; +%newobject ParaMEDMEM::DataArrayDouble::toNoInterlace; +%newobject ParaMEDMEM::DataArrayDouble::fromPolarToCart; +%newobject ParaMEDMEM::DataArrayDouble::fromCylToCart; +%newobject ParaMEDMEM::DataArrayDouble::fromSpherToCart; +%newobject ParaMEDMEM::DataArrayDouble::getDifferentValues; +%newobject ParaMEDMEM::DataArrayDouble::findClosestTupleId; +%newobject ParaMEDMEM::DataArrayDouble::computeNbOfInteractionsWith; +%newobject ParaMEDMEM::DataArrayDouble::duplicateEachTupleNTimes; +%newobject ParaMEDMEM::DataArrayDouble::__neg__; +%newobject ParaMEDMEM::DataArrayDouble::__radd__; +%newobject ParaMEDMEM::DataArrayDouble::__rsub__; +%newobject ParaMEDMEM::DataArrayDouble::__rmul__; +%newobject ParaMEDMEM::DataArrayDouble::__rdiv__; +%newobject ParaMEDMEM::DataArrayDouble::__pow__; +%newobject ParaMEDMEM::DataArrayDouble::__rpow__; +%newobject ParaMEDMEM::DataArrayDoubleTuple::buildDADouble; + +%feature("unref") DataArray "$this->decrRef();" +%feature("unref") DataArrayDouble "$this->decrRef();" +%feature("unref") DataArrayInt "$this->decrRef();" +%feature("unref") DataArrayChar "$this->decrRef();" +%feature("unref") DataArrayAsciiChar "$this->decrRef();" +%feature("unref") DataArrayByte "$this->decrRef();" + +namespace ParaMEDMEM +{ + class DataArray : public RefCountObject, public TimeLabel + { + public: + void setName(const std::string& name); + void copyStringInfoFrom(const DataArray& other) throw(INTERP_KERNEL::Exception); + void copyPartOfStringInfoFrom(const DataArray& other, const std::vector<int>& compoIds) throw(INTERP_KERNEL::Exception); + void copyPartOfStringInfoFrom2(const std::vector<int>& compoIds, const DataArray& other) throw(INTERP_KERNEL::Exception); + bool areInfoEqualsIfNotWhy(const DataArray& other, std::string& reason) const throw(INTERP_KERNEL::Exception); + bool areInfoEquals(const DataArray& other) const throw(INTERP_KERNEL::Exception); + std::string cppRepr(const std::string& varName) const throw(INTERP_KERNEL::Exception); + std::string getName() const; + void setInfoOnComponents(const std::vector<std::string>& info) throw(INTERP_KERNEL::Exception); + void setInfoAndChangeNbOfCompo(const std::vector<std::string>& info) throw(INTERP_KERNEL::Exception); + std::vector<std::string> getVarsOnComponent() const throw(INTERP_KERNEL::Exception); + std::vector<std::string> getUnitsOnComponent() const throw(INTERP_KERNEL::Exception); + std::string getInfoOnComponent(int i) const throw(INTERP_KERNEL::Exception); + std::string getVarOnComponent(int i) const throw(INTERP_KERNEL::Exception); + std::string getUnitOnComponent(int i) const throw(INTERP_KERNEL::Exception); + void setInfoOnComponent(int i, const std::string& info) throw(INTERP_KERNEL::Exception); + int getNumberOfComponents() const; + virtual void alloc(int nbOfTuple, int nbOfCompo=1) throw(INTERP_KERNEL::Exception); + virtual void reAlloc(int nbOfTuples) throw(INTERP_KERNEL::Exception); + virtual bool isAllocated() const throw(INTERP_KERNEL::Exception); + virtual void checkAllocated() const throw(INTERP_KERNEL::Exception); + virtual void desallocate() throw(INTERP_KERNEL::Exception); + virtual int getNumberOfTuples() const throw(INTERP_KERNEL::Exception); + virtual std::size_t getNbOfElems() const throw(INTERP_KERNEL::Exception); + virtual std::size_t getNbOfElemAllocated() const throw(INTERP_KERNEL::Exception); + virtual DataArray *deepCpy() const throw(INTERP_KERNEL::Exception); + virtual DataArray *selectByTupleId2(int bg, int end2, int step) const throw(INTERP_KERNEL::Exception); + virtual void rearrange(int newNbOfCompo) throw(INTERP_KERNEL::Exception); + void checkNbOfTuples(int nbOfTuples, const std::string& msg) const throw(INTERP_KERNEL::Exception); + void checkNbOfComps(int nbOfCompo, const std::string& msg) const throw(INTERP_KERNEL::Exception); + void checkNbOfTuplesAndComp(const DataArray& other, const std::string& msg) const throw(INTERP_KERNEL::Exception); + void checkNbOfTuplesAndComp(int nbOfTuples, int nbOfCompo, const std::string& msg) const throw(INTERP_KERNEL::Exception); + void checkNbOfElems(std::size_t nbOfElems, const std::string& msg) const throw(INTERP_KERNEL::Exception); + static int GetNumberOfItemGivenBES(int begin, int end, int step, const std::string& msg) throw(INTERP_KERNEL::Exception); + static int GetNumberOfItemGivenBESRelative(int begin, int end, int step, const std::string& msg) throw(INTERP_KERNEL::Exception); + static int GetPosOfItemGivenBESRelativeNoThrow(int value, int begin, int end, int step) throw(INTERP_KERNEL::Exception); + static std::string GetVarNameFromInfo(const std::string& info) throw(INTERP_KERNEL::Exception); + static std::string GetUnitFromInfo(const std::string& info) throw(INTERP_KERNEL::Exception); + static std::string BuildInfoFromVarAndUnit(const std::string& var, const std::string& unit) throw(INTERP_KERNEL::Exception); + void updateTime() const; + %extend + { + PyObject *getInfoOnComponents() const throw(INTERP_KERNEL::Exception) + { + const std::vector<std::string>& comps=self->getInfoOnComponents(); + PyObject *ret=PyList_New((int)comps.size()); + for(int i=0;i<(int)comps.size();i++) + PyList_SetItem(ret,i,PyString_FromString(comps[i].c_str())); + return ret; + } + + void copyPartOfStringInfoFrom(const DataArray& other, PyObject *li) throw(INTERP_KERNEL::Exception) + { + std::vector<int> tmp; + convertPyToNewIntArr3(li,tmp); + self->copyPartOfStringInfoFrom(other,tmp); + } + + void copyPartOfStringInfoFrom2(PyObject *li, const DataArray& other) throw(INTERP_KERNEL::Exception) + { + std::vector<int> tmp; + convertPyToNewIntArr3(li,tmp); + self->copyPartOfStringInfoFrom2(tmp,other); + } + + virtual void renumberInPlace(PyObject *li) throw(INTERP_KERNEL::Exception) + { + void *da=0; + int res1=SWIG_ConvertPtr(li,&da,SWIGTYPE_p_ParaMEDMEM__DataArrayInt, 0 | 0 ); + if (!SWIG_IsOK(res1)) + { + int size; + INTERP_KERNEL::AutoPtr<int> tmp=convertPyToNewIntArr2(li,&size); + if(size!=self->getNumberOfTuples()) + { + throw INTERP_KERNEL::Exception("Invalid list length ! Must be equal to number of tuples !"); + } + self->renumberInPlace(tmp); + } + else + { + DataArrayInt *da2=reinterpret_cast< DataArrayInt * >(da); + if(!da2) + throw INTERP_KERNEL::Exception("Not null DataArrayInt instance expected !"); + da2->checkAllocated(); + int size=self->getNumberOfTuples(); + if(size!=self->getNumberOfTuples()) + { + throw INTERP_KERNEL::Exception("Invalid list length ! Must be equal to number of tuples !"); + } + self->renumberInPlace(da2->getConstPointer()); + } + } + + virtual void renumberInPlaceR(PyObject *li) throw(INTERP_KERNEL::Exception) + { + void *da=0; + int res1=SWIG_ConvertPtr(li,&da,SWIGTYPE_p_ParaMEDMEM__DataArrayInt, 0 | 0 ); + if (!SWIG_IsOK(res1)) + { + int size; + INTERP_KERNEL::AutoPtr<int> tmp=convertPyToNewIntArr2(li,&size); + if(size!=self->getNumberOfTuples()) + { + throw INTERP_KERNEL::Exception("Invalid list length ! Must be equal to number of tuples !"); + } + self->renumberInPlaceR(tmp); + } + else + { + DataArrayInt *da2=reinterpret_cast< DataArrayInt * >(da); + if(!da2) + throw INTERP_KERNEL::Exception("Not null DataArrayInt instance expected !"); + da2->checkAllocated(); + int size=self->getNumberOfTuples(); + if(size!=self->getNumberOfTuples()) + { + throw INTERP_KERNEL::Exception("Invalid list length ! Must be equal to number of tuples !"); + } + self->renumberInPlaceR(da2->getConstPointer()); + } + } + + //tuplesSelec in PyObject * because DataArrayInt is not already existing ! + virtual void setContigPartOfSelectedValues(int tupleIdStart, PyObject *aBase, PyObject *tuplesSelec) throw(INTERP_KERNEL::Exception) + { + static const char msg[]="DataArray::setContigPartOfSelectedValues2 : 4th parameter \"tuplesSelec\" should be of type DataArrayInt"; + DataArray *a=CheckAndRetrieveDataArrayInstance(aBase,"DataArray::setContigPartOfSelectedValues2 : 3rd parameter \"aBase\" should be of type DataArray"); + DataArray *tuplesSelecPtr=CheckAndRetrieveDataArrayInstance(tuplesSelec,msg); + DataArrayInt *tuplesSelecPtr2=0; + if(tuplesSelecPtr) + { + tuplesSelecPtr2=dynamic_cast<DataArrayInt *>(tuplesSelecPtr); + if(!tuplesSelecPtr2) + throw INTERP_KERNEL::Exception(msg); + } + self->setContigPartOfSelectedValues(tupleIdStart,a,tuplesSelecPtr2); + } + + virtual void setContigPartOfSelectedValues2(int tupleIdStart, PyObject *aBase, int bg, int end2, int step) throw(INTERP_KERNEL::Exception) + { + DataArray *a=CheckAndRetrieveDataArrayInstance(aBase,"DataArray::setContigPartOfSelectedValues2 : 2nd parameter \"aBase\" should be of type DataArray"); + self->setContigPartOfSelectedValues2(tupleIdStart,a,bg,end2,step); + } + + virtual DataArray *selectByTupleRanges(PyObject *li) const throw(INTERP_KERNEL::Exception) + { + std::vector<std::pair<int,int> > ranges; + convertPyToVectorPairInt(li,ranges); + return self->selectByTupleRanges(ranges); + } + + virtual DataArray *selectByTupleId(PyObject *li) const throw(INTERP_KERNEL::Exception) + { + void *da=0; + int res1=SWIG_ConvertPtr(li,&da,SWIGTYPE_p_ParaMEDMEM__DataArrayInt, 0 | 0 ); + if (!SWIG_IsOK(res1)) + { + int size; + INTERP_KERNEL::AutoPtr<int> tmp=convertPyToNewIntArr2(li,&size); + return self->selectByTupleId(tmp,tmp+size); + } + else + { + DataArrayInt *da2=reinterpret_cast< DataArrayInt * >(da); + if(!da2) + throw INTERP_KERNEL::Exception("Not null DataArrayInt instance expected !"); + da2->checkAllocated(); + return self->selectByTupleId(da2->getConstPointer(),da2->getConstPointer()+da2->getNbOfElems()); + } + } + + virtual DataArray *selectByTupleIdSafe(PyObject *li) const throw(INTERP_KERNEL::Exception) + { + void *da=0; + int res1=SWIG_ConvertPtr(li,&da,SWIGTYPE_p_ParaMEDMEM__DataArrayInt, 0 | 0 ); + if (!SWIG_IsOK(res1)) + { + int size; + INTERP_KERNEL::AutoPtr<int> tmp=convertPyToNewIntArr2(li,&size); + return self->selectByTupleIdSafe(tmp,tmp+size); + } + else + { + DataArrayInt *da2=reinterpret_cast< DataArrayInt * >(da); + if(!da2) + throw INTERP_KERNEL::Exception("Not null DataArrayInt instance expected !"); + da2->checkAllocated(); + return self->selectByTupleIdSafe(da2->getConstPointer(),da2->getConstPointer()+da2->getNbOfElems()); + } + } + + virtual PyObject *keepSelectedComponents(PyObject *li) const throw(INTERP_KERNEL::Exception) + { + std::vector<int> tmp; + convertPyToNewIntArr3(li,tmp); + DataArray *ret=self->keepSelectedComponents(tmp); + return convertDataArray(ret,SWIG_POINTER_OWN | 0 ); + } + + static PyObject *GetSlice(PyObject *slic, int sliceId, int nbOfSlices) throw(INTERP_KERNEL::Exception) + { + if(!PySlice_Check(slic)) + throw INTERP_KERNEL::Exception("DataArray::GetSlice (wrap) : expecting a pyslice as second (first) parameter !"); + Py_ssize_t strt=2,stp=2,step=2; + PySliceObject *sly=reinterpret_cast<PySliceObject *>(slic); + GetIndicesOfSliceExplicitely(sly,&strt,&stp,&step,"DataArray::GetSlice (wrap) : the input slice is invalid !"); + int a,b; + DataArray::GetSlice(strt,stp,step,sliceId,nbOfSlices,a,b); + return PySlice_New(PyInt_FromLong(a),PyInt_FromLong(b),PyInt_FromLong(step)); + } + + PyObject *getSlice(PyObject *slic, int sliceId, int nbOfSlices) const throw(INTERP_KERNEL::Exception) + { + if(!PySlice_Check(slic)) + throw INTERP_KERNEL::Exception("DataArray::getSlice (wrap) : expecting a pyslice as second (first) parameter !"); + Py_ssize_t strt=2,stp=2,step=2; + PySliceObject *sly=reinterpret_cast<PySliceObject *>(slic); + GetIndicesOfSlice(sly,self->getNumberOfTuples(),&strt,&stp,&step,"DataArray::getSlice (wrap) : the input slice is invalid !"); + int a,b; + DataArray::GetSlice(strt,stp,step,sliceId,nbOfSlices,a,b); + return PySlice_New(PyInt_FromLong(a),PyInt_FromLong(b),PyInt_FromLong(step)); + } + + static int GetNumberOfItemGivenBES(PyObject *slic) throw(INTERP_KERNEL::Exception) + { + if(!PySlice_Check(slic)) + throw INTERP_KERNEL::Exception("DataArray::GetNumberOfItemGivenBES (wrap) : expecting a pyslice as second (first) parameter !"); + Py_ssize_t strt=2,stp=2,step=2; + PySliceObject *sly=reinterpret_cast<PySliceObject *>(slic); + GetIndicesOfSliceExplicitely(sly,&strt,&stp,&step,"DataArray::GetNumberOfItemGivenBES (wrap) : the input slice is invalid !"); + return DataArray::GetNumberOfItemGivenBES(strt,stp,step,""); + } + + static int GetNumberOfItemGivenBESRelative(PyObject *slic) throw(INTERP_KERNEL::Exception) + { + if(!PySlice_Check(slic)) + throw INTERP_KERNEL::Exception("DataArray::GetNumberOfItemGivenBESRelative (wrap) : expecting a pyslice as second (first) parameter !"); + Py_ssize_t strt=2,stp=2,step=2; + PySliceObject *sly=reinterpret_cast<PySliceObject *>(slic); + GetIndicesOfSliceExplicitely(sly,&strt,&stp,&step,"DataArray::GetNumberOfItemGivenBESRelative (wrap) : the input slice is invalid !"); + return DataArray::GetNumberOfItemGivenBESRelative(strt,stp,step,""); + } + + static DataArray *Aggregate(PyObject *arrs) throw(INTERP_KERNEL::Exception) + { + std::vector<const DataArray *> tmp; + convertFromPyObjVectorOfObj<const ParaMEDMEM::DataArray *>(arrs,SWIGTYPE_p_ParaMEDMEM__DataArray,"DataArray",tmp); + return DataArray::Aggregate(tmp); + } + + int getNumberOfItemGivenBES(PyObject *slic) const throw(INTERP_KERNEL::Exception) + { + if(!PySlice_Check(slic)) + throw INTERP_KERNEL::Exception("DataArray::getNumberOfItemGivenBES (wrap) : expecting a pyslice as second (first) parameter !"); + Py_ssize_t strt=2,stp=2,step=2; + PySliceObject *sly=reinterpret_cast<PySliceObject *>(slic); + GetIndicesOfSlice(sly,self->getNumberOfTuples(),&strt,&stp,&step,"DataArray::getNumberOfItemGivenBES (wrap) : the input slice is invalid !"); + return DataArray::GetNumberOfItemGivenBES(strt,stp,step,""); + } + + int getNumberOfItemGivenBESRelative(PyObject *slic) throw(INTERP_KERNEL::Exception) + { + if(!PySlice_Check(slic)) + throw INTERP_KERNEL::Exception("DataArray::getNumberOfItemGivenBESRelative (wrap) : expecting a pyslice as second (first) parameter !"); + Py_ssize_t strt=2,stp=2,step=2; + PySliceObject *sly=reinterpret_cast<PySliceObject *>(slic); + GetIndicesOfSlice(sly,self->getNumberOfTuples(),&strt,&stp,&step,"DataArray::getNumberOfItemGivenBESRelative (wrap) : the input slice is invalid !"); + return DataArray::GetNumberOfItemGivenBESRelative(strt,stp,step,""); + } + + PyObject *__getstate__() const throw(INTERP_KERNEL::Exception) + { + PyObject *ret(PyTuple_New(2)); + std::string a0(self->getName()); + const std::vector<std::string> &a1(self->getInfoOnComponents()); + PyTuple_SetItem(ret,0,PyString_FromString(a0.c_str())); + // + int sz(a1.size()); + PyObject *ret1(PyList_New(sz)); + for(int i=0;i<sz;i++) + PyList_SetItem(ret1,i,PyString_FromString(a1[i].c_str())); + PyTuple_SetItem(ret,1,ret1); + // + return ret; + } + + void __setstate__(PyObject *inp) throw(INTERP_KERNEL::Exception) + { + static const char MSG[]="DataArrayDouble.__setstate__ : expected input is a tuple of size 2 with string as 1st arg and list of string as 2nd arg !"; + if(!PyTuple_Check(inp)) + throw INTERP_KERNEL::Exception("DataArrayDouble.__setstate__ : invalid input ! Invalid overwrite of __getstate__ ?"); + int sz(PyTuple_Size(inp)); + if(sz!=2) + throw INTERP_KERNEL::Exception("DataArrayDouble.__setstate__ : invalid tuple in input ! Should be of size 2 ! Invalid overwrite of __getstate__ ?"); + PyObject *a0(PyTuple_GetItem(inp,0)); + if(!PyString_Check(a0)) + throw INTERP_KERNEL::Exception(MSG); + PyObject *a1(PyTuple_GetItem(inp,1)); + std::vector<std::string> a1cpp; + if(!fillStringVector(a1,a1cpp)) + throw INTERP_KERNEL::Exception(MSG); + self->setName(PyString_AsString(a0)); + self->setInfoOnComponents(a1cpp); + } + } + }; + + class DataArrayInt; + class DataArrayDoubleIterator; + + class DataArrayDouble : public DataArray + { + public: + static DataArrayDouble *New(); + double doubleValue() const throw(INTERP_KERNEL::Exception); + bool empty() const throw(INTERP_KERNEL::Exception); + DataArrayDouble *performCpy(bool deepCpy) const throw(INTERP_KERNEL::Exception); + void cpyFrom(const DataArrayDouble& other) throw(INTERP_KERNEL::Exception); + void reserve(std::size_t nbOfElems) throw(INTERP_KERNEL::Exception); + void pushBackSilent(double val) throw(INTERP_KERNEL::Exception); + double popBackSilent() throw(INTERP_KERNEL::Exception); + void pack() const throw(INTERP_KERNEL::Exception); + void allocIfNecessary(int nbOfTuple, int nbOfCompo) throw(INTERP_KERNEL::Exception); + void fillWithZero() throw(INTERP_KERNEL::Exception); + void fillWithValue(double val) throw(INTERP_KERNEL::Exception); + void iota(double init=0.) throw(INTERP_KERNEL::Exception); + bool isUniform(double val, double eps) const throw(INTERP_KERNEL::Exception); + void sort(bool asc=true) throw(INTERP_KERNEL::Exception); + void reverse() throw(INTERP_KERNEL::Exception); + void checkMonotonic(bool increasing, double eps) const throw(INTERP_KERNEL::Exception); + bool isMonotonic(bool increasing, double eps) const throw(INTERP_KERNEL::Exception); + std::string repr() const throw(INTERP_KERNEL::Exception); + std::string reprZip() const throw(INTERP_KERNEL::Exception); + std::string reprNotTooLong() const throw(INTERP_KERNEL::Exception); + bool isEqual(const DataArrayDouble& other, double prec) const throw(INTERP_KERNEL::Exception); + bool isEqualWithoutConsideringStr(const DataArrayDouble& other, double prec) const throw(INTERP_KERNEL::Exception); + DataArrayInt *convertToIntArr() const throw(INTERP_KERNEL::Exception); + DataArrayDouble *fromNoInterlace() const throw(INTERP_KERNEL::Exception); + DataArrayDouble *toNoInterlace() const throw(INTERP_KERNEL::Exception); + DataArrayDouble *substr(int tupleIdBg, int tupleIdEnd=-1) const throw(INTERP_KERNEL::Exception); + void transpose() throw(INTERP_KERNEL::Exception); + DataArrayDouble *changeNbOfComponents(int newNbOfComp, double dftValue) const throw(INTERP_KERNEL::Exception); + void meldWith(const DataArrayDouble *other) throw(INTERP_KERNEL::Exception); + DataArrayDouble *duplicateEachTupleNTimes(int nbTimes) const throw(INTERP_KERNEL::Exception); + DataArrayDouble *getDifferentValues(double prec, int limitTupleId=-1) const throw(INTERP_KERNEL::Exception); + DataArrayInt *findClosestTupleId(const DataArrayDouble *other) const throw(INTERP_KERNEL::Exception); + DataArrayInt *computeNbOfInteractionsWith(const DataArrayDouble *otherBBoxFrmt, double eps) const throw(INTERP_KERNEL::Exception); + void setPartOfValues1(const DataArrayDouble *a, int bgTuples, int endTuples, int stepTuples, int bgComp, int endComp, int stepComp, bool strictCompoCompare=true) throw(INTERP_KERNEL::Exception); + void setPartOfValuesSimple1(double a, int bgTuples, int endTuples, int stepTuples, int bgComp, int endComp, int stepComp) throw(INTERP_KERNEL::Exception); + void setPartOfValuesAdv(const DataArrayDouble *a, const DataArrayInt *tuplesSelec) throw(INTERP_KERNEL::Exception); + double getIJ(int tupleId, int compoId) const throw(INTERP_KERNEL::Exception); + double front() const throw(INTERP_KERNEL::Exception); + double back() const throw(INTERP_KERNEL::Exception); + double getIJSafe(int tupleId, int compoId) const throw(INTERP_KERNEL::Exception); + void setIJ(int tupleId, int compoId, double newVal) throw(INTERP_KERNEL::Exception); + void setIJSilent(int tupleId, int compoId, double newVal) throw(INTERP_KERNEL::Exception); + double *getPointer() throw(INTERP_KERNEL::Exception); + void checkNoNullValues() const throw(INTERP_KERNEL::Exception); + DataArrayDouble *computeBBoxPerTuple(double epsilon=0.0) const throw(INTERP_KERNEL::Exception); + void recenterForMaxPrecision(double eps) throw(INTERP_KERNEL::Exception); + double getMaxValue(int& tupleId) const throw(INTERP_KERNEL::Exception); + double getMaxValueInArray() const throw(INTERP_KERNEL::Exception); + double getMinValue(int& tupleId) const throw(INTERP_KERNEL::Exception); + double getMinValueInArray() const throw(INTERP_KERNEL::Exception); + int count(double value, double eps) const throw(INTERP_KERNEL::Exception); + double getAverageValue() const throw(INTERP_KERNEL::Exception); + double norm2() const throw(INTERP_KERNEL::Exception); + double normMax() const throw(INTERP_KERNEL::Exception); + double normMin() const throw(INTERP_KERNEL::Exception); + double accumulate(int compId) const throw(INTERP_KERNEL::Exception); + DataArrayDouble *fromPolarToCart() const throw(INTERP_KERNEL::Exception); + DataArrayDouble *fromCylToCart() const throw(INTERP_KERNEL::Exception); + DataArrayDouble *fromSpherToCart() const throw(INTERP_KERNEL::Exception); + DataArrayDouble *doublyContractedProduct() const throw(INTERP_KERNEL::Exception); + DataArrayDouble *determinant() const throw(INTERP_KERNEL::Exception); + DataArrayDouble *eigenValues() const throw(INTERP_KERNEL::Exception); + DataArrayDouble *eigenVectors() const throw(INTERP_KERNEL::Exception); + DataArrayDouble *inverse() const throw(INTERP_KERNEL::Exception); + DataArrayDouble *trace() const throw(INTERP_KERNEL::Exception); + DataArrayDouble *deviator() const throw(INTERP_KERNEL::Exception); + DataArrayDouble *magnitude() const throw(INTERP_KERNEL::Exception); + DataArrayDouble *maxPerTuple() const throw(INTERP_KERNEL::Exception); + DataArrayDouble *sumPerTuple() const throw(INTERP_KERNEL::Exception); + DataArrayDouble *buildEuclidianDistanceDenseMatrix() const throw(INTERP_KERNEL::Exception); + DataArrayDouble *buildEuclidianDistanceDenseMatrixWith(const DataArrayDouble *other) const throw(INTERP_KERNEL::Exception); + void sortPerTuple(bool asc) throw(INTERP_KERNEL::Exception); + void abs() throw(INTERP_KERNEL::Exception); + DataArrayDouble *computeAbs() const throw(INTERP_KERNEL::Exception); + void applyLin(double a, double b, int compoId) throw(INTERP_KERNEL::Exception); + void applyLin(double a, double b) throw(INTERP_KERNEL::Exception); + void applyInv(double numerator) throw(INTERP_KERNEL::Exception); + void applyPow(double val) throw(INTERP_KERNEL::Exception); + void applyRPow(double val) throw(INTERP_KERNEL::Exception); + DataArrayDouble *negate() const throw(INTERP_KERNEL::Exception); + DataArrayDouble *applyFunc(int nbOfComp, FunctionToEvaluate func) const throw(INTERP_KERNEL::Exception); + DataArrayDouble *applyFunc(int nbOfComp, const std::string& func, bool isSafe=true) const throw(INTERP_KERNEL::Exception); + DataArrayDouble *applyFunc(const std::string& func, bool isSafe=true) const throw(INTERP_KERNEL::Exception); + void applyFuncOnThis(const std::string& func, bool isSafe=true) throw(INTERP_KERNEL::Exception); + DataArrayDouble *applyFunc2(int nbOfComp, const std::string& func, bool isSafe=true) const throw(INTERP_KERNEL::Exception); + DataArrayDouble *applyFunc3(int nbOfComp, const std::vector<std::string>& varsOrder, const std::string& func, bool isSafe=true) const throw(INTERP_KERNEL::Exception); + void applyFuncFast32(const std::string& func) throw(INTERP_KERNEL::Exception); + void applyFuncFast64(const std::string& func) throw(INTERP_KERNEL::Exception); + DataArrayInt *getIdsInRange(double vmin, double vmax) const throw(INTERP_KERNEL::Exception); + DataArrayInt *getIdsNotInRange(double vmin, double vmax) const throw(INTERP_KERNEL::Exception); + static DataArrayDouble *Aggregate(const DataArrayDouble *a1, const DataArrayDouble *a2) throw(INTERP_KERNEL::Exception); + static DataArrayDouble *Meld(const DataArrayDouble *a1, const DataArrayDouble *a2) throw(INTERP_KERNEL::Exception); + static DataArrayDouble *Dot(const DataArrayDouble *a1, const DataArrayDouble *a2) throw(INTERP_KERNEL::Exception); + static DataArrayDouble *CrossProduct(const DataArrayDouble *a1, const DataArrayDouble *a2) throw(INTERP_KERNEL::Exception); + static DataArrayDouble *Max(const DataArrayDouble *a1, const DataArrayDouble *a2) throw(INTERP_KERNEL::Exception); + static DataArrayDouble *Min(const DataArrayDouble *a1, const DataArrayDouble *a2) throw(INTERP_KERNEL::Exception); + static DataArrayDouble *Add(const DataArrayDouble *a1, const DataArrayDouble *a2) throw(INTERP_KERNEL::Exception); + void addEqual(const DataArrayDouble *other) throw(INTERP_KERNEL::Exception); + static DataArrayDouble *Substract(const DataArrayDouble *a1, const DataArrayDouble *a2) throw(INTERP_KERNEL::Exception); + void substractEqual(const DataArrayDouble *other) throw(INTERP_KERNEL::Exception); + static DataArrayDouble *Multiply(const DataArrayDouble *a1, const DataArrayDouble *a2) throw(INTERP_KERNEL::Exception); + void multiplyEqual(const DataArrayDouble *other) throw(INTERP_KERNEL::Exception); + static DataArrayDouble *Divide(const DataArrayDouble *a1, const DataArrayDouble *a2) throw(INTERP_KERNEL::Exception); + void divideEqual(const DataArrayDouble *other) throw(INTERP_KERNEL::Exception); + static DataArrayDouble *Pow(const DataArrayDouble *a1, const DataArrayDouble *a2) throw(INTERP_KERNEL::Exception); + void powEqual(const DataArrayDouble *other) throw(INTERP_KERNEL::Exception); + %extend + { + DataArrayDouble() throw(INTERP_KERNEL::Exception) + { + return DataArrayDouble::New(); + } + + static DataArrayDouble *New(PyObject *elt0, PyObject *nbOfTuples=0, PyObject *elt2=0) throw(INTERP_KERNEL::Exception) + { + const char *msgBase="ParaMEDMEM::DataArrayDouble::New : Available API are : \n-DataArrayDouble.New()\n-DataArrayDouble.New([1.,3.,4.])\n-DataArrayDouble.New([1.,3.,4.],3)\n-DataArrayDouble.New([1.,3.,4.,5.],2,2)\n-DataArrayDouble.New([1.,3.,4.,5.,7,8.],3,2)\n-DataArrayDouble.New([(1.,3.),(4.,5.),(7,8.)])\n-DataArrayDouble.New(5)\n-DataArrayDouble.New(5,2)"; + std::string msg(msgBase); +#ifdef WITH_NUMPY + msg+="\n-DataArrayDouble.New(numpy array with dtype=float64)"; +#endif + msg+=" !"; + if(PyList_Check(elt0) || PyTuple_Check(elt0)) + { + if(nbOfTuples) + { + if(PyInt_Check(nbOfTuples)) + { + int nbOfTuples1=PyInt_AS_LONG(nbOfTuples); + if(nbOfTuples1<0) + throw INTERP_KERNEL::Exception("DataArrayDouble::New : should be a positive set of allocated memory !"); + if(elt2) + { + if(PyInt_Check(elt2)) + {//DataArrayDouble.New([1.,3.,4.,5.],2,2) + int nbOfCompo=PyInt_AS_LONG(elt2); + if(nbOfCompo<0) + throw INTERP_KERNEL::Exception("DataArrayDouble::New : should be a positive number of components !"); + MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New(); + std::vector<double> tmp=fillArrayWithPyListDbl2(elt0,nbOfTuples1,nbOfCompo); + ret->alloc(nbOfTuples1,nbOfCompo); std::copy(tmp.begin(),tmp.end(),ret->getPointer()); + return ret.retn(); + } + else + throw INTERP_KERNEL::Exception(msg.c_str()); + } + else + {//DataArrayDouble.New([1.,3.,4.],3) + MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New(); + int tmpp1=-1; + std::vector<double> tmp=fillArrayWithPyListDbl2(elt0,nbOfTuples1,tmpp1); + ret->alloc(nbOfTuples1,tmpp1); std::copy(tmp.begin(),tmp.end(),ret->getPointer()); + return ret.retn(); + } + } + else + throw INTERP_KERNEL::Exception(msg.c_str()); + } + else + {// DataArrayDouble.New([1.,3.,4.]) + MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New(); + int tmpp1=-1,tmpp2=-1; + std::vector<double> tmp=fillArrayWithPyListDbl2(elt0,tmpp1,tmpp2); + ret->alloc(tmpp1,tmpp2); std::copy(tmp.begin(),tmp.end(),ret->getPointer()); + return ret.retn(); + } + } + else if(PyInt_Check(elt0)) + { + int nbOfTuples1=PyInt_AS_LONG(elt0); + if(nbOfTuples1<0) + throw INTERP_KERNEL::Exception("DataArrayDouble::New : should be a positive set of allocated memory !"); + if(nbOfTuples) + { + if(!elt2) + { + if(PyInt_Check(nbOfTuples)) + {//DataArrayDouble.New(5,2) + int nbOfCompo=PyInt_AS_LONG(nbOfTuples); + if(nbOfCompo<0) + throw INTERP_KERNEL::Exception("DataArrayDouble::New : should be a positive number of components !"); + MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New(); + ret->alloc(nbOfTuples1,nbOfCompo); + return ret.retn(); + } + else + throw INTERP_KERNEL::Exception(msg.c_str()); + } + else + throw INTERP_KERNEL::Exception(msg.c_str()); + } + else + {//DataArrayDouble.New(5) + MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=DataArrayDouble::New(); + ret->alloc(nbOfTuples1,1); + return ret.retn(); + } + } +#ifdef WITH_NUMPY + else if(PyArray_Check(elt0) && nbOfTuples==NULL && elt2==NULL) + {//DataArrayDouble.New(numpyArray) + return BuildNewInstance<DataArrayDouble,double>(elt0,NPY_DOUBLE,&PyCallBackDataArrayDouble_RefType,"FLOAT64"); + } +#endif + else + throw INTERP_KERNEL::Exception(msg.c_str()); + throw INTERP_KERNEL::Exception(msg.c_str());//to make g++ happy + } + + DataArrayDouble(PyObject *elt0, PyObject *nbOfTuples=0, PyObject *elt2=0) throw(INTERP_KERNEL::Exception) + { + return ParaMEDMEM_DataArrayDouble_New__SWIG_1(elt0,nbOfTuples,elt2); + } + + void pushBackValsSilent(PyObject *li) throw(INTERP_KERNEL::Exception) + { + double val; + std::vector<double> bb; + int sw,nbTuples=-1; + const char msg[]="Python wrap of DataArrayDouble::pushBackValsSilent : "; + const double *tmp=convertObjToPossibleCpp5_SingleCompo(li,sw,val,bb,msg,true,nbTuples); + self->pushBackValsSilent(tmp,tmp+nbTuples); + } + + std::string __repr__() const throw(INTERP_KERNEL::Exception) + { + std::ostringstream oss; + self->reprQuickOverview(oss); + return oss.str(); + } + + std::string __str__() const throw(INTERP_KERNEL::Exception) + { + return self->reprNotTooLong(); + } + + double __float__() const throw(INTERP_KERNEL::Exception) + { + return self->doubleValue(); + } + + int __len__() const throw(INTERP_KERNEL::Exception) + { + if(self->isAllocated()) + { + return self->getNumberOfTuples(); + } + else + { + throw INTERP_KERNEL::Exception("DataArrayDouble::__len__ : Instance is NOT allocated !"); + } + } + + DataArrayDoubleIterator *__iter__() throw(INTERP_KERNEL::Exception) + { + return self->iterator(); + } + + void setValues(PyObject *li, PyObject *nbOfTuples=0, PyObject *nbOfComp=0) throw(INTERP_KERNEL::Exception) + { + const char *msg="ParaMEDMEM::DataArrayDouble::setValues : Available API are : \n-DataArrayDouble.setValues([1.,3.,4.])\n-DataArrayDouble.setValues([1.,3.,4.],3)\n-DataArrayDouble.setValues([1.,3.,4.,5.],2,2)\n-DataArrayDouble.setValues([(1.,1.7),(3.,3.7),(4.,4.7)])\n !"; + if(PyList_Check(li) || PyTuple_Check(li)) + { + if(nbOfTuples) + { + if(PyInt_Check(nbOfTuples)) + { + int nbOfTuples1=PyInt_AS_LONG(nbOfTuples); + if(nbOfTuples1<0) + throw INTERP_KERNEL::Exception("DataArrayDouble::setValues : should be a positive set of allocated memory !"); + if(nbOfComp) + { + if(PyInt_Check(nbOfComp)) + {//DataArrayDouble.setValues([1.,3.,4.,5.],2,2) + int nbOfCompo=PyInt_AS_LONG(nbOfComp); + if(nbOfCompo<0) + throw INTERP_KERNEL::Exception("DataArrayDouble::setValues : should be a positive number of components !"); + std::vector<double> tmp=fillArrayWithPyListDbl2(li,nbOfTuples1,nbOfCompo); + self->alloc(nbOfTuples1,nbOfCompo); std::copy(tmp.begin(),tmp.end(),self->getPointer()); + } + else + throw INTERP_KERNEL::Exception(msg); + } + else + {//DataArrayDouble.setValues([1.,3.,4.],3) + int tmpp1=-1; + std::vector<double> tmp=fillArrayWithPyListDbl2(li,nbOfTuples1,tmpp1); + self->alloc(nbOfTuples1,tmpp1); std::copy(tmp.begin(),tmp.end(),self->getPointer()); + } + } + else + throw INTERP_KERNEL::Exception(msg); + } + else + {// DataArrayDouble.setValues([1.,3.,4.]) + int tmpp1=-1,tmpp2=-1; + std::vector<double> tmp=fillArrayWithPyListDbl2(li,tmpp1,tmpp2); + self->alloc(tmpp1,tmpp2); std::copy(tmp.begin(),tmp.end(),self->getPointer()); + } + } + else + throw INTERP_KERNEL::Exception(msg); + } + + PyObject *getValues() const throw(INTERP_KERNEL::Exception) + { + const double *vals=self->getConstPointer(); + return convertDblArrToPyList(vals,self->getNbOfElems()); + } + +#ifdef WITH_NUMPY + PyObject *toNumPyArray() throw(INTERP_KERNEL::Exception) // not const. It is not a bug ! + { + return ToNumPyArray<DataArrayDouble,double>(self,NPY_DOUBLE,"DataArrayDouble"); + } +#endif + + PyObject *isEqualIfNotWhy(const DataArrayDouble& other, double prec) const throw(INTERP_KERNEL::Exception) + { + std::string ret1; + bool ret0=self->isEqualIfNotWhy(other,prec,ret1); + PyObject *ret=PyTuple_New(2); + PyObject *ret0Py=ret0?Py_True:Py_False; + Py_XINCREF(ret0Py); + PyTuple_SetItem(ret,0,ret0Py); + PyTuple_SetItem(ret,1,PyString_FromString(ret1.c_str())); + return ret; + } + + PyObject *getValuesAsTuple() const throw(INTERP_KERNEL::Exception) + { + const double *vals=self->getConstPointer(); + int nbOfComp=self->getNumberOfComponents(); + int nbOfTuples=self->getNumberOfTuples(); + return convertDblArrToPyListOfTuple(vals,nbOfComp,nbOfTuples); + } + + DataArrayDouble *renumber(PyObject *li) throw(INTERP_KERNEL::Exception) + { + void *da=0; + int res1=SWIG_ConvertPtr(li,&da,SWIGTYPE_p_ParaMEDMEM__DataArrayInt, 0 | 0 ); + if (!SWIG_IsOK(res1)) + { + int size; + INTERP_KERNEL::AutoPtr<int> tmp=convertPyToNewIntArr2(li,&size); + if(size!=self->getNumberOfTuples()) + { + throw INTERP_KERNEL::Exception("Invalid list length ! Must be equal to number of tuples !"); + } + return self->renumber(tmp); + } + else + { + DataArrayInt *da2=reinterpret_cast< DataArrayInt * >(da); + if(!da2) + throw INTERP_KERNEL::Exception("Not null DataArrayInt instance expected !"); + da2->checkAllocated(); + int size=self->getNumberOfTuples(); + if(size!=self->getNumberOfTuples()) + { + throw INTERP_KERNEL::Exception("Invalid list length ! Must be equal to number of tuples !"); + } + return self->renumber(da2->getConstPointer()); + } + } + + DataArrayDouble *renumberR(PyObject *li) throw(INTERP_KERNEL::Exception) + { + void *da=0; + int res1=SWIG_ConvertPtr(li,&da,SWIGTYPE_p_ParaMEDMEM__DataArrayInt, 0 | 0 ); + if (!SWIG_IsOK(res1)) + { + int size; + INTERP_KERNEL::AutoPtr<int> tmp=convertPyToNewIntArr2(li,&size); + if(size!=self->getNumberOfTuples()) + { + throw INTERP_KERNEL::Exception("Invalid list length ! Must be equal to number of tuples !"); + } + return self->renumberR(tmp); + } + else + { + DataArrayInt *da2=reinterpret_cast< DataArrayInt * >(da); + if(!da2) + throw INTERP_KERNEL::Exception("Not null DataArrayInt instance expected !"); + da2->checkAllocated(); + int size=self->getNumberOfTuples(); + if(size!=self->getNumberOfTuples()) + { + throw INTERP_KERNEL::Exception("Invalid list length ! Must be equal to number of tuples !"); + } + return self->renumberR(da2->getConstPointer()); + } + } + + DataArrayDouble *renumberAndReduce(PyObject *li, int newNbOfTuple) throw(INTERP_KERNEL::Exception) + { + void *da=0; + int res1=SWIG_ConvertPtr(li,&da,SWIGTYPE_p_ParaMEDMEM__DataArrayInt, 0 | 0 ); + if (!SWIG_IsOK(res1)) + { + int size; + INTERP_KERNEL::AutoPtr<int> tmp=convertPyToNewIntArr2(li,&size); + if(size!=self->getNumberOfTuples()) + { + throw INTERP_KERNEL::Exception("Invalid list length ! Must be equal to number of tuples !"); + } + return self->renumberAndReduce(tmp,newNbOfTuple); + } + else + { + DataArrayInt *da2=reinterpret_cast< DataArrayInt * >(da); + if(!da2) + throw INTERP_KERNEL::Exception("Not null DataArrayInt instance expected !"); + da2->checkAllocated(); + int size=self->getNumberOfTuples(); + if(size!=self->getNumberOfTuples()) + { + throw INTERP_KERNEL::Exception("Invalid list length ! Must be equal to number of tuples !"); + } + return self->renumberAndReduce(da2->getConstPointer(),newNbOfTuple); + } + } + + PyObject *minimalDistanceTo(const DataArrayDouble *other) const throw(INTERP_KERNEL::Exception) + { + int thisTupleId,otherTupleId; + double r0=self->minimalDistanceTo(other,thisTupleId,otherTupleId); + PyObject *ret=PyTuple_New(3); + PyTuple_SetItem(ret,0,PyFloat_FromDouble(r0)); + PyTuple_SetItem(ret,1,PyInt_FromLong(thisTupleId)); + PyTuple_SetItem(ret,2,PyInt_FromLong(otherTupleId)); + return ret; + } + + PyObject *getMaxValue() const throw(INTERP_KERNEL::Exception) + { + int tmp; + double r1=self->getMaxValue(tmp); + PyObject *ret=PyTuple_New(2); + PyTuple_SetItem(ret,0,PyFloat_FromDouble(r1)); + PyTuple_SetItem(ret,1,PyInt_FromLong(tmp)); + return ret; + } + + PyObject *getMaxValue2() const throw(INTERP_KERNEL::Exception) + { + DataArrayInt *tmp; + double r1=self->getMaxValue2(tmp); + PyObject *ret=PyTuple_New(2); + PyTuple_SetItem(ret,0,PyFloat_FromDouble(r1)); + PyTuple_SetItem(ret,1,SWIG_NewPointerObj(SWIG_as_voidptr(tmp),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 )); + return ret; + } + + PyObject *getMinValue() const throw(INTERP_KERNEL::Exception) + { + int tmp; + double r1=self->getMinValue(tmp); + PyObject *ret=PyTuple_New(2); + PyTuple_SetItem(ret,0,PyFloat_FromDouble(r1)); + PyTuple_SetItem(ret,1,PyInt_FromLong(tmp)); + return ret; + } + + PyObject *getMinValue2() const throw(INTERP_KERNEL::Exception) + { + DataArrayInt *tmp; + double r1=self->getMinValue2(tmp); + PyObject *ret=PyTuple_New(2); + PyTuple_SetItem(ret,0,PyFloat_FromDouble(r1)); + PyTuple_SetItem(ret,1,SWIG_NewPointerObj(SWIG_as_voidptr(tmp),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 )); + return ret; + } + + PyObject *getMinMaxPerComponent() const throw(INTERP_KERNEL::Exception) + { + int nbOfCompo=self->getNumberOfComponents(); + INTERP_KERNEL::AutoPtr<double> tmp=new double[2*nbOfCompo]; + self->getMinMaxPerComponent(tmp); + PyObject *ret=convertDblArrToPyListOfTuple(tmp,2,nbOfCompo); + return ret; + } + + PyObject *accumulate() const throw(INTERP_KERNEL::Exception) + { + int sz=self->getNumberOfComponents(); + INTERP_KERNEL::AutoPtr<double> tmp=new double[sz]; + self->accumulate(tmp); + return convertDblArrToPyList(tmp,sz); + } + + DataArrayDouble *accumulatePerChunck(PyObject *indexArr) const throw(INTERP_KERNEL::Exception) + { + int sw,sz,val; + std::vector<int> val2; + const int *bg=convertObjToPossibleCpp1_Safe(indexArr,sw,sz,val,val2); + return self->accumulatePerChunck(bg,bg+sz); + } + + PyObject *findCommonTuples(double prec, int limitNodeId=-1) const throw(INTERP_KERNEL::Exception) + { + DataArrayInt *comm, *commIndex; + self->findCommonTuples(prec,limitNodeId,comm,commIndex); + PyObject *res = PyList_New(2); + PyList_SetItem(res,0,SWIG_NewPointerObj(SWIG_as_voidptr(comm),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 )); + PyList_SetItem(res,1,SWIG_NewPointerObj(SWIG_as_voidptr(commIndex),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 )); + return res; + } + + PyObject *distanceToTuple(PyObject *tuple) const throw(INTERP_KERNEL::Exception) + { + double val; + DataArrayDouble *a; + DataArrayDoubleTuple *aa; + std::vector<double> bb; + int sw; + int tupleId=-1,nbOfCompo=self->getNumberOfComponents(); + const double *pt=convertObjToPossibleCpp5_Safe(tuple,sw,val,a,aa,bb,"Python wrap of DataArrayDouble::distanceToTuple",1,nbOfCompo,true); + // + double ret0=self->distanceToTuple(pt,pt+nbOfCompo,tupleId); + PyObject *ret=PyTuple_New(2); + PyTuple_SetItem(ret,0,PyFloat_FromDouble(ret0)); + PyTuple_SetItem(ret,1,PyInt_FromLong(tupleId)); + return ret; + } + + void setSelectedComponents(const DataArrayDouble *a, PyObject *li) throw(INTERP_KERNEL::Exception) + { + std::vector<int> tmp; + convertPyToNewIntArr3(li,tmp); + self->setSelectedComponents(a,tmp); + } + + PyObject *getTuple(int tupleId) throw(INTERP_KERNEL::Exception) + { + int sz=self->getNumberOfComponents(); + INTERP_KERNEL::AutoPtr<double> tmp=new double[sz]; + self->getTuple(tupleId,tmp); + return convertDblArrToPyList(tmp,sz); + } + + static DataArrayDouble *Aggregate(PyObject *li) throw(INTERP_KERNEL::Exception) + { + std::vector<const DataArrayDouble *> tmp; + convertFromPyObjVectorOfObj<const DataArrayDouble *>(li,SWIGTYPE_p_ParaMEDMEM__DataArrayDouble,"DataArrayDouble",tmp); + return DataArrayDouble::Aggregate(tmp); + } + + static DataArrayDouble *Meld(PyObject *li) throw(INTERP_KERNEL::Exception) + { + std::vector<const DataArrayDouble *> tmp; + convertFromPyObjVectorOfObj<const DataArrayDouble *>(li,SWIGTYPE_p_ParaMEDMEM__DataArrayDouble,"DataArrayDouble",tmp); + return DataArrayDouble::Meld(tmp); + } + + PyObject *computeTupleIdsNearTuples(PyObject *pt, double eps) const throw(INTERP_KERNEL::Exception) + { + double val; + DataArrayDouble *a; + DataArrayDoubleTuple *aa; + std::vector<double> bb; + int sw; + int nbComp=self->getNumberOfComponents(),nbTuples=-1; + const char msg[]="Python wrap of DataArrayDouble::computeTupleIdsNearTuples : "; + const double *pos=convertObjToPossibleCpp5_Safe2(pt,sw,val,a,aa,bb,msg,nbComp,true,nbTuples); + MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> inpu=DataArrayDouble::New(); inpu->useArray(pos,false,CPP_DEALLOC,nbTuples,nbComp); + DataArrayInt *c=0,*cI=0; + self->computeTupleIdsNearTuples(inpu,eps,c,cI); + PyObject *ret=PyTuple_New(2); + PyTuple_SetItem(ret,0,SWIG_NewPointerObj(SWIG_as_voidptr(c),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 )); + PyTuple_SetItem(ret,1,SWIG_NewPointerObj(SWIG_as_voidptr(cI),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 )); + return ret; + } + + PyObject *areIncludedInMe(const DataArrayDouble *other, double prec) const throw(INTERP_KERNEL::Exception) + { + DataArrayInt *ret1=0; + bool ret0=self->areIncludedInMe(other,prec,ret1); + PyObject *ret=PyTuple_New(2); + PyObject *ret0Py=ret0?Py_True:Py_False; + Py_XINCREF(ret0Py); + PyTuple_SetItem(ret,0,ret0Py); + PyTuple_SetItem(ret,1,SWIG_NewPointerObj(SWIG_as_voidptr(ret1),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 )); + return ret; + } + + PyObject *__getitem__(PyObject *obj) throw(INTERP_KERNEL::Exception) + { + const char msg[]="Unexpected situation in DataArrayDouble::__getitem__ !"; + const char msg2[]="DataArrayDouble::__getitem__ : Mismatch of slice values in 2nd parameter (components) !"; + self->checkAllocated(); + int nbOfTuples=self->getNumberOfTuples(); + int nbOfComponents=self->getNumberOfComponents(); + int it1,ic1; + std::vector<int> vt1,vc1; + std::pair<int, std::pair<int,int> > pt1,pc1; + DataArrayInt *dt1=0,*dc1=0; + int sw; + convertObjToPossibleCpp3(obj,nbOfTuples,nbOfComponents,sw,it1,ic1,vt1,vc1,pt1,pc1,dt1,dc1); + MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret; + switch(sw) + { + case 1: + if(nbOfComponents==1) + return PyFloat_FromDouble(self->getIJSafe(it1,0)); + return SWIG_NewPointerObj(SWIG_as_voidptr(self->selectByTupleIdSafe(&it1,&it1+1)),SWIGTYPE_p_ParaMEDMEM__DataArrayDouble, SWIG_POINTER_OWN | 0 ); + case 2: + return SWIG_NewPointerObj(SWIG_as_voidptr(self->selectByTupleIdSafe(&vt1[0],&vt1[0]+vt1.size())),SWIGTYPE_p_ParaMEDMEM__DataArrayDouble, SWIG_POINTER_OWN | 0 ); + case 3: + return SWIG_NewPointerObj(SWIG_as_voidptr(self->selectByTupleId2(pt1.first,pt1.second.first,pt1.second.second)),SWIGTYPE_p_ParaMEDMEM__DataArrayDouble, SWIG_POINTER_OWN | 0 ); + case 4: + return SWIG_NewPointerObj(SWIG_as_voidptr(self->selectByTupleIdSafe(dt1->getConstPointer(),dt1->getConstPointer()+dt1->getNbOfElems())),SWIGTYPE_p_ParaMEDMEM__DataArrayDouble, SWIG_POINTER_OWN | 0 ); + case 5: + return PyFloat_FromDouble(self->getIJSafe(it1,ic1)); + case 6: + { + ret=self->selectByTupleIdSafe(&vt1[0],&vt1[0]+vt1.size()); + std::vector<int> v2(1,ic1); + return SWIG_NewPointerObj(SWIG_as_voidptr(ret->keepSelectedComponents(v2)),SWIGTYPE_p_ParaMEDMEM__DataArrayDouble, SWIG_POINTER_OWN | 0 ); + } + case 7: + { + ret=self->selectByTupleId2(pt1.first,pt1.second.first,pt1.second.second); + std::vector<int> v2(1,ic1); + return SWIG_NewPointerObj(SWIG_as_voidptr(ret->keepSelectedComponents(v2)),SWIGTYPE_p_ParaMEDMEM__DataArrayDouble, SWIG_POINTER_OWN | 0 ); + } + case 8: + { + ret=self->selectByTupleIdSafe(dt1->getConstPointer(),dt1->getConstPointer()+dt1->getNbOfElems()); + std::vector<int> v2(1,ic1); + return SWIG_NewPointerObj(SWIG_as_voidptr(ret->keepSelectedComponents(v2)),SWIGTYPE_p_ParaMEDMEM__DataArrayDouble, SWIG_POINTER_OWN | 0 ); + } + case 9: + { + ret=self->selectByTupleIdSafe(&it1,&it1+1); + return SWIG_NewPointerObj(SWIG_as_voidptr(ret->keepSelectedComponents(vc1)),SWIGTYPE_p_ParaMEDMEM__DataArrayDouble, SWIG_POINTER_OWN | 0 ); + } + case 10: + { + ret=self->selectByTupleIdSafe(&vt1[0],&vt1[0]+vt1.size()); + return SWIG_NewPointerObj(SWIG_as_voidptr(ret->keepSelectedComponents(vc1)),SWIGTYPE_p_ParaMEDMEM__DataArrayDouble, SWIG_POINTER_OWN | 0 ); + } + case 11: + { + ret=self->selectByTupleId2(pt1.first,pt1.second.first,pt1.second.second); + return SWIG_NewPointerObj(SWIG_as_voidptr(ret->keepSelectedComponents(vc1)),SWIGTYPE_p_ParaMEDMEM__DataArrayDouble, SWIG_POINTER_OWN | 0 ); + } + case 12: + { + ret=self->selectByTupleIdSafe(dt1->getConstPointer(),dt1->getConstPointer()+dt1->getNbOfElems()); + return SWIG_NewPointerObj(SWIG_as_voidptr(ret->keepSelectedComponents(vc1)),SWIGTYPE_p_ParaMEDMEM__DataArrayDouble, SWIG_POINTER_OWN | 0 ); + } + case 13: + { + ret=self->selectByTupleIdSafe(&it1,&it1+1); + int nbOfComp=DataArray::GetNumberOfItemGivenBESRelative(pc1.first,pc1.second.first,pc1.second.second,msg2); + std::vector<int> v2(nbOfComp); + for(int i=0;i<nbOfComp;i++) + v2[i]=pc1.first+i*pc1.second.second; + return SWIG_NewPointerObj(SWIG_as_voidptr(ret->keepSelectedComponents(v2)),SWIGTYPE_p_ParaMEDMEM__DataArrayDouble, SWIG_POINTER_OWN | 0 ); + } + case 14: + { + ret=self->selectByTupleIdSafe(&vt1[0],&vt1[0]+vt1.size()); + int nbOfComp=DataArray::GetNumberOfItemGivenBESRelative(pc1.first,pc1.second.first,pc1.second.second,msg2); + std::vector<int> v2(nbOfComp); + for(int i=0;i<nbOfComp;i++) + v2[i]=pc1.first+i*pc1.second.second; + return SWIG_NewPointerObj(SWIG_as_voidptr(ret->keepSelectedComponents(v2)),SWIGTYPE_p_ParaMEDMEM__DataArrayDouble, SWIG_POINTER_OWN | 0 ); + } + case 15: + { + ret=self->selectByTupleId2(pt1.first,pt1.second.first,pt1.second.second); + int nbOfComp=DataArray::GetNumberOfItemGivenBESRelative(pc1.first,pc1.second.first,pc1.second.second,msg2); + std::vector<int> v2(nbOfComp); + for(int i=0;i<nbOfComp;i++) + v2[i]=pc1.first+i*pc1.second.second; + return SWIG_NewPointerObj(SWIG_as_voidptr(ret->keepSelectedComponents(v2)),SWIGTYPE_p_ParaMEDMEM__DataArrayDouble, SWIG_POINTER_OWN | 0 ); + } + case 16: + { + ret=self->selectByTupleIdSafe(dt1->getConstPointer(),dt1->getConstPointer()+dt1->getNbOfElems()); + int nbOfComp=DataArray::GetNumberOfItemGivenBESRelative(pc1.first,pc1.second.first,pc1.second.second,msg2); + std::vector<int> v2(nbOfComp); + for(int i=0;i<nbOfComp;i++) + v2[i]=pc1.first+i*pc1.second.second; + return SWIG_NewPointerObj(SWIG_as_voidptr(ret->keepSelectedComponents(v2)),SWIGTYPE_p_ParaMEDMEM__DataArrayDouble, SWIG_POINTER_OWN | 0 ); + } + default: + throw INTERP_KERNEL::Exception(msg); + } + } + + DataArrayDouble *__setitem__(PyObject *obj, PyObject *value) throw(INTERP_KERNEL::Exception) + { + self->checkAllocated(); + const char msg[]="Unexpected situation in DataArrayDouble::__setitem__ !"; + int nbOfTuples=self->getNumberOfTuples(); + int nbOfComponents=self->getNumberOfComponents(); + int sw1,sw2; + double i1; + std::vector<double> v1; + DataArrayDouble *d1=0; + convertObjToPossibleCpp4(value,sw1,i1,v1,d1); + int it1,ic1; + std::vector<int> vt1,vc1; + std::pair<int, std::pair<int,int> > pt1,pc1; + DataArrayInt *dt1=0,*dc1=0; + convertObjToPossibleCpp3(obj,nbOfTuples,nbOfComponents,sw2,it1,ic1,vt1,vc1,pt1,pc1,dt1,dc1); + MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> tmp; + switch(sw2) + { + case 1: + { + switch(sw1) + { + case 1: + self->setPartOfValuesSimple1(i1,it1,it1+1,1,0,nbOfComponents,1); + return self; + case 2: + tmp=DataArrayDouble::New(); + tmp->useArray(&v1[0],false,CPP_DEALLOC,1,v1.size()); + self->setPartOfValues1(tmp,it1,it1+1,1,0,nbOfComponents,1,false); + return self; + case 3: + self->setPartOfValues1(d1,it1,it1+1,1,0,nbOfComponents,1); + return self; + default: + throw INTERP_KERNEL::Exception(msg); + } + break; + } + case 2: + { + switch(sw1) + { + case 1: + self->setPartOfValuesSimple3(i1,&vt1[0],&vt1[0]+vt1.size(),0,nbOfComponents,1); + return self; + case 2: + tmp=DataArrayDouble::New(); + tmp->useArray(&v1[0],false,CPP_DEALLOC,1,v1.size()); + self->setPartOfValues3(tmp,&vt1[0],&vt1[0]+vt1.size(),0,nbOfComponents,1,false); + return self; + case 3: + self->setPartOfValues3(d1,&vt1[0],&vt1[0]+vt1.size(),0,nbOfComponents,1); + return self; + default: + throw INTERP_KERNEL::Exception(msg); + } + break; + } + case 3: + { + switch(sw1) + { + case 1: + self->setPartOfValuesSimple1(i1,pt1.first,pt1.second.first,pt1.second.second,0,nbOfComponents,1); + return self; + case 2: + tmp=DataArrayDouble::New(); + tmp->useArray(&v1[0],false,CPP_DEALLOC,1,v1.size()); + self->setPartOfValues1(tmp,pt1.first,pt1.second.first,pt1.second.second,0,nbOfComponents,1,false); + return self; + case 3: + self->setPartOfValues1(d1,pt1.first,pt1.second.first,pt1.second.second,0,nbOfComponents,1); + return self; + default: + throw INTERP_KERNEL::Exception(msg); + } + break; + } + case 4: + { + switch(sw1) + { + case 1: + self->setPartOfValuesSimple3(i1,dt1->getConstPointer(),dt1->getConstPointer()+dt1->getNbOfElems(),0,nbOfComponents,1); + return self; + case 2: + tmp=DataArrayDouble::New(); + tmp->useArray(&v1[0],false,CPP_DEALLOC,1,v1.size()); + self->setPartOfValues3(tmp,dt1->getConstPointer(),dt1->getConstPointer()+dt1->getNbOfElems(),0,nbOfComponents,1,false); + return self; + case 3: + self->setPartOfValues3(d1,dt1->getConstPointer(),dt1->getConstPointer()+dt1->getNbOfElems(),0,nbOfComponents,1); + return self; + default: + throw INTERP_KERNEL::Exception(msg); + } + break; + } + case 5: + { + switch(sw1) + { + case 1: + self->setPartOfValuesSimple1(i1,it1,it1+1,1,ic1,ic1+1,1); + return self; + case 2: + tmp=DataArrayDouble::New(); + tmp->useArray(&v1[0],false,CPP_DEALLOC,1,v1.size()); + self->setPartOfValues1(tmp,it1,it1+1,1,ic1,ic1+1,1,false); + return self; + case 3: + self->setPartOfValues1(d1,it1,it1+1,1,ic1,ic1+1,1); + return self; + default: + throw INTERP_KERNEL::Exception(msg); + } + break; + } + case 6: + { + switch(sw1) + { + case 1: + self->setPartOfValuesSimple3(i1,&vt1[0],&vt1[0]+vt1.size(),ic1,ic1+1,1); + return self; + case 2: + tmp=DataArrayDouble::New(); + tmp->useArray(&v1[0],false,CPP_DEALLOC,1,v1.size()); + self->setPartOfValues3(tmp,&vt1[0],&vt1[0]+vt1.size(),ic1,ic1+1,1,false); + return self; + case 3: + self->setPartOfValues3(d1,&vt1[0],&vt1[0]+vt1.size(),ic1,ic1+1,1); + return self; + default: + throw INTERP_KERNEL::Exception(msg); + } + break; + } + case 7: + { + switch(sw1) + { + case 1: + self->setPartOfValuesSimple1(i1,pt1.first,pt1.second.first,pt1.second.second,ic1,ic1+1,1); + return self; + case 2: + tmp=DataArrayDouble::New(); + tmp->useArray(&v1[0],false,CPP_DEALLOC,1,v1.size()); + self->setPartOfValues1(tmp,pt1.first,pt1.second.first,pt1.second.second,ic1,ic1+1,1,false); + return self; + case 3: + self->setPartOfValues1(d1,pt1.first,pt1.second.first,pt1.second.second,ic1,ic1+1,1); + return self; + default: + throw INTERP_KERNEL::Exception(msg); + } + break; + } + case 8: + { + switch(sw1) + { + case 1: + self->setPartOfValuesSimple3(i1,dt1->getConstPointer(),dt1->getConstPointer()+dt1->getNbOfElems(),ic1,ic1+1,1); + return self; + case 2: + tmp=DataArrayDouble::New(); + tmp->useArray(&v1[0],false,CPP_DEALLOC,1,v1.size()); + self->setPartOfValues3(tmp,dt1->getConstPointer(),dt1->getConstPointer()+dt1->getNbOfElems(),ic1,ic1+1,1,false); + return self; + case 3: + self->setPartOfValues3(d1,dt1->getConstPointer(),dt1->getConstPointer()+dt1->getNbOfElems(),ic1,ic1+1,1); + return self; + default: + throw INTERP_KERNEL::Exception(msg); + } + break; + } + case 9: + { + switch(sw1) + { + case 1: + self->setPartOfValuesSimple2(i1,&it1,&it1+1,&vc1[0],&vc1[0]+vc1.size()); + return self; + case 2: + tmp=DataArrayDouble::New(); + tmp->useArray(&v1[0],false,CPP_DEALLOC,1,v1.size()); + self->setPartOfValues2(tmp,&it1,&it1+1,&vc1[0],&vc1[0]+vc1.size(),false); + return self; + case 3: + self->setPartOfValues2(d1,&it1,&it1+1,&vc1[0],&vc1[0]+vc1.size()); + return self; + default: + throw INTERP_KERNEL::Exception(msg); + } + break; + } + case 10: + { + switch(sw1) + { + case 1: + self->setPartOfValuesSimple2(i1,&vt1[0],&vt1[0]+vt1.size(),&vc1[0],&vc1[0]+vc1.size()); + return self; + case 2: + tmp=DataArrayDouble::New(); + tmp->useArray(&v1[0],false,CPP_DEALLOC,1,v1.size()); + self->setPartOfValues2(tmp,&vt1[0],&vt1[0]+vt1.size(),&vc1[0],&vc1[0]+vc1.size(),false); + return self; + case 3: + self->setPartOfValues2(d1,&vt1[0],&vt1[0]+vt1.size(),&vc1[0],&vc1[0]+vc1.size()); + return self; + default: + throw INTERP_KERNEL::Exception(msg); + } + break; + } + case 11: + { + switch(sw1) + { + case 1: + self->setPartOfValuesSimple4(i1,pt1.first,pt1.second.first,pt1.second.second,&vc1[0],&vc1[0]+vc1.size()); + return self; + case 2: + tmp=DataArrayDouble::New(); + tmp->useArray(&v1[0],false,CPP_DEALLOC,1,v1.size()); + self->setPartOfValues4(tmp,pt1.first,pt1.second.first,pt1.second.second,&vc1[0],&vc1[0]+vc1.size(),false); + return self; + case 3: + self->setPartOfValues4(d1,pt1.first,pt1.second.first,pt1.second.second,&vc1[0],&vc1[0]+vc1.size()); + return self; + default: + throw INTERP_KERNEL::Exception(msg); + } + break; + } + case 12: + { + switch(sw1) + { + case 1: + self->setPartOfValuesSimple2(i1,dt1->getConstPointer(),dt1->getConstPointer()+dt1->getNbOfElems(),&vc1[0],&vc1[0]+vc1.size()); + return self; + case 2: + tmp=DataArrayDouble::New(); + tmp->useArray(&v1[0],false,CPP_DEALLOC,1,v1.size()); + self->setPartOfValues2(tmp,dt1->getConstPointer(),dt1->getConstPointer()+dt1->getNbOfElems(),&vc1[0],&vc1[0]+vc1.size(),false); + return self; + case 3: + self->setPartOfValues2(d1,dt1->getConstPointer(),dt1->getConstPointer()+dt1->getNbOfElems(),&vc1[0],&vc1[0]+vc1.size()); + return self; + default: + throw INTERP_KERNEL::Exception(msg); + } + break; + } + case 13: + { + switch(sw1) + { + case 1: + self->setPartOfValuesSimple1(i1,it1,it1+1,1,pc1.first,pc1.second.first,pc1.second.second); + return self; + case 2: + tmp=DataArrayDouble::New(); + tmp->useArray(&v1[0],false,CPP_DEALLOC,1,v1.size()); + self->setPartOfValues1(tmp,it1,it1+1,1,pc1.first,pc1.second.first,pc1.second.second,false); + return self; + case 3: + self->setPartOfValues1(d1,it1,it1+1,1,pc1.first,pc1.second.first,pc1.second.second); + return self; + default: + throw INTERP_KERNEL::Exception(msg); + } + break; + } + case 14: + { + switch(sw1) + { + case 1: + self->setPartOfValuesSimple3(i1,&vt1[0],&vt1[0]+vt1.size(),pc1.first,pc1.second.first,pc1.second.second); + return self; + case 2: + tmp=DataArrayDouble::New(); + tmp->useArray(&v1[0],false,CPP_DEALLOC,1,v1.size()); + self->setPartOfValues3(tmp,&vt1[0],&vt1[0]+vt1.size(),pc1.first,pc1.second.first,pc1.second.second,false); + return self; + case 3: + self->setPartOfValues3(d1,&vt1[0],&vt1[0]+vt1.size(),pc1.first,pc1.second.first,pc1.second.second); + return self; + default: + throw INTERP_KERNEL::Exception(msg); + } + break; + } + case 15: + { + switch(sw1) + { + case 1: + self->setPartOfValuesSimple1(i1,pt1.first,pt1.second.first,pt1.second.second,pc1.first,pc1.second.first,pc1.second.second); + return self; + case 2: + tmp=DataArrayDouble::New(); + tmp->useArray(&v1[0],false,CPP_DEALLOC,1,v1.size()); + self->setPartOfValues1(tmp,pt1.first,pt1.second.first,pt1.second.second,pc1.first,pc1.second.first,pc1.second.second,false); + return self; + case 3: + self->setPartOfValues1(d1,pt1.first,pt1.second.first,pt1.second.second,pc1.first,pc1.second.first,pc1.second.second); + return self; + default: + throw INTERP_KERNEL::Exception(msg); + } + break; + } + case 16: + { + switch(sw1) + { + case 1: + self->setPartOfValuesSimple3(i1,dt1->getConstPointer(),dt1->getConstPointer()+dt1->getNbOfElems(),pc1.first,pc1.second.first,pc1.second.second); + return self; + case 2: + tmp=DataArrayDouble::New(); + tmp->useArray(&v1[0],false,CPP_DEALLOC,1,v1.size()); + self->setPartOfValues3(tmp,dt1->getConstPointer(),dt1->getConstPointer()+dt1->getNbOfElems(),pc1.first,pc1.second.first,pc1.second.second,false); + return self; + case 3: + self->setPartOfValues3(d1,dt1->getConstPointer(),dt1->getConstPointer()+dt1->getNbOfElems(),pc1.first,pc1.second.first,pc1.second.second); + return self; + default: + throw INTERP_KERNEL::Exception(msg); + } + break; + } + default: + throw INTERP_KERNEL::Exception(msg); + } + return self; + } + + DataArrayDouble *__neg__() const throw(INTERP_KERNEL::Exception) + { + return self->negate(); + } + + PyObject *__add__(PyObject *obj) throw(INTERP_KERNEL::Exception) + { + const char msg[]="Unexpected situation in DataArrayDouble.__add__ !"; + double val; + DataArrayDouble *a; + DataArrayDoubleTuple *aa; + std::vector<double> bb; + int sw; + // +#ifndef WITHOUT_AUTOFIELD + void *argp; + if(SWIG_IsOK(SWIG_ConvertPtr(obj,&argp,SWIGTYPE_p_ParaMEDMEM__MEDCouplingFieldDouble,0|0))) + { + MEDCouplingFieldDouble *other=reinterpret_cast< ParaMEDMEM::MEDCouplingFieldDouble * >(argp); + if(other) + { + PyObject *tmp=SWIG_NewPointerObj(SWIG_as_voidptr(self),SWIGTYPE_p_ParaMEDMEM__DataArrayDouble, 0 | 0 ); + MEDCouplingAutoRefCountObjectPtr<MEDCouplingFieldDouble> ret=ParaMEDMEM_MEDCouplingFieldDouble___radd__Impl(other,tmp); + Py_XDECREF(tmp); + return SWIG_NewPointerObj(SWIG_as_voidptr(ret.retn()),SWIGTYPE_p_ParaMEDMEM__MEDCouplingFieldDouble, SWIG_POINTER_OWN | 0 ); + } + else + throw INTERP_KERNEL::Exception(msg); + } +#endif + // + convertObjToPossibleCpp5(obj,sw,val,a,aa,bb); + switch(sw) + { + case 1: + { + MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=self->deepCpy(); + ret->applyLin(1.,val); + return SWIG_NewPointerObj(SWIG_as_voidptr(ret.retn()),SWIGTYPE_p_ParaMEDMEM__DataArrayDouble, SWIG_POINTER_OWN | 0 ); + } + case 2: + { + return SWIG_NewPointerObj(SWIG_as_voidptr(DataArrayDouble::Add(self,a)),SWIGTYPE_p_ParaMEDMEM__DataArrayDouble, SWIG_POINTER_OWN | 0 ); + } + case 3: + { + MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> aaa=aa->buildDADouble(1,self->getNumberOfComponents()); + return SWIG_NewPointerObj(SWIG_as_voidptr(DataArrayDouble::Add(self,aaa)),SWIGTYPE_p_ParaMEDMEM__DataArrayDouble, SWIG_POINTER_OWN | 0 ); + } + case 4: + { + MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> aaa=DataArrayDouble::New(); aaa->useArray(&bb[0],false,CPP_DEALLOC,1,(int)bb.size()); + return SWIG_NewPointerObj(SWIG_as_voidptr(DataArrayDouble::Add(self,aaa)),SWIGTYPE_p_ParaMEDMEM__DataArrayDouble, SWIG_POINTER_OWN | 0 ); + } + default: + throw INTERP_KERNEL::Exception(msg); + } + } + + DataArrayDouble *__radd__(PyObject *obj) throw(INTERP_KERNEL::Exception) + { + const char msg[]="Unexpected situation in __radd__ !"; + double val; + DataArrayDouble *a; + DataArrayDoubleTuple *aa; + std::vector<double> bb; + int sw; + convertObjToPossibleCpp5(obj,sw,val,a,aa,bb); + switch(sw) + { + case 1: + { + MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=self->deepCpy(); + ret->applyLin(1.,val); + return ret.retn(); + } + case 3: + { + MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> aaa=aa->buildDADouble(1,self->getNumberOfComponents()); + return DataArrayDouble::Add(self,aaa); + } + case 4: + { + MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> aaa=DataArrayDouble::New(); aaa->useArray(&bb[0],false,CPP_DEALLOC,1,(int)bb.size()); + return DataArrayDouble::Add(self,aaa); + } + default: + throw INTERP_KERNEL::Exception(msg); + } + } + + PyObject *___iadd___(PyObject *trueSelf, PyObject *obj) throw(INTERP_KERNEL::Exception) + { + const char msg[]="Unexpected situation in __iadd__ !"; + double val; + DataArrayDouble *a; + DataArrayDoubleTuple *aa; + std::vector<double> bb; + int sw; + convertObjToPossibleCpp5(obj,sw,val,a,aa,bb); + switch(sw) + { + case 1: + { + self->applyLin(1.,val); + Py_XINCREF(trueSelf); + return trueSelf; + } + case 2: + { + self->addEqual(a); + Py_XINCREF(trueSelf); + return trueSelf; + } + case 3: + { + MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> aaa=aa->buildDADouble(1,self->getNumberOfComponents()); + self->addEqual(aaa); + Py_XINCREF(trueSelf); + return trueSelf; + } + case 4: + { + MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> aaa=DataArrayDouble::New(); aaa->useArray(&bb[0],false,CPP_DEALLOC,1,(int)bb.size()); + self->addEqual(aaa); + Py_XINCREF(trueSelf); + return trueSelf; + } + default: + throw INTERP_KERNEL::Exception(msg); + } + } + + PyObject *__sub__(PyObject *obj) throw(INTERP_KERNEL::Exception) + { + const char msg[]="Unexpected situation in __sub__ !"; + double val; + DataArrayDouble *a; + DataArrayDoubleTuple *aa; + std::vector<double> bb; + int sw; + // +#ifndef WITHOUT_AUTOFIELD + void *argp; + if(SWIG_IsOK(SWIG_ConvertPtr(obj,&argp,SWIGTYPE_p_ParaMEDMEM__MEDCouplingFieldDouble,0|0))) + { + MEDCouplingFieldDouble *other=reinterpret_cast< ParaMEDMEM::MEDCouplingFieldDouble * >(argp); + if(other) + { + PyObject *tmp=SWIG_NewPointerObj(SWIG_as_voidptr(self),SWIGTYPE_p_ParaMEDMEM__DataArrayDouble, 0 | 0 ); + MEDCouplingAutoRefCountObjectPtr<MEDCouplingFieldDouble> ret=ParaMEDMEM_MEDCouplingFieldDouble___rsub__Impl(other,tmp); + Py_XDECREF(tmp); + return SWIG_NewPointerObj(SWIG_as_voidptr(ret.retn()),SWIGTYPE_p_ParaMEDMEM__MEDCouplingFieldDouble, SWIG_POINTER_OWN | 0 ); + } + else + throw INTERP_KERNEL::Exception(msg); + } +#endif + // + convertObjToPossibleCpp5(obj,sw,val,a,aa,bb); + switch(sw) + { + case 1: + { + MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=self->deepCpy(); + ret->applyLin(1.,-val); + return SWIG_NewPointerObj(SWIG_as_voidptr(ret.retn()),SWIGTYPE_p_ParaMEDMEM__DataArrayDouble, SWIG_POINTER_OWN | 0 ); + } + case 2: + { + return SWIG_NewPointerObj(SWIG_as_voidptr(DataArrayDouble::Substract(self,a)),SWIGTYPE_p_ParaMEDMEM__DataArrayDouble, SWIG_POINTER_OWN | 0 ); + } + case 3: + { + MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> aaa=aa->buildDADouble(1,self->getNumberOfComponents()); + return SWIG_NewPointerObj(SWIG_as_voidptr(DataArrayDouble::Substract(self,aaa)),SWIGTYPE_p_ParaMEDMEM__DataArrayDouble, SWIG_POINTER_OWN | 0 ); + } + case 4: + { + MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> aaa=DataArrayDouble::New(); aaa->useArray(&bb[0],false,CPP_DEALLOC,1,(int)bb.size()); + return SWIG_NewPointerObj(SWIG_as_voidptr(DataArrayDouble::Substract(self,aaa)),SWIGTYPE_p_ParaMEDMEM__DataArrayDouble, SWIG_POINTER_OWN | 0 ); + } + default: + throw INTERP_KERNEL::Exception(msg); + } + } + + DataArrayDouble *__rsub__(PyObject *obj) throw(INTERP_KERNEL::Exception) + { + const char msg[]="Unexpected situation in __rsub__ !"; + double val; + DataArrayDouble *a; + DataArrayDoubleTuple *aa; + std::vector<double> bb; + int sw; + convertObjToPossibleCpp5(obj,sw,val,a,aa,bb); + switch(sw) + { + case 1: + { + MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=self->deepCpy(); + ret->applyLin(-1.,val); + return ret.retn(); + } + case 3: + { + MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> aaa=aa->buildDADouble(1,self->getNumberOfComponents()); + return DataArrayDouble::Substract(aaa,self); + } + case 4: + { + MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> aaa=DataArrayDouble::New(); aaa->useArray(&bb[0],false,CPP_DEALLOC,1,(int)bb.size()); + return DataArrayDouble::Substract(aaa,self); + } + default: + throw INTERP_KERNEL::Exception(msg); + } + } + + PyObject *___isub___(PyObject *trueSelf, PyObject *obj) throw(INTERP_KERNEL::Exception) + { + const char msg[]="Unexpected situation in __isub__ !"; + double val; + DataArrayDouble *a; + DataArrayDoubleTuple *aa; + std::vector<double> bb; + int sw; + convertObjToPossibleCpp5(obj,sw,val,a,aa,bb); + switch(sw) + { + case 1: + { + self->applyLin(1,-val); + Py_XINCREF(trueSelf); + return trueSelf; + } + case 2: + { + self->substractEqual(a); + Py_XINCREF(trueSelf); + return trueSelf; + } + case 3: + { + MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> aaa=aa->buildDADouble(1,self->getNumberOfComponents()); + self->substractEqual(aaa); + Py_XINCREF(trueSelf); + return trueSelf; + } + case 4: + { + MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> aaa=DataArrayDouble::New(); aaa->useArray(&bb[0],false,CPP_DEALLOC,1,(int)bb.size()); + self->substractEqual(aaa); + Py_XINCREF(trueSelf); + return trueSelf; + } + default: + throw INTERP_KERNEL::Exception(msg); + } + } + + PyObject *__mul__(PyObject *obj) throw(INTERP_KERNEL::Exception) + { + const char msg[]="Unexpected situation in __mul__ !"; + double val; + DataArrayDouble *a; + DataArrayDoubleTuple *aa; + std::vector<double> bb; + int sw; + // +#ifndef WITHOUT_AUTOFIELD + void *argp; + if(SWIG_IsOK(SWIG_ConvertPtr(obj,&argp,SWIGTYPE_p_ParaMEDMEM__MEDCouplingFieldDouble,0|0))) + { + MEDCouplingFieldDouble *other=reinterpret_cast< ParaMEDMEM::MEDCouplingFieldDouble * >(argp); + if(other) + { + PyObject *tmp=SWIG_NewPointerObj(SWIG_as_voidptr(self),SWIGTYPE_p_ParaMEDMEM__DataArrayDouble, 0 | 0 ); + MEDCouplingAutoRefCountObjectPtr<MEDCouplingFieldDouble> ret=ParaMEDMEM_MEDCouplingFieldDouble___rmul__Impl(other,tmp); + Py_XDECREF(tmp); + return SWIG_NewPointerObj(SWIG_as_voidptr(ret.retn()),SWIGTYPE_p_ParaMEDMEM__MEDCouplingFieldDouble, SWIG_POINTER_OWN | 0 ); + } + else + throw INTERP_KERNEL::Exception(msg); + } +#endif + // + convertObjToPossibleCpp5(obj,sw,val,a,aa,bb); + switch(sw) + { + case 1: + { + MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=self->deepCpy(); + ret->applyLin(val,0.); + return SWIG_NewPointerObj(SWIG_as_voidptr(ret.retn()),SWIGTYPE_p_ParaMEDMEM__DataArrayDouble, SWIG_POINTER_OWN | 0 ); + } + case 2: + { + return SWIG_NewPointerObj(SWIG_as_voidptr(DataArrayDouble::Multiply(self,a)),SWIGTYPE_p_ParaMEDMEM__DataArrayDouble, SWIG_POINTER_OWN | 0 ); + } + case 3: + { + MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> aaa=aa->buildDADouble(1,self->getNumberOfComponents()); + return SWIG_NewPointerObj(SWIG_as_voidptr(DataArrayDouble::Multiply(self,aaa)),SWIGTYPE_p_ParaMEDMEM__DataArrayDouble, SWIG_POINTER_OWN | 0 ); + } + case 4: + { + MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> aaa=DataArrayDouble::New(); aaa->useArray(&bb[0],false,CPP_DEALLOC,1,(int)bb.size()); + return SWIG_NewPointerObj(SWIG_as_voidptr(DataArrayDouble::Multiply(self,aaa)),SWIGTYPE_p_ParaMEDMEM__DataArrayDouble, SWIG_POINTER_OWN | 0 ); + } + default: + throw INTERP_KERNEL::Exception(msg); + } + } + + DataArrayDouble *__rmul__(PyObject *obj) throw(INTERP_KERNEL::Exception) + { + const char msg[]="Unexpected situation in __rmul__ !"; + double val; + DataArrayDouble *a; + DataArrayDoubleTuple *aa; + std::vector<double> bb; + int sw; + convertObjToPossibleCpp5(obj,sw,val,a,aa,bb); + switch(sw) + { + case 1: + { + MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=self->deepCpy(); + ret->applyLin(val,0.); + return ret.retn(); + } + case 3: + { + MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> aaa=aa->buildDADouble(1,self->getNumberOfComponents()); + return DataArrayDouble::Multiply(self,aaa); + } + case 4: + { + MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> aaa=DataArrayDouble::New(); aaa->useArray(&bb[0],false,CPP_DEALLOC,1,(int)bb.size()); + return DataArrayDouble::Multiply(self,aaa); + } + default: + throw INTERP_KERNEL::Exception(msg); + } + } + + PyObject *___imul___(PyObject *trueSelf, PyObject *obj) throw(INTERP_KERNEL::Exception) + { + const char msg[]="Unexpected situation in __imul__ !"; + double val; + DataArrayDouble *a; + DataArrayDoubleTuple *aa; + std::vector<double> bb; + int sw; + convertObjToPossibleCpp5(obj,sw,val,a,aa,bb); + switch(sw) + { + case 1: + { + self->applyLin(val,0.); + Py_XINCREF(trueSelf); + return trueSelf; + } + case 2: + { + self->multiplyEqual(a); + Py_XINCREF(trueSelf); + return trueSelf; + } + case 3: + { + MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> aaa=aa->buildDADouble(1,self->getNumberOfComponents()); + self->multiplyEqual(aaa); + Py_XINCREF(trueSelf); + return trueSelf; + } + case 4: + { + MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> aaa=DataArrayDouble::New(); aaa->useArray(&bb[0],false,CPP_DEALLOC,1,(int)bb.size()); + self->multiplyEqual(aaa); + Py_XINCREF(trueSelf); + return trueSelf; + } + default: + throw INTERP_KERNEL::Exception(msg); + } + } + + PyObject *__div__(PyObject *obj) throw(INTERP_KERNEL::Exception) + { + const char msg[]="Unexpected situation in __div__ !"; + double val; + DataArrayDouble *a; + DataArrayDoubleTuple *aa; + std::vector<double> bb; + int sw; + // +#ifndef WITHOUT_AUTOFIELD + void *argp; + if(SWIG_IsOK(SWIG_ConvertPtr(obj,&argp,SWIGTYPE_p_ParaMEDMEM__MEDCouplingFieldDouble,0|0))) + { + MEDCouplingFieldDouble *other=reinterpret_cast< ParaMEDMEM::MEDCouplingFieldDouble * >(argp); + if(other) + { + PyObject *tmp=SWIG_NewPointerObj(SWIG_as_voidptr(self),SWIGTYPE_p_ParaMEDMEM__DataArrayDouble, 0 | 0 ); + MEDCouplingAutoRefCountObjectPtr<MEDCouplingFieldDouble> ret=ParaMEDMEM_MEDCouplingFieldDouble___rdiv__Impl(other,tmp); + Py_XDECREF(tmp); + return SWIG_NewPointerObj(SWIG_as_voidptr(ret.retn()),SWIGTYPE_p_ParaMEDMEM__MEDCouplingFieldDouble, SWIG_POINTER_OWN | 0 ); + } + else + throw INTERP_KERNEL::Exception(msg); + } +#endif + // + convertObjToPossibleCpp5(obj,sw,val,a,aa,bb); + switch(sw) + { + case 1: + { + if(val==0.) + throw INTERP_KERNEL::Exception("DataArrayDouble::__div__ : trying to divide by zero !"); + MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=self->deepCpy(); + ret->applyLin(1/val,0.); + return SWIG_NewPointerObj(SWIG_as_voidptr(ret.retn()),SWIGTYPE_p_ParaMEDMEM__DataArrayDouble, SWIG_POINTER_OWN | 0 ); + } + case 2: + { + return SWIG_NewPointerObj(SWIG_as_voidptr(DataArrayDouble::Divide(self,a)),SWIGTYPE_p_ParaMEDMEM__DataArrayDouble, SWIG_POINTER_OWN | 0 ); + } + case 3: + { + MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> aaa=aa->buildDADouble(1,self->getNumberOfComponents()); + return SWIG_NewPointerObj(SWIG_as_voidptr(DataArrayDouble::Divide(self,aaa)),SWIGTYPE_p_ParaMEDMEM__DataArrayDouble, SWIG_POINTER_OWN | 0 ); + } + case 4: + { + MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> aaa=DataArrayDouble::New(); aaa->useArray(&bb[0],false,CPP_DEALLOC,1,(int)bb.size()); + return SWIG_NewPointerObj(SWIG_as_voidptr(DataArrayDouble::Divide(self,aaa)),SWIGTYPE_p_ParaMEDMEM__DataArrayDouble, SWIG_POINTER_OWN | 0 ); + } + default: + throw INTERP_KERNEL::Exception(msg); + } + } + + DataArrayDouble *__rdiv__(PyObject *obj) throw(INTERP_KERNEL::Exception) + { + const char msg[]="Unexpected situation in __rdiv__ !"; + double val; + DataArrayDouble *a; + DataArrayDoubleTuple *aa; + std::vector<double> bb; + int sw; + convertObjToPossibleCpp5(obj,sw,val,a,aa,bb); + switch(sw) + { + case 1: + { + MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=self->deepCpy(); + ret->applyInv(val); + return ret.retn(); + } + case 3: + { + MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> aaa=aa->buildDADouble(1,self->getNumberOfComponents()); + return DataArrayDouble::Divide(aaa,self); + } + case 4: + { + MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> aaa=DataArrayDouble::New(); aaa->useArray(&bb[0],false,CPP_DEALLOC,1,(int)bb.size()); + return DataArrayDouble::Divide(aaa,self); + } + default: + throw INTERP_KERNEL::Exception(msg); + } + } + + PyObject *___idiv___(PyObject *trueSelf, PyObject *obj) throw(INTERP_KERNEL::Exception) + { + const char msg[]="Unexpected situation in __idiv__ !"; + double val; + DataArrayDouble *a; + DataArrayDoubleTuple *aa; + std::vector<double> bb; + int sw; + convertObjToPossibleCpp5(obj,sw,val,a,aa,bb); + switch(sw) + { + case 1: + { + if(val==0.) + throw INTERP_KERNEL::Exception("DataArrayDouble::__div__ : trying to divide by zero !"); + self->applyLin(1./val,0.); + Py_XINCREF(trueSelf); + return trueSelf; + } + case 2: + { + self->divideEqual(a); + Py_XINCREF(trueSelf); + return trueSelf; + } + case 3: + { + MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> aaa=aa->buildDADouble(1,self->getNumberOfComponents()); + self->divideEqual(aaa); + Py_XINCREF(trueSelf); + return trueSelf; + } + case 4: + { + MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> aaa=DataArrayDouble::New(); aaa->useArray(&bb[0],false,CPP_DEALLOC,1,(int)bb.size()); + self->divideEqual(aaa); + Py_XINCREF(trueSelf); + return trueSelf; + } + default: + throw INTERP_KERNEL::Exception(msg); + } + } + + DataArrayDouble *__pow__(PyObject *obj) throw(INTERP_KERNEL::Exception) + { + const char msg[]="Unexpected situation in __pow__ !"; + double val; + DataArrayDouble *a; + DataArrayDoubleTuple *aa; + std::vector<double> bb; + int sw; + convertObjToPossibleCpp5(obj,sw,val,a,aa,bb); + switch(sw) + { + case 1: + { + MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=self->deepCpy(); + ret->applyPow(val); + return ret.retn(); + } + case 2: + { + return DataArrayDouble::Pow(self,a); + } + case 3: + { + MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> aaa=aa->buildDADouble(1,self->getNumberOfComponents()); + return DataArrayDouble::Pow(self,aaa); + } + case 4: + { + MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> aaa=DataArrayDouble::New(); aaa->useArray(&bb[0],false,CPP_DEALLOC,1,(int)bb.size()); + return DataArrayDouble::Pow(self,aaa); + } + default: + throw INTERP_KERNEL::Exception(msg); + } + } + + DataArrayDouble *__rpow__(PyObject *obj) throw(INTERP_KERNEL::Exception) + { + const char msg[]="Unexpected situation in __rpow__ !"; + double val; + DataArrayDouble *a; + DataArrayDoubleTuple *aa; + std::vector<double> bb; + int sw; + convertObjToPossibleCpp5(obj,sw,val,a,aa,bb); + switch(sw) + { + case 1: + { + MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=self->deepCpy(); + ret->applyRPow(val); + return ret.retn(); + } + case 3: + { + MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> aaa=aa->buildDADouble(1,self->getNumberOfComponents()); + return DataArrayDouble::Pow(aaa,self); + } + case 4: + { + MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> aaa=DataArrayDouble::New(); aaa->useArray(&bb[0],false,CPP_DEALLOC,1,(int)bb.size()); + return DataArrayDouble::Pow(aaa,self); + } + default: + throw INTERP_KERNEL::Exception(msg); + } + } + + PyObject *___ipow___(PyObject *trueSelf, PyObject *obj) throw(INTERP_KERNEL::Exception) + { + const char msg[]="Unexpected situation in __ipow__ !"; + double val; + DataArrayDouble *a; + DataArrayDoubleTuple *aa; + std::vector<double> bb; + int sw; + convertObjToPossibleCpp5(obj,sw,val,a,aa,bb); + switch(sw) + { + case 1: + { + self->applyPow(val); + Py_XINCREF(trueSelf); + return trueSelf; + } + case 2: + { + self->powEqual(a); + Py_XINCREF(trueSelf); + return trueSelf; + } + case 3: + { + MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> aaa=aa->buildDADouble(1,self->getNumberOfComponents()); + self->powEqual(aaa); + Py_XINCREF(trueSelf); + return trueSelf; + } + case 4: + { + MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> aaa=DataArrayDouble::New(); aaa->useArray(&bb[0],false,CPP_DEALLOC,1,(int)bb.size()); + self->powEqual(aaa); + Py_XINCREF(trueSelf); + return trueSelf; + } + default: + throw INTERP_KERNEL::Exception(msg); + } + } + + PyObject *computeTupleIdsNearTuples(const DataArrayDouble *other, double eps) + { + DataArrayInt *c=0,*cI=0; + // + self->computeTupleIdsNearTuples(other,eps,c,cI); + PyObject *ret=PyTuple_New(2); + PyTuple_SetItem(ret,0,SWIG_NewPointerObj(SWIG_as_voidptr(c),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 )); + PyTuple_SetItem(ret,1,SWIG_NewPointerObj(SWIG_as_voidptr(cI),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 )); + return ret; + } + + PyObject *maxPerTupleWithCompoId() const throw(INTERP_KERNEL::Exception) + { + DataArrayInt *ret1=0; + DataArrayDouble *ret0=self->maxPerTupleWithCompoId(ret1); + PyObject *ret=PyTuple_New(2); + PyTuple_SetItem(ret,0,SWIG_NewPointerObj(SWIG_as_voidptr(ret0),SWIGTYPE_p_ParaMEDMEM__DataArrayDouble, SWIG_POINTER_OWN | 0 )); + PyTuple_SetItem(ret,1,SWIG_NewPointerObj(SWIG_as_voidptr(ret1),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 )); + return ret; + } + + // serialization + static PyObject *___new___(PyObject *cls, PyObject *args) throw(INTERP_KERNEL::Exception) + { + static const char MSG[]="DataArrayDouble.__new__ : the args in input is expected to be a tuple !"; + if(!PyTuple_Check(args)) + throw INTERP_KERNEL::Exception(MSG); + PyObject *builtinsd(PyEval_GetBuiltins());//borrowed + PyObject *obj(PyDict_GetItemString(builtinsd,"object"));//borrowed + PyObject *selfMeth(PyObject_GetAttrString(obj,"__new__")); + // + PyObject *tmp0(PyTuple_New(1)); + PyTuple_SetItem(tmp0,0,cls); Py_XINCREF(cls); + PyObject *instance(PyObject_CallObject(selfMeth,tmp0)); + Py_DECREF(tmp0); + Py_DECREF(selfMeth); + PyObject *initMeth(PyObject_GetAttrString(instance,"__init__")); + int sz(PyTuple_Size(args)); + + if(PyTuple_Size(args)==2 && PyDict_Check(PyTuple_GetItem(args,1)) && PyDict_Size(PyTuple_GetItem(args,1))==1 ) + {// NOT general case. only true if in unpickeling context ! call __init__. Because for all other cases, __init__ is called right after __new__ ! + PyObject *zeNumpyRepr(0); + PyObject *tmp1(PyInt_FromLong(0)); + zeNumpyRepr=PyDict_GetItem(PyTuple_GetItem(args,1),tmp1);//borrowed + Py_DECREF(tmp1); + PyObject *tmp3(PyTuple_New(1)); + PyTuple_SetItem(tmp3,0,zeNumpyRepr); Py_XINCREF(zeNumpyRepr); + PyObject *tmp2(PyObject_CallObject(initMeth,tmp3)); + Py_XDECREF(tmp2); + Py_DECREF(tmp3); + } + Py_DECREF(initMeth); + return instance; + } + + PyObject *__getnewargs__() throw(INTERP_KERNEL::Exception) + { +#ifdef WITH_NUMPY + if(!self->isAllocated()) + throw INTERP_KERNEL::Exception("PyWrap of DataArrayDouble.__getnewargs__ : self is not allocated !"); + PyObject *ret(PyTuple_New(1)); + PyObject *ret0(PyDict_New()); + PyObject *numpyArryObj(ParaMEDMEM_DataArrayDouble_toNumPyArray(self)); + {// create a dict to discriminite in __new__ if __init__ should be called. Not beautiful but not idea ... + PyObject *tmp1(PyInt_FromLong(0)); + PyDict_SetItem(ret0,tmp1,numpyArryObj); Py_DECREF(tmp1); Py_DECREF(numpyArryObj); + PyTuple_SetItem(ret,0,ret0); + } + return ret; +#else + throw INTERP_KERNEL::Exception("PyWrap of DataArrayDouble.__getnewargs__ : not implemented because numpy is not active in your configuration ! No serialization/unserialization available without numpy !"); +#endif + } + } + }; + + class DataArrayDoubleTuple; + + class DataArrayDoubleIterator + { + public: + DataArrayDoubleIterator(DataArrayDouble *da); + ~DataArrayDoubleIterator(); + %extend + { + PyObject *next() + { + DataArrayDoubleTuple *ret=self->nextt(); + if(ret) + return SWIG_NewPointerObj(SWIG_as_voidptr(ret),SWIGTYPE_p_ParaMEDMEM__DataArrayDoubleTuple,SWIG_POINTER_OWN|0); + else + { + PyErr_SetString(PyExc_StopIteration,"No more data."); + return 0; + } + } + } + }; + + class DataArrayDoubleTuple + { + public: + int getNumberOfCompo() const throw(INTERP_KERNEL::Exception); + DataArrayDouble *buildDADouble(int nbOfTuples, int nbOfCompo) const throw(INTERP_KERNEL::Exception); + %extend + { + std::string __str__() const throw(INTERP_KERNEL::Exception) + { + return self->repr(); + } + + double __float__() const throw(INTERP_KERNEL::Exception) + { + return self->doubleValue(); + } + + DataArrayDouble *buildDADouble() throw(INTERP_KERNEL::Exception) + { + return self->buildDADouble(1,self->getNumberOfCompo()); + } + + PyObject *___iadd___(PyObject *trueSelf, PyObject *obj) throw(INTERP_KERNEL::Exception) + { + MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=self->buildDADouble(1,self->getNumberOfCompo()); + ParaMEDMEM_DataArrayDouble____iadd___(ret,0,obj); + Py_XINCREF(trueSelf); + return trueSelf; + } + + PyObject *___isub___(PyObject *trueSelf, PyObject *obj) throw(INTERP_KERNEL::Exception) + { + MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=self->buildDADouble(1,self->getNumberOfCompo()); + ParaMEDMEM_DataArrayDouble____isub___(ret,0,obj); + Py_XINCREF(trueSelf); + return trueSelf; + } + + PyObject *___imul___(PyObject *trueSelf, PyObject *obj) throw(INTERP_KERNEL::Exception) + { + MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=self->buildDADouble(1,self->getNumberOfCompo()); + ParaMEDMEM_DataArrayDouble____imul___(ret,0,obj); + Py_XINCREF(trueSelf); + return trueSelf; + } + + PyObject *___idiv___(PyObject *trueSelf, PyObject *obj) throw(INTERP_KERNEL::Exception) + { + MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> ret=self->buildDADouble(1,self->getNumberOfCompo()); + ParaMEDMEM_DataArrayDouble____idiv___(ret,0,obj); + Py_XINCREF(trueSelf); + return trueSelf; + } + + PyObject *__len__() throw(INTERP_KERNEL::Exception) + { + return PyInt_FromLong(self->getNumberOfCompo()); + } + + PyObject *__getitem__(PyObject *obj) throw(INTERP_KERNEL::Exception) + { + const char msg2[]="DataArrayDoubleTuple::__getitem__ : Mismatch of slice values in 2nd parameter (components) !"; + int sw; + int singleVal; + std::vector<int> multiVal; + std::pair<int, std::pair<int,int> > slic; + ParaMEDMEM::DataArrayInt *daIntTyypp=0; + const double *pt=self->getConstPointer(); + int nbc=self->getNumberOfCompo(); + convertObjToPossibleCpp2WithNegIntInterp(obj,nbc,sw,singleVal,multiVal,slic,daIntTyypp); + switch(sw) + { + case 1: + { + if(singleVal>=nbc) + { + std::ostringstream oss; + oss << "Requesting for id " << singleVal << " having only " << nbc << " components !"; + PyErr_SetString(PyExc_StopIteration,oss.str().c_str()); + return 0; + } + if(singleVal>=0) + return PyFloat_FromDouble(pt[singleVal]); + else + { + if(nbc+singleVal>0) + return PyFloat_FromDouble(pt[nbc+singleVal]); + else + { + std::ostringstream oss; + oss << "Requesting for id " << singleVal << " having only " << nbc << " components !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + } + } + case 2: + { + PyObject *t=PyTuple_New(multiVal.size()); + for(int j=0;j<(int)multiVal.size();j++) + { + int cid=multiVal[j]; + if(cid>=nbc) + { + std::ostringstream oss; + oss << "Requesting for id #" << cid << " having only " << nbc << " components !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + PyTuple_SetItem(t,j,PyFloat_FromDouble(pt[cid])); + } + return t; + } + case 3: + { + int sz=DataArray::GetNumberOfItemGivenBES(slic.first,slic.second.first,slic.second.second,msg2); + PyObject *t=PyTuple_New(sz); + for(int j=0;j<sz;j++) + PyTuple_SetItem(t,j,PyFloat_FromDouble(pt[slic.first+j*slic.second.second])); + return t; + } + default: + throw INTERP_KERNEL::Exception("DataArrayDoubleTuple::__getitem__ : unrecognized type entered !"); + } + } + + DataArrayDoubleTuple *__setitem__(PyObject *obj, PyObject *value) throw(INTERP_KERNEL::Exception) + { + const char msg[]="DataArrayDoubleTuple::__setitem__ : unrecognized type entered, int, slice, list<int>, tuple<int> !"; + const char msg2[]="DataArrayDoubleTuple::__setitem__ : Mismatch of slice values in 2nd parameter (components) !"; + int sw1,sw2; + double singleValV; + std::vector<double> multiValV; + ParaMEDMEM::DataArrayDoubleTuple *daIntTyyppV=0; + int nbc=self->getNumberOfCompo(); + convertObjToPossibleCpp44(value,sw1,singleValV,multiValV,daIntTyyppV); + int singleVal; + std::vector<int> multiVal; + std::pair<int, std::pair<int,int> > slic; + ParaMEDMEM::DataArrayInt *daIntTyypp=0; + double *pt=self->getPointer(); + convertObjToPossibleCpp2WithNegIntInterp(obj,nbc,sw2,singleVal,multiVal,slic,daIntTyypp); + switch(sw2) + { + case 1: + { + if(singleVal>=nbc) + { + std::ostringstream oss; + oss << "Requesting for setting id # " << singleVal << " having only " << nbc << " components !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + switch(sw1) + { + case 1: + { + pt[singleVal]=singleValV; + return self; + } + case 2: + { + if(multiValV.size()!=1) + { + std::ostringstream oss; + oss << "Requesting for setting id # " << singleVal << " with a list or tuple with size != 1 ! "; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + pt[singleVal]=multiValV[0]; + return self; + } + case 3: + { + pt[singleVal]=daIntTyyppV->getConstPointer()[0]; + return self; + } + default: + throw INTERP_KERNEL::Exception(msg); + } + } + case 2: + { + switch(sw1) + { + case 1: + { + for(std::vector<int>::const_iterator it=multiVal.begin();it!=multiVal.end();it++) + { + if(*it>=nbc) + { + std::ostringstream oss; + oss << "Requesting for setting id # " << *it << " having only " << nbc << " components !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + pt[*it]=singleValV; + } + return self; + } + case 2: + { + if(multiVal.size()!=multiValV.size()) + { + std::ostringstream oss; + oss << "Mismatch length of during assignment : " << multiValV.size() << " != " << multiVal.size() << " !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + for(int i=0;i<(int)multiVal.size();i++) + { + int pos=multiVal[i]; + if(pos>=nbc) + { + std::ostringstream oss; + oss << "Requesting for setting id # " << pos << " having only " << nbc << " components !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + pt[multiVal[i]]=multiValV[i]; + } + return self; + } + case 3: + { + const double *ptV=daIntTyyppV->getConstPointer(); + if(nbc>daIntTyyppV->getNumberOfCompo()) + { + std::ostringstream oss; + oss << "Mismatch length of during assignment : " << nbc << " != " << daIntTyyppV->getNumberOfCompo() << " !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + std::copy(ptV,ptV+nbc,pt); + return self; + } + default: + throw INTERP_KERNEL::Exception(msg); + } + } + case 3: + { + int sz=DataArray::GetNumberOfItemGivenBES(slic.first,slic.second.first,slic.second.second,msg2); + switch(sw1) + { + case 1: + { + for(int j=0;j<sz;j++) + pt[slic.first+j*slic.second.second]=singleValV; + return self; + } + case 2: + { + if(sz!=(int)multiValV.size()) + { + std::ostringstream oss; + oss << "Mismatch length of during assignment : " << multiValV.size() << " != " << sz << " !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + for(int j=0;j<sz;j++) + pt[slic.first+j*slic.second.second]=multiValV[j]; + return self; + } + case 3: + { + const double *ptV=daIntTyyppV->getConstPointer(); + if(sz>daIntTyyppV->getNumberOfCompo()) + { + std::ostringstream oss; + oss << "Mismatch length of during assignment : " << nbc << " != " << daIntTyyppV->getNumberOfCompo() << " !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + for(int j=0;j<sz;j++) + pt[slic.first+j*slic.second.second]=ptV[j]; + return self; + } + default: + throw INTERP_KERNEL::Exception(msg); + } + } + default: + throw INTERP_KERNEL::Exception(msg); + } + } + } + }; + + class DataArrayIntIterator; + + class DataArrayInt : public DataArray + { + public: + static DataArrayInt *New(); + int intValue() const throw(INTERP_KERNEL::Exception); + int getHashCode() const throw(INTERP_KERNEL::Exception); + bool empty() const throw(INTERP_KERNEL::Exception); + DataArrayInt *performCpy(bool deepCpy) const throw(INTERP_KERNEL::Exception); + void cpyFrom(const DataArrayInt& other) throw(INTERP_KERNEL::Exception); + void reserve(std::size_t nbOfElems) throw(INTERP_KERNEL::Exception); + void pushBackSilent(int val) throw(INTERP_KERNEL::Exception); + int popBackSilent() throw(INTERP_KERNEL::Exception); + void pack() const throw(INTERP_KERNEL::Exception); + void allocIfNecessary(int nbOfTuple, int nbOfCompo) throw(INTERP_KERNEL::Exception); + bool isEqual(const DataArrayInt& other) const throw(INTERP_KERNEL::Exception); + bool isEqualWithoutConsideringStr(const DataArrayInt& other) const throw(INTERP_KERNEL::Exception); + bool isEqualWithoutConsideringStrAndOrder(const DataArrayInt& other) const throw(INTERP_KERNEL::Exception); + DataArrayInt *buildPermutationArr(const DataArrayInt& other) const throw(INTERP_KERNEL::Exception); + DataArrayInt *sumPerTuple() const throw(INTERP_KERNEL::Exception); + void sort(bool asc=true) throw(INTERP_KERNEL::Exception); + void reverse() throw(INTERP_KERNEL::Exception); + void checkMonotonic(bool increasing) const throw(INTERP_KERNEL::Exception); + bool isMonotonic(bool increasing) const throw(INTERP_KERNEL::Exception); + void checkStrictlyMonotonic(bool increasing) const throw(INTERP_KERNEL::Exception); + bool isStrictlyMonotonic(bool increasing) const throw(INTERP_KERNEL::Exception); + void fillWithZero() throw(INTERP_KERNEL::Exception); + void fillWithValue(int val) throw(INTERP_KERNEL::Exception); + void iota(int init=0) throw(INTERP_KERNEL::Exception); + void replaceOneValByInThis(int valToBeReplaced, int replacedBy) throw(INTERP_KERNEL::Exception); + std::string repr() const throw(INTERP_KERNEL::Exception); + std::string reprZip() const throw(INTERP_KERNEL::Exception); + std::string reprNotTooLong() const throw(INTERP_KERNEL::Exception); + DataArrayInt *invertArrayO2N2N2O(int newNbOfElem) const throw(INTERP_KERNEL::Exception); + DataArrayInt *invertArrayN2O2O2N(int oldNbOfElem) const throw(INTERP_KERNEL::Exception); + DataArrayInt *invertArrayO2N2N2OBis(int newNbOfElem) const throw(INTERP_KERNEL::Exception); + DataArrayDouble *convertToDblArr() const throw(INTERP_KERNEL::Exception); + DataArrayInt *fromNoInterlace() const throw(INTERP_KERNEL::Exception); + DataArrayInt *toNoInterlace() const throw(INTERP_KERNEL::Exception); + DataArrayInt *selectByTupleId2(int bg, int end, int step) const throw(INTERP_KERNEL::Exception); + DataArrayInt *checkAndPreparePermutation() const throw(INTERP_KERNEL::Exception); + DataArrayInt *buildPermArrPerLevel() const throw(INTERP_KERNEL::Exception); + bool isIdentity() const throw(INTERP_KERNEL::Exception); + bool isIdentity2(int sizeExpected) const throw(INTERP_KERNEL::Exception); + bool isUniform(int val) const throw(INTERP_KERNEL::Exception); + DataArrayInt *substr(int tupleIdBg, int tupleIdEnd=-1) const throw(INTERP_KERNEL::Exception); + void transpose() throw(INTERP_KERNEL::Exception); + DataArrayInt *changeNbOfComponents(int newNbOfComp, int dftValue) const throw(INTERP_KERNEL::Exception); + void meldWith(const DataArrayInt *other) throw(INTERP_KERNEL::Exception); + void setPartOfValues1(const DataArrayInt *a, int bgTuples, int endTuples, int stepTuples, int bgComp, int endComp, int stepComp, bool strictCompoCompare=true) throw(INTERP_KERNEL::Exception); + void setPartOfValuesSimple1(int a, int bgTuples, int endTuples, int stepTuples, int bgComp, int endComp, int stepComp) throw(INTERP_KERNEL::Exception); + void setPartOfValuesAdv(const DataArrayInt *a, const DataArrayInt *tuplesSelec) throw(INTERP_KERNEL::Exception); + void getTuple(int tupleId, int *res) const throw(INTERP_KERNEL::Exception); + int getIJ(int tupleId, int compoId) const throw(INTERP_KERNEL::Exception); + int getIJSafe(int tupleId, int compoId) const throw(INTERP_KERNEL::Exception); + int front() const throw(INTERP_KERNEL::Exception); + int back() const throw(INTERP_KERNEL::Exception); + void setIJ(int tupleId, int compoId, int newVal) throw(INTERP_KERNEL::Exception); + void setIJSilent(int tupleId, int compoId, int newVal) throw(INTERP_KERNEL::Exception); + int *getPointer() throw(INTERP_KERNEL::Exception); + const int *getConstPointer() const throw(INTERP_KERNEL::Exception); + DataArrayIntIterator *iterator() throw(INTERP_KERNEL::Exception); + const int *begin() const throw(INTERP_KERNEL::Exception); + const int *end() const throw(INTERP_KERNEL::Exception); + DataArrayInt *getIdsEqual(int val) const throw(INTERP_KERNEL::Exception); + DataArrayInt *getIdsNotEqual(int val) const throw(INTERP_KERNEL::Exception); + int changeValue(int oldValue, int newValue) throw(INTERP_KERNEL::Exception); + int locateTuple(const std::vector<int>& tupl) const throw(INTERP_KERNEL::Exception); + int locateValue(int value) const throw(INTERP_KERNEL::Exception); + int locateValue(const std::vector<int>& vals) const throw(INTERP_KERNEL::Exception); + int search(const std::vector<int>& vals) const throw(INTERP_KERNEL::Exception); + bool presenceOfTuple(const std::vector<int>& tupl) const throw(INTERP_KERNEL::Exception); + bool presenceOfValue(int value) const throw(INTERP_KERNEL::Exception); + bool presenceOfValue(const std::vector<int>& vals) const throw(INTERP_KERNEL::Exception); + int count(int value) const throw(INTERP_KERNEL::Exception); + int accumulate(int compId) const throw(INTERP_KERNEL::Exception); + int getMaxValue(int& tupleId) const throw(INTERP_KERNEL::Exception); + int getMaxValueInArray() const throw(INTERP_KERNEL::Exception); + int getMinValue(int& tupleId) const throw(INTERP_KERNEL::Exception); + int getMinValueInArray() const throw(INTERP_KERNEL::Exception); + void abs() throw(INTERP_KERNEL::Exception); + DataArrayInt *computeAbs() const throw(INTERP_KERNEL::Exception); + void applyLin(int a, int b, int compoId) throw(INTERP_KERNEL::Exception); + void applyLin(int a, int b) throw(INTERP_KERNEL::Exception); + void applyInv(int numerator) throw(INTERP_KERNEL::Exception); + DataArrayInt *negate() const throw(INTERP_KERNEL::Exception); + void applyDivideBy(int val) throw(INTERP_KERNEL::Exception); + void applyModulus(int val) throw(INTERP_KERNEL::Exception); + void applyRModulus(int val) throw(INTERP_KERNEL::Exception); + void applyPow(int val) throw(INTERP_KERNEL::Exception); + void applyRPow(int val) throw(INTERP_KERNEL::Exception); + DataArrayInt *getIdsInRange(int vmin, int vmax) const throw(INTERP_KERNEL::Exception); + DataArrayInt *getIdsNotInRange(int vmin, int vmax) const throw(INTERP_KERNEL::Exception); + DataArrayInt *getIdsStrictlyNegative() const throw(INTERP_KERNEL::Exception); + bool checkAllIdsInRange(int vmin, int vmax) const throw(INTERP_KERNEL::Exception); + static DataArrayInt *Aggregate(const DataArrayInt *a1, const DataArrayInt *a2, int offsetA2) throw(INTERP_KERNEL::Exception); + static DataArrayInt *Meld(const DataArrayInt *a1, const DataArrayInt *a2) throw(INTERP_KERNEL::Exception); + static DataArrayInt *MakePartition(const std::vector<const DataArrayInt *>& groups, int newNb, std::vector< std::vector<int> >& fidsOfGroups) throw(INTERP_KERNEL::Exception); + static DataArrayInt *BuildUnion(const std::vector<const DataArrayInt *>& arr) throw(INTERP_KERNEL::Exception); + static DataArrayInt *BuildIntersection(const std::vector<const DataArrayInt *>& arr) throw(INTERP_KERNEL::Exception); + static DataArrayInt *FindPermutationFromFirstToSecond(const DataArrayInt *ids1, const DataArrayInt *ids2) throw(INTERP_KERNEL::Exception); + DataArrayInt *buildComplement(int nbOfElement) const throw(INTERP_KERNEL::Exception); + DataArrayInt *buildSubstraction(const DataArrayInt *other) const throw(INTERP_KERNEL::Exception); + DataArrayInt *buildSubstractionOptimized(const DataArrayInt *other) const throw(INTERP_KERNEL::Exception); + DataArrayInt *buildUnion(const DataArrayInt *other) const throw(INTERP_KERNEL::Exception); + DataArrayInt *buildIntersection(const DataArrayInt *other) const throw(INTERP_KERNEL::Exception); + DataArrayInt *buildUnique() const throw(INTERP_KERNEL::Exception); + DataArrayInt *buildUniqueNotSorted() const throw(INTERP_KERNEL::Exception); + DataArrayInt *deltaShiftIndex() const throw(INTERP_KERNEL::Exception); + void computeOffsets() throw(INTERP_KERNEL::Exception); + void computeOffsets2() throw(INTERP_KERNEL::Exception); + DataArrayInt *buildExplicitArrByRanges(const DataArrayInt *offsets) const throw(INTERP_KERNEL::Exception); + DataArrayInt *findRangeIdForEachTuple(const DataArrayInt *ranges) const throw(INTERP_KERNEL::Exception); + DataArrayInt *findIdInRangeForEachTuple(const DataArrayInt *ranges) const throw(INTERP_KERNEL::Exception); + void sortEachPairToMakeALinkedList() throw(INTERP_KERNEL::Exception); + DataArrayInt *duplicateEachTupleNTimes(int nbTimes) const throw(INTERP_KERNEL::Exception); + DataArrayInt *getDifferentValues() const throw(INTERP_KERNEL::Exception); + static DataArrayInt *Add(const DataArrayInt *a1, const DataArrayInt *a2) throw(INTERP_KERNEL::Exception); + void addEqual(const DataArrayInt *other) throw(INTERP_KERNEL::Exception); + static DataArrayInt *Substract(const DataArrayInt *a1, const DataArrayInt *a2) throw(INTERP_KERNEL::Exception); + void substractEqual(const DataArrayInt *other) throw(INTERP_KERNEL::Exception); + static DataArrayInt *Multiply(const DataArrayInt *a1, const DataArrayInt *a2) throw(INTERP_KERNEL::Exception); + void multiplyEqual(const DataArrayInt *other) throw(INTERP_KERNEL::Exception); + static DataArrayInt *Divide(const DataArrayInt *a1, const DataArrayInt *a2) throw(INTERP_KERNEL::Exception); + void divideEqual(const DataArrayInt *other) throw(INTERP_KERNEL::Exception); + static DataArrayInt *Modulus(const DataArrayInt *a1, const DataArrayInt *a2) throw(INTERP_KERNEL::Exception); + void modulusEqual(const DataArrayInt *other) throw(INTERP_KERNEL::Exception); + static DataArrayInt *Pow(const DataArrayInt *a1, const DataArrayInt *a2) throw(INTERP_KERNEL::Exception); + void powEqual(const DataArrayInt *other) throw(INTERP_KERNEL::Exception); + public: + static DataArrayInt *Range(int begin, int end, int step) throw(INTERP_KERNEL::Exception); + %extend + { + DataArrayInt() throw(INTERP_KERNEL::Exception) + { + return DataArrayInt::New(); + } + + static DataArrayInt *New(PyObject *elt0, PyObject *nbOfTuples=0, PyObject *nbOfComp=0) throw(INTERP_KERNEL::Exception) + { + const char *msgBase="ParaMEDMEM::DataArrayInt::New : Available API are : \n-DataArrayInt.New()\n-DataArrayInt.New([1,3,4])\n-DataArrayInt.New([1,3,4],3)\n-DataArrayInt.New([1,3,4,5],2,2)\n-DataArrayInt.New([1,3,4,5,7,8],3,2)\n-DataArrayInt.New([(1,3),(4,5),(7,8)])\n-DataArrayInt.New(5)\n-DataArrayInt.New(5,2)"; + std::string msg(msgBase); +#ifdef WITH_NUMPY + msg+="\n-DataArrayInt.New(numpy array with dtype=int32)"; +#endif + msg+=" !"; + if(PyList_Check(elt0) || PyTuple_Check(elt0)) + { + if(nbOfTuples) + { + if(PyInt_Check(nbOfTuples)) + { + int nbOfTuples1=PyInt_AS_LONG(nbOfTuples); + if(nbOfTuples1<0) + throw INTERP_KERNEL::Exception("DataArrayInt::New : should be a positive set of allocated memory !"); + if(nbOfComp) + { + if(PyInt_Check(nbOfComp)) + {//DataArrayInt.New([1,3,4,5],2,2) + int nbOfCompo=PyInt_AS_LONG(nbOfComp); + if(nbOfCompo<0) + throw INTERP_KERNEL::Exception("DataArrayInt::New : should be a positive number of components !"); + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New(); + std::vector<int> tmp=fillArrayWithPyListInt2(elt0,nbOfTuples1,nbOfCompo); + ret->alloc(nbOfTuples1,nbOfCompo); std::copy(tmp.begin(),tmp.end(),ret->getPointer()); + return ret.retn(); + } + else + throw INTERP_KERNEL::Exception(msg.c_str()); + } + else + {//DataArrayInt.New([1,3,4],3) + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New(); + int tmpp1=-1; + std::vector<int> tmp=fillArrayWithPyListInt2(elt0,nbOfTuples1,tmpp1); + ret->alloc(nbOfTuples1,tmpp1); std::copy(tmp.begin(),tmp.end(),ret->getPointer()); + return ret.retn(); + } + } + else + throw INTERP_KERNEL::Exception(msg.c_str()); + } + else + {// DataArrayInt.New([1,3,4]) + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New(); + int tmpp1=-1,tmpp2=-1; + std::vector<int> tmp=fillArrayWithPyListInt2(elt0,tmpp1,tmpp2); + ret->alloc(tmpp1,tmpp2); std::copy(tmp.begin(),tmp.end(),ret->getPointer()); + return ret.retn(); + } + } + else if(PyInt_Check(elt0)) + { + int nbOfTuples1=PyInt_AS_LONG(elt0); + if(nbOfTuples1<0) + throw INTERP_KERNEL::Exception("DataArrayInt::New : should be a positive set of allocated memory !"); + if(nbOfTuples) + { + if(!nbOfComp) + { + if(PyInt_Check(nbOfTuples)) + {//DataArrayInt.New(5,2) + int nbOfCompo=PyInt_AS_LONG(nbOfTuples); + if(nbOfCompo<0) + throw INTERP_KERNEL::Exception("DataArrayInt::New : should be a positive number of components !"); + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New(); + ret->alloc(nbOfTuples1,nbOfCompo); + return ret.retn(); + } + else + throw INTERP_KERNEL::Exception(msg.c_str()); + } + else + throw INTERP_KERNEL::Exception(msg.c_str()); + } + else + {//DataArrayInt.New(5) + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New(); + ret->alloc(nbOfTuples1,1); + return ret.retn(); + } + } +#ifdef WITH_NUMPY + else if(PyArray_Check(elt0) && nbOfTuples==NULL && nbOfComp==NULL) + {//DataArrayInt.New(numpyArray) + return BuildNewInstance<DataArrayInt,int>(elt0,NPY_INT32,&PyCallBackDataArrayInt_RefType,"INT32"); + } +#endif + else + throw INTERP_KERNEL::Exception(msg.c_str()); + throw INTERP_KERNEL::Exception(msg.c_str());//to make g++ happy + } + + DataArrayInt(PyObject *elt0, PyObject *nbOfTuples=0, PyObject *nbOfComp=0) throw(INTERP_KERNEL::Exception) + { + return ParaMEDMEM_DataArrayInt_New__SWIG_1(elt0,nbOfTuples,nbOfComp); + } + + std::string __str__() const throw(INTERP_KERNEL::Exception) + { + return self->reprNotTooLong(); + } + + int __len__() const throw(INTERP_KERNEL::Exception) + { + if(self->isAllocated()) + { + return self->getNumberOfTuples(); + } + else + { + throw INTERP_KERNEL::Exception("DataArrayInt::__len__ : Instance is NOT allocated !"); + } + } + + int __int__() const throw(INTERP_KERNEL::Exception) + { + return self->intValue(); + } + + DataArrayIntIterator *__iter__() throw(INTERP_KERNEL::Exception) + { + return self->iterator(); + } + + PyObject *accumulate() const throw(INTERP_KERNEL::Exception) + { + int sz=self->getNumberOfComponents(); + INTERP_KERNEL::AutoPtr<int> tmp=new int[sz]; + self->accumulate(tmp); + return convertIntArrToPyList(tmp,sz); + } + + DataArrayInt *accumulatePerChunck(PyObject *indexArr) const throw(INTERP_KERNEL::Exception) + { + int sw,sz,val; + std::vector<int> val2; + const int *bg=convertObjToPossibleCpp1_Safe(indexArr,sw,sz,val,val2); + return self->accumulatePerChunck(bg,bg+sz); + } + + DataArrayInt *getIdsEqualTuple(PyObject *inputTuple) const throw(INTERP_KERNEL::Exception) + { + int sw,sz,val; + std::vector<int> val2; + const int *bg(convertObjToPossibleCpp1_Safe(inputTuple,sw,sz,val,val2)); + return self->getIdsEqualTuple(bg,bg+sz); + } + + PyObject *splitInBalancedSlices(int nbOfSlices) const throw(INTERP_KERNEL::Exception) + { + std::vector< std::pair<int,int> > slcs(self->splitInBalancedSlices(nbOfSlices)); + PyObject *ret=PyList_New(slcs.size()); + for(std::size_t i=0;i<slcs.size();i++) + PyList_SetItem(ret,i,PySlice_New(PyInt_FromLong(slcs[i].first),PyInt_FromLong(slcs[i].second),PyInt_FromLong(1))); + return ret; + } + + DataArrayInt *buildExplicitArrOfSliceOnScaledArr(PyObject *slic) const throw(INTERP_KERNEL::Exception) + { + if(!PySlice_Check(slic)) + throw INTERP_KERNEL::Exception("DataArrayInt::buildExplicitArrOfSliceOnScaledArr (wrap) : expecting a pyslice as second (first) parameter !"); + Py_ssize_t strt=2,stp=2,step=2; + PySliceObject *sly=reinterpret_cast<PySliceObject *>(slic); + GetIndicesOfSliceExplicitely(sly,&strt,&stp,&step,"DataArrayInt::buildExplicitArrOfSliceOnScaledArr (wrap) : the input slice is invalid !"); + if(strt==std::numeric_limits<int>::max() || stp==std::numeric_limits<int>::max()) + throw INTERP_KERNEL::Exception("DataArrayInt::buildExplicitArrOfSliceOnScaledArr (wrap) : the input slice contains some unknowns that can't be determined in static method ! Call DataArray::getSlice (non static) instead !"); + return self->buildExplicitArrOfSliceOnScaledArr(strt,stp,step); + } + + PyObject *getMinMaxValues() const throw(INTERP_KERNEL::Exception) + { + int a,b; + self->getMinMaxValues(a,b); + PyObject *ret=PyTuple_New(2); + PyTuple_SetItem(ret,0,PyInt_FromLong(a)); + PyTuple_SetItem(ret,1,PyInt_FromLong(b)); + return ret; + } + + static PyObject *BuildOld2NewArrayFromSurjectiveFormat2(int nbOfOldTuples, PyObject *arr, PyObject *arrI) throw(INTERP_KERNEL::Exception) + { + int newNbOfTuples=-1; + int szArr,szArrI,sw,iTypppArr,iTypppArrI; + std::vector<int> stdvecTyyppArr,stdvecTyyppArrI; + const int *arrPtr=convertObjToPossibleCpp1_Safe(arr,sw,szArr,iTypppArr,stdvecTyyppArr); + const int *arrIPtr=convertObjToPossibleCpp1_Safe(arrI,sw,szArrI,iTypppArrI,stdvecTyyppArrI); + DataArrayInt *ret0=ParaMEDMEM::DataArrayInt::BuildOld2NewArrayFromSurjectiveFormat2(nbOfOldTuples,arrPtr,arrIPtr,arrIPtr+szArrI,newNbOfTuples); + PyObject *ret=PyTuple_New(2); + PyTuple_SetItem(ret,0,SWIG_NewPointerObj((void*)ret0,SWIGTYPE_p_ParaMEDMEM__DataArrayInt,SWIG_POINTER_OWN | 0)); + PyTuple_SetItem(ret,1,PyInt_FromLong(newNbOfTuples)); + return ret; + } + + static DataArrayInt *CheckAndPreparePermutation(PyObject *arr) throw(INTERP_KERNEL::Exception) + { + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret(DataArrayInt::New()); + int szArr,sw,iTypppArr; + std::vector<int> stdvecTyyppArr; + const int *arrPtr(convertObjToPossibleCpp1_Safe(arr,sw,szArr,iTypppArr,stdvecTyyppArr)); + int *pt(ParaMEDMEM::DataArrayInt::CheckAndPreparePermutation(arrPtr,arrPtr+szArr)); + ret->useArray(pt,true,ParaMEDMEM::C_DEALLOC,szArr,1); + return ret.retn(); + } + + void setValues(PyObject *li, PyObject *nbOfTuples=0, PyObject *nbOfComp=0) throw(INTERP_KERNEL::Exception) + { + const char *msg="ParaMEDMEM::DataArrayInt::setValues : Available API are : \n-DataArrayInt.setValues([1,3,4])\n-DataArrayInt.setValues([1,3,4],3)\n-DataArrayInt.setValues([1,3,4,5],2,2)\n-DataArrayInt.New(5)\n !"; + if(PyList_Check(li) || PyTuple_Check(li)) + { + if(nbOfTuples) + { + if(PyInt_Check(nbOfTuples)) + { + int nbOfTuples1=PyInt_AS_LONG(nbOfTuples); + if(nbOfTuples<0) + throw INTERP_KERNEL::Exception("DataArrayInt::setValue : should be a positive set of allocated memory !"); + if(nbOfComp) + { + if(PyInt_Check(nbOfComp)) + {//DataArrayInt.setValues([1,3,4,5],2,2) + int nbOfCompo=PyInt_AS_LONG(nbOfComp); + if(nbOfCompo<0) + throw INTERP_KERNEL::Exception("DataArrayInt::setValue : should be a positive number of components !"); + std::vector<int> tmp=fillArrayWithPyListInt2(li,nbOfTuples1,nbOfCompo); + self->alloc(nbOfTuples1,nbOfCompo); std::copy(tmp.begin(),tmp.end(),self->getPointer()); + } + else + throw INTERP_KERNEL::Exception(msg); + } + else + {//DataArrayInt.setValues([1,3,4],3) + int tmpp1=-1; + std::vector<int> tmp=fillArrayWithPyListInt2(li,nbOfTuples1,tmpp1); + self->alloc(nbOfTuples1,tmpp1); std::copy(tmp.begin(),tmp.end(),self->getPointer()); + } + } + else + throw INTERP_KERNEL::Exception(msg); + } + else + {// DataArrayInt.setValues([1,3,4]) + int tmpp1=-1,tmpp2=-1; + std::vector<int> tmp=fillArrayWithPyListInt2(li,tmpp1,tmpp2); + self->alloc(tmpp1,tmpp2); std::copy(tmp.begin(),tmp.end(),self->getPointer()); + } + } + else + throw INTERP_KERNEL::Exception(msg); + } + + PyObject *getValues() const throw(INTERP_KERNEL::Exception) + { + const int *vals=self->getConstPointer(); + return convertIntArrToPyList(vals,self->getNbOfElems()); + } + +#ifdef WITH_NUMPY + PyObject *toNumPyArray() throw(INTERP_KERNEL::Exception) // not const. It is not a bug ! + { + return ToNumPyArray<DataArrayInt,int>(self,NPY_INT32,"DataArrayInt"); + } +#endif + + PyObject *isEqualIfNotWhy(const DataArrayInt& other) const throw(INTERP_KERNEL::Exception) + { + std::string ret1; + bool ret0=self->isEqualIfNotWhy(other,ret1); + PyObject *ret=PyTuple_New(2); + PyObject *ret0Py=ret0?Py_True:Py_False; + Py_XINCREF(ret0Py); + PyTuple_SetItem(ret,0,ret0Py); + PyTuple_SetItem(ret,1,PyString_FromString(ret1.c_str())); + return ret; + } + + PyObject *getValuesAsTuple() const throw(INTERP_KERNEL::Exception) + { + const int *vals=self->getConstPointer(); + int nbOfComp=self->getNumberOfComponents(); + int nbOfTuples=self->getNumberOfTuples(); + return convertIntArrToPyListOfTuple(vals,nbOfComp,nbOfTuples); + } + + static PyObject *MakePartition(PyObject *gps, int newNb) throw(INTERP_KERNEL::Exception) + { + std::vector<const DataArrayInt *> groups; + std::vector< std::vector<int> > fidsOfGroups; + convertFromPyObjVectorOfObj<const ParaMEDMEM::DataArrayInt *>(gps,SWIGTYPE_p_ParaMEDMEM__DataArrayInt,"DataArrayInt",groups); + ParaMEDMEM::DataArrayInt *ret0=ParaMEDMEM::DataArrayInt::MakePartition(groups,newNb,fidsOfGroups); + PyObject *ret = PyList_New(2); + PyList_SetItem(ret,0,SWIG_NewPointerObj(SWIG_as_voidptr(ret0),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 )); + int sz=fidsOfGroups.size(); + PyObject *ret1 = PyList_New(sz); + for(int i=0;i<sz;i++) + PyList_SetItem(ret1,i,convertIntArrToPyList2(fidsOfGroups[i])); + PyList_SetItem(ret,1,ret1); + return ret; + } + + void transformWithIndArr(PyObject *li) throw(INTERP_KERNEL::Exception) + { + void *da=0; + int res1=SWIG_ConvertPtr(li,&da,SWIGTYPE_p_ParaMEDMEM__DataArrayInt, 0 | 0 ); + if (!SWIG_IsOK(res1)) + { + int size; + INTERP_KERNEL::AutoPtr<int> tmp=convertPyToNewIntArr2(li,&size); + self->transformWithIndArr(tmp,tmp+size); + } + else + { + DataArrayInt *da2=reinterpret_cast< DataArrayInt * >(da); + self->transformWithIndArr(da2->getConstPointer(),da2->getConstPointer()+da2->getNbOfElems()); + } + } + + DataArrayInt *getIdsEqualList(PyObject *obj) throw(INTERP_KERNEL::Exception) + { + int sw; + int singleVal; + std::vector<int> multiVal; + std::pair<int, std::pair<int,int> > slic; + ParaMEDMEM::DataArrayInt *daIntTyypp=0; + convertObjToPossibleCpp2(obj,self->getNumberOfTuples(),sw,singleVal,multiVal,slic,daIntTyypp); + switch(sw) + { + case 1: + return self->getIdsEqualList(&singleVal,&singleVal+1); + case 2: + return self->getIdsEqualList(&multiVal[0],&multiVal[0]+multiVal.size()); + case 4: + return self->getIdsEqualList(daIntTyypp->begin(),daIntTyypp->end()); + default: + throw INTERP_KERNEL::Exception("DataArrayInt::getIdsEqualList : unrecognized type entered, expected list of int, tuple of int or DataArrayInt !"); + } + } + + DataArrayInt *getIdsNotEqualList(PyObject *obj) throw(INTERP_KERNEL::Exception) + { + int sw; + int singleVal; + std::vector<int> multiVal; + std::pair<int, std::pair<int,int> > slic; + ParaMEDMEM::DataArrayInt *daIntTyypp=0; + convertObjToPossibleCpp2(obj,self->getNumberOfTuples(),sw,singleVal,multiVal,slic,daIntTyypp); + switch(sw) + { + case 1: + return self->getIdsNotEqualList(&singleVal,&singleVal+1); + case 2: + return self->getIdsNotEqualList(&multiVal[0],&multiVal[0]+multiVal.size()); + case 4: + return self->getIdsNotEqualList(daIntTyypp->begin(),daIntTyypp->end()); + default: + throw INTERP_KERNEL::Exception("DataArrayInt::getIdsNotEqualList : unrecognized type entered, expected list of int, tuple of int or DataArrayInt !"); + } + } + + PyObject *splitByValueRange(PyObject *li) const throw(INTERP_KERNEL::Exception) + { + DataArrayInt *ret0=0,*ret1=0,*ret2=0; + void *da=0; + int res1=SWIG_ConvertPtr(li,&da,SWIGTYPE_p_ParaMEDMEM__DataArrayInt, 0 | 0 ); + if (!SWIG_IsOK(res1)) + { + int size; + INTERP_KERNEL::AutoPtr<int> tmp=convertPyToNewIntArr2(li,&size); + self->splitByValueRange(tmp,(int *)tmp+size,ret0,ret1,ret2); + } + else + { + DataArrayInt *da2=reinterpret_cast< DataArrayInt * >(da); + if(!da2) + throw INTERP_KERNEL::Exception("Not null DataArrayInt instance expected !"); + da2->checkAllocated(); + int size=self->getNumberOfTuples(); + self->splitByValueRange(da2->getConstPointer(),da2->getConstPointer()+size,ret0,ret1,ret2); + } + PyObject *ret = PyList_New(3); + PyList_SetItem(ret,0,SWIG_NewPointerObj(SWIG_as_voidptr(ret0),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 )); + PyList_SetItem(ret,1,SWIG_NewPointerObj(SWIG_as_voidptr(ret1),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 )); + PyList_SetItem(ret,2,SWIG_NewPointerObj(SWIG_as_voidptr(ret2),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 )); + return ret; + } + + DataArrayInt *transformWithIndArrR(PyObject *li) const throw(INTERP_KERNEL::Exception) + { + void *da=0; + int res1=SWIG_ConvertPtr(li,&da,SWIGTYPE_p_ParaMEDMEM__DataArrayInt, 0 | 0 ); + if (!SWIG_IsOK(res1)) + { + int size; + INTERP_KERNEL::AutoPtr<int> tmp=convertPyToNewIntArr2(li,&size); + return self->transformWithIndArrR(tmp,tmp+size); + } + else + { + DataArrayInt *da2=reinterpret_cast< DataArrayInt * >(da); + return self->transformWithIndArrR(da2->getConstPointer(),da2->getConstPointer()+da2->getNbOfElems()); + } + } + + DataArrayInt *renumberAndReduce(PyObject *li, int newNbOfTuple) throw(INTERP_KERNEL::Exception) + { + void *da=0; + int res1=SWIG_ConvertPtr(li,&da,SWIGTYPE_p_ParaMEDMEM__DataArrayInt, 0 | 0 ); + if (!SWIG_IsOK(res1)) + { + int size; + INTERP_KERNEL::AutoPtr<int> tmp=convertPyToNewIntArr2(li,&size); + if(size!=self->getNumberOfTuples()) + { + throw INTERP_KERNEL::Exception("Invalid list length ! Must be equal to number of tuples !"); + } + return self->renumberAndReduce(tmp,newNbOfTuple); + } + else + { + DataArrayInt *da2=reinterpret_cast< DataArrayInt * >(da); + if(!da2) + throw INTERP_KERNEL::Exception("Not null DataArrayInt instance expected !"); + da2->checkAllocated(); + int size=self->getNumberOfTuples(); + if(size!=self->getNumberOfTuples()) + { + throw INTERP_KERNEL::Exception("Invalid list length ! Must be equal to number of tuples !"); + } + return self->renumberAndReduce(da2->getConstPointer(),newNbOfTuple); + } + } + + DataArrayInt *renumber(PyObject *li) throw(INTERP_KERNEL::Exception) + { + void *da=0; + int res1=SWIG_ConvertPtr(li,&da,SWIGTYPE_p_ParaMEDMEM__DataArrayInt, 0 | 0 ); + if (!SWIG_IsOK(res1)) + { + int size; + INTERP_KERNEL::AutoPtr<int> tmp=convertPyToNewIntArr2(li,&size); + if(size!=self->getNumberOfTuples()) + { + throw INTERP_KERNEL::Exception("Invalid list length ! Must be equal to number of tuples !"); + } + return self->renumber(tmp); + } + else + { + DataArrayInt *da2=reinterpret_cast< DataArrayInt * >(da); + if(!da2) + throw INTERP_KERNEL::Exception("Not null DataArrayInt instance expected !"); + da2->checkAllocated(); + int size=self->getNumberOfTuples(); + if(size!=self->getNumberOfTuples()) + { + throw INTERP_KERNEL::Exception("Invalid list length ! Must be equal to number of tuples !"); + } + return self->renumber(da2->getConstPointer()); + } + } + + DataArrayInt *renumberR(PyObject *li) throw(INTERP_KERNEL::Exception) + { + void *da=0; + int res1=SWIG_ConvertPtr(li,&da,SWIGTYPE_p_ParaMEDMEM__DataArrayInt, 0 | 0 ); + if (!SWIG_IsOK(res1)) + { + int size; + INTERP_KERNEL::AutoPtr<int> tmp=convertPyToNewIntArr2(li,&size); + if(size!=self->getNumberOfTuples()) + { + throw INTERP_KERNEL::Exception("Invalid list length ! Must be equal to number of tuples !"); + } + return self->renumberR(tmp); + } + else + { + DataArrayInt *da2=reinterpret_cast< DataArrayInt * >(da); + if(!da2) + throw INTERP_KERNEL::Exception("Not null DataArrayInt instance expected !"); + da2->checkAllocated(); + int size=self->getNumberOfTuples(); + if(size!=self->getNumberOfTuples()) + { + throw INTERP_KERNEL::Exception("Invalid list length ! Must be equal to number of tuples !"); + } + return self->renumberR(da2->getConstPointer()); + } + } + + void setSelectedComponents(const DataArrayInt *a, PyObject *li) throw(INTERP_KERNEL::Exception) + { + std::vector<int> tmp; + convertPyToNewIntArr3(li,tmp); + self->setSelectedComponents(a,tmp); + } + + PyObject *getTuple(int tupleId) throw(INTERP_KERNEL::Exception) + { + int sz=self->getNumberOfComponents(); + INTERP_KERNEL::AutoPtr<int> tmp=new int[sz]; + self->getTuple(tupleId,tmp); + return convertIntArrToPyList(tmp,sz); + } + + PyObject *changeSurjectiveFormat(int targetNb) const throw(INTERP_KERNEL::Exception) + { + DataArrayInt *arr=0; + DataArrayInt *arrI=0; + self->changeSurjectiveFormat(targetNb,arr,arrI); + PyObject *res = PyList_New(2); + PyList_SetItem(res,0,SWIG_NewPointerObj((void*)arr,SWIGTYPE_p_ParaMEDMEM__DataArrayInt,SWIG_POINTER_OWN | 0)); + PyList_SetItem(res,1,SWIG_NewPointerObj((void*)arrI,SWIGTYPE_p_ParaMEDMEM__DataArrayInt,SWIG_POINTER_OWN | 0)); + return res; + } + + static DataArrayInt *Meld(PyObject *li) throw(INTERP_KERNEL::Exception) + { + std::vector<const DataArrayInt *> tmp; + convertFromPyObjVectorOfObj<const ParaMEDMEM::DataArrayInt *>(li,SWIGTYPE_p_ParaMEDMEM__DataArrayInt,"DataArrayInt",tmp); + return DataArrayInt::Meld(tmp); + } + + static DataArrayInt *Aggregate(PyObject *li) throw(INTERP_KERNEL::Exception) + { + std::vector<const DataArrayInt *> tmp; + convertFromPyObjVectorOfObj<const ParaMEDMEM::DataArrayInt *>(li,SWIGTYPE_p_ParaMEDMEM__DataArrayInt,"DataArrayInt",tmp); + return DataArrayInt::Aggregate(tmp); + } + + static DataArrayInt *AggregateIndexes(PyObject *li) throw(INTERP_KERNEL::Exception) + { + std::vector<const DataArrayInt *> tmp; + convertFromPyObjVectorOfObj<const ParaMEDMEM::DataArrayInt *>(li,SWIGTYPE_p_ParaMEDMEM__DataArrayInt,"DataArrayInt",tmp); + return DataArrayInt::AggregateIndexes(tmp); + } + + static DataArrayInt *BuildUnion(PyObject *li) throw(INTERP_KERNEL::Exception) + { + std::vector<const DataArrayInt *> tmp; + convertFromPyObjVectorOfObj<const ParaMEDMEM::DataArrayInt *>(li,SWIGTYPE_p_ParaMEDMEM__DataArrayInt,"DataArrayInt",tmp); + return DataArrayInt::BuildUnion(tmp); + } + + static DataArrayInt *BuildIntersection(PyObject *li) throw(INTERP_KERNEL::Exception) + { + std::vector<const DataArrayInt *> tmp; + convertFromPyObjVectorOfObj<const ParaMEDMEM::DataArrayInt *>(li,SWIGTYPE_p_ParaMEDMEM__DataArrayInt,"DataArrayInt",tmp); + return DataArrayInt::BuildIntersection(tmp); + } + + PyObject *getMaxValue() const throw(INTERP_KERNEL::Exception) + { + int tmp; + int r1=self->getMaxValue(tmp); + PyObject *ret=PyTuple_New(2); + PyTuple_SetItem(ret,0,PyInt_FromLong(r1)); + PyTuple_SetItem(ret,1,PyInt_FromLong(tmp)); + return ret; + } + + PyObject *getMinValue() const throw(INTERP_KERNEL::Exception) + { + int tmp; + int r1=self->getMinValue(tmp); + PyObject *ret=PyTuple_New(2); + PyTuple_SetItem(ret,0,PyInt_FromLong(r1)); + PyTuple_SetItem(ret,1,PyInt_FromLong(tmp)); + return ret; + } + + int index(PyObject *obj) const throw(INTERP_KERNEL::Exception) + { + int nbOfCompo=self->getNumberOfComponents(); + switch(nbOfCompo) + { + case 1: + { + if(PyInt_Check(obj)) + { + int val=(int)PyInt_AS_LONG(obj); + return self->locateValue(val); + } + else + throw INTERP_KERNEL::Exception("DataArrayInt::index : 'this' contains one component and trying to find an element which is not an integer !"); + } + default: + { + std::vector<int> arr; + convertPyToNewIntArr3(obj,arr); + return self->locateTuple(arr); + } + } + } + + bool __contains__(PyObject *obj) const throw(INTERP_KERNEL::Exception) + { + int nbOfCompo=self->getNumberOfComponents(); + switch(nbOfCompo) + { + case 0: + return false; + case 1: + { + if(PyInt_Check(obj)) + { + int val=(int)PyInt_AS_LONG(obj); + return self->presenceOfValue(val); + } + else + throw INTERP_KERNEL::Exception("DataArrayInt::__contains__ : 'this' contains one component and trying to find an element which is not an integer !"); + } + default: + { + std::vector<int> arr; + convertPyToNewIntArr3(obj,arr); + return self->presenceOfTuple(arr); + } + } + } + + PyObject *__getitem__(PyObject *obj) throw(INTERP_KERNEL::Exception) + { + const char msg[]="Unexpected situation in DataArrayInt::__getitem__ !"; + const char msg2[]="DataArrayInt::__getitem__ : Mismatch of slice values in 2nd parameter (components) !"; + self->checkAllocated(); + int nbOfTuples=self->getNumberOfTuples(); + int nbOfComponents=self->getNumberOfComponents(); + int it1,ic1; + std::vector<int> vt1,vc1; + std::pair<int, std::pair<int,int> > pt1,pc1; + DataArrayInt *dt1=0,*dc1=0; + int sw; + convertObjToPossibleCpp3(obj,nbOfTuples,nbOfComponents,sw,it1,ic1,vt1,vc1,pt1,pc1,dt1,dc1); + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret; + switch(sw) + { + case 1: + { + if(nbOfComponents==1) + return PyInt_FromLong(self->getIJSafe(it1,0)); + return SWIG_NewPointerObj(SWIG_as_voidptr(self->selectByTupleIdSafe(&it1,&it1+1)),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 ); + } + case 2: + return SWIG_NewPointerObj(SWIG_as_voidptr(self->selectByTupleIdSafe(&vt1[0],&vt1[0]+vt1.size())),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 ); + case 3: + return SWIG_NewPointerObj(SWIG_as_voidptr(self->selectByTupleId2(pt1.first,pt1.second.first,pt1.second.second)),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 ); + case 4: + return SWIG_NewPointerObj(SWIG_as_voidptr(self->selectByTupleIdSafe(dt1->getConstPointer(),dt1->getConstPointer()+dt1->getNbOfElems())),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 ); + case 5: + return PyInt_FromLong(self->getIJSafe(it1,ic1)); + case 6: + { + ret=self->selectByTupleIdSafe(&vt1[0],&vt1[0]+vt1.size()); + std::vector<int> v2(1,ic1); + return SWIG_NewPointerObj(SWIG_as_voidptr(ret->keepSelectedComponents(v2)),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 ); + } + case 7: + { + ret=self->selectByTupleId2(pt1.first,pt1.second.first,pt1.second.second); + std::vector<int> v2(1,ic1); + return SWIG_NewPointerObj(SWIG_as_voidptr(ret->keepSelectedComponents(v2)),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 ); + } + case 8: + { + ret=self->selectByTupleIdSafe(dt1->getConstPointer(),dt1->getConstPointer()+dt1->getNbOfElems()); + std::vector<int> v2(1,ic1); + return SWIG_NewPointerObj(SWIG_as_voidptr(ret->keepSelectedComponents(v2)),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 ); + } + case 9: + { + ret=self->selectByTupleIdSafe(&it1,&it1+1); + return SWIG_NewPointerObj(SWIG_as_voidptr(ret->keepSelectedComponents(vc1)),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 ); + } + case 10: + { + ret=self->selectByTupleIdSafe(&vt1[0],&vt1[0]+vt1.size()); + return SWIG_NewPointerObj(SWIG_as_voidptr(ret->keepSelectedComponents(vc1)),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 ); + } + case 11: + { + ret=self->selectByTupleId2(pt1.first,pt1.second.first,pt1.second.second); + return SWIG_NewPointerObj(SWIG_as_voidptr(ret->keepSelectedComponents(vc1)),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 ); + } + case 12: + { + ret=self->selectByTupleIdSafe(dt1->getConstPointer(),dt1->getConstPointer()+dt1->getNbOfElems()); + return SWIG_NewPointerObj(SWIG_as_voidptr(ret->keepSelectedComponents(vc1)),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 ); + } + case 13: + { + ret=self->selectByTupleIdSafe(&it1,&it1+1); + int nbOfComp=DataArray::GetNumberOfItemGivenBESRelative(pc1.first,pc1.second.first,pc1.second.second,msg2); + std::vector<int> v2(nbOfComp); + for(int i=0;i<nbOfComp;i++) + v2[i]=pc1.first+i*pc1.second.second; + return SWIG_NewPointerObj(SWIG_as_voidptr(ret->keepSelectedComponents(v2)),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 ); + } + case 14: + { + ret=self->selectByTupleIdSafe(&vt1[0],&vt1[0]+vt1.size()); + int nbOfComp=DataArray::GetNumberOfItemGivenBESRelative(pc1.first,pc1.second.first,pc1.second.second,msg2); + std::vector<int> v2(nbOfComp); + for(int i=0;i<nbOfComp;i++) + v2[i]=pc1.first+i*pc1.second.second; + return SWIG_NewPointerObj(SWIG_as_voidptr(ret->keepSelectedComponents(v2)),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 ); + } + case 15: + { + ret=self->selectByTupleId2(pt1.first,pt1.second.first,pt1.second.second); + int nbOfComp=DataArray::GetNumberOfItemGivenBESRelative(pc1.first,pc1.second.first,pc1.second.second,msg2); + std::vector<int> v2(nbOfComp); + for(int i=0;i<nbOfComp;i++) + v2[i]=pc1.first+i*pc1.second.second; + return SWIG_NewPointerObj(SWIG_as_voidptr(ret->keepSelectedComponents(v2)),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 ); + } + case 16: + { + ret=self->selectByTupleIdSafe(dt1->getConstPointer(),dt1->getConstPointer()+dt1->getNbOfElems()); + int nbOfComp=DataArray::GetNumberOfItemGivenBESRelative(pc1.first,pc1.second.first,pc1.second.second,msg2); + std::vector<int> v2(nbOfComp); + for(int i=0;i<nbOfComp;i++) + v2[i]=pc1.first+i*pc1.second.second; + return SWIG_NewPointerObj(SWIG_as_voidptr(ret->keepSelectedComponents(v2)),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 ); + } + default: + throw INTERP_KERNEL::Exception(msg); + } + } + + DataArrayInt *__setitem__(PyObject *obj, PyObject *value) throw(INTERP_KERNEL::Exception) + { + self->checkAllocated(); + const char msg[]="Unexpected situation in __setitem__ !"; + int nbOfTuples=self->getNumberOfTuples(); + int nbOfComponents=self->getNumberOfComponents(); + int sw1,sw2; + int i1; + std::vector<int> v1; + DataArrayInt *d1=0; + DataArrayIntTuple *dd1=0; + convertObjToPossibleCpp1(value,sw1,i1,v1,d1,dd1); + int it1,ic1; + std::vector<int> vt1,vc1; + std::pair<int, std::pair<int,int> > pt1,pc1; + DataArrayInt *dt1=0,*dc1=0; + convertObjToPossibleCpp3(obj,nbOfTuples,nbOfComponents,sw2,it1,ic1,vt1,vc1,pt1,pc1,dt1,dc1); + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> tmp; + switch(sw2) + { + case 1: + { + switch(sw1) + { + case 1: + self->setPartOfValuesSimple1(i1,it1,it1+1,1,0,nbOfComponents,1); + return self; + case 2: + tmp=DataArrayInt::New(); + tmp->useArray(&v1[0],false,CPP_DEALLOC,1,v1.size()); + self->setPartOfValues1(tmp,it1,it1+1,1,0,nbOfComponents,1,false); + return self; + case 3: + self->setPartOfValues1(d1,it1,it1+1,1,0,nbOfComponents,1); + return self; + case 4: + tmp=dd1->buildDAInt(1,self->getNumberOfComponents()); + self->setPartOfValues1(tmp,it1,it1+1,1,0,nbOfComponents,1); + return self; + default: + throw INTERP_KERNEL::Exception(msg); + } + break; + } + case 2: + { + switch(sw1) + { + case 1: + self->setPartOfValuesSimple3(i1,&vt1[0],&vt1[0]+vt1.size(),0,nbOfComponents,1); + return self; + case 2: + tmp=DataArrayInt::New(); + tmp->useArray(&v1[0],false,CPP_DEALLOC,1,v1.size()); + self->setPartOfValues3(tmp,&vt1[0],&vt1[0]+vt1.size(),0,nbOfComponents,1,false); + return self; + case 3: + self->setPartOfValues3(d1,&vt1[0],&vt1[0]+vt1.size(),0,nbOfComponents,1); + return self; + case 4: + tmp=dd1->buildDAInt(1,self->getNumberOfComponents()); + self->setPartOfValues3(tmp,&vt1[0],&vt1[0]+vt1.size(),0,nbOfComponents,1); + return self; + default: + throw INTERP_KERNEL::Exception(msg); + } + break; + } + case 3: + { + switch(sw1) + { + case 1: + self->setPartOfValuesSimple1(i1,pt1.first,pt1.second.first,pt1.second.second,0,nbOfComponents,1); + return self; + case 2: + tmp=DataArrayInt::New(); + tmp->useArray(&v1[0],false,CPP_DEALLOC,1,v1.size()); + self->setPartOfValues1(tmp,pt1.first,pt1.second.first,pt1.second.second,0,nbOfComponents,1,false); + return self; + case 3: + self->setPartOfValues1(d1,pt1.first,pt1.second.first,pt1.second.second,0,nbOfComponents,1); + return self; + case 4: + tmp=dd1->buildDAInt(1,self->getNumberOfComponents()); + self->setPartOfValues1(tmp,pt1.first,pt1.second.first,pt1.second.second,0,nbOfComponents,1); + return self; + default: + throw INTERP_KERNEL::Exception(msg); + } + break; + } + case 4: + { + switch(sw1) + { + case 1: + self->setPartOfValuesSimple3(i1,dt1->getConstPointer(),dt1->getConstPointer()+dt1->getNbOfElems(),0,nbOfComponents,1); + return self; + case 2: + tmp=DataArrayInt::New(); + tmp->useArray(&v1[0],false,CPP_DEALLOC,1,v1.size()); + self->setPartOfValues3(tmp,dt1->getConstPointer(),dt1->getConstPointer()+dt1->getNbOfElems(),0,nbOfComponents,1,false); + return self; + case 3: + self->setPartOfValues3(d1,dt1->getConstPointer(),dt1->getConstPointer()+dt1->getNbOfElems(),0,nbOfComponents,1); + return self; + case 4: + tmp=dd1->buildDAInt(1,self->getNumberOfComponents()); + self->setPartOfValues3(tmp,dt1->getConstPointer(),dt1->getConstPointer()+dt1->getNbOfElems(),0,nbOfComponents,1); + return self; + default: + throw INTERP_KERNEL::Exception(msg); + } + break; + } + case 5: + { + switch(sw1) + { + case 1: + self->setPartOfValuesSimple1(i1,it1,it1+1,1,ic1,ic1+1,1); + return self; + case 2: + tmp=DataArrayInt::New(); + tmp->useArray(&v1[0],false,CPP_DEALLOC,1,v1.size()); + self->setPartOfValues1(tmp,it1,it1+1,1,ic1,ic1+1,1,false); + return self; + case 3: + self->setPartOfValues1(d1,it1,it1+1,1,ic1,ic1+1,1); + return self; + case 4: + tmp=dd1->buildDAInt(1,self->getNumberOfComponents()); + self->setPartOfValues1(tmp,it1,it1+1,1,ic1,ic1+1,1); + return self; + default: + throw INTERP_KERNEL::Exception(msg); + } + break; + } + case 6: + { + switch(sw1) + { + case 1: + self->setPartOfValuesSimple3(i1,&vt1[0],&vt1[0]+vt1.size(),ic1,ic1+1,1); + return self; + case 2: + tmp=DataArrayInt::New(); + tmp->useArray(&v1[0],false,CPP_DEALLOC,1,v1.size()); + self->setPartOfValues3(tmp,&vt1[0],&vt1[0]+vt1.size(),ic1,ic1+1,1,false); + return self; + case 3: + self->setPartOfValues3(d1,&vt1[0],&vt1[0]+vt1.size(),ic1,ic1+1,1); + return self; + case 4: + tmp=dd1->buildDAInt(1,self->getNumberOfComponents()); + self->setPartOfValues3(tmp,&vt1[0],&vt1[0]+vt1.size(),ic1,ic1+1,1); + return self; + default: + throw INTERP_KERNEL::Exception(msg); + } + break; + } + case 7: + { + switch(sw1) + { + case 1: + self->setPartOfValuesSimple1(i1,pt1.first,pt1.second.first,pt1.second.second,ic1,ic1+1,1); + return self; + case 2: + tmp=DataArrayInt::New(); + tmp->useArray(&v1[0],false,CPP_DEALLOC,1,v1.size()); + self->setPartOfValues1(tmp,pt1.first,pt1.second.first,pt1.second.second,ic1,ic1+1,1,false); + return self; + case 3: + self->setPartOfValues1(d1,pt1.first,pt1.second.first,pt1.second.second,ic1,ic1+1,1); + return self; + case 4: + tmp=dd1->buildDAInt(1,self->getNumberOfComponents()); + self->setPartOfValues1(tmp,pt1.first,pt1.second.first,pt1.second.second,ic1,ic1+1,1); + return self; + default: + throw INTERP_KERNEL::Exception(msg); + } + break; + } + case 8: + { + switch(sw1) + { + case 1: + self->setPartOfValuesSimple3(i1,dt1->getConstPointer(),dt1->getConstPointer()+dt1->getNbOfElems(),ic1,ic1+1,1); + return self; + case 2: + tmp=DataArrayInt::New(); + tmp->useArray(&v1[0],false,CPP_DEALLOC,1,v1.size()); + self->setPartOfValues3(tmp,dt1->getConstPointer(),dt1->getConstPointer()+dt1->getNbOfElems(),ic1,ic1+1,1,false); + return self; + case 3: + self->setPartOfValues3(d1,dt1->getConstPointer(),dt1->getConstPointer()+dt1->getNbOfElems(),ic1,ic1+1,1); + return self; + case 4: + tmp=dd1->buildDAInt(1,self->getNumberOfComponents()); + self->setPartOfValues3(tmp,dt1->getConstPointer(),dt1->getConstPointer()+dt1->getNbOfElems(),ic1,ic1+1,1); + return self; + default: + throw INTERP_KERNEL::Exception(msg); + } + break; + } + case 9: + { + switch(sw1) + { + case 1: + self->setPartOfValuesSimple2(i1,&it1,&it1+1,&vc1[0],&vc1[0]+vc1.size()); + return self; + case 2: + tmp=DataArrayInt::New(); + tmp->useArray(&v1[0],false,CPP_DEALLOC,1,v1.size()); + self->setPartOfValues2(tmp,&it1,&it1+1,&vc1[0],&vc1[0]+vc1.size(),false); + return self; + case 3: + self->setPartOfValues2(d1,&it1,&it1+1,&vc1[0],&vc1[0]+vc1.size()); + return self; + case 4: + tmp=dd1->buildDAInt(1,self->getNumberOfComponents()); + self->setPartOfValues2(tmp,&it1,&it1+1,&vc1[0],&vc1[0]+vc1.size()); + return self; + default: + throw INTERP_KERNEL::Exception(msg); + } + break; + } + case 10: + { + switch(sw1) + { + case 1: + self->setPartOfValuesSimple2(i1,&vt1[0],&vt1[0]+vt1.size(),&vc1[0],&vc1[0]+vc1.size()); + return self; + case 2: + tmp=DataArrayInt::New(); + tmp->useArray(&v1[0],false,CPP_DEALLOC,1,v1.size()); + self->setPartOfValues2(tmp,&vt1[0],&vt1[0]+vt1.size(),&vc1[0],&vc1[0]+vc1.size(),false); + return self; + case 3: + self->setPartOfValues2(d1,&vt1[0],&vt1[0]+vt1.size(),&vc1[0],&vc1[0]+vc1.size()); + return self; + case 4: + tmp=dd1->buildDAInt(1,self->getNumberOfComponents()); + self->setPartOfValues2(tmp,&vt1[0],&vt1[0]+vt1.size(),&vc1[0],&vc1[0]+vc1.size()); + return self; + default: + throw INTERP_KERNEL::Exception(msg); + } + break; + } + case 11: + { + switch(sw1) + { + case 1: + self->setPartOfValuesSimple4(i1,pt1.first,pt1.second.first,pt1.second.second,&vc1[0],&vc1[0]+vc1.size()); + return self; + case 2: + tmp=DataArrayInt::New(); + tmp->useArray(&v1[0],false,CPP_DEALLOC,1,v1.size()); + self->setPartOfValues4(tmp,pt1.first,pt1.second.first,pt1.second.second,&vc1[0],&vc1[0]+vc1.size(),false); + return self; + case 3: + self->setPartOfValues4(d1,pt1.first,pt1.second.first,pt1.second.second,&vc1[0],&vc1[0]+vc1.size()); + return self; + case 4: + tmp=dd1->buildDAInt(1,self->getNumberOfComponents()); + self->setPartOfValues4(tmp,pt1.first,pt1.second.first,pt1.second.second,&vc1[0],&vc1[0]+vc1.size()); + return self; + default: + throw INTERP_KERNEL::Exception(msg); + } + break; + } + case 12: + { + switch(sw1) + { + case 1: + self->setPartOfValuesSimple2(i1,dt1->getConstPointer(),dt1->getConstPointer()+dt1->getNbOfElems(),&vc1[0],&vc1[0]+vc1.size()); + return self; + case 2: + tmp=DataArrayInt::New(); + tmp->useArray(&v1[0],false,CPP_DEALLOC,1,v1.size()); + self->setPartOfValues2(tmp,dt1->getConstPointer(),dt1->getConstPointer()+dt1->getNbOfElems(),&vc1[0],&vc1[0]+vc1.size(),false); + return self; + case 3: + self->setPartOfValues2(d1,dt1->getConstPointer(),dt1->getConstPointer()+dt1->getNbOfElems(),&vc1[0],&vc1[0]+vc1.size()); + return self; + case 4: + tmp=dd1->buildDAInt(1,self->getNumberOfComponents()); + self->setPartOfValues2(tmp,dt1->getConstPointer(),dt1->getConstPointer()+dt1->getNbOfElems(),&vc1[0],&vc1[0]+vc1.size()); + return self; + default: + throw INTERP_KERNEL::Exception(msg); + } + break; + } + case 13: + { + switch(sw1) + { + case 1: + self->setPartOfValuesSimple1(i1,it1,it1+1,1,pc1.first,pc1.second.first,pc1.second.second); + return self; + case 2: + tmp=DataArrayInt::New(); + tmp->useArray(&v1[0],false,CPP_DEALLOC,1,v1.size()); + self->setPartOfValues1(tmp,it1,it1+1,1,pc1.first,pc1.second.first,pc1.second.second,false); + return self; + case 3: + self->setPartOfValues1(d1,it1,it1+1,1,pc1.first,pc1.second.first,pc1.second.second); + return self; + case 4: + tmp=dd1->buildDAInt(1,self->getNumberOfComponents()); + self->setPartOfValues1(tmp,it1,it1+1,1,pc1.first,pc1.second.first,pc1.second.second); + return self; + default: + throw INTERP_KERNEL::Exception(msg); + } + break; + } + case 14: + { + switch(sw1) + { + case 1: + self->setPartOfValuesSimple3(i1,&vt1[0],&vt1[0]+vt1.size(),pc1.first,pc1.second.first,pc1.second.second); + return self; + case 2: + tmp=DataArrayInt::New(); + tmp->useArray(&v1[0],false,CPP_DEALLOC,1,v1.size()); + self->setPartOfValues3(tmp,&vt1[0],&vt1[0]+vt1.size(),pc1.first,pc1.second.first,pc1.second.second,false); + return self; + case 3: + self->setPartOfValues3(d1,&vt1[0],&vt1[0]+vt1.size(),pc1.first,pc1.second.first,pc1.second.second); + return self; + case 4: + tmp=dd1->buildDAInt(1,self->getNumberOfComponents()); + self->setPartOfValues3(tmp,&vt1[0],&vt1[0]+vt1.size(),pc1.first,pc1.second.first,pc1.second.second); + return self; + default: + throw INTERP_KERNEL::Exception(msg); + } + break; + } + case 15: + { + switch(sw1) + { + case 1: + self->setPartOfValuesSimple1(i1,pt1.first,pt1.second.first,pt1.second.second,pc1.first,pc1.second.first,pc1.second.second); + return self; + case 2: + tmp=DataArrayInt::New(); + tmp->useArray(&v1[0],false,CPP_DEALLOC,1,v1.size()); + self->setPartOfValues1(tmp,pt1.first,pt1.second.first,pt1.second.second,pc1.first,pc1.second.first,pc1.second.second,false); + return self; + case 3: + self->setPartOfValues1(d1,pt1.first,pt1.second.first,pt1.second.second,pc1.first,pc1.second.first,pc1.second.second); + return self; + case 4: + tmp=dd1->buildDAInt(1,self->getNumberOfComponents()); + self->setPartOfValues1(tmp,pt1.first,pt1.second.first,pt1.second.second,pc1.first,pc1.second.first,pc1.second.second); + return self; + default: + throw INTERP_KERNEL::Exception(msg); + } + break; + } + case 16: + { + switch(sw1) + { + case 1: + self->setPartOfValuesSimple3(i1,dt1->getConstPointer(),dt1->getConstPointer()+dt1->getNbOfElems(),pc1.first,pc1.second.first,pc1.second.second); + return self; + case 2: + tmp=DataArrayInt::New(); + tmp->useArray(&v1[0],false,CPP_DEALLOC,1,v1.size()); + self->setPartOfValues3(tmp,dt1->getConstPointer(),dt1->getConstPointer()+dt1->getNbOfElems(),pc1.first,pc1.second.first,pc1.second.second,false); + return self; + case 3: + self->setPartOfValues3(d1,dt1->getConstPointer(),dt1->getConstPointer()+dt1->getNbOfElems(),pc1.first,pc1.second.first,pc1.second.second); + return self; + case 4: + tmp=dd1->buildDAInt(1,self->getNumberOfComponents()); + self->setPartOfValues3(tmp,dt1->getConstPointer(),dt1->getConstPointer()+dt1->getNbOfElems(),pc1.first,pc1.second.first,pc1.second.second); + return self; + default: + throw INTERP_KERNEL::Exception(msg); + } + break; + } + default: + throw INTERP_KERNEL::Exception(msg); + } + return self; + } + + DataArrayInt *__neg__() const throw(INTERP_KERNEL::Exception) + { + return self->negate(); + } + + DataArrayInt *__add__(PyObject *obj) throw(INTERP_KERNEL::Exception) + { + const char msg[]="Unexpected situation in __add__ !"; + int val; + DataArrayInt *a; + std::vector<int> aa; + DataArrayIntTuple *aaa; + int sw; + convertObjToPossibleCpp1(obj,sw,val,aa,a,aaa); + switch(sw) + { + case 1: + { + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=self->deepCpy(); + ret->applyLin(1,val); + return ret.retn(); + } + case 2: + { + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> aaaa=DataArrayInt::New(); aaaa->useArray(&aa[0],false,CPP_DEALLOC,1,(int)aa.size()); + return DataArrayInt::Add(self,aaaa); + } + case 3: + { + return DataArrayInt::Add(self,a); + } + case 4: + { + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> aaaa=aaa->buildDAInt(1,self->getNumberOfComponents()); + return DataArrayInt::Add(self,aaaa); + } + default: + throw INTERP_KERNEL::Exception(msg); + } + } + + DataArrayInt *__radd__(PyObject *obj) throw(INTERP_KERNEL::Exception) + { + const char msg[]="Unexpected situation in __radd__ !"; + int val; + DataArrayInt *a; + std::vector<int> aa; + DataArrayIntTuple *aaa; + int sw; + convertObjToPossibleCpp1(obj,sw,val,aa,a,aaa); + switch(sw) + { + case 1: + { + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=self->deepCpy(); + ret->applyLin(1,val); + return ret.retn(); + } + case 2: + { + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> aaaa=DataArrayInt::New(); aaaa->useArray(&aa[0],false,CPP_DEALLOC,1,(int)aa.size()); + return DataArrayInt::Add(self,aaaa); + } + case 4: + { + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> aaaa=aaa->buildDAInt(1,self->getNumberOfComponents()); + return DataArrayInt::Add(self,aaaa); + } + default: + throw INTERP_KERNEL::Exception(msg); + } + } + + PyObject *___iadd___(PyObject *trueSelf, PyObject *obj) throw(INTERP_KERNEL::Exception) + { + const char msg[]="Unexpected situation in __iadd__ !"; + int val; + DataArrayInt *a; + std::vector<int> aa; + DataArrayIntTuple *aaa; + int sw; + convertObjToPossibleCpp1(obj,sw,val,aa,a,aaa); + switch(sw) + { + case 1: + { + self->applyLin(1,val); + Py_XINCREF(trueSelf); + return trueSelf; + } + case 2: + { + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> bb=DataArrayInt::New(); bb->useArray(&aa[0],false,CPP_DEALLOC,1,(int)aa.size()); + self->addEqual(bb); + Py_XINCREF(trueSelf); + return trueSelf; + } + case 3: + { + self->addEqual(a); + Py_XINCREF(trueSelf); + return trueSelf; + } + case 4: + { + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> aaaa=aaa->buildDAInt(1,self->getNumberOfComponents()); + self->addEqual(aaaa); + Py_XINCREF(trueSelf); + return trueSelf; + } + default: + throw INTERP_KERNEL::Exception(msg); + } + } + + DataArrayInt *__sub__(PyObject *obj) throw(INTERP_KERNEL::Exception) + { + const char msg[]="Unexpected situation in __sub__ !"; + int val; + DataArrayInt *a; + std::vector<int> aa; + DataArrayIntTuple *aaa; + int sw; + convertObjToPossibleCpp1(obj,sw,val,aa,a,aaa); + switch(sw) + { + case 1: + { + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=self->deepCpy(); + ret->applyLin(1,-val); + return ret.retn(); + } + case 2: + { + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> aaaa=DataArrayInt::New(); aaaa->useArray(&aa[0],false,CPP_DEALLOC,1,(int)aa.size()); + return DataArrayInt::Substract(self,aaaa); + } + case 3: + { + return DataArrayInt::Substract(self,a); + } + case 4: + { + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> aaaa=aaa->buildDAInt(1,self->getNumberOfComponents()); + return DataArrayInt::Substract(self,aaaa); + } + default: + throw INTERP_KERNEL::Exception(msg); + } + } + + DataArrayInt *__rsub__(PyObject *obj) throw(INTERP_KERNEL::Exception) + { + const char msg[]="Unexpected situation in __rsub__ !"; + int val; + DataArrayInt *a; + std::vector<int> aa; + DataArrayIntTuple *aaa; + int sw; + convertObjToPossibleCpp1(obj,sw,val,aa,a,aaa); + switch(sw) + { + case 1: + { + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=self->deepCpy(); + ret->applyLin(-1,val); + return ret.retn(); + } + case 2: + { + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> aaaa=DataArrayInt::New(); aaaa->useArray(&aa[0],false,CPP_DEALLOC,1,(int)aa.size()); + return DataArrayInt::Substract(aaaa,self); + } + case 4: + { + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> aaaa=aaa->buildDAInt(1,self->getNumberOfComponents()); + return DataArrayInt::Substract(aaaa,self); + } + default: + throw INTERP_KERNEL::Exception(msg); + } + } + + PyObject *___isub___(PyObject *trueSelf, PyObject *obj) throw(INTERP_KERNEL::Exception) + { + const char msg[]="Unexpected situation in __isub__ !"; + int val; + DataArrayInt *a; + std::vector<int> aa; + DataArrayIntTuple *aaa; + int sw; + convertObjToPossibleCpp1(obj,sw,val,aa,a,aaa); + switch(sw) + { + case 1: + { + self->applyLin(1,-val); + Py_XINCREF(trueSelf); + return trueSelf; + } + case 2: + { + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> bb=DataArrayInt::New(); bb->useArray(&aa[0],false,CPP_DEALLOC,1,(int)aa.size()); + self->substractEqual(bb); + Py_XINCREF(trueSelf); + return trueSelf; + } + case 3: + { + self->substractEqual(a); + Py_XINCREF(trueSelf); + return trueSelf; + } + case 4: + { + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> aaaa=aaa->buildDAInt(1,self->getNumberOfComponents()); + self->substractEqual(aaaa); + Py_XINCREF(trueSelf); + return trueSelf; + } + default: + throw INTERP_KERNEL::Exception(msg); + } + } + + DataArrayInt *__mul__(PyObject *obj) throw(INTERP_KERNEL::Exception) + { + const char msg[]="Unexpected situation in __mul__ !"; + int val; + DataArrayInt *a; + std::vector<int> aa; + DataArrayIntTuple *aaa; + int sw; + convertObjToPossibleCpp1(obj,sw,val,aa,a,aaa); + switch(sw) + { + case 1: + { + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=self->deepCpy(); + ret->applyLin(val,0); + return ret.retn(); + } + case 2: + { + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> aaaa=DataArrayInt::New(); aaaa->useArray(&aa[0],false,CPP_DEALLOC,1,(int)aa.size()); + return DataArrayInt::Multiply(self,aaaa); + } + case 3: + { + return DataArrayInt::Multiply(self,a); + } + case 4: + { + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> aaaa=aaa->buildDAInt(1,self->getNumberOfComponents()); + return DataArrayInt::Multiply(self,aaaa); + } + default: + throw INTERP_KERNEL::Exception(msg); + } + } + + DataArrayInt *__rmul__(PyObject *obj) throw(INTERP_KERNEL::Exception) + { + const char msg[]="Unexpected situation in __rmul__ !"; + int val; + DataArrayInt *a; + std::vector<int> aa; + DataArrayIntTuple *aaa; + int sw; + convertObjToPossibleCpp1(obj,sw,val,aa,a,aaa); + switch(sw) + { + case 1: + { + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=self->deepCpy(); + ret->applyLin(val,0); + return ret.retn(); + } + case 2: + { + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> aaaa=DataArrayInt::New(); aaaa->useArray(&aa[0],false,CPP_DEALLOC,1,(int)aa.size()); + return DataArrayInt::Multiply(self,aaaa); + } + case 4: + { + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> aaaa=aaa->buildDAInt(1,self->getNumberOfComponents()); + return DataArrayInt::Multiply(self,aaaa); + } + default: + throw INTERP_KERNEL::Exception(msg); + } + } + + PyObject *___imul___(PyObject *trueSelf, PyObject *obj) throw(INTERP_KERNEL::Exception) + { + const char msg[]="Unexpected situation in __imul__ !"; + int val; + DataArrayInt *a; + std::vector<int> aa; + DataArrayIntTuple *aaa; + int sw; + convertObjToPossibleCpp1(obj,sw,val,aa,a,aaa); + switch(sw) + { + case 1: + { + self->applyLin(val,0); + Py_XINCREF(trueSelf); + return trueSelf; + } + case 2: + { + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> bb=DataArrayInt::New(); bb->useArray(&aa[0],false,CPP_DEALLOC,1,(int)aa.size()); + self->multiplyEqual(bb); + Py_XINCREF(trueSelf); + return trueSelf; + } + case 3: + { + self->multiplyEqual(a); + Py_XINCREF(trueSelf); + return trueSelf; + } + case 4: + { + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> aaaa=aaa->buildDAInt(1,self->getNumberOfComponents()); + self->multiplyEqual(aaaa); + Py_XINCREF(trueSelf); + return trueSelf; + } + default: + throw INTERP_KERNEL::Exception(msg); + } + } + + DataArrayInt *__div__(PyObject *obj) throw(INTERP_KERNEL::Exception) + { + const char msg[]="Unexpected situation in __div__ !"; + int val; + DataArrayInt *a; + std::vector<int> aa; + DataArrayIntTuple *aaa; + int sw; + convertObjToPossibleCpp1(obj,sw,val,aa,a,aaa); + switch(sw) + { + case 1: + { + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=self->deepCpy(); + ret->applyDivideBy(val); + return ret.retn(); + } + case 2: + { + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> aaaa=DataArrayInt::New(); aaaa->useArray(&aa[0],false,CPP_DEALLOC,1,(int)aa.size()); + return DataArrayInt::Divide(self,aaaa); + } + case 3: + { + return DataArrayInt::Divide(self,a); + } + case 4: + { + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> aaaa=aaa->buildDAInt(1,self->getNumberOfComponents()); + return DataArrayInt::Divide(self,aaaa); + } + default: + throw INTERP_KERNEL::Exception(msg); + } + } + + DataArrayInt *__rdiv__(PyObject *obj) throw(INTERP_KERNEL::Exception) + { + const char msg[]="Unexpected situation in __rdiv__ !"; + int val; + DataArrayInt *a; + std::vector<int> aa; + DataArrayIntTuple *aaa; + int sw; + convertObjToPossibleCpp1(obj,sw,val,aa,a,aaa); + switch(sw) + { + case 1: + { + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=self->deepCpy(); + ret->applyInv(val); + return ret.retn(); + } + case 2: + { + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> aaaa=DataArrayInt::New(); aaaa->useArray(&aa[0],false,CPP_DEALLOC,1,(int)aa.size()); + return DataArrayInt::Divide(aaaa,self); + } + case 4: + { + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> aaaa=aaa->buildDAInt(1,self->getNumberOfComponents()); + return DataArrayInt::Divide(aaaa,self); + } + default: + throw INTERP_KERNEL::Exception(msg); + } + } + + PyObject *___idiv___(PyObject *trueSelf, PyObject *obj) throw(INTERP_KERNEL::Exception) + { + const char msg[]="Unexpected situation in __idiv__ !"; + int val; + DataArrayInt *a; + std::vector<int> aa; + DataArrayIntTuple *aaa; + int sw; + convertObjToPossibleCpp1(obj,sw,val,aa,a,aaa); + switch(sw) + { + case 1: + { + self->applyDivideBy(val); + Py_XINCREF(trueSelf); + return trueSelf; + } + case 2: + { + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> bb=DataArrayInt::New(); bb->useArray(&aa[0],false,CPP_DEALLOC,1,(int)aa.size()); + self->divideEqual(bb); + Py_XINCREF(trueSelf); + return trueSelf; + } + case 3: + { + self->divideEqual(a); + Py_XINCREF(trueSelf); + return trueSelf; + } + case 4: + { + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> aaaa=aaa->buildDAInt(1,self->getNumberOfComponents()); + self->divideEqual(aaaa); + Py_XINCREF(trueSelf); + return trueSelf; + } + default: + throw INTERP_KERNEL::Exception(msg); + } + } + + DataArrayInt *__mod__(PyObject *obj) throw(INTERP_KERNEL::Exception) + { + const char msg[]="Unexpected situation in __mod__ !"; + int val; + DataArrayInt *a; + std::vector<int> aa; + DataArrayIntTuple *aaa; + int sw; + convertObjToPossibleCpp1(obj,sw,val,aa,a,aaa); + switch(sw) + { + case 1: + { + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=self->deepCpy(); + ret->applyModulus(val); + return ret.retn(); + } + case 2: + { + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> aaaa=DataArrayInt::New(); aaaa->useArray(&aa[0],false,CPP_DEALLOC,1,(int)aa.size()); + return DataArrayInt::Modulus(self,aaaa); + } + case 3: + { + return DataArrayInt::Modulus(self,a); + } + case 4: + { + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> aaaa=aaa->buildDAInt(1,self->getNumberOfComponents()); + return DataArrayInt::Modulus(self,aaaa); + } + default: + throw INTERP_KERNEL::Exception(msg); + } + } + + DataArrayInt *__rmod__(PyObject *obj) throw(INTERP_KERNEL::Exception) + { + const char msg[]="Unexpected situation in __rmod__ !"; + int val; + DataArrayInt *a; + std::vector<int> aa; + DataArrayIntTuple *aaa; + int sw; + convertObjToPossibleCpp1(obj,sw,val,aa,a,aaa); + switch(sw) + { + case 1: + { + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=self->deepCpy(); + ret->applyRModulus(val); + return ret.retn(); + } + case 2: + { + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> aaaa=DataArrayInt::New(); aaaa->useArray(&aa[0],false,CPP_DEALLOC,1,(int)aa.size()); + return DataArrayInt::Modulus(aaaa,self); + } + case 3: + { + return DataArrayInt::Modulus(a,self); + } + case 4: + { + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> aaaa=aaa->buildDAInt(1,self->getNumberOfComponents()); + return DataArrayInt::Modulus(aaaa,self); + } + default: + throw INTERP_KERNEL::Exception(msg); + } + } + + PyObject *___imod___(PyObject *trueSelf, PyObject *obj) throw(INTERP_KERNEL::Exception) + { + const char msg[]="Unexpected situation in __imod__ !"; + int val; + DataArrayInt *a; + std::vector<int> aa; + DataArrayIntTuple *aaa; + int sw; + convertObjToPossibleCpp1(obj,sw,val,aa,a,aaa); + switch(sw) + { + case 1: + { + self->applyModulus(val); + Py_XINCREF(trueSelf); + return trueSelf; + } + case 3: + { + self->modulusEqual(a); + Py_XINCREF(trueSelf); + return trueSelf; + } + case 4: + { + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> aaaa=aaa->buildDAInt(1,self->getNumberOfComponents()); + self->modulusEqual(aaaa); + Py_XINCREF(trueSelf); + return trueSelf; + } + default: + throw INTERP_KERNEL::Exception(msg); + } + } + + DataArrayInt *__pow__(PyObject *obj) throw(INTERP_KERNEL::Exception) + { + const char msg[]="Unexpected situation in __pow__ !"; + int val; + DataArrayInt *a; + std::vector<int> aa; + DataArrayIntTuple *aaa; + int sw; + convertObjToPossibleCpp1(obj,sw,val,aa,a,aaa); + switch(sw) + { + case 1: + { + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=self->deepCpy(); + ret->applyPow(val); + return ret.retn(); + } + case 2: + { + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> aaaa=DataArrayInt::New(); aaaa->useArray(&aa[0],false,CPP_DEALLOC,1,(int)aa.size()); + return DataArrayInt::Pow(self,aaaa); + } + case 3: + { + return DataArrayInt::Pow(self,a); + } + case 4: + { + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> aaaa=aaa->buildDAInt(1,self->getNumberOfComponents()); + return DataArrayInt::Pow(self,aaaa); + } + default: + throw INTERP_KERNEL::Exception(msg); + } + } + + DataArrayInt *__rpow__(PyObject *obj) throw(INTERP_KERNEL::Exception) + { + const char msg[]="Unexpected situation in __rpow__ !"; + int val; + DataArrayInt *a; + std::vector<int> aa; + DataArrayIntTuple *aaa; + int sw; + convertObjToPossibleCpp1(obj,sw,val,aa,a,aaa); + switch(sw) + { + case 1: + { + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=self->deepCpy(); + ret->applyRPow(val); + return ret.retn(); + } + case 2: + { + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> aaaa=DataArrayInt::New(); aaaa->useArray(&aa[0],false,CPP_DEALLOC,1,(int)aa.size()); + return DataArrayInt::Pow(aaaa,self); + } + case 3: + { + return DataArrayInt::Pow(a,self); + } + case 4: + { + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> aaaa=aaa->buildDAInt(1,self->getNumberOfComponents()); + return DataArrayInt::Pow(aaaa,self); + } + default: + throw INTERP_KERNEL::Exception(msg); + } + } + + PyObject *___ipow___(PyObject *trueSelf, PyObject *obj) throw(INTERP_KERNEL::Exception) + { + const char msg[]="Unexpected situation in __ipow__ !"; + int val; + DataArrayInt *a; + std::vector<int> aa; + DataArrayIntTuple *aaa; + int sw; + convertObjToPossibleCpp1(obj,sw,val,aa,a,aaa); + switch(sw) + { + case 1: + { + self->applyPow(val); + Py_XINCREF(trueSelf); + return trueSelf; + } + case 3: + { + self->powEqual(a); + Py_XINCREF(trueSelf); + return trueSelf; + } + case 4: + { + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> aaaa=aaa->buildDAInt(1,self->getNumberOfComponents()); + self->powEqual(aaaa); + Py_XINCREF(trueSelf); + return trueSelf; + } + default: + throw INTERP_KERNEL::Exception(msg); + } + } + + std::string __repr__() const throw(INTERP_KERNEL::Exception) + { + std::ostringstream oss; + self->reprQuickOverview(oss); + return oss.str(); + } + + void pushBackValsSilent(PyObject *li) throw(INTERP_KERNEL::Exception) + { + int szArr,sw,iTypppArr; + std::vector<int> stdvecTyyppArr; + const int *tmp=convertObjToPossibleCpp1_Safe(li,sw,szArr,iTypppArr,stdvecTyyppArr); + self->pushBackValsSilent(tmp,tmp+szArr); + } + + PyObject *partitionByDifferentValues() const throw(INTERP_KERNEL::Exception) + { + std::vector<int> ret1; + std::vector<DataArrayInt *> ret0=self->partitionByDifferentValues(ret1); + std::size_t sz=ret0.size(); + PyObject *pyRet=PyTuple_New(2); + PyObject *pyRet0=PyList_New((int)sz); + PyObject *pyRet1=PyList_New((int)sz); + for(std::size_t i=0;i<sz;i++) + { + PyList_SetItem(pyRet0,i,SWIG_NewPointerObj(SWIG_as_voidptr(ret0[i]),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 )); + PyList_SetItem(pyRet1,i,PyInt_FromLong(ret1[i])); + } + PyTuple_SetItem(pyRet,0,pyRet0); + PyTuple_SetItem(pyRet,1,pyRet1); + return pyRet; + } + + PyObject *searchRangesInListOfIds(const DataArrayInt *listOfIds) const throw(INTERP_KERNEL::Exception) + { + DataArrayInt *ret0=0,*ret1=0; + self->searchRangesInListOfIds(listOfIds,ret0,ret1); + PyObject *pyRet=PyTuple_New(2); + PyTuple_SetItem(pyRet,0,SWIG_NewPointerObj(SWIG_as_voidptr(ret0),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 )); + PyTuple_SetItem(pyRet,1,SWIG_NewPointerObj(SWIG_as_voidptr(ret1),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 )); + return pyRet; + } + + PyObject *isRange() const throw(INTERP_KERNEL::Exception) + { + int a(0),b(0),c(0); + bool ret(self->isRange(a,b,c)); + PyObject *pyRet=PyTuple_New(2); + PyObject *ret0Py=ret?Py_True:Py_False,*ret1Py(0); + Py_XINCREF(ret0Py); + PyTuple_SetItem(pyRet,0,ret0Py); + if(ret) + ret1Py=PySlice_New(PyInt_FromLong(a),PyInt_FromLong(b),PyInt_FromLong(c)); + else + { + ret1Py=Py_None; + Py_XINCREF(ret1Py); + } + PyTuple_SetItem(pyRet,1,ret1Py); + return pyRet; + } + + // serialization + static PyObject *___new___(PyObject *cls, PyObject *args) throw(INTERP_KERNEL::Exception) + { + static const char MSG[]="DataArrayInt.__new__ : the args in input is expected to be a tuple !"; + if(!PyTuple_Check(args)) + throw INTERP_KERNEL::Exception(MSG); + PyObject *builtinsd(PyEval_GetBuiltins());//borrowed + PyObject *obj(PyDict_GetItemString(builtinsd,"object"));//borrowed + PyObject *selfMeth(PyObject_GetAttrString(obj,"__new__")); + // + PyObject *tmp0(PyTuple_New(1)); + PyTuple_SetItem(tmp0,0,cls); Py_XINCREF(cls); + PyObject *instance(PyObject_CallObject(selfMeth,tmp0)); + Py_DECREF(tmp0); + Py_DECREF(selfMeth); + PyObject *initMeth(PyObject_GetAttrString(instance,"__init__")); + int sz(PyTuple_Size(args)); + + if(PyTuple_Size(args)==2 && PyDict_Check(PyTuple_GetItem(args,1)) && PyDict_Size(PyTuple_GetItem(args,1))==1 ) + {// NOT general case. only true if in unpickeling context ! call __init__. Because for all other cases, __init__ is called right after __new__ ! + PyObject *zeNumpyRepr(0); + PyObject *tmp1(PyInt_FromLong(0)); + zeNumpyRepr=PyDict_GetItem(PyTuple_GetItem(args,1),tmp1);//borrowed + Py_DECREF(tmp1); + PyObject *tmp3(PyTuple_New(1)); + PyTuple_SetItem(tmp3,0,zeNumpyRepr); Py_XINCREF(zeNumpyRepr); + PyObject *tmp2(PyObject_CallObject(initMeth,tmp3)); + Py_XDECREF(tmp2); + Py_DECREF(tmp3); + } + Py_DECREF(initMeth); + return instance; + } + + PyObject *__getnewargs__() throw(INTERP_KERNEL::Exception) + { +#ifdef WITH_NUMPY + if(!self->isAllocated()) + throw INTERP_KERNEL::Exception("PyWrap of DataArrayInt.__getnewargs__ : self is not allocated !"); + PyObject *ret(PyTuple_New(1)); + PyObject *ret0(PyDict_New()); + PyObject *numpyArryObj(ParaMEDMEM_DataArrayInt_toNumPyArray(self)); + {// create a dict to discriminite in __new__ if __init__ should be called. Not beautiful but not idea ... + PyObject *tmp1(PyInt_FromLong(0)); + PyDict_SetItem(ret0,tmp1,numpyArryObj); Py_DECREF(tmp1); Py_DECREF(numpyArryObj); + PyTuple_SetItem(ret,0,ret0); + } + return ret; +#else + throw INTERP_KERNEL::Exception("PyWrap of DataArrayInt.__getnewargs__ : not implemented because numpy is not active in your configuration ! No serialization/unserialization available without numpy !"); +#endif + } + } + }; + + class DataArrayIntTuple; + + class DataArrayIntIterator + { + public: + DataArrayIntIterator(DataArrayInt *da); + ~DataArrayIntIterator(); + %extend + { + PyObject *next() + { + DataArrayIntTuple *ret=self->nextt(); + if(ret) + return SWIG_NewPointerObj(SWIG_as_voidptr(ret),SWIGTYPE_p_ParaMEDMEM__DataArrayIntTuple,SWIG_POINTER_OWN | 0); + else + { + PyErr_SetString(PyExc_StopIteration,"No more data."); + return 0; + } + } + } + }; + + class DataArrayIntTuple + { + public: + int getNumberOfCompo() const throw(INTERP_KERNEL::Exception); + DataArrayInt *buildDAInt(int nbOfTuples, int nbOfCompo) const throw(INTERP_KERNEL::Exception); + %extend + { + std::string __str__() const throw(INTERP_KERNEL::Exception) + { + return self->repr(); + } + + int __int__() const throw(INTERP_KERNEL::Exception) + { + return self->intValue(); + } + + DataArrayInt *buildDAInt() throw(INTERP_KERNEL::Exception) + { + return self->buildDAInt(1,self->getNumberOfCompo()); + } + + PyObject *___iadd___(PyObject *trueSelf, PyObject *obj) throw(INTERP_KERNEL::Exception) + { + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=self->buildDAInt(1,self->getNumberOfCompo()); + ParaMEDMEM_DataArrayInt____iadd___(ret,0,obj); + Py_XINCREF(trueSelf); + return trueSelf; + } + + PyObject *___isub___(PyObject *trueSelf, PyObject *obj) throw(INTERP_KERNEL::Exception) + { + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=self->buildDAInt(1,self->getNumberOfCompo()); + ParaMEDMEM_DataArrayInt____isub___(ret,0,obj); + Py_XINCREF(trueSelf); + return trueSelf; + } + + PyObject *___imul___(PyObject *trueSelf, PyObject *obj) throw(INTERP_KERNEL::Exception) + { + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=self->buildDAInt(1,self->getNumberOfCompo()); + ParaMEDMEM_DataArrayInt____imul___(ret,0,obj); + Py_XINCREF(trueSelf); + return trueSelf; + } + + PyObject *___idiv___(PyObject *trueSelf, PyObject *obj) throw(INTERP_KERNEL::Exception) + { + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=self->buildDAInt(1,self->getNumberOfCompo()); + ParaMEDMEM_DataArrayInt____idiv___(ret,0,obj); + Py_XINCREF(trueSelf); + return trueSelf; + } + + PyObject *___imod___(PyObject *trueSelf, PyObject *obj) throw(INTERP_KERNEL::Exception) + { + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=self->buildDAInt(1,self->getNumberOfCompo()); + ParaMEDMEM_DataArrayInt____imod___(ret,0,obj); + Py_XINCREF(trueSelf); + return trueSelf; + } + + PyObject *__len__() throw(INTERP_KERNEL::Exception) + { + return PyInt_FromLong(self->getNumberOfCompo()); + } + + PyObject *__getitem__(PyObject *obj) throw(INTERP_KERNEL::Exception) + { + const char msg2[]="DataArrayIntTuple::__getitem__ : Mismatch of slice values in 2nd parameter (components) !"; + int sw; + int singleVal; + std::vector<int> multiVal; + std::pair<int, std::pair<int,int> > slic; + ParaMEDMEM::DataArrayInt *daIntTyypp=0; + const int *pt=self->getConstPointer(); + int nbc=self->getNumberOfCompo(); + convertObjToPossibleCpp2WithNegIntInterp(obj,nbc,sw,singleVal,multiVal,slic,daIntTyypp); + switch(sw) + { + case 1: + { + if(singleVal>=nbc) + { + std::ostringstream oss; + oss << "Requesting for id " << singleVal << " having only " << nbc << " components !"; + PyErr_SetString(PyExc_StopIteration,oss.str().c_str()); + return 0; + } + if(singleVal>=0) + return PyInt_FromLong(pt[singleVal]); + else + { + if(nbc+singleVal>0) + return PyInt_FromLong(pt[nbc+singleVal]); + else + { + std::ostringstream oss; + oss << "Requesting for id " << singleVal << " having only " << nbc << " components !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + } + } + case 2: + { + PyObject *t=PyTuple_New(multiVal.size()); + for(int j=0;j<(int)multiVal.size();j++) + { + int cid=multiVal[j]; + if(cid>=nbc) + { + std::ostringstream oss; + oss << "Requesting for id #" << cid << " having only " << nbc << " components !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + PyTuple_SetItem(t,j,PyInt_FromLong(pt[cid])); + } + return t; + } + case 3: + { + int sz=DataArray::GetNumberOfItemGivenBES(slic.first,slic.second.first,slic.second.second,msg2); + PyObject *t=PyTuple_New(sz); + for(int j=0;j<sz;j++) + PyTuple_SetItem(t,j,PyInt_FromLong(pt[slic.first+j*slic.second.second])); + return t; + } + default: + throw INTERP_KERNEL::Exception("DataArrayIntTuple::__getitem__ : unrecognized type entered !"); + } + } + + DataArrayIntTuple *__setitem__(PyObject *obj, PyObject *value) throw(INTERP_KERNEL::Exception) + { + const char msg[]="DataArrayIntTuple::__setitem__ : unrecognized type entered, int, slice, list<int>, tuple<int> !"; + const char msg2[]="DataArrayIntTuple::__setitem__ : Mismatch of slice values in 2nd parameter (components) !"; + int sw1,sw2; + int singleValV; + std::vector<int> multiValV; + std::pair<int, std::pair<int,int> > slicV; + ParaMEDMEM::DataArrayIntTuple *daIntTyyppV=0; + int nbc=self->getNumberOfCompo(); + convertObjToPossibleCpp22(value,nbc,sw1,singleValV,multiValV,slicV,daIntTyyppV); + int singleVal; + std::vector<int> multiVal; + std::pair<int, std::pair<int,int> > slic; + ParaMEDMEM::DataArrayInt *daIntTyypp=0; + int *pt=self->getPointer(); + convertObjToPossibleCpp2WithNegIntInterp(obj,nbc,sw2,singleVal,multiVal,slic,daIntTyypp); + switch(sw2) + { + case 1: + { + if(singleVal>=nbc) + { + std::ostringstream oss; + oss << "Requesting for setting id # " << singleVal << " having only " << nbc << " components !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + switch(sw1) + { + case 1: + { + pt[singleVal]=singleValV; + return self; + } + case 2: + { + if(multiValV.size()!=1) + { + std::ostringstream oss; + oss << "Requesting for setting id # " << singleVal << " with a list or tuple with size != 1 ! "; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + pt[singleVal]=multiValV[0]; + return self; + } + case 4: + { + pt[singleVal]=daIntTyyppV->getConstPointer()[0]; + return self; + } + default: + throw INTERP_KERNEL::Exception(msg); + } + } + case 2: + { + switch(sw1) + { + case 1: + { + for(std::vector<int>::const_iterator it=multiVal.begin();it!=multiVal.end();it++) + { + if(*it>=nbc) + { + std::ostringstream oss; + oss << "Requesting for setting id # " << *it << " having only " << nbc << " components !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + pt[*it]=singleValV; + } + return self; + } + case 2: + { + if(multiVal.size()!=multiValV.size()) + { + std::ostringstream oss; + oss << "Mismatch length of during assignment : " << multiValV.size() << " != " << multiVal.size() << " !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + for(int i=0;i<(int)multiVal.size();i++) + { + int pos=multiVal[i]; + if(pos>=nbc) + { + std::ostringstream oss; + oss << "Requesting for setting id # " << pos << " having only " << nbc << " components !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + pt[multiVal[i]]=multiValV[i]; + } + return self; + } + case 4: + { + const int *ptV=daIntTyyppV->getConstPointer(); + if(nbc>daIntTyyppV->getNumberOfCompo()) + { + std::ostringstream oss; + oss << "Mismatch length of during assignment : " << nbc << " != " << daIntTyyppV->getNumberOfCompo() << " !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + std::copy(ptV,ptV+nbc,pt); + return self; + } + default: + throw INTERP_KERNEL::Exception(msg); + } + } + case 3: + { + int sz=DataArray::GetNumberOfItemGivenBES(slic.first,slic.second.first,slic.second.second,msg2); + switch(sw1) + { + case 1: + { + for(int j=0;j<sz;j++) + pt[slic.first+j*slic.second.second]=singleValV; + return self; + } + case 2: + { + if(sz!=(int)multiValV.size()) + { + std::ostringstream oss; + oss << "Mismatch length of during assignment : " << multiValV.size() << " != " << sz << " !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + for(int j=0;j<sz;j++) + pt[slic.first+j*slic.second.second]=multiValV[j]; + return self; + } + case 4: + { + const int *ptV=daIntTyyppV->getConstPointer(); + if(sz>daIntTyyppV->getNumberOfCompo()) + { + std::ostringstream oss; + oss << "Mismatch length of during assignment : " << nbc << " != " << daIntTyyppV->getNumberOfCompo() << " !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + for(int j=0;j<sz;j++) + pt[slic.first+j*slic.second.second]=ptV[j]; + return self; + } + default: + throw INTERP_KERNEL::Exception(msg); + } + } + default: + throw INTERP_KERNEL::Exception(msg); + } + } + } + }; + + class DataArrayChar : public DataArray + { + public: + virtual DataArrayChar *buildEmptySpecializedDAChar() const throw(INTERP_KERNEL::Exception); + int getHashCode() const throw(INTERP_KERNEL::Exception); + bool empty() const throw(INTERP_KERNEL::Exception); + void cpyFrom(const DataArrayChar& other) throw(INTERP_KERNEL::Exception); + void reserve(std::size_t nbOfElems) throw(INTERP_KERNEL::Exception); + void pushBackSilent(char val) throw(INTERP_KERNEL::Exception); + char popBackSilent() throw(INTERP_KERNEL::Exception); + void pack() const throw(INTERP_KERNEL::Exception); + void allocIfNecessary(int nbOfTuple, int nbOfCompo) throw(INTERP_KERNEL::Exception); + bool isEqual(const DataArrayChar& other) const throw(INTERP_KERNEL::Exception); + bool isEqualWithoutConsideringStr(const DataArrayChar& other) const throw(INTERP_KERNEL::Exception); + void reverse() throw(INTERP_KERNEL::Exception); + void fillWithZero() throw(INTERP_KERNEL::Exception); + void fillWithValue(char val) throw(INTERP_KERNEL::Exception); + std::string repr() const throw(INTERP_KERNEL::Exception); + std::string reprZip() const throw(INTERP_KERNEL::Exception); + DataArrayInt *convertToIntArr() const throw(INTERP_KERNEL::Exception); + DataArrayChar *renumber(const int *old2New) const throw(INTERP_KERNEL::Exception); + DataArrayChar *renumberR(const int *new2Old) const throw(INTERP_KERNEL::Exception); + DataArrayChar *renumberAndReduce(const int *old2NewBg, int newNbOfTuple) const throw(INTERP_KERNEL::Exception); + bool isUniform(char val) const throw(INTERP_KERNEL::Exception); + DataArrayChar *substr(int tupleIdBg, int tupleIdEnd=-1) const throw(INTERP_KERNEL::Exception); + DataArrayChar *changeNbOfComponents(int newNbOfComp, char dftValue) const throw(INTERP_KERNEL::Exception); + void meldWith(const DataArrayChar *other) throw(INTERP_KERNEL::Exception); + void setPartOfValuesAdv(const DataArrayChar *a, const DataArrayChar *tuplesSelec) throw(INTERP_KERNEL::Exception); + char front() const throw(INTERP_KERNEL::Exception); + char back() const throw(INTERP_KERNEL::Exception); + void setIJ(int tupleId, int compoId, char newVal) throw(INTERP_KERNEL::Exception); + void setIJSilent(int tupleId, int compoId, char newVal) throw(INTERP_KERNEL::Exception); + char *getPointer() throw(INTERP_KERNEL::Exception); + DataArrayInt *getIdsEqual(char val) const throw(INTERP_KERNEL::Exception); + DataArrayInt *getIdsNotEqual(char val) const throw(INTERP_KERNEL::Exception); + int locateTuple(const std::vector<char>& tupl) const throw(INTERP_KERNEL::Exception); + bool presenceOfTuple(const std::vector<char>& tupl) const throw(INTERP_KERNEL::Exception); + char getMaxValue(int& tupleId) const throw(INTERP_KERNEL::Exception); + char getMaxValueInArray() const throw(INTERP_KERNEL::Exception); + char getMinValue(int& tupleId) const throw(INTERP_KERNEL::Exception); + char getMinValueInArray() const throw(INTERP_KERNEL::Exception); + DataArrayInt *getIdsInRange(char vmin, char vmax) const throw(INTERP_KERNEL::Exception); + static DataArrayChar *Aggregate(const DataArrayChar *a1, const DataArrayChar *a2) throw(INTERP_KERNEL::Exception); + static DataArrayChar *Meld(const DataArrayChar *a1, const DataArrayChar *a2) throw(INTERP_KERNEL::Exception); + %extend + { + int __len__() const throw(INTERP_KERNEL::Exception) + { + if(self->isAllocated()) + { + return self->getNumberOfTuples(); + } + else + { + throw INTERP_KERNEL::Exception("DataArrayChar::__len__ : Instance is NOT allocated !"); + } + } + + PyObject *isEqualIfNotWhy(const DataArrayChar& other) const throw(INTERP_KERNEL::Exception) + { + std::string ret1; + bool ret0=self->isEqualIfNotWhy(other,ret1); + PyObject *ret=PyTuple_New(2); + PyObject *ret0Py=ret0?Py_True:Py_False; + Py_XINCREF(ret0Py); + PyTuple_SetItem(ret,0,ret0Py); + PyTuple_SetItem(ret,1,PyString_FromString(ret1.c_str())); + return ret; + } + + DataArrayChar *renumber(PyObject *li) throw(INTERP_KERNEL::Exception) + { + void *da=0; + int res1=SWIG_ConvertPtr(li,&da,SWIGTYPE_p_ParaMEDMEM__DataArrayInt, 0 | 0 ); + if (!SWIG_IsOK(res1)) + { + int size; + INTERP_KERNEL::AutoPtr<int> tmp=convertPyToNewIntArr2(li,&size); + if(size!=self->getNumberOfTuples()) + { + throw INTERP_KERNEL::Exception("Invalid list length ! Must be equal to number of tuples !"); + } + return self->renumber(tmp); + } + else + { + DataArrayInt *da2=reinterpret_cast< DataArrayInt * >(da); + if(!da2) + throw INTERP_KERNEL::Exception("Not null DataArrayInt instance expected !"); + da2->checkAllocated(); + int size=self->getNumberOfTuples(); + if(size!=self->getNumberOfTuples()) + { + throw INTERP_KERNEL::Exception("Invalid list length ! Must be equal to number of tuples !"); + } + return self->renumber(da2->getConstPointer()); + } + } + + DataArrayChar *renumberR(PyObject *li) throw(INTERP_KERNEL::Exception) + { + void *da=0; + int res1=SWIG_ConvertPtr(li,&da,SWIGTYPE_p_ParaMEDMEM__DataArrayInt, 0 | 0 ); + if (!SWIG_IsOK(res1)) + { + int size; + INTERP_KERNEL::AutoPtr<int> tmp=convertPyToNewIntArr2(li,&size); + if(size!=self->getNumberOfTuples()) + { + throw INTERP_KERNEL::Exception("Invalid list length ! Must be equal to number of tuples !"); + } + return self->renumberR(tmp); + } + else + { + DataArrayInt *da2=reinterpret_cast< DataArrayInt * >(da); + if(!da2) + throw INTERP_KERNEL::Exception("Not null DataArrayInt instance expected !"); + da2->checkAllocated(); + int size=self->getNumberOfTuples(); + if(size!=self->getNumberOfTuples()) + { + throw INTERP_KERNEL::Exception("Invalid list length ! Must be equal to number of tuples !"); + } + return self->renumberR(da2->getConstPointer()); + } + } + + DataArrayChar *renumberAndReduce(PyObject *li, int newNbOfTuple) throw(INTERP_KERNEL::Exception) + { + void *da=0; + int res1=SWIG_ConvertPtr(li,&da,SWIGTYPE_p_ParaMEDMEM__DataArrayInt, 0 | 0 ); + if (!SWIG_IsOK(res1)) + { + int size; + INTERP_KERNEL::AutoPtr<int> tmp=convertPyToNewIntArr2(li,&size); + if(size!=self->getNumberOfTuples()) + { + throw INTERP_KERNEL::Exception("Invalid list length ! Must be equal to number of tuples !"); + } + return self->renumberAndReduce(tmp,newNbOfTuple); + } + else + { + DataArrayInt *da2=reinterpret_cast< DataArrayInt * >(da); + if(!da2) + throw INTERP_KERNEL::Exception("Not null DataArrayInt instance expected !"); + da2->checkAllocated(); + int size=self->getNumberOfTuples(); + if(size!=self->getNumberOfTuples()) + { + throw INTERP_KERNEL::Exception("Invalid list length ! Must be equal to number of tuples !"); + } + return self->renumberAndReduce(da2->getConstPointer(),newNbOfTuple); + } + } + + static DataArrayChar *Aggregate(PyObject *dachs) throw(INTERP_KERNEL::Exception) + { + std::vector<const ParaMEDMEM::DataArrayChar *> tmp; + convertFromPyObjVectorOfObj<const ParaMEDMEM::DataArrayChar *>(dachs,SWIGTYPE_p_ParaMEDMEM__DataArrayChar,"DataArrayChar",tmp); + return DataArrayChar::Aggregate(tmp); + } + + static DataArrayChar *Meld(PyObject *dachs) throw(INTERP_KERNEL::Exception) + { + std::vector<const ParaMEDMEM::DataArrayChar *> tmp; + convertFromPyObjVectorOfObj<const ParaMEDMEM::DataArrayChar *>(dachs,SWIGTYPE_p_ParaMEDMEM__DataArrayChar,"DataArrayChar",tmp); + return DataArrayChar::Meld(tmp); + } + } + }; + + class DataArrayByteIterator; + + class DataArrayByte : public DataArrayChar + { + public: + static DataArrayByte *New(); + DataArrayByteIterator *iterator() throw(INTERP_KERNEL::Exception); + DataArrayByte *performCpy(bool deepCpy) const throw(INTERP_KERNEL::Exception); + char byteValue() const throw(INTERP_KERNEL::Exception); + %extend + { + DataArrayByte() throw(INTERP_KERNEL::Exception) + { + return DataArrayByte::New(); + } + + static DataArrayByte *New(PyObject *elt0, PyObject *nbOfTuples=0, PyObject *nbOfComp=0) throw(INTERP_KERNEL::Exception) + { + const char *msg="ParaMEDMEM::DataArrayByte::New : Available API are : \n-DataArrayByte.New()\n--DataArrayByte.New([1,3,4])\n-DataArrayByte.New([1,3,4],3)\n-DataArrayByte.New([1,3,4,5],2,2)\n-DataArrayByte.New(5)\n-DataArrayByte.New(5,2) !"; + if(PyList_Check(elt0) || PyTuple_Check(elt0)) + { + if(nbOfTuples) + { + if(PyInt_Check(nbOfTuples)) + { + int nbOfTuples1=PyInt_AS_LONG(nbOfTuples); + if(nbOfTuples1<0) + throw INTERP_KERNEL::Exception("DataArrayByte::New : should be a positive set of allocated memory !"); + if(nbOfComp) + { + if(PyInt_Check(nbOfComp)) + {//DataArrayByte.New([1,3,4,5],2,2) + int nbOfCompo=PyInt_AS_LONG(nbOfComp); + if(nbOfCompo<0) + throw INTERP_KERNEL::Exception("DataArrayByte::New : should be a positive number of components !"); + MEDCouplingAutoRefCountObjectPtr<DataArrayByte> ret=DataArrayByte::New(); + std::vector<int> tmp=fillArrayWithPyListInt2(elt0,nbOfTuples1,nbOfCompo); + ret->alloc(nbOfTuples1,nbOfCompo); std::copy(tmp.begin(),tmp.end(),ret->getPointer()); + return ret.retn(); + } + else + throw INTERP_KERNEL::Exception(msg); + } + else + {//DataArrayByte.New([1,3,4],3) + MEDCouplingAutoRefCountObjectPtr<DataArrayByte> ret=DataArrayByte::New(); + int tmpp1=-1; + std::vector<int> tmp=fillArrayWithPyListInt2(elt0,nbOfTuples1,tmpp1); + ret->alloc(nbOfTuples1,tmpp1); std::copy(tmp.begin(),tmp.end(),ret->getPointer()); + return ret.retn(); + } + } + else + throw INTERP_KERNEL::Exception(msg); + } + else + {// DataArrayByte.New([1,3,4]) + MEDCouplingAutoRefCountObjectPtr<DataArrayByte> ret=DataArrayByte::New(); + int tmpp1=-1,tmpp2=-1; + std::vector<int> tmp=fillArrayWithPyListInt2(elt0,tmpp1,tmpp2); + ret->alloc(tmpp1,tmpp2); std::copy(tmp.begin(),tmp.end(),ret->getPointer()); + return ret.retn(); + } + } + else if(PyInt_Check(elt0)) + { + int nbOfTuples1=PyInt_AS_LONG(elt0); + if(nbOfTuples1<0) + throw INTERP_KERNEL::Exception("DataArrayByte::New : should be a positive set of allocated memory !"); + if(nbOfTuples) + { + if(!nbOfComp) + { + if(PyInt_Check(nbOfTuples)) + {//DataArrayByte.New(5,2) + int nbOfCompo=PyInt_AS_LONG(nbOfTuples); + if(nbOfCompo<0) + throw INTERP_KERNEL::Exception("DataArrayByte::New : should be a positive number of components !"); + MEDCouplingAutoRefCountObjectPtr<DataArrayByte> ret=DataArrayByte::New(); + ret->alloc(nbOfTuples1,nbOfCompo); + return ret.retn(); + } + else + throw INTERP_KERNEL::Exception(msg); + } + else + throw INTERP_KERNEL::Exception(msg); + } + else + {//DataArrayByte.New(5) + MEDCouplingAutoRefCountObjectPtr<DataArrayByte> ret=DataArrayByte::New(); + ret->alloc(nbOfTuples1,1); + return ret.retn(); + } + } + else + throw INTERP_KERNEL::Exception(msg); + } + + DataArrayByte(PyObject *elt0, PyObject *nbOfTuples=0, PyObject *nbOfComp=0) throw(INTERP_KERNEL::Exception) + { + return ParaMEDMEM_DataArrayByte_New__SWIG_1(elt0,nbOfTuples,nbOfComp); + } + + std::string __repr__() const throw(INTERP_KERNEL::Exception) + { + std::ostringstream oss; + self->reprQuickOverview(oss); + return oss.str(); + } + + int __int__() const throw(INTERP_KERNEL::Exception) + { + return (int) self->byteValue(); + } + + DataArrayByteIterator *__iter__() throw(INTERP_KERNEL::Exception) + { + return self->iterator(); + } + + int getIJ(int tupleId, int compoId) const throw(INTERP_KERNEL::Exception) + { + return (int)self->getIJ(tupleId,compoId); + } + + int getIJSafe(int tupleId, int compoId) const throw(INTERP_KERNEL::Exception) + { + return (int)self->getIJSafe(tupleId,compoId); + } + + std::string __str__() const throw(INTERP_KERNEL::Exception) + { + return self->repr(); + } + + PyObject *toStrList() const throw(INTERP_KERNEL::Exception) + { + const char *vals=self->getConstPointer(); + int nbOfComp=self->getNumberOfComponents(); + int nbOfTuples=self->getNumberOfTuples(); + return convertCharArrToPyListOfTuple(vals,nbOfComp,nbOfTuples); + } + + bool presenceOfTuple(PyObject *tupl) const throw(INTERP_KERNEL::Exception) + { + int sz=-1,sw=-1; + int ival=-1; std::vector<int> ivval; + const int *pt=convertObjToPossibleCpp1_Safe(tupl,sw,sz,ival,ivval); + std::vector<char> vals(sz); + std::copy(pt,pt+sz,vals.begin()); + return self->presenceOfTuple(vals); + } + + bool presenceOfValue(PyObject *vals) const throw(INTERP_KERNEL::Exception) + { + int sz=-1,sw=-1; + int ival=-1; std::vector<int> ivval; + const int *pt=convertObjToPossibleCpp1_Safe(vals,sw,sz,ival,ivval); + std::vector<char> vals2(sz); + std::copy(pt,pt+sz,vals2.begin()); + return self->presenceOfValue(vals2); + } + + int locateValue(PyObject *vals) const throw(INTERP_KERNEL::Exception) + { + int sz=-1,sw=-1; + int ival=-1; std::vector<int> ivval; + const int *pt=convertObjToPossibleCpp1_Safe(vals,sw,sz,ival,ivval); + std::vector<char> vals2(sz); + std::copy(pt,pt+sz,vals2.begin()); + return self->locateValue(vals2); + } + + int locateTuple(PyObject *tupl) const throw(INTERP_KERNEL::Exception) + { + int sz=-1,sw=-1; + int ival=-1; std::vector<int> ivval; + const int *pt=convertObjToPossibleCpp1_Safe(tupl,sw,sz,ival,ivval); + std::vector<char> vals(sz); + std::copy(pt,pt+sz,vals.begin()); + return self->locateTuple(vals); + } + + int search(PyObject *strOrListOfInt) const throw(INTERP_KERNEL::Exception) + { + int sz=-1,sw=-1; + int ival=-1; std::vector<int> ivval; + const int *pt=convertObjToPossibleCpp1_Safe(strOrListOfInt,sw,sz,ival,ivval); + std::vector<char> vals(sz); + std::copy(pt,pt+sz,vals.begin()); + return self->search(vals); + } + + PyObject *getTuple(int tupleId) throw(INTERP_KERNEL::Exception) + { + int sz=self->getNumberOfComponents(); + INTERP_KERNEL::AutoPtr<char> tmp=new char[sz]; + self->getTuple(tupleId,tmp); + PyObject *ret=PyTuple_New(sz); + for(int i=0;i<sz;i++) PyTuple_SetItem(ret,i,PyInt_FromLong((int)tmp[i])); + return ret; + } + + PyObject *getMaxValue() const throw(INTERP_KERNEL::Exception) + { + int tmp; + int r1=(int)self->getMaxValue(tmp); + PyObject *ret=PyTuple_New(2); + PyTuple_SetItem(ret,0,PyInt_FromLong(r1)); + PyTuple_SetItem(ret,1,PyInt_FromLong(tmp)); + return ret; + } + + PyObject *getMinValue() const throw(INTERP_KERNEL::Exception) + { + int tmp; + int r1=(int)self->getMinValue(tmp); + PyObject *ret=PyTuple_New(2); + PyTuple_SetItem(ret,0,PyInt_FromLong(r1)); + PyTuple_SetItem(ret,1,PyInt_FromLong(tmp)); + return ret; + } + + int index(PyObject *obj) const throw(INTERP_KERNEL::Exception) + { + int nbOfCompo=self->getNumberOfComponents(); + switch(nbOfCompo) + { + case 1: + { + if(PyInt_Check(obj)) + { + int val=(int)PyInt_AS_LONG(obj); + return self->locateValue(val); + } + else + throw INTERP_KERNEL::Exception("DataArrayByte::index : 'this' contains one component and trying to find an element which is not an integer !"); + } + default: + return ParaMEDMEM_DataArrayByte_locateTuple(self,obj); + } + } + + bool __contains__(PyObject *obj) const throw(INTERP_KERNEL::Exception) + { + int nbOfCompo=self->getNumberOfComponents(); + switch(nbOfCompo) + { + case 0: + return false; + case 1: + { + if(PyInt_Check(obj)) + { + int val=(int)PyInt_AS_LONG(obj); + return self->presenceOfValue(val); + } + else + throw INTERP_KERNEL::Exception("DataArrayByte::__contains__ : 'this' contains one component and trying to find an element which is not an integer !"); + } + default: + return ParaMEDMEM_DataArrayByte_presenceOfTuple(self,obj); + } + } + + DataArrayByte *__setitem__(PyObject *obj, PyObject *value) throw(INTERP_KERNEL::Exception) + { + self->checkAllocated(); + const char msg[]="Unexpected situation in __setitem__ !"; + int nbOfTuples(self->getNumberOfTuples()),nbOfComponents(self->getNumberOfComponents()); + int sw1,sw2; + int i1; + std::vector<int> v1; + DataArrayInt *d1=0; + DataArrayIntTuple *dd1=0; + convertObjToPossibleCpp1(value,sw1,i1,v1,d1,dd1); + int it1,ic1; + std::vector<int> vt1,vc1; + std::pair<int, std::pair<int,int> > pt1,pc1; + DataArrayInt *dt1=0,*dc1=0; + convertObjToPossibleCpp3(obj,nbOfTuples,nbOfComponents,sw2,it1,ic1,vt1,vc1,pt1,pc1,dt1,dc1); + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> tmp; + switch(sw2) + { + case 1: + { + switch(sw1) + { + case 1: + self->setPartOfValuesSimple1(i1,it1,it1+1,1,0,nbOfComponents,1); + return self; + default: + throw INTERP_KERNEL::Exception(msg); + } + break; + } + case 2: + { + switch(sw1) + { + case 1: + self->setPartOfValuesSimple3(i1,&vt1[0],&vt1[0]+vt1.size(),0,nbOfComponents,1); + return self; + default: + throw INTERP_KERNEL::Exception(msg); + } + break; + } + case 3: + { + switch(sw1) + { + case 1: + self->setPartOfValuesSimple1(i1,pt1.first,pt1.second.first,pt1.second.second,0,nbOfComponents,1); + return self; + default: + throw INTERP_KERNEL::Exception(msg); + } + break; + } + case 4: + { + switch(sw1) + { + case 1: + self->setPartOfValuesSimple3(i1,dt1->getConstPointer(),dt1->getConstPointer()+dt1->getNbOfElems(),0,nbOfComponents,1); + return self; + default: + throw INTERP_KERNEL::Exception(msg); + } + break; + } + case 5: + { + switch(sw1) + { + case 1: + self->setPartOfValuesSimple1(i1,it1,it1+1,1,ic1,ic1+1,1); + return self; + default: + throw INTERP_KERNEL::Exception(msg); + } + break; + } + case 6: + { + switch(sw1) + { + case 1: + self->setPartOfValuesSimple3(i1,&vt1[0],&vt1[0]+vt1.size(),ic1,ic1+1,1); + return self; + default: + throw INTERP_KERNEL::Exception(msg); + } + break; + } + case 7: + { + switch(sw1) + { + case 1: + self->setPartOfValuesSimple1(i1,pt1.first,pt1.second.first,pt1.second.second,ic1,ic1+1,1); + return self; + default: + throw INTERP_KERNEL::Exception(msg); + } + break; + } + case 8: + { + switch(sw1) + { + case 1: + self->setPartOfValuesSimple3(i1,dt1->getConstPointer(),dt1->getConstPointer()+dt1->getNbOfElems(),ic1,ic1+1,1); + return self; + default: + throw INTERP_KERNEL::Exception(msg); + } + break; + } + case 9: + { + switch(sw1) + { + case 1: + self->setPartOfValuesSimple2(i1,&it1,&it1+1,&vc1[0],&vc1[0]+vc1.size()); + return self; + default: + throw INTERP_KERNEL::Exception(msg); + } + break; + } + case 10: + { + switch(sw1) + { + case 1: + self->setPartOfValuesSimple2(i1,&vt1[0],&vt1[0]+vt1.size(),&vc1[0],&vc1[0]+vc1.size()); + return self; + default: + throw INTERP_KERNEL::Exception(msg); + } + break; + } + case 11: + { + switch(sw1) + { + case 1: + self->setPartOfValuesSimple4(i1,pt1.first,pt1.second.first,pt1.second.second,&vc1[0],&vc1[0]+vc1.size()); + return self; + default: + throw INTERP_KERNEL::Exception(msg); + } + break; + } + case 12: + { + switch(sw1) + { + case 1: + self->setPartOfValuesSimple2(i1,dt1->getConstPointer(),dt1->getConstPointer()+dt1->getNbOfElems(),&vc1[0],&vc1[0]+vc1.size()); + return self; + default: + throw INTERP_KERNEL::Exception(msg); + } + break; + } + case 13: + { + switch(sw1) + { + case 1: + self->setPartOfValuesSimple1(i1,it1,it1+1,1,pc1.first,pc1.second.first,pc1.second.second); + return self; + default: + throw INTERP_KERNEL::Exception(msg); + } + break; + } + case 14: + { + switch(sw1) + { + case 1: + self->setPartOfValuesSimple3(i1,&vt1[0],&vt1[0]+vt1.size(),pc1.first,pc1.second.first,pc1.second.second); + return self; + default: + throw INTERP_KERNEL::Exception(msg); + } + break; + } + case 15: + { + switch(sw1) + { + case 1: + self->setPartOfValuesSimple1(i1,pt1.first,pt1.second.first,pt1.second.second,pc1.first,pc1.second.first,pc1.second.second); + return self; + default: + throw INTERP_KERNEL::Exception(msg); + } + break; + } + case 16: + { + switch(sw1) + { + case 1: + self->setPartOfValuesSimple3(i1,dt1->getConstPointer(),dt1->getConstPointer()+dt1->getNbOfElems(),pc1.first,pc1.second.first,pc1.second.second); + return self; + default: + throw INTERP_KERNEL::Exception(msg); + } + break; + } + default: + throw INTERP_KERNEL::Exception(msg); + } + return self; + } + } + }; + + class DataArrayByteTuple; + + class DataArrayByteIterator + { + public: + DataArrayByteIterator(DataArrayByte *da); + ~DataArrayByteIterator(); + }; + + class DataArrayByteTuple + { + public: + std::string repr() const throw(INTERP_KERNEL::Exception); + DataArrayByte *buildDAByte(int nbOfTuples, int nbOfCompo) const throw(INTERP_KERNEL::Exception); + %extend + { + std::string __str__() const throw(INTERP_KERNEL::Exception) + { + return self->repr(); + } + + char __int__() const throw(INTERP_KERNEL::Exception) + { + return self->byteValue(); + } + + DataArrayByte *buildDAByte() throw(INTERP_KERNEL::Exception) + { + return self->buildDAByte(1,self->getNumberOfCompo()); + } + } + }; + + class DataArrayAsciiCharIterator; + + class DataArrayAsciiChar : public DataArrayChar + { + public: + static DataArrayAsciiChar *New(); + DataArrayAsciiCharIterator *iterator() throw(INTERP_KERNEL::Exception); + DataArrayAsciiChar *performCpy(bool deepCpy) const throw(INTERP_KERNEL::Exception); + char asciiCharValue() const throw(INTERP_KERNEL::Exception); + %extend + { + DataArrayAsciiChar() throw(INTERP_KERNEL::Exception) + { + return DataArrayAsciiChar::New(); + } + + static DataArrayAsciiChar *New(PyObject *elt0, PyObject *nbOfTuples=0, PyObject *nbOfComp=0) throw(INTERP_KERNEL::Exception) + { + const char *msg="ParaMEDMEM::DataArrayAsciiChar::New : Available API are : \n-DataArrayAsciiChar.New()\n-DataArrayAsciiChar.New([1,3,4])\n-DataArrayAsciiChar.New([\"abc\",\"de\",\"fghi\"])\n-DataArrayAsciiChar.New([\"abc\",\"de\",\"fghi\"],\"t\")\n-DataArrayAsciiChar.New([1,3,4],3)\n-DataArrayAsciiChar.New([1,3,4,5],2,2)\n-DataArrayAsciiChar.New(5)\n-DataArrayAsciiChar.New(5,2) !"; + if(PyList_Check(elt0) || PyTuple_Check(elt0)) + { + if(nbOfTuples) + { + if(PyInt_Check(nbOfTuples)) + { + int nbOfTuples1=PyInt_AS_LONG(nbOfTuples); + if(nbOfTuples1<0) + throw INTERP_KERNEL::Exception("DataArrayAsciiChar::New : should be a positive set of allocated memory !"); + if(nbOfComp) + { + if(PyInt_Check(nbOfComp)) + {//DataArrayAsciiChar.New([1,3,4,5],2,2) + int nbOfCompo=PyInt_AS_LONG(nbOfComp); + if(nbOfCompo<0) + throw INTERP_KERNEL::Exception("DataArrayAsciiChar::New : should be a positive number of components !"); + MEDCouplingAutoRefCountObjectPtr<DataArrayAsciiChar> ret=DataArrayAsciiChar::New(); + std::vector<int> tmp=fillArrayWithPyListInt2(elt0,nbOfTuples1,nbOfCompo); + ret->alloc(nbOfTuples1,nbOfCompo); std::copy(tmp.begin(),tmp.end(),ret->getPointer()); + return ret.retn(); + } + else + throw INTERP_KERNEL::Exception(msg); + } + else + {//DataArrayAsciiChar.New([1,3,4],3) + MEDCouplingAutoRefCountObjectPtr<DataArrayAsciiChar> ret=DataArrayAsciiChar::New(); + int tmpp1=-1; + std::vector<int> tmp=fillArrayWithPyListInt2(elt0,nbOfTuples1,tmpp1); + ret->alloc(nbOfTuples1,tmpp1); std::copy(tmp.begin(),tmp.end(),ret->getPointer()); + return ret.retn(); + } + } + else if(PyString_Check(nbOfTuples)) + { + if(PyString_Size(nbOfTuples)!=1) + throw INTERP_KERNEL::Exception(msg); + //DataArrayAsciiChar.New(["abc","de","fghi"],"t") + std::vector<std::string> tmp; + if(fillStringVector(elt0,tmp)) + return DataArrayAsciiChar::New(tmp,PyString_AsString(nbOfTuples)[0]); + else + throw INTERP_KERNEL::Exception(msg); + } + else + throw INTERP_KERNEL::Exception(msg); + } + else + { + std::vector<std::string> tmmp; + if(fillStringVector(elt0,tmmp)) + //DataArrayAsciiChar.New(["abc","de","fghi"]) + return DataArrayAsciiChar::New(tmmp,' '); + else + { + // DataArrayAsciiChar.New([1,3,4]) + MEDCouplingAutoRefCountObjectPtr<DataArrayAsciiChar> ret=DataArrayAsciiChar::New(); + int tmpp1=-1,tmpp2=-1; + std::vector<int> tmp=fillArrayWithPyListInt2(elt0,tmpp1,tmpp2); + ret->alloc(tmpp1,tmpp2); std::copy(tmp.begin(),tmp.end(),ret->getPointer()); + return ret.retn(); + } + } + } + else if(PyInt_Check(elt0)) + { + int nbOfTuples1=PyInt_AS_LONG(elt0); + if(nbOfTuples1<0) + throw INTERP_KERNEL::Exception("DataArrayAsciiChar::New : should be a positive set of allocated memory !"); + if(nbOfTuples) + { + if(!nbOfComp) + { + if(PyInt_Check(nbOfTuples)) + {//DataArrayAsciiChar.New(5,2) + int nbOfCompo=PyInt_AS_LONG(nbOfTuples); + if(nbOfCompo<0) + throw INTERP_KERNEL::Exception("DataArrayAsciiChar::New : should be a positive number of components !"); + MEDCouplingAutoRefCountObjectPtr<DataArrayAsciiChar> ret=DataArrayAsciiChar::New(); + ret->alloc(nbOfTuples1,nbOfCompo); + return ret.retn(); + } + else + throw INTERP_KERNEL::Exception(msg); + } + else + throw INTERP_KERNEL::Exception(msg); + } + else + {//DataArrayAsciiChar.New(5) + MEDCouplingAutoRefCountObjectPtr<DataArrayAsciiChar> ret=DataArrayAsciiChar::New(); + ret->alloc(nbOfTuples1,1); + return ret.retn(); + } + } + else + throw INTERP_KERNEL::Exception(msg); + } + + DataArrayAsciiChar(PyObject *elt0, PyObject *nbOfTuples=0, PyObject *nbOfComp=0) throw(INTERP_KERNEL::Exception) + { + return ParaMEDMEM_DataArrayAsciiChar_New__SWIG_1(elt0,nbOfTuples,nbOfComp); + } + + std::string __repr__() const throw(INTERP_KERNEL::Exception) + { + std::ostringstream oss; + self->reprQuickOverview(oss); + return oss.str(); + } + + DataArrayAsciiCharIterator *__iter__() throw(INTERP_KERNEL::Exception) + { + return self->iterator(); + } + + std::string getIJ(int tupleId, int compoId) const throw(INTERP_KERNEL::Exception) + { + char tmp[2]; tmp[1]='\0'; + tmp[0]=self->getIJ(tupleId,compoId); + return std::string(tmp); + } + + std::string getIJSafe(int tupleId, int compoId) const throw(INTERP_KERNEL::Exception) + { + char tmp[2]; tmp[1]='\0'; + tmp[0]=self->getIJSafe(tupleId,compoId); + return std::string(tmp); + } + + std::string __str__() const throw(INTERP_KERNEL::Exception) + { + return self->repr(); + } + + PyObject *toStrList() const throw(INTERP_KERNEL::Exception) + { + const char *vals=self->getConstPointer(); + int nbOfComp=self->getNumberOfComponents(); + int nbOfTuples=self->getNumberOfTuples(); + return convertCharArrToPyListOfTuple(vals,nbOfComp,nbOfTuples); + } + + bool presenceOfTuple(PyObject *tupl) const throw(INTERP_KERNEL::Exception) + { + if(PyString_Check(tupl)) + { + Py_ssize_t sz=PyString_Size(tupl); + std::vector<char> vals(sz); + std::copy(PyString_AsString(tupl),PyString_AsString(tupl)+sz,vals.begin()); + return self->presenceOfTuple(vals); + } + else + throw INTERP_KERNEL::Exception("DataArrayAsciiChar::presenceOfTuple : only strings in input supported !"); + } + + bool presenceOfValue(PyObject *vals) const throw(INTERP_KERNEL::Exception) + { + if(PyString_Check(vals)) + { + Py_ssize_t sz=PyString_Size(vals); + std::vector<char> vals2(sz); + std::copy(PyString_AsString(vals),PyString_AsString(vals)+sz,vals2.begin()); + return self->presenceOfValue(vals2); + } + else + throw INTERP_KERNEL::Exception("DataArrayAsciiChar::presenceOfValue : only strings in input supported !"); + } + + int locateValue(PyObject *vals) const throw(INTERP_KERNEL::Exception) + { + if(PyString_Check(vals)) + { + Py_ssize_t sz=PyString_Size(vals); + std::vector<char> vals2(sz); + std::copy(PyString_AsString(vals),PyString_AsString(vals)+sz,vals2.begin()); + return self->locateValue(vals2); + } + else + throw INTERP_KERNEL::Exception("DataArrayAsciiChar::locateValue : only strings in input supported !"); + } + + int locateTuple(PyObject *tupl) const throw(INTERP_KERNEL::Exception) + { + if(PyString_Check(tupl)) + { + Py_ssize_t sz=PyString_Size(tupl); + std::vector<char> vals(sz); + std::copy(PyString_AsString(tupl),PyString_AsString(tupl)+sz,vals.begin()); + return self->locateTuple(vals); + } + else + throw INTERP_KERNEL::Exception("DataArrayAsciiChar::locateTuple : only strings in input supported !"); + } + + int search(PyObject *strOrListOfInt) const throw(INTERP_KERNEL::Exception) + { + if(PyString_Check(strOrListOfInt)) + { + Py_ssize_t sz=PyString_Size(strOrListOfInt); + std::vector<char> vals(sz); + std::copy(PyString_AsString(strOrListOfInt),PyString_AsString(strOrListOfInt)+sz,vals.begin()); + return self->search(vals); + } + else + throw INTERP_KERNEL::Exception("DataArrayAsciiChar::search : only strings in input supported !"); + } + + PyObject *getTuple(int tupleId) const throw(INTERP_KERNEL::Exception) + { + int sz=self->getNumberOfComponents(); + INTERP_KERNEL::AutoPtr<char> tmp=new char[sz+1]; tmp[sz]='\0'; + self->getTuple(tupleId,tmp); + return PyString_FromString(tmp); + } + + PyObject *getMaxValue() const throw(INTERP_KERNEL::Exception) + { + int tmp; + char tmp2[2]; tmp2[1]='\0'; + tmp2[0]=self->getMaxValue(tmp); + PyObject *ret=PyTuple_New(2); + PyTuple_SetItem(ret,0,PyString_FromString(tmp2)); + PyTuple_SetItem(ret,1,PyInt_FromLong(tmp)); + return ret; + } + + PyObject *getMinValue() const throw(INTERP_KERNEL::Exception) + { + int tmp; + char tmp2[2]; tmp2[1]='\0'; + tmp2[0]=self->getMinValue(tmp); + PyObject *ret=PyTuple_New(2); + PyTuple_SetItem(ret,0,PyString_FromString(tmp2)); + PyTuple_SetItem(ret,1,PyInt_FromLong(tmp)); + return ret; + } + + int index(PyObject *obj) const throw(INTERP_KERNEL::Exception) + { + int nbOfCompo=self->getNumberOfComponents(); + switch(nbOfCompo) + { + case 1: + { + if(PyString_Check(obj)) + { + Py_ssize_t sz=PyString_Size(obj); + char *pt=PyString_AsString(obj); + if(sz==1) + return self->locateValue(pt[0]); + else + throw INTERP_KERNEL::Exception("DataArrayAsciiChar::index : 'this' contains one component and trying to find a string with size different from 1 !"); + } + else + throw INTERP_KERNEL::Exception("DataArrayAsciiChar::index : 'this' contains one component and trying to find an element which is not an integer !"); + } + default: + return ParaMEDMEM_DataArrayAsciiChar_locateTuple(self,obj); + } + } + + bool __contains__(PyObject *obj) const throw(INTERP_KERNEL::Exception) + { + int nbOfCompo=self->getNumberOfComponents(); + switch(nbOfCompo) + { + case 0: + return false; + case 1: + { + if(PyString_Check(obj)) + { + Py_ssize_t sz=PyString_Size(obj); + char *pt=PyString_AsString(obj); + if(sz==1) + return self->presenceOfValue(pt[0]); + else + throw INTERP_KERNEL::Exception("DataArrayAsciiChar::__contains__ : 'this' contains one component and trying to find a string with size different from 1 !"); + } + else + throw INTERP_KERNEL::Exception("DataArrayAsciiChar::__contains__ : 'this' contains one component and trying to find an element which is not an integer !"); + } + default: + return ParaMEDMEM_DataArrayAsciiChar_presenceOfTuple(self,obj); + } + } + + PyObject *__getitem__(PyObject *obj) const throw(INTERP_KERNEL::Exception) + { + int sw,iTypppArr; + std::vector<int> stdvecTyyppArr; + std::pair<int, std::pair<int,int> > sTyyppArr; + ParaMEDMEM::DataArrayInt *daIntTyypp=0; + convertObjToPossibleCpp2WithNegIntInterp(obj,self->getNumberOfTuples(),sw,iTypppArr,stdvecTyyppArr,sTyyppArr,daIntTyypp); + switch(sw) + { + case 1: + return ParaMEDMEM_DataArrayAsciiChar_getTuple(self,iTypppArr); + case 2: + return convertDataArrayChar(self->selectByTupleIdSafe(&stdvecTyyppArr[0],&stdvecTyyppArr[0]+stdvecTyyppArr.size()), SWIG_POINTER_OWN | 0 ); + case 3: + return convertDataArrayChar(self->selectByTupleId2(sTyyppArr.first,sTyyppArr.second.first,sTyyppArr.second.second), SWIG_POINTER_OWN | 0 ); + case 4: + return convertDataArrayChar(self->selectByTupleIdSafe(daIntTyypp->begin(),daIntTyypp->end()), SWIG_POINTER_OWN | 0 ); + default: + throw INTERP_KERNEL::Exception("DataArrayAsciiChar::__getitem__ : supporting int, list of int, tuple of int, DataArrayInt and slice in input !"); + } + } + + DataArrayAsciiChar *__setitem__(PyObject *obj, PyObject *value) throw(INTERP_KERNEL::Exception) + { + static const char msg[]="DataArrayAsciiChar::__setitem__ : supporting int, list of int, tuple of int, DataArrayInt and slice in input, and 4 types accepted in value : string, list or tuple of strings having same size, not null DataArrayChar instance."; + int sw1,iTypppArr; + std::vector<int> stdvecTyyppArr; + std::pair<int, std::pair<int,int> > sTyyppArr; + ParaMEDMEM::DataArrayInt *daIntTyypp=0; + int nbOfCompo=self->getNumberOfComponents(); + int nbOfTuples=self->getNumberOfTuples(); + convertObjToPossibleCpp2WithNegIntInterp(obj,nbOfTuples,sw1,iTypppArr,stdvecTyyppArr,sTyyppArr,daIntTyypp); + int sw2; + char vc; std::string sc; std::vector<std::string> vsc; DataArrayChar *dacc=0; + convertObjToPossibleCpp6(value,sw2,vc,sc,vsc,dacc); + switch(sw1) + { + case 1: + {//obj int + switch(sw2) + {//value char + case 1: + { + self->setPartOfValuesSimple3(vc,&iTypppArr,&iTypppArr+1,0,nbOfCompo,1); + return self; + } + //value string + case 2: + { + MEDCouplingAutoRefCountObjectPtr<DataArrayAsciiChar> tmp=DataArrayAsciiChar::New(sc); + self->setPartOfValues3(tmp,&iTypppArr,&iTypppArr+1,0,nbOfCompo,1,false); + return self; + } + //value vector<string> + case 3: + { + MEDCouplingAutoRefCountObjectPtr<DataArrayAsciiChar> tmp=DataArrayAsciiChar::New(vsc,' '); + self->setPartOfValues3(tmp,&iTypppArr,&iTypppArr+1,0,nbOfCompo,1,false); + return self; + } + //value DataArrayChar + case 4: + { + self->setPartOfValues3(dacc,&iTypppArr,&iTypppArr+1,0,nbOfCompo,1,false); + return self; + } + default: + throw INTERP_KERNEL::Exception(msg); + } + } + case 2: + {//obj list-tuple[int] + switch(sw2) + { + {//value char + case 1: + { + self->setPartOfValuesSimple3(vc,&stdvecTyyppArr[0],&stdvecTyyppArr[0]+stdvecTyyppArr.size(),0,nbOfCompo,1); + return self; + } + //value string + case 2: + { + MEDCouplingAutoRefCountObjectPtr<DataArrayAsciiChar> tmp=DataArrayAsciiChar::New(sc); + self->setPartOfValues3(tmp,&stdvecTyyppArr[0],&stdvecTyyppArr[0]+stdvecTyyppArr.size(),0,nbOfCompo,1,false); + return self; + } + //value vector<string> + case 3: + { + MEDCouplingAutoRefCountObjectPtr<DataArrayAsciiChar> tmp=DataArrayAsciiChar::New(vsc,' '); + self->setPartOfValues3(tmp,&stdvecTyyppArr[0],&stdvecTyyppArr[0]+stdvecTyyppArr.size(),0,nbOfCompo,1,false); + return self; + } + //value DataArrayChar + case 4: + { + self->setPartOfValues3(dacc,&stdvecTyyppArr[0],&stdvecTyyppArr[0]+stdvecTyyppArr.size(),0,nbOfCompo,1,false); + return self; + } + default: + throw INTERP_KERNEL::Exception(msg); + } + } + } + case 3: + {//slice + switch(sw2) + { + {//value char + case 1: + { + self->setPartOfValuesSimple1(vc,sTyyppArr.first,sTyyppArr.second.first,sTyyppArr.second.second,0,nbOfCompo,1); + return self; + } + //value string + case 2: + { + MEDCouplingAutoRefCountObjectPtr<DataArrayAsciiChar> tmp=DataArrayAsciiChar::New(sc); + self->setPartOfValues1(tmp,sTyyppArr.first,sTyyppArr.second.first,sTyyppArr.second.second,0,nbOfCompo,1,false); + return self; + } + //value vector<string> + case 3: + { + MEDCouplingAutoRefCountObjectPtr<DataArrayAsciiChar> tmp=DataArrayAsciiChar::New(vsc,' '); + self->setPartOfValues1(tmp,sTyyppArr.first,sTyyppArr.second.first,sTyyppArr.second.second,0,nbOfCompo,1,false); + return self; + } + //value DataArrayChar + case 4: + { + self->setPartOfValues1(dacc,sTyyppArr.first,sTyyppArr.second.first,sTyyppArr.second.second,0,nbOfCompo,1,false); + return self; + } + default: + throw INTERP_KERNEL::Exception(msg); + } + } + } + case 4: + {//DataArrayInt + switch(sw2) + { + {//value char + case 1: + { + self->setPartOfValuesSimple3(vc,daIntTyypp->begin(),daIntTyypp->end(),0,nbOfCompo,1); + return self; + } + //value string + case 2: + { + MEDCouplingAutoRefCountObjectPtr<DataArrayAsciiChar> tmp=DataArrayAsciiChar::New(sc); + self->setPartOfValues3(tmp,daIntTyypp->begin(),daIntTyypp->end(),0,nbOfCompo,1,false); + return self; + } + //value vector<string> + case 3: + { + MEDCouplingAutoRefCountObjectPtr<DataArrayAsciiChar> tmp=DataArrayAsciiChar::New(vsc,' '); + self->setPartOfValues3(tmp,daIntTyypp->begin(),daIntTyypp->end(),0,nbOfCompo,1,false); + return self; + } + //value DataArrayChar + case 4: + { + self->setPartOfValues3(dacc,daIntTyypp->begin(),daIntTyypp->end(),0,nbOfCompo,1,false); + return self; + } + default: + throw INTERP_KERNEL::Exception(msg); + } + } + } + default: + throw INTERP_KERNEL::Exception(msg); + } + } + } + }; + + class DataArrayAsciiCharTuple; + + class DataArrayAsciiCharIterator + { + public: + DataArrayAsciiCharIterator(DataArrayAsciiChar *da); + ~DataArrayAsciiCharIterator(); + %extend + { + PyObject *next() + { + DataArrayAsciiCharTuple *ret=self->nextt(); + if(ret) + return SWIG_NewPointerObj(SWIG_as_voidptr(ret),SWIGTYPE_p_ParaMEDMEM__DataArrayAsciiCharTuple,SWIG_POINTER_OWN | 0); + else + { + PyErr_SetString(PyExc_StopIteration,"No more data."); + return 0; + } + } + } + }; + + class DataArrayAsciiCharTuple + { + public: + int getNumberOfCompo() const throw(INTERP_KERNEL::Exception); + DataArrayAsciiChar *buildDAAsciiChar(int nbOfTuples, int nbOfCompo) const throw(INTERP_KERNEL::Exception); + %extend + { + std::string __str__() const throw(INTERP_KERNEL::Exception) + { + return self->repr(); + } + + DataArrayAsciiChar *buildDAAsciiChar() throw(INTERP_KERNEL::Exception) + { + return self->buildDAAsciiChar(1,self->getNumberOfCompo()); + } + } + }; +} diff --git a/src/medtool/src/MEDCoupling_Swig/MEDCouplingNumPyTest.py b/src/medtool/src/MEDCoupling_Swig/MEDCouplingNumPyTest.py new file mode 100644 index 000000000..e5d7943bf --- /dev/null +++ b/src/medtool/src/MEDCoupling_Swig/MEDCouplingNumPyTest.py @@ -0,0 +1,672 @@ +# -*- coding: iso-8859-1 -*- +# Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 +# 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 +# + +from MEDCoupling import * + +if MEDCouplingHasNumPyBindings(): + from numpy import * + pass + +from platform import architecture +from sys import getrefcount + +import os,gc,weakref,unittest + +class MEDCouplingNumPyTest(unittest.TestCase): + + @unittest.skipUnless(MEDCouplingHasNumPyBindings(),"requires numpy") + def test1(self): + sz=20 + a=array(0,dtype=int32) + a.resize(sz) + a[:]=4 + self.assertEqual(getrefcount(a),2) + a=a.cumsum(dtype=int32) + a=array(a,dtype=int64) ; a=array(a,dtype=int32) + self.assertEqual(getrefcount(a),2) + d=DataArrayInt(a) + d[:]=2 + # + e=DataArrayInt(sz) ; e.fillWithValue(2) + self.assertTrue(d.isEqual(e)) + # + a[:]=4 ; e.fillWithValue(4) + self.assertTrue(d.isEqual(e)) + pass + + @unittest.skipUnless(MEDCouplingHasNumPyBindings(),"requires numpy") + def test2(self): + sz=20 + a=array(0,dtype=int32) + a.resize(sz,2) + self.assertEqual(getrefcount(a),2) + b=a.reshape(2*sz) + self.assertEqual(getrefcount(a),3) + self.assertEqual(getrefcount(b),2) + b[:]=5 + d=DataArrayInt(b) + # + e=DataArrayInt(sz*2) ; e.fillWithValue(5) + self.assertTrue(d.isEqual(e)) + pass + + @unittest.skipUnless(MEDCouplingHasNumPyBindings(),"requires numpy") + def test3(self): + sz=10 + a=array(0,dtype=int32) + a.resize(sz,2) + b=a.reshape(2*sz) + c=a.reshape(2,sz) + b[:]=6 + b[7:17]=7 + d=DataArrayInt(b) + self.assertTrue(d.isEqual(DataArrayInt([6,6,6,6,6,6,6,7,7,7,7,7,7,7,7,7,7,6,6,6]))) + # + a=zeros((10,2),dtype=int32) + b=a.T + c=b.view() + a.shape=20 + a[3:]=10. + d=DataArrayInt(a) + self.assertTrue(d.isEqual(DataArrayInt([0,0,0,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10]))) + pass + + @unittest.skipUnless(MEDCouplingHasNumPyBindings(),"requires numpy") + def test4(self): + a=zeros(20,dtype=int32) + b = a[::-1] + self.assertRaises(InterpKernelException,DataArrayInt.New,b) # b is not contiguous in memory + pass + + @unittest.skipUnless(MEDCouplingHasNumPyBindings(),"requires numpy") + def test5(self): + a=arange(20,dtype=int32) + self.assertEqual(weakref.getweakrefcount(a),0) + d=DataArrayInt(a) + self.assertEqual(weakref.getweakrefcount(a),1) + self.assertTrue(not a.flags["OWNDATA"]) + self.assertTrue(d.isIdentity()) + self.assertEqual(len(d),20) + a[:]=2 # modifying a and d because a and d share the same chunk of data + self.assertTrue(d.isUniform(2)) + del d # d is destroyed, a retrieves its ownership of its initial chunk of data + ##@@ Ensure a pass of the garbage collector so that the de-allocator of d is called + import gc + gc.collect() + self.assertTrue(a.flags["OWNDATA"]) + a[:]=4 # a can be used has usual + self.assertTrue(DataArrayInt(a).isUniform(4)) + pass + + @unittest.skipUnless(MEDCouplingHasNumPyBindings(),"requires numpy") + def test6(self): + a=arange(20,dtype=int32) + d=DataArrayInt(a) # d owns data of a + e=DataArrayInt(a) # a not owned -> e only an access to chunk of a + self.assertTrue(d.isIdentity()) + self.assertTrue(e.isIdentity()) + a[:]=6 + self.assertTrue(d.isUniform(6)) + self.assertTrue(e.isUniform(6)) + del a # a destroyed -> d no change because owned and e array is has no more data set + ##@@ Ensure a pass of the garbage collector so that the de-allocator of d is called + import gc + gc.collect() + self.assertTrue(d.isUniform(6)) + self.assertTrue(not e.isAllocated()) + pass + + @unittest.skipUnless(MEDCouplingHasNumPyBindings(),"requires numpy") + def test7(self): + a=array(0,dtype=int32) ; a.resize(10,2) + b=a.reshape(20) + c=a.reshape(2,10) + d=DataArrayInt(b) # d owns data of a + e=DataArrayInt(b) # a not owned -> e only an access to chunk of a + f=DataArrayInt(b) # a not owned -> e only an access to chunk of a + del d # d removed -> a ownes again data + ##@@ Ensure a pass of the garbage collector so that the de-allocator of d is called + import gc + gc.collect() + self.assertTrue(e.isUniform(0)) + e[:]=6 + self.assertTrue(e.isUniform(6)) + self.assertTrue(f.isUniform(6)) + self.assertEqual(b.tolist(),[6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6]) + self.assertEqual(a.tolist(),[[6,6],[6,6],[6,6],[6,6],[6,6],[6,6],[6,6],[6,6],[6,6],[6,6]]) + b[:]=arange(20) + del b # no impact on e and f because a is the base of a. + ##@@ Ensure a pass of the garbage collector so that the de-allocator of d is called + gc.collect() + self.assertTrue(f.isIdentity()) + self.assertTrue(e.isIdentity()) + del a # a destroyed, but as c has its base set to a, a exists -> e and f not allocated + ##@@ Ensure a pass of the garbage collector so that the de-allocator of d is called + gc.collect() + self.assertTrue(f.isIdentity()) + self.assertTrue(e.isIdentity()) + del c # c killed -> a killed -> e and d are put into not allocated state + ##@@ Ensure a pass of the garbage collector so that the de-allocator of d is called + gc.collect() + self.assertTrue(not e.isAllocated()) + self.assertTrue(not f.isAllocated()) + pass + + @unittest.skipUnless(MEDCouplingHasNumPyBindings(),"requires numpy") + def test8(self): + a=arange(20,dtype=int32) + self.assertTrue(a.flags["OWNDATA"]) + d=DataArrayInt(a) # d owns data of a + self.assertTrue(not a.flags["OWNDATA"]) + d.pushBackSilent(20)# d pushBack so release of chunk of data -> a becomes owner of its data again + self.assertTrue(a.flags["OWNDATA"]) + self.assertTrue(d.isEqual(DataArrayInt([0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20]))) + self.assertEqual(a.tolist(),[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19]) + pass + + @unittest.skipUnless(MEDCouplingHasNumPyBindings(),"requires numpy") + def test9(self): + sz=20 + a=array(0,dtype=float64) + a.resize(sz) + a[:]=4 + self.assertEqual(getrefcount(a),2) + a=a.cumsum(dtype=float64) + self.assertEqual(getrefcount(a),2) + d=DataArrayDouble(a) + d[:]=2 + # + e=DataArrayDouble(sz) ; e.fillWithValue(2) + self.assertTrue(d.isEqual(e,1e-14)) + # + a[:]=4 ; e.fillWithValue(4) + self.assertTrue(d.isEqual(e,1e-14)) + pass + + @unittest.skipUnless(MEDCouplingHasNumPyBindings(),"requires numpy") + def test10(self): + sz=20 + a=array(0,dtype=float64) + a.resize(sz,2) + self.assertEqual(getrefcount(a),2) + b=a.reshape(2*sz) + self.assertEqual(getrefcount(a),3) + self.assertEqual(getrefcount(b),2) + b[:]=5 + d=DataArrayDouble(b) + # + e=DataArrayDouble(sz*2) ; e.fillWithValue(5) + self.assertTrue(d.isEqual(e,1e-14)) + pass + + @unittest.skipUnless(MEDCouplingHasNumPyBindings(),"requires numpy") + def test11(self): + sz=10 + a=array(0,dtype=float64) + a.resize(sz,2) + b=a.reshape(2*sz) + c=a.reshape(2,sz) + b[:]=6 + b[7:17]=7 + d=DataArrayDouble(b) + self.assertTrue(d.isEqual(DataArrayDouble([6,6,6,6,6,6,6,7,7,7,7,7,7,7,7,7,7,6,6,6]),1e-14)) + # + a=zeros((10,2),dtype=float64) + b=a.T + c=b.view() + a.shape=20 + a[3:]=10. + d=DataArrayDouble(a) + self.assertTrue(d.isEqual(DataArrayDouble([0,0,0,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10]),1e-14)) + pass + + @unittest.skipUnless(MEDCouplingHasNumPyBindings(),"requires numpy") + def test12(self): + a=zeros(20,dtype=float64) + b = a[::-1] + self.assertRaises(InterpKernelException,DataArrayDouble.New,b) # b is not contiguous in memory + pass + + @unittest.skipUnless(MEDCouplingHasNumPyBindings(),"requires numpy") + def test13(self): + a=arange(20,dtype=float64) + self.assertEqual(weakref.getweakrefcount(a),0) + d=DataArrayDouble(a) + self.assertEqual(weakref.getweakrefcount(a),1) + self.assertTrue(not a.flags["OWNDATA"]) + self.assertTrue(d.isEqual(DataArrayDouble([0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19]),1e-14)) + self.assertEqual(len(d),20) + a[:]=2 # modifying a and d because a and d share the same chunk of data + self.assertTrue(d.isUniform(2,1e-14)) + del d # d is destroyed, a retrieves its ownership of its initial chunk of data + ##@@ Ensure a pass of the garbage collector so that the de-allocator of d is called + import gc + gc.collect() + self.assertTrue(a.flags["OWNDATA"]) + a[:]=4 # a can be used has usual + self.assertTrue(DataArrayDouble(a).isUniform(4,1e-14)) + pass + + @unittest.skipUnless(MEDCouplingHasNumPyBindings(),"requires numpy") + def test14(self): + a=arange(20,dtype=float64) + d=DataArrayDouble(a) # d owns data of a + e=DataArrayDouble(a) # a not owned -> e only an access to chunk of a + self.assertTrue(d.isEqual(DataArrayDouble([0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19]),1e-14)) + self.assertTrue(e.isEqual(DataArrayDouble([0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19]),1e-14)) + a[:]=6 + self.assertTrue(d.isUniform(6,1e-14)) + self.assertTrue(e.isUniform(6,1e-14)) + del a # a destroyed -> d no change because owned and e array is has no more data set + ##@@ Ensure a pass of the garbage collector so that the de-allocator of d is called + import gc + gc.collect() + self.assertTrue(d.isUniform(6,1e-14)) + self.assertTrue(not e.isAllocated()) + pass + + @unittest.skipUnless(MEDCouplingHasNumPyBindings(),"requires numpy") + def test15(self): + a=array(0,dtype=float64) ; a.resize(10,2) + b=a.reshape(20) + c=a.reshape(2,10) + d=DataArrayDouble(b) # d owns data of a + e=DataArrayDouble(b) # a not owned -> e only an access to chunk of a + f=DataArrayDouble(b) # a not owned -> e only an access to chunk of a + del d # d removed -> a ownes again data + ##@@ Ensure a pass of the garbage collector so that the de-allocator of d is called + import gc + gc.collect() + self.assertTrue(e.isUniform(0,1e-14)) + e[:]=6 + self.assertTrue(e.isUniform(6,1e-14)) + self.assertTrue(f.isUniform(6,1e-14)) + self.assertEqual(b.tolist(),[6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6]) + self.assertEqual(a.tolist(),[[6,6],[6,6],[6,6],[6,6],[6,6],[6,6],[6,6],[6,6],[6,6],[6,6]]) + b[:]=arange(20) + del b # no impact on e and f because a is the base of a. + ##@@ Ensure a pass of the garbage collector so that the de-allocator of d is called + gc.collect() + self.assertTrue(f.isEqual(DataArrayDouble([0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19]),1e-14)) + self.assertTrue(e.isEqual(DataArrayDouble([0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19]),1e-14)) + del a # a destroyed, but as c has its base set to a, a exists -> e and f not allocated + ##@@ Ensure a pass of the garbage collector so that the de-allocator of d is called + gc.collect() + self.assertTrue(f.isEqual(DataArrayDouble([0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19]),1e-14)) + self.assertTrue(e.isEqual(DataArrayDouble([0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19]),1e-14)) + del c # c killed -> a killed -> e and d are put into not allocated state + ##@@ Ensure a pass of the garbage collector so that the de-allocator of d is called + gc.collect() + self.assertTrue(not e.isAllocated()) + self.assertTrue(not f.isAllocated()) + pass + + @unittest.skipUnless(MEDCouplingHasNumPyBindings(),"requires numpy") + def test16(self): + a=arange(20,dtype=float64) + self.assertTrue(a.flags["OWNDATA"]) + d=DataArrayDouble(a) # d owns data of a + self.assertTrue(not a.flags["OWNDATA"]) + d.pushBackSilent(20)# d pushBack so release of chunk of data -> a becomes owner of its data again + self.assertTrue(a.flags["OWNDATA"]) + self.assertTrue(d.isEqual(DataArrayDouble([0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20]),1e-14)) + self.assertEqual(a.tolist(),[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19]) + pass + + @unittest.skipUnless(MEDCouplingHasNumPyBindings(),"requires numpy") + def test17(self): + d=DataArrayInt.Range(0,20,1) + a=d.toNumPyArray() + self.assertTrue(not a.flags["OWNDATA"]) + a[-2:]=100 + self.assertTrue(d.isEqual(DataArrayInt([0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,100,100]))) + self.assertEqual(a.tolist(),[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,100,100]) + del a + ##@@ Ensure a pass of the garbage collector so that the de-allocator of d is called + import gc + gc.collect() + self.assertTrue(d.isEqual(DataArrayInt([0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,100,100]))) + # + d.rearrange(2) + a=d.toNumPyArray() + self.assertTrue(not a.flags["OWNDATA"]) + a[-2:]=200 + self.assertTrue(d.isEqual(DataArrayInt([0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,200,200,200,200],10,2))) + self.assertEqual(a.tolist(),[[0,1],[2,3],[4,5],[6,7],[8,9],[10,11],[12,13],[14,15],[200,200],[200,200]]) + del a + ##@@ Ensure a pass of the garbage collector so that the de-allocator of d is called + gc.collect() + self.assertTrue(d.isEqual(DataArrayInt([0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,200,200,200,200],10,2))) + pass + + @unittest.skipUnless(MEDCouplingHasNumPyBindings(),"requires numpy") + def test18(self): + d=DataArrayInt.Range(0,20,1) + d=d.convertToDblArr() + a=d.toNumPyArray() + self.assertTrue(not a.flags["OWNDATA"]) + a[-2:]=100 + self.assertTrue(d.isEqual(DataArrayDouble([0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,100,100]),1e-14)) + self.assertEqual(a.tolist(),[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,100,100]) + del a + ##@@ Ensure a pass of the garbage collector so that the de-allocator of d is called + import gc + gc.collect() + self.assertTrue(d.isEqual(DataArrayDouble([0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,100,100]),1e-14)) + # + d.rearrange(2) + a=d.toNumPyArray() + self.assertTrue(not a.flags["OWNDATA"]) + a[-2:]=200 + self.assertTrue(d.isEqual(DataArrayDouble([0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,200,200,200,200],10,2),1e-14)) + self.assertEqual(a.tolist(),[[0,1],[2,3],[4,5],[6,7],[8,9],[10,11],[12,13],[14,15],[200,200],[200,200]]) + del a + ##@@ Ensure a pass of the garbage collector so that the de-allocator of d is called + gc.collect() + self.assertTrue(d.isEqual(DataArrayDouble([0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,200,200,200,200],10,2),1e-14)) + pass + + @unittest.skipUnless(MEDCouplingHasNumPyBindings(),"requires numpy") + def test19(self): + sz=20 + a=array(0,dtype=int32) + a.resize(sz/2,2) + a[:]=4 + self.assertEqual(getrefcount(a),2) + d=DataArrayInt(a) + self.assertEqual(10,d.getNumberOfTuples()) + self.assertEqual(2,d.getNumberOfComponents()) + self.assertEqual(sz,d.getNbOfElems()) + self.assertTrue(d.isEqual(DataArrayInt([(4,4),(4,4),(4,4),(4,4),(4,4),(4,4),(4,4),(4,4),(4,4),(4,4)]))) + a[:]=7 + self.assertTrue(d.isEqual(DataArrayInt([(7,7),(7,7),(7,7),(7,7),(7,7),(7,7),(7,7),(7,7),(7,7),(7,7)]))) + # + b=a.reshape((2,5,2)) + self.assertRaises(InterpKernelException,DataArrayInt.New,b) # b has not dimension in [0,1] ! + pass + + @unittest.skipUnless(MEDCouplingHasNumPyBindings(),"requires numpy") + def test20(self): + sz=20 + a=array(0,dtype=float64) + a.resize(sz/2,2) + a[:]=4 + self.assertEqual(getrefcount(a),2) + d=DataArrayDouble(a) + self.assertEqual(10,d.getNumberOfTuples()) + self.assertEqual(2,d.getNumberOfComponents()) + self.assertEqual(sz,d.getNbOfElems()) + self.assertTrue(d.isEqual(DataArrayDouble([(4.,4.),(4.,4.),(4.,4.),(4.,4.),(4.,4.),(4.,4.),(4.,4.),(4.,4.),(4.,4.),(4.,4.)]),1e-14)) + a[:]=7 + self.assertTrue(d.isEqual(DataArrayDouble([(7.,7.),(7.,7.),(7.,7.),(7.,7.),(7.,7.),(7.,7.),(7.,7.),(7.,7.),(7.,7.),(7.,7.)]),1e-14)) + # + b=a.reshape((2,5,2)) + self.assertRaises(InterpKernelException,DataArrayDouble.New,b) # b has not dimension in [0,1] ! + pass + + @unittest.skipUnless(MEDCouplingHasNumPyBindings(),"requires numpy") + def test21(self): + #tests that only DataArray*(npArray) contructor is available + a=array(0,dtype=int32) + a.resize(20) + DataArrayInt(a) + self.assertRaises(InterpKernelException,DataArrayInt.New,a,20) + self.assertRaises(InterpKernelException,DataArrayInt.New,a,20,1) + a=array(0,dtype=float64) + a.resize(20) + DataArrayDouble(a) + self.assertRaises(InterpKernelException,DataArrayDouble.New,a,20) + self.assertRaises(InterpKernelException,DataArrayDouble.New,a,20,1) + pass + + @unittest.skipUnless(MEDCouplingHasNumPyBindings(),"requires numpy") + def test22(self): + d=DataArrayDouble(10) + d.iota() + a=d.toNumPyArray() + self.assertTrue(not a.flags["OWNDATA"]) + del d + gc.collect() + self.assertTrue(a.flags["OWNDATA"]) + self.assertEqual(a.tolist(),[0.,1.,2.,3.,4.,5.,6.,7.,8.,9.]) + # + d=DataArrayInt(10) + d.iota() + a=d.toNumPyArray() + self.assertTrue(not a.flags["OWNDATA"]) + del d + gc.collect() + self.assertTrue(a.flags["OWNDATA"]) + self.assertEqual(a.tolist(),[0,1,2,3,4,5,6,7,8,9]) + pass + + @unittest.skipUnless(MEDCouplingHasNumPyBindings(),"requires numpy") + def test23(self): + d=DataArrayDouble(10) + d.iota() + a=d.toNumPyArray() + b=d.toNumPyArray() + c=d.toNumPyArray() + self.assertTrue(not a.flags["OWNDATA"]) + self.assertTrue(not b.flags["OWNDATA"]) + self.assertTrue(not c.flags["OWNDATA"]) + self.assertEqual(a.tolist(),[0.,1.,2.,3.,4.,5.,6.,7.,8.,9.]) + self.assertEqual(b.tolist(),[0.,1.,2.,3.,4.,5.,6.,7.,8.,9.]) + self.assertEqual(c.tolist(),[0.,1.,2.,3.,4.,5.,6.,7.,8.,9.]) + del d + gc.collect() + self.assertTrue(a.flags["OWNDATA"]) + self.assertTrue(not b.flags["OWNDATA"]) + self.assertTrue(not c.flags["OWNDATA"]) + self.assertEqual(a.tolist(),[0.,1.,2.,3.,4.,5.,6.,7.,8.,9.]) + self.assertEqual(b.tolist(),[0.,1.,2.,3.,4.,5.,6.,7.,8.,9.]) + self.assertEqual(c.tolist(),[0.,1.,2.,3.,4.,5.,6.,7.,8.,9.]) + # + d=DataArrayInt(10) + d.iota() + a=d.toNumPyArray() + b=d.toNumPyArray() + c=d.toNumPyArray() + self.assertTrue(not a.flags["OWNDATA"]) + self.assertTrue(not b.flags["OWNDATA"]) + self.assertTrue(not c.flags["OWNDATA"]) + self.assertEqual(a.tolist(),[0,1,2,3,4,5,6,7,8,9]) + self.assertEqual(b.tolist(),[0,1,2,3,4,5,6,7,8,9]) + self.assertEqual(c.tolist(),[0,1,2,3,4,5,6,7,8,9]) + del d + gc.collect() + self.assertTrue(a.flags["OWNDATA"]) + self.assertTrue(not b.flags["OWNDATA"]) + self.assertTrue(not c.flags["OWNDATA"]) + self.assertEqual(a.tolist(),[0,1,2,3,4,5,6,7,8,9]) + self.assertEqual(b.tolist(),[0,1,2,3,4,5,6,7,8,9]) + self.assertEqual(c.tolist(),[0,1,2,3,4,5,6,7,8,9]) + pass + + @unittest.skipUnless(MEDCouplingHasNumPyBindings(),"requires numpy") + def test24(self): + d=DataArrayDouble(10) + d.iota() + a=d.toNumPyArray() + self.assertEqual(a.tolist(),[0.,1.,2.,3.,4.,5.,6.,7.,8.,9.]) + self.assertTrue(not a.flags["OWNDATA"]) + self.assertTrue(a.base is None) + del a + gc.collect() + a=d.toNumPyArray() + self.assertEqual(a.tolist(),[0.,1.,2.,3.,4.,5.,6.,7.,8.,9.]) + self.assertTrue(not a.flags["OWNDATA"]) + self.assertTrue(a.base is None) + b=d.toNumPyArray() + self.assertEqual(a.tolist(),[0.,1.,2.,3.,4.,5.,6.,7.,8.,9.]) + self.assertEqual(b.tolist(),[0.,1.,2.,3.,4.,5.,6.,7.,8.,9.]) + self.assertTrue(not a.flags["OWNDATA"]) + self.assertTrue(not b.flags["OWNDATA"]) + self.assertTrue(b.base is a) + del a + gc.collect() + self.assertEqual(b.tolist(),[0.,1.,2.,3.,4.,5.,6.,7.,8.,9.]) + self.assertTrue(not b.flags["OWNDATA"]) + del d + gc.collect() + self.assertEqual(b.tolist(),[0.,1.,2.,3.,4.,5.,6.,7.,8.,9.]) + self.assertTrue(not b.flags["OWNDATA"]) + # + d=DataArrayInt(10) + d.iota() + a=d.toNumPyArray() + self.assertEqual(a.tolist(),[0,1,2,3,4,5,6,7,8,9]) + self.assertTrue(not a.flags["OWNDATA"]) + self.assertTrue(a.base is None) + del a + gc.collect() + a=d.toNumPyArray() + self.assertEqual(a.tolist(),[0,1,2,3,4,5,6,7,8,9]) + self.assertTrue(not a.flags["OWNDATA"]) + self.assertTrue(a.base is None) + b=d.toNumPyArray() + self.assertEqual(a.tolist(),[0,1,2,3,4,5,6,7,8,9]) + self.assertEqual(b.tolist(),[0,1,2,3,4,5,6,7,8,9]) + self.assertTrue(not a.flags["OWNDATA"]) + self.assertTrue(not b.flags["OWNDATA"]) + self.assertTrue(b.base is a) + del a + gc.collect() + self.assertEqual(b.tolist(),[0.,1.,2.,3.,4.,5.,6.,7.,8.,9.]) + self.assertTrue(not b.flags["OWNDATA"]) + del d + gc.collect() + self.assertEqual(b.tolist(),[0.,1.,2.,3.,4.,5.,6.,7.,8.,9.]) + self.assertTrue(not b.flags["OWNDATA"]) + pass + + @unittest.skipUnless(MEDCouplingHasNumPyBindings(),"requires numpy") + def test25(self): + a=arange(10,dtype=int32) + b=DataArrayInt(a) + c=DataArrayInt(a) + d=DataArrayInt(a) + self.assertTrue(b.isIdentity()) ; self.assertEqual(len(b),10) + self.assertTrue(c.isIdentity()) ; self.assertEqual(len(c),10) + self.assertTrue(d.isIdentity()) ; self.assertEqual(len(d),10) + c.pushBackSilent(10) # c and a,b are dissociated + self.assertTrue(b.isIdentity()) ; self.assertEqual(len(b),10) + self.assertTrue(c.isIdentity()) ; self.assertEqual(len(c),11) + self.assertTrue(d.isIdentity()) ; self.assertEqual(len(d),10) + del a + gc.collect() + self.assertTrue(b.isIdentity()) ; self.assertEqual(len(b),10) + self.assertTrue(c.isIdentity()) ; self.assertEqual(len(c),11) + self.assertTrue(not d.isAllocated()) + del b + gc.collect() + self.assertTrue(c.isIdentity()) ; self.assertEqual(len(c),11) + # + a=arange(10,dtype=int32) + b=DataArrayInt(a) + c=DataArrayInt(a) + self.assertTrue(b.isIdentity()) ; self.assertEqual(len(b),10) + self.assertTrue(c.isIdentity()) ; self.assertEqual(len(c),10) + b.pushBackSilent(10) # c and a,b are dissociated + self.assertTrue(b.isIdentity()) ; self.assertEqual(len(b),11) + self.assertTrue(c.isIdentity()) ; self.assertEqual(len(c),10) + del a + gc.collect() + self.assertTrue(b.isIdentity()) ; self.assertEqual(len(b),11) + self.assertTrue(not c.isAllocated()) + del b + gc.collect() + self.assertTrue(not c.isAllocated()) + # + a=float64(arange(5,dtype=int32)) + b=DataArrayDouble(a) + c=DataArrayDouble(a) + d=DataArrayDouble(a) + self.assertTrue(b.isEqual(DataArrayDouble([0.,1.,2.,3.,4.]),1e-12)) + self.assertTrue(c.isEqual(DataArrayDouble([0.,1.,2.,3.,4.]),1e-12)) + self.assertTrue(d.isEqual(DataArrayDouble([0.,1.,2.,3.,4.]),1e-12)) + c.pushBackSilent(10.) # c and a,b are dissociated + self.assertTrue(b.isEqual(DataArrayDouble([0.,1.,2.,3.,4.]),1e-12)) + self.assertTrue(c.isEqual(DataArrayDouble([0.,1.,2.,3.,4.,10.]),1e-12)) + self.assertTrue(d.isEqual(DataArrayDouble([0.,1.,2.,3.,4.]),1e-12)) + del a + gc.collect() + self.assertTrue(b.isEqual(DataArrayDouble([0.,1.,2.,3.,4.]),1e-12)) + self.assertTrue(c.isEqual(DataArrayDouble([0.,1.,2.,3.,4.,10.]),1e-12)) + self.assertTrue(not d.isAllocated()) + del b + gc.collect() + self.assertTrue(c.isEqual(DataArrayDouble([0.,1.,2.,3.,4.,10.]),1e-12)) + # + a=float64(arange(5,dtype=int32)) + b=DataArrayDouble(a) + c=DataArrayDouble(a) + self.assertTrue(b.isEqual(DataArrayDouble([0.,1.,2.,3.,4.]),1e-12)) + self.assertTrue(c.isEqual(DataArrayDouble([0.,1.,2.,3.,4.]),1e-12)) + b.pushBackSilent(10.) # c and a,b are dissociated + self.assertTrue(b.isEqual(DataArrayDouble([0.,1.,2.,3.,4.,10.]),1e-12)) + self.assertTrue(c.isEqual(DataArrayDouble([0.,1.,2.,3.,4.]),1e-12)) + del a + gc.collect() + self.assertTrue(b.isEqual(DataArrayDouble([0.,1.,2.,3.,4.,10.]),1e-12)) + self.assertTrue(not c.isAllocated()) + del b + gc.collect() + self.assertTrue(not c.isAllocated()) + pass + + @unittest.skipUnless(MEDCouplingHasNumPyBindings(),"requires numpy") + def test26(self): + d=DataArrayInt(15) ; d.iota() + d.rearrange(3) + a=d.toNumPyArray() + self.assertEqual(a.ndim,2) + self.assertEqual(a.size,15) + self.assertEqual(a.shape,(5,3)) + self.assertEqual(a.strides,(12,4)) + self.assertEqual(a.nbytes,60) + self.assertEqual(a.itemsize,4) + self.assertEqual(a.tolist(),[[0,1,2],[3,4,5],[6,7,8],[9,10,11],[12,13,14]]) + # + d2=d.convertToDblArr() + a2=d2.toNumPyArray() + self.assertEqual(a2.ndim,2) + self.assertEqual(a2.size,15) + self.assertEqual(a2.shape,(5,3)) + self.assertEqual(a2.strides,(24,8)) + self.assertEqual(a2.nbytes,120) + self.assertEqual(a2.itemsize,8) + self.assertEqual(a2.tolist(),[[0.,1.,2.],[3.,4.,5.],[6.,7.,8.],[9.,10.,11.],[12.,13.,14.]]) + pass + + @unittest.skipUnless(MEDCouplingHasNumPyBindings(),"requires numpy") + def test27(self): + m0=DenseMatrix(DataArrayDouble([2,3,4,5,1,6]),2,3) + m0np=m0.toNumPyMatrix() + self.assertEqual(m0np.shape,(2,3)) + self.assertEqual(m0np.tolist(),[[2.0,3.0,4.0],[5.0,1.0,6.0]]) + pass + + def setUp(self): + pass + pass + +#gc.set_debug(gc.DEBUG_LEAK) +unittest.main() diff --git a/src/medtool/src/MEDCoupling_Swig/MEDCouplingPickleTest.py b/src/medtool/src/MEDCoupling_Swig/MEDCouplingPickleTest.py new file mode 100644 index 000000000..677b11082 --- /dev/null +++ b/src/medtool/src/MEDCoupling_Swig/MEDCouplingPickleTest.py @@ -0,0 +1,300 @@ +# -*- coding: iso-8859-1 -*- +# Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 +# 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 +# + +from MEDCoupling import * +from MEDCouplingDataForTest import MEDCouplingDataForTest + +if MEDCouplingHasNumPyBindings(): + from numpy import * + pass + +from platform import architecture +from sys import getrefcount + +import os,gc,weakref,cPickle,unittest + +class MEDCouplingPickleTest(unittest.TestCase): + @unittest.skipUnless(MEDCouplingHasNumPyBindings(),"requires numpy") + def test1(self): + """ Test of a simple DataArrayDouble.""" + x=DataArrayDouble(10,1) ; x.iota() ; x.rearrange(2) ; x.setInfoOnComponents(["aa","bbb"]) + x.setName("toto") + pickled=cPickle.dumps(x,cPickle.HIGHEST_PROTOCOL) + xx=cPickle.loads(pickled) + self.assertTrue(xx.isEqual(x,1e-16)) + # Bigger to check that the behavior is OK for large strings. + x=DataArrayDouble(1200) ; x.iota() ; x.setInfoOnComponents(["aa"]) + x.setName("titi") + pickled=cPickle.dumps(x,cPickle.HIGHEST_PROTOCOL) + xx=cPickle.loads(pickled) + self.assertTrue(xx.isEqual(x,1e-16)) + pass + + @unittest.skipUnless(MEDCouplingHasNumPyBindings(),"requires numpy") + def test2(self): + """ Test of a simple DataArrayInt.""" + x=DataArrayInt(10) ; x.iota() ; x.rearrange(2) ; x.setInfoOnComponents(["aa","bbb"]) + x.setName("toto") + pickled=cPickle.dumps(x,cPickle.HIGHEST_PROTOCOL) + xx=cPickle.loads(pickled) + self.assertTrue(xx.isEqual(x)) + # Bigger to check that the behavior is OK for large strings. + x=DataArrayInt(1200) ; x.iota() ; x.setInfoOnComponents(["aa"]) + x.setName("titi") + pickled=cPickle.dumps(x,cPickle.HIGHEST_PROTOCOL) + xx=cPickle.loads(pickled) + self.assertTrue(xx.isEqual(x)) + pass + + @unittest.skipUnless(MEDCouplingHasNumPyBindings(),"requires numpy") + def test3(self): + """ Test of a MEDCouplingUMesh pickeling.""" + arr=DataArrayDouble(10) ; arr.iota() + m=MEDCouplingCMesh() ; m.setCoords(arr,arr,arr) + m=m.buildUnstructured() + m.setName("mesh") + m.getCoords().setInfoOnComponents(["aa","bbb","ddddd"]) + m.checkCoherency() + st=cPickle.dumps(m,cPickle.HIGHEST_PROTOCOL) + m2=cPickle.loads(st) + self.assertTrue(m2.isEqual(m,1e-16)) + pass + + @unittest.skipUnless(MEDCouplingHasNumPyBindings(),"requires numpy") + def test4(self): + """ Idem test3 except that here serialization/deserialization is done explicitely.""" + arr=DataArrayDouble(10) ; arr.iota() + m=MEDCouplingCMesh() ; m.setCoords(arr,arr,arr) + m=m.buildUnstructured() + m.setName("mesh") + m.getCoords().setInfoOnComponents(["aa","bbb","ddddd"]) + m.checkCoherency() + # + a0,a1,a2=m.getTinySerializationInformation() + b0,b1=m.serialize() + m2=MEDCouplingUMesh() + m2.unserialization(a0,a1,b0,b1,a2); + self.assertTrue(m2.isEqual(m,1e-16)) + pass + + @unittest.skipUnless(MEDCouplingHasNumPyBindings(),"requires numpy") + def test5(self): + """ Test of a MEDCouplingCMesh pickeling.""" + arrX=DataArrayDouble(10) ; arrX.iota() ; arrX.setInfoOnComponents(["aa"]) + arrY=DataArrayDouble(5) ; arrY.iota() ; arrY.setInfoOnComponents(["bbb"]) + arrZ=DataArrayDouble(7) ; arrZ.iota() ; arrZ.setInfoOnComponents(["cccc"]) + # + m=MEDCouplingCMesh() ; m.setCoords(arrX,arrY,arrZ) + m.setName("mesh") + m.checkCoherency() + st=cPickle.dumps(m,cPickle.HIGHEST_PROTOCOL) + m2=cPickle.loads(st) + self.assertTrue(m2.isEqual(m,1e-16)) + self.assertTrue(m2.getCoordsAt(0).isEqual(arrX,1e-16)) + pass + + @unittest.skipUnless(MEDCouplingHasNumPyBindings(),"requires numpy") + def test6(self): + """ Test of a MEDCoupling1SGTUMesh pickeling.""" + arr=DataArrayDouble(10) ; arr.iota() + m=MEDCouplingCMesh() ; m.setCoords(arr,arr) + m=m.build1SGTUnstructured() + self.assertTrue(isinstance(m,MEDCoupling1SGTUMesh)) + st=cPickle.dumps(m,cPickle.HIGHEST_PROTOCOL) + m2=cPickle.loads(st) + self.assertTrue(m2.isEqual(m,1e-16)) + pass + + @unittest.skipUnless(MEDCouplingHasNumPyBindings(),"requires numpy") + def test7(self): + """ Test of a MEDCoupling1DGTUMesh pickeling.""" + arr=DataArrayDouble(10) ; arr.iota() + m=MEDCouplingCMesh() ; m.setCoords(arr,arr) + m=m.buildUnstructured() ; m.convertAllToPoly() + m=MEDCoupling1DGTUMesh(m) + self.assertTrue(isinstance(m,MEDCoupling1DGTUMesh)) + st=cPickle.dumps(m,cPickle.HIGHEST_PROTOCOL) + m2=cPickle.loads(st) + self.assertTrue(m2.isEqual(m,1e-16)) + pass + + @unittest.skipUnless(MEDCouplingHasNumPyBindings(),"requires numpy") + def test8(self): + """ Test of a MEDCouplingExtrudedMesh pickeling.""" + arrX=DataArrayDouble(10) ; arrX.iota() ; arrX.setInfoOnComponents(["aa"]) + arrY=DataArrayDouble(5) ; arrY.iota() ; arrY.setInfoOnComponents(["bbb"]) + arrZ=DataArrayDouble(7) ; arrZ.iota() ; arrZ.setInfoOnComponents(["cccc"]) + m=MEDCouplingCMesh() ; m.setCoords(arrX,arrY,arrZ) + mesh3D=m.buildUnstructured() ; del m + # + m=MEDCouplingCMesh() ; m.setCoords(arrX,arrY) + mesh2D=m.buildUnstructured() ; del m + # + mesh2D.setCoords(mesh3D.getCoords()) + mesh=MEDCouplingExtrudedMesh(mesh3D,mesh2D,0) ; del mesh3D,mesh2D + self.assertTrue(isinstance(mesh,MEDCouplingExtrudedMesh)) + st=cPickle.dumps(mesh,cPickle.HIGHEST_PROTOCOL) + m2=cPickle.loads(st) + self.assertTrue(m2.isEqual(mesh,1e-16)) + pass + + @unittest.skipUnless(MEDCouplingHasNumPyBindings(),"requires numpy") + def test9(self): + """ Test of a MEDCouplingCurveLinearMesh pickeling.""" + arrX=DataArrayDouble(10) ; arrX.iota() ; arrX.setInfoOnComponents(["aa"]) + arrY=DataArrayDouble(5) ; arrY.iota() ; arrY.setInfoOnComponents(["bbb"]) + m=MEDCouplingCMesh() ; m.setCoords(arrX,arrY) + m=m.buildUnstructured() + # + mesh=MEDCouplingCurveLinearMesh() ; mesh.setCoords(m.getCoords()) ; del m + mesh.setNodeGridStructure([10,5]) + st=cPickle.dumps(mesh,cPickle.HIGHEST_PROTOCOL) + m2=cPickle.loads(st) + self.assertTrue(m2.isEqual(mesh,1e-16)) + pass + + @unittest.skipUnless(MEDCouplingHasNumPyBindings(),"requires numpy") + def test10(self): + """ Test of a MEDCouplingIMesh pickeling.""" + m=MEDCouplingIMesh("mesh",3,DataArrayInt([3,1,4]),DataArrayDouble([1.5,2.5,3.5]),DataArrayDouble((0.5,1.,0.25))) ; m.setAxisUnit("km") + m.checkCoherency() + st=cPickle.dumps(m,cPickle.HIGHEST_PROTOCOL) + m2=cPickle.loads(st) + self.assertTrue(m2.isEqual(m,1e-16)) + self.assertEqual(m2.getName(),m.getName()) + pass + + @unittest.skipUnless(MEDCouplingHasNumPyBindings(),"requires numpy") + def test11(self): + """ Test of MEDCouplingFieldDouble lying on MEDCouplingCMesh pickeling. """ + arrX=DataArrayDouble(10) ; arrX.iota() ; arrX.setInfoOnComponents(["aa"]) + arrY=DataArrayDouble(5) ; arrY.iota() ; arrY.setInfoOnComponents(["bbb"]) + m=MEDCouplingCMesh() ; m.setCoords(arrX,arrY) + f=m.getMeasureField(True) + f.setName("aname") + a=f.getArray() + b=a[:] ; b.iota(7000.) + f.setArray(DataArrayDouble.Meld(a,b)) + f.getArray().setInfoOnComponents(["u1","vv2"]) + f.checkCoherency(); + # + st=cPickle.dumps(f,cPickle.HIGHEST_PROTOCOL) + f2=cPickle.loads(st) + self.assertTrue(f2.isEqual(f,1e-16,1e-16)) + self.assertTrue(f2.getMesh().isEqual(f.getMesh(),1e-16)) + pass + + @unittest.skipUnless(MEDCouplingHasNumPyBindings(),"requires numpy") + def test12(self): + """ Test of MEDCouplingFieldDouble on Gauss Points lying on MEDCouplingUMesh pickeling.""" + _a=0.446948490915965; + _b=0.091576213509771; + _p1=0.11169079483905; + _p2=0.0549758718227661; + refCoo1=[ 0.,0., 1.,0., 0.,1. ] + gsCoo1=[ 2*_b-1, 1-4*_b, 2*_b-1, 2.07*_b-1, 1-4*_b, + 2*_b-1, 1-4*_a, 2*_a-1, 2*_a-1, 1-4*_a, 2*_a-1, 2*_a-1 ] + wg1=[ 4*_p2, 4*_p2, 4*_p2, 4*_p1, 4*_p1, 4*_p1 ] + _refCoo1=refCoo1 + _gsCoo1=gsCoo1 + _wg1=wg1 + # + m=MEDCouplingDataForTest.build2DTargetMesh_1(); + f=MEDCouplingFieldDouble.New(ON_GAUSS_PT,NO_TIME); + f.setMesh(m); + self.assertEqual(5,f.getNumberOfMeshPlacesExpected()); + self.assertEqual(0,f.getNbOfGaussLocalization()); + f.setGaussLocalizationOnType(NORM_TRI3,_refCoo1,_gsCoo1,_wg1); + f.setGaussLocalizationOnType(NORM_TRI3,_refCoo1,_gsCoo1,_wg1); # not a bug only to check that it works well + self.assertRaises(InterpKernelException,f.setGaussLocalizationOnType,NORM_QUAD4,_refCoo1,_gsCoo1,_wg1) + self.assertEqual(1,f.getNbOfGaussLocalization()); + refCoo2=[ 0.,0., 1.,0., 1.,1., 0.,1. ] + _refCoo2=refCoo2 + _gsCoo1=_gsCoo1[0:4] + _wg1=_wg1[0:2] + f.setGaussLocalizationOnType(NORM_QUAD4,_refCoo2,_gsCoo1,_wg1); + self.assertEqual(2,f.getNbOfGaussLocalization()); + array=DataArrayDouble.New(); + ptr=18*2*[None] + for i in xrange(18*2): + ptr[i]=float(i+1) + array.setValues(ptr,18,2); + ptr=array.getPointer(); + f.setArray(array); + f.setName("MyFirstFieldOnGaussPoint"); + f.checkCoherency(); + self.assertAlmostEqual(27.,f.getIJK(2,5,0),14); + self.assertAlmostEqual(16.,f.getIJK(1,5,1),14); + # + f.clearGaussLocalizations(); + self.assertEqual(0,f.getNbOfGaussLocalization()); + self.assertRaises(InterpKernelException,f.checkCoherency); + ids1=[0,1,3,4] + self.assertRaises(InterpKernelException,f.setGaussLocalizationOnCells,ids1,_refCoo2,_gsCoo1,_wg1); + self.assertEqual(0,f.getNbOfGaussLocalization()); + ids2=[0,4] + f.setGaussLocalizationOnCells(ids2,_refCoo2,_gsCoo1,_wg1); + self.assertEqual(1,f.getNbOfGaussLocalization()); + self.assertEqual(0,f.getGaussLocalizationIdOfOneCell(0)); + self.assertRaises(InterpKernelException,f.getGaussLocalizationIdOfOneCell,1); + ids3=[1,2] + f.setGaussLocalizationOnCells(ids3,_refCoo1,_gsCoo1,_wg1); + self.assertEqual(2,f.getNbOfGaussLocalization()); + self.assertEqual(0,f.getGaussLocalizationIdOfOneCell(0)); + self.assertEqual(1,f.getGaussLocalizationIdOfOneCell(1)); + self.assertEqual(1,f.getGaussLocalizationIdOfOneCell(2)); + self.assertRaises(InterpKernelException,f.checkCoherency);#<- cell 3 has no localization + ids4=[3] + _gsCoo2=_gsCoo1; + _wg2=_wg1; + _gsCoo2[0]=0.8888777776666; + _wg2[0]=0.1234567892377; + f.setGaussLocalizationOnCells(ids4,_refCoo2,_gsCoo2,_wg2); + self.assertEqual(3,f.getNbOfGaussLocalization()); + tmpIds=f.getCellIdsHavingGaussLocalization(0); + self.assertEqual(ids2,list(tmpIds.getValues())); + self.assertRaises(InterpKernelException,f.checkCoherency);#<- it's always not ok because undelying array not with the good size. + array2=f.getArray().substr(0,10); + f.setArray(array2); + f.checkCoherency(); + #### + st=cPickle.dumps(f,cPickle.HIGHEST_PROTOCOL) + f2=cPickle.loads(st) + self.assertTrue(f2.isEqual(f,1e-16,1e-16)) + self.assertTrue(f2.getMesh().isEqual(f.getMesh(),1e-16)) + pass + + def test13(self): + eStr="This is an exception." + e=InterpKernelException(eStr) + self.assertEqual(e.what(),eStr) + st=cPickle.dumps(e,cPickle.HIGHEST_PROTOCOL) + e2=cPickle.loads(st) + self.assertTrue(e is not e2) + self.assertTrue(isinstance(e2,InterpKernelException)) + self.assertEqual(e2.what(),eStr) + pass + + def setUp(self): + pass + pass + +if __name__=="__main__": + unittest.main() diff --git a/src/medtool/src/MEDCoupling_Swig/MEDCouplingRefCountObject.i b/src/medtool/src/MEDCoupling_Swig/MEDCouplingRefCountObject.i new file mode 100644 index 000000000..48003ef55 --- /dev/null +++ b/src/medtool/src/MEDCoupling_Swig/MEDCouplingRefCountObject.i @@ -0,0 +1,168 @@ +// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 +// 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) + +namespace INTERP_KERNEL +{ + class Exception + { + public: + Exception(const char* what); + ~Exception() throw (); + const char *what() const throw (); + %extend + { + std::string __str__() const + { + return std::string(self->what()); + } + } + }; +} + +namespace ParaMEDMEM +{ + class TimeLabel + { + public: + void declareAsNew() const; + virtual void updateTime() const; + unsigned int getTimeOfThis() const; + protected: + ~TimeLabel(); + }; +} + +namespace ParaMEDMEM +{ + typedef enum + { + C_DEALLOC = 2, + CPP_DEALLOC = 3 + } DeallocType; + + const char *MEDCouplingVersionStr(); + int MEDCouplingVersion(); + int MEDCouplingSizeOfVoidStar(); + bool MEDCouplingByteOrder(); + const char *MEDCouplingByteOrderStr(); + + class BigMemoryObject + { + public: + std::size_t getHeapMemorySize() const throw(INTERP_KERNEL::Exception); + std::string getHeapMemorySizeStr() const throw(INTERP_KERNEL::Exception); + bool isObjectInTheProgeny(const BigMemoryObject *obj) const throw(INTERP_KERNEL::Exception); + virtual std::size_t getHeapMemorySizeWithoutChildren() const throw(INTERP_KERNEL::Exception); + virtual ~BigMemoryObject(); + %extend + { + virtual PyObject *getDirectChildren() const throw(INTERP_KERNEL::Exception) + { + std::vector<const BigMemoryObject *> c(self->getDirectChildren()); + PyObject *ret(PyList_New(c.size())); + for(std::size_t i=0;i<c.size();i++) + PyList_SetItem(ret,i,SWIG_NewPointerObj(SWIG_as_voidptr(c[i]),SWIGTYPE_p_ParaMEDMEM__BigMemoryObject, 0 | 0 )); + return ret; + } + + PyObject *getAllTheProgeny() const throw(INTERP_KERNEL::Exception) + { + std::vector<const BigMemoryObject *> c(self->getAllTheProgeny()); + PyObject *ret(PyList_New(c.size())); + for(std::size_t i=0;i<c.size();i++) + PyList_SetItem(ret,i,SWIG_NewPointerObj(SWIG_as_voidptr(c[i]),SWIGTYPE_p_ParaMEDMEM__BigMemoryObject, 0 | 0 )); + return ret; + } + + static std::size_t GetHeapMemorySizeOfObjs(PyObject *objs) throw(INTERP_KERNEL::Exception) + { + std::vector<const BigMemoryObject *> cppObjs; + convertFromPyObjVectorOfObj<const ParaMEDMEM::BigMemoryObject *>(objs,SWIGTYPE_p_ParaMEDMEM__BigMemoryObject,"BigMemoryObject",cppObjs); + return BigMemoryObject::GetHeapMemorySizeOfObjs(cppObjs); + } + } + }; + + class RefCountObjectOnly + { + public: + bool decrRef() const; + void incrRef() const; + int getRCValue() const; + protected: + ~RefCountObjectOnly(); + }; + + class RefCountObject : public RefCountObjectOnly, public BigMemoryObject + { + protected: + ~RefCountObject(); + }; +} + +%inline +{ + PyObject *MEDCouplingVersionMajMinRel() + { + int tmp0=0,tmp1=0,tmp2=0; + MEDCouplingVersionMajMinRel(tmp0,tmp1,tmp2); + PyObject *res = PyList_New(3); + PyList_SetItem(res,0,SWIG_From_int(tmp0)); + PyList_SetItem(res,1,SWIG_From_int(tmp1)); + PyList_SetItem(res,2,SWIG_From_int(tmp2)); + return res; + } + + bool MEDCouplingHasNumPyBindings() + { +#ifdef WITH_NUMPY + return true; +#else + return false; +#endif + } + + bool MEDCouplingHasSciPyBindings() + { +#ifdef WITH_SCIPY + return true; +#else + return false; +#endif + } + + std::string MEDCouplingCompletionScript() throw(INTERP_KERNEL::Exception) + { + static const char script[]="import rlcompleter,readline\nreadline.parse_and_bind('tab:complete')"; + std::ostringstream oss; oss << "MEDCouplingCompletionScript : error when trying to activate completion ! readline not present ?\nScript is :\n" << script; + if(PyRun_SimpleString(script)!=0) + throw INTERP_KERNEL::Exception(oss.str().c_str()); + return std::string(script); + } +} + +%pythoncode %{ +def INTERPKERNELExceptionReduceFunct(a,b): + ret=InterpKernelException.__new__(a) + ret.__init__(*b) + return ret +def INTERPKERNELExceptionReduce(self): + return INTERPKERNELExceptionReduceFunct,(InterpKernelException,(self.what(),)) +%} diff --git a/src/medtool/src/MEDCoupling_Swig/MEDCouplingRemapper.i b/src/medtool/src/MEDCoupling_Swig/MEDCouplingRemapper.i new file mode 100644 index 000000000..135958b88 --- /dev/null +++ b/src/medtool/src/MEDCoupling_Swig/MEDCouplingRemapper.i @@ -0,0 +1,222 @@ +// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 +// 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 +// + +%module MEDCouplingRemapper + +#define MEDCOUPLING_EXPORT +#define INTERPKERNEL_EXPORT +#define MEDCOUPLINGREMAPPER_EXPORT + +%{ +#include "MEDCouplingMemArray.hxx" +#include "MEDCouplingUMesh.hxx" +#include "MEDCouplingField.hxx" +#include "MEDCouplingFieldDouble.hxx" +#include "MEDCouplingRemapper.hxx" + +using namespace ParaMEDMEM; +using namespace INTERP_KERNEL; +%} + +%newobject ParaMEDMEM::MEDCouplingRemapper::transferField; +%newobject ParaMEDMEM::MEDCouplingRemapper::reverseTransferField; + +%include "MEDCouplingCommon.i" +%include "InterpolationOptions.hxx" + +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 + { + private: + void updateTime() const; + public: + MEDCouplingRemapper(); + ~MEDCouplingRemapper(); + int prepare(const MEDCouplingMesh *srcMesh, const MEDCouplingMesh *targetMesh, const std::string& method) throw(INTERP_KERNEL::Exception); + int prepareEx(const MEDCouplingFieldTemplate *src, const MEDCouplingFieldTemplate *target) throw(INTERP_KERNEL::Exception); + void transfer(const MEDCouplingFieldDouble *srcField, MEDCouplingFieldDouble *targetField, double dftValue) throw(INTERP_KERNEL::Exception); + void partialTransfer(const MEDCouplingFieldDouble *srcField, MEDCouplingFieldDouble *targetField) throw(INTERP_KERNEL::Exception); + void reverseTransfer(MEDCouplingFieldDouble *srcField, const MEDCouplingFieldDouble *targetField, double dftValue) throw(INTERP_KERNEL::Exception); + MEDCouplingFieldDouble *transferField(const MEDCouplingFieldDouble *srcField, double dftValue) throw(INTERP_KERNEL::Exception); + MEDCouplingFieldDouble *reverseTransferField(const MEDCouplingFieldDouble *targetField, double dftValue) throw(INTERP_KERNEL::Exception); + bool setOptionInt(const std::string& key, int value) throw(INTERP_KERNEL::Exception); + bool setOptionDouble(const std::string& key, double value) throw(INTERP_KERNEL::Exception); + bool setOptionString(const std::string& key, const std::string& value) throw(INTERP_KERNEL::Exception); + int getInterpolationMatrixPolicy() const throw(INTERP_KERNEL::Exception); + void setInterpolationMatrixPolicy(int newInterpMatPol) throw(INTERP_KERNEL::Exception); + // + int nullifiedTinyCoeffInCrudeMatrixAbs(double maxValAbs) throw(INTERP_KERNEL::Exception); + int nullifiedTinyCoeffInCrudeMatrix(double scaleFactor) throw(INTERP_KERNEL::Exception); + double getMaxValueInCrudeMatrix() const throw(INTERP_KERNEL::Exception); + int getNumberOfColsOfMatrix() const throw(INTERP_KERNEL::Exception); + static std::string BuildMethodFrom(const std::string& meth1, const std::string& meth2) throw(INTERP_KERNEL::Exception); + %extend + { + PyObject *getCrudeMatrix() const throw(INTERP_KERNEL::Exception) + { + const std::vector<std::map<int,double> >& m=self->getCrudeMatrix(); + std::size_t sz=m.size(); + PyObject *ret=PyList_New(sz); + for(std::size_t i=0;i<sz;i++) + { + const std::map<int,double>& row=m[i]; + PyObject *ret0=PyDict_New(); + for(std::map<int,double>::const_iterator it=row.begin();it!=row.end();it++) + PyDict_SetItem(ret0,PyInt_FromLong((*it).first),PyFloat_FromDouble((*it).second)); + PyList_SetItem(ret,i,ret0); + } + return ret; + } +#if defined(WITH_NUMPY) && defined(WITH_SCIPY) + PyObject *getCrudeCSRMatrix() const throw(INTERP_KERNEL::Exception) + { + return ToCSRMatrix(self->getCrudeMatrix(),self->getNumberOfColsOfMatrix()); + } +#endif + } + }; +} + +%pythoncode %{ +def ParaMEDMEMDataArrayDoublenew(cls,*args): + import _MEDCouplingRemapper + return _MEDCouplingRemapper.DataArrayDouble____new___(cls,args) +def ParaMEDMEMDataArrayDoubleIadd(self,*args): + import _MEDCouplingRemapper + return _MEDCouplingRemapper.DataArrayDouble____iadd___(self, self, *args) +def ParaMEDMEMDataArrayDoubleIsub(self,*args): + import _MEDCouplingRemapper + return _MEDCouplingRemapper.DataArrayDouble____isub___(self, self, *args) +def ParaMEDMEMDataArrayDoubleImul(self,*args): + import _MEDCouplingRemapper + return _MEDCouplingRemapper.DataArrayDouble____imul___(self, self, *args) +def ParaMEDMEMDataArrayDoubleIdiv(self,*args): + import _MEDCouplingRemapper + return _MEDCouplingRemapper.DataArrayDouble____idiv___(self, self, *args) +def ParaMEDMEMDataArrayDoubleIpow(self,*args): + import _MEDCouplingRemapper + return _MEDCouplingRemapper.DataArrayDouble____ipow___(self, self, *args) +def ParaMEDMEMMEDCouplingFieldDoublenew(cls,*args): + import _MEDCouplingRemapper + return _MEDCouplingRemapper.MEDCouplingFieldDouble____new___(cls,args) +def ParaMEDMEMMEDCouplingFieldDoubleIadd(self,*args): + import _MEDCouplingRemapper + return _MEDCouplingRemapper.MEDCouplingFieldDouble____iadd___(self, self, *args) +def ParaMEDMEMMEDCouplingFieldDoubleIsub(self,*args): + import _MEDCouplingRemapper + return _MEDCouplingRemapper.MEDCouplingFieldDouble____isub___(self, self, *args) +def ParaMEDMEMMEDCouplingFieldDoubleImul(self,*args): + import _MEDCouplingRemapper + return _MEDCouplingRemapper.MEDCouplingFieldDouble____imul___(self, self, *args) +def ParaMEDMEMMEDCouplingFieldDoubleIdiv(self,*args): + import _MEDCouplingRemapper + return _MEDCouplingRemapper.MEDCouplingFieldDouble____idiv___(self, self, *args) +def ParaMEDMEMMEDCouplingFieldDoubleIpow(self,*args): + import _MEDCouplingRemapper + return _MEDCouplingRemapper.MEDCouplingFieldDouble____ipow___(self, self, *args) +def ParaMEDMEMDataArrayIntnew(cls,*args): + import _MEDCouplingRemapper + return _MEDCouplingRemapper.DataArrayInt____new___(cls,args) +def ParaMEDMEMDataArrayIntnew(cls,*args): + import _MEDCoupling + return _MEDCoupling.DataArrayInt____new___(cls,args) +def ParaMEDMEMDataArrayIntIadd(self,*args): + import _MEDCouplingRemapper + return _MEDCouplingRemapper.DataArrayInt____iadd___(self, self, *args) +def ParaMEDMEMDataArrayIntIsub(self,*args): + import _MEDCouplingRemapper + return _MEDCouplingRemapper.DataArrayInt____isub___(self, self, *args) +def ParaMEDMEMDataArrayIntImul(self,*args): + import _MEDCouplingRemapper + return _MEDCouplingRemapper.DataArrayInt____imul___(self, self, *args) +def ParaMEDMEMDataArrayIntIdiv(self,*args): + import _MEDCouplingRemapper + return _MEDCouplingRemapper.DataArrayInt____idiv___(self, self, *args) +def ParaMEDMEMDataArrayIntImod(self,*args): + import _MEDCouplingRemapper + return _MEDCouplingRemapper.DataArrayInt____imod___(self, self, *args) +def ParaMEDMEMDataArrayIntIpow(self,*args): + import _MEDCouplingRemapper + return _MEDCouplingRemapper.DataArrayInt____ipow___(self, self, *args) +def ParaMEDMEMDataArrayDoubleTupleIadd(self,*args): + import _MEDCouplingRemapper + return _MEDCouplingRemapper.DataArrayDoubleTuple____iadd___(self, self, *args) +def ParaMEDMEMDataArrayDoubleTupleIsub(self,*args): + import _MEDCouplingRemapper + return _MEDCouplingRemapper.DataArrayDoubleTuple____isub___(self, self, *args) +def ParaMEDMEMDataArrayDoubleTupleImul(self,*args): + import _MEDCouplingRemapper + return _MEDCouplingRemapper.DataArrayDoubleTuple____imul___(self, self, *args) +def ParaMEDMEMDataArrayDoubleTupleIdiv(self,*args): + import _MEDCouplingRemapper + return _MEDCouplingRemapper.DataArrayDoubleTuple____idiv___(self, self, *args) +def ParaMEDMEMDataArrayIntTupleIadd(self,*args): + import _MEDCouplingRemapper + return _MEDCouplingRemapper.DataArrayIntTuple____iadd___(self, self, *args) +def ParaMEDMEMDataArrayIntTupleIsub(self,*args): + import _MEDCouplingRemapper + return _MEDCouplingRemapper.DataArrayIntTuple____isub___(self, self, *args) +def ParaMEDMEMDataArrayIntTupleImul(self,*args): + import _MEDCouplingRemapper + return _MEDCouplingRemapper.DataArrayIntTuple____imul___(self, self, *args) +def ParaMEDMEMDataArrayIntTupleIdiv(self,*args): + import _MEDCouplingRemapper + return _MEDCouplingRemapper.DataArrayIntTuple____idiv___(self, self, *args) +def ParaMEDMEMDataArrayIntTupleImod(self,*args): + import _MEDCouplingRemapper + return _MEDCouplingRemapper.DataArrayIntTuple____imod___(self, self, *args) +def ParaMEDMEMDenseMatrixIadd(self,*args): + import _MEDCouplingRemapper + return _MEDCouplingRemapper.DenseMatrix____iadd___(self, self, *args) +def ParaMEDMEMDenseMatrixIsub(self,*args): + import _MEDCouplingRemapper + return _MEDCouplingRemapper.DenseMatrix____isub___(self, self, *args) +def ParaMEDMEMMEDCouplingUMeshnew(cls,*args): + import _MEDCouplingRemapper + return _MEDCouplingRemapper.MEDCouplingUMesh____new___(cls,args) +def ParaMEDMEMMEDCoupling1DGTUMeshnew(cls,*args): + import _MEDCouplingRemapper + return _MEDCouplingRemapper.MEDCoupling1DGTUMesh____new___(cls,args) +def ParaMEDMEMMEDCoupling1SGTUMeshnew(cls,*args): + import _MEDCouplingRemapper + return _MEDCouplingRemapper.MEDCoupling1SGTUMesh____new___(cls,args) +def ParaMEDMEMMEDCouplingCurveLinearMeshnew(cls,*args): + import _MEDCouplingRemapper + return _MEDCouplingRemapper.MEDCouplingCurveLinearMesh____new___(cls,args) +def ParaMEDMEMMEDCouplingCMeshnew(cls,*args): + import _MEDCouplingRemapper + return _MEDCouplingRemapper.MEDCouplingCMesh____new___(cls,args) +def ParaMEDMEMMEDCouplingIMeshnew(cls,*args): + import _MEDCouplingRemapper + return _MEDCouplingRemapper.MEDCouplingIMesh____new___(cls,args) +def ParaMEDMEMMEDCouplingExtrudedMeshnew(cls,*args): + import _MEDCouplingRemapper + return _MEDCouplingRemapper.MEDCouplingExtrudedMesh____new___(cls,args) +%} + +%include "MEDCouplingFinalize.i" diff --git a/src/medtool/src/MEDCoupling_Swig/MEDCouplingRemapperTest.py b/src/medtool/src/MEDCoupling_Swig/MEDCouplingRemapperTest.py new file mode 100644 index 000000000..ba5ba6428 --- /dev/null +++ b/src/medtool/src/MEDCoupling_Swig/MEDCouplingRemapperTest.py @@ -0,0 +1,907 @@ +# -*- coding: iso-8859-1 -*- +# Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 +# 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 +# + +from MEDCouplingDataForTest import MEDCouplingDataForTest +from MEDCouplingRemapper import * +from math import * +import unittest + +class MEDCouplingBasicsTest(unittest.TestCase): + def testRemapper1(self): + sourceMesh=self.build2DSourceMesh_1(); + targetMesh=self.build2DTargetMesh_1(); + remapper=MEDCouplingRemapper() + remapper.setPrecision(1e-12); + remapper.setIntersectionType(Triangulation); + self.failUnless(remapper.prepare(sourceMesh,targetMesh,"P0P0")==1); + srcField=MEDCouplingFieldDouble.New(ON_CELLS); + srcField.setNature(ConservativeVolumic); + srcField.setMesh(sourceMesh); + array=DataArrayDouble.New(); + ptr=sourceMesh.getNumberOfCells()*[None] + for i in xrange(sourceMesh.getNumberOfCells()): + ptr[i]=float(i+7) + pass + array.setValues(ptr,sourceMesh.getNumberOfCells(),1); + srcField.setArray(array); + srcField.setName("abc") ; srcField.setDescription("def") + srcField.setTime(7.7,9,10) + trgfield=remapper.transferField(srcField,4.57); + self.assertEqual("abc",trgfield.getName()) + self.assertEqual("def",trgfield.getDescription()) + a,b,c=trgfield.getTime() + self.assertAlmostEqual(7.7,a,14) + self.assertEqual(b,9) + self.assertEqual(c,10) + values=trgfield.getArray().getValues(); + valuesExpected=[7.5 ,7. ,7.,8.,7.5]; + for i in xrange(targetMesh.getNumberOfCells()): + self.failUnless(abs(values[i]-valuesExpected[i])<1e-12); + pass + self.failUnless(1==trgfield.getArray().getNumberOfComponents()); + pass + + def testPrepareEx1(self): + sourceMesh=self.build2DSourceMesh_1(); + targetMesh=self.build2DTargetMesh_3(); + # + remapper=MEDCouplingRemapper(); + remapper.setPrecision(1e-12); + remapper.setIntersectionType(Triangulation); + srcFt=MEDCouplingFieldTemplate.New(ON_CELLS); + trgFt=MEDCouplingFieldTemplate.New(ON_CELLS); + srcFt.setMesh(sourceMesh); + trgFt.setMesh(targetMesh); + self.assertEqual(1,remapper.prepareEx(srcFt,trgFt)); + srcField=MEDCouplingFieldDouble.New(ON_CELLS); + srcField.setNature(ConservativeVolumic); + srcField.setMesh(sourceMesh); + array=DataArrayDouble.New(); + ptr=sourceMesh.getNumberOfCells()*[None] + for i in xrange(sourceMesh.getNumberOfCells()): + ptr[i]=float(i+7); + pass + array.setValues(ptr,sourceMesh.getNumberOfCells(),1); + srcField.setArray(array); + trgfield=remapper.transferField(srcField,4.220173); + values=trgfield.getArray().getValues(); + valuesExpected=[7.75, 7.0625, 4.220173,8.0] + self.assertEqual(4,trgfield.getArray().getNumberOfTuples()); + self.assertEqual(1,trgfield.getArray().getNumberOfComponents()); + for i0 in xrange(4): + self.assertAlmostEqual(valuesExpected[i0],values[i0],12); + pass + pass + + def testPartialTransfer1(self): + sourceMesh=self.build2DSourceMesh_1(); + targetMesh=self.build2DTargetMesh_3(); + # + remapper=MEDCouplingRemapper(); + remapper.setPrecision(1e-12); + remapper.setIntersectionType(Triangulation); + srcFt=MEDCouplingFieldTemplate.New(ON_CELLS); + trgFt=MEDCouplingFieldTemplate.New(ON_CELLS); + srcFt.setMesh(sourceMesh); + trgFt.setMesh(targetMesh); + self.assertEqual(1,remapper.prepareEx(srcFt,trgFt)); + srcField=MEDCouplingFieldDouble.New(ON_CELLS); + srcField.setNature(ConservativeVolumic); + srcField.setMesh(sourceMesh); + array=DataArrayDouble.New(); + ptr=sourceMesh.getNumberOfCells()*[None] + for i in xrange(sourceMesh.getNumberOfCells()): + ptr[i]=float(i+7); + pass + array.setValues(ptr,sourceMesh.getNumberOfCells(),1); + srcField.setArray(array); + trgfield=MEDCouplingFieldDouble.New(ON_CELLS); + trgfield.setNature(ConservativeVolumic); + trgfield.setMesh(targetMesh); + array=DataArrayDouble.New(); + ptr=targetMesh.getNumberOfCells()*[None] + for i in xrange(targetMesh.getNumberOfCells()): + ptr[i]=4.220173; + pass + array.setValues(ptr,targetMesh.getNumberOfCells(),1); + trgfield.setArray(array); + remapper.partialTransfer(srcField,trgfield); + values=trgfield.getArray().getValues(); + valuesExpected=[7.75, 7.0625, 4.220173,8.0] + self.assertEqual(4,trgfield.getArray().getNumberOfTuples()); + self.assertEqual(1,trgfield.getArray().getNumberOfComponents()); + for i0 in xrange(4): + self.assertAlmostEqual(valuesExpected[i0],values[i0],12); + pass + pass + + def testPrepareUC(self): + # 1D + coords=DataArrayDouble([0.,0.5,0.7]) + src=MEDCouplingUMesh("",1) ; src.setCoords(coords) + src.allocateCells(2) ; src.insertNextCell(NORM_SEG2,[0,1]) ; src.insertNextCell(NORM_SEG2,[1,2]) ; src.finishInsertingCells() + trg=MEDCouplingCMesh() ; arr=DataArrayDouble([-0.7,-0.1,0.2,0.7,2.,2.3]) + trg.setCoordsAt(0,arr) + fieldSrc=MEDCouplingFieldDouble(ON_CELLS,NO_TIME) ; fieldSrc.setMesh(src) ; arrSrc=DataArrayDouble([10.,30.]) + fieldSrc.setNature(Integral) ; fieldSrc.setArray(arrSrc) + rem=MEDCouplingRemapper() + rem.prepare(src,trg,"P0P0") + trgField=rem.transferField(fieldSrc,-7.) + expected1=[-7.,4.,36.,-7.,-7.] + self.assertEqual(5,trgField.getArray().getNumberOfTuples()) + self.assertEqual(5,len(expected1)) + for i,val in enumerate(expected1): + self.assertAlmostEqual(expected1[i],trgField.getArray().getIJ(i,0),12); + pass + # 2D + coords=DataArrayDouble([0.,0.,0.,1.,1.,1.,1.,0.,0.5,-0.2],5,2) + src=MEDCouplingUMesh("",2) ; src.setCoords(coords) + src.allocateCells(2) ; src.insertNextCell(NORM_TRI3,[0,1,2]) ; src.insertNextCell(NORM_TRI3,[3,4,0]) ; src.finishInsertingCells() + trg=MEDCouplingCMesh() ; arr=DataArrayDouble([-0.7,-0.1,0.2,0.7,2.,2.3]) + trg.setCoordsAt(0,arr) ; trg.setCoordsAt(1,arr) + fieldSrc=MEDCouplingFieldDouble(ON_CELLS,NO_TIME) ; fieldSrc.setMesh(src) ; arrSrc=DataArrayDouble([10.,30.]) + fieldSrc.setNature(Integral) ; fieldSrc.setArray(arrSrc) + rem=MEDCouplingRemapper() + rem.prepare(src,trg,"P0P0") + trgField=rem.transferField(fieldSrc,-7.) + expected2=[-7.,-7.,7.35,0.15,-7.,-7.,2.8,14.85,5.25,-7.,-7.,2.,2.5,-7.,-7.,-7.,1.2,3.,0.9,-7.,-7.,-7.,-7.,-7.,-7.] + self.assertEqual(25,trgField.getArray().getNumberOfTuples()) + self.assertEqual(25,len(expected2)) + for i,val in enumerate(expected2): + self.assertAlmostEqual(expected2[i],trgField.getArray().getIJ(i,0),12); + pass + # 3D + coords=DataArrayDouble([0.,0.,0.,0.,1.,0.,1.,1.,0.,1.,0.,0.,0.5,-0.2,0.,0.1,0.8,1.,0.5,0.,1.],7,3) + src=MEDCouplingUMesh("",3) ; src.setCoords(coords) + src.allocateCells(2) ; src.insertNextCell(NORM_TETRA4,[0,1,2,5]) ; src.insertNextCell(NORM_TETRA4,[3,4,0,6]) ; src.finishInsertingCells() + trg=MEDCouplingCMesh() ; arr=DataArrayDouble([-0.7,-0.1,0.2,0.7,2.,2.3]) ; arr2=DataArrayDouble([-0.7,0.2,0.6,1.2,2.]) + trg.setCoordsAt(0,arr) ; trg.setCoordsAt(1,arr) ; trg.setCoordsAt(2,arr2) + src.checkCoherency2(1e-10) + trg.checkCoherency() + fieldSrc=MEDCouplingFieldDouble(ON_CELLS,NO_TIME) ; fieldSrc.setMesh(src) ; arrSrc=DataArrayDouble([10.,30.]) + fieldSrc.setNature(Integral) ; fieldSrc.setArray(arrSrc) + rem=MEDCouplingRemapper() + rem.prepare(src,trg,"P0P0") + trgField=rem.transferField(fieldSrc,-7.) + expected3=[-7.,-7.,2.925,0.015,-7.,-7.,0.9392,8.595,2.265,-7.,-7.,1.1008,1.1192,-7.,-7.,-7.,0.6392,1.6408,0.2808,-7.,-7.,-7.,-7.,-7.,-7.,-7.,-7.,0.81,-7.,-7.,-7.,0.1208,11.55,0.96,-7.,-7.,1.1752,0.6592,-7.,-7.,-7.,0.8512,1.7744,0.0192,-7.,-7.,-7.,-7.,-7.,-7.,-7.,-7.,-7.,-7.,-7.,-7.,-7.,1.92,-7.,-7.,-7.,0.12578571428571422,0.007314285714285673,-7.,-7.,-7.,0.3189253968253971,0.1879746031746033,-7.,-7.,-7.,-7.,-7.,-7.,-7.,-7.,-7.,-7.,-7.,-7.,-7.,-7.,-7.,-7.,-7.,-7.,-7.,-7.,-7.,-7.,-7.,-7.,-7.,-7.,-7.,-7.,-7.,-7.,-7.,-7.] + self.assertEqual(100,trgField.getArray().getNumberOfTuples()) + self.assertEqual(100,len(expected3)) + for i,val in enumerate(expected3): + self.assertAlmostEqual(expected3[i],trgField.getArray().getIJ(i,0),12); + pass + pass + + def testPrepareCU(self): + # 1D + coords=DataArrayDouble([0.,0.5,0.7]) + trg=MEDCouplingUMesh("",1) ; trg.setCoords(coords) + trg.allocateCells(2) ; trg.insertNextCell(NORM_SEG2,[0,1]) ; trg.insertNextCell(NORM_SEG2,[1,2]) ; trg.finishInsertingCells() + src=MEDCouplingCMesh() ; arr=DataArrayDouble([-0.7,-0.1,0.2,0.7,2.,2.3]) + src.setCoordsAt(0,arr) + fieldSrc=MEDCouplingFieldDouble(ON_CELLS,NO_TIME) ; fieldSrc.setMesh(src) ; arrTrg=DataArrayDouble([10.,30.,40.,70.,80.]) + fieldSrc.setNature(Integral) ; fieldSrc.setArray(arrTrg) + rem=MEDCouplingRemapper() + rem.prepare(src,trg,"P0P0") + trgField=rem.transferField(fieldSrc,-7.) + expected1=[44.,16.] + self.assertEqual(2.,trgField.getArray().getNumberOfTuples()) + self.assertEqual(2,len(expected1)) + for i,val in enumerate(expected1): + self.assertAlmostEqual(expected1[i],trgField.getArray().getIJ(i,0),12); + pass + # 2D + coords=DataArrayDouble([0.,0.,0.,1.,1.,1.,1.,0.,0.5,-0.2],5,2) + trg=MEDCouplingUMesh("",2) ; trg.setCoords(coords) + trg.allocateCells(2) ; trg.insertNextCell(NORM_TRI3,[0,1,2]) ; trg.insertNextCell(NORM_TRI3,[3,4,0]) ; trg.finishInsertingCells() + src=MEDCouplingCMesh() ; arr=DataArrayDouble([-0.7,-0.1,0.2,0.7,2.,2.3]) + src.setCoordsAt(0,arr) ; src.setCoordsAt(1,arr) + fieldSrc=MEDCouplingFieldDouble(ON_CELLS,NO_TIME) ; fieldSrc.setMesh(src) ; arrSrc=DataArrayDouble([10.,30.,40.,70.,80.,110.,130.,140.,170.,180.,210.,230.,240.,270.,280.,310.,330.,340.,370.,380.,410.,430.,440.,470.,480.]) + fieldSrc.setNature(Integral) ; fieldSrc.setArray(arrSrc) + rem=MEDCouplingRemapper() + rem.prepare(src,trg,"P0P0") + trgField=rem.transferField(fieldSrc,-7.) + expected2=[441.3050624589086,68.69529914529915] + self.assertEqual(2,trgField.getArray().getNumberOfTuples()) + self.assertEqual(2,len(expected2)) + for i,val in enumerate(expected2): + self.assertAlmostEqual(expected2[i],trgField.getArray().getIJ(i,0),12); + pass + # 3D + coords=DataArrayDouble([0.,0.,0.,0.,1.,0.,1.,1.,0.,1.,0.,0.,0.5,-0.2,0.,0.1,0.8,1.,0.5,0.,1.],7,3) + trg=MEDCouplingUMesh("",3) ; trg.setCoords(coords) + trg.allocateCells(2) ; trg.insertNextCell(NORM_TETRA4,[0,1,2,5]) ; trg.insertNextCell(NORM_TETRA4,[3,4,0,6]) ; trg.finishInsertingCells() + src=MEDCouplingCMesh() ; arr=DataArrayDouble([-0.7,-0.1,0.2,0.7,2.,2.3]) ; arr2=DataArrayDouble([-0.7,0.2,0.6,1.2,2.]) + src.setCoordsAt(0,arr) ; src.setCoordsAt(1,arr) ; src.setCoordsAt(2,arr2) + trg.checkCoherency2(1e-10) + src.checkCoherency() + fieldSrc=MEDCouplingFieldDouble(ON_CELLS,NO_TIME) ; fieldSrc.setMesh(src) ; arrSrc=DataArrayDouble(100) ; arrSrc.iota(7.7) + fieldSrc.setNature(Integral) ; fieldSrc.setArray(arrSrc) + rem=MEDCouplingRemapper() + rem.prepare(src,trg,"P0P0") + trgField=rem.transferField(fieldSrc,-7.) + expected3=[39.635196634558845,12.13422356758468] + self.assertEqual(2,trgField.getArray().getNumberOfTuples()) + self.assertEqual(2,len(expected3)) + for i,val in enumerate(expected3): + self.assertAlmostEqual(expected3[i],trgField.getArray().getIJ(i,0),12); + pass + pass + + def testPrepareCC(self): + # 1D + src=MEDCouplingCMesh() ; arr=DataArrayDouble([-0.7,-0.1,0.2,0.7,2.,2.3]) + src.setCoordsAt(0,arr) + trg=MEDCouplingCMesh() ; arr=DataArrayDouble([-0.9,-0.1,0.15]) + trg.setCoordsAt(0,arr) + fieldSrc=MEDCouplingFieldDouble(ON_CELLS,NO_TIME) ; fieldSrc.setMesh(src) ; arrTrg=DataArrayDouble([10.,30.,40.,70.,80.]) + fieldSrc.setNature(Integral) ; fieldSrc.setArray(arrTrg) + rem=MEDCouplingRemapper() + rem.prepare(src,trg,"P0P0") + trgField=rem.transferField(fieldSrc,-7.) + expected1=[10.,25.] + self.assertEqual(2.,trgField.getArray().getNumberOfTuples()) + self.assertEqual(2,len(expected1)) + for i,val in enumerate(expected1): + self.assertAlmostEqual(expected1[i],trgField.getArray().getIJ(i,0),12); + pass + # 2D + src=MEDCouplingCMesh() ; arr=DataArrayDouble([-0.7,-0.1,0.2,0.7,2.,2.3]) + src.setCoordsAt(0,arr) ; src.setCoordsAt(1,arr) + trg=MEDCouplingCMesh() ; arr=DataArrayDouble([-0.9,-0.1,0.15]) + trg.setCoordsAt(0,arr) ; trg.setCoordsAt(1,arr) + fieldSrc=MEDCouplingFieldDouble(ON_CELLS,NO_TIME) ; fieldSrc.setMesh(src) ; arrSrc=DataArrayDouble([10.,30.,40.,70.,80.,110.,130.,140.,170.,180.,210.,230.,240.,270.,280.,310.,330.,340.,370.,380.,410.,430.,440.,470.,480.]) + fieldSrc.setNature(Integral) ; fieldSrc.setArray(arrSrc) + rem=MEDCouplingRemapper() + rem.prepare(src,trg,"P0P0") + trgField=rem.transferField(fieldSrc,-7.) + expected2=[10.,25.,91.66666666666666,90.27777777777777] + self.assertEqual(4,trgField.getArray().getNumberOfTuples()) + self.assertEqual(4,len(expected2)) + for i,val in enumerate(expected2): + self.assertAlmostEqual(expected2[i],trgField.getArray().getIJ(i,0),12); + pass + # 3D + src=MEDCouplingCMesh() ; arr=DataArrayDouble([-0.7,-0.1,0.2,0.7,2.,2.3]) + src.setCoordsAt(0,arr) ; src.setCoordsAt(1,arr) ; src.setCoordsAt(2,arr) + trg=MEDCouplingCMesh() ; arr=DataArrayDouble([-0.9,-0.1,0.15]) + trg.setCoordsAt(0,arr) ; trg.setCoordsAt(1,arr) ; trg.setCoordsAt(2,arr) + fieldSrc=MEDCouplingFieldDouble(ON_CELLS,NO_TIME) ; fieldSrc.setMesh(src) ; arrSrc=DataArrayDouble(125) ; arrSrc.iota(7.7) + fieldSrc.setNature(Integral) ; fieldSrc.setArray(arrSrc) ; fieldSrc.checkCoherency() + rem=MEDCouplingRemapper() + rem.prepare(src,trg,"P0P0") + trgField=rem.transferField(fieldSrc,-7.) + expected3=[7.7, 7.249999999999999, 10.583333333333332, 9.513888888888886, 27.25, 23.40277777777777, 26.180555555555546, 22.39583333333333] + self.assertEqual(8,trgField.getArray().getNumberOfTuples()) + self.assertEqual(8,len(expected3)) + for i,val in enumerate(expected3): + self.assertAlmostEqual(expected3[i],trgField.getArray().getIJ(i,0),12); + pass + pass + + # Bug when source mesh is not homogeneously oriented in source mesh + def testNonRegressionNonHomegenousOrriented3DCells(self): + csrc=DataArrayDouble([-0.15240000188350677,0,0,-0.1086929515004158,0,0,-0.15240000188350677,0.018142856657505035,0,-0.13054648041725159,0.0090714283287525177,0.019050000235438347,-0.13054648041725159,0.0090714283287525177,0],5,3) + src1=MEDCouplingUMesh("src",3) ; src1.allocateCells(0) ; src1.insertNextCell(NORM_TETRA4,[0,1,4,3]) ; src1.insertNextCell(NORM_TETRA4,[2,0,4,3]) + src2=MEDCouplingUMesh("src",3) ; src2.allocateCells(0) ; src2.insertNextCell(NORM_TETRA4,[0,4,1,3]) ; src2.insertNextCell(NORM_TETRA4,[2,0,4,3]) + src1.setCoords(csrc) ; src2.setCoords(csrc) + ctrg=DataArrayDouble([-0.15240000188350677,-0.038100000470876694,0,0.32379999756813049,-0.038100000470876694,0,-0.15240000188350677,0.076200000941753387,0,0.32379999756813049,0.076200000941753387,0,-0.15240000188350677,-0.038100000470876694,0.076200000941753387,0.32379999756813049,-0.038100000470876694,0.076200000941753387,-0.15240000188350677,0.076200000941753387,0.076200000941753387,0.32379999756813049,0.076200000941753387,0.076200000941753387],8,3) + trg=MEDCouplingUMesh("trg",3) ; trg.allocateCells(0) ; trg.insertNextCell(NORM_HEXA8,[0,1,3,2,4,5,7,6]) + trg.setCoords(ctrg) + rem1=MEDCouplingRemapper() ; rem1.setSplittingPolicy(PLANAR_FACE_5) ; rem1.prepare(src1,trg,"P0P0") + rem2=MEDCouplingRemapper() ; rem2.setSplittingPolicy(PLANAR_FACE_5) ; rem2.prepare(src1,trg,"P0P0") + mat1=rem1.getCrudeMatrix() ; mat2=rem2.getCrudeMatrix() + self.assertEqual(1,len(mat1)) ; self.assertEqual(1,len(mat2)) + self.assertEqual(mat1[0].keys(),mat2[0].keys()) ; self.assertEqual([0,1],mat1[0].keys()) + self.assertAlmostEqual(1.25884108122e-06,mat1[0][0],16) ; self.assertAlmostEqual(1.25884108122e-06,mat2[0][0],16) + self.assertAlmostEqual(1.25884086663e-06,mat1[0][1],16) ; self.assertAlmostEqual(1.25884086663e-06,mat2[0][1],16) + # + d=DataArrayDouble([13.45,27.67],2,1) + f1=MEDCouplingFieldDouble(ON_CELLS,ONE_TIME) ; f1.setMesh(src1) ; f1.setArray(d) ; f1.setNature(RevIntegral) + f2=MEDCouplingFieldDouble(ON_CELLS,ONE_TIME) ; f2.setMesh(src2) ; f2.setArray(d) ; f2.setNature(RevIntegral) + f11=rem1.transferField(f1,1e300) ; f22=rem2.transferField(f2,1e300) + expected1=DataArrayDouble([0.012480539537637884]) + self.assertTrue(f11.getArray().isEqual(expected1,1e-15)) + self.assertTrue(f22.getArray().isEqual(expected1,1e-15)) + # + f1.setNature(Integral) ; f2.setNature(Integral) + f11=rem1.transferField(f1,1e300) ; f22=rem2.transferField(f2,1e300) + # + expected2=DataArrayDouble([41.12]) + self.assertTrue(f11.getArray().isEqual(expected2,1e-13)) + self.assertTrue(f22.getArray().isEqual(expected2,1e-13)) + pass + + def testCellToNodeReverse3D(self): + c=DataArrayDouble([0.,1.,2.5]) + cc=MEDCouplingCMesh() + cc.setCoords(c,c,c) + um=cc.buildUnstructured() + f=um.getMeasureField(ON_CELLS) + # + n2o=um.simplexize(PLANAR_FACE_5) + f.setArray(f.getArray()[n2o]) + f.checkCoherency() + f.setNature(ConservativeVolumic) + f.setTime(5.6,7,8) + f.setName("toto") ; f.setDescription("aDescription") + p=MEDCouplingRemapper() + p.setIntersectionType(Barycentric) + p.prepare(um,um,"P1P0") + fNode=p.reverseTransferField(f,1e300) + self.assertEqual("toto",fNode.getName()) + self.assertEqual("aDescription",fNode.getDescription()) + a,b,c=fNode.getTime() + self.assertAlmostEqual(5.6,a,14) + self.assertEqual(7,b) ; self.assertEqual(8,c) + # + integExpected=34.328125 + self.assertAlmostEqual(fNode.integral(False)[0],integExpected,14) + self.assertAlmostEqual(f.integral(False)[0],integExpected,14) + pass + + def testGauss2Gauss2DValidated(self): + srcFt=MEDCouplingDataForTest.buildFieldOnGauss_1() + trgFt=MEDCouplingDataForTest.buildFieldOnGauss_2() + src=MEDCouplingFieldDouble(srcFt) + self.assertEqual(srcFt.getMesh().getHiddenCppPointer(),src.getMesh().getHiddenCppPointer()) + self.assertEqual(srcFt.getDiscretization().getHiddenCppPointer(),src.getDiscretization().getHiddenCppPointer()) + #values given by ASTER usecase + src.setArray(DataArrayDouble([1.,1.,0.,0.,1.,1.,1.,1.,0.,0.,1.,1.,1.,1.,1.,1.,0.,0.,0.,0.,1.,1.,1.,1.,1.,1.,1.,1.,0.,0.,0.,0.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,0.,0.,0.,0.,0.,0.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,0.,0.,0.,0.,0.,0.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,0.,0.,0.,0.,0.,0.,0.,0.,0.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,0.,0.,0.,0.,0.,0.,0.,0.,0.,1.,1.,1.,1.,1.,1.,1.,1.,1.])) + src.getArray().setInfoOnComponents(["DOMA"]) + rem=MEDCouplingRemapper() + rem.setIntersectionType(PointLocator) + rem.prepareEx(srcFt,trgFt) + trg=rem.transferField(src,1e300) + self.assertEqual(trg.getMesh().getHiddenCppPointer(),trgFt.getMesh().getHiddenCppPointer()) + self.assertEqual(trg.getDiscretization().getHiddenCppPointer(),trgFt.getDiscretization().getHiddenCppPointer()) + #values given after interpolation in ASTER + arrExpected=DataArrayDouble([1.,1.,1.,0.,0.,0.,1.,1.,1.,1.,1.,0.,0.,0.,1.,1.,1.,1.,1.,0.,0.,0.,1.,1.,1.,1.,1.,0.,0.,0.,1.,1.,1.,1.,1.,0.,0.,0.,1.,1.,1.,1.,1.,1.,1.,0.,0.,1.,0.,1.,1.,0.,1.,1.,1.,1.,1.,1.,1.,1.,1.,0.,0.,1.,0.,1.,1.,0.,1.,1.,1.,1.,1.,1.,1.,1.,1.,0.,0.,1.,0.,1.,1.,0.,1.,1.,1.,1.,1.,1.,1.,1.,1.,0.,0.,1.,0.,1.,1.,0.,1.,1.,1.,1.,1.,1.,1.,1.,1.,0.,0.,1.,0.,1.,1.,0.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,0.,1.,0.,0.,0.,0.,1.,1.,1.,0.,0.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,0.,1.,0.,0.,0.,0.,1.,1.,1.,0.,0.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,0.,1.,0.,0.,0.,0.,1.,1.,1.,0.,0.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,0.,1.,0.,0.,0.,0.,1.,1.,1.,0.,0.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,0.,1.,0.,0.,0.,0.,1.,1.,1.,0.,0.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,0.,0.,1.,0.,0.,0.,1.,0.,0.,1.,1.,0.,0.,1.,0.,0.,0.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,0.,0.,1.,0.,0.,0.,1.,0.,0.,1.,1.,0.,0.,1.,0.,0.,0.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,0.,0.,1.,0.,0.,0.,1.,0.,0.,1.,1.,0.,0.,1.,0.,0.,0.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,0.,0.,1.,0.,0.,0.,1.,0.,0.,1.,1.,0.,0.,1.,0.,0.,0.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,0.,0.,1.,0.,0.,0.,1.,0.,0.,1.,1.,0.,0.,1.,0.,0.,0.,1.,1.,1.,1.,1.,1.,1.,1.,1.]) ; arrExpected.setInfoOnComponents(["DOMA"]) + self.assertTrue(trg.getArray().isEqual(arrExpected,1e-12)) + # + # second part of the test : reverse source and target + # + rem.prepareEx(trgFt,srcFt)# sorry trgFt is in the place of source and srcFt in the place of target it is not a bug + trg=MEDCouplingFieldDouble(trgFt) + #values given after interpolation in ASTER + trg.setArray(DataArrayDouble([1.,1.,0.,0.,1.,0.,1.,1.,1.,1.,0.,0.,1.,0.,1.,1.,1.,1.,0.,0.,1.,0.,1.,1.,1.,1.,0.,0.,1.,0.,1.,1.,1.,1.,0.,0.,1.,0.,1.,1.,1.,1.,1.,1.,1.,0.,0.,1.,0.,1.,1.,0.,1.,1.,1.,1.,1.,1.,1.,1.,1.,0.,0.,1.,0.,1.,1.,0.,1.,1.,1.,1.,1.,1.,1.,1.,1.,0.,0.,1.,0.,1.,1.,0.,1.,1.,1.,1.,1.,1.,1.,1.,1.,0.,0.,1.,0.,1.,1.,0.,1.,1.,1.,1.,1.,1.,1.,1.,1.,0.,0.,1.,0.,1.,1.,0.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,0.,1.,0.,0.,0.,0.,1.,1.,0.,0.,0.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,0.,1.,0.,0.,0.,0.,1.,1.,0.,0.,0.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,0.,1.,0.,0.,0.,0.,1.,1.,0.,0.,0.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,0.,1.,0.,0.,0.,0.,1.,1.,0.,0.,0.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,0.,1.,0.,0.,0.,0.,1.,1.,0.,0.,0.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,0.,0.,1.,0.,0.,0.,1.,0.,0.,1.,1.,0.,0.,1.,0.,0.,0.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,0.,0.,1.,0.,0.,0.,1.,0.,0.,1.,1.,0.,0.,1.,0.,0.,0.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,0.,0.,1.,0.,0.,0.,1.,0.,0.,1.,1.,0.,0.,1.,0.,0.,0.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,0.,0.,1.,0.,0.,0.,1.,0.,0.,1.,1.,0.,0.,1.,0.,0.,0.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,0.,0.,1.,0.,0.,0.,1.,0.,0.,1.,1.,0.,0.,1.,0.,0.,0.,1.,1.,1.,1.,1.,1.,1.,1.,1.])) + trg.getArray().setInfoOnComponents(["DOMA"]) + src=rem.transferField(trg,1e300) + #values given after interpolation in ASTER + arrExpected2=DataArrayDouble([1.,1.,0.,0.,1.,1.,1.,1.,0.,0.,1.,1.,1.,1.,1.,1.,0.,0.,0.,0.,1.,1.,1., 1.,1.,1.,1.,1.,0.,0.,0.,0.,0.,1.,1.,1.,1.,1.,1.,1.,1.,1.,0.,0.,0.,0.,0.,0.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,0.,0.,0.,0.,0.,0.,1.,1.,1.,1.,1.,1.,1.,1.,0.,1.,1.,0.,1.,1.,1.,1.,0.,0.,0.,0.,1.,0.,0.,0.,1.,1.,1.,0.,1.,1.,1.,1.,1.,1.,0.,0.,1.,1.,0.,1.,1.,1.,0.,1.,0.,0.,0.,1.,0.,0.,0.,1.,1.,1.,0.,1.,1.,1.,1.,1.]) ; arrExpected2.setInfoOnComponents(["DOMA"]) + # modification of values in ASTER due to modification of algorithm + # target PG 82 in target cell 32(C)/36 PG 1(C)/9 is in source cell 58(C)/120 source Gauss point 113 (1(C)/4). Values must be 1. and not 0. + arrExpected2.setIJ(82,0,1.) + self.assertTrue(src.getArray().isEqual(arrExpected2,1e-12)) + pass + + def testGauss2Gauss3DValidated(self): + srcFt=MEDCouplingDataForTest.buildFieldOnGauss_3() + trgFt=MEDCouplingDataForTest.buildFieldOnGauss_4() + src=MEDCouplingFieldDouble(srcFt) + self.assertEqual(srcFt.getMesh().getHiddenCppPointer(),src.getMesh().getHiddenCppPointer()) + self.assertEqual(srcFt.getDiscretization().getHiddenCppPointer(),src.getDiscretization().getHiddenCppPointer()) + #values given by ASTER usecase + src.setArray(DataArrayDouble([0.,1.,1.,1.,1.,1.,0.,0.,0.,0.,0.,0.,0.,0.,0.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,0.,0.,0.,0.,0.,1.,1.,0.,0.,1.,1.,1.,1.,0.,0.,1.,1.,0.,0.])) + src.getArray().setInfoOnComponents(["DOMA"]) + rem=MEDCouplingRemapper() + rem.setIntersectionType(PointLocator) + rem.prepareEx(srcFt,trgFt) + trg=rem.transferField(src,1e300) + self.assertEqual(trg.getMesh().getHiddenCppPointer(),trgFt.getMesh().getHiddenCppPointer()) + self.assertEqual(trg.getDiscretization().getHiddenCppPointer(),trgFt.getDiscretization().getHiddenCppPointer()) + #values given after interpolation in ASTER + arrExpected=DataArrayDouble([0.,1.,1.,1.,1.,1.,0.,0.,0.,0.,0.,0.,0.,0.,0.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,0.,1.,0.,0.,0.,1.,1.,0.,0.,1.,1.,1.,1.,0.,1.,1.,1.,0.,1.]) ; arrExpected.setInfoOnComponents(["DOMA"]) + self.assertTrue(trg.getArray().isEqual(arrExpected,1e-12)) + # + # second part of the test : reverse source and target + # + rem.prepareEx(trgFt,srcFt)# sorry trgFt is in the place of source and srcFt in the place of target it is not a bug + trg=MEDCouplingFieldDouble(trgFt) + #values given after interpolation in ASTER + trg.setArray(DataArrayDouble([0.,1.,1.,1.,1.,1.,0.,0.,0.,0.,0.,0.,0.,0.,0.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,0.,0.,1.,1.,0.,0.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.])) + trg.getArray().setInfoOnComponents(["DOMA"]) + src=rem.transferField(trg,1e300) + #values given after interpolation in ASTER + arrExpected2=DataArrayDouble([0.,1.,1.,1.,1.,1.,0.,0.,0.,0.,0.,0.,0.,0.,0.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,1.,0.,1.,0.,1.,0.,1.,1.,1.,0.,1.,1.,1.,1.,0.,1.,1.,1.,0.,1.]) ; arrExpected2.setInfoOnComponents(["DOMA"]) + self.assertTrue(src.getArray().isEqual(arrExpected2,1e-12)) + pass + + def testSwig2MixOfUMesh(self): + arr0=DataArrayDouble([0,1,1.5]) ; arr1=DataArrayDouble([0,1]) + sc=MEDCouplingCMesh() ; sc.setCoords(arr0,arr1,arr1) + tc=sc.deepCpy() ; tc.translate([0.4,0.3,0.3]) + # umesh-umesh + # 90 (umesh-1sgtumesh) + rem=MEDCouplingRemapper() ; rem.setIntersectionType(Triangulation) + s=sc.buildUnstructured() ; t=tc.build1SGTUnstructured() + self.assertTrue(isinstance(s,MEDCouplingUMesh)) + self.assertTrue(isinstance(t,MEDCoupling1SGTUMesh)) + rem.prepare(s,t,"P0P0") + mat=rem.getCrudeMatrix() + self.assertEqual(2,len(mat)) ; self.assertEqual(2,len(mat[0])) ; self.assertEqual(1,len(mat[1])) + self.assertAlmostEqual(0.294,mat[0][0],14) ; self.assertAlmostEqual(0.196,mat[0][1],14) ; self.assertAlmostEqual(0.049,mat[1][1],14) + del s,t + # 91 (umesh-1dgtumesh) + rem=MEDCouplingRemapper() ; rem.setIntersectionType(Triangulation) + s=sc.buildUnstructured() ; t=tc.buildUnstructured() ; t.convertAllToPoly() ; t=MEDCoupling1DGTUMesh(t) + self.assertTrue(isinstance(s,MEDCouplingUMesh)) + self.assertTrue(isinstance(t,MEDCoupling1DGTUMesh)) + rem.prepare(s,t,"P0P0") + mat=rem.getCrudeMatrix() + self.assertEqual(2,len(mat)) ; self.assertEqual(2,len(mat[0])) ; self.assertEqual(1,len(mat[1])) + self.assertAlmostEqual(0.294,mat[0][0],14) ; self.assertAlmostEqual(0.196,mat[0][1],14) ; self.assertAlmostEqual(0.049,mat[1][1],14) + del s,t + # 165 (1sgtumesh-umesh) + rem=MEDCouplingRemapper() ; rem.setIntersectionType(Triangulation) + s=sc.build1SGTUnstructured() ; t=tc.buildUnstructured() + self.assertTrue(isinstance(s,MEDCoupling1SGTUMesh)) + self.assertTrue(isinstance(t,MEDCouplingUMesh)) + rem.prepare(s,t,"P0P0") + mat=rem.getCrudeMatrix() + self.assertEqual(2,len(mat)) ; self.assertEqual(2,len(mat[0])) ; self.assertEqual(1,len(mat[1])) + self.assertAlmostEqual(0.294,mat[0][0],14) ; self.assertAlmostEqual(0.196,mat[0][1],14) ; self.assertAlmostEqual(0.049,mat[1][1],14) + del s,t + # 181 (1dgtumesh-umesh + rem=MEDCouplingRemapper() ; rem.setIntersectionType(Triangulation) + s=sc.buildUnstructured() ; s.convertAllToPoly() ; s=MEDCoupling1DGTUMesh(s) ; t=tc.buildUnstructured() + self.assertTrue(isinstance(s,MEDCoupling1DGTUMesh)) + self.assertTrue(isinstance(t,MEDCouplingUMesh)) + rem.prepare(s,t,"P0P0") + mat=rem.getCrudeMatrix() + self.assertEqual(2,len(mat)) ; self.assertEqual(2,len(mat[0])) ; self.assertEqual(1,len(mat[1])) + self.assertAlmostEqual(0.294,mat[0][0],14) ; self.assertAlmostEqual(0.196,mat[0][1],14) ; self.assertAlmostEqual(0.049,mat[1][1],14) + del s,t + # 170 (1sgtumesh-1sgtumesh) + rem=MEDCouplingRemapper() ; rem.setIntersectionType(Triangulation) + s=sc.build1SGTUnstructured() ; t=tc.build1SGTUnstructured() + self.assertTrue(isinstance(s,MEDCoupling1SGTUMesh)) + self.assertTrue(isinstance(t,MEDCoupling1SGTUMesh)) + rem.prepare(s,t,"P0P0") + mat=rem.getCrudeMatrix() + self.assertEqual(2,len(mat)) ; self.assertEqual(2,len(mat[0])) ; self.assertEqual(1,len(mat[1])) + self.assertAlmostEqual(0.294,mat[0][0],14) ; self.assertAlmostEqual(0.196,mat[0][1],14) ; self.assertAlmostEqual(0.049,mat[1][1],14) + del s,t + # 171 (1sgtumesh-1dgtumesh) + rem=MEDCouplingRemapper() ; rem.setIntersectionType(Triangulation) + s=sc.build1SGTUnstructured() ; t=tc.buildUnstructured() ; t.convertAllToPoly() ; t=MEDCoupling1DGTUMesh(t) + self.assertTrue(isinstance(s,MEDCoupling1SGTUMesh)) + self.assertTrue(isinstance(t,MEDCoupling1DGTUMesh)) + rem.prepare(s,t,"P0P0") + mat=rem.getCrudeMatrix() + self.assertEqual(2,len(mat)) ; self.assertEqual(2,len(mat[0])) ; self.assertEqual(1,len(mat[1])) + self.assertAlmostEqual(0.294,mat[0][0],14) ; self.assertAlmostEqual(0.196,mat[0][1],14) ; self.assertAlmostEqual(0.049,mat[1][1],14) + del s,t + # 186 (1dgtumesh-1sgtumesh) + rem=MEDCouplingRemapper() ; rem.setIntersectionType(Triangulation) + s=sc.buildUnstructured() ; s.convertAllToPoly() ; s=MEDCoupling1DGTUMesh(s) ; t=tc.build1SGTUnstructured() + self.assertTrue(isinstance(s,MEDCoupling1DGTUMesh)) + self.assertTrue(isinstance(t,MEDCoupling1SGTUMesh)) + rem.prepare(s,t,"P0P0") + mat=rem.getCrudeMatrix() + self.assertEqual(2,len(mat)) ; self.assertEqual(2,len(mat[0])) ; self.assertEqual(1,len(mat[1])) + self.assertAlmostEqual(0.294,mat[0][0],14) ; self.assertAlmostEqual(0.196,mat[0][1],14) ; self.assertAlmostEqual(0.049,mat[1][1],14) + del s,t + # 187 (1dgtumesh-1dgtumesh) + rem=MEDCouplingRemapper() ; rem.setIntersectionType(Triangulation) + s=sc.buildUnstructured() ; s.convertAllToPoly() ; s=MEDCoupling1DGTUMesh(s) ; t=tc.buildUnstructured() ; t.convertAllToPoly() ; t=MEDCoupling1DGTUMesh(t) + self.assertTrue(isinstance(s,MEDCoupling1DGTUMesh)) + self.assertTrue(isinstance(t,MEDCoupling1DGTUMesh)) + rem.prepare(s,t,"P0P0") + mat=rem.getCrudeMatrix() + self.assertEqual(2,len(mat)) ; self.assertEqual(2,len(mat[0])) ; self.assertEqual(1,len(mat[1])) + self.assertAlmostEqual(0.294,mat[0][0],14) ; self.assertAlmostEqual(0.196,mat[0][1],14) ; self.assertAlmostEqual(0.049,mat[1][1],14) + del s,t + # (umesh-cmesh) + # 167 (1sgtumesh-cmesh) + rem=MEDCouplingRemapper() ; rem.setIntersectionType(Triangulation) + s=sc.build1SGTUnstructured() ; t=tc.deepCpy() + self.assertTrue(isinstance(s,MEDCoupling1SGTUMesh)) + self.assertTrue(isinstance(t,MEDCouplingCMesh)) + rem.prepare(s,t,"P0P0") + mat=rem.getCrudeMatrix() + self.assertEqual(2,len(mat)) ; self.assertEqual(2,len(mat[0])) ; self.assertEqual(1,len(mat[1])) + self.assertAlmostEqual(0.294,mat[0][0],14) ; self.assertAlmostEqual(0.196,mat[0][1],14) ; self.assertAlmostEqual(0.049,mat[1][1],14) + del s,t + # 183 (1dgtumesh-cmesh) + #rem=MEDCouplingRemapper() ; rem.setIntersectionType(Triangulation) + #s=sc.buildUnstructured() ; s.convertAllToPoly() ; s=MEDCoupling1DGTUMesh(s) ; t=tc.deepCpy() + #self.assertTrue(isinstance(s,MEDCoupling1DGTUMesh)) + #self.assertTrue(isinstance(t,MEDCouplingCMesh)) + #rem.prepare(s,t,"P0P0") + #mat=rem.getCrudeMatrix() + #self.assertEqual(2,len(mat)) ; self.assertEqual(2,len(mat[0])) ; self.assertEqual(1,len(mat[1])) + #self.assertAlmostEqual(0.294,mat[0][0],14) ; self.assertAlmostEqual(0.196,mat[0][1],14) ; self.assertAlmostEqual(0.049,mat[1][1],14) + #del s,t + # (cmesh-umesh) + # 122 (cmesh-1sgtumesh) + rem=MEDCouplingRemapper() ; rem.setIntersectionType(Triangulation) + s=sc.deepCpy() ; t=tc.build1SGTUnstructured() + self.assertTrue(isinstance(s,MEDCouplingCMesh)) + self.assertTrue(isinstance(t,MEDCoupling1SGTUMesh)) + rem.prepare(s,t,"P0P0") + mat=rem.getCrudeMatrix() + self.assertEqual(2,len(mat)) ; self.assertEqual(2,len(mat[0])) ; self.assertEqual(1,len(mat[1])) + self.assertAlmostEqual(0.294,mat[0][0],14) ; self.assertAlmostEqual(0.196,mat[0][1],14) ; self.assertAlmostEqual(0.049,mat[1][1],14) + del s,t + # 123 (cmesh-1dgtumesh) + #rem=MEDCouplingRemapper() ; rem.setIntersectionType(Triangulation) + #s=sc.deepCpy() ; t=tc.buildUnstructured() ; t.convertAllToPoly() ; t=MEDCoupling1DGTUMesh(t) + #self.assertTrue(isinstance(s,MEDCouplingCMesh)) + #self.assertTrue(isinstance(t,MEDCoupling1DGTUMesh)) + #rem.prepare(s,t,"P0P0") + #mat=rem.getCrudeMatrix() + #self.assertEqual(2,len(mat)) ; self.assertEqual(2,len(mat[0])) ; self.assertEqual(1,len(mat[1])) + #self.assertAlmostEqual(0.294,mat[0][0],14) ; self.assertAlmostEqual(0.196,mat[0][1],14) ; self.assertAlmostEqual(0.049,mat[1][1],14) + #del s,t + pass + + def testSwig2BarycentricP1P13D_1(self): + sCoo=DataArrayDouble([0.313,0.00218,6.90489,0.313,0.10692667,6.90489,0.313,0.10692667,6.96790167,0.313,0.00218,6.9773125,0.313,0.21167333,6.90489,0.313,0.21167333,6.95849083,0.313,0.31642,6.90489,0.313,0.31642,6.94908,0.313,0.09383333,7.04891667,0.313,0.00218,7.049735,0.313,0.18548667,7.04809833,0.313,0.27714,7.04728,0.313,0.05782667,7.133205,0.313,0.00218,7.1221575,0.313,0.11347333,7.1442525,0.313,0.16912,7.1553,0.313,0.02509333,7.19458,0.313,0.00218,7.19458,0.313,0.04800667,7.19458,0.313,0.07092,7.19458,0.31005609,0.00218,6.90460005,0.31005609,0.10692667,6.90460005,0.29776312,0.10692667,6.96640097,0.29592716,0.00218,6.97563097,0.31005609,0.21167333,6.90460005,0.29959908,0.21167333,6.95717096,0.31005609,0.31642,6.90460005,0.30143505,0.31642,6.94794095,0.28195788,0.09383333,7.04585928,0.28179823,0.00218,7.04666189,0.28211753,0.18548667,7.04505668,0.28227718,0.27714,7.04425407,0.26551404,0.05782667,7.12852804,0.2676693,0.00218,7.11769282,0.26335878,0.11347333,7.13936327,0.26120352,0.16912,7.15019849,0.25354037,0.02509333,7.18872374,0.25354037,0.00218,7.18872374,0.25354037,0.04800667,7.18872374,0.25354037,0.07092,7.18872374,0.30722531,0.00218,6.90374134,0.30722531,0.10692667,6.90374134,0.28311179,0.10692667,6.96195653,0.27951042,0.00218,6.97065101,0.30722531,0.21167333,6.90374134,0.28671316,0.21167333,6.95326205,0.30722531,0.31642,6.90374134,0.29031453,0.31642,6.94456758,0.25210869,0.09383333,7.03680463,0.25179553,0.00218,7.03756067,0.25242185,0.18548667,7.03604859,0.25273501,0.27714,7.03529255,0.21985294,0.05782667,7.1146769,0.22408063,0.00218,7.10447034,0.21562524,0.11347333,7.12488346,0.21139755,0.16912,7.13509002,0.19636574,0.02509333,7.17138,0.19636574,0.00218,7.17138,0.19636574,0.04800667,7.17138,0.19636574,0.07092,7.17138,0.30461645,0.00218,6.90234688,0.30461645,0.10692667,6.90234688,0.26960904,0.10692667,6.95473916,0.26438066,0.00218,6.96256398,0.30461645,0.21167333,6.90234688,0.27483742,0.21167333,6.94691434,0.30461645,0.31642,6.90234688,0.2800658,0.31642,6.93908952,0.22459952,0.09383333,7.02210067,0.22414487,0.00218,7.02278109,0.22505416,0.18548667,7.02142025,0.2255088,0.27714,7.02073983,0.17777143,0.05782667,7.09218386,0.18390909,0.00218,7.0829982,0.17163377,0.11347333,7.10136952,0.1654961,0.16912,7.11055518,0.1436733,0.02509333,7.14321531,0.1436733,0.00218,7.14321531,0.1436733,0.04800667,7.14321531,0.1436733,0.07092,7.14321531,0.30232976,0.00218,6.90047024,0.30232976,0.10692667,6.90047024,0.25777378,0.10692667,6.94502622,0.25111932,0.00218,6.95168068,0.30232976,0.21167333,6.90047024,0.26442825,0.21167333,6.93837175,0.30232976,0.31642,6.90047024,0.27108271,0.31642,6.93171729,0.20048753,0.09383333,7.00231247,0.19990888,0.00218,7.00289112,0.20106618,0.18548667,7.00173382,0.20164482,0.27714,7.00115518,0.14088667,0.05782667,7.06191333,0.14869844,0.00218,7.05410156,0.13307491,0.11347333,7.06972509,0.12526315,0.16912,7.07753685,0.097488,0.02509333,7.105312,0.097488,0.00218,7.105312,0.097488,0.04800667,7.105312,0.097488,0.07092,7.105312,0.30045312,0.00218,6.89818355,0.30045312,0.10692667,6.89818355,0.24806084,0.10692667,6.93319096,0.24023602,0.00218,6.93841934,0.30045312,0.21167333,6.89818355,0.25588566,0.21167333,6.92796258,0.30045312,0.31642,6.89818355,0.26371048,0.31642,6.9227342,0.18069933,0.09383333,6.97820048,0.18001891,0.00218,6.97865513,0.18137975,0.18548667,6.97774584,0.18206017,0.27714,6.9772912,0.11061614,0.05782667,7.02502857,0.1198018,0.00218,7.01889091,0.10143048,0.11347333,7.03116623,0.09224482,0.16912,7.0373039,0.05958469,0.02509333,7.0591267,0.05958469,0.00218,7.0591267,0.05958469,0.04800667,7.0591267,0.05958469,0.07092,7.0591267,0.29905866,0.00218,6.89557469,0.29905866,0.10692667,6.89557469,0.24084347,0.10692667,6.91968821,0.23214899,0.00218,6.92328958,0.29905866,0.21167333,6.89557469,0.24953795,0.21167333,6.91608684,0.29905866,0.31642,6.89557469,0.25823242,0.31642,6.91248547,0.16599537,0.09383333,6.95069131,0.16523933,0.00218,6.95100447,0.16675141,0.18548667,6.95037815,0.16750745,0.27714,6.95006499,0.0881231,0.05782667,6.98294706,0.09832966,0.00218,6.97871937,0.07791654,0.11347333,6.98717476,0.06770998,0.16912,6.99140245,0.03142,0.02509333,7.00643426,0.03142,0.00218,7.00643426,0.03142,0.04800667,7.00643426,0.03142,0.07092,7.00643426,0.29819995,0.00218,6.89274391,0.29819995,0.10692667,6.89274391,0.23639903,0.10692667,6.90503688,0.22716903,0.00218,6.90687284,0.29819995,0.21167333,6.89274391,0.24562904,0.21167333,6.90320092,0.29819995,0.31642,6.89274391,0.25485905,0.31642,6.90136495,0.15694072,0.09383333,6.92084212,0.15613811,0.00218,6.92100177,0.15774332,0.18548667,6.92068247,0.15854593,0.27714,6.92052282,0.07427196,0.05782667,6.93728596,0.08510718,0.00218,6.9351307,0.06343673,0.11347333,6.93944122,0.05260151,0.16912,6.94159648,0.01407626,0.02509333,6.94925963,0.01407626,0.00218,6.94925963,0.01407626,0.04800667,6.94925963,0.01407626,0.07092,6.94925963,0.29792818,0.00218,6.89054043,0.29792818,0.10692667,6.89054043,0.23499241,0.10692667,6.89363227,0.22559291,0.00218,6.89409403,0.29792818,0.21167333,6.89054043,0.24439191,0.21167333,6.8931705,0.29792818,0.31642,6.89054043,0.25379141,0.31642,6.89270873,0.154075,0.09383333,6.89760748,0.15325765,0.00218,6.89764764,0.15489234,0.18548667,6.89756733,0.15570969,0.27714,6.89752718,0.06988819,0.05782667,6.90174332,0.08092238,0.00218,6.90120124,0.058854,0.11347333,6.90228539,0.04781981,0.16912,6.90282747,0.00858712,0.02509333,6.90475485,0.00858712,0.00218,6.90475485,0.00858712,0.04800667,6.90475485,0.00858712,0.07092,6.90475485,0.29791,0.00218,6.820902,0.29791,0.10692667,6.820902,0.23489833,0.10692667,6.820902,0.2254875,0.00218,6.820902,0.29791,0.21167333,6.820902,0.24430917,0.21167333,6.820902,0.29791,0.31642,6.820902,0.25372,0.31642,6.820902,0.15388333,0.09383333,6.820902,0.153065,0.00218,6.820902,0.15470167,0.18548667,6.820902,0.15552,0.27714,6.820902,0.069595,0.05782667,6.820902,0.0806425,0.00218,6.820902,0.0585475,0.11347333,6.820902,0.0475,0.16912,6.820902,0.00822,0.02509333,6.820902,0.00822,0.00218,6.820902,0.00822,0.04800667,6.820902,0.00822,0.07092,6.820902],200,3) + sConn=DataArrayInt([0,1,2,3,20,21,22,23,1,4,5,2,21,24,25,22,4,6,7,5,24,26,27,25,3,2,8,9,23,22,28,29,2,5,10,8,22,25,30,28,5,7,11,10,25,27,31,30,9,8,12,13,29,28,32,33,8,10,14,12,28,30,34,32,10,11,15,14,30,31,35,34,13,12,16,17,33,32,36,37,12,14,18,16,32,34,38,36,14,15,19,18,34,35,39,38,20,21,22,23,40,41,42,43,21,24,25,22,41,44,45,42,24,26,27,25,44,46,47,45,23,22,28,29,43,42,48,49,22,25,30,28,42,45,50,48,25,27,31,30,45,47,51,50,29,28,32,33,49,48,52,53,28,30,34,32,48,50,54,52,30,31,35,34,50,51,55,54,33,32,36,37,53,52,56,57,32,34,38,36,52,54,58,56,34,35,39,38,54,55,59,58,40,41,42,43,60,61,62,63,41,44,45,42,61,64,65,62,44,46,47,45,64,66,67,65,43,42,48,49,63,62,68,69,42,45,50,48,62,65,70,68,45,47,51,50,65,67,71,70,49,48,52,53,69,68,72,73,48,50,54,52,68,70,74,72,50,51,55,54,70,71,75,74,53,52,56,57,73,72,76,77,52,54,58,56,72,74,78,76,54,55,59,58,74,75,79,78,60,61,62,63,80,81,82,83,61,64,65,62,81,84,85,82,64,66,67,65,84,86,87,85,63,62,68,69,83,82,88,89,62,65,70,68,82,85,90,88,65,67,71,70,85,87,91,90,69,68,72,73,89,88,92,93,68,70,74,72,88,90,94,92,70,71,75,74,90,91,95,94,73,72,76,77,93,92,96,97,72,74,78,76,92,94,98,96,74,75,79,78,94,95,99,98,80,81,82,83,100,101,102,103,81,84,85,82,101,104,105,102,84,86,87,85,104,106,107,105,83,82,88,89,103,102,108,109,82,85,90,88,102,105,110,108,85,87,91,90,105,107,111,110,89,88,92,93,109,108,112,113,88,90,94,92,108,110,114,112,90,91,95,94,110,111,115,114,93,92,96,97,113,112,116,117,92,94,98,96,112,114,118,116,94,95,99,98,114,115,119,118,100,101,102,103,120,121,122,123,101,104,105,102,121,124,125,122,104,106,107,105,124,126,127,125,103,102,108,109,123,122,128,129,102,105,110,108,122,125,130,128,105,107,111,110,125,127,131,130,109,108,112,113,129,128,132,133,108,110,114,112,128,130,134,132,110,111,115,114,130,131,135,134,113,112,116,117,133,132,136,137,112,114,118,116,132,134,138,136,114,115,119,118,134,135,139,138,120,121,122,123,140,141,142,143,121,124,125,122,141,144,145,142,124,126,127,125,144,146,147,145,123,122,128,129,143,142,148,149,122,125,130,128,142,145,150,148,125,127,131,130,145,147,151,150,129,128,132,133,149,148,152,153,128,130,134,132,148,150,154,152,130,131,135,134,150,151,155,154,133,132,136,137,153,152,156,157,132,134,138,136,152,154,158,156,134,135,139,138,154,155,159,158,140,141,142,143,160,161,162,163,141,144,145,142,161,164,165,162,144,146,147,145,164,166,167,165,143,142,148,149,163,162,168,169,142,145,150,148,162,165,170,168,145,147,151,150,165,167,171,170,149,148,152,153,169,168,172,173,148,150,154,152,168,170,174,172,150,151,155,154,170,171,175,174,153,152,156,157,173,172,176,177,152,154,158,156,172,174,178,176,154,155,159,158,174,175,179,178,160,161,162,163,180,181,182,183,161,164,165,162,181,184,185,182,164,166,167,165,184,186,187,185,163,162,168,169,183,182,188,189,162,165,170,168,182,185,190,188,165,167,171,170,185,187,191,190,169,168,172,173,189,188,192,193,168,170,174,172,188,190,194,192,170,171,175,174,190,191,195,194,173,172,176,177,193,192,196,197,172,174,178,176,192,194,198,196,174,175,179,178,194,195,199,198]) + s=MEDCoupling1SGTUMesh("target",NORM_HEXA8) ; s.setCoords(sCoo) + s.setNodalConnectivity(sConn) + # + tCoo=DataArrayDouble([0.328,0.012,6.8598,0.328,0.168320184237353,6.8598,0.328,0.324640368474706,6.8598,0.328,0.0,6.8598,0.298,0.012,6.8598,0.1565,0.012,6.8598,0.180205346493166,0.144794653506834,6.8598,0.298,0.168320184237353,6.8598,0.0,0.012,6.8598,0.0916755774886107,0.233324422511389,6.8598,0.298,0.324640368474706,6.8598,0.298,0.0,6.8598,0.1565,0.0,6.8598,0.0,0.0,6.8598,0.328,0.012,7.2298,0.328,0.168320184237353,7.2298,0.328,0.324640368474706,7.2298,0.328,0.0,7.2298,0.298,0.012,7.2298,0.1565,0.012,7.2298,0.180205346493166,0.144794653506834,7.2298,0.298,0.168320184237353,7.2298,0.0,0.012,7.2298,0.0916755774886107,0.233324422511389,7.2298,0.298,0.324640368474706,7.2298,0.298,0.0,7.2298,0.1565,0.0,7.2298,0.0,0.0,7.2298],28,3) + tConn=DataArrayInt([4,5,6,7,18,19,20,21,5,8,9,6,19,22,23,20,6,9,10,7,20,23,24,21,11,12,5,4,25,26,19,18,12,13,8,5,26,27,22,19,3,11,4,0,17,25,18,14,0,4,7,1,14,18,21,15,1,7,10,2,15,21,24,16]) + t=MEDCoupling1SGTUMesh("target",NORM_HEXA8) ; t.setCoords(tCoo) + t.setNodalConnectivity(tConn) + # + s.simplexize(PLANAR_FACE_5) + aRemapper=MEDCouplingRemapper() + aRemapper.setPrecision(1e-12) + aRemapper.setIntersectionType(Barycentric) + self.assertEqual(aRemapper.prepare(s,t,'P1P1'),1) + m=aRemapper.getCrudeMatrix() + self.assertEqual(len(m),28) + for i in xrange(28): + if i not in [5,6]: + self.assertEqual(len(m[i]),0) + pass + pass + self.assertEqual(len(m[5]),4) + self.assertEqual(len(m[6]),4) + self.assertAlmostEqual(0.10714286103952797,m[5][168],12) + self.assertAlmostEqual(0.35691534416938014,m[5][169],12) + self.assertAlmostEqual(0.04492099619713096,m[5][163],12) + self.assertAlmostEqual(0.49102079859396097,m[5][189],12) + self.assertAlmostEqual(0.14039089397104254,m[6][185],12) + self.assertAlmostEqual(0.16362822318261033,m[6][162],12) + self.assertAlmostEqual(0.3438363717836785 ,m[6][188],12) + self.assertAlmostEqual(0.3521445110626687 ,m[6][170],12) + pass + + @unittest.skipUnless(MEDCouplingHasNumPyBindings() and MEDCouplingHasSciPyBindings(),"requires numpy AND scipy") + def testGetCrudeCSRMatrix1(self): + """ testing CSR matrix output using numpy/scipy. + """ + from scipy.sparse import spdiags #diags + import scipy + from numpy import array + arr=DataArrayDouble(3) ; arr.iota() + m=MEDCouplingCMesh() ; m.setCoords(arr,arr) + src=m.buildUnstructured() + trg=src.deepCpy() ; trg=trg[[0,1,3]] + trg.getCoords()[:]*=0.5 ; trg.getCoords()[:]+=[0.3,0.25] + # Let's interpolate. + rem=MEDCouplingRemapper() + rem.prepare(src,trg,"P0P0") + # Internal crude sparse matrix computed. Let's manipulate it using CSR matrix in scipy. + for i in xrange(10): + m=rem.getCrudeCSRMatrix() + pass + m2=rem.getCrudeCSRMatrix() + diff=m-m2 + self.assertTrue(isinstance(m,scipy.sparse.csr.csr_matrix)) + self.assertEqual(m.getnnz(),7) + self.assertAlmostEqual(m[0,0],0.25,12) + self.assertAlmostEqual(m[1,0],0.1,12) + self.assertAlmostEqual(m[1,1],0.15,12) + self.assertAlmostEqual(m[2,0],0.05,12) + self.assertAlmostEqual(m[2,1],0.075,12) + self.assertAlmostEqual(m[2,2],0.05,12) + self.assertAlmostEqual(m[2,3],0.075,12) + self.assertEqual(diff.getnnz(),0) + # IntegralGlobConstraint (division by sum of cols) + colSum=m.sum(axis=0) + # version 0.12.0 # m_0=m*diags(array(1/colSum),[0]) + m_0=m*spdiags(array(1/colSum),[0],colSum.shape[1],colSum.shape[1]) + del colSum + self.assertAlmostEqual(m_0[0,0],0.625,12) + self.assertAlmostEqual(m_0[1,0],0.25,12) + self.assertAlmostEqual(m_0[1,1],0.6666666666666667,12) + self.assertAlmostEqual(m_0[2,0],0.125,12) + self.assertAlmostEqual(m_0[2,1],0.3333333333333333,12) + self.assertAlmostEqual(m_0[2,2],1.,12) + self.assertAlmostEqual(m_0[2,3],1.,12) + self.assertEqual(m_0.getnnz(),7) + # ConservativeVolumic (division by sum of rows) + rowSum=m.sum(axis=1) + # version 0.12.0 # m_1=diags(array(1/rowSum.transpose()),[0])*m + m_1=spdiags(array(1/rowSum.transpose()),[0],rowSum.shape[0],rowSum.shape[0])*m + del rowSum + self.assertAlmostEqual(m_1[0,0],1.,12) + self.assertAlmostEqual(m_1[1,0],0.4,12) + self.assertAlmostEqual(m_1[1,1],0.6,12) + self.assertAlmostEqual(m_1[2,0],0.2,12) + self.assertAlmostEqual(m_1[2,1],0.3,12) + self.assertAlmostEqual(m_1[2,2],0.2,12) + self.assertAlmostEqual(m_1[2,3],0.3,12) + self.assertEqual(m_1.getnnz(),7) + pass + + @unittest.skipUnless(MEDCouplingHasNumPyBindings() and MEDCouplingHasSciPyBindings(),"requires numpy AND scipy") + def testP0P1Bary_1(self): + a=MEDCouplingUMesh("a",2) + a.allocateCells() + conna=[0,1,3,2,1,4,5,3,4,6,7,5,6,8,9,7,8,10,11,9,10,12,13,11,12,14,15,13,14,16,17,15,16,18,19,17,18,20,21,19,20,22,23,21,22,24,25,23,24,26,27,25] + a.setCoords(DataArrayDouble([1.54,0,-0.01,1.54,0.02,-0.01,1.54,0,0.01,1.54,0.02,0.01,1.54,0.04,-0.01,1.54,0.04,0.01,1.54,0.06,-0.01,1.54,0.06,0.01,1.54,0.08,-0.01,1.54,0.08,0.01,1.54,0.1,-0.01,1.54,0.1,0.01,1.54,0.12,-0.01,1.54,0.12,0.01,1.54,0.14,-0.01,1.54,0.14,0.01,1.54,0.16,-0.01,1.54,0.16,0.01,1.54,0.18,-0.01,1.54,0.18,0.01,1.54,0.2,-0.01,1.54,0.2,0.01,1.54,0.22,-0.01,1.54,0.22,0.01,1.54,0.24,-0.01,1.54,0.24,0.01,1.54,0.26,-0.01,1.54,0.26,0.01],28,3)) + for i in xrange(13): + a.insertNextCell(NORM_QUAD4,conna[4*i:4*(i+1)]) + pass + a.finishInsertingCells() ; a.simplexize(0) + # + connb=[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,0,2,39,3,5,40,6,8,41,9,11,42,12,14,43,15,17,44,18,20,45,21,23,46,24,26,47,27,29,48,30,32,49,33,35,50,36,38,51,52,2,39,53,5,40,54,8,41,55,11,42,56,14,43,57,17,44,58,20,45,59,23,46,60,26,47,61,29,48,62,32,49,63,35,50,64,38,51,52,2,65,53,5,66,54,8,67,55,11,68,56,14,69,57,17,70,58,20,71,59,23,72,60,26,73,61,29,74,62,32,75,63,35,76,64,38,77,53,2,65,54,5,66,55,8,67,56,11,68,57,14,69,58,17,70,59,20,71,60,23,72,61,26,73,62,29,74,63,32,75,64,35,76,78,38,77,53,2,40,54,5,41,55,8,42,56,11,43,57,14,44,58,17,45,59,20,46,60,23,47,61,26,48,62,29,49,63,32,50,64,35,51,78,38,79,3,2,40,6,5,41,9,8,42,12,11,43,15,14,44,18,17,45,21,20,46,24,23,47,27,26,48,30,29,49,33,32,50,36,35,51,80,38,79,3,2,1,6,5,4,9,8,7,12,11,10,15,14,13,18,17,16,21,20,19,24,23,22,27,26,25,30,29,28,33,32,31,36,35,34,80,38,37] + b=MEDCouplingUMesh("b",2) + b.allocateCells() + for i in xrange(104): + b.insertNextCell(NORM_TRI3,connb[3*i:3*(i+1)]) + pass + b.setCoords(DataArrayDouble([1.54,0,-0.01,1.54,0.01,-0.01,1.54,0.01,0,1.54,0.02,-0.01,1.54,0.03,-0.01,1.54,0.03,0,1.54,0.04,-0.01,1.54,0.05,-0.01,1.54,0.05,0,1.54,0.06,-0.01,1.54,0.07,-0.01,1.54,0.07,0,1.54,0.08,-0.01,1.54,0.09,-0.01,1.54,0.09,0,1.54,0.1,-0.01,1.54,0.11,-0.01,1.54,0.11,0,1.54,0.12,-0.01,1.54,0.13,-0.01,1.54,0.13,0,1.54,0.14,-0.01,1.54,0.15,-0.01,1.54,0.15,0,1.54,0.16,-0.01,1.54,0.17,-0.01,1.54,0.17,0,1.54,0.18,-0.01,1.54,0.19,-0.01,1.54,0.19,0,1.54,0.2,-0.01,1.54,0.21,-0.01,1.54,0.21,0,1.54,0.22,-0.01,1.54,0.23,-0.01,1.54,0.23,0,1.54,0.24,-0.01,1.54,0.25,-0.01,1.54,0.25,0,1.54,0,0,1.54,0.02,0,1.54,0.04,0,1.54,0.06,0,1.54,0.08,0,1.54,0.1,0,1.54,0.12,0,1.54,0.14,0,1.54,0.16,0,1.54,0.18,0,1.54,0.2,0,1.54,0.22,0,1.54,0.24,0,1.54,0,0.01,1.54,0.02,0.01,1.54,0.04,0.01,1.54,0.06,0.01,1.54,0.08,0.01,1.54,0.1,0.01,1.54,0.12,0.01,1.54,0.14,0.01,1.54,0.16,0.01,1.54,0.18,0.01,1.54,0.2,0.01,1.54,0.22,0.01,1.54,0.24,0.01,1.54,0.01,0.01,1.54,0.03,0.01,1.54,0.05,0.01,1.54,0.07,0.01,1.54,0.09,0.01,1.54,0.11,0.01,1.54,0.13,0.01,1.54,0.15,0.01,1.54,0.17,0.01,1.54,0.19,0.01,1.54,0.21,0.01,1.54,0.23,0.01,1.54,0.25,0.01,1.54,0.26,0.01,1.54,0.26,0,1.54,0.26,-0.01],81,3)) + # + rem=MEDCouplingRemapper() ; rem.setIntersectionType(Barycentric) + rem.prepare(a,b,"P1P0") + m0=rem.getCrudeCSRMatrix() + self.assertEqual(m0.nnz,312) + # + ids=4*[None] ; vs=4*[None] + ids[0]=DataArrayInt([0,3,6,9,12,15,18,21,24,27,30,33,36,39,42,45,48,51,54,57,60,63,66,69,72,75,158,161,164,167,170,173,176,179,182,185,188,191,194,197,200,203,206,209,212,215,218,221,224,227,230,233]) ; vs[0]=10./3. + ids[1]=DataArrayInt([1,2,4,5,7,8,10,11,13,14,16,17,19,20,22,23,25,26,28,29,31,32,34,35,37,38,40,41,43,44,46,47,49,50,52,53,55,56,58,59,61,62,64,65,67,68,70,71,73,74,76,77,80,83,86,89,92,95,98,101,104,107,110,113,116,117,120,123,126,129,132,135,138,141,144,147,150,153,156,157,159,160,162,163,165,166,168,169,171,172,174,175,177,178,180,181,183,184,186,187,189,190,192,193,195,196,198,199,201,202,204,205,207,208,210,211,213,214,216,217,219,220,222,223,225,226,228,229,231,232,234,237,240,243,246,249,252,255,258,261,264,267,270,275,278,281,284,287,290,293,296,299,302,305,308,311]) ; vs[1]=5./6. + ids[2]=DataArrayInt([78,81,84,87,90,93,96,99,102,105,108,111,114,119,122,125,128,131,134,137,140,143,146,149,152,155,236,239,242,245,248,251,254,257,260,263,266,269,272,273,276,279,282,285,288,291,294,297,300,303,306,309]) ; vs[2]=5./3. + ids[3]=DataArrayInt([79,82,85,88,91,94,97,100,103,106,109,112,115,118,121,124,127,130,133,136,139,142,145,148,151,154,235,238,241,244,247,250,253,256,259,262,265,268,271,274,277,280,283,286,289,292,295,298,301,304,307,310]) ; vs[3]=2.5 + vals=DataArrayDouble(312,1) + for idd,v in zip(ids,vs): + vals[idd]=v + pass + vals*=1e-5 + eps0=DataArrayDouble(m0.data)-vals ; eps0.abs() + self.assertTrue(eps0.getIdsInRange(1e-17,1e300).empty()) + self.assertTrue(DataArrayInt(m0.indices).isEqual(DataArrayInt([0,1,3,1,4,5,4,6,7,6,8,9,8,10,11,10,12,13,12,14,15,14,16,17,16,18,19,18,20,21,20,22,23,22,24,25,24,26,27,0,2,3,1,3,5,4,5,7,6,7,9,8,9,11,10,11,13,12,13,15,14,15,17,16,17,19,18,19,21,20,21,23,22,23,25,24,25,27,0,2,3,1,3,5,4,5,7,6,7,9,8,9,11,10,11,13,12,13,15,14,15,17,16,17,19,18,19,21,20,21,23,22,23,25,24,25,27,0,2,3,1,3,5,4,5,7,6,7,9,8,9,11,10,11,13,12,13,15,14,15,17,16,17,19,18,19,21,20,21,23,22,23,25,24,25,27,0,2,3,1,3,5,4,5,7,6,7,9,8,9,11,10,11,13,12,13,15,14,15,17,16,17,19,18,19,21,20,21,23,22,23,25,24,25,27,0,1,3,1,4,5,4,6,7,6,8,9,8,10,11,10,12,13,12,14,15,14,16,17,16,18,19,18,20,21,20,22,23,22,24,25,24,26,27,0,1,3,1,4,5,4,6,7,6,8,9,8,10,11,10,12,13,12,14,15,14,16,17,16,18,19,18,20,21,20,22,23,22,24,25,24,26,27,0,1,3,1,4,5,4,6,7,6,8,9,8,10,11,10,12,13,12,14,15,14,16,17,16,18,19,18,20,21,20,22,23,22,24,25,24,26,27]))) + self.assertTrue(DataArrayInt(m0.indptr).isEqual(DataArrayInt([0,3,6,9,12,15,18,21,24,27,30,33,36,39,42,45,48,51,54,57,60,63,66,69,72,75,78,81,84,87,90,93,96,99,102,105,108,111,114,117,120,123,126,129,132,135,138,141,144,147,150,153,156,159,162,165,168,171,174,177,180,183,186,189,192,195,198,201,204,207,210,213,216,219,222,225,228,231,234,237,240,243,246,249,252,255,258,261,264,267,270,273,276,279,282,285,288,291,294,297,300,303,306,309,312]))) + # + rem2=MEDCouplingRemapper() ; rem2.setIntersectionType(Barycentric) + rem2.prepare(b,a,"P0P1") + m1=rem2.getCrudeCSRMatrix() + self.assertEqual(m1.nnz,312) + # + m1=rem2.getCrudeCSRMatrix() + m1t=m1.transpose() + delta=m0-m1t + self.assertTrue(DataArrayDouble(delta.data).isUniform(0.,1e-17)) + pass + + @unittest.skipUnless(MEDCouplingHasNumPyBindings() and MEDCouplingHasSciPyBindings(),"requires numpy AND scipy") + def testNonConformWithRemapper_1(self): + coo=DataArrayDouble([-0.396700000780411,-0.134843245350081,-0.0361311386958691,-0.407550009429364,-0.13484324535008,-0.0361311386958923,-0.396700000780411,-0.132191446077668,-0.0448729493559049,-0.407550009429364,-0.132191446077666,-0.0448729493559254,-0.396700000780411,-0.128973582738749,-0.0534226071577727,-0.407550009429364,-0.128973582738747,-0.0534226071577904,-0.396700000780411,-0.128348829636458,-0.0346583696473619,-0.407550009429364,-0.128348829636457,-0.0346583696473822,-0.396700000780411,-0.125874740261886,-0.0430683597970123,-0.407550009429364,-0.125874740261885,-0.0430683597970302,-0.396700000780411,-0.122905344829122,-0.051310216195766,-0.407550009429364,-0.12290534482912,-0.0513102161957814],12,3) + conn=DataArrayInt([2,9,3,11,2,3,5,11,2,8,9,11,2,10,8,11,2,5,4,11,2,4,10,11,3,0,1,6,3,1,7,6,3,2,0,6,3,8,2,6,3,7,9,6,3,9,8,6]) + m=MEDCoupling1SGTUMesh("mesh",NORM_TETRA4) + m.setNodalConnectivity(conn) + m.setCoords(coo) + # m is ready + m1,d,di,rd,rdi=m.buildUnstructured().buildDescendingConnectivity() + rdi2=rdi.deltaShiftIndex() + cellIds=rdi2.getIdsEqual(1) + skinAndNonConformCells=m1[cellIds] + skinAndNonConformCells.zipCoords() # at this point skinAndNonConformCells contains non conform cells and skin cells. Now trying to split them in two parts. + # + rem=MEDCouplingRemapper() + rem.setMaxDistance3DSurfIntersect(1e-12) + rem.setMinDotBtwPlane3DSurfIntersect(0.99)# this line is important it is to tell to remapper to select only cells with very close orientation + rem.prepare(skinAndNonConformCells,skinAndNonConformCells,"P0P0") + mat=rem.getCrudeCSRMatrix() + indptr=DataArrayInt(mat.indptr) + indptr2=indptr.deltaShiftIndex() + cellIdsOfNonConformCells=indptr2.getIdsNotEqual(1) + cellIdsOfSkin=indptr2.getIdsEqual(1) + self.assertTrue(cellIdsOfSkin.isEqual(DataArrayInt([1,2,3,5,6,7,8,9,10,11,12,13,14,15,16,17,19,20,21,23]))) + self.assertTrue(cellIdsOfNonConformCells.isEqual(DataArrayInt([0,4,18,22]))) + pass + + def test3D1DOnP1P0_1(self): + """ This test focused on P1P0 interpolation with a source with meshDim=1 spaceDim=3 and a target with meshDim=3. + This test has revealed a bug in remapper. A reverse matrix is computed so a reverse method should be given in input. + """ + target=MEDCouplingCMesh() + arrX=DataArrayDouble([0,1]) ; arrY=DataArrayDouble([0,1]) ; arrZ=DataArrayDouble(11) ; arrZ.iota() + target.setCoords(arrX,arrY,arrZ) + target=target.buildUnstructured() ; target.setName("TargetSecondaire") + # + sourceCoo=DataArrayDouble([(0.5,0.5,0.1),(0.5,0.5,1.2),(0.5,0.5,1.6),(0.5,0.5,1.8),(0.5,0.5,2.43),(0.5,0.5,2.55),(0.5,0.5,4.1),(0.5,0.5,4.4),(0.5,0.5,4.9),(0.5,0.5,5.1),(0.5,0.5,7.6),(0.5,0.5,7.7),(0.5,0.5,8.2),(0.5,0.5,8.4),(0.5,0.5,8.6),(0.5,0.5,8.8),(0.5,0.5,9.2),(0.5,0.5,9.6),(0.5,0.5,11.5)]) + source=MEDCoupling1SGTUMesh("SourcePrimaire",NORM_SEG2) + source.setCoords(sourceCoo) + source.allocateCells() + for i in xrange(len(sourceCoo)-1): + source.insertNextCell([i,i+1]) + pass + source=source.buildUnstructured() + fsource=MEDCouplingFieldDouble(ON_NODES) ; fsource.setName("field") + fsource.setMesh(source) + arr=DataArrayDouble(len(sourceCoo)) ; arr.iota(0.7) ; arr*=arr + fsource.setArray(arr) + fsource.setNature(ConservativeVolumic) + # + rem=MEDCouplingRemapper() + rem.setIntersectionType(PointLocator) + rem.prepare(source,target,"P1P0") + f2Test=rem.transferField(fsource,-27) + self.assertEqual(f2Test.getName(),fsource.getName()) + self.assertEqual(f2Test.getMesh().getHiddenCppPointer(),target.getHiddenCppPointer()) + expArr=DataArrayDouble([0.49,7.956666666666667,27.29,-27,59.95666666666667,94.09,-27,125.69,202.89,296.09]) + self.assertTrue(f2Test.getArray().isEqual(expArr,1e-12)) + f2Test=rem.reverseTransferField(f2Test,-36) + self.assertEqual(f2Test.getName(),fsource.getName()) + self.assertEqual(f2Test.getMesh().getHiddenCppPointer(),source.getHiddenCppPointer()) + expArr2=DataArrayDouble([0.49,7.956666666666667,7.956666666666667,7.956666666666667,27.29,27.29,59.95666666666667,59.95666666666667,59.95666666666667,94.09,125.69,125.69,202.89,202.89,202.89,202.89,296.09,296.09,-36.]) + self.assertTrue(f2Test.getArray().isEqual(expArr2,1e-12)) + pass + + def testRemapperAMR1(self): + """ This test is the origin of the ref values for MEDCouplingBasicsTest.testAMR2""" + coarse=DataArrayDouble(35) ; coarse.iota(0) #X=5,Y=7 + fine=DataArrayDouble(3*2*4*4) ; fine.iota(0) #X=3,Y=2 refined by 4 + MEDCouplingIMesh.CondenseFineToCoarse([5,7],fine,[(1,4),(2,4)],[4,4],coarse) + # + m=MEDCouplingCartesianAMRMesh("mesh",2,[6,8],[0.,0.],[1.,1.]) + trgMesh=m.buildUnstructured() + m.addPatch([(1,4),(2,4)],[4,4]) + srcMesh=m[0].getMesh().buildUnstructured() + srcField=MEDCouplingFieldDouble(ON_CELLS) + fine2=DataArrayDouble(3*2*4*4) ; fine2.iota(0) ; srcField.setArray(fine2) + srcField.setMesh(srcMesh) ; srcField.setNature(Integral) + # + trgField=MEDCouplingFieldDouble(ON_CELLS) + coarse2=DataArrayDouble(35) ; coarse2.iota(0) ; trgField.setArray(coarse2) + trgField.setMesh(trgMesh) ; trgField.setNature(Integral) + # + rem=MEDCouplingRemapper() + rem.prepare(srcMesh,trgMesh,"P0P0") + rem.partialTransfer(srcField,trgField) + # + self.assertTrue(coarse.isEqual(trgField.getArray(),1e-12)) + pass + + @unittest.skipUnless(MEDCouplingHasNumPyBindings() and MEDCouplingHasSciPyBindings(),"requires numpy AND scipy") + def test1DPointLocator1(self): + """This test focuses on PointLocator for P1P1 in 1D and 2DCurve.""" + from numpy import array + from scipy.sparse import diags,csr_matrix,identity + ## basic case 1D + arrS=DataArrayInt.Range(0,11,1).convertToDblArr() + arrT=DataArrayDouble([0.1,1.7,5.5,9.6]) + mS=MEDCouplingCMesh() ; mS.setCoords(arrS) + mT=MEDCouplingCMesh() ; mT.setCoords(arrT) + rem=MEDCouplingRemapper() + rem.setIntersectionType(PointLocator) + self.assertEqual(rem.prepare(mS.buildUnstructured(),mT.buildUnstructured(),"P1P1"),1) + m=rem.getCrudeCSRMatrix() + rowSum=m.sum(axis=1) + m=diags(array(1/rowSum.transpose()),[0])*m + # expected matrix + row=array([0,0,1,1,2,2,3,3]) + col=array([0,1,1,2,5,6,9,10]) + data=array([0.9,0.1,0.3,0.7,0.5,0.5,0.4,0.6]) + mExp0=csr_matrix((data,(row,col)),shape=(4,11)) + # compute diff and check + diff=abs(m-mExp0) + self.assertAlmostEqual(diff.max(),0.,14) + ## full specific case 1D where target=source + rem=MEDCouplingRemapper() + rem.setIntersectionType(PointLocator) + self.assertEqual(rem.prepare(mS.buildUnstructured(),mS.buildUnstructured(),"P1P1"),1) + m=rem.getCrudeCSRMatrix() + rowSum=m.sum(axis=1) + m=diags(array(1/rowSum.transpose()),[0])*m + # expected matrix + mExp1=identity(11) + diff=abs(m-mExp1) + self.assertAlmostEqual(diff.max(),0.,14) + ## case where some points in target are not in source + arrT=DataArrayDouble([-0.2,0.1,1.7,5.5,10.3]) + mT=MEDCouplingCMesh() ; mT.setCoords(arrT) + mT=mT.buildUnstructured() + rem=MEDCouplingRemapper() + rem.setIntersectionType(PointLocator) + self.assertEqual(rem.prepare(mS.buildUnstructured(),mT,"P1P1"),1) + m=rem.getCrudeCSRMatrix() + row=array([1,1,2,2,3,3]) + col=array([0,1,1,2,5,6]) + data=array([0.9,0.1,0.3,0.7,0.5,0.5]) + mExp2=csr_matrix((data,(row,col)),shape=(5,11)) + diff=abs(m-mExp2) + self.assertAlmostEqual(diff.max(),0.,14) + ## basic case 2D Curve + arrS=DataArrayInt.Range(0,11,1).convertToDblArr() + arrT=DataArrayDouble([0.1,1.7,5.5,9.6]) + mS=MEDCouplingCMesh() ; mS.setCoords(arrS) + mT=MEDCouplingCMesh() ; mT.setCoords(arrT) + mS=mS.buildUnstructured() ; mS.changeSpaceDimension(2) + mT=mT.buildUnstructured() ; mT.changeSpaceDimension(2) + mS.rotate([-1.,-1.],1.2) + mT.rotate([-1.,-1.],1.2) + rem=MEDCouplingRemapper() + rem.setIntersectionType(PointLocator) + self.assertEqual(rem.prepare(mS,mT,"P1P1"),1) + m=rem.getCrudeCSRMatrix() + rowSum=m.sum(axis=1) + m=diags(array(1/rowSum.transpose()),[0])*m + diff=abs(m-mExp0) + self.assertAlmostEqual(diff.max(),0.,14) + pass + + def build2DSourceMesh_1(self): + sourceCoords=[-0.3,-0.3, 0.7,-0.3, -0.3,0.7, 0.7,0.7] + sourceConn=[0,3,1,0,2,3] + sourceMesh=MEDCouplingUMesh.New("my name of mesh 2D",2) + sourceMesh.allocateCells(2); + sourceMesh.insertNextCell(NORM_TRI3,3,sourceConn[0:3]); + sourceMesh.insertNextCell(NORM_TRI3,3,sourceConn[3:6]); + sourceMesh.finishInsertingCells(); + myCoords=DataArrayDouble.New(); + myCoords.setValues(sourceCoords,4,2); + sourceMesh.setCoords(myCoords); + return sourceMesh; + + def build2DTargetMesh_1(self): + targetCoords=[-0.3,-0.3, 0.2,-0.3, 0.7,-0.3, -0.3,0.2, 0.2,0.2, 0.7,0.2, -0.3,0.7, 0.2,0.7, 0.7,0.7 ] + targetConn=[0,3,4,1, 1,4,2, 4,5,2, 6,7,4,3, 7,8,5,4] + targetMesh=MEDCouplingUMesh.New(); + targetMesh.setMeshDimension(2); + targetMesh.allocateCells(5); + targetMesh.insertNextCell(NORM_QUAD4,4,targetConn[0:4]); + targetMesh.insertNextCell(NORM_TRI3,3,targetConn[4:7]); + targetMesh.insertNextCell(NORM_TRI3,3,targetConn[7:10]); + targetMesh.insertNextCell(NORM_QUAD4,4,targetConn[10:14]); + targetMesh.insertNextCell(NORM_QUAD4,4,targetConn[14:18]); + targetMesh.finishInsertingCells(); + myCoords=DataArrayDouble.New(); + myCoords.setValues(targetCoords,9,2); + targetMesh.setCoords(myCoords); + return targetMesh; + + def build2DTargetMesh_3(self): + targetCoords=[-0.6,-0.4, -0.1,-0.4, 1.1,-0.4, 2.1,-0.4, -0.6,0.1, -0.1,0.1, 1.1,0.1, 2.1,0.1, -0.6,1.1, -0.1,1.1] + targetConn=[0,4,5,1, 1,5,6,2, 2,6,7,3, 4,8,9,5] + targetMesh=MEDCouplingUMesh.New(); + targetMesh.setMeshDimension(2); + targetMesh.allocateCells(4); + for i in xrange(4): + targetMesh.insertNextCell(NORM_QUAD4,4,targetConn[4*i:4*(i+1)]) + pass + targetMesh.finishInsertingCells(); + myCoords=DataArrayDouble.New(); + myCoords.setValues(targetCoords,10,2); + targetMesh.setCoords(myCoords); + return targetMesh; + pass + + def setUp(self): + pass + pass + +unittest.main() diff --git a/src/medtool/src/MEDCoupling_Swig/MEDCouplingTimeDiscretization.i b/src/medtool/src/MEDCoupling_Swig/MEDCouplingTimeDiscretization.i new file mode 100644 index 000000000..411033e59 --- /dev/null +++ b/src/medtool/src/MEDCoupling_Swig/MEDCouplingTimeDiscretization.i @@ -0,0 +1,171 @@ +// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 +// 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) + +namespace ParaMEDMEM +{ + class MEDCouplingTimeDiscretization : public TimeLabel, public BigMemoryObject + { + public: + static MEDCouplingTimeDiscretization *New(TypeOfTimeDiscretization type) throw(INTERP_KERNEL::Exception); + void setTimeUnit(const char *unit); + const char *getTimeUnit() const; + virtual void copyTinyAttrFrom(const MEDCouplingTimeDiscretization& other) throw(INTERP_KERNEL::Exception); + 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 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); + virtual TypeOfTimeDiscretization getEnum() const throw(INTERP_KERNEL::Exception); + virtual void synchronizeTimeWith(const MEDCouplingMesh *mesh) throw(INTERP_KERNEL::Exception); + virtual MEDCouplingTimeDiscretization *aggregate(const MEDCouplingTimeDiscretization *other) const throw(INTERP_KERNEL::Exception); + virtual MEDCouplingTimeDiscretization *aggregate(const std::vector<const MEDCouplingTimeDiscretization *>& other) const throw(INTERP_KERNEL::Exception); + virtual MEDCouplingTimeDiscretization *meld(const MEDCouplingTimeDiscretization *other) const throw(INTERP_KERNEL::Exception); + virtual MEDCouplingTimeDiscretization *dot(const MEDCouplingTimeDiscretization *other) const throw(INTERP_KERNEL::Exception); + virtual MEDCouplingTimeDiscretization *crossProduct(const MEDCouplingTimeDiscretization *other) const throw(INTERP_KERNEL::Exception); + virtual MEDCouplingTimeDiscretization *max(const MEDCouplingTimeDiscretization *other) const throw(INTERP_KERNEL::Exception); + virtual MEDCouplingTimeDiscretization *min(const MEDCouplingTimeDiscretization *other) const throw(INTERP_KERNEL::Exception); + virtual MEDCouplingTimeDiscretization *add(const MEDCouplingTimeDiscretization *other) const throw(INTERP_KERNEL::Exception); + virtual void addEqual(const MEDCouplingTimeDiscretization *other) throw(INTERP_KERNEL::Exception); + virtual MEDCouplingTimeDiscretization *substract(const MEDCouplingTimeDiscretization *other) const throw(INTERP_KERNEL::Exception); + virtual void substractEqual(const MEDCouplingTimeDiscretization *other) throw(INTERP_KERNEL::Exception); + virtual MEDCouplingTimeDiscretization *multiply(const MEDCouplingTimeDiscretization *other) const throw(INTERP_KERNEL::Exception); + virtual void multiplyEqual(const MEDCouplingTimeDiscretization *other) throw(INTERP_KERNEL::Exception); + virtual MEDCouplingTimeDiscretization *divide(const MEDCouplingTimeDiscretization *other) const throw(INTERP_KERNEL::Exception); + virtual void divideEqual(const MEDCouplingTimeDiscretization *other) throw(INTERP_KERNEL::Exception); + virtual MEDCouplingTimeDiscretization *pow(const MEDCouplingTimeDiscretization *other) const throw(INTERP_KERNEL::Exception); + virtual void powEqual(const MEDCouplingTimeDiscretization *other) throw(INTERP_KERNEL::Exception); + virtual MEDCouplingTimeDiscretization *performCpy(bool deepCpy) const throw(INTERP_KERNEL::Exception); + void setTimeTolerance(double val); + double getTimeTolerance() const; + virtual void checkNoTimePresence() const throw(INTERP_KERNEL::Exception); + virtual void checkTimePresence(double time) const throw(INTERP_KERNEL::Exception); + 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<DataArrayDouble *>& arrays, TimeLabel *owner) throw(INTERP_KERNEL::Exception); + DataArrayDouble *getArray() throw(INTERP_KERNEL::Exception); + const DataArrayDouble *getArray() const throw(INTERP_KERNEL::Exception); + 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); + virtual void getValueForTime(double time, const std::vector<double>& vals, double *res) const throw(INTERP_KERNEL::Exception); + virtual void getArrays(std::vector<DataArrayDouble *>& 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); + virtual double getStartTime(int& iteration, int& order) const throw(INTERP_KERNEL::Exception); + virtual double getEndTime(int& iteration, int& order) const throw(INTERP_KERNEL::Exception); + void setTime(double time, int iteration, int order) throw(INTERP_KERNEL::Exception); + void setIteration(int it) throw(INTERP_KERNEL::Exception); + void setOrder(int order) throw(INTERP_KERNEL::Exception); + void setTimeValue(double val) throw(INTERP_KERNEL::Exception); + virtual void setStartIteration(int it) throw(INTERP_KERNEL::Exception); + virtual void setEndIteration(int it) throw(INTERP_KERNEL::Exception); + virtual void setStartOrder(int order) throw(INTERP_KERNEL::Exception); + virtual void setEndOrder(int order) throw(INTERP_KERNEL::Exception); + virtual void setStartTimeValue(double time) throw(INTERP_KERNEL::Exception); + virtual void setEndTimeValue(double time) throw(INTERP_KERNEL::Exception); + virtual void setStartTime(double time, int iteration, int order) throw(INTERP_KERNEL::Exception); + virtual void setEndTime(double time, int iteration, int order) throw(INTERP_KERNEL::Exception); + virtual void getValueOnTime(int eltId, double time, double *value) const throw(INTERP_KERNEL::Exception); + virtual void getValueOnDiscTime(int eltId, int iteration, int order, double *value) const throw(INTERP_KERNEL::Exception); + // + virtual MEDCouplingTimeDiscretization *doublyContractedProduct() const throw(INTERP_KERNEL::Exception); + virtual MEDCouplingTimeDiscretization *determinant() const throw(INTERP_KERNEL::Exception); + virtual MEDCouplingTimeDiscretization *eigenValues() const throw(INTERP_KERNEL::Exception); + virtual MEDCouplingTimeDiscretization *eigenVectors() const throw(INTERP_KERNEL::Exception); + virtual MEDCouplingTimeDiscretization *inverse() const throw(INTERP_KERNEL::Exception); + 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<int>& compoIds) const throw(INTERP_KERNEL::Exception); + virtual void setSelectedComponents(const MEDCouplingTimeDiscretization *other, const std::vector<int>& 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) 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<std::string>& 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); + virtual void fillFromAnalytic3(const DataArrayDouble *loc, int nbOfComp, const std::vector<std::string>& varsOrder, const char *func) throw(INTERP_KERNEL::Exception); + // + virtual ~MEDCouplingTimeDiscretization(); + }; + + class MEDCouplingNoTimeLabel : public MEDCouplingTimeDiscretization + { + public: + MEDCouplingNoTimeLabel(); + MEDCouplingNoTimeLabel(const MEDCouplingTimeDiscretization& other, bool deepCpy); + public: + static const TypeOfTimeDiscretization DISCRETIZATION=NO_TIME; + static const char REPR[]; + }; + + class MEDCouplingWithTimeStep : public MEDCouplingTimeDiscretization + { + public: + MEDCouplingWithTimeStep(); + public: + static const TypeOfTimeDiscretization DISCRETIZATION=ONE_TIME; + static const char REPR[]; + }; + + class MEDCouplingConstOnTimeInterval : public MEDCouplingTimeDiscretization + { + protected: + MEDCouplingConstOnTimeInterval(); + MEDCouplingConstOnTimeInterval(const MEDCouplingConstOnTimeInterval& other, bool deepCpy); + public: + static const TypeOfTimeDiscretization DISCRETIZATION=CONST_ON_TIME_INTERVAL; + static const char REPR[]; + }; + + class MEDCouplingTwoTimeSteps : public MEDCouplingTimeDiscretization + { + }; + + class MEDCouplingLinearTime : public MEDCouplingTwoTimeSteps + { + public: + MEDCouplingLinearTime(); + public: + static const TypeOfTimeDiscretization DISCRETIZATION=LINEAR_TIME; + static const char REPR[]; + }; +} + +#endif diff --git a/src/medtool/src/MEDCoupling_Swig/MEDCouplingTypemaps.i b/src/medtool/src/MEDCoupling_Swig/MEDCouplingTypemaps.i new file mode 100644 index 000000000..94bed84df --- /dev/null +++ b/src/medtool/src/MEDCoupling_Swig/MEDCouplingTypemaps.i @@ -0,0 +1,457 @@ +// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 +// 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 "MEDCouplingDataArrayTypemaps.i" + +static PyObject *convertMesh(ParaMEDMEM::MEDCouplingMesh *mesh, int owner) throw(INTERP_KERNEL::Exception) +{ + PyObject *ret=0; + if(!mesh) + { + Py_XINCREF(Py_None); + return Py_None; + } + if(dynamic_cast<ParaMEDMEM::MEDCouplingUMesh *>(mesh)) + ret=SWIG_NewPointerObj((void*)mesh,SWIGTYPE_p_ParaMEDMEM__MEDCouplingUMesh,owner); + if(dynamic_cast<ParaMEDMEM::MEDCoupling1SGTUMesh *>(mesh)) + ret=SWIG_NewPointerObj((void*)mesh,SWIGTYPE_p_ParaMEDMEM__MEDCoupling1SGTUMesh,owner); + if(dynamic_cast<ParaMEDMEM::MEDCoupling1DGTUMesh *>(mesh)) + ret=SWIG_NewPointerObj((void*)mesh,SWIGTYPE_p_ParaMEDMEM__MEDCoupling1DGTUMesh,owner); + if(dynamic_cast<ParaMEDMEM::MEDCouplingExtrudedMesh *>(mesh)) + ret=SWIG_NewPointerObj((void*)mesh,SWIGTYPE_p_ParaMEDMEM__MEDCouplingExtrudedMesh,owner); + if(dynamic_cast<ParaMEDMEM::MEDCouplingCMesh *>(mesh)) + ret=SWIG_NewPointerObj((void*)mesh,SWIGTYPE_p_ParaMEDMEM__MEDCouplingCMesh,owner); + if(dynamic_cast<ParaMEDMEM::MEDCouplingCurveLinearMesh *>(mesh)) + ret=SWIG_NewPointerObj((void*)mesh,SWIGTYPE_p_ParaMEDMEM__MEDCouplingCurveLinearMesh,owner); + if(dynamic_cast<ParaMEDMEM::MEDCouplingIMesh *>(mesh)) + ret=SWIG_NewPointerObj((void*)mesh,SWIGTYPE_p_ParaMEDMEM__MEDCouplingIMesh,owner); + if(!ret) + throw INTERP_KERNEL::Exception("Not recognized type of mesh on downcast !"); + return ret; +} + +static PyObject *convertFieldDiscretization(ParaMEDMEM::MEDCouplingFieldDiscretization *fd, int owner) throw(INTERP_KERNEL::Exception) +{ + PyObject *ret=0; + if(!fd) + { + Py_XINCREF(Py_None); + return Py_None; + } + if(dynamic_cast<ParaMEDMEM::MEDCouplingFieldDiscretizationP0 *>(fd)) + ret=SWIG_NewPointerObj(reinterpret_cast<void*>(fd),SWIGTYPE_p_ParaMEDMEM__MEDCouplingFieldDiscretizationP0,owner); + if(dynamic_cast<ParaMEDMEM::MEDCouplingFieldDiscretizationP1 *>(fd)) + ret=SWIG_NewPointerObj(reinterpret_cast<void*>(fd),SWIGTYPE_p_ParaMEDMEM__MEDCouplingFieldDiscretizationP1,owner); + if(dynamic_cast<ParaMEDMEM::MEDCouplingFieldDiscretizationGauss *>(fd)) + ret=SWIG_NewPointerObj(reinterpret_cast<void*>(fd),SWIGTYPE_p_ParaMEDMEM__MEDCouplingFieldDiscretizationGauss,owner); + if(dynamic_cast<ParaMEDMEM::MEDCouplingFieldDiscretizationGaussNE *>(fd)) + ret=SWIG_NewPointerObj(reinterpret_cast<void*>(fd),SWIGTYPE_p_ParaMEDMEM__MEDCouplingFieldDiscretizationGaussNE,owner); + if(dynamic_cast<ParaMEDMEM::MEDCouplingFieldDiscretizationKriging *>(fd)) + ret=SWIG_NewPointerObj(reinterpret_cast<void*>(fd),SWIGTYPE_p_ParaMEDMEM__MEDCouplingFieldDiscretizationKriging,owner); + if(!ret) + throw INTERP_KERNEL::Exception("Not recognized type of field discretization on downcast !"); + return ret; +} + +static PyObject* convertMultiFields(ParaMEDMEM::MEDCouplingMultiFields *mfs, int owner) throw(INTERP_KERNEL::Exception) +{ + PyObject *ret=0; + if(!mfs) + { + Py_XINCREF(Py_None); + return Py_None; + } + if(dynamic_cast<ParaMEDMEM::MEDCouplingFieldOverTime *>(mfs)) + ret=SWIG_NewPointerObj((void*)mfs,SWIGTYPE_p_ParaMEDMEM__MEDCouplingFieldOverTime,owner); + else + ret=SWIG_NewPointerObj((void*)mfs,SWIGTYPE_p_ParaMEDMEM__MEDCouplingMultiFields,owner); + return ret; +} + +static PyObject *convertPartDefinition(ParaMEDMEM::PartDefinition *pd, int owner) throw(INTERP_KERNEL::Exception) +{ + PyObject *ret=0; + if(!pd) + { + Py_XINCREF(Py_None); + return Py_None; + } + if(dynamic_cast<ParaMEDMEM::DataArrayPartDefinition *>(pd)) + ret=SWIG_NewPointerObj((void*)pd,SWIGTYPE_p_ParaMEDMEM__DataArrayPartDefinition,owner); + else + ret=SWIG_NewPointerObj((void*)pd,SWIGTYPE_p_ParaMEDMEM__SlicePartDefinition,owner); + return ret; +} + +static PyObject *convertCartesianAMRMesh(ParaMEDMEM::MEDCouplingCartesianAMRMeshGen *mesh, int owner) throw(INTERP_KERNEL::Exception) +{ + if(!mesh) + { + Py_XINCREF(Py_None); + return Py_None; + } + if(dynamic_cast<ParaMEDMEM::MEDCouplingCartesianAMRMeshSub *>(mesh)) + { + return SWIG_NewPointerObj(reinterpret_cast<void*>(mesh),SWIGTYPE_p_ParaMEDMEM__MEDCouplingCartesianAMRMeshSub,owner); + } + if(dynamic_cast<ParaMEDMEM::MEDCouplingCartesianAMRMesh *>(mesh)) + { + return SWIG_NewPointerObj(reinterpret_cast<void*>(mesh),SWIGTYPE_p_ParaMEDMEM__MEDCouplingCartesianAMRMesh,owner); + } + throw INTERP_KERNEL::Exception("convertCartesianAMRMesh wrap : unrecognized type of cartesian AMR mesh !"); +} + +static PyObject *convertDataForGodFather(ParaMEDMEM::MEDCouplingDataForGodFather *data, int owner) throw(INTERP_KERNEL::Exception) +{ + if(!data) + { + Py_XINCREF(Py_None); + return Py_None; + } + if(dynamic_cast<ParaMEDMEM::MEDCouplingAMRAttribute *>(data)) + { + return SWIG_NewPointerObj(reinterpret_cast<void*>(data),SWIGTYPE_p_ParaMEDMEM__MEDCouplingAMRAttribute,owner); + } + throw INTERP_KERNEL::Exception("convertDataForGodFather wrap : unrecognized data type for AMR !"); +} + +static PyObject *convertCartesianAMRPatch(ParaMEDMEM::MEDCouplingCartesianAMRPatchGen *patch, int owner) throw(INTERP_KERNEL::Exception) +{ + if(!patch) + { + Py_XINCREF(Py_None); + return Py_None; + } + if(dynamic_cast<ParaMEDMEM::MEDCouplingCartesianAMRPatchGF *>(patch)) + { + return SWIG_NewPointerObj(reinterpret_cast<void*>(patch),SWIGTYPE_p_ParaMEDMEM__MEDCouplingCartesianAMRPatchGF,owner); + } + if(dynamic_cast<ParaMEDMEM::MEDCouplingCartesianAMRPatch *>(patch)) + { + return SWIG_NewPointerObj(reinterpret_cast<void*>(patch),SWIGTYPE_p_ParaMEDMEM__MEDCouplingCartesianAMRPatch,owner); + } + throw INTERP_KERNEL::Exception("convertCartesianAMRPatch wrap : unrecognized type of cartesian AMR patch !"); +} + +static ParaMEDMEM::MEDCouplingFieldDouble *ParaMEDMEM_MEDCouplingFieldDouble___add__Impl(ParaMEDMEM::MEDCouplingFieldDouble *self, PyObject *obj) throw(INTERP_KERNEL::Exception) +{ + const char msg[]="Unexpected situation in MEDCouplingFieldDouble.__add__ ! Expecting a not null MEDCouplingFieldDouble or DataArrayDouble or DataArrayDoubleTuple instance, or a list of double, or a double."; + const char msg2[]="in MEDCouplingFieldDouble.__add__ : self field has no Array of values set !"; + void *argp; + // + if(SWIG_IsOK(SWIG_ConvertPtr(obj,&argp,SWIGTYPE_p_ParaMEDMEM__MEDCouplingFieldDouble,0|0))) + { + ParaMEDMEM::MEDCouplingFieldDouble *other=reinterpret_cast< ParaMEDMEM::MEDCouplingFieldDouble * >(argp); + if(other) + return (*self)+(*other); + else + throw INTERP_KERNEL::Exception(msg); + } + // + double val; + ParaMEDMEM::DataArrayDouble *a; + ParaMEDMEM::DataArrayDoubleTuple *aa; + std::vector<double> bb; + int sw; + convertObjToPossibleCpp5(obj,sw,val,a,aa,bb); + switch(sw) + { + case 1: + { + if(!self->getArray()) + throw INTERP_KERNEL::Exception(msg2); + ParaMEDMEM::MEDCouplingAutoRefCountObjectPtr<ParaMEDMEM::DataArrayDouble> ret=self->getArray()->deepCpy(); + ret->applyLin(1.,val); + ParaMEDMEM::MEDCouplingAutoRefCountObjectPtr<ParaMEDMEM::MEDCouplingFieldDouble> ret2=self->clone(false); + ret2->setArray(ret); + return ret2.retn(); + } + case 2: + { + if(!self->getArray()) + throw INTERP_KERNEL::Exception(msg2); + ParaMEDMEM::MEDCouplingAutoRefCountObjectPtr<ParaMEDMEM::DataArrayDouble> ret=ParaMEDMEM::DataArrayDouble::Add(self->getArray(),a); + ParaMEDMEM::MEDCouplingAutoRefCountObjectPtr<ParaMEDMEM::MEDCouplingFieldDouble> ret2=self->clone(false); + ret2->setArray(ret); + return ret2.retn(); + } + case 3: + { + if(!self->getArray()) + throw INTERP_KERNEL::Exception(msg2); + ParaMEDMEM::MEDCouplingAutoRefCountObjectPtr<ParaMEDMEM::DataArrayDouble> aaa=aa->buildDADouble(1,self->getNumberOfComponents()); + ParaMEDMEM::MEDCouplingAutoRefCountObjectPtr<ParaMEDMEM::DataArrayDouble> ret=ParaMEDMEM::DataArrayDouble::Add(self->getArray(),aaa); + ParaMEDMEM::MEDCouplingAutoRefCountObjectPtr<ParaMEDMEM::MEDCouplingFieldDouble> ret2=self->clone(false); + ret2->setArray(ret); + return ret2.retn(); + } + case 4: + { + if(!self->getArray()) + throw INTERP_KERNEL::Exception(msg2); + ParaMEDMEM::MEDCouplingAutoRefCountObjectPtr<ParaMEDMEM::DataArrayDouble> aaa=ParaMEDMEM::DataArrayDouble::New(); aaa->useArray(&bb[0],false,ParaMEDMEM::CPP_DEALLOC,1,(int)bb.size()); + ParaMEDMEM::MEDCouplingAutoRefCountObjectPtr<ParaMEDMEM::DataArrayDouble> ret=ParaMEDMEM::DataArrayDouble::Add(self->getArray(),aaa); + ParaMEDMEM::MEDCouplingAutoRefCountObjectPtr<ParaMEDMEM::MEDCouplingFieldDouble> ret2=self->clone(false); + ret2->setArray(ret); + return ret2.retn(); + } + default: + { throw INTERP_KERNEL::Exception(msg); } + } +} + +static ParaMEDMEM::MEDCouplingFieldDouble *ParaMEDMEM_MEDCouplingFieldDouble___radd__Impl(ParaMEDMEM::MEDCouplingFieldDouble *self, PyObject *obj) throw(INTERP_KERNEL::Exception) +{ + return ParaMEDMEM_MEDCouplingFieldDouble___add__Impl(self,obj); +} + +static ParaMEDMEM::MEDCouplingFieldDouble *ParaMEDMEM_MEDCouplingFieldDouble___rsub__Impl(ParaMEDMEM::MEDCouplingFieldDouble *self, PyObject *obj) throw(INTERP_KERNEL::Exception) +{ + const char msg[]="Unexpected situation in MEDCouplingFieldDouble.__rsub__ ! Expecting a not null MEDCouplingFieldDouble or DataArrayDouble or DataArrayDoubleTuple instance, or a list of double, or a double."; + const char msg2[]="in MEDCouplingFieldDouble.__rsub__ : self field has no Array of values set !"; + void *argp; + // + if(SWIG_IsOK(SWIG_ConvertPtr(obj,&argp,SWIGTYPE_p_ParaMEDMEM__MEDCouplingFieldDouble,0|0))) + { + ParaMEDMEM::MEDCouplingFieldDouble *other=reinterpret_cast< ParaMEDMEM::MEDCouplingFieldDouble * >(argp); + if(other) + return (*other)-(*self); + else + throw INTERP_KERNEL::Exception(msg); + } + // + double val; + ParaMEDMEM::DataArrayDouble *a; + ParaMEDMEM::DataArrayDoubleTuple *aa; + std::vector<double> bb; + int sw; + convertObjToPossibleCpp5(obj,sw,val,a,aa,bb); + switch(sw) + { + case 1: + { + if(!self->getArray()) + throw INTERP_KERNEL::Exception(msg2); + ParaMEDMEM::MEDCouplingAutoRefCountObjectPtr<ParaMEDMEM::DataArrayDouble> ret=self->getArray()->deepCpy(); + ret->applyLin(-1.,val); + ParaMEDMEM::MEDCouplingAutoRefCountObjectPtr<ParaMEDMEM::MEDCouplingFieldDouble> ret2=self->clone(false); + ret2->setArray(ret); + return ret2.retn(); + } + case 2: + { + if(!self->getArray()) + throw INTERP_KERNEL::Exception(msg2); + ParaMEDMEM::MEDCouplingAutoRefCountObjectPtr<ParaMEDMEM::DataArrayDouble> ret=ParaMEDMEM::DataArrayDouble::Substract(a,self->getArray()); + ParaMEDMEM::MEDCouplingAutoRefCountObjectPtr<ParaMEDMEM::MEDCouplingFieldDouble> ret2=self->clone(false); + ret2->setArray(ret); + return ret2.retn(); + } + case 3: + { + if(!self->getArray()) + throw INTERP_KERNEL::Exception(msg2); + ParaMEDMEM::MEDCouplingAutoRefCountObjectPtr<ParaMEDMEM::DataArrayDouble> aaa=aa->buildDADouble(1,self->getNumberOfComponents()); + ParaMEDMEM::MEDCouplingAutoRefCountObjectPtr<ParaMEDMEM::DataArrayDouble> ret=ParaMEDMEM::DataArrayDouble::Substract(aaa,self->getArray()); + ParaMEDMEM::MEDCouplingAutoRefCountObjectPtr<ParaMEDMEM::MEDCouplingFieldDouble> ret2=self->clone(false); + ret2->setArray(ret); + return ret2.retn(); + } + case 4: + { + if(!self->getArray()) + throw INTERP_KERNEL::Exception(msg2); + ParaMEDMEM::MEDCouplingAutoRefCountObjectPtr<ParaMEDMEM::DataArrayDouble> aaa=ParaMEDMEM::DataArrayDouble::New(); aaa->useArray(&bb[0],false,ParaMEDMEM::CPP_DEALLOC,1,(int)bb.size()); + ParaMEDMEM::MEDCouplingAutoRefCountObjectPtr<ParaMEDMEM::DataArrayDouble> ret=ParaMEDMEM::DataArrayDouble::Substract(aaa,self->getArray()); + ParaMEDMEM::MEDCouplingAutoRefCountObjectPtr<ParaMEDMEM::MEDCouplingFieldDouble> ret2=self->clone(false); + ret2->setArray(ret); + return ret2.retn(); + } + default: + { throw INTERP_KERNEL::Exception(msg); } + } +} + +static ParaMEDMEM::MEDCouplingFieldDouble *ParaMEDMEM_MEDCouplingFieldDouble___mul__Impl(ParaMEDMEM::MEDCouplingFieldDouble *self, PyObject *obj) throw(INTERP_KERNEL::Exception) +{ + const char msg[]="Unexpected situation in MEDCouplingFieldDouble.__mul__ ! Expecting a not null MEDCouplingFieldDouble or DataArrayDouble or DataArrayDoubleTuple instance, or a list of double, or a double."; + const char msg2[]="in MEDCouplingFieldDouble.__mul__ : self field has no Array of values set !"; + void *argp; + // + if(SWIG_IsOK(SWIG_ConvertPtr(obj,&argp,SWIGTYPE_p_ParaMEDMEM__MEDCouplingFieldDouble,0|0))) + { + ParaMEDMEM::MEDCouplingFieldDouble *other=reinterpret_cast< ParaMEDMEM::MEDCouplingFieldDouble * >(argp); + if(other) + return (*self)*(*other); + else + throw INTERP_KERNEL::Exception(msg); + } + // + double val; + ParaMEDMEM::DataArrayDouble *a; + ParaMEDMEM::DataArrayDoubleTuple *aa; + std::vector<double> bb; + int sw; + convertObjToPossibleCpp5(obj,sw,val,a,aa,bb); + switch(sw) + { + case 1: + { + if(!self->getArray()) + throw INTERP_KERNEL::Exception(msg2); + ParaMEDMEM::MEDCouplingAutoRefCountObjectPtr<ParaMEDMEM::DataArrayDouble> ret=self->getArray()->deepCpy(); + ret->applyLin(val,0.); + ParaMEDMEM::MEDCouplingAutoRefCountObjectPtr<ParaMEDMEM::MEDCouplingFieldDouble> ret2=self->clone(false); + ret2->setArray(ret); + return ret2.retn(); + } + case 2: + { + if(!self->getArray()) + throw INTERP_KERNEL::Exception(msg2); + ParaMEDMEM::MEDCouplingAutoRefCountObjectPtr<ParaMEDMEM::DataArrayDouble> ret=ParaMEDMEM::DataArrayDouble::Multiply(self->getArray(),a); + ParaMEDMEM::MEDCouplingAutoRefCountObjectPtr<ParaMEDMEM::MEDCouplingFieldDouble> ret2=self->clone(false); + ret2->setArray(ret); + return ret2.retn(); + } + case 3: + { + if(!self->getArray()) + throw INTERP_KERNEL::Exception(msg2); + ParaMEDMEM::MEDCouplingAutoRefCountObjectPtr<ParaMEDMEM::DataArrayDouble> aaa=aa->buildDADouble(1,self->getNumberOfComponents()); + ParaMEDMEM::MEDCouplingAutoRefCountObjectPtr<ParaMEDMEM::DataArrayDouble> ret=ParaMEDMEM::DataArrayDouble::Multiply(self->getArray(),aaa); + ParaMEDMEM::MEDCouplingAutoRefCountObjectPtr<ParaMEDMEM::MEDCouplingFieldDouble> ret2=self->clone(false); + ret2->setArray(ret); + return ret2.retn(); + } + case 4: + { + if(!self->getArray()) + throw INTERP_KERNEL::Exception(msg2); + ParaMEDMEM::MEDCouplingAutoRefCountObjectPtr<ParaMEDMEM::DataArrayDouble> aaa=ParaMEDMEM::DataArrayDouble::New(); aaa->useArray(&bb[0],false,ParaMEDMEM::CPP_DEALLOC,1,(int)bb.size()); + ParaMEDMEM::MEDCouplingAutoRefCountObjectPtr<ParaMEDMEM::DataArrayDouble> ret=ParaMEDMEM::DataArrayDouble::Multiply(self->getArray(),aaa); + ParaMEDMEM::MEDCouplingAutoRefCountObjectPtr<ParaMEDMEM::MEDCouplingFieldDouble> ret2=self->clone(false); + ret2->setArray(ret); + return ret2.retn(); + } + default: + { throw INTERP_KERNEL::Exception(msg); } + } +} + +ParaMEDMEM::MEDCouplingFieldDouble *ParaMEDMEM_MEDCouplingFieldDouble___rmul__Impl(ParaMEDMEM::MEDCouplingFieldDouble *self, PyObject *obj) throw(INTERP_KERNEL::Exception) +{ + return ParaMEDMEM_MEDCouplingFieldDouble___mul__Impl(self,obj); +} + +ParaMEDMEM::MEDCouplingFieldDouble *ParaMEDMEM_MEDCouplingFieldDouble___rdiv__Impl(ParaMEDMEM::MEDCouplingFieldDouble *self, PyObject *obj) throw(INTERP_KERNEL::Exception) +{ + const char msg[]="Unexpected situation in MEDCouplingFieldDouble.__rdiv__ ! Expecting a not null MEDCouplingFieldDouble or DataArrayDouble or DataArrayDoubleTuple instance, or a list of double, or a double."; + const char msg2[]="in MEDCouplingFieldDouble.__div__ : self field has no Array of values set !"; + void *argp; + // + if(SWIG_IsOK(SWIG_ConvertPtr(obj,&argp,SWIGTYPE_p_ParaMEDMEM__MEDCouplingFieldDouble,0|0))) + { + ParaMEDMEM::MEDCouplingFieldDouble *other=reinterpret_cast< ParaMEDMEM::MEDCouplingFieldDouble * >(argp); + if(other) + return (*other)/(*self); + else + throw INTERP_KERNEL::Exception(msg); + } + // + double val; + ParaMEDMEM::DataArrayDouble *a; + ParaMEDMEM::DataArrayDoubleTuple *aa; + std::vector<double> bb; + int sw; + convertObjToPossibleCpp5(obj,sw,val,a,aa,bb); + switch(sw) + { + case 1: + { + if(!self->getArray()) + throw INTERP_KERNEL::Exception(msg2); + ParaMEDMEM::MEDCouplingAutoRefCountObjectPtr<ParaMEDMEM::DataArrayDouble> ret=self->getArray()->deepCpy(); + ret->applyInv(val); + ParaMEDMEM::MEDCouplingAutoRefCountObjectPtr<ParaMEDMEM::MEDCouplingFieldDouble> ret2=self->clone(false); + ret2->setArray(ret); + return ret2.retn(); + } + case 2: + { + if(!self->getArray()) + throw INTERP_KERNEL::Exception(msg2); + ParaMEDMEM::MEDCouplingAutoRefCountObjectPtr<ParaMEDMEM::DataArrayDouble> ret=ParaMEDMEM::DataArrayDouble::Divide(a,self->getArray()); + ParaMEDMEM::MEDCouplingAutoRefCountObjectPtr<ParaMEDMEM::MEDCouplingFieldDouble> ret2=self->clone(false); + ret2->setArray(ret); + return ret2.retn(); + } + case 3: + { + if(!self->getArray()) + throw INTERP_KERNEL::Exception(msg2); + ParaMEDMEM::MEDCouplingAutoRefCountObjectPtr<ParaMEDMEM::DataArrayDouble> aaa=aa->buildDADouble(1,self->getNumberOfComponents()); + ParaMEDMEM::MEDCouplingAutoRefCountObjectPtr<ParaMEDMEM::DataArrayDouble> ret=ParaMEDMEM::DataArrayDouble::Divide(aaa,self->getArray()); + ParaMEDMEM::MEDCouplingAutoRefCountObjectPtr<ParaMEDMEM::MEDCouplingFieldDouble> ret2=self->clone(false); + ret2->setArray(ret); + return ret2.retn(); + } + case 4: + { + if(!self->getArray()) + throw INTERP_KERNEL::Exception(msg2); + ParaMEDMEM::MEDCouplingAutoRefCountObjectPtr<ParaMEDMEM::DataArrayDouble> aaa=ParaMEDMEM::DataArrayDouble::New(); aaa->useArray(&bb[0],false,ParaMEDMEM::CPP_DEALLOC,1,(int)bb.size()); + ParaMEDMEM::MEDCouplingAutoRefCountObjectPtr<ParaMEDMEM::DataArrayDouble> ret=ParaMEDMEM::DataArrayDouble::Divide(aaa,self->getArray()); + ParaMEDMEM::MEDCouplingAutoRefCountObjectPtr<ParaMEDMEM::MEDCouplingFieldDouble> ret2=self->clone(false); + ret2->setArray(ret); + return ret2.retn(); + } + default: + { throw INTERP_KERNEL::Exception(msg); } + } +} + +static PyObject *NewMethWrapCallInitOnlyIfEmptyDictInInput(PyObject *cls, PyObject *args, const char *clsName) +{ + if(!PyTuple_Check(args)) + { + std::ostringstream oss; oss << clsName << ".__new__ : the args in input is expected to be a tuple !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + PyObject *builtinsd(PyEval_GetBuiltins());//borrowed + PyObject *obj(PyDict_GetItemString(builtinsd,"object"));//borrowed + PyObject *selfMeth(PyObject_GetAttrString(obj,"__new__")); + // + PyObject *tmp0(PyTuple_New(1)); + PyTuple_SetItem(tmp0,0,cls); Py_XINCREF(cls); + PyObject *instance(PyObject_CallObject(selfMeth,tmp0)); + Py_DECREF(tmp0); + Py_DECREF(selfMeth); + if(PyTuple_Size(args)==2 && PyDict_Check(PyTuple_GetItem(args,1)) && PyDict_Size(PyTuple_GetItem(args,1))==0 ) + {// NOT general case. only true if in unpickeling context ! call __init__. Because for all other cases, __init__ is called right after __new__ ! + PyObject *initMeth(PyObject_GetAttrString(instance,"__init__")); + PyObject *tmp3(PyTuple_New(0)); + PyObject *tmp2(PyObject_CallObject(initMeth,tmp3)); + Py_XDECREF(tmp2); + Py_DECREF(tmp3); + Py_DECREF(initMeth); + } + return instance; +} diff --git a/src/medtool/src/MEDLoader/CMakeLists.txt b/src/medtool/src/MEDLoader/CMakeLists.txt new file mode 100644 index 000000000..4794ef2e3 --- /dev/null +++ b/src/medtool/src/MEDLoader/CMakeLists.txt @@ -0,0 +1,84 @@ +# Copyright (C) 2012-2015 CEA/DEN, EDF 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, 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 +# 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) + +ADD_DEFINITIONS(${HDF5_DEFINITIONS} ${MEDFILE_DEFINITIONS} ${XDR_DEFINITIONS}) + +IF(SALOME_MED_ENABLE_PYTHON) + ADD_SUBDIRECTORY(Swig) +ENDIF(SALOME_MED_ENABLE_PYTHON) + +IF(SALOME_BUILD_TESTS) + ADD_SUBDIRECTORY(Test) +ENDIF(SALOME_BUILD_TESTS) + +SET(MEDLOADER_XDR_INCLUDE_DIRS) +SET(MEDLOADER_XDR_LIBRARIES) + +IF(WIN32) + IF(SALOME_MED_MEDLOADER_USE_XDR) + ADD_DEFINITIONS(-DNOMINMAX) + SET(MEDLOADER_XDR_INCLUDE_DIRS ${XDR_INCLUDE_DIRS}) + SET(MEDLOADER_XDR_LIBRARIES ${XDR_LIBRARIES}) + ENDIF(SALOME_MED_MEDLOADER_USE_XDR) +ELSE(WIN32) + SET(MEDLOADER_XDR_INCLUDE_DIRS ${XDR_INCLUDE_DIRS}) +ENDIF(WIN32) + +INCLUDE_DIRECTORIES( + ${MEDFILE_INCLUDE_DIRS} + ${HDF5_INCLUDE_DIRS} + ${MEDLOADER_XDR_INCLUDE_DIRS} + ${CMAKE_CURRENT_SOURCE_DIR}/../MEDCoupling + ${CMAKE_CURRENT_SOURCE_DIR}/../INTERP_KERNEL + ${CMAKE_CURRENT_SOURCE_DIR}/../INTERP_KERNEL/Bases + ${CMAKE_CURRENT_SOURCE_DIR}/../INTERP_KERNEL/Geometric2D + ${CMAKE_CURRENT_SOURCE_DIR}/../INTERP_KERNEL/ExprEval + ${CMAKE_CURRENT_SOURCE_DIR}/../INTERP_KERNEL/GaussPoints + ) + +SET(medloader_SOURCES + MEDLoader.cxx + MEDLoaderBase.cxx + MEDFileUtilities.cxx + MEDFileMesh.cxx + MEDFileMeshElt.cxx + MEDFileBasis.cxx + MEDFileMeshLL.cxx + MEDFileField.cxx + MEDFileJoint.cxx + MEDFileParameter.cxx + MEDFileData.cxx + MEDFileFieldOverView.cxx + MEDFileMeshReadSelector.cxx + SauvMedConvertor.cxx + SauvReader.cxx + SauvWriter.cxx + ) + +ADD_LIBRARY(medloader SHARED ${medloader_SOURCES}) +SET_TARGET_PROPERTIES(medloader PROPERTIES COMPILE_FLAGS "") +TARGET_LINK_LIBRARIES(medloader medcoupling ${MEDFILE_C_LIBRARIES} ${HDF5_LIBRARIES} ${MEDLOADER_XDR_LIBRARIES}) +INSTALL(TARGETS medloader EXPORT ${PROJECT_NAME}TargetGroup DESTINATION ${MEDTOOL_INSTALL_LIBS}) + +FILE(GLOB medloader_HEADERS_HXX "${CMAKE_CURRENT_SOURCE_DIR}/*.hxx") +INSTALL(FILES ${medloader_HEADERS_HXX} DESTINATION ${MEDTOOL_INSTALL_HEADERS}) + +# To allow usage as SWIG dependencies: +SET(medloader_HEADERS_HXX PARENT_SCOPE) diff --git a/src/medtool/src/MEDLoader/MEDFileBasis.cxx b/src/medtool/src/MEDLoader/MEDFileBasis.cxx new file mode 100644 index 000000000..8e61dfb0e --- /dev/null +++ b/src/medtool/src/MEDLoader/MEDFileBasis.cxx @@ -0,0 +1,49 @@ +// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 +// 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 "MEDFileBasis.hxx" + +#include <cstring> + +using namespace ParaMEDMEM; + +MEDFileString::MEDFileString(int maxLgth):_max_lgth(maxLgth),_content(new char[maxLgth+1]) +{ + std::fill(_content,_content+maxLgth+1,'\0'); +} + +MEDFileString::~MEDFileString() +{ + delete [] _content; +} + +void MEDFileString::set(const char *s) +{ + if((int)strlen(s)>_max_lgth) + throw INTERP_KERNEL::Exception("Name is too long to be stored in MEDfile !"); + std::fill(_content,_content+_max_lgth+1,'\0'); + strcpy(_content,s); +} + +std::string MEDFileString::getRepr() const +{ + return std::string(_content); +} + diff --git a/src/medtool/src/MEDLoader/MEDFileBasis.hxx b/src/medtool/src/MEDLoader/MEDFileBasis.hxx new file mode 100644 index 000000000..41f402787 --- /dev/null +++ b/src/medtool/src/MEDLoader/MEDFileBasis.hxx @@ -0,0 +1,62 @@ +// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 +// 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 __MEDFILEBASIS_HXX__ +#define __MEDFILEBASIS_HXX__ + +#include "InterpKernelException.hxx" + +#include <string> +#include <vector> + +namespace ParaMEDMEM +{ + class MEDFileString + { + public: + MEDFileString(int maxLgth); + ~MEDFileString(); + void set(const char *s); + char *getPointer() { return _content; } + const char *getReprForWrite() const { return _content; } + std::string getRepr() const; + private: + int _max_lgth; + char *_content; + }; + + + class MEDFileMultiString + { + public: + MEDFileMultiString(int nbOfCompo, int maxLgthPerCompo); + ~MEDFileMultiString(); + void set(int compoId, const char *s); + const char *getReprForWrite() const; + std::vector<std::string> getRepr() const; + std::string getReprPerComp(int compId) const; + private: + int _nb_of_comp; + int _max_lgth_per_comp; + char *_content; + }; +} + +#endif diff --git a/src/medtool/src/MEDLoader/MEDFileData.cxx b/src/medtool/src/MEDLoader/MEDFileData.cxx new file mode 100644 index 000000000..a979b38f5 --- /dev/null +++ b/src/medtool/src/MEDLoader/MEDFileData.cxx @@ -0,0 +1,252 @@ +// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 +// 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 "MEDFileData.hxx" + +using namespace ParaMEDMEM; + +MEDFileData *MEDFileData::New(const std::string& fileName) +{ + return new MEDFileData(fileName); +} + +MEDFileData *MEDFileData::New() +{ + return new MEDFileData; +} + +MEDFileData *MEDFileData::deepCpy() const +{ + MEDCouplingAutoRefCountObjectPtr<MEDFileFields> fields; + if((const MEDFileFields *)_fields) + fields=_fields->deepCpy(); + MEDCouplingAutoRefCountObjectPtr<MEDFileMeshes> meshes; + if((const MEDFileMeshes *)_meshes) + meshes=_meshes->deepCpy(); + MEDCouplingAutoRefCountObjectPtr<MEDFileParameters> params; + if((const MEDFileParameters *)_params) + params=_params->deepCpy(); + MEDCouplingAutoRefCountObjectPtr<MEDFileJoints> joints; + MEDCouplingAutoRefCountObjectPtr<MEDFileData> ret=MEDFileData::New(); + ret->_fields=fields; ret->_meshes=meshes; ret->_params=params; + return ret.retn(); +} + +std::size_t MEDFileData::getHeapMemorySizeWithoutChildren() const +{ + return 0; +} + +std::vector<const BigMemoryObject *> MEDFileData::getDirectChildrenWithNull() const +{ + std::vector<const BigMemoryObject *> ret; + ret.push_back((const MEDFileFields *)_fields); + ret.push_back((const MEDFileMeshes *)_meshes); + ret.push_back((const MEDFileParameters *)_params); + return ret; + +} + +/** Return a borrowed reference (caller is not responsible for object destruction) */ +MEDFileFields *MEDFileData::getFields() const +{ + return const_cast<MEDFileFields *>(static_cast<const MEDFileFields *>(_fields)); +} + +/** Return a borrowed reference (caller is not responsible for object destruction) */ +MEDFileMeshes *MEDFileData::getMeshes() const +{ + return const_cast<MEDFileMeshes *>(static_cast<const MEDFileMeshes *>(_meshes)); +} + +/** Return a borrowed reference (caller is not responsible for object destruction) */ +MEDFileParameters *MEDFileData::getParams() const +{ + return const_cast<MEDFileParameters *>(static_cast<const MEDFileParameters *>(_params)); +} + +void MEDFileData::setFields(MEDFileFields *fields) +{ + if(fields) + fields->incrRef(); + _fields=fields; +} + +void MEDFileData::setMeshes(MEDFileMeshes *meshes) +{ + if(meshes) + meshes->incrRef(); + _meshes=meshes; +} + +void MEDFileData::setParams(MEDFileParameters *params) +{ + if(params) + params->incrRef(); + _params=params; +} + +int MEDFileData::getNumberOfFields() const +{ + const MEDFileFields *f=_fields; + if(!f) + throw INTERP_KERNEL::Exception("MEDFileData::getNumberOfFields : no fields set !"); + return f->getNumberOfFields(); +} + +int MEDFileData::getNumberOfMeshes() const +{ + const MEDFileMeshes *m=_meshes; + if(!m) + throw INTERP_KERNEL::Exception("MEDFileData::getNumberOfMeshes : no meshes set !"); + return m->getNumberOfMeshes(); +} + +int MEDFileData::getNumberOfParams() const +{ + const MEDFileParameters *p=_params; + if(!p) + throw INTERP_KERNEL::Exception("MEDFileData::getNumberOfParams : no params set !"); + return p->getNumberOfParams(); +} + +std::string MEDFileData::simpleRepr() const +{ + std::ostringstream oss; + oss << "(***************)\n(* MEDFileData *)\n(***************)\n\nFields part :\n*************\n\n"; + const MEDFileFields *tmp=_fields; + if(tmp) + { + tmp->simpleRepr(0,oss); + oss << std::endl; + } + else + oss << "No fields set !!!\n\n"; + oss << "Meshes part :\n*************\n\n"; + const MEDFileMeshes *tmp2=_meshes; + if(tmp2) + { + tmp2->simpleReprWithoutHeader(oss); + } + else + oss << "No meshes set !!!\n\n"; + oss << "Params part :\n*************\n\n"; + const MEDFileParameters *tmp3=_params; + if(tmp3) + { + tmp3->simpleReprWithoutHeader(oss); + } + else + oss << "No params set !!!\n"; + return oss.str(); +} + +bool MEDFileData::changeMeshNames(const std::vector< std::pair<std::string,std::string> >& modifTab) +{ + bool ret=false; + MEDFileFields *fields=_fields; + if(fields) + ret=fields->changeMeshNames(modifTab) || ret; + MEDFileMeshes *meshes=_meshes; + if(meshes) + ret=meshes->changeNames(modifTab) || ret; + return ret; +} + +bool MEDFileData::changeMeshName(const std::string& oldMeshName, const std::string& newMeshName) +{ + std::string oldName(oldMeshName); + std::vector< std::pair<std::string,std::string> > v(1); + v[0].first=oldName; v[0].second=newMeshName; + return changeMeshNames(v); +} + +/*! + * This method performs unpolyzation in meshes in \a this and if it leads to a modification to one or more than one meshes in \a this + * the fields are automatically renumbered (for those impacted, that is to say here fields on cells and fields on gauss points on impacted fields) + * + * \return If true is returned it means that some meshes in \a this has been modified and eventually fields have been renumbered. + * \n If false \a this remains unchanged. + */ +bool MEDFileData::unPolyzeMeshes() +{ + MEDFileMeshes *ms=_meshes; + if(!ms) + return false; + std::vector< MEDFileMesh * > meshesImpacted; + std::vector< DataArrayInt * > renumParamsOfMeshImpacted;//same size as meshesImpacted + std::vector< std::vector<int> > oldCodeOfMeshImpacted,newCodeOfMeshImpacted;//same size as meshesImpacted + std::vector<MEDCouplingAutoRefCountObjectPtr<DataArrayInt> > memSaverIfThrow;//same size as meshesImpacted + for(int i=0;i<ms->getNumberOfMeshes();i++) + { + MEDFileMesh *m=ms->getMeshAtPos(i); + if(m) + { + std::vector<int> oldCode,newCode; + DataArrayInt *o2nRenumCell=0; + bool modif=m->unPolyze(oldCode,newCode,o2nRenumCell); + if(!modif) + continue; + renumParamsOfMeshImpacted.push_back(o2nRenumCell); memSaverIfThrow.push_back(o2nRenumCell); + oldCodeOfMeshImpacted.push_back(oldCode); + newCodeOfMeshImpacted.push_back(newCode); + meshesImpacted.push_back(m); + } + } + if(!meshesImpacted.empty()) + { + MEDFileFields *fs=_fields; + if(fs) + for(std::size_t i=0;i<meshesImpacted.size();i++) + fs->renumberEntitiesLyingOnMesh(meshesImpacted[i]->getName(),oldCodeOfMeshImpacted[i],newCodeOfMeshImpacted[i],renumParamsOfMeshImpacted[i]); + } + return !meshesImpacted.empty(); +} + +MEDFileData::MEDFileData() +{ +} + +MEDFileData::MEDFileData(const std::string& fileName) +try +{ + _fields=MEDFileFields::New(fileName); + _meshes=MEDFileMeshes::New(fileName); + _params=MEDFileParameters::New(fileName); +} +catch(INTERP_KERNEL::Exception& e) +{ + throw e; +} + +void MEDFileData::write(const std::string& fileName, int mode) const +{ + med_access_mode medmod=MEDFileUtilities::TraduceWriteMode(mode); + MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName.c_str(),medmod); + const MEDFileMeshes *ms=_meshes; + if(ms) + ms->write(fid); + const MEDFileFields *fs=_fields; + if(fs) + fs->writeLL(fid); + const MEDFileParameters *ps=_params; + if(ps) + ps->writeLL(fid); +} diff --git a/src/medtool/src/MEDLoader/MEDFileData.hxx b/src/medtool/src/MEDLoader/MEDFileData.hxx new file mode 100644 index 000000000..ce7a2ea36 --- /dev/null +++ b/src/medtool/src/MEDLoader/MEDFileData.hxx @@ -0,0 +1,68 @@ +// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 +// 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 __MEDFILEDATA_HXX__ +#define __MEDFILEDATA_HXX__ + +#include "MEDCouplingAutoRefCountObjectPtr.hxx" +#include "MEDFileParameter.hxx" +#include "MEDFileField.hxx" +#include "MEDFileMesh.hxx" + +namespace ParaMEDMEM +{ + /*! + * User class. + */ + class MEDFileData : public RefCountObject, public MEDFileWritable + { + public: + MEDLOADER_EXPORT static MEDFileData *New(const std::string& fileName); + MEDLOADER_EXPORT static MEDFileData *New(); + MEDLOADER_EXPORT MEDFileData *deepCpy() const; + MEDLOADER_EXPORT std::size_t getHeapMemorySizeWithoutChildren() const; + MEDLOADER_EXPORT std::vector<const BigMemoryObject *> getDirectChildrenWithNull() const; + MEDLOADER_EXPORT MEDFileFields *getFields() const; + MEDLOADER_EXPORT MEDFileMeshes *getMeshes() const; + MEDLOADER_EXPORT MEDFileParameters *getParams() const; + MEDLOADER_EXPORT void setFields(MEDFileFields *fields); + MEDLOADER_EXPORT void setMeshes(MEDFileMeshes *meshes); + MEDLOADER_EXPORT void setParams(MEDFileParameters *params); + MEDLOADER_EXPORT int getNumberOfFields() const; + MEDLOADER_EXPORT int getNumberOfMeshes() const; + MEDLOADER_EXPORT int getNumberOfParams() const; + MEDLOADER_EXPORT std::string simpleRepr() const; + // + MEDLOADER_EXPORT bool changeMeshNames(const std::vector< std::pair<std::string,std::string> >& modifTab); + MEDLOADER_EXPORT bool changeMeshName(const std::string& oldMeshName, const std::string& newMeshName); + MEDLOADER_EXPORT bool unPolyzeMeshes(); + // + MEDLOADER_EXPORT void write(const std::string& fileName, int mode) const; + private: + MEDFileData(); + MEDFileData(const std::string& fileName); + private: + MEDCouplingAutoRefCountObjectPtr<MEDFileFields> _fields; + MEDCouplingAutoRefCountObjectPtr<MEDFileMeshes> _meshes; + MEDCouplingAutoRefCountObjectPtr<MEDFileParameters> _params; + }; +} + +#endif diff --git a/src/medtool/src/MEDLoader/MEDFileField.cxx b/src/medtool/src/MEDLoader/MEDFileField.cxx new file mode 100644 index 000000000..932e70028 --- /dev/null +++ b/src/medtool/src/MEDLoader/MEDFileField.cxx @@ -0,0 +1,10491 @@ +// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 +// 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 "MEDFileField.hxx" +#include "MEDFileMesh.hxx" +#include "MEDLoaderBase.hxx" +#include "MEDFileUtilities.hxx" +#include "MEDFileSafeCaller.txx" +#include "MEDFileFieldOverView.hxx" + +#include "MEDCouplingFieldDouble.hxx" +#include "MEDCouplingFieldDiscretization.hxx" + +#include "InterpKernelAutoPtr.hxx" +#include "CellModel.hxx" + +#include <algorithm> +#include <iterator> + +extern med_geometry_type typmai[MED_N_CELL_FIXED_GEO]; +extern INTERP_KERNEL::NormalizedCellType typmai2[MED_N_CELL_FIXED_GEO]; +extern med_geometry_type typmainoeud[1]; +extern med_geometry_type typmai3[34]; + +using namespace ParaMEDMEM; + +const char MEDFileField1TSWithoutSDA::TYPE_STR[]="FLOAT64"; +const char MEDFileIntField1TSWithoutSDA::TYPE_STR[]="INT32"; + +MEDFileFieldLoc *MEDFileFieldLoc::New(med_idt fid, const std::string& locName) +{ + return new MEDFileFieldLoc(fid,locName); +} + +MEDFileFieldLoc *MEDFileFieldLoc::New(med_idt fid, int id) +{ + return new MEDFileFieldLoc(fid,id); +} + +MEDFileFieldLoc *MEDFileFieldLoc::New(const std::string& locName, INTERP_KERNEL::NormalizedCellType geoType, const std::vector<double>& refCoo, const std::vector<double>& gsCoo, const std::vector<double>& w) +{ + return new MEDFileFieldLoc(locName,geoType,refCoo,gsCoo,w); +} + +MEDFileFieldLoc::MEDFileFieldLoc(med_idt fid, const std::string& locName):_name(locName) +{ + med_geometry_type geotype; + med_geometry_type sectiongeotype; + int nsectionmeshcell; + INTERP_KERNEL::AutoPtr<char> geointerpname=MEDLoaderBase::buildEmptyString(MED_NAME_SIZE); + INTERP_KERNEL::AutoPtr<char> sectionmeshname=MEDLoaderBase::buildEmptyString(MED_NAME_SIZE); + MEDlocalizationInfoByName(fid,locName.c_str(),&geotype,&_dim,&_nb_gauss_pt,geointerpname,sectionmeshname,&nsectionmeshcell,§iongeotype); + _geo_type=(INTERP_KERNEL::NormalizedCellType)(std::distance(typmai3,std::find(typmai3,typmai3+34,geotype))); + const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(_geo_type); + _nb_node_per_cell=cm.getNumberOfNodes(); + _ref_coo.resize(_dim*_nb_node_per_cell); + _gs_coo.resize(_dim*_nb_gauss_pt); + _w.resize(_nb_gauss_pt); + MEDlocalizationRd(fid,locName.c_str(),MED_FULL_INTERLACE,&_ref_coo[0],&_gs_coo[0],&_w[0]); +} + +MEDFileFieldLoc::MEDFileFieldLoc(med_idt fid, int id) +{ + med_geometry_type geotype; + med_geometry_type sectiongeotype; + int nsectionmeshcell; + INTERP_KERNEL::AutoPtr<char> locName=MEDLoaderBase::buildEmptyString(MED_NAME_SIZE); + INTERP_KERNEL::AutoPtr<char> geointerpname=MEDLoaderBase::buildEmptyString(MED_NAME_SIZE); + INTERP_KERNEL::AutoPtr<char> sectionmeshname=MEDLoaderBase::buildEmptyString(MED_NAME_SIZE); + MEDlocalizationInfo(fid,id+1,locName,&geotype,&_dim,&_nb_gauss_pt,geointerpname,sectionmeshname,&nsectionmeshcell,§iongeotype); + _name=locName; + _geo_type=(INTERP_KERNEL::NormalizedCellType)(std::distance(typmai3,std::find(typmai3,typmai3+34,geotype))); + const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(_geo_type); + _nb_node_per_cell=cm.getNumberOfNodes(); + _ref_coo.resize(_dim*_nb_node_per_cell); + _gs_coo.resize(_dim*_nb_gauss_pt); + _w.resize(_nb_gauss_pt); + MEDlocalizationRd(fid,locName,MED_FULL_INTERLACE,&_ref_coo[0],&_gs_coo[0],&_w[0]); +} + +MEDFileFieldLoc::MEDFileFieldLoc(const std::string& locName, INTERP_KERNEL::NormalizedCellType geoType, + const std::vector<double>& refCoo, const std::vector<double>& gsCoo, const std::vector<double>& w):_name(locName),_geo_type(geoType),_ref_coo(refCoo),_gs_coo(gsCoo), + _w(w) +{ + const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(_geo_type); + _dim=cm.getDimension(); + _nb_node_per_cell=cm.getNumberOfNodes(); + _nb_gauss_pt=_w.size(); +} + +MEDFileFieldLoc *MEDFileFieldLoc::deepCpy() const +{ + return new MEDFileFieldLoc(*this); +} + +std::size_t MEDFileFieldLoc::getHeapMemorySizeWithoutChildren() const +{ + return (_ref_coo.capacity()+_gs_coo.capacity()+_w.capacity())*sizeof(double)+_name.capacity(); +} + +std::vector<const BigMemoryObject *> MEDFileFieldLoc::getDirectChildrenWithNull() const +{ + return std::vector<const BigMemoryObject *>(); +} + +void MEDFileFieldLoc::simpleRepr(std::ostream& oss) const +{ + static const char OFF7[]="\n "; + oss << "\"" << _name << "\"" << OFF7; + oss << "GeoType=" << INTERP_KERNEL::CellModel::GetCellModel(_geo_type).getRepr() << OFF7; + oss << "Dimension=" << _dim << OFF7; + oss << "Number of Gauss points=" << _nb_gauss_pt << OFF7; + oss << "Number of nodes per cell=" << _nb_node_per_cell << OFF7; + oss << "RefCoords="; std::copy(_ref_coo.begin(),_ref_coo.end(),std::ostream_iterator<double>(oss," ")); oss << OFF7; + oss << "Weights="; std::copy(_w.begin(),_w.end(),std::ostream_iterator<double>(oss," ")); oss << OFF7; + oss << "GaussPtsCoords="; std::copy(_gs_coo.begin(),_gs_coo.end(),std::ostream_iterator<double>(oss," ")); oss << std::endl; +} + +void MEDFileFieldLoc::setName(const std::string& name) +{ + _name=name; +} + +bool MEDFileFieldLoc::isEqual(const MEDFileFieldLoc& other, double eps) const +{ + if(_name!=other._name) + return false; + if(_dim!=other._dim) + return false; + if(_nb_gauss_pt!=other._nb_gauss_pt) + return false; + if(_nb_node_per_cell!=other._nb_node_per_cell) + return false; + if(_geo_type!=other._geo_type) + return false; + if(!MEDCouplingGaussLocalization::AreAlmostEqual(_ref_coo,other._ref_coo,eps)) + return false; + if(!MEDCouplingGaussLocalization::AreAlmostEqual(_gs_coo,other._gs_coo,eps)) + return false; + if(!MEDCouplingGaussLocalization::AreAlmostEqual(_w,other._w,eps)) + return false; + + return true; +} + +void MEDFileFieldLoc::writeLL(med_idt fid) const +{ + MEDlocalizationWr(fid,_name.c_str(),typmai3[(int)_geo_type],_dim,&_ref_coo[0],MED_FULL_INTERLACE,_nb_gauss_pt,&_gs_coo[0],&_w[0],MED_NO_INTERPOLATION,MED_NO_MESH_SUPPORT); +} + +std::string MEDFileFieldLoc::repr() const +{ + std::ostringstream oss; oss.precision(15); + const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(_geo_type); + oss << "Localization \"" << _name << "\" :\n" << " - Geometric Type : " << cm.getRepr(); + oss << "\n - Dimension : " << _dim << "\n - Number of gauss points : "; + oss << _nb_gauss_pt << "\n - Number of nodes in cell : " << _nb_node_per_cell; + oss << "\n - Ref coords are : "; + int sz=_ref_coo.size(); + if(sz%_dim==0) + { + int nbOfTuples=sz/_dim; + for(int i=0;i<nbOfTuples;i++) + { + oss << "("; + for(int j=0;j<_dim;j++) + { oss << _ref_coo[i*_dim+j]; if(j!=_dim-1) oss << ", "; } + oss << ") "; + } + } + else + std::copy(_ref_coo.begin(),_ref_coo.end(),std::ostream_iterator<double>(oss," ")); + oss << "\n - Gauss coords in reference element : "; + sz=_gs_coo.size(); + if(sz%_dim==0) + { + int nbOfTuples=sz/_dim; + for(int i=0;i<nbOfTuples;i++) + { + oss << "("; + for(int j=0;j<_dim;j++) + { oss << _gs_coo[i*_dim+j]; if(j!=_dim-1) oss << ", "; } + oss << ") "; + } + } + else + std::copy(_gs_coo.begin(),_gs_coo.end(),std::ostream_iterator<double>(oss," ")); + oss << "\n - Weights of Gauss coords are : "; std::copy(_w.begin(),_w.end(),std::ostream_iterator<double>(oss," ")); + return oss.str(); +} + +void MEDFileFieldPerMeshPerTypePerDisc::assignFieldNoProfile(int& start, int offset, int nbOfCells, const MEDCouplingFieldDouble *field, const DataArray *arrr, MEDFileFieldGlobsReal& glob, const MEDFileFieldNameScope& nasc) +{ + _type=field->getTypeOfField(); + _start=start; + switch(_type) + { + case ON_CELLS: + { + getOrCreateAndGetArray()->setContigPartOfSelectedValues2(_start,arrr,offset,offset+nbOfCells,1); + _end=_start+nbOfCells; + _nval=nbOfCells; + break; + } + case ON_GAUSS_NE: + { + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> arr=field->getDiscretization()->getOffsetArr(field->getMesh()); + const int *arrPtr=arr->getConstPointer(); + getOrCreateAndGetArray()->setContigPartOfSelectedValues2(_start,arrr,arrPtr[offset],arrPtr[offset+nbOfCells],1); + _end=_start+(arrPtr[offset+nbOfCells]-arrPtr[offset]); + _nval=nbOfCells; + break; + } + case ON_GAUSS_PT: + { + const MEDCouplingFieldDiscretization *disc=field->getDiscretization(); + const MEDCouplingGaussLocalization& gsLoc=field->getGaussLocalization(_loc_id); + const MEDCouplingFieldDiscretizationGauss *disc2=dynamic_cast<const MEDCouplingFieldDiscretizationGauss *>(disc); + if(!disc2) + throw INTERP_KERNEL::Exception("assignFieldNoProfile : invalid call to this method ! Internal Error !"); + const DataArrayInt *dai=disc2->getArrayOfDiscIds(); + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> dai2=disc2->getOffsetArr(field->getMesh()); + const int *dai2Ptr=dai2->getConstPointer(); + int nbi=gsLoc.getWeights().size(); + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> da2=dai->selectByTupleId2(offset,offset+nbOfCells,1); + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> da3=da2->getIdsEqual(_loc_id); + const int *da3Ptr=da3->getConstPointer(); + if(da3->getNumberOfTuples()!=nbOfCells) + {//profile : for gauss even in NoProfile !!! + std::ostringstream oss; oss << "Pfl_" << nasc.getName() << "_" << INTERP_KERNEL::CellModel::GetCellModel(getGeoType()).getRepr() << "_" << _loc_id; + _profile=oss.str(); + da3->setName(_profile.c_str()); + glob.appendProfile(da3); + } + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> da4=DataArrayInt::New(); + _nval=da3->getNbOfElems(); + da4->alloc(_nval*nbi,1); + int *da4Ptr=da4->getPointer(); + for(int i=0;i<_nval;i++) + { + int ref=dai2Ptr[offset+da3Ptr[i]]; + for(int j=0;j<nbi;j++) + *da4Ptr++=ref+j; + } + std::ostringstream oss2; oss2 << "Loc_" << nasc.getName() << "_" << INTERP_KERNEL::CellModel::GetCellModel(getGeoType()).getRepr() << "_" << _loc_id; + _localization=oss2.str(); + getOrCreateAndGetArray()->setContigPartOfSelectedValues(_start,arrr,da4); + _end=_start+_nval*nbi; + glob.appendLoc(_localization.c_str(),getGeoType(),gsLoc.getRefCoords(),gsLoc.getGaussCoords(),gsLoc.getWeights()); + break; + } + default: + throw INTERP_KERNEL::Exception("MEDFileFieldPerMeshPerTypePerDisc::assignFieldNoProfile : not implemented yet for such discretization type of field !"); + } + start=_end; +} + +/*! + * Leaf method of field with profile assignement. This method is the most general one. No optimization is done here. + * \param [in] pflName input containing name of profile if any. 0 if no profile (except for GAUSS_PT where a no profile can hide a profile when splitted by loc_id). + * \param [in] multiTypePfl is the end user profile specified in high level API + * \param [in] idsInPfl is the selection into the \a multiTypePfl whole profile that corresponds to the current geometric type. + * \param [in] locIds is the profile needed to be created for MED file format. It can be null if all cells of current geometric type are fetched in \a multiTypePfl. + * \b WARNING if not null the MED file profile can be subdivided again in case of Gauss points. + * \param [in] mesh is the mesh coming from the MEDFileMesh instance in correspondance with the MEDFileField. The mesh inside the \a field is simply ignored. + */ +void MEDFileFieldPerMeshPerTypePerDisc::assignFieldProfile(bool isPflAlone, int& start, const DataArrayInt *multiTypePfl, const DataArrayInt *idsInPfl, DataArrayInt *locIds, int nbOfEltsInWholeMesh, const MEDCouplingFieldDouble *field, const DataArray *arrr, const MEDCouplingMesh *mesh, MEDFileFieldGlobsReal& glob, const MEDFileFieldNameScope& nasc) +{ + _profile.clear(); + _type=field->getTypeOfField(); + std::string pflName(multiTypePfl->getName()); + std::ostringstream oss; oss << pflName; + if(_type!=ON_NODES) + { + if(!isPflAlone) + { const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(getGeoType()); oss << "_" << cm.getRepr(); } + } + else + { oss << "_NODE"; } + if(locIds) + { + if(pflName.empty()) + throw INTERP_KERNEL::Exception("MEDFileFieldPerMeshPerTypePerDisc::assignFieldProfile : existing profile with empty name !"); + if(_type!=ON_GAUSS_PT) + { + locIds->setName(oss.str().c_str()); + glob.appendProfile(locIds); + _profile=oss.str(); + } + } + _start=start; + switch(_type) + { + case ON_NODES: + { + _nval=idsInPfl->getNumberOfTuples(); + getOrCreateAndGetArray()->setContigPartOfSelectedValues2(_start,arrr,0,arrr->getNumberOfTuples(),1); + _end=_start+_nval; + break; + } + case ON_CELLS: + { + _nval=idsInPfl->getNumberOfTuples(); + getOrCreateAndGetArray()->setContigPartOfSelectedValues(_start,arrr,idsInPfl); + _end=_start+_nval; + break; + } + case ON_GAUSS_NE: + { + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> arr=field->getDiscretization()->getOffsetArr(mesh); + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> arr2=arr->deltaShiftIndex(); + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> arr3=arr2->selectByTupleId(multiTypePfl->begin(),multiTypePfl->end()); + arr3->computeOffsets2(); + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> tmp=idsInPfl->buildExplicitArrByRanges(arr3); + int trueNval=tmp->getNumberOfTuples(); + _nval=idsInPfl->getNumberOfTuples(); + getOrCreateAndGetArray()->setContigPartOfSelectedValues(_start,arrr,tmp); + _end=_start+trueNval; + break; + } + case ON_GAUSS_PT: + { + const MEDCouplingFieldDiscretizationGauss *disc2=dynamic_cast<const MEDCouplingFieldDiscretizationGauss *>(field->getDiscretization()); + if(!disc2) + throw INTERP_KERNEL::Exception("addNewEntryIfNecessaryGauss : invalid call to this method ! Internal Error !"); + const DataArrayInt *da1=disc2->getArrayOfDiscIds(); + const MEDCouplingGaussLocalization& gsLoc=field->getGaussLocalization(_loc_id); + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> da2=da1->selectByTupleId(idsInPfl->begin(),idsInPfl->end()); + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> da3=da2->getIdsEqual(_loc_id); + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> da4=idsInPfl->selectByTupleId(da3->begin(),da3->end()); + // + MEDCouplingAutoRefCountObjectPtr<MEDCouplingMesh> mesh2=mesh->buildPart(multiTypePfl->begin(),multiTypePfl->end()); + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> arr=disc2->getOffsetArr(mesh2); + // + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> tmp=DataArrayInt::New(); + int trueNval=0; + for(const int *pt=da4->begin();pt!=da4->end();pt++) + trueNval+=arr->getIJ(*pt+1,0)-arr->getIJ(*pt,0); + tmp->alloc(trueNval,1); + int *tmpPtr=tmp->getPointer(); + for(const int *pt=da4->begin();pt!=da4->end();pt++) + for(int j=arr->getIJ(*pt,0);j<arr->getIJ(*pt+1,0);j++) + *tmpPtr++=j; + // + _nval=da4->getNumberOfTuples(); + getOrCreateAndGetArray()->setContigPartOfSelectedValues(_start,arrr,tmp); + _end=_start+trueNval; + oss << "_loc_" << _loc_id; + if(locIds) + { + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> da5=locIds->selectByTupleId(da3->begin(),da3->end()); + da5->setName(oss.str().c_str()); + glob.appendProfile(da5); + _profile=oss.str(); + } + else + { + if(da3->getNumberOfTuples()!=nbOfEltsInWholeMesh || !da3->isIdentity()) + { + da3->setName(oss.str().c_str()); + glob.appendProfile(da3); + _profile=oss.str(); + } + } + std::ostringstream oss2; oss2 << "Loc_" << nasc.getName() << "_" << INTERP_KERNEL::CellModel::GetCellModel(getGeoType()).getRepr() << "_" << _loc_id; + _localization=oss2.str(); + glob.appendLoc(_localization.c_str(),getGeoType(),gsLoc.getRefCoords(),gsLoc.getGaussCoords(),gsLoc.getWeights()); + break; + } + default: + throw INTERP_KERNEL::Exception("MEDFileFieldPerMeshPerTypePerDisc::assignFieldProfile : not implemented yet for such discretization type of field !"); + } + start=_end; +} + +void MEDFileFieldPerMeshPerTypePerDisc::assignNodeFieldNoProfile(int& start, const MEDCouplingFieldDouble *field, const DataArray *arrr, MEDFileFieldGlobsReal& glob) +{ + _start=start; + _nval=arrr->getNumberOfTuples(); + getOrCreateAndGetArray()->setContigPartOfSelectedValues2(_start,arrr,0,_nval,1); + _end=_start+_nval; + start=_end; +} + +MEDFileFieldPerMeshPerTypePerDisc *MEDFileFieldPerMeshPerTypePerDisc::NewOnRead(MEDFileFieldPerMeshPerType *fath, TypeOfField type, int profileIt, const PartDefinition *pd) +{ + return new MEDFileFieldPerMeshPerTypePerDisc(fath,type,profileIt,pd); +} + +MEDFileFieldPerMeshPerTypePerDisc *MEDFileFieldPerMeshPerTypePerDisc::New(MEDFileFieldPerMeshPerType *fath, TypeOfField type, int locId) +{ + return new MEDFileFieldPerMeshPerTypePerDisc(fath,type,locId,std::string()); +} + +MEDFileFieldPerMeshPerTypePerDisc *MEDFileFieldPerMeshPerTypePerDisc::New(const MEDFileFieldPerMeshPerTypePerDisc& other) +{ + return new MEDFileFieldPerMeshPerTypePerDisc(other); +} + +std::size_t MEDFileFieldPerMeshPerTypePerDisc::getHeapMemorySizeWithoutChildren() const +{ + return _profile.capacity()+_localization.capacity()+sizeof(MEDFileFieldPerMeshPerTypePerDisc); +} + +std::vector<const BigMemoryObject *> MEDFileFieldPerMeshPerTypePerDisc::getDirectChildrenWithNull() const +{ + std::vector<const BigMemoryObject *> ret(1); + ret[0]=(const PartDefinition*)_pd; + return ret; +} + +MEDFileFieldPerMeshPerTypePerDisc *MEDFileFieldPerMeshPerTypePerDisc::deepCpy(MEDFileFieldPerMeshPerType *father) const +{ + MEDCouplingAutoRefCountObjectPtr<MEDFileFieldPerMeshPerTypePerDisc> ret=new MEDFileFieldPerMeshPerTypePerDisc(*this); + ret->_father=father; + return ret.retn(); +} + +MEDFileFieldPerMeshPerTypePerDisc::MEDFileFieldPerMeshPerTypePerDisc(MEDFileFieldPerMeshPerType *fath, TypeOfField atype, int profileIt, const PartDefinition *pd) +try:_type(atype),_father(fath),_profile_it(profileIt),_pd(const_cast<PartDefinition *>(pd)) +{ + if(pd) + pd->incrRef(); +} +catch(INTERP_KERNEL::Exception& e) +{ + throw e; +} + +MEDFileFieldPerMeshPerTypePerDisc::MEDFileFieldPerMeshPerTypePerDisc(MEDFileFieldPerMeshPerType *fath, TypeOfField type, int locId, const std::string& dummy):_type(type),_father(fath),_loc_id(locId) +{ +} + +MEDFileFieldPerMeshPerTypePerDisc::MEDFileFieldPerMeshPerTypePerDisc(const MEDFileFieldPerMeshPerTypePerDisc& other):RefCountObject(other),_type(other._type),_father(0),_start(other._start),_end(other._end),_nval(other._nval),_profile(other._profile),_localization(other._localization),_loc_id(other._loc_id),_profile_it(other._profile_it),_pd(other._pd),_tmp_work1(other._tmp_work1) +{ +} + +MEDFileFieldPerMeshPerTypePerDisc::MEDFileFieldPerMeshPerTypePerDisc():_type(ON_CELLS),_father(0),_start(-std::numeric_limits<int>::max()),_end(-std::numeric_limits<int>::max()), + _nval(-std::numeric_limits<int>::max()),_loc_id(-std::numeric_limits<int>::max()) +{ +} + +void MEDFileFieldPerMeshPerTypePerDisc::goReadZeValuesInFile(med_idt fid, const std::string& fieldName, int nbOfCompo, int iteration, int order, med_entity_type menti, med_geometry_type mgeoti, unsigned char *startFeedingPtr) +{ + const PartDefinition *pd(_pd); + if(!pd) + { + INTERP_KERNEL::AutoPtr<char> locname(MEDLoaderBase::buildEmptyString(MED_NAME_SIZE)); + int nbi,tmp1; + med_int nbValsInFile(MEDfieldnValueWithProfileByName(fid,fieldName.c_str(),iteration,order,menti,mgeoti,_profile.c_str(),MED_COMPACT_PFLMODE,&tmp1,locname,&nbi)); + if(_end-_start!=nbValsInFile*nbi) + { + std::ostringstream oss; oss << "MEDFileFieldPerMeshPerTypePerDisc::goReadZeValuesInFile : The number of tuples to read is " << nbValsInFile << "*" << nbi << " (nb integration points) ! But in data structure it values " << _end-_start << " is expected !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + MEDFILESAFECALLERRD0(MEDfieldValueWithProfileRd,(fid,fieldName.c_str(),iteration,order,menti,mgeoti,MED_COMPACT_PFLMODE,_profile.c_str(),MED_FULL_INTERLACE,MED_ALL_CONSTITUENT,startFeedingPtr)); + } + else + { + if(!_profile.empty()) + throw INTERP_KERNEL::Exception("MEDFileFieldPerMeshPerTypePerDisc::goReadZeValuesInFile : not implemented !"); + INTERP_KERNEL::AutoPtr<char> pflname(MEDLoaderBase::buildEmptyString(MED_NAME_SIZE)),locname(MEDLoaderBase::buildEmptyString(MED_NAME_SIZE)); + int profilesize,nbi; + int overallNval(MEDfieldnValueWithProfile(fid,fieldName.c_str(),iteration,order,menti,mgeoti,_profile_it+1,MED_COMPACT_PFLMODE,pflname,&profilesize,locname,&nbi)); + const SlicePartDefinition *spd(dynamic_cast<const SlicePartDefinition *>(pd)); + if(spd) + { + int start,stop,step; + spd->getSlice(start,stop,step); + int nbOfEltsToLoad(DataArray::GetNumberOfItemGivenBES(start,stop,step,"MEDFileFieldPerMeshPerTypePerDisc::goReadZeValuesInFile")); + med_filter filter=MED_FILTER_INIT; + MEDfilterBlockOfEntityCr(fid,/*nentity*/overallNval,/*nvaluesperentity*/nbi,/*nconstituentpervalue*/nbOfCompo, + MED_ALL_CONSTITUENT,MED_FULL_INTERLACE,MED_COMPACT_STMODE,MED_NO_PROFILE, + /*start*/start+1,/*stride*/step,/*count*/1,/*blocksize*/nbOfEltsToLoad, + /*lastblocksize=useless because count=1*/0,&filter); + MEDFILESAFECALLERRD0(MEDfieldValueAdvancedRd,(fid,fieldName.c_str(),iteration,order,menti,mgeoti,&filter,startFeedingPtr)); + MEDfilterClose(&filter); + return ; + } + const DataArrayPartDefinition *dpd(dynamic_cast<const DataArrayPartDefinition *>(pd)); + if(dpd) + { + dpd->checkCoherency(); + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> myIds(dpd->toDAI()); + int a(myIds->getMinValueInArray()),b(myIds->getMaxValueInArray()); + myIds->applyLin(1,-a); + int nbOfEltsToLoad(b-a+1); + med_filter filter=MED_FILTER_INIT; + {//TODO : manage int32 ! + MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> tmp(DataArrayDouble::New()); + tmp->alloc(nbOfEltsToLoad,nbOfCompo); + MEDfilterBlockOfEntityCr(fid,/*nentity*/overallNval,/*nvaluesperentity*/nbi,/*nconstituentpervalue*/nbOfCompo, + MED_ALL_CONSTITUENT,MED_FULL_INTERLACE,MED_COMPACT_STMODE,MED_NO_PROFILE, + /*start*/a+1,/*stride*/1,/*count*/1,/*blocksize*/nbOfEltsToLoad, + /*lastblocksize=useless because count=1*/0,&filter); + MEDFILESAFECALLERRD0(MEDfieldValueAdvancedRd,(fid,fieldName.c_str(),iteration,order,menti,mgeoti,&filter,reinterpret_cast<unsigned char *>(tmp->getPointer()))); + MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> feeder(DataArrayDouble::New()); + feeder->useExternalArrayWithRWAccess(reinterpret_cast<double *>(startFeedingPtr),_nval,nbOfCompo); + feeder->setContigPartOfSelectedValues(0,tmp,myIds); + } + MEDfilterClose(&filter); + } + else + throw INTERP_KERNEL::Exception("Not implemented yet for not slices!"); + } +} + +const MEDFileFieldPerMeshPerType *MEDFileFieldPerMeshPerTypePerDisc::getFather() const +{ + return _father; +} + +void MEDFileFieldPerMeshPerTypePerDisc::loadOnlyStructureOfDataRecursively(med_idt fid, int& start, const MEDFileFieldNameScope& nasc) +{ + INTERP_KERNEL::AutoPtr<char> locname(MEDLoaderBase::buildEmptyString(MED_NAME_SIZE)); + INTERP_KERNEL::AutoPtr<char> pflname(MEDLoaderBase::buildEmptyString(MED_NAME_SIZE)); + std::string fieldName(nasc.getName()),meshName(getMeshName()); + int iteration(getIteration()),order(getOrder()); + TypeOfField type(getType()); + INTERP_KERNEL::NormalizedCellType geoType(getGeoType()); + int profilesize,nbi; + med_geometry_type mgeoti; + med_entity_type menti(MEDFileFieldPerMeshPerType::ConvertIntoMEDFileType(type,geoType,mgeoti)); + int zeNVal(MEDfieldnValueWithProfile(fid,fieldName.c_str(),iteration,order,menti,mgeoti,_profile_it+1,MED_COMPACT_PFLMODE,pflname,&profilesize,locname,&nbi)); + _profile=MEDLoaderBase::buildStringFromFortran(pflname,MED_NAME_SIZE); + _localization=MEDLoaderBase::buildStringFromFortran(locname,MED_NAME_SIZE); + const PartDefinition *pd(_pd); + if(!pd) + { + _nval=zeNVal; + } + else + { + if(!_profile.empty()) + throw INTERP_KERNEL::Exception("MEDFileFieldPerMeshPerTypePerDisc::loadOnlyStructureOfDataRecursively : profiles are not managed yet with part of def !"); + _nval=pd->getNumberOfElems(); + } + _start=start; + _end=start+_nval*nbi; + start=_end; + if(type==ON_CELLS && !_localization.empty()) + { + if(_localization!="MED_GAUSS_ELNO")//For compatibily with MED2.3 + setType(ON_GAUSS_PT); + else + { + setType(ON_GAUSS_NE); + _localization.clear(); + } + } +} + +void MEDFileFieldPerMeshPerTypePerDisc::loadBigArray(med_idt fid, const MEDFileFieldNameScope& nasc) +{ + std::string fieldName(nasc.getName()),meshName(getMeshName()); + int iteration(getIteration()),order(getOrder()); + TypeOfField type(getType()); + INTERP_KERNEL::NormalizedCellType geoType(getGeoType()); + med_geometry_type mgeoti; + med_entity_type menti(MEDFileFieldPerMeshPerType::ConvertIntoMEDFileType(type,geoType,mgeoti)); + if(_start>_end) + throw INTERP_KERNEL::Exception("MEDFileFieldPerMeshPerTypePerDisc::loadBigArray : internal error in range !"); + if(_start==_end) + return ; + DataArray *arr(getOrCreateAndGetArray());//arr is not null due to the spec of getOrCreateAndGetArray + if(_start<0 || _start>=arr->getNumberOfTuples()) + { + std::ostringstream oss; oss << "MEDFileFieldPerMeshPerTypePerDisc::loadBigArray : Invalid start ("<< _start << ") regarding admissible range of allocated array [0," << arr->getNumberOfTuples() << ") !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + if(_end<0 || _end>arr->getNumberOfTuples()) + { + std::ostringstream oss; oss << "MEDFileFieldPerMeshPerTypePerDisc::loadBigArray : Invalid start ("<< _start << ") regarding admissible range of allocated array [0," << arr->getNumberOfTuples() << "] !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + int nbOfCompo(arr->getNumberOfComponents()); + DataArrayDouble *arrD(dynamic_cast<DataArrayDouble *>(arr)); + if(arrD) + { + double *startFeeding(arrD->getPointer()+_start*nbOfCompo); + goReadZeValuesInFile(fid,fieldName,nbOfCompo,iteration,order,menti,mgeoti,reinterpret_cast<unsigned char*>(startFeeding)); + return ; + } + DataArrayInt *arrI(dynamic_cast<DataArrayInt *>(arr)); + if(arrI) + { + int *startFeeding(arrI->getPointer()+_start*nbOfCompo); + goReadZeValuesInFile(fid,fieldName,nbOfCompo,iteration,order,menti,mgeoti,reinterpret_cast<unsigned char*>(startFeeding)); + return ; + } + throw INTERP_KERNEL::Exception("Error on array reading ! Unrecognized type of field ! Should be in FLOAT64 or INT32 !"); +} + +/*! + * Set a \c this->_start **and** \c this->_end keeping the same delta between the two. + */ +void MEDFileFieldPerMeshPerTypePerDisc::setNewStart(int newValueOfStart) +{ + int delta=_end-_start; + _start=newValueOfStart; + _end=_start+delta; +} + +int MEDFileFieldPerMeshPerTypePerDisc::getIteration() const +{ + return _father->getIteration(); +} + +int MEDFileFieldPerMeshPerTypePerDisc::getOrder() const +{ + return _father->getOrder(); +} + +double MEDFileFieldPerMeshPerTypePerDisc::getTime() const +{ + return _father->getTime(); +} + +std::string MEDFileFieldPerMeshPerTypePerDisc::getMeshName() const +{ + return _father->getMeshName(); +} + +void MEDFileFieldPerMeshPerTypePerDisc::simpleRepr(int bkOffset, std::ostream& oss, int id) const +{ + const char startLine[]=" ## "; + std::string startLine2(bkOffset,' '); + startLine2+=startLine; + MEDCouplingFieldDiscretization *tmp=MEDCouplingFieldDiscretization::New(_type); + oss << startLine2 << "Localization #" << id << "." << std::endl; + oss << startLine2 << " Type=" << tmp->getRepr() << "." << std::endl; + delete tmp; + oss << startLine2 << " This type discretization lies on profile : \"" << _profile << "\" and on the following localization : \"" << _localization << "\"." << std::endl; + oss << startLine2 << " This type discretization has " << _end-_start << " tuples (start=" << _start << ", end=" << _end << ")." << std::endl; + oss << startLine2 << " This type discretization has " << (_end-_start)/_nval << " integration points." << std::endl; +} + +TypeOfField MEDFileFieldPerMeshPerTypePerDisc::getType() const +{ + return _type; +} + +void MEDFileFieldPerMeshPerTypePerDisc::fillTypesOfFieldAvailable(std::set<TypeOfField>& types) const +{ + types.insert(_type); +} + +void MEDFileFieldPerMeshPerTypePerDisc::setType(TypeOfField newType) +{ + _type=newType; +} + +INTERP_KERNEL::NormalizedCellType MEDFileFieldPerMeshPerTypePerDisc::getGeoType() const +{ + return _father->getGeoType(); +} + +int MEDFileFieldPerMeshPerTypePerDisc::getNumberOfComponents() const +{ + return _father->getNumberOfComponents(); +} + +int MEDFileFieldPerMeshPerTypePerDisc::getNumberOfTuples() const +{ + return _end-_start; +} + +DataArray *MEDFileFieldPerMeshPerTypePerDisc::getOrCreateAndGetArray() +{ + return _father->getOrCreateAndGetArray(); +} + +const DataArray *MEDFileFieldPerMeshPerTypePerDisc::getOrCreateAndGetArray() const +{ + const MEDFileFieldPerMeshPerType *fath=_father; + return fath->getOrCreateAndGetArray(); +} + +const std::vector<std::string>& MEDFileFieldPerMeshPerTypePerDisc::getInfo() const +{ + return _father->getInfo(); +} + +std::string MEDFileFieldPerMeshPerTypePerDisc::getProfile() const +{ + return _profile; +} + +void MEDFileFieldPerMeshPerTypePerDisc::setProfile(const std::string& newPflName) +{ + _profile=newPflName; +} + +std::string MEDFileFieldPerMeshPerTypePerDisc::getLocalization() const +{ + return _localization; +} + +void MEDFileFieldPerMeshPerTypePerDisc::setLocalization(const std::string& newLocName) +{ + _localization=newLocName; +} + +void MEDFileFieldPerMeshPerTypePerDisc::changePflsRefsNamesGen(const std::vector< std::pair<std::vector<std::string>, std::string > >& mapOfModif) +{ + for(std::vector< std::pair<std::vector<std::string>, std::string > >::const_iterator it2=mapOfModif.begin();it2!=mapOfModif.end();it2++) + { + if(std::find((*it2).first.begin(),(*it2).first.end(),_profile)!=(*it2).first.end()) + { + _profile=(*it2).second; + return; + } + } +} + +void MEDFileFieldPerMeshPerTypePerDisc::changeLocsRefsNamesGen(const std::vector< std::pair<std::vector<std::string>, std::string > >& mapOfModif) +{ + for(std::vector< std::pair<std::vector<std::string>, std::string > >::const_iterator it2=mapOfModif.begin();it2!=mapOfModif.end();it2++) + { + if(std::find((*it2).first.begin(),(*it2).first.end(),_localization)!=(*it2).first.end()) + { + _localization=(*it2).second; + return; + } + } +} + +void MEDFileFieldPerMeshPerTypePerDisc::getFieldAtLevel(TypeOfField type, const MEDFileFieldGlobsReal *glob, std::vector< std::pair<int,int> >& dads, std::vector<const DataArrayInt *>& pfls, std::vector<int>& locs, std::vector<INTERP_KERNEL::NormalizedCellType>& geoTypes) const +{ + if(type!=_type) + return ; + dads.push_back(std::pair<int,int>(_start,_end)); + geoTypes.push_back(getGeoType()); + if(_profile.empty()) + pfls.push_back(0); + else + { + pfls.push_back(glob->getProfile(_profile.c_str())); + } + if(_localization.empty()) + locs.push_back(-1); + else + { + locs.push_back(glob->getLocalizationId(_localization.c_str())); + } +} + +void MEDFileFieldPerMeshPerTypePerDisc::fillValues(int discId, int& startEntryId, std::vector< std::pair<std::pair<INTERP_KERNEL::NormalizedCellType,int>,std::pair<int,int> > >& entries) const +{ + entries[startEntryId]=std::pair<std::pair<INTERP_KERNEL::NormalizedCellType,int> ,std::pair<int,int> >(std::pair<INTERP_KERNEL::NormalizedCellType,int>(getGeoType(),discId),std::pair<int,int>(_start,_end)); + startEntryId++; +} + +void MEDFileFieldPerMeshPerTypePerDisc::writeLL(med_idt fid, const MEDFileFieldNameScope& nasc) const +{ + TypeOfField type=getType(); + INTERP_KERNEL::NormalizedCellType geoType=getGeoType(); + med_geometry_type mgeoti; + med_entity_type menti=MEDFileFieldPerMeshPerType::ConvertIntoMEDFileType(type,geoType,mgeoti); + const DataArray *arr=getOrCreateAndGetArray(); + if(!arr) + throw INTERP_KERNEL::Exception("MEDFileFieldPerMeshPerTypePerDisc::writeLL : no array set !"); + const DataArrayDouble *arrD=dynamic_cast<const DataArrayDouble *>(arr); + const DataArrayInt *arrI=dynamic_cast<const DataArrayInt *>(arr); + const unsigned char *locToWrite=0; + if(arrD) + locToWrite=reinterpret_cast<const unsigned char *>(arrD->getConstPointer()+_start*arr->getNumberOfComponents()); + else if(arrI) + locToWrite=reinterpret_cast<const unsigned char *>(arrI->getConstPointer()+_start*arr->getNumberOfComponents()); + else + throw INTERP_KERNEL::Exception("MEDFileFieldPerMeshPerTypePerDisc::writeLL : not recognized type of values ! Supported are FLOAT64 and INT32 !"); + MEDFILESAFECALLERWR0(MEDfieldValueWithProfileWr,(fid,nasc.getName().c_str(),getIteration(),getOrder(),getTime(),menti,mgeoti, + MED_COMPACT_PFLMODE,_profile.c_str(),_localization.c_str(),MED_FULL_INTERLACE,MED_ALL_CONSTITUENT,_nval, + locToWrite)); +} + +void MEDFileFieldPerMeshPerTypePerDisc::getCoarseData(TypeOfField& type, std::pair<int,int>& dad, std::string& pfl, std::string& loc) const +{ + type=_type; + pfl=_profile; + loc=_localization; + dad.first=_start; dad.second=_end; +} + +/*! + * \param [in] codeOfMesh is of format returned by MEDCouplingUMesh::getDistributionOfTypes. And for each *i* oldCode[3*i+2] gives the position (MEDFileUMesh::PutInThirdComponentOfCodeOffset). + * This code corresponds to the distribution of types in the corresponding mesh. + * \param [out] ptToFill memory zone where the output will be stored. + * \return the size of data pushed into output param \a ptToFill + */ +int MEDFileFieldPerMeshPerTypePerDisc::fillEltIdsFromCode(int offset, const std::vector<int>& codeOfMesh, const MEDFileFieldGlobsReal& glob, int *ptToFill) const +{ + _loc_id=offset; + std::ostringstream oss; + std::size_t nbOfType=codeOfMesh.size()/3; + int found=-1; + for(std::size_t i=0;i<nbOfType && found==-1;i++) + if(getGeoType()==(INTERP_KERNEL::NormalizedCellType)codeOfMesh[3*i]) + found=(int)i; + if(found==-1) + { + const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(getGeoType()); + oss << "MEDFileFieldPerMeshPerTypePerDisc::fillEltIdsFromCode : not found geometric type " << cm.getRepr() << " in the referenced mesh of field !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + int *work=ptToFill; + if(_profile.empty()) + { + if(_nval!=codeOfMesh[3*found+1]) + { + const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(getGeoType()); + oss << "MEDFileFieldPerMeshPerTypePerDisc::fillEltIdsFromCode : for geometric type " << cm.getRepr() << " number of elt ids in mesh is equal to " << _nval; + oss << " whereas mesh has " << codeOfMesh[3*found+1] << " for this geometric type !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + for(int ii=codeOfMesh[3*found+2];ii<codeOfMesh[3*found+2]+_nval;ii++) + *work++=ii; + } + else + { + const DataArrayInt *pfl=glob.getProfile(_profile.c_str()); + if(pfl->getNumberOfTuples()!=_nval) + { + const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(getGeoType()); + oss << "MEDFileFieldPerMeshPerTypePerDisc::fillEltIdsFromCode : for geometric type " << cm.getRepr() << ", field is defined on profile \"" << _profile << "\" and size of profile is "; + oss << _nval; + oss << pfl->getNumberOfTuples() << " whereas the number of ids is set to " << _nval << " for this geometric type !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + int offset2=codeOfMesh[3*found+2]; + for(const int *pflId=pfl->begin();pflId!=pfl->end();pflId++) + { + if(*pflId<codeOfMesh[3*found+1]) + *work++=offset2+*pflId; + } + } + return _nval; +} + +int MEDFileFieldPerMeshPerTypePerDisc::fillTupleIds(int *ptToFill) const +{ + for(int i=_start;i<_end;i++) + *ptToFill++=i; + return _end-_start; +} + +int MEDFileFieldPerMeshPerTypePerDisc::ConvertType(TypeOfField type, int locId) +{ + switch(type) + { + case ON_CELLS: + return -2; + case ON_GAUSS_NE: + return -1; + case ON_GAUSS_PT: + return locId; + default: + throw INTERP_KERNEL::Exception("MEDFileFieldPerMeshPerTypePerDisc::ConvertType : not managed type of field !"); + } +} + +std::vector< std::vector< const MEDFileFieldPerMeshPerTypePerDisc *> > MEDFileFieldPerMeshPerTypePerDisc::SplitPerDiscretization(const std::vector< const MEDFileFieldPerMeshPerTypePerDisc *>& entries) +{ + int id=0; + std::map<std::pair<std::string,TypeOfField>,int> m; + std::vector< std::vector< const MEDFileFieldPerMeshPerTypePerDisc *> > ret; + for(std::vector< const MEDFileFieldPerMeshPerTypePerDisc *>::const_iterator it=entries.begin();it!=entries.end();it++) + if(m.find(std::pair<std::string,TypeOfField>((*it)->getLocalization(),(*it)->getType()))==m.end()) + m[std::pair<std::string,TypeOfField>((*it)->getLocalization(),(*it)->getType())]=id++; + ret.resize(id); + for(std::vector< const MEDFileFieldPerMeshPerTypePerDisc *>::const_iterator it=entries.begin();it!=entries.end();it++) + ret[m[std::pair<std::string,TypeOfField>((*it)->getLocalization(),(*it)->getType())]].push_back(*it); + return ret; +} + +/*! + * - \c this->_loc_id mutable attribute is used for elt id in mesh offsets. + * + * \param [in] offset the offset id used to take into account that \a result is not compulsary empty in input + * \param [in] entriesOnSameDisc some entries **on same localization** if not the result can be invalid. The _start and _end on them are relative to \a arr parameter. + * \param [in] explicitIdsInMesh ids in mesh of the considered chunk. + * \param [in] newCode one of the input parameter to explicit the new geo type dispatch (in classical format same than those asked by MEDFileFields::renumberEntitiesLyingOnMesh) + * \param [in,out] glob if necessary by the method, new profiles can be added to it + * \param [in,out] arr after the call of this method \a arr is renumbered to be compliant with added entries to \a result. + * \param [out] result All new entries will be appended on it. + * \return false if the configuration of renumbering leads to an unnecessary resplit of input \a entriesOnSameDisc. If not true is returned (the most general case !) + */ +bool MEDFileFieldPerMeshPerTypePerDisc::RenumberChunks(int offset, const std::vector< const MEDFileFieldPerMeshPerTypePerDisc *>& entriesOnSameDisc, + const DataArrayInt *explicitIdsInMesh, + const std::vector<int>& newCode, + MEDFileFieldGlobsReal& glob, DataArrayDouble *arr, + std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileFieldPerMeshPerTypePerDisc> >& result) +{ + if(entriesOnSameDisc.empty()) + return false; + TypeOfField type=entriesOnSameDisc[0]->getType(); + int szEntities=0,szTuples=0; + for(std::vector< const MEDFileFieldPerMeshPerTypePerDisc *>::const_iterator it=entriesOnSameDisc.begin();it!=entriesOnSameDisc.end();it++) + { szEntities+=(*it)->_nval; szTuples+=(*it)->_end-(*it)->_start; } + int nbi=szTuples/szEntities; + if(szTuples%szEntities!=0) + throw INTERP_KERNEL::Exception("MEDFileFieldPerMeshPerTypePerDisc::RenumberChunks : internal error the splitting into same dicretization failed !"); + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> renumTuples=DataArrayInt::New(); renumTuples->alloc(szTuples,1); + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ranges=MEDCouplingUMesh::ComputeRangesFromTypeDistribution(newCode); + std::vector< MEDCouplingAutoRefCountObjectPtr<DataArrayInt> > newGeoTypesPerChunk(entriesOnSameDisc.size()); + std::vector< const DataArrayInt * > newGeoTypesPerChunk2(entriesOnSameDisc.size()); + std::vector< MEDCouplingAutoRefCountObjectPtr<DataArrayInt> > newGeoTypesPerChunk_bis(entriesOnSameDisc.size()); + std::vector< const DataArrayInt * > newGeoTypesPerChunk3(entriesOnSameDisc.size()); + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> newGeoTypesPerChunk4=DataArrayInt::New(); newGeoTypesPerChunk4->alloc(szEntities,nbi); + int id=0; + for(std::vector< const MEDFileFieldPerMeshPerTypePerDisc *>::const_iterator it=entriesOnSameDisc.begin();it!=entriesOnSameDisc.end();it++,id++) + { + int startOfEltIdOfChunk=(*it)->_start; + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> newEltIds=explicitIdsInMesh->substr(startOfEltIdOfChunk,startOfEltIdOfChunk+(*it)->_nval); + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> rangeIdsForChunk=newEltIds->findRangeIdForEachTuple(ranges); + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> idsInRrangeForChunk=newEltIds->findIdInRangeForEachTuple(ranges); + // + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> tmp=rangeIdsForChunk->duplicateEachTupleNTimes(nbi); rangeIdsForChunk->rearrange(nbi); + newGeoTypesPerChunk4->setPartOfValues1(tmp,(*it)->_tmp_work1-offset,(*it)->_tmp_work1+(*it)->_nval*nbi-offset,1,0,nbi,1); + // + newGeoTypesPerChunk[id]=rangeIdsForChunk; newGeoTypesPerChunk2[id]=rangeIdsForChunk; + newGeoTypesPerChunk_bis[id]=idsInRrangeForChunk; newGeoTypesPerChunk3[id]=idsInRrangeForChunk; + } + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> newGeoTypesEltIdsAllGather=DataArrayInt::Aggregate(newGeoTypesPerChunk2); newGeoTypesPerChunk.clear(); newGeoTypesPerChunk2.clear(); + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> newGeoTypesEltIdsAllGather2=DataArrayInt::Aggregate(newGeoTypesPerChunk3); newGeoTypesPerChunk_bis.clear(); newGeoTypesPerChunk3.clear(); + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> diffVals=newGeoTypesEltIdsAllGather->getDifferentValues(); + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> renumEltIds=newGeoTypesEltIdsAllGather->buildPermArrPerLevel(); + // + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> renumTupleIds=newGeoTypesPerChunk4->buildPermArrPerLevel(); + // + MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> arrPart=arr->substr(offset,offset+szTuples); + arrPart->renumberInPlace(renumTupleIds->begin()); + arr->setPartOfValues1(arrPart,offset,offset+szTuples,1,0,arrPart->getNumberOfComponents(),1); + bool ret=false; + const int *idIt=diffVals->begin(); + std::list<const MEDFileFieldPerMeshPerTypePerDisc *> li(entriesOnSameDisc.begin(),entriesOnSameDisc.end()); + int offset2=0; + for(int i=0;i<diffVals->getNumberOfTuples();i++,idIt++) + { + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ids=newGeoTypesEltIdsAllGather->getIdsEqual(*idIt); + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> subIds=newGeoTypesEltIdsAllGather2->selectByTupleId(ids->begin(),ids->end()); + int nbEntityElts=subIds->getNumberOfTuples(); + bool ret2; + MEDCouplingAutoRefCountObjectPtr<MEDFileFieldPerMeshPerTypePerDisc> eltToAdd=MEDFileFieldPerMeshPerTypePerDisc:: + NewObjectOnSameDiscThanPool(type,(INTERP_KERNEL::NormalizedCellType)newCode[3*(*idIt)],subIds,!subIds->isIdentity() || nbEntityElts!=newCode[3*(*idIt)+1],nbi, + offset+offset2, + li,glob,ret2); + ret=ret || ret2; + result.push_back(eltToAdd); + offset2+=nbEntityElts*nbi; + } + ret=ret || li.empty(); + return ret; +} + +/*! + * \param [in] typeF type of field of new chunk + * \param [in] geoType the geometric type of the chunk + * \param [in] idsOfMeshElt the entity ids of mesh (cells or nodes) of the new chunk. + * \param [in] isPfl specifies if a profile is requested regarding size of \a idsOfMeshElt and the number of such entities regarding underlying mesh. + * \param [in] nbi number of integration points + * \param [in] offset The offset in the **global array of data**. + * \param [in,out] entriesOnSameDisc the pool **on the same discretization** inside which it will be attempted to find an existing entry corresponding exactly + * to the new chunk to create. + * \param [in,out] glob the global shared info that will be requested for existing profiles or to append a new profile if needed. + * \param [out] notInExisting If false the return newly allocated entry is not coming from \a entriesOnSameDisc. If true the output comes from copy of \a entriesOnSameDisc + * and corresponding entry erased from \a entriesOnSameDisc. + * \return a newly allocated chunk + */ +MEDFileFieldPerMeshPerTypePerDisc *MEDFileFieldPerMeshPerTypePerDisc::NewObjectOnSameDiscThanPool(TypeOfField typeF, INTERP_KERNEL::NormalizedCellType geoType, DataArrayInt *idsOfMeshElt, + bool isPfl, int nbi, int offset, + std::list< const MEDFileFieldPerMeshPerTypePerDisc *>& entriesOnSameDisc, + MEDFileFieldGlobsReal& glob, + bool ¬InExisting) +{ + int nbMeshEntities=idsOfMeshElt->getNumberOfTuples(); + std::list< const MEDFileFieldPerMeshPerTypePerDisc *>::iterator it=entriesOnSameDisc.begin(); + for(;it!=entriesOnSameDisc.end();it++) + { + if(((INTERP_KERNEL::NormalizedCellType)(*it)->_loc_id)==geoType && (*it)->_nval==nbMeshEntities) + { + if(!isPfl) + { + if((*it)->_profile.empty()) + break; + else + if(!(*it)->_profile.empty()) + { + const DataArrayInt *pfl=glob.getProfile((*it)->_profile.c_str()); + if(pfl->isEqualWithoutConsideringStr(*idsOfMeshElt)) + break; + } + } + } + } + if(it==entriesOnSameDisc.end()) + { + notInExisting=true; + MEDFileFieldPerMeshPerTypePerDisc *ret=new MEDFileFieldPerMeshPerTypePerDisc; + ret->_type=typeF; + ret->_loc_id=(int)geoType; + ret->_nval=nbMeshEntities; + ret->_start=offset; + ret->_end=ret->_start+ret->_nval*nbi; + if(isPfl) + { + idsOfMeshElt->setName(glob.createNewNameOfPfl().c_str()); + glob.appendProfile(idsOfMeshElt); + ret->_profile=idsOfMeshElt->getName(); + } + //tony treatment of localization + return ret; + } + else + { + notInExisting=false; + MEDFileFieldPerMeshPerTypePerDisc *ret=MEDFileFieldPerMeshPerTypePerDisc::New(*(*it)); + ret->_loc_id=(int)geoType; + ret->setNewStart(offset); + entriesOnSameDisc.erase(it); + return ret; + } + +} + +MEDFileFieldPerMeshPerType *MEDFileFieldPerMeshPerType::NewOnRead(med_idt fid, MEDFileFieldPerMesh *fath, TypeOfField type, INTERP_KERNEL::NormalizedCellType geoType, const MEDFileFieldNameScope& nasc, const PartDefinition *pd) +{ + return new MEDFileFieldPerMeshPerType(fid,fath,type,geoType,nasc,pd); +} + +MEDFileFieldPerMeshPerType *MEDFileFieldPerMeshPerType::New(MEDFileFieldPerMesh *fath, INTERP_KERNEL::NormalizedCellType geoType) +{ + return new MEDFileFieldPerMeshPerType(fath,geoType); +} + +std::size_t MEDFileFieldPerMeshPerType::getHeapMemorySizeWithoutChildren() const +{ + return _field_pm_pt_pd.capacity()*sizeof(MEDCouplingAutoRefCountObjectPtr<MEDFileFieldPerMeshPerTypePerDisc>); +} + +std::vector<const BigMemoryObject *> MEDFileFieldPerMeshPerType::getDirectChildrenWithNull() const +{ + std::vector<const BigMemoryObject *> ret; + for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileFieldPerMeshPerTypePerDisc> >::const_iterator it=_field_pm_pt_pd.begin();it!=_field_pm_pt_pd.end();it++) + ret.push_back((const MEDFileFieldPerMeshPerTypePerDisc *)*it); + return ret; +} + +MEDFileFieldPerMeshPerType *MEDFileFieldPerMeshPerType::deepCpy(MEDFileFieldPerMesh *father) const +{ + MEDCouplingAutoRefCountObjectPtr<MEDFileFieldPerMeshPerType> ret=new MEDFileFieldPerMeshPerType(*this); + ret->_father=father; + std::size_t i=0; + for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileFieldPerMeshPerTypePerDisc> >::const_iterator it=_field_pm_pt_pd.begin();it!=_field_pm_pt_pd.end();it++,i++) + { + if((const MEDFileFieldPerMeshPerTypePerDisc *)*it) + ret->_field_pm_pt_pd[i]=(*it)->deepCpy((MEDFileFieldPerMeshPerType *)ret); + } + return ret.retn(); +} + +void MEDFileFieldPerMeshPerType::assignFieldNoProfile(int& start, int offset, int nbOfCells, const MEDCouplingFieldDouble *field, const DataArray *arr, MEDFileFieldGlobsReal& glob, const MEDFileFieldNameScope& nasc) +{ + std::vector<int> pos=addNewEntryIfNecessary(field,offset,nbOfCells); + for(std::vector<int>::const_iterator it=pos.begin();it!=pos.end();it++) + _field_pm_pt_pd[*it]->assignFieldNoProfile(start,offset,nbOfCells,field,arr,glob,nasc); +} + +/*! + * This method is the most general one. No optimization is done here. + * \param [in] multiTypePfl is the end user profile specified in high level API + * \param [in] idsInPfl is the selection into the \a multiTypePfl whole profile that corresponds to the current geometric type. + * \param [in] locIds is the profile needed to be created for MED file format. It can be null if all cells of current geometric type are fetched in \a multiTypePfl. + * \b WARNING if not null the MED file profile can be subdivided again in case of Gauss points. + * \param [in] nbOfEltsInWholeMesh nb of elts of type \a this->_geo_type in \b WHOLE mesh + * \param [in] mesh is the mesh coming from the MEDFileMesh instance in correspondance with the MEDFileField. The mesh inside the \a field is simply ignored. + */ +void MEDFileFieldPerMeshPerType::assignFieldProfile(bool isPflAlone, int& start, const DataArrayInt *multiTypePfl, const DataArrayInt *idsInPfl, DataArrayInt *locIds, int nbOfEltsInWholeMesh, const MEDCouplingFieldDouble *field, const DataArray *arr, const MEDCouplingMesh *mesh, MEDFileFieldGlobsReal& glob, const MEDFileFieldNameScope& nasc) +{ + std::vector<int> pos=addNewEntryIfNecessary(field,idsInPfl); + for(std::vector<int>::const_iterator it=pos.begin();it!=pos.end();it++) + _field_pm_pt_pd[*it]->assignFieldProfile(isPflAlone,start,multiTypePfl,idsInPfl,locIds,nbOfEltsInWholeMesh,field,arr,mesh,glob,nasc); +} + +void MEDFileFieldPerMeshPerType::assignNodeFieldNoProfile(int& start, const MEDCouplingFieldDouble *field, const DataArray *arr, MEDFileFieldGlobsReal& glob) +{ + _field_pm_pt_pd.resize(1); + _field_pm_pt_pd[0]=MEDFileFieldPerMeshPerTypePerDisc::New(this,ON_NODES,-3); + _field_pm_pt_pd[0]->assignNodeFieldNoProfile(start,field,arr,glob); +} + +void MEDFileFieldPerMeshPerType::assignNodeFieldProfile(int& start, const DataArrayInt *pfl, const MEDCouplingFieldDouble *field, const DataArray *arr, MEDFileFieldGlobsReal& glob, const MEDFileFieldNameScope& nasc) +{ + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> pfl2=pfl->deepCpy(); + if(!arr || !arr->isAllocated()) + throw INTERP_KERNEL::Exception("MEDFileFieldPerMeshPerType::assignNodeFieldProfile : input array is null, or not allocated !"); + _field_pm_pt_pd.resize(1); + _field_pm_pt_pd[0]=MEDFileFieldPerMeshPerTypePerDisc::New(this,ON_NODES,-3); + _field_pm_pt_pd[0]->assignFieldProfile(true,start,pfl,pfl2,pfl2,-1,field,arr,0,glob,nasc);//mesh is not requested so 0 is send. +} + +std::vector<int> MEDFileFieldPerMeshPerType::addNewEntryIfNecessary(const MEDCouplingFieldDouble *field, int offset, int nbOfCells) +{ + TypeOfField type=field->getTypeOfField(); + if(type!=ON_GAUSS_PT) + { + int locIdToFind=MEDFileFieldPerMeshPerTypePerDisc::ConvertType(type,0); + int sz=_field_pm_pt_pd.size(); + bool found=false; + for(int j=0;j<sz && !found;j++) + { + if(_field_pm_pt_pd[j]->getLocId()==locIdToFind) + { + _field_pm_pt_pd[j]=MEDFileFieldPerMeshPerTypePerDisc::New(this,type,locIdToFind); + found=true; + } + } + if(!found) + { + _field_pm_pt_pd.resize(sz+1); + _field_pm_pt_pd[sz]=MEDFileFieldPerMeshPerTypePerDisc::New(this,type,locIdToFind); + } + std::vector<int> ret(1,(int)sz); + return ret; + } + else + { + std::vector<int> ret2=addNewEntryIfNecessaryGauss(field,offset,nbOfCells); + int sz2=ret2.size(); + std::vector<int> ret3(sz2); + int k=0; + for(int i=0;i<sz2;i++) + { + int sz=_field_pm_pt_pd.size(); + int locIdToFind=ret2[i]; + bool found=false; + for(int j=0;j<sz && !found;j++) + { + if(_field_pm_pt_pd[j]->getLocId()==locIdToFind) + { + _field_pm_pt_pd[j]=MEDFileFieldPerMeshPerTypePerDisc::New(this,type,locIdToFind); + ret3[k++]=j; + found=true; + } + } + if(!found) + { + _field_pm_pt_pd.resize(sz+1); + _field_pm_pt_pd[sz]=MEDFileFieldPerMeshPerTypePerDisc::New(this,type,locIdToFind); + ret3[k++]=sz; + } + } + return ret3; + } +} + +std::vector<int> MEDFileFieldPerMeshPerType::addNewEntryIfNecessaryGauss(const MEDCouplingFieldDouble *field, int offset, int nbOfCells) +{ + const MEDCouplingFieldDiscretization *disc=field->getDiscretization(); + const MEDCouplingFieldDiscretizationGauss *disc2=dynamic_cast<const MEDCouplingFieldDiscretizationGauss *>(disc); + if(!disc2) + throw INTERP_KERNEL::Exception("addNewEntryIfNecessaryGauss : invalid call to this method ! Internal Error !"); + const DataArrayInt *da=disc2->getArrayOfDiscIds(); + if(!da) + throw INTERP_KERNEL::Exception("addNewEntryIfNecessaryGauss (no profile) : no localization ids per cell array available ! The input Gauss node field is maybe invalid !"); + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> da2=da->selectByTupleId2(offset,offset+nbOfCells,1); + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> retTmp=da2->getDifferentValues(); + if(retTmp->presenceOfValue(-1)) + throw INTERP_KERNEL::Exception("addNewEntryIfNecessaryGauss : some cells have no dicretization description !"); + std::vector<int> ret(retTmp->begin(),retTmp->end()); + return ret; +} + +std::vector<int> MEDFileFieldPerMeshPerType::addNewEntryIfNecessary(const MEDCouplingFieldDouble *field, const DataArrayInt *subCells) +{ + TypeOfField type=field->getTypeOfField(); + if(type!=ON_GAUSS_PT) + { + int locIdToFind=MEDFileFieldPerMeshPerTypePerDisc::ConvertType(type,0); + int sz=_field_pm_pt_pd.size(); + bool found=false; + for(int j=0;j<sz && !found;j++) + { + if(_field_pm_pt_pd[j]->getLocId()==locIdToFind) + { + _field_pm_pt_pd[j]=MEDFileFieldPerMeshPerTypePerDisc::New(this,type,locIdToFind); + found=true; + } + } + if(!found) + { + _field_pm_pt_pd.resize(sz+1); + _field_pm_pt_pd[sz]=MEDFileFieldPerMeshPerTypePerDisc::New(this,type,locIdToFind); + } + std::vector<int> ret(1,0); + return ret; + } + else + { + std::vector<int> ret2=addNewEntryIfNecessaryGauss(field,subCells); + int sz2=ret2.size(); + std::vector<int> ret3(sz2); + int k=0; + for(int i=0;i<sz2;i++) + { + int sz=_field_pm_pt_pd.size(); + int locIdToFind=ret2[i]; + bool found=false; + for(int j=0;j<sz && !found;j++) + { + if(_field_pm_pt_pd[j]->getLocId()==locIdToFind) + { + _field_pm_pt_pd[j]=MEDFileFieldPerMeshPerTypePerDisc::New(this,type,locIdToFind); + ret3[k++]=j; + found=true; + } + } + if(!found) + { + _field_pm_pt_pd.resize(sz+1); + _field_pm_pt_pd[sz]=MEDFileFieldPerMeshPerTypePerDisc::New(this,type,locIdToFind); + ret3[k++]=sz; + } + } + return ret3; + } +} + +std::vector<int> MEDFileFieldPerMeshPerType::addNewEntryIfNecessaryGauss(const MEDCouplingFieldDouble *field, const DataArrayInt *subCells) +{ + const MEDCouplingFieldDiscretization *disc=field->getDiscretization(); + const MEDCouplingFieldDiscretizationGauss *disc2=dynamic_cast<const MEDCouplingFieldDiscretizationGauss *>(disc); + if(!disc2) + throw INTERP_KERNEL::Exception("addNewEntryIfNecessaryGauss : invalid call to this method ! Internal Error !"); + const DataArrayInt *da=disc2->getArrayOfDiscIds(); + if(!da) + throw INTERP_KERNEL::Exception("addNewEntryIfNecessaryGauss : no localization ids per cell array available ! The input Gauss node field is maybe invalid !"); + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> da2=da->selectByTupleIdSafe(subCells->getConstPointer(),subCells->getConstPointer()+subCells->getNumberOfTuples()); + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> retTmp=da2->getDifferentValues(); + if(retTmp->presenceOfValue(-1)) + throw INTERP_KERNEL::Exception("addNewEntryIfNecessaryGauss : some cells have no dicretization description !"); + std::vector<int> ret(retTmp->begin(),retTmp->end()); + return ret; +} + +const MEDFileFieldPerMesh *MEDFileFieldPerMeshPerType::getFather() const +{ + return _father; +} + +void MEDFileFieldPerMeshPerType::getDimension(int& dim) const +{ + const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(_geo_type); + int curDim=(int)cm.getDimension(); + dim=std::max(dim,curDim); +} + +void MEDFileFieldPerMeshPerType::fillTypesOfFieldAvailable(std::set<TypeOfField>& types) const +{ + for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileFieldPerMeshPerTypePerDisc> >::const_iterator it=_field_pm_pt_pd.begin();it!=_field_pm_pt_pd.end();it++) + { + (*it)->fillTypesOfFieldAvailable(types); + } +} + +void MEDFileFieldPerMeshPerType::fillFieldSplitedByType(std::vector< std::pair<int,int> >& dads, std::vector<TypeOfField>& types, std::vector<std::string>& pfls, std::vector<std::string>& locs) const +{ + int sz=_field_pm_pt_pd.size(); + dads.resize(sz); types.resize(sz); pfls.resize(sz); locs.resize(sz); + for(int i=0;i<sz;i++) + { + _field_pm_pt_pd[i]->getCoarseData(types[i],dads[i],pfls[i],locs[i]); + } +} + +int MEDFileFieldPerMeshPerType::getIteration() const +{ + return _father->getIteration(); +} + +int MEDFileFieldPerMeshPerType::getOrder() const +{ + return _father->getOrder(); +} + +double MEDFileFieldPerMeshPerType::getTime() const +{ + return _father->getTime(); +} + +std::string MEDFileFieldPerMeshPerType::getMeshName() const +{ + return _father->getMeshName(); +} + +void MEDFileFieldPerMeshPerType::simpleRepr(int bkOffset, std::ostream& oss, int id) const +{ + const char startLine[]=" ## "; + std::string startLine2(bkOffset,' '); + std::string startLine3(startLine2); + startLine3+=startLine; + if(_geo_type!=INTERP_KERNEL::NORM_ERROR) + { + const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(_geo_type); + oss << startLine3 << "Entry geometry type #" << id << " is lying on geometry types " << cm.getRepr() << "." << std::endl; + } + else + oss << startLine3 << "Entry geometry type #" << id << " is lying on NODES." << std::endl; + oss << startLine3 << "Entry is defined on " << _field_pm_pt_pd.size() << " localizations." << std::endl; + int i=0; + for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileFieldPerMeshPerTypePerDisc> >::const_iterator it=_field_pm_pt_pd.begin();it!=_field_pm_pt_pd.end();it++,i++) + { + const MEDFileFieldPerMeshPerTypePerDisc *cur=(*it); + if(cur) + cur->simpleRepr(bkOffset,oss,i); + else + { + oss << startLine2 << " ## " << "Localization #" << i << " is empty !" << std::endl; + } + } +} + +void MEDFileFieldPerMeshPerType::getSizes(int& globalSz, int& nbOfEntries) const +{ + for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileFieldPerMeshPerTypePerDisc> >::const_iterator it=_field_pm_pt_pd.begin();it!=_field_pm_pt_pd.end();it++) + { + globalSz+=(*it)->getNumberOfTuples(); + } + nbOfEntries+=(int)_field_pm_pt_pd.size(); +} + +INTERP_KERNEL::NormalizedCellType MEDFileFieldPerMeshPerType::getGeoType() const +{ + return _geo_type; +} + + +int MEDFileFieldPerMeshPerType::getNumberOfComponents() const +{ + return _father->getNumberOfComponents(); +} + +bool MEDFileFieldPerMeshPerType::presenceOfMultiDiscPerGeoType() const +{ + std::size_t nb(0); + for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileFieldPerMeshPerTypePerDisc> >::const_iterator it=_field_pm_pt_pd.begin();it!=_field_pm_pt_pd.end();it++) + { + const MEDFileFieldPerMeshPerTypePerDisc *fmtd(*it); + if(fmtd) + nb++; + } + return nb>1; +} + +DataArray *MEDFileFieldPerMeshPerType::getOrCreateAndGetArray() +{ + return _father->getOrCreateAndGetArray(); +} + +const DataArray *MEDFileFieldPerMeshPerType::getOrCreateAndGetArray() const +{ + const MEDFileFieldPerMesh *fath=_father; + return fath->getOrCreateAndGetArray(); +} + +const std::vector<std::string>& MEDFileFieldPerMeshPerType::getInfo() const +{ + return _father->getInfo(); +} + +std::vector<std::string> MEDFileFieldPerMeshPerType::getPflsReallyUsed() const +{ + std::vector<std::string> ret; + std::set<std::string> ret2; + for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileFieldPerMeshPerTypePerDisc> >::const_iterator it1=_field_pm_pt_pd.begin();it1!=_field_pm_pt_pd.end();it1++) + { + std::string tmp=(*it1)->getProfile(); + if(!tmp.empty()) + if(ret2.find(tmp)==ret2.end()) + { + ret.push_back(tmp); + ret2.insert(tmp); + } + } + return ret; +} + +std::vector<std::string> MEDFileFieldPerMeshPerType::getLocsReallyUsed() const +{ + std::vector<std::string> ret; + std::set<std::string> ret2; + for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileFieldPerMeshPerTypePerDisc> >::const_iterator it1=_field_pm_pt_pd.begin();it1!=_field_pm_pt_pd.end();it1++) + { + std::string tmp=(*it1)->getLocalization(); + if(!tmp.empty() && tmp!=MED_GAUSS_ELNO) + if(ret2.find(tmp)==ret2.end()) + { + ret.push_back(tmp); + ret2.insert(tmp); + } + } + return ret; +} + +std::vector<std::string> MEDFileFieldPerMeshPerType::getPflsReallyUsedMulti() const +{ + std::vector<std::string> ret; + std::set<std::string> ret2; + for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileFieldPerMeshPerTypePerDisc> >::const_iterator it1=_field_pm_pt_pd.begin();it1!=_field_pm_pt_pd.end();it1++) + { + std::string tmp=(*it1)->getProfile(); + if(!tmp.empty()) + ret.push_back(tmp); + } + return ret; +} + +std::vector<std::string> MEDFileFieldPerMeshPerType::getLocsReallyUsedMulti() const +{ + std::vector<std::string> ret; + for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileFieldPerMeshPerTypePerDisc> >::const_iterator it1=_field_pm_pt_pd.begin();it1!=_field_pm_pt_pd.end();it1++) + { + std::string tmp=(*it1)->getLocalization(); + if(!tmp.empty() && tmp!=MED_GAUSS_ELNO) + ret.push_back(tmp); + } + return ret; +} + +void MEDFileFieldPerMeshPerType::changePflsRefsNamesGen(const std::vector< std::pair<std::vector<std::string>, std::string > >& mapOfModif) +{ + for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileFieldPerMeshPerTypePerDisc> >::iterator it1=_field_pm_pt_pd.begin();it1!=_field_pm_pt_pd.end();it1++) + (*it1)->changePflsRefsNamesGen(mapOfModif); +} + +void MEDFileFieldPerMeshPerType::changeLocsRefsNamesGen(const std::vector< std::pair<std::vector<std::string>, std::string > >& mapOfModif) +{ + for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileFieldPerMeshPerTypePerDisc> >::iterator it1=_field_pm_pt_pd.begin();it1!=_field_pm_pt_pd.end();it1++) + (*it1)->changeLocsRefsNamesGen(mapOfModif); +} + +MEDFileFieldPerMeshPerTypePerDisc *MEDFileFieldPerMeshPerType::getLeafGivenLocId(int locId) +{ + if(_field_pm_pt_pd.empty()) + { + const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(_geo_type); + std::ostringstream oss; oss << "MEDFileFieldPerMeshPerType::getLeafGivenLocId : no localizations for geotype \"" << cm.getRepr() << "\" !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + if(locId>=0 && locId<(int)_field_pm_pt_pd.size()) + return _field_pm_pt_pd[locId]; + const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(_geo_type); + std::ostringstream oss2; oss2 << "MEDFileFieldPerMeshPerType::getLeafGivenLocId : no such locId available (" << locId; + oss2 << ") for geometric type \"" << cm.getRepr() << "\" It should be in [0," << _field_pm_pt_pd.size() << ") !"; + throw INTERP_KERNEL::Exception(oss2.str().c_str()); + return static_cast<MEDFileFieldPerMeshPerTypePerDisc*>(0); +} + +const MEDFileFieldPerMeshPerTypePerDisc *MEDFileFieldPerMeshPerType::getLeafGivenLocId(int locId) const +{ + if(_field_pm_pt_pd.empty()) + { + const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(_geo_type); + std::ostringstream oss; oss << "MEDFileFieldPerMeshPerType::getLeafGivenLocId : no localizations for geotype \"" << cm.getRepr() << "\" !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + if(locId>=0 && locId<(int)_field_pm_pt_pd.size()) + return _field_pm_pt_pd[locId]; + const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(_geo_type); + std::ostringstream oss2; oss2 << "MEDFileFieldPerMeshPerType::getLeafGivenLocId : no such locId available (" << locId; + oss2 << ") for geometric type \"" << cm.getRepr() << "\" It should be in [0," << _field_pm_pt_pd.size() << ") !"; + throw INTERP_KERNEL::Exception(oss2.str().c_str()); + return static_cast<const MEDFileFieldPerMeshPerTypePerDisc*>(0); +} + +void MEDFileFieldPerMeshPerType::getFieldAtLevel(int meshDim, TypeOfField type, const MEDFileFieldGlobsReal *glob, std::vector< std::pair<int,int> >& dads, std::vector<const DataArrayInt *>& pfls, std::vector<int>& locs, std::vector<INTERP_KERNEL::NormalizedCellType>& geoTypes) const +{ + if(_geo_type!=INTERP_KERNEL::NORM_ERROR) + { + const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(_geo_type); + if(meshDim!=(int)cm.getDimension()) + return ; + } + for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileFieldPerMeshPerTypePerDisc> >::const_iterator it=_field_pm_pt_pd.begin();it!=_field_pm_pt_pd.end();it++) + (*it)->getFieldAtLevel(type,glob,dads,pfls,locs,geoTypes); +} + +void MEDFileFieldPerMeshPerType::fillValues(int& startEntryId, std::vector< std::pair<std::pair<INTERP_KERNEL::NormalizedCellType,int>,std::pair<int,int> > >& entries) const +{ + int i=0; + for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileFieldPerMeshPerTypePerDisc> >::const_iterator it=_field_pm_pt_pd.begin();it!=_field_pm_pt_pd.end();it++,i++) + { + (*it)->fillValues(i,startEntryId,entries); + } +} + +void MEDFileFieldPerMeshPerType::setLeaves(const std::vector< MEDCouplingAutoRefCountObjectPtr< MEDFileFieldPerMeshPerTypePerDisc > >& leaves) +{ + _field_pm_pt_pd=leaves; + for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileFieldPerMeshPerTypePerDisc> >::iterator it=_field_pm_pt_pd.begin();it!=_field_pm_pt_pd.end();it++) + (*it)->setFather(this); +} + +/*! + * \param [in,out] globalNum a global numbering counter for the renumbering. + * \param [out] its - list of pair (start,stop) kept + * \return bool - false if the type of field \a tof is not contained in \a this. + */ +bool MEDFileFieldPerMeshPerType::keepOnlySpatialDiscretization(TypeOfField tof, int &globalNum, std::vector< std::pair<int,int> >& its) +{ + bool ret(false); + std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileFieldPerMeshPerTypePerDisc> > newPmPtPd; + for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileFieldPerMeshPerTypePerDisc> >::iterator it=_field_pm_pt_pd.begin();it!=_field_pm_pt_pd.end();it++) + if((*it)->getType()==tof) + { + newPmPtPd.push_back(*it); + std::pair<int,int> bgEnd; bgEnd.first=(*it)->getStart(); bgEnd.second=(*it)->getEnd(); + (*it)->setNewStart(globalNum); + globalNum=(*it)->getEnd(); + its.push_back(bgEnd); + ret=true; + } + if(ret) + _field_pm_pt_pd=newPmPtPd; + return ret; +} + +/*! + * \param [in,out] globalNum a global numbering counter for the renumbering. + * \param [out] its - list of pair (start,stop) kept + * \return bool - false if the type of field \a tof is not contained in \a this. + */ +bool MEDFileFieldPerMeshPerType::keepOnlyGaussDiscretization(std::size_t idOfDisc, int &globalNum, std::vector< std::pair<int,int> >& its) +{ + if(_field_pm_pt_pd.size()<=idOfDisc) + return false; + MEDCouplingAutoRefCountObjectPtr<MEDFileFieldPerMeshPerTypePerDisc> elt(_field_pm_pt_pd[idOfDisc]); + std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileFieldPerMeshPerTypePerDisc> > newPmPtPd(1,elt); + std::pair<int,int> bgEnd; bgEnd.first=_field_pm_pt_pd[idOfDisc]->getStart(); bgEnd.second=_field_pm_pt_pd[idOfDisc]->getEnd(); + elt->setNewStart(globalNum); + globalNum=elt->getEnd(); + its.push_back(bgEnd); + _field_pm_pt_pd=newPmPtPd; + return true; +} + +MEDFileFieldPerMeshPerType::MEDFileFieldPerMeshPerType(MEDFileFieldPerMesh *fath, INTERP_KERNEL::NormalizedCellType geoType):_father(fath),_geo_type(geoType) +{ +} + +MEDFileFieldPerMeshPerType::MEDFileFieldPerMeshPerType(med_idt fid, MEDFileFieldPerMesh *fath, TypeOfField type, INTERP_KERNEL::NormalizedCellType geoType, const MEDFileFieldNameScope& nasc, const PartDefinition *pd):_father(fath),_geo_type(geoType) +{ + INTERP_KERNEL::AutoPtr<char> pflName=MEDLoaderBase::buildEmptyString(MED_NAME_SIZE); + INTERP_KERNEL::AutoPtr<char> locName=MEDLoaderBase::buildEmptyString(MED_NAME_SIZE); + med_geometry_type mgeoti; + med_entity_type menti(ConvertIntoMEDFileType(type,geoType,mgeoti)); + int nbProfiles(MEDfieldnProfile(fid,nasc.getName().c_str(),getIteration(),getOrder(),menti,mgeoti,pflName,locName)); + _field_pm_pt_pd.resize(nbProfiles); + for(int i=0;i<nbProfiles;i++) + { + _field_pm_pt_pd[i]=MEDFileFieldPerMeshPerTypePerDisc::NewOnRead(this,type,i,pd); + } + if(type==ON_CELLS) + { + int nbProfiles2(MEDfieldnProfile(fid,nasc.getName().c_str(),getIteration(),getOrder(),MED_NODE_ELEMENT,mgeoti,pflName,locName)); + for(int i=0;i<nbProfiles2;i++) + _field_pm_pt_pd.push_back(MEDFileFieldPerMeshPerTypePerDisc::NewOnRead(this,ON_GAUSS_NE,i,pd)); + } +} + +void MEDFileFieldPerMeshPerType::loadOnlyStructureOfDataRecursively(med_idt fid, int &start, const MEDFileFieldNameScope& nasc) +{ + for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileFieldPerMeshPerTypePerDisc> >::iterator it=_field_pm_pt_pd.begin();it!=_field_pm_pt_pd.end();it++) + (*it)->loadOnlyStructureOfDataRecursively(fid,start,nasc); +} + +void MEDFileFieldPerMeshPerType::loadBigArraysRecursively(med_idt fid, const MEDFileFieldNameScope& nasc) +{ + for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileFieldPerMeshPerTypePerDisc> >::iterator it=_field_pm_pt_pd.begin();it!=_field_pm_pt_pd.end();it++) + (*it)->loadBigArray(fid,nasc); +} + +void MEDFileFieldPerMeshPerType::writeLL(med_idt fid, const MEDFileFieldNameScope& nasc) const +{ + for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileFieldPerMeshPerTypePerDisc> >::const_iterator it=_field_pm_pt_pd.begin();it!=_field_pm_pt_pd.end();it++) + { + (*it)->copyOptionsFrom(*this); + (*it)->writeLL(fid,nasc); + } +} + +med_entity_type MEDFileFieldPerMeshPerType::ConvertIntoMEDFileType(TypeOfField ikType, INTERP_KERNEL::NormalizedCellType ikGeoType, med_geometry_type& medfGeoType) +{ + switch(ikType) + { + case ON_CELLS: + medfGeoType=typmai3[(int)ikGeoType]; + return MED_CELL; + case ON_NODES: + medfGeoType=MED_NONE; + return MED_NODE; + case ON_GAUSS_NE: + medfGeoType=typmai3[(int)ikGeoType]; + return MED_NODE_ELEMENT; + case ON_GAUSS_PT: + medfGeoType=typmai3[(int)ikGeoType]; + return MED_CELL; + default: + throw INTERP_KERNEL::Exception("MEDFileFieldPerMeshPerType::ConvertIntoMEDFileType : unexpected entity type ! internal error"); + } + return MED_UNDEF_ENTITY_TYPE; +} + +MEDFileFieldPerMesh *MEDFileFieldPerMesh::NewOnRead(med_idt fid, MEDFileAnyTypeField1TSWithoutSDA *fath, int meshCsit, int meshIteration, int meshOrder, const MEDFileFieldNameScope& nasc, const MEDFileMesh *mm, const std::vector< std::pair<TypeOfField,INTERP_KERNEL::NormalizedCellType> > *entities) +{ + return new MEDFileFieldPerMesh(fid,fath,meshCsit,meshIteration,meshOrder,nasc,mm,entities); +} + +MEDFileFieldPerMesh *MEDFileFieldPerMesh::New(MEDFileAnyTypeField1TSWithoutSDA *fath, const MEDCouplingMesh *mesh) +{ + return new MEDFileFieldPerMesh(fath,mesh); +} + +std::size_t MEDFileFieldPerMesh::getHeapMemorySizeWithoutChildren() const +{ + return _mesh_name.capacity()+_field_pm_pt.capacity()*sizeof(MEDCouplingAutoRefCountObjectPtr< MEDFileFieldPerMeshPerType >); +} + +std::vector<const BigMemoryObject *> MEDFileFieldPerMesh::getDirectChildrenWithNull() const +{ + std::vector<const BigMemoryObject *> ret; + for(std::vector< MEDCouplingAutoRefCountObjectPtr< MEDFileFieldPerMeshPerType > >::const_iterator it=_field_pm_pt.begin();it!=_field_pm_pt.end();it++) + ret.push_back((const MEDFileFieldPerMeshPerType *)*it); + return ret; +} + +MEDFileFieldPerMesh *MEDFileFieldPerMesh::deepCpy(MEDFileAnyTypeField1TSWithoutSDA *father) const +{ + MEDCouplingAutoRefCountObjectPtr< MEDFileFieldPerMesh > ret=new MEDFileFieldPerMesh(*this); + ret->_father=father; + std::size_t i=0; + for(std::vector< MEDCouplingAutoRefCountObjectPtr< MEDFileFieldPerMeshPerType > >::const_iterator it=_field_pm_pt.begin();it!=_field_pm_pt.end();it++,i++) + { + if((const MEDFileFieldPerMeshPerType *)*it) + ret->_field_pm_pt[i]=(*it)->deepCpy((MEDFileFieldPerMesh *)(ret)); + } + return ret.retn(); +} + +void MEDFileFieldPerMesh::simpleRepr(int bkOffset, std::ostream& oss, int id) const +{ + std::string startLine(bkOffset,' '); + oss << startLine << "## Field part (" << id << ") lying on mesh \"" << _mesh_name << "\", Mesh iteration=" << _mesh_iteration << ". Mesh order=" << _mesh_order << "." << std::endl; + oss << startLine << "## Field is defined on " << _field_pm_pt.size() << " types." << std::endl; + int i=0; + for(std::vector< MEDCouplingAutoRefCountObjectPtr< MEDFileFieldPerMeshPerType > >::const_iterator it=_field_pm_pt.begin();it!=_field_pm_pt.end();it++,i++) + { + const MEDFileFieldPerMeshPerType *cur=*it; + if(cur) + cur->simpleRepr(bkOffset,oss,i); + else + { + oss << startLine << " ## Entry geometry type #" << i << " is empty !" << std::endl; + } + } +} + +void MEDFileFieldPerMesh::copyTinyInfoFrom(const MEDCouplingMesh *mesh) +{ + _mesh_name=mesh->getName(); + mesh->getTime(_mesh_iteration,_mesh_order); +} + +void MEDFileFieldPerMesh::assignFieldNoProfileNoRenum(int& start, const std::vector<int>& code, const MEDCouplingFieldDouble *field, const DataArray *arr, MEDFileFieldGlobsReal& glob, const MEDFileFieldNameScope& nasc) +{ + int nbOfTypes=code.size()/3; + int offset=0; + for(int i=0;i<nbOfTypes;i++) + { + INTERP_KERNEL::NormalizedCellType type=(INTERP_KERNEL::NormalizedCellType)code[3*i]; + int nbOfCells=code[3*i+1]; + int pos=addNewEntryIfNecessary(type); + _field_pm_pt[pos]->assignFieldNoProfile(start,offset,nbOfCells,field,arr,glob,nasc); + offset+=nbOfCells; + } +} + +/*! + * This method is the most general one. No optimization is done here. + * \param [in] multiTypePfl is the end user profile specified in high level API + * \param [in] code is the code of \a mesh[multiTypePfl] mesh. It is of size of number of different geometric types into \a mesh[multiTypePfl]. + * \param [in] code2 is the code of the \b WHOLE mesh on the same level. So all types in \a code are in \a code2. + * \param [in] idsInPflPerType is the selection into the \a multiTypePfl whole profile that corresponds to the given geometric type. This vector is always 3 times smaller than \a code. + * \param [in] idsPerType is a vector containing the profiles needed to be created for MED file format. \b WARNING these processed MED file profiles can be subdivided again in case of Gauss points. + * \param [in] mesh is the mesh coming from the MEDFileMesh instance in correspondance with the MEDFileField. The mesh inside the \a field is simply ignored. + */ +void MEDFileFieldPerMesh::assignFieldProfile(int& start, const DataArrayInt *multiTypePfl, const std::vector<int>& code, const std::vector<int>& code2, const std::vector<DataArrayInt *>& idsInPflPerType, const std::vector<DataArrayInt *>& idsPerType, const MEDCouplingFieldDouble *field, const DataArray *arr, const MEDCouplingMesh *mesh, MEDFileFieldGlobsReal& glob, const MEDFileFieldNameScope& nasc) +{ + int nbOfTypes(code.size()/3); + for(int i=0;i<nbOfTypes;i++) + { + INTERP_KERNEL::NormalizedCellType type=(INTERP_KERNEL::NormalizedCellType)code[3*i]; + int pos=addNewEntryIfNecessary(type); + DataArrayInt *pfl=0; + if(code[3*i+2]!=-1) + pfl=idsPerType[code[3*i+2]]; + int nbOfTupes2=code2.size()/3; + int found=0; + for(;found<nbOfTupes2;found++) + if(code[3*i]==code2[3*found]) + break; + if(found==nbOfTupes2) + throw INTERP_KERNEL::Exception("MEDFileFieldPerMesh::assignFieldProfile : internal problem ! Should never happen ! Please report bug to anthony.geay@cea.fr !"); + _field_pm_pt[pos]->assignFieldProfile(nbOfTypes==1,start,multiTypePfl,idsInPflPerType[i],pfl,code2[3*found+1],field,arr,mesh,glob,nasc); + } +} + +void MEDFileFieldPerMesh::assignNodeFieldNoProfile(int& start, const MEDCouplingFieldDouble *field, const DataArray *arr, MEDFileFieldGlobsReal& glob) +{ + int pos=addNewEntryIfNecessary(INTERP_KERNEL::NORM_ERROR); + _field_pm_pt[pos]->assignNodeFieldNoProfile(start,field,arr,glob); +} + +void MEDFileFieldPerMesh::assignNodeFieldProfile(int& start, const DataArrayInt *pfl, const MEDCouplingFieldDouble *field, const DataArray *arr, MEDFileFieldGlobsReal& glob, const MEDFileFieldNameScope& nasc) +{ + int pos=addNewEntryIfNecessary(INTERP_KERNEL::NORM_ERROR); + _field_pm_pt[pos]->assignNodeFieldProfile(start,pfl,field,arr,glob,nasc); +} + +void MEDFileFieldPerMesh::loadOnlyStructureOfDataRecursively(med_idt fid, int& start, const MEDFileFieldNameScope& nasc) +{ + for(std::vector< MEDCouplingAutoRefCountObjectPtr< MEDFileFieldPerMeshPerType > >::iterator it=_field_pm_pt.begin();it!=_field_pm_pt.end();it++) + (*it)->loadOnlyStructureOfDataRecursively(fid,start,nasc); +} + +void MEDFileFieldPerMesh::loadBigArraysRecursively(med_idt fid, const MEDFileFieldNameScope& nasc) +{ + for(std::vector< MEDCouplingAutoRefCountObjectPtr< MEDFileFieldPerMeshPerType > >::iterator it=_field_pm_pt.begin();it!=_field_pm_pt.end();it++) + (*it)->loadBigArraysRecursively(fid,nasc); +} + +void MEDFileFieldPerMesh::writeLL(med_idt fid, const MEDFileFieldNameScope& nasc) const +{ + int nbOfTypes=_field_pm_pt.size(); + for(int i=0;i<nbOfTypes;i++) + { + _field_pm_pt[i]->copyOptionsFrom(*this); + _field_pm_pt[i]->writeLL(fid,nasc); + } +} + +void MEDFileFieldPerMesh::getDimension(int& dim) const +{ + for(std::vector< MEDCouplingAutoRefCountObjectPtr< MEDFileFieldPerMeshPerType > >::const_iterator it=_field_pm_pt.begin();it!=_field_pm_pt.end();it++) + (*it)->getDimension(dim); +} + +void MEDFileFieldPerMesh::fillTypesOfFieldAvailable(std::set<TypeOfField>& types) const +{ + for(std::vector< MEDCouplingAutoRefCountObjectPtr< MEDFileFieldPerMeshPerType > >::const_iterator it=_field_pm_pt.begin();it!=_field_pm_pt.end();it++) + (*it)->fillTypesOfFieldAvailable(types); +} + +std::vector< std::vector< std::pair<int,int> > > MEDFileFieldPerMesh::getFieldSplitedByType(std::vector<INTERP_KERNEL::NormalizedCellType>& types, std::vector< std::vector<TypeOfField> >& typesF, std::vector< std::vector<std::string> >& pfls, std::vector< std::vector<std::string> > & locs) const +{ + int sz=_field_pm_pt.size(); + std::vector< std::vector<std::pair<int,int> > > ret(sz); + types.resize(sz); typesF.resize(sz); pfls.resize(sz); locs.resize(sz); + for(int i=0;i<sz;i++) + { + types[i]=_field_pm_pt[i]->getGeoType(); + _field_pm_pt[i]->fillFieldSplitedByType(ret[i],typesF[i],pfls[i],locs[i]); + } + return ret; +} + +double MEDFileFieldPerMesh::getTime() const +{ + int tmp1,tmp2; + return _father->getTime(tmp1,tmp2); +} + +int MEDFileFieldPerMesh::getIteration() const +{ + return _father->getIteration(); +} + +int MEDFileFieldPerMesh::getOrder() const +{ + return _father->getOrder(); +} + +int MEDFileFieldPerMesh::getNumberOfComponents() const +{ + return _father->getNumberOfComponents(); +} + +bool MEDFileFieldPerMesh::presenceOfMultiDiscPerGeoType() const +{ + for(std::vector< MEDCouplingAutoRefCountObjectPtr< MEDFileFieldPerMeshPerType > >::const_iterator it=_field_pm_pt.begin();it!=_field_pm_pt.end();it++) + { + const MEDFileFieldPerMeshPerType *fpmt(*it); + if(!fpmt) + continue; + if(fpmt->presenceOfMultiDiscPerGeoType()) + return true; + } + return false; +} + +DataArray *MEDFileFieldPerMesh::getOrCreateAndGetArray() +{ + if(!_father) + throw INTERP_KERNEL::Exception("MEDFileFieldPerMesh::getOrCreateAndGetArray : no father ! internal error !"); + return _father->getOrCreateAndGetArray(); +} + +const DataArray *MEDFileFieldPerMesh::getOrCreateAndGetArray() const +{ + if(!_father) + throw INTERP_KERNEL::Exception("MEDFileFieldPerMesh::getOrCreateAndGetArray : no father ! internal error !"); + return _father->getOrCreateAndGetArray(); +} + +const std::vector<std::string>& MEDFileFieldPerMesh::getInfo() const +{ + return _father->getInfo(); +} + +/*! + * type,geoTypes,dads,pfls,locs are input parameters. They should have the same size. + * Before the call of this method 'geoTypes','dads','pfls','locs' must be reorganized so that types in geoTypes are contiguous and ordered following typmai2 array. + * It returns 2 output vectors : + * - 'code' of size 3*sz where sz is the number of different values into 'geoTypes' + * - 'notNullPfls' contains sz2 values that are extracted from 'pfls' in which null profiles have been removed. + * 'code' and 'notNullPfls' are in MEDCouplingUMesh::checkTypeConsistencyAndContig format. + */ +void MEDFileFieldPerMesh::SortArraysPerType(const MEDFileFieldGlobsReal *glob, TypeOfField type, const std::vector<INTERP_KERNEL::NormalizedCellType>& geoTypes, const std::vector< std::pair<int,int> >& dads, const std::vector<const DataArrayInt *>& pfls, const std::vector<int>& locs, std::vector<int>& code, std::vector<DataArrayInt *>& notNullPfls) +{ + int notNullPflsSz=0; + int nbOfArrs=geoTypes.size(); + for(int i=0;i<nbOfArrs;i++) + if(pfls[i]) + notNullPflsSz++; + std::set<INTERP_KERNEL::NormalizedCellType> geoTypes3(geoTypes.begin(),geoTypes.end()); + int nbOfDiffGeoTypes=geoTypes3.size(); + code.resize(3*nbOfDiffGeoTypes); + notNullPfls.resize(notNullPflsSz); + notNullPflsSz=0; + int j=0; + for(int i=0;i<nbOfDiffGeoTypes;i++) + { + int startZone=j; + INTERP_KERNEL::NormalizedCellType refType=geoTypes[j]; + std::vector<const DataArrayInt *> notNullTmp; + if(pfls[j]) + notNullTmp.push_back(pfls[j]); + j++; + for(;j<nbOfArrs;j++) + if(geoTypes[j]==refType) + { + if(pfls[j]) + notNullTmp.push_back(pfls[j]); + } + else + break; + std::vector< std::pair<int,int> > tmpDads(dads.begin()+startZone,dads.begin()+j); + std::vector<const DataArrayInt *> tmpPfls(pfls.begin()+startZone,pfls.begin()+j); + std::vector<int> tmpLocs(locs.begin()+startZone,locs.begin()+j); + code[3*i]=(int)refType; + std::vector<INTERP_KERNEL::NormalizedCellType> refType2(1,refType); + code[3*i+1]=ComputeNbOfElems(glob,type,refType2,tmpDads,tmpLocs); + if(notNullTmp.empty()) + code[3*i+2]=-1; + else + { + notNullPfls[notNullPflsSz]=DataArrayInt::Aggregate(notNullTmp); + code[3*i+2]=notNullPflsSz++; + } + } +} + +/*! + * 'dads' 'geoTypes' and 'locs' are input parameters that should have same size sz. sz should be >=1. + */ +int MEDFileFieldPerMesh::ComputeNbOfElems(const MEDFileFieldGlobsReal *glob, TypeOfField type, const std::vector<INTERP_KERNEL::NormalizedCellType>& geoTypes, const std::vector< std::pair<int,int> >& dads, const std::vector<int>& locs) +{ + int sz=dads.size(); + int ret=0; + for(int i=0;i<sz;i++) + { + if(locs[i]==-1) + { + if(type!=ON_GAUSS_NE) + ret+=dads[i].second-dads[i].first; + else + { + const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(geoTypes[i]); + ret+=(dads[i].second-dads[i].first)/cm.getNumberOfNodes(); + } + } + else + { + int nbOfGaussPtPerCell=glob->getNbOfGaussPtPerCell(locs[i]); + ret+=(dads[i].second-dads[i].first)/nbOfGaussPtPerCell; + } + } + return ret; +} + +std::vector<std::string> MEDFileFieldPerMesh::getPflsReallyUsed() const +{ + std::vector<std::string> ret; + std::set<std::string> ret2; + for(std::vector< MEDCouplingAutoRefCountObjectPtr< MEDFileFieldPerMeshPerType > >::const_iterator it=_field_pm_pt.begin();it!=_field_pm_pt.end();it++) + { + std::vector<std::string> tmp=(*it)->getPflsReallyUsed(); + for(std::vector<std::string>::const_iterator it2=tmp.begin();it2!=tmp.end();it2++) + if(ret2.find(*it2)==ret2.end()) + { + ret.push_back(*it2); + ret2.insert(*it2); + } + } + return ret; +} + +std::vector<std::string> MEDFileFieldPerMesh::getPflsReallyUsedMulti() const +{ + std::vector<std::string> ret; + for(std::vector< MEDCouplingAutoRefCountObjectPtr< MEDFileFieldPerMeshPerType > >::const_iterator it=_field_pm_pt.begin();it!=_field_pm_pt.end();it++) + { + std::vector<std::string> tmp=(*it)->getPflsReallyUsedMulti(); + ret.insert(ret.end(),tmp.begin(),tmp.end()); + } + return ret; +} + +std::vector<std::string> MEDFileFieldPerMesh::getLocsReallyUsed() const +{ + std::vector<std::string> ret; + std::set<std::string> ret2; + for(std::vector< MEDCouplingAutoRefCountObjectPtr< MEDFileFieldPerMeshPerType > >::const_iterator it=_field_pm_pt.begin();it!=_field_pm_pt.end();it++) + { + std::vector<std::string> tmp=(*it)->getLocsReallyUsed(); + for(std::vector<std::string>::const_iterator it2=tmp.begin();it2!=tmp.end();it2++) + if(ret2.find(*it2)==ret2.end()) + { + ret.push_back(*it2); + ret2.insert(*it2); + } + } + return ret; +} + +std::vector<std::string> MEDFileFieldPerMesh::getLocsReallyUsedMulti() const +{ + std::vector<std::string> ret; + for(std::vector< MEDCouplingAutoRefCountObjectPtr< MEDFileFieldPerMeshPerType > >::const_iterator it=_field_pm_pt.begin();it!=_field_pm_pt.end();it++) + { + std::vector<std::string> tmp=(*it)->getLocsReallyUsedMulti(); + ret.insert(ret.end(),tmp.begin(),tmp.end()); + } + return ret; +} + +bool MEDFileFieldPerMesh::changeMeshNames(const std::vector< std::pair<std::string,std::string> >& modifTab) +{ + for(std::vector< std::pair<std::string,std::string> >::const_iterator it=modifTab.begin();it!=modifTab.end();it++) + { + if((*it).first==_mesh_name) + { + _mesh_name=(*it).second; + return true; + } + } + return false; +} + +bool MEDFileFieldPerMesh::renumberEntitiesLyingOnMesh(const std::string& meshName, const std::vector<int>& oldCode, const std::vector<int>& newCode, const DataArrayInt *renumO2N, + MEDFileFieldGlobsReal& glob) +{ + if(_mesh_name!=meshName) + return false; + std::set<INTERP_KERNEL::NormalizedCellType> typesToKeep; + for(std::size_t i=0;i<oldCode.size()/3;i++) typesToKeep.insert((INTERP_KERNEL::NormalizedCellType)oldCode[3*i]); + std::vector< std::pair<std::pair<INTERP_KERNEL::NormalizedCellType,int>,std::pair<int,int> > > entries; + std::vector< const MEDFileFieldPerMeshPerTypePerDisc *> entriesKept; + std::vector< const MEDFileFieldPerMeshPerTypePerDisc *> otherEntries; + getUndergroundDataArrayExt(entries); + DataArray *arr0=getOrCreateAndGetArray();//tony + if(!arr0) + throw INTERP_KERNEL::Exception("MEDFileFieldPerMesh::renumberEntitiesLyingOnMesh : DataArray storing values of field is null !"); + DataArrayDouble *arr=dynamic_cast<DataArrayDouble *>(arr0);//tony + if(!arr0) + throw INTERP_KERNEL::Exception("MEDFileFieldPerMesh::renumberEntitiesLyingOnMesh : DataArray storing values is double ! Not managed for the moment !"); + int sz=0; + if(!arr) + throw INTERP_KERNEL::Exception("MEDFileFieldPerMesh::renumberEntitiesLyingOnMesh : DataArrayDouble storing values of field is null !"); + for(std::vector< std::pair<std::pair<INTERP_KERNEL::NormalizedCellType,int>,std::pair<int,int> > >::const_iterator it=entries.begin();it!=entries.end();it++) + { + if(typesToKeep.find((*it).first.first)!=typesToKeep.end()) + { + entriesKept.push_back(getLeafGivenTypeAndLocId((*it).first.first,(*it).first.second)); + sz+=(*it).second.second-(*it).second.first; + } + else + otherEntries.push_back(getLeafGivenTypeAndLocId((*it).first.first,(*it).first.second)); + } + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> renumDefrag=DataArrayInt::New(); renumDefrag->alloc(arr->getNumberOfTuples(),1); renumDefrag->fillWithZero(); + //////////////////// + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> explicitIdsOldInMesh=DataArrayInt::New(); explicitIdsOldInMesh->alloc(sz,1);//sz is a majorant of the real size. A realloc will be done after + int *workI2=explicitIdsOldInMesh->getPointer(); + int sz1=0,sz2=0,sid=1; + std::vector< std::vector< const MEDFileFieldPerMeshPerTypePerDisc *> > entriesKeptML=MEDFileFieldPerMeshPerTypePerDisc::SplitPerDiscretization(entriesKept); + // std::vector<int> tupleIdOfStartOfNewChuncksV(entriesKeptML.size()); + for(std::vector< std::vector< const MEDFileFieldPerMeshPerTypePerDisc *> >::const_iterator itL1=entriesKeptML.begin();itL1!=entriesKeptML.end();itL1++,sid++) + { + // tupleIdOfStartOfNewChuncksV[sid-1]=sz2; + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> explicitIdsOldInArr=DataArrayInt::New(); explicitIdsOldInArr->alloc(sz,1); + int *workI=explicitIdsOldInArr->getPointer(); + for(std::vector< const MEDFileFieldPerMeshPerTypePerDisc *>::const_iterator itL2=(*itL1).begin();itL2!=(*itL1).end();itL2++) + { + int delta1=(*itL2)->fillTupleIds(workI); workI+=delta1; sz1+=delta1; + (*itL2)->setLocId(sz2); + (*itL2)->_tmp_work1=(*itL2)->getStart(); + int delta2=(*itL2)->fillEltIdsFromCode(sz2,oldCode,glob,workI2); workI2+=delta2; sz2+=delta2; + } + renumDefrag->setPartOfValuesSimple3(sid,explicitIdsOldInArr->begin(),explicitIdsOldInArr->end(),0,1,1); + } + explicitIdsOldInMesh->reAlloc(sz2); + int tupleIdOfStartOfNewChuncks=arr->getNumberOfTuples()-sz2; + //////////////////// + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> permArrDefrag=renumDefrag->buildPermArrPerLevel(); renumDefrag=0; + // perform redispatching of non concerned MEDFileFieldPerMeshPerTypePerDisc + std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileFieldPerMeshPerTypePerDisc> > otherEntriesNew; + for(std::vector< const MEDFileFieldPerMeshPerTypePerDisc *>::const_iterator it=otherEntries.begin();it!=otherEntries.end();it++) + { + otherEntriesNew.push_back(MEDFileFieldPerMeshPerTypePerDisc::New(*(*it))); + otherEntriesNew.back()->setNewStart(permArrDefrag->getIJ((*it)->getStart(),0)); + otherEntriesNew.back()->setLocId((*it)->getGeoType()); + } + std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileFieldPerMeshPerTypePerDisc> > entriesKeptNew; + std::vector< const MEDFileFieldPerMeshPerTypePerDisc *> entriesKeptNew2; + for(std::vector< const MEDFileFieldPerMeshPerTypePerDisc *>::const_iterator it=entriesKept.begin();it!=entriesKept.end();it++) + { + MEDCouplingAutoRefCountObjectPtr<MEDFileFieldPerMeshPerTypePerDisc> elt=MEDFileFieldPerMeshPerTypePerDisc::New(*(*it)); + int newStart=elt->getLocId(); + elt->setLocId((*it)->getGeoType()); + elt->setNewStart(newStart); + elt->_tmp_work1=permArrDefrag->getIJ(elt->_tmp_work1,0); + entriesKeptNew.push_back(elt); + entriesKeptNew2.push_back(elt); + } + MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> arr2=arr->renumber(permArrDefrag->getConstPointer()); + // perform redispatching of concerned MEDFileFieldPerMeshPerTypePerDisc -> values are in arr2 + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> explicitIdsNewInMesh=renumO2N->selectByTupleId(explicitIdsOldInMesh->begin(),explicitIdsOldInMesh->end()); + std::vector< std::vector< const MEDFileFieldPerMeshPerTypePerDisc *> > entriesKeptPerDisc=MEDFileFieldPerMeshPerTypePerDisc::SplitPerDiscretization(entriesKeptNew2); + bool ret=false; + for(std::vector< std::vector< const MEDFileFieldPerMeshPerTypePerDisc *> >::const_iterator it4=entriesKeptPerDisc.begin();it4!=entriesKeptPerDisc.end();it4++) + { + sid=0; + /*for(std::vector< const MEDFileFieldPerMeshPerTypePerDisc *>::const_iterator itL2=(*it4).begin();itL2!=(*it4).end();itL2++) + { + MEDFileFieldPerMeshPerTypePerDisc *curNC=const_cast<MEDFileFieldPerMeshPerTypePerDisc *>(*itL2); + curNC->setNewStart(permArrDefrag->getIJ((*itL2)->getStart(),0)-tupleIdOfStartOfNewChuncks+tupleIdOfStartOfNewChuncksV[sid]); + }*/ + ret=MEDFileFieldPerMeshPerTypePerDisc::RenumberChunks(tupleIdOfStartOfNewChuncks,*it4,explicitIdsNewInMesh,newCode, + glob,arr2,otherEntriesNew) || ret; + } + if(!ret) + return false; + // Assign new dispatching + assignNewLeaves(otherEntriesNew); + arr->cpyFrom(*arr2); + return true; +} + +/*! + * \param [in,out] globalNum a global numbering counter for the renumbering. + * \param [out] its - list of pair (start,stop) kept + */ +void MEDFileFieldPerMesh::keepOnlySpatialDiscretization(TypeOfField tof, int &globalNum, std::vector< std::pair<int,int> >& its) +{ + std::vector< MEDCouplingAutoRefCountObjectPtr< MEDFileFieldPerMeshPerType > > ret; + for(std::vector< MEDCouplingAutoRefCountObjectPtr< MEDFileFieldPerMeshPerType > >::iterator it=_field_pm_pt.begin();it!=_field_pm_pt.end();it++) + { + std::vector< std::pair<int,int> > its2; + if((*it)->keepOnlySpatialDiscretization(tof,globalNum,its2)) + { + ret.push_back(*it); + its.insert(its.end(),its2.begin(),its2.end()); + } + } + _field_pm_pt=ret; +} + +/*! + * \param [in,out] globalNum a global numbering counter for the renumbering. + * \param [out] its - list of pair (start,stop) kept + */ +void MEDFileFieldPerMesh::keepOnlyGaussDiscretization(std::size_t idOfDisc, int &globalNum, std::vector< std::pair<int,int> >& its) +{ + std::vector< MEDCouplingAutoRefCountObjectPtr< MEDFileFieldPerMeshPerType > > ret; + for(std::vector< MEDCouplingAutoRefCountObjectPtr< MEDFileFieldPerMeshPerType > >::iterator it=_field_pm_pt.begin();it!=_field_pm_pt.end();it++) + { + std::vector< std::pair<int,int> > its2; + if((*it)->keepOnlyGaussDiscretization(idOfDisc,globalNum,its2)) + { + ret.push_back(*it); + its.insert(its.end(),its2.begin(),its2.end()); + } + } + _field_pm_pt=ret; +} + +void MEDFileFieldPerMesh::assignNewLeaves(const std::vector< MEDCouplingAutoRefCountObjectPtr< MEDFileFieldPerMeshPerTypePerDisc > >& leaves) +{ + std::map<INTERP_KERNEL::NormalizedCellType,std::vector< MEDCouplingAutoRefCountObjectPtr< MEDFileFieldPerMeshPerTypePerDisc> > > types; + for( std::vector< MEDCouplingAutoRefCountObjectPtr< MEDFileFieldPerMeshPerTypePerDisc > >::const_iterator it=leaves.begin();it!=leaves.end();it++) + types[(INTERP_KERNEL::NormalizedCellType)(*it)->getLocId()].push_back(*it); + // + std::vector< MEDCouplingAutoRefCountObjectPtr< MEDFileFieldPerMeshPerType > > fieldPmPt(types.size()); + std::map<INTERP_KERNEL::NormalizedCellType,std::vector< MEDCouplingAutoRefCountObjectPtr< MEDFileFieldPerMeshPerTypePerDisc> > >::const_iterator it1=types.begin(); + std::vector< MEDCouplingAutoRefCountObjectPtr< MEDFileFieldPerMeshPerType > >::iterator it2=fieldPmPt.begin(); + for(;it1!=types.end();it1++,it2++) + { + MEDCouplingAutoRefCountObjectPtr<MEDFileFieldPerMeshPerType> elt=MEDFileFieldPerMeshPerType::New(this,(INTERP_KERNEL::NormalizedCellType)((*it1).second[0]->getLocId())); + elt->setLeaves((*it1).second); + *it2=elt; + } + _field_pm_pt=fieldPmPt; +} + +void MEDFileFieldPerMesh::changePflsRefsNamesGen(const std::vector< std::pair<std::vector<std::string>, std::string > >& mapOfModif) +{ + for(std::vector< MEDCouplingAutoRefCountObjectPtr< MEDFileFieldPerMeshPerType > >::iterator it=_field_pm_pt.begin();it!=_field_pm_pt.end();it++) + (*it)->changePflsRefsNamesGen(mapOfModif); +} + +void MEDFileFieldPerMesh::changeLocsRefsNamesGen(const std::vector< std::pair<std::vector<std::string>, std::string > >& mapOfModif) +{ + for(std::vector< MEDCouplingAutoRefCountObjectPtr< MEDFileFieldPerMeshPerType > >::iterator it=_field_pm_pt.begin();it!=_field_pm_pt.end();it++) + (*it)->changeLocsRefsNamesGen(mapOfModif); +} + +/*! + * \param [in] mesh is the whole mesh + */ +MEDCouplingFieldDouble *MEDFileFieldPerMesh::getFieldOnMeshAtLevel(TypeOfField type, const MEDFileFieldGlobsReal *glob, const MEDCouplingMesh *mesh, bool& isPfl, MEDCouplingAutoRefCountObjectPtr<DataArray>& arrOut, const MEDFileFieldNameScope& nasc) const +{ + if(_field_pm_pt.empty()) + throw INTERP_KERNEL::Exception("MEDFileFieldPerMesh::getFieldOnMeshAtLevel : no types field set !"); + // + std::vector< std::pair<int,int> > dads; + std::vector<const DataArrayInt *> pfls; + std::vector<DataArrayInt *> notNullPflsPerGeoType; + std::vector<int> locs,code; + std::vector<INTERP_KERNEL::NormalizedCellType> geoTypes; + for(std::vector< MEDCouplingAutoRefCountObjectPtr< MEDFileFieldPerMeshPerType > >::const_iterator it=_field_pm_pt.begin();it!=_field_pm_pt.end();it++) + (*it)->getFieldAtLevel(mesh->getMeshDimension(),type,glob,dads,pfls,locs,geoTypes); + // Sort by types + SortArraysPerType(glob,type,geoTypes,dads,pfls,locs,code,notNullPflsPerGeoType); + if(code.empty()) + { + std::ostringstream oss; oss << "MEDFileFieldPerMesh::getFieldOnMeshAtLevel : " << "The field \"" << nasc.getName() << "\" exists but not with such spatial discretization or such dimension specified !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + // + std::vector< MEDCouplingAutoRefCountObjectPtr<DataArrayInt> > notNullPflsPerGeoType2(notNullPflsPerGeoType.begin(),notNullPflsPerGeoType.end()); + std::vector< const DataArrayInt *> notNullPflsPerGeoType3(notNullPflsPerGeoType.begin(),notNullPflsPerGeoType.end()); + if(type!=ON_NODES) + { + DataArrayInt *arr=mesh->checkTypeConsistencyAndContig(code,notNullPflsPerGeoType3); + if(!arr) + return finishField(type,glob,dads,locs,mesh,isPfl,arrOut,nasc); + else + { + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> arr2(arr); + return finishField2(type,glob,dads,locs,geoTypes,mesh,arr,isPfl,arrOut,nasc); + } + } + else + { + if(code.size()!=3) + throw INTERP_KERNEL::Exception("MEDFileFieldPerMesh::getFieldOnMeshAtLevel : internal error #1 !"); + int nb=code[1]; + if(code[2]==-1) + { + if(nb!=mesh->getNumberOfNodes()) + { + std::ostringstream oss; oss << "MEDFileFieldPerMesh::getFieldOnMeshAtLevel : There is a problem there is " << nb << " nodes in field whereas there is " << mesh->getNumberOfNodes(); + oss << " nodes in mesh !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + return finishField(type,glob,dads,locs,mesh,isPfl,arrOut,nasc); + } + else + return finishFieldNode2(glob,dads,locs,mesh,notNullPflsPerGeoType3[0],isPfl,arrOut,nasc); + } +} + +DataArray *MEDFileFieldPerMesh::getFieldOnMeshAtLevelWithPfl(TypeOfField type, const MEDCouplingMesh *mesh, DataArrayInt *&pfl, const MEDFileFieldGlobsReal *glob, const MEDFileFieldNameScope& nasc) const +{ + if(_field_pm_pt.empty()) + throw INTERP_KERNEL::Exception("MEDFileFieldPerMesh::getFieldOnMeshAtLevel : no types field set !"); + // + std::vector<std::pair<int,int> > dads; + std::vector<const DataArrayInt *> pfls; + std::vector<DataArrayInt *> notNullPflsPerGeoType; + std::vector<int> locs,code; + std::vector<INTERP_KERNEL::NormalizedCellType> geoTypes; + for(std::vector< MEDCouplingAutoRefCountObjectPtr< MEDFileFieldPerMeshPerType > >::const_iterator it=_field_pm_pt.begin();it!=_field_pm_pt.end();it++) + (*it)->getFieldAtLevel(mesh->getMeshDimension(),type,glob,dads,pfls,locs,geoTypes); + // Sort by types + SortArraysPerType(glob,type,geoTypes,dads,pfls,locs,code,notNullPflsPerGeoType); + if(code.empty()) + { + std::ostringstream oss; oss << "MEDFileFieldPerMesh::getFieldOnMeshAtLevelWithPfl : " << "The field \"" << nasc.getName() << "\" exists but not with such spatial discretization or such dimension specified !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + std::vector< MEDCouplingAutoRefCountObjectPtr<DataArrayInt> > notNullPflsPerGeoType2(notNullPflsPerGeoType.begin(),notNullPflsPerGeoType.end()); + std::vector< const DataArrayInt *> notNullPflsPerGeoType3(notNullPflsPerGeoType.begin(),notNullPflsPerGeoType.end()); + if(type!=ON_NODES) + { + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> arr=mesh->checkTypeConsistencyAndContig(code,notNullPflsPerGeoType3); + return finishField4(dads,arr,mesh->getNumberOfCells(),pfl); + } + else + { + if(code.size()!=3) + throw INTERP_KERNEL::Exception("MEDFileFieldPerMesh::getFieldOnMeshAtLevel : internal error #1 !"); + int nb=code[1]; + if(code[2]==-1) + { + if(nb!=mesh->getNumberOfNodes()) + { + std::ostringstream oss; oss << "MEDFileFieldPerMesh::getFieldOnMeshAtLevel : There is a problem there is " << nb << " nodes in field whereas there is " << mesh->getNumberOfNodes(); + oss << " nodes in mesh !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + } + return finishField4(dads,code[2]==-1?0:notNullPflsPerGeoType3[0],mesh->getNumberOfNodes(),pfl); + } + // + return 0; +} + +void MEDFileFieldPerMesh::getUndergroundDataArrayExt(std::vector< std::pair<std::pair<INTERP_KERNEL::NormalizedCellType,int>,std::pair<int,int> > >& entries) const +{ + int globalSz=0; + int nbOfEntries=0; + for(std::vector< MEDCouplingAutoRefCountObjectPtr< MEDFileFieldPerMeshPerType > >::const_iterator it=_field_pm_pt.begin();it!=_field_pm_pt.end();it++) + { + (*it)->getSizes(globalSz,nbOfEntries); + } + entries.resize(nbOfEntries); + nbOfEntries=0; + for(std::vector< MEDCouplingAutoRefCountObjectPtr< MEDFileFieldPerMeshPerType > >::const_iterator it=_field_pm_pt.begin();it!=_field_pm_pt.end();it++) + { + (*it)->fillValues(nbOfEntries,entries); + } +} + +MEDFileFieldPerMeshPerTypePerDisc *MEDFileFieldPerMesh::getLeafGivenTypeAndLocId(INTERP_KERNEL::NormalizedCellType typ, int locId) +{ + for(std::vector< MEDCouplingAutoRefCountObjectPtr< MEDFileFieldPerMeshPerType > >::iterator it=_field_pm_pt.begin();it!=_field_pm_pt.end();it++) + { + if((*it)->getGeoType()==typ) + return (*it)->getLeafGivenLocId(locId); + } + const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(typ); + std::ostringstream oss; oss << "MEDFileFieldPerMesh::getLeafGivenTypeAndLocId : no such geometric type \"" << cm.getRepr() << "\" in this !" << std::endl; + oss << "Possiblities are : "; + for(std::vector< MEDCouplingAutoRefCountObjectPtr< MEDFileFieldPerMeshPerType > >::const_iterator it=_field_pm_pt.begin();it!=_field_pm_pt.end();it++) + { + const INTERP_KERNEL::CellModel& cm2=INTERP_KERNEL::CellModel::GetCellModel((*it)->getGeoType()); + oss << "\"" << cm2.getRepr() << "\", "; + } + throw INTERP_KERNEL::Exception(oss.str().c_str()); +} + +const MEDFileFieldPerMeshPerTypePerDisc *MEDFileFieldPerMesh::getLeafGivenTypeAndLocId(INTERP_KERNEL::NormalizedCellType typ, int locId) const +{ + for(std::vector< MEDCouplingAutoRefCountObjectPtr< MEDFileFieldPerMeshPerType > >::const_iterator it=_field_pm_pt.begin();it!=_field_pm_pt.end();it++) + { + if((*it)->getGeoType()==typ) + return (*it)->getLeafGivenLocId(locId); + } + const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(typ); + std::ostringstream oss; oss << "MEDFileFieldPerMesh::getLeafGivenTypeAndLocId : no such geometric type \"" << cm.getRepr() << "\" in this !" << std::endl; + oss << "Possiblities are : "; + for(std::vector< MEDCouplingAutoRefCountObjectPtr< MEDFileFieldPerMeshPerType > >::const_iterator it=_field_pm_pt.begin();it!=_field_pm_pt.end();it++) + { + const INTERP_KERNEL::CellModel& cm2=INTERP_KERNEL::CellModel::GetCellModel((*it)->getGeoType()); + oss << "\"" << cm2.getRepr() << "\", "; + } + throw INTERP_KERNEL::Exception(oss.str().c_str()); +} + +int MEDFileFieldPerMesh::addNewEntryIfNecessary(INTERP_KERNEL::NormalizedCellType type) +{ + int i=0; + int pos=std::distance(typmai2,std::find(typmai2,typmai2+MED_N_CELL_FIXED_GEO,type)); + std::vector< MEDCouplingAutoRefCountObjectPtr< MEDFileFieldPerMeshPerType > >::iterator it2=_field_pm_pt.begin(); + for(std::vector< MEDCouplingAutoRefCountObjectPtr< MEDFileFieldPerMeshPerType > >::iterator it=_field_pm_pt.begin();it!=_field_pm_pt.end();it++,i++) + { + INTERP_KERNEL::NormalizedCellType curType=(*it)->getGeoType(); + if(type==curType) + return i; + else + { + int pos2=std::distance(typmai2,std::find(typmai2,typmai2+MED_N_CELL_FIXED_GEO,curType)); + if(pos>pos2) + it2=it+1; + } + } + int ret=std::distance(_field_pm_pt.begin(),it2); + _field_pm_pt.insert(it2,MEDFileFieldPerMeshPerType::New(this,type)); + return ret; +} + +/*! + * 'dads' and 'locs' input parameters have the same number of elements + * \param [in] mesh is \b NOT the global mesh, but the possibly reduced mesh. \a mesh parameter will be directly aggregated in the returned field + */ +MEDCouplingFieldDouble *MEDFileFieldPerMesh::finishField(TypeOfField type, const MEDFileFieldGlobsReal *glob, + const std::vector< std::pair<int,int> >& dads, const std::vector<int>& locs, + const MEDCouplingMesh *mesh, bool& isPfl, MEDCouplingAutoRefCountObjectPtr<DataArray>& arrOut, const MEDFileFieldNameScope& nasc) const +{ + isPfl=false; + MEDCouplingAutoRefCountObjectPtr<MEDCouplingFieldDouble> ret=MEDCouplingFieldDouble::New(type,ONE_TIME); + ret->setMesh(mesh); ret->setName(nasc.getName().c_str()); ret->setTime(getTime(),getIteration(),getOrder()); ret->setTimeUnit(nasc.getDtUnit().c_str()); + MEDCouplingAutoRefCountObjectPtr<DataArray> da=getOrCreateAndGetArray()->selectByTupleRanges(dads); + const std::vector<std::string>& infos=getInfo(); + da->setInfoOnComponents(infos); + da->setName(""); + if(type==ON_GAUSS_PT) + { + int offset=0; + int nbOfArrs=dads.size(); + for(int i=0;i<nbOfArrs;i++) + { + std::vector<std::pair<int,int> > dads2(1,dads[i]); const std::vector<int> locs2(1,locs[i]); + const std::vector<INTERP_KERNEL::NormalizedCellType> geoTypes2(1,INTERP_KERNEL::NORM_ERROR); + int nbOfElems=ComputeNbOfElems(glob,type,geoTypes2,dads2,locs2); + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> di=DataArrayInt::New(); + di->alloc(nbOfElems,1); + di->iota(offset); + const MEDFileFieldLoc& fl=glob->getLocalizationFromId(locs[i]); + ret->setGaussLocalizationOnCells(di->getConstPointer(),di->getConstPointer()+nbOfElems,fl.getRefCoords(),fl.getGaussCoords(),fl.getGaussWeights()); + offset+=nbOfElems; + } + } + arrOut=da; + return ret.retn(); +} + +/*! + * This method is an extension of MEDFileFieldPerMesh::finishField method. It deals with profiles. This method should be called when type is different from ON_NODES. + * 'dads', 'locs' and 'geoTypes' input parameters have the same number of elements. + * No check of this is performed. 'da' array contains an array in old2New style to be applyied to mesh to obtain the right support. + * The order of cells in the returned field is those imposed by the profile. + * \param [in] mesh is the global mesh. + */ +MEDCouplingFieldDouble *MEDFileFieldPerMesh::finishField2(TypeOfField type, const MEDFileFieldGlobsReal *glob, + const std::vector<std::pair<int,int> >& dads, const std::vector<int>& locs, + const std::vector<INTERP_KERNEL::NormalizedCellType>& geoTypes, + const MEDCouplingMesh *mesh, const DataArrayInt *da, bool& isPfl, MEDCouplingAutoRefCountObjectPtr<DataArray>& arrOut, const MEDFileFieldNameScope& nasc) const +{ + if(da->isIdentity()) + { + int nbOfTuples=da->getNumberOfTuples(); + if(nbOfTuples==mesh->getNumberOfCells()) + return finishField(type,glob,dads,locs,mesh,isPfl,arrOut,nasc); + } + MEDCouplingAutoRefCountObjectPtr<MEDCouplingMesh> m2=mesh->buildPart(da->getConstPointer(),da->getConstPointer()+da->getNbOfElems()); + m2->setName(mesh->getName().c_str()); + MEDCouplingAutoRefCountObjectPtr<MEDCouplingFieldDouble> ret=finishField(type,glob,dads,locs,m2,isPfl,arrOut,nasc); + isPfl=true; + return ret.retn(); +} + +/*! + * This method is the complement of MEDFileFieldPerMesh::finishField2 method except that this method works for node profiles. + */ +MEDCouplingFieldDouble *MEDFileFieldPerMesh::finishFieldNode2(const MEDFileFieldGlobsReal *glob, + const std::vector<std::pair<int,int> >& dads, const std::vector<int>& locs, + const MEDCouplingMesh *mesh, const DataArrayInt *da, bool& isPfl, MEDCouplingAutoRefCountObjectPtr<DataArray>& arrOut, const MEDFileFieldNameScope& nasc) const +{ + if(da->isIdentity()) + { + int nbOfTuples=da->getNumberOfTuples(); + if(nbOfTuples==mesh->getNumberOfNodes())//No problem for NORM_ERROR because it is in context of node + return finishField(ON_NODES,glob,dads,locs,mesh,isPfl,arrOut,nasc); + } + // Treatment of particular case where nodal field on pfl is requested with a meshDimRelToMax=1. + const MEDCouplingUMesh *meshu=dynamic_cast<const MEDCouplingUMesh *>(mesh); + if(meshu) + { + if(meshu->getNodalConnectivity()==0) + { + MEDCouplingAutoRefCountObjectPtr<MEDCouplingFieldDouble> ret=finishField(ON_CELLS,glob,dads,locs,mesh,isPfl,arrOut,nasc); + int nb=da->getNbOfElems(); + const int *ptr=da->getConstPointer(); + MEDCouplingUMesh *meshuc=const_cast<MEDCouplingUMesh *>(meshu); + meshuc->allocateCells(nb); + for(int i=0;i<nb;i++) + meshuc->insertNextCell(INTERP_KERNEL::NORM_POINT1,1,ptr+i); + meshuc->finishInsertingCells(); + ret->setMesh(meshuc); + const MEDCouplingFieldDiscretization *disc=ret->getDiscretization(); + if(!disc) throw INTERP_KERNEL::Exception("MEDFileFieldPerMesh::finishFieldNode2 : internal error, no discretization on field !"); + disc->checkCoherencyBetween(meshuc,arrOut); + return ret.retn(); + } + } + // + MEDCouplingAutoRefCountObjectPtr<MEDCouplingFieldDouble> ret=finishField(ON_NODES,glob,dads,locs,mesh,isPfl,arrOut,nasc); + isPfl=true; + DataArrayInt *arr2=0; + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> cellIds=mesh->getCellIdsFullyIncludedInNodeIds(da->getConstPointer(),da->getConstPointer()+da->getNbOfElems()); + MEDCouplingAutoRefCountObjectPtr<MEDCouplingMesh> mesh2=mesh->buildPartAndReduceNodes(cellIds->getConstPointer(),cellIds->getConstPointer()+cellIds->getNbOfElems(),arr2); + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> arr3(arr2); + int nnodes=mesh2->getNumberOfNodes(); + if(nnodes==(int)da->getNbOfElems()) + { + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> da3=da->transformWithIndArrR(arr2->begin(),arr2->end()); + arrOut->renumberInPlace(da3->getConstPointer()); + mesh2->setName(mesh->getName().c_str()); + ret->setMesh(mesh2); + return ret.retn(); + } + else + { + std::ostringstream oss; oss << "MEDFileFieldPerMesh::finishFieldNode2 : The field on nodes lies on a node profile so that it is impossible to find a submesh having exactly the same nodes of that profile !!!"; + oss << "So it is impossible to return a well definied MEDCouplingFieldDouble instance on specified mesh on a specified meshDim !" << std::endl; + oss << "To retrieve correctly such a field you have 3 possibilities :" << std::endl; + oss << " - use an another meshDim compatible with the field on nodes (MED file does not have such information)" << std::endl; + oss << " - use an another a meshDimRelToMax equal to 1 -> it will return a mesh with artificial cell POINT1 containing the profile !" << std::endl; + oss << " - if definitely the node profile has no link with mesh connectivity use MEDFileField1TS::getFieldWithProfile or MEDFileFieldMultiTS::getFieldWithProfile methods instead !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + return 0; +} + +/*! + * This method is the most light method of field retrieving. + */ +DataArray *MEDFileFieldPerMesh::finishField4(const std::vector<std::pair<int,int> >& dads, const DataArrayInt *pflIn, int nbOfElems, DataArrayInt *&pflOut) const +{ + if(!pflIn) + { + pflOut=DataArrayInt::New(); + pflOut->alloc(nbOfElems,1); + pflOut->iota(0); + } + else + { + pflOut=const_cast<DataArrayInt*>(pflIn); + pflOut->incrRef(); + } + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> safePfl(pflOut); + MEDCouplingAutoRefCountObjectPtr<DataArray> da=getOrCreateAndGetArray()->selectByTupleRanges(dads); + const std::vector<std::string>& infos=getInfo(); + int nbOfComp=infos.size(); + for(int i=0;i<nbOfComp;i++) + da->setInfoOnComponent(i,infos[i].c_str()); + safePfl->incrRef(); + return da.retn(); +} + + +/// @cond INTERNAL + +class MFFPMIter +{ +public: + static MFFPMIter *NewCell(const std::vector< std::pair<TypeOfField,INTERP_KERNEL::NormalizedCellType> > *entities); + static bool IsPresenceOfNode(const std::vector< std::pair<TypeOfField,INTERP_KERNEL::NormalizedCellType> > *entities); + virtual ~MFFPMIter() { } + virtual void begin() = 0; + virtual bool finished() const = 0; + virtual void next() = 0; + virtual int current() const = 0; +}; + +class MFFPMIterSimple : public MFFPMIter +{ +public: + MFFPMIterSimple():_pos(0) { } + void begin() { _pos=0; } + bool finished() const { return _pos>=MED_N_CELL_FIXED_GEO; } + void next() { _pos++; } + int current() const { return _pos; } +private: + int _pos; +}; + +class MFFPMIter2 : public MFFPMIter +{ +public: + MFFPMIter2(const std::vector<INTERP_KERNEL::NormalizedCellType>& cts); + void begin() { _it=_ids.begin(); } + bool finished() const { return _it==_ids.end(); } + void next() { _it++; } + int current() const { return *_it; } +private: + std::vector<int> _ids; + std::vector<int>::const_iterator _it; +}; + +MFFPMIter *MFFPMIter::NewCell(const std::vector< std::pair<TypeOfField,INTERP_KERNEL::NormalizedCellType> > *entities) +{ + if(!entities) + return new MFFPMIterSimple; + else + { + std::vector<INTERP_KERNEL::NormalizedCellType> tmp; + for(std::vector< std::pair<TypeOfField,INTERP_KERNEL::NormalizedCellType> >::const_iterator it=(*entities).begin();it!=(*entities).end();it++) + { + if((*it).first==ON_CELLS || (*it).first==ON_GAUSS_NE || (*it).first==ON_GAUSS_PT) + tmp.push_back((*it).second); + } + return new MFFPMIter2(tmp); + } +} + +bool MFFPMIter::IsPresenceOfNode(const std::vector< std::pair<TypeOfField,INTERP_KERNEL::NormalizedCellType> > *entities) +{ + if(!entities) + return true; + else + { + for(std::vector< std::pair<TypeOfField,INTERP_KERNEL::NormalizedCellType> >::const_iterator it=(*entities).begin();it!=(*entities).end();it++) + if((*it).first==ON_NODES) + return true; + return false; + } +} + +MFFPMIter2::MFFPMIter2(const std::vector<INTERP_KERNEL::NormalizedCellType>& cts) +{ + std::size_t sz(cts.size()); + _ids.resize(sz); + for(std::size_t i=0;i<sz;i++) + { + INTERP_KERNEL::NormalizedCellType *loc(std::find(typmai2,typmai2+MED_N_CELL_FIXED_GEO,cts[i])); + if(loc!=typmai2+MED_N_CELL_FIXED_GEO) + _ids[i]=(int)std::distance(typmai2,loc); + else + throw INTERP_KERNEL::Exception("MFFPMIter2 : The specified geo type does not exists !"); + } +} + +/// @endcond + +MEDFileFieldPerMesh::MEDFileFieldPerMesh(med_idt fid, MEDFileAnyTypeField1TSWithoutSDA *fath, int meshCsit, int meshIteration, int meshOrder, const MEDFileFieldNameScope& nasc, const MEDFileMesh *mm, const std::vector< std::pair<TypeOfField,INTERP_KERNEL::NormalizedCellType> > *entities):_mesh_iteration(meshIteration),_mesh_order(meshOrder), + _father(fath) +{ + INTERP_KERNEL::AutoPtr<char> meshName(MEDLoaderBase::buildEmptyString(MED_NAME_SIZE)); + INTERP_KERNEL::AutoPtr<char> pflName(MEDLoaderBase::buildEmptyString(MED_NAME_SIZE)); + INTERP_KERNEL::AutoPtr<char> locName(MEDLoaderBase::buildEmptyString(MED_NAME_SIZE)); + const MEDFileUMesh *mmu(dynamic_cast<const MEDFileUMesh *>(mm)); + INTERP_KERNEL::AutoCppPtr<MFFPMIter> iter0(MFFPMIter::NewCell(entities)); + for(iter0->begin();!iter0->finished();iter0->next()) + { + int nbProfile (MEDfield23nProfile(fid,nasc.getName().c_str(),getIteration(),getOrder(),MED_CELL ,typmai[iter0->current()],meshCsit+1,meshName,pflName,locName)); + std::string name0(MEDLoaderBase::buildStringFromFortran(meshName,MED_NAME_SIZE+1)); + int nbProfile2(MEDfield23nProfile(fid,nasc.getName().c_str(),getIteration(),getOrder(),MED_NODE_ELEMENT,typmai[iter0->current()],meshCsit+1,meshName,pflName,locName)); + std::string name1(MEDLoaderBase::buildStringFromFortran(meshName,MED_NAME_SIZE+1)); + if(nbProfile>0 || nbProfile2>0) + { + const PartDefinition *pd(0); + if(mmu) + pd=mmu->getPartDefAtLevel(mmu->getRelativeLevOnGeoType(typmai2[iter0->current()]),typmai2[iter0->current()]); + _field_pm_pt.push_back(MEDFileFieldPerMeshPerType::NewOnRead(fid,this,ON_CELLS,typmai2[iter0->current()],nasc,pd)); + if(nbProfile>0) + _mesh_name=name0; + else + _mesh_name=name1; + } + } + if(MFFPMIter::IsPresenceOfNode(entities)) + { + int nbProfile(MEDfield23nProfile(fid,nasc.getName().c_str(),getIteration(),getOrder(),MED_NODE,MED_NONE,meshCsit+1,meshName,pflName,locName)); + if(nbProfile>0) + { + const PartDefinition *pd(0); + if(mmu) + pd=mmu->getPartDefAtLevel(1,INTERP_KERNEL::NORM_ERROR); + _field_pm_pt.push_back(MEDFileFieldPerMeshPerType::NewOnRead(fid,this,ON_NODES,INTERP_KERNEL::NORM_ERROR,nasc,pd)); + _mesh_name=MEDLoaderBase::buildStringFromFortran(meshName,MED_NAME_SIZE+1); + } + } +} + +MEDFileFieldPerMesh::MEDFileFieldPerMesh(MEDFileAnyTypeField1TSWithoutSDA *fath, const MEDCouplingMesh *mesh):_father(fath) +{ + copyTinyInfoFrom(mesh); +} + +void MEDFileFieldGlobs::loadProfileInFile(med_idt fid, int id, const std::string& pflName) +{ + if(id>=(int)_pfls.size()) + _pfls.resize(id+1); + _pfls[id]=DataArrayInt::New(); + int lgth(MEDprofileSizeByName(fid,pflName.c_str())); + _pfls[id]->setName(pflName); + _pfls[id]->alloc(lgth,1); + MEDFILESAFECALLERRD0(MEDprofileRd,(fid,pflName.c_str(),_pfls[id]->getPointer())); + _pfls[id]->applyLin(1,-1,0);//Converting into C format +} + +void MEDFileFieldGlobs::loadProfileInFile(med_idt fid, int i) +{ + INTERP_KERNEL::AutoPtr<char> pflName=MEDLoaderBase::buildEmptyString(MED_NAME_SIZE); + int sz; + MEDFILESAFECALLERRD0(MEDprofileInfo,(fid,i+1,pflName,&sz)); + std::string pflCpp=MEDLoaderBase::buildStringFromFortran(pflName,MED_NAME_SIZE); + if(i>=(int)_pfls.size()) + _pfls.resize(i+1); + _pfls[i]=DataArrayInt::New(); + _pfls[i]->alloc(sz,1); + _pfls[i]->setName(pflCpp.c_str()); + MEDFILESAFECALLERRD0(MEDprofileRd,(fid,pflName,_pfls[i]->getPointer())); + _pfls[i]->applyLin(1,-1,0);//Converting into C format +} + +void MEDFileFieldGlobs::writeGlobals(med_idt fid, const MEDFileWritable& opt) const +{ + int nbOfPfls=_pfls.size(); + for(int i=0;i<nbOfPfls;i++) + { + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> cpy=_pfls[i]->deepCpy(); + cpy->applyLin(1,1,0); + INTERP_KERNEL::AutoPtr<char> pflName=MEDLoaderBase::buildEmptyString(MED_NAME_SIZE); + MEDLoaderBase::safeStrCpy(_pfls[i]->getName().c_str(),MED_NAME_SIZE,pflName,opt.getTooLongStrPolicy()); + MEDFILESAFECALLERWR0(MEDprofileWr,(fid,pflName,_pfls[i]->getNumberOfTuples(),cpy->getConstPointer())); + } + // + int nbOfLocs=_locs.size(); + for(int i=0;i<nbOfLocs;i++) + _locs[i]->writeLL(fid); +} + +void MEDFileFieldGlobs::appendGlobs(const MEDFileFieldGlobs& other, double eps) +{ + std::vector<std::string> pfls=getPfls(); + for(std::vector< MEDCouplingAutoRefCountObjectPtr<DataArrayInt> >::const_iterator it=other._pfls.begin();it!=other._pfls.end();it++) + { + std::vector<std::string>::iterator it2=std::find(pfls.begin(),pfls.end(),(*it)->getName()); + if(it2==pfls.end()) + { + _pfls.push_back(*it); + } + else + { + int id=std::distance(pfls.begin(),it2); + if(!(*it)->isEqual(*_pfls[id])) + { + std::ostringstream oss; oss << "MEDFileFieldGlobs::appendGlobs : Profile \"" << (*it)->getName() << "\" already exists and is different from those expecting to be append !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + } + } + std::vector<std::string> locs=getLocs(); + for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileFieldLoc> >::const_iterator it=other._locs.begin();it!=other._locs.end();it++) + { + std::vector<std::string>::iterator it2=std::find(locs.begin(),locs.end(),(*it)->getName()); + if(it2==locs.end()) + { + _locs.push_back(*it); + } + else + { + int id=std::distance(locs.begin(),it2); + if(!(*it)->isEqual(*_locs[id],eps)) + { + std::ostringstream oss; oss << "MEDFileFieldGlobs::appendGlobs : Localization \"" << (*it)->getName() << "\" already exists and is different from those expecting to be append !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + } + } +} + +void MEDFileFieldGlobs::checkGlobsPflsPartCoherency(const std::vector<std::string>& pflsUsed) const +{ + for(std::vector<std::string>::const_iterator it=pflsUsed.begin();it!=pflsUsed.end();it++) + getProfile((*it).c_str()); +} + +void MEDFileFieldGlobs::checkGlobsLocsPartCoherency(const std::vector<std::string>& locsUsed) const +{ + for(std::vector<std::string>::const_iterator it=locsUsed.begin();it!=locsUsed.end();it++) + getLocalization((*it).c_str()); +} + +void MEDFileFieldGlobs::loadGlobals(med_idt fid, const MEDFileFieldGlobsReal& real) +{ + std::vector<std::string> profiles=real.getPflsReallyUsed(); + int sz=profiles.size(); + _pfls.resize(sz); + for(int i=0;i<sz;i++) + loadProfileInFile(fid,i,profiles[i].c_str()); + // + std::vector<std::string> locs=real.getLocsReallyUsed(); + sz=locs.size(); + _locs.resize(sz); + for(int i=0;i<sz;i++) + _locs[i]=MEDFileFieldLoc::New(fid,locs[i].c_str()); +} + +void MEDFileFieldGlobs::loadAllGlobals(med_idt fid) +{ + int nProfil=MEDnProfile(fid); + for(int i=0;i<nProfil;i++) + loadProfileInFile(fid,i); + int sz=MEDnLocalization(fid); + _locs.resize(sz); + for(int i=0;i<sz;i++) + { + _locs[i]=MEDFileFieldLoc::New(fid,i); + } +} + +MEDFileFieldGlobs *MEDFileFieldGlobs::New(const std::string& fname) +{ + return new MEDFileFieldGlobs(fname); +} + +MEDFileFieldGlobs *MEDFileFieldGlobs::New() +{ + return new MEDFileFieldGlobs; +} + +std::size_t MEDFileFieldGlobs::getHeapMemorySizeWithoutChildren() const +{ + return _file_name.capacity()+_pfls.capacity()*sizeof(MEDCouplingAutoRefCountObjectPtr<DataArrayInt>)+_locs.capacity()*sizeof(MEDCouplingAutoRefCountObjectPtr<MEDFileFieldLoc>); +} + +std::vector<const BigMemoryObject *> MEDFileFieldGlobs::getDirectChildrenWithNull() const +{ + std::vector<const BigMemoryObject *> ret; + for(std::vector< MEDCouplingAutoRefCountObjectPtr< DataArrayInt > >::const_iterator it=_pfls.begin();it!=_pfls.end();it++) + ret.push_back((const DataArrayInt *)*it); + for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileFieldLoc> >::const_iterator it=_locs.begin();it!=_locs.end();it++) + ret.push_back((const MEDFileFieldLoc *)*it); + return ret; +} + +MEDFileFieldGlobs *MEDFileFieldGlobs::deepCpy() const +{ + MEDCouplingAutoRefCountObjectPtr<MEDFileFieldGlobs> ret=new MEDFileFieldGlobs(*this); + std::size_t i=0; + for(std::vector< MEDCouplingAutoRefCountObjectPtr<DataArrayInt> >::const_iterator it=_pfls.begin();it!=_pfls.end();it++,i++) + { + if((const DataArrayInt *)*it) + ret->_pfls[i]=(*it)->deepCpy(); + } + i=0; + for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileFieldLoc> >::const_iterator it=_locs.begin();it!=_locs.end();it++,i++) + { + if((const MEDFileFieldLoc*)*it) + ret->_locs[i]=(*it)->deepCpy(); + } + return ret.retn(); +} + +/*! + * \throw if a profile in \a pfls in not in \a this. + * \throw if a localization in \a locs in not in \a this. + * \sa MEDFileFieldGlobs::deepCpyPart + */ +MEDFileFieldGlobs *MEDFileFieldGlobs::shallowCpyPart(const std::vector<std::string>& pfls, const std::vector<std::string>& locs) const +{ + MEDCouplingAutoRefCountObjectPtr<MEDFileFieldGlobs> ret=MEDFileFieldGlobs::New(); + for(std::vector<std::string>::const_iterator it1=pfls.begin();it1!=pfls.end();it1++) + { + DataArrayInt *pfl=const_cast<DataArrayInt *>(getProfile((*it1).c_str())); + if(!pfl) + throw INTERP_KERNEL::Exception("MEDFileFieldGlobs::shallowCpyPart : internal error ! pfl null !"); + pfl->incrRef(); + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> pfl2(pfl); + ret->_pfls.push_back(pfl2); + } + for(std::vector<std::string>::const_iterator it2=locs.begin();it2!=locs.end();it2++) + { + MEDFileFieldLoc *loc=const_cast<MEDFileFieldLoc *>(&getLocalization((*it2).c_str())); + if(!loc) + throw INTERP_KERNEL::Exception("MEDFileFieldGlobs::shallowCpyPart : internal error ! loc null !"); + loc->incrRef(); + MEDCouplingAutoRefCountObjectPtr<MEDFileFieldLoc> loc2(loc); + ret->_locs.push_back(loc2); + } + ret->setFileName(getFileName()); + return ret.retn(); +} + +/*! + * \throw if a profile in \a pfls in not in \a this. + * \throw if a localization in \a locs in not in \a this. + * \sa MEDFileFieldGlobs::shallowCpyPart + */ +MEDFileFieldGlobs *MEDFileFieldGlobs::deepCpyPart(const std::vector<std::string>& pfls, const std::vector<std::string>& locs) const +{ + MEDCouplingAutoRefCountObjectPtr<MEDFileFieldGlobs> ret=MEDFileFieldGlobs::New(); + for(std::vector<std::string>::const_iterator it1=pfls.begin();it1!=pfls.end();it1++) + { + DataArrayInt *pfl=const_cast<DataArrayInt *>(getProfile((*it1).c_str())); + if(!pfl) + throw INTERP_KERNEL::Exception("MEDFileFieldGlobs::deepCpyPart : internal error ! pfl null !"); + ret->_pfls.push_back(pfl->deepCpy()); + } + for(std::vector<std::string>::const_iterator it2=locs.begin();it2!=locs.end();it2++) + { + MEDFileFieldLoc *loc=const_cast<MEDFileFieldLoc *>(&getLocalization((*it2).c_str())); + if(!loc) + throw INTERP_KERNEL::Exception("MEDFileFieldGlobs::deepCpyPart : internal error ! loc null !"); + ret->_locs.push_back(loc->deepCpy()); + } + ret->setFileName(getFileName()); + return ret.retn(); +} + +MEDFileFieldGlobs::MEDFileFieldGlobs(const std::string& fname):_file_name(fname) +{ +} + +MEDFileFieldGlobs::MEDFileFieldGlobs() +{ +} + +MEDFileFieldGlobs::~MEDFileFieldGlobs() +{ +} + +void MEDFileFieldGlobs::simpleRepr(std::ostream& oss) const +{ + oss << "Profiles :\n"; + std::size_t n=_pfls.size(); + for(std::size_t i=0;i<n;i++) + { + oss << " - #" << i << " "; + const DataArrayInt *pfl=_pfls[i]; + if(pfl) + oss << "\"" << pfl->getName() << "\"\n"; + else + oss << "EMPTY !\n"; + } + n=_locs.size(); + oss << "Localizations :\n"; + for(std::size_t i=0;i<n;i++) + { + oss << " - #" << i << " "; + const MEDFileFieldLoc *loc=_locs[i]; + if(loc) + loc->simpleRepr(oss); + else + oss<< "EMPTY !\n"; + } +} + +void MEDFileFieldGlobs::setFileName(const std::string& fileName) +{ + _file_name=fileName; +} + +void MEDFileFieldGlobs::changePflsNamesInStruct(const std::vector< std::pair<std::vector<std::string>, std::string > >& mapOfModif) +{ + for(std::vector< MEDCouplingAutoRefCountObjectPtr<DataArrayInt> >::iterator it=_pfls.begin();it!=_pfls.end();it++) + { + DataArrayInt *elt(*it); + if(elt) + { + std::string name(elt->getName()); + for(std::vector< std::pair<std::vector<std::string>, std::string > >::const_iterator it2=mapOfModif.begin();it2!=mapOfModif.end();it2++) + { + if(std::find((*it2).first.begin(),(*it2).first.end(),name)!=(*it2).first.end()) + { + elt->setName((*it2).second.c_str()); + return; + } + } + } + } +} + +void MEDFileFieldGlobs::changeLocsNamesInStruct(const std::vector< std::pair<std::vector<std::string>, std::string > >& mapOfModif) +{ + for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileFieldLoc> >::iterator it=_locs.begin();it!=_locs.end();it++) + { + MEDFileFieldLoc *elt(*it); + if(elt) + { + std::string name(elt->getName()); + for(std::vector< std::pair<std::vector<std::string>, std::string > >::const_iterator it2=mapOfModif.begin();it2!=mapOfModif.end();it2++) + { + if(std::find((*it2).first.begin(),(*it2).first.end(),name)!=(*it2).first.end()) + { + elt->setName((*it2).second.c_str()); + return; + } + } + } + } +} + +int MEDFileFieldGlobs::getNbOfGaussPtPerCell(int locId) const +{ + if(locId<0 || locId>=(int)_locs.size()) + throw INTERP_KERNEL::Exception("MEDFileFieldGlobs::getNbOfGaussPtPerCell : Invalid localization id !"); + return _locs[locId]->getNbOfGaussPtPerCell(); +} + +const MEDFileFieldLoc& MEDFileFieldGlobs::getLocalization(const std::string& locName) const +{ + return getLocalizationFromId(getLocalizationId(locName)); +} + +const MEDFileFieldLoc& MEDFileFieldGlobs::getLocalizationFromId(int locId) const +{ + if(locId<0 || locId>=(int)_locs.size()) + throw INTERP_KERNEL::Exception("MEDFileFieldGlobs::getLocalizationFromId : Invalid localization id !"); + return *_locs[locId]; +} + +/// @cond INTERNAL +namespace ParaMEDMEMImpl +{ + class LocFinder + { + public: + LocFinder(const std::string& loc):_loc(loc) { } + bool operator() (const MEDCouplingAutoRefCountObjectPtr<MEDFileFieldLoc>& loc) { return loc->isName(_loc); } + private: + const std::string &_loc; + }; + + class PflFinder + { + public: + PflFinder(const std::string& pfl):_pfl(pfl) { } + bool operator() (const MEDCouplingAutoRefCountObjectPtr<DataArrayInt>& pfl) { return _pfl==pfl->getName(); } + private: + const std::string& _pfl; + }; +} +/// @endcond + +int MEDFileFieldGlobs::getLocalizationId(const std::string& loc) const +{ + std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileFieldLoc> >::const_iterator it=std::find_if(_locs.begin(),_locs.end(),ParaMEDMEMImpl::LocFinder(loc)); + if(it==_locs.end()) + { + std::ostringstream oss; oss << "MEDFileFieldGlobs::getLocalisationId : no such localisation name : \"" << loc << "\" Possible localizations are : "; + for(it=_locs.begin();it!=_locs.end();it++) + oss << "\"" << (*it)->getName() << "\", "; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + return std::distance(_locs.begin(),it); +} + +/*! + * The returned value is never null. + */ +const DataArrayInt *MEDFileFieldGlobs::getProfile(const std::string& pflName) const +{ + std::string pflNameCpp(pflName); + std::vector< MEDCouplingAutoRefCountObjectPtr<DataArrayInt> >::const_iterator it=std::find_if(_pfls.begin(),_pfls.end(),ParaMEDMEMImpl::PflFinder(pflNameCpp)); + if(it==_pfls.end()) + { + std::ostringstream oss; oss << "MEDFileFieldGlobs::getProfile: no such profile name : \"" << pflNameCpp << "\" Possible profiles are : "; + for(it=_pfls.begin();it!=_pfls.end();it++) + oss << "\"" << (*it)->getName() << "\", "; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + return *it; +} + +const DataArrayInt *MEDFileFieldGlobs::getProfileFromId(int pflId) const +{ + if(pflId<0 || pflId>=(int)_pfls.size()) + throw INTERP_KERNEL::Exception("MEDFileFieldGlobs::getProfileFromId : Invalid profile id !"); + return _pfls[pflId]; +} + +MEDFileFieldLoc& MEDFileFieldGlobs::getLocalizationFromId(int locId) +{ + if(locId<0 || locId>=(int)_locs.size()) + throw INTERP_KERNEL::Exception("MEDFileFieldGlobs::getLocalizationFromId : Invalid localization id !"); + return *_locs[locId]; +} + +MEDFileFieldLoc& MEDFileFieldGlobs::getLocalization(const std::string& locName) +{ + return getLocalizationFromId(getLocalizationId(locName)); +} + +/*! + * The returned value is never null. + */ +DataArrayInt *MEDFileFieldGlobs::getProfile(const std::string& pflName) +{ + std::string pflNameCpp(pflName); + std::vector< MEDCouplingAutoRefCountObjectPtr<DataArrayInt> >::iterator it=std::find_if(_pfls.begin(),_pfls.end(),ParaMEDMEMImpl::PflFinder(pflNameCpp)); + if(it==_pfls.end()) + { + std::ostringstream oss; oss << "MEDFileFieldGlobs::getProfile: no such profile name : \"" << pflNameCpp << "\" Possible profiles are : "; + for(it=_pfls.begin();it!=_pfls.end();it++) + oss << "\"" << (*it)->getName() << "\", "; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + return *it; +} + +DataArrayInt *MEDFileFieldGlobs::getProfileFromId(int pflId) +{ + if(pflId<0 || pflId>=(int)_pfls.size()) + throw INTERP_KERNEL::Exception("MEDFileFieldGlobs::getProfileFromId : Invalid profile id !"); + return _pfls[pflId]; +} + +void MEDFileFieldGlobs::killProfileIds(const std::vector<int>& pflIds) +{ + std::vector< MEDCouplingAutoRefCountObjectPtr<DataArrayInt> > newPfls; + int i=0; + for(std::vector< MEDCouplingAutoRefCountObjectPtr<DataArrayInt> >::const_iterator it=_pfls.begin();it!=_pfls.end();it++,i++) + { + if(std::find(pflIds.begin(),pflIds.end(),i)==pflIds.end()) + newPfls.push_back(*it); + } + _pfls=newPfls; +} + +void MEDFileFieldGlobs::killLocalizationIds(const std::vector<int>& locIds) +{ + std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileFieldLoc> > newLocs; + int i=0; + for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileFieldLoc> >::const_iterator it=_locs.begin();it!=_locs.end();it++,i++) + { + if(std::find(locIds.begin(),locIds.end(),i)==locIds.end()) + newLocs.push_back(*it); + } + _locs=newLocs; +} + +std::vector<std::string> MEDFileFieldGlobs::getPfls() const +{ + int sz=_pfls.size(); + std::vector<std::string> ret(sz); + for(int i=0;i<sz;i++) + ret[i]=_pfls[i]->getName(); + return ret; +} + +std::vector<std::string> MEDFileFieldGlobs::getLocs() const +{ + int sz=_locs.size(); + std::vector<std::string> ret(sz); + for(int i=0;i<sz;i++) + ret[i]=_locs[i]->getName(); + return ret; +} + +bool MEDFileFieldGlobs::existsPfl(const std::string& pflName) const +{ + std::vector<std::string> v=getPfls(); + std::string s(pflName); + return std::find(v.begin(),v.end(),s)!=v.end(); +} + +bool MEDFileFieldGlobs::existsLoc(const std::string& locName) const +{ + std::vector<std::string> v=getLocs(); + std::string s(locName); + return std::find(v.begin(),v.end(),s)!=v.end(); +} + +std::vector< std::vector<int> > MEDFileFieldGlobs::whichAreEqualProfiles() const +{ + std::map<int,std::vector<int> > m; + int i=0; + for(std::vector< MEDCouplingAutoRefCountObjectPtr<DataArrayInt> >::const_iterator it=_pfls.begin();it!=_pfls.end();it++,i++) + { + const DataArrayInt *tmp=(*it); + if(tmp) + { + m[tmp->getHashCode()].push_back(i); + } + } + std::vector< std::vector<int> > ret; + for(std::map<int,std::vector<int> >::const_iterator it2=m.begin();it2!=m.end();it2++) + { + if((*it2).second.size()>1) + { + std::vector<int> ret0; + bool equalityOrNot=false; + for(std::vector<int>::const_iterator it3=(*it2).second.begin();it3!=(*it2).second.end();it3++) + { + std::vector<int>::const_iterator it4=it3; it4++; + for(;it4!=(*it2).second.end();it4++) + { + if(_pfls[*it3]->isEqualWithoutConsideringStr(*_pfls[*it4])) + { + if(!equalityOrNot) + ret0.push_back(*it3); + ret0.push_back(*it4); + equalityOrNot=true; + } + } + } + if(!ret0.empty()) + ret.push_back(ret0); + } + } + return ret; +} + +std::vector< std::vector<int> > MEDFileFieldGlobs::whichAreEqualLocs(double eps) const +{ + throw INTERP_KERNEL::Exception("MEDFileFieldGlobs::whichAreEqualLocs : no implemented yet ! Sorry !"); +} + +void MEDFileFieldGlobs::appendProfile(DataArrayInt *pfl) +{ + std::string name(pfl->getName()); + if(name.empty()) + throw INTERP_KERNEL::Exception("MEDFileFieldGlobs::appendProfile : unsupported profiles with no name !"); + for(std::vector< MEDCouplingAutoRefCountObjectPtr<DataArrayInt> >::const_iterator it=_pfls.begin();it!=_pfls.end();it++) + if(name==(*it)->getName()) + { + if(!pfl->isEqual(*(*it))) + { + std::ostringstream oss; oss << "MEDFileFieldGlobs::appendProfile : profile \"" << name << "\" already exists and is different from existing !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + } + pfl->incrRef(); + _pfls.push_back(pfl); +} + +void MEDFileFieldGlobs::appendLoc(const std::string& locName, INTERP_KERNEL::NormalizedCellType geoType, const std::vector<double>& refCoo, const std::vector<double>& gsCoo, const std::vector<double>& w) +{ + std::string name(locName); + if(name.empty()) + throw INTERP_KERNEL::Exception("MEDFileFieldGlobs::appendLoc : unsupported localizations with no name !"); + MEDCouplingAutoRefCountObjectPtr<MEDFileFieldLoc> obj=MEDFileFieldLoc::New(locName,geoType,refCoo,gsCoo,w); + for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileFieldLoc> >::const_iterator it=_locs.begin();it!=_locs.end();it++) + if((*it)->isName(locName)) + { + if(!(*it)->isEqual(*obj,1e-12)) + { + std::ostringstream oss; oss << "MEDFileFieldGlobs::appendLoc : localization \"" << name << "\" already exists and is different from existing !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + } + _locs.push_back(obj); +} + +std::string MEDFileFieldGlobs::createNewNameOfPfl() const +{ + std::vector<std::string> names=getPfls(); + return CreateNewNameNotIn("NewPfl_",names); +} + +std::string MEDFileFieldGlobs::createNewNameOfLoc() const +{ + std::vector<std::string> names=getLocs(); + return CreateNewNameNotIn("NewLoc_",names); +} + +std::string MEDFileFieldGlobs::CreateNewNameNotIn(const std::string& prefix, const std::vector<std::string>& namesToAvoid) +{ + for(std::size_t sz=0;sz<100000;sz++) + { + std::ostringstream tryName; + tryName << prefix << sz; + if(std::find(namesToAvoid.begin(),namesToAvoid.end(),tryName.str())==namesToAvoid.end()) + return tryName.str(); + } + throw INTERP_KERNEL::Exception("MEDFileFieldGlobs::CreateNewNameNotIn : impossible to create an additional profile limit of 100000 profiles reached !"); +} + +/*! + * Creates a MEDFileFieldGlobsReal on a given file name. Nothing is read here. + * \param [in] fname - the file name. + */ +MEDFileFieldGlobsReal::MEDFileFieldGlobsReal(const std::string& fname):_globals(MEDFileFieldGlobs::New(fname)) +{ +} + +/*! + * Creates an empty MEDFileFieldGlobsReal. + */ +MEDFileFieldGlobsReal::MEDFileFieldGlobsReal():_globals(MEDFileFieldGlobs::New()) +{ +} + +std::size_t MEDFileFieldGlobsReal::getHeapMemorySizeWithoutChildren() const +{ + return 0; +} + +std::vector<const BigMemoryObject *> MEDFileFieldGlobsReal::getDirectChildrenWithNull() const +{ + std::vector<const BigMemoryObject *> ret; + ret.push_back((const MEDFileFieldGlobs *)_globals); + return ret; +} + +/*! + * Returns a string describing profiles and Gauss points held in \a this. + * \return std::string - the description string. + */ +void MEDFileFieldGlobsReal::simpleReprGlobs(std::ostream& oss) const +{ + const MEDFileFieldGlobs *glob=_globals; + std::ostringstream oss2; oss2 << glob; + std::string stars(oss2.str().length(),'*'); + oss << "Globals information on fields (at " << oss2.str() << "):" << "\n************************************" << stars << "\n\n"; + if(glob) + glob->simpleRepr(oss); + else + oss << "NO GLOBAL INFORMATION !\n"; +} + +void MEDFileFieldGlobsReal::resetContent() +{ + _globals=MEDFileFieldGlobs::New(); +} + +MEDFileFieldGlobsReal::~MEDFileFieldGlobsReal() +{ +} + +/*! + * Copies references to profiles and Gauss points from another MEDFileFieldGlobsReal. + * \param [in] other - the other MEDFileFieldGlobsReal to copy data from. + */ +void MEDFileFieldGlobsReal::shallowCpyGlobs(const MEDFileFieldGlobsReal& other) +{ + _globals=other._globals; +} + +/*! + * Copies references to ** only used ** by \a this, profiles and Gauss points from another MEDFileFieldGlobsReal. + * \param [in] other - the other MEDFileFieldGlobsReal to copy data from. + */ +void MEDFileFieldGlobsReal::shallowCpyOnlyUsedGlobs(const MEDFileFieldGlobsReal& other) +{ + const MEDFileFieldGlobs *otherg(other._globals); + if(!otherg) + return ; + _globals=otherg->shallowCpyPart(getPflsReallyUsed(),getLocsReallyUsed()); +} + +/*! + * Copies deeply to ** only used ** by \a this, profiles and Gauss points from another MEDFileFieldGlobsReal. + * \param [in] other - the other MEDFileFieldGlobsReal to copy data from. + */ +void MEDFileFieldGlobsReal::deepCpyOnlyUsedGlobs(const MEDFileFieldGlobsReal& other) +{ + const MEDFileFieldGlobs *otherg(other._globals); + if(!otherg) + return ; + _globals=otherg->deepCpyPart(getPflsReallyUsed(),getLocsReallyUsed()); +} + +void MEDFileFieldGlobsReal::deepCpyGlobs(const MEDFileFieldGlobsReal& other) +{ + _globals=other._globals; + if((const MEDFileFieldGlobs *)_globals) + _globals=other._globals->deepCpy(); +} + +/*! + * Adds profiles and Gauss points held by another MEDFileFieldGlobsReal to \a this one. + * \param [in] other - the MEDFileFieldGlobsReal to copy data from. + * \param [in] eps - a precision used to compare Gauss points with same name held by + * \a this and \a other MEDFileFieldGlobsReal. + * \throw If \a this and \a other hold profiles with equal names but different ids. + * \throw If \a this and \a other hold different Gauss points with equal names. + */ +void MEDFileFieldGlobsReal::appendGlobs(const MEDFileFieldGlobsReal& other, double eps) +{ + const MEDFileFieldGlobs *thisGlobals(_globals),*otherGlobals(other._globals); + if(thisGlobals==otherGlobals) + return ; + if(!thisGlobals) + { + _globals=other._globals; + return ; + } + _globals->appendGlobs(*other._globals,eps); +} + +void MEDFileFieldGlobsReal::checkGlobsCoherency() const +{ + checkGlobsPflsPartCoherency(); + checkGlobsLocsPartCoherency(); +} + +void MEDFileFieldGlobsReal::checkGlobsPflsPartCoherency() const +{ + contentNotNull()->checkGlobsPflsPartCoherency(getPflsReallyUsed()); +} + +void MEDFileFieldGlobsReal::checkGlobsLocsPartCoherency() const +{ + contentNotNull()->checkGlobsLocsPartCoherency(getLocsReallyUsed()); +} + +void MEDFileFieldGlobsReal::loadProfileInFile(med_idt fid, int id, const std::string& pflName) +{ + contentNotNull()->loadProfileInFile(fid,id,pflName); +} + +void MEDFileFieldGlobsReal::loadProfileInFile(med_idt fid, int id) +{ + contentNotNull()->loadProfileInFile(fid,id); +} + +void MEDFileFieldGlobsReal::loadGlobals(med_idt fid) +{ + contentNotNull()->loadGlobals(fid,*this); +} + +void MEDFileFieldGlobsReal::loadAllGlobals(med_idt fid) +{ + contentNotNull()->loadAllGlobals(fid); +} + +void MEDFileFieldGlobsReal::writeGlobals(med_idt fid, const MEDFileWritable& opt) const +{ + contentNotNull()->writeGlobals(fid,opt); +} + +/*! + * Returns names of all profiles. To get only used profiles call getPflsReallyUsed() + * or getPflsReallyUsedMulti(). + * \return std::vector<std::string> - a sequence of names of all profiles. + */ +std::vector<std::string> MEDFileFieldGlobsReal::getPfls() const +{ + return contentNotNull()->getPfls(); +} + +/*! + * Returns names of all localizations. To get only used localizations call getLocsReallyUsed() + * or getLocsReallyUsedMulti(). + * \return std::vector<std::string> - a sequence of names of all localizations. + */ +std::vector<std::string> MEDFileFieldGlobsReal::getLocs() const +{ + return contentNotNull()->getLocs(); +} + +/*! + * Checks if the profile with a given name exists. + * \param [in] pflName - the profile name of interest. + * \return bool - \c true if the profile named \a pflName exists. + */ +bool MEDFileFieldGlobsReal::existsPfl(const std::string& pflName) const +{ + return contentNotNull()->existsPfl(pflName); +} + +/*! + * Checks if the localization with a given name exists. + * \param [in] locName - the localization name of interest. + * \return bool - \c true if the localization named \a locName exists. + */ +bool MEDFileFieldGlobsReal::existsLoc(const std::string& locName) const +{ + return contentNotNull()->existsLoc(locName); +} + +std::string MEDFileFieldGlobsReal::createNewNameOfPfl() const +{ + return contentNotNull()->createNewNameOfPfl(); +} + +std::string MEDFileFieldGlobsReal::createNewNameOfLoc() const +{ + return contentNotNull()->createNewNameOfLoc(); +} + +/*! + * Sets the name of a MED file. + * \param [inout] fileName - the file name. + */ +void MEDFileFieldGlobsReal::setFileName(const std::string& fileName) +{ + contentNotNull()->setFileName(fileName); +} + +/*! + * Finds equal profiles. Two profiles are considered equal if they contain the same ids + * in the same order. + * \return std::vector< std::vector<int> > - a sequence of groups of equal profiles. + * Each item of this sequence is a vector containing ids of equal profiles. + */ +std::vector< std::vector<int> > MEDFileFieldGlobsReal::whichAreEqualProfiles() const +{ + return contentNotNull()->whichAreEqualProfiles(); +} + +/*! + * Finds equal localizations. + * \param [in] eps - a precision used to compare real values of the localizations. + * \return std::vector< std::vector<int> > - a sequence of groups of equal localizations. + * Each item of this sequence is a vector containing ids of equal localizations. + */ +std::vector< std::vector<int> > MEDFileFieldGlobsReal::whichAreEqualLocs(double eps) const +{ + return contentNotNull()->whichAreEqualLocs(eps); +} + +/*! + * Renames the profiles. References to profiles (a reference is a profile name) are not changed. + * \param [in] mapOfModif - a sequence describing required renaming. 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 name of the first item. + */ +void MEDFileFieldGlobsReal::changePflsNamesInStruct(const std::vector< std::pair<std::vector<std::string>, std::string > >& mapOfModif) +{ + contentNotNull()->changePflsNamesInStruct(mapOfModif); +} + +/*! + * Renames the localizations. References to localizations (a reference is a localization name) are not changed. + * \param [in] mapOfModif - a sequence describing required renaming. 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 name of the first item. + */ +void MEDFileFieldGlobsReal::changeLocsNamesInStruct(const std::vector< std::pair<std::vector<std::string>, std::string > >& mapOfModif) +{ + contentNotNull()->changeLocsNamesInStruct(mapOfModif); +} + +/*! + * Replaces references to some profiles (a reference is a profile name) by references + * to other profiles and, contrary to changePflsRefsNamesGen(), renames the profiles + * them-selves accordingly. <br> + * This method is a generalization of changePflName(). + * \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. + * \sa changePflsRefsNamesGen() + * \sa changePflName() + */ +void MEDFileFieldGlobsReal::changePflsNames(const std::vector< std::pair<std::vector<std::string>, std::string > >& mapOfModif) +{ + changePflsRefsNamesGen(mapOfModif); + changePflsNamesInStruct(mapOfModif); +} + +/*! + * Replaces references to some localizations (a reference is a localization name) by references + * to other localizations and, contrary to changeLocsRefsNamesGen(), renames the localizations + * them-selves accordingly. <br> + * This method is a generalization of changeLocName(). + * \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. + * \sa changeLocsRefsNamesGen() + * \sa changeLocName() + */ +void MEDFileFieldGlobsReal::changeLocsNames(const std::vector< std::pair<std::vector<std::string>, std::string > >& mapOfModif) +{ + changeLocsRefsNamesGen(mapOfModif); + changeLocsNamesInStruct(mapOfModif); +} + +/*! + * Renames the profile having a given name and updates references to this profile. + * \param [in] oldName - the name of the profile to rename. + * \param [in] newName - a new name of the profile. + * \sa changePflsNames(). + */ +void MEDFileFieldGlobsReal::changePflName(const std::string& oldName, const std::string& newName) +{ + std::vector< std::pair<std::vector<std::string>, std::string > > mapOfModif(1); + std::pair<std::vector<std::string>, std::string > p(std::vector<std::string>(1,std::string(oldName)),std::string(newName)); + mapOfModif[0]=p; + changePflsNames(mapOfModif); +} + +/*! + * Renames the localization having a given name and updates references to this localization. + * \param [in] oldName - the name of the localization to rename. + * \param [in] newName - a new name of the localization. + * \sa changeLocsNames(). + */ +void MEDFileFieldGlobsReal::changeLocName(const std::string& oldName, const std::string& newName) +{ + std::vector< std::pair<std::vector<std::string>, std::string > > mapOfModif(1); + std::pair<std::vector<std::string>, std::string > p(std::vector<std::string>(1,std::string(oldName)),std::string(newName)); + mapOfModif[0]=p; + changeLocsNames(mapOfModif); +} + +/*! + * Removes duplicated profiles. Returns a map used to update references to removed + * profiles via changePflsRefsNamesGen(). + * Equal profiles are found using whichAreEqualProfiles(). + * \return std::vector< std::pair<std::vector<std::string>, std::string > > - + * a sequence describing the performed replacements of profiles. Each element of + * this sequence is a pair whose + * - the first item is a vector of profile names replaced by the second item, + * - the second item is a profile name replacing every profile of the first item. + */ +std::vector< std::pair<std::vector<std::string>, std::string > > MEDFileFieldGlobsReal::zipPflsNames() +{ + std::vector< std::vector<int> > pseudoRet=whichAreEqualProfiles(); + std::vector< std::pair<std::vector<std::string>, std::string > > ret(pseudoRet.size()); + int i=0; + for(std::vector< std::vector<int> >::const_iterator it=pseudoRet.begin();it!=pseudoRet.end();it++,i++) + { + std::vector< std::string > tmp((*it).size()); + int j=0; + for(std::vector<int>::const_iterator it2=(*it).begin();it2!=(*it).end();it2++,j++) + tmp[j]=std::string(getProfileFromId(*it2)->getName()); + std::pair<std::vector<std::string>, std::string > p(tmp,tmp.front()); + ret[i]=p; + std::vector<int> tmp2((*it).begin()+1,(*it).end()); + killProfileIds(tmp2); + } + changePflsRefsNamesGen(ret); + return ret; +} + +/*! + * Removes duplicated localizations. Returns a map used to update references to removed + * localizations via changeLocsRefsNamesGen(). + * Equal localizations are found using whichAreEqualLocs(). + * \param [in] eps - a precision used to compare real values of the localizations. + * \return std::vector< std::pair<std::vector<std::string>, std::string > > - + * a sequence describing the performed replacements of localizations. Each element of + * this sequence is a pair whose + * - the first item is a vector of localization names replaced by the second item, + * - the second item is a localization name replacing every localization of the first item. + */ +std::vector< std::pair<std::vector<std::string>, std::string > > MEDFileFieldGlobsReal::zipLocsNames(double eps) +{ + std::vector< std::vector<int> > pseudoRet=whichAreEqualLocs(eps); + std::vector< std::pair<std::vector<std::string>, std::string > > ret(pseudoRet.size()); + int i=0; + for(std::vector< std::vector<int> >::const_iterator it=pseudoRet.begin();it!=pseudoRet.end();it++,i++) + { + std::vector< std::string > tmp((*it).size()); + int j=0; + for(std::vector<int>::const_iterator it2=(*it).begin();it2!=(*it).end();it2++,j++) + tmp[j]=std::string(getLocalizationFromId(*it2).getName()); + std::pair<std::vector<std::string>, std::string > p(tmp,tmp.front()); + ret[i]=p; + std::vector<int> tmp2((*it).begin()+1,(*it).end()); + killLocalizationIds(tmp2); + } + changeLocsRefsNamesGen(ret); + return ret; +} + +/*! + * Returns number of Gauss points per cell in a given localization. + * \param [in] locId - an id of the localization of interest. + * \return int - the number of the Gauss points per cell. + */ +int MEDFileFieldGlobsReal::getNbOfGaussPtPerCell(int locId) const +{ + return contentNotNull()->getNbOfGaussPtPerCell(locId); +} + +/*! + * Returns an id of a localization by its name. + * \param [in] loc - the localization name of interest. + * \return int - the id of the localization. + * \throw If there is no a localization named \a loc. + */ +int MEDFileFieldGlobsReal::getLocalizationId(const std::string& loc) const +{ + return contentNotNull()->getLocalizationId(loc); +} + +/*! + * Returns the name of the MED file. + * \return const std::string& - the MED file name. + */ +std::string MEDFileFieldGlobsReal::getFileName() const +{ + return contentNotNull()->getFileName(); +} + +/*! + * Returns a localization object by its name. + * \param [in] locName - the name of the localization of interest. + * \return const MEDFileFieldLoc& - the localization object having the name \a locName. + * \throw If there is no a localization named \a locName. + */ +const MEDFileFieldLoc& MEDFileFieldGlobsReal::getLocalization(const std::string& locName) const +{ + return contentNotNull()->getLocalization(locName); +} + +/*! + * Returns a localization object by its id. + * \param [in] locId - the id of the localization of interest. + * \return const MEDFileFieldLoc& - the localization object having the id \a locId. + * \throw If there is no a localization with id \a locId. + */ +const MEDFileFieldLoc& MEDFileFieldGlobsReal::getLocalizationFromId(int locId) const +{ + return contentNotNull()->getLocalizationFromId(locId); +} + +/*! + * Returns a profile array by its name. + * \param [in] pflName - the name of the profile of interest. + * \return const DataArrayInt * - the profile array having the name \a pflName. + * \throw If there is no a profile named \a pflName. + */ +const DataArrayInt *MEDFileFieldGlobsReal::getProfile(const std::string& pflName) const +{ + return contentNotNull()->getProfile(pflName); +} + +/*! + * Returns a profile array by its id. + * \param [in] pflId - the id of the profile of interest. + * \return const DataArrayInt * - the profile array having the id \a pflId. + * \throw If there is no a profile with id \a pflId. + */ +const DataArrayInt *MEDFileFieldGlobsReal::getProfileFromId(int pflId) const +{ + return contentNotNull()->getProfileFromId(pflId); +} + +/*! + * Returns a localization object, apt for modification, by its id. + * \param [in] locId - the id of the localization of interest. + * \return MEDFileFieldLoc& - a non-const reference to the localization object + * having the id \a locId. + * \throw If there is no a localization with id \a locId. + */ +MEDFileFieldLoc& MEDFileFieldGlobsReal::getLocalizationFromId(int locId) +{ + return contentNotNull()->getLocalizationFromId(locId); +} + +/*! + * Returns a localization object, apt for modification, by its name. + * \param [in] locName - the name of the localization of interest. + * \return MEDFileFieldLoc& - a non-const reference to the localization object + * having the name \a locName. + * \throw If there is no a localization named \a locName. + */ +MEDFileFieldLoc& MEDFileFieldGlobsReal::getLocalization(const std::string& locName) +{ + return contentNotNull()->getLocalization(locName); +} + +/*! + * Returns a profile array, apt for modification, by its name. + * \param [in] pflName - the name of the profile of interest. + * \return DataArrayInt * - a non-const pointer to the profile array having the name \a pflName. + * \throw If there is no a profile named \a pflName. + */ +DataArrayInt *MEDFileFieldGlobsReal::getProfile(const std::string& pflName) +{ + return contentNotNull()->getProfile(pflName); +} + +/*! + * Returns a profile array, apt for modification, by its id. + * \param [in] pflId - the id of the profile of interest. + * \return DataArrayInt * - a non-const pointer to the profile array having the id \a pflId. + * \throw If there is no a profile with id \a pflId. + */ +DataArrayInt *MEDFileFieldGlobsReal::getProfileFromId(int pflId) +{ + return contentNotNull()->getProfileFromId(pflId); +} + +/*! + * Removes profiles given by their ids. No data is updated to track this removal. + * \param [in] pflIds - a sequence of ids of the profiles to remove. + */ +void MEDFileFieldGlobsReal::killProfileIds(const std::vector<int>& pflIds) +{ + contentNotNull()->killProfileIds(pflIds); +} + +/*! + * Removes localizations given by their ids. No data is updated to track this removal. + * \param [in] locIds - a sequence of ids of the localizations to remove. + */ +void MEDFileFieldGlobsReal::killLocalizationIds(const std::vector<int>& locIds) +{ + contentNotNull()->killLocalizationIds(locIds); +} + +/*! + * Stores a profile array. + * \param [in] pfl - the profile array to store. + * \throw If the name of \a pfl is empty. + * \throw If a profile with the same name as that of \a pfl already exists but contains + * different ids. + */ +void MEDFileFieldGlobsReal::appendProfile(DataArrayInt *pfl) +{ + contentNotNull()->appendProfile(pfl); +} + +/*! + * Adds a new localization of Gauss points. + * \param [in] locName - the name of the new localization. + * \param [in] geoType - a geometrical type of the reference cell. + * \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] w - the weights of Gauss points. + * \throw If \a locName is empty. + * \throw If a localization with the name \a locName already exists but is + * different form the new one. + */ +void MEDFileFieldGlobsReal::appendLoc(const std::string& locName, INTERP_KERNEL::NormalizedCellType geoType, const std::vector<double>& refCoo, const std::vector<double>& gsCoo, const std::vector<double>& w) +{ + contentNotNull()->appendLoc(locName,geoType,refCoo,gsCoo,w); +} + +MEDFileFieldGlobs *MEDFileFieldGlobsReal::contentNotNull() +{ + MEDFileFieldGlobs *g(_globals); + if(!g) + throw INTERP_KERNEL::Exception("MEDFileFieldGlobsReal::contentNotNull : no content in not const !"); + return g; +} + +const MEDFileFieldGlobs *MEDFileFieldGlobsReal::contentNotNull() const +{ + const MEDFileFieldGlobs *g(_globals); + if(!g) + throw INTERP_KERNEL::Exception("MEDFileFieldGlobsReal::contentNotNull : no content in const !"); + return g; +} + +//= MEDFileFieldNameScope + +MEDFileFieldNameScope::MEDFileFieldNameScope() +{ +} + +MEDFileFieldNameScope::MEDFileFieldNameScope(const std::string& fieldName):_name(fieldName) +{ +} + +/*! + * Returns the name of \a this field. + * \return std::string - a string containing the field name. + */ +std::string MEDFileFieldNameScope::getName() const +{ + return _name; +} + +/*! + * Sets name of \a this field + * \param [in] name - the new field name. + */ +void MEDFileFieldNameScope::setName(const std::string& fieldName) +{ + _name=fieldName; +} + +std::string MEDFileFieldNameScope::getDtUnit() const +{ + return _dt_unit; +} + +void MEDFileFieldNameScope::setDtUnit(const std::string& dtUnit) +{ + _dt_unit=dtUnit; +} + +void MEDFileFieldNameScope::copyNameScope(const MEDFileFieldNameScope& other) +{ + _name=other._name; + _dt_unit=other._dt_unit; +} + +//= MEDFileAnyTypeField1TSWithoutSDA + +void MEDFileAnyTypeField1TSWithoutSDA::deepCpyLeavesFrom(const MEDFileAnyTypeField1TSWithoutSDA& other) +{ + _field_per_mesh.resize(other._field_per_mesh.size()); + std::size_t i=0; + for(std::vector< MEDCouplingAutoRefCountObjectPtr< MEDFileFieldPerMesh > >::const_iterator it=other._field_per_mesh.begin();it!=other._field_per_mesh.end();it++,i++) + { + if((const MEDFileFieldPerMesh *)*it) + _field_per_mesh[i]=(*it)->deepCpy(this); + } +} + +/*! + * Prints a string describing \a this field into a stream. This string is outputted + * by \c print Python command. + * \param [in] bkOffset - number of white spaces printed at the beginning of each line. + * \param [in,out] oss - the out stream. + * \param [in] f1tsId - the field index within a MED file. If \a f1tsId < 0, the tiny + * info id printed, else, not. + */ +void MEDFileAnyTypeField1TSWithoutSDA::simpleRepr(int bkOffset, std::ostream& oss, int f1tsId) const +{ + std::string startOfLine(bkOffset,' '); + oss << startOfLine << "Field "; + if(bkOffset==0) + oss << "[Type=" << getTypeStr() << "] with name \"" << getName() << "\" "; + oss << "on one time Step "; + if(f1tsId>=0) + oss << "(" << f1tsId << ") "; + oss << "on iteration=" << _iteration << " order=" << _order << "." << std::endl; + oss << startOfLine << "Time attached is : " << _dt << " [" << _dt_unit << "]." << std::endl; + const DataArray *arr=getUndergroundDataArray(); + if(arr) + { + const std::vector<std::string> &comps=arr->getInfoOnComponents(); + if(f1tsId<0) + { + oss << startOfLine << "Field has " << comps.size() << " components with the following infos :" << std::endl; + for(std::vector<std::string>::const_iterator it=comps.begin();it!=comps.end();it++) + oss << startOfLine << " - \"" << (*it) << "\"" << std::endl; + } + if(arr->isAllocated()) + { + oss << startOfLine << "Whole field contains " << arr->getNumberOfTuples() << " tuples." << std::endl; + } + else + oss << startOfLine << "The array of the current field has not allocated yet !" << std::endl; + } + else + { + oss << startOfLine << "Field infos are empty ! Not defined yet !" << std::endl; + } + oss << startOfLine << "----------------------" << std::endl; + if(!_field_per_mesh.empty()) + { + int i=0; + for(std::vector< MEDCouplingAutoRefCountObjectPtr< MEDFileFieldPerMesh > >::const_iterator it2=_field_per_mesh.begin();it2!=_field_per_mesh.end();it2++,i++) + { + const MEDFileFieldPerMesh *cur=(*it2); + if(cur) + cur->simpleRepr(bkOffset,oss,i); + else + oss << startOfLine << "Field per mesh #" << i << " is not defined !" << std::endl; + } + } + else + { + oss << startOfLine << "Field is not defined on any meshes !" << std::endl; + } + oss << startOfLine << "----------------------" << std::endl; +} + +std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileAnyTypeField1TSWithoutSDA> > MEDFileAnyTypeField1TSWithoutSDA::splitComponents() const +{ + const DataArray *arr(getUndergroundDataArray()); + if(!arr) + throw INTERP_KERNEL::Exception("MEDFileAnyTypeField1TSWithoutSDA::splitComponents : no array defined !"); + int nbOfCompo=arr->getNumberOfComponents(); + std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileAnyTypeField1TSWithoutSDA> > ret(nbOfCompo); + for(int i=0;i<nbOfCompo;i++) + { + ret[i]=deepCpy(); + std::vector<int> v(1,i); + MEDCouplingAutoRefCountObjectPtr<DataArray> arr2=arr->keepSelectedComponents(v); + ret[i]->setArray(arr2); + } + return ret; +} + +MEDFileAnyTypeField1TSWithoutSDA::MEDFileAnyTypeField1TSWithoutSDA(const std::string& fieldName, int csit, int iteration, int order):MEDFileFieldNameScope(fieldName),_iteration(iteration),_order(order),_csit(csit),_nb_of_tuples_to_be_allocated(-2) +{ +} + +MEDFileAnyTypeField1TSWithoutSDA::MEDFileAnyTypeField1TSWithoutSDA():_iteration(-1),_order(-1),_dt(0.),_csit(-1),_nb_of_tuples_to_be_allocated(-1) +{ +} + +/*! + * Returns the maximal dimension of supporting elements. Returns -2 if \a this is + * empty. Returns -1 if this in on nodes. + * \return int - the dimension of \a this. + */ +int MEDFileAnyTypeField1TSWithoutSDA::getDimension() const +{ + int ret=-2; + for(std::vector< MEDCouplingAutoRefCountObjectPtr< MEDFileFieldPerMesh > >::const_iterator it=_field_per_mesh.begin();it!=_field_per_mesh.end();it++) + (*it)->getDimension(ret); + return ret; +} + +/*! + * Returns the mesh name. + * \return std::string - a string holding the mesh name. + * \throw If \c _field_per_mesh.empty() + */ +std::string MEDFileAnyTypeField1TSWithoutSDA::getMeshName() const +{ + if(_field_per_mesh.empty()) + throw INTERP_KERNEL::Exception("MEDFileFieldPerMeshPerTypePerDisc::getMeshName : No field set !"); + return _field_per_mesh[0]->getMeshName(); +} + +void MEDFileAnyTypeField1TSWithoutSDA::setMeshName(const std::string& newMeshName) +{ + std::string oldName(getMeshName()); + std::vector< std::pair<std::string,std::string> > v(1); + v[0].first=oldName; v[0].second=newMeshName; + changeMeshNames(v); +} + +bool MEDFileAnyTypeField1TSWithoutSDA::changeMeshNames(const std::vector< std::pair<std::string,std::string> >& modifTab) +{ + bool ret=false; + for(std::vector< MEDCouplingAutoRefCountObjectPtr< MEDFileFieldPerMesh > >::iterator it=_field_per_mesh.begin();it!=_field_per_mesh.end();it++) + { + MEDFileFieldPerMesh *cur(*it); + if(cur) + ret=cur->changeMeshNames(modifTab) || ret; + } + return ret; +} + +/*! + * Returns the number of iteration of the state of underlying mesh. + * \return int - the iteration number. + * \throw If \c _field_per_mesh.empty() + */ +int MEDFileAnyTypeField1TSWithoutSDA::getMeshIteration() const +{ + if(_field_per_mesh.empty()) + throw INTERP_KERNEL::Exception("MEDFileFieldPerMeshPerTypePerDisc::getMeshIteration : No field set !"); + return _field_per_mesh[0]->getMeshIteration(); +} + +/*! + * Returns the order number of iteration of the state of underlying mesh. + * \return int - the order number. + * \throw If \c _field_per_mesh.empty() + */ +int MEDFileAnyTypeField1TSWithoutSDA::getMeshOrder() const +{ + if(_field_per_mesh.empty()) + throw INTERP_KERNEL::Exception("MEDFileFieldPerMeshPerTypePerDisc::getMeshOrder : No field set !"); + return _field_per_mesh[0]->getMeshOrder(); +} + +/*! + * Checks if \a this field is tagged by a given iteration number and a given + * iteration order number. + * \param [in] iteration - the iteration number of interest. + * \param [in] order - the iteration order number of interest. + * \return bool - \c true if \a this->getIteration() == \a iteration && + * \a this->getOrder() == \a order. + */ +bool MEDFileAnyTypeField1TSWithoutSDA::isDealingTS(int iteration, int order) const +{ + return iteration==_iteration && order==_order; +} + +/*! + * Returns number of iteration and order number of iteration when + * \a this field has been calculated. + * \return std::pair<int,int> - a pair of the iteration number and the iteration + * order number. + */ +std::pair<int,int> MEDFileAnyTypeField1TSWithoutSDA::getDtIt() const +{ + std::pair<int,int> p; + fillIteration(p); + return p; +} + +/*! + * Returns number of iteration and order number of iteration when + * \a this field has been calculated. + * \param [in,out] p - a pair returning the iteration number and the iteration + * order number. + */ +void MEDFileAnyTypeField1TSWithoutSDA::fillIteration(std::pair<int,int>& p) const +{ + p.first=_iteration; + p.second=_order; +} + +/*! + * Returns all types of spatial discretization of \a this field. + * \param [in,out] types - a sequence of types of \a this field. + */ +void MEDFileAnyTypeField1TSWithoutSDA::fillTypesOfFieldAvailable(std::vector<TypeOfField>& types) const +{ + std::set<TypeOfField> types2; + for(std::vector< MEDCouplingAutoRefCountObjectPtr< MEDFileFieldPerMesh > >::const_iterator it=_field_per_mesh.begin();it!=_field_per_mesh.end();it++) + { + (*it)->fillTypesOfFieldAvailable(types2); + } + std::back_insert_iterator< std::vector<TypeOfField> > bi(types); + std::copy(types2.begin(),types2.end(),bi); +} + +/*! + * Returns all types of spatial discretization of \a this field. + * \return std::vector<TypeOfField> - a sequence of types of spatial discretization + * of \a this field. + */ +std::vector<TypeOfField> MEDFileAnyTypeField1TSWithoutSDA::getTypesOfFieldAvailable() const +{ + std::vector<TypeOfField> ret; + fillTypesOfFieldAvailable(ret); + return ret; +} + +std::vector<std::string> MEDFileAnyTypeField1TSWithoutSDA::getPflsReallyUsed2() const +{ + std::vector<std::string> ret; + std::set<std::string> ret2; + for(std::vector< MEDCouplingAutoRefCountObjectPtr< MEDFileFieldPerMesh > >::const_iterator it=_field_per_mesh.begin();it!=_field_per_mesh.end();it++) + { + std::vector<std::string> tmp=(*it)->getPflsReallyUsed(); + for(std::vector<std::string>::const_iterator it2=tmp.begin();it2!=tmp.end();it2++) + if(ret2.find(*it2)==ret2.end()) + { + ret.push_back(*it2); + ret2.insert(*it2); + } + } + return ret; +} + +std::vector<std::string> MEDFileAnyTypeField1TSWithoutSDA::getLocsReallyUsed2() const +{ + std::vector<std::string> ret; + std::set<std::string> ret2; + for(std::vector< MEDCouplingAutoRefCountObjectPtr< MEDFileFieldPerMesh > >::const_iterator it=_field_per_mesh.begin();it!=_field_per_mesh.end();it++) + { + std::vector<std::string> tmp=(*it)->getLocsReallyUsed(); + for(std::vector<std::string>::const_iterator it2=tmp.begin();it2!=tmp.end();it2++) + if(ret2.find(*it2)==ret2.end()) + { + ret.push_back(*it2); + ret2.insert(*it2); + } + } + return ret; +} + +std::vector<std::string> MEDFileAnyTypeField1TSWithoutSDA::getPflsReallyUsedMulti2() const +{ + std::vector<std::string> ret; + for(std::vector< MEDCouplingAutoRefCountObjectPtr< MEDFileFieldPerMesh > >::const_iterator it=_field_per_mesh.begin();it!=_field_per_mesh.end();it++) + { + std::vector<std::string> tmp=(*it)->getPflsReallyUsedMulti(); + ret.insert(ret.end(),tmp.begin(),tmp.end()); + } + return ret; +} + +std::vector<std::string> MEDFileAnyTypeField1TSWithoutSDA::getLocsReallyUsedMulti2() const +{ + std::vector<std::string> ret; + std::set<std::string> ret2; + for(std::vector< MEDCouplingAutoRefCountObjectPtr< MEDFileFieldPerMesh > >::const_iterator it=_field_per_mesh.begin();it!=_field_per_mesh.end();it++) + { + std::vector<std::string> tmp=(*it)->getLocsReallyUsedMulti(); + ret.insert(ret.end(),tmp.begin(),tmp.end()); + } + return ret; +} + +void MEDFileAnyTypeField1TSWithoutSDA::changePflsRefsNamesGen2(const std::vector< std::pair<std::vector<std::string>, std::string > >& mapOfModif) +{ + for(std::vector< MEDCouplingAutoRefCountObjectPtr< MEDFileFieldPerMesh > >::iterator it=_field_per_mesh.begin();it!=_field_per_mesh.end();it++) + (*it)->changePflsRefsNamesGen(mapOfModif); +} + +void MEDFileAnyTypeField1TSWithoutSDA::changeLocsRefsNamesGen2(const std::vector< std::pair<std::vector<std::string>, std::string > >& mapOfModif) +{ + for(std::vector< MEDCouplingAutoRefCountObjectPtr< MEDFileFieldPerMesh > >::iterator it=_field_per_mesh.begin();it!=_field_per_mesh.end();it++) + (*it)->changeLocsRefsNamesGen(mapOfModif); +} + +/*! + * Returns all attributes of parts of \a this field lying on a given mesh. + * Each part differs from other ones by a type of supporting mesh entity. The _i_-th + * item of every of returned sequences refers to the _i_-th part of \a this field. + * Thus all sequences returned by this method are of the same length equal to number + * of different types of supporting entities.<br> + * A field part can include sub-parts with several different spatial discretizations, + * \ref ParaMEDMEM::ON_CELLS "ON_CELLS" and \ref ParaMEDMEM::ON_GAUSS_PT "ON_GAUSS_PT" + * for example. Hence, some of the returned sequences contains nested sequences, and an item + * of a nested sequence corresponds to a type of spatial discretization.<br> + * This method allows for iteration over MEDFile DataStructure without any overhead. + * \param [in] mname - a name of a mesh of interest. It can be \c NULL, which is valid + * for the case with only one underlying mesh. (Actually, the number of meshes is + * not checked if \a mname == \c NULL). + * \param [in,out] types - a sequence of types of underlying mesh entities. A type per + * a field part is returned. + * \param [in,out] typesF - a sequence of sequences of types of spatial discretizations. + * This sequence is of the same length as \a types. + * \param [in,out] pfls - a sequence returning a profile name per each type of spatial + * discretization. A profile name can be empty. + * Length of this and of nested sequences is the same as that of \a typesF. + * \param [in,out] locs - a sequence returning a localization name per each type of spatial + * discretization. A localization name can be empty. + * Length of this and of nested sequences is the same as that of \a typesF. + * \return std::vector< std::vector< std::pair<int,int> > > - a sequence holding a range + * of ids of tuples within the data array, per each type of spatial + * discretization within one mesh entity type. + * Length of this and of nested sequences is the same as that of \a typesF. + * \throw If no field is lying on \a mname. + */ +std::vector< std::vector< std::pair<int,int> > > MEDFileAnyTypeField1TSWithoutSDA::getFieldSplitedByType(const std::string& mname, std::vector<INTERP_KERNEL::NormalizedCellType>& types, std::vector< std::vector<TypeOfField> >& typesF, std::vector< std::vector<std::string> >& pfls, std::vector< std::vector<std::string> >& locs) const +{ + int meshId=0; + if(!mname.empty()) + meshId=getMeshIdFromMeshName(mname); + else + if(_field_per_mesh.empty()) + throw INTERP_KERNEL::Exception("MEDFileField1TSWithoutSDA::getFieldSplitedByType : This is empty !"); + return _field_per_mesh[meshId]->getFieldSplitedByType(types,typesF,pfls,locs); +} + +/*! + * Returns dimensions of mesh elements \a this field lies on. The returned value is a + * maximal absolute dimension and values returned via the out parameter \a levs are + * dimensions relative to the maximal absolute dimension. <br> + * This method is designed for MEDFileField1TS instances that have a discretization + * \ref ParaMEDMEM::ON_CELLS "ON_CELLS", + * \ref ParaMEDMEM::ON_GAUSS_PT "ON_GAUSS_PT", + * \ref ParaMEDMEM::ON_GAUSS_NE "ON_GAUSS_NE". + * Only these 3 discretizations will be taken into account here. If \a this is + * \ref ParaMEDMEM::ON_NODES "ON_NODES", -1 is returned and \a levs are empty.<br> + * This method is useful to make the link between the dimension of the underlying mesh + * and the levels of \a this, because it is possible that the highest dimension of \a this + * field is not equal to the dimension of the underlying mesh. + * + * Let's consider the following case: + * - mesh \a m1 has a meshDimension 3 and has non empty levels [0,-1,-2] with elements + * TETRA4, HEXA8, TRI3 and SEG2. + * - field \a f1 lies on \a m1 and is defined on 3D and 1D elements TETRA4 and SEG2. + * - field \a f2 lies on \a m1 and is defined on 2D and 1D elements TRI3 and SEG2. + * + * In this case \a f1->getNonEmptyLevels() returns (3,[0,-2]) and \a + * f2->getNonEmptyLevels() returns (2,[0,-1]). <br> + * The returned values can be used for example to retrieve a MEDCouplingFieldDouble lying + * on elements of a certain relative level by calling getFieldAtLevel(). \a meshDimRelToMax + * parameter of getFieldAtLevel() is computed basing on the returned values as this: + * <em> meshDimRelToMax = absDim - meshDim + relativeLev </em>. + * For example<br> + * to retrieve the highest level of + * \a f1: <em>f1->getFieldAtLevel( ON_CELLS, 3-3+0 ); // absDim - meshDim + relativeLev</em><br> + * to retrieve the lowest level of \a f1: <em>f1->getFieldAtLevel( ON_CELLS, 3-3+(-2) );</em><br> + * to retrieve the highest level of \a f2: <em>f2->getFieldAtLevel( ON_CELLS, 2-3+0 );</em><br> + * to retrieve the lowest level of \a f2: <em>f2->getFieldAtLevel( ON_CELLS, 2-3+(-1) )</em>. + * \param [in] mname - a name of a mesh of interest. It can be \c NULL, which is valid + * for the case with only one underlying mesh. (Actually, the number of meshes is + * not checked if \a mname == \c NULL). + * \param [in,out] levs - a sequence returning the dimensions relative to the maximal + * absolute one. They are in decreasing order. This sequence is cleared before + * filling it in. + * \return int - the maximal absolute dimension of elements \a this fields lies on. + * \throw If no field is lying on \a mname. + */ +int MEDFileAnyTypeField1TSWithoutSDA::getNonEmptyLevels(const std::string& mname, std::vector<int>& levs) const +{ + levs.clear(); + int meshId=getMeshIdFromMeshName(mname); + std::vector<INTERP_KERNEL::NormalizedCellType> types; + std::vector< std::vector<TypeOfField> > typesF; + std::vector< std::vector<std::string> > pfls, locs; + _field_per_mesh[meshId]->getFieldSplitedByType(types,typesF,pfls,locs); + if(types.empty()) + throw INTERP_KERNEL::Exception("MEDFileField1TSWithoutSDA::getNonEmptyLevels : 'this' is empty !"); + std::set<INTERP_KERNEL::NormalizedCellType> st(types.begin(),types.end()); + if(st.size()==1 && (*st.begin())==INTERP_KERNEL::NORM_ERROR) + return -1; + st.erase(INTERP_KERNEL::NORM_ERROR); + std::set<int> ret1; + for(std::set<INTERP_KERNEL::NormalizedCellType>::const_iterator it=st.begin();it!=st.end();it++) + { + const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(*it); + ret1.insert((int)cm.getDimension()); + } + int ret=*std::max_element(ret1.begin(),ret1.end()); + std::copy(ret1.rbegin(),ret1.rend(),std::back_insert_iterator<std::vector<int> >(levs)); + std::transform(levs.begin(),levs.end(),levs.begin(),std::bind2nd(std::plus<int>(),-ret)); + return ret; +} + +/*! + * \param [in] mName specifies the underlying mesh name. This value can be pointer 0 for users that do not deal with fields on multi mesh. + * \param [in] typ is for the geometric cell type (or INTERP_KERNEL::NORM_ERROR for node field) entry to find the right MEDFileFieldPerMeshPerTypePerDisc instance to set. + * \param [in] locId is the localization id to find the right MEDFileFieldPerMeshPerTypePerDisc instance to set. It corresponds to the position of + * \c pfls[std::distance(types.begin(),std::find(types.begin(),typ)] vector in MEDFileField1TSWithoutSDA::getFieldSplitedByType. For non gausspoints field users, the value is 0. + */ +MEDFileFieldPerMeshPerTypePerDisc *MEDFileAnyTypeField1TSWithoutSDA::getLeafGivenMeshAndTypeAndLocId(const std::string& mName, INTERP_KERNEL::NormalizedCellType typ, int locId) +{ + int mid=getMeshIdFromMeshName(mName); + return _field_per_mesh[mid]->getLeafGivenTypeAndLocId(typ,locId); +} + +/*! + * \param [in] mName specifies the underlying mesh name. This value can be pointer 0 for users that do not deal with fields on multi mesh. + * \param [in] typ is for the geometric cell type (or INTERP_KERNEL::NORM_ERROR for node field) entry to find the right MEDFileFieldPerMeshPerTypePerDisc instance to set. + * \param [in] locId is the localization id to find the right MEDFileFieldPerMeshPerTypePerDisc instance to set. It corresponds to the position of + * \c pfls[std::distance(types.begin(),std::find(types.begin(),typ)] vector in MEDFileField1TSWithoutSDA::getFieldSplitedByType. For non gausspoints field users, the value is 0. + */ +const MEDFileFieldPerMeshPerTypePerDisc *MEDFileAnyTypeField1TSWithoutSDA::getLeafGivenMeshAndTypeAndLocId(const std::string& mName, INTERP_KERNEL::NormalizedCellType typ, int locId) const +{ + int mid=getMeshIdFromMeshName(mName); + return _field_per_mesh[mid]->getLeafGivenTypeAndLocId(typ,locId); +} + +/*! + * \param [in] mName specifies the underlying mesh name. This value can be pointer 0 for users that do not deal with fields on multi mesh. + */ +int MEDFileAnyTypeField1TSWithoutSDA::getMeshIdFromMeshName(const std::string& mName) const +{ + if(_field_per_mesh.empty()) + throw INTERP_KERNEL::Exception("MEDFileField1TSWithoutSDA::getMeshIdFromMeshName : No field set !"); + if(mName.empty()) + return 0; + std::string mName2(mName); + int ret=0; + std::vector<std::string> msg; + for(std::vector< MEDCouplingAutoRefCountObjectPtr< MEDFileFieldPerMesh > >::const_iterator it=_field_per_mesh.begin();it!=_field_per_mesh.end();it++,ret++) + if(mName2==(*it)->getMeshName()) + return ret; + else + msg.push_back((*it)->getMeshName()); + std::ostringstream oss; oss << "MEDFileField1TSWithoutSDA::getMeshIdFromMeshName : No such mesh \"" << mName2 << "\" as underlying mesh of field \"" << getName() << "\" !\n"; + oss << "Possible meshes are : "; + for(std::vector<std::string>::const_iterator it2=msg.begin();it2!=msg.end();it2++) + oss << "\"" << (*it2) << "\" "; + throw INTERP_KERNEL::Exception(oss.str().c_str()); +} + +int MEDFileAnyTypeField1TSWithoutSDA::addNewEntryIfNecessary(const MEDCouplingMesh *mesh) +{ + if(!mesh) + throw INTERP_KERNEL::Exception("MEDFileAnyTypeField1TSWithoutSDA::addNewEntryIfNecessary : input mesh is NULL !"); + std::string tmp(mesh->getName()); + if(tmp.empty()) + throw INTERP_KERNEL::Exception("MEDFileField1TSWithoutSDA::addNewEntryIfNecessary : empty mesh name ! unsupported by MED file !"); + std::vector< MEDCouplingAutoRefCountObjectPtr< MEDFileFieldPerMesh > >::const_iterator it=_field_per_mesh.begin(); + int i=0; + for(;it!=_field_per_mesh.end();it++,i++) + { + if((*it)->getMeshName()==tmp) + return i; + } + int sz=_field_per_mesh.size(); + _field_per_mesh.resize(sz+1); + _field_per_mesh[sz]=MEDFileFieldPerMesh::New(this,mesh); + return sz; +} + +bool MEDFileAnyTypeField1TSWithoutSDA::renumberEntitiesLyingOnMesh(const std::string& meshName, const std::vector<int>& oldCode, const std::vector<int>& newCode, const DataArrayInt *renumO2N, + MEDFileFieldGlobsReal& glob) +{ + bool ret=false; + for(std::vector< MEDCouplingAutoRefCountObjectPtr< MEDFileFieldPerMesh > >::iterator it=_field_per_mesh.begin();it!=_field_per_mesh.end();it++) + { + MEDFileFieldPerMesh *fpm(*it); + if(fpm) + ret=fpm->renumberEntitiesLyingOnMesh(meshName,oldCode,newCode,renumO2N,glob) || ret; + } + return ret; +} + +/*! + * This method splits \a this into several sub-parts so that each sub parts have exactly one spatial discretization. This method implements the minimal + * splitting that leads to single spatial discretization of this. + * + * \sa splitMultiDiscrPerGeoTypes + */ +std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileAnyTypeField1TSWithoutSDA> > MEDFileAnyTypeField1TSWithoutSDA::splitDiscretizations() const +{ + std::vector<INTERP_KERNEL::NormalizedCellType> types; + std::vector< std::vector<TypeOfField> > typesF; + std::vector< std::vector<std::string> > pfls,locs; + std::vector< std::vector<std::pair<int,int> > > bgEnd(getFieldSplitedByType(getMeshName().c_str(),types,typesF,pfls,locs)); + std::set<TypeOfField> allEnt; + for(std::vector< std::vector<TypeOfField> >::const_iterator it1=typesF.begin();it1!=typesF.end();it1++) + for(std::vector<TypeOfField>::const_iterator it2=(*it1).begin();it2!=(*it1).end();it2++) + allEnt.insert(*it2); + std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileAnyTypeField1TSWithoutSDA> > ret(allEnt.size()); + std::set<TypeOfField>::const_iterator it3(allEnt.begin()); + for(std::size_t i=0;i<allEnt.size();i++,it3++) + { + std::vector< std::pair<int,int> > its; + ret[i]=shallowCpy(); + int newLgth(ret[i]->keepOnlySpatialDiscretization(*it3,its)); + ret[i]->updateData(newLgth,its); + } + return ret; +} + +/*! + * This method performs a sub splitting as splitDiscretizations does but finer. This is the finest spliting level that can be done. + * This method implements the minimal splitting so that each returned elements are mono Gauss discretization per geometric type. + * + * \sa splitDiscretizations + */ +std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileAnyTypeField1TSWithoutSDA> > MEDFileAnyTypeField1TSWithoutSDA::splitMultiDiscrPerGeoTypes() const +{ + std::vector<INTERP_KERNEL::NormalizedCellType> types; + std::vector< std::vector<TypeOfField> > typesF; + std::vector< std::vector<std::string> > pfls,locs; + std::vector< std::vector<std::pair<int,int> > > bgEnd(getFieldSplitedByType(getMeshName().c_str(),types,typesF,pfls,locs)); + std::set<TypeOfField> allEnt; + std::size_t nbOfMDPGT(0),ii(0); + for(std::vector< std::vector<TypeOfField> >::const_iterator it1=typesF.begin();it1!=typesF.end();it1++,ii++) + { + nbOfMDPGT=std::max(nbOfMDPGT,locs[ii].size()); + for(std::vector<TypeOfField>::const_iterator it2=(*it1).begin();it2!=(*it1).end();it2++) + allEnt.insert(*it2); + } + if(allEnt.size()!=1) + throw INTERP_KERNEL::Exception("MEDFileAnyTypeField1TSWithoutSDA::splitMultiDiscrPerGeoTypes : this field is expected to be defined only on one spatial discretization !"); + if(nbOfMDPGT==0) + throw INTERP_KERNEL::Exception("MEDFileAnyTypeField1TSWithoutSDA::splitMultiDiscrPerGeoTypes : empty field !"); + if(nbOfMDPGT==1) + { + std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileAnyTypeField1TSWithoutSDA> > ret0(1); + ret0[0]=const_cast<MEDFileAnyTypeField1TSWithoutSDA *>(this); this->incrRef(); + return ret0; + } + std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileAnyTypeField1TSWithoutSDA> > ret(nbOfMDPGT); + for(std::size_t i=0;i<nbOfMDPGT;i++) + { + std::vector< std::pair<int,int> > its; + ret[i]=shallowCpy(); + int newLgth(ret[i]->keepOnlyGaussDiscretization(i,its)); + ret[i]->updateData(newLgth,its); + } + return ret; +} + +int MEDFileAnyTypeField1TSWithoutSDA::keepOnlySpatialDiscretization(TypeOfField tof, std::vector< std::pair<int,int> >& its) +{ + int globalCounter(0); + for(std::vector< MEDCouplingAutoRefCountObjectPtr< MEDFileFieldPerMesh > >::iterator it=_field_per_mesh.begin();it!=_field_per_mesh.end();it++) + (*it)->keepOnlySpatialDiscretization(tof,globalCounter,its); + return globalCounter; +} + +int MEDFileAnyTypeField1TSWithoutSDA::keepOnlyGaussDiscretization(std::size_t idOfDisc, std::vector< std::pair<int,int> >& its) +{ + int globalCounter(0); + for(std::vector< MEDCouplingAutoRefCountObjectPtr< MEDFileFieldPerMesh > >::iterator it=_field_per_mesh.begin();it!=_field_per_mesh.end();it++) + (*it)->keepOnlyGaussDiscretization(idOfDisc,globalCounter,its); + return globalCounter; +} + +void MEDFileAnyTypeField1TSWithoutSDA::updateData(int newLgth, const std::vector< std::pair<int,int> >& oldStartStops) +{ + if(_nb_of_tuples_to_be_allocated>=0) + { + _nb_of_tuples_to_be_allocated=newLgth; + const DataArray *oldArr(getUndergroundDataArray()); + if(oldArr) + { + MEDCouplingAutoRefCountObjectPtr<DataArray> newArr(createNewEmptyDataArrayInstance()); + newArr->setInfoAndChangeNbOfCompo(oldArr->getInfoOnComponents()); + setArray(newArr); + _nb_of_tuples_to_be_allocated=newLgth;//force the _nb_of_tuples_to_be_allocated because setArray has been used specialy + } + return ; + } + if(_nb_of_tuples_to_be_allocated==-1) + return ; + if(_nb_of_tuples_to_be_allocated==-2 || _nb_of_tuples_to_be_allocated==-3) + { + const DataArray *oldArr(getUndergroundDataArray()); + if(!oldArr || !oldArr->isAllocated()) + throw INTERP_KERNEL::Exception("MEDFileAnyTypeField1TSWithoutSDA::updateData : internal error 1 !"); + MEDCouplingAutoRefCountObjectPtr<DataArray> newArr(createNewEmptyDataArrayInstance()); + newArr->alloc(newLgth,getNumberOfComponents()); + if(oldArr) + newArr->copyStringInfoFrom(*oldArr); + int pos=0; + for(std::vector< std::pair<int,int> >::const_iterator it=oldStartStops.begin();it!=oldStartStops.end();it++) + { + if((*it).second<(*it).first) + throw INTERP_KERNEL::Exception("MEDFileAnyTypeField1TSWithoutSDA::updateData : the range in the leaves was invalid !"); + newArr->setContigPartOfSelectedValues2(pos,oldArr,(*it).first,(*it).second,1); + pos+=(*it).second-(*it).first; + } + setArray(newArr); + return ; + } + throw INTERP_KERNEL::Exception("MEDFileAnyTypeField1TSWithoutSDA::updateData : internal error 2 !"); +} + +void MEDFileAnyTypeField1TSWithoutSDA::writeLL(med_idt fid, const MEDFileWritable& opts, const MEDFileFieldNameScope& nasc) const +{ + if(_field_per_mesh.empty()) + throw INTERP_KERNEL::Exception("MEDFileField1TSWithoutSDA::writeLL : empty field !"); + if(_field_per_mesh.size()>1) + throw INTERP_KERNEL::Exception("MEDFileField1TSWithoutSDA::writeLL : In MED3.0 mode in writting mode only ONE underlying mesh supported !"); + _field_per_mesh[0]->copyOptionsFrom(opts); + _field_per_mesh[0]->writeLL(fid,nasc); +} + +/*! + * This methods returns true is the allocation has been needed leading to a modification of state in \a this->_nb_of_tuples_to_be_allocated. + * If false is returned the memory allocation is not required. + */ +bool MEDFileAnyTypeField1TSWithoutSDA::allocIfNecessaryTheArrayToReceiveDataFromFile() +{ + if(_nb_of_tuples_to_be_allocated>=0) + { + getOrCreateAndGetArray()->alloc(_nb_of_tuples_to_be_allocated,getNumberOfComponents()); + _nb_of_tuples_to_be_allocated=-2; + return true; + } + if(_nb_of_tuples_to_be_allocated==-2 || _nb_of_tuples_to_be_allocated==-3) + return false; + if(_nb_of_tuples_to_be_allocated==-1) + throw INTERP_KERNEL::Exception("MEDFileAnyTypeField1TSWithoutSDA::allocIfNecessaryTheArrayToReceiveDataFromFile : trying to read from a file an empty instance ! Need to prepare the structure before !"); + if(_nb_of_tuples_to_be_allocated<-3) + throw INTERP_KERNEL::Exception("MEDFileAnyTypeField1TSWithoutSDA::allocIfNecessaryTheArrayToReceiveDataFromFile : internal error !"); + throw INTERP_KERNEL::Exception("MEDFileAnyTypeField1TSWithoutSDA::allocIfNecessaryTheArrayToReceiveDataFromFile : internal error !"); +} + +void MEDFileAnyTypeField1TSWithoutSDA::loadOnlyStructureOfDataRecursively(med_idt fid, const MEDFileFieldNameScope& nasc, const MEDFileMeshes *ms, const std::vector< std::pair<TypeOfField,INTERP_KERNEL::NormalizedCellType> > *entities) +{ + med_int numdt,numit; + med_float dt; + med_int nmesh; + med_bool localMesh; + med_int meshnumdt,meshnumit; + INTERP_KERNEL::AutoPtr<char> meshName=MEDLoaderBase::buildEmptyString(MED_NAME_SIZE); + MEDFILESAFECALLERRD0(MEDfieldComputingStepInfo,(fid,nasc.getName().c_str(),_csit,&numdt,&numit,&_dt)); + MEDFILESAFECALLERRD0(MEDfield23ComputingStepMeshInfo,(fid,nasc.getName().c_str(),_csit,&numdt,&numit,&dt,&nmesh,meshName,&localMesh,&meshnumdt,&meshnumit)); + if(_iteration!=numdt || _order!=numit) + throw INTERP_KERNEL::Exception("MEDFileAnyTypeField1TSWithoutSDA::loadBigArraysRecursively : unexpected exception internal error !"); + _field_per_mesh.resize(nmesh); + // + MEDFileMesh *mm(0); + if(ms) + { + std::string meshNameCpp(MEDLoaderBase::buildStringFromFortran(meshName,MED_NAME_SIZE+1)); + mm=ms->getMeshWithName(meshNameCpp); + } + // + for(int i=0;i<nmesh;i++) + _field_per_mesh[i]=MEDFileFieldPerMesh::NewOnRead(fid,this,i,meshnumdt,meshnumit,nasc,mm,entities); + _nb_of_tuples_to_be_allocated=0; + for(int i=0;i<nmesh;i++) + _field_per_mesh[i]->loadOnlyStructureOfDataRecursively(fid,_nb_of_tuples_to_be_allocated,nasc); +} + +void MEDFileAnyTypeField1TSWithoutSDA::loadBigArraysRecursively(med_idt fid, const MEDFileFieldNameScope& nasc) +{ + allocIfNecessaryTheArrayToReceiveDataFromFile(); + for(std::vector< MEDCouplingAutoRefCountObjectPtr< MEDFileFieldPerMesh > >::iterator it=_field_per_mesh.begin();it!=_field_per_mesh.end();it++) + (*it)->loadBigArraysRecursively(fid,nasc); +} + +void MEDFileAnyTypeField1TSWithoutSDA::loadBigArraysRecursivelyIfNecessary(med_idt fid, const MEDFileFieldNameScope& nasc) +{ + if(allocIfNecessaryTheArrayToReceiveDataFromFile()) + for(std::vector< MEDCouplingAutoRefCountObjectPtr< MEDFileFieldPerMesh > >::iterator it=_field_per_mesh.begin();it!=_field_per_mesh.end();it++) + (*it)->loadBigArraysRecursively(fid,nasc); +} + +void MEDFileAnyTypeField1TSWithoutSDA::loadStructureAndBigArraysRecursively(med_idt fid, const MEDFileFieldNameScope& nasc, const MEDFileMeshes *ms, const std::vector< std::pair<TypeOfField,INTERP_KERNEL::NormalizedCellType> > *entities) +{ + loadOnlyStructureOfDataRecursively(fid,nasc,ms,entities); + loadBigArraysRecursively(fid,nasc); +} + +void MEDFileAnyTypeField1TSWithoutSDA::unloadArrays() +{ + DataArray *thisArr(getUndergroundDataArray()); + if(thisArr && thisArr->isAllocated()) + { + _nb_of_tuples_to_be_allocated=thisArr->getNumberOfTuples(); + thisArr->desallocate(); + } +} + +std::size_t MEDFileAnyTypeField1TSWithoutSDA::getHeapMemorySizeWithoutChildren() const +{ + return _dt_unit.capacity()+_field_per_mesh.capacity()*sizeof(MEDCouplingAutoRefCountObjectPtr< MEDFileFieldPerMesh >); +} + +std::vector<const BigMemoryObject *> MEDFileAnyTypeField1TSWithoutSDA::getDirectChildrenWithNull() const +{ + std::vector<const BigMemoryObject *> ret; + if(getUndergroundDataArray()) + ret.push_back(getUndergroundDataArray()); + for(std::vector< MEDCouplingAutoRefCountObjectPtr< MEDFileFieldPerMesh > >::const_iterator it=_field_per_mesh.begin();it!=_field_per_mesh.end();it++) + ret.push_back((const MEDFileFieldPerMesh *)*it); + return ret; +} + +/*! + * Adds a MEDCouplingFieldDouble to \a this. The underlying mesh of the given field is + * checked if its elements are sorted suitable for writing to MED file ("STB" stands for + * "Sort By Type"), if not, an exception is thrown. + * \param [in] field - the field to add to \a this. The array of field \a field is ignored + * \param [in] arr - the array of values. + * \param [in,out] glob - the global data where profiles and localization present in + * \a field, if any, are added. + * \throw If the name of \a field is empty. + * \throw If the data array of \a field is not set. + * \throw If \a this->_arr is already allocated but has different number of components + * than \a field. + * \throw If the underlying mesh of \a field has no name. + * \throw If elements in the mesh are not in the order suitable for writing to the MED file. + */ +void MEDFileAnyTypeField1TSWithoutSDA::setFieldNoProfileSBT(const MEDCouplingFieldDouble *field, const DataArray *arr, MEDFileFieldGlobsReal& glob, const MEDFileFieldNameScope& nasc) +{ + const MEDCouplingMesh *mesh=field->getMesh(); + // + TypeOfField type=field->getTypeOfField(); + std::vector<DataArrayInt *> dummy; + int start=copyTinyInfoFrom(field,arr); + int pos=addNewEntryIfNecessary(mesh); + if(type!=ON_NODES) + { + std::vector<int> code=MEDFileField1TSWithoutSDA::CheckSBTMesh(mesh); + _field_per_mesh[pos]->assignFieldNoProfileNoRenum(start,code,field,arr,glob,nasc); + } + else + _field_per_mesh[pos]->assignNodeFieldNoProfile(start,field,arr,glob); +} + +/*! + * Adds a MEDCouplingFieldDouble to \a this. Specified entities of a given dimension + * of a given mesh are used as the support of the given field (a real support is not used). + * Elements of the given mesh must be sorted suitable for writing to MED file. + * Order of underlying mesh entities of the given field specified by \a profile parameter + * is not prescribed; this method permutes field values to have them sorted by element + * type as required for writing to MED file. A new profile is added only if no equal + * profile is missing. + * \param [in] field - the field to add to \a this. The field double values are ignored. + * \param [in] arrOfVals - the values of the field \a field used. + * \param [in] mesh - the supporting mesh of \a field. + * \param [in] meshDimRelToMax - a relative dimension of mesh entities \a field lies on. + * \param [in] profile - ids of mesh entities on which corresponding field values lie. + * \param [in,out] glob - the global data where profiles and localization present in + * \a field, if any, are added. + * \throw If either \a field or \a mesh or \a profile has an empty name. + * \throw If there are no mesh entities of \a meshDimRelToMax dimension in \a mesh. + * \throw If the data array of \a field is not set. + * \throw If \a this->_arr is already allocated but has different number of components + * than \a field. + * \throw If elements in \a mesh are not in the order suitable for writing to the MED file. + * \sa setFieldNoProfileSBT() + */ +void MEDFileAnyTypeField1TSWithoutSDA::setFieldProfile(const MEDCouplingFieldDouble *field, const DataArray *arrOfVals, const MEDFileMesh *mesh, int meshDimRelToMax, const DataArrayInt *profile, MEDFileFieldGlobsReal& glob, const MEDFileFieldNameScope& nasc) +{ + if(!field) + throw INTERP_KERNEL::Exception("MEDFileAnyTypeField1TSWithoutSDA::setFieldProfile : input field is null !"); + if(!arrOfVals || !arrOfVals->isAllocated()) + throw INTERP_KERNEL::Exception("MEDFileAnyTypeField1TSWithoutSDA::setFieldProfile : input array is null or not allocated !"); + TypeOfField type=field->getTypeOfField(); + std::vector<DataArrayInt *> idsInPflPerType; + std::vector<DataArrayInt *> idsPerType; + std::vector<int> code,code2; + MEDCouplingAutoRefCountObjectPtr<MEDCouplingMesh> m=mesh->getGenMeshAtLevel(meshDimRelToMax); + if(type!=ON_NODES) + { + m->splitProfilePerType(profile,code,idsInPflPerType,idsPerType); + std::vector< MEDCouplingAutoRefCountObjectPtr<DataArrayInt> > idsInPflPerType2(idsInPflPerType.size()); std::copy(idsInPflPerType.begin(),idsInPflPerType.end(),idsInPflPerType2.begin()); + std::vector< MEDCouplingAutoRefCountObjectPtr<DataArrayInt> > idsPerType2(idsPerType.size()); std::copy(idsPerType.begin(),idsPerType.end(),idsPerType2.begin()); + std::vector<const DataArrayInt *> idsPerType3(idsPerType.size()); std::copy(idsPerType.begin(),idsPerType.end(),idsPerType3.begin()); + // start of check + MEDCouplingAutoRefCountObjectPtr<MEDCouplingFieldDouble> field2=field->clone(false); + int nbOfTuplesExp=field2->getNumberOfTuplesExpectedRegardingCode(code,idsPerType3); + if(nbOfTuplesExp!=arrOfVals->getNumberOfTuples()) + { + std::ostringstream oss; oss << "MEDFileAnyTypeField1TSWithoutSDA::setFieldProfile : The array is expected to have " << nbOfTuplesExp << " tuples ! It has " << arrOfVals->getNumberOfTuples() << " !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + // end of check + int start=copyTinyInfoFrom(field,arrOfVals); + code2=m->getDistributionOfTypes(); + // + int pos=addNewEntryIfNecessary(m); + _field_per_mesh[pos]->assignFieldProfile(start,profile,code,code2,idsInPflPerType,idsPerType,field,arrOfVals,m,glob,nasc); + } + else + { + if(!profile || !profile->isAllocated() || profile->getNumberOfComponents()!=1) + throw INTERP_KERNEL::Exception("MEDFileAnyTypeField1TSWithoutSDA::setFieldProfile : input profile is null, not allocated or with number of components != 1 !"); + std::vector<int> v(3); v[0]=-1; v[1]=profile->getNumberOfTuples(); v[2]=0; + std::vector<const DataArrayInt *> idsPerType3(1); idsPerType3[0]=profile; + int nbOfTuplesExp=field->getNumberOfTuplesExpectedRegardingCode(v,idsPerType3); + if(nbOfTuplesExp!=arrOfVals->getNumberOfTuples()) + { + std::ostringstream oss; oss << "MEDFileAnyTypeField1TSWithoutSDA::setFieldProfile : For node field, the array is expected to have " << nbOfTuplesExp << " tuples ! It has " << arrOfVals->getNumberOfTuples() << " !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + int start=copyTinyInfoFrom(field,arrOfVals); + int pos=addNewEntryIfNecessary(m); + _field_per_mesh[pos]->assignNodeFieldProfile(start,profile,field,arrOfVals,glob,nasc); + } +} + +/*! + * \param [in] newNbOfTuples - The new nb of tuples to be allocated. + */ +void MEDFileAnyTypeField1TSWithoutSDA::allocNotFromFile(int newNbOfTuples) +{ + if(_nb_of_tuples_to_be_allocated>=0) + throw INTERP_KERNEL::Exception("MEDFileAnyTypeField1TSWithoutSDA::allocNotFromFile : the object is expected to be appended to a data coming from a file but not loaded ! Load before appending data !"); + DataArray *arr(getOrCreateAndGetArray()); + arr->alloc(newNbOfTuples,arr->getNumberOfComponents()); + _nb_of_tuples_to_be_allocated=-3; +} + +/*! + * Copies tiny info and allocates \a this->_arr instance of DataArrayDouble to + * append data of a given MEDCouplingFieldDouble. So that the size of \a this->_arr becomes + * larger by the size of \a field. Returns an id of the first not filled + * tuple of \a this->_arr. + * \param [in] field - the field to copy the info on components and the name from. + * \return int - the id of first not initialized tuple of \a this->_arr. + * \throw If the name of \a field is empty. + * \throw If the data array of \a field is not set. + * \throw If \a this->_arr is already allocated but has different number of components + * than \a field. + */ +int MEDFileAnyTypeField1TSWithoutSDA::copyTinyInfoFrom(const MEDCouplingFieldDouble *field, const DataArray *arr) +{ + if(!field) + throw INTERP_KERNEL::Exception("MEDFileAnyTypeField1TSWithoutSDA::copyTinyInfoFrom : input field is NULL !"); + std::string name(field->getName()); + setName(name.c_str()); + setDtUnit(field->getTimeUnit()); + if(name.empty()) + throw INTERP_KERNEL::Exception("MEDFileField1TSWithoutSDA::copyTinyInfoFrom : unsupported fields with no name in MED file !"); + if(!arr) + throw INTERP_KERNEL::Exception("MEDFileField1TSWithoutSDA::copyTinyInfoFrom : no array set !"); + if(!arr->isAllocated()) + throw INTERP_KERNEL::Exception("MEDFileField1TSWithoutSDA::copyTinyInfoFrom : array is not allocated !"); + _dt=field->getTime(_iteration,_order); + getOrCreateAndGetArray()->setInfoAndChangeNbOfCompo(arr->getInfoOnComponents()); + if(!getOrCreateAndGetArray()->isAllocated()) + { + allocNotFromFile(arr->getNumberOfTuples()); + return 0; + } + else + { + int oldNbOfTuples=getOrCreateAndGetArray()->getNumberOfTuples(); + int newNbOfTuples=oldNbOfTuples+arr->getNumberOfTuples(); + getOrCreateAndGetArray()->reAlloc(newNbOfTuples); + _nb_of_tuples_to_be_allocated=-3; + return oldNbOfTuples; + } +} + +/*! + * Returns number of components in \a this field + * \return int - the number of components. + */ +int MEDFileAnyTypeField1TSWithoutSDA::getNumberOfComponents() const +{ + return getOrCreateAndGetArray()->getNumberOfComponents(); +} + +/*! + * Change info on components in \a this. + * \throw If size of \a infos is not equal to the number of components already in \a this. + */ +void MEDFileAnyTypeField1TSWithoutSDA::setInfo(const std::vector<std::string>& infos) +{ + DataArray *arr=getOrCreateAndGetArray(); + arr->setInfoOnComponents(infos);//will throw an exception if number of components mimatches +} + +/*! + * Returns info on components of \a this field. + * \return const std::vector<std::string>& - a sequence of strings each being an + * information on _i_-th component. + */ +const std::vector<std::string>& MEDFileAnyTypeField1TSWithoutSDA::getInfo() const +{ + const DataArray *arr=getOrCreateAndGetArray(); + return arr->getInfoOnComponents(); +} + +/*! + * Returns a mutable info on components of \a this field. + * \return std::vector<std::string>& - a sequence of strings each being an + * information on _i_-th component. + */ +std::vector<std::string>& MEDFileAnyTypeField1TSWithoutSDA::getInfo() +{ + DataArray *arr=getOrCreateAndGetArray(); + return arr->getInfoOnComponents(); +} + +bool MEDFileAnyTypeField1TSWithoutSDA::presenceOfMultiDiscPerGeoType() const +{ + for(std::vector< MEDCouplingAutoRefCountObjectPtr< MEDFileFieldPerMesh > >::const_iterator it=_field_per_mesh.begin();it!=_field_per_mesh.end();it++) + { + const MEDFileFieldPerMesh *fpm(*it); + if(!fpm) + continue; + if(fpm->presenceOfMultiDiscPerGeoType()) + return true; + } + return false; +} + +/*! + * Returns a new MEDCouplingFieldDouble of given type lying on a given support. + * \param [in] type - a spatial discretization of the new field. + * \param [in] meshDimRelToMax - a relative dimension of the supporting mesh entities. + * \param [in] mName - a name of the supporting mesh. + * \param [in] renumPol - specifies how to permute values of the result field according to + * the optional numbers of cells and nodes, if any. The valid values are + * - 0 - do not permute. + * - 1 - permute cells. + * - 2 - permute nodes. + * - 3 - permute cells and nodes. + * + * \param [in] glob - the global data storing profiles and localization. + * \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 MED file is not readable. + * \throw If there is no mesh named \a mName in the MED file. + * \throw If there are no mesh entities of \a meshDimRelToMax dimension in the mesh. + * \throw If no field of \a this is lying on the mesh \a mName. + * \throw If no field values of the given \a type or given \a meshDimRelToMax are available. + */ +MEDCouplingFieldDouble *MEDFileAnyTypeField1TSWithoutSDA::getFieldAtLevel(TypeOfField type, int meshDimRelToMax, const std::string& mName, int renumPol, const MEDFileFieldGlobsReal *glob, MEDCouplingAutoRefCountObjectPtr<DataArray>& arrOut, const MEDFileFieldNameScope& nasc) const +{ + MEDCouplingAutoRefCountObjectPtr<MEDFileMesh> mm; + if(mName.empty()) + mm=MEDFileMesh::New(glob->getFileName(),getMeshName().c_str(),getMeshIteration(),getMeshOrder()); + else + mm=MEDFileMesh::New(glob->getFileName(),mName,getMeshIteration(),getMeshOrder()); + return MEDFileAnyTypeField1TSWithoutSDA::getFieldOnMeshAtLevel(type,meshDimRelToMax,renumPol,glob,mm,arrOut,nasc); +} + +/*! + * Returns a new MEDCouplingFieldDouble of given type lying on a given support. + * \param [in] type - a spatial discretization of the new field. + * \param [in] meshDimRelToMax - a relative dimension of the supporting mesh entities. + * \param [in] renumPol - specifies how to permute values of the result field according to + * the optional numbers of cells and nodes, if any. The valid values are + * - 0 - do not permute. + * - 1 - permute cells. + * - 2 - permute nodes. + * - 3 - permute cells and nodes. + * + * \param [in] glob - the global data storing profiles and localization. + * \param [in] mesh - the supporting mesh. + * \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 MED file is not readable. + * \throw If no field of \a this is lying on \a mesh. + * \throw If there are no mesh entities of \a meshDimRelToMax dimension in the mesh. + * \throw If no field values of the given \a type or given \a meshDimRelToMax are available. + */ +MEDCouplingFieldDouble *MEDFileAnyTypeField1TSWithoutSDA::getFieldOnMeshAtLevel(TypeOfField type, int meshDimRelToMax, int renumPol, const MEDFileFieldGlobsReal *glob, const MEDFileMesh *mesh, MEDCouplingAutoRefCountObjectPtr<DataArray>& arrOut, const MEDFileFieldNameScope& nasc) const +{ + MEDCouplingAutoRefCountObjectPtr<MEDCouplingMesh> m=mesh->getGenMeshAtLevel(meshDimRelToMax,false); + const DataArrayInt *d=mesh->getNumberFieldAtLevel(meshDimRelToMax); + const DataArrayInt *e=mesh->getNumberFieldAtLevel(1); + if(meshDimRelToMax==1) + (static_cast<MEDCouplingUMesh *>((MEDCouplingMesh *)m))->setMeshDimension(0); + return MEDFileAnyTypeField1TSWithoutSDA::getFieldOnMeshAtLevel(type,renumPol,glob,m,d,e,arrOut,nasc); +} + +/*! + * Returns a new MEDCouplingFieldDouble of a given type lying on the top level cells of a + * given mesh. + * \param [in] type - a spatial discretization of the new field. + * \param [in] mName - a name of the supporting mesh. + * \param [in] renumPol - specifies how to permute values of the result field according to + * the optional numbers of cells and nodes, if any. The valid values are + * - 0 - do not permute. + * - 1 - permute cells. + * - 2 - permute nodes. + * - 3 - permute cells and nodes. + * + * \param [in] glob - the global data storing profiles and localization. + * \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 MED file is not readable. + * \throw If there is no mesh named \a mName in the MED file. + * \throw If there are no mesh entities in the mesh. + * \throw If no field values of the given \a type are available. + */ +MEDCouplingFieldDouble *MEDFileAnyTypeField1TSWithoutSDA::getFieldAtTopLevel(TypeOfField type, const std::string& mName, int renumPol, const MEDFileFieldGlobsReal *glob, MEDCouplingAutoRefCountObjectPtr<DataArray>& arrOut, const MEDFileFieldNameScope& nasc) const +{ + MEDCouplingAutoRefCountObjectPtr<MEDFileMesh> mm; + if(mName.empty()) + mm=MEDFileMesh::New(glob->getFileName(),getMeshName().c_str(),getMeshIteration(),getMeshOrder()); + else + mm=MEDFileMesh::New(glob->getFileName(),mName,getMeshIteration(),getMeshOrder()); + int absDim=getDimension(); + int meshDimRelToMax=absDim-mm->getMeshDimension(); + return MEDFileAnyTypeField1TSWithoutSDA::getFieldOnMeshAtLevel(type,meshDimRelToMax,renumPol,glob,mm,arrOut,nasc); +} + +/*! + * Returns a new MEDCouplingFieldDouble of given type lying on a given support. + * \param [in] type - a spatial discretization of the new field. + * \param [in] renumPol - specifies how to permute values of the result field according to + * the optional numbers of cells and nodes, if any. The valid values are + * - 0 - do not permute. + * - 1 - permute cells. + * - 2 - permute nodes. + * - 3 - permute cells and nodes. + * + * \param [in] glob - the global data storing profiles and localization. + * \param [in] mesh - the supporting mesh. + * \param [in] cellRenum - the cell numbers array used for permutation of the result + * field according to \a renumPol. + * \param [in] nodeRenum - the node numbers array used for permutation of the result + * field according to \a renumPol. + * \return MEDCouplingFieldDouble * - a new instance of MEDCouplingFieldDouble. The + * caller is to delete this field using decrRef() as it is no more needed. + * \throw If there are no mesh entities of \a meshDimRelToMax dimension in the mesh. + * \throw If no field of \a this is lying on \a mesh. + * \throw If no field values of the given \a type or given \a meshDimRelToMax are available. + */ +MEDCouplingFieldDouble *MEDFileAnyTypeField1TSWithoutSDA::getFieldOnMeshAtLevel(TypeOfField type, int renumPol, const MEDFileFieldGlobsReal *glob, const MEDCouplingMesh *mesh, const DataArrayInt *cellRenum, const DataArrayInt *nodeRenum, MEDCouplingAutoRefCountObjectPtr<DataArray>& arrOut, const MEDFileFieldNameScope& nasc) const +{ + static const char msg1[]="MEDFileField1TSWithoutSDA::getFieldOnMeshAtLevel : request for a renumbered field following mesh numbering whereas it is a profile field !"; + int meshId=getMeshIdFromMeshName(mesh->getName()); + bool isPfl=false; + MEDCouplingAutoRefCountObjectPtr<MEDCouplingFieldDouble> ret=_field_per_mesh[meshId]->getFieldOnMeshAtLevel(type,glob,mesh,isPfl,arrOut,nasc); + switch(renumPol) + { + case 0: + { + //no need to test _field_per_mesh.empty() because geMeshName has already done it + return ret.retn(); + } + case 3: + case 1: + { + if(isPfl) + throw INTERP_KERNEL::Exception(msg1); + //no need to test _field_per_mesh.empty() because geMeshName has already done it + if(cellRenum) + { + if((int)cellRenum->getNbOfElems()!=mesh->getNumberOfCells()) + { + std::ostringstream oss; oss << "MEDFileField1TSWithoutSDA::getFieldOnMeshAtLevel : Request of simple renumbering but it seems that underlying mesh \"" << mesh->getName() << "\" of requested field "; + oss << "\"" << getName() << "\" has partial renumbering (some geotype has no renumber) !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + MEDCouplingFieldDiscretization *disc=ret->getDiscretization(); + if(!disc) throw INTERP_KERNEL::Exception("MEDFileAnyTypeField1TSWithoutSDA::getFieldOnMeshAtLevel : internal error, no discretization on field !"); + std::vector<DataArray *> arrOut2(1,arrOut); + // 2 following lines replace ret->renumberCells(cellRenum->getConstPointer()) if not DataArrayDouble + disc->renumberArraysForCell(ret->getMesh(),arrOut2,cellRenum->getConstPointer(),true); + (const_cast<MEDCouplingMesh*>(ret->getMesh()))->renumberCells(cellRenum->getConstPointer(),true); + } + if(renumPol==1) + return ret.retn(); + } + case 2: + { + //no need to test _field_per_mesh.empty() because geMeshName has already done it + if(isPfl) + throw INTERP_KERNEL::Exception(msg1); + if(nodeRenum) + { + if((int)nodeRenum->getNbOfElems()!=mesh->getNumberOfNodes()) + { + std::ostringstream oss; oss << "MEDFileField1TSWithoutSDA::getFieldOnMeshAtLevel : Request of simple renumbering but it seems that underlying mesh \"" << mesh->getName() << "\" of requested field "; + oss << "\"" << nasc.getName() << "\" not defined on all nodes !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> nodeRenumSafe=nodeRenum->checkAndPreparePermutation(); + if(!dynamic_cast<DataArrayDouble *>((DataArray *)arrOut)) + throw INTERP_KERNEL::Exception("MEDFileField1TSWithoutSDA::getFieldOnMeshAtLevel : node renumbering not implemented for not double DataArrays !"); + ret->renumberNodes(nodeRenumSafe->getConstPointer()); + } + return ret.retn(); + } + default: + throw INTERP_KERNEL::Exception("MEDFileField1TSWithoutSDA::getFieldOnMeshAtLevel : unsupported renum policy ! Dealing with policy 0 1 2 and 3 !"); + } +} + +/*! + * Returns values and a profile of the field of a given type lying on a given support. + * \param [in] type - a spatial discretization of the field. + * \param [in] meshDimRelToMax - a relative dimension of the supporting mesh entities. + * \param [in] mesh - the supporting mesh. + * \param [out] pfl - a new instance of DataArrayInt holding ids of mesh entities the + * field of interest lies on. If the field lies on all entities of the given + * dimension, all ids in \a pfl are zero. The caller is to delete this array + * using decrRef() as it is no more needed. + * \param [in] glob - the global data storing profiles and localization. + * \return DataArrayDouble * - a new instance of DataArrayDouble holding values of the + * field. The caller is to delete this array using decrRef() as it is no more needed. + * \throw If there are no mesh entities of \a meshDimRelToMax dimension in \a mesh. + * \throw If no field of \a this is lying on \a mesh. + * \throw If no field values of the given \a type are available. + */ +DataArray *MEDFileAnyTypeField1TSWithoutSDA::getFieldWithProfile(TypeOfField type, int meshDimRelToMax, const MEDFileMesh *mesh, DataArrayInt *&pfl, const MEDFileFieldGlobsReal *glob, const MEDFileFieldNameScope& nasc) const +{ + MEDCouplingAutoRefCountObjectPtr<MEDCouplingMesh> m=mesh->getGenMeshAtLevel(meshDimRelToMax); + int meshId=getMeshIdFromMeshName(mesh->getName().c_str()); + MEDCouplingAutoRefCountObjectPtr<DataArray> ret=_field_per_mesh[meshId]->getFieldOnMeshAtLevelWithPfl(type,m,pfl,glob,nasc); + ret->setName(nasc.getName().c_str()); + return ret.retn(); +} + +//= MEDFileField1TSWithoutSDA + +/*! + * Throws if a given value is not a valid (non-extended) relative dimension. + * \param [in] meshDimRelToMax - the relative dimension value. + * \throw If \a meshDimRelToMax > 0. + */ +void MEDFileField1TSWithoutSDA::CheckMeshDimRel(int meshDimRelToMax) +{ + if(meshDimRelToMax>0) + throw INTERP_KERNEL::Exception("CheckMeshDimRel : This is a meshDimRel not a meshDimRelExt ! So value should be <=0 !"); +} + +/*! + * Checks if elements of a given mesh are in the order suitable for writing + * to the MED file. If this is not so, an exception is thrown. In a case of success, returns a + * vector describing types of elements and their number. + * \param [in] mesh - the mesh to check. + * \return std::vector<int> - a vector holding for each element type (1) item of + * INTERP_KERNEL::NormalizedCellType, (2) number of elements, (3) -1. + * These values are in full-interlace mode. + * \throw If elements in \a mesh are not in the order suitable for writing to the MED file. + */ +std::vector<int> MEDFileField1TSWithoutSDA::CheckSBTMesh(const MEDCouplingMesh *mesh) +{ + if(!mesh) + throw INTERP_KERNEL::Exception("MEDFileField1TSWithoutSDA::CheckSBTMesh : input mesh is NULL !"); + std::set<INTERP_KERNEL::NormalizedCellType> geoTypes=mesh->getAllGeoTypes(); + int nbOfTypes=geoTypes.size(); + std::vector<int> code(3*nbOfTypes); + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> arr1=DataArrayInt::New(); + arr1->alloc(nbOfTypes,1); + int *arrPtr=arr1->getPointer(); + std::set<INTERP_KERNEL::NormalizedCellType>::const_iterator it=geoTypes.begin(); + for(int i=0;i<nbOfTypes;i++,it++) + arrPtr[i]=std::distance(typmai2,std::find(typmai2,typmai2+MED_N_CELL_FIXED_GEO,*it)); + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> arr2=arr1->checkAndPreparePermutation(); + const int *arrPtr2=arr2->getConstPointer(); + int i=0; + for(it=geoTypes.begin();it!=geoTypes.end();it++,i++) + { + int pos=arrPtr2[i]; + int nbCells=mesh->getNumberOfCellsWithType(*it); + code[3*pos]=(int)(*it); + code[3*pos+1]=nbCells; + code[3*pos+2]=-1;//no profiles + } + std::vector<const DataArrayInt *> idsPerType;//no profiles + DataArrayInt *da=mesh->checkTypeConsistencyAndContig(code,idsPerType); + if(da) + { + da->decrRef(); + throw INTERP_KERNEL::Exception("MEDFileField1TSWithoutSDA::CheckSBTMesh : underlying mesh is not sorted by type as MED file expects !"); + } + return code; +} + +MEDFileField1TSWithoutSDA *MEDFileField1TSWithoutSDA::New(const std::string& fieldName, int csit, int iteration, int order, const std::vector<std::string>& infos) +{ + return new MEDFileField1TSWithoutSDA(fieldName,csit,iteration,order,infos); +} + +/*! + * Returns all attributes and values of parts of \a this field lying on a given mesh. + * Each part differs from other ones by a type of supporting mesh entity. The _i_-th + * item of every of returned sequences refers to the _i_-th part of \a this field. + * Thus all sequences returned by this method are of the same length equal to number + * of different types of supporting entities.<br> + * A field part can include sub-parts with several different spatial discretizations, + * \ref ParaMEDMEM::ON_CELLS "ON_CELLS" and \ref ParaMEDMEM::ON_GAUSS_PT "ON_GAUSS_PT" + * for example. Hence, some of the returned sequences contains nested sequences, and an item + * of a nested sequence corresponds to a type of spatial discretization.<br> + * This method allows for iteration over MEDFile DataStructure with a reduced overhead. + * The overhead is due to selecting values into new instances of DataArrayDouble. + * \param [in] mname - a name of a mesh of interest. It can be \c NULL, which is valid + * for the case with only one underlying mesh. (Actually, the number of meshes is + * not checked if \a mname == \c NULL). + * \param [in,out] types - a sequence of types of underlying mesh entities. A type per + * a field part is returned. + * \param [in,out] typesF - a sequence of sequences of types of spatial discretizations. + * A field part can include sub-parts with several different spatial discretizations, + * \ref ParaMEDMEM::ON_CELLS "ON_CELLS" and + * \ref ParaMEDMEM::ON_GAUSS_PT "ON_GAUSS_PT" for example. + * This sequence is of the same length as \a types. + * \param [in,out] pfls - a sequence returning a profile name per each type of spatial + * discretization. A profile name can be empty. + * Length of this and of nested sequences is the same as that of \a typesF. + * \param [in,out] locs - a sequence returning a localization name per each type of spatial + * discretization. A localization name can be empty. + * Length of this and of nested sequences is the same as that of \a typesF. + * \return std::vector< std::vector<DataArrayDouble *> > - a sequence holding arrays of values + * per each type of spatial discretization within one mesh entity type. + * The caller is to delete each DataArrayDouble using decrRef() as it is no more needed. + * Length of this and of nested sequences is the same as that of \a typesF. + * \throw If no field is lying on \a mname. + */ +std::vector< std::vector<DataArrayDouble *> > MEDFileField1TSWithoutSDA::getFieldSplitedByType2(const std::string& mname, std::vector<INTERP_KERNEL::NormalizedCellType>& types, std::vector< std::vector<TypeOfField> >& typesF, std::vector< std::vector<std::string> >& pfls, std::vector< std::vector<std::string> >& locs) const +{ + int meshId=0; + if(!mname.empty()) + meshId=getMeshIdFromMeshName(mname); + else + if(_field_per_mesh.empty()) + throw INTERP_KERNEL::Exception("MEDFileField1TSWithoutSDA::getFieldSplitedByType : This is empty !"); + std::vector< std::vector< std::pair<int,int> > > ret0=_field_per_mesh[meshId]->getFieldSplitedByType(types,typesF,pfls,locs); + int nbOfRet=ret0.size(); + std::vector< std::vector<DataArrayDouble *> > ret(nbOfRet); + for(int i=0;i<nbOfRet;i++) + { + const std::vector< std::pair<int,int> >& p=ret0[i]; + int nbOfRet1=p.size(); + ret[i].resize(nbOfRet1); + for(int j=0;j<nbOfRet1;j++) + { + DataArrayDouble *tmp=_arr->selectByTupleId2(p[j].first,p[j].second,1); + ret[i][j]=tmp; + } + } + return ret; +} + +/*! + * Returns a pointer to the underground DataArrayDouble instance. So the + * caller should not decrRef() it. This method allows for a direct access to the field + * values. This method is quite unusable if there is more than a nodal field or a cell + * field on single geometric cell type. + * \return DataArrayDouble * - the pointer to the field values array. + */ +DataArrayDouble *MEDFileField1TSWithoutSDA::getUndergroundDataArrayDouble() const +{ + const DataArrayDouble *ret=_arr; + if(ret) + return const_cast<DataArrayDouble *>(ret); + else + return 0; +} + +const char *MEDFileField1TSWithoutSDA::getTypeStr() const +{ + return TYPE_STR; +} + +MEDFileIntField1TSWithoutSDA *MEDFileField1TSWithoutSDA::convertToInt() const +{ + MEDCouplingAutoRefCountObjectPtr<MEDFileIntField1TSWithoutSDA> ret(new MEDFileIntField1TSWithoutSDA); + ret->MEDFileAnyTypeField1TSWithoutSDA::operator =(*this); + ret->deepCpyLeavesFrom(*this); + const DataArrayDouble *arr(_arr); + if(arr) + { + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> arr2(arr->convertToIntArr()); + ret->setArray(arr2); + } + return ret.retn(); +} + +/*! + * Returns a pointer to the underground DataArrayDouble instance. So the + * caller should not decrRef() it. This method allows for a direct access to the field + * values. This method is quite unusable if there is more than a nodal field or a cell + * field on single geometric cell type. + * \return DataArrayDouble * - the pointer to the field values array. + */ +DataArray *MEDFileField1TSWithoutSDA::getUndergroundDataArray() const +{ + return getUndergroundDataArrayDouble(); +} + +/*! + * Returns a pointer to the underground DataArrayDouble instance and a + * sequence describing parameters of a support of each part of \a this field. The + * caller should not decrRef() the returned DataArrayDouble. This method allows for a + * direct access to the field values. This method is intended for the field lying on one + * mesh only. + * \param [in,out] entries - the sequence describing parameters of a support of each + * part of \a this field. Each item of this sequence consists of two parts. The + * first part describes a type of mesh entity and an id of discretization of a + * current field part. The second part describes a range of values [begin,end) + * within the returned array relating to the current field part. + * \return DataArrayDouble * - the pointer to the field values array. + * \throw If the number of underlying meshes is not equal to 1. + * \throw If no field values are available. + * \sa getUndergroundDataArray() + */ +DataArrayDouble *MEDFileField1TSWithoutSDA::getUndergroundDataArrayDoubleExt(std::vector< std::pair<std::pair<INTERP_KERNEL::NormalizedCellType,int>,std::pair<int,int> > >& entries) const +{ + if(_field_per_mesh.size()!=1) + throw INTERP_KERNEL::Exception("MEDFileField1TSWithoutSDA::getUndergroundDataArrayExt : field lies on several meshes, this method has no sense !"); + if(_field_per_mesh[0]==0) + throw INTERP_KERNEL::Exception("MEDFileField1TSWithoutSDA::getUndergroundDataArrayExt : no field specified !"); + _field_per_mesh[0]->getUndergroundDataArrayExt(entries); + return getUndergroundDataArrayDouble(); +} + +/*! + * Returns a pointer to the underground DataArrayDouble instance and a + * sequence describing parameters of a support of each part of \a this field. The + * caller should not decrRef() the returned DataArrayDouble. This method allows for a + * direct access to the field values. This method is intended for the field lying on one + * mesh only. + * \param [in,out] entries - the sequence describing parameters of a support of each + * part of \a this field. Each item of this sequence consists of two parts. The + * first part describes a type of mesh entity and an id of discretization of a + * current field part. The second part describes a range of values [begin,end) + * within the returned array relating to the current field part. + * \return DataArrayDouble * - the pointer to the field values array. + * \throw If the number of underlying meshes is not equal to 1. + * \throw If no field values are available. + * \sa getUndergroundDataArray() + */ +DataArray *MEDFileField1TSWithoutSDA::getUndergroundDataArrayExt(std::vector< std::pair<std::pair<INTERP_KERNEL::NormalizedCellType,int>,std::pair<int,int> > >& entries) const +{ + return getUndergroundDataArrayDoubleExt(entries); +} + +MEDFileField1TSWithoutSDA::MEDFileField1TSWithoutSDA(const std::string& fieldName, int csit, int iteration, int order, const std::vector<std::string>& infos):MEDFileAnyTypeField1TSWithoutSDA(fieldName,csit,iteration,order) +{ + DataArrayDouble *arr(getOrCreateAndGetArrayDouble()); + arr->setInfoAndChangeNbOfCompo(infos); +} + +MEDFileField1TSWithoutSDA::MEDFileField1TSWithoutSDA():MEDFileAnyTypeField1TSWithoutSDA() +{ +} + +MEDFileAnyTypeField1TSWithoutSDA *MEDFileField1TSWithoutSDA::shallowCpy() const +{ + MEDCouplingAutoRefCountObjectPtr<MEDFileField1TSWithoutSDA> ret(new MEDFileField1TSWithoutSDA(*this)); + ret->deepCpyLeavesFrom(*this); + return ret.retn(); +} + +MEDFileAnyTypeField1TSWithoutSDA *MEDFileField1TSWithoutSDA::deepCpy() const +{ + MEDCouplingAutoRefCountObjectPtr<MEDFileField1TSWithoutSDA> ret=static_cast<MEDFileField1TSWithoutSDA *>(shallowCpy()); + if((const DataArrayDouble *)_arr) + ret->_arr=_arr->deepCpy(); + return ret.retn(); +} + +void MEDFileField1TSWithoutSDA::setArray(DataArray *arr) +{ + if(!arr) + { + _nb_of_tuples_to_be_allocated=-1; + _arr=0; + return ; + } + DataArrayDouble *arrC=dynamic_cast<DataArrayDouble *>(arr); + if(!arrC) + throw INTERP_KERNEL::Exception("MEDFileField1TSWithoutSDA::setArray : the input not null array is not of type DataArrayDouble !"); + else + _nb_of_tuples_to_be_allocated=-3; + arrC->incrRef(); + _arr=arrC; +} + +DataArray *MEDFileField1TSWithoutSDA::createNewEmptyDataArrayInstance() const +{ + return DataArrayDouble::New(); +} + +DataArrayDouble *MEDFileField1TSWithoutSDA::getOrCreateAndGetArrayDouble() +{ + DataArrayDouble *ret=_arr; + if(ret) + return ret; + _arr=DataArrayDouble::New(); + return _arr; +} + +DataArray *MEDFileField1TSWithoutSDA::getOrCreateAndGetArray() +{ + return getOrCreateAndGetArrayDouble(); +} + +const DataArrayDouble *MEDFileField1TSWithoutSDA::getOrCreateAndGetArrayDouble() const +{ + const DataArrayDouble *ret=_arr; + if(ret) + return ret; + DataArrayDouble *ret2=DataArrayDouble::New(); + const_cast<MEDFileField1TSWithoutSDA *>(this)->_arr=DataArrayDouble::New(); + return ret2; +} + +const DataArray *MEDFileField1TSWithoutSDA::getOrCreateAndGetArray() const +{ + return getOrCreateAndGetArrayDouble(); +} + +//= MEDFileIntField1TSWithoutSDA + +MEDFileIntField1TSWithoutSDA *MEDFileIntField1TSWithoutSDA::New(const std::string& fieldName, int csit, int iteration, int order, const std::vector<std::string>& infos) +{ + return new MEDFileIntField1TSWithoutSDA(fieldName,csit,iteration,order,infos); +} + +MEDFileIntField1TSWithoutSDA::MEDFileIntField1TSWithoutSDA():MEDFileAnyTypeField1TSWithoutSDA() +{ +} + +MEDFileIntField1TSWithoutSDA::MEDFileIntField1TSWithoutSDA(const std::string& fieldName, int csit, int iteration, int order, + const std::vector<std::string>& infos):MEDFileAnyTypeField1TSWithoutSDA(fieldName,csit,iteration,order) +{ + DataArrayInt *arr(getOrCreateAndGetArrayInt()); + arr->setInfoAndChangeNbOfCompo(infos); +} + +const char *MEDFileIntField1TSWithoutSDA::getTypeStr() const +{ + return TYPE_STR; +} + +MEDFileField1TSWithoutSDA *MEDFileIntField1TSWithoutSDA::convertToDouble() const +{ + MEDCouplingAutoRefCountObjectPtr<MEDFileField1TSWithoutSDA> ret(new MEDFileField1TSWithoutSDA); + ret->MEDFileAnyTypeField1TSWithoutSDA::operator =(*this); + ret->deepCpyLeavesFrom(*this); + const DataArrayInt *arr(_arr); + if(arr) + { + MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> arr2(arr->convertToDblArr()); + ret->setArray(arr2); + } + return ret.retn(); +} + +/*! + * Returns a pointer to the underground DataArrayInt instance. So the + * caller should not decrRef() it. This method allows for a direct access to the field + * values. This method is quite unusable if there is more than a nodal field or a cell + * field on single geometric cell type. + * \return DataArrayInt * - the pointer to the field values array. + */ +DataArray *MEDFileIntField1TSWithoutSDA::getUndergroundDataArray() const +{ + return getUndergroundDataArrayInt(); +} + +/*! + * Returns a pointer to the underground DataArrayInt instance. So the + * caller should not decrRef() it. This method allows for a direct access to the field + * values. This method is quite unusable if there is more than a nodal field or a cell + * field on single geometric cell type. + * \return DataArrayInt * - the pointer to the field values array. + */ +DataArrayInt *MEDFileIntField1TSWithoutSDA::getUndergroundDataArrayInt() const +{ + const DataArrayInt *ret=_arr; + if(ret) + return const_cast<DataArrayInt *>(ret); + else + return 0; +} + +/*! + * Returns a pointer to the underground DataArrayInt instance and a + * sequence describing parameters of a support of each part of \a this field. The + * caller should not decrRef() the returned DataArrayInt. This method allows for a + * direct access to the field values. This method is intended for the field lying on one + * mesh only. + * \param [in,out] entries - the sequence describing parameters of a support of each + * part of \a this field. Each item of this sequence consists of two parts. The + * first part describes a type of mesh entity and an id of discretization of a + * current field part. The second part describes a range of values [begin,end) + * within the returned array relating to the current field part. + * \return DataArrayInt * - the pointer to the field values array. + * \throw If the number of underlying meshes is not equal to 1. + * \throw If no field values are available. + * \sa getUndergroundDataArray() + */ +DataArray *MEDFileIntField1TSWithoutSDA::getUndergroundDataArrayExt(std::vector< std::pair<std::pair<INTERP_KERNEL::NormalizedCellType,int>,std::pair<int,int> > >& entries) const +{ + return getUndergroundDataArrayIntExt(entries); +} + +/*! + * Returns a pointer to the underground DataArrayInt instance and a + * sequence describing parameters of a support of each part of \a this field. The + * caller should not decrRef() the returned DataArrayInt. This method allows for a + * direct access to the field values. This method is intended for the field lying on one + * mesh only. + * \param [in,out] entries - the sequence describing parameters of a support of each + * part of \a this field. Each item of this sequence consists of two parts. The + * first part describes a type of mesh entity and an id of discretization of a + * current field part. The second part describes a range of values [begin,end) + * within the returned array relating to the current field part. + * \return DataArrayInt * - the pointer to the field values array. + * \throw If the number of underlying meshes is not equal to 1. + * \throw If no field values are available. + * \sa getUndergroundDataArray() + */ +DataArrayInt *MEDFileIntField1TSWithoutSDA::getUndergroundDataArrayIntExt(std::vector< std::pair<std::pair<INTERP_KERNEL::NormalizedCellType,int>,std::pair<int,int> > >& entries) const +{ + if(_field_per_mesh.size()!=1) + throw INTERP_KERNEL::Exception("MEDFileField1TSWithoutSDA::getUndergroundDataArrayExt : field lies on several meshes, this method has no sense !"); + if(_field_per_mesh[0]==0) + throw INTERP_KERNEL::Exception("MEDFileField1TSWithoutSDA::getUndergroundDataArrayExt : no field specified !"); + _field_per_mesh[0]->getUndergroundDataArrayExt(entries); + return getUndergroundDataArrayInt(); +} + +MEDFileAnyTypeField1TSWithoutSDA *MEDFileIntField1TSWithoutSDA::shallowCpy() const +{ + MEDCouplingAutoRefCountObjectPtr<MEDFileIntField1TSWithoutSDA> ret(new MEDFileIntField1TSWithoutSDA(*this)); + ret->deepCpyLeavesFrom(*this); + return ret.retn(); +} + +MEDFileAnyTypeField1TSWithoutSDA *MEDFileIntField1TSWithoutSDA::deepCpy() const +{ + MEDCouplingAutoRefCountObjectPtr<MEDFileIntField1TSWithoutSDA> ret=static_cast<MEDFileIntField1TSWithoutSDA *>(shallowCpy()); + if((const DataArrayInt *)_arr) + ret->_arr=_arr->deepCpy(); + return ret.retn(); +} + +void MEDFileIntField1TSWithoutSDA::setArray(DataArray *arr) +{ + if(!arr) + { + _nb_of_tuples_to_be_allocated=-1; + _arr=0; + return ; + } + DataArrayInt *arrC=dynamic_cast<DataArrayInt *>(arr); + if(!arrC) + throw INTERP_KERNEL::Exception("MEDFileIntField1TSWithoutSDA::setArray : the input not null array is not of type DataArrayInt !"); + else + _nb_of_tuples_to_be_allocated=-3; + arrC->incrRef(); + _arr=arrC; +} + +DataArray *MEDFileIntField1TSWithoutSDA::createNewEmptyDataArrayInstance() const +{ + return DataArrayInt::New(); +} + +DataArrayInt *MEDFileIntField1TSWithoutSDA::getOrCreateAndGetArrayInt() +{ + DataArrayInt *ret=_arr; + if(ret) + return ret; + _arr=DataArrayInt::New(); + return _arr; +} + +DataArray *MEDFileIntField1TSWithoutSDA::getOrCreateAndGetArray() +{ + return getOrCreateAndGetArrayInt(); +} + +const DataArrayInt *MEDFileIntField1TSWithoutSDA::getOrCreateAndGetArrayInt() const +{ + const DataArrayInt *ret=_arr; + if(ret) + return ret; + DataArrayInt *ret2=DataArrayInt::New(); + const_cast<MEDFileIntField1TSWithoutSDA *>(this)->_arr=DataArrayInt::New(); + return ret2; +} + +const DataArray *MEDFileIntField1TSWithoutSDA::getOrCreateAndGetArray() const +{ + return getOrCreateAndGetArrayInt(); +} + +MEDFileAnyTypeField1TS::MEDFileAnyTypeField1TS() +{ +} + +//= MEDFileAnyTypeField1TS + +MEDFileAnyTypeField1TSWithoutSDA *MEDFileAnyTypeField1TS::BuildContentFrom(med_idt fid, const std::string& fileName, bool loadAll, const MEDFileMeshes *ms) +{ + med_field_type typcha; + // + std::vector<std::string> infos; + std::string dtunit,fieldName; + LocateField2(fid,fileName,0,true,fieldName,typcha,infos,dtunit); + MEDCouplingAutoRefCountObjectPtr<MEDFileAnyTypeField1TSWithoutSDA> ret; + switch(typcha) + { + case MED_FLOAT64: + { + ret=MEDFileField1TSWithoutSDA::New(fieldName.c_str(),-1,-1/*iteration*/,-1/*order*/,std::vector<std::string>()); + break; + } + case MED_INT32: + { + ret=MEDFileIntField1TSWithoutSDA::New(fieldName.c_str(),-1,-1/*iteration*/,-1/*order*/,std::vector<std::string>()); + break; + } + default: + { + std::ostringstream oss; oss << "MEDFileAnyTypeField1TS::BuildContentFrom(fileName) : file \'" << fileName << "\' contains field with name \'" << fieldName << "\' but the type of the first field is not in [MED_FLOAT64, MED_INT32] !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + } + ret->setDtUnit(dtunit.c_str()); + ret->getOrCreateAndGetArray()->setInfoAndChangeNbOfCompo(infos); + // + med_int numdt,numit; + med_float dt; + MEDFILESAFECALLERRD0(MEDfieldComputingStepInfo,(fid,fieldName.c_str(),1,&numdt,&numit,&dt)); + ret->setTime(numdt,numit,dt); + ret->_csit=1; + if(loadAll) + ret->loadStructureAndBigArraysRecursively(fid,*((const MEDFileAnyTypeField1TSWithoutSDA*)ret),ms,0); + else + ret->loadOnlyStructureOfDataRecursively(fid,*((const MEDFileAnyTypeField1TSWithoutSDA*)ret),ms,0); + return ret.retn(); +} + +MEDFileAnyTypeField1TS::MEDFileAnyTypeField1TS(const std::string& fileName, bool loadAll, const MEDFileMeshes *ms) +try:MEDFileFieldGlobsReal(fileName) +{ + MEDFileUtilities::CheckFileForRead(fileName); + MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName.c_str(),MED_ACC_RDONLY); + _content=BuildContentFrom(fid,fileName,loadAll,ms); + loadGlobals(fid); +} +catch(INTERP_KERNEL::Exception& e) +{ + throw e; +} + +MEDFileAnyTypeField1TSWithoutSDA *MEDFileAnyTypeField1TS::BuildContentFrom(med_idt fid, const std::string& fileName, const std::string& fieldName, bool loadAll, const MEDFileMeshes *ms) +{ + med_field_type typcha; + std::vector<std::string> infos; + std::string dtunit; + int iii=-1; + int nbSteps=LocateField(fid,fileName,fieldName,iii,typcha,infos,dtunit); + MEDCouplingAutoRefCountObjectPtr<MEDFileAnyTypeField1TSWithoutSDA> ret; + switch(typcha) + { + case MED_FLOAT64: + { + ret=MEDFileField1TSWithoutSDA::New(fieldName,-1,-1/*iteration*/,-1/*order*/,std::vector<std::string>()); + break; + } + case MED_INT32: + { + ret=MEDFileIntField1TSWithoutSDA::New(fieldName,-1,-1/*iteration*/,-1/*order*/,std::vector<std::string>()); + break; + } + default: + { + std::ostringstream oss; oss << "MEDFileAnyTypeField1TS::BuildContentFrom(fileName,fieldName) : file \'" << fileName << "\' contains field with name \'" << fieldName << "\' but the type of field is not in [MED_FLOAT64, MED_INT32] !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + } + ret->setDtUnit(dtunit.c_str()); + ret->getOrCreateAndGetArray()->setInfoAndChangeNbOfCompo(infos); + // + if(nbSteps<1) + { + std::ostringstream oss; oss << "MEDFileField1TS(fileName,fieldName) : file \'" << fileName << "\' contains field with name \'" << fieldName << "\' but there is no time steps on it !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + // + med_int numdt,numit; + med_float dt; + MEDFILESAFECALLERRD0(MEDfieldComputingStepInfo,(fid,fieldName.c_str(),1,&numdt,&numit,&dt)); + ret->setTime(numdt,numit,dt); + ret->_csit=1; + if(loadAll) + ret->loadStructureAndBigArraysRecursively(fid,*((const MEDFileAnyTypeField1TSWithoutSDA*)ret),ms,0); + else + ret->loadOnlyStructureOfDataRecursively(fid,*((const MEDFileAnyTypeField1TSWithoutSDA*)ret),ms,0); + return ret.retn(); +} + +MEDFileAnyTypeField1TS::MEDFileAnyTypeField1TS(const std::string& fileName, const std::string& fieldName, bool loadAll, const MEDFileMeshes *ms) +try:MEDFileFieldGlobsReal(fileName) +{ + MEDFileUtilities::CheckFileForRead(fileName); + MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName.c_str(),MED_ACC_RDONLY); + _content=BuildContentFrom(fid,fileName,fieldName,loadAll,ms); + loadGlobals(fid); +} +catch(INTERP_KERNEL::Exception& e) +{ + throw e; +} + +MEDFileAnyTypeField1TS *MEDFileAnyTypeField1TS::BuildNewInstanceFromContent(MEDFileAnyTypeField1TSWithoutSDA *c, const std::string& fileName) +{ + if(!c) + throw INTERP_KERNEL::Exception("MEDFileAnyTypeField1TS::BuildNewInstanceFromContent : empty content in input : unable to build a new instance !"); + if(dynamic_cast<const MEDFileField1TSWithoutSDA *>(c)) + { + MEDCouplingAutoRefCountObjectPtr<MEDFileField1TS> ret=MEDFileField1TS::New(); + ret->setFileName(fileName); + ret->_content=c; c->incrRef(); + return ret.retn(); + } + if(dynamic_cast<const MEDFileIntField1TSWithoutSDA *>(c)) + { + MEDCouplingAutoRefCountObjectPtr<MEDFileIntField1TS> ret=MEDFileIntField1TS::New(); + ret->setFileName(fileName); + ret->_content=c; c->incrRef(); + return ret.retn(); + } + throw INTERP_KERNEL::Exception("MEDFileAnyTypeField1TS::BuildNewInstanceFromContent : internal error ! a content of type different from FLOAT64 and INT32 has been built but not intercepted !"); +} + +MEDFileAnyTypeField1TS *MEDFileAnyTypeField1TS::New(const std::string& fileName, bool loadAll) +{ + MEDFileUtilities::CheckFileForRead(fileName); + MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName.c_str(),MED_ACC_RDONLY); + MEDCouplingAutoRefCountObjectPtr<MEDFileAnyTypeField1TSWithoutSDA> c=BuildContentFrom(fid,fileName,loadAll,0); + MEDCouplingAutoRefCountObjectPtr<MEDFileAnyTypeField1TS> ret=BuildNewInstanceFromContent(c,fileName); + ret->loadGlobals(fid); + return ret.retn(); +} + +MEDFileAnyTypeField1TS *MEDFileAnyTypeField1TS::New(const std::string& fileName, const std::string& fieldName, bool loadAll) +{ + MEDFileUtilities::CheckFileForRead(fileName); + MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName.c_str(),MED_ACC_RDONLY); + MEDCouplingAutoRefCountObjectPtr<MEDFileAnyTypeField1TSWithoutSDA> c=BuildContentFrom(fid,fileName,fieldName,loadAll,0); + MEDCouplingAutoRefCountObjectPtr<MEDFileAnyTypeField1TS> ret=BuildNewInstanceFromContent(c,fileName); + ret->loadGlobals(fid); + return ret.retn(); +} + +MEDFileAnyTypeField1TS *MEDFileAnyTypeField1TS::New(const std::string& fileName, const std::string& fieldName, int iteration, int order, bool loadAll) +{ + MEDFileUtilities::CheckFileForRead(fileName); + MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName.c_str(),MED_ACC_RDONLY); + MEDCouplingAutoRefCountObjectPtr<MEDFileAnyTypeField1TSWithoutSDA> c=BuildContentFrom(fid,fileName,fieldName,iteration,order,loadAll,0); + MEDCouplingAutoRefCountObjectPtr<MEDFileAnyTypeField1TS> ret=BuildNewInstanceFromContent(c,fileName); + ret->loadGlobals(fid); + return ret.retn(); +} + +MEDFileAnyTypeField1TSWithoutSDA *MEDFileAnyTypeField1TS::BuildContentFrom(med_idt fid, const std::string& fileName, const std::string& fieldName, int iteration, int order, bool loadAll, const MEDFileMeshes *ms) +{ + med_field_type typcha; + std::vector<std::string> infos; + std::string dtunit; + int iii=-1; + int nbOfStep2=LocateField(fid,fileName,fieldName,iii,typcha,infos,dtunit); + MEDCouplingAutoRefCountObjectPtr<MEDFileAnyTypeField1TSWithoutSDA> ret; + switch(typcha) + { + case MED_FLOAT64: + { + ret=MEDFileField1TSWithoutSDA::New(fieldName,-1,iteration,order,std::vector<std::string>()); + break; + } + case MED_INT32: + { + ret=MEDFileIntField1TSWithoutSDA::New(fieldName,-1,iteration,order,std::vector<std::string>()); + break; + } + default: + { + std::ostringstream oss; oss << "MEDFileAnyTypeField1TS::BuildContentFrom(fileName,fieldName,iteration,order) : file \'" << fileName << "\' contains field with name \'" << fieldName << "\' but the type of field is not in [MED_FLOAT64, MED_INT32] !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + } + ret->setDtUnit(dtunit.c_str()); + ret->getOrCreateAndGetArray()->setInfoAndChangeNbOfCompo(infos); + // + bool found=false; + std::vector< std::pair<int,int> > dtits(nbOfStep2); + for(int i=0;i<nbOfStep2 && !found;i++) + { + med_int numdt,numit; + med_float dt; + MEDFILESAFECALLERRD0(MEDfieldComputingStepInfo,(fid,fieldName.c_str(),i+1,&numdt,&numit,&dt)); + if(numdt==iteration && numit==order) + { + found=true; + ret->_csit=i+1; + } + else + dtits[i]=std::pair<int,int>(numdt,numit); + } + if(!found) + { + std::ostringstream oss; oss << "No such iteration (" << iteration << "," << order << ") in existing field '" << fieldName << "' in file '" << fileName << "' ! Available iterations are : "; + for(std::vector< std::pair<int,int> >::const_iterator iter=dtits.begin();iter!=dtits.end();iter++) + oss << "(" << (*iter).first << "," << (*iter).second << "), "; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + if(loadAll) + ret->loadStructureAndBigArraysRecursively(fid,*((const MEDFileAnyTypeField1TSWithoutSDA*)ret),ms,0); + else + ret->loadOnlyStructureOfDataRecursively(fid,*((const MEDFileAnyTypeField1TSWithoutSDA*)ret),ms,0); + return ret.retn(); +} + +MEDFileAnyTypeField1TS::MEDFileAnyTypeField1TS(const std::string& fileName, const std::string& fieldName, int iteration, int order, bool loadAll, const MEDFileMeshes *ms) +try:MEDFileFieldGlobsReal(fileName) +{ + MEDFileUtilities::CheckFileForRead(fileName); + MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName.c_str(),MED_ACC_RDONLY); + _content=BuildContentFrom(fid,fileName.c_str(),fieldName.c_str(),iteration,order,loadAll,ms); + loadGlobals(fid); +} +catch(INTERP_KERNEL::Exception& e) +{ + throw e; +} + +/*! + * This constructor is a shallow copy constructor. If \a shallowCopyOfContent is true the content of \a other is shallow copied. + * If \a shallowCopyOfContent is false, \a other is taken to be the content of \a this. + * + * \warning this is a shallow copy constructor + */ +MEDFileAnyTypeField1TS::MEDFileAnyTypeField1TS(const MEDFileAnyTypeField1TSWithoutSDA& other, bool shallowCopyOfContent) +{ + if(!shallowCopyOfContent) + { + const MEDFileAnyTypeField1TSWithoutSDA *otherPtr(&other); + otherPtr->incrRef(); + _content=const_cast<MEDFileAnyTypeField1TSWithoutSDA *>(otherPtr); + } + else + { + _content=other.shallowCpy(); + } +} + +int MEDFileAnyTypeField1TS::LocateField2(med_idt fid, const std::string& fileName, int fieldIdCFormat, bool checkFieldId, std::string& fieldName, med_field_type& typcha, std::vector<std::string>& infos, std::string& dtunitOut) +{ + if(checkFieldId) + { + int nbFields=MEDnField(fid); + if(fieldIdCFormat>=nbFields) + { + std::ostringstream oss; oss << "MEDFileAnyTypeField1TS::LocateField2(fileName) : in file \'" << fileName << "\' number of fields is " << nbFields << " ! Trying to request for id " << fieldIdCFormat << " !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + } + int ncomp(MEDfieldnComponent(fid,fieldIdCFormat+1)); + INTERP_KERNEL::AutoPtr<char> comp=MEDLoaderBase::buildEmptyString(ncomp*MED_SNAME_SIZE); + INTERP_KERNEL::AutoPtr<char> unit=MEDLoaderBase::buildEmptyString(ncomp*MED_SNAME_SIZE); + INTERP_KERNEL::AutoPtr<char> dtunit=MEDLoaderBase::buildEmptyString(MED_LNAME_SIZE); + INTERP_KERNEL::AutoPtr<char> nomcha=MEDLoaderBase::buildEmptyString(MED_NAME_SIZE); + INTERP_KERNEL::AutoPtr<char> nomMaa=MEDLoaderBase::buildEmptyString(MED_NAME_SIZE); + med_bool localMesh; + int nbOfStep; + MEDFILESAFECALLERRD0(MEDfieldInfo,(fid,fieldIdCFormat+1,nomcha,nomMaa,&localMesh,&typcha,comp,unit,dtunit,&nbOfStep)); + fieldName=MEDLoaderBase::buildStringFromFortran(nomcha,MED_NAME_SIZE); + dtunitOut=MEDLoaderBase::buildStringFromFortran(dtunit,MED_LNAME_SIZE); + infos.clear(); infos.resize(ncomp); + for(int j=0;j<ncomp;j++) + infos[j]=MEDLoaderBase::buildUnionUnit((char *)comp+j*MED_SNAME_SIZE,MED_SNAME_SIZE,(char *)unit+j*MED_SNAME_SIZE,MED_SNAME_SIZE); + return nbOfStep; +} + +/*! + * This method throws an INTERP_KERNEL::Exception if \a fieldName field is not in file pointed by \a fid and with name \a fileName. + * + * \param [out] + * \return in case of success the number of time steps available for the field with name \a fieldName. + */ +int MEDFileAnyTypeField1TS::LocateField(med_idt fid, const std::string& fileName, const std::string& fieldName, int& posCFormat, med_field_type& typcha, std::vector<std::string>& infos, std::string& dtunitOut) +{ + int nbFields=MEDnField(fid); + bool found=false; + std::vector<std::string> fns(nbFields); + int nbOfStep2=-1; + for(int i=0;i<nbFields && !found;i++) + { + std::string tmp; + nbOfStep2=LocateField2(fid,fileName,i,false,tmp,typcha,infos,dtunitOut); + fns[i]=tmp; + found=(tmp==fieldName); + if(found) + posCFormat=i; + } + if(!found) + { + std::ostringstream oss; oss << "No such field '" << fieldName << "' in file '" << fileName << "' ! Available fields are : "; + for(std::vector<std::string>::const_iterator it=fns.begin();it!=fns.end();it++) + oss << "\"" << *it << "\" "; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + return nbOfStep2; +} + +/*! + * This method as MEDFileField1TSW::setLocNameOnLeaf, is dedicated for advanced user that a want a very fine control on their data structure + * without overhead. This method can be called only regarding information returned by MEDFileField1TSWithoutSDA::getFieldSplitedByType or MEDFileField1TSWithoutSDA::getFieldSplitedByType2. + * This method changes the attribute (here it's profile name) of the leaf datastructure (MEDFileFieldPerMeshPerTypePerDisc instance). + * It is the responsability of the caller to invoke MEDFileFieldGlobs::appendProfile or MEDFileFieldGlobs::getProfile + * to keep a valid instance. + * If \b this do not have any leaf that correspond to the request of the input parameter (\b mName, \b typ, \b locId) an INTERP_KERNEL::Exception will be thrown. + * If \b newPflName profile name does not already exist the profile with old name will be renamed with name \b newPflName. + * If \b newPflName already exists and that \b forceRenameOnGlob is false (the default) an INTERP_KERNEL::Exception will be thrown to avoid big confusion. In this case the called should rename before the profile name with name \b newPflName. + * + * \param [in] mName specifies the underlying mesh name. This value can be pointer 0 for users that do not deal with fields on multi mesh. + * \param [in] typ is for the geometric cell type (or INTERP_KERNEL::NORM_ERROR for node field) entry to find the right MEDFileFieldPerMeshPerTypePerDisc instance to set. + * \param [in] locId is the localization id to find the right MEDFileFieldPerMeshPerTypePerDisc instance to set. It corresponds to the position of + * \c pfls[std::distance(types.begin(),std::find(types.begin(),typ)] vector in MEDFileField1TSWithoutSDA::getFieldSplitedByType. For non gausspoints field users, the value is 0. + * \param [in] newLocName is the new localization name. + * \param [in] forceRenameOnGlob specifies the behaviour in case of profile \b newPflName already exists. If true, the renaming is done without check. It can lead to major bug. + * If false, an exception will be thrown to force user to change previously the name of the profile with name \b newPflName + */ +void MEDFileAnyTypeField1TS::setProfileNameOnLeaf(const std::string& mName, INTERP_KERNEL::NormalizedCellType typ, int locId, const std::string& newPflName, bool forceRenameOnGlob) +{ + MEDFileFieldPerMeshPerTypePerDisc *disc=getLeafGivenMeshAndTypeAndLocId(mName,typ,locId); + std::string oldPflName=disc->getProfile(); + std::vector<std::string> vv=getPflsReallyUsedMulti(); + int nbOfOcc=std::count(vv.begin(),vv.end(),oldPflName); + if(forceRenameOnGlob || (!existsPfl(newPflName) && nbOfOcc==1)) + { + disc->setProfile(newPflName); + DataArrayInt *pfl=getProfile(oldPflName.c_str()); + pfl->setName(newPflName); + } + else + { + std::ostringstream oss; oss << "MEDFileField1TS::setProfileNameOnLeaf : Profile \"" << newPflName << "\" already exists or referenced more than one !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } +} + +/*! + * This method as MEDFileField1TSW::setProfileNameOnLeaf, is dedicated for advanced user that a want a very fine control on their data structure + * without overhead. This method can be called only regarding information returned by MEDFileField1TSWithoutSDA::getFieldSplitedByType or MEDFileField1TSWithoutSDA::getFieldSplitedByType2. + * This method changes the attribute (here it's localization name) of the leaf datastructure (MEDFileFieldPerMeshPerTypePerDisc instance). + * It is the responsability of the caller to invoke MEDFileFieldGlobs::appendProfile or MEDFileFieldGlobs::getProfile + * to keep a valid instance. + * If \b this do not have any leaf that correspond to the request of the input parameter (\b mName, \b typ, \b locId) an INTERP_KERNEL::Exception will be thrown. + * This method is an extension of MEDFileField1TSWithoutSDA::setProfileNameOnLeafExt method because it performs a modification of global info. + * If \b newLocName profile name does not already exist the localization with old name will be renamed with name \b newLocName. + * If \b newLocName already exists an INTERP_KERNEL::Exception will be thrown to avoid big confusion. In this case the called should rename before the profile name with name \b newLocName. + * + * \param [in] mName specifies the underlying mesh name. This value can be pointer 0 for users that do not deal with fields on multi mesh. + * \param [in] typ is for the geometric cell type (or INTERP_KERNEL::NORM_ERROR for node field) entry to find the right MEDFileFieldPerMeshPerTypePerDisc instance to set. + * \param [in] locId is the localization id to find the right MEDFileFieldPerMeshPerTypePerDisc instance to set. It corresponds to the position of + * \c pfls[std::distance(types.begin(),std::find(types.begin(),typ)] vector in MEDFileField1TSWithoutSDA::getFieldSplitedByType. For non gausspoints field users, the value is 0. + * \param [in] newLocName is the new localization name. + * \param [in] forceRenameOnGlob specifies the behaviour in case of profile \b newLocName already exists. If true, the renaming is done without check. It can lead to major bug. + * If false, an exception will be thrown to force user to change previously the name of the profile with name \b newLocName + */ +void MEDFileAnyTypeField1TS::setLocNameOnLeaf(const std::string& mName, INTERP_KERNEL::NormalizedCellType typ, int locId, const std::string& newLocName, bool forceRenameOnGlob) +{ + MEDFileFieldPerMeshPerTypePerDisc *disc=getLeafGivenMeshAndTypeAndLocId(mName,typ,locId); + std::string oldLocName=disc->getLocalization(); + std::vector<std::string> vv=getLocsReallyUsedMulti(); + int nbOfOcc=std::count(vv.begin(),vv.end(),oldLocName); + if(forceRenameOnGlob || (!existsLoc(newLocName) && nbOfOcc==1)) + { + disc->setLocalization(newLocName); + MEDFileFieldLoc& loc=getLocalization(oldLocName.c_str()); + loc.setName(newLocName); + } + else + { + std::ostringstream oss; oss << "MEDFileField1TS::setLocNameOnLeaf : Localization \"" << newLocName << "\" already exists or referenced more than one !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } +} + +MEDFileAnyTypeField1TSWithoutSDA *MEDFileAnyTypeField1TS::contentNotNullBase() +{ + MEDFileAnyTypeField1TSWithoutSDA *ret=_content; + if(!ret) + throw INTERP_KERNEL::Exception("MEDFileAnyTypeField1TS : content is expected to be not null !"); + return ret; +} + +const MEDFileAnyTypeField1TSWithoutSDA *MEDFileAnyTypeField1TS::contentNotNullBase() const +{ + const MEDFileAnyTypeField1TSWithoutSDA *ret=_content; + if(!ret) + throw INTERP_KERNEL::Exception("MEDFileAnyTypeField1TS : const content is expected to be not null !"); + return ret; +} + +/*! + * Writes \a this field into a MED file specified by its name. + * \param [in] fileName - the MED file name. + * \param [in] mode - the writing mode. For more on \a mode, see \ref AdvMEDLoaderBasics. + * - 2 - erase; an existing file is removed. + * - 1 - append; same data should not be present in an existing file. + * - 0 - overwrite; same data present in an existing file is overwritten. + * \throw If the field name is not set. + * \throw If no field data is set. + * \throw If \a mode == 1 and the same data is present in an existing file. + */ +void MEDFileAnyTypeField1TS::write(const std::string& fileName, int mode) const +{ + med_access_mode medmod=MEDFileUtilities::TraduceWriteMode(mode); + MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName.c_str(),medmod); + writeLL(fid); +} + +/*! + * This method alloc the arrays and load potentially huge arrays contained in this field. + * This method should be called when a MEDFileAnyTypeField1TS::New constructor has been with false as the last parameter. + * This method can be also called to refresh or reinit values from a file. + * + * \throw If the fileName is not set or points to a non readable MED file. + * \sa MEDFileAnyTypeField1TS::loadArraysIfNecessary + */ +void MEDFileAnyTypeField1TS::loadArrays() +{ + if(getFileName().empty()) + throw INTERP_KERNEL::Exception("MEDFileAnyTypeField1TS::loadArrays : the structure does not come from a file !"); + MEDFileUtilities::AutoFid fid=MEDfileOpen(getFileName().c_str(),MED_ACC_RDONLY); + contentNotNullBase()->loadBigArraysRecursively(fid,*contentNotNullBase()); +} + +/*! + * This method behaves as MEDFileAnyTypeField1TS::loadArrays does, the first call, if \a this was built using a file without loading big arrays. + * But once data loaded once, this method does nothing. Contrary to MEDFileAnyTypeField1TS::loadArrays and MEDFileAnyTypeField1TS::unloadArrays + * this method does not throw if \a this does not come from file read. + * + * \sa MEDFileAnyTypeField1TS::loadArrays, MEDFileAnyTypeField1TS::unloadArrays + */ +void MEDFileAnyTypeField1TS::loadArraysIfNecessary() +{ + if(!getFileName().empty()) + { + MEDFileUtilities::AutoFid fid=MEDfileOpen(getFileName().c_str(),MED_ACC_RDONLY); + contentNotNullBase()->loadBigArraysRecursivelyIfNecessary(fid,*contentNotNullBase()); + } +} + +/*! + * This method releases potentially big data arrays and so returns to the same heap memory than status loaded with 'loadAll' parameter set to false. + * \b WARNING, this method does release arrays even if \a this does not come from a load of a MED file. + * So this method can lead to a loss of data. If you want to unload arrays safely call MEDFileAnyTypeField1TS::unloadArraysWithoutDataLoss instead. + * + * \sa MEDFileAnyTypeField1TS::loadArrays, MEDFileAnyTypeField1TS::loadArraysIfNecessary, MEDFileAnyTypeField1TS::unloadArraysWithoutDataLoss + */ +void MEDFileAnyTypeField1TS::unloadArrays() +{ + contentNotNullBase()->unloadArrays(); +} + +/*! + * This method potentially releases big data arrays if \a this is coming from a file. If \a this has been built from scratch this method will have no effect. + * This method is the symetrical method of MEDFileAnyTypeField1TS::loadArraysIfNecessary. + * This method is useful to reduce \b safely amount of heap memory necessary for \a this by using MED file as database. + * + * \sa MEDFileAnyTypeField1TS::loadArraysIfNecessary + */ +void MEDFileAnyTypeField1TS::unloadArraysWithoutDataLoss() +{ + if(!getFileName().empty()) + contentNotNullBase()->unloadArrays(); +} + +void MEDFileAnyTypeField1TS::writeLL(med_idt fid) const +{ + int nbComp=getNumberOfComponents(); + INTERP_KERNEL::AutoPtr<char> comp=MEDLoaderBase::buildEmptyString(nbComp*MED_SNAME_SIZE); + INTERP_KERNEL::AutoPtr<char> unit=MEDLoaderBase::buildEmptyString(nbComp*MED_SNAME_SIZE); + for(int i=0;i<nbComp;i++) + { + std::string info=getInfo()[i]; + std::string c,u; + MEDLoaderBase::splitIntoNameAndUnit(info,c,u); + MEDLoaderBase::safeStrCpy2(c.c_str(),MED_SNAME_SIZE,comp+i*MED_SNAME_SIZE,_too_long_str); + MEDLoaderBase::safeStrCpy2(u.c_str(),MED_SNAME_SIZE,unit+i*MED_SNAME_SIZE,_too_long_str); + } + if(getName().empty()) + throw INTERP_KERNEL::Exception("MEDFileField1TS::write : MED file does not accept field with empty name !"); + MEDFILESAFECALLERWR0(MEDfieldCr,(fid,getName().c_str(),getMEDFileFieldType(),nbComp,comp,unit,getDtUnit().c_str(),getMeshName().c_str())); + writeGlobals(fid,*this); + contentNotNullBase()->writeLL(fid,*this,*contentNotNullBase()); +} + +std::size_t MEDFileAnyTypeField1TS::getHeapMemorySizeWithoutChildren() const +{ + return MEDFileFieldGlobsReal::getHeapMemorySizeWithoutChildren(); +} + +std::vector<const BigMemoryObject *> MEDFileAnyTypeField1TS::getDirectChildrenWithNull() const +{ + std::vector<const BigMemoryObject *> ret(MEDFileFieldGlobsReal::getDirectChildrenWithNull()); + ret.push_back((const MEDFileAnyTypeField1TSWithoutSDA *)_content); + return ret; +} + +/*! + * Returns a string describing \a this field. This string is outputted + * by \c print Python command. + */ +std::string MEDFileAnyTypeField1TS::simpleRepr() const +{ + std::ostringstream oss; + contentNotNullBase()->simpleRepr(0,oss,-1); + simpleReprGlobs(oss); + return oss.str(); +} + +/*! + * This method returns all profiles whose name is non empty used. + * \b WARNING If profile is used several times it will be reported \b only \b once. + * To get non empty name profiles as time as they appear in \b this call MEDFileField1TS::getPflsReallyUsedMulti instead. + */ +std::vector<std::string> MEDFileAnyTypeField1TS::getPflsReallyUsed() const +{ + return contentNotNullBase()->getPflsReallyUsed2(); +} + +/*! + * This method returns all localizations whose name is non empty used. + * \b WARNING If localization is used several times it will be reported \b only \b once. + */ +std::vector<std::string> MEDFileAnyTypeField1TS::getLocsReallyUsed() const +{ + return contentNotNullBase()->getLocsReallyUsed2(); +} + +/*! + * This method returns all profiles whose name is non empty used. + * \b WARNING contrary to MEDFileField1TS::getPflsReallyUsed, if profile is used several times it will be reported as time as it appears. + */ +std::vector<std::string> MEDFileAnyTypeField1TS::getPflsReallyUsedMulti() const +{ + return contentNotNullBase()->getPflsReallyUsedMulti2(); +} + +/*! + * This method returns all localizations whose name is non empty used. + * \b WARNING contrary to MEDFileField1TS::getLocsReallyUsed if localization is used several times it will be reported as time as it appears. + */ +std::vector<std::string> MEDFileAnyTypeField1TS::getLocsReallyUsedMulti() const +{ + return contentNotNullBase()->getLocsReallyUsedMulti2(); +} + +void MEDFileAnyTypeField1TS::changePflsRefsNamesGen(const std::vector< std::pair<std::vector<std::string>, std::string > >& mapOfModif) +{ + contentNotNullBase()->changePflsRefsNamesGen2(mapOfModif); +} + +void MEDFileAnyTypeField1TS::changeLocsRefsNamesGen(const std::vector< std::pair<std::vector<std::string>, std::string > >& mapOfModif) +{ + contentNotNullBase()->changeLocsRefsNamesGen2(mapOfModif); +} + +int MEDFileAnyTypeField1TS::getDimension() const +{ + return contentNotNullBase()->getDimension(); +} + +int MEDFileAnyTypeField1TS::getIteration() const +{ + return contentNotNullBase()->getIteration(); +} + +int MEDFileAnyTypeField1TS::getOrder() const +{ + return contentNotNullBase()->getOrder(); +} + +double MEDFileAnyTypeField1TS::getTime(int& iteration, int& order) const +{ + return contentNotNullBase()->getTime(iteration,order); +} + +void MEDFileAnyTypeField1TS::setTime(int iteration, int order, double val) +{ + contentNotNullBase()->setTime(iteration,order,val); +} + +std::string MEDFileAnyTypeField1TS::getName() const +{ + return contentNotNullBase()->getName(); +} + +void MEDFileAnyTypeField1TS::setName(const std::string& name) +{ + contentNotNullBase()->setName(name); +} + +void MEDFileAnyTypeField1TS::simpleRepr(int bkOffset, std::ostream& oss, int f1tsId) const +{ + contentNotNullBase()->simpleRepr(bkOffset,oss,f1tsId); +} + +std::string MEDFileAnyTypeField1TS::getDtUnit() const +{ + return contentNotNullBase()->getDtUnit(); +} + +void MEDFileAnyTypeField1TS::setDtUnit(const std::string& dtUnit) +{ + contentNotNullBase()->setDtUnit(dtUnit); +} + +std::string MEDFileAnyTypeField1TS::getMeshName() const +{ + return contentNotNullBase()->getMeshName(); +} + +void MEDFileAnyTypeField1TS::setMeshName(const std::string& newMeshName) +{ + contentNotNullBase()->setMeshName(newMeshName); +} + +bool MEDFileAnyTypeField1TS::changeMeshNames(const std::vector< std::pair<std::string,std::string> >& modifTab) +{ + return contentNotNullBase()->changeMeshNames(modifTab); +} + +int MEDFileAnyTypeField1TS::getMeshIteration() const +{ + return contentNotNullBase()->getMeshIteration(); +} + +int MEDFileAnyTypeField1TS::getMeshOrder() const +{ + return contentNotNullBase()->getMeshOrder(); +} + +int MEDFileAnyTypeField1TS::getNumberOfComponents() const +{ + return contentNotNullBase()->getNumberOfComponents(); +} + +bool MEDFileAnyTypeField1TS::isDealingTS(int iteration, int order) const +{ + return contentNotNullBase()->isDealingTS(iteration,order); +} + +std::pair<int,int> MEDFileAnyTypeField1TS::getDtIt() const +{ + return contentNotNullBase()->getDtIt(); +} + +void MEDFileAnyTypeField1TS::fillIteration(std::pair<int,int>& p) const +{ + contentNotNullBase()->fillIteration(p); +} + +void MEDFileAnyTypeField1TS::fillTypesOfFieldAvailable(std::vector<TypeOfField>& types) const +{ + contentNotNullBase()->fillTypesOfFieldAvailable(types); +} + +void MEDFileAnyTypeField1TS::setInfo(const std::vector<std::string>& infos) +{ + contentNotNullBase()->setInfo(infos); +} + +const std::vector<std::string>& MEDFileAnyTypeField1TS::getInfo() const +{ + return contentNotNullBase()->getInfo(); +} +std::vector<std::string>& MEDFileAnyTypeField1TS::getInfo() +{ + return contentNotNullBase()->getInfo(); +} + +bool MEDFileAnyTypeField1TS::presenceOfMultiDiscPerGeoType() const +{ + return contentNotNullBase()->presenceOfMultiDiscPerGeoType(); +} + +MEDFileFieldPerMeshPerTypePerDisc *MEDFileAnyTypeField1TS::getLeafGivenMeshAndTypeAndLocId(const std::string& mName, INTERP_KERNEL::NormalizedCellType typ, int locId) +{ + return contentNotNullBase()->getLeafGivenMeshAndTypeAndLocId(mName,typ,locId); +} + +const MEDFileFieldPerMeshPerTypePerDisc *MEDFileAnyTypeField1TS::getLeafGivenMeshAndTypeAndLocId(const std::string& mName, INTERP_KERNEL::NormalizedCellType typ, int locId) const +{ + return contentNotNullBase()->getLeafGivenMeshAndTypeAndLocId(mName,typ,locId); +} + +int MEDFileAnyTypeField1TS::getNonEmptyLevels(const std::string& mname, std::vector<int>& levs) const +{ + return contentNotNullBase()->getNonEmptyLevels(mname,levs); +} + +std::vector<TypeOfField> MEDFileAnyTypeField1TS::getTypesOfFieldAvailable() const +{ + return contentNotNullBase()->getTypesOfFieldAvailable(); +} + +std::vector< std::vector<std::pair<int,int> > > MEDFileAnyTypeField1TS::getFieldSplitedByType(const std::string& mname, std::vector<INTERP_KERNEL::NormalizedCellType>& types, std::vector< std::vector<TypeOfField> >& typesF, + std::vector< std::vector<std::string> >& pfls, std::vector< std::vector<std::string> >& locs) const +{ + return contentNotNullBase()->getFieldSplitedByType(mname,types,typesF,pfls,locs); +} + +/*! + * This method returns as MEDFileAnyTypeField1TS new instances as number of components in \a this. + * The returned instances are deep copy of \a this except that for globals that are share with those contained in \a this. + * ** WARNING ** do no forget to rename the ouput instances to avoid to write n-times in the same MED file field ! + */ +std::vector< MEDCouplingAutoRefCountObjectPtr< MEDFileAnyTypeField1TS > > MEDFileAnyTypeField1TS::splitComponents() const +{ + const MEDFileAnyTypeField1TSWithoutSDA *content(_content); + if(!content) + throw INTERP_KERNEL::Exception("MEDFileAnyTypeField1TS::splitComponents : no content in this ! Unable to split components !"); + std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileAnyTypeField1TSWithoutSDA> > contentsSplit=content->splitComponents(); + std::size_t sz(contentsSplit.size()); + std::vector< MEDCouplingAutoRefCountObjectPtr< MEDFileAnyTypeField1TS > > ret(sz); + for(std::size_t i=0;i<sz;i++) + { + ret[i]=shallowCpy(); + ret[i]->_content=contentsSplit[i]; + } + return ret; +} + +/*! + * This method returns as MEDFileAnyTypeField1TS new instances as number of spatial discretizations in \a this. + * The returned instances are shallowed copied of \a this except that for globals that are share with those contained in \a this. + */ +std::vector< MEDCouplingAutoRefCountObjectPtr< MEDFileAnyTypeField1TS > > MEDFileAnyTypeField1TS::splitDiscretizations() const +{ + const MEDFileAnyTypeField1TSWithoutSDA *content(_content); + if(!content) + throw INTERP_KERNEL::Exception("MEDFileAnyTypeField1TS::splitDiscretizations : no content in this ! Unable to split discretization !"); + std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileAnyTypeField1TSWithoutSDA> > contentsSplit(content->splitDiscretizations()); + std::size_t sz(contentsSplit.size()); + std::vector< MEDCouplingAutoRefCountObjectPtr< MEDFileAnyTypeField1TS > > ret(sz); + for(std::size_t i=0;i<sz;i++) + { + ret[i]=shallowCpy(); + ret[i]->_content=contentsSplit[i]; + } + return ret; +} + +/*! + * This method returns as MEDFileAnyTypeField1TS new instances as number of maximal number of discretization in \a this. + * The returned instances are shallowed copied of \a this except that for globals that are share with those contained in \a this. + */ +std::vector< MEDCouplingAutoRefCountObjectPtr< MEDFileAnyTypeField1TS > > MEDFileAnyTypeField1TS::splitMultiDiscrPerGeoTypes() const +{ + const MEDFileAnyTypeField1TSWithoutSDA *content(_content); + if(!content) + throw INTERP_KERNEL::Exception("MEDFileAnyTypeField1TS::splitMultiDiscrPerGeoTypes : no content in this ! Unable to split discretization !"); + std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileAnyTypeField1TSWithoutSDA> > contentsSplit(content->splitMultiDiscrPerGeoTypes()); + std::size_t sz(contentsSplit.size()); + std::vector< MEDCouplingAutoRefCountObjectPtr< MEDFileAnyTypeField1TS > > ret(sz); + for(std::size_t i=0;i<sz;i++) + { + ret[i]=shallowCpy(); + ret[i]->_content=contentsSplit[i]; + } + return ret; +} + +MEDFileAnyTypeField1TS *MEDFileAnyTypeField1TS::deepCpy() const +{ + MEDCouplingAutoRefCountObjectPtr<MEDFileAnyTypeField1TS> ret=shallowCpy(); + if((const MEDFileAnyTypeField1TSWithoutSDA *)_content) + ret->_content=_content->deepCpy(); + ret->deepCpyGlobs(*this); + return ret.retn(); +} + +int MEDFileAnyTypeField1TS::copyTinyInfoFrom(const MEDCouplingFieldDouble *field, const DataArray *arr) +{ + return contentNotNullBase()->copyTinyInfoFrom(field,arr); +} + +//= MEDFileField1TS + +/*! + * Returns a new instance of MEDFileField1TS holding data of the first time step of + * the first field that has been read from a specified MED file. + * \param [in] fileName - the name of the MED file to read. + * \return MEDFileField1TS * - a new instance of MEDFileFieldMultiTS. The caller + * is to delete this field using decrRef() as it is no more needed. + * \throw If reading the file fails. + */ +MEDFileField1TS *MEDFileField1TS::New(const std::string& fileName, bool loadAll) +{ + MEDCouplingAutoRefCountObjectPtr<MEDFileField1TS> ret(new MEDFileField1TS(fileName,loadAll,0)); + ret->contentNotNull(); + return ret.retn(); +} + +/*! + * Returns a new instance of MEDFileField1TS holding data of the first time step of + * a given field that has been read from a specified MED file. + * \param [in] fileName - the name of the MED file to read. + * \param [in] fieldName - the name of the field to read. + * \return MEDFileField1TS * - a new instance of MEDFileFieldMultiTS. The caller + * is to delete this field using decrRef() as it is no more needed. + * \throw If reading the file fails. + * \throw If there is no field named \a fieldName in the file. + */ +MEDFileField1TS *MEDFileField1TS::New(const std::string& fileName, const std::string& fieldName, bool loadAll) +{ + MEDCouplingAutoRefCountObjectPtr<MEDFileField1TS> ret(new MEDFileField1TS(fileName,fieldName,loadAll,0)); + ret->contentNotNull(); + return ret.retn(); +} + +/*! + * Returns a new instance of MEDFileField1TS holding data of a given time step of + * a given field that has been read from a specified MED file. + * \param [in] fileName - the name of the MED file to read. + * \param [in] fieldName - the name of the field to read. + * \param [in] iteration - the iteration number of a required time step. + * \param [in] order - the iteration order number of required time step. + * \return MEDFileField1TS * - a new instance of MEDFileFieldMultiTS. The caller + * is to delete this field using decrRef() as it is no more needed. + * \throw If reading the file fails. + * \throw If there is no field named \a fieldName in the file. + * \throw If the required time step is missing from the file. + */ +MEDFileField1TS *MEDFileField1TS::New(const std::string& fileName, const std::string& fieldName, int iteration, int order, bool loadAll) +{ + MEDCouplingAutoRefCountObjectPtr<MEDFileField1TS> ret(new MEDFileField1TS(fileName,fieldName,iteration,order,loadAll,0)); + ret->contentNotNull(); + return ret.retn(); +} + +/*! + * Returns a new instance of MEDFileField1TS. If \a shallowCopyOfContent is true the content of \a other is shallow copied. + * If \a shallowCopyOfContent is false, \a other is taken to be the content of \a this. + * + * Returns a new instance of MEDFileField1TS holding either a shallow copy + * of a given MEDFileField1TSWithoutSDA ( \a other ) or \a other itself. + * \warning this is a shallow copy constructor + * \param [in] other - a MEDFileField1TSWithoutSDA to copy. + * \param [in] shallowCopyOfContent - if \c true, a shallow copy of \a other is created. + * \return MEDFileField1TS * - a new instance of MEDFileField1TS. The caller + * is to delete this field using decrRef() as it is no more needed. + */ +MEDFileField1TS *MEDFileField1TS::New(const MEDFileField1TSWithoutSDA& other, bool shallowCopyOfContent) +{ + MEDCouplingAutoRefCountObjectPtr<MEDFileField1TS> ret=new MEDFileField1TS(other,shallowCopyOfContent); + ret->contentNotNull(); + return ret.retn(); +} + +/*! + * Returns a new empty instance of MEDFileField1TS. + * \return MEDFileField1TS * - a new instance of MEDFileField1TS. The caller + * is to delete this field using decrRef() as it is no more needed. + */ +MEDFileField1TS *MEDFileField1TS::New() +{ + MEDCouplingAutoRefCountObjectPtr<MEDFileField1TS> ret=new MEDFileField1TS; + ret->contentNotNull(); + return ret.retn(); +} + +/*! + * This method performs a copy with datatype modification ( float64->int32 ) of \a this. The globals information are copied + * following the given input policy. + * + * \param [in] isDeepCpyGlobs - a boolean that indicates the behaviour concerning globals (profiles and localizations) + * By default (true) the globals are deeply copied. + * \return MEDFileIntField1TS * - a new object that is the result of the conversion of \a this to int32 field. + */ +MEDFileIntField1TS *MEDFileField1TS::convertToInt(bool isDeepCpyGlobs) const +{ + MEDCouplingAutoRefCountObjectPtr<MEDFileIntField1TS> ret; + const MEDFileAnyTypeField1TSWithoutSDA *content(_content); + if(content) + { + const MEDFileField1TSWithoutSDA *contc=dynamic_cast<const MEDFileField1TSWithoutSDA *>(content); + if(!contc) + throw INTERP_KERNEL::Exception("MEDFileField1TS::convertToInt : the content inside this is not FLOAT64 ! This is incoherent !"); + MEDCouplingAutoRefCountObjectPtr<MEDFileIntField1TSWithoutSDA> newc(contc->convertToInt()); + ret=static_cast<MEDFileIntField1TS *>(MEDFileAnyTypeField1TS::BuildNewInstanceFromContent((MEDFileIntField1TSWithoutSDA *)newc,getFileName())); + } + else + ret=MEDFileIntField1TS::New(); + if(isDeepCpyGlobs) + ret->deepCpyGlobs(*this); + else + ret->shallowCpyGlobs(*this); + return ret.retn(); +} + +const MEDFileField1TSWithoutSDA *MEDFileField1TS::contentNotNull() const +{ + const MEDFileAnyTypeField1TSWithoutSDA *pt(_content); + if(!pt) + throw INTERP_KERNEL::Exception("MEDFileField1TS::contentNotNull : the content pointer is null !"); + const MEDFileField1TSWithoutSDA *ret=dynamic_cast<const MEDFileField1TSWithoutSDA *>(pt); + if(!ret) + throw INTERP_KERNEL::Exception("MEDFileField1TS::contentNotNull : the content pointer is not null but it is not of type double ! Reason is maybe that the read field has not the type FLOAT64 !"); + return ret; +} + +MEDFileField1TSWithoutSDA *MEDFileField1TS::contentNotNull() +{ + MEDFileAnyTypeField1TSWithoutSDA *pt(_content); + if(!pt) + throw INTERP_KERNEL::Exception("MEDFileField1TS::contentNotNull : the non const content pointer is null !"); + MEDFileField1TSWithoutSDA *ret=dynamic_cast<MEDFileField1TSWithoutSDA *>(pt); + if(!ret) + throw INTERP_KERNEL::Exception("MEDFileField1TS::contentNotNull : the non const content pointer is not null but it is not of type double ! Reason is maybe that the read field has not the type FLOAT64 !"); + return ret; +} + +void MEDFileField1TS::SetDataArrayDoubleInField(MEDCouplingFieldDouble *f, MEDCouplingAutoRefCountObjectPtr<DataArray>& arr) +{ + if(!f) + throw INTERP_KERNEL::Exception("MEDFileField1TS::SetDataArrayDoubleInField : input field is NULL !"); + if(!((DataArray*)arr)) + throw INTERP_KERNEL::Exception("MEDFileField1TS::SetDataArrayDoubleInField : no array !"); + DataArrayDouble *arrOutC=dynamic_cast<DataArrayDouble *>((DataArray*)arr); + if(!arrOutC) + throw INTERP_KERNEL::Exception("MEDFileField1TS::SetDataArrayDoubleInField : mismatch between dataArrays type and MEDFileField1TS ! Expected double !"); + f->setArray(arrOutC); +} + +DataArrayDouble *MEDFileField1TS::ReturnSafelyDataArrayDouble(MEDCouplingAutoRefCountObjectPtr<DataArray>& arr) +{ + if(!((DataArray*)arr)) + throw INTERP_KERNEL::Exception("MEDFileField1TS::ReturnSafelyDataArrayDouble : no array !"); + DataArrayDouble *arrOutC=dynamic_cast<DataArrayDouble *>((DataArray*)arr); + if(!arrOutC) + throw INTERP_KERNEL::Exception("MEDFileField1TS::ReturnSafelyDataArrayDouble : mismatch between dataArrays type and MEDFileField1TS ! Expected double !"); + arrOutC->incrRef(); + return arrOutC; +} + +MEDFileField1TS::MEDFileField1TS(const std::string& fileName, bool loadAll, const MEDFileMeshes *ms) +try:MEDFileAnyTypeField1TS(fileName,loadAll,ms) +{ +} +catch(INTERP_KERNEL::Exception& e) +{ throw e; } + +MEDFileField1TS::MEDFileField1TS(const std::string& fileName, const std::string& fieldName, bool loadAll, const MEDFileMeshes *ms) +try:MEDFileAnyTypeField1TS(fileName,fieldName,loadAll,ms) +{ +} +catch(INTERP_KERNEL::Exception& e) +{ throw e; } + +MEDFileField1TS::MEDFileField1TS(const std::string& fileName, const std::string& fieldName, int iteration, int order, bool loadAll, const MEDFileMeshes *ms) +try:MEDFileAnyTypeField1TS(fileName,fieldName,iteration,order,loadAll,ms) +{ +} +catch(INTERP_KERNEL::Exception& e) +{ throw e; } + +/*! + * This constructor is a shallow copy constructor. If \a shallowCopyOfContent is true the content of \a other is shallow copied. + * If \a shallowCopyOfContent is false, \a other is taken to be the content of \a this. + * + * \warning this is a shallow copy constructor + */ +MEDFileField1TS::MEDFileField1TS(const MEDFileField1TSWithoutSDA& other, bool shallowCopyOfContent) +try:MEDFileAnyTypeField1TS(other,shallowCopyOfContent) +{ +} +catch(INTERP_KERNEL::Exception& e) +{ throw e; } + +MEDFileField1TS::MEDFileField1TS() +{ + _content=new MEDFileField1TSWithoutSDA; +} + +/*! + * Returns a new MEDCouplingFieldDouble of a given type lying on + * mesh entities of a given dimension of the first mesh in MED file. If \a this field + * has not been constructed via file reading, an exception is thrown. + * For more info, see \ref AdvMEDLoaderAPIFieldRW + * \param [in] type - a spatial discretization of interest. + * \param [in] meshDimRelToMax - a relative dimension of the supporting mesh entities. + * \param [in] renumPol - specifies how to permute values of the result field according to + * the optional numbers of cells and nodes, if any. The valid values are + * - 0 - do not permute. + * - 1 - permute cells. + * - 2 - permute nodes. + * - 3 - permute cells and nodes. + * + * \return MEDCouplingFieldDouble * - a new instance of MEDCouplingFieldDouble. The + * caller is to delete this field using decrRef() as it is no more needed. + * \throw If \a this field has not been constructed via file reading. + * \throw If the MED file is not readable. + * \throw If there is no mesh in the MED file. + * \throw If there are no mesh entities of \a meshDimRelToMax dimension in the mesh. + * \throw If no field values of the given \a type or given \a meshDimRelToMax are available. + * \sa getFieldOnMeshAtLevel() + */ +MEDCouplingFieldDouble *MEDFileField1TS::getFieldAtLevel(TypeOfField type, int meshDimRelToMax, int renumPol) const +{ + if(getFileName().empty()) + throw INTERP_KERNEL::Exception("MEDFileField1TS::getFieldAtLevel : Request for a method that can be used for instances coming from file loading ! Use getFieldOnMeshAtLevel method instead !"); + MEDCouplingAutoRefCountObjectPtr<DataArray> arrOut; + MEDCouplingAutoRefCountObjectPtr<MEDCouplingFieldDouble> ret=contentNotNull()->getFieldAtLevel(type,meshDimRelToMax,std::string(),renumPol,this,arrOut,*contentNotNull()); + MEDFileField1TS::SetDataArrayDoubleInField(ret,arrOut); + return ret.retn(); +} + +/*! + * Returns a new MEDCouplingFieldDouble of a given type lying on + * the top level cells of the first mesh in MED file. If \a this field + * has not been constructed via file reading, an exception is thrown. + * For more info, see \ref AdvMEDLoaderAPIFieldRW + * \param [in] type - a spatial discretization of interest. + * \param [in] renumPol - specifies how to permute values of the result field according to + * the optional numbers of cells and nodes, if any. The valid values are + * - 0 - do not permute. + * - 1 - permute cells. + * - 2 - permute nodes. + * - 3 - permute cells and nodes. + * + * \return MEDCouplingFieldDouble * - a new instance of MEDCouplingFieldDouble. The + * caller is to delete this field using decrRef() as it is no more needed. + * \throw If \a this field has not been constructed via file reading. + * \throw If the MED file is not readable. + * \throw If there is no mesh in the MED file. + * \throw If no field values of the given \a type. + * \throw If no field values lying on the top level support. + * \sa getFieldAtLevel() + */ +MEDCouplingFieldDouble *MEDFileField1TS::getFieldAtTopLevel(TypeOfField type, int renumPol) const +{ + if(getFileName().empty()) + throw INTERP_KERNEL::Exception("MEDFileField1TS::getFieldAtTopLevel : Request for a method that can be used for instances coming from file loading ! Use getFieldOnMeshAtTopLevel method instead !"); + MEDCouplingAutoRefCountObjectPtr<DataArray> arrOut; + MEDCouplingAutoRefCountObjectPtr<MEDCouplingFieldDouble> ret=contentNotNull()->getFieldAtTopLevel(type,std::string(),renumPol,this,arrOut,*contentNotNull()); + MEDFileField1TS::SetDataArrayDoubleInField(ret,arrOut); + return ret.retn(); +} + +/*! + * Returns a new MEDCouplingFieldDouble of given type lying on a given mesh. + * For more info, see \ref AdvMEDLoaderAPIFieldRW + * \param [in] type - a spatial discretization of the new field. + * \param [in] mesh - the supporting mesh. + * \param [in] renumPol - specifies how to permute values of the result field according to + * the optional numbers of cells and nodes, if any. The valid values are + * - 0 - do not permute. + * - 1 - permute cells. + * - 2 - permute nodes. + * - 3 - permute cells and nodes. + * + * \return MEDCouplingFieldDouble * - a new instance of MEDCouplingFieldDouble. The + * caller is to delete this field using decrRef() as it is no more needed. + * \throw If no field of \a this is lying on \a mesh. + * \throw If the mesh is empty. + * \throw If no field values of the given \a type are available. + * \sa getFieldAtLevel() + * \sa getFieldOnMeshAtLevel() + */ +MEDCouplingFieldDouble *MEDFileField1TS::getFieldOnMeshAtLevel(TypeOfField type, const MEDCouplingMesh *mesh, int renumPol) const +{ + MEDCouplingAutoRefCountObjectPtr<DataArray> arrOut; + MEDCouplingAutoRefCountObjectPtr<MEDCouplingFieldDouble> ret=contentNotNull()->getFieldOnMeshAtLevel(type,renumPol,this,mesh,0,0,arrOut,*contentNotNull()); + MEDFileField1TS::SetDataArrayDoubleInField(ret,arrOut); + return ret.retn(); +} + +/*! + * Returns a new MEDCouplingFieldDouble of a given type lying on a given support. + * For more info, see \ref AdvMEDLoaderAPIFieldRW + * \param [in] type - a spatial discretization of interest. + * \param [in] meshDimRelToMax - a relative dimension of the supporting mesh entities. + * \param [in] mesh - the supporting mesh. + * \param [in] renumPol - specifies how to permute values of the result field according to + * the optional numbers of cells and nodes, if any. The valid values are + * - 0 - do not permute. + * - 1 - permute cells. + * - 2 - permute nodes. + * - 3 - permute cells and nodes. + * + * \return MEDCouplingFieldDouble * - a new instance of MEDCouplingFieldDouble. The + * caller is to delete this field using decrRef() as it is no more needed. + * \throw If there are no mesh entities of \a meshDimRelToMax dimension in the mesh. + * \throw If no field of \a this is lying on \a mesh. + * \throw If no field values of the given \a type or given \a meshDimRelToMax are available. + * \sa getFieldAtLevel() + * \sa getFieldOnMeshAtLevel() + */ +MEDCouplingFieldDouble *MEDFileField1TS::getFieldOnMeshAtLevel(TypeOfField type, int meshDimRelToMax, const MEDFileMesh *mesh, int renumPol) const +{ + MEDCouplingAutoRefCountObjectPtr<DataArray> arrOut; + MEDCouplingAutoRefCountObjectPtr<MEDCouplingFieldDouble> ret=contentNotNull()->getFieldOnMeshAtLevel(type,meshDimRelToMax,renumPol,this,mesh,arrOut,*contentNotNull()); + MEDFileField1TS::SetDataArrayDoubleInField(ret,arrOut); + return ret.retn(); +} + +/*! + * Returns a new MEDCouplingFieldDouble of a given type lying on a given support. + * This method is called "Old" because in MED3 norm a field has only one meshName + * attached, so this method is for readers of MED2 files. If \a this field + * has not been constructed via file reading, an exception is thrown. + * For more info, see \ref AdvMEDLoaderAPIFieldRW + * \param [in] type - a spatial discretization of interest. + * \param [in] mName - a name of the supporting mesh. + * \param [in] meshDimRelToMax - a relative dimension of the supporting mesh entities. + * \param [in] renumPol - specifies how to permute values of the result field according to + * the optional numbers of cells and nodes, if any. The valid values are + * - 0 - do not permute. + * - 1 - permute cells. + * - 2 - permute nodes. + * - 3 - permute cells and nodes. + * + * \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 MED file is not readable. + * \throw If there is no mesh named \a mName in the MED file. + * \throw If there are no mesh entities of \a meshDimRelToMax dimension in the mesh. + * \throw If \a this field has not been constructed via file reading. + * \throw If no field of \a this is lying on the mesh named \a mName. + * \throw If no field values of the given \a type or given \a meshDimRelToMax are available. + * \sa getFieldAtLevel() + */ +MEDCouplingFieldDouble *MEDFileField1TS::getFieldAtLevelOld(TypeOfField type, const std::string& mname, int meshDimRelToMax, int renumPol) const +{ + if(getFileName().empty()) + throw INTERP_KERNEL::Exception("MEDFileField1TS::getFieldAtLevelOld : Request for a method that can be used for instances coming from file loading ! Use getFieldOnMeshAtLevel method instead !"); + MEDCouplingAutoRefCountObjectPtr<DataArray> arrOut; + MEDCouplingAutoRefCountObjectPtr<MEDCouplingFieldDouble> ret=contentNotNull()->getFieldAtLevel(type,meshDimRelToMax,mname,renumPol,this,arrOut,*contentNotNull()); + MEDFileField1TS::SetDataArrayDoubleInField(ret,arrOut); + return ret.retn(); +} + +/*! + * Returns values and a profile of the field of a given type lying on a given support. + * For more info, see \ref AdvMEDLoaderAPIFieldRW + * \param [in] type - a spatial discretization of the field. + * \param [in] meshDimRelToMax - a relative dimension of the supporting mesh entities. + * \param [in] mesh - the supporting mesh. + * \param [out] pfl - a new instance of DataArrayInt holding ids of mesh entities the + * field of interest lies on. If the field lies on all entities of the given + * dimension, all ids in \a pfl are zero. The caller is to delete this array + * using decrRef() as it is no more needed. + * \return DataArrayDouble * - a new instance of DataArrayDouble holding values of the + * field. The caller is to delete this array using decrRef() as it is no more needed. + * \throw If there are no mesh entities of \a meshDimRelToMax dimension in \a mesh. + * \throw If no field of \a this is lying on \a mesh. + * \throw If no field values of the given \a type or given \a meshDimRelToMax are available. + */ +DataArrayDouble *MEDFileField1TS::getFieldWithProfile(TypeOfField type, int meshDimRelToMax, const MEDFileMesh *mesh, DataArrayInt *&pfl) const +{ + MEDCouplingAutoRefCountObjectPtr<DataArray> ret=contentNotNull()->getFieldWithProfile(type,meshDimRelToMax,mesh,pfl,this,*contentNotNull()); + return MEDFileField1TS::ReturnSafelyDataArrayDouble(ret); +} + +/*! + * Adds a MEDCouplingFieldDouble to \a this. The underlying mesh of the given field is + * checked if its elements are sorted suitable for writing to MED file ("STB" stands for + * "Sort By Type"), if not, an exception is thrown. + * For more info, see \ref AdvMEDLoaderAPIFieldRW + * \param [in] field - the field to add to \a this. + * \throw If the name of \a field is empty. + * \throw If the data array of \a field is not set. + * \throw If the data array is already allocated but has different number of components + * than \a field. + * \throw If the underlying mesh of \a field has no name. + * \throw If elements in the mesh are not in the order suitable for writing to the MED file. + */ +void MEDFileField1TS::setFieldNoProfileSBT(const MEDCouplingFieldDouble *field) +{ + setFileName(""); + contentNotNull()->setFieldNoProfileSBT(field,field->getArray(),*this,*contentNotNull()); +} + +/*! + * Adds a MEDCouplingFieldDouble to \a this. As described in \ref MEDLoaderMainC a field in MED file sense + * can be an aggregation of several MEDCouplingFieldDouble instances. + * The mesh support of input parameter \a field is ignored here, it can be NULL. + * The support of field \a field is expected to be those computed with the input parameter \a mesh, \a meshDimRelToMax, + * and \a profile. + * + * This method will check that the field based on the computed support is coherent. If not an exception will be thrown. + * A new profile is added only if no equal profile is missing. + * For more info, see \ref AdvMEDLoaderAPIFieldRW + * \param [in] field - the field to add to \a this. The mesh support of field is ignored. + * \param [in] mesh - the supporting mesh of \a field. + * \param [in] meshDimRelToMax - a relative dimension of mesh entities \a field lies on (useless if field spatial discretization is ON_NODES). + * \param [in] profile - ids of mesh entities on which corresponding field values lie. + * \throw If either \a field or \a mesh or \a profile has an empty name. + * \throw If there are no mesh entities of \a meshDimRelToMax dimension in \a mesh. + * \throw If the data array of \a field is not set. + * \throw If the data array of \a this is already allocated but has different number of + * components than \a field. + * \throw If elements in \a mesh are not in the order suitable for writing to the MED file. + * \sa setFieldNoProfileSBT() + */ +void MEDFileField1TS::setFieldProfile(const MEDCouplingFieldDouble *field, const MEDFileMesh *mesh, int meshDimRelToMax, const DataArrayInt *profile) +{ + setFileName(""); + contentNotNull()->setFieldProfile(field,field->getArray(),mesh,meshDimRelToMax,profile,*this,*contentNotNull()); +} + +MEDFileAnyTypeField1TS *MEDFileField1TS::shallowCpy() const +{ + return new MEDFileField1TS(*this); +} + +DataArrayDouble *MEDFileField1TS::getUndergroundDataArray() const +{ + return contentNotNull()->getUndergroundDataArrayDouble(); +} + +DataArrayDouble *MEDFileField1TS::getUndergroundDataArrayExt(std::vector< std::pair<std::pair<INTERP_KERNEL::NormalizedCellType,int>,std::pair<int,int> > >& entries) const +{ + return contentNotNull()->getUndergroundDataArrayDoubleExt(entries); +} + +std::vector< std::vector<DataArrayDouble *> > MEDFileField1TS::getFieldSplitedByType2(const std::string& mname, std::vector<INTERP_KERNEL::NormalizedCellType>& types, std::vector< std::vector<TypeOfField> >& typesF, + std::vector< std::vector<std::string> >& pfls, std::vector< std::vector<std::string> >& locs) const +{ + return contentNotNull()->getFieldSplitedByType2(mname,types,typesF,pfls,locs); +} + +//= MEDFileIntField1TS + +MEDFileIntField1TS *MEDFileIntField1TS::New() +{ + MEDCouplingAutoRefCountObjectPtr<MEDFileIntField1TS> ret=new MEDFileIntField1TS; + ret->contentNotNull(); + return ret.retn(); +} + +MEDFileIntField1TS *MEDFileIntField1TS::New(const std::string& fileName, bool loadAll) +{ + MEDCouplingAutoRefCountObjectPtr<MEDFileIntField1TS> ret(new MEDFileIntField1TS(fileName,loadAll,0)); + ret->contentNotNull(); + return ret.retn(); +} + +MEDFileIntField1TS *MEDFileIntField1TS::New(const std::string& fileName, const std::string& fieldName, bool loadAll) +{ + MEDCouplingAutoRefCountObjectPtr<MEDFileIntField1TS> ret(new MEDFileIntField1TS(fileName,fieldName,loadAll,0)); + ret->contentNotNull(); + return ret.retn(); +} + +MEDFileIntField1TS *MEDFileIntField1TS::New(const std::string& fileName, const std::string& fieldName, int iteration, int order, bool loadAll) +{ + MEDCouplingAutoRefCountObjectPtr<MEDFileIntField1TS> ret(new MEDFileIntField1TS(fileName,fieldName,iteration,order,loadAll,0)); + ret->contentNotNull(); + return ret.retn(); +} + +MEDFileIntField1TS *MEDFileIntField1TS::New(const MEDFileIntField1TSWithoutSDA& other, bool shallowCopyOfContent) +{ + MEDCouplingAutoRefCountObjectPtr<MEDFileIntField1TS> ret=new MEDFileIntField1TS(other,shallowCopyOfContent); + ret->contentNotNull(); + return ret.retn(); +} + +MEDFileIntField1TS::MEDFileIntField1TS() +{ + _content=new MEDFileIntField1TSWithoutSDA; +} + +MEDFileIntField1TS::MEDFileIntField1TS(const std::string& fileName, bool loadAll, const MEDFileMeshes *ms) +try:MEDFileAnyTypeField1TS(fileName,loadAll,ms) +{ +} +catch(INTERP_KERNEL::Exception& e) +{ throw e; } + +MEDFileIntField1TS::MEDFileIntField1TS(const std::string& fileName, const std::string& fieldName, bool loadAll, const MEDFileMeshes *ms) +try:MEDFileAnyTypeField1TS(fileName,fieldName,loadAll,ms) +{ +} +catch(INTERP_KERNEL::Exception& e) +{ throw e; } + +MEDFileIntField1TS::MEDFileIntField1TS(const std::string& fileName, const std::string& fieldName, int iteration, int order, bool loadAll, const MEDFileMeshes *ms) +try:MEDFileAnyTypeField1TS(fileName,fieldName,iteration,order,loadAll,ms) +{ +} +catch(INTERP_KERNEL::Exception& e) +{ throw e; } + +/*! + * This constructor is a shallow copy constructor. If \a shallowCopyOfContent is true the content of \a other is shallow copied. + * If \a shallowCopyOfContent is false, \a other is taken to be the content of \a this. + * + * \warning this is a shallow copy constructor + */ +MEDFileIntField1TS::MEDFileIntField1TS(const MEDFileIntField1TSWithoutSDA& other, bool shallowCopyOfContent):MEDFileAnyTypeField1TS(other,shallowCopyOfContent) +{ +} + +MEDFileAnyTypeField1TS *MEDFileIntField1TS::shallowCpy() const +{ + return new MEDFileIntField1TS(*this); +} + +/*! + * This method performs a copy with datatype modification ( int32->float64 ) of \a this. The globals information are copied + * following the given input policy. + * + * \param [in] isDeepCpyGlobs - a boolean that indicates the behaviour concerning globals (profiles and localizations) + * By default (true) the globals are deeply copied. + * \return MEDFileField1TS * - a new object that is the result of the conversion of \a this to float64 field. + */ +MEDFileField1TS *MEDFileIntField1TS::convertToDouble(bool isDeepCpyGlobs) const +{ + MEDCouplingAutoRefCountObjectPtr<MEDFileField1TS> ret; + const MEDFileAnyTypeField1TSWithoutSDA *content(_content); + if(content) + { + const MEDFileIntField1TSWithoutSDA *contc=dynamic_cast<const MEDFileIntField1TSWithoutSDA *>(content); + if(!contc) + throw INTERP_KERNEL::Exception("MEDFileIntField1TS::convertToInt : the content inside this is not INT32 ! This is incoherent !"); + MEDCouplingAutoRefCountObjectPtr<MEDFileField1TSWithoutSDA> newc(contc->convertToDouble()); + ret=static_cast<MEDFileField1TS *>(MEDFileAnyTypeField1TS::BuildNewInstanceFromContent((MEDFileField1TSWithoutSDA *)newc,getFileName())); + } + else + ret=MEDFileField1TS::New(); + if(isDeepCpyGlobs) + ret->deepCpyGlobs(*this); + else + ret->shallowCpyGlobs(*this); + return ret.retn(); +} + +/*! + * Adds a MEDCouplingFieldDouble to \a this. The underlying mesh of the given field is + * checked if its elements are sorted suitable for writing to MED file ("STB" stands for + * "Sort By Type"), if not, an exception is thrown. + * For more info, see \ref AdvMEDLoaderAPIFieldRW + * \param [in] field - the field to add to \a this. The field double values are ignored. + * \param [in] arrOfVals - the values of the field \a field used. + * \throw If the name of \a field is empty. + * \throw If the data array of \a field is not set. + * \throw If the data array is already allocated but has different number of components + * than \a field. + * \throw If the underlying mesh of \a field has no name. + * \throw If elements in the mesh are not in the order suitable for writing to the MED file. + */ +void MEDFileIntField1TS::setFieldNoProfileSBT(const MEDCouplingFieldDouble *field, const DataArrayInt *arrOfVals) +{ + setFileName(""); + contentNotNull()->setFieldNoProfileSBT(field,arrOfVals,*this,*contentNotNull()); +} + +/*! + * Adds a MEDCouplingFieldDouble to \a this. As described in \ref MEDLoaderMainC a field in MED file sense + * can be an aggregation of several MEDCouplingFieldDouble instances. + * The mesh support of input parameter \a field is ignored here, it can be NULL. + * The support of field \a field is expected to be those computed with the input parameter \a mesh, \a meshDimRelToMax, + * and \a profile. + * + * This method will check that the field based on the computed support is coherent. If not an exception will be thrown. + * A new profile is added only if no equal profile is missing. + * For more info, see \ref AdvMEDLoaderAPIFieldRW + * \param [in] field - the field to add to \a this. The field double values and mesh support are ignored. + * \param [in] arrOfVals - the values of the field \a field used. + * \param [in] mesh - the supporting mesh of \a field. + * \param [in] meshDimRelToMax - a relative dimension of mesh entities \a field lies on (useless if field spatial discretization is ON_NODES). + * \param [in] profile - ids of mesh entities on which corresponding field values lie. + * \throw If either \a field or \a mesh or \a profile has an empty name. + * \throw If there are no mesh entities of \a meshDimRelToMax dimension in \a mesh. + * \throw If the data array of \a field is not set. + * \throw If the data array of \a this is already allocated but has different number of + * components than \a field. + * \throw If elements in \a mesh are not in the order suitable for writing to the MED file. + * \sa setFieldNoProfileSBT() + */ +void MEDFileIntField1TS::setFieldProfile(const MEDCouplingFieldDouble *field, const DataArrayInt *arrOfVals, const MEDFileMesh *mesh, int meshDimRelToMax, const DataArrayInt *profile) +{ + setFileName(""); + contentNotNull()->setFieldProfile(field,arrOfVals,mesh,meshDimRelToMax,profile,*this,*contentNotNull()); +} + +const MEDFileIntField1TSWithoutSDA *MEDFileIntField1TS::contentNotNull() const +{ + const MEDFileAnyTypeField1TSWithoutSDA *pt(_content); + if(!pt) + throw INTERP_KERNEL::Exception("MEDFileIntField1TS::contentNotNull : the content pointer is null !"); + const MEDFileIntField1TSWithoutSDA *ret=dynamic_cast<const MEDFileIntField1TSWithoutSDA *>(pt); + if(!ret) + throw INTERP_KERNEL::Exception("MEDFileIntField1TS::contentNotNull : the content pointer is not null but it is not of type int32 ! Reason is maybe that the read field has not the type INT32 !"); + return ret; +} + +MEDCouplingFieldDouble *MEDFileIntField1TS::getFieldAtLevel(TypeOfField type, int meshDimRelToMax, DataArrayInt* &arrOut, int renumPol) const +{ + if(getFileName().empty()) + throw INTERP_KERNEL::Exception("MEDFileIntField1TS::getFieldAtLevel : Request for a method that can be used for instances coming from file loading ! Use getFieldOnMeshAtLevel method instead !"); + MEDCouplingAutoRefCountObjectPtr<DataArray> arrOut2; + MEDCouplingAutoRefCountObjectPtr<MEDCouplingFieldDouble> ret=contentNotNull()->getFieldAtLevel(type,meshDimRelToMax,std::string(),renumPol,this,arrOut2,*contentNotNull()); + DataArrayInt *arrOutC=dynamic_cast<DataArrayInt *>((DataArray *)arrOut2); + if(!arrOutC) + throw INTERP_KERNEL::Exception("MEDFileIntField1TS::getFieldAtLevelOld : mismatch between dataArrays type and MEDFileIntField1TS ! Expected int32 !"); + arrOut=arrOutC; + arrOut->incrRef(); // arrOut2 dies at the end of the func + return ret.retn(); +} + +DataArrayInt *MEDFileIntField1TS::ReturnSafelyDataArrayInt(MEDCouplingAutoRefCountObjectPtr<DataArray>& arr) +{ + if(!((DataArray *)arr)) + throw INTERP_KERNEL::Exception("MEDFileIntField1TS::ReturnSafelyDataArrayInt : input DataArray is NULL !"); + DataArrayInt *arrC=dynamic_cast<DataArrayInt *>((DataArray *)arr); + if(!arrC) + throw INTERP_KERNEL::Exception("MEDFileIntField1TS::ReturnSafelyDataArrayInt : input DataArray is not of type INT32 !"); + arrC->incrRef(); + return arrC; +} + +/*! + * Returns a new MEDCouplingFieldDouble of a given type lying on + * the top level cells of the first mesh in MED file. If \a this field + * has not been constructed via file reading, an exception is thrown. + * For more info, see \ref AdvMEDLoaderAPIFieldRW + * \param [in] type - a spatial discretization of interest. + * \param [out] arrOut - the DataArrayInt containing values of field. + * \param [in] renumPol - specifies how to permute values of the result field according to + * the optional numbers of cells and nodes, if any. The valid values are + * - 0 - do not permute. + * - 1 - permute cells. + * - 2 - permute nodes. + * - 3 - permute cells and nodes. + * + * \return MEDCouplingFieldDouble * - a new instance of MEDCouplingFieldDouble. The + * caller is to delete this field using decrRef() as it is no more needed. + * \throw If \a this field has not been constructed via file reading. + * \throw If the MED file is not readable. + * \throw If there is no mesh in the MED file. + * \throw If no field values of the given \a type. + * \throw If no field values lying on the top level support. + * \sa getFieldAtLevel() + */ +MEDCouplingFieldDouble *MEDFileIntField1TS::getFieldAtTopLevel(TypeOfField type, DataArrayInt* &arrOut, int renumPol) const +{ + if(getFileName().empty()) + throw INTERP_KERNEL::Exception("MEDFileField1TS::getFieldAtTopLevel : Request for a method that can be used for instances coming from file loading ! Use getFieldOnMeshAtTopLevel method instead !"); + MEDCouplingAutoRefCountObjectPtr<DataArray> arr; + MEDCouplingAutoRefCountObjectPtr<MEDCouplingFieldDouble> ret=contentNotNull()->getFieldAtTopLevel(type,std::string(),renumPol,this,arr,*contentNotNull()); + arrOut=MEDFileIntField1TS::ReturnSafelyDataArrayInt(arr); + return ret.retn(); +} + +/*! + * Returns a new MEDCouplingFieldDouble of given type lying on a given mesh. + * For more info, see \ref AdvMEDLoaderAPIFieldRW + * \param [in] type - a spatial discretization of the new field. + * \param [in] mesh - the supporting mesh. + * \param [out] arrOut - the DataArrayInt containing values of field. + * \param [in] renumPol - specifies how to permute values of the result field according to + * the optional numbers of cells and nodes, if any. The valid values are + * - 0 - do not permute. + * - 1 - permute cells. + * - 2 - permute nodes. + * - 3 - permute cells and nodes. + * + * \return MEDCouplingFieldDouble * - a new instance of MEDCouplingFieldDouble. The + * caller is to delete this field using decrRef() as it is no more needed. + * \throw If no field of \a this is lying on \a mesh. + * \throw If the mesh is empty. + * \throw If no field values of the given \a type are available. + * \sa getFieldAtLevel() + * \sa getFieldOnMeshAtLevel() + */ +MEDCouplingFieldDouble *MEDFileIntField1TS::getFieldOnMeshAtLevel(TypeOfField type, const MEDCouplingMesh *mesh, DataArrayInt* &arrOut, int renumPol) const +{ + MEDCouplingAutoRefCountObjectPtr<DataArray> arr; + MEDCouplingAutoRefCountObjectPtr<MEDCouplingFieldDouble> ret=contentNotNull()->getFieldOnMeshAtLevel(type,renumPol,this,mesh,0,0,arr,*contentNotNull()); + arrOut=MEDFileIntField1TS::ReturnSafelyDataArrayInt(arr); + return ret.retn(); +} + +/*! + * Returns a new MEDCouplingFieldDouble of a given type lying on a given support. + * For more info, see \ref AdvMEDLoaderAPIFieldRW + * \param [in] type - a spatial discretization of interest. + * \param [in] meshDimRelToMax - a relative dimension of the supporting mesh entities. + * \param [out] arrOut - the DataArrayInt containing values of field. + * \param [in] mesh - the supporting mesh. + * \param [in] renumPol - specifies how to permute values of the result field according to + * the optional numbers of cells and nodes, if any. The valid values are + * - 0 - do not permute. + * - 1 - permute cells. + * - 2 - permute nodes. + * - 3 - permute cells and nodes. + * + * \return MEDCouplingFieldDouble * - a new instance of MEDCouplingFieldDouble. The + * caller is to delete this field using decrRef() as it is no more needed. + * \throw If there are no mesh entities of \a meshDimRelToMax dimension in the mesh. + * \throw If no field of \a this is lying on \a mesh. + * \throw If no field values of the given \a type or given \a meshDimRelToMax are available. + * \sa getFieldAtLevel() + * \sa getFieldOnMeshAtLevel() + */ +MEDCouplingFieldDouble *MEDFileIntField1TS::getFieldOnMeshAtLevel(TypeOfField type, int meshDimRelToMax, const MEDFileMesh *mesh, DataArrayInt* &arrOut, int renumPol) const +{ + MEDCouplingAutoRefCountObjectPtr<DataArray> arr; + MEDCouplingAutoRefCountObjectPtr<MEDCouplingFieldDouble> ret=contentNotNull()->getFieldOnMeshAtLevel(type,meshDimRelToMax,renumPol,this,mesh,arr,*contentNotNull()); + arrOut=MEDFileIntField1TS::ReturnSafelyDataArrayInt(arr); + return ret.retn(); +} + +/*! + * Returns a new MEDCouplingFieldDouble of a given type lying on a given support. + * This method is called "Old" because in MED3 norm a field has only one meshName + * attached, so this method is for readers of MED2 files. If \a this field + * has not been constructed via file reading, an exception is thrown. + * For more info, see \ref AdvMEDLoaderAPIFieldRW + * \param [in] type - a spatial discretization of interest. + * \param [in] mName - a name of the supporting mesh. + * \param [in] meshDimRelToMax - a relative dimension of the supporting mesh entities. + * \param [out] arrOut - the DataArrayInt containing values of field. + * \param [in] renumPol - specifies how to permute values of the result field according to + * the optional numbers of cells and nodes, if any. The valid values are + * - 0 - do not permute. + * - 1 - permute cells. + * - 2 - permute nodes. + * - 3 - permute cells and nodes. + * + * \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 MED file is not readable. + * \throw If there is no mesh named \a mName in the MED file. + * \throw If there are no mesh entities of \a meshDimRelToMax dimension in the mesh. + * \throw If \a this field has not been constructed via file reading. + * \throw If no field of \a this is lying on the mesh named \a mName. + * \throw If no field values of the given \a type or given \a meshDimRelToMax are available. + * \sa getFieldAtLevel() + */ +MEDCouplingFieldDouble *MEDFileIntField1TS::getFieldAtLevelOld(TypeOfField type, const std::string& mname, int meshDimRelToMax, DataArrayInt* &arrOut, int renumPol) const +{ + if(getFileName().empty()) + throw INTERP_KERNEL::Exception("MEDFileField1TS::getFieldAtLevelOld : Request for a method that can be used for instances coming from file loading ! Use getFieldOnMeshAtLevel method instead !"); + MEDCouplingAutoRefCountObjectPtr<DataArray> arr; + MEDCouplingAutoRefCountObjectPtr<MEDCouplingFieldDouble> ret=contentNotNull()->getFieldAtLevel(type,meshDimRelToMax,mname,renumPol,this,arr,*contentNotNull()); + arrOut=MEDFileIntField1TS::ReturnSafelyDataArrayInt(arr); + return ret.retn(); +} + +/*! + * Returns values and a profile of the field of a given type lying on a given support. + * For more info, see \ref AdvMEDLoaderAPIFieldRW + * \param [in] type - a spatial discretization of the field. + * \param [in] meshDimRelToMax - a relative dimension of the supporting mesh entities. + * \param [in] mesh - the supporting mesh. + * \param [out] pfl - a new instance of DataArrayInt holding ids of mesh entities the + * field of interest lies on. If the field lies on all entities of the given + * dimension, all ids in \a pfl are zero. The caller is to delete this array + * using decrRef() as it is no more needed. + * \return DataArrayInt * - a new instance of DataArrayInt holding values of the + * field. The caller is to delete this array using decrRef() as it is no more needed. + * \throw If there are no mesh entities of \a meshDimRelToMax dimension in \a mesh. + * \throw If no field of \a this is lying on \a mesh. + * \throw If no field values of the given \a type or given \a meshDimRelToMax are available. + */ +DataArrayInt *MEDFileIntField1TS::getFieldWithProfile(TypeOfField type, int meshDimRelToMax, const MEDFileMesh *mesh, DataArrayInt *&pfl) const +{ + MEDCouplingAutoRefCountObjectPtr<DataArray> arr=contentNotNull()->getFieldWithProfile(type,meshDimRelToMax,mesh,pfl,this,*contentNotNull()); + return MEDFileIntField1TS::ReturnSafelyDataArrayInt(arr); +} + +MEDFileIntField1TSWithoutSDA *MEDFileIntField1TS::contentNotNull() +{ + MEDFileAnyTypeField1TSWithoutSDA *pt(_content); + if(!pt) + throw INTERP_KERNEL::Exception("MEDFileIntField1TS::contentNotNull : the non const content pointer is null !"); + MEDFileIntField1TSWithoutSDA *ret=dynamic_cast<MEDFileIntField1TSWithoutSDA *>(pt); + if(!ret) + throw INTERP_KERNEL::Exception("MEDFileIntField1TS::contentNotNull : the non const content pointer is not null but it is not of type int32 ! Reason is maybe that the read field has not the type INT32 !"); + return ret; +} + +DataArrayInt *MEDFileIntField1TS::getUndergroundDataArray() const +{ + return contentNotNull()->getUndergroundDataArrayInt(); +} + +//= MEDFileAnyTypeFieldMultiTSWithoutSDA + +MEDFileAnyTypeFieldMultiTSWithoutSDA::MEDFileAnyTypeFieldMultiTSWithoutSDA() +{ +} + +MEDFileAnyTypeFieldMultiTSWithoutSDA::MEDFileAnyTypeFieldMultiTSWithoutSDA(const std::string& fieldName):MEDFileFieldNameScope(fieldName) +{ +} + +/*! + * \param [in] fieldId field id in C mode + */ +MEDFileAnyTypeFieldMultiTSWithoutSDA::MEDFileAnyTypeFieldMultiTSWithoutSDA(med_idt fid, int fieldId, bool loadAll, const MEDFileMeshes *ms, const std::vector< std::pair<TypeOfField,INTERP_KERNEL::NormalizedCellType> > *entities) +{ + med_field_type typcha; + std::string dtunitOut; + int nbOfStep=MEDFileAnyTypeField1TS::LocateField2(fid,"",fieldId,false,_name,typcha,_infos,dtunitOut); + setDtUnit(dtunitOut.c_str()); + loadStructureOrStructureAndBigArraysRecursively(fid,nbOfStep,typcha,loadAll,ms,entities); +} + +MEDFileAnyTypeFieldMultiTSWithoutSDA::MEDFileAnyTypeFieldMultiTSWithoutSDA(med_idt fid, const std::string& fieldName, med_field_type fieldTyp, const std::vector<std::string>& infos, int nbOfStep, const std::string& dtunit, bool loadAll, const MEDFileMeshes *ms, const std::vector< std::pair<TypeOfField,INTERP_KERNEL::NormalizedCellType> > *entities) +try:MEDFileFieldNameScope(fieldName),_infos(infos) +{ + setDtUnit(dtunit.c_str()); + loadStructureOrStructureAndBigArraysRecursively(fid,nbOfStep,fieldTyp,loadAll,ms,entities); +} +catch(INTERP_KERNEL::Exception& e) +{ + throw e; +} + +std::size_t MEDFileAnyTypeFieldMultiTSWithoutSDA::getHeapMemorySizeWithoutChildren() const +{ + std::size_t ret(_name.capacity()+_infos.capacity()*sizeof(std::string)+_time_steps.capacity()*sizeof(MEDCouplingAutoRefCountObjectPtr<MEDFileField1TSWithoutSDA>)); + for(std::vector<std::string>::const_iterator it=_infos.begin();it!=_infos.end();it++) + ret+=(*it).capacity(); + return ret; +} + +std::vector<const BigMemoryObject *> MEDFileAnyTypeFieldMultiTSWithoutSDA::getDirectChildrenWithNull() const +{ + std::vector<const BigMemoryObject *> ret; + for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileAnyTypeField1TSWithoutSDA> >::const_iterator it=_time_steps.begin();it!=_time_steps.end();it++) + ret.push_back((const MEDFileAnyTypeField1TSWithoutSDA *)*it); + return ret; +} + +/*! + * If one of the id in [ \a startIds , \a endIds ) points to a null element, there is not throw. Simply, this empty element is added as if it were not + * NULL. + */ +MEDFileAnyTypeFieldMultiTSWithoutSDA *MEDFileAnyTypeFieldMultiTSWithoutSDA::buildFromTimeStepIds(const int *startIds, const int *endIds) const +{ + MEDCouplingAutoRefCountObjectPtr<MEDFileAnyTypeFieldMultiTSWithoutSDA> ret=createNew(); + ret->setInfo(_infos); + int sz=(int)_time_steps.size(); + for(const int *id=startIds;id!=endIds;id++) + { + if(*id>=0 && *id<sz) + { + const MEDFileAnyTypeField1TSWithoutSDA *tse=_time_steps[*id]; + MEDCouplingAutoRefCountObjectPtr<MEDFileAnyTypeField1TSWithoutSDA> tse2; + if(tse) + { + tse->incrRef(); + tse2=(const_cast<MEDFileAnyTypeField1TSWithoutSDA *>(tse)); + } + ret->pushBackTimeStep(tse2); + } + else + { + std::ostringstream oss; oss << "MEDFileAnyTypeFieldMultiTSWithoutSDA::buildFromTimeStepIds : At pos #" << std::distance(startIds,id) << " value is " << *id; + oss << " ! Should be in [0," << sz << ") !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + } + if(ret->getNumberOfTS()>0) + ret->synchronizeNameScope(); + ret->copyNameScope(*this); + return ret.retn(); +} + +/*! + * If one of the id in the input range points to a null element, there is not throw. Simply, this empty element is added as if it were not + * NULL. + */ +MEDFileAnyTypeFieldMultiTSWithoutSDA *MEDFileAnyTypeFieldMultiTSWithoutSDA::buildFromTimeStepIds2(int bg, int end, int step) const +{ + static const char msg[]="MEDFileAnyTypeFieldMultiTSWithoutSDA::buildFromTimeStepIds2"; + int nbOfEntriesToKeep=DataArrayInt::GetNumberOfItemGivenBESRelative(bg,end,step,msg); + MEDCouplingAutoRefCountObjectPtr<MEDFileAnyTypeFieldMultiTSWithoutSDA> ret=createNew(); + ret->setInfo(_infos); + int sz=(int)_time_steps.size(); + int j=bg; + for(int i=0;i<nbOfEntriesToKeep;i++,j+=step) + { + if(j>=0 && j<sz) + { + const MEDFileAnyTypeField1TSWithoutSDA *tse=_time_steps[j]; + MEDCouplingAutoRefCountObjectPtr<MEDFileAnyTypeField1TSWithoutSDA> tse2; + if(tse) + { + tse->incrRef(); + tse2=(const_cast<MEDFileAnyTypeField1TSWithoutSDA *>(tse)); + } + ret->pushBackTimeStep(tse2); + } + else + { + std::ostringstream oss; oss << "MEDFileAnyTypeFieldMultiTSWithoutSDA::buildFromTimeStepIds : At pos #" << i << " value is " << j; + oss << " ! Should be in [0," << sz << ") !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + } + if(ret->getNumberOfTS()>0) + ret->synchronizeNameScope(); + ret->copyNameScope(*this); + return ret.retn(); +} + +MEDFileAnyTypeFieldMultiTSWithoutSDA *MEDFileAnyTypeFieldMultiTSWithoutSDA::partOfThisLyingOnSpecifiedTimeSteps(const std::vector< std::pair<int,int> >& timeSteps) const +{ + int id=0; + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ids=DataArrayInt::New(); ids->alloc(0,1); + for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileAnyTypeField1TSWithoutSDA> >::const_iterator it=_time_steps.begin();it!=_time_steps.end();it++,id++) + { + const MEDFileAnyTypeField1TSWithoutSDA *cur(*it); + if(!cur) + continue; + std::pair<int,int> p(cur->getIteration(),cur->getOrder()); + if(std::find(timeSteps.begin(),timeSteps.end(),p)!=timeSteps.end()) + ids->pushBackSilent(id); + } + return buildFromTimeStepIds(ids->begin(),ids->end()); +} + +MEDFileAnyTypeFieldMultiTSWithoutSDA *MEDFileAnyTypeFieldMultiTSWithoutSDA::partOfThisNotLyingOnSpecifiedTimeSteps(const std::vector< std::pair<int,int> >& timeSteps) const +{ + int id=0; + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ids=DataArrayInt::New(); ids->alloc(0,1); + for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileAnyTypeField1TSWithoutSDA> >::const_iterator it=_time_steps.begin();it!=_time_steps.end();it++,id++) + { + const MEDFileAnyTypeField1TSWithoutSDA *cur(*it); + if(!cur) + continue; + std::pair<int,int> p(cur->getIteration(),cur->getOrder()); + if(std::find(timeSteps.begin(),timeSteps.end(),p)==timeSteps.end()) + ids->pushBackSilent(id); + } + return buildFromTimeStepIds(ids->begin(),ids->end()); +} + +bool MEDFileAnyTypeFieldMultiTSWithoutSDA::presenceOfMultiDiscPerGeoType() const +{ + for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileAnyTypeField1TSWithoutSDA> >::const_iterator it=_time_steps.begin();it!=_time_steps.end();it++) + { + const MEDFileAnyTypeField1TSWithoutSDA *cur(*it); + if(!cur) + continue; + if(cur->presenceOfMultiDiscPerGeoType()) + return true; + } + return false; +} + +const std::vector<std::string>& MEDFileAnyTypeFieldMultiTSWithoutSDA::getInfo() const +{ + return _infos; +} + +void MEDFileAnyTypeFieldMultiTSWithoutSDA::setInfo(const std::vector<std::string>& info) +{ + _infos=info; +} + +int MEDFileAnyTypeFieldMultiTSWithoutSDA::getTimeStepPos(int iteration, int order) const +{ + int ret=0; + for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileAnyTypeField1TSWithoutSDA> >::const_iterator it=_time_steps.begin();it!=_time_steps.end();it++,ret++) + { + const MEDFileAnyTypeField1TSWithoutSDA *pt(*it); + if(pt->isDealingTS(iteration,order)) + return ret; + } + std::ostringstream oss; oss << "MEDFileFieldMultiTS::getTimeStepPos : Muli timestep field on time (" << iteration << "," << order << ") does not exist ! Available (iteration,order) are :\n"; + std::vector< std::pair<int,int> > vp=getIterations(); + for(std::vector< std::pair<int,int> >::const_iterator it2=vp.begin();it2!=vp.end();it2++) + oss << "(" << (*it2).first << "," << (*it2).second << ") "; + throw INTERP_KERNEL::Exception(oss.str().c_str()); +} + +const MEDFileAnyTypeField1TSWithoutSDA& MEDFileAnyTypeFieldMultiTSWithoutSDA::getTimeStepEntry(int iteration, int order) const +{ + return *_time_steps[getTimeStepPos(iteration,order)]; +} + +MEDFileAnyTypeField1TSWithoutSDA& MEDFileAnyTypeFieldMultiTSWithoutSDA::getTimeStepEntry(int iteration, int order) +{ + return *_time_steps[getTimeStepPos(iteration,order)]; +} + +std::string MEDFileAnyTypeFieldMultiTSWithoutSDA::getMeshName() const +{ + if(_time_steps.empty()) + throw INTERP_KERNEL::Exception("MEDFileFieldMultiTSWithoutSDA::getMeshName : not time steps !"); + return _time_steps[0]->getMeshName(); +} + +void MEDFileAnyTypeFieldMultiTSWithoutSDA::setMeshName(const std::string& newMeshName) +{ + std::string oldName(getMeshName()); + std::vector< std::pair<std::string,std::string> > v(1); + v[0].first=oldName; v[0].second=newMeshName; + changeMeshNames(v); +} + +bool MEDFileAnyTypeFieldMultiTSWithoutSDA::changeMeshNames(const std::vector< std::pair<std::string,std::string> >& modifTab) +{ + bool ret=false; + for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileAnyTypeField1TSWithoutSDA> >::iterator it=_time_steps.begin();it!=_time_steps.end();it++) + { + MEDFileAnyTypeField1TSWithoutSDA *cur(*it); + if(cur) + ret=cur->changeMeshNames(modifTab) || ret; + } + return ret; +} + +/*! + * See doc at MEDFileField1TSWithoutSDA::getUndergroundDataArray + */ +DataArray *MEDFileAnyTypeFieldMultiTSWithoutSDA::getUndergroundDataArray(int iteration, int order) const +{ + return getTimeStepEntry(iteration,order).getUndergroundDataArray(); +} + +/*! + * See doc at MEDFileField1TSWithoutSDA::getUndergroundDataArrayExt + */ +DataArray *MEDFileAnyTypeFieldMultiTSWithoutSDA::getUndergroundDataArrayExt(int iteration, int order, std::vector< std::pair<std::pair<INTERP_KERNEL::NormalizedCellType,int>,std::pair<int,int> > >& entries) const +{ + return getTimeStepEntry(iteration,order).getUndergroundDataArrayExt(entries); +} + +bool MEDFileAnyTypeFieldMultiTSWithoutSDA::renumberEntitiesLyingOnMesh(const std::string& meshName, const std::vector<int>& oldCode, const std::vector<int>& newCode, const DataArrayInt *renumO2N, + MEDFileFieldGlobsReal& glob) +{ + bool ret=false; + for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileAnyTypeField1TSWithoutSDA> >::iterator it=_time_steps.begin();it!=_time_steps.end();it++) + { + MEDFileAnyTypeField1TSWithoutSDA *f1ts(*it); + if(f1ts) + ret=f1ts->renumberEntitiesLyingOnMesh(meshName,oldCode,newCode,renumO2N,glob) || ret; + } + return ret; +} + +void MEDFileAnyTypeFieldMultiTSWithoutSDA::simpleRepr(int bkOffset, std::ostream& oss, int fmtsId) const +{ + std::string startLine(bkOffset,' '); + oss << startLine << "Field multi time steps [Type=" << getTypeStr() << "]"; + if(fmtsId>=0) + oss << " (" << fmtsId << ")"; + oss << " has the following name: \"" << _name << "\"." << std::endl; + oss << startLine << "Field multi time steps has " << _infos.size() << " components with the following infos :" << std::endl; + for(std::vector<std::string>::const_iterator it=_infos.begin();it!=_infos.end();it++) + { + oss << startLine << " - \"" << *it << "\"" << std::endl; + } + int i=0; + for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileAnyTypeField1TSWithoutSDA> >::const_iterator it=_time_steps.begin();it!=_time_steps.end();it++,i++) + { + std::string chapter(17,'0'+i); + oss << startLine << chapter << std::endl; + const MEDFileAnyTypeField1TSWithoutSDA *cur=(*it); + if(cur) + cur->simpleRepr(bkOffset+2,oss,i); + else + oss << startLine << " Field on one time step #" << i << " is not defined !" << std::endl; + oss << startLine << chapter << std::endl; + } +} + +std::vector< std::pair<int,int> > MEDFileAnyTypeFieldMultiTSWithoutSDA::getTimeSteps(std::vector<double>& ret1) const +{ + std::size_t sz=_time_steps.size(); + std::vector< std::pair<int,int> > ret(sz); + ret1.resize(sz); + for(std::size_t i=0;i<sz;i++) + { + const MEDFileAnyTypeField1TSWithoutSDA *f1ts=_time_steps[i]; + if(f1ts) + { + ret1[i]=f1ts->getTime(ret[i].first,ret[i].second); + } + else + { + std::ostringstream oss; oss << "MEDFileFieldMultiTSWithoutSDA::getTimeSteps : At rank #" << i << " time step is not defined. Invoke eraseEmptyTS method !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + } + return ret; +} + +void MEDFileAnyTypeFieldMultiTSWithoutSDA::pushBackTimeStep(MEDCouplingAutoRefCountObjectPtr<MEDFileAnyTypeField1TSWithoutSDA>& tse) +{ + MEDFileAnyTypeField1TSWithoutSDA *tse2(tse); + if(!tse2) + throw INTERP_KERNEL::Exception("MEDFileAnyTypeFieldMultiTSWithoutSDA::pushBackTimeStep : input content object is null !"); + checkCoherencyOfType(tse2); + if(_time_steps.empty()) + { + setName(tse2->getName().c_str()); + setInfo(tse2->getInfo()); + } + checkThatComponentsMatch(tse2->getInfo()); + _time_steps.push_back(tse); +} + +void MEDFileAnyTypeFieldMultiTSWithoutSDA::synchronizeNameScope() +{ + std::size_t nbOfCompo=_infos.size(); + for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileAnyTypeField1TSWithoutSDA> >::iterator it=_time_steps.begin();it!=_time_steps.end();it++) + { + MEDFileAnyTypeField1TSWithoutSDA *cur=(*it); + if(cur) + { + if((cur->getInfo()).size()!=nbOfCompo) + { + std::ostringstream oss; oss << "MEDFileAnyTypeFieldMultiTSWithoutSDA::synchronizeNameScope : Mismatch in the number of components of parts ! Should be " << nbOfCompo; + oss << " ! but the field at iteration=" << cur->getIteration() << " order=" << cur->getOrder() << " has " << (cur->getInfo()).size() << " components !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + cur->copyNameScope(*this); + } + } +} + +void MEDFileAnyTypeFieldMultiTSWithoutSDA::loadStructureOrStructureAndBigArraysRecursively(med_idt fid, int nbPdt, med_field_type fieldTyp, bool loadAll, const MEDFileMeshes *ms, const std::vector< std::pair<TypeOfField,INTERP_KERNEL::NormalizedCellType> > *entities) +{ + _time_steps.resize(nbPdt); + for(int i=0;i<nbPdt;i++) + { + std::vector< std::pair<int,int> > ts; + med_int numdt=0,numo=0; + med_int meshIt=0,meshOrder=0; + med_float dt=0.0; + MEDFILESAFECALLERRD0(MEDfieldComputingStepMeshInfo,(fid,_name.c_str(),i+1,&numdt,&numo,&dt,&meshIt,&meshOrder)); + switch(fieldTyp) + { + case MED_FLOAT64: + { + _time_steps[i]=MEDFileField1TSWithoutSDA::New(_name.c_str(),i+1,numdt,numo,_infos); + break; + } + case MED_INT32: + { + _time_steps[i]=MEDFileIntField1TSWithoutSDA::New(_name.c_str(),i+1,numdt,numo,_infos); + break; + } + default: + throw INTERP_KERNEL::Exception("MEDFileAnyTypeFieldMultiTSWithoutSDA::loadStructureOrStructureAndBigArraysRecursively : managed field type are : FLOAT64, INT32 !"); + } + if(loadAll) + _time_steps[i]->loadStructureAndBigArraysRecursively(fid,*this,ms,entities); + else + _time_steps[i]->loadOnlyStructureOfDataRecursively(fid,*this,ms,entities); + } +} + +void MEDFileAnyTypeFieldMultiTSWithoutSDA::writeLL(med_idt fid, const MEDFileWritable& opts) const +{ + if(_time_steps.empty()) + throw INTERP_KERNEL::Exception("MEDFileFieldMultiTSWithoutSDA::writeLL : no time steps set !"); + checkThatNbOfCompoOfTSMatchThis(); + std::vector<std::string> infos(getInfo()); + int nbComp=infos.size(); + INTERP_KERNEL::AutoPtr<char> comp=MEDLoaderBase::buildEmptyString(nbComp*MED_SNAME_SIZE); + INTERP_KERNEL::AutoPtr<char> unit=MEDLoaderBase::buildEmptyString(nbComp*MED_SNAME_SIZE); + for(int i=0;i<nbComp;i++) + { + std::string info=infos[i]; + std::string c,u; + MEDLoaderBase::splitIntoNameAndUnit(info,c,u); + MEDLoaderBase::safeStrCpy2(c.c_str(),MED_SNAME_SIZE,comp+i*MED_SNAME_SIZE,opts.getTooLongStrPolicy()); + MEDLoaderBase::safeStrCpy2(u.c_str(),MED_SNAME_SIZE,unit+i*MED_SNAME_SIZE,opts.getTooLongStrPolicy()); + } + if(_name.empty()) + throw INTERP_KERNEL::Exception("MEDFileFieldMultiTSWithoutSDA::write : MED file does not accept field with empty name !"); + MEDFILESAFECALLERWR0(MEDfieldCr,(fid,_name.c_str(),getMEDFileFieldType(),nbComp,comp,unit,getDtUnit().c_str(),getMeshName().c_str())); + int nbOfTS=_time_steps.size(); + for(int i=0;i<nbOfTS;i++) + _time_steps[i]->writeLL(fid,opts,*this); +} + +void MEDFileAnyTypeFieldMultiTSWithoutSDA::loadBigArraysRecursively(med_idt fid, const MEDFileFieldNameScope& nasc) +{ + for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileAnyTypeField1TSWithoutSDA> >::iterator it=_time_steps.begin();it!=_time_steps.end();it++) + { + MEDFileAnyTypeField1TSWithoutSDA *elt(*it); + if(elt) + elt->loadBigArraysRecursively(fid,nasc); + } +} + +void MEDFileAnyTypeFieldMultiTSWithoutSDA::loadBigArraysRecursivelyIfNecessary(med_idt fid, const MEDFileFieldNameScope& nasc) +{ + for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileAnyTypeField1TSWithoutSDA> >::iterator it=_time_steps.begin();it!=_time_steps.end();it++) + { + MEDFileAnyTypeField1TSWithoutSDA *elt(*it); + if(elt) + elt->loadBigArraysRecursivelyIfNecessary(fid,nasc); + } +} + +void MEDFileAnyTypeFieldMultiTSWithoutSDA::unloadArrays() +{ + for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileAnyTypeField1TSWithoutSDA> >::iterator it=_time_steps.begin();it!=_time_steps.end();it++) + { + MEDFileAnyTypeField1TSWithoutSDA *elt(*it); + if(elt) + elt->unloadArrays(); + } +} + +int MEDFileAnyTypeFieldMultiTSWithoutSDA::getNumberOfTS() const +{ + return _time_steps.size(); +} + +void MEDFileAnyTypeFieldMultiTSWithoutSDA::eraseEmptyTS() +{ + std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileAnyTypeField1TSWithoutSDA> > newTS; + for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileAnyTypeField1TSWithoutSDA> >::const_iterator it=_time_steps.begin();it!=_time_steps.end();it++) + { + const MEDFileAnyTypeField1TSWithoutSDA *tmp=(*it); + if(tmp) + newTS.push_back(*it); + } + _time_steps=newTS; +} + +void MEDFileAnyTypeFieldMultiTSWithoutSDA::eraseTimeStepIds(const int *startIds, const int *endIds) +{ + std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileAnyTypeField1TSWithoutSDA> > newTS; + int maxId=(int)_time_steps.size(); + int ii=0; + std::set<int> idsToDel; + for(const int *id=startIds;id!=endIds;id++,ii++) + { + if(*id>=0 && *id<maxId) + { + idsToDel.insert(*id); + } + else + { + std::ostringstream oss; oss << "MEDFileFieldMultiTSWithoutSDA::eraseTimeStepIds : At pos #" << ii << " request for id=" << *id << " not in [0," << maxId << ") !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + } + for(int iii=0;iii<maxId;iii++) + if(idsToDel.find(iii)==idsToDel.end()) + newTS.push_back(_time_steps[iii]); + _time_steps=newTS; +} + +void MEDFileAnyTypeFieldMultiTSWithoutSDA::eraseTimeStepIds2(int bg, int end, int step) +{ + static const char msg[]="MEDFileAnyTypeFieldMultiTSWithoutSDA::eraseTimeStepIds2"; + int nbOfEntriesToKill=DataArrayInt::GetNumberOfItemGivenBESRelative(bg,end,step,msg); + if(nbOfEntriesToKill==0) + return ; + std::size_t sz=_time_steps.size(); + std::vector<bool> b(sz,true); + int j=bg; + for(int i=0;i<nbOfEntriesToKill;i++,j+=step) + b[j]=false; + std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileAnyTypeField1TSWithoutSDA> > newTS; + for(std::size_t i=0;i<sz;i++) + if(b[i]) + newTS.push_back(_time_steps[i]); + _time_steps=newTS; +} + +int MEDFileAnyTypeFieldMultiTSWithoutSDA::getPosOfTimeStep(int iteration, int order) const +{ + int ret=0; + std::ostringstream oss; oss << "MEDFileFieldMultiTSWithoutSDA::getPosOfTimeStep : No such time step (" << iteration << "," << order << ") !\nPossibilities are : "; + for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileAnyTypeField1TSWithoutSDA> >::const_iterator it=_time_steps.begin();it!=_time_steps.end();it++,ret++) + { + const MEDFileAnyTypeField1TSWithoutSDA *tmp(*it); + if(tmp) + { + int it2,ord; + tmp->getTime(it2,ord); + if(it2==iteration && order==ord) + return ret; + else + oss << "(" << it2 << "," << ord << "), "; + } + } + throw INTERP_KERNEL::Exception(oss.str().c_str()); +} + +int MEDFileAnyTypeFieldMultiTSWithoutSDA::getPosGivenTime(double time, double eps) const +{ + int ret=0; + std::ostringstream oss; oss << "MEDFileFieldMultiTSWithoutSDA::getPosGivenTime : No such time step " << time << "! \nPossibilities are : "; + oss.precision(15); + for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileAnyTypeField1TSWithoutSDA> >::const_iterator it=_time_steps.begin();it!=_time_steps.end();it++,ret++) + { + const MEDFileAnyTypeField1TSWithoutSDA *tmp(*it); + if(tmp) + { + int it2,ord; + double ti=tmp->getTime(it2,ord); + if(fabs(time-ti)<eps) + return ret; + else + oss << ti << ", "; + } + } + throw INTERP_KERNEL::Exception(oss.str().c_str()); +} + +std::vector< std::pair<int,int> > MEDFileAnyTypeFieldMultiTSWithoutSDA::getIterations() const +{ + int lgth=_time_steps.size(); + std::vector< std::pair<int,int> > ret(lgth); + for(int i=0;i<lgth;i++) + _time_steps[i]->fillIteration(ret[i]); + return ret; +} + +/*! + * This method has 3 inputs 'iteration' 'order' 'mname'. 'mname' can be null if the user is the general case where there is only one meshName lying on 'this' + * This method returns two things. + * - The absolute dimension of 'this' in first parameter. + * - The available ext levels relative to the absolute dimension returned in first parameter. These relative levels are relative + * to the first output parameter. The values in 'levs' will be returned in decreasing order. + * + * This method is designed for MEDFileFieldMultiTS instances that have a discritization ON_CELLS, ON_GAUSS_NE and ON_GAUSS. + * Only these 3 discretizations will be taken into account here. + * + * If 'this' is empty this method will throw an INTERP_KERNEL::Exception. + * If there is \b only node fields defined in 'this' -1 is returned and 'levs' output parameter will be empty. In this + * case the caller has to know the underlying mesh it refers to. By defaut it is the level 0 of the corresponding mesh. + * + * This method is usefull to make the link between meshDimension of the underlying mesh in 'this' and the levels on 'this'. + * It is possible (even if it is not common) that the highest level in 'this' were not equal to the meshDimension of the underlying mesh in 'this'. + * + * Let's consider the typical following case : + * - a mesh 'm1' has a meshDimension 3 and has the following non empty levels + * [0,-1,-2] for example 'm1' lies on TETRA4, HEXA8 TRI3 and SEG2 + * - 'f1' lies on 'm1' and is defined on 3D and 1D cells for example + * TETRA4 and SEG2 + * - 'f2' lies on 'm1' too and is defined on 2D and 1D cells for example TRI3 and SEG2 + * + * In this case f1->getNonEmptyLevelsExt will return (3,[0,-2]) and f2->getNonEmptyLevelsExt will return (2,[0,-1]) + * + * To retrieve the highest level of f1 it should be done, f1->getFieldAtLevel(ON_CELLS,3-3+0);//absDim-meshDim+relativeLev + * To retrieve the lowest level of f1 it should be done, f1->getFieldAtLevel(ON_CELLS,3-3+(-2));//absDim-meshDim+relativeLev + * To retrieve the highest level of f2 it should be done, f1->getFieldAtLevel(ON_CELLS,2-3+0);//absDim-meshDim+relativeLev + * To retrieve the lowest level of f2 it should be done, f1->getFieldAtLevel(ON_CELLS,2-3+(-1));//absDim-meshDim+relativeLev + */ +int MEDFileAnyTypeFieldMultiTSWithoutSDA::getNonEmptyLevels(int iteration, int order, const std::string& mname, std::vector<int>& levs) const +{ + return getTimeStepEntry(iteration,order).getNonEmptyLevels(mname,levs); +} + +const MEDFileAnyTypeField1TSWithoutSDA *MEDFileAnyTypeFieldMultiTSWithoutSDA::getTimeStepAtPos2(int pos) const +{ + if(pos<0 || pos>=(int)_time_steps.size()) + { + std::ostringstream oss; oss << "MEDFileAnyTypeFieldMultiTSWithoutSDA::getTimeStepAtPos2 : request for pos #" << pos << " whereas should be in [0," << _time_steps.size() << ") !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + const MEDFileAnyTypeField1TSWithoutSDA *item=_time_steps[pos]; + if(item==0) + { + std::ostringstream oss; oss << "MEDFileAnyTypeFieldMultiTSWithoutSDA::getTimeStepAtPos2 : request for pos #" << pos << ", this pos id exists but the underlying Field1TS is null !"; + oss << "\nTry to use following method eraseEmptyTS !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + return item; +} + +MEDFileAnyTypeField1TSWithoutSDA *MEDFileAnyTypeFieldMultiTSWithoutSDA::getTimeStepAtPos2(int pos) +{ + if(pos<0 || pos>=(int)_time_steps.size()) + { + std::ostringstream oss; oss << "MEDFileAnyTypeFieldMultiTSWithoutSDA::getTimeStepAtPos2 : request for pos #" << pos << " whereas should be in [0," << _time_steps.size() << ") !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + MEDFileAnyTypeField1TSWithoutSDA *item=_time_steps[pos]; + if(item==0) + { + std::ostringstream oss; oss << "MEDFileAnyTypeFieldMultiTSWithoutSDA::getTimeStepAtPos2 : request for pos #" << pos << ", this pos id exists but the underlying Field1TS is null !"; + oss << "\nTry to use following method eraseEmptyTS !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + return item; +} + +std::vector<std::string> MEDFileAnyTypeFieldMultiTSWithoutSDA::getPflsReallyUsed2() const +{ + std::vector<std::string> ret; + std::set<std::string> ret2; + for(std::vector< MEDCouplingAutoRefCountObjectPtr< MEDFileAnyTypeField1TSWithoutSDA > >::const_iterator it=_time_steps.begin();it!=_time_steps.end();it++) + { + std::vector<std::string> tmp=(*it)->getPflsReallyUsed2(); + for(std::vector<std::string>::const_iterator it2=tmp.begin();it2!=tmp.end();it2++) + if(ret2.find(*it2)==ret2.end()) + { + ret.push_back(*it2); + ret2.insert(*it2); + } + } + return ret; +} + +std::vector<std::string> MEDFileAnyTypeFieldMultiTSWithoutSDA::getLocsReallyUsed2() const +{ + std::vector<std::string> ret; + std::set<std::string> ret2; + for(std::vector< MEDCouplingAutoRefCountObjectPtr< MEDFileAnyTypeField1TSWithoutSDA > >::const_iterator it=_time_steps.begin();it!=_time_steps.end();it++) + { + std::vector<std::string> tmp=(*it)->getLocsReallyUsed2(); + for(std::vector<std::string>::const_iterator it2=tmp.begin();it2!=tmp.end();it2++) + if(ret2.find(*it2)==ret2.end()) + { + ret.push_back(*it2); + ret2.insert(*it2); + } + } + return ret; +} + +std::vector<std::string> MEDFileAnyTypeFieldMultiTSWithoutSDA::getPflsReallyUsedMulti2() const +{ + std::vector<std::string> ret; + for(std::vector< MEDCouplingAutoRefCountObjectPtr< MEDFileAnyTypeField1TSWithoutSDA > >::const_iterator it=_time_steps.begin();it!=_time_steps.end();it++) + { + std::vector<std::string> tmp=(*it)->getPflsReallyUsedMulti2(); + ret.insert(ret.end(),tmp.begin(),tmp.end()); + } + return ret; +} + +std::vector<std::string> MEDFileAnyTypeFieldMultiTSWithoutSDA::getLocsReallyUsedMulti2() const +{ + std::vector<std::string> ret; + for(std::vector< MEDCouplingAutoRefCountObjectPtr< MEDFileAnyTypeField1TSWithoutSDA > >::const_iterator it=_time_steps.begin();it!=_time_steps.end();it++) + { + std::vector<std::string> tmp=(*it)->getLocsReallyUsedMulti2(); + ret.insert(ret.end(),tmp.begin(),tmp.end()); + } + return ret; +} + +void MEDFileAnyTypeFieldMultiTSWithoutSDA::changePflsRefsNamesGen2(const std::vector< std::pair<std::vector<std::string>, std::string > >& mapOfModif) +{ + for(std::vector< MEDCouplingAutoRefCountObjectPtr< MEDFileAnyTypeField1TSWithoutSDA > >::iterator it=_time_steps.begin();it!=_time_steps.end();it++) + (*it)->changePflsRefsNamesGen2(mapOfModif); +} + +void MEDFileAnyTypeFieldMultiTSWithoutSDA::changeLocsRefsNamesGen2(const std::vector< std::pair<std::vector<std::string>, std::string > >& mapOfModif) +{ + for(std::vector< MEDCouplingAutoRefCountObjectPtr< MEDFileAnyTypeField1TSWithoutSDA > >::iterator it=_time_steps.begin();it!=_time_steps.end();it++) + (*it)->changeLocsRefsNamesGen2(mapOfModif); +} + +std::vector< std::vector<TypeOfField> > MEDFileAnyTypeFieldMultiTSWithoutSDA::getTypesOfFieldAvailable() const +{ + int lgth=_time_steps.size(); + std::vector< std::vector<TypeOfField> > ret(lgth); + for(int i=0;i<lgth;i++) + _time_steps[i]->fillTypesOfFieldAvailable(ret[i]); + return ret; +} + +/*! + * entry point for users that want to iterate into MEDFile DataStructure without any overhead. + */ +std::vector< std::vector< std::pair<int,int> > > MEDFileAnyTypeFieldMultiTSWithoutSDA::getFieldSplitedByType(int iteration, int order, const std::string& mname, std::vector<INTERP_KERNEL::NormalizedCellType>& types, std::vector< std::vector<TypeOfField> >& typesF, std::vector< std::vector<std::string> >& pfls, std::vector< std::vector<std::string> >& locs) const +{ + return getTimeStepEntry(iteration,order).getFieldSplitedByType(mname,types,typesF,pfls,locs); +} + +MEDFileAnyTypeFieldMultiTSWithoutSDA *MEDFileAnyTypeFieldMultiTSWithoutSDA::deepCpy() const +{ + MEDCouplingAutoRefCountObjectPtr<MEDFileAnyTypeFieldMultiTSWithoutSDA> ret=shallowCpy(); + std::size_t i=0; + for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileAnyTypeField1TSWithoutSDA> >::const_iterator it=_time_steps.begin();it!=_time_steps.end();it++,i++) + { + if((const MEDFileAnyTypeField1TSWithoutSDA *)*it) + ret->_time_steps[i]=(*it)->deepCpy(); + } + return ret.retn(); +} + +std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileAnyTypeFieldMultiTSWithoutSDA> > MEDFileAnyTypeFieldMultiTSWithoutSDA::splitComponents() const +{ + std::size_t sz(_infos.size()),sz2(_time_steps.size()); + std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileAnyTypeFieldMultiTSWithoutSDA> > ret(sz); + std::vector< std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileAnyTypeField1TSWithoutSDA> > > ts(sz2); + for(std::size_t i=0;i<sz;i++) + { + ret[i]=shallowCpy(); + ret[i]->_infos.resize(1); ret[i]->_infos[0]=_infos[i]; + } + for(std::size_t i=0;i<sz2;i++) + { + std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileAnyTypeField1TSWithoutSDA> > ret1=_time_steps[i]->splitComponents(); + if(ret1.size()!=sz) + { + std::ostringstream oss; oss << "MEDFileAnyTypeFieldMultiTSWithoutSDA::splitComponents : At rank #" << i << " number of components is " << ret1.size() << " whereas it should be for all time steps " << sz << " !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + ts[i]=ret1; + } + for(std::size_t i=0;i<sz;i++) + for(std::size_t j=0;j<sz2;j++) + ret[i]->_time_steps[j]=ts[j][i]; + return ret; +} + +/*! + * This method splits into discretization each time steps in \a this. + * ** WARNING ** the returned instances are not compulsary defined on the same time steps series ! + */ +std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileAnyTypeFieldMultiTSWithoutSDA> > MEDFileAnyTypeFieldMultiTSWithoutSDA::splitDiscretizations() const +{ + std::size_t sz(_time_steps.size()); + std::vector< std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileAnyTypeField1TSWithoutSDA> > > items(sz); + for(std::size_t i=0;i<sz;i++) + { + const MEDFileAnyTypeField1TSWithoutSDA *timeStep(_time_steps[i]); + if(!timeStep) + { + std::ostringstream oss; oss << "MEDFileAnyTypeFieldMultiTSWithoutSDA::splitDiscretizations : time step #" << i << " is null !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + items[i]=timeStep->splitDiscretizations(); + } + // + std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileAnyTypeFieldMultiTSWithoutSDA> > ret; + std::vector< std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileAnyTypeField1TSWithoutSDA> > > ret2; + std::vector< TypeOfField > types; + for(std::vector< std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileAnyTypeField1TSWithoutSDA> > >::const_iterator it0=items.begin();it0!=items.end();it0++) + for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileAnyTypeField1TSWithoutSDA> >::const_iterator it1=(*it0).begin();it1!=(*it0).end();it1++) + { + std::vector<TypeOfField> ts=(*it1)->getTypesOfFieldAvailable(); + if(ts.size()!=1) + throw INTERP_KERNEL::Exception("MEDFileAnyTypeFieldMultiTSWithoutSDA::splitDiscretizations : it appears that the splitting of MEDFileAnyTypeField1TSWithoutSDA::splitDiscretizations has returned invalid result !"); + std::vector< TypeOfField >::iterator it2=std::find(types.begin(),types.end(),ts[0]); + if(it2==types.end()) + types.push_back(ts[0]); + } + ret.resize(types.size()); ret2.resize(types.size()); + for(std::vector< std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileAnyTypeField1TSWithoutSDA> > >::const_iterator it0=items.begin();it0!=items.end();it0++) + for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileAnyTypeField1TSWithoutSDA> >::const_iterator it1=(*it0).begin();it1!=(*it0).end();it1++) + { + TypeOfField typ=(*it1)->getTypesOfFieldAvailable()[0]; + std::size_t pos=std::distance(types.begin(),std::find(types.begin(),types.end(),typ)); + ret2[pos].push_back(*it1); + } + for(std::size_t i=0;i<types.size();i++) + { + MEDCouplingAutoRefCountObjectPtr<MEDFileAnyTypeFieldMultiTSWithoutSDA> elt(createNew()); + for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileAnyTypeField1TSWithoutSDA> >::iterator it1=ret2[i].begin();it1!=ret2[i].end();it1++) + elt->pushBackTimeStep(*it1);//also updates infos in elt + ret[i]=elt; + elt->MEDFileFieldNameScope::operator=(*this); + } + return ret; +} + +/*! + * Contrary to splitDiscretizations method this method makes the hypothesis that the times series are **NOT** impacted by the splitting of multi discretization. + */ +std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileAnyTypeFieldMultiTSWithoutSDA> > MEDFileAnyTypeFieldMultiTSWithoutSDA::splitMultiDiscrPerGeoTypes() const +{ + std::size_t sz(_time_steps.size()); + std::vector< std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileAnyTypeField1TSWithoutSDA> > > items(sz); + std::size_t szOut(std::numeric_limits<std::size_t>::max()); + for(std::size_t i=0;i<sz;i++) + { + const MEDFileAnyTypeField1TSWithoutSDA *timeStep(_time_steps[i]); + if(!timeStep) + { + std::ostringstream oss; oss << "MEDFileAnyTypeFieldMultiTSWithoutSDA::splitMultiDiscrPerGeoTypes : time step #" << i << " is null !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + items[i]=timeStep->splitMultiDiscrPerGeoTypes(); + if(szOut==std::numeric_limits<std::size_t>::max()) + szOut=items[i].size(); + else + if(items[i].size()!=szOut) + throw INTERP_KERNEL::Exception("MEDFileAnyTypeFieldMultiTSWithoutSDA::splitMultiDiscrPerGeoTypes : The splitting per discretization is expected to be same among time steps !"); + } + if(szOut==std::numeric_limits<std::size_t>::max()) + throw INTERP_KERNEL::Exception("MEDFileAnyTypeFieldMultiTSWithoutSDA::splitMultiDiscrPerGeoTypes : empty field !"); + std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileAnyTypeFieldMultiTSWithoutSDA> > ret(szOut); + for(std::size_t i=0;i<szOut;i++) + { + MEDCouplingAutoRefCountObjectPtr<MEDFileAnyTypeFieldMultiTSWithoutSDA> elt(createNew()); + for(std::size_t j=0;j<sz;j++) + elt->pushBackTimeStep(items[j][i]); + ret[i]=elt; + elt->MEDFileFieldNameScope::operator=(*this); + } + return ret; +} + +void MEDFileAnyTypeFieldMultiTSWithoutSDA::copyTinyInfoFrom(const MEDCouplingFieldDouble *field, const DataArray *arr) +{ + _name=field->getName(); + if(_name.empty()) + throw INTERP_KERNEL::Exception("MEDFileFieldMultiTSWithoutSDA::copyTinyInfoFrom : unsupported fields with no name in MED file !"); + if(!arr) + throw INTERP_KERNEL::Exception("MEDFileFieldMultiTSWithoutSDA::copyTinyInfoFrom : no array set !"); + _infos=arr->getInfoOnComponents(); +} + +void MEDFileAnyTypeFieldMultiTSWithoutSDA::checkCoherencyOfTinyInfo(const MEDCouplingFieldDouble *field, const DataArray *arr) const +{ + static const char MSG[]="MEDFileFieldMultiTSWithoutSDA::checkCoherencyOfTinyInfo : invalid "; + if(_name!=field->getName()) + { + std::ostringstream oss; oss << MSG << "name ! should be \"" << _name; + oss << "\" and it is set in input field to \"" << field->getName() << "\" !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + if(!arr) + throw INTERP_KERNEL::Exception("MEDFileFieldMultiTSWithoutSDA::checkCoherencyOfTinyInfo : no array set !"); + checkThatComponentsMatch(arr->getInfoOnComponents()); +} + +void MEDFileAnyTypeFieldMultiTSWithoutSDA::checkThatComponentsMatch(const std::vector<std::string>& compos) const +{ + static const char MSG[]="MEDFileFieldMultiTSWithoutSDA::checkThatComponentsMatch : "; + if(getInfo().size()!=compos.size()) + { + std::ostringstream oss; oss << MSG << "mismatch of number of components between this (" << getInfo().size() << ") and "; + oss << " number of components of element to append (" << compos.size() << ") !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + if(_infos!=compos) + { + std::ostringstream oss; oss << MSG << "components have same size but are different ! should be \""; + std::copy(_infos.begin(),_infos.end(),std::ostream_iterator<std::string>(oss,", ")); + oss << " But compo in input fields are : "; + std::copy(compos.begin(),compos.end(),std::ostream_iterator<std::string>(oss,", ")); + oss << " !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } +} + +void MEDFileAnyTypeFieldMultiTSWithoutSDA::checkThatNbOfCompoOfTSMatchThis() const +{ + std::size_t sz=_infos.size(); + int j=0; + for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileAnyTypeField1TSWithoutSDA> >::const_iterator it=_time_steps.begin();it!=_time_steps.end();it++,j++) + { + const MEDFileAnyTypeField1TSWithoutSDA *elt(*it); + if(elt) + if(elt->getInfo().size()!=sz) + { + std::ostringstream oss; oss << "MEDFileAnyTypeFieldMultiTSWithoutSDA::checkThatNbOfCompoOfTSMatchThis : At pos #" << j << " the number of components is equal to "; + oss << elt->getInfo().size() << " whereas it is expected to be equal to " << sz << " !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + } +} + +void MEDFileAnyTypeFieldMultiTSWithoutSDA::appendFieldNoProfileSBT(const MEDCouplingFieldDouble *field, const DataArray *arr, MEDFileFieldGlobsReal& glob) +{ + if(!field) + throw INTERP_KERNEL::Exception("MEDFileAnyTypeFieldMultiTSWithoutSDA::appendFieldNoProfileSBT : input field is NULL !"); + if(!_time_steps.empty()) + checkCoherencyOfTinyInfo(field,arr); + MEDFileAnyTypeField1TSWithoutSDA *objC=createNew1TSWithoutSDAEmptyInstance(); + MEDCouplingAutoRefCountObjectPtr<MEDFileAnyTypeField1TSWithoutSDA> obj(objC); + objC->setFieldNoProfileSBT(field,arr,glob,*this); + copyTinyInfoFrom(field,arr); + _time_steps.push_back(obj); +} + +void MEDFileAnyTypeFieldMultiTSWithoutSDA::appendFieldProfile(const MEDCouplingFieldDouble *field, const DataArray *arr, const MEDFileMesh *mesh, int meshDimRelToMax, const DataArrayInt *profile, MEDFileFieldGlobsReal& glob) +{ + if(!field) + throw INTERP_KERNEL::Exception("MEDFileIntFieldMultiTSWithoutSDA::appendFieldNoProfileSBT : input field is NULL !"); + if(!_time_steps.empty()) + checkCoherencyOfTinyInfo(field,arr); + MEDFileField1TSWithoutSDA *objC=new MEDFileField1TSWithoutSDA; + MEDCouplingAutoRefCountObjectPtr<MEDFileAnyTypeField1TSWithoutSDA> obj(objC); + objC->setFieldProfile(field,arr,mesh,meshDimRelToMax,profile,glob,*this); + copyTinyInfoFrom(field,arr); + _time_steps.push_back(obj); +} + +void MEDFileAnyTypeFieldMultiTSWithoutSDA::setIteration(int i, MEDCouplingAutoRefCountObjectPtr<MEDFileAnyTypeField1TSWithoutSDA> ts) +{ + int sz=(int)_time_steps.size(); + if(i<0 || i>=sz) + { + std::ostringstream oss; oss << "MEDFileAnyTypeFieldMultiTSWithoutSDA::setIteration : trying to set element at place #" << i << " should be in [0," << sz << ") !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + const MEDFileAnyTypeField1TSWithoutSDA *tsPtr(ts); + if(tsPtr) + { + if(tsPtr->getNumberOfComponents()!=(int)_infos.size()) + { + std::ostringstream oss; oss << "MEDFileAnyTypeFieldMultiTSWithoutSDA::setIteration : trying to set element with " << tsPtr->getNumberOfComponents() << " components ! Should be " << _infos.size() << " !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + } + _time_steps[i]=ts; +} + +//= MEDFileFieldMultiTSWithoutSDA + +MEDFileFieldMultiTSWithoutSDA *MEDFileFieldMultiTSWithoutSDA::New(med_idt fid, const std::string& fieldName, med_field_type fieldTyp, const std::vector<std::string>& infos, int nbOfStep, const std::string& dtunit, bool loadAll, const MEDFileMeshes *ms, const std::vector< std::pair<TypeOfField,INTERP_KERNEL::NormalizedCellType> > *entities) +{ + return new MEDFileFieldMultiTSWithoutSDA(fid,fieldName,fieldTyp,infos,nbOfStep,dtunit,loadAll,ms,entities); +} + +MEDFileFieldMultiTSWithoutSDA::MEDFileFieldMultiTSWithoutSDA() +{ +} + +MEDFileFieldMultiTSWithoutSDA::MEDFileFieldMultiTSWithoutSDA(const std::string& fieldName):MEDFileAnyTypeFieldMultiTSWithoutSDA(fieldName) +{ +} + +/*! + * \param [in] fieldId field id in C mode + */ +MEDFileFieldMultiTSWithoutSDA::MEDFileFieldMultiTSWithoutSDA(med_idt fid, int fieldId, bool loadAll, const MEDFileMeshes *ms, const std::vector< std::pair<TypeOfField,INTERP_KERNEL::NormalizedCellType> > *entities) +try:MEDFileAnyTypeFieldMultiTSWithoutSDA(fid,fieldId,loadAll,ms,entities) +{ +} +catch(INTERP_KERNEL::Exception& e) +{ throw e; } + +MEDFileFieldMultiTSWithoutSDA::MEDFileFieldMultiTSWithoutSDA(med_idt fid, const std::string& fieldName, med_field_type fieldTyp, const std::vector<std::string>& infos, int nbOfStep, const std::string& dtunit, bool loadAll, const MEDFileMeshes *ms, const std::vector< std::pair<TypeOfField,INTERP_KERNEL::NormalizedCellType> > *entities) +try:MEDFileAnyTypeFieldMultiTSWithoutSDA(fid,fieldName,fieldTyp,infos,nbOfStep,dtunit,loadAll,ms,entities) +{ +} +catch(INTERP_KERNEL::Exception& e) +{ throw e; } + +MEDFileAnyTypeField1TSWithoutSDA *MEDFileFieldMultiTSWithoutSDA::createNew1TSWithoutSDAEmptyInstance() const +{ + return new MEDFileField1TSWithoutSDA; +} + +void MEDFileFieldMultiTSWithoutSDA::checkCoherencyOfType(const MEDFileAnyTypeField1TSWithoutSDA *f1ts) const +{ + if(!f1ts) + throw INTERP_KERNEL::Exception("MEDFileFieldMultiTSWithoutSDA::checkCoherencyOfType : input field1TS is NULL ! Impossible to check !"); + const MEDFileField1TSWithoutSDA *f1tsC=dynamic_cast<const MEDFileField1TSWithoutSDA *>(f1ts); + if(!f1tsC) + throw INTERP_KERNEL::Exception("MEDFileFieldMultiTSWithoutSDA::checkCoherencyOfType : the input field1TS is not a FLOAT64 type !"); +} + +const char *MEDFileFieldMultiTSWithoutSDA::getTypeStr() const +{ + return MEDFileField1TSWithoutSDA::TYPE_STR; +} + +MEDFileAnyTypeFieldMultiTSWithoutSDA *MEDFileFieldMultiTSWithoutSDA::shallowCpy() const +{ + return new MEDFileFieldMultiTSWithoutSDA(*this); +} + +MEDFileAnyTypeFieldMultiTSWithoutSDA *MEDFileFieldMultiTSWithoutSDA::createNew() const +{ + return new MEDFileFieldMultiTSWithoutSDA; +} + +/*! + * entry point for users that want to iterate into MEDFile DataStructure with a reduced overhead because output arrays are extracted (created) specially + * for the call of this method. That's why the DataArrayDouble instance in returned vector of vector should be dealed by the caller. + */ +std::vector< std::vector<DataArrayDouble *> > MEDFileFieldMultiTSWithoutSDA::getFieldSplitedByType2(int iteration, int order, const std::string& mname, std::vector<INTERP_KERNEL::NormalizedCellType>& types, std::vector< std::vector<TypeOfField> >& typesF, std::vector< std::vector<std::string> >& pfls, std::vector< std::vector<std::string> >& locs) const +{ + const MEDFileAnyTypeField1TSWithoutSDA& myF1TS=getTimeStepEntry(iteration,order); + const MEDFileField1TSWithoutSDA *myF1TSC=dynamic_cast<const MEDFileField1TSWithoutSDA *>(&myF1TS); + if(!myF1TSC) + throw INTERP_KERNEL::Exception("MEDFileFieldMultiTSWithoutSDA::getFieldSplitedByType2 : mismatch of type of field expecting FLOAT64 !"); + return myF1TSC->getFieldSplitedByType2(mname,types,typesF,pfls,locs); +} + +MEDFileIntFieldMultiTSWithoutSDA *MEDFileFieldMultiTSWithoutSDA::convertToInt() const +{ + MEDCouplingAutoRefCountObjectPtr<MEDFileIntFieldMultiTSWithoutSDA> ret(new MEDFileIntFieldMultiTSWithoutSDA); + ret->MEDFileAnyTypeFieldMultiTSWithoutSDA::operator =(*this); + int i=0; + for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileAnyTypeField1TSWithoutSDA> >::const_iterator it=_time_steps.begin();it!=_time_steps.end();it++,i++) + { + const MEDFileAnyTypeField1TSWithoutSDA *eltToConv(*it); + if(eltToConv) + { + const MEDFileField1TSWithoutSDA *eltToConvC=dynamic_cast<const MEDFileField1TSWithoutSDA *>(eltToConv); + if(!eltToConvC) + throw INTERP_KERNEL::Exception("MEDFileFieldMultiTSWithoutSDA::convertToInt : presence of an invalid 1TS type ! Should be of type FLOAT64 !"); + MEDCouplingAutoRefCountObjectPtr<MEDFileAnyTypeField1TSWithoutSDA> elt=eltToConvC->convertToInt(); + ret->setIteration(i,elt); + } + } + return ret.retn(); +} + +//= MEDFileAnyTypeFieldMultiTS + +MEDFileAnyTypeFieldMultiTS::MEDFileAnyTypeFieldMultiTS() +{ +} + +MEDFileAnyTypeFieldMultiTS::MEDFileAnyTypeFieldMultiTS(const std::string& fileName, bool loadAll, const MEDFileMeshes *ms) +try:MEDFileFieldGlobsReal(fileName) +{ + MEDFileUtilities::CheckFileForRead(fileName); + MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName.c_str(),MED_ACC_RDONLY); + _content=BuildContentFrom(fid,fileName,loadAll,ms); + loadGlobals(fid); +} +catch(INTERP_KERNEL::Exception& e) +{ + throw e; +} + +MEDFileAnyTypeFieldMultiTSWithoutSDA *MEDFileAnyTypeFieldMultiTS::BuildContentFrom(med_idt fid, const std::string& fileName, const std::string& fieldName, bool loadAll, const MEDFileMeshes *ms, const std::vector< std::pair<TypeOfField,INTERP_KERNEL::NormalizedCellType> > *entities) +{ + med_field_type typcha; + std::vector<std::string> infos; + std::string dtunit; + int i=-1; + MEDFileAnyTypeField1TS::LocateField(fid,fileName,fieldName,i,typcha,infos,dtunit); + MEDCouplingAutoRefCountObjectPtr<MEDFileAnyTypeFieldMultiTSWithoutSDA> ret; + switch(typcha) + { + case MED_FLOAT64: + { + ret=new MEDFileFieldMultiTSWithoutSDA(fid,i,loadAll,ms,entities); + break; + } + case MED_INT32: + { + ret=new MEDFileIntFieldMultiTSWithoutSDA(fid,i,loadAll,ms,entities); + break; + } + default: + { + std::ostringstream oss; oss << "MEDFileAnyTypeFieldMultiTS::BuildContentFrom(fileName,fieldName) : file \'" << fileName << "\' contains field with name \'" << fieldName << "\' but the type of field is not in [MED_FLOAT64, MED_INT32] !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + } + ret->setDtUnit(dtunit.c_str()); + return ret.retn(); +} + +MEDFileAnyTypeFieldMultiTSWithoutSDA *MEDFileAnyTypeFieldMultiTS::BuildContentFrom(med_idt fid, const std::string& fileName, bool loadAll, const MEDFileMeshes *ms) +{ + med_field_type typcha; + // + std::vector<std::string> infos; + std::string dtunit,fieldName; + MEDFileAnyTypeField1TS::LocateField2(fid,fileName,0,true,fieldName,typcha,infos,dtunit); + MEDCouplingAutoRefCountObjectPtr<MEDFileAnyTypeFieldMultiTSWithoutSDA> ret; + switch(typcha) + { + case MED_FLOAT64: + { + ret=new MEDFileFieldMultiTSWithoutSDA(fid,0,loadAll,ms,0); + break; + } + case MED_INT32: + { + ret=new MEDFileIntFieldMultiTSWithoutSDA(fid,0,loadAll,ms,0); + break; + } + default: + { + std::ostringstream oss; oss << "MEDFileAnyTypeFieldMultiTS::BuildContentFrom(fileName) : file \'" << fileName << "\' contains field with name \'" << fieldName << "\' but the type of the first field is not in [MED_FLOAT64, MED_INT32] !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + } + ret->setDtUnit(dtunit.c_str()); + return ret.retn(); +} + +MEDFileAnyTypeFieldMultiTS *MEDFileAnyTypeFieldMultiTS::BuildNewInstanceFromContent(MEDFileAnyTypeFieldMultiTSWithoutSDA *c, const std::string& fileName) +{ + if(!c) + throw INTERP_KERNEL::Exception("MEDFileAnyTypeFieldMultiTS::BuildNewInstanceFromContent : empty content in input : unable to build a new instance !"); + if(dynamic_cast<const MEDFileFieldMultiTSWithoutSDA *>(c)) + { + MEDCouplingAutoRefCountObjectPtr<MEDFileFieldMultiTS> ret=MEDFileFieldMultiTS::New(); + ret->setFileName(fileName); + ret->_content=c; c->incrRef(); + return ret.retn(); + } + if(dynamic_cast<const MEDFileIntFieldMultiTSWithoutSDA *>(c)) + { + MEDCouplingAutoRefCountObjectPtr<MEDFileIntFieldMultiTS> ret=MEDFileIntFieldMultiTS::New(); + ret->setFileName(fileName); + ret->_content=c; c->incrRef(); + return ret.retn(); + } + throw INTERP_KERNEL::Exception("MEDFileAnyTypeFieldMultiTS::BuildNewInstanceFromContent : internal error ! a content of type different from FLOAT64 and INT32 has been built but not intercepted !"); +} + +MEDFileAnyTypeFieldMultiTS::MEDFileAnyTypeFieldMultiTS(const std::string& fileName, const std::string& fieldName, bool loadAll, const MEDFileMeshes *ms, const std::vector< std::pair<TypeOfField,INTERP_KERNEL::NormalizedCellType> > *entities) +try:MEDFileFieldGlobsReal(fileName) +{ + MEDFileUtilities::CheckFileForRead(fileName); + MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName.c_str(),MED_ACC_RDONLY); + _content=BuildContentFrom(fid,fileName,fieldName,loadAll,ms,entities); + loadGlobals(fid); +} +catch(INTERP_KERNEL::Exception& e) +{ + throw e; +} + +//= MEDFileIntFieldMultiTSWithoutSDA + +MEDFileIntFieldMultiTSWithoutSDA *MEDFileIntFieldMultiTSWithoutSDA::New(med_idt fid, const std::string& fieldName, med_field_type fieldTyp, const std::vector<std::string>& infos, int nbOfStep, const std::string& dtunit, bool loadAll, const MEDFileMeshes *ms, const std::vector< std::pair<TypeOfField,INTERP_KERNEL::NormalizedCellType> > *entities) +{ + return new MEDFileIntFieldMultiTSWithoutSDA(fid,fieldName,fieldTyp,infos,nbOfStep,dtunit,loadAll,ms,entities); +} + +MEDFileIntFieldMultiTSWithoutSDA::MEDFileIntFieldMultiTSWithoutSDA() +{ +} + +MEDFileIntFieldMultiTSWithoutSDA::MEDFileIntFieldMultiTSWithoutSDA(const std::string& fieldName):MEDFileAnyTypeFieldMultiTSWithoutSDA(fieldName) +{ +} + +MEDFileIntFieldMultiTSWithoutSDA::MEDFileIntFieldMultiTSWithoutSDA(med_idt fid, const std::string& fieldName, med_field_type fieldTyp, const std::vector<std::string>& infos, int nbOfStep, const std::string& dtunit, bool loadAll, const MEDFileMeshes *ms, const std::vector< std::pair<TypeOfField,INTERP_KERNEL::NormalizedCellType> > *entities) +try:MEDFileAnyTypeFieldMultiTSWithoutSDA(fid,fieldName,fieldTyp,infos,nbOfStep,dtunit,loadAll,ms,entities) +{ +} +catch(INTERP_KERNEL::Exception& e) +{ throw e; } + +/*! + * \param [in] fieldId field id in C mode + */ +MEDFileIntFieldMultiTSWithoutSDA::MEDFileIntFieldMultiTSWithoutSDA(med_idt fid, int fieldId, bool loadAll, const MEDFileMeshes *ms, const std::vector< std::pair<TypeOfField,INTERP_KERNEL::NormalizedCellType> > *entities) +try:MEDFileAnyTypeFieldMultiTSWithoutSDA(fid,fieldId,loadAll,ms,entities) +{ +} +catch(INTERP_KERNEL::Exception& e) +{ throw e; } + +MEDFileAnyTypeField1TSWithoutSDA *MEDFileIntFieldMultiTSWithoutSDA::createNew1TSWithoutSDAEmptyInstance() const +{ + return new MEDFileIntField1TSWithoutSDA; +} + +void MEDFileIntFieldMultiTSWithoutSDA::checkCoherencyOfType(const MEDFileAnyTypeField1TSWithoutSDA *f1ts) const +{ + if(!f1ts) + throw INTERP_KERNEL::Exception("MEDFileIntFieldMultiTSWithoutSDA::checkCoherencyOfType : input field1TS is NULL ! Impossible to check !"); + const MEDFileIntField1TSWithoutSDA *f1tsC=dynamic_cast<const MEDFileIntField1TSWithoutSDA *>(f1ts); + if(!f1tsC) + throw INTERP_KERNEL::Exception("MEDFileIntFieldMultiTSWithoutSDA::checkCoherencyOfType : the input field1TS is not a INT32 type !"); +} + +const char *MEDFileIntFieldMultiTSWithoutSDA::getTypeStr() const +{ + return MEDFileIntField1TSWithoutSDA::TYPE_STR; +} + +MEDFileAnyTypeFieldMultiTSWithoutSDA *MEDFileIntFieldMultiTSWithoutSDA::shallowCpy() const +{ + return new MEDFileIntFieldMultiTSWithoutSDA(*this); +} + +MEDFileAnyTypeFieldMultiTSWithoutSDA *MEDFileIntFieldMultiTSWithoutSDA::createNew() const +{ + return new MEDFileIntFieldMultiTSWithoutSDA; +} + +MEDFileFieldMultiTSWithoutSDA *MEDFileIntFieldMultiTSWithoutSDA::convertToDouble() const +{ + MEDCouplingAutoRefCountObjectPtr<MEDFileFieldMultiTSWithoutSDA> ret(new MEDFileFieldMultiTSWithoutSDA); + ret->MEDFileAnyTypeFieldMultiTSWithoutSDA::operator =(*this); + int i=0; + for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileAnyTypeField1TSWithoutSDA> >::const_iterator it=_time_steps.begin();it!=_time_steps.end();it++,i++) + { + const MEDFileAnyTypeField1TSWithoutSDA *eltToConv(*it); + if(eltToConv) + { + const MEDFileIntField1TSWithoutSDA *eltToConvC=dynamic_cast<const MEDFileIntField1TSWithoutSDA *>(eltToConv); + if(!eltToConvC) + throw INTERP_KERNEL::Exception("MEDFileIntFieldMultiTSWithoutSDA::convertToInt : presence of an invalid 1TS type ! Should be of type INT32 !"); + MEDCouplingAutoRefCountObjectPtr<MEDFileAnyTypeField1TSWithoutSDA> elt=eltToConvC->convertToDouble(); + ret->setIteration(i,elt); + } + } + return ret.retn(); +} + +//= MEDFileAnyTypeFieldMultiTS + +/*! + * Returns a new instance of MEDFileFieldMultiTS or MEDFileIntFieldMultiTS holding data of the first field + * that has been read from a specified MED file. + * \param [in] fileName - the name of the MED file to read. + * \return MEDFileFieldMultiTS * - a new instance of MEDFileFieldMultiTS or MEDFileIntFieldMultiTS. The caller + * is to delete this field using decrRef() as it is no more needed. + * \throw If reading the file fails. + */ +MEDFileAnyTypeFieldMultiTS *MEDFileAnyTypeFieldMultiTS::New(const std::string& fileName, bool loadAll) +{ + MEDFileUtilities::CheckFileForRead(fileName); + MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName.c_str(),MED_ACC_RDONLY); + MEDCouplingAutoRefCountObjectPtr<MEDFileAnyTypeFieldMultiTSWithoutSDA> c=BuildContentFrom(fid,fileName,loadAll,0); + MEDCouplingAutoRefCountObjectPtr<MEDFileAnyTypeFieldMultiTS> ret=BuildNewInstanceFromContent(c,fileName); + ret->loadGlobals(fid); + return ret.retn(); +} + +/*! + * Returns a new instance of MEDFileFieldMultiTS or MEDFileIntFieldMultiTS holding data of a given field + * that has been read from a specified MED file. + * \param [in] fileName - the name of the MED file to read. + * \param [in] fieldName - the name of the field to read. + * \return MEDFileFieldMultiTS * - a new instance of MEDFileFieldMultiTS or MEDFileIntFieldMultiTS. The caller + * is to delete this field using decrRef() as it is no more needed. + * \throw If reading the file fails. + * \throw If there is no field named \a fieldName in the file. + */ +MEDFileAnyTypeFieldMultiTS *MEDFileAnyTypeFieldMultiTS::New(const std::string& fileName, const std::string& fieldName, bool loadAll) +{ + MEDFileUtilities::CheckFileForRead(fileName); + MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName.c_str(),MED_ACC_RDONLY); + MEDCouplingAutoRefCountObjectPtr<MEDFileAnyTypeFieldMultiTSWithoutSDA> c(BuildContentFrom(fid,fileName,fieldName,loadAll,0,0)); + MEDCouplingAutoRefCountObjectPtr<MEDFileAnyTypeFieldMultiTS> ret=BuildNewInstanceFromContent(c,fileName); + ret->loadGlobals(fid); + return ret.retn(); +} + +/*! + * This constructor is a shallow copy constructor. If \a shallowCopyOfContent is true the content of \a other is shallow copied. + * If \a shallowCopyOfContent is false, \a other is taken to be the content of \a this. + * + * \warning this is a shallow copy constructor + */ +MEDFileAnyTypeFieldMultiTS::MEDFileAnyTypeFieldMultiTS(const MEDFileAnyTypeFieldMultiTSWithoutSDA& other, bool shallowCopyOfContent) +{ + if(!shallowCopyOfContent) + { + const MEDFileAnyTypeFieldMultiTSWithoutSDA *otherPtr(&other); + otherPtr->incrRef(); + _content=const_cast<MEDFileAnyTypeFieldMultiTSWithoutSDA *>(otherPtr); + } + else + { + _content=other.shallowCpy(); + } +} + +MEDFileAnyTypeFieldMultiTSWithoutSDA *MEDFileAnyTypeFieldMultiTS::contentNotNullBase() +{ + MEDFileAnyTypeFieldMultiTSWithoutSDA *ret=_content; + if(!ret) + throw INTERP_KERNEL::Exception("MEDFileAnyTypeFieldMultiTS : content is expected to be not null !"); + return ret; +} + +const MEDFileAnyTypeFieldMultiTSWithoutSDA *MEDFileAnyTypeFieldMultiTS::contentNotNullBase() const +{ + const MEDFileAnyTypeFieldMultiTSWithoutSDA *ret=_content; + if(!ret) + throw INTERP_KERNEL::Exception("MEDFileAnyTypeFieldMultiTS : const content is expected to be not null !"); + return ret; +} + +std::vector<std::string> MEDFileAnyTypeFieldMultiTS::getPflsReallyUsed() const +{ + return contentNotNullBase()->getPflsReallyUsed2(); +} + +std::vector<std::string> MEDFileAnyTypeFieldMultiTS::getLocsReallyUsed() const +{ + return contentNotNullBase()->getLocsReallyUsed2(); +} + +std::vector<std::string> MEDFileAnyTypeFieldMultiTS::getPflsReallyUsedMulti() const +{ + return contentNotNullBase()->getPflsReallyUsedMulti2(); +} + +std::vector<std::string> MEDFileAnyTypeFieldMultiTS::getLocsReallyUsedMulti() const +{ + return contentNotNullBase()->getLocsReallyUsedMulti2(); +} + +void MEDFileAnyTypeFieldMultiTS::changePflsRefsNamesGen(const std::vector< std::pair<std::vector<std::string>, std::string > >& mapOfModif) +{ + contentNotNullBase()->changePflsRefsNamesGen2(mapOfModif); +} + +void MEDFileAnyTypeFieldMultiTS::changeLocsRefsNamesGen(const std::vector< std::pair<std::vector<std::string>, std::string > >& mapOfModif) +{ + contentNotNullBase()->changeLocsRefsNamesGen2(mapOfModif); +} + +int MEDFileAnyTypeFieldMultiTS::getNumberOfTS() const +{ + return contentNotNullBase()->getNumberOfTS(); +} + +void MEDFileAnyTypeFieldMultiTS::eraseEmptyTS() +{ + contentNotNullBase()->eraseEmptyTS(); +} + +void MEDFileAnyTypeFieldMultiTS::eraseTimeStepIds(const int *startIds, const int *endIds) +{ + contentNotNullBase()->eraseTimeStepIds(startIds,endIds); +} + +void MEDFileAnyTypeFieldMultiTS::eraseTimeStepIds2(int bg, int end, int step) +{ + contentNotNullBase()->eraseTimeStepIds2(bg,end,step); +} + +MEDFileAnyTypeFieldMultiTS *MEDFileAnyTypeFieldMultiTS::buildSubPart(const int *startIds, const int *endIds) const +{ + MEDCouplingAutoRefCountObjectPtr<MEDFileAnyTypeFieldMultiTSWithoutSDA> c=contentNotNullBase()->buildFromTimeStepIds(startIds,endIds); + MEDCouplingAutoRefCountObjectPtr<MEDFileAnyTypeFieldMultiTS> ret=shallowCpy(); + ret->_content=c; + return ret.retn(); +} + +MEDFileAnyTypeFieldMultiTS *MEDFileAnyTypeFieldMultiTS::buildSubPartSlice(int bg, int end, int step) const +{ + MEDCouplingAutoRefCountObjectPtr<MEDFileAnyTypeFieldMultiTSWithoutSDA> c=contentNotNullBase()->buildFromTimeStepIds2(bg,end,step); + MEDCouplingAutoRefCountObjectPtr<MEDFileAnyTypeFieldMultiTS> ret=shallowCpy(); + ret->_content=c; + return ret.retn(); +} + +std::vector< std::pair<int,int> > MEDFileAnyTypeFieldMultiTS::getIterations() const +{ + return contentNotNullBase()->getIterations(); +} + +void MEDFileAnyTypeFieldMultiTS::pushBackTimeSteps(const std::vector<MEDFileAnyTypeField1TS *>& f1ts) +{ + for(std::vector<MEDFileAnyTypeField1TS *>::const_iterator it=f1ts.begin();it!=f1ts.end();it++) + pushBackTimeStep(*it); +} + +void MEDFileAnyTypeFieldMultiTS::pushBackTimeSteps(MEDFileAnyTypeFieldMultiTS *fmts) +{ + if(!fmts) + throw INTERP_KERNEL::Exception("MEDFileAnyTypeFieldMultiTS::pushBackTimeSteps : Input fmts is NULL !"); + int nbOfTS(fmts->getNumberOfTS()); + for(int i=0;i<nbOfTS;i++) + { + MEDCouplingAutoRefCountObjectPtr<MEDFileAnyTypeField1TS> elt(fmts->getTimeStepAtPos(i)); + pushBackTimeStep(elt); + } +} + +void MEDFileAnyTypeFieldMultiTS::pushBackTimeStep(MEDFileAnyTypeField1TS *f1ts) +{ + if(!f1ts) + throw INTERP_KERNEL::Exception("MEDFileAnyTypeFieldMultiTSWithoutSDA::pushBackTimeStep : input pointer is NULL !"); + checkCoherencyOfType(f1ts); + f1ts->incrRef(); + MEDCouplingAutoRefCountObjectPtr<MEDFileAnyTypeField1TS> f1tsSafe(f1ts); + MEDFileAnyTypeField1TSWithoutSDA *c=f1ts->contentNotNullBase(); + c->incrRef(); + MEDCouplingAutoRefCountObjectPtr<MEDFileAnyTypeField1TSWithoutSDA> cSafe(c); + if(!((MEDFileAnyTypeFieldMultiTSWithoutSDA *)_content)) + throw INTERP_KERNEL::Exception("MEDFileAnyTypeFieldMultiTSWithoutSDA::pushBackTimeStep : no content in this !"); + _content->pushBackTimeStep(cSafe); + appendGlobs(*f1ts,1e-12); +} + +void MEDFileAnyTypeFieldMultiTS::synchronizeNameScope() +{ + contentNotNullBase()->synchronizeNameScope(); +} + +int MEDFileAnyTypeFieldMultiTS::getPosOfTimeStep(int iteration, int order) const +{ + return contentNotNullBase()->getPosOfTimeStep(iteration,order); +} + +int MEDFileAnyTypeFieldMultiTS::getPosGivenTime(double time, double eps) const +{ + return contentNotNullBase()->getPosGivenTime(time,eps); +} + +int MEDFileAnyTypeFieldMultiTS::getNonEmptyLevels(int iteration, int order, const std::string& mname, std::vector<int>& levs) const +{ + return contentNotNullBase()->getNonEmptyLevels(iteration,order,mname,levs); +} + +std::vector< std::vector<TypeOfField> > MEDFileAnyTypeFieldMultiTS::getTypesOfFieldAvailable() const +{ + return contentNotNullBase()->getTypesOfFieldAvailable(); +} + +std::vector< std::vector< std::pair<int,int> > > MEDFileAnyTypeFieldMultiTS::getFieldSplitedByType(int iteration, int order, const std::string& mname, std::vector<INTERP_KERNEL::NormalizedCellType>& types, std::vector< std::vector<TypeOfField> >& typesF, std::vector< std::vector<std::string> >& pfls, std::vector< std::vector<std::string> >& locs) const +{ + return contentNotNullBase()->getFieldSplitedByType(iteration,order,mname,types,typesF,pfls,locs); +} + +std::string MEDFileAnyTypeFieldMultiTS::getName() const +{ + return contentNotNullBase()->getName(); +} + +void MEDFileAnyTypeFieldMultiTS::setName(const std::string& name) +{ + contentNotNullBase()->setName(name); +} + +std::string MEDFileAnyTypeFieldMultiTS::getDtUnit() const +{ + return contentNotNullBase()->getDtUnit(); +} + +void MEDFileAnyTypeFieldMultiTS::setDtUnit(const std::string& dtUnit) +{ + contentNotNullBase()->setDtUnit(dtUnit); +} + +void MEDFileAnyTypeFieldMultiTS::simpleRepr(int bkOffset, std::ostream& oss, int fmtsId) const +{ + contentNotNullBase()->simpleRepr(bkOffset,oss,fmtsId); +} + +std::vector< std::pair<int,int> > MEDFileAnyTypeFieldMultiTS::getTimeSteps(std::vector<double>& ret1) const +{ + return contentNotNullBase()->getTimeSteps(ret1); +} + +std::string MEDFileAnyTypeFieldMultiTS::getMeshName() const +{ + return contentNotNullBase()->getMeshName(); +} + +void MEDFileAnyTypeFieldMultiTS::setMeshName(const std::string& newMeshName) +{ + contentNotNullBase()->setMeshName(newMeshName); +} + +bool MEDFileAnyTypeFieldMultiTS::changeMeshNames(const std::vector< std::pair<std::string,std::string> >& modifTab) +{ + return contentNotNullBase()->changeMeshNames(modifTab); +} + +const std::vector<std::string>& MEDFileAnyTypeFieldMultiTS::getInfo() const +{ + return contentNotNullBase()->getInfo(); +} + +bool MEDFileAnyTypeFieldMultiTS::presenceOfMultiDiscPerGeoType() const +{ + return contentNotNullBase()->presenceOfMultiDiscPerGeoType(); +} + +void MEDFileAnyTypeFieldMultiTS::setInfo(const std::vector<std::string>& info) +{ + return contentNotNullBase()->setInfo(info); +} + +int MEDFileAnyTypeFieldMultiTS::getNumberOfComponents() const +{ + const std::vector<std::string> ret=getInfo(); + return (int)ret.size(); +} + +void MEDFileAnyTypeFieldMultiTS::writeLL(med_idt fid) const +{ + writeGlobals(fid,*this); + contentNotNullBase()->writeLL(fid,*this); +} + +/*! + * Writes \a this field into a MED file specified by its name. + * \param [in] fileName - the MED file name. + * \param [in] mode - the writing mode. For more on \a mode, see \ref AdvMEDLoaderBasics. + * - 2 - erase; an existing file is removed. + * - 1 - append; same data should not be present in an existing file. + * - 0 - overwrite; same data present in an existing file is overwritten. + * \throw If the field name is not set. + * \throw If no field data is set. + * \throw If \a mode == 1 and the same data is present in an existing file. + */ +void MEDFileAnyTypeFieldMultiTS::write(const std::string& fileName, int mode) const +{ + med_access_mode medmod=MEDFileUtilities::TraduceWriteMode(mode); + MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName.c_str(),medmod); + writeLL(fid); +} + +/*! + * This method alloc the arrays and load potentially huge arrays contained in this field. + * This method should be called when a MEDFileAnyTypeFieldMultiTS::New constructor has been with false as the last parameter. + * This method can be also called to refresh or reinit values from a file. + * + * \throw If the fileName is not set or points to a non readable MED file. + */ +void MEDFileAnyTypeFieldMultiTS::loadArrays() +{ + if(getFileName().empty()) + throw INTERP_KERNEL::Exception("MEDFileAnyTypeFieldMultiTS::loadArrays : the structure does not come from a file !"); + MEDFileUtilities::AutoFid fid=MEDfileOpen(getFileName().c_str(),MED_ACC_RDONLY); + contentNotNullBase()->loadBigArraysRecursively(fid,*contentNotNullBase()); +} + +/*! + * This method behaves as MEDFileAnyTypeFieldMultiTS::loadArrays does, the first call, if \a this was built using a file without loading big arrays. + * But once data loaded once, this method does nothing. + * + * \throw If the fileName is not set or points to a non readable MED file. + * \sa MEDFileAnyTypeFieldMultiTS::loadArrays, MEDFileAnyTypeFieldMultiTS::unloadArrays + */ +void MEDFileAnyTypeFieldMultiTS::loadArraysIfNecessary() +{ + if(!getFileName().empty()) + { + MEDFileUtilities::AutoFid fid=MEDfileOpen(getFileName().c_str(),MED_ACC_RDONLY); + contentNotNullBase()->loadBigArraysRecursivelyIfNecessary(fid,*contentNotNullBase()); + } +} + +/*! + * This method releases potentially big data arrays and so returns to the same heap memory than status loaded with 'loadAll' parameter set to false. + * \b WARNING, this method does release arrays even if \a this does not come from a load of a MED file. + * So this method can lead to a loss of data. If you want to unload arrays safely call MEDFileAnyTypeFieldMultiTS::unloadArraysWithoutDataLoss instead. + * + * \sa MEDFileAnyTypeFieldMultiTS::loadArrays, MEDFileAnyTypeFieldMultiTS::loadArraysIfNecessary, MEDFileAnyTypeFieldMultiTS::unloadArraysWithoutDataLoss + */ +void MEDFileAnyTypeFieldMultiTS::unloadArrays() +{ + contentNotNullBase()->unloadArrays(); +} + +/*! + * This method potentially releases big data arrays if \a this is coming from a file. If \a this has been built from scratch this method will have no effect. + * This method is the symetrical method of MEDFileAnyTypeFieldMultiTS::loadArraysIfNecessary. + * This method is useful to reduce \b safely amount of heap memory necessary for \a this by using MED file as database. + * + * \sa MEDFileAnyTypeFieldMultiTS::loadArraysIfNecessary + */ +void MEDFileAnyTypeFieldMultiTS::unloadArraysWithoutDataLoss() +{ + if(!getFileName().empty()) + contentNotNullBase()->unloadArrays(); +} + +std::string MEDFileAnyTypeFieldMultiTS::simpleRepr() const +{ + std::ostringstream oss; + contentNotNullBase()->simpleRepr(0,oss,-1); + simpleReprGlobs(oss); + return oss.str(); +} + +std::size_t MEDFileAnyTypeFieldMultiTS::getHeapMemorySizeWithoutChildren() const +{ + return MEDFileFieldGlobsReal::getHeapMemorySizeWithoutChildren(); +} + +std::vector<const BigMemoryObject *> MEDFileAnyTypeFieldMultiTS::getDirectChildrenWithNull() const +{ + std::vector<const BigMemoryObject *> ret(MEDFileFieldGlobsReal::getDirectChildrenWithNull()); + ret.push_back((const MEDFileAnyTypeFieldMultiTSWithoutSDA *)_content); + return ret; +} + +/*! + * This method returns as MEDFileAnyTypeFieldMultiTS new instances as number of components in \a this. + * The returned instances are deep copy of \a this except that for globals that are share with those contained in \a this. + * ** WARNING ** do no forget to rename the ouput instances to avoid to write n-times in the same MED file field ! + */ +std::vector< MEDCouplingAutoRefCountObjectPtr< MEDFileAnyTypeFieldMultiTS > > MEDFileAnyTypeFieldMultiTS::splitComponents() const +{ + const MEDFileAnyTypeFieldMultiTSWithoutSDA *content(_content); + if(!content) + throw INTERP_KERNEL::Exception("MEDFileAnyTypeFieldMultiTS::splitComponents : no content in this ! Unable to split components !"); + std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileAnyTypeFieldMultiTSWithoutSDA> > contentsSplit=content->splitComponents(); + std::size_t sz(contentsSplit.size()); + std::vector< MEDCouplingAutoRefCountObjectPtr< MEDFileAnyTypeFieldMultiTS > > ret(sz); + for(std::size_t i=0;i<sz;i++) + { + ret[i]=shallowCpy(); + ret[i]->_content=contentsSplit[i]; + } + return ret; +} + +/*! + * This method returns as MEDFileAnyTypeFieldMultiTS new instances as number of discretizations over time steps in \a this. + * The returned instances are shallow copied of \a this included globals that are share with those contained in \a this. + */ +std::vector< MEDCouplingAutoRefCountObjectPtr< MEDFileAnyTypeFieldMultiTS > > MEDFileAnyTypeFieldMultiTS::splitDiscretizations() const +{ + const MEDFileAnyTypeFieldMultiTSWithoutSDA *content(_content); + if(!content) + throw INTERP_KERNEL::Exception("MEDFileAnyTypeFieldMultiTS::splitDiscretizations : no content in this ! Unable to split discretizations !"); + std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileAnyTypeFieldMultiTSWithoutSDA> > contentsSplit(content->splitDiscretizations()); + std::size_t sz(contentsSplit.size()); + std::vector< MEDCouplingAutoRefCountObjectPtr< MEDFileAnyTypeFieldMultiTS > > ret(sz); + for(std::size_t i=0;i<sz;i++) + { + ret[i]=shallowCpy(); + ret[i]->_content=contentsSplit[i]; + } + return ret; +} + +/*! + * This method returns as MEDFileAnyTypeFieldMultiTS new instances as number of sub-discretizations over time steps in \a this. + * The returned instances are shallow copied of \a this included globals that are share with those contained in \a this. + */ +std::vector< MEDCouplingAutoRefCountObjectPtr< MEDFileAnyTypeFieldMultiTS > > MEDFileAnyTypeFieldMultiTS::splitMultiDiscrPerGeoTypes() const +{ + const MEDFileAnyTypeFieldMultiTSWithoutSDA *content(_content); + if(!content) + throw INTERP_KERNEL::Exception("MEDFileAnyTypeFieldMultiTS::splitMultiDiscrPerGeoTypes : no content in this ! Unable to split discretizations !"); + std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileAnyTypeFieldMultiTSWithoutSDA> > contentsSplit(content->splitMultiDiscrPerGeoTypes()); + std::size_t sz(contentsSplit.size()); + std::vector< MEDCouplingAutoRefCountObjectPtr< MEDFileAnyTypeFieldMultiTS > > ret(sz); + for(std::size_t i=0;i<sz;i++) + { + ret[i]=shallowCpy(); + ret[i]->_content=contentsSplit[i]; + } + return ret; +} + +MEDFileAnyTypeFieldMultiTS *MEDFileAnyTypeFieldMultiTS::deepCpy() const +{ + MEDCouplingAutoRefCountObjectPtr<MEDFileAnyTypeFieldMultiTS> ret=shallowCpy(); + if((const MEDFileAnyTypeFieldMultiTSWithoutSDA *)_content) + ret->_content=_content->deepCpy(); + ret->deepCpyGlobs(*this); + return ret.retn(); +} + +MEDCouplingAutoRefCountObjectPtr<MEDFileAnyTypeFieldMultiTSWithoutSDA> MEDFileAnyTypeFieldMultiTS::getContent() +{ + return _content; +} + +/*! + * Returns a new MEDFileField1TS or MEDFileIntField1TS holding data of a given time step of \a this field. + * \param [in] iteration - the iteration number of a required time step. + * \param [in] order - the iteration order number of required time step. + * \return MEDFileField1TS * or MEDFileIntField1TS *- a new instance of MEDFileField1TS or MEDFileIntField1TS. The caller is to + * delete this field using decrRef() as it is no more needed. + * \throw If there is no required time step in \a this field. + */ +MEDFileAnyTypeField1TS *MEDFileAnyTypeFieldMultiTS::getTimeStep(int iteration, int order) const +{ + int pos=getPosOfTimeStep(iteration,order); + return getTimeStepAtPos(pos); +} + +/*! + * Returns a new MEDFileField1TS or MEDFileIntField1TS holding data of a given time step of \a this field. + * \param [in] time - the time of the time step of interest. + * \param [in] eps - a precision used to compare time values. + * \return MEDFileField1TS * - a new instance of MEDFileField1TS. The caller is to + * delete this field using decrRef() as it is no more needed. + * \throw If there is no required time step in \a this field. + */ +MEDFileAnyTypeField1TS *MEDFileAnyTypeFieldMultiTS::getTimeStepGivenTime(double time, double eps) const +{ + int pos=getPosGivenTime(time,eps); + return getTimeStepAtPos(pos); +} + +/*! + * This method groups not null items in \a vectFMTS per time step series. Two time series are considered equal if the list of their pair of integers iteration,order are equal. + * The float64 value of time attached to the pair of integers are not considered here. + * WARNING the returned pointers are not incremented. The caller is \b not responsible to deallocate them ! This method only reorganizes entries in \a vectFMTS. + * + * \param [in] vectFMTS - vector of not null fields defined on a same global data pointer. + * \throw If there is a null pointer in \a vectFMTS. + */ +std::vector< std::vector<MEDFileAnyTypeFieldMultiTS *> > MEDFileAnyTypeFieldMultiTS::SplitIntoCommonTimeSeries(const std::vector<MEDFileAnyTypeFieldMultiTS *>& vectFMTS) +{ + static const char msg[]="MEDFileAnyTypeFieldMultiTS::SplitIntoCommonTimeSeries : presence of null instance in input vector !"; + std::vector< std::vector<MEDFileAnyTypeFieldMultiTS *> > ret; + std::list<MEDFileAnyTypeFieldMultiTS *> lstFMTS(vectFMTS.begin(),vectFMTS.end()); + while(!lstFMTS.empty()) + { + std::list<MEDFileAnyTypeFieldMultiTS *>::iterator it(lstFMTS.begin()); + MEDFileAnyTypeFieldMultiTS *curIt(*it); + if(!curIt) + throw INTERP_KERNEL::Exception(msg); + std::vector< std::pair<int,int> > refIts=curIt->getIterations(); + std::vector<MEDFileAnyTypeFieldMultiTS *> elt; + elt.push_back(curIt); it=lstFMTS.erase(it); + while(it!=lstFMTS.end()) + { + curIt=*it; + if(!curIt) + throw INTERP_KERNEL::Exception(msg); + std::vector< std::pair<int,int> > curIts=curIt->getIterations(); + if(refIts==curIts) + { elt.push_back(curIt); it=lstFMTS.erase(it); } + else + it++; + } + ret.push_back(elt); + } + return ret; +} + +/*! + * This method splits the input list \a vectFMTS considering the aspect of the geometrical support over time. + * All returned instances in a subvector can be safely loaded, rendered along time + * All items must be defined on the same time step ids ( see MEDFileAnyTypeFieldMultiTS::SplitIntoCommonTimeSeries method ). + * Each item in \a vectFMTS is expected to have one and exactly one spatial discretization along time. + * All items in \a vectFMTS must lie on the mesh (located by meshname and time step) and compatible with the input mesh \a mesh (having the same name than those in items). + * All items in \a vectFMTS whose spatial discretization is not ON_NODES will appear once. + * For items in \a vectFMTS that are ON_NODES it is possible to appear several times (more than once or once) in the returned vector. + * + * \param [in] vectFMTS - list of multi times step part all defined each on a same spatial discretization along time and pointing to a mesh whose name is equal to \c mesh->getName(). + * \param [in] mesh - the mesh shared by all items in \a vectFMTS across time. + * \param [out] fsc - A vector having same size than returned vector. It specifies the support comporator of the corresponding vector of MEDFileAnyTypeFieldMultiTS in returned vector of vector. + * \return - A vector of vector of objects that contains the same pointers (objects) than thoose in \a vectFMTS except that there are organized differently. So pointers included in returned vector of vector should \b not been dealt by the caller. + * + * \throw If an element in \a vectFMTS has not only one spatial discretization set. + * \throw If an element in \a vectFMTS change of spatial discretization along time. + * \throw If an element in \a vectFMTS lies on a mesh with meshname different from those in \a mesh. + * \thorw If some elements in \a vectFMTS do not have the same times steps. + * \throw If mesh is null. + * \throw If an element in \a vectFMTS is null. + * \sa MEDFileAnyTypeFieldMultiTS::AreOnSameSupportAcrossTime + */ +std::vector< std::vector<MEDFileAnyTypeFieldMultiTS *> > MEDFileAnyTypeFieldMultiTS::SplitPerCommonSupport(const std::vector<MEDFileAnyTypeFieldMultiTS *>& vectFMTS, const MEDFileMesh *mesh, std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileFastCellSupportComparator> >& fsc) +{ + static const char msg[]="MEDFileAnyTypeFieldMultiTS::SplitPerCommonSupport : presence of a null instance in the input vector !"; + if(!mesh) + throw INTERP_KERNEL::Exception("MEDFileAnyTypeFieldMultiTS::SplitPerCommonSupport : input mesh is null !"); + std::vector< std::vector<MEDFileAnyTypeFieldMultiTS *> > ret; + if(vectFMTS.empty()) + return ret; + std::vector<MEDFileAnyTypeFieldMultiTS *>::const_iterator it(vectFMTS.begin()); + MEDFileAnyTypeFieldMultiTS *frstElt(*it); + if(!frstElt) + throw INTERP_KERNEL::Exception(msg); + std::size_t i=0; + std::vector<MEDFileAnyTypeFieldMultiTS *> vectFMTSNotNodes; + std::vector<MEDFileAnyTypeFieldMultiTS *> vectFMTSNodes; + for(;it!=vectFMTS.end();it++,i++) + { + if(!(*it)) + throw INTERP_KERNEL::Exception(msg); + TypeOfField tof0,tof1; + if(CheckSupportAcrossTime(frstElt,*it,mesh,tof0,tof1)>0) + { + if(tof1!=ON_NODES) + vectFMTSNotNodes.push_back(*it); + else + vectFMTSNodes.push_back(*it); + } + else + vectFMTSNotNodes.push_back(*it); + } + std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileFastCellSupportComparator> > cmps; + std::vector< std::vector<MEDFileAnyTypeFieldMultiTS *> > retCell=SplitPerCommonSupportNotNodesAlg(vectFMTSNotNodes,mesh,cmps); + ret=retCell; + for(std::vector<MEDFileAnyTypeFieldMultiTS *>::const_iterator it2=vectFMTSNodes.begin();it2!=vectFMTSNodes.end();it2++) + { + i=0; + bool isFetched(false); + for(std::vector< std::vector<MEDFileAnyTypeFieldMultiTS *> >::const_iterator it0=retCell.begin();it0!=retCell.end();it0++,i++) + { + if((*it0).empty()) + throw INTERP_KERNEL::Exception("MEDFileAnyTypeFieldMultiTS::SplitPerCommonSupport : internal error !"); + if(cmps[i]->isCompatibleWithNodesDiscr(*it2)) + { ret[i].push_back(*it2); isFetched=true; } + } + if(!isFetched) + { + std::vector<MEDFileAnyTypeFieldMultiTS *> tmp(1,*it2); + MEDCouplingAutoRefCountObjectPtr<MEDFileMeshStruct> tmp2(MEDFileMeshStruct::New(mesh)); + ret.push_back(tmp); retCell.push_back(tmp); cmps.push_back(MEDFileFastCellSupportComparator::New(tmp2,*it2)); + } + } + fsc=cmps; + return ret; +} + +/*! + * WARNING no check here. The caller must be sure that all items in vectFMTS are coherent each other in time steps, only one same spatial discretization and not ON_NODES. + * \param [out] cmps - same size than the returned vector. + */ +std::vector< std::vector<MEDFileAnyTypeFieldMultiTS *> > MEDFileAnyTypeFieldMultiTS::SplitPerCommonSupportNotNodesAlg(const std::vector<MEDFileAnyTypeFieldMultiTS *>& vectFMTS, const MEDFileMesh *mesh, std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileFastCellSupportComparator> >& cmps) +{ + std::vector< std::vector<MEDFileAnyTypeFieldMultiTS *> > ret; + std::list<MEDFileAnyTypeFieldMultiTS *> lstFMTS(vectFMTS.begin(),vectFMTS.end()); + while(!lstFMTS.empty()) + { + std::list<MEDFileAnyTypeFieldMultiTS *>::iterator it(lstFMTS.begin()); + MEDFileAnyTypeFieldMultiTS *ref(*it); + std::vector<MEDFileAnyTypeFieldMultiTS *> elt; + elt.push_back(ref); it=lstFMTS.erase(it); + MEDCouplingAutoRefCountObjectPtr<MEDFileMeshStruct> mst(MEDFileMeshStruct::New(mesh)); + MEDCouplingAutoRefCountObjectPtr<MEDFileFastCellSupportComparator> cmp(MEDFileFastCellSupportComparator::New(mst,ref)); + while(it!=lstFMTS.end()) + { + MEDFileAnyTypeFieldMultiTS *curIt(*it); + if(cmp->isEqual(curIt)) + { elt.push_back(curIt); it=lstFMTS.erase(it); } + else + it++; + } + ret.push_back(elt); cmps.push_back(cmp); + } + return ret; +} + +/*! + * This method scan the two main structs along time of \a f0 and \a f1 to see if there are all lying on the same mesh along time than those in \a mesh. + * \a f0 and \a f1 must be defined each only on a same spatial discretization even if this can be different each other. + * + * \throw If \a f0 or \a f1 has not only one spatial discretization set. + * \throw If \a f0 or \a f1 change of spatial discretization along time. + * \throw If \a f0 or \a f1 on a mesh with meshname different from those in \a mesh. + * \thorw If \a f0 and \a f1 do not have the same times steps. + * \throw If mesh is null. + * \throw If \a f0 or \a f1 is null. + * \sa MEDFileAnyTypeFieldMultiTS::SplitPerCommonSupport + */ +int MEDFileAnyTypeFieldMultiTS::CheckSupportAcrossTime(MEDFileAnyTypeFieldMultiTS *f0, MEDFileAnyTypeFieldMultiTS *f1, const MEDFileMesh *mesh, TypeOfField& tof0, TypeOfField& tof1) +{ + if(!mesh) + throw INTERP_KERNEL::Exception("MEDFileAnyTypeFieldMultiTS::CheckSupportAcrossTime : input mesh is null !"); + if(!f0 || !f1) + throw INTERP_KERNEL::Exception("MEDFileAnyTypeFieldMultiTS::CheckSupportAcrossTime : presence of null instance in fields over time !"); + if(f0->getMeshName()!=mesh->getName()) + { + std::ostringstream oss; oss << "MEDFileAnyTypeFieldMultiTS::CheckSupportAcrossTime : first field points to mesh \""<< f0->getMeshName() << "\" and input mesh to compare has name \"" << mesh->getName() << "\" !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + if(f1->getMeshName()!=mesh->getName()) + { + std::ostringstream oss; oss << "MEDFileAnyTypeFieldMultiTS::CheckSupportAcrossTime : second field points to mesh \""<< f1->getMeshName() << "\" and input mesh to compare has name \"" << mesh->getName() << "\" !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + int nts=f0->getNumberOfTS(); + if(nts!=f1->getNumberOfTS()) + throw INTERP_KERNEL::Exception("MEDFileAnyTypeFieldMultiTS::CheckSupportAcrossTime : number of time steps are not the same !"); + if(nts==0) + return nts; + for(int i=0;i<nts;i++) + { + MEDCouplingAutoRefCountObjectPtr<MEDFileAnyTypeField1TS> f0cur=f0->getTimeStepAtPos(i); + MEDCouplingAutoRefCountObjectPtr<MEDFileAnyTypeField1TS> f1cur=f1->getTimeStepAtPos(i); + std::vector<TypeOfField> tofs0(f0cur->getTypesOfFieldAvailable()),tofs1(f1cur->getTypesOfFieldAvailable()); + if(tofs0.size()!=1 || tofs1.size()!=1) + throw INTERP_KERNEL::Exception("MEDFileAnyTypeFieldMultiTS::CheckSupportAcrossTime : All time steps must be defined on only one spatial discretization !"); + if(i!=0) + { + if(tof0!=tofs0[0] || tof1!=tofs1[0]) + throw INTERP_KERNEL::Exception("MEDFileAnyTypeFieldMultiTS::CheckSupportAcrossTime : Across times steps MEDFileAnyTypeFieldMultiTS instances have to keep the same unique spatial discretization !"); + } + else + { tof0=tofs0[0]; tof1=tofs1[0]; } + if(f0cur->getMeshIteration()!=mesh->getIteration() || f0cur->getMeshOrder()!=mesh->getOrder()) + { + std::ostringstream oss; oss << "MEDFileAnyTypeFieldMultiTS::CheckSupportAcrossTime : first field points to mesh time step (" << f0cur->getMeshIteration() << ","<< f0cur->getMeshOrder() << ") whereas input mesh points to time step (" << mesh->getIteration() << "," << mesh->getOrder() << ") !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + if(f1cur->getMeshIteration()!=mesh->getIteration() || f1cur->getMeshOrder()!=mesh->getOrder()) + { + std::ostringstream oss; oss << "MEDFileAnyTypeFieldMultiTS::CheckSupportAcrossTime : second field points to mesh time step (" << f1cur->getMeshIteration() << ","<< f1cur->getMeshOrder() << ") whereas input mesh points to time step (" << mesh->getIteration() << "," << mesh->getOrder() << ") !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + if(f0cur->getIteration()!=f1cur->getIteration() || f0cur->getOrder()!=f1cur->getOrder()) + { + std::ostringstream oss; oss << "MEDFileAnyTypeFieldMultiTS::CheckSupportAcrossTime : all the time steps must be the same ! it is not the case (" << f0cur->getIteration() << "," << f0cur->getOrder() << ")!=(" << f1cur->getIteration() << "," << f1cur->getOrder() << ") !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + } + return nts; +} + +MEDFileAnyTypeFieldMultiTSIterator *MEDFileAnyTypeFieldMultiTS::iterator() +{ + return new MEDFileAnyTypeFieldMultiTSIterator(this); +} + +//= MEDFileFieldMultiTS + +/*! + * Returns a new empty instance of MEDFileFieldMultiTS. + * \return MEDFileFieldMultiTS * - a new instance of MEDFileFieldMultiTS. The caller + * is to delete this field using decrRef() as it is no more needed. + */ +MEDFileFieldMultiTS *MEDFileFieldMultiTS::New() +{ + return new MEDFileFieldMultiTS; +} + +/*! + * Returns a new instance of MEDFileFieldMultiTS holding data of the first field + * that has been read from a specified MED file. + * \param [in] fileName - the name of the MED file to read. + * \return MEDFileFieldMultiTS * - a new instance of MEDFileFieldMultiTS. The caller + * is to delete this field using decrRef() as it is no more needed. + * \throw If reading the file fails. + */ +MEDFileFieldMultiTS *MEDFileFieldMultiTS::New(const std::string& fileName, bool loadAll) +{ + MEDCouplingAutoRefCountObjectPtr<MEDFileFieldMultiTS> ret=new MEDFileFieldMultiTS(fileName,loadAll,0); + ret->contentNotNull();//to check that content type matches with \a this type. + return ret.retn(); +} + +/*! + * Returns a new instance of MEDFileFieldMultiTS holding data of a given field + * that has been read from a specified MED file. + * \param [in] fileName - the name of the MED file to read. + * \param [in] fieldName - the name of the field to read. + * \return MEDFileFieldMultiTS * - a new instance of MEDFileFieldMultiTS. The caller + * is to delete this field using decrRef() as it is no more needed. + * \throw If reading the file fails. + * \throw If there is no field named \a fieldName in the file. + */ +MEDFileFieldMultiTS *MEDFileFieldMultiTS::New(const std::string& fileName, const std::string& fieldName, bool loadAll) +{ + MEDCouplingAutoRefCountObjectPtr<MEDFileFieldMultiTS> ret=new MEDFileFieldMultiTS(fileName,fieldName,loadAll,0); + ret->contentNotNull();//to check that content type matches with \a this type. + return ret.retn(); +} + +/*! + * Returns a new instance of MEDFileFieldMultiTS. If \a shallowCopyOfContent is true the content of \a other is shallow copied. + * If \a shallowCopyOfContent is false, \a other is taken to be the content of \a this. + * + * Returns a new instance of MEDFileFieldMultiTS holding either a shallow copy + * of a given MEDFileFieldMultiTSWithoutSDA ( \a other ) or \a other itself. + * \warning this is a shallow copy constructor + * \param [in] other - a MEDFileField1TSWithoutSDA to copy. + * \param [in] shallowCopyOfContent - if \c true, a shallow copy of \a other is created. + * \return MEDFileFieldMultiTS * - a new instance of MEDFileFieldMultiTS. The caller + * is to delete this field using decrRef() as it is no more needed. + */ +MEDFileFieldMultiTS *MEDFileFieldMultiTS::New(const MEDFileFieldMultiTSWithoutSDA& other, bool shallowCopyOfContent) +{ + return new MEDFileFieldMultiTS(other,shallowCopyOfContent); +} + +MEDFileFieldMultiTS *MEDFileFieldMultiTS::LoadSpecificEntities(const std::string& fileName, const std::string& fieldName, const std::vector< std::pair<TypeOfField,INTERP_KERNEL::NormalizedCellType> >& entities, bool loadAll) +{ + MEDCouplingAutoRefCountObjectPtr<MEDFileFieldMultiTS> ret(new MEDFileFieldMultiTS(fileName,fieldName,loadAll,0,&entities)); + ret->contentNotNull();//to check that content type matches with \a this type. + return ret.retn(); +} + +MEDFileAnyTypeFieldMultiTS *MEDFileFieldMultiTS::shallowCpy() const +{ + return new MEDFileFieldMultiTS(*this); +} + +void MEDFileFieldMultiTS::checkCoherencyOfType(const MEDFileAnyTypeField1TS *f1ts) const +{ + if(!f1ts) + throw INTERP_KERNEL::Exception("MEDFileFieldMultiTS::checkCoherencyOfType : input field1TS is NULL ! Impossible to check !"); + const MEDFileField1TS *f1tsC=dynamic_cast<const MEDFileField1TS *>(f1ts); + if(!f1tsC) + throw INTERP_KERNEL::Exception("MEDFileFieldMultiTS::checkCoherencyOfType : the input field1TS is not a FLOAT64 type !"); +} + +/*! + * This method performs a copy with datatype modification ( float64->int32 ) of \a this. The globals information are copied + * following the given input policy. + * + * \param [in] isDeepCpyGlobs - a boolean that indicates the behaviour concerning globals (profiles and localizations) + * By default (true) the globals are deeply copied. + * \return MEDFileIntFieldMultiTS * - a new object that is the result of the conversion of \a this to int32 field. + */ +MEDFileIntFieldMultiTS *MEDFileFieldMultiTS::convertToInt(bool isDeepCpyGlobs) const +{ + MEDCouplingAutoRefCountObjectPtr<MEDFileIntFieldMultiTS> ret; + const MEDFileAnyTypeFieldMultiTSWithoutSDA *content(_content); + if(content) + { + const MEDFileFieldMultiTSWithoutSDA *contc=dynamic_cast<const MEDFileFieldMultiTSWithoutSDA *>(content); + if(!contc) + throw INTERP_KERNEL::Exception("MEDFileFieldMultiTS::convertToInt : the content inside this is not FLOAT64 ! This is incoherent !"); + MEDCouplingAutoRefCountObjectPtr<MEDFileIntFieldMultiTSWithoutSDA> newc(contc->convertToInt()); + ret=static_cast<MEDFileIntFieldMultiTS *>(MEDFileAnyTypeFieldMultiTS::BuildNewInstanceFromContent((MEDFileIntFieldMultiTSWithoutSDA *)newc,getFileName())); + } + else + ret=MEDFileIntFieldMultiTS::New(); + if(isDeepCpyGlobs) + ret->deepCpyGlobs(*this); + else + ret->shallowCpyGlobs(*this); + return ret.retn(); +} + +/*! + * Returns a new MEDFileField1TS holding data of a given time step of \a this field. + * \param [in] pos - a time step id. + * \return MEDFileField1TS * - a new instance of MEDFileField1TS. The caller is to + * delete this field using decrRef() as it is no more needed. + * \throw If \a pos is not a valid time step id. + */ +MEDFileAnyTypeField1TS *MEDFileFieldMultiTS::getTimeStepAtPos(int pos) const +{ + const MEDFileAnyTypeField1TSWithoutSDA *item=contentNotNullBase()->getTimeStepAtPos2(pos); + if(!item) + { + std::ostringstream oss; oss << "MEDFileFieldMultiTS::getTimeStepAtPos : field at pos #" << pos << " is null !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + const MEDFileField1TSWithoutSDA *itemC=dynamic_cast<const MEDFileField1TSWithoutSDA *>(item); + if(itemC) + { + MEDCouplingAutoRefCountObjectPtr<MEDFileField1TS> ret=MEDFileField1TS::New(*itemC,false); + ret->shallowCpyGlobs(*this); + return ret.retn(); + } + std::ostringstream oss; oss << "MEDFileFieldMultiTS::getTimeStepAtPos : type of field at pos #" << pos << " is not FLOAT64 !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); +} + +/*! + * Returns a new MEDCouplingFieldDouble of a given type, of a given time step, lying on + * mesh entities of a given dimension of the first mesh in MED file. + * For more info, see \ref AdvMEDLoaderAPIFieldRW + * \param [in] type - a spatial discretization of interest. + * \param [in] iteration - the iteration number of a required time step. + * \param [in] order - the iteration order number of required time step. + * \param [in] meshDimRelToMax - a relative dimension of the supporting mesh entities. + * \param [in] renumPol - specifies how to permute values of the result field according to + * the optional numbers of cells and nodes, if any. The valid values are + * - 0 - do not permute. + * - 1 - permute cells. + * - 2 - permute nodes. + * - 3 - permute cells and nodes. + * + * \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 MED file is not readable. + * \throw If there is no mesh in the MED file. + * \throw If there are no mesh entities of \a meshDimRelToMax dimension in the mesh. + * \throw If no field values of the required parameters are available. + */ +MEDCouplingFieldDouble *MEDFileFieldMultiTS::getFieldAtLevel(TypeOfField type, int iteration, int order, int meshDimRelToMax, int renumPol) const +{ + const MEDFileAnyTypeField1TSWithoutSDA& myF1TS=contentNotNullBase()->getTimeStepEntry(iteration,order); + const MEDFileField1TSWithoutSDA *myF1TSC=dynamic_cast<const MEDFileField1TSWithoutSDA *>(&myF1TS); + if(!myF1TSC) + throw INTERP_KERNEL::Exception("MEDFileFieldMultiTS::getFieldAtLevel : mismatch of type of field expecting FLOAT64 !"); + MEDCouplingAutoRefCountObjectPtr<DataArray> arrOut; + MEDCouplingAutoRefCountObjectPtr<MEDCouplingFieldDouble> ret=myF1TSC->getFieldAtLevel(type,meshDimRelToMax,std::string(),renumPol,this,arrOut,*contentNotNullBase()); + MEDFileField1TS::SetDataArrayDoubleInField(ret,arrOut); + return ret.retn(); +} + +/*! + * Returns a new MEDCouplingFieldDouble of a given type, of a given time step, lying on + * the top level cells of the first mesh in MED file. + * For more info, see \ref AdvMEDLoaderAPIFieldRW + * \param [in] type - a spatial discretization of interest. + * \param [in] iteration - the iteration number of a required time step. + * \param [in] order - the iteration order number of required time step. + * \param [in] renumPol - specifies how to permute values of the result field according to + * the optional numbers of cells and nodes, if any. The valid values are + * - 0 - do not permute. + * - 1 - permute cells. + * - 2 - permute nodes. + * - 3 - permute cells and nodes. + * + * \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 MED file is not readable. + * \throw If there is no mesh in the MED file. + * \throw If no field values of the required parameters are available. + */ +MEDCouplingFieldDouble *MEDFileFieldMultiTS::getFieldAtTopLevel(TypeOfField type, int iteration, int order, int renumPol) const +{ + const MEDFileAnyTypeField1TSWithoutSDA& myF1TS=contentNotNullBase()->getTimeStepEntry(iteration,order); + const MEDFileField1TSWithoutSDA *myF1TSC=dynamic_cast<const MEDFileField1TSWithoutSDA *>(&myF1TS); + if(!myF1TSC) + throw INTERP_KERNEL::Exception("MEDFileFieldMultiTS::getFieldAtTopLevel : mismatch of type of field !"); + MEDCouplingAutoRefCountObjectPtr<DataArray> arrOut; + MEDCouplingAutoRefCountObjectPtr<MEDCouplingFieldDouble> ret=myF1TSC->getFieldAtTopLevel(type,std::string(),renumPol,this,arrOut,*contentNotNullBase()); + MEDFileField1TS::SetDataArrayDoubleInField(ret,arrOut); + return ret.retn(); +} + +/*! + * Returns a new MEDCouplingFieldDouble of a given type, of a given time step, lying on + * a given support. + * For more info, see \ref AdvMEDLoaderAPIFieldRW + * \param [in] type - a spatial discretization of interest. + * \param [in] iteration - the iteration number of a required time step. + * \param [in] order - the iteration order number of required time step. + * \param [in] meshDimRelToMax - a relative dimension of the supporting mesh entities. + * \param [in] mesh - the supporting mesh. + * \param [in] renumPol - specifies how to permute values of the result field according to + * the optional numbers of cells and nodes, if any. The valid values are + * - 0 - do not permute. + * - 1 - permute cells. + * - 2 - permute nodes. + * - 3 - permute cells and nodes. + * + * \return MEDCouplingFieldDouble * - a new instance of MEDCouplingFieldDouble. The + * caller is to delete this field using decrRef() as it is no more needed. + * \throw If there are no mesh entities of \a meshDimRelToMax dimension in the mesh. + * \throw If no field of \a this is lying on \a mesh. + * \throw If no field values of the required parameters are available. + */ +MEDCouplingFieldDouble *MEDFileFieldMultiTS::getFieldOnMeshAtLevel(TypeOfField type, int iteration, int order, int meshDimRelToMax, const MEDFileMesh *mesh, int renumPol) const +{ + const MEDFileAnyTypeField1TSWithoutSDA& myF1TS=contentNotNullBase()->getTimeStepEntry(iteration,order); + const MEDFileField1TSWithoutSDA *myF1TSC=dynamic_cast<const MEDFileField1TSWithoutSDA *>(&myF1TS); + if(!myF1TSC) + throw INTERP_KERNEL::Exception("MEDFileFieldMultiTS::getFieldOnMeshAtLevel : mismatch of type of field !"); + MEDCouplingAutoRefCountObjectPtr<DataArray> arrOut; + MEDCouplingAutoRefCountObjectPtr<MEDCouplingFieldDouble> ret=myF1TSC->getFieldOnMeshAtLevel(type,meshDimRelToMax,renumPol,this,mesh,arrOut,*contentNotNullBase()); + MEDFileField1TS::SetDataArrayDoubleInField(ret,arrOut); + return ret.retn(); +} + +/*! + * Returns a new MEDCouplingFieldDouble of given type, of a given time step, lying on a + * given support. + * For more info, see \ref AdvMEDLoaderAPIFieldRW + * \param [in] type - a spatial discretization of the new field. + * \param [in] iteration - the iteration number of a required time step. + * \param [in] order - the iteration order number of required time step. + * \param [in] mesh - the supporting mesh. + * \param [in] renumPol - specifies how to permute values of the result field according to + * the optional numbers of cells and nodes, if any. The valid values are + * - 0 - do not permute. + * - 1 - permute cells. + * - 2 - permute nodes. + * - 3 - permute cells and nodes. + * + * \return MEDCouplingFieldDouble * - a new instance of MEDCouplingFieldDouble. The + * caller is to delete this field using decrRef() as it is no more needed. + * \throw If no field of \a this is lying on \a mesh. + * \throw If no field values of the required parameters are available. + */ +MEDCouplingFieldDouble *MEDFileFieldMultiTS::getFieldOnMeshAtLevel(TypeOfField type, int iteration, int order, const MEDCouplingMesh *mesh, int renumPol) const +{ + const MEDFileAnyTypeField1TSWithoutSDA& myF1TS=contentNotNullBase()->getTimeStepEntry(iteration,order); + const MEDFileField1TSWithoutSDA *myF1TSC=dynamic_cast<const MEDFileField1TSWithoutSDA *>(&myF1TS); + if(!myF1TSC) + throw INTERP_KERNEL::Exception("MEDFileFieldMultiTS::getFieldOnMeshAtLevel : mismatch of type of field !"); + MEDCouplingAutoRefCountObjectPtr<DataArray> arrOut; + MEDCouplingAutoRefCountObjectPtr<MEDCouplingFieldDouble> ret=myF1TSC->getFieldOnMeshAtLevel(type,renumPol,this,mesh,0,0,arrOut,*contentNotNullBase()); + MEDFileField1TS::SetDataArrayDoubleInField(ret,arrOut); + return ret.retn(); +} + +/*! + * This method has a close behaviour than MEDFileFieldMultiTS::getFieldAtLevel. + * This method is called 'old' because the user should give the mesh name he wants to use for it's field. + * This method is useful for MED2 file format when field on different mesh was autorized. + */ +MEDCouplingFieldDouble *MEDFileFieldMultiTS::getFieldAtLevelOld(TypeOfField type, const std::string& mname, int iteration, int order, int meshDimRelToMax, int renumPol) const +{ + const MEDFileAnyTypeField1TSWithoutSDA& myF1TS=contentNotNullBase()->getTimeStepEntry(iteration,order); + const MEDFileField1TSWithoutSDA *myF1TSC=dynamic_cast<const MEDFileField1TSWithoutSDA *>(&myF1TS); + if(!myF1TSC) + throw INTERP_KERNEL::Exception("MEDFileFieldMultiTS::getFieldAtLevelOld : mismatch of type of field !"); + MEDCouplingAutoRefCountObjectPtr<DataArray> arrOut; + MEDCouplingAutoRefCountObjectPtr<MEDCouplingFieldDouble> ret=myF1TSC->getFieldAtLevel(type,meshDimRelToMax,mname,renumPol,this,arrOut,*contentNotNullBase()); + MEDFileField1TS::SetDataArrayDoubleInField(ret,arrOut); + return ret.retn(); +} + +/*! + * Returns values and a profile of the field of a given type, of a given time step, + * lying on a given support. + * For more info, see \ref AdvMEDLoaderAPIFieldRW + * \param [in] type - a spatial discretization of the field. + * \param [in] iteration - the iteration number of a required time step. + * \param [in] order - the iteration order number of required time step. + * \param [in] meshDimRelToMax - a relative dimension of the supporting mesh entities. + * \param [in] mesh - the supporting mesh. + * \param [out] pfl - a new instance of DataArrayInt holding ids of mesh entities the + * field of interest lies on. If the field lies on all entities of the given + * dimension, all ids in \a pfl are zero. The caller is to delete this array + * using decrRef() as it is no more needed. + * \param [in] glob - the global data storing profiles and localization. + * \return DataArrayDouble * - a new instance of DataArrayDouble holding values of the + * field. The caller is to delete this array using decrRef() as it is no more needed. + * \throw If there are no mesh entities of \a meshDimRelToMax dimension in \a mesh. + * \throw If no field of \a this is lying on \a mesh. + * \throw If no field values of the required parameters are available. + */ +DataArrayDouble *MEDFileFieldMultiTS::getFieldWithProfile(TypeOfField type, int iteration, int order, int meshDimRelToMax, const MEDFileMesh *mesh, DataArrayInt *&pfl) const +{ + const MEDFileAnyTypeField1TSWithoutSDA& myF1TS=contentNotNullBase()->getTimeStepEntry(iteration,order); + const MEDFileField1TSWithoutSDA *myF1TSC=dynamic_cast<const MEDFileField1TSWithoutSDA *>(&myF1TS); + if(!myF1TSC) + throw INTERP_KERNEL::Exception("MEDFileFieldMultiTS::getFieldWithProfile : mismatch of type of field !"); + MEDCouplingAutoRefCountObjectPtr<DataArray> ret=myF1TSC->getFieldWithProfile(type,meshDimRelToMax,mesh,pfl,this,*contentNotNullBase()); + return MEDFileField1TS::ReturnSafelyDataArrayDouble(ret); +} + +const MEDFileFieldMultiTSWithoutSDA *MEDFileFieldMultiTS::contentNotNull() const +{ + const MEDFileAnyTypeFieldMultiTSWithoutSDA *pt(_content); + if(!pt) + throw INTERP_KERNEL::Exception("MEDFileFieldMultiTS::contentNotNull : the content pointer is null !"); + const MEDFileFieldMultiTSWithoutSDA *ret=dynamic_cast<const MEDFileFieldMultiTSWithoutSDA *>(pt); + if(!ret) + throw INTERP_KERNEL::Exception("MEDFileFieldMultiTS::contentNotNull : the content pointer is not null but it is not of type double ! Reason is maybe that the read field has not the type FLOAT64 !"); + return ret; +} + +MEDFileFieldMultiTSWithoutSDA *MEDFileFieldMultiTS::contentNotNull() +{ + MEDFileAnyTypeFieldMultiTSWithoutSDA *pt(_content); + if(!pt) + throw INTERP_KERNEL::Exception("MEDFileFieldMultiTS::contentNotNull : the non const content pointer is null !"); + MEDFileFieldMultiTSWithoutSDA *ret=dynamic_cast<MEDFileFieldMultiTSWithoutSDA *>(pt); + if(!ret) + throw INTERP_KERNEL::Exception("MEDFileFieldMultiTS::contentNotNull : the non const content pointer is not null but it is not of type double ! Reason is maybe that the read field has not the type FLOAT64 !"); + return ret; +} + +/*! + * Adds a MEDCouplingFieldDouble to \a this as another time step. The underlying mesh of + * the given field is checked if its elements are sorted suitable for writing to MED file + * ("STB" stands for "Sort By Type"), if not, an exception is thrown. + * For more info, see \ref AdvMEDLoaderAPIFieldRW + * \param [in] field - the field to add to \a this. + * \throw If the name of \a field is empty. + * \throw If the data array of \a field is not set. + * \throw If existing time steps have different name or number of components than \a field. + * \throw If the underlying mesh of \a field has no name. + * \throw If elements in the mesh are not in the order suitable for writing to the MED file. + */ +void MEDFileFieldMultiTS::appendFieldNoProfileSBT(const MEDCouplingFieldDouble *field) +{ + const DataArrayDouble *arr=0; + if(field) + arr=field->getArray(); + contentNotNull()->appendFieldNoProfileSBT(field,arr,*this); +} + +/*! + * Adds a MEDCouplingFieldDouble to \a this as another time step. + * The mesh support of input parameter \a field is ignored here, it can be NULL. + * The support of field \a field is expected to be those computed with the input parameter \a mesh, \a meshDimRelToMax, + * and \a profile. + * + * This method will check that the field based on the computed support is coherent. If not an exception will be thrown. + * A new profile is added only if no equal profile is missing. + * For more info, see \ref AdvMEDLoaderAPIFieldRW + * \param [in] field - the field to add to \a this. The mesh support of field is ignored. + * \param [in] mesh - the supporting mesh of \a field. + * \param [in] meshDimRelToMax - a relative dimension of mesh entities \a field lies on (useless if field spatial discretization is ON_NODES). + * \param [in] profile - ids of mesh entities on which corresponding field values lie. + * \throw If either \a field or \a mesh or \a profile has an empty name. + * \throw If there are no mesh entities of \a meshDimRelToMax dimension in \a mesh. + * \throw If the data array of \a field is not set. + * \throw If the data array of \a this is already allocated but has different number of + * components than \a field. + * \throw If elements in \a mesh are not in the order suitable for writing to the MED file. + * \sa setFieldNoProfileSBT() + */ +void MEDFileFieldMultiTS::appendFieldProfile(const MEDCouplingFieldDouble *field, const MEDFileMesh *mesh, int meshDimRelToMax, const DataArrayInt *profile) +{ + const DataArrayDouble *arr=0; + if(field) + arr=field->getArray(); + contentNotNull()->appendFieldProfile(field,arr,mesh,meshDimRelToMax,profile,*this); +} + +MEDFileFieldMultiTS::MEDFileFieldMultiTS() +{ + _content=new MEDFileFieldMultiTSWithoutSDA; +} + +MEDFileFieldMultiTS::MEDFileFieldMultiTS(const std::string& fileName, bool loadAll, const MEDFileMeshes *ms) +try:MEDFileAnyTypeFieldMultiTS(fileName,loadAll,ms) +{ +} +catch(INTERP_KERNEL::Exception& e) +{ throw e; } + +MEDFileFieldMultiTS::MEDFileFieldMultiTS(const std::string& fileName, const std::string& fieldName, bool loadAll, const MEDFileMeshes *ms, const std::vector< std::pair<TypeOfField,INTERP_KERNEL::NormalizedCellType> > *entities) +try:MEDFileAnyTypeFieldMultiTS(fileName,fieldName,loadAll,ms,entities) +{ +} +catch(INTERP_KERNEL::Exception& e) +{ throw e; } + +MEDFileFieldMultiTS::MEDFileFieldMultiTS(const MEDFileFieldMultiTSWithoutSDA& other, bool shallowCopyOfContent):MEDFileAnyTypeFieldMultiTS(other,shallowCopyOfContent) +{ +} + +std::vector< std::vector<DataArrayDouble *> > MEDFileFieldMultiTS::getFieldSplitedByType2(int iteration, int order, const std::string& mname, std::vector<INTERP_KERNEL::NormalizedCellType>& types, std::vector< std::vector<TypeOfField> >& typesF, std::vector< std::vector<std::string> >& pfls, std::vector< std::vector<std::string> >& locs) const +{ + return contentNotNull()->getFieldSplitedByType2(iteration,order,mname,types,typesF,pfls,locs); +} + +DataArrayDouble *MEDFileFieldMultiTS::getUndergroundDataArray(int iteration, int order) const +{ + return static_cast<DataArrayDouble *>(contentNotNull()->getUndergroundDataArray(iteration,order)); +} + +DataArrayDouble *MEDFileFieldMultiTS::getUndergroundDataArrayExt(int iteration, int order, std::vector< std::pair<std::pair<INTERP_KERNEL::NormalizedCellType,int>,std::pair<int,int> > >& entries) const +{ + return static_cast<DataArrayDouble *>(contentNotNull()->getUndergroundDataArrayExt(iteration,order,entries)); +} + +//= MEDFileAnyTypeFieldMultiTSIterator + +MEDFileAnyTypeFieldMultiTSIterator::MEDFileAnyTypeFieldMultiTSIterator(MEDFileAnyTypeFieldMultiTS *fmts):_fmts(fmts),_iter_id(0),_nb_iter(0) +{ + if(fmts) + { + fmts->incrRef(); + _nb_iter=fmts->getNumberOfTS(); + } +} + +MEDFileAnyTypeFieldMultiTSIterator::~MEDFileAnyTypeFieldMultiTSIterator() +{ +} + +MEDFileAnyTypeField1TS *MEDFileAnyTypeFieldMultiTSIterator::nextt() +{ + if(_iter_id<_nb_iter) + { + MEDFileAnyTypeFieldMultiTS *fmts(_fmts); + if(fmts) + return fmts->getTimeStepAtPos(_iter_id++); + else + return 0; + } + else + return 0; +} + +//= MEDFileIntFieldMultiTS + +/*! + * Returns a new empty instance of MEDFileFieldMultiTS. + * \return MEDFileIntFieldMultiTS * - a new instance of MEDFileIntFieldMultiTS. The caller + * is to delete this field using decrRef() as it is no more needed. + */ +MEDFileIntFieldMultiTS *MEDFileIntFieldMultiTS::New() +{ + return new MEDFileIntFieldMultiTS; +} + +/*! + * Returns a new instance of MEDFileIntFieldMultiTS holding data of the first field + * that has been read from a specified MED file. + * \param [in] fileName - the name of the MED file to read. + * \return MEDFileFieldMultiTS * - a new instance of MEDFileIntFieldMultiTS. The caller + * is to delete this field using decrRef() as it is no more needed. + * \throw If reading the file fails. + */ +MEDFileIntFieldMultiTS *MEDFileIntFieldMultiTS::New(const std::string& fileName, bool loadAll) +{ + MEDCouplingAutoRefCountObjectPtr<MEDFileIntFieldMultiTS> ret=new MEDFileIntFieldMultiTS(fileName,loadAll,0); + ret->contentNotNull();//to check that content type matches with \a this type. + return ret.retn(); +} + +/*! + * Returns a new instance of MEDFileIntFieldMultiTS holding data of a given field + * that has been read from a specified MED file. + * \param [in] fileName - the name of the MED file to read. + * \param [in] fieldName - the name of the field to read. + * \return MEDFileFieldMultiTS * - a new instance of MEDFileIntFieldMultiTS. The caller + * is to delete this field using decrRef() as it is no more needed. + * \throw If reading the file fails. + * \throw If there is no field named \a fieldName in the file. + */ +MEDFileIntFieldMultiTS *MEDFileIntFieldMultiTS::New(const std::string& fileName, const std::string& fieldName, bool loadAll) +{ + MEDCouplingAutoRefCountObjectPtr<MEDFileIntFieldMultiTS> ret=new MEDFileIntFieldMultiTS(fileName,fieldName,loadAll,0); + ret->contentNotNull();//to check that content type matches with \a this type. + return ret.retn(); +} + +/*! + * Returns a new instance of MEDFileIntFieldMultiTS. If \a shallowCopyOfContent is true the content of \a other is shallow copied. + * If \a shallowCopyOfContent is false, \a other is taken to be the content of \a this. + * + * Returns a new instance of MEDFileIntFieldMultiTS holding either a shallow copy + * of a given MEDFileIntFieldMultiTSWithoutSDA ( \a other ) or \a other itself. + * \warning this is a shallow copy constructor + * \param [in] other - a MEDFileIntField1TSWithoutSDA to copy. + * \param [in] shallowCopyOfContent - if \c true, a shallow copy of \a other is created. + * \return MEDFileIntFieldMultiTS * - a new instance of MEDFileIntFieldMultiTS. The caller + * is to delete this field using decrRef() as it is no more needed. + */ +MEDFileIntFieldMultiTS *MEDFileIntFieldMultiTS::New(const MEDFileIntFieldMultiTSWithoutSDA& other, bool shallowCopyOfContent) +{ + return new MEDFileIntFieldMultiTS(other,shallowCopyOfContent); +} + +MEDFileIntFieldMultiTS *MEDFileIntFieldMultiTS::LoadSpecificEntities(const std::string& fileName, const std::string& fieldName, const std::vector< std::pair<TypeOfField,INTERP_KERNEL::NormalizedCellType> >& entities, bool loadAll) +{ + MEDCouplingAutoRefCountObjectPtr<MEDFileIntFieldMultiTS> ret=new MEDFileIntFieldMultiTS(fileName,fieldName,loadAll,0,&entities); + ret->contentNotNull();//to check that content type matches with \a this type. + return ret.retn(); +} + +/*! + * This method performs a copy with datatype modification ( int32->float64 ) of \a this. The globals information are copied + * following the given input policy. + * + * \param [in] isDeepCpyGlobs - a boolean that indicates the behaviour concerning globals (profiles and localizations) + * By default (true) the globals are deeply copied. + * \return MEDFileFieldMultiTS * - a new object that is the result of the conversion of \a this to float64 field. + */ +MEDFileFieldMultiTS *MEDFileIntFieldMultiTS::convertToDouble(bool isDeepCpyGlobs) const +{ + MEDCouplingAutoRefCountObjectPtr<MEDFileFieldMultiTS> ret; + const MEDFileAnyTypeFieldMultiTSWithoutSDA *content(_content); + if(content) + { + const MEDFileIntFieldMultiTSWithoutSDA *contc=dynamic_cast<const MEDFileIntFieldMultiTSWithoutSDA *>(content); + if(!contc) + throw INTERP_KERNEL::Exception("MEDFileIntFieldMultiTS::convertToInt : the content inside this is not INT32 ! This is incoherent !"); + MEDCouplingAutoRefCountObjectPtr<MEDFileFieldMultiTSWithoutSDA> newc(contc->convertToDouble()); + ret=static_cast<MEDFileFieldMultiTS *>(MEDFileAnyTypeFieldMultiTS::BuildNewInstanceFromContent((MEDFileFieldMultiTSWithoutSDA *)newc,getFileName())); + } + else + ret=MEDFileFieldMultiTS::New(); + if(isDeepCpyGlobs) + ret->deepCpyGlobs(*this); + else + ret->shallowCpyGlobs(*this); + return ret.retn(); +} + +MEDFileAnyTypeFieldMultiTS *MEDFileIntFieldMultiTS::shallowCpy() const +{ + return new MEDFileIntFieldMultiTS(*this); +} + +void MEDFileIntFieldMultiTS::checkCoherencyOfType(const MEDFileAnyTypeField1TS *f1ts) const +{ + if(!f1ts) + throw INTERP_KERNEL::Exception("MEDFileIntFieldMultiTS::checkCoherencyOfType : input field1TS is NULL ! Impossible to check !"); + const MEDFileIntField1TS *f1tsC=dynamic_cast<const MEDFileIntField1TS *>(f1ts); + if(!f1tsC) + throw INTERP_KERNEL::Exception("MEDFileIntFieldMultiTS::checkCoherencyOfType : the input field1TS is not a INT32 type !"); +} + +/*! + * Returns a new MEDCouplingFieldDouble of a given type, of a given time step, lying on + * mesh entities of a given dimension of the first mesh in MED file. + * For more info, see \ref AdvMEDLoaderAPIFieldRW + * \param [in] type - a spatial discretization of interest. + * \param [in] iteration - the iteration number of a required time step. + * \param [in] order - the iteration order number of required time step. + * \param [in] meshDimRelToMax - a relative dimension of the supporting mesh entities. + * \param [out] arrOut - the DataArrayInt containing values of field. + * \param [in] renumPol - specifies how to permute values of the result field according to + * the optional numbers of cells and nodes, if any. The valid values are + * - 0 - do not permute. + * - 1 - permute cells. + * - 2 - permute nodes. + * - 3 - permute cells and nodes. + * + * \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 MED file is not readable. + * \throw If there is no mesh in the MED file. + * \throw If there are no mesh entities of \a meshDimRelToMax dimension in the mesh. + * \throw If no field values of the required parameters are available. + */ +MEDCouplingFieldDouble *MEDFileIntFieldMultiTS::getFieldAtLevel(TypeOfField type, int iteration, int order, int meshDimRelToMax, DataArrayInt* &arrOut, int renumPol) const +{ + const MEDFileAnyTypeField1TSWithoutSDA& myF1TS=contentNotNullBase()->getTimeStepEntry(iteration,order); + const MEDFileIntField1TSWithoutSDA *myF1TSC=dynamic_cast<const MEDFileIntField1TSWithoutSDA *>(&myF1TS); + if(!myF1TSC) + throw INTERP_KERNEL::Exception("MEDFileIntFieldMultiTS::getFieldAtLevel : mismatch of type of field expecting INT32 !"); + MEDCouplingAutoRefCountObjectPtr<DataArray> arr; + MEDCouplingAutoRefCountObjectPtr<MEDCouplingFieldDouble> ret=myF1TSC->getFieldAtLevel(type,meshDimRelToMax,std::string(),renumPol,this,arr,*contentNotNullBase()); + arrOut=MEDFileIntField1TS::ReturnSafelyDataArrayInt(arr); + return ret.retn(); +} + +/*! + * Returns a new MEDCouplingFieldDouble of a given type, of a given time step, lying on + * the top level cells of the first mesh in MED file. + * For more info, see \ref AdvMEDLoaderAPIFieldRW + * \param [in] type - a spatial discretization of interest. + * \param [in] iteration - the iteration number of a required time step. + * \param [in] order - the iteration order number of required time step. + * \param [out] arrOut - the DataArrayInt containing values of field. + * \param [in] renumPol - specifies how to permute values of the result field according to + * the optional numbers of cells and nodes, if any. The valid values are + * - 0 - do not permute. + * - 1 - permute cells. + * - 2 - permute nodes. + * - 3 - permute cells and nodes. + * + * \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 MED file is not readable. + * \throw If there is no mesh in the MED file. + * \throw If no field values of the required parameters are available. + */ +MEDCouplingFieldDouble *MEDFileIntFieldMultiTS::getFieldAtTopLevel(TypeOfField type, int iteration, int order, DataArrayInt* &arrOut, int renumPol) const +{ + const MEDFileAnyTypeField1TSWithoutSDA& myF1TS=contentNotNullBase()->getTimeStepEntry(iteration,order); + const MEDFileIntField1TSWithoutSDA *myF1TSC=dynamic_cast<const MEDFileIntField1TSWithoutSDA *>(&myF1TS); + if(!myF1TSC) + throw INTERP_KERNEL::Exception("MEDFileIntFieldMultiTS::getFieldAtTopLevel : mismatch of type of field ! INT32 expected !"); + MEDCouplingAutoRefCountObjectPtr<DataArray> arr; + MEDCouplingAutoRefCountObjectPtr<MEDCouplingFieldDouble> ret=myF1TSC->getFieldAtTopLevel(type,std::string(),renumPol,this,arr,*contentNotNullBase()); + arrOut=MEDFileIntField1TS::ReturnSafelyDataArrayInt(arr); + return ret.retn(); +} + +/*! + * Returns a new MEDCouplingFieldDouble of a given type, of a given time step, lying on + * a given support. + * For more info, see \ref AdvMEDLoaderAPIFieldRW + * \param [in] type - a spatial discretization of interest. + * \param [in] iteration - the iteration number of a required time step. + * \param [in] order - the iteration order number of required time step. + * \param [out] arrOut - the DataArrayInt containing values of field. + * \param [in] meshDimRelToMax - a relative dimension of the supporting mesh entities. + * \param [in] mesh - the supporting mesh. + * \param [in] renumPol - specifies how to permute values of the result field according to + * the optional numbers of cells and nodes, if any. The valid values are + * - 0 - do not permute. + * - 1 - permute cells. + * - 2 - permute nodes. + * - 3 - permute cells and nodes. + * + * \return MEDCouplingFieldDouble * - a new instance of MEDCouplingFieldDouble. The + * caller is to delete this field using decrRef() as it is no more needed. + * \throw If there are no mesh entities of \a meshDimRelToMax dimension in the mesh. + * \throw If no field of \a this is lying on \a mesh. + * \throw If no field values of the required parameters are available. + */ +MEDCouplingFieldDouble *MEDFileIntFieldMultiTS::getFieldOnMeshAtLevel(TypeOfField type, int iteration, int order, int meshDimRelToMax, const MEDFileMesh *mesh, DataArrayInt* &arrOut, int renumPol) const +{ + const MEDFileAnyTypeField1TSWithoutSDA& myF1TS=contentNotNullBase()->getTimeStepEntry(iteration,order); + const MEDFileIntField1TSWithoutSDA *myF1TSC=dynamic_cast<const MEDFileIntField1TSWithoutSDA *>(&myF1TS); + if(!myF1TSC) + throw INTERP_KERNEL::Exception("MEDFileFieldMultiTS::getFieldOnMeshAtLevel : mismatch of type of field ! INT32 expected !"); + MEDCouplingAutoRefCountObjectPtr<DataArray> arr; + MEDCouplingAutoRefCountObjectPtr<MEDCouplingFieldDouble> ret=myF1TSC->getFieldOnMeshAtLevel(type,meshDimRelToMax,renumPol,this,mesh,arr,*contentNotNullBase()); + arrOut=MEDFileIntField1TS::ReturnSafelyDataArrayInt(arr); + return ret.retn(); +} + +/*! + * Returns a new MEDCouplingFieldDouble of given type, of a given time step, lying on a + * given support. + * For more info, see \ref AdvMEDLoaderAPIFieldRW + * \param [in] type - a spatial discretization of the new field. + * \param [in] iteration - the iteration number of a required time step. + * \param [in] order - the iteration order number of required time step. + * \param [in] mesh - the supporting mesh. + * \param [out] arrOut - the DataArrayInt containing values of field. + * \param [in] renumPol - specifies how to permute values of the result field according to + * the optional numbers of cells and nodes, if any. The valid values are + * - 0 - do not permute. + * - 1 - permute cells. + * - 2 - permute nodes. + * - 3 - permute cells and nodes. + * + * \return MEDCouplingFieldDouble * - a new instance of MEDCouplingFieldDouble. The + * caller is to delete this field using decrRef() as it is no more needed. + * \throw If no field of \a this is lying on \a mesh. + * \throw If no field values of the required parameters are available. + */ +MEDCouplingFieldDouble *MEDFileIntFieldMultiTS::getFieldOnMeshAtLevel(TypeOfField type, int iteration, int order, const MEDCouplingMesh *mesh, DataArrayInt* &arrOut, int renumPol) const +{ + const MEDFileAnyTypeField1TSWithoutSDA& myF1TS=contentNotNullBase()->getTimeStepEntry(iteration,order); + const MEDFileIntField1TSWithoutSDA *myF1TSC=dynamic_cast<const MEDFileIntField1TSWithoutSDA *>(&myF1TS); + if(!myF1TSC) + throw INTERP_KERNEL::Exception("MEDFileFieldIntMultiTS::getFieldOnMeshAtLevel : mismatch of type of field ! INT32 expected !"); + MEDCouplingAutoRefCountObjectPtr<DataArray> arr; + MEDCouplingAutoRefCountObjectPtr<MEDCouplingFieldDouble> ret=myF1TSC->getFieldOnMeshAtLevel(type,renumPol,this,mesh,0,0,arr,*contentNotNullBase()); + arrOut=MEDFileIntField1TS::ReturnSafelyDataArrayInt(arr); + return ret.retn(); +} + +/*! + * This method has a close behaviour than MEDFileIntFieldMultiTS::getFieldAtLevel. + * This method is called 'old' because the user should give the mesh name he wants to use for it's field. + * This method is useful for MED2 file format when field on different mesh was autorized. + */ +MEDCouplingFieldDouble *MEDFileIntFieldMultiTS::getFieldAtLevelOld(TypeOfField type, int iteration, int order, const std::string& mname, int meshDimRelToMax, DataArrayInt* &arrOut, int renumPol) const +{ + const MEDFileAnyTypeField1TSWithoutSDA& myF1TS=contentNotNullBase()->getTimeStepEntry(iteration,order); + const MEDFileIntField1TSWithoutSDA *myF1TSC=dynamic_cast<const MEDFileIntField1TSWithoutSDA *>(&myF1TS); + if(!myF1TSC) + throw INTERP_KERNEL::Exception("MEDFileFieldMultiTS::getFieldOnMeshAtLevel : mismatch of type of field ! INT32 expected !"); + MEDCouplingAutoRefCountObjectPtr<DataArray> arr; + MEDCouplingAutoRefCountObjectPtr<MEDCouplingFieldDouble> ret=myF1TSC->getFieldAtLevel(type,meshDimRelToMax,mname,renumPol,this,arr,*contentNotNullBase()); + arrOut=MEDFileIntField1TS::ReturnSafelyDataArrayInt(arr); + return ret.retn(); +} + +/*! + * Returns values and a profile of the field of a given type, of a given time step, + * lying on a given support. + * For more info, see \ref AdvMEDLoaderAPIFieldRW + * \param [in] type - a spatial discretization of the field. + * \param [in] iteration - the iteration number of a required time step. + * \param [in] order - the iteration order number of required time step. + * \param [in] meshDimRelToMax - a relative dimension of the supporting mesh entities. + * \param [in] mesh - the supporting mesh. + * \param [out] pfl - a new instance of DataArrayInt holding ids of mesh entities the + * field of interest lies on. If the field lies on all entities of the given + * dimension, all ids in \a pfl are zero. The caller is to delete this array + * using decrRef() as it is no more needed. + * \param [in] glob - the global data storing profiles and localization. + * \return DataArrayInt * - a new instance of DataArrayInt holding values of the + * field. The caller is to delete this array using decrRef() as it is no more needed. + * \throw If there are no mesh entities of \a meshDimRelToMax dimension in \a mesh. + * \throw If no field of \a this is lying on \a mesh. + * \throw If no field values of the required parameters are available. + */ +DataArrayInt *MEDFileIntFieldMultiTS::getFieldWithProfile(TypeOfField type, int iteration, int order, int meshDimRelToMax, const MEDFileMesh *mesh, DataArrayInt *&pfl) const +{ + const MEDFileAnyTypeField1TSWithoutSDA& myF1TS=contentNotNullBase()->getTimeStepEntry(iteration,order); + const MEDFileIntField1TSWithoutSDA *myF1TSC=dynamic_cast<const MEDFileIntField1TSWithoutSDA *>(&myF1TS); + if(!myF1TSC) + throw INTERP_KERNEL::Exception("MEDFileIntFieldMultiTS::getFieldWithProfile : mismatch of type of field ! INT32 expected !"); + MEDCouplingAutoRefCountObjectPtr<DataArray> ret=myF1TSC->getFieldWithProfile(type,meshDimRelToMax,mesh,pfl,this,*contentNotNullBase()); + return MEDFileIntField1TS::ReturnSafelyDataArrayInt(ret); +} + +/*! + * Returns a new MEDFileIntField1TS holding data of a given time step of \a this field. + * \param [in] pos - a time step id. + * \return MEDFileIntField1TS * - a new instance of MEDFileIntField1TS. The caller is to + * delete this field using decrRef() as it is no more needed. + * \throw If \a pos is not a valid time step id. + */ +MEDFileAnyTypeField1TS *MEDFileIntFieldMultiTS::getTimeStepAtPos(int pos) const +{ + const MEDFileAnyTypeField1TSWithoutSDA *item=contentNotNullBase()->getTimeStepAtPos2(pos); + if(!item) + { + std::ostringstream oss; oss << "MEDFileIntFieldMultiTS::getTimeStepAtPos : field at pos #" << pos << " is null !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + const MEDFileIntField1TSWithoutSDA *itemC=dynamic_cast<const MEDFileIntField1TSWithoutSDA *>(item); + if(itemC) + { + MEDCouplingAutoRefCountObjectPtr<MEDFileIntField1TS> ret=MEDFileIntField1TS::New(*itemC,false); + ret->shallowCpyGlobs(*this); + return ret.retn(); + } + std::ostringstream oss; oss << "MEDFileIntFieldMultiTS::getTimeStepAtPos : type of field at pos #" << pos << " is not INT32 !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); +} + +/*! + * Adds a MEDCouplingFieldDouble to \a this as another time step. The underlying mesh of + * the given field is checked if its elements are sorted suitable for writing to MED file + * ("STB" stands for "Sort By Type"), if not, an exception is thrown. + * For more info, see \ref AdvMEDLoaderAPIFieldRW + * \param [in] field - the field to add to \a this. + * \throw If the name of \a field is empty. + * \throw If the data array of \a field is not set. + * \throw If existing time steps have different name or number of components than \a field. + * \throw If the underlying mesh of \a field has no name. + * \throw If elements in the mesh are not in the order suitable for writing to the MED file. + */ +void MEDFileIntFieldMultiTS::appendFieldNoProfileSBT(const MEDCouplingFieldDouble *field, const DataArrayInt *arrOfVals) +{ + contentNotNull()->appendFieldNoProfileSBT(field,arrOfVals,*this); +} + +/*! + * Adds a MEDCouplingFieldDouble to \a this as another time step. + * The mesh support of input parameter \a field is ignored here, it can be NULL. + * The support of field \a field is expected to be those computed with the input parameter \a mesh, \a meshDimRelToMax, + * and \a profile. + * + * This method will check that the field based on the computed support is coherent. If not an exception will be thrown. + * A new profile is added only if no equal profile is missing. + * For more info, see \ref AdvMEDLoaderAPIFieldRW + * \param [in] field - the field to add to \a this. The field double values and mesh support are ignored. + * \param [in] arrOfVals - the values of the field \a field used. + * \param [in] mesh - the supporting mesh of \a field. + * \param [in] meshDimRelToMax - a relative dimension of mesh entities \a field lies on (useless if field spatial discretization is ON_NODES). + * \param [in] profile - ids of mesh entities on which corresponding field values lie. + * \throw If either \a field or \a mesh or \a profile has an empty name. + * \throw If there are no mesh entities of \a meshDimRelToMax dimension in \a mesh. + * \throw If the data array of \a field is not set. + * \throw If the data array of \a this is already allocated but has different number of + * components than \a field. + * \throw If elements in \a mesh are not in the order suitable for writing to the MED file. + * \sa setFieldNoProfileSBT() + */ +void MEDFileIntFieldMultiTS::appendFieldProfile(const MEDCouplingFieldDouble *field, const DataArrayInt *arrOfVals, const MEDFileMesh *mesh, int meshDimRelToMax, const DataArrayInt *profile) +{ + contentNotNull()->appendFieldProfile(field,arrOfVals,mesh,meshDimRelToMax,profile,*this); +} + +const MEDFileIntFieldMultiTSWithoutSDA *MEDFileIntFieldMultiTS::contentNotNull() const +{ + const MEDFileAnyTypeFieldMultiTSWithoutSDA *pt(_content); + if(!pt) + throw INTERP_KERNEL::Exception("MEDFileIntFieldMultiTS::contentNotNull : the content pointer is null !"); + const MEDFileIntFieldMultiTSWithoutSDA *ret=dynamic_cast<const MEDFileIntFieldMultiTSWithoutSDA *>(pt); + if(!ret) + throw INTERP_KERNEL::Exception("MEDFileIntFieldMultiTS::contentNotNull : the content pointer is not null but it is not of type int ! Reason is maybe that the read field has not the type INT32 !"); + return ret; +} + +MEDFileIntFieldMultiTSWithoutSDA *MEDFileIntFieldMultiTS::contentNotNull() +{ + MEDFileAnyTypeFieldMultiTSWithoutSDA *pt(_content); + if(!pt) + throw INTERP_KERNEL::Exception("MEDFileIntFieldMultiTS::contentNotNull : the non const content pointer is null !"); + MEDFileIntFieldMultiTSWithoutSDA *ret=dynamic_cast<MEDFileIntFieldMultiTSWithoutSDA *>(pt); + if(!ret) + throw INTERP_KERNEL::Exception("MEDFileIntFieldMultiTS::contentNotNull : the non const content pointer is not null but it is not of type int ! Reason is maybe that the read field has not the type INT32 !"); + return ret; +} + +MEDFileIntFieldMultiTS::MEDFileIntFieldMultiTS() +{ + _content=new MEDFileIntFieldMultiTSWithoutSDA; +} + +MEDFileIntFieldMultiTS::MEDFileIntFieldMultiTS(const MEDFileIntFieldMultiTSWithoutSDA& other, bool shallowCopyOfContent):MEDFileAnyTypeFieldMultiTS(other,shallowCopyOfContent) +{ +} + +MEDFileIntFieldMultiTS::MEDFileIntFieldMultiTS(const std::string& fileName, bool loadAll, const MEDFileMeshes *ms) +try:MEDFileAnyTypeFieldMultiTS(fileName,loadAll,ms) +{ +} +catch(INTERP_KERNEL::Exception& e) +{ throw e; } + +MEDFileIntFieldMultiTS::MEDFileIntFieldMultiTS(const std::string& fileName, const std::string& fieldName, bool loadAll, const MEDFileMeshes *ms, const std::vector< std::pair<TypeOfField,INTERP_KERNEL::NormalizedCellType> > *entities) +try:MEDFileAnyTypeFieldMultiTS(fileName,fieldName,loadAll,ms,entities) +{ +} +catch(INTERP_KERNEL::Exception& e) +{ throw e; } + +DataArrayInt *MEDFileIntFieldMultiTS::getUndergroundDataArray(int iteration, int order) const +{ + return static_cast<DataArrayInt *>(contentNotNull()->getUndergroundDataArray(iteration,order)); +} + +//= MEDFileFields + +MEDFileFields *MEDFileFields::New() +{ + return new MEDFileFields; +} + +MEDFileFields *MEDFileFields::New(const std::string& fileName, bool loadAll) +{ + return new MEDFileFields(fileName,loadAll,0,0); +} + +MEDFileFields *MEDFileFields::LoadPartOf(const std::string& fileName, bool loadAll, const MEDFileMeshes *ms) +{ + return new MEDFileFields(fileName,loadAll,ms,0); +} + +MEDFileFields *MEDFileFields::LoadSpecificEntities(const std::string& fileName, const std::vector< std::pair<TypeOfField,INTERP_KERNEL::NormalizedCellType> >& entities, bool loadAll) +{ + return new MEDFileFields(fileName,loadAll,0,&entities); +} + +std::size_t MEDFileFields::getHeapMemorySizeWithoutChildren() const +{ + std::size_t ret(MEDFileFieldGlobsReal::getHeapMemorySizeWithoutChildren()); + ret+=_fields.capacity()*sizeof(MEDCouplingAutoRefCountObjectPtr<MEDFileAnyTypeFieldMultiTSWithoutSDA>); + return ret; +} + +std::vector<const BigMemoryObject *> MEDFileFields::getDirectChildrenWithNull() const +{ + std::vector<const BigMemoryObject *> ret; + for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileAnyTypeFieldMultiTSWithoutSDA> >::const_iterator it=_fields.begin();it!=_fields.end();it++) + ret.push_back((const MEDFileAnyTypeFieldMultiTSWithoutSDA *)*it); + return ret; +} + +MEDFileFields *MEDFileFields::deepCpy() const +{ + MEDCouplingAutoRefCountObjectPtr<MEDFileFields> ret=shallowCpy(); + std::size_t i=0; + for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileAnyTypeFieldMultiTSWithoutSDA> >::const_iterator it=_fields.begin();it!=_fields.end();it++,i++) + { + if((const MEDFileAnyTypeFieldMultiTSWithoutSDA*)*it) + ret->_fields[i]=(*it)->deepCpy(); + } + ret->deepCpyGlobs(*this); + return ret.retn(); +} + +MEDFileFields *MEDFileFields::shallowCpy() const +{ + return new MEDFileFields(*this); +} + +/*! + * This method scans for all fields in \a this which time steps ids are common. Time step are discriminated by the pair of integer (iteration,order) whatever + * the double time value. If all returned time steps are \b exactly those for all fields in \a this output parameter \a areThereSomeForgottenTS will be set to false. + * If \a areThereSomeForgottenTS is set to true, only the sorted intersection of time steps present for all fields in \a this will be returned. + * + * \param [out] areThereSomeForgottenTS - indicates to the caller if there is some time steps in \a this that are not present for all fields in \a this. + * \return the sorted list of time steps (specified with a pair of integer iteration first and order second) present for all fields in \a this. + * + * \sa MEDFileFields::partOfThisLyingOnSpecifiedTimeSteps, MEDFileFields::partOfThisNotLyingOnSpecifiedTimeSteps + */ +std::vector< std::pair<int,int> > MEDFileFields::getCommonIterations(bool& areThereSomeForgottenTS) const +{ + std::set< std::pair<int,int> > s; + bool firstShot=true; + areThereSomeForgottenTS=false; + for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileAnyTypeFieldMultiTSWithoutSDA> >::const_iterator it=_fields.begin();it!=_fields.end();it++) + { + if(!(const MEDFileAnyTypeFieldMultiTSWithoutSDA*)*it) + continue; + std::vector< std::pair<int,int> > v=(*it)->getIterations(); + std::set< std::pair<int,int> > s1; std::copy(v.begin(),v.end(),std::inserter(s1,s1.end())); + if(firstShot) + { s=s1; firstShot=false; } + else + { + std::set< std::pair<int,int> > s2; std::set_intersection(s.begin(),s.end(),s1.begin(),s1.end(),std::inserter(s2,s2.end())); + if(s!=s2) + areThereSomeForgottenTS=true; + s=s2; + } + } + std::vector< std::pair<int,int> > ret; + std::copy(s.begin(),s.end(),std::back_insert_iterator< std::vector< std::pair<int,int> > >(ret)); + return ret; +} + +int MEDFileFields::getNumberOfFields() const +{ + return _fields.size(); +} + +std::vector<std::string> MEDFileFields::getFieldsNames() const +{ + std::vector<std::string> ret(_fields.size()); + int i=0; + for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileAnyTypeFieldMultiTSWithoutSDA> >::const_iterator it=_fields.begin();it!=_fields.end();it++,i++) + { + const MEDFileAnyTypeFieldMultiTSWithoutSDA *f=(*it); + if(f) + { + ret[i]=f->getName(); + } + else + { + std::ostringstream oss; oss << "MEDFileFields::getFieldsNames : At rank #" << i << " field is not defined !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + } + return ret; +} + +std::vector<std::string> MEDFileFields::getMeshesNames() const +{ + std::vector<std::string> ret; + for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileAnyTypeFieldMultiTSWithoutSDA> >::const_iterator it=_fields.begin();it!=_fields.end();it++) + { + const MEDFileAnyTypeFieldMultiTSWithoutSDA *cur(*it); + if(cur) + ret.push_back(cur->getMeshName()); + } + return ret; +} + +std::string MEDFileFields::simpleRepr() const +{ + std::ostringstream oss; + oss << "(*****************)\n(* MEDFileFields *)\n(*****************)\n\n"; + simpleRepr(0,oss); + return oss.str(); +} + +void MEDFileFields::simpleRepr(int bkOffset, std::ostream& oss) const +{ + int nbOfFields=getNumberOfFields(); + std::string startLine(bkOffset,' '); + oss << startLine << "There are " << nbOfFields << " fields in this :" << std::endl; + int i=0; + for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileAnyTypeFieldMultiTSWithoutSDA> >::const_iterator it=_fields.begin();it!=_fields.end();it++,i++) + { + const MEDFileAnyTypeFieldMultiTSWithoutSDA *cur=(*it); + if(cur) + { + oss << startLine << " - # "<< i << " has the following name : \"" << cur->getName() << "\"." << std::endl; + } + else + { + oss << startLine << " - not defined !" << std::endl; + } + } + i=0; + for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileAnyTypeFieldMultiTSWithoutSDA> >::const_iterator it=_fields.begin();it!=_fields.end();it++,i++) + { + const MEDFileAnyTypeFieldMultiTSWithoutSDA *cur=(*it); + std::string chapter(17,'0'+i); + oss << startLine << chapter << std::endl; + if(cur) + { + cur->simpleRepr(bkOffset+2,oss,i); + } + else + { + oss << startLine << " - not defined !" << std::endl; + } + oss << startLine << chapter << std::endl; + } + simpleReprGlobs(oss); +} + +MEDFileFields::MEDFileFields() +{ +} + +MEDFileFields::MEDFileFields(const std::string& fileName, bool loadAll, const MEDFileMeshes *ms, const std::vector< std::pair<TypeOfField,INTERP_KERNEL::NormalizedCellType> > *entities) +try:MEDFileFieldGlobsReal(fileName) +{ + MEDFileUtilities::CheckFileForRead(fileName); + MEDFileUtilities::AutoFid fid(MEDfileOpen(fileName.c_str(),MED_ACC_RDONLY)); + int nbFields(MEDnField(fid)); + _fields.resize(nbFields); + med_field_type typcha; + for(int i=0;i<nbFields;i++) + { + std::vector<std::string> infos; + std::string fieldName,dtunit; + int nbOfStep(MEDFileAnyTypeField1TS::LocateField2(fid,fileName,i,false,fieldName,typcha,infos,dtunit)); + switch(typcha) + { + case MED_FLOAT64: + { + _fields[i]=MEDFileFieldMultiTSWithoutSDA::New(fid,fieldName.c_str(),typcha,infos,nbOfStep,dtunit,loadAll,ms,entities); + break; + } + case MED_INT32: + { + _fields[i]=MEDFileIntFieldMultiTSWithoutSDA::New(fid,fieldName.c_str(),typcha,infos,nbOfStep,dtunit,loadAll,ms,entities); + break; + } + default: + { + std::ostringstream oss; oss << "constructor MEDFileFields(fileName) : file \'" << fileName << "\' at pos #" << i << " field has name \'" << fieldName << "\' but the type of field is not in [MED_FLOAT64, MED_INT32] !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + } + } + loadAllGlobals(fid); +} +catch(INTERP_KERNEL::Exception& e) +{ + throw e; +} + +void MEDFileFields::writeLL(med_idt fid) const +{ + int i=0; + writeGlobals(fid,*this); + for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileAnyTypeFieldMultiTSWithoutSDA> >::const_iterator it=_fields.begin();it!=_fields.end();it++,i++) + { + const MEDFileAnyTypeFieldMultiTSWithoutSDA *elt=*it; + if(!elt) + { + std::ostringstream oss; oss << "MEDFileFields::write : at rank #" << i << "/" << _fields.size() << " field is empty !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + elt->writeLL(fid,*this); + } +} + +void MEDFileFields::write(const std::string& fileName, int mode) const +{ + med_access_mode medmod=MEDFileUtilities::TraduceWriteMode(mode); + MEDFileUtilities::AutoFid fid(MEDfileOpen(fileName.c_str(),medmod)); + writeLL(fid); +} + +/*! + * This method alloc the arrays and load potentially huge arrays contained in this field. + * This method should be called when a MEDFileAnyTypeFieldMultiTS::New constructor has been with false as the last parameter. + * This method can be also called to refresh or reinit values from a file. + * + * \throw If the fileName is not set or points to a non readable MED file. + */ +void MEDFileFields::loadArrays() +{ + if(getFileName().empty()) + throw INTERP_KERNEL::Exception("MEDFileFields::loadArrays : the structure does not come from a file !"); + MEDFileUtilities::AutoFid fid=MEDfileOpen(getFileName().c_str(),MED_ACC_RDONLY); + for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileAnyTypeFieldMultiTSWithoutSDA> >::iterator it=_fields.begin();it!=_fields.end();it++) + { + MEDFileAnyTypeFieldMultiTSWithoutSDA *elt(*it); + if(elt) + elt->loadBigArraysRecursively(fid,*elt); + } +} + +/*! + * This method behaves as MEDFileFields::loadArrays does, the first call, if \a this was built using a file without loading big arrays. + * But once data loaded once, this method does nothing. + * + * \throw If the fileName is not set or points to a non readable MED file. + * \sa MEDFileFields::loadArrays, MEDFileFields::unloadArrays + */ +void MEDFileFields::loadArraysIfNecessary() +{ + if(!getFileName().empty()) + { + MEDFileUtilities::AutoFid fid=MEDfileOpen(getFileName().c_str(),MED_ACC_RDONLY); + for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileAnyTypeFieldMultiTSWithoutSDA> >::iterator it=_fields.begin();it!=_fields.end();it++) + { + MEDFileAnyTypeFieldMultiTSWithoutSDA *elt(*it); + if(elt) + elt->loadBigArraysRecursivelyIfNecessary(fid,*elt); + } + } +} + +/*! + * This method releases potentially big data arrays and so returns to the same heap memory than status loaded with 'loadAll' parameter set to false. + * \b WARNING, this method does release arrays even if \a this does not come from a load of a MED file. + * So this method can lead to a loss of data. If you want to unload arrays safely call MEDFileFields::unloadArraysWithoutDataLoss instead. + * + * \sa MEDFileFields::loadArrays, MEDFileFields::loadArraysIfNecessary, MEDFileFields::unloadArraysWithoutDataLoss + */ +void MEDFileFields::unloadArrays() +{ + for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileAnyTypeFieldMultiTSWithoutSDA> >::iterator it=_fields.begin();it!=_fields.end();it++) + { + MEDFileAnyTypeFieldMultiTSWithoutSDA *elt(*it); + if(elt) + elt->unloadArrays(); + } +} + +/*! + * This method potentially releases big data arrays if \a this is coming from a file. If \a this has been built from scratch this method will have no effect. + * This method is the symetrical method of MEDFileFields::loadArraysIfNecessary. + * This method is useful to reduce \b safely amount of heap memory necessary for \a this by using MED file as database. + * + * \sa MEDFileFields::loadArraysIfNecessary + */ +void MEDFileFields::unloadArraysWithoutDataLoss() +{ + if(!getFileName().empty()) + unloadArrays(); +} + +std::vector<std::string> MEDFileFields::getPflsReallyUsed() const +{ + std::vector<std::string> ret; + std::set<std::string> ret2; + for(std::vector< MEDCouplingAutoRefCountObjectPtr< MEDFileAnyTypeFieldMultiTSWithoutSDA > >::const_iterator it=_fields.begin();it!=_fields.end();it++) + { + std::vector<std::string> tmp=(*it)->getPflsReallyUsed2(); + for(std::vector<std::string>::const_iterator it2=tmp.begin();it2!=tmp.end();it2++) + if(ret2.find(*it2)==ret2.end()) + { + ret.push_back(*it2); + ret2.insert(*it2); + } + } + return ret; +} + +std::vector<std::string> MEDFileFields::getLocsReallyUsed() const +{ + std::vector<std::string> ret; + std::set<std::string> ret2; + for(std::vector< MEDCouplingAutoRefCountObjectPtr< MEDFileAnyTypeFieldMultiTSWithoutSDA > >::const_iterator it=_fields.begin();it!=_fields.end();it++) + { + std::vector<std::string> tmp=(*it)->getLocsReallyUsed2(); + for(std::vector<std::string>::const_iterator it2=tmp.begin();it2!=tmp.end();it2++) + if(ret2.find(*it2)==ret2.end()) + { + ret.push_back(*it2); + ret2.insert(*it2); + } + } + return ret; +} + +std::vector<std::string> MEDFileFields::getPflsReallyUsedMulti() const +{ + std::vector<std::string> ret; + for(std::vector< MEDCouplingAutoRefCountObjectPtr< MEDFileAnyTypeFieldMultiTSWithoutSDA > >::const_iterator it=_fields.begin();it!=_fields.end();it++) + { + std::vector<std::string> tmp=(*it)->getPflsReallyUsedMulti2(); + ret.insert(ret.end(),tmp.begin(),tmp.end()); + } + return ret; +} + +std::vector<std::string> MEDFileFields::getLocsReallyUsedMulti() const +{ + std::vector<std::string> ret; + for(std::vector< MEDCouplingAutoRefCountObjectPtr< MEDFileAnyTypeFieldMultiTSWithoutSDA > >::const_iterator it=_fields.begin();it!=_fields.end();it++) + { + std::vector<std::string> tmp=(*it)->getLocsReallyUsed2(); + ret.insert(ret.end(),tmp.begin(),tmp.end()); + } + return ret; +} + +void MEDFileFields::changePflsRefsNamesGen(const std::vector< std::pair<std::vector<std::string>, std::string > >& mapOfModif) +{ + for(std::vector< MEDCouplingAutoRefCountObjectPtr< MEDFileAnyTypeFieldMultiTSWithoutSDA > >::iterator it=_fields.begin();it!=_fields.end();it++) + (*it)->changePflsRefsNamesGen2(mapOfModif); +} + +void MEDFileFields::changeLocsRefsNamesGen(const std::vector< std::pair<std::vector<std::string>, std::string > >& mapOfModif) +{ + for(std::vector< MEDCouplingAutoRefCountObjectPtr< MEDFileAnyTypeFieldMultiTSWithoutSDA > >::iterator it=_fields.begin();it!=_fields.end();it++) + (*it)->changeLocsRefsNamesGen2(mapOfModif); +} + +void MEDFileFields::resize(int newSize) +{ + _fields.resize(newSize); +} + +void MEDFileFields::pushFields(const std::vector<MEDFileAnyTypeFieldMultiTS *>& fields) +{ + for(std::vector<MEDFileAnyTypeFieldMultiTS *>::const_iterator it=fields.begin();it!=fields.end();it++) + pushField(*it); +} + +void MEDFileFields::pushField(MEDFileAnyTypeFieldMultiTS *field) +{ + if(!field) + throw INTERP_KERNEL::Exception("MEDFileFields::pushMesh : invalid input pointer ! should be different from 0 !"); + _fields.push_back(field->getContent()); + appendGlobs(*field,1e-12); +} + +void MEDFileFields::setFieldAtPos(int i, MEDFileAnyTypeFieldMultiTS *field) +{ + if(!field) + throw INTERP_KERNEL::Exception("MEDFileFields::setFieldAtPos : invalid input pointer ! should be different from 0 !"); + if(i>=(int)_fields.size()) + _fields.resize(i+1); + _fields[i]=field->getContent(); + appendGlobs(*field,1e-12); +} + +void MEDFileFields::destroyFieldAtPos(int i) +{ + destroyFieldsAtPos(&i,&i+1); +} + +void MEDFileFields::destroyFieldsAtPos(const int *startIds, const int *endIds) +{ + std::vector<bool> b(_fields.size(),true); + for(const int *i=startIds;i!=endIds;i++) + { + if(*i<0 || *i>=(int)_fields.size()) + { + std::ostringstream oss; oss << "MEDFileFields::destroyFieldsAtPos : Invalid given id in input (" << *i << ") should be in [0," << _fields.size() << ") !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + b[*i]=false; + } + std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileAnyTypeFieldMultiTSWithoutSDA> > fields(std::count(b.begin(),b.end(),true)); + std::size_t j=0; + for(std::size_t i=0;i<_fields.size();i++) + if(b[i]) + fields[j++]=_fields[i]; + _fields=fields; +} + +void MEDFileFields::destroyFieldsAtPos2(int bg, int end, int step) +{ + static const char msg[]="MEDFileFields::destroyFieldsAtPos2"; + int nbOfEntriesToKill=DataArrayInt::GetNumberOfItemGivenBESRelative(bg,end,step,msg); + std::vector<bool> b(_fields.size(),true); + int k=bg; + for(int i=0;i<nbOfEntriesToKill;i++,k+=step) + { + if(k<0 || k>=(int)_fields.size()) + { + std::ostringstream oss; oss << "MEDFileFields::destroyFieldsAtPos2 : Invalid given id in input (" << k << ") should be in [0," << _fields.size() << ") !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + b[k]=false; + } + std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileAnyTypeFieldMultiTSWithoutSDA> > fields(std::count(b.begin(),b.end(),true)); + std::size_t j=0; + for(std::size_t i=0;i<_fields.size();i++) + if(b[i]) + fields[j++]=_fields[i]; + _fields=fields; +} + +bool MEDFileFields::changeMeshNames(const std::vector< std::pair<std::string,std::string> >& modifTab) +{ + bool ret=false; + for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileAnyTypeFieldMultiTSWithoutSDA> >::iterator it=_fields.begin();it!=_fields.end();it++) + { + MEDFileAnyTypeFieldMultiTSWithoutSDA *cur(*it); + if(cur) + ret=cur->changeMeshNames(modifTab) || ret; + } + return ret; +} + +/*! + * \param [in] meshName the name of the mesh that will be renumbered. + * \param [in] oldCode is of format returned by MEDCouplingUMesh::getDistributionOfTypes. And for each *i* oldCode[3*i+2] gives the position (MEDFileUMesh::PutInThirdComponentOfCodeOffset). + * This code corresponds to the distribution of types in the corresponding mesh. + * \param [in] newCode idem to param \a oldCode except that here the new distribution is given. + * \param [in] renumO2N the old to new renumber array. + * \return If true a renumbering has been performed. The structure in \a this has been modified. If false, nothing has been done: it is typically the case if \a meshName is not refered by any + * field in \a this. + */ +bool MEDFileFields::renumberEntitiesLyingOnMesh(const std::string& meshName, const std::vector<int>& oldCode, const std::vector<int>& newCode, const DataArrayInt *renumO2N) +{ + bool ret=false; + for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileAnyTypeFieldMultiTSWithoutSDA> >::iterator it=_fields.begin();it!=_fields.end();it++) + { + MEDFileAnyTypeFieldMultiTSWithoutSDA *fmts(*it); + if(fmts) + { + ret=fmts->renumberEntitiesLyingOnMesh(meshName,oldCode,newCode,renumO2N,*this) || ret; + } + } + return ret; +} + +MEDFileAnyTypeFieldMultiTS *MEDFileFields::getFieldAtPos(int i) const +{ + if(i<0 || i>=(int)_fields.size()) + { + std::ostringstream oss; oss << "MEDFileFields::getFieldAtPos : Invalid given id in input (" << i << ") should be in [0," << _fields.size() << ") !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + const MEDFileAnyTypeFieldMultiTSWithoutSDA *fmts=_fields[i]; + if(!fmts) + return 0; + MEDCouplingAutoRefCountObjectPtr<MEDFileAnyTypeFieldMultiTS> ret; + const MEDFileFieldMultiTSWithoutSDA *fmtsC=dynamic_cast<const MEDFileFieldMultiTSWithoutSDA *>(fmts); + const MEDFileIntFieldMultiTSWithoutSDA *fmtsC2=dynamic_cast<const MEDFileIntFieldMultiTSWithoutSDA *>(fmts); + if(fmtsC) + ret=MEDFileFieldMultiTS::New(*fmtsC,false); + else if(fmtsC2) + ret=MEDFileIntFieldMultiTS::New(*fmtsC2,false); + else + { + std::ostringstream oss; oss << "MEDFileFields::getFieldAtPos : At pos #" << i << " field is neither double (FLOAT64) nor integer (INT32) !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + ret->shallowCpyGlobs(*this); + return ret.retn(); +} + +/*! + * Return a shallow copy of \a this reduced to the fields ids defined in [ \a startIds , endIds ). + * This method is accessible in python using __getitem__ with a list in input. + * \return a new object that the caller should deal with. + */ +MEDFileFields *MEDFileFields::buildSubPart(const int *startIds, const int *endIds) const +{ + MEDCouplingAutoRefCountObjectPtr<MEDFileFields> ret=shallowCpy(); + std::size_t sz=std::distance(startIds,endIds); + std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileAnyTypeFieldMultiTSWithoutSDA> > fields(sz); + int j=0; + for(const int *i=startIds;i!=endIds;i++,j++) + { + if(*i<0 || *i>=(int)_fields.size()) + { + std::ostringstream oss; oss << "MEDFileFields::buildSubPart : Invalid given id in input (" << *i << ") should be in [0," << _fields.size() << ") !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + fields[j]=_fields[*i]; + } + ret->_fields=fields; + return ret.retn(); +} + +MEDFileAnyTypeFieldMultiTS *MEDFileFields::getFieldWithName(const std::string& fieldName) const +{ + return getFieldAtPos(getPosFromFieldName(fieldName)); +} + +/*! + * This method removes, if any, fields in \a this having no time steps. + * If there is one or more than one such field in \a this true is returned and those fields will not be referenced anymore in \a this. + * + * If false is returned \a this does not contain such fields. If false is returned this method can be considered as const. + */ +bool MEDFileFields::removeFieldsWithoutAnyTimeStep() +{ + std::vector<MEDCouplingAutoRefCountObjectPtr<MEDFileAnyTypeFieldMultiTSWithoutSDA> > newFields; + for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileAnyTypeFieldMultiTSWithoutSDA> >::const_iterator it=_fields.begin();it!=_fields.end();it++) + { + const MEDFileAnyTypeFieldMultiTSWithoutSDA *elt(*it); + if(elt) + { + if(elt->getNumberOfTS()>0) + newFields.push_back(*it); + } + } + if(_fields.size()==newFields.size()) + return false; + _fields=newFields; + return true; +} + +/*! + * This method returns a new object containing part of \a this fields lying on mesh name specified by the input parameter \a meshName. + * This method can be seen as a filter applied on \a this, that returns an object containing + * reduced the list of fields compared to those in \a this. The returned object is a new object but the object on which it lies are only + * shallow copied from \a this. + * + * \param [in] meshName - the name of the mesh on w + * \return a new object that the caller should deal with. + */ +MEDFileFields *MEDFileFields::partOfThisLyingOnSpecifiedMeshName(const std::string& meshName) const +{ + MEDCouplingAutoRefCountObjectPtr<MEDFileFields> ret=MEDFileFields::New(); + for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileAnyTypeFieldMultiTSWithoutSDA> >::const_iterator it=_fields.begin();it!=_fields.end();it++) + { + const MEDFileAnyTypeFieldMultiTSWithoutSDA *cur=(*it); + if(!cur) + continue; + if(cur->getMeshName()==meshName) + { + cur->incrRef(); + MEDCouplingAutoRefCountObjectPtr<MEDFileAnyTypeFieldMultiTSWithoutSDA> cur2(const_cast<MEDFileAnyTypeFieldMultiTSWithoutSDA *>(cur)); + ret->_fields.push_back(cur2); + } + } + ret->shallowCpyOnlyUsedGlobs(*this); + return ret.retn(); +} + +/*! + * This method returns a new object containing part of \a this fields lying ** exactly ** on the time steps specified by input parameter \a timeSteps. + * Input time steps are specified using a pair of integer (iteration, order). + * This method can be seen as a filter applied on \a this, that returns an object containing the same number of fields than those in \a this, + * but for each multitimestep only the time steps in \a timeSteps are kept. + * Typically the input parameter \a timeSteps comes from the call of MEDFileFields::getCommonIterations. + * + * The returned object points to shallow copy of elements in \a this. + * + * \param [in] timeSteps - the time steps given by a vector of pair of integers (iteration,order) + * \throw If there is a field in \a this that is \b not defined on a time step in the input \a timeSteps. + * \sa MEDFileFields::getCommonIterations, MEDFileFields::partOfThisNotLyingOnSpecifiedTimeSteps + */ +MEDFileFields *MEDFileFields::partOfThisLyingOnSpecifiedTimeSteps(const std::vector< std::pair<int,int> >& timeSteps) const +{ + MEDCouplingAutoRefCountObjectPtr<MEDFileFields> ret=MEDFileFields::New(); + for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileAnyTypeFieldMultiTSWithoutSDA> >::const_iterator it=_fields.begin();it!=_fields.end();it++) + { + const MEDFileAnyTypeFieldMultiTSWithoutSDA *cur=(*it); + if(!cur) + continue; + MEDCouplingAutoRefCountObjectPtr<MEDFileAnyTypeFieldMultiTSWithoutSDA> elt=cur->partOfThisLyingOnSpecifiedTimeSteps(timeSteps); + ret->_fields.push_back(elt); + } + ret->shallowCpyOnlyUsedGlobs(*this); + return ret.retn(); +} + +/*! + * \sa MEDFileFields::getCommonIterations, MEDFileFields::partOfThisLyingOnSpecifiedTimeSteps + */ +MEDFileFields *MEDFileFields::partOfThisNotLyingOnSpecifiedTimeSteps(const std::vector< std::pair<int,int> >& timeSteps) const +{ + MEDCouplingAutoRefCountObjectPtr<MEDFileFields> ret=MEDFileFields::New(); + for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileAnyTypeFieldMultiTSWithoutSDA> >::const_iterator it=_fields.begin();it!=_fields.end();it++) + { + const MEDFileAnyTypeFieldMultiTSWithoutSDA *cur=(*it); + if(!cur) + continue; + MEDCouplingAutoRefCountObjectPtr<MEDFileAnyTypeFieldMultiTSWithoutSDA> elt=cur->partOfThisNotLyingOnSpecifiedTimeSteps(timeSteps); + if(elt->getNumberOfTS()!=0) + ret->_fields.push_back(elt); + } + ret->shallowCpyOnlyUsedGlobs(*this); + return ret.retn(); +} + +MEDFileFieldsIterator *MEDFileFields::iterator() +{ + return new MEDFileFieldsIterator(this); +} + +int MEDFileFields::getPosFromFieldName(const std::string& fieldName) const +{ + std::string tmp(fieldName); + std::vector<std::string> poss; + for(std::size_t i=0;i<_fields.size();i++) + { + const MEDFileAnyTypeFieldMultiTSWithoutSDA *f=_fields[i]; + if(f) + { + std::string fname(f->getName()); + if(tmp==fname) + return i; + else + poss.push_back(fname); + } + } + std::ostringstream oss; oss << "MEDFileFields::getPosFromFieldName : impossible to find field '" << tmp << "' in this ! Possibilities are : "; + std::copy(poss.begin(),poss.end(),std::ostream_iterator<std::string>(oss,", ")); + oss << " !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); +} + +MEDFileFieldsIterator::MEDFileFieldsIterator(MEDFileFields *fs):_fs(fs),_iter_id(0),_nb_iter(0) +{ + if(fs) + { + fs->incrRef(); + _nb_iter=fs->getNumberOfFields(); + } +} + +MEDFileFieldsIterator::~MEDFileFieldsIterator() +{ +} + +MEDFileAnyTypeFieldMultiTS *MEDFileFieldsIterator::nextt() +{ + if(_iter_id<_nb_iter) + { + MEDFileFields *fs(_fs); + if(fs) + return fs->getFieldAtPos(_iter_id++); + else + return 0; + } + else + return 0; +} diff --git a/src/medtool/src/MEDLoader/MEDFileField.hxx b/src/medtool/src/MEDLoader/MEDFileField.hxx new file mode 100644 index 000000000..bf0e31351 --- /dev/null +++ b/src/medtool/src/MEDLoader/MEDFileField.hxx @@ -0,0 +1,1171 @@ +// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 +// 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 __MEDFILEFIELD_HXX__ +#define __MEDFILEFIELD_HXX__ + +#include "MEDLoaderDefines.hxx" + +#include "MEDFileFieldOverView.hxx" +#include "MEDFileUtilities.hxx" + +#include "MEDCouplingAutoRefCountObjectPtr.hxx" +#include "MEDCouplingRefCountObject.hxx" +#include "MEDCouplingMemArray.hxx" + +#include "NormalizedUnstructuredMesh.hxx" +#include "InterpKernelException.hxx" + +#include <vector> +#include <string> +#include <list> +#include <set> + +#include "med.h" + +namespace ParaMEDMEM +{ + class MEDFileFieldGlobs; + class MEDCouplingMesh; + class MEDCouplingFieldDouble; + class MEDFileMesh; + + class MEDFileFieldLoc : public RefCountObject + { + public: + MEDLOADER_EXPORT void simpleRepr(std::ostream& oss) const; + MEDLOADER_EXPORT std::string getName() const { return _name; } + MEDLOADER_EXPORT void setName(const std::string& name); + static MEDFileFieldLoc *New(med_idt fid, const std::string& locName); + static MEDFileFieldLoc *New(med_idt fid, int id); + static MEDFileFieldLoc *New(const std::string& locName, INTERP_KERNEL::NormalizedCellType geoType, const std::vector<double>& refCoo, const std::vector<double>& gsCoo, const std::vector<double>& w); + std::size_t getHeapMemorySizeWithoutChildren() const; + std::vector<const BigMemoryObject *> getDirectChildrenWithNull() const; + MEDFileFieldLoc *deepCpy() const; + MEDLOADER_EXPORT int getNbOfGaussPtPerCell() const { return _nb_gauss_pt; } + MEDLOADER_EXPORT void writeLL(med_idt fid) const; + MEDLOADER_EXPORT std::string repr() const; + MEDLOADER_EXPORT bool isName(const std::string& name) const { return _name==name; } + MEDLOADER_EXPORT int getDimension() const { return _dim; } + MEDLOADER_EXPORT int getNumberOfGaussPoints() const { return _nb_gauss_pt; } + MEDLOADER_EXPORT int getNumberOfPointsInCells() const { return _nb_node_per_cell; } + MEDLOADER_EXPORT const std::vector<double>& getRefCoords() const { return _ref_coo; } + MEDLOADER_EXPORT const std::vector<double>& getGaussCoords() const { return _gs_coo; } + MEDLOADER_EXPORT const std::vector<double>& getGaussWeights() const { return _w; } + MEDLOADER_EXPORT INTERP_KERNEL::NormalizedCellType getGeoType() const { return _geo_type; } + MEDLOADER_EXPORT bool isEqual(const MEDFileFieldLoc& other, double eps) const; + private: + MEDFileFieldLoc(med_idt fid, const std::string& locName); + MEDFileFieldLoc(med_idt fid, int id); + MEDFileFieldLoc(const std::string& locName, INTERP_KERNEL::NormalizedCellType geoType, const std::vector<double>& refCoo, const std::vector<double>& gsCoo, const std::vector<double>& w); + private: + int _dim; + int _nb_gauss_pt; + int _nb_node_per_cell; + std::string _name; + INTERP_KERNEL::NormalizedCellType _geo_type; + std::vector<double> _ref_coo; + std::vector<double> _gs_coo; + std::vector<double> _w; + }; + + /// @cond INTERNAL + class MEDFileAnyTypeField1TSWithoutSDA; + class MEDFileFieldPerMeshPerType; + class MEDFileField1TSWithoutSDA; + class MEDFileFieldNameScope; + class MEDFileFieldGlobsReal; + class MEDFileFieldPerMesh; + class PartDefinition; + + class MEDFileFieldPerMeshPerTypePerDisc : public RefCountObject, public MEDFileWritable + { + public: + static MEDFileFieldPerMeshPerTypePerDisc *NewOnRead(MEDFileFieldPerMeshPerType *fath, TypeOfField type, int profileIt, const PartDefinition *pd); + static MEDFileFieldPerMeshPerTypePerDisc *New(MEDFileFieldPerMeshPerType *fath, TypeOfField type, int locId); + static MEDFileFieldPerMeshPerTypePerDisc *New(const MEDFileFieldPerMeshPerTypePerDisc& other); + std::size_t getHeapMemorySizeWithoutChildren() const; + std::vector<const BigMemoryObject *> getDirectChildrenWithNull() const; + MEDFileFieldPerMeshPerTypePerDisc *deepCpy(MEDFileFieldPerMeshPerType *father) const; + void assignFieldNoProfile(int& start, int offset, int nbOfCells, const MEDCouplingFieldDouble *field, const DataArray *arrr, MEDFileFieldGlobsReal& glob, const MEDFileFieldNameScope& nasc); + void assignFieldProfile(bool isPflAlone, int& start, const DataArrayInt *multiTypePfl, const DataArrayInt *idsInPfl, DataArrayInt *locIds, int nbOfEltsInWholeMesh, const MEDCouplingFieldDouble *field, const DataArray *arrr, const MEDCouplingMesh *mesh, MEDFileFieldGlobsReal& glob, const MEDFileFieldNameScope& nasc); + void assignNodeFieldNoProfile(int& start, const MEDCouplingFieldDouble *field, const DataArray *arrr, MEDFileFieldGlobsReal& glob); + void getCoarseData(TypeOfField& type, std::pair<int,int>& dad, std::string& pfl, std::string& loc) const; + void writeLL(med_idt fid, const MEDFileFieldNameScope& nasc) const; + const MEDFileFieldPerMeshPerType *getFather() const; + void loadOnlyStructureOfDataRecursively(med_idt fid, int& start, const MEDFileFieldNameScope& nasc); + void loadBigArray(med_idt fid, const MEDFileFieldNameScope& nasc); + void setNewStart(int newValueOfStart); + int getIteration() const; + int getOrder() const; + double getTime() const; + std::string getMeshName() const; + TypeOfField getType() const; + void simpleRepr(int bkOffset, std::ostream& oss, int id) const; + void fillTypesOfFieldAvailable(std::set<TypeOfField>& types) const; + void setType(TypeOfField newType); + INTERP_KERNEL::NormalizedCellType getGeoType() const; + int getNumberOfComponents() const; + int getNumberOfTuples() const; + int getStart() const { return _start; } + int getEnd() const { return _end; } + DataArray *getOrCreateAndGetArray(); + const DataArray *getOrCreateAndGetArray() const; + const std::vector<std::string>& getInfo() const; + std::string getProfile() const; + void setProfile(const std::string& newPflName); + std::string getLocalization() const; + void setLocalization(const std::string& newLocName); + int getLocId() const { return _loc_id; } + void setLocId(int newId) const { _loc_id=newId; } + void setFather(MEDFileFieldPerMeshPerType *newFather) { _father=newFather; } + void changePflsRefsNamesGen(const std::vector< std::pair<std::vector<std::string>, std::string > >& mapOfModif); + void changeLocsRefsNamesGen(const std::vector< std::pair<std::vector<std::string>, std::string > >& mapOfModif); + void getFieldAtLevel(TypeOfField type, const MEDFileFieldGlobsReal *glob, std::vector< std::pair<int,int> >& dads, std::vector<const DataArrayInt *>& pfls, std::vector<int>& locs, + std::vector<INTERP_KERNEL::NormalizedCellType>& geoTypes) const; + void fillValues(int discId, int& startEntryId, std::vector< std::pair<std::pair<INTERP_KERNEL::NormalizedCellType,int>,std::pair<int,int> > >& entries) const; + int fillEltIdsFromCode(int offset, const std::vector<int>& codeOfMesh, const MEDFileFieldGlobsReal& glob, int *ptToFill) const; + int fillTupleIds(int *ptToFill) const; + static int ConvertType(TypeOfField type, int locId); + static std::vector< std::vector< const MEDFileFieldPerMeshPerTypePerDisc *> > SplitPerDiscretization(const std::vector< const MEDFileFieldPerMeshPerTypePerDisc *>& entries); + static bool RenumberChunks(int offset, const std::vector< const MEDFileFieldPerMeshPerTypePerDisc *>& entriesOnSameDisc, + const DataArrayInt *explicitIdsInMesh, const std::vector<int>& newCode, + MEDFileFieldGlobsReal& glob, DataArrayDouble *arr, std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileFieldPerMeshPerTypePerDisc> >& result); + static MEDFileFieldPerMeshPerTypePerDisc *NewObjectOnSameDiscThanPool(TypeOfField typeF, INTERP_KERNEL::NormalizedCellType geoType, DataArrayInt *idsOfMeshElt, + bool isPfl, int nbi, int offset, std::list< const MEDFileFieldPerMeshPerTypePerDisc *>& entriesOnSameDisc, + MEDFileFieldGlobsReal& glob, bool ¬InExisting); + private: + MEDFileFieldPerMeshPerTypePerDisc(MEDFileFieldPerMeshPerType *fath, TypeOfField type, int profileIt, const PartDefinition *pd); + MEDFileFieldPerMeshPerTypePerDisc(MEDFileFieldPerMeshPerType *fath, TypeOfField type, int profileIt, const std::string& dummy); + MEDFileFieldPerMeshPerTypePerDisc(const MEDFileFieldPerMeshPerTypePerDisc& other); + MEDFileFieldPerMeshPerTypePerDisc(); + private: + void goReadZeValuesInFile(med_idt fid, const std::string& fieldName, int nbOfCompo, int iteration, int order, med_entity_type menti, med_geometry_type mgeoti, unsigned char *startFeedingPtr); + private: + TypeOfField _type; + MEDFileFieldPerMeshPerType *_father; + int _start; + int _end; + //! _nval is different than end-start in case of ON_GAUSS_PT and ON_GAUSS_NE ! (_nval=(_end-_start)/nbi) + int _nval; + std::string _profile; + std::string _localization; + //! only on assignement -3 : ON_NODES, -2 : ON_CELLS, -1 : ON_GAUSS_NE, 0..* : ON_GAUSS_PT + mutable int _loc_id; + mutable int _profile_it; + MEDCouplingAutoRefCountObjectPtr<PartDefinition> _pd; + public: + mutable int _tmp_work1; + }; + + class MEDFileFieldPerMeshPerType : public RefCountObject, public MEDFileWritable + { + public: + static MEDFileFieldPerMeshPerType *New(MEDFileFieldPerMesh *fath, INTERP_KERNEL::NormalizedCellType geoType); + static MEDFileFieldPerMeshPerType *NewOnRead(med_idt fid, MEDFileFieldPerMesh *fath, TypeOfField type, INTERP_KERNEL::NormalizedCellType geoType, const MEDFileFieldNameScope& nasc, const PartDefinition *pd); + std::size_t getHeapMemorySizeWithoutChildren() const; + std::vector<const BigMemoryObject *> getDirectChildrenWithNull() const; + MEDFileFieldPerMeshPerType *deepCpy(MEDFileFieldPerMesh *father) const; + void assignFieldNoProfile(int& start, int offset, int nbOfCells, const MEDCouplingFieldDouble *field, const DataArray *arr, MEDFileFieldGlobsReal& glob, const MEDFileFieldNameScope& nasc); + void assignFieldProfile(bool isPflAlone, int& start, const DataArrayInt *multiTypePfl, const DataArrayInt *idsInPfl, DataArrayInt *locIds, int nbOfEltsInWholeMesh, const MEDCouplingFieldDouble *field, const DataArray *arr, const MEDCouplingMesh *mesh, MEDFileFieldGlobsReal& glob, const MEDFileFieldNameScope& nasc); + void assignNodeFieldNoProfile(int& start, const MEDCouplingFieldDouble *field, const DataArray *arr, MEDFileFieldGlobsReal& glob); + void assignNodeFieldProfile(int& start, const DataArrayInt *pfl, const MEDCouplingFieldDouble *field, const DataArray *arr, MEDFileFieldGlobsReal& glob, const MEDFileFieldNameScope& nasc); + const MEDFileFieldPerMesh *getFather() const; + void loadOnlyStructureOfDataRecursively(med_idt fid, int &start, const MEDFileFieldNameScope& nasc); + void loadBigArraysRecursively(med_idt fid, const MEDFileFieldNameScope& nasc); + void writeLL(med_idt fid, const MEDFileFieldNameScope& nasc) const; + void getDimension(int& dim) const; + void fillTypesOfFieldAvailable(std::set<TypeOfField>& types) const; + void fillFieldSplitedByType(std::vector< std::pair<int,int> >& dads, std::vector<TypeOfField>& types, std::vector<std::string>& pfls, std::vector<std::string>& locs) const; + int getIteration() const; + int getOrder() const; + double getTime() const; + std::string getMeshName() const; + void simpleRepr(int bkOffset, std::ostream& oss, int id) const; + void getSizes(int& globalSz, int& nbOfEntries) const; + INTERP_KERNEL::NormalizedCellType getGeoType() const; + int getNumberOfComponents() const; + bool presenceOfMultiDiscPerGeoType() const; + DataArray *getOrCreateAndGetArray(); + const DataArray *getOrCreateAndGetArray() const; + const std::vector<std::string>& getInfo() const; + std::vector<std::string> getPflsReallyUsed() const; + std::vector<std::string> getLocsReallyUsed() const; + std::vector<std::string> getPflsReallyUsedMulti() const; + std::vector<std::string> getLocsReallyUsedMulti() const; + void changePflsRefsNamesGen(const std::vector< std::pair<std::vector<std::string>, std::string > >& mapOfModif); + void changeLocsRefsNamesGen(const std::vector< std::pair<std::vector<std::string>, std::string > >& mapOfModif); + MEDFileFieldPerMeshPerTypePerDisc *getLeafGivenLocId(int locId); + const MEDFileFieldPerMeshPerTypePerDisc *getLeafGivenLocId(int locId) const; + void getFieldAtLevel(int meshDim, TypeOfField type, const MEDFileFieldGlobsReal *glob, std::vector< std::pair<int,int> >& dads, std::vector<const DataArrayInt *>& pfls, std::vector<int>& locs, std::vector<INTERP_KERNEL::NormalizedCellType>& geoTypes) const; + void fillValues(int& startEntryId, std::vector< std::pair<std::pair<INTERP_KERNEL::NormalizedCellType,int>,std::pair<int,int> > >& entries) const; + void setLeaves(const std::vector< MEDCouplingAutoRefCountObjectPtr< MEDFileFieldPerMeshPerTypePerDisc > >& leaves); + bool keepOnlySpatialDiscretization(TypeOfField tof, int &globalNum, std::vector< std::pair<int,int> >& its); + bool keepOnlyGaussDiscretization(std::size_t idOfDisc, int &globalNum, std::vector< std::pair<int,int> >& its); + static med_entity_type ConvertIntoMEDFileType(TypeOfField ikType, INTERP_KERNEL::NormalizedCellType ikGeoType, med_geometry_type& medfGeoType); + private: + std::vector<int> addNewEntryIfNecessary(const MEDCouplingFieldDouble *field, int offset, int nbOfCells); + std::vector<int> addNewEntryIfNecessaryGauss(const MEDCouplingFieldDouble *field, int offset, int nbOfCells); + std::vector<int> addNewEntryIfNecessary(const MEDCouplingFieldDouble *field, const DataArrayInt *subCells); + std::vector<int> addNewEntryIfNecessaryGauss(const MEDCouplingFieldDouble *field, const DataArrayInt *subCells); + MEDFileFieldPerMeshPerType(med_idt fid, MEDFileFieldPerMesh *fath, TypeOfField type, INTERP_KERNEL::NormalizedCellType geoType, const MEDFileFieldNameScope& nasc, const PartDefinition *pd); + MEDFileFieldPerMeshPerType(MEDFileFieldPerMesh *fath, INTERP_KERNEL::NormalizedCellType geoType); + private: + MEDFileFieldPerMesh *_father; + std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileFieldPerMeshPerTypePerDisc> > _field_pm_pt_pd; + INTERP_KERNEL::NormalizedCellType _geo_type; + }; + + class MEDFileMesh; + + class MEDFileFieldPerMesh : public RefCountObject, public MEDFileWritable + { + public: + static MEDFileFieldPerMesh *New(MEDFileAnyTypeField1TSWithoutSDA *fath, const MEDCouplingMesh *mesh); + static MEDFileFieldPerMesh *NewOnRead(med_idt fid, MEDFileAnyTypeField1TSWithoutSDA *fath, int meshCsit, int meshIteration, int meshOrder, const MEDFileFieldNameScope& nasc, const MEDFileMesh *mm, const std::vector< std::pair<TypeOfField,INTERP_KERNEL::NormalizedCellType> > *entities); + std::size_t getHeapMemorySizeWithoutChildren() const; + std::vector<const BigMemoryObject *> getDirectChildrenWithNull() const; + MEDFileFieldPerMesh *deepCpy(MEDFileAnyTypeField1TSWithoutSDA *father) const; + void simpleRepr(int bkOffset,std::ostream& oss, int id) const; + void copyTinyInfoFrom(const MEDCouplingMesh *mesh); + void assignFieldProfile(int& start, const DataArrayInt *multiTypePfl, const std::vector<int>& code, const std::vector<int>& code2, const std::vector<DataArrayInt *>& idsInPflPerType, const std::vector<DataArrayInt *>& idsPerType, const MEDCouplingFieldDouble *field, const DataArray *arr, const MEDCouplingMesh *mesh, MEDFileFieldGlobsReal& glob, const MEDFileFieldNameScope& nasc); + void assignFieldNoProfileNoRenum(int& start, const std::vector<int>& code, const MEDCouplingFieldDouble *field, const DataArray *arr, MEDFileFieldGlobsReal& glob, const MEDFileFieldNameScope& nasc); + void assignNodeFieldNoProfile(int& start, const MEDCouplingFieldDouble *field, const DataArray *arr, MEDFileFieldGlobsReal& glob); + void assignNodeFieldProfile(int& start, const DataArrayInt *pfl, const MEDCouplingFieldDouble *field, const DataArray *arr, MEDFileFieldGlobsReal& glob, const MEDFileFieldNameScope& nasc); + void loadOnlyStructureOfDataRecursively(med_idt fid, int &start, const MEDFileFieldNameScope& nasc); + void loadBigArraysRecursively(med_idt fid, const MEDFileFieldNameScope& nasc); + void writeLL(med_idt fid, const MEDFileFieldNameScope& nasc) const; + void fillTypesOfFieldAvailable(std::set<TypeOfField>& types) const; + std::vector< std::vector< std::pair<int,int> > > getFieldSplitedByType(std::vector<INTERP_KERNEL::NormalizedCellType>& types, std::vector< std::vector<TypeOfField> >& typesF, std::vector< std::vector<std::string> >& pfls, std::vector< std::vector<std::string> >& locs) const; + void getDimension(int& dim) const; + double getTime() const; + int getIteration() const; + int getOrder() const; + int getMeshIteration() const { return _mesh_iteration; } + int getMeshOrder() const { return _mesh_order; } + std::string getMeshName() const { return _mesh_name; } + int getNumberOfComponents() const; + bool presenceOfMultiDiscPerGeoType() const; + DataArray *getOrCreateAndGetArray(); + const DataArray *getOrCreateAndGetArray() const; + const std::vector<std::string>& getInfo() const; + std::vector<std::string> getPflsReallyUsed() const; + std::vector<std::string> getLocsReallyUsed() const; + std::vector<std::string> getPflsReallyUsedMulti() const; + std::vector<std::string> getLocsReallyUsedMulti() const; + bool changeMeshNames(const std::vector< std::pair<std::string,std::string> >& modifTab); + bool renumberEntitiesLyingOnMesh(const std::string& meshName, const std::vector<int>& oldCode, const std::vector<int>& newCode, const DataArrayInt *renumO2N, MEDFileFieldGlobsReal& glob); + void keepOnlySpatialDiscretization(TypeOfField tof, int &globalNum, std::vector< std::pair<int,int> >& its); + void keepOnlyGaussDiscretization(std::size_t idOfDisc, int &globalNum, std::vector< std::pair<int,int> >& its); + void changePflsRefsNamesGen(const std::vector< std::pair<std::vector<std::string>, std::string > >& mapOfModif); + void changeLocsRefsNamesGen(const std::vector< std::pair<std::vector<std::string>, std::string > >& mapOfModif); + MEDCouplingFieldDouble *getFieldOnMeshAtLevel(TypeOfField type, const MEDFileFieldGlobsReal *glob, const MEDCouplingMesh *mesh, bool& isPfl, MEDCouplingAutoRefCountObjectPtr<DataArray> &arrOut, const MEDFileFieldNameScope& nasc) const; + DataArray *getFieldOnMeshAtLevelWithPfl(TypeOfField type, const MEDCouplingMesh *mesh, DataArrayInt *&pfl, const MEDFileFieldGlobsReal *glob, const MEDFileFieldNameScope& nasc) const; + void getUndergroundDataArrayExt(std::vector< std::pair<std::pair<INTERP_KERNEL::NormalizedCellType,int>,std::pair<int,int> > >& entries) const; + MEDFileFieldPerMeshPerTypePerDisc *getLeafGivenTypeAndLocId(INTERP_KERNEL::NormalizedCellType typ, int locId); + const MEDFileFieldPerMeshPerTypePerDisc *getLeafGivenTypeAndLocId(INTERP_KERNEL::NormalizedCellType typ, int locId) const; + private: + int addNewEntryIfNecessary(INTERP_KERNEL::NormalizedCellType type); + MEDCouplingFieldDouble *finishField(TypeOfField type, const MEDFileFieldGlobsReal *glob, + const std::vector< std::pair<int,int> >& dads, const std::vector<int>& locs, const MEDCouplingMesh *mesh, bool& isPfl, MEDCouplingAutoRefCountObjectPtr<DataArray> &arrOut, const MEDFileFieldNameScope& nasc) const; + MEDCouplingFieldDouble *finishField2(TypeOfField type, const MEDFileFieldGlobsReal *glob, + const std::vector< std::pair<int,int> >& dads, const std::vector<int>& locs, + const std::vector<INTERP_KERNEL::NormalizedCellType>& geoTypes, + const MEDCouplingMesh *mesh, const DataArrayInt *da, bool& isPfl, MEDCouplingAutoRefCountObjectPtr<DataArray> &arrOut, const MEDFileFieldNameScope& nasc) const; + MEDCouplingFieldDouble *finishFieldNode2(const MEDFileFieldGlobsReal *glob, + const std::vector< std::pair<int,int> >& dads, const std::vector<int>& locs, + const MEDCouplingMesh *mesh, const DataArrayInt *da, bool& isPfl, MEDCouplingAutoRefCountObjectPtr<DataArray> &arrOut, const MEDFileFieldNameScope& nasc) const; + DataArray *finishField4(const std::vector< std::pair<int,int> >& dads, const DataArrayInt *pflIn, int nbOfElems, DataArrayInt *&pflOut) const; + void assignNewLeaves(const std::vector< MEDCouplingAutoRefCountObjectPtr< MEDFileFieldPerMeshPerTypePerDisc > >& leaves); + static void SortArraysPerType(const MEDFileFieldGlobsReal *glob, TypeOfField type, + const std::vector<INTERP_KERNEL::NormalizedCellType>& geoTypes, const std::vector< std::pair<int,int> >& dads, const std::vector<const DataArrayInt *>& pfls, const std::vector<int>& locs, + std::vector<int>& code, std::vector<DataArrayInt *>& notNullPfls); + static int ComputeNbOfElems(const MEDFileFieldGlobsReal *glob, TypeOfField type, const std::vector<INTERP_KERNEL::NormalizedCellType>& geoTypes, const std::vector< std::pair<int,int> >& dads, const std::vector<int>& locs); + MEDFileFieldPerMesh(med_idt fid, MEDFileAnyTypeField1TSWithoutSDA *fath, int meshCsit, int meshIteration, int meshOrder, const MEDFileFieldNameScope& nasc, const MEDFileMesh *mm, const std::vector< std::pair<TypeOfField,INTERP_KERNEL::NormalizedCellType> > *entities); + MEDFileFieldPerMesh(MEDFileAnyTypeField1TSWithoutSDA *fath, const MEDCouplingMesh *mesh); + private: + std::string _mesh_name; + int _mesh_iteration; + int _mesh_order; + MEDFileAnyTypeField1TSWithoutSDA *_father; + std::vector< MEDCouplingAutoRefCountObjectPtr< MEDFileFieldPerMeshPerType > > _field_pm_pt; + }; + + class MEDFileFieldGlobsReal; + + class MEDFileFieldGlobs : public RefCountObject + { + public: + static MEDFileFieldGlobs *New(const std::string& fname); + static MEDFileFieldGlobs *New(); + std::size_t getHeapMemorySizeWithoutChildren() const; + std::vector<const BigMemoryObject *> getDirectChildrenWithNull() const; + MEDFileFieldGlobs *deepCpy() const; + MEDFileFieldGlobs *shallowCpyPart(const std::vector<std::string>& pfls, const std::vector<std::string>& locs) const; + MEDFileFieldGlobs *deepCpyPart(const std::vector<std::string>& pfls, const std::vector<std::string>& locs) const; + void simpleRepr(std::ostream& oss) const; + void appendGlobs(const MEDFileFieldGlobs& other, double eps); + void checkGlobsPflsPartCoherency(const std::vector<std::string>& pflsUsed) const; + void checkGlobsLocsPartCoherency(const std::vector<std::string>& locsUsed) const; + void loadProfileInFile(med_idt fid, int id, const std::string& pflName); + void loadProfileInFile(med_idt fid, int id); + void loadGlobals(med_idt fid, const MEDFileFieldGlobsReal& real); + void loadAllGlobals(med_idt fid); + void writeGlobals(med_idt fid, const MEDFileWritable& opt) const; + std::vector<std::string> getPfls() const; + std::vector<std::string> getLocs() const; + bool existsPfl(const std::string& pflName) const; + bool existsLoc(const std::string& locName) const; + std::string createNewNameOfPfl() const; + std::string createNewNameOfLoc() const; + std::vector< std::vector<int> > whichAreEqualProfiles() const; + std::vector< std::vector<int> > whichAreEqualLocs(double eps) const; + void setFileName(const std::string& fileName); + void changePflsNamesInStruct(const std::vector< std::pair<std::vector<std::string>, std::string > >& mapOfModif); + void changeLocsNamesInStruct(const std::vector< std::pair<std::vector<std::string>, std::string > >& mapOfModif); + int getNbOfGaussPtPerCell(int locId) const; + int getLocalizationId(const std::string& loc) const; + std::string getFileName() const { return _file_name; } + const MEDFileFieldLoc& getLocalizationFromId(int locId) const; + const MEDFileFieldLoc& getLocalization(const std::string& locName) const; + const DataArrayInt *getProfileFromId(int pflId) const; + const DataArrayInt *getProfile(const std::string& pflName) const; + MEDFileFieldLoc& getLocalizationFromId(int locId); + MEDFileFieldLoc& getLocalization(const std::string& locName); + DataArrayInt *getProfile(const std::string& pflName); + DataArrayInt *getProfileFromId(int pflId); + void killProfileIds(const std::vector<int>& pflIds); + void killLocalizationIds(const std::vector<int>& locIds); + // + void appendProfile(DataArrayInt *pfl); + void appendLoc(const std::string& locName, INTERP_KERNEL::NormalizedCellType geoType, const std::vector<double>& refCoo, const std::vector<double>& gsCoo, const std::vector<double>& w); + // + static std::string CreateNewNameNotIn(const std::string& prefix, const std::vector<std::string>& namesToAvoid); + protected: + MEDFileFieldGlobs(const std::string& fname); + MEDFileFieldGlobs(); + ~MEDFileFieldGlobs(); + protected: + std::vector< MEDCouplingAutoRefCountObjectPtr<DataArrayInt> > _pfls; + std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileFieldLoc> > _locs; + std::string _file_name; + }; + + /// @endcond INTERNAL + + class MEDFileFieldGlobsReal + { + public: + MEDLOADER_EXPORT MEDFileFieldGlobsReal(const std::string& fname); + MEDLOADER_EXPORT MEDFileFieldGlobsReal(); + MEDLOADER_EXPORT std::size_t getHeapMemorySizeWithoutChildren() const; + MEDLOADER_EXPORT std::vector<const BigMemoryObject *> getDirectChildrenWithNull() const; + MEDLOADER_EXPORT void simpleReprGlobs(std::ostream& oss) const; + MEDLOADER_EXPORT void resetContent(); + MEDLOADER_EXPORT void shallowCpyGlobs(const MEDFileFieldGlobsReal& other); + MEDLOADER_EXPORT void deepCpyGlobs(const MEDFileFieldGlobsReal& other); + MEDLOADER_EXPORT void shallowCpyOnlyUsedGlobs(const MEDFileFieldGlobsReal& other); + MEDLOADER_EXPORT void deepCpyOnlyUsedGlobs(const MEDFileFieldGlobsReal& other); + MEDLOADER_EXPORT void appendGlobs(const MEDFileFieldGlobsReal& other, double eps); + MEDLOADER_EXPORT void checkGlobsCoherency() const; + MEDLOADER_EXPORT void checkGlobsPflsPartCoherency() const; + MEDLOADER_EXPORT void checkGlobsLocsPartCoherency() const; + MEDLOADER_EXPORT virtual std::vector<std::string> getPflsReallyUsed() const = 0; + MEDLOADER_EXPORT virtual std::vector<std::string> getLocsReallyUsed() const = 0; + MEDLOADER_EXPORT virtual std::vector<std::string> getPflsReallyUsedMulti() const = 0; + MEDLOADER_EXPORT virtual std::vector<std::string> getLocsReallyUsedMulti() const = 0; + MEDLOADER_EXPORT virtual void changePflsRefsNamesGen(const std::vector< std::pair<std::vector<std::string>, std::string > >& mapOfModif) = 0; + MEDLOADER_EXPORT virtual void changeLocsRefsNamesGen(const std::vector< std::pair<std::vector<std::string>, std::string > >& mapOfModif) = 0; + MEDLOADER_EXPORT virtual ~MEDFileFieldGlobsReal(); + // + MEDLOADER_EXPORT void loadProfileInFile(med_idt fid, int id, const std::string& pflName); + MEDLOADER_EXPORT void loadProfileInFile(med_idt fid, int id); + MEDLOADER_EXPORT void loadGlobals(med_idt fid); + MEDLOADER_EXPORT void loadAllGlobals(med_idt fid); + MEDLOADER_EXPORT void writeGlobals(med_idt fid, const MEDFileWritable& opt) const; + MEDLOADER_EXPORT std::vector<std::string> getPfls() const; + MEDLOADER_EXPORT std::vector<std::string> getLocs() const; + MEDLOADER_EXPORT bool existsPfl(const std::string& pflName) const; + MEDLOADER_EXPORT bool existsLoc(const std::string& locName) const; + MEDLOADER_EXPORT std::string createNewNameOfPfl() const; + MEDLOADER_EXPORT std::string createNewNameOfLoc() const; + MEDLOADER_EXPORT std::vector< std::vector<int> > whichAreEqualProfiles() const; + MEDLOADER_EXPORT std::vector< std::vector<int> > whichAreEqualLocs(double eps) const; + MEDLOADER_EXPORT void setFileName(const std::string& fileName); + MEDLOADER_EXPORT void changePflsNamesInStruct(const std::vector< std::pair<std::vector<std::string>, std::string > >& mapOfModif); + MEDLOADER_EXPORT void changeLocsNamesInStruct(const std::vector< std::pair<std::vector<std::string>, std::string > >& mapOfModif); + MEDLOADER_EXPORT void changePflsNames(const std::vector< std::pair<std::vector<std::string>, std::string > >& mapOfModif); + MEDLOADER_EXPORT void changeLocsNames(const std::vector< std::pair<std::vector<std::string>, std::string > >& mapOfModif); + MEDLOADER_EXPORT void changePflName(const std::string& oldName, const std::string& newName); + MEDLOADER_EXPORT void changeLocName(const std::string& oldName, const std::string& newName); + MEDLOADER_EXPORT std::vector< std::pair<std::vector<std::string>, std::string > > zipPflsNames(); + MEDLOADER_EXPORT std::vector< std::pair<std::vector<std::string>, std::string > > zipLocsNames(double eps); + MEDLOADER_EXPORT int getNbOfGaussPtPerCell(int locId) const; + MEDLOADER_EXPORT int getLocalizationId(const std::string& loc) const; + MEDLOADER_EXPORT std::string getFileName() const; + MEDLOADER_EXPORT const MEDFileFieldLoc& getLocalizationFromId(int locId) const; + MEDLOADER_EXPORT const MEDFileFieldLoc& getLocalization(const std::string& locName) const; + MEDLOADER_EXPORT MEDFileFieldLoc& getLocalizationFromId(int locId); + MEDLOADER_EXPORT MEDFileFieldLoc& getLocalization(const std::string& locName); + MEDLOADER_EXPORT const DataArrayInt *getProfile(const std::string& pflName) const; + MEDLOADER_EXPORT const DataArrayInt *getProfileFromId(int pflId) const; + MEDLOADER_EXPORT DataArrayInt *getProfile(const std::string& pflName); + MEDLOADER_EXPORT DataArrayInt *getProfileFromId(int pflId); + MEDLOADER_EXPORT void killProfileIds(const std::vector<int>& pflIds); + MEDLOADER_EXPORT void killLocalizationIds(const std::vector<int>& locIds); + // + MEDLOADER_EXPORT void appendProfile(DataArrayInt *pfl); + MEDLOADER_EXPORT void appendLoc(const std::string& locName, INTERP_KERNEL::NormalizedCellType geoType, const std::vector<double>& refCoo, const std::vector<double>& gsCoo, const std::vector<double>& w); + protected: + MEDFileFieldGlobs *contentNotNull(); + const MEDFileFieldGlobs *contentNotNull() const; + protected: + MEDCouplingAutoRefCountObjectPtr< MEDFileFieldGlobs > _globals; + }; + + class MEDFileFieldNameScope + { + public: + MEDLOADER_EXPORT MEDFileFieldNameScope(); + MEDLOADER_EXPORT MEDFileFieldNameScope(const std::string& fieldName); + MEDLOADER_EXPORT std::string getName() const; + MEDLOADER_EXPORT void setName(const std::string& fieldName); + MEDLOADER_EXPORT std::string getDtUnit() const; + MEDLOADER_EXPORT void setDtUnit(const std::string& dtUnit); + MEDLOADER_EXPORT void copyNameScope(const MEDFileFieldNameScope& other); + protected: + std::string _name; + std::string _dt_unit; + }; + + class MEDFileMeshes; + + /*! + * SDA is for Shared Data Arrays such as profiles. + */ + class MEDFileAnyTypeField1TSWithoutSDA : public RefCountObject, public MEDFileFieldNameScope + { + public: + MEDLOADER_EXPORT MEDFileAnyTypeField1TSWithoutSDA(); + MEDLOADER_EXPORT MEDFileAnyTypeField1TSWithoutSDA(const std::string& fieldName, int csit, int iteration, int order); + MEDLOADER_EXPORT int getIteration() const { return _iteration; } + MEDLOADER_EXPORT int getOrder() const { return _order; } + MEDLOADER_EXPORT double getTime(int& iteration, int& order) const { iteration=_iteration; order=_order; return _dt; } + MEDLOADER_EXPORT void setTime(int iteration, int order, double val) { _dt=val; _iteration=iteration; _order=order; } + MEDLOADER_EXPORT int getDimension() const; + MEDLOADER_EXPORT std::string getMeshName() const; + MEDLOADER_EXPORT void setMeshName(const std::string& newMeshName); + MEDLOADER_EXPORT bool changeMeshNames(const std::vector< std::pair<std::string,std::string> >& modifTab); + MEDLOADER_EXPORT int getMeshIteration() const; + MEDLOADER_EXPORT int getMeshOrder() const; + MEDLOADER_EXPORT bool isDealingTS(int iteration, int order) const; + MEDLOADER_EXPORT std::pair<int,int> getDtIt() const; + MEDLOADER_EXPORT void fillIteration(std::pair<int,int>& p) const; + MEDLOADER_EXPORT void fillTypesOfFieldAvailable(std::vector<TypeOfField>& types) const; + MEDLOADER_EXPORT std::vector<TypeOfField> getTypesOfFieldAvailable() const; + // + MEDLOADER_EXPORT std::vector<std::string> getPflsReallyUsed2() const; + MEDLOADER_EXPORT std::vector<std::string> getLocsReallyUsed2() const; + MEDLOADER_EXPORT std::vector<std::string> getPflsReallyUsedMulti2() const; + MEDLOADER_EXPORT std::vector<std::string> getLocsReallyUsedMulti2() const; + MEDLOADER_EXPORT void changePflsRefsNamesGen2(const std::vector< std::pair<std::vector<std::string>, std::string > >& mapOfModif); + MEDLOADER_EXPORT void changeLocsRefsNamesGen2(const std::vector< std::pair<std::vector<std::string>, std::string > >& mapOfModif); + // + MEDLOADER_EXPORT int getNonEmptyLevels(const std::string& mname, std::vector<int>& levs) const; + MEDLOADER_EXPORT std::vector< std::vector<std::pair<int,int> > > getFieldSplitedByType(const std::string& mname, std::vector<INTERP_KERNEL::NormalizedCellType>& types, std::vector< std::vector<TypeOfField> >& typesF, std::vector< std::vector<std::string> >& pfls, std::vector< std::vector<std::string> >& locs) const; + // + MEDLOADER_EXPORT MEDFileFieldPerMeshPerTypePerDisc *getLeafGivenMeshAndTypeAndLocId(const std::string& mName, INTERP_KERNEL::NormalizedCellType typ, int locId); + MEDLOADER_EXPORT const MEDFileFieldPerMeshPerTypePerDisc *getLeafGivenMeshAndTypeAndLocId(const std::string& mName, INTERP_KERNEL::NormalizedCellType typ, int locId) const; + MEDLOADER_EXPORT void deepCpyLeavesFrom(const MEDFileAnyTypeField1TSWithoutSDA& other); + public: + MEDLOADER_EXPORT int getNumberOfComponents() const; + MEDLOADER_EXPORT const std::vector<std::string>& getInfo() const; + MEDLOADER_EXPORT std::vector<std::string>& getInfo(); + MEDLOADER_EXPORT bool presenceOfMultiDiscPerGeoType() const; + MEDLOADER_EXPORT void setInfo(const std::vector<std::string>& infos); + MEDLOADER_EXPORT std::size_t getHeapMemorySizeWithoutChildren() const; + MEDLOADER_EXPORT std::vector<const BigMemoryObject *> getDirectChildrenWithNull() const; + MEDLOADER_EXPORT int copyTinyInfoFrom(const MEDCouplingFieldDouble *field, const DataArray *arr); + MEDLOADER_EXPORT void setFieldNoProfileSBT(const MEDCouplingFieldDouble *field, const DataArray *arr, MEDFileFieldGlobsReal& glob, const MEDFileFieldNameScope& nasc); + MEDLOADER_EXPORT void setFieldProfile(const MEDCouplingFieldDouble *field, const DataArray *arrOfVals, const MEDFileMesh *mesh, int meshDimRelToMax, const DataArrayInt *profile, MEDFileFieldGlobsReal& glob, const MEDFileFieldNameScope& nasc); + MEDLOADER_EXPORT virtual void simpleRepr(int bkOffset, std::ostream& oss, int f1tsId) const; + MEDLOADER_EXPORT virtual MEDFileAnyTypeField1TSWithoutSDA *deepCpy() const = 0; + MEDLOADER_EXPORT virtual MEDFileAnyTypeField1TSWithoutSDA *shallowCpy() const = 0; + MEDLOADER_EXPORT virtual std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileAnyTypeField1TSWithoutSDA> > splitComponents() const; + MEDLOADER_EXPORT virtual const char *getTypeStr() const = 0; + MEDLOADER_EXPORT virtual DataArray *getUndergroundDataArray() const = 0; + MEDLOADER_EXPORT virtual DataArray *getUndergroundDataArrayExt(std::vector< std::pair<std::pair<INTERP_KERNEL::NormalizedCellType,int>,std::pair<int,int> > >& entries) const = 0; + MEDLOADER_EXPORT virtual void setArray(DataArray *arr) = 0; + MEDLOADER_EXPORT virtual DataArray *createNewEmptyDataArrayInstance() const = 0; + MEDLOADER_EXPORT virtual DataArray *getOrCreateAndGetArray() = 0; + MEDLOADER_EXPORT virtual const DataArray *getOrCreateAndGetArray() const = 0; + public: + MEDLOADER_EXPORT MEDCouplingFieldDouble *getFieldAtLevel(TypeOfField type, int meshDimRelToMax, const std::string& mName, int renumPol, const MEDFileFieldGlobsReal *glob, MEDCouplingAutoRefCountObjectPtr<DataArray> &arrOut, const MEDFileFieldNameScope& nasc) const; + MEDLOADER_EXPORT MEDCouplingFieldDouble *getFieldOnMeshAtLevel(TypeOfField type, int meshDimRelToMax, int renumPol, const MEDFileFieldGlobsReal *glob, const MEDFileMesh *mesh, MEDCouplingAutoRefCountObjectPtr<DataArray> &arrOut, const MEDFileFieldNameScope& nasc) const; + MEDLOADER_EXPORT MEDCouplingFieldDouble *getFieldAtTopLevel(TypeOfField type, const std::string& mName, int renumPol, const MEDFileFieldGlobsReal *glob, MEDCouplingAutoRefCountObjectPtr<DataArray> &arrOut, const MEDFileFieldNameScope& nasc) const; + MEDLOADER_EXPORT MEDCouplingFieldDouble *getFieldOnMeshAtLevel(TypeOfField type, int renumPol, const MEDFileFieldGlobsReal *glob, const MEDCouplingMesh *mesh, const DataArrayInt *cellRenum, const DataArrayInt *nodeRenum, MEDCouplingAutoRefCountObjectPtr<DataArray> &arrOut, const MEDFileFieldNameScope& nasc) const; + DataArray *getFieldWithProfile(TypeOfField type, int meshDimRelToMax, const MEDFileMesh *mesh, DataArrayInt *&pfl, const MEDFileFieldGlobsReal *glob, const MEDFileFieldNameScope& nasc) const; + public: + MEDLOADER_EXPORT bool renumberEntitiesLyingOnMesh(const std::string& meshName, const std::vector<int>& oldCode, const std::vector<int>& newCode, const DataArrayInt *renumO2N, MEDFileFieldGlobsReal& glob); + MEDLOADER_EXPORT std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileAnyTypeField1TSWithoutSDA> > splitDiscretizations() const; + MEDLOADER_EXPORT std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileAnyTypeField1TSWithoutSDA> > splitMultiDiscrPerGeoTypes() const; + MEDLOADER_EXPORT int keepOnlySpatialDiscretization(TypeOfField tof, std::vector< std::pair<int,int> >& its); + MEDLOADER_EXPORT int keepOnlyGaussDiscretization(std::size_t idOfDisc, std::vector< std::pair<int,int> >& its); + public: + MEDLOADER_EXPORT void allocNotFromFile(int newNbOfTuples); + MEDLOADER_EXPORT bool allocIfNecessaryTheArrayToReceiveDataFromFile(); + MEDLOADER_EXPORT void loadOnlyStructureOfDataRecursively(med_idt fid, const MEDFileFieldNameScope& nasc, const MEDFileMeshes *ms, const std::vector< std::pair<TypeOfField,INTERP_KERNEL::NormalizedCellType> > *entities); + MEDLOADER_EXPORT void loadBigArraysRecursively(med_idt fid, const MEDFileFieldNameScope& nasc); + MEDLOADER_EXPORT void loadBigArraysRecursivelyIfNecessary(med_idt fid, const MEDFileFieldNameScope& nasc); + MEDLOADER_EXPORT void loadStructureAndBigArraysRecursively(med_idt fid, const MEDFileFieldNameScope& nasc, const MEDFileMeshes *ms, const std::vector< std::pair<TypeOfField,INTERP_KERNEL::NormalizedCellType> > *entities); + MEDLOADER_EXPORT void unloadArrays(); + MEDLOADER_EXPORT void writeLL(med_idt fid, const MEDFileWritable& opts, const MEDFileFieldNameScope& nasc) const; + protected: + int getMeshIdFromMeshName(const std::string& mName) const; + int addNewEntryIfNecessary(const MEDCouplingMesh *mesh); + void updateData(int newLgth, const std::vector< std::pair<int,int> >& oldStartStops); + protected: + std::vector< MEDCouplingAutoRefCountObjectPtr< MEDFileFieldPerMesh > > _field_per_mesh; + int _iteration; + int _order; + double _dt; + public: + //! only useable on reading + mutable int _csit; + // -3 means allocated and build from scratch + // -2 means allocated and read from a file + // -1 means not allocated and build from scratch + // >=0 means not allocated and read from a file + mutable int _nb_of_tuples_to_be_allocated; + }; + + class MEDFileIntField1TSWithoutSDA; + + /*! + * SDA is for Shared Data Arrays such as profiles. + */ + class MEDFileField1TSWithoutSDA : public MEDFileAnyTypeField1TSWithoutSDA + { + public: + MEDLOADER_EXPORT const char *getTypeStr() const; + MEDLOADER_EXPORT DataArray *getUndergroundDataArray() const; + MEDLOADER_EXPORT DataArray *getUndergroundDataArrayExt(std::vector< std::pair<std::pair<INTERP_KERNEL::NormalizedCellType,int>,std::pair<int,int> > >& entries) const; + MEDLOADER_EXPORT DataArrayDouble *getUndergroundDataArrayDouble() const; + MEDLOADER_EXPORT DataArrayDouble *getUndergroundDataArrayDoubleExt(std::vector< std::pair<std::pair<INTERP_KERNEL::NormalizedCellType,int>,std::pair<int,int> > >& entries) const; + MEDLOADER_EXPORT std::vector< std::vector<DataArrayDouble *> > getFieldSplitedByType2(const std::string& mname, std::vector<INTERP_KERNEL::NormalizedCellType>& types, std::vector< std::vector<TypeOfField> >& typesF, std::vector< std::vector<std::string> >& pfls, std::vector< std::vector<std::string> >& locs) const; + MEDLOADER_EXPORT static void CheckMeshDimRel(int meshDimRelToMax); + MEDLOADER_EXPORT static std::vector<int> CheckSBTMesh(const MEDCouplingMesh *mesh); + MEDLOADER_EXPORT static MEDFileField1TSWithoutSDA *New(const std::string& fieldName, int csit, int iteration, int order, const std::vector<std::string>& infos); + public: + MEDLOADER_EXPORT MEDFileField1TSWithoutSDA(); + MEDLOADER_EXPORT MEDFileField1TSWithoutSDA(const std::string& fieldName, int csit, int iteration, int order, const std::vector<std::string>& infos); + MEDLOADER_EXPORT MEDFileAnyTypeField1TSWithoutSDA *shallowCpy() const; + MEDLOADER_EXPORT MEDFileAnyTypeField1TSWithoutSDA *deepCpy() const; + MEDLOADER_EXPORT void setArray(DataArray *arr); + MEDLOADER_EXPORT DataArray *createNewEmptyDataArrayInstance() const; + MEDLOADER_EXPORT DataArray *getOrCreateAndGetArray(); + MEDLOADER_EXPORT const DataArray *getOrCreateAndGetArray() const; + MEDLOADER_EXPORT DataArrayDouble *getOrCreateAndGetArrayDouble(); + MEDLOADER_EXPORT const DataArrayDouble *getOrCreateAndGetArrayDouble() const; + MEDLOADER_EXPORT MEDFileIntField1TSWithoutSDA *convertToInt() const; + protected: + MEDCouplingAutoRefCountObjectPtr< DataArrayDouble > _arr; + public: + static const char TYPE_STR[]; + }; + + /*! + * SDA is for Shared Data Arrays such as profiles. + */ + class MEDFileIntField1TSWithoutSDA : public MEDFileAnyTypeField1TSWithoutSDA + { + public: + MEDLOADER_EXPORT MEDFileIntField1TSWithoutSDA(); + MEDLOADER_EXPORT static MEDFileIntField1TSWithoutSDA *New(const std::string& fieldName, int csit, int iteration, int order, const std::vector<std::string>& infos); + MEDLOADER_EXPORT MEDFileAnyTypeField1TSWithoutSDA *deepCpy() const; + MEDLOADER_EXPORT MEDFileAnyTypeField1TSWithoutSDA *shallowCpy() const; + MEDLOADER_EXPORT const char *getTypeStr() const; + MEDLOADER_EXPORT DataArray *getUndergroundDataArray() const; + MEDLOADER_EXPORT DataArray *getUndergroundDataArrayExt(std::vector< std::pair<std::pair<INTERP_KERNEL::NormalizedCellType,int>,std::pair<int,int> > >& entries) const; + MEDLOADER_EXPORT void setArray(DataArray *arr); + MEDLOADER_EXPORT DataArray *createNewEmptyDataArrayInstance() const; + MEDLOADER_EXPORT DataArray *getOrCreateAndGetArray(); + MEDLOADER_EXPORT const DataArray *getOrCreateAndGetArray() const; + MEDLOADER_EXPORT DataArrayInt *getOrCreateAndGetArrayInt(); + MEDLOADER_EXPORT const DataArrayInt *getOrCreateAndGetArrayInt() const; + MEDLOADER_EXPORT DataArrayInt *getUndergroundDataArrayInt() const; + MEDLOADER_EXPORT DataArrayInt *getUndergroundDataArrayIntExt(std::vector< std::pair<std::pair<INTERP_KERNEL::NormalizedCellType,int>,std::pair<int,int> > >& entries) const; + MEDLOADER_EXPORT MEDFileField1TSWithoutSDA *convertToDouble() const; + protected: + MEDFileIntField1TSWithoutSDA(const std::string& fieldName, int csit, int iteration, int order, const std::vector<std::string>& infos); + protected: + MEDCouplingAutoRefCountObjectPtr< DataArrayInt > _arr; + public: + MEDLOADER_EXPORT static const char TYPE_STR[]; + }; + + /*! + * User class. + */ + class MEDFileAnyTypeField1TS : public RefCountObject, public MEDFileWritable, public MEDFileFieldGlobsReal + { + protected: + MEDLOADER_EXPORT MEDFileAnyTypeField1TS(); + MEDLOADER_EXPORT MEDFileAnyTypeField1TS(const std::string& fileName, bool loadAll, const MEDFileMeshes *ms); + MEDLOADER_EXPORT MEDFileAnyTypeField1TS(const std::string& fileName, const std::string& fieldName, bool loadAll, const MEDFileMeshes *ms); + MEDLOADER_EXPORT MEDFileAnyTypeField1TS(const std::string& fileName, const std::string& fieldName, int iteration, int order, bool loadAll, const MEDFileMeshes *ms); + MEDLOADER_EXPORT MEDFileAnyTypeField1TS(const MEDFileAnyTypeField1TSWithoutSDA& other, bool shallowCopyOfContent); + MEDLOADER_EXPORT static MEDFileAnyTypeField1TS *BuildNewInstanceFromContent(MEDFileAnyTypeField1TSWithoutSDA *c, const std::string& fileName); + MEDLOADER_EXPORT static MEDFileAnyTypeField1TSWithoutSDA *BuildContentFrom(med_idt fid, const std::string& fileName, bool loadAll, const MEDFileMeshes *ms); + MEDLOADER_EXPORT static MEDFileAnyTypeField1TSWithoutSDA *BuildContentFrom(med_idt fid, const std::string& fileName, const std::string& fieldName, bool loadAll, const MEDFileMeshes *ms); + MEDLOADER_EXPORT static MEDFileAnyTypeField1TSWithoutSDA *BuildContentFrom(med_idt fid, const std::string& fileName, const std::string& fieldName, int iteration, int order, bool loadAll, const MEDFileMeshes *ms); + MEDLOADER_EXPORT void writeLL(med_idt fid) const; + // direct forwarding to MEDFileAnyTypeField1TSWithoutSDA instance _content + public: + MEDLOADER_EXPORT static MEDFileAnyTypeField1TS *New(const std::string& fileName, bool loadAll=true); + MEDLOADER_EXPORT static MEDFileAnyTypeField1TS *New(const std::string& fileName, const std::string& fieldName, bool loadAll=true); + MEDLOADER_EXPORT static MEDFileAnyTypeField1TS *New(const std::string& fileName, const std::string& fieldName, int iteration, int order, bool loadAll=true); + MEDLOADER_EXPORT int getDimension() const; + MEDLOADER_EXPORT int getIteration() const; + MEDLOADER_EXPORT int getOrder() const; + MEDLOADER_EXPORT double getTime(int& iteration, int& order) const; + MEDLOADER_EXPORT void setTime(int iteration, int order, double val); + MEDLOADER_EXPORT std::string getName() const; + MEDLOADER_EXPORT void setName(const std::string& name); + MEDLOADER_EXPORT std::string simpleRepr() const; + MEDLOADER_EXPORT void simpleRepr(int bkOffset, std::ostream& oss, int f1tsId) const; + MEDLOADER_EXPORT std::string getDtUnit() const; + MEDLOADER_EXPORT void setDtUnit(const std::string& dtUnit); + MEDLOADER_EXPORT std::string getMeshName() const; + MEDLOADER_EXPORT void setMeshName(const std::string& newMeshName); + MEDLOADER_EXPORT bool changeMeshNames(const std::vector< std::pair<std::string,std::string> >& modifTab); + MEDLOADER_EXPORT int getMeshIteration() const; + MEDLOADER_EXPORT int getMeshOrder() const; + MEDLOADER_EXPORT int getNumberOfComponents() const; + MEDLOADER_EXPORT bool isDealingTS(int iteration, int order) const; + MEDLOADER_EXPORT std::pair<int,int> getDtIt() const; + MEDLOADER_EXPORT void fillIteration(std::pair<int,int>& p) const; + MEDLOADER_EXPORT void fillTypesOfFieldAvailable(std::vector<TypeOfField>& types) const; + MEDLOADER_EXPORT void setInfo(const std::vector<std::string>& infos); + MEDLOADER_EXPORT const std::vector<std::string>& getInfo() const; + MEDLOADER_EXPORT std::vector<std::string>& getInfo(); + MEDLOADER_EXPORT bool presenceOfMultiDiscPerGeoType() const; + MEDLOADER_EXPORT std::vector<TypeOfField> getTypesOfFieldAvailable() const; + MEDLOADER_EXPORT std::vector< std::vector<std::pair<int,int> > > getFieldSplitedByType(const std::string& mname, std::vector<INTERP_KERNEL::NormalizedCellType>& types, std::vector< std::vector<TypeOfField> >& typesF, + std::vector< std::vector<std::string> >& pfls, std::vector< std::vector<std::string> >& locs) const; + MEDLOADER_EXPORT MEDFileFieldPerMeshPerTypePerDisc *getLeafGivenMeshAndTypeAndLocId(const std::string& mName, INTERP_KERNEL::NormalizedCellType typ, int locId); + MEDLOADER_EXPORT const MEDFileFieldPerMeshPerTypePerDisc *getLeafGivenMeshAndTypeAndLocId(const std::string& mName, INTERP_KERNEL::NormalizedCellType typ, int locId) const; + MEDLOADER_EXPORT int getNonEmptyLevels(const std::string& mname, std::vector<int>& levs) const; + public: + MEDLOADER_EXPORT void write(const std::string& fileName, int mode) const; + MEDLOADER_EXPORT void loadArrays(); + MEDLOADER_EXPORT void loadArraysIfNecessary(); + MEDLOADER_EXPORT void unloadArrays(); + MEDLOADER_EXPORT void unloadArraysWithoutDataLoss(); + MEDLOADER_EXPORT std::vector< MEDCouplingAutoRefCountObjectPtr< MEDFileAnyTypeField1TS > > splitComponents() const; + MEDLOADER_EXPORT std::vector< MEDCouplingAutoRefCountObjectPtr< MEDFileAnyTypeField1TS > > splitDiscretizations() const; + MEDLOADER_EXPORT std::vector< MEDCouplingAutoRefCountObjectPtr< MEDFileAnyTypeField1TS > > splitMultiDiscrPerGeoTypes() const; + MEDLOADER_EXPORT MEDFileAnyTypeField1TS *deepCpy() const; + MEDLOADER_EXPORT int copyTinyInfoFrom(const MEDCouplingFieldDouble *field, const DataArray *arr); + MEDLOADER_EXPORT virtual MEDFileAnyTypeField1TS *shallowCpy() const = 0; + public: + //! underground method see MEDFileField1TSWithoutSDA::setProfileNameOnLeaf + MEDLOADER_EXPORT void setProfileNameOnLeaf(const std::string& mName, INTERP_KERNEL::NormalizedCellType typ, int locId, const std::string& newPflName, bool forceRenameOnGlob=false); + //! underground method see MEDFileField1TSWithoutSDA::setLocNameOnLeaf + MEDLOADER_EXPORT void setLocNameOnLeaf(const std::string& mName, INTERP_KERNEL::NormalizedCellType typ, int locId, const std::string& newLocName, bool forceRenameOnGlob=false); + MEDLOADER_EXPORT std::size_t getHeapMemorySizeWithoutChildren() const; + MEDLOADER_EXPORT std::vector<const BigMemoryObject *> getDirectChildrenWithNull() const; + MEDLOADER_EXPORT std::vector<std::string> getPflsReallyUsed() const; + MEDLOADER_EXPORT std::vector<std::string> getLocsReallyUsed() const; + MEDLOADER_EXPORT std::vector<std::string> getPflsReallyUsedMulti() const; + MEDLOADER_EXPORT std::vector<std::string> getLocsReallyUsedMulti() const; + MEDLOADER_EXPORT void changePflsRefsNamesGen(const std::vector< std::pair<std::vector<std::string>, std::string > >& mapOfModif); + MEDLOADER_EXPORT void changeLocsRefsNamesGen(const std::vector< std::pair<std::vector<std::string>, std::string > >& mapOfModif); + public: + MEDLOADER_EXPORT static int LocateField2(med_idt fid, const std::string& fileName, int fieldIdCFormat, bool checkFieldId, std::string& fieldName, med_field_type& typcha, std::vector<std::string>& infos, std::string& dtunitOut); + MEDLOADER_EXPORT static int LocateField(med_idt fid, const std::string& fileName, const std::string& fieldName, int& posCFormat, med_field_type& typcha, std::vector<std::string>& infos, std::string& dtunitOut); + public: + MEDLOADER_EXPORT virtual med_field_type getMEDFileFieldType() const = 0; + MEDLOADER_EXPORT MEDFileAnyTypeField1TSWithoutSDA *contentNotNullBase(); + MEDLOADER_EXPORT const MEDFileAnyTypeField1TSWithoutSDA *contentNotNullBase() const; + protected: + MEDCouplingAutoRefCountObjectPtr<MEDFileAnyTypeField1TSWithoutSDA> _content; + }; + + class MEDFileIntField1TS; + + /*! + * User class. + */ + class MEDFileField1TS : public MEDFileAnyTypeField1TS + { + public: + MEDLOADER_EXPORT static MEDFileField1TS *New(const std::string& fileName, bool loadAll=true); + MEDLOADER_EXPORT static MEDFileField1TS *New(const std::string& fileName, const std::string& fieldName, bool loadAll=true); + MEDLOADER_EXPORT static MEDFileField1TS *New(const std::string& fileName, const std::string& fieldName, int iteration, int order, bool loadAll=true); + MEDLOADER_EXPORT static MEDFileField1TS *New(const MEDFileField1TSWithoutSDA& other, bool shallowCopyOfContent); + MEDLOADER_EXPORT static MEDFileField1TS *New(); + MEDLOADER_EXPORT MEDFileIntField1TS *convertToInt(bool isDeepCpyGlobs=true) const; + // + MEDLOADER_EXPORT MEDCouplingFieldDouble *getFieldAtLevel(TypeOfField type, int meshDimRelToMax, int renumPol=0) const; + MEDLOADER_EXPORT MEDCouplingFieldDouble *getFieldAtTopLevel(TypeOfField type, int renumPol=0) const; + MEDLOADER_EXPORT MEDCouplingFieldDouble *getFieldOnMeshAtLevel(TypeOfField type, int meshDimRelToMax, const MEDFileMesh *mesh, int renumPol=0) const; + MEDLOADER_EXPORT MEDCouplingFieldDouble *getFieldOnMeshAtLevel(TypeOfField type, const MEDCouplingMesh *mesh, int renumPol=0) const; + MEDLOADER_EXPORT MEDCouplingFieldDouble *getFieldAtLevelOld(TypeOfField type, const std::string& mname, int meshDimRelToMax, int renumPol=0) const; + MEDLOADER_EXPORT DataArrayDouble *getFieldWithProfile(TypeOfField type, int meshDimRelToMax, const MEDFileMesh *mesh, DataArrayInt *&pfl) const; + // + MEDLOADER_EXPORT void setFieldNoProfileSBT(const MEDCouplingFieldDouble *field); + MEDLOADER_EXPORT void setFieldProfile(const MEDCouplingFieldDouble *field, const MEDFileMesh *mesh, int meshDimRelToMax, const DataArrayInt *profile); + // direct forwarding to MEDFileField1TSWithoutSDA instance _content + public: + MEDLOADER_EXPORT MEDFileAnyTypeField1TS *shallowCpy() const; + MEDLOADER_EXPORT DataArrayDouble *getUndergroundDataArray() const; + MEDLOADER_EXPORT DataArrayDouble *getUndergroundDataArrayExt(std::vector< std::pair<std::pair<INTERP_KERNEL::NormalizedCellType,int>,std::pair<int,int> > >& entries) const; + + MEDLOADER_EXPORT std::vector< std::vector<DataArrayDouble *> > getFieldSplitedByType2(const std::string& mname, std::vector<INTERP_KERNEL::NormalizedCellType>& types, std::vector< std::vector<TypeOfField> >& typesF, + std::vector< std::vector<std::string> >& pfls, std::vector< std::vector<std::string> >& locs) const; + public: + MEDLOADER_EXPORT static void SetDataArrayDoubleInField(MEDCouplingFieldDouble *f, MEDCouplingAutoRefCountObjectPtr<DataArray>& arr); + MEDLOADER_EXPORT static DataArrayDouble *ReturnSafelyDataArrayDouble(MEDCouplingAutoRefCountObjectPtr<DataArray>& arr); + private: + med_field_type getMEDFileFieldType() const { return MED_FLOAT64; } + const MEDFileField1TSWithoutSDA *contentNotNull() const; + MEDFileField1TSWithoutSDA *contentNotNull(); + private: + ~MEDFileField1TS() { } + MEDFileField1TS(const std::string& fileName, bool loadAll, const MEDFileMeshes *ms); + MEDFileField1TS(const std::string& fileName, const std::string& fieldName, bool loadAll, const MEDFileMeshes *ms); + MEDFileField1TS(const std::string& fileName, const std::string& fieldName, int iteration, int order, bool loadAll, const MEDFileMeshes *ms); + MEDFileField1TS(const MEDFileField1TSWithoutSDA& other, bool shallowCopyOfContent); + MEDFileField1TS(); + }; + + class MEDFileIntField1TS : public MEDFileAnyTypeField1TS + { + public: + MEDLOADER_EXPORT static MEDFileIntField1TS *New(); + MEDLOADER_EXPORT static MEDFileIntField1TS *New(const std::string& fileName, bool loadAll=true); + MEDLOADER_EXPORT static MEDFileIntField1TS *New(const std::string& fileName, const std::string& fieldName, bool loadAll=true); + MEDLOADER_EXPORT static MEDFileIntField1TS *New(const std::string& fileName, const std::string& fieldName, int iteration, int order, bool loadAll=true); + MEDLOADER_EXPORT static MEDFileIntField1TS *New(const MEDFileIntField1TSWithoutSDA& other, bool shallowCopyOfContent); + MEDLOADER_EXPORT MEDFileField1TS *convertToDouble(bool isDeepCpyGlobs=true) const; + MEDLOADER_EXPORT MEDFileAnyTypeField1TS *shallowCpy() const; + // + MEDLOADER_EXPORT MEDCouplingFieldDouble *getFieldAtLevel(TypeOfField type, int meshDimRelToMax, DataArrayInt* &arrOut, int renumPol=0) const; + MEDLOADER_EXPORT MEDCouplingFieldDouble *getFieldAtTopLevel(TypeOfField type, DataArrayInt* &arrOut, int renumPol=0) const; + MEDLOADER_EXPORT MEDCouplingFieldDouble *getFieldOnMeshAtLevel(TypeOfField type, int meshDimRelToMax, const MEDFileMesh *mesh, DataArrayInt* &arrOut, int renumPol=0) const; + MEDLOADER_EXPORT MEDCouplingFieldDouble *getFieldOnMeshAtLevel(TypeOfField type, const MEDCouplingMesh *mesh, DataArrayInt* &arrOut, int renumPol=0) const; + MEDLOADER_EXPORT MEDCouplingFieldDouble *getFieldAtLevelOld(TypeOfField type, const std::string& mname, int meshDimRelToMax, DataArrayInt* &arrOut, int renumPol=0) const; + MEDLOADER_EXPORT DataArrayInt *getFieldWithProfile(TypeOfField type, int meshDimRelToMax, const MEDFileMesh *mesh, DataArrayInt *&pfl) const; + // + MEDLOADER_EXPORT void setFieldNoProfileSBT(const MEDCouplingFieldDouble *field, const DataArrayInt *arrOfVals); + MEDLOADER_EXPORT void setFieldProfile(const MEDCouplingFieldDouble *field, const DataArrayInt *arrOfVals, const MEDFileMesh *mesh, int meshDimRelToMax, const DataArrayInt *profile); + MEDLOADER_EXPORT DataArrayInt *getUndergroundDataArray() const; + public: + MEDLOADER_EXPORT static DataArrayInt *ReturnSafelyDataArrayInt(MEDCouplingAutoRefCountObjectPtr<DataArray>& arr); + private: + med_field_type getMEDFileFieldType() const { return MED_INT32; } + const MEDFileIntField1TSWithoutSDA *contentNotNull() const; + MEDFileIntField1TSWithoutSDA *contentNotNull(); + private: + ~MEDFileIntField1TS() { } + MEDFileIntField1TS(); + MEDFileIntField1TS(const std::string& fileName, bool loadAll, const MEDFileMeshes *ms); + MEDFileIntField1TS(const std::string& fileName, const std::string& fieldName, bool loadAll, const MEDFileMeshes *ms); + MEDFileIntField1TS(const std::string& fileName, const std::string& fieldName, int iteration, int order, bool loadAll, const MEDFileMeshes *ms); + MEDFileIntField1TS(const MEDFileIntField1TSWithoutSDA& other, bool shallowCopyOfContent); + }; + + class MEDFileAnyTypeFieldMultiTSWithoutSDA : public RefCountObject, public MEDFileFieldNameScope + { + protected: + MEDFileAnyTypeFieldMultiTSWithoutSDA(); + MEDFileAnyTypeFieldMultiTSWithoutSDA(const std::string& fieldName); + MEDFileAnyTypeFieldMultiTSWithoutSDA(med_idt fid, int fieldId, bool loadAll, const MEDFileMeshes *ms, const std::vector< std::pair<TypeOfField,INTERP_KERNEL::NormalizedCellType> > *entities); + MEDFileAnyTypeFieldMultiTSWithoutSDA(med_idt fid, const std::string& fieldName, med_field_type fieldTyp, const std::vector<std::string>& infos, int nbOfStep, const std::string& dtunit, bool loadAll, const MEDFileMeshes *ms, const std::vector< std::pair<TypeOfField,INTERP_KERNEL::NormalizedCellType> > *entities); + public: + MEDLOADER_EXPORT std::size_t getHeapMemorySizeWithoutChildren() const; + MEDLOADER_EXPORT std::vector<const BigMemoryObject *> getDirectChildrenWithNull() const; + MEDLOADER_EXPORT virtual MEDFileAnyTypeFieldMultiTSWithoutSDA *deepCpy() const; + MEDLOADER_EXPORT virtual std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileAnyTypeFieldMultiTSWithoutSDA> > splitComponents() const; + MEDLOADER_EXPORT virtual std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileAnyTypeFieldMultiTSWithoutSDA> > splitDiscretizations() const; + MEDLOADER_EXPORT virtual std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileAnyTypeFieldMultiTSWithoutSDA> > splitMultiDiscrPerGeoTypes() const; + MEDLOADER_EXPORT virtual const char *getTypeStr() const = 0; + MEDLOADER_EXPORT virtual MEDFileAnyTypeFieldMultiTSWithoutSDA *shallowCpy() const = 0; + MEDLOADER_EXPORT virtual MEDFileAnyTypeFieldMultiTSWithoutSDA *createNew() const = 0; + MEDLOADER_EXPORT virtual MEDFileAnyTypeField1TSWithoutSDA *createNew1TSWithoutSDAEmptyInstance() const = 0; + MEDLOADER_EXPORT virtual void checkCoherencyOfType(const MEDFileAnyTypeField1TSWithoutSDA *f1ts) const = 0; + MEDLOADER_EXPORT const std::vector<std::string>& getInfo() const; + MEDLOADER_EXPORT bool presenceOfMultiDiscPerGeoType() const; + MEDLOADER_EXPORT void setInfo(const std::vector<std::string>& info); + MEDLOADER_EXPORT int getTimeStepPos(int iteration, int order) const; + MEDLOADER_EXPORT const MEDFileAnyTypeField1TSWithoutSDA& getTimeStepEntry(int iteration, int order) const; + MEDLOADER_EXPORT MEDFileAnyTypeField1TSWithoutSDA& getTimeStepEntry(int iteration, int order); + MEDLOADER_EXPORT std::string getMeshName() const; + MEDLOADER_EXPORT void setMeshName(const std::string& newMeshName); + MEDLOADER_EXPORT bool changeMeshNames(const std::vector< std::pair<std::string,std::string> >& modifTab); + MEDLOADER_EXPORT int getNumberOfTS() const; + MEDLOADER_EXPORT void eraseEmptyTS(); + MEDLOADER_EXPORT void eraseTimeStepIds(const int *startIds, const int *endIds); + MEDLOADER_EXPORT void eraseTimeStepIds2(int bg, int end, int step); + MEDLOADER_EXPORT MEDFileAnyTypeFieldMultiTSWithoutSDA *buildFromTimeStepIds(const int *startIds, const int *endIds) const; + MEDLOADER_EXPORT MEDFileAnyTypeFieldMultiTSWithoutSDA *buildFromTimeStepIds2(int bg, int end, int step) const; + MEDLOADER_EXPORT MEDFileAnyTypeFieldMultiTSWithoutSDA *partOfThisLyingOnSpecifiedTimeSteps(const std::vector< std::pair<int,int> >& timeSteps) const; + MEDLOADER_EXPORT MEDFileAnyTypeFieldMultiTSWithoutSDA *partOfThisNotLyingOnSpecifiedTimeSteps(const std::vector< std::pair<int,int> >& timeSteps) const; + MEDLOADER_EXPORT int getPosOfTimeStep(int iteration, int order) const; + MEDLOADER_EXPORT int getPosGivenTime(double time, double eps=1e-8) const; + MEDLOADER_EXPORT std::vector< std::pair<int,int> > getIterations() const; + MEDLOADER_EXPORT std::vector< std::pair<int,int> > getTimeSteps(std::vector<double>& ret1) const; + MEDLOADER_EXPORT void pushBackTimeStep(MEDCouplingAutoRefCountObjectPtr<MEDFileAnyTypeField1TSWithoutSDA>& tse); + MEDLOADER_EXPORT void synchronizeNameScope(); + MEDLOADER_EXPORT void simpleRepr(int bkOffset, std::ostream& oss, int fmtsId) const; + MEDLOADER_EXPORT int getNonEmptyLevels(int iteration, int order, const std::string& mname, std::vector<int>& levs) const; + MEDLOADER_EXPORT void appendFieldNoProfileSBT(const MEDCouplingFieldDouble *field, const DataArray *arr, MEDFileFieldGlobsReal& glob); + MEDLOADER_EXPORT void appendFieldProfile(const MEDCouplingFieldDouble *field, const DataArray *arr, const MEDFileMesh *mesh, int meshDimRelToMax, const DataArrayInt *profile, MEDFileFieldGlobsReal& glob); + MEDLOADER_EXPORT std::vector< std::vector< std::pair<int,int> > > getFieldSplitedByType(int iteration, int order, const std::string& mname, std::vector<INTERP_KERNEL::NormalizedCellType>& types, std::vector< std::vector<TypeOfField> >& typesF, std::vector< std::vector<std::string> >& pfls, std::vector< std::vector<std::string> >& locs) const; + MEDLOADER_EXPORT std::vector< std::vector<TypeOfField> > getTypesOfFieldAvailable() const; + MEDLOADER_EXPORT DataArray *getUndergroundDataArray(int iteration, int order) const; + MEDLOADER_EXPORT DataArray *getUndergroundDataArrayExt(int iteration, int order, std::vector< std::pair<std::pair<INTERP_KERNEL::NormalizedCellType,int>,std::pair<int,int> > >& entries) const; + MEDLOADER_EXPORT bool renumberEntitiesLyingOnMesh(const std::string& meshName, const std::vector<int>& oldCode, const std::vector<int>& newCode, const DataArrayInt *renumO2N, MEDFileFieldGlobsReal& glob); + MEDLOADER_EXPORT void loadStructureOrStructureAndBigArraysRecursively(med_idt fid, int nbPdt, med_field_type fieldTyp, bool loadAll, const MEDFileMeshes *ms, const std::vector< std::pair<TypeOfField,INTERP_KERNEL::NormalizedCellType> > *entities); + MEDLOADER_EXPORT void writeLL(med_idt fid, const MEDFileWritable& opts) const; + MEDLOADER_EXPORT void loadBigArraysRecursively(med_idt fid, const MEDFileFieldNameScope& nasc); + MEDLOADER_EXPORT void loadBigArraysRecursivelyIfNecessary(med_idt fid, const MEDFileFieldNameScope& nasc); + MEDLOADER_EXPORT void unloadArrays(); + public: + MEDLOADER_EXPORT const MEDFileAnyTypeField1TSWithoutSDA *getTimeStepAtPos2(int pos) const; + MEDLOADER_EXPORT MEDFileAnyTypeField1TSWithoutSDA *getTimeStepAtPos2(int pos); + MEDLOADER_EXPORT std::vector<std::string> getPflsReallyUsed2() const; + MEDLOADER_EXPORT std::vector<std::string> getLocsReallyUsed2() const; + MEDLOADER_EXPORT std::vector<std::string> getPflsReallyUsedMulti2() const; + MEDLOADER_EXPORT std::vector<std::string> getLocsReallyUsedMulti2() const; + MEDLOADER_EXPORT void changePflsRefsNamesGen2(const std::vector< std::pair<std::vector<std::string>, std::string > >& mapOfModif); + MEDLOADER_EXPORT void changeLocsRefsNamesGen2(const std::vector< std::pair<std::vector<std::string>, std::string > >& mapOfModif); + MEDLOADER_EXPORT void setIteration(int i, MEDCouplingAutoRefCountObjectPtr<MEDFileAnyTypeField1TSWithoutSDA> ts); + protected: + virtual med_field_type getMEDFileFieldType() const = 0; + void copyTinyInfoFrom(const MEDCouplingFieldDouble *field, const DataArray *arr); + void checkCoherencyOfTinyInfo(const MEDCouplingFieldDouble *field, const DataArray *arr) const; + void checkThatComponentsMatch(const std::vector<std::string>& compos) const; + void checkThatNbOfCompoOfTSMatchThis() const; + protected: + std::vector<std::string> _infos; + std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileAnyTypeField1TSWithoutSDA> > _time_steps; + }; + + class MEDFileIntFieldMultiTSWithoutSDA; + + class MEDFileFieldMultiTSWithoutSDA : public MEDFileAnyTypeFieldMultiTSWithoutSDA + { + public: + MEDLOADER_EXPORT static MEDFileFieldMultiTSWithoutSDA *New(med_idt fid, const std::string& fieldName, med_field_type fieldTyp, const std::vector<std::string>& infos, int nbOfStep, const std::string& dtunit, bool loadAll, const MEDFileMeshes *ms, const std::vector< std::pair<TypeOfField,INTERP_KERNEL::NormalizedCellType> > *entities); + MEDLOADER_EXPORT MEDFileFieldMultiTSWithoutSDA(med_idt fid, int fieldId, bool loadAll, const MEDFileMeshes *ms, const std::vector< std::pair<TypeOfField,INTERP_KERNEL::NormalizedCellType> > *entities); + MEDLOADER_EXPORT const char *getTypeStr() const; + MEDLOADER_EXPORT MEDFileAnyTypeFieldMultiTSWithoutSDA *shallowCpy() const; + MEDLOADER_EXPORT MEDFileAnyTypeFieldMultiTSWithoutSDA *createNew() const; + MEDLOADER_EXPORT std::vector< std::vector<DataArrayDouble *> > getFieldSplitedByType2(int iteration, int order, const std::string& mname, std::vector<INTERP_KERNEL::NormalizedCellType>& types, std::vector< std::vector<TypeOfField> >& typesF, std::vector< std::vector<std::string> >& pfls, std::vector< std::vector<std::string> >& locs) const; + MEDLOADER_EXPORT MEDFileIntFieldMultiTSWithoutSDA *convertToInt() const; + protected: + MEDFileFieldMultiTSWithoutSDA(const std::string& fieldName); + MEDFileFieldMultiTSWithoutSDA(med_idt fid, const std::string& fieldName, med_field_type fieldTyp, const std::vector<std::string>& infos, int nbOfStep, const std::string& dtunit, bool loadAll, const MEDFileMeshes *ms, const std::vector< std::pair<TypeOfField,INTERP_KERNEL::NormalizedCellType> > *entities); + med_field_type getMEDFileFieldType() const { return MED_FLOAT64; } + MEDFileAnyTypeField1TSWithoutSDA *createNew1TSWithoutSDAEmptyInstance() const; + void checkCoherencyOfType(const MEDFileAnyTypeField1TSWithoutSDA *f1ts) const; + public: + MEDLOADER_EXPORT MEDFileFieldMultiTSWithoutSDA(); + }; + + class MEDFileIntFieldMultiTSWithoutSDA : public MEDFileAnyTypeFieldMultiTSWithoutSDA + { + public: + MEDLOADER_EXPORT static MEDFileIntFieldMultiTSWithoutSDA *New(med_idt fid, const std::string& fieldName, med_field_type fieldTyp, const std::vector<std::string>& infos, int nbOfStep, const std::string& dtunit, bool loadAll, const MEDFileMeshes *ms, const std::vector< std::pair<TypeOfField,INTERP_KERNEL::NormalizedCellType> > *entities); + MEDLOADER_EXPORT MEDFileIntFieldMultiTSWithoutSDA(med_idt fid, int fieldId, bool loadAll, const MEDFileMeshes *ms, const std::vector< std::pair<TypeOfField,INTERP_KERNEL::NormalizedCellType> > *entities); + MEDLOADER_EXPORT const char *getTypeStr() const; + MEDLOADER_EXPORT MEDFileAnyTypeFieldMultiTSWithoutSDA *shallowCpy() const; + MEDLOADER_EXPORT MEDFileAnyTypeFieldMultiTSWithoutSDA *createNew() const; + MEDLOADER_EXPORT MEDFileFieldMultiTSWithoutSDA *convertToDouble() const; + protected: + MEDFileIntFieldMultiTSWithoutSDA(const std::string& fieldName); + MEDFileIntFieldMultiTSWithoutSDA(med_idt fid, const std::string& fieldName, med_field_type fieldTyp, const std::vector<std::string>& infos, int nbOfStep, const std::string& dtunit, bool loadAll, const MEDFileMeshes *ms, const std::vector< std::pair<TypeOfField,INTERP_KERNEL::NormalizedCellType> > *entities); + med_field_type getMEDFileFieldType() const { return MED_INT32; } + MEDFileAnyTypeField1TSWithoutSDA *createNew1TSWithoutSDAEmptyInstance() const; + void checkCoherencyOfType(const MEDFileAnyTypeField1TSWithoutSDA *f1ts) const; + public: + MEDLOADER_EXPORT MEDFileIntFieldMultiTSWithoutSDA(); + }; + + class MEDFileAnyTypeFieldMultiTSIterator; + class MEDFileFastCellSupportComparator; + /*! + * User class. + */ + class MEDFileAnyTypeFieldMultiTS : public RefCountObject, public MEDFileWritable, public MEDFileFieldGlobsReal + { + protected: + MEDFileAnyTypeFieldMultiTS(); + MEDFileAnyTypeFieldMultiTS(const std::string& fileName, bool loadAll, const MEDFileMeshes *ms); + MEDFileAnyTypeFieldMultiTS(const std::string& fileName, const std::string& fieldName, bool loadAll, const MEDFileMeshes *ms, const std::vector< std::pair<TypeOfField,INTERP_KERNEL::NormalizedCellType> > *entities=0); + MEDFileAnyTypeFieldMultiTS(const MEDFileAnyTypeFieldMultiTSWithoutSDA& other, bool shallowCopyOfContent); + static MEDFileAnyTypeFieldMultiTS *BuildNewInstanceFromContent(MEDFileAnyTypeFieldMultiTSWithoutSDA *c, const std::string& fileName); + static MEDFileAnyTypeFieldMultiTSWithoutSDA *BuildContentFrom(med_idt fid, const std::string& fileName, bool loadAll, const MEDFileMeshes *ms); + static MEDFileAnyTypeFieldMultiTSWithoutSDA *BuildContentFrom(med_idt fid, const std::string& fileName, const std::string& fieldName, bool loadAll, const MEDFileMeshes *ms, const std::vector< std::pair<TypeOfField,INTERP_KERNEL::NormalizedCellType> > *entities); + public: + MEDLOADER_EXPORT static MEDFileAnyTypeFieldMultiTS *New(const std::string& fileName, bool loadAll=true); + MEDLOADER_EXPORT static MEDFileAnyTypeFieldMultiTS *New(const std::string& fileName, const std::string& fieldName, bool loadAll=true); + MEDLOADER_EXPORT void loadArrays(); + MEDLOADER_EXPORT void loadArraysIfNecessary(); + MEDLOADER_EXPORT void unloadArrays(); + MEDLOADER_EXPORT void unloadArraysWithoutDataLoss(); + MEDLOADER_EXPORT void write(const std::string& fileName, int mode) const; + MEDLOADER_EXPORT void writeLL(med_idt fid) const; + MEDLOADER_EXPORT std::size_t getHeapMemorySizeWithoutChildren() const; + MEDLOADER_EXPORT std::vector<const BigMemoryObject *> getDirectChildrenWithNull() const; + MEDLOADER_EXPORT virtual MEDFileAnyTypeFieldMultiTS *deepCpy() const; + MEDLOADER_EXPORT std::vector< MEDCouplingAutoRefCountObjectPtr< MEDFileAnyTypeFieldMultiTS > > splitComponents() const; + MEDLOADER_EXPORT std::vector< MEDCouplingAutoRefCountObjectPtr< MEDFileAnyTypeFieldMultiTS > > splitDiscretizations() const; + MEDLOADER_EXPORT std::vector< MEDCouplingAutoRefCountObjectPtr< MEDFileAnyTypeFieldMultiTS > > splitMultiDiscrPerGeoTypes() const; + MEDLOADER_EXPORT virtual MEDFileAnyTypeFieldMultiTS *shallowCpy() const = 0; + MEDLOADER_EXPORT virtual void checkCoherencyOfType(const MEDFileAnyTypeField1TS *f1ts) const = 0; + // + MEDLOADER_EXPORT virtual MEDFileAnyTypeField1TS *getTimeStepAtPos(int pos) const = 0; + MEDLOADER_EXPORT MEDFileAnyTypeField1TS *getTimeStep(int iteration, int order) const; + MEDLOADER_EXPORT MEDFileAnyTypeField1TS *getTimeStepGivenTime(double time, double eps=1e-8) const; + MEDLOADER_EXPORT static std::vector< std::vector<MEDFileAnyTypeFieldMultiTS *> > SplitIntoCommonTimeSeries(const std::vector<MEDFileAnyTypeFieldMultiTS *>& vectFMTS); + MEDLOADER_EXPORT static std::vector< std::vector<MEDFileAnyTypeFieldMultiTS *> > SplitPerCommonSupport(const std::vector<MEDFileAnyTypeFieldMultiTS *>& vectFMTS, const MEDFileMesh *mesh, std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileFastCellSupportComparator> >& fsc); + MEDLOADER_EXPORT static int CheckSupportAcrossTime(MEDFileAnyTypeFieldMultiTS *f0, MEDFileAnyTypeFieldMultiTS *f1, const MEDFileMesh *mesh, TypeOfField& tof0, TypeOfField& tof1); + public:// direct forwarding to MEDFileField1TSWithoutSDA instance _content + MEDLOADER_EXPORT std::string getName() const; + MEDLOADER_EXPORT void setName(const std::string& name); + MEDLOADER_EXPORT std::string getDtUnit() const; + MEDLOADER_EXPORT void setDtUnit(const std::string& dtUnit); + MEDLOADER_EXPORT std::string getMeshName() const; + MEDLOADER_EXPORT void setMeshName(const std::string& newMeshName); + MEDLOADER_EXPORT std::string simpleRepr() const; + MEDLOADER_EXPORT void simpleRepr(int bkOffset, std::ostream& oss, int fmtsId) const; + MEDLOADER_EXPORT int getNumberOfTS() const; + MEDLOADER_EXPORT void eraseEmptyTS(); + MEDLOADER_EXPORT void eraseTimeStepIds(const int *startIds, const int *endIds); + MEDLOADER_EXPORT void eraseTimeStepIds2(int bg, int end, int step); + MEDLOADER_EXPORT MEDFileAnyTypeFieldMultiTS *buildSubPart(const int *startIds, const int *endIds) const; + MEDLOADER_EXPORT MEDFileAnyTypeFieldMultiTS *buildSubPartSlice(int bg, int end, int step) const; + MEDLOADER_EXPORT std::vector< std::pair<int,int> > getTimeSteps(std::vector<double>& ret1) const; + MEDLOADER_EXPORT std::vector< std::pair<int,int> > getIterations() const; + MEDLOADER_EXPORT void pushBackTimeSteps(const std::vector<MEDFileAnyTypeField1TS *>& f1ts); + MEDLOADER_EXPORT void pushBackTimeSteps(MEDFileAnyTypeFieldMultiTS *fmts); + MEDLOADER_EXPORT void pushBackTimeStep(MEDFileAnyTypeField1TS *f1ts); + MEDLOADER_EXPORT void synchronizeNameScope(); + MEDLOADER_EXPORT int getPosOfTimeStep(int iteration, int order) const; + MEDLOADER_EXPORT int getPosGivenTime(double time, double eps=1e-8) const; + MEDLOADER_EXPORT MEDFileAnyTypeFieldMultiTSIterator *iterator(); + MEDLOADER_EXPORT bool changeMeshNames(const std::vector< std::pair<std::string,std::string> >& modifTab); + MEDLOADER_EXPORT const std::vector<std::string>& getInfo() const; + MEDLOADER_EXPORT bool presenceOfMultiDiscPerGeoType() const; + MEDLOADER_EXPORT void setInfo(const std::vector<std::string>& info); + MEDLOADER_EXPORT int getNumberOfComponents() const; + MEDLOADER_EXPORT int getNonEmptyLevels(int iteration, int order, const std::string& mname, std::vector<int>& levs) const; + MEDLOADER_EXPORT std::vector< std::vector<TypeOfField> > getTypesOfFieldAvailable() const; + MEDLOADER_EXPORT std::vector< std::vector< std::pair<int,int> > > getFieldSplitedByType(int iteration, int order, const std::string& mname, std::vector<INTERP_KERNEL::NormalizedCellType>& types, std::vector< std::vector<TypeOfField> >& typesF, std::vector< std::vector<std::string> >& pfls, std::vector< std::vector<std::string> >& locs) const; + MEDLOADER_EXPORT MEDCouplingAutoRefCountObjectPtr<MEDFileAnyTypeFieldMultiTSWithoutSDA> getContent(); + public: + MEDLOADER_EXPORT std::vector<std::string> getPflsReallyUsed() const; + MEDLOADER_EXPORT std::vector<std::string> getLocsReallyUsed() const; + MEDLOADER_EXPORT std::vector<std::string> getPflsReallyUsedMulti() const; + MEDLOADER_EXPORT std::vector<std::string> getLocsReallyUsedMulti() const; + MEDLOADER_EXPORT void changePflsRefsNamesGen(const std::vector< std::pair<std::vector<std::string>, std::string > >& mapOfModif); + MEDLOADER_EXPORT void changeLocsRefsNamesGen(const std::vector< std::pair<std::vector<std::string>, std::string > >& mapOfModif); + protected: + MEDFileAnyTypeFieldMultiTSWithoutSDA *contentNotNullBase(); + const MEDFileAnyTypeFieldMultiTSWithoutSDA *contentNotNullBase() const; + private: + static std::vector< std::vector<MEDFileAnyTypeFieldMultiTS *> > SplitPerCommonSupportNotNodesAlg(const std::vector<MEDFileAnyTypeFieldMultiTS *>& vectFMTS, const MEDFileMesh *mesh, std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileFastCellSupportComparator> >& cmps); + protected: + MEDCouplingAutoRefCountObjectPtr<MEDFileAnyTypeFieldMultiTSWithoutSDA> _content; + }; + + class MEDFileIntFieldMultiTS; + + /*! + * User class. + */ + class MEDFileFieldMultiTS : public MEDFileAnyTypeFieldMultiTS + { + public: + MEDLOADER_EXPORT static MEDFileFieldMultiTS *New(); + MEDLOADER_EXPORT static MEDFileFieldMultiTS *New(const std::string& fileName, bool loadAll=true); + MEDLOADER_EXPORT static MEDFileFieldMultiTS *New(const std::string& fileName, const std::string& fieldName, bool loadAll=true); + MEDLOADER_EXPORT static MEDFileFieldMultiTS *New(const MEDFileFieldMultiTSWithoutSDA& other, bool shallowCopyOfContent); + MEDLOADER_EXPORT static MEDFileFieldMultiTS *LoadSpecificEntities(const std::string& fileName, const std::string& fieldName, const std::vector< std::pair<TypeOfField,INTERP_KERNEL::NormalizedCellType> >& entities, bool loadAll=true); + MEDLOADER_EXPORT MEDFileAnyTypeFieldMultiTS *shallowCpy() const; + MEDLOADER_EXPORT void checkCoherencyOfType(const MEDFileAnyTypeField1TS *f1ts) const; + MEDLOADER_EXPORT MEDFileIntFieldMultiTS *convertToInt(bool isDeepCpyGlobs=true) const; + // + MEDLOADER_EXPORT MEDFileAnyTypeField1TS *getTimeStepAtPos(int pos) const; + MEDLOADER_EXPORT MEDFileAnyTypeField1TS *getTimeStep(int iteration, int order) const; + MEDLOADER_EXPORT MEDFileAnyTypeField1TS *getTimeStepGivenTime(double time, double eps=1e-8) const; + // + MEDLOADER_EXPORT MEDCouplingFieldDouble *getFieldAtLevel(TypeOfField type, int iteration, int order, int meshDimRelToMax, int renumPol=0) const; + MEDLOADER_EXPORT MEDCouplingFieldDouble *getFieldAtTopLevel(TypeOfField type, int iteration, int order, int renumPol=0) const; + MEDLOADER_EXPORT MEDCouplingFieldDouble *getFieldOnMeshAtLevel(TypeOfField type, int iteration, int order, int meshDimRelToMax, const MEDFileMesh *mesh, int renumPol=0) const; + MEDLOADER_EXPORT MEDCouplingFieldDouble *getFieldOnMeshAtLevel(TypeOfField type, int iteration, int order, const MEDCouplingMesh *mesh, int renumPol=0) const; + MEDLOADER_EXPORT MEDCouplingFieldDouble *getFieldAtLevelOld(TypeOfField type, const std::string& mname, int iteration, int order, int meshDimRelToMax, int renumPol=0) const; + MEDLOADER_EXPORT DataArrayDouble *getFieldWithProfile(TypeOfField type, int iteration, int order, int meshDimRelToMax, const MEDFileMesh *mesh, DataArrayInt *&pfl) const; + // + MEDLOADER_EXPORT void appendFieldNoProfileSBT(const MEDCouplingFieldDouble *field); + MEDLOADER_EXPORT void appendFieldProfile(const MEDCouplingFieldDouble *field, const MEDFileMesh *mesh, int meshDimRelToMax, const DataArrayInt *profile); + MEDLOADER_EXPORT std::vector< std::vector<DataArrayDouble *> > getFieldSplitedByType2(int iteration, int order, const std::string& mname, std::vector<INTERP_KERNEL::NormalizedCellType>& types, std::vector< std::vector<TypeOfField> >& typesF, std::vector< std::vector<std::string> >& pfls, std::vector< std::vector<std::string> >& locs) const; + MEDLOADER_EXPORT DataArrayDouble *getUndergroundDataArray(int iteration, int order) const; + MEDLOADER_EXPORT DataArrayDouble *getUndergroundDataArrayExt(int iteration, int order, std::vector< std::pair<std::pair<INTERP_KERNEL::NormalizedCellType,int>,std::pair<int,int> > >& entries) const; + private: + const MEDFileFieldMultiTSWithoutSDA *contentNotNull() const; + MEDFileFieldMultiTSWithoutSDA *contentNotNull(); + private: + ~MEDFileFieldMultiTS() { } + MEDFileFieldMultiTS(); + MEDFileFieldMultiTS(const MEDFileFieldMultiTSWithoutSDA& other, bool shallowCopyOfContent); + MEDFileFieldMultiTS(const std::string& fileName, bool loadAll, const MEDFileMeshes *ms); + MEDFileFieldMultiTS(const std::string& fileName, const std::string& fieldName, bool loadAll, const MEDFileMeshes *ms, const std::vector< std::pair<TypeOfField,INTERP_KERNEL::NormalizedCellType> > *entities=0); + }; + + /*! + * User class. + */ + class MEDFileIntFieldMultiTS : public MEDFileAnyTypeFieldMultiTS + { + public: + MEDLOADER_EXPORT static MEDFileIntFieldMultiTS *New(); + MEDLOADER_EXPORT static MEDFileIntFieldMultiTS *New(const std::string& fileName, bool loadAll=true); + MEDLOADER_EXPORT static MEDFileIntFieldMultiTS *New(const std::string& fileName, const std::string& fieldName, bool loadAll=true); + MEDLOADER_EXPORT static MEDFileIntFieldMultiTS *New(const MEDFileIntFieldMultiTSWithoutSDA& other, bool shallowCopyOfContent); + MEDLOADER_EXPORT static MEDFileIntFieldMultiTS *LoadSpecificEntities(const std::string& fileName, const std::string& fieldName, const std::vector< std::pair<TypeOfField,INTERP_KERNEL::NormalizedCellType> >& entities, bool loadAll=true); + MEDLOADER_EXPORT MEDFileAnyTypeFieldMultiTS *shallowCpy() const; + MEDLOADER_EXPORT void checkCoherencyOfType(const MEDFileAnyTypeField1TS *f1ts) const; + MEDLOADER_EXPORT MEDFileAnyTypeField1TS *getTimeStepAtPos(int pos) const; + MEDLOADER_EXPORT MEDFileFieldMultiTS *convertToDouble(bool isDeepCpyGlobs=true) const; + // + MEDLOADER_EXPORT MEDCouplingFieldDouble *getFieldAtLevel(TypeOfField type, int iteration, int order, int meshDimRelToMax, DataArrayInt* &arrOut, int renumPol=0) const; + MEDLOADER_EXPORT MEDCouplingFieldDouble *getFieldAtTopLevel(TypeOfField type, int iteration, int order, DataArrayInt* &arrOut, int renumPol=0) const; + MEDLOADER_EXPORT MEDCouplingFieldDouble *getFieldOnMeshAtLevel(TypeOfField type, int iteration, int order, int meshDimRelToMax, const MEDFileMesh *mesh, DataArrayInt* &arrOut, int renumPol=0) const; + MEDLOADER_EXPORT MEDCouplingFieldDouble *getFieldOnMeshAtLevel(TypeOfField type, int iteration, int order, const MEDCouplingMesh *mesh, DataArrayInt* &arrOut, int renumPol=0) const; + MEDLOADER_EXPORT MEDCouplingFieldDouble *getFieldAtLevelOld(TypeOfField type, int iteration, int order, const std::string& mname, int meshDimRelToMax, DataArrayInt* &arrOut, int renumPol=0) const; + MEDLOADER_EXPORT DataArrayInt *getFieldWithProfile(TypeOfField type, int iteration, int order, int meshDimRelToMax, const MEDFileMesh *mesh, DataArrayInt *&pfl) const; + // + MEDLOADER_EXPORT void appendFieldNoProfileSBT(const MEDCouplingFieldDouble *field, const DataArrayInt *arrOfVals); + MEDLOADER_EXPORT void appendFieldProfile(const MEDCouplingFieldDouble *field, const DataArrayInt *arrOfVals, const MEDFileMesh *mesh, int meshDimRelToMax, const DataArrayInt *profile); + // + MEDLOADER_EXPORT DataArrayInt *getUndergroundDataArray(int iteration, int order) const; + private: + const MEDFileIntFieldMultiTSWithoutSDA *contentNotNull() const; + MEDFileIntFieldMultiTSWithoutSDA *contentNotNull(); + private: + ~MEDFileIntFieldMultiTS() { } + MEDFileIntFieldMultiTS(); + MEDFileIntFieldMultiTS(const MEDFileIntFieldMultiTSWithoutSDA& other, bool shallowCopyOfContent); + MEDFileIntFieldMultiTS(const std::string& fileName, bool loadAll, const MEDFileMeshes *ms); + MEDFileIntFieldMultiTS(const std::string& fileName, const std::string& fieldName, bool loadAll, const MEDFileMeshes *ms, const std::vector< std::pair<TypeOfField,INTERP_KERNEL::NormalizedCellType> > *entities=0); + }; + + class MEDFileAnyTypeFieldMultiTSIterator + { + public: + MEDLOADER_EXPORT MEDFileAnyTypeFieldMultiTSIterator(MEDFileAnyTypeFieldMultiTS *fmts); + MEDLOADER_EXPORT ~MEDFileAnyTypeFieldMultiTSIterator(); + MEDLOADER_EXPORT MEDFileAnyTypeField1TS *nextt(); + private: + MEDCouplingAutoRefCountObjectPtr<MEDFileAnyTypeFieldMultiTS> _fmts; + int _iter_id; + int _nb_iter; + }; + + class MEDFileFieldsIterator; + + /*! + * Use class. + */ + class MEDFileFields : public RefCountObject, public MEDFileFieldGlobsReal, public MEDFileWritable + { + public: + MEDLOADER_EXPORT static MEDFileFields *New(); + MEDLOADER_EXPORT static MEDFileFields *New(const std::string& fileName, bool loadAll=true); + MEDLOADER_EXPORT static MEDFileFields *LoadPartOf(const std::string& fileName, bool loadAll=true, const MEDFileMeshes *ms=0); + MEDLOADER_EXPORT static MEDFileFields *LoadSpecificEntities(const std::string& fileName, const std::vector< std::pair<TypeOfField,INTERP_KERNEL::NormalizedCellType> >& entities, bool loadAll=true); + MEDLOADER_EXPORT std::size_t getHeapMemorySizeWithoutChildren() const; + MEDLOADER_EXPORT std::vector<const BigMemoryObject *> getDirectChildrenWithNull() const; + MEDLOADER_EXPORT MEDFileFields *deepCpy() const; + MEDLOADER_EXPORT MEDFileFields *shallowCpy() const; + MEDLOADER_EXPORT void write(const std::string& fileName, int mode) const; + MEDLOADER_EXPORT void writeLL(med_idt fid) const; + MEDLOADER_EXPORT void loadArrays(); + MEDLOADER_EXPORT void loadArraysIfNecessary(); + MEDLOADER_EXPORT void unloadArrays(); + MEDLOADER_EXPORT void unloadArraysWithoutDataLoss(); + MEDLOADER_EXPORT int getNumberOfFields() const; + MEDLOADER_EXPORT std::vector< std::pair<int,int> > getCommonIterations(bool& areThereSomeForgottenTS) const; + MEDLOADER_EXPORT std::vector<std::string> getFieldsNames() const; + MEDLOADER_EXPORT std::vector<std::string> getMeshesNames() const; + MEDLOADER_EXPORT std::string simpleRepr() const; + MEDLOADER_EXPORT void simpleRepr(int bkOffset, std::ostream& oss) const; + // + MEDLOADER_EXPORT void resize(int newSize); + MEDLOADER_EXPORT void pushField(MEDFileAnyTypeFieldMultiTS *field); + MEDLOADER_EXPORT void pushFields(const std::vector<MEDFileAnyTypeFieldMultiTS *>& fields); + MEDLOADER_EXPORT void setFieldAtPos(int i, MEDFileAnyTypeFieldMultiTS *field); + MEDLOADER_EXPORT int getPosFromFieldName(const std::string& fieldName) const; + MEDLOADER_EXPORT MEDFileAnyTypeFieldMultiTS *getFieldAtPos(int i) const; + MEDLOADER_EXPORT MEDFileAnyTypeFieldMultiTS *getFieldWithName(const std::string& fieldName) const; + MEDLOADER_EXPORT MEDFileFields *buildSubPart(const int *startIds, const int *endIds) const; + MEDLOADER_EXPORT bool removeFieldsWithoutAnyTimeStep(); + MEDLOADER_EXPORT MEDFileFields *partOfThisLyingOnSpecifiedMeshName(const std::string& meshName) const; + MEDLOADER_EXPORT MEDFileFields *partOfThisLyingOnSpecifiedTimeSteps(const std::vector< std::pair<int,int> >& timeSteps) const; + MEDLOADER_EXPORT MEDFileFields *partOfThisNotLyingOnSpecifiedTimeSteps(const std::vector< std::pair<int,int> >& timeSteps) const; + MEDLOADER_EXPORT MEDFileFieldsIterator *iterator(); + MEDLOADER_EXPORT void destroyFieldAtPos(int i); + MEDLOADER_EXPORT void destroyFieldsAtPos(const int *startIds, const int *endIds); + MEDLOADER_EXPORT void destroyFieldsAtPos2(int bg, int end, int step); + MEDLOADER_EXPORT bool changeMeshNames(const std::vector< std::pair<std::string,std::string> >& modifTab); + MEDLOADER_EXPORT bool renumberEntitiesLyingOnMesh(const std::string& meshName, const std::vector<int>& oldCode, const std::vector<int>& newCode, const DataArrayInt *renumO2N); + public: + MEDLOADER_EXPORT std::vector<std::string> getPflsReallyUsed() const; + MEDLOADER_EXPORT std::vector<std::string> getLocsReallyUsed() const; + MEDLOADER_EXPORT std::vector<std::string> getPflsReallyUsedMulti() const; + MEDLOADER_EXPORT std::vector<std::string> getLocsReallyUsedMulti() const; + MEDLOADER_EXPORT void changePflsRefsNamesGen(const std::vector< std::pair<std::vector<std::string>, std::string > >& mapOfModif); + MEDLOADER_EXPORT void changeLocsRefsNamesGen(const std::vector< std::pair<std::vector<std::string>, std::string > >& mapOfModif); + private: + ~MEDFileFields() { } + MEDFileFields(); + MEDFileFields(const std::string& fileName, bool loadAll, const MEDFileMeshes *ms, const std::vector< std::pair<TypeOfField,INTERP_KERNEL::NormalizedCellType> > *entities); + private: + std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileAnyTypeFieldMultiTSWithoutSDA> > _fields; + }; + + class MEDFileFieldsIterator + { + public: + MEDLOADER_EXPORT MEDFileFieldsIterator(MEDFileFields *fs); + MEDLOADER_EXPORT ~MEDFileFieldsIterator(); + MEDLOADER_EXPORT MEDFileAnyTypeFieldMultiTS *nextt(); + private: + MEDCouplingAutoRefCountObjectPtr<MEDFileFields> _fs; + int _iter_id; + int _nb_iter; + }; +} + +#endif diff --git a/src/medtool/src/MEDLoader/MEDFileFieldOverView.cxx b/src/medtool/src/MEDLoader/MEDFileFieldOverView.cxx new file mode 100644 index 000000000..4f0367cb2 --- /dev/null +++ b/src/medtool/src/MEDLoader/MEDFileFieldOverView.cxx @@ -0,0 +1,2427 @@ +// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 +// 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 "MEDFileFieldOverView.hxx" +#include "MEDFileField.hxx" +#include "MEDFileMesh.hxx" + +#include "MEDCouplingFieldDiscretization.hxx" +#include "CellModel.hxx" + +using namespace ParaMEDMEM; + +const unsigned char MEDMeshMultiLev::PARAMEDMEM_2_VTKTYPE[MEDMeshMultiLev::PARAMEDMEM_2_VTKTYPE_LGTH]= +{1,3,21,5,9,7,22,34,23,28,255,255,255,255,10,14,13,255,12,255,24,255,16,27,255,26,255,29,255,255,25,42,36,4}; + +const unsigned char MEDMeshMultiLev::HEXA27_PERM_ARRAY[27]={0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,24,22,21,23,20,25,26}; + +const char MEDFileField1TSStructItem2::NEWLY_CREATED_PFL_NAME[]="???"; + +MEDFileMeshStruct *MEDFileMeshStruct::New(const MEDFileMesh *mesh) +{ + return new MEDFileMeshStruct(mesh); +} + +std::size_t MEDFileMeshStruct::getHeapMemorySizeWithoutChildren() const +{ + std::size_t ret(0); + for(std::vector< std::vector<int> >::const_iterator it0=_geo_types_distrib.begin();it0!=_geo_types_distrib.end();it0++) + ret+=(*it0).capacity()*sizeof(int); + ret+=_geo_types_distrib.capacity()*sizeof(std::vector<int>); + return ret; +} + +std::vector<const BigMemoryObject *> MEDFileMeshStruct::getDirectChildrenWithNull() const +{ + return std::vector<const BigMemoryObject *>(); +} + +MEDFileMeshStruct::MEDFileMeshStruct(const MEDFileMesh *mesh):_mesh(mesh) +{ + std::vector<int> levs(mesh->getNonEmptyLevels()); + _name=mesh->getName(); + _nb_nodes=mesh->getNumberOfNodes(); + if(!levs.empty()) + { + _geo_types_distrib.resize(-(*std::min_element(levs.begin(),levs.end()))+1); + for(std::vector<int>::const_iterator lev=levs.begin();lev!=levs.end();lev++) + _geo_types_distrib[-(*lev)]=mesh->getDistributionOfTypes(*lev); + } +} + +int MEDFileMeshStruct::getLevelOfGeoType(INTERP_KERNEL::NormalizedCellType t) const +{ + int j=0; + for(std::vector< std::vector<int> >::const_iterator it1=_geo_types_distrib.begin();it1!=_geo_types_distrib.end();it1++,j--) + { + std::size_t sz=(*it1).size(); + if(sz%3!=0) + throw INTERP_KERNEL::Exception("MEDFileMeshStruct::getLevelOfGeoType : internal error in code !"); + std::size_t nbGeo=sz/3; + for(std::size_t i=0;i<nbGeo;i++) + if((*it1)[3*i]==(int)t) + return j; + } + throw INTERP_KERNEL::Exception("MEDFileMeshStruct::getLevelOfGeoType : The specified geometric type is not present in the mesh structure !"); +} + +/*! + * \sa MEDFileMeshStruct::doesManageGeoType + */ +int MEDFileMeshStruct::getNumberOfElemsOfGeoType(INTERP_KERNEL::NormalizedCellType t) const +{ + for(std::vector< std::vector<int> >::const_iterator it1=_geo_types_distrib.begin();it1!=_geo_types_distrib.end();it1++) + { + std::size_t sz=(*it1).size(); + if(sz%3!=0) + throw INTERP_KERNEL::Exception("MEDFileMeshStruct::getNumberOfElemsOfGeoType : internal error in code !"); + std::size_t nbGeo=sz/3; + for(std::size_t i=0;i<nbGeo;i++) + if((*it1)[3*i]==(int)t) + return (*it1)[3*i+1]; + } + throw INTERP_KERNEL::Exception("The specified geometric type is not present in the mesh structure !"); +} + +/*! + * \sa MEDFileMeshStruct::getNumberOfElemsOfGeoType + */ +bool MEDFileMeshStruct::doesManageGeoType(INTERP_KERNEL::NormalizedCellType t) const +{ + for(std::vector< std::vector<int> >::const_iterator it1=_geo_types_distrib.begin();it1!=_geo_types_distrib.end();it1++) + { + std::size_t sz=(*it1).size(); + if(sz%3!=0) + throw INTERP_KERNEL::Exception("MEDFileMeshStruct::doesManageGeoType : internal error in code !"); + std::size_t nbGeo=sz/3; + for(std::size_t i=0;i<nbGeo;i++) + if((*it1)[3*i]==(int)t) + return true; + } + return false; +} + +void MEDFileMeshStruct::appendIfImplicitType(INTERP_KERNEL::NormalizedCellType t) +{ + if(!_mesh->hasImplicitPart()) + throw INTERP_KERNEL::Exception("MEDFileMeshStruct::appendIfImplicitType : by default no implicit geo type can be appended !"); + static const char MSG[]="MEDFileMeshStruct::appendIfImplicitType : the distribution does not looks like structured standard !"; + if(_geo_types_distrib.size()!=1) + throw INTERP_KERNEL::Exception(MSG); + std::size_t sz(_geo_types_distrib[0].size()); + if(sz%3!=0) + throw INTERP_KERNEL::Exception("MEDFileMeshStruct::appendIfImplicitType : internal error in code !"); + std::size_t nbGeo(sz/3); + if(nbGeo!=1) + throw INTERP_KERNEL::Exception(MSG); + std::vector<int> arr(3); arr[0]=(int)t; arr[1]=_mesh->buildImplicitPartIfAny(t); arr[2]=-1; + _geo_types_distrib.push_back(arr); +} + + +int MEDFileMeshStruct::getNumberOfLevs() const +{ + return (int)_geo_types_distrib.size(); +} + +int MEDFileMeshStruct::getNumberOfGeoTypesInLev(int relativeLev) const +{ + int pos(-relativeLev); + if(pos<0 || pos>=(int)_geo_types_distrib.size()) + throw INTERP_KERNEL::Exception("MEDFileMeshStruct::getNumberOfGeoTypesInLev : invalid level specified !"); + std::size_t sz=_geo_types_distrib[pos].size(); + if(sz%3!=0) + throw INTERP_KERNEL::Exception("MEDFileMeshStruct::getNumberOfGeoTypesInLev : internal error in code !"); + return (int)(sz/3); +} + +//= + +std::size_t MEDMeshMultiLev::getHeapMemorySizeWithoutChildren() const +{ + return 0; +} + +std::vector<const BigMemoryObject *> MEDMeshMultiLev::getDirectChildrenWithNull() const +{ + return std::vector<const BigMemoryObject *>(); +} + +MEDMeshMultiLev *MEDMeshMultiLev::New(const MEDFileMesh *m, const std::vector<int>& levs) +{ + if(!m) + throw INTERP_KERNEL::Exception("MEDMeshMultiLev::New : null input pointer !"); + const MEDFileUMesh *um(dynamic_cast<const MEDFileUMesh *>(m)); + if(um) + return MEDUMeshMultiLev::New(um,levs); + const MEDFileCMesh *cm(dynamic_cast<const MEDFileCMesh *>(m)); + if(cm) + return MEDCMeshMultiLev::New(cm,levs); + const MEDFileCurveLinearMesh *clm(dynamic_cast<const MEDFileCurveLinearMesh *>(m)); + if(clm) + return MEDCurveLinearMeshMultiLev::New(clm,levs); + throw INTERP_KERNEL::Exception("MEDMeshMultiLev::New : unrecognized type of mesh ! Must be in [MEDFileUMesh,MEDFileCMesh,MEDFileCurveLinearMesh] !"); +} + +MEDMeshMultiLev *MEDMeshMultiLev::New(const MEDFileMesh *m, const std::vector<INTERP_KERNEL::NormalizedCellType>& gts, const std::vector<const DataArrayInt *>& pfls, const std::vector<int>& nbEntities) +{ + if(!m) + throw INTERP_KERNEL::Exception("MEDMeshMultiLev::New 2 : null input pointer !"); + const MEDFileUMesh *um(dynamic_cast<const MEDFileUMesh *>(m)); + if(um) + return MEDUMeshMultiLev::New(um,gts,pfls,nbEntities); + const MEDFileCMesh *cm(dynamic_cast<const MEDFileCMesh *>(m)); + if(cm) + return MEDCMeshMultiLev::New(cm,gts,pfls,nbEntities); + const MEDFileCurveLinearMesh *clm(dynamic_cast<const MEDFileCurveLinearMesh *>(m)); + if(clm) + return MEDCurveLinearMeshMultiLev::New(clm,gts,pfls,nbEntities); + throw INTERP_KERNEL::Exception("MEDMeshMultiLev::New 2 : unrecognized type of mesh ! Must be in [MEDFileUMesh,MEDFileCMesh,MEDFileCurveLinearMesh] !"); +} + +MEDMeshMultiLev *MEDMeshMultiLev::NewOnlyOnNode(const MEDFileMesh *m, const DataArrayInt *pflOnNode) +{ + MEDCouplingAutoRefCountObjectPtr<MEDMeshMultiLev> ret(MEDMeshMultiLev::New(m,m->getNonEmptyLevels())); + ret->selectPartOfNodes(pflOnNode); + return ret.retn(); +} + +void MEDMeshMultiLev::setNodeReduction(const DataArrayInt *nr) +{ + if(nr) + nr->incrRef(); + _node_reduction=const_cast<DataArrayInt*>(nr); +} + +void MEDMeshMultiLev::setCellReduction(const DataArrayInt *cr) +{ + if(_pfls.size()!=1) + throw INTERP_KERNEL::Exception("MEDMeshMultiLev::setCellReduction : can be used only for single geo type mesh !"); + _pfls[0]=const_cast<DataArrayInt*>(cr); + if(cr) + cr->incrRef(); +} + +bool MEDMeshMultiLev::isFastlyTheSameStruct(const MEDFileField1TSStructItem& fst, const MEDFileFieldGlobsReal *globs) const +{ + if(fst.getType()==ON_NODES) + { + if(fst.getNumberOfItems()!=1) + throw INTERP_KERNEL::Exception("MEDMeshMultiLev::isFastlyTheSameStruct : unexpected situation for nodes !"); + const MEDFileField1TSStructItem2& p(fst[0]); + std::string pflName(p.getPflName()); + const DataArrayInt *nr(_node_reduction); + if(pflName.empty() && !nr) + return true; + if(!pflName.empty() && !nr) + return false; + if(pflName==nr->getName()) + return true; + return false; + } + else + { + std::size_t sz(fst.getNumberOfItems()); + if(sz!=_geo_types.size()) + return false; + int strt(0); + for(std::size_t i=0;i<sz;i++) + { + const MEDFileField1TSStructItem2& p(fst[i]); + if(!p.isFastlyEqual(strt,_geo_types[i],getPflNameOfId(i).c_str())) + return false; + } + return true; + } +} + +DataArray *MEDMeshMultiLev::buildDataArray(const MEDFileField1TSStructItem& fst, const MEDFileFieldGlobsReal *globs, const DataArray *vals) const +{ + MEDCouplingAutoRefCountObjectPtr<DataArray> ret(const_cast<DataArray *>(vals)); ret->incrRef(); + if(isFastlyTheSameStruct(fst,globs)) + return ret.retn(); + else + return constructDataArray(fst,globs,vals); +} + +/*! + * \param [out] famIds - Can be null. If not null the instance has to be dealt by the caller (decrRef). + * \param [out] isWithoutCopy - When true the returned instance \a famIds if not null is directly those in the data structure. + */ +void MEDMeshMultiLev::retrieveFamilyIdsOnCells(DataArrayInt *& famIds, bool& isWithoutCopy) const +{ + const DataArrayInt *fids(_cell_fam_ids); + if(!fids) + { famIds=0; isWithoutCopy=true; return ; } + std::size_t sz(_geo_types.size()); + bool presenceOfPfls(false); + for(std::size_t i=0;i<sz && !presenceOfPfls;i++) + { + const DataArrayInt *pfl(_pfls[i]); + if(pfl) + presenceOfPfls=true; + } + if(!presenceOfPfls) + { famIds=const_cast<DataArrayInt *>(fids); famIds->incrRef(); isWithoutCopy=_mesh->isObjectInTheProgeny(famIds); return ; } + //bad luck the slowest part + isWithoutCopy=false; + std::vector< MEDCouplingAutoRefCountObjectPtr<DataArrayInt> > retSafe(sz); + std::vector< const DataArrayInt *> ret(sz); + int start(0); + for(std::size_t i=0;i<sz;i++) + { + const DataArrayInt *pfl(_pfls[i]); + int lgth(_nb_entities[i]); + if(pfl) + { + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> tmp(fids->selectByTupleId2(start,start+lgth,1)); + retSafe[i]=tmp->selectByTupleIdSafe(pfl->begin(),pfl->end()); + } + else + { + retSafe[i]=fids->selectByTupleId2(start,start+lgth,1); + } + ret[i]=retSafe[i]; + start+=lgth; + } + famIds=DataArrayInt::Aggregate(ret); +} + +/*! + * \param [out] numIds - Can be null. If not null the instance has to be dealt by the caller (decrRef). + * \param [out] isWithoutCopy - When true the returned instance \a numIds if not null is directly those in the data structure. + */ +void MEDMeshMultiLev::retrieveNumberIdsOnCells(DataArrayInt *& numIds, bool& isWithoutCopy) const +{ + const DataArrayInt *nids(_cell_num_ids); + if(!nids) + { numIds=0; isWithoutCopy=true; return ; } + std::size_t sz(_geo_types.size()); + bool presenceOfPfls(false); + for(std::size_t i=0;i<sz && !presenceOfPfls;i++) + { + const DataArrayInt *pfl(_pfls[i]); + if(pfl) + presenceOfPfls=true; + } + if(!presenceOfPfls) + { numIds=const_cast<DataArrayInt *>(nids); numIds->incrRef(); isWithoutCopy=_mesh->isObjectInTheProgeny(numIds); return ; } + //bad luck the slowest part + isWithoutCopy=false; + std::vector< MEDCouplingAutoRefCountObjectPtr<DataArrayInt> > retSafe(sz); + std::vector< const DataArrayInt *> ret(sz); + int start(0); + for(std::size_t i=0;i<sz;i++) + { + const DataArrayInt *pfl(_pfls[i]); + int lgth(_nb_entities[i]); + if(pfl) + { + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> tmp(nids->selectByTupleId2(start,start+lgth,1)); + retSafe[i]=tmp->selectByTupleIdSafe(pfl->begin(),pfl->end()); + } + else + { + retSafe[i]=nids->selectByTupleId2(start,start+lgth,1); + } + ret[i]=retSafe[i]; + start+=lgth; + } + numIds=DataArrayInt::Aggregate(ret); +} + +/*! + * \param [out] famIds - Can be null. If not null the instance has to be dealt by the caller (decrRef). + * \param [out] isWithoutCopy - When true the returned instance \a famIds if not null is directly those in the data structure. + */ +void MEDMeshMultiLev::retrieveFamilyIdsOnNodes(DataArrayInt *& famIds, bool& isWithoutCopy) const +{ + const DataArrayInt *fids(_node_fam_ids); + if(!fids) + { famIds=0; isWithoutCopy=true; return ; } + const DataArrayInt *nr(_node_reduction); + if(nr) + { + isWithoutCopy=false; + famIds=fids->selectByTupleIdSafe(nr->begin(),nr->end()); + } + else + { + famIds=const_cast<DataArrayInt *>(fids); famIds->incrRef(); + isWithoutCopy=_mesh->isObjectInTheProgeny(famIds); + } +} + +/*! + * \param [out] numIds - Can be null. If not null the instance has to be dealt by the caller (decrRef). + * \param [out] isWithoutCopy - When true the returned instance \a numIds if not null is directly those in the data structure. + */ +void MEDMeshMultiLev::retrieveNumberIdsOnNodes(DataArrayInt *& numIds, bool& isWithoutCopy) const +{ + const DataArrayInt *fids(_node_num_ids); + if(!fids) + { numIds=0; isWithoutCopy=true; return ; } + const DataArrayInt *nr(_node_reduction); + if(nr) + { + isWithoutCopy=false; + numIds=fids->selectByTupleIdSafe(nr->begin(),nr->end()); + } + else + { + numIds=const_cast<DataArrayInt *>(fids); numIds->incrRef(); + isWithoutCopy=_mesh->isObjectInTheProgeny(numIds); + } +} + +std::vector< INTERP_KERNEL::NormalizedCellType > MEDMeshMultiLev::getGeoTypes() const +{ + return _geo_types; +} + +void MEDMeshMultiLev::setFamilyIdsOnCells(DataArrayInt *famIds) +{ + _cell_fam_ids=famIds; + if(famIds) + famIds->incrRef(); +} + +void MEDMeshMultiLev::setNumberIdsOnCells(DataArrayInt *numIds) +{ + _cell_num_ids=numIds; + if(numIds) + numIds->incrRef(); +} + +void MEDMeshMultiLev::setFamilyIdsOnNodes(DataArrayInt *famIds) +{ + _node_fam_ids=famIds; + if(famIds) + famIds->incrRef(); +} + +void MEDMeshMultiLev::setNumberIdsOnNodes(DataArrayInt *numIds) +{ + _node_num_ids=numIds; + if(numIds) + numIds->incrRef(); +} + +std::string MEDMeshMultiLev::getPflNameOfId(int id) const +{ + std::size_t sz(_pfls.size()); + if(id<0 || id>=(int)sz) + throw INTERP_KERNEL::Exception("MEDMeshMultiLev::getPflNameOfId : invalid input id !"); + const DataArrayInt *pfl(_pfls[id]); + if(!pfl) + return std::string(""); + return pfl->getName(); +} + +/*! + * Returns the number of cells having geometric type \a t. + * The profiles are **NOT** taken into account here. + */ +int MEDMeshMultiLev::getNumberOfCells(INTERP_KERNEL::NormalizedCellType t) const +{ + std::size_t sz(_nb_entities.size()); + for(std::size_t i=0;i<sz;i++) + if(_geo_types[i]==t) + return _nb_entities[i]; + throw INTERP_KERNEL::Exception("MEDMeshMultiLev::getNumberOfCells : not existing geometric type in this !"); +} + +int MEDMeshMultiLev::getNumberOfNodes() const +{ + return _nb_nodes; +} + +DataArray *MEDMeshMultiLev::constructDataArray(const MEDFileField1TSStructItem& fst, const MEDFileFieldGlobsReal *globs, const DataArray *vals) const +{ + if(fst.getType()==ON_NODES) + { + if(fst.getNumberOfItems()!=1) + throw INTERP_KERNEL::Exception("MEDMeshMultiLev::constructDataArray : unexpected situation for nodes !"); + const MEDFileField1TSStructItem2& p(fst[0]); + std::string pflName(p.getPflName()); + const DataArrayInt *nr(_node_reduction); + if(pflName.empty() && !nr) + return vals->deepCpy(); + if(pflName.empty() && nr) + throw INTERP_KERNEL::Exception("MEDMeshMultiLev::constructDataArray : unexpected situation for nodes 2 !"); + if(!pflName.empty() && nr) + { + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> p1(globs->getProfile(pflName.c_str())->deepCpy()); + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> p2(nr->deepCpy()); + p1->sort(true); p2->sort(true); + if(!p1->isEqualWithoutConsideringStr(*p2)) + throw INTERP_KERNEL::Exception("MEDMeshMultiLev::constructDataArray : it appears that a profile on nodes does not cover the cells correctly !"); + p1=DataArrayInt::FindPermutationFromFirstToSecond(globs->getProfile(pflName.c_str()),nr); + MEDCouplingAutoRefCountObjectPtr<DataArray> ret(vals->deepCpy()); + ret->renumberInPlace(p1->begin()); + return ret.retn(); + } + if(!pflName.empty() && !nr) + { + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> p1(globs->getProfile(pflName.c_str())->deepCpy()); + p1->sort(true); + if(!p1->isIdentity() || p1->getNumberOfTuples()!=getNumberOfNodes()) + throw INTERP_KERNEL::Exception("MEDMeshMultiLev::constructDataArray : unexpected situation for nodes 4 !"); + MEDCouplingAutoRefCountObjectPtr<DataArray> ret(vals->deepCpy()); + ret->renumberInPlace(globs->getProfile(pflName.c_str())->begin()); + return ret.retn(); + } + throw INTERP_KERNEL::Exception("MEDMeshMultiLev::constructDataArray : unexpected situation for nodes 5 !"); + } + else + { + std::size_t sz(fst.getNumberOfItems()); + std::set<INTERP_KERNEL::NormalizedCellType> s(_geo_types.begin(),_geo_types.end()); + if(s.size()!=_geo_types.size()) + throw INTERP_KERNEL::Exception("MEDMeshMultiLev::constructDataArray : unexpected situation for cells 2 !"); + std::vector< const DataArray *> arr(s.size()); + std::vector< MEDCouplingAutoRefCountObjectPtr<DataArray> > arrSafe(s.size()); + int iii(0); + int nc(vals->getNumberOfComponents()); + std::vector<std::string> compInfo(vals->getInfoOnComponents()); + for(std::vector< INTERP_KERNEL::NormalizedCellType >::const_iterator it=_geo_types.begin();it!=_geo_types.end();it++,iii++) + { + const DataArrayInt *thisP(_pfls[iii]); + std::vector<const MEDFileField1TSStructItem2 *> ps; + for(std::size_t i=0;i<sz;i++) + { + const MEDFileField1TSStructItem2& p(fst[i]); + if(p.getGeo()==*it) + ps.push_back(&p); + } + if(ps.empty()) + throw INTERP_KERNEL::Exception("MEDMeshMultiLev::constructDataArray : unexpected situation for cells 1 !"); + if(ps.size()==1) + { + int nbi(ps[0]->getNbOfIntegrationPts(globs)); + const DataArrayInt *otherP(ps[0]->getPfl(globs)); + const std::pair<int,int>& strtStop(ps[0]->getStartStop()); + MEDCouplingAutoRefCountObjectPtr<DataArray> ret(vals->selectByTupleId2(strtStop.first,strtStop.second,1)); + if(!thisP && !otherP) + { + arrSafe[iii]=ret; arr[iii]=ret; + continue; + } + if(thisP && otherP) + { + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> p1(otherP->invertArrayN2O2O2N(getNumberOfCells(ps[0]->getGeo()))); + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> p2(thisP->deepCpy()); + p2->transformWithIndArr(p1->begin(),p1->end()); + //p1=p2->getIdsNotEqual(-1); + //p1=p2->selectByTupleIdSafe(p1->begin(),p1->end()); + ret->rearrange(nbi*nc); ret=ret->selectByTupleIdSafe(p2->begin(),p2->end()); ret->rearrange(nc); ret->setInfoOnComponents(compInfo); + arrSafe[iii]=ret; arr[iii]=ret; + continue; + } + if(!thisP && otherP) + { + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> p1(otherP->deepCpy()); + p1->sort(true); + p1->checkAllIdsInRange(0,getNumberOfCells(ps[0]->getGeo())); + p1=DataArrayInt::FindPermutationFromFirstToSecond(otherP,p1); + ret->rearrange(nbi*nc); ret->renumberInPlace(p1->begin()); ret->rearrange(nc); ret->setInfoOnComponents(compInfo); + arrSafe[iii]=ret; arr[iii]=ret; + continue; + } + throw INTERP_KERNEL::Exception("MEDMeshMultiLev::constructDataArray : unexpected situation for cells 3 !"); + } + else + { + std::vector< const DataArrayInt * >otherPS(ps.size()); + std::vector< const DataArray * > arr2(ps.size()); + std::vector< MEDCouplingAutoRefCountObjectPtr<DataArray> > arr2Safe(ps.size()); + std::vector< const DataArrayInt * > nbis(ps.size()); + std::vector< MEDCouplingAutoRefCountObjectPtr<DataArrayInt> > nbisSafe(ps.size()); + int jj(0); + for(std::vector<const MEDFileField1TSStructItem2 *>::const_iterator it2=ps.begin();it2!=ps.end();it2++,jj++) + { + int nbi((*it2)->getNbOfIntegrationPts(globs)); + const DataArrayInt *otherPfl((*it2)->getPfl(globs)); + const std::pair<int,int>& strtStop((*it2)->getStartStop()); + MEDCouplingAutoRefCountObjectPtr<DataArray> ret2(vals->selectByTupleId2(strtStop.first,strtStop.second,1)); + if(!otherPfl) + throw INTERP_KERNEL::Exception("MEDMeshMultiLev::constructDataArray : unexpected situation for cells 4 !"); + arr2[jj]=ret2; arr2Safe[jj]=ret2; otherPS[jj]=otherPfl; + nbisSafe[jj]=DataArrayInt::New(); nbisSafe[jj]->alloc(otherPfl->getNumberOfTuples(),1); nbisSafe[jj]->fillWithValue(nbi); + nbis[jj]=nbisSafe[jj]; + } + MEDCouplingAutoRefCountObjectPtr<DataArray> arr3(DataArray::Aggregate(arr2)); + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> otherP(DataArrayInt::Aggregate(otherPS)); + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> zenbis(DataArrayInt::Aggregate(nbis)); + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> otherPN(otherP->invertArrayN2O2O2N(getNumberOfCells(*it))); + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> p1; + if(thisP) + p1=DataArrayInt::FindPermutationFromFirstToSecond(otherP,thisP); + else + p1=otherP->deepCpy(); + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> zenbisN(zenbis->renumber(p1->begin())); + zenbisN->computeOffsets2(); + jj=0; + for(std::vector<const MEDFileField1TSStructItem2 *>::const_iterator it2=ps.begin();it2!=ps.end();it2++,jj++) + { + //int nbi((*it2)->getNbOfIntegrationPts(globs)); + const DataArrayInt *otherPfl((*it2)->getPfl(globs)); + const std::pair<int,int>& strtStop((*it2)->getStartStop()); + MEDCouplingAutoRefCountObjectPtr<DataArray> ret2(vals->selectByTupleId2(strtStop.first,strtStop.second,1)); + // + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> p2(otherPfl->deepCpy()); + p2->transformWithIndArr(otherPN->begin(),otherPN->end()); + p2->transformWithIndArr(p1->begin(),p1->end()); + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> idsN(p2->buildExplicitArrByRanges(zenbisN)); + arr3->setPartOfValuesBase3(ret2,idsN->begin(),idsN->end(),0,nc,1); + } + arrSafe[iii]=arr3; arr[iii]=arr3; + continue; + } + } + return DataArray::Aggregate(arr); + } +} + +/*! + * This method is called to add NORM_POINT1 cells in \a this so that orphan nodes in \a verticesToAdd will be fetched. + */ +void MEDMeshMultiLev::appendVertices(const DataArrayInt *verticesToAdd, DataArrayInt *nr) +{ + int nbOfVertices(verticesToAdd->getNumberOfTuples()); + std::size_t sz(_pfls.size()); + _pfls.resize(sz+1); + _geo_types.resize(sz+1,INTERP_KERNEL::NORM_POINT1); + _nb_entities.resize(sz+1,nbOfVertices); + _node_reduction=nr; nr->incrRef(); + _nb_nodes+=nbOfVertices; + const DataArrayInt *cf(_cell_fam_ids),*cn(_cell_num_ids),*nf(_node_fam_ids),*nn(_node_num_ids); + if(cf) + { + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> tmp; + std::vector<const DataArrayInt *> a(2); + a[0]=cf; + if(nf) + tmp=nf->selectByTupleIdSafe(verticesToAdd->begin(),verticesToAdd->end()); + else + { + tmp=DataArrayInt::New(); tmp->alloc(nbOfVertices,1); tmp->fillWithZero(); + } + a[1]=tmp; + _cell_fam_ids=DataArrayInt::Aggregate(a); + } + if(cn) + { + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> tmp; + std::vector<const DataArrayInt *> a(2); + a[0]=cn; + if(nn) + tmp=nn->selectByTupleIdSafe(verticesToAdd->begin(),verticesToAdd->end()); + else + { + tmp=DataArrayInt::New(); tmp->alloc(nbOfVertices,1); tmp->fillWithZero(); + } + a[1]=tmp; + _cell_num_ids=DataArrayInt::Aggregate(a); + } +} + +MEDMeshMultiLev::MEDMeshMultiLev(const MEDFileMesh *mesh):_mesh(mesh),_nb_nodes(0) +{ +} + +MEDMeshMultiLev::MEDMeshMultiLev(const MEDFileMesh *mesh, int nbNodes, const std::vector<INTERP_KERNEL::NormalizedCellType>& gts, const std::vector<const DataArrayInt *>& pfls, const std::vector<int>& nbEntities):_mesh(mesh),_geo_types(gts),_nb_entities(nbEntities),_nb_nodes(nbNodes) +{ + std::size_t sz(_geo_types.size()); + if(sz!=pfls.size() || sz!=nbEntities.size()) + throw INTERP_KERNEL::Exception("MEDMeshMultiLev::MEDMeshMultiLev : input vector must have the same size !"); + _pfls.resize(sz); + for(std::size_t i=0;i<sz;i++) + { + if(pfls[i]) + pfls[i]->incrRef(); + _pfls[i]=const_cast<DataArrayInt *>(pfls[i]); + } +} + +MEDMeshMultiLev::MEDMeshMultiLev(const MEDMeshMultiLev& other):RefCountObject(other),_mesh(other._mesh),_pfls(other._pfls),_geo_types(other._geo_types),_nb_entities(other._nb_entities),_node_reduction(other._node_reduction),_nb_nodes(other._nb_nodes),_cell_fam_ids(other._cell_fam_ids),_cell_num_ids(other._cell_num_ids),_node_fam_ids(other._node_fam_ids),_node_num_ids(other._node_num_ids) +{ +} + +//= + +MEDUMeshMultiLev *MEDUMeshMultiLev::New(const MEDFileUMesh *m, const std::vector<int>& levs) +{ + return new MEDUMeshMultiLev(m,levs); +} + +MEDUMeshMultiLev::MEDUMeshMultiLev(const MEDFileUMesh *m, const std::vector<int>& levs):MEDMeshMultiLev(m) +{ + if(!m) + throw INTERP_KERNEL::Exception("MEDUMeshMultiLev constructor : null input pointer !"); + std::vector<MEDCoupling1GTUMesh *> v; + for(std::vector<int>::const_iterator it=levs.begin();it!=levs.end();it++) + { + std::vector<MEDCoupling1GTUMesh *> vTmp(m->getDirectUndergroundSingleGeoTypeMeshes(*it)); + v.insert(v.end(),vTmp.begin(),vTmp.end()); + } + std::size_t sz(v.size()); + if(v.empty()) + { + _coords=m->getCoords(); _coords->incrRef(); + } + _parts.resize(sz); + _pfls.resize(sz); + _geo_types.resize(sz); + _nb_entities.resize(sz); + for(std::size_t i=0;i<sz;i++) + { + MEDCoupling1GTUMesh *obj(v[i]); + if(obj) + obj->incrRef(); + else + throw INTERP_KERNEL::Exception("MEDUMeshMultiLev constructor : presence of a null pointer !"); + _parts[i]=obj; + _geo_types[i]=obj->getCellModelEnum(); + _nb_entities[i]=obj->getNumberOfCells(); + } + // ids fields management + bool cellFamIdsNoCpy(levs.size()==1); + if(cellFamIdsNoCpy) + { + const DataArrayInt *tmp(m->getFamilyFieldAtLevel(levs[0])); + if(tmp) + { + tmp->incrRef(); + _cell_fam_ids=(const_cast<DataArrayInt *>(tmp)); + } + } + else + { + std::vector<const DataArrayInt *> tmps(levs.size()); + bool f(true); + for(std::size_t i=0;i<levs.size();i++) + { + tmps[i]=m->getFamilyFieldAtLevel(levs[i]); + if(!tmps[i]) + f=false; + } + if(f && !tmps.empty()) + _cell_fam_ids=DataArrayInt::Aggregate(tmps); + } + bool cellNumIdsNoCpy(levs.size()==1); + if(cellNumIdsNoCpy) + { + const DataArrayInt *tmp(m->getNumberFieldAtLevel(levs[0])); + if(tmp) + { + tmp->incrRef(); + _cell_num_ids=(const_cast<DataArrayInt *>(tmp)); + } + } + else + { + std::vector<const DataArrayInt *> tmps(levs.size()); + bool n(true); + for(std::size_t i=0;i<levs.size();i++) + { + tmps[i]=m->getNumberFieldAtLevel(levs[i]); + if(!tmps[i]) + n=false; + } + if(n && !tmps.empty()) + _cell_num_ids=DataArrayInt::Aggregate(tmps); + } + // node part + { + const DataArrayInt *tmp(m->getFamilyFieldAtLevel(1)); + if(tmp) + { + tmp->incrRef(); + _node_fam_ids=(const_cast<DataArrayInt *>(tmp)); + } + } + { + const DataArrayInt *tmp(m->getNumberFieldAtLevel(1)); + if(tmp) + { + tmp->incrRef(); + _node_num_ids=(const_cast<DataArrayInt *>(tmp)); + } + } +} + +MEDUMeshMultiLev *MEDUMeshMultiLev::New(const MEDFileUMesh *m, const std::vector<INTERP_KERNEL::NormalizedCellType>& gts, const std::vector<const DataArrayInt *>& pfls, const std::vector<int>& nbEntities) +{ + return new MEDUMeshMultiLev(m,gts,pfls,nbEntities); +} + +MEDUMeshMultiLev::MEDUMeshMultiLev(const MEDFileUMesh *m, const std::vector<INTERP_KERNEL::NormalizedCellType>& gts, const std::vector<const DataArrayInt *>& pfls, const std::vector<int>& nbEntities):MEDMeshMultiLev(m,m->getNumberOfNodes(),gts,pfls,nbEntities) +{ + std::size_t sz(gts.size()); + if(sz<1) + throw INTERP_KERNEL::Exception("constructor of MEDUMeshMultiLev : number of different geo type must be >= 1 !"); + unsigned dim(INTERP_KERNEL::CellModel::GetCellModel(gts[0]).getDimension()); + _parts.resize(sz); + bool isSameDim(true),isNoPfl(true); + for(std::size_t i=0;i<sz;i++) + { + MEDCoupling1GTUMesh *elt(m->getDirectUndergroundSingleGeoTypeMesh(gts[i])); + if(INTERP_KERNEL::CellModel::GetCellModel(gts[i]).getDimension()!=dim) + isSameDim=false; + if(pfls[i]) + isNoPfl=false; + if(elt) + elt->incrRef(); + _parts[i]=elt; + } + // ids fields management + int lev((int)dim-m->getMeshDimension()); + if(isSameDim && isNoPfl && m->getGeoTypesAtLevel(lev)==gts)//optimized part + { + const DataArrayInt *famIds(m->getFamilyFieldAtLevel(lev)); + if(famIds) + { _cell_fam_ids=const_cast<DataArrayInt*>(famIds); famIds->incrRef(); } + const DataArrayInt *numIds(m->getNumberFieldAtLevel(lev)); + if(numIds) + { _cell_num_ids=const_cast<DataArrayInt*>(numIds); numIds->incrRef(); } + famIds=m->getFamilyFieldAtLevel(1); + if(famIds) + { _node_fam_ids=const_cast<DataArrayInt*>(famIds); famIds->incrRef(); } + numIds=m->getNumberFieldAtLevel(1); + if(numIds) + { _node_num_ids=const_cast<DataArrayInt*>(numIds); numIds->incrRef(); } + return ; + } + // + std::vector< MEDCouplingAutoRefCountObjectPtr<DataArrayInt> > famIdsSafe(sz); + std::vector<const DataArrayInt *> famIds(sz); + bool f(true); + for(std::size_t i=0;i<sz;i++) + { + famIdsSafe[i]=m->extractFamilyFieldOnGeoType(gts[i]); + famIds[i]=famIdsSafe[i]; + if(!famIds[i]) + f=false; + } + if(f) + _cell_fam_ids=DataArrayInt::Aggregate(famIds); + std::vector< MEDCouplingAutoRefCountObjectPtr<DataArrayInt> > numIdsSafe(sz); + std::vector<const DataArrayInt *> numIds(sz); + bool n(true); + for(std::size_t i=0;i<sz;i++) + { + numIdsSafe[i]=m->extractNumberFieldOnGeoType(gts[i]); + numIds[i]=numIdsSafe[i]; + if(!numIds[i]) + n=false; + } + if(n) + _cell_num_ids=DataArrayInt::Aggregate(numIds); + // node ids management + const DataArrayInt *nodeFamIds(m->getFamilyFieldAtLevel(1)); + if(nodeFamIds) + { _node_fam_ids=const_cast<DataArrayInt*>(nodeFamIds); nodeFamIds->incrRef(); } + const DataArrayInt *nodeNumIds(m->getNumberFieldAtLevel(1)); + if(nodeNumIds) + { _node_num_ids=const_cast<DataArrayInt*>(nodeNumIds); nodeNumIds->incrRef(); } +} + +void MEDUMeshMultiLev::selectPartOfNodes(const DataArrayInt *pflNodes) +{ + if(!pflNodes || !pflNodes->isAllocated()) + return ; + std::size_t sz(_parts.size()); + std::vector< MEDCouplingAutoRefCountObjectPtr<DataArrayInt> > a(sz); + std::vector< const DataArrayInt *> aa(sz); + for(std::size_t i=0;i<sz;i++) + { + const DataArrayInt *pfl(_pfls[i]); + MEDCouplingAutoRefCountObjectPtr<MEDCoupling1GTUMesh> m(_parts[i]); + if(pfl) + m=dynamic_cast<MEDCoupling1GTUMesh *>(_parts[i]->buildPartOfMySelfKeepCoords(pfl->begin(),pfl->end())); + DataArrayInt *cellIds=0; + m->fillCellIdsToKeepFromNodeIds(pflNodes->begin(),pflNodes->end(),true,cellIds); + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> cellIdsSafe(cellIds); + MEDCouplingAutoRefCountObjectPtr<MEDCouplingPointSet> m2(m->buildPartOfMySelfKeepCoords(cellIds->begin(),cellIds->end())); + int tmp=-1; + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> o2n(m2->getNodeIdsInUse(tmp)); + a[i]=o2n->invertArrayO2N2N2O(tmp); aa[i]=a[i]; + if(pfl) + _pfls[i]=pfl->selectByTupleIdSafe(cellIds->begin(),cellIds->end()); + else + _pfls[i]=cellIdsSafe; + } + if(!aa.empty()) + _node_reduction=DataArrayInt::Aggregate(aa);//general case + else + _node_reduction=pflNodes->deepCpy();//case where no cells in read mesh. + _node_reduction->sort(true); + _node_reduction=_node_reduction->buildUnique(); + if(_node_reduction->getNumberOfTuples()==pflNodes->getNumberOfTuples()) + return ;//This is the classical case where the input node profile corresponds perfectly to a subset of cells in _parts + if(_node_reduction->getNumberOfTuples()>pflNodes->getNumberOfTuples()) + throw INTERP_KERNEL::Exception("MEDUMeshMultiLev::selectPartOfNodes : internal error in MEDCoupling during cell select from a list of nodes !"); + // Here the cells available in _parts is not enough to cover all the nodes in pflNodes. So adding vertices cells in _parts... + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> pflNodes2(pflNodes->deepCpy()); + pflNodes2->sort(true); + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> diff(pflNodes2->buildSubstractionOptimized(_node_reduction)); + appendVertices(diff,pflNodes2); +} + +MEDMeshMultiLev *MEDUMeshMultiLev::prepare() const +{ + return new MEDUMeshMultiLev(*this); +} + +MEDUMeshMultiLev::MEDUMeshMultiLev(const MEDUMeshMultiLev& other):MEDMeshMultiLev(other),_parts(other._parts),_coords(other._coords) +{ +} + +MEDUMeshMultiLev::MEDUMeshMultiLev(const MEDStructuredMeshMultiLev& other, const MEDCouplingAutoRefCountObjectPtr<MEDCoupling1GTUMesh>& part):MEDMeshMultiLev(other) +{ + _parts.resize(1); + _parts[0]=part; + _geo_types.resize(1); _geo_types[0]=part->getCellModelEnum(); + _nb_entities.resize(1); _nb_entities[0]=part->getNumberOfCells(); + _pfls.resize(1); _pfls[0]=0; +} + +/*! + * To be called only once ! Because due to some optimizations (sometimes aggressive) the internal state can be changed... + * If returned value is false output pointer \a coords is not the internal pointer. If returned value is true output pointer \a coords is directly the internal pointer. + * If true is returned, the \a coords output parameter should be used with care (non const method call) to avoid to change the internal state of MEDFileUMesh instance. + */ +bool MEDUMeshMultiLev::buildVTUArrays(DataArrayDouble *& coords, DataArrayByte *&types, DataArrayInt *&cellLocations, DataArrayInt *& cells, DataArrayInt *&faceLocations, DataArrayInt *&faces) const +{ + const DataArrayDouble *tmp(0); + if(_parts.empty()) + tmp=_coords; + else + tmp=_parts[0]->getCoords(); + if(!tmp) + throw INTERP_KERNEL::Exception("MEDUMeshMultiLev::getVTUArrays : the coordinates are null !"); + MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> a(const_cast<DataArrayDouble *>(tmp)); tmp->incrRef(); + int szBCE(0),szD(0),szF(0); + bool isPolyh(false); + int iii(0); + for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCoupling1GTUMesh> >::const_iterator it=_parts.begin();it!=_parts.end();it++,iii++) + { + const MEDCoupling1GTUMesh *cur(*it); + if(!cur) + throw INTERP_KERNEL::Exception("MEDUMeshMultiLev::getVTUArrays : a part is null !"); + // + const DataArrayInt *pfl(_pfls[iii]); + MEDCouplingAutoRefCountObjectPtr<MEDCoupling1GTUMesh> cur2; + if(!pfl) + { cur2=const_cast<MEDCoupling1GTUMesh *>(cur); cur2->incrRef(); } + else + { cur2=dynamic_cast<MEDCoupling1GTUMesh *>(cur->buildPartOfMySelfKeepCoords(pfl->begin(),pfl->end())); cur=cur2; } + // + int curNbCells(cur->getNumberOfCells()); + szBCE+=curNbCells; + if((*it)->getCellModelEnum()!=INTERP_KERNEL::NORM_POLYHED) + szD+=cur->getNodalConnectivity()->getNumberOfTuples()+curNbCells; + else + { + isPolyh=true; + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> tmp2(cur->computeEffectiveNbOfNodesPerCell()); + szD+=tmp2->accumulate(0)+curNbCells; + szF+=2*curNbCells+cur->getNodalConnectivity()->getNumberOfTuples(); + } + } + MEDCouplingAutoRefCountObjectPtr<DataArrayByte> b(DataArrayByte::New()); b->alloc(szBCE,1); char *bPtr(b->getPointer()); + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> c(DataArrayInt::New()); c->alloc(szBCE,1); int *cPtr(c->getPointer()); + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> d(DataArrayInt::New()); d->alloc(szD,1); int *dPtr(d->getPointer()); + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> e(DataArrayInt::New()),f(DataArrayInt::New()); int *ePtr(0),*fPtr(0); + if(isPolyh) + { e->alloc(szBCE,1); ePtr=e->getPointer(); f->alloc(szF,1); fPtr=f->getPointer(); } + int k(0); + iii=0; + for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCoupling1GTUMesh> >::const_iterator it=_parts.begin();it!=_parts.end();it++,iii++) + { + const MEDCoupling1GTUMesh *cur(*it); + // + const DataArrayInt *pfl(_pfls[iii]); + MEDCouplingAutoRefCountObjectPtr<MEDCoupling1GTUMesh> cur2; + if(!pfl) + { cur2=const_cast<MEDCoupling1GTUMesh *>(cur); cur2->incrRef(); } + else + { cur2=dynamic_cast<MEDCoupling1GTUMesh *>(cur->buildPartOfMySelfKeepCoords(pfl->begin(),pfl->end())); cur=cur2; } + // + int curNbCells(cur->getNumberOfCells()); + int gt((int)cur->getCellModelEnum()); + if(gt<0 || gt>=PARAMEDMEM_2_VTKTYPE_LGTH) + throw INTERP_KERNEL::Exception("MEDUMeshMultiLev::getVTUArrays : invalid geometric type !"); + unsigned char gtvtk(PARAMEDMEM_2_VTKTYPE[gt]); + if(gtvtk==255) + throw INTERP_KERNEL::Exception("MEDUMeshMultiLev::getVTUArrays : no VTK type for the requested INTERP_KERNEL geometric type !"); + std::fill(bPtr,bPtr+curNbCells,gtvtk); bPtr+=curNbCells; + const MEDCoupling1SGTUMesh *scur(dynamic_cast<const MEDCoupling1SGTUMesh *>(cur)); + const MEDCoupling1DGTUMesh *dcur(dynamic_cast<const MEDCoupling1DGTUMesh *>(cur)); + const int *connPtr(cur->getNodalConnectivity()->begin()); + if(!scur && !dcur) + throw INTERP_KERNEL::Exception("MEDUMeshMultiLev::getVTUArrays : internal error !"); + if(scur) + { + if(cur->getCellModelEnum()!=INTERP_KERNEL::NORM_HEXA27) + { + int nnpc(scur->getNumberOfNodesPerCell()); + for(int i=0;i<curNbCells;i++,connPtr+=nnpc) + { + *dPtr++=nnpc; + dPtr=std::copy(connPtr,connPtr+nnpc,dPtr); + *cPtr++=k; k+=nnpc+1; + } + } + else + { + for(int i=0;i<curNbCells;i++,connPtr+=27) + { + *dPtr++=27; + for(int j=0;j<27;j++,dPtr++) + *dPtr=connPtr[HEXA27_PERM_ARRAY[j]]; + *cPtr++=k; k+=28; + } + } + if(isPolyh) + { std::fill(ePtr,ePtr+curNbCells,-1); ePtr+=curNbCells; } + } + else + { + const int *connIPtr(dcur->getNodalConnectivityIndex()->begin()); + if(cur->getCellModelEnum()!=INTERP_KERNEL::NORM_POLYHED) + { + for(int i=0;i<curNbCells;i++,connIPtr++) + { + *dPtr++=connIPtr[1]-connIPtr[0]; + dPtr=std::copy(connPtr+connIPtr[0],connPtr+connIPtr[1],dPtr); + *cPtr++=k; k+=connIPtr[1]-connIPtr[0]+1; + } + } + else + { + for(int i=0;i<curNbCells;i++,connIPtr++) + { + std::set<int> s(connPtr+connIPtr[0],connPtr+connIPtr[1]); s.erase(-1); + *dPtr++=(int)s.size(); + dPtr=std::copy(s.begin(),s.end(),dPtr); + *cPtr++=k; k+=(int)s.size()+1; + } + } + if(isPolyh) + { + connIPtr=dcur->getNodalConnectivityIndex()->begin(); + if(cur->getCellModelEnum()!=INTERP_KERNEL::NORM_POLYHED) + { std::fill(ePtr,ePtr+curNbCells,-1); ePtr+=curNbCells; } + else + { + int kk(0); + for(int i=0;i<curNbCells;i++,connIPtr++) + { + int nbFace(std::count(connPtr+connIPtr[0],connPtr+connIPtr[1],-1)+1); + *fPtr++=nbFace; + const int *work(connPtr+connIPtr[0]); + for(int j=0;j<nbFace;j++) + { + const int *work2=std::find(work,connPtr+connIPtr[1],-1); + *fPtr++=std::distance(work,work2); + fPtr=std::copy(work,work2,fPtr); + work=work2+1; + } + *ePtr++=kk; kk+=connIPtr[1]-connIPtr[0]+2; + } + } + } + } + } + if(!isPolyh) + reorderNodesIfNecessary(a,d,0); + else + reorderNodesIfNecessary(a,d,f); + if(a->getNumberOfComponents()!=3) + a=a->changeNbOfComponents(3,0.); + coords=a.retn(); types=b.retn(); cellLocations=c.retn(); cells=d.retn(); + if(!isPolyh) + { faceLocations=0; faces=0; } + else + { faceLocations=e.retn(); faces=f.retn(); } + return _mesh->isObjectInTheProgeny(coords); +} + +void MEDUMeshMultiLev::reorderNodesIfNecessary(MEDCouplingAutoRefCountObjectPtr<DataArrayDouble>& coords, DataArrayInt *nodalConnVTK, DataArrayInt *polyhedNodalConnVTK) const +{ + const DataArrayInt *nr(_node_reduction); + if(!nr) + return ; + if(nodalConnVTK->empty() && !polyhedNodalConnVTK) + { + coords=(coords->selectByTupleIdSafe(nr->begin(),nr->end())); + return ; + } + int sz(coords->getNumberOfTuples()); + std::vector<bool> b(sz,false); + const int *work(nodalConnVTK->begin()),*endW(nodalConnVTK->end()); + while(work!=endW) + { + int nb(*work++); + for(int i=0;i<nb && work!=endW;i++,work++) + { + if(*work>=0 && *work<sz) + b[*work]=true; + else + throw INTERP_KERNEL::Exception("MEDUMeshMultiLev::reorderNodesIfNecessary : internal error !"); + } + } + if(polyhedNodalConnVTK) + { + work=polyhedNodalConnVTK->begin(); endW=polyhedNodalConnVTK->end(); + while(work!=endW) + { + int nb(*work++); + for(int i=0;i<nb && work!=endW;i++) + { + int nb2(*work++); + for(int j=0;j<nb2 && work!=endW;j++,work++) + { + if(*work>=0 && *work<sz) + b[*work]=true; + else + throw INTERP_KERNEL::Exception("MEDUMeshMultiLev::reorderNodesIfNecessary : internal error #2 !"); + } + } + } + } + int szExp(std::count(b.begin(),b.end(),true)); + if(szExp!=nr->getNumberOfTuples()) + throw INTERP_KERNEL::Exception("MEDUMeshMultiLev::reorderNodesIfNecessary : internal error #3 !"); + // Go renumbering ! + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> o2n(DataArrayInt::New()); o2n->alloc(sz,1); + int *o2nPtr(o2n->getPointer()); + int newId(0); + for(int i=0;i<sz;i++,o2nPtr++) + if(b[i]) *o2nPtr=newId++; else *o2nPtr=-1; + const int *o2nPtrc(o2n->begin()); + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> n2o(o2n->invertArrayO2N2N2O(nr->getNumberOfTuples())); + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> perm(DataArrayInt::FindPermutationFromFirstToSecond(n2o,nr)); + const int *permPtr(perm->begin()); + int *work2(nodalConnVTK->getPointer()),*endW2(nodalConnVTK->getPointer()+nodalConnVTK->getNumberOfTuples()); + while(work2!=endW2) + { + int nb(*work2++); + for(int i=0;i<nb && work2!=endW2;i++,work2++) + *work2=permPtr[o2nPtrc[*work2]]; + } + if(polyhedNodalConnVTK) + { + work2=polyhedNodalConnVTK->getPointer(); endW2=polyhedNodalConnVTK->getPointer()+polyhedNodalConnVTK->getNumberOfTuples(); + while(work2!=endW2) + { + int nb(*work2++); + for(int i=0;i<nb && work2!=endW2;i++) + { + int nb2(*work2++); + for(int j=0;j<nb2 && work2!=endW2;j++,work2++) + *work2=permPtr[o2nPtrc[*work2]]; + } + } + } + coords=(coords->selectByTupleIdSafe(nr->begin(),nr->end())); +} + + +void MEDUMeshMultiLev::appendVertices(const DataArrayInt *verticesToAdd, DataArrayInt *nr) +{ + int nbOfCells(verticesToAdd->getNumberOfTuples());//it is not a bug cells are NORM_POINT1 + MEDMeshMultiLev::appendVertices(verticesToAdd,nr); + MEDCouplingAutoRefCountObjectPtr<MEDCoupling1SGTUMesh> elt(MEDCoupling1SGTUMesh::New("",INTERP_KERNEL::NORM_POINT1)); + elt->allocateCells(nbOfCells); + for(int i=0;i<nbOfCells;i++) + { + int pt(verticesToAdd->getIJ(i,0)); + elt->insertNextCell(&pt,&pt+1); + } + if(_parts.empty()) + throw INTERP_KERNEL::Exception("MEDUMeshMultiLev::appendVertices : parts are empty !"); + elt->setCoords(_parts[0]->getCoords()); + MEDCouplingAutoRefCountObjectPtr<MEDCoupling1GTUMesh> elt2((MEDCoupling1SGTUMesh *)elt); elt2->incrRef(); + _parts.push_back(elt2); +} + +//= + +MEDStructuredMeshMultiLev::MEDStructuredMeshMultiLev(const MEDFileStructuredMesh *m, const std::vector<int>& lev):MEDMeshMultiLev(m),_is_internal(true) +{ + initStdFieldOfIntegers(m); +} + +MEDStructuredMeshMultiLev::MEDStructuredMeshMultiLev(const MEDFileStructuredMesh *m, int nbOfNodes, const std::vector<INTERP_KERNEL::NormalizedCellType>& gts, const std::vector<const DataArrayInt *>& pfls, const std::vector<int>& nbEntities):MEDMeshMultiLev(m,nbOfNodes,gts,pfls,nbEntities),_is_internal(true) +{ + initStdFieldOfIntegers(m); +} + +MEDStructuredMeshMultiLev::MEDStructuredMeshMultiLev(const MEDStructuredMeshMultiLev& other):MEDMeshMultiLev(other),_is_internal(true),_face_fam_ids(other._face_fam_ids),_face_num_ids(other._face_num_ids) +{ +} + +void MEDStructuredMeshMultiLev::initStdFieldOfIntegers(const MEDFileStructuredMesh *m) +{ + // ids fields management + const DataArrayInt *tmp(0); + tmp=m->getFamilyFieldAtLevel(0); + if(tmp) + { + tmp->incrRef(); + _cell_fam_ids=const_cast<DataArrayInt *>(tmp); + } + tmp=m->getNumberFieldAtLevel(0); + if(tmp) + { + tmp->incrRef(); + _cell_num_ids=const_cast<DataArrayInt *>(tmp); + } + // + tmp=0; + tmp=m->getFamilyFieldAtLevel(1); + if(tmp) + { + tmp->incrRef(); + _node_fam_ids=const_cast<DataArrayInt *>(tmp); + } + tmp=m->getNumberFieldAtLevel(1); + if(tmp) + { + tmp->incrRef(); + _node_num_ids=const_cast<DataArrayInt *>(tmp); + } + // faces (if any) + tmp=m->getFamilyFieldAtLevel(-1); + if(tmp) + { + tmp->incrRef(); + _face_fam_ids=const_cast<DataArrayInt *>(tmp); + } + tmp=m->getNumberFieldAtLevel(-1); + if(tmp) + { + tmp->incrRef(); + _face_num_ids=const_cast<DataArrayInt *>(tmp); + } +} + +void MEDStructuredMeshMultiLev::moveFaceToCell() const +{ + const_cast<MEDStructuredMeshMultiLev *>(this)->_cell_fam_ids=_face_fam_ids; const_cast<MEDStructuredMeshMultiLev *>(this)->_face_fam_ids=0; + const_cast<MEDStructuredMeshMultiLev *>(this)->_cell_num_ids=_face_num_ids; const_cast<MEDStructuredMeshMultiLev *>(this)->_face_num_ids=0; +} + +bool MEDStructuredMeshMultiLev::prepareForImplicitUnstructuredMeshCase(MEDMeshMultiLev *&ret) const +{ + ret=0; + if(_geo_types.empty()) + return false; + if(_geo_types.size()!=1) + throw INTERP_KERNEL::Exception("MEDStructuredMeshMultiLev::prepareForImplicitUnstructuredMeshCase only one geo types supported at most supported for the moment !"); + INTERP_KERNEL::NormalizedCellType gt(MEDCouplingStructuredMesh::GetGeoTypeGivenMeshDimension(_mesh->getMeshDimension())); + if(_geo_types[0]==gt) + return false; + MEDCoupling1GTUMesh *facesIfPresent((static_cast<const MEDFileStructuredMesh *>(_mesh))->getImplicitFaceMesh()); + if(!facesIfPresent) + return false; + const DataArrayInt *pfl(0),*nr(_node_reduction); + if(!_pfls.empty()) + pfl=_pfls[0]; + MEDCouplingAutoRefCountObjectPtr<MEDCoupling1GTUMesh> facesIfPresent2(facesIfPresent); facesIfPresent->incrRef(); + moveFaceToCell(); + MEDCouplingAutoRefCountObjectPtr<MEDUMeshMultiLev> ret2(new MEDUMeshMultiLev(*this,facesIfPresent2)); + if(pfl) + ret2->setCellReduction(pfl); + if(nr) + throw INTERP_KERNEL::Exception("MEDStructuredMeshMultiLev::prepareForImplicitUnstructuredMeshCase : case is not treated yet for node reduction on implicit unstructured mesh."); + ret=ret2.retn(); + return true; +} + +void MEDStructuredMeshMultiLev::dealWithImplicitUnstructuredMesh(const MEDFileMesh *m) +{ + const DataArrayInt *tmp(0); + tmp=m->getFamilyFieldAtLevel(-1); + if(tmp) + { + tmp->incrRef(); + _cell_fam_ids=const_cast<DataArrayInt *>(tmp); + } + tmp=m->getNumberFieldAtLevel(-1); + if(tmp) + { + tmp->incrRef(); + _cell_num_ids=const_cast<DataArrayInt *>(tmp); + } +} + +void MEDStructuredMeshMultiLev::selectPartOfNodes(const DataArrayInt *pflNodes) +{ + if(!pflNodes || !pflNodes->isAllocated()) + return ; + std::vector<int> ngs(getNodeGridStructure()); + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> conn(MEDCouplingStructuredMesh::Build1GTNodalConnectivity(&ngs[0],&ngs[0]+ngs.size())); + MEDCouplingAutoRefCountObjectPtr<MEDCoupling1SGTUMesh> m(MEDCoupling1SGTUMesh::New("",MEDCouplingStructuredMesh::GetGeoTypeGivenMeshDimension(ngs.size()))); + m->setNodalConnectivity(conn); + const DataArrayInt *pfl(_pfls[0]); + if(pfl) + { + m=dynamic_cast<MEDCoupling1SGTUMesh *>(m->buildPartOfMySelfKeepCoords(pfl->begin(),pfl->end())); + } + DataArrayInt *cellIds=0; + m->fillCellIdsToKeepFromNodeIds(pflNodes->begin(),pflNodes->end(),true,cellIds); + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> cellIdsSafe(cellIds); + MEDCouplingAutoRefCountObjectPtr<MEDCouplingPointSet> m2(m->buildPartOfMySelfKeepCoords(cellIds->begin(),cellIds->end())); + int tmp=-1; + _node_reduction=m2->getNodeIdsInUse(tmp); + if(pfl) + _pfls[0]=pfl->selectByTupleIdSafe(cellIds->begin(),cellIds->end()); + else + _pfls[0]=cellIdsSafe; +} + +//= + +MEDCMeshMultiLev *MEDCMeshMultiLev::New(const MEDFileCMesh *m, const std::vector<int>& levs) +{ + return new MEDCMeshMultiLev(m,levs); +} + +MEDCMeshMultiLev *MEDCMeshMultiLev::New(const MEDFileCMesh *m, const std::vector<INTERP_KERNEL::NormalizedCellType>& gts, const std::vector<const DataArrayInt *>& pfls, const std::vector<int>& nbEntities) +{ + return new MEDCMeshMultiLev(m,gts,pfls,nbEntities); +} + +MEDCMeshMultiLev::MEDCMeshMultiLev(const MEDFileCMesh *m, const std::vector<int>& levs):MEDStructuredMeshMultiLev(m,levs) +{ + if(!m) + throw INTERP_KERNEL::Exception("MEDCMeshMultiLev constructor : null input pointer !"); + if(levs.size()!=1 || levs[0]!=0) + throw INTERP_KERNEL::Exception("MEDCMeshMultiLev constructor : levels supported is 0 only !"); + int sdim(m->getSpaceDimension()); + _coords.resize(sdim); + for(int i=0;i<sdim;i++) + { + DataArrayDouble *elt(const_cast<DataArrayDouble *>(m->getMesh()->getCoordsAt(i))); + if(!elt) + throw INTERP_KERNEL::Exception("MEDCMeshMultiLev constructor 2 : presence of null pointer for an vector of double along an axis !"); + elt->incrRef(); + _coords[i]=elt; + } +} + +MEDCMeshMultiLev::MEDCMeshMultiLev(const MEDFileCMesh *m, const std::vector<INTERP_KERNEL::NormalizedCellType>& gts, const std::vector<const DataArrayInt *>& pfls, const std::vector<int>& nbEntities):MEDStructuredMeshMultiLev(m,m->getNumberOfNodes(),gts,pfls,nbEntities) +{ + if(!m) + throw INTERP_KERNEL::Exception("MEDCMeshMultiLev constructor 2 : null input pointer !"); + if(gts.size()!=1 || pfls.size()!=1) + throw INTERP_KERNEL::Exception("MEDCMeshMultiLev constructor 2 : lengthes of gts and pfls must be equal to one !"); + int mdim(m->getMeshDimension()); + INTERP_KERNEL::NormalizedCellType gt(MEDCouplingStructuredMesh::GetGeoTypeGivenMeshDimension(mdim)); + if(gt==gts[0]) + { + _coords.resize(mdim); + for(int i=0;i<mdim;i++) + { + DataArrayDouble *elt(const_cast<DataArrayDouble *>(m->getMesh()->getCoordsAt(i))); + if(!elt) + throw INTERP_KERNEL::Exception("MEDCMeshMultiLev constructor 2 : presence of null pointer for an vector of double along an axis !"); + _coords[i]=elt; _coords[i]->incrRef(); + } + } + else + dealWithImplicitUnstructuredMesh(m); +} + +MEDCMeshMultiLev::MEDCMeshMultiLev(const MEDCMeshMultiLev& other):MEDStructuredMeshMultiLev(other),_coords(other._coords) +{ +} + +std::vector<int> MEDCMeshMultiLev::getNodeGridStructure() const +{ + std::vector<int> ret(_coords.size()); + for(std::size_t i=0;i<_coords.size();i++) + ret[i]=_coords[i]->getNumberOfTuples(); + return ret; +} + +MEDMeshMultiLev *MEDCMeshMultiLev::prepare() const +{ + MEDMeshMultiLev *retSpecific(0); + if(prepareForImplicitUnstructuredMeshCase(retSpecific)) + return retSpecific; + const DataArrayInt *pfl(0),*nr(_node_reduction); + if(!_pfls.empty()) + pfl=_pfls[0]; + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> nnr; + std::vector<int> cgs,ngs(getNodeGridStructure()); + cgs.resize(ngs.size()); + std::transform(ngs.begin(),ngs.end(),cgs.begin(),std::bind2nd(std::plus<int>(),-1)); + if(pfl) + { + std::vector< std::pair<int,int> > cellParts; + MEDCouplingAutoRefCountObjectPtr<MEDMeshMultiLev> ret2; + if(MEDCouplingStructuredMesh::IsPartStructured(pfl->begin(),pfl->end(),cgs,cellParts)) + { + MEDCouplingAutoRefCountObjectPtr<MEDCMeshMultiLev> ret(new MEDCMeshMultiLev(*this)); + ret->_is_internal=false; + if(nr) + { nnr=nr->deepCpy(); nnr->sort(true); ret->setNodeReduction(nnr); } + ret->_nb_entities[0]=pfl->getNumberOfTuples(); + ret->_pfls[0]=0; + std::vector< MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> > coords(_coords.size()); + for(std::size_t i=0;i<_coords.size();i++) + coords[i]=_coords[i]->selectByTupleId2(cellParts[i].first,cellParts[i].second+1,1); + ret->_coords=coords; + ret2=(MEDCMeshMultiLev *)ret; ret2->incrRef(); + } + else + { + MEDCouplingAutoRefCountObjectPtr<MEDCouplingCMesh> m(MEDCouplingCMesh::New()); + for(std::size_t i=0;i<ngs.size();i++) + m->setCoordsAt(i,_coords[i]); + MEDCouplingAutoRefCountObjectPtr<MEDCoupling1SGTUMesh> m2(m->build1SGTUnstructured()); + MEDCouplingAutoRefCountObjectPtr<MEDCoupling1GTUMesh> m3=dynamic_cast<MEDCoupling1GTUMesh *>(m2->buildPartOfMySelfKeepCoords(pfl->begin(),pfl->end())); + MEDCouplingAutoRefCountObjectPtr<MEDUMeshMultiLev> ret(new MEDUMeshMultiLev(*this,m3)); + if(nr) + { m3->zipCoords(); nnr=nr->deepCpy(); nnr->sort(true); ret->setNodeReduction(nnr); } + ret2=(MEDUMeshMultiLev *)ret; ret2->incrRef(); + } + const DataArrayInt *famIds(_cell_fam_ids),*numIds(_cell_num_ids); + if(famIds) + { + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> tmp(famIds->selectByTupleIdSafe(pfl->begin(),pfl->end())); + ret2->setFamilyIdsOnCells(tmp); + } + if(numIds) + { + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> tmp(numIds->selectByTupleIdSafe(pfl->begin(),pfl->end())); + ret2->setNumberIdsOnCells(tmp); + } + return ret2.retn(); + + } + else + { + MEDCouplingAutoRefCountObjectPtr<MEDCMeshMultiLev> ret(new MEDCMeshMultiLev(*this)); + if(nr) + { nnr=nr->deepCpy(); nnr->sort(true); ret->setNodeReduction(nnr); } + return ret.retn(); + } +} + +/*! + * \a param [out] isInternal if true the returned pointers are those in main data structure. If false those pointers have been built espacially for that method. + */ +std::vector< DataArrayDouble * > MEDCMeshMultiLev::buildVTUArrays(bool& isInternal) const +{ + isInternal=_is_internal; + std::size_t sz(_coords.size()); + std::vector< DataArrayDouble * > ret(sz); + for(std::size_t i=0;i<sz;i++) + { + ret[i]=const_cast<DataArrayDouble *>((const DataArrayDouble *)_coords[i]); + ret[i]->incrRef(); + } + return ret; +} + +//= + +MEDCurveLinearMeshMultiLev *MEDCurveLinearMeshMultiLev::New(const MEDFileCurveLinearMesh *m, const std::vector<int>& levs) +{ + return new MEDCurveLinearMeshMultiLev(m,levs); +} + +MEDCurveLinearMeshMultiLev *MEDCurveLinearMeshMultiLev::New(const MEDFileCurveLinearMesh *m, const std::vector<INTERP_KERNEL::NormalizedCellType>& gts, const std::vector<const DataArrayInt *>& pfls, const std::vector<int>& nbEntities) +{ + return new MEDCurveLinearMeshMultiLev(m,gts,pfls,nbEntities); +} + +MEDCurveLinearMeshMultiLev::MEDCurveLinearMeshMultiLev(const MEDFileCurveLinearMesh *m, const std::vector<int>& levs):MEDStructuredMeshMultiLev(m,levs) +{ + if(!m) + throw INTERP_KERNEL::Exception("MEDCurveLinearMeshMultiLev constructor : null input pointer !"); + if(levs.size()!=1 || levs[0]!=0) + throw INTERP_KERNEL::Exception("MEDCurveLinearMeshMultiLev constructor : levels supported is 0 only !"); + DataArrayDouble *coords(const_cast<DataArrayDouble *>(m->getMesh()->getCoords())); + if(!coords) + throw INTERP_KERNEL::Exception("MEDCurveLinearMeshMultiLev constructor 2 : no coords set !"); + coords->incrRef(); + _coords=coords; + _structure=m->getMesh()->getNodeGridStructure(); +} + +MEDCurveLinearMeshMultiLev::MEDCurveLinearMeshMultiLev(const MEDFileCurveLinearMesh *m, const std::vector<INTERP_KERNEL::NormalizedCellType>& gts, const std::vector<const DataArrayInt *>& pfls, const std::vector<int>& nbEntities):MEDStructuredMeshMultiLev(m,m->getNumberOfNodes(),gts,pfls,nbEntities) +{ + if(!m) + throw INTERP_KERNEL::Exception("MEDCurveLinearMeshMultiLev constructor 2 : null input pointer !"); + if(gts.size()!=1 || pfls.size()!=1) + throw INTERP_KERNEL::Exception("MEDCurveLinearMeshMultiLev constructor 2 : lengthes of gts and pfls must be equal to one !"); + INTERP_KERNEL::NormalizedCellType gt(MEDCouplingStructuredMesh::GetGeoTypeGivenMeshDimension(m->getMeshDimension())); + if(gt==gts[0]) + { + DataArrayDouble *coords(const_cast<DataArrayDouble *>(m->getMesh()->getCoords())); + if(!coords) + throw INTERP_KERNEL::Exception("MEDCurveLinearMeshMultiLev constructor 2 : no coords set !"); + coords->incrRef(); + _coords=coords; + _structure=m->getMesh()->getNodeGridStructure(); + } + else + dealWithImplicitUnstructuredMesh(m); +} + +MEDCurveLinearMeshMultiLev::MEDCurveLinearMeshMultiLev(const MEDCurveLinearMeshMultiLev& other):MEDStructuredMeshMultiLev(other),_coords(other._coords),_structure(other._structure) +{ +} + +std::vector<int> MEDCurveLinearMeshMultiLev::getNodeGridStructure() const +{ + return _structure; +} + +MEDMeshMultiLev *MEDCurveLinearMeshMultiLev::prepare() const +{ + MEDMeshMultiLev *retSpecific(0); + if(prepareForImplicitUnstructuredMeshCase(retSpecific)) + return retSpecific; + const DataArrayInt *pfl(0),*nr(_node_reduction); + if(!_pfls.empty()) + pfl=_pfls[0]; + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> nnr; + std::vector<int> cgs,ngs(getNodeGridStructure()); + cgs.resize(ngs.size()); + std::transform(ngs.begin(),ngs.end(),cgs.begin(),std::bind2nd(std::plus<int>(),-1)); + if(pfl) + { + std::vector< std::pair<int,int> > cellParts,nodeParts; + MEDCouplingAutoRefCountObjectPtr<MEDMeshMultiLev> ret2; + if(MEDCouplingStructuredMesh::IsPartStructured(pfl->begin(),pfl->end(),cgs,cellParts)) + { + nodeParts=cellParts; + std::vector<int> st(ngs.size()); + for(std::size_t i=0;i<ngs.size();i++) + { + nodeParts[i].second++; + st[i]=nodeParts[i].second-nodeParts[i].first; + } + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> p(MEDCouplingStructuredMesh::BuildExplicitIdsFrom(ngs,nodeParts)); + MEDCouplingAutoRefCountObjectPtr<MEDCurveLinearMeshMultiLev> ret(new MEDCurveLinearMeshMultiLev(*this)); + ret->_is_internal=false; + if(nr) + { nnr=nr->deepCpy(); nnr->sort(true); ret->setNodeReduction(nnr); } + ret->_nb_entities[0]=pfl->getNumberOfTuples(); + ret->_pfls[0]=0; + ret->_coords=_coords->selectByTupleIdSafe(p->begin(),p->end()); + ret->_structure=st; + ret2=(MEDCurveLinearMeshMultiLev *)ret; ret2->incrRef(); + } + else + { + MEDCouplingAutoRefCountObjectPtr<MEDCouplingCurveLinearMesh> m(MEDCouplingCurveLinearMesh::New()); + m->setCoords(_coords); m->setNodeGridStructure(&_structure[0],&_structure[0]+_structure.size()); + MEDCouplingAutoRefCountObjectPtr<MEDCoupling1SGTUMesh> m2(m->build1SGTUnstructured()); + MEDCouplingAutoRefCountObjectPtr<MEDCoupling1GTUMesh> m3=dynamic_cast<MEDCoupling1GTUMesh *>(m2->buildPartOfMySelfKeepCoords(pfl->begin(),pfl->end())); + MEDCouplingAutoRefCountObjectPtr<MEDUMeshMultiLev> ret(new MEDUMeshMultiLev(*this,m3)); + if(nr) + { m3->zipCoords(); nnr=nr->deepCpy(); nnr->sort(true); ret->setNodeReduction(nnr); } + ret2=(MEDUMeshMultiLev *)ret; ret2->incrRef(); + } + const DataArrayInt *famIds(_cell_fam_ids),*numIds(_cell_num_ids); + if(famIds) + { + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> tmp(famIds->selectByTupleIdSafe(pfl->begin(),pfl->end())); + ret2->setFamilyIdsOnCells(tmp); + } + if(numIds) + { + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> tmp(numIds->selectByTupleIdSafe(pfl->begin(),pfl->end())); + ret2->setNumberIdsOnCells(tmp); + } + return ret2.retn(); + } + else + { + MEDCouplingAutoRefCountObjectPtr<MEDCurveLinearMeshMultiLev> ret(new MEDCurveLinearMeshMultiLev(*this)); + if(nr) + { nnr=nr->deepCpy(); nnr->sort(true); ret->setNodeReduction(nnr); } + return ret.retn(); + } +} + +void MEDCurveLinearMeshMultiLev::buildVTUArrays(DataArrayDouble *&coords, std::vector<int>& nodeStrct, bool& isInternal) const +{ + isInternal=_is_internal; + nodeStrct=_structure; + const DataArrayDouble *coo(_coords); + if(!coo) + throw INTERP_KERNEL::Exception("MEDCurveLinearMeshMultiLev::buildVTUArrays : null pointer on coordinates !"); + coords=const_cast<DataArrayDouble *>(coo); coords->incrRef(); +} + +//= + +MEDFileField1TSStructItem2::MEDFileField1TSStructItem2() +{ +} + +MEDFileField1TSStructItem2::MEDFileField1TSStructItem2(INTERP_KERNEL::NormalizedCellType a, const std::pair<int,int>& b, const std::string& c, const std::string& d):_geo_type(a),_start_end(b),_pfl(DataArrayInt::New()),_loc(d),_nb_of_entity(-1) +{ + _pfl->setName(c.c_str()); +} + +void MEDFileField1TSStructItem2::checkWithMeshStructForCells(const MEDFileMeshStruct *mst, const MEDFileFieldGlobsReal *globs) +{ + if(!mst->doesManageGeoType(_geo_type)) + { + MEDFileMeshStruct *mstUnConstCasted(const_cast<MEDFileMeshStruct *>(mst)); + mstUnConstCasted->appendIfImplicitType(_geo_type); + } + int nbOfEnt=mst->getNumberOfElemsOfGeoType(_geo_type); + checkInRange(nbOfEnt,1,globs); +} + +void MEDFileField1TSStructItem2::checkWithMeshStructForGaussNE(const MEDFileMeshStruct *mst, const MEDFileFieldGlobsReal *globs) +{ + int nbOfEnt=mst->getNumberOfElemsOfGeoType(_geo_type); + const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(_geo_type); + checkInRange(nbOfEnt,(int)cm.getNumberOfNodes(),globs); +} + +void MEDFileField1TSStructItem2::checkWithMeshStructForGaussPT(const MEDFileMeshStruct *mst, const MEDFileFieldGlobsReal *globs) +{ + if(!globs) + throw INTERP_KERNEL::Exception("MEDFileField1TSStructItem2::checkWithMeshStructForGaussPT : no globals specified !"); + if(_loc.empty()) + throw INTERP_KERNEL::Exception("MEDFileField1TSStructItem2::checkWithMeshStructForGaussPT : no localization specified !"); + const MEDFileFieldLoc& loc=globs->getLocalization(_loc.c_str()); + int nbOfEnt=mst->getNumberOfElemsOfGeoType(_geo_type); + checkInRange(nbOfEnt,loc.getNumberOfGaussPoints(),globs); +} + +int MEDFileField1TSStructItem2::getNbOfIntegrationPts(const MEDFileFieldGlobsReal *globs) const +{ + if(_loc.empty()) + { + if(getPflName().empty()) + return (_start_end.second-_start_end.first)/_nb_of_entity; + else + return (_start_end.second-_start_end.first)/getPfl(globs)->getNumberOfTuples(); + } + else + { + const MEDFileFieldLoc& loc(globs->getLocalization(_loc.c_str())); + return loc.getNumberOfGaussPoints(); + } +} + +std::string MEDFileField1TSStructItem2::getPflName() const +{ + return _pfl->getName(); +} + +const DataArrayInt *MEDFileField1TSStructItem2::getPfl(const MEDFileFieldGlobsReal *globs) const +{ + if(!_pfl->isAllocated()) + { + if(_pfl->getName().empty()) + return 0; + else + return globs->getProfile(_pfl->getName().c_str()); + } + else + return _pfl; +} + +/*! + * \param [in] nbOfEntity - number of entity that can be either cells or nodes. Not other possiblity. + * \param [in] nip - number of integration points. 1 for ON_CELLS and NO_NODES + */ +void MEDFileField1TSStructItem2::checkInRange(int nbOfEntity, int nip, const MEDFileFieldGlobsReal *globs) +{ + _nb_of_entity=nbOfEntity; + if(_pfl->getName().empty()) + { + if(nbOfEntity!=(_start_end.second-_start_end.first)/nip) + throw INTERP_KERNEL::Exception("MEDFileField1TSStructItem2::checkInRange : Mismatch between number of entities and size of field !"); + return ; + } + else + { + if(!globs) + throw INTERP_KERNEL::Exception("MEDFileField1TSStructItem2::checkInRange : Presence of a profile on field whereas no globals found in file !"); + const DataArrayInt *pfl=globs->getProfile(_pfl->getName().c_str()); + if(!pfl) + throw INTERP_KERNEL::Exception("MEDFileField1TSStructItem2::checkInRange : Presence of a profile on field whereas no such profile found in file !"); + pfl->checkAllIdsInRange(0,nbOfEntity); + } +} + +bool MEDFileField1TSStructItem2::isFastlyEqual(int& startExp, INTERP_KERNEL::NormalizedCellType gt, const std::string& pflName) const +{ + if(startExp!=_start_end.first) + return false; + if(gt!=_geo_type) + return false; + if(getPflName()!=pflName) + return false; + startExp=_start_end.second; + return true; +} + +bool MEDFileField1TSStructItem2::operator==(const MEDFileField1TSStructItem2& other) const +{ + //_nb_of_entity is not taken into account here. It is not a bug, because no mesh consideration needed here to perform fast compare. + //idem for _loc. It is not an effective attribute for support comparison. + return _geo_type==other._geo_type && _start_end==other._start_end && _pfl->getName()==other._pfl->getName(); +} + +bool MEDFileField1TSStructItem2::isCellSupportEqual(const MEDFileField1TSStructItem2& other, const MEDFileFieldGlobsReal *globs) const +{ + if(_geo_type!=other._geo_type) + return false; + if(_nb_of_entity!=other._nb_of_entity) + return false; + if((_pfl->getName().empty() && !other._pfl->getName().empty()) || (!_pfl->getName().empty() && other._pfl->getName().empty())) + return false; + if(_pfl->getName().empty() && other._pfl->getName().empty()) + return true; + const DataArrayInt *pfl1(getPfl(globs)),*pfl2(other.getPfl(globs)); + return pfl1->isEqualWithoutConsideringStr(*pfl2); +} + +bool MEDFileField1TSStructItem2::isNodeSupportEqual(const MEDFileField1TSStructItem2& other, const MEDFileFieldGlobsReal *globs) const +{ + return isCellSupportEqual(other,globs); +} + +/*! + * \a objs must be non empty. \a objs should contain items having same geometric type. + */ +MEDFileField1TSStructItem2 MEDFileField1TSStructItem2::BuildAggregationOf(const std::vector<const MEDFileField1TSStructItem2 *>& objs, const MEDFileFieldGlobsReal *globs) +{ + if(objs.empty()) + throw INTERP_KERNEL::Exception("MEDFileField1TSStructItem2::BuildAggregationOf : empty input !"); + if(objs.size()==1) + return MEDFileField1TSStructItem2(*objs[0]); + INTERP_KERNEL::NormalizedCellType gt(objs[0]->_geo_type); + int nbEntityRef(objs[0]->_nb_of_entity); + std::size_t sz(objs.size()); + std::vector<const DataArrayInt *> arrs(sz); + for(std::size_t i=0;i<sz;i++) + { + const MEDFileField1TSStructItem2 *obj(objs[i]); + if(gt!=obj->_geo_type) + throw INTERP_KERNEL::Exception("MEDFileField1TSStructItem2::BuildAggregationOf : invalid situation ! All input must have the same geo type !"); + if(nbEntityRef!=obj->_nb_of_entity) + throw INTERP_KERNEL::Exception("MEDFileField1TSStructItem2::BuildAggregationOf : invalid situation ! All input must have the global nb of entity !"); + if(obj->_pfl->getName().empty()) + throw INTERP_KERNEL::Exception("MEDFileField1TSStructItem2::BuildAggregationOf : invalid situation ! Several same geo type chunk must all lie on profiles !"); + arrs[i]=globs->getProfile(obj->_pfl->getName().c_str()); + } + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> arr(DataArrayInt::Aggregate(arrs)); + arr->sort(); + int oldNbTuples(arr->getNumberOfTuples()); + arr=arr->buildUnique(); + if(oldNbTuples!=arr->getNumberOfTuples()) + throw INTERP_KERNEL::Exception("MEDFileField1TSStructItem2::BuildAggregationOf : some entities are present several times !"); + if(arr->isIdentity() && oldNbTuples==nbEntityRef) + { + std::pair<int,int> p(0,nbEntityRef); + std::string a,b; + MEDFileField1TSStructItem2 ret(gt,p,a,b); + ret._nb_of_entity=nbEntityRef; + return ret; + } + else + { + arr->setName(NEWLY_CREATED_PFL_NAME); + std::pair<int,int> p(0,oldNbTuples); + std::string a,b; + MEDFileField1TSStructItem2 ret(gt,p,a,b); + ret._nb_of_entity=nbEntityRef; + ret._pfl=arr; + return ret; + } +} + +std::size_t MEDFileField1TSStructItem2::getHeapMemorySizeWithoutChildren() const +{ + std::size_t ret(_loc.capacity()); + return ret; +} + +std::vector<const BigMemoryObject *> MEDFileField1TSStructItem2::getDirectChildrenWithNull() const +{ + std::vector<const BigMemoryObject *> ret; + ret.push_back((const DataArrayInt *)_pfl); + return ret; +} + +//= + +MEDFileField1TSStructItem::MEDFileField1TSStructItem(TypeOfField a, const std::vector< MEDFileField1TSStructItem2 >& b):_computed(false),_type(a),_items(b) +{ +} + +void MEDFileField1TSStructItem::checkWithMeshStruct(const MEDFileMeshStruct *mst, const MEDFileFieldGlobsReal *globs) +{ + switch(_type) + { + case ON_NODES: + { + int nbOfEnt=mst->getNumberOfNodes(); + if(_items.size()!=1) + throw INTERP_KERNEL::Exception("MEDFileField1TSStructItem::checkWithMeshStruct : for nodes field only one subdivision supported !"); + _items[0].checkInRange(nbOfEnt,1,globs); + break ; + } + case ON_CELLS: + { + for(std::vector< MEDFileField1TSStructItem2 >::iterator it=_items.begin();it!=_items.end();it++) + (*it).checkWithMeshStructForCells(mst,globs); + break; + } + case ON_GAUSS_NE: + { + for(std::vector< MEDFileField1TSStructItem2 >::iterator it=_items.begin();it!=_items.end();it++) + (*it).checkWithMeshStructForGaussNE(mst,globs); + break; + } + case ON_GAUSS_PT: + { + for(std::vector< MEDFileField1TSStructItem2 >::iterator it=_items.begin();it!=_items.end();it++) + (*it).checkWithMeshStructForGaussPT(mst,globs); + break; + } + default: + throw INTERP_KERNEL::Exception("MEDFileField1TSStructItem::checkWithMeshStruct : not managed field type !"); + } +} + +bool MEDFileField1TSStructItem::operator==(const MEDFileField1TSStructItem& other) const +{ + if(_type!=other._type) + return false; + if(_items.size()!=other._items.size()) + return false; + for(std::size_t i=0;i<_items.size();i++) + if(!(_items[i]==other._items[i])) + return false; + return true; +} + +bool MEDFileField1TSStructItem::isCellSupportEqual(const MEDFileField1TSStructItem& other, const MEDFileFieldGlobsReal *globs) const +{ + if(_type!=other._type) + return false; + if(_items.size()!=other._items.size()) + return false; + for(std::size_t i=0;i<_items.size();i++) + if(!(_items[i].isCellSupportEqual(other._items[i],globs))) + return false; + return true; +} + +bool MEDFileField1TSStructItem::isNodeSupportEqual(const MEDFileField1TSStructItem& other, const MEDFileFieldGlobsReal *globs) const +{ + if(_type!=other._type) + return false; + if(_items.size()!=other._items.size()) + return false; + for(std::size_t i=0;i<_items.size();i++) + if(!(_items[i].isNodeSupportEqual(other._items[i],globs))) + return false; + return true; +} + +bool MEDFileField1TSStructItem::isEntityCell() const +{ + if(_type==ON_NODES) + return false; + else + return true; +} + +class CmpGeo +{ +public: + CmpGeo(INTERP_KERNEL::NormalizedCellType geoTyp):_geo_type(geoTyp) { } + bool operator()(const std::pair< INTERP_KERNEL::NormalizedCellType, std::vector<std::size_t> > & v) const { return _geo_type==v.first; } +private: + INTERP_KERNEL::NormalizedCellType _geo_type; +}; + +MEDFileField1TSStructItem MEDFileField1TSStructItem::simplifyMeOnCellEntity(const MEDFileFieldGlobsReal *globs) const +{ + if(!isEntityCell()) + throw INTERP_KERNEL::Exception("MEDFileField1TSStructItem::simplifyMeOnCellEntity : must be on ON_CELLS, ON_GAUSS_NE or ON_GAUSS_PT !"); + std::vector< std::pair< INTERP_KERNEL::NormalizedCellType, std::vector<std::size_t> > > m; + std::size_t i=0; + for(std::vector< MEDFileField1TSStructItem2 >::const_iterator it=_items.begin();it!=_items.end();it++,i++) + { + std::vector< std::pair< INTERP_KERNEL::NormalizedCellType, std::vector<std::size_t> > >::iterator it0(std::find_if(m.begin(),m.end(),CmpGeo((*it).getGeo()))); + if(it0==m.end()) + m.push_back(std::pair< INTERP_KERNEL::NormalizedCellType, std::vector<std::size_t> >((*it).getGeo(),std::vector<std::size_t>(1,i))); + else + (*it0).second.push_back(i); + } + if(m.size()==_items.size()) + { + MEDFileField1TSStructItem ret(*this); + ret._type=ON_CELLS; + return ret; + } + std::size_t sz(m.size()); + std::vector< MEDFileField1TSStructItem2 > items(sz); + for(i=0;i<sz;i++) + { + const std::vector<std::size_t>& ids=m[i].second; + std::vector<const MEDFileField1TSStructItem2 *>objs(ids.size()); + for(std::size_t j=0;j<ids.size();j++) + objs[j]=&_items[ids[j]]; + items[i]=MEDFileField1TSStructItem2::BuildAggregationOf(objs,globs); + } + MEDFileField1TSStructItem ret(ON_CELLS,items); + ret._computed=true; + return ret; +} + +/*! + * \a this is expected to be ON_CELLS and simplified. + */ +bool MEDFileField1TSStructItem::isCompatibleWithNodesDiscr(const MEDFileField1TSStructItem& other, const MEDFileMeshStruct *meshSt, const MEDFileFieldGlobsReal *globs) const +{ + if(other._type!=ON_NODES) + throw INTERP_KERNEL::Exception("MEDFileField1TSStructItem::isCompatibleWithNodesDiscr : other must be on nodes !"); + if(other._items.size()!=1) + throw INTERP_KERNEL::Exception("MEDFileField1TSStructItem::isCompatibleWithNodesDiscr : other is on nodes but number of subparts !"); + int theFirstLevFull; + bool ret0=isFullyOnOneLev(meshSt,theFirstLevFull); + const MEDFileField1TSStructItem2& otherNodeIt(other._items[0]); + int nbOfNodes(meshSt->getNumberOfNodes()); + if(otherNodeIt.getPflName().empty()) + {//on all nodes + if(!ret0) + return false; + std::vector<bool> nodesFetched(nbOfNodes,false); + meshSt->getTheMesh()->whichAreNodesFetched(*this,globs,nodesFetched); + if(std::find(nodesFetched.begin(),nodesFetched.end(),false)==nodesFetched.end()) + return theFirstLevFull==0; + else + return false; + } + else + { + const DataArrayInt *pfl=globs->getProfile(otherNodeIt.getPflName().c_str()); + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> cpyPfl(pfl->deepCpy()); + cpyPfl->sort(); + if(cpyPfl->isIdentity() && cpyPfl->getNumberOfTuples()==nbOfNodes) + {//on all nodes also ! + if(!ret0) + return false; + return theFirstLevFull==0; + } + std::vector<bool> nodesFetched(nbOfNodes,false); + meshSt->getTheMesh()->whichAreNodesFetched(*this,globs,nodesFetched); + return cpyPfl->isFittingWith(nodesFetched); + } +} + +bool MEDFileField1TSStructItem::isFullyOnOneLev(const MEDFileMeshStruct *meshSt, int& theFirstLevFull) const +{ + if(_type!=ON_CELLS) + throw INTERP_KERNEL::Exception("MEDFileField1TSStructItem::isFullyOnOneLev : works only for ON_CELLS discretization !"); + if(_items.empty()) + throw INTERP_KERNEL::Exception("MEDFileField1TSStructItem::isFullyOnOneLev : items vector is empty !"); + int nbOfLevs(meshSt->getNumberOfLevs()); + if(nbOfLevs==0) + throw INTERP_KERNEL::Exception("MEDFileField1TSStructItem::isFullyOnOneLev : no levels in input mesh structure !"); + std::vector<int> levs(nbOfLevs); + theFirstLevFull=1; + std::set<INTERP_KERNEL::NormalizedCellType> gts; + for(std::vector< MEDFileField1TSStructItem2 >::const_iterator it=_items.begin();it!=_items.end();it++) + { + if(!(*it).getPflName().empty()) + return false; + INTERP_KERNEL::NormalizedCellType gt((*it).getGeo()); + if(gts.find(gt)!=gts.end()) + throw INTERP_KERNEL::Exception("MEDFileField1TSStructItem::isFullyOnOneLev : internal error !"); + gts.insert(gt); + int pos(meshSt->getLevelOfGeoType((*it).getGeo())); + levs[-pos]++; + } + for(int i=0;i<nbOfLevs;i++) + if(meshSt->getNumberOfGeoTypesInLev(-i)==levs[i]) + { theFirstLevFull=-i; return true; } + return false; +} + +const MEDFileField1TSStructItem2& MEDFileField1TSStructItem::operator[](std::size_t i) const +{ + if(i>=_items.size()) + throw INTERP_KERNEL::Exception("MEDFileField1TSStructItem::operator[] : input is not in valid range !"); + return _items[i]; +} + +std::size_t MEDFileField1TSStructItem::getHeapMemorySizeWithoutChildren() const +{ + std::size_t ret(_items.size()*sizeof(MEDFileField1TSStructItem2)); + return ret; +} + +std::vector<const BigMemoryObject *> MEDFileField1TSStructItem::getDirectChildrenWithNull() const +{ + std::vector<const BigMemoryObject *> ret; + for(std::vector< MEDFileField1TSStructItem2 >::const_iterator it=_items.begin();it!=_items.end();it++) + ret.push_back(&(*it)); + return ret; +} + +MEDMeshMultiLev *MEDFileField1TSStructItem::buildFromScratchDataSetSupportOnCells(const MEDFileMeshStruct *mst, const MEDFileFieldGlobsReal *globs) const +{ + std::size_t sz(_items.size()); + std::vector<INTERP_KERNEL::NormalizedCellType> a0(sz); + std::vector<const DataArrayInt *> a1(sz); + std::vector<int> a2(sz); + std::size_t i(0); + for(std::vector< MEDFileField1TSStructItem2 >::const_iterator it=_items.begin();it!=_items.end();it++,i++) + { + a0[i]=(*it).getGeo(); + a1[i]=(*it).getPfl(globs); + a2[i]=mst->getNumberOfElemsOfGeoType((*it).getGeo()); + } + return MEDMeshMultiLev::New(mst->getTheMesh(),a0,a1,a2); +} + +std::vector<INTERP_KERNEL::NormalizedCellType> MEDFileField1TSStructItem::getGeoTypes(const MEDFileMesh *m) const +{ + std::vector<INTERP_KERNEL::NormalizedCellType> ret; + if(_type==ON_NODES) + { + if(!_items.empty() && _items[0].getPflName().empty()) + { + if(m) + return m->getAllGeoTypes(); + else + return ret; + } + else + return ret; + } + for(std::vector< MEDFileField1TSStructItem2 >::const_iterator it=_items.begin();it!=_items.end();it++) + { + INTERP_KERNEL::NormalizedCellType elt((*it).getGeo()); + std::vector<INTERP_KERNEL::NormalizedCellType>::iterator it2(std::find(ret.begin(),ret.end(),elt)); + if(it2==ret.end()) + ret.push_back(elt); + } + return ret; +} + +MEDFileField1TSStructItem MEDFileField1TSStructItem::BuildItemFrom(const MEDFileAnyTypeField1TS *ref, const MEDFileMeshStruct *meshSt) +{ + std::vector< MEDFileField1TSStructItem2 > anItems; + // + std::vector< std::vector<std::string> > pfls,locs; + std::vector< std::vector<TypeOfField> > typesF; + std::vector<INTERP_KERNEL::NormalizedCellType> geoTypes; + std::vector< std::vector<std::pair<int,int> > > strtEnds=ref->getFieldSplitedByType(std::string(),geoTypes,typesF,pfls,locs); + std::size_t nbOfGeoTypes(geoTypes.size()); + if(nbOfGeoTypes==0) + throw INTERP_KERNEL::Exception("MEDFileField1TSStruct : not null by empty ref !"); + if(typesF[0].empty()) + throw INTERP_KERNEL::Exception("MEDFileField1TSStruct : internal error #1 bis !"); + TypeOfField atype(typesF[0][0]); + for(std::size_t i=0;i<nbOfGeoTypes;i++) + { + std::size_t sz=typesF[i].size(); + if(strtEnds[i].size()<1 || sz<1 || pfls[i].size()<1) + throw INTERP_KERNEL::Exception("MEDFileField1TSStruct : internal error #1 !"); + // + for(std::size_t j=0;j<sz;j++) + { + if(atype==typesF[i][j]) + anItems.push_back(MEDFileField1TSStructItem2(geoTypes[i],strtEnds[i][j],pfls[i][j],locs[i][j])); + else + throw INTERP_KERNEL::Exception("MEDFileField1TSStruct : can be applied only on single spatial discretization fields ! Call SplitPerDiscretization method !"); + } + } + MEDFileField1TSStructItem ret(atype,anItems); + try + { + ret.checkWithMeshStruct(meshSt,ref); + } + catch(INTERP_KERNEL::Exception& e) + { + std::ostringstream oss; oss << e.what() << " (" << MEDCouplingFieldDiscretization::GetTypeOfFieldRepr(ret.getType()) << ")"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + return ret; +} + +//= + +MEDFileField1TSStruct *MEDFileField1TSStruct::New(const MEDFileAnyTypeField1TS *ref, MEDFileMeshStruct *mst) +{ + return new MEDFileField1TSStruct(ref,mst); +} + +MEDFileField1TSStruct::MEDFileField1TSStruct(const MEDFileAnyTypeField1TS *ref, MEDFileMeshStruct *mst) +{ + _already_checked.push_back(MEDFileField1TSStructItem::BuildItemFrom(ref,mst)); +} + +void MEDFileField1TSStruct::checkWithMeshStruct(MEDFileMeshStruct *mst, const MEDFileFieldGlobsReal *globs) +{ + if(_already_checked.empty()) + throw INTERP_KERNEL::Exception("MEDFileField1TSStruct::checkWithMeshStruct : not correctly initialized !"); + _already_checked.back().checkWithMeshStruct(mst,globs); +} + +bool MEDFileField1TSStruct::isEqualConsideringThePast(const MEDFileAnyTypeField1TS *other, const MEDFileMeshStruct *mst) const +{ + MEDFileField1TSStructItem b(MEDFileField1TSStructItem::BuildItemFrom(other,mst)); + for(std::vector<MEDFileField1TSStructItem>::const_iterator it=_already_checked.begin();it!=_already_checked.end();it++) + { + if((*it)==b) + return true; + } + return false; +} + +/*! + * Not const because \a other structure will be added to the \c _already_checked attribute in case of success. + */ +bool MEDFileField1TSStruct::isSupportSameAs(const MEDFileAnyTypeField1TS *other, const MEDFileMeshStruct *meshSt) +{ + if(_already_checked.empty()) + throw INTERP_KERNEL::Exception("MEDFileField1TSStruct::isSupportSameAs : no ref !"); + MEDFileField1TSStructItem b(MEDFileField1TSStructItem::BuildItemFrom(other,meshSt)); + if(!_already_checked[0].isEntityCell() || !b.isEntityCell()) + throw INTERP_KERNEL::Exception("MEDFileField1TSStruct::isSupportSameAs : only available on cell entities !"); + MEDFileField1TSStructItem other1(b.simplifyMeOnCellEntity(other)); + int found=-1,i=0; + for(std::vector<MEDFileField1TSStructItem>::const_iterator it=_already_checked.begin();it!=_already_checked.end();it++,i++) + if((*it).isComputed()) + { found=i; break; } + bool ret(false); + if(found==-1) + { + MEDFileField1TSStructItem this1(_already_checked[0].simplifyMeOnCellEntity(other)); + ret=this1.isCellSupportEqual(other1,other); + if(ret) + _already_checked.push_back(this1); + } + else + ret=_already_checked[found].isCellSupportEqual(other1,other); + if(ret) + _already_checked.push_back(b); + return ret; +} + +/*! + * \param [in] other - a field with only one spatial discretization : ON_NODES. + */ +bool MEDFileField1TSStruct::isCompatibleWithNodesDiscr(const MEDFileAnyTypeField1TS *other, const MEDFileMeshStruct *meshSt) +{ + if(_already_checked.empty()) + throw INTERP_KERNEL::Exception("MEDFileField1TSStruct::isCompatibleWithNodesDiscr : no ref !"); + MEDFileField1TSStructItem other1(MEDFileField1TSStructItem::BuildItemFrom(other,meshSt)); + if(_already_checked[0].isEntityCell()) + { + int found=-1,i=0; + for(std::vector<MEDFileField1TSStructItem>::const_iterator it=_already_checked.begin();it!=_already_checked.end();it++,i++) + if((*it).isComputed()) + { found=i; break; } + bool ret(false); + if(found==-1) + { + MEDFileField1TSStructItem this1(_already_checked[0].simplifyMeOnCellEntity(other)); + ret=this1.isCompatibleWithNodesDiscr(other1,meshSt,other); + if(ret) + _already_checked.push_back(this1); + } + else + ret=_already_checked[found].isCompatibleWithNodesDiscr(other1,meshSt,other); + if(ret) + _already_checked.push_back(other1); + return ret; + } + else + return _already_checked[0].isNodeSupportEqual(other1,other); +} + +std::size_t MEDFileField1TSStruct::getHeapMemorySizeWithoutChildren() const +{ + std::size_t ret(_already_checked.capacity()*sizeof(MEDFileField1TSStructItem)); + return ret; +} + +std::vector<const BigMemoryObject *> MEDFileField1TSStruct::getDirectChildrenWithNull() const +{ + std::vector<const BigMemoryObject *> ret; + for(std::vector<MEDFileField1TSStructItem>::const_iterator it=_already_checked.begin();it!=_already_checked.end();it++) + ret.push_back(&(*it)); + return ret; +} + +MEDMeshMultiLev *MEDFileField1TSStruct::buildFromScratchDataSetSupport(const MEDFileMeshStruct *mst, const MEDFileFieldGlobsReal *globs) const +{ + if(_already_checked.empty()) + throw INTERP_KERNEL::Exception("MEDFileField1TSStruct::buildFromScratchDataSetSupport : No outline structure in this !"); + int pos0(-1),pos1(-1); + if(presenceOfCellDiscr(pos0)) + { + MEDCouplingAutoRefCountObjectPtr<MEDMeshMultiLev> ret(_already_checked[pos0].buildFromScratchDataSetSupportOnCells(mst,globs)); + if(presenceOfPartialNodeDiscr(pos1)) + ret->setNodeReduction(_already_checked[pos1][0].getPfl(globs)); + return ret.retn(); + } + else + { + if(!presenceOfPartialNodeDiscr(pos1)) + {//we have only all nodes, no cell definition info -> all existing levels !; + return MEDMeshMultiLev::New(mst->getTheMesh(),mst->getTheMesh()->getNonEmptyLevels()); + } + else + return MEDMeshMultiLev::NewOnlyOnNode(mst->getTheMesh(),_already_checked[pos1][0].getPfl(globs)); + } +} + +bool MEDFileField1TSStruct::isDataSetSupportFastlyEqualTo(const MEDFileField1TSStruct& other, const MEDFileFieldGlobsReal *globs) const +{ + int b0,b1; + bool a0(presenceOfCellDiscr(b0)),a1(presenceOfPartialNodeDiscr(b1)); + int d0,d1; + bool c0(other.presenceOfCellDiscr(d0)),c1(other.presenceOfPartialNodeDiscr(d1)); + if(a0!=c0 || a1!=c1) + return false; + if(a0) + if(!_already_checked[b0].isCellSupportEqual(other._already_checked[d0],globs)) + return false; + if(a1) + if(!_already_checked[b1].isNodeSupportEqual(other._already_checked[d1],globs)) + return false; + return true; +} + +std::vector<INTERP_KERNEL::NormalizedCellType> MEDFileField1TSStruct::getGeoTypes(const MEDFileMesh *m) const +{ + std::vector<INTERP_KERNEL::NormalizedCellType> ret; + for(std::vector<MEDFileField1TSStructItem>::const_iterator it=_already_checked.begin();it!=_already_checked.end();it++) + { + std::vector<INTERP_KERNEL::NormalizedCellType> ret2((*it).getGeoTypes(m)); + for(std::vector<INTERP_KERNEL::NormalizedCellType>::const_iterator it2=ret2.begin();it2!=ret2.end();it2++) + { + if(*it2==INTERP_KERNEL::NORM_ERROR) + continue; + std::vector<INTERP_KERNEL::NormalizedCellType>::iterator it3(std::find(ret.begin(),ret.end(),*it2)); + if(it3==ret.end()) + ret.push_back(*it2); + } + } + return ret; +} + +/*! + * Returns true if presence in \a this of discretization ON_CELLS, ON_GAUSS_PT, ON_GAUSS_NE. + * If true is returned the pos of the easiest is returned. The easiest is the first element in \a this having the less splitted subparts. + */ +bool MEDFileField1TSStruct::presenceOfCellDiscr(int& pos) const +{ + std::size_t refSz(std::numeric_limits<std::size_t>::max()); + bool ret(false); + int i(0); + for(std::vector<MEDFileField1TSStructItem>::const_iterator it=_already_checked.begin();it!=_already_checked.end();it++,i++) + { + if((*it).getType()!=ON_NODES) + { + ret=true; + std::size_t sz((*it).getNumberOfItems()); + if(refSz>sz) + { pos=i; refSz=sz; } + } + } + if(refSz==0) + throw INTERP_KERNEL::Exception("MEDFileField1TSStruct::presenceOfCellDiscr : an element in this on entity CELL is empty !"); + return ret; +} + +/*! + * Returns true if presence in \a this of discretization ON_NODES. + * If true is returned the pos of the first element containing the single subpart. + */ +bool MEDFileField1TSStruct::presenceOfPartialNodeDiscr(int& pos) const +{ + int i(0); + for(std::vector<MEDFileField1TSStructItem>::const_iterator it=_already_checked.begin();it!=_already_checked.end();it++,i++) + { + if((*it).getType()==ON_NODES) + { + std::size_t sz((*it).getNumberOfItems()); + if(sz==1) + { + if(!(*it)[0].getPflName().empty()) + { pos=i; return true; } + } + else + throw INTERP_KERNEL::Exception("MEDFileField1TSStruct::presenceOfPartialNodeDiscr : an element in this on entity NODE is split into several parts !"); + } + } + return false; +} + +//= + +MEDFileFastCellSupportComparator *MEDFileFastCellSupportComparator::New(const MEDFileMeshStruct *m, const MEDFileAnyTypeFieldMultiTS *ref) +{ + return new MEDFileFastCellSupportComparator(m,ref); +} + +MEDFileFastCellSupportComparator::MEDFileFastCellSupportComparator(const MEDFileMeshStruct *m, const MEDFileAnyTypeFieldMultiTS *ref) +{ + if(!m) + throw INTERP_KERNEL::Exception("MEDFileFastCellSupportComparator constructor : null input mesh struct !"); + _mesh_comp=const_cast<MEDFileMeshStruct *>(m); _mesh_comp->incrRef(); + int nbPts=ref->getNumberOfTS(); + _f1ts_cmps.resize(nbPts); + for(int i=0;i<nbPts;i++) + { + MEDCouplingAutoRefCountObjectPtr<MEDFileAnyTypeField1TS> elt=ref->getTimeStepAtPos(i); + try + { + _f1ts_cmps[i]=MEDFileField1TSStruct::New(elt,_mesh_comp); + _f1ts_cmps[i]->checkWithMeshStruct(_mesh_comp,elt); + } + catch(INTERP_KERNEL::Exception& e) + { + std::ostringstream oss; oss << "Problem in field with name \"" << ref->getName() << "\"" << std::endl; + oss << "More Details : " << e.what(); + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + } +} + +std::size_t MEDFileFastCellSupportComparator::getHeapMemorySizeWithoutChildren() const +{ + std::size_t ret(_f1ts_cmps.capacity()*sizeof(MEDCouplingAutoRefCountObjectPtr<MEDFileField1TSStruct>)); + return ret; +} + +std::vector<const BigMemoryObject *> MEDFileFastCellSupportComparator::getDirectChildrenWithNull() const +{ + std::vector<const BigMemoryObject *> ret; + const MEDFileMeshStruct *mst(_mesh_comp); + if(mst) + ret.push_back(mst); + for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileField1TSStruct> >::const_iterator it=_f1ts_cmps.begin();it!=_f1ts_cmps.end();it++) + ret.push_back((const MEDFileField1TSStruct *)*it); + return ret; +} + +bool MEDFileFastCellSupportComparator::isEqual(const MEDFileAnyTypeFieldMultiTS *other) +{ + int nbPts=other->getNumberOfTS(); + if(nbPts!=(int)_f1ts_cmps.size()) + { + std::ostringstream oss; oss << "MEDFileFastCellSupportComparator::isEqual : unexpected nb of time steps in input ! Should be " << _f1ts_cmps.size() << " it is in reality " << nbPts << " !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + for(int i=0;i<nbPts;i++) + { + MEDCouplingAutoRefCountObjectPtr<MEDFileAnyTypeField1TS> elt=other->getTimeStepAtPos(i); + if(!_f1ts_cmps[i]->isEqualConsideringThePast(elt,_mesh_comp)) + if(!_f1ts_cmps[i]->isSupportSameAs(elt,_mesh_comp)) + return false; + } + return true; +} + +bool MEDFileFastCellSupportComparator::isCompatibleWithNodesDiscr(const MEDFileAnyTypeFieldMultiTS *other) +{ + int nbPts=other->getNumberOfTS(); + if(nbPts!=(int)_f1ts_cmps.size()) + { + std::ostringstream oss; oss << "MEDFileFastCellSupportComparator::isCompatibleWithNodesDiscr : unexpected nb of time steps in input ! Should be " << _f1ts_cmps.size() << " it is in reality " << nbPts << " !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + for(int i=0;i<nbPts;i++) + { + MEDCouplingAutoRefCountObjectPtr<MEDFileAnyTypeField1TS> elt=other->getTimeStepAtPos(i); + if(!_f1ts_cmps[i]->isCompatibleWithNodesDiscr(elt,_mesh_comp)) + return false; + } + return true; +} + +MEDMeshMultiLev *MEDFileFastCellSupportComparator::buildFromScratchDataSetSupport(int timeStepId, const MEDFileFieldGlobsReal *globs) const +{ + if(timeStepId<0 || timeStepId>=(int)_f1ts_cmps.size()) + { + std::ostringstream oss; oss << "MEDFileFastCellSupportComparator::buildFromScratchDataSetSupport : requested time step id #" << timeStepId << " is not in [0," << _f1ts_cmps.size() << ") !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + const MEDFileField1TSStruct *obj(_f1ts_cmps[timeStepId]); + if(!obj) + { + std::ostringstream oss; oss << "MEDFileFastCellSupportComparator::buildFromScratchDataSetSupport : at time step id #" << timeStepId << " no field structure overview defined !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + return obj->buildFromScratchDataSetSupport(_mesh_comp,globs); +} + +bool MEDFileFastCellSupportComparator::isDataSetSupportEqualToThePreviousOne(int timeStepId, const MEDFileFieldGlobsReal *globs) const +{ + if(timeStepId<=0 || timeStepId>=(int)_f1ts_cmps.size()) + { + std::ostringstream oss; oss << "MEDFileFastCellSupportComparator::isDataSetSupportEqualToThePreviousOne : requested time step id #" << timeStepId << " is not in [1," << _f1ts_cmps.size() << ") !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + const MEDFileField1TSStruct *obj(_f1ts_cmps[timeStepId]); + const MEDFileField1TSStruct *objRef(_f1ts_cmps[timeStepId-1]); + return objRef->isDataSetSupportFastlyEqualTo(*obj,globs); +} + +int MEDFileFastCellSupportComparator::getNumberOfTS() const +{ + return _f1ts_cmps.size(); +} + +std::vector<INTERP_KERNEL::NormalizedCellType> MEDFileFastCellSupportComparator::getGeoTypesAt(int timeStepId, const MEDFileMesh *m) const +{ + if(timeStepId<0 || timeStepId>=(int)_f1ts_cmps.size()) + { + std::ostringstream oss; oss << "MEDFileFastCellSupportComparator::getGeoTypesAt : requested time step id #" << timeStepId << " is not in [0," << _f1ts_cmps.size() << ") !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + const MEDFileField1TSStruct *elt(_f1ts_cmps[timeStepId]); + if(!elt) + { + std::ostringstream oss; oss << "MEDFileFastCellSupportComparator::getGeoTypesAt : requested time step id #" << timeStepId << " points to a NULL pointer !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + return elt->getGeoTypes(m); +} diff --git a/src/medtool/src/MEDLoader/MEDFileFieldOverView.hxx b/src/medtool/src/MEDLoader/MEDFileFieldOverView.hxx new file mode 100644 index 000000000..25384f4bd --- /dev/null +++ b/src/medtool/src/MEDLoader/MEDFileFieldOverView.hxx @@ -0,0 +1,311 @@ +// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 +// 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 __MEDFILEFIELDOVERVIEW_HXX__ +#define __MEDFILEFIELDOVERVIEW_HXX__ + +#include "MEDLoaderDefines.hxx" + +#include "MEDCouplingAutoRefCountObjectPtr.hxx" +#include "MEDCouplingRefCountObject.hxx" +#include "MEDCoupling1GTUMesh.hxx" + +#include "NormalizedUnstructuredMesh.hxx" +#include "InterpKernelException.hxx" + +#include <vector> + +namespace ParaMEDMEM +{ + class DataArrayInt; + class MEDCouplingMesh; + class MEDFileMesh; + class MEDFileUMesh; + class MEDFileCMesh; + class MEDFileStructuredMesh; + class MEDFileCurveLinearMesh; + class MEDFileFieldGlobs; + class MEDFileFieldGlobsReal; + class MEDFileAnyTypeField1TS; + class MEDFileAnyTypeFieldMultiTS; + + class MEDFileMeshStruct : public RefCountObject + { + public: + MEDLOADER_EXPORT static MEDFileMeshStruct *New(const MEDFileMesh *mesh); + std::size_t getHeapMemorySizeWithoutChildren() const; + std::vector<const BigMemoryObject *> getDirectChildrenWithNull() const; + const MEDFileMesh *getTheMesh() const { return _mesh; } + int getNumberOfNodes() const { return _nb_nodes; } + bool doesManageGeoType(INTERP_KERNEL::NormalizedCellType t) const; + int getNumberOfElemsOfGeoType(INTERP_KERNEL::NormalizedCellType t) const; + int getLevelOfGeoType(INTERP_KERNEL::NormalizedCellType t) const; + int getNumberOfLevs() const; + int getNumberOfGeoTypesInLev(int relativeLev) const; + // non const methods + void appendIfImplicitType(INTERP_KERNEL::NormalizedCellType t); + private: + MEDFileMeshStruct(const MEDFileMesh *mesh); + private: + const MEDFileMesh *_mesh; + std::string _name; + int _nb_nodes; + std::vector< std::vector<int> > _geo_types_distrib; + }; + + class MEDFileField1TSStructItem; + + class MEDMeshMultiLev : public RefCountObject + { + public: + std::size_t getHeapMemorySizeWithoutChildren() const; + std::vector<const BigMemoryObject *> getDirectChildrenWithNull() const; + public: + static MEDMeshMultiLev *New(const MEDFileMesh *m, const std::vector<INTERP_KERNEL::NormalizedCellType>& gts, const std::vector<const DataArrayInt *>& pfls, const std::vector<int>& nbEntities); + static MEDMeshMultiLev *New(const MEDFileMesh *m, const std::vector<int>& levs); + static MEDMeshMultiLev *NewOnlyOnNode(const MEDFileMesh *m, const DataArrayInt *pflOnNode); + void setNodeReduction(const DataArrayInt *nr); + void setCellReduction(const DataArrayInt *cr); + bool isFastlyTheSameStruct(const MEDFileField1TSStructItem& fst, const MEDFileFieldGlobsReal *globs) const; + MEDLOADER_EXPORT DataArray *buildDataArray(const MEDFileField1TSStructItem& fst, const MEDFileFieldGlobsReal *globs, const DataArray *vals) const; + MEDLOADER_EXPORT void retrieveFamilyIdsOnCells(DataArrayInt *& famIds, bool& isWithoutCopy) const; + MEDLOADER_EXPORT void retrieveNumberIdsOnCells(DataArrayInt *& numIds, bool& isWithoutCopy) const; + MEDLOADER_EXPORT void retrieveFamilyIdsOnNodes(DataArrayInt *& famIds, bool& isWithoutCopy) const; + MEDLOADER_EXPORT void retrieveNumberIdsOnNodes(DataArrayInt *& numIds, bool& isWithoutCopy) const; + MEDLOADER_EXPORT std::vector< INTERP_KERNEL::NormalizedCellType > getGeoTypes() const; + void setFamilyIdsOnCells(DataArrayInt *famIds); + void setNumberIdsOnCells(DataArrayInt *numIds); + void setFamilyIdsOnNodes(DataArrayInt *famIds); + void setNumberIdsOnNodes(DataArrayInt *numIds); + virtual void selectPartOfNodes(const DataArrayInt *pflNodes) = 0; + virtual MEDMeshMultiLev *prepare() const = 0; + int getNumberOfCells(INTERP_KERNEL::NormalizedCellType t) const; + int getNumberOfNodes() const; + protected: + std::string getPflNameOfId(int id) const; + DataArray *constructDataArray(const MEDFileField1TSStructItem& fst, const MEDFileFieldGlobsReal *globs, const DataArray *vals) const; + virtual void appendVertices(const DataArrayInt *verticesToAdd, DataArrayInt *nr); + protected: + MEDMeshMultiLev(const MEDFileMesh *mesh); + MEDMeshMultiLev(const MEDMeshMultiLev& other); + MEDMeshMultiLev(const MEDFileMesh *mesh, int nbNodes, const std::vector<INTERP_KERNEL::NormalizedCellType>& gts, const std::vector<const DataArrayInt *>& pfls, const std::vector<int>& nbEntities); + protected: + const MEDFileMesh *_mesh; + std::vector< MEDCouplingAutoRefCountObjectPtr<DataArrayInt> > _pfls; + std::vector< INTERP_KERNEL::NormalizedCellType > _geo_types; + std::vector<int> _nb_entities; + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> _node_reduction; + int _nb_nodes; + // + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> _cell_fam_ids; + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> _cell_num_ids; + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> _node_fam_ids; + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> _node_num_ids; + public: + MEDLOADER_EXPORT static const int PARAMEDMEM_2_VTKTYPE_LGTH=34; + MEDLOADER_EXPORT static const unsigned char PARAMEDMEM_2_VTKTYPE[PARAMEDMEM_2_VTKTYPE_LGTH]; + MEDLOADER_EXPORT static const unsigned char HEXA27_PERM_ARRAY[27]; + }; + + class MEDStructuredMeshMultiLev; + + class MEDUMeshMultiLev : public MEDMeshMultiLev + { + public: + static MEDUMeshMultiLev *New(const MEDFileUMesh *m, const std::vector<int>& levs); + static MEDUMeshMultiLev *New(const MEDFileUMesh *m, const std::vector<INTERP_KERNEL::NormalizedCellType>& gts, const std::vector<const DataArrayInt *>& pfls, const std::vector<int>& nbEntities); + void selectPartOfNodes(const DataArrayInt *pflNodes); + MEDMeshMultiLev *prepare() const; + MEDUMeshMultiLev(const MEDStructuredMeshMultiLev& other, const MEDCouplingAutoRefCountObjectPtr<MEDCoupling1GTUMesh>& part); + MEDLOADER_EXPORT bool buildVTUArrays(DataArrayDouble *& coords, DataArrayByte *&types, DataArrayInt *&cellLocations, DataArrayInt *& cells, DataArrayInt *&faceLocations, DataArrayInt *&faces) const; + protected: + void appendVertices(const DataArrayInt *verticesToAdd, DataArrayInt *nr); + private: + void reorderNodesIfNecessary(MEDCouplingAutoRefCountObjectPtr<DataArrayDouble>& coords, DataArrayInt *nodalConnVTK, DataArrayInt *polyhedNodalConnVTK) const; + private: + MEDUMeshMultiLev(const MEDUMeshMultiLev& other); + MEDUMeshMultiLev(const MEDFileUMesh *m, const std::vector<int>& levs); + MEDUMeshMultiLev(const MEDFileUMesh *m, const std::vector<INTERP_KERNEL::NormalizedCellType>& gts, const std::vector<const DataArrayInt *>& pfls, const std::vector<int>& nbEntities); + private: + std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCoupling1GTUMesh> > _parts; + //! this attribute is used only for mesh with no cells but having coordinates. For classical umeshes those pointer is equal to pointer of coordinates of instances in this->_parts. + MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> _coords; + }; + + class MEDStructuredMeshMultiLev : public MEDMeshMultiLev + { + public: + void selectPartOfNodes(const DataArrayInt *pflNodes); + virtual std::vector<int> getNodeGridStructure() const = 0; + protected: + MEDStructuredMeshMultiLev(const MEDStructuredMeshMultiLev& other); + MEDStructuredMeshMultiLev(const MEDFileStructuredMesh *m, const std::vector<int>& lev); + MEDStructuredMeshMultiLev(const MEDFileStructuredMesh *m, int nbOfNodes, const std::vector<INTERP_KERNEL::NormalizedCellType>& gts, const std::vector<const DataArrayInt *>& pfls, const std::vector<int>& nbEntities); + void dealWithImplicitUnstructuredMesh(const MEDFileMesh *m); + protected: + void moveFaceToCell() const; + bool prepareForImplicitUnstructuredMeshCase(MEDMeshMultiLev *&ret) const; + private: + void initStdFieldOfIntegers(const MEDFileStructuredMesh *m); + protected: + bool _is_internal; + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> _face_fam_ids; + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> _face_num_ids; + }; + + class MEDCMeshMultiLev : public MEDStructuredMeshMultiLev + { + public: + static MEDCMeshMultiLev *New(const MEDFileCMesh *m, const std::vector<int>& levs); + static MEDCMeshMultiLev *New(const MEDFileCMesh *m, const std::vector<INTERP_KERNEL::NormalizedCellType>& gts, const std::vector<const DataArrayInt *>& pfls, const std::vector<int>& nbEntities); + std::vector<int> getNodeGridStructure() const; + MEDMeshMultiLev *prepare() const; + MEDLOADER_EXPORT std::vector< DataArrayDouble * > buildVTUArrays(bool& isInternal) const; + private: + MEDCMeshMultiLev(const MEDCMeshMultiLev& other); + MEDCMeshMultiLev(const MEDFileCMesh *m, const std::vector<int>& levs); + MEDCMeshMultiLev(const MEDFileCMesh *m, const std::vector<INTERP_KERNEL::NormalizedCellType>& gts, const std::vector<const DataArrayInt *>& pfls, const std::vector<int>& nbEntities); + private: + std::vector< MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> > _coords; + }; + + class MEDCurveLinearMeshMultiLev : public MEDStructuredMeshMultiLev + { + public: + static MEDCurveLinearMeshMultiLev *New(const MEDFileCurveLinearMesh *m, const std::vector<int>& levs); + static MEDCurveLinearMeshMultiLev *New(const MEDFileCurveLinearMesh *m, const std::vector<INTERP_KERNEL::NormalizedCellType>& gts, const std::vector<const DataArrayInt *>& pfls , const std::vector<int>& nbEntities); + std::vector<int> getNodeGridStructure() const; + MEDMeshMultiLev *prepare() const; + MEDLOADER_EXPORT void buildVTUArrays(DataArrayDouble *&coords, std::vector<int>& nodeStrct, bool& isInternal) const; + private: + MEDCurveLinearMeshMultiLev(const MEDCurveLinearMeshMultiLev& other); + MEDCurveLinearMeshMultiLev(const MEDFileCurveLinearMesh *m, const std::vector<int>& levs); + MEDCurveLinearMeshMultiLev(const MEDFileCurveLinearMesh *m, const std::vector<INTERP_KERNEL::NormalizedCellType>& gts, const std::vector<const DataArrayInt *>& pfls, const std::vector<int>& nbEntities); + private: + MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> _coords; + std::vector<int> _structure; + }; + + class MEDFileField1TSStructItem2 : public BigMemoryObject + { + public: + MEDFileField1TSStructItem2(); + MEDFileField1TSStructItem2(INTERP_KERNEL::NormalizedCellType a, const std::pair<int,int>& b, const std::string& pfl, const std::string& loc); + void checkWithMeshStructForCells(const MEDFileMeshStruct *mst, const MEDFileFieldGlobsReal *globs); + void checkWithMeshStructForGaussNE(const MEDFileMeshStruct *mst, const MEDFileFieldGlobsReal *globs); + void checkWithMeshStructForGaussPT(const MEDFileMeshStruct *mst, const MEDFileFieldGlobsReal *globs); + // + MEDLOADER_EXPORT std::size_t getHeapMemorySizeWithoutChildren() const; + MEDLOADER_EXPORT std::vector<const BigMemoryObject *> getDirectChildrenWithNull() const; + // + const DataArrayInt *getPfl(const MEDFileFieldGlobsReal *globs) const; + INTERP_KERNEL::NormalizedCellType getGeo() const { return _geo_type; } + int getNbEntity() const { return _nb_of_entity; } + const std::pair<int,int>& getStartStop() const { return _start_end; } + std::string getPflName() const; + int getNbOfIntegrationPts(const MEDFileFieldGlobsReal *globs) const; + //! warning this method also set _nb_of_entity attribute ! + void checkInRange(int nbOfEntity, int nip, const MEDFileFieldGlobsReal *globs); + bool isFastlyEqual(int& startExp, INTERP_KERNEL::NormalizedCellType gt, const std::string& pflName) const; + bool operator==(const MEDFileField1TSStructItem2& other) const; + bool isCellSupportEqual(const MEDFileField1TSStructItem2& other, const MEDFileFieldGlobsReal *globs) const; + bool isNodeSupportEqual(const MEDFileField1TSStructItem2& other, const MEDFileFieldGlobsReal *globs) const; + static MEDFileField1TSStructItem2 BuildAggregationOf(const std::vector<const MEDFileField1TSStructItem2 *>& objs, const MEDFileFieldGlobsReal *globs); + public: + static const char NEWLY_CREATED_PFL_NAME[]; + private: + INTERP_KERNEL::NormalizedCellType _geo_type; + std::pair<int,int> _start_end; + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> _pfl; + std::string _loc; + int _nb_of_entity; + }; + + class MEDFileField1TSStructItem : public BigMemoryObject + { + public: + MEDFileField1TSStructItem():_computed(false),_type(ON_CELLS) { } + MEDFileField1TSStructItem(TypeOfField a, const std::vector< MEDFileField1TSStructItem2 >& b); + void checkWithMeshStruct(const MEDFileMeshStruct *mst, const MEDFileFieldGlobsReal *globs); + bool operator==(const MEDFileField1TSStructItem& other) const; + MEDLOADER_EXPORT std::size_t getHeapMemorySizeWithoutChildren() const; + MEDLOADER_EXPORT std::vector<const BigMemoryObject *> getDirectChildrenWithNull() const; + bool isEntityCell() const; + bool isComputed() const { return _computed; } + TypeOfField getType() const { return _type; } + std::size_t getNumberOfItems() const { return _items.size(); } + const MEDFileField1TSStructItem2& operator[](std::size_t i) const; + // + bool isCellSupportEqual(const MEDFileField1TSStructItem& other, const MEDFileFieldGlobsReal *globs) const; + bool isNodeSupportEqual(const MEDFileField1TSStructItem& other, const MEDFileFieldGlobsReal *globs) const; + MEDFileField1TSStructItem simplifyMeOnCellEntity(const MEDFileFieldGlobsReal *globs) const; + bool isCompatibleWithNodesDiscr(const MEDFileField1TSStructItem& other, const MEDFileMeshStruct *meshSt, const MEDFileFieldGlobsReal *globs) const; + bool isFullyOnOneLev(const MEDFileMeshStruct *meshSt, int& theFirstLevFull) const; + std::vector<INTERP_KERNEL::NormalizedCellType> getGeoTypes(const MEDFileMesh *m) const; + MEDLOADER_EXPORT MEDMeshMultiLev *buildFromScratchDataSetSupportOnCells(const MEDFileMeshStruct *mst, const MEDFileFieldGlobsReal *globs) const; + MEDLOADER_EXPORT static MEDFileField1TSStructItem BuildItemFrom(const MEDFileAnyTypeField1TS *ref, const MEDFileMeshStruct *meshSt); + private: + bool _computed; + TypeOfField _type; + std::vector< MEDFileField1TSStructItem2 > _items; + }; + + class MEDFileField1TSStruct : public RefCountObject + { + public: + static MEDFileField1TSStruct *New(const MEDFileAnyTypeField1TS *ref, MEDFileMeshStruct *mst); + void checkWithMeshStruct(MEDFileMeshStruct *mst, const MEDFileFieldGlobsReal *globs); + std::size_t getHeapMemorySizeWithoutChildren() const; + std::vector<const BigMemoryObject *> getDirectChildrenWithNull() const; + bool isEqualConsideringThePast(const MEDFileAnyTypeField1TS *other, const MEDFileMeshStruct *mst) const; + bool isSupportSameAs(const MEDFileAnyTypeField1TS *other, const MEDFileMeshStruct *meshSt); + bool isCompatibleWithNodesDiscr(const MEDFileAnyTypeField1TS *other, const MEDFileMeshStruct *meshSt); + MEDLOADER_EXPORT MEDMeshMultiLev *buildFromScratchDataSetSupport(const MEDFileMeshStruct *mst, const MEDFileFieldGlobsReal *globs) const; + bool isDataSetSupportFastlyEqualTo(const MEDFileField1TSStruct& other, const MEDFileFieldGlobsReal *globs) const; + std::vector<INTERP_KERNEL::NormalizedCellType> getGeoTypes(const MEDFileMesh *m) const; + private: + MEDFileField1TSStruct(const MEDFileAnyTypeField1TS *ref, MEDFileMeshStruct *mst); + bool presenceOfCellDiscr(int& pos) const; + bool presenceOfPartialNodeDiscr(int& pos) const; + private: + std::vector<MEDFileField1TSStructItem> _already_checked; + }; + + class MEDFileFastCellSupportComparator : public RefCountObject + { + public: + MEDLOADER_EXPORT static MEDFileFastCellSupportComparator *New(const MEDFileMeshStruct *m, const MEDFileAnyTypeFieldMultiTS *ref); + MEDLOADER_EXPORT MEDMeshMultiLev *buildFromScratchDataSetSupport(int timeStepId, const MEDFileFieldGlobsReal *globs) const; + MEDLOADER_EXPORT bool isDataSetSupportEqualToThePreviousOne(int timeStepId, const MEDFileFieldGlobsReal *globs) const; + MEDLOADER_EXPORT int getNumberOfTS() const; + MEDLOADER_EXPORT std::vector<INTERP_KERNEL::NormalizedCellType> getGeoTypesAt(int timeStepId, const MEDFileMesh *m) const; + bool isEqual(const MEDFileAnyTypeFieldMultiTS *other); + bool isCompatibleWithNodesDiscr(const MEDFileAnyTypeFieldMultiTS *other); + std::size_t getHeapMemorySizeWithoutChildren() const; + std::vector<const BigMemoryObject *> getDirectChildrenWithNull() const; + private: + MEDFileFastCellSupportComparator(const MEDFileMeshStruct *m, const MEDFileAnyTypeFieldMultiTS *ref); + private: + MEDCouplingAutoRefCountObjectPtr<MEDFileMeshStruct> _mesh_comp; + std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileField1TSStruct> > _f1ts_cmps; + }; +} + +#endif diff --git a/src/medtool/src/MEDLoader/MEDFileJoint.cxx b/src/medtool/src/MEDLoader/MEDFileJoint.cxx new file mode 100644 index 000000000..2db32825a --- /dev/null +++ b/src/medtool/src/MEDLoader/MEDFileJoint.cxx @@ -0,0 +1,839 @@ +// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// + +#include "MEDFileJoint.hxx" +#include "MEDFileUtilities.hxx" +#include "MEDLoader.hxx" +#include "MEDLoaderBase.hxx" +#include "MEDFileSafeCaller.txx" + +#include "CellModel.hxx" +#include "InterpKernelAutoPtr.hxx" + +extern med_geometry_type typmai[MED_N_CELL_FIXED_GEO]; +extern INTERP_KERNEL::NormalizedCellType typmai2[MED_N_CELL_FIXED_GEO]; +extern med_geometry_type typmai3[34]; + +using namespace ParaMEDMEM; + +std::size_t MEDFileJointCorrespondence::getHeapMemorySizeWithoutChildren() const +{ + return sizeof(MEDCouplingAutoRefCountObjectPtr<DataArrayInt>); +} + +std::vector<const BigMemoryObject *> MEDFileJointCorrespondence::getDirectChildrenWithNull() const +{ + return std::vector<const BigMemoryObject *>(); +} + +MEDFileJointCorrespondence::MEDFileJointCorrespondence(): + _is_nodal( true ), + _loc_geo_type( INTERP_KERNEL::NORM_ERROR ), + _rem_geo_type( INTERP_KERNEL::NORM_ERROR ) +{ +} + +/*! + * Constructor. + * \param [in] correspondence - correspondence. + * \param [in] is_nodal - is the correspondence of cells or nodes. + * \param [in] loc_geo_type - the local geometry type of correspondence. + * \param [in] rem_geo_type - the remote geometry type of correspondence. + */ +MEDFileJointCorrespondence::MEDFileJointCorrespondence(DataArrayInt* correspondence, + bool isNodal, + INTERP_KERNEL::NormalizedCellType loc_geo_type, + INTERP_KERNEL::NormalizedCellType rem_geo_type): + _is_nodal( isNodal ), + _loc_geo_type( loc_geo_type ), + _rem_geo_type( rem_geo_type ) +{ + MEDFileJointCorrespondence::setCorrespondence( correspondence ); +} + +MEDFileJointCorrespondence* MEDFileJointCorrespondence::New(DataArrayInt* correspondence, + INTERP_KERNEL::NormalizedCellType loc_geo_type, + INTERP_KERNEL::NormalizedCellType rem_geo_type) +{ + return new MEDFileJointCorrespondence(correspondence, /*isNodal=*/false, loc_geo_type, rem_geo_type ); +} + +/*! + * Returns a new MEDFileJointCorrespondence of nodes + */ +MEDFileJointCorrespondence *MEDFileJointCorrespondence::New(DataArrayInt* correspondence) +{ + return new MEDFileJointCorrespondence(correspondence); +} + +/*! + * Returns a new undefined MEDFileJointCorrespondence + */ + +MEDFileJointCorrespondence *MEDFileJointCorrespondence::New() +{ + return new MEDFileJointCorrespondence(); +} + +/*! + * Writes \a this joint into a MED file specified by its name. + * \param [in] fileName - the MED file name. + * \param [in] mode - the writing mode. For more on \a mode, see \ref AdvMEDLoaderBasics. + * - 2 - erase; an existing file is removed. + * - 1 - append; same data should not be present in an existing file. + * - 0 - overwrite; same data present in an existing file is overwritten. + * \param [in] order - order. + * \param [in] iteration - iteration. + * \throw If the mesh name is not set. + * \throw If \a mode == 1 and the same data is present in an existing file. + */ +void MEDFileJointCorrespondence::write(const std::string& fileName, int mode, const std::string& localMeshName, const std::string& jointName, int order, int iteration) const +{ + med_access_mode medmod=MEDFileUtilities::TraduceWriteMode(mode); + MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName.c_str(),medmod); + + std::ostringstream oss; oss << "MEDFileJointCorrespondence : error on attempt to write in file : \"" << fileName << "\""; + MEDFileUtilities::CheckMEDCode(fid,fid,oss.str()); + + if (( !_is_nodal ) && + ( _loc_geo_type == INTERP_KERNEL::NORM_ERROR || + _rem_geo_type == INTERP_KERNEL::NORM_ERROR )) + { + throw INTERP_KERNEL::Exception( "Geometric type not specified for a cell Joint" ); + } + + if ( (const DataArrayInt *)_correspondence ) + { + writeLL(fid, localMeshName, jointName, order, iteration); + } + else + { + throw INTERP_KERNEL::Exception("MEDFileJointCorrespondence::write : correspondence array not defined"); + } +} + +void MEDFileJointCorrespondence::writeLL(med_idt fid, const std::string& localMeshName, const std::string& jointName, int order, int iteration) const +{ + if ( _is_nodal ) + { + MEDFILESAFECALLERWR0(MEDsubdomainCorrespondenceWr,(fid, localMeshName.c_str(), jointName.c_str(), + order, iteration, + MED_NODE, MED_NONE, + MED_NODE, MED_NONE, + _correspondence->getNbOfElems()/2, + _correspondence->getConstPointer())); + } + else + { + MEDFILESAFECALLERWR0(MEDsubdomainCorrespondenceWr,(fid, localMeshName.c_str(), jointName.c_str(), + order, iteration, + MED_CELL, typmai3[ _loc_geo_type ], + MED_CELL, typmai3[ _rem_geo_type ], + _correspondence->getNbOfElems()/2, + _correspondence->getConstPointer())); + } +} + +void MEDFileJointCorrespondence::setCorrespondence(DataArrayInt *corr) +{ + _correspondence=corr; + if ( corr ) + corr->incrRef(); +} + +/*! + * Checks if \a this and another mesh are equal. + * \param [in] other - the mesh to compare with. + * \return bool - \c true if the meshes are equal, \c false, else. + */ +bool MEDFileJointCorrespondence::isEqual(const MEDFileJointCorrespondence *other) const +{ + if(_is_nodal!=other->_is_nodal) + return false; + if(_loc_geo_type!=other->_loc_geo_type) + return false; + if(_rem_geo_type!=other->_rem_geo_type) + return false; + if(!_correspondence->isEqual(*other->_correspondence)) + return false; + return true; +} + +MEDFileJointCorrespondence *MEDFileJointCorrespondence::deepCpy() const +{ + MEDCouplingAutoRefCountObjectPtr<MEDFileJointCorrespondence> ret=new MEDFileJointCorrespondence(*this); + return ret.retn(); +} + +MEDFileJointCorrespondence *MEDFileJointCorrespondence::shallowCpy() const +{ + MEDCouplingAutoRefCountObjectPtr<MEDFileJointCorrespondence> ret=new MEDFileJointCorrespondence(*this); + return ret.retn(); +} + +/*! + * Returns a string describing \a this mesh. This description includes the correspondence and + * the number correspondence. + * \return std::string - the joint information string. + */ +std::string MEDFileJointCorrespondence::simpleRepr() const +{ + std::ostringstream oss; + oss << "(*************************************)\n(* JOINT_CORRESPOND INFORMATION: *)\n(*************************************)\n"; + oss << "- entity type of the correspondence : " << ( getIsNodal() ? "NODE" : "CELL" ) << "\n"; + oss << "- Local geometry type of the correspondence : " << INTERP_KERNEL::CellModel::GetCellModel( _loc_geo_type ).getRepr() << "\n"; + oss << "- Remote geometry type of the correspondence : " << INTERP_KERNEL::CellModel::GetCellModel( _rem_geo_type ).getRepr() << "\n"; + if ( (const DataArrayInt *)_correspondence ) + { + oss << "- Number entity of the correspondence : " << getCorrespondence()->getNumberOfTuples() << "\n"; + + const DataArrayInt* tmp=getCorrespondence(); + oss << "- Correspondence : <<"; + for(const int *it=tmp->begin();it!=tmp->end();it++) + oss<< *it << " "; + } + else + { + oss << "- Number entity of the correspondence : 0\n"; + } + oss << std::endl; + return oss.str(); +} + + +MEDFileJointOneStep::MEDFileJointOneStep():_order(-1),_iteration(-1) +{ +} + +std::size_t MEDFileJointOneStep::getHeapMemorySizeWithoutChildren() const +{ + return _correspondences.capacity()*sizeof(MEDCouplingAutoRefCountObjectPtr<DataArrayInt>); +} + +std::vector<const BigMemoryObject *> MEDFileJointOneStep::getDirectChildrenWithNull() const +{ + return std::vector<const BigMemoryObject *>(); +} + +MEDFileJointOneStep *MEDFileJointOneStep::New(int dt, int it) +{ + MEDFileJointOneStep* j = new MEDFileJointOneStep(); + j->setOrder( dt ); + j->setIteration( it ); + return j; +} + +/*! + * Returns a new MEDFileJointOneStep. + * \param [in] fileName - the name of MED file to read. + * \param [in] mName - the name of the mesh to read. + * \param [in] jointName - the joint name. + * \param [in] num - the number of an iteration. + * \return MEDFileMesh * - a new instance of MEDFileJointOneStep. + * \throw If the file is not readable. + * \throw If there is no mesh with given attributes in the file. + */ +MEDFileJointOneStep *MEDFileJointOneStep::New(const std::string& fileName, const std::string& mName, const std::string& jointName, int num) +{ + MEDFileUtilities::CheckFileForRead(fileName); + MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName.c_str(), MED_ACC_RDONLY); + return new MEDFileJointOneStep(fid, mName, jointName, num); +} + +MEDFileJointOneStep* MEDFileJointOneStep::New(med_idt fid, const std::string& mName, const std::string& jointName, int num) +{ + return new MEDFileJointOneStep( fid, mName, jointName, num); +} + +MEDFileJointOneStep::MEDFileJointOneStep(med_idt fid, const std::string& mName, const std::string& jointName, int num) +{ + int order, iteration, ncorrespondence; + MEDFILESAFECALLERRD0(MEDsubdomainComputingStepInfo,(fid, mName.c_str(), jointName.c_str(), num, &order, &iteration, &ncorrespondence)); + MEDFileJointOneStep::setOrder(order); + MEDFileJointOneStep::setIteration(iteration); + for ( int cur_it = 1; cur_it <= ncorrespondence; ++cur_it ) + { + int num_entity; + med_entity_type loc_ent_type, rem_ent_type; + med_geometry_type loc_geo_type, rem_geo_type; + MEDFILESAFECALLERRD0(MEDsubdomainCorrespondenceSizeInfo,(fid, mName.c_str(), jointName.c_str(), order, iteration, cur_it, + &loc_ent_type, &loc_geo_type, &rem_ent_type, &rem_geo_type, &num_entity)); + if ( num_entity > 0 ) + { + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> correspondence=DataArrayInt::New(); + correspondence->alloc(num_entity*2, 1); + MEDFILESAFECALLERRD0(MEDsubdomainCorrespondenceRd,(fid, mName.c_str(), jointName.c_str(), order, iteration, loc_ent_type, + loc_geo_type, rem_ent_type, rem_geo_type, correspondence->getPointer())); + MEDFileJointCorrespondence *cor=MEDFileJointCorrespondence::New(); + cor->setIsNodal( loc_ent_type == MED_NODE ); + cor->setLocalGeometryType ( convertGeometryType( loc_geo_type )); + cor->setRemoteGeometryType( convertGeometryType( rem_geo_type )); + cor->setCorrespondence( correspondence ); + _correspondences.push_back(cor); + } + } +} + +/*! + * Writes \a this joint into a MED file specified by its name. + * \param [in] fileName - the MED file name. + * \param [in] mode - the writing mode. For more on \a mode, see \ref AdvMEDLoaderBasics. + * - 2 - erase; an existing file is removed. + * - 1 - append; same data should not be present in an existing file. + * - 0 - overwrite; same data present in an existing file is overwritten. + * \throw If the mesh name is not set. + * \throw If \a mode == 1 and the same data is present in an existing file. + */ +void MEDFileJointOneStep::write(const std::string& fileName, int mode, const std::string& localMeshName, const std::string& jointName) const +{ + med_access_mode medmod=MEDFileUtilities::TraduceWriteMode(mode); + MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName.c_str(),medmod); + std::ostringstream oss; oss << "MEDFileJointOneStep : error on attempt to write in file : \"" << fileName << "\""; + MEDFileUtilities::CheckMEDCode(fid,fid,oss.str()); + if ( _correspondences.empty() ) + throw INTERP_KERNEL::Exception("MEDFileJointOneStep::write : no correspondences defined !"); + writeLL(fid, localMeshName, jointName); +} + +void MEDFileJointOneStep::writeLL(med_idt fid, const std::string& localMeshName, const std::string& jointName) const +{ + for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileJointCorrespondence> >::const_iterator it=_correspondences.begin();it!=_correspondences.end();it++) + { + (*it)->writeLL(fid, localMeshName, jointName, getOrder(), getIteration()); + } +} + +void MEDFileJointOneStep::pushCorrespondence(MEDFileJointCorrespondence* correspondence) +{ + if(!correspondence) + throw INTERP_KERNEL::Exception("MEDFileJointCorrespondence::pushCorrespondence : invalid input pointer ! should be different from 0 !"); + _correspondences.push_back(correspondence); + correspondence->incrRef(); +} + +int MEDFileJointOneStep::getNumberOfCorrespondences() const +{ + return _correspondences.size(); +} + +/** Return a borrowed reference (caller is not responsible) */ +MEDFileJointCorrespondence *MEDFileJointOneStep::getCorrespondenceAtPos(int i) const +{ + if(i<0 || i>=(int)_correspondences.size()) + { + std::ostringstream oss; oss << "MEDFileJointOneStep::getCorrespondenceAtPos : invalid correspondence id given in parameter ! Should be in [0;" << _correspondences.size() << ") !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + const MEDFileJointCorrespondence* ret = _correspondences[i]; + return const_cast<MEDFileJointCorrespondence *>( ret ); +} + +/*! + * Checks if \a this and another Joint are equal. + * \param [in] other - the Joint to compare with. + * \return bool - \c true if the Joints are equal, \c false, else. + */ +bool MEDFileJointOneStep::isEqual(const MEDFileJointOneStep *other) const +{ + if(_order!=other->_order) + return false; + if(_iteration!=other->_iteration) + return false; + if ( getNumberOfCorrespondences() != other->getNumberOfCorrespondences() ) + return false; + + std::vector<int> found( getNumberOfCorrespondences(), false ); + for(int i=0; i<getNumberOfCorrespondences(); i++) + { + int j; + for(j=0; j<getNumberOfCorrespondences(); j++) + { + if ( !found[ j ] && + getCorrespondenceAtPos(i)->isEqual(other->getCorrespondenceAtPos(j))) + { + found[ j ] = true; + break; + } + } + if ( j == getNumberOfCorrespondences() ) + return false; + } + return true; +} + +MEDFileJointOneStep *MEDFileJointOneStep::deepCpy() const +{ + std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileJointCorrespondence> > correspondences(_correspondences.size()); + std::size_t i=0; + for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileJointCorrespondence> >::const_iterator it=_correspondences.begin();it!=_correspondences.end();it++,i++) + if((const MEDFileJointCorrespondence *)*it) + correspondences[i]=(*it)->deepCpy(); + MEDCouplingAutoRefCountObjectPtr<MEDFileJointOneStep> ret= new MEDFileJointOneStep; + ret->_correspondences=correspondences; + return ret.retn(); +} + +MEDFileJointOneStep *MEDFileJointOneStep::shallowCpy() const +{ + MEDCouplingAutoRefCountObjectPtr<MEDFileJointOneStep> ret=new MEDFileJointOneStep(*this); + return ret.retn(); +} + +/*! + * Returns a string describing \a this Joint. This description includes the correspondence and + * the number of correspondences. + * \return std::string - the joint information string. + */ +std::string MEDFileJointOneStep::simpleRepr() const +{ + std::ostringstream oss; + oss << "(*************************************)\n(* JOINT_ONE_STEP INFORMATION: *)\n(*************************************)\n"; + oss << "- Number of the correspondences : <<" << _correspondences.size() << ">>\n"; + for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileJointCorrespondence> >::const_iterator it=_correspondences.begin();it!=_correspondences.end();it++) + { + oss << (*it)->simpleRepr(); + } + return oss.str(); +} +INTERP_KERNEL::NormalizedCellType MEDFileJointOneStep::convertGeometryType(med_geometry_type geotype) +{ + INTERP_KERNEL::NormalizedCellType result=INTERP_KERNEL::NORM_ERROR; + for(int i=0; i<MED_N_CELL_FIXED_GEO; i++) + { + if (typmai[i]==geotype) + { + result=typmai2[i]; + break; + } + } + return result; +} +std::size_t MEDFileJoint::getHeapMemorySizeWithoutChildren() const +{ + return _joint.capacity()*sizeof(MEDCouplingAutoRefCountObjectPtr<MEDFileJointOneStep>); +} + +std::vector<const BigMemoryObject *> MEDFileJoint::getDirectChildrenWithNull() const +{ + return std::vector<const BigMemoryObject *>(); +} + +MEDFileJoint *MEDFileJoint::New() +{ + return new MEDFileJoint(); +} + +MEDFileJoint *MEDFileJoint::New(const std::string& fileName, const std::string& mName, int curJoint) +{ + MEDFileUtilities::CheckFileForRead(fileName); + MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName.c_str(), MED_ACC_RDONLY); + return new MEDFileJoint(fid,mName,curJoint); +} + +MEDFileJoint *MEDFileJoint::New(med_idt fid, const std::string& mName, int curJoint) +{ + return new MEDFileJoint(fid,mName,curJoint); +} + +MEDFileJoint *MEDFileJoint::New(const std::string& jointName, const std::string& locMeshName, const std::string& remoteMeshName, int remoteMeshNum) +{ + MEDFileJoint* j = new MEDFileJoint(); + j->setJointName( jointName ); + j->setLocalMeshName( locMeshName ); + j->setRemoteMeshName( remoteMeshName ); + j->setDomainNumber( remoteMeshNum ); + return j; +} + +MEDFileJoint::MEDFileJoint() +{ +} + +/*! + * Returns a new MEDFileJoint holding the mesh data that has been read from a given MED + * file. The Joint to load is specified by mesh name and a Joint iteration. + * \param [in] fileName - the name of MED file to read. + * \param [in] mName - the name of the mesh to read. + * \param [in] curJoint - the iteration number of current joint. + * \return MEDFileJoint * - a new instance of MEDFileJoint. + * \throw If the file is not readable. + * \throw If there is no mesh with given attributes in the file. + */ +MEDFileJoint::MEDFileJoint(med_idt fid, const std::string& mName, int curJoint) +{ + INTERP_KERNEL::AutoPtr<char> joint_name=MEDLoaderBase::buildEmptyString(MED_NAME_SIZE); + INTERP_KERNEL::AutoPtr<char> desc_name=MEDLoaderBase::buildEmptyString(MED_COMMENT_SIZE); + INTERP_KERNEL::AutoPtr<char> rem_mesh_name=MEDLoaderBase::buildEmptyString(MED_NAME_SIZE); + int domain_number=0, nstep=0, nocstpncorrespondence=0; + MEDFILESAFECALLERRD0(MEDsubdomainJointInfo,(fid,mName.c_str(), curJoint, joint_name, desc_name, &domain_number,rem_mesh_name, + &nstep, &nocstpncorrespondence)); + setLocalMeshName(mName); + setRemoteMeshName(MEDLoaderBase::buildStringFromFortran(rem_mesh_name,MED_NAME_SIZE)); + setDescription(MEDLoaderBase::buildStringFromFortran(desc_name,MED_COMMENT_SIZE)); + setJointName(MEDLoaderBase::buildStringFromFortran(joint_name,MED_NAME_SIZE)); + setDomainNumber(domain_number); + for(int cur_step=1; cur_step <= nstep; ++cur_step) + { + MEDFileJointOneStep *cor=MEDFileJointOneStep::New(fid, mName.c_str(), getJointName(), cur_step); + _joint.push_back(cor); + } +} + +/*! + * Writes \a this joint into a MED file specified by its name. + * \param [in] fileName - the MED file name. + * \param [in] mode - the writing mode. For more on \a mode, see \ref AdvMEDLoaderBasics. + * - 2 - erase; an existing file is removed. + * - 1 - append; same data should not be present in an existing file. + * - 0 - overwrite; same data present in an existing file is overwritten. + * \throw If the mesh name is not set. + * \throw If \a mode == 1 and the same data is present in an existing file. + */ +void MEDFileJoint::write(const std::string& fileName, int mode) const +{ + med_access_mode medmod=MEDFileUtilities::TraduceWriteMode(mode); + MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName.c_str(),medmod); + std::ostringstream oss; oss << "MEDFileJoint : error on attempt to write in file : \"" << fileName << "\""; + MEDFileUtilities::CheckMEDCode(fid,fid,oss.str()); + write(fid); +} + +void MEDFileJoint::write(med_idt fid) const +{ + // if ( _loc_mesh_name.empty() ) + // throw INTERP_KERNEL::Exception("MEDFileJoint::write : name of a local mesh not defined!"); + MEDFILESAFECALLERWR0(MEDsubdomainJointCr,(fid,getLocalMeshName().c_str(),getJointName().c_str(),getDescription().c_str(),getDomainNumber(),getRemoteMeshName().c_str())); + for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileJointOneStep> >::const_iterator it=_joint.begin();it!=_joint.end();it++) { + (*it)->writeLL(fid, getLocalMeshName(),getJointName()); + } +} + +void MEDFileJoint::pushStep(MEDFileJointOneStep* step) +{ + if(!step) + throw INTERP_KERNEL::Exception("MEDFileJoint::pushStep : invalid input pointer ! should be different from 0 !"); + _joint.push_back(step); + step->incrRef(); +} + +int MEDFileJoint::getNumberOfSteps() const +{ + return _joint.size(); +} + +/** Return a borrowed reference (caller is not responsible) */ +MEDFileJointOneStep *MEDFileJoint::getStepAtPos(int i) const +{ + if(i<0 || i>=(int)_joint.size()) + { + std::ostringstream oss; oss << "MEDFileJoint::getStepAtPos : invalid step id given in parameter ! Should be in [0;" << _joint.size() << ") !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + const MEDFileJointOneStep* ret = _joint[i]; + return const_cast<MEDFileJointOneStep *>( ret ); +} + +/*! + * Checks if \a this and another Joint are equal. + * \param [in] other - the Joint to compare with. + * \return bool - \c true if the Joints are equal, \c false, else. + */ +bool MEDFileJoint::isEqual(const MEDFileJoint *other) const +{ + if(_loc_mesh_name!=other->_loc_mesh_name) + return false; + if(_joint_name!=other->_joint_name) + return false; + if(_desc_name!=other->_desc_name) + return false; + if(_rem_mesh_name!=other->_rem_mesh_name) + return false; + if(_domain_number!=other->_domain_number) + return false; + std::vector<int> found( getNumberOfSteps(), false ); + for(int i=0; i<getNumberOfSteps(); i++) + { + int j; + for(j=0; j<getNumberOfSteps(); j++) + { + if ( !found[ j ] && + getStepAtPos(i)->isEqual(other->getStepAtPos(j))) + { + found[ j ] = true; + break; + } + } + if ( j == getNumberOfSteps() ) + return false; + } + return true; +} + +MEDFileJoint *MEDFileJoint::deepCpy() const +{ + std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileJointOneStep> > joint(_joint.size()); + std::size_t i=0; + for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileJointOneStep> >::const_iterator it=_joint.begin();it!=_joint.end();it++,i++) + if((const MEDFileJointOneStep *)*it) + joint[i]=(*it)->deepCpy(); + MEDCouplingAutoRefCountObjectPtr<MEDFileJoint> ret=MEDFileJoint::New(); + ret->_joint=joint; + return ret.retn(); +} + +MEDFileJoint *MEDFileJoint::shallowCpy() const +{ + MEDCouplingAutoRefCountObjectPtr<MEDFileJoint> ret=new MEDFileJoint(*this); + return ret.retn(); +} + +bool MEDFileJoint::changeJointNames(const std::vector< std::pair<std::string,std::string> >& modifTab) +{ + for(std::vector< std::pair<std::string,std::string> >::const_iterator it=modifTab.begin();it!=modifTab.end();it++) + { + if((*it).first==_joint_name) + { + _joint_name=(*it).second; + return true; + } + } + return false; +} + +/*! + * Returns a string describing \a this mesh. This description includes the correspondence and + * the number correspondence. + * \return std::string - the joint information string. + */ +std::string MEDFileJoint::simpleRepr() const +{ + std::ostringstream oss; + oss << "(*************************************)\n(* JOINT INFORMATION: *)\n(*************************************)\n"; + oss << "- Local Mesh name : <<" << getLocalMeshName() << ">>\n"; + oss << "- Remote Mesh name : <<" << getRemoteMeshName() << ">>\n"; + oss << "- Description : <<" << getDescription() << ">>\n"; + oss << "- Joint name : <<" << getJointName() << ">>\n"; + oss << "- Domain number : " << getDomainNumber() << "\n"; + for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileJointOneStep> >::const_iterator it=_joint.begin();it!=_joint.end();it++) + { + oss << (*it)->simpleRepr(); + } + return oss.str(); +} + +MEDFileJoints *MEDFileJoints::New() +{ + return new MEDFileJoints; +} + +MEDFileJoints *MEDFileJoints::New(const std::string& fileName, const std::string& meshName) +{ + MEDFileUtilities::CheckFileForRead(fileName); + MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName.c_str(), MED_ACC_RDONLY); + return new MEDFileJoints( fid, meshName ); +} + +MEDFileJoints *MEDFileJoints::New(med_idt fid, const std::string& meshName) +{ + return new MEDFileJoints( fid, meshName ); +} + +void MEDFileJoints::write(med_idt fid) const +{ + for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileJoint> >::const_iterator it=_joints.begin();it!=_joints.end();it++) + { + (*it)->write(fid); + } +} + +void MEDFileJoints::write(const std::string& fileName, int mode) const +{ + med_access_mode medmod=MEDFileUtilities::TraduceWriteMode(mode); + MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName.c_str(),medmod); + std::ostringstream oss; oss << "MEDFileJoints : error on attempt to write in file : \"" << fileName << "\""; + MEDFileUtilities::CheckMEDCode(fid,fid,oss.str()); + write(fid); +} + +std::string MEDFileJoints::getMeshName() const +{ + for ( size_t i = 0; i <= _joints.size(); ++i ) + if ( (const MEDFileJoint*) _joints[i] ) + return _joints[i]->getLocalMeshName(); + + return ""; +} + +int MEDFileJoints::getNumberOfJoints() const +{ + return _joints.size(); +} + +/** Return a borrowed reference (caller is not responsible) */ +MEDFileJoint *MEDFileJoints::getJointAtPos(int i) const +{ + if(i<0 || i>=(int)_joints.size()) + { + std::ostringstream oss; oss << "MEDFileJoints::getJointAtPos : invalid joint id given in parameter ! Should be in [0;" << _joints.size() << ") !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + const MEDFileJoint* ret = _joints[i]; + return const_cast<MEDFileJoint *>( ret ); +} + + +/** Return a borrowed reference (caller is not responsible) */ +MEDFileJoint *MEDFileJoints::getJointWithName(const std::string& jname) const +{ + std::vector<std::string> js=getJointsNames(); + std::vector<std::string>::iterator it=std::find(js.begin(),js.end(),jname); + if(it==js.end()) + { + std::ostringstream oss; oss << "MEDFileJoints::getJointWithName : Joint \"" << jname << "\" does not exist in this ! Existing are : "; + std::copy(js.begin(),js.end(),std::ostream_iterator<std::string>(oss," ")); + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + return getJointAtPos((int)std::distance(js.begin(),it)); +} + +std::vector<std::string> MEDFileJoints::getJointsNames() const +{ + std::vector<std::string> ret(_joints.size()); + int i=0; + for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileJoint> >::const_iterator it=_joints.begin();it!=_joints.end();it++,i++) + { + const MEDFileJoint *f=(*it); + if(f) + { + ret[i]=f->getJointName(); + } + else + { + std::ostringstream oss; oss << "MEDFileJoints::getJointsNames : At rank #" << i << " joint is not defined !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + } + return ret; +} + +bool MEDFileJoints::changeJointNames(const std::vector< std::pair<std::string,std::string> >& modifTab) +{ + bool ret=false; + for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileJoint> >::iterator it=_joints.begin();it!=_joints.end();it++) + { + MEDFileJoint *cur(*it); + if(cur) + ret=cur->changeJointNames(modifTab) || ret; + } + return ret; +} + +void MEDFileJoints::resize(int newSize) +{ + _joints.resize(newSize); +} + +void MEDFileJoints::pushJoint(MEDFileJoint *joint) +{ + if(!joint) + throw INTERP_KERNEL::Exception("MEDFileJoints::pushJoint() : invalid input pointer ! should be different from 0 !"); + if ( !_joints.empty() && + _joints[0]->getLocalMeshName() != joint->getLocalMeshName() ) + throw INTERP_KERNEL::Exception("MEDFileJoints::pushJoint() : different names of local meshes ! should be equal !"); + + _joints.push_back(joint); + joint->incrRef(); +} + +void MEDFileJoints::setJointAtPos(int i, MEDFileJoint *joint) +{ + if(!joint) + throw INTERP_KERNEL::Exception("MEDFileJoints::setJointAtPos : invalid input pointer ! should be different from 0 !"); + if(i>=(int)_joints.size()) + _joints.resize(i+1); + _joints[i]=joint; + joint->incrRef(); +} + +void MEDFileJoints::destroyJointAtPos(int i) +{ + if(i<0 || i>=(int)_joints.size()) + { + std::ostringstream oss; oss << "MEDFileJoints::destroyJointAtPos : Invalid given id in input (" << i << ") should be in [0," << _joints.size() << ") !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + _joints.erase(_joints.begin()+i); +} + +MEDFileJoints::MEDFileJoints() +{ +} + +MEDFileJoints::MEDFileJoints(med_idt fid, const std::string& meshName) +{ + int num_joint=MEDnSubdomainJoint(fid, meshName.c_str() ); + for(int i = 1; i <= num_joint; i++) + _joints.push_back(MEDFileJoint::New(fid,meshName,i)); +} + +MEDFileJoints *MEDFileJoints::deepCpy() const +{ + std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileJoint> > joints(_joints.size()); + std::size_t i=0; + for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileJoint> >::const_iterator it=_joints.begin();it!=_joints.end();it++,i++) + if((const MEDFileJoint *)*it) + joints[i]=(*it)->deepCpy(); + MEDCouplingAutoRefCountObjectPtr<MEDFileJoints> ret=MEDFileJoints::New(); + ret->_joints=joints; + return ret.retn(); +} + +std::size_t MEDFileJoints::getHeapMemorySizeWithoutChildren() const +{ + return _joints.capacity()*(sizeof(MEDCouplingAutoRefCountObjectPtr<MEDFileJoint>)); +} + +std::vector<const BigMemoryObject *> MEDFileJoints::getDirectChildrenWithNull() const +{ + std::vector<const BigMemoryObject *> ret; + for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileJoint> >::const_iterator it=_joints.begin();it!=_joints.end();it++) + ret.push_back((const MEDFileJoint *)*it); + return ret; +} + +std::string MEDFileJoints::simpleRepr() const +{ + std::ostringstream oss; + oss << "(*****************)\n(* MEDFileJoints *)\n(*****************)\n\n"; + simpleReprWithoutHeader(oss); + return oss.str(); +} + +void MEDFileJoints::simpleReprWithoutHeader(std::ostream& oss) const +{ + int nbOfJoints=getNumberOfJoints(); + oss << "There are " << nbOfJoints << " joints with the following names : \n"; + std::vector<std::string> jns=getJointsNames(); + for(int i=0;i<nbOfJoints;i++) + oss << " - #" << i << " \"" << jns[i] << "\"\n"; + for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileJoint> >::const_iterator it=_joints.begin();it!=_joints.end();it++) + { + oss << (*it)->simpleRepr(); + } +} diff --git a/src/medtool/src/MEDLoader/MEDFileJoint.hxx b/src/medtool/src/MEDLoader/MEDFileJoint.hxx new file mode 100644 index 000000000..1d32312f8 --- /dev/null +++ b/src/medtool/src/MEDLoader/MEDFileJoint.hxx @@ -0,0 +1,194 @@ +// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 +// 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 __MEDFILEJOINT_HXX__ +#define __MEDFILEJOINT_HXX__ + +#include "MEDLoaderDefines.hxx" +#include "MEDFileUtilities.hxx" +#include "MEDCouplingMemArray.hxx" +#include "MEDCouplingAutoRefCountObjectPtr.hxx" + +namespace ParaMEDMEM +{ +/*! + * \brief Joint Correspondence enumerates pairs of corresponding entities of a + * certain geometrical type in adjacent mesh domains. + * Correspondence of nodes is constructed when you specify no cell type, + * else Correspondence of cells is constructed. + */ +class MEDFileJointCorrespondence : public RefCountObject, public MEDFileWritable +{ +public: + MEDLOADER_EXPORT static MEDFileJointCorrespondence *New(); + MEDLOADER_EXPORT static MEDFileJointCorrespondence *New(DataArrayInt* correspondence); // nodes + MEDLOADER_EXPORT static MEDFileJointCorrespondence *New(DataArrayInt* correspondence, // cells + INTERP_KERNEL::NormalizedCellType loc_geo_type, + INTERP_KERNEL::NormalizedCellType rem_geo_type); + MEDLOADER_EXPORT std::size_t getHeapMemorySizeWithoutChildren() const; + MEDLOADER_EXPORT std::vector<const BigMemoryObject *> getDirectChildrenWithNull() const; + MEDLOADER_EXPORT MEDFileJointCorrespondence *deepCpy() const; + MEDLOADER_EXPORT MEDFileJointCorrespondence *shallowCpy() const; + MEDLOADER_EXPORT bool isEqual(const MEDFileJointCorrespondence *other) const; + MEDLOADER_EXPORT void setIsNodal(bool isNodal) { _is_nodal = isNodal; } + MEDLOADER_EXPORT bool getIsNodal() const { return _is_nodal; } + MEDLOADER_EXPORT void setLocalGeometryType(INTERP_KERNEL::NormalizedCellType type) { _loc_geo_type=type; } + MEDLOADER_EXPORT INTERP_KERNEL::NormalizedCellType getLocalGeometryType() const { return _loc_geo_type; } + MEDLOADER_EXPORT void setRemoteGeometryType(INTERP_KERNEL::NormalizedCellType type) { _rem_geo_type=type; } + MEDLOADER_EXPORT INTERP_KERNEL::NormalizedCellType getRemoteGeometryType() const { return _rem_geo_type; } + MEDLOADER_EXPORT void setCorrespondence(DataArrayInt *corr); + MEDLOADER_EXPORT const DataArrayInt *getCorrespondence() const { return _correspondence; } + MEDLOADER_EXPORT void write(const std::string& fileName, int mode, const std::string& localMeshName, const std::string& jointName, int order, int iteration) const; + + MEDLOADER_EXPORT std::string simpleRepr() const; + MEDLOADER_EXPORT void writeLL(med_idt fid, const std::string& localMeshName, const std::string& jointName, int order, int iteration) const; +private: + MEDFileJointCorrespondence(); + MEDFileJointCorrespondence(DataArrayInt* correspondence, + bool is_nodal = true, + INTERP_KERNEL::NormalizedCellType loc_geo_type = INTERP_KERNEL::NORM_ERROR, + INTERP_KERNEL::NormalizedCellType rem_geo_type = INTERP_KERNEL::NORM_ERROR); +private: + bool _is_nodal; + INTERP_KERNEL::NormalizedCellType _loc_geo_type; + INTERP_KERNEL::NormalizedCellType _rem_geo_type; + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> _correspondence; +}; + +/*! + * \brief Joint of one iteration holds correspondences of entities of all types + */ +class MEDFileJointOneStep : public RefCountObject, public MEDFileWritable +{ +public: + MEDLOADER_EXPORT static MEDFileJointOneStep *New(int dt=-1, int it=-1); + MEDLOADER_EXPORT static MEDFileJointOneStep *New(const std::string& fileName, const std::string& mName, const std::string& jointName, int number=1); + MEDLOADER_EXPORT static MEDFileJointOneStep *New(med_idt fid, const std::string& mName, const std::string& jointName, int number=1); + MEDLOADER_EXPORT std::size_t getHeapMemorySizeWithoutChildren() const; + MEDLOADER_EXPORT std::vector<const BigMemoryObject *> getDirectChildrenWithNull() const; + MEDLOADER_EXPORT MEDFileJointOneStep *deepCpy() const; + MEDLOADER_EXPORT MEDFileJointOneStep *shallowCpy() const; + MEDLOADER_EXPORT bool isEqual(const MEDFileJointOneStep *other) const; + MEDLOADER_EXPORT void setOrder(int order) { _order=order; } + MEDLOADER_EXPORT int getOrder() const { return _order; } + MEDLOADER_EXPORT void setIteration(int it) { _iteration=it; } + MEDLOADER_EXPORT int getIteration() const { return _iteration; } + MEDLOADER_EXPORT void pushCorrespondence(MEDFileJointCorrespondence* correspondence); + MEDLOADER_EXPORT int getNumberOfCorrespondences() const; + MEDLOADER_EXPORT MEDFileJointCorrespondence *getCorrespondenceAtPos(int i) const; + + MEDLOADER_EXPORT void write(const std::string& fileName, int mode, const std::string& localMeshName, const std::string& jointName) const; + + MEDLOADER_EXPORT std::string simpleRepr() const; + MEDLOADER_EXPORT void writeLL(med_idt fid, const std::string& localMeshName, const std::string& jointName) const; +private: + MEDFileJointOneStep(); + MEDFileJointOneStep(med_idt fid, const std::string& mName, const std::string& jointName, int number); + MEDLOADER_EXPORT INTERP_KERNEL::NormalizedCellType convertGeometryType(med_geometry_type geotype); +protected: + int _order; + int _iteration; +private: + std::vector<MEDCouplingAutoRefCountObjectPtr<MEDFileJointCorrespondence> > _correspondences; +}; + +/*! + * \brief Joint holds a sequence of joints of different iterations relating to + * a pair of mesh domains: a local one and a distant one + */ +class MEDFileJoint : public RefCountObject, public MEDFileWritable +{ +public: + MEDLOADER_EXPORT static MEDFileJoint *New(); + MEDLOADER_EXPORT static MEDFileJoint *New(const std::string& fileName, const std::string& mName, int num); + MEDLOADER_EXPORT static MEDFileJoint *New(med_idt fid, const std::string& mName, int num); + MEDLOADER_EXPORT static MEDFileJoint *New(const std::string& jointName, const std::string& locMeshName, const std::string& remoteMeshName, int remoteMeshNum ); + MEDLOADER_EXPORT std::size_t getHeapMemorySizeWithoutChildren() const; + MEDLOADER_EXPORT std::vector<const BigMemoryObject *> getDirectChildrenWithNull() const; + MEDLOADER_EXPORT MEDFileJoint *deepCpy() const; + MEDLOADER_EXPORT MEDFileJoint *shallowCpy() const; + MEDLOADER_EXPORT bool isEqual(const MEDFileJoint *other) const; + MEDLOADER_EXPORT void setLocalMeshName(const std::string& name) { _loc_mesh_name=name; } + MEDLOADER_EXPORT std::string getLocalMeshName() const { return _loc_mesh_name; } + MEDLOADER_EXPORT void setRemoteMeshName(const std::string& name) { _rem_mesh_name=name; } + MEDLOADER_EXPORT std::string getRemoteMeshName() const { return _rem_mesh_name; } + MEDLOADER_EXPORT void setDescription(const std::string& name) { _desc_name=name; } + MEDLOADER_EXPORT std::string getDescription() const { return _desc_name; } + MEDLOADER_EXPORT void setJointName(const std::string& name) { _joint_name=name; } + MEDLOADER_EXPORT std::string getJointName() const { return _joint_name; } + MEDLOADER_EXPORT bool changeJointNames(const std::vector< std::pair<std::string,std::string> >& modifTab); + MEDLOADER_EXPORT void setDomainNumber(const int& number) { _domain_number=number; } + MEDLOADER_EXPORT int getDomainNumber() const { return _domain_number; } + MEDLOADER_EXPORT void pushStep(MEDFileJointOneStep* step); + MEDLOADER_EXPORT int getNumberOfSteps() const; + MEDLOADER_EXPORT MEDFileJointOneStep *getStepAtPos(int i) const; + + MEDLOADER_EXPORT void write(const std::string& fileName, int mode) const; + MEDLOADER_EXPORT void write(med_idt fid) const; + + MEDLOADER_EXPORT std::string simpleRepr() const; + private: + MEDFileJoint(); + MEDFileJoint(med_idt fid, const std::string& mName, int num); + private: + std::string _loc_mesh_name; + std::string _joint_name; + std::string _desc_name; + int _domain_number; + std::string _rem_mesh_name; + std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileJointOneStep> > _joint; + }; + + /*! + * \brief Joints of a mesh domain relating to all other mesh domains + */ + class MEDFileJoints : public RefCountObject, public MEDFileWritable + { + public: + MEDLOADER_EXPORT static MEDFileJoints *New(); + MEDLOADER_EXPORT static MEDFileJoints *New(const std::string& fileName, const std::string& meshName); + MEDLOADER_EXPORT static MEDFileJoints *New(med_idt fid, const std::string& meshName); + MEDLOADER_EXPORT MEDFileJoints *deepCpy() const; + MEDLOADER_EXPORT std::size_t getHeapMemorySizeWithoutChildren() const; + MEDLOADER_EXPORT std::vector<const BigMemoryObject *> getDirectChildrenWithNull() const; + MEDLOADER_EXPORT std::string simpleRepr() const; + MEDLOADER_EXPORT void simpleReprWithoutHeader(std::ostream& oss) const; + MEDLOADER_EXPORT void write(const std::string& fileName, int mode) const; + MEDLOADER_EXPORT void write(med_idt fid) const; + MEDLOADER_EXPORT std::string getMeshName() const; + MEDLOADER_EXPORT int getNumberOfJoints() const; + MEDLOADER_EXPORT MEDFileJoint *getJointAtPos(int i) const; + MEDLOADER_EXPORT MEDFileJoint *getJointWithName(const std::string& jname) const; + MEDLOADER_EXPORT std::vector<std::string> getJointsNames() const; + MEDLOADER_EXPORT bool changeJointNames(const std::vector< std::pair<std::string,std::string> >& modifTab); + // + MEDLOADER_EXPORT void resize(int newSize); + MEDLOADER_EXPORT void pushJoint(MEDFileJoint *joint); + MEDLOADER_EXPORT void setJointAtPos(int i, MEDFileJoint *joint); + MEDLOADER_EXPORT void destroyJointAtPos(int i); + private: + ~MEDFileJoints() { } + MEDFileJoints(); + MEDFileJoints(med_idt fid, const std::string& meshName); + private: + std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileJoint> > _joints; + }; +} + +#endif diff --git a/src/medtool/src/MEDLoader/MEDFileMesh.cxx b/src/medtool/src/MEDLoader/MEDFileMesh.cxx new file mode 100644 index 000000000..a2ae03287 --- /dev/null +++ b/src/medtool/src/MEDLoader/MEDFileMesh.cxx @@ -0,0 +1,6779 @@ +// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 +// 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 "MEDFileMesh.hxx" +#include "MEDFileUtilities.hxx" +#include "MEDFileFieldOverView.hxx" +#include "MEDFileField.hxx" +#include "MEDLoader.hxx" +#include "MEDFileSafeCaller.txx" +#include "MEDLoaderBase.hxx" + +#include "MEDCouplingUMesh.hxx" + +#include "InterpKernelAutoPtr.hxx" + +#include <limits> +#include <cmath> + +extern med_geometry_type typmai3[34]; + +using namespace ParaMEDMEM; + +const char MEDFileMesh::DFT_FAM_NAME[]="FAMILLE_ZERO"; + +MEDFileMesh::MEDFileMesh():_order(-1),_iteration(-1),_time(0.),_univ_wr_status(true) +{ +} + +std::size_t MEDFileMesh::getHeapMemorySizeWithoutChildren() const +{ + std::size_t ret(_dt_unit.capacity()+_name.capacity()+_univ_name.capacity()+_desc_name.capacity()); + for(std::map<std::string, std::vector<std::string> >::const_iterator it=_groups.begin();it!=_groups.end();it++) + { + ret+=(*it).first.capacity()+(*it).second.capacity()*sizeof(std::string); + for(std::vector<std::string>::const_iterator it2=(*it).second.begin();it2!=(*it).second.end();it2++) + ret+=(*it2).capacity(); + } + for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++) + ret+=(*it).first.capacity()+sizeof(int); + return ret; +} + +std::vector<const BigMemoryObject *> MEDFileMesh::getDirectChildrenWithNull() const +{ + return std::vector<const BigMemoryObject *>(); +} + +/*! + * Returns a new MEDFileMesh holding the mesh data that has been read from a given MED + * file. The first mesh in the file is loaded. + * \param [in] fileName - the name of MED file to read. + * \return MEDFileMesh * - a new instance of MEDFileMesh. The caller is to delete this + * mesh using decrRef() as it is no more needed. + * \throw If the file is not readable. + * \throw If there is no meshes in the file. + * \throw If the mesh in the file is of a not supported type. + */ +MEDFileMesh *MEDFileMesh::New(const std::string& fileName, MEDFileMeshReadSelector *mrs) +{ + std::vector<std::string> ms=MEDLoader::GetMeshNames(fileName); + if(ms.empty()) + { + std::ostringstream oss; oss << "MEDFileMesh::New : no meshes in file \"" << fileName << "\" !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + MEDFileUtilities::CheckFileForRead(fileName); + ParaMEDMEM::MEDCouplingMeshType meshType; + MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName.c_str(),MED_ACC_RDONLY); + int dt,it; + std::string dummy2; + MEDFileMeshL2::GetMeshIdFromName(fid,ms.front(),meshType,dt,it,dummy2); + switch(meshType) + { + case UNSTRUCTURED: + { + MEDCouplingAutoRefCountObjectPtr<MEDFileUMesh> ret=MEDFileUMesh::New(); + ret->loadUMeshFromFile(fid,ms.front(),dt,it,mrs); + ret->loadJointsFromFile(fid); + return (MEDFileUMesh *)ret.retn(); + } + case CARTESIAN: + { + MEDCouplingAutoRefCountObjectPtr<MEDFileCMesh> ret=MEDFileCMesh::New(); + ret->loadCMeshFromFile(fid,ms.front(),dt,it,mrs); + ret->loadJointsFromFile(fid); + return (MEDFileCMesh *)ret.retn(); + } + case CURVE_LINEAR: + { + MEDCouplingAutoRefCountObjectPtr<MEDFileCurveLinearMesh> ret=MEDFileCurveLinearMesh::New(); + ret->loadCLMeshFromFile(fid,ms.front(),dt,it,mrs); + ret->loadJointsFromFile(fid); + return (MEDFileCurveLinearMesh *)ret.retn(); + } + default: + { + std::ostringstream oss; oss << "MEDFileMesh::New : MED file exists and has mesh '" << ms.front() << "' exists but unsupported type yet !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + } +} + +/*! + * Returns a new MEDFileMesh holding the mesh data that has been read from a given MED + * file. The mesh to load is specified by its name and numbers of a time step and an + * iteration. + * \param [in] fileName - the name of MED file to read. + * \param [in] mName - the name of the mesh to read. + * \param [in] dt - the number of a time step. + * \param [in] it - the number of an iteration. + * \param [in] joints - the sub-domain joints to use instead of those that can be read + * from the MED file. Usually this joints are those just read by another iteration + * of mName mesh, when this method is called by MEDFileMeshMultiTS::New() + * \return MEDFileMesh * - a new instance of MEDFileMesh. The caller is to delete this + * mesh using decrRef() as it is no more needed. + * \throw If the file is not readable. + * \throw If there is no mesh with given attributes in the file. + * \throw If the mesh in the file is of a not supported type. + */ +MEDFileMesh *MEDFileMesh::New(const std::string& fileName, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs, MEDFileJoints* joints) +{ + MEDFileUtilities::CheckFileForRead(fileName); + ParaMEDMEM::MEDCouplingMeshType meshType; + MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName.c_str(),MED_ACC_RDONLY); + int dummy0,dummy1; + std::string dummy2; + MEDFileMeshL2::GetMeshIdFromName(fid,mName,meshType,dummy0,dummy1,dummy2); + switch(meshType) + { + case UNSTRUCTURED: + { + MEDCouplingAutoRefCountObjectPtr<MEDFileUMesh> ret=MEDFileUMesh::New(); + ret->loadUMeshFromFile(fid,mName,dt,it,mrs); + ret->loadJointsFromFile(fid,joints); + return (MEDFileUMesh *)ret.retn(); + } + case CARTESIAN: + { + MEDCouplingAutoRefCountObjectPtr<MEDFileCMesh> ret=MEDFileCMesh::New(); + ret->loadCMeshFromFile(fid,mName,dt,it,mrs); + ret->loadJointsFromFile(fid,joints); + return (MEDFileCMesh *)ret.retn(); + } + case CURVE_LINEAR: + { + MEDCouplingAutoRefCountObjectPtr<MEDFileCurveLinearMesh> ret=MEDFileCurveLinearMesh::New(); + ret->loadCLMeshFromFile(fid,mName,dt,it,mrs); + ret->loadJointsFromFile(fid,joints); + return (MEDFileCurveLinearMesh *)ret.retn(); + } + default: + { + std::ostringstream oss; oss << "MEDFileMesh::New : MED file exists and has mesh '" << mName << "' exists but unsupported type yet !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + } +} + +/*! + * Writes \a this mesh into an open MED file specified by its descriptor. + * \param [in] fid - the MED file descriptor. + * \throw If the mesh name is not set. + * \throw If the file is open for reading only. + * \throw If the writing mode == 1 and the same data is present in an existing file. + */ +void MEDFileMesh::write(med_idt fid) const +{ + if(!existsFamily(0)) + const_cast<MEDFileMesh *>(this)->addFamily(DFT_FAM_NAME,0); + if(_name.empty()) + throw INTERP_KERNEL::Exception("MEDFileMesh : name is empty. MED file ask for a NON EMPTY name !"); + writeLL(fid); +} + +/*! + * Writes \a this mesh into a MED file specified by its name. + * \param [in] fileName - the MED file name. + * \param [in] mode - the writing mode. For more on \a mode, see \ref AdvMEDLoaderBasics. + * - 2 - erase; an existing file is removed. + * - 1 - append; same data should not be present in an existing file. + * - 0 - overwrite; same data present in an existing file is overwritten. + * \throw If the mesh name is not set. + * \throw If \a mode == 1 and the same data is present in an existing file. + */ +void MEDFileMesh::write(const std::string& fileName, int mode) const +{ + med_access_mode medmod=MEDFileUtilities::TraduceWriteMode(mode); + MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName.c_str(),medmod); + std::ostringstream oss; oss << "MEDFileMesh : error on attempt to write in file : \"" << fileName << "\""; + MEDFileUtilities::CheckMEDCode(fid,fid,oss.str()); + write(fid); +} + +/*! + * Checks if \a this and another mesh are equal. + * \param [in] other - the mesh to compare with. + * \param [in] eps - a precision used to compare real values. + * \param [in,out] what - the string returning description of unequal data. + * \return bool - \c true if the meshes are equal, \c false, else. + */ +bool MEDFileMesh::isEqual(const MEDFileMesh *other, double eps, std::string& what) const +{ + if(_order!=other->_order) + { + what="Orders differ !"; + return false; + } + if(_iteration!=other->_iteration) + { + what="Iterations differ !"; + return false; + } + if(fabs(_time-other->_time)>eps) + { + what="Time values differ !"; + return false; + } + if(_dt_unit!=other->_dt_unit) + { + what="Time units differ !"; + return false; + } + if(_name!=other->_name) + { + what="Names differ !"; + return false; + } + //univ_name has been ignored -> not a bug because it is a mutable attribute + if(_desc_name!=other->_desc_name) + { + what="Description names differ !"; + return false; + } + if(!areGrpsEqual(other,what)) + return false; + if(!areFamsEqual(other,what)) + return false; + return true; +} + +void MEDFileMesh::setName(const std::string& name) +{ + _name=name; +} + +/*! + * Clears redundant attributes of incorporated data arrays. + */ +void MEDFileMesh::clearNonDiscrAttributes() const +{ + +} + +bool MEDFileMesh::changeNames(const std::vector< std::pair<std::string,std::string> >& modifTab) +{ + for(std::vector< std::pair<std::string,std::string> >::const_iterator it=modifTab.begin();it!=modifTab.end();it++) + { + if((*it).first==_name) + { + _name=(*it).second; + return true; + } + } + return false; +} + +/*! + * Copies data on groups and families from another mesh. + * \param [in] other - the mesh to copy the data from. + */ +void MEDFileMesh::copyFamGrpMapsFrom(const MEDFileMesh& other) +{ + _groups=other._groups; + _families=other._families; +} + + +/*! + * This method clear all the groups in the map. + * So this method does not operate at all on arrays. + * So this method can lead to orphan families. + * + * \sa MEDFileMesh::clearFamMap, MEDFileMesh::clearFamGrpMaps + */ +void MEDFileMesh::clearGrpMap() +{ + _groups.clear(); +} + +/*! + * This method clear all the families in the map. + * So this method does not operate at all on arrays. + * WARNING ! if there are some groups lying on cleared families, those groups will be impacted ! + * + * \sa MEDFileMesh::clearFamMap, MEDFileMesh::clearFamGrpMaps + */ +void MEDFileMesh::clearFamMap() +{ + _families.clear(); +} + +/*! + * This method clear all the families and groups in the map. + * So this method does not operate at all on arrays. + * As all groups and families entry will be removed after + * the call of MEDFileMesh::setFamilyFieldArr method with 0 or None (python) in the 2nd parameter can be useful to reduce the size of the object. + * + * \sa MEDFileMesh::clearFamMap, MEDFileMesh::clearFamMap + */ +void MEDFileMesh::clearFamGrpMaps() +{ + clearGrpMap(); + clearFamMap(); +} + +/*! + * Returns names of families constituting a group. + * \param [in] name - the name of the group of interest. + * \return std::vector<std::string> - a sequence of names of the families. + * \throw If the name of a nonexistent group is specified. + */ +std::vector<std::string> MEDFileMesh::getFamiliesOnGroup(const std::string& name) const +{ + std::string oname(name); + std::map<std::string, std::vector<std::string> >::const_iterator it=_groups.find(oname); + if(it==_groups.end()) + { + std::vector<std::string> grps=getGroupsNames(); + std::ostringstream oss; oss << "No such groupname \"" << name << "\" !\nAvailable groups are :"; + std::copy(grps.begin(),grps.end(),std::ostream_iterator<std::string>(oss," ")); + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + return (*it).second; +} + +/*! + * Returns names of families constituting some groups. + * \param [in] grps - a sequence of names of groups of interest. + * \return std::vector<std::string> - a sequence of names of the families. + * \throw If a name of a nonexistent group is present in \a grps. + */ +std::vector<std::string> MEDFileMesh::getFamiliesOnGroups(const std::vector<std::string>& grps) const +{ + std::set<std::string> fams; + for(std::vector<std::string>::const_iterator it=grps.begin();it!=grps.end();it++) + { + std::map<std::string, std::vector<std::string> >::const_iterator it2=_groups.find(*it); + if(it2==_groups.end()) + { + std::ostringstream oss; oss << "No such group in mesh \"" << _name << "\" : " << *it; + std::vector<std::string> grps2=getGroupsNames(); oss << "\" !\nAvailable groups are :"; + std::copy(grps2.begin(),grps2.end(),std::ostream_iterator<std::string>(oss," ")); + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + fams.insert((*it2).second.begin(),(*it2).second.end()); + } + std::vector<std::string> fams2(fams.begin(),fams.end()); + return fams2; +} + +/*! + * Returns ids of families constituting a group. + * \param [in] name - the name of the group of interest. + * \return std::vector<int> - sequence of ids of the families. + * \throw If the name of a nonexistent group is specified. + */ +std::vector<int> MEDFileMesh::getFamiliesIdsOnGroup(const std::string& name) const +{ + std::string oname(name); + std::map<std::string, std::vector<std::string> >::const_iterator it=_groups.find(oname); + std::vector<std::string> grps=getGroupsNames(); + if(it==_groups.end()) + { + std::ostringstream oss; oss << "No such groupname \"" << name << "\" !\nAvailable groups are :"; + std::copy(grps.begin(),grps.end(),std::ostream_iterator<std::string>(oss," ")); + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + return getFamiliesIds((*it).second); +} + +/*! + * Sets names of families constituting a group. If data on families of this group is + * already present, it is overwritten. Every family in \a fams is checked, and if a + family is not yet in \a this mesh, the default group id \c 0 is assigned to it. + * \param [in] name - the name of the group of interest. + * \param [in] fams - a sequence of names of families constituting the group. + */ +void MEDFileMesh::setFamiliesOnGroup(const std::string& name, const std::vector<std::string>& fams) +{ + std::string oname(name); + _groups[oname]=fams; + for(std::vector<std::string>::const_iterator it1=fams.begin();it1!=fams.end();it1++) + { + std::map<std::string,int>::iterator it2=_families.find(*it1); + if(it2==_families.end()) + _families[*it1]=0; + } +} + +/*! + * Sets families constituting a group. The families are specified by their ids. + * If a family name is not found by its id, an exception is thrown. + * If several families have same id, the first one in lexical order is taken. + * \param [in] name - the name of the group of interest. + * \param [in] famIds - a sequence of ids of families constituting the group. + * \throw If a family name is not found by its id. + */ +void MEDFileMesh::setFamiliesIdsOnGroup(const std::string& name, const std::vector<int>& famIds) +{ + std::string oname(name); + std::vector<std::string> fams(famIds.size()); + int i=0; + for(std::vector<int>::const_iterator it1=famIds.begin();it1!=famIds.end();it1++,i++) + { + std::string name2=getFamilyNameGivenId(*it1); + fams[i]=name2; + } + _groups[oname]=fams; +} + +/*! + * Returns names of groups including a given family. + * \param [in] name - the name of the family of interest. + * \return std::vector<std::string> - a sequence of names of groups including the family. + */ +std::vector<std::string> MEDFileMesh::getGroupsOnFamily(const std::string& name) const +{ + std::vector<std::string> ret; + for(std::map<std::string, std::vector<std::string> >::const_iterator it1=_groups.begin();it1!=_groups.end();it1++) + { + for(std::vector<std::string>::const_iterator it2=(*it1).second.begin();it2!=(*it1).second.end();it2++) + if((*it2)==name) + { + ret.push_back((*it1).first); + break; + } + } + return ret; +} + +/*! + * Adds an existing family to groups. + * \param [in] famName - a name of family to add to \a grps. + * \param [in] grps - a sequence of group names to add the family in. + * \throw If a family named \a famName not yet exists. + */ +void MEDFileMesh::setGroupsOnFamily(const std::string& famName, const std::vector<std::string>& grps) +{ + std::string fName(famName); + const std::map<std::string,int>::const_iterator it=_families.find(fName); + if(it==_families.end()) + { + std::vector<std::string> fams=getFamiliesNames(); + std::ostringstream oss; oss << "No such familyname \"" << fName << "\" !\nAvailable families are :"; + std::copy(fams.begin(),fams.end(),std::ostream_iterator<std::string>(oss," ")); + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + for(std::vector<std::string>::const_iterator it3=grps.begin();it3!=grps.end();it3++) + { + std::map< std::string, std::vector<std::string> >::iterator it2=_groups.find(*it3); + if(it2!=_groups.end()) + (*it2).second.push_back(fName); + else + { + std::vector<std::string> grps2(1,fName); + _groups[*it3]=grps2; + } + } +} + +/*! + * Returns names of all groups of \a this mesh. + * \return std::vector<std::string> - a sequence of group names. + */ +std::vector<std::string> MEDFileMesh::getGroupsNames() const +{ + std::vector<std::string> ret(_groups.size()); + int i=0; + for(std::map<std::string, std::vector<std::string> >::const_iterator it=_groups.begin();it!=_groups.end();it++,i++) + ret[i]=(*it).first; + return ret; +} + +/*! + * Returns names of all families of \a this mesh. + * \return std::vector<std::string> - a sequence of family names. + */ +std::vector<std::string> MEDFileMesh::getFamiliesNames() const +{ + std::vector<std::string> ret(_families.size()); + int i=0; + for(std::map<std::string, int >::const_iterator it=_families.begin();it!=_families.end();it++,i++) + ret[i]=(*it).first; + return ret; +} + +/*! + * Changes a name of every family, included in one group only, to be same as the group name. + * \throw If there are families with equal names in \a this mesh. + */ +void MEDFileMesh::assignFamilyNameWithGroupName() +{ + std::map<std::string, std::vector<std::string> > groups(_groups); + std::map<std::string,int> newFams; + for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++) + { + std::vector<std::string> grps=getGroupsOnFamily((*it).first); + if(grps.size()==1 && groups[grps[0]].size()==1) + { + if(newFams.find(grps[0])!=newFams.end()) + { + std::ostringstream oss; oss << "MEDFileMesh::assignFamilyNameWithGroupName : Family \"" << grps[0] << "\" already exists !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + newFams[grps[0]]=(*it).second; + std::vector<std::string>& grps2=groups[grps[0]]; + std::size_t pos=std::distance(grps2.begin(),std::find(grps2.begin(),grps2.end(),(*it).first)); + grps2[pos]=grps[0]; + } + else + { + if(newFams.find((*it).first)!=newFams.end()) + { + std::ostringstream oss; oss << "MEDFileMesh::assignFamilyNameWithGroupName : Family \"" << (*it).first << "\" already exists !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + newFams[(*it).first]=(*it).second; + } + } + _families=newFams; + _groups=groups; +} + +/*! + * Removes all groups lying on no family. If there is no empty groups, \a this is let untouched. + * + * \return the removed groups. + */ +std::vector<std::string> MEDFileMesh::removeEmptyGroups() +{ + std::vector<std::string> ret; + std::map<std::string, std::vector<std::string> > newGrps; + for(std::map<std::string, std::vector<std::string> >::const_iterator it=_groups.begin();it!=_groups.end();it++) + { + if((*it).second.empty()) + ret.push_back((*it).first); + else + newGrps[(*it).first]=(*it).second; + } + if(!ret.empty()) + _groups=newGrps; + return ret; +} + +/*! + * Removes a group from \a this mesh. + * \param [in] name - the name of the group to remove. + * \throw If no group with such a \a name exists. + */ +void MEDFileMesh::removeGroup(const std::string& name) +{ + std::string oname(name); + std::map<std::string, std::vector<std::string> >::iterator it=_groups.find(oname); + std::vector<std::string> grps=getGroupsNames(); + if(it==_groups.end()) + { + std::ostringstream oss; oss << "No such groupname \"" << name << "\" !\nAvailable groups are :"; + std::copy(grps.begin(),grps.end(),std::ostream_iterator<std::string>(oss," ")); + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + _groups.erase(it); +} + +/*! + * Removes a family from \a this mesh. + * \param [in] name - the name of the family to remove. + * \throw If no family with such a \a name exists. + */ +void MEDFileMesh::removeFamily(const std::string& name) +{ + std::string oname(name); + std::map<std::string, int >::iterator it=_families.find(oname); + std::vector<std::string> fams=getFamiliesNames(); + if(it==_families.end()) + { + std::ostringstream oss; oss << "No such familyname \"" << name << "\" !\nAvailable families are :"; + std::copy(fams.begin(),fams.end(),std::ostream_iterator<std::string>(oss," ")); + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + _families.erase(it); + for(std::map<std::string, std::vector<std::string> >::iterator it3=_groups.begin();it3!=_groups.end();it3++) + { + std::vector<std::string>& v=(*it3).second; + std::vector<std::string>::iterator it4=std::find(v.begin(),v.end(),oname); + if(it4!=v.end()) + v.erase(it4); + } +} + +/*! + * Removes all groups in \a this that are orphan. A group is orphan if this group lies on + * a set of families, themselves orphan. A family is said orphan if its id appears nowhere in + * family field whatever its level. This method also suppresses the orphan families. + * + * \return - The list of removed groups names. + * + * \sa MEDFileMesh::removeOrphanFamilies. + */ +std::vector<std::string> MEDFileMesh::removeOrphanGroups() +{ + removeOrphanFamilies(); + return removeEmptyGroups(); +} + +/*! + * Removes all families in \a this that are orphan. A family is said orphan if its id appears nowhere in + * family field whatever its level. Groups are updated in consequence, that is to say all groups lying on orphan family, will see their families list modified. + * + * \return - The list of removed families names. + * \sa MEDFileMesh::removeOrphanGroups. + */ +std::vector<std::string> MEDFileMesh::removeOrphanFamilies() +{ + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> allFamIdsInUse=computeAllFamilyIdsInUse(); + std::vector<std::string> ret; + if(!((DataArrayInt*)allFamIdsInUse)) + { + ret=getFamiliesNames(); + _families.clear(); _groups.clear(); + return ret; + } + std::map<std::string,int> famMap; + std::map<std::string, std::vector<std::string> > grps(_groups); + for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++) + { + if(allFamIdsInUse->presenceOfValue((*it).second)) + famMap[(*it).first]=(*it).second; + else + { + ret.push_back((*it).first); + std::vector<std::string> grpsOnEraseFam=getGroupsOnFamily((*it).first); + for(std::vector<std::string>::const_iterator it2=grpsOnEraseFam.begin();it2!=grpsOnEraseFam.end();it2++) + { + std::map<std::string, std::vector<std::string> >::iterator it3=grps.find(*it2);//it3!=grps.empty() thanks to copy + std::vector<std::string>& famv=(*it3).second; + std::vector<std::string>::iterator it4=std::find(famv.begin(),famv.end(),(*it).first);//it4!=famv.end() thanks to copy + famv.erase(it4); + } + } + } + if(!ret.empty()) + { _families=famMap; _groups=grps; } + return ret; +} + +/*! + * This method operates only on maps in \a this. The arrays are not considered here. So this method will remove a family (except "FAMILLE_ZERO" family) if no group lies on it whatever + * this family is orphan or not. + * + * \warning this method is different from removeOrphanFamilies that scans family field array to find orphan families. + */ +void MEDFileMesh::removeFamiliesReferedByNoGroups() +{ + std::map<std::string,int> fams; + std::set<std::string> sfams; + for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++) + sfams.insert((*it).first); + for(std::map<std::string, std::vector<std::string> >::const_iterator it0=_groups.begin();it0!=_groups.end();it0++) + for(std::vector<std::string>::const_iterator it1=(*it0).second.begin();it1!=(*it0).second.end();it1++) + sfams.erase(*it1); + for(std::set<std::string>::const_iterator it=sfams.begin();it!=sfams.end();it++) + if(*it!=DFT_FAM_NAME) + _families.erase(*it); +} + +/*! + * This method has no impact on groups. This method only works on families. This method firstly removes families not refered by any groups in \a this, then all unused entities + * are put as belonging to family 0 ("FAMILLE_ZERO"). Finally, all orphanFamilies are killed. + * This method raises an exception if "FAMILLE_ZERO" is already belonging to a group. + * + * \sa MEDFileMesh::removeOrphanFamilies + */ +void MEDFileMesh::rearrangeFamilies() +{ + checkOrphanFamilyZero(); + removeFamiliesReferedByNoGroups(); + // + std::vector<int> levels(getNonEmptyLevelsExt()); + std::set<int> idsRefed; + for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++) + idsRefed.insert((*it).second); + for(std::vector<int>::const_iterator it=levels.begin();it!=levels.end();it++) + { + const DataArrayInt *fams(0); + try + { + fams=getFamilyFieldAtLevel(*it); + } + catch(INTERP_KERNEL::Exception& e) { } + if(!fams) + continue; + std::vector<bool> v(fams->getNumberOfTuples(),false); + for(std::set<int>::const_iterator pt=idsRefed.begin();pt!=idsRefed.end();pt++) + fams->switchOnTupleEqualTo(*pt,v); + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> unfetchedIds(DataArrayInt::BuildListOfSwitchedOff(v)); + if(!unfetchedIds->empty()) + { + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> newFams(fams->deepCpy()); + newFams->setPartOfValuesSimple3(0,unfetchedIds->begin(),unfetchedIds->end(),0,1,1); + setFamilyFieldArr(*it,newFams); + } + } + removeOrphanFamilies(); +} + +/*! + * This method only checks that "FAMILLE_ZERO" is orphan (not belonging to a group). + */ +void MEDFileMesh::checkOrphanFamilyZero() const +{ + for(std::map<std::string, std::vector<std::string> >::const_iterator it=_groups.begin();it!=_groups.end();it++) + { + if(std::find((*it).second.begin(),(*it).second.end(),DFT_FAM_NAME)!=(*it).second.end()) + { + std::ostringstream oss; oss << "MEDFileMesh::rearrangeFamilies : Groups \"" << (*it).first << "\" is lying on family \"" << DFT_FAM_NAME << "\" !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + } +} + +/*! + * Renames a group in \a this mesh. + * \param [in] oldName - a current name of the group to rename. + * \param [in] newName - a new group name. + * \throw If no group named \a oldName exists in \a this mesh. + * \throw If a group named \a newName already exists. + */ +void MEDFileMesh::changeGroupName(const std::string& oldName, const std::string& newName) +{ + std::string oname(oldName); + std::map<std::string, std::vector<std::string> >::iterator it=_groups.find(oname); + std::vector<std::string> grps=getGroupsNames(); + if(it==_groups.end()) + { + std::ostringstream oss; oss << "No such groupname \"" << oldName << "\" !\nAvailable groups are :"; + std::copy(grps.begin(),grps.end(),std::ostream_iterator<std::string>(oss," ")); + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + std::string nname(newName); + std::map<std::string, std::vector<std::string> >::iterator it2=_groups.find(nname); + if(it2!=_groups.end()) + { + std::ostringstream oss; oss << "Such groupname \"" << newName << "\" already exists ! Kill it before !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + std::vector<std::string> cpy=(*it).second; + _groups.erase(it); + _groups[newName]=cpy; +} + +/*! + * Changes an id of a family in \a this mesh. + * This method calls changeFamilyIdArr(). + * \param [in] oldId - a current id of the family. + * \param [in] newId - a new family id. + */ +void MEDFileMesh::changeFamilyId(int oldId, int newId) +{ + changeFamilyIdArr(oldId,newId); + std::map<std::string,int> fam2; + for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++) + { + if((*it).second==oldId) + fam2[(*it).first]=newId; + else + fam2[(*it).first]=(*it).second; + } + _families=fam2; +} + +/*! + * Renames a family in \a this mesh. + * \param [in] oldName - a current name of the family to rename. + * \param [in] newName - a new family name. + * \throw If no family named \a oldName exists in \a this mesh. + * \throw If a family named \a newName already exists. + */ +void MEDFileMesh::changeFamilyName(const std::string& oldName, const std::string& newName) +{ + std::string oname(oldName); + std::map<std::string, int >::iterator it=_families.find(oname); + std::vector<std::string> fams=getFamiliesNames(); + if(it==_families.end()) + { + std::ostringstream oss; oss << "No such familyname \"" << oldName << "\" !\nAvailable families are :"; + std::copy(fams.begin(),fams.end(),std::ostream_iterator<std::string>(oss," ")); + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + std::string nname(newName); + std::map<std::string, int >::iterator it2=_families.find(nname); + if(it2!=_families.end()) + { + std::ostringstream oss; oss << "Such familyname \"" << newName << " already exists ! Kill it before !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + int cpy=(*it).second; + _families.erase(it); + _families[newName]=cpy; + for(std::map<std::string, std::vector<std::string> >::iterator it3=_groups.begin();it3!=_groups.end();it3++) + { + std::vector<std::string>& v=(*it3).second; + std::vector<std::string>::iterator it4=std::find(v.begin(),v.end(),oname); + if(it4!=v.end()) + (*it4)=nname; + } +} + +/*! + * Checks if \a this and another mesh contains the same families. + * \param [in] other - the mesh to compare with \a this one. + * \param [in,out] what - an unused parameter. + * \return bool - \c true if number of families and their ids are the same in the two + * meshes. Families with the id == \c 0 are not considered. + */ +bool MEDFileMesh::areFamsEqual(const MEDFileMesh *other, std::string& what) const +{ + if(_families==other->_families) + return true; + std::map<std::string,int> fam0; + std::map<std::string,int> fam1; + for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++) + if((*it).second!=0) + fam0[(*it).first]=(*it).second; + for(std::map<std::string,int>::const_iterator it=other->_families.begin();it!=other->_families.end();it++) + if((*it).second!=0) + fam1[(*it).first]=(*it).second; + return fam0==fam1; +} + +/*! + * Checks if \a this and another mesh contains the same groups. + * \param [in] other - the mesh to compare with \a this one. + * \param [in,out] what - a string describing a difference of groups of the two meshes + * in case if this method returns \c false. + * \return bool - \c true if number of groups and families constituting them are the + * same in the two meshes. + */ +bool MEDFileMesh::areGrpsEqual(const MEDFileMesh *other, std::string& what) const +{ + if(_groups==other->_groups) + return true; + bool ret=true; + std::size_t sz=_groups.size(); + if(sz!=other->_groups.size()) + { + what="Groups differ because not same number !\n"; + ret=false; + } + if(ret) + { + std::map<std::string, std::vector<std::string> >::const_iterator it1=_groups.begin(); + for(std::size_t i=0;i<sz && ret;i++,it1++) + { + std::map<std::string, std::vector<std::string> >::const_iterator it2=other->_groups.find((*it1).first); + if(it2!=other->_groups.end()) + { + std::set<std::string> s1((*it1).second.begin(),(*it1).second.end()); + std::set<std::string> s2((*it2).second.begin(),(*it2).second.end()); + ret=(s1==s2); + } + else + { + ret=false; + what="A group in first mesh exists not in other !\n"; + } + } + } + if(!ret) + { + std::ostringstream oss; oss << "Groups description differs :\n"; + oss << "First group description :\n"; + for(std::map<std::string, std::vector<std::string> >::const_iterator it=_groups.begin();it!=_groups.end();it++) + { + oss << " Group \"" << (*it).first << "\" on following families :\n"; + for(std::vector<std::string>::const_iterator it2=(*it).second.begin();it2!=(*it).second.end();it2++) + oss << " \"" << *it2 << "\n"; + } + oss << "Second group description :\n"; + for(std::map<std::string, std::vector<std::string> >::const_iterator it=other->_groups.begin();it!=other->_groups.end();it++) + { + oss << " Group \"" << (*it).first << "\" on following families :\n"; + for(std::vector<std::string>::const_iterator it2=(*it).second.begin();it2!=(*it).second.end();it2++) + oss << " \"" << *it2 << "\n"; + } + what+=oss.str(); + } + return ret; +} + +/*! + * Checks if a group with a given name exists in \a this mesh. + * \param [in] groupName - the group name. + * \return bool - \c true the group \a groupName exists in \a this mesh. + */ +bool MEDFileMesh::existsGroup(const std::string& groupName) const +{ + std::string grpName(groupName); + return _groups.find(grpName)!=_groups.end(); +} + +/*! + * Checks if a family with a given id exists in \a this mesh. + * \param [in] famId - the family id. + * \return bool - \c true the family with the id \a famId exists in \a this mesh. + */ +bool MEDFileMesh::existsFamily(int famId) const +{ + for(std::map<std::string,int>::const_iterator it2=_families.begin();it2!=_families.end();it2++) + if((*it2).second==famId) + return true; + return false; +} + +/*! + * Checks if a family with a given name exists in \a this mesh. + * \param [in] familyName - the family name. + * \return bool - \c true the family \a familyName exists in \a this mesh. + */ +bool MEDFileMesh::existsFamily(const std::string& familyName) const +{ + std::string fname(familyName); + return _families.find(fname)!=_families.end(); +} + +/*! + * Sets an id of a family. + * \param [in] familyName - the family name. + * \param [in] id - a new id of the family. + */ +void MEDFileMesh::setFamilyId(const std::string& familyName, int id) +{ + std::string fname(familyName); + _families[fname]=id; +} + +void MEDFileMesh::setFamilyIdUnique(const std::string& familyName, int id) +{ + std::string fname(familyName); + for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++) + if((*it).second==id) + { + if((*it).first!=familyName) + { + std::ostringstream oss; oss << "MEDFileMesh::setFamilyIdUnique : Family id #" << id << " is already belonging to family with name \"" << (*it).first << "\" !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + } + _families[fname]=id; +} + +/*! + * Adds a family to \a this mesh. + * \param [in] familyName - a name of the family. + * \param [in] famId - an id of the family. + * \throw If a family with the same name or id already exists in \a this mesh. + */ +void MEDFileMesh::addFamily(const std::string& familyName, int famId) +{ + std::string fname(familyName); + std::map<std::string,int>::const_iterator it=_families.find(fname); + if(it==_families.end()) + { + for(std::map<std::string,int>::const_iterator it2=_families.begin();it2!=_families.end();it2++) + if((*it2).second==famId) + { + std::ostringstream oss; + oss << "MEDFileMesh::addFamily : Family \"" << (*it2).first << "\" already exists with specified id : " << famId << " !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + _families[fname]=famId; + } + else + { + if((*it).second!=famId) + { + std::ostringstream oss; + oss << "MEDFileMesh::addFamily : Family \"" << fname << "\" already exists but has id set to " << (*it).second << " different from asked famId " << famId << " !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + } +} + +/*! + * Creates a group including all mesh entities of given dimension. + * \warning This method does \b not guarantee that the created group includes mesh + * entities of only \a meshDimRelToMaxExt dimension in the case if some family id is + * present in family fields of different dimensions. To assure this, call + * ensureDifferentFamIdsPerLevel() \b before calling this method. + * \param [in] meshDimRelToMaxExt - a relative dimension of mesh entities to include to + * the group. + * \param [in] groupName - a name of the new group. + * \throw If a group named \a groupName already exists. + * \throw If no mesh entities of dimension \a meshDimRelToMaxExt exist in \a this mesh. + * \throw If no family field of dimension \a meshDimRelToMaxExt is present in \a this mesh. + */ +void MEDFileMesh::createGroupOnAll(int meshDimRelToMaxExt, const std::string& groupName) +{ + std::string grpName(groupName); + std::vector<int> levs=getNonEmptyLevelsExt(); + if(std::find(levs.begin(),levs.end(),meshDimRelToMaxExt)==levs.end()) + { + std::ostringstream oss; oss << "MEDFileMesh::createGroupOnAll : The relative ext dimension " << meshDimRelToMaxExt << " is not available !" << std::endl; + oss << "Available relative ext levels are : "; + std::copy(levs.begin(),levs.end(),std::ostream_iterator<int>(oss," ")); + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + if(existsGroup(groupName)) + { + std::ostringstream oss; oss << "MEDFileMesh::createGroupOnAll : The groups \"" << grpName << "\" already exists in this !" << std::endl; + oss << "Already existing groups are : "; + std::copy(levs.begin(),levs.end(),std::ostream_iterator<int>(oss," ")); + oss << std::endl << "Please choose an another group name or call removeGroup(\"" << grpName << "\") method !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + const DataArrayInt *fieldFamIds=getFamilyFieldAtLevel(meshDimRelToMaxExt); + if(fieldFamIds==0) + throw INTERP_KERNEL::Exception("MEDFileMesh::createGroupOnAll : Family field arr ids is not defined for this level !"); + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> famIds=fieldFamIds->getDifferentValues(); + std::vector<std::string> familiesOnWholeGroup; + for(const int *it=famIds->begin();it!=famIds->end();it++) + { + bool tmp; + familiesOnWholeGroup.push_back(findOrCreateAndGiveFamilyWithId(*it,tmp)); + } + _groups[grpName]=familiesOnWholeGroup; +} + +/*! + * Ensures that given family ids do not present in family fields of dimensions different + * than given ones. If a family id is present in the family fields of dimensions different + * than the given ones, a new family is created and the whole data is updated accordingly. + * \param [in] famIds - a sequence of family ids to check. + * \param [in] vMeshDimRelToMaxExt - a sequence of relative dimensions to which the \a + * famIds should exclusively belong. + * \return bool - \c true if no modification is done in \a this mesh by this method. + */ +bool MEDFileMesh::keepFamIdsOnlyOnLevs(const std::vector<int>& famIds, const std::vector<int>& vMeshDimRelToMaxExt) +{ + std::set<int> levsInput(vMeshDimRelToMaxExt.begin(),vMeshDimRelToMaxExt.end()); + std::vector<int> levs=getNonEmptyLevelsExt(); + std::set<int> levs2(levs.begin(),levs.end()); + std::vector<int> levsToTest; + std::set_difference(levs2.begin(),levs2.end(),levsInput.begin(),levsInput.end(),std::back_insert_iterator< std::vector<int> >(levsToTest)); + std::set<int> famIds2(famIds.begin(),famIds.end()); + bool ret=true; + int maxFamId=1; + if(!_families.empty()) + maxFamId=getMaxFamilyId()+1; + std::vector<std::string> allFams=getFamiliesNames(); + for(std::vector<int>::const_iterator it=levsToTest.begin();it!=levsToTest.end();it++) + { + const DataArrayInt *fieldFamIds=getFamilyFieldAtLevel(*it); + if(fieldFamIds) + { + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> famIds3=fieldFamIds->getDifferentValues(); + std::vector<int> tmp; + std::set_intersection(famIds3->begin(),famIds3->end(),famIds2.begin(),famIds2.end(),std::back_insert_iterator< std::vector<int> >(tmp)); + for(std::vector<int>::const_iterator it2=tmp.begin();it2!=tmp.end();it2++) + { + ret=false; + std::string famName=getFamilyNameGivenId(*it2); + std::ostringstream oss; oss << "Family_" << maxFamId; + std::string zeName=CreateNameNotIn(oss.str(),allFams); + addFamilyOnAllGroupsHaving(famName,zeName); + _families[zeName]=maxFamId; + (const_cast<DataArrayInt *>(fieldFamIds))->changeValue(*it2,maxFamId); + maxFamId++; + } + } + } + return ret; +} + +/*! + * Adds a family to a given group in \a this mesh. If the group with a given name does + * not exist, it is created. + * \param [in] grpName - the name of the group to add the family in. + * \param [in] famName - the name of the family to add to the group named \a grpName. + * \throw If \a grpName or \a famName is an empty string. + * \throw If no family named \a famName is present in \a this mesh. + */ +void MEDFileMesh::addFamilyOnGrp(const std::string& grpName, const std::string& famName) +{ + std::string grpn(grpName); + std::string famn(famName); + if(grpn.empty() || famn.empty()) + throw INTERP_KERNEL::Exception("MEDFileMesh::addFamilyOnGrp : input strings must be non null !"); + std::vector<std::string> fams=getFamiliesNames(); + if(std::find(fams.begin(),fams.end(),famn)==fams.end()) + { + std::ostringstream oss; oss << "MEDFileMesh::addFamilyOnGrp : Family \"" << famn << "\" does not exist !" << std::endl; + oss << "Create this family or choose an existing one ! Existing fams are : "; + std::copy(fams.begin(),fams.end(),std::ostream_iterator<std::string>(oss," ")); oss << "."; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + std::map<std::string, std::vector<std::string> >::iterator it=_groups.find(grpn); + if(it==_groups.end()) + { + _groups[grpn].push_back(famn); + } + else + { + std::vector<std::string>::iterator it2=std::find((*it).second.begin(),(*it).second.end(),famn); + if(it2==(*it).second.end()) + (*it).second.push_back(famn); + } +} + +/*! + * This method adds to all groups lying on family with name 'famName' the other family name 'otherFamName'. + * This method is quite underground because it can lead to unconsistency because family 'otherFamName' is \b not added into _families. + * This method is used by MEDFileMesh::keepFamIdsOnlyOnLevs method. + */ +void MEDFileMesh::addFamilyOnAllGroupsHaving(const std::string& famName, const std::string& otherFamName) +{ + std::string famNameCpp(famName); + std::string otherCpp(otherFamName); + for(std::map<std::string, std::vector<std::string> >::iterator it=_groups.begin();it!=_groups.end();it++) + { + std::vector<std::string>& v=(*it).second; + if(std::find(v.begin(),v.end(),famNameCpp)!=v.end()) + { + v.push_back(otherCpp); + } + } +} + +/*! + * \param [in] ids ids and group name of the new group to add. The ids should be sorted and different each other (MED file norm). + * \parma [in,out] famArr family array on level of interest to be renumbered. The input pointer should be not \c NULL (no check of that will be performed) + */ +void MEDFileMesh::addGroupUnderground(bool isNodeGroup, const DataArrayInt *ids, DataArrayInt *famArr) +{ + if(!ids) + throw INTERP_KERNEL::Exception("MEDFileUMesh::addGroup : NULL pointer in input !"); + std::string grpName(ids->getName()); + if(grpName.empty()) + throw INTERP_KERNEL::Exception("MEDFileUMesh::addGroup : empty group name ! MED file format do not accept empty group name !"); + ids->checkStrictlyMonotonic(true); + famArr->incrRef(); MEDCouplingAutoRefCountObjectPtr<DataArrayInt> famArrTmp(famArr); + std::vector<std::string> grpsNames=getGroupsNames(); + if(std::find(grpsNames.begin(),grpsNames.end(),grpName)!=grpsNames.end()) + { + std::ostringstream oss; oss << "MEDFileUMesh::addGroup : Group with name \"" << grpName << "\" already exists ! Destroy it before calling this method !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + std::list< MEDCouplingAutoRefCountObjectPtr<DataArrayInt> > allFamIds(getAllNonNullFamilyIds()); + allFamIds.erase(std::find(allFamIds.begin(),allFamIds.end(),famArrTmp)); + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> famIds=famArr->selectByTupleIdSafe(ids->begin(),ids->end()); + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> diffFamIds=famIds->getDifferentValues(); + std::vector<int> familyIds; + std::vector< MEDCouplingAutoRefCountObjectPtr<DataArrayInt> > idsPerfamiliyIds; + int maxVal=getTheMaxAbsFamilyId()+1; + std::map<std::string,int> families(_families); + std::map<std::string, std::vector<std::string> > groups(_groups); + std::vector<std::string> fams; + bool created(false); + for(const int *famId=diffFamIds->begin();famId!=diffFamIds->end();famId++) + { + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ids2Tmp=famIds->getIdsEqual(*famId); + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ids2=ids->selectByTupleId(ids2Tmp->begin(),ids2Tmp->end()); + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ids1=famArr->getIdsEqual(*famId); + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret0(ids1->buildSubstractionOptimized(ids2)); + if(ret0->empty()) + { + bool isFamPresent=false; + for(std::list< MEDCouplingAutoRefCountObjectPtr<DataArrayInt> >::const_iterator itl=allFamIds.begin();itl!=allFamIds.end() && !isFamPresent;itl++) + isFamPresent=(*itl)->presenceOfValue(*famId); + if(!isFamPresent) + { familyIds.push_back(*famId); idsPerfamiliyIds.push_back(ret0); fams.push_back(FindOrCreateAndGiveFamilyWithId(families,*famId,created)); } // adding *famId in grp + else + { + familyIds.push_back(isNodeGroup?maxVal:-maxVal); idsPerfamiliyIds.push_back(ids2); + std::string locFamName=FindOrCreateAndGiveFamilyWithId(families,isNodeGroup?maxVal:-maxVal,created); + fams.push_back(locFamName); + if(existsFamily(*famId)) + { + std::string locFamName2=getFamilyNameGivenId(*famId); std::vector<std::string> v(2); v[0]=locFamName2; v[1]=locFamName; + ChangeAllGroupsContainingFamily(groups,getFamilyNameGivenId(*famId),v); + } + maxVal++; + } // modifying all other groups on *famId to lie on maxVal and lie the grp on maxVal + } + else + { + familyIds.push_back(isNodeGroup?maxVal:-maxVal); idsPerfamiliyIds.push_back(ret0); // modifying all other groups on *famId to lie on maxVal and on maxVal+1 + familyIds.push_back(isNodeGroup?maxVal+1:-maxVal-1); idsPerfamiliyIds.push_back(ids2);//grp lie only on maxVal+1 + std::string n2(FindOrCreateAndGiveFamilyWithId(families,isNodeGroup?maxVal+1:-maxVal-1,created)); fams.push_back(n2); + if(existsFamily(*famId)) + { + std::string n1(FindOrCreateAndGiveFamilyWithId(families,isNodeGroup?maxVal:-maxVal,created)); std::vector<std::string> v(2); v[0]=n1; v[1]=n2; + ChangeAllGroupsContainingFamily(groups,getFamilyNameGivenId(*famId),v); + } + maxVal+=2; + } + } + for(std::size_t i=0;i<familyIds.size();i++) + { + DataArrayInt *da=idsPerfamiliyIds[i]; + famArr->setPartOfValuesSimple3(familyIds[i],da->begin(),da->end(),0,1,1); + } + _families=families; + _groups=groups; + _groups[grpName]=fams; +} + +void MEDFileMesh::changeAllGroupsContainingFamily(const std::string& familyNameToChange, const std::vector<std::string>& newFamiliesNames) +{ + ChangeAllGroupsContainingFamily(_groups,familyNameToChange,newFamiliesNames); +} + +void MEDFileMesh::ChangeAllGroupsContainingFamily(std::map<std::string, std::vector<std::string> >& groups, const std::string& familyNameToChange, const std::vector<std::string>& newFamiliesNames) +{ + std::string fam(familyNameToChange); + for(std::map<std::string, std::vector<std::string> >::iterator it=groups.begin();it!=groups.end();it++) + { + std::vector<std::string>& fams((*it).second); + std::vector<std::string>::iterator it2=std::find(fams.begin(),fams.end(),fam); + if(it2!=fams.end()) + { + fams.erase(it2); + fams.insert(fams.end(),newFamiliesNames.begin(),newFamiliesNames.end()); + } + } +} + +/*! + * Returns a name of the family having a given id or, if no such a family exists, creates + * a new uniquely named family and returns its name. + * \param [in] id - the id of the family whose name is required. + * \param [out] created - returns \c true if the new family has been created, \c false, else. + * \return std::string - the name of the existing or the created family. + * \throw If it is not possible to create a unique family name. + */ +std::string MEDFileMesh::findOrCreateAndGiveFamilyWithId(int id, bool& created) +{ + return FindOrCreateAndGiveFamilyWithId(_families,id,created); +} + +/*! + * If it exists a family whose family id is equal to 'id' this method behaves as MEDFileMesh::getFamilyNameGivenId. + * In this case, 'this' internal states remains unchanged and 'created' out parameter will be set to false. + * If there is no family whose family id is equal to 'id' a family is created with a name different from those + * already existing. In this case 'created' will be returned with a value set to true, and internal state + * will be modified. + * This method will throws an exception if it is not possible to create a unique family name. + */ +std::string MEDFileMesh::FindOrCreateAndGiveFamilyWithId(std::map<std::string,int>& families, int id, bool& created) +{ + std::vector<std::string> famAlreadyExisting(families.size()); + int ii=0; + for(std::map<std::string,int>::const_iterator it=families.begin();it!=families.end();it++,ii++) + { + if((*it).second!=id) + { + famAlreadyExisting[ii]=(*it).first; + } + else + { + created=false; + return (*it).first; + } + } + created=true; + std::ostringstream oss; oss << "Family_" << id; + std::string ret=CreateNameNotIn(oss.str(),famAlreadyExisting); + families[ret]=id; + return ret; +} + +/*! + * Sets names and ids of all families in \a this mesh. + * \param [in] info - a map of a family name to a family id. + */ +void MEDFileMesh::setFamilyInfo(const std::map<std::string,int>& info) +{ + _families=info; +} + +/*! + * Sets names of all groups and families constituting them in \a this mesh. + * \param [in] info - a map of a group name to a vector of names of families + * constituting the group. + */ +void MEDFileMesh::setGroupInfo(const std::map<std::string, std::vector<std::string> >&info) +{ + _groups=info; +} + +/*! + * Returns an id of the family having a given name. + * \param [in] name - the name of the family of interest. + * \return int - the id of the family of interest. + * \throw If no family with such a \a name exists. + */ +int MEDFileMesh::getFamilyId(const std::string& name) const +{ + std::string oname(name); + std::map<std::string, int>::const_iterator it=_families.find(oname); + std::vector<std::string> fams=getFamiliesNames(); + if(it==_families.end()) + { + std::ostringstream oss; oss << "No such familyname \"" << name << "\" !\nAvailable families are :"; + std::copy(fams.begin(),fams.end(),std::ostream_iterator<std::string>(oss," ")); + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + return (*it).second; +} + +/*! + * Returns ids of the families having given names. + * \param [in] fams - a sequence of the names of families of interest. + * \return std::vector<int> - a sequence of the ids of families of interest. + * \throw If \a fams contains a name of an inexistent family. + */ +std::vector<int> MEDFileMesh::getFamiliesIds(const std::vector<std::string>& fams) const +{ + std::vector<int> ret(fams.size()); + int i=0; + for(std::vector<std::string>::const_iterator it=fams.begin();it!=fams.end();it++,i++) + { + std::map<std::string, int>::const_iterator it2=_families.find(*it); + if(it2==_families.end()) + { + std::vector<std::string> fams2=getFamiliesNames(); + std::ostringstream oss; oss << "No such familyname \"" << *it << "\" in input list !\nAvailable families are :"; + std::copy(fams2.begin(),fams2.end(),std::ostream_iterator<std::string>(oss," ")); + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + ret[i]=(*it2).second; + } + return ret; +} + +/*! + * Returns a maximal abs(id) of families in \a this mesh. + * \return int - the maximal norm of family id. + * \throw If there are no families in \a this mesh. + */ +int MEDFileMesh::getMaxAbsFamilyId() const +{ + if(_families.empty()) + throw INTERP_KERNEL::Exception("MEDFileMesh::getMaxFamilyId : no families set !"); + int ret=-std::numeric_limits<int>::max(); + for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++) + { + ret=std::max(std::abs((*it).second),ret); + } + return ret; +} + +/*! + * Returns a maximal id of families in \a this mesh. + * \return int - the maximal family id. + * \throw If there are no families in \a this mesh. + */ +int MEDFileMesh::getMaxFamilyId() const +{ + if(_families.empty()) + throw INTERP_KERNEL::Exception("MEDFileMesh::getMaxFamilyId : no families set !"); + int ret=-std::numeric_limits<int>::max(); + for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++) + { + ret=std::max((*it).second,ret); + } + return ret; +} + +/*! + * Returns a minimal id of families in \a this mesh. + * \return int - the minimal family id. + * \throw If there are no families in \a this mesh. + */ +int MEDFileMesh::getMinFamilyId() const +{ + if(_families.empty()) + throw INTERP_KERNEL::Exception("MEDFileMesh::getMinFamilyId : no families set !"); + int ret=std::numeric_limits<int>::max(); + for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++) + { + ret=std::min((*it).second,ret); + } + return ret; +} + +/*! + * Returns a maximal id of families in \a this mesh. Not only named families are + * considered but all family fields as well. + * \return int - the maximal family id. + */ +int MEDFileMesh::getTheMaxAbsFamilyId() const +{ + int m1=-std::numeric_limits<int>::max(); + for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++) + m1=std::max(std::abs((*it).second),m1); + int m2=getMaxAbsFamilyIdInArrays(); + return std::max(m1,m2); +} + +/*! + * Returns a maximal id of families in \a this mesh. Not only named families are + * considered but all family fields as well. + * \return int - the maximal family id. + */ +int MEDFileMesh::getTheMaxFamilyId() const +{ + int m1=-std::numeric_limits<int>::max(); + for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++) + m1=std::max((*it).second,m1); + int m2=getMaxFamilyIdInArrays(); + return std::max(m1,m2); +} + +/*! + * Returns a minimal id of families in \a this mesh. Not only named families are + * considered but all family fields as well. + * \return int - the minimal family id. + */ +int MEDFileMesh::getTheMinFamilyId() const +{ + int m1=std::numeric_limits<int>::max(); + for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++) + m1=std::min((*it).second,m1); + int m2=getMinFamilyIdInArrays(); + return std::min(m1,m2); +} + +/*! + * This method only considers the maps. The contain of family array is ignored here. + * + * \sa MEDFileMesh::computeAllFamilyIdsInUse + */ +DataArrayInt *MEDFileMesh::getAllFamiliesIdsReferenced() const +{ + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret=DataArrayInt::New(); + std::set<int> v; + for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++) + v.insert((*it).second); + ret->alloc((int)v.size(),1); + std::copy(v.begin(),v.end(),ret->getPointer()); + return ret.retn(); +} + +/*! + * This method does not consider map of family name, family id. Only family field array on different levels is considered. + * + * \sa MEDFileMesh::getAllFamiliesIdsReferenced + */ +DataArrayInt *MEDFileMesh::computeAllFamilyIdsInUse() const +{ + std::vector<int> famLevs=getFamArrNonEmptyLevelsExt(); + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret; + for(std::vector<int>::const_iterator it=famLevs.begin();it!=famLevs.end();it++) + { + const DataArrayInt *arr=getFamilyFieldAtLevel(*it);//arr not null due to spec of getFamArrNonEmptyLevelsExt + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> dv=arr->getDifferentValues(); + if((DataArrayInt *) ret) + ret=dv->buildUnion(ret); + else + ret=dv; + } + return ret.retn(); +} + +/*! + * true is returned if no modification has been needed. false if family + * renumbering has been needed. + */ +bool MEDFileMesh::ensureDifferentFamIdsPerLevel() +{ + std::vector<int> levs=getNonEmptyLevelsExt(); + std::set<int> allFamIds; + int maxId=getMaxFamilyId()+1; + std::map<int,std::vector<int> > famIdsToRenum; + for(std::vector<int>::const_iterator it=levs.begin();it!=levs.end();it++) + { + const DataArrayInt *fam=getFamilyFieldAtLevel(*it); + if(fam) + { + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> tmp=fam->getDifferentValues(); + std::set<int> r2; + std::set_intersection(tmp->begin(),tmp->end(),allFamIds.begin(),allFamIds.end(),std::inserter(r2,r2.end())); + if(!r2.empty()) + famIdsToRenum[*it].insert(famIdsToRenum[*it].end(),r2.begin(),r2.end()); + std::set<int> r3; + std::set_union(tmp->begin(),tmp->end(),allFamIds.begin(),allFamIds.end(),std::inserter(r3,r3.end())); + } + } + if(famIdsToRenum.empty()) + return true; + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> allIds=getAllFamiliesIdsReferenced(); + for(std::map<int,std::vector<int> >::const_iterator it2=famIdsToRenum.begin();it2!=famIdsToRenum.end();it2++) + { + DataArrayInt *fam=const_cast<DataArrayInt *>(getFamilyFieldAtLevel((*it2).first)); + int *famIdsToChange=fam->getPointer(); + std::map<int,int> ren; + for(std::vector<int>::const_iterator it3=(*it2).second.begin();it3!=(*it2).second.end();it3++,maxId++) + { + if(allIds->presenceOfValue(*it3)) + { + std::string famName=getFamilyNameGivenId(*it3); + std::vector<std::string> grps=getGroupsOnFamily(famName); + ren[*it3]=maxId; + bool dummy; + std::string newFam=findOrCreateAndGiveFamilyWithId(maxId,dummy); + for(std::vector<std::string>::const_iterator it4=grps.begin();it4!=grps.end();it4++) + addFamilyOnGrp((*it4),newFam); + } + } + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ids=fam->getIdsEqualList(&(*it2).second[0],&(*it2).second[0]+(*it2).second.size()); + for(const int *id=ids->begin();id!=ids->end();id++) + famIdsToChange[*id]=ren[famIdsToChange[*id]]; + } + return false; +} + +/*! + * This method normalizes fam id with the policy explained underneath. This policy is close to those implemented in SMESH. + * Level #0 famids > 0, Level #-1 famids < 0, Level #-2 famids=0, Level #1 famids=0 + * This policy is those used by SMESH and Trio and that is the opposite of those in MED file. + * This method will throw an exception if a same family id is detected in different level. + * \warning This policy is the opposite of those in MED file documentation ... + */ +void MEDFileMesh::normalizeFamIdsTrio() +{ + ensureDifferentFamIdsPerLevel(); + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> allIds=getAllFamiliesIdsReferenced(); + std::vector<int> levs=getNonEmptyLevelsExt(); + std::set<int> levsS(levs.begin(),levs.end()); + std::set<std::string> famsFetched; + std::map<std::string,int> families; + if(std::find(levs.begin(),levs.end(),0)!=levs.end()) + { + levsS.erase(0); + const DataArrayInt *fam=getFamilyFieldAtLevel(0); + if(fam) + { + int refId=1; + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> tmp=fam->getDifferentValues(); + std::map<int,int> ren; + for(const int *it=tmp->begin();it!=tmp->end();it++,refId++) + ren[*it]=refId; + int nbOfTuples=fam->getNumberOfTuples(); + int *start=const_cast<DataArrayInt *>(fam)->getPointer(); + for(int *w=start;w!=start+nbOfTuples;w++) + *w=ren[*w]; + for(const int *it=tmp->begin();it!=tmp->end();it++) + { + if(allIds->presenceOfValue(*it)) + { + std::string famName=getFamilyNameGivenId(*it); + families[famName]=ren[*it]; + famsFetched.insert(famName); + } + } + } + } + if(std::find(levs.begin(),levs.end(),-1)!=levs.end()) + { + levsS.erase(-1); + const DataArrayInt *fam=getFamilyFieldAtLevel(-1); + if(fam) + { + int refId=-1; + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> tmp=fam->getDifferentValues(); + std::map<int,int> ren; + for(const int *it=tmp->begin();it!=tmp->end();it++,refId--) + ren[*it]=refId; + int nbOfTuples=fam->getNumberOfTuples(); + int *start=const_cast<DataArrayInt *>(fam)->getPointer(); + for(int *w=start;w!=start+nbOfTuples;w++) + *w=ren[*w]; + for(const int *it=tmp->begin();it!=tmp->end();it++) + { + if(allIds->presenceOfValue(*it)) + { + std::string famName=getFamilyNameGivenId(*it); + families[famName]=ren[*it]; + famsFetched.insert(famName); + } + } + } + } + for(std::set<int>::const_iterator it2=levsS.begin();it2!=levsS.end();it2++) + { + DataArrayInt *fam=const_cast<DataArrayInt*>(getFamilyFieldAtLevel(*it2)); + if(fam) + { + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> tmp=fam->getDifferentValues(); + fam->fillWithZero(); + for(const int *it3=tmp->begin();it3!=tmp->end();it3++) + if(allIds->presenceOfValue(*it3)) + { + std::string famName=getFamilyNameGivenId(*it3); + families[famName]=0; + famsFetched.insert(famName); + } + } + } + // + std::vector<std::string> allFams=getFamiliesNames(); + std::set<std::string> allFamsS(allFams.begin(),allFams.end()); + std::set<std::string> unFetchedIds; + std::set_difference(allFamsS.begin(),allFamsS.end(),famsFetched.begin(),famsFetched.end(),std::inserter(unFetchedIds,unFetchedIds.end())); + for(std::set<std::string>::const_iterator it4=unFetchedIds.begin();it4!=unFetchedIds.end();it4++) + families[*it4]=_families[*it4]; + _families=families; +} + +/*! + * This method normalizes fam id with the following policy. + * Level #0 famids < 0, Level #-1 famids < 0 and for Level #1 famids >= 0 + * This policy is those defined in the MED file format but is the opposite of those implemented in SMESH and Trio. + * This method will throw an exception if a same family id is detected in different level. + */ +void MEDFileMesh::normalizeFamIdsMEDFile() +{ + ensureDifferentFamIdsPerLevel(); + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> allIds=getAllFamiliesIdsReferenced(); + std::vector<int> levs=getNonEmptyLevelsExt(); + std::set<int> levsS(levs.begin(),levs.end()); + std::set<std::string> famsFetched; + std::map<std::string,int> families; + int refId=1; + if(std::find(levs.begin(),levs.end(),1)!=levs.end()) + { + levsS.erase(1); + const DataArrayInt *fam=getFamilyFieldAtLevel(1); + if(fam) + { + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> tmp=fam->getDifferentValues(); + std::map<int,int> ren; + for(const int *it=tmp->begin();it!=tmp->end();it++,refId++) + ren[*it]=refId; + int nbOfTuples=fam->getNumberOfTuples(); + int *start=const_cast<DataArrayInt *>(fam)->getPointer(); + for(int *w=start;w!=start+nbOfTuples;w++) + *w=ren[*w]; + for(const int *it=tmp->begin();it!=tmp->end();it++) + { + if(allIds->presenceOfValue(*it)) + { + std::string famName=getFamilyNameGivenId(*it); + families[famName]=ren[*it]; + famsFetched.insert(famName); + } + } + } + } + refId=-1; + for(std::set<int>::const_reverse_iterator it2=levsS.rbegin();it2!=levsS.rend();it2++) + { + const DataArrayInt *fam=getFamilyFieldAtLevel(*it2); + if(fam) + { + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> tmp=fam->getDifferentValues(); + std::map<int,int> ren; + for(const int *it=tmp->begin();it!=tmp->end();it++,refId--) + ren[*it]=refId; + int nbOfTuples=fam->getNumberOfTuples(); + int *start=const_cast<DataArrayInt *>(fam)->getPointer(); + for(int *w=start;w!=start+nbOfTuples;w++) + *w=ren[*w]; + for(const int *it=tmp->begin();it!=tmp->end();it++) + { + if(allIds->presenceOfValue(*it)) + { + std::string famName=getFamilyNameGivenId(*it); + families[famName]=ren[*it]; + famsFetched.insert(famName); + } + } + } + } + // + std::vector<std::string> allFams=getFamiliesNames(); + std::set<std::string> allFamsS(allFams.begin(),allFams.end()); + std::set<std::string> unFetchedIds; + std::set_difference(allFamsS.begin(),allFamsS.end(),famsFetched.begin(),famsFetched.end(),std::inserter(unFetchedIds,unFetchedIds.end())); + for(std::set<std::string>::const_iterator it4=unFetchedIds.begin();it4!=unFetchedIds.end();it4++) + families[*it4]=_families[*it4]; + _families=families; +} + +/*! + * Returns a name of the family by its id. If there are several families having the given + * id, the name first in lexical order is returned. + * \param [in] id - the id of the family whose name is required. + * \return std::string - the name of the found family. + * \throw If no family with the given \a id exists. + */ +std::string MEDFileMesh::getFamilyNameGivenId(int id) const +{ + for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++) + if((*it).second==id) + return (*it).first; + std::ostringstream oss; oss << "MEDFileUMesh::getFamilyNameGivenId : no such family id : " << id; + throw INTERP_KERNEL::Exception(oss.str().c_str()); +} + +/*! + * Returns a string describing \a this mesh. This description includes the mesh name and + * the mesh description string. + * \return std::string - the mesh information string. + */ +std::string MEDFileMesh::simpleRepr() const +{ + std::ostringstream oss; + oss << "(*************************************)\n(* GENERAL INFORMATION ON THE MESH : *)\n(*************************************)\n"; + oss << "- Name of the mesh : <<" << getName() << ">>\n"; + oss << "- Description associated to the mesh : " << getDescription() << std::endl; + return oss.str(); +} + +/*! + * This method is nearly like getFamilyFieldAtLevel method. Except that if the array does not exist at the specified level \a meshDimRelToMaxExt + * an empty one is created. + */ +DataArrayInt *MEDFileMesh::getOrCreateAndGetFamilyFieldAtLevel(int meshDimRelToMaxExt) +{ + DataArrayInt *ret(getFamilyFieldAtLevel(meshDimRelToMaxExt)); + if(ret) + return ret; + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> arr(DataArrayInt::New()); + arr->alloc(getSizeAtLevel(meshDimRelToMaxExt),1); + arr->fillWithZero(); + setFamilyFieldArr(meshDimRelToMaxExt,arr); + return getFamilyFieldAtLevel(meshDimRelToMaxExt); +} + +/*! + * Returns ids of mesh entities contained in a given group of a given dimension. + * \param [in] meshDimRelToMaxExt - a relative dimension of the mesh entities whose ids + * are required. + * \param [in] grp - the name of the group 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 group. The caller + * is to delete this array using decrRef() as it is no more needed. + * \throw If the name of a nonexistent group is specified. + * \throw If the family field is missing for \a meshDimRelToMaxExt. + */ +DataArrayInt *MEDFileMesh::getGroupArr(int meshDimRelToMaxExt, const std::string& grp, bool renum) const +{ + std::vector<std::string> tmp(1); + tmp[0]=grp; + DataArrayInt *ret=getGroupsArr(meshDimRelToMaxExt,tmp,renum); + ret->setName(grp); + return ret; +} + +/*! + * Returns ids of mesh entities contained in given groups of a given dimension. + * \param [in] meshDimRelToMaxExt - a relative dimension of the mesh entities whose ids + * are required. + * \param [in] grps - the names of the groups 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 groups. The caller + * is to delete this array using decrRef() as it is no more needed. + * \throw If the name of a nonexistent group is present in \a grps. + * \throw If the family field is missing for \a meshDimRelToMaxExt. + */ +DataArrayInt *MEDFileMesh::getGroupsArr(int meshDimRelToMaxExt, const std::vector<std::string>& grps, bool renum) const +{ + std::vector<std::string> fams2=getFamiliesOnGroups(grps); + return getFamiliesArr(meshDimRelToMaxExt,fams2,renum); +} + +/*! + * Returns ids of mesh entities contained in a given family of a given dimension. + * \param [in] meshDimRelToMaxExt - a relative dimension of the mesh entities whose ids + * are required. + * \param [in] fam - the name of the family 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 family. 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::getFamilyArr(int meshDimRelToMaxExt, const std::string& fam, bool renum) const +{ + std::vector<std::string> tmp(1); + tmp[0]=fam; + DataArrayInt *ret=getFamiliesArr(meshDimRelToMaxExt,tmp,renum); + ret->setName(fam); + return ret; +} + +/*! + * Returns ids of nodes contained in a given group. + * \param [in] grp - the name of the group of interest. + * \param [in] renum - if \c true, the optional numbers of nodes, if available, are + * returned instead of ids. + * \return DataArrayInt * - a new instance of DataArrayInt holding either ids or + * numbers, if available and required, of nodes of the group. The caller + * is to delete this array using decrRef() as it is no more needed. + * \throw If the name of a nonexistent group is specified. + * \throw If the family field is missing for nodes. + */ +DataArrayInt *MEDFileMesh::getNodeGroupArr(const std::string& grp, bool renum) const +{ + std::vector<std::string> tmp(1); + tmp[0]=grp; + DataArrayInt *ret=getNodeGroupsArr(tmp,renum); + ret->setName(grp); + return ret; +} + +/*! + * Returns ids of nodes contained in given groups. + * \param [in] grps - the names of the groups of interest. + * \param [in] renum - if \c true, the optional numbers of nodes, if available, are + * returned instead of ids. + * \return DataArrayInt * - a new instance of DataArrayInt holding either ids or + * numbers, if available and required, of nodes of the groups. The caller + * is to delete this array using decrRef() as it is no more needed. + * \throw If the name of a nonexistent group is present in \a grps. + * \throw If the family field is missing for nodes. + */ +DataArrayInt *MEDFileMesh::getNodeGroupsArr(const std::vector<std::string>& grps, bool renum) const +{ + return getGroupsArr(1,grps,renum); +} + +/*! + * Returns ids of nodes contained in a given group. + * \param [in] grp - the name of the group of interest. + * \param [in] renum - if \c true, the optional numbers of nodes, if available, are + * returned instead of ids. + * \return DataArrayInt * - a new instance of DataArrayInt holding either ids or + * numbers, if available and required, of nodes of the group. The caller + * is to delete this array using decrRef() as it is no more needed. + * \throw If the name of a nonexistent group is specified. + * \throw If the family field is missing for nodes. + */ +DataArrayInt *MEDFileMesh::getNodeFamilyArr(const std::string& fam, bool renum) const +{ + std::vector<std::string> tmp(1); + tmp[0]=fam; + DataArrayInt *ret=getNodeFamiliesArr(tmp,renum); + ret->setName(fam); + return ret; +} + +/*! + * Returns ids of nodes contained in given families. + * \param [in] fams - the names of the families of interest. + * \param [in] renum - if \c true, the optional numbers of nodes, if available, are + * returned instead of ids. + * \return DataArrayInt * - a new instance of DataArrayInt holding either ids or + * numbers, if available and required, of nodes 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 nodes. + */ +DataArrayInt *MEDFileMesh::getNodeFamiliesArr(const std::vector<std::string>& fams, bool renum) const +{ + return getFamiliesArr(1,fams,renum); +} + +/*! + * Adds groups of given dimension and creates corresponding families and family fields + * given ids of mesh entities of each group. + * \param [in] meshDimRelToMaxExt - the relative mesh dimension of given mesh entities. + * \param [in] grps - a sequence of arrays of ids each describing a group. + * \param [in] renum - \c true means that \a grps contains not ids but optional numbers + * of mesh entities. + * \throw If names of some groups in \a grps are equal. + * \throw If \a grps includes a group with an empty name. + * \throw If \a grps includes invalid ids (or numbers if \a renum == \c true ). + * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh. + */ +void MEDFileMesh::setGroupsAtLevel(int meshDimRelToMaxExt, const std::vector<const DataArrayInt *>& grps, bool renum) +{ + if(grps.empty()) + return ; + std::set<std::string> grpsName; + std::vector<std::string> grpsName2(grps.size()); + int i=0; + + for(std::vector<const DataArrayInt *>::const_iterator it=grps.begin();it!=grps.end();it++,i++) + { + grpsName.insert((*it)->getName()); + grpsName2[i]=(*it)->getName(); + } + if(grpsName.size()!=grps.size()) + throw INTERP_KERNEL::Exception("MEDFileUMesh::setGroupsAtLevel : groups name must be different each other !"); + if(grpsName.find(std::string(""))!=grpsName.end()) + throw INTERP_KERNEL::Exception("MEDFileUMesh::setGroupsAtLevel : groups name must be different empty string !"); + int sz=getSizeAtLevel(meshDimRelToMaxExt); + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> fam; + std::vector< std::vector<int> > fidsOfGroups; + if(!renum) + { + fam=DataArrayInt::MakePartition(grps,sz,fidsOfGroups); + } + else + { + std::vector< MEDCouplingAutoRefCountObjectPtr<DataArrayInt> > grps2(grps.size()); + for(unsigned int ii=0;ii<grps.size();ii++) + { + grps2[ii]=MEDFileUMeshSplitL1::Renumber(getRevNumberFieldAtLevel(meshDimRelToMaxExt),grps[ii]); + grps2[ii]->setName(grps[ii]->getName()); + } + std::vector<const DataArrayInt *> grps3(grps2.begin(),grps2.end()); + fam=DataArrayInt::MakePartition(grps3,sz,fidsOfGroups); + } + int offset=1; + if(!_families.empty()) + offset=getMaxAbsFamilyId()+1; + TranslateFamilyIds(meshDimRelToMaxExt==1?offset:-offset,fam,fidsOfGroups); + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ids=fam->getDifferentValues(); + appendFamilyEntries(ids,fidsOfGroups,grpsName2); + setFamilyFieldArr(meshDimRelToMaxExt,fam); +} + +/*! + * This method append into '_families' attribute the families whose ids are in 'famIds'. Warning 'famIds' are expected to be ids + * not in '_families'. Groups information are given in parameters in order to give to families representative names. + * For the moment, the two last input parameters are not taken into account. + */ +void MEDFileMesh::appendFamilyEntries(const DataArrayInt *famIds, const std::vector< std::vector<int> >& fidsOfGrps, const std::vector<std::string>& grpNames) +{ + std::map<int,std::string> famInv; + for(const int *it=famIds->begin();it!=famIds->end();it++) + { + std::ostringstream oss; + oss << "Family_" << (*it); + _families[oss.str()]=(*it); + famInv[*it]=oss.str(); + } + int i=0; + for(std::vector< std::vector<int> >::const_iterator it1=fidsOfGrps.begin();it1!=fidsOfGrps.end();it1++,i++) + { + for(std::vector<int>::const_iterator it2=(*it1).begin();it2!=(*it1).end();it2++) + { + _groups[grpNames[i]].push_back(famInv[*it2]); + } + } +} + +std::vector<INTERP_KERNEL::NormalizedCellType> MEDFileMesh::getAllGeoTypes() const +{ + std::vector<int> levs(getNonEmptyLevels()); + std::vector<INTERP_KERNEL::NormalizedCellType> ret; + for(std::vector<int>::const_iterator it=levs.begin();it!=levs.end();it++) + { + std::vector<INTERP_KERNEL::NormalizedCellType> elts(getGeoTypesAtLevel(*it)); + ret.insert(ret.end(),elts.begin(),elts.end()); + } + return ret; +} + +std::vector<int> MEDFileMesh::getDistributionOfTypes(int meshDimRelToMax) const +{ + MEDCouplingAutoRefCountObjectPtr<MEDCouplingMesh> mLev(getGenMeshAtLevel(meshDimRelToMax)); + return mLev->getDistributionOfTypes(); +} + +void MEDFileMesh::TranslateFamilyIds(int offset, DataArrayInt *famArr, std::vector< std::vector<int> >& famIdsPerGrp) +{ + famArr->applyLin(offset>0?1:-1,offset,0); + for(std::vector< std::vector<int> >::iterator it1=famIdsPerGrp.begin();it1!=famIdsPerGrp.end();it1++) + { + if(offset<0) + std::transform((*it1).begin(),(*it1).end(),(*it1).begin(),std::negate<int>()); + std::transform((*it1).begin(),(*it1).end(),(*it1).begin(),std::bind2nd(std::plus<int>(),offset)); + } +} + +/*! + * Warning no check is done on 'nameTry' in parameter. It should be non empty. + * This method returns a name close to 'nameTry' so that it is not already into 'namesToAvoid'. + * If this method fails to find such a name it will throw an exception. + */ +std::string MEDFileMesh::CreateNameNotIn(const std::string& nameTry, const std::vector<std::string>& namesToAvoid) +{ + //attempt #0 + if(std::find(namesToAvoid.begin(),namesToAvoid.end(),nameTry)==namesToAvoid.end()) + return nameTry; + //attempt #1 + std::size_t len=nameTry.length(); + for(std::size_t ii=1;ii<len;ii++) + { + std::string tmp=nameTry.substr(ii,len-ii); + if(std::find(namesToAvoid.begin(),namesToAvoid.end(),tmp)==namesToAvoid.end()) + return tmp; + } + //attempt #2 + if(len>=1) + { + for(std::size_t i=1;i<30;i++) + { + std::string tmp1(nameTry.at(0),i); + tmp1+=nameTry; + if(std::find(namesToAvoid.begin(),namesToAvoid.end(),tmp1)==namesToAvoid.end()) + return tmp1; + } + } + //attempt #3 + std::string tmp2; + for(std::vector<std::string>::const_iterator it2=namesToAvoid.begin();it2!=namesToAvoid.end();it2++) + tmp2+=(*it2); + if(std::find(namesToAvoid.begin(),namesToAvoid.end(),tmp2)==namesToAvoid.end()) + return tmp2; + throw INTERP_KERNEL::Exception("MEDFileMesh::CreateNameNotIn : impossible to find a not already used name !"); +} + +int MEDFileMesh::PutInThirdComponentOfCodeOffset(std::vector<int>& code, int strt) +{ + std::size_t nbOfChunks=code.size()/3; + if(code.size()%3!=0) + throw INTERP_KERNEL::Exception("MEDFileMesh::PutInThirdComponentOfCodeOffset : code has invalid size : should be of size 3*x !"); + int ret=strt; + for(std::size_t i=0;i<nbOfChunks;i++) + { + code[3*i+2]=ret; + ret+=code[3*i+1]; + } + return ret; +} + +/*! + * This method should be called by any set* method of subclasses to deal automatically with _name attribute. + * If _name attribute is empty the name of 'm' if taken as _name attribute. + * If _name is not empty and that 'm' has the same name nothing is done. + * If _name is not emplt and that 'm' has \b NOT the same name an exception is thrown. + */ +void MEDFileMesh::dealWithTinyInfo(const MEDCouplingMesh *m) +{ + if(!m) + throw INTERP_KERNEL::Exception("MEDFileMesh::dealWithTinyInfo : input mesh in NULL !"); + if(_name.empty()) + _name=m->getName(); + else + { + std::string name(m->getName()); + if(!name.empty()) + { + if(_name!=name) + { + std::ostringstream oss; oss << "MEDFileMesh::dealWithTinyInfo : name of current MEDfile mesh is '" << _name << "' whereas name of input mesh is : '"; + oss << name << "' ! Names must match !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + } + } + if(_desc_name.empty()) + _desc_name=m->getDescription(); + else + { + std::string name(m->getDescription()); + if(!name.empty()) + { + if(_desc_name!=name) + { + std::ostringstream oss; oss << "MEDFileMesh::dealWithTinyInfo : description of current MEDfile mesh is '" << _desc_name << "' whereas name of input mesh is : '"; + oss << name << "' ! Names must match !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + } + } +} + +void MEDFileMesh::getFamilyRepr(std::ostream& oss) const +{ + oss << "(**************************)\n(* FAMILIES OF THE MESH : *)\n(**************************)\n"; + for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++) + { + oss << "- Family with name \"" << (*it).first << "\" with number " << (*it).second << std::endl; + oss << " - Groups lying on this family : "; + std::vector<std::string> grps=getGroupsOnFamily((*it).first); + std::copy(grps.begin(),grps.end(),std::ostream_iterator<std::string>(oss," ")); + oss << std::endl << std::endl; + } +} + +/*! + * Returns a new MEDFileUMesh holding the mesh data that has been read from a given MED + * file. The mesh to load is specified by its name and numbers of a time step and an + * iteration. + * \param [in] fileName - the name of MED file to read. + * \param [in] mName - the name of the mesh to read. + * \param [in] dt - the number of a time step. + * \param [in] it - the number of an iteration. + * \return MEDFileUMesh * - a new instance of MEDFileUMesh. The caller is to delete this + * mesh using decrRef() as it is no more needed. + * \throw If the file is not readable. + * \throw If there is no mesh with given attributes in the file. + * \throw If the mesh in the file is not an unstructured one. + */ +MEDFileUMesh *MEDFileUMesh::New(const std::string& fileName, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs) +{ + MEDFileUtilities::CheckFileForRead(fileName); + MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName.c_str(),MED_ACC_RDONLY); + return new MEDFileUMesh(fid,mName,dt,it,mrs); +} + +/*! + * Returns a new MEDFileUMesh holding the mesh data that has been read from a given MED + * file. The first mesh in the file is loaded. + * \param [in] fileName - the name of MED file to read. + * \return MEDFileUMesh * - a new instance of MEDFileUMesh. The caller is to delete this + * mesh using decrRef() as it is no more needed. + * \throw If the file is not readable. + * \throw If there is no meshes in the file. + * \throw If the mesh in the file is not an unstructured one. + */ +MEDFileUMesh *MEDFileUMesh::New(const std::string& fileName, MEDFileMeshReadSelector *mrs) +{ + std::vector<std::string> ms=MEDLoader::GetMeshNames(fileName); + if(ms.empty()) + { + std::ostringstream oss; oss << "MEDFileUMesh::New : no meshes in file \"" << fileName << "\" !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + MEDFileUtilities::CheckFileForRead(fileName); + MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName.c_str(),MED_ACC_RDONLY); + int dt,it; + ParaMEDMEM::MEDCouplingMeshType meshType; + std::string dummy2; + MEDFileMeshL2::GetMeshIdFromName(fid,ms.front(),meshType,dt,it,dummy2); + return new MEDFileUMesh(fid,ms.front(),dt,it,mrs); +} + +/*! + * Returns an empty instance of MEDFileUMesh. + * \return MEDFileUMesh * - a new instance of MEDFileUMesh. The caller is to delete this + * mesh using decrRef() as it is no more needed. + */ +MEDFileUMesh *MEDFileUMesh::New() +{ + return new MEDFileUMesh; +} + +/*! + * This method loads from file with name \a fileName the mesh called \a mName as New does. The difference is that + * here only a part of cells contained in the file will be loaded. The selection of cell is specified using the two consecutive parameters + * \a types and \a slicPerTyp. This method allows to load from a mesh (typically huge) in a MED file a part of cells of that mesh. + * The part of cells is specified using triplet (start,stop,step) for each geometric type. Only nodes lying on selected cells will be loaded to reduce + * at most the memory consumtion. + * + * \param [in] fileName - the name of the file. + * \param [in] mName - the name of the mesh to be read. + * \param [in] types - the list of the geo types of which some part will be taken. A geometric type in \a types must appear only once at most. + * \param [in] slicPerType - an array of size 3 times larger than \a types that specifies for each type in \a types (in the same order) resp the start, the stop and the step. + * \param [in] dt - the iteration, that is to say the first element of the pair that locates the asked time step. + * \param [in] it - the order, that is to say the second element of the pair that locates the asked time step. + * \param [in] mrs - the request for what to be loaded. + * \return MEDFileUMesh * - a new instance of MEDFileUMesh. The caller is to delete this mesh using decrRef() as it is no more needed. + */ +MEDFileUMesh *MEDFileUMesh::LoadPartOf(const std::string& fileName, const std::string& mName, const std::vector<INTERP_KERNEL::NormalizedCellType>& types, const std::vector<int>& slicPerTyp, int dt, int it, MEDFileMeshReadSelector *mrs) +{ + MEDFileUtilities::CheckFileForRead(fileName); + MEDFileUtilities::AutoFid fid(MEDfileOpen(fileName.c_str(),MED_ACC_RDONLY)); + return MEDFileUMesh::LoadPartOf(fid,mName,types,slicPerTyp,dt,it,mrs); +} + +/*! + * Please refer to the other MEDFileUMesh::LoadPartOf method that has the same semantic and the same parameter (excepted the first). + * This method is \b NOT wrapped into python. + */ +MEDFileUMesh *MEDFileUMesh::LoadPartOf(med_idt fid, const std::string& mName, const std::vector<INTERP_KERNEL::NormalizedCellType>& types, const std::vector<int>& slicPerTyp, int dt, int it, MEDFileMeshReadSelector *mrs) +{ + MEDCouplingAutoRefCountObjectPtr<MEDFileUMesh> ret(MEDFileUMesh::New()); + ret->loadPartUMeshFromFile(fid,mName,types,slicPerTyp,dt,it,mrs); + return ret.retn(); +} + +std::size_t MEDFileUMesh::getHeapMemorySizeWithoutChildren() const +{ + std::size_t ret(MEDFileMesh::getHeapMemorySizeWithoutChildren()); + ret+=_ms.capacity()*(sizeof(MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1>)); + return ret; +} + +std::vector<const BigMemoryObject *> MEDFileUMesh::getDirectChildrenWithNull() const +{ + std::vector<const BigMemoryObject *> ret(MEDFileMesh::getDirectChildrenWithNull()); + ret.push_back((const DataArrayDouble*)_coords); + ret.push_back((const DataArrayInt *)_fam_coords); + ret.push_back((const DataArrayInt *)_num_coords); + ret.push_back((const DataArrayInt *)_rev_num_coords); + ret.push_back((const DataArrayAsciiChar *)_name_coords); + ret.push_back((const PartDefinition *)_part_coords); + for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++) + ret.push_back((const MEDFileUMeshSplitL1*) *it); + return ret; +} + +MEDFileMesh *MEDFileUMesh::shallowCpy() const +{ + MEDCouplingAutoRefCountObjectPtr<MEDFileUMesh> ret=new MEDFileUMesh(*this); + return ret.retn(); +} + +MEDFileMesh *MEDFileUMesh::createNewEmpty() const +{ + return new MEDFileUMesh; +} + +MEDFileMesh *MEDFileUMesh::deepCpy() const +{ + MEDCouplingAutoRefCountObjectPtr<MEDFileUMesh> ret=new MEDFileUMesh(*this); + if((const DataArrayDouble*)_coords) + ret->_coords=_coords->deepCpy(); + if((const DataArrayInt*)_fam_coords) + ret->_fam_coords=_fam_coords->deepCpy(); + if((const DataArrayInt*)_num_coords) + ret->_num_coords=_num_coords->deepCpy(); + if((const DataArrayInt*)_rev_num_coords) + ret->_rev_num_coords=_rev_num_coords->deepCpy(); + if((const DataArrayAsciiChar*)_name_coords) + ret->_name_coords=_name_coords->deepCpy(); + std::size_t i=0; + for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++,i++) + { + if((const MEDFileUMeshSplitL1 *)(*it)) + ret->_ms[i]=(*it)->deepCpy(ret->_coords); + } + if((const PartDefinition*)_part_coords) + ret->_part_coords=_part_coords->deepCpy(); + return ret.retn(); +} + +/*! + * Checks if \a this and another mesh are equal. + * \param [in] other - the mesh to compare with. + * \param [in] eps - a precision used to compare real values. + * \param [in,out] what - the string returning description of unequal data. + * \return bool - \c true if the meshes are equal, \c false, else. + */ +bool MEDFileUMesh::isEqual(const MEDFileMesh *other, double eps, std::string& what) const +{ + if(!MEDFileMesh::isEqual(other,eps,what)) + return false; + const MEDFileUMesh *otherC=dynamic_cast<const MEDFileUMesh *>(other); + if(!otherC) + { + what="Mesh types differ ! This is unstructured and other is NOT !"; + return false; + } + clearNonDiscrAttributes(); + otherC->clearNonDiscrAttributes(); + const DataArrayDouble *coo1=_coords; + const DataArrayDouble *coo2=otherC->_coords; + if((coo1==0 && coo2!=0) || (coo1!=0 && coo2==0)) + { + what="Mismatch of coordinates ! One is defined and not other !"; + return false; + } + if(coo1) + { + bool ret=coo1->isEqual(*coo2,eps); + if(!ret) + { + what="Coords differ !"; + return false; + } + } + const DataArrayInt *famc1=_fam_coords; + const DataArrayInt *famc2=otherC->_fam_coords; + if((famc1==0 && famc2!=0) || (famc1!=0 && famc2==0)) + { + what="Mismatch of families arr on nodes ! One is defined and not other !"; + return false; + } + if(famc1) + { + bool ret=famc1->isEqual(*famc2); + if(!ret) + { + what="Families arr on node differ !"; + return false; + } + } + const DataArrayInt *numc1=_num_coords; + const DataArrayInt *numc2=otherC->_num_coords; + if((numc1==0 && numc2!=0) || (numc1!=0 && numc2==0)) + { + what="Mismatch of numbering arr on nodes ! One is defined and not other !"; + return false; + } + if(numc1) + { + bool ret=numc1->isEqual(*numc2); + if(!ret) + { + what="Numbering arr on node differ !"; + return false; + } + } + const DataArrayAsciiChar *namec1=_name_coords; + const DataArrayAsciiChar *namec2=otherC->_name_coords; + if((namec1==0 && namec2!=0) || (namec1!=0 && namec2==0)) + { + what="Mismatch of naming arr on nodes ! One is defined and not other !"; + return false; + } + if(namec1) + { + bool ret=namec1->isEqual(*namec2); + if(!ret) + { + what="Names arr on node differ !"; + return false; + } + } + if(_ms.size()!=otherC->_ms.size()) + { + what="Number of levels differs !"; + return false; + } + std::size_t sz=_ms.size(); + for(std::size_t i=0;i<sz;i++) + { + const MEDFileUMeshSplitL1 *s1=_ms[i]; + const MEDFileUMeshSplitL1 *s2=otherC->_ms[i]; + if((s1==0 && s2!=0) || (s1!=0 && s2==0)) + { + what="Mismatch of presence of sub levels !"; + return false; + } + if(s1) + { + bool ret=s1->isEqual(s2,eps,what); + if(!ret) + return false; + } + } + const PartDefinition *pd0(_part_coords),*pd1(otherC->_part_coords); + if(!pd0 && !pd1) + return true; + if((!pd0 && pd1) || (pd0 && !pd1)) + { + what=std::string("node part def is defined only for one among this or other !"); + return false; + } + return pd0->isEqual(pd1,what); +} + +/*! + * Clears redundant attributes of incorporated data arrays. + */ +void MEDFileUMesh::clearNonDiscrAttributes() const +{ + MEDFileMesh::clearNonDiscrAttributes(); + const DataArrayDouble *coo1=_coords; + if(coo1) + (const_cast<DataArrayDouble *>(coo1))->setName("");//This parameter is not discriminant for comparison + const DataArrayInt *famc1=_fam_coords; + if(famc1) + (const_cast<DataArrayInt *>(famc1))->setName("");//This parameter is not discriminant for comparison + const DataArrayInt *numc1=_num_coords; + if(numc1) + (const_cast<DataArrayInt *>(numc1))->setName("");//This parameter is not discriminant for comparison + const DataArrayAsciiChar *namc1=_name_coords; + if(namc1) + (const_cast<DataArrayAsciiChar *>(namc1))->setName("");//This parameter is not discriminant for comparison + for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++) + { + const MEDFileUMeshSplitL1 *tmp=(*it); + if(tmp) + tmp->clearNonDiscrAttributes(); + } +} + +void MEDFileUMesh::setName(const std::string& name) +{ + for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> >::iterator it=_ms.begin();it!=_ms.end();it++) + if((MEDFileUMeshSplitL1 *)(*it)!=0) + (*it)->setName(name); + MEDFileMesh::setName(name); +} + +MEDFileUMesh::MEDFileUMesh() +{ +} + +MEDFileUMesh::MEDFileUMesh(med_idt fid, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs) +try +{ + loadUMeshFromFile(fid,mName,dt,it,mrs); + loadJointsFromFile(fid); + } +catch(INTERP_KERNEL::Exception& e) +{ + throw e; +} + +/*! + * This method loads only a part of specified cells (given by range of cell ID per geometric type) + * See MEDFileUMesh::LoadPartOf for detailed description. + * + * \sa loadUMeshFromFile + */ +void MEDFileUMesh::loadPartUMeshFromFile(med_idt fid, const std::string& mName, const std::vector<INTERP_KERNEL::NormalizedCellType>& types, const std::vector<int>& slicPerTyp, int dt, int it, MEDFileMeshReadSelector *mrs) +{ + MEDFileUMeshL2 loaderl2; + ParaMEDMEM::MEDCouplingMeshType meshType; + int dummy0,dummy1; + std::string dummy2; + int mid(MEDFileUMeshL2::GetMeshIdFromName(fid,mName,meshType,dummy0,dummy1,dummy2)); + if(meshType!=UNSTRUCTURED) + { + std::ostringstream oss; oss << "loadPartUMeshFromFile : Trying to load as unstructured an existing mesh with name '" << mName << "' !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + loaderl2.loadPart(fid,mid,mName,types,slicPerTyp,dt,it,mrs); + dispatchLoadedPart(fid,loaderl2,mName,mrs); +} + +/*! + * \brief Write joints in a file + */ +void MEDFileMesh::writeJoints(med_idt fid) const +{ + if ( (const MEDFileJoints*) _joints ) + _joints->write(fid); +} + +/*! + * \brief Load joints in a file or use provided ones + */ +//================================================================================ +/*! + * \brief Load joints in a file or use provided ones + * \param [in] fid - MED file descriptor + * \param [in] toUseInstedOfReading - optional joints to use instead of reading, + * Usually this joints are those just read by another iteration + * of namesake mesh, when this method is called by MEDFileMeshMultiTS::New() + */ +//================================================================================ + +void MEDFileMesh::loadJointsFromFile(med_idt fid, MEDFileJoints* toUseInstedOfReading) +{ + if ( toUseInstedOfReading ) + setJoints( toUseInstedOfReading ); + else + _joints = MEDFileJoints::New( fid, _name ); +} + +/*! + * \brief Return number of joints, which is equal to number of adjacent mesh domains + */ +int MEDFileMesh::getNumberOfJoints() +{ + return ( (MEDFileJoints*) _joints ) ? _joints->getNumberOfJoints() : 0; +} + +/*! + * \brief Return joints with all adjacent mesh domains + */ +MEDFileJoints * MEDFileMesh::getJoints() const +{ + return const_cast<MEDFileJoints*>(& (*_joints)); +} + +void MEDFileMesh::setJoints( MEDFileJoints* joints ) +{ + if ( joints != _joints ) + { + _joints = joints; + if ( joints ) + joints->incrRef(); + } +} + +/*! + * This method loads \b all \b the \b mesh \a mName in the file with \a fid descriptor. + * + * \sa loadPartUMeshFromFile + */ +void MEDFileUMesh::loadUMeshFromFile(med_idt fid, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs) +{ + MEDFileUMeshL2 loaderl2; + ParaMEDMEM::MEDCouplingMeshType meshType; + int dummy0,dummy1; + std::string dummy2; + int mid(MEDFileUMeshL2::GetMeshIdFromName(fid,mName,meshType,dummy0,dummy1,dummy2)); + if(meshType!=UNSTRUCTURED) + { + std::ostringstream oss; oss << "Trying to load as unstructured an existing mesh with name '" << mName << "' !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + loaderl2.loadAll(fid,mid,mName,dt,it,mrs); + dispatchLoadedPart(fid,loaderl2,mName,mrs); +} + +void MEDFileUMesh::dispatchLoadedPart(med_idt fid, const MEDFileUMeshL2& loaderl2, const std::string& mName, MEDFileMeshReadSelector *mrs) +{ + int lev=loaderl2.getNumberOfLevels(); + _ms.resize(lev); + for(int i=0;i<lev;i++) + { + if(!loaderl2.emptyLev(i)) + _ms[i]=new MEDFileUMeshSplitL1(loaderl2,mName,i); + else + _ms[i]=0; + } + MEDFileMeshL2::ReadFamiliesAndGrps(fid,mName,_families,_groups,mrs); + // + setName(loaderl2.getName()); + setDescription(loaderl2.getDescription()); + setUnivName(loaderl2.getUnivName()); + setIteration(loaderl2.getIteration()); + setOrder(loaderl2.getOrder()); + setTimeValue(loaderl2.getTime()); + setTimeUnit(loaderl2.getTimeUnit()); + _coords=loaderl2.getCoords(); + if(!mrs || mrs->isNodeFamilyFieldReading()) + _fam_coords=loaderl2.getCoordsFamily(); + if(!mrs || mrs->isNodeNumFieldReading()) + _num_coords=loaderl2.getCoordsNum(); + if(!mrs || mrs->isNodeNameFieldReading()) + _name_coords=loaderl2.getCoordsName(); + _part_coords=loaderl2.getPartDefOfCoo(); + computeRevNum(); +} + +MEDFileUMesh::~MEDFileUMesh() +{ +} + +void MEDFileUMesh::writeLL(med_idt fid) const +{ + const DataArrayDouble *coo=_coords; + INTERP_KERNEL::AutoPtr<char> maa=MEDLoaderBase::buildEmptyString(MED_NAME_SIZE); + INTERP_KERNEL::AutoPtr<char> desc=MEDLoaderBase::buildEmptyString(MED_COMMENT_SIZE); + MEDLoaderBase::safeStrCpy(_name.c_str(),MED_NAME_SIZE,maa,_too_long_str); + MEDLoaderBase::safeStrCpy(_desc_name.c_str(),MED_COMMENT_SIZE,desc,_too_long_str); + int spaceDim=coo?coo->getNumberOfComponents():0; + int mdim(0); + if(!_ms.empty()) + mdim=getMeshDimension(); + INTERP_KERNEL::AutoPtr<char> comp=MEDLoaderBase::buildEmptyString(spaceDim*MED_SNAME_SIZE); + INTERP_KERNEL::AutoPtr<char> unit=MEDLoaderBase::buildEmptyString(spaceDim*MED_SNAME_SIZE); + for(int i=0;i<spaceDim;i++) + { + std::string info=coo->getInfoOnComponent(i); + std::string c,u; + MEDLoaderBase::splitIntoNameAndUnit(info,c,u); + MEDLoaderBase::safeStrCpy2(c.c_str(),MED_SNAME_SIZE-1,comp+i*MED_SNAME_SIZE,_too_long_str);//MED_TAILLE_PNOM-1 to avoid to write '\0' on next compo + MEDLoaderBase::safeStrCpy2(u.c_str(),MED_SNAME_SIZE-1,unit+i*MED_SNAME_SIZE,_too_long_str);//MED_TAILLE_PNOM-1 to avoid to write '\0' on next compo + } + MEDFILESAFECALLERWR0(MEDmeshCr,(fid,maa,spaceDim,mdim,MED_UNSTRUCTURED_MESH,desc,"",MED_SORT_DTIT,MED_CARTESIAN,comp,unit)); + if(_univ_wr_status) + MEDFILESAFECALLERWR0(MEDmeshUniversalNameWr,(fid,maa)); + std::string meshName(MEDLoaderBase::buildStringFromFortran(maa,MED_NAME_SIZE)); + MEDFileUMeshL2::WriteCoords(fid,meshName,_iteration,_order,_time,_coords,_fam_coords,_num_coords,_name_coords); + for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++) + if((const MEDFileUMeshSplitL1 *)(*it)!=0) + (*it)->write(fid,meshName,mdim); + MEDFileUMeshL2::WriteFamiliesAndGrps(fid,meshName,_families,_groups,_too_long_str); + + writeJoints(fid); +} + +/*! + * Returns relative dimensions of mesh entities (excluding nodes) present in \a this mesh. + * \return std::vector<int> - a sequence of the relative dimensions. + */ +std::vector<int> MEDFileUMesh::getNonEmptyLevels() const +{ + std::vector<int> ret; + int lev=0; + for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++,lev--) + if((const MEDFileUMeshSplitL1 *)(*it)!=0) + if(!(*it)->empty()) + ret.push_back(lev); + return ret; +} + +/*! + * Returns relative dimensions of mesh entities (including nodes) present in \a this mesh. + * \return std::vector<int> - a sequence of the relative dimensions. + */ +std::vector<int> MEDFileUMesh::getNonEmptyLevelsExt() const +{ + std::vector<int> ret0=getNonEmptyLevels(); + if((const DataArrayDouble *) _coords) + { + std::vector<int> ret(ret0.size()+1); + ret[0]=1; + std::copy(ret0.begin(),ret0.end(),ret.begin()+1); + return ret; + } + return ret0; +} + +std::vector<int> MEDFileUMesh::getFamArrNonEmptyLevelsExt() const +{ + std::vector<int> ret; + const DataArrayInt *famCoo(_fam_coords); + if(famCoo) + ret.push_back(1); + int lev=0; + for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++,lev--) + { + const MEDFileUMeshSplitL1 *cur(*it); + if(cur) + if(cur->getFamilyField()) + ret.push_back(lev); + } + return ret; +} + +std::vector<int> MEDFileUMesh::getNumArrNonEmptyLevelsExt() const +{ + std::vector<int> ret; + const DataArrayInt *numCoo(_num_coords); + if(numCoo) + ret.push_back(1); + int lev=0; + for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++,lev--) + { + const MEDFileUMeshSplitL1 *cur(*it); + if(cur) + if(cur->getNumberField()) + ret.push_back(lev); + } + return ret; +} + +std::vector<int> MEDFileUMesh::getNameArrNonEmptyLevelsExt() const +{ + std::vector<int> ret; + const DataArrayAsciiChar *nameCoo(_name_coords); + if(nameCoo) + ret.push_back(1); + int lev=0; + for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++,lev--) + { + const MEDFileUMeshSplitL1 *cur(*it); + if(cur) + if(cur->getNameField()) + ret.push_back(lev); + } + return ret; +} + +/*! + * Returns all relative mesh levels (**excluding nodes**) where a given group is defined. + * To include nodes, call getGrpNonEmptyLevelsExt() method. + * \param [in] grp - the name of the group of interest. + * \return std::vector<int> - a sequence of the relative dimensions. + */ +std::vector<int> MEDFileUMesh::getGrpNonEmptyLevels(const std::string& grp) const +{ + std::vector<std::string> fams=getFamiliesOnGroup(grp); + return getFamsNonEmptyLevels(fams); +} + +/*! + * Returns all relative mesh levels (including nodes) where a given group is defined. + * \param [in] grp - the name of the group of interest. + * \return std::vector<int> - a sequence of the relative dimensions. + */ +std::vector<int> MEDFileUMesh::getGrpNonEmptyLevelsExt(const std::string& grp) const +{ + std::vector<std::string> fams=getFamiliesOnGroup(grp); + return getFamsNonEmptyLevelsExt(fams); +} + +/*! + * Returns all relative mesh levels (**excluding nodes**) where a given family is defined. + * To include nodes, call getFamNonEmptyLevelsExt() method. + * \param [in] fam - the name of the family of interest. + * \return std::vector<int> - a sequence of the relative dimensions. + */ +std::vector<int> MEDFileUMesh::getFamNonEmptyLevels(const std::string& fam) const +{ + std::vector<std::string> fams(1,std::string(fam)); + return getFamsNonEmptyLevels(fams); +} + +/*! + * Returns all relative mesh levels (including nodes) where a given family is defined. + * \param [in] fam - the name of the family of interest. + * \return std::vector<int> - a sequence of the relative dimensions. + */ +std::vector<int> MEDFileUMesh::getFamNonEmptyLevelsExt(const std::string& fam) const +{ + std::vector<std::string> fams(1,std::string(fam)); + return getFamsNonEmptyLevelsExt(fams); +} + +/*! + * Returns all relative mesh levels (**excluding nodes**) where given groups are defined. + * To include nodes, call getGrpsNonEmptyLevelsExt() method. + * \param [in] grps - a sequence of names of the groups of interest. + * \return std::vector<int> - a sequence of the relative dimensions. + */ +std::vector<int> MEDFileUMesh::getGrpsNonEmptyLevels(const std::vector<std::string>& grps) const +{ + std::vector<std::string> fams=getFamiliesOnGroups(grps); + return getFamsNonEmptyLevels(fams); +} + +/*! + * Returns all relative mesh levels (including nodes) where given groups are defined. + * \param [in] grps - a sequence of names of the groups of interest. + * \return std::vector<int> - a sequence of the relative dimensions. + */ +std::vector<int> MEDFileUMesh::getGrpsNonEmptyLevelsExt(const std::vector<std::string>& grps) const +{ + std::vector<std::string> fams=getFamiliesOnGroups(grps); + return getFamsNonEmptyLevelsExt(fams); +} + +/*! + * Returns all relative mesh levels (**excluding nodes**) where given families are defined. + * To include nodes, call getFamsNonEmptyLevelsExt() method. + * \param [in] fams - the name of the family of interest. + * \return std::vector<int> - a sequence of the relative dimensions. + */ +std::vector<int> MEDFileUMesh::getFamsNonEmptyLevels(const std::vector<std::string>& fams) const +{ + std::vector<int> ret; + std::vector<int> levs=getNonEmptyLevels(); + std::vector<int> famIds=getFamiliesIds(fams); + for(std::vector<int>::const_iterator it=levs.begin();it!=levs.end();it++) + if(_ms[-(*it)]->presenceOfOneFams(famIds)) + ret.push_back(*it); + return ret; +} + +/*! + * Returns all relative mesh levels (including nodes) where given families are defined. + * \param [in] fams - the names of the families of interest. + * \return std::vector<int> - a sequence of the relative dimensions. + */ +std::vector<int> MEDFileUMesh::getFamsNonEmptyLevelsExt(const std::vector<std::string>& fams) const +{ + std::vector<int> ret0=getFamsNonEmptyLevels(fams); + const DataArrayInt *famCoords=_fam_coords; + if(!famCoords) + return ret0; + std::vector<int> famIds=getFamiliesIds(fams); + if(famCoords->presenceOfValue(famIds)) + { + std::vector<int> ret(ret0.size()+1); + ret[0]=1; + std::copy(ret0.begin(),ret0.end(),ret.begin()+1); + return ret; + } + else + return ret0; +} + +/*! + * Returns names of groups that partly or fully appear on the level \a meshDimRelToMaxExt. + * \param [in] meshDimRelToMaxExt - a relative dimension of interest. + * \return std::vector<std::string> - a sequence of group names at \a meshDimRelToMaxExt + * level. + */ +std::vector<std::string> MEDFileUMesh::getGroupsOnSpecifiedLev(int meshDimRelToMaxExt) const +{ + std::vector<std::string> ret; + std::vector<std::string> allGrps=getGroupsNames(); + for(std::vector<std::string>::const_iterator it=allGrps.begin();it!=allGrps.end();it++) + { + std::vector<int> levs=getGrpNonEmptyLevelsExt((*it)); + if(std::find(levs.begin(),levs.end(),meshDimRelToMaxExt)!=levs.end()) + ret.push_back(*it); + } + return ret; +} + +int MEDFileUMesh::getMaxAbsFamilyIdInArrays() const +{ + int ret=-std::numeric_limits<int>::max(),tmp=-1; + if((const DataArrayInt *)_fam_coords) + { + int val=_fam_coords->getMaxValue(tmp); + ret=std::max(ret,std::abs(val)); + } + for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++) + { + if((const MEDFileUMeshSplitL1 *)(*it)) + { + const DataArrayInt *da=(*it)->getFamilyField(); + if(da) + { + int val=da->getMaxValue(tmp); + ret=std::max(ret,std::abs(val)); + } + } + } + return ret; +} + +int MEDFileUMesh::getMaxFamilyIdInArrays() const +{ + int ret=-std::numeric_limits<int>::max(),tmp=-1; + if((const DataArrayInt *)_fam_coords) + { + int val=_fam_coords->getMaxValue(tmp); + ret=std::max(ret,val); + } + for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++) + { + if((const MEDFileUMeshSplitL1 *)(*it)) + { + const DataArrayInt *da=(*it)->getFamilyField(); + if(da) + { + int val=da->getMaxValue(tmp); + ret=std::max(ret,val); + } + } + } + return ret; +} + +int MEDFileUMesh::getMinFamilyIdInArrays() const +{ + int ret=std::numeric_limits<int>::max(),tmp=-1; + if((const DataArrayInt *)_fam_coords) + { + int val=_fam_coords->getMinValue(tmp); + ret=std::min(ret,val); + } + for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++) + { + if((const MEDFileUMeshSplitL1 *)(*it)) + { + const DataArrayInt *da=(*it)->getFamilyField(); + if(da) + { + int val=da->getMinValue(tmp); + ret=std::min(ret,val); + } + } + } + return ret; +} + +/*! + * Returns the dimension on cells in \a this mesh. + * \return int - the mesh dimension. + * \throw If there are no cells in this mesh. + */ +int MEDFileUMesh::getMeshDimension() const +{ + int lev=0; + for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++,lev++) + if((const MEDFileUMeshSplitL1 *)(*it)!=0) + return (*it)->getMeshDimension()+lev; + throw INTERP_KERNEL::Exception("MEDFileUMesh::getMeshDimension : impossible to find a mesh dimension !"); +} + +/*! + * Returns the space dimension of \a this mesh that is equal to number of components in + * the node coordinates array. + * \return int - the space dimension of \a this mesh. + * \throw If the node coordinates array is not available. + */ +int MEDFileUMesh::getSpaceDimension() const +{ + const DataArrayDouble *coo=_coords; + if(!coo) + throw INTERP_KERNEL::Exception(" MEDFileUMesh::getSpaceDimension : no coords set !"); + return coo->getNumberOfComponents(); +} + +/*! + * Returns a string describing \a this mesh. + * \return std::string - the mesh information string. + */ +std::string MEDFileUMesh::simpleRepr() const +{ + std::ostringstream oss; + oss << MEDFileMesh::simpleRepr(); + const DataArrayDouble *coo=_coords; + oss << "- The dimension of the space is "; + static const char MSG1[]= "*** NO COORDS SET ***"; + static const char MSG2[]= "*** NO CONNECTIVITY SET FOR THIS LEVEL***"; + if(coo) + oss << _coords->getNumberOfComponents() << std::endl; + else + oss << MSG1 << std::endl; + oss << "- Type of the mesh : UNSTRUCTURED\n"; + oss << "- Number of nodes : "; + if(coo) + oss << _coords->getNumberOfTuples() << std::endl; + else + oss << MSG1 << std::endl; + std::size_t nbOfLev=_ms.size(); + oss << "- Number of levels allocated : " << nbOfLev << std::endl; + for(std::size_t i=0;i<nbOfLev;i++) + { + const MEDFileUMeshSplitL1 *lev=_ms[i]; + oss << " - Level #" << -((int) i) << " has dimension : "; + if(lev) + { + oss << lev->getMeshDimension() << std::endl; + lev->simpleRepr(oss); + } + else + oss << MSG2 << std::endl; + } + oss << "- Number of families : " << _families.size() << std::endl << std::endl; + if(coo) + { + oss << "(***********************)\n(* NODES OF THE MESH : *)\n(***********************)\n"; + oss << "- Names of coordinates :" << std::endl; + std::vector<std::string> vars=coo->getVarsOnComponent(); + std::copy(vars.begin(),vars.end(),std::ostream_iterator<std::string>(oss," ")); + oss << std::endl << "- Units of coordinates : " << std::endl; + std::vector<std::string> units=coo->getUnitsOnComponent(); + std::copy(units.begin(),units.end(),std::ostream_iterator<std::string>(oss," ")); + } + oss << std::endl << std::endl; + getFamilyRepr(oss); + return oss.str(); +} + +/*! + * Returns a full textual description of \a this mesh. + * \return std::string - the string holding the mesh description. + */ +std::string MEDFileUMesh::advancedRepr() const +{ + return simpleRepr(); +} + +/*! + * 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 MEDFileUMesh::getSizeAtLevel(int meshDimRelToMaxExt) const +{ + if(meshDimRelToMaxExt==1) + { + if(!((const DataArrayDouble *)_coords)) + throw INTERP_KERNEL::Exception("MEDFileUMesh::getSizeAtLevel : no coordinates specified !"); + return _coords->getNumberOfTuples(); + } + return getMeshAtLevSafe(meshDimRelToMaxExt)->getSize(); +} + +/*! + * 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 \c NULL. + */ +const DataArrayInt *MEDFileUMesh::getFamilyFieldAtLevel(int meshDimRelToMaxExt) const +{ + if(meshDimRelToMaxExt==1) + return _fam_coords; + const MEDFileUMeshSplitL1 *l1(getMeshAtLevSafe(meshDimRelToMaxExt)); + return l1->getFamilyField(); +} + +DataArrayInt *MEDFileUMesh::getFamilyFieldAtLevel(int meshDimRelToMaxExt) +{ + if(meshDimRelToMaxExt==1) + return _fam_coords; + MEDFileUMeshSplitL1 *l1(getMeshAtLevSafe(meshDimRelToMaxExt)); + return l1->getFamilyField(); +} + +/*! + * 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 *MEDFileUMesh::getNumberFieldAtLevel(int meshDimRelToMaxExt) const +{ + if(meshDimRelToMaxExt==1) + return _num_coords; + const MEDFileUMeshSplitL1 *l1=getMeshAtLevSafe(meshDimRelToMaxExt); + return l1->getNumberField(); +} + +const DataArrayAsciiChar *MEDFileUMesh::getNameFieldAtLevel(int meshDimRelToMaxExt) const +{ + if(meshDimRelToMaxExt==1) + return _name_coords; + const MEDFileUMeshSplitL1 *l1=getMeshAtLevSafe(meshDimRelToMaxExt); + return l1->getNameField(); +} + +/*! + * This method returns for a specified relative level \a meshDimRelToMaxExt the part effectively read (if the instance is the result of the read of a file). + * + * \param [in] meshDimRelToMaxExt - the extended relative level for which the part definition is requested. + * \param [in] gt - The input geometric type for which the part definition is requested. + * \return the part definition owned by \a this. So no need to deallocate the returned instance. + */ +const PartDefinition *MEDFileUMesh::getPartDefAtLevel(int meshDimRelToMaxExt, INTERP_KERNEL::NormalizedCellType gt) const +{ + if(meshDimRelToMaxExt==1) + return _part_coords; + const MEDFileUMeshSplitL1 *l1(getMeshAtLevSafe(meshDimRelToMaxExt)); + return l1->getPartDef(gt); +} + +int MEDFileUMesh::getNumberOfNodes() const +{ + const DataArrayDouble *coo(_coords); + if(!coo) + throw INTERP_KERNEL::Exception(" MEDFileUMesh::getNumberOfNodes : no coords set !"); + return coo->getNumberOfTuples(); +} + +int MEDFileUMesh::getNumberOfCellsAtLevel(int meshDimRelToMaxExt) const +{ + const MEDFileUMeshSplitL1 *l1(getMeshAtLevSafe(meshDimRelToMaxExt)); + return l1->getNumberOfCells(); +} + +bool MEDFileUMesh::hasImplicitPart() const +{ + return false; +} + +int MEDFileUMesh::buildImplicitPartIfAny(INTERP_KERNEL::NormalizedCellType gt) const +{ + throw INTERP_KERNEL::Exception("MEDFileUMesh::buildImplicitPartIfAny : unstructured meshes do not have implicit part !"); +} + +void MEDFileUMesh::releaseImplicitPartIfAny() const +{ +} + +void MEDFileUMesh::whichAreNodesFetched(const MEDFileField1TSStructItem& st, const MEDFileFieldGlobsReal *globs, std::vector<bool>& nodesFetched) const +{ + std::size_t sz(st.getNumberOfItems()); + for(std::size_t i=0;i<sz;i++) + { + INTERP_KERNEL::NormalizedCellType curGt(st[i].getGeo()); + const MEDCoupling1GTUMesh *m(getDirectUndergroundSingleGeoTypeMesh(curGt)); + if(st[i].getPflName().empty()) + m->computeNodeIdsAlg(nodesFetched); + else + { + const DataArrayInt *arr(globs->getProfile(st[i].getPflName())); + MEDCouplingAutoRefCountObjectPtr<MEDCoupling1GTUMesh> m2(dynamic_cast<MEDCoupling1GTUMesh *>(m->buildPartOfMySelf(arr->begin(),arr->end(),true))); + m2->computeNodeIdsAlg(nodesFetched); + } + } +} + +/*! + * 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 *MEDFileUMesh::getRevNumberFieldAtLevel(int meshDimRelToMaxExt) const +{ + if(meshDimRelToMaxExt==1) + { + if(!((const DataArrayInt *)_num_coords)) + throw INTERP_KERNEL::Exception("MEDFileUMesh::getRevNumberFieldAtLevel : no coordinates renum specified !"); + return _rev_num_coords; + } + const MEDFileUMeshSplitL1 *l1=getMeshAtLevSafe(meshDimRelToMaxExt); + return l1->getRevNumberField(); +} + +/*! + * 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 *MEDFileUMesh::getCoords() const +{ + MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> tmp(_coords); + if((DataArrayDouble *)tmp) + { + return tmp; + } + return 0; +} + +/*! + * Returns a new MEDCouplingUMesh corresponding to mesh entities included in a given + * group of \a this mesh. Only mesh entities of a given dimension are included in the + * new mesh. + * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities of interest. + * \param [in] grp - the name of the group whose mesh entities are included in the + * new mesh. + * \param [in] renum - if \c true, cells and nodes of the result mesh are permuted + * according to the optional numbers of entities, if available. + * \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 name of a nonexistent group is specified. + * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh. + */ +MEDCouplingUMesh *MEDFileUMesh::getGroup(int meshDimRelToMaxExt, const std::string& grp, bool renum) const +{ + synchronizeTinyInfoOnLeaves(); + std::vector<std::string> tmp(1); + tmp[0]=grp; + return getGroups(meshDimRelToMaxExt,tmp,renum); +} + +/*! + * Returns a new MEDCouplingUMesh corresponding to mesh entities included in given + * groups of \a this mesh. Only mesh entities of a given dimension are included in the + * new mesh. + * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities of interest. + * \param [in] grps - a sequence of group names whose mesh entities are included in the + * new mesh. + * \param [in] renum - if \c true, cells and nodes of the result mesh are permuted + * according to the optional numbers of entities, if available. + * \return MEDCouplingUMesh * - a new instance of MEDCouplingUMesh. The caller is to + * delete this mesh using decrRef() as it is no more needed. + * \throw If a name of a nonexistent group is present in \a grps. + * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh. + */ +MEDCouplingUMesh *MEDFileUMesh::getGroups(int meshDimRelToMaxExt, const std::vector<std::string>& grps, bool renum) const +{ + synchronizeTinyInfoOnLeaves(); + std::vector<std::string> fams2=getFamiliesOnGroups(grps); + MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> zeRet=getFamilies(meshDimRelToMaxExt,fams2,renum); + if(grps.size()==1 && ((MEDCouplingUMesh *)zeRet)) + zeRet->setName(grps[0]); + return zeRet.retn(); +} + +/*! + * Returns a new MEDCouplingUMesh corresponding to mesh entities included in a given + * family of \a this mesh. Only mesh entities of a given dimension are included in the + * new mesh. + * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities of interest. + * \param [in] fam - the name of the family whose mesh entities are included in the + * new mesh. + * \param [in] renum - if \c true, cells and nodes of the result mesh are permuted + * according to the optional numbers of entities, if available. + * \return MEDCouplingUMesh * - a new instance of MEDCouplingUMesh. The caller is to + * delete this mesh using decrRef() as it is no more needed. + * \throw If a name of a nonexistent family is present in \a grps. + * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh. + */ +MEDCouplingUMesh *MEDFileUMesh::getFamily(int meshDimRelToMaxExt, const std::string& fam, bool renum) const +{ + synchronizeTinyInfoOnLeaves(); + std::vector<std::string> tmp(1); + tmp[0]=fam; + return getFamilies(meshDimRelToMaxExt,tmp,renum); +} + +/*! + * Returns a new MEDCouplingUMesh corresponding to mesh entities included in given + * families of \a this mesh. Only mesh entities of a given dimension are included in the + * new mesh. + * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities of interest. + * \param [in] fams - a sequence of family names whose mesh entities are included in the + * new mesh. + * \param [in] renum - if \c true, cells and nodes of the result mesh are permuted + * according to the optional numbers of entities, if available. + * \return MEDCouplingUMesh * - a new instance of MEDCouplingUMesh. The caller is to + * delete this mesh using decrRef() as it is no more needed. + * \throw If a name of a nonexistent family is present in \a fams. + * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh. + */ +MEDCouplingUMesh *MEDFileUMesh::getFamilies(int meshDimRelToMaxExt, const std::vector<std::string>& fams, bool renum) const +{ + synchronizeTinyInfoOnLeaves(); + if(meshDimRelToMaxExt==1) + { + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> arr=getFamiliesArr(1,fams,renum); + MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> ret=MEDCouplingUMesh::New(); + MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> c=_coords->selectByTupleId(arr->getConstPointer(),arr->getConstPointer()+arr->getNbOfElems()); + ret->setCoords(c); + return ret.retn(); + } + std::vector<int> famIds=getFamiliesIds(fams); + const MEDFileUMeshSplitL1 *l1=getMeshAtLevSafe(meshDimRelToMaxExt); + MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> zeRet; + if(!famIds.empty()) + zeRet=l1->getFamilyPart(&famIds[0],&famIds[0]+famIds.size(),renum); + else + zeRet=l1->getFamilyPart(0,0,renum); + if(fams.size()==1 && ((MEDCouplingUMesh *)zeRet)) + zeRet->setName(fams[0]); + return zeRet.retn(); +} + +/*! + * 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 *MEDFileUMesh::getFamiliesArr(int meshDimRelToMaxExt, const std::vector<std::string>& fams, bool renum) const +{ + std::vector<int> famIds=getFamiliesIds(fams); + if(meshDimRelToMaxExt==1) + { + if((const DataArrayInt *)_fam_coords) + { + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> da; + if(!famIds.empty()) + da=_fam_coords->getIdsEqualList(&famIds[0],&famIds[0]+famIds.size()); + else + da=_fam_coords->getIdsEqualList(0,0); + if(renum) + return MEDFileUMeshSplitL1::Renumber(_num_coords,da); + else + return da.retn(); + } + else + throw INTERP_KERNEL::Exception("MEDFileUMesh::getFamiliesArr : no family array specified on nodes !"); + } + const MEDFileUMeshSplitL1 *l1=getMeshAtLevSafe(meshDimRelToMaxExt); + if(!famIds.empty()) + return l1->getFamilyPartArr(&famIds[0],&famIds[0]+famIds.size(),renum); + else + return l1->getFamilyPartArr(0,0,renum); +} + +/*! + * Returns a MEDCouplingUMesh of a given relative dimension. + * \warning If \a meshDimRelToMaxExt == 1 (which means nodes), the returned mesh **is not + * valid**. This is a feature, because MEDLoader does not create cells that do not exist! + * To build a valid MEDCouplingUMesh from the returned one in this case, + * call MEDCouplingUMesh::Build0DMeshFromCoords(). + * \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 MEDCouplingUMesh * - a pointer to MEDCouplingUMesh 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. + * \sa getGenMeshAtLevel() + */ +MEDCouplingUMesh *MEDFileUMesh::getMeshAtLevel(int meshDimRelToMaxExt, bool renum) const +{ + synchronizeTinyInfoOnLeaves(); + if(meshDimRelToMaxExt==1) + { + if(!renum) + { + MEDCouplingUMesh *umesh=MEDCouplingUMesh::New(); + MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> cc=_coords->deepCpy(); + umesh->setCoords(cc); + MEDFileUMeshSplitL1::ClearNonDiscrAttributes(umesh); + umesh->setName(getName()); + return umesh; + } + } + const MEDFileUMeshSplitL1 *l1=getMeshAtLevSafe(meshDimRelToMaxExt); + return l1->getWholeMesh(renum); +} + +/*! + * Returns a MEDCouplingUMesh of a given relative dimension. + * \warning If \a meshDimRelToMaxExt == 1 (which means nodes), the returned mesh **is not + * valid**. This is a feature, because MEDLoader does not create cells that do not exist! + * To build a valid MEDCouplingUMesh from the returned one in this case, + * call MEDCouplingUMesh::Build0DMeshFromCoords(). + * \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 MEDCouplingUMesh that the caller is to + * delete using decrRef() as it is no more needed. + * \throw If there are no mesh entities of \a meshDimRelToMax dimension in \a this mesh. + * \sa getMeshAtLevel() + */ +MEDCouplingMesh *MEDFileUMesh::getGenMeshAtLevel(int meshDimRelToMax, bool renum) const +{ + return getMeshAtLevel(meshDimRelToMax,renum); +} + +std::vector<int> MEDFileUMesh::getDistributionOfTypes(int meshDimRelToMax) const +{ + const MEDFileUMeshSplitL1 *l1(getMeshAtLevSafe(meshDimRelToMax)); + return l1->getDistributionOfTypes(); +} + +/*! + * Returns a MEDCouplingUMesh of a relative dimension == 0. + * \param [in] renum - if \c true, the returned mesh is permuted according to the + * optional numbers of mesh entities. + * \return MEDCouplingUMesh * - a pointer to MEDCouplingUMesh that the caller is to + * delete using decrRef() as it is no more needed. + * \throw If there are no mesh entities of the relative dimension == 0 in \a this mesh. + */ +MEDCouplingUMesh *MEDFileUMesh::getLevel0Mesh(bool renum) const +{ + return getMeshAtLevel(0,renum); +} + +/*! + * Returns a MEDCouplingUMesh of a relative dimension == -1. + * \param [in] renum - if \c true, the returned mesh is permuted according to the + * optional numbers of mesh entities. + * \return MEDCouplingUMesh * - a pointer to MEDCouplingUMesh that the caller is to + * delete using decrRef() as it is no more needed. + * \throw If there are no mesh entities of the relative dimension == -1 in \a this mesh. + */ +MEDCouplingUMesh *MEDFileUMesh::getLevelM1Mesh(bool renum) const +{ + return getMeshAtLevel(-1,renum); +} + +/*! + * Returns a MEDCouplingUMesh of a relative dimension == -2. + * \param [in] renum - if \c true, the returned mesh is permuted according to the + * optional numbers of mesh entities. + * \return MEDCouplingUMesh * - a pointer to MEDCouplingUMesh that the caller is to + * delete using decrRef() as it is no more needed. + * \throw If there are no mesh entities of the relative dimension == -2 in \a this mesh. + */ +MEDCouplingUMesh *MEDFileUMesh::getLevelM2Mesh(bool renum) const +{ + return getMeshAtLevel(-2,renum); +} + +/*! + * Returns a MEDCouplingUMesh of a relative dimension == -3. + * \param [in] renum - if \c true, the returned mesh is permuted according to the + * optional numbers of mesh entities. + * \return MEDCouplingUMesh * - a pointer to MEDCouplingUMesh that the caller is to + * delete using decrRef() as it is no more needed. + * \throw If there are no mesh entities of the relative dimension == -3 in \a this mesh. + */ +MEDCouplingUMesh *MEDFileUMesh::getLevelM3Mesh(bool renum) const +{ + return getMeshAtLevel(-3,renum); +} + +/*! + * This method is for advanced users. There is two storing strategy of mesh in \a this. + * Either MEDCouplingUMesh, or vector of MEDCoupling1GTUMesh instances. + * When assignement is done the first one is done, which is not optimal in write mode for MED file. + * This method allows to switch from MEDCouplingUMesh mode to MEDCoupling1GTUMesh mode. + */ +void MEDFileUMesh::forceComputationOfParts() const +{ + for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++) + { + const MEDFileUMeshSplitL1 *elt(*it); + if(elt) + elt->forceComputationOfParts(); + } +} + +/*! + * This method returns a vector of mesh parts containing each exactly one geometric type. + * This method will never launch an automatic computation of split by type (an INTERP_KERNEL::Exception will be then thrown). + * This method is only for memory aware users. + * The returned pointers are **NOT** new object pointer. No need to mange them. + */ +std::vector<MEDCoupling1GTUMesh *> MEDFileUMesh::getDirectUndergroundSingleGeoTypeMeshes(int meshDimRelToMax) const +{ + const MEDFileUMeshSplitL1 *sp(getMeshAtLevSafe(meshDimRelToMax)); + return sp->getDirectUndergroundSingleGeoTypeMeshes(); +} + +/*! + * This method returns the part of \a this having the geometric type \a gt. + * If such part is not existing an exception will be thrown. + * The returned pointer is **NOT** new object pointer. No need to mange it. + */ +MEDCoupling1GTUMesh *MEDFileUMesh::getDirectUndergroundSingleGeoTypeMesh(INTERP_KERNEL::NormalizedCellType gt) const +{ + const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(gt); + int lev=(int)cm.getDimension()-getMeshDimension(); + const MEDFileUMeshSplitL1 *sp(getMeshAtLevSafe(lev)); + return sp->getDirectUndergroundSingleGeoTypeMesh(gt); +} + +/*! + * Given a relative level \a meshDimRelToMax it returns the sorted vector of geometric types present in \a this. + * \throw if the reqsuested \a meshDimRelToMax does not exist. + */ +std::vector<INTERP_KERNEL::NormalizedCellType> MEDFileUMesh::getGeoTypesAtLevel(int meshDimRelToMax) const +{ + const MEDFileUMeshSplitL1 *sp(getMeshAtLevSafe(meshDimRelToMax)); + return sp->getGeoTypes(); +} + +/*! + * This method extracts from whole family field ids the part relative to the input parameter \a gt. + * \param [in] gt - the geometric type for which the family field is asked. + * \return DataArrayInt * - a pointer to DataArrayInt that the caller is to + * delete using decrRef() as it is no more needed. + * \sa MEDFileUMesh::extractNumberFieldOnGeoType + */ +DataArrayInt *MEDFileUMesh::extractFamilyFieldOnGeoType(INTERP_KERNEL::NormalizedCellType gt) const +{ + const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(gt); + int lev=(int)cm.getDimension()-getMeshDimension(); + const MEDFileUMeshSplitL1 *sp(getMeshAtLevSafe(lev)); + return sp->extractFamilyFieldOnGeoType(gt); +} + +/*! + * This method extracts from whole number field ids the part relative to the input parameter \a gt. + * \param [in] gt - the geometric type for which the number field is asked. + * \return DataArrayInt * - a pointer to DataArrayInt that the caller is to + * delete using decrRef() as it is no more needed. + * \sa MEDFileUMesh::extractFamilyFieldOnGeoType + */ +DataArrayInt *MEDFileUMesh::extractNumberFieldOnGeoType(INTERP_KERNEL::NormalizedCellType gt) const +{ + const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(gt); + int lev=(int)cm.getDimension()-getMeshDimension(); + const MEDFileUMeshSplitL1 *sp(getMeshAtLevSafe(lev)); + return sp->extractNumberFieldOnGeoType(gt); +} + +/*! + * This method returns for specified geometric type \a gt the relative level to \a this. + * If the relative level is empty an exception will be thrown. + */ +int MEDFileUMesh::getRelativeLevOnGeoType(INTERP_KERNEL::NormalizedCellType gt) const +{ + const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(gt); + int ret((int)cm.getDimension()-getMeshDimension()); + getMeshAtLevSafe(ret);//To test that returned value corresponds to a valid level. + return ret; +} + +const MEDFileUMeshSplitL1 *MEDFileUMesh::getMeshAtLevSafe(int meshDimRelToMaxExt) const +{ + if(meshDimRelToMaxExt==1) + throw INTERP_KERNEL::Exception("Dimension request is invalid : asking for node level (1) !"); + if(meshDimRelToMaxExt>1) + throw INTERP_KERNEL::Exception("Dimension request is invalid (>1) !"); + int tracucedRk=-meshDimRelToMaxExt; + if(tracucedRk>=(int)_ms.size()) + throw INTERP_KERNEL::Exception("Invalid mesh dim relative to max given ! Too low !"); + if((const MEDFileUMeshSplitL1 *)_ms[tracucedRk]==0) + throw INTERP_KERNEL::Exception("On specified lev (or entity) no cells exists !"); + return _ms[tracucedRk]; +} + +MEDFileUMeshSplitL1 *MEDFileUMesh::getMeshAtLevSafe(int meshDimRelToMaxExt) +{ + if(meshDimRelToMaxExt==1) + throw INTERP_KERNEL::Exception("Dimension request is invalid : asking for node level (1) !"); + if(meshDimRelToMaxExt>1) + throw INTERP_KERNEL::Exception("Dimension request is invalid (>1) !"); + int tracucedRk=-meshDimRelToMaxExt; + if(tracucedRk>=(int)_ms.size()) + throw INTERP_KERNEL::Exception("Invalid mesh dim relative to max given ! Too low !"); + if((const MEDFileUMeshSplitL1 *)_ms[tracucedRk]==0) + throw INTERP_KERNEL::Exception("On specified lev (or entity) no cells exists !"); + return _ms[tracucedRk]; +} + +void MEDFileUMesh::checkMeshDimCoherency(int meshDim, int meshDimRelToMax) const +{ + if(-meshDimRelToMax>=(int)_ms.size()) + throw INTERP_KERNEL::Exception("MEDFileUMesh::checkMeshDimCoherency : The meshdim of mesh is not managed by 'this' !"); + int i=0; + for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++,i++) + { + if(((const MEDFileUMeshSplitL1*) (*it))!=0) + { + int ref=(*it)->getMeshDimension(); + if(ref+i!=meshDim-meshDimRelToMax) + throw INTERP_KERNEL::Exception("MEDFileUMesh::checkMeshDimCoherency : no coherency between levels !"); + } + } +} + +/*! + * Sets the node coordinates array of \a this mesh. + * \param [in] coords - the new node coordinates array. + * \throw If \a coords == \c NULL. + */ +void MEDFileUMesh::setCoords(DataArrayDouble *coords) +{ + if(!coords) + throw INTERP_KERNEL::Exception("MEDFileUMesh::setCoords : null pointer in input !"); + coords->checkAllocated(); + int nbOfTuples=coords->getNumberOfTuples(); + _coords=coords; + coords->incrRef(); + _fam_coords=DataArrayInt::New(); + _fam_coords->alloc(nbOfTuples,1); + _fam_coords->fillWithZero(); + for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> >::iterator it=_ms.begin();it!=_ms.end();it++) + if((MEDFileUMeshSplitL1 *)(*it)) + (*it)->setCoords(coords); +} + +/*! + * Removes all groups of a given dimension in \a this mesh. + * \param [in] meshDimRelToMaxExt - the relative dimension of interest. + * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh. + */ +void MEDFileUMesh::eraseGroupsAtLevel(int meshDimRelToMaxExt) +{ + if(meshDimRelToMaxExt==1) + { + if((DataArrayInt *)_fam_coords) + _fam_coords->fillWithZero(); + return ; + } + MEDFileUMeshSplitL1 *l1=getMeshAtLevSafe(meshDimRelToMaxExt); + l1->eraseFamilyField(); + optimizeFamilies(); +} + +/*! + * Removes all families with ids not present in the family fields of \a this mesh. + */ +void MEDFileUMesh::optimizeFamilies() +{ + std::vector<int> levs=getNonEmptyLevelsExt(); + std::set<int> allFamsIds; + for(std::vector<int>::const_iterator it=levs.begin();it!=levs.end();it++) + { + const DataArrayInt *ffield=getFamilyFieldAtLevel(*it); + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ids=ffield->getDifferentValues(); + std::set<int> res; + std::set_union(ids->begin(),ids->end(),allFamsIds.begin(),allFamsIds.end(),std::inserter(res,res.begin())); + allFamsIds=res; + } + std::set<std::string> famNamesToKill; + for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++) + { + if(allFamsIds.find((*it).second)!=allFamsIds.end()) + famNamesToKill.insert((*it).first); + } + for(std::set<std::string>::const_iterator it=famNamesToKill.begin();it!=famNamesToKill.end();it++) + _families.erase(*it); + std::vector<std::string> grpNamesToKill; + for(std::map<std::string, std::vector<std::string> >::iterator it=_groups.begin();it!=_groups.end();it++) + { + std::vector<std::string> tmp; + for(std::vector<std::string>::const_iterator it2=(*it).second.begin();it2!=(*it).second.end();it2++) + { + if(famNamesToKill.find(*it2)==famNamesToKill.end()) + tmp.push_back(*it2); + } + if(!tmp.empty()) + (*it).second=tmp; + else + tmp.push_back((*it).first); + } + for(std::vector<std::string>::const_iterator it=grpNamesToKill.begin();it!=grpNamesToKill.end();it++) + _groups.erase(*it); +} + +/** + * \b this must be filled at level 0 and -1, typically the -1 level being (part of) the descending connectivity + * of the top level. This method build a "crack", or an inner boundary, in \b this along the group of level -1 named grpNameM1. + * The boundary is built according to the following method: + * - all nodes along the boundary which are not lying on an internal extremity of the (-1)-level group are duplicated (so the + * coordinates array is extended). + * - new (-1)-level cells are built lying on those new nodes. So the edges/faces along the group are duplicated. + * After this operation a top-level cell bordering the group will loose some neighbors (typically the cell which is on the + * other side of the group is no more a neighbor) + * - finally, the connectivity of (part of) the top level-cells bordering the group is also modified so that some cells + * bordering the newly created boundary use the newly computed nodes. + * + * \param[in] grpNameM1 name of the (-1)-level group defining the boundary + * \param[out] nodesDuplicated ids of the initial nodes which have been duplicated (and whose copy is put at the end of + * the coord array) + * \param[out] cellsModified ids of the cells whose connectivity has been modified (to use the newly created nodes) + * \param[out] cellsNotModified ids of the rest of cells bordering the new boundary whose connectivity remains unchanged. + */ +void MEDFileUMesh::buildInnerBoundaryAlongM1Group(const std::string& grpNameM1, DataArrayInt *&nodesDuplicated, + DataArrayInt *&cellsModified, DataArrayInt *&cellsNotModified) +{ + std::vector<int> levs=getNonEmptyLevels(); + if(std::find(levs.begin(),levs.end(),0)==levs.end() || std::find(levs.begin(),levs.end(),-1)==levs.end()) + throw INTERP_KERNEL::Exception("MEDFileUMesh::buildInnerBoundaryAlongM1Group : This method works only for mesh definied on level 0 and -1 !"); + MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m0=getMeshAtLevel(0); + MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m1=getMeshAtLevel(-1); + int nbNodes=m0->getNumberOfNodes(); + MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m11=getGroup(-1,grpNameM1); + DataArrayInt *tmp00=0,*tmp11=0,*tmp22=0; + m0->findNodesToDuplicate(*m11,tmp00,tmp11,tmp22); + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> nodeIdsToDuplicate(tmp00); + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> cellsToModifyConn0(tmp11); + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> cellsToModifyConn1(tmp22); + MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> tmp0=static_cast<MEDCouplingUMesh *>(m0->buildPartOfMySelf(cellsToModifyConn0->begin(),cellsToModifyConn0->end(),true)); + // node renumbering of cells in m1 impacted by duplication of node but not in group 'grpNameM1' on level -1 + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> descTmp0=DataArrayInt::New(),descITmp0=DataArrayInt::New(),revDescTmp0=DataArrayInt::New(),revDescITmp0=DataArrayInt::New(); + MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> tmp0Desc=tmp0->buildDescendingConnectivity(descTmp0,descITmp0,revDescTmp0,revDescITmp0); + descTmp0=0; descITmp0=0; revDescTmp0=0; revDescITmp0=0; + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> cellsInM1ToRenumW2=tmp0Desc->getCellIdsLyingOnNodes(nodeIdsToDuplicate->begin(),nodeIdsToDuplicate->end(),false); + MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> cellsInM1ToRenumW3=static_cast<MEDCouplingUMesh *>(tmp0Desc->buildPartOfMySelf(cellsInM1ToRenumW2->begin(),cellsInM1ToRenumW2->end(),true)); + DataArrayInt *cellsInM1ToRenumW4Tmp=0; + m1->areCellsIncludedIn(cellsInM1ToRenumW3,2,cellsInM1ToRenumW4Tmp); + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> cellsInM1ToRenumW4(cellsInM1ToRenumW4Tmp); + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> cellsInM1ToRenumW5=cellsInM1ToRenumW4->getIdsInRange(0,m1->getNumberOfCells()); + cellsInM1ToRenumW5->transformWithIndArr(cellsInM1ToRenumW4->begin(),cellsInM1ToRenumW4->end()); + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> grpIds=getGroupArr(-1,grpNameM1); + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> cellsInM1ToRenum=cellsInM1ToRenumW5->buildSubstraction(grpIds); + MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m1Part=static_cast<MEDCouplingUMesh *>(m1->buildPartOfMySelf(cellsInM1ToRenum->begin(),cellsInM1ToRenum->end(),true)); + m1Part->duplicateNodesInConn(nodeIdsToDuplicate->begin(),nodeIdsToDuplicate->end(),nbNodes); + m1->setPartOfMySelf(cellsInM1ToRenum->begin(),cellsInM1ToRenum->end(),*m1Part); + // end of node renumbering of cells in m1 impacted by duplication of node but not in group of level -1 'grpNameM1' + tmp0->duplicateNodes(nodeIdsToDuplicate->begin(),nodeIdsToDuplicate->end()); + m0->setCoords(tmp0->getCoords()); + m0->setPartOfMySelf(cellsToModifyConn0->begin(),cellsToModifyConn0->end(),*tmp0); + m1->setCoords(m0->getCoords()); + _coords=m0->getCoords(); _coords->incrRef(); + // duplication of cells in group 'grpNameM1' on level -1 + m11->duplicateNodesInConn(nodeIdsToDuplicate->begin(),nodeIdsToDuplicate->end(),nbNodes); m11->setCoords(m0->getCoords()); + std::vector<const MEDCouplingUMesh *> v(2); v[0]=m1; v[1]=m11; + MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> newm1=MEDCouplingUMesh::AggregateSortedByTypeMeshesOnSameCoords(v,tmp00,tmp11); + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> szOfCellGrpOfSameType(tmp00); + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> idInMsOfCellGrpOfSameType(tmp11); + // + newm1->setName(getName()); + const DataArrayInt *fam=getFamilyFieldAtLevel(-1); + if(!fam) + throw INTERP_KERNEL::Exception("MEDFileUMesh::buildInnerBoundaryAlongM1Group : internal problem !"); + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> newFam=DataArrayInt::New(); + newFam->alloc(newm1->getNumberOfCells(),1); + // Get a new family ID: care must be taken if we need a positive ID or a negative one: + // Positive ID for family of nodes, negative for all the rest. + int idd; + if (m1->getMeshDimension() == 0) + idd=getMaxFamilyId()+1; + else + idd=getMinFamilyId()-1; + int globStart=0,start=0,end,globEnd; + int nbOfChunks=szOfCellGrpOfSameType->getNumberOfTuples(); + for(int i=0;i<nbOfChunks;i++) + { + globEnd=globStart+szOfCellGrpOfSameType->getIJ(i,0); + if(idInMsOfCellGrpOfSameType->getIJ(i,0)==0) + { + end=start+szOfCellGrpOfSameType->getIJ(i,0); + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> part=fam->selectByTupleId2(start,end,1); + newFam->setPartOfValues1(part,globStart,globEnd,1,0,1,1,true); + start=end; + } + else + { + newFam->setPartOfValuesSimple1(idd,globStart,globEnd,1,0,1,1); + } + globStart=globEnd; + } + newm1->setCoords(getCoords()); + setMeshAtLevel(-1,newm1); + setFamilyFieldArr(-1,newFam); + std::string grpName2(grpNameM1); grpName2+="_dup"; + addFamily(grpName2,idd); + addFamilyOnGrp(grpName2,grpName2); + // + fam=_fam_coords; + if(fam) + { + int newNbOfNodes=getCoords()->getNumberOfTuples(); + newFam=DataArrayInt::New(); newFam->alloc(newNbOfNodes,1); + newFam->setPartOfValues1(fam,0,nbNodes,1,0,1,1,true); + newFam->setPartOfValuesSimple1(0,nbNodes,newNbOfNodes,1,0,1,1); + _fam_coords=newFam; + } + nodesDuplicated=nodeIdsToDuplicate.retn(); + cellsModified=cellsToModifyConn0.retn(); + cellsNotModified=cellsToModifyConn1.retn(); +} + +/*! + * \param [out] oldCode retrieves the distribution of types before the call if true is returned + * \param [out] newCode etrieves the distribution of types after the call if true is returned + * \param [out] o2nRenumCell tells for **all levels** the old 2 new renumbering of cells. + * + * \return false if no modification has been performed linked to the unpolyzation. Neither cell type, not cell numbers. When false is returned no need of field on cells or on gauss renumbering. + * Inversely, if true is returned, it means that distribution of cell by geometric type has changed and field on cell and field on gauss point must be renumbered. + */ +bool MEDFileUMesh::unPolyze(std::vector<int>& oldCode, std::vector<int>& newCode, DataArrayInt *& o2nRenumCell) +{ + o2nRenumCell=0; oldCode.clear(); newCode.clear(); + std::vector<int> levs=getNonEmptyLevels(); + bool ret=false; + std::vector< const DataArrayInt* > renumCellsSplited;//same than memorySaverIfThrow + std::vector< MEDCouplingAutoRefCountObjectPtr<DataArrayInt> > memorySaverIfThrow;//same than renumCellsSplited only in case of throw + int start=0; + int end=0; + for(std::vector<int>::reverse_iterator it=levs.rbegin();it!=levs.rend();it++) + { + MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m=getMeshAtLevel(*it); + std::vector<int> code1=m->getDistributionOfTypes(); + end=PutInThirdComponentOfCodeOffset(code1,start); + oldCode.insert(oldCode.end(),code1.begin(),code1.end()); + bool hasChanged=m->unPolyze(); + DataArrayInt *fake=0; + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> o2nCellsPart=m->getLevArrPerCellTypes(MEDCouplingUMesh::MEDMEM_ORDER, + MEDCouplingUMesh::MEDMEM_ORDER+MEDCouplingUMesh::N_MEDMEM_ORDER,fake); + fake->decrRef(); + renumCellsSplited.push_back(o2nCellsPart); memorySaverIfThrow.push_back(o2nCellsPart); + if(hasChanged) + { + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> o2nCellsPart2=o2nCellsPart->buildPermArrPerLevel(); + m->renumberCells(o2nCellsPart2->getConstPointer(),false); + ret=true; + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> famField2,numField2; + const DataArrayInt *famField=getFamilyFieldAtLevel(*it); if(famField) { famField->incrRef(); famField2=const_cast<DataArrayInt *>(famField); } + const DataArrayInt *numField=getNumberFieldAtLevel(*it); if(numField) { numField->incrRef(); numField2=const_cast<DataArrayInt *>(numField); } + setMeshAtLevel(*it,m); + std::vector<int> code2=m->getDistributionOfTypes(); + end=PutInThirdComponentOfCodeOffset(code2,start); + newCode.insert(newCode.end(),code2.begin(),code2.end()); + // + if(o2nCellsPart2->isIdentity()) + continue; + if(famField) + { + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> newFamField=famField->renumber(o2nCellsPart2->getConstPointer()); + setFamilyFieldArr(*it,newFamField); + } + if(numField) + { + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> newNumField=numField->renumber(o2nCellsPart2->getConstPointer()); + setRenumFieldArr(*it,newNumField); + } + } + else + { + newCode.insert(newCode.end(),code1.begin(),code1.end()); + } + start=end; + } + if(ret) + { + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> renumCells=DataArrayInt::Aggregate(renumCellsSplited); + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> o2nRenumCellRet=renumCells->buildPermArrPerLevel(); + o2nRenumCell=o2nRenumCellRet.retn(); + } + return ret; +} + +/*! \cond HIDDEN_ITEMS */ +struct MEDLoaderAccVisit1 +{ + MEDLoaderAccVisit1():_new_nb_of_nodes(0) { } + int operator()(bool val) { return val?_new_nb_of_nodes++:-1; } + int _new_nb_of_nodes; +}; +/*! \endcond */ + +/*! + * Array returned is the correspondance in \b old \b to \b new format. The returned array is newly created and should be dealt by the caller. + * The maximum value stored in returned array is the number of nodes of \a this minus 1 after call of this method. + * The size of returned array is the number of nodes of the old (previous to the call of this method) number of nodes. + * -1 values in returned array means that the corresponding old node is no more used. + * + * \return newly allocated array containing correspondance in \b old \b to \b new format. If all nodes in \a this are fetched \c NULL pointer is returned and nothing + * is modified in \a this. + * \throw If no coordinates are set in \a this or if there is in any available mesh in \a this a cell having a nodal connectivity containing a node id not in the range of + * set coordinates. + */ +DataArrayInt *MEDFileUMesh::zipCoords() +{ + const DataArrayDouble *coo(getCoords()); + if(!coo) + throw INTERP_KERNEL::Exception("MEDFileUMesh::zipCoords : no coordinates set in this !"); + int nbOfNodes(coo->getNumberOfTuples()); + std::vector<bool> nodeIdsInUse(nbOfNodes,false); + std::vector<int> neLevs(getNonEmptyLevels()); + for(std::vector<int>::const_iterator lev=neLevs.begin();lev!=neLevs.end();lev++) + { + const MEDFileUMeshSplitL1 *zeLev(getMeshAtLevSafe(*lev)); + if(zeLev->isMeshStoredSplitByType()) + { + std::vector<MEDCoupling1GTUMesh *> ms(zeLev->getDirectUndergroundSingleGeoTypeMeshes()); + for(std::vector<MEDCoupling1GTUMesh *>::const_iterator it=ms.begin();it!=ms.end();it++) + if(*it) + (*it)->computeNodeIdsAlg(nodeIdsInUse); + } + else + { + MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> mesh(zeLev->getWholeMesh(false)); + mesh->computeNodeIdsAlg(nodeIdsInUse); + } + } + int nbrOfNodesInUse((int)std::count(nodeIdsInUse.begin(),nodeIdsInUse.end(),true)); + if(nbrOfNodesInUse==nbOfNodes) + return 0;//no need to update _part_coords + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret(DataArrayInt::New()); ret->alloc(nbOfNodes,1); + std::transform(nodeIdsInUse.begin(),nodeIdsInUse.end(),ret->getPointer(),MEDLoaderAccVisit1()); + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ret2(ret->invertArrayO2N2N2OBis(nbrOfNodesInUse)); + MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> newCoords(coo->selectByTupleIdSafe(ret2->begin(),ret2->end())); + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> newFamCoords; + MEDCouplingAutoRefCountObjectPtr<DataArrayAsciiChar> newNameCoords; + if((const DataArrayInt *)_fam_coords) + newFamCoords=_fam_coords->selectByTupleIdSafe(ret2->begin(),ret2->end()); + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> newNumCoords; + if((const DataArrayInt *)_num_coords) + newNumCoords=_num_coords->selectByTupleIdSafe(ret2->begin(),ret2->end()); + if((const DataArrayAsciiChar *)_name_coords) + newNameCoords=static_cast<DataArrayAsciiChar *>(_name_coords->selectByTupleIdSafe(ret2->begin(),ret2->end())); + _coords=newCoords; _fam_coords=newFamCoords; _num_coords=newNumCoords; _name_coords=newNameCoords; _rev_num_coords=0; + for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> >::iterator it=_ms.begin();it!=_ms.end();it++) + { + if((MEDFileUMeshSplitL1*)*it) + { + (*it)->renumberNodesInConn(ret->begin()); + (*it)->setCoords(_coords); + } + } + // updates _part_coords + const PartDefinition *pc(_part_coords); + if(pc) + { + MEDCouplingAutoRefCountObjectPtr<PartDefinition> tmpPD(DataArrayPartDefinition::New(ret2)); + _part_coords=tmpPD->composeWith(pc); + } + return ret.retn(); +} + +/*! + * This method performs an extrusion along a path defined by \a m1D. + * \a this is expected to be a mesh with max mesh dimension equal to 2. + * \a m1D is expected to be a mesh with space dimesion equal to 3 and mesh dimension equal to 1. + * Mesh dimensions of returned mesh is incremented by one compared to thoose in \a this. + * This method scans all levels in \a this + * and put them in the returned mesh. All groups in \a this are also put in the returned mesh. + * + * \param [in] m1D - the mesh defining the extrusion path. + * \param [in] policy - defines the policy of extrusion (see MEDCouplingUMesh::buildExtrudedMesh for more details) + * \return - a new reference on mesh (you have to deal with using decrRef). The returned mesh will have the same name than \a this. + * + * \sa MEDCouplingUMesh::buildExtrudedMesh + */ +MEDFileUMesh *MEDFileUMesh::buildExtrudedMesh(const MEDCouplingUMesh *m1D, int policy) const +{ + if(getMeshDimension()!=2) + throw INTERP_KERNEL::Exception("MEDFileUMesh::buildExtrudedMesh : this is expected to be with mesh dimension equal to 2 !"); + MEDCouplingAutoRefCountObjectPtr<MEDFileUMesh> ret(MEDFileUMesh::New()); + m1D->checkCoherency(); + if(m1D->getMeshDimension()!=1) + throw INTERP_KERNEL::Exception("MEDFileUMesh::buildExtrudedMesh : input mesh must have a mesh dimension equal to one !"); + int nbRep(m1D->getNumberOfCells()); + std::vector<int> levs(getNonEmptyLevels()); + std::vector<std::string> grps(getGroupsNames()); + std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> > zeList; + DataArrayDouble *coords(0); + std::size_t nbOfLevsOut(levs.size()+1); + std::vector< MEDCouplingAutoRefCountObjectPtr<DataArrayInt> > o2ns(nbOfLevsOut); + for(std::vector<int>::const_iterator lev=levs.begin();lev!=levs.end();lev++) + { + MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> item(getMeshAtLevel(*lev)); + item=item->clone(false); + item->changeSpaceDimension(3+(*lev),0.);//no problem non const but change DataArrayDouble for coordinates do not alter data + MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> tmp(static_cast<MEDCouplingUMesh *>(m1D->deepCpy())); + tmp->changeSpaceDimension(3+(*lev),0.); + MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> elt(item->buildExtrudedMesh(tmp,policy)); + zeList.push_back(elt); + if(*lev==0) + coords=elt->getCoords(); + } + if(!coords) + throw INTERP_KERNEL::Exception("MEDFileUMesh::buildExtrudedMesh : internal error !"); + for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> >::iterator it=zeList.begin();it!=zeList.end();it++) + { + (*it)->setName(getName()); + (*it)->setCoords(coords); + } + for(std::size_t ii=0;ii!=zeList.size();ii++) + { + int lev(levs[ii]); + MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> elt(zeList[ii]); + if(lev<=-1) + { + MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> elt1(getMeshAtLevel(lev+1)); + MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> elt2(elt1->clone(false)); + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> tmp(elt2->getNodalConnectivity()->deepCpy()); + elt2->setConnectivity(tmp,elt2->getNodalConnectivityIndex()); + elt2->shiftNodeNumbersInConn(nbRep*elt1->getNumberOfNodes()); + elt1->setCoords(elt->getCoords()); elt2->setCoords(elt->getCoords()); + std::vector<const MEDCouplingUMesh *> elts(3); + elts[0]=elt; elts[1]=elt1; elts[2]=elt2; + elt=MEDCouplingUMesh::MergeUMeshesOnSameCoords(elts); + elt->setName(getName()); + } + // + o2ns[ii]=elt->sortCellsInMEDFileFrmt(); + ret->setMeshAtLevel(lev,elt); + } + MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> endLev(getMeshAtLevel(levs.back())),endLev2; + endLev=endLev->clone(false); endLev->setCoords(coords); + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> tmp(endLev->getNodalConnectivity()->deepCpy()); + endLev2=endLev->clone(false); endLev2->setConnectivity(tmp,endLev->getNodalConnectivityIndex()); + endLev2->shiftNodeNumbersInConn(nbRep*getNumberOfNodes()); + endLev=MEDCouplingUMesh::MergeUMeshesOnSameCoords(endLev,endLev2); + o2ns[levs.size()]=endLev->sortCellsInMEDFileFrmt(); + endLev->setName(getName()); + ret->setMeshAtLevel(levs.back()-1,endLev); + // + for(std::size_t ii=0;ii!=zeList.size();ii++) + { + int lev(levs[ii]); + std::vector< MEDCouplingAutoRefCountObjectPtr<DataArrayInt> > outGrps; + std::vector< const DataArrayInt * > outGrps2; + if(lev<=-1) + { + for(std::vector<std::string>::const_iterator grp=grps.begin();grp!=grps.end();grp++) + { + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> grpArr(getGroupArr(lev+1,*grp)); + if(!grpArr->empty()) + { + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> grpArr1(grpArr->deepCpy()),grpArr2(grpArr->deepCpy()); + int offset0(zeList[ii]->getNumberOfCells()); + int offset1(offset0+getNumberOfCellsAtLevel(lev+1)); + grpArr1->applyLin(1,offset0); grpArr2->applyLin(1,offset1); + std::ostringstream oss; oss << grpArr2->getName() << "_top"; + grpArr2->setName(oss.str()); + grpArr1->transformWithIndArr(o2ns[ii]->begin(),o2ns[ii]->end()); + grpArr2->transformWithIndArr(o2ns[ii]->begin(),o2ns[ii]->end()); + outGrps.push_back(grpArr1); outGrps.push_back(grpArr2); + outGrps2.push_back(grpArr1); outGrps2.push_back(grpArr2); + } + } + } + // + for(std::vector<std::string>::const_iterator grp=grps.begin();grp!=grps.end();grp++) + { + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> grpArr(getGroupArr(lev,*grp)); + if(!grpArr->empty()) + { + int nbCellsB4Extrusion(getNumberOfCellsAtLevel(lev)); + std::vector< MEDCouplingAutoRefCountObjectPtr<DataArrayInt> > grpArrs(nbRep); + std::vector< const DataArrayInt *> grpArrs2(nbRep); + for(int iii=0;iii<nbRep;iii++) + { + grpArrs[iii]=grpArr->deepCpy(); grpArrs[iii]->applyLin(1,iii*nbCellsB4Extrusion); + grpArrs2[iii]=grpArrs[iii]; + } + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> grpArrExt(DataArrayInt::Aggregate(grpArrs2)); + grpArrExt->transformWithIndArr(o2ns[ii]->begin(),o2ns[ii]->end()); + std::ostringstream grpName; grpName << *grp << "_extruded"; + grpArrExt->setName(grpName.str()); + outGrps.push_back(grpArrExt); + outGrps2.push_back(grpArrExt); + } + } + ret->setGroupsAtLevel(lev,outGrps2); + } + std::vector< MEDCouplingAutoRefCountObjectPtr<DataArrayInt> > outGrps; + std::vector< const DataArrayInt * > outGrps2; + for(std::vector<std::string>::const_iterator grp=grps.begin();grp!=grps.end();grp++) + { + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> grpArr1(getGroupArr(levs.back(),*grp)); + if(grpArr1->empty()) + continue; + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> grpArr2(grpArr1->deepCpy()); + std::ostringstream grpName; grpName << *grp << "_top"; + grpArr2->setName(grpName.str()); + grpArr2->applyLin(1,getNumberOfCellsAtLevel(levs.back())); + outGrps.push_back(grpArr1); outGrps.push_back(grpArr2); + outGrps2.push_back(grpArr1); outGrps2.push_back(grpArr2); + } + ret->setGroupsAtLevel(levs.back()-1,outGrps2); + return ret.retn(); +} + +/*! + * This method converts all linear cells in \a this into quadratic cells (following the \a conversionType policy). + * All the cells converted are put in the returned instance. This method applies all the groups and families in \a this to returned instance. + * Groups on nodes and families on nodes are copied directly to the returned instance without transformation. + * + * \param [in] conversionType - conversionType specifies the type of conversion expected. Only 0 (default) and 1 are supported presently. 0 those that creates the 'most' simple + * corresponding quadratic cells. 1 is those creating the 'most' complex. + * \param [in] eps - detection threshold for coordinates. + * \return A new instance that is the result of the conversion. The caller has the ownership of this returned instance. + * + * \sa MEDCouplingUMesh::convertLinearCellsToQuadratic , quadraticToLinear + */ +MEDFileUMesh *MEDFileUMesh::linearToQuadratic(int conversionType, double eps) const +{ + MEDCouplingAutoRefCountObjectPtr<MEDFileUMesh> ret(MEDFileUMesh::New()); + int initialNbNodes(getNumberOfNodes()); + MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m0Tmp(getMeshAtLevel(0)); + MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m0(dynamic_cast<MEDCouplingUMesh *>(m0Tmp->deepCpy())); + { + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> notUsed(m0->convertLinearCellsToQuadratic(conversionType)); + } + DataArrayDouble *zeCoords(m0->getCoords()); + ret->setMeshAtLevel(0,m0); + std::vector<int> levs(getNonEmptyLevels()); + const DataArrayInt *famField(getFamilyFieldAtLevel(0)); + if(famField) + { + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> famFieldCpy(famField->deepCpy()); + ret->setFamilyFieldArr(0,famFieldCpy); + } + famField=getFamilyFieldAtLevel(1); + if(famField) + { + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> fam(DataArrayInt::New()); fam->alloc(zeCoords->getNumberOfTuples(),1); + fam->fillWithZero(); + fam->setPartOfValues1(famField,0,initialNbNodes,1,0,1,1); + ret->setFamilyFieldArr(1,fam); + } + ret->copyFamGrpMapsFrom(*this); + MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> partZeCoords(zeCoords->selectByTupleId2(initialNbNodes,zeCoords->getNumberOfTuples(),1)); + for(std::vector<int>::const_iterator lev=levs.begin();lev!=levs.end();lev++) + { + if(*lev==0) + continue; + MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m1Tmp(getMeshAtLevel(*lev)); + MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m1(dynamic_cast<MEDCouplingUMesh *>(m1Tmp->deepCpy())); + if(m1->getMeshDimension()!=0) + { + { + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> notUsed(m1->convertLinearCellsToQuadratic(conversionType)); + }//kill unused notUsed var + MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> m1Coords(m1->getCoords()->selectByTupleId2(initialNbNodes,m1->getNumberOfNodes(),1)); + DataArrayInt *b(0); + bool a(partZeCoords->areIncludedInMe(m1Coords,eps,b)); + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> bSafe(b); + if(!a) + { + std::ostringstream oss; oss << "MEDFileUMesh::linearCellsToQuadratic : for level " << *lev << " problem to identify nodes generated !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + b->applyLin(1,initialNbNodes); + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> l0(DataArrayInt::New()); l0->alloc(initialNbNodes,1); l0->iota(); + std::vector<const DataArrayInt *> v(2); v[0]=l0; v[1]=b; + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> renum(DataArrayInt::Aggregate(v)); + m1->renumberNodesInConn(renum->begin()); + } + m1->setCoords(zeCoords); + ret->setMeshAtLevel(*lev,m1); + famField=getFamilyFieldAtLevel(*lev); + if(famField) + { + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> famFieldCpy(famField->deepCpy()); + ret->setFamilyFieldArr(*lev,famFieldCpy); + } + } + return ret.retn(); +} + +/*! + * This method converts all quadratic cells in \a this into linear cells. + * All the cells converted are put in the returned instance. This method applies all the groups and families in \a this to returned instance. + * Groups on nodes and families on nodes are copied directly to the returned instance without transformation. + * + * \param [in] eps - detection threshold for coordinates. + * \return A new instance that is the result of the conversion. The caller has the ownership of this returned instance. + * + * \sa MEDCouplingUMesh::convertLinearCellsToQuadratic , linearToQuadratic + */ +MEDFileUMesh *MEDFileUMesh::quadraticToLinear(double eps) const +{ + MEDCouplingAutoRefCountObjectPtr<MEDFileUMesh> ret(MEDFileUMesh::New()); + MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m0Tmp(getMeshAtLevel(0)); + MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m0(dynamic_cast<MEDCouplingUMesh *>(m0Tmp->deepCpy())); + m0->convertQuadraticCellsToLinear(); + m0->zipCoords(); + DataArrayDouble *zeCoords(m0->getCoords()); + ret->setMeshAtLevel(0,m0); + std::vector<int> levs(getNonEmptyLevels()); + const DataArrayInt *famField(getFamilyFieldAtLevel(0)); + if(famField) + { + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> famFieldCpy(famField->deepCpy()); + ret->setFamilyFieldArr(0,famFieldCpy); + } + famField=getFamilyFieldAtLevel(1); + if(famField) + { + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> fam(famField->selectByTupleId2(0,zeCoords->getNumberOfTuples(),1)); + ret->setFamilyFieldArr(1,fam); + } + ret->copyFamGrpMapsFrom(*this); + for(std::vector<int>::const_iterator lev=levs.begin();lev!=levs.end();lev++) + { + if(*lev==0) + continue; + MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m1Tmp(getMeshAtLevel(*lev)); + MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m1(dynamic_cast<MEDCouplingUMesh *>(m1Tmp->deepCpy())); + m1->convertQuadraticCellsToLinear(); + m1->zipCoords(); + DataArrayInt *b(0); + bool a(zeCoords->areIncludedInMe(m1->getCoords(),eps,b)); + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> bSafe(b); + if(!a) + { + std::ostringstream oss; oss << "MEDFileUMesh::quadraticToLinear : for level " << *lev << " problem to identify nodes generated !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + m1->renumberNodesInConn(b->begin()); + m1->setCoords(zeCoords); + ret->setMeshAtLevel(*lev,m1); + famField=getFamilyFieldAtLevel(*lev); + if(famField) + { + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> famFieldCpy(famField->deepCpy()); + ret->setFamilyFieldArr(*lev,famFieldCpy); + } + } + return ret.retn(); +} + +void MEDFileUMesh::serialize(std::vector<double>& tinyDouble, std::vector<int>& tinyInt, std::vector<std::string>& tinyStr, std::vector< MEDCouplingAutoRefCountObjectPtr<DataArrayInt> >& bigArraysI, MEDCouplingAutoRefCountObjectPtr<DataArrayDouble>& bigArrayD) +{ + clearNonDiscrAttributes(); + forceComputationOfParts(); + tinyDouble.clear(); tinyInt.clear(); tinyStr.clear(); bigArraysI.clear(); bigArrayD=0; + std::vector<int> layer0; + layer0.push_back(_order); //0 i + layer0.push_back(_iteration);//1 i + layer0.push_back(getSpaceDimension());//2 i + tinyDouble.push_back(_time);//0 d + tinyStr.push_back(_name);//0 s + tinyStr.push_back(_desc_name);//1 s + for(int i=0;i<getSpaceDimension();i++) + tinyStr.push_back(_coords->getInfoOnComponent(i)); + layer0.push_back((int)_families.size());//3 i <- key info aa layer#0 + for(std::map<std::string,int>::const_iterator it=_families.begin();it!=_families.end();it++) + { + tinyStr.push_back((*it).first); + layer0.push_back((*it).second); + } + layer0.push_back((int)_groups.size());//3+aa i <- key info bb layer#0 + for(std::map<std::string, std::vector<std::string> >::const_iterator it0=_groups.begin();it0!=_groups.end();it0++) + { + layer0.push_back((int)(*it0).second.size()); + tinyStr.push_back((*it0).first); + for(std::vector<std::string>::const_iterator it1=((*it0).second).begin();it1!=((*it0).second).end();it1++) + tinyStr.push_back(*it1); + } + // sizeof(layer0)==3+aa+1+bb layer#0 + bigArrayD=_coords;// 0 bd + bigArraysI.push_back(_fam_coords);// 0 bi + bigArraysI.push_back(_num_coords);// 1 bi + const PartDefinition *pd(_part_coords); + if(!pd) + layer0.push_back(-1); + else + { + std::vector<int> tmp0; + pd->serialize(tmp0,bigArraysI); + tinyInt.push_back(tmp0.size()); + tinyInt.insert(tinyInt.end(),tmp0.begin(),tmp0.end()); + } + // + std::vector<int> layer1; + std::vector<int> levs(getNonEmptyLevels()); + layer1.push_back((int)levs.size());// 0 i <- key + layer1.insert(layer1.end(),levs.begin(),levs.end()); + for(std::vector<int>::const_iterator it=levs.begin();it!=levs.end();it++) + { + const MEDFileUMeshSplitL1 *lev(getMeshAtLevSafe(*it)); + lev->serialize(layer1,bigArraysI); + } + // put layers all together. + tinyInt.push_back(layer0.size()); + tinyInt.insert(tinyInt.end(),layer0.begin(),layer0.end()); + tinyInt.push_back(layer1.size()); + tinyInt.insert(tinyInt.end(),layer1.begin(),layer1.end()); +} + +void MEDFileUMesh::unserialize(std::vector<double>& tinyDouble, std::vector<int>& tinyInt, std::vector<std::string>& tinyStr, + std::vector< MEDCouplingAutoRefCountObjectPtr<DataArrayInt> >& bigArraysI, MEDCouplingAutoRefCountObjectPtr<DataArrayDouble>& bigArrayD) +{ + int sz0(tinyInt[0]); + std::vector<int> layer0(tinyInt.begin()+1,tinyInt.begin()+1+sz0); + int sz1(tinyInt[sz0+1]); + std::vector<int> layer1(tinyInt.begin()+2+sz0,tinyInt.begin()+2+sz0+sz1); + // + std::reverse(layer0.begin(),layer0.end()); + std::reverse(layer1.begin(),layer1.end()); + std::reverse(tinyDouble.begin(),tinyDouble.end()); + std::reverse(tinyStr.begin(),tinyStr.end()); + std::reverse(bigArraysI.begin(),bigArraysI.end()); + // + _order=layer0.back(); layer0.pop_back(); + _iteration=layer0.back(); layer0.pop_back(); + int spaceDim(layer0.back()); layer0.pop_back(); + _time=tinyDouble.back(); tinyDouble.pop_back(); + _name=tinyStr.back(); tinyStr.pop_back(); + _desc_name=tinyStr.back(); tinyStr.pop_back(); + _coords=bigArrayD; _coords->rearrange(spaceDim); + for(int i=0;i<spaceDim;i++) + { + _coords->setInfoOnComponent(i,tinyStr.back()); + tinyStr.pop_back(); + } + int nbOfFams(layer0.back()); layer0.pop_back(); + _families.clear(); + for(int i=0;i<nbOfFams;i++) + { + _families[tinyStr.back()]=layer0.back(); + tinyStr.pop_back(); layer0.pop_back(); + } + int nbGroups(layer0.back()); layer0.pop_back(); + _groups.clear(); + for(int i=0;i<nbGroups;i++) + { + std::string grpName(tinyStr.back()); tinyStr.pop_back(); + int nbOfFamsOnGrp(layer0.back()); layer0.pop_back(); + std::vector<std::string> fams(nbOfFamsOnGrp); + for(int j=0;j<nbOfFamsOnGrp;j++) + { + fams[j]=tinyStr.back(); tinyStr.pop_back(); + } + _groups[grpName]=fams; + } + _fam_coords=bigArraysI.back(); bigArraysI.pop_back(); + _num_coords=bigArraysI.back(); bigArraysI.pop_back(); + _part_coords=0; + int isPd(layer0.back()); layer0.pop_back(); + if(isPd!=-1) + { + std::vector<int> tmp0(layer0.begin(),layer0.begin()+isPd); + layer0.erase(layer0.begin(),layer0.begin()+isPd); + _part_coords=PartDefinition::Unserialize(tmp0,bigArraysI); + } + if(!layer0.empty()) + throw INTERP_KERNEL::Exception("MEDFileUMesh::unserialize : something wrong during unserialization #1 !"); + // + int nbLevs(layer1.back()); layer1.pop_back(); + std::vector<int> levs(layer1.rbegin(),layer1.rbegin()+nbLevs); layer1.erase(layer1.end()-nbLevs,layer1.end()); + _ms.clear(); + int maxLev(-(*std::min_element(levs.begin(),levs.end()))); + _ms.resize(maxLev+1); + for(int i=0;i<nbLevs;i++) + { + int lev(levs[i]); + int pos(-lev); + _ms[pos]=MEDFileUMeshSplitL1::Unserialize(_name,_coords,layer1,bigArraysI); + } +} + +/*! + * Adds a group of nodes to \a this mesh. + * \param [in] ids - a DataArrayInt providing ids and a name of the group to add. + * The ids should be sorted and different each other (MED file norm). + * + * \warning this method can alter default "FAMILLE_ZERO" family. + * For users sensitive to this a call to MEDFileMesh::rearrangeFamilies will be necessary after addGroup session. + * + * \throw If the node coordinates array is not set. + * \throw If \a ids == \c NULL. + * \throw If \a ids->getName() == "". + * \throw If \a ids does not respect the MED file norm. + * \throw If a group with name \a ids->getName() already exists. + */ +void MEDFileUMesh::addNodeGroup(const DataArrayInt *ids) +{ + const DataArrayDouble *coords(_coords); + if(!coords) + throw INTERP_KERNEL::Exception("MEDFileUMesh::addNodeGroup : no coords set !"); + int nbOfNodes(coords->getNumberOfTuples()); + if(!((DataArrayInt *)_fam_coords)) + { _fam_coords=DataArrayInt::New(); _fam_coords->alloc(nbOfNodes,1); _fam_coords->fillWithZero(); } + // + addGroupUnderground(true,ids,_fam_coords); +} + +/*! + * Adds a group of nodes/cells/faces/edges to \a this mesh. + * + * \param [in] ids - a DataArrayInt providing ids and a name of the group to add. + * The ids should be sorted and different each other (MED file norm). + * + * \warning this method can alter default "FAMILLE_ZERO" family. + * For users sensitive to this a call to MEDFileMesh::rearrangeFamilies will be necessary after addGroup session. + * + * \throw If the node coordinates array is not set. + * \throw If \a ids == \c NULL. + * \throw If \a ids->getName() == "". + * \throw If \a ids does not respect the MED file norm. + * \throw If a group with name \a ids->getName() already exists. + */ +void MEDFileUMesh::addGroup(int meshDimRelToMaxExt, const DataArrayInt *ids) +{ + std::vector<int> levs(getNonEmptyLevelsExt()); + if(std::find(levs.begin(),levs.end(),meshDimRelToMaxExt)==levs.end()) + { + std::ostringstream oss; oss << "MEDFileUMesh::addGroup : level " << meshDimRelToMaxExt << " not available ! Should be in "; + std::copy(levs.begin(),levs.end(),std::ostream_iterator<int>(oss," ")); oss << " !"; throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + if(meshDimRelToMaxExt==1) + { addNodeGroup(ids); return ; } + MEDFileUMeshSplitL1 *lev(getMeshAtLevSafe(meshDimRelToMaxExt)); + DataArrayInt *fam(lev->getOrCreateAndGetFamilyField()); + addGroupUnderground(false,ids,fam); +} + +/*! + * Changes a name of a family specified by its id. + * \param [in] id - the id of the family of interest. + * \param [in] newFamName - the new family name. + * \throw If no family with the given \a id exists. + */ +void MEDFileUMesh::setFamilyNameAttachedOnId(int id, const std::string& newFamName) +{ + std::string oldName=getFamilyNameGivenId(id); + _families.erase(oldName); + _families[newFamName]=id; +} + +/*! + * Removes a mesh of a given dimension. + * \param [in] meshDimRelToMax - the relative dimension of interest. + * \throw If there is no mesh at level \a meshDimRelToMax in \a this mesh. + */ +void MEDFileUMesh::removeMeshAtLevel(int meshDimRelToMax) +{ + std::vector<int> levSet=getNonEmptyLevels(); + std::vector<int>::const_iterator it=std::find(levSet.begin(),levSet.end(),meshDimRelToMax); + if(it==levSet.end()) + throw INTERP_KERNEL::Exception("MEDFileUMesh::removeMeshAtLevel : the requested level is not existing !"); + int pos=(-meshDimRelToMax); + _ms[pos]=0; +} + +/*! + * Sets a new MEDCoupling1GTUMesh at a given level in \a this mesh. + * \param [in] meshDimRelToMax - a relative level to set the mesh at. + * \param [in] m - the new mesh to set. + * \throw If the name or the description of \a this mesh and \a m are not empty and are + * different. + * \throw If the node coordinates array is set \a this in mesh and \a m refers to + * another node coordinates array. + * \throw If the mesh dimension of \a m does not correspond to \a meshDimRelToMax or + * to the existing meshes of other levels of \a this mesh. + */ +void MEDFileUMesh::setMeshAtLevel(int meshDimRelToMax, MEDCoupling1GTUMesh *m) +{ + MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> elt(new MEDFileUMeshSplitL1(m)); + checkAndGiveEntryInSplitL1(meshDimRelToMax,m)=elt; +} + +/*! + * Sets a new MEDCouplingUMesh at a given level in \a this mesh. + * \param [in] meshDimRelToMax - a relative level to set the mesh at. + * \param [in] m - the new mesh to set. + * \param [in] newOrOld - if \c true, cells in \a m are sorted by type to be ready for + * writing \a this mesh in a MED file. + * \throw If the name or the description of \a this mesh and \a m are not empty and are + * different. + * \throw If the node coordinates array is set \a this in mesh and \a m refers to + * another node coordinates array. + * \throw If the mesh dimension of \a m does not correspond to \a meshDimRelToMax or + * to the existing meshes of other levels of \a this mesh. + */ +void MEDFileUMesh::setMeshAtLevel(int meshDimRelToMax, MEDCouplingUMesh *m, bool newOrOld) +{ + MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> elt(new MEDFileUMeshSplitL1(m,newOrOld)); + checkAndGiveEntryInSplitL1(meshDimRelToMax,m)=elt; +} + +MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1>& MEDFileUMesh::checkAndGiveEntryInSplitL1(int meshDimRelToMax, MEDCouplingPointSet *m) +{ + dealWithTinyInfo(m); + std::vector<int> levSet=getNonEmptyLevels(); + if(std::find(levSet.begin(),levSet.end(),meshDimRelToMax)==levSet.end()) + { + if((DataArrayDouble *)_coords==0) + { + DataArrayDouble *c=m->getCoords(); + if(c) + c->incrRef(); + _coords=c; + } + if(m->getCoords()!=_coords) + throw INTERP_KERNEL::Exception("MEDFileUMesh::setMeshAtLevel : Invalid Given Mesh ! The coordinates are not the same ! try to use tryToShareSameCoords !"); + int sz=(-meshDimRelToMax)+1; + if(sz>=(int)_ms.size()) + _ms.resize(sz); + checkMeshDimCoherency(m->getMeshDimension(),meshDimRelToMax); + return _ms[sz-1]; + } + else + return _ms[-meshDimRelToMax]; +} + +/*! + * This method allows to set at once the content of different levels in \a this. + * This method is equivalent to a series of call to MEDFileUMesh::setMeshAtLevel. + * + * \param [in] ms - List of unstructured meshes lying on the same coordinates and having different mesh dimesnion. + * \param [in] renum - the parameter (set to false by default) that tells the beheviour if there is a mesh on \a ms that is not geo type sorted. + * If false, an exception ois thrown. If true the mesh is reordered automatically. It is highly recommanded to let this parameter to false. + * + * \throw If \a there is a null pointer in \a ms. + * \sa MEDFileUMesh::setMeshAtLevel + */ +void MEDFileUMesh::setMeshes(const std::vector<const MEDCouplingUMesh *>& ms, bool renum) +{ + if(ms.empty()) + return ; + const MEDCouplingUMesh *mRef=ms[0]; + if(!mRef) + throw INTERP_KERNEL::Exception("MEDFileUMesh::setMeshes : null instance in the first element of input meshes !"); + std::string name(mRef->getName()); + const DataArrayDouble *coo(mRef->getCoords()); + std::set<int> s; + int zeDim=-1; + for(std::vector<const MEDCouplingUMesh *>::const_iterator it=ms.begin();it!=ms.end();it++) + { + const MEDCouplingUMesh *cur(*it); + if(!cur) + throw INTERP_KERNEL::Exception("MEDFileUMesh::setMeshes : null instance in input vector of meshes !"); + if(coo!=cur->getCoords()) + throw INTERP_KERNEL::Exception("MEDFileUMesh::setMeshes : The input meshes do not share the same coordinates !"); + int mdim=cur->getMeshDimension(); + zeDim=std::max(zeDim,mdim); + if(s.find(mdim)!=s.end()) + throw INTERP_KERNEL::Exception("MEDFileUMesh::setMeshes : The input meshes must share the same coordinates pointer, and should have different mesh dimension each other !"); + } + for(std::vector<const MEDCouplingUMesh *>::const_iterator it=ms.begin();it!=ms.end();it++) + { + int mdim=(*it)->getMeshDimension(); + setName((*it)->getName()); + setMeshAtLevel(mdim-zeDim,const_cast<MEDCouplingUMesh *>(*it),renum); + } + setName(name); +} + +/*! + * Creates one MEDCouplingUMesh at a given level in \a this mesh from a sequence of + * meshes each representing a group, and creates corresponding groups in \a this mesh. + * The given meshes must share the same node coordinates array. + * \param [in] meshDimRelToMax - the relative dimension to create the mesh and groups at. + * \param [in] ms - the sequence of meshes. Each mesh in \a ms represents a group to + * create in \a this mesh. + * \throw If \a ms is empty. + * \throw If dimension of meshes in \a ms does not correspond to \a meshDimRelToMax or + * to the existing meshes of other levels of \a this mesh. + * \throw If the meshes in \a ms do not share the same node coordinates array. + * \throw If the node coordinates array of \a this mesh (if any) is not the same as that + * of the given meshes. + * \throw If \a ms[ i ] is not well defined (MEDCouplingUMesh::checkCoherency()). + * \throw If names of some meshes in \a ms are equal. + * \throw If \a ms includes a mesh with an empty name. + */ +void MEDFileUMesh::setGroupsFromScratch(int meshDimRelToMax, const std::vector<const MEDCouplingUMesh *>& ms, bool renum) +{ + if(ms.empty()) + throw INTERP_KERNEL::Exception("MEDFileUMesh::setGroupsFromScratch : expecting a non empty vector !"); + int sz=(-meshDimRelToMax)+1; + if(sz>=(int)_ms.size()) + _ms.resize(sz); + checkMeshDimCoherency(ms[0]->getMeshDimension(),meshDimRelToMax); + DataArrayDouble *coo=checkMultiMesh(ms); + if((DataArrayDouble *)_coords==0) + { + coo->incrRef(); + _coords=coo; + } + else + if((DataArrayDouble *)_coords!=coo) + throw INTERP_KERNEL::Exception("MEDFileUMesh::setGroupsFromScratch : coordinates mismatches !"); + std::vector<DataArrayInt *> corr; + MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m=MEDCouplingUMesh::FuseUMeshesOnSameCoords(ms,_zipconn_pol,corr); + std::vector< MEDCouplingAutoRefCountObjectPtr<DataArrayInt> > corr3(corr.begin(),corr.end()); + setMeshAtLevel(meshDimRelToMax,m,renum); + std::vector<const DataArrayInt *> corr2(corr.begin(),corr.end()); + setGroupsAtLevel(meshDimRelToMax,corr2,true); +} + +/*! + * Creates groups at a given level in \a this mesh from a sequence of + * meshes each representing a group. + * The given meshes must share the same node coordinates array. + * \param [in] meshDimRelToMax - the relative dimension to create the groups at. + * \param [in] ms - the sequence of meshes. Each mesh in \a ms represents a group to + * create in \a this mesh. + * \param [in] renum - if \c true, then the optional numbers of entities are taken into + * account. + * \throw If \a ms is empty. + * \throw If dimension of meshes in \a ms does not correspond to \a meshDimRelToMax or + * to the existing meshes of other levels of \a this mesh. + * \throw If the meshes in \a ms do not share the same node coordinates array. + * \throw If the node coordinates array of \a this mesh (if any) is not the same as that + * of the given meshes. + * \throw If \a ms[ i ] is not well defined (MEDCouplingUMesh::checkCoherency()). + * \throw If names of some meshes in \a ms are equal. + * \throw If \a ms includes a mesh with an empty name. + */ +void MEDFileUMesh::setGroupsOnSetMesh(int meshDimRelToMax, const std::vector<const MEDCouplingUMesh *>& ms, bool renum) +{ + if(ms.empty()) + throw INTERP_KERNEL::Exception("MEDFileUMesh::setGroupsOnSetMesh : expecting a non empty vector !"); + int sz=(-meshDimRelToMax)+1; + if(sz>=(int)_ms.size()) + _ms.resize(sz); + checkMeshDimCoherency(ms[0]->getMeshDimension(),meshDimRelToMax); + DataArrayDouble *coo=checkMultiMesh(ms); + if((DataArrayDouble *)_coords==0) + { + coo->incrRef(); + _coords=coo; + } + else + if((DataArrayDouble *)_coords!=coo) + throw INTERP_KERNEL::Exception("MEDFileUMesh::setGroupsOnSetMesh : coordinates mismatches !"); + MEDCouplingUMesh *m=getMeshAtLevel(meshDimRelToMax,renum); + std::vector< MEDCouplingAutoRefCountObjectPtr<DataArrayInt> > corr(ms.size()); + int i=0; + for(std::vector<const MEDCouplingUMesh *>::const_iterator it=ms.begin();it!=ms.end();it++,i++) + { + DataArrayInt *arr=0; + bool test=m->areCellsIncludedIn(*it,_zipconn_pol,arr); + corr[i]=arr; + if(!test) + { + std::ostringstream oss; oss << "MEDFileUMesh::setGroupsOnSetMesh : mesh #" << i << " is not part of whole mesh !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + } + std::vector<const DataArrayInt *> corr2(corr.begin(),corr.end()); + setGroupsAtLevel(meshDimRelToMax,corr2,renum); +} + +DataArrayDouble *MEDFileUMesh::checkMultiMesh(const std::vector<const MEDCouplingUMesh *>& ms) const +{ + const DataArrayDouble *ret=ms[0]->getCoords(); + int mdim=ms[0]->getMeshDimension(); + for(unsigned int i=1;i<ms.size();i++) + { + ms[i]->checkCoherency(); + if(ms[i]->getCoords()!=ret) + throw INTERP_KERNEL::Exception("MEDFileUMesh::checkMultiMesh : meshes must share the same coords !"); + if(ms[i]->getMeshDimension()!=mdim) + throw INTERP_KERNEL::Exception("MEDFileUMesh::checkMultiMesh : meshes have not same mesh dimension !"); + } + return const_cast<DataArrayDouble *>(ret); +} + +/*! + * 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 MEDFileUMesh::setFamilyFieldArr(int meshDimRelToMaxExt, DataArrayInt *famArr) +{ + if(meshDimRelToMaxExt==1) + { + if(!famArr) + { + _fam_coords=0; + return ; + } + DataArrayDouble *coo(_coords); + if(!coo) + throw INTERP_KERNEL::Exception("MEDFileUMesh::setFamilyFieldArr : the coordinates have not been set !"); + famArr->checkNbOfTuplesAndComp(coo->getNumberOfTuples(),1,"MEDFileUMesh::setFamilyFieldArr : Problem in size of node family arr ! "); + famArr->incrRef(); + _fam_coords=famArr; + return ; + } + if(meshDimRelToMaxExt>1) + throw INTERP_KERNEL::Exception("MEDFileUMesh::setFamilyFieldArr : Dimension request is invalid (>1) !"); + int traducedRk=-meshDimRelToMaxExt; + if(traducedRk>=(int)_ms.size()) + throw INTERP_KERNEL::Exception("Invalid mesh dim relative to max given ! Too low !"); + if((MEDFileUMeshSplitL1 *)_ms[traducedRk]==0) + throw INTERP_KERNEL::Exception("On specified lev (or entity) no cells exists !"); + return _ms[traducedRk]->setFamilyArr(famArr); +} + +/*! + * 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 MEDFileUMesh::setRenumFieldArr(int meshDimRelToMaxExt, DataArrayInt *renumArr) +{ + if(meshDimRelToMaxExt==1) + { + if(!renumArr) + { + _num_coords=0; + _rev_num_coords=0; + return ; + } + DataArrayDouble *coo(_coords); + if(!coo) + throw INTERP_KERNEL::Exception("MEDFileUMesh::setRenumFieldArr : the coordinates have not been set !"); + renumArr->checkNbOfTuplesAndComp(coo->getNumberOfTuples(),1,"MEDFileUMesh::setRenumArr : Problem in size of node numbering arr ! "); + renumArr->incrRef(); + _num_coords=renumArr; + computeRevNum(); + return ; + } + if(meshDimRelToMaxExt>1) + throw INTERP_KERNEL::Exception("MEDFileUMesh::setRenumArr : Dimension request is invalid (>1) !"); + int traducedRk=-meshDimRelToMaxExt; + if(traducedRk>=(int)_ms.size()) + throw INTERP_KERNEL::Exception("Invalid mesh dim relative to max given ! Too low !"); + if((MEDFileUMeshSplitL1 *)_ms[traducedRk]==0) + throw INTERP_KERNEL::Exception("On specified lev (or entity) no cells exists !"); + return _ms[traducedRk]->setRenumArr(renumArr); +} + +/*! + * Sets the optional names of mesh entities of a given dimension. + * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities. + * \param [in] nameArr - the array of the names. + * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh. + * \throw If \a nameArr has an invalid size. + */ +void MEDFileUMesh::setNameFieldAtLevel(int meshDimRelToMaxExt, DataArrayAsciiChar *nameArr) +{ + if(meshDimRelToMaxExt==1) + { + if(!nameArr) + { + _name_coords=0; + return ; + } + DataArrayDouble *coo(_coords); + if(!coo) + throw INTERP_KERNEL::Exception("MEDFileUMesh::setNameFieldAtLevel : the coordinates have not been set !"); + nameArr->checkNbOfTuplesAndComp(coo->getNumberOfTuples(),MED_SNAME_SIZE,"MEDFileUMesh::setNameFieldAtLevel : Problem in size of node numbering arr ! "); + nameArr->incrRef(); + _name_coords=nameArr; + return ; + } + if(meshDimRelToMaxExt>1) + throw INTERP_KERNEL::Exception("MEDFileUMesh::setNameFieldAtLevel : Dimension request is invalid (>1) !"); + int traducedRk=-meshDimRelToMaxExt; + if(traducedRk>=(int)_ms.size()) + throw INTERP_KERNEL::Exception("Invalid mesh dim relative to max given ! Too low !"); + if((MEDFileUMeshSplitL1 *)_ms[traducedRk]==0) + throw INTERP_KERNEL::Exception("On specified lev (or entity) no cells exists !"); + return _ms[traducedRk]->setNameArr(nameArr); +} + +void MEDFileUMesh::synchronizeTinyInfoOnLeaves() const +{ + for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++) + if((const MEDFileUMeshSplitL1 *)(*it)) + (*it)->synchronizeTinyInfo(*this); +} + +/*! + * This method is called by MEDFileMesh::changeFamilyId. It performs only one part of the family id modification. + */ +void MEDFileUMesh::changeFamilyIdArr(int oldId, int newId) +{ + DataArrayInt *arr=_fam_coords; + if(arr) + arr->changeValue(oldId,newId); + for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> >::iterator it=_ms.begin();it!=_ms.end();it++) + { + MEDFileUMeshSplitL1 *sp=(*it); + if(sp) + { + sp->changeFamilyIdArr(oldId,newId); + } + } +} + +std::list< MEDCouplingAutoRefCountObjectPtr<DataArrayInt> > MEDFileUMesh::getAllNonNullFamilyIds() const +{ + std::list< MEDCouplingAutoRefCountObjectPtr<DataArrayInt> > ret; + const DataArrayInt *da(_fam_coords); + if(da) + { da->incrRef(); ret.push_back(MEDCouplingAutoRefCountObjectPtr<DataArrayInt>(const_cast<DataArrayInt *>(da))); } + for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> >::const_iterator it=_ms.begin();it!=_ms.end();it++) + { + const MEDFileUMeshSplitL1 *elt(*it); + if(elt) + { + da=elt->getFamilyField(); + if(da) + { da->incrRef(); ret.push_back(MEDCouplingAutoRefCountObjectPtr<DataArrayInt>(const_cast<DataArrayInt *>(da))); } + } + } + return ret; +} + +void MEDFileUMesh::computeRevNum() const +{ + if((const DataArrayInt *)_num_coords) + { + int pos; + int maxValue=_num_coords->getMaxValue(pos); + _rev_num_coords=_num_coords->invertArrayN2O2O2N(maxValue+1); + } +} + +std::size_t MEDFileStructuredMesh::getHeapMemorySizeWithoutChildren() const +{ + return MEDFileMesh::getHeapMemorySizeWithoutChildren(); +} + +std::vector<const BigMemoryObject *> MEDFileStructuredMesh::getDirectChildrenWithNull() const +{ + std::vector<const BigMemoryObject *> ret(MEDFileMesh::getDirectChildrenWithNull()); + ret.push_back((const DataArrayInt *)_fam_nodes); + ret.push_back((const DataArrayInt *)_num_nodes); + ret.push_back((const DataArrayAsciiChar *)_names_nodes); + ret.push_back((const DataArrayInt *)_fam_cells); + ret.push_back((const DataArrayInt *)_num_cells); + ret.push_back((const DataArrayAsciiChar *)_names_cells); + ret.push_back((const DataArrayInt *)_fam_faces); + ret.push_back((const DataArrayInt *)_num_faces); + ret.push_back((const DataArrayInt *)_rev_num_nodes); + ret.push_back((const DataArrayAsciiChar *)_names_faces); + ret.push_back((const DataArrayInt *)_rev_num_cells); + ret.push_back((const MEDCoupling1SGTUMesh*)_faces_if_necessary); + return ret; +} + +int MEDFileStructuredMesh::getMaxAbsFamilyIdInArrays() const +{ + int ret=-std::numeric_limits<int>::max(),tmp=-1; + if((const DataArrayInt *)_fam_nodes) + { + int val=_fam_nodes->getMaxValue(tmp); + ret=std::max(ret,std::abs(val)); + } + if((const DataArrayInt *)_fam_cells) + { + int val=_fam_cells->getMaxValue(tmp); + ret=std::max(ret,std::abs(val)); + } + if((const DataArrayInt *)_fam_faces) + { + int val=_fam_faces->getMaxValue(tmp); + ret=std::max(ret,std::abs(val)); + } + return ret; +} + +int MEDFileStructuredMesh::getMaxFamilyIdInArrays() const +{ + int ret=-std::numeric_limits<int>::max(),tmp=-1; + if((const DataArrayInt *)_fam_nodes) + { + int val=_fam_nodes->getMaxValue(tmp); + ret=std::max(ret,val); + } + if((const DataArrayInt *)_fam_cells) + { + int val=_fam_cells->getMaxValue(tmp); + ret=std::max(ret,val); + } + if((const DataArrayInt *)_fam_faces) + { + int val=_fam_faces->getMaxValue(tmp); + ret=std::max(ret,val); + } + return ret; +} + +int MEDFileStructuredMesh::getMinFamilyIdInArrays() const +{ + int ret=std::numeric_limits<int>::max(),tmp=-1; + if((const DataArrayInt *)_fam_nodes) + { + int val=_fam_nodes->getMinValue(tmp); + ret=std::min(ret,val); + } + if((const DataArrayInt *)_fam_cells) + { + int val=_fam_cells->getMinValue(tmp); + ret=std::min(ret,val); + } + if((const DataArrayInt *)_fam_faces) + { + int val=_fam_faces->getMinValue(tmp); + ret=std::min(ret,val); + } + return ret; +} + +bool MEDFileStructuredMesh::isEqual(const MEDFileMesh *other, double eps, std::string& what) const +{ + if(!MEDFileMesh::isEqual(other,eps,what)) + return false; + const MEDFileStructuredMesh *otherC=dynamic_cast<const MEDFileStructuredMesh *>(other); + if(!otherC) + { + what="Mesh types differ ! This is structured and other is NOT !"; + return false; + } + const DataArrayInt *famc1=_fam_nodes; + const DataArrayInt *famc2=otherC->_fam_nodes; + if((famc1==0 && famc2!=0) || (famc1!=0 && famc2==0)) + { + what="Mismatch of families arr on nodes ! One is defined and not other !"; + return false; + } + if(famc1) + { + bool ret=famc1->isEqual(*famc2); + if(!ret) + { + what="Families arr on nodes differ !"; + return false; + } + } + famc1=_fam_cells; + famc2=otherC->_fam_cells; + if((famc1==0 && famc2!=0) || (famc1!=0 && famc2==0)) + { + what="Mismatch of families arr on cells ! One is defined and not other !"; + return false; + } + if(famc1) + { + bool ret=famc1->isEqual(*famc2); + if(!ret) + { + what="Families arr on cells differ !"; + return false; + } + } + famc1=_fam_faces; + famc2=otherC->_fam_faces; + if((famc1==0 && famc2!=0) || (famc1!=0 && famc2==0)) + { + what="Mismatch of families arr on faces ! One is defined and not other !"; + return false; + } + if(famc1) + { + bool ret=famc1->isEqual(*famc2); + if(!ret) + { + what="Families arr on faces differ !"; + return false; + } + } + famc1=_num_nodes; + famc2=otherC->_num_nodes; + if((famc1==0 && famc2!=0) || (famc1!=0 && famc2==0)) + { + what="Mismatch of numbering arr on nodes ! One is defined and not other !"; + return false; + } + if(famc1) + { + bool ret=famc1->isEqual(*famc2); + if(!ret) + { + what="Numbering arr on nodes differ !"; + return false; + } + } + famc1=_num_cells; + famc2=otherC->_num_cells; + if((famc1==0 && famc2!=0) || (famc1!=0 && famc2==0)) + { + what="Mismatch of numbering arr on cells ! One is defined and not other !"; + return false; + } + if(famc1) + { + bool ret=famc1->isEqual(*famc2); + if(!ret) + { + what="Numbering arr on cells differ !"; + return false; + } + } + famc1=_num_faces; + famc2=otherC->_num_faces; + if((famc1==0 && famc2!=0) || (famc1!=0 && famc2==0)) + { + what="Mismatch of numbering arr on faces ! One is defined and not other !"; + return false; + } + if(famc1) + { + bool ret=famc1->isEqual(*famc2); + if(!ret) + { + what="Numbering arr on faces differ !"; + return false; + } + } + const DataArrayAsciiChar *d1=_names_cells; + const DataArrayAsciiChar *d2=otherC->_names_cells; + if((d1==0 && d2!=0) || (d1!=0 && d2==0)) + { + what="Mismatch of naming arr on cells ! One is defined and not other !"; + return false; + } + if(d1) + { + bool ret=d1->isEqual(*d2); + if(!ret) + { + what="Naming arr on cells differ !"; + return false; + } + } + d1=_names_faces; + d2=otherC->_names_faces; + if((d1==0 && d2!=0) || (d1!=0 && d2==0)) + { + what="Mismatch of naming arr on faces ! One is defined and not other !"; + return false; + } + if(d1) + { + bool ret=d1->isEqual(*d2); + if(!ret) + { + what="Naming arr on faces differ !"; + return false; + } + } + d1=_names_nodes; + d2=otherC->_names_nodes; + if((d1==0 && d2!=0) || (d1!=0 && d2==0)) + { + what="Mismatch of naming arr on nodes ! One is defined and not other !"; + return false; + } + if(d1) + { + bool ret=d1->isEqual(*d2); + if(!ret) + { + what="Naming arr on nodes differ !"; + return false; + } + } + return true; +} + +void MEDFileStructuredMesh::clearNonDiscrAttributes() const +{ + MEDFileMesh::clearNonDiscrAttributes(); + const DataArrayInt *tmp=_fam_nodes; + if(tmp) + (const_cast<DataArrayInt *>(tmp))->setName(""); + tmp=_num_nodes; + if(tmp) + (const_cast<DataArrayInt *>(tmp))->setName(""); + tmp=_fam_cells; + if(tmp) + (const_cast<DataArrayInt *>(tmp))->setName(""); + tmp=_num_cells; + if(tmp) + (const_cast<DataArrayInt *>(tmp))->setName(""); + tmp=_fam_faces; + if(tmp) + (const_cast<DataArrayInt *>(tmp))->setName(""); + tmp=_num_faces; + if(tmp) + (const_cast<DataArrayInt *>(tmp))->setName(""); +} + +/*! + * 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 *MEDFileStructuredMesh::getFamiliesArr(int meshDimRelToMaxExt, const std::vector<std::string>& fams, bool renum) const +{ + std::vector<int> famIds(getFamiliesIds(fams)); + switch(meshDimRelToMaxExt) + { + case 1: + { + if((const DataArrayInt *)_fam_nodes) + { + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> da; + if(!famIds.empty()) + da=_fam_nodes->getIdsEqualList(&famIds[0],&famIds[0]+famIds.size()); + else + da=_fam_nodes->getIdsEqualList(0,0); + if(renum) + return MEDFileUMeshSplitL1::Renumber(_num_nodes,da); + else + return da.retn(); + } + else + throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getFamiliesArr : no family array specified on nodes !"); + break; + } + case 0: + { + if((const DataArrayInt *)_fam_cells) + { + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> da; + if(!famIds.empty()) + da=_fam_cells->getIdsEqualList(&famIds[0],&famIds[0]+famIds.size()); + else + da=_fam_cells->getIdsEqualList(0,0); + if(renum) + return MEDFileUMeshSplitL1::Renumber(_num_cells,da); + else + return da.retn(); + } + else + throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getFamiliesArr : no family array specified on cells !"); + break; + } + case -1: + { + if((const DataArrayInt *)_fam_faces) + { + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> da; + if(!famIds.empty()) + da=_fam_faces->getIdsEqualList(&famIds[0],&famIds[0]+famIds.size()); + else + da=_fam_faces->getIdsEqualList(0,0); + if(renum) + return MEDFileUMeshSplitL1::Renumber(_num_faces,da); + else + return da.retn(); + } + else + throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getFamiliesArr : no family array specified on faces !"); + break; + } + default: + throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getFamiliesArr : input meshDimRelative must be in [0,1,-1] !"); + } + throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getFamiliesArr : unmanaged case !"); +} + +/*! + * 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. + * \throw If \a meshDimRelToMaxExt != 0 and \a meshDimRelToMaxExt != 1 and \a meshDimRelToMaxExt != -1. + */ +void MEDFileStructuredMesh::setFamilyFieldArr(int meshDimRelToMaxExt, DataArrayInt *famArr) +{ + const MEDCouplingStructuredMesh *mesh(getStructuredMesh()); + if(!mesh) + throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::setFamilyFieldArr : no structured mesh specified ! Impossible to set family array !"); + switch(meshDimRelToMaxExt) + { + case 0: + { + int nbCells=mesh->getNumberOfCells(); + famArr->checkNbOfTuplesAndComp(nbCells,1,"MEDFileStructuredMesh::setFamilyFieldArr : Problem in size of Family arr ! Mismatch with number of cells of mesh !"); + _fam_cells=famArr; + break; + } + case 1: + { + int nbNodes=mesh->getNumberOfNodes(); + famArr->checkNbOfTuplesAndComp(nbNodes,1,"MEDFileStructuredMesh::setFamilyFieldArr : Problem in size of Family arr ! Mismatch with number of nodes of mesh !"); + _fam_nodes=famArr; + break; + } + case -1: + { + int nbCells=mesh->getNumberOfCellsOfSubLevelMesh(); + famArr->checkNbOfTuplesAndComp(nbCells,1,"MEDFileStructuredMesh::setFamilyFieldArr : Problem in size of Family arr ! Mismatch with number of faces of mesh !"); + _fam_faces=famArr; + break; + } + default: + throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::setFamilyFieldArr : Only available for levels 0 or 1 or -1 !"); + } + if(famArr) + famArr->incrRef(); +} + +/*! + * 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. + * \throw If \a meshDimRelToMaxExt != 0 and \a meshDimRelToMaxExt != 1. + */ +void MEDFileStructuredMesh::setRenumFieldArr(int meshDimRelToMaxExt, DataArrayInt *renumArr) +{ + const MEDCouplingStructuredMesh *mesh=getStructuredMesh(); + if(!mesh) + throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::setRenumFieldArr : no structured mesh specified ! Impossible to set number array !"); + switch(meshDimRelToMaxExt) + { + case 0: + { + int nbCells=mesh->getNumberOfCells(); + renumArr->checkNbOfTuplesAndComp(nbCells,1,"MEDFileStructuredMesh::setRenumFieldArr : Problem in size of Renum arr ! Mismatch with number of cells of mesh !"); + _num_cells=renumArr; + break; + } + case 1: + { + int nbNodes=mesh->getNumberOfNodes(); + renumArr->checkNbOfTuplesAndComp(nbNodes,1,"MEDFileStructuredMesh::setRenumFieldArr : Problem in size of Family arr ! Mismatch with number of nodes of mesh !"); + _num_nodes=renumArr; + break; + } + case -1: + { + int nbCells=mesh->getNumberOfCellsOfSubLevelMesh(); + renumArr->checkNbOfTuplesAndComp(nbCells,1,"MEDFileStructuredMesh::setRenumFieldArr : Problem in size of Renum arr ! Mismatch with number of faces of mesh !"); + _num_faces=renumArr; + break; + } + default: + throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::setRenumFieldArr : Only available for levels 0 or 1 or -1 !"); + } + if(renumArr) + renumArr->incrRef(); +} + +/*! + * Sets the optional names of mesh entities of a given dimension. + * \param [in] meshDimRelToMaxExt - the relative dimension of mesh entities. + * \param [in] nameArr - the array of the names. + * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh. + * \throw If \a nameArr has an invalid size. + */ +void MEDFileStructuredMesh::setNameFieldAtLevel(int meshDimRelToMaxExt, DataArrayAsciiChar *nameArr) +{ + const MEDCouplingStructuredMesh *mesh(getStructuredMesh()); + if(!mesh) + throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::setNameFieldAtLevel : no structured mesh specified ! Impossible to set names array !"); + switch(meshDimRelToMaxExt) + { + case 0: + { + int nbCells=mesh->getNumberOfCells(); + nameArr->checkNbOfTuplesAndComp(nbCells,MED_SNAME_SIZE,"MEDFileStructuredMesh::setNameFieldAtLevel : Problem in size of names arr ! Mismatch with number of cells of mesh !"); + _names_cells=nameArr; + break; + } + case 1: + { + int nbNodes=mesh->getNumberOfNodes(); + nameArr->checkNbOfTuplesAndComp(nbNodes,MED_SNAME_SIZE,"MEDFileStructuredMesh::setNameFieldAtLevel : Problem in size of names arr ! Mismatch with number of nodes of mesh !"); + _names_nodes=nameArr; + break; + } + case -1: + { + int nbCells=mesh->getNumberOfCellsOfSubLevelMesh(); + nameArr->checkNbOfTuplesAndComp(nbCells,MED_SNAME_SIZE,"MEDFileStructuredMesh::setNameFieldAtLevel : Problem in size of names arr ! Mismatch with number of faces of mesh !"); + _names_cells=nameArr; + } + default: + throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::setNameFieldAtLevel : Only available for levels 0 or 1 or -1 !"); + } + if(nameArr) + nameArr->incrRef(); +} + +/*! + * Adds a group of nodes to \a this mesh. + * \param [in] ids - a DataArrayInt providing ids and a name of the group to add. + * The ids should be sorted and different each other (MED file norm). + * + * \warning this method can alter default "FAMILLE_ZERO" family. + * For users sensitive to this a call to MEDFileMesh::rearrangeFamilies will be necessary after addGroup session. + * + * \throw If the node coordinates array is not set. + * \throw If \a ids == \c NULL. + * \throw If \a ids->getName() == "". + * \throw If \a ids does not respect the MED file norm. + * \throw If a group with name \a ids->getName() already exists. + */ +void MEDFileStructuredMesh::addNodeGroup(const DataArrayInt *ids) +{ + addGroup(1,ids); +} + +/*! + * Adds a group of nodes/cells/faces/edges to \a this mesh. + * + * \param [in] ids - a DataArrayInt providing ids and a name of the group to add. + * The ids should be sorted and different each other (MED file norm). + * + * \warning this method can alter default "FAMILLE_ZERO" family. + * For users sensitive to this a call to MEDFileMesh::rearrangeFamilies will be necessary after addGroup session. + * + * \throw If the node coordinates array is not set. + * \throw If \a ids == \c NULL. + * \throw If \a ids->getName() == "". + * \throw If \a ids does not respect the MED file norm. + * \throw If a group with name \a ids->getName() already exists. + */ +void MEDFileStructuredMesh::addGroup(int meshDimRelToMaxExt, const DataArrayInt *ids) +{ + DataArrayInt *fam(getOrCreateAndGetFamilyFieldAtLevel(meshDimRelToMaxExt)); + addGroupUnderground(false,ids,fam); + return ; +} + +/*! + * 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 \c NULL. + * \throw If \a meshDimRelToMaxExt != 0 and \a meshDimRelToMaxExt != 1. + */ +const DataArrayInt *MEDFileStructuredMesh::getFamilyFieldAtLevel(int meshDimRelToMaxExt) const +{ + switch(meshDimRelToMaxExt) + { + case 0: + return _fam_cells; + case 1: + return _fam_nodes; + case -1: + return _fam_faces; + default: + throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getFamilyFieldAtLevel : Only available for levels 0 or 1 or -1 !"); + } +} + +/*! + * 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 \c NULL. + * \throw If \a meshDimRelToMaxExt != 0 and \a meshDimRelToMaxExt != 1. + */ +DataArrayInt *MEDFileStructuredMesh::getFamilyFieldAtLevel(int meshDimRelToMaxExt) +{ + switch(meshDimRelToMaxExt) + { + case 0: + return _fam_cells; + case 1: + return _fam_nodes; + case -1: + return _fam_faces; + default: + throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getFamilyFieldAtLevel : Only available for levels 0 or 1 or -1 !"); + } +} + +/*! + * 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. + * \throw If \a meshDimRelToMaxExt != 0 and \a meshDimRelToMaxExt != 1. + */ +const DataArrayInt *MEDFileStructuredMesh::getNumberFieldAtLevel(int meshDimRelToMaxExt) const +{ + switch(meshDimRelToMaxExt) + { + case 0: + return _num_cells; + case 1: + return _num_nodes; + case -1: + return _num_faces; + default: + throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getNumberFieldAtLevel : Only available for levels 0 or 1 or -1 !"); + } +} + +/*! + * 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 \a meshDimRelToMaxExt != 0 and \a meshDimRelToMaxExt != 1. + * \throw If there are no mesh entities of \a meshDimRelToMaxExt dimension in \a this mesh. + */ +const DataArrayInt *MEDFileStructuredMesh::getRevNumberFieldAtLevel(int meshDimRelToMaxExt) const +{ + if(meshDimRelToMaxExt!=0 && meshDimRelToMaxExt!=1) + throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getRevNumberFieldAtLevel : Only available for levels 0 or 1 !"); + if(meshDimRelToMaxExt==0) + { + if((const DataArrayInt *)_num_cells) + { + int pos; + int maxValue=_num_cells->getMaxValue(pos); + _rev_num_cells=_num_cells->invertArrayN2O2O2N(maxValue+1); + return _rev_num_cells; + } + else + throw INTERP_KERNEL::Exception("MEDFileCMesh::getRevNumberFieldAtLevel : no cell renumbering for a request on reverse numbering !"); + } + else + { + if((const DataArrayInt *)_num_nodes) + { + int pos; + int maxValue=_num_nodes->getMaxValue(pos); + _rev_num_nodes=_num_nodes->invertArrayN2O2O2N(maxValue+1); + return _rev_num_nodes; + } + else + throw INTERP_KERNEL::Exception("MEDFileCMesh::getRevNumberFieldAtLevel : no node renumbering for a request on reverse numbering !"); + } +} + +const DataArrayAsciiChar *MEDFileStructuredMesh::getNameFieldAtLevel(int meshDimRelToMaxExt) const +{ + switch(meshDimRelToMaxExt) + { + case 0: + return _names_cells; + case 1: + return _names_nodes; + case -1: + return _names_faces; + default: + throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getNameFieldAtLevel : Only available for levels 0 or 1 or -1 !"); + } +} + +/*! + * Returns relative dimensions of mesh entities (excluding nodes) present in \a this mesh. + * \return std::vector<int> - a sequence of the relative dimensions: [0]. + */ +std::vector<int> MEDFileStructuredMesh::getNonEmptyLevels() const +{ + std::vector<int> ret(1); + return ret; +} + +/*! + * Returns relative dimensions of mesh entities (including nodes) present in \a this mesh. + * \return std::vector<int> - a sequence of the relative dimensions: [1,0]. + */ +std::vector<int> MEDFileStructuredMesh::getNonEmptyLevelsExt() const +{ + std::vector<int> ret(2); + ret[0]=1; + return ret; +} + +/*! + * Returns the set of extensive levels (nodes included) where not NULL family arr are defined. + */ +std::vector<int> MEDFileStructuredMesh::getFamArrNonEmptyLevelsExt() const +{ + std::vector<int> ret; + const DataArrayInt *famNodes(_fam_nodes),*famCells(_fam_cells),*famFaces(_fam_faces); + if(famNodes) + ret.push_back(1); + if(famCells) + ret.push_back(0); + if(famFaces) + ret.push_back(-1); + return ret; +} + +/*! + * Returns the set of extensive levels (nodes included) where not NULL numbering arr are defined. + */ +std::vector<int> MEDFileStructuredMesh::getNumArrNonEmptyLevelsExt() const +{ + std::vector<int> ret; + const DataArrayInt *numNodes(_num_nodes),*numCells(_num_cells),*numFaces(_num_faces); + if(numNodes) + ret.push_back(1); + if(numCells) + ret.push_back(0); + if(numFaces) + ret.push_back(-1); + return ret; +} + +/*! + * Returns the set of extensive levels (nodes included) where not NULL naming arr are defined. + */ +std::vector<int> MEDFileStructuredMesh::getNameArrNonEmptyLevelsExt() const +{ + std::vector<int> ret; + const DataArrayAsciiChar *namesNodes(_names_nodes),*namesCells(_names_cells),*namesFaces(_names_faces); + if(namesNodes) + ret.push_back(1); + if(namesCells) + ret.push_back(0); + if(namesFaces) + ret.push_back(-1); + return ret; +} + +/*! + * no implementation here, it is not a bug, but intresically no polyhedra in \a this. + */ +bool MEDFileStructuredMesh::unPolyze(std::vector<int>& oldCode, std::vector<int>& newCode, DataArrayInt *& o2nRenumCell) +{ + oldCode.clear(); newCode.clear(); o2nRenumCell=0; + return false; +} + +void MEDFileStructuredMesh::changeFamilyIdArr(int oldId, int newId) +{ + DataArrayInt *arr=_fam_nodes; + if(arr) + arr->changeValue(oldId,newId); + arr=_fam_cells; + if(arr) + arr->changeValue(oldId,newId); + arr=_fam_faces; + if(arr) + arr->changeValue(oldId,newId); +} + +std::list< MEDCouplingAutoRefCountObjectPtr<DataArrayInt> > MEDFileStructuredMesh::getAllNonNullFamilyIds() const +{ + std::list< MEDCouplingAutoRefCountObjectPtr<DataArrayInt> > ret; + const DataArrayInt *da(_fam_nodes); + if(da) + { da->incrRef(); ret.push_back(MEDCouplingAutoRefCountObjectPtr<DataArrayInt>(const_cast<DataArrayInt *>(da))); } + da=_fam_cells; + if(da) + { da->incrRef(); ret.push_back(MEDCouplingAutoRefCountObjectPtr<DataArrayInt>(const_cast<DataArrayInt *>(da))); } + da=_fam_faces; + if(da) + { da->incrRef(); ret.push_back(MEDCouplingAutoRefCountObjectPtr<DataArrayInt>(const_cast<DataArrayInt *>(da))); } + return ret; +} + +void MEDFileStructuredMesh::deepCpyAttributes() +{ + if((const DataArrayInt*)_fam_nodes) + _fam_nodes=_fam_nodes->deepCpy(); + if((const DataArrayInt*)_num_nodes) + _num_nodes=_num_nodes->deepCpy(); + if((const DataArrayAsciiChar*)_names_nodes) + _names_nodes=_names_nodes->deepCpy(); + if((const DataArrayInt*)_fam_cells) + _fam_cells=_fam_cells->deepCpy(); + if((const DataArrayInt*)_num_cells) + _num_cells=_num_cells->deepCpy(); + if((const DataArrayAsciiChar*)_names_cells) + _names_cells=_names_cells->deepCpy(); + if((const DataArrayInt*)_fam_faces) + _fam_faces=_fam_faces->deepCpy(); + if((const DataArrayInt*)_num_faces) + _num_faces=_num_faces->deepCpy(); + if((const DataArrayAsciiChar*)_names_faces) + _names_faces=_names_faces->deepCpy(); + if((const DataArrayInt*)_rev_num_nodes) + _rev_num_nodes=_rev_num_nodes->deepCpy(); + if((const DataArrayInt*)_rev_num_cells) + _rev_num_cells=_rev_num_cells->deepCpy(); +} + +/*! + * Returns a pointer to mesh at the specified level (here 0 is compulsary for cartesian mesh). + * + * \return a pointer to cartesian mesh that need to be managed by the caller. + * \warning the returned pointer has to be managed by the caller. + */ + +/*! + * Returns a pointer to MEDCouplingStructuredMesh held by \a this. + * \param [in] meshDimRelToMax - it must be \c 0 or \c -1. + * \param [in] renum - it must be \c false. + * \return MEDCouplingMesh * - a pointer to MEDCouplingMesh that the caller is to + * delete using decrRef() as it is no more needed. + */ +MEDCouplingMesh *MEDFileStructuredMesh::getGenMeshAtLevel(int meshDimRelToMax, bool renum) const +{ + if(renum) + throw INTERP_KERNEL::Exception("MEDFileCurveLinearMesh does not support renumbering ! To do it perform request of renum array directly !"); + const MEDCouplingStructuredMesh *m(getStructuredMesh()); + switch(meshDimRelToMax) + { + case 0: + { + if(m) + m->incrRef(); + return const_cast<MEDCouplingStructuredMesh *>(m); + } + case -1: + { + if(!m) + throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getGenMeshAtLevel : level -1 requested must be non empty to be able to compute unstructured sub mesh !"); + buildMinusOneImplicitPartIfNeeded(); + MEDCouplingMesh *ret(_faces_if_necessary); + if(ret) + ret->incrRef(); + return ret; + } + default: + throw INTERP_KERNEL::Exception("MEDFileCurveLinearMesh does not support multi level for mesh 0 expected as input !"); + } +} + +/*! + * 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 MEDFileStructuredMesh::getSizeAtLevel(int meshDimRelToMaxExt) const +{ + const MEDCouplingStructuredMesh *cmesh(getStructuredMesh()); + if(!cmesh) + throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getSizeAtLevel : No structured mesh set !"); + switch(meshDimRelToMaxExt) + { + case 0: + return cmesh->getNumberOfCells(); + case 1: + return cmesh->getNumberOfNodes(); + case -1: + return cmesh->getNumberOfCellsOfSubLevelMesh(); + default: + throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getSizeAtLevel : Only available for levels 0 or 1 or -1 !"); + } +} + +int MEDFileStructuredMesh::getNumberOfNodes() const +{ + const MEDCouplingStructuredMesh *cmesh(getStructuredMesh()); + if(!cmesh) + throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getNumberOfNodes : no cartesian mesh set !"); + return cmesh->getNumberOfNodes(); +} + +int MEDFileStructuredMesh::getNumberOfCellsAtLevel(int meshDimRelToMaxExt) const +{ + const MEDCouplingStructuredMesh *cmesh(getStructuredMesh()); + if(!cmesh) + throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getNumberOfNodes : no cartesian mesh set !"); + switch(meshDimRelToMaxExt) + { + case 0: + return cmesh->getNumberOfCells(); + case -1: + return cmesh->getNumberOfCellsOfSubLevelMesh(); + default: + throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getNumberOfNodes : only meshDimRelToMax=0 and meshDimRelToMax=-1 supported !"); + } +} + +bool MEDFileStructuredMesh::hasImplicitPart() const +{ + return true; +} + +/*! + * \sa MEDFileStructuredMesh::getImplicitFaceMesh + */ +int MEDFileStructuredMesh::buildImplicitPartIfAny(INTERP_KERNEL::NormalizedCellType gt) const +{ + static const char MSG[]="MEDFileStructuredMesh::buildImplicitPartIfAny : the given geo type is not manageable by a structured mesh !"; + const MEDCoupling1SGTUMesh *zeFaceMesh(_faces_if_necessary); + if(!zeFaceMesh) + { + const INTERP_KERNEL::CellModel& cm(INTERP_KERNEL::CellModel::GetCellModel(MEDCouplingStructuredMesh::GetGeoTypeGivenMeshDimension(getMeshDimension()))); + if(cm.getReverseExtrudedType()!=gt) + throw INTERP_KERNEL::Exception(MSG); + buildImplicitPart(); + return getStructuredMesh()->getNumberOfCellsOfSubLevelMesh(); + } + else + { + if(gt!=zeFaceMesh->getCellModelEnum()) + throw INTERP_KERNEL::Exception(MSG); + return zeFaceMesh->getNumberOfCells(); + } +} + +void MEDFileStructuredMesh::buildMinusOneImplicitPartIfNeeded() const +{ + const MEDCoupling1SGTUMesh *zeFaceMesh(_faces_if_necessary); + if(!zeFaceMesh) + buildImplicitPart(); +} + +void MEDFileStructuredMesh::buildImplicitPart() const +{ + const MEDCouplingStructuredMesh *mcmesh(getStructuredMesh()); + if(!mcmesh) + throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::buildImplicitPart : Unable to build the implicit part of structured mesh because no structured mesh at level 0 defined !"); + _faces_if_necessary=mcmesh->build1SGTSubLevelMesh(); +} + +void MEDFileStructuredMesh::releaseImplicitPartIfAny() const +{ + _faces_if_necessary=0; +} + +/*! + * Retrieves the internal pointer (no decrRef requested) of the implicit face mesh if any. + * To force to build it you can invoke MEDFileStructuredMesh::buildImplicitPartIfAny method. + * + * \sa MEDFileStructuredMesh::buildImplicitPartIfAny + */ +MEDCoupling1SGTUMesh *MEDFileStructuredMesh::getImplicitFaceMesh() const +{ + return _faces_if_necessary; +} + +std::vector<INTERP_KERNEL::NormalizedCellType> MEDFileStructuredMesh::getGeoTypesAtLevel(int meshDimRelToMax) const +{ + const MEDCouplingStructuredMesh *cmesh(getStructuredMesh()); + if(!cmesh) + throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getGeoTypesAtLevel : No structured mesh set !"); + switch(meshDimRelToMax) + { + case 0: + { + std::vector<INTERP_KERNEL::NormalizedCellType> ret(1,cmesh->getTypeOfCell(0)); + return ret; + } + case -1: + { + int mdim(cmesh->getMeshDimension()); + if(mdim<1) + throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getGeoTypesAtLevel : only one level available for structured meshes ! Input 0 is mandatory or 0D mesh !"); + std::vector<INTERP_KERNEL::NormalizedCellType> ret(1,MEDCouplingStructuredMesh::GetGeoTypeGivenMeshDimension(mdim-1)); + return ret; + } + default: + throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::getGeoTypesAtLevel : only 2 levels available at most : 0 and -1 !"); + } +} + +void MEDFileStructuredMesh::whichAreNodesFetched(const MEDFileField1TSStructItem& st, const MEDFileFieldGlobsReal *globs, std::vector<bool>& nodesFetched) const +{ + if(st.getNumberOfItems()!=1) + throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::whichAreNodesFetched : The sturture of field is not lying on single geo type ! it is not managed yet for structured mesh !"); + if(st[0].getGeo()!=MEDCouplingStructuredMesh::GetGeoTypeGivenMeshDimension(getMeshDimension())) + throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::whichAreNodesFetched : The sturture of field is not lying on expected geo type !"); + if(getNumberOfNodes()!=(int)nodesFetched.size()) + throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::whichAreNodesFetched : invalid size of array !"); + if(st[0].getPflName().empty()) + { + std::fill(nodesFetched.begin(),nodesFetched.end(),true); + return ; + } + const DataArrayInt *arr(globs->getProfile(st[0].getPflName())); + const MEDCouplingStructuredMesh *cmesh=getStructuredMesh();//cmesh not null because getNumberOfNodes called before + int sz(nodesFetched.size()); + for(const int *work=arr->begin();work!=arr->end();work++) + { + std::vector<int> conn; + cmesh->getNodeIdsOfCell(*work,conn); + for(std::vector<int>::const_iterator it=conn.begin();it!=conn.end();it++) + if(*it>=0 && *it<sz) + nodesFetched[*it]=true; + else + throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::whichAreNodesFetched : internal error !"); + } +} + +med_geometry_type MEDFileStructuredMesh::GetGeoTypeFromMeshDim(int meshDim) +{ + INTERP_KERNEL::NormalizedCellType ct(MEDCouplingStructuredMesh::GetGeoTypeGivenMeshDimension(meshDim)); + return typmai3[ct]; +} + +void MEDFileStructuredMesh::LoadStrMeshDAFromFile(med_idt fid, int meshDim, int dt, int it, const std::string& mName, MEDFileMeshReadSelector *mrs, + MEDCouplingAutoRefCountObjectPtr<DataArrayInt>& famCells, MEDCouplingAutoRefCountObjectPtr<DataArrayInt>& numCells, MEDCouplingAutoRefCountObjectPtr<DataArrayAsciiChar>& namesCells) +{ + med_bool chgt=MED_FALSE,trsf=MED_FALSE; + med_geometry_type geoTypeReq=MEDFileStructuredMesh::GetGeoTypeFromMeshDim(meshDim); + int nbOfElt(0); + nbOfElt=MEDmeshnEntity(fid,mName.c_str(),dt,it,MED_CELL,geoTypeReq,MED_FAMILY_NUMBER,MED_NODAL,&chgt,&trsf); + if(nbOfElt>0) + { + if(!mrs || mrs->isCellFamilyFieldReading()) + { + famCells=DataArrayInt::New(); + famCells->alloc(nbOfElt,1); + MEDFILESAFECALLERRD0(MEDmeshEntityFamilyNumberRd,(fid,mName.c_str(),dt,it,MED_CELL,geoTypeReq,famCells->getPointer())); + } + } + nbOfElt=MEDmeshnEntity(fid,mName.c_str(),dt,it,MED_CELL,geoTypeReq,MED_NUMBER,MED_NODAL,&chgt,&trsf); + if(nbOfElt>0) + { + if(!mrs || mrs->isCellNumFieldReading()) + { + numCells=DataArrayInt::New(); + numCells->alloc(nbOfElt,1); + MEDFILESAFECALLERRD0(MEDmeshEntityNumberRd,(fid,mName.c_str(),dt,it,MED_CELL,geoTypeReq,numCells->getPointer())); + } + } + nbOfElt=MEDmeshnEntity(fid,mName.c_str(),dt,it,MED_CELL,geoTypeReq,MED_NAME,MED_NODAL,&chgt,&trsf); + if(nbOfElt>0) + { + if(!mrs || mrs->isCellNameFieldReading()) + { + namesCells=DataArrayAsciiChar::New(); + namesCells->alloc(nbOfElt+1,MED_SNAME_SIZE);//not a bug to avoid the memory corruption due to last \0 at the end + MEDFILESAFECALLERRD0(MEDmeshEntityNameRd,(fid,mName.c_str(),dt,it,MED_CELL,geoTypeReq,namesCells->getPointer())); + namesCells->reAlloc(nbOfElt);//not a bug to avoid the memory corruption due to last \0 at the end + } + } +} + +void MEDFileStructuredMesh::loadStrMeshFromFile(MEDFileStrMeshL2 *strm, med_idt fid, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs) +{ + setName(strm->getName()); + setDescription(strm->getDescription()); + setUnivName(strm->getUnivName()); + setIteration(strm->getIteration()); + setOrder(strm->getOrder()); + setTimeValue(strm->getTime()); + setTimeUnit(strm->getTimeUnit()); + MEDFileMeshL2::ReadFamiliesAndGrps(fid,mName,_families,_groups,mrs); + med_bool chgt=MED_FALSE,trsf=MED_FALSE; + int nbOfElt(MEDmeshnEntity(fid,mName.c_str(),dt,it,MED_NODE,MED_NONE,MED_FAMILY_NUMBER,MED_NODAL,&chgt,&trsf)); + if(nbOfElt>0) + { + if(!mrs || mrs->isNodeFamilyFieldReading()) + { + int nbNodes(getNumberOfNodes()); + if(nbOfElt>nbNodes) + throw INTERP_KERNEL::Exception("MEDFileStructuredMesh::loadStrMeshFromFile : invalid size of family node array regarding number of nodes in this ! File seems to be corrupted !"); + _fam_nodes=DataArrayInt::New(); + _fam_nodes->alloc(nbNodes,1);//yes nbNodes and not nbOfElt see next line. + if(nbNodes>nbOfElt)//yes it appends some times... It explains surely the mdump implementation. Bug revealed by PARAVIS EDF #2475 on structured.med file where only 12 first nodes are !=0 so nbOfElt=12 and nbOfNodes=378... + _fam_nodes->fillWithZero(); + MEDFILESAFECALLERRD0(MEDmeshEntityFamilyNumberRd,(fid,mName.c_str(),dt,it,MED_NODE,MED_NONE,_fam_nodes->getPointer())); + } + } + nbOfElt=MEDmeshnEntity(fid,mName.c_str(),dt,it,MED_NODE,MED_NONE,MED_NUMBER,MED_NODAL,&chgt,&trsf); + if(nbOfElt>0) + { + if(!mrs || mrs->isNodeNumFieldReading()) + { + _num_nodes=DataArrayInt::New(); + _num_nodes->alloc(nbOfElt,1); + MEDFILESAFECALLERRD0(MEDmeshEntityNumberRd,(fid,mName.c_str(),dt,it,MED_NODE,MED_NONE,_num_nodes->getPointer())); + } + } + nbOfElt=MEDmeshnEntity(fid,mName.c_str(),dt,it,MED_NODE,MED_NONE,MED_NAME,MED_NODAL,&chgt,&trsf); + if(nbOfElt>0) + { + if(!mrs || mrs->isNodeNameFieldReading()) + { + _names_nodes=DataArrayAsciiChar::New(); + _names_nodes->alloc(nbOfElt+1,MED_SNAME_SIZE);//not a bug to avoid the memory corruption due to last \0 at the end + MEDFILESAFECALLERRD0(MEDmeshEntityNameRd,(fid,mName.c_str(),dt,it,MED_NODE,MED_NONE,_names_nodes->getPointer())); + _names_nodes->reAlloc(nbOfElt);//not a bug to avoid the memory corruption due to last \0 at the end + } + } + int meshDim(getStructuredMesh()->getMeshDimension()); + LoadStrMeshDAFromFile(fid,meshDim,dt,it,mName,mrs,_fam_cells,_num_cells,_names_cells); + if(meshDim>=1) + LoadStrMeshDAFromFile(fid,meshDim-1,dt,it,mName,mrs,_fam_faces,_num_faces,_names_faces); +} + +void MEDFileStructuredMesh::writeStructuredLL(med_idt fid, const std::string& maa) const +{ + int meshDim(getStructuredMesh()->getMeshDimension()); + med_geometry_type geoTypeReq(GetGeoTypeFromMeshDim(meshDim)),geoTypeReq2(GetGeoTypeFromMeshDim(meshDim-1)); + // + if((const DataArrayInt *)_fam_cells) + MEDFILESAFECALLERWR0(MEDmeshEntityFamilyNumberWr,(fid,maa.c_str(),_iteration,_order,MED_CELL,geoTypeReq,_fam_cells->getNumberOfTuples(),_fam_cells->getConstPointer())); + if((const DataArrayInt *)_fam_faces) + MEDFILESAFECALLERWR0(MEDmeshEntityFamilyNumberWr,(fid,maa.c_str(),_iteration,_order,MED_CELL,geoTypeReq2,_fam_faces->getNumberOfTuples(),_fam_faces->getConstPointer())); + if((const DataArrayInt *)_fam_nodes) + MEDFILESAFECALLERWR0(MEDmeshEntityFamilyNumberWr,(fid,maa.c_str(),_iteration,_order,MED_NODE,MED_NONE,_fam_nodes->getNumberOfTuples(),_fam_nodes->getConstPointer())); + if((const DataArrayInt *)_num_cells) + MEDFILESAFECALLERWR0(MEDmeshEntityNumberWr,(fid,maa.c_str(),_iteration,_order,MED_CELL,geoTypeReq,_num_cells->getNumberOfTuples(),_num_cells->getConstPointer())); + if((const DataArrayInt *)_num_faces) + MEDFILESAFECALLERWR0(MEDmeshEntityNumberWr,(fid,maa.c_str(),_iteration,_order,MED_CELL,geoTypeReq2,_num_faces->getNumberOfTuples(),_num_faces->getConstPointer())); + if((const DataArrayInt *)_num_nodes) + MEDFILESAFECALLERWR0(MEDmeshEntityNumberWr,(fid,maa.c_str(),_iteration,_order,MED_NODE,MED_NONE,_num_nodes->getNumberOfTuples(),_num_nodes->getConstPointer())); + if((const DataArrayAsciiChar *)_names_cells) + { + if(_names_cells->getNumberOfComponents()!=MED_SNAME_SIZE) + { + std::ostringstream oss; oss << "MEDFileStructuredMesh::writeStructuredLL : expected a name field on cells with number of components set to " << MED_SNAME_SIZE; + oss << " ! The array has " << _names_cells->getNumberOfComponents() << " components !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + MEDFILESAFECALLERWR0(MEDmeshEntityNameWr,(fid,maa.c_str(),_iteration,_order,MED_CELL,geoTypeReq,_names_cells->getNumberOfTuples(),_names_cells->getConstPointer())); + } + if((const DataArrayAsciiChar *)_names_faces) + { + if(_names_faces->getNumberOfComponents()!=MED_SNAME_SIZE) + { + std::ostringstream oss; oss << "MEDFileStructuredMesh::writeStructuredLL : expected a name field on faces with number of components set to " << MED_SNAME_SIZE; + oss << " ! The array has " << _names_faces->getNumberOfComponents() << " components !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + MEDFILESAFECALLERWR0(MEDmeshEntityNameWr,(fid,maa.c_str(),_iteration,_order,MED_CELL,geoTypeReq2,_names_faces->getNumberOfTuples(),_names_faces->getConstPointer())); + } + if((const DataArrayAsciiChar *)_names_nodes) + { + if(_names_nodes->getNumberOfComponents()!=MED_SNAME_SIZE) + { + std::ostringstream oss; oss << "MEDFileStructuredMesh::writeStructuredLL : expected a name field on nodes with number of components set to " << MED_SNAME_SIZE; + oss << " ! The array has " << _names_cells->getNumberOfComponents() << " components !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + MEDFILESAFECALLERWR0(MEDmeshEntityNameWr,(fid,maa.c_str(),_iteration,_order,MED_NODE,MED_NONE,_names_nodes->getNumberOfTuples(),_names_nodes->getConstPointer())); + } + // + MEDFileUMeshL2::WriteFamiliesAndGrps(fid,maa.c_str(),_families,_groups,_too_long_str); +} + +/*! + * Returns an empty instance of MEDFileCMesh. + * \return MEDFileCMesh * - a new instance of MEDFileCMesh. The caller is to delete this + * mesh using decrRef() as it is no more needed. + */ +MEDFileCMesh *MEDFileCMesh::New() +{ + return new MEDFileCMesh; +} + +/*! + * Returns a new MEDFileCMesh holding the mesh data that has been read from a given MED + * file. The first mesh in the file is loaded. + * \param [in] fileName - the name of MED file to read. + * \return MEDFileCMesh * - a new instance of MEDFileCMesh. The caller is to delete this + * mesh using decrRef() as it is no more needed. + * \throw If the file is not readable. + * \throw If there is no meshes in the file. + * \throw If the mesh in the file is not a Cartesian one. + */ +MEDFileCMesh *MEDFileCMesh::New(const std::string& fileName, MEDFileMeshReadSelector *mrs) +{ + std::vector<std::string> ms=MEDLoader::GetMeshNames(fileName); + if(ms.empty()) + { + std::ostringstream oss; oss << "MEDFileUMesh::New : no meshes in file \"" << fileName << "\" !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + MEDFileUtilities::CheckFileForRead(fileName); + MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName.c_str(),MED_ACC_RDONLY); + int dt,it; + ParaMEDMEM::MEDCouplingMeshType meshType; + std::string dummy2; + MEDFileMeshL2::GetMeshIdFromName(fid,ms.front(),meshType,dt,it,dummy2); + return new MEDFileCMesh(fid,ms.front(),dt,it,mrs); +} + +/*! + * Returns a new MEDFileCMesh holding the mesh data that has been read from a given MED + * file. The mesh to load is specified by its name and numbers of a time step and an + * iteration. + * \param [in] fileName - the name of MED file to read. + * \param [in] mName - the name of the mesh to read. + * \param [in] dt - the number of a time step. + * \param [in] it - the number of an iteration. + * \return MEDFileCMesh * - a new instance of MEDFileCMesh. The caller is to delete this + * mesh using decrRef() as it is no more needed. + * \throw If the file is not readable. + * \throw If there is no mesh with given attributes in the file. + * \throw If the mesh in the file is not a Cartesian one. + */ +MEDFileCMesh *MEDFileCMesh::New(const std::string& fileName, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs) +{ + MEDFileUtilities::CheckFileForRead(fileName); + MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName.c_str(),MED_ACC_RDONLY); + return new MEDFileCMesh(fid,mName,dt,it,mrs); +} + +std::size_t MEDFileCMesh::getHeapMemorySizeWithoutChildren() const +{ + return MEDFileStructuredMesh::getHeapMemorySizeWithoutChildren(); +} + +std::vector<const BigMemoryObject *> MEDFileCMesh::getDirectChildrenWithNull() const +{ + std::vector<const BigMemoryObject *> ret(MEDFileStructuredMesh::getDirectChildrenWithNull()); + ret.push_back((const MEDCouplingCMesh *)_cmesh); + return ret; +} + +/*! + * Returns the dimension on cells in \a this mesh. + * \return int - the mesh dimension. + * \throw If there are no cells in this mesh. + */ +int MEDFileCMesh::getMeshDimension() const +{ + if(!((const MEDCouplingCMesh*)_cmesh)) + throw INTERP_KERNEL::Exception("MEDFileCMesh::getMeshDimension : unable to get meshdimension because no mesh set !"); + return _cmesh->getMeshDimension(); +} + +/*! + * Returns the dimension on nodes in \a this mesh. + * \return int - the space dimension. + * \throw If there are no cells in this mesh. + */ +int MEDFileCMesh::getSpaceDimension() const +{ + if(!((const MEDCouplingCMesh*)_cmesh)) + throw INTERP_KERNEL::Exception("MEDFileCMesh::getSpaceDimension : unable to get spacedimension because no mesh set !"); + return _cmesh->getSpaceDimension(); +} + +/*! + * Returns a string describing \a this mesh. + * \return std::string - the mesh information string. + */ +std::string MEDFileCMesh::simpleRepr() const +{ + return MEDFileStructuredMesh::simpleRepr(); +} + +/*! + * Returns a full textual description of \a this mesh. + * \return std::string - the string holding the mesh description. + */ +std::string MEDFileCMesh::advancedRepr() const +{ + return simpleRepr(); +} + +MEDFileMesh *MEDFileCMesh::shallowCpy() const +{ + MEDCouplingAutoRefCountObjectPtr<MEDFileCMesh> ret=new MEDFileCMesh(*this); + return ret.retn(); +} + +MEDFileMesh *MEDFileCMesh::createNewEmpty() const +{ + return new MEDFileCMesh; +} + +MEDFileMesh *MEDFileCMesh::deepCpy() const +{ + MEDCouplingAutoRefCountObjectPtr<MEDFileCMesh> ret=new MEDFileCMesh(*this); + if((const MEDCouplingCMesh*)_cmesh) + ret->_cmesh=static_cast<MEDCouplingCMesh*>(_cmesh->deepCpy()); + ret->deepCpyAttributes(); + return ret.retn(); +} + +/*! + * Checks if \a this and another mesh are equal. + * \param [in] other - the mesh to compare with. + * \param [in] eps - a precision used to compare real values. + * \param [in,out] what - the string returning description of unequal data. + * \return bool - \c true if the meshes are equal, \c false, else. + */ +bool MEDFileCMesh::isEqual(const MEDFileMesh *other, double eps, std::string& what) const +{ + if(!MEDFileStructuredMesh::isEqual(other,eps,what)) + return false; + const MEDFileCMesh *otherC=dynamic_cast<const MEDFileCMesh *>(other); + if(!otherC) + { + what="Mesh types differ ! This is cartesian and other is NOT !"; + return false; + } + clearNonDiscrAttributes(); + otherC->clearNonDiscrAttributes(); + const MEDCouplingCMesh *coo1=_cmesh; + const MEDCouplingCMesh *coo2=otherC->_cmesh; + if((coo1==0 && coo2!=0) || (coo1!=0 && coo2==0)) + { + what="Mismatch of cartesian meshes ! One is defined and not other !"; + return false; + } + if(coo1) + { + bool ret=coo1->isEqual(coo2,eps); + if(!ret) + { + what="cartesian meshes differ !"; + return false; + } + } + return true; +} + +/*! + * Clears redundant attributes of incorporated data arrays. + */ +void MEDFileCMesh::clearNonDiscrAttributes() const +{ + MEDFileStructuredMesh::clearNonDiscrAttributes(); + MEDFileUMeshSplitL1::ClearNonDiscrAttributes(_cmesh);//to it is not a bug umeshsplit have already the method implemented +} + +MEDFileCMesh::MEDFileCMesh() +{ +} + +MEDFileCMesh::MEDFileCMesh(med_idt fid, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs) +try +{ + loadCMeshFromFile(fid,mName,dt,it,mrs); + loadJointsFromFile(fid); +} +catch(INTERP_KERNEL::Exception& e) +{ + throw e; +} + +void MEDFileCMesh::loadCMeshFromFile(med_idt fid, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs) +{ + ParaMEDMEM::MEDCouplingMeshType meshType; + int dummy0,dummy1; + std::string dtunit; + int mid=MEDFileMeshL2::GetMeshIdFromName(fid,mName,meshType,dummy0,dummy1,dtunit); + if(meshType!=CARTESIAN) + { + std::ostringstream oss; oss << "Trying to load as cartesian an existing mesh with name '" << mName << "' that is NOT cartesian !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + MEDFileCMeshL2 loaderl2; + loaderl2.loadAll(fid,mid,mName,dt,it); + MEDCouplingCMesh *mesh=loaderl2.getMesh(); + mesh->incrRef(); + _cmesh=mesh; + loadStrMeshFromFile(&loaderl2,fid,mName,dt,it,mrs); +} + +/*! + * Returns a const pointer to MEDCouplingCMesh held by \a this mesh. + * \return const MEDCouplingCMesh * - a pointer to the held MEDCouplingCMesh. + */ +const MEDCouplingCMesh *MEDFileCMesh::getMesh() const +{ + synchronizeTinyInfoOnLeaves(); + return _cmesh; +} + +const MEDCouplingStructuredMesh *MEDFileCMesh::getStructuredMesh() const +{ + synchronizeTinyInfoOnLeaves(); + return _cmesh; +} + +/*! + * Sets the MEDCouplingCMesh holding the data of \a this mesh. + * \param [in] m - the new MEDCouplingCMesh to refer to. + * \throw If the name or the description of \a this mesh and \a m are not empty and are + * different. + */ +void MEDFileCMesh::setMesh(MEDCouplingCMesh *m) +{ + dealWithTinyInfo(m); + if(m) + m->incrRef(); + _cmesh=m; +} + +void MEDFileCMesh::writeLL(med_idt fid) const +{ + INTERP_KERNEL::AutoPtr<char> maa=MEDLoaderBase::buildEmptyString(MED_NAME_SIZE); + INTERP_KERNEL::AutoPtr<char> desc=MEDLoaderBase::buildEmptyString(MED_COMMENT_SIZE); + INTERP_KERNEL::AutoPtr<char> dtunit=MEDLoaderBase::buildEmptyString(MED_LNAME_SIZE); + MEDLoaderBase::safeStrCpy(_name.c_str(),MED_NAME_SIZE,maa,_too_long_str); + MEDLoaderBase::safeStrCpy(_desc_name.c_str(),MED_COMMENT_SIZE,desc,_too_long_str); + MEDLoaderBase::safeStrCpy(_dt_unit.c_str(),MED_LNAME_SIZE,dtunit,_too_long_str); + int spaceDim(_cmesh->getSpaceDimension()); + INTERP_KERNEL::AutoPtr<char> comp=MEDLoaderBase::buildEmptyString(spaceDim*MED_SNAME_SIZE); + INTERP_KERNEL::AutoPtr<char> unit=MEDLoaderBase::buildEmptyString(spaceDim*MED_SNAME_SIZE); + for(int i=0;i<spaceDim;i++) + { + std::string info(_cmesh->getCoordsAt(i)->getInfoOnComponent(0)); + std::string c,u; + MEDLoaderBase::splitIntoNameAndUnit(info,c,u); + MEDLoaderBase::safeStrCpy2(c.c_str(),MED_SNAME_SIZE-1,comp+i*MED_SNAME_SIZE,_too_long_str);//MED_TAILLE_PNOM-1 to avoid to write '\0' on next compo + MEDLoaderBase::safeStrCpy2(u.c_str(),MED_SNAME_SIZE-1,unit+i*MED_SNAME_SIZE,_too_long_str);//MED_TAILLE_PNOM-1 to avoid to write '\0' on next compo + } + MEDFILESAFECALLERWR0(MEDmeshCr,(fid,maa,spaceDim,spaceDim,MED_STRUCTURED_MESH,desc,dtunit,MED_SORT_DTIT,MED_CARTESIAN,comp,unit)); + if(_univ_wr_status) + MEDFILESAFECALLERWR0(MEDmeshUniversalNameWr,(fid,maa)); + MEDFILESAFECALLERWR0(MEDmeshGridTypeWr,(fid,maa,MED_CARTESIAN_GRID)); + for(int i=0;i<spaceDim;i++) + { + const DataArrayDouble *da=_cmesh->getCoordsAt(i); + MEDFILESAFECALLERWR0(MEDmeshGridIndexCoordinateWr,(fid,maa,_iteration,_order,_time,i+1,da->getNumberOfTuples(),da->getConstPointer())); + } + // + std::string meshName(MEDLoaderBase::buildStringFromFortran(maa,MED_NAME_SIZE)); + MEDFileStructuredMesh::writeStructuredLL(fid,meshName); + + writeJoints(fid); +} + +void MEDFileCMesh::synchronizeTinyInfoOnLeaves() const +{ + const MEDCouplingCMesh *cmesh=_cmesh; + if(!cmesh) + return; + (const_cast<MEDCouplingCMesh *>(cmesh))->setName(_name); + (const_cast<MEDCouplingCMesh *>(cmesh))->setDescription(_desc_name); + (const_cast<MEDCouplingCMesh *>(cmesh))->setTime(_time,_iteration,_order); + (const_cast<MEDCouplingCMesh *>(cmesh))->setTimeUnit(_dt_unit); +} + +MEDFileCurveLinearMesh *MEDFileCurveLinearMesh::New() +{ + return new MEDFileCurveLinearMesh; +} + +MEDFileCurveLinearMesh *MEDFileCurveLinearMesh::New(const std::string& fileName, MEDFileMeshReadSelector *mrs) +{ + std::vector<std::string> ms=MEDLoader::GetMeshNames(fileName); + if(ms.empty()) + { + std::ostringstream oss; oss << "MEDFileUMesh::New : no meshes in file \"" << fileName << "\" !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + MEDFileUtilities::CheckFileForRead(fileName); + MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName.c_str(),MED_ACC_RDONLY); + int dt,it; + ParaMEDMEM::MEDCouplingMeshType meshType; + std::string dummy2; + MEDFileMeshL2::GetMeshIdFromName(fid,ms.front(),meshType,dt,it,dummy2); + return new MEDFileCurveLinearMesh(fid,ms.front(),dt,it,mrs); +} + +MEDFileCurveLinearMesh *MEDFileCurveLinearMesh::New(const std::string& fileName, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs) +{ + MEDFileUtilities::CheckFileForRead(fileName); + MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName.c_str(),MED_ACC_RDONLY); + return new MEDFileCurveLinearMesh(fid,mName,dt,it,mrs); +} + +std::size_t MEDFileCurveLinearMesh::getHeapMemorySizeWithoutChildren() const +{ + return MEDFileStructuredMesh::getHeapMemorySizeWithoutChildren(); +} + +std::vector<const BigMemoryObject *> MEDFileCurveLinearMesh::getDirectChildrenWithNull() const +{ + std::vector<const BigMemoryObject *> ret(MEDFileStructuredMesh::getDirectChildrenWithNull()); + ret.push_back((const MEDCouplingCurveLinearMesh *)_clmesh); + return ret; +} + +MEDFileMesh *MEDFileCurveLinearMesh::shallowCpy() const +{ + MEDCouplingAutoRefCountObjectPtr<MEDFileCurveLinearMesh> ret=new MEDFileCurveLinearMesh(*this); + return ret.retn(); +} + +MEDFileMesh *MEDFileCurveLinearMesh::createNewEmpty() const +{ + return new MEDFileCurveLinearMesh; +} + +MEDFileMesh *MEDFileCurveLinearMesh::deepCpy() const +{ + MEDCouplingAutoRefCountObjectPtr<MEDFileCurveLinearMesh> ret=new MEDFileCurveLinearMesh(*this); + if((const MEDCouplingCurveLinearMesh*)_clmesh) + ret->_clmesh=static_cast<MEDCouplingCurveLinearMesh*>(_clmesh->deepCpy()); + ret->deepCpyAttributes(); + return ret.retn(); +} + +int MEDFileCurveLinearMesh::getMeshDimension() const +{ + if(!((const MEDCouplingCurveLinearMesh*)_clmesh)) + throw INTERP_KERNEL::Exception("MEDFileCurveLinearMesh::getMeshDimension : unable to get meshdimension because no mesh set !"); + return _clmesh->getMeshDimension(); +} + +std::string MEDFileCurveLinearMesh::simpleRepr() const +{ + return MEDFileStructuredMesh::simpleRepr(); +} + +std::string MEDFileCurveLinearMesh::advancedRepr() const +{ + return simpleRepr(); +} + +bool MEDFileCurveLinearMesh::isEqual(const MEDFileMesh *other, double eps, std::string& what) const +{ + if(!MEDFileStructuredMesh::isEqual(other,eps,what)) + return false; + const MEDFileCurveLinearMesh *otherC=dynamic_cast<const MEDFileCurveLinearMesh *>(other); + if(!otherC) + { + what="Mesh types differ ! This is curve linear and other is NOT !"; + return false; + } + clearNonDiscrAttributes(); + otherC->clearNonDiscrAttributes(); + const MEDCouplingCurveLinearMesh *coo1=_clmesh; + const MEDCouplingCurveLinearMesh *coo2=otherC->_clmesh; + if((coo1==0 && coo2!=0) || (coo1!=0 && coo2==0)) + { + what="Mismatch of curve linear meshes ! One is defined and not other !"; + return false; + } + if(coo1) + { + bool ret=coo1->isEqual(coo2,eps); + if(!ret) + { + what="curve linear meshes differ !"; + return false; + } + } + return true; +} + +void MEDFileCurveLinearMesh::clearNonDiscrAttributes() const +{ + MEDFileStructuredMesh::clearNonDiscrAttributes(); + MEDFileUMeshSplitL1::ClearNonDiscrAttributes(_clmesh);//to it is not a bug umeshsplit have already the method implemented +} + +void MEDFileCurveLinearMesh::synchronizeTinyInfoOnLeaves() const +{ + const MEDCouplingCurveLinearMesh *clmesh=_clmesh; + if(!clmesh) + return; + (const_cast<MEDCouplingCurveLinearMesh *>(clmesh))->setName(_name); + (const_cast<MEDCouplingCurveLinearMesh *>(clmesh))->setDescription(_desc_name); + (const_cast<MEDCouplingCurveLinearMesh *>(clmesh))->setTime(_time,_iteration,_order); + (const_cast<MEDCouplingCurveLinearMesh *>(clmesh))->setTimeUnit(_dt_unit); +} + +const MEDCouplingCurveLinearMesh *MEDFileCurveLinearMesh::getMesh() const +{ + synchronizeTinyInfoOnLeaves(); + return _clmesh; +} + +void MEDFileCurveLinearMesh::setMesh(MEDCouplingCurveLinearMesh *m) +{ + dealWithTinyInfo(m); + if(m) + m->incrRef(); + _clmesh=m; +} + +const MEDCouplingStructuredMesh *MEDFileCurveLinearMesh::getStructuredMesh() const +{ + synchronizeTinyInfoOnLeaves(); + return _clmesh; +} + +MEDFileCurveLinearMesh::MEDFileCurveLinearMesh() +{ +} + +MEDFileCurveLinearMesh::MEDFileCurveLinearMesh(med_idt fid, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs) +try +{ + loadCLMeshFromFile(fid,mName,dt,it,mrs); + loadJointsFromFile(fid); +} +catch(INTERP_KERNEL::Exception& e) +{ + throw e; +} + +void MEDFileCurveLinearMesh::writeLL(med_idt fid) const +{ + INTERP_KERNEL::AutoPtr<char> maa=MEDLoaderBase::buildEmptyString(MED_NAME_SIZE); + INTERP_KERNEL::AutoPtr<char> desc=MEDLoaderBase::buildEmptyString(MED_COMMENT_SIZE); + INTERP_KERNEL::AutoPtr<char> dtunit=MEDLoaderBase::buildEmptyString(MED_LNAME_SIZE); + MEDLoaderBase::safeStrCpy(_name.c_str(),MED_NAME_SIZE,maa,_too_long_str); + MEDLoaderBase::safeStrCpy(_desc_name.c_str(),MED_COMMENT_SIZE,desc,_too_long_str); + MEDLoaderBase::safeStrCpy(_dt_unit.c_str(),MED_LNAME_SIZE,dtunit,_too_long_str); + int spaceDim=_clmesh->getSpaceDimension(); + int meshDim=_clmesh->getMeshDimension(); + INTERP_KERNEL::AutoPtr<char> comp=MEDLoaderBase::buildEmptyString(spaceDim*MED_SNAME_SIZE); + INTERP_KERNEL::AutoPtr<char> unit=MEDLoaderBase::buildEmptyString(spaceDim*MED_SNAME_SIZE); + const DataArrayDouble *coords=_clmesh->getCoords(); + if(!coords) + throw INTERP_KERNEL::Exception("MEDFileCurveLinearMesh::writeLL : no coordinates set !"); + for(int i=0;i<spaceDim;i++) + { + std::string info(_clmesh->getCoords()->getInfoOnComponent(i)); + std::string c,u; + MEDLoaderBase::splitIntoNameAndUnit(info,c,u); + MEDLoaderBase::safeStrCpy2(c.c_str(),MED_SNAME_SIZE-1,comp+i*MED_SNAME_SIZE,_too_long_str);//MED_TAILLE_PNOM-1 to avoid to write '\0' on next compo + MEDLoaderBase::safeStrCpy2(u.c_str(),MED_SNAME_SIZE-1,unit+i*MED_SNAME_SIZE,_too_long_str);//MED_TAILLE_PNOM-1 to avoid to write '\0' on next compo + } + MEDFILESAFECALLERWR0(MEDmeshCr,(fid,maa,spaceDim,meshDim,MED_STRUCTURED_MESH,desc,dtunit,MED_SORT_DTIT,MED_CARTESIAN,comp,unit)); + if(_univ_wr_status) + MEDFILESAFECALLERWR0(MEDmeshUniversalNameWr,(fid,maa)); + MEDFILESAFECALLERWR0(MEDmeshGridTypeWr,(fid,maa,MED_CURVILINEAR_GRID)); + std::vector<int> nodeGridSt=_clmesh->getNodeGridStructure(); + MEDFILESAFECALLERWR0(MEDmeshGridStructWr,(fid,maa,_iteration,_order,_time,&nodeGridSt[0])); + + MEDFILESAFECALLERWR0(MEDmeshNodeCoordinateWr,(fid,maa,_iteration,_order,_time,MED_FULL_INTERLACE,coords->getNumberOfTuples(),coords->begin())); + // + std::string meshName(MEDLoaderBase::buildStringFromFortran(maa,MED_NAME_SIZE)); + MEDFileStructuredMesh::writeStructuredLL(fid,meshName); + + writeJoints(fid); +} + +void MEDFileCurveLinearMesh::loadCLMeshFromFile(med_idt fid, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs) +{ + ParaMEDMEM::MEDCouplingMeshType meshType; + int dummy0,dummy1; + std::string dtunit; + int mid=MEDFileMeshL2::GetMeshIdFromName(fid,mName,meshType,dummy0,dummy1,dtunit); + if(meshType!=CURVE_LINEAR) + { + std::ostringstream oss; oss << "Trying to load as curve linear an existing mesh with name '" << mName << "' that is NOT curve linear !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + MEDFileCLMeshL2 loaderl2; + loaderl2.loadAll(fid,mid,mName,dt,it); + MEDCouplingCurveLinearMesh *mesh=loaderl2.getMesh(); + mesh->incrRef(); + _clmesh=mesh; + loadStrMeshFromFile(&loaderl2,fid,mName,dt,it,mrs); +} + +MEDFileMeshMultiTS *MEDFileMeshMultiTS::New() +{ + return new MEDFileMeshMultiTS; +} + +MEDFileMeshMultiTS *MEDFileMeshMultiTS::New(const std::string& fileName) +{ + return new MEDFileMeshMultiTS(fileName); +} + +MEDFileMeshMultiTS *MEDFileMeshMultiTS::New(const std::string& fileName, const std::string& mName) +{ + return new MEDFileMeshMultiTS(fileName,mName); +} + +MEDFileMeshMultiTS *MEDFileMeshMultiTS::deepCpy() const +{ + MEDCouplingAutoRefCountObjectPtr<MEDFileMeshMultiTS> ret=MEDFileMeshMultiTS::New(); + std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileMesh> > meshOneTs(_mesh_one_ts.size()); + std::size_t i=0; + for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileMesh> >::const_iterator it=_mesh_one_ts.begin();it!=_mesh_one_ts.end();it++,i++) + if((const MEDFileMesh *)*it) + meshOneTs[i]=(*it)->deepCpy(); + ret->_mesh_one_ts=meshOneTs; + return ret.retn(); +} + +std::size_t MEDFileMeshMultiTS::getHeapMemorySizeWithoutChildren() const +{ + return _mesh_one_ts.capacity()*sizeof(MEDCouplingAutoRefCountObjectPtr<MEDFileMesh>); +} + +std::vector<const BigMemoryObject *> MEDFileMeshMultiTS::getDirectChildrenWithNull() const +{ + std::vector<const BigMemoryObject *> ret; + for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileMesh> >::const_iterator it=_mesh_one_ts.begin();it!=_mesh_one_ts.end();it++) + ret.push_back((const MEDFileMesh *)*it); + return ret; +} + +std::string MEDFileMeshMultiTS::getName() const +{ + if(_mesh_one_ts.empty()) + throw INTERP_KERNEL::Exception("MEDFileMeshMultiTS::getName : no time steps set !"); + return _mesh_one_ts[0]->getName(); +} + +void MEDFileMeshMultiTS::setName(const std::string& newMeshName) +{ + std::string oldName(getName()); + std::vector< std::pair<std::string,std::string> > v(1); + v[0].first=oldName; v[0].second=newMeshName; + changeNames(v); +} + +bool MEDFileMeshMultiTS::changeNames(const std::vector< std::pair<std::string,std::string> >& modifTab) +{ + bool ret=false; + for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileMesh> >::iterator it=_mesh_one_ts.begin();it!=_mesh_one_ts.end();it++) + { + MEDFileMesh *cur(*it); + if(cur) + ret=cur->changeNames(modifTab) || ret; + } + return ret; +} + +MEDFileMesh *MEDFileMeshMultiTS::getOneTimeStep() const +{ + if(_mesh_one_ts.empty()) + throw INTERP_KERNEL::Exception("MEDFileMeshMultiTS::getOneTimeStep : empty time step set !"); + return const_cast<MEDFileMesh *>(static_cast<const MEDFileMesh *>(_mesh_one_ts[0])); +} + +void MEDFileMeshMultiTS::setOneTimeStep(MEDFileMesh *mesh1TimeStep) +{ + if(!mesh1TimeStep) + throw INTERP_KERNEL::Exception("MEDFileMeshMultiTS::setOneTimeStep : input pointer should be different from 0 !"); + _mesh_one_ts.resize(1); + mesh1TimeStep->incrRef(); + //MEDCouplingAutoRefCountObjectPtr<MEDFileMesh> toto=mesh1TimeStep; + _mesh_one_ts[0]=mesh1TimeStep; +} + +MEDFileJoints * MEDFileMeshMultiTS::getJoints() const +{ + if ( MEDFileMesh* m = getOneTimeStep() ) + return m->getJoints(); + return 0; +} + +/*! + * \brief Set Joints that are common to all time-stamps + */ +void MEDFileMeshMultiTS::setJoints( MEDFileJoints* joints ) +{ + for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileMesh> >::iterator it=_mesh_one_ts.begin();it!=_mesh_one_ts.end();it++) + { + (*it)->setJoints( joints ); + } +} + +void MEDFileMeshMultiTS::write(med_idt fid) const +{ + MEDFileJoints *joints(getJoints()); + bool jointsWritten(false); + + for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileMesh> >::const_iterator it=_mesh_one_ts.begin();it!=_mesh_one_ts.end();it++) + { + if ( jointsWritten ) + const_cast<MEDFileMesh&>(**it).setJoints( 0 ); + else + jointsWritten = true; + + (*it)->copyOptionsFrom(*this); + (*it)->write(fid); + } + + (const_cast<MEDFileMeshMultiTS*>(this))->setJoints( joints ); // restore joints +} + +void MEDFileMeshMultiTS::write(const std::string& fileName, int mode) const +{ + med_access_mode medmod=MEDFileUtilities::TraduceWriteMode(mode); + MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName.c_str(),medmod); + std::ostringstream oss; oss << "MEDFileMesh : error on attempt to write in file : \"" << fileName << "\""; + MEDFileUtilities::CheckMEDCode(fid,fid,oss.str()); + write(fid); +} + +void MEDFileMeshMultiTS::loadFromFile(const std::string& fileName, const std::string& mName) +{ + MEDFileJoints* joints = 0; + if ( !_mesh_one_ts.empty() && getOneTimeStep() ) + { + // joints of mName already read, pass them to MEDFileMesh::New() to prevent repeated reading + joints = getOneTimeStep()->getJoints(); + } + + _mesh_one_ts.clear(); //for the moment to be improved + _mesh_one_ts.push_back( MEDFileMesh::New(fileName,mName,-1,-1,0, joints )); +} + +MEDFileMeshMultiTS::MEDFileMeshMultiTS() +{ +} + +MEDFileMeshMultiTS::MEDFileMeshMultiTS(const std::string& fileName) +try +{ + std::vector<std::string> ms=MEDLoader::GetMeshNames(fileName); + if(ms.empty()) + { + std::ostringstream oss; oss << "MEDFileUMesh::New : no meshes in file \"" << fileName << "\" !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + MEDFileUtilities::CheckFileForRead(fileName); + MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName.c_str(),MED_ACC_RDONLY); + int dt,it; + ParaMEDMEM::MEDCouplingMeshType meshType; + std::string dummy2; + MEDFileMeshL2::GetMeshIdFromName(fid,ms.front(),meshType,dt,it,dummy2); + loadFromFile(fileName,ms.front()); +} +catch(INTERP_KERNEL::Exception& e) +{ + throw e; +} + +MEDFileMeshMultiTS::MEDFileMeshMultiTS(const std::string& fileName, const std::string& mName) +try +{ + loadFromFile(fileName,mName); +} +catch(INTERP_KERNEL::Exception& e) +{ + throw e; +} + +MEDFileMeshes *MEDFileMeshes::New() +{ + return new MEDFileMeshes; +} + +MEDFileMeshes *MEDFileMeshes::New(const std::string& fileName) +{ + return new MEDFileMeshes(fileName); +} + +void MEDFileMeshes::write(med_idt fid) const +{ + checkCoherency(); + for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileMeshMultiTS> >::const_iterator it=_meshes.begin();it!=_meshes.end();it++) + { + (*it)->copyOptionsFrom(*this); + (*it)->write(fid); + } +} + +void MEDFileMeshes::write(const std::string& fileName, int mode) const +{ + med_access_mode medmod=MEDFileUtilities::TraduceWriteMode(mode); + MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName.c_str(),medmod); + std::ostringstream oss; oss << "MEDFileMesh : error on attempt to write in file : \"" << fileName << "\""; + MEDFileUtilities::CheckMEDCode(fid,fid,oss.str()); + checkCoherency(); + write(fid); +} + +int MEDFileMeshes::getNumberOfMeshes() const +{ + return _meshes.size(); +} + +MEDFileMeshesIterator *MEDFileMeshes::iterator() +{ + return new MEDFileMeshesIterator(this); +} + +/** Return a borrowed reference (caller is not responsible) */ +MEDFileMesh *MEDFileMeshes::getMeshAtPos(int i) const +{ + if(i<0 || i>=(int)_meshes.size()) + { + std::ostringstream oss; oss << "MEDFileMeshes::getMeshAtPos : invalid mesh id given in parameter ! Should be in [0;" << _meshes.size() << ") !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + return _meshes[i]->getOneTimeStep(); +} + +/** Return a borrowed reference (caller is not responsible) */ +MEDFileMesh *MEDFileMeshes::getMeshWithName(const std::string& mname) const +{ + std::vector<std::string> ms=getMeshesNames(); + std::vector<std::string>::iterator it=std::find(ms.begin(),ms.end(),mname); + if(it==ms.end()) + { + std::ostringstream oss; oss << "MEDFileMeshes::getMeshWithName : Mesh \"" << mname << "\" does not exist in this ! Existing are : "; + std::copy(ms.begin(),ms.end(),std::ostream_iterator<std::string>(oss," ")); + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + return getMeshAtPos((int)std::distance(ms.begin(),it)); +} + +std::vector<std::string> MEDFileMeshes::getMeshesNames() const +{ + std::vector<std::string> ret(_meshes.size()); + int i=0; + for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileMeshMultiTS> >::const_iterator it=_meshes.begin();it!=_meshes.end();it++,i++) + { + const MEDFileMeshMultiTS *f=(*it); + if(f) + { + ret[i]=f->getName(); + } + else + { + std::ostringstream oss; oss << "MEDFileMeshes::getMeshesNames : At rank #" << i << " mesh is not defined !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + } + return ret; +} +/*const MEDFileJoints* MEDFileMeshes::getJoints() const +{ + const MEDFileJoints *ret=_joints; + if(!ret) + { + std::ostringstream oss; oss << "MEDFileMeshes::getJoints : joints is not defined !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + return ret; +}*/ + +bool MEDFileMeshes::changeNames(const std::vector< std::pair<std::string,std::string> >& modifTab) +{ + bool ret=false; + for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileMeshMultiTS> >::iterator it=_meshes.begin();it!=_meshes.end();it++) + { + MEDFileMeshMultiTS *cur(*it); + if(cur) + ret=cur->changeNames(modifTab) || ret; + } + return ret; +} + +void MEDFileMeshes::resize(int newSize) +{ + _meshes.resize(newSize); +} + +void MEDFileMeshes::pushMesh(MEDFileMesh *mesh) +{ + if(!mesh) + throw INTERP_KERNEL::Exception("MEDFileMeshes::pushMesh : invalid input pointer ! should be different from 0 !"); + MEDFileMeshMultiTS *elt=MEDFileMeshMultiTS::New(); + elt->setOneTimeStep(mesh); + _meshes.push_back(elt); +} + +void MEDFileMeshes::setMeshAtPos(int i, MEDFileMesh *mesh) +{ + if(!mesh) + throw INTERP_KERNEL::Exception("MEDFileMeshes::setMeshAtPos : invalid input pointer ! should be different from 0 !"); + if(i>=(int)_meshes.size()) + _meshes.resize(i+1); + MEDFileMeshMultiTS *elt=MEDFileMeshMultiTS::New(); + elt->setOneTimeStep(mesh); + _meshes[i]=elt; +} + +void MEDFileMeshes::destroyMeshAtPos(int i) +{ + if(i<0 || i>=(int)_meshes.size()) + { + std::ostringstream oss; oss << "MEDFileMeshes::destroyMeshAtPos : Invalid given id in input (" << i << ") should be in [0," << _meshes.size() << ") !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + _meshes.erase(_meshes.begin()+i); +} + +void MEDFileMeshes::loadFromFile(const std::string& fileName) +{ + std::vector<std::string> ms=MEDLoader::GetMeshNames(fileName); + int i=0; + _meshes.resize(ms.size()); + for(std::vector<std::string>::const_iterator it=ms.begin();it!=ms.end();it++,i++) + _meshes[i]=MEDFileMeshMultiTS::New(fileName,(*it)); +} + +MEDFileMeshes::MEDFileMeshes() +{ +} + +MEDFileMeshes::MEDFileMeshes(const std::string& fileName) +try +{ + loadFromFile(fileName); +} +catch(INTERP_KERNEL::Exception& /*e*/) +{ +} + +MEDFileMeshes *MEDFileMeshes::deepCpy() const +{ + std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileMeshMultiTS> > meshes(_meshes.size()); + std::size_t i=0; + for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileMeshMultiTS> >::const_iterator it=_meshes.begin();it!=_meshes.end();it++,i++) + if((const MEDFileMeshMultiTS *)*it) + meshes[i]=(*it)->deepCpy(); + MEDCouplingAutoRefCountObjectPtr<MEDFileMeshes> ret=MEDFileMeshes::New(); + ret->_meshes=meshes; + return ret.retn(); +} + +std::size_t MEDFileMeshes::getHeapMemorySizeWithoutChildren() const +{ + return _meshes.capacity()*(sizeof(MEDCouplingAutoRefCountObjectPtr<MEDFileMeshMultiTS>)); +} + +std::vector<const BigMemoryObject *> MEDFileMeshes::getDirectChildrenWithNull() const +{ + std::vector<const BigMemoryObject *> ret; + for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileMeshMultiTS> >::const_iterator it=_meshes.begin();it!=_meshes.end();it++) + ret.push_back((const MEDFileMeshMultiTS *)*it); + return ret; +} + +std::string MEDFileMeshes::simpleRepr() const +{ + std::ostringstream oss; + oss << "(*****************)\n(* MEDFileMeshes *)\n(*****************)\n\n"; + simpleReprWithoutHeader(oss); + return oss.str(); +} + +void MEDFileMeshes::simpleReprWithoutHeader(std::ostream& oss) const +{ + int nbOfMeshes=getNumberOfMeshes(); + oss << "There are " << nbOfMeshes << " meshes with the following names : \n"; + std::vector<std::string> mns=getMeshesNames(); + for(int i=0;i<nbOfMeshes;i++) + oss << " - #" << i << " \"" << mns[i] << "\"\n"; +} + +void MEDFileMeshes::checkCoherency() const +{ + static const char MSG[]="MEDFileMeshes::checkCoherency : mesh at rank "; + int i=0; + std::set<std::string> s; + for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileMeshMultiTS> >::const_iterator it=_meshes.begin();it!=_meshes.end();it++,i++) + { + const MEDFileMeshMultiTS *elt=(*it); + if(!elt) + { + std::ostringstream oss; oss << MSG << i << "/" << _meshes.size() << " is empty !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + std::size_t sz=s.size(); + s.insert(std::string((*it)->getName())); + if(s.size()==sz) + { + std::ostringstream oss; oss << MSG << i << " has a name (\"" << (*it)->getName() << "\") already used by an another mesh in list !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + } +} + +MEDFileMeshesIterator::MEDFileMeshesIterator(MEDFileMeshes *ms):_ms(ms),_iter_id(0),_nb_iter(0) +{ + if(ms) + { + ms->incrRef(); + _nb_iter=ms->getNumberOfMeshes(); + } +} + +MEDFileMeshesIterator::~MEDFileMeshesIterator() +{ +} + +MEDFileMesh *MEDFileMeshesIterator::nextt() +{ + if(_iter_id<_nb_iter) + { + MEDFileMeshes *ms(_ms); + if(ms) + return ms->getMeshAtPos(_iter_id++); + else + return 0; + } + else + return 0; +} diff --git a/src/medtool/src/MEDLoader/MEDFileMesh.hxx b/src/medtool/src/MEDLoader/MEDFileMesh.hxx new file mode 100644 index 000000000..87ffb429a --- /dev/null +++ b/src/medtool/src/MEDLoader/MEDFileMesh.hxx @@ -0,0 +1,548 @@ +// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 +// 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 __MEDFILEMESH_HXX__ +#define __MEDFILEMESH_HXX__ + +#include "MEDLoaderDefines.hxx" +#include "MEDFileMeshLL.hxx" +#include "MEDFileUtilities.hxx" +#include "MEDCouplingPartDefinition.hxx" +#include "MEDFileMeshReadSelector.hxx" +#include "MEDFileJoint.hxx" + +#include <map> +#include <list> + +namespace ParaMEDMEM +{ + class MEDFileFieldGlobsReal; + class MEDFileField1TSStructItem; + + class MEDFileMesh : public RefCountObject, public MEDFileWritable + { + public: + MEDLOADER_EXPORT static MEDFileMesh *New(const std::string& fileName, MEDFileMeshReadSelector *mrs=0); + MEDLOADER_EXPORT static MEDFileMesh *New(const std::string& fileName, const std::string& mName, int dt=-1, int it=-1, MEDFileMeshReadSelector *mrs=0, MEDFileJoints* joints=0); + MEDLOADER_EXPORT std::size_t getHeapMemorySizeWithoutChildren() const; + MEDLOADER_EXPORT std::vector<const BigMemoryObject *> getDirectChildrenWithNull() const; + MEDLOADER_EXPORT virtual MEDFileMesh *createNewEmpty() const = 0; + MEDLOADER_EXPORT virtual MEDFileMesh *deepCpy() const = 0; + MEDLOADER_EXPORT virtual MEDFileMesh *shallowCpy() const = 0; + MEDLOADER_EXPORT virtual bool isEqual(const MEDFileMesh *other, double eps, std::string& what) const; + MEDLOADER_EXPORT virtual void clearNonDiscrAttributes() const; + MEDLOADER_EXPORT virtual void setName(const std::string& name); + MEDLOADER_EXPORT bool changeNames(const std::vector< std::pair<std::string,std::string> >& modifTab); + MEDLOADER_EXPORT std::string getName() const { return _name; } + MEDLOADER_EXPORT std::string getUnivName() const { return _univ_name; } + MEDLOADER_EXPORT bool getUnivNameWrStatus() const { return _univ_wr_status; } + MEDLOADER_EXPORT void setUnivNameWrStatus(bool newStatus) { _univ_wr_status=newStatus; } + MEDLOADER_EXPORT void setDescription(const std::string& name) { _desc_name=name; } + MEDLOADER_EXPORT std::string getDescription() const { return _desc_name; } + MEDLOADER_EXPORT void setOrder(int order) { _order=order; } + MEDLOADER_EXPORT int getOrder() const { return _order; } + MEDLOADER_EXPORT void setIteration(int it) { _iteration=it; } + MEDLOADER_EXPORT int getIteration() const { return _iteration; } + MEDLOADER_EXPORT void setTimeValue(double time) { _time=time; } + MEDLOADER_EXPORT void setTime(int dt, int it, double time) { _time=time; _iteration=dt; _order=it; } + MEDLOADER_EXPORT double getTime(int& dt, int& it) { dt=_iteration; it=_order; return _time; } + MEDLOADER_EXPORT double getTimeValue() const { return _time; } + MEDLOADER_EXPORT void setTimeUnit(const std::string& unit) { _dt_unit=unit; } + MEDLOADER_EXPORT std::string getTimeUnit() const { return _dt_unit; } + MEDLOADER_EXPORT std::vector<INTERP_KERNEL::NormalizedCellType> getAllGeoTypes() const; + MEDLOADER_EXPORT virtual int getNumberOfNodes() const = 0; + MEDLOADER_EXPORT virtual int getNumberOfCellsAtLevel(int meshDimRelToMaxExt) const = 0; + MEDLOADER_EXPORT virtual bool hasImplicitPart() const = 0; + MEDLOADER_EXPORT virtual int buildImplicitPartIfAny(INTERP_KERNEL::NormalizedCellType gt) const = 0; + MEDLOADER_EXPORT virtual void releaseImplicitPartIfAny() const = 0; + MEDLOADER_EXPORT virtual std::vector<INTERP_KERNEL::NormalizedCellType> getGeoTypesAtLevel(int meshDimRelToMax) const = 0; + MEDLOADER_EXPORT virtual std::vector<int> getNonEmptyLevels() const = 0; + MEDLOADER_EXPORT virtual std::vector<int> getNonEmptyLevelsExt() const = 0; + MEDLOADER_EXPORT virtual std::vector<int> getFamArrNonEmptyLevelsExt() const = 0; + MEDLOADER_EXPORT virtual std::vector<int> getNumArrNonEmptyLevelsExt() const = 0; + MEDLOADER_EXPORT virtual std::vector<int> getNameArrNonEmptyLevelsExt() const = 0; + MEDLOADER_EXPORT virtual void write(const std::string& fileName, int mode) const; + MEDLOADER_EXPORT virtual void write(med_idt fid) const; + MEDLOADER_EXPORT virtual int getSizeAtLevel(int meshDimRelToMaxExt) const = 0; + MEDLOADER_EXPORT virtual MEDCouplingMesh *getGenMeshAtLevel(int meshDimRelToMax, bool renum=false) const = 0; + MEDLOADER_EXPORT virtual std::vector<int> getDistributionOfTypes(int meshDimRelToMax) const; + MEDLOADER_EXPORT virtual void whichAreNodesFetched(const MEDFileField1TSStructItem& st, const MEDFileFieldGlobsReal *globs, std::vector<bool>& nodesFetched) const = 0; + // + MEDLOADER_EXPORT bool areFamsEqual(const MEDFileMesh *other, std::string& what) const; + MEDLOADER_EXPORT bool areGrpsEqual(const MEDFileMesh *other, std::string& what) const; + MEDLOADER_EXPORT bool existsGroup(const std::string& groupName) const; + MEDLOADER_EXPORT bool existsFamily(int famId) const; + MEDLOADER_EXPORT bool existsFamily(const std::string& familyName) const; + MEDLOADER_EXPORT void setFamilyId(const std::string& familyName, int id); + MEDLOADER_EXPORT void setFamilyIdUnique(const std::string& familyName, int id); + MEDLOADER_EXPORT virtual void addFamily(const std::string& familyName, int id); + MEDLOADER_EXPORT virtual void createGroupOnAll(int meshDimRelToMaxExt, const std::string& groupName); + MEDLOADER_EXPORT virtual bool keepFamIdsOnlyOnLevs(const std::vector<int>& famIds, const std::vector<int>& levs); + MEDLOADER_EXPORT void addFamilyOnGrp(const std::string& grpName, const std::string& famName); + MEDLOADER_EXPORT std::string findOrCreateAndGiveFamilyWithId(int id, bool& created); + MEDLOADER_EXPORT void setFamilyInfo(const std::map<std::string,int>& info); + MEDLOADER_EXPORT void setGroupInfo(const std::map<std::string, std::vector<std::string> >&info); + MEDLOADER_EXPORT void copyFamGrpMapsFrom(const MEDFileMesh& other); + MEDLOADER_EXPORT void clearGrpMap(); + MEDLOADER_EXPORT void clearFamMap(); + MEDLOADER_EXPORT void clearFamGrpMaps(); + MEDLOADER_EXPORT const std::map<std::string,int>& getFamilyInfo() const { return _families; } + MEDLOADER_EXPORT const std::map<std::string, std::vector<std::string> >& getGroupInfo() const { return _groups; } + MEDLOADER_EXPORT std::vector<std::string> getFamiliesOnGroup(const std::string& name) const; + MEDLOADER_EXPORT std::vector<std::string> getFamiliesOnGroups(const std::vector<std::string>& grps) const; + MEDLOADER_EXPORT std::vector<int> getFamiliesIdsOnGroup(const std::string& name) const; + MEDLOADER_EXPORT void setFamiliesOnGroup(const std::string& name, const std::vector<std::string>& fams); + MEDLOADER_EXPORT void setFamiliesIdsOnGroup(const std::string& name, const std::vector<int>& famIds); + MEDLOADER_EXPORT std::vector<std::string> getGroupsOnFamily(const std::string& name) const; + MEDLOADER_EXPORT void setGroupsOnFamily(const std::string& famName, const std::vector<std::string>& grps); + MEDLOADER_EXPORT std::vector<std::string> getGroupsNames() const; + MEDLOADER_EXPORT std::vector<std::string> getFamiliesNames() const; + MEDLOADER_EXPORT void assignFamilyNameWithGroupName(); + MEDLOADER_EXPORT std::vector<std::string> removeEmptyGroups(); + MEDLOADER_EXPORT void removeGroup(const std::string& name); + MEDLOADER_EXPORT void removeFamily(const std::string& name); + MEDLOADER_EXPORT std::vector<std::string> removeOrphanGroups(); + MEDLOADER_EXPORT std::vector<std::string> removeOrphanFamilies(); + MEDLOADER_EXPORT void removeFamiliesReferedByNoGroups(); + MEDLOADER_EXPORT void rearrangeFamilies(); + MEDLOADER_EXPORT void checkOrphanFamilyZero() const; + MEDLOADER_EXPORT void changeGroupName(const std::string& oldName, const std::string& newName); + MEDLOADER_EXPORT void changeFamilyName(const std::string& oldName, const std::string& newName); + MEDLOADER_EXPORT void changeFamilyId(int oldId, int newId); + MEDLOADER_EXPORT void changeAllGroupsContainingFamily(const std::string& familyNameToChange, const std::vector<std::string>& newFamiliesNames); + MEDLOADER_EXPORT int getFamilyId(const std::string& name) const; + MEDLOADER_EXPORT int getMaxAbsFamilyId() const; + MEDLOADER_EXPORT int getMaxFamilyId() const; + MEDLOADER_EXPORT int getMinFamilyId() const; + MEDLOADER_EXPORT int getTheMaxAbsFamilyId() const; + MEDLOADER_EXPORT int getTheMaxFamilyId() const; + MEDLOADER_EXPORT int getTheMinFamilyId() const; + MEDLOADER_EXPORT virtual int getMaxAbsFamilyIdInArrays() const = 0; + MEDLOADER_EXPORT virtual int getMaxFamilyIdInArrays() const = 0; + MEDLOADER_EXPORT virtual int getMinFamilyIdInArrays() const = 0; + MEDLOADER_EXPORT DataArrayInt *getAllFamiliesIdsReferenced() const; + MEDLOADER_EXPORT DataArrayInt *computeAllFamilyIdsInUse() const; + MEDLOADER_EXPORT std::vector<int> getFamiliesIds(const std::vector<std::string>& famNames) const; + MEDLOADER_EXPORT std::string getFamilyNameGivenId(int id) const; + MEDLOADER_EXPORT bool ensureDifferentFamIdsPerLevel(); + MEDLOADER_EXPORT void normalizeFamIdsTrio(); + MEDLOADER_EXPORT void normalizeFamIdsMEDFile(); + MEDLOADER_EXPORT virtual int getMeshDimension() const = 0; + MEDLOADER_EXPORT virtual std::string simpleRepr() const; + MEDLOADER_EXPORT virtual std::string advancedRepr() const = 0; + // + MEDLOADER_EXPORT virtual void setGroupsAtLevel(int meshDimRelToMaxExt, const std::vector<const DataArrayInt *>& grps, bool renum=false); + MEDLOADER_EXPORT virtual void setFamilyFieldArr(int meshDimRelToMaxExt, DataArrayInt *famArr) = 0; + MEDLOADER_EXPORT virtual void setRenumFieldArr(int meshDimRelToMaxExt, DataArrayInt *renumArr) = 0; + MEDLOADER_EXPORT virtual void setNameFieldAtLevel(int meshDimRelToMaxExt, DataArrayAsciiChar *nameArr) = 0; + MEDLOADER_EXPORT virtual void addNodeGroup(const DataArrayInt *ids) = 0; + MEDLOADER_EXPORT virtual void addGroup(int meshDimRelToMaxExt, const DataArrayInt *ids) = 0; + MEDLOADER_EXPORT virtual const DataArrayInt *getFamilyFieldAtLevel(int meshDimRelToMaxExt) const = 0; + MEDLOADER_EXPORT virtual DataArrayInt *getFamilyFieldAtLevel(int meshDimRelToMaxExt) = 0; + MEDLOADER_EXPORT DataArrayInt *getOrCreateAndGetFamilyFieldAtLevel(int meshDimRelToMaxExt); + MEDLOADER_EXPORT virtual const DataArrayInt *getNumberFieldAtLevel(int meshDimRelToMaxExt) const = 0; + MEDLOADER_EXPORT virtual const DataArrayInt *getRevNumberFieldAtLevel(int meshDimRelToMaxExt) const = 0; + MEDLOADER_EXPORT virtual const DataArrayAsciiChar *getNameFieldAtLevel(int meshDimRelToMaxExt) const = 0; + MEDLOADER_EXPORT virtual DataArrayInt *getFamiliesArr(int meshDimRelToMaxExt, const std::vector<std::string>& fams, bool renum=false) const = 0; + MEDLOADER_EXPORT virtual DataArrayInt *getGroupsArr(int meshDimRelToMaxExt, const std::vector<std::string>& grps, bool renum=false) const; + MEDLOADER_EXPORT virtual DataArrayInt *getGroupArr(int meshDimRelToMaxExt, const std::string& grp, bool renum=false) const; + MEDLOADER_EXPORT virtual DataArrayInt *getFamilyArr(int meshDimRelToMaxExt, const std::string& fam, bool renum=false) const; + MEDLOADER_EXPORT virtual DataArrayInt *getNodeGroupArr(const std::string& grp, bool renum=false) const; + MEDLOADER_EXPORT virtual DataArrayInt *getNodeGroupsArr(const std::vector<std::string>& grps, bool renum=false) const; + MEDLOADER_EXPORT virtual DataArrayInt *getNodeFamilyArr(const std::string& fam, bool renum=false) const; + MEDLOADER_EXPORT virtual DataArrayInt *getNodeFamiliesArr(const std::vector<std::string>& fams, bool renum=false) const; + // tools + MEDLOADER_EXPORT virtual bool unPolyze(std::vector<int>& oldCode, std::vector<int>& newCode, DataArrayInt *& o2nRenumCell) = 0; + MEDLOADER_EXPORT int getNumberOfJoints(); + MEDLOADER_EXPORT MEDFileJoints *getJoints() const; + MEDLOADER_EXPORT void setJoints( MEDFileJoints* joints ); + protected: + MEDFileMesh(); + //! protected because no way in MED file API to specify this name + void setUnivName(const std::string& name) { _univ_name=name; } + void addFamilyOnAllGroupsHaving(const std::string& famName, const std::string& otherFamName); + virtual void writeLL(med_idt fid) const = 0; + void dealWithTinyInfo(const MEDCouplingMesh *m); + virtual void synchronizeTinyInfoOnLeaves() const = 0; + void getFamilyRepr(std::ostream& oss) const; + virtual void appendFamilyEntries(const DataArrayInt *famIds, const std::vector< std::vector<int> >& fidsOfGrps, const std::vector<std::string>& grpNames); + virtual void changeFamilyIdArr(int oldId, int newId) = 0; + virtual std::list< MEDCouplingAutoRefCountObjectPtr<DataArrayInt> > getAllNonNullFamilyIds() const = 0; + void addGroupUnderground(bool isNodeGroup, const DataArrayInt *ids, DataArrayInt *famArr); + static void TranslateFamilyIds(int offset, DataArrayInt *famArr, std::vector< std::vector<int> >& famIdsPerGrp); + static void ChangeAllGroupsContainingFamily(std::map<std::string, std::vector<std::string> >& groups, const std::string& familyNameToChange, const std::vector<std::string>& newFamiliesNames); + static std::string FindOrCreateAndGiveFamilyWithId(std::map<std::string,int>& families, int id, bool& created); + static std::string CreateNameNotIn(const std::string& nameTry, const std::vector<std::string>& namesToAvoid); + static int PutInThirdComponentOfCodeOffset(std::vector<int>& code, int strt); + void writeJoints(med_idt fid) const; + void loadJointsFromFile(med_idt fid, MEDFileJoints* toUseInstedOfReading=0); + protected: + int _order; + int _iteration; + double _time; + std::string _dt_unit; + std::string _name; + //! this attribute do not impact the state of instance -> mutable + mutable std::string _univ_name; + bool _univ_wr_status; + std::string _desc_name; + MEDCouplingAutoRefCountObjectPtr<MEDFileJoints> _joints; + protected: + std::map<std::string, std::vector<std::string> > _groups; + std::map<std::string,int> _families; + public: + MEDLOADER_EXPORT static const char DFT_FAM_NAME[]; + }; + + class MEDFileUMesh : public MEDFileMesh + { + friend class MEDFileMesh; + public: + MEDLOADER_EXPORT static MEDFileUMesh *New(const std::string& fileName, const std::string& mName, int dt=-1, int it=-1, MEDFileMeshReadSelector *mrs=0); + MEDLOADER_EXPORT static MEDFileUMesh *New(const std::string& fileName, MEDFileMeshReadSelector *mrs=0); + MEDLOADER_EXPORT static MEDFileUMesh *New(); + MEDLOADER_EXPORT static MEDFileUMesh *LoadPartOf(const std::string& fileName, const std::string& mName, const std::vector<INTERP_KERNEL::NormalizedCellType>& types, const std::vector<int>& slicPerTyp, int dt=-1, int it=-1, MEDFileMeshReadSelector *mrs=0); + MEDLOADER_EXPORT static MEDFileUMesh *LoadPartOf(med_idt fid, const std::string& mName, const std::vector<INTERP_KERNEL::NormalizedCellType>& types, const std::vector<int>& slicPerTyp, int dt=-1, int it=-1, MEDFileMeshReadSelector *mrs=0); + MEDLOADER_EXPORT std::size_t getHeapMemorySizeWithoutChildren() const; + MEDLOADER_EXPORT std::vector<const BigMemoryObject *> getDirectChildrenWithNull() const; + MEDLOADER_EXPORT MEDFileMesh *createNewEmpty() const; + MEDLOADER_EXPORT MEDFileMesh *deepCpy() const; + MEDLOADER_EXPORT MEDFileMesh *shallowCpy() const; + MEDLOADER_EXPORT bool isEqual(const MEDFileMesh *other, double eps, std::string& what) const; + MEDLOADER_EXPORT void clearNonDiscrAttributes() const; + MEDLOADER_EXPORT void setName(const std::string& name); + // + MEDLOADER_EXPORT int getMaxAbsFamilyIdInArrays() const; + MEDLOADER_EXPORT int getMaxFamilyIdInArrays() const; + MEDLOADER_EXPORT int getMinFamilyIdInArrays() const; + MEDLOADER_EXPORT int getMeshDimension() const; + MEDLOADER_EXPORT int getSpaceDimension() const; + MEDLOADER_EXPORT std::string simpleRepr() const; + MEDLOADER_EXPORT std::string advancedRepr() const; + MEDLOADER_EXPORT int getSizeAtLevel(int meshDimRelToMaxExt) const; + MEDLOADER_EXPORT const DataArrayInt *getFamilyFieldAtLevel(int meshDimRelToMaxExt) const; + MEDLOADER_EXPORT DataArrayInt *getFamilyFieldAtLevel(int meshDimRelToMaxExt); + MEDLOADER_EXPORT const DataArrayInt *getNumberFieldAtLevel(int meshDimRelToMaxExt) const; + MEDLOADER_EXPORT const DataArrayInt *getRevNumberFieldAtLevel(int meshDimRelToMaxExt) const; + MEDLOADER_EXPORT const DataArrayAsciiChar *getNameFieldAtLevel(int meshDimRelToMaxExt) const; + MEDLOADER_EXPORT const PartDefinition *getPartDefAtLevel(int meshDimRelToMaxExt, INTERP_KERNEL::NormalizedCellType gt=INTERP_KERNEL::NORM_ERROR) const; + MEDLOADER_EXPORT int getNumberOfNodes() const; + MEDLOADER_EXPORT int getNumberOfCellsAtLevel(int meshDimRelToMaxExt) const; + MEDLOADER_EXPORT bool hasImplicitPart() const; + MEDLOADER_EXPORT int buildImplicitPartIfAny(INTERP_KERNEL::NormalizedCellType gt) const; + MEDLOADER_EXPORT void releaseImplicitPartIfAny() const; + MEDLOADER_EXPORT std::vector<INTERP_KERNEL::NormalizedCellType> getGeoTypesAtLevel(int meshDimRelToMax) const; + MEDLOADER_EXPORT void whichAreNodesFetched(const MEDFileField1TSStructItem& st, const MEDFileFieldGlobsReal *globs, std::vector<bool>& nodesFetched) const; + MEDLOADER_EXPORT std::vector<int> getNonEmptyLevels() const; + MEDLOADER_EXPORT std::vector<int> getNonEmptyLevelsExt() const; + MEDLOADER_EXPORT std::vector<int> getFamArrNonEmptyLevelsExt() const; + MEDLOADER_EXPORT std::vector<int> getNumArrNonEmptyLevelsExt() const; + MEDLOADER_EXPORT std::vector<int> getNameArrNonEmptyLevelsExt() const; + MEDLOADER_EXPORT std::vector<int> getGrpNonEmptyLevels(const std::string& grp) const; + MEDLOADER_EXPORT std::vector<int> getGrpNonEmptyLevelsExt(const std::string& grp) const; + MEDLOADER_EXPORT std::vector<int> getFamNonEmptyLevels(const std::string& fam) const; + MEDLOADER_EXPORT std::vector<int> getFamNonEmptyLevelsExt(const std::string& fam) const; + MEDLOADER_EXPORT std::vector<int> getGrpsNonEmptyLevels(const std::vector<std::string>& grps) const; + MEDLOADER_EXPORT std::vector<int> getGrpsNonEmptyLevelsExt(const std::vector<std::string>& grps) const; + MEDLOADER_EXPORT std::vector<int> getFamsNonEmptyLevels(const std::vector<std::string>& fams) const; + MEDLOADER_EXPORT std::vector<int> getFamsNonEmptyLevelsExt(const std::vector<std::string>& fams) const; + MEDLOADER_EXPORT std::vector<std::string> getGroupsOnSpecifiedLev(int meshDimRelToMaxExt) const; + MEDLOADER_EXPORT DataArrayDouble *getCoords() const; + MEDLOADER_EXPORT MEDCouplingUMesh *getGroup(int meshDimRelToMaxExt, const std::string& grp, bool renum=false) const; + MEDLOADER_EXPORT MEDCouplingUMesh *getGroups(int meshDimRelToMaxExt, const std::vector<std::string>& grps, bool renum=false) const; + MEDLOADER_EXPORT MEDCouplingUMesh *getFamily(int meshDimRelToMaxExt, const std::string& fam, bool renum=false) const; + MEDLOADER_EXPORT MEDCouplingUMesh *getFamilies(int meshDimRelToMaxExt, const std::vector<std::string>& fams, bool renum=false) const; + MEDLOADER_EXPORT DataArrayInt *getFamiliesArr(int meshDimRelToMaxExt, const std::vector<std::string>& fams, bool renum=false) const; + MEDLOADER_EXPORT MEDCouplingUMesh *getMeshAtLevel(int meshDimRelToMaxExt, bool renum=false) const; + MEDLOADER_EXPORT MEDCouplingMesh *getGenMeshAtLevel(int meshDimRelToMax, bool renum=false) const; + MEDLOADER_EXPORT std::vector<int> getDistributionOfTypes(int meshDimRelToMax) const; + MEDLOADER_EXPORT MEDCouplingUMesh *getLevel0Mesh(bool renum=false) const; + MEDLOADER_EXPORT MEDCouplingUMesh *getLevelM1Mesh(bool renum=false) const; + MEDLOADER_EXPORT MEDCouplingUMesh *getLevelM2Mesh(bool renum=false) const; + MEDLOADER_EXPORT MEDCouplingUMesh *getLevelM3Mesh(bool renum=false) const; + MEDLOADER_EXPORT void forceComputationOfParts() const; + MEDLOADER_EXPORT std::vector<MEDCoupling1GTUMesh *> getDirectUndergroundSingleGeoTypeMeshes(int meshDimRelToMax) const; + MEDLOADER_EXPORT MEDCoupling1GTUMesh *getDirectUndergroundSingleGeoTypeMesh(INTERP_KERNEL::NormalizedCellType gt) const; + MEDLOADER_EXPORT DataArrayInt *extractFamilyFieldOnGeoType(INTERP_KERNEL::NormalizedCellType gt) const; + MEDLOADER_EXPORT DataArrayInt *extractNumberFieldOnGeoType(INTERP_KERNEL::NormalizedCellType gt) const; + MEDLOADER_EXPORT int getRelativeLevOnGeoType(INTERP_KERNEL::NormalizedCellType gt) const; + // + MEDLOADER_EXPORT void setFamilyNameAttachedOnId(int id, const std::string& newFamName); + MEDLOADER_EXPORT void setCoords(DataArrayDouble *coords); + MEDLOADER_EXPORT void eraseGroupsAtLevel(int meshDimRelToMaxExt); + MEDLOADER_EXPORT void setFamilyFieldArr(int meshDimRelToMaxExt, DataArrayInt *famArr); + MEDLOADER_EXPORT void setRenumFieldArr(int meshDimRelToMaxExt, DataArrayInt *renumArr); + MEDLOADER_EXPORT void setNameFieldAtLevel(int meshDimRelToMaxExt, DataArrayAsciiChar *nameArr); + MEDLOADER_EXPORT void addNodeGroup(const DataArrayInt *ids); + MEDLOADER_EXPORT void addGroup(int meshDimRelToMaxExt, const DataArrayInt *ids); + MEDLOADER_EXPORT void removeMeshAtLevel(int meshDimRelToMax); + MEDLOADER_EXPORT void setMeshAtLevel(int meshDimRelToMax, MEDCoupling1GTUMesh *m); + MEDLOADER_EXPORT void setMeshAtLevel(int meshDimRelToMax, MEDCouplingUMesh *m, bool newOrOld=false); + MEDLOADER_EXPORT void setMeshes(const std::vector<const MEDCouplingUMesh *>& ms, bool renum=false); + MEDLOADER_EXPORT void setGroupsFromScratch(int meshDimRelToMax, const std::vector<const MEDCouplingUMesh *>& ms, bool renum=false); + MEDLOADER_EXPORT void setGroupsOnSetMesh(int meshDimRelToMax, const std::vector<const MEDCouplingUMesh *>& ms, bool renum=false); + MEDLOADER_EXPORT void optimizeFamilies(); + // tools + MEDLOADER_EXPORT void buildInnerBoundaryAlongM1Group(const std::string& grpNameM1, DataArrayInt *&nodesDuplicated, DataArrayInt *&cellsModified, DataArrayInt *&cellsNotModified); + MEDLOADER_EXPORT bool unPolyze(std::vector<int>& oldCode, std::vector<int>& newCode, DataArrayInt *& o2nRenumCell); + MEDLOADER_EXPORT DataArrayInt *zipCoords(); + MEDLOADER_EXPORT MEDFileUMesh *buildExtrudedMesh(const MEDCouplingUMesh *m1D, int policy) const; + MEDLOADER_EXPORT MEDFileUMesh *linearToQuadratic(int conversionType=0, double eps=1e-12) const; + MEDLOADER_EXPORT MEDFileUMesh *quadraticToLinear(double eps=1e-12) const; + // serialization + MEDLOADER_EXPORT void serialize(std::vector<double>& tinyDouble, std::vector<int>& tinyInt, std::vector<std::string>& tinyStr, + std::vector< MEDCouplingAutoRefCountObjectPtr<DataArrayInt> >& bigArraysI, MEDCouplingAutoRefCountObjectPtr<DataArrayDouble>& bigArrayD); + MEDLOADER_EXPORT void unserialize(std::vector<double>& tinyDouble, std::vector<int>& tinyInt, std::vector<std::string>& tinyStr, + std::vector< MEDCouplingAutoRefCountObjectPtr<DataArrayInt> >& bigArraysI, MEDCouplingAutoRefCountObjectPtr<DataArrayDouble>& bigArrayD); + private: + MEDLOADER_EXPORT ~MEDFileUMesh(); + void writeLL(med_idt fid) const; + MEDFileUMesh(); + MEDFileUMesh(med_idt fid, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs); + void loadPartUMeshFromFile(med_idt fid, const std::string& mName, const std::vector<INTERP_KERNEL::NormalizedCellType>& types, const std::vector<int>& slicPerTyp, int dt=-1, int it=-1, MEDFileMeshReadSelector *mrs=0); + void loadUMeshFromFile(med_idt fid, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs); + void dispatchLoadedPart(med_idt fid, const MEDFileUMeshL2& loaderl2, const std::string& mName, MEDFileMeshReadSelector *mrs); + const MEDFileUMeshSplitL1 *getMeshAtLevSafe(int meshDimRelToMaxExt) const; + MEDFileUMeshSplitL1 *getMeshAtLevSafe(int meshDimRelToMaxExt); + void checkMeshDimCoherency(int meshDim, int meshDimRelToMax) const; + DataArrayDouble *checkMultiMesh(const std::vector<const MEDCouplingUMesh *>& ms) const; + void computeRevNum() const; + void synchronizeTinyInfoOnLeaves() const; + void changeFamilyIdArr(int oldId, int newId); + std::list< MEDCouplingAutoRefCountObjectPtr<DataArrayInt> > getAllNonNullFamilyIds() const; + MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1>& checkAndGiveEntryInSplitL1(int meshDimRelToMax, MEDCouplingPointSet *m); + private: + std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> > _ms; + MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> _coords; + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> _fam_coords; + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> _num_coords; + MEDCouplingAutoRefCountObjectPtr<DataArrayAsciiChar> _name_coords; + mutable MEDCouplingAutoRefCountObjectPtr<DataArrayInt> _rev_num_coords; + MEDCouplingAutoRefCountObjectPtr<PartDefinition> _part_coords; + }; + + class MEDFileStructuredMesh : public MEDFileMesh + { + friend class MEDFileMesh; + public: + MEDLOADER_EXPORT std::size_t getHeapMemorySizeWithoutChildren() const; + MEDLOADER_EXPORT std::vector<const BigMemoryObject *> getDirectChildrenWithNull() const; + MEDLOADER_EXPORT int getMaxAbsFamilyIdInArrays() const; + MEDLOADER_EXPORT int getMaxFamilyIdInArrays() const; + MEDLOADER_EXPORT int getMinFamilyIdInArrays() const; + MEDLOADER_EXPORT bool isEqual(const MEDFileMesh *other, double eps, std::string& what) const; + MEDLOADER_EXPORT void clearNonDiscrAttributes() const; + MEDLOADER_EXPORT DataArrayInt *getFamiliesArr(int meshDimRelToMaxExt, const std::vector<std::string>& fams, bool renum=false) const; + MEDLOADER_EXPORT const DataArrayInt *getFamilyFieldAtLevel(int meshDimRelToMaxExt) const; + MEDLOADER_EXPORT DataArrayInt *getFamilyFieldAtLevel(int meshDimRelToMaxExt); + MEDLOADER_EXPORT void setFamilyFieldArr(int meshDimRelToMaxExt, DataArrayInt *famArr); + MEDLOADER_EXPORT void setRenumFieldArr(int meshDimRelToMaxExt, DataArrayInt *renumArr); + MEDLOADER_EXPORT void setNameFieldAtLevel(int meshDimRelToMaxExt, DataArrayAsciiChar *nameArr); + MEDLOADER_EXPORT void addNodeGroup(const DataArrayInt *ids); + MEDLOADER_EXPORT void addGroup(int meshDimRelToMaxExt, const DataArrayInt *ids); + MEDLOADER_EXPORT const DataArrayInt *getNumberFieldAtLevel(int meshDimRelToMaxExt) const; + MEDLOADER_EXPORT const DataArrayInt *getRevNumberFieldAtLevel(int meshDimRelToMaxExt) const; + MEDLOADER_EXPORT const DataArrayAsciiChar *getNameFieldAtLevel(int meshDimRelToMaxExt) const; + MEDLOADER_EXPORT std::vector<int> getNonEmptyLevels() const; + MEDLOADER_EXPORT std::vector<int> getNonEmptyLevelsExt() const; + MEDLOADER_EXPORT std::vector<int> getFamArrNonEmptyLevelsExt() const; + MEDLOADER_EXPORT std::vector<int> getNumArrNonEmptyLevelsExt() const; + MEDLOADER_EXPORT std::vector<int> getNameArrNonEmptyLevelsExt() const; + MEDCouplingMesh *getGenMeshAtLevel(int meshDimRelToMax, bool renum=false) const; + MEDLOADER_EXPORT int getSizeAtLevel(int meshDimRelToMaxExt) const; + MEDLOADER_EXPORT int getNumberOfNodes() const; + MEDLOADER_EXPORT int getNumberOfCellsAtLevel(int meshDimRelToMaxExt) const; + MEDLOADER_EXPORT bool hasImplicitPart() const; + MEDLOADER_EXPORT int buildImplicitPartIfAny(INTERP_KERNEL::NormalizedCellType gt) const; + MEDLOADER_EXPORT void releaseImplicitPartIfAny() const; + MEDLOADER_EXPORT MEDCoupling1SGTUMesh *getImplicitFaceMesh() const; + MEDLOADER_EXPORT std::vector<INTERP_KERNEL::NormalizedCellType> getGeoTypesAtLevel(int meshDimRelToMax) const; + MEDLOADER_EXPORT void whichAreNodesFetched(const MEDFileField1TSStructItem& st, const MEDFileFieldGlobsReal *globs, std::vector<bool>& nodesFetched) const; + MEDLOADER_EXPORT virtual const MEDCouplingStructuredMesh *getStructuredMesh() const = 0; + // tools + MEDLOADER_EXPORT bool unPolyze(std::vector<int>& oldCode, std::vector<int>& newCode, DataArrayInt *& o2nRenumCell); + protected: + ~MEDFileStructuredMesh() { } + void changeFamilyIdArr(int oldId, int newId); + std::list< MEDCouplingAutoRefCountObjectPtr<DataArrayInt> > getAllNonNullFamilyIds() const; + void deepCpyAttributes(); + void loadStrMeshFromFile(MEDFileStrMeshL2 *strm, med_idt fid, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs); + void writeStructuredLL(med_idt fid, const std::string& maa) const; + void buildImplicitPart() const; + void buildMinusOneImplicitPartIfNeeded() const; + static med_geometry_type GetGeoTypeFromMeshDim(int meshDim); + private: + static void LoadStrMeshDAFromFile(med_idt fid, int meshDim, int dt, int it, const std::string& mName, MEDFileMeshReadSelector *mrs, + MEDCouplingAutoRefCountObjectPtr<DataArrayInt>& famCells, MEDCouplingAutoRefCountObjectPtr<DataArrayInt>& numCells, MEDCouplingAutoRefCountObjectPtr<DataArrayAsciiChar>& namesCells); + private: + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> _fam_nodes; + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> _num_nodes; + MEDCouplingAutoRefCountObjectPtr<DataArrayAsciiChar> _names_nodes; + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> _fam_cells; + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> _num_cells; + MEDCouplingAutoRefCountObjectPtr<DataArrayAsciiChar> _names_cells; + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> _fam_faces; + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> _num_faces; + MEDCouplingAutoRefCountObjectPtr<DataArrayAsciiChar> _names_faces; + mutable MEDCouplingAutoRefCountObjectPtr<DataArrayInt> _rev_num_nodes; + mutable MEDCouplingAutoRefCountObjectPtr<DataArrayInt> _rev_num_cells; + mutable MEDCouplingAutoRefCountObjectPtr<MEDCoupling1SGTUMesh> _faces_if_necessary; + }; + + class MEDFileCMesh : public MEDFileStructuredMesh + { + friend class MEDFileMesh; + public: + MEDLOADER_EXPORT static MEDFileCMesh *New(); + MEDLOADER_EXPORT static MEDFileCMesh *New(const std::string& fileName, MEDFileMeshReadSelector *mrs=0); + MEDLOADER_EXPORT static MEDFileCMesh *New(const std::string& fileName, const std::string& mName, int dt=-1, int it=-1, MEDFileMeshReadSelector *mrs=0); + MEDLOADER_EXPORT std::size_t getHeapMemorySizeWithoutChildren() const; + MEDLOADER_EXPORT std::vector<const BigMemoryObject *> getDirectChildrenWithNull() const; + MEDLOADER_EXPORT MEDFileMesh *createNewEmpty() const; + MEDLOADER_EXPORT MEDFileMesh *deepCpy() const; + MEDLOADER_EXPORT MEDFileMesh *shallowCpy() const; + MEDLOADER_EXPORT bool isEqual(const MEDFileMesh *other, double eps, std::string& what) const; + MEDLOADER_EXPORT int getMeshDimension() const; + MEDLOADER_EXPORT int getSpaceDimension() const; + MEDLOADER_EXPORT std::string simpleRepr() const; + MEDLOADER_EXPORT std::string advancedRepr() const; + MEDLOADER_EXPORT void clearNonDiscrAttributes() const; + MEDLOADER_EXPORT const MEDCouplingCMesh *getMesh() const; + MEDLOADER_EXPORT void setMesh(MEDCouplingCMesh *m); + private: + ~MEDFileCMesh() { } + const MEDCouplingStructuredMesh *getStructuredMesh() const; + void writeLL(med_idt fid) const; + MEDFileCMesh(); + void synchronizeTinyInfoOnLeaves() const; + MEDFileCMesh(med_idt fid, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs); + void loadCMeshFromFile(med_idt fid, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs); + private: + MEDCouplingAutoRefCountObjectPtr<MEDCouplingCMesh> _cmesh; + }; + + class MEDFileCurveLinearMesh : public MEDFileStructuredMesh + { + friend class MEDFileMesh; + public: + MEDLOADER_EXPORT static MEDFileCurveLinearMesh *New(); + MEDLOADER_EXPORT static MEDFileCurveLinearMesh *New(const std::string& fileName, MEDFileMeshReadSelector *mrs=0); + MEDLOADER_EXPORT static MEDFileCurveLinearMesh *New(const std::string& fileName, const std::string& mName, int dt=-1, int it=-1, MEDFileMeshReadSelector *mrs=0); + MEDLOADER_EXPORT std::size_t getHeapMemorySizeWithoutChildren() const; + MEDLOADER_EXPORT std::vector<const BigMemoryObject *> getDirectChildrenWithNull() const; + MEDLOADER_EXPORT MEDFileMesh *createNewEmpty() const; + MEDLOADER_EXPORT MEDFileMesh *deepCpy() const; + MEDLOADER_EXPORT MEDFileMesh *shallowCpy() const; + MEDLOADER_EXPORT bool isEqual(const MEDFileMesh *other, double eps, std::string& what) const; + MEDLOADER_EXPORT int getMeshDimension() const; + MEDLOADER_EXPORT std::string simpleRepr() const; + MEDLOADER_EXPORT std::string advancedRepr() const; + MEDLOADER_EXPORT void clearNonDiscrAttributes() const; + MEDLOADER_EXPORT const MEDCouplingCurveLinearMesh *getMesh() const; + MEDLOADER_EXPORT void setMesh(MEDCouplingCurveLinearMesh *m); + private: + ~MEDFileCurveLinearMesh() { } + MEDFileCurveLinearMesh(); + MEDFileCurveLinearMesh(med_idt fid, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs); + const MEDCouplingStructuredMesh *getStructuredMesh() const; + void synchronizeTinyInfoOnLeaves() const; + void writeLL(med_idt fid) const; + void loadCLMeshFromFile(med_idt fid, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs);//to imp + private: + MEDCouplingAutoRefCountObjectPtr<MEDCouplingCurveLinearMesh> _clmesh; + }; + + class MEDFileMeshMultiTS : public RefCountObject, public MEDFileWritable + { + public: + MEDLOADER_EXPORT static MEDFileMeshMultiTS *New(); + MEDLOADER_EXPORT static MEDFileMeshMultiTS *New(const std::string& fileName); + MEDLOADER_EXPORT static MEDFileMeshMultiTS *New(const std::string& fileName, const std::string& mName); + MEDLOADER_EXPORT MEDFileMeshMultiTS *deepCpy() const; + MEDLOADER_EXPORT std::size_t getHeapMemorySizeWithoutChildren() const; + MEDLOADER_EXPORT std::vector<const BigMemoryObject *> getDirectChildrenWithNull() const; + MEDLOADER_EXPORT std::string getName() const; + MEDLOADER_EXPORT void setName(const std::string& newMeshName); + MEDLOADER_EXPORT bool changeNames(const std::vector< std::pair<std::string,std::string> >& modifTab); + MEDLOADER_EXPORT MEDFileMesh *getOneTimeStep() const; + MEDLOADER_EXPORT void write(med_idt fid) const; + MEDLOADER_EXPORT void write(const std::string& fileName, int mode) const; + MEDLOADER_EXPORT void setOneTimeStep(MEDFileMesh *mesh1TimeStep); + MEDLOADER_EXPORT MEDFileJoints *getJoints() const; + MEDLOADER_EXPORT void setJoints( MEDFileJoints* joints ); + private: + ~MEDFileMeshMultiTS() { } + void loadFromFile(const std::string& fileName, const std::string& mName); + MEDFileMeshMultiTS(); + MEDFileMeshMultiTS(const std::string& fileName); + MEDFileMeshMultiTS(const std::string& fileName, const std::string& mName); + private: + std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileMesh> > _mesh_one_ts; + }; + + class MEDFileMeshesIterator; + + class MEDFileMeshes : public RefCountObject, public MEDFileWritable + { + public: + MEDLOADER_EXPORT static MEDFileMeshes *New(); + MEDLOADER_EXPORT static MEDFileMeshes *New(const std::string& fileName); + MEDLOADER_EXPORT MEDFileMeshes *deepCpy() const; + MEDLOADER_EXPORT std::size_t getHeapMemorySizeWithoutChildren() const; + MEDLOADER_EXPORT std::vector<const BigMemoryObject *> getDirectChildrenWithNull() const; + MEDLOADER_EXPORT std::string simpleRepr() const; + MEDLOADER_EXPORT void simpleReprWithoutHeader(std::ostream& oss) const; + MEDLOADER_EXPORT void write(const std::string& fileName, int mode) const; + MEDLOADER_EXPORT void write(med_idt fid) const; + MEDLOADER_EXPORT int getNumberOfMeshes() const; + MEDLOADER_EXPORT MEDFileMeshesIterator *iterator(); + MEDLOADER_EXPORT MEDFileMesh *getMeshAtPos(int i) const; + MEDLOADER_EXPORT MEDFileMesh *getMeshWithName(const std::string& mname) const; + MEDLOADER_EXPORT std::vector<std::string> getMeshesNames() const; + MEDLOADER_EXPORT bool changeNames(const std::vector< std::pair<std::string,std::string> >& modifTab); + // + MEDLOADER_EXPORT void resize(int newSize); + MEDLOADER_EXPORT void pushMesh(MEDFileMesh *mesh); + MEDLOADER_EXPORT void setMeshAtPos(int i, MEDFileMesh *mesh); + MEDLOADER_EXPORT void destroyMeshAtPos(int i); + private: + ~MEDFileMeshes() { } + void checkCoherency() const; + void loadFromFile(const std::string& fileName); + MEDFileMeshes(); + MEDFileMeshes(const std::string& fileName); + private: + std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileMeshMultiTS> > _meshes; + }; + + class MEDFileMeshesIterator + { + public: + MEDLOADER_EXPORT MEDFileMeshesIterator(MEDFileMeshes *ms); + MEDLOADER_EXPORT ~MEDFileMeshesIterator(); + MEDLOADER_EXPORT MEDFileMesh *nextt(); + private: + MEDCouplingAutoRefCountObjectPtr<MEDFileMeshes> _ms; + int _iter_id; + int _nb_iter; + }; +} + +#endif diff --git a/src/medtool/src/MEDLoader/MEDFileMeshElt.cxx b/src/medtool/src/MEDLoader/MEDFileMeshElt.cxx new file mode 100644 index 000000000..c2aa5504e --- /dev/null +++ b/src/medtool/src/MEDLoader/MEDFileMeshElt.cxx @@ -0,0 +1,404 @@ +// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 +// 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 "MEDFileMeshElt.hxx" +#include "MEDFileSafeCaller.txx" +#include "MEDFileMeshReadSelector.hxx" + +#include "MEDCouplingUMesh.hxx" + +#include "InterpKernelException.hxx" +#include "InterpKernelAutoPtr.hxx" +#include "CellModel.hxx" + +#include <iostream> + +extern med_geometry_type typmai3[34]; + +using namespace ParaMEDMEM; + +MEDFileUMeshPerType *MEDFileUMeshPerType::New(med_idt fid, const char *mName, int dt, int it, int mdim, med_geometry_type geoElt, INTERP_KERNEL::NormalizedCellType geoElt2, MEDFileMeshReadSelector *mrs) +{ + med_entity_type whichEntity; + if(!isExisting(fid,mName,dt,it,geoElt,whichEntity)) + return 0; + return new MEDFileUMeshPerType(fid,mName,dt,it,mdim,geoElt,geoElt2,whichEntity,mrs); +} + +MEDFileUMeshPerType *MEDFileUMeshPerType::NewPart(med_idt fid, const char *mName, int dt, int it, int mdim, INTERP_KERNEL::NormalizedCellType geoElt2, int strt, int stp, int step, MEDFileMeshReadSelector *mrs) +{ + int geoElt2i((int)geoElt2); + if(geoElt2i<0 || geoElt2i>=34) + throw INTERP_KERNEL::Exception("MEDFileUMeshPerType::NewPart : Not recognized MEDCoupling/MEDLoader geometric type !"); + med_geometry_type geoElt(typmai3[geoElt2]); + med_entity_type whichEntity; + if(!isExisting(fid,mName,dt,it,geoElt,whichEntity)) + throw INTERP_KERNEL::Exception("MEDFileUMeshPerType::NewPart : The specified geo type is not present in the specified mesh !"); + MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshPerType> ret(new MEDFileUMeshPerType); + ret->loadPart(fid,mName,dt,it,mdim,geoElt,geoElt2,whichEntity,strt,stp,step,mrs); + return ret.retn(); +} + +std::size_t MEDFileUMeshPerType::getHeapMemorySizeWithoutChildren() const +{ + return 0; +} + +std::vector<const BigMemoryObject *> MEDFileUMeshPerType::getDirectChildrenWithNull() const +{ + std::vector<const BigMemoryObject *> ret; + ret.push_back((const MEDCoupling1GTUMesh *)_m); + ret.push_back((const DataArrayInt *)_num); + ret.push_back((const DataArrayInt *)_fam); + ret.push_back((const DataArrayAsciiChar *)_names); + return ret; +} + +bool MEDFileUMeshPerType::isExisting(med_idt fid, const char *mName, int dt, int it, med_geometry_type geoElt, med_entity_type& whichEntity) +{ + static const med_entity_type entities[3]={MED_CELL,MED_DESCENDING_FACE,MED_DESCENDING_EDGE}; + int nbOfElt=0; + for(int i=0;i<3;i++) + { + med_bool changement,transformation; + int tmp(MEDmeshnEntity(fid,mName,dt,it,entities[i],geoElt,MED_CONNECTIVITY,MED_NODAL,&changement,&transformation)); + if(tmp>nbOfElt) + { + nbOfElt=tmp; + whichEntity=entities[i]; + if(i>0) + std::cerr << "WARNING : MEDFile has been detected to be no compilant with MED 3 : Please change entity in MEDFile for geotype " << geoElt << std::endl; + } + } + return nbOfElt>0; +} + +int MEDFileUMeshPerType::getDim() const +{ + return _m->getMeshDimension(); +} + +MEDFileUMeshPerType::MEDFileUMeshPerType() +{ +} + +MEDFileUMeshPerType::MEDFileUMeshPerType(med_idt fid, const char *mName, int dt, int it, int mdim, med_geometry_type geoElt, INTERP_KERNEL::NormalizedCellType type, + med_entity_type entity, MEDFileMeshReadSelector *mrs):_entity(entity) +{ + med_bool changement,transformation; + int curNbOfElem(MEDmeshnEntity(fid,mName,dt,it,entity,geoElt,MED_CONNECTIVITY,MED_NODAL,&changement,&transformation)); + const INTERP_KERNEL::CellModel& cm(INTERP_KERNEL::CellModel::GetCellModel(type)); + if(!cm.isDynamic()) + { + loadFromStaticType(fid,mName,dt,it,mdim,curNbOfElem,geoElt,type,entity,mrs); + return; + } + if(type==INTERP_KERNEL::NORM_POLYGON || type==INTERP_KERNEL::NORM_QPOLYG) + { + loadPolyg(fid,mName,dt,it,mdim,curNbOfElem,geoElt,entity,mrs); + return; + } + //if(type==INTERP_KERNEL::NORM_POLYHED) + loadPolyh(fid,mName,dt,it,mdim,curNbOfElem,geoElt,entity,mrs); +} + +void MEDFileUMeshPerType::loadPart(med_idt fid, const char *mName, int dt, int it, int mdim, med_geometry_type geoElt, INTERP_KERNEL::NormalizedCellType type, + med_entity_type entity, int strt, int end, int step, MEDFileMeshReadSelector *mrs) +{ + med_bool changement,transformation; + int curNbOfElem(MEDmeshnEntity(fid,mName,dt,it,entity,geoElt,MED_CONNECTIVITY,MED_NODAL,&changement,&transformation)); + const INTERP_KERNEL::CellModel& cm(INTERP_KERNEL::CellModel::GetCellModel(type)); + _pd=PartDefinition::New(strt,end,step); + if(!cm.isDynamic()) + { + loadPartStaticType(fid,mName,dt,it,mdim,curNbOfElem,geoElt,type,entity,strt,end,step,mrs); + } + else + throw INTERP_KERNEL::Exception("MEDFileUMeshPerType::loadPart : not implemented yet for the dynamic type !"); +} + +void MEDFileUMeshPerType::loadFromStaticType(med_idt fid, const char *mName, int dt, int it, int mdim, int curNbOfElem, med_geometry_type geoElt, INTERP_KERNEL::NormalizedCellType type, + med_entity_type entity, MEDFileMeshReadSelector *mrs) +{ + _m=MEDCoupling1SGTUMesh::New(mName,type); + MEDCoupling1SGTUMesh *mc(dynamic_cast<MEDCoupling1SGTUMesh *>((MEDCoupling1GTUMesh *)_m)); + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> conn(DataArrayInt::New()); + int nbOfNodesPerCell(mc->getNumberOfNodesPerCell()); + conn->alloc(nbOfNodesPerCell*curNbOfElem,1); + MEDFILESAFECALLERRD0(MEDmeshElementConnectivityRd,(fid,mName,dt,it,entity,geoElt,MED_NODAL,MED_FULL_INTERLACE,conn->getPointer())); + std::transform(conn->begin(),conn->end(),conn->getPointer(),std::bind2nd(std::plus<int>(),-1)); + mc->setNodalConnectivity(conn); + loadCommonPart(fid,mName,dt,it,mdim,curNbOfElem,geoElt,entity,mrs); +} + +void MEDFileUMeshPerType::loadPartStaticType(med_idt fid, const char *mName, int dt, int it, int mdim, int curNbOfElem, med_geometry_type geoElt, INTERP_KERNEL::NormalizedCellType type, + med_entity_type entity, int strt, int end, int step, MEDFileMeshReadSelector *mrs) +{ + if(strt<0) + throw INTERP_KERNEL::Exception("MEDFileUMeshPerType::loadPartStaticType : start pos is negative !"); + if(end>curNbOfElem) + throw INTERP_KERNEL::Exception("MEDFileUMeshPerType::loadPartStaticType : end is after the authorized range !"); + int nbOfEltsToLoad(DataArray::GetNumberOfItemGivenBES(strt,end,step,"MEDFileUMeshPerType::loadPartStaticType")); + _m=MEDCoupling1SGTUMesh::New(mName,type); + MEDCoupling1SGTUMesh *mc(dynamic_cast<MEDCoupling1SGTUMesh *>((MEDCoupling1GTUMesh *)_m)); + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> conn(DataArrayInt::New()); + int nbOfNodesPerCell(mc->getNumberOfNodesPerCell()); + conn->alloc(nbOfNodesPerCell*nbOfEltsToLoad,1); + med_filter filter=MED_FILTER_INIT; + MEDfilterBlockOfEntityCr(fid,/*nentity*/curNbOfElem,/*nvaluesperentity*/1,/*nconstituentpervalue*/nbOfNodesPerCell, + MED_ALL_CONSTITUENT,MED_FULL_INTERLACE,MED_COMPACT_STMODE,MED_NO_PROFILE, + /*start*/strt+1,/*stride*/step,/*count*/1,/*blocksize*/nbOfEltsToLoad, + /*lastblocksize=useless because count=1*/0,&filter); + MEDFILESAFECALLERRD0(MEDmeshElementConnectivityAdvancedRd,(fid,mName,dt,it,entity,geoElt,MED_NODAL,&filter,conn->getPointer())); + MEDfilterClose(&filter); + std::transform(conn->begin(),conn->end(),conn->getPointer(),std::bind2nd(std::plus<int>(),-1)); + mc->setNodalConnectivity(conn); + loadPartOfCellCommonPart(fid,mName,strt,end,step,dt,it,mdim,curNbOfElem,geoElt,entity,mrs); +} + +void MEDFileUMeshPerType::loadCommonPart(med_idt fid, const char *mName, int dt, int it, int mdim, int curNbOfElem, med_geometry_type geoElt, + med_entity_type entity, MEDFileMeshReadSelector *mrs) +{ + med_bool changement,transformation; + _fam=0; + if(MEDmeshnEntity(fid,mName,dt,it,entity,geoElt,MED_FAMILY_NUMBER,MED_NODAL,&changement,&transformation)>0) + { + if(!mrs || mrs->isCellFamilyFieldReading()) + { + _fam=DataArrayInt::New(); + _fam->alloc(curNbOfElem,1); + if(MEDmeshEntityFamilyNumberRd(fid,mName,dt,it,entity,geoElt,_fam->getPointer())!=0) + std::fill(_fam->getPointer(),_fam->getPointer()+curNbOfElem,0); + } + } + _num=0; + if(MEDmeshnEntity(fid,mName,dt,it,entity,geoElt,MED_NUMBER,MED_NODAL,&changement,&transformation)>0) + { + if(!mrs || mrs->isCellNumFieldReading()) + { + _num=DataArrayInt::New(); + _num->alloc(curNbOfElem,1); + if(MEDmeshEntityNumberRd(fid,mName,dt,it,entity,geoElt,_num->getPointer())!=0) + _num=0; + } + } + _names=0; + if(MEDmeshnEntity(fid,mName,dt,it,entity,geoElt,MED_NAME,MED_NODAL,&changement,&transformation)>0) + { + if(!mrs || mrs->isCellNameFieldReading()) + { + _names=DataArrayAsciiChar::New(); + _names->alloc(curNbOfElem+1,MED_SNAME_SIZE);//not a bug to avoid the memory corruption due to last \0 at the end + if(MEDmeshEntityNameRd(fid,mName,dt,it,entity,geoElt,_names->getPointer())!=0) + _names=0; + else + _names->reAlloc(curNbOfElem);//not a bug to avoid the memory corruption due to last \0 at the end + } + } +} + +void MEDFileUMeshPerType::loadPartOfCellCommonPart(med_idt fid, const char *mName, int strt, int stp, int step, int dt, int it, int mdim, int curNbOfElem, med_geometry_type geoElt, med_entity_type entity, MEDFileMeshReadSelector *mrs) +{ + med_bool changement,transformation; + _fam=0; + int nbOfEltsToLoad(DataArray::GetNumberOfItemGivenBES(strt,stp,step,"MEDFileUMeshPerType::loadPartOfCellCommonPart")); + if(MEDmeshnEntity(fid,mName,dt,it,entity,geoElt,MED_FAMILY_NUMBER,MED_NODAL,&changement,&transformation)>0) + { + if(!mrs || mrs->isCellFamilyFieldReading()) + { + _fam=DataArrayInt::New(); + _fam->alloc(nbOfEltsToLoad,1); + med_filter filter=MED_FILTER_INIT; + MEDfilterBlockOfEntityCr(fid,/*nentity*/curNbOfElem,/*nvaluesperentity*/1,/*nconstituentpervalue*/1, + MED_ALL_CONSTITUENT,MED_FULL_INTERLACE,MED_COMPACT_STMODE,MED_NO_PROFILE, + /*start*/strt+1,/*stride*/step,/*count*/1,/*blocksize*/nbOfEltsToLoad, + /*lastblocksize=useless because count=1*/0,&filter); + if(MEDmeshEntityAttributeAdvancedRd(fid,mName,MED_FAMILY_NUMBER,dt,it,entity,geoElt,&filter,_fam->getPointer())!=0) + _fam->fillWithZero(); + MEDfilterClose(&filter); + } + } + _num=0; + if(MEDmeshnEntity(fid,mName,dt,it,entity,geoElt,MED_NUMBER,MED_NODAL,&changement,&transformation)>0) + { + if(!mrs || mrs->isCellNumFieldReading()) + { + _num=DataArrayInt::New(); + _num->alloc(nbOfEltsToLoad,1); + med_filter filter=MED_FILTER_INIT; + MEDfilterBlockOfEntityCr(fid,/*nentity*/curNbOfElem,/*nvaluesperentity*/1,/*nconstituentpervalue*/1, + MED_ALL_CONSTITUENT,MED_FULL_INTERLACE,MED_COMPACT_STMODE,MED_NO_PROFILE, + /*start*/strt+1,/*stride*/step,/*count*/1,/*blocksize*/nbOfEltsToLoad, + /*lastblocksize=useless because count=1*/0,&filter); + if(MEDmeshEntityAttributeAdvancedRd(fid,mName,MED_NUMBER,dt,it,entity,geoElt,&filter,_num->getPointer())!=0) + _num->fillWithZero(); + MEDfilterClose(&filter); + } + } + _names=0; + if(MEDmeshnEntity(fid,mName,dt,it,entity,geoElt,MED_NAME,MED_NODAL,&changement,&transformation)>0) + { + if(!mrs || mrs->isCellNameFieldReading()) + { + _names=DataArrayAsciiChar::New(); + _names->alloc(nbOfEltsToLoad+1,MED_SNAME_SIZE);//not a bug to avoid the memory corruption due to last \0 at the end + med_filter filter=MED_FILTER_INIT; + MEDfilterBlockOfEntityCr(fid,/*nentity*/curNbOfElem,/*nvaluesperentity*/1,/*nconstituentpervalue*/1, + MED_ALL_CONSTITUENT,MED_FULL_INTERLACE,MED_COMPACT_STMODE,MED_NO_PROFILE, + /*start*/strt+1,/*stride*/step,/*count*/1,/*blocksize*/nbOfEltsToLoad, + /*lastblocksize=useless because count=1*/0,&filter); + if(MEDmeshEntityAttributeAdvancedRd(fid,mName,MED_NAME,dt,it,entity,geoElt,&filter,_names->getPointer())!=0) + _names=0; + else + _names->reAlloc(nbOfEltsToLoad);//not a bug to avoid the memory corruption due to last \0 at the end + MEDfilterClose(&filter); + } + } +} + +void MEDFileUMeshPerType::loadPolyg(med_idt fid, const char *mName, int dt, int it, int mdim, int arraySize, med_geometry_type geoElt, + med_entity_type entity, MEDFileMeshReadSelector *mrs) +{ + med_bool changement,transformation; + med_int curNbOfElem(MEDmeshnEntity(fid,mName,dt,it,entity,geoElt,MED_INDEX_NODE,MED_NODAL,&changement,&transformation)-1); + _m=MEDCoupling1DGTUMesh::New(mName,geoElt==MED_POLYGON?INTERP_KERNEL::NORM_POLYGON:INTERP_KERNEL::NORM_QPOLYG); + MEDCouplingAutoRefCountObjectPtr<MEDCoupling1DGTUMesh> mc(DynamicCast<MEDCoupling1GTUMesh,MEDCoupling1DGTUMesh>(_m)); + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> conn(DataArrayInt::New()),connI(DataArrayInt::New()); + conn->alloc(arraySize,1); connI->alloc(curNbOfElem+1,1); + MEDFILESAFECALLERRD0(MEDmeshPolygon2Rd,(fid,mName,dt,it,MED_CELL,geoElt,MED_NODAL,connI->getPointer(),conn->getPointer())); + std::transform(conn->begin(),conn->end(),conn->getPointer(),std::bind2nd(std::plus<int>(),-1)); + std::transform(connI->begin(),connI->end(),connI->getPointer(),std::bind2nd(std::plus<int>(),-1)); + mc->setNodalConnectivity(conn,connI); + loadCommonPart(fid,mName,dt,it,mdim,curNbOfElem,geoElt,entity,mrs); +} + +void MEDFileUMeshPerType::loadPolyh(med_idt fid, const char *mName, int dt, int it, int mdim, int connFaceLgth, med_geometry_type geoElt, + med_entity_type entity, MEDFileMeshReadSelector *mrs) +{ + med_bool changement,transformation; + med_int indexFaceLgth(MEDmeshnEntity(fid,mName,dt,it,MED_CELL,MED_POLYHEDRON,MED_INDEX_NODE,MED_NODAL,&changement,&transformation)); + int curNbOfElem(MEDmeshnEntity(fid,mName,dt,it,MED_CELL,MED_POLYHEDRON,MED_INDEX_FACE,MED_NODAL,&changement,&transformation)-1); + _m=MEDCoupling1DGTUMesh::New(mName,INTERP_KERNEL::NORM_POLYHED); + MEDCouplingAutoRefCountObjectPtr<MEDCoupling1DGTUMesh> mc(DynamicCastSafe<MEDCoupling1GTUMesh,MEDCoupling1DGTUMesh>(_m)); + INTERP_KERNEL::AutoPtr<int> index=new int[curNbOfElem+1]; + INTERP_KERNEL::AutoPtr<int> indexFace=new int[indexFaceLgth]; + INTERP_KERNEL::AutoPtr<int> locConn=new int[connFaceLgth]; + MEDFILESAFECALLERRD0(MEDmeshPolyhedronRd,(fid,mName,dt,it,MED_CELL,MED_NODAL,index,indexFace,locConn)); + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> conn(DataArrayInt::New()),connI(DataArrayInt::New()); + int arraySize=connFaceLgth; + for(int i=0;i<curNbOfElem;i++) + arraySize+=index[i+1]-index[i]-1; + conn=DataArrayInt::New(); + conn->alloc(arraySize,1); + int *wFinalConn=conn->getPointer(); + connI->alloc(curNbOfElem+1,1); + int *finalIndex(connI->getPointer()); + finalIndex[0]=0; + for(int i=0;i<curNbOfElem;i++) + { + finalIndex[i+1]=finalIndex[i]+index[i+1]-index[i]-1+indexFace[index[i+1]-1]-indexFace[index[i]-1]; + wFinalConn=std::transform(locConn+indexFace[index[i]-1]-1,locConn+indexFace[index[i]]-1,wFinalConn,std::bind2nd(std::plus<int>(),-1)); + for(int j=index[i];j<index[i+1]-1;j++) + { + *wFinalConn++=-1; + wFinalConn=std::transform(locConn+indexFace[j]-1,locConn+indexFace[j+1]-1,wFinalConn,std::bind2nd(std::plus<int>(),-1)); + } + } + mc->setNodalConnectivity(conn,connI); + loadCommonPart(fid,mName,dt,it,mdim,curNbOfElem,MED_POLYHEDRON,entity,mrs); +} + +void MEDFileUMeshPerType::Write(med_idt fid, const std::string& mname, int mdim, const MEDCoupling1GTUMesh *m, const DataArrayInt *fam, const DataArrayInt *num, const DataArrayAsciiChar *names) +{ + int nbOfCells=m->getNumberOfCells(); + if(nbOfCells<1) + return ; + int dt,it; + double timm=m->getTime(dt,it); + INTERP_KERNEL::NormalizedCellType ikt=m->getTypeOfCell(0); + const INTERP_KERNEL::CellModel& cm=INTERP_KERNEL::CellModel::GetCellModel(ikt); + med_geometry_type curMedType=typmai3[(int)ikt]; + if(!cm.isDynamic()) + { + const MEDCoupling1SGTUMesh *m0(dynamic_cast<const MEDCoupling1SGTUMesh *>(m)); + if(!m0) + throw INTERP_KERNEL::Exception("MEDFileUMeshPerType::Write : internal error #1 !"); + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> arr(m0->getNodalConnectivity()->deepCpy()); + std::transform(arr->begin(),arr->end(),arr->getPointer(),std::bind2nd(std::plus<int>(),1)); + MEDFILESAFECALLERWR0(MEDmeshElementConnectivityWr,(fid,mname.c_str(),dt,it,timm,MED_CELL,curMedType,MED_NODAL,MED_FULL_INTERLACE,nbOfCells,arr->begin())); + } + else + { + const MEDCoupling1DGTUMesh *m0(dynamic_cast<const MEDCoupling1DGTUMesh *>(m)); + if(!m0) + throw INTERP_KERNEL::Exception("MEDFileUMeshPerType::Write : internal error #2 !"); + if(ikt==INTERP_KERNEL::NORM_POLYGON || ikt==INTERP_KERNEL::NORM_QPOLYG) + { + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> arr(m0->getNodalConnectivity()->deepCpy()),arrI(m0->getNodalConnectivityIndex()->deepCpy()); + std::transform(arr->begin(),arr->end(),arr->getPointer(),std::bind2nd(std::plus<int>(),1)); + std::transform(arrI->begin(),arrI->end(),arrI->getPointer(),std::bind2nd(std::plus<int>(),1)); + MEDFILESAFECALLERWR0(MEDmeshPolygon2Wr,(fid,mname.c_str(),dt,it,timm,MED_CELL,ikt==INTERP_KERNEL::NORM_POLYGON?MED_POLYGON:MED_POLYGON2,MED_NODAL,nbOfCells+1,arrI->begin(),arr->begin())); + } + else + { + const int *conn(m0->getNodalConnectivity()->begin()),*connI(m0->getNodalConnectivityIndex()->begin()); + int meshLgth=m0->getNodalConnectivityLength(); + int nbOfFaces=std::count(conn,conn+meshLgth,-1)+nbOfCells; + INTERP_KERNEL::AutoPtr<int> tab1=new int[nbOfCells+1]; + int *w1=tab1; *w1=1; + INTERP_KERNEL::AutoPtr<int> tab2=new int[nbOfFaces+1]; + int *w2=tab2; *w2=1; + INTERP_KERNEL::AutoPtr<int> bigtab=new int[meshLgth]; + int *bt=bigtab; + for(int i=0;i<nbOfCells;i++,w1++) + { + int nbOfFaces2=0; + for(const int *w=conn+connI[i];w!=conn+connI[i+1];w2++) + { + const int *wend=std::find(w,conn+connI[i+1],-1); + bt=std::transform(w,wend,bt,std::bind2nd(std::plus<int>(),1)); + int nbOfNode=std::distance(w,wend); + w2[1]=w2[0]+nbOfNode; + if(wend!=conn+connI[i+1]) + w=wend+1; + else + w=wend; + nbOfFaces2++; + } + w1[1]=w1[0]+nbOfFaces2; + } + MEDFILESAFECALLERWR0(MEDmeshPolyhedronWr,(fid,mname.c_str(),dt,it,timm,MED_CELL,MED_NODAL,nbOfCells+1,tab1,nbOfFaces+1,tab2,bigtab)); + } + } + if(fam) + MEDFILESAFECALLERWR0(MEDmeshEntityFamilyNumberWr,(fid,mname.c_str(),dt,it,MED_CELL,curMedType,nbOfCells,fam->getConstPointer())); + if(num) + MEDFILESAFECALLERWR0(MEDmeshEntityNumberWr,(fid,mname.c_str(),dt,it,MED_CELL,curMedType,nbOfCells,num->getConstPointer())); + if(names) + { + if(names->getNumberOfComponents()!=MED_SNAME_SIZE) + { + std::ostringstream oss; oss << "MEDFileUMeshPerType::write : expected a name field on cells with number of components set to " << MED_SNAME_SIZE; + oss << " ! The array has " << names->getNumberOfComponents() << " components !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + MEDFILESAFECALLERWR0(MEDmeshEntityNameWr,(fid,mname.c_str(),dt,it,MED_CELL,curMedType,nbOfCells,names->getConstPointer())); + } +} diff --git a/src/medtool/src/MEDLoader/MEDFileMeshElt.hxx b/src/medtool/src/MEDLoader/MEDFileMeshElt.hxx new file mode 100644 index 000000000..9d57bc1e8 --- /dev/null +++ b/src/medtool/src/MEDLoader/MEDFileMeshElt.hxx @@ -0,0 +1,79 @@ +// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 +// 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 __MEDFILEMESHELT_HXX__ +#define __MEDFILEMESHELT_HXX__ + +#include "MEDCouplingMemArray.hxx" +#include "MEDCoupling1GTUMesh.hxx" +#include "MEDCouplingPartDefinition.hxx" +#include "MEDCouplingAutoRefCountObjectPtr.hxx" + +#include "NormalizedUnstructuredMesh.hxx" + +#include "med.h" + +namespace ParaMEDMEM +{ + class MEDCouplingUMesh; + class MEDFileMeshReadSelector; + + class MEDFileUMeshPerType : public RefCountObject + { + public: + static MEDFileUMeshPerType *New(med_idt fid, const char *mName, int dt, int it, int mdim, med_geometry_type geoElt, INTERP_KERNEL::NormalizedCellType geoElt2, MEDFileMeshReadSelector *mrs); + static MEDFileUMeshPerType *NewPart(med_idt fid, const char *mName, int dt, int it, int mdim, INTERP_KERNEL::NormalizedCellType geoElt2, int strt, int stp, int step, MEDFileMeshReadSelector *mrs); + static bool isExisting(med_idt fid, const char *mName, int dt, int it, med_geometry_type geoElt, med_entity_type& whichEntity); + std::size_t getHeapMemorySizeWithoutChildren() const; + std::vector<const BigMemoryObject *> getDirectChildrenWithNull() const; + int getDim() const; + MEDCoupling1GTUMesh *getMesh() const { return const_cast<MEDCoupling1GTUMesh *>((const MEDCoupling1GTUMesh *)_m); } + const DataArrayInt *getFam() const { return _fam; } + const DataArrayInt *getNum() const { return _num; } + const DataArrayAsciiChar *getNames() const { return _names; } + const PartDefinition *getPartDef() const { return _pd; } + static void Write(med_idt fid, const std::string& mname, int mdim, const MEDCoupling1GTUMesh *m, const DataArrayInt *fam, const DataArrayInt *num, const DataArrayAsciiChar *names); + private: + MEDFileUMeshPerType(); + MEDFileUMeshPerType(med_idt fid, const char *mName, int dt, int it, int mdim, med_geometry_type geoElt, INTERP_KERNEL::NormalizedCellType type, + med_entity_type entity, MEDFileMeshReadSelector *mrs); + void loadPart(med_idt fid, const char *mName, int dt, int it, int mdim, med_geometry_type geoElt, INTERP_KERNEL::NormalizedCellType type, + med_entity_type entity, int strt, int end, int step, MEDFileMeshReadSelector *mrs); + void loadFromStaticType(med_idt fid, const char *mName, int dt, int it, int mdim, int curNbOfElem, med_geometry_type geoElt, INTERP_KERNEL::NormalizedCellType type, + med_entity_type entity, MEDFileMeshReadSelector *mrs); + void loadPartStaticType(med_idt fid, const char *mName, int dt, int it, int mdim, int curNbOfElem, med_geometry_type geoElt, INTERP_KERNEL::NormalizedCellType type, + med_entity_type entity, int strt, int end, int step, MEDFileMeshReadSelector *mrs); + void loadPolyg(med_idt fid, const char *mName, int dt, int it, int mdim, int arraySize, med_geometry_type geoElt, + med_entity_type entity, MEDFileMeshReadSelector *mrs); + void loadPolyh(med_idt fid, const char *mName, int dt, int it, int mdim, int connFaceLgth, med_geometry_type geoElt, + med_entity_type entity, MEDFileMeshReadSelector *mrs); + void loadCommonPart(med_idt fid, const char *mName, int dt, int it, int mdim, int curNbOfElem, med_geometry_type geoElt, med_entity_type entity, MEDFileMeshReadSelector *mrs); + void loadPartOfCellCommonPart(med_idt fid, const char *mName, int strt, int stp, int step, int dt, int it, int mdim, int curNbOfElem, med_geometry_type geoElt, med_entity_type entity, MEDFileMeshReadSelector *mrs); + private: + MEDCouplingAutoRefCountObjectPtr<MEDCoupling1GTUMesh> _m; + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> _num; + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> _fam; + MEDCouplingAutoRefCountObjectPtr<DataArrayAsciiChar> _names; + MEDCouplingAutoRefCountObjectPtr<PartDefinition> _pd; + med_entity_type _entity; + }; +} + +#endif diff --git a/src/medtool/src/MEDLoader/MEDFileMeshLL.cxx b/src/medtool/src/MEDLoader/MEDFileMeshLL.cxx new file mode 100644 index 000000000..218f7bb72 --- /dev/null +++ b/src/medtool/src/MEDLoader/MEDFileMeshLL.cxx @@ -0,0 +1,1707 @@ +// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 +// 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 "MEDFileMeshLL.hxx" +#include "MEDFileMesh.hxx" +#include "MEDLoaderBase.hxx" +#include "MEDFileSafeCaller.txx" +#include "MEDFileMeshReadSelector.hxx" + +#include "MEDCouplingUMesh.hxx" + +#include "InterpKernelAutoPtr.hxx" +#include "CellModel.hxx" + +#include <set> + +extern med_geometry_type typmai[MED_N_CELL_FIXED_GEO]; +extern INTERP_KERNEL::NormalizedCellType typmai2[MED_N_CELL_FIXED_GEO]; +extern med_geometry_type typmainoeud[1]; + +using namespace ParaMEDMEM; + +MEDFileMeshL2::MEDFileMeshL2():_name(MED_NAME_SIZE),_description(MED_COMMENT_SIZE),_univ_name(MED_LNAME_SIZE),_dt_unit(MED_LNAME_SIZE) +{ +} + +std::size_t MEDFileMeshL2::getHeapMemorySizeWithoutChildren() const +{ + return 0; +} + +std::vector<const BigMemoryObject *> MEDFileMeshL2::getDirectChildrenWithNull() const +{ + return std::vector<const BigMemoryObject *>(); +} + +int MEDFileMeshL2::GetMeshIdFromName(med_idt fid, const std::string& mname, ParaMEDMEM::MEDCouplingMeshType& meshType, int& dt, int& it, std::string& dtunit1) +{ + med_mesh_type type_maillage; + char maillage_description[MED_COMMENT_SIZE+1]; + char dtunit[MED_LNAME_SIZE+1]; + med_int spaceDim,dim; + char nommaa[MED_NAME_SIZE+1]; + med_int n=MEDnMesh(fid); + bool found=false; + int ret=-1; + med_sorting_type stype; + std::vector<std::string> ms; + int nstep; + med_axis_type axistype; + for(int i=0;i<n && !found;i++) + { + int naxis(MEDmeshnAxis(fid,i+1)); + INTERP_KERNEL::AutoPtr<char> axisname=MEDLoaderBase::buildEmptyString(naxis*MED_SNAME_SIZE); + INTERP_KERNEL::AutoPtr<char> axisunit=MEDLoaderBase::buildEmptyString(naxis*MED_SNAME_SIZE); + MEDFILESAFECALLERRD0(MEDmeshInfo,(fid,i+1,nommaa,&spaceDim,&dim,&type_maillage,maillage_description,dtunit,&stype,&nstep,&axistype,axisname,axisunit)); + dtunit1=MEDLoaderBase::buildStringFromFortran(dtunit,sizeof(dtunit)); + std::string cur=MEDLoaderBase::buildStringFromFortran(nommaa,sizeof(nommaa)); + ms.push_back(cur); + if(cur==mname) + { + found=true; + ret=i+1; + } + } + if(!found) + { + std::ostringstream oss; + oss << "No such meshname (" << mname << ") in file ! Must be in : "; + std::copy(ms.begin(),ms.end(),std::ostream_iterator<std::string>(oss,", ")); + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + switch(type_maillage) + { + case MED_UNSTRUCTURED_MESH: + meshType=UNSTRUCTURED; + break; + case MED_STRUCTURED_MESH: + { + med_grid_type gt; + MEDFILESAFECALLERRD0(MEDmeshGridTypeRd,(fid,mname.c_str(),>)); + switch(gt) + { + case MED_CARTESIAN_GRID: + meshType=CARTESIAN; + break; + case MED_CURVILINEAR_GRID: + meshType=CURVE_LINEAR; + break; + default: + throw INTERP_KERNEL::Exception("MEDFileUMeshL2::getMeshIdFromName : unrecognized structured mesh type ! Supported are :\n - cartesian\n - curve linear\n"); + } + break; + } + default: + throw INTERP_KERNEL::Exception("MEDFileUMeshL2::getMeshIdFromName : unrecognized mesh type !"); + } + med_int numdt,numit; + med_float dtt; + MEDFILESAFECALLERRD0(MEDmeshComputationStepInfo,(fid,mname.c_str(),1,&numdt,&numit,&dtt)); + dt=numdt; it=numit; + return ret; +} + +double MEDFileMeshL2::CheckMeshTimeStep(med_idt fid, const std::string& mName, int nstep, int dt, int it) +{ + bool found=false; + med_int numdt,numit; + med_float dtt; + std::vector< std::pair<int,int> > p(nstep); + for(int i=0;i<nstep;i++) + { + MEDFILESAFECALLERRD0(MEDmeshComputationStepInfo,(fid,mName.c_str(),i+1,&numdt,&numit,&dtt)); + p[i]=std::make_pair<int,int>(numdt,numit); + found=(numdt==dt) && (numit==numit); + } + if(!found) + { + std::ostringstream oss; oss << "No such iteration=" << dt << ",order=" << it << " numbers found for mesh '" << mName << "' ! "; + oss << "Possibilities are : "; + for(int i=0;i<nstep;i++) + oss << "(" << p[i].first << "," << p[i].second << "), "; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + return dtt; +} + +std::vector<std::string> MEDFileMeshL2::getAxisInfoOnMesh(med_idt fid, int mId, const std::string& mName, ParaMEDMEM::MEDCouplingMeshType& meshType, int& nstep, int& Mdim) +{ + med_mesh_type type_maillage; + med_int spaceDim; + med_sorting_type stype; + med_axis_type axistype; + int naxis(MEDmeshnAxis(fid,mId)); + INTERP_KERNEL::AutoPtr<char> nameTmp=MEDLoaderBase::buildEmptyString(MED_NAME_SIZE); + INTERP_KERNEL::AutoPtr<char> axisname=MEDLoaderBase::buildEmptyString(naxis*MED_SNAME_SIZE); + INTERP_KERNEL::AutoPtr<char> axisunit=MEDLoaderBase::buildEmptyString(naxis*MED_SNAME_SIZE); + INTERP_KERNEL::AutoPtr<char> univTmp=MEDLoaderBase::buildEmptyString(MED_LNAME_SIZE); + if(MEDmeshInfo(fid,mId,nameTmp,&spaceDim,&Mdim,&type_maillage,_description.getPointer(),_dt_unit.getPointer(), + &stype,&nstep,&axistype,axisname,axisunit)!=0) + throw INTERP_KERNEL::Exception("A problem has been detected when trying to get info on mesh !"); + MEDmeshUniversalNameRd(fid,nameTmp,_univ_name.getPointer());// do not protect MEDFILESAFECALLERRD0 call : Thanks to fra.med. + switch(type_maillage) + { + case MED_UNSTRUCTURED_MESH: + meshType=UNSTRUCTURED; + break; + case MED_STRUCTURED_MESH: + { + med_grid_type gt; + MEDFILESAFECALLERRD0(MEDmeshGridTypeRd,(fid,mName.c_str(),>)); + switch(gt) + { + case MED_CARTESIAN_GRID: + meshType=CARTESIAN; + break; + case MED_CURVILINEAR_GRID: + meshType=CURVE_LINEAR; + break; + default: + throw INTERP_KERNEL::Exception("MEDFileUMeshL2::getAxisInfoOnMesh : unrecognized structured mesh type ! Supported are :\n - cartesian\n - curve linear\n"); + } + break; + } + default: + throw INTERP_KERNEL::Exception("MEDFileUMeshL2::getMeshIdFromName : unrecognized mesh type !"); + } + // + std::vector<std::string> infosOnComp(naxis); + for(int i=0;i<naxis;i++) + { + std::string info=MEDLoaderBase::buildUnionUnit(((char *)axisname)+i*MED_SNAME_SIZE,MED_SNAME_SIZE,((char *)axisunit)+i*MED_SNAME_SIZE,MED_SNAME_SIZE); + infosOnComp[i]=info; + } + return infosOnComp; +} + +void MEDFileMeshL2::ReadFamiliesAndGrps(med_idt fid, const std::string& meshName, std::map<std::string,int>& fams, std::map<std::string, std::vector<std::string> >& grps, MEDFileMeshReadSelector *mrs) +{ + if(mrs && !(mrs->isCellFamilyFieldReading() || mrs->isNodeFamilyFieldReading())) + return ; + char nomfam[MED_NAME_SIZE+1]; + med_int numfam; + int nfam=MEDnFamily(fid,meshName.c_str()); + for(int i=0;i<nfam;i++) + { + int ngro=MEDnFamilyGroup(fid,meshName.c_str(),i+1); + med_int natt=MEDnFamily23Attribute(fid,meshName.c_str(),i+1); + INTERP_KERNEL::AutoPtr<med_int> attide=new med_int[natt]; + INTERP_KERNEL::AutoPtr<med_int> attval=new med_int[natt]; + INTERP_KERNEL::AutoPtr<char> attdes=new char[MED_COMMENT_SIZE*natt+1]; + INTERP_KERNEL::AutoPtr<char> gro=new char[MED_LNAME_SIZE*ngro+1]; + MEDfamily23Info(fid,meshName.c_str(),i+1,nomfam,attide,attval,attdes,&numfam,gro); + std::string famName=MEDLoaderBase::buildStringFromFortran(nomfam,MED_NAME_SIZE); + fams[famName]=numfam; + for(int j=0;j<ngro;j++) + { + std::string groupname=MEDLoaderBase::buildStringFromFortran(gro+j*MED_LNAME_SIZE,MED_LNAME_SIZE); + grps[groupname].push_back(famName); + } + } +} + +void MEDFileMeshL2::WriteFamiliesAndGrps(med_idt fid, const std::string& mname, const std::map<std::string,int>& fams, const std::map<std::string, std::vector<std::string> >& grps, int tooLongStrPol) +{ + for(std::map<std::string,int>::const_iterator it=fams.begin();it!=fams.end();it++) + { + std::vector<std::string> grpsOfFam; + for(std::map<std::string, std::vector<std::string> >::const_iterator it1=grps.begin();it1!=grps.end();it1++) + { + if(std::find((*it1).second.begin(),(*it1).second.end(),(*it).first)!=(*it1).second.end()) + grpsOfFam.push_back((*it1).first); + } + int ngro=grpsOfFam.size(); + INTERP_KERNEL::AutoPtr<char> groName=MEDLoaderBase::buildEmptyString(MED_LNAME_SIZE*ngro); + int i=0; + for(std::vector<std::string>::const_iterator it2=grpsOfFam.begin();it2!=grpsOfFam.end();it2++,i++) + MEDLoaderBase::safeStrCpy2((*it2).c_str(),MED_LNAME_SIZE-1,groName+i*MED_LNAME_SIZE,tooLongStrPol); + INTERP_KERNEL::AutoPtr<char> famName=MEDLoaderBase::buildEmptyString(MED_NAME_SIZE); + MEDLoaderBase::safeStrCpy((*it).first.c_str(),MED_NAME_SIZE,famName,tooLongStrPol); + int ret=MEDfamilyCr(fid,mname.c_str(),famName,(*it).second,ngro,groName); + ret++; + } +} + +MEDFileUMeshL2::MEDFileUMeshL2() +{ +} + +std::vector<std::string> MEDFileUMeshL2::loadCommonPart(med_idt fid, int mId, const std::string& mName, int dt, int it, int& Mdim) +{ + Mdim=-3; + _name.set(mName.c_str()); + int nstep; + ParaMEDMEM::MEDCouplingMeshType meshType; + std::vector<std::string> ret(getAxisInfoOnMesh(fid,mId,mName.c_str(),meshType,nstep,Mdim)); + if(nstep==0) + { + Mdim=-4; + return std::vector<std::string>(); + } + if(meshType!=UNSTRUCTURED) + throw INTERP_KERNEL::Exception("Invalid mesh type ! You are expected an unstructured one whereas in file it is not an unstructured !"); + _time=CheckMeshTimeStep(fid,mName,nstep,dt,it); + _iteration=dt; + _order=it; + return ret; +} + +void MEDFileUMeshL2::loadAll(med_idt fid, int mId, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs) +{ + int Mdim; + std::vector<std::string> infosOnComp(loadCommonPart(fid,mId,mName,dt,it,Mdim)); + if(Mdim==-4) + return ; + loadConnectivity(fid,Mdim,mName,dt,it,mrs);//to improve check (dt,it) coherency + loadCoords(fid,mId,infosOnComp,mName,dt,it); +} + +void MEDFileUMeshL2::loadPart(med_idt fid, int mId, const std::string& mName, const std::vector<INTERP_KERNEL::NormalizedCellType>& types, const std::vector<int>& slicPerTyp, int dt, int it, MEDFileMeshReadSelector *mrs) +{ + int Mdim; + std::vector<std::string> infosOnComp(loadCommonPart(fid,mId,mName,dt,it,Mdim)); + if(Mdim==-4) + return ; + loadPartOfConnectivity(fid,Mdim,mName,types,slicPerTyp,dt,it,mrs); + med_bool changement,transformation; + int nCoords(MEDmeshnEntity(fid,mName.c_str(),dt,it,MED_NODE,MED_NONE,MED_COORDINATE,MED_NO_CMODE,&changement,&transformation)); + std::vector<bool> fetchedNodeIds(nCoords,false); + for(std::vector< std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshPerType> > >::const_iterator it0=_per_type_mesh.begin();it0!=_per_type_mesh.end();it0++) + for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshPerType> >::const_iterator it1=(*it0).begin();it1!=(*it0).end();it1++) + (*it1)->getMesh()->computeNodeIdsAlg(fetchedNodeIds); + int nMin(std::distance(fetchedNodeIds.begin(),std::find(fetchedNodeIds.begin(),fetchedNodeIds.end(),true))); + int nMax(std::distance(fetchedNodeIds.rbegin(),std::find(fetchedNodeIds.rbegin(),fetchedNodeIds.rend(),true))); + nMax=nCoords-nMax; + for(std::vector< std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshPerType> > >::const_iterator it0=_per_type_mesh.begin();it0!=_per_type_mesh.end();it0++) + for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshPerType> >::const_iterator it1=(*it0).begin();it1!=(*it0).end();it1++) + (*it1)->getMesh()->renumberNodesWithOffsetInConn(-nMin); + loadPartCoords(fid,mId,infosOnComp,mName,dt,it,nMin,nMax); +} + +void MEDFileUMeshL2::loadConnectivity(med_idt fid, int mdim, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs) +{ + _per_type_mesh.resize(1); + _per_type_mesh[0].clear(); + for(int j=0;j<MED_N_CELL_FIXED_GEO;j++) + { + MEDFileUMeshPerType *tmp(MEDFileUMeshPerType::New(fid,mName.c_str(),dt,it,mdim,typmai[j],typmai2[j],mrs)); + if(tmp) + _per_type_mesh[0].push_back(tmp); + } + sortTypes(); +} + +void MEDFileUMeshL2::loadPartOfConnectivity(med_idt fid, int mdim, const std::string& mName, const std::vector<INTERP_KERNEL::NormalizedCellType>& types, const std::vector<int>& slicPerTyp, int dt, int it, MEDFileMeshReadSelector *mrs) +{ + std::size_t nbOfTypes(types.size()); + if(slicPerTyp.size()!=3*nbOfTypes) + throw INTERP_KERNEL::Exception("MEDFileUMeshL2::loadPartOfConnectivity : The size of slicPerTyp array is expected to be equal to 3 times size of array types !"); + std::set<INTERP_KERNEL::NormalizedCellType> types2(types.begin(),types.end()); + if(types2.size()!=nbOfTypes) + throw INTERP_KERNEL::Exception("MEDFileUMeshL2::loadPartOfConnectivity : the geometric types in types array must appear once !"); + _per_type_mesh.resize(1); + _per_type_mesh[0].clear(); + for(std::size_t ii=0;ii<nbOfTypes;ii++) + { + int strt(slicPerTyp[3*ii+0]),stp(slicPerTyp[3*ii+1]),step(slicPerTyp[3*ii+2]); + MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshPerType> tmp(MEDFileUMeshPerType::NewPart(fid,mName.c_str(),dt,it,mdim,types[ii],strt,stp,step,mrs)); + _per_type_mesh[0].push_back(tmp); + } + sortTypes(); +} + +void MEDFileUMeshL2::loadCoords(med_idt fid, int mId, const std::vector<std::string>& infosOnComp, const std::string& mName, int dt, int it) +{ + int spaceDim((int)infosOnComp.size()); + med_bool changement,transformation; + int nCoords(MEDmeshnEntity(fid,mName.c_str(),dt,it,MED_NODE,MED_NONE,MED_COORDINATE,MED_NO_CMODE,&changement,&transformation)); + _coords=DataArrayDouble::New(); + _coords->alloc(nCoords,spaceDim); + double *coordsPtr(_coords->getPointer()); + if (nCoords) + MEDFILESAFECALLERRD0(MEDmeshNodeCoordinateRd,(fid,mName.c_str(),dt,it,MED_FULL_INTERLACE,coordsPtr)); + if(MEDmeshnEntity(fid,mName.c_str(),dt,it,MED_NODE,MED_NO_GEOTYPE,MED_FAMILY_NUMBER,MED_NODAL,&changement,&transformation)>0) + { + _fam_coords=DataArrayInt::New(); + _fam_coords->alloc(nCoords,1); + MEDFILESAFECALLERRD0(MEDmeshEntityFamilyNumberRd,(fid,mName.c_str(),dt,it,MED_NODE,MED_NO_GEOTYPE,_fam_coords->getPointer())); + } + else + _fam_coords=0; + if(MEDmeshnEntity(fid,mName.c_str(),dt,it,MED_NODE,MED_NO_GEOTYPE,MED_NUMBER,MED_NODAL,&changement,&transformation)>0) + { + _num_coords=DataArrayInt::New(); + _num_coords->alloc(nCoords,1); + MEDFILESAFECALLERRD0(MEDmeshEntityNumberRd,(fid,mName.c_str(),dt,it,MED_NODE,MED_NO_GEOTYPE,_num_coords->getPointer())); + } + else + _num_coords=0; + if(MEDmeshnEntity(fid,mName.c_str(),dt,it,MED_NODE,MED_NO_GEOTYPE,MED_NAME,MED_NODAL,&changement,&transformation)>0) + { + _name_coords=DataArrayAsciiChar::New(); + _name_coords->alloc(nCoords+1,MED_SNAME_SIZE);//not a bug to avoid the memory corruption due to last \0 at the end + MEDFILESAFECALLERRD0(MEDmeshEntityNameRd,(fid,mName.c_str(),dt,it,MED_NODE,MED_NO_GEOTYPE,_name_coords->getPointer())); + _name_coords->reAlloc(nCoords);//not a bug to avoid the memory corruption due to last \0 at the end + } + else + _name_coords=0; + for(int i=0;i<spaceDim;i++) + _coords->setInfoOnComponent(i,infosOnComp[i]); +} + +void MEDFileUMeshL2::loadPartCoords(med_idt fid, int mId, const std::vector<std::string>& infosOnComp, const std::string& mName, int dt, int it, int nMin, int nMax) +{ + med_bool changement,transformation; + int spaceDim((int)infosOnComp.size()),nCoords(MEDmeshnEntity(fid,mName.c_str(),dt,it,MED_NODE,MED_NONE,MED_COORDINATE,MED_NO_CMODE,&changement,&transformation)); + _coords=DataArrayDouble::New(); + int nbNodesToLoad(nMax-nMin); + _coords->alloc(nbNodesToLoad,spaceDim); + med_filter filter=MED_FILTER_INIT,filter2=MED_FILTER_INIT; + MEDfilterBlockOfEntityCr(fid,/*nentity*/nCoords,/*nvaluesperentity*/1,/*nconstituentpervalue*/spaceDim, + MED_ALL_CONSTITUENT,MED_FULL_INTERLACE,MED_COMPACT_STMODE,MED_NO_PROFILE, + /*start*/nMin+1,/*stride*/1,/*count*/1,/*blocksize*/nbNodesToLoad, + /*lastblocksize=useless because count=1*/0,&filter); + MEDFILESAFECALLERRD0(MEDmeshNodeCoordinateAdvancedRd,(fid,mName.c_str(),dt,it,&filter,_coords->getPointer())); + _part_coords=PartDefinition::New(nMin,nMax,1); + MEDfilterClose(&filter); + MEDfilterBlockOfEntityCr(fid,nCoords,1,1,MED_ALL_CONSTITUENT,MED_FULL_INTERLACE,MED_COMPACT_STMODE, + MED_NO_PROFILE,nMin+1,1,1,nbNodesToLoad,0,&filter2); + if(MEDmeshnEntity(fid,mName.c_str(),dt,it,MED_NODE,MED_NO_GEOTYPE,MED_FAMILY_NUMBER,MED_NODAL,&changement,&transformation)>0) + { + _fam_coords=DataArrayInt::New(); + _fam_coords->alloc(nbNodesToLoad,1); + MEDFILESAFECALLERRD0(MEDmeshEntityAttributeAdvancedRd,(fid,mName.c_str(),MED_FAMILY_NUMBER,dt,it,MED_NODE,MED_NO_GEOTYPE,&filter2,_fam_coords->getPointer())); + } + else + _fam_coords=0; + if(MEDmeshnEntity(fid,mName.c_str(),dt,it,MED_NODE,MED_NO_GEOTYPE,MED_NUMBER,MED_NODAL,&changement,&transformation)>0) + { + _num_coords=DataArrayInt::New(); + _num_coords->alloc(nbNodesToLoad,1); + MEDFILESAFECALLERRD0(MEDmeshEntityAttributeAdvancedRd,(fid,mName.c_str(),MED_NUMBER,dt,it,MED_NODE,MED_NO_GEOTYPE,&filter2,_num_coords->getPointer())); + } + else + _num_coords=0; + if(MEDmeshnEntity(fid,mName.c_str(),dt,it,MED_NODE,MED_NO_GEOTYPE,MED_NAME,MED_NODAL,&changement,&transformation)>0) + { + _name_coords=DataArrayAsciiChar::New(); + _name_coords->alloc(nbNodesToLoad+1,MED_SNAME_SIZE);//not a bug to avoid the memory corruption due to last \0 at the end + MEDFILESAFECALLERRD0(MEDmeshEntityAttributeAdvancedRd,(fid,mName.c_str(),MED_NAME,dt,it,MED_NODE,MED_NO_GEOTYPE,&filter2,_name_coords->getPointer())); + _name_coords->reAlloc(nbNodesToLoad);//not a bug to avoid the memory corruption due to last \0 at the end + } + else + _name_coords=0; + MEDfilterClose(&filter2); + _coords->setInfoOnComponents(infosOnComp); +} + +void MEDFileUMeshL2::sortTypes() +{ + std::set<int> mdims; + std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshPerType> > tmp(_per_type_mesh[0]); + _per_type_mesh.clear(); + for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshPerType> >::const_iterator it=tmp.begin();it!=tmp.end();it++) + mdims.insert((*it)->getDim()); + if(mdims.empty()) + return; + int mdim=*mdims.rbegin(); + _per_type_mesh.resize(mdim+1); + for(int dim=mdim+1;dim!=0;dim--) + { + std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshPerType> >& elt=_per_type_mesh[mdim+1-dim]; + for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshPerType> >::const_iterator it=tmp.begin();it!=tmp.end();it++) + if((*it)->getDim()==dim-1) + elt.push_back(*it); + } + // suppression of contiguous empty levels at the end of _per_type_mesh. + int nbOfUselessLev=0; + bool isFirst=true; + for(std::vector< std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshPerType> > >::reverse_iterator it2=_per_type_mesh.rbegin();it2!=_per_type_mesh.rend();it2++) + { + if((*it2).empty() && isFirst) + { + nbOfUselessLev++; + } + else + isFirst=false; + } + _per_type_mesh.resize(_per_type_mesh.size()-nbOfUselessLev); +} + +void MEDFileUMeshL2::WriteCoords(med_idt fid, const std::string& mname, int dt, int it, double time, const DataArrayDouble *coords, const DataArrayInt *famCoords, const DataArrayInt *numCoords, const DataArrayAsciiChar *nameCoords) +{ + if(!coords) + return ; + MEDFILESAFECALLERWR0(MEDmeshNodeCoordinateWr,(fid,mname.c_str(),dt,it,time,MED_FULL_INTERLACE,coords->getNumberOfTuples(),coords->getConstPointer())); + if(famCoords) + MEDFILESAFECALLERWR0(MEDmeshEntityFamilyNumberWr,(fid,mname.c_str(),dt,it,MED_NODE,MED_NO_GEOTYPE,famCoords->getNumberOfTuples(),famCoords->getConstPointer())); + if(numCoords) + MEDFILESAFECALLERWR0(MEDmeshEntityNumberWr,(fid,mname.c_str(),dt,it,MED_NODE,MED_NO_GEOTYPE,numCoords->getNumberOfTuples(),numCoords->getConstPointer())); + if(nameCoords) + { + if(nameCoords->getNumberOfComponents()!=MED_SNAME_SIZE) + { + std::ostringstream oss; oss << " MEDFileUMeshL2::WriteCoords : expected a name field on nodes with number of components set to " << MED_SNAME_SIZE; + oss << " ! The array has " << nameCoords->getNumberOfComponents() << " components !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + MEDFILESAFECALLERWR0(MEDmeshEntityNameWr,(fid,mname.c_str(),dt,it,MED_NODE,MED_NO_GEOTYPE,nameCoords->getNumberOfTuples(),nameCoords->getConstPointer())); + } +} + +bool MEDFileUMeshL2::isFamDefinedOnLev(int levId) const +{ + for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshPerType> >::const_iterator it=_per_type_mesh[levId].begin();it!=_per_type_mesh[levId].end();it++) + if((*it)->getFam()==0) + return false; + return true; +} + +bool MEDFileUMeshL2::isNumDefinedOnLev(int levId) const +{ + for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshPerType> >::const_iterator it=_per_type_mesh[levId].begin();it!=_per_type_mesh[levId].end();it++) + if((*it)->getNum()==0) + return false; + return true; +} + +bool MEDFileUMeshL2::isNamesDefinedOnLev(int levId) const +{ + for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshPerType> >::const_iterator it=_per_type_mesh[levId].begin();it!=_per_type_mesh[levId].end();it++) + if((*it)->getNames()==0) + return false; + return true; +} + +MEDFileCMeshL2::MEDFileCMeshL2() +{ +} + +void MEDFileCMeshL2::loadAll(med_idt fid, int mId, const std::string& mName, int dt, int it) +{ + _name.set(mName.c_str()); + int nstep; + int Mdim; + ParaMEDMEM::MEDCouplingMeshType meshType; + std::vector<std::string> infosOnComp=getAxisInfoOnMesh(fid,mId,mName.c_str(),meshType,nstep,Mdim); + if(meshType!=CARTESIAN) + throw INTERP_KERNEL::Exception("Invalid mesh type ! You are expected a structured one whereas in file it is not a structured !"); + _time=CheckMeshTimeStep(fid,mName,nstep,dt,it); + _iteration=dt; + _order=it; + // + med_grid_type gridtype; + MEDFILESAFECALLERRD0(MEDmeshGridTypeRd,(fid,mName.c_str(),&gridtype)); + if(gridtype!=MED_CARTESIAN_GRID) + throw INTERP_KERNEL::Exception("Invalid structured mesh ! Expected cartesian mesh type !"); + _cmesh=MEDCouplingCMesh::New(); + for(int i=0;i<Mdim;i++) + { + med_data_type dataTypeReq=GetDataTypeCorrespondingToSpaceId(i); + med_bool chgt=MED_FALSE,trsf=MED_FALSE; + int nbOfElt(MEDmeshnEntity(fid,mName.c_str(),dt,it,MED_NODE,MED_NONE,dataTypeReq,MED_NO_CMODE,&chgt,&trsf)); + MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> da=DataArrayDouble::New(); + da->alloc(nbOfElt,1); + da->setInfoOnComponent(0,infosOnComp[i]); + MEDFILESAFECALLERRD0(MEDmeshGridIndexCoordinateRd,(fid,mName.c_str(),dt,it,i+1,da->getPointer())); + _cmesh->setCoordsAt(i,da); + } +} + +med_data_type MEDFileCMeshL2::GetDataTypeCorrespondingToSpaceId(int id) +{ + switch(id) + { + case 0: + return MED_COORDINATE_AXIS1; + case 1: + return MED_COORDINATE_AXIS2; + case 2: + return MED_COORDINATE_AXIS3; + default: + throw INTERP_KERNEL::Exception("Invalid meshdim detected in Cartesian Grid !"); + } +} + +MEDFileCLMeshL2::MEDFileCLMeshL2() +{ +} + +void MEDFileCLMeshL2::loadAll(med_idt fid, int mId, const std::string& mName, int dt, int it) +{ + _name.set(mName.c_str()); + int nstep; + int Mdim; + ParaMEDMEM::MEDCouplingMeshType meshType; + std::vector<std::string> infosOnComp=getAxisInfoOnMesh(fid,mId,mName,meshType,nstep,Mdim); + if(meshType!=CURVE_LINEAR) + throw INTERP_KERNEL::Exception("Invalid mesh type ! You are expected a structured one whereas in file it is not a structured !"); + _time=CheckMeshTimeStep(fid,mName,nstep,dt,it); + _iteration=dt; + _order=it; + // + _clmesh=MEDCouplingCurveLinearMesh::New(); + INTERP_KERNEL::AutoPtr<int> stGrid=new int[Mdim]; + MEDFILESAFECALLERRD0(MEDmeshGridStructRd,(fid,mName.c_str(),dt,it,stGrid)); + _clmesh->setNodeGridStructure(stGrid,((int *)stGrid)+Mdim); + med_bool chgt=MED_FALSE,trsf=MED_FALSE; + int nbNodes(MEDmeshnEntity(fid,mName.c_str(),dt,it,MED_NODE,MED_NONE,MED_COORDINATE,MED_NO_CMODE,&chgt,&trsf)); + MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> da=DataArrayDouble::New(); + da->alloc(nbNodes,infosOnComp.size()); + da->setInfoOnComponents(infosOnComp); + MEDFILESAFECALLERRD0(MEDmeshNodeCoordinateRd,(fid,mName.c_str(),dt,it,MED_FULL_INTERLACE,da->getPointer())); + _clmesh->setCoords(da); +} + +MEDFileUMeshPermCompute::MEDFileUMeshPermCompute(const MEDFileUMeshSplitL1* st):_st(st),_mpt_time(0),_num_time(0) +{ +} + +/*! + * Warning it returns an instance to deallocate !!!! + */ +MEDFileUMeshPermCompute::operator MEDCouplingUMesh *() const +{ + _st->_num->updateTime(); + if((MEDCouplingUMesh *)_m==0) + { + updateTime(); + _m=static_cast<MEDCouplingUMesh *>(_st->_m_by_types.getUmesh()->deepCpy()); + _m->renumberCells(_st->_num->getConstPointer(),true); + return _m.retn(); + } + else + { + if(_mpt_time==_st->_m_by_types.getTimeOfThis() && _num_time==_st->_num->getTimeOfThis()) + return _m.retn(); + else + { + updateTime(); + _m=static_cast<MEDCouplingUMesh *>(_st->_m_by_types.getUmesh()->deepCpy()); + _m->renumberCells(_st->_num->getConstPointer(),true); + return _m.retn(); + } + } +} + +void MEDFileUMeshPermCompute::operator=(MEDCouplingUMesh *m) +{ + _m=m; +} + +void MEDFileUMeshPermCompute::updateTime() const +{ + _mpt_time=_st->_m_by_types.getTimeOfThis(); + _num_time=_st->_num->getTimeOfThis(); +} + +std::vector<const BigMemoryObject *> MEDFileUMeshPermCompute::getDirectChildrenWithNull() const +{ + std::vector<const BigMemoryObject *> ret; + ret.push_back((const MEDCouplingUMesh *)_m); + return ret; +} + +std::size_t MEDFileUMeshPermCompute::getHeapMemorySizeWithoutChildren() const +{ + return sizeof(MEDFileUMeshPermCompute); +} + +MEDFileUMeshSplitL1::MEDFileUMeshSplitL1(const MEDFileUMeshSplitL1& other):RefCountObject(other),_m_by_types(other._m_by_types),_fam(other._fam),_num(other._num),_names(other._names),_rev_num(other._rev_num),_m(this) +{ +} + +MEDFileUMeshSplitL1::MEDFileUMeshSplitL1(const MEDFileUMeshL2& l2, const std::string& mName, int id):_m(this) +{ + const std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshPerType> >& v=l2.getLev(id); + if(v.empty()) + return; + int sz=v.size(); + std::vector<const MEDCoupling1GTUMesh *> ms(sz); + std::vector<const DataArrayInt *> fams(sz),nums(sz); + std::vector<const DataArrayChar *> names(sz); + std::vector<const PartDefinition *> pds(sz); + for(int i=0;i<sz;i++) + { + MEDCoupling1GTUMesh *elt(v[i]->getMesh()); + MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> tmp2=l2.getCoords(); + elt->setCoords(tmp2); + ms[i]=elt; + pds[i]=v[i]->getPartDef(); + } + _m_by_types.assignParts(ms); + _m_by_types.assignDefParts(pds); + if(l2.isFamDefinedOnLev(id)) + { + for(int i=0;i<sz;i++) + fams[i]=v[i]->getFam(); + if(sz!=1) + _fam=DataArrayInt::Aggregate(fams); + else + { + fams[0]->incrRef(); + _fam=const_cast<DataArrayInt *>(fams[0]); + } + } + if(l2.isNumDefinedOnLev(id)) + { + for(int i=0;i<sz;i++) + nums[i]=v[i]->getNum(); + if(sz!=1) + _num=DataArrayInt::Aggregate(nums); + else + { + nums[0]->incrRef(); + _num=const_cast<DataArrayInt *>(nums[0]); + } + computeRevNum(); + } + if(l2.isNamesDefinedOnLev(id)) + { + for(int i=0;i<sz;i++) + names[i]=v[i]->getNames(); + _names=dynamic_cast<DataArrayAsciiChar *>(DataArrayChar::Aggregate(names)); + } +} + +MEDFileUMeshSplitL1::MEDFileUMeshSplitL1(MEDCoupling1GTUMesh *m):_m(this) +{ + std::vector< const MEDCoupling1GTUMesh * > v(1); + v[0]=m; + assignParts(v); +} + +MEDFileUMeshSplitL1::MEDFileUMeshSplitL1(MEDCouplingUMesh *m):_m(this) +{ + assignMesh(m,true); +} + +MEDFileUMeshSplitL1::MEDFileUMeshSplitL1(MEDCouplingUMesh *m, bool newOrOld):_m(this) +{ + assignMesh(m,newOrOld); +} + +void MEDFileUMeshSplitL1::setName(const std::string& name) +{ + _m_by_types.setName(name); +} + +std::size_t MEDFileUMeshSplitL1::getHeapMemorySizeWithoutChildren() const +{ + return 0; +} + +std::vector<const BigMemoryObject *> MEDFileUMeshSplitL1::getDirectChildrenWithNull() const +{ + std::vector<const BigMemoryObject *> ret; + ret.push_back(&_m_by_types); + ret.push_back(&_m); + ret.push_back((const DataArrayInt*)_fam); + ret.push_back((const DataArrayInt*)_num); + ret.push_back((const DataArrayInt*)_rev_num); + ret.push_back((const DataArrayAsciiChar*)_names); + return ret; +} + +MEDFileUMeshSplitL1 *MEDFileUMeshSplitL1::deepCpy(DataArrayDouble *coords) const +{ + MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> ret=new MEDFileUMeshSplitL1(*this); + ret->_m_by_types=_m_by_types.deepCpy(coords); + if((const DataArrayInt *)_fam) + ret->_fam=_fam->deepCpy(); + if((const DataArrayInt *)_num) + ret->_num=_num->deepCpy(); + if((const DataArrayInt *)_rev_num) + ret->_rev_num=_rev_num->deepCpy(); + if((const DataArrayAsciiChar *)_names) + ret->_names=_names->deepCpy(); + return ret.retn(); +} + +bool MEDFileUMeshSplitL1::isEqual(const MEDFileUMeshSplitL1 *other, double eps, std::string& what) const +{ + if(!_m_by_types.isEqual(other->_m_by_types,eps,what)) + return false; + const DataArrayInt *d1=_fam; + const DataArrayInt *d2=other->_fam; + if((d1==0 && d2!=0) || (d1!=0 && d2==0)) + { + what="Presence of family arr in one sublevel and not in other!"; + return false; + } + if(d1) + if(!d1->isEqual(*d2)) + { + what="family arr at a sublevel are not deeply equal !"; + return false; + } + d1=_num; + d2=other->_num; + if((d1==0 && d2!=0) || (d1!=0 && d2==0)) + { + what="Presence of cell numbering arr in one sublevel and not in other!"; + return false; + } + if(d1) + if(!d1->isEqual(*d2)) + { + what="Numbering cell arr at a sublevel are not deeply equal !"; + return false; + } + const DataArrayAsciiChar *e1=_names; + const DataArrayAsciiChar *e2=other->_names; + if((e1==0 && e2!=0) || (e1!=0 && e2==0)) + { + what="Presence of cell names arr in one sublevel and not in other!"; + return false; + } + if(e1) + if(!e1->isEqual(*e2)) + { + what="Name cell arr at a sublevel are not deeply equal !"; + return false; + } + return true; +} + +void MEDFileUMeshSplitL1::synchronizeTinyInfo(const MEDFileMesh& master) const +{ + _m_by_types.synchronizeTinyInfo(master); +} + +void MEDFileUMeshSplitL1::clearNonDiscrAttributes() const +{ + _m_by_types.clearNonDiscrAttributes(); +} + +void MEDFileUMeshSplitL1::ClearNonDiscrAttributes(const MEDCouplingMesh *tmp) +{ + if(!tmp) + return ; + (const_cast<MEDCouplingMesh *>(tmp))->setName(""); + (const_cast<MEDCouplingMesh *>(tmp))->setDescription(""); + (const_cast<MEDCouplingMesh *>(tmp))->setTime(0.,-1,-1); + (const_cast<MEDCouplingMesh *>(tmp))->setTimeUnit(""); +} + +void MEDFileUMeshSplitL1::setCoords(DataArrayDouble *coords) +{ + _m_by_types.setCoords(coords); +} + +void MEDFileUMeshSplitL1::assignMesh(MEDCouplingUMesh *m, bool newOrOld) +{ + if(newOrOld) + { + m->incrRef(); + _m=m; + _m_by_types.assignUMesh(dynamic_cast<MEDCouplingUMesh *>(m->deepCpy())); + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> da=_m_by_types.getUmesh()->getRenumArrForConsecutiveCellTypesSpec(typmai2,typmai2+MED_N_CELL_FIXED_GEO); + if(!da->isIdentity()) + { + _num=da->invertArrayO2N2N2O(m->getNumberOfCells()); + _m.updateTime(); + computeRevNum(); + _m_by_types.getUmesh()->renumberCells(da->getConstPointer(),false); + } + } + else + { + if(!m->checkConsecutiveCellTypesAndOrder(typmai2,typmai2+MED_N_CELL_FIXED_GEO)) + throw INTERP_KERNEL::Exception("MEDFileUMeshSplitL1::assignMesh : the mode of mesh setting expects to follow the MED file numbering convention ! it is not the case !"); + m->incrRef(); + _m_by_types.assignUMesh(m); + } + assignCommonPart(); +} + +void MEDFileUMeshSplitL1::forceComputationOfParts() const +{ + _m_by_types.forceComputationOfPartsFromUMesh(); +} + +void MEDFileUMeshSplitL1::assignParts(const std::vector< const MEDCoupling1GTUMesh * >& mParts) +{ + _m_by_types.assignParts(mParts); + assignCommonPart(); +} + +MEDFileUMeshSplitL1::MEDFileUMeshSplitL1():_m(this) +{ +} + +void MEDFileUMeshSplitL1::assignCommonPart() +{ + _fam=DataArrayInt::New(); + _fam->alloc(_m_by_types.getSize(),1); + _fam->fillWithValue(0); +} + +bool MEDFileUMeshSplitL1::empty() const +{ + return _m_by_types.empty(); +} + +bool MEDFileUMeshSplitL1::presenceOfOneFams(const std::vector<int>& ids) const +{ + const DataArrayInt *fam=_fam; + if(!fam) + return false; + return fam->presenceOfValue(ids); +} + +int MEDFileUMeshSplitL1::getMeshDimension() const +{ + return _m_by_types.getMeshDimension(); +} + +void MEDFileUMeshSplitL1::simpleRepr(std::ostream& oss) const +{ + std::vector<int> code=_m_by_types.getDistributionOfTypes(); + int nbOfTypes=code.size()/3; + for(int i=0;i<nbOfTypes;i++) + { + INTERP_KERNEL::NormalizedCellType typ=(INTERP_KERNEL::NormalizedCellType) code[3*i]; + oss << " - Number of cells with type " << INTERP_KERNEL::CellModel::GetCellModel(typ).getRepr() << " : " << code[3*i+1] << std::endl; + } +} + +int MEDFileUMeshSplitL1::getSize() const +{ + return _m_by_types.getSize(); +} + +MEDCouplingUMesh *MEDFileUMeshSplitL1::getFamilyPart(const int *idsBg, const int *idsEnd, bool renum) const +{ + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> eltsToKeep=_fam->getIdsEqualList(idsBg,idsEnd); + MEDCouplingUMesh *m=(MEDCouplingUMesh *)_m_by_types.getUmesh()->buildPartOfMySelf(eltsToKeep->getConstPointer(),eltsToKeep->getConstPointer()+eltsToKeep->getNumberOfTuples(),true); + if(renum) + return renumIfNeeded(m,eltsToKeep->getConstPointer()); + return m; +} + +DataArrayInt *MEDFileUMeshSplitL1::getFamilyPartArr(const int *idsBg, const int *idsEnd, bool renum) const +{ + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> da=_fam->getIdsEqualList(idsBg,idsEnd); + if(renum) + return renumIfNeededArr(da); + return da.retn(); +} + +std::vector<INTERP_KERNEL::NormalizedCellType> MEDFileUMeshSplitL1::getGeoTypes() const +{ + return _m_by_types.getGeoTypes(); +} + +MEDCouplingUMesh *MEDFileUMeshSplitL1::getWholeMesh(bool renum) const +{ + MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> tmp; + if(renum && ((const DataArrayInt *)_num)) + tmp=_m; + else + { tmp=_m_by_types.getUmesh(); if(tmp) tmp->incrRef(); } + return tmp.retn(); +} + +int MEDFileUMeshSplitL1::getNumberOfCells() const +{ + return _m_by_types.getNumberOfCells(); +} + +DataArrayInt *MEDFileUMeshSplitL1::extractFamilyFieldOnGeoType(INTERP_KERNEL::NormalizedCellType gt) const +{ + const DataArrayInt *fam(_fam); + if(!fam) + return 0; + int start(0),stop(0); + _m_by_types.getStartStopOfGeoTypeWithoutComputation(gt,start,stop); + return fam->selectByTupleId2(start,stop,1); +} + +DataArrayInt *MEDFileUMeshSplitL1::extractNumberFieldOnGeoType(INTERP_KERNEL::NormalizedCellType gt) const +{ + const DataArrayInt *num(_num); + if(!num) + return 0; + int start(0),stop(0); + _m_by_types.getStartStopOfGeoTypeWithoutComputation(gt,start,stop); + return num->selectByTupleId2(start,stop,1); +} + +DataArrayInt *MEDFileUMeshSplitL1::getOrCreateAndGetFamilyField() +{ + if((DataArrayInt *)_fam) + return _fam; + int nbOfTuples=_m_by_types.getSize(); + _fam=DataArrayInt::New(); _fam->alloc(nbOfTuples,1); _fam->fillWithZero(); + return _fam; +} + +const DataArrayInt *MEDFileUMeshSplitL1::getFamilyField() const +{ + return _fam; +} + +const DataArrayInt *MEDFileUMeshSplitL1::getNumberField() const +{ + return _num; +} + +const DataArrayInt *MEDFileUMeshSplitL1::getRevNumberField() const +{ + return _rev_num; +} + +const DataArrayAsciiChar *MEDFileUMeshSplitL1::getNameField() const +{ + return _names; +} + +const PartDefinition *MEDFileUMeshSplitL1::getPartDef(INTERP_KERNEL::NormalizedCellType gt) const +{ + return _m_by_types.getPartDefOfWithoutComputation(gt); +} + +void MEDFileUMeshSplitL1::eraseFamilyField() +{ + _fam->fillWithZero(); +} + +/*! + * This method ignores _m and _m_by_types. + */ +void MEDFileUMeshSplitL1::setGroupsFromScratch(const std::vector<const MEDCouplingUMesh *>& ms, std::map<std::string,int>& familyIds, + std::map<std::string, std::vector<std::string> >& groups) +{ + std::vector< DataArrayInt * > corr; + _m=MEDCouplingUMesh::FuseUMeshesOnSameCoords(ms,0,corr); + std::vector< MEDCouplingAutoRefCountObjectPtr<DataArrayInt> > corrMSafe(corr.begin(),corr.end()); + std::vector< std::vector<int> > fidsOfGroups; + std::vector< const DataArrayInt * > corr2(corr.begin(),corr.end()); + _fam=DataArrayInt::MakePartition(corr2,((MEDCouplingUMesh *)_m)->getNumberOfCells(),fidsOfGroups); + int nbOfCells=((MEDCouplingUMesh *)_m)->getNumberOfCells(); + std::map<int,std::string> newfams; + std::map<int,int> famIdTrad; + TraduceFamilyNumber(fidsOfGroups,familyIds,famIdTrad,newfams); + int *w=_fam->getPointer(); + for(int i=0;i<nbOfCells;i++,w++) + *w=famIdTrad[*w]; +} + +void MEDFileUMeshSplitL1::write(med_idt fid, const std::string& mName, int mdim) const +{ + std::vector<MEDCoupling1GTUMesh *> ms(_m_by_types.getParts()); + int start=0; + for(std::vector<MEDCoupling1GTUMesh *>::const_iterator it=ms.begin();it!=ms.end();it++) + { + int nbCells=(*it)->getNumberOfCells(); + int end=start+nbCells; + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> fam,num; + MEDCouplingAutoRefCountObjectPtr<DataArrayAsciiChar> names; + if((const DataArrayInt *)_fam) + fam=_fam->substr(start,end); + if((const DataArrayInt *)_num) + num=_num->substr(start,end); + if((const DataArrayAsciiChar *)_names) + names=static_cast<DataArrayAsciiChar *>(_names->substr(start,end)); + MEDFileUMeshPerType::Write(fid,mName,mdim,(*it),fam,num,names); + start=end; + } +} + +void MEDFileUMeshSplitL1::renumberNodesInConn(const int *newNodeNumbersO2N) +{ + _m_by_types.renumberNodesInConnWithoutComputation(newNodeNumbersO2N); +} + +void MEDFileUMeshSplitL1::serialize(std::vector<int>& tinyInt, std::vector< MEDCouplingAutoRefCountObjectPtr<DataArrayInt> >& bigArraysI) const +{ + bigArraysI.push_back(_fam); + bigArraysI.push_back(_num); + _m_by_types.serialize(tinyInt,bigArraysI); +} + +void MEDFileUMeshSplitL1::unserialize(const std::string& name, DataArrayDouble *coo, std::vector<int>& tinyInt, std::vector< MEDCouplingAutoRefCountObjectPtr<DataArrayInt> >& bigArraysI) +{ + _fam=bigArraysI.back(); bigArraysI.pop_back(); + _num=bigArraysI.back(); bigArraysI.pop_back(); + _m_by_types.unserialize(name,coo,tinyInt,bigArraysI); +} + +void MEDFileUMeshSplitL1::changeFamilyIdArr(int oldId, int newId) +{ + DataArrayInt *arr=_fam; + if(arr) + arr->changeValue(oldId,newId); +} + +void MEDFileUMeshSplitL1::setFamilyArr(DataArrayInt *famArr) +{ + if(!famArr) + { + _fam=0; + return ; + } + int sz(_m_by_types.getSize()); + famArr->checkNbOfTuplesAndComp(sz,1,"MEDFileUMeshSplitL1::setFamilyArr : Problem in size of Family arr ! "); + famArr->incrRef(); + _fam=famArr; +} + +DataArrayInt *MEDFileUMeshSplitL1::getFamilyField() +{ + return _fam; +} + +void MEDFileUMeshSplitL1::setRenumArr(DataArrayInt *renumArr) +{ + if(!renumArr) + { + _num=0; + _rev_num=0; + return ; + } + int sz(_m_by_types.getSize()); + renumArr->checkNbOfTuplesAndComp(sz,1,"MEDFileUMeshSplitL1::setRenumArr : Problem in size of numbering arr ! "); + renumArr->incrRef(); + _num=renumArr; + computeRevNum(); +} + +void MEDFileUMeshSplitL1::setNameArr(DataArrayAsciiChar *nameArr) +{ + if(!nameArr) + { + _names=0; + return ; + } + int sz(_m_by_types.getSize()); + nameArr->checkNbOfTuplesAndComp(sz,MED_SNAME_SIZE,"MEDFileUMeshSplitL1::setNameArr : Problem in size of name arr ! "); + nameArr->incrRef(); + _names=nameArr; +} + +MEDCouplingUMesh *MEDFileUMeshSplitL1::Renumber2(const DataArrayInt *renum, MEDCouplingUMesh *m, const int *cellIds) +{ + if(renum==0) + return m; + if(cellIds==0) + m->renumberCells(renum->getConstPointer(),true); + else + { + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> locnum=renum->selectByTupleId(cellIds,cellIds+m->getNumberOfCells()); + m->renumberCells(locnum->getConstPointer(),true); + } + return m; +} + +MEDFileUMeshSplitL1 *MEDFileUMeshSplitL1::Unserialize(const std::string& name, DataArrayDouble *coo, std::vector<int>& tinyInt, std::vector< MEDCouplingAutoRefCountObjectPtr<DataArrayInt> >& bigArraysI) +{ + MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshSplitL1> ret(new MEDFileUMeshSplitL1); + ret->unserialize(name,coo,tinyInt,bigArraysI); + return ret.retn(); +} + +MEDCouplingUMesh *MEDFileUMeshSplitL1::renumIfNeeded(MEDCouplingUMesh *m, const int *cellIds) const +{ + return Renumber2(_num,m,cellIds); +} + +DataArrayInt *MEDFileUMeshSplitL1::Renumber(const DataArrayInt *renum, const DataArrayInt *da) +{ + if((const DataArrayInt *)renum==0) + { + da->incrRef(); + return const_cast<DataArrayInt *>(da); + } + return renum->selectByTupleId(da->getConstPointer(),da->getConstPointer()+da->getNumberOfTuples()); +} + +DataArrayInt *MEDFileUMeshSplitL1::renumIfNeededArr(const DataArrayInt *da) const +{ + return Renumber(_num,da); +} + +std::vector<int> MEDFileUMeshSplitL1::GetNewFamiliesNumber(int nb, const std::map<std::string,int>& families) +{ + int id=-1; + for(std::map<std::string,int>::const_iterator it=families.begin();it!=families.end();it++) + id=std::max(id,(*it).second); + if(id==-1) + id=0; + std::vector<int> ret(nb); + for(int i=1;i<=nb;i++) + ret[i]=id+i; + return ret; +} + +void MEDFileUMeshSplitL1::TraduceFamilyNumber(const std::vector< std::vector<int> >& fidsGrps, std::map<std::string,int>& familyIds, + std::map<int,int>& famIdTrad, std::map<int,std::string>& newfams) +{ + std::set<int> allfids; + //tony +} + +void MEDFileUMeshSplitL1::computeRevNum() const +{ + int pos; + int maxValue=_num->getMaxValue(pos); + _rev_num=_num->invertArrayN2O2O2N(maxValue+1); +} + +//= + +MEDFileUMeshAggregateCompute::MEDFileUMeshAggregateCompute():_mp_time(0),_m_time(0) +{ +} + +void MEDFileUMeshAggregateCompute::setName(const std::string& name) +{ + if(_m_time>=_mp_time) + { + MEDCouplingUMesh *um(_m); + if(um) + um->setName(name); + } + if(_mp_time>=_m_time) + { + for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCoupling1GTUMesh> >::iterator it=_m_parts.begin();it!=_m_parts.end();it++) + { + MEDCoupling1GTUMesh *tmp(*it); + if(tmp) + tmp->setName(name); + } + } +} + +void MEDFileUMeshAggregateCompute::assignParts(const std::vector< const MEDCoupling1GTUMesh * >& mParts) +{ + std::size_t sz(mParts.size()); + std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCoupling1GTUMesh> > ret(sz); + for(std::size_t i=0;i<sz;i++) + { + const MEDCoupling1GTUMesh *elt(mParts[i]); + if(!elt) + throw INTERP_KERNEL::Exception("MEDFileUMeshAggregateCompute::assignParts : presence of null pointer !"); + ret[i]=const_cast<MEDCoupling1GTUMesh *>(elt); elt->incrRef(); + } + _m_parts=ret; + _part_def.clear(); _part_def.resize(sz); + _mp_time=std::max(_mp_time,_m_time)+1; + _m=0; +} + +void MEDFileUMeshAggregateCompute::assignDefParts(const std::vector<const PartDefinition *>& partDefs) +{ + if(_mp_time<_m_time) + throw INTERP_KERNEL::Exception("MEDFileUMeshAggregateCompute::assignDefParts : the parts require a computation !"); + std::size_t sz(partDefs.size()); + if(_part_def.size()!=partDefs.size() || _part_def.size()!=_m_parts.size()) + throw INTERP_KERNEL::Exception("MEDFileUMeshAggregateCompute::assignDefParts : sizes of vectors of part definition mismatch !"); + for(std::size_t i=0;i<sz;i++) + { + const PartDefinition *elt(partDefs[i]); + if(elt) + elt->incrRef(); + _part_def[i]=const_cast<PartDefinition*>(elt); + } +} + +void MEDFileUMeshAggregateCompute::assignUMesh(MEDCouplingUMesh *m) +{ + _m=m; + _m_parts.clear(); + _m_time=std::max(_mp_time,_m_time)+1; +} + +MEDCouplingUMesh *MEDFileUMeshAggregateCompute::getUmesh() const +{ + if(_mp_time<=_m_time) + return _m; + std::vector< const MEDCoupling1GTUMesh *> mp(_m_parts.size()); + std::copy(_m_parts.begin(),_m_parts.end(),mp.begin()); + _m=MEDCoupling1GTUMesh::AggregateOnSameCoordsToUMesh(mp); + _m_parts.clear();//to avoid memory peak ! + _m_time=_mp_time+1;//+1 is important ! That is to say that only _m is OK not _m_parts because cleared ! + return _m; +} + +int MEDFileUMeshAggregateCompute::getNumberOfCells() const +{ + if(_mp_time<=_m_time) + return _m->getNumberOfCells(); + int ret(0); + for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCoupling1GTUMesh> >::const_iterator it=_m_parts.begin();it!=_m_parts.end();it++) + ret+=(*it)->getNumberOfCells(); + return ret; +} + +std::vector<INTERP_KERNEL::NormalizedCellType> MEDFileUMeshAggregateCompute::getGeoTypes() const +{ + if(_mp_time>=_m_time) + { + std::size_t sz(_m_parts.size()); + std::vector<INTERP_KERNEL::NormalizedCellType> ret(sz); + for(std::size_t i=0;i<sz;i++) + ret[i]=_m_parts[i]->getCellModelEnum(); + return ret; + } + else + return _m->getAllGeoTypesSorted(); +} + +std::vector<MEDCoupling1GTUMesh *> MEDFileUMeshAggregateCompute::retrievePartsWithoutComputation() const +{ + if(_mp_time<_m_time) + throw INTERP_KERNEL::Exception("MEDFileUMeshAggregateCompute::getPartsWithoutComputation : the parts require a computation !"); + // + std::vector<MEDCoupling1GTUMesh *> ret(_m_parts.size()); + std::size_t i(0); + for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCoupling1GTUMesh> >::const_iterator it=_m_parts.begin();it!=_m_parts.end();it++,i++) + { + const MEDCoupling1GTUMesh *elt(*it); + ret[i]=const_cast<MEDCoupling1GTUMesh *>(elt); + } + return ret; +} + +std::vector<MEDCoupling1GTUMesh *> MEDFileUMeshAggregateCompute::getParts() const +{ + if(_mp_time<_m_time) + forceComputationOfPartsFromUMesh(); + return retrievePartsWithoutComputation(); +} + +MEDCoupling1GTUMesh *MEDFileUMeshAggregateCompute::retrievePartWithoutComputation(INTERP_KERNEL::NormalizedCellType gt) const +{ + std::vector<MEDCoupling1GTUMesh *> v(retrievePartsWithoutComputation()); + std::size_t sz(v.size()); + for(std::size_t i=0;i<sz;i++) + { + if(v[i]) + if(v[i]->getCellModelEnum()==gt) + return v[i]; + } + throw INTERP_KERNEL::Exception("MEDFileUMeshAggregateCompute::getPartWithoutComputation : the geometric type is not existing !"); +} + +void MEDFileUMeshAggregateCompute::getStartStopOfGeoTypeWithoutComputation(INTERP_KERNEL::NormalizedCellType gt, int& start, int& stop) const +{ + start=0; stop=0; + std::vector<MEDCoupling1GTUMesh *> v(retrievePartsWithoutComputation()); + std::size_t sz(v.size()); + for(std::size_t i=0;i<sz;i++) + { + if(v[i]) + { + if(v[i]->getCellModelEnum()==gt) + { + stop=start+v[i]->getNumberOfCells(); + return; + } + else + start+=v[i]->getNumberOfCells(); + } + } + throw INTERP_KERNEL::Exception("MEDFileUMeshAggregateCompute::getStartStopOfGeoTypeWithoutComputation : the geometric type is not existing !"); +} + +void MEDFileUMeshAggregateCompute::renumberNodesInConnWithoutComputation(const int *newNodeNumbersO2N) +{ + if(_mp_time>_m_time) + { + for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCoupling1GTUMesh> >::iterator it=_m_parts.begin();it!=_m_parts.end();it++) + { + MEDCoupling1GTUMesh *m(*it); + if(m) + m->renumberNodesInConn(newNodeNumbersO2N); + } + } + else + { + MEDCouplingUMesh *m(getUmesh()); + if(!m) + return; + m->renumberNodesInConn(newNodeNumbersO2N); + } +} + +void MEDFileUMeshAggregateCompute::forceComputationOfPartsFromUMesh() const +{ + const MEDCouplingUMesh *m(_m); + if(!m) + { + if(_m_parts.empty()) + throw INTERP_KERNEL::Exception("MEDFileUMeshAggregateCompute::forceComputationOfPartsFromUMesh : null UMesh !"); + else + return ;// no needs to compte parts they are already here ! + } + std::vector<MEDCouplingUMesh *> ms(m->splitByType()); + std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> > msMSafe(ms.begin(),ms.end()); + std::size_t sz(msMSafe.size()); + _m_parts.resize(sz); + for(std::size_t i=0;i<sz;i++) + _m_parts[i]=MEDCoupling1GTUMesh::New(ms[i]); + _part_def.clear(); + _part_def.resize(_m_parts.size()); + _mp_time=std::max(_mp_time,_m_time); +} + +const PartDefinition *MEDFileUMeshAggregateCompute::getPartDefOfWithoutComputation(INTERP_KERNEL::NormalizedCellType gt) const +{ + if(_mp_time<_m_time) + throw INTERP_KERNEL::Exception("MEDFileUMeshAggregateCompute::getPartDefOfWithoutComputation : the parts require a computation !"); + if(_m_parts.size()!=_part_def.size()) + throw INTERP_KERNEL::Exception("MEDFileUMeshAggregateCompute::getPartDefOfWithoutComputation : size of arrays are expected to be the same !"); + std::size_t sz(_m_parts.size()); + for(std::size_t i=0;i<sz;i++) + { + const MEDCoupling1GTUMesh *mesh(_m_parts[i]); + if(mesh) + if(mesh->getCellModelEnum()==gt) + return _part_def[i]; + } + throw INTERP_KERNEL::Exception("MEDFileUMeshAggregateCompute::getPartDefOfWithoutComputation : The input geo type is not existing in this !"); +} + +void MEDFileUMeshAggregateCompute::serialize(std::vector<int>& tinyInt, std::vector< MEDCouplingAutoRefCountObjectPtr<DataArrayInt> >& bigArraysI) const +{ + if(_mp_time<_m_time) + throw INTERP_KERNEL::Exception("MEDFileUMeshAggregateCompute::serialize : the parts require a computation !"); + std::size_t sz(_m_parts.size()); + tinyInt.push_back((int)sz); + for(std::size_t i=0;i<sz;i++) + { + const MEDCoupling1GTUMesh *mesh(_m_parts[i]); + if(!mesh) + throw INTERP_KERNEL::Exception("MEDFileUMeshAggregateCompute::serialize : one part is empty !"); + tinyInt.push_back(mesh->getCellModelEnum()); + const MEDCoupling1SGTUMesh *mesh1(dynamic_cast<const MEDCoupling1SGTUMesh *>(mesh)); + const MEDCoupling1DGTUMesh *mesh2(dynamic_cast<const MEDCoupling1DGTUMesh *>(mesh)); + if(mesh1) + { + DataArrayInt *elt(mesh1->getNodalConnectivity()); + if(elt) + elt->incrRef(); + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> elt1(elt); + bigArraysI.push_back(elt1); + } + else if(mesh2) + { + DataArrayInt *elt1(mesh2->getNodalConnectivity()),*elt2(mesh2->getNodalConnectivityIndex()); + if(elt1) + elt1->incrRef(); + if(elt2) + elt2->incrRef(); + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> elt11(elt1),elt22(elt2); + bigArraysI.push_back(elt11); bigArraysI.push_back(elt22); + } + else + throw INTERP_KERNEL::Exception("MEDFileUMeshAggregateCompute::serialize : unrecognized single geo type mesh !"); + const PartDefinition *pd(_part_def[i]); + if(!pd) + tinyInt.push_back(-1); + else + { + std::vector<int> tinyTmp; + pd->serialize(tinyTmp,bigArraysI); + tinyInt.push_back((int)tinyTmp.size()); + tinyInt.insert(tinyInt.end(),tinyTmp.begin(),tinyTmp.end()); + } + } +} + +void MEDFileUMeshAggregateCompute::unserialize(const std::string& name, DataArrayDouble *coo, std::vector<int>& tinyInt, std::vector< MEDCouplingAutoRefCountObjectPtr<DataArrayInt> >& bigArraysI) +{ + int nbParts(tinyInt.back()); tinyInt.pop_back(); + _part_def.clear(); _part_def.resize(nbParts); + _m_parts.clear(); _m_parts.resize(nbParts); + for(int i=0;i<nbParts;i++) + { + INTERP_KERNEL::NormalizedCellType tp((INTERP_KERNEL::NormalizedCellType) tinyInt.back()); tinyInt.pop_back(); + MEDCouplingAutoRefCountObjectPtr<MEDCoupling1GTUMesh> mesh(MEDCoupling1GTUMesh::New(name,tp)); + mesh->setCoords(coo); + MEDCoupling1SGTUMesh *mesh1(dynamic_cast<MEDCoupling1SGTUMesh *>((MEDCoupling1GTUMesh *) mesh)); + MEDCoupling1DGTUMesh *mesh2(dynamic_cast<MEDCoupling1DGTUMesh *>((MEDCoupling1GTUMesh *) mesh)); + if(mesh1) + { + mesh1->setNodalConnectivity(bigArraysI.back()); bigArraysI.pop_back(); + } + else if(mesh2) + { + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> elt0,elt1; + elt0=bigArraysI.back(); bigArraysI.pop_back(); + elt1=bigArraysI.back(); bigArraysI.pop_back(); + mesh2->setNodalConnectivity(elt0,elt1); + } + else + throw INTERP_KERNEL::Exception("MEDFileUMeshAggregateCompute::unserialize : unrecognized single geo type mesh !"); + _m_parts[i]=mesh; + int pdid(tinyInt.back()); tinyInt.pop_back(); + if(pdid!=-1) + _part_def[i]=PartDefinition::Unserialize(tinyInt,bigArraysI); + _mp_time=std::max(_mp_time,_m_time)+1; + } +} + +/*! + * This method returns true if \a this is stored split by type false if stored in a merged unstructured mesh. + */ +bool MEDFileUMeshAggregateCompute::isStoredSplitByType() const +{ + return _mp_time>=_m_time; +} + +std::size_t MEDFileUMeshAggregateCompute::getTimeOfThis() const +{ + if(_mp_time>_m_time) + return getTimeOfParts(); + if(_m_time>_mp_time) + return getTimeOfUMesh(); + return std::max(getTimeOfParts(),getTimeOfUMesh()); +} + +std::size_t MEDFileUMeshAggregateCompute::getTimeOfParts() const +{ + std::size_t ret(0); + for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCoupling1GTUMesh> >::const_iterator it=_m_parts.begin();it!=_m_parts.end();it++) + { + const MEDCoupling1GTUMesh *elt(*it); + if(!elt) + throw INTERP_KERNEL::Exception("MEDFileUMeshAggregateCompute::getTimeOfParts : null obj in parts !"); + ret=std::max(ret,elt->getTimeOfThis()); + } + if(ret==0) + throw INTERP_KERNEL::Exception("MEDFileUMeshAggregateCompute::getTimeOfParts : parts is empty !"); + return ret; +} + +std::size_t MEDFileUMeshAggregateCompute::getTimeOfUMesh() const +{ + const MEDCouplingUMesh *m(_m); + if(!m) + throw INTERP_KERNEL::Exception("MEDFileUMeshAggregateCompute::getTimeOfUMesh : unmesh is null !"); + return m->getTimeOfThis(); +} + +std::size_t MEDFileUMeshAggregateCompute::getHeapMemorySizeWithoutChildren() const +{ + std::size_t ret(_m_parts.size()*sizeof(MEDCouplingAutoRefCountObjectPtr<MEDCoupling1GTUMesh>)); + return ret; +} + +std::vector<const BigMemoryObject *> MEDFileUMeshAggregateCompute::getDirectChildrenWithNull() const +{ + std::vector<const BigMemoryObject *> ret; + for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCoupling1GTUMesh> >::const_iterator it=_m_parts.begin();it!=_m_parts.end();it++) + ret.push_back((const MEDCoupling1GTUMesh *)*it); + ret.push_back((const MEDCouplingUMesh *)_m); + return ret; +} + +MEDFileUMeshAggregateCompute MEDFileUMeshAggregateCompute::deepCpy(DataArrayDouble *coords) const +{ + MEDFileUMeshAggregateCompute ret; + ret._m_parts.resize(_m_parts.size()); + for(std::size_t i=0;i<_m_parts.size();i++) + { + const MEDCoupling1GTUMesh *elt(_m_parts[i]); + if(elt) + { + ret._m_parts[i]=static_cast<ParaMEDMEM::MEDCoupling1GTUMesh*>(elt->deepCpy()); + ret._m_parts[i]->setCoords(coords); + } + } + ret._mp_time=_mp_time; ret._m_time=_m_time; + if((const MEDCouplingUMesh *)_m) + { + ret._m=static_cast<ParaMEDMEM::MEDCouplingUMesh*>(_m->deepCpy()); + ret._m->setCoords(coords); + } + std::size_t sz(_part_def.size()); + ret._part_def.clear(); ret._part_def.resize(sz); + for(std::size_t i=0;i<sz;i++) + { + const PartDefinition *elt(_part_def[i]); + if(elt) + ret._part_def[i]=elt->deepCpy(); + } + return ret; +} + +bool MEDFileUMeshAggregateCompute::isEqual(const MEDFileUMeshAggregateCompute& other, double eps, std::string& what) const +{ + const MEDCouplingUMesh *m1(getUmesh()); + const MEDCouplingUMesh *m2(other.getUmesh()); + if((m1==0 && m2!=0) || (m1!=0 && m2==0)) + { + what="Presence of mesh in one sublevel and not in other!"; + return false; + } + if(m1) + { + std::string what2; + if(!m1->isEqualIfNotWhy(m2,eps,what2)) + { + what=std::string("meshes at a sublevel are not deeply equal (")+what2+std::string(")!"); + return false; + } + } + std::size_t sz(_part_def.size()); + if(sz!=other._part_def.size()) + { + what=std::string("number of subdivision per geo type for part definition is not the same !"); + return false; + } + for(std::size_t i=0;i<sz;i++) + { + const PartDefinition *pd0(_part_def[i]),*pd1(other._part_def[i]); + if(!pd0 && !pd1) + continue; + if((!pd0 && pd1) || (pd0 && !pd1)) + { + what=std::string("a cell part def is defined only for one among this or other !"); + return false; + } + bool ret(pd0->isEqual(pd1,what)); + if(!ret) + return false; + } + return true; +} + +void MEDFileUMeshAggregateCompute::clearNonDiscrAttributes() const +{ + for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCoupling1GTUMesh> >::const_iterator it=_m_parts.begin();it!=_m_parts.end();it++) + MEDFileUMeshSplitL1::ClearNonDiscrAttributes(*it); + MEDFileUMeshSplitL1::ClearNonDiscrAttributes(_m); +} + +void MEDFileUMeshAggregateCompute::synchronizeTinyInfo(const MEDFileMesh& master) const +{ + for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCoupling1GTUMesh> >::const_iterator it=_m_parts.begin();it!=_m_parts.end();it++) + { + const MEDCoupling1GTUMesh *tmp(*it); + if(tmp) + { + (const_cast<MEDCoupling1GTUMesh *>(tmp))->setName(master.getName().c_str()); + (const_cast<MEDCoupling1GTUMesh *>(tmp))->setDescription(master.getDescription().c_str()); + (const_cast<MEDCoupling1GTUMesh *>(tmp))->setTime(master.getTimeValue(),master.getIteration(),master.getOrder()); + (const_cast<MEDCoupling1GTUMesh *>(tmp))->setTimeUnit(master.getTimeUnit()); + } + } + const MEDCouplingUMesh *m(_m); + if(m) + { + (const_cast<MEDCouplingUMesh *>(m))->setName(master.getName().c_str()); + (const_cast<MEDCouplingUMesh *>(m))->setDescription(master.getDescription().c_str()); + (const_cast<MEDCouplingUMesh *>(m))->setTime(master.getTimeValue(),master.getIteration(),master.getOrder()); + (const_cast<MEDCouplingUMesh *>(m))->setTimeUnit(master.getTimeUnit()); + } +} + +bool MEDFileUMeshAggregateCompute::empty() const +{ + if(_mp_time<_m_time) + return ((const MEDCouplingUMesh *)_m)==0; + //else _mp_time>=_m_time) + return _m_parts.empty(); +} + +int MEDFileUMeshAggregateCompute::getMeshDimension() const +{ + if(_mp_time<_m_time) + { + const MEDCouplingUMesh *m(_m); + if(!m) + throw INTERP_KERNEL::Exception("MEDFileUMeshAggregateCompute::getMeshDimension : no umesh in this !"); + return m->getMeshDimension(); + } + else + { + if(_m_parts.empty()) + throw INTERP_KERNEL::Exception("MEDFileUMeshAggregateCompute::getMeshDimension : part mesh is empty !"); + const MEDCoupling1GTUMesh *m(_m_parts[0]); + if(!m) + throw INTERP_KERNEL::Exception("MEDFileUMeshAggregateCompute::getMeshDimension : part mesh contains null instance !"); + return m->getMeshDimension(); + } +} + +std::vector<int> MEDFileUMeshAggregateCompute::getDistributionOfTypes() const +{ + if(_mp_time<_m_time) + { + const MEDCouplingUMesh *m(_m); + if(!m) + throw INTERP_KERNEL::Exception("MEDFileUMeshAggregateCompute::getDistributionOfTypes : no umesh in this !"); + return m->getDistributionOfTypes(); + } + else + { + std::vector<int> ret; + for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCoupling1GTUMesh> >::const_iterator it=_m_parts.begin();it!=_m_parts.end();it++) + { + const MEDCoupling1GTUMesh *tmp(*it); + if(!tmp) + throw INTERP_KERNEL::Exception("MEDFileUMeshAggregateCompute::getDistributionOfTypes : part mesh contains null instance !"); + std::vector<int> ret0(tmp->getDistributionOfTypes()); + ret.insert(ret.end(),ret0.begin(),ret0.end()); + } + return ret; + } +} + +int MEDFileUMeshAggregateCompute::getSize() const +{ + if(_mp_time<_m_time) + { + const MEDCouplingUMesh *m(_m); + if(!m) + throw INTERP_KERNEL::Exception("MEDFileUMeshAggregateCompute::getSize : no umesh in this !"); + return m->getNumberOfCells(); + } + else + { + int ret=0; + for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCoupling1GTUMesh> >::const_iterator it=_m_parts.begin();it!=_m_parts.end();it++) + { + const MEDCoupling1GTUMesh *m(*it); + if(!m) + throw INTERP_KERNEL::Exception("MEDFileUMeshAggregateCompute::getSize : part mesh contains null instance !"); + ret+=m->getNumberOfCells(); + } + return ret; + } +} + +void MEDFileUMeshAggregateCompute::setCoords(DataArrayDouble *coords) +{ + for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCoupling1GTUMesh> >::iterator it=_m_parts.begin();it!=_m_parts.end();it++) + { + MEDCoupling1GTUMesh *tmp(*it); + if(tmp) + (*it)->setCoords(coords); + } + MEDCouplingUMesh *m(_m); + if(m) + m->setCoords(coords); +} diff --git a/src/medtool/src/MEDLoader/MEDFileMeshLL.hxx b/src/medtool/src/MEDLoader/MEDFileMeshLL.hxx new file mode 100644 index 000000000..b6872efc7 --- /dev/null +++ b/src/medtool/src/MEDLoader/MEDFileMeshLL.hxx @@ -0,0 +1,274 @@ +// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 +// 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 __MEDFILEMESHLL_HXX__ +#define __MEDFILEMESHLL_HXX__ + +#include "MEDFileBasis.hxx" +#include "MEDFileMeshElt.hxx" + +#include "MEDCouplingUMesh.hxx" +#include "MEDCouplingCMesh.hxx" +#include "MEDCoupling1GTUMesh.hxx" +#include "MEDCouplingPartDefinition.hxx" +#include "MEDCouplingCurveLinearMesh.hxx" +#include "MEDCouplingAutoRefCountObjectPtr.hxx" + +#include "med.h" + +#include <map> + +namespace ParaMEDMEM +{ + class MEDFileMeshReadSelector; + + class MEDFileMeshL2 : public RefCountObject + { + public: + MEDFileMeshL2(); + std::size_t getHeapMemorySizeWithoutChildren() const; + std::vector<const BigMemoryObject *> getDirectChildrenWithNull() const; + const char *getName() const { return _name.getReprForWrite(); } + const char *getDescription() const { return _description.getReprForWrite(); } + const char *getUnivName() const { return _univ_name.getReprForWrite(); } + const char *getTimeUnit() const { return _dt_unit.getReprForWrite(); } + int getIteration() const { return _iteration; } + int getOrder() const { return _order; } + double getTime() const { return _time; } + MEDCouplingAutoRefCountObjectPtr<PartDefinition> getPartDefOfCoo() const { return _part_coords; } + std::vector<std::string> getAxisInfoOnMesh(med_idt fid, int mId, const std::string& mName, ParaMEDMEM::MEDCouplingMeshType& meshType, int& nstep, int& Mdim); + static int GetMeshIdFromName(med_idt fid, const std::string& mName, ParaMEDMEM::MEDCouplingMeshType& meshType, int& dt, int& it, std::string& dtunit1); + static double CheckMeshTimeStep(med_idt fid, const std::string& mname, int nstep, int dt, int it); + static void ReadFamiliesAndGrps(med_idt fid, const std::string& mname, std::map<std::string,int>& fams, std::map<std::string, std::vector<std::string> >& grps, MEDFileMeshReadSelector *mrs); + static void WriteFamiliesAndGrps(med_idt fid, const std::string& mname, const std::map<std::string,int>& fams, const std::map<std::string, std::vector<std::string> >& grps, int tooLongStrPol); + protected: + MEDFileString _name; + MEDFileString _description; + MEDFileString _univ_name; + MEDFileString _dt_unit; + int _iteration; + int _order; + double _time; + MEDCouplingAutoRefCountObjectPtr<PartDefinition> _part_coords; + }; + + class MEDFileUMeshL2 : public MEDFileMeshL2 + { + public: + MEDFileUMeshL2(); + std::vector<std::string> loadCommonPart(med_idt fid, int mId, const std::string& mName, int dt, int it, int& Mdim); + void loadAll(med_idt fid, int mId, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs); + void loadPart(med_idt fid, int mId, const std::string& mName, const std::vector<INTERP_KERNEL::NormalizedCellType>& types, const std::vector<int>& slicPerTyp, int dt, int it, MEDFileMeshReadSelector *mrs); + void loadConnectivity(med_idt fid, int mdim, const std::string& mName, int dt, int it, MEDFileMeshReadSelector *mrs); + void loadPartOfConnectivity(med_idt fid, int mdim, const std::string& mName, const std::vector<INTERP_KERNEL::NormalizedCellType>& types, const std::vector<int>& slicPerTyp, int dt, int it, MEDFileMeshReadSelector *mrs); + void loadCoords(med_idt fid, int mId, const std::vector<std::string>& infosOnComp, const std::string& mName, int dt, int it); + void loadPartCoords(med_idt fid, int mId, const std::vector<std::string>& infosOnComp, const std::string& mName, int dt, int it, int nMin, int nMax); + int getNumberOfLevels() const { return _per_type_mesh.size(); } + bool emptyLev(int levId) const { return _per_type_mesh[levId].empty(); } + const std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshPerType> >& getLev(int levId) const { return _per_type_mesh[levId]; } + bool isFamDefinedOnLev(int levId) const; + bool isNumDefinedOnLev(int levId) const; + bool isNamesDefinedOnLev(int levId) const; + MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> getCoords() const { return _coords; } + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> getCoordsFamily() const { return _fam_coords; } + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> getCoordsNum() const { return _num_coords; } + MEDCouplingAutoRefCountObjectPtr<DataArrayAsciiChar> getCoordsName() const { return _name_coords; } + static void WriteCoords(med_idt fid, const std::string& mname, int dt, int it, double time, const DataArrayDouble *coords, const DataArrayInt *famCoords, const DataArrayInt *numCoords, const DataArrayAsciiChar *nameCoords); + private: + void sortTypes(); + private: + std::vector< std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileUMeshPerType> > > _per_type_mesh; + MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> _coords; + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> _fam_coords; + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> _num_coords; + MEDCouplingAutoRefCountObjectPtr<DataArrayAsciiChar> _name_coords; + }; + + class MEDFileStrMeshL2 : public MEDFileMeshL2 + { + }; + + class MEDFileCMeshL2 : public MEDFileStrMeshL2 + { + public: + MEDFileCMeshL2(); + void loadAll(med_idt fid, int mId, const std::string& mName, int dt, int it); + MEDCouplingCMesh *getMesh() { return _cmesh; } + private: + static med_data_type GetDataTypeCorrespondingToSpaceId(int id); + private: + MEDCouplingAutoRefCountObjectPtr<MEDCouplingCMesh> _cmesh; + }; + + class MEDFileCLMeshL2 : public MEDFileStrMeshL2 + { + public: + MEDFileCLMeshL2(); + void loadAll(med_idt fid, int mId, const std::string& mName, int dt, int it); + MEDCouplingCurveLinearMesh *getMesh() { return _clmesh; } + private: + MEDCouplingAutoRefCountObjectPtr<MEDCouplingCurveLinearMesh> _clmesh; + }; + + class MEDFileMesh; + class MEDFileUMeshSplitL1; + + class MEDFileUMeshPermCompute : public BigMemoryObject + { + public: + MEDFileUMeshPermCompute(const MEDFileUMeshSplitL1* st); + operator MEDCouplingUMesh *() const; + void operator=(MEDCouplingUMesh *m); + void updateTime() const; + std::vector<const BigMemoryObject *> getDirectChildrenWithNull() const; + std::size_t getHeapMemorySizeWithoutChildren() const; + private: + const MEDFileUMeshSplitL1 *_st; + mutable std::size_t _mpt_time; + mutable std::size_t _num_time; + mutable MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> _m; + }; + + class MEDFileUMeshAggregateCompute : public BigMemoryObject + { + public: + MEDFileUMeshAggregateCompute(); + void setName(const std::string& name); + void assignParts(const std::vector< const MEDCoupling1GTUMesh * >& mParts); + void assignDefParts(const std::vector<const PartDefinition *>& partDefs); + void assignUMesh(MEDCouplingUMesh *m); + MEDCouplingUMesh *getUmesh() const; + int getNumberOfCells() const; + std::vector<MEDCoupling1GTUMesh *> getParts() const; + std::vector<INTERP_KERNEL::NormalizedCellType> getGeoTypes() const; + std::vector<MEDCoupling1GTUMesh *> retrievePartsWithoutComputation() const; + MEDCoupling1GTUMesh *retrievePartWithoutComputation(INTERP_KERNEL::NormalizedCellType gt) const; + void getStartStopOfGeoTypeWithoutComputation(INTERP_KERNEL::NormalizedCellType gt, int& start, int& stop) const; + void renumberNodesInConnWithoutComputation(const int *newNodeNumbersO2N); + bool isStoredSplitByType() const; + std::size_t getTimeOfThis() const; + std::size_t getHeapMemorySizeWithoutChildren() const; + std::vector<const BigMemoryObject *> getDirectChildrenWithNull() const; + MEDFileUMeshAggregateCompute deepCpy(DataArrayDouble *coords) const; + bool isEqual(const MEDFileUMeshAggregateCompute& other, double eps, std::string& what) const; + void clearNonDiscrAttributes() const; + void synchronizeTinyInfo(const MEDFileMesh& master) const; + bool empty() const; + int getMeshDimension() const; + std::vector<int> getDistributionOfTypes() const; + int getSize() const; + void setCoords(DataArrayDouble *coords); + void forceComputationOfPartsFromUMesh() const; + const PartDefinition *getPartDefOfWithoutComputation(INTERP_KERNEL::NormalizedCellType gt) const; + void serialize(std::vector<int>& tinyInt, std::vector< MEDCouplingAutoRefCountObjectPtr<DataArrayInt> >& bigArraysI) const; + void unserialize(const std::string& name, DataArrayDouble *coo, std::vector<int>& tinyInt, std::vector< MEDCouplingAutoRefCountObjectPtr<DataArrayInt> >& bigArraysI); + private: + std::size_t getTimeOfParts() const; + std::size_t getTimeOfUMesh() const; + private: + mutable std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCoupling1GTUMesh> > _m_parts; + mutable std::size_t _mp_time; + mutable std::size_t _m_time; + mutable MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> _m; + mutable std::vector< MEDCouplingAutoRefCountObjectPtr<PartDefinition> > _part_def; + }; + + class MEDFileUMeshSplitL1 : public RefCountObject + { + friend class MEDFileUMeshPermCompute; + public: + MEDFileUMeshSplitL1(const MEDFileUMeshSplitL1& other); + MEDFileUMeshSplitL1(const MEDFileUMeshL2& l2, const std::string& mName, int id); + MEDFileUMeshSplitL1(MEDCoupling1GTUMesh *m); + MEDFileUMeshSplitL1(MEDCouplingUMesh *m); + MEDFileUMeshSplitL1(MEDCouplingUMesh *m, bool newOrOld); + void setName(const std::string& name); + std::size_t getHeapMemorySizeWithoutChildren() const; + std::vector<const BigMemoryObject *> getDirectChildrenWithNull() const; + MEDFileUMeshSplitL1 *deepCpy(DataArrayDouble *coords) const; + void setCoords(DataArrayDouble *coords); + bool isEqual(const MEDFileUMeshSplitL1 *other, double eps, std::string& what) const; + void clearNonDiscrAttributes() const; + void synchronizeTinyInfo(const MEDFileMesh& master) const; + void assignMesh(MEDCouplingUMesh *m, bool newOrOld); + void assignParts(const std::vector< const MEDCoupling1GTUMesh * >& mParts); + void forceComputationOfParts() const; + bool empty() const; + bool presenceOfOneFams(const std::vector<int>& ids) const; + int getMeshDimension() const; + void simpleRepr(std::ostream& oss) const; + int getSize() const; + MEDCouplingUMesh *getFamilyPart(const int *idsBg, const int *idsEnd, bool renum) const; + DataArrayInt *getFamilyPartArr(const int *idsBg, const int *idsEnd, bool renum) const; + MEDCouplingUMesh *getWholeMesh(bool renum) const; + int getNumberOfCells() const; + bool isMeshStoredSplitByType() const { return _m_by_types.isStoredSplitByType(); } + std::vector<INTERP_KERNEL::NormalizedCellType> getGeoTypes() const; + std::vector<MEDCoupling1GTUMesh *> getDirectUndergroundSingleGeoTypeMeshes() const { return _m_by_types.retrievePartsWithoutComputation(); } + MEDCoupling1GTUMesh *getDirectUndergroundSingleGeoTypeMesh(INTERP_KERNEL::NormalizedCellType gt) const { return _m_by_types.retrievePartWithoutComputation(gt); } + DataArrayInt *extractFamilyFieldOnGeoType(INTERP_KERNEL::NormalizedCellType gt) const; + DataArrayInt *extractNumberFieldOnGeoType(INTERP_KERNEL::NormalizedCellType gt) const; + std::vector<int> getDistributionOfTypes() const { return _m_by_types.getDistributionOfTypes(); } + DataArrayInt *getOrCreateAndGetFamilyField(); + const DataArrayInt *getFamilyField() const; + const DataArrayInt *getNumberField() const; + const DataArrayAsciiChar *getNameField() const; + const DataArrayInt *getRevNumberField() const; + const PartDefinition *getPartDef(INTERP_KERNEL::NormalizedCellType gt) const; + void eraseFamilyField(); + void setGroupsFromScratch(const std::vector<const MEDCouplingUMesh *>& ms, std::map<std::string,int>& familyIds, + std::map<std::string, std::vector<std::string> >& groups); + void write(med_idt fid, const std::string& mName, int mdim) const; + // + void setFamilyArr(DataArrayInt *famArr); + DataArrayInt *getFamilyField(); + void setRenumArr(DataArrayInt *renumArr); + void setNameArr(DataArrayAsciiChar *nameArr); + void changeFamilyIdArr(int oldId, int newId); + // + void renumberNodesInConn(const int *newNodeNumbersO2N); + // + void serialize(std::vector<int>& tinyInt, std::vector< MEDCouplingAutoRefCountObjectPtr<DataArrayInt> >& bigArraysI) const; + void unserialize(const std::string& name, DataArrayDouble *coo, std::vector<int>& tinyInt, std::vector< MEDCouplingAutoRefCountObjectPtr<DataArrayInt> >& bigArraysI); + // + static void ClearNonDiscrAttributes(const MEDCouplingMesh *tmp); + static std::vector<int> GetNewFamiliesNumber(int nb, const std::map<std::string,int>& families); + static void TraduceFamilyNumber(const std::vector< std::vector<int> >& fidsGrps, std::map<std::string,int>& familyIds, + std::map<int,int>& famIdTrad, std::map<int,std::string>& newfams); + static DataArrayInt *Renumber(const DataArrayInt *renum, const DataArrayInt *da); + static MEDCouplingUMesh *Renumber2(const DataArrayInt *renum, MEDCouplingUMesh *m, const int *cellIds); + static MEDFileUMeshSplitL1 *Unserialize(const std::string& name, DataArrayDouble *coo, std::vector<int>& tinyInt, std::vector< MEDCouplingAutoRefCountObjectPtr<DataArrayInt> >& bigArraysI); + private: + MEDFileUMeshSplitL1(); + void assignCommonPart(); + MEDCouplingUMesh *renumIfNeeded(MEDCouplingUMesh *m, const int *cellIds) const; + DataArrayInt *renumIfNeededArr(const DataArrayInt *da) const; + void computeRevNum() const; + private: + MEDFileUMeshAggregateCompute _m_by_types; + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> _fam; + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> _num; + MEDCouplingAutoRefCountObjectPtr<DataArrayAsciiChar> _names; + mutable MEDCouplingAutoRefCountObjectPtr<DataArrayInt> _rev_num; + MEDFileUMeshPermCompute _m; + }; +} + +#endif diff --git a/src/medtool/src/MEDLoader/MEDFileMeshReadSelector.cxx b/src/medtool/src/MEDLoader/MEDFileMeshReadSelector.cxx new file mode 100644 index 000000000..e7ac589b0 --- /dev/null +++ b/src/medtool/src/MEDLoader/MEDFileMeshReadSelector.cxx @@ -0,0 +1,145 @@ +// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 +// 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 "MEDFileMeshReadSelector.hxx" + +using namespace ParaMEDMEM; + +MEDFileMeshReadSelector::MEDFileMeshReadSelector():_code(0xFFFFFFFF) +{ +} + +MEDFileMeshReadSelector::MEDFileMeshReadSelector(unsigned int code):_code(code) +{ +} + +unsigned int MEDFileMeshReadSelector::getCode() const +{ + return _code; +} + +void MEDFileMeshReadSelector::setCode(unsigned int newCode) +{ + _code=newCode; +} + +bool MEDFileMeshReadSelector::isCellFamilyFieldReading() const +{ + return _code & 0x00000001; +} + +bool MEDFileMeshReadSelector::isNodeFamilyFieldReading() const +{ + return _code & 0x00000002; +} + +bool MEDFileMeshReadSelector::isCellNameFieldReading() const +{ + return _code & 0x00000004; +} + +bool MEDFileMeshReadSelector::isNodeNameFieldReading() const +{ + return _code & 0x00000008; +} + +bool MEDFileMeshReadSelector::isCellNumFieldReading() const +{ + return _code & 0x00000010; +} + +bool MEDFileMeshReadSelector::isNodeNumFieldReading() const +{ + return _code & 0x00000020; +} + +void MEDFileMeshReadSelector::setCellFamilyFieldReading(bool b) +{ + unsigned int code(_code & 0xFFFFFFFE); + unsigned int b2=b?1:0; + //b2<<=0; + code+=b2; + _code=code; +} + +void MEDFileMeshReadSelector::setNodeFamilyFieldReading(bool b) +{ + unsigned int code(_code & 0xFFFFFFFD); + unsigned int b2=b?1:0; + b2<<=1; + code+=b2; + _code=code; +} + +void MEDFileMeshReadSelector::setCellNameFieldReading(bool b) +{ + unsigned int code(_code & 0xFFFFFFFB); + unsigned int b2=b?1:0; + b2<<=2; + code+=b2; + _code=code; +} + +void MEDFileMeshReadSelector::setNodeNameFieldReading(bool b) +{ + unsigned int code(_code & 0xFFFFFFF7); + unsigned int b2=b?1:0; + b2<<=3; + code+=b2; + _code=code; +} + +void MEDFileMeshReadSelector::setCellNumFieldReading(bool b) +{ + unsigned int code(_code & 0xFFFFFFEF); + unsigned int b2=b?1:0; + b2<<=4; + code+=b2; + _code=code; +} + +void MEDFileMeshReadSelector::setNodeNumFieldReading(bool b) +{ + unsigned int code(_code & 0xFFFFFFDF); + unsigned int b2=b?1:0; + b2<<=5; + code+=b2; + _code=code; +} + +void MEDFileMeshReadSelector::reprAll(std::ostream& str) const +{ + str << "MEDFileMeshReadSelector (code=" << _code << ") : \n"; + str << "Read family field on cells : " << ReprStatus(isCellFamilyFieldReading()) << std::endl; + str << "Read family field on nodes : " << ReprStatus(isNodeFamilyFieldReading()) << std::endl; + str << "Read name field on cells : " << ReprStatus(isCellNameFieldReading()) << std::endl; + str << "Read name field on nodes : " << ReprStatus(isNodeNameFieldReading()) << std::endl; + str << "Read number field on cells : " << ReprStatus(isCellNumFieldReading()) << std::endl; + str << "Read number field name on nodes : " << ReprStatus(isNodeNumFieldReading()); +} + +std::string MEDFileMeshReadSelector::ReprStatus(bool v) +{ + if(v) + return std::string("ON"); + else + return std::string("OFF"); +} + diff --git a/src/medtool/src/MEDLoader/MEDFileMeshReadSelector.hxx b/src/medtool/src/MEDLoader/MEDFileMeshReadSelector.hxx new file mode 100644 index 000000000..2a90b7dc0 --- /dev/null +++ b/src/medtool/src/MEDLoader/MEDFileMeshReadSelector.hxx @@ -0,0 +1,64 @@ +// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 +// 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 __MEDFILEMESHREADSELECTOR_HXX__ +#define __MEDFILEMESHREADSELECTOR_HXX__ + +#include "MEDLoaderDefines.hxx" + +#include <sstream> +#include <string> + +namespace ParaMEDMEM +{ + class MEDLOADER_EXPORT MEDFileMeshReadSelector + { + public: + MEDFileMeshReadSelector(); + MEDFileMeshReadSelector(unsigned int code); + unsigned int getCode() const; + void setCode(unsigned int newCode); + bool isCellFamilyFieldReading() const; + bool isNodeFamilyFieldReading() const; + bool isCellNameFieldReading() const; + bool isNodeNameFieldReading() const; + bool isCellNumFieldReading() const; + bool isNodeNumFieldReading() const; + void setCellFamilyFieldReading(bool b); + void setNodeFamilyFieldReading(bool b); + void setCellNameFieldReading(bool b); + void setNodeNameFieldReading(bool b); + void setCellNumFieldReading(bool b); + void setNodeNumFieldReading(bool b); + void reprAll(std::ostream& str) const; + private: + static std::string ReprStatus(bool v); + private: + //bit #0 cell family field + //bit #1 node family field + //bit #2 cell name field + //bit #3 node name field + //bit #4 cell num field + //bit #5 node num field + unsigned int _code; + }; +} + +#endif diff --git a/src/medtool/src/MEDLoader/MEDFileParameter.cxx b/src/medtool/src/MEDLoader/MEDFileParameter.cxx new file mode 100644 index 000000000..d6aa3c46b --- /dev/null +++ b/src/medtool/src/MEDLoader/MEDFileParameter.cxx @@ -0,0 +1,920 @@ +// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 +// 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 "MEDFileParameter.hxx" +#include "MEDFileUtilities.hxx" +#include "MEDFileSafeCaller.txx" +#include "MEDLoaderBase.hxx" + +#include "InterpKernelAutoPtr.hxx" + +#include <set> + +using namespace ParaMEDMEM; + +MEDFileParameter1TS::MEDFileParameter1TS(int iteration, int order, double time):_iteration(iteration),_order(order),_time(time) +{ +} + +MEDFileParameter1TS::MEDFileParameter1TS():_iteration(-1),_order(-1),_time(0.) +{ +} + +bool MEDFileParameter1TS::isEqual(const MEDFileParameter1TS *other, double eps, std::string& what) const +{ + std::ostringstream oss; + if(!other) + { what="Other is null"; return false; } + if(_iteration!=other->_iteration) + { oss << "iteration number mismatches " << _iteration << " != " << other->_iteration; what=oss.str(); return false; } + if(_order!=other->_order) + { oss << "order number mismatches " << _iteration << " != " << other->_iteration; what=oss.str(); return false; } + if(fabs(_time-other->_time)>eps) + { oss << "time mismatches " << _time << " != " << other->_time << " eps=" << eps; what=oss.str(); return false; } + return true; +} + +MEDFileParameter1TS *MEDFileParameterDouble1TSWTI::deepCpy() const +{ + return new MEDFileParameterDouble1TSWTI(*this); +} + +bool MEDFileParameterDouble1TSWTI::isEqual(const MEDFileParameter1TS *other, double eps, std::string& what) const +{ + if(!MEDFileParameter1TS::isEqual(other,eps,what)) + return false; + const MEDFileParameterDouble1TSWTI *otherC=dynamic_cast<const MEDFileParameterDouble1TSWTI *>(other); + if(!otherC) + { what="IsEqual fails because this is double parameter other no !"; return false; } + if(fabs(_arr-otherC->_arr)>eps) + { std::ostringstream oss; oss << "value differ " << _arr << " != " << otherC->_arr << " (eps=" << eps << ")"; return false; } + return true; +} + +std::size_t MEDFileParameterDouble1TSWTI::getHeapMemorySizeWithoutChildren() const +{ + return sizeof(MEDFileParameterDouble1TSWTI); +} + +std::vector<const BigMemoryObject *> MEDFileParameterDouble1TSWTI::getDirectChildrenWithNull() const +{ + return std::vector<const BigMemoryObject *>(); +} + +std::string MEDFileParameterDouble1TSWTI::simpleRepr() const +{ + std::ostringstream oss; + simpleRepr2(0,oss); + return oss.str(); +} + +void MEDFileParameterDouble1TSWTI::simpleRepr2(int bkOffset, std::ostream& oss) const +{ + std::string startOfLine(bkOffset,' '); + oss << startOfLine << "ParameterDoubleItem with (iteration,order) = (" << _iteration << "," << _order << ")" << std::endl; + oss << startOfLine << "Time associacited = " << _time << std::endl; + oss << startOfLine << "The value is ***** " << _arr << " *****" << std::endl; +} + +MEDFileParameterDouble1TSWTI *MEDFileParameterDouble1TSWTI::New(int iteration, int order, double time) +{ + return new MEDFileParameterDouble1TSWTI(iteration,order,time); +} + +MEDFileParameterDouble1TSWTI::MEDFileParameterDouble1TSWTI():_arr(std::numeric_limits<double>::max()) +{ +} + +MEDFileParameterDouble1TSWTI::MEDFileParameterDouble1TSWTI(int iteration, int order, double time):MEDFileParameter1TS(iteration,order,time) +{ +} + +void MEDFileParameterDouble1TSWTI::finishLoading(med_idt fid, const std::string& name, int dt, int it, int nbOfSteps) +{ + std::ostringstream oss; oss << "MEDFileParameterDouble1TS::finishLoading : no specified time step (" << dt << "," << it << ") ! Time steps available : "; + for(int i=0;i<nbOfSteps;i++) + { + int locDt,locIt; + double tim; + MEDFILESAFECALLERRD0(MEDparameterComputationStepInfo,(fid,name.c_str(),i+1,&locDt,&locIt,&tim)); + if(dt==locDt && it==locIt) + { + _iteration=locDt; _order=locIt; _time=tim; + MEDFILESAFECALLERRD0(MEDparameterValueRd,(fid,name.c_str(),_iteration,_order,reinterpret_cast<unsigned char *const>(&_arr))); + return ; + } + else + { + oss << "(" << locDt << "," << locIt << ")"; + if(i!=nbOfSteps-1) + oss << ", "; + } + } + throw INTERP_KERNEL::Exception(oss.str().c_str()); +} + +void MEDFileParameterDouble1TSWTI::readValue(med_idt fid, const std::string& name) +{ + MEDFILESAFECALLERRD0(MEDparameterValueRd,(fid,name.c_str(),_iteration,_order,reinterpret_cast<unsigned char *const>(&_arr))); +} + +void MEDFileParameterDouble1TSWTI::finishLoading(med_idt fid, const std::string& name, int timeStepId) +{ + int locDt,locIt; + double dt; + MEDFILESAFECALLERRD0(MEDparameterComputationStepInfo,(fid,name.c_str(),timeStepId+1,&locDt,&locIt,&dt)); + _iteration=locDt; _order=locIt; _time=dt; + MEDFILESAFECALLERRD0(MEDparameterValueRd,(fid,name.c_str(),_iteration,_order,reinterpret_cast<unsigned char *const>(&_arr))); +} + +void MEDFileParameterDouble1TSWTI::writeLL(med_idt fid, const std::string& name, const MEDFileWritable& mw) const +{ + char nameW[MED_NAME_SIZE+1]; + MEDLoaderBase::safeStrCpy(name.c_str(),MED_NAME_SIZE,nameW,mw.getTooLongStrPolicy()); + MEDFILESAFECALLERWR0(MEDparameterValueWr,(fid,nameW,_iteration,_order,_time,reinterpret_cast<const unsigned char *>(&_arr))); +} + +std::size_t MEDFileParameterTinyInfo::getHeapMemSizeOfStrings() const +{ + return _dt_unit.capacity()+_name.capacity()+_desc_name.capacity(); +} + +bool MEDFileParameterTinyInfo::isEqualStrings(const MEDFileParameterTinyInfo& other, std::string& what) const +{ + std::ostringstream oss; + if(_name!=other._name) + { oss << "name differ ! this=" << _name << " and other=" << other._name; what=oss.str(); return false; } + if(_desc_name!=other._desc_name) + { oss << "name differ ! this=" << _desc_name << " and other=" << other._desc_name; what=oss.str(); return false; } + if(_dt_unit!=other._dt_unit) + { oss << "unit of time differ ! this=" << _dt_unit << " and other=" << other._dt_unit; what=oss.str(); return false; } + return true; +} + +void MEDFileParameterTinyInfo::writeLLHeader(med_idt fid, med_parameter_type typ) const +{ + char nameW[MED_NAME_SIZE+1],descW[MED_COMMENT_SIZE+1],dtunitW[MED_SNAME_SIZE+1]; + MEDLoaderBase::safeStrCpy(_name.c_str(),MED_NAME_SIZE,nameW,getTooLongStrPolicy()); + MEDLoaderBase::safeStrCpy(_desc_name.c_str(),MED_COMMENT_SIZE,descW,getTooLongStrPolicy()); + MEDLoaderBase::safeStrCpy(_dt_unit.c_str(),MED_SNAME_SIZE,dtunitW,getTooLongStrPolicy()); + MEDFILESAFECALLERWR0(MEDparameterCr,(fid,nameW,typ,descW,dtunitW)); +} + +void MEDFileParameterTinyInfo::mainRepr(int bkOffset, std::ostream& oss) const +{ + std::string startOfLine(bkOffset,' '); + oss << startOfLine << "Parameter with name \"" << _name << "\"" << std::endl; + oss << startOfLine << "Parameter with description \"" << _desc_name << "\"" << std::endl; + oss << startOfLine << "Parameter with unit name \"" << _dt_unit << "\"" << std::endl; +} + +MEDFileParameterDouble1TS *MEDFileParameterDouble1TS::New() +{ + return new MEDFileParameterDouble1TS; +} + +MEDFileParameterDouble1TS *MEDFileParameterDouble1TS::New(const std::string& fileName) +{ + return new MEDFileParameterDouble1TS(fileName); +} + +MEDFileParameterDouble1TS *MEDFileParameterDouble1TS::New(const std::string& fileName, const std::string& paramName) +{ + return new MEDFileParameterDouble1TS(fileName,paramName); +} + +MEDFileParameterDouble1TS *MEDFileParameterDouble1TS::New(const std::string& fileName, const std::string& paramName, int dt, int it) +{ + return new MEDFileParameterDouble1TS(fileName,paramName,dt,it); +} + +MEDFileParameterDouble1TS::MEDFileParameterDouble1TS() +{ +} + +MEDFileParameterDouble1TS::MEDFileParameterDouble1TS(const std::string& fileName, const std::string& paramName, int dt, int it) +{ + MEDFileUtilities::CheckFileForRead(fileName); + MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName.c_str(),MED_ACC_RDONLY); + int nbPar=MEDnParameter(fid); + std::ostringstream oss; oss << "MEDFileParameterDouble1TS : no double param name \"" << paramName << "\" ! Double Parameters available are : "; + INTERP_KERNEL::AutoPtr<char> pName=MEDLoaderBase::buildEmptyString(MED_NAME_SIZE); + INTERP_KERNEL::AutoPtr<char> descName=MEDLoaderBase::buildEmptyString(MED_COMMENT_SIZE); + INTERP_KERNEL::AutoPtr<char> unitName=MEDLoaderBase::buildEmptyString(MED_SNAME_SIZE); + med_parameter_type paramType; + for(int i=0;i<nbPar;i++) + { + int nbOfSteps; + MEDFILESAFECALLERRD0(MEDparameterInfo,(fid,i+1,pName,¶mType,descName,unitName,&nbOfSteps)); + std::string paramNameCpp=MEDLoaderBase::buildStringFromFortran(pName,MED_NAME_SIZE); + if(paramNameCpp==paramName && paramType==MED_FLOAT64) + { + _dt_unit=MEDLoaderBase::buildStringFromFortran(unitName,MED_SNAME_SIZE); + _name=paramNameCpp; + _desc_name=MEDLoaderBase::buildStringFromFortran(descName,MED_COMMENT_SIZE); + finishLoading(fid,_name,dt,it,nbOfSteps); + return ; + } + else + { + oss << paramNameCpp; + if(i!=nbPar-1) oss << ", "; + } + } + throw INTERP_KERNEL::Exception(oss.str().c_str()); +} + +MEDFileParameterDouble1TS::MEDFileParameterDouble1TS(const std::string& fileName, const std::string& paramName) +{ + MEDFileUtilities::CheckFileForRead(fileName); + MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName.c_str(),MED_ACC_RDONLY); + int nbPar=MEDnParameter(fid); + std::ostringstream oss; oss << "MEDFileParameterDouble1TS : no double param name \"" << paramName << "\" ! Double Parameters available are : "; + INTERP_KERNEL::AutoPtr<char> pName=MEDLoaderBase::buildEmptyString(MED_NAME_SIZE); + INTERP_KERNEL::AutoPtr<char> descName=MEDLoaderBase::buildEmptyString(MED_COMMENT_SIZE); + INTERP_KERNEL::AutoPtr<char> unitName=MEDLoaderBase::buildEmptyString(MED_SNAME_SIZE); + med_parameter_type paramType; + for(int i=0;i<nbPar;i++) + { + int nbOfSteps; + MEDFILESAFECALLERRD0(MEDparameterInfo,(fid,i+1,pName,¶mType,descName,unitName,&nbOfSteps)); + std::string paramNameCpp=MEDLoaderBase::buildStringFromFortran(pName,MED_NAME_SIZE); + if(paramNameCpp==paramName && paramType==MED_FLOAT64) + { + if(nbOfSteps>0) + { + _dt_unit=MEDLoaderBase::buildStringFromFortran(unitName,MED_SNAME_SIZE); + _name=paramNameCpp; + _desc_name=MEDLoaderBase::buildStringFromFortran(descName,MED_COMMENT_SIZE); + finishLoading(fid,_name,0); + return ; + } + else + { + std::ostringstream oss2; oss2 << "Param name \"" << paramName << "\" exists but no time steps on it !"; + throw INTERP_KERNEL::Exception(oss2.str().c_str()); + } + } + else + { + oss << paramNameCpp; + if(i!=nbPar-1) oss << ", "; + } + } + throw INTERP_KERNEL::Exception(oss.str().c_str()); +} + +MEDFileParameterDouble1TS::MEDFileParameterDouble1TS(const std::string& fileName) +{ + MEDFileUtilities::CheckFileForRead(fileName); + MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName.c_str(),MED_ACC_RDONLY); + int nbPar=MEDnParameter(fid); + if(nbPar<1) + { + std::ostringstream oss2; oss2 << "No parameter in file \"" << fileName << "\" !"; + throw INTERP_KERNEL::Exception(oss2.str().c_str()); + } + INTERP_KERNEL::AutoPtr<char> pName=MEDLoaderBase::buildEmptyString(MED_NAME_SIZE); + INTERP_KERNEL::AutoPtr<char> descName=MEDLoaderBase::buildEmptyString(MED_COMMENT_SIZE); + INTERP_KERNEL::AutoPtr<char> unitName=MEDLoaderBase::buildEmptyString(MED_SNAME_SIZE); + med_parameter_type paramType; + int nbOfSteps; + MEDFILESAFECALLERRD0(MEDparameterInfo,(fid,1,pName,¶mType,descName,unitName,&nbOfSteps)); + std::string paramNameCpp=MEDLoaderBase::buildStringFromFortran(pName,MED_NAME_SIZE); + if(paramType==MED_FLOAT64) + { + if(nbOfSteps>0) + { + _dt_unit=MEDLoaderBase::buildStringFromFortran(unitName,MED_SNAME_SIZE); + _name=paramNameCpp; + _desc_name=MEDLoaderBase::buildStringFromFortran(descName,MED_COMMENT_SIZE); + finishLoading(fid,_name,0); + return ; + } + else + { + std::ostringstream oss2; oss2 << "Double param name \"" << paramNameCpp << "\" exists in file \""<< fileName << "\"but no time steps on it !"; + throw INTERP_KERNEL::Exception(oss2.str().c_str()); + } + } + else + { + std::ostringstream oss2; oss2 << "First parameter in file \"" << fileName << "\" is not double !"; + throw INTERP_KERNEL::Exception(oss2.str().c_str()); + } +} + +bool MEDFileParameterDouble1TS::isEqual(const MEDFileParameter1TS *other, double eps, std::string& what) const +{ + if(!MEDFileParameterDouble1TSWTI::isEqual(other,eps,what)) + return false; + const MEDFileParameterDouble1TS *otherC=dynamic_cast<const MEDFileParameterDouble1TS *>(other); + if(!otherC) + { what="Other is not of type MEDFileParameterDouble1TS as this"; return false; } + if(!isEqualStrings(*otherC,what)) + return false; + return true; +} + +MEDFileParameter1TS *MEDFileParameterDouble1TS::deepCpy() const +{ + return new MEDFileParameterDouble1TS(*this); +} + +std::string MEDFileParameterDouble1TS::simpleRepr() const +{ + std::ostringstream oss; + MEDFileParameterTinyInfo::mainRepr(0,oss); + MEDFileParameterDouble1TSWTI::simpleRepr2(0,oss); + return oss.str(); +} + +std::size_t MEDFileParameterDouble1TS::getHeapMemorySizeWithoutChildren() const +{ + return getHeapMemSizeOfStrings()+sizeof(MEDFileParameterDouble1TS); +} + +std::vector<const BigMemoryObject *> MEDFileParameterDouble1TS::getDirectChildrenWithNull() const +{ + return std::vector<const BigMemoryObject *>(); +} + +void MEDFileParameterDouble1TS::write(const std::string& fileName, int mode) const +{ + med_access_mode medmod=MEDFileUtilities::TraduceWriteMode(mode); + MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName.c_str(),medmod); + MEDFileParameterTinyInfo::writeLLHeader(fid,MED_FLOAT64); + MEDFileParameterDouble1TSWTI::writeLL(fid,_name,*this); +} + +MEDFileParameterMultiTS *MEDFileParameterMultiTS::New() +{ + return new MEDFileParameterMultiTS; +} + +MEDFileParameterMultiTS *MEDFileParameterMultiTS::New(const std::string& fileName) +{ + return new MEDFileParameterMultiTS(fileName); +} + +MEDFileParameterMultiTS *MEDFileParameterMultiTS::New(const std::string& fileName, const std::string& paramName) +{ + return new MEDFileParameterMultiTS(fileName,paramName); +} + +MEDFileParameterMultiTS::MEDFileParameterMultiTS() +{ +} + +MEDFileParameterMultiTS::MEDFileParameterMultiTS(const MEDFileParameterMultiTS& other, bool deepCopy):MEDFileParameterTinyInfo(other),_param_per_ts(other._param_per_ts) +{ + if(deepCopy) + for(std::size_t i=0;i<_param_per_ts.size();i++) + { + const MEDFileParameter1TS *elt=_param_per_ts[i]; + if(elt) + _param_per_ts[i]=elt->deepCpy(); + } +} + +MEDFileParameterMultiTS::MEDFileParameterMultiTS(const std::string& fileName) +{ + MEDFileUtilities::CheckFileForRead(fileName); + MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName.c_str(),MED_ACC_RDONLY); + int nbPar=MEDnParameter(fid); + if(nbPar<1) + { + std::ostringstream oss; oss << "MEDFileParameterMultiTS : no parameter in file \"" << fileName << "\" !" ; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + INTERP_KERNEL::AutoPtr<char> pName=MEDLoaderBase::buildEmptyString(MED_NAME_SIZE); + INTERP_KERNEL::AutoPtr<char> descName=MEDLoaderBase::buildEmptyString(MED_COMMENT_SIZE); + INTERP_KERNEL::AutoPtr<char> unitName=MEDLoaderBase::buildEmptyString(MED_SNAME_SIZE); + med_parameter_type paramType; + int nbOfSteps; + MEDFILESAFECALLERRD0(MEDparameterInfo,(fid,1,pName,¶mType,descName,unitName,&nbOfSteps)); + std::string paramNameCpp=MEDLoaderBase::buildStringFromFortran(pName,MED_NAME_SIZE); + _dt_unit=MEDLoaderBase::buildStringFromFortran(unitName,MED_SNAME_SIZE); + _name=paramNameCpp; + _desc_name=MEDLoaderBase::buildStringFromFortran(descName,MED_COMMENT_SIZE); + finishLoading(fid,paramType,nbOfSteps); +} + +MEDFileParameterMultiTS::MEDFileParameterMultiTS(const std::string& fileName, const std::string& paramName) +{ + MEDFileUtilities::CheckFileForRead(fileName); + MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName.c_str(),MED_ACC_RDONLY); + int nbPar=MEDnParameter(fid); + std::ostringstream oss; oss << "MEDFileParameterDouble1TS : no double param name \"" << paramName << "\" ! Double Parameters available are : "; + INTERP_KERNEL::AutoPtr<char> pName=MEDLoaderBase::buildEmptyString(MED_NAME_SIZE); + INTERP_KERNEL::AutoPtr<char> descName=MEDLoaderBase::buildEmptyString(MED_COMMENT_SIZE); + INTERP_KERNEL::AutoPtr<char> unitName=MEDLoaderBase::buildEmptyString(MED_SNAME_SIZE); + med_parameter_type paramType; + for(int i=0;i<nbPar;i++) + { + int nbOfSteps; + MEDFILESAFECALLERRD0(MEDparameterInfo,(fid,i+1,pName,¶mType,descName,unitName,&nbOfSteps)); + std::string paramNameCpp=MEDLoaderBase::buildStringFromFortran(pName,MED_NAME_SIZE); + if(paramNameCpp==paramName) + { + if(nbOfSteps>0) + { + _dt_unit=MEDLoaderBase::buildStringFromFortran(unitName,MED_SNAME_SIZE); + _name=paramNameCpp; + _desc_name=MEDLoaderBase::buildStringFromFortran(descName,MED_COMMENT_SIZE); + finishLoading(fid,paramType,nbOfSteps); + return ; + } + else + { + std::ostringstream oss2; oss2 << "Param name \"" << paramName << "\" exists but no time steps on it !"; + throw INTERP_KERNEL::Exception(oss2.str().c_str()); + } + } + else + { + oss << paramNameCpp; + if(i!=nbPar-1) oss << ", "; + } + } + throw INTERP_KERNEL::Exception(oss.str().c_str()); +} + +void MEDFileParameterMultiTS::finishLoading(med_idt fid, med_parameter_type typ, int nbOfSteps) +{ + _param_per_ts.resize(nbOfSteps); + for(int i=0;i<nbOfSteps;i++) + { + int dt,it; + double tim; + MEDFILESAFECALLERRD0(MEDparameterComputationStepInfo,(fid,_name.c_str(),i+1,&dt,&it,&tim)); + switch(typ) + { + case MED_FLOAT64: + _param_per_ts[i]=MEDFileParameterDouble1TSWTI::New(dt,it,tim); + _param_per_ts[i]->readValue(fid,_name.c_str()); + break; + /*case MED_INT32; + _param_per_ts[i]=; + break;*/ + default: + throw INTERP_KERNEL::Exception("MEDFileParameterMultiTS::finishLoading : supporting only FLOAT64 !"); + } + } +} + +std::size_t MEDFileParameterMultiTS::getHeapMemorySizeWithoutChildren() const +{ + std::size_t ret(sizeof(MEDFileParameterMultiTS)); + ret+=sizeof(MEDCouplingAutoRefCountObjectPtr<MEDFileParameter1TS>)*_param_per_ts.capacity(); + return ret; +} + +std::vector<const BigMemoryObject *> MEDFileParameterMultiTS::getDirectChildrenWithNull() const +{ + std::vector<const BigMemoryObject *> ret; + for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileParameter1TS> >::const_iterator it=_param_per_ts.begin();it!=_param_per_ts.end();it++) + ret.push_back((const MEDFileParameter1TS *)*it); + return ret; +} + +MEDFileParameterMultiTS *MEDFileParameterMultiTS::deepCpy() const +{ + return new MEDFileParameterMultiTS(*this,true); +} + +bool MEDFileParameterMultiTS::isEqual(const MEDFileParameterMultiTS *other, double eps, std::string& what) const +{ + if(!other) + { what="other is null !"; return false; } + if(_param_per_ts.size()!=other->_param_per_ts.size()) + { what="number of time steps differs !"; return false; } + std::ostringstream oss; + for(std::size_t i=0;i<_param_per_ts.size();i++) + { + const MEDFileParameter1TS *a(_param_per_ts[i]),*b(other->_param_per_ts[i]); + if((a && !b) || (!a && b)) + { oss << "At time step id #" << i << " pointer is defined on one side not in the other !"; what=oss.str(); return false; } + if(a) + if(!a->isEqual(b,eps,what)) + { oss << " At time step id #" << i << " non equality !"; what+=oss.str(); return false; } + } + return true; +} + +void MEDFileParameterMultiTS::write(const std::string& fileName, int mode) const +{ + med_access_mode medmod=MEDFileUtilities::TraduceWriteMode(mode); + MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName.c_str(),medmod); + writeLL(fid,*this); +} + +void MEDFileParameterMultiTS::writeLL(med_idt fid, const MEDFileWritable& mw) const +{ + std::set<med_parameter_type> diffType; + for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileParameter1TS> >::const_iterator it=_param_per_ts.begin();it!=_param_per_ts.end();it++) + { + const MEDFileParameter1TS *elt(*it); + if(dynamic_cast<const MEDFileParameterDouble1TSWTI *>(elt)) + diffType.insert(MED_FLOAT64); + } + if(diffType.size()>1) + throw INTERP_KERNEL::Exception("MEDFileParameterMultiTS::writeLL : impossible to mix type of data in parameters in MED file ! Only float64 or only int32 ..."); + if(diffType.empty()) + return; + med_parameter_type typ=*diffType.begin(); + MEDFileParameterTinyInfo::writeLLHeader(fid,typ); + for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileParameter1TS> >::const_iterator it=_param_per_ts.begin();it!=_param_per_ts.end();it++) + { + const MEDFileParameter1TS *elt(*it); + if(elt) + elt->writeLL(fid,_name,mw); + } +} + +std::string MEDFileParameterMultiTS::simpleRepr() const +{ + std::ostringstream oss; + simpleRepr2(0,oss); + return oss.str(); +} + +void MEDFileParameterMultiTS::simpleRepr2(int bkOffset, std::ostream& oss) const +{ + MEDFileParameterTinyInfo::mainRepr(bkOffset,oss); + for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileParameter1TS> >::const_iterator it=_param_per_ts.begin();it!=_param_per_ts.end();it++) + { + const MEDFileParameter1TS *elt(*it); + if(elt) + elt->simpleRepr2(bkOffset+2,oss); + } +} + +void MEDFileParameterMultiTS::appendValue(int dt, int it, double time, double val) +{ + MEDCouplingAutoRefCountObjectPtr<MEDFileParameterDouble1TSWTI> elt=MEDFileParameterDouble1TSWTI::New(dt,it,time); + elt->setValue(val); + MEDCouplingAutoRefCountObjectPtr<MEDFileParameter1TS> elt2((MEDFileParameterDouble1TSWTI*)elt); elt2->incrRef(); + _param_per_ts.push_back(elt2); +} + +double MEDFileParameterMultiTS::getDoubleValue(int iteration, int order) const +{ + int pos=getPosOfTimeStep(iteration,order); + const MEDFileParameter1TS *elt=_param_per_ts[pos]; + if(!elt) + { + std::ostringstream oss; oss << "MEDFileParameterMultiTS::getDoubleValue : time iteration it=" << iteration << " order=" << order; + oss << " exists but elt is empty !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + const MEDFileParameterDouble1TSWTI *eltC=dynamic_cast<const MEDFileParameterDouble1TSWTI *>(elt); + if(!eltC) + { + std::ostringstream oss; oss << "MEDFileParameterMultiTS::getDoubleValue : time iteration it=" << iteration << " order=" << order; + oss << " exists but not double !"; + } + return eltC->getValue(); +} + +int MEDFileParameterMultiTS::getPosOfTimeStep(int iteration, int order) const +{ + int ret=0; + std::ostringstream oss; oss << "MEDFileParameterMultiTS::getPosOfTimeStep : no such iteration=" << iteration << " order=" << order << " ! Possibilities are :"; + for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileParameter1TS> >::const_iterator it=_param_per_ts.begin();it!=_param_per_ts.end();it++,ret++) + { + const MEDFileParameter1TS *elt(*it); + if(elt) + { + if(elt->getIteration()==iteration && elt->getOrder()==order) + return ret; + else + oss << "(" << elt->getIteration() << "," << elt->getOrder() << "), "; + } + } + throw INTERP_KERNEL::Exception(oss.str().c_str()); +} + +int MEDFileParameterMultiTS::getPosGivenTime(double time, double eps) const +{ + int ret=0; + std::ostringstream oss; oss << "MEDFileParameterMultiTS::getPosGivenTime : no such time=" << time << " ! Possibilities are :"; + for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileParameter1TS> >::const_iterator it=_param_per_ts.begin();it!=_param_per_ts.end();it++,ret++) + { + const MEDFileParameter1TS *elt(*it); + if(elt) + { + if(fabs(elt->getTimeValue()-time)<=eps) + return ret; + else + oss << elt->getTimeValue() << ", "; + } + } + throw INTERP_KERNEL::Exception(oss.str().c_str()); +} + +/*! + * \return an internal pointer that can be null. Warning the caller is \b not responsible of the returned pointer. + */ +MEDFileParameter1TS *MEDFileParameterMultiTS::getTimeStepAtPos(int posId) const +{ + if(posId<0 || posId>=(int)_param_per_ts.size()) + { + std::ostringstream oss; oss << "MEDFileParameterMultiTS::getTimeStepAtPos : invalid pos ! Should be in [0," << _param_per_ts.size() << ") !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + return const_cast<MEDFileParameter1TS *>(static_cast<const MEDFileParameter1TS *>(_param_per_ts[posId])); +} + +void MEDFileParameterMultiTS::eraseTimeStepIds(const int *startIds, const int *endIds) +{ + std::vector<bool> b(_param_per_ts.size(),true); + int len=(int)_param_per_ts.size(); + for(const int *w=startIds;w!=endIds;w++) + if(*w>=0 && *w<len) + b[*w]=false; + else + { + std::ostringstream oss; oss << "MEDFileParameterMultiTS::eraseTimeStepIds : At pos #" << std::distance(startIds,w) << " value is " << *w << " should be in [0," << len << ") !"; throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + std::size_t newNb=std::count(b.begin(),b.end(),true); + std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileParameter1TS> > paramPerTs(newNb); + std::size_t j=0; + for(std::size_t i=0;i<_param_per_ts.size();i++) + if(b[i]) + paramPerTs[j++]=_param_per_ts[i]; + _param_per_ts=paramPerTs; +} + +int MEDFileParameterMultiTS::getNumberOfTS() const +{ + return (int) getIterations().size(); +} + +std::vector< std::pair<int,int> > MEDFileParameterMultiTS::getIterations() const +{ + std::vector< std::pair<int,int> > ret; + for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileParameter1TS> >::const_iterator it=_param_per_ts.begin();it!=_param_per_ts.end();it++) + { + const MEDFileParameter1TS *elt(*it); + if(elt) + ret.push_back(std::pair<int,int>(elt->getIteration(),elt->getOrder())); + } + return ret; +} + +/*! + * \param [out] ret1 + */ +std::vector< std::pair<int,int> > MEDFileParameterMultiTS::getTimeSteps(std::vector<double>& ret1) const +{ + std::vector< std::pair<int,int> > ret0; + ret1.clear(); + for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileParameter1TS> >::const_iterator it=_param_per_ts.begin();it!=_param_per_ts.end();it++) + { + const MEDFileParameter1TS *elt(*it); + if(elt) + { + ret0.push_back(std::pair<int,int>(elt->getIteration(),elt->getOrder())); + ret1.push_back(elt->getTimeValue()); + } + } + return ret0; +} + +MEDFileParameters *MEDFileParameters::New() +{ + return new MEDFileParameters; +} + +MEDFileParameters *MEDFileParameters::New(const std::string& fileName) +{ + return new MEDFileParameters(fileName); +} + +MEDFileParameters::MEDFileParameters(const std::string& fileName) +{ + MEDFileUtilities::CheckFileForRead(fileName); + MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName.c_str(),MED_ACC_RDONLY); + int nbPar=MEDnParameter(fid); + _params.resize(nbPar); + INTERP_KERNEL::AutoPtr<char> pName=MEDLoaderBase::buildEmptyString(MED_NAME_SIZE); + INTERP_KERNEL::AutoPtr<char> descName=MEDLoaderBase::buildEmptyString(MED_COMMENT_SIZE); + INTERP_KERNEL::AutoPtr<char> unitName=MEDLoaderBase::buildEmptyString(MED_SNAME_SIZE); + med_parameter_type paramType; + for(int i=0;i<nbPar;i++) + { + int nbOfSteps; + MEDFILESAFECALLERRD0(MEDparameterInfo,(fid,i+1,pName,¶mType,descName,unitName,&nbOfSteps)); + std::string paramNameCpp=MEDLoaderBase::buildStringFromFortran(pName,MED_NAME_SIZE); + _params[i]=MEDFileParameterMultiTS::New(fileName,paramNameCpp); + } +} + +MEDFileParameters::MEDFileParameters() +{ +} + +std::size_t MEDFileParameters::getHeapMemorySizeWithoutChildren() const +{ + std::size_t ret(sizeof(MEDFileParameters)); + ret+=sizeof(MEDCouplingAutoRefCountObjectPtr<MEDFileParameterMultiTS>)*_params.capacity(); + return ret; +} + +std::vector<const BigMemoryObject *> MEDFileParameters::getDirectChildrenWithNull() const +{ + std::vector<const BigMemoryObject *> ret; + for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileParameterMultiTS> >::const_iterator it=_params.begin();it!=_params.end();it++) + ret.push_back((const MEDFileParameterMultiTS *)*it); + return ret; +} + +MEDFileParameters *MEDFileParameters::deepCpy() const +{ + return new MEDFileParameters(*this,true); +} + +bool MEDFileParameters::isEqual(const MEDFileParameters *other, double eps, std::string& what) const +{ + if(!other) + { what="other is null !"; return false; } + if(_params.size()!=other->_params.size()) + { what="number of parameters differs !"; return false; } + std::ostringstream oss; + for(std::size_t i=0;i<_params.size();i++) + { + const MEDFileParameterMultiTS *a(_params[i]),*b(other->_params[i]); + if((a && !b) || (!a && b)) + { oss << "At param with id #" << i << " pointer is defined on one side not in the other !"; what=oss.str(); return false; } + if(a) + if(!a->isEqual(b,eps,what)) + { oss << " At param with id #" << i << " non equality !"; what+=oss.str(); return false; } + } + return true; +} + +MEDFileParameters::MEDFileParameters(const MEDFileParameters& other, bool deepCopy):MEDFileWritable(other),_params(other._params) +{ + if(deepCopy) + for(std::size_t i=0;i<_params.size();i++) + { + const MEDFileParameterMultiTS *elt=_params[i]; + if(elt) + _params[i]=elt->deepCpy(); + } +} + +void MEDFileParameters::write(const std::string& fileName, int mode) const +{ + med_access_mode medmod=MEDFileUtilities::TraduceWriteMode(mode); + MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName.c_str(),medmod); + writeLL(fid); +} + +void MEDFileParameters::writeLL(med_idt fid) const +{ + for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileParameterMultiTS> >::const_iterator it=_params.begin();it!=_params.end();it++) + { + const MEDFileParameterMultiTS *elt(*it); + if(elt) + elt->writeLL(fid,*this); + } +} + +std::vector<std::string> MEDFileParameters::getParamsNames() const +{ + std::vector<std::string> ret(_params.size()); + int i=0; + for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileParameterMultiTS> >::const_iterator it=_params.begin();it!=_params.end();it++,i++) + { + const MEDFileParameterMultiTS *p=(*it); + if(p) + { + ret[i]=p->getName(); + } + else + { + std::ostringstream oss; oss << "MEDFileParameters::getParamsNames : At rank #" << i << " param is not defined !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + } + return ret; +} + +std::string MEDFileParameters::simpleRepr() const +{ + std::ostringstream oss; + simpleReprWithoutHeader(oss); + return oss.str(); +} + +void MEDFileParameters::simpleReprWithoutHeader(std::ostream& oss) const +{ + for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileParameterMultiTS> >::const_iterator it=_params.begin();it!=_params.end();it++) + { + const MEDFileParameterMultiTS *elt(*it); + if(elt) + elt->simpleRepr2(2,oss); + } +} + +void MEDFileParameters::resize(int newSize) +{ + if(newSize<0) + throw INTERP_KERNEL::Exception("MEDFileParameters::resize : should be positive !"); + _params.resize(newSize); +} + +void MEDFileParameters::pushParam(MEDFileParameterMultiTS *param) +{ + if(param) + param->incrRef(); + MEDCouplingAutoRefCountObjectPtr<MEDFileParameterMultiTS> elt(param); + _params.push_back(elt); +} + +void MEDFileParameters::setParamAtPos(int i, MEDFileParameterMultiTS *param) +{ + if(i<0) + throw INTERP_KERNEL::Exception("MEDFileParameters::setParamAtPos : should be positive !"); + if(i>=(int)_params.size()) + _params.resize(i+1); + if(param) + param->incrRef(); + MEDCouplingAutoRefCountObjectPtr<MEDFileParameterMultiTS> elt(param); + _params[i]=elt; +} + +/*! + * \return an internal pointer that can be null. Warning the caller is \b not responsible of the returned pointer. + */ +MEDFileParameterMultiTS *MEDFileParameters::getParamAtPos(int i) const +{ + if(i<0 || i>=(int)_params.size()) + { + std::ostringstream oss; oss << "MEDFileParameters::getParamAtPos : should be in [0," << _params.size() << ") !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + const MEDFileParameterMultiTS *elt=_params[i]; + return const_cast<MEDFileParameterMultiTS *>(elt); +} + +/*! + * \return an internal pointer that can be null. Warning the caller is \b not responsible of the returned pointer. + */ +MEDFileParameterMultiTS *MEDFileParameters::getParamWithName(const std::string& paramName) const +{ + int pos=getPosFromParamName(paramName); + return getParamAtPos(pos); +} + +void MEDFileParameters::destroyParamAtPos(int i) +{ + if(i<0 || i>=(int)_params.size()) + { + std::ostringstream oss; oss << "MEDFileParameters::destroyParamAtPos : should be in [0," << _params.size() << ") !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + _params[i]=MEDCouplingAutoRefCountObjectPtr<MEDFileParameterMultiTS>(0); +} + +int MEDFileParameters::getPosFromParamName(const std::string& paramName) const +{ + std::ostringstream oss; oss << "MEDFileParameters::getPosFromParamName : no such name=" << paramName << " ! Possibilities are :"; + int ret=0; + for(std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileParameterMultiTS> >::const_iterator it=_params.begin();it!=_params.end();it++,ret++) + { + const MEDFileParameterMultiTS *elt(*it); + if(elt) + { + if(std::string(elt->getName())==paramName) + return ret; + else + oss << elt->getName() << ", "; + } + } + throw INTERP_KERNEL::Exception(oss.str().c_str()); +} + +int MEDFileParameters::getNumberOfParams() const +{ + return (int)_params.size(); +} diff --git a/src/medtool/src/MEDLoader/MEDFileParameter.hxx b/src/medtool/src/MEDLoader/MEDFileParameter.hxx new file mode 100644 index 000000000..f223fc78c --- /dev/null +++ b/src/medtool/src/MEDLoader/MEDFileParameter.hxx @@ -0,0 +1,187 @@ +// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 +// 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 __MEDFILEPARAMETER_HXX__ +#define __MEDFILEPARAMETER_HXX__ + +#include "MEDLoaderDefines.hxx" +#include "MEDFileUtilities.hxx" +#include "MEDCouplingMemArray.hxx" +#include "MEDCouplingAutoRefCountObjectPtr.hxx" + +namespace ParaMEDMEM +{ + class MEDFileParameter1TS : public RefCountObject + { + public: + MEDLOADER_EXPORT virtual MEDFileParameter1TS *deepCpy() const = 0; + MEDLOADER_EXPORT virtual bool isEqual(const MEDFileParameter1TS *other, double eps, std::string& what) const; + MEDLOADER_EXPORT virtual void simpleRepr2(int bkOffset, std::ostream& oss) const = 0; + MEDLOADER_EXPORT virtual void readValue(med_idt fid, const std::string& name) = 0; + MEDLOADER_EXPORT virtual void writeLL(med_idt fid, const std::string& name, const MEDFileWritable& mw) const = 0; + public: + MEDLOADER_EXPORT void setIteration(int it) { _iteration=it; } + MEDLOADER_EXPORT int getIteration() const { return _iteration; } + MEDLOADER_EXPORT void setOrder(int order) { _order=order; } + MEDLOADER_EXPORT int getOrder() const { return _order; } + MEDLOADER_EXPORT void setTimeValue(double time) { _time=time; } + MEDLOADER_EXPORT void setTime(int dt, int it, double time) { _time=time; _iteration=dt; _order=it; } + MEDLOADER_EXPORT double getTime(int& dt, int& it) { dt=_iteration; it=_order; return _time; } + MEDLOADER_EXPORT double getTimeValue() const { return _time; } + protected: + MEDFileParameter1TS(int iteration, int order, double time); + MEDFileParameter1TS(); + protected: + int _iteration; + int _order; + double _time; + }; + + class MEDFileParameterDouble1TSWTI : public MEDFileParameter1TS + { + public: + MEDLOADER_EXPORT static MEDFileParameterDouble1TSWTI *New(int iteration, int order, double time); + MEDLOADER_EXPORT MEDFileParameter1TS *deepCpy() const; + MEDLOADER_EXPORT void setValue(double val) { _arr=val; } + MEDLOADER_EXPORT double getValue() const { return _arr; } + MEDLOADER_EXPORT bool isEqual(const MEDFileParameter1TS *other, double eps, std::string& what) const; + MEDLOADER_EXPORT std::size_t getHeapMemorySizeWithoutChildren() const; + MEDLOADER_EXPORT std::vector<const BigMemoryObject *> getDirectChildrenWithNull() const; + MEDLOADER_EXPORT void readValue(med_idt fid, const std::string& name); + MEDLOADER_EXPORT std::string simpleRepr() const; + protected: + MEDFileParameterDouble1TSWTI(); + MEDFileParameterDouble1TSWTI(int iteration, int order, double time); + void simpleRepr2(int bkOffset, std::ostream& oss) const; + void finishLoading(med_idt fid, const std::string& name, int dt, int it, int nbOfSteps); + void finishLoading(med_idt fid, const std::string& name, int timeStepId); + void writeLL(med_idt fid, const std::string& name, const MEDFileWritable& mw) const; + protected: + double _arr; + }; + + class MEDFileParameterTinyInfo : public MEDFileWritable + { + public: + MEDLOADER_EXPORT void setDescription(const std::string& name) { _desc_name=name; } + MEDLOADER_EXPORT std::string getDescription() const { return _desc_name; } + MEDLOADER_EXPORT void setTimeUnit(const std::string& unit) { _dt_unit=unit; } + MEDLOADER_EXPORT std::string getTimeUnit() const { return _dt_unit; } + MEDLOADER_EXPORT std::size_t getHeapMemSizeOfStrings() const; + MEDLOADER_EXPORT bool isEqualStrings(const MEDFileParameterTinyInfo& other, std::string& what) const; + protected: + void writeLLHeader(med_idt fid, med_parameter_type typ) const; + void mainRepr(int bkOffset, std::ostream& oss) const; + protected: + std::string _dt_unit; + std::string _name; + std::string _desc_name; + }; + + class MEDFileParameterDouble1TS : public MEDFileParameterDouble1TSWTI, public MEDFileParameterTinyInfo + { + public: + MEDLOADER_EXPORT static MEDFileParameterDouble1TS *New(); + MEDLOADER_EXPORT static MEDFileParameterDouble1TS *New(const std::string& fileName); + MEDLOADER_EXPORT static MEDFileParameterDouble1TS *New(const std::string& fileName, const std::string& paramName); + MEDLOADER_EXPORT static MEDFileParameterDouble1TS *New(const std::string& fileName, const std::string& paramName, int dt, int it); + MEDLOADER_EXPORT virtual MEDFileParameter1TS *deepCpy() const; + MEDLOADER_EXPORT virtual bool isEqual(const MEDFileParameter1TS *other, double eps, std::string& what) const; + MEDLOADER_EXPORT virtual std::string simpleRepr() const; + MEDLOADER_EXPORT std::size_t getHeapMemorySizeWithoutChildren() const; + MEDLOADER_EXPORT std::vector<const BigMemoryObject *> getDirectChildrenWithNull() const; + MEDLOADER_EXPORT void setName(const std::string& name) { _name=name; } + MEDLOADER_EXPORT std::string getName() const { return _name; } + MEDLOADER_EXPORT void write(const std::string& fileName, int mode) const; + private: + MEDFileParameterDouble1TS(); + MEDFileParameterDouble1TS(const std::string& fileName); + MEDFileParameterDouble1TS(const std::string& fileName, const std::string& paramName); + MEDFileParameterDouble1TS(const std::string& fileName, const std::string& paramName, int dt, int it); + }; + + class MEDFileParameterMultiTS : public RefCountObject, public MEDFileParameterTinyInfo + { + public: + MEDLOADER_EXPORT static MEDFileParameterMultiTS *New(); + MEDLOADER_EXPORT static MEDFileParameterMultiTS *New(const std::string& fileName); + MEDLOADER_EXPORT static MEDFileParameterMultiTS *New(const std::string& fileName, const std::string& paramName); + MEDLOADER_EXPORT std::string getName() const { return _name; } + MEDLOADER_EXPORT void setName(const std::string& name) { _name=name; } + MEDLOADER_EXPORT std::size_t getHeapMemorySizeWithoutChildren() const; + MEDLOADER_EXPORT std::vector<const BigMemoryObject *> getDirectChildrenWithNull() const; + MEDLOADER_EXPORT MEDFileParameterMultiTS *deepCpy() const; + MEDLOADER_EXPORT bool isEqual(const MEDFileParameterMultiTS *other, double eps, std::string& what) const; + MEDLOADER_EXPORT void write(const std::string& fileName, int mode) const; + MEDLOADER_EXPORT void writeLL(med_idt fid, const MEDFileWritable& mw) const; + MEDLOADER_EXPORT std::string simpleRepr() const; + MEDLOADER_EXPORT void appendValue(int dt, int it, double time, double val); + MEDLOADER_EXPORT double getDoubleValue(int iteration, int order) const; + MEDLOADER_EXPORT int getPosOfTimeStep(int iteration, int order) const; + MEDLOADER_EXPORT int getPosGivenTime(double time, double eps=1e-8) const; + MEDLOADER_EXPORT MEDFileParameter1TS *getTimeStepAtPos(int posId) const; + MEDLOADER_EXPORT void eraseTimeStepIds(const int *startIds, const int *endIds); + MEDLOADER_EXPORT int getNumberOfTS() const; + MEDLOADER_EXPORT std::vector< std::pair<int,int> > getIterations() const; + MEDLOADER_EXPORT std::vector< std::pair<int,int> > getTimeSteps(std::vector<double>& ret1) const; + MEDLOADER_EXPORT void simpleRepr2(int bkOffset, std::ostream& oss) const; + protected: + MEDFileParameterMultiTS(); + MEDFileParameterMultiTS(const MEDFileParameterMultiTS& other, bool deepCopy); + MEDFileParameterMultiTS(const std::string& fileName); + MEDFileParameterMultiTS(const std::string& fileName, const std::string& paramName); + void finishLoading(med_idt fid, med_parameter_type typ, int nbOfSteps); + protected: + std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileParameter1TS> > _param_per_ts; + }; + + class MEDFileParameters : public RefCountObject, public MEDFileWritable + { + public: + MEDLOADER_EXPORT static MEDFileParameters *New(); + MEDLOADER_EXPORT static MEDFileParameters *New(const std::string& fileName); + MEDLOADER_EXPORT std::size_t getHeapMemorySizeWithoutChildren() const; + MEDLOADER_EXPORT std::vector<const BigMemoryObject *> getDirectChildrenWithNull() const; + MEDLOADER_EXPORT MEDFileParameters *deepCpy() const; + MEDLOADER_EXPORT bool isEqual(const MEDFileParameters *other, double eps, std::string& what) const; + MEDLOADER_EXPORT void write(const std::string& fileName, int mode) const; + MEDLOADER_EXPORT void writeLL(med_idt fid) const; + MEDLOADER_EXPORT std::vector<std::string> getParamsNames() const; + MEDLOADER_EXPORT std::string simpleRepr() const; + MEDLOADER_EXPORT void simpleReprWithoutHeader(std::ostream& oss) const; + MEDLOADER_EXPORT void resize(int newSize); + MEDLOADER_EXPORT void pushParam(MEDFileParameterMultiTS *param); + MEDLOADER_EXPORT void setParamAtPos(int i, MEDFileParameterMultiTS *param); + MEDLOADER_EXPORT MEDFileParameterMultiTS *getParamAtPos(int i) const; + MEDLOADER_EXPORT MEDFileParameterMultiTS *getParamWithName(const std::string& paramName) const; + MEDLOADER_EXPORT void destroyParamAtPos(int i); + MEDLOADER_EXPORT int getPosFromParamName(const std::string& paramName) const; + MEDLOADER_EXPORT int getNumberOfParams() const; + protected: + void simpleRepr2(int bkOffset, std::ostream& oss) const; + MEDFileParameters(const std::string& fileName); + MEDFileParameters(const MEDFileParameters& other, bool deepCopy); + MEDFileParameters(); + protected: + std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileParameterMultiTS> > _params; + }; +} + +#endif diff --git a/src/medtool/src/MEDLoader/MEDFileSafeCaller.txx b/src/medtool/src/MEDLoader/MEDFileSafeCaller.txx new file mode 100644 index 000000000..2ce1bd6cf --- /dev/null +++ b/src/medtool/src/MEDLoader/MEDFileSafeCaller.txx @@ -0,0 +1,41 @@ +// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 +// 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 (EDF R&D) + +#ifndef __MEDFILESAFECALLER_TXX__ +#define __MEDFILESAFECALLER_TXX__ + +#include "med.h" + +#include "InterpKernelException.hxx" + +#include <sstream> + +// TXX extension to avoid to be installed. + +// This macro calls safely MEDFile functions returning 0 +#define MEDFILESAFECALLER0(a,b) { med_err retCode(a b); \ + if(retCode!=0) { std::ostringstream osszz; osszz << "Return code of MEDFile call \"" << #a << "\" is not 0 as expected ! ( Return code was "<< retCode << " at " << __FILE__ << ":" << __LINE__ << " )"; throw INTERP_KERNEL::Exception(osszz.str().c_str()); } } + +#define MEDFILESAFECALLERRD0(a,b) MEDFILESAFECALLER0(a,b) + +#define MEDFILESAFECALLERWR0(a,b) { med_err retCode(a b); \ + if(retCode!=0) { std::ostringstream osszz; osszz << "Return code of MEDFile call \"" << #a << "\" is not 0 as expected during writing operation ! ( Return code was "<< retCode << " at " << __FILE__ << ":" << __LINE__ << " ). Check write access on MED file ?"; throw INTERP_KERNEL::Exception(osszz.str().c_str()); } } + +#endif diff --git a/src/medtool/src/MEDLoader/MEDFileUtilities.cxx b/src/medtool/src/MEDLoader/MEDFileUtilities.cxx new file mode 100644 index 000000000..a52d8a28b --- /dev/null +++ b/src/medtool/src/MEDLoader/MEDFileUtilities.cxx @@ -0,0 +1,147 @@ +// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 +// 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 "MEDFileUtilities.hxx" +#include "MEDLoaderBase.hxx" + +#include <sstream> + +med_access_mode MEDFileUtilities::TraduceWriteMode(int medloaderwritemode) +{ + switch(medloaderwritemode) + { + case 2: + return MED_ACC_CREAT; + case 1: + return MED_ACC_RDEXT; + case 0: + return MED_ACC_RDWR; + default: + throw INTERP_KERNEL::Exception("Invalid write mode specified ! must be 0(write with no question), 1(append) or 2(creation)"); + } +} + +const char *MEDFileUtilities::GetReadableMEDFieldType(med_field_type ft) +{ + static const char medFloat64[]="MED_FLOAT64"; + static const char medInt32[]="MED_INT32"; + static const char medInt64[]="MED_INT64"; + switch(ft) + { + case MED_FLOAT64: + return medFloat64; + case MED_INT32: + return medInt32; + case MED_INT64: + return medInt64; + default: + throw INTERP_KERNEL::Exception("Non supported field type ! Should be FLOAT64, INT32 or INT64 !"); + } +} + +void MEDFileUtilities::CheckMEDCode(int code, med_idt fid, const std::string& msg) +{ + if(code<0) + { + std::ostringstream oss; + oss << "MEDFile has returned an error code (" << code <<") : " << msg; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } +} + +void MEDFileUtilities::CheckFileForRead(const std::string& fileName) +{ + int status=MEDLoaderBase::getStatusOfFile(fileName); + std::ostringstream oss; + oss << " File : \"" << fileName << "\""; + switch(status) + { + case MEDLoaderBase::DIR_LOCKED: + { + oss << " has been detected as unreadable : impossible to read anything !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + case MEDLoaderBase::NOT_EXIST: + { + oss << " has been detected as NOT EXISTING : impossible to read anything !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + case MEDLoaderBase::EXIST_WRONLY: + { + oss << " has been detected as WRITE ONLY : impossible to read anything !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + } + AutoFid fid=MEDfileOpen(fileName.c_str(),MED_ACC_RDONLY); + if(fid<0) + { + oss << " has been detected as unreadable by MED file : impossible to read anything !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + oss << " has been detected readable but "; + int major,minor,release; + MEDfileNumVersionRd(fid,&major,&minor,&release); + if(major<2 || (major==2 && minor<2)) + { + oss << "version of MED file is < 2.2 : impossible to read anything !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } +} + +MEDFileUtilities::AutoFid::AutoFid(med_idt fid):_fid(fid) +{ +} + +MEDFileUtilities::AutoFid::~AutoFid() +{ + MEDfileClose(_fid); +} + +ParaMEDMEM::MEDFileWritable::MEDFileWritable():_too_long_str(0),_zipconn_pol(2) +{ +} + +void ParaMEDMEM::MEDFileWritable::copyOptionsFrom(const MEDFileWritable& other) const +{ + _too_long_str=other._too_long_str; + _zipconn_pol=other._zipconn_pol; +} + +int ParaMEDMEM::MEDFileWritable::getTooLongStrPolicy() const +{ + return _too_long_str; +} + +void ParaMEDMEM::MEDFileWritable::setTooLongStrPolicy(int newVal) +{ + if(newVal!=2 && newVal!=1 && newVal!=0) + throw INTERP_KERNEL::Exception("MEDFileWritable::setTooLongStrPolicy : invalid policy should be in 0,1 or 2 !"); + _too_long_str=newVal; +} + +int ParaMEDMEM::MEDFileWritable::getZipConnPolicy() +{ + return _zipconn_pol; +} + +void ParaMEDMEM::MEDFileWritable::setZipConnPolicy(int newVal) +{ + _zipconn_pol=newVal; +} diff --git a/src/medtool/src/MEDLoader/MEDFileUtilities.hxx b/src/medtool/src/MEDLoader/MEDFileUtilities.hxx new file mode 100644 index 000000000..ffac85a16 --- /dev/null +++ b/src/medtool/src/MEDLoader/MEDFileUtilities.hxx @@ -0,0 +1,64 @@ +// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 +// 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 __MEDFILEUTILITIES_HXX__ +#define __MEDFILEUTILITIES_HXX__ + +#include "InterpKernelException.hxx" +#include "MEDLoaderDefines.hxx" + +#include "med.h" + +namespace MEDFileUtilities +{ + med_access_mode TraduceWriteMode(int medloaderwritemode); + const char *GetReadableMEDFieldType(med_field_type ft); + void CheckMEDCode(int code, med_idt fid, const std::string& msg); + void CheckFileForRead(const std::string& fileName); + + class AutoFid + { + public: + AutoFid(med_idt fid); + operator med_idt() const { return _fid; } + ~AutoFid(); + private: + med_idt _fid; + }; +} + +namespace ParaMEDMEM +{ + class MEDLOADER_EXPORT MEDFileWritable + { + public: + MEDFileWritable(); + void copyOptionsFrom(const MEDFileWritable& other) const; + int getTooLongStrPolicy() const; + void setTooLongStrPolicy(int newVal); + int getZipConnPolicy(); + void setZipConnPolicy(int newVal); + protected://policies on write + mutable int _too_long_str; + mutable int _zipconn_pol; + }; +} + +#endif diff --git a/src/medtool/src/MEDLoader/MEDLoader.cxx b/src/medtool/src/MEDLoader/MEDLoader.cxx new file mode 100644 index 000000000..70c6d889a --- /dev/null +++ b/src/medtool/src/MEDLoader/MEDLoader.cxx @@ -0,0 +1,1585 @@ +// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 +// 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 "MEDLoader.hxx" +#include "MEDLoaderBase.hxx" +#include "MEDFileUtilities.hxx" +#include "MEDFileSafeCaller.txx" +#include "MEDFileMesh.hxx" +#include "MEDFileField.hxx" +#include "CellModel.hxx" +#include "MEDCouplingUMesh.hxx" +#include "MEDCouplingMemArray.hxx" +#include "MEDCouplingFieldDouble.hxx" +#include "MEDCouplingGaussLocalization.hxx" +#include "MEDCouplingAutoRefCountObjectPtr.hxx" + +#include "InterpKernelAutoPtr.hxx" + +#include "med.h" + +#include <string> +#include <limits> +#include <cstring> +#include <sstream> +#include <fstream> +#include <numeric> +#include <iterator> +#include <algorithm> + +/*! \class MEDLoader + * + * \brief Static class offering the "basic" API to read and write MED files/ + * + * This class implements only static methods and offers the high level API to access MED files. + * Take a look at \ref medloader for more details. + * + */ + +med_geometry_type typmai[MED_N_CELL_FIXED_GEO] = { MED_POINT1, + MED_SEG2, + MED_SEG3, + MED_SEG4, + MED_TRIA3, + MED_QUAD4, + MED_TRIA6, + MED_TRIA7, + MED_QUAD8, + MED_QUAD9, + MED_TETRA4, + MED_PYRA5, + MED_PENTA6, + MED_HEXA8, + MED_OCTA12, + MED_TETRA10, + MED_PYRA13, + MED_PENTA15, + MED_HEXA20, + MED_HEXA27, + MED_POLYGON, + MED_POLYGON2, + MED_POLYHEDRON }; + +med_geometry_type typmainoeud[1] = { MED_NONE }; + +INTERP_KERNEL::NormalizedCellType typmai2[MED_N_CELL_FIXED_GEO] = { INTERP_KERNEL::NORM_POINT1, + INTERP_KERNEL::NORM_SEG2, + INTERP_KERNEL::NORM_SEG3, + INTERP_KERNEL::NORM_SEG4, + INTERP_KERNEL::NORM_TRI3, + INTERP_KERNEL::NORM_QUAD4, + INTERP_KERNEL::NORM_TRI6, + INTERP_KERNEL::NORM_TRI7, + INTERP_KERNEL::NORM_QUAD8, + INTERP_KERNEL::NORM_QUAD9, + INTERP_KERNEL::NORM_TETRA4, + INTERP_KERNEL::NORM_PYRA5, + INTERP_KERNEL::NORM_PENTA6, + INTERP_KERNEL::NORM_HEXA8, + INTERP_KERNEL::NORM_HEXGP12, + INTERP_KERNEL::NORM_TETRA10, + INTERP_KERNEL::NORM_PYRA13, + INTERP_KERNEL::NORM_PENTA15, + INTERP_KERNEL::NORM_HEXA20, + INTERP_KERNEL::NORM_HEXA27, + INTERP_KERNEL::NORM_POLYGON, + INTERP_KERNEL::NORM_QPOLYG, + INTERP_KERNEL::NORM_POLYHED }; + +med_geometry_type typmai3[34] = { MED_POINT1,//0 + MED_SEG2,//1 + MED_SEG3,//2 + MED_TRIA3,//3 + MED_QUAD4,//4 + MED_POLYGON,//5 + MED_TRIA6,//6 + MED_TRIA7,//7 + MED_QUAD8,//8 + MED_QUAD9,//9 + MED_SEG4,//10 + MED_NONE,//11 + MED_NONE,//12 + MED_NONE,//13 + MED_TETRA4,//14 + MED_PYRA5,//15 + MED_PENTA6,//16 + MED_NONE,//17 + MED_HEXA8,//18 + MED_NONE,//19 + MED_TETRA10,//20 + MED_NONE,//21 + MED_OCTA12,//22 + MED_PYRA13,//23 + MED_NONE,//24 + MED_PENTA15,//25 + MED_NONE,//26 + MED_HEXA27,//27 + MED_NONE,//28 + MED_NONE,//29 + MED_HEXA20,//30 + MED_POLYHEDRON,//31 + MED_POLYGON2,//32 + MED_NONE//33 +}; + +double MEDLoader::_EPS_FOR_NODE_COMP=1.e-12; + +int MEDLoader::_COMP_FOR_CELL=0; + +int MEDLoader::_TOO_LONG_STR=0; + +using namespace ParaMEDMEM; + +/// @cond INTERNAL + +namespace MEDLoaderNS +{ + int readUMeshDimFromFile(const std::string& fileName, const std::string& meshName, std::vector<int>& possibilities); + void dispatchElems(int nbOfElemCell, int nbOfElemFace, int& nbOfElem, med_entity_type& whichEntity); + void writeFieldWithoutReadingAndMappingOfMeshInFile(const std::string& fileName, const ParaMEDMEM::MEDCouplingFieldDouble *f, bool writeFromScratch); + med_int getIdFromMeshName(med_idt fid, const std::string& meshName, std::string& trueMeshName); + std::vector<std::string> getMeshNamesFid(med_idt fid); +} + +/// @endcond + + +/// @cond INTERNAL + +/*! + * This method returns a first quick overview of mesh with name \a meshName into the file \a fileName. + * @param possibilities the relativeToMeshDim authorized to returned maxdim. This vector is systematically cleared at the begin of this method. + * @return the maximal mesh dimension of specified mesh. If nothing found -1 is returned. + */ +int MEDLoaderNS::readUMeshDimFromFile(const std::string& fileName, const std::string& meshName, std::vector<int>& possibilities) +{ + possibilities.clear(); + MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName.c_str(),MED_ACC_RDONLY); + int ret; + std::set<int> poss; + char nommaa[MED_NAME_SIZE+1]; + char maillage_description[MED_COMMENT_SIZE+1]; + med_mesh_type type_maillage; + med_int Sdim,Mdim; + std::string trueMeshName; + med_int meshId=getIdFromMeshName(fid,meshName,trueMeshName); + INTERP_KERNEL::AutoPtr<char> dt_unit=MEDLoaderBase::buildEmptyString(MED_LNAME_SIZE); + med_sorting_type sortingType; + med_int nstep; + med_axis_type axisType; + int naxis(MEDmeshnAxis(fid,meshId)); + INTERP_KERNEL::AutoPtr<char> axisname=MEDLoaderBase::buildEmptyString(naxis*MED_SNAME_SIZE); + INTERP_KERNEL::AutoPtr<char> axisunit=MEDLoaderBase::buildEmptyString(naxis*MED_SNAME_SIZE); + MEDFILESAFECALLERRD0(MEDmeshInfo,(fid,meshId,nommaa,&Sdim,&Mdim,&type_maillage,maillage_description,dt_unit,&sortingType,&nstep,&axisType,axisname,axisunit)); + // limitation + if(nstep!=1) + { + throw INTERP_KERNEL::Exception("multisteps on mesh not managed yet !"); + } + med_int numdt,numit; + med_float dt; + MEDFILESAFECALLERRD0(MEDmeshComputationStepInfo,(fid,nommaa,1,&numdt,&numit,&dt)); + // endlimitation + for(int i=0;i<MED_N_CELL_GEO_FIXED_CON;i++) + { + med_geometry_type curMedType=typmai[i]; + med_bool changement,transformation; + int curNbOfElemM(MEDmeshnEntity(fid,nommaa,numdt,numit,MED_CELL,curMedType,MED_CONNECTIVITY,MED_NODAL,&changement,&transformation)); + int curNbOfElemF(MEDmeshnEntity(fid,nommaa,numdt,numit,MED_CELL,curMedType,MED_CONNECTIVITY,MED_NODAL,&changement,&transformation));//limitation + int curNbOfElem; + med_entity_type whichEntity; + MEDLoaderNS::dispatchElems(curNbOfElemM,curNbOfElemF,curNbOfElem,whichEntity); + if(curNbOfElem>0) + { + INTERP_KERNEL::NormalizedCellType type=typmai2[i]; + int curDim=(int)INTERP_KERNEL::CellModel::GetCellModel(type).getDimension(); + poss.insert(curDim); + } + } + if(!poss.empty()) + { + ret=*poss.rbegin(); + for(std::set<int>::const_reverse_iterator it=poss.rbegin();it!=poss.rend();it++) + possibilities.push_back(*it-ret); + } + else + ret=-2; + return ret; +} + +med_int MEDLoaderNS::getIdFromMeshName(med_idt fid, const std::string& meshName, std::string& trueMeshName) + { + if(meshName.empty()) + { + std::vector<std::string> meshes=getMeshNamesFid(fid); + if(meshes.empty()) + throw INTERP_KERNEL::Exception("No mesh in file"); + trueMeshName=meshes[0]; + return 1; + } + std::string meshNameStr(meshName); + std::vector<std::string> meshes=getMeshNamesFid(fid); + if(meshes.empty()) + throw INTERP_KERNEL::Exception("No mesh in file"); + std::vector<std::string>::iterator iter=std::find(meshes.begin(),meshes.end(),meshNameStr); + if(iter==meshes.end()) + { + std::ostringstream os2; + os2 << "MeshName '" << meshName << "' not in file : meshes available : "; + std::copy(meshes.begin(),meshes.end(),std::ostream_iterator<std::string>(os2," ")); + throw INTERP_KERNEL::Exception(os2.str().c_str()); + } + trueMeshName=meshName; + return iter-meshes.begin()+1; + } + +std::vector<std::string> MEDLoaderNS::getMeshNamesFid(med_idt fid) +{ + med_mesh_type type_maillage; + char maillage_description[MED_COMMENT_SIZE+1]; + char dtunit[MED_COMMENT_SIZE+1]; + med_int space_dim; + med_int mesh_dim; + char nommaa[MED_NAME_SIZE+1]; + med_axis_type axistype; + med_sorting_type stype; + med_int n=MEDnMesh(fid); + std::vector<std::string> ret(n); + for(int i=0;i<n;i++) + { + int naxis(MEDmeshnAxis(fid,i+1)); + INTERP_KERNEL::AutoPtr<char> axisname=MEDLoaderBase::buildEmptyString(naxis*MED_SNAME_SIZE); + INTERP_KERNEL::AutoPtr<char> axisunit=MEDLoaderBase::buildEmptyString(naxis*MED_SNAME_SIZE); + int nstep; + MEDFILESAFECALLERRD0(MEDmeshInfo,(fid,i+1,nommaa,&space_dim,&mesh_dim,&type_maillage,maillage_description,dtunit,&stype,&nstep,&axistype,axisname,axisunit)); + std::string cur=MEDLoaderBase::buildStringFromFortran(nommaa,sizeof(nommaa)); + ret[i]=cur; + } + return ret; +} + +/*! + * This methods allows to merger all entities and to considerate only cell types. + */ +void MEDLoaderNS::dispatchElems(int nbOfElemCell, int nbOfElemFace, int& nbOfElem, med_entity_type& whichEntity) +{ + if(nbOfElemCell>=nbOfElemFace) + { + whichEntity=MED_CELL; + nbOfElem=nbOfElemCell; + } + else + { + whichEntity=MED_CELL; + nbOfElem=nbOfElemFace; + } +} + +/// @endcond + +void MEDLoader::AssignStaticWritePropertiesTo(ParaMEDMEM::MEDFileWritable& obj) +{ + obj.setTooLongStrPolicy(_TOO_LONG_STR); +} + +bool MEDLoader::HasXDR() +{ +#ifdef HAS_XDR + return true; +#else + return false; +#endif +} + +std::string MEDLoader::MEDFileVersionStr() +{ + return std::string(MED_VERSION_STR); +} + +void MEDLoader::MEDFileVersion(int& major, int& minor, int& release) +{ + major=MED_NUM_MAJEUR; + minor=MED_NUM_MINEUR; + release=MED_NUM_RELEASE; +} + +/*! + * This method sets the epsilon value used for node comparison when trying to buid a profile for a field on node/cell on an already written mesh. + */ +void MEDLoader::SetEpsilonForNodeComp(double val) +{ + _EPS_FOR_NODE_COMP=val; +} + +/*! + * This method sets the policy comparison when trying to fit the already written mesh on a field. The semantic of the policy is specified in MEDCouplingUMesh::zipConnectivityTraducer. + */ +void MEDLoader::SetCompPolicyForCell(int val) +{ + _COMP_FOR_CELL=val; +} + +/*! + * This method set the behaviour of MEDLoader when a too long string is seen in datastructure before copy it in MED file. + * By default (0) an exception is thrown. If equal to 1 a warning is emitted in std_err but no exception is thrown. + */ +void MEDLoader::SetTooLongStrPolicy(int val) +{ + _TOO_LONG_STR=val; +} + +/*! + * Given a 'fileName' and a 'meshName' this method returns global information concerning this mesh. + * It returns, in this order : + * - number of cells sorted by dimension and by geometry type. The first entry in the vector is the maximal dimension, the 2nd in the vector is the maximal dimension-1... + * - the mesh dimension + * - the space dimension + * - the number of nodes + */ +std::vector< std::vector< std::pair<INTERP_KERNEL::NormalizedCellType,int> > > MEDLoader::GetUMeshGlobalInfo(const std::string& fileName, const std::string& meshName, int &meshDim, int& spaceDim, int& numberOfNodes) +{ + CheckFileForRead(fileName); + MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName.c_str(),MED_ACC_RDONLY); + std::set<int> poss; + char nommaa[MED_NAME_SIZE+1]; + char maillage_description[MED_COMMENT_SIZE+1]; + med_mesh_type type_maillage; + std::string trueMeshName; + med_int meshId=MEDLoaderNS::getIdFromMeshName(fid,meshName,trueMeshName); + INTERP_KERNEL::AutoPtr<char> dt_unit=MEDLoaderBase::buildEmptyString(MED_LNAME_SIZE); + med_sorting_type sortingType; + med_int nstep; + med_axis_type axisType; + int naxis(MEDmeshnAxis(fid,meshId)); + INTERP_KERNEL::AutoPtr<char> axisname=MEDLoaderBase::buildEmptyString(naxis*MED_SNAME_SIZE); + INTERP_KERNEL::AutoPtr<char> axisunit=MEDLoaderBase::buildEmptyString(naxis*MED_SNAME_SIZE); + MEDFILESAFECALLERRD0(MEDmeshInfo,(fid,meshId,nommaa,&spaceDim,&meshDim,&type_maillage,maillage_description,dt_unit,&sortingType,&nstep,&axisType,axisname,axisunit)); + if(type_maillage!=MED_UNSTRUCTURED_MESH) + { + std::ostringstream oss; oss << "MEDLoader::GetUMeshGlobalInfo : Mesh \""<< meshName << "\" in file \"" << fileName; + oss << "\" exists but it is not an unstructured mesh ! This method is not relevant for mesh types that are not unstructured !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + // limitation + if(nstep!=1) + throw INTERP_KERNEL::Exception("MEDLoader::GetUMeshGlobalInfo : multisteps on mesh not managed !"); + med_int numdt,numit; + med_float dt; + MEDFILESAFECALLERRD0(MEDmeshComputationStepInfo,(fid,nommaa,1,&numdt,&numit,&dt)); + // endlimitation + std::vector<int> dims; + std::vector< std::pair<INTERP_KERNEL::NormalizedCellType,int> > geoTypes; + med_bool changement,transformation; + for(int i=0;i<MED_N_CELL_FIXED_GEO;i++) + { + med_geometry_type curMedType=typmai[i]; + int curNbOfElemM(MEDmeshnEntity(fid,nommaa,numdt,numit,MED_CELL,curMedType,MED_CONNECTIVITY,MED_NODAL,&changement,&transformation)); + if(curNbOfElemM>0) + { + INTERP_KERNEL::NormalizedCellType typp=typmai2[i]; + int mdimCell=INTERP_KERNEL::CellModel::GetCellModel(typp).getDimension(); + dims.push_back(mdimCell); + geoTypes.push_back(std::pair<INTERP_KERNEL::NormalizedCellType,int>(typp,curNbOfElemM)); + } + } + int maxLev=*std::max_element(dims.begin(),dims.end()); + int lowLev=*std::min_element(dims.begin(),dims.end()); + int nbOfLevels=maxLev-lowLev+1; + std::vector< std::vector< std::pair<INTERP_KERNEL::NormalizedCellType,int> > > ret(nbOfLevels); + for(std::size_t i=0;i<dims.size();i++) + { + ret[maxLev-dims[i]].push_back(geoTypes[i]); + } + numberOfNodes=MEDmeshnEntity(fid,nommaa,numdt,numit,MED_NODE,MED_NONE,MED_COORDINATE,MED_NO_CMODE,&changement,&transformation); + return ret; +} + +void MEDLoader::CheckFileForRead(const std::string& fileName) +{ + MEDFileUtilities::CheckFileForRead(fileName); +} + +std::vector<std::string> MEDLoader::GetMeshNames(const std::string& fileName) +{ + CheckFileForRead(fileName); + MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName.c_str(),MED_ACC_RDONLY); + std::vector<std::string> ret=MEDLoaderNS::getMeshNamesFid(fid); + return ret; +} + +std::vector< std::pair<std::string,std::string> > MEDLoader::GetComponentsNamesOfField(const std::string& fileName, const std::string& fieldName) +{ + CheckFileForRead(fileName); + MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName.c_str(),MED_ACC_RDONLY); + med_int nbFields(MEDnField(fid)); + std::vector<std::string> fields(nbFields); + med_field_type typcha; + for(int i=0;i<nbFields;i++) + { + med_int ncomp(MEDfieldnComponent(fid,i+1)); + INTERP_KERNEL::AutoPtr<char> comp=new char[ncomp*MED_SNAME_SIZE+1]; + INTERP_KERNEL::AutoPtr<char> unit=new char[ncomp*MED_SNAME_SIZE+1]; + INTERP_KERNEL::AutoPtr<char> dt_unit=MEDLoaderBase::buildEmptyString(MED_LNAME_SIZE); + med_int nbPdt; + med_bool localmesh; + INTERP_KERNEL::AutoPtr<char> maa_ass=MEDLoaderBase::buildEmptyString(MED_NAME_SIZE); + INTERP_KERNEL::AutoPtr<char> nomcha=MEDLoaderBase::buildEmptyString(MED_NAME_SIZE); + MEDFILESAFECALLERRD0(MEDfieldInfo,(fid,i+1,nomcha,maa_ass,&localmesh,&typcha,comp,unit,dt_unit,&nbPdt)); + std::string meshName=MEDLoaderBase::buildStringFromFortran(maa_ass,MED_NAME_SIZE); + std::string curFieldName=MEDLoaderBase::buildStringFromFortran(nomcha,MED_NAME_SIZE+1); + if(curFieldName==fieldName) + { + std::vector< std::pair<std::string,std::string> > ret(ncomp); + for(int j=0;j<ncomp;j++) + ret[j]=std::pair<std::string,std::string>(MEDLoaderBase::buildStringFromFortran(((char *)comp)+j*MED_SNAME_SIZE,MED_SNAME_SIZE), + MEDLoaderBase::buildStringFromFortran(((char *)unit)+j*MED_SNAME_SIZE,MED_SNAME_SIZE)); + return ret; + } + fields[i]=curFieldName; + } + std::ostringstream oss; oss << "MEDLoader::GetComponentsNamesOfField : no such field \"" << fieldName << "\" in file \"" << fileName << "\" !" << std::endl; + oss << "Possible field names are : " << std::endl; + std::copy(fields.begin(),fields.end(),std::ostream_iterator<std::string>(oss," ")); + throw INTERP_KERNEL::Exception(oss.str().c_str()); +} + +std::vector<std::string> MEDLoader::GetMeshNamesOnField(const std::string& fileName, const std::string& fieldName) +{ + CheckFileForRead(fileName); + std::vector<std::string> ret; + // + MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName.c_str(),MED_ACC_RDONLY); + med_int nbFields=MEDnField(fid); + // + med_field_type typcha; + INTERP_KERNEL::AutoPtr<char> dt_unit=MEDLoaderBase::buildEmptyString(MED_LNAME_SIZE); + INTERP_KERNEL::AutoPtr<char> nomcha=MEDLoaderBase::buildEmptyString(MED_NAME_SIZE); + med_bool localmesh; + // + for(int i=0;i<nbFields;i++) + { + med_int ncomp(MEDfieldnComponent(fid,i+1)); + INTERP_KERNEL::AutoPtr<char> comp=new char[ncomp*MED_SNAME_SIZE+1]; + INTERP_KERNEL::AutoPtr<char> unit=new char[ncomp*MED_SNAME_SIZE+1]; + med_int nbPdt; + INTERP_KERNEL::AutoPtr<char> maa_ass=MEDLoaderBase::buildEmptyString(MED_NAME_SIZE); + MEDFILESAFECALLERRD0(MEDfieldInfo,(fid,i+1,nomcha,maa_ass,&localmesh,&typcha,comp,unit,dt_unit,&nbPdt)); + std::string meshName=MEDLoaderBase::buildStringFromFortran(maa_ass,MED_NAME_SIZE); + std::string curFieldName=MEDLoaderBase::buildStringFromFortran(nomcha,MED_NAME_SIZE+1); + if(curFieldName==fieldName) + ret.push_back(meshName); + } + return ret; +} + +std::vector<std::string> MEDLoader::GetMeshFamiliesNames(const std::string& fileName, const std::string& meshName) +{ + CheckFileForRead(fileName); + MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName.c_str(),MED_ACC_RDONLY); + med_int nfam=MEDnFamily(fid,meshName.c_str()); + std::vector<std::string> ret(nfam); + char nomfam[MED_NAME_SIZE+1]; + med_int numfam; + for(int i=0;i<nfam;i++) + { + int ngro=MEDnFamilyGroup(fid,meshName.c_str(),i+1); + med_int natt=MEDnFamily23Attribute(fid,meshName.c_str(),i+1); + INTERP_KERNEL::AutoPtr<med_int> attide=new med_int[natt]; + INTERP_KERNEL::AutoPtr<med_int> attval=new med_int[natt]; + INTERP_KERNEL::AutoPtr<char> attdes=new char[MED_COMMENT_SIZE*natt+1]; + INTERP_KERNEL::AutoPtr<char> gro=new char[MED_LNAME_SIZE*ngro+1]; + MEDfamily23Info(fid,meshName.c_str(),i+1,nomfam,attide,attval,attdes,&numfam,gro); + std::string cur=MEDLoaderBase::buildStringFromFortran(nomfam,sizeof(nomfam)); + ret[i]=cur; + } + return ret; +} + + +std::vector<std::string> MEDLoader::GetMeshFamiliesNamesOnGroup(const std::string& fileName, const std::string& meshName, const std::string& grpName) +{ + CheckFileForRead(fileName); + MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName.c_str(),MED_ACC_RDONLY); + med_int nfam=MEDnFamily(fid,meshName.c_str()); + std::vector<std::string> ret; + char nomfam[MED_NAME_SIZE+1]; + med_int numfam; + for(int i=0;i<nfam;i++) + { + int ngro=MEDnFamilyGroup(fid,meshName.c_str(),i+1); + med_int natt=MEDnFamily23Attribute(fid,meshName.c_str(),i+1); + INTERP_KERNEL::AutoPtr<med_int> attide=new med_int[natt]; + INTERP_KERNEL::AutoPtr<med_int> attval=new med_int[natt]; + INTERP_KERNEL::AutoPtr<char> attdes=new char[MED_COMMENT_SIZE*natt+1]; + INTERP_KERNEL::AutoPtr<char> gro=new char[MED_LNAME_SIZE*ngro+1]; + MEDfamily23Info(fid,meshName.c_str(),i+1,nomfam,attide,attval,attdes,&numfam,gro); + std::string cur=MEDLoaderBase::buildStringFromFortran(nomfam,sizeof(nomfam)); + for(int j=0;j<ngro;j++) + { + std::string cur2=MEDLoaderBase::buildStringFromFortran(gro+j*MED_LNAME_SIZE,MED_LNAME_SIZE); + if(cur2==grpName) + ret.push_back(cur); + } + } + return ret; +} + +std::vector<std::string> MEDLoader::GetMeshGroupsNamesOnFamily(const std::string& fileName, const std::string& meshName, const std::string& famName) +{ + CheckFileForRead(fileName); + MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName.c_str(),MED_ACC_RDONLY); + med_int nfam=MEDnFamily(fid,meshName.c_str()); + std::vector<std::string> ret; + char nomfam[MED_NAME_SIZE+1]; + med_int numfam; + bool found=false; + for(int i=0;i<nfam && !found;i++) + { + int ngro=MEDnFamilyGroup(fid,meshName.c_str(),i+1); + med_int natt=MEDnFamily23Attribute(fid,meshName.c_str(),i+1); + INTERP_KERNEL::AutoPtr<med_int> attide=new med_int[natt]; + INTERP_KERNEL::AutoPtr<med_int> attval=new med_int[natt]; + INTERP_KERNEL::AutoPtr<char> attdes=new char[MED_COMMENT_SIZE*natt+1]; + INTERP_KERNEL::AutoPtr<char> gro=new char[MED_LNAME_SIZE*ngro+1]; + MEDfamily23Info(fid,meshName.c_str(),i+1,nomfam,attide,attval,attdes,&numfam,gro); + std::string cur=MEDLoaderBase::buildStringFromFortran(nomfam,sizeof(nomfam)); + found=(cur==famName); + if(found) + for(int j=0;j<ngro;j++) + { + std::string cur2=MEDLoaderBase::buildStringFromFortran(gro+j*MED_LNAME_SIZE,MED_LNAME_SIZE); + ret.push_back(cur2); + } + } + if(!found) + { + std::ostringstream oss; + oss << "MEDLoader::GetMeshGroupsNamesOnFamily : no such family \"" << famName << "\" in file \"" << fileName << "\" in mesh \"" << meshName << "\" !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + return ret; +} + + +std::vector<std::string> MEDLoader::GetMeshGroupsNames(const std::string& fileName, const std::string& meshName) +{ + CheckFileForRead(fileName); + MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName.c_str(),MED_ACC_RDONLY); + med_int nfam=MEDnFamily(fid,meshName.c_str()); + std::vector<std::string> ret; + char nomfam[MED_NAME_SIZE+1]; + med_int numfam; + for(int i=0;i<nfam;i++) + { + int ngro=MEDnFamilyGroup(fid,meshName.c_str(),i+1); + med_int natt=MEDnFamily23Attribute(fid,meshName.c_str(),i+1); + INTERP_KERNEL::AutoPtr<med_int> attide=new med_int[natt]; + INTERP_KERNEL::AutoPtr<med_int> attval=new med_int[natt]; + INTERP_KERNEL::AutoPtr<char> attdes=new char[MED_COMMENT_SIZE*natt+1]; + INTERP_KERNEL::AutoPtr<char> gro=new char[MED_LNAME_SIZE*ngro+1]; + MEDfamily23Info(fid,meshName.c_str(),i+1,nomfam,attide,attval,attdes,&numfam,gro); + for(int j=0;j<ngro;j++) + { + std::string cur=MEDLoaderBase::buildStringFromFortran(gro+j*MED_LNAME_SIZE,MED_LNAME_SIZE); + if(std::find(ret.begin(),ret.end(),cur)==ret.end()) + ret.push_back(cur); + } + } + return ret; +} + +std::vector<ParaMEDMEM::TypeOfField> MEDLoader::GetTypesOfField(const std::string& fileName, const std::string& meshName, const std::string& fieldName) +{ + std::vector<ParaMEDMEM::TypeOfField> ret; + MEDCouplingAutoRefCountObjectPtr<MEDFileAnyTypeFieldMultiTS> fs(MEDFileAnyTypeFieldMultiTS::New(fileName,fieldName,false)); + if(fs->getMeshName()!=meshName) + { + std::ostringstream oss; oss << "MEDLoader::GetTypesOfField : The field \"" << fieldName << "\" in file \"" << fileName << "\" is not lying on mesh \"" << meshName << "\""; + oss << " The name of the mesh in file is \"" << fs->getMeshName() << "\"!"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + int nbTS(fs->getNumberOfTS()); + if(nbTS==0) + return ret; + for(int i=0;i<nbTS;i++) + { + MEDCouplingAutoRefCountObjectPtr<MEDFileAnyTypeField1TS> f1ts(fs->getTimeStepAtPos(i)); + std::vector<ParaMEDMEM::TypeOfField> tof(f1ts->getTypesOfFieldAvailable()); + for(std::vector<ParaMEDMEM::TypeOfField>::const_iterator it=tof.begin();it!=tof.end();it++) + if(std::find(ret.begin(),ret.end(),*it)==ret.end()) + ret.push_back(*it); + } + // sort ret to put before ON_NODES then ON_CELLS then the remaining. + std::vector<ParaMEDMEM::TypeOfField> ret2; + if(std::find(ret.begin(),ret.end(),ON_NODES)!=ret.end()) + ret2.push_back(ON_NODES); + if(std::find(ret.begin(),ret.end(),ON_CELLS)!=ret.end()) + ret2.push_back(ON_CELLS); + for(std::vector<ParaMEDMEM::TypeOfField>::const_iterator it=ret.begin();it!=ret.end();it++) + if(*it!=ON_NODES && *it!=ON_CELLS) + ret2.push_back(*it); + return ret2; +} + +std::vector<std::string> MEDLoader::GetAllFieldNames(const std::string& fileName) +{ + CheckFileForRead(fileName); + std::vector<std::string> ret; + MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName.c_str(),MED_ACC_RDONLY); + med_int nbFields=MEDnField(fid); + med_field_type typcha; + for(int i=0;i<nbFields;i++) + { + med_int ncomp(MEDfieldnComponent(fid,i+1)); + INTERP_KERNEL::AutoPtr<char> comp=new char[ncomp*MED_SNAME_SIZE+1]; + INTERP_KERNEL::AutoPtr<char> unit=new char[ncomp*MED_SNAME_SIZE+1]; + INTERP_KERNEL::AutoPtr<char> nomcha=MEDLoaderBase::buildEmptyString(MED_NAME_SIZE); + INTERP_KERNEL::AutoPtr<char> maa_ass=MEDLoaderBase::buildEmptyString(MED_NAME_SIZE); + INTERP_KERNEL::AutoPtr<char> dt_unit=new char[MED_LNAME_SIZE+1]; + med_int nbPdt; + med_bool localmesh; + MEDFILESAFECALLERRD0(MEDfieldInfo,(fid,i+1,nomcha,maa_ass,&localmesh,&typcha,comp,unit,dt_unit,&nbPdt)); + ret.push_back(std::string(nomcha)); + } + return ret; +} + +std::vector<std::string> MEDLoader::GetAllFieldNamesOnMesh(const std::string& fileName, const std::string& meshName) +{ + CheckFileForRead(fileName); + std::vector<std::string> ret; + MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName.c_str(),MED_ACC_RDONLY); + med_int nbFields=MEDnField(fid); + // + med_field_type typcha; + char *maa_ass=MEDLoaderBase::buildEmptyString(MED_NAME_SIZE); + char *nomcha=MEDLoaderBase::buildEmptyString(MED_NAME_SIZE); + // + for(int i=0;i<nbFields;i++) + { + med_int ncomp(MEDfieldnComponent(fid,i+1)); + INTERP_KERNEL::AutoPtr<char> comp=new char[ncomp*MED_SNAME_SIZE+1]; + INTERP_KERNEL::AutoPtr<char> unit=new char[ncomp*MED_SNAME_SIZE+1]; + INTERP_KERNEL::AutoPtr<char> dt_unit=new char[MED_LNAME_SIZE+1]; + med_int nbPdt; + med_bool localmesh; + MEDFILESAFECALLERRD0(MEDfieldInfo,(fid,i+1,nomcha,maa_ass,&localmesh,&typcha,comp,unit,dt_unit,&nbPdt)); + std::string curFieldName=MEDLoaderBase::buildStringFromFortran(nomcha,MED_NAME_SIZE+1); + std::string curMeshName=MEDLoaderBase::buildStringFromFortran(maa_ass,MED_NAME_SIZE+1); + // + if(curMeshName==meshName) + ret.push_back(curFieldName); + } + delete [] maa_ass; + delete [] nomcha; + return ret; +} + +std::vector<std::string> MEDLoader::GetFieldNamesOnMesh(ParaMEDMEM::TypeOfField type, const std::string& fileName, const std::string& meshName) +{ + CheckFileForRead(fileName); + switch(type) + { + case ON_CELLS: + return GetCellFieldNamesOnMesh(fileName,meshName); + case ON_NODES: + return GetNodeFieldNamesOnMesh(fileName,meshName); + default: + throw INTERP_KERNEL::Exception("Type of field specified not managed ! manages are ON_NODES or ON_CELLS !"); + } +} + +std::vector<std::string> MEDLoader::GetCellFieldNamesOnMesh(const std::string& fileName, const std::string& meshName) +{ + CheckFileForRead(fileName); + std::vector<std::string> ret; + MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName.c_str(),MED_ACC_RDONLY); + med_int nbFields=MEDnField(fid); + // + med_field_type typcha; + //med_int nbpdtnor=0,pflsize,*pflval,lnsize; + med_int numdt=0,numo=0; + med_float dt=0.0; + char pflname[MED_NAME_SIZE+1]=""; + char locname[MED_NAME_SIZE+1]=""; + INTERP_KERNEL::AutoPtr<char> maa_ass=MEDLoaderBase::buildEmptyString(MED_NAME_SIZE); + INTERP_KERNEL::AutoPtr<char> dt_unit=MEDLoaderBase::buildEmptyString(MED_LNAME_SIZE); + INTERP_KERNEL::AutoPtr<char> nomcha=MEDLoaderBase::buildEmptyString(MED_NAME_SIZE); + med_bool localmesh; + med_int nbPdt; + // + for(int i=0;i<nbFields;i++) + { + med_int ncomp(MEDfieldnComponent(fid,i+1)); + INTERP_KERNEL::AutoPtr<char> comp=new char[ncomp*MED_SNAME_SIZE+1]; + INTERP_KERNEL::AutoPtr<char> unit=new char[ncomp*MED_SNAME_SIZE+1]; + MEDFILESAFECALLERRD0(MEDfieldInfo,(fid,i+1,nomcha,maa_ass,&localmesh,&typcha,comp,unit,dt_unit,&nbPdt)); + std::string curFieldName=MEDLoaderBase::buildStringFromFortran(nomcha,MED_NAME_SIZE+1); + std::string curMeshName=MEDLoaderBase::buildStringFromFortran(maa_ass,MED_NAME_SIZE+1); + int profilesize,nbi; + if(curMeshName==meshName) + { + bool found=false; + for(int j=0;j<MED_N_CELL_FIXED_GEO && !found;j++) + { + if(nbPdt>0) + { + MEDFILESAFECALLERRD0(MEDfieldComputingStepInfo,(fid,nomcha,1,&numdt,&numo,&dt)); + med_int nbOfVal(MEDfieldnValueWithProfile(fid,nomcha,numdt,numo,MED_CELL,typmai[j],1,MED_COMPACT_PFLMODE, + pflname,&profilesize,locname,&nbi)); + if(nbOfVal>0) + { + found=true; + ret.push_back(curFieldName); + } + } + } + } + } + return ret; +} + +std::vector<std::string> MEDLoader::GetNodeFieldNamesOnMesh(const std::string& fileName, const std::string& meshName) +{ + CheckFileForRead(fileName); + std::vector<std::string> ret; + MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName.c_str(),MED_ACC_RDONLY); + med_int nbFields=MEDnField(fid); + char pflname[MED_NAME_SIZE+1]=""; + char locname[MED_NAME_SIZE+1]=""; + // + med_field_type typcha; + med_int numdt=0,numo=0; + med_float dt=0.0; + INTERP_KERNEL::AutoPtr<char> maa_ass=MEDLoaderBase::buildEmptyString(MED_NAME_SIZE); + INTERP_KERNEL::AutoPtr<char> dt_unit=MEDLoaderBase::buildEmptyString(MED_LNAME_SIZE); + INTERP_KERNEL::AutoPtr<char> nomcha=MEDLoaderBase::buildEmptyString(MED_NAME_SIZE); + med_bool localmesh; + // + for(int i=0;i<nbFields;i++) + { + med_int ncomp(MEDfieldnComponent(fid,i+1)); + INTERP_KERNEL::AutoPtr<char> comp=new char[ncomp*MED_SNAME_SIZE+1]; + INTERP_KERNEL::AutoPtr<char> unit=new char[ncomp*MED_SNAME_SIZE+1]; + med_int nbPdt; + MEDFILESAFECALLERRD0(MEDfieldInfo,(fid,i+1,nomcha,maa_ass,&localmesh,&typcha,comp,unit,dt_unit,&nbPdt)); + std::string curFieldName=MEDLoaderBase::buildStringFromFortran(nomcha,MED_NAME_SIZE+1); + std::string curMeshName=MEDLoaderBase::buildStringFromFortran(maa_ass,MED_NAME_SIZE+1); + if(nbPdt>0) + { + int profilesize,nbi; + MEDFILESAFECALLERRD0(MEDfieldComputingStepInfo,(fid,nomcha,1,&numdt,&numo,&dt)); + med_int nbOfVal(MEDfieldnValueWithProfile(fid,nomcha,numdt,numo,MED_NODE,MED_NONE,1,MED_COMPACT_PFLMODE, + pflname,&profilesize,locname,&nbi)); + if(curMeshName==meshName && nbOfVal>0) + { + ret.push_back(curFieldName); + } + } + } + return ret; +} + +std::vector< std::pair< std::pair<int,int>, double> > MEDLoader::GetAllFieldIterations(const std::string& fileName, const std::string& fieldName) +{ + CheckFileForRead(fileName); + std::vector< std::pair< std::pair<int,int>, double > > ret; + MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName.c_str(),MED_ACC_RDONLY); + med_int nbFields=MEDnField(fid); + // + med_field_type typcha; + med_int numdt=0,numo=0; + med_float dt=0.0; + INTERP_KERNEL::AutoPtr<char> maa_ass=MEDLoaderBase::buildEmptyString(MED_NAME_SIZE); + INTERP_KERNEL::AutoPtr<char> dt_unit=MEDLoaderBase::buildEmptyString(MED_LNAME_SIZE); + INTERP_KERNEL::AutoPtr<char> nomcha=MEDLoaderBase::buildEmptyString(MED_NAME_SIZE); + med_bool localmesh; + // + std::ostringstream oss; oss << "MEDLoader::GetAllFieldIterations : No field with name \"" << fieldName<< "\" in file \"" << fileName << "\" ! Possible fields are : "; + for(int i=0;i<nbFields;i++) + { + med_int ncomp(MEDfieldnComponent(fid,i+1)); + INTERP_KERNEL::AutoPtr<char> comp=new char[ncomp*MED_SNAME_SIZE+1]; + INTERP_KERNEL::AutoPtr<char> unit=new char[ncomp*MED_SNAME_SIZE+1]; + med_int nbPdt; + MEDFILESAFECALLERRD0(MEDfieldInfo,(fid,i+1,nomcha,maa_ass,&localmesh,&typcha,comp,unit,dt_unit,&nbPdt)); + std::string curFieldName=MEDLoaderBase::buildStringFromFortran(nomcha,MED_NAME_SIZE+1); + if(curFieldName==fieldName) + { + for(int k=0;k<nbPdt;k++) + { + MEDFILESAFECALLERRD0(MEDfieldComputingStepInfo,(fid,nomcha,k+1,&numdt,&numo,&dt)); + ret.push_back(std::make_pair(std::make_pair(numdt,numo),dt)); + } + return ret; + } + else + { + oss << "\"" << curFieldName << "\""; + if(i!=nbFields-1) oss << ", "; + } + } + oss << " !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); +} + +double MEDLoader::GetTimeAttachedOnFieldIteration(const std::string& fileName, const std::string& fieldName, int iteration, int order) +{ + CheckFileForRead(fileName); + MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName.c_str(),MED_ACC_RDONLY); + med_int nbFields=MEDnField(fid); + // + med_field_type typcha; + med_int numdt=0,numo=0; + med_float dt=0.0; + med_bool local; + INTERP_KERNEL::AutoPtr<char> maa_ass=MEDLoaderBase::buildEmptyString(MED_NAME_SIZE); + INTERP_KERNEL::AutoPtr<char> dt_unit=MEDLoaderBase::buildEmptyString(MED_LNAME_SIZE); + INTERP_KERNEL::AutoPtr<char> nomcha=MEDLoaderBase::buildEmptyString(MED_NAME_SIZE); + // + bool found=false; + bool found2=false; + double ret=std::numeric_limits<double>::max(); + for(int i=0;i<nbFields && !found;i++) + { + med_int ncomp(MEDfieldnComponent(fid,i+1)); + INTERP_KERNEL::AutoPtr<char> comp=new char[ncomp*MED_SNAME_SIZE+1]; + INTERP_KERNEL::AutoPtr<char> unit=new char[ncomp*MED_SNAME_SIZE+1]; + med_int nbPdt; + MEDFILESAFECALLERRD0(MEDfieldInfo,(fid,i+1,nomcha,maa_ass,&local,&typcha,comp,unit,dt_unit,&nbPdt)); + std::string curFieldName=MEDLoaderBase::buildStringFromFortran(nomcha,MED_NAME_SIZE+1); + if(curFieldName==fieldName) + { + found=true; + for(int k=0;k<nbPdt;k++) + { + MEDFILESAFECALLERRD0(MEDfieldComputingStepInfo,(fid,nomcha,k+1,&numdt,&numo,&dt)); + if(numdt==iteration && numo==order) + { + found2=true; + ret=dt; + } + } + } + } + if(!found || !found2) + { + std::ostringstream oss; + oss << "No such field with name \"" << fieldName << "\" and iteration,order=(" << iteration << "," << order << ") exists in file \"" << fileName << "\" !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + return ret; +} + +std::vector< std::pair<int,int> > MEDLoader::GetFieldIterations(ParaMEDMEM::TypeOfField type, const std::string& fileName, const std::string& meshName, const std::string& fieldName) +{ + CheckFileForRead(fileName); + switch(type) + { + case ON_CELLS: + return GetCellFieldIterations(fileName,meshName,fieldName); + case ON_NODES: + return GetNodeFieldIterations(fileName,meshName,fieldName); + default: + throw INTERP_KERNEL::Exception("Type of field specified not managed ! manages are ON_NODES or ON_CELLS !"); + } +} + +std::vector< std::pair<int,int> > MEDLoader::GetCellFieldIterations(const std::string& fileName, const std::string& meshName, const std::string& fieldName) +{ + CheckFileForRead(fileName); + std::string meshNameCpp(meshName); + std::vector< std::pair<int,int> > ret; + MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName.c_str(),MED_ACC_RDONLY); + med_int nbFields=MEDnField(fid); + // + med_field_type typcha; + med_int numdt=0,numo=0; + med_float dt=0.0; + char pflname[MED_NAME_SIZE+1]=""; + char locname[MED_NAME_SIZE+1]=""; + INTERP_KERNEL::AutoPtr<char> maa_ass=MEDLoaderBase::buildEmptyString(MED_NAME_SIZE); + INTERP_KERNEL::AutoPtr<char> dt_unit=MEDLoaderBase::buildEmptyString(MED_LNAME_SIZE); + INTERP_KERNEL::AutoPtr<char> nomcha=MEDLoaderBase::buildEmptyString(MED_NAME_SIZE); + med_bool localmesh; + // + std::ostringstream oss; oss << "MEDLoader::GetCellFieldIterations : No cell Field field with name \"" << fieldName<< "\" in file \"" << fileName << "\" ! Possible fields are : "; + std::set<std::string> s2; + for(int i=0;i<nbFields;i++) + { + med_int ncomp(MEDfieldnComponent(fid,i+1)); + INTERP_KERNEL::AutoPtr<char> comp=new char[ncomp*MED_SNAME_SIZE+1]; + INTERP_KERNEL::AutoPtr<char> unit=new char[ncomp*MED_SNAME_SIZE+1]; + med_int nbPdt; + MEDFILESAFECALLERRD0(MEDfieldInfo,(fid,i+1,nomcha,maa_ass,&localmesh,&typcha,comp,unit,dt_unit,&nbPdt)); + std::string curFieldName=MEDLoaderBase::buildStringFromFortran(nomcha,MED_NAME_SIZE+1); + if(curFieldName==fieldName) + { + bool found=false; + for(int j=0;j<MED_N_CELL_FIXED_GEO && !found;j++) + { + for(int k=0;k<nbPdt;k++) + { + int profilesize,nbi; + MEDFILESAFECALLERRD0(MEDfieldComputingStepInfo,(fid,nomcha,k+1,&numdt,&numo,&dt)); + med_int nbOfVal(MEDfieldnValueWithProfile(fid,nomcha,numdt,numo,MED_CELL,typmai[j],1,MED_COMPACT_PFLMODE, + pflname,&profilesize,locname,&nbi)); + std::string maa_ass_cpp(maa_ass); + if(nbOfVal>0) + { + if(meshNameCpp==maa_ass_cpp) + { + found=true; + ret.push_back(std::make_pair(numdt,numo)); + } + else + s2.insert(maa_ass_cpp); + } + } + } + } + else + { + oss << "\"" << curFieldName << "\""; + if(i!=nbFields-1) oss << ", "; + } + } + if(ret.empty()) + { + if(!s2.empty()) + { + oss << ". Cell Field \"" << fieldName << "\" exists but lies on meshes with names : \""; + std::copy(s2.begin(),s2.end(),std::ostream_iterator<std::string>(oss,"\", \"")); + } + oss << " !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + return ret; +} + +std::vector< std::pair<int,int> > MEDLoader::GetNodeFieldIterations(const std::string& fileName, const std::string& meshName, const std::string& fieldName) +{ + CheckFileForRead(fileName); + std::string meshNameCpp(meshName); + std::vector< std::pair<int,int> > ret; + MEDFileUtilities::AutoFid fid=MEDfileOpen(fileName.c_str(),MED_ACC_RDONLY); + med_int nbFields=MEDnField(fid); + // + med_field_type typcha; + med_int numdt=0,numo=0; + med_float dt=0.0; + char pflname[MED_NAME_SIZE+1]=""; + char locname[MED_NAME_SIZE+1]=""; + INTERP_KERNEL::AutoPtr<char> maa_ass=MEDLoaderBase::buildEmptyString(MED_NAME_SIZE); + INTERP_KERNEL::AutoPtr<char> dt_unit=MEDLoaderBase::buildEmptyString(MED_LNAME_SIZE); + INTERP_KERNEL::AutoPtr<char> nomcha=MEDLoaderBase::buildEmptyString(MED_NAME_SIZE); + med_bool localmesh; + // + std::ostringstream oss; oss << "MEDLoader::GetNodeFieldIterations : No node Field field with name \"" << fieldName<< "\" in file \"" << fileName << "\" ! Possible fields are : "; + std::set<std::string> s2; + for(int i=0;i<nbFields;i++) + { + med_int ncomp(MEDfieldnComponent(fid,i+1)); + INTERP_KERNEL::AutoPtr<char> comp=new char[ncomp*MED_SNAME_SIZE+1]; + INTERP_KERNEL::AutoPtr<char> unit=new char[ncomp*MED_SNAME_SIZE+1]; + med_int nbPdt; + MEDFILESAFECALLERRD0(MEDfieldInfo,(fid,i+1,nomcha,maa_ass,&localmesh,&typcha,comp,unit,dt_unit,&nbPdt)); + std::string curFieldName=MEDLoaderBase::buildStringFromFortran(nomcha,MED_NAME_SIZE+1); + if(curFieldName==fieldName) + { + for(int k=0;k<nbPdt;k++) + { + int profilesize,nbi; + MEDFILESAFECALLERRD0(MEDfieldComputingStepInfo,(fid,nomcha,k+1,&numdt,&numo,&dt)); + med_int nbOfVal(MEDfieldnValueWithProfile(fid,nomcha,numdt,numo,MED_NODE,MED_NONE,1,MED_COMPACT_PFLMODE, + pflname,&profilesize,locname,&nbi)); + std::string maa_ass_cpp(maa_ass); + if(nbOfVal>0) + { + if(meshNameCpp==maa_ass_cpp) + { ret.push_back(std::make_pair(numdt,numo)); } + else + s2.insert(maa_ass_cpp); + } + } + } + else + { + oss << "\"" << curFieldName << "\""; + if(i!=nbFields-1) oss << ", "; + } + } + if(ret.empty()) + { + if(!s2.empty()) + { + oss << ". Node Field \"" << fieldName << "\" exists but lies on meshes with names : \""; + std::copy(s2.begin(),s2.end(),std::ostream_iterator<std::string>(oss,"\", \"")); + } + oss << " !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + return ret; +} + +ParaMEDMEM::MEDCouplingMesh *MEDLoader::ReadMeshFromFile(const std::string& fileName, const std::string& meshName, int meshDimRelToMax) +{ + CheckFileForRead(fileName); + MEDCouplingAutoRefCountObjectPtr<MEDFileMesh> mm(MEDFileMesh::New(fileName,meshName)); + MEDFileMesh *mmPtr(mm); + MEDFileUMesh *mmuPtr=dynamic_cast<MEDFileUMesh *>(mmPtr); + if(mmuPtr) + return mmuPtr->getMeshAtLevel(meshDimRelToMax,true); + MEDFileCMesh *mmcPtr=dynamic_cast<MEDFileCMesh *>(mmPtr); + if(mmcPtr) + { + const MEDCouplingCMesh *ret(mmcPtr->getMesh()); ret->incrRef(); + return const_cast<MEDCouplingCMesh *>(ret); + } + MEDFileCurveLinearMesh *mmc2Ptr=dynamic_cast<MEDFileCurveLinearMesh *>(mmPtr); + if(mmc2Ptr) + { + const MEDCouplingCurveLinearMesh *ret(mmc2Ptr->getMesh()); ret->incrRef(); + return const_cast<MEDCouplingCurveLinearMesh *>(ret); + } + std::ostringstream oss; oss << "MEDLoader::ReadMeshFromFile : The mesh \"" << meshName << "\" in file \"" << fileName << "\" has not a recognized type !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); +} + +ParaMEDMEM::MEDCouplingMesh *MEDLoader::ReadMeshFromFile(const std::string& fileName, int meshDimRelToMax) +{ + CheckFileForRead(fileName); + MEDCouplingAutoRefCountObjectPtr<MEDFileMesh> mm(MEDFileMesh::New(fileName)); + MEDFileMesh *mmPtr(mm); + MEDFileUMesh *mmuPtr=dynamic_cast<MEDFileUMesh *>(mmPtr); + if(mmuPtr) + return mmuPtr->getMeshAtLevel(meshDimRelToMax,true); + MEDFileCMesh *mmcPtr=dynamic_cast<MEDFileCMesh *>(mmPtr); + if(mmcPtr) + { + const MEDCouplingCMesh *ret(mmcPtr->getMesh()); ret->incrRef(); + return const_cast<MEDCouplingCMesh *>(ret); + } + MEDFileCurveLinearMesh *mmc2Ptr=dynamic_cast<MEDFileCurveLinearMesh *>(mmPtr); + if(mmc2Ptr) + { + const MEDCouplingCurveLinearMesh *ret(mmc2Ptr->getMesh()); ret->incrRef(); + return const_cast<MEDCouplingCurveLinearMesh *>(ret); + } + std::ostringstream oss; oss << "MEDLoader::ReadMeshFromFile (2) : The first mesh \"" << mm->getName() << "\" in file \"" << fileName << "\" has not a recognized type !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); +} + +ParaMEDMEM::MEDCouplingUMesh *MEDLoader::ReadUMeshFromFile(const std::string& fileName, const std::string& meshName, int meshDimRelToMax) +{ + CheckFileForRead(fileName); + MEDCouplingAutoRefCountObjectPtr<MEDFileMesh> mm(MEDFileMesh::New(fileName,meshName)); + MEDFileMesh *mmPtr(mm); + MEDFileUMesh *mmuPtr=dynamic_cast<MEDFileUMesh *>(mmPtr); + if(!mmuPtr) + { + std::ostringstream oss; oss << "MEDLoader::ReadUMeshFromFile : With fileName=\""<< fileName << "\", meshName=\""<< meshName << "\" exists but it is not an unstructured mesh !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + return mmuPtr->getMeshAtLevel(meshDimRelToMax,true); +} + +ParaMEDMEM::MEDCouplingUMesh *MEDLoader::ReadUMeshFromFile(const std::string& fileName, int meshDimRelToMax) +{ + CheckFileForRead(fileName); + MEDCouplingAutoRefCountObjectPtr<MEDFileMesh> mm(MEDFileMesh::New(fileName)); + MEDFileMesh *mmPtr(mm); + MEDFileUMesh *mmuPtr=dynamic_cast<MEDFileUMesh *>(mmPtr); + if(!mmuPtr) + { + std::ostringstream oss; oss << "MEDLoader::ReadUMeshFromFile : With fileName=\""<< fileName << "\", meshName (the first) =\""<< mm->getName() << "\" exists but it is not an unstructured mesh !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + return mmuPtr->getMeshAtLevel(meshDimRelToMax,true); +} + +int MEDLoader::ReadUMeshDimFromFile(const std::string& fileName, const std::string& meshName) +{ + CheckFileForRead(fileName); + std::vector<int> poss; + return MEDLoaderNS::readUMeshDimFromFile(fileName,meshName,poss); +} + +ParaMEDMEM::MEDCouplingUMesh *MEDLoader::ReadUMeshFromFamilies(const std::string& fileName, const std::string& meshName, int meshDimRelToMax, const std::vector<std::string>& fams) +{ + CheckFileForRead(fileName); + MEDCouplingAutoRefCountObjectPtr<MEDFileMesh> mm(MEDFileMesh::New(fileName,meshName)); + MEDFileMesh *mmPtr(mm); + MEDFileUMesh *mmuPtr=dynamic_cast<MEDFileUMesh *>(mmPtr); + if(!mmuPtr) + { + std::ostringstream oss; oss << "MEDLoader::ReadUMeshFromFamilies : With fileName=\""<< fileName << "\", meshName (the first) =\""<< mm->getName() << "\" exists but it is not an unstructured mesh !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + return mmuPtr->getFamilies(meshDimRelToMax,fams,true); +} + +ParaMEDMEM::MEDCouplingUMesh *MEDLoader::ReadUMeshFromGroups(const std::string& fileName, const std::string& meshName, int meshDimRelToMax, const std::vector<std::string>& grps) +{ + CheckFileForRead(fileName); + MEDCouplingAutoRefCountObjectPtr<MEDFileMesh> mm=MEDFileMesh::New(fileName,meshName); + MEDFileMesh *mmPtr(mm); + MEDFileUMesh *mmuPtr=dynamic_cast<MEDFileUMesh *>(mmPtr); + if(!mmuPtr) + { + std::ostringstream oss; oss << "MEDLoader::ReadUMeshFromGroups : With fileName=\""<< fileName << "\", meshName (the first) =\""<< mm->getName() << "\" exists but it is not an unstructured mesh !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + return mmuPtr->getGroups(meshDimRelToMax,grps,true); +} + +ParaMEDMEM::MEDCouplingFieldDouble *MEDLoader::ReadField(ParaMEDMEM::TypeOfField type, const std::string& fileName, const std::string& meshName, int meshDimRelToMax, const std::string& fieldName, int iteration, int order) +{ + CheckFileForRead(fileName); + switch(type) + { + case ON_CELLS: + return ReadFieldCell(fileName,meshName,meshDimRelToMax,fieldName,iteration,order); + case ON_NODES: + return ReadFieldNode(fileName,meshName,meshDimRelToMax,fieldName,iteration,order); + case ON_GAUSS_PT: + return ReadFieldGauss(fileName,meshName,meshDimRelToMax,fieldName,iteration,order); + case ON_GAUSS_NE: + return ReadFieldGaussNE(fileName,meshName,meshDimRelToMax,fieldName,iteration,order); + default: + throw INTERP_KERNEL::Exception("Type of field specified not managed ! manages are ON_NODES, ON_CELLS, ON_GAUSS_PT or ON_GAUSS_NE !"); + } +} + +std::vector<ParaMEDMEM::MEDCouplingFieldDouble *> MEDLoader::ReadFieldsOnSameMesh(ParaMEDMEM::TypeOfField type, const std::string& fileName, const std::string& meshName, int meshDimRelToMax, const std::string& fieldName, + const std::vector<std::pair<int,int> >& its) +{ + if(its.empty()) + return std::vector<ParaMEDMEM::MEDCouplingFieldDouble *>(); + CheckFileForRead(fileName); + std::vector<ParaMEDMEM::MEDCouplingFieldDouble *> ret(its.size()); + std::vector< MEDCouplingAutoRefCountObjectPtr<MEDCouplingFieldDouble> > retSafe(its.size()); + if(its.empty()) + return ret; + //Retrieving mesh of rank 0 and field on rank 0 too. + MEDCouplingAutoRefCountObjectPtr<MEDFileMesh> mm=MEDFileMesh::New(fileName,meshName); + MEDFileMesh *mmPtr(mm); + MEDFileUMesh *mmuPtr=dynamic_cast<MEDFileUMesh *>(mmPtr); + if(!mmuPtr) + throw INTERP_KERNEL::Exception("MEDLoader::ReadFieldsOnSameMesh : only unstructured mesh is managed !"); + MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m=mmuPtr->getMeshAtLevel(meshDimRelToMax); + const DataArrayInt *o2n=mmuPtr->getNumberFieldAtLevel(meshDimRelToMax); + MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> m2(m->clone(true)); + if(o2n) + m2->renumberCells(o2n->begin(),true); + int i=0; + for(std::vector<std::pair<int,int> >::const_iterator it=its.begin();it!=its.end();it++,i++) + { + MEDCouplingAutoRefCountObjectPtr<MEDFileField1TS> ff=MEDFileField1TS::New(fileName,fieldName,(*it).first,(*it).second); + MEDCouplingAutoRefCountObjectPtr<MEDCouplingFieldDouble> retElt=ff->getFieldOnMeshAtLevel(type,m); + if(o2n) + retElt->renumberCells(o2n->begin(),true); + retElt->setMesh(m2); + retSafe[i]=retElt; + } + i=0; + for(std::vector<std::pair<int,int> >::const_iterator it=its.begin();it!=its.end();it++,i++) + ret[i]=retSafe[i].retn(); + return ret; +} + +std::vector<ParaMEDMEM::MEDCouplingFieldDouble *> MEDLoader::ReadFieldsCellOnSameMesh(const std::string& fileName, const std::string& meshName, int meshDimRelToMax, const std::string& fieldName, + const std::vector<std::pair<int,int> >& its) +{ + return ReadFieldsOnSameMesh(ON_CELLS,fileName,meshName,meshDimRelToMax,fieldName,its); +} + +std::vector<ParaMEDMEM::MEDCouplingFieldDouble *> MEDLoader::ReadFieldsNodeOnSameMesh(const std::string& fileName, const std::string& meshName, int meshDimRelToMax, const std::string& fieldName, + const std::vector<std::pair<int,int> >& its) +{ + return ReadFieldsOnSameMesh(ON_NODES,fileName,meshName,meshDimRelToMax,fieldName,its); +} + +std::vector<ParaMEDMEM::MEDCouplingFieldDouble *> MEDLoader::ReadFieldsGaussOnSameMesh(const std::string& fileName, const std::string& meshName, int meshDimRelToMax, const std::string& fieldName, + const std::vector<std::pair<int,int> >& its) +{ + return ReadFieldsOnSameMesh(ON_GAUSS_PT,fileName,meshName,meshDimRelToMax,fieldName,its); +} + +std::vector<ParaMEDMEM::MEDCouplingFieldDouble *> MEDLoader::ReadFieldsGaussNEOnSameMesh(const std::string& fileName, const std::string& meshName, int meshDimRelToMax, const std::string& fieldName, + const std::vector<std::pair<int,int> >& its) +{ + return ReadFieldsOnSameMesh(ON_GAUSS_NE,fileName,meshName,meshDimRelToMax,fieldName,its); +} + +ParaMEDMEM::MEDCouplingFieldDouble *MEDLoader::ReadFieldCell(const std::string& fileName, const std::string& meshName, int meshDimRelToMax, const std::string& fieldName, int iteration, int order) +{ + MEDCouplingAutoRefCountObjectPtr<MEDFileField1TS> ff=MEDFileField1TS::New(fileName,fieldName,iteration,order); + MEDCouplingAutoRefCountObjectPtr<MEDFileMesh> mm=MEDFileMesh::New(fileName,meshName); + MEDCouplingAutoRefCountObjectPtr<MEDCouplingMesh> m=mm->getGenMeshAtLevel(meshDimRelToMax,false); + MEDFileMesh *mPtr(mm); + MEDFileUMesh *muPtr=dynamic_cast<MEDFileUMesh *>(mPtr); + MEDCouplingAutoRefCountObjectPtr<MEDCouplingFieldDouble> ret=ff->getFieldOnMeshAtLevel(ON_CELLS,m); + if(muPtr) + { + const DataArrayInt *num=muPtr->getNumberFieldAtLevel(meshDimRelToMax); + if(num) + ret->renumberCells(num->begin()); + } + return ret.retn(); +} + +ParaMEDMEM::MEDCouplingFieldDouble *MEDLoader::ReadFieldNode(const std::string& fileName, const std::string& meshName, int meshDimRelToMax, const std::string& fieldName, int iteration, int order) +{ + MEDCouplingAutoRefCountObjectPtr<MEDFileField1TS> ff=MEDFileField1TS::New(fileName,fieldName,iteration,order); + MEDCouplingAutoRefCountObjectPtr<MEDFileMesh> mm=MEDFileMesh::New(fileName,meshName); + MEDCouplingAutoRefCountObjectPtr<MEDCouplingMesh> m=mm->getGenMeshAtLevel(meshDimRelToMax,false); + MEDFileMesh *mPtr(mm); + MEDCouplingAutoRefCountObjectPtr<MEDCouplingFieldDouble> ret=ff->getFieldOnMeshAtLevel(ON_NODES,m); + MEDFileUMesh *muPtr=dynamic_cast<MEDFileUMesh *>(mPtr); + if(ff->getPflsReallyUsed().empty()) + { + if(muPtr) + { + const DataArrayInt *num=muPtr->getNumberFieldAtLevel(meshDimRelToMax); + if(num) + ret->renumberCells(num->begin()); + } + } + else + { + DataArrayInt *pfl=0,*arr2=0; + MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> arr=ff->getFieldWithProfile(ON_NODES,meshDimRelToMax,mm,pfl); + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> pflSafe(pfl); + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> mp=m->getCellIdsFullyIncludedInNodeIds(pfl->begin(),pfl->end()); + MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> mzip=static_cast<MEDCouplingUMesh *>(m->buildPartAndReduceNodes(mp->begin(),mp->end(),arr2)); + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> arr2Safe(arr2); + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> arr3=arr2->invertArrayO2N2N2O(mzip->getNumberOfNodes()); + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> pflSorted(pflSafe->deepCpy()); pflSorted->sort(true); + if(!arr3->isEqualWithoutConsideringStr(*pflSorted)) + throw INTERP_KERNEL::Exception("MEDLoader::ReadFieldNode : not implemented yet !"); + if(!arr3->isEqualWithoutConsideringStr(*pflSafe)) + { + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> o2n2=pflSafe->checkAndPreparePermutation(); + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> n2o2=o2n2->invertArrayO2N2N2O(o2n2->getNumberOfTuples()); + mzip->renumberNodes(n2o2->begin(),n2o2->getNumberOfTuples()); + arr->setName(""); + ret->setArray(arr); + } + ret->setMesh(mzip); + } + return ret.retn(); +} + +ParaMEDMEM::MEDCouplingFieldDouble *MEDLoader::ReadFieldGauss(const std::string& fileName, const std::string& meshName, int meshDimRelToMax, const std::string& fieldName, int iteration, int order) +{ + MEDCouplingAutoRefCountObjectPtr<MEDFileField1TS> ff=MEDFileField1TS::New(fileName,fieldName,iteration,order); + MEDCouplingAutoRefCountObjectPtr<MEDFileMesh> mm=MEDFileMesh::New(fileName,meshName); + MEDCouplingAutoRefCountObjectPtr<MEDCouplingMesh> m=mm->getGenMeshAtLevel(meshDimRelToMax,false); + MEDFileMesh *mPtr(mm); + MEDFileUMesh *muPtr=dynamic_cast<MEDFileUMesh *>(mPtr); + MEDCouplingAutoRefCountObjectPtr<MEDCouplingFieldDouble> ret=ff->getFieldOnMeshAtLevel(ON_GAUSS_PT,m); + if(muPtr) + { + const DataArrayInt *num=muPtr->getNumberFieldAtLevel(meshDimRelToMax); + if(num) + ret->renumberCells(num->begin()); + } + return ret.retn(); +} + +ParaMEDMEM::MEDCouplingFieldDouble *MEDLoader::ReadFieldGaussNE(const std::string& fileName, const std::string& meshName, int meshDimRelToMax, const std::string& fieldName, int iteration, int order) +{ + MEDCouplingAutoRefCountObjectPtr<MEDFileField1TS> ff=MEDFileField1TS::New(fileName,fieldName,iteration,order); + MEDCouplingAutoRefCountObjectPtr<MEDFileMesh> mm=MEDFileMesh::New(fileName,meshName); + MEDCouplingAutoRefCountObjectPtr<MEDCouplingMesh> m=mm->getGenMeshAtLevel(meshDimRelToMax,false); + MEDFileMesh *mPtr(mm); + MEDFileUMesh *muPtr=dynamic_cast<MEDFileUMesh *>(mPtr); + MEDCouplingAutoRefCountObjectPtr<MEDCouplingFieldDouble> ret=ff->getFieldOnMeshAtLevel(ON_GAUSS_NE,m); + if(muPtr) + { + const DataArrayInt *num=muPtr->getNumberFieldAtLevel(meshDimRelToMax); + if(num) + ret->renumberCells(num->begin()); + } + return ret.retn(); +} + +void MEDLoader::WriteMesh(const std::string& fileName, const ParaMEDMEM::MEDCouplingMesh *mesh, bool writeFromScratch) +{ + if(!mesh) + throw INTERP_KERNEL::Exception("MEDLoader::WriteMesh : input mesh is null !"); + const MEDCouplingUMesh *um(dynamic_cast<const MEDCouplingUMesh *>(mesh)); + if(um) + { + WriteUMesh(fileName,um,writeFromScratch); + return ; + } + int mod=writeFromScratch?2:0; + const MEDCoupling1GTUMesh *um2(dynamic_cast<const MEDCoupling1GTUMesh *>(mesh)); + if(um2) + { + MEDCouplingAutoRefCountObjectPtr<MEDFileUMesh> mmu(MEDFileUMesh::New()); + AssignStaticWritePropertiesTo(*mmu); + mmu->setMeshAtLevel(0,const_cast<MEDCoupling1GTUMesh *>(um2)); + mmu->write(fileName,mod); + return ; + } + const MEDCouplingCMesh *um3(dynamic_cast<const MEDCouplingCMesh *>(mesh)); + if(um3) + { + MEDCouplingAutoRefCountObjectPtr<MEDFileCMesh> mmc(MEDFileCMesh::New()); + AssignStaticWritePropertiesTo(*mmc); + mmc->setMesh(const_cast<MEDCouplingCMesh *>(um3)); + mmc->write(fileName,mod); + return ; + } + const MEDCouplingCurveLinearMesh *um4(dynamic_cast<const MEDCouplingCurveLinearMesh *>(mesh)); + if(um4) + { + MEDCouplingAutoRefCountObjectPtr<MEDFileCurveLinearMesh> mmc(MEDFileCurveLinearMesh::New()); + AssignStaticWritePropertiesTo(*mmc); + mmc->setMesh(const_cast<MEDCouplingCurveLinearMesh *>(um4)); + mmc->write(fileName,mod); + return ; + } + throw INTERP_KERNEL::Exception("MEDLoader::WriteMesh : only MEDCouplingUMesh, MEDCoupling1GTUMesh, MEDCouplingCMesh, MEDCouplingCurveLinear are dealed in this API for the moment !"); +} + +void MEDLoader::WriteUMesh(const std::string& fileName, const ParaMEDMEM::MEDCouplingUMesh *mesh, bool writeFromScratch) +{ + if(!mesh) + throw INTERP_KERNEL::Exception("MEDLoader::WriteUMesh : input mesh is null !"); + int mod=writeFromScratch?2:0; + MEDCouplingAutoRefCountObjectPtr<MEDFileUMesh> m(MEDFileUMesh::New()); + AssignStaticWritePropertiesTo(*m); + MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> mcpy(static_cast<MEDCouplingUMesh *>(mesh->deepCpy())); + m->setMeshAtLevel(0,mcpy,true); + m->write(fileName,mod); +} + +void MEDLoader::WriteUMeshDep(const std::string& fileName, const ParaMEDMEM::MEDCouplingUMesh *mesh, bool writeFromScratch) +{ + MEDLoader::WriteUMesh(fileName,mesh,writeFromScratch); +} + +void MEDLoader::WriteUMeshesPartition(const std::string& fileName, const std::string& meshNameC, const std::vector<const ParaMEDMEM::MEDCouplingUMesh *>& meshes, bool writeFromScratch) +{ + std::string meshName(meshNameC); + if(meshName.empty()) + throw INTERP_KERNEL::Exception("Trying to write a unstructured mesh with no name ! MED file format needs a not empty mesh name : change 2nd parameter !"); + int status=MEDLoaderBase::getStatusOfFile(fileName); + if(status!=MEDLoaderBase::EXIST_RW && status!=MEDLoaderBase::NOT_EXIST) + { + std::ostringstream oss; oss << "File with name \'" << fileName << "\' has not valid permissions !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + MEDCouplingAutoRefCountObjectPtr<MEDFileUMesh> m(MEDFileUMesh::New()); + AssignStaticWritePropertiesTo(*m); + m->setGroupsFromScratch(0,meshes,true); + m->setName(meshNameC); + int mod=writeFromScratch?2:0; + m->write(fileName,mod); +} + +void MEDLoader::WriteUMeshesPartitionDep(const std::string& fileName, const std::string& meshNameC, const std::vector<const ParaMEDMEM::MEDCouplingUMesh *>& meshes, bool writeFromScratch) +{ + WriteUMeshesPartition(fileName,meshNameC,meshes,writeFromScratch); +} + +void MEDLoader::WriteUMeshes(const std::string& fileName, const std::vector<const ParaMEDMEM::MEDCouplingUMesh *>& meshes, bool writeFromScratch) +{ + int mod=writeFromScratch?2:0; + MEDCouplingAutoRefCountObjectPtr<MEDFileUMesh> m(MEDFileUMesh::New()); + AssignStaticWritePropertiesTo(*m); + m->setMeshes(meshes,true); + m->write(fileName,mod); +} + +void MEDLoaderNS::writeFieldWithoutReadingAndMappingOfMeshInFile(const std::string& fileName, const ParaMEDMEM::MEDCouplingFieldDouble *f, bool writeFromScratch) +{ + MEDCouplingAutoRefCountObjectPtr<MEDFileField1TS> ff(MEDFileField1TS::New()); + MEDLoader::AssignStaticWritePropertiesTo(*ff); + MEDCouplingAutoRefCountObjectPtr<MEDCouplingFieldDouble> f2(f->deepCpy()); + const MEDCouplingMesh *m(f2->getMesh()); + const MEDCouplingUMesh *um(dynamic_cast<const MEDCouplingUMesh *>(m)); + const MEDCoupling1GTUMesh *um2(dynamic_cast<const MEDCoupling1GTUMesh *>(m)); + const MEDCouplingCMesh *um3(dynamic_cast<const MEDCouplingCMesh *>(m)); + const MEDCouplingCurveLinearMesh *um4(dynamic_cast<const MEDCouplingCurveLinearMesh *>(m)); + MEDCouplingAutoRefCountObjectPtr<MEDFileMesh> mm; + int mod=writeFromScratch?2:0; + if(um) + { + MEDCouplingAutoRefCountObjectPtr<MEDFileUMesh> mmu(MEDFileUMesh::New()); + MEDLoader::AssignStaticWritePropertiesTo(*mmu); + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> o2n(um->getRenumArrForMEDFileFrmt()); + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> n2o(o2n->invertArrayO2N2N2O(o2n->getNumberOfTuples())); + f2->renumberCells(o2n->begin(),false); + mmu->setMeshAtLevel(0,const_cast<MEDCouplingUMesh *>(static_cast<const MEDCouplingUMesh *>(f2->getMesh()))); + mmu->setRenumFieldArr(0,n2o); + ff->setFieldNoProfileSBT(f2); + mmu->write(fileName,mod); + } + else if(um2) + { + MEDCouplingAutoRefCountObjectPtr<MEDFileUMesh> mmu(MEDFileUMesh::New()); + MEDLoader::AssignStaticWritePropertiesTo(*mmu); + mmu->setMeshAtLevel(0,const_cast<MEDCoupling1GTUMesh *>(um2)); + ff->setFieldNoProfileSBT(f2); + mmu->write(fileName,mod); + } + else if(um3) + { + MEDCouplingAutoRefCountObjectPtr<MEDFileCMesh> mmc(MEDFileCMesh::New()); + MEDLoader::AssignStaticWritePropertiesTo(*mmc); + mmc->setMesh(const_cast<MEDCouplingCMesh *>(um3)); + ff->setFieldNoProfileSBT(f2); + mmc->write(fileName,mod); + } + else if(um4) + { + MEDCouplingAutoRefCountObjectPtr<MEDFileCurveLinearMesh> mmc(MEDFileCurveLinearMesh::New()); + MEDLoader::AssignStaticWritePropertiesTo(*mmc); + mmc->setMesh(const_cast<MEDCouplingCurveLinearMesh *>(um4)); + ff->setFieldNoProfileSBT(f2); + mmc->write(fileName,mod); + } + else + throw INTERP_KERNEL::Exception("MEDLoaderNS::writeFieldWithoutReadingAndMappingOfMeshInFile : only MEDCouplingUMesh, MEDCoupling1GTUMesh, MEDCouplingCMesh, MEDCouplingCurveLinear are dealed in this API for the moment !"); + ff->write(fileName,0); +} + +void MEDLoader::WriteField(const std::string& fileName, const ParaMEDMEM::MEDCouplingFieldDouble *f, bool writeFromScratch) +{ + if(!f) + throw INTERP_KERNEL::Exception("MEDLoader::WriteField : input field is NULL !"); + f->checkCoherency(); + int status=MEDLoaderBase::getStatusOfFile(fileName); + if(status!=MEDLoaderBase::EXIST_RW && status!=MEDLoaderBase::NOT_EXIST) + { + std::ostringstream oss; oss << "File with name \'" << fileName << "\' has not valid permissions !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + if(writeFromScratch || (!writeFromScratch && status==MEDLoaderBase::NOT_EXIST)) + { + MEDLoaderNS::writeFieldWithoutReadingAndMappingOfMeshInFile(fileName,f,true); + } + else + { + std::vector<std::string> meshNames=GetMeshNames(fileName); + if(!f->getMesh()) + throw INTERP_KERNEL::Exception("MEDLoader::WriteField : trying to write a field with no mesh !"); + std::string fileNameCpp(f->getMesh()->getName()); + if(std::find(meshNames.begin(),meshNames.end(),fileNameCpp)==meshNames.end()) + MEDLoaderNS::writeFieldWithoutReadingAndMappingOfMeshInFile(fileName,f,false); + else + { + MEDCouplingAutoRefCountObjectPtr<MEDFileMesh> mm(MEDFileMesh::New(fileName,f->getMesh()->getName().c_str())); + AssignStaticWritePropertiesTo(*mm); + const MEDFileMesh *mmPtr(mm); + const MEDFileUMesh *mmuPtr=dynamic_cast<const MEDFileUMesh *>(mmPtr); + if(!mmuPtr) + throw INTERP_KERNEL::Exception("MEDLoader::WriteField : only umeshes are supported now !"); + MEDCouplingAutoRefCountObjectPtr<MEDCouplingFieldDouble> f2(f->deepCpy()); + MEDCouplingUMesh *m=dynamic_cast<MEDCouplingUMesh *>(const_cast<MEDCouplingMesh *>(f2->getMesh())); + if(!m) + throw INTERP_KERNEL::Exception("MEDLoader::WriteField : only umesh in input field supported !"); + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> o2n=m->getRenumArrForMEDFileFrmt(); + f2->renumberCells(o2n->begin(),false); + m=static_cast<MEDCouplingUMesh *>(const_cast<MEDCouplingMesh *>(f2->getMesh())); + MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> mread=mmuPtr->getMeshAtLevel(m->getMeshDimension()-mm->getMeshDimension()); + if(f2->getTypeOfField()!=ON_NODES) + { + m->tryToShareSameCoordsPermute(*mread,_EPS_FOR_NODE_COMP); + DataArrayInt *part=0; + bool b=mread->areCellsIncludedIn(m,_COMP_FOR_CELL,part); + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> partSafe(part); + if(!b) + { + std::ostringstream oss; oss << "MEDLoader::WriteField : The file \""<< fileName << "\" already contains a mesh named \""<< f->getMesh()->getName() << "\" and this mesh in the file is not compatible (a subpart) with the mesh you intend to write ! This is maybe due to a too strict policy ! Try with to lease it by calling SetCompPolicyForCell !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + MEDCouplingAutoRefCountObjectPtr<MEDFileField1TS> f1ts(MEDFileField1TS::New()); + AssignStaticWritePropertiesTo(*f1ts); + if(part->isIdentity() && part->getNumberOfTuples()==mread->getNumberOfCells()) + f1ts->setFieldNoProfileSBT(f2); + else + { + part->setName(f1ts->createNewNameOfPfl().c_str()); + f1ts->setFieldProfile(f2,mm,m->getMeshDimension()-mm->getMeshDimension(),part); + } + f1ts->write(fileName,0); + return ; + } + else + { + DataArrayInt *part=0; + bool b=mread->getCoords()->areIncludedInMe(m->getCoords(),_EPS_FOR_NODE_COMP,part); + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> partSafe(part); + if(!b) + { + std::ostringstream oss; oss << "MEDLoader::WriteField : The file \""<< fileName << "\" already contains a mesh named \""<< f->getMesh()->getName() << "\" and this mesh in the file is not compatible (a subpart regarding nodes) with the mesh you intend to write ! This is maybe due to a too strict epsilon ! Try with to lease it by calling SetEpsilonForNodeComp !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + MEDCouplingAutoRefCountObjectPtr<MEDFileField1TS> f1ts(MEDFileField1TS::New()); + AssignStaticWritePropertiesTo(*f1ts); + if(part->isIdentity() && part->getNumberOfTuples()==mread->getNumberOfNodes()) + f1ts->setFieldNoProfileSBT(f2); + else + { + part->setName(f1ts->createNewNameOfPfl().c_str()); + f1ts->setFieldProfile(f2,mm,m->getMeshDimension()-mm->getMeshDimension(),part); + } + f1ts->write(fileName,0); + } + } + } +} + +void MEDLoader::WriteFieldDep(const std::string& fileName, const ParaMEDMEM::MEDCouplingFieldDouble *f, bool writeFromScratch) +{ + WriteField(fileName,f,writeFromScratch); +} + +void MEDLoader::WriteFieldUsingAlreadyWrittenMesh(const std::string& fileName, const ParaMEDMEM::MEDCouplingFieldDouble *f) +{ + if(!f) + throw INTERP_KERNEL::Exception("MEDLoader::WriteFieldUsingAlreadyWrittenMesh : input field is null !"); + f->checkCoherency(); + int status=MEDLoaderBase::getStatusOfFile(fileName); + if(status!=MEDLoaderBase::EXIST_RW) + { + std::ostringstream oss; oss << "File with name \'" << fileName << "\' has not valid permissions or not exists !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + MEDCouplingAutoRefCountObjectPtr<MEDFileField1TS> f1ts(MEDFileField1TS::New()); + AssignStaticWritePropertiesTo(*f1ts); + MEDCouplingUMesh *m(dynamic_cast<MEDCouplingUMesh *>(const_cast<MEDCouplingMesh *>(f->getMesh()))); + if(m) + { + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> o2n(m->getRenumArrForMEDFileFrmt()); + MEDCouplingAutoRefCountObjectPtr<MEDCouplingFieldDouble> f2(f->deepCpy()); + f2->renumberCells(o2n->begin(),false); + f1ts->setFieldNoProfileSBT(f2); + } + else + f1ts->setFieldNoProfileSBT(f); + f1ts->write(fileName,0); +} diff --git a/src/medtool/src/MEDLoader/MEDLoader.hxx b/src/medtool/src/MEDLoader/MEDLoader.hxx new file mode 100644 index 000000000..df2bfa462 --- /dev/null +++ b/src/medtool/src/MEDLoader/MEDLoader.hxx @@ -0,0 +1,111 @@ +// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 +// 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 __MEDLOADER_HXX__ +#define __MEDLOADER_HXX__ + +#include "MEDLoaderDefines.hxx" +#include "InterpKernelException.hxx" +#include "MEDCouplingRefCountObject.hxx" +#include "NormalizedUnstructuredMesh.hxx" + +#include <list> +#include <vector> + +namespace ParaMEDMEM +{ + class DataArrayInt; + class MEDCouplingMesh; + class MEDCouplingUMesh; + class MEDCouplingFieldDouble; + class MEDFileWritable; +} + +class MEDLOADER_EXPORT MEDLoader +{ +public: + static void SetEpsilonForNodeComp(double val); + static void SetCompPolicyForCell(int val); + static void SetTooLongStrPolicy(int val); + static bool HasXDR(); + static std::string MEDFileVersionStr(); + static void MEDFileVersion(int& major, int& minor, int& release); + static void CheckFileForRead(const std::string& fileName); + static std::vector<std::string> GetMeshNames(const std::string& fileName); + static std::vector< std::vector< std::pair<INTERP_KERNEL::NormalizedCellType,int> > > GetUMeshGlobalInfo(const std::string& fileName, const std::string& meshName, int &meshDim, int& spaceDim, int& numberOfNodes); + static std::vector< std::pair<std::string,std::string> > GetComponentsNamesOfField(const std::string& fileName, const std::string& fieldName); + static std::vector<std::string> GetMeshNamesOnField(const std::string& fileName, const std::string& fieldName); + static std::vector<std::string> GetMeshGroupsNames(const std::string& fileName, const std::string& meshName); + static std::vector<std::string> GetMeshFamiliesNames(const std::string& fileName, const std::string& meshName); + static std::vector<std::string> GetMeshFamiliesNamesOnGroup(const std::string& fileName, const std::string& meshName, const std::string& grpName); + static std::vector<std::string> GetMeshGroupsNamesOnFamily(const std::string& fileName, const std::string& meshName, const std::string& famName); + static std::vector<std::string> GetAllFieldNames(const std::string& fileName); + static std::vector<std::string> GetAllFieldNamesOnMesh(const std::string& fileName, const std::string& meshName); + static std::vector<ParaMEDMEM::TypeOfField> GetTypesOfField(const std::string& fileName, const std::string& meshName, const std::string& fieldName); + static std::vector<std::string> GetFieldNamesOnMesh(ParaMEDMEM::TypeOfField type, const std::string& fileName, const std::string& meshName); + static std::vector<std::string> GetCellFieldNamesOnMesh(const std::string& fileName, const std::string& meshName); + static std::vector<std::string> GetNodeFieldNamesOnMesh(const std::string& fileName, const std::string& meshName); + static std::vector< std::pair<int,int> > GetFieldIterations(ParaMEDMEM::TypeOfField type, const std::string& fileName, const std::string& meshName, const std::string& fieldName); + static std::vector< std::pair<int,int> > GetCellFieldIterations(const std::string& fileName, const std::string& meshName, const std::string& fieldName); + static std::vector< std::pair<int,int> > GetNodeFieldIterations(const std::string& fileName, const std::string& meshName, const std::string& fieldName); + static std::vector< std::pair< std::pair<int,int>, double> > GetAllFieldIterations(const std::string& fileName, const std::string& fieldName); + static double GetTimeAttachedOnFieldIteration(const std::string& fileName, const std::string& fieldName, int iteration, int order); + static ParaMEDMEM::MEDCouplingUMesh *ReadUMeshFromFamilies(const std::string& fileName, const std::string& meshName, int meshDimRelToMax, const std::vector<std::string>& fams); + static ParaMEDMEM::MEDCouplingUMesh *ReadUMeshFromGroups(const std::string& fileName, const std::string& meshName, int meshDimRelToMax, const std::vector<std::string>& grps); + static ParaMEDMEM::MEDCouplingMesh *ReadMeshFromFile(const std::string& fileName, const std::string& meshName, int meshDimRelToMax=0); + static ParaMEDMEM::MEDCouplingMesh *ReadMeshFromFile(const std::string& fileName, int meshDimRelToMax=0); + static ParaMEDMEM::MEDCouplingUMesh *ReadUMeshFromFile(const std::string& fileName, const std::string& meshName, int meshDimRelToMax=0); + static ParaMEDMEM::MEDCouplingUMesh *ReadUMeshFromFile(const std::string& fileName, int meshDimRelToMax=0); + static int ReadUMeshDimFromFile(const std::string& fileName, const std::string& meshName); + static ParaMEDMEM::MEDCouplingFieldDouble *ReadField(ParaMEDMEM::TypeOfField type, const std::string& fileName, const std::string& meshName, int meshDimRelToMax, const std::string& fieldName, int iteration, int order); + static std::vector<ParaMEDMEM::MEDCouplingFieldDouble *> ReadFieldsOnSameMesh(ParaMEDMEM::TypeOfField type, const std::string& fileName, const std::string& meshName, int meshDimRelToMax, const std::string& fieldName, + const std::vector<std::pair<int,int> >& its); + static std::vector<ParaMEDMEM::MEDCouplingFieldDouble *> ReadFieldsCellOnSameMesh(const std::string& fileName, const std::string& meshName, int meshDimRelToMax, const std::string& fieldName, + const std::vector<std::pair<int,int> >& its); + static std::vector<ParaMEDMEM::MEDCouplingFieldDouble *> ReadFieldsNodeOnSameMesh(const std::string& fileName, const std::string& meshName, int meshDimRelToMax, const std::string& fieldName, + const std::vector<std::pair<int,int> >& its); + static std::vector<ParaMEDMEM::MEDCouplingFieldDouble *> ReadFieldsGaussOnSameMesh(const std::string& fileName, const std::string& meshName, int meshDimRelToMax, const std::string& fieldName, + const std::vector<std::pair<int,int> >& its); + static std::vector<ParaMEDMEM::MEDCouplingFieldDouble *> ReadFieldsGaussNEOnSameMesh(const std::string& fileName, const std::string& meshName, int meshDimRelToMax, const std::string& fieldName, + const std::vector<std::pair<int,int> >& its); + static ParaMEDMEM::MEDCouplingFieldDouble *ReadFieldCell(const std::string& fileName, const std::string& meshName, int meshDimRelToMax, const std::string& fieldName, int iteration, int order); + static ParaMEDMEM::MEDCouplingFieldDouble *ReadFieldNode(const std::string& fileName, const std::string& meshName, int meshDimRelToMax, const std::string& fieldName, int iteration, int order); + static ParaMEDMEM::MEDCouplingFieldDouble *ReadFieldGauss(const std::string& fileName, const std::string& meshName, int meshDimRelToMax, const std::string& fieldName, int iteration, int order); + static ParaMEDMEM::MEDCouplingFieldDouble *ReadFieldGaussNE(const std::string& fileName, const std::string& meshName, int meshDimRelToMax, const std::string& fieldName, int iteration, int order); + static void WriteMesh(const std::string& fileName, const ParaMEDMEM::MEDCouplingMesh *mesh, bool writeFromScratch); + static void WriteUMesh(const std::string& fileName, const ParaMEDMEM::MEDCouplingUMesh *mesh, bool writeFromScratch); + static void WriteUMeshDep(const std::string& fileName, const ParaMEDMEM::MEDCouplingUMesh *mesh, bool writeFromScratch); + static void WriteUMeshesPartition(const std::string& fileName, const std::string& meshName, const std::vector<const ParaMEDMEM::MEDCouplingUMesh *>& meshes, bool writeFromScratch); + static void WriteUMeshesPartitionDep(const std::string& fileName, const std::string& meshName, const std::vector<const ParaMEDMEM::MEDCouplingUMesh *>& meshes, bool writeFromScratch); + static void WriteUMeshes(const std::string& fileName, const std::vector<const ParaMEDMEM::MEDCouplingUMesh *>& meshes, bool writeFromScratch); + static void WriteField(const std::string& fileName, const ParaMEDMEM::MEDCouplingFieldDouble *f, bool writeFromScratch); + static void WriteFieldDep(const std::string& fileName, const ParaMEDMEM::MEDCouplingFieldDouble *f, bool writeFromScratch); + static void WriteFieldUsingAlreadyWrittenMesh(const std::string& fileName, const ParaMEDMEM::MEDCouplingFieldDouble *f); +public: + static void AssignStaticWritePropertiesTo(ParaMEDMEM::MEDFileWritable& obj); +private: + MEDLoader(); +public: + static double _EPS_FOR_NODE_COMP; + static int _COMP_FOR_CELL; + static int _TOO_LONG_STR; +}; + +#endif diff --git a/src/medtool/src/MEDLoader/MEDLoaderBase.cxx b/src/medtool/src/MEDLoader/MEDLoaderBase.cxx new file mode 100644 index 000000000..13db3d9d9 --- /dev/null +++ b/src/medtool/src/MEDLoader/MEDLoaderBase.cxx @@ -0,0 +1,237 @@ +// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 +// 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 "MEDLoaderBase.hxx" +#include "InterpKernelException.hxx" + +#include <sstream> +#include <fstream> +#include <cstring> +#include <iostream> + +const char MEDLoaderBase::WHITE_SPACES[]=" \n"; + +int MEDLoaderBase::getStatusOfFile(const std::string& fileName) +{ + std::ifstream ifs; + ifs.open(fileName.c_str()); + if((ifs.rdstate() & std::ifstream::failbit)!=0) + { + ifs.close(); + return NOT_EXIST; + } + std::ofstream ofs(fileName.c_str(),std::ios_base::app); + if((ofs.rdstate() & std::ofstream::failbit)!=0) + { + return EXIST_RDONLY; + } + return EXIST_RW; +} + +char *MEDLoaderBase::buildEmptyString(int lgth) +{ + char *ret=new char[lgth+1]; + std::fill(ret,ret+lgth,' '); + ret[lgth]='\0'; + return ret; +} + +void MEDLoaderBase::getDirAndBaseName(const std::string& fullName, std::string& dirName, std::string& baseName) +{ + std::size_t pos=fullName.find_last_of(getPathSep()); + if(pos!=std::string::npos) + { + dirName=fullName.substr(0,pos); + baseName=fullName.substr(pos+1); + } + else + { + dirName.clear(); + baseName=fullName; + } +} + +std::string MEDLoaderBase::joinPath(const std::string& dirName, const std::string& baseName) +{ + if(!dirName.empty()) + return dirName+getPathSep()+baseName; + else + return baseName; +} + +std::string MEDLoaderBase::getPathSep() +{ +#ifndef WIN32 + return std::string("/"); +#else + return std::string("\\"); +#endif +} + +std::string MEDLoaderBase::buildUnionUnit(const char *name, int nameLgth, const char *unit, int unitLgth) +{ + std::string ret(buildStringFromFortran(name,nameLgth)); + std::string unitCpp(buildStringFromFortran(unit,unitLgth)); + if(unitCpp.empty() || unitCpp[0]=='\0') + return ret; + ret+=" ["; + ret+=unitCpp; + ret+="]"; + return ret; +} + +void MEDLoaderBase::splitIntoNameAndUnit(const std::string& s, std::string& name, std::string& unit) +{ + std::string::size_type f1=s.find_first_of('['); + std::string::size_type f2=s.find_last_of(']'); + if(f1!=std::string::npos && f2!=std::string::npos) + { + if(f1<f2) + { + name=s.substr(0,f1); + unit=s.substr(f1+1,f2-f1-1); + strip(name); + strip(unit); + return; + } + } + name=s; + unit=""; +} + +void MEDLoaderBase::strip(std::string& s) +{ + std::string::size_type f1=s.find_first_not_of(' '); + if(f1==std::string::npos) + { + s=""; + return ; + } + std::string::size_type f2=s.find_last_not_of(' '); + s=s.substr(f1,f2-f1+1); +} + +/*! + * This method operates a safe copy from 'src' to 'dest' by checking the size of 'src' before trying to copy. + * If size of 'src' string is higher than 'maxLgth' the behaviour is dependant from 'behaviour' parameter. + * If 'behaviour' equals 0 an exception is thrown. If 'behaviour' equals 1 an attempt of zipping of string will be done + * ( see zipString to have more details). + */ +void MEDLoaderBase::safeStrCpy(const char *src, int maxLgth, char *dest, int behaviour) +{ + if((int)strlen(src)>maxLgth) + { + if(behaviour==0 || behaviour>1) + { + std::ostringstream oss; oss << "A string : \"" << src << "\" has been detected to be too long for MED File ( > " << maxLgth << ") !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + else if(behaviour==1) + { + std::string s=zipString(src,maxLgth); + std::cerr << "A string : \"" << src << "\" has been detected to be too long for MED File ( > " << maxLgth << ") : "; + std::cerr << "zipping to : " << s << "\n"; + strcpy(dest,s.c_str()); + return ; + } + } + strcpy(dest,src); +} + +/*! + * This method is equivalent to MEDLoaderBase::safeStrCpy except that here no '\0' car is put. + * This method should be used for multi string in one string. + */ +void MEDLoaderBase::safeStrCpy2(const char *src, int maxLgth, char *dest, int behaviour) +{ + if((int)strlen(src)>maxLgth) + { + if(behaviour==0 || behaviour>1) + { + std::ostringstream oss; oss << "A string : \"" << src << "\" has been detected to be too long for MED File ( > " << maxLgth << ") !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + else if(behaviour==1) + { + std::string s=zipString(src,maxLgth); + std::cerr << "A string : \"" << src << "\" has been detected to be too long for MED File ( > " << maxLgth << ") : "; + std::cerr << "zipping to : " << s << "\n"; + strcpy(dest,s.c_str()); + return ; + } + } + int n=strlen(src); + strncpy(dest,src,n); +} + +std::string MEDLoaderBase::buildStringFromFortran(const char *expr, int lgth) +{ + std::string ret(expr,lgth); + std::string whiteSpaces(WHITE_SPACES); + std::size_t lgthReal=strlen(ret.c_str()); + std::string ret2=ret.substr(0,lgthReal); + std::size_t found=ret2.find_last_not_of(whiteSpaces); + if (found!=std::string::npos) + ret2.erase(found+1); + else + ret2.clear();//ret is all whitespace + return ret2; +} + +/*! + * This method given the target size to respect 'sizeToRespect' tries to reduce size of 'src' string. + * This method uses several soft methods to do its job. But if it fails a simple cut of string will be performed. + */ +std::string MEDLoaderBase::zipString(const std::string& src, int sizeToRespect) +{ + std::string s(src); + strip(s); + if((int)s.length()<=sizeToRespect) + return s; + s=src; + zipEqualConsChar(s,3); + if((int)s.length()<=sizeToRespect) + return s; + s=src; + zipEqualConsChar(s,2); + if((int)s.length()<=sizeToRespect) + return s; + s=src; + return s.substr(0,sizeToRespect); +} + +/*! + * This method see if there is in 's' more than 'minConsSmChar' consecutive same character. + * If yes, the group will be zipped using only one character for this group. + * If no such group is found, s remains unchanged. + */ +void MEDLoaderBase::zipEqualConsChar(std::string& s, int minConsSmChar) +{ + for(std::string::iterator it=s.begin();it!=s.end();it++) + { + char tmp=*it; + int sz=1; + for(std::string::iterator it2=it+1;it2!=s.end() && *it2==tmp;it2++) + sz++; + if(sz>=minConsSmChar) + s.erase(it+1,it+sz); + } +} + diff --git a/src/medtool/src/MEDLoader/MEDLoaderBase.hxx b/src/medtool/src/MEDLoader/MEDLoaderBase.hxx new file mode 100644 index 000000000..5ff6cf6e8 --- /dev/null +++ b/src/medtool/src/MEDLoader/MEDLoaderBase.hxx @@ -0,0 +1,54 @@ +// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 +// 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 __MEDLOADERBASE_HXX__ +#define __MEDLOADERBASE_HXX__ + +#include "MEDLoaderDefines.hxx" +#include "InterpKernelException.hxx" + +#include <string> + +class MEDLOADER_EXPORT MEDLoaderBase +{ +public: + static int getStatusOfFile(const std::string& fileName); + static char *buildEmptyString(int lgth); + static void getDirAndBaseName(const std::string& fullName, std::string& dirName, std::string& baseName); + static std::string getPathSep(); + static std::string joinPath(const std::string& dirName, const std::string& baseName); + static std::string buildUnionUnit(const char *name, int nameLgth, const char *unit, int unitLgth); + static void splitIntoNameAndUnit(const std::string& s, std::string& name, std::string& unit); + static void strip(std::string& s); + static void safeStrCpy(const char *src, int maxLgth, char *dest, int behaviour); + static void safeStrCpy2(const char *src, int maxLgth, char *dest, int behaviour); + static std::string buildStringFromFortran(const char *expr, int lgth); + static void zipEqualConsChar(std::string& s, int minConsSmChar); + static std::string zipString(const std::string& src, int sizeToRespect); +public: + static const int EXIST_RW=0; + static const int NOT_EXIST=1; + static const int EXIST_RDONLY=2; + static const int EXIST_WRONLY=3; + static const int DIR_LOCKED=4; + static const char WHITE_SPACES[]; +}; + +#endif diff --git a/src/medtool/src/MEDLoader/MEDLoaderDefines.hxx b/src/medtool/src/MEDLoader/MEDLoaderDefines.hxx new file mode 100644 index 000000000..fd92fc66b --- /dev/null +++ b/src/medtool/src/MEDLoader/MEDLoaderDefines.hxx @@ -0,0 +1,34 @@ +// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 +// 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 __MEDLOADERDEFINES_HXX__ +#define __MEDLOADERDEFINES_HXX__ + +#ifdef WIN32 +# if defined medloader_EXPORTS +# define MEDLOADER_EXPORT __declspec(dllexport) +# else +# define MEDLOADER_EXPORT __declspec(dllimport) +# endif +#else +# define MEDLOADER_EXPORT +#endif + +#endif diff --git a/src/medtool/src/MEDLoader/SauvMedConvertor.cxx b/src/medtool/src/MEDLoader/SauvMedConvertor.cxx new file mode 100644 index 000000000..dd2ba8961 --- /dev/null +++ b/src/medtool/src/MEDLoader/SauvMedConvertor.cxx @@ -0,0 +1,3830 @@ +// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 +// 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 +// +// File : SauvMedConvertor.cxx +// Created : Tue Aug 16 14:43:20 2011 +// Author : Edward AGAPOV (eap) +// + +#include "SauvMedConvertor.hxx" + +#include "CellModel.hxx" +#include "MEDFileMesh.hxx" +#include "MEDFileField.hxx" +#include "MEDFileData.hxx" +#include "MEDCouplingFieldDouble.hxx" + +#include <iostream> +#include <cassert> +#include <cmath> +#include <queue> +#include <limits> + +#include <cstdlib> +#include <cstring> +#include <fcntl.h> + +#ifdef WIN32 +#include <io.h> +#else +#include <unistd.h> +#endif + +#ifdef HAS_XDR +#include <rpc/xdr.h> +#endif + +using namespace SauvUtilities; +using namespace ParaMEDMEM; + +namespace +{ + // for ASCII file reader + const int GIBI_MaxOutputLen = 150; // max length of a line in the sauve file + const int GIBI_BufferSize = 16184; // for buffered reading + + using namespace INTERP_KERNEL; + + const size_t MaxMedCellType = NORM_ERROR; + const size_t NbGibiCellTypes = 47; + const TCellType GibiTypeToMed[NbGibiCellTypes] = + { + /*1 */ NORM_POINT1 ,/*2 */ NORM_SEG2 ,/*3 */ NORM_SEG3 ,/*4 */ NORM_TRI3 ,/*5 */ NORM_ERROR , + /*6 */ NORM_TRI6 ,/*7 */ NORM_ERROR ,/*8 */ NORM_QUAD4 ,/*9 */ NORM_ERROR ,/*10*/ NORM_QUAD8 , + /*11*/ NORM_ERROR ,/*12*/ NORM_ERROR ,/*13*/ NORM_ERROR ,/*14*/ NORM_HEXA8 ,/*15*/ NORM_HEXA20 , + /*16*/ NORM_PENTA6 ,/*17*/ NORM_PENTA15,/*18*/ NORM_ERROR ,/*19*/ NORM_ERROR ,/*20*/ NORM_ERROR , + /*21*/ NORM_ERROR ,/*22*/ NORM_ERROR ,/*23*/ NORM_TETRA4 ,/*24*/ NORM_TETRA10,/*25*/ NORM_PYRA5 , + /*26*/ NORM_PYRA13 ,/*27*/ NORM_ERROR ,/*28*/ NORM_ERROR ,/*29*/ NORM_ERROR ,/*30*/ NORM_ERROR , + /*31*/ NORM_ERROR ,/*32*/ NORM_ERROR ,/*33*/ NORM_ERROR ,/*34*/ NORM_ERROR ,/*35*/ NORM_ERROR , + /*36*/ NORM_ERROR ,/*37*/ NORM_ERROR ,/*38*/ NORM_ERROR ,/*39*/ NORM_ERROR ,/*40*/ NORM_ERROR , + /*41*/ NORM_ERROR ,/*42*/ NORM_ERROR ,/*43*/ NORM_ERROR ,/*44*/ NORM_ERROR ,/*45*/ NORM_ERROR , + /*46*/ NORM_ERROR ,/*47*/ NORM_ERROR + }; + + //================================================================================ + /*! + * \brief Return dimension of a group + */ + //================================================================================ + + unsigned getDim( const Group* grp ) + { + return SauvUtilities::getDimension( grp->_groups.empty() ? grp->_cellType : grp->_groups[0]->_cellType ); + } + + //================================================================================ + /*! + * \brief Converts connectivity of quadratic elements + */ + //================================================================================ + + inline void ConvertQuadratic( const INTERP_KERNEL::NormalizedCellType type, + const Cell & aCell ) + { + if ( const int * conn = getGibi2MedQuadraticInterlace( type )) + { + Cell* ma = const_cast<Cell*>(&aCell); + std::vector< Node* > new_nodes( ma->_nodes.size() ); + for (std:: size_t i = 0; i < new_nodes.size(); ++i ) + new_nodes[ i ] = ma->_nodes[ conn[ i ]]; + ma->_nodes.swap( new_nodes ); + } + } + + //================================================================================ + /*! + * \brief Returns a vector of pairs of node indices to inverse a med volume element + */ + //================================================================================ + + void getReverseVector (const INTERP_KERNEL::NormalizedCellType type, + std::vector<std::pair<int,int> > & swapVec ) + { + swapVec.clear(); + + switch ( type ) + { + case NORM_TETRA4: + swapVec.resize(1); + swapVec[0] = std::make_pair( 1, 2 ); + break; + case NORM_PYRA5: + swapVec.resize(1); + swapVec[0] = std::make_pair( 1, 3 ); + break; + case NORM_PENTA6: + swapVec.resize(2); + swapVec[0] = std::make_pair( 1, 2 ); + swapVec[1] = std::make_pair( 4, 5 ); + break; + case NORM_HEXA8: + swapVec.resize(2); + swapVec[0] = std::make_pair( 1, 3 ); + swapVec[1] = std::make_pair( 5, 7 ); + break; + case NORM_TETRA10: + swapVec.resize(3); + swapVec[0] = std::make_pair( 1, 2 ); + swapVec[1] = std::make_pair( 4, 6 ); + swapVec[2] = std::make_pair( 8, 9 ); + break; + case NORM_PYRA13: + swapVec.resize(4); + swapVec[0] = std::make_pair( 1, 3 ); + swapVec[1] = std::make_pair( 5, 8 ); + swapVec[2] = std::make_pair( 6, 7 ); + swapVec[3] = std::make_pair( 10, 12 ); + break; + case NORM_PENTA15: + swapVec.resize(4); + swapVec[0] = std::make_pair( 1, 2 ); + swapVec[1] = std::make_pair( 4, 5 ); + swapVec[2] = std::make_pair( 6, 8 ); + swapVec[3] = std::make_pair( 9, 11 ); + break; + case NORM_HEXA20: + swapVec.resize(7); + swapVec[0] = std::make_pair( 1, 3 ); + swapVec[1] = std::make_pair( 5, 7 ); + swapVec[2] = std::make_pair( 8, 11 ); + swapVec[3] = std::make_pair( 9, 10 ); + swapVec[4] = std::make_pair( 12, 15 ); + swapVec[5] = std::make_pair( 13, 14 ); + swapVec[6] = std::make_pair( 17, 19 ); + break; + // case NORM_SEG3: no need to reverse edges + // swapVec.resize(1); + // swapVec[0] = std::make_pair( 1, 2 ); + // break; + case NORM_TRI6: + swapVec.resize(2); + swapVec[0] = std::make_pair( 1, 2 ); + swapVec[1] = std::make_pair( 3, 5 ); + break; + case NORM_QUAD8: + swapVec.resize(3); + swapVec[0] = std::make_pair( 1, 3 ); + swapVec[1] = std::make_pair( 4, 7 ); + swapVec[2] = std::make_pair( 5, 6 ); + break; + default:; + } + } + + //================================================================================ + /*! + * \brief Inverses element orientation using vector of indices to swap + */ + //================================================================================ + + inline void reverse(const Cell & aCell, const std::vector<std::pair<int,int> > & swapVec ) + { + Cell* ma = const_cast<Cell*>(&aCell); + for ( unsigned i = 0; i < swapVec.size(); ++i ) + std::swap( ma->_nodes[ swapVec[i].first ], + ma->_nodes[ swapVec[i].second ]); + if ( swapVec.empty() ) + ma->_reverse = true; + else + ma->_reverse = false; + } + //================================================================================ + /*! + * \brief Comparator of cells by number used for ordering cells within a med group + */ + struct TCellByIDCompare + { + bool operator () (const Cell* i1, const Cell* i2) + { + return i1->_number < i2->_number; + } + }; + typedef std::map< const Cell*, unsigned, TCellByIDCompare > TCellToOrderMap; + + //================================================================================ + /*! + * \brief Fill Group::_relocTable if necessary + */ + //================================================================================ + + void setRelocationTable( Group* grp, TCellToOrderMap& cell2order ) + { + if ( !grp->_isProfile ) return; + + // check if relocation table is necessary + bool isRelocated = false; + unsigned newOrder = 0; + TCellToOrderMap::iterator c2oIt = cell2order.begin(), c2oEnd = cell2order.end(); + for ( ; !isRelocated && c2oIt != c2oEnd; ++c2oIt, ++newOrder ) + isRelocated = ( c2oIt->second != newOrder ); + + if ( isRelocated ) + { + grp->_relocTable.resize( cell2order.size() ); + for ( newOrder = 0, c2oIt = cell2order.begin(); c2oIt != c2oEnd; ++c2oIt, ++newOrder ) + grp->_relocTable[ c2oIt->second ] = newOrder; + } + } +} + +namespace // define default GAUSS points +{ + typedef std::vector<double> TDoubleVector; + typedef double* TCoordSlice; + typedef int TInt; + //--------------------------------------------------------------- + //! Shape function definitions + //--------------------------------------------------------------- + struct TShapeFun + { + TInt myDim; + TInt myNbRef; + TDoubleVector myRefCoord; + + TShapeFun(TInt theDim = 0, TInt theNbRef = 0) + :myDim(theDim),myNbRef(theNbRef),myRefCoord(theNbRef*theDim) {} + + TInt GetNbRef() const { return myNbRef; } + + TCoordSlice GetCoord(TInt theRefId) { return &myRefCoord[0] + theRefId * myDim; } + }; + //--------------------------------------------------------------- + /*! + * \brief Description of family of integration points + */ + //--------------------------------------------------------------- + struct TGaussDef + { + int myType; //!< element geometry (EGeometrieElement or med_geometrie_element) + TDoubleVector myRefCoords; //!< description of reference points + TDoubleVector myCoords; //!< coordinates of Gauss points + TDoubleVector myWeights; //!< weights, len(weights)==<nb of gauss points> + + /*! + * \brief Creates definition of gauss points family + * \param geomType - element geometry (EGeometrieElement or med_geometrie_element) + * \param nbPoints - nb gauss point + * \param variant - [1-3] to choose the variant of definition + * + * Throws in case of invalid parameters + * variant == 1 refers to "Fonctions de forme et points d'integration + * des elements finis" v7.4 by J. PELLET, X. DESROCHES, 15/09/05 + * variant == 2 refers to the same doc v6.4 by J.P. LEFEBVRE, X. DESROCHES, 03/07/03 + * variant == 3 refers to the same doc v6.4, second variant for 2D elements + */ + TGaussDef(const int geomType, const int nbPoints, const int variant=1); + + int dim() const { return SauvUtilities::getDimension( NormalizedCellType( myType )); } + int nbPoints() const { return myWeights.capacity(); } + + private: + void add(const double x, const double weight); + void add(const double x, const double y, const double weight); + void add(const double x, const double y, const double z, const double weight); + void setRefCoords(const TShapeFun& aShapeFun) { myRefCoords = aShapeFun.myRefCoord; } + }; + struct TSeg2a: TShapeFun { + TSeg2a(); + }; + struct TSeg3a: TShapeFun { + TSeg3a(); + }; + struct TTria3a: TShapeFun { + TTria3a(); + }; + struct TTria6a: TShapeFun { + TTria6a(); + }; + struct TTria3b: TShapeFun { + TTria3b(); + }; + struct TTria6b: TShapeFun { + TTria6b(); + }; + struct TQuad4a: TShapeFun { + TQuad4a(); + }; + struct TQuad8a: TShapeFun { + TQuad8a(); + }; + struct TQuad4b: TShapeFun { + TQuad4b(); + }; + struct TQuad8b: TShapeFun { + TQuad8b(); + }; + struct TTetra4a: TShapeFun { + TTetra4a(); + }; + struct TTetra10a: TShapeFun { + TTetra10a(); + }; + struct TTetra4b: TShapeFun { + TTetra4b(); + }; + struct TTetra10b: TShapeFun { + TTetra10b(); + }; + struct THexa8a: TShapeFun { + THexa8a(); + }; + struct THexa20a: TShapeFun { + THexa20a(TInt theDim = 3, TInt theNbRef = 20); + }; + struct THexa27a: THexa20a { + THexa27a(); + }; + struct THexa8b: TShapeFun { + THexa8b(); + }; + struct THexa20b: TShapeFun { + THexa20b(TInt theDim = 3, TInt theNbRef = 20); + }; + struct TPenta6a: TShapeFun { + TPenta6a(); + }; + struct TPenta6b: TShapeFun { + TPenta6b(); + }; + struct TPenta15a: TShapeFun { + TPenta15a(); + }; + struct TPenta15b: TShapeFun { + TPenta15b(); + }; + struct TPyra5a: TShapeFun { + TPyra5a(); + }; + struct TPyra5b: TShapeFun { + TPyra5b(); + }; + struct TPyra13a: TShapeFun { + TPyra13a(); + }; + struct TPyra13b: TShapeFun { + TPyra13b(); + }; + + void TGaussDef::add(const double x, const double weight) + { + if ( dim() != 1 ) + THROW_IK_EXCEPTION("TGaussDef: dim() != 1"); + if ( myWeights.capacity() == myWeights.size() ) + THROW_IK_EXCEPTION("TGaussDef: Extra gauss point"); + myCoords.push_back( x ); + myWeights.push_back( weight ); + } + void TGaussDef::add(const double x, const double y, const double weight) + { + if ( dim() != 2 ) + THROW_IK_EXCEPTION("TGaussDef: dim() != 2"); + if ( myWeights.capacity() == myWeights.size() ) + THROW_IK_EXCEPTION("TGaussDef: Extra gauss point"); + myCoords.push_back( x ); + myCoords.push_back( y ); + myWeights.push_back( weight ); + } + void TGaussDef::add(const double x, const double y, const double z, const double weight) + { + if ( dim() != 3 ) + THROW_IK_EXCEPTION("TGaussDef: dim() != 3"); + if ( myWeights.capacity() == myWeights.size() ) + THROW_IK_EXCEPTION("TGaussDef: Extra gauss point"); + myCoords.push_back( x ); + myCoords.push_back( y ); + myCoords.push_back( z ); + myWeights.push_back( weight ); + } + + //--------------------------------------------------------------- + TSeg2a::TSeg2a():TShapeFun(1,2) + { + TInt aNbRef = GetNbRef(); + for(TInt aRefId = 0; aRefId < aNbRef; aRefId++){ + TCoordSlice aCoord = GetCoord(aRefId); + switch(aRefId){ + case 0: aCoord[0] = -1.0; break; + case 1: aCoord[0] = 1.0; break; + } + } + } + //--------------------------------------------------------------- + TSeg3a::TSeg3a():TShapeFun(1,3) + { + TInt aNbRef = GetNbRef(); + for(TInt aRefId = 0; aRefId < aNbRef; aRefId++){ + TCoordSlice aCoord = GetCoord(aRefId); + switch(aRefId){ + case 0: aCoord[0] = -1.0; break; + case 1: aCoord[0] = 1.0; break; + case 2: aCoord[0] = 0.0; break; + } + } + } + //--------------------------------------------------------------- + TTria3a::TTria3a(): + TShapeFun(2,3) + { + TInt aNbRef = GetNbRef(); + for(TInt aRefId = 0; aRefId < aNbRef; aRefId++){ + TCoordSlice aCoord = GetCoord(aRefId); + switch(aRefId){ + case 0: aCoord[0] = -1.0; aCoord[1] = 1.0; break; + case 1: aCoord[0] = -1.0; aCoord[1] = -1.0; break; + case 2: aCoord[0] = 1.0; aCoord[1] = -1.0; break; + } + } + } + //--------------------------------------------------------------- + TTria6a::TTria6a():TShapeFun(2,6) + { + TInt aNbRef = GetNbRef(); + for(TInt aRefId = 0; aRefId < aNbRef; aRefId++){ + TCoordSlice aCoord = GetCoord(aRefId); + switch(aRefId){ + case 0: aCoord[0] = -1.0; aCoord[1] = 1.0; break; + case 1: aCoord[0] = -1.0; aCoord[1] = -1.0; break; + case 2: aCoord[0] = 1.0; aCoord[1] = -1.0; break; + + case 3: aCoord[0] = -1.0; aCoord[1] = 1.0; break; + case 4: aCoord[0] = 0.0; aCoord[1] = -1.0; break; + case 5: aCoord[0] = 0.0; aCoord[1] = 0.0; break; + } + } + } + //--------------------------------------------------------------- + TTria3b::TTria3b(): + TShapeFun(2,3) + { + TInt aNbRef = GetNbRef(); + for(TInt aRefId = 0; aRefId < aNbRef; aRefId++){ + TCoordSlice aCoord = GetCoord(aRefId); + switch(aRefId){ + case 0: aCoord[0] = 0.0; aCoord[1] = 0.0; break; + case 1: aCoord[0] = 1.0; aCoord[1] = 0.0; break; + case 2: aCoord[0] = 0.0; aCoord[1] = 1.0; break; + } + } + } + //--------------------------------------------------------------- + TTria6b::TTria6b(): + TShapeFun(2,6) + { + TInt aNbRef = GetNbRef(); + for(TInt aRefId = 0; aRefId < aNbRef; aRefId++){ + TCoordSlice aCoord = GetCoord(aRefId); + switch(aRefId){ + case 0: aCoord[0] = 0.0; aCoord[1] = 0.0; break; + case 1: aCoord[0] = 1.0; aCoord[1] = 0.0; break; + case 2: aCoord[0] = 0.0; aCoord[1] = 1.0; break; + + case 3: aCoord[0] = 0.5; aCoord[1] = 0.0; break; + case 4: aCoord[0] = 0.5; aCoord[1] = 0.5; break; + case 5: aCoord[0] = 0.0; aCoord[1] = 0.5; break; + } + } + } + //--------------------------------------------------------------- + TQuad4a::TQuad4a(): + TShapeFun(2,4) + { + TInt aNbRef = GetNbRef(); + for(TInt aRefId = 0; aRefId < aNbRef; aRefId++){ + TCoordSlice aCoord = GetCoord(aRefId); + switch(aRefId){ + case 0: aCoord[0] = -1.0; aCoord[1] = 1.0; break; + case 1: aCoord[0] = -1.0; aCoord[1] = -1.0; break; + case 2: aCoord[0] = 1.0; aCoord[1] = -1.0; break; + case 3: aCoord[0] = 1.0; aCoord[1] = 1.0; break; + } + } + } + //--------------------------------------------------------------- + TQuad8a::TQuad8a(): + TShapeFun(2,8) + { + TInt aNbRef = GetNbRef(); + for(TInt aRefId = 0; aRefId < aNbRef; aRefId++){ + TCoordSlice aCoord = GetCoord(aRefId); + switch(aRefId){ + case 0: aCoord[0] = -1.0; aCoord[1] = 1.0; break; + case 1: aCoord[0] = -1.0; aCoord[1] = -1.0; break; + case 2: aCoord[0] = 1.0; aCoord[1] = -1.0; break; + case 3: aCoord[0] = 1.0; aCoord[1] = 1.0; break; + + case 4: aCoord[0] = -1.0; aCoord[1] = 0.0; break; + case 5: aCoord[0] = 0.0; aCoord[1] = -1.0; break; + case 6: aCoord[0] = 1.0; aCoord[1] = 0.0; break; + case 7: aCoord[0] = 0.0; aCoord[1] = 1.0; break; + } + } + } + //--------------------------------------------------------------- + TQuad4b::TQuad4b(): + TShapeFun(2,4) + { + TInt aNbRef = GetNbRef(); + for(TInt aRefId = 0; aRefId < aNbRef; aRefId++){ + TCoordSlice aCoord = GetCoord(aRefId); + switch(aRefId){ + case 0: aCoord[0] = -1.0; aCoord[1] = -1.0; break; + case 1: aCoord[0] = 1.0; aCoord[1] = -1.0; break; + case 2: aCoord[0] = 1.0; aCoord[1] = 1.0; break; + case 3: aCoord[0] = -1.0; aCoord[1] = 1.0; break; + } + } + } + //--------------------------------------------------------------- + TQuad8b::TQuad8b(): + TShapeFun(2,8) + { + TInt aNbRef = GetNbRef(); + for(TInt aRefId = 0; aRefId < aNbRef; aRefId++){ + TCoordSlice aCoord = GetCoord(aRefId); + switch(aRefId){ + case 0: aCoord[0] = -1.0; aCoord[1] = -1.0; break; + case 1: aCoord[0] = 1.0; aCoord[1] = -1.0; break; + case 2: aCoord[0] = 1.0; aCoord[1] = 1.0; break; + case 3: aCoord[0] = -1.0; aCoord[1] = 1.0; break; + + case 4: aCoord[0] = 0.0; aCoord[1] = -1.0; break; + case 5: aCoord[0] = 1.0; aCoord[1] = 0.0; break; + case 6: aCoord[0] = 0.0; aCoord[1] = 1.0; break; + case 7: aCoord[0] = -1.0; aCoord[1] = 0.0; break; + } + } + } + //--------------------------------------------------------------- + TTetra4a::TTetra4a(): + TShapeFun(3,4) + { + TInt aNbRef = GetNbRef(); + for(TInt aRefId = 0; aRefId < aNbRef; aRefId++){ + TCoordSlice aCoord = GetCoord(aRefId); + switch(aRefId){ + case 0: aCoord[0] = 0.0; aCoord[1] = 1.0; aCoord[2] = 0.0; break; + case 1: aCoord[0] = 0.0; aCoord[1] = 0.0; aCoord[2] = 1.0; break; + case 2: aCoord[0] = 0.0; aCoord[1] = 0.0; aCoord[2] = 0.0; break; + case 3: aCoord[0] = 1.0; aCoord[1] = 0.0; aCoord[2] = 0.0; break; + } + } + } + //--------------------------------------------------------------- + TTetra10a::TTetra10a(): + TShapeFun(3,10) + { + TInt aNbRef = GetNbRef(); + for(TInt aRefId = 0; aRefId < aNbRef; aRefId++){ + TCoordSlice aCoord = GetCoord(aRefId); + switch(aRefId){ + case 0: aCoord[0] = 0.0; aCoord[1] = 1.0; aCoord[2] = 0.0; break; + case 1: aCoord[0] = 0.0; aCoord[1] = 0.0; aCoord[2] = 1.0; break; + case 2: aCoord[0] = 0.0; aCoord[1] = 0.0; aCoord[2] = 0.0; break; + case 3: aCoord[0] = 1.0; aCoord[1] = 0.0; aCoord[2] = 0.0; break; + + case 4: aCoord[0] = 0.0; aCoord[1] = 0.5; aCoord[2] = 0.5; break; + case 5: aCoord[0] = 0.0; aCoord[1] = 0.0; aCoord[2] = 0.5; break; + case 6: aCoord[0] = 0.0; aCoord[1] = 0.5; aCoord[2] = 0.0; break; + + case 7: aCoord[0] = 0.5; aCoord[1] = 0.5; aCoord[2] = 0.0; break; + case 8: aCoord[0] = 0.5; aCoord[1] = 0.0; aCoord[2] = 0.5; break; + case 9: aCoord[0] = 0.5; aCoord[1] = 0.0; aCoord[2] = 0.0; break; + } + } + } + //--------------------------------------------------------------- + TTetra4b::TTetra4b(): + TShapeFun(3,4) + { + TInt aNbRef = GetNbRef(); + for(TInt aRefId = 0; aRefId < aNbRef; aRefId++){ + TCoordSlice aCoord = GetCoord(aRefId); + switch(aRefId){ + case 0: aCoord[0] = 0.0; aCoord[1] = 1.0; aCoord[2] = 0.0; break; + case 2: aCoord[0] = 0.0; aCoord[1] = 0.0; aCoord[2] = 1.0; break; + case 1: aCoord[0] = 0.0; aCoord[1] = 0.0; aCoord[2] = 0.0; break; + case 3: aCoord[0] = 1.0; aCoord[1] = 0.0; aCoord[2] = 0.0; break; + } + } + } + //--------------------------------------------------------------- + TTetra10b::TTetra10b(): + TShapeFun(3,10) + { + TInt aNbRef = GetNbRef(); + for(TInt aRefId = 0; aRefId < aNbRef; aRefId++){ + TCoordSlice aCoord = GetCoord(aRefId); + switch(aRefId){ + case 0: aCoord[0] = 0.0; aCoord[1] = 1.0; aCoord[2] = 0.0; break; + case 2: aCoord[0] = 0.0; aCoord[1] = 0.0; aCoord[2] = 1.0; break; + case 1: aCoord[0] = 0.0; aCoord[1] = 0.0; aCoord[2] = 0.0; break; + case 3: aCoord[0] = 1.0; aCoord[1] = 0.0; aCoord[2] = 0.0; break; + + case 6: aCoord[0] = 0.0; aCoord[1] = 0.5; aCoord[2] = 0.5; break; + case 5: aCoord[0] = 0.0; aCoord[1] = 0.0; aCoord[2] = 0.5; break; + case 4: aCoord[0] = 0.0; aCoord[1] = 0.5; aCoord[2] = 0.0; break; + + case 7: aCoord[0] = 0.5; aCoord[1] = 0.5; aCoord[2] = 0.0; break; + case 9: aCoord[0] = 0.5; aCoord[1] = 0.0; aCoord[2] = 0.5; break; + case 8: aCoord[0] = 0.5; aCoord[1] = 0.0; aCoord[2] = 0.0; break; + } + } + } + //--------------------------------------------------------------- + THexa8a::THexa8a(): + TShapeFun(3,8) + { + TInt aNbRef = GetNbRef(); + for(TInt aRefId = 0; aRefId < aNbRef; aRefId++){ + TCoordSlice aCoord = GetCoord(aRefId); + switch(aRefId){ + case 0: aCoord[0] = -1.0; aCoord[1] = -1.0; aCoord[2] = -1.0; break; + case 1: aCoord[0] = 1.0; aCoord[1] = -1.0; aCoord[2] = -1.0; break; + case 2: aCoord[0] = 1.0; aCoord[1] = 1.0; aCoord[2] = -1.0; break; + case 3: aCoord[0] = -1.0; aCoord[1] = 1.0; aCoord[2] = -1.0; break; + case 4: aCoord[0] = -1.0; aCoord[1] = -1.0; aCoord[2] = 1.0; break; + case 5: aCoord[0] = 1.0; aCoord[1] = -1.0; aCoord[2] = 1.0; break; + case 6: aCoord[0] = 1.0; aCoord[1] = 1.0; aCoord[2] = 1.0; break; + case 7: aCoord[0] = -1.0; aCoord[1] = 1.0; aCoord[2] = 1.0; break; + } + } + } + //--------------------------------------------------------------- + THexa20a::THexa20a(TInt theDim, TInt theNbRef): + TShapeFun(theDim,theNbRef) + { + TInt aNbRef = myRefCoord.size(); + for(TInt aRefId = 0; aRefId < aNbRef; aRefId++){ + TCoordSlice aCoord = GetCoord(aRefId); + switch(aRefId){ + case 0: aCoord[0] = -1.0; aCoord[1] = -1.0; aCoord[2] = -1.0; break; + case 1: aCoord[0] = 1.0; aCoord[1] = -1.0; aCoord[2] = -1.0; break; + case 2: aCoord[0] = 1.0; aCoord[1] = 1.0; aCoord[2] = -1.0; break; + case 3: aCoord[0] = -1.0; aCoord[1] = 1.0; aCoord[2] = -1.0; break; + case 4: aCoord[0] = -1.0; aCoord[1] = -1.0; aCoord[2] = 1.0; break; + case 5: aCoord[0] = 1.0; aCoord[1] = -1.0; aCoord[2] = 1.0; break; + case 6: aCoord[0] = 1.0; aCoord[1] = 1.0; aCoord[2] = 1.0; break; + case 7: aCoord[0] = -1.0; aCoord[1] = 1.0; aCoord[2] = 1.0; break; + + case 8: aCoord[0] = 0.0; aCoord[1] = -1.0; aCoord[2] = -1.0; break; + case 9: aCoord[0] = 1.0; aCoord[1] = 0.0; aCoord[2] = -1.0; break; + case 10: aCoord[0] = 0.0; aCoord[1] = 1.0; aCoord[2] = -1.0; break; + case 11: aCoord[0] = -1.0; aCoord[1] = 0.0; aCoord[2] = -1.0; break; + case 12: aCoord[0] = -1.0; aCoord[1] = -1.0; aCoord[2] = 0.0; break; + case 13: aCoord[0] = 1.0; aCoord[1] = -1.0; aCoord[2] = 0.0; break; + case 14: aCoord[0] = 1.0; aCoord[1] = 1.0; aCoord[2] = 0.0; break; + case 15: aCoord[0] = -1.0; aCoord[1] = 1.0; aCoord[2] = 0.0; break; + case 16: aCoord[0] = 0.0; aCoord[1] = -1.0; aCoord[2] = 1.0; break; + case 17: aCoord[0] = 1.0; aCoord[1] = 0.0; aCoord[2] = 1.0; break; + case 18: aCoord[0] = 0.0; aCoord[1] = 1.0; aCoord[2] = 1.0; break; + case 19: aCoord[0] = -1.0; aCoord[1] = 0.0; aCoord[2] = 1.0; break; + } + } + } + //--------------------------------------------------------------- + THexa27a::THexa27a(): + THexa20a(3,27) + { + TInt aNbRef = myRefCoord.size(); + for(TInt aRefId = 0; aRefId < aNbRef; aRefId++){ + TCoordSlice aCoord = GetCoord(aRefId); + switch(aRefId){ + case 20: aCoord[0] = 0.0; aCoord[1] = 0.0; aCoord[2] = -1.0; break; + case 21: aCoord[0] = 0.0; aCoord[1] = -1.0; aCoord[2] = 0.0; break; + case 22: aCoord[0] = 1.0; aCoord[1] = 0.0; aCoord[2] = 0.0; break; + case 23: aCoord[0] = 0.0; aCoord[1] = 1.0; aCoord[2] = 0.0; break; + case 24: aCoord[0] = -1.0; aCoord[1] = 0.0; aCoord[2] = 0.0; break; + case 25: aCoord[0] = 0.0; aCoord[1] = 0.0; aCoord[2] = 1.0; break; + case 26: aCoord[0] = 0.0; aCoord[1] = 0.0; aCoord[2] = 0.0; break; + } + } + } + //--------------------------------------------------------------- + THexa8b::THexa8b(): + TShapeFun(3,8) + { + TInt aNbRef = GetNbRef(); + for(TInt aRefId = 0; aRefId < aNbRef; aRefId++){ + TCoordSlice aCoord = GetCoord(aRefId); + switch(aRefId){ + case 0: aCoord[0] = -1.0; aCoord[1] = -1.0; aCoord[2] = -1.0; break; + case 3: aCoord[0] = 1.0; aCoord[1] = -1.0; aCoord[2] = -1.0; break; + case 2: aCoord[0] = 1.0; aCoord[1] = 1.0; aCoord[2] = -1.0; break; + case 1: aCoord[0] = -1.0; aCoord[1] = 1.0; aCoord[2] = -1.0; break; + case 4: aCoord[0] = -1.0; aCoord[1] = -1.0; aCoord[2] = 1.0; break; + case 7: aCoord[0] = 1.0; aCoord[1] = -1.0; aCoord[2] = 1.0; break; + case 6: aCoord[0] = 1.0; aCoord[1] = 1.0; aCoord[2] = 1.0; break; + case 5: aCoord[0] = -1.0; aCoord[1] = 1.0; aCoord[2] = 1.0; break; + } + } + } + //--------------------------------------------------------------- + THexa20b::THexa20b(TInt theDim, TInt theNbRef): + TShapeFun(theDim,theNbRef) + { + TInt aNbRef = myRefCoord.size(); + for(TInt aRefId = 0; aRefId < aNbRef; aRefId++){ + TCoordSlice aCoord = GetCoord(aRefId); + switch(aRefId){ + case 0: aCoord[0] = -1.0; aCoord[1] = -1.0; aCoord[2] = -1.0; break; + case 3: aCoord[0] = 1.0; aCoord[1] = -1.0; aCoord[2] = -1.0; break; + case 2: aCoord[0] = 1.0; aCoord[1] = 1.0; aCoord[2] = -1.0; break; + case 1: aCoord[0] = -1.0; aCoord[1] = 1.0; aCoord[2] = -1.0; break; + case 4: aCoord[0] = -1.0; aCoord[1] = -1.0; aCoord[2] = 1.0; break; + case 7: aCoord[0] = 1.0; aCoord[1] = -1.0; aCoord[2] = 1.0; break; + case 6: aCoord[0] = 1.0; aCoord[1] = 1.0; aCoord[2] = 1.0; break; + case 5: aCoord[0] = -1.0; aCoord[1] = 1.0; aCoord[2] = 1.0; break; + + case 11: aCoord[0] = 0.0; aCoord[1] = -1.0; aCoord[2] = -1.0; break; + case 10: aCoord[0] = 1.0; aCoord[1] = 0.0; aCoord[2] = -1.0; break; + case 9: aCoord[0] = 0.0; aCoord[1] = 1.0; aCoord[2] = -1.0; break; + case 8: aCoord[0] = -1.0; aCoord[1] = 0.0; aCoord[2] = -1.0; break; + case 16: aCoord[0] = -1.0; aCoord[1] = -1.0; aCoord[2] = 0.0; break; + case 19: aCoord[0] = 1.0; aCoord[1] = -1.0; aCoord[2] = 0.0; break; + case 18: aCoord[0] = 1.0; aCoord[1] = 1.0; aCoord[2] = 0.0; break; + case 17: aCoord[0] = -1.0; aCoord[1] = 1.0; aCoord[2] = 0.0; break; + case 15: aCoord[0] = 0.0; aCoord[1] = -1.0; aCoord[2] = 1.0; break; + case 14: aCoord[0] = 1.0; aCoord[1] = 0.0; aCoord[2] = 1.0; break; + case 13: aCoord[0] = 0.0; aCoord[1] = 1.0; aCoord[2] = 1.0; break; + case 12: aCoord[0] = -1.0; aCoord[1] = 0.0; aCoord[2] = 1.0; break; + } + } + } + //--------------------------------------------------------------- + TPenta6a::TPenta6a(): + TShapeFun(3,6) + { + TInt aNbRef = myRefCoord.size(); + for(TInt aRefId = 0; aRefId < aNbRef; aRefId++){ + TCoordSlice aCoord = GetCoord(aRefId); + switch(aRefId){ + case 0: aCoord[0] = -1.0; aCoord[1] = 1.0; aCoord[2] = 0.0; break; + case 1: aCoord[0] = -1.0; aCoord[1] = -0.0; aCoord[2] = 1.0; break; + case 2: aCoord[0] = -1.0; aCoord[1] = 0.0; aCoord[2] = 0.0; break; + case 3: aCoord[0] = 1.0; aCoord[1] = 1.0; aCoord[2] = 0.0; break; + case 4: aCoord[0] = 1.0; aCoord[1] = 0.0; aCoord[2] = 1.0; break; + case 5: aCoord[0] = 1.0; aCoord[1] = 0.0; aCoord[2] = 0.0; break; + } + } + } + //--------------------------------------------------------------- + TPenta6b::TPenta6b(): + TShapeFun(3,6) + { + TInt aNbRef = myRefCoord.size(); + for(TInt aRefId = 0; aRefId < aNbRef; aRefId++){ + TCoordSlice aCoord = GetCoord(aRefId); + switch(aRefId){ + case 0: aCoord[0] = -1.0; aCoord[1] = 1.0; aCoord[2] = 0.0; break; + case 2: aCoord[0] = -1.0; aCoord[1] = -0.0; aCoord[2] = 1.0; break; + case 1: aCoord[0] = -1.0; aCoord[1] = 0.0; aCoord[2] = 0.0; break; + case 3: aCoord[0] = 1.0; aCoord[1] = 1.0; aCoord[2] = 0.0; break; + case 5: aCoord[0] = 1.0; aCoord[1] = 0.0; aCoord[2] = 1.0; break; + case 4: aCoord[0] = 1.0; aCoord[1] = 0.0; aCoord[2] = 0.0; break; + } + } + } + //--------------------------------------------------------------- + TPenta15a::TPenta15a(): + TShapeFun(3,15) + { + TInt aNbRef = myRefCoord.size(); + for(TInt aRefId = 0; aRefId < aNbRef; aRefId++){ + TCoordSlice aCoord = GetCoord(aRefId); + switch(aRefId){ + case 0: aCoord[0] = -1.0; aCoord[1] = 1.0; aCoord[2] = 0.0; break; + case 1: aCoord[0] = -1.0; aCoord[1] = -0.0; aCoord[2] = 1.0; break; + case 2: aCoord[0] = -1.0; aCoord[1] = 0.0; aCoord[2] = 0.0; break; + case 3: aCoord[0] = 1.0; aCoord[1] = 1.0; aCoord[2] = 0.0; break; + case 4: aCoord[0] = 1.0; aCoord[1] = 0.0; aCoord[2] = 1.0; break; + case 5: aCoord[0] = 1.0; aCoord[1] = 0.0; aCoord[2] = 0.0; break; + + case 6: aCoord[0] = -1.0; aCoord[1] = 0.5; aCoord[2] = 0.5; break; + case 7: aCoord[0] = -1.0; aCoord[1] = 0.0; aCoord[2] = 0.5; break; + case 8: aCoord[0] = -1.0; aCoord[1] = 0.5; aCoord[2] = 0.0; break; + case 9: aCoord[0] = 0.0; aCoord[1] = 1.0; aCoord[2] = 0.0; break; + case 10: aCoord[0] = 0.0; aCoord[1] = 0.0; aCoord[2] = 1.0; break; + case 11: aCoord[0] = 0.0; aCoord[1] = 0.0; aCoord[2] = 0.0; break; + case 12: aCoord[0] = 1.0; aCoord[1] = 0.5; aCoord[2] = 0.5; break; + case 13: aCoord[0] = 1.0; aCoord[1] = 0.0; aCoord[2] = 0.5; break; + case 14: aCoord[0] = 1.0; aCoord[1] = 0.5; aCoord[2] = 0.0; break; + } + } + } + //--------------------------------------------------------------- + TPenta15b::TPenta15b(): + TShapeFun(3,15) + { + TInt aNbRef = myRefCoord.size(); + for(TInt aRefId = 0; aRefId < aNbRef; aRefId++){ + TCoordSlice aCoord = GetCoord(aRefId); + switch(aRefId){ + case 0: aCoord[0] = -1.0; aCoord[1] = 1.0; aCoord[2] = 0.0; break; + case 2: aCoord[0] = -1.0; aCoord[1] = -0.0; aCoord[2] = 1.0; break; + case 1: aCoord[0] = -1.0; aCoord[1] = 0.0; aCoord[2] = 0.0; break; + case 3: aCoord[0] = 1.0; aCoord[1] = 1.0; aCoord[2] = 0.0; break; + case 5: aCoord[0] = 1.0; aCoord[1] = 0.0; aCoord[2] = 1.0; break; + case 4: aCoord[0] = 1.0; aCoord[1] = 0.0; aCoord[2] = 0.0; break; + + case 8: aCoord[0] = -1.0; aCoord[1] = 0.5; aCoord[2] = 0.5; break; + case 7: aCoord[0] = -1.0; aCoord[1] = 0.0; aCoord[2] = 0.5; break; + case 6: aCoord[0] = -1.0; aCoord[1] = 0.5; aCoord[2] = 0.0; break; + case 12: aCoord[0] = 0.0; aCoord[1] = 1.0; aCoord[2] = 0.0; break; + case 14: aCoord[0] = 0.0; aCoord[1] = 0.0; aCoord[2] = 1.0; break; + case 13: aCoord[0] = 0.0; aCoord[1] = 0.0; aCoord[2] = 0.0; break; + case 11: aCoord[0] = 1.0; aCoord[1] = 0.5; aCoord[2] = 0.5; break; + case 10: aCoord[0] = 1.0; aCoord[1] = 0.0; aCoord[2] = 0.5; break; + case 9: aCoord[0] = 1.0; aCoord[1] = 0.5; aCoord[2] = 0.0; break; + } + } + } + //--------------------------------------------------------------- + TPyra5a::TPyra5a(): + TShapeFun(3,5) + { + TInt aNbRef = myRefCoord.size(); + for(TInt aRefId = 0; aRefId < aNbRef; aRefId++){ + TCoordSlice aCoord = GetCoord(aRefId); + switch(aRefId){ + case 0: aCoord[0] = 1.0; aCoord[1] = 0.0; aCoord[2] = 0.0; break; + case 1: aCoord[0] = 0.0; aCoord[1] = 1.0; aCoord[2] = 0.0; break; + case 2: aCoord[0] = -1.0; aCoord[1] = 0.0; aCoord[2] = 0.0; break; + case 3: aCoord[0] = 0.0; aCoord[1] = -1.0; aCoord[2] = 0.0; break; + case 4: aCoord[0] = 0.0; aCoord[1] = 0.0; aCoord[2] = 1.0; break; + } + } + } + //--------------------------------------------------------------- + TPyra5b::TPyra5b(): + TShapeFun(3,5) + { + TInt aNbRef = myRefCoord.size(); + for(TInt aRefId = 0; aRefId < aNbRef; aRefId++){ + TCoordSlice aCoord = GetCoord(aRefId); + switch(aRefId){ + case 0: aCoord[0] = 1.0; aCoord[1] = 0.0; aCoord[2] = 0.0; break; + case 3: aCoord[0] = 0.0; aCoord[1] = 1.0; aCoord[2] = 0.0; break; + case 2: aCoord[0] = -1.0; aCoord[1] = 0.0; aCoord[2] = 0.0; break; + case 1: aCoord[0] = 0.0; aCoord[1] = -1.0; aCoord[2] = 0.0; break; + case 4: aCoord[0] = 0.0; aCoord[1] = 0.0; aCoord[2] = 1.0; break; + } + } + } + //--------------------------------------------------------------- + TPyra13a::TPyra13a(): + TShapeFun(3,13) + { + TInt aNbRef = myRefCoord.size(); + for(TInt aRefId = 0; aRefId < aNbRef; aRefId++){ + TCoordSlice aCoord = GetCoord(aRefId); + switch(aRefId){ + case 0: aCoord[0] = 1.0; aCoord[1] = 0.0; aCoord[2] = 0.0; break; + case 1: aCoord[0] = 0.0; aCoord[1] = 1.0; aCoord[2] = 0.0; break; + case 2: aCoord[0] = -1.0; aCoord[1] = 0.0; aCoord[2] = 0.0; break; + case 3: aCoord[0] = 0.0; aCoord[1] = -1.0; aCoord[2] = 0.0; break; + case 4: aCoord[0] = 0.0; aCoord[1] = 0.0; aCoord[2] = 1.0; break; + + case 5: aCoord[0] = 0.5; aCoord[1] = 0.5; aCoord[2] = 0.0; break; + case 6: aCoord[0] = -0.5; aCoord[1] = 0.5; aCoord[2] = 0.0; break; + case 7: aCoord[0] = -0.5; aCoord[1] = -0.5; aCoord[2] = 0.0; break; + case 8: aCoord[0] = 0.5; aCoord[1] = -0.5; aCoord[2] = 0.0; break; + case 9: aCoord[0] = 0.5; aCoord[1] = 0.0; aCoord[2] = 0.5; break; + case 10: aCoord[0] = 0.0; aCoord[1] = 0.5; aCoord[2] = 0.5; break; + case 11: aCoord[0] = -0.5; aCoord[1] = 0.0; aCoord[2] = 0.5; break; + case 12: aCoord[0] = 0.0; aCoord[1] = -0.5; aCoord[2] = 0.5; break; + } + } + } + //--------------------------------------------------------------- + TPyra13b::TPyra13b(): + TShapeFun(3,13) + { + TInt aNbRef = myRefCoord.size(); + for(TInt aRefId = 0; aRefId < aNbRef; aRefId++){ + TCoordSlice aCoord = GetCoord(aRefId); + switch(aRefId){ + case 0: aCoord[0] = 1.0; aCoord[1] = 0.0; aCoord[2] = 0.0; break; + case 3: aCoord[0] = 0.0; aCoord[1] = 1.0; aCoord[2] = 0.0; break; + case 2: aCoord[0] = -1.0; aCoord[1] = 0.0; aCoord[2] = 0.0; break; + case 1: aCoord[0] = 0.0; aCoord[1] = -1.0; aCoord[2] = 0.0; break; + case 4: aCoord[0] = 0.0; aCoord[1] = 0.0; aCoord[2] = 1.0; break; + + case 8: aCoord[0] = 0.5; aCoord[1] = 0.5; aCoord[2] = 0.0; break; + case 7: aCoord[0] = -0.5; aCoord[1] = 0.5; aCoord[2] = 0.0; break; + case 6: aCoord[0] = -0.5; aCoord[1] = -0.5; aCoord[2] = 0.0; break; + case 5: aCoord[0] = 0.5; aCoord[1] = -0.5; aCoord[2] = 0.0; break; + case 9: aCoord[0] = 0.5; aCoord[1] = 0.0; aCoord[2] = 0.5; break; + case 12: aCoord[0] = 0.0; aCoord[1] = 0.5; aCoord[2] = 0.5; break; + case 11: aCoord[0] = -0.5; aCoord[1] = 0.0; aCoord[2] = 0.5; break; + case 10: aCoord[0] = 0.0; aCoord[1] = -0.5; aCoord[2] = 0.5; break; + } + } + } + /*! + * \brief Fill definition of gauss points family + */ + + TGaussDef::TGaussDef(const int geom, const int nbGauss, const int variant) + { + myType = geom; + myCoords .reserve( nbGauss * dim() ); + myWeights.reserve( nbGauss ); + + switch ( geom ) { + + case NORM_SEG2: + case NORM_SEG3: + if (geom == NORM_SEG2) setRefCoords( TSeg2a() ); + else setRefCoords( TSeg3a() ); + switch ( nbGauss ) { + case 1: { + add( 0.0, 2.0 ); break; + } + case 2: { + const double a = 0.577350269189626; + add( a, 1.0 ); + add( -a, 1.0 ); break; + } + case 3: { + const double a = 0.774596669241; + const double P1 = 1./1.8; + const double P2 = 1./1.125; + add( -a, P1 ); + add( 0, P2 ); + add( a, P1 ); break; + } + case 4: { + const double a = 0.339981043584856, b = 0.861136311594053; + const double P1 = 0.652145154862546, P2 = 0.347854845137454 ; + add( a, P1 ); + add( -a, P1 ); + add( b, P2 ); + add( -b, P2 ); break; + } + default: + THROW_IK_EXCEPTION("TGaussDef: Invalid nb of gauss points for SEG"<<nbGauss); + } + break; + + case NORM_TRI3: + case NORM_TRI6: + if ( variant == 1 ) { + if (geom == NORM_TRI3) setRefCoords( TTria3b() ); + else setRefCoords( TTria6b() ); + switch ( nbGauss ) { + case 1: { // FPG1 + add( 1/3., 1/3., 1/2. ); break; + } + case 3: { // FPG3 + // what about COT3 ??? + add( 1/6., 1/6., 1/6. ); + add( 2/3., 1/6., 1/6. ); + add( 1/6., 2/3., 1/6. ); break; + } + case 4: { // FPG4 + add( 1/5., 1/5., 25/(24*4.) ); + add( 3/5., 1/5., 25/(24*4.) ); + add( 1/5., 3/5., 25/(24*4.) ); + add( 1/3., 1/3., -27/(24*4.) ); break; + } + case 6: { // FPG6 + const double P1 = 0.11169079483905, P2 = 0.0549758718227661; + const double a = 0.445948490915965, b = 0.091576213509771; + add( b, b, P2 ); + add( 1-2*b, b, P2 ); + add( b, 1-2*b, P2 ); + add( a, 1-2*a, P1 ); + add( a, a, P1 ); + add( 1-2*a, a, P1 ); break; + } + case 7: { // FPG7 + const double A = 0.470142064105115; + const double B = 0.101286507323456; + const double P1 = 0.066197076394253; + const double P2 = 0.062969590272413; + add( 1/3., 1/3., 9/80. ); + add( A, A, P1 ); + add( 1-2*A, A, P1 ); + add( A, 1-2*A, P1 ); + add( B, B, P2 ); + add( 1-2*B, B, P2 ); + add( B, 1-2*B, P2 ); break; + } + case 12: { // FPG12 + const double A = 0.063089014491502; + const double B = 0.249286745170910; + const double C = 0.310352451033785; + const double D = 0.053145049844816; + const double P1 = 0.025422453185103; + const double P2 = 0.058393137863189; + const double P3 = 0.041425537809187; + add( A, A, P1 ); + add( 1-2*A, A, P1 ); + add( A, 1-2*A, P1 ); + add( B, B, P2 ); + add( 1-2*B, B, P2 ); + add( B, 1-2*B, P2 ); + add( C, D, P3 ); + add( D, C, P3 ); + add( 1-C-D, C, P3 ); + add( 1-C-D, D, P3 ); + add( C, 1-C-D, P3 ); + add( D, 1-C-D, P3 ); break; + } + default: + THROW_IK_EXCEPTION("TGaussDef: Invalid nb of gauss points for TRIA, variant 1: " + <<nbGauss); + } + } + else if ( variant == 2 ) { + if (geom == NORM_TRI3) setRefCoords( TTria3a() ); + else setRefCoords( TTria6a() ); + switch ( nbGauss ) { + case 1: { + add( -1/3., -1/3., 2. ); break; + } + case 3: { + add( -2/3., 1/3., 2/3. ); + add( -2/3., -2/3., 2/3. ); + add( 1/3., -2/3., 2/3. ); break; + } + case 6: { + const double P1 = 0.11169079483905, P2 = 0.0549758718227661; + const double A = 0.445948490915965, B = 0.091576213509771; + add( 2*B-1, 1-4*B, 4*P2 ); + add( 2*B-1, 2*B-1, 4*P2 ); + add( 1-4*B, 2*B-1, 4*P2 ); + add( 1-4*A, 2*A-1, 4*P1 ); + add( 2*A-1, 1-4*A, 4*P1 ); + add( 2*A-1, 2*A-1, 4*P1 ); break; + } + default: + THROW_IK_EXCEPTION("TGaussDef: Invalid nb of gauss points for TRIA, variant 2: " + <<nbGauss); + } + } + else if ( variant == 3 ) { + if (geom == NORM_TRI3) setRefCoords( TTria3b() ); + else setRefCoords( TTria6b() ); + switch ( nbGauss ) { + case 4: { + add( 1/3., 1/3., -27/96 ); + add( 0.2 , 0.2 , 25/96 ); + add( 0.6 , 0.2 , 25/96 ); + add( 0.2 , 0.6 , 25/96 ); break; + } + default: + THROW_IK_EXCEPTION("TGaussDef: Invalid nb of gauss points for TRIA, variant 3: " + <<nbGauss); + } + } + break; + + case NORM_QUAD4: + case NORM_QUAD8: + if ( variant == 1 ) { + if (geom == NORM_QUAD4) setRefCoords( TQuad4b() ); + else setRefCoords( TQuad8b() ); + switch ( nbGauss ) { + case 1: { // FPG1 + add( 0, 0, 4 ); break; + } + case 4: { // FPG4 + const double a = 1/sqrt(3.); + add( -a, -a, 1 ); + add( a, -a, 1 ); + add( a, a, 1 ); + add( -a, a, 1 ); break; + } + case 5: { // out from the 3 specs + const double a = 0.774596669241483; + add( -a, -a, 0.5 ); + add( a, -a, 0.5 ); + add( a, a, 0.5 ); + add( -a, a, 0.5 ); + add( 0, 0, 2.0 ); break; + } + case 9: { // FPG9 + const double a = 0.774596669241483; + add( -a, -a, 25/81. ); + add( a, -a, 25/81. ); + add( a, a, 25/81. ); + add( -a, a, 25/81. ); + add( 0., -a, 40/81. ); + add( a, 0., 40/81. ); + add( 0., a, 40/81. ); + add( -a, 0., 40/81. ); + add( 0., 0., 64/81. ); break; + } + default: + THROW_IK_EXCEPTION("TGaussDef: Invalid nb of gauss points for QUAD, variant 1: " + <<nbGauss); + } + } + else if ( variant == 2 ) { + if (geom == NORM_QUAD4) setRefCoords( TQuad4a() ); + else setRefCoords( TQuad8a() ); + switch ( nbGauss ) { + case 4: { + const double a = 1/sqrt(3.); + add( -a, a, 1 ); + add( -a, -a, 1 ); + add( a, -a, 1 ); + add( a, a, 1 ); break; + } + case 9: { + const double a = 0.774596669241483; + add( -a, a, 25/81. ); + add( -a, -a, 25/81. ); + add( a, -a, 25/81. ); + add( a, a, 25/81. ); + add( -a, 0., 40/81. ); + add( 0., -a, 40/81. ); + add( a, 0., 40/81. ); + add( 0., a, 40/81. ); + add( 0., 0., 64/81. ); break; + } + default: + THROW_IK_EXCEPTION("TGaussDef: Invalid nb of gauss points for QUAD, variant 1: " + <<nbGauss); + } + } + else if ( variant == 3 ) { + if (geom == NORM_QUAD4) setRefCoords( TQuad4b() ); + else setRefCoords( TQuad8b() ); + switch ( nbGauss ) { + case 4: { + const double a = 3/sqrt(3.); + add( -a, -a, 1 ); + add( -a, a, 1 ); + add( a, -a, 1 ); + add( a, a, 1 ); break; + } + case 9: { + const double a = sqrt(3/5.), c1 = 5/9., c2 = 8/9.; + const double c12 = c1*c2, c22 = c2*c2, c1c2 = c1*c2; + add( -a, -a, c12 ); + add( -a, 0., c1c2 ); + add( -a, a, c12 ); + add( 0., -a, c1c2 ); + add( 0., 0., c22 ); + add( 0., a, c1c2 ); + add( a, -a, c12 ); + add( a, 0., c1c2 ); + add( a, a, c12 ); break; + } + default: + THROW_IK_EXCEPTION("TGaussDef: Invalid nb of gauss points for QUAD, variant 3: " + <<nbGauss); + } + } + break; + + case NORM_TETRA4: + case NORM_TETRA10: + if (geom == NORM_TETRA4) setRefCoords( TTetra4a() ); + else setRefCoords( TTetra10a() ); + switch ( nbGauss ) { + case 4: { // FPG4 + const double a = (5 - sqrt(5.))/20., b = (5 + 3*sqrt(5.))/20.; + add( a, a, a, 1/24. ); + add( a, a, b, 1/24. ); + add( a, b, a, 1/24. ); + add( b, a, a, 1/24. ); break; + } + case 5: { // FPG5 + const double a = 0.25, b = 1/6., c = 0.5; + add( a, a, a, -2/15. ); + add( b, b, b, 3/40. ); + add( b, b, c, 3/40. ); + add( b, c, b, 3/40. ); + add( c, b, b, 3/40. ); break; + } + case 15: { // FPG15 + const double a = 0.25; + const double b1 = (7 + sqrt(15.))/34., c1 = (13 + 3*sqrt(15.))/34., d = (5 - sqrt(15.))/20.; + const double b2 = (7 - sqrt(15.))/34., c2 = (13 - 3*sqrt(15.))/34., e = (5 + sqrt(15.))/20.; + const double P1 = (2665 - 14*sqrt(15.))/226800.; + const double P2 = (2665 + 14*sqrt(15.))/226800.; + add( a, a, a, 8/405.);//_____ + add( b1, b1, b1, P1 ); + add( b1, b1, c1, P1 ); + add( b1, c1, b1, P1 ); + add( c1, b1, b1, P1 );//_____ + add( b2, b2, b2, P2 ); + add( b2, b2, c2, P2 ); + add( b2, c2, b2, P2 ); + add( c2, b2, b2, P2 );//_____ + add( d, d, e, 5/567.); + add( d, e, d, 5/567.); + add( e, d, d, 5/567.); + add( d, e, e, 5/567.); + add( e, d, e, 5/567.); + add( e, e, d, 5/567.); + break; + } + default: + THROW_IK_EXCEPTION("TGaussDef: Invalid nb of gauss points for TETRA: "<<nbGauss); + } + break; + + case NORM_PYRA5: + case NORM_PYRA13: + if (geom == NORM_PYRA5) setRefCoords( TPyra5a() ); + else setRefCoords( TPyra13a() ); + switch ( nbGauss ) { + case 5: { // FPG5 + const double h1 = 0.1531754163448146; + const double h2 = 0.6372983346207416; + add( .5, 0., h1, 2/15. ); + add( 0., .5, h1, 2/15. ); + add( -.5, 0., h1, 2/15. ); + add( 0., -.5, h1, 2/15. ); + add( 0., 0., h2, 2/15. ); break; + } + case 6: { // FPG6 + const double p1 = 0.1024890634400000 ; + const double p2 = 0.1100000000000000 ; + const double p3 = 0.1467104129066667 ; + const double a = 0.5702963741068025 ; + const double h1 = 0.1666666666666666 ; + const double h2 = 0.08063183038464675; + const double h3 = 0.6098484849057127 ; + add( a, 0., h1, p1 ); + add( 0., a, h1, p1 ); + add( -a, 0., h1, p1 ); + add( 0., -a, h1, p1 ); + add( 0., 0., h2, p2 ); + add( 0., 0., h3, p3 ); break; + } + case 27: { // FPG27 + const double a1 = 0.788073483; + const double b6 = 0.499369002; + const double b1 = 0.848418011; + const double c8 = 0.478508449; + const double c1 = 0.652816472; + const double d12 = 0.032303742; + const double d1 = 1.106412899; + double z = 1/2., fz = b1/2*(1 - z); + add( 0., 0., z, a1 ); // 1 + add( fz, fz, z, b6 ); // 2 + add( -fz, fz, z, b6 ); // 3 + add( -fz, -fz, z, b6 ); // 4 + add( fz, -fz, z, b6 ); // 5 + z = (1 - b1)/2.; + add( 0., 0., z, b6 ); // 6 + z = (1 + b1)/2.; + add( 0., 0., z, b6 ); // 7 + z = (1 - c1)/2.; fz = c1*(1 - z); + add( fz, 0., z, c8 ); // 8 + add( 0., fz, z, c8 ); // 9 + add( -fz, 0., z, c8 ); // 10 + add( 0., -fz, z, c8 ); // 11 + z = (1 + c1)/2.; fz = c1*(1 - z); + add( fz, 0., z, c8 ); // 12 + add( 0., fz, z, c8 ); // 13 + add( -fz, 0., z, c8 ); // 14 + add( 0., -fz, z, c8 ); // 15 + z = (1 - d1)/2., fz = d1/2*(1 - z); + add( fz, fz, z, d12); // 16 + add( -fz, fz, z, d12); // 17 + add( -fz, -fz, z, d12); // 18 + add( fz, -fz, z, d12); // 19 + z = 1/2.; fz = d1*(1 - z); + add( fz, 0., z, d12); // 20 + add( 0., fz, z, d12); // 21 + add( -fz, 0., z, d12); // 22 + add( 0., -fz, z, d12); // 23 + z = (1 + d1)/2., fz = d1/2*(1 - z); + add( fz, fz, z, d12); // 24 + add( -fz, fz, z, d12); // 25 + add( -fz, -fz, z, d12); // 26 + add( fz, -fz, z, d12); // 27 + break; + } + default: + THROW_IK_EXCEPTION("TGaussDef: Invalid nb of gauss points for PYRA: "<<nbGauss); + } + break; + case NORM_PENTA6: + case NORM_PENTA15: + if (geom == NORM_PENTA6) setRefCoords( TPenta6a() ); + else setRefCoords( TPenta15a() ); + switch ( nbGauss ) { + case 6: { // FPG6 + const double a = sqrt(3.)/3.; + add( -a, .5, .5, 1/6. ); + add( -a, 0., .5, 1/6. ); + add( -a, .5, 0., 1/6. ); + add( a, .5, .5, 1/6. ); + add( a, 0., .5, 1/6. ); + add( a, .5, 0., 1/6. ); break; + } + case 8: { // FPG8 + const double a = 0.577350269189626; + add( -a, 1/3., 1/3., -27/96. ); + add( -a, 0.6, 0.2, 25/96. ); + add( -a, 0.2, 0.6, 25/96. ); + add( -a, 0.2, 0.2, 25/96. ); + add( +a, 1/3., 1/3., -27/96. ); + add( +a, 0.6, 0.2, 25/96. ); + add( +a, 0.2, 0.6, 25/96. ); + add( +a, 0.2, 0.2, 25/96. ); break; + } + case 21: { // FPG21 + const double d = sqrt(3/5.), c1 = 5/9., c2 = 8/9.; // d <=> alfa + const double a = (6 + sqrt(15.))/21.; + const double b = (6 - sqrt(15.))/21.; + const double P1 = (155 + sqrt(15.))/2400.; + const double P2 = (155 - sqrt(15.))/2400.; //___ + add( -d, 1/3., 1/3., c1*9/80. );//___ + add( -d, a, a, c1*P1 ); + add( -d, 1-2*a, a, c1*P1 ); + add( -d, a, 1-2*a, c1*P1 );//___ + add( -d, b, b, c1*P2 ); + add( -d, 1-2*b, b, c1*P2 ); + add( -d, b, 1-2*b, c1*P2 );//___ + add( 0., 1/3., 1/3., c2*9/80. );//___ + add( 0., a, a, c2*P1 ); + add( 0., 1-2*a, a, c2*P1 ); + add( 0., a, 1-2*a, c2*P1 );//___ + add( 0., b, b, c2*P2 ); + add( 0., 1-2*b, b, c2*P2 ); + add( 0., b, 1-2*b, c2*P2 );//___ + add( d, 1/3., 1/3., c1*9/80. );//___ + add( d, a, a, c1*P1 ); + add( d, 1-2*a, a, c1*P1 ); + add( d, a, 1-2*a, c1*P1 );//___ + add( d, b, b, c1*P2 ); + add( d, 1-2*b, b, c1*P2 ); + add( d, b, 1-2*b, c1*P2 );//___ + break; + } + default: + THROW_IK_EXCEPTION("TGaussDef: Invalid nb of gauss points for PENTA: " <<nbGauss); + } + break; + + case NORM_HEXA8: + case NORM_HEXA20: + if (geom == NORM_HEXA8) setRefCoords( THexa8a() ); + else setRefCoords( THexa20a() ); + switch ( nbGauss ) { + case 8: { // FPG8 + const double a = sqrt(3.)/3.; + add( -a, -a, -a, 1. ); + add( -a, -a, a, 1. ); + add( -a, a, -a, 1. ); + add( -a, a, a, 1. ); + add( a, -a, -a, 1. ); + add( a, -a, a, 1. ); + add( a, a, -a, 1. ); + add( a, a, a, 1. ); break; + } + case 27: { // FPG27 + const double a = sqrt(3/5.), c1 = 5/9., c2 = 8/9.; + const double c12 = c1*c1, c13 = c1*c1*c1; + const double c22 = c2*c2, c23 = c2*c2*c2; + add( -a, -a, -a, c13 ); // 1 + add( -a, -a, 0., c12*c2 ); // 2 + add( -a, -a, a, c13 ); // 3 + add( -a, 0., -a, c12*c2 ); // 4 + add( -a, 0., 0., c1*c22 ); // 5 + add( -a, 0., a, c12*c2 ); // 6 + add( -a, a, -a, c13 ); // 7 + add( -a, a, 0., c12*c2 ); // 8 + add( -a, a, a, c13 ); // 9 + add( 0., -a, -a, c12*c2 ); // 10 + add( 0., -a, 0., c1*c22 ); // 11 + add( 0., -a, a, c12*c2 ); // 12 + add( 0., 0., -a, c1*c22 ); // 13 + add( 0., 0., 0., c23 ); // 14 + add( 0., 0., a, c1*c22 ); // 15 + add( 0., a, -a, c12*c2 ); // 16 + add( 0., a, 0., c1*c22 ); // 17 + add( 0., a, a, c12*c2 ); // 18 + add( a, -a, -a, c13 ); // 19 + add( a, -a, 0., c12*c2 ); // 20 + add( a, -a, a, c13 ); // 21 + add( a, 0., -a, c12*c2 ); // 22 + add( a, 0., 0., c1*c22 ); // 23 + add( a, 0., a, c12*c2 ); // 24 + add( a, a, -a, c13 ); // 25 + add( a, a, 0., c12*c2 ); // 26 + add( a, a, a, c13 ); // 27 + break; + } + default: + THROW_IK_EXCEPTION("TGaussDef: Invalid nb of gauss points for PENTA: " <<nbGauss); + } + break; + + default: + THROW_IK_EXCEPTION("TGaussDef: unexpected EGeometrieElement: "<< geom); + } + + if ( myWeights.capacity() != myWeights.size() ) + THROW_IK_EXCEPTION("TGaussDef: Not all gauss points defined"); + } +} + +//================================================================================ +/*! + * \brief Return dimension for the given cell type + */ +//================================================================================ + +unsigned SauvUtilities::getDimension( INTERP_KERNEL::NormalizedCellType type ) +{ + return type == NORM_ERROR ? -1 : INTERP_KERNEL::CellModel::GetCellModel( type ).getDimension(); +} + +//================================================================================ +/*! + * \brief Returns interlace array to transform a quadratic GIBI element to a MED one. + * i-th array item gives node index in GIBI connectivity for i-th MED node + */ +//================================================================================ + +const int * SauvUtilities::getGibi2MedQuadraticInterlace( INTERP_KERNEL::NormalizedCellType type ) +{ + static std::vector<const int*> conn; + static const int hexa20 [] = {0,6,4,2, 12,18,16,14, 7,5,3,1, 19,17,15,13, 8,11,10,9}; + static const int penta15[] = {0,2,4, 9,11,13, 1,3,5, 10,12,14, 6,8,7}; + static const int pyra13 [] = {0,2,4,6, 12, 1,3,5,7, 8,9,10,11}; + static const int tetra10[] = {0,2,4, 9, 1,3,5, 6,7,8}; + static const int quad8 [] = {0,2,4,6, 1,3,5,7}; + static const int tria6 [] = {0,2,4, 1,3,5}; + static const int seg3 [] = {0,2,1}; + if ( conn.empty() ) + { + conn.resize( MaxMedCellType + 1, 0 ); + conn[ NORM_HEXA20 ] = hexa20; + conn[ NORM_PENTA15] = penta15; + conn[ NORM_PYRA13 ] = pyra13; + conn[ NORM_TETRA10] = tetra10; + conn[ NORM_SEG3 ] = seg3; + conn[ NORM_TRI6 ] = tria6; + conn[ NORM_QUAD8 ] = quad8; + } + return conn[ type ]; +} + +//================================================================================ +/*! + * \brief Avoid coping sortedNodeIDs + */ +//================================================================================ + +Cell::Cell(const Cell& ma) + : _nodes(ma._nodes), _reverse(ma._reverse), _sortedNodeIDs(0), _number(ma._number) +{ + if ( ma._sortedNodeIDs ) + { + _sortedNodeIDs = new int[ _nodes.size() ]; + std::copy( ma._sortedNodeIDs, ma._sortedNodeIDs + _nodes.size(), _sortedNodeIDs ); + } +} + +//================================================================================ +/*! + * \brief Rerturn the i-th link of face + */ +//================================================================================ + +SauvUtilities::Link Cell::link(int i) const +{ + int i2 = ( i + 1 ) % _nodes.size(); + if ( _reverse ) + return std::make_pair( _nodes[i2]->_number, _nodes[i]->_number ); + else + return std::make_pair( _nodes[i]->_number, _nodes[i2]->_number ); +} + +//================================================================================ +/*! + * \brief creates if needed and return _sortedNodeIDs + */ +//================================================================================ + +const TID* Cell::getSortedNodes() const +{ + if ( !_sortedNodeIDs ) + { + size_t l=_nodes.size(); + _sortedNodeIDs = new int[ l ]; + + for (size_t i=0; i!=l; ++i) + _sortedNodeIDs[i]=_nodes[i]->_number; + std::sort( _sortedNodeIDs, _sortedNodeIDs + l ); + } + return _sortedNodeIDs; +} + +//================================================================================ +/*! + * \brief Compare sorted ids of cell nodes + */ +//================================================================================ + +bool Cell::operator< (const Cell& ma) const +{ + if ( _nodes.size() == 1 ) + return _nodes[0] < ma._nodes[0]; + + const int* v1 = getSortedNodes(); + const int* v2 = ma.getSortedNodes(); + for ( const int* vEnd = v1 + _nodes.size(); v1 < vEnd; ++v1, ++v2 ) + if(*v1 != *v2) + return *v1 < *v2; + return false; +} + +//================================================================================ +/*! + * \brief Dump a Cell + */ +//================================================================================ + +std::ostream& SauvUtilities::operator<< (std::ostream& os, const SauvUtilities::Cell& ma) +{ + os << "cell " << ma._number << " (" << ma._nodes.size() << " nodes) : < " << ma._nodes[0]->_number; + for( size_t i=1; i!=ma._nodes.size(); ++i) + os << ", " << ma._nodes[i]->_number; +#ifdef _DEBUG_ + os << " > sortedNodes: "; + if ( ma._sortedNodeIDs ) { + os << "< "; + for( size_t i=0; i!=ma._nodes.size(); ++i) + os << ( i ? ", " : "" ) << ma._sortedNodeIDs[i]; + os << " >"; + } + else { + os << "NULL"; + } +#endif + return os; +} + +//================================================================================ +/*! + * \brief Return nb of elements in the group + */ +//================================================================================ + +int Group::size() const +{ + int sizze = 0; + if ( !_relocTable.empty() ) + sizze = _relocTable.size(); + else if ( _medGroup ) + sizze = _medGroup->getNumberOfTuples(); + else if ( !_cells.empty() ) + sizze = _cells.size(); + else + for ( size_t i = 0; i < _groups.size(); ++i ) + sizze += _groups[i]->size(); + return sizze; +} + +//================================================================================ +/*! + * \brief Conver gibi element type to med one + */ +//================================================================================ + +INTERP_KERNEL::NormalizedCellType SauvUtilities::gibi2medGeom( size_t gibiType ) +{ + if ( gibiType < 1 || gibiType > NbGibiCellTypes ) + return NORM_ERROR; + + return GibiTypeToMed[ gibiType - 1 ]; +} + +//================================================================================ +/*! + * \brief Conver med element type to gibi one + */ +//================================================================================ + +int SauvUtilities::med2gibiGeom( INTERP_KERNEL::NormalizedCellType medGeomType ) +{ + for ( unsigned int i = 0; i < NbGibiCellTypes; i++ ) + if ( GibiTypeToMed[ i ] == medGeomType ) + return i + 1; + + return -1; +} + +//================================================================================ +/*! + * \brief Remember the file name + */ +//================================================================================ + +FileReader::FileReader(const char* fileName):_fileName(fileName),_iRead(0),_nbToRead(0) +{ +} + +//================================================================================ +/*! + * \brief Constructor of ASCII sauve file reader + */ +//================================================================================ + +ASCIIReader::ASCIIReader(const char* fileName) + :FileReader(fileName), + _file(-1) +{ +} + +//================================================================================ +/*! + * \brief Return true + */ +//================================================================================ + +bool ASCIIReader::isASCII() const +{ + return true; +} + +//================================================================================ +/*! + * \brief Try to open an ASCII file + */ +//================================================================================ + +bool ASCIIReader::open() +{ +#ifdef WIN32 + _file = ::_open (_fileName.c_str(), _O_RDONLY|_O_BINARY); +#else + _file = ::open (_fileName.c_str(), O_RDONLY); +#endif + if (_file >= 0) + { + _start = new char [GIBI_BufferSize]; // working buffer beginning + //_tmpBuf = new char [GIBI_MaxOutputLen]; + _ptr = _start; + _eptr = _start; + _lineNb = 0; + } + else + { + //THROW_IK_EXCEPTION("Can't open file "<<_fileName << " fd: " << _file); + } + return (_file >= 0); +} + +//================================================================================ +/*! + * \brief Close the file + */ +//================================================================================ + +ASCIIReader::~ASCIIReader() +{ + if (_file >= 0) + { + ::close (_file); + if (_start != 0L) + { + delete [] _start; + //delete [] _tmpBuf; + _start = 0; + } + _file = -1; + } +} + +//================================================================================ +/*! + * \brief Return a next line of the file + */ +//================================================================================ + +bool ASCIIReader::getNextLine (char* & line, bool raiseOEF /*= true*/ ) +{ + if ( getLine( line )) return true; + if ( raiseOEF ) + THROW_IK_EXCEPTION("Unexpected EOF on ln "<<_lineNb); + return false; +} + +//================================================================================ +/*! + * \brief Read a next line of the file if necessary + */ +//================================================================================ + +bool ASCIIReader::getLine(char* & line) +{ + bool aResult = true; + // Check the state of the buffer; + // if there is too little left, read the next portion of data + int nBytesRest = _eptr - _ptr; + if (nBytesRest < GIBI_MaxOutputLen) + { + if (nBytesRest > 0) + { + // move the remaining portion to the buffer beginning + for ( int i = 0; i < nBytesRest; ++i ) + _start[i] = _ptr[i]; + //memcpy (_tmpBuf, _ptr, nBytesRest); + //memcpy (_start, _tmpBuf, nBytesRest); + } + else + { + nBytesRest = 0; + } + _ptr = _start; + const int nBytesRead = ::read (_file, + &_start [nBytesRest], + GIBI_BufferSize - nBytesRest); + nBytesRest += nBytesRead; + _eptr = &_start [nBytesRest]; + } + // Check the buffer for the end-of-line + char * ptr = _ptr; + while (true) + { + // Check for end-of-the-buffer, the ultimate criterion for termination + if (ptr >= _eptr) + { + if (nBytesRest <= 0) + aResult = false; + else + _eptr[-1] = '\0'; + break; + } + // seek the line-feed character + if (ptr[0] == '\n') + { + if (ptr[-1] == '\r') + ptr[-1] = '\0'; + ptr[0] = '\0'; + ++ptr; + break; + } + ++ptr; + } + // Output the result + line = _ptr; + _ptr = ptr; + _lineNb++; + + return aResult; +} + +//================================================================================ +/*! + * \brief Prepare for iterating over given nb of values + * \param nbToRead - nb of fields to read + * \param nbPosInLine - nb of fields in one line + * \param width - field width + * \param shift - shift from line beginning to the field start + */ +//================================================================================ + +void ASCIIReader::init( int nbToRead, int nbPosInLine, int width, int shift /*= 0*/ ) +{ + _nbToRead = nbToRead; + _nbPosInLine = nbPosInLine; + _width = width; + _shift = shift; + _iPos = _iRead = 0; + if ( _nbToRead ) + { + getNextLine( _curPos ); + _curPos = _curPos + _shift; + } + else + { + _curPos = 0; + } + _curLocale.clear(); +} + +//================================================================================ +/*! + * \brief Prepare for iterating over given nb of string values + */ +//================================================================================ + +void ASCIIReader::initNameReading(int nbValues, int width /*= 8*/) +{ + init( nbValues, 72 / ( width + 1 ), width, 1 ); +} + +//================================================================================ +/*! + * \brief Prepare for iterating over given nb of integer values + */ +//================================================================================ + +void ASCIIReader::initIntReading(int nbValues) +{ + init( nbValues, 10, 8 ); +} + +//================================================================================ +/*! + * \brief Prepare for iterating over given nb of real values + */ +//================================================================================ + +void ASCIIReader::initDoubleReading(int nbValues) +{ + init( nbValues, 3, 22 ); + + // Correction 2 of getDouble(): set "C" numeric locale to read numbers + // with dot decimal point separator, as it is in SAUVE files + _curLocale = setlocale(LC_NUMERIC, "C"); +} + +//================================================================================ +/*! + * \brief Return true if not all values have been read + */ +//================================================================================ + +bool ASCIIReader::more() const +{ + bool result = false; + if ( _iRead < _nbToRead) + { + if ( _curPos ) result = true; + } + return result; +} + +//================================================================================ +/*! + * \brief Go to the nex value + */ +//================================================================================ + +void ASCIIReader::next() +{ + if ( !more() ) + THROW_IK_EXCEPTION("SauvUtilities::ASCIIReader::next(): no more() values to read"); + ++_iRead; + ++_iPos; + if ( _iRead < _nbToRead ) + { + if ( _iPos >= _nbPosInLine ) + { + getNextLine( _curPos ); + _curPos = _curPos + _shift; + _iPos = 0; + } + else + { + _curPos = _curPos + _width + _shift; + } + } + else + { + _curPos = 0; + if ( !_curLocale.empty() ) + { + setlocale(LC_NUMERIC, _curLocale.c_str()); + _curLocale.clear(); + } + } +} + +//================================================================================ +/*! + * \brief Return the current integer value + */ +//================================================================================ + +int ASCIIReader::getInt() const +{ + // fix for two glued ints (issue 0021009): + // Line nb | File contents + // ------------------------------------------------------------------------------------ + // 53619905 | 1 2 6 8 + // 53619906 | SCALAIRE + // 53619907 | -63312600499 1 0 0 0 -2 0 2 + // where -63312600499 is actualy -633 and 12600499 + char hold=_curPos[_width]; + _curPos[_width] = '\0'; + int result = atoi( _curPos ); + _curPos[_width] = hold; + return result; + //return atoi(str()); +} + +//================================================================================ +/*! + * \brief Return the current float value + */ +//================================================================================ + +float ASCIIReader::getFloat() const +{ + return getDouble(); +} + +//================================================================================ +/*! + * \brief Return the current double value + */ +//================================================================================ + +double ASCIIReader::getDouble() const +{ + //std::string aStr (_curPos); + + // Correction: add missing 'E' specifier + // int aPosStart = aStr.find_first_not_of(" \t"); + // if (aPosStart < (int)aStr.length()) { + // int aPosSign = aStr.find_first_of("+-", aPosStart + 1); // pass the leading symbol, as it can be a sign + // if (aPosSign < (int)aStr.length()) { + // if (aStr[aPosSign - 1] != 'e' && aStr[aPosSign - 1] != 'E') + // aStr.insert(aPosSign, "E", 1); + // } + // } + + // Different Correction (more optimal) + // Sample: + // 0.00000000000000E+00 -2.37822406690632E+01 6.03062748797469E+01 + // 7.70000000000000-100 7.70000000000000+100 7.70000000000000+100 + //0123456789012345678901234567890123456789012345678901234567890123456789 + const size_t posE = 18; + std::string aStr (_curPos); + if ( aStr.find('E') < 0 && aStr.find('e') < 0 ) + { + if ( aStr.size() < posE+1 ) + THROW_IK_EXCEPTION("No more doubles (line #" << lineNb() << ")"); + aStr.insert( posE, "E", 1 ); + return atof(aStr.c_str()); + } + return atof( _curPos ); +} + +//================================================================================ +/*! + * \brief Return the current string value + */ +//================================================================================ + +std::string ASCIIReader::getName() const +{ + int len = _width; + while (( _curPos[len-1] == ' ' || _curPos[len-1] == 0) && len > 0 ) + len--; + return std::string( _curPos, len ); +} + +//================================================================================ +/*! + * \brief Constructor of a binary sauve file reader + */ +//================================================================================ + +XDRReader::XDRReader(const char* fileName) :FileReader(fileName), _xdrs_file(NULL) +{ +} + +//================================================================================ +/*! + * \brief Close the XDR sauve file + */ +//================================================================================ + +XDRReader::~XDRReader() +{ +#ifdef HAS_XDR + if ( _xdrs_file ) + { + xdr_destroy((XDR*)_xdrs); + free((XDR*)_xdrs); + ::fclose(_xdrs_file); + _xdrs_file = NULL; + } +#endif +} + +//================================================================================ +/*! + * \brief Return false + */ +//================================================================================ + +bool XDRReader::isASCII() const +{ + return false; +} + +//================================================================================ +/*! + * \brief Try to open an XRD file + */ +//================================================================================ + +bool XDRReader::open() +{ + bool xdr_ok = false; +#ifdef HAS_XDR +#ifdef WIN32 + if ((_xdrs_file = ::fopen(_fileName.c_str(), "rb"))) +#else + if ((_xdrs_file = ::fopen(_fileName.c_str(), "r"))) +#endif + { + _xdrs = (XDR *)malloc(sizeof(XDR)); + xdrstdio_create((XDR*)_xdrs, _xdrs_file, XDR_DECODE); + + const int maxsize = 10; + char icha[maxsize+1]; + char* icha2 = icha; + if (( xdr_ok = xdr_string((XDR*)_xdrs, &icha2, maxsize))) + { + icha[maxsize] = '\0'; + xdr_ok = (strcmp(icha, "CASTEM XDR") == 0); + } + if ( !xdr_ok ) + { + xdr_destroy((XDR*)_xdrs); + free((XDR*)_xdrs); + fclose(_xdrs_file); + _xdrs_file = NULL; + } + } +#endif + return xdr_ok; +} + +//================================================================================ +/*! + * \brief A stub + */ +//================================================================================ + +bool XDRReader::getNextLine (char* &, bool ) +{ + return true; +} + +//================================================================================ +/*! + * \brief Prepare for iterating over given nb of values + * \param nbToRead - nb of fields to read + * \param width - field width + */ +//================================================================================ + +void XDRReader::init( int nbToRead, int width/*=0*/ ) +{ + if(_iRead < _nbToRead) + { + std::cout << "_iRead, _nbToRead : " << _iRead << " " << _nbToRead << std::endl; + std::cout << "Unfinished iteration before new one !" << std::endl; + THROW_IK_EXCEPTION("SauvUtilities::XDRReader::init(): Unfinished iteration before new one !"); + } + _iRead = 0; + _nbToRead = nbToRead; + _width = width; +} + +//================================================================================ +/*! + * \brief Prepare for iterating over given nb of string values + */ +//================================================================================ + +void XDRReader::initNameReading(int nbValues, int width) +{ + init( nbValues, width ); + _xdr_kind = _xdr_kind_char; + if(nbValues*width) + { + unsigned int nels = nbValues*width; + _xdr_cvals = (char*)malloc((nels+1)*sizeof(char)); +#ifdef HAS_XDR + xdr_string((XDR*)_xdrs, &_xdr_cvals, nels); +#endif + _xdr_cvals[nels] = '\0'; + } +} + +//================================================================================ +/*! + * \brief Prepare for iterating over given nb of integer values + */ +//================================================================================ + +void XDRReader::initIntReading(int nbValues) +{ + init( nbValues ); + _xdr_kind = _xdr_kind_int; + if(nbValues) + { +#ifdef HAS_XDR + unsigned int nels = nbValues; + unsigned int actual_nels; + _xdr_ivals = (int*)malloc(nels*sizeof(int)); + xdr_array((XDR*)_xdrs, (char **)&_xdr_ivals, &actual_nels, nels, sizeof(int), (xdrproc_t)xdr_int); +#endif + } +} + +//================================================================================ +/*! + * \brief Prepare for iterating over given nb of real values + */ +//================================================================================ + +void XDRReader::initDoubleReading(int nbValues) +{ + init( nbValues ); + _xdr_kind = _xdr_kind_double; + if(nbValues) + { +#ifdef HAS_XDR + unsigned int nels = nbValues; + unsigned int actual_nels; + _xdr_dvals = (double*)malloc(nels*sizeof(double)); + xdr_array((XDR*)_xdrs, (char **)&_xdr_dvals, &actual_nels, nels, sizeof(double), (xdrproc_t)xdr_double); +#endif + } +} + +//================================================================================ +/*! + * \brief Return true if not all values have been read + */ +//================================================================================ + +bool XDRReader::more() const +{ + return _iRead < _nbToRead; +} + +//================================================================================ +/*! + * \brief Go to the nex value + */ +//================================================================================ + +void XDRReader::next() +{ + if ( !more() ) + THROW_IK_EXCEPTION("SauvUtilities::XDRReader::next(): no more() values to read"); + + ++_iRead; + if ( _iRead < _nbToRead ) + { + } + else + { + if(_xdr_kind == _xdr_kind_char) free(_xdr_cvals); + if(_xdr_kind == _xdr_kind_int) free(_xdr_ivals); + if(_xdr_kind == _xdr_kind_double) free(_xdr_dvals); + _xdr_kind = _xdr_kind_null; + } +} + +//================================================================================ +/*! + * \brief Return the current integer value + */ +//================================================================================ + +int XDRReader::getInt() const +{ + if(_iRead < _nbToRead) + { + return _xdr_ivals[_iRead]; + } + else + { + int result = 0; +#ifdef HAS_XDR + xdr_int((XDR*)_xdrs, &result); +#endif + return result; + } +} + +//================================================================================ +/*! + * \brief Return the current float value + */ +//================================================================================ + +float XDRReader::getFloat() const +{ + float result = 0; +#ifdef HAS_XDR + xdr_float((XDR*)_xdrs, &result); +#endif + return result; +} + +//================================================================================ +/*! + * \brief Return the current double value + */ +//================================================================================ + +double XDRReader::getDouble() const +{ + if(_iRead < _nbToRead) + { + return _xdr_dvals[_iRead]; + } + else + { + double result = 0; +#ifdef HAS_XDR + xdr_double((XDR*)_xdrs, &result); +#endif + return result; + } +} + +//================================================================================ +/*! + * \brief Return the current string value + */ +//================================================================================ + +std::string XDRReader::getName() const +{ + int len = _width; + char* s = _xdr_cvals + _iRead*_width; + while (( s[len-1] == ' ' || s[len-1] == 0) && len > 0 ) + len--; + return std::string( s, len ); +} + +//================================================================================ +/*! + * \brief Throw an exception if not all needed data is present + */ +//================================================================================ + +void IntermediateMED::checkDataAvailability() const +{ + if ( _spaceDim == 0 ) + THROW_IK_EXCEPTION("Wrong file format"); // it is the first record in the sauve file + + if ( _groups.empty() ) + THROW_IK_EXCEPTION("No elements have been read"); + + if ( _points.empty() || _nbNodes == 0 ) + THROW_IK_EXCEPTION("Nodes of elements are not filled"); + + if ( _coords.empty() ) + THROW_IK_EXCEPTION("Node coordinates are missing"); + + if ( _coords.size() < _nbNodes * _spaceDim ) + THROW_IK_EXCEPTION("Nodes and coordinates mismatch"); +} + +//================================================================================ +/*! + * \brief Safely adds a new Group + */ +//================================================================================ + +Group* IntermediateMED::addNewGroup(std::vector<SauvUtilities::Group*>* groupsToFix) +{ + if ( _groups.size() == _groups.capacity() ) // re-allocation would occure + { + std::vector<Group> newGroups( _groups.size() ); + newGroups.push_back( Group() ); + + for ( size_t i = 0; i < _groups.size(); ++i ) + { + // avoid copying _cells + std::vector<const Cell*> cells; + cells.swap( _groups[i]._cells ); + newGroups[i] = _groups[i]; + newGroups[i]._cells.swap( cells ); + + // correct pointers to sub-groups + for ( size_t j = 0; j < _groups[i]._groups.size(); ++j ) + { + int iG = _groups[i]._groups[j] - &_groups[0]; + newGroups[i]._groups[j] = & newGroups[ iG ]; + } + } + + // fix given groups + if ( groupsToFix ) + for ( size_t i = 0; i < groupsToFix->size(); ++i ) + if ( (*groupsToFix)[i] ) + { + int iG = (*groupsToFix)[i] - &_groups[0]; + (*groupsToFix)[i] = & newGroups[ iG ]; + } + + // fix field supports + for ( int isNode = 0; isNode < 2; ++isNode ) + { + std::vector<DoubleField* >& fields = isNode ? _nodeFields : _cellFields; + for ( size_t i = 0; i < fields.size(); ++i ) + { + if ( !fields[i] ) continue; + for ( size_t j = 0; j < fields[i]->_sub.size(); ++j ) + if ( fields[i]->_sub[j]._support ) + { + int iG = fields[i]->_sub[j]._support - &_groups[0]; + fields[i]->_sub[j]._support = & newGroups[ iG ]; + } + if ( fields[i]->_group ) + { + int iG = fields[i]->_group - &_groups[0]; + fields[i]->_group = & newGroups[ iG ]; + } + } + } + + _groups.swap( newGroups ); + } + else + { + _groups.push_back( Group() ); + } + return &_groups.back(); +} + +//================================================================================ +/*! + * \brief Makes ParaMEDMEM::MEDFileData from self + */ +//================================================================================ + +ParaMEDMEM::MEDFileData* IntermediateMED::convertInMEDFileDS() +{ + MEDCouplingAutoRefCountObjectPtr< MEDFileUMesh > mesh = makeMEDFileMesh(); + MEDCouplingAutoRefCountObjectPtr< MEDFileFields > fields = makeMEDFileFields(mesh); + + MEDCouplingAutoRefCountObjectPtr< MEDFileMeshes > meshes = MEDFileMeshes::New(); + MEDCouplingAutoRefCountObjectPtr< MEDFileData > medData = MEDFileData::New(); + meshes->pushMesh( mesh ); + medData->setMeshes( meshes ); + if ( fields ) medData->setFields( fields ); + + return medData.retn(); +} + +//================================================================================ +/*! + * \brief Creates ParaMEDMEM::MEDFileUMesh from its data + */ +//================================================================================ + +ParaMEDMEM::MEDFileUMesh* IntermediateMED::makeMEDFileMesh() +{ + // check if all needed piles are present + checkDataAvailability(); + + // set long names + setGroupLongNames(); + + // fix element orientation + if ( _spaceDim == 2 || _spaceDim == 1 ) + orientElements2D(); + else if ( _spaceDim == 3 ) + orientElements3D(); + + // process groups + decreaseHierarchicalDepthOfSubgroups(); + eraseUselessGroups(); + //detectMixDimGroups(); + + // assign IDs + _points.numberNodes(); + numberElements(); + + // make the med mesh + + MEDFileUMesh* mesh = MEDFileUMesh::New(); + + DataArrayDouble *coords = getCoords(); + setConnectivity( mesh, coords ); + setGroups( mesh ); + + coords->decrRef(); + + if ( !mesh->getName().c_str() || strlen( mesh->getName().c_str() ) == 0 ) + mesh->setName( "MESH" ); + + return mesh; +} + +//================================================================================ +/*! + * \brief Set long names to groups + */ +//================================================================================ + +void IntermediateMED::setGroupLongNames() +{ + // IMP 0020434: mapping GIBI names to MED names + // set med names to objects (mesh, fields, support, group or other) + + std::set<int> treatedGroups; + + std::list<nameGIBItoMED>::iterator itGIBItoMED = _listGIBItoMED_mail.begin(); + for (; itGIBItoMED != _listGIBItoMED_mail.end(); itGIBItoMED++) + { + if ( (int)_groups.size() < itGIBItoMED->gibi_id ) continue; + + SauvUtilities::Group & grp = _groups[itGIBItoMED->gibi_id - 1]; + + // if there are several names for grp then the 1st name is the name + // of grp and the rest ones are names of groups referring grp (issue 0021311) + const bool isRefName = !treatedGroups.insert( itGIBItoMED->gibi_id ).second; + if ( !isRefName ) + { + grp._name = _mapStrings[ itGIBItoMED->med_id ]; + } + else if ( !grp._refNames.empty() && grp._refNames.back().empty() ) + { + for ( unsigned i = 0; i < grp._refNames.size(); ++i ) + if ( grp._refNames[i].empty() ) + grp._refNames[i] = _mapStrings[ (*itGIBItoMED).med_id ]; + } + else + { + grp._refNames.push_back( _mapStrings[ (*itGIBItoMED).med_id ]); + } + } +} + +//================================================================================ +/*! + * \brief Set long names to fields + */ +//================================================================================ + +void IntermediateMED::setFieldLongNames(std::set< std::string >& usedNames) +{ + std::list<nameGIBItoMED>::iterator itGIBItoMED = _listGIBItoMED_cham.begin(); + for (; itGIBItoMED != _listGIBItoMED_cham.end(); itGIBItoMED++) + { + if (itGIBItoMED->gibi_pile == PILE_FIELD) + { + _cellFields[itGIBItoMED->gibi_id - 1]->_name = _mapStrings[itGIBItoMED->med_id]; + } + else if (itGIBItoMED->gibi_pile == PILE_NODES_FIELD) + { + _nodeFields[itGIBItoMED->gibi_id - 1]->_name = _mapStrings[itGIBItoMED->med_id]; + } + } // iterate on _listGIBItoMED_cham + + for (itGIBItoMED =_listGIBItoMED_comp.begin(); itGIBItoMED != _listGIBItoMED_comp.end(); itGIBItoMED++) + { + std::string medName = _mapStrings[itGIBItoMED->med_id]; + std::string gibiName = _mapStrings[itGIBItoMED->gibi_id]; + + bool name_found = false; + for ( int isNodal = 0; isNodal < 2 && !name_found; ++isNodal ) + { + std::vector<DoubleField* > & fields = isNodal ? _nodeFields : _cellFields; + for ( size_t ifi = 0; ifi < fields.size() && !name_found; ifi++) + { + if (medName.find( fields[ifi]->_name + "." ) == 0 ) + { + std::vector<DoubleField::_Sub_data>& aSubDs = fields[ifi]->_sub; + int nbSub = aSubDs.size(); + for (int isu = 0; isu < nbSub; isu++) + for (int ico = 0; ico < aSubDs[isu].nbComponents(); ico++) + { + if (aSubDs[isu].compName(ico) == gibiName) + { + std::string medNameCompo = medName.substr( fields[ifi]->_name.size() + 1 ); + fields[ifi]->_sub[isu].compName(ico) = medNameCompo; + } + } + } + } + } + } // iterate on _listGIBItoMED_comp + + for ( size_t i = 0; i < _nodeFields.size() ; i++) + usedNames.insert( _nodeFields[i]->_name ); + for ( size_t i = 0; i < _cellFields.size() ; i++) + usedNames.insert( _cellFields[i]->_name ); +} + +//================================================================================ +/*! + * \brief Decrease hierarchical depth of subgroups + */ +//================================================================================ + +void IntermediateMED::decreaseHierarchicalDepthOfSubgroups() +{ + for (size_t i=0; i!=_groups.size(); ++i) + { + Group& grp = _groups[i]; + for (size_t j = 0; j < grp._groups.size(); ++j ) + { + Group & sub_grp = *grp._groups[j]; + if ( !sub_grp._groups.empty() ) + { + // replace j with its 1st subgroup + grp._groups[j] = sub_grp._groups[0]; + // push back the rest subs + grp._groups.insert( grp._groups.end(), ++sub_grp._groups.begin(), sub_grp._groups.end() ); + } + } + // remove empty sub-_groups + std::vector< Group* > newSubGroups; + newSubGroups.reserve( grp._groups.size() ); + for (size_t j = 0; j < grp._groups.size(); ++j ) + if ( !grp._groups[j]->empty() ) + newSubGroups.push_back( grp._groups[j] ); + if ( newSubGroups.size() < grp._groups.size() ) + grp._groups.swap( newSubGroups ); + } +} + +//================================================================================ +/*! + * \brief Erase _groups that won't be converted + */ +//================================================================================ + +void IntermediateMED::eraseUselessGroups() +{ + // propagate _isProfile=true to sub-groups of composite groups + // for (size_t int i=0; i!=_groups.size(); ++i) + // { + // Group* grp = _groups[i]; + // if ( grp->_isProfile && !grp->_groups.empty() ) + // for (size_t j = 0; j < grp->_groups.size(); ++j ) + // grp->_groups[j]->_isProfile=true; + // } + std::set<Group*> groups2convert; + // keep not named sub-groups of field supports + for (size_t i=0; i!=_groups.size(); ++i) + { + Group& grp = _groups[i]; + if ( grp._isProfile && !grp._groups.empty() ) + groups2convert.insert( grp._groups.begin(), grp._groups.end() ); + } + + // keep named groups and their subgroups + for (size_t i=0; i!=_groups.size(); ++i) + { + Group& grp = _groups[i]; + if ( !grp._name.empty() && !grp.empty() ) + { + groups2convert.insert( &grp ); + groups2convert.insert( grp._groups.begin(), grp._groups.end() ); + } + } + // erase groups that are not in groups2convert and not _isProfile + for (size_t i=0; i!=_groups.size(); ++i) + { + Group* grp = &_groups[i]; + if ( !grp->_isProfile && !groups2convert.count( grp ) ) + { + grp->_cells.clear(); + grp->_groups.clear(); + } + } +} + +//================================================================================ +/*! + * \brief Detect _groups of mixed dimension + */ +//================================================================================ + +void IntermediateMED::detectMixDimGroups() +{ + //hasMixedCells = false; + for ( size_t i=0; i < _groups.size(); ++i ) + { + Group& grp = _groups[i]; + if ( grp._groups.size() < 2 ) + continue; + + // check if sub-groups have different dimension + unsigned dim1 = getDim( &grp ); + for ( size_t j = 1; j < grp._groups.size(); ++j ) + { + unsigned dim2 = getDim( grp._groups[j] ); + if ( dim1 != dim2 ) + { + grp._cells.clear(); + grp._groups.clear(); + if ( !grp._name.empty() ) + std::cout << "Erase a group with elements of different dim |" << grp._name << "|"<< std::endl; + break; + } + } + } +} + +//================================================================================ +/*! + * \brief Fix connectivity of elements in 2D space + */ +//================================================================================ + +void IntermediateMED::orientElements2D() +{ + std::set<Cell>::const_iterator elemIt, elemEnd; + std::vector< std::pair<int,int> > swapVec; + + // ------------------------------------ + // fix connectivity of quadratic edges + // ------------------------------------ + std::set<Cell>& quadEdges = _cellsByType[ INTERP_KERNEL::NORM_SEG3 ]; + if ( !quadEdges.empty() ) + { + elemIt = quadEdges.begin(), elemEnd = quadEdges.end(); + for ( ; elemIt != elemEnd; ++elemIt ) + ConvertQuadratic( INTERP_KERNEL::NORM_SEG3, *elemIt ); + } + + CellsByDimIterator faceIt( *this, 2 ); + while ( const std::set<Cell > * faces = faceIt.nextType() ) + { + TCellType cellType = faceIt.type(); + bool isQuadratic = getGibi2MedQuadraticInterlace( cellType ); + + getReverseVector( cellType, swapVec ); + + // ------------------------------------ + // fix connectivity of quadratic faces + // ------------------------------------ + if ( isQuadratic ) + for ( elemIt = faces->begin(), elemEnd = faces->end(); elemIt != elemEnd; elemIt++ ) + ConvertQuadratic( cellType, *elemIt ); + + // -------------------------- + // orient faces clockwise + // -------------------------- + // COMMENTED for issue 0022612 note 17739 + // int iQuad = isQuadratic ? 2 : 1; + // for ( elemIt = faces->begin(), elemEnd = faces->end(); elemIt != elemEnd; elemIt++ ) + // { + // // look for index of the most left node + // int iLeft = 0, iNode, nbNodes = elemIt->_nodes.size() / iQuad; + // double x, minX = nodeCoords( elemIt->_nodes[0] )[0]; + // for ( iNode = 1; iNode < nbNodes; ++iNode ) + // if (( x = nodeCoords( elemIt->_nodes[ iNode ])[ 0 ]) < minX ) + // minX = x, iLeft = iNode; + + // // indeces of the nodes neighboring the most left one + // int iPrev = ( iLeft - 1 < 0 ) ? nbNodes - 1 : iLeft - 1; + // int iNext = ( iLeft + 1 == nbNodes ) ? 0 : iLeft + 1; + // // find components of prev-left and left-next vectors + // double xP = nodeCoords( elemIt->_nodes[ iPrev ])[ 0 ]; + // double yP = nodeCoords( elemIt->_nodes[ iPrev ])[ 1 ]; + // double xN = nodeCoords( elemIt->_nodes[ iNext ])[ 0 ]; + // double yN = nodeCoords( elemIt->_nodes[ iNext ])[ 1 ]; + // double xL = nodeCoords( elemIt->_nodes[ iLeft ])[ 0 ]; + // double yL = nodeCoords( elemIt->_nodes[ iLeft ])[ 1 ]; + // double xPL = xL - xP, yPL = yL - yP; // components of prev-left vector + // double xLN = xN - xL, yLN = yN - yL; // components of left-next vector + // // normalise y of the vectors + // double modPL = sqrt ( xPL * xPL + yPL * yPL ); + // double modLN = sqrt ( xLN * xLN + yLN * yLN ); + // if ( modLN > std::numeric_limits<double>::min() && + // modPL > std::numeric_limits<double>::min() ) + // { + // yPL /= modPL; + // yLN /= modLN; + // // summary direction of neighboring links must be positive + // bool clockwise = ( yPL + yLN > 0 ); + // if ( !clockwise ) + // reverse( *elemIt, swapVec ); + // } + // } + } +} + +//================================================================================ +/*! + * \brief Fix connectivity of elements in 3D space + */ +//================================================================================ + +void IntermediateMED::orientElements3D() +{ + // set _reverse flags of faces + // COMMENTED for issue 0022612 note 17739 + //orientFaces3D(); + + // ----------------- + // fix connectivity + // ----------------- + + std::set<Cell>::const_iterator elemIt, elemEnd; + std::vector< std::pair<int,int> > swapVec; + + for ( int dim = 1; dim <= 3; ++dim ) + { + CellsByDimIterator cellsIt( *this, dim ); + while ( const std::set<Cell > * elems = cellsIt.nextType() ) + { + TCellType cellType = cellsIt.type(); + bool isQuadratic = getGibi2MedQuadraticInterlace( cellType ); + getReverseVector( cellType, swapVec ); + + elemIt = elems->begin(), elemEnd = elems->end(); + for ( ; elemIt != elemEnd; elemIt++ ) + { + // GIBI connectivity -> MED one + if( isQuadratic ) + ConvertQuadratic( cellType, *elemIt ); + + // reverse faces + if ( elemIt->_reverse ) + reverse ( *elemIt, swapVec ); + } + } + } + + // COMMENTED for issue 0022612 note 17739 + //orientVolumes(); +} + +//================================================================================ +/*! + * \brief Orient equally (by setting _reverse flag) all connected faces in 3D space + */ +//================================================================================ + +void IntermediateMED::orientFaces3D() +{ + // fill map of links and their faces + std::set<const Cell*> faces; + std::map<const Cell*, Group*> fgm; + std::map<Link, std::list<const Cell*> > linkFacesMap; + std::map<Link, std::list<const Cell*> >::iterator lfIt, lfIt2; + + for (size_t i=0; i!=_groups.size(); ++i) + { + Group& grp = _groups[i]; + if ( !grp._cells.empty() && getDimension( grp._cellType ) == 2 ) + for ( size_t j = 0; j < grp._cells.size(); ++j ) + if ( faces.insert( grp._cells[j] ).second ) + { + for ( size_t k = 0; k < grp._cells[j]->_nodes.size(); ++k ) + linkFacesMap[ grp._cells[j]->link( k ) ].push_back( grp._cells[j] ); + fgm.insert( std::make_pair( grp._cells[j], &grp )); + } + } + // dump linkFacesMap + // for ( lfIt = linkFacesMap.begin(); lfIt!=linkFacesMap.end(); lfIt++) { + // cout<< "LINK: " << lfIt->first.first << "-" << lfIt->first.second << std::endl; + // std::list<const Cell*> & fList = lfIt->second; + // std::list<const Cell*>::iterator fIt = fList.begin(); + // for ( ; fIt != fList.end(); fIt++ ) + // cout << "\t" << **fIt << fgm[*fIt]->nom << std::endl; + // } + + // Each oriented link must appear in one face only, else a face is reversed. + + std::queue<const Cell*> faceQueue; /* the queue contains well oriented faces + whose neighbors orientation is to be checked */ + bool manifold = true; + while ( !linkFacesMap.empty() ) + { + if ( faceQueue.empty() ) + { + assert( !linkFacesMap.begin()->second.empty() ); + faceQueue.push( linkFacesMap.begin()->second.front() ); + } + while ( !faceQueue.empty() ) + { + const Cell* face = faceQueue.front(); + faceQueue.pop(); + + // loop on links of <face> + for ( int i = 0; i < (int)face->_nodes.size(); ++i ) + { + Link link = face->link( i ); + // find the neighbor faces + lfIt = linkFacesMap.find( link ); + int nbFaceByLink = 0; + std::list< const Cell* > ml; + if ( lfIt != linkFacesMap.end() ) + { + std::list<const Cell*> & fList = lfIt->second; + std::list<const Cell*>::iterator fIt = fList.begin(); + assert( fIt != fList.end() ); + for ( ; fIt != fList.end(); fIt++, nbFaceByLink++ ) + { + ml.push_back( *fIt ); + if ( *fIt != face ) // wrongly oriented neighbor face + { + const Cell* badFace = *fIt; + // reverse and remove badFace from linkFacesMap + for ( int j = 0; j < (int)badFace->_nodes.size(); ++j ) + { + Link badlink = badFace->link( j ); + if ( badlink == link ) continue; + lfIt2 = linkFacesMap.find( badlink ); + if ( lfIt2 != linkFacesMap.end() ) + { + std::list<const Cell*> & ff = lfIt2->second; + std::list<const Cell*>::iterator lfIt3 = find( ff.begin(), ff.end(), badFace ); + // check if badFace has been found, + // else we can't erase it + // case of degenerated face in edge + if (lfIt3 != ff.end()) + { + ff.erase( lfIt3 ); + if ( ff.empty() ) + linkFacesMap.erase( lfIt2 ); + } + } + } + badFace->_reverse = true; // reverse + //INFOS_MED( "REVERSE " << *badFace ); + faceQueue.push( badFace ); + } + } + linkFacesMap.erase( lfIt ); + } + // add good neighbors to the queue + Link revLink( link.second, link.first ); + lfIt = linkFacesMap.find( revLink ); + if ( lfIt != linkFacesMap.end() ) + { + std::list<const Cell*> & fList = lfIt->second; + std::list<const Cell*>::iterator fIt = fList.begin(); + for ( ; fIt != fList.end(); fIt++, nbFaceByLink++ ) + { + ml.push_back( *fIt ); + if ( *fIt != face ) + faceQueue.push( *fIt ); + } + linkFacesMap.erase( lfIt ); + } + if ( nbFaceByLink > 2 ) + { + if ( manifold ) + { + std::list<const Cell*>::iterator ii = ml.begin(); + std::cout << nbFaceByLink << " faces by 1 link:" << std::endl; + for( ; ii!= ml.end(); ii++ ) + std::cout << "in sub-mesh <" << fgm[ *ii ]->_name << "> " << **ii << std::endl; + } + manifold = false; + } + } // loop on links of the being checked face + } // loop on the face queue + } // while ( !linkFacesMap.empty() ) + + if ( !manifold ) + std::cout << " -> Non manifold mesh, faces orientation may be incorrect" << std::endl; +} + +//================================================================================ +/*! + * \brief Orient volumes according to MED conventions: + * normal of a bottom (first) face should be outside + */ +//================================================================================ + +void IntermediateMED::orientVolumes() +{ + std::set<Cell>::const_iterator elemIt, elemEnd; + std::vector< std::pair<int,int> > swapVec; + + CellsByDimIterator cellsIt( *this, 3 ); + while ( const std::set<Cell > * elems = cellsIt.nextType() ) + { + TCellType cellType = cellsIt.type(); + elemIt = elems->begin(), elemEnd = elems->end(); + int nbBottomNodes = 0; + switch ( cellType ) + { + case NORM_TETRA4: + case NORM_TETRA10: + case NORM_PENTA6: + case NORM_PENTA15: + nbBottomNodes = 3; break; + case NORM_PYRA5: + case NORM_PYRA13: + case NORM_HEXA8: + case NORM_HEXA20: + nbBottomNodes = 4; break; + default: continue; + } + getReverseVector( cellType, swapVec ); + + for ( ; elemIt != elemEnd; elemIt++ ) + { + // find a normal to the bottom face + const double* n[4]; + n[0] = nodeCoords( elemIt->_nodes[0]); // 3 bottom nodes + n[1] = nodeCoords( elemIt->_nodes[1]); + n[2] = nodeCoords( elemIt->_nodes[2]); + n[3] = nodeCoords( elemIt->_nodes[nbBottomNodes]); // a top node + double vec01[3]; // vector n[0]-n[1] + vec01[0] = n[1][0] - n[0][0]; + vec01[1] = n[1][1] - n[0][1]; + vec01[2] = n[1][2] - n[0][2]; + double vec02 [3]; // vector n[0]-n[2] + vec02[0] = n[2][0] - n[0][0]; + vec02[1] = n[2][1] - n[0][1]; + vec02[2] = n[2][2] - n[0][2]; + double normal [3]; // vec01 ^ vec02 + normal[0] = vec01[1] * vec02[2] - vec01[2] * vec02[1]; + normal[1] = vec01[2] * vec02[0] - vec01[0] * vec02[2]; + normal[2] = vec01[0] * vec02[1] - vec01[1] * vec02[0]; + // check if the 102 angle is convex + if ( nbBottomNodes > 3 ) + { + const double* n3 = nodeCoords( elemIt->_nodes[nbBottomNodes-1] );// last bottom node + double vec03 [3]; // vector n[0]-n3 + vec03[0] = n3[0] - n[0][0]; + vec03[1] = n3[1] - n[0][1]; + vec03[2] = n3[2] - n[0][2]; + if ( fabs( normal[0]+normal[1]+normal[2] ) <= std::numeric_limits<double>::max() ) // vec01 || vec02 + { + normal[0] = vec01[1] * vec03[2] - vec01[2] * vec03[1]; // vec01 ^ vec03 + normal[1] = vec01[2] * vec03[0] - vec01[0] * vec03[2]; + normal[2] = vec01[0] * vec03[1] - vec01[1] * vec03[0]; + } + else + { + double vec [3]; // normal ^ vec01 + vec[0] = normal[1] * vec01[2] - normal[2] * vec01[1]; + vec[1] = normal[2] * vec01[0] - normal[0] * vec01[2]; + vec[2] = normal[0] * vec01[1] - normal[1] * vec01[0]; + double dot2 = vec[0]*vec03[0] + vec[1]*vec03[1] + vec[2]*vec03[2]; // vec*vec03 + if ( dot2 < 0 ) // concave -> reverse normal + { + normal[0] *= -1; + normal[1] *= -1; + normal[2] *= -1; + } + } + } + // direction from top to bottom + double tbDir[3]; + tbDir[0] = n[0][0] - n[3][0]; + tbDir[1] = n[0][1] - n[3][1]; + tbDir[2] = n[0][2] - n[3][2]; + + // compare 2 directions: normal and top-bottom + double dot = normal[0]*tbDir[0] + normal[1]*tbDir[1] + normal[2]*tbDir[2]; + if ( dot < 0. ) // need reverse + reverse( *elemIt, swapVec ); + + } // loop on volumes of one geometry + } // loop on 3D geometry types + +} + +//================================================================================ +/*! + * \brief Assign new IDs to nodes by skipping not used nodes and return their number + */ +//================================================================================ + +int NodeContainer::numberNodes() +{ + int id = 1; + for ( size_t i = 0; i < _nodes.size(); ++i ) + for ( size_t j = 0; j < _nodes[i].size(); ++j ) + if ( _nodes[i][j].isUsed() ) + _nodes[i][j]._number = id++; + return id-1; +} + + +//================================================================================ +/*! + * \brief Assign new IDs to elements + */ +//================================================================================ + +void IntermediateMED::numberElements() +{ + std::set<Cell>::const_iterator elemIt, elemEnd; + + // numbering _cells of type NORM_POINT1 by node number + { + const std::set<Cell>& points = _cellsByType[ INTERP_KERNEL::NORM_POINT1 ]; + elemIt = points.begin(), elemEnd = points.end(); + for ( ; elemIt != elemEnd; ++elemIt ) + elemIt->_number = elemIt->_nodes[0]->_number; + } + + // numbering 1D-3D _cells + for ( int dim = 1; dim <= 3; ++dim ) + { + // check if re-numeration is needed (to try to keep elem oreder as in sauve file ) + bool ok = true, renumEntity = false; + CellsByDimIterator cellsIt( *this, dim ); + int prevNbElems = 0; + while ( const std::set<Cell> * typeCells = cellsIt.nextType() ) + { + TID minNumber = std::numeric_limits<TID>::max(), maxNumber = 0; + for ( elemIt = typeCells->begin(), elemEnd = typeCells->end(); elemIt!=elemEnd; ++elemIt) + { + if ( elemIt->_number < minNumber ) minNumber = elemIt->_number; + if ( elemIt->_number > maxNumber ) maxNumber = elemIt->_number; + } + TID typeSize = typeCells->size(); + if ( typeSize != maxNumber - minNumber + 1 ) + ok = false; + if ( prevNbElems != 0 ) { + if ( minNumber == 1 ) + renumEntity = true; + else if ( prevNbElems+1 != (int)minNumber ) + ok = false; + } + prevNbElems += typeSize; + } + + if ( ok && renumEntity ) // each geom type was numerated separately + { + cellsIt.init( dim ); + prevNbElems = cellsIt.nextType()->size(); // no need to renumber the first type + while ( const std::set<Cell> * typeCells = cellsIt.nextType() ) + { + for ( elemIt = typeCells->begin(), elemEnd = typeCells->end(); elemIt!=elemEnd; ++elemIt) + elemIt->_number += prevNbElems; + prevNbElems += typeCells->size(); + } + } + if ( !ok ) + { + int cellID=1; + cellsIt.init( dim ); + while ( const std::set<Cell> * typeCells = cellsIt.nextType() ) + for ( elemIt = typeCells->begin(), elemEnd = typeCells->end(); elemIt!=elemEnd; ++elemIt) + elemIt->_number = cellID++; + } + } +} + +//================================================================================ +/*! + * \brief Creates coord array + */ +//================================================================================ + +ParaMEDMEM::DataArrayDouble * IntermediateMED::getCoords() +{ + DataArrayDouble* coordArray = DataArrayDouble::New(); + coordArray->alloc( _nbNodes, _spaceDim ); + double * coordPrt = coordArray->getPointer(); + for ( int i = 0, nb = _points.size(); i < nb; ++i ) + { + Node* n = getNode( i+1 ); + if ( n->isUsed() ) + { + const double* nCoords = nodeCoords( n ); + std::copy( nCoords, nCoords+_spaceDim, coordPrt ); + coordPrt += _spaceDim; + } + } + return coordArray; +} + +//================================================================================ +/*! + * \brief Sets connectivity of elements to the mesh + * \param mesh - mesh to fill in + * \param coords - coordinates that must be shared by all meshes of different dim + */ +//================================================================================ + +void IntermediateMED::setConnectivity( ParaMEDMEM::MEDFileUMesh* mesh, + ParaMEDMEM::DataArrayDouble* coords ) +{ + int meshDim = 0; + + mesh->setCoords( coords ); + + std::set<Cell>::const_iterator elemIt, elemEnd; + for ( int dim = 3; dim > 0; --dim ) + { + CellsByDimIterator dimCells( *this, dim ); + + int nbOfCells = 0; + while ( const std::set<Cell > * cells = dimCells.nextType() ) + nbOfCells += cells->size(); + if ( nbOfCells == 0 ) + continue; + + if ( !meshDim ) meshDim = dim; + + MEDCouplingUMesh* dimMesh = MEDCouplingUMesh::New(); + dimMesh->setCoords( coords ); + dimMesh->setMeshDimension( dim ); + dimMesh->allocateCells( nbOfCells ); + + int prevNbCells = 0; + dimCells.init( dim ); + while ( const std::set<Cell > * cells = dimCells.nextType() ) + { + // fill connectivity array to take into account order of elements in the sauv file + const int nbCellNodes = cells->begin()->_nodes.size(); + std::vector< TID > connectivity( cells->size() * nbCellNodes ); + int * nodalConnOfCell; + for ( elemIt = cells->begin(), elemEnd = cells->end(); elemIt != elemEnd; ++elemIt ) + { + const Cell& cell = *elemIt; + const int index = cell._number - 1 - prevNbCells; + nodalConnOfCell = &connectivity[ index * nbCellNodes ]; + if ( cell._reverse ) + for ( int i = nbCellNodes-1; i >= 0; --i ) + *nodalConnOfCell++ = cell._nodes[i]->_number - 1; + else + for ( int i = 0; i < nbCellNodes; ++i ) + *nodalConnOfCell++ = cell._nodes[i]->_number - 1; + } + prevNbCells += cells->size(); + + // fill dimMesh + TCellType cellType = dimCells.type(); + nodalConnOfCell = &connectivity[0]; + for ( size_t i = 0; i < cells->size(); ++i, nodalConnOfCell += nbCellNodes ) + dimMesh->insertNextCell( cellType, nbCellNodes, nodalConnOfCell ); + } + dimMesh->finishInsertingCells(); + mesh->setMeshAtLevel( dim - meshDim, dimMesh ); + dimMesh->decrRef(); + } +} + +//================================================================================ +/*! + * \brief Fill in the mesh with groups + * \param mesh - mesh to fill in + */ +//================================================================================ + +void IntermediateMED::setGroups( ParaMEDMEM::MEDFileUMesh* mesh ) +{ + bool isMeshNameSet = false; + const int meshDim = mesh->getMeshDimension(); + for ( int dim = 0; dim <= meshDim; ++dim ) + { + const int meshDimRelToMaxExt = ( dim == 0 ? 1 : dim - meshDim ); + + std::vector<const DataArrayInt *> medGroups; + std::vector<MEDCouplingAutoRefCountObjectPtr<DataArrayInt> > refGroups; + for ( size_t i = 0; i < _groups.size(); ++i ) + { + Group& grp = _groups[i]; + if ( (int)getDim( &grp ) != dim && + grp._groups.empty() ) // to allow groups on diff dims + continue; + // convert only named groups or field supports + if ( grp.empty() || (grp._name.empty() && !grp._isProfile )) + continue; + //if ( grp._medGroup ) continue; // already converted + + // sort cells by ID and remember their initial order in the group + TCellToOrderMap cell2order; + unsigned orderInGroup = 0; + std::vector< Group* > groupVec; + if ( grp._groups.empty() ) groupVec.push_back( & grp ); + else groupVec = grp._groups; + for ( size_t iG = 0; iG < groupVec.size(); ++iG ) + { + Group* aG = groupVec[ iG ]; + if ( (int)getDim( aG ) != dim ) + continue; + for ( size_t iC = 0; iC < aG->_cells.size(); ++iC ) + cell2order.insert( cell2order.end(), std::make_pair( aG->_cells[iC], orderInGroup++ )); + } + if ( cell2order.empty() ) + continue; + bool isSelfIntersect = ( orderInGroup != cell2order.size() ); + if ( isSelfIntersect ) // self intersecting group + { + std::ostringstream msg; + msg << "Self intersecting sub-mesh: id = " << i+1 + << ", name = |" << grp._name << "|" << std::endl + << " nb unique elements = " << cell2order.size() << std::endl + << " total nb elements = " << orderInGroup; + if ( grp._isProfile ) + { + THROW_IK_EXCEPTION( msg.str() ); + } + else + { + std::cout << msg.str() << std::endl; + } + } + // create a med group + grp._medGroup = DataArrayInt::New(); + grp._medGroup->setName( grp._name.c_str() ); + grp._medGroup->alloc( cell2order.size(), /*nbOfCompo=*/1 ); + int * idsPtr = grp._medGroup->getPointer(); + TCellToOrderMap::iterator cell2orderIt, cell2orderEnd = cell2order.end(); + for ( cell2orderIt = cell2order.begin(); cell2orderIt != cell2orderEnd; ++cell2orderIt ) + *idsPtr++ = (*cell2orderIt).first->_number - 1; + + // try to set the mesh name + if ( !isMeshNameSet && + dim == meshDim && + !grp._name.empty() && + grp.size() == mesh->getSizeAtLevel( meshDimRelToMaxExt )) + { + mesh->setName( grp._name.c_str() ); + isMeshNameSet = true; + } + if ( !grp._name.empty() ) + { + medGroups.push_back( grp._medGroup ); + } + // set relocation table + setRelocationTable( &grp, cell2order ); + + // Issue 0021311. Use case: a gibi group has references (recorded in pile 1) + // and several names (pile 27) refer (pile 10) to this group. + // We create a copy of this group per each named reference + std::set<std::string> uniqueNames; + uniqueNames.insert( grp._name ); + for ( unsigned iRef = 0 ; iRef < grp._refNames.size(); ++iRef ) + if ( !grp._refNames[ iRef ].empty() && + uniqueNames.insert( grp._refNames[ iRef ]).second ) // for name uniqueness (23155) + { + refGroups.push_back( grp._medGroup->deepCpy() ); + refGroups.back()->setName( grp._refNames[ iRef ].c_str() ); + medGroups.push_back( refGroups.back() ); + } + } + mesh->setGroupsAtLevel( meshDimRelToMaxExt, medGroups ); + } +} + +//================================================================================ +/*! + * \brief Return true if the group is on all elements and return its relative dimension + */ +//================================================================================ + +bool IntermediateMED::isOnAll( const Group* grp, int & dimRel ) const +{ + int dim = getDim( grp ); + + int nbElems = 0; + if ( dim == 0 ) + { + nbElems = _nbNodes; + dimRel = 0; + } + else + { + CellsByDimIterator dimCells( *this, dim ); + while ( const std::set<Cell > * cells = dimCells.nextType() ) + nbElems += cells->size(); + + int meshDim = 3; + for ( ; meshDim > 0; --meshDim ) + { + dimCells.init( meshDim ); + if ( dimCells.nextType() ) + break; + } + dimRel = dim - meshDim; + } + + bool onAll = ( nbElems == grp->size() ); + return onAll; +} + +//================================================================================ +/*! + * \brief Makes fields from own data + */ +//================================================================================ + +ParaMEDMEM::MEDFileFields * IntermediateMED::makeMEDFileFields(ParaMEDMEM::MEDFileUMesh* mesh) +{ + if ( _nodeFields.empty() && _cellFields.empty() ) return 0; + + // set long names + std::set< std::string > usedFieldNames; + setFieldLongNames(usedFieldNames); + + MEDFileFields* fields = MEDFileFields::New(); + + for ( size_t i = 0; i < _nodeFields.size(); ++i ) + setFields( _nodeFields[i], fields, mesh, i+1, usedFieldNames ); + + for ( size_t i = 0; i < _cellFields.size(); ++i ) + setFields( _cellFields[i], fields, mesh, i+1, usedFieldNames ); + + return fields; +} + +//================================================================================ +/*! + * \brief Make med fields from a SauvUtilities::DoubleField + */ +//================================================================================ + +void IntermediateMED::setFields( SauvUtilities::DoubleField* fld, + ParaMEDMEM::MEDFileFields* medFields, + ParaMEDMEM::MEDFileUMesh* mesh, + const TID castemID, + std::set< std::string >& usedFieldNames) +{ + bool sameNbGauss = true; + if ( !fld || !fld->isMedCompatible( sameNbGauss )) return; + + if ( !sameNbGauss ) + fld->splitSubWithDiffNbGauss(); + + // if ( !fld->hasCommonSupport() ): + // each sub makes MEDFileFieldMultiTS + // else: + // unite several subs into a MEDCouplingFieldDouble + + const bool uniteSubs = fld->hasCommonSupport() && sameNbGauss; + if ( !uniteSubs ) + std::cout << "Castem field #" << castemID << " <" << fld->_name + << "> is incompatible with MED format, so we split it into several fields:" << std::endl; + + for ( size_t iSub = 0; iSub < fld->_sub.size(); ) + { + // set field name + if ( !uniteSubs || fld->_name.empty() ) + makeFieldNewName( usedFieldNames, fld ); + + // allocate values + DataArrayDouble * values = DataArrayDouble::New(); + values->alloc( fld->getNbTuples(iSub), fld->_sub[iSub].nbComponents() ); + + // set values + double * valPtr = values->getPointer(); + if ( uniteSubs ) + { + int nbElems = fld->_group->size(); + for ( int elemShift = 0; elemShift < nbElems && iSub < fld->_sub.size(); ) + elemShift += fld->setValues( valPtr, iSub++, elemShift ); + setTS( fld, values, medFields, mesh ); + } + else + { + fld->setValues( valPtr, iSub ); + setTS( fld, values, medFields, mesh, iSub++ ); + + std::cout << fld->_name << " with compoments"; + for ( size_t i = 0; i < (size_t)fld->_sub[iSub-1].nbComponents(); ++i ) + std::cout << " " << fld->_sub[iSub-1]._comp_names[ i ]; + std::cout << std::endl; + } + } +} + +//================================================================================ +/*! + * \brief Store value array of a field into med fields + */ +//================================================================================ + +void IntermediateMED::setTS( SauvUtilities::DoubleField* fld, + ParaMEDMEM::DataArrayDouble* values, + ParaMEDMEM::MEDFileFields* medFields, + ParaMEDMEM::MEDFileUMesh* mesh, + const int iSub) +{ + // treat a field support + const Group* support = fld->getSupport( iSub ); + int dimRel; + const bool onAll = isOnAll( support, dimRel ); + if ( !onAll && support->_name.empty() ) + { + const_cast<Group*>(support)->_name += "PFL_" + fld->_name; + support->_medGroup->setName( support->_name.c_str() ); + } + + // make and fill a time-stamp + + MEDCouplingFieldDouble * timeStamp = MEDCouplingFieldDouble::New( fld->getMedType( iSub ), + fld->getMedTimeDisc() ); + timeStamp->setName( fld->_name.c_str() ); + timeStamp->setDescription( fld->_description.c_str() ); + // set the mesh + if ( onAll ) + { + MEDCouplingAutoRefCountObjectPtr + < MEDCouplingUMesh > dimMesh = mesh->getMeshAtLevel( dimRel ); + timeStamp->setMesh( dimMesh ); + } + else if ( timeStamp->getTypeOfField() == ParaMEDMEM::ON_NODES ) + { + DataArrayDouble * coo = mesh->getCoords(); + MEDCouplingAutoRefCountObjectPtr + <DataArrayDouble> subCoo = coo->selectByTupleId(support->_medGroup->begin(), + support->_medGroup->end()); + MEDCouplingAutoRefCountObjectPtr< MEDCouplingUMesh > nodeSubMesh = + MEDCouplingUMesh::Build0DMeshFromCoords( subCoo ); + timeStamp->setMesh( nodeSubMesh ); + } + else + { + MEDCouplingAutoRefCountObjectPtr + < MEDCouplingUMesh > dimMesh = mesh->getMeshAtLevel( dimRel ); + MEDCouplingAutoRefCountObjectPtr + <MEDCouplingMesh> subMesh = dimMesh->buildPart(support->_medGroup->begin(), + support->_medGroup->end()); + timeStamp->setMesh( subMesh); + } + // set values + for ( size_t i = 0; i < (size_t)fld->_sub[iSub].nbComponents(); ++i ) + values->setInfoOnComponent( i, fld->_sub[iSub]._comp_names[ i ].c_str() ); + timeStamp->setArray( values ); + values->decrRef(); + // set gauss points + if ( timeStamp->getTypeOfField() == ParaMEDMEM::ON_GAUSS_PT ) + { + TGaussDef gaussDef( fld->_sub[iSub]._support->_cellType, + fld->_sub[iSub].nbGauss() ); + timeStamp->setGaussLocalizationOnType( fld->_sub[iSub]._support->_cellType, + gaussDef.myRefCoords, + gaussDef.myCoords, + gaussDef.myWeights ); + } + // get a field to add the time-stamp + bool isNewMedField = false; + if ( !fld->_curMedField || fld->_name != fld->_curMedField->getName() ) + { + fld->_curMedField = MEDFileFieldMultiTS::New(); + isNewMedField = true; + } + + // set an order + const int nbTS = fld->_curMedField->getNumberOfTS(); + if ( nbTS > 0 ) + timeStamp->setOrder( nbTS ); + + // add the time-stamp + timeStamp->checkCoherency(); + if ( onAll ) + fld->_curMedField->appendFieldNoProfileSBT( timeStamp ); + else + fld->_curMedField->appendFieldProfile( timeStamp, mesh, dimRel, support->_medGroup ); + timeStamp->decrRef(); + + if ( isNewMedField ) // timeStamp must be added before this + { + medFields->pushField( fld->_curMedField ); + } +} + +//================================================================================ +/*! + * \brief Make a new unique name for a field + */ +//================================================================================ + +void IntermediateMED::makeFieldNewName(std::set< std::string >& usedNames, + SauvUtilities::DoubleField* fld ) +{ + std::string base = fld->_name; + if ( base.empty() ) + { + base = "F_"; + } + else + { + std::string::size_type pos = base.rfind('_'); + if ( pos != std::string::npos ) + base = base.substr( 0, pos+1 ); + else + base += '_'; + } + + int i = 1; + do + { + fld->_name = base + SauvUtilities::toString( i++ ); + } + while( !usedNames.insert( fld->_name ).second ); +} + +//================================================================================ +/*! + * \brief Split sub-components with different nb of gauss points into several sub-components + * \param [in,out] fld - a field to split if necessary + */ +//================================================================================ + +void DoubleField::splitSubWithDiffNbGauss() +{ + for ( size_t iSub = 0; iSub < _sub.size(); ++iSub ) + { + if ( _sub[iSub].isSameNbGauss() ) continue; + + _sub.insert( _sub.begin() + iSub + 1, 1, _Sub_data() ); + _Sub_data & subToSplit = _sub[iSub]; + _Sub_data & subNew = _sub[iSub+1]; + size_t iDiff = 1; + while ( subToSplit._nb_gauss[ 0 ] == subToSplit._nb_gauss[ iDiff ] ) + ++iDiff; + subNew._support = subToSplit._support; + subNew._comp_names.assign( subToSplit._comp_names.begin() + iDiff, + subToSplit._comp_names.end() ); + subNew._nb_gauss.assign ( subToSplit._nb_gauss.begin() + iDiff, + subToSplit._nb_gauss.end() ); + subToSplit._comp_names.resize( iDiff ); + subToSplit._nb_gauss.resize ( iDiff ); + } +} + +//================================================================================ +/*! + * \brief Return a vector ready to fill in + */ +//================================================================================ + +std::vector< double >& DoubleField::addComponent( int nb_values ) +{ + _comp_values.push_back( std::vector< double >() ); + std::vector< double >& res = _comp_values.back(); + res.resize( nb_values ); + return res; +} + +DoubleField::~DoubleField() +{ + if(_curMedField) + _curMedField->decrRef(); +} + +//================================================================================ +/*! + * \brief Returns a supporting group + */ +//================================================================================ + +const Group* DoubleField::getSupport( const int iSub ) const +{ + return _group ? _group : _sub[iSub]._support; +} + +//================================================================================ +/*! + * \brief Return true if each sub-component is a time stamp + */ +//================================================================================ + +bool DoubleField::isMultiTimeStamps() const +{ + if ( _sub.size() < 2 ) + return false; + bool sameSupports = true; + Group* grpp1 = _sub[0]._support;// grpp NOT grp because XDR under Windows defines grp... + for ( size_t i = 1; i < _sub.size() && sameSupports; ++i ) + sameSupports = ( grpp1 == _sub[i]._support ); + + return sameSupports; +} + +//================================================================================ +/*! + * \brief True if the field can be converted into the med field + */ +//================================================================================ + +bool DoubleField::isMedCompatible(bool& sameNbGauss) const +{ + for ( size_t iSub = 0; iSub < _sub.size(); ++iSub ) + { + if ( !getSupport(iSub) || !getSupport(iSub)->_medGroup ) + THROW_IK_EXCEPTION("SauvReader INTERNAL ERROR: NULL field support"); + + sameNbGauss = true; + if ( !_sub[iSub].isSameNbGauss() ) + { + std::cout << "Field <" << _name << "> : different nb of gauss points in components" << std::endl; + sameNbGauss = false; + //return false; + } + } + return true; +} + +//================================================================================ +/*! + * \brief return true if all sub-components has same components and same nbGauss + */ +//================================================================================ + +bool DoubleField::hasSameComponentsBySupport() const +{ + std::vector< _Sub_data >::const_iterator sub_data = _sub.begin(); + const _Sub_data& first_sub_data = *sub_data; + for ( ++sub_data ; sub_data != _sub.end(); ++sub_data ) + { + if ( first_sub_data._comp_names != sub_data->_comp_names ) + return false; // diff names of components + + if ( first_sub_data._nb_gauss != sub_data->_nb_gauss && + first_sub_data._support->_cellType == sub_data->_support->_cellType) + return false; // diff nb of gauss points on same cell type + } + return true; +} + +//================================================================================ +/*! + * \brief Return type of MEDCouplingFieldDouble + */ +//================================================================================ + +ParaMEDMEM::TypeOfField DoubleField::getMedType( const int iSub ) const +{ + using namespace INTERP_KERNEL; + + const Group* grp = hasCommonSupport() ? _group : _sub[iSub]._support; + if ( _sub[iSub].nbGauss() > 1 ) + { + const CellModel& cm = CellModel::GetCellModel( _sub[iSub]._support->_cellType ); + return (int) cm.getNumberOfNodes() == _sub[iSub].nbGauss() ? ON_GAUSS_NE : ON_GAUSS_PT; + } + else + { + return getDim( grp ) == 0 ? ON_NODES : ON_CELLS; + } +} + +//================================================================================ +/*! + * \brief Return TypeOfTimeDiscretization + */ +//================================================================================ + +ParaMEDMEM::TypeOfTimeDiscretization DoubleField::getMedTimeDisc() const +{ + return ONE_TIME; + // NO_TIME = 4, + // ONE_TIME = 5, + // LINEAR_TIME = 6, + // CONST_ON_TIME_INTERVAL = 7 +} + +//================================================================================ +/*! + * \brief Return nb tuples to be used to allocate DataArrayDouble + */ +//================================================================================ + +int DoubleField::getNbTuples( const int iSub ) const +{ + int nb = 0; + if ( hasCommonSupport() && !_group->_groups.empty() ) + for ( size_t i = 0; i < _group->_groups.size(); ++i ) + nb += _sub[i].nbGauss() * _sub[i]._support->size(); + else + nb = _sub[iSub].nbGauss() * getSupport(iSub)->size(); + return nb; +} + +//================================================================================ +/*! + * \brief Store values of a sub-component and return nb of elements in the iSub + */ +//================================================================================ + +int DoubleField::setValues( double * valPtr, const int iSub, const int elemShift ) const +{ + // find values for iSub + int iComp = 0; + for ( int iS = 0; iS < iSub; ++iS ) + iComp += _sub[iS].nbComponents(); + const std::vector< double > * compValues = &_comp_values[ iComp ]; + + // Set values + + const std::vector< unsigned >& relocTable = getSupport( iSub )->_relocTable; + + const int nbElems = _sub[iSub]._support->size(); + const int nbGauss = _sub[iSub].nbGauss(); + const int nbComponents = _sub[iSub].nbComponents(); + const int nbValsByElem = nbComponents * nbGauss; + + // check nb values + int nbVals = 0; + for ( iComp = 0; iComp < nbComponents; ++iComp ) + nbVals += compValues[iComp].size(); + const bool isConstField = ( nbVals == nbComponents ); // one value per component (issue 22321) + if ( !isConstField && nbVals != nbElems * nbValsByElem ) + THROW_IK_EXCEPTION("SauvMedConvertor.cxx: support size mismatches field size"); + + // compute nb values in previous subs + int valsShift = 0; + for ( int iS = iSub-1, shift = elemShift; shift > 0; --iS) + { + int nbE = _sub[iS]._support->size(); + shift -= nbE; + valsShift += nbE * _sub[iS].nbComponents() * _sub[iS].nbGauss(); + } + + if ( isConstField ) + for ( int iE = 0; iE < nbElems; ++iE ) + { + int iMed = valsShift + nbValsByElem * ( relocTable.empty() ? iE : relocTable[iE+elemShift]-elemShift ); + for ( iComp = 0; iComp < nbComponents; ++iComp ) + valPtr[ iMed + iComp ] = compValues[iComp][ 0 ]; + } + else + for ( int iE = 0; iE < nbElems; ++iE ) + { + int iMed = valsShift + nbValsByElem * ( relocTable.empty() ? iE : relocTable[iE+elemShift]-elemShift ); + for ( iComp = 0; iComp < nbComponents; ++iComp ) + for ( int iG = 0; iG < nbGauss; ++iG ) + valPtr[ iMed + iG * nbComponents + iComp ] = compValues[iComp][ iE * nbGauss + iG ]; + } + return nbElems; +} + +//================================================================================ +/*! + * \brief Destructor of IntermediateMED + */ +//================================================================================ + +IntermediateMED::~IntermediateMED() +{ + for ( size_t i = 0; i < _nodeFields.size(); ++i ) + if ( _nodeFields[i] ) + delete _nodeFields[i]; + _nodeFields.clear(); + + for ( size_t i = 0; i < _cellFields.size(); ++i ) + if ( _cellFields[i] ) + delete _cellFields[i]; + _cellFields.clear(); + + for ( size_t i = 0; i < _groups.size(); ++i ) + if ( _groups[i]._medGroup ) + _groups[i]._medGroup->decrRef(); +} + +//================================================================================ +/*! + * \brief CellsByDimIterator constructor + */ +CellsByDimIterator::CellsByDimIterator( const IntermediateMED & medi, int dimm) +{ + myImed = & medi; + init( dimm ); +} +/*! + * \brief Initialize iteration on cells of given dimention + */ +void CellsByDimIterator::init(const int dimm) +{ + myCurType = -1; + myTypeEnd = INTERP_KERNEL::NORM_HEXA20 + 1; + myDim = dimm; +} +/*! + * \brief return next set of Cell's of required dimension + */ +const std::set< Cell > * CellsByDimIterator::nextType() +{ + while ( ++myCurType < myTypeEnd ) + if ( !myImed->_cellsByType[myCurType].empty() && ( myDim < 0 || dim(false) == myDim )) + return & myImed->_cellsByType[myCurType]; + return 0; +} +/*! + * \brief return dimension of cells returned by the last or further next() + */ +int CellsByDimIterator::dim(const bool last) const +{ + int typp = myCurType; + if ( !last ) + while ( typp < myTypeEnd && myImed->_cellsByType[typp].empty() ) + ++typp; + return typp < myTypeEnd ? getDimension( TCellType( typp )) : 4; +} +// END CellsByDimIterator ======================================================== + diff --git a/src/medtool/src/MEDLoader/SauvMedConvertor.hxx b/src/medtool/src/MEDLoader/SauvMedConvertor.hxx new file mode 100644 index 000000000..b52cacd0f --- /dev/null +++ b/src/medtool/src/MEDLoader/SauvMedConvertor.hxx @@ -0,0 +1,388 @@ +// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 +// 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 +// +// File : SauvMedConvertor.hxx +// Created : Tue Aug 16 14:14:02 2011 +// Author : Edward AGAPOV (eap) +// + +#ifndef __SauvMedConvertor_HXX__ +#define __SauvMedConvertor_HXX__ + +#include "InterpKernelException.hxx" +#include "NormalizedUnstructuredMesh.hxx" +#include "MEDCouplingRefCountObject.hxx" +#include "SauvUtilities.hxx" + +#include <vector> +#include <set> +#include <map> +#include <list> +#include <algorithm> + +namespace ParaMEDMEM +{ + class DataArrayDouble; + class DataArrayInt; + class MEDFileData; + class MEDFileFields; + class MEDFileFieldMultiTS; + class MEDFileUMesh; +} + +namespace SauvUtilities +{ + struct IntermediateMED; + + // ============================================================================== + typedef int TID; // an ID countered from 1 + typedef std::pair<TID,TID> Link; // a pair of node numbers + + typedef INTERP_KERNEL::NormalizedCellType TCellType; + + // ============================================================================== + struct Node + { + TID _number; + size_t _coordID; + + Node():_number(0){} + bool isUsed() const { return _number != 0; } + }; + + // ============================================================================== + struct Cell + { + std::vector< Node* > _nodes; + mutable bool _reverse; // to reverse orienation of a face only + mutable TID* _sortedNodeIDs; // for comparison + mutable TID _number; + + Cell(size_t nnNodes=0) : _nodes(nnNodes),_reverse(false),_sortedNodeIDs(0),_number(0) {} + Cell(const Cell& ma); + void init() const { if ( _sortedNodeIDs ) delete [] _sortedNodeIDs; _sortedNodeIDs = 0; } + ~Cell() { init(); } + + const TID* getSortedNodes() const; // creates if needed and return _sortedNodeIDs + bool operator < (const Cell& ma) const; + Link link(int i) const; + + private: + Cell& operator=(const Cell& ma); + }; + std::ostream& operator << (std::ostream& os, const Cell& ma); + + // ============================================================================== + struct Group + { + TCellType _cellType; + std::string _name; + std::vector<const Cell*> _cells; + std::vector< Group* > _groups; // des sous-groupes composant le Group + bool _isProfile; // is a field support or not + std::vector<std::string> _refNames; /* names of groups referring this one; + _refNames is resized according to nb of references + while reading a group (pile 1) and it is filled with + names while reading long names (pile 27); each named + reference is converted into a copy of the medGroup + (issue 0021311) + */ + ParaMEDMEM::DataArrayInt* _medGroup; // result of conversion + std::vector< unsigned > _relocTable; // for _cells[i] gives its index in _medGroup + + bool empty() const { return _cells.empty() && _groups.empty(); } + int size() const; + Group():_cellType(INTERP_KERNEL::NORM_ERROR), _isProfile(false), _medGroup(NULL) {} + }; + + // ============================================================================== + struct DoubleField + { + // a field contains several subcomponents each referring to its own support and + // having several named components + // ---------------------------------------------------------------------------- + struct _Sub_data // a subcomponent + // -------------------------------- + { + Group* _support; // support + std::vector<std::string> _comp_names; // component names + std::vector<int> _nb_gauss; // nb values per element in a component + + void setData( int nb_comp, Group* supp ) + { _support = supp; _comp_names.resize(nb_comp); _nb_gauss.resize(nb_comp,1); } + int nbComponents() const { return _comp_names.size(); } + std::string & compName( int i_comp ) { return _comp_names[ i_comp ]; } + bool isSameNbGauss() const { return *std::max_element( _nb_gauss.begin(), _nb_gauss.end() ) == + *std::min_element( _nb_gauss.begin(), _nb_gauss.end() ); } + int nbGauss() const { return _nb_gauss[0] ? _nb_gauss[0] : 1; } + bool hasGauss() const { return nbGauss() > 1; } + }; + // ---------------------------------------------------------------------------- + TID _idInFile; + std::string _name; + std::string _description; // field description + std::vector< _Sub_data > _sub; + Group* _group; /* if _group == NULL then each subcomponent makes a + separate med field, else all subcomponents + are converted into timestamps of one med field. + The latter is possible only if nb of components in all subs + is the same and supports of subcomponents do not overlap + */ + std::vector< std::vector< double > > _comp_values; + ParaMEDMEM::MEDFileFieldMultiTS* _curMedField; + + DoubleField( int nb_sub, int total_nb_comp ) + : _sub(nb_sub), _group(NULL), _curMedField(NULL) { _comp_values.reserve( total_nb_comp ); } + ~DoubleField(); + std::vector< double >& addComponent( int nb_values ); // return a vector ready to fill in + bool hasCommonSupport() const { return _group; } // true if there is one support for all subs + bool hasSameComponentsBySupport() const; + + bool isMultiTimeStamps() const; + bool isMedCompatible(bool& sameNbGauss) const; + ParaMEDMEM::TypeOfField getMedType( const int iSub=0 ) const; + ParaMEDMEM::TypeOfTimeDiscretization getMedTimeDisc() const; + int getNbTuples( const int iSub=0 ) const; + int getNbValuesPerElement( const int iSub=0 ) const; + int getNbGauss( const int iSub=0 ) const; + const Group* getSupport( const int iSub=0 ) const; + int setValues( double * valPtr, const int iSub, const int elemShift=0 ) const; + void splitSubWithDiffNbGauss(); + + //virtual void dump(std::ostream&) const; + //virtual ~DoubleField() {} + }; + // ============================================================================== + /*! + * \if developper + * Iterator on set of Cell's of given dimension + * \endif + */ + class CellsByDimIterator + { + public: + CellsByDimIterator( const IntermediateMED & medi, int dim=-1); // dim=-1 - for all dimensions + void init(const int dim=-1); + + //!< return next set of Cell's of required dimension + const std::set<Cell > * nextType(); + //!< return dimension of Cell's returned by the last or further next() + int dim(const bool last=true) const; + //!< return type of Cell's returned by the last next() + TCellType type() const { return TCellType( myCurType ); } + + private: + const IntermediateMED* myImed; + int myCurType, myTypeEnd; + int myDim; + }; + + // ============================================================================== + /*! + * \if developper + * Container of Node's. Prevents re-allocation at addition of Node's + * \endif + */ + class NodeContainer + { + std::vector< std::vector< Node > > _nodes; + public: + Node* getNode( const TID nID ) + { + const size_t chunkSize = 1000; + const size_t chunkID = (nID-1) / chunkSize; + const size_t pos = (nID-1) % chunkSize; + if ( _nodes.size() < chunkID+1 ) + { + std::vector< std::vector< Node > > newNodes(chunkID+1); + for ( size_t i = 0; i < _nodes.size(); ++i ) + newNodes[i].swap( _nodes[i] ); + for ( size_t i = _nodes.size(); i < newNodes.size(); ++i ) + newNodes[i].resize( chunkSize ); + _nodes.swap( newNodes ); + } + return & _nodes[chunkID][pos]; + } + bool empty() const { return _nodes.empty(); } + size_t size() const { return empty() ? 0 : _nodes.size() * _nodes[0].size(); } + int numberNodes(); + }; + + // ============================================================================== + /*! + * \if developper + * Intermediate structure used to store data read from the Sauve format file. + * The structure provides functions that transform the stored data to the MED format + * + * The elements inserted in maillage are ordered in order to avoid duplicated elements. + * \endif + */ + struct IntermediateMED + { + unsigned _spaceDim; + unsigned _nbNodes; + NodeContainer _points; + std::vector<double> _coords; + std::vector<Group> _groups; + std::vector<DoubleField* > _nodeFields; + std::vector<DoubleField* > _cellFields; + + // IMP 0020434: mapping GIBI names to MED names + std::list<nameGIBItoMED> _listGIBItoMED_mail; // to read from table "MED_MAIL" of PILE_TABLES + std::list<nameGIBItoMED> _listGIBItoMED_cham; // to read from table "MED_CHAM" of PILE_TABLES + std::list<nameGIBItoMED> _listGIBItoMED_comp; // to read from table "MED_COMP" of PILE_TABLES + std::map<int,std::string> _mapStrings; // to read from PILE_STRINGS + + IntermediateMED(): _spaceDim(0), _nbNodes(0) {} + ~IntermediateMED(); + + Node* getNode( TID nID ) { return _points.getNode( nID ); } + int getNbCellsOfType( TCellType type ) const { return _cellsByType[type].size(); } + const Cell* insert(TCellType type, const Cell& ma) { return &( *_cellsByType[type].insert( ma ).first ); } + Group* addNewGroup(std::vector<SauvUtilities::Group*>* groupsToFix=0); + ParaMEDMEM::MEDFileData* convertInMEDFileDS(); + + private: + + ParaMEDMEM::MEDFileUMesh* makeMEDFileMesh(); + ParaMEDMEM::DataArrayDouble * getCoords(); + void setConnectivity( ParaMEDMEM::MEDFileUMesh* mesh, ParaMEDMEM::DataArrayDouble* coords ); + void setGroups( ParaMEDMEM::MEDFileUMesh* mesh ); + ParaMEDMEM::MEDFileFields * makeMEDFileFields(ParaMEDMEM::MEDFileUMesh* mesh); + void setFields( SauvUtilities::DoubleField* fld, + ParaMEDMEM::MEDFileFields* medFields, + ParaMEDMEM::MEDFileUMesh* mesh, + const TID castemID, + std::set< std::string >& usedNames); + void setTS( SauvUtilities::DoubleField* fld, + ParaMEDMEM::DataArrayDouble* values, + ParaMEDMEM::MEDFileFields* medFields, + ParaMEDMEM::MEDFileUMesh* mesh, + const int iSub=0); + void checkDataAvailability() const; + void setGroupLongNames(); + void setFieldLongNames(std::set< std::string >& usedNames); + void makeFieldNewName(std::set< std::string >& usedNames, + SauvUtilities::DoubleField* fld ); + void decreaseHierarchicalDepthOfSubgroups(); + void eraseUselessGroups(); + void detectMixDimGroups(); + void orientElements2D(); + void orientElements3D(); + void orientFaces3D(); + void orientVolumes(); + void numberElements(); + bool isOnAll( const Group* grp, int & dimRel ) const; + const double* nodeCoords( const Node* n ) { return &_coords[ (n->_coordID-1) * _spaceDim ]; } + + // IntermediateMED() + // { myNodesNumerated = myMaillesNumerated = myGroupsTreated = false; currentTypeMailles = 0; } + // ~IntermediateMED(); + + //bool myNodesNumerated, myMaillesNumerated; + + // mailles groupped by geom type; use insert() for filling in and + // _CellsByDimIterator for exploring it + //std::set<_Cell> maillage; + std::set< Cell > _cellsByType[ INTERP_KERNEL::NORM_HEXA20 + 1 ]; + friend class CellsByDimIterator; + }; + +// ============================================================================== + /*! + * \brief ASCII sauve file reader + */ + class ASCIIReader : public FileReader + { + public: + ASCIIReader(const char* fileName); + virtual ~ASCIIReader(); + virtual bool isASCII() const; + virtual bool open(); + virtual bool getNextLine (char* & line, bool raiseOEF = true ); + virtual void initNameReading(int nbValues, int width = 8); + virtual void initIntReading(int nbValues); + virtual void initDoubleReading(int nbValues); + virtual bool more() const; + virtual void next(); + virtual int getInt() const; + virtual float getFloat() const; + virtual double getDouble() const; + virtual std::string getName() const; + int lineNb() const { return _lineNb; } + + private: + + bool getLine(char* & line); + void init( int nbToRead, int nbPosInLine, int width, int shift = 0 ); + + // getting a line from the file + int _file; + char* _start; // working buffer beginning + char* _ptr; + char* _eptr; + int _lineNb; + + // line parsing + int _iPos, _nbPosInLine, _width, _shift; + char* _curPos; + }; +// ============================================================================== + /*! + * \brief XDR (binary) sauve file reader + */ + class XDRReader : public FileReader + { + public: + XDRReader(const char* fileName); + virtual ~XDRReader(); + virtual bool isASCII() const; + virtual bool open(); + virtual bool getNextLine (char* & line, bool raiseOEF = true ); + virtual void initNameReading(int nbValues, int width = 8); + virtual void initIntReading(int nbValues); + virtual void initDoubleReading(int nbValues); + virtual bool more() const; + virtual void next(); + virtual int getInt() const; + virtual float getFloat() const; + virtual double getDouble() const; + virtual std::string getName() const; + + private: + + void init( int nbToRead, int width = 0 ); + + FILE* _xdrs_file; + void* _xdrs; + int* _xdr_ivals; + double* _xdr_dvals; + char* _xdr_cvals; + int _width; + int _xdr_kind; + enum + { + _xdr_kind_null, + _xdr_kind_char, + _xdr_kind_int, + _xdr_kind_double + }; + }; +} + +#endif diff --git a/src/medtool/src/MEDLoader/SauvReader.cxx b/src/medtool/src/MEDLoader/SauvReader.cxx new file mode 100644 index 000000000..77c7c4f21 --- /dev/null +++ b/src/medtool/src/MEDLoader/SauvReader.cxx @@ -0,0 +1,1216 @@ +// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 +// 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 +// +// File : SauvReader.cxx +// Created : Tue Aug 16 13:57:42 2011 +// Author : Edward AGAPOV (eap) +// + +#include "SauvReader.hxx" + +#include "SauvMedConvertor.hxx" +#include "MEDCouplingAutoRefCountObjectPtr.hxx" +#include "NormalizedUnstructuredMesh.hxx" +#include "MEDCouplingRefCountObject.hxx" + +#include <cstring> +#include <sstream> +#include <iostream> + +using namespace ParaMEDMEM; +using namespace SauvUtilities; +using namespace std; + +#define GIBI_EQUAL(var_str, stat_str) (strncmp (var_str, stat_str, strlen(stat_str)) == 0) + +//================================================================================ +/*! + * \brief Creates a reader of a given sauve file + */ +//================================================================================ + +SauvReader* SauvReader::New(const std::string& fileName) +{ + if ( fileName.empty() ) THROW_IK_EXCEPTION("Invalid file name"); + + ParaMEDMEM::MEDCouplingAutoRefCountObjectPtr< SauvUtilities::FileReader> parser; + + // try to open as XRD + parser = new XDRReader( fileName.c_str() ); + if ( parser->open() ) + { + SauvReader* reader = new SauvReader; + reader->_fileReader = parser.retn(); + return reader; + } + + // try to open as ASCII + parser = new ASCIIReader( fileName.c_str() ); + if ( parser->open() ) + { + SauvReader* reader = new SauvReader; + reader->_fileReader = parser.retn(); + return reader; + } + + THROW_IK_EXCEPTION("Unable to open file |"<< fileName << "|"); +} +//================================================================================ +/*! + * \brief Destructor + */ +//================================================================================ + +SauvReader::~SauvReader() +{ + _fileReader->decrRef(); +} + +std::size_t SauvReader::getHeapMemorySizeWithoutChildren() const +{ + return 0; +} + +std::vector<const BigMemoryObject *> SauvReader::getDirectChildrenWithNull() const +{ + return std::vector<const BigMemoryObject *>(); +} + +//================================================================================ +/*! + * \brief Return current line of ASCII file to report an error + */ +//================================================================================ + +std::string SauvReader::lineNb() const +{ + if ( isASCII() ) + return string(" (line #") + SauvUtilities::toString + ( static_cast<SauvUtilities::ASCIIReader*>( _fileReader )->lineNb() ) + ")"; + + return ""; +} + +//================================================================================ +/*! + * \brief Reads contents of the sauve file and convert it to MEDFileData + */ +//================================================================================ + +ParaMEDMEM::MEDFileData * SauvReader::loadInMEDFileDS() +{ + SauvUtilities::IntermediateMED iMed; // intermadiate DS + _iMed = &iMed; + + char* line; // a current line + const char* enregistrement_type=" ENREGISTREMENT DE TYPE"; + + while ( getNextLine(line, /*raiseOEF=*/false)) // external loop looking for "ENREGISTREMENT DE TYPE" + { + if ( isASCII() && !GIBI_EQUAL( line, enregistrement_type )) + continue; // "ENREGISTREMENT DE TYPE" not found -> read the next line + + // read the number of a record + int recordNumber; + if ( isASCII() ) + recordNumber = atoi( line + strlen(enregistrement_type) + 1 ); + else + recordNumber = getInt(); + + // read the record + if ( recordNumber == 2 ) + readRecord2(); + else if (recordNumber == 4 ) + readRecord4(); + else if (recordNumber == 7 ) + readRecord7(); + else if (recordNumber == 5 ) + break; // stop reading + else + if ( !isASCII() ) + THROW_IK_EXCEPTION("XDR : ENREGISTREMENT DE TYPE " << recordNumber << " not implemented!!!"); + } + + ParaMEDMEM::MEDFileData* medFileData = iMed.convertInMEDFileDS(); + + return medFileData; +} + +//================================================================================ +/*! + * \brief Reads "ENREGISTREMENT DE TYPE 4" + */ +//================================================================================ + +void SauvReader::readRecord4() +{ + if ( !isASCII() ) + { + getInt(); // skip NIVEAU + getInt(); // skip ERREUR + _iMed->_spaceDim = getInt(); + getFloat(); // skip DENSITE + } + else + { + char* line; + getNextLine(line); + const char* s = " NIVEAU 15 NIVEAU ERREUR 0 DIMENSION"; + _iMed->_spaceDim = atoi( line + strlen( s ) + 1 ); + if ( !GIBI_EQUAL( line, " NIVEAU" )) + THROW_IK_EXCEPTION( "Could not read space dimension" << lineNb() ); + } + if ( _iMed->_spaceDim < 1 ) + THROW_IK_EXCEPTION( "Invalid space dimension:" << _iMed->_spaceDim ); +} + +//================================================================================ +/*! + * \brief Reads "ENREGISTREMENT DE TYPE 7" + */ +//================================================================================ + +void SauvReader::readRecord7() +{ + if ( !isASCII() ) + { + getInt(); // skip NOMBRE INFO CASTEM2000 + getInt(); // skip IFOUR + getInt(); // skip NIFOUR + getInt(); // skip IFOMOD + getInt(); // skip IECHO + getInt(); // skip IIMPI + getInt(); // skip IOSPI + getInt(); // skip ISOTYP + getInt(); // skip NSDPGE + } + else + { + // skip 3 lines: + // NOMBRE INFO CASTEM2000 8 + // IFOUR 2 NIFOUR 0 IFOMOD 2 IECHO 1 IIMPI 0 IOSPI 0 ISOTYP 1 + // NSDPGE 0 + char* line; + getNextLine(line); + getNextLine(line); + getNextLine(line); + } +} + +//================================================================================ +/*! + * \brief Reads the pile number, nb of objects and nb named of objects + */ +//================================================================================ + +int SauvReader::readPileNumber(int& nbNamedObjects, int& nbObjects) +{ + // FORMAT(' PILE NUMERO',I4,'NBRE ObjectS NOMMES',I8,'NBRE ObjectS',I8) + int pileNumber; + if ( !isASCII() ) + { + initIntReading(3); + pileNumber = getInt(); next(); + nbNamedObjects = getInt(); next(); + nbObjects = getInt(); next(); + } + else + { + char* line; + getNextLine(line); + const char *s1 = " PILE NUMERO", *s2 = "NBRE ObjectS NOMMES", *s3 = "NBRE ObjectS"; + if ( ! GIBI_EQUAL( line, s1 ) ) + THROW_IK_EXCEPTION("Could not read the pile number " << lineNb() ); + line = line + strlen(s1); + pileNumber = atoi( line ); + line = line + 4 + strlen(s2); + nbNamedObjects = atoi( line ); + line = line + 8 + strlen(s3); + nbObjects = atoi( line ); + } + if ( nbNamedObjects<0 ) + THROW_IK_EXCEPTION("Invalid nb of named objects: " << nbNamedObjects << lineNb() ); + if ( nbObjects<0) + THROW_IK_EXCEPTION("Invalid nb of objects: " << nbObjects << lineNb() ); + // It appears to be a valid case + // if ( nbObjects<nbNamedObjects) + // THROW_IK_EXCEPTION("In PILE " << pileNumber << + // " nb of objects is less than nb of named objects" << lineNb() ); + return pileNumber; +} + +//================================================================================ +/*! + * \brief Reads "ENREGISTREMENT DE TYPE 2" + */ +//================================================================================ + +void SauvReader::readRecord2() +{ + if ( _iMed->_spaceDim == 0 ) + THROW_IK_EXCEPTION("Missing ENREGISTREMENT DE TYPE 4"); + + // read a pile number + int pileNumber, nbNamedObjects, nbObjects; + pileNumber = readPileNumber(nbNamedObjects, nbObjects); + + if ( !_encounteredPiles.insert( pileNumber ).second && // piles may repeat + isASCII()) + return; + + // read object names and their indices + vector<string> objectNames(nbNamedObjects); + for ( initNameReading( nbNamedObjects ); more(); next() ) + objectNames[ index() ] = getName(); + + vector<int> nameIndices(nbNamedObjects); + for ( initIntReading( nbNamedObjects ); more(); next() ) + nameIndices[ index() ] = getInt(); + + switch ( pileNumber ) + { + case PILE_SOUS_MAILLAGE: + read_PILE_SOUS_MAILLAGE(nbObjects, objectNames, nameIndices); + break; + case PILE_NODES_FIELD: + read_PILE_NODES_FIELD(nbObjects, objectNames, nameIndices); + break; + case PILE_TABLES: + read_PILE_TABLES(nbObjects, objectNames, nameIndices); + break; + case PILE_LREEL: + read_PILE_LREEL(nbObjects, objectNames, nameIndices); + break; + case PILE_LOGIQUES: + read_PILE_LOGIQUES(nbObjects, objectNames, nameIndices); + break; + case PILE_FLOATS: + read_PILE_FLOATS(nbObjects, objectNames, nameIndices); + break; + case PILE_INTEGERS: + read_PILE_INTEGERS(nbObjects, objectNames, nameIndices); + break; + case PILE_STRINGS: + read_PILE_STRINGS(nbObjects, objectNames, nameIndices); + break; + case PILE_LMOTS: + read_PILE_LMOTS(nbObjects, objectNames, nameIndices); + break; + case PILE_NOEUDS: + read_PILE_NOEUDS(nbObjects, objectNames, nameIndices); + break; + case PILE_COORDONNEES: + read_PILE_COORDONNEES(nbObjects, objectNames, nameIndices); + break; + case PILE_MODL: + read_PILE_MODL(nbObjects, objectNames, nameIndices); + break; + case PILE_FIELD: + read_PILE_FIELD(nbObjects, objectNames, nameIndices); + break; + default: + if ( !isASCII() ) + THROW_IK_EXCEPTION("XDR : reading PILE " << pileNumber << " not implemented !!!"); + } +} + +//================================================================================ +/*! + * \brief Reads "PILE NUMERO 1": gibi sub-meshes that are converted into med groups + */ +//================================================================================ + +void SauvReader::read_PILE_SOUS_MAILLAGE(const int nbObjects, + std::vector<std::string>& objectNames, + std::vector<int>& nameIndices) +{ + _iMed->_groups.reserve(nbObjects*2); // fields may add some groups + + char* line; + map<int,int> strangeGroupType; + int i; + + for (int object=0; object!=nbObjects; ++object) // loop on sub-groups + { + initIntReading( 5 ); + int castemCellType = getIntNext(); + int nbSubGroups = getIntNext(); + int nbReferences = getIntNext(); + int nbNodesPerElem = getIntNext(); + int nbElements = getIntNext(); + + _iMed->_groups.push_back(Group()); + SauvUtilities::Group & group = _iMed->_groups.back(); + + // Issue 0021311. Allocate places for names of referring groups + // that will be possibly filled after reading long names from + // PILE_TABLES and PILE_STRINGS + group._refNames.resize( nbReferences ); + + // castemCellType=0 corresponds to a sub-mesh composed of other sub-meshes + if (castemCellType==0 && nbSubGroups>0) + { + group._groups.resize( nbSubGroups ); + for ( initIntReading( nbSubGroups ); more(); next() ) + group._groups[ index() ] = & _iMed->_groups[ getInt() - 1 ]; + //std::sort( group._groups.begin(), group._groups.end() ); // for _groups comparison in getFieldSupport() + } + // skip references + if ( isASCII() ) + for ( i = 0; i < nbReferences; i += 10 ) // FORMAT(10I8) + getNextLine(line); + else + for (initIntReading(nbReferences); more(); next()); + + // skip colors + if ( isASCII() ) + for ( i = 0; i < nbElements; i += 10 ) + getNextLine(line); + else + for (initIntReading(nbElements); more(); next()); + + // not a composite group + if (castemCellType>0 && nbSubGroups==0) + { + group._cellType = SauvUtilities::gibi2medGeom(castemCellType); + + initIntReading( nbElements * nbNodesPerElem ); + if ( group._cellType == INTERP_KERNEL::NORM_ERROR ) // look for group end + { + for ( ; more(); next()); + strangeGroupType.insert( make_pair( object, castemCellType )); + } + else + { + // if ( group._cellType == MED_POINT1 ) group._cellType = NORM_ERROR; // issue 21199 + + // read connectivity of elements of a group + SauvUtilities::Cell ma( nbNodesPerElem ); + SauvUtilities::Node* pNode; + group._cells.resize( nbElements ); + for ( i = 0; i < nbElements; ++i ) + { + ma.init(); + for ( int n = 0; n < nbNodesPerElem; ++n ) + { + int nodeID = getIntNext(); + pNode = _iMed->getNode( nodeID ); + ma._nodes[n] = pNode; + _iMed->_nbNodes += ( !pNode->isUsed() ); + pNode->_number = nodeID; + } + ma._number = _iMed->getNbCellsOfType( group._cellType ) + 1; + group._cells[i] = _iMed->insert( group._cellType, ma ); + } + } + } + } // loop on groups + + // set group names + for (i=0; i!=(int)objectNames.size(); ++i) + { + int grpID = nameIndices[i]; + SauvUtilities::Group & grp = _iMed->_groups[ grpID-1 ]; + if ( !grp._name.empty() ) // a group has several names + { // create a group with subgroup grp and named grp.name + SauvUtilities::Group* newGroup = _iMed->addNewGroup(); + newGroup->_groups.push_back( &_iMed->_groups[ grpID-1 ]); + newGroup->_name = grp._name; + } + grp._name=objectNames[i]; +#ifdef _DEBUG + map<int,int>::iterator it = strangeGroupType.find( grpID - 1 ); + if ( it != strangeGroupType.end() ) + cout << "Skip " << grp._name << " of not supported CASTEM type: " << it->second << endl; +#endif + } +} // read_PILE_SOUS_MAILLAGE() + +//================================================================================ +/*! + * \brief Skip "PILE NUMERO 18" of XDR file + */ +//================================================================================ + +void SauvReader::read_PILE_LREEL (const int nbObjects, std::vector<std::string>&, std::vector<int>&) +{ + if ( isXRD() ) + { + for (int object=0; object!=nbObjects; ++object) // pour chaque Group + { + initIntReading(1); + int nb_vals = getIntNext(); + initDoubleReading(nb_vals); + for(int i=0; i<nb_vals; i++) next(); + } + } +} + +//================================================================================ +/*! + * \brief Skip "PILE NUMERO 24" of XDR file + */ +//================================================================================ + +void SauvReader::read_PILE_LOGIQUES (const int, std::vector<std::string>&, std::vector<int>&) +{ + if ( isXRD() ) + { + initIntReading(1); + int nb_vals = getIntNext(); + initIntReading(nb_vals); + for(int i=0; i<nb_vals; i++) next(); + } +} + +//================================================================================ +/*! + * \brief Skip "PILE NUMERO 25" of XDR file + */ +//================================================================================ + +void SauvReader::read_PILE_FLOATS (const int, std::vector<std::string>&, std::vector<int>&) +{ + if ( isXRD() ) + { + initIntReading(1); + int nb_vals = getIntNext(); + initDoubleReading(nb_vals); + for(int i=0; i<nb_vals; i++) next(); + } +} + +//================================================================================ +/*! + * \brief Skip "PILE NUMERO 26" of XDR file + */ +//================================================================================ + +void SauvReader::read_PILE_INTEGERS (const int, std::vector<std::string>&, std::vector<int>&) +{ + if ( isXRD() ) + { + initIntReading(1); + int nb_vals = getIntNext(); + initIntReading(nb_vals); + for(int i=0; i<nb_vals; i++) next(); + } +} + +//================================================================================ +/*! + * \brief Skip "PILE NUMERO 29" of XDR file + */ +//================================================================================ + +void SauvReader::read_PILE_LMOTS (const int nbObjects, std::vector<std::string>&, std::vector<int>&) +{ + if ( isXRD() ) + { + for (int object=0; object!=nbObjects; ++object) // pour chaque Group + { + initIntReading(2); + int len = getIntNext(); + int nb_vals = getIntNext(); + int nb_char = len*nb_vals; + int nb_char_tmp = 0; + int fixed_length = 71; + while (nb_char_tmp < nb_char) + { + int remain_len = nb_char - nb_char_tmp; + int width; + if ( remain_len > fixed_length ) + { + width = fixed_length; + } + else + { + width = remain_len; + } + initNameReading(1, width); + next(); + nb_char_tmp += width; + } + } + } +} + +//================================================================================ +/*! + * \brief Skip "PILE NUMERO 38" of XDR file + */ +//================================================================================ + +void SauvReader::read_PILE_MODL (const int nbObjects, std::vector<std::string>&, std::vector<int>&) +{ + if ( isXRD() ) + { + for (int object=0; object!=nbObjects; ++object) // pour chaque Group + { + // see wrmodl.eso + initIntReading(10); + int n1 = getIntNext(); + int nm2 = getIntNext(); + int nm3 = getIntNext(); + int nm4 = getIntNext(); + int nm5 = getIntNext(); + int n45 = getIntNext(); + /*int nm6 =*/ getIntNext(); + /*int nm7 =*/ getIntNext(); + next(); + next(); + int nm1 = n1 * n45; + int nm9 = n1 * 16; + for (initIntReading(nm1); more(); next()); + for (initIntReading(nm9); more(); next()); + for (initNameReading(nm5, 8); more(); next()); + for (initNameReading(nm2, 8); more(); next()); + for (initNameReading(nm3, 8); more(); next()); + for (initIntReading(nm4); more(); next()); + } + } +} // Fin case pile 38 + +//================================================================================ +/*! + * \brief Read "PILE NUMERO 32": links to node coordinates + */ +//================================================================================ + +void SauvReader::read_PILE_NOEUDS (const int nbObjects, std::vector<std::string>&, std::vector<int>&) +{ + initIntReading(1); + int nb_indices = getIntNext(); + + if (nb_indices != nbObjects) + THROW_IK_EXCEPTION("Error of reading PILE NUMERO " << PILE_NOEUDS << lineNb() ); + + for ( initIntReading( nbObjects ); more(); next() ) + { + int coordID = getInt(); + _iMed->getNode( index()+1 )->_coordID = coordID; + } +} + +//================================================================================ +/*! + * \brief Read "PILE NUMERO 33": node coordinates + */ +//================================================================================ + +void SauvReader::read_PILE_COORDONNEES (const int nbObjects, std::vector<std::string>&, std::vector<int>&) +{ + initIntReading(1); + int nbReals = getIntNext(); + + if ( nbReals < (int)(_iMed->_nbNodes*(_iMed->_spaceDim+1)) ) + THROW_IK_EXCEPTION("Error of reading PILE NUMERO " << PILE_COORDONNEES << lineNb() ); + + // there are coordinates + density for each node + _iMed->_coords.resize( nbReals - nbReals/(_iMed->_spaceDim+1)); + double* coordPtr = &_iMed->_coords[0]; + + initDoubleReading( nbReals ); + while ( more() ) + { + for (unsigned j = 0; j < _iMed->_spaceDim; ++j, next()) + *coordPtr++ = getDouble(); + // skip density + getDouble(); + next(); + } +} + +//================================================================================ +/*! + * \brief Find or create a Group equal to a given field support + */ +//================================================================================ + +void SauvReader::setFieldSupport(const vector<SauvUtilities::Group*>& supports, + SauvUtilities::DoubleField* field) +{ + SauvUtilities::Group* group = NULL; + set<SauvUtilities::Group*> sup_set( supports.begin(), supports.end() ); + if ( sup_set.size() == 1 ) // one or equal supports + { + group = supports[0]; + } + else + { + // check if sub-components are on cells of different types + map<int,int> nbGaussByCellType; + for ( size_t i = 0; i < supports.size(); ++i ) + { + map<int,int>::iterator ct2ng = nbGaussByCellType.find( supports[i]->_cellType ); + if ( ct2ng == nbGaussByCellType.end() ) + nbGaussByCellType[ supports[i]->_cellType ] = field->_sub[i].nbGauss(); + else if ( ct2ng->second != field->_sub[i].nbGauss() ) + return; + } + bool isSameCellType = ( nbGaussByCellType.size() == 1 ); + // try to find an existing composite group with the same sub-groups + if ( isSameCellType ) + for ( size_t i = 0; i < _iMed->_groups.size() && !group; ++i ) + { + Group & grp = _iMed->_groups[i]; + if (sup_set.size() == grp._groups.size()) + { + bool sameOrder = true; + for ( size_t j = 0; j < supports.size() && sameOrder; ++j ) + sameOrder = ( supports[j] == grp._groups[ j % grp._groups.size() ]); + if ( sameOrder ) + group = & _iMed->_groups[i]; + } + } + if ( !group ) // no such a group, add a new one + { + vector<SauvUtilities::Group*> newGroups( supports.begin(), + supports.begin() + sup_set.size() ); + // check if supports includes newGroups in the same order + bool sameOrder = true; + for ( size_t j = newGroups.size(); j < supports.size() && sameOrder; ++j ) + sameOrder = ( supports[j] == newGroups[ j % newGroups.size() ]); + if ( sameOrder ) + { + group = _iMed->addNewGroup( & newGroups ); + group->_groups.swap( newGroups ); + } + } + // sort field sub-components and supports by cell type + if ( group && !isSameCellType ) + { + // sort groups + vector<SauvUtilities::Group*>& groups = group->_groups; + bool isModified = false, isSwapped = true; + while ( isSwapped ) + { + isSwapped = false; + for ( size_t i = 1; i < groups.size(); ++i ) + { + int nbN1 = groups[i-1]->empty() ? 0 : groups[i-1]->_cells[0]->_nodes.size(); + int nbN2 = groups[i ]->empty() ? 0 : groups[i ]->_cells[0]->_nodes.size(); + if ( nbN1 > nbN2 ) + { + isSwapped = isModified = true; + std::swap( groups[i], groups[i-1] ); + } + } + } + // relocate sub-components according to a new order of groups + if ( isModified ) + { + vector< DoubleField::_Sub_data > newSub ( field->_sub.size() ); + vector< vector< double > > newValues( field->_comp_values.size() ); + size_t iFromSub = 0, iNewSub = 0, iNewComp = 0; + for ( ; iFromSub < field->_sub.size(); iFromSub += groups.size() ) + { + size_t iFromComp = iNewComp; + for ( size_t iG = 0; iG < groups.size(); ++iG ) + { + size_t iComp = iFromComp; + for ( size_t iSub = iFromSub; iSub < field->_sub.size(); ++iSub ) + if ( field->_sub[ iSub ]._support == groups[ iG ] ) + { + newSub[ iNewSub++ ] = field->_sub[ iSub ]; + int iC = 0, nbC = field->_sub[ iSub ].nbComponents(); + for ( ; iC < nbC; ++iC ) + newValues[ iNewComp++ ].swap( field->_comp_values[ iComp++ ]); + break; + } + else + { + iComp += field->_sub[ iSub ].nbComponents(); + } + } + } + field->_sub.swap( newSub ); + field->_comp_values.swap( newValues ); + } + } + } + if ( group ) + group->_isProfile = true; + + field->_group = group; +} + +//================================================================================ +/*! + * \brief Set field names + */ +//================================================================================ + +void SauvReader::setFieldNames(const vector<SauvUtilities::DoubleField* >& fields, + const vector<string>& objets_nommes, + const vector<int>& indices_objets_nommes) +{ + unsigned i; + for ( i = 0; i < indices_objets_nommes.size(); ++i ) + { + int fieldIndex = indices_objets_nommes[ i ]; + if ( fields[ fieldIndex - 1 ] ) + fields[ fieldIndex - 1 ]->_name = objets_nommes[ i ]; + } +} + +//================================================================================ +/*! + * \brief Read "PILE NUMERO 2": NODE FIELDS + */ +//================================================================================ + +void SauvReader::read_PILE_NODES_FIELD (const int nbObjects, + std::vector<std::string>& objectNames, + std::vector<int>& nameIndices) +{ + _iMed->_nodeFields.resize( nbObjects, (SauvUtilities::DoubleField*) 0 ); + for (int object=0; object!=nbObjects; ++object) // loop on fields + { + // EXAMPLE ( with no values ) + + // (1) 4 7 2 1 + // (2) -88 0 3 -89 0 1 -90 0 2 -91 + // (2) 0 1 + // (3) FX FY FZ FZ FX FY FLX + // (4) 0 0 0 0 0 0 0 + // (5) cree par muc pri + // (6) + // (7) 2 + + // (1): nb subcomponents, nb components(total), IFOUR, nb attributes + int nb_sub, total_nb_comp, nb_attr; + int i_sub, i_comp; + initIntReading( 4 ); + nb_sub = getIntNext(); + total_nb_comp = getIntNext(); + next(); // ignore IFOUR + nb_attr = getIntNext(); + if ( nb_sub < 0 || total_nb_comp < 0 || nb_attr < 0 ) + THROW_IK_EXCEPTION("Error of field reading " << lineNb()); + + // (2) loop on subcomponents of a field, for each read + // (a) support, (b) number of values and (c) number of components + vector<Group*> supports( nb_sub ); + vector<int> nb_values ( nb_sub ); + vector<int> nb_comps ( nb_sub ); + int total_nb_values = 0; + initIntReading( nb_sub * 3 ); + for ( i_sub = 0; i_sub < nb_sub; ++i_sub ) + { + int supId = -getIntNext(); // (a) reference to support + if ( supId < 1 || supId > (int)_iMed->_groups.size() ) + THROW_IK_EXCEPTION("Wrong mesh reference: "<< supId << lineNb() ); + supports[ i_sub ] = &_iMed->_groups[ supId-1 ]; // (a) reference to support + + nb_values[ i_sub ] = getIntNext(); // (b) nb points + total_nb_values += nb_values[ i_sub ]; + if ( nb_values[ i_sub ] < 0 ) + THROW_IK_EXCEPTION(" Wrong nb of points: " << nb_values[ i_sub ] << lineNb() ); + nb_comps[ i_sub ] = getInt(); next(); // (c) nb of components in i_sub + } + + // create a field if there are values + SauvUtilities::DoubleField* fdouble = 0; + if ( total_nb_values > 0 ) + fdouble = new DoubleField( nb_sub, total_nb_comp ); + _iMed->_nodeFields[ object ] = fdouble; + + // (3) component names + initNameReading( total_nb_comp, 4 ); + for ( i_sub = 0; i_sub < nb_sub; ++i_sub ) + { + // store support id and nb components of a sub + if ( fdouble ) + fdouble->_sub[ i_sub ].setData( nb_comps[ i_sub ], supports[ i_sub ] ); + for ( i_comp = 0; i_comp < nb_comps[ i_sub ]; ++i_comp, next() ) + { + // store component name + string compName = getName(); + if ( fdouble ) + fdouble->_sub[ i_sub ].compName( i_comp ) = compName; + } + } + // (4) nb harmonics ( ignored ) + for ( initIntReading( total_nb_comp ); more(); next() ); + // (5) TYPE ( ignored ) + for (initNameReading(1, /*length=*/71); more(); next()); + // (6) TITRE ( ignored ) + for (initNameReading(1, /*length=*/71); more(); next()); + // (7) attributes ( ignored ) + for ( initIntReading( nb_attr ); more(); next() ); + + for ( i_sub = 0; i_sub < nb_sub; ++i_sub ) + { + // loop on components: read values + initDoubleReading( nb_values[ i_sub ] * nb_comps[ i_sub ] ); + for ( i_comp = 0; i_comp < nb_comps[ i_sub ]; ++i_comp ) + { + if ( fdouble ) + { + vector<double>& vals = fdouble->addComponent( nb_values[ i_sub ] ); + for ( int i = 0; more() && i < nb_values[ i_sub ]; next(), ++i ) + vals[ i ] = getDouble(); + } + else + { + for ( int i = 0; i < nb_values[ i_sub ]; next(), ++i ); + } + } + } // loop on subcomponents of a field + + // set a supporting group including all subs supports but only + // if all subs have the same components + if ( fdouble && fdouble->hasSameComponentsBySupport() ) + setFieldSupport( supports, fdouble ); + else + for ( i_sub = 0; i_sub < nb_sub; ++i_sub ) + fdouble->_sub[ i_sub ]._support->_isProfile = true; + + } // end loop on field objects + + // set field names + setFieldNames( _iMed->_nodeFields, objectNames, nameIndices ); + +} // read_PILE_NODES_FIELD() + +//================================================================================ +/*! + * \brief Read "PILE NUMERO 39": FIELDS + */ +//================================================================================ + +void SauvReader::read_PILE_FIELD (const int nbObjects, + std::vector<std::string>& objectNames, + std::vector<int>& nameIndices) +{ + // REAL EXAMPLE + + // (1) 1 2 6 16 + // (2) CARACTERISTIQUES + // (3) -15 317773 4 0 0 0 -2 0 3 + // (4) 317581 + // (5) 0 + // (6) 317767 317761 317755 317815 + // (7) YOUN NU H SIGY + // (8) REAL*8 REAL*8 REAL*8 REAL*8 + // (9) 1 1 0 0 + // (10) 2.00000000000000E+05 + // (11) 1 1 0 0 + // (12) 3.30000000000000E-01 + // (13) 1 1 0 0 + // (14) 1.00000000000000E+04 + // (15) 6 706 0 0 + // (16) 1.00000000000000E+02 1.00000000000000E+02 1.00000000000000E+02 + // (17) 1.00000000000000E+02 1.00000000000000E+02 1.00000000000000E+02 + // (18) ... + + _iMed->_cellFields.resize( nbObjects, (SauvUtilities::DoubleField*) 0 ); + for (int object=0; object!=nbObjects; ++object) // pour chaque field + { + initIntReading( 4 ); + int i_sub, nb_sub = getIntNext(); // (1) <nb_sub> 2 6 <title length> + next(); // skip "2" + next(); // skip "6" + int title_length = getIntNext(); // <title length> + if ( nb_sub < 1 ) + THROW_IK_EXCEPTION("Error of field reading: wrong nb of subcomponents " << nb_sub << lineNb() ); + + string description; + if ( title_length ) + { + if ( isXRD() ) + { + initNameReading(1, title_length); + description = getName(); + next(); + } + else + { + char* line; + getNextLine( line ); // (2) title + const int len = 72; // line length + description = string(line + len - title_length, title_length); // title is right justified + } + } + // look for a line starting with '-' : <reference to support> + if ( isXRD() ) + { + initIntReading( nb_sub * 9 ); + } + else + { + do { + initIntReading( nb_sub * 9 ); + } while ( getInt() >= 0 ); + } + int total_nb_comp = 0; + vector<Group*> supports( nb_sub ); + vector<int> nb_comp( nb_sub ); + for ( i_sub = 0; i_sub < nb_sub; ++i_sub ) + { // (3) + int supportId = -getIntNext(); // <reference to support> + next(); // ignore <address> + nb_comp [ i_sub ] = getIntNext(); // <nb of components in the sub> + for ( int i = 0; i < 6; ++i ) next(); // ignore 6 ints, in example "0 0 0 -2 0 3" + + if ( supportId < 1 || supportId > (int)_iMed->_groups.size() ) + THROW_IK_EXCEPTION("Error of field reading: wrong mesh reference "<< supportId << lineNb() ); + if ( nb_comp[ i_sub ] < 0 ) + THROW_IK_EXCEPTION("Error of field reading: wrong nb of components " <<nb_comp[ i_sub ] << lineNb() ); + + supports[ i_sub ] = &_iMed->_groups[ supportId-1 ]; + total_nb_comp += nb_comp[ i_sub ]; + } + // (4) dummy strings + for ( initNameReading( nb_sub, 17 ); more(); next() ); + // (5) dummy strings + for ( initNameReading( nb_sub ); more(); next() ); + + // loop on subcomponents of a field, each of which refers to + // a certain support and has its own number of components; + // read component values + SauvUtilities::DoubleField* fdouble = 0; + for ( i_sub = 0; i_sub < nb_sub; ++ i_sub ) + { + vector<string> comp_names( nb_comp[ i_sub ]), comp_type( nb_comp[ i_sub ]); + // (6) nb_comp addresses of MELVAL structure + for ( initIntReading( nb_comp[ i_sub ] ); more(); next() ); + // (7) component names + for ( initNameReading( nb_comp[ i_sub ] ); more(); next() ) + comp_names[ index() ] = getName(); + // (8) component type + for ( initNameReading( nb_comp[ i_sub ], 17 ); more(); next() ) // 17 is name width + { + comp_type[ index() ] = getName(); + // component types must be the same + if ( index() > 0 && comp_type[ index() ] != comp_type[ index() - 1] ) + THROW_IK_EXCEPTION( "Error of field reading: diff component types <" + << comp_type[ index() ] << "> != <" << comp_type[ index() - 1 ] + << ">" << lineNb() ); + } + // now type is known, create a field, one for all subs + bool isReal = (nb_comp[i_sub] > 0) ? (comp_type[0] == "REAL*8") : true; + if ( !fdouble && total_nb_comp ) + { + if ( !isReal ) + cout << "Warning: read NOT REAL field, type <" << comp_type[0] << ">" << lineNb() << endl; + _iMed->_cellFields[ object ] = fdouble = new SauvUtilities::DoubleField( nb_sub, total_nb_comp ); + fdouble->_description = description; + } + // store support id and nb components of a sub + if ( fdouble ) + fdouble->_sub[ i_sub ].setData( nb_comp[ i_sub ], supports[ i_sub ]); + // loop on components: read values + for ( int i_comp = 0; i_comp < nb_comp[ i_sub ]; ++i_comp ) + { + // (9) nb of values + initIntReading( 4 ); + int nb_val_by_elem = getIntNext(); + int nb_values = getIntNext(); + next(); + next(); + fdouble->_sub[ i_sub ]._nb_gauss[ i_comp ] = nb_val_by_elem; + + // (10) values + nb_values *= nb_val_by_elem; + if ( fdouble ) + { + vector<double> & vals = fdouble->addComponent( nb_values ); + for ( isReal ? initDoubleReading( nb_values ) : initIntReading( nb_values ); more(); next()) + vals[ index() ] = getDouble(); + // store component name + fdouble->_sub[ i_sub ].compName( i_comp ) = comp_names[ i_comp ]; + } + else + { + for ( isReal ? initDoubleReading( nb_values ) : initIntReading( nb_values ); more(); next() ) ; + } + } + } // loop on subcomponents of a field + + // set id of a group including all sub supports but only + // if all subs have the same nb of components + if ( fdouble && fdouble->hasSameComponentsBySupport() ) + setFieldSupport( supports, fdouble ); + else + for ( i_sub = 0; i_sub < nb_sub; ++i_sub ) + fdouble->_sub[ i_sub ]._support->_isProfile = true; + + } // end loop on field objects + + // set field names + setFieldNames( _iMed->_cellFields, objectNames, nameIndices ); + +} // read_PILE_FIELD() + +//================================================================================ +/*! + * \brief Read "PILE NUMERO 10": TABLES + */ +//================================================================================ + +void SauvReader::read_PILE_TABLES (const int nbObjects, + std::vector<std::string>& objectNames, + std::vector<int>& nameIndices) +{ + // IMP 0020434: mapping GIBI names to MED names + + string table_med_mail = "MED_MAIL"; + string table_med_cham = "MED_CHAM"; + string table_med_comp = "MED_COMP"; + int table_med_mail_id = -1; + int table_med_cham_id = -1; + int table_med_comp_id = -1; + for (size_t iname = 0; iname < objectNames.size(); iname++) + if (objectNames[iname] == table_med_mail) table_med_mail_id = nameIndices[iname]; + else if (objectNames[iname] == table_med_cham) table_med_cham_id = nameIndices[iname]; + else if (objectNames[iname] == table_med_comp) table_med_comp_id = nameIndices[iname]; + + if ( isASCII() ) + if (table_med_mail_id < 0 && table_med_cham_id < 0 && table_med_comp_id < 0) + return; + + for (int itable = 1; itable <= nbObjects; itable++) + { + // read tables "MED_MAIL", "MED_CHAM" and "MED_COMP", that keeps correspondence + // between GIBI names (8 symbols if any) and MED names (possibly longer) + initIntReading(1); + int nb_table_vals = getIntNext(); + if (nb_table_vals < 0) + THROW_IK_EXCEPTION("Error of reading PILE NUMERO 10" << lineNb() ); + + int name_i_med_pile; + initIntReading(nb_table_vals); + for (int i = 0; i < nb_table_vals/4; i++) + { + if (itable == table_med_mail_id || + itable == table_med_cham_id || + itable == table_med_comp_id) + { + nameGIBItoMED name_i; + name_i_med_pile = getIntNext(); + name_i.med_id = getIntNext(); + name_i.gibi_pile = getIntNext(); + name_i.gibi_id = getIntNext(); + + if (name_i_med_pile != PILE_STRINGS) + { + // error: med(long) names are always kept in PILE_STRINGS + } + if (itable == table_med_mail_id) + { + if (name_i.gibi_pile != PILE_SOUS_MAILLAGE) { + // error: must be PILE_SOUS_MAILLAGE + } + _iMed->_listGIBItoMED_mail.push_back(name_i); + } + else if (itable == table_med_cham_id) + { + if (name_i.gibi_pile != PILE_FIELD && + name_i.gibi_pile != PILE_NODES_FIELD) + { + // error: must be PILE_FIELD or PILE_NODES_FIELD + } + _iMed->_listGIBItoMED_cham.push_back(name_i); + } + else if (itable == table_med_comp_id) + { + if (name_i.gibi_pile != PILE_STRINGS) + { + // error: gibi(short) names of components are kept in PILE_STRINGS + } + _iMed->_listGIBItoMED_comp.push_back(name_i); + } + } + else + { + // pass table + for ( int ii = 0; ii < 4; ++ii ) next(); + } + } + } // for (int itable = 0; itable < nbObjects; itable++) +} + +//================================================================================ +/*! + * \brief Read "PILE NUMERO 27" + */ +//================================================================================ + +void SauvReader::read_PILE_STRINGS (const int nbObjects, + std::vector<std::string>& objectNames, + std::vector<int>& nameIndices) +{ + // IMP 0020434: mapping GIBI names to MED names + initIntReading(2); + int stringLen = getIntNext(); + int nbSubStrings = getIntNext(); + if (nbSubStrings != nbObjects) + THROW_IK_EXCEPTION("Error of reading PILE NUMERO 27" << lineNb() ); + + string aWholeString; + if ( isXRD() ) + { + const int fixedLength = 71; + while ((int)aWholeString.length() < stringLen) + { + int remainLen = stringLen - aWholeString.length(); + int len; + if ( remainLen > fixedLength ) + { + len = fixedLength; + } + else + { + len = remainLen; + } + initNameReading(1, len); + aWholeString += getName(); + next(); + } + } + else + { + char* line; + const int fixedLength = 71; + while ((int)aWholeString.length() < stringLen) + { + getNextLine( line ); + int remainLen = stringLen - aWholeString.length(); + if ( remainLen > fixedLength ) + { + aWholeString += line + 1; + } + else + { + aWholeString += line + ( 72 - remainLen ); + } + } + } + int prevOffset = 0; + int currOffset = 0; + initIntReading(nbSubStrings); + for (int istr = 1; istr <= nbSubStrings; istr++, next()) + { + currOffset = getInt(); + // fill mapStrings + _iMed->_mapStrings[istr] = aWholeString.substr(prevOffset, currOffset - prevOffset); + prevOffset = currOffset; + } +} diff --git a/src/medtool/src/MEDLoader/SauvReader.hxx b/src/medtool/src/MEDLoader/SauvReader.hxx new file mode 100644 index 000000000..4be5977b3 --- /dev/null +++ b/src/medtool/src/MEDLoader/SauvReader.hxx @@ -0,0 +1,104 @@ +// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 +// 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 +// +// File : SauvReader.hxx +// Created : Tue Aug 16 13:04:25 2011 +// Author : Edward AGAPOV (eap) +// +#ifndef __SAUVREADER_HXX__ +#define __SAUVREADER_HXX__ + +#include "MEDLoaderDefines.hxx" +#include "InterpKernelException.hxx" +#include "SauvUtilities.hxx" +#include "MEDCouplingRefCountObject.hxx" + +#include <vector> +#include <string> +#include <set> + +namespace SauvUtilities +{ + class FileReader; + struct IntermediateMED; + struct Group; + struct DoubleField; +} +namespace ParaMEDMEM +{ + class MEDFileData; + +class SauvReader : public ParaMEDMEM::RefCountObject +{ + public: + MEDLOADER_EXPORT static SauvReader* New(const std::string& fileName); + MEDLOADER_EXPORT ParaMEDMEM::MEDFileData * loadInMEDFileDS(); + MEDLOADER_EXPORT ~SauvReader(); + + private: + std::size_t getHeapMemorySizeWithoutChildren() const; + std::vector<const BigMemoryObject *> getDirectChildrenWithNull() const; + void readRecord2(); + void readRecord4(); + void readRecord7(); + + int readPileNumber(int& nbNamedObjects, int& nbObjects); + void read_PILE_SOUS_MAILLAGE(const int nbObjects, std::vector<std::string>& objectNames, std::vector<int>& nameIndices); + void read_PILE_NODES_FIELD (const int nbObjects, std::vector<std::string>& objectNames, std::vector<int>& nameIndices); + void read_PILE_TABLES (const int nbObjects, std::vector<std::string>& objectNames, std::vector<int>& nameIndices); + void read_PILE_LREEL (const int nbObjects, std::vector<std::string>& objectNames, std::vector<int>& nameIndices); + void read_PILE_LOGIQUES (const int nbObjects, std::vector<std::string>& objectNames, std::vector<int>& nameIndices); + void read_PILE_FLOATS (const int nbObjects, std::vector<std::string>& objectNames, std::vector<int>& nameIndices); + void read_PILE_INTEGERS (const int nbObjects, std::vector<std::string>& objectNames, std::vector<int>& nameIndices); + void read_PILE_STRINGS (const int nbObjects, std::vector<std::string>& objectNames, std::vector<int>& nameIndices); + void read_PILE_LMOTS (const int nbObjects, std::vector<std::string>& objectNames, std::vector<int>& nameIndices); + void read_PILE_NOEUDS (const int nbObjects, std::vector<std::string>& objectNames, std::vector<int>& nameIndices); + void read_PILE_COORDONNEES (const int nbObjects, std::vector<std::string>& objectNames, std::vector<int>& nameIndices); + void read_PILE_MODL (const int nbObjects, std::vector<std::string>& objectNames, std::vector<int>& nameIndices); + void read_PILE_FIELD (const int nbObjects, std::vector<std::string>& objectNames, std::vector<int>& nameIndices); + + void setFieldSupport(const std::vector<SauvUtilities::Group*>& supports, + SauvUtilities::DoubleField* field); + void setFieldNames(const std::vector<SauvUtilities::DoubleField*>& fields, + const std::vector<std::string>& objectNames, + const std::vector<int>& nameIndices); + + bool isASCII() const { return _fileReader->isASCII(); } + bool isXRD() const { return !isASCII(); } + bool getNextLine (char* & line, bool raiseOEF = true ) { return _fileReader->getNextLine( line, raiseOEF ); } + void initNameReading(int nbValues, int width = 8) { _fileReader->initNameReading( nbValues, width ); } + void initIntReading(int nbValues) { _fileReader->initIntReading( nbValues ); } + void initDoubleReading(int nbValues) { _fileReader->initDoubleReading( nbValues ); } + bool more() const { return _fileReader->more(); } + void next() { _fileReader->next(); } + int index() const { return _fileReader->index(); } + int getInt() const { return _fileReader->getInt(); } + int getIntNext() { int i = getInt(); next(); return i; } + float getFloat() const { return _fileReader->getFloat(); } + double getDouble() const { return _fileReader->getDouble(); } + std::string getName() const { return _fileReader->getName(); } + std::string lineNb() const; + + + std::set<int> _encounteredPiles; + + SauvUtilities::FileReader* _fileReader; + SauvUtilities::IntermediateMED* _iMed; +}; +} +#endif diff --git a/src/medtool/src/MEDLoader/SauvUtilities.hxx b/src/medtool/src/MEDLoader/SauvUtilities.hxx new file mode 100644 index 000000000..3fa32d79e --- /dev/null +++ b/src/medtool/src/MEDLoader/SauvUtilities.hxx @@ -0,0 +1,120 @@ +// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 +// 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 +// +// File : SauvUtilities.hxx +// Created : Mon Aug 22 18:27:34 2011 +// Author : Edward AGAPOV (eap) + +#ifndef __SAUVUTILITIES_HXX__ +#define __SAUVUTILITIES_HXX__ + +#include "MEDLoaderDefines.hxx" +#include "MEDCouplingRefCountObject.hxx" +#include "NormalizedUnstructuredMesh.hxx" + +#include <string> +#include <sstream> + +#define THROW_IK_EXCEPTION(text) \ + { \ + std::ostringstream oss; oss << text; \ + throw INTERP_KERNEL::Exception(oss.str().c_str()); \ + } + +namespace SauvUtilities +{ + INTERP_KERNEL::NormalizedCellType MEDLOADER_EXPORT gibi2medGeom( size_t gibiType ); + int med2gibiGeom( INTERP_KERNEL::NormalizedCellType medGeomType ); + const int * getGibi2MedQuadraticInterlace( INTERP_KERNEL::NormalizedCellType type ); + unsigned getDimension( INTERP_KERNEL::NormalizedCellType type ); + + enum Readable_Piles + { + PILE_SOUS_MAILLAGE=1 , + PILE_NODES_FIELD =2 , + PILE_TABLES =10, + PILE_LREEL =18, + PILE_LOGIQUES =24, + PILE_FLOATS =25, + PILE_INTEGERS =26, + PILE_STRINGS =27, + PILE_LMOTS =29, + PILE_NOEUDS =32, + PILE_COORDONNEES =33, + PILE_MODL =38, + PILE_FIELD =39, + PILE_LAST_READABLE=39 + }; + + //================================================================================ + /*! + * \brief Converts anything to string + */ + //================================================================================ + + template<class T> std::string toString(const T& anything) + { + std::ostringstream s; s << anything; return s.str(); + } + + // ============================================================================== + // IMP 0020434: mapping GIBI names to MED names + struct nameGIBItoMED + { + // GIBI value + int gibi_pile; // PILE_SOUS_MAILLAGE or PILE_FIELD/PILE_NODES_FIELD, or PILE_STRINGS(for components) + int gibi_id; + std::string gibi_name; // used only for components + // MED value + // med_pile = 27; // PILE_STRINGS + int med_id; // used only on reading + std::string med_name; // used only on writing + }; + + // ============================================================================== + /*! + * \brief Base class for ASCII and XDR file readers + */ + class FileReader : public ParaMEDMEM::RefCountObject + { + public: + FileReader(const char* fileName); + virtual ~FileReader() {} + virtual bool isASCII() const = 0; + + virtual bool open() = 0; + virtual bool getNextLine (char* & line, bool raiseOEF = true ) = 0; + virtual void initNameReading(int nbValues, int width = 8) = 0; + virtual void initIntReading(int nbValues) = 0; + virtual void initDoubleReading(int nbValues) = 0; + virtual bool more() const = 0; + virtual void next() = 0; + virtual int index() const { return _iRead; } + virtual int getInt() const = 0; + virtual float getFloat() const = 0; + virtual double getDouble() const = 0; + virtual std::string getName() const = 0; + protected: + std::size_t getHeapMemorySizeWithoutChildren() const { return 0; } + std::vector<const BigMemoryObject *> getDirectChildrenWithNull() const { return std::vector<const BigMemoryObject *>(); } + protected: + std::string _fileName, _curLocale; + int _iRead, _nbToRead; + }; +} +#endif diff --git a/src/medtool/src/MEDLoader/SauvWriter.cxx b/src/medtool/src/MEDLoader/SauvWriter.cxx new file mode 100644 index 000000000..701ab1e95 --- /dev/null +++ b/src/medtool/src/MEDLoader/SauvWriter.cxx @@ -0,0 +1,1378 @@ +// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 +// 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 +// +// File : SauvWriter.cxx +// Created : Wed Aug 24 12:55:55 2011 +// Author : Edward AGAPOV (eap) + +#include "SauvWriter.hxx" + +#include "InterpKernelException.hxx" +#include "MEDFileMesh.hxx" +#include "MEDFileField.hxx" +#include "MEDFileData.hxx" +#include "CellModel.hxx" + +#include <fstream> +#include <sstream> +#include <iostream> +#include <cstdlib> +#include <iomanip> + +using namespace ParaMEDMEM; +using namespace SauvUtilities; +using namespace std; + +#define INFOS_MED(txt) cout << txt << endl; + +namespace +{ + const char* zeroI8 = " 0"; // FORMAT(I8) + + // ============================================================ + // the class writes endl to the file as soon as <limit> fields + // have been written after the last endl + // ============================================================ + + class TFieldCounter + { + fstream& _file; + int _count, _limit; + public: + TFieldCounter(fstream& f, int limit=0): _file(f), _limit(limit) { init(); } + void init(int limit=0) // init, is done by stop() as well + { if (limit) _limit = limit; _count = 0; } + void operator++(int) // next + { if ( ++_count == _limit ) { _file << endl; init(); }} + void stop() // init() and write endl if there was no endl after the last written field + { if ( _count ) _file << endl; init(); } + ~TFieldCounter() { stop(); } + }; + + //================================================================================ + /*! + * \brief Return a name of a field support on all elements + */ + //================================================================================ + + string noProfileName( INTERP_KERNEL::NormalizedCellType type ) + { + return "INTERP_KERNEL::NormalizedCellType_" + SauvUtilities::toString( type ); + } + + //================================================================================ + /*! + * \brief Remove white spaces from the head and tail + */ + //================================================================================ + + string cleanName( const string& theName ) + { + string name = theName; + if ( !name.empty() ) + { + // cut off leading white spaces + string::size_type firstChar = name.find_first_not_of(" \t"); + if (firstChar < name.length()) + { + name = name.substr(firstChar); + } + else + { + name = ""; // only whitespaces there - remove them + } + // cut off trailing white spaces + string::size_type lastChar = name.find_last_not_of(" \t"); + if (lastChar < name.length()) + name = name.substr(0, lastChar + 1); + } + return name; + } + + //================================================================================ + /*! + * \brief Converts MED long names into SAUVE short ones, returnes a healed long name + */ + //================================================================================ + + string addName (map<string,int>& nameMap, + map<string,int>& namePrefixesMap, + const string& theName, + const int index) + { + // Converts names like: + // MED: GIBI: + // TEMPERATURE_FLUIDE -> TEMPE001 + // TEMPERATURE_SOLIDE -> TEMPE002 + // PRESSION -> PRESSION + // NU -> NU + // VOLUM001 -> VOLUM001 + // VOLUMOFOBJECT -> VOLUM003 + // VOLUM002 -> VOLUM002 + string healedName = cleanName(theName); + int ind = index; + + if (!healedName.empty()) + { + string name = healedName; + int len = name.length(); + for (int i = 0; i < len; ++i) + name[i] = toupper(name[i]); + + bool doResave = false; // only for tracing + + // I. Save a short name as it is + if (len <= 8) + { + INFOS_MED("Save <" << theName << "> as <" << name << ">"); + + map<string,int>::iterator it = nameMap.find(name); + if (it != nameMap.end()) + { + // There is already such name in the map. + + // a. Replace in the map the old pair by the current one + int old_ind = nameMap[name]; + nameMap[name] = ind; + // b. Rebuild the old pair (which was in the map, + // it seems to be built automatically by step II) + ind = old_ind; + // continue with step II + doResave = true; // only for tracing + } + else + { + // Save in the map + nameMap.insert(make_pair(name, ind)); + + // Update loc_index for this name (if last free characters represents a number) + // to avoid conflicts with long names, same in first 5 characters + if (len == 8) + { + int new_loc_index = atoi(name.c_str() + 5); + if (new_loc_index > 0) + { + // prefix + string str = name.substr(0,5); + if (namePrefixesMap.find(str) != namePrefixesMap.end()) + { + int old_loc_index = namePrefixesMap[str]; + if (new_loc_index < old_loc_index) new_loc_index = old_loc_index; + } + namePrefixesMap[str] = new_loc_index; + } + } + return healedName; + } + } // if (len <= 8) + + // II. Cut long name and add a numeric suffix + + // first 5 or less characters of the name + if (len > 5) name = name.substr(0,5); + + // numeric suffix + map<string,int>::iterator name2ind = namePrefixesMap.insert( make_pair( name, 0 )).first; + string numSuffix = SauvUtilities::toString( ++(name2ind->second) ); + + if ( numSuffix.size() + name.size() > 8 ) + THROW_IK_EXCEPTION("Can't write not unique name: " << healedName); + + if ( numSuffix.size() < 3 ) + numSuffix.insert( 0, 3 - numSuffix.size(), '0' ); + + name += numSuffix; + nameMap.insert(make_pair(name, ind)); + + if (doResave) + { + INFOS_MED("Resave previous <" << healedName << "> as <" << name << ">"); + } + else + { + INFOS_MED("Save <" << theName << "> as <" << name << ">"); + } + } + return healedName; + } +} + +SauvWriter::SauvWriter():_cpy_grp_if_on_single_family(false) +{ +} + +SauvWriter* SauvWriter::New() +{ + return new SauvWriter; +} + +std::size_t SauvWriter::getHeapMemorySizeWithoutChildren() const +{ + return 0; +} + +std::vector<const BigMemoryObject *> SauvWriter::getDirectChildrenWithNull() const +{ + return std::vector<const BigMemoryObject *>(); +} + +void SauvWriter::setCpyGrpIfOnASingleFamilyStatus(bool status) +{ + _cpy_grp_if_on_single_family=status; +} + +bool SauvWriter::getCpyGrpIfOnASingleFamilyStatus() const +{ + return _cpy_grp_if_on_single_family; +} + +//================================================================================ +/*! + * \brief Fills own DS by MEDFileData + */ +//================================================================================ + +void SauvWriter::setMEDFileDS(const MEDFileData* medData, + unsigned meshIndex) +{ + if ( !medData) THROW_IK_EXCEPTION("NULL MEDFileData"); + + MEDFileMeshes * meshes = medData->getMeshes(); + MEDFileFields * fields = medData->getFields(); + if ( !meshes) THROW_IK_EXCEPTION("No meshes in MEDFileData"); + + _fileMesh = meshes->getMeshAtPos( meshIndex ); + _fileMesh->incrRef(); + + if ( fields ) + for ( int i = 0; i < fields->getNumberOfFields(); ++i ) + { + MEDFileAnyTypeFieldMultiTS * fB = fields->getFieldAtPos(i); + MEDFileFieldMultiTS * f = dynamic_cast<MEDFileFieldMultiTS *>(fB); + if(!f) + continue;// fields on int32 not managed + if ( f->getMeshName() == _fileMesh->getName() ) + { + vector< vector<TypeOfField> > fTypes = f->getTypesOfFieldAvailable(); + if ( fTypes[0].size() == 1 && fTypes[0][0] == ON_NODES ) + _nodeFields.push_back( f ); + else + _cellFields.push_back( f ); + } + } +} + +//================================================================================ +/*! + * \brief Adds a submesh + */ +//================================================================================ + +SauvWriter::SubMesh* SauvWriter::addSubMesh(const std::string& name, int dimRelExt) +{ + if ( _subs.capacity() < _subs.size() + 1 ) + THROW_IK_EXCEPTION("SauvWriter: INTERNAL error, wrong evaluation of nb of sub-meshes"); + _subs.resize( _subs.size() + 1 ); + SubMesh& sm = _subs.back(); + sm._name = name; + sm._dimRelExt = dimRelExt; + return &sm; +} +//================================================================================ +/*! + * \brief Returns nb of cell types + */ +//================================================================================ + +int SauvWriter::SubMesh::nbTypes() const +{ + int nb = 0; + for (int i = 0; i < cellIDsByTypeSize(); ++i ) + nb += int( !_cellIDsByType[i].empty() ); + return nb; +} + +//================================================================================ +/*! + * \brief Fill _subs + */ +//================================================================================ + +void SauvWriter::fillSubMeshes( int& nbSauvObjects, map<string,int>& nameNbMap ) +{ + // evaluate nb of _subs in order to avoid re-allocation of _subs + int nbSubs = 1; // for the very mesh + nbSubs += _fileMesh->getFamilyInfo().size() + 4; // + 4 zero families (for each dimRelExt) + nbSubs += _fileMesh->getGroupInfo().size(); + nbSubs += evaluateNbProfileSubMeshes(); + _subs.clear(); + _subs.reserve( nbSubs ); + + fillFamilySubMeshes(); + fillGroupSubMeshes(); + fillProfileSubMeshes(); + + // fill names of SubMesh'es and count nb of sauv sub-meshes they will be stored into + nbSauvObjects = 0; + map<string,int> namePrefixMap; + for ( size_t i = 0; i < _subs.size(); ++i ) + { + SubMesh& sm = _subs[i]; + + sm._nbSauvObjects = 0; + if ( sm._subs.empty() ) + { + sm._nbSauvObjects = sm.nbTypes(); + } + else + { + sm._nbSauvObjects = 1; + } + + sm._id = nbSauvObjects+1; + nbSauvObjects += sm._nbSauvObjects; + + if ( sm._nbSauvObjects ) + sm._name = addName( nameNbMap, namePrefixMap, sm._name, sm._id ); + + if ( sm._nbSauvObjects && !sm._name.empty() ) + { + nameGIBItoMED aMEDName; + aMEDName.gibi_pile = PILE_SOUS_MAILLAGE; + aMEDName.gibi_id = sm._id; + aMEDName.med_name = sm._name; + _longNames[ LN_MAIL ].push_back(aMEDName); + } + } +} + +//================================================================================ +/*! + * \brief fill sub-meshes of families + */ +//================================================================================ + +void SauvWriter::fillFamilySubMeshes() +{ + SubMesh* nilSm = (SubMesh*) 0; + std::vector<int> dims = _fileMesh->getNonEmptyLevelsExt(); + for ( size_t iDim = 0; iDim < dims.size(); ++iDim ) + { + int dimRelExt = dims[ iDim ]; + MEDCouplingAutoRefCountObjectPtr< MEDCouplingMesh > mesh = _fileMesh->getGenMeshAtLevel(dimRelExt); + const DataArrayInt * famIds = _fileMesh->getFamilyFieldAtLevel(dimRelExt); + if ( !famIds ) continue; + + int curFamID = 0; + SubMesh* curSubMesh = addSubMesh( "", dimRelExt ); // submesh of zero family + _famIDs2Sub[0] = curSubMesh; + int sub0Index = _subs.size()-1; + + const int * famID = famIds->begin(), * famIDEnd = famIds->end(); + for ( int cellID = 0; famID < famIDEnd; ++famID, cellID++ ) + { + if ( *famID != curFamID ) + { + curFamID = *famID; + map< int, SubMesh* >::iterator f2s = _famIDs2Sub.insert( make_pair( curFamID, nilSm )).first; + if ( !f2s->second ) + f2s->second = addSubMesh( "", dimRelExt ); // no names for families + curSubMesh = f2s->second; + } + INTERP_KERNEL::NormalizedCellType cellType = + dimRelExt == 1 ? INTERP_KERNEL::NORM_POINT1 : mesh->getTypeOfCell( cellID ); + curSubMesh->_cellIDsByType[ cellType ].push_back( cellID ); + } + + if ( dimRelExt == 1 ) + { + // clear submesh of nodal zero family + _famIDs2Sub[0]->_cellIDsByType[ INTERP_KERNEL::NORM_POINT1 ].clear(); + } + else if ( dimRelExt == 0 ) + { + // make a submesh including all cells + if ( sub0Index == (int)(_subs.size()-1) ) + { + _famIDs2Sub[0]->_name = _fileMesh->getName(); // there is the zero family only + } + else + { + curSubMesh = addSubMesh( _fileMesh->getName(), dimRelExt ); + if ( _famIDs2Sub[0]->nbTypes() == 0 ) + sub0Index++; // skip an empty zero family + for ( size_t i = sub0Index; i < _subs.size()-1; ++i ) + curSubMesh->_subs.push_back( & _subs[i] ); + } + } + } +} + +//================================================================================ +/*! + * \brief fill sub-meshes of groups + */ +//================================================================================ + +void SauvWriter::fillGroupSubMeshes() +{ + const map<string, vector<string> >& grpFams = _fileMesh->getGroupInfo(); + map<string, vector<string> >::const_iterator g2ff = grpFams.begin(); + for ( ; g2ff != grpFams.end(); ++g2ff ) + { + const string& groupName = g2ff->first; + const vector<string>& famNames = g2ff->second; + if ( famNames.empty() ) continue; + std::vector<SubMesh*> famSubMeshes( famNames.size() ); + std::size_t k = 0; + for ( size_t i = 0; i < famNames.size(); ++i ) + { + int famID = _fileMesh->getFamilyId( famNames[i].c_str() ); + map< int, SubMesh* >::iterator i2f = _famIDs2Sub.find( famID ); + if ( i2f != _famIDs2Sub.end() ) + { + famSubMeshes[ k ] = i2f->second; + ++k; + } + } + // if a family exists but has no element, no submesh has been found for this family + // => we have to resize famSubMeshes with the number of submeshes stored + if (k != famNames.size()) + famSubMeshes.resize(k); + SubMesh* grpSubMesh = addSubMesh( groupName, famSubMeshes[0]->_dimRelExt ); + if(!_cpy_grp_if_on_single_family) + grpSubMesh->_subs.swap( famSubMeshes ); + else + { + /* If a group sub mesh consists of only one family, the group is written as + * a copy of this family. + * A mesh composed of only one submesh may cause an issue with some Gibi operators.*/ + if (famSubMeshes.size() == 1) + { + for(int i = 0; i < famSubMeshes[0]->cellIDsByTypeSize() ; i++) + { + grpSubMesh->_cellIDsByType[i] = famSubMeshes[0]->_cellIDsByType[i]; + } + } + else + grpSubMesh->_subs.swap( famSubMeshes ); + } + } +} + + +//================================================================================ +/*! + * \brief fill sub-meshes of profiles + */ +//================================================================================ + +void SauvWriter::fillProfileSubMeshes() +{ + _profile2Sub.clear(); + SubMesh* nilSm = (SubMesh*) 0; + for ( int isOnNodes = 0; isOnNodes < 2; ++isOnNodes ) + { + vector< MEDCouplingAutoRefCountObjectPtr< MEDFileFieldMultiTS > > + fields = isOnNodes ? _nodeFields : _cellFields; + for ( size_t i = 0; i < fields.size(); ++i ) + { + vector< pair<int,int> > iters = fields[i]->getIterations(); + + vector<INTERP_KERNEL::NormalizedCellType> types; + vector< vector<TypeOfField> > typesF; + vector< vector<string> > pfls, locs; + fields[i]->getFieldSplitedByType( iters[0].first, iters[0].second, + _fileMesh->getName().c_str(), types, typesF, pfls, locs); + int dimRelExt; + for ( size_t iType = 0; iType < types.size(); ++iType ) + { + if ( types[iType] == INTERP_KERNEL::NORM_ERROR ) + dimRelExt = 1; // on nodes + else + dimRelExt = getDimension( types[iType] ) - _fileMesh->getMeshDimension(); + for ( size_t iPfl = 0; iPfl < pfls[iType].size(); ++iPfl ) + { + bool isOnAll = pfls[iType][iPfl].empty(); + if ( isOnAll ) pfls[iType][iPfl] = noProfileName( types[iType] ); + map< string, SubMesh* >::iterator pfl2sm = + _profile2Sub.insert( make_pair( pfls[iType][iPfl], nilSm )).first; + if ( !pfl2sm->second ) + { + SubMesh* sm = pfl2sm->second = addSubMesh( "", dimRelExt ); // no names for profiles + const DataArrayInt * pfl = isOnAll ? 0 : fields[i]->getProfile( pfls[iType][iPfl].c_str() ); + makeProfileIDs( sm, types[iType], pfl ); + } + } + } + } + } +} + +//================================================================================ +/*! + * \brief Return max possible nb of sub-meshes to decsribe field supports + */ +//================================================================================ + +int SauvWriter::evaluateNbProfileSubMeshes() const +{ + int nb = 0; + for ( size_t i = 0; i < _nodeFields.size(); ++i ) + nb += 1 + _nodeFields[i]->getPflsReallyUsed().size(); + + for ( size_t i = 0; i < _cellFields.size(); ++i ) + { + nb += _cellFields[i]->getPflsReallyUsed().size(); + + vector< pair<int,int> > iters = _cellFields[i]->getIterations(); + + vector<INTERP_KERNEL::NormalizedCellType> types; + vector< vector<TypeOfField> > typesF; + vector< vector<string> > pfls, locs; + _cellFields[i]->getFieldSplitedByType( iters[0].first, iters[0].second, + _fileMesh->getName().c_str(), types, typesF, pfls, locs); + nb += 2 * types.size(); // x 2 - a type can be on nodes and on cells at the same time + } + + return nb; +} + +//================================================================================ +/*! + * \brief Transorm a profile into ids of mesh elements + */ +//================================================================================ + +void SauvWriter::makeProfileIDs( SubMesh* sm, + INTERP_KERNEL::NormalizedCellType type, + const DataArrayInt* profile ) +{ + MEDCouplingAutoRefCountObjectPtr< MEDCouplingMesh > + mesh = _fileMesh->getGenMeshAtLevel(sm->_dimRelExt); + const MEDCouplingUMesh* uMesh = dynamic_cast< const MEDCouplingUMesh* > ((const MEDCouplingMesh*) mesh ); + + if ( sm->_dimRelExt == 1 ) type = INTERP_KERNEL::NORM_POINT1; + vector< int >& ids = sm->_cellIDsByType[ type ]; + + if ( sm->_dimRelExt == 1 || !uMesh ) + { + // profile on nodes or mesh is CARTESIAN + if ( profile ) + { + ids.assign( profile->begin(), profile->end() ); + } + else // on all + { + ids.resize( sm->_dimRelExt == 1 ? mesh->getNumberOfNodes() : mesh->getNumberOfCells() ); + for ( size_t i = 0; i < ids.size(); ++i ) + ids[i]=i; + } + } + else + { + // profile on cells + vector<int> code(3); + code[0] = type; + if ( profile ) // on profile + { + code[1] = profile->getNumberOfTuples(); + code[2] = 0; + } + else // on all cells + { + code[1] = mesh->getNumberOfCellsWithType( type ); + code[2] = -1; + } + vector<const DataArrayInt *> idsPerType( 1, profile ); + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> + resIDs = uMesh->checkTypeConsistencyAndContig( code, idsPerType ); + if (( const DataArrayInt *) resIDs ) + { + ids.assign( resIDs->begin(), resIDs->end() ); + } + else // mesh includes only one type + { + int nbE = code[1]; + for ( ids.resize( nbE ); nbE; --nbE ) + ids[ nbE-1 ] = nbE-1; + } + } +} + +//================================================================================ +/*! + * \brief Write its data into the SAUVE file + */ +//================================================================================ + +void SauvWriter::write(const std::string& fileName) +{ + std::fstream fileStream; + fileStream.open( fileName.c_str(), ios::out); + if +#ifdef WIN32 + ( !fileStream || !fileStream.is_open() ) +#else + ( !fileStream || !fileStream.rdbuf()->is_open() ) +#endif + THROW_IK_EXCEPTION("Can't open the file |"<<fileName<<"|"); + _sauvFile = &fileStream; + + _subs.clear(); + _famIDs2Sub.clear(); + _profile2Sub.clear(); + _longNames[ LN_MAIL ].clear(); + _longNames[ LN_CHAM ].clear(); + _longNames[ LN_COMP ].clear(); + + map<string,int> fldNamePrefixMap; + + writeFileHead(); + writeSubMeshes(); + writeNodes(); + writeNodalFields(fldNamePrefixMap); + writeElemFields(fldNamePrefixMap); + writeLongNames(); + writeLastRecord(); + + _sauvFile->close(); +} +//================================================================================ +/*! + * \brief Writes "ENREGISTREMENT DE TYPE" 4 and 7 + */ +//================================================================================ + +void SauvWriter::writeFileHead() +{ + MEDCouplingAutoRefCountObjectPtr< MEDCouplingMesh > mesh = _fileMesh->getGenMeshAtLevel(0); + + *_sauvFile + << " ENREGISTREMENT DE TYPE 4" << endl + << " NIVEAU 16 NIVEAU ERREUR 0 DIMENSION " << mesh->getSpaceDimension() <<endl + << " DENSITE 0.00000E+00" << endl + << " ENREGISTREMENT DE TYPE 7" << endl + << " NOMBRE INFO CASTEM2000 8" <<endl + << " IFOUR -1 NIFOUR 0 IFOMOD -1 IECHO 1 IIMPI 0 IOSPI 0 ISOTYP 1" << endl + << " NSDPGE 0" << endl; +} + +//================================================================================ +/*! + * \brief Writes names of objects + */ +//================================================================================ + +void SauvWriter::writeNames( const map<string,int>& nameNbMap ) +{ + if ( !nameNbMap.empty() ) + { + // write names of objects + // * 8001 FORMAT(8(1X,A8)) + TFieldCounter fcount( *_sauvFile, 8 ); + *_sauvFile << left; + map<string,int>::const_iterator nameNbIt = nameNbMap.begin(); + for ( ; nameNbIt != nameNbMap.end(); nameNbIt++, fcount++ ) + *_sauvFile << " " << setw(8) << nameNbIt->first; + fcount.stop(); + *_sauvFile << right; + + // write IDs of named objects in the pile + // * 8000 FORMAT(10I8) + nameNbIt = nameNbMap.begin(); + for ( fcount.init(10); nameNbIt != nameNbMap.end(); nameNbIt++, fcount++ ) + *_sauvFile << setw(8) << nameNbIt->second; + } +} + +//================================================================================ +/*! + * \brief Writes "PILE NUMERO 1" + */ +//================================================================================ + +void SauvWriter::writeSubMeshes() +{ + int nbSauvObjects; + map<string,int> nameNbMap; + fillSubMeshes( nbSauvObjects, nameNbMap ); + + // * 800 FORMAT (' ENREGISTREMENT DE TYPE', I4) + *_sauvFile << " ENREGISTREMENT DE TYPE 2" << endl; + // * 801 FORMAT(' PILE NUMERO',I4,'NBRE OBJETS NOMMES',I8,'NBRE OBJETS',I8) + *_sauvFile << " PILE NUMERO 1NBRE OBJETS NOMMES" << setw(8) << nameNbMap.size() << + "NBRE OBJETS" << setw(8) << nbSauvObjects <<endl; + + writeNames( nameNbMap ); + + TFieldCounter fcount( *_sauvFile, 10 ); // 10 intergers per line + + for ( size_t iSub = 0; iSub < _subs.size(); ++iSub ) + { + SubMesh& sm = _subs[iSub]; + if ( sm._nbSauvObjects < 1 ) continue; + + // The first record of each sub-mesh writes + // - type of cells; zero means a compound object whose the 2nd record enumerates its components + // - number of components of a compound object + // - number of references; each reference means a "pointer" to this sub-mesh + // - number of nodes per cell + // - number of cells + + if ( !sm._subs.empty() ) + { + writeCompoundSubMesh(iSub); + } + else + { + // write each sub-type as a SAUV sub-mesh + MEDCouplingAutoRefCountObjectPtr< MEDCouplingMesh > + mesh = _fileMesh->getGenMeshAtLevel( sm._dimRelExt ); + MEDCouplingAutoRefCountObjectPtr< MEDCouplingUMesh> + umesh = mesh->buildUnstructured(); + + for ( int iType=0; iType < sm.cellIDsByTypeSize(); ++iType ) + { + const vector<int>& cellIDs = sm._cellIDsByType[iType]; + if ( cellIDs.empty() ) continue; + + INTERP_KERNEL::NormalizedCellType + cellType = INTERP_KERNEL::NormalizedCellType( iType ); + const INTERP_KERNEL::CellModel & + cell = INTERP_KERNEL::CellModel::GetCellModel( cellType ); + int castemType = SauvUtilities::med2gibiGeom( cellType ); + unsigned nbElemNodes = cell.getNumberOfNodes(); + unsigned nbElems = cellIDs.size(); + + *_sauvFile << setw(8) << castemType + << zeroI8 + << zeroI8 + << setw(8) << nbElemNodes + << setw(8) << nbElems << endl; + + // write color of each element + // * 8000 FORMAT(10I8) + for ( size_t i = 0; i < nbElems; ++i, fcount++ ) *_sauvFile << zeroI8; + fcount.stop(); + + // write connectivity + // gibi IDs are in FORTRAN mode while MEDCoupling IDs are in C mode + if ( sm._dimRelExt == 1 ) // nodes + { + for ( size_t i = 0; i < nbElems; ++i, fcount++ ) + *_sauvFile << setw(8) << ( cellIDs[i] + 1 ); + } + else + { + // indices to transform MED connectivity to GIBI one + const int * toMedConn = getGibi2MedQuadraticInterlace( cellType ); + + vector< int > cellConn( nbElemNodes ), transformedConn( nbElemNodes ); + for ( size_t i = 0; i < nbElems; ++i ) + { + cellConn.clear(); + umesh->getNodeIdsOfCell( cellIDs[i], cellConn ); + if ( toMedConn ) + { + for ( unsigned j = 0; j < nbElemNodes; ++j ) + transformedConn[ toMedConn[ j ]] = cellConn[ j ]; + cellConn.swap( transformedConn ); + } + for ( unsigned j = 0; j < nbElemNodes; ++j, fcount++ ) + *_sauvFile << setw(8) << ( cellConn[j] + 1 ); + } + } + fcount.stop(); + + } // loop on cell types + } // not a compound object + } // loop on sub-meshes +} + +//================================================================================ +/*! + * \brief Writes a sum-mesh composed of other sum-meshes + * This submesh corresponds to a med mesh or group composed of families + */ +//================================================================================ + +void SauvWriter::writeCompoundSubMesh(int iSub) +{ + SubMesh& sm = _subs[iSub]; + if ( sm._nbSauvObjects < 1 || sm._subs.empty()) return; + + vector< int > subIDs; + for ( size_t i = 0; i < sm._subs.size(); ++i ) // loop on sub-meshes of families + for ( int j = 0; j < sm._subs[i]->_nbSauvObjects; ++j ) + subIDs.push_back( sm._subs[i]->_id + j ); + + *_sauvFile << zeroI8 + << setw(8) << subIDs.size() + << zeroI8 + << zeroI8 + << zeroI8 << endl; + + TFieldCounter fcount( *_sauvFile, 10 ); // 10 intergers per line + for ( size_t i = 0; i < subIDs.size(); ++i, fcount++ ) + *_sauvFile << setw(8) << subIDs[i]; +} + +//================================================================================ +/*! + * \brief Write piles relating to nodes + */ +//================================================================================ + +void SauvWriter::writeNodes() +{ + MEDCouplingAutoRefCountObjectPtr< MEDCouplingMesh > mesh = _fileMesh->getGenMeshAtLevel( 1 ); + MEDCouplingAutoRefCountObjectPtr< MEDCouplingUMesh > umesh = mesh->buildUnstructured(); + + // write the index connecting nodes with their coodrinates + + const int nbNodes = umesh->getNumberOfNodes(); + *_sauvFile << " ENREGISTREMENT DE TYPE 2" << endl + << " PILE NUMERO 32NBRE OBJETS NOMMES 0NBRE OBJETS" << setw(8) << nbNodes << endl; + *_sauvFile << setw(8) << nbNodes << endl; + // + TFieldCounter fcount( *_sauvFile, 10 );// * 8000 FORMAT(10I8) + for ( int i = 0; i < nbNodes; ++i, fcount++ ) + *_sauvFile << setw(8) << i + 1; + fcount.stop(); + + // write coordinates and density of nodes + + *_sauvFile << " ENREGISTREMENT DE TYPE 2" << endl; + *_sauvFile << " PILE NUMERO 33NBRE OBJETS NOMMES 0NBRE OBJETS 1" << endl; + // + const int dim = umesh->getSpaceDimension(); + const int nbValues = nbNodes * ( dim + 1 ); + *_sauvFile << setw(8) << nbValues << endl; + + // * 8003 FORMAT(1P,3E22.14) + const char* density = " 0.00000000000000E+00"; + fcount.init(3); + _sauvFile->precision(14); + _sauvFile->setf( ios_base::scientific, ios_base::floatfield ); + _sauvFile->setf( ios_base::uppercase ); + MEDCouplingAutoRefCountObjectPtr< DataArrayDouble> coordArray = umesh->getCoordinatesAndOwner(); + const double precision = 1.e-99; // PAL12077 + for ( int i = 0; i < nbNodes; ++i) + { + for ( int j = 0; j < dim; ++j, fcount++ ) + { + double coo = coordArray->getIJ( i, j ); + bool zero = ( -precision < coo && coo < precision ); + *_sauvFile << setw(22) << ( zero ? 0.0 : coo ); + } + *_sauvFile << density; + fcount++; + } +} + +//================================================================================ +/*! + * \brief Store correspondence between GIBI (short) and MED (long) names + * + * IMP 0020434: mapping GIBI names to MED names + * Store correspondence between GIBI and MED names as one PILE_STRINGS and one + * PILE_TABLES (in three tables: MED_MAIL, MED_CHAM and MED_COMP) + */ +//================================================================================ + +void SauvWriter::writeLongNames() +{ + int nbTables = + 3 - _longNames[ LN_MAIL ].empty() - _longNames[ LN_CHAM ].empty() - _longNames[ LN_COMP ].empty(); + if (nbTables == 0) return; + + // --------------------- + // Write the TABLE pile + // --------------------- + + *_sauvFile << " ENREGISTREMENT DE TYPE 2" << endl + << " PILE NUMERO 10NBRE OBJETS NOMMES" << setw(8) << nbTables + << "NBRE OBJETS" << setw(8) << nbTables << endl; + // table names + if (!_longNames[ LN_MAIL ].empty()) *_sauvFile << " MED_MAIL"; + if (!_longNames[ LN_CHAM ].empty()) *_sauvFile << " MED_CHAM"; + if (!_longNames[ LN_COMP ].empty()) *_sauvFile << " MED_COMP"; + *_sauvFile << endl; + // table indices + for ( int i = 0; i < nbTables; ++i ) *_sauvFile << setw(8) << i+1; + *_sauvFile << endl; + + string theWholeString; // concatenated long names + vector<int> theOffsets; + int iStr = 1; + TFieldCounter fcount (*_sauvFile, 10); + + for ( int iTbl = 0; iTbl < LN_NB; ++iTbl ) + { + vector<nameGIBItoMED>& longNames = _longNames[ iTbl ]; + if ( longNames.empty() ) continue; + const bool isComp = ( iTbl == LN_COMP); + + // to assure unique MED names + set<string> medUniqueNames; + + *_sauvFile << setw(8) << longNames.size()*4 << endl; // Nb of table values + + vector<nameGIBItoMED>::iterator itGIBItoMED = longNames.begin(); + for (; itGIBItoMED != longNames.end(); itGIBItoMED++, iStr++) + { + // PILE of i-th key (med name) + *_sauvFile << setw(8) << PILE_STRINGS; + fcount++; + // ID of i-th key (med name) + *_sauvFile << setw(8) << iStr; + fcount++; + // PILE of i-th value (gibi name) + *_sauvFile << setw(8) << itGIBItoMED->gibi_pile; + fcount++; + // ID of i-th value (gibi name) + *_sauvFile << setw(8) << ( isComp ? ++iStr : itGIBItoMED->gibi_id ); + fcount++; + + // add a MED name to the string (while making it be unique for sub-meshes and fields) + string aMedName = itGIBItoMED->med_name; + if ( !isComp ) + for (int ind = 1; !medUniqueNames.insert(aMedName).second; ++ind ) + aMedName = itGIBItoMED->med_name + "_" + SauvUtilities::toString( ind ); + theWholeString += aMedName; + + // add an offset + theOffsets.push_back( theWholeString.size() ); + if ( isComp ) + { + theWholeString += itGIBItoMED->gibi_name; + theOffsets.push_back( theWholeString.size() ); + } + } + fcount.stop(); + } + + // ---------------------- + // Write the STRING pile + // ---------------------- + + const int nbNames = theOffsets.size(); + *_sauvFile << " ENREGISTREMENT DE TYPE 2" << endl + << " PILE NUMERO 27NBRE OBJETS NOMMES" << zeroI8 << "NBRE OBJETS" << setw(8) << nbNames << endl + << setw(8) << theWholeString.length() << setw(8) << nbNames << endl; + + // write the whole string + const int fixedLength = 71; + for ( string::size_type aPos = 0; aPos < theWholeString.length(); aPos += fixedLength) + *_sauvFile << setw(72) << theWholeString.substr(aPos, fixedLength) << endl; + + // write the offsets + for ( size_t i = 0; i < theOffsets.size(); ++i, fcount++ ) + *_sauvFile << setw(8) << theOffsets[i]; +} + +//================================================================================ +/*! + * \brief Write beginning of field record + */ +//================================================================================ + +void SauvWriter::writeFieldNames( const bool isNodal, + std::map<std::string,int>& fldNamePrefixMap) +{ + vector< MEDCouplingAutoRefCountObjectPtr< MEDFileFieldMultiTS > >& + flds = isNodal ? _nodeFields : _cellFields; + map<string,int> nameNbMap; + + for ( size_t iF = 0; iF < flds.size(); ++iF ) + { + string name = addName( nameNbMap, fldNamePrefixMap, flds[iF]->getName(), iF+1 ); + nameGIBItoMED aMEDName; + aMEDName.gibi_pile = isNodal ? PILE_NODES_FIELD : PILE_FIELD; + aMEDName.gibi_id = iF+1; + aMEDName.med_name = name; + _longNames[ LN_CHAM ].push_back(aMEDName); + } + + *_sauvFile << " ENREGISTREMENT DE TYPE 2" << endl + << ( isNodal ? " PILE NUMERO 2" : " PILE NUMERO 39") + << "NBRE OBJETS NOMMES" << setw(8) << nameNbMap.size() + << "NBRE OBJETS" << setw(8) << flds.size() << endl; + writeNames( nameNbMap ); +} + +//================================================================================ +/*! + * \brief Make short names of field components + * + * IMP 0020434: mapping GIBI names to MED names + */ +//================================================================================ + +void SauvWriter::makeCompNames(const string& fieldName, + const vector<string>& compInfo, + map<string, string>& mapMedToGibi) +{ + for ( size_t i = 0; i < compInfo.size(); ++i ) + mapMedToGibi[compInfo[i]] = cleanName( compInfo[i] ); + + int compIndex = 1; + map<string, string>::iterator namesIt = mapMedToGibi.begin(); + for (; namesIt != mapMedToGibi.end(); namesIt++) + { + string & compGibiName = (*namesIt).second; + if (compGibiName.size() > 4) { + // use new name in form "CXXX", where "XXX" is a number + do + { + compGibiName = SauvUtilities::toString( compIndex++ ); + if ( compGibiName.size() < 3 ) + compGibiName.insert( 0, 3 - compGibiName.size(), '0' ); + compGibiName = "C" + compGibiName; + } + while (mapMedToGibi.count(compGibiName) > 0); // real component name could be CXXX + } + + string compMedName = fieldName + "." + namesIt->first; + nameGIBItoMED aMEDName; + aMEDName.med_name = compMedName; + aMEDName.gibi_pile = PILE_STRINGS; + aMEDName.gibi_name = compGibiName; + _longNames[ LN_COMP ].push_back(aMEDName); + } +} + +//================================================================================ +/*! + * \brief Writes "PILE NUMERO 2": fields on nodes + */ +//================================================================================ + +void SauvWriter::writeNodalFields(map<string,int>& fldNamePrefixMap) +{ + writeFieldNames( /*isNodal=*/true, fldNamePrefixMap ); + + TFieldCounter fcount (*_sauvFile, 10); + + // EXAMPLE ( with no values ) + + // (1) 4 7 2 1 + // (2) -88 0 3 -89 0 1 -90 0 2 -91 + // (2) 0 1 + // (3) FX FY FZ FZ FX FY FLX + // (4) 0 0 0 0 0 0 0 + // (5) cree par muc pri + // (6) + // (7) 2 + for ( size_t iF = 0; iF < _nodeFields.size(); ++iF ) + { + // (1) write nb subcomponents, nb components(total) + vector< pair<int,int> > iters = _nodeFields[iF]->getIterations(); + const vector<string>& compInfo = _nodeFields[iF]->getInfo(); + const int nbSub = iters.size(); + const int nbComp = compInfo.size(); + const int totalNbComp = nbSub * nbComp; + *_sauvFile << setw(8) << nbSub + << setw(8) << totalNbComp + << setw(8) << -1 // IFOUR + << setw(8) << 0 << endl; // nb attributes + + // (2) for each sub-component (iteration) + // write support, number of values and number of components + fcount.init(10); + vector< int > vals(3); + for ( std::size_t iIt = 0; iIt < iters.size(); ++iIt ) + { + pair<int,int> it = iters[iIt]; + + vector<INTERP_KERNEL::NormalizedCellType> types; + vector< vector<TypeOfField> > typesF; + vector< vector<string> > pfls, locs; + vector< vector< std::pair<int,int> > > valsVec; + valsVec=_nodeFields[iF]->getFieldSplitedByType( it.first, it.second, _fileMesh->getName().c_str(), + types, typesF, pfls, locs); + // believe that there can be only one type in a nodal field, + // so do not use a loop on types + if ( pfls[0][0].empty() ) pfls[0][0] = noProfileName( types[0] ); + map< string, SubMesh* >::iterator pfl2Sub = _profile2Sub.find( pfls[0][0] ); + if ( pfl2Sub == _profile2Sub.end() ) + THROW_IK_EXCEPTION( "SauvWriter::writeNodalFields(): no sub-mesh for profile |" + << pfls[0][0] << "|"); + vals[0] = -pfl2Sub->second->_id; + vals[1] = (valsVec[0][0].second-valsVec[0][0].first); + vals[2] = compInfo.size(); + for ( size_t i = 0; i < vals.size(); ++i, fcount++ ) + *_sauvFile << setw(8) << vals[i]; + } + fcount.stop(); + + // (3) Write names of components + map<string, string> mapMedToGibi; + makeCompNames( _nodeFields[iF]->getName(), compInfo, mapMedToGibi ); + fcount.init(8); + *_sauvFile << left; + for ( std::size_t iIt = 0; iIt < iters.size(); ++iIt ) + for ( size_t i = 0; i < compInfo.size(); ++i, fcount++ ) + *_sauvFile << " " << setw(4) << mapMedToGibi[compInfo[i]]; + *_sauvFile << right; + fcount.stop(); + + // (4) nb harmonics + fcount.init(10); + for ( size_t i = 0; i < (std::size_t)totalNbComp; ++i, fcount++ ) + *_sauvFile << " " << setw(8) << 0; + fcount.stop(); + + string description = _nodeFields[iF]->getName(); + *_sauvFile << endl; // (5) TYPE + *_sauvFile << setw(72) << description.substr(0,71) << endl; // (6) TITRE + //*_sauvFile << endl; // (7) 0 attributes + + // write values of each component + fcount.init( 3 ); // 3 values per a line + for ( std::size_t iIt = 0; iIt < iters.size(); ++iIt ) + { + pair<int,int> it = iters[iIt]; + + vector<INTERP_KERNEL::NormalizedCellType> types; + vector< vector<TypeOfField> > typesF; + vector< vector<string> > pfls, locs; + vector< vector< std::pair<int,int> > > valsVec; + valsVec = _nodeFields[iF]->getFieldSplitedByType( it.first, it.second, _fileMesh->getName().c_str(), + types, typesF, pfls, locs); + // believe that there can be only one type in a nodal field, + // so do not perform a loop on types + const DataArrayDouble* valsArray = _nodeFields[iF]->getUndergroundDataArray(it.first, it.second); + for ( size_t j = 0; j < compInfo.size(); ++j ) + { + for ( size_t i = valsVec[0][0].first; i < (std::size_t)valsVec[0][0].second; ++i, fcount++ ) + *_sauvFile << setw(22) << valsArray->getIJ( i, j ); + fcount.stop(); + } + } + } // loop on fiels +} + +//================================================================================ +/*! + * \brief Writes "PILE NUMERO 39": fields on cells + */ +//================================================================================ + +void SauvWriter::writeElemFields(map<string,int>& fldNamePrefixMap) +{ + writeFieldNames( /*isNodal=*/false, fldNamePrefixMap ); + + TFieldCounter fcount (*_sauvFile, 10); + + // REAL EXAMPLE + + // (1) 1 2 6 16 + // (2) CARACTERISTIQUES + // (3) -15 317773 4 0 0 0 -2 0 3 + // (4) 317581 + // (5) 0 + // (6) 317767 317761 317755 317815 + // (7) YOUN NU H SIGY + // (8) REAL*8 REAL*8 REAL*8 REAL*8 + // (9) 1 1 0 0 + // (10) 2.00000000000000E+05 + // (9) 1 1 0 0 + // (10) 3.30000000000000E-01 + // (9) 1 1 0 0 + // (10) 1.00000000000000E+04 + // (9) 6 706 0 0 + // (10) 1.00000000000000E+02 1.00000000000000E+02 1.00000000000000E+02 + // (10) 1.00000000000000E+02 1.00000000000000E+02 1.00000000000000E+02 + // (10) ... + + for ( size_t iF = 0; iF < _cellFields.size(); ++iF ) + { + // count nb of sub-components + int iSub, nbSub = 0; + vector< pair<int,int> > iters = _cellFields[iF]->getIterations(); + for ( std::size_t iIt = 0; iIt < iters.size(); ++iIt ) + { + pair<int,int> it = iters[iIt]; + + vector<INTERP_KERNEL::NormalizedCellType> types; + vector< vector<TypeOfField> > typesF; + vector< vector<string> > pfls, locs; + vector< vector< std::pair<int,int> > > valsVec; + valsVec = _cellFields[iF]->getFieldSplitedByType( it.first, it.second, _fileMesh->getName().c_str(), + types, typesF, pfls, locs); + for ( size_t i = 0; i < valsVec.size(); ++i ) + nbSub += valsVec[i].size(); + } + // (1) write nb sub-components, title length + *_sauvFile << setw(8) << nbSub + << setw(8) << -1 // whatever + << setw(8) << 6 // whatever + << setw(8) << 72 << endl; // title length + // (2) title + string title = _cellFields[iF]->getName(); + *_sauvFile << setw(72) << title.substr(0,71) << endl; + *_sauvFile << setw(72) << " " << endl; + + // (3) support, nb components + vector<int> vals(9, 0); + const vector<string>& compInfo = _cellFields[iF]->getInfo(); + vals[2] = compInfo.size(); + fcount.init(10); + for ( std::size_t iIt = 0; iIt < iters.size(); ++iIt ) + { + pair<int,int> it = iters[iIt]; + + vector<INTERP_KERNEL::NormalizedCellType> types; + vector< vector<TypeOfField> > typesF; + vector< vector<string> > pfls, locs; + _cellFields[iF]->getFieldSplitedByType( it.first, it.second, _fileMesh->getName().c_str(), + types, typesF, pfls, locs); + for ( size_t iType = 0; iType < pfls.size(); ++iType ) + for ( size_t iP = 0; iP < pfls[iType].size(); ++iP ) + { + if ( pfls[iType][iP].empty() ) pfls[iType][iP] = noProfileName( types[iType] ); + map< string, SubMesh* >::iterator pfl2Sub = _profile2Sub.find( pfls[iType][iP] ); + if ( pfl2Sub == _profile2Sub.end() ) + THROW_IK_EXCEPTION( "SauvWriter::writeElemFields(): no sub-mesh for profile |" + << pfls[iType][iP] << "|"); + const int supportID = pfl2Sub->second->_id; + vals[0] = -supportID; + + for ( size_t i = 0; i < vals.size(); ++i, fcount++ ) + *_sauvFile << setw(8) << vals[ i ]; + } + } + fcount.stop(); + + // (4) dummy strings + for ( fcount.init(4), iSub = 0; iSub < nbSub; ++iSub, fcount++ ) + *_sauvFile << " "; + fcount.stop(); + + // (5) dummy strings + for ( fcount.init(8), iSub = 0; iSub < nbSub; ++iSub, fcount++ ) + *_sauvFile << " "; + fcount.stop(); + + // loop on sub-components of a field, each of which refers to + // a certain support and has its own number of components + for ( std::size_t iIt = 0; iIt < iters.size(); ++iIt ) + { + pair<int,int> it = iters[iIt]; + writeElemTimeStamp( iF, it.first, it.second ); + } + } // loop on cell fields +} + +//================================================================================ +/*! + * \brief Write one elemental time stamp + */ +//================================================================================ + +void SauvWriter::writeElemTimeStamp(int iF, int iter, int order) +{ + // (6) 317767 317761 317755 317815 + // (7) YOUN NU H SIGY + // (8) REAL*8 REAL*8 REAL*8 REAL*8 + // (9) 1 1 0 0 + // (10) 2.00000000000000E+05 + // (9) 1 1 0 0 + // (10) 3.30000000000000E-01 + // (9) 1 1 0 0 + // (10) 1.00000000000000E+04 + // (9) 6 706 0 0 + // (10) 1.00000000000000E+02 1.00000000000000E+02 1.00000000000000E+02 + // (10) 1.00000000000000E+02 1.00000000000000E+02 1.00000000000000E+02 + + TFieldCounter fcount (*_sauvFile, 10); + + vector<INTERP_KERNEL::NormalizedCellType> types; + vector< vector<TypeOfField> > typesF; + vector< vector<string> > pfls, locs; + vector< vector< std::pair<int,int> > > valsVec; + valsVec = _cellFields[iF]->getFieldSplitedByType( iter, order, _fileMesh->getName().c_str(), + types, typesF, pfls, locs); + for ( size_t iType = 0; iType < pfls.size(); ++iType ) + for ( size_t iP = 0; iP < pfls[iType].size(); ++iP ) + { + const vector<string>& compInfo = _cellFields[iF]->getInfo(); + + // (6) component addresses + int iComp = 0, nbComp = compInfo.size(); + for ( fcount.init(10); iComp < nbComp; ++iComp, fcount++ ) + *_sauvFile << setw(8) << 777; // a good number + fcount.stop(); + + // (7) component names + map<string, string> mapMedToGibi; + makeCompNames( _cellFields[iF]->getName(), compInfo, mapMedToGibi ); + *_sauvFile << left; + for ( fcount.init(8), iComp = 0; iComp < nbComp; ++iComp, fcount++ ) + *_sauvFile << " " << setw(8) << mapMedToGibi[compInfo[iComp]]; + fcount.stop(); + + // (8) component types + for ( fcount.init(4), iComp = 0; iComp < nbComp; ++iComp, fcount++ ) + *_sauvFile << " " << setw(17) << "REAL*8"; + fcount.stop(); + *_sauvFile << right; + + // (9) nb values per element, nb of elements + int nbPntPerCell = 1; + if ( !locs[iType][iP].empty() ) + { + int locID = _cellFields[iF]->getLocalizationId( locs[iType][iP].c_str() ); + nbPntPerCell = _cellFields[iF]->getNbOfGaussPtPerCell( locID ); + } + else if ( typesF[iType][iP] == ON_GAUSS_NE ) + { + nbPntPerCell = INTERP_KERNEL::CellModel::GetCellModel(types[iType]).getNumberOfNodes(); + } + + // (10) values + const std::pair<int,int>& bgEnd = valsVec[iType][iP]; + const DataArrayDouble* valArray = _cellFields[iF]->getUndergroundDataArray(iter, order); + for ( iComp = 0; iComp < nbComp; ++iComp ) + { + *_sauvFile << setw(8) << nbPntPerCell + << setw(8) << (bgEnd.second-bgEnd.first) / nbPntPerCell + << setw(8) << 0 + << setw(8) << 0 + << endl; + fcount.init(3); + for ( size_t i = bgEnd.first; i < (size_t) bgEnd.second; ++i, fcount++ ) + *_sauvFile << setw(22) << valArray->getIJ( i, iComp ); + fcount.stop(); + } + } +} + +//================================================================================ +/*! + * \brief Write the last record of the SAUV file + */ +//================================================================================ + +void SauvWriter::writeLastRecord() +{ + *_sauvFile << " ENREGISTREMENT DE TYPE 5" << endl; + *_sauvFile << "LABEL AUTOMATIQUE : 1" << endl; +} diff --git a/src/medtool/src/MEDLoader/SauvWriter.hxx b/src/medtool/src/MEDLoader/SauvWriter.hxx new file mode 100644 index 000000000..7887296e3 --- /dev/null +++ b/src/medtool/src/MEDLoader/SauvWriter.hxx @@ -0,0 +1,118 @@ +// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 +// 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 +// +// File : SauvWriter.hxx +// Created : Wed Aug 24 11:18:49 2011 +// Author : Edward AGAPOV (eap) + +#ifndef __SAUVWRITER_HXX__ +#define __SAUVWRITER_HXX__ + +#include "MEDLoaderDefines.hxx" +#include "MEDCouplingRefCountObject.hxx" +#include "NormalizedUnstructuredMesh.hxx" +#include "SauvUtilities.hxx" +#include "MEDCouplingAutoRefCountObjectPtr.hxx" + +#include <vector> +#include <string> +#include <map> + +namespace ParaMEDMEM +{ + class MEDFileData; + class MEDFileMesh; + class MEDFileFieldMultiTS; + class DataArrayInt; + + /*! + * \brief Class to write a MEDFileData into a SAUVE format file + */ + class SauvWriter : public ParaMEDMEM::RefCountObject + { + public: + MEDLOADER_EXPORT static SauvWriter *New(); + MEDLOADER_EXPORT void setMEDFileDS(const MEDFileData* medData, unsigned meshIndex = 0); + MEDLOADER_EXPORT void write(const std::string& fileName); + MEDLOADER_EXPORT void setCpyGrpIfOnASingleFamilyStatus(bool status); + MEDLOADER_EXPORT bool getCpyGrpIfOnASingleFamilyStatus() const; + private: + SauvWriter(); + std::size_t getHeapMemorySizeWithoutChildren() const; + std::vector<const BigMemoryObject *> getDirectChildrenWithNull() const; + /*! + * \brief Class representing a GIBI sub-mesh (described in the pile 1 of the SAUVE file). + * It stands for a named med sub-mesh (family, etc) and contains either cell IDs or other sub-meshes. + */ + struct SubMesh + { + std::vector<int> _cellIDsByType[ INTERP_KERNEL::NORM_MAXTYPE+1 ]; + std::vector<SubMesh*> _subs; + std::string _name; + int _id; + int _nbSauvObjects; + int _dimRelExt; + int nbTypes() const; + static int cellIDsByTypeSize() { return INTERP_KERNEL::NORM_MAXTYPE+1; } + }; + SubMesh* addSubMesh(const std::string& name, int dimRelExt); + + void fillSubMeshes(int& nbSauvObjects, std::map<std::string,int>& nameNbMap); + void fillFamilySubMeshes(); + void fillGroupSubMeshes(); + void fillProfileSubMeshes(); + int evaluateNbProfileSubMeshes() const; + void makeCompNames(const std::string& fieldName, + const std::vector<std::string>& compInfo, + std::map<std::string, std::string>& compMedToGibi ); + void makeProfileIDs( SubMesh* sm, + INTERP_KERNEL::NormalizedCellType type, + const DataArrayInt* profile ); + void writeFileHead(); + void writeSubMeshes(); + void writeCompoundSubMesh(int iSub); + void writeNodes(); + void writeLongNames(); + void writeNodalFields(std::map<std::string,int>& fldNamePrefixMap); + void writeElemFields(std::map<std::string,int>& fldNamePrefixMap); + void writeFieldNames(const bool isNodal, std::map<std::string,int>& fldNamePrefixMap); + void writeElemTimeStamp(int iF, int iter, int order); + void writeLastRecord(); + void writeNames( const std::map<std::string,int>& nameNbMap ); + + private: + + MEDCouplingAutoRefCountObjectPtr< MEDFileMesh > _fileMesh; + std::vector< MEDCouplingAutoRefCountObjectPtr< MEDFileFieldMultiTS > > _nodeFields; + std::vector< MEDCouplingAutoRefCountObjectPtr< MEDFileFieldMultiTS > > _cellFields; + + std::vector<SubMesh> _subs; + std::map< int, SubMesh* > _famIDs2Sub; + std::map< std::string, SubMesh* > _profile2Sub; + enum + { + LN_MAIL=0, LN_CHAM, LN_COMP, LN_NB + }; + std::vector<SauvUtilities::nameGIBItoMED> _longNames[ LN_NB ]; + + std::fstream* _sauvFile; + bool _cpy_grp_if_on_single_family; + }; +} + +#endif diff --git a/src/medtool/src/MEDLoader/Swig/CMakeLists.txt b/src/medtool/src/MEDLoader/Swig/CMakeLists.txt new file mode 100644 index 000000000..54a9a602c --- /dev/null +++ b/src/medtool/src/MEDLoader/Swig/CMakeLists.txt @@ -0,0 +1,112 @@ +# Copyright (C) 2012-2015 CEA/DEN, EDF 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, 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 +# 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) + +FIND_PACKAGE(SWIG REQUIRED) +INCLUDE(${SWIG_USE_FILE}) + +ADD_DEFINITIONS(${PYTHON_DEFINITIONS}) + +SET_SOURCE_FILES_PROPERTIES(MEDLoader.i PROPERTIES CPLUSPLUS ON) +SET_SOURCE_FILES_PROPERTIES(MEDLoader.i PROPERTIES SWIG_DEFINITIONS "-shadow") +SET(SWIG_MODULE_MEDLoader_EXTRA_FLAGS ${SWIG_EXTRA_FLAGS_FOR_NUMPYANDSCIPY}) + +SET (MEDLoader_SWIG_DPYS_FILES + MEDLoaderCommon.i + MEDLoaderTypemaps.i) + +INCLUDE_DIRECTORIES( + ${PYTHON_INCLUDE_DIRS} + ${MEDFILE_INCLUDE_DIRS} + ${HDF5_INCLUDE_DIRS} + ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_CURRENT_SOURCE_DIR}/.. + ${CMAKE_CURRENT_SOURCE_DIR}/../../MEDCoupling_Swig + ${CMAKE_CURRENT_SOURCE_DIR}/../../MEDCoupling + ${CMAKE_CURRENT_SOURCE_DIR}/../../INTERP_KERNEL + ${CMAKE_CURRENT_SOURCE_DIR}/../../INTERP_KERNEL/Bases + ${CMAKE_CURRENT_SOURCE_DIR}/../../INTERP_KERNEL/Geometric2D + ${CMAKE_CURRENT_SOURCE_DIR}/../../INTERP_KERNEL/ExprEval + ${CMAKE_CURRENT_SOURCE_DIR}/../../INTERP_KERNEL/GaussPoints + ${PROJECT_BINARY_DIR}/doc +) + +SET (SWIG_MODULE_MEDLoader_EXTRA_DEPS ${MEDLoader_SWIG_DPYS_FILES} + ${medloader_HEADERS_HXX} + ${medcoupling_HEADERS_HXX} ${medcoupling_HEADERS_TXX} + ${interpkernel_HEADERS_HXX} ${interpkernel_HEADERS_TXX}) + +# SWIG must run after the doc if we want to have the docstrings extracted from Doxygen +# into the Python module: +IF(SALOME_BUILD_DOC) + LIST(APPEND SWIG_MODULE_MEDLoader_EXTRA_FLAGS -DWITH_DOCSTRINGS) + LIST(APPEND SWIG_MODULE_MEDLoader_EXTRA_DEPS + ${PROJECT_BINARY_DIR}/doc/MEDLoader_doc.i + swig_ready) +ENDIF() + +SWIG_ADD_MODULE(MEDLoader python MEDLoader.i) +SWIG_LINK_LIBRARIES(MEDLoader ${PYTHON_LIBRARIES} ${PLATFORM_LIBS} medloader medcoupling) +IF(WIN32) + SET_TARGET_PROPERTIES(_MEDLoader PROPERTIES DEBUG_OUTPUT_NAME _MEDLoader_d) +ENDIF(WIN32) + +INSTALL(TARGETS _MEDLoader DESTINATION ${MEDTOOL_INSTALL_PYTHON}) +INSTALL(FILES MEDLoader.i MEDLoaderTypemaps.i MEDLoaderCommon.i DESTINATION ${MEDTOOL_INSTALL_HEADERS}) + +#SET(PYFILES_TO_INSTALL ${CMAKE_CURRENT_BINARY_DIR}/MEDLoader.py) +#SALOME_INSTALL_SCRIPTS("${PYFILES_TO_INSTALL}" ${SALOME_INSTALL_PYTHON}) +#INSTALL(FILES "${PYFILES_TO_INSTALL}" DESTINATION ${MEDTOOL_INSTALL_PYTHON}) +INSTALL(FILES ${CMAKE_CURRENT_BINARY_DIR}/MEDLoader.py DESTINATION ${MEDTOOL_INSTALL_PYTHON}) + +INSTALL(FILES MEDLoaderDataForTest.py MEDLoaderTest.py MEDLoaderTest2.py MEDLoaderTest3.py MEDLoaderTest4.py SauvLoaderTest.py MEDLoaderExamplesTest.py MEDLoaderCouplingTrainingSession.py CaseIO.py CaseReader.py CaseWriter.py VTKReader.py MEDLoaderSplitter.py medutilities.py DESTINATION ${MEDTOOL_INSTALL_SCRIPT_SCRIPTS}) +INSTALL(FILES med2sauv PERMISSIONS OWNER_EXECUTE OWNER_WRITE OWNER_READ GROUP_EXECUTE GROUP_READ WORLD_EXECUTE WORLD_READ DESTINATION ${MEDTOOL_INSTALL_BINS} ) +INSTALL(FILES sauv2med PERMISSIONS OWNER_EXECUTE OWNER_WRITE OWNER_READ GROUP_EXECUTE GROUP_READ WORLD_EXECUTE WORLD_READ DESTINATION ${MEDTOOL_INSTALL_BINS} ) +INSTALL(FILES case2med PERMISSIONS OWNER_EXECUTE OWNER_WRITE OWNER_READ GROUP_EXECUTE GROUP_READ WORLD_EXECUTE WORLD_READ DESTINATION ${MEDTOOL_INSTALL_BINS} ) +INSTALL(FILES med2case PERMISSIONS OWNER_EXECUTE OWNER_WRITE OWNER_READ GROUP_EXECUTE GROUP_READ WORLD_EXECUTE WORLD_READ DESTINATION ${MEDTOOL_INSTALL_BINS} ) + +#SALOME_GENERATE_TESTS_ENVIRONMENT(tests_env) + +ADD_TEST(MEDLoaderTest ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/MEDLoaderTest.py) +SET_TESTS_PROPERTIES(MEDLoaderTest PROPERTIES ENVIRONMENT "${tests_env}") +ADD_TEST(MEDLoaderTest2 ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/MEDLoaderTest2.py) +SET_TESTS_PROPERTIES(MEDLoaderTest2 PROPERTIES ENVIRONMENT "${tests_env}") +ADD_TEST(MEDLoaderTest3 ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/MEDLoaderTest3.py) +SET_TESTS_PROPERTIES(MEDLoaderTest3 PROPERTIES ENVIRONMENT "${tests_env}") +ADD_TEST(MEDLoaderTest4 ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/MEDLoaderTest4.py) +SET_TESTS_PROPERTIES(MEDLoaderTest4 PROPERTIES ENVIRONMENT "${tests_env}") +ADD_TEST(MEDLoaderExamplesTest ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/MEDLoaderExamplesTest.py) +SET_TESTS_PROPERTIES(MEDLoaderExamplesTest PROPERTIES ENVIRONMENT "${tests_env}") +ADD_TEST(SauvLoaderTest ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/SauvLoaderTest.py) +SET_TESTS_PROPERTIES(SauvLoaderTest PROPERTIES ENVIRONMENT "${tests_env}") + +IF(NUMPY_FOUND) + ADD_TEST(MEDLoaderCouplingTrainingSession ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/MEDLoaderCouplingTrainingSession.py) + SET_TESTS_PROPERTIES(MEDLoaderCouplingTrainingSession PROPERTIES ENVIRONMENT "${tests_env}") +ENDIF(NUMPY_FOUND) + +# Application tests + +SET(TEST_INSTALL_DIRECTORY ${MEDTOOL_INSTALL_SCRIPT_SCRIPTS}/test/MEDCoupling/MEDLoader/Swig) + +INSTALL(FILES MEDLoaderDataForTest.py MEDLoaderTest.py MEDLoaderTest2.py MEDLoaderTest3.py MEDLoaderTest4.py SauvLoaderTest.py MEDLoaderExamplesTest.py MEDLoaderCouplingTrainingSession.py CaseIO.py CaseReader.py CaseWriter.py VTKReader.py MEDLoaderSplitter.py medutilities.py DESTINATION ${TEST_INSTALL_DIRECTORY}) + +INSTALL(FILES CTestTestfileInstall.cmake + DESTINATION ${TEST_INSTALL_DIRECTORY} + RENAME CTestTestfile.cmake) diff --git a/src/medtool/src/MEDLoader/Swig/CTestTestfileInstall.cmake b/src/medtool/src/MEDLoader/Swig/CTestTestfileInstall.cmake new file mode 100644 index 000000000..819a91abd --- /dev/null +++ b/src/medtool/src/MEDLoader/Swig/CTestTestfileInstall.cmake @@ -0,0 +1,40 @@ +# Copyright (C) 2015 CEA/DEN, EDF 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, 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 +# 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_TEST(MEDLoaderTest python MEDLoaderTest.py) +SET_TESTS_PROPERTIES(MEDLoaderTest PROPERTIES LABELS "${COMPONENT_NAME}") + +ADD_TEST(MEDLoaderTest2 python MEDLoaderTest2.py) +SET_TESTS_PROPERTIES(MEDLoaderTest2 PROPERTIES LABELS "${COMPONENT_NAME}") + +ADD_TEST(MEDLoaderTest3 python MEDLoaderTest3.py) +SET_TESTS_PROPERTIES(MEDLoaderTest3 PROPERTIES LABELS "${COMPONENT_NAME}") + +ADD_TEST(MEDLoaderTest4 python MEDLoaderTest4.py) +SET_TESTS_PROPERTIES(MEDLoaderTest4 PROPERTIES LABELS "${COMPONENT_NAME}") + +ADD_TEST(MEDLoaderExamplesTest python MEDLoaderExamplesTest.py) +SET_TESTS_PROPERTIES(MEDLoaderExamplesTest PROPERTIES LABELS "${COMPONENT_NAME}") + +ADD_TEST(SauvLoaderTest python SauvLoaderTest.py) +SET_TESTS_PROPERTIES(SauvLoaderTest PROPERTIES LABELS "${COMPONENT_NAME}") + +# if numpy is used +ADD_TEST(MEDLoaderCouplingTrainingSession python MEDLoaderCouplingTrainingSession.py) +SET_TESTS_PROPERTIES(MEDLoaderCouplingTrainingSession PROPERTIES LABELS "${COMPONENT_NAME}") diff --git a/src/medtool/src/MEDLoader/Swig/CaseIO.py b/src/medtool/src/MEDLoader/Swig/CaseIO.py new file mode 100644 index 000000000..1adece4ed --- /dev/null +++ b/src/medtool/src/MEDLoader/Swig/CaseIO.py @@ -0,0 +1,31 @@ +# -*- coding: iso-8859-1 -*- +# Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 +# 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/DM2S/STMF/LGLS) + +from MEDLoader import * + +class CaseIO: + dictMCTyp={NORM_HEXA8:"hexa8",NORM_POLYHED:"nfaced",NORM_QUAD4:"quad4",NORM_POLYGON:"nsided",NORM_POINT1:"point",NORM_SEG2:"bar2",NORM_SEG3:"bar3",NORM_TRI3:"tria3",NORM_TRI6:"tria6",NORM_QUAD8:"quad8",NORM_TETRA4:"tetra4",NORM_TETRA10:"tetra10",NORM_PYRA5:"pyramid5",NORM_PYRA13:"pyramid13",NORM_PENTA6:"penta6",NORM_PENTA15:"penta15",NORM_HEXA20:"hexa20"} + discSpatial={ON_CELLS:"element",ON_NODES:"node"} + dictCompo={1:"scalar",3:"vector",6:"tensor",9:"tensor9"} + dictMCTyp2=dict((v,k) for k,v in dictMCTyp.iteritems()) + discSpatial2=dict((v,k) for k,v in discSpatial.iteritems()) + dictCompo2=dict((v,k) for k,v in dictCompo.iteritems()) + pass diff --git a/src/medtool/src/MEDLoader/Swig/CaseReader.py b/src/medtool/src/MEDLoader/Swig/CaseReader.py new file mode 100644 index 000000000..7fc267180 --- /dev/null +++ b/src/medtool/src/MEDLoader/Swig/CaseReader.py @@ -0,0 +1,419 @@ +# -*- coding: iso-8859-1 -*- +# Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 +# 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/DM2S/STMF/LGLS) + +# http://www-vis.lbl.gov/NERSC/Software/ensight/doc/OnlineHelp/UM-C11.pdf +import numpy as np +from MEDLoader import * +from CaseIO import CaseIO +import sys,re + +class CaseReader(CaseIO): + """ Converting a file in the Case format (Ensight) to the MED format. + A new file with the same base name and the .med extension is created. + """ + + @classmethod + def New(cls,fileName): + """ Static constructor. """ + return CaseReader(fileName) + pass + + def __init__(self,fileName): + """ Constructor """ + self._fileName=fileName + self._dirName=os.path.dirname(self._fileName) + pass + + def __traduceMesh(self,name,typ,coords,cells): + """ Convert a CASE mesh into a MEDCouplingUMesh. """ + nbCoords=len(coords) + coo=np.array(coords,dtype="float64") ; coo=coo.reshape(nbCoords,3) + coo=DataArrayDouble(coo) ; coo=coo.fromNoInterlace() + ct=self.dictMCTyp2[typ] + m=MEDCouplingUMesh(name,MEDCouplingUMesh.GetDimensionOfGeometricType(ct)) + m.setCoords(coo) + nbNodesPerCell=MEDCouplingMesh.GetNumberOfNodesOfGeometricType(ct) + cI=DataArrayInt(len(cells)+1) ; cI.iota() ; cI*=nbNodesPerCell+1 + # + cells2=cells.reshape(len(cells),nbNodesPerCell) + if cells2.dtype=='int32': + c2=DataArrayInt(cells2) + else: + c2=DataArrayInt(np.array(cells2,dtype="int32")) + pass + c=DataArrayInt(len(cells),nbNodesPerCell+1) ; c[:,0]=ct ; c[:,1:]=c2-1 ; c.rearrange(1) + m.setConnectivity(c,cI,True) + m.checkCoherency2() + return m + + def __traduceMeshForPolyhed(self,name,coords,arr0,arr1,arr2): + nbCoords=len(coords) + coo=np.array(coords,dtype="float64") ; coo=coo.reshape(nbCoords,3) + coo=DataArrayDouble(coo) ; coo=coo.fromNoInterlace() + m=MEDCouplingUMesh(name,3) + m.setCoords(coo) + # + arr2=arr2[:]-1 + arr0mc0=DataArrayInt(arr0) ; arr0mc0.computeOffsets2() + arr0mc1=DataArrayInt(arr0).deepCpy() + arr0mc2=DataArrayInt(len(arr0),2) ; arr0mc2[:,0]=DataArrayInt(arr0)-1 ; arr0mc2[:,1]=1 ; arr0mc2.rearrange(1) ; arr0mc2.computeOffsets2() + arr0mc3=DataArrayInt.Range(0,2*len(arr0),2).buildExplicitArrByRanges(arr0mc2) + arr1mc0=DataArrayInt(arr1) ; arr1mc0.computeOffsets2() + arr1mc1=arr1mc0[arr0mc0] ; arr1mc1[1:]+=arr0mc0[1:] + arr1mc2=DataArrayInt(arr1).deepCpy() ; arr1mc2+=1 ; arr1mc2.computeOffsets2() + arr2mc0=(arr1mc2[1:])[arr0mc3] + # + c=DataArrayInt(arr1.size+arr2.size) + c[arr1mc1[:-1]]=NORM_POLYHED + c[arr2mc0]=-1 + a=arr2mc0.buildUnion(arr1mc1[:-1]).buildComplement(len(c)) + c[a]=DataArrayInt(arr2) + # + m.setConnectivity(c,arr1mc1,True) + m.checkCoherency2() + return m + + def __traduceMeshForPolygon(self,name,coords,arr0,arr1): + nbCoords=len(coords) + coo=np.array(coords,dtype="float64") ; coo=coo.reshape(nbCoords,3) + coo=DataArrayDouble(coo) ; coo=coo.fromNoInterlace() + m=MEDCouplingUMesh(name,2) + m.setCoords(coo) + # + arr0_0=DataArrayInt(arr0+1) ; arr0_0.computeOffsets2() + arr0_1=DataArrayInt(len(arr0),2) ; arr0_1[:,1]=DataArrayInt(arr0) ; arr0_1[:,0]=1 ; arr0_1.rearrange(1) ; arr0_1.computeOffsets2() + arr0_2=DataArrayInt.Range(1,2*len(arr0),2).buildExplicitArrByRanges(arr0_1) + c=DataArrayInt(len(arr0)+len(arr1)) ; c[:]=0 ; c[arr0_0[:-1]]=NORM_POLYGON + c[arr0_2]=DataArrayInt(arr1-1) + # + m.setConnectivity(c,arr0_0,True) + m.checkCoherency2() + return m + + def __convertGeo2MED(self,geoFileName): + """ Convert all the geometry (all the meshes) contained in teh CASE file into MEDCouplingUMesh'es. """ + fd=open(os.path.join(self._dirName,geoFileName),"r+b") ; fd.seek(0,2) ; end=fd.tell() ; fd.seek(0) ; title=fd.read(80) + title=title.strip().lower() + if "binary" not in title: + raise Exception("Error only binary geo files are supported for the moment !") + pass + zeType=True + if "fortran" in title: + mcmeshes=self.__convertGeo2MEDFortran(fd,end) ; zeType=False + else: + mcmeshes=self.__convertGeo2MEDC(fd,end) + # + ms=MEDFileMeshes() + ms.resize(len(mcmeshes)) + for i,m in enumerate(mcmeshes): + mlm=MEDFileUMesh() + mlm.setMeshAtLevel(0,m) + ms.setMeshAtPos(i,mlm) + pass + return mcmeshes,ms,zeType + + def __convertGeo2MEDFortran(self,fd,end): + mcmeshes=[] + fd.read(80) # comment 1 + fd.read(80) # comment 2 + fd.read(80) # node id + fd.read(80) # element id + pos=fd.tell() + elt=fd.read(80) ; elt=elt.strip() ; pos=fd.tell() + mcmeshes2=[] + typ="part" + nbOfTurn=0 + while abs(pos-end)>8 and "part" in typ: + if "part" not in elt: + raise Exception("Error on reading mesh fortran #1 !") + fd.seek(fd.tell()+4)# skip # + tmp=fd.read(80) ; meshName=tmp.split("P")[-1] + tmp=fd.read(80) + if "coordinates" not in tmp: + raise Exception("Error on reading mesh fortran #2 !") + pos=fd.tell() # 644 + if nbOfTurn==0: + pos+=76 # what else ? + else: + pos+=40 + pass + nbNodes=np.memmap(fd,dtype='>i4',mode='r',offset=int(pos),shape=(1,)).tolist()[0] + pos+=12 # what else ? + a=np.memmap(fd,dtype='>f4',mode='r',offset=int(pos),shape=(nbNodes)) + b=np.memmap(fd,dtype='>f4',mode='r',offset=int(pos+nbNodes*4+2*4),shape=(nbNodes)) + c=np.memmap(fd,dtype='>f4',mode='r',offset=int(pos+nbNodes*2*4+4*4),shape=(nbNodes)) + coo=np.zeros(dtype=">f4",shape=(nbNodes*3)) + coo[:nbNodes]=a ; coo[nbNodes:2*nbNodes]=b ; coo[2*nbNodes:]=c + coo=coo.reshape(nbNodes,3) + pos+=nbNodes*3*4 ; fd.seek(pos)#np.array(0,dtype='float%i'%(typeOfCoo)).nbytes + typ=fd.read(80).strip() ; pos=fd.tell() + zeK="" + for k in self.dictMCTyp2.keys(): + if k in typ: + zeK=k + break + pass + pass + pos+=8*4 # yeh man ! + nbCellsOfType=np.memmap(fd,dtype='>i4',mode='r',offset=int(pos),shape=(1,)).tolist()[0] + pos+=4 # for the number of cells + pos+=2*4 # because it's great ! + nbNodesPerCell=MEDCouplingMesh.GetNumberOfNodesOfGeometricType(self.dictMCTyp2[zeK]) + nodalConn=np.memmap(fd,dtype='>i4',mode='r',offset=pos,shape=(nbCellsOfType,nbNodesPerCell)) + meshName=meshName.strip() + mcmeshes2.append(self.__traduceMesh(meshName,zeK,coo,nodalConn)) + pos+=nbNodesPerCell*nbCellsOfType*4 + if abs(pos-end)>8: + fd.seek(pos) ;elt=fd.read(80) ; typ=elt[:] ; pos+=80 + pass + nbOfTurn+=1 + pass + #coo=mcmeshes2[0].getCoords() ; name=mcmeshes2[0].getName() + #for itmesh in mcmeshes2: itmesh.setCoords(coo) + #m=MEDCouplingUMesh.MergeUMeshesOnSameCoords(mcmeshes2) ; m.setName(name) + #mcmeshes.append(m) + return mcmeshes2 + + def __convertGeo2MEDC(self,fd,end): + fd.readline() + name=fd.readline().strip() ; fd.readline() ; fd.readline() + pos=fd.tell() + mcmeshes=[] + elt=fd.read(80) ; elt=elt.strip() ; pos+=80 + while pos!=end: + if "part" not in elt: + raise Exception("Error on reading mesh #1 !") + fd.seek(fd.tell()+4) + meshName=fd.read(80).strip() + if fd.read(len("coordinates"))!="coordinates": + raise Exception("Error on reading mesh #2 !") + pos=fd.tell() + typeOfCoo=np.memmap(fd,dtype='byte',mode='r',offset=int(pos),shape=(1)).tolist()[0] + pos+=1+17*4 + nbNodes=np.memmap(fd,dtype='int32',mode='r',offset=int(pos),shape=(1,)).tolist()[0] + pos+=4 + coo=np.memmap(fd,dtype='float32',mode='r',offset=int(pos),shape=(nbNodes,3)) + pos+=nbNodes*3*4 ; fd.seek(pos)#np.array(0,dtype='float%i'%(typeOfCoo)).nbytes + typ=fd.read(80).strip() ; pos=fd.tell() + mcmeshes2=[] + while pos!=end and typ!="part": + mctyp=self.dictMCTyp2[typ] + nbCellsOfType=np.memmap(fd,dtype='int32',mode='r',offset=int(pos),shape=(1,)).tolist()[0] + pos+=4 + if mctyp!=NORM_POLYHED and mctyp!=NORM_POLYGON: + nbNodesPerCell=MEDCouplingMesh.GetNumberOfNodesOfGeometricType(mctyp) + cells=np.memmap(fd,dtype='int32',mode='r',offset=pos,shape=(nbCellsOfType,nbNodesPerCell)) + pos+=nbCellsOfType*nbNodesPerCell*4 + fd.seek(pos) + mcmeshes2.append(self.__traduceMesh(meshName,typ,coo,cells)) + elif mctyp==NORM_POLYHED: + nbOfFacesPerCell=np.memmap(fd,dtype='int32',mode='r',offset=int(pos),shape=(nbCellsOfType,)) + pos+=nbCellsOfType*4 + szOfNbOfNodesPerFacePerCellArr=int(nbOfFacesPerCell.sum()) + arr1=np.memmap(fd,dtype='int32',mode='r',offset=int(pos),shape=(szOfNbOfNodesPerFacePerCellArr,))#arr1 -> nbOfNodesPerFacePerCellArr + pos+=szOfNbOfNodesPerFacePerCellArr*4 + szOfNodesPerFacePerCellArr=arr1.sum() + arr2=np.memmap(fd,dtype='int32',mode='r',offset=int(pos),shape=(szOfNodesPerFacePerCellArr,))#arr2 -> nodesPerFacePerCellArr + pos+=szOfNodesPerFacePerCellArr*4 ; fd.seek(pos) + mcmeshes2.append(self.__traduceMeshForPolyhed(meshName,coo,nbOfFacesPerCell,arr1,arr2)) + pass + else: + nbOfNodesPerCell=np.memmap(fd,dtype='int32',mode='r',offset=int(pos),shape=(nbCellsOfType,)) + pos+=nbCellsOfType*4 + szOfNbOfNodesPerCellArr=int(nbOfNodesPerCell.sum()) + arr1=np.memmap(fd,dtype='int32',mode='r',offset=int(pos),shape=(szOfNbOfNodesPerCellArr,)) + pos+=szOfNbOfNodesPerCellArr*4 ; fd.seek(pos) + mcmeshes2.append(self.__traduceMeshForPolygon(meshName,coo,nbOfNodesPerCell,arr1)) + if pos!=end: + elt=fd.read(80) ; elt=elt.strip() ; typ=elt[:] ; pos+=80 + pass + pass + coo=mcmeshes2[0].getCoords() ; name=mcmeshes2[0].getName() + for itmesh in mcmeshes2: itmesh.setCoords(coo) + m=MEDCouplingUMesh.MergeUMeshesOnSameCoords(mcmeshes2) ; m.setName(name) + mcmeshes.append(m) + pass + return mcmeshes + + + def __convertField(self,mlfields, mcmeshes, fileName, fieldName, discr, nbCompo, locId, it): + """ Convert the fields. """ + stars=re.search("[\*]+",fileName).group() + st="%0"+str(len(stars))+"i" + trueFileName=fileName.replace(stars,st%(it)) + fd=open(os.path.join(self._dirName,trueFileName),"r+b") ; fd.seek(0,2) ; end=fd.tell() ; fd.seek(0) + name=fd.readline().strip().split(" ")[0] + if name!=fieldName: + raise Exception("ConvertField : mismatch") + pos=fd.tell() + st=fd.read(80) ; st=st.strip() ; pos=fd.tell() + while pos!=end: + if st!="part": + raise Exception("ConvertField : mismatch #2") + fdisc=MEDCouplingFieldDiscretization.New(self.discSpatial2[discr]) + meshId=np.memmap(fd,dtype='int32',mode='r',offset=int(pos),shape=(1)).tolist()[0]-1 + nbOfValues=fdisc.getNumberOfTuples(mcmeshes[meshId]) + vals2=DataArrayDouble(nbOfValues,nbCompo) + fd.seek(pos+4) + st=fd.read(80).strip() ; pos=fd.tell() + offset=0 + while pos!=end and st!="part": + if st!="coordinates": + nbOfValsOfTyp=mcmeshes[meshId].getNumberOfCellsWithType(self.dictMCTyp2[st]) + else: + nbOfValsOfTyp=nbOfValues + pass + vals=np.memmap(fd,dtype='float32',mode='r',offset=int(pos),shape=(nbOfValsOfTyp,nbCompo))#np.memmap(fd,dtype='int32',mode='r',offset=159,shape=(1)) + vals2[offset:offset+nbOfValsOfTyp]=DataArrayDouble(np.array(vals,dtype='float64')).fromNoInterlace() + pos+=nbOfValsOfTyp*nbCompo*4 ; fd.seek(pos) + st=fd.read(80) ; st=st.strip() ; pos=fd.tell() + offset+=nbOfValsOfTyp + pass + f=MEDCouplingFieldDouble(self.discSpatial2[discr],ONE_TIME) ; f.setName("%s_%s"%(fieldName,mcmeshes[meshId].getName())) + f.setMesh(mcmeshes[meshId]) ; f.setArray(vals2) ; f.setTime(float(it),it,-1) + f.checkCoherency() + mlfields[locId+meshId].appendFieldNoProfileSBT(f) + pass + + def __convertFieldFortran(self,mlfields, mcmeshes, fileName, fieldName, discr, nbCompo, locId, it): + """ Convert the fields. """ + if re.search("[\*]+",fileName): + stars=re.search("[\*]+",fileName).group() + st="%0"+str(len(stars))+"i" + trueFileName=fileName.replace(stars,st%(it)) + pass + else: + trueFileName=fileName + pass + fd=open(os.path.join(self._dirName,trueFileName),"r+b") ; fd.seek(0,2) ; end=fd.tell() ; fd.seek(0) + name=fd.read(80) + if fieldName not in name: + raise Exception("ConvertField : mismatch") + pos=fd.tell() + st=fd.read(80) ; st=st.strip() ; pos=fd.tell() + if "part" not in st: + raise Exception("ConvertField : mismatch #2") + st=fd.read(80).strip() ; pos=fd.tell() + pos+=12 # I love it + offset=0 + nbTurn=0 + while pos!=end and "part" not in st: + fdisc=MEDCouplingFieldDiscretization.New(self.discSpatial2[discr]) + nbOfValues=fdisc.getNumberOfTuples(mcmeshes[nbTurn]) + vals2=DataArrayDouble(nbOfValues,nbCompo) + pos+=24 # I love it again ! + nbOfValsOfTyp=np.memmap(fd,dtype='>i4',mode='r',offset=pos,shape=(1)).tolist()[0]/4 + pos+=4 + vals=np.zeros(dtype=">f4",shape=(nbOfValsOfTyp*nbCompo)) + for iii in xrange(nbCompo): + valsTmp=np.memmap(fd,dtype='>f4',mode='r',offset=int(pos),shape=(nbOfValsOfTyp)) + vals[iii*nbOfValsOfTyp:(iii+1)*nbOfValsOfTyp]=valsTmp + pos+=nbOfValsOfTyp*4 + pos+=2*4 ## hey hey, that is the ultimate class ! + vals2.setInfoOnComponent(iii,chr(ord('X')+iii)) + pass + if pos>end: + pos=end + pass + vals=vals.reshape(nbOfValsOfTyp,nbCompo) + vals2[offset:offset+nbOfValsOfTyp]=DataArrayDouble(np.array(vals,dtype='float64')).fromNoInterlace() + if pos!=end: + fd.seek(pos) + st=fd.read(80) ; st=st.strip() ; pos=fd.tell() + st=fd.read(80) ; st=st.strip() ; pos=fd.tell() + pass + f=MEDCouplingFieldDouble(self.discSpatial2[discr],ONE_TIME) ; f.setName("%s_%s"%(fieldName,mcmeshes[nbTurn].getName())) + f.setMesh(mcmeshes[nbTurn]) ; f.setArray(vals2) ; f.setTime(float(it),it,-1) + f.checkCoherency() + mlfields[locId+nbTurn].appendFieldNoProfileSBT(f) + nbTurn+=1 + pass + pass + + def loadInMEDFileDS(self): + """ Load a CASE file into a MEDFileData object. """ + f=file(self._fileName) + lines=f.readlines() + ind=lines.index("GEOMETRY\n") + if ind==-1: + raise Exception("Error with file %s"%(fname)) + geoName=re.match("model:([\W]*)([\w\.]+)",lines[ind+1]).group(2) + m1,m2,typeOfFile=self.__convertGeo2MED(geoName) + fieldsInfo=[] ; nbOfTimeSteps=0 + if "VARIABLE\n" in lines: + ind=lines.index("VARIABLE\n") + end=len(lines)-1 + if "TIME\n" in lines: + end=lines.index("TIME\n") + pass + for i in xrange(ind+1,end): + m=re.match("^([\w]+)[\s]+\per[\s]+([\w]+)[\s]*\:[\s]*([\w]+)[\s]+([\S]+)$",lines[i]) + if m: + if m.groups()[0]=="constant": + continue + spatialDisc=m.groups()[1] ; fieldName=m.groups()[2] ; nbOfCompo=self.dictCompo2[m.groups()[0]] ; fieldFileName=m.groups()[3] + fieldsInfo.append((fieldName,spatialDisc,nbOfCompo,fieldFileName)) + pass + pass + + expr=re.compile("number[\s]+of[\s]+steps[\s]*\:[\s]*([\d]+)") + tmp=filter(expr.search,lines) + if len(tmp)!=0: + nbOfTimeSteps=int(expr.search(filter(expr.search,lines)[0]).group(1)) + expr=re.compile("filename[\s]+start[\s]+number[\s]*\:[\s]*([\d]+)") + startIt=int(expr.search(filter(expr.search,lines)[0]).group(1)) + expr=re.compile("filename[\s]+increment[\s]*\:[\s]*([\d]+)") + incrIt=int(expr.search(filter(expr.search,lines)[0]).group(1)) + else: + nbOfTimeSteps=1 + startIt=0 + incrIt=1 + pass + curIt=startIt + pass + mlfields=MEDFileFields() + mlfields.resize(len(fieldsInfo)*len(m1)) + i=0 + for field in fieldsInfo: + for m in m1: + mlfields.setFieldAtPos(i,MEDFileFieldMultiTS()) + i+=1 + pass + pass + for ts in xrange(nbOfTimeSteps): + i=0 + for field in fieldsInfo: + if typeOfFile: + self.__convertField(mlfields,m1,field[3],field[0],field[1],field[2],i,curIt); + else: + self.__convertFieldFortran(mlfields,m1,field[3],field[0],field[1],field[2],i,curIt) + pass + i+=len(m1) + pass + curIt+=incrIt + pass + ret=MEDFileData() + ret.setMeshes(m2) + del mlfields[filter(lambda x: len(mlfields[x])==0,range(len(mlfields)))] + ret.setFields(mlfields) + return ret + + pass diff --git a/src/medtool/src/MEDLoader/Swig/CaseWriter.py b/src/medtool/src/MEDLoader/Swig/CaseWriter.py new file mode 100644 index 000000000..73112ad65 --- /dev/null +++ b/src/medtool/src/MEDLoader/Swig/CaseWriter.py @@ -0,0 +1,349 @@ +# -*- coding: iso-8859-1 -*- +# Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 +# 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/DM2S/STMF/LGLS) + +import numpy as np +from CaseIO import CaseIO +from MEDLoader import * +import sys,re,os,mmap + +### www-vis.lbl.gov/NERSC/Software/ensight/doc/OnlineHelp/UM-C11.pdf + +class CaseWriter(CaseIO): + """ Converting MED file format in memory to a the Case file format (Ensight). + A new file with the same base name and the .case extension is created with its depencies (.geo ...). + """ + + header="""FORMAT +type: ensight gold +GEOMETRY +model: %(geofilewithoutpath)s +""" + header_varpart="""VARIABLE""" + header_timepart="""TIME +time set: 1 +number of steps: %(NbTimeSteps)i +filename start number: 0 +filename increment: 1 +time values: +%(TimeValues)s +""" + + @classmethod + def New(cls): + """ Static constructor. """ + return CaseWriter() + pass + + def __init__(self): + """ Constructor """ + self.__export_groups=False + pass + + def setMEDFileDS(self,medData): + """ Input should be MEDFileData instance """ + self._med_data=medData + pass + + def isExportingGroups(self): + """ return the status of exporting groups policy """ + return self.__export_groups + + def setExportingGroups(self,status): + assert(isinstance(status,bool)) + self.__export_groups=status + pass + + + def write(self,fileName): + """ Write into the specified fileName series the result """ + self._file_name=fileName + self._base_name_without_dir=os.path.splitext(os.path.basename(self._file_name))[0] + self._l=self._file_name.split(os.path.sep) ; self._l[-1]=os.path.splitext(self._l[-1])[0] + self._base_name_with_dir=os.path.sep.join(self._l) + self._real_written_file_name=[] + self._dico={} + for mesh in self._med_data.getMeshes(): + additionnalFileNamePart="" + if len(self._med_data.getMeshes())!=1: + additionnalFileNamePart="_%s"%(mesh.getName()) + pass + self._dico["geofilewithoutpath"]="%s%s.geo"%(self._base_name_without_dir,additionnalFileNamePart) + h0=self.header%self._dico + self.__writeMeshesPart(mesh,"%s%s.geo"%(self._base_name_with_dir,additionnalFileNamePart)) + # + h2=self.__writeFieldsPart(self._med_data.getFields().partOfThisLyingOnSpecifiedMeshName(mesh.getName())) + realWrittenCaseFileNameForCurMesh="%s%s.case"%(self._base_name_with_dir,additionnalFileNamePart) + fheader=open(realWrittenCaseFileNameForCurMesh,"w") ; fheader.write((h0+h2)%self._dico) + self._real_written_file_name.append(realWrittenCaseFileNameForCurMesh) + pass + return self._real_written_file_name + + def __writeMeshesPart(self,mdm,meshfn): + try: + os.remove(meshfn) + except: + pass + f=open(meshfn,"w+b") + sz=5*80 + # + assert(isinstance(mdm,MEDFileUMesh)) + ms2=[[mdm.getMeshAtLevel(lev) for lev in mdm.getNonEmptyLevels()[:1]]] + if self.__export_groups: + for grpnm in mdm.getGroupsNames(): + ms3=[] + for lev in mdm.getGrpNonEmptyLevels(grpnm)[:1]: + m=mdm.getGroup(lev,grpnm) ; m.zipCoords() + ms3.append(m) + pass + ms2.append(ms3) + pass + pass + for ms in ms2: + nn=ms[0].getNumberOfNodes() + sz+=self.__computeSizeOfGeoFile(ms,nn) + pass + pass + a=np.memmap(f,dtype='byte',mode='w+',offset=0,shape=(sz,)) ; a.flush() # truncate to set the size of the file + mm=mmap.mmap(f.fileno(),offset=0,length=0) + mm.write(self.__str80("C Binary")) + mm.write(self.__str80("Exported from MEDCoupling/MEDLoader SALOME version %s"%(MEDCouplingVersionStr()))) + mm.write(self.__str80("Conversion using CaseWriter class")) + mm.write(self.__str80("node id off")) + mm.write(self.__str80("element id off")) + for iii,ms in enumerate(ms2): + nn=ms[0].getNumberOfNodes() + mm.write(self.__str80("part")) + a=np.memmap(f,dtype='int32',mode='w+',offset=mm.tell(),shape=(1,)) + a[0]=iii+1 ; a.flush() ; mm.seek(mm.tell()+4) # part number maybe to change ? + name=ms[0].getName() + if iii>0: + name="%s_%s"%(ms2[0][0].getName(),name) + pass + mm.write(self.__str80(name)) + mm.write(self.__str80("coordinates")) + a=np.memmap(f,dtype='int32',mode='w+',offset=mm.tell(),shape=(1,)) + a[0]=nn ; a.flush() # number of nodes + mm.seek(mm.tell()+4) + coo=ms[0].getCoords() + spaceDim=coo.getNumberOfComponents() + if spaceDim!=3: + coo=coo.changeNbOfComponents(3,0.) + pass + a=np.memmap(f,dtype='float32',mode='w+',offset=mm.tell(),shape=(3,nn)) + c=coo.toNoInterlace() ; c.rearrange(1) ; cnp=c.toNumPyArray() ; cnp=cnp.reshape(3,nn) + a[:]=cnp ; a.flush() ; mm.seek(mm.tell()+3*nn*4) + for m in ms: + i=0 + for typ2,nbelem,dummy in m.getDistributionOfTypes(): + typ=typ2 + if typ not in self.dictMCTyp: + typ=MEDCouplingMesh.GetCorrespondingPolyType(typ) + pass + mp=m[i:i+nbelem] + mm.write(self.__str80(self.dictMCTyp[typ])) + a=np.memmap(f,dtype='int32',mode='w+',offset=mm.tell(),shape=(1,)) + a[0]=nbelem ; a.flush() ; mm.seek(mm.tell()+4) + if typ!=NORM_POLYHED and typ!=NORM_POLYGON: + nbNodesPerElem=MEDCouplingMesh.GetNumberOfNodesOfGeometricType(typ) + c=mp.getNodalConnectivity() ; c.rearrange(nbNodesPerElem+1) ; c=c[:,1:] ; c.rearrange(1) ; c+=1 + a=np.memmap(f,dtype='int32',mode='w+',offset=mm.tell(),shape=(nbNodesPerElem*nbelem,)) + a[:]=c.toNumPyArray() ; a.flush() ; mm.seek(mm.tell()+nbNodesPerElem*nbelem*4) + pass + elif typ==NORM_POLYHED: + mp.orientCorrectlyPolyhedrons() + c=mp.computeNbOfFacesPerCell() + a=np.memmap(f,dtype='int32',mode='w+',offset=mm.tell(),shape=(nbelem,)) + a[:]=c.toNumPyArray(); a.flush() ; mm.seek(mm.tell()+nbelem*4) + c=mp.getNodalConnectivity()[:] ; c.pushBackSilent(-1) ; c[mp.getNodalConnectivityIndex()[:-1]]=-1 ; ids=c.getIdsEqual(-1) ; nbOfNodesPerFace=ids.deltaShiftIndex()-1 + a=np.memmap(f,dtype='int32',mode='w+',offset=mm.tell(),shape=(len(nbOfNodesPerFace),)) + a[:]=nbOfNodesPerFace.toNumPyArray() ; a.flush() ; mm.seek(mm.tell()+len(nbOfNodesPerFace)*4) + ids2=ids.buildComplement(ids.back()+1) + c2=mp.getNodalConnectivity()[ids2]+1 + a=np.memmap(f,dtype='int32',mode='w+',offset=mm.tell(),shape=(len(c2),)) + a[:]=c2.toNumPyArray() ; a.flush() ; mm.seek(mm.tell()+len(c2)*4) + pass + else: + nbOfNodesPerCell=mp.getNodalConnectivityIndex().deltaShiftIndex()-1 + a=np.memmap(f,dtype='int32',mode='w+',offset=mm.tell(),shape=(len(nbOfNodesPerCell),)) + a[:]=nbOfNodesPerCell.toNumPyArray() ; a.flush() ; mm.seek(mm.tell()+len(nbOfNodesPerCell)*4) + ids2=mp.getNodalConnectivityIndex().buildComplement(mp.getNodalConnectivityIndex().back()+1) + c2=mp.getNodalConnectivity()[ids2]+1 + a=np.memmap(f,dtype='int32',mode='w+',offset=mm.tell(),shape=(len(c2),)) + a[:]=c2.toNumPyArray() ; a.flush() ; mm.seek(mm.tell()+len(c2)*4) + pass + i+=nbelem + pass + pass + pass + pass + + def __writeFieldsPart(self,mdfs): + if not mdfs: + return "" + self._ze_top_dict={} + its,areForgottenTS=mdfs.getCommonIterations() + if areForgottenTS: + print "WARNING : some iterations are NOT present in all fields ! Kept iterations are : %s !"%(str(its)) + pass + TimeValues="" + for it in its: + TimeValues+="%s\n"%(str(mdfs[0][it].getTime()[-1])) + pass + dictVars={} + for mdf in mdfs: + nbCompo=mdf.getNumberOfComponents() + if nbCompo not in self.dictCompo: + l=filter(lambda x:x-nbCompo>0,self.dictCompo.keys()) + if len(l)==0: + print "Field \"%s\" will be ignored because number of components (%i) is too big to be %s supported by case files !"%(mdf.getName(),nbCompo,str(self.dictCompo.keys())) + continue + pass + print "WARNING : Field \"%s\" will have its number of components (%i) set to %i, in order to be supported by case files (must be in %s) !"%(mdf.getName(),nbCompo,l[0],str(self.dictCompo.keys())) + nbCompo=l[0] + pass + if nbCompo in dictVars: + dictVars[nbCompo].append(mdf) + pass + else: + dictVars[nbCompo]=[mdf] + pass + pass + for mdf in mdfs: + nbCompo=mdf.getNumberOfComponents() + if nbCompo not in self.dictCompo: + l=filter(lambda x:x-nbCompo>0,self.dictCompo.keys()) + if len(l)==0: + continue; + nbCompo=l[0] + pass + for iii,it in enumerate(its): + ff=mdf[it] + isMultiDisc=len(ff.getTypesOfFieldAvailable())>1 + for typ in ff.getTypesOfFieldAvailable(): + l=self._l[:] ; l[-1]="%s%s.%s"%(self._base_name_without_dir,str(iii).rjust(4,"0"),ff.getName()) + if isMultiDisc: + l[-1]="%s_%s"(l[-1],MEDCouplingFieldDiscretization.New(typ).getStringRepr()) + pass + fffn=l[-1] + try: + os.remove(os.path.sep.join(l)) + except: + pass + f=open(os.path.sep.join(l),"w+b") + summ=0 + for geo,[(curTyp,(bg,end),pfl,loc)] in ff.getFieldSplitedByType(): + if typ==curTyp: + summ+=4*nbCompo*(end-bg)+80 + pass + pass + a=np.memmap(f,dtype='byte',mode='w+',offset=0,shape=(2*80+4+summ,)) ; a.flush() # truncate to set the size of the file + mm=mmap.mmap(f.fileno(),offset=0,length=0) + k1=ff.getName() + if isMultiDisc: + k1="%s_%s"%(k1,MEDCouplingFieldDiscretization.New(typ).getStringRepr()) + pass + mm.write(self.__str80(k1)) + mm.write(self.__str80("part")) + a=np.memmap(f,dtype='int32',mode='w+',offset=mm.tell(),shape=(1,)) + a[0]=1 ; a.flush() ; mm.seek(mm.tell()+4) # part number maybe to change ? + for geo,[(curTyp,(bg,end),pfl,loc)] in ff.getFieldSplitedByType(): + if pfl!="": + raise Exception("Field \"%s\" contains profiles ! Profiles are not supported yet !"%(mdf.getName())) + if typ==curTyp: + arr=ff.getUndergroundDataArray()[bg:end].changeNbOfComponents(nbCompo,0.) ; arr=arr.toNoInterlace() + if typ==ON_CELLS: + mm.write(self.__str80(self.dictMCTyp[geo])) + pass + elif typ==ON_NODES: + mm.write(self.__str80("coordinates")) + pass + else: + print "UnManaged type of field for field \"%s\" !"%(mdf.getName()) + pass + a=np.memmap(f,dtype='float32',mode='w+',offset=mm.tell(),shape=(nbCompo,end-bg)) + b=arr.toNumPyArray() ; b=b.reshape(nbCompo,end-bg) + a[:]=b + a.flush() ; mm.seek(mm.tell()+nbCompo*(end-bg)*4) + pass + pass + k="%s per %s"%(self.dictCompo[nbCompo],self.discSpatial[typ]) + if k in self._ze_top_dict: + if k1 in self._ze_top_dict[k]: + self._ze_top_dict[k][k1].append(fffn) + pass + else: + self._ze_top_dict[k][k1]=[fffn] + pass + else: + self._ze_top_dict[k]={k1:[fffn]} + pass + pass + pass + pass + headerPart="" + if len(self._ze_top_dict)!=0: + hvp=self.header_varpart[:] + for k in self._ze_top_dict: + for k1 in self._ze_top_dict[k]: + hvp+="\n%s: %s %s"%(k,k1,re.sub("([\d]{4})",4*"*",self._ze_top_dict[k][k1][0])) + pass + pass + hvp+="\n" + headerPart+=hvp + # + ddd={"NbTimeSteps":len(its),"TimeValues":TimeValues} + htp=self.header_timepart%ddd + headerPart+=htp + pass + return headerPart + + @classmethod + def __str80(cls,st): + if len(st)>79: + raise Exception("String \"%s\" is too long (>79) !"%(st)) + return st.ljust(79)+"\n" + + def __computeSizeOfGeoFile(self,listOfMeshes,nn): + sz=0 + for m in listOfMeshes: + distribTypes=m.getDistributionOfTypes() + sz+=80+4+2*80+4+nn*3*4 + i=0 + for typ2,nbelem,dummy in distribTypes: + typ=typ2 + if typ not in self.dictMCTyp: + typ=MEDCouplingMesh.GetCorrespondingPolyType() + pass + if typ!=NORM_POLYHED and typ!=NORM_POLYGON: + sz+=80+4+MEDCouplingMesh.GetNumberOfNodesOfGeometricType(typ)*nbelem*4 + pass + elif typ==NORM_POLYHED: + mplh=m[i:i+nbelem] ; delta=len(mplh.getNodalConnectivity())+nbelem + sz+=80+4+delta*4 + pass + else: + mplh=m[i:i+nbelem] ; delta=len(mplh.getNodalConnectivity()) + sz+=80+4+delta*4 + pass + i+=nbelem + pass + pass + return sz diff --git a/src/medtool/src/MEDLoader/Swig/MEDLoader.i b/src/medtool/src/MEDLoader/Swig/MEDLoader.i new file mode 100644 index 000000000..d85b63816 --- /dev/null +++ b/src/medtool/src/MEDLoader/Swig/MEDLoader.i @@ -0,0 +1,148 @@ +// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 +// 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 "MEDLoaderCommon.i" + +%pythoncode %{ +def ParaMEDMEMDataArrayDoublenew(cls,*args): + import _MEDLoader + return _MEDLoader.DataArrayDouble____new___(cls,args) +def ParaMEDMEMDataArrayDoubleIadd(self,*args): + import _MEDLoader + return _MEDLoader.DataArrayDouble____iadd___(self, self, *args) +def ParaMEDMEMDataArrayDoubleIsub(self,*args): + import _MEDLoader + return _MEDLoader.DataArrayDouble____isub___(self, self, *args) +def ParaMEDMEMDataArrayDoubleImul(self,*args): + import _MEDLoader + return _MEDLoader.DataArrayDouble____imul___(self, self, *args) +def ParaMEDMEMDataArrayDoubleIdiv(self,*args): + import _MEDLoader + return _MEDLoader.DataArrayDouble____idiv___(self, self, *args) +def ParaMEDMEMDataArrayDoubleIpow(self,*args): + import _MEDLoader + return _MEDLoader.DataArrayDouble____ipow___(self, self, *args) +def ParaMEDMEMMEDCouplingFieldDoublenew(cls,*args): + import _MEDLoader + return _MEDLoader.MEDCouplingFieldDouble____new___(cls,args) +def ParaMEDMEMMEDCouplingFieldDoubleIadd(self,*args): + import _MEDLoader + return _MEDLoader.MEDCouplingFieldDouble____iadd___(self, self, *args) +def ParaMEDMEMMEDCouplingFieldDoubleIsub(self,*args): + import _MEDLoader + return _MEDLoader.MEDCouplingFieldDouble____isub___(self, self, *args) +def ParaMEDMEMMEDCouplingFieldDoubleImul(self,*args): + import _MEDLoader + return _MEDLoader.MEDCouplingFieldDouble____imul___(self, self, *args) +def ParaMEDMEMMEDCouplingFieldDoubleIdiv(self,*args): + import _MEDLoader + return _MEDLoader.MEDCouplingFieldDouble____idiv___(self, self, *args) +def ParaMEDMEMMEDCouplingFieldDoubleIpow(self,*args): + import _MEDLoader + return _MEDLoader.MEDCouplingFieldDouble____ipow___(self, self, *args) +def ParaMEDMEMDataArrayIntnew(cls,*args): + import _MEDLoader + return _MEDLoader.DataArrayInt____new___(cls,args) +def ParaMEDMEMDataArrayIntIadd(self,*args): + import _MEDLoader + return _MEDLoader.DataArrayInt____iadd___(self, self, *args) +def ParaMEDMEMDataArrayIntIsub(self,*args): + import _MEDLoader + return _MEDLoader.DataArrayInt____isub___(self, self, *args) +def ParaMEDMEMDataArrayIntImul(self,*args): + import _MEDLoader + return _MEDLoader.DataArrayInt____imul___(self, self, *args) +def ParaMEDMEMDataArrayIntIdiv(self,*args): + import _MEDLoader + return _MEDLoader.DataArrayInt____idiv___(self, self, *args) +def ParaMEDMEMDataArrayIntImod(self,*args): + import _MEDLoader + return _MEDLoader.DataArrayInt____imod___(self, self, *args) +def ParaMEDMEMDataArrayIntIpow(self,*args): + import _MEDLoader + return _MEDLoader.DataArrayInt____ipow___(self, self, *args) +def ParaMEDMEMDataArrayDoubleTupleIadd(self,*args): + import _MEDLoader + return _MEDLoader.DataArrayDoubleTuple____iadd___(self, self, *args) +def ParaMEDMEMDataArrayDoubleTupleIsub(self,*args): + import _MEDLoader + return _MEDLoader.DataArrayDoubleTuple____isub___(self, self, *args) +def ParaMEDMEMDataArrayDoubleTupleImul(self,*args): + import _MEDLoader + return _MEDLoader.DataArrayDoubleTuple____imul___(self, self, *args) +def ParaMEDMEMDataArrayDoubleTupleIdiv(self,*args): + import _MEDLoader + return _MEDLoader.DataArrayDoubleTuple____idiv___(self, self, *args) +def ParaMEDMEMDataArrayIntTupleIadd(self,*args): + import _MEDLoader + return _MEDLoader.DataArrayIntTuple____iadd___(self, self, *args) +def ParaMEDMEMDataArrayIntTupleIsub(self,*args): + import _MEDLoader + return _MEDLoader.DataArrayIntTuple____isub___(self, self, *args) +def ParaMEDMEMDataArrayIntTupleImul(self,*args): + import _MEDLoader + return _MEDLoader.DataArrayIntTuple____imul___(self, self, *args) +def ParaMEDMEMDataArrayIntTupleIdiv(self,*args): + import _MEDLoader + return _MEDLoader.DataArrayIntTuple____idiv___(self, self, *args) +def ParaMEDMEMDataArrayIntTupleImod(self,*args): + import _MEDLoader + return _MEDLoader.DataArrayIntTuple____imod___(self, self, *args) +def ParaMEDMEMDenseMatrixIadd(self,*args): + import _MEDLoader + return _MEDLoader.DenseMatrix____iadd___(self, self, *args) +def ParaMEDMEMDenseMatrixIsub(self,*args): + import _MEDLoader + return _MEDLoader.DenseMatrix____isub___(self, self, *args) +def ParaMEDMEMMEDCouplingUMeshnew(cls,*args): + import _MEDLoader + return _MEDLoader.MEDCouplingUMesh____new___(cls,args) +def ParaMEDMEMMEDCoupling1DGTUMeshnew(cls,*args): + import _MEDLoader + return _MEDLoader.MEDCoupling1DGTUMesh____new___(cls,args) +def ParaMEDMEMMEDCoupling1SGTUMeshnew(cls,*args): + import _MEDLoader + return _MEDLoader.MEDCoupling1SGTUMesh____new___(cls,args) +def ParaMEDMEMMEDCouplingCurveLinearMeshnew(cls,*args): + import _MEDLoader + return _MEDLoader.MEDCouplingCurveLinearMesh____new___(cls,args) +def ParaMEDMEMMEDCouplingCMeshnew(cls,*args): + import _MEDLoader + return _MEDLoader.MEDCouplingCMesh____new___(cls,args) +def ParaMEDMEMMEDCouplingIMeshnew(cls,*args): + import _MEDLoader + return _MEDLoader.MEDCouplingIMesh____new___(cls,args) +def ParaMEDMEMMEDCouplingExtrudedMeshnew(cls,*args): + import _MEDLoader + return _MEDLoader.MEDCouplingExtrudedMesh____new___(cls,args) +%} + +%pythoncode %{ +def ParaMEDMEMMEDFileUMeshnew(cls,*args): + import _MEDLoader + return _MEDLoader.MEDFileUMesh____new___(cls,args) +%} + +%include "MEDCouplingFinalize.i" + +%pythoncode %{ +MEDFileUMesh.__new__=classmethod(ParaMEDMEMMEDFileUMeshnew) +del ParaMEDMEMMEDFileUMeshnew +%} diff --git a/src/medtool/src/MEDLoader/Swig/MEDLoaderCommon.i b/src/medtool/src/MEDLoader/Swig/MEDLoaderCommon.i new file mode 100644 index 000000000..85d65699b --- /dev/null +++ b/src/medtool/src/MEDLoader/Swig/MEDLoaderCommon.i @@ -0,0 +1,3529 @@ +// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 +// 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) + +%module MEDLoader + +#define MEDCOUPLING_EXPORT +#define MEDLOADER_EXPORT + +#ifdef WITH_DOCSTRINGS +%include "MEDLoader_doc.i" +#endif + +%include "MEDCouplingCommon.i" + +%{ +#include "MEDLoader.hxx" +#include "MEDFileJoint.hxx" +#include "MEDFileMesh.hxx" +#include "MEDFileField.hxx" +#include "MEDFileParameter.hxx" +#include "MEDFileData.hxx" +#include "MEDFileMeshReadSelector.hxx" +#include "MEDFileFieldOverView.hxx" +#include "MEDLoaderTypemaps.i" +#include "SauvReader.hxx" +#include "SauvWriter.hxx" + +using namespace ParaMEDMEM; +%} + +#if SWIG_VERSION >= 0x010329 +%template() std::vector<std::string>; +#endif + +%typemap(out) ParaMEDMEM::MEDFileMesh* +{ + $result=convertMEDFileMesh($1,$owner); +} + +%typemap(out) ParaMEDMEM::MEDFileParameter1TS* +{ + $result=convertMEDFileParameter1TS($1,$owner); +} + +%typemap(out) ParaMEDMEM::MEDFileAnyTypeFieldMultiTS* +{ + $result=convertMEDFileFieldMultiTS($1,$owner); +} + +%typemap(out) ParaMEDMEM::MEDFileAnyTypeField1TS* +{ + $result=convertMEDFileField1TS($1,$owner); +} + +%typemap(out) ParaMEDMEM::MEDMeshMultiLev* +{ + $result=convertMEDMeshMultiLev($1,$owner); +} + +%newobject MEDLoader::ReadUMeshFromFamilies; +%newobject MEDLoader::ReadUMeshFromGroups; +%newobject MEDLoader::ReadUMeshFromFile; +%newobject MEDLoader::ReadMeshFromFile; +%newobject MEDLoader::ReadField; +%newobject MEDLoader::ReadFieldCell; +%newobject MEDLoader::ReadFieldNode; +%newobject MEDLoader::ReadFieldGauss; +%newobject MEDLoader::ReadFieldGaussNE; +%newobject ParaMEDMEM::MEDFileMesh::New; +%newobject ParaMEDMEM::MEDFileMesh::createNewEmpty; +%newobject ParaMEDMEM::MEDFileMesh::deepCpy; +%newobject ParaMEDMEM::MEDFileMesh::shallowCpy; +%newobject ParaMEDMEM::MEDFileMesh::getGenMeshAtLevel; +%newobject ParaMEDMEM::MEDFileMesh::__getitem__; +%newobject ParaMEDMEM::MEDFileMesh::getGroupArr; +%newobject ParaMEDMEM::MEDFileMesh::getGroupsArr; +%newobject ParaMEDMEM::MEDFileMesh::getFamilyArr; +%newobject ParaMEDMEM::MEDFileMesh::getFamiliesArr; +%newobject ParaMEDMEM::MEDFileMesh::getNodeGroupArr; +%newobject ParaMEDMEM::MEDFileMesh::getNodeGroupsArr; +%newobject ParaMEDMEM::MEDFileMesh::getNodeFamilyArr; +%newobject ParaMEDMEM::MEDFileMesh::getNodeFamiliesArr; +%newobject ParaMEDMEM::MEDFileMesh::getAllFamiliesIdsReferenced; +%newobject ParaMEDMEM::MEDFileMesh::computeAllFamilyIdsInUse; +%newobject ParaMEDMEM::MEDFileData::getJoints; +%newobject ParaMEDMEM::MEDFileStructuredMesh::getImplicitFaceMesh; +%newobject ParaMEDMEM::MEDFileUMesh::New; +%newobject ParaMEDMEM::MEDFileUMesh::LoadPartOf; +%newobject ParaMEDMEM::MEDFileUMesh::getCoords; +%newobject ParaMEDMEM::MEDFileUMesh::getPartDefAtLevel; +%newobject ParaMEDMEM::MEDFileUMesh::getGroup; +%newobject ParaMEDMEM::MEDFileUMesh::getGroups; +%newobject ParaMEDMEM::MEDFileUMesh::getFamily; +%newobject ParaMEDMEM::MEDFileUMesh::getFamilies; +%newobject ParaMEDMEM::MEDFileUMesh::getMeshAtLevel; +%newobject ParaMEDMEM::MEDFileUMesh::getLevel0Mesh; +%newobject ParaMEDMEM::MEDFileUMesh::getLevelM1Mesh; +%newobject ParaMEDMEM::MEDFileUMesh::getLevelM2Mesh; +%newobject ParaMEDMEM::MEDFileUMesh::getLevelM3Mesh; +%newobject ParaMEDMEM::MEDFileUMesh::getDirectUndergroundSingleGeoTypeMesh; +%newobject ParaMEDMEM::MEDFileUMesh::extractFamilyFieldOnGeoType; +%newobject ParaMEDMEM::MEDFileUMesh::extractNumberFieldOnGeoType; +%newobject ParaMEDMEM::MEDFileUMesh::zipCoords; +%newobject ParaMEDMEM::MEDFileUMesh::buildExtrudedMesh; +%newobject ParaMEDMEM::MEDFileUMesh::linearToQuadratic; +%newobject ParaMEDMEM::MEDFileUMesh::quadraticToLinear; +%newobject ParaMEDMEM::MEDFileCMesh::New; +%newobject ParaMEDMEM::MEDFileCurveLinearMesh::New; +%newobject ParaMEDMEM::MEDFileMeshMultiTS::New; +%newobject ParaMEDMEM::MEDFileMeshMultiTS::deepCpy; +%newobject ParaMEDMEM::MEDFileMeshMultiTS::getOneTimeStep; +%newobject ParaMEDMEM::MEDFileMeshes::New; +%newobject ParaMEDMEM::MEDFileMeshes::deepCpy; +%newobject ParaMEDMEM::MEDFileMeshes::getMeshAtPos; +%newobject ParaMEDMEM::MEDFileMeshes::getMeshWithName; +%newobject ParaMEDMEM::MEDFileMeshes::__getitem__; +%newobject ParaMEDMEM::MEDFileMeshes::__iter__; + +%newobject ParaMEDMEM::MEDFileFields::New; +%newobject ParaMEDMEM::MEDFileFields::LoadPartOf; +%newobject ParaMEDMEM::MEDFileFields::LoadSpecificEntities; +%newobject ParaMEDMEM::MEDFileFields::deepCpy; +%newobject ParaMEDMEM::MEDFileFields::shallowCpy; +%newobject ParaMEDMEM::MEDFileFields::getFieldWithName; +%newobject ParaMEDMEM::MEDFileFields::getFieldAtPos; +%newobject ParaMEDMEM::MEDFileFields::partOfThisLyingOnSpecifiedMeshName; +%newobject ParaMEDMEM::MEDFileFields::partOfThisLyingOnSpecifiedTimeSteps; +%newobject ParaMEDMEM::MEDFileFields::partOfThisNotLyingOnSpecifiedTimeSteps; +%newobject ParaMEDMEM::MEDFileFields::__iter__; + +%newobject ParaMEDMEM::MEDFileAnyTypeFieldMultiTS::New; +%newobject ParaMEDMEM::MEDFileAnyTypeFieldMultiTS::deepCpy; +%newobject ParaMEDMEM::MEDFileAnyTypeFieldMultiTS::shallowCpy; +%newobject ParaMEDMEM::MEDFileAnyTypeFieldMultiTS::getTimeStepAtPos; +%newobject ParaMEDMEM::MEDFileAnyTypeFieldMultiTS::getTimeStep; +%newobject ParaMEDMEM::MEDFileAnyTypeFieldMultiTS::getTimeStepGivenTime; +%newobject ParaMEDMEM::MEDFileAnyTypeFieldMultiTS::__iter__; +%newobject ParaMEDMEM::MEDFileFieldMultiTS::New; +%newobject ParaMEDMEM::MEDFileFieldMultiTS::LoadSpecificEntities; +%newobject ParaMEDMEM::MEDFileFieldMultiTS::getFieldAtLevel; +%newobject ParaMEDMEM::MEDFileFieldMultiTS::getFieldAtTopLevel; +%newobject ParaMEDMEM::MEDFileFieldMultiTS::getFieldOnMeshAtLevel; +%newobject ParaMEDMEM::MEDFileFieldMultiTS::getFieldAtLevelOld; +%newobject ParaMEDMEM::MEDFileFieldMultiTS::getUndergroundDataArray; +%newobject ParaMEDMEM::MEDFileFieldMultiTS::convertToInt; +%newobject ParaMEDMEM::MEDFileIntFieldMultiTS::New; +%newobject ParaMEDMEM::MEDFileIntFieldMultiTS::LoadSpecificEntities; +%newobject ParaMEDMEM::MEDFileIntFieldMultiTS::getUndergroundDataArray; +%newobject ParaMEDMEM::MEDFileIntFieldMultiTS::convertToDouble; + +%newobject ParaMEDMEM::MEDFileAnyTypeField1TS::New; +%newobject ParaMEDMEM::MEDFileAnyTypeField1TS::shallowCpy; +%newobject ParaMEDMEM::MEDFileAnyTypeField1TS::deepCpy; +%newobject ParaMEDMEM::MEDFileField1TS::New; +%newobject ParaMEDMEM::MEDFileField1TS::getFieldAtLevel; +%newobject ParaMEDMEM::MEDFileField1TS::getFieldAtTopLevel; +%newobject ParaMEDMEM::MEDFileField1TS::getFieldOnMeshAtLevel; +%newobject ParaMEDMEM::MEDFileField1TS::getFieldAtLevelOld; +%newobject ParaMEDMEM::MEDFileField1TS::getUndergroundDataArray; +%newobject ParaMEDMEM::MEDFileField1TS::convertToInt; +%newobject ParaMEDMEM::MEDFileIntField1TS::New; +%newobject ParaMEDMEM::MEDFileIntField1TS::getUndergroundDataArray; +%newobject ParaMEDMEM::MEDFileIntField1TS::convertToDouble; + +%newobject ParaMEDMEM::MEDFileData::New; +%newobject ParaMEDMEM::MEDFileData::deepCpy; +%newobject ParaMEDMEM::MEDFileData::getMeshes; +%newobject ParaMEDMEM::MEDFileData::getFields; +%newobject ParaMEDMEM::MEDFileData::getParams; + +%newobject ParaMEDMEM::MEDFileParameterDouble1TS::New; +%newobject ParaMEDMEM::MEDFileParameterDouble1TS::deepCpy; +%newobject ParaMEDMEM::MEDFileParameterMultiTS::New; +%newobject ParaMEDMEM::MEDFileParameterMultiTS::deepCpy; +%newobject ParaMEDMEM::MEDFileParameterMultiTS::getTimeStepAtPos; +%newobject ParaMEDMEM::MEDFileParameterMultiTS::__getitem__; +%newobject ParaMEDMEM::MEDFileParameters::New; +%newobject ParaMEDMEM::MEDFileParameters::deepCpy; +%newobject ParaMEDMEM::MEDFileParameters::getParamAtPos; +%newobject ParaMEDMEM::MEDFileParameters::getParamWithName; +%newobject ParaMEDMEM::MEDFileParameters::__getitem__; + +%newobject ParaMEDMEM::MEDFileJointCorrespondence::New; +%newobject ParaMEDMEM::MEDFileJointCorrespondence::deepCpy; +%newobject ParaMEDMEM::MEDFileJointCorrespondence::shallowCpy; +%newobject ParaMEDMEM::MEDFileJointOneStep::New; +%newobject ParaMEDMEM::MEDFileJointOneStep::deepCpy; +%newobject ParaMEDMEM::MEDFileJointOneStep::shallowCpy; +%newobject ParaMEDMEM::MEDFileJoint::New; +%newobject ParaMEDMEM::MEDFileJoint::deepCpy; +%newobject ParaMEDMEM::MEDFileJoint::shallowCpy; +%newobject ParaMEDMEM::MEDFileJoints::New; +%newobject ParaMEDMEM::MEDFileJoints::deepCpy; +%newobject ParaMEDMEM::MEDFileJoints::getJointAtPos; +%newobject ParaMEDMEM::MEDFileJoints::getJointWithName; +%newobject ParaMEDMEM::MEDFileJoints::__getitem__; + +%newobject ParaMEDMEM::SauvWriter::New; +%newobject ParaMEDMEM::SauvReader::New; +%newobject ParaMEDMEM::SauvReader::loadInMEDFileDS; + +%newobject ParaMEDMEM::MEDFileMeshStruct::New; +%newobject ParaMEDMEM::MEDMeshMultiLev::prepare; +%newobject ParaMEDMEM::MEDMeshMultiLev::buildDataArray; +%newobject ParaMEDMEM::MEDFileFastCellSupportComparator::New; +%newobject ParaMEDMEM::MEDFileFastCellSupportComparator::buildFromScratchDataSetSupport; + +%feature("unref") MEDFileMesh "$this->decrRef();" +%feature("unref") MEDFileUMesh "$this->decrRef();" +%feature("unref") MEDFileCMesh "$this->decrRef();" +%feature("unref") MEDFileMeshMultiTS "$this->decrRef();" +%feature("unref") MEDFileMeshes "$this->decrRef();" +%feature("unref") MEDFileFieldLoc "$this->decrRef();" +%feature("unref") MEDFileAnyTypeField1TS "$this->decrRef();" +%feature("unref") MEDFileField1TS "$this->decrRef();" +%feature("unref") MEDFileIntField1TS "$this->decrRef();" +%feature("unref") MEDFileAnyTypeFieldMultiTS "$this->decrRef();" +%feature("unref") MEDFileFieldMultiTS "$this->decrRef();" +%feature("unref") MEDFileIntFieldMultiTS "$this->decrRef();" +%feature("unref") MEDFileFields "$this->decrRef();" +%feature("unref") MEDFileParameter1TS "$this->decrRef();" +%feature("unref") MEDFileParameterDouble1TSWTI "$this->decrRef();" +%feature("unref") MEDFileParameterDouble1TS "$this->decrRef();" +%feature("unref") MEDFileParameterMultiTS "$this->decrRef();" +%feature("unref") MEDFileParameters "$this->decrRef();" +%feature("unref") MEDFileJointCorrespondence "$this->decrRef();" +%feature("unref") MEDFileJointOneStep "$this->decrRef();" +%feature("unref") MEDFileJoint "$this->decrRef();" +%feature("unref") MEDFileJoints "$this->decrRef();" +%feature("unref") MEDFileData "$this->decrRef();" +%feature("unref") SauvReader "$this->decrRef();" +%feature("unref") SauvWriter "$this->decrRef();" +%feature("unref") MEDFileFastCellSupportComparator "$this->decrRef();" +%feature("unref") MEDMeshMultiLev "$this->decrRef();" +%feature("unref") MEDUMeshMultiLev "$this->decrRef();" +%feature("unref") MEDCMeshMultiLev "$this->decrRef();" +%feature("unref") MEDCurveLinearMeshMultiLev "$this->decrRef();" +%feature("unref") MEDFileMeshStruct "$this->decrRef();" + +class MEDLoader +{ +public: + static bool HasXDR(); + static std::string MEDFileVersionStr(); + static void SetEpsilonForNodeComp(double val) throw(INTERP_KERNEL::Exception); + static void SetCompPolicyForCell(int val) throw(INTERP_KERNEL::Exception); + static void SetTooLongStrPolicy(int val) throw(INTERP_KERNEL::Exception); + static void CheckFileForRead(const std::string& fileName) throw(INTERP_KERNEL::Exception); + static std::vector<std::string> GetMeshNames(const std::string& fileName) throw(INTERP_KERNEL::Exception); + static std::vector<std::string> GetMeshNamesOnField(const std::string& fileName, const std::string& fieldName) throw(INTERP_KERNEL::Exception); + static std::vector<std::string> GetMeshGroupsNames(const std::string& fileName, const std::string& meshName) throw(INTERP_KERNEL::Exception); + static std::vector<std::string> GetMeshFamiliesNames(const std::string& fileName, const std::string& meshName) throw(INTERP_KERNEL::Exception); + static std::vector<std::string> GetMeshFamiliesNamesOnGroup(const std::string& fileName, const std::string& meshName, const std::string& grpName) throw(INTERP_KERNEL::Exception); + static std::vector<std::string> GetMeshGroupsNamesOnFamily(const std::string& fileName, const std::string& meshName, const std::string& famName) throw(INTERP_KERNEL::Exception); + static std::vector<std::string> GetAllFieldNamesOnMesh(const std::string& fileName, const std::string& meshName) throw(INTERP_KERNEL::Exception); + static std::vector<std::string> GetAllFieldNames(const std::string& fileName) throw(INTERP_KERNEL::Exception); + static std::vector<std::string> GetFieldNamesOnMesh(ParaMEDMEM::TypeOfField type, const std::string& fileName, const std::string& meshName) throw(INTERP_KERNEL::Exception); + static std::vector<std::string> GetCellFieldNamesOnMesh(const std::string& fileName, const std::string& meshName) throw(INTERP_KERNEL::Exception); + static std::vector<std::string> GetNodeFieldNamesOnMesh(const std::string& fileName, const std::string& meshName) throw(INTERP_KERNEL::Exception); + static double GetTimeAttachedOnFieldIteration(const std::string& fileName, const std::string& fieldName, int iteration, int order) throw(INTERP_KERNEL::Exception); + static void AssignStaticWritePropertiesTo(ParaMEDMEM::MEDFileWritable& obj) throw(INTERP_KERNEL::Exception); + %extend + { + static PyObject *MEDFileVersion() + { + int major,minor,release; + MEDLoader::MEDFileVersion(major,minor,release); + PyObject *ret(PyTuple_New(3)); + PyTuple_SetItem(ret,0,SWIG_From_int(major)); + PyTuple_SetItem(ret,1,SWIG_From_int(minor)); + PyTuple_SetItem(ret,2,SWIG_From_int(release)); + return ret; + } + + static PyObject *GetFieldIterations(ParaMEDMEM::TypeOfField type, const std::string& fileName, const std::string& meshName, const std::string& fieldName) throw(INTERP_KERNEL::Exception) + { + std::vector< std::pair<int,int> > res=MEDLoader::GetFieldIterations(type,fileName,meshName,fieldName); + PyObject *ret=PyList_New(res.size()); + int rk=0; + for(std::vector< std::pair<int,int> >::const_iterator iter=res.begin();iter!=res.end();iter++,rk++) + { + PyObject *elt=PyTuple_New(2); + PyTuple_SetItem(elt,0,SWIG_From_int((*iter).first)); + PyTuple_SetItem(elt,1,SWIG_From_int((*iter).second)); + PyList_SetItem(ret,rk,elt); + } + return ret; + } + + static PyObject *GetAllFieldIterations(const std::string& fileName, const std::string& fieldName) throw(INTERP_KERNEL::Exception) + { + std::vector< std::pair< std::pair<int,int>, double> > res=MEDLoader::GetAllFieldIterations(fileName,fieldName); + PyObject *ret=PyList_New(res.size()); + int rk=0; + for(std::vector< std::pair< std::pair<int,int>, double> >::const_iterator iter=res.begin();iter!=res.end();iter++,rk++) + { + PyObject *elt=PyTuple_New(3); + PyTuple_SetItem(elt,0,SWIG_From_int((*iter).first.first)); + PyTuple_SetItem(elt,1,SWIG_From_int((*iter).first.second)); + PyTuple_SetItem(elt,2,SWIG_From_double((*iter).second)); + PyList_SetItem(ret,rk,elt); + } + return ret; + } + + static PyObject *GetCellFieldIterations(const std::string& fileName, const std::string& meshName, const std::string& fieldName) throw(INTERP_KERNEL::Exception) + { + std::vector< std::pair<int,int> > res=MEDLoader::GetCellFieldIterations(fileName,meshName,fieldName); + PyObject *ret=PyList_New(res.size()); + int rk=0; + for(std::vector< std::pair<int,int> >::const_iterator iter=res.begin();iter!=res.end();iter++,rk++) + { + PyObject *elt=PyTuple_New(2); + PyTuple_SetItem(elt,0,SWIG_From_int((*iter).first)); + PyTuple_SetItem(elt,1,SWIG_From_int((*iter).second)); + PyList_SetItem(ret,rk,elt); + } + return ret; + } + static PyObject *GetNodeFieldIterations(const std::string& fileName, const std::string& meshName, const std::string& fieldName) throw(INTERP_KERNEL::Exception) + { + std::vector< std::pair<int,int> > res=MEDLoader::GetNodeFieldIterations(fileName,meshName,fieldName); + PyObject *ret=PyList_New(res.size()); + int rk=0; + for(std::vector< std::pair<int,int> >::const_iterator iter=res.begin();iter!=res.end();iter++,rk++) + { + PyObject *elt=PyTuple_New(2); + PyTuple_SetItem(elt,0,SWIG_From_int((*iter).first)); + PyTuple_SetItem(elt,1,SWIG_From_int((*iter).second)); + PyList_SetItem(ret,rk,elt); + } + return ret; + } + static PyObject *GetComponentsNamesOfField(const std::string& fileName, const std::string& fieldName) throw(INTERP_KERNEL::Exception) + { + std::vector< std::pair<std::string,std::string> > res=MEDLoader::GetComponentsNamesOfField(fileName,fieldName); + PyObject *ret=PyList_New(res.size()); + int rk=0; + for(std::vector< std::pair<std::string,std::string> >::const_iterator iter=res.begin();iter!=res.end();iter++,rk++) + { + PyObject *elt=PyTuple_New(2); + PyTuple_SetItem(elt,0,PyString_FromString((*iter).first.c_str())); + PyTuple_SetItem(elt,1,PyString_FromString((*iter).second.c_str())); + PyList_SetItem(ret,rk,elt); + } + return ret; + } + static PyObject *GetUMeshGlobalInfo(const std::string& fileName, const std::string& meshName) throw(INTERP_KERNEL::Exception) + { + int meshDim,spaceDim,numberOfNodes; + std::vector< std::vector< std::pair<INTERP_KERNEL::NormalizedCellType,int> > > res=MEDLoader::GetUMeshGlobalInfo(fileName,meshName,meshDim,spaceDim,numberOfNodes); + PyObject *ret=PyTuple_New(4); + PyObject *elt0=PyList_New(res.size()); + int i=0; + for(std::vector< std::vector< std::pair<INTERP_KERNEL::NormalizedCellType,int> > >::const_iterator it=res.begin();it!=res.end();it++,i++) + { + const std::vector< std::pair<INTERP_KERNEL::NormalizedCellType,int> >&obj2=(*it); + int j=0; + PyObject *elt1=PyList_New(obj2.size()); + for(std::vector< std::pair<INTERP_KERNEL::NormalizedCellType,int> >::const_iterator it2=obj2.begin();it2!=obj2.end();it2++,j++) + { + PyObject *elt2=PyTuple_New(2); + PyTuple_SetItem(elt2,0,SWIG_From_int((int)(*it2).first)); + PyTuple_SetItem(elt2,1,SWIG_From_int((*it2).second)); + PyList_SetItem(elt1,j,elt2); + } + PyList_SetItem(elt0,i,elt1); + } + PyTuple_SetItem(ret,0,elt0); + PyTuple_SetItem(ret,1,SWIG_From_int(meshDim)); + PyTuple_SetItem(ret,2,SWIG_From_int(spaceDim)); + PyTuple_SetItem(ret,3,SWIG_From_int(numberOfNodes)); + return ret; + } + static PyObject *ReadFieldsOnSameMesh(ParaMEDMEM::TypeOfField type, const std::string& fileName, const std::string& meshName, int meshDimRelToMax, + const std::string& fieldName, PyObject *liIts) throw(INTERP_KERNEL::Exception) + { + std::vector<std::pair<int,int> > its=convertTimePairIdsFromPy(liIts); + std::vector<ParaMEDMEM::MEDCouplingFieldDouble *> res=MEDLoader::ReadFieldsOnSameMesh(type,fileName,meshName,meshDimRelToMax,fieldName,its); + return convertFieldDoubleVecToPy(res); + } + static void WriteUMeshesPartition(const std::string& fileName, const std::string& meshName, PyObject *li, bool writeFromScratch) throw(INTERP_KERNEL::Exception) + { + std::vector<const ParaMEDMEM::MEDCouplingUMesh *> v; + convertFromPyObjVectorOfObj<const ParaMEDMEM::MEDCouplingUMesh *>(li,SWIGTYPE_p_ParaMEDMEM__MEDCouplingUMesh,"MEDCouplingUMesh",v); + MEDLoader::WriteUMeshesPartition(fileName,meshName,v,writeFromScratch); + } + static void WriteUMeshesPartitionDep(const std::string& fileName, const std::string& meshName, PyObject *li, bool writeFromScratch) throw(INTERP_KERNEL::Exception) + { + std::vector<const ParaMEDMEM::MEDCouplingUMesh *> v; + convertFromPyObjVectorOfObj<const ParaMEDMEM::MEDCouplingUMesh *>(li,SWIGTYPE_p_ParaMEDMEM__MEDCouplingUMesh,"MEDCouplingUMesh",v); + MEDLoader::WriteUMeshesPartitionDep(fileName,meshName,v,writeFromScratch); + } + static void WriteUMeshes(const std::string& fileName, PyObject *li, bool writeFromScratch) throw(INTERP_KERNEL::Exception) + { + std::vector<const ParaMEDMEM::MEDCouplingUMesh *> v; + convertFromPyObjVectorOfObj<const ParaMEDMEM::MEDCouplingUMesh *>(li,SWIGTYPE_p_ParaMEDMEM__MEDCouplingUMesh,"MEDCouplingUMesh",v); + MEDLoader::WriteUMeshes(fileName,v,writeFromScratch); + } + static PyObject *GetTypesOfField(const std::string& fileName, const std::string& meshName, const std::string& fieldName) throw(INTERP_KERNEL::Exception) + { + std::vector< ParaMEDMEM::TypeOfField > v=MEDLoader::GetTypesOfField(fileName,meshName,fieldName); + int size=v.size(); + PyObject *ret=PyList_New(size); + for(int i=0;i<size;i++) + PyList_SetItem(ret,i,PyInt_FromLong((int)v[i])); + return ret; + } + static ParaMEDMEM::MEDCouplingUMesh *ReadUMeshFromGroups(const std::string& fileName, const std::string& meshName, int meshDimRelToMax, PyObject *li) throw(INTERP_KERNEL::Exception) + { + std::vector<std::string> grps; + converPyListToVecString(li,grps); + return MEDLoader::ReadUMeshFromGroups(fileName,meshName,meshDimRelToMax,grps); + } + static ParaMEDMEM::MEDCouplingUMesh *ReadUMeshFromFamilies(const std::string& fileName, const std::string& meshName, int meshDimRelToMax, PyObject *li) throw(INTERP_KERNEL::Exception) + { + std::vector<std::string> fams; + converPyListToVecString(li,fams); + return MEDLoader::ReadUMeshFromFamilies(fileName,meshName,meshDimRelToMax,fams); + } + } + static ParaMEDMEM::MEDCouplingMesh *ReadMeshFromFile(const std::string& fileName, const std::string& meshName, int meshDimRelToMax=0) throw(INTERP_KERNEL::Exception); + static ParaMEDMEM::MEDCouplingMesh *ReadMeshFromFile(const std::string& fileName, int meshDimRelToMax=0) throw(INTERP_KERNEL::Exception); + static ParaMEDMEM::MEDCouplingUMesh *ReadUMeshFromFile(const std::string& fileName, const std::string& meshName, int meshDimRelToMax=0) throw(INTERP_KERNEL::Exception); + static ParaMEDMEM::MEDCouplingUMesh *ReadUMeshFromFile(const std::string& fileName, int meshDimRelToMax=0) throw(INTERP_KERNEL::Exception); + static int ReadUMeshDimFromFile(const std::string& fileName, const std::string& meshName) throw(INTERP_KERNEL::Exception); + static ParaMEDMEM::MEDCouplingFieldDouble *ReadField(ParaMEDMEM::TypeOfField type, const std::string& fileName, const std::string& meshName, int meshDimRelToMax, const std::string& fieldName, int iteration, int order) throw(INTERP_KERNEL::Exception); + static ParaMEDMEM::MEDCouplingFieldDouble *ReadFieldCell(const std::string& fileName, const std::string& meshName, int meshDimRelToMax, const std::string& fieldName, int iteration, int order) throw(INTERP_KERNEL::Exception); + static ParaMEDMEM::MEDCouplingFieldDouble *ReadFieldNode(const std::string& fileName, const std::string& meshName, int meshDimRelToMax, const std::string& fieldName, int iteration, int order) throw(INTERP_KERNEL::Exception); + static ParaMEDMEM::MEDCouplingFieldDouble *ReadFieldGauss(const std::string& fileName, const std::string& meshName, int meshDimRelToMax, const std::string& fieldName, int iteration, int order) throw(INTERP_KERNEL::Exception); + static ParaMEDMEM::MEDCouplingFieldDouble *ReadFieldGaussNE(const std::string& fileName, const std::string& meshName, int meshDimRelToMax, const std::string& fieldName, int iteration, int order) throw(INTERP_KERNEL::Exception); + static void WriteMesh(const std::string& fileName, const ParaMEDMEM::MEDCouplingMesh *mesh, bool writeFromScratch) throw(INTERP_KERNEL::Exception); + static void WriteUMesh(const std::string& fileName, const ParaMEDMEM::MEDCouplingUMesh *mesh, bool writeFromScratch) throw(INTERP_KERNEL::Exception); + static void WriteUMeshDep(const std::string& fileName, const ParaMEDMEM::MEDCouplingUMesh *mesh, bool writeFromScratch) throw(INTERP_KERNEL::Exception); + static void WriteField(const std::string& fileName, const ParaMEDMEM::MEDCouplingFieldDouble *f, bool writeFromScratch) throw(INTERP_KERNEL::Exception); + static void WriteFieldDep(const std::string& fileName, const ParaMEDMEM::MEDCouplingFieldDouble *f, bool writeFromScratch) throw(INTERP_KERNEL::Exception); + static void WriteFieldUsingAlreadyWrittenMesh(const std::string& fileName, const ParaMEDMEM::MEDCouplingFieldDouble *f) throw(INTERP_KERNEL::Exception); +}; + +namespace ParaMEDMEM +{ + class MEDFileWritable + { + public: + void copyOptionsFrom(const MEDFileWritable& other) const; + int getTooLongStrPolicy() const throw(INTERP_KERNEL::Exception); + void setTooLongStrPolicy(int newVal) throw(INTERP_KERNEL::Exception); + int getZipConnPolicy() throw(INTERP_KERNEL::Exception); + void setZipConnPolicy(int newVal) throw(INTERP_KERNEL::Exception); + }; + + class MEDFileMeshReadSelector + { + public: + MEDFileMeshReadSelector(); + MEDFileMeshReadSelector(unsigned int code); + unsigned int getCode() const; + void setCode(unsigned int newCode); + bool isCellFamilyFieldReading() const; + bool isNodeFamilyFieldReading() const; + bool isCellNameFieldReading() const; + bool isNodeNameFieldReading() const; + bool isCellNumFieldReading() const; + bool isNodeNumFieldReading() const; + void setCellFamilyFieldReading(bool b); + void setNodeFamilyFieldReading(bool b); + void setCellNameFieldReading(bool b); + void setNodeNameFieldReading(bool b); + void setCellNumFieldReading(bool b); + void setNodeNumFieldReading(bool b); + %extend + { + std::string __str__() const throw(INTERP_KERNEL::Exception) + { + std::ostringstream oss; + self->reprAll(oss); + return oss.str(); + } + + std::string __repr__() const throw(INTERP_KERNEL::Exception) + { + std::ostringstream oss; oss << "MEDFileMeshReadSelector C++ instance at " << self << " (with code=" << self->getCode() << ")."; + return oss.str(); + } + } + }; + class MEDFileJointCorrespondence : public RefCountObject, public MEDFileWritable + { + public: + static MEDFileJointCorrespondence *New() throw(INTERP_KERNEL::Exception); + static MEDFileJointCorrespondence *New(DataArrayInt* correspondence) // nodes + throw(INTERP_KERNEL::Exception); + static MEDFileJointCorrespondence *New(DataArrayInt* correspondence, // cells + INTERP_KERNEL::NormalizedCellType loc_geo_type, + INTERP_KERNEL::NormalizedCellType rem_geo_type) + throw(INTERP_KERNEL::Exception); + std::vector<const BigMemoryObject *> getDirectChildrenWithNull() const; + MEDFileJointCorrespondence *deepCpy() const; + MEDFileJointCorrespondence *shallowCpy() const; + void setIsNodal(bool isNodal); + bool getIsNodal() const; + bool isEqual(const MEDFileJointCorrespondence *other) const; + void setLocalGeometryType(INTERP_KERNEL::NormalizedCellType type); + INTERP_KERNEL::NormalizedCellType getLocalGeometryType() const; + void setRemoteGeometryType(INTERP_KERNEL::NormalizedCellType type); + INTERP_KERNEL::NormalizedCellType getRemoteGeometryType() const; + void setCorrespondence(DataArrayInt *corr) throw(INTERP_KERNEL::Exception); + const DataArrayInt *getCorrespondence() const throw(INTERP_KERNEL::Exception); + void write(const std::string& fileName, int mode, const std::string& localMeshName, const std::string& jointName, int order, int iteration) const throw(INTERP_KERNEL::Exception); + std::string simpleRepr() const throw(INTERP_KERNEL::Exception); + %extend + { + MEDFileJointCorrespondence() + { + return MEDFileJointCorrespondence::New(); + } + MEDFileJointCorrespondence(DataArrayInt* correspondence) throw(INTERP_KERNEL::Exception) + { + return MEDFileJointCorrespondence::New(correspondence); + } + MEDFileJointCorrespondence(DataArrayInt* correspondence, // cells + INTERP_KERNEL::NormalizedCellType loc_geo_type, + INTERP_KERNEL::NormalizedCellType rem_geo_type) throw(INTERP_KERNEL::Exception) + { + return MEDFileJointCorrespondence::New(correspondence, loc_geo_type, rem_geo_type); + } + + std::string __str__() const throw(INTERP_KERNEL::Exception) + { + return self->simpleRepr(); + } + } + }; + + class MEDFileJointOneStep : public RefCountObject, public MEDFileWritable + { + public: + static MEDFileJointOneStep *New(int dt=-1, int it=-1) throw(INTERP_KERNEL::Exception); + static MEDFileJointOneStep *New(const std::string& fileName, const std::string& mName, const std::string& jointName, int number=1) throw(INTERP_KERNEL::Exception); + MEDFileJointOneStep *deepCpy() const; + MEDFileJointOneStep *shallowCpy() const; + bool isEqual(const MEDFileJointOneStep *other) const; + void setOrder(int order); + int getOrder() const; + void setIteration(int it); + int getIteration() const; + void pushCorrespondence(MEDFileJointCorrespondence* correspondence); + int getNumberOfCorrespondences() const; + MEDFileJointCorrespondence *getCorrespondenceAtPos(int i) const; + void write(const std::string& fileName, int mode, const std::string& localMeshName, const std::string& jointName) const throw(INTERP_KERNEL::Exception); + std::string simpleRepr() const throw(INTERP_KERNEL::Exception); + %extend + { + MEDFileJointOneStep() + { + return MEDFileJointOneStep::New(); + } + + MEDFileJointOneStep(const std::string& fileName, const std::string& mName, const std::string& jointName, int number) throw(INTERP_KERNEL::Exception) + { + return MEDFileJointOneStep::New(fileName,mName,jointName,number); + } + + std::string __str__() const throw(INTERP_KERNEL::Exception) + { + return self->simpleRepr(); + } + } + }; + class MEDFileJoint : public RefCountObject, public MEDFileWritable + { + public: + static MEDFileJoint *New() throw(INTERP_KERNEL::Exception); + static MEDFileJoint *New(const std::string& fileName, const std::string& mName, int num) throw(INTERP_KERNEL::Exception); + static MEDFileJoint *New(const std::string& jointName, const std::string& locMeshName, const std::string& remoteMeshName, int remoteMeshNum ) throw(INTERP_KERNEL::Exception); + MEDFileJoint *deepCpy() const; + MEDFileJoint *shallowCpy() const; + bool isEqual(const MEDFileJoint *other) const; + void setLocalMeshName(const std::string& name); + std::string getLocalMeshName() const; + void setRemoteMeshName(const std::string& name); + std::string getRemoteMeshName() const; + void setDescription(const std::string& name); + std::string getDescription() const; + void setJointName(const std::string& name); + std::string getJointName() const; + bool changeJointNames(const std::vector< std::pair<std::string,std::string> >& modifTab) throw(INTERP_KERNEL::Exception); + void setDomainNumber(const int& number); + int getDomainNumber() const; + void pushStep(MEDFileJointOneStep* step); + int getNumberOfSteps() const; + MEDFileJointOneStep *getStepAtPos(int i) const; + void write(const std::string& fileName, int mode) const throw(INTERP_KERNEL::Exception); + std::string simpleRepr() const; + %extend + { + MEDFileJoint() + { + return MEDFileJoint::New(); + } + + MEDFileJoint(const std::string& fileName, const std::string& mName, int num) throw(INTERP_KERNEL::Exception) + { + return MEDFileJoint::New(fileName,mName,num); + } + + std::string __str__() const throw(INTERP_KERNEL::Exception) + { + return self->simpleRepr(); + } + } + }; + + class MEDFileJoints : public RefCountObject, public MEDFileWritable + { + public: + static MEDFileJoints *New() throw(INTERP_KERNEL::Exception); + static MEDFileJoints *New(const std::string& fileName, const std::string& meshName) throw(INTERP_KERNEL::Exception); + MEDFileJoints *deepCpy() const; + std::string simpleRepr() const; + void write(const std::string& fileName, int mode) const throw(INTERP_KERNEL::Exception); + std::string getMeshName() const; + int getNumberOfJoints() const; + std::vector<std::string> getJointsNames() const; + bool changeJointNames(const std::vector< std::pair<std::string,std::string> >& modifTab) throw(INTERP_KERNEL::Exception); + void resize(int newSize) throw(INTERP_KERNEL::Exception); + void pushJoint(MEDFileJoint *joint); + void setJointAtPos(int i, MEDFileJoint *joint) throw(INTERP_KERNEL::Exception); + void destroyJointAtPos(int i) throw(INTERP_KERNEL::Exception); + %extend + { + MEDFileJoints() + { + return MEDFileJoints::New(); + } + + MEDFileJoints(const std::string& fileName, const std::string& meshName) throw(INTERP_KERNEL::Exception) + { + return MEDFileJoints::New(fileName,meshName); + } + + std::string __str__() const throw(INTERP_KERNEL::Exception) + { + return self->simpleRepr(); + } + + MEDFileJoint *__getitem__(PyObject *obj) throw(INTERP_KERNEL::Exception) + { + if(PyInt_Check(obj)) + { + MEDFileJoint *ret=self->getJointAtPos(InterpreteNegativeInt((int)PyInt_AS_LONG(obj),self->getNumberOfJoints())); + if(ret) + ret->incrRef(); + return ret; + } + else if(PyString_Check(obj)) + { + MEDFileJoint *ret=self->getJointWithName(PyString_AsString(obj)); + if(ret) + ret->incrRef(); + return ret; + } + else + throw INTERP_KERNEL::Exception("MEDFileJoints::__getitem__ : only integer or string with meshname supported !"); + } + + int __len__() const throw(INTERP_KERNEL::Exception) + { + return self->getNumberOfJoints(); + } + + MEDFileJoint *getJointAtPos(int i) const throw(INTERP_KERNEL::Exception) + { + MEDFileJoint *ret=self->getJointAtPos(i); + if(ret) + ret->incrRef(); + return ret; + } + + MEDFileJoint *getJointWithName(const std::string& paramName) const throw(INTERP_KERNEL::Exception) + { + MEDFileJoint *ret=self->getJointWithName(paramName); + if(ret) + ret->incrRef(); + return ret; + } + } + }; + + class MEDFileMesh : public RefCountObject, public MEDFileWritable + { + public: + static MEDFileMesh *New(const std::string& fileName, MEDFileMeshReadSelector *mrs=0) throw(INTERP_KERNEL::Exception); + static MEDFileMesh *New(const std::string& fileName, const std::string& mName, int dt=-1, int it=-1, MEDFileMeshReadSelector *mrs=0) throw(INTERP_KERNEL::Exception); + virtual MEDFileMesh *createNewEmpty() const throw(INTERP_KERNEL::Exception); + virtual MEDFileMesh *deepCpy() const throw(INTERP_KERNEL::Exception); + virtual MEDFileMesh *shallowCpy() const throw(INTERP_KERNEL::Exception); + virtual void clearNonDiscrAttributes() const throw(INTERP_KERNEL::Exception); + void setName(const std::string& name); + std::string getName(); + std::string getUnivName() const; + bool getUnivNameWrStatus() const; + void setUnivNameWrStatus(bool newStatus); + void setDescription(const std::string& name); + std::string getDescription() const; + void setOrder(int order); + int getOrder() const; + void setIteration(int it); + int getIteration(); + void setTimeValue(double time); + void setTime(int dt, int it, double time); + double getTimeValue() const; + void setTimeUnit(const std::string& unit); + std::string getTimeUnit() const; + virtual int getNumberOfNodes() const throw(INTERP_KERNEL::Exception); + virtual int getNumberOfCellsAtLevel(int meshDimRelToMaxExt) const throw(INTERP_KERNEL::Exception); + virtual bool hasImplicitPart() const throw(INTERP_KERNEL::Exception); + virtual int buildImplicitPartIfAny(INTERP_KERNEL::NormalizedCellType gt) const throw(INTERP_KERNEL::Exception); + virtual void releaseImplicitPartIfAny() const throw(INTERP_KERNEL::Exception); + virtual std::vector<int> getFamArrNonEmptyLevelsExt() const throw(INTERP_KERNEL::Exception); + virtual std::vector<int> getNumArrNonEmptyLevelsExt() const throw(INTERP_KERNEL::Exception); + virtual std::vector<int> getNameArrNonEmptyLevelsExt() const throw(INTERP_KERNEL::Exception); + virtual std::vector<int> getDistributionOfTypes(int meshDimRelToMax) const throw(INTERP_KERNEL::Exception); + std::vector<int> getNonEmptyLevels() const throw(INTERP_KERNEL::Exception); + std::vector<int> getNonEmptyLevelsExt() const throw(INTERP_KERNEL::Exception); + void write(const std::string& fileName, int mode) const throw(INTERP_KERNEL::Exception); + int getSizeAtLevel(int meshDimRelToMaxExt) const throw(INTERP_KERNEL::Exception); + // + bool existsGroup(const std::string& groupName) const throw(INTERP_KERNEL::Exception); + bool existsFamily(int famId) const throw(INTERP_KERNEL::Exception); + bool existsFamily(const std::string& familyName) const throw(INTERP_KERNEL::Exception); + void setFamilyId(const std::string& familyName, int id) throw(INTERP_KERNEL::Exception); + void setFamilyIdUnique(const std::string& familyName, int id) throw(INTERP_KERNEL::Exception); + void addFamily(const std::string& familyName, int id) throw(INTERP_KERNEL::Exception); + void addFamilyOnGrp(const std::string& grpName, const std::string& famName) throw(INTERP_KERNEL::Exception); + virtual void createGroupOnAll(int meshDimRelToMaxExt, const std::string& groupName) throw(INTERP_KERNEL::Exception); + virtual bool keepFamIdsOnlyOnLevs(const std::vector<int>& famIds, const std::vector<int>& levs) throw(INTERP_KERNEL::Exception); + void copyFamGrpMapsFrom(const MEDFileMesh& other) throw(INTERP_KERNEL::Exception); + void clearGrpMap() throw(INTERP_KERNEL::Exception); + void clearFamMap() throw(INTERP_KERNEL::Exception); + void clearFamGrpMaps() throw(INTERP_KERNEL::Exception); + const std::map<std::string,int>& getFamilyInfo() const throw(INTERP_KERNEL::Exception); + const std::map<std::string, std::vector<std::string> >& getGroupInfo() const throw(INTERP_KERNEL::Exception); + std::vector<std::string> getFamiliesOnGroup(const std::string& name) const throw(INTERP_KERNEL::Exception); + std::vector<std::string> getFamiliesOnGroups(const std::vector<std::string>& grps) const throw(INTERP_KERNEL::Exception); + std::vector<int> getFamiliesIdsOnGroup(const std::string& name) const throw(INTERP_KERNEL::Exception); + void setFamiliesOnGroup(const std::string& name, const std::vector<std::string>& fams) throw(INTERP_KERNEL::Exception); + void setFamiliesIdsOnGroup(const std::string& name, const std::vector<int>& famIds) throw(INTERP_KERNEL::Exception); + std::vector<std::string> getGroupsOnFamily(const std::string& name) const throw(INTERP_KERNEL::Exception); + void setGroupsOnFamily(const std::string& famName, const std::vector<std::string>& grps) throw(INTERP_KERNEL::Exception); + std::vector<std::string> getGroupsNames() const throw(INTERP_KERNEL::Exception); + std::vector<std::string> getFamiliesNames() const throw(INTERP_KERNEL::Exception); + void assignFamilyNameWithGroupName() throw(INTERP_KERNEL::Exception); + std::vector<std::string> removeEmptyGroups() throw(INTERP_KERNEL::Exception); + void removeGroup(const std::string& name) throw(INTERP_KERNEL::Exception); + void removeFamily(const std::string& name) throw(INTERP_KERNEL::Exception); + std::vector<std::string> removeOrphanGroups() throw(INTERP_KERNEL::Exception); + std::vector<std::string> removeOrphanFamilies() throw(INTERP_KERNEL::Exception); + void removeFamiliesReferedByNoGroups() throw(INTERP_KERNEL::Exception); + void rearrangeFamilies() throw(INTERP_KERNEL::Exception); + void checkOrphanFamilyZero() const throw(INTERP_KERNEL::Exception); + void changeGroupName(const std::string& oldName, const std::string& newName) throw(INTERP_KERNEL::Exception); + void changeFamilyName(const std::string& oldName, const std::string& newName) throw(INTERP_KERNEL::Exception); + void changeFamilyId(int oldId, int newId) throw(INTERP_KERNEL::Exception); + void changeAllGroupsContainingFamily(const std::string& familyNameToChange, const std::vector<std::string>& newFamiliesNames) throw(INTERP_KERNEL::Exception); + void setFamilyInfo(const std::map<std::string,int>& info); + void setGroupInfo(const std::map<std::string, std::vector<std::string> >&info); + int getFamilyId(const std::string& name) const throw(INTERP_KERNEL::Exception); + int getMaxAbsFamilyId() const throw(INTERP_KERNEL::Exception); + int getMaxFamilyId() const throw(INTERP_KERNEL::Exception); + int getMinFamilyId() const throw(INTERP_KERNEL::Exception); + int getTheMaxAbsFamilyId() const throw(INTERP_KERNEL::Exception); + int getTheMaxFamilyId() const throw(INTERP_KERNEL::Exception); + int getTheMinFamilyId() const throw(INTERP_KERNEL::Exception); + virtual int getMaxAbsFamilyIdInArrays() const throw(INTERP_KERNEL::Exception); + virtual int getMaxFamilyIdInArrays() const throw(INTERP_KERNEL::Exception); + virtual int getMinFamilyIdInArrays() const throw(INTERP_KERNEL::Exception); + DataArrayInt *getAllFamiliesIdsReferenced() const throw(INTERP_KERNEL::Exception); + DataArrayInt *computeAllFamilyIdsInUse() const throw(INTERP_KERNEL::Exception); + std::vector<int> getFamiliesIds(const std::vector<std::string>& famNames) const throw(INTERP_KERNEL::Exception); + std::string getFamilyNameGivenId(int id) const throw(INTERP_KERNEL::Exception); + bool ensureDifferentFamIdsPerLevel() throw(INTERP_KERNEL::Exception); + void normalizeFamIdsTrio() throw(INTERP_KERNEL::Exception); + void normalizeFamIdsMEDFile() throw(INTERP_KERNEL::Exception); + virtual int getMeshDimension() const throw(INTERP_KERNEL::Exception); + virtual std::string simpleRepr() const throw(INTERP_KERNEL::Exception); + virtual std::string advancedRepr() const throw(INTERP_KERNEL::Exception); + // + virtual MEDCouplingMesh *getGenMeshAtLevel(int meshDimRelToMax, bool renum=false) const throw(INTERP_KERNEL::Exception); + virtual void setFamilyFieldArr(int meshDimRelToMaxExt, DataArrayInt *famArr) throw(INTERP_KERNEL::Exception); + virtual void setRenumFieldArr(int meshDimRelToMaxExt, DataArrayInt *renumArr) throw(INTERP_KERNEL::Exception); + virtual void setNameFieldAtLevel(int meshDimRelToMaxExt, DataArrayAsciiChar *nameArr) throw(INTERP_KERNEL::Exception); + virtual void addNodeGroup(const DataArrayInt *ids) throw(INTERP_KERNEL::Exception); + virtual void addGroup(int meshDimRelToMaxExt, const DataArrayInt *ids) throw(INTERP_KERNEL::Exception); + virtual DataArrayInt *getFamiliesArr(int meshDimRelToMaxExt, const std::vector<std::string>& fams, bool renum=false) const throw(INTERP_KERNEL::Exception); + virtual DataArrayInt *getGroupsArr(int meshDimRelToMaxExt, const std::vector<std::string>& grps, bool renum=false) const throw(INTERP_KERNEL::Exception); + virtual DataArrayInt *getGroupArr(int meshDimRelToMaxExt, const std::string& grp, bool renum=false) const throw(INTERP_KERNEL::Exception); + virtual DataArrayInt *getFamilyArr(int meshDimRelToMaxExt, const std::string& fam, bool renum=false) const throw(INTERP_KERNEL::Exception); + virtual DataArrayInt *getNodeGroupArr(const std::string& grp, bool renum=false) const throw(INTERP_KERNEL::Exception); + virtual DataArrayInt *getNodeGroupsArr(const std::vector<std::string>& grps, bool renum=false) const throw(INTERP_KERNEL::Exception); + virtual DataArrayInt *getNodeFamilyArr(const std::string& fam, bool renum=false) const throw(INTERP_KERNEL::Exception); + virtual DataArrayInt *getNodeFamiliesArr(const std::vector<std::string>& fams, bool renum=false) const throw(INTERP_KERNEL::Exception); + int getNumberOfJoints(); + MEDFileJoints *getJoints(); + void setJoints( MEDFileJoints* joints ); + %extend + { + std::string __str__() const throw(INTERP_KERNEL::Exception) + { + return self->simpleRepr(); + } + + MEDCouplingMesh *__getitem__(int meshDimRelToMaxExt) const throw(INTERP_KERNEL::Exception) + { + return self->getGenMeshAtLevel(meshDimRelToMaxExt,false); + } + + PyObject *getTime() throw(INTERP_KERNEL::Exception) + { + int tmp1,tmp2; + double tmp0=self->getTime(tmp1,tmp2); + PyObject *res = PyList_New(3); + PyList_SetItem(res,0,SWIG_From_int(tmp1)); + PyList_SetItem(res,1,SWIG_From_int(tmp2)); + PyList_SetItem(res,2,SWIG_From_double(tmp0)); + return res; + } + + virtual PyObject *isEqual(const MEDFileMesh *other, double eps) const throw(INTERP_KERNEL::Exception) + { + std::string what; + bool ret0=self->isEqual(other,eps,what); + PyObject *res=PyList_New(2); + PyObject *ret0Py=ret0?Py_True:Py_False; + Py_XINCREF(ret0Py); + PyList_SetItem(res,0,ret0Py); + PyList_SetItem(res,1,PyString_FromString(what.c_str())); + return res; + } + + void setGroupsAtLevel(int meshDimRelToMaxExt, PyObject *li, bool renum=false) throw(INTERP_KERNEL::Exception) + { + std::vector<const DataArrayInt *> grps; + convertFromPyObjVectorOfObj<const ParaMEDMEM::DataArrayInt *>(li,SWIGTYPE_p_ParaMEDMEM__DataArrayInt,"DataArrayInt",grps); + self->setGroupsAtLevel(meshDimRelToMaxExt,grps,renum); + } + + PyObject *areFamsEqual(const MEDFileMesh *other) const throw(INTERP_KERNEL::Exception) + { + std::string what; + bool ret0=self->areFamsEqual(other,what); + PyObject *res=PyList_New(2); + PyObject *ret0Py=ret0?Py_True:Py_False; + Py_XINCREF(ret0Py); + PyList_SetItem(res,0,ret0Py); + PyList_SetItem(res,1,PyString_FromString(what.c_str())); + return res; + } + + PyObject *areGrpsEqual(const MEDFileMesh *other) const throw(INTERP_KERNEL::Exception) + { + std::string what; + bool ret0=self->areGrpsEqual(other,what); + PyObject *res=PyList_New(2); + PyObject *ret0Py=ret0?Py_True:Py_False; + Py_XINCREF(ret0Py); + PyList_SetItem(res,0,ret0Py); + PyList_SetItem(res,1,PyString_FromString(what.c_str())); + return res; + } + + PyObject *getAllGeoTypes() const throw(INTERP_KERNEL::Exception) + { + std::vector<INTERP_KERNEL::NormalizedCellType> result(self->getAllGeoTypes()); + std::vector<INTERP_KERNEL::NormalizedCellType>::const_iterator iL=result.begin(); + PyObject *res=PyList_New(result.size()); + for(int i=0;iL!=result.end(); i++, iL++) + PyList_SetItem(res,i,PyInt_FromLong(*iL)); + return res; + } + + PyObject *getGeoTypesAtLevel(int meshDimRelToMax) const throw(INTERP_KERNEL::Exception) + { + std::vector<INTERP_KERNEL::NormalizedCellType> result(self->getGeoTypesAtLevel(meshDimRelToMax)); + std::vector<INTERP_KERNEL::NormalizedCellType>::const_iterator iL=result.begin(); + PyObject *res=PyList_New(result.size()); + for(int i=0;iL!=result.end(); i++, iL++) + PyList_SetItem(res,i,PyInt_FromLong(*iL)); + return res; + } + + PyObject *getFamilyFieldAtLevel(int meshDimRelToMaxExt) const throw(INTERP_KERNEL::Exception) + { + const DataArrayInt *tmp=self->getFamilyFieldAtLevel(meshDimRelToMaxExt); + if(tmp) + tmp->incrRef(); + return SWIG_NewPointerObj(SWIG_as_voidptr(tmp),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 ); + } + + PyObject *getOrCreateAndGetFamilyFieldAtLevel(int meshDimRelToMaxExt) throw(INTERP_KERNEL::Exception) + { + const DataArrayInt *tmp=self->getOrCreateAndGetFamilyFieldAtLevel(meshDimRelToMaxExt); + if(tmp) + tmp->incrRef(); + return SWIG_NewPointerObj(SWIG_as_voidptr(tmp),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 ); + } + + PyObject *getNumberFieldAtLevel(int meshDimRelToMaxExt) const throw(INTERP_KERNEL::Exception) + { + const DataArrayInt *tmp=self->getNumberFieldAtLevel(meshDimRelToMaxExt); + if(tmp) + tmp->incrRef(); + return SWIG_NewPointerObj(SWIG_as_voidptr(tmp),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 ); + } + + PyObject *getRevNumberFieldAtLevel(int meshDimRelToMaxExt) const throw(INTERP_KERNEL::Exception) + { + const DataArrayInt *tmp=self->getRevNumberFieldAtLevel(meshDimRelToMaxExt); + if(tmp) + tmp->incrRef(); + return SWIG_NewPointerObj(SWIG_as_voidptr(tmp),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 ); + } + + PyObject *getNameFieldAtLevel(int meshDimRelToMaxExt) const throw(INTERP_KERNEL::Exception) + { + const DataArrayAsciiChar *tmp=self->getNameFieldAtLevel(meshDimRelToMaxExt); + if(tmp) + tmp->incrRef(); + return SWIG_NewPointerObj(SWIG_as_voidptr(tmp),SWIGTYPE_p_ParaMEDMEM__DataArrayAsciiChar, SWIG_POINTER_OWN | 0 ); + } + + PyObject *findOrCreateAndGiveFamilyWithId(int id, bool& created) throw(INTERP_KERNEL::Exception) + { + bool ret1; + std::string ret0=self->findOrCreateAndGiveFamilyWithId(id,ret1); + PyObject *ret=PyTuple_New(2); + PyTuple_SetItem(ret,0,PyString_FromString(ret0.c_str())); + PyTuple_SetItem(ret,1,SWIG_From_bool(ret1)); + return ret; + } + + PyObject *unPolyze() throw(INTERP_KERNEL::Exception) + { + DataArrayInt *ret3=0; + std::vector<int> ret1,ret2; + bool ret0=self->unPolyze(ret1,ret2,ret3); + PyObject *ret=PyTuple_New(4); + PyTuple_SetItem(ret,0,SWIG_From_bool(ret0)); + // + PyObject *retLev1_0=PyList_New((int)ret1.size()/3); + for(int j=0;j<(int)ret1.size()/3;j++) + { + PyObject *retLev2=PyList_New(3); + PyList_SetItem(retLev2,0,SWIG_From_int(ret1[3*j])); + PyList_SetItem(retLev2,1,SWIG_From_int(ret1[3*j+1])); + PyList_SetItem(retLev2,2,SWIG_From_int(ret1[3*j+2])); + PyList_SetItem(retLev1_0,j,retLev2); + } + PyTuple_SetItem(ret,1,retLev1_0); + // + PyObject *retLev1_1=PyList_New((int)ret2.size()/3); + for(int j=0;j<(int)ret2.size()/3;j++) + { + PyObject *retLev2=PyList_New(3); + PyList_SetItem(retLev2,0,SWIG_From_int(ret2[3*j])); + PyList_SetItem(retLev2,1,SWIG_From_int(ret2[3*j+1])); + PyList_SetItem(retLev2,2,SWIG_From_int(ret2[3*j+2])); + PyList_SetItem(retLev1_1,j,retLev2); + } + PyTuple_SetItem(ret,2,retLev1_1); + // + PyTuple_SetItem(ret,3,SWIG_NewPointerObj(SWIG_as_voidptr(ret3),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 )); + return ret; + } + } + }; + + class MEDFileUMesh : public MEDFileMesh + { + public: + static MEDFileUMesh *New(const std::string& fileName, const std::string& mName, int dt=-1, int it=-1, MEDFileMeshReadSelector *mrs=0) throw(INTERP_KERNEL::Exception); + static MEDFileUMesh *New(const std::string& fileName, MEDFileMeshReadSelector *mrs=0) throw(INTERP_KERNEL::Exception); + static MEDFileUMesh *New(); + ~MEDFileUMesh(); + int getSpaceDimension() const throw(INTERP_KERNEL::Exception); + int getRelativeLevOnGeoType(INTERP_KERNEL::NormalizedCellType gt) const throw(INTERP_KERNEL::Exception); + // + std::vector<int> getGrpNonEmptyLevels(const std::string& grp) const throw(INTERP_KERNEL::Exception); + std::vector<int> getGrpNonEmptyLevelsExt(const std::string& grp) const throw(INTERP_KERNEL::Exception); + std::vector<int> getFamNonEmptyLevels(const std::string& fam) const throw(INTERP_KERNEL::Exception); + std::vector<int> getFamNonEmptyLevelsExt(const std::string& fam) const throw(INTERP_KERNEL::Exception); + std::vector<int> getGrpsNonEmptyLevels(const std::vector<std::string>& grps) const throw(INTERP_KERNEL::Exception); + std::vector<int> getGrpsNonEmptyLevelsExt(const std::vector<std::string>& grps) const throw(INTERP_KERNEL::Exception); + std::vector<int> getFamsNonEmptyLevels(const std::vector<std::string>& fams) const throw(INTERP_KERNEL::Exception); + std::vector<int> getFamsNonEmptyLevelsExt(const std::vector<std::string>& fams) const throw(INTERP_KERNEL::Exception); + std::vector<std::string> getGroupsOnSpecifiedLev(int meshDimRelToMaxExt) const throw(INTERP_KERNEL::Exception); + MEDCouplingUMesh *getGroup(int meshDimRelToMaxExt, const std::string& grp, bool renum=false) const throw(INTERP_KERNEL::Exception); + MEDCouplingUMesh *getGroups(int meshDimRelToMaxExt, const std::vector<std::string>& grps, bool renum=false) const throw(INTERP_KERNEL::Exception); + MEDCouplingUMesh *getFamily(int meshDimRelToMaxExt, const std::string& fam, bool renum=false) const throw(INTERP_KERNEL::Exception); + MEDCouplingUMesh *getFamilies(int meshDimRelToMaxExt, const std::vector<std::string>& fams, bool renum=false) const throw(INTERP_KERNEL::Exception); + DataArrayInt *getNodeGroupsArr(const std::vector<std::string>& grps, bool renum=false) const throw(INTERP_KERNEL::Exception); + MEDCouplingUMesh *getMeshAtLevel(int meshDimRelToMaxExt, bool renum=false) const throw(INTERP_KERNEL::Exception); + MEDCouplingUMesh *getLevel0Mesh(bool renum=false) const throw(INTERP_KERNEL::Exception); + MEDCouplingUMesh *getLevelM1Mesh(bool renum=false) const throw(INTERP_KERNEL::Exception); + MEDCouplingUMesh *getLevelM2Mesh(bool renum=false) const throw(INTERP_KERNEL::Exception); + MEDCouplingUMesh *getLevelM3Mesh(bool renum=false) const throw(INTERP_KERNEL::Exception); + void forceComputationOfParts() const throw(INTERP_KERNEL::Exception); + // + void setFamilyNameAttachedOnId(int id, const std::string& newFamName) throw(INTERP_KERNEL::Exception); + void setCoords(DataArrayDouble *coords) throw(INTERP_KERNEL::Exception); + void eraseGroupsAtLevel(int meshDimRelToMaxExt) throw(INTERP_KERNEL::Exception); + void removeMeshAtLevel(int meshDimRelToMax) throw(INTERP_KERNEL::Exception); + void setMeshAtLevel(int meshDimRelToMax, MEDCoupling1GTUMesh *m) throw(INTERP_KERNEL::Exception); + void setMeshAtLevel(int meshDimRelToMax, MEDCouplingUMesh *m, bool newOrOld=false) throw(INTERP_KERNEL::Exception); + void optimizeFamilies() throw(INTERP_KERNEL::Exception); + DataArrayInt *zipCoords() throw(INTERP_KERNEL::Exception); + DataArrayInt *extractFamilyFieldOnGeoType(INTERP_KERNEL::NormalizedCellType gt) const throw(INTERP_KERNEL::Exception); + DataArrayInt *extractNumberFieldOnGeoType(INTERP_KERNEL::NormalizedCellType gt) const throw(INTERP_KERNEL::Exception); + MEDFileUMesh *buildExtrudedMesh(const MEDCouplingUMesh *m1D, int policy) const throw(INTERP_KERNEL::Exception); + MEDFileUMesh *linearToQuadratic(int conversionType=0, double eps=1e-12) const throw(INTERP_KERNEL::Exception); + MEDFileUMesh *quadraticToLinear(double eps=1e-12) const throw(INTERP_KERNEL::Exception); + %extend + { + MEDFileUMesh(const std::string& fileName, const std::string& mName, int dt=-1, int it=-1, MEDFileMeshReadSelector *mrs=0) throw(INTERP_KERNEL::Exception) + { + return MEDFileUMesh::New(fileName,mName,dt,it,mrs); + } + + MEDFileUMesh(const std::string& fileName, MEDFileMeshReadSelector *mrs=0) throw(INTERP_KERNEL::Exception) + { + return MEDFileUMesh::New(fileName,mrs); + } + + MEDFileUMesh() + { + return MEDFileUMesh::New(); + } + + // serialization + static PyObject *___new___(PyObject *cls, PyObject *args) throw(INTERP_KERNEL::Exception) + { + return NewMethWrapCallInitOnlyIfEmptyDictInInput(cls,args,"MEDFileUMesh"); + } + + static MEDFileUMesh *LoadPartOf(const std::string& fileName, const std::string& mName, PyObject *types, const std::vector<int>& slicPerTyp, int dt=-1, int it=-1, MEDFileMeshReadSelector *mrs=0) throw(INTERP_KERNEL::Exception) + { + std::vector<int> typesCpp1; + convertPyToNewIntArr3(types,typesCpp1); + std::size_t sz(typesCpp1.size()); + std::vector<INTERP_KERNEL::NormalizedCellType> typesCpp2(sz); + for(std::size_t ii=0;ii<sz;ii++) + typesCpp2[ii]=(INTERP_KERNEL::NormalizedCellType)typesCpp1[ii]; + return MEDFileUMesh::LoadPartOf(fileName,mName,typesCpp2,slicPerTyp,dt,it,mrs); + } + + PyObject *__getnewargs__() throw(INTERP_KERNEL::Exception) + {// put an empty dict in input to say to __new__ to call __init__... + PyObject *ret(PyTuple_New(1)); + PyObject *ret0(PyDict_New()); + PyTuple_SetItem(ret,0,ret0); + return ret; + } + + PyObject *__getstate__() throw(INTERP_KERNEL::Exception) + { + std::vector<double> a0; + std::vector<int> a1; + std::vector<std::string> a2; + std::vector< MEDCouplingAutoRefCountObjectPtr<DataArrayInt> > a3; + MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> a4; + self->serialize(a0,a1,a2,a3,a4); + PyObject *ret(PyTuple_New(5)); + PyTuple_SetItem(ret,0,convertDblArrToPyList2(a0)); + PyTuple_SetItem(ret,1,convertIntArrToPyList2(a1)); + int sz(a2.size()); + PyObject *ret2(PyList_New(sz)); + for(int i=0;i<sz;i++) + PyList_SetItem(ret2,i,PyString_FromString(a2[i].c_str())); + PyTuple_SetItem(ret,2,ret2); + sz=a3.size(); + PyObject *ret3(PyList_New(sz)); + for(int i=0;i<sz;i++) + { + DataArrayInt *elt(a3[i]); + if(elt) + elt->incrRef(); + PyList_SetItem(ret3,i,SWIG_NewPointerObj(SWIG_as_voidptr(elt),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 )); + } + PyTuple_SetItem(ret,3,ret3); + DataArrayDouble *ret4(a4); + if(ret4) + ret4->incrRef(); + PyTuple_SetItem(ret,4,SWIG_NewPointerObj(SWIG_as_voidptr(ret4),SWIGTYPE_p_ParaMEDMEM__DataArrayDouble, SWIG_POINTER_OWN | 0 )); + return ret; + } + + void __setstate__(PyObject *inp) throw(INTERP_KERNEL::Exception) + { + static const char MSG[]="MEDFileUMesh.__setstate__ : expected input is a tuple of size 4 !"; + if(!PyTuple_Check(inp)) + throw INTERP_KERNEL::Exception(MSG); + int sz(PyTuple_Size(inp)); + if(sz!=5) + throw INTERP_KERNEL::Exception(MSG); + std::vector<double> a0; + std::vector<int> a1; + std::vector<std::string> a2; + std::vector< MEDCouplingAutoRefCountObjectPtr<DataArrayInt> > a3; + MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> a4; + // + PyObject *a0py(PyTuple_GetItem(inp,0)),*a1py(PyTuple_GetItem(inp,1)),*a2py(PyTuple_GetItem(inp,2)); + int tmp(-1); + fillArrayWithPyListDbl3(a0py,tmp,a0); + convertPyToNewIntArr3(a1py,a1); + fillStringVector(a2py,a2); + // + PyObject *b0py(PyTuple_GetItem(inp,3)),*b1py(PyTuple_GetItem(inp,4)); + void *argp(0); + int status(SWIG_ConvertPtr(b1py,&argp,SWIGTYPE_p_ParaMEDMEM__DataArrayDouble,0|0)); + if(!SWIG_IsOK(status)) + throw INTERP_KERNEL::Exception(MSG); + a4=reinterpret_cast<DataArrayDouble *>(argp); + if((DataArrayDouble *)a4) + a4->incrRef(); + { + std::vector< DataArrayInt * > a3Tmp; + convertFromPyObjVectorOfObj<ParaMEDMEM::DataArrayInt *>(b0py,SWIGTYPE_p_ParaMEDMEM__DataArrayInt,"DataArrayInt",a3Tmp); + std::size_t sz(a3Tmp.size()); + a3.resize(sz); + for(std::size_t i=0;i<sz;i++) + { + a3[i]=a3Tmp[i]; + if(a3Tmp[i]) + a3Tmp[i]->incrRef(); + } + self->unserialize(a0,a1,a2,a3,a4); + } + } + + void __setitem__(int meshDimRelToMax, MEDCouplingPointSet *mesh) throw(INTERP_KERNEL::Exception) + { + if(!mesh) + throw INTERP_KERNEL::Exception("MEDFileUMesh::__setitem__ : Input mesh is NULL !"); + MEDCouplingUMesh *m0(dynamic_cast<MEDCouplingUMesh *>(mesh)); + if(m0) + { + self->setMeshAtLevel(meshDimRelToMax,m0,false); + return ; + } + MEDCoupling1GTUMesh *m1(dynamic_cast<MEDCoupling1GTUMesh *>(mesh)); + if(m1) + { + self->setMeshAtLevel(meshDimRelToMax,m1); + return ; + } + throw INTERP_KERNEL::Exception("MEDFileUMesh::__setitem__ : Not recognized input mesh !"); + } + + void __delitem__(int meshDimRelToMax) throw(INTERP_KERNEL::Exception) + { + self->removeMeshAtLevel(meshDimRelToMax); + } + + void setMeshes(PyObject *li, bool renum=false) throw(INTERP_KERNEL::Exception) + { + std::vector<const MEDCouplingUMesh *> ms; + convertFromPyObjVectorOfObj<const ParaMEDMEM::MEDCouplingUMesh *>(li,SWIGTYPE_p_ParaMEDMEM__MEDCouplingUMesh,"MEDCouplingUMesh",ms); + self->setMeshes(ms,renum); + } + + void setGroupsFromScratch(int meshDimRelToMax, PyObject *li, bool renum=false) throw(INTERP_KERNEL::Exception) + { + std::vector<const MEDCouplingUMesh *> ms; + convertFromPyObjVectorOfObj<const ParaMEDMEM::MEDCouplingUMesh *>(li,SWIGTYPE_p_ParaMEDMEM__MEDCouplingUMesh,"MEDCouplingUMesh",ms); + self->setGroupsFromScratch(meshDimRelToMax,ms,renum); + } + + void setGroupsOnSetMesh(int meshDimRelToMax, PyObject *li, bool renum=false) throw(INTERP_KERNEL::Exception) + { + std::vector<const MEDCouplingUMesh *> ms; + convertFromPyObjVectorOfObj<const ParaMEDMEM::MEDCouplingUMesh *>(li,SWIGTYPE_p_ParaMEDMEM__MEDCouplingUMesh,"MEDCouplingUMesh",ms); + self->setGroupsOnSetMesh(meshDimRelToMax,ms,renum); + } + + DataArrayDouble *getCoords() const throw(INTERP_KERNEL::Exception) + { + DataArrayDouble *ret=self->getCoords(); + if(ret) + ret->incrRef(); + return ret; + } + + PartDefinition *getPartDefAtLevel(int meshDimRelToMaxExt, INTERP_KERNEL::NormalizedCellType gt=INTERP_KERNEL::NORM_ERROR) const throw(INTERP_KERNEL::Exception) + { + const PartDefinition *ret(self->getPartDefAtLevel(meshDimRelToMaxExt,gt)); + if(ret) + ret->incrRef(); + return const_cast<PartDefinition *>(ret); + } + + PyObject *buildInnerBoundaryAlongM1Group(const std::string& grpNameM1) throw(INTERP_KERNEL::Exception) + { + DataArrayInt *ret0=0,*ret1=0,*ret2=0; + self->buildInnerBoundaryAlongM1Group(grpNameM1,ret0,ret1,ret2); + PyObject *ret=PyTuple_New(3); + PyTuple_SetItem(ret,0,SWIG_NewPointerObj(SWIG_as_voidptr(ret0),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 )); + PyTuple_SetItem(ret,1,SWIG_NewPointerObj(SWIG_as_voidptr(ret1),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 )); + PyTuple_SetItem(ret,2,SWIG_NewPointerObj(SWIG_as_voidptr(ret2),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 )); + return ret; + } + + MEDCoupling1GTUMesh *getDirectUndergroundSingleGeoTypeMesh(INTERP_KERNEL::NormalizedCellType gt) const throw(INTERP_KERNEL::Exception) + { + MEDCoupling1GTUMesh *ret(self->getDirectUndergroundSingleGeoTypeMesh(gt)); + if(ret) + ret->incrRef(); + return ret; + } + + PyObject *getDirectUndergroundSingleGeoTypeMeshes(int meshDimRelToMax) const throw(INTERP_KERNEL::Exception) + { + std::vector<MEDCoupling1GTUMesh *> tmp(self->getDirectUndergroundSingleGeoTypeMeshes(meshDimRelToMax)); + std::size_t sz(tmp.size()); + PyObject *ret=PyList_New(sz); + for(std::size_t i=0;i<sz;i++) + { + if(tmp[i]) + tmp[i]->incrRef(); + PyList_SetItem(ret,i,convertMesh(tmp[i], SWIG_POINTER_OWN | 0 )); + } + return ret; + } + } + }; + + class MEDFileStructuredMesh : public MEDFileMesh + { + public: + %extend + { + MEDCoupling1SGTUMesh *getImplicitFaceMesh() const throw(INTERP_KERNEL::Exception) + { + MEDCoupling1SGTUMesh *ret(self->getImplicitFaceMesh()); + if(ret) + ret->incrRef(); + return ret; + } + } + }; + + class MEDFileCMesh : public MEDFileStructuredMesh + { + public: + static MEDFileCMesh *New(); + static MEDFileCMesh *New(const std::string& fileName, MEDFileMeshReadSelector *mrs=0) throw(INTERP_KERNEL::Exception); + static MEDFileCMesh *New(const std::string& fileName, const std::string& mName, int dt=-1, int it=-1, MEDFileMeshReadSelector *mrs=0) throw(INTERP_KERNEL::Exception); + void setMesh(MEDCouplingCMesh *m) throw(INTERP_KERNEL::Exception); + int getSpaceDimension() const throw(INTERP_KERNEL::Exception); + %extend + { + MEDFileCMesh() + { + return MEDFileCMesh::New(); + } + + MEDFileCMesh(const std::string& fileName, MEDFileMeshReadSelector *mrs=0) throw(INTERP_KERNEL::Exception) + { + return MEDFileCMesh::New(fileName,mrs); + } + + MEDFileCMesh(const std::string& fileName, const std::string& mName, int dt=-1, int it=-1, MEDFileMeshReadSelector *mrs=0) throw(INTERP_KERNEL::Exception) + { + return MEDFileCMesh::New(fileName,mName,dt,it,mrs); + } + + PyObject *getMesh() const throw(INTERP_KERNEL::Exception) + { + const MEDCouplingCMesh *tmp=self->getMesh(); + if(tmp) + tmp->incrRef(); + return SWIG_NewPointerObj(SWIG_as_voidptr(tmp),SWIGTYPE_p_ParaMEDMEM__MEDCouplingCMesh, SWIG_POINTER_OWN | 0 ); + } + } + }; + + class MEDFileCurveLinearMesh : public MEDFileStructuredMesh + { + public: + static MEDFileCurveLinearMesh *New(); + static MEDFileCurveLinearMesh *New(const std::string& fileName, MEDFileMeshReadSelector *mrs=0) throw(INTERP_KERNEL::Exception); + static MEDFileCurveLinearMesh *New(const std::string& fileName, const std::string& mName, int dt=-1, int it=-1, MEDFileMeshReadSelector *mrs=0) throw(INTERP_KERNEL::Exception); + void setMesh(MEDCouplingCurveLinearMesh *m) throw(INTERP_KERNEL::Exception); + %extend + { + MEDFileCurveLinearMesh() + { + return MEDFileCurveLinearMesh::New(); + } + + MEDFileCurveLinearMesh(const std::string& fileName, MEDFileMeshReadSelector *mrs=0) throw(INTERP_KERNEL::Exception) + { + return MEDFileCurveLinearMesh::New(fileName,mrs); + } + + MEDFileCurveLinearMesh(const std::string& fileName, const std::string& mName, int dt=-1, int it=-1, MEDFileMeshReadSelector *mrs=0) throw(INTERP_KERNEL::Exception) + { + return MEDFileCurveLinearMesh::New(fileName,mName,dt,it,mrs); + } + + PyObject *getMesh() const throw(INTERP_KERNEL::Exception) + { + const MEDCouplingCurveLinearMesh *tmp=self->getMesh(); + if(tmp) + tmp->incrRef(); + return SWIG_NewPointerObj(SWIG_as_voidptr(tmp),SWIGTYPE_p_ParaMEDMEM__MEDCouplingCurveLinearMesh, SWIG_POINTER_OWN | 0 ); + } + } + }; + + class MEDFileMeshMultiTS : public RefCountObject, public MEDFileWritable + { + public: + static MEDFileMeshMultiTS *New(); + static MEDFileMeshMultiTS *New(const std::string& fileName) throw(INTERP_KERNEL::Exception); + static MEDFileMeshMultiTS *New(const std::string& fileName, const std::string& mName) throw(INTERP_KERNEL::Exception); + MEDFileMeshMultiTS *deepCpy() const throw(INTERP_KERNEL::Exception); + std::string getName() const throw(INTERP_KERNEL::Exception); + void write(const std::string& fileName, int mode) const throw(INTERP_KERNEL::Exception); + void setOneTimeStep(MEDFileMesh *mesh1TimeStep) throw(INTERP_KERNEL::Exception); + %extend + { + MEDFileMeshMultiTS() + { + return MEDFileMeshMultiTS::New(); + } + + MEDFileMeshMultiTS(const std::string& fileName) throw(INTERP_KERNEL::Exception) + { + return MEDFileMeshMultiTS::New(fileName); + } + + MEDFileMeshMultiTS(const std::string& fileName, const std::string& mName) throw(INTERP_KERNEL::Exception) + { + return MEDFileMeshMultiTS::New(fileName,mName); + } + + MEDFileMesh *getOneTimeStep() const throw(INTERP_KERNEL::Exception) + { + MEDFileMesh *ret=self->getOneTimeStep(); + if(ret) + ret->incrRef(); + return ret; + } + } + }; + + class MEDFileMeshesIterator + { + public: + %extend + { + PyObject *next() throw(INTERP_KERNEL::Exception) + { + MEDFileMesh *ret=self->nextt(); + if(ret) + { + ret->incrRef(); + return convertMEDFileMesh(ret,SWIG_POINTER_OWN | 0 ); + } + else + { + PyErr_SetString(PyExc_StopIteration,"No more data."); + return 0; + } + } + } + }; + + class MEDFileMeshes : public RefCountObject, public MEDFileWritable + { + public: + static MEDFileMeshes *New(); + static MEDFileMeshes *New(const std::string& fileName) throw(INTERP_KERNEL::Exception); + MEDFileMeshes *deepCpy() const throw(INTERP_KERNEL::Exception); + void write(const std::string& fileName, int mode) const throw(INTERP_KERNEL::Exception); + int getNumberOfMeshes() const throw(INTERP_KERNEL::Exception); + std::vector<std::string> getMeshesNames() const throw(INTERP_KERNEL::Exception); + // + void resize(int newSize) throw(INTERP_KERNEL::Exception); + void pushMesh(MEDFileMesh *mesh) throw(INTERP_KERNEL::Exception); + void setMeshAtPos(int i, MEDFileMesh *mesh) throw(INTERP_KERNEL::Exception); + void destroyMeshAtPos(int i) throw(INTERP_KERNEL::Exception); + %extend + { + MEDFileMeshes() + { + return MEDFileMeshes::New(); + } + + MEDFileMeshes(const std::string& fileName) throw(INTERP_KERNEL::Exception) + { + return MEDFileMeshes::New(fileName); + } + + std::string __str__() const throw(INTERP_KERNEL::Exception) + { + return self->simpleRepr(); + } + + MEDFileMesh *__getitem__(PyObject *obj) throw(INTERP_KERNEL::Exception) + { + if(PyInt_Check(obj)) + { + MEDFileMesh *ret=self->getMeshAtPos(InterpreteNegativeInt((int)PyInt_AS_LONG(obj),self->getNumberOfMeshes())); + if(ret) + ret->incrRef(); + return ret; + } + else if(PyString_Check(obj)) + { + MEDFileMesh *ret=self->getMeshWithName(PyString_AsString(obj)); + if(ret) + ret->incrRef(); + return ret; + } + else + throw INTERP_KERNEL::Exception("MEDFileMeshes::__getitem__ : only integer or string with meshname supported !"); + } + + MEDFileMeshes *__setitem__(int obj, MEDFileMesh *mesh) throw(INTERP_KERNEL::Exception) + { + self->setMeshAtPos(obj,mesh); + return self; + } + + MEDFileMeshesIterator *__iter__() throw(INTERP_KERNEL::Exception) + { + return self->iterator(); + } + + int __len__() const throw(INTERP_KERNEL::Exception) + { + return self->getNumberOfMeshes(); + } + + MEDFileMesh *getMeshAtPos(int i) const throw(INTERP_KERNEL::Exception) + { + MEDFileMesh *ret=self->getMeshAtPos(i); + if(ret) + ret->incrRef(); + return ret; + } + MEDFileMesh *getMeshWithName(const std::string& mname) const throw(INTERP_KERNEL::Exception) + { + MEDFileMesh *ret=self->getMeshWithName(mname); + if(ret) + ret->incrRef(); + return ret; + } + } + }; + + class MEDFileFieldLoc : public RefCountObject + { + public: + std::string getName() const; + int getDimension() const; + int getNumberOfGaussPoints() const; + int getNumberOfPointsInCells() const; + const std::vector<double>& getRefCoords() const; + const std::vector<double>& getGaussCoords() const; + const std::vector<double>& getGaussWeights() const; + bool isEqual(const MEDFileFieldLoc& other, double eps) const throw(INTERP_KERNEL::Exception); + %extend + { + std::string __str__() const throw(INTERP_KERNEL::Exception) + { + return self->repr(); + } + } + }; + + class MEDFileFieldGlobsReal + { + public: + void resetContent(); + void shallowCpyGlobs(const MEDFileFieldGlobsReal& other) throw(INTERP_KERNEL::Exception); + void deepCpyGlobs(const MEDFileFieldGlobsReal& other) throw(INTERP_KERNEL::Exception); + void shallowCpyOnlyUsedGlobs(const MEDFileFieldGlobsReal& other) throw(INTERP_KERNEL::Exception); + void deepCpyOnlyUsedGlobs(const MEDFileFieldGlobsReal& other) throw(INTERP_KERNEL::Exception); + void appendGlobs(const MEDFileFieldGlobsReal& other, double eps) throw(INTERP_KERNEL::Exception); + void checkGlobsCoherency() const throw(INTERP_KERNEL::Exception); + void checkGlobsPflsPartCoherency() const throw(INTERP_KERNEL::Exception); + void checkGlobsLocsPartCoherency() const throw(INTERP_KERNEL::Exception); + std::vector<std::string> getPfls() const throw(INTERP_KERNEL::Exception); + std::vector<std::string> getLocs() const throw(INTERP_KERNEL::Exception); + bool existsPfl(const std::string& pflName) const throw(INTERP_KERNEL::Exception); + bool existsLoc(const std::string& locName) const throw(INTERP_KERNEL::Exception); + std::string createNewNameOfPfl() const throw(INTERP_KERNEL::Exception); + std::string createNewNameOfLoc() const throw(INTERP_KERNEL::Exception); + std::vector< std::vector<int> > whichAreEqualProfiles() const throw(INTERP_KERNEL::Exception); + std::vector< std::vector<int> > whichAreEqualLocs(double eps) const throw(INTERP_KERNEL::Exception); + virtual std::vector<std::string> getPflsReallyUsed() const throw(INTERP_KERNEL::Exception); + virtual std::vector<std::string> getLocsReallyUsed() const throw(INTERP_KERNEL::Exception); + virtual std::vector<std::string> getPflsReallyUsedMulti() const throw(INTERP_KERNEL::Exception); + virtual std::vector<std::string> getLocsReallyUsedMulti() const throw(INTERP_KERNEL::Exception); + void killProfileIds(const std::vector<int>& pflIds) throw(INTERP_KERNEL::Exception); + void killLocalizationIds(const std::vector<int>& locIds) throw(INTERP_KERNEL::Exception); + void changePflName(const std::string& oldName, const std::string& newName) throw(INTERP_KERNEL::Exception); + void changeLocName(const std::string& oldName, const std::string& newName) throw(INTERP_KERNEL::Exception); + int getNbOfGaussPtPerCell(int locId) const throw(INTERP_KERNEL::Exception); + int getLocalizationId(const std::string& loc) const throw(INTERP_KERNEL::Exception); + %extend + { + PyObject *getProfile(const std::string& pflName) const throw(INTERP_KERNEL::Exception) + { + const DataArrayInt *ret=self->getProfile(pflName); + if(ret) + ret->incrRef(); + return SWIG_NewPointerObj(SWIG_as_voidptr(ret),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 ); + } + + PyObject *getProfileFromId(int pflId) const throw(INTERP_KERNEL::Exception) + { + const DataArrayInt *ret=self->getProfileFromId(pflId); + if(ret) + ret->incrRef(); + return SWIG_NewPointerObj(SWIG_as_voidptr(ret),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 ); + } + + PyObject *getLocalizationFromId(int locId) const throw(INTERP_KERNEL::Exception) + { + const MEDFileFieldLoc *loc=&self->getLocalizationFromId(locId); + if(loc) + loc->incrRef(); + return SWIG_NewPointerObj(SWIG_as_voidptr(loc),SWIGTYPE_p_ParaMEDMEM__MEDFileFieldLoc, SWIG_POINTER_OWN | 0 ); + } + + PyObject *getLocalization(const std::string& locName) const throw(INTERP_KERNEL::Exception) + { + const MEDFileFieldLoc *loc=&self->getLocalization(locName); + if(loc) + loc->incrRef(); + return SWIG_NewPointerObj(SWIG_as_voidptr(loc),SWIGTYPE_p_ParaMEDMEM__MEDFileFieldLoc, SWIG_POINTER_OWN | 0 ); + } + + PyObject *zipPflsNames() throw(INTERP_KERNEL::Exception) + { + std::vector< std::pair<std::vector<std::string>, std::string > > ret=self->zipPflsNames(); + return convertVecPairVecStToPy(ret); + } + + PyObject *zipLocsNames(double eps) throw(INTERP_KERNEL::Exception) + { + std::vector< std::pair<std::vector<std::string>, std::string > > ret=self->zipLocsNames(eps); + return convertVecPairVecStToPy(ret); + } + + void changePflsNames(PyObject *li) throw(INTERP_KERNEL::Exception) + { + std::vector< std::pair<std::vector<std::string>, std::string > > v=convertVecPairVecStFromPy(li); + self->changePflsNames(v); + } + + void changePflsRefsNamesGen(PyObject *li) throw(INTERP_KERNEL::Exception) + { + std::vector< std::pair<std::vector<std::string>, std::string > > v=convertVecPairVecStFromPy(li); + self->changePflsRefsNamesGen(v); + } + + void changePflsNamesInStruct(PyObject *li) throw(INTERP_KERNEL::Exception) + { + std::vector< std::pair<std::vector<std::string>, std::string > > v=convertVecPairVecStFromPy(li); + self->changePflsNamesInStruct(v); + } + + void changeLocsNames(PyObject *li) throw(INTERP_KERNEL::Exception) + { + std::vector< std::pair<std::vector<std::string>, std::string > > v=convertVecPairVecStFromPy(li); + self->changeLocsNames(v); + } + + void changeLocsRefsNamesGen(PyObject *li) throw(INTERP_KERNEL::Exception) + { + std::vector< std::pair<std::vector<std::string>, std::string > > v=convertVecPairVecStFromPy(li); + self->changeLocsRefsNamesGen(v); + } + + void changeLocsNamesInStruct(PyObject *li) throw(INTERP_KERNEL::Exception) + { + std::vector< std::pair<std::vector<std::string>, std::string > > v=convertVecPairVecStFromPy(li); + self->changeLocsNamesInStruct(v); + } + + std::string simpleReprGlobs() const throw(INTERP_KERNEL::Exception) + { + std::ostringstream oss; + self->simpleReprGlobs(oss); + return oss.str(); + } + } + }; + + class MEDFileAnyTypeField1TS : public RefCountObject, public MEDFileFieldGlobsReal, public MEDFileWritable + { + public: + static MEDFileAnyTypeField1TS *New(const std::string& fileName, bool loadAll=true) throw(INTERP_KERNEL::Exception); + static MEDFileAnyTypeField1TS *New(const std::string& fileName, const std::string& fieldName, bool loadAll=true) throw(INTERP_KERNEL::Exception); + static MEDFileAnyTypeField1TS *New(const std::string& fileName, const std::string& fieldName, int iteration, int order, bool loadAll=true) throw(INTERP_KERNEL::Exception); + void write(const std::string& fileName, int mode) const throw(INTERP_KERNEL::Exception); + void loadArrays() throw(INTERP_KERNEL::Exception); + void loadArraysIfNecessary() throw(INTERP_KERNEL::Exception); + void unloadArrays() throw(INTERP_KERNEL::Exception); + void unloadArraysWithoutDataLoss() throw(INTERP_KERNEL::Exception); + int getDimension() const throw(INTERP_KERNEL::Exception); + int getIteration() const throw(INTERP_KERNEL::Exception); + int getOrder() const throw(INTERP_KERNEL::Exception); + std::string getName() throw(INTERP_KERNEL::Exception); + void setName(const std::string& name) throw(INTERP_KERNEL::Exception); + std::string getMeshName() throw(INTERP_KERNEL::Exception); + void setMeshName(const std::string& newMeshName) throw(INTERP_KERNEL::Exception); + int getMeshIteration() const throw(INTERP_KERNEL::Exception); + int getMeshOrder() const throw(INTERP_KERNEL::Exception); + int getNumberOfComponents() const throw(INTERP_KERNEL::Exception); + bool isDealingTS(int iteration, int order) const throw(INTERP_KERNEL::Exception); + void setInfo(const std::vector<std::string>& infos) throw(INTERP_KERNEL::Exception); + const std::vector<std::string>& getInfo() const throw(INTERP_KERNEL::Exception); + bool presenceOfMultiDiscPerGeoType() const throw(INTERP_KERNEL::Exception); + void setTime(int iteration, int order, double val) throw(INTERP_KERNEL::Exception); + virtual MEDFileAnyTypeField1TS *shallowCpy() const throw(INTERP_KERNEL::Exception); + MEDFileAnyTypeField1TS *deepCpy() const throw(INTERP_KERNEL::Exception); + std::string getDtUnit() const throw(INTERP_KERNEL::Exception); + void setDtUnit(const std::string& dtUnit) throw(INTERP_KERNEL::Exception); + %extend + { + PyObject *getTime() throw(INTERP_KERNEL::Exception) + { + int tmp1,tmp2; + double tmp0=self->getTime(tmp1,tmp2); + PyObject *res = PyList_New(3); + PyList_SetItem(res,0,SWIG_From_int(tmp1)); + PyList_SetItem(res,1,SWIG_From_int(tmp2)); + PyList_SetItem(res,2,SWIG_From_double(tmp0)); + return res; + } + + PyObject *getDtIt() const throw(INTERP_KERNEL::Exception) + { + std::pair<int,int> res=self->getDtIt(); + PyObject *elt=PyTuple_New(2); + PyTuple_SetItem(elt,0,SWIG_From_int(res.first)); + PyTuple_SetItem(elt,1,SWIG_From_int(res.second)); + return elt; + } + + void setProfileNameOnLeaf(INTERP_KERNEL::NormalizedCellType typ, int locId, const std::string& newPflName, bool forceRenameOnGlob=false) throw(INTERP_KERNEL::Exception) + { + self->setProfileNameOnLeaf(0,typ,locId,newPflName,forceRenameOnGlob); + } + + void setLocNameOnLeaf(INTERP_KERNEL::NormalizedCellType typ, int locId, const std::string& newLocName, bool forceRenameOnGlob=false) throw(INTERP_KERNEL::Exception) + { + self->setLocNameOnLeaf(0,typ,locId,newLocName,forceRenameOnGlob); + } + + bool changeMeshNames(PyObject *li) throw(INTERP_KERNEL::Exception) + { + std::vector< std::pair<std::string,std::string> > modifTab=convertVecPairStStFromPy(li); + return self->changeMeshNames(modifTab); + } + + PyObject *getTypesOfFieldAvailable() const throw(INTERP_KERNEL::Exception) + { + std::vector<TypeOfField> ret=self->getTypesOfFieldAvailable(); + PyObject *ret2=PyList_New(ret.size()); + for(int i=0;i<(int)ret.size();i++) + PyList_SetItem(ret2,i,SWIG_From_int(ret[i])); + return ret2; + } + + PyObject *getNonEmptyLevels(const std::string& mname=std::string()) const throw(INTERP_KERNEL::Exception) + { + std::vector<int> ret1; + int ret0=self->getNonEmptyLevels(mname,ret1); + PyObject *elt=PyTuple_New(2); + PyTuple_SetItem(elt,0,SWIG_From_int(ret0)); + PyTuple_SetItem(elt,1,convertIntArrToPyList2(ret1)); + return elt; + } + + PyObject *getFieldSplitedByType(const std::string& mname=std::string()) const throw(INTERP_KERNEL::Exception) + { + std::vector<INTERP_KERNEL::NormalizedCellType> types; + std::vector< std::vector<TypeOfField> > typesF; + std::vector< std::vector<std::string> > pfls; + std::vector< std::vector<std::string> > locs; + std::vector< std::vector< std::pair<int,int> > > ret=self->getFieldSplitedByType(mname,types,typesF,pfls,locs); + int sz=ret.size(); + PyObject *ret2=PyList_New(sz); + for(int i=0;i<sz;i++) + { + const std::vector< std::pair<int,int> >& dadsI=ret[i]; + const std::vector<TypeOfField>& typesFI=typesF[i]; + const std::vector<std::string>& pflsI=pfls[i]; + const std::vector<std::string>& locsI=locs[i]; + PyObject *elt=PyTuple_New(2); + PyTuple_SetItem(elt,0,SWIG_From_int(types[i])); + int sz2=ret[i].size(); + PyObject *elt2=PyList_New(sz2); + for(int j=0;j<sz2;j++) + { + PyObject *elt3=PyTuple_New(4); + PyTuple_SetItem(elt3,0,SWIG_From_int(typesFI[j])); + PyObject *elt4=PyTuple_New(2); PyTuple_SetItem(elt4,0,SWIG_From_int(dadsI[j].first)); PyTuple_SetItem(elt4,1,SWIG_From_int(dadsI[j].second)); + PyTuple_SetItem(elt3,1,elt4); + PyTuple_SetItem(elt3,2,PyString_FromString(pflsI[j].c_str())); + PyTuple_SetItem(elt3,3,PyString_FromString(locsI[j].c_str())); + PyList_SetItem(elt2,j,elt3); + } + PyTuple_SetItem(elt,1,elt2); + PyList_SetItem(ret2,i,elt); + } + return ret2; + } + + PyObject *splitComponents() const throw(INTERP_KERNEL::Exception) + { + std::vector< MEDCouplingAutoRefCountObjectPtr< MEDFileAnyTypeField1TS > > ret=self->splitComponents(); + std::size_t sz=ret.size(); + PyObject *retPy=PyList_New(sz); + for(std::size_t i=0;i<sz;i++) + PyList_SetItem(retPy,i,convertMEDFileField1TS(ret[i].retn(), SWIG_POINTER_OWN | 0 )); + return retPy; + } + + PyObject *splitDiscretizations() const throw(INTERP_KERNEL::Exception) + { + std::vector< MEDCouplingAutoRefCountObjectPtr< MEDFileAnyTypeField1TS > > ret=self->splitDiscretizations(); + std::size_t sz=ret.size(); + PyObject *retPy=PyList_New(sz); + for(std::size_t i=0;i<sz;i++) + PyList_SetItem(retPy,i,convertMEDFileField1TS(ret[i].retn(), SWIG_POINTER_OWN | 0 )); + return retPy; + } + + PyObject *splitMultiDiscrPerGeoTypes() const throw(INTERP_KERNEL::Exception) + { + std::vector< MEDCouplingAutoRefCountObjectPtr< MEDFileAnyTypeField1TS > > ret=self->splitMultiDiscrPerGeoTypes(); + std::size_t sz=ret.size(); + PyObject *retPy=PyList_New(sz); + for(std::size_t i=0;i<sz;i++) + PyList_SetItem(retPy,i,convertMEDFileField1TS(ret[i].retn(), SWIG_POINTER_OWN | 0 )); + return retPy; + } + } + }; + + class MEDFileField1TS : public MEDFileAnyTypeField1TS + { + public: + static MEDFileField1TS *New(const std::string& fileName, const std::string& fieldName, int iteration, int order, bool loadAll=true) throw(INTERP_KERNEL::Exception); + static MEDFileField1TS *New(const std::string& fileName, const std::string& fieldName, bool loadAll=true) throw(INTERP_KERNEL::Exception); + static MEDFileField1TS *New(const std::string& fileName, bool loadAll=true) throw(INTERP_KERNEL::Exception); + static MEDFileField1TS *New(); + ParaMEDMEM::MEDFileIntField1TS *convertToInt(bool isDeepCpyGlobs=true) const throw(INTERP_KERNEL::Exception); + MEDCouplingFieldDouble *getFieldAtLevel(TypeOfField type, int meshDimRelToMax, int renumPol=0) const throw(INTERP_KERNEL::Exception); + MEDCouplingFieldDouble *getFieldAtTopLevel(TypeOfField type, int renumPol=0) const throw(INTERP_KERNEL::Exception); + MEDCouplingFieldDouble *getFieldOnMeshAtLevel(TypeOfField type, const MEDCouplingMesh *mesh, int renumPol=0) const throw(INTERP_KERNEL::Exception); + MEDCouplingFieldDouble *getFieldOnMeshAtLevel(TypeOfField type, int meshDimRelToMax, const MEDFileMesh *mesh, int renumPol=0) const throw(INTERP_KERNEL::Exception); + MEDCouplingFieldDouble *getFieldAtLevelOld(TypeOfField type, const std::string& mname, int meshDimRelToMax, int renumPol=0) const throw(INTERP_KERNEL::Exception); + // + void setFieldNoProfileSBT(const MEDCouplingFieldDouble *field) throw(INTERP_KERNEL::Exception); + void setFieldProfile(const MEDCouplingFieldDouble *field, const MEDFileMesh *mesh, int meshDimRelToMax, const DataArrayInt *profile) throw(INTERP_KERNEL::Exception); + void setProfileNameOnLeaf(const std::string& mName, INTERP_KERNEL::NormalizedCellType typ, int locId, const std::string& newPflName, bool forceRenameOnGlob=false) throw(INTERP_KERNEL::Exception); + void setLocNameOnLeaf(const std::string& mName, INTERP_KERNEL::NormalizedCellType typ, int locId, const std::string& newLocName, bool forceRenameOnGlob=false) throw(INTERP_KERNEL::Exception); + %extend + { + MEDFileField1TS(const std::string& fileName, bool loadAll=true) throw(INTERP_KERNEL::Exception) + { + return MEDFileField1TS::New(fileName,loadAll); + } + + MEDFileField1TS(const std::string& fileName, const std::string& fieldName, bool loadAll=true) throw(INTERP_KERNEL::Exception) + { + return MEDFileField1TS::New(fileName,fieldName,loadAll); + } + + MEDFileField1TS(const std::string& fileName, const std::string& fieldName, int iteration, int order, bool loadAll=true) throw(INTERP_KERNEL::Exception) + { + return MEDFileField1TS::New(fileName,fieldName,iteration,order,loadAll); + } + + MEDFileField1TS() + { + return MEDFileField1TS::New(); + } + + void copyTinyInfoFrom(const MEDCouplingFieldDouble *field) throw(INTERP_KERNEL::Exception) + { + const DataArrayDouble *arr=0; + if(field) + arr=field->getArray(); + self->copyTinyInfoFrom(field,arr); + } + + std::string __str__() const throw(INTERP_KERNEL::Exception) + { + return self->simpleRepr(); + } + + PyObject *getFieldWithProfile(TypeOfField type, int meshDimRelToMax, const MEDFileMesh *mesh) const throw(INTERP_KERNEL::Exception) + { + DataArrayInt *ret1=0; + DataArrayDouble *ret0=self->getFieldWithProfile(type,meshDimRelToMax,mesh,ret1); + PyObject *ret=PyTuple_New(2); + PyTuple_SetItem(ret,0,SWIG_NewPointerObj(SWIG_as_voidptr(ret0),SWIGTYPE_p_ParaMEDMEM__DataArrayDouble, SWIG_POINTER_OWN | 0 )); + PyTuple_SetItem(ret,1,SWIG_NewPointerObj(SWIG_as_voidptr(ret1),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 )); + return ret; + } + + PyObject *getFieldSplitedByType2(const std::string& mname=std::string()) const throw(INTERP_KERNEL::Exception) + { + std::vector<INTERP_KERNEL::NormalizedCellType> types; + std::vector< std::vector<TypeOfField> > typesF; + std::vector< std::vector<std::string> > pfls; + std::vector< std::vector<std::string> > locs; + std::vector< std::vector<DataArrayDouble *> > ret=self->getFieldSplitedByType2(mname,types,typesF,pfls,locs); + int sz=ret.size(); + PyObject *ret2=PyList_New(sz); + for(int i=0;i<sz;i++) + { + const std::vector<DataArrayDouble *>& dadsI=ret[i]; + const std::vector<TypeOfField>& typesFI=typesF[i]; + const std::vector<std::string>& pflsI=pfls[i]; + const std::vector<std::string>& locsI=locs[i]; + PyObject *elt=PyTuple_New(2); + PyTuple_SetItem(elt,0,SWIG_From_int(types[i])); + int sz2=ret[i].size(); + PyObject *elt2=PyList_New(sz2); + for(int j=0;j<sz2;j++) + { + PyObject *elt3=PyTuple_New(4); + PyTuple_SetItem(elt3,0,SWIG_From_int(typesFI[j])); + PyTuple_SetItem(elt3,1,SWIG_NewPointerObj(SWIG_as_voidptr(dadsI[j]),SWIGTYPE_p_ParaMEDMEM__DataArrayDouble, SWIG_POINTER_OWN | 0 )); + PyTuple_SetItem(elt3,2,PyString_FromString(pflsI[j].c_str())); + PyTuple_SetItem(elt3,3,PyString_FromString(locsI[j].c_str())); + PyList_SetItem(elt2,j,elt3); + } + PyTuple_SetItem(elt,1,elt2); + PyList_SetItem(ret2,i,elt); + } + return ret2; + } + + DataArrayDouble *getUndergroundDataArray() const throw(INTERP_KERNEL::Exception) + { + DataArrayDouble *ret=self->getUndergroundDataArray(); + if(ret) + ret->incrRef(); + return ret; + } + + PyObject *getUndergroundDataArrayExt() const throw(INTERP_KERNEL::Exception) + { + std::vector< std::pair<std::pair<INTERP_KERNEL::NormalizedCellType,int>,std::pair<int,int> > > elt1Cpp; + DataArrayDouble *elt0=self->getUndergroundDataArrayExt(elt1Cpp); + if(elt0) + elt0->incrRef(); + PyObject *ret=PyTuple_New(2); + PyTuple_SetItem(ret,0,SWIG_NewPointerObj(SWIG_as_voidptr(elt0),SWIGTYPE_p_ParaMEDMEM__DataArrayDouble, SWIG_POINTER_OWN | 0 )); + std::size_t sz=elt1Cpp.size(); + PyObject *elt=PyList_New(sz); + for(std::size_t i=0;i<sz;i++) + { + PyObject *elt1=PyTuple_New(2); + PyObject *elt2=PyTuple_New(2); + PyTuple_SetItem(elt2,0,SWIG_From_int((int)elt1Cpp[i].first.first)); + PyTuple_SetItem(elt2,1,SWIG_From_int(elt1Cpp[i].first.second)); + PyObject *elt3=PyTuple_New(2); + PyTuple_SetItem(elt3,0,SWIG_From_int(elt1Cpp[i].second.first)); + PyTuple_SetItem(elt3,1,SWIG_From_int(elt1Cpp[i].second.second)); + PyTuple_SetItem(elt1,0,elt2); + PyTuple_SetItem(elt1,1,elt3); + PyList_SetItem(elt,i,elt1); + } + PyTuple_SetItem(ret,1,elt); + return ret; + } + } + }; + + class MEDFileIntField1TS : public MEDFileAnyTypeField1TS + { + public: + static MEDFileIntField1TS *New(); + static MEDFileIntField1TS *New(const std::string& fileName, bool loadAll=true) throw(INTERP_KERNEL::Exception); + static MEDFileIntField1TS *New(const std::string& fileName, const std::string& fieldName, bool loadAll=true) throw(INTERP_KERNEL::Exception); + static MEDFileIntField1TS *New(const std::string& fileName, const std::string& fieldName, int iteration, int order, bool loadAll=true) throw(INTERP_KERNEL::Exception); + ParaMEDMEM::MEDFileField1TS *convertToDouble(bool isDeepCpyGlobs=true) const throw(INTERP_KERNEL::Exception); + // + void setFieldNoProfileSBT(const MEDCouplingFieldDouble *field, const DataArrayInt *arrOfVals) throw(INTERP_KERNEL::Exception); + void setFieldProfile(const MEDCouplingFieldDouble *field, const DataArrayInt *arrOfVals, const MEDFileMesh *mesh, int meshDimRelToMax, const DataArrayInt *profile) throw(INTERP_KERNEL::Exception); + %extend + { + MEDFileIntField1TS() throw(INTERP_KERNEL::Exception) + { + return MEDFileIntField1TS::New(); + } + + MEDFileIntField1TS(const std::string& fileName, bool loadAll=true) throw(INTERP_KERNEL::Exception) + { + return MEDFileIntField1TS::New(fileName,loadAll); + } + + MEDFileIntField1TS(const std::string& fileName, const std::string& fieldName, bool loadAll=true) throw(INTERP_KERNEL::Exception) + { + return MEDFileIntField1TS::New(fileName,fieldName,loadAll); + } + + MEDFileIntField1TS(const std::string& fileName, const std::string& fieldName, int iteration, int order, bool loadAll=true) throw(INTERP_KERNEL::Exception) + { + return MEDFileIntField1TS::New(fileName,fieldName,iteration,order,loadAll); + } + + std::string __str__() const throw(INTERP_KERNEL::Exception) + { + return self->simpleRepr(); + } + + PyObject *getFieldAtLevel(TypeOfField type, int meshDimRelToMax, int renumPol=0) const throw(INTERP_KERNEL::Exception) + { + DataArrayInt *ret1=0; + MEDCouplingFieldDouble *ret0=self->getFieldAtLevel(type,meshDimRelToMax,ret1,renumPol); + PyObject *ret=PyTuple_New(2); + PyTuple_SetItem(ret,0,SWIG_NewPointerObj(SWIG_as_voidptr(ret0),SWIGTYPE_p_ParaMEDMEM__MEDCouplingFieldDouble, SWIG_POINTER_OWN | 0 )); + PyTuple_SetItem(ret,1,SWIG_NewPointerObj(SWIG_as_voidptr(ret1),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 )); + return ret; + } + + PyObject *getFieldAtTopLevel(TypeOfField type, int renumPol=0) const throw(INTERP_KERNEL::Exception) + { + DataArrayInt *ret1=0; + MEDCouplingFieldDouble *ret0=self->getFieldAtTopLevel(type,ret1,renumPol); + PyObject *ret=PyTuple_New(2); + PyTuple_SetItem(ret,0,SWIG_NewPointerObj(SWIG_as_voidptr(ret0),SWIGTYPE_p_ParaMEDMEM__MEDCouplingFieldDouble, SWIG_POINTER_OWN | 0 )); + PyTuple_SetItem(ret,1,SWIG_NewPointerObj(SWIG_as_voidptr(ret1),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 )); + return ret; + } + + PyObject *getFieldOnMeshAtLevel(TypeOfField type, int meshDimRelToMax, const MEDFileMesh *mesh, int renumPol=0) const throw(INTERP_KERNEL::Exception) + { + DataArrayInt *ret1=0; + MEDCouplingFieldDouble *ret0=self->getFieldOnMeshAtLevel(type,meshDimRelToMax,mesh,ret1,renumPol); + PyObject *ret=PyTuple_New(2); + PyTuple_SetItem(ret,0,SWIG_NewPointerObj(SWIG_as_voidptr(ret0),SWIGTYPE_p_ParaMEDMEM__MEDCouplingFieldDouble, SWIG_POINTER_OWN | 0 )); + PyTuple_SetItem(ret,1,SWIG_NewPointerObj(SWIG_as_voidptr(ret1),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 )); + return ret; + } + + PyObject *getFieldOnMeshAtLevel(TypeOfField type, const MEDCouplingMesh *mesh, int renumPol=0) const throw(INTERP_KERNEL::Exception) + { + DataArrayInt *ret1=0; + MEDCouplingFieldDouble *ret0=self->getFieldOnMeshAtLevel(type,mesh,ret1,renumPol); + PyObject *ret=PyTuple_New(2); + PyTuple_SetItem(ret,0,SWIG_NewPointerObj(SWIG_as_voidptr(ret0),SWIGTYPE_p_ParaMEDMEM__MEDCouplingFieldDouble, SWIG_POINTER_OWN | 0 )); + PyTuple_SetItem(ret,1,SWIG_NewPointerObj(SWIG_as_voidptr(ret1),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 )); + return ret; + } + + PyObject *getFieldAtLevelOld(TypeOfField type, const std::string& mname, int meshDimRelToMax, int renumPol=0) const throw(INTERP_KERNEL::Exception) + { + DataArrayInt *ret1=0; + MEDCouplingFieldDouble *ret0=self->getFieldAtLevelOld(type,mname,meshDimRelToMax,ret1,renumPol); + PyObject *ret=PyTuple_New(2); + PyTuple_SetItem(ret,0,SWIG_NewPointerObj(SWIG_as_voidptr(ret0),SWIGTYPE_p_ParaMEDMEM__MEDCouplingFieldDouble, SWIG_POINTER_OWN | 0 )); + PyTuple_SetItem(ret,1,SWIG_NewPointerObj(SWIG_as_voidptr(ret1),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 )); + return ret; + } + + PyObject *getFieldWithProfile(TypeOfField type, int meshDimRelToMax, const MEDFileMesh *mesh) const throw(INTERP_KERNEL::Exception) + { + DataArrayInt *ret1=0; + DataArrayInt *ret0=self->getFieldWithProfile(type,meshDimRelToMax,mesh,ret1); + PyObject *ret=PyTuple_New(2); + PyTuple_SetItem(ret,0,SWIG_NewPointerObj(SWIG_as_voidptr(ret0),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 )); + PyTuple_SetItem(ret,1,SWIG_NewPointerObj(SWIG_as_voidptr(ret1),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 )); + return ret; + } + + DataArrayInt *getUndergroundDataArray() const throw(INTERP_KERNEL::Exception) + { + DataArrayInt *ret=self->getUndergroundDataArray(); + if(ret) + ret->incrRef(); + return ret; + } + } + }; + + class MEDFileAnyTypeFieldMultiTSIterator + { + public: + %extend + { + PyObject *next() throw(INTERP_KERNEL::Exception) + { + MEDFileAnyTypeField1TS *ret=self->nextt(); + if(ret) + return convertMEDFileField1TS(ret, SWIG_POINTER_OWN | 0 ); + else + { + PyErr_SetString(PyExc_StopIteration,"No more data."); + return 0; + } + } + } + }; + + class MEDFileAnyTypeFieldMultiTS : public RefCountObject, public MEDFileFieldGlobsReal, public MEDFileWritable + { + public: + static MEDFileAnyTypeFieldMultiTS *New(const std::string& fileName, bool loadAll=true) throw(INTERP_KERNEL::Exception); + static MEDFileAnyTypeFieldMultiTS *New(const std::string& fileName, const std::string& fieldName, bool loadAll=true) throw(INTERP_KERNEL::Exception); + MEDFileAnyTypeFieldMultiTS *deepCpy() const throw(INTERP_KERNEL::Exception); + virtual MEDFileAnyTypeFieldMultiTS *shallowCpy() const throw(INTERP_KERNEL::Exception); + std::string getName() const throw(INTERP_KERNEL::Exception); + void setName(const std::string& name) throw(INTERP_KERNEL::Exception); + std::string getDtUnit() const throw(INTERP_KERNEL::Exception); + void setDtUnit(const std::string& dtUnit) throw(INTERP_KERNEL::Exception); + std::string getMeshName() const throw(INTERP_KERNEL::Exception); + void setMeshName(const std::string& newMeshName) throw(INTERP_KERNEL::Exception); + const std::vector<std::string>& getInfo() const throw(INTERP_KERNEL::Exception); + bool presenceOfMultiDiscPerGeoType() const throw(INTERP_KERNEL::Exception); + int getNumberOfComponents() const throw(INTERP_KERNEL::Exception); + int getNumberOfTS() const throw(INTERP_KERNEL::Exception); + void eraseEmptyTS() throw(INTERP_KERNEL::Exception); + int getPosOfTimeStep(int iteration, int order) const throw(INTERP_KERNEL::Exception); + int getPosGivenTime(double time, double eps=1e-8) const throw(INTERP_KERNEL::Exception); + void write(const std::string& fileName, int mode) const throw(INTERP_KERNEL::Exception); + void loadArrays() throw(INTERP_KERNEL::Exception); + void loadArraysIfNecessary() throw(INTERP_KERNEL::Exception); + void unloadArrays() throw(INTERP_KERNEL::Exception); + void unloadArraysWithoutDataLoss() throw(INTERP_KERNEL::Exception); + // + virtual MEDFileAnyTypeField1TS *getTimeStepAtPos(int pos) const throw(INTERP_KERNEL::Exception); + MEDFileAnyTypeField1TS *getTimeStep(int iteration, int order) const throw(INTERP_KERNEL::Exception); + MEDFileAnyTypeField1TS *getTimeStepGivenTime(double time, double eps=1e-8) const throw(INTERP_KERNEL::Exception); + void pushBackTimeStep(MEDFileAnyTypeField1TS *f1ts) throw(INTERP_KERNEL::Exception); + void synchronizeNameScope() throw(INTERP_KERNEL::Exception); + %extend + { + int __len__() const throw(INTERP_KERNEL::Exception) + { + return self->getNumberOfTS(); + } + + int getTimeId(PyObject *elt0) const throw(INTERP_KERNEL::Exception) + { + if(elt0 && PyInt_Check(elt0)) + {//fmts[3] + int pos=PyInt_AS_LONG(elt0); + return pos; + } + else if(elt0 && PyTuple_Check(elt0)) + { + if(PyTuple_Size(elt0)==2) + { + PyObject *o0=PyTuple_GetItem(elt0,0); + PyObject *o1=PyTuple_GetItem(elt0,1); + if(PyInt_Check(o0) && PyInt_Check(o1)) + {//fmts(1,-1) + int iter=PyInt_AS_LONG(o0); + int order=PyInt_AS_LONG(o1); + return self->getPosOfTimeStep(iter,order); + } + else + throw INTERP_KERNEL::Exception("MEDFileAnyTypeFieldMultiTS::__getitem__ : invalid input param ! input is a tuple of size 2 but two integers are expected in this tuple to request a time steps !"); + } + else + throw INTERP_KERNEL::Exception("MEDFileAnyTypeFieldMultiTS::__getitem__ : invalid input param ! input is a tuple of size != 2 ! two integers are expected in this tuple to request a time steps !"); + } + else if(elt0 && PyFloat_Check(elt0)) + { + double val=PyFloat_AS_DOUBLE(elt0); + return self->getPosGivenTime(val); + } + else + throw INTERP_KERNEL::Exception("MEDFileAnyTypeFieldMultiTS::__getitem__ : invalid input params ! expected fmts[int], fmts[int,int] or fmts[double] to request time step !"); + } + + PyObject *getIterations() const throw(INTERP_KERNEL::Exception) + { + std::vector< std::pair<int,int> > res=self->getIterations(); + PyObject *ret=PyList_New(res.size()); + int rk=0; + for(std::vector< std::pair<int,int> >::const_iterator iter=res.begin();iter!=res.end();iter++,rk++) + { + PyObject *elt=PyTuple_New(2); + PyTuple_SetItem(elt,0,SWIG_From_int((*iter).first)); + PyTuple_SetItem(elt,1,SWIG_From_int((*iter).second)); + PyList_SetItem(ret,rk,elt); + } + return ret; + } + + PyObject *getTimeSteps() const throw(INTERP_KERNEL::Exception) + { + std::vector<double> ret1; + std::vector< std::pair<int,int> > ret=self->getTimeSteps(ret1); + std::size_t sz=ret.size(); + PyObject *ret2=PyList_New(sz); + for(std::size_t i=0;i<sz;i++) + { + PyObject *elt=PyTuple_New(3); + PyTuple_SetItem(elt,0,SWIG_From_int(ret[i].first)); + PyTuple_SetItem(elt,1,SWIG_From_int(ret[i].second)); + PyTuple_SetItem(elt,2,SWIG_From_double(ret1[i])); + PyList_SetItem(ret2,i,elt); + } + return ret2; + } + + PyObject *getTypesOfFieldAvailable() const throw(INTERP_KERNEL::Exception) + { + std::vector< std::vector<TypeOfField> > ret=self->getTypesOfFieldAvailable(); + PyObject *ret2=PyList_New(ret.size()); + for(int i=0;i<(int)ret.size();i++) + { + const std::vector<TypeOfField>& rett=ret[i]; + PyObject *ret3=PyList_New(rett.size()); + for(int j=0;j<(int)rett.size();j++) + PyList_SetItem(ret3,j,SWIG_From_int(rett[j])); + PyList_SetItem(ret2,i,ret3); + } + return ret2; + } + + PyObject *getNonEmptyLevels(int iteration, int order, const std::string& mname=std::string()) const throw(INTERP_KERNEL::Exception) + { + std::vector<int> ret1; + int ret0=self->getNonEmptyLevels(iteration,order,mname,ret1); + PyObject *elt=PyTuple_New(2); + PyTuple_SetItem(elt,0,SWIG_From_int(ret0)); + PyTuple_SetItem(elt,1,convertIntArrToPyList2(ret1)); + return elt; + } + + PyObject *getFieldSplitedByType(int iteration, int order, const std::string& mname=std::string()) const throw(INTERP_KERNEL::Exception) + { + std::vector<INTERP_KERNEL::NormalizedCellType> types; + std::vector< std::vector<TypeOfField> > typesF; + std::vector< std::vector<std::string> > pfls; + std::vector< std::vector<std::string> > locs; + std::vector< std::vector< std::pair<int,int> > > ret=self->getFieldSplitedByType(iteration,order,mname,types,typesF,pfls,locs); + int sz=ret.size(); + PyObject *ret2=PyList_New(sz); + for(int i=0;i<sz;i++) + { + const std::vector< std::pair<int,int> >& dadsI=ret[i]; + const std::vector<TypeOfField>& typesFI=typesF[i]; + const std::vector<std::string>& pflsI=pfls[i]; + const std::vector<std::string>& locsI=locs[i]; + PyObject *elt=PyTuple_New(2); + PyTuple_SetItem(elt,0,SWIG_From_int(types[i])); + int sz2=ret[i].size(); + PyObject *elt2=PyList_New(sz2); + for(int j=0;j<sz2;j++) + { + PyObject *elt3=PyTuple_New(4); + PyTuple_SetItem(elt3,0,SWIG_From_int(typesFI[j])); + PyObject *elt4=PyTuple_New(2); PyTuple_SetItem(elt4,0,SWIG_From_int(dadsI[j].first)); PyTuple_SetItem(elt4,1,SWIG_From_int(dadsI[j].second)); + PyTuple_SetItem(elt3,1,elt4); + PyTuple_SetItem(elt3,2,PyString_FromString(pflsI[j].c_str())); + PyTuple_SetItem(elt3,3,PyString_FromString(locsI[j].c_str())); + PyList_SetItem(elt2,j,elt3); + } + PyTuple_SetItem(elt,1,elt2); + PyList_SetItem(ret2,i,elt); + } + return ret2; + } + + std::vector<int> getTimeIds(PyObject *elts) const throw(INTERP_KERNEL::Exception) + { + if(PyList_Check(elts)) + { + int sz=PyList_Size(elts); + std::vector<int> ret(sz); + for(int i=0;i<sz;i++) + { + PyObject *elt=PyList_GetItem(elts,i); + ret[i]=ParaMEDMEM_MEDFileAnyTypeFieldMultiTS_getTimeId(self,elt); + } + return ret; + } + else + { + std::vector<int> ret(1); + ret[0]=ParaMEDMEM_MEDFileAnyTypeFieldMultiTS_getTimeId(self,elts); + return ret; + } + } + + void __delitem__(PyObject *elts) throw(INTERP_KERNEL::Exception) + { + if(PySlice_Check(elts)) + { + Py_ssize_t strt=2,stp=2,step=2; + PySliceObject *oC=reinterpret_cast<PySliceObject *>(elts); + GetIndicesOfSlice(oC,self->getNumberOfTS(),&strt,&stp,&step,"MEDFileAnyTypeFieldMultiTS.__delitem__ : error in input slice !"); + self->eraseTimeStepIds2(strt,stp,step); + } + else + { + std::vector<int> idsToRemove=ParaMEDMEM_MEDFileAnyTypeFieldMultiTS_getTimeIds(self,elts); + if(!idsToRemove.empty()) + self->eraseTimeStepIds(&idsToRemove[0],&idsToRemove[0]+idsToRemove.size()); + } + } + + void eraseTimeStepIds(PyObject *li) throw(INTERP_KERNEL::Exception) + { + int sw; + int pos1; + std::vector<int> pos2; + DataArrayInt *pos3=0; + DataArrayIntTuple *pos4=0; + convertObjToPossibleCpp1(li,sw,pos1,pos2,pos3,pos4); + switch(sw) + { + case 1: + { + self->eraseTimeStepIds(&pos1,&pos1+1); + return; + } + case 2: + { + if(pos2.empty()) + return; + self->eraseTimeStepIds(&pos2[0],&pos2[0]+pos2.size()); + return ; + } + case 3: + { + self->eraseTimeStepIds(pos3->begin(),pos3->end()); + return ; + } + default: + throw INTERP_KERNEL::Exception("MEDFileAnyTypeFieldMultiTS::eraseTimeStepIds : unexpected input array type recognized !"); + } + } + + MEDFileAnyTypeFieldMultiTSIterator *__iter__() throw(INTERP_KERNEL::Exception) + { + return self->iterator(); + } + + PyObject *__getitem__(PyObject *elt0) const throw(INTERP_KERNEL::Exception) + { + if(elt0 && PyList_Check(elt0)) + { + int sz=PyList_Size(elt0); + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> da=DataArrayInt::New(); da->alloc(sz,1); + int *pt=da->getPointer(); + for(int i=0;i<sz;i++,pt++) + { + PyObject *elt1=PyList_GetItem(elt0,i); + *pt=MEDFileAnyTypeFieldMultiTSgetitemSingleTS__(self,elt1); + } + return convertMEDFileFieldMultiTS(self->buildSubPart(da->begin(),da->end()),SWIG_POINTER_OWN | 0); + } + else if(elt0 && PySlice_Check(elt0)) + { + Py_ssize_t strt=2,stp=2,step=2; + PySliceObject *oC=reinterpret_cast<PySliceObject *>(elt0); + GetIndicesOfSlice(oC,self->getNumberOfTS(),&strt,&stp,&step,"MEDFileAnyTypeFieldMultiTS.__getitem__ : error in input slice !"); + return convertMEDFileFieldMultiTS(self->buildSubPartSlice(strt,stp,step),SWIG_POINTER_OWN | 0); + } + else + return convertMEDFileField1TS(self->getTimeStepAtPos(MEDFileAnyTypeFieldMultiTSgetitemSingleTS__(self,elt0)),SWIG_POINTER_OWN | 0); + } + + bool changeMeshNames(PyObject *li) throw(INTERP_KERNEL::Exception) + { + std::vector< std::pair<std::string,std::string> > modifTab=convertVecPairStStFromPy(li); + return self->changeMeshNames(modifTab); + } + + PyObject *splitComponents() const throw(INTERP_KERNEL::Exception) + { + std::vector< MEDCouplingAutoRefCountObjectPtr< MEDFileAnyTypeFieldMultiTS > > ret=self->splitComponents(); + std::size_t sz=ret.size(); + PyObject *retPy=PyList_New(sz); + for(std::size_t i=0;i<sz;i++) + PyList_SetItem(retPy,i,convertMEDFileFieldMultiTS(ret[i].retn(), SWIG_POINTER_OWN | 0 )); + return retPy; + } + + PyObject *splitDiscretizations() const throw(INTERP_KERNEL::Exception) + { + std::vector< MEDCouplingAutoRefCountObjectPtr< MEDFileAnyTypeFieldMultiTS > > ret=self->splitDiscretizations(); + std::size_t sz=ret.size(); + PyObject *retPy=PyList_New(sz); + for(std::size_t i=0;i<sz;i++) + PyList_SetItem(retPy,i,convertMEDFileFieldMultiTS(ret[i].retn(), SWIG_POINTER_OWN | 0 )); + return retPy; + } + + PyObject *splitMultiDiscrPerGeoTypes() const throw(INTERP_KERNEL::Exception) + { + std::vector< MEDCouplingAutoRefCountObjectPtr< MEDFileAnyTypeFieldMultiTS > > ret=self->splitMultiDiscrPerGeoTypes(); + std::size_t sz=ret.size(); + PyObject *retPy=PyList_New(sz); + for(std::size_t i=0;i<sz;i++) + PyList_SetItem(retPy,i,convertMEDFileFieldMultiTS(ret[i].retn(), SWIG_POINTER_OWN | 0 )); + return retPy; + } + + void pushBackTimeSteps(PyObject *li) throw(INTERP_KERNEL::Exception) + { + void *argp(0); + int status(SWIG_ConvertPtr(li,&argp,SWIGTYPE_p_ParaMEDMEM__MEDFileAnyTypeFieldMultiTS,0|0)); + if(SWIG_IsOK(status)) + { + self->pushBackTimeSteps(reinterpret_cast<MEDFileAnyTypeFieldMultiTS *>(argp)); + } + else + { + std::vector<MEDFileAnyTypeField1TS *> tmp; + convertFromPyObjVectorOfObj<ParaMEDMEM::MEDFileAnyTypeField1TS *>(li,SWIGTYPE_p_ParaMEDMEM__MEDFileAnyTypeField1TS,"MEDFileAnyTypeField1TS",tmp); + self->pushBackTimeSteps(tmp); + } + } + + static PyObject *MEDFileAnyTypeFieldMultiTS::SplitIntoCommonTimeSeries(PyObject *li) throw(INTERP_KERNEL::Exception) + { + std::vector<MEDFileAnyTypeFieldMultiTS *> vectFMTS; + convertFromPyObjVectorOfObj<ParaMEDMEM::MEDFileAnyTypeFieldMultiTS *>(li,SWIGTYPE_p_ParaMEDMEM__MEDFileAnyTypeFieldMultiTS,"MEDFileAnyTypeFieldMultiTS",vectFMTS); + std::vector< std::vector<MEDFileAnyTypeFieldMultiTS *> > ret=MEDFileAnyTypeFieldMultiTS::SplitIntoCommonTimeSeries(vectFMTS); + std::size_t sz=ret.size(); + PyObject *retPy=PyList_New(sz); + for(std::size_t i=0;i<sz;i++) + { + std::size_t sz2=ret[i].size(); + PyObject *ret1Py=PyList_New(sz2); + for(std::size_t j=0;j<sz2;j++) + { + MEDFileAnyTypeFieldMultiTS *elt(ret[i][j]); + if(elt) + elt->incrRef(); + PyList_SetItem(ret1Py,j,convertMEDFileFieldMultiTS(elt,SWIG_POINTER_OWN | 0 )); + } + PyList_SetItem(retPy,i,ret1Py); + } + return retPy; + } + + static PyObject *MEDFileAnyTypeFieldMultiTS::SplitPerCommonSupport(PyObject *li, const MEDFileMesh *mesh) throw(INTERP_KERNEL::Exception) + { + std::vector<MEDFileAnyTypeFieldMultiTS *> vectFMTS; + convertFromPyObjVectorOfObj<ParaMEDMEM::MEDFileAnyTypeFieldMultiTS *>(li,SWIGTYPE_p_ParaMEDMEM__MEDFileAnyTypeFieldMultiTS,"MEDFileAnyTypeFieldMultiTS",vectFMTS); + std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileFastCellSupportComparator> > ret2; + std::vector< std::vector<MEDFileAnyTypeFieldMultiTS *> > ret=MEDFileAnyTypeFieldMultiTS::SplitPerCommonSupport(vectFMTS,mesh,ret2); + if(ret2.size()!=ret.size()) + { + std::ostringstream oss; oss << "MEDFileAnyTypeFieldMultiTS::SplitPerCommonSupport (PyWrap) : internal error ! Size of 2 vectors must match ! (" << ret.size() << "!=" << ret2.size() << ") !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + std::size_t sz=ret.size(); + PyObject *retPy=PyList_New(sz); + for(std::size_t i=0;i<sz;i++) + { + std::size_t sz2=ret[i].size(); + PyObject *ret0Py=PyTuple_New(2); + PyObject *ret1Py=PyList_New(sz2); + for(std::size_t j=0;j<sz2;j++) + { + MEDFileAnyTypeFieldMultiTS *elt(ret[i][j]); + if(elt) + elt->incrRef(); + PyList_SetItem(ret1Py,j,convertMEDFileFieldMultiTS(elt,SWIG_POINTER_OWN | 0 )); + } + PyTuple_SetItem(ret0Py,0,ret1Py); + PyTuple_SetItem(ret0Py,1,SWIG_NewPointerObj(SWIG_as_voidptr(ret2[i].retn()),SWIGTYPE_p_ParaMEDMEM__MEDFileFastCellSupportComparator, SWIG_POINTER_OWN | 0 )); + PyList_SetItem(retPy,i,ret0Py); + } + return retPy; + } + } + }; + + class MEDFileFieldMultiTS : public MEDFileAnyTypeFieldMultiTS + { + public: + static MEDFileFieldMultiTS *New() throw(INTERP_KERNEL::Exception); + static MEDFileFieldMultiTS *New(const std::string& fileName, bool loadAll=true) throw(INTERP_KERNEL::Exception); + static MEDFileFieldMultiTS *New(const std::string& fileName, const std::string& fieldName, bool loadAll=true) throw(INTERP_KERNEL::Exception); + // + MEDCouplingFieldDouble *getFieldAtLevel(TypeOfField type, int iteration, int order, int meshDimRelToMax, int renumPol=0) const throw(INTERP_KERNEL::Exception); + MEDCouplingFieldDouble *getFieldAtTopLevel(TypeOfField type, int iteration, int order, int renumPol=0) const throw(INTERP_KERNEL::Exception); + MEDCouplingFieldDouble *getFieldOnMeshAtLevel(TypeOfField type, int iteration, int order, int meshDimRelToMax, const MEDFileMesh *mesh, int renumPol=0) const throw(INTERP_KERNEL::Exception); + MEDCouplingFieldDouble *getFieldOnMeshAtLevel(TypeOfField type, int iteration, int order, const MEDCouplingMesh *mesh, int renumPol=0) const throw(INTERP_KERNEL::Exception); + MEDCouplingFieldDouble *getFieldAtLevelOld(TypeOfField type, const std::string& mname, int iteration, int order, int meshDimRelToMax, int renumPol=0) const throw(INTERP_KERNEL::Exception); + // + void appendFieldNoProfileSBT(const MEDCouplingFieldDouble *field) throw(INTERP_KERNEL::Exception); + void appendFieldProfile(const MEDCouplingFieldDouble *field, const MEDFileMesh *mesh, int meshDimRelToMax, const DataArrayInt *profile) throw(INTERP_KERNEL::Exception); + ParaMEDMEM::MEDFileIntFieldMultiTS *convertToInt(bool isDeepCpyGlobs=true) const throw(INTERP_KERNEL::Exception); + %extend + { + MEDFileFieldMultiTS() + { + return MEDFileFieldMultiTS::New(); + } + + MEDFileFieldMultiTS(const std::string& fileName, bool loadAll=true) throw(INTERP_KERNEL::Exception) + { + return MEDFileFieldMultiTS::New(fileName,loadAll); + } + + MEDFileFieldMultiTS(const std::string& fileName, const std::string& fieldName, bool loadAll=true) throw(INTERP_KERNEL::Exception) + { + return MEDFileFieldMultiTS::New(fileName,fieldName,loadAll); + } + + static MEDFileFieldMultiTS *LoadSpecificEntities(const std::string& fileName, const std::string& fieldName, PyObject *entities, bool loadAll=true) + { + std::vector<std::pair<int,int> > tmp(convertTimePairIdsFromPy(entities)); + std::size_t sz(tmp.size()); + std::vector< std::pair<TypeOfField,INTERP_KERNEL::NormalizedCellType> > entitiesCpp(sz); + for(std::size_t i=0;i<sz;i++) + { + entitiesCpp[i].first=(TypeOfField)tmp[i].first; + entitiesCpp[i].second=(INTERP_KERNEL::NormalizedCellType)tmp[i].second; + } + return MEDFileFieldMultiTS::LoadSpecificEntities(fileName,fieldName,entitiesCpp,loadAll); + } + + std::string __str__() const throw(INTERP_KERNEL::Exception) + { + return self->simpleRepr(); + } + + PyObject *getFieldWithProfile(TypeOfField type, int iteration, int order, int meshDimRelToMax, const MEDFileMesh *mesh) const throw(INTERP_KERNEL::Exception) + { + DataArrayInt *ret1=0; + DataArrayDouble *ret0=self->getFieldWithProfile(type,iteration,order,meshDimRelToMax,mesh,ret1); + PyObject *ret=PyTuple_New(2); + PyTuple_SetItem(ret,0,SWIG_NewPointerObj(SWIG_as_voidptr(ret0),SWIGTYPE_p_ParaMEDMEM__DataArrayDouble, SWIG_POINTER_OWN | 0 )); + PyTuple_SetItem(ret,1,SWIG_NewPointerObj(SWIG_as_voidptr(ret1),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 )); + return ret; + } + + PyObject *getFieldSplitedByType2(int iteration, int order, const std::string& mname=std::string()) const throw(INTERP_KERNEL::Exception) + { + std::vector<INTERP_KERNEL::NormalizedCellType> types; + std::vector< std::vector<TypeOfField> > typesF; + std::vector< std::vector<std::string> > pfls; + std::vector< std::vector<std::string> > locs; + std::vector< std::vector<DataArrayDouble *> > ret=self->getFieldSplitedByType2(iteration,order,mname,types,typesF,pfls,locs); + int sz=ret.size(); + PyObject *ret2=PyList_New(sz); + for(int i=0;i<sz;i++) + { + const std::vector<DataArrayDouble *>& dadsI=ret[i]; + const std::vector<TypeOfField>& typesFI=typesF[i]; + const std::vector<std::string>& pflsI=pfls[i]; + const std::vector<std::string>& locsI=locs[i]; + PyObject *elt=PyTuple_New(2); + PyTuple_SetItem(elt,0,SWIG_From_int(types[i])); + int sz2=ret[i].size(); + PyObject *elt2=PyList_New(sz2); + for(int j=0;j<sz2;j++) + { + PyObject *elt3=PyTuple_New(4); + PyTuple_SetItem(elt3,0,SWIG_From_int(typesFI[j])); + PyTuple_SetItem(elt3,1,SWIG_NewPointerObj(SWIG_as_voidptr(dadsI[j]),SWIGTYPE_p_ParaMEDMEM__DataArrayDouble, SWIG_POINTER_OWN | 0 )); + PyTuple_SetItem(elt3,2,PyString_FromString(pflsI[j].c_str())); + PyTuple_SetItem(elt3,3,PyString_FromString(locsI[j].c_str())); + PyList_SetItem(elt2,j,elt3); + } + PyTuple_SetItem(elt,1,elt2); + PyList_SetItem(ret2,i,elt); + } + return ret2; + } + DataArrayDouble *getUndergroundDataArray(int iteration, int order) const throw(INTERP_KERNEL::Exception) + { + DataArrayDouble *ret=self->getUndergroundDataArray(iteration,order); + if(ret) + ret->incrRef(); + return ret; + } + + PyObject *getUndergroundDataArrayExt(int iteration, int order) const throw(INTERP_KERNEL::Exception) + { + std::vector< std::pair<std::pair<INTERP_KERNEL::NormalizedCellType,int>,std::pair<int,int> > > elt1Cpp; + DataArrayDouble *elt0=self->getUndergroundDataArrayExt(iteration,order,elt1Cpp); + if(elt0) + elt0->incrRef(); + PyObject *ret=PyTuple_New(2); + PyTuple_SetItem(ret,0,SWIG_NewPointerObj(SWIG_as_voidptr(elt0),SWIGTYPE_p_ParaMEDMEM__DataArrayDouble, SWIG_POINTER_OWN | 0 )); + std::size_t sz=elt1Cpp.size(); + PyObject *elt=PyList_New(sz); + for(std::size_t i=0;i<sz;i++) + { + PyObject *elt1=PyTuple_New(2); + PyObject *elt2=PyTuple_New(2); + PyTuple_SetItem(elt2,0,SWIG_From_int(elt1Cpp[i].first.first)); + PyTuple_SetItem(elt2,1,SWIG_From_int(elt1Cpp[i].first.second)); + PyObject *elt3=PyTuple_New(2); + PyTuple_SetItem(elt3,0,SWIG_From_int(elt1Cpp[i].second.first)); + PyTuple_SetItem(elt3,1,SWIG_From_int(elt1Cpp[i].second.second)); + PyTuple_SetItem(elt1,0,elt2); + PyTuple_SetItem(elt1,1,elt3); + PyList_SetItem(elt,i,elt1); + } + PyTuple_SetItem(ret,1,elt); + return ret; + } + } + }; + + class MEDFileFieldsIterator + { + public: + %extend + { + PyObject *next() throw(INTERP_KERNEL::Exception) + { + MEDFileAnyTypeFieldMultiTS *ret=self->nextt(); + if(ret) + return convertMEDFileFieldMultiTS(ret, SWIG_POINTER_OWN | 0 ); + else + { + PyErr_SetString(PyExc_StopIteration,"No more data."); + return 0; + } + } + } + }; + + class MEDFileIntFieldMultiTS : public MEDFileAnyTypeFieldMultiTS + { + public: + static MEDFileIntFieldMultiTS *New(); + static MEDFileIntFieldMultiTS *New(const std::string& fileName, bool loadAll=true) throw(INTERP_KERNEL::Exception); + static MEDFileIntFieldMultiTS *New(const std::string& fileName, const std::string& fieldName, bool loadAll=true) throw(INTERP_KERNEL::Exception); + // + void appendFieldNoProfileSBT(const MEDCouplingFieldDouble *field, const DataArrayInt *arrOfVals) throw(INTERP_KERNEL::Exception); + void appendFieldProfile(const MEDCouplingFieldDouble *field, const DataArrayInt *arrOfVals, const MEDFileMesh *mesh, int meshDimRelToMax, const DataArrayInt *profile) throw(INTERP_KERNEL::Exception); + ParaMEDMEM::MEDFileFieldMultiTS *convertToDouble(bool isDeepCpyGlobs=true) const throw(INTERP_KERNEL::Exception); + %extend + { + MEDFileIntFieldMultiTS() + { + return MEDFileIntFieldMultiTS::New(); + } + + MEDFileIntFieldMultiTS(const std::string& fileName, bool loadAll=true) throw(INTERP_KERNEL::Exception) + { + return MEDFileIntFieldMultiTS::New(fileName,loadAll); + } + + MEDFileIntFieldMultiTS(const std::string& fileName, const std::string& fieldName, bool loadAll=true) throw(INTERP_KERNEL::Exception) + { + return MEDFileIntFieldMultiTS::New(fileName,fieldName,loadAll); + } + + static MEDFileIntFieldMultiTS *LoadSpecificEntities(const std::string& fileName, const std::string& fieldName, PyObject *entities, bool loadAll=true) + { + std::vector<std::pair<int,int> > tmp(convertTimePairIdsFromPy(entities)); + std::size_t sz(tmp.size()); + std::vector< std::pair<TypeOfField,INTERP_KERNEL::NormalizedCellType> > entitiesCpp(sz); + for(std::size_t i=0;i<sz;i++) + { + entitiesCpp[i].first=(TypeOfField)tmp[i].first; + entitiesCpp[i].second=(INTERP_KERNEL::NormalizedCellType)tmp[i].second; + } + return MEDFileIntFieldMultiTS::LoadSpecificEntities(fileName,fieldName,entitiesCpp,loadAll); + } + + std::string __str__() const throw(INTERP_KERNEL::Exception) + { + return self->simpleRepr(); + } + + PyObject *getFieldAtLevel(TypeOfField type, int iteration, int order, int meshDimRelToMax, int renumPol=0) const throw(INTERP_KERNEL::Exception) + { + DataArrayInt *ret1=0; + MEDCouplingFieldDouble *ret0=self->getFieldAtLevel(type,iteration,order,meshDimRelToMax,ret1,renumPol); + PyObject *ret=PyTuple_New(2); + PyTuple_SetItem(ret,0,SWIG_NewPointerObj(SWIG_as_voidptr(ret0),SWIGTYPE_p_ParaMEDMEM__MEDCouplingFieldDouble, SWIG_POINTER_OWN | 0 )); + PyTuple_SetItem(ret,1,SWIG_NewPointerObj(SWIG_as_voidptr(ret1),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 )); + return ret; + } + + PyObject *getFieldAtTopLevel(TypeOfField type, int iteration, int order, int renumPol=0) const throw(INTERP_KERNEL::Exception) + { + DataArrayInt *ret1=0; + MEDCouplingFieldDouble *ret0=self->getFieldAtTopLevel(type,iteration,order,ret1,renumPol); + PyObject *ret=PyTuple_New(2); + PyTuple_SetItem(ret,0,SWIG_NewPointerObj(SWIG_as_voidptr(ret0),SWIGTYPE_p_ParaMEDMEM__MEDCouplingFieldDouble, SWIG_POINTER_OWN | 0 )); + PyTuple_SetItem(ret,1,SWIG_NewPointerObj(SWIG_as_voidptr(ret1),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 )); + return ret; + } + + PyObject *getFieldOnMeshAtLevel(TypeOfField type, int iteration, int order, int meshDimRelToMax, const MEDFileMesh *mesh, int renumPol=0) const throw(INTERP_KERNEL::Exception) + { + DataArrayInt *ret1=0; + MEDCouplingFieldDouble *ret0=self->getFieldOnMeshAtLevel(type,iteration,order,meshDimRelToMax,mesh,ret1,renumPol); + PyObject *ret=PyTuple_New(2); + PyTuple_SetItem(ret,0,SWIG_NewPointerObj(SWIG_as_voidptr(ret0),SWIGTYPE_p_ParaMEDMEM__MEDCouplingFieldDouble, SWIG_POINTER_OWN | 0 )); + PyTuple_SetItem(ret,1,SWIG_NewPointerObj(SWIG_as_voidptr(ret1),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 )); + return ret; + } + + PyObject *getFieldOnMeshAtLevel(TypeOfField type, int iteration, int order, const MEDCouplingMesh *mesh, int renumPol=0) const throw(INTERP_KERNEL::Exception) + { + DataArrayInt *ret1=0; + MEDCouplingFieldDouble *ret0=self->getFieldOnMeshAtLevel(type,iteration,order,mesh,ret1,renumPol); + PyObject *ret=PyTuple_New(2); + PyTuple_SetItem(ret,0,SWIG_NewPointerObj(SWIG_as_voidptr(ret0),SWIGTYPE_p_ParaMEDMEM__MEDCouplingFieldDouble, SWIG_POINTER_OWN | 0 )); + PyTuple_SetItem(ret,1,SWIG_NewPointerObj(SWIG_as_voidptr(ret1),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 )); + return ret; + } + + PyObject *getFieldAtLevelOld(TypeOfField type, int iteration, int order, const std::string& mname, int meshDimRelToMax, int renumPol=0) const throw(INTERP_KERNEL::Exception) + { + DataArrayInt *ret1=0; + MEDCouplingFieldDouble *ret0=self->getFieldAtLevelOld(type,iteration,order,mname,meshDimRelToMax,ret1,renumPol); + PyObject *ret=PyTuple_New(2); + PyTuple_SetItem(ret,0,SWIG_NewPointerObj(SWIG_as_voidptr(ret0),SWIGTYPE_p_ParaMEDMEM__MEDCouplingFieldDouble, SWIG_POINTER_OWN | 0 )); + PyTuple_SetItem(ret,1,SWIG_NewPointerObj(SWIG_as_voidptr(ret1),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 )); + return ret; + } + + PyObject *getFieldWithProfile(TypeOfField type, int iteration, int order, int meshDimRelToMax, const MEDFileMesh *mesh) const throw(INTERP_KERNEL::Exception) + { + DataArrayInt *ret1=0; + DataArrayInt *ret0=self->getFieldWithProfile(type,iteration,order,meshDimRelToMax,mesh,ret1); + PyObject *ret=PyTuple_New(2); + PyTuple_SetItem(ret,0,SWIG_NewPointerObj(SWIG_as_voidptr(ret0),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 )); + PyTuple_SetItem(ret,1,SWIG_NewPointerObj(SWIG_as_voidptr(ret1),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 )); + return ret; + } + + DataArrayInt *getUndergroundDataArray(int iteration, int order) const throw(INTERP_KERNEL::Exception) + { + DataArrayInt *ret=self->getUndergroundDataArray(iteration,order); + if(ret) + ret->incrRef(); + return ret; + } + } + }; + + class MEDFileFields : public RefCountObject, public MEDFileFieldGlobsReal, public MEDFileWritable + { + public: + static MEDFileFields *New() throw(INTERP_KERNEL::Exception); + static MEDFileFields *New(const std::string& fileName, bool loadAll=true) throw(INTERP_KERNEL::Exception); + static MEDFileFields *LoadPartOf(const std::string& fileName, bool loadAll=true, const MEDFileMeshes *ms=0) throw(INTERP_KERNEL::Exception); + MEDFileFields *deepCpy() const throw(INTERP_KERNEL::Exception); + MEDFileFields *shallowCpy() const throw(INTERP_KERNEL::Exception); + void loadArrays() throw(INTERP_KERNEL::Exception); + void loadArraysIfNecessary() throw(INTERP_KERNEL::Exception); + void unloadArrays() throw(INTERP_KERNEL::Exception); + void unloadArraysWithoutDataLoss() throw(INTERP_KERNEL::Exception); + void write(const std::string& fileName, int mode) const throw(INTERP_KERNEL::Exception); + int getNumberOfFields() const; + std::vector<std::string> getFieldsNames() const throw(INTERP_KERNEL::Exception); + std::vector<std::string> getMeshesNames() const throw(INTERP_KERNEL::Exception); + // + void resize(int newSize) throw(INTERP_KERNEL::Exception); + void pushField(MEDFileAnyTypeFieldMultiTS *field) throw(INTERP_KERNEL::Exception); + void setFieldAtPos(int i, MEDFileAnyTypeFieldMultiTS *field) throw(INTERP_KERNEL::Exception); + int getPosFromFieldName(const std::string& fieldName) const throw(INTERP_KERNEL::Exception); + MEDFileAnyTypeFieldMultiTS *getFieldAtPos(int i) const throw(INTERP_KERNEL::Exception); + MEDFileAnyTypeFieldMultiTS *getFieldWithName(const std::string& fieldName) const throw(INTERP_KERNEL::Exception); + MEDFileFields *partOfThisLyingOnSpecifiedMeshName(const std::string& meshName) const throw(INTERP_KERNEL::Exception); + void destroyFieldAtPos(int i) throw(INTERP_KERNEL::Exception); + bool removeFieldsWithoutAnyTimeStep() throw(INTERP_KERNEL::Exception); + %extend + { + MEDFileFields() + { + return MEDFileFields::New(); + } + + MEDFileFields(const std::string& fileName, bool loadAll=true) throw(INTERP_KERNEL::Exception) + { + return MEDFileFields::New(fileName,loadAll); + } + + std::string __str__() const throw(INTERP_KERNEL::Exception) + { + return self->simpleRepr(); + } + + static MEDFileFields *LoadSpecificEntities(const std::string& fileName, PyObject *entities, bool loadAll=true) throw(INTERP_KERNEL::Exception) + { + std::vector<std::pair<int,int> > tmp(convertTimePairIdsFromPy(entities)); + std::size_t sz(tmp.size()); + std::vector< std::pair<TypeOfField,INTERP_KERNEL::NormalizedCellType> > entitiesCpp(sz); + for(std::size_t i=0;i<sz;i++) + { + entitiesCpp[i].first=(TypeOfField)tmp[i].first; + entitiesCpp[i].second=(INTERP_KERNEL::NormalizedCellType)tmp[i].second; + } + return MEDFileFields::LoadSpecificEntities(fileName,entitiesCpp,loadAll); + } + + PyObject *getCommonIterations() const throw(INTERP_KERNEL::Exception) + { + bool ret1; + std::vector< std::pair<int,int> > ret0=self->getCommonIterations(ret1); + PyObject *ret=PyTuple_New(2); + PyObject *ret_0=PyList_New(ret0.size()); + int rk=0; + for(std::vector< std::pair<int,int> >::const_iterator iter=ret0.begin();iter!=ret0.end();iter++,rk++) + { + PyObject *elt=PyTuple_New(2); + PyTuple_SetItem(elt,0,SWIG_From_int((*iter).first)); + PyTuple_SetItem(elt,1,SWIG_From_int((*iter).second)); + PyList_SetItem(ret_0,rk,elt); + } + PyTuple_SetItem(ret,0,ret_0); + PyObject *ret_1=ret1?Py_True:Py_False; Py_XINCREF(ret_1); + PyTuple_SetItem(ret,1,ret_1); + return ret; + } + + MEDFileFields *partOfThisLyingOnSpecifiedTimeSteps(PyObject *timeSteps) const throw(INTERP_KERNEL::Exception) + { + std::vector< std::pair<int,int> > ts=convertTimePairIdsFromPy(timeSteps); + return self->partOfThisLyingOnSpecifiedTimeSteps(ts); + } + + MEDFileFields *partOfThisNotLyingOnSpecifiedTimeSteps(PyObject *timeSteps) const throw(INTERP_KERNEL::Exception) + { + std::vector< std::pair<int,int> > ts=convertTimePairIdsFromPy(timeSteps); + return self->partOfThisNotLyingOnSpecifiedTimeSteps(ts); + } + + PyObject *__getitem__(PyObject *obj) throw(INTERP_KERNEL::Exception) + { + if(obj && PyList_Check(obj)) + { + int sz=PyList_Size(obj); + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> da=DataArrayInt::New(); da->alloc(sz,1); + int *pt=da->getPointer(); + for(int i=0;i<sz;i++,pt++) + { + PyObject *elt1=PyList_GetItem(obj,i); + *pt=MEDFileFieldsgetitemSingleTS__(self,elt1); + } + return SWIG_NewPointerObj(SWIG_as_voidptr(self->buildSubPart(da->begin(),da->end())),SWIGTYPE_p_ParaMEDMEM__MEDFileFields, SWIG_POINTER_OWN | 0 ); + } + else + return convertMEDFileFieldMultiTS(self->getFieldAtPos(MEDFileFieldsgetitemSingleTS__(self,obj)), SWIG_POINTER_OWN | 0 ); + } + + MEDFileFields *__setitem__(int obj, MEDFileFieldMultiTS *field) throw(INTERP_KERNEL::Exception) + { + self->setFieldAtPos(obj,field); + return self; + } + + int __len__() const throw(INTERP_KERNEL::Exception) + { + return self->getNumberOfFields(); + } + + MEDFileFieldsIterator *__iter__() throw(INTERP_KERNEL::Exception) + { + return self->iterator(); + } + + bool changeMeshNames(PyObject *li) throw(INTERP_KERNEL::Exception) + { + std::vector< std::pair<std::string,std::string> > modifTab=convertVecPairStStFromPy(li); + return self->changeMeshNames(modifTab); + } + + int getPosOfField(PyObject *elt0) const throw(INTERP_KERNEL::Exception) + { + if(elt0 && PyInt_Check(elt0)) + {//fmts[3] + return PyInt_AS_LONG(elt0); + } + else if(elt0 && PyString_Check(elt0)) + return self->getPosFromFieldName(PyString_AsString(elt0)); + else + throw INTERP_KERNEL::Exception("MEDFileFields::getPosOfField : invalid input params ! expected fields[int], fields[string_of_field_name] !"); + } + + std::vector<int> getPosOfFields(PyObject *elts) const throw(INTERP_KERNEL::Exception) + { + if(PyList_Check(elts)) + { + int sz=PyList_Size(elts); + std::vector<int> ret(sz); + for(int i=0;i<sz;i++) + { + PyObject *elt=PyList_GetItem(elts,i); + ret[i]=ParaMEDMEM_MEDFileFields_getPosOfField(self,elt); + } + return ret; + } + else + { + std::vector<int> ret(1); + ret[0]=ParaMEDMEM_MEDFileFields_getPosOfField(self,elts); + return ret; + } + } + + void pushFields(PyObject *fields) throw(INTERP_KERNEL::Exception) + { + std::vector<MEDFileAnyTypeFieldMultiTS *> tmp; + convertFromPyObjVectorOfObj<ParaMEDMEM::MEDFileAnyTypeFieldMultiTS *>(fields,SWIGTYPE_p_ParaMEDMEM__MEDFileAnyTypeFieldMultiTS,"MEDFileAnyTypeFieldMultiTS",tmp); + self->pushFields(tmp); + } + + void __delitem__(PyObject *elts) throw(INTERP_KERNEL::Exception) + { + if(elts && PySlice_Check(elts)) + { + Py_ssize_t strt=2,stp=2,step=2; + PySliceObject *oC=reinterpret_cast<PySliceObject *>(elts); + GetIndicesOfSlice(oC,self->getNumberOfFields(),&strt,&stp,&step,"MEDFileFields.__delitem__ : error in input slice !"); + self->destroyFieldsAtPos2(strt,stp,step); + } + else + { + std::vector<int> idsToRemove=ParaMEDMEM_MEDFileFields_getPosOfFields(self,elts); + if(!idsToRemove.empty()) + self->destroyFieldsAtPos(&idsToRemove[0],&idsToRemove[0]+idsToRemove.size()); + } + } + } + }; + + class MEDFileParameter1TS : public RefCountObject + { + public: + void setIteration(int it); + int getIteration() const; + void setOrder(int order); + int getOrder() const; + void setTimeValue(double time); + void setTime(int dt, int it, double time); + double getTime(int& dt, int& it); + double getTimeValue() const; + }; + + class MEDFileParameterDouble1TSWTI : public MEDFileParameter1TS + { + public: + void setValue(double val) throw(INTERP_KERNEL::Exception); + double getValue() const throw(INTERP_KERNEL::Exception); + std::string simpleRepr() const throw(INTERP_KERNEL::Exception); + %extend + { + std::string __str__() const throw(INTERP_KERNEL::Exception) + { + return self->simpleRepr(); + } + } + }; + + class MEDFileParameterTinyInfo : public MEDFileWritable + { + public: + void setDescription(const std::string& name); + std::string getDescription() const; + void setTimeUnit(const std::string& unit); + std::string getTimeUnit() const; + }; + + class MEDFileParameterDouble1TS : public MEDFileParameterDouble1TSWTI, public MEDFileParameterTinyInfo + { + public: + static MEDFileParameterDouble1TS *New(); + static MEDFileParameterDouble1TS *New(const std::string& fileName) throw(INTERP_KERNEL::Exception); + static MEDFileParameterDouble1TS *New(const std::string& fileName, const std::string& paramName) throw(INTERP_KERNEL::Exception); + static MEDFileParameterDouble1TS *New(const std::string& fileName, const std::string& paramName, int dt, int it) throw(INTERP_KERNEL::Exception); + virtual MEDFileParameter1TS *deepCpy() const throw(INTERP_KERNEL::Exception); + virtual std::string simpleRepr() const throw(INTERP_KERNEL::Exception); + void setName(const std::string& name) throw(INTERP_KERNEL::Exception); + std::string getName() const throw(INTERP_KERNEL::Exception); + void write(const std::string& fileName, int mode) const throw(INTERP_KERNEL::Exception); + %extend + { + MEDFileParameterDouble1TS() + { + return MEDFileParameterDouble1TS::New(); + } + + MEDFileParameterDouble1TS(const std::string& fileName) throw(INTERP_KERNEL::Exception) + { + return MEDFileParameterDouble1TS::New(fileName); + } + + MEDFileParameterDouble1TS(const std::string& fileName, const std::string& paramName) throw(INTERP_KERNEL::Exception) + { + return MEDFileParameterDouble1TS::New(fileName,paramName); + } + + MEDFileParameterDouble1TS(const std::string& fileName, const std::string& paramName, int dt, int it) throw(INTERP_KERNEL::Exception) + { + return MEDFileParameterDouble1TS::New(fileName,paramName,dt,it); + } + + std::string __str__() const throw(INTERP_KERNEL::Exception) + { + return self->simpleRepr(); + } + + PyObject *isEqual(const MEDFileParameter1TS *other, double eps) const throw(INTERP_KERNEL::Exception) + { + std::string what; + bool ret0=self->isEqual(other,eps,what); + PyObject *res=PyList_New(2); + PyObject *ret0Py=ret0?Py_True:Py_False; + Py_XINCREF(ret0Py); + PyList_SetItem(res,0,ret0Py); + PyList_SetItem(res,1,PyString_FromString(what.c_str())); + return res; + } + } + }; + + class MEDFileParameterMultiTS : public RefCountObject, public MEDFileParameterTinyInfo + { + public: + static MEDFileParameterMultiTS *New(); + static MEDFileParameterMultiTS *New(const std::string& fileName) throw(INTERP_KERNEL::Exception); + static MEDFileParameterMultiTS *New(const std::string& fileName, const std::string& paramName) throw(INTERP_KERNEL::Exception); + std::string getName() const; + void setName(const std::string& name); + MEDFileParameterMultiTS *deepCpy() const throw(INTERP_KERNEL::Exception); + void write(const std::string& fileName, int mode) const throw(INTERP_KERNEL::Exception); + std::string simpleRepr() const throw(INTERP_KERNEL::Exception); + void appendValue(int dt, int it, double time, double val) throw(INTERP_KERNEL::Exception); + double getDoubleValue(int iteration, int order) const throw(INTERP_KERNEL::Exception); + int getPosOfTimeStep(int iteration, int order) const throw(INTERP_KERNEL::Exception); + int getPosGivenTime(double time, double eps=1e-8) const throw(INTERP_KERNEL::Exception); + int getNumberOfTS() const throw(INTERP_KERNEL::Exception); + %extend + { + MEDFileParameterMultiTS() + { + return MEDFileParameterMultiTS::New(); + } + + MEDFileParameterMultiTS(const std::string& fileName) + { + return MEDFileParameterMultiTS::New(fileName); + } + + MEDFileParameterMultiTS(const std::string& fileName, const std::string& paramName) + { + return MEDFileParameterMultiTS::New(fileName,paramName); + } + + std::string __str__() const throw(INTERP_KERNEL::Exception) + { + return self->simpleRepr(); + } + + PyObject *isEqual(const MEDFileParameterMultiTS *other, double eps) const throw(INTERP_KERNEL::Exception) + { + std::string what; + bool ret0=self->isEqual(other,eps,what); + PyObject *res=PyList_New(2); + PyObject *ret0Py=ret0?Py_True:Py_False; + Py_XINCREF(ret0Py); + PyList_SetItem(res,0,ret0Py); + PyList_SetItem(res,1,PyString_FromString(what.c_str())); + return res; + } + + void eraseTimeStepIds(PyObject *ids) throw(INTERP_KERNEL::Exception) + { + int sw; + int pos1; + std::vector<int> pos2; + DataArrayInt *pos3=0; + DataArrayIntTuple *pos4=0; + convertObjToPossibleCpp1(ids,sw,pos1,pos2,pos3,pos4); + switch(sw) + { + case 1: + { + self->eraseTimeStepIds(&pos1,&pos1+1); + return; + } + case 2: + { + if(pos2.empty()) + return; + self->eraseTimeStepIds(&pos2[0],&pos2[0]+pos2.size()); + return ; + } + case 3: + { + self->eraseTimeStepIds(pos3->begin(),pos3->end()); + return ; + } + default: + throw INTERP_KERNEL::Exception("MEDFileParameterMultiTS::eraseTimeStepIds : unexpected input array type recognized !"); + } + } + + int getTimeStepId(PyObject *elt0) const throw(INTERP_KERNEL::Exception) + { + if(elt0 && PyInt_Check(elt0)) + {//fmts[3] + int pos=InterpreteNegativeInt(PyInt_AS_LONG(elt0),self->getNumberOfTS()); + return pos; + } + else if(elt0 && PyTuple_Check(elt0)) + { + if(PyTuple_Size(elt0)==2) + { + PyObject *o0=PyTuple_GetItem(elt0,0); + PyObject *o1=PyTuple_GetItem(elt0,1); + if(PyInt_Check(o0) && PyInt_Check(o1)) + {//fmts(1,-1) + int iter=PyInt_AS_LONG(o0); + int order=PyInt_AS_LONG(o1); + return self->getPosOfTimeStep(iter,order); + } + else + throw INTERP_KERNEL::Exception("MEDFileParameterMultiTS::getTimeStepId : invalid input param ! input is a tuple of size 2 but two integers are expected in this tuple to request a time steps !"); + } + else + throw INTERP_KERNEL::Exception("MEDFileParameterMultiTS::getTimeStepId : invalid input param ! input is a tuple of size != 2 ! two integers are expected in this tuple to request a time steps !"); + } + else if(elt0 && PyFloat_Check(elt0)) + { + double val=PyFloat_AS_DOUBLE(elt0); + return self->getPosGivenTime(val); + } + else + throw INTERP_KERNEL::Exception("MEDFileParameterMultiTS::getTimeStepId : invalid input params ! expected fmts[int], fmts[int,int] or fmts[double] to request time step !"); + } + + MEDFileParameter1TS *__getitem__(PyObject *elt0) const throw(INTERP_KERNEL::Exception) + { + MEDFileParameter1TS *ret=self->getTimeStepAtPos(ParaMEDMEM_MEDFileParameterMultiTS_getTimeStepId(self,elt0)); + if(ret) + ret->incrRef(); + return ret; + } + + std::vector<int> getTimeStepIds(PyObject *elts) const throw(INTERP_KERNEL::Exception) + { + if(PyList_Check(elts)) + { + int sz=PyList_Size(elts); + std::vector<int> ret(sz); + for(int i=0;i<sz;i++) + { + PyObject *elt=PyList_GetItem(elts,i); + ret[i]=ParaMEDMEM_MEDFileParameterMultiTS_getTimeStepId(self,elt); + } + return ret; + } + else + { + std::vector<int> ret(1); + ret[0]=ParaMEDMEM_MEDFileParameterMultiTS_getTimeStepId(self,elts); + return ret; + } + } + + void __delitem__(PyObject *elts) throw(INTERP_KERNEL::Exception) + { + std::vector<int> idsToRemove=ParaMEDMEM_MEDFileParameterMultiTS_getTimeStepIds(self,elts); + if(!idsToRemove.empty()) + self->eraseTimeStepIds(&idsToRemove[0],&idsToRemove[0]+idsToRemove.size()); + } + + MEDFileParameter1TS *getTimeStepAtPos(int posId) const throw(INTERP_KERNEL::Exception) + { + MEDFileParameter1TS *ret=self->getTimeStepAtPos(posId); + if(ret) + ret->incrRef(); + return ret; + } + + PyObject *getIterations() const throw(INTERP_KERNEL::Exception) + { + std::vector< std::pair<int,int> > res=self->getIterations(); + PyObject *ret=PyList_New(res.size()); + int rk=0; + for(std::vector< std::pair<int,int> >::const_iterator iter=res.begin();iter!=res.end();iter++,rk++) + { + PyObject *elt=PyTuple_New(2); + PyTuple_SetItem(elt,0,SWIG_From_int((*iter).first)); + PyTuple_SetItem(elt,1,SWIG_From_int((*iter).second)); + PyList_SetItem(ret,rk,elt); + } + return ret; + } + + PyObject *getTimeSteps() const throw(INTERP_KERNEL::Exception) + { + std::vector<double> res2; + std::vector< std::pair<int,int> > res=self->getTimeSteps(res2); + PyObject *ret=PyList_New(res.size()); + int rk=0; + for(std::vector< std::pair<int,int> >::const_iterator iter=res.begin();iter!=res.end();iter++,rk++) + { + PyObject *elt=PyTuple_New(3); + PyTuple_SetItem(elt,0,SWIG_From_int((*iter).first)); + PyTuple_SetItem(elt,1,SWIG_From_int((*iter).second)); + PyTuple_SetItem(elt,2,SWIG_From_double(res2[rk])); + PyList_SetItem(ret,rk,elt); + } + return ret; + } + } + }; + + class MEDFileParameters : public RefCountObject, public MEDFileWritable + { + public: + static MEDFileParameters *New(); + static MEDFileParameters *New(const std::string& fileName) throw(INTERP_KERNEL::Exception); + MEDFileParameters *deepCpy() const throw(INTERP_KERNEL::Exception); + void write(const std::string& fileName, int mode) const throw(INTERP_KERNEL::Exception); + std::vector<std::string> getParamsNames() const throw(INTERP_KERNEL::Exception); + std::string simpleRepr() const throw(INTERP_KERNEL::Exception); + void resize(int newSize) throw(INTERP_KERNEL::Exception); + void pushParam(MEDFileParameterMultiTS *param) throw(INTERP_KERNEL::Exception); + void setParamAtPos(int i, MEDFileParameterMultiTS *param) throw(INTERP_KERNEL::Exception); + void destroyParamAtPos(int i) throw(INTERP_KERNEL::Exception); + int getPosFromParamName(const std::string& paramName) const throw(INTERP_KERNEL::Exception); + int getNumberOfParams() const throw(INTERP_KERNEL::Exception); + %extend + { + MEDFileParameters() + { + return MEDFileParameters::New(); + } + + MEDFileParameters(const std::string& fileName) + { + return MEDFileParameters::New(fileName); + } + + std::string __str__() const throw(INTERP_KERNEL::Exception) + { + return self->simpleRepr(); + } + + MEDFileParameterMultiTS *__getitem__(PyObject *obj) throw(INTERP_KERNEL::Exception) + { + if(PyInt_Check(obj)) + { + MEDFileParameterMultiTS *ret=self->getParamAtPos(InterpreteNegativeInt((int)PyInt_AS_LONG(obj),self->getNumberOfParams())); + if(ret) + ret->incrRef(); + return ret; + } + else if(PyString_Check(obj)) + { + MEDFileParameterMultiTS *ret=self->getParamWithName(PyString_AsString(obj)); + if(ret) + ret->incrRef(); + return ret; + } + else + throw INTERP_KERNEL::Exception("MEDFileParameters::__getitem__ : only integer or string with meshname supported !"); + } + + int __len__() const throw(INTERP_KERNEL::Exception) + { + return self->getNumberOfParams(); + } + + MEDFileParameterMultiTS *getParamAtPos(int i) const throw(INTERP_KERNEL::Exception) + { + MEDFileParameterMultiTS *ret=self->getParamAtPos(i); + if(ret) + ret->incrRef(); + return ret; + } + + MEDFileParameterMultiTS *getParamWithName(const std::string& paramName) const throw(INTERP_KERNEL::Exception) + { + MEDFileParameterMultiTS *ret=self->getParamWithName(paramName); + if(ret) + ret->incrRef(); + return ret; + } + + PyObject *isEqual(const MEDFileParameters *other, double eps) const throw(INTERP_KERNEL::Exception) + { + std::string what; + bool ret0=self->isEqual(other,eps,what); + PyObject *res=PyList_New(2); + PyObject *ret0Py=ret0?Py_True:Py_False; + Py_XINCREF(ret0Py); + PyList_SetItem(res,0,ret0Py); + PyList_SetItem(res,1,PyString_FromString(what.c_str())); + return res; + } + } + }; + + class MEDFileData : public RefCountObject, public MEDFileWritable + { + public: + static MEDFileData *New(const std::string& fileName) throw(INTERP_KERNEL::Exception); + static MEDFileData *New(); + MEDFileData *deepCpy() const throw(INTERP_KERNEL::Exception); + void setFields(MEDFileFields *fields) throw(INTERP_KERNEL::Exception); + void setMeshes(MEDFileMeshes *meshes) throw(INTERP_KERNEL::Exception); + void setParams(MEDFileParameters *params) throw(INTERP_KERNEL::Exception); + int getNumberOfFields() const throw(INTERP_KERNEL::Exception); + int getNumberOfMeshes() const throw(INTERP_KERNEL::Exception); + int getNumberOfParams() const throw(INTERP_KERNEL::Exception); + // + bool changeMeshName(const std::string& oldMeshName, const std::string& newMeshName) throw(INTERP_KERNEL::Exception); + bool unPolyzeMeshes() throw(INTERP_KERNEL::Exception); + // + void write(const std::string& fileName, int mode) const throw(INTERP_KERNEL::Exception); + %extend + { + MEDFileData(const std::string& fileName) throw(INTERP_KERNEL::Exception) + { + return MEDFileData::New(fileName); + } + + MEDFileData() + { + return MEDFileData::New(); + } + + std::string __str__() const throw(INTERP_KERNEL::Exception) + { + return self->simpleRepr(); + } + + MEDFileMeshes *getMeshes() const throw(INTERP_KERNEL::Exception) + { + MEDFileMeshes *ret=self->getMeshes(); + if(ret) + ret->incrRef(); + return ret; + } + + MEDFileParameters *getParams() const throw(INTERP_KERNEL::Exception) + { + MEDFileParameters *ret=self->getParams(); + if(ret) + ret->incrRef(); + return ret; + } + + MEDFileFields *getFields() const throw(INTERP_KERNEL::Exception) + { + MEDFileFields *ret=self->getFields(); + if(ret) + ret->incrRef(); + return ret; + } + + bool changeMeshNames(PyObject *li) throw(INTERP_KERNEL::Exception) + { + std::vector< std::pair<std::string,std::string> > modifTab=convertVecPairStStFromPy(li); + return self->changeMeshNames(modifTab); + } + } + }; + + class SauvReader : public RefCountObject + { + public: + static SauvReader* New(const std::string& fileName) throw(INTERP_KERNEL::Exception); + MEDFileData * loadInMEDFileDS() throw(INTERP_KERNEL::Exception); + %extend + { + SauvReader(const std::string& fileName) throw(INTERP_KERNEL::Exception) + { + return SauvReader::New(fileName); + } + } + }; + + class SauvWriter : public RefCountObject + { + public: + static SauvWriter * New(); + void setMEDFileDS(const MEDFileData* medData, unsigned meshIndex = 0) throw(INTERP_KERNEL::Exception); + void write(const std::string& fileName) throw(INTERP_KERNEL::Exception); + void setCpyGrpIfOnASingleFamilyStatus(bool status) throw(INTERP_KERNEL::Exception); + bool getCpyGrpIfOnASingleFamilyStatus() const throw(INTERP_KERNEL::Exception); + %extend + { + SauvWriter() throw(INTERP_KERNEL::Exception) + { + return SauvWriter::New(); + } + } + }; + + /////////////// + + class MEDFileMeshStruct; + + class MEDFileField1TSStructItem + { + public: + static MEDFileField1TSStructItem BuildItemFrom(const MEDFileAnyTypeField1TS *ref, const MEDFileMeshStruct *meshSt) throw(INTERP_KERNEL::Exception); + }; + + class MEDFileMeshStruct : public RefCountObject + { + public: + static MEDFileMeshStruct *New(const MEDFileMesh *mesh) throw(INTERP_KERNEL::Exception); + protected: + ~MEDFileMeshStruct(); + }; + + class MEDMeshMultiLev : public RefCountObject + { + public: + virtual MEDMeshMultiLev *prepare() const throw(INTERP_KERNEL::Exception); + DataArray *buildDataArray(const MEDFileField1TSStructItem& fst, const MEDFileFieldGlobsReal *globs, const DataArray *vals) const throw(INTERP_KERNEL::Exception); + protected: + ~MEDMeshMultiLev(); + public: + %extend + { + PyObject *retrieveFamilyIdsOnCells() const throw(INTERP_KERNEL::Exception) + { + DataArrayInt *famIds(0); + bool isWithoutCopy(false); + self->retrieveFamilyIdsOnCells(famIds,isWithoutCopy); + PyObject *ret=PyTuple_New(2); + PyObject *ret1Py=isWithoutCopy?Py_True:Py_False; + Py_XINCREF(ret1Py); + PyTuple_SetItem(ret,0,SWIG_NewPointerObj(SWIG_as_voidptr(famIds),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 )); + PyTuple_SetItem(ret,1,ret1Py); + return ret; + } + + PyObject *retrieveNumberIdsOnCells() const throw(INTERP_KERNEL::Exception) + { + DataArrayInt *numIds(0); + bool isWithoutCopy(false); + self->retrieveNumberIdsOnCells(numIds,isWithoutCopy); + PyObject *ret=PyTuple_New(2); + PyObject *ret1Py=isWithoutCopy?Py_True:Py_False; + Py_XINCREF(ret1Py); + PyTuple_SetItem(ret,0,SWIG_NewPointerObj(SWIG_as_voidptr(numIds),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 )); + PyTuple_SetItem(ret,1,ret1Py); + return ret; + } + + PyObject *retrieveFamilyIdsOnNodes() const throw(INTERP_KERNEL::Exception) + { + DataArrayInt *famIds(0); + bool isWithoutCopy(false); + self->retrieveFamilyIdsOnNodes(famIds,isWithoutCopy); + PyObject *ret=PyTuple_New(2); + PyObject *ret1Py=isWithoutCopy?Py_True:Py_False; + Py_XINCREF(ret1Py); + PyTuple_SetItem(ret,0,SWIG_NewPointerObj(SWIG_as_voidptr(famIds),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 )); + PyTuple_SetItem(ret,1,ret1Py); + return ret; + } + + PyObject *retrieveNumberIdsOnNodes() const throw(INTERP_KERNEL::Exception) + { + DataArrayInt *numIds(0); + bool isWithoutCopy(false); + self->retrieveNumberIdsOnNodes(numIds,isWithoutCopy); + PyObject *ret=PyTuple_New(2); + PyObject *ret1Py=isWithoutCopy?Py_True:Py_False; + Py_XINCREF(ret1Py); + PyTuple_SetItem(ret,0,SWIG_NewPointerObj(SWIG_as_voidptr(numIds),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 )); + PyTuple_SetItem(ret,1,ret1Py); + return ret; + } + + PyObject *getGeoTypes() const throw(INTERP_KERNEL::Exception) + { + std::vector< INTERP_KERNEL::NormalizedCellType > result(self->getGeoTypes()); + std::vector< INTERP_KERNEL::NormalizedCellType >::const_iterator iL(result.begin()); + PyObject *res(PyList_New(result.size())); + for(int i=0;iL!=result.end(); i++, iL++) + PyList_SetItem(res,i,PyInt_FromLong(*iL)); + return res; + } + } + }; + + class MEDUMeshMultiLev : public MEDMeshMultiLev + { + protected: + ~MEDUMeshMultiLev(); + public: + %extend + { + PyObject *buildVTUArrays() const throw(INTERP_KERNEL::Exception) + { + DataArrayDouble *coords(0); DataArrayByte *types(0); DataArrayInt *cellLocations(0),*cells(0),*faceLocations(0),*faces(0); + bool ncc(self->buildVTUArrays(coords,types,cellLocations,cells,faceLocations,faces)); + PyObject *ret0Py=ncc?Py_True:Py_False; + Py_XINCREF(ret0Py); + PyObject *ret=PyTuple_New(7); + PyTuple_SetItem(ret,0,ret0Py); + PyTuple_SetItem(ret,1,SWIG_NewPointerObj(SWIG_as_voidptr(coords),SWIGTYPE_p_ParaMEDMEM__DataArrayDouble, SWIG_POINTER_OWN | 0 )); + PyTuple_SetItem(ret,2,SWIG_NewPointerObj(SWIG_as_voidptr(types),SWIGTYPE_p_ParaMEDMEM__DataArrayByte, SWIG_POINTER_OWN | 0 )); + PyTuple_SetItem(ret,3,SWIG_NewPointerObj(SWIG_as_voidptr(cellLocations),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 )); + PyTuple_SetItem(ret,4,SWIG_NewPointerObj(SWIG_as_voidptr(cells),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 )); + PyTuple_SetItem(ret,5,SWIG_NewPointerObj(SWIG_as_voidptr(faceLocations),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 )); + PyTuple_SetItem(ret,6,SWIG_NewPointerObj(SWIG_as_voidptr(faces),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 )); + return ret; + } + } + }; + + class MEDStructuredMeshMultiLev : public MEDMeshMultiLev + { + protected: + ~MEDStructuredMeshMultiLev(); + }; + + class MEDCMeshMultiLev : public MEDStructuredMeshMultiLev + { + protected: + ~MEDCMeshMultiLev(); + public: + %extend + { + PyObject *buildVTUArrays() const throw(INTERP_KERNEL::Exception) + { + bool isInternal; + std::vector< DataArrayDouble * > objs(self->buildVTUArrays(isInternal)); + std::size_t sz(objs.size()); + PyObject *ret(PyTuple_New(2)); + PyObject *ret0=PyList_New(sz); + for(std::size_t i=0;i<sz;i++) + PyList_SetItem(ret0,i,SWIG_NewPointerObj(SWIG_as_voidptr(objs[i]),SWIGTYPE_p_ParaMEDMEM__DataArrayDouble, SWIG_POINTER_OWN | 0 )); + PyTuple_SetItem(ret,0,ret0); + PyObject *ret1Py(isInternal?Py_True:Py_False); + Py_XINCREF(ret1Py); + PyTuple_SetItem(ret,1,ret1Py); + return ret; + } + } + }; + + class MEDCurveLinearMeshMultiLev : public MEDStructuredMeshMultiLev + { + protected: + ~MEDCurveLinearMeshMultiLev(); + public: + %extend + { + PyObject *buildVTUArrays() const throw(INTERP_KERNEL::Exception) + { + DataArrayDouble *ret0(0); + std::vector<int> ret1; + bool ret2; + self->buildVTUArrays(ret0,ret1,ret2); + std::size_t sz(ret1.size()); + PyObject *ret=PyTuple_New(3); + PyTuple_SetItem(ret,0,SWIG_NewPointerObj(SWIG_as_voidptr(ret0),SWIGTYPE_p_ParaMEDMEM__DataArrayDouble, SWIG_POINTER_OWN | 0 )); + PyObject *ret1Py=PyList_New(sz); + for(std::size_t i=0;i<sz;i++) + PyList_SetItem(ret1Py,i,SWIG_From_int(ret1[i])); + PyTuple_SetItem(ret,1,ret1Py); + PyObject *ret2Py(ret2?Py_True:Py_False); + Py_XINCREF(ret2Py); + PyTuple_SetItem(ret,2,ret2Py); + return ret; + } + } + }; + + class MEDFileFastCellSupportComparator : public RefCountObject + { + public: + static MEDFileFastCellSupportComparator *New(const MEDFileMeshStruct *m, const MEDFileAnyTypeFieldMultiTS *ref) throw(INTERP_KERNEL::Exception); + MEDMeshMultiLev *buildFromScratchDataSetSupport(int timeStepId, const MEDFileFieldGlobsReal *globs) const throw(INTERP_KERNEL::Exception); + bool isDataSetSupportEqualToThePreviousOne(int timeStepId, const MEDFileFieldGlobsReal *globs) const throw(INTERP_KERNEL::Exception); + int getNumberOfTS() const throw(INTERP_KERNEL::Exception); + protected: + ~MEDFileFastCellSupportComparator(); + public: + %extend + { + PyObject *getGeoTypesAt(int timeStepId, const MEDFileMesh *m) const throw(INTERP_KERNEL::Exception) + { + std::vector< INTERP_KERNEL::NormalizedCellType > result(self->getGeoTypesAt(timeStepId,m)); + std::vector< INTERP_KERNEL::NormalizedCellType >::const_iterator iL(result.begin()); + PyObject *res(PyList_New(result.size())); + for(int i=0;iL!=result.end(); i++, iL++) + PyList_SetItem(res,i,PyInt_FromLong(*iL)); + return res; + } + } + }; +} diff --git a/src/medtool/src/MEDLoader/Swig/MEDLoaderCouplingTrainingSession.py b/src/medtool/src/MEDLoader/Swig/MEDLoaderCouplingTrainingSession.py new file mode 100644 index 000000000..8001e2798 --- /dev/null +++ b/src/medtool/src/MEDLoader/Swig/MEDLoaderCouplingTrainingSession.py @@ -0,0 +1,592 @@ +# -*- coding: iso-8859-1 -*- +# Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 +# 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/DM2S/STMF/LGLS) + +from MEDLoader import * +from MEDCouplingRemapper import * +import math, os + +d=DataArrayDouble.New(6,2) +d[:,0]=3. +d[:,1]=range(6) +d[:,1]*=math.pi/3. +d=d.fromPolarToCart() +d.setInfoOnComponents(["X [m]","Y [m]"]) +print d.getValues() +print d +print d.magnitude().isUniform(3.,1e-12) +# +radius=3. +translationToPerform=[[0.,0.],[3./2.*radius,-radius*math.sqrt(3.)/2],[3./2.*radius,radius*math.sqrt(3.)/2],[0.,radius*math.sqrt(3.)],[-3./2.*radius,radius*math.sqrt(3.)/2],[-3./2.*radius,-radius*math.sqrt(3.)/2],[0.,-radius*math.sqrt(3.)]] +ds=len(translationToPerform)*[None] +for pos,t in enumerate(translationToPerform): + ds[pos]=d[:] + ds[pos]+=t + pass +# +d2=DataArrayDouble.Aggregate(ds) +oldNbOfTuples=d2.getNumberOfTuples() +c,cI=d2.findCommonTuples(1e-12) +tmp=c[cI[0]:cI[0+1]] +print tmp +a=cI.deltaShiftIndex() +b=a-1 +myNewNbOfTuples=oldNbOfTuples-sum(b.getValues()) +o2n,newNbOfTuples=DataArrayInt.BuildOld2NewArrayFromSurjectiveFormat2(oldNbOfTuples,c,cI) +print "Ai je trouve le bon resultat ? %s"%(str(myNewNbOfTuples==newNbOfTuples)) ; assert myNewNbOfTuples==newNbOfTuples +# +d3=d2.renumberAndReduce(o2n,newNbOfTuples) +n2o=o2n.invertArrayO2N2N2O(newNbOfTuples) +d3_bis=d2[n2o] +print "Ai je trouve le bon resultat (2) ? %s"%(str(d3.isEqual(d3_bis,1e-12))) ; assert d3.isEqual(d3_bis,1e-12) +# +d3+=[3.3,4.4] +# d3 contains coordinates +m=MEDCouplingUMesh.New("My7hexagons",2) +m.setCoords(d3) +m.allocateCells(7) +for i in xrange(7): + m.insertNextCell(NORM_POLYGON,o2n[6*i:6*(i+1)].getValues()) + pass +m.finishInsertingCells() +m.checkCoherency() +# +m.writeVTK("My7hexagons.vtu") + +######## + +coords=[0.,0.,0., 1.,1.,0., 1.,1.25,0., 1.,0.,0., 1.,1.5,0., 2.,0.,0., 2.,1.,0., 1.,2.,0., 0.,2.,0., 3.,1.,0., + 3.,2.,0., 0.,1.,0., 1.,3.,0., 2.,2.,0., 2.,3.,0., + 0.,0.,1., 1.,1.,1., 1.,1.25,1., 1.,0.,1., 1.,1.5,1., 2.,0.,1., 2.,1.,1., 1.,2.,1., 0.,2.,1., 3.,1.,1., + 3.,2.,1., 0.,1.,1., 1.,3.,1., 2.,2.,1., 2.,3.,1., + 0.,0.,2., 1.,1.,2., 1.,1.25,2., 1.,0.,2., 1.,1.5,2., 2.,0.,2., 2.,1.,2., 1.,2.,2., 0.,2.,2., 3.,1.,2., + 3.,2.,2., 0.,1.,2., 1.,3.,2., 2.,2.,2., 2.,3.,2., + 0.,0.,3., 1.,1.,3., 1.,1.25,3., 1.,0.,3., 1.,1.5,3., 2.,0.,3., 2.,1.,3., 1.,2.,3., 0.,2.,3., 3.,1.,3., + 3.,2.,3., 0.,1.,3., 1.,3.,3., 2.,2.,3., 2.,3.,3.] +conn=[0,11,1,3,15,26,16,18, 1,2,4,7,13,6,-1,1,16,21,6,-1,6,21,28,13,-1,13,7,22,28,-1,7,4,19,22,-1,4,2,17,19,-1,2,1,16,17,-1,16,21,28,22,19,17, + 1,6,5,3,16,21,20,18, 13,10,9,6,28,25,24,21, 11,8,7,4,2,1,-1,11,26,16,1,-1,1,16,17,2,-1,2,17,19,4,-1,4,19,22,7,-1,7,8,23,22,-1,8,11,26,23,-1,26,16,17,19,22,23, + 7,12,14,13,22,27,29,28, 15,26,16,18,30,41,31,33, 16,17,19,22,28,21,-1,16,31,36,21,-1,21,36,43,28,-1,28,22,37,43,-1,22,19,34,37,-1,19,17,32,34,-1,17,16,31,32,-1,31,36,43,37,34,32, + 16,21,20,18,31,36,35,33, 28,25,24,21,43,40,39,36, 26,23,22,19,17,16,-1,26,41,31,16,-1,16,31,32,17,-1,17,32,34,19,-1,19,34,37,22,-1,22,23,38,37,-1,23,26,41,38,-1,41,31,32,34,37,38, + 22,27,29,28,37,42,44,43, 30,41,31,33,45,56,46,48, 31,32,34,37,43,36,-1,31,46,51,36,-1,36,51,58,43,-1,43,37,52,58,-1,37,34,49,52,-1,34,32,47,49,-1,32,31,46,47,-1,46,51,58,52,49,47, + 31,36,35,33,46,51,50,48, 43,40,39,36,58,55,54,51, 41,38,37,34,32,31,-1,41,56,46,31,-1,31,46,47,32,-1,32,47,49,34,-1,34,49,52,37,-1,37,38,53,52,-1,38,41,56,53,-1,56,46,47,49,52,53, + 37,42,44,43,52,57,59,58] +mesh3D=MEDCouplingUMesh.New("mesh3D",3); +mesh3D.allocateCells(18); +mesh3D.insertNextCell(NORM_HEXA8,conn[0:8]); mesh3D.insertNextCell(NORM_POLYHED,conn[8:51]); mesh3D.insertNextCell(NORM_HEXA8,conn[51:59]); mesh3D.insertNextCell(NORM_HEXA8,conn[59:67]); mesh3D.insertNextCell(NORM_POLYHED,conn[67:110]); mesh3D.insertNextCell(NORM_HEXA8,conn[110:118]); +mesh3D.insertNextCell(NORM_HEXA8,conn[118:126]); mesh3D.insertNextCell(NORM_POLYHED,conn[126:169]); mesh3D.insertNextCell(NORM_HEXA8,conn[169:177]); mesh3D.insertNextCell(NORM_HEXA8,conn[177:185]); mesh3D.insertNextCell(NORM_POLYHED,conn[185:228]); mesh3D.insertNextCell(NORM_HEXA8,conn[228:236]); +mesh3D.insertNextCell(NORM_HEXA8,conn[236:244]); mesh3D.insertNextCell(NORM_POLYHED,conn[244:287]); mesh3D.insertNextCell(NORM_HEXA8,conn[287:295]); mesh3D.insertNextCell(NORM_HEXA8,conn[295:303]); mesh3D.insertNextCell(NORM_POLYHED,conn[303:346]); mesh3D.insertNextCell(NORM_HEXA8,conn[346:354]); +mesh3D.finishInsertingCells(); +myCoords=DataArrayDouble.New(coords,60,3); +myCoords.setInfoOnComponents(["X [m]","Y [m]","Z [m]"]) +mesh3D.setCoords(myCoords); +mesh3D.orientCorrectlyPolyhedrons() +mesh3D.sortCellsInMEDFileFrmt() +mesh3D.checkCoherency() +renum=DataArrayInt.New(60) ; renum[:15]=range(15,30) ; renum[15:30]=range(15) ; renum[30:45]=range(45,60) ; renum[45:]=range(30,45) +mesh3D.renumberNodes(renum,60) +# +mesh3D.getCoords()[:]*=100. +mesh3D.getCoords().setInfoOnComponents(["X [cm]","Y [cm]","Z [cm]"]) +# +zLev=mesh3D.getCoords()[:,2] +zLev=zLev.getDifferentValues(1e-12) +zLev.sort() +# +tmp,cellIdsSol1=mesh3D.buildSlice3D([0.,0.,(zLev[1]+zLev[2])/2],[0.,0.,1.],1e-12) +bary=mesh3D.getBarycenterAndOwner() +baryZ=bary[:,2] +cellIdsSol2=baryZ.getIdsInRange(zLev[1],zLev[2]) +nodeIds=mesh3D.findNodesOnPlane([0.,0.,zLev[0]],[0.,0.,1.],1e-10) +mesh2D=mesh3D.buildFacePartOfMySelfNode(nodeIds,True) +extMesh=MEDCouplingExtrudedMesh.New(mesh3D,mesh2D,0) +cellIdsSol3=extMesh.getMesh3DIds()[mesh2D.getNumberOfCells():2*mesh2D.getNumberOfCells()] +for i in xrange(3): + exec("print cellIdsSol%s.getValues()"%(i+1)) +# +mesh3DPart=mesh3D[cellIdsSol2] # equivalent to mesh3DPart=mesh3D.buildPartOfMySelf(cellIdsSol2,True) +mesh3DPart.zipCoords() +print mesh3DPart.checkConsecutiveCellTypesAndOrder([NORM_HEXA8,NORM_POLYHED]) ; assert mesh3DPart.checkConsecutiveCellTypesAndOrder([NORM_HEXA8,NORM_POLYHED]) +print mesh3DPart.checkConsecutiveCellTypes() ; assert mesh3DPart.checkConsecutiveCellTypes() +#print mesh3DPart.advancedRepr() +# +baryXY=bary[:,[0,1]] +baryXY-=[250.,150.] +magn=baryXY.magnitude() +cellIds2Sol1=magn.getIdsInRange(0.,1e-12) +# +bary2=mesh2D.getBarycenterAndOwner()[:,[0,1]] +bary2-=[250.,150.] +magn=bary2.magnitude() +ids=magn.getIdsInRange(0.,1e-12) +idStart=int(ids) # ids is assumed to contain only one value, if not an exception is thrown +cellIds2Sol2=extMesh.getMesh3DIds()[range(idStart,mesh3D.getNumberOfCells(),mesh2D.getNumberOfCells())] +# +mesh3DSlice2=mesh3D[cellIds2Sol1] +mesh3DSlice2.zipCoords() +# +mesh3DSlice2bis=mesh3DSlice2.deepCpy() +mesh3DSlice2bis.translate([0.,1000.,0.]) +mesh3DSlice2All=MEDCouplingUMesh.MergeUMeshes([mesh3DSlice2,mesh3DSlice2bis]) +mesh3DSlice2All.writeVTK("mesh3DSlice2All.vtu") +# +mesh3DSurf,desc,descIndx,revDesc,revDescIndx=mesh3D.buildDescendingConnectivity() +numberOf3DCellSharing=revDescIndx.deltaShiftIndex() +cellIds=numberOf3DCellSharing.getIdsNotEqual(1) +mesh3DSurfInside=mesh3DSurf[cellIds] +mesh3DSurfInside.writeVTK("mesh3DSurfInside.vtu") + +###### + +xarr=DataArrayDouble.New(11,1) +xarr.iota(0.) +cmesh=MEDCouplingCMesh.New() +cmesh.setCoords(xarr,xarr,xarr) +mesh=cmesh.buildUnstructured() +mesh.convertToPolyTypes(DataArrayInt.Range(0,mesh.getNumberOfCells(),2)) +# + +f=mesh.fillFromAnalytic(ON_CELLS,1,"(x-5.)*(x-5.)+(y-5.)*(y-5.)+(z-5.)*(z-5.)") +f.setName("MyField") +# +f2=MEDCouplingFieldDouble.New(ON_CELLS,ONE_TIME) +f2.setMesh(mesh) +f2.setName("MyField2") +f2.fillFromAnalytic(1,"(x-5.)*(x-5.)+(y-5.)*(y-5.)+(z-5.)*(z-5.)") +print "f and f2 are equal : %s"%(f.isEqualWithoutConsideringStr(f2,1e-13,1e-12)) ; assert f.isEqualWithoutConsideringStr(f2,1e-13,1e-12) +# +ids1=f.getArray().getIdsInRange(0.,5.) +fPart1=f.buildSubPart(ids1) +ids2=f.getArray().getIdsInRange(50.,1.e300) +fPart2=f.buildSubPart(ids2) +#Renumbering cells to follow MED file +fPart1Cpy=fPart1.deepCpy() +o2n=fPart1Cpy.getMesh().sortCellsInMEDFileFrmt() +fPart1Cpy.getArray().renumberInPlace(o2n) +#Check that fPart1Cpy and fPart1 are the same +fPart1Cpy.substractInPlaceDM(fPart1,12,1e-12) +fPart1Cpy.getArray().abs() +print "Fields are the same ? %s"%(fPart1Cpy.getArray().accumulate()[0]<1e-12) ; assert fPart1Cpy.getArray().accumulate()[0]<1e-12 +# +fPart12=MEDCouplingFieldDouble.MergeFields([fPart1,fPart2]) +# evaluation on points +bary=fPart12.getMesh().getBarycenterAndOwner() +arr1=fPart12.getValueOnMulti(bary) +arr2=f.getValueOnMulti(bary) +delta=arr1-arr2 +delta.abs() +print "Check OK : %s"%(delta.accumulate()[0]<1e-12) ; assert delta.accumulate()[0]<1e-12 +# +print abs(fPart12.integral(0,True)-fPart12.getArray().accumulate()[0])<1e-10 ; assert abs(fPart12.integral(0,True)-fPart12.getArray().accumulate()[0])<1e-10 +fPart12.getMesh().scale([0.,0.,0.],1.2) +print abs(fPart12.integral(0,True)-fPart12.getArray().accumulate()[0]*1.2*1.2*1.2)<1e-8 ; assert abs(fPart12.integral(0,True)-fPart12.getArray().accumulate()[0]*1.2*1.2*1.2)<1e-8 +# Explosion of field +fVec=mesh.fillFromAnalytic(ON_CELLS,3,"(x-5.)*IVec+(y-5.)*JVec+(z-5.)*KVec") +fVecPart1=fVec.buildSubPart(ids1) +fVecPart1.setName("fVecPart1") +cells=fPart1.getMesh().getNumberOfCells()*[None] +for icell,vec in enumerate(fVecPart1.getArray()): + m=fPart1.getMesh()[[icell]] + m.zipCoords() + m.translate(vec) + cells[icell]=m + pass +meshFVecPart1Exploded=MEDCouplingUMesh.MergeUMeshes(cells) +fPart1.setMesh(meshFVecPart1Exploded) + +#### + +targetCoords=[-0.3,-0.3, 0.2,-0.3, 0.7,-0.3, -0.3,0.2, 0.2,0.2, 0.7,0.2, -0.3,0.7, 0.2,0.7, 0.7,0.7 ]; +targetConn=[0,3,4,1, 1,4,2, 4,5,2, 6,7,4,3, 7,8,5,4]; +targetMesh=MEDCouplingUMesh.New("MyMesh",2); +targetMesh.allocateCells(5); +targetMesh.insertNextCell(NORM_TRI3,3,targetConn[4:7]); +targetMesh.insertNextCell(NORM_TRI3,3,targetConn[7:10]); +targetMesh.insertNextCell(NORM_QUAD4,4,targetConn[0:4]); +targetMesh.insertNextCell(NORM_QUAD4,4,targetConn[10:14]); +targetMesh.insertNextCell(NORM_QUAD4,4,targetConn[14:18]); +targetMesh.finishInsertingCells(); +myCoords=DataArrayDouble.New(targetCoords,9,2); +myCoords.setInfoOnComponents(["X [km]","YY [mm]"]) +targetMesh.setCoords(myCoords); +# +MEDLoader.WriteUMesh("TargetMesh.med",targetMesh,True) +# +meshRead=MEDLoader.ReadUMeshFromFile("TargetMesh.med",targetMesh.getName(),0) +print "Is the mesh read in file equals targetMesh ? %s"%(meshRead.isEqual(targetMesh,1e-12)) ; assert meshRead.isEqual(targetMesh,1e-12) +# +f=MEDCouplingFieldDouble.New(ON_CELLS,ONE_TIME) +f.setTime(5.6,7,8) +f.setArray(targetMesh.getBarycenterAndOwner()) +f.setMesh(targetMesh) +f.setName("AFieldName") +MEDLoader.WriteField("MyFirstField.med",f,True) +# +f2=MEDLoader.ReadFieldCell("MyFirstField.med",f.getMesh().getName(),0,f.getName(),7,8) +print "Is the field read in file equals f ? %s"%(f2.isEqual(f,1e-12,1e-12)) ; assert f2.isEqual(f,1e-12,1e-12) +# +MEDLoader.WriteUMesh("MySecondField.med",f.getMesh(),True) +MEDLoader.WriteFieldUsingAlreadyWrittenMesh("MySecondField.med",f) +# +f2=f.clone(True) +f2.getArray()[:]*=2.0 +f2.setTime(7.8,9,10) +MEDLoader.WriteFieldUsingAlreadyWrittenMesh("MySecondField.med",f2) +# +f3=MEDLoader.ReadFieldCell("MySecondField.med",f.getMesh().getName(),0,f.getName(),7,8) +print "Is the field read in file equals f ? %s"%(f.isEqual(f3,1e-12,1e-12)) ; assert f.isEqual(f3,1e-12,1e-12) +f4=MEDLoader.ReadFieldCell("MySecondField.med",f.getMesh().getName(),0,f.getName(),9,10) +print "Is the field read in file equals f ? %s"%(f2.isEqual(f4,1e-12,1e-12)) ; assert f2.isEqual(f4,1e-12,1e-12) + +##### + +targetCoords=[-0.3,-0.3, 0.2,-0.3, 0.7,-0.3, -0.3,0.2, 0.2,0.2, 0.7,0.2, -0.3,0.7, 0.2,0.7, 0.7,0.7 ]; +targetConn=[0,3,4,1, 1,4,2, 4,5,2, 6,7,4,3, 7,8,5,4]; +targetMesh=MEDCouplingUMesh.New("MyMesh",2); +targetMesh.allocateCells(5); +targetMesh.insertNextCell(NORM_TRI3,3,targetConn[4:7]); +targetMesh.insertNextCell(NORM_TRI3,3,targetConn[7:10]); +targetMesh.insertNextCell(NORM_QUAD4,4,targetConn[0:4]); +targetMesh.insertNextCell(NORM_QUAD4,4,targetConn[10:14]); +targetMesh.insertNextCell(NORM_QUAD4,4,targetConn[14:18]); +targetMesh.finishInsertingCells(); +myCoords=DataArrayDouble.New(targetCoords,9,2); +myCoords.setInfoOnComponents(["X [km]","YY [mm]"]) +targetMesh.setCoords(myCoords); +# +targetMeshConsti=targetMesh.buildDescendingConnectivity()[0] +targetMesh1=targetMeshConsti[[3,4,7,8]] +targetMesh1.setName(targetMesh.getName()) +# +meshMEDFile=MEDFileUMesh.New() +meshMEDFile.setMeshAtLevel(0,targetMesh) +meshMEDFile.setMeshAtLevel(-1,targetMesh1) +# Some groups on cells Level 0 +grp0_0=DataArrayInt.New([0,1,3]) ; grp0_0.setName("grp0_Lev0") +grp1_0=DataArrayInt.New([1,2,3,4]) ; grp1_0.setName("grp1_Lev0") +meshMEDFile.setGroupsAtLevel(0,[grp0_0,grp1_0]) +# Some groups on cells Level -1 +grp0_M1=DataArrayInt.New([0,1]) ; grp0_M1.setName("grp0_LevM1") +grp1_M1=DataArrayInt.New([0,1,2]) ; grp1_M1.setName("grp1_LevM1") +grp2_M1=DataArrayInt.New([1,2,3]) ; grp2_M1.setName("grp2_LevM1") +meshMEDFile.setGroupsAtLevel(-1,[grp0_M1,grp1_M1,grp2_M1]) +# +meshMEDFile.write("TargetMesh2.med",2) # 2 stands for write from scratch +# +meshMEDFileRead=MEDFileMesh.New("TargetMesh2.med") +meshRead0=meshMEDFileRead.getMeshAtLevel(0) +meshRead1=meshMEDFileRead.getMeshAtLevel(-1) +print "Is the mesh at level 0 read in file equals targetMesh ? %s"%(meshRead0.isEqual(targetMesh,1e-12)) ; assert meshRead0.isEqual(targetMesh,1e-12) +print "Is the mesh at level -1 read in file equals targetMesh ? %s"%(meshRead1.isEqual(targetMesh1,1e-12)) ; assert meshRead1.isEqual(targetMesh1,1e-12) +# +print meshMEDFileRead.getGrpNonEmptyLevels("grp0_Lev0") +grp0_0_read=meshMEDFileRead.getGroupArr(0,"grp0_Lev0") +print "Is group \"grp0_Lev0\" are the same ? %s"%(grp0_0_read.isEqual(grp0_0)) ; assert grp0_0_read.isEqual(grp0_0) +# +# Fields +# +f=MEDCouplingFieldDouble.New(ON_CELLS,ONE_TIME) +f.setTime(5.6,7,8) +f.setArray(targetMesh.getBarycenterAndOwner()) +f.setMesh(targetMesh) +f.setName("AFieldName") +# +fMEDFile=MEDFileField1TS.New() +fMEDFile.setFieldNoProfileSBT(f) +# +fMEDFile.write("TargetMesh2.med",0) # 0 is very important here because we want to append to TargetMesh2.med and not to scratch it +# +fMEDFileRead=MEDFileField1TS.New("TargetMesh2.med",f.getName(),7,8) +fRead1=fMEDFileRead.getFieldOnMeshAtLevel(ON_CELLS,0,meshMEDFileRead) # fastest method. No read in file. +fRead2=fMEDFileRead.getFieldAtLevel(ON_CELLS,0) # basic method like, mesh is reread in file... +print "Does the field f remains the same using fast method ? %s"%(fRead1.isEqual(f,1e-12,1e-12)) ; assert fRead1.isEqual(f,1e-12,1e-12) +print "Does the field f remains the same using slow method ? %s"%(fRead2.isEqual(f,1e-12,1e-12)) ; assert fRead2.isEqual(f,1e-12,1e-12) +# +# Writing and Reading fields on profile using MEDLoader advanced API +# +pfl=DataArrayInt.New([1,2,3]) ; pfl.setName("My1stPfl") +fPart=f.buildSubPart(pfl) +fPart.setName("fPart") +# +fMEDFile2=MEDFileField1TS.New() +fMEDFile2.setFieldProfile(fPart,meshMEDFileRead,0,pfl) +fMEDFile2.write("TargetMesh2.med",0) # 0 is very important here because we want to append to TargetMesh2.med and not to scratch it +# +fMEDFileRead2=MEDFileField1TS.New("TargetMesh2.med",fPart.getName(),7,8) +fPartRead,pflRead=fMEDFileRead2.getFieldWithProfile(ON_CELLS,0,meshMEDFileRead) +print fPartRead.isEqualWithoutConsideringStr(fPart.getArray(),1e-12) ; assert fPartRead.isEqualWithoutConsideringStr(fPart.getArray(),1e-12) +print pflRead.isEqualWithoutConsideringStr(pfl) ; assert pflRead.isEqualWithoutConsideringStr(pfl) + +##### + +m0=MEDCouplingCMesh() +arr=DataArrayDouble(31,1) ; arr.iota(0.) +m0.setCoords(arr,arr) +m0=m0.buildUnstructured() +m00=m0[::2] ; m00.simplexize(0) ; m01=m0[1::2] +m0=MEDCouplingUMesh.MergeUMeshes([m00,m01]) +m0.getCoords()[:]*=1/15. +m0.setName("mesh") +# +CellField=MEDCouplingFieldDouble(ON_CELLS,ONE_TIME) ; CellField.setTime(5.6,5,6) ; CellField.setMesh(m0) +CellField.setName("CellField") +CellField.fillFromAnalytic(1,"exp(-((x-1)*(x-1)+(y-1)*(y-1)))") ; CellField.getArray().setInfoOnComponent(0,"powercell [W]") +NodeField=MEDCouplingFieldDouble(ON_NODES,ONE_TIME) ; NodeField.setTime(5.6,5,6) ; NodeField.setMesh(m0) +NodeField.setName("NodeField") +NodeField.fillFromAnalytic(1,"exp(-((x-1)*(x-1)+(y-1)*(y-1)))") ; NodeField.getArray().setInfoOnComponent(0,"powernode [W]") +# +proc0=m0.getCellsInBoundingBox([(0.,0.4),(0.,0.4)],1e-10) +proc1=proc0.buildComplement(m0.getNumberOfCells()) +# +NodeField0=NodeField[proc0] ; NodeField0.getMesh().setName(m0.getName()) ; CellField0=CellField[proc0] ; CellField0.setMesh(NodeField0.getMesh()) +NodeField1=NodeField[proc1] ; NodeField1.getMesh().setName(m0.getName()) ; CellField1=CellField[proc1] ; CellField1.setMesh(NodeField1.getMesh()) +# +proc0_fname="proc0.med" +MEDLoader.WriteField(proc0_fname,NodeField0,True) +MEDLoader.WriteFieldUsingAlreadyWrittenMesh(proc0_fname,CellField0) +proc1_fname="proc1.med" +MEDLoader.WriteField(proc1_fname,NodeField1,True) +MEDLoader.WriteFieldUsingAlreadyWrittenMesh(proc1_fname,CellField1) +# +CellField0_read=MEDLoader.ReadFieldCell("proc0.med","mesh",0,"CellField",5,6) +CellField1_read=MEDLoader.ReadFieldCell("proc1.med","mesh",0,"CellField",5,6) +CellField_read=MEDCouplingFieldDouble.MergeFields([CellField0_read,CellField1_read]) +CellFieldCpy=CellField.deepCpy() +CellFieldCpy.substractInPlaceDM(CellField_read,10,1e-12) +CellFieldCpy.getArray().abs() +print CellFieldCpy.getArray().isUniform(0.,1e-12) +# +NodeField0_read=MEDLoader.ReadFieldNode("proc0.med","mesh",0,"NodeField",5,6) +NodeField1_read=MEDLoader.ReadFieldNode("proc1.med","mesh",0,"NodeField",5,6) +NodeField_read=MEDCouplingFieldDouble.MergeFields([NodeField0_read,NodeField1_read]) +NodeField_read.mergeNodes(1e-10) +NodeFieldCpy=NodeField.deepCpy() +NodeFieldCpy.mergeNodes(1e-10) +NodeFieldCpy.substractInPlaceDM(NodeField_read,10,1e-12) +print NodeFieldCpy.getArray().isUniform(0.,1e-12) ; assert NodeFieldCpy.getArray().isUniform(0.,1e-12) +# +fileNames=["proc0.med","proc1.med"] +msML=[MEDFileMesh.New(fname) for fname in fileNames] +fsML=[MEDFileFields.New(fname) for fname in fileNames] +mergeMLMesh=MEDFileUMesh() +mergeMLFields=MEDFileFields() +for lev in msML[0].getNonEmptyLevels(): + o2nML=len(msML[0].getNonEmptyLevels())*[None] + cs=[mML.getCoords() for mML in msML] + mergeMLMesh.setCoords(DataArrayDouble.Aggregate(cs)) + ms=[mML.getMeshAtLevel(lev) for mML in msML] + m=MEDCouplingUMesh.MergeUMeshes(ms) ; m.setCoords(mergeMLMesh.getCoords()) + o2nML[lev]=m.sortCellsInMEDFileFrmt() + mergeMLMesh.setMeshAtLevel(lev,m) + pass +# +for fieldName in fsML[0].getFieldsNames(): + fmts=[fML[fieldName] for fML in fsML] + mergeField=MEDFileFieldMultiTS() + for dt,it,tim in fmts[0].getTimeSteps(): + fts=[fmt[dt,it] for fmt in fmts] + arrs=len(fts)*[None] + for typp in fts[0].getTypesOfFieldAvailable(): + arr1s=[] + if typp==ON_CELLS: + for ft in fts: + for geoTyp,smth in ft.getFieldSplitedByType(): + if geoTyp!=NORM_ERROR: + smth1=filter(lambda x:x[0]==ON_CELLS,smth) + arr2s=[ft.getUndergroundDataArray()[elt[1][0]:elt[1][1]] for elt in smth1] + arr1s.append(DataArrayDouble.Aggregate(arr2s)) + pass + pass + pass + pass + else: + for ft in fts: + smth=filter(lambda x:x[0]==NORM_ERROR,ft.getFieldSplitedByType()) + arr2=DataArrayDouble.Aggregate([ft.getUndergroundDataArray()[elt[1][0][1][0]:elt[1][0][1][1]] for elt in smth]) + arr1s.append(arr2) + pass + pass + arr=DataArrayDouble.Aggregate(arr1s) + if typp==ON_CELLS: + arr.renumberInPlace(o2nML[lev]) + mcf=MEDCouplingFieldDouble(typp,ONE_TIME) ; mcf.setName(fieldName) ; mcf.setTime(tim,dt,it) ; mcf.setArray(arr) + mcf.setMesh(mergeMLMesh.getMeshAtLevel(lev)) ; mcf.checkCoherency() + mergeField.appendFieldNoProfileSBT(mcf) + pass + pass + mergeMLFields.pushField(mergeField) + pass +mergeMLMesh.write("merge.med",2) +mergeMLFields.write("merge.med",0) + +##### + +arr=DataArrayDouble(11) ; arr.iota(0) +trgMesh=MEDCouplingCMesh() ; trgMesh.setCoords(arr,arr) ; trgMesh=trgMesh.buildUnstructured() +# +arr=DataArrayDouble(21) ; arr.iota(0) ; arr*=0.5 +srcMesh=MEDCouplingCMesh() ; srcMesh.setCoords(arr,arr) ; srcMesh=srcMesh.buildUnstructured() +# +tmp=srcMesh[:20] ; tmp.simplexize(0) +srcMesh=MEDCouplingUMesh.MergeUMeshes([tmp,srcMesh[20:]]) +# +remap=MEDCouplingRemapper() +remap.prepare(srcMesh,trgMesh,"P0P0") +# +myMatrix=remap.getCrudeMatrix() +print myMatrix # pour voir a quoi elle ressemble +sumByRows=DataArrayDouble(len(myMatrix)) +for i,wIt in enumerate(sumByRows): + su=0. + for it in myMatrix[i]: + su+=myMatrix[i][it] + wIt[0]=su +print "Does interpolation look OK ? %s"%(str(sumByRows.isUniform(1.,1e-12))) ; assert sumByRows.isUniform(1.,1e-12) +# +srcField=MEDCouplingFieldDouble(ON_CELLS,ONE_TIME) ; srcField.setMesh(srcMesh) +srcField.fillFromAnalytic(1,"7-sqrt((x-5.)*(x-5.)+(y-5.)*(y-5.))") ; CellField.getArray().setInfoOnComponent(0,"powercell [W]") +# +#remap.transferField(srcField,1e300) +srcField.setNature(ConservativeVolumic) +trgFieldCV=remap.transferField(srcField,1e300) +# +print "ConservativeVolumic %lf == %lf"%(srcField.integral(True)[0],trgFieldCV.integral(True)[0]) ; assert abs(srcField.integral(True)[0]-trgFieldCV.integral(True)[0])<1e-6 +print "ConservativeVolumic %lf != %lf"%(srcField.getArray().accumulate()[0],trgFieldCV.getArray().accumulate()[0]) ; assert abs(srcField.getArray().accumulate()[0]-trgFieldCV.getArray().accumulate()[0])>1e-6 +# +srcField.setNature(Integral) +trgFieldI=remap.transferField(srcField,1e300) +# +print "IntegralGlobConstraint %lf != %lf"%(srcField.integral(True)[0],trgFieldI.integral(True)[0]) ; assert abs(srcField.integral(True)[0]-trgFieldI.integral(True)[0])>1e-6 +print "IntegralGlobConstraint %lf == %lf"%(srcField.getArray().accumulate()[0],trgFieldI.getArray().accumulate()[0]) ; assert abs(srcField.getArray().accumulate()[0]-trgFieldI.getArray().accumulate()[0])<1e-6 + +###### + +from numpy import * +from math import acos + +med_root_dir=os.getenv("MED_ROOT_DIR") +agitateur_file=os.path.join(os.getenv("MED_ROOT_DIR"),"share","salome","resources","med","agitateur.med") +data=MEDFileData(agitateur_file) +ts=data.getFields()[0].getTimeSteps() +print ts +# +fMts=data.getFields()["DISTANCE_INTERFACE_ELEM_BODY_ELEM_DOM"] +f1ts=fMts[(2,-1)] +fMc=f1ts.getFieldAtLevel(ON_CELLS,0) +arr=fMc.getArray() +arr.getMinMaxPerComponent() # juste pour voir la plage de variation du champ par compo +ids=arr.getIdsInRange(0.,1.) +f2Mc=fMc[ids] +# +pressMts=data.getFields()["PRESSION_ELEM_DOM"] +press1ts=pressMts[(2,-1)] +pressMc=press1ts.getFieldAtLevel(ON_CELLS,0) +pressOnAgitateurMc=pressMc[ids] +# +pressOnAgitateurMc.getMesh().zipCoords() +# +agitateurMesh3DMc=pressOnAgitateurMc.getMesh() +m3DSurf,desc,descI,revDesc,revDescI=agitateurMesh3DMc.buildDescendingConnectivity() +nbOf3DCellSharing=revDescI.deltaShiftIndex() +ids2=nbOf3DCellSharing.getIdsEqual(1) +agitateurSkinMc=m3DSurf[ids2] +OffsetsOfTupleIdsInField=revDescI[ids2] +tupleIdsInField=revDesc[OffsetsOfTupleIdsInField] +pressOnSkinAgitateurMc=pressOnAgitateurMc[tupleIdsInField] +pressOnSkinAgitateurMc.setMesh(agitateurSkinMc) +# +pressSkin=pressOnSkinAgitateurMc.getArray() +pressSkin*=1e5 +areaSkin=agitateurSkinMc.getMeasureField(True).getArray() +forceSkin=pressSkin*areaSkin +normalSkin=agitateurSkinMc.buildOrthogonalField().getArray() +forceVectSkin=forceSkin*normalSkin +# +singlePolyhedron=agitateurMesh3DMc.buildSpreadZonesWithPoly() +singlePolyhedron.orientCorrectlyPolyhedrons() +centerOfMass=singlePolyhedron.getBarycenterAndOwner() + +barySkin=agitateurSkinMc.getBarycenterAndOwner() +posSkin=barySkin-centerOfMass + +torquePerCellOnSkin=DataArrayDouble.CrossProduct(posSkin,forceVectSkin) + +zeTorque=torquePerCellOnSkin.accumulate() +print "couple = %r N.m"%(zeTorque[2]) ; assert abs(zeTorque[2]-0.37)<1e-2 + +speedMts=data.getFields()["VITESSE_ELEM_DOM"] +speed1ts=speedMts[(2,-1)] +speedMc=speed1ts.getFieldAtLevel(ON_CELLS,0) +speedOnSkin=speedMc.getArray()[tupleIdsInField] +powerSkin=DataArrayDouble.Dot(forceVectSkin,speedOnSkin) +power=powerSkin.accumulate()[0] +print "power = %r W"%(power) ; assert abs(power-4.22)<1e-2 + +x2=posSkin[:,0]*posSkin[:,0] ; x2=x2.accumulate()[0] +y2=posSkin[:,1]*posSkin[:,1] ; y2=y2.accumulate()[0] +xy=posSkin[:,0]*posSkin[:,1] ; xy=xy.accumulate()[0] +inertiaSkin=matrix([[x2,xy],[xy,y2]]) +inertiaSkinValues,inertiaSkinVects=linalg.eig(inertiaSkin) +pos=max(enumerate(inertiaSkinValues),key=lambda x: x[1])[0] +vect0=inertiaSkinVects[pos].tolist()[0] +print vect0 + +def computeAngle(locAgitateur1ts): + fMc=locAgitateur1ts.getFieldAtLevel(ON_CELLS,0) + arr=fMc.getArray() + ids=arr.getIdsInRange(0.,1.) + f2Mc=fMc[ids] + m3DSurf,desc,descI,revDesc,revDescI=f2Mc.getMesh().buildDescendingConnectivity() + nbOf3DCellSharing=revDescI.deltaShiftIndex() + ids2=nbOf3DCellSharing.getIdsEqual(1) + agitateurSkinMc=m3DSurf[ids2] + # + singlePolyhedron=agitateurMesh3DMc.buildSpreadZonesWithPoly() + singlePolyhedron.orientCorrectlyPolyhedrons() + centerOfMass=singlePolyhedron.getBarycenterAndOwner() + bary=agitateurSkinMc.getBarycenterAndOwner() + posSkin=bary-centerOfMass + x2=posSkin[:,0]*posSkin[:,0] ; x2=x2.accumulate()[0] + y2=posSkin[:,1]*posSkin[:,1] ; y2=y2.accumulate()[0] + xy=posSkin[:,0]*posSkin[:,1] ; xy=xy.accumulate()[0] + inertiaSkin=matrix([[x2,xy],[xy,y2]]) + inertiaSkinValues,inertiaSkinVects=linalg.eig(inertiaSkin) + pos=max(enumerate(inertiaSkinValues),key=lambda x: x[1])[0] + vect0=inertiaSkinVects[pos].tolist()[0] + return vect0 + +vects=len(ts)*[None] +for itts,locAgitateur1ts in zip(ts,data.getFields()["DISTANCE_INTERFACE_ELEM_BODY_ELEM_DOM"]): + angle=computeAngle(locAgitateur1ts) + vects[itts[0]]=angle + pass + +angle2=len(ts)*[0.] +for pos in xrange(2,len(vects)): + norm1=sqrt(vects[pos-1][0]*vects[pos-1][0]+vects[pos-1][1]*vects[pos-1][1]) + norm2=sqrt(vects[pos][0]*vects[pos][0]+vects[pos][1]*vects[pos][1]) + crs=vects[pos-1][0]*vects[pos][0]+vects[pos-1][1]*vects[pos][1] + crs/=norm1 ; crs/=norm2 ; crs=min(crs,1.) + angle2[pos]=acos(crs)#/(ts[pos][2]-ts[pos-1][2]) + pass + +omega=sum(angle2)/(ts[-1][2]-ts[0][2]) +print sum(angle2) ; assert abs(sum(angle2)-1.12)<1e-2 +print "Au pdt (%d,%d) a %r s le couple est de : %r N.m, power/omega=%r N.m"%(ts[2][0],ts[2][1],ts[2][2],zeTorque[2],power/omega) +assert abs(power/omega-0.37)<1e-2 diff --git a/src/medtool/src/MEDLoader/Swig/MEDLoaderDataForTest.py b/src/medtool/src/MEDLoader/Swig/MEDLoaderDataForTest.py new file mode 100644 index 000000000..e8f0f5332 --- /dev/null +++ b/src/medtool/src/MEDLoader/Swig/MEDLoaderDataForTest.py @@ -0,0 +1,728 @@ +# -*- coding: iso-8859-1 -*- +# Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 +# 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) + +from MEDLoader import * +from math import pi,e,sqrt + +class MEDLoaderDataForTest: + def build1DMesh_1(cls): + coords=[ 0.0, 0.3, 0.75, 1.0, 1.4, 1.3 ] + conn=[ 0,1, 1,2, 2,3 , 3,4,5] + mesh=MEDCouplingUMesh.New(); + mesh.setName("1DMesh_1"); + mesh.setMeshDimension(1); + mesh.allocateCells(4); + mesh.insertNextCell(NORM_SEG2,2,conn[0:2]) + mesh.insertNextCell(NORM_SEG2,2,conn[2:4]) + mesh.insertNextCell(NORM_SEG2,2,conn[4:6]) + mesh.insertNextCell(NORM_SEG3,3,conn[6:9]) + mesh.finishInsertingCells(); + myCoords=DataArrayDouble.New(); + myCoords.setValues(coords,6,1); + myCoords.setInfoOnComponent(0,"tototototototot [m*m*m*m*m*m*m*m]"); + mesh.setCoords(myCoords); + return mesh; + + def build2DCurveMesh_1(cls): + coords=[ 0.0,0.0, 0.3,0.3, 0.75,0.75, 1.0,1.0, 1.4,1.4, 1.3,1.3 ] + conn=[ 0,1, 1,2, 2,3 , 3,4,5] + mesh=MEDCouplingUMesh.New(); + mesh.setName("2DCurveMesh_1"); + mesh.setMeshDimension(1); + mesh.allocateCells(4); + mesh.insertNextCell(NORM_SEG2,2,conn[0:2]) + mesh.insertNextCell(NORM_SEG2,2,conn[2:4]) + mesh.insertNextCell(NORM_SEG2,2,conn[4:6]) + mesh.insertNextCell(NORM_SEG3,3,conn[6:9]) + mesh.finishInsertingCells(); + myCoords=DataArrayDouble.New(); + myCoords.setValues(coords,6,2); + mesh.setCoords(myCoords); + return mesh; + + def build2DMesh_1(cls): + targetCoords=[-0.3,-0.3, 0.2,-0.3, 0.7,-0.3, -0.3,0.2, 0.2,0.2, 0.7,0.2, -0.3,0.7, 0.2,0.7, 0.7,0.7, + -0.05,0.95, 0.2,1.2, 0.45,0.95] + targetConn=[1,4,2, 4,5,2, 6,10,8,9,11,7, 0,3,4,1, 6,7,4,3, 7,8,5,4] + targetMesh=MEDCouplingUMesh.New(); + targetMesh.setMeshDimension(2); + targetMesh.allocateCells(6); + targetMesh.setName("2DMesh_1"); + targetMesh.insertNextCell(NORM_TRI3,3,targetConn[0:3]) + targetMesh.insertNextCell(NORM_TRI3,3,targetConn[3:6]) + targetMesh.insertNextCell(NORM_TRI6,6,targetConn[6:12]) + targetMesh.insertNextCell(NORM_QUAD4,4,targetConn[12:16]) + targetMesh.insertNextCell(NORM_QUAD4,4,targetConn[16:20]) + targetMesh.insertNextCell(NORM_POLYGON,4,targetConn[20:24]) + targetMesh.finishInsertingCells(); + myCoords=DataArrayDouble.New(); + myCoords.setValues(targetCoords,12,2); + myCoords.setInfoOnComponent(0,"tototototototot [m]"); + myCoords.setInfoOnComponent(1,"energie [kW]"); + targetMesh.setCoords(myCoords) + return targetMesh; + + def build2DMesh_2(cls): + targetCoords=[-0.3,-0.3, 0.2,-0.3, 0.7,-0.3, -0.3,0.2, 0.2,0.2, 0.7,0.2, -0.3,0.7, 0.2,0.7, 0.7,0.7, + -0.05,0.95, 0.2,1.2, 0.45,0.95] + targetConn=[1,4,2, 4,5,2, 6,10,8,9,11,7, 0,3,4,1, 6,7,4,3, 7,8,5,4] + targetMesh=MEDCouplingUMesh.New(); + targetMesh.setMeshDimension(2); + targetMesh.allocateCells(5); + targetMesh.setName("2DMesh_2"); + targetMesh.insertNextCell(NORM_TRI3,3,targetConn[0:3]) + targetMesh.insertNextCell(NORM_TRI3,3,targetConn[3:6]) + targetMesh.insertNextCell(NORM_QUAD4,4,targetConn[12:16]) + targetMesh.insertNextCell(NORM_QUAD4,4,targetConn[16:20]) + targetMesh.insertNextCell(NORM_TRI6,6,targetConn[6:12]) + targetMesh.finishInsertingCells(); + myCoords=DataArrayDouble.New(); + myCoords.setValues(targetCoords,12,2); + myCoords.setInfoOnComponent(0,"toto [m]"); + myCoords.setInfoOnComponent(1,"energie [kW]"); + targetMesh.setCoords(myCoords); + return targetMesh; + + #this mesh has several cells duplicated ! it is not beautiful but efficient to test file WR. + def build2DMesh_3(cls): + targetCoords=[-0.3,-0.3, 0.2,-0.3, 0.7,-0.3, -0.3,0.2, 0.2,0.2, 0.7,0.2, -0.3,0.7, 0.2,0.7, 0.7,0.7, + -0.05,0.95, 0.2,1.2, 0.45,0.95] + targetConn=[1,4,2, 4,5,2, 6,10,8,9,11,7, 0,3,4,1, 6,7,4,3, 7,8,5,4] + targetMesh=MEDCouplingUMesh.New(); + targetMesh.setMeshDimension(2); + targetMesh.allocateCells(13); + targetMesh.setName("2DMesh_3"); + targetMesh.insertNextCell(NORM_TRI3,3,targetConn[0:3]) + targetMesh.insertNextCell(NORM_TRI3,3,targetConn[3:6]) + targetMesh.insertNextCell(NORM_TRI3,3,targetConn[0:3]) + targetMesh.insertNextCell(NORM_TRI3,3,targetConn[3:6]) + targetMesh.insertNextCell(NORM_TRI3,3,targetConn[0:3]) + targetMesh.insertNextCell(NORM_TRI3,3,targetConn[3:6]) + targetMesh.insertNextCell(NORM_QUAD4,4,targetConn[12:16]) + targetMesh.insertNextCell(NORM_QUAD4,4,targetConn[16:20]) + targetMesh.insertNextCell(NORM_QUAD4,4,targetConn[12:16]) + targetMesh.insertNextCell(NORM_QUAD4,4,targetConn[16:20]) + targetMesh.insertNextCell(NORM_TRI6,6,targetConn[6:12]) + targetMesh.insertNextCell(NORM_TRI6,6,targetConn[6:12]) + targetMesh.insertNextCell(NORM_TRI6,6,targetConn[6:12]) + targetMesh.finishInsertingCells(); + myCoords=DataArrayDouble.New(); + myCoords.setValues(targetCoords,12,2); + myCoords.setInfoOnComponent(0,"toto [m]"); + myCoords.setInfoOnComponent(1,"energie [kW]"); + targetMesh.setCoords(myCoords); + return targetMesh; + + def build3DMesh_1(cls): + coords=[0.,0.,0., 1.,1.,0., 1.,1.25,0., 0.,1.,0., 1.,1.5,0., 2.,0.,0., 2.,1.,0., 1.,2.,0., 0.,2.,0., 3.,1.,0., + 3.,2.,0., 0.,1.,0., 1.,3.,0., 2.,2.,0., 2.,3.,0., + 0.,0.,1., 1.,1.,1., 1.,1.25,1., 0.,1.,1., 1.,1.5,1., 2.,0.,1., 2.,1.,1., 1.,2.,1., 0.,2.,1., 3.,1.,1., + 3.,2.,1., 0.,1.,1., 1.,3.,1., 2.,2.,1., 2.,3.,1., + 0.,0.,2., 1.,1.,2., 1.,1.25,2., 0.,1.,2., 1.,1.5,2., 2.,0.,2., 2.,1.,2., 1.,2.,2., 0.,2.,2., 3.,1.,2., + 3.,2.,2., 0.,1.,2., 1.,3.,2., 2.,2.,2., 2.,3.,2., + 0.,0.,3., 1.,1.,3., 1.,1.25,3., 0.,1.,3., 1.,1.5,3., 2.,0.,3., 2.,1.,3., 1.,2.,3., 0.,2.,3., 3.,1.,3., + 3.,2.,3., 0.,1.,3., 1.,3.,3., 2.,2.,3., 2.,3.,3.] + conn=[ + # 0 + 0,11,1,3,15,26,16,18, 1,2,4,7,13,6,-1,1,16,21,6,-1,6,21,28,13,-1,13,7,22,28,-1,7,4,19,22,-1,4,2,17,19,-1,2,1,16,17,-1,16,21,28,22,19,17, + 1,6,5,3,16,21,20,18, 13,10,9,6,28,25,24,21, + 11,8,7,4,2,1,-1,11,26,16,1,-1,1,16,17,2,-1,2,17,19,4,-1,4,19,22,7,-1,7,8,23,22,-1,8,11,26,23,-1,26,16,17,19,22,23, + 7,12,14,13,22,27,29,28, + # 1 + 15,26,16,18,30,41,31,33, 16,17,19,22,28,21,-1,16,31,36,21,-1,21,36,43,28,-1,28,22,37,43,-1,22,19,34,37,-1,19,17,32,34,-1,17,16,31,32,-1,31,36,43,37,34,32, + 16,21,20,18,31,36,35,33, 28,25,24,21,43,40,39,36, + 26,23,22,19,17,16,-1,26,41,31,16,-1,16,31,32,17,-1,17,32,34,19,-1,19,34,37,22,-1,22,23,38,37,-1,23,26,41,38,-1,41,31,32,34,37,38, + 22,27,29,28,37,42,44,43, + # 2 + 30,41,31,33,45,56,46,48, 31,32,34,37,43,36,-1,31,46,51,36,-1,36,51,58,43,-1,43,37,52,58,-1,37,34,49,52,-1,34,32,47,49,-1,32,31,46,47,-1,46,51,58,52,49,47, + 31,36,35,33,46,51,50,48, 43,40,39,36,58,55,54,51, + 41,38,37,34,32,31,-1,41,56,46,31,-1,31,46,47,32,-1,32,47,49,34,-1,34,49,52,37,-1,37,38,53,52,-1,38,41,56,53,-1,56,46,47,49,52,53, + 37,42,44,43,52,57,59,58] + # + ret=MEDCouplingUMesh.New(); + ret.setName("3DMesh_1"); + ret.setMeshDimension(3); + ret.allocateCells(18); + # + ret.insertNextCell(NORM_HEXA8,8,conn[0:8]) + ret.insertNextCell(NORM_HEXA8,8,conn[51:59]) + ret.insertNextCell(NORM_HEXA8,8,conn[59:67]) + ret.insertNextCell(NORM_HEXA8,8,conn[110:118]) + # + ret.insertNextCell(NORM_HEXA8,8,conn[118:126]) + ret.insertNextCell(NORM_HEXA8,8,conn[169:177]) + ret.insertNextCell(NORM_HEXA8,8,conn[177:185]) + ret.insertNextCell(NORM_HEXA8,8,conn[228:236]) + # + ret.insertNextCell(NORM_HEXA8,8,conn[236:244]) + ret.insertNextCell(NORM_HEXA8,8,conn[287:295]) + ret.insertNextCell(NORM_HEXA8,8,conn[295:303]) + ret.insertNextCell(NORM_HEXA8,8,conn[346:354]) + # + ret.insertNextCell(NORM_POLYHED,43,conn[8:51]) + ret.insertNextCell(NORM_POLYHED,43,conn[67:110]) + ret.insertNextCell(NORM_POLYHED,43,conn[126:169]) + ret.insertNextCell(NORM_POLYHED,43,conn[185:228]) + ret.insertNextCell(NORM_POLYHED,43,conn[244:287]) + ret.insertNextCell(NORM_POLYHED,43,conn[303:346]) + # + ret.finishInsertingCells(); + myCoords=DataArrayDouble.New(); + myCoords.setValues(coords,60,3); + myCoords.setInfoOnComponent(0,"titi [m]"); + myCoords.setInfoOnComponent(1,"density power [MW/m^3]"); + myCoords.setInfoOnComponent(2,"t [kW]"); + ret.setCoords(myCoords); + return ret; + + def build3DSurfMesh_1(cls): + targetCoords=[-0.3,-0.3,-0.3, 0.2,-0.3,-0.3, 0.7,-0.3,-0.3, -0.3,0.2,-0.3, 0.2,0.2,-0.3, 0.7,0.2,-0.3, -0.3,0.7,-0.3, 0.2,0.7,-0.3, 0.7,0.7,-0.3 + ,-0.05,0.95,-0.3, 0.2,1.2,-0.3, 0.45,0.95,-0.3] + targetConn=[1,4,2, 4,5,2, 6,10,8,9,11,7, 0,3,4,1, 6,7,4,3, 7,8,5,4] + targetMesh=MEDCouplingUMesh.New(); + targetMesh.setMeshDimension(2); + targetMesh.allocateCells(6); + targetMesh.setName("3DSurfMesh_1"); + targetMesh.insertNextCell(NORM_TRI3,3,targetConn[0:3]) + targetMesh.insertNextCell(NORM_TRI3,3,targetConn[3:6]) + targetMesh.insertNextCell(NORM_QUAD4,4,targetConn[12:16]) + targetMesh.insertNextCell(NORM_QUAD4,4,targetConn[16:20]) + targetMesh.insertNextCell(NORM_TRI6,6,targetConn[6:12]) + targetMesh.insertNextCell(NORM_POLYGON,4,targetConn[20:24]) + targetMesh.finishInsertingCells(); + myCoords=DataArrayDouble.New(); + myCoords.setValues(targetCoords,12,3); + myCoords.setInfoOnComponent(0,"toto [m]"); + myCoords.setInfoOnComponent(2,"ff [km]");#component 1 is not set for test + targetMesh.setCoords(myCoords); + return targetMesh; + + def build3DMesh_2(cls): + m3dsurfBase=MEDLoaderDataForTest.build3DSurfMesh_1(); + numbers=[0,1,2,3,5] + m3dsurf=m3dsurfBase.buildPartOfMySelf(numbers,False); + m1dBase=MEDLoaderDataForTest.build1DMesh_1(); + numbers2=[0,1,2,3] + m1d=m1dBase.buildPartOfMySelf(numbers2,False); + m1d.changeSpaceDimension(3); + vec=[0.,1.,0.] + pt=[0.,0.,0.] + m1d.rotate(pt,vec,-pi/2.); + ret=m3dsurf.buildExtrudedMesh(m1d,0); + return ret; + + def buildMultiLevelMesh_1(cls): + coo=[10.,0.,10.,1.25,10.,2.5,10.,3.75,10.,5.,8.75,0.,8.75,1.25,8.75,2.5,8.75,3.75,8.75,5.,7.5,0.,7.5,1.25,7.5,2.5,7.5,3.75,7.5,5.,6.25,0.,6.25,1.25,6.25,2.5,6.25,3.75,6.25,5.,5.,0.,5.,1.25,5.,2.5,5.,3.75,5.,5.,3.75,0.,3.75,1.25,3.75,2.5,3.75,3.75,3.75,5.,2.5,0.,2.5,1.25,2.5,2.5,2.5,3.75,2.5,5.,1.25,0.,1.25,1.25,1.25,2.5,1.25,3.75,1.25,5.,0.,1.25,0.,2.5,0.,3.75,0.,5.,0.,0.,0.,5.,10.,5.,0.,10.,10.,10.,5.,5.,5.,5.,5.,10.,5.,10.,0.625,5.,1.25,5.,1.875,5.,2.5,5.,3.125,5.,3.75,5.,4.375,5.,5.,6.25,5.,7.5,5.,8.75,4.375,10.,3.75,10.,3.125,10.,2.5,10.,1.875,10.,1.25,10.,0.625,10.,0.,8.75,0.,7.5,0.,6.25,4.375,6.25,4.375,7.5,4.375,8.75,3.75,6.25,3.75,7.5,3.75,8.75,3.125,6.25,3.125,7.5,3.125,8.75,2.5,6.25,2.5,7.5,2.5,8.75,1.875,6.25,1.875,7.5,1.875,8.75,1.25,6.25,1.25,7.5,1.25,8.75,0.625,6.25,0.625,7.5,0.625,8.75,5.625,5.,6.25,5.,6.875,5.,7.5,5.,8.125,5.,8.75,5.,9.375,5.,10.,6.25,10.,7.5,10.,8.75,9.375,10.,8.75,10.,8.125,10.,7.5,10.,6.875,10.,6.25,10.,5.625,10.,5.,8.75,5.,7.5,5.,6.25,9.375,6.25,9.375,7.5,9.375,8.75,8.75,6.25,8.75,7.5,8.75,8.75,8.125,6.25,8.125,7.5,8.125,8.75,7.5,6.25,7.5,7.5,7.5,8.75,6.875,6.25,6.875,7.5,6.875,8.75,6.25,6.25,6.25,7.5,6.25,8.75,5.625,6.25,5.625,7.5,5.625,8.75] + coo2=DataArrayDouble.New() + coo2.setValues(coo,135,2) + coo2=coo2.changeNbOfComponents(3,0.) + coo2.setInfoOnComponent(0,"X [INCONNUE]") + coo2.setInfoOnComponent(1,"Y [INCONNUE]") + coo2.setInfoOnComponent(2,"Z [INCONNUE]") + c2tri=[0,1,6,0,6,5,1,2,6,2,7,6,2,3,8,2,8,7,3,4,8,4,9,8,5,6,11,5,11,10,6,7,11,7,12,11,7,8,13,7,13,12,8,9,13,9,14,13,10,11,16,10,16,15,11,12,16,12,17,16,12,13,18,12,18,17,13,14,18,14,19,18,15,16,21,15,21,20,16,17,21,17,22,21,17,18,23,17,23,22,18,19,23,19,24,23,20,21,26,20,26,25,21,22,26,22,27,26,22,23,28,22,28,27,23,24,28,24,29,28,25,26,31,25,31,30,26,27,31,27,32,31,27,28,33,27,33,32,28,29,33,29,34,33,30,31,36,30,36,35,31,32,36,32,37,36,32,33,38,32,38,37,33,34,38,34,39,38,35,36,40,35,40,44,36,37,40,37,41,40,37,38,42,37,42,41,38,39,42,39,43,42] + c2quad4=[46,101,114,100,101,102,115,114,102,103,116,115,103,48,104,116,100,114,117,99,114,115,118,117,115,116,119,118,116,104,105,119,99,117,120,98,117,118,121,120,118,119,122,121,119,105,106,122,98,120,123,97,120,121,124,123,121,122,125,124,122,106,107,125,97,123,126,96,123,124,127,126,124,125,128,127,125,107,108,128,96,126,129,95,126,127,130,129,127,128,131,130,128,108,109,131,95,129,132,94,129,130,133,132,130,131,134,133,131,109,110,134,94,132,113,50,132,133,112,113,133,134,111,112,134,110,51,111,49,60,73,59,60,61,74,73,61,62,75,74,62,52,63,75,59,73,76,58,73,74,77,76,74,75,78,77,75,63,64,78,58,76,79,57,76,77,80,79,77,78,81,80,78,64,65,81,57,79,82,56,79,80,83,82,80,81,84,83,81,65,66,84,56,82,85,55,82,83,86,85,83,84,87,86,84,66,67,87,55,85,88,54,85,86,89,88,86,87,90,89,87,67,68,90,54,88,91,53,88,89,92,91,89,90,93,92,90,68,69,93,53,91,72,45,91,92,71,72,92,93,70,71,93,69,47,70] + m2=MEDCouplingUMesh.New("ma",2) + m2.setCoords(coo2) + m2.allocateCells(128) + nbTri=len(c2tri)/3 + for i in xrange(nbTri): + m2.insertNextCell(NORM_TRI3,3,c2tri[3*i:3*i+3]) + pass + nbQua=len(c2quad4)/4 + for i in xrange(nbQua): + m2.insertNextCell(NORM_QUAD4,4,c2quad4[4*i:4*i+4]) + pass + m2.finishInsertingCells() + m2.setDescription("CREE PAR CODE_ASTER") + m1=MEDCouplingUMesh.New("ma",1) + m1.setCoords(coo2) + c1seg=[0,1,1,2,2,3,3,4,4,9,9,14,14,19,19,24,24,29,29,34,34,39,39,43,43,42,42,41,41,40,40,44,44,35,35,30,30,25,25,20,20,15,15,10,10,5,5,0,43,39,39,34,34,29,29,24,24,19,19,14,14,9,9,4,45,53,53,54,54,55,55,56,56,57,57,58,58,59,59,49,49,60,60,61,61,62,62,52,52,63,63,64,64,65,65,66,66,67,67,68,68,69,69,47,47,70,70,71,71,72,72,45,50,94,94,95,95,96,96,97,97,98,98,99,99,100,100,46,46,101,101,102,102,103,103,48,48,104,104,105,105,106,106,107,107,108,108,109,109,110,110,51,51,111,111,112,112,113,113,50] + m1.allocateCells(80) + for i in xrange(80): + m1.insertNextCell(NORM_SEG2,2,c1seg[2*i:2*i+2]) + pass + m1.finishInsertingCells() + m1.setDescription("CREE PAR CODE_ASTER") + m0=MEDCouplingUMesh.New("ma",0) + m0.setCoords(coo2) + c0pt=[44,0,47,48] + m0.allocateCells(4) + for i in xrange(4): + m0.insertNextCell(NORM_POINT1,1,[c0pt[i]]) + pass + m0.finishInsertingCells() + f2=DataArrayInt.New() + f2.alloc(128,1) + f2[:64]=-1 + f2[64:96]=-2 + f2[96:]=-3 + f1=DataArrayInt.New() + f1.alloc(80,1) + f1[:4]=-8 + f1[4:12]=-9 + f1[12:16]=-10 + f1[16:24]=-11 + f1[24:28]=-12 + f1[28:32]=-13 + f1[32:40]=-14 + f1[40:44]=-15 + f1[44:52]=-16 + f1[52:56]=-17 + f1[56:64]=-18 + f1[64:68]=-19 + f1[68:76]=-20 + f1[76:]=-21 + f0=DataArrayInt.New() + f0.setValues([-4,-5,-6,-7],4,1) + p=DataArrayInt.New() + p.alloc(135,1) + p.fillWithZero() + p1=DataArrayInt.New() + p1.alloc(13,1) + p1.iota(1) + p[[0,4,24,43,44,45,46,47,48,49,50,51,52]]=p1 + n2=DataArrayInt.New() + n2.alloc(128,1) + n2.iota(1) + n1=DataArrayInt.New() + n1.alloc(80,1) + n1.iota(133) + n0=DataArrayInt.New() + n0.alloc(4,1) + n0.iota(129) + fns=['A1A2____________________________', 'A1______________________________', 'A2A4____________________________', 'A2______________________________', 'A3A1____________________________', 'A3C5____________________________', 'A3______________________________', 'A4A3____________________________', 'A4______________________________', 'B1C1____________________________', 'B1______________________________', 'B2B4____________________________', 'B2______________________________', 'B3B1____________________________', 'B3______________________________', 'B4C3____________________________', 'B4______________________________', 'C1C4____________________________', 'C1______________________________', 'C2B2____________________________', 'C2______________________________', 'C3C2____________________________', 'C3______________________________', 'C4B3____________________________', 'C4______________________________', 'C5A4____________________________', 'C5______PMMA____________________', 'FAMILLE_ZERO', 'MESH____APPS____AP1_____________', 'MESH____APPS____AP2_____________', 'MESH____APPS____AP3_____________', 'MESH____APPS____AP4_____________', 'MESH____DALQ1___DALLE___________', 'MESH____DALQ2___DALLE___________', 'MESH____DALT3___DALLE___________'] + fids=[-11, 5, -8, 1, -10, -12, 4, -9, 2, -14, 6, -19, 7, -17, 8, -20, 9, -15, 10, -18, 11, -21, 12, -16, 13, -13, 3, 0, -4, -5, -6, -7, -3, -2, -1] + grpns=['A1', 'A1A2', 'A2', 'A2A4', 'A3', 'A3A1', 'A3C5', 'A4', 'A4A3', 'AP1', 'AP2', 'AP3', 'AP4', 'APPS', 'B1', 'B1C1', 'B2', 'B2B4', 'B3', 'B3B1', 'B4', 'B4C3', 'C1', 'C1C4', 'C2', 'C2B2', 'C3', 'C3C2', 'C4', 'C4B3', 'C5', 'C5A4', 'DALLE', 'DALQ1', 'DALQ2', 'DALT3', 'MESH', 'PMMA'] + famIdsPerGrp=[[5],[-11],[1],[-8],[4],[-10],[-12],[2],[-9],[-4],[-5],[-6],[-7],[-4,-5,-6,-7],[6],[-14],[7],[-19],[8],[-17],[9],[-20],[10],[-15],[11],[-18],[12],[-21],[13],[-16],[3],[-13],[-3,-2,-1],[-3],[-2],[-1],[-4,-5,-6,-7,-3,-2,-1],[3]] + return m2,m1,m0,f2,f1,f0,p,n2,n1,n0,fns,fids,grpns,famIdsPerGrp + + def buildMLMeshUnPolyze(cls,tester): + """Level 0 (meshDim=3) - 2 TETRA4 + 3 PENTA6 + 2 POLYH + # POLYH #0 becomes 1 TETRA4 + # POLYH #1 becomes HEXA8 + # Level -1 (meshDim=2) - 2 TRI3 + 3 QUAD4 + 4 POLYG + # POLYG #2 becomes TRI3""" + meshName="NightmareMesh" + # + coords=DataArrayDouble.New(38,3) ; coords.rearrange(1) ; coords.iota(1000.) ; coords.rearrange(3) ; coords.setInfoOnComponents(["X [m]","Y [m]","Z [m]"]) + mesh0=MEDCouplingUMesh(meshName,3) + type0=[NORM_TETRA4,NORM_TETRA4, NORM_PENTA6,NORM_PENTA6,NORM_PENTA6, NORM_POLYHED,NORM_POLYHED] + conn0=[[0,1,2,3],[4,5,6,7], [8,9,10,11,12,13],[14,15,16,17,18,19],[20,21,22,23,24,25], [26,27,28,-1,26,29,27,-1,27,29,28,-1,28,29,26],[30,31,32,33,-1,34,37,36,35,-1,30,34,35,31,-1,31,35,36,32,-1,32,36,37,33,-1,33,37,34,30]] + mesh0.allocateCells(len(type0)) + for typ,nodalConn in zip(type0,conn0): + mesh0.insertNextCell(typ,nodalConn); + pass + mesh0.finishInsertingCells() + mesh0.setCoords(coords) + + meshM1=MEDCouplingUMesh(meshName,2) + typeM1=[NORM_TRI3,NORM_TRI3, NORM_QUAD4,NORM_QUAD4,NORM_QUAD4, NORM_POLYGON,NORM_POLYGON,NORM_POLYGON,NORM_POLYGON] + connM1=[[0,1,2],[3,4,5], [6,7,8,9],[10,11,12,13],[14,15,16,17], [18,19,20,21,22],[23,24,25,26,27],[28,29,30],[31,32,33,34,35,36,37]] + meshM1.allocateCells(len(typeM1)) + for typ,nodalConn in zip(typeM1,connM1): + meshM1.insertNextCell(typ,nodalConn); + pass + meshM1.finishInsertingCells() + meshM1.setCoords(coords) + # + mm=MEDFileUMesh.New() + mm.setMeshAtLevel(0,mesh0) + mm.setMeshAtLevel(-1,meshM1) + grp0_L0=DataArrayInt.New([0,1,5,7]) ; grp0_L0.setName("grp0_L0") + grp1_L0=DataArrayInt.New([1,2,3,4,6]) ; grp1_L0.setName("grp1_L0") + tester.assertRaises(InterpKernelException,mm.setGroupsAtLevel,0,[grp0_L0,grp1_L0])# presence of 7 in grp0_L0 (only 7 cells at level 0) -> throw + grp0_L0=DataArrayInt.New([0,1,5,6]) ; grp0_L0.setName("grp0_L0") + mm.setGroupsAtLevel(0,[grp0_L0,grp1_L0]) + grp0_LM1=DataArrayInt.New([1,2,3,4,7]) ; grp0_LM1.setName("grp0_LM1") + grp1_LM1=DataArrayInt.New([2,3,4,5]) ; grp1_LM1.setName("grp1_LM1") + grp2_LM1=DataArrayInt.New([5,6,7,8]) ; grp2_LM1.setName("grp2_LM1") + mm.setGroupsAtLevel(-1,[grp0_LM1,grp1_LM1,grp2_LM1]) + grp0_Node=DataArrayInt.New([0,11,15,16]) ; grp0_Node.setName("grp0_Node") + grp1_Node=DataArrayInt.New([1,2,13,14,16]) ; grp1_Node.setName("grp1_Node") + mm.setGroupsAtLevel(1,[grp0_Node,grp1_Node]) + # + tester.assertRaises(InterpKernelException,mm.setRenumFieldArr,0,DataArrayInt.New([0,8,9,4,5,6,7,10]))# to big array + mm.setRenumFieldArr(0,DataArrayInt.New([0,8,9,4,5,6,7])) + da=DataArrayInt.New([0,8,9,4,5,6,7,11,12]) + mm.setRenumFieldArr(-1,da) + mm.setRenumFieldArr(-1,None) + mm.setRenumFieldArr(-1,da) + da=DataArrayInt.New(mm.getNumberOfNodes()+1) ; da.iota(8) ; tester.assertRaises(InterpKernelException,mm.setRenumFieldArr,1,da) # to big array more than number of nodes + da=DataArrayInt.New(mm.getNumberOfNodes()) ; da.iota(8) ; mm.setRenumFieldArr(1,da) + return mm + + def buildVecFieldOnCells_1(cls): + mesh=MEDLoaderDataForTest.build3DSurfMesh_1(); + nbOfCells=mesh.getNumberOfCells(); + f1=MEDCouplingFieldDouble.New(ON_CELLS,ONE_TIME); + f1.setName("VectorFieldOnCells"); + f1.setMesh(mesh); + array=DataArrayDouble.New(); + arr1=[0.,10.,20.,1.,11.,21.,2.,12.,22.,3.,13.,23.,4.,14.,24.,5.,15.,25.] + array.setValues(arr1,nbOfCells,3); + array.setInfoOnComponent(0,"power [MW/m^3]"); + array.setInfoOnComponent(1,"density [g/cm^3]"); + array.setInfoOnComponent(2,"temperature [K]"); + f1.setArray(array); + tmp=array.getPointer(); + f1.setTime(2.,0,1); + f1.checkCoherency(); + return f1; + + def buildVecFieldOnNodes_1(cls): + mesh=MEDLoaderDataForTest.build3DSurfMesh_1(); + nbOfNodes=mesh.getNumberOfNodes(); + f1=MEDCouplingFieldDouble.New(ON_NODES,ONE_TIME); + f1.setName("VectorFieldOnNodes"); + f1.setMesh(mesh); + array=DataArrayDouble.New(); + f1.setArray(array); + arr1=[70.,80.,90.,71.,81.,91.,72.,82.,92.,73.,83.,93.,74.,84.,94.,75.,85.,95., + 1000.,10010.,10020.,1001.,10011.,10021.,1002.,10012.,10022.,1003.,10013.,10023.,1004.,10014.,10024.,1005.,10015.,10025.] + array.setValues(arr1,nbOfNodes,3); + array.setInfoOnComponent(0,"power [MW/m^3]"); + array.setInfoOnComponent(1,"density [g/cm^3]"); + array.setInfoOnComponent(2,"temperature [K]"); + f1.setTime(2.12,2,3); + f1.checkCoherency(); + return f1; + + def buildVecFieldOnGauss_1(cls): + _a=0.446948490915965; + _b=0.091576213509771; + _p1=0.11169079483905; + _p2=0.0549758718227661; + refCoo1=[ 0.,0., 1.,0., 0.,1. ] + gsCoo1=[ 2*_b-1, 1-4*_b, 2*_b-1, 2.07*_b-1, 1-4*_b, + 2*_b-1, 1-4*_a, 2*_a-1, 2*_a-1, 1-4*_a, 2*_a-1, 2*_a-1 ]; + wg1=[ 4*_p2, 4*_p2, 4*_p2, 4*_p1, 4*_p1, 4*_p1 ] + _refCoo1=refCoo1; + _gsCoo1=gsCoo1; + _wg1=wg1; + m=MEDLoaderDataForTest.build2DMesh_2(); + f=MEDCouplingFieldDouble.New(ON_GAUSS_PT,ONE_TIME); + f.setTime(3.14,1,5); + f.setMesh(m); + f.setGaussLocalizationOnType(NORM_TRI3,_refCoo1,_gsCoo1,_wg1); + refCoo2=[-1.0,1.0, -1.0,-1.0, 1.0,-1.0, -1.0,0.0, 0.0,-1.0, 0.0,0.0 ] + _refCoo2=refCoo2; + _gsCoo1=_gsCoo1[0:6]; + _gsCoo2=_gsCoo1 + _wg1=_wg1[0:3]; + _wg2=_wg1 + refCoo3=[ 0.,0., 1.,0., 1.,1., 0.,1. ] + _refCoo3=refCoo3; + _gsCoo1=_gsCoo1[0:4]; + _wg1=_wg1[0:2]; + f.setGaussLocalizationOnType(NORM_QUAD4,_refCoo3,_gsCoo1,_wg1); + f.setGaussLocalizationOnType(NORM_TRI6,_refCoo2,_gsCoo2,_wg2); + array=DataArrayDouble.New(); + array.alloc(19,2); + ptr=array.getPointer(); + for i in xrange(19*2): + array.setIJ(0,i,float(i+7)); + pass + f.setArray(array); + f.setName("MyFirstFieldOnGaussPoint"); + array.setInfoOnComponent(0,"power [MW/m^3]"); + array.setInfoOnComponent(1,"density"); + f.checkCoherency(); + return f; + + def buildVecFieldOnGauss_2(cls): + _a=0.446948490915965; + _b=0.091576213509771; + _p1=0.11169079483905; + _p2=0.0549758718227661; + refCoo1=[ 0.,0., 1.,0., 0.,1. ] + gsCoo1=[ 2*_b-1, 1-4*_b, 2*_b-1, 2.07*_b-1, 1-4*_b, + 2*_b-1, 1-4*_a, 2*_a-1, 2*_a-1, 1-4*_a, 2*_a-1, 2*_a-1 ]; + wg1=[ 4*_p2, 4*_p2, 4*_p2, 4*_p1, 4*_p1, 4*_p1 ] + _refCoo1=refCoo1; + _gsCoo1=gsCoo1; + _wg1=wg1; + m=MEDLoaderDataForTest.build2DMesh_3(); + f=MEDCouplingFieldDouble.New(ON_GAUSS_PT,ONE_TIME); + f.setTime(3.14,1,5); + f.setMesh(m); + di=DataArrayInt.New(); di.setValues([0,2,3],3,1) + f.setGaussLocalizationOnCells(di,_refCoo1,_gsCoo1,_wg1) + _wg1[-1]*=2 + f.setGaussLocalizationOnCells([1,5],_refCoo1,_gsCoo1,_wg1); + _wg1[-1]*=2 + f.setGaussLocalizationOnCells([4],_refCoo1,_gsCoo1,_wg1); + refCoo2=[-1.0,1.0, -1.0,-1.0, 1.0,-1.0, -1.0,0.0, 0.0,-1.0, 0.0,0.0 ] + _refCoo2=refCoo2; + _gsCoo1=_gsCoo1[0:6]; + _gsCoo2=_gsCoo1 + _wg1=_wg1[0:3]; + _wg2=_wg1 + refCoo3=[ 0.,0., 1.,0., 1.,1., 0.,1. ] + _refCoo3=refCoo3; + _gsCoo1=_gsCoo1[0:4]; + _wg1=_wg1[0:2]; + f.setGaussLocalizationOnCells([6,7,8],_refCoo3,_gsCoo1,_wg1); + _wg1[-1]*=2 + f.setGaussLocalizationOnCells([9],_refCoo3,_gsCoo1,_wg1); + f.setGaussLocalizationOnType(NORM_TRI6,_refCoo2,_gsCoo2,_wg2); + array=DataArrayDouble.New(); + array.alloc(53,2); + ptr=array.getPointer(); + for i in xrange(53*2): + array.setIJ(0,i,float(i+7)); + pass + f.setArray(array); + f.setName("MyFirstFieldOnGaussPoint"); + array.setInfoOnComponent(0,"power [MW/m^3]"); + array.setInfoOnComponent(1,"density"); + f.checkCoherency(); + return f; + + # idem buildVecFieldOnGauss_2 except that different discretizations are sorted inside one type + def buildVecFieldOnGauss_2_Simpler(cls): + _a=0.446948490915965; + _b=0.091576213509771; + _p1=0.11169079483905; + _p2=0.0549758718227661; + refCoo1=[ 0.,0., 1.,0., 0.,1. ] + gsCoo1=[ 2*_b-1, 1-4*_b, 2*_b-1, 2.07*_b-1, 1-4*_b, + 2*_b-1, 1-4*_a, 2*_a-1, 2*_a-1, 1-4*_a, 2*_a-1, 2*_a-1 ]; + wg1=[ 4*_p2, 4*_p2, 4*_p2, 4*_p1, 4*_p1, 4*_p1 ] + _refCoo1=refCoo1; + _gsCoo1=gsCoo1; + _wg1=wg1; + m=MEDLoaderDataForTest.build2DMesh_3(); + f=MEDCouplingFieldDouble.New(ON_GAUSS_PT,ONE_TIME); + f.setTime(3.14,1,5); + f.setMesh(m); + di=DataArrayInt.New(); di.setValues([0,1,2],3,1) + f.setGaussLocalizationOnCells(di,_refCoo1,_gsCoo1,_wg1) + _wg1[-1]*=2 + f.setGaussLocalizationOnCells([3,4],_refCoo1,_gsCoo1,_wg1); + _wg1[-1]*=2 + f.setGaussLocalizationOnCells([5],_refCoo1,_gsCoo1,_wg1); + refCoo2=[-1.0,1.0, -1.0,-1.0, 1.0,-1.0, -1.0,0.0, 0.0,-1.0, 0.0,0.0 ] + _refCoo2=refCoo2; + _gsCoo1=_gsCoo1[0:6]; + _gsCoo2=_gsCoo1 + _wg1=_wg1[0:3]; + _wg2=_wg1 + refCoo3=[ 0.,0., 1.,0., 1.,1., 0.,1. ] + _refCoo3=refCoo3; + _gsCoo1=_gsCoo1[0:4]; + _wg1=_wg1[0:2]; + f.setGaussLocalizationOnCells([6,7,8],_refCoo3,_gsCoo1,_wg1); + _wg1[-1]*=2 + f.setGaussLocalizationOnCells([9],_refCoo3,_gsCoo1,_wg1); + f.setGaussLocalizationOnType(NORM_TRI6,_refCoo2,_gsCoo2,_wg2); + array=DataArrayDouble.New(); + array.alloc(53,2); + ptr=array.getPointer(); + for i in xrange(53*2): + array.setIJ(0,i,float(i+7)); + pass + f.setArray(array); + f.setName("MyFirstFieldOnGaussPoint"); + array.setInfoOnComponent(0,"power [MW/m^3]"); + array.setInfoOnComponent(1,"density"); + f.checkCoherency(); + return f; + + def buildVecFieldOnGaussNE_1(cls): + m=MEDLoaderDataForTest.build2DMesh_2(); + f=MEDCouplingFieldDouble.New(ON_GAUSS_NE,ONE_TIME); + f.setTime(3.14,1,5); + f.setMesh(m); + array=DataArrayDouble.New(); + array.alloc(20,2); + for i in xrange(2*20): + array.setIJ(0,i,float(i+8)); + f.setArray(array); + array.setInfoOnComponent(0,"power [W]"); + array.setInfoOnComponent(1,"temperature"); + f.setName("MyFieldOnGaussNE"); + f.checkCoherency(); + return f; + + def buildACompleteMEDDataStructureWithFieldsOnCells_1(cls): + coo=DataArrayDouble([0,0,1,0,2,0,0,1,1,1,2,1,0,2,1,2,2,2],9,2) + m0=MEDCouplingUMesh("mesh",2) + m0.setCoords(coo) + m0.allocateCells() + m0.insertNextCell(NORM_TRI3,[1,4,2]) + m0.insertNextCell(NORM_TRI3,[4,5,2]) + m0.insertNextCell(NORM_QUAD4,[0,3,4,1]) + m0.insertNextCell(NORM_QUAD4,[6,7,4,3]) + m0.insertNextCell(NORM_QUAD4,[7,8,5,4]) + m1=m0.computeSkin() + mm=MEDFileUMesh() + #2 levels + mm.setMeshAtLevel(0,m0) ; mm.setMeshAtLevel(-1,m1) + #some grps/families on the 2 levels + grp0=DataArrayInt([0,2,4]); grp0.setName("gr0_0_2_4") + grp1=DataArrayInt([1,2,3,4]); grp1.setName("gr0_1_2_3_4") + grp2=DataArrayInt([0,4]); grp2.setName("gr0_0_4") + mm.setGroupsAtLevel(0,[grp0,grp1,grp2]) + grp3=DataArrayInt([0,1]); grp3.setName("grM1_SegOnTri3") + grp4=DataArrayInt([2,3,4,5,6,7]); grp4.setName("grM1_SegOnQuad4") + grp5=DataArrayInt([0,3]); grp5.setName("grM1_bottom") + mm.setGroupsAtLevel(-1,[grp3,grp4,grp5]) + ms=MEDFileMeshes() + ms.pushMesh(mm) + # 3 fields + fs=MEDFileFields() + # 1st Field - fNoProfile - no profile on levels 0 + f1Name="fNoProfile" + timeStepsF1=[(0,-1,0.01),(1,-1,0.02)] + f1=MEDFileFieldMultiTS() + for i,(it,order,tim) in enumerate(timeStepsF1): + f11Tmp=MEDCouplingFieldDouble(ON_CELLS,ONE_TIME) + f11Tmp.setTime(tim,it,order) + f11Tmp.setMesh(m0) + arr=DataArrayDouble(m0.getNumberOfCells(),1) ; arr.iota() ; arr+=1+i ; arr*=0.1 + f11Tmp.setArray(arr) + f11Tmp.checkCoherency() + f11Tmp.setName(f1Name) + f1.appendFieldNoProfileSBT(f11Tmp) + pass + fs.pushField(f1) + # 2nd Field - fNoProfileMultiLevs - no profile on levels 0 and -1 + f2Name="fNoProfileMultiLevs" + timeStepsF2=[(0,-1,0.),(1,-1,0.1),(2,-1,0.2)] + f2=MEDFileFieldMultiTS() + for i,(it,order,tim) in enumerate(timeStepsF2): + f21Tmp=MEDCouplingFieldDouble(ON_CELLS,ONE_TIME) + f21Tmp.setTime(tim,it,order) + f21Tmp.setMesh(m0) + arr=DataArrayDouble(m0.getNumberOfCells(),1) ; arr.iota() ; arr+=1+i + f21Tmp.setArray(arr) + f21Tmp.checkCoherency() + f21Tmp.setName(f2Name) + f2.appendFieldNoProfileSBT(f21Tmp) + f22Tmp=MEDCouplingFieldDouble(ON_CELLS,ONE_TIME) + f22Tmp.setTime(tim,it,order) + f22Tmp.setMesh(m1) + arr=DataArrayDouble(m1.getNumberOfCells(),1) ; arr.iota() ; arr+=100+1+i + f22Tmp.setArray(arr) + f22Tmp.checkCoherency() + f22Tmp.setName(f2Name) + f2[it,order].setFieldNoProfileSBT(f22Tmp) + pass + fs.pushField(f2) + # 3rd field - fProfileMultiLevs - The most complex one + f3Name="fProfileMultiLevs" + timeStepsF3=[(0,-1,0.),(1,-1,10.),(2,-1,20.),(3,-1,30.),] + f3=MEDFileFieldMultiTS() + for i,(it,order,tim) in enumerate(timeStepsF3): + pfl1=DataArrayInt([0,1,3,4]) ; pfl1.setName("pfl1") + m0Part=m0[pfl1] + f31Tmp=MEDCouplingFieldDouble(ON_CELLS,ONE_TIME) + f31Tmp.setTime(tim,it,order) + f31Tmp.setMesh(m0Part) + arr=DataArrayDouble(m0Part.getNumberOfCells(),1) ; arr.iota() ; arr+=1000+i+1 + f31Tmp.setArray(arr) + f31Tmp.checkCoherency() + f31Tmp.setName(f3Name) + f3.appendFieldProfile(f31Tmp,mm,0,pfl1) + pfl2=DataArrayInt([0,3]) ; pfl2.setName("pfl2Bottom") + m1Part=m1[pfl2] + f32Tmp=MEDCouplingFieldDouble(ON_CELLS,ONE_TIME) + f32Tmp.setTime(tim,it,order) + f32Tmp.setMesh(m1Part) + arr=DataArrayDouble(m1Part.getNumberOfCells(),1) ; arr.iota() ; arr+=2000+1+i + f32Tmp.setArray(arr) + f32Tmp.checkCoherency() + f32Tmp.setName(f3Name) + f3[it,order].setFieldProfile(f32Tmp,mm,-1,pfl2) + pass + fs.pushField(f3) + # + data=MEDFileData() ; data.setMeshes(ms) ; data.setFields(fs) + return data + + def buildAMEDFileDataWithGroupOnOneFamilyForSauv(self): + # Coordinates + coords = [0.,0., 0.,1., 1.,1., 1.,0.] + # lvl 0 connectivity + conn2D = [1,2,3,4] + # lvl -1 connectivity + conn1D = [0,1, 1,2, 2,3, 4,1] + # lvl 0 mesh + mesh2D=MEDCouplingUMesh.New() + mesh2D.setMeshDimension(2) + mesh2D.allocateCells(1) + mesh2D.insertNextCell(NORM_QUAD4,4,conn2D) + mesh2D.finishInsertingCells() + # lvl -1 mesh + mesh1D=MEDCouplingUMesh.New() + mesh1D.setMeshDimension(1) + mesh1D.allocateCells(4) + mesh1D.insertNextCell(NORM_SEG2,2,conn1D[0:2]) + mesh1D.insertNextCell(NORM_SEG2,2,conn1D[2:4]) + mesh1D.insertNextCell(NORM_SEG2,2,conn1D[4:6]) + mesh1D.insertNextCell(NORM_SEG2,2,conn1D[6:8]) + mesh1D.finishInsertingCells() + # assigning coordinates + meshCoords=DataArrayDouble.New() + meshCoords.setValues(coords, 4, 2) + mesh2D.setCoords(meshCoords) + mesh1D.setCoords(meshCoords) + # Creating a multi level mesh + mm = MEDFileUMesh.New() + mm.setMeshAtLevel(0, mesh2D) + mm.setMeshAtLevel(-1, mesh1D) + mm.setName("carre") + # Creating groups + # Creating a group with an element on level -1 + grp0_LM1 = DataArrayInt.New([0]) + grp0_LM1.setName("grp0_LM1") + # Creating a group with all elements on level -1 + grp1_LM1 = DataArrayInt.New([0,1,2,3]) + grp1_LM1.setName("grp1_LM1") + # + mm.setGroupsAtLevel(-1,[grp0_LM1,grp1_LM1]) + # + ms=MEDFileMeshes.New() + ms.setMeshAtPos(0,mm) + mfd=MEDFileData.New() + mfd.setMeshes(ms) + # + return mfd + + build1DMesh_1=classmethod(build1DMesh_1) + build2DCurveMesh_1=classmethod(build2DCurveMesh_1) + build2DMesh_1=classmethod(build2DMesh_1) + build2DMesh_2=classmethod(build2DMesh_2) + build2DMesh_3=classmethod(build2DMesh_3) + build3DMesh_1=classmethod(build3DMesh_1) + build3DSurfMesh_1=classmethod(build3DSurfMesh_1) + build3DMesh_2=classmethod(build3DMesh_2) + buildMLMeshUnPolyze=classmethod(buildMLMeshUnPolyze) + buildMultiLevelMesh_1=classmethod(buildMultiLevelMesh_1) + buildVecFieldOnCells_1=classmethod(buildVecFieldOnCells_1) + buildVecFieldOnNodes_1=classmethod(buildVecFieldOnNodes_1) + buildVecFieldOnGauss_1=classmethod(buildVecFieldOnGauss_1) + buildVecFieldOnGauss_2=classmethod(buildVecFieldOnGauss_2) + buildVecFieldOnGauss_2_Simpler=classmethod(buildVecFieldOnGauss_2_Simpler) + buildVecFieldOnGaussNE_1=classmethod(buildVecFieldOnGaussNE_1) + buildACompleteMEDDataStructureWithFieldsOnCells_1=classmethod(buildACompleteMEDDataStructureWithFieldsOnCells_1) + buildAMEDFileDataWithGroupOnOneFamilyForSauv=classmethod(buildAMEDFileDataWithGroupOnOneFamilyForSauv) + pass diff --git a/src/medtool/src/MEDLoader/Swig/MEDLoaderExamplesTest.py b/src/medtool/src/MEDLoader/Swig/MEDLoaderExamplesTest.py new file mode 100644 index 000000000..d7b6aa4cb --- /dev/null +++ b/src/medtool/src/MEDLoader/Swig/MEDLoaderExamplesTest.py @@ -0,0 +1,252 @@ +# -*- coding: iso-8859-1 -*- +# Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 +# 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) + +from MEDLoader import * +import unittest +import os + +class MEDLoaderBasicsTest(unittest.TestCase): + def testExampleReadFieldOnAllEntity1(self): + from MEDLoaderDataForTest import MEDLoaderDataForTest +#! [PySnippetReadFieldOnAllEntity1_1] + fname="PyExamples1.med" + meshName="mesh" + fieldName="FieldOnAll" + iteration=3 + order=4 +#! [PySnippetReadFieldOnAllEntity1_1] +#! [PySnippetWriteFieldOnAllEntity1_2] + m=MEDLoaderDataForTest.build2DMesh_3() + m=m[:10] + m.setName(meshName) + f=m.getMeasureField(ON_CELLS) + f=f.buildNewTimeReprFromThis(ONE_TIME,False) + f.setTime(5.5,iteration,order) + f.setName(fieldName) + # MEDCoupling finished, MEDLoader advanced API specific part starting from here + mm=MEDFileUMesh.New() + mm.setMeshAtLevel(0,m) + ff=MEDFileField1TS.New() + ff.setFieldNoProfileSBT(f) + mm.write(fname,2) + ff.write(fname,0) +#! [PySnippetWriteFieldOnAllEntity1_2] +#! [PySnippetReadFieldOnAllEntity1_3] + medfileField1TS=MEDFileField1TS.New(fname,fieldName,iteration,order) + mm=MEDFileMesh.New(fname) + fread=medfileField1TS.getFieldOnMeshAtLevel(ON_CELLS,0,mm) + fread2=medfileField1TS.getFieldAtLevel(ON_CELLS,0) + self.assertTrue(fread.isEqual(f,1e-12,1e-12)) + self.assertTrue(fread2.isEqual(f,1e-12,1e-12)) +#! [PySnippetReadFieldOnAllEntity1_3] +#! [PySnippetReadFieldOnAllEntity1_4] + medfileFieldMTS=MEDFileFieldMultiTS.New(fname,fieldName) + mm=MEDFileMesh.New(fname) + fread=medfileFieldMTS.getFieldOnMeshAtLevel(ON_CELLS,iteration,order,0,mm) + fread2=medfileFieldMTS.getFieldAtLevel(ON_CELLS,iteration,order,0) + self.assertTrue(fread.isEqual(f,1e-12,1e-12)) + self.assertTrue(fread2.isEqual(f,1e-12,1e-12)) +#! [PySnippetReadFieldOnAllEntity1_4] +#! [PySnippetReadFieldOnAllEntity1_5] + medfileFieldMTS=MEDFileFieldMultiTS.New(fname,fieldName) + for medfileField1TS in medfileFieldMTS: + if medfileField1TS.getTime()[:2]==[iteration,order]: + fread=medfileField1TS.getFieldOnMeshAtLevel(ON_CELLS,0,mm) + fread2=medfileField1TS.getFieldAtLevel(ON_CELLS,0) + self.assertTrue(fread.isEqual(f,1e-12,1e-12)) + self.assertTrue(fread2.isEqual(f,1e-12,1e-12)) + pass + pass +#! [PySnippetReadFieldOnAllEntity1_5] + pass + + def testExampleReadFieldPartial1(self): + from MEDLoaderDataForTest import MEDLoaderDataForTest +#! [PySnippetReadFieldPartial1_1] + fname="PyExamples2.med" + meshName="mesh" + fieldName="FieldPartial" + iteration=3 + order=4 +#! [PySnippetReadFieldPartial1_1] +#! [PySnippetWriteFieldPartial1_2] + m=MEDLoaderDataForTest.build2DMesh_1() + m.sortCellsInMEDFileFrmt() + m.setName(meshName) + # end of generation of a mesh -> let's create a field on that mesh + f=m.getMeasureField(ON_CELLS) + f=f.buildNewTimeReprFromThis(ONE_TIME,False) + f.setTime(5.5,iteration,order) + f.setName(fieldName) + # The MEDCoupling part is finished -> let's perform advanced API + mm=MEDFileUMesh.New() + mm.setMeshAtLevel(0,m) # the MED file data structure is ready for writing. Of course mm could have been more complicated with groups, families, multilevel + # Let's building a sub field + pfl=DataArrayInt.New([1,3,4,5]) + pfl.setName("myPfl") # here it is necessary to give a name to be compliant with MED file + f=f[pfl] ; f.getMesh().setName(m.getName()) # of course f should be in coherence with pfl -> f[pfl] + # + ff=MEDFileField1TS.New() + tmp=f.getMesh() # useless line, only to show that mesh into f is not considered by MEDFileField1TS.setFieldProfile + f.setMesh(None) # useless line, only to show that mesh into f is not considered by MEDFileField1TS.setFieldProfile + ff.setFieldProfile(f,mm,0,pfl) + f.setMesh(tmp) # useless line, only to show that mesh into f is not considered by MEDFileField1TS.setFieldProfile + mm.write(fname,2) + ff.write(fname,0) +#! [PySnippetWriteFieldPartial1_2] +#! [PySnippetReadFieldPartial1_3] + mm=MEDFileMesh.New(fname) + medfileField1TS=MEDFileField1TS.New(fname,fieldName,iteration,order) + fread=medfileField1TS.getFieldOnMeshAtLevel(ON_CELLS,0,mm) + fread2=medfileField1TS.getFieldAtLevel(ON_CELLS,0) + self.assertTrue(fread.isEqual(f,1e-12,1e-12)) + self.assertTrue(fread2.isEqual(f,1e-12,1e-12)) +#! [PySnippetReadFieldPartial1_3] +#! [PySnippetReadFieldPartial1_4] + medfileField1TS=MEDFileField1TS.New(fname,fieldName,iteration,order) + mm=MEDFileMesh.New(fname) + valsRead,pflRead=medfileField1TS.getFieldWithProfile(ON_CELLS,0,mm) + self.assertEqual(valsRead.getName(),f.getName()) + valsRead.setName("") + self.assertTrue(valsRead.isEqual(f.getArray(),1e-12)) + pflRead.setName(pfl.getName()) + self.assertTrue(pflRead.isEqual(pfl)) +#! [PySnippetReadFieldPartial1_4] +#! [PySnippetReadFieldPartial1_5] + firstApproachMesh=fread.getMesh() + mm=MEDFileMesh.New(fname) + wholeMesh=mm.getMeshAtLevel(0) + wholeMesh.tryToShareSameCoords(firstApproachMesh,1e-12) + isIncluded,pflComputed=wholeMesh.areCellsIncludedIn(firstApproachMesh,2) + self.assertTrue(isIncluded) + self.assertEqual(pflComputed.getName(),mm.getName()) + pflComputed.setName(pflRead.getName()) + self.assertTrue(pflComputed.isEqual(pflRead)) +#! [PySnippetReadFieldPartial1_5] +#! [PySnippetReadFieldPartial1_6] + mm=MEDFileMesh.New(fname) + wholeMesh=mm.getMeshAtLevel(0) + computedMesh=wholeMesh[pflRead] ; computedMesh.setName(mm.getName()) + self.assertTrue(computedMesh.isEqual(fread.getMesh(),1e-12)) + fieldFromSecondApproach=MEDCouplingFieldDouble.New(ON_CELLS,ONE_TIME) + fieldFromSecondApproach.setName(medfileField1TS.getName()) + fieldFromSecondApproach.setMesh(computedMesh) + fieldFromSecondApproach.setArray(valsRead) + fieldFromSecondApproach.setTime(medfileField1TS.getTime()[2],medfileField1TS.getTime()[0],medfileField1TS.getTime()[1]) + self.assertTrue(fieldFromSecondApproach.isEqual(fread,1e-12,1e-12)) +#! [PySnippetReadFieldPartial1_6] + pass + + def testExampleMeshAdvAPI1(self): + da=DataArrayDouble.New([0.,1.1,2.3,3.6]) + meshName="Example2" + cmesh=MEDCouplingCMesh.New() ; cmesh.setCoords(da,da,da) + myMesh=cmesh.buildUnstructured() +#! [PySnippetMeshAdvAPI1_1] + self.assertTrue(isinstance(myMesh,MEDCouplingUMesh)) + myMesh.setName(meshName) + MEDLoader.WriteUMesh("wFile1.med",myMesh,True) +#! [PySnippetMeshAdvAPI1_1] + os.remove("wFile1.med") +#! [PySnippetMeshAdvAPI1_2] + self.assertTrue(isinstance(myMesh,MEDCouplingUMesh)) + myMesh.setName(meshName) + MEDLoader.WriteUMesh("wFile1.med",myMesh,False) +#! [PySnippetMeshAdvAPI1_2] + f=myMesh.getMeasureField(ON_CELLS) + f=f.buildNewTimeReprFromThis(ONE_TIME,False) + f.setName("myField") +#! [PySnippetMeshAdvAPI1_3] + MEDLoader.WriteUMesh("file3.med",f.getMesh(),True) + f.setTime(1.2,1,0) + fileNameMultiTimeStep="file3.med" + MEDLoader.WriteFieldUsingAlreadyWrittenMesh(fileNameMultiTimeStep,f) + f.setTime(1.3,2,0) + f.applyFunc("sqrt(x)"); + #Writing second time step with iteration==2 and order==0 + MEDLoader.WriteFieldUsingAlreadyWrittenMesh("file3.med",f); +#! [PySnippetMeshAdvAPI1_3] +#! [PySnippetMeshAdvAPI1_11] + timeStepsIds=MEDLoader.GetCellFieldIterations("file3.med","Example2","myField") + self.assertEqual([(1, 0),(2, 0)],timeStepsIds) + fs=MEDLoader.ReadFieldsOnSameMesh(ON_CELLS,"file3.med","Example2",0,"myField",timeStepsIds); +#! [PySnippetMeshAdvAPI1_11] + ### + myMesh0=myMesh[:] ; myMesh0.setName("Example2") + myMesh1=myMesh0.buildDescendingConnectivity()[0] ; myMesh1.setName(myMesh0.getName()) + myMesh2=myMesh1.buildDescendingConnectivity()[0] ; myMesh2.setName(myMesh0.getName()) + myMesh3=myMesh2.buildDescendingConnectivity()[0] ; myMesh3.setName(myMesh0.getName()) + mm=MEDFileUMesh.New() + mm.setMeshAtLevel(0,myMesh0) + mm.setMeshAtLevel(-1,myMesh1) + mm.setMeshAtLevel(-2,myMesh2) + mm.setMeshAtLevel(-3,myMesh3) + mm.write("file2.med",2) + F1Cell=MEDCouplingFieldDouble.New(ON_CELLS,ONE_TIME) + F1Cell.setMesh(myMesh0) + F1Cell.setArray(myMesh0.getCoords()[:myMesh0.getNumberOfCells()]) + F1Cell.setTime(1000.,2,3) + F1Cell.setName("F1Cell") + MEDLoader.WriteFieldUsingAlreadyWrittenMesh("file2.med",F1Cell) + F1Cell1=F1Cell.deepCpy() + F1Cell1.setMesh(myMesh1) + F1Cell1.setArray(myMesh1.getBarycenterAndOwner()) + MEDLoader.WriteFieldUsingAlreadyWrittenMesh("file2.med",F1Cell1) +#! [PySnippetMeshAdvAPI1_12] + f1Cell_3D=MEDLoader.ReadFieldCell("file2.med","Example2",0,"F1Cell",2,3) +#! [PySnippetMeshAdvAPI1_12] +#! [PySnippetMeshAdvAPI1_13] + f1Cell_2D=MEDLoader.ReadFieldCell("file2.med","Example2",-1,"F1Cell",2,3) +#! [PySnippetMeshAdvAPI1_13] + self.assertTrue(F1Cell.isEqual(f1Cell_3D,1e-12,1e-12)) +#! [PySnippetMeshAdvAPI1_8] + self.assertEqual(3,MEDLoader.ReadUMeshDimFromFile("file2.med","Example2")) +#! [PySnippetMeshAdvAPI1_8] +#! [PySnippetMeshAdvAPI1_7] + m2D=MEDLoader.ReadUMeshFromFile("file2.med","Example2",0) +#! [PySnippetMeshAdvAPI1_7] +#! [PySnippetMeshAdvAPI1_4] + m2D=MEDLoader.ReadUMeshFromFile("file2.med","Example2",-1) +#! [PySnippetMeshAdvAPI1_4] +#! [PySnippetMeshAdvAPI1_5] + m1D=MEDLoader.ReadUMeshFromFile("file2.med","Example2",-2) +#! [PySnippetMeshAdvAPI1_5] +#! [PySnippetMeshAdvAPI1_6] + m0D=MEDLoader.ReadUMeshFromFile("file2.med","Example2",-3) +#! [PySnippetMeshAdvAPI1_6] + for i in xrange(4): + mm.removeMeshAtLevel(-i) + pass + mm.setMeshAtLevel(0,myMesh1) + mm.setMeshAtLevel(-1,myMesh2) + mm.setName("MyMesh") + mm.write("file1.med",2) +#! [PySnippetMeshAdvAPI1_9] + m2D=MEDLoader.ReadUMeshFromFile("file1.med","MyMesh",0) +#! [PySnippetMeshAdvAPI1_9] +#! [PySnippetMeshAdvAPI1_10] + m1D=MEDLoader.ReadUMeshFromFile("file1.med","MyMesh",-1) +#! [PySnippetMeshAdvAPI1_10] + pass + + pass + +unittest.main() diff --git a/src/medtool/src/MEDLoader/Swig/MEDLoaderSplitter.py b/src/medtool/src/MEDLoader/Swig/MEDLoaderSplitter.py new file mode 100644 index 000000000..41e766794 --- /dev/null +++ b/src/medtool/src/MEDLoader/Swig/MEDLoaderSplitter.py @@ -0,0 +1,115 @@ +# -*- coding: iso-8859-1 -*- +# Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 +# 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/DM2S/STMF/LGLS) + +from MEDLoader import * +import os + +class MEDLoaderSplitter: + @classmethod + def New(cls,mfd,idsLst): + """ mfd is a MEDFileData instance containing only one mesh. idsLst is a list of DataArrayInt containing each the ids per processor """ + return MEDLoaderSplitter(fileName) + pass + + def __init__(self,mfd,idsLst): + """ mfd is a MEDFileData instance containing only one mesh. idsLst is a list of DataArrayInt containing each the ids per processor """ + mfmsh=mfd.getMeshes() + mfflds=mfd.getFields() + if len(mfmsh)!=1: + raise InterpKernelException("Works only with one mesh !") + mfflds=mfflds.partOfThisLyingOnSpecifiedMeshName(mfmsh[0].getName()) + retf=self.__splitFields(mfmsh[0],mfflds,idsLst) + retm=self.__splitMesh(mfmsh[0],idsLst) + self._mfd_splitted=[MEDFileData() for i in xrange(len(idsLst))] + for a,b,c in zip(self._mfd_splitted,retf,retm): + a.setFields(b) ; a.setMeshes(c) + pass + pass + + def getSplittedInstances(self): + return self._mfd_splitted + + @classmethod + def __splitMEDFileField1TSNode(cls,f,f1ts,ids): + fRet=f[ids] + f1ts.setFieldNoProfileSBT(fRet) + pass + + @classmethod + def __splitMEDFileField1TSCell(cls,f,f1ts,ids): + fRet=f[ids] + m=fRet.getMesh() ; m.zipCoords() + o2n=m.getRenumArrForMEDFileFrmt() ; fRet.renumberCells(o2n,False) + f1ts.setFieldNoProfileSBT(fRet) + pass + + def __splitMEDFileField1TS(self,mm,f1ts,idsLst): + ret=[MEDFileField1TS() for i in xrange(len(idsLst))] + dico={ON_CELLS:self.__splitMEDFileField1TSCell, + ON_NODES:self.__splitMEDFileField1TSNode, + ON_GAUSS_PT:self.__splitMEDFileField1TSCell, + ON_GAUSS_NE:self.__splitMEDFileField1TSCell} + for t in f1ts.getTypesOfFieldAvailable(): + f=f1ts.getFieldOnMeshAtLevel(t,0,mm) + for i,f0 in enumerate(ret): + dico[t](f,f0,idsLst[i]) + pass + pass + return ret + + def __splitFields(self,mm,mfflds,idsLst): + ret0=[MEDFileFields() for i in xrange(len(idsLst))] + for fmts in mfflds: + if len(fmts.getPflsReallyUsed())!=0: + print "Field \"%s\" contains profiles ! Not supported yet ! This field will be ignored !"%(fmts.getName()) + continue + pass + ret1=[MEDFileFieldMultiTS() for i in xrange(len(idsLst))] + for f1ts in fmts: + for fmtsPart,f1tsPart in zip(ret1,self.__splitMEDFileField1TS(mm,f1ts,idsLst)): + fmtsPart.pushBackTimeStep(f1tsPart) + pass + pass + for fieldsPart,fmtsPart in zip(ret0,ret1): + fieldsPart.pushField(fmtsPart); + pass + pass + return ret0 + + def __splitMesh(self,mfm,idsLst): + ret0=[MEDFileMeshes() for i in xrange(len(idsLst))] + m=mfm.getMeshAtLevel(0) + for ret,ids in zip(ret0,idsLst): + mlPart=mfm.createNewEmpty() + mPart=m[ids] ; trad=mPart.zipCoordsTraducer() + trad=trad.invertArrayO2N2N2O(mPart.getNumberOfNodes()) + mlPart.setMeshAtLevel(0,mPart) + if 0 in mfm.getFamArrNonEmptyLevelsExt(): + mlPart.setFamilyFieldArr(0,mfm.getFamilyFieldAtLevel(0)[ids]) + pass + if 1 in mfm.getFamArrNonEmptyLevelsExt(): + mlPart.setFamilyFieldArr(1,mfm.getFamilyFieldAtLevel(1)[trad]) + pass + mlPart.copyFamGrpMapsFrom(mfm) + ret.pushMesh(mlPart) + pass + return ret0 + pass diff --git a/src/medtool/src/MEDLoader/Swig/MEDLoaderTest.py b/src/medtool/src/MEDLoader/Swig/MEDLoaderTest.py new file mode 100644 index 000000000..38ee4afa9 --- /dev/null +++ b/src/medtool/src/MEDLoader/Swig/MEDLoaderTest.py @@ -0,0 +1,756 @@ +# -*- coding: iso-8859-1 -*- +# Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 +# 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) + +import MEDLoader +import unittest +from math import pi,e,sqrt +from MEDLoaderDataForTest import MEDLoaderDataForTest + +class MEDLoaderTest(unittest.TestCase): + def testMesh1DRW(self): + mesh=MEDLoaderDataForTest.build1DMesh_1(); + mesh.checkCoherency(); + MEDLoader.MEDLoader.WriteUMesh("Pyfile1.med",mesh,True); + mesh_rw=MEDLoader.MEDLoader.ReadUMeshFromFile("Pyfile1.med",mesh.getName(),0); + self.assertTrue(mesh.isEqual(mesh_rw,1e-12)); + pass + + def testMesh2DCurveRW(self): + mesh=MEDLoaderDataForTest.build2DCurveMesh_1(); + mesh.checkCoherency(); + MEDLoader.MEDLoader.WriteUMesh("Pyfile2.med",mesh,True); + mesh_rw=MEDLoader.MEDLoader.ReadUMeshFromFile("Pyfile2.med",mesh.getName(),0); + self.assertTrue(mesh.isEqual(mesh_rw,1e-12)); + pass + + def testMesh2DRW(self): + mesh=MEDLoaderDataForTest.build2DMesh_1(); + mesh.checkCoherency(); + MEDLoader.MEDLoader.WriteUMesh("Pyfile3.med",mesh,True); + mesh_rw=MEDLoader.MEDLoader.ReadUMeshFromFile("Pyfile3.med",mesh.getName(),0); + self.assertTrue(mesh.isEqual(mesh_rw,1e-12)); + pass + + def testMesh3DSurfRW(self): + mesh=MEDLoaderDataForTest.build3DSurfMesh_1(); + mesh.checkCoherency(); + MEDLoader.MEDLoader.WriteUMesh("Pyfile4.med",mesh,True); + mesh_rw=MEDLoader.MEDLoader.ReadUMeshFromFile("Pyfile4.med",mesh.getName(),0); + self.assertTrue(mesh.isEqual(mesh_rw,1e-12)); + pass + + def testMesh3DRW(self): + mesh=MEDLoaderDataForTest.build3DMesh_1(); + mesh.checkCoherency(); + MEDLoader.MEDLoader.WriteUMesh("Pyfile5.med",mesh,True); + mesh_rw=MEDLoader.MEDLoader.ReadUMeshFromFile("Pyfile5.med",mesh.getName(),0); + self.assertTrue(mesh.isEqual(mesh_rw,1e-12)); + pass + + def testFieldRW1(self): + f1=MEDLoaderDataForTest.buildVecFieldOnCells_1(); + MEDLoader.MEDLoader.WriteField("Pyfile6.med",f1,True); + f2=MEDLoader.MEDLoader.ReadFieldCell("Pyfile6.med",f1.getMesh().getName(),0,f1.getName(),0,1); + self.assertTrue(f1.isEqual(f2,1e-12,1e-12)); + # + f1=MEDLoaderDataForTest.buildVecFieldOnNodes_1(); + MEDLoader.MEDLoader.WriteField("Pyfile7.med",f1,True); + f2=MEDLoader.MEDLoader.ReadFieldNode("Pyfile7.med",f1.getMesh().getName(),0,f1.getName(),2,3); + self.assertTrue(f1.isEqual(f2,1e-12,1e-12)); + self.assertRaises(Exception,MEDLoader.MEDLoader.ReadFieldCell,"Pyfile7.med",f1.getMesh().getName(),0,f1.getName(),2,3); + pass + + def testFieldRW2(self): + fileName="Pyfile8.med"; + VAL1=12345.67890314; + VAL2=-1111111111111.; + f1=MEDLoaderDataForTest.buildVecFieldOnCells_1(); + MEDLoader.MEDLoader.WriteField(fileName,f1,True); + f1.setTime(10.,8,9); + f1.getArray().setIJ(0,0,VAL1); + MEDLoader.MEDLoader.WriteFieldUsingAlreadyWrittenMesh(fileName,f1); + f1.setTime(10.14,18,19); + f1.getArray().setIJ(0,0,VAL2); + MEDLoader.MEDLoader.WriteFieldUsingAlreadyWrittenMesh(fileName,f1); + #retrieving time steps... + f2=MEDLoader.MEDLoader.ReadFieldCell(fileName,f1.getMesh().getName(),0,f1.getName(),8,9); + f1.setTime(10.,8,9); + f1.getArray().setIJ(0,0,VAL1); + self.assertTrue(f1.isEqual(f2,1e-12,1e-12)); + f2=MEDLoader.MEDLoader.ReadFieldCell(fileName,f1.getMesh().getName(),0,f1.getName(),0,1); + f3=MEDLoaderDataForTest.buildVecFieldOnCells_1(); + self.assertTrue(f3.isEqual(f2,1e-12,1e-12)); + f2=MEDLoader.MEDLoader.ReadFieldCell(fileName,f1.getMesh().getName(),0,f1.getName(),18,19); + f1.setTime(10.14,18,19); + f1.getArray().setIJ(0,0,VAL2); + self.assertTrue(f1.isEqual(f2,1e-12,1e-12)); + #test of throw on invalid (dt,it) + self.assertRaises(Exception,MEDLoader.MEDLoader.ReadFieldCell,fileName,f1.getMesh().getName(),0,f1.getName(),28,19); + #ON NODES + f1=MEDLoaderDataForTest.buildVecFieldOnNodes_1(); + fileName2="Pyfile9.med"; + MEDLoader.MEDLoader.WriteField(fileName2,f1,True); + f1.setTime(110.,108,109); + tmp=f1.getArray().getPointer(); + f1.getArray().setIJ(0,3,VAL1); + MEDLoader.MEDLoader.WriteFieldUsingAlreadyWrittenMesh(fileName2,f1); + f1.setTime(210.,208,209); + f1.getArray().setIJ(0,3,VAL2); + MEDLoader.MEDLoader.WriteFieldUsingAlreadyWrittenMesh(fileName2,f1); + f2=MEDLoader.MEDLoader.ReadFieldNode(fileName2,f1.getMesh().getName(),0,f1.getName(),108,109); + f1.setTime(110.,108,109); + f1.getArray().setIJ(0,3,VAL1); + self.assertTrue(f1.isEqual(f2,1e-12,1e-12)); + f2=MEDLoader.MEDLoader.ReadFieldNode(fileName2,f1.getMesh().getName(),0,f1.getName(),2,3); + f3=MEDLoaderDataForTest.buildVecFieldOnNodes_1(); + self.assertTrue(f3.isEqual(f2,1e-12,1e-12)); + f2=MEDLoader.MEDLoader.ReadFieldNode(fileName2,f1.getMesh().getName(),0,f1.getName(),208,209); + f1.setTime(210.,208,209); + f1.getArray().setIJ(0,3,VAL2); + self.assertTrue(f1.isEqual(f2,1e-12,1e-12)); + pass + + # + # Multi field in a same file, but this field has several + # + def testFieldRW3(self): + fileName="Pyfile11.med"; + VAL1=12345.67890314; + VAL2=-1111111111111.; + name1="AField"; + name3="AMesh1"; + f1=MEDLoaderDataForTest.buildVecFieldOnCells_1(); + f1.getMesh().setName(name3); + f1.setName(name1); + f1.setTime(10.,8,9); + tmp=f1.getArray().getPointer(); + f1.getArray().setIJ(0,0,VAL1); + MEDLoader.MEDLoader.WriteField(fileName,f1,True); + f1.setTime(10.14,18,19); + f1.getArray().setIJ(0,0,VAL2); + MEDLoader.MEDLoader.WriteFieldUsingAlreadyWrittenMesh(fileName,f1); + f1.getMesh().setName(name3); + f1.setTime(10.55,28,29); + f1.getArray().setIJ(0,0,3*VAL1); + MEDLoader.MEDLoader.WriteFieldUsingAlreadyWrittenMesh(fileName,f1); + vec=MEDLoader.MEDLoader.GetMeshNamesOnField(fileName,name1); + f1.setTime(10.66,38,39); + f1.getArray().setIJ(0,0,3*VAL2); + MEDLoader.MEDLoader.WriteFieldUsingAlreadyWrittenMesh(fileName,f1); + f1.setTime(10.77,48,49); + f1.getArray().setIJ(0,0,4*VAL2); + MEDLoader.MEDLoader.WriteFieldUsingAlreadyWrittenMesh(fileName,f1); + #ON NODES + f1=MEDLoaderDataForTest.buildVecFieldOnNodes_1(); + f1.setName(name1); + f1.getMesh().setName(name3); + f1.setTime(110.,8,9); + MEDLoader.MEDLoader.WriteFieldUsingAlreadyWrittenMesh(fileName,f1); + f1.setTime(110.,108,109); + tmp=f1.getArray().getPointer(); + f1.getArray().setIJ(0,3,VAL1); + MEDLoader.MEDLoader.WriteFieldUsingAlreadyWrittenMesh(fileName,f1); + f1.setTime(210.,208,209); + f1.getArray().setIJ(0,3,VAL2); + MEDLoader.MEDLoader.WriteFieldUsingAlreadyWrittenMesh(fileName,f1); + # + it1=MEDLoader.MEDLoader.GetCellFieldIterations(fileName,name3,name1); + self.assertEqual(5,len(it1)); + self.assertEqual(8,it1[0][0]); self.assertEqual(9,it1[0][1]); + self.assertEqual(18,it1[1][0]); self.assertEqual(19,it1[1][1]); + self.assertEqual(28,it1[2][0]); self.assertEqual(29,it1[2][1]); + self.assertEqual(38,it1[3][0]); self.assertEqual(39,it1[3][1]); + self.assertEqual(48,it1[4][0]); self.assertEqual(49,it1[4][1]); + it3=MEDLoader.MEDLoader.GetNodeFieldIterations(fileName,name3,name1); + self.assertEqual(3,len(it3)); + self.assertEqual(8,it3[0][0]); self.assertEqual(9,it3[0][1]); + self.assertEqual(108,it3[1][0]); self.assertEqual(109,it3[1][1]); + self.assertEqual(208,it3[2][0]); self.assertEqual(209,it3[2][1]); + # + # + f1=MEDLoader.MEDLoader.ReadFieldCell(fileName,name3,0,name1,8,9); + self.assertAlmostEqual(VAL1,f1.getArray().getIJ(0,0),13); + f1=MEDLoader.MEDLoader.ReadFieldCell(fileName,name3,0,name1,18,19); + self.assertAlmostEqual(VAL2,f1.getArray().getIJ(0,0),13); + f1=MEDLoader.MEDLoader.ReadFieldCell(fileName,name3,0,name1,28,29); + self.assertAlmostEqual(3*VAL1,f1.getArray().getIJ(0,0),13); + f1=MEDLoader.MEDLoader.ReadFieldCell(fileName,name3,0,name1,38,39); + self.assertAlmostEqual(3*VAL2,f1.getArray().getIJ(0,0),13); + f1=MEDLoader.MEDLoader.ReadFieldCell(fileName,name3,0,name1,48,49); + self.assertAlmostEqual(4*VAL2,f1.getArray().getIJ(0,0),13); + # + f1=MEDLoader.MEDLoader.ReadFieldNode(fileName,name3,0,name1,8,9); + self.assertAlmostEqual(71.,f1.getArray().getIJ(0,3),13); + f1=MEDLoader.MEDLoader.ReadFieldNode(fileName,name3,0,name1,108,109); + self.assertAlmostEqual(VAL1,f1.getArray().getIJ(0,3),13); + f1=MEDLoader.MEDLoader.ReadFieldNode(fileName,name3,0,name1,208,209); + self.assertAlmostEqual(VAL2,f1.getArray().getIJ(0,3),13); + pass + + def testMultiMeshRW1(self): + fileName="Pyfile10.med"; + mesh1=MEDLoaderDataForTest.build3DMesh_1(); + part1=[1,2,4,13,15] + mesh2=mesh1.buildPartOfMySelf(part1,True); + mesh2.setName("mesh2"); + part2=[3,4,13,14] + mesh3=mesh1.buildPartOfMySelf(part2,True); + mesh3.setName("mesh3"); + mesh4=MEDLoader.MEDCouplingUMesh.New(); + mesh4.setName("mesh4"); + mesh4.setMeshDimension(3); + mesh4.allocateCells(1); + conn=[0,11,1,3] + mesh4.insertNextCell(MEDLoader.NORM_TETRA4,4,conn[0:4]) + mesh4.finishInsertingCells(); + mesh4.setCoords(mesh1.getCoords()); + meshes=[mesh1,mesh2,mesh3,mesh4] + mnane="3DToto"; + MEDLoader.MEDLoader.WriteUMeshesPartition(fileName,mnane,meshes,True); + # + mesh5=MEDLoader.MEDLoader.ReadUMeshFromFile(fileName,mnane); + mesh1.setName(mnane); + part3=[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17] + mesh6=mesh5.buildPartOfMySelf(part3,True); + mesh6.setName(mnane); + self.assertTrue(mesh6.isEqual(mesh1,1e-12)); + grps=MEDLoader.MEDLoader.GetMeshGroupsNames(fileName,mnane); + self.assertEqual(4,len(grps)); + grps.index("mesh2"); + grps.index("mesh3"); + grps.index("mesh4"); + grps.index("3DMesh_1"); + # + vec=("mesh2",); + mesh2_2=MEDLoader.MEDLoader.ReadUMeshFromGroups(fileName,mnane,0,vec); + self.assertTrue(mesh2_2.isEqual(mesh2,1e-12)); + vec=["mesh3"]; + mesh3_2=MEDLoader.MEDLoader.ReadUMeshFromGroups(fileName,mnane,0,vec); + self.assertTrue(mesh3_2.isEqual(mesh3,1e-12)); + vec=["mesh4"]; + mesh4_2=MEDLoader.MEDLoader.ReadUMeshFromGroups(fileName,mnane,0,vec); + self.assertTrue(mesh4_2.isEqual(mesh4,1e-12)); + vec="3DMesh_1"; + mesh1_2=MEDLoader.MEDLoader.ReadUMeshFromGroups(fileName,mnane,0,vec); + mesh1.setName("3DMesh_1"); + self.assertTrue(mesh1_2.isEqual(mesh1,1e-12)); + # + vec=["Family_-3","Family_-5"]; + mesh2_2=MEDLoader.MEDLoader.ReadUMeshFromFamilies(fileName,mnane,0,vec); + mesh2_2.setName("mesh2"); + self.assertTrue(mesh2_2.isEqual(mesh2,1e-12)); + # + ret=MEDLoader.MEDLoader.GetMeshFamiliesNamesOnGroup(fileName,"3DToto","3DMesh_1"); + self.assertEqual(4,len(ret)); + self.assertEqual(ret[0],"Family_-2"); + self.assertEqual(ret[1],"Family_-3"); + self.assertEqual(ret[2],"Family_-4"); + self.assertEqual(ret[3],"Family_-5"); + # + ret1=MEDLoader.MEDLoader.GetMeshGroupsNamesOnFamily(fileName,"3DToto","Family_-3"); + self.assertEqual(2,len(ret1)); + self.assertEqual(ret1[0],"3DMesh_1"); + self.assertEqual(ret1[1],"mesh2"); + pass + + def testFieldProfilRW1(self): + fileName="Pyfile12.med"; + mesh1=MEDLoaderDataForTest.build3DMesh_1(); + da,b,newNbOfNodes=mesh1.mergeNodes(1e-12); + MEDLoader.MEDLoader.WriteUMesh(fileName,mesh1,True); + part1=[1,2,4,13,15] + mesh2=mesh1.buildPartOfMySelf(part1,True); + mesh2.setName(mesh1.getName());#<- important for the test + # + nbOfCells=mesh2.getNumberOfCells(); + self.assertEqual(5,nbOfCells); + f1=MEDLoader.MEDCouplingFieldDouble.New(MEDLoader.ON_CELLS,MEDLoader.ONE_TIME); + f1.setName("VectorFieldOnCells"); + f1.setMesh(mesh2); + array=MEDLoader.DataArrayDouble.New(); + array.alloc(nbOfCells,2); + f1.setArray(array); + arr1=[71.,171.,10.,110.,20.,120.,30.,130.,40.,140.] + array.setValues(arr1,nbOfCells,2); + f1.setTime(3.14,2,7); + f1.checkCoherency(); + # + MEDLoader.MEDLoader.WriteField(fileName,f1,False);#<- False important for the test + # + f2=MEDLoader.MEDLoader.ReadFieldCell(fileName,f1.getMesh().getName(),0,f1.getName(),2,7); + tt=MEDLoader.MEDLoader.GetTypesOfField(fileName,f1.getMesh().getName(),f1.getName()); + self.assertEqual(tt,[MEDLoader.ON_CELLS]); + f2.checkCoherency(); + self.assertTrue(f1.isEqual(f2,1e-12,1e-12)); + # + pass + + def testFieldGaussRW1(self): + fileName="Pyfile13.med"; + f1=MEDLoaderDataForTest.buildVecFieldOnGauss_1(); + MEDLoader.MEDLoader.WriteField(fileName,f1,True); + f2=MEDLoader.MEDLoader.ReadField(MEDLoader.ON_GAUSS_PT,fileName,f1.getMesh().getName(),0,f1.getName(),1,5); + self.assertTrue(f1.isEqual(f2,1e-12,1e-12)); + pass + + def testFieldGaussNERW1(self): + fileName="Pyfile14.med"; + f1=MEDLoaderDataForTest.buildVecFieldOnGaussNE_1(); + MEDLoader.MEDLoader.WriteField(fileName,f1,True); + self.assertEqual([MEDLoader.ON_GAUSS_NE],MEDLoader.MEDLoader.GetTypesOfField(fileName,'2DMesh_2','MyFieldOnGaussNE')) #Bug 22/5/2014 + f2=MEDLoader.MEDLoader.ReadField(MEDLoader.ON_GAUSS_NE,fileName,f1.getMesh().getName(),0,f1.getName(),1,5); + self.assertTrue(f1.isEqual(f2,1e-12,1e-12)); + pass + + def testMesh3DSurfShuffleRW(self): + fileName="Pyfile15.med"; + mesh=MEDLoaderDataForTest.build3DSurfMesh_1(); + renumber1=[2,5,1,0,3,4] + mesh.renumberCells(renumber1,False); + mesh.checkCoherency(); + MEDLoader.MEDLoader.WriteUMesh(fileName,mesh,True); + mesh_rw=MEDLoader.MEDLoader.ReadUMeshFromFile(fileName,mesh.getName(),0); + self.assertTrue(mesh.isEqual(mesh_rw,1e-12)); + pass + + def testMultiFieldShuffleRW1(self): + fileName="Pyfile17.med"; + m=MEDLoaderDataForTest.build3DMesh_2(); + self.assertEqual(20,m.getNumberOfCells()); + self.assertEqual(45,m.getNumberOfNodes()); + polys=[1,4,6] + m.convertToPolyTypes(polys); + renum=[1,3,2,8,9,12,13,16,19,0,4,7,5,15,14,17,10,18,6,11] + m.renumberCells(renum,False); + m.orientCorrectlyPolyhedrons(); + # Writing + MEDLoader.MEDLoader.WriteUMesh(fileName,m,True); + f1Tmp=m.getMeasureField(False); + f1=f1Tmp.buildNewTimeReprFromThis(MEDLoader.ONE_TIME,False); + f1.setTime(0.,1,2); + f_1=f1.cloneWithMesh(True); + MEDLoader.MEDLoader.WriteFieldUsingAlreadyWrittenMesh(fileName,f1); + f1.applyFunc("2*x"); + f1.setTime(0.01,3,4); + f_2=f1.cloneWithMesh(True); + MEDLoader.MEDLoader.WriteFieldUsingAlreadyWrittenMesh(fileName,f1); + f1.applyFunc("2*x/3"); + f1.setTime(0.02,5,6); + f_3=f1.cloneWithMesh(True); + MEDLoader.MEDLoader.WriteFieldUsingAlreadyWrittenMesh(fileName,f1); + # Reading + its=[(1,2),(3,4),(5,6)]; + fs=MEDLoader.MEDLoader.ReadFieldsOnSameMesh(MEDLoader.ON_CELLS,fileName,f_1.getMesh().getName(),0,f_1.getName(),its); + self.assertEqual(3,len(fs)); + self.assertTrue(fs[0].isEqual(f_1,1e-12,1e-12)); + self.assertTrue(fs[1].isEqual(f_2,1e-12,1e-12)); + self.assertTrue(fs[2].isEqual(f_3,1e-12,1e-12)); + pass + + def testWriteUMeshesRW1(self): + fileName="Pyfile18.med"; + m3d=MEDLoaderDataForTest.build3DMesh_2(); + pt=[0.,0.,-0.3] + vec=[0.,0.,1.] + nodes=m3d.findNodesOnPlane(pt,vec,1e-12); + m2d=m3d.buildFacePartOfMySelfNode(nodes,True); + renumber=[1,2,0,4,3] + m2d.renumberCells(renumber,False); + m2d.setName("ExampleOfMultiDimW"); + meshes=[m2d,m3d] + MEDLoader.MEDLoader.WriteUMeshes(fileName,meshes,True); + m3d_bis=MEDLoader.MEDLoader.ReadUMeshFromFile(fileName,m2d.getName(),0); + self.assertTrue(not m3d_bis.isEqual(m3d,1e-12)); + m3d_bis.setName(m3d.getName()); + self.assertTrue(m3d_bis.isEqual(m3d,1e-12)); + m2d_bis=MEDLoader.MEDLoader.ReadUMeshFromFile(fileName,m2d.getName(),-1);#-1 for faces + self.assertTrue(m2d_bis.isEqual(m2d,1e-12)); + # Creation of a field on faces. + f1=MEDLoader.MEDCouplingFieldDouble.New(MEDLoader.ON_CELLS,MEDLoader.ONE_TIME); + f1.setName("FieldOnFacesShuffle"); + f1.setMesh(m2d); + array=MEDLoader.DataArrayDouble.New(); + arr1=[71.,171.,10.,110.,20.,120.,30.,130.,40.,140.] + array.setValues(arr1,m2d.getNumberOfCells(),2); + array.setInfoOnComponent(0,"plkj [mm]"); + array.setInfoOnComponent(1,"pqqqss [mm]"); + f1.setArray(array); + tmp=array.setValues(arr1,m2d.getNumberOfCells(),2); + f1.setTime(3.14,2,7); + f1.checkCoherency(); + MEDLoader.MEDLoader.WriteFieldUsingAlreadyWrittenMesh(fileName,f1); + f2=MEDLoader.MEDLoader.ReadFieldCell(fileName,f1.getMesh().getName(),-1,f1.getName(),2,7); + self.assertTrue(f2.isEqual(f1,1e-12,1e-12)); + pass + + def testFieldNodeProfilRW1(self): + fileName="Pyfile19.med"; + fileName2="Pyfile20.med"; + m=MEDLoaderDataForTest.build2DMesh_1(); + nbOfNodes=m.getNumberOfNodes(); + MEDLoader.MEDLoader.WriteUMesh(fileName,m,True); + f1=MEDLoader.MEDCouplingFieldDouble.New(MEDLoader.ON_NODES,MEDLoader.ONE_TIME); + f1.setName("VFieldOnNodes"); + f1.setMesh(m); + array=MEDLoader.DataArrayDouble.New(); + arr1=[1.,101.,2.,102.,3.,103.,4.,104.,5.,105.,6.,106.,7.,107.,8.,108.,9.,109.,10.,110.,11.,111.,12.,112.] + array.setValues(arr1,nbOfNodes,2); + f1.setArray(array); + array.setInfoOnComponent(0,"tyty [mm]"); + array.setInfoOnComponent(1,"uiop [MW]"); + f1.setTime(3.14,2,7); + f1.checkCoherency(); + arr2=[1,4] + f2=f1.buildSubPart(arr2); + f2.getMesh().setName(f1.getMesh().getName()); + MEDLoader.MEDLoader.WriteField(fileName,f2,False);#<- False important for the test + # + f3=MEDLoader.MEDLoader.ReadFieldNode(fileName,f2.getMesh().getName(),0,f2.getName(),2,7); + f3.checkCoherency(); + self.assertTrue(f3.isEqual(f2,1e-12,1e-12)); + # + arr3=[1,3,0,5,2,4] + f2.renumberNodes(arr3); + MEDLoader.MEDLoader.WriteUMesh(fileName2,m,True); + MEDLoader.MEDLoader.WriteField(fileName2,f2,False);#<- False important for the test + f3=MEDLoader.MEDLoader.ReadFieldNode(fileName2,f2.getMesh().getName(),0,f2.getName(),2,7); + f3.checkCoherency(); + self.assertTrue(f3.isEqual(f2,1e-12,1e-12)); + # + pass + + def testFieldNodeProfilRW2(self): + fileName="Pyfile23.med"; + mesh=MEDLoaderDataForTest.build3DSurfMesh_1(); + MEDLoader.MEDLoader.WriteUMesh(fileName,mesh,True); + # + f1=MEDLoader.MEDCouplingFieldDouble.New(MEDLoader.ON_NODES,MEDLoader.ONE_TIME); + f1.setName("FieldMix"); + f1.setMesh(mesh); + arr2=[1071.,1171.,1010.,1110.,1020.,1120.,1030.,1130.,1040.,1140.,1050.,1150., + 1060.,1160.,1070.,1170.,1080.,1180.,1090.,1190.,1091.,1191.,1092.,1192.]; + array=MEDLoader.DataArrayDouble.New(); + array.setValues(arr2,12,2); + f1.setArray(array); + array.setInfoOnComponent(0,"plkj [mm]"); + array.setInfoOnComponent(1,"pqqqss [mm]"); + tmp=array.getPointer(); + f1.setTime(3.17,2,7); + # + renumArr=[3,7,2,1,5,11,10,0,9,6,8,4] + f1.renumberNodes(renumArr); + f1.checkCoherency(); + MEDLoader.MEDLoader.WriteField(fileName,f1,False);#<- False important for the test + f2=MEDLoader.MEDLoader.ReadFieldNode(fileName,f1.getMesh().getName(),0,f1.getName(),2,7); + self.assertTrue(f2.isEqual(f1,1e-12,1e-12)); + # + pass + + def testMixCellAndNodesFieldRW1(self): + fileName="Pyfile21.med"; + mesh=MEDLoaderDataForTest.build3DSurfMesh_1(); + f1=MEDLoader.MEDCouplingFieldDouble.New(MEDLoader.ON_CELLS,MEDLoader.ONE_TIME); + f1.setName("FieldMix"); + f1.setMesh(mesh); + array=MEDLoader.DataArrayDouble.New(); + f1.setArray(array); + arr1=[71.,171.,10.,110.,20.,120.,30.,130.,40.,140.,50.,150.] + array.setValues(arr1,6,2); + array.setInfoOnComponent(0,"plkj [mm]"); + array.setInfoOnComponent(1,"pqqqss [mm]"); + f1.setTime(3.14,2,7); + f1.checkCoherency(); + # + f2=MEDLoader.MEDCouplingFieldDouble.New(MEDLoader.ON_NODES,MEDLoader.ONE_TIME); + f2.setName("FieldMix"); + f2.setMesh(mesh); + array=MEDLoader.DataArrayDouble.New(); + f2.setArray(array); + arr2=[1071.,1171.,1010.,1110.,1020.,1120.,1030.,1130.,1040.,1140.,1050.,1150., + 1060.,1160.,1070.,1170.,1080.,1180.,1090.,1190.,1091.,1191.,1092.,1192.] + array.setValues(arr2,12,2) + array.setInfoOnComponent(0,"plkj [mm]"); + array.setInfoOnComponent(1,"pqqqss [mm]"); + f2.setTime(3.14,2,7); + f2.checkCoherency(); + # + MEDLoader.MEDLoader.WriteField(fileName,f1,True); + ts=MEDLoader.MEDLoader.GetTypesOfField(fileName,f1.getMesh().getName(),f1.getName()); + self.assertEqual(1,len(ts)); + self.assertEqual(MEDLoader.ON_CELLS,ts[0]); + fs=MEDLoader.MEDLoader.GetAllFieldNamesOnMesh(fileName,f1.getMesh().getName()); + self.assertEqual(1,len(fs)); + self.assertTrue(fs[0]=="FieldMix"); + MEDLoader.MEDLoader.WriteFieldUsingAlreadyWrittenMesh(fileName,f2); + fs=MEDLoader.MEDLoader.GetAllFieldNamesOnMesh(fileName,f1.getMesh().getName()); + self.assertEqual(1,len(fs)); + self.assertTrue(fs[0]=="FieldMix"); + # + ts=MEDLoader.MEDLoader.GetTypesOfField(fileName,f1.getMesh().getName(),f1.getName()); + self.assertEqual(2,len(ts)); + self.assertEqual(MEDLoader.ON_NODES,ts[0]); + self.assertEqual(MEDLoader.ON_CELLS,ts[1]); + # + f3=MEDLoader.MEDLoader.ReadFieldNode(fileName,f1.getMesh().getName(),0,f1.getName(),2,7); + self.assertTrue(f3.isEqual(f2,1e-12,1e-12)); + f3=MEDLoader.MEDLoader.ReadFieldCell(fileName,f1.getMesh().getName(),0,f1.getName(),2,7); + self.assertTrue(f3.isEqual(f1,1e-12,1e-12)); + # + pass + + def testGetAllFieldNamesRW1(self): + fileName="Pyfile22.med"; + mesh=MEDLoaderDataForTest.build2DMesh_2(); + f1=MEDLoader.MEDCouplingFieldDouble.New(MEDLoader.ON_NODES,MEDLoader.ONE_TIME); + f1.setName("Field1"); + f1.setTime(3.44,5,6); + f1.setMesh(mesh); + f1.fillFromAnalytic(2,"x+y"); + MEDLoader.MEDLoader.WriteField(fileName,f1,True); + f1.setTime(1002.3,7,8); + f1.fillFromAnalytic(2,"x+77.*y"); + MEDLoader.MEDLoader.WriteFieldUsingAlreadyWrittenMesh(fileName,f1); + f1.setName("Field2"); + MEDLoader.MEDLoader.WriteField(fileName,f1,False); + f1.setName("Field3"); + mesh.setName("2DMesh_2Bis"); + MEDLoader.MEDLoader.WriteField(fileName,f1,False); + f1=MEDLoader.MEDCouplingFieldDouble.New(MEDLoader.ON_CELLS,MEDLoader.ONE_TIME); + f1.setName("Field8"); + f1.setTime(8.99,7,9); + f1.setMesh(mesh); + f1.fillFromAnalytic(3,"3*x+y"); + MEDLoader.MEDLoader.WriteField(fileName,f1,False); + fs=MEDLoader.MEDLoader.GetAllFieldNames(fileName); + self.assertEqual(4,len(fs)); + self.assertTrue(fs[0]=="Field1"); + self.assertTrue(fs[1]=="Field2"); + self.assertTrue(fs[2]=="Field3"); + self.assertTrue(fs[3]=="Field8"); + pass + + def testBigNbOfCompoNonReg(self): + fileName="Pyfile57.med" + m=MEDLoader.MEDCouplingCMesh() ; m.setCoords(MEDLoader.DataArrayDouble([0,1,2,3]),MEDLoader.DataArrayDouble([0,1]),MEDLoader.DataArrayDouble([0,1])) + m=m.buildUnstructured() ; m.setName("TinyMesh") + f=MEDLoader.MEDCouplingFieldDouble(MEDLoader.ON_CELLS) ; f.setMesh(m) + nbOfCompo=4100 + arr=MEDLoader.DataArrayDouble(nbOfCompo*3) ; arr.iota() + arr.rearrange(nbOfCompo) + arr.setInfoOnComponents(["c%i"%(i) for i in xrange(nbOfCompo)]) + f.setArray(arr) + f.setName("FieldBigCompo") + MEDLoader.MEDLoader.WriteField(fileName,f,True) + f2=MEDLoader.MEDLoader.ReadFieldCell(fileName,m.getName(),0,f.getName(),-1,-1) + self.assertTrue(f.isEqual(f2,1e-12,1e-12)) + pass + + def testMultiMeshTypeWrite0(self): + fname="Pyfile73.med" + m=MEDLoader.MEDCoupling1SGTUMesh("mesh",MEDLoader.NORM_QUAD4) ; m.allocateCells() + m.insertNextCell([0,2,1,3]) + m.setCoords(MEDLoader.DataArrayDouble([0.,0.,1.,1.,1.,0.,0.,1.],4,2)) + # + ms=[m.deepCpy() for i in xrange(4)] + for i,elt in enumerate(ms): + elt.translate([float(i)*1.5,0.]) + pass + # + m0=MEDLoader.MEDCoupling1SGTUMesh.Merge1SGTUMeshes(ms) + f=m0.getMeasureField(False) ; f.getArray().setInfoOnComponents(["ABC [defg]"]) + MEDLoader.MEDLoader.WriteField(fname,f,True) + # + fRead=MEDLoader.MEDLoader.ReadFieldCell(fname,"merge",0,f.getName(),-1,-1) + fRead.setMesh(MEDLoader.MEDCoupling1SGTUMesh(fRead.getMesh())) + self.assertTrue(f.isEqual(fRead,1e-12,1e-12)) + # + m0=m0.buildUnstructured() ; m0.convertAllToPoly() + m0=MEDLoader.MEDCoupling1DGTUMesh(m0) + f=m0.getMeasureField(False) ; f.getArray().setInfoOnComponents(["ABC [defg]"]) + MEDLoader.MEDLoader.WriteField(fname,f,True) + # + fRead=MEDLoader.MEDLoader.ReadFieldCell(fname,"merge",0,f.getName(),-1,-1) + fRead.setMesh(MEDLoader.MEDCoupling1DGTUMesh(fRead.getMesh())) + self.assertTrue(f.isEqual(fRead,1e-12,1e-12)) + # + m0=MEDLoader.MEDCouplingCMesh() + arr=MEDLoader.DataArrayDouble(4) ; arr.iota() + m0.setCoords(arr,arr) + m0.setName("mesh") + f=m0.getMeasureField(False) ; f.getArray().setInfoOnComponents(["ABC [defg]"]) + MEDLoader.MEDLoader.WriteField(fname,f,True) + # + fRead=MEDLoader.MEDLoader.ReadFieldCell(fname,"mesh",0,f.getName(),-1,-1) + self.assertTrue(f.isEqual(fRead,1e-12,1e-12)) + # + c=m0.buildUnstructured().getCoords() + m0=MEDLoader.MEDCouplingCurveLinearMesh("mesh") + m0.setNodeGridStructure([4,4]) + m0.setCoords(c) + f=m0.getMeasureField(False) ; f.getArray().setInfoOnComponents(["ABC [defg]"]) + MEDLoader.MEDLoader.WriteField(fname,f,True) + # + fRead=MEDLoader.MEDLoader.ReadFieldCell(fname,"mesh",0,f.getName(),-1,-1) + self.assertTrue(f.isEqual(fRead,1e-12,1e-12)) + pass + + def testMultiMeshTypeWrite1(self): + fname="Pyfile74.med" + m=MEDLoader.MEDCoupling1SGTUMesh("mesh",MEDLoader.NORM_QUAD4) ; m.allocateCells() + m.insertNextCell([0,2,1,3]) + m.setCoords(MEDLoader.DataArrayDouble([0.,0.,1.,1.,1.,0.,0.,1.],4,2)) + # + ms=[m.deepCpy() for i in xrange(4)] + for i,elt in enumerate(ms): + elt.translate([float(i)*1.5,0.]) + pass + m0=MEDLoader.MEDCoupling1SGTUMesh.Merge1SGTUMeshes(ms) + MEDLoader.MEDLoader.WriteMesh(fname,m0,True) + # + mRead=MEDLoader.MEDLoader.ReadMeshFromFile(fname,"merge",0) + self.assertTrue(isinstance(mRead,MEDLoader.MEDCouplingUMesh)) + mRead=MEDLoader.MEDCoupling1SGTUMesh(mRead) + self.assertTrue(m0.isEqual(mRead,1e-12)) + # + m0=m0.buildUnstructured() ; m0.convertAllToPoly() + m0=MEDLoader.MEDCoupling1DGTUMesh(m0) + MEDLoader.MEDLoader.WriteMesh(fname,m0,True) + # + mRead=MEDLoader.MEDLoader.ReadMeshFromFile(fname,"merge",0) + mRead=MEDLoader.MEDCoupling1DGTUMesh(mRead) + self.assertTrue(m0.isEqual(mRead,1e-12)) + # + m0=MEDLoader.MEDCouplingCMesh() + arr=MEDLoader.DataArrayDouble(4) ; arr.iota() + m0.setCoords(arr,arr) + m0.setName("mesh") + MEDLoader.MEDLoader.WriteMesh(fname,m0,True) + # + mRead=MEDLoader.MEDLoader.ReadMeshFromFile(fname,0) + self.assertTrue(isinstance(mRead,MEDLoader.MEDCouplingCMesh)) + self.assertTrue(m0.isEqual(mRead,1e-12)) + # + c=m0.buildUnstructured().getCoords() + m0=MEDLoader.MEDCouplingCurveLinearMesh("mesh") + m0.setNodeGridStructure([4,4]) + m0.setCoords(c) + MEDLoader.MEDLoader.WriteMesh(fname,m0,True) + # + mRead=MEDLoader.MEDLoader.ReadMeshFromFile(fname,0) + self.assertTrue(isinstance(mRead,MEDLoader.MEDCouplingCurveLinearMesh)) + self.assertTrue(m0.isEqual(mRead,1e-12)) + pass + + def testChangeGroupName(self): + """ This test is a non regression test on MEDFileUMesh.changeGroupName thanks to Alliance. + """ + mfd=MEDLoaderDataForTest.buildAMEDFileDataWithGroupOnOneFamilyForSauv() + mesh = mfd.getMeshes().getMeshAtPos(0) + mesh.changeGroupName("grp0_LM1", "xonall1") + self.assertTrue("xonall1" in mesh.getGroupsNames()) + pass + + def testFieldWithTooLongName(self): + """ This test is a non regression test, to check that in basic API the policies are taken into account. + """ + fname="Pyfile75.med" + # Coordinates + coords = [0.,0., 0.,1., 1.,1., 1.,0.] + # lvl 0 connectivity + conn2D = [1,2,3,4] + # lvl 0 mesh + m=MEDLoader.MEDCouplingUMesh.New("mesh",2) + m.allocateCells(1) + m.insertNextCell(MEDLoader.NORM_QUAD4,4,conn2D) + m.finishInsertingCells() + # assigning coordinates + meshCoords=MEDLoader.DataArrayDouble.New() + meshCoords.setValues(coords, 4, 2) + m.setCoords(meshCoords) + # + f=MEDLoader.MEDCouplingFieldDouble.New(MEDLoader.ON_CELLS,MEDLoader.ONE_TIME) + f.setMesh(m) + d=MEDLoader.DataArrayDouble.New() + d.alloc(1,1) + d.iota(1.) + # seting a long name + d.setInfoOnComponent(0,"CONCENTRATION of I129") + f.setArray(d) + f.setName("field") + # + mm=MEDLoader.MEDFileUMesh() + MEDLoader.MEDLoader.SetTooLongStrPolicy(2) + MEDLoader.MEDLoader.AssignStaticWritePropertiesTo(mm) + self.assertEqual(2,mm.getTooLongStrPolicy()) + MEDLoader.MEDLoader.SetTooLongStrPolicy(0) + MEDLoader.MEDLoader.AssignStaticWritePropertiesTo(mm) + self.assertEqual(0,mm.getTooLongStrPolicy()) + del mm + # + MEDLoader.MEDLoader.SetTooLongStrPolicy(2) + self.assertRaises(MEDLoader.InterpKernelException,MEDLoader.MEDLoader.WriteField,fname,f,True)# the component name is too long + policy 2 -> throw + f.getArray().setInfoOnComponent(0,'I129') + MEDLoader.MEDLoader.WriteField(fname,f,True) + pass + + def testUsingAlreadyWrittenMesh2(self): + """ This test focuses on MEDLoader.WriteFieldUsingAlreadyWrittenMesh with mesh different from UMesh. + """ + fname="Pyfile76.med" + mesh=MEDLoader.MEDCouplingCMesh("mesh") + arrX=MEDLoader.DataArrayDouble([0,1,2,3]) + arrY=MEDLoader.DataArrayDouble([0,2,3,5,7]) + arrZ=MEDLoader.DataArrayDouble([7]) + mesh.setCoords(arrX,arrY,arrZ) + # + f1=MEDLoader.MEDCouplingFieldDouble(MEDLoader.ON_NODES) ; f1.setName("f1") + f1.setMesh(mesh) + arr=MEDLoader.DataArrayDouble(20) ; arr.iota() + f1.setArray(arr) + f1.checkCoherency() + # + f2=MEDLoader.MEDCouplingFieldDouble(MEDLoader.ON_NODES) ; f2.setName("f2") + f2.setMesh(mesh) + arr=MEDLoader.DataArrayDouble(20) ; arr.iota() ; arr*=3 + f2.setArray(arr) + f2.checkCoherency() + # + f11=f1.deepCpy() ; (f11.getArray())[:]*=4 ; f11.setTime(1.1,5,6) + # + MEDLoader.MEDLoader.WriteMesh(fname,f1.getMesh(),True) + MEDLoader.MEDLoader.WriteFieldUsingAlreadyWrittenMesh(fname,f1) + MEDLoader.MEDLoader.WriteFieldUsingAlreadyWrittenMesh(fname,f2) + MEDLoader.MEDLoader.WriteFieldUsingAlreadyWrittenMesh(fname,f11) + ## + f1r=MEDLoader.MEDLoader.ReadFieldNode(fname,"mesh",0,"f1",-1,-1); + self.assertTrue(f1.isEqual(f1r,1e-12,1e-12)) + self.assertTrue(f1r.getArray().isEqual(MEDLoader.DataArrayDouble([0.,1.,2.,3.,4.,5.,6.,7.,8.,9.,10.,11.,12.,13.,14.,15.,16.,17.,18.,19.]),1e-12)) + f2r=MEDLoader.MEDLoader.ReadFieldNode(fname,"mesh",0,"f2",-1,-1); + self.assertTrue(f2.isEqual(f2r,1e-12,1e-12)) + self.assertTrue(f2r.getArray().isEqual(MEDLoader.DataArrayDouble([0.,3.,6.,9.,12.,15.,18.,21.,24.,27.,30.,33.,36.,39.,42.,45.,48.,51.,54.,57.]),1e-12)) + f3r=MEDLoader.MEDLoader.ReadFieldNode(fname,"mesh",0,"f1",5,6); + self.assertTrue(f11.isEqual(f3r,1e-12,1e-12)) + self.assertTrue(f3r.getArray().isEqual(MEDLoader.DataArrayDouble([0.,4.,8.,12.,16.,20.,24.,28.,32.,36.,40.,44.,48.,52.,56.,60.,64.,68.,72.,76.]),1e-12)) + pass + pass + +if __name__ == "__main__": + unittest.main() diff --git a/src/medtool/src/MEDLoader/Swig/MEDLoaderTest2.py b/src/medtool/src/MEDLoader/Swig/MEDLoaderTest2.py new file mode 100644 index 000000000..06cc645d0 --- /dev/null +++ b/src/medtool/src/MEDLoader/Swig/MEDLoaderTest2.py @@ -0,0 +1,341 @@ +# -*- coding: iso-8859-1 -*- +# Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 +# 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) + +from MEDLoader import * +import unittest +from math import pi,e,sqrt +from MEDLoaderDataForTest import MEDLoaderDataForTest + +class MEDLoaderTest(unittest.TestCase): + def testMesh1DRW(self): + mesh=MEDLoaderDataForTest.build1DMesh_1(); + mesh.checkCoherency(); + MEDLoader.WriteUMeshDep("Pyfile1.med",mesh,False); + mesh_rw=MEDLoader.ReadUMeshFromFile("Pyfile1.med",mesh.getName(),0); + self.assertTrue(mesh.isEqual(mesh_rw,1e-12)); + pass + + def testMesh2DCurveRW(self): + mesh=MEDLoaderDataForTest.build2DCurveMesh_1(); + mesh.checkCoherency(); + MEDLoader.WriteUMeshDep("Pyfile2.med",mesh,False); + mesh_rw=MEDLoader.ReadUMeshFromFile("Pyfile2.med",mesh.getName(),0); + self.assertTrue(mesh.isEqual(mesh_rw,1e-12)); + pass + + def testMesh2DRW(self): + mesh=MEDLoaderDataForTest.build2DMesh_1(); + mesh.checkCoherency(); + MEDLoader.WriteUMeshDep("Pyfile3.med",mesh,False); + mesh_rw=MEDLoader.ReadUMeshFromFile("Pyfile3.med",mesh.getName(),0); + self.assertTrue(mesh.isEqual(mesh_rw,1e-12)); + pass + + def testMesh3DSurfRW(self): + mesh=MEDLoaderDataForTest.build3DSurfMesh_1(); + mesh.checkCoherency(); + MEDLoader.WriteUMeshDep("Pyfile4.med",mesh,False); + mesh_rw=MEDLoader.ReadUMeshFromFile("Pyfile4.med",mesh.getName(),0); + self.assertTrue(mesh.isEqual(mesh_rw,1e-12)); + pass + + def testMesh3DRW(self): + mesh=MEDLoaderDataForTest.build3DMesh_1(); + mesh.checkCoherency(); + MEDLoader.WriteUMeshDep("Pyfile5.med",mesh,False); + mesh_rw=MEDLoader.ReadUMeshFromFile("Pyfile5.med",mesh.getName(),0); + self.assertTrue(mesh.isEqual(mesh_rw,1e-12)); + pass + + def testFieldRW1(self): + f1=MEDLoaderDataForTest.buildVecFieldOnCells_1(); + MEDLoader.WriteFieldDep("Pyfile6.med",f1,False); + f2=MEDLoader.ReadFieldCell("Pyfile6.med",f1.getMesh().getName(),0,f1.getName(),0,1); + self.assertTrue(f1.isEqual(f2,1e-12,1e-12)); + # + f1=MEDLoaderDataForTest.buildVecFieldOnNodes_1(); + MEDLoader.WriteFieldDep("Pyfile7.med",f1,False); + f2=MEDLoader.ReadFieldNode("Pyfile7.med",f1.getMesh().getName(),0,f1.getName(),2,3); + self.assertTrue(f1.isEqual(f2,1e-12,1e-12)); + pass + + def testFieldRW2(self): + fileName="Pyfile8.med"; + VAL1=12345.67890314; + VAL2=-1111111111111.; + f1=MEDLoaderDataForTest.buildVecFieldOnCells_1(); + MEDLoader.WriteFieldDep(fileName,f1,False); + f1.setTime(10.,8,9); + f1.getArray().setIJ(0,0,VAL1); + MEDLoader.WriteFieldUsingAlreadyWrittenMesh(fileName,f1); + f1.setTime(10.14,18,19); + f1.getArray().setIJ(0,0,VAL2); + MEDLoader.WriteFieldUsingAlreadyWrittenMesh(fileName,f1); + #retrieving time steps... + f2=MEDLoader.ReadFieldCell(fileName,f1.getMesh().getName(),0,f1.getName(),8,9); + f1.setTime(10.,8,9); + f1.getArray().setIJ(0,0,VAL1); + self.assertTrue(f1.isEqual(f2,1e-12,1e-12)); + f2=MEDLoader.ReadFieldCell(fileName,f1.getMesh().getName(),0,f1.getName(),0,1); + f3=MEDLoaderDataForTest.buildVecFieldOnCells_1(); + self.assertTrue(f3.isEqual(f2,1e-12,1e-12)); + f2=MEDLoader.ReadFieldCell(fileName,f1.getMesh().getName(),0,f1.getName(),18,19); + f1.setTime(10.14,18,19); + f1.getArray().setIJ(0,0,VAL2); + self.assertTrue(f1.isEqual(f2,1e-12,1e-12)); + #ON NODES + f1=MEDLoaderDataForTest.buildVecFieldOnNodes_1(); + fileName2="Pyfile9.med"; + MEDLoader.WriteFieldDep(fileName2,f1,False); + f1.setTime(110.,108,109); + tmp=f1.getArray().getPointer(); + f1.getArray().setIJ(0,3,VAL1); + MEDLoader.WriteFieldUsingAlreadyWrittenMesh(fileName2,f1); + f1.setTime(210.,208,209); + f1.getArray().setIJ(0,3,VAL2); + MEDLoader.WriteFieldUsingAlreadyWrittenMesh(fileName2,f1); + f2=MEDLoader.ReadFieldNode(fileName2,f1.getMesh().getName(),0,f1.getName(),108,109); + f1.setTime(110.,108,109); + f1.getArray().setIJ(0,3,VAL1); + self.assertTrue(f1.isEqual(f2,1e-12,1e-12)); + f2=MEDLoader.ReadFieldNode(fileName2,f1.getMesh().getName(),0,f1.getName(),2,3); + f3=MEDLoaderDataForTest.buildVecFieldOnNodes_1(); + self.assertTrue(f3.isEqual(f2,1e-12,1e-12)); + f2=MEDLoader.ReadFieldNode(fileName2,f1.getMesh().getName(),0,f1.getName(),208,209); + f1.setTime(210.,208,209); + f1.getArray().setIJ(0,3,VAL2); + self.assertTrue(f1.isEqual(f2,1e-12,1e-12)); + pass + + # + # Multi field in a same file, but this field has several + # + def testFieldRW3(self): + fileName="Pyfile11.med"; + VAL1=12345.67890314; + VAL2=-1111111111111.; + name1="AField"; + name3="AMesh1"; + f1=MEDLoaderDataForTest.buildVecFieldOnCells_1(); + f1.getMesh().setName(name3); + f1.setName(name1); + f1.setTime(10.,8,9); + tmp=f1.getArray().getPointer(); + f1.getArray().setIJ(0,0,VAL1); + MEDLoader.WriteFieldDep(fileName,f1,False); + f1.setTime(10.14,18,19); + f1.getArray().setIJ(0,0,VAL2); + MEDLoader.WriteFieldUsingAlreadyWrittenMesh(fileName,f1); + f1.getMesh().setName(name3); + f1.setTime(10.55,28,29); + f1.getArray().setIJ(0,0,3*VAL1); + MEDLoader.WriteFieldUsingAlreadyWrittenMesh(fileName,f1); + f1.setTime(10.66,38,39); + f1.getArray().setIJ(0,0,3*VAL2); + MEDLoader.WriteFieldUsingAlreadyWrittenMesh(fileName,f1); + f1.setTime(10.77,48,49); + f1.getArray().setIJ(0,0,4*VAL2); + MEDLoader.WriteFieldUsingAlreadyWrittenMesh(fileName,f1); + #ON NODES + f1=MEDLoaderDataForTest.buildVecFieldOnNodes_1(); + f1.setName(name1); + f1.getMesh().setName(name3); + f1.setTime(110.,8,9); + MEDLoader.WriteFieldUsingAlreadyWrittenMesh(fileName,f1); + f1.setTime(110.,108,109); + tmp=f1.getArray().getPointer(); + f1.getArray().setIJ(0,3,VAL1); + MEDLoader.WriteFieldUsingAlreadyWrittenMesh(fileName,f1); + f1.setTime(210.,208,209); + f1.getArray().setIJ(0,3,VAL2); + MEDLoader.WriteFieldUsingAlreadyWrittenMesh(fileName,f1); + # + it1=MEDLoader.GetCellFieldIterations(fileName,name3,name1); + self.assertEqual(5,len(it1)); + self.assertEqual(8,it1[0][0]); self.assertEqual(9,it1[0][1]); + self.assertEqual(18,it1[1][0]); self.assertEqual(19,it1[1][1]); + self.assertEqual(28,it1[2][0]); self.assertEqual(29,it1[2][1]); + self.assertEqual(38,it1[3][0]); self.assertEqual(39,it1[3][1]); + self.assertEqual(48,it1[4][0]); self.assertEqual(49,it1[4][1]); + it3=MEDLoader.GetNodeFieldIterations(fileName,name3,name1); + self.assertEqual(3,len(it3)); + self.assertEqual(8,it3[0][0]); self.assertEqual(9,it3[0][1]); + self.assertEqual(108,it3[1][0]); self.assertEqual(109,it3[1][1]); + self.assertEqual(208,it3[2][0]); self.assertEqual(209,it3[2][1]); + # + # + f1=MEDLoader.ReadFieldCell(fileName,name3,0,name1,8,9); + self.assertAlmostEqual(VAL1,f1.getArray().getIJ(0,0),13); + f1=MEDLoader.ReadFieldCell(fileName,name3,0,name1,18,19); + self.assertAlmostEqual(VAL2,f1.getArray().getIJ(0,0),13); + f1=MEDLoader.ReadFieldCell(fileName,name3,0,name1,28,29); + self.assertAlmostEqual(3*VAL1,f1.getArray().getIJ(0,0),13); + f1=MEDLoader.ReadFieldCell(fileName,name3,0,name1,38,39); + self.assertAlmostEqual(3*VAL2,f1.getArray().getIJ(0,0),13); + f1=MEDLoader.ReadFieldCell(fileName,name3,0,name1,48,49); + self.assertAlmostEqual(4*VAL2,f1.getArray().getIJ(0,0),13); + # + f1=MEDLoader.ReadFieldNode(fileName,name3,0,name1,8,9); + self.assertAlmostEqual(71.,f1.getArray().getIJ(0,3),13); + f1=MEDLoader.ReadFieldNode(fileName,name3,0,name1,108,109); + self.assertAlmostEqual(VAL1,f1.getArray().getIJ(0,3),13); + f1=MEDLoader.ReadFieldNode(fileName,name3,0,name1,208,209); + self.assertAlmostEqual(VAL2,f1.getArray().getIJ(0,3),13); + pass + + def testMultiMeshRW1(self): + fileName="Pyfile10.med"; + mesh1=MEDLoaderDataForTest.build3DMesh_1(); + part1=[1,2,4,13,15] + mesh2=mesh1.buildPartOfMySelf(part1,True); + mesh2.setName("mesh2"); + part2=[3,4,13,14] + mesh3=mesh1.buildPartOfMySelf(part2,True); + mesh3.setName("mesh3"); + mesh4=MEDCouplingUMesh.New(); + mesh4.setName("mesh4"); + mesh4.setMeshDimension(3); + mesh4.allocateCells(1); + conn=[0,11,1,3] + mesh4.insertNextCell(NORM_TETRA4,4,conn[0:4]) + mesh4.finishInsertingCells(); + mesh4.setCoords(mesh1.getCoords()); + meshes=[mesh1,mesh2,mesh3,mesh4] + mnane="3DToto"; + MEDLoader.WriteUMeshesPartitionDep(fileName,mnane,meshes,False); + # + mesh5=MEDLoader.ReadUMeshFromFile(fileName,mnane); + mesh1.setName(mnane); + part3=[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17] + mesh6=mesh5.buildPartOfMySelf(part3,True); + mesh6.setName(mnane); + self.assertTrue(mesh6.isEqual(mesh1,1e-12)); + grps=MEDLoader.GetMeshGroupsNames(fileName,mnane); + self.assertEqual(4,len(grps)); + grps.index("mesh2"); + grps.index("mesh3"); + grps.index("mesh4"); + grps.index("3DMesh_1"); + # + vec=["mesh2"]; + mesh2_2=MEDLoader.ReadUMeshFromGroups(fileName,mnane,0,vec); + self.assertTrue(mesh2_2.isEqual(mesh2,1e-12)); + vec=["mesh3"]; + mesh3_2=MEDLoader.ReadUMeshFromGroups(fileName,mnane,0,vec); + self.assertTrue(mesh3_2.isEqual(mesh3,1e-12)); + vec=["mesh4"]; + mesh4_2=MEDLoader.ReadUMeshFromGroups(fileName,mnane,0,vec); + self.assertTrue(mesh4_2.isEqual(mesh4,1e-12)); + vec=["3DMesh_1"]; + mesh1_2=MEDLoader.ReadUMeshFromGroups(fileName,mnane,0,vec); + mesh1.setName("3DMesh_1"); + self.assertTrue(mesh1_2.isEqual(mesh1,1e-12)); + # + vec=["Family_-5","Family_-3"]; + mesh2_2=MEDLoader.ReadUMeshFromFamilies(fileName,mnane,0,vec); + mesh2_2.setName("mesh2"); + self.assertTrue(mesh2_2.isEqual(mesh2,1e-12)); + pass + + def testMesh3DSurfShuffleRW(self): + fileName="Pyfile15.med"; + mesh=MEDLoaderDataForTest.build3DSurfMesh_1(); + renumber1=[2,5,1,0,3,4] + mesh.renumberCells(renumber1,False); + mesh.checkCoherency(); + MEDLoader.WriteUMeshDep(fileName,mesh,False); + mesh_rw=MEDLoader.ReadUMeshFromFile(fileName,mesh.getName(),0); + self.assertTrue(mesh.isEqual(mesh_rw,1e-12)); + pass + + def testMultiFieldShuffleRW1(self): + fileName="Pyfile17.med"; + m=MEDLoaderDataForTest.build3DMesh_2(); + self.assertEqual(20,m.getNumberOfCells()); + self.assertEqual(45,m.getNumberOfNodes()); + polys=[1,4,6] + m.convertToPolyTypes(polys); + renum=[1,3,2,8,9,12,13,16,19,0,4,7,5,15,14,17,10,18,6,11] + m.renumberCells(renum,False); + m.orientCorrectlyPolyhedrons(); + # Writing + MEDLoader.WriteUMeshDep(fileName,m,False); + f1Tmp=m.getMeasureField(False); + f1=f1Tmp.buildNewTimeReprFromThis(ONE_TIME,False); + f1.setTime(0.,1,2); + f_1=f1.cloneWithMesh(True); + MEDLoader.WriteFieldUsingAlreadyWrittenMesh(fileName,f1); + f1.applyFunc("2*x"); + f1.setTime(0.01,3,4); + f_2=f1.cloneWithMesh(True); + MEDLoader.WriteFieldUsingAlreadyWrittenMesh(fileName,f1); + f1.applyFunc("2*x/3"); + f1.setTime(0.02,5,6); + f_3=f1.cloneWithMesh(True); + MEDLoader.WriteFieldUsingAlreadyWrittenMesh(fileName,f1); + # Reading + its=[(1,2),(3,4),(5,6)]; + fs=MEDLoader.ReadFieldsOnSameMesh(ON_CELLS,fileName,f_1.getMesh().getName(),0,f_1.getName(),its); + self.assertEqual(3,len(fs)); + self.assertTrue(fs[0].isEqual(f_1,1e-12,1e-12)); + self.assertTrue(fs[1].isEqual(f_2,1e-12,1e-12)); + self.assertTrue(fs[2].isEqual(f_3,1e-12,1e-12)); + pass + + def testWriteUMeshesRW1(self): + fileName="Pyfile18.med"; + m3d=MEDLoaderDataForTest.build3DMesh_2(); + pt=[0.,0.,-0.3] + vec=[0.,0.,1.] + nodes=m3d.findNodesOnPlane(pt,vec,1e-12); + m2d=m3d.buildFacePartOfMySelfNode(nodes,True); + renumber=[1,2,0,4,3] + m2d.renumberCells(renumber,False); + m2d.setName("ExampleOfMultiDimW"); + meshes=[m2d,m3d] + MEDLoader.WriteUMeshes(fileName,meshes,False); + m3d_bis=MEDLoader.ReadUMeshFromFile(fileName,m2d.getName(),0); + self.assertTrue(not m3d_bis.isEqual(m3d,1e-12)); + m3d_bis.setName(m3d.getName()); + self.assertTrue(m3d_bis.isEqual(m3d,1e-12)); + m2d_bis=MEDLoader.ReadUMeshFromFile(fileName,m2d.getName(),-1);#-1 for faces + self.assertTrue(m2d_bis.isEqual(m2d,1e-12)); + # Creation of a field on faces. + f1=MEDCouplingFieldDouble.New(ON_CELLS,ONE_TIME); + f1.setName("FieldOnFacesShuffle"); + f1.setMesh(m2d); + array=DataArrayDouble.New(); + arr1=[71.,171.,10.,110.,20.,120.,30.,130.,40.,140.] + array.setValues(arr1,m2d.getNumberOfCells(),2); + array.setInfoOnComponent(0,"plkj [mm]"); + array.setInfoOnComponent(1,"pqqqss [mm]"); + f1.setArray(array); + tmp=array.setValues(arr1,m2d.getNumberOfCells(),2); + f1.setTime(3.14,2,7); + f1.checkCoherency(); + MEDLoader.WriteFieldUsingAlreadyWrittenMesh(fileName,f1); + f2=MEDLoader.ReadFieldCell(fileName,f1.getMesh().getName(),-1,f1.getName(),2,7); + self.assertTrue(f2.isEqual(f1,1e-12,1e-12)); + pass + pass + +if __name__ == "__main__": + unittest.main() diff --git a/src/medtool/src/MEDLoader/Swig/MEDLoaderTest3.py b/src/medtool/src/MEDLoader/Swig/MEDLoaderTest3.py new file mode 100644 index 000000000..ce9e0e076 --- /dev/null +++ b/src/medtool/src/MEDLoader/Swig/MEDLoaderTest3.py @@ -0,0 +1,4659 @@ +# -*- coding: iso-8859-1 -*- +# Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 +# 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) + +from MEDLoader import * +import unittest +import platform +from math import pi,e,sqrt +from MEDLoaderDataForTest import MEDLoaderDataForTest + +class MEDLoaderTest(unittest.TestCase): + def testMEDMesh1(self): + fileName="Pyfile18.med" + mname="ExampleOfMultiDimW" + medmesh=MEDFileMesh.New(fileName,mname) + self.assertRaises(InterpKernelException,MEDFileMesh.New,fileName,"") + self.assertEqual((0,-1),medmesh.getNonEmptyLevels()) + m1_0=medmesh.getLevel0Mesh(True) + m1_1=MEDLoader.ReadUMeshFromFile(fileName,mname,0) + self.assertTrue(m1_0.isEqual(m1_1,1e-12)); + m2_0=medmesh.getLevelM1Mesh(True) + m2_1=MEDLoader.ReadUMeshFromFile(fileName,mname,-1) + self.assertTrue(m2_0.isEqual(m2_1,1e-12)); + pass + + def testMEDMesh2(self): + fileName="Pyfile10.med" + mname="3DToto" + outFileName="MEDFileMesh1.med" + medmesh=MEDFileUMesh.New(fileName,mname) + self.assertEqual((0,),medmesh.getNonEmptyLevels()) + m1_0=medmesh.getLevel0Mesh(True) + m1_1=MEDLoader.ReadUMeshFromFile(fileName,mname,0) + self.assertTrue(m1_0.isEqual(m1_1,1e-12)); + g1_0=medmesh.getGroup(0,"mesh2",True) + g1_1=MEDLoader.ReadUMeshFromGroups(fileName,mname,0,["mesh2"]); + self.assertTrue(g1_0.isEqual(g1_1,1e-12)); + g1_0=medmesh.getGroup(0,"mesh3",True) + g1_1=MEDLoader.ReadUMeshFromGroups(fileName,mname,0,["mesh3"]); + self.assertTrue(g1_0.isEqual(g1_1,1e-12)); + g1_0=medmesh.getGroups(0,["mesh3","mesh2"]) + g1_1=MEDLoader.ReadUMeshFromGroups(fileName,mname,0,["mesh3","mesh2"]); + g1_1.setName(g1_0.getName()) + self.assertTrue(g1_0.isEqual(g1_1,1e-12)); + g1_0=medmesh.getFamily(0,"Family_-3",True) + g1_1=MEDLoader.ReadUMeshFromFamilies(fileName,mname,0,["Family_-3"]); + self.assertTrue(g1_0.isEqual(g1_1,1e-12)); + g1_0=medmesh.getFamilies(0,["Family_-3","Family_-5"],True) + g1_1=MEDLoader.ReadUMeshFromFamilies(fileName,mname,0,["Family_-3","Family_-5"]); + g1_1.setName(g1_0.getName()) + self.assertTrue(g1_0.isEqual(g1_1,1e-12)); + self.assertTrue(g1_0.isEqual(g1_1,1e-12)); + medmesh.write(outFileName,2); + self.assertEqual([1,2,4,13,15],medmesh.getGroupArr(0,"mesh2",True).getValues()); + self.assertEqual([1,2,15],medmesh.getFamilyArr(0,"Family_-3",True).getValues()); + self.assertEqual([1,2,4,13,15],medmesh.getFamiliesArr(0,["Family_-5","Family_-3"],True).getValues()); + self.assertEqual([18,1,2,3,4,13,14,15],medmesh.getGroupsArr(0,["mesh2","mesh4","mesh3"],True).getValues()); + famn=medmesh.getFamilyNameGivenId(0) + self.assertRaises(InterpKernelException,medmesh.getNodeFamilyArr,famn,True); + #without renum + self.assertEqual([2,3,5,14,16],medmesh.getGroupArr(0,"mesh2").getValues()); + self.assertEqual([2,3,16],medmesh.getFamilyArr(0,"Family_-3").getValues()); + self.assertEqual([2,3,5,14,16],medmesh.getFamiliesArr(0,["Family_-5","Family_-3"]).getValues()); + self.assertEqual([0,2,3,4,5,14,15,16],medmesh.getGroupsArr(0,["mesh2","mesh3","mesh4"],False).getValues()); + self.assertRaises(InterpKernelException,medmesh.getNodeFamilyArr,famn,False); + pass + + # this tests emulates MEDMEM ( Except that it works ! ) The permutation are NOT taken into account + def testMEDMesh3(self): + outFileName="MEDFileMesh3.med" + c=DataArrayDouble.New() + coords=[-0.3,-0.3, 0.2,-0.3, 0.7,-0.3, -0.3,0.2, 0.2,0.2, 0.7,0.2, -0.3,0.7, 0.2,0.7, 0.7,0.7 ]; + targetConn=[0,3,4,1, 1,4,2, 4,5,2, 6,7,4,3, 7,8,5,4] + c.setValues(coords,9,2) + m=MEDCouplingUMesh.New(); + m.setMeshDimension(2); + m.allocateCells(5); + m.insertNextCell(NORM_TRI3,3,targetConn[4:7]) + m.insertNextCell(NORM_TRI3,3,targetConn[7:10]) + m.insertNextCell(NORM_QUAD4,4,targetConn[0:4]) + m.insertNextCell(NORM_POLYGON,4,targetConn[10:14]) + m.insertNextCell(NORM_POLYGON,4,targetConn[14:18]) + m.finishInsertingCells(); + m.setCoords(c) + m.checkCoherency() + m1=MEDCouplingUMesh.New(); + m1.setMeshDimension(1); + m1.allocateCells(3); + m1.insertNextCell(NORM_SEG2,2,[1,4]) + m1.insertNextCell(NORM_SEG2,2,[3,6]) + m1.insertNextCell(NORM_SEG3,3,[2,8,5]) + m1.finishInsertingCells(); + m1.setCoords(c) + m1.checkCoherency() + m2=MEDCouplingUMesh.New(); + m2.setMeshDimension(0); + m2.allocateCells(4); + m2.insertNextCell(NORM_POINT1,1,[1]) + m2.insertNextCell(NORM_POINT1,1,[3]) + m2.insertNextCell(NORM_POINT1,1,[2]) + m2.insertNextCell(NORM_POINT1,1,[6]) + m2.finishInsertingCells(); + m2.setCoords(c) + m2.checkCoherency() + # + mm=MEDFileUMesh.New() + self.assertTrue(mm.getUnivNameWrStatus()) + mm.setName("MyFirstMEDCouplingMEDmesh") + mm.setDescription("IHopeToConvinceLastMEDMEMUsers") + mm.setCoords(c) + mm.setMeshAtLevel(-1,m1); + mm.setMeshAtLevel(0,m); + mm.setMeshAtLevel(-2,m2); + # playing with groups + g1_2=DataArrayInt.New() + g1_2.setValues([1,3],2,1) + g1_2.setName("G1") + g2_2=DataArrayInt.New() + g2_2.setValues([1,2,3],3,1) + g2_2.setName("G2") + mm.setGroupsAtLevel(0,[g1_2,g2_2],False) + g1_1=DataArrayInt.New() + g1_1.setValues([0,1,2],3,1) + g1_1.setName("G1") + g2_1=DataArrayInt.New() + g2_1.setValues([0,2],2,1) + g2_1.setName("G2") + mm.setGroupsAtLevel(-1,[g1_1,g2_1],False) + g1_N=DataArrayInt.New() + g1_N.setValues(range(8),8,1) + g1_N.setName("G1") + g2_N=DataArrayInt.New() + g2_N.setValues(range(9),9,1) + g2_N.setName("G2") + mm.setGroupsAtLevel(1,[g1_N,g2_N],False) + mm.createGroupOnAll(0,"GrpOnAllCell") + # check content of mm + t=mm.getGroupArr(0,"G1",False) + self.assertTrue(g1_2.isEqual(t)); + t=mm.getGroupArr(0,"G2",False) + self.assertTrue(g2_2.isEqual(t)); + t=mm.getGroupArr(-1,"G1",False) + self.assertTrue(g1_1.isEqual(t)); + t=mm.getGroupArr(-1,"G2",False) + self.assertTrue(g2_1.isEqual(t)); + t=mm.getGroupArr(1,"G1",False) + self.assertTrue(g1_N.isEqual(t)); + t=mm.getGroupArr(1,"G2",False) + self.assertTrue(g2_N.isEqual(t)); + self.assertTrue(mm.existsGroup("GrpOnAllCell")); + t=mm.getGroupArr(0,"GrpOnAllCell") + self.assertTrue(t.getValues()==range(5)) + # + mmCpy=mm.deepCpy() + self.assertTrue(mm.isEqual(mmCpy,1e-12)[0]) ; del mm + mmCpy.write(outFileName,2); + # + mm=MEDFileMesh.New(outFileName) + # + self.assertEqual([NORM_TRI3,NORM_QUAD4,NORM_POLYGON],mm.getGeoTypesAtLevel(0)) + self.assertEqual([NORM_SEG2,NORM_SEG3],mm.getGeoTypesAtLevel(-1)) + self.assertEqual([NORM_POINT1],mm.getGeoTypesAtLevel(-2)) + mm0=mm.getDirectUndergroundSingleGeoTypeMesh(NORM_POLYGON) + self.assertTrue(isinstance(mm0,MEDCoupling1DGTUMesh)) + self.assertTrue(mm0.getNodalConnectivity().isEqual(DataArrayInt([6,7,4,3,7,8,5,4]))) + self.assertTrue(mm0.getNodalConnectivityIndex().isEqual(DataArrayInt([0,4,8]))) + lmm=mm.getDirectUndergroundSingleGeoTypeMeshes(0) + self.assertEqual(3,len(lmm)) + self.assertTrue(isinstance(lmm[0],MEDCoupling1SGTUMesh)) + self.assertTrue(isinstance(lmm[1],MEDCoupling1SGTUMesh)) + self.assertTrue(isinstance(lmm[2],MEDCoupling1DGTUMesh)) + # + self.assertTrue(mm.getUnivNameWrStatus()) + self.assertTrue(isinstance(mm.getUnivName(),str)) + self.assertTrue(len(mm.getUnivName())!=0) + mbis=mm.getMeshAtLevel(0) + m.setName(mm.getName()) ; m.setDescription(mm.getDescription()) + self.assertTrue(m.isEqual(mbis,1e-12)); + # + self.assertEqual(([[(3, 2), (4, 1), (5, 8)], [(1, 2), (2, 1)], [(0, 4)]], 2, 2, 9),MEDLoader.GetUMeshGlobalInfo(outFileName,"MyFirstMEDCouplingMEDmesh")) + pass + + # this test is the testMEDMesh3 except that permutation is dealed here + def testMEDMesh4(self): + outFileName="MEDFileMesh4.med" + c=DataArrayDouble.New() + coords=[-0.3,-0.3, 0.2,-0.3, 0.7,-0.3, -0.3,0.2, 0.2,0.2, 0.7,0.2, -0.3,0.7, 0.2,0.7, 0.7,0.7 ]; + targetConn=[0,3,4,1, 1,4,2, 4,5,2, 6,7,4,3, 7,8,5,4] + c.setValues(coords,9,2) + c.setInfoOnComponent(0,"abcdef [km]") + c.setInfoOnComponent(1,"ghij [MW]") + m=MEDCouplingUMesh.New(); + m.setMeshDimension(2); + m.allocateCells(5); + m.insertNextCell(NORM_QUAD4,4,targetConn[0:4]) + m.insertNextCell(NORM_TRI3,3,targetConn[4:7]) + m.insertNextCell(NORM_TRI3,3,targetConn[7:10]) + m.insertNextCell(NORM_QUAD4,4,targetConn[10:14]) + m.insertNextCell(NORM_QUAD4,4,targetConn[14:18]) + m.finishInsertingCells(); + m.setCoords(c) + m.checkCoherency() + m1=MEDCouplingUMesh.New(); + m1.setMeshDimension(1); + m1.allocateCells(3); + m1.insertNextCell(NORM_SEG2,2,[1,4]) + m1.insertNextCell(NORM_SEG3,3,[2,8,5]) + m1.insertNextCell(NORM_SEG2,2,[3,6]) + m1.finishInsertingCells(); + m1.setCoords(c) + m1.checkCoherency() + m2=MEDCouplingUMesh.New(); + m2.setMeshDimension(0); + m2.allocateCells(4); + m2.insertNextCell(NORM_POINT1,1,[1]) + m2.insertNextCell(NORM_POINT1,1,[3]) + m2.insertNextCell(NORM_POINT1,1,[2]) + m2.insertNextCell(NORM_POINT1,1,[6]) + m2.finishInsertingCells(); + m2.setCoords(c) + m2.checkCoherency() + # + mm=MEDFileUMesh.New() + mm.setName("My2ndMEDCouplingMEDmesh") + mm.setDescription("ThisIsImpossibleToDoWithMEDMEM") + mm.setCoords(c) + renumNode=DataArrayInt.New() + renumNode.setValues([10,11,12,13,14,15,16,17,18],9,1) + mm.setRenumFieldArr(1,renumNode) + mm.setMeshAtLevel(-1,m1,True); + mm.setMeshAtLevel(0,m,True); + mm.setMeshAtLevel(-2,m2,True); + mm.removeMeshAtLevel(-2) + mm.setMeshAtLevel(-2,m2,True); + # playing with groups + g1_2=DataArrayInt.New() + g1_2.setValues([2,3],2,1) + g1_2.setName("G1") + g2_2=DataArrayInt.New() + g2_2.setValues([2,0,3],3,1) + g2_2.setName("G2") + mm.setGroupsAtLevel(0,[g1_2,g2_2],True) + g1_1=DataArrayInt.New() + g1_1.setValues([0,2,1],3,1) + g1_1.setName("G1") + g2_1=DataArrayInt.New() + g2_1.setValues([0,2],2,1) + g2_1.setName("G2") + mm.setGroupsAtLevel(-1,[g1_1,g2_1],True) + g1_N=DataArrayInt.New() + g1_N.setValues([10,11,12,13,14,15,16,17],8,1) + g1_N.setName("G1") + g2_N=DataArrayInt.New() + g2_N.setValues([10,11,12,13,14,15,16,17,18],9,1) + g2_N.setName("G2") + mm.setGroupsAtLevel(1,[g1_N,g2_N],True) + # check content of mm + t=mm.getGroupArr(0,"G1",True) + self.assertTrue(g1_2.isEqual(t)); + t=mm.getGroupArr(0,"G2",True) + self.assertTrue(g2_2.isEqual(t)); + t=mm.getGroupArr(-1,"G1",True) + self.assertTrue(g1_1.isEqual(t)); + t=mm.getGroupArr(-1,"G2",True) + self.assertTrue(g2_1.isEqual(t)); + self.assertTrue(not mm.existsGroup("GrpOnAllCell")); + # + mm.write(outFileName,2); + mm2=MEDFileMesh.New(outFileName) + res=mm.isEqual(mm2,1e-12) + self.assertTrue(res[0]) + l=list(mm2.getFamiliesOnGroup("G2")) ; l.sort() + self.assertEqual(['Family_-3','Family_-4','Family_-7','Family_10','Family_11'],l) + mm2.keepFamIdsOnlyOnLevs([3],[-1]) + for lev in mm.getGrpNonEmptyLevelsExt("G2"): + self.assertEqual(mm.getGroupArr(lev,"G2").getValues(),mm2.getGroupArr(lev,"G2").getValues()) + pass + l=list(mm2.getFamiliesOnGroup("G2")) ; l.sort() + self.assertEqual(['Family_-3','Family_-4','Family_-7','Family_10','Family_11'],l) + # + self.assertEqual([-7,-7,-6],mm2.getFamilyFieldAtLevel(-1).getValues()) + mm2.getFamilyFieldAtLevel(-1).setIJ(1,0,-8) + self.assertEqual([-7,-8,-6],mm2.getFamilyFieldAtLevel(-1).getValues()) + self.assertTrue(not mm2.existsFamily("Family_-8")) + mm2.createGroupOnAll(-1,"GrpOnAllFace") + self.assertTrue(mm2.existsFamily("Family_-8")) + self.assertEqual(range(3),mm2.getGroupArr(-1,"GrpOnAllFace").getValues()) + pass + + #testing persistence of retrieved arrays + def testMEDMesh5(self): + fileName="Pyfile18.med" + mname="ExampleOfMultiDimW" + medmesh=MEDFileUMesh.New(fileName,mname) + m1_0=medmesh.getLevel0Mesh(True) + da1=medmesh.getFamilyFieldAtLevel(0) + del medmesh + self.assertEqual(20,m1_0.getNumberOfCells()) + self.assertEqual(20,da1.getNumberOfTuples()) + pass + + def testMEDMesh6(self): + outFileName="MEDFileMesh5.med" + m=MEDFileCMesh.New() + m.setTime(-1,-1,2.3) + m1=MEDCouplingCMesh.New(); + da=DataArrayDouble.New() + da.setValues([0.,1.,2.],3,1) + da.setInfoOnComponent(0,"XX [mm]") + m1.setCoordsAt(0,da) + da=DataArrayDouble.New() + da.setValues([0.,1.2],2,1) + da.setInfoOnComponent(0,"YY [km]") + m1.setCoordsAt(1,da) + da=DataArrayDouble.New() + da.setValues([0.,1.3],2,1) + da.setInfoOnComponent(0,"ZZ [um]") + m1.setCoordsAt(2,da) + m.setMesh(m1) + self.assertTrue(m[0].isEqual(m1,1e-12)) + self.assertTrue(isinstance(m[0],MEDCouplingCMesh)) + m.setName("myFirstCartMesh") + m.setDescription("mmmmpppppppp") + m.setTimeValue(2.3) + m.setTimeUnit("ms") + da=DataArrayInt.New() + da.setValues([0,0,1,0,1,2,4,3,0,1,2,2],12,1) + m.setFamilyFieldArr(1,da) + m.setFamilyId("family1",1) + da=m.getFamilyArr(1,"family1") + expected1=[2,4,9] + self.assertEqual(expected1,da.getValues()) + self.assertTrue(m.getUnivNameWrStatus()) + m.write(outFileName,2); + mm=MEDFileMesh.New(outFileName) + self.assertEqual([NORM_HEXA8],mm.getGeoTypesAtLevel(0)) + self.assertTrue(isinstance(mm,MEDFileCMesh)) + self.assertTrue(isinstance(mm.getUnivName(),str)) + self.assertTrue(len(mm.getUnivName())!=0) + self.assertTrue(m.isEqual(mm,1e-12)[0]) + self.assertEqual(expected1,mm.getFamilyArr(1,"family1").getValues()) + m2=mm.getMesh() + tt=m.getTime() + m1.setTime(tt[2],tt[0],tt[1]) + m1.setName(m.getName()) + m1.setTimeUnit(m.getTimeUnit()) + m1.setDescription(m.getDescription()) + self.assertTrue(m2.isEqual(m1,1e-12)); + pass + + def testMEDMesh7(self): + fileName="Pyfile24.med" + m2,m1,m0,f2,f1,f0,p,n2,n1,n0,fns,fids,grpns,famIdsPerGrp=MEDLoaderDataForTest.buildMultiLevelMesh_1() + m=MEDFileUMesh.New() + m.setCoords(m2.getCoords()) + m.setMeshAtLevel(0,m2) + m.setMeshAtLevel(-1,m1) + m.setMeshAtLevel(-2,m0) + m.setFamilyFieldArr(0,f2) + m.setFamilyFieldArr(-1,f1) + m.setFamilyFieldArr(-2,f0) + m.setFamilyFieldArr(1,p) + m.setRenumFieldArr(0,n2) + m.setRenumFieldArr(-1,n1) + m.setRenumFieldArr(-2,n0) + nbOfFams=len(fns) + for i in xrange(nbOfFams): + m.addFamily(fns[i],fids[i]) + pass + nbOfGrps=len(grpns) + for i in xrange(nbOfGrps): + m.setFamiliesIdsOnGroup(grpns[i],famIdsPerGrp[i]) + pass + m.setName(m2.getName()) + m.setDescription(m2.getDescription()) + # + self.assertEqual((-1,),m.getGrpNonEmptyLevels("A2A4")) + self.assertEqual((),m.getGrpNonEmptyLevels("A1")) + self.assertEqual((-2,),m.getGrpNonEmptyLevels("AP2")) + self.assertEqual((-1,-2),m.getGrpsNonEmptyLevels(["A2A4","AP2"])) + self.assertEqual((-1,),m.getFamNonEmptyLevels('A4A3____________________________')) + self.assertEqual((0,),m.getFamNonEmptyLevels('MESH____DALT3___DALLE___________')) + self.assertEqual((0,-1,),m.getFamsNonEmptyLevels(['MESH____DALT3___DALLE___________','A4A3____________________________'])) + self.assertEqual(('A1A2','A2A4','A3A1','A3C5','A4A3','B1C1','B2B4','B3B1','B4C3','C1C4','C2B2','C3C2','C4B3','C5A4'),m.getGroupsOnSpecifiedLev(-1)) + self.assertEqual(('DALLE','DALQ1','DALQ2','DALT3','MESH'),m.getGroupsOnSpecifiedLev(0)) + # + m.write(fileName,2) + self.assertRaises(InterpKernelException,MEDFileField1TS,fileName)#throw because no field in file fileName + pass + + def funcToTestDelItem(self,ff): + del ff[[0.02,(3,4)]] + pass + + #emulation of pointe.med file. + def testMEDField1(self): + mm=MEDFileMesh.New("Pyfile17.med") + mm.write("Pyfile17_bis.med",2) + ff=MEDFileFieldMultiTS("Pyfile17.med") + tsExpected=[[1,2],[3,4],[5,6]] + self.assertEqual(3,len(ff)) + for pos,f1ts in enumerate(ff): + self.assertEqual(tsExpected[pos],f1ts.getTime()[:2]) + self.assertEqual(type(f1ts),MEDFileField1TS) + pass + self.assertEqual("MeasureOfMesh_Extruded",ff.getName()) + self.assertEqual([3,4],ff[1].getTime()[:-1]) + self.assertEqual([3,4],ff[3,4].getTime()[:-1]) + self.assertEqual([3,4],ff[0.01].getTime()[:-1]) + ff.write("Pyfile17_bis.med",0) + # + ts=ff.getTimeSteps() ; ts=[elt[:-1] for elt in ts] + self.assertEqual([(1,2),(3,4),(5,6)],ts) + self.funcToTestDelItem(ff) + ts=ff.getTimeSteps() ; ts=[elt[:-1] for elt in ts] + self.assertEqual([(1,2)],ts) + pass + + #profiles + def testMEDField2(self): + mm=MEDFileMesh.New("Pyfile19.med") + mm.write("Pyfile19_bis.med",2) + ff=MEDFileFieldMultiTS.New("Pyfile19.med") + ff.write("Pyfile19_bis.med",0) + self.assertEqual([('tyty','mm'),('uiop','MW')],MEDLoader.GetComponentsNamesOfField("Pyfile19_bis.med","VFieldOnNodes")) + pass + + #gauss points + def testMEDField3(self): + mm=MEDFileMesh.New("Pyfile13.med") + mm.write("Pyfile13_bis.med",2) + ff=MEDFileFieldMultiTS.New("Pyfile13.med","MyFirstFieldOnGaussPoint") + ff.write("Pyfile13_bis.med",0) + ff=MEDFileField1TS.New("Pyfile13.med","MyFirstFieldOnGaussPoint",1,5) + f=ff.getFieldAtLevel(ON_GAUSS_PT,0) + f2=MEDLoader.ReadFieldGauss("Pyfile13.med",'2DMesh_2',0,'MyFirstFieldOnGaussPoint',1,5) + self.assertTrue(f.isEqual(f2,1e-12,1e-12)) + ff3=MEDFileField1TS.New("Pyfile13.med","MyFirstFieldOnGaussPoint") + f3=ff3.getFieldAtLevel(ON_GAUSS_PT,0) + self.assertTrue(f.isEqual(f3,1e-12,1e-12)) + ff4=MEDFileField1TS.New("Pyfile13.med") + f4=ff4.getFieldAtLevel(ON_GAUSS_PT,0) + self.assertTrue(f.isEqual(f4,1e-12,1e-12)) + pass + + #gauss NE + def testMEDField4(self): + mm=MEDFileMesh.New("Pyfile14.med") + mm.write("Pyfile14_bis.med",2) + ff=MEDFileFieldMultiTS.New("Pyfile14.med","MyFieldOnGaussNE") + ff.write("Pyfile14_bis.med",0) + ff=MEDFileField1TS.New("Pyfile14.med","MyFieldOnGaussNE",1,5) + f=ff.getFieldAtLevel(ON_GAUSS_NE,0) + f2=MEDLoader.ReadFieldGaussNE("Pyfile14.med",'2DMesh_2',0,"MyFieldOnGaussNE",1,5) + self.assertTrue(f.isEqual(f2,1e-12,1e-12)) + pass + + # MEDField get/set on pointe.med + def testMEDField5(self): + ff=MEDFileField1TS.New("Pyfile17.med","MeasureOfMesh_Extruded",1,2) + f=ff.getFieldAtLevel(ON_CELLS,0) + f2=MEDLoader.ReadFieldCell("Pyfile17.med","Extruded",0,"MeasureOfMesh_Extruded",1,2) + self.assertTrue(f.getMesh().getCoords().isEqual(f2.getMesh().getCoords(),1e-12)) + f.getMesh().tryToShareSameCoords(f2.getMesh(),1e-12) + f.changeUnderlyingMesh(f2.getMesh(),22,1e-12) + self.assertTrue(f.isEqual(f2,1e-12,1e-12)) + # no with renumbering + f=ff.getFieldAtLevel(ON_CELLS,0,1) + f2=MEDLoader.ReadFieldCell("Pyfile17.med","Extruded",0,"MeasureOfMesh_Extruded",1,2) + self.assertTrue(f.isEqual(f2,1e-12,1e-12)) + f=ff.getFieldAtLevel(ON_CELLS,0,3) + self.assertTrue(f.isEqual(f2,1e-12,1e-12)) + f=ff.getFieldAtLevel(ON_CELLS,0,2) + self.assertTrue(not f.isEqual(f2,1e-12,1e-12)) + f.changeUnderlyingMesh(f2.getMesh(),12,1e-12) + self.assertTrue(f.isEqual(f2,1e-12,1e-12)) + pass + + # MEDField get/set on profiles nodes + def testMEDField6(self): + ff=MEDFileFieldMultiTS.New("Pyfile7.med","VectorFieldOnNodes") + its=ff.getIterations() + self.assertRaises(InterpKernelException,ff.getFieldAtLevel,ON_CELLS,its[0][0],its[0][1],0)# request on cell and it is not on cells + f=ff.getFieldAtLevel(ON_NODES,its[0][0],its[0][1],0) + f2=MEDLoader.ReadFieldNode("Pyfile7.med",'3DSurfMesh_1',0,"VectorFieldOnNodes",its[0][0],its[0][1]) + self.assertTrue(f.isEqual(f2,1e-12,1e-12)) + ff=MEDFileFieldMultiTS.New("Pyfile19.med","VFieldOnNodes") + its=ff.getIterations() + f=ff.getFieldAtLevel(ON_NODES,its[0][0],its[0][1],0) + f2=MEDLoader.ReadFieldNode("Pyfile19.med",'2DMesh_1',0,"VFieldOnNodes",its[0][0],its[0][1]) + self.assertTrue(f.isEqual(f2,1e-12,1e-12)) + self.assertRaises(InterpKernelException,ff.getFieldAtLevel,ON_CELLS,its[0][0],its[0][1],0)# request on cell and it is not on cells + self.assertRaises(InterpKernelException,ff.getFieldAtLevel,ON_NODES,its[0][0],its[0][1],0,1)#request renumber following mesh : it is on profile ! + pass + + # MEDField get/set on profiles cells + def testMEDField7(self): + ff=MEDFileFieldMultiTS.New("Pyfile12.med","VectorFieldOnCells") + its=ff.getIterations() + f=ff.getFieldAtLevel(ON_CELLS,its[0][0],its[0][1],0) + f2=MEDLoader.ReadFieldCell("Pyfile12.med",'3DMesh_1',0,"VectorFieldOnCells",its[0][0],its[0][1]) + self.assertTrue(f.isEqual(f2,1e-12,1e-12)) + pass + + #first test of assignation. No profile and types sorted by type. + def testMEDField8(self): + fname="Pyfile25.med" + f1=MEDLoaderDataForTest.buildVecFieldOnCells_1(); + m1=f1.getMesh() + mm1=MEDFileUMesh.New() + mm1.setCoords(m1.getCoords()) + mm1.setMeshAtLevel(0,m1) + mm1.setName(m1.getName()) + mm1.write(fname,2) + ff1=MEDFileField1TS.New() + ff1.setFieldNoProfileSBT(f1) + ff1.write(fname,0) + f2=MEDLoader.ReadFieldCell(fname,f1.getMesh().getName(),0,f1.getName(),f1.getTime()[1],f1.getTime()[2]); + itt,orr,ti=ff1.getTime() + self.assertEqual(0,itt); self.assertEqual(1,orr); self.assertAlmostEqual(2.,ti,14); + self.assertTrue(f1.isEqual(f2,1e-12,1e-12)) + ff1.setTime(3,4,2.3) + itt,orr,ti=ff1.getTime() + self.assertEqual(3,itt); self.assertEqual(4,orr); self.assertAlmostEqual(2.3,ti,14); + da,infos=ff1.getUndergroundDataArrayExt() + f2.getArray().setName(da.getName())#da has the same name than f2 + self.assertTrue(da.isEqual(f2.getArray(),1e-12)) + self.assertEqual([((3, 0), (0, 2)), ((4, 0), (2, 4)), ((6, 0), (4, 5)), ((5, 0), (5, 6))],infos) + # + fname="Pyfile26.med" + f1=MEDLoaderDataForTest.buildVecFieldOnNodes_1(); + m1=f1.getMesh() + mm1=MEDFileUMesh.New() + mm1.setCoords(m1.getCoords()) + mm1.setMeshAtLevel(0,m1) + mm1.setName(m1.getName()) + mm1.write(fname,2) + ff1=MEDFileField1TS.New() + ff1.setFieldNoProfileSBT(f1) + nv=1456. + da=ff1.getUndergroundDataArray().setIJ(0,0,nv) + ff1.write(fname,0) + f2=MEDLoader.ReadFieldNode(fname,f1.getMesh().getName(),0,f1.getName(),f1.getTime()[1],f1.getTime()[2]) + self.assertTrue(not f1.isEqual(f2,1e-12,1e-12)) + f1.getArray().setIJ(0,0,nv) + self.assertTrue(f1.isEqual(f2,1e-12,1e-12)) + # + fname="Pyfile27.med" + f1=MEDLoaderDataForTest.buildVecFieldOnGaussNE_1(); + m1=f1.getMesh() + mm1=MEDFileUMesh.New() + mm1.setCoords(m1.getCoords()) + mm1.setMeshAtLevel(0,m1) + mm1.setName(m1.getName()) + mm1.write(fname,2) + ff1=MEDFileField1TS.New() + ff1.setFieldNoProfileSBT(f1) + ff1.write(fname,0) + f2=MEDLoader.ReadFieldGaussNE(fname,f1.getMesh().getName(),0,f1.getName(),f1.getTime()[1],f1.getTime()[2]) + self.assertTrue(f1.isEqual(f2,1e-12,1e-12)) + da,infos=ff1.getUndergroundDataArrayExt() + f2.getArray().setName(da.getName())#da has the same name than f2 + self.assertTrue(da.isEqual(f2.getArray(),1e-12)) + self.assertEqual([((3, 0), (0, 6)), ((4, 0), (6, 14)), ((6, 0), (14, 20))],infos) + # + fname="Pyfile28.med" + f1=MEDLoaderDataForTest.buildVecFieldOnGauss_2_Simpler(); + f1InvalidCpy=f1.deepCpy() + f1InvalidCpy.setDiscretization(MEDCouplingFieldDiscretizationGauss()) + f1InvalidCpy2=f1.deepCpy() + f1InvalidCpy2.setDiscretization(MEDCouplingFieldDiscretizationGauss()) + m1=f1.getMesh() + mm1=MEDFileUMesh.New() + mm1.setCoords(m1.getCoords()) + mm1.setMeshAtLevel(0,m1) + mm1.setName(m1.getName()) + mm1.write(fname,2) + ff1=MEDFileField1TS.New() + self.assertRaises(InterpKernelException,ff1.setFieldNoProfileSBT,f1InvalidCpy) # fails because no Gauss localization per cell set !* + f1InvalidCpy2.getDiscretization().setArrayOfDiscIds(f1.getDiscretization().getArrayOfDiscIds()) # fails because no Gauss localization set whereas gauss locid per cell given ! + self.assertRaises(InterpKernelException,ff1.setFieldNoProfileSBT,f1InvalidCpy2) + ff1.setFieldNoProfileSBT(f1) + ff1.write(fname,0) + ff2=MEDFileField1TS.New(fname,f1.getName(),f1.getTime()[1],f1.getTime()[2]) + f2=ff2.getFieldAtLevel(ON_GAUSS_PT,0) + self.assertTrue(f1.isEqual(f2,1e-12,1e-12)) + sbt=ff2.getFieldSplitedByType2() + loc1=ff2.getLocalization("Loc_MyFirstFieldOnGaussPoint_NORM_TRI6_5") + self.assertEqual("Loc_MyFirstFieldOnGaussPoint_NORM_TRI6_5",loc1.getName()) + self.assertEqual((-1, 1,-1,-1,1,-1,-1,0,0,-1,0,0),loc1.getRefCoords()) + self.assertEqual(6,loc1.getNumberOfPointsInCells()) + self.assertEqual(3,loc1.getNumberOfGaussPoints()) + self.assertEqual(2,loc1.getDimension()) + da,infos=ff2.getUndergroundDataArrayExt() + f2.getArray().setName(da.getName())#da has the same name than f2 + self.assertTrue(da.isEqual(f2.getArray(),1e-12)) + self.assertEqual(53,da.getNumberOfTuples()) + self.assertEqual([((3, 0), (0, 18)), ((3, 1), (18, 30)), ((3, 2), (30, 36)), ((4, 0), (36, 42)), ((4, 1), (42, 44)), ((6, 0), (44, 53))],infos) + # + pass + + def testMEDFileData1(self): + fname="Pyfile29.med" + d=MEDFileData.New() + # + m1=MEDLoaderDataForTest.build1DMesh_1() + mm1=MEDFileUMesh.New() ; mm1.setCoords(m1.getCoords()) ; mm1.setMeshAtLevel(0,m1) ; mm1.setName(m1.getName()) + mmm1=MEDFileMeshMultiTS.New() ; + mmm1.setOneTimeStep(mm1) + m2=MEDLoaderDataForTest.build2DCurveMesh_1() + mm2=MEDFileUMesh.New() ; mm2.setCoords(m2.getCoords()) ; mm2.setMeshAtLevel(0,m2) ; mm2.setName(m2.getName()) + mmm2=MEDFileMeshMultiTS.New() ; mmm2.setOneTimeStep(mm2) + ms=MEDFileMeshes.New(); ms.setMeshAtPos(0,mm1) ; ms.setMeshAtPos(1,mm2) + d.setMeshes(ms) + for name,mmm in zip(["1DMesh_1","2DCurveMesh_1"],ms): + self.assertEqual(name,mmm.getName()) + self.assertEqual(type(mmm),MEDFileUMesh) + pass + self.assertEqual(('1DMesh_1', '2DCurveMesh_1'),d.getMeshes().getMeshesNames()) + # + ff1=MEDFileFieldMultiTS.New() + ff21=MEDFileFieldMultiTS.New() + ff22=MEDFileFieldMultiTS.New() + f1=m1.getMeasureField(True) ; f1.setName("f1") ; f1=f1.buildNewTimeReprFromThis(ONE_TIME,False) + f1.getArray().setInfoOnComponent(0,"power [kW]") + ff1.appendFieldNoProfileSBT(f1) + f21=m2.getMeasureField(True) ; f21.setName("f21") ; f21=f21.buildNewTimeReprFromThis(ONE_TIME,False) + f21.getArray().setInfoOnComponent(0,"sta [mm]") ; + ff21.appendFieldNoProfileSBT(f21) + f22=f21.deepCpy() ; f22.setName("f22") ; f22=f22.buildNewTimeReprFromThis(ONE_TIME,False) ; + f22.applyFunc(2,"3*x*IVec+2*x*JVec") + f22.getArray().setInfoOnComponent(0,"distance [km]") ; f22.getArray().setInfoOnComponent(1,"displacement [cm]") + ff22.appendFieldNoProfileSBT(f22) + fs=MEDFileFields.New() + fs.pushField(ff1) ; fs.pushField(ff21) ; fs.pushField(ff22) + for name,fmts in zip(["f1","f21","f22"],fs): + self.assertEqual(name,fmts.getName()) + pass + d.setFields(fs) + # + fname2="Pyfile29_2.med" + d.write(fname2,2) + # + d2=MEDFileData.New(fname2) + self.assertEqual(2,d2.getNumberOfMeshes()) + self.assertEqual(3,d2.getNumberOfFields()) + self.assertTrue(isinstance(d2.getMeshes().getMeshAtPos(0),MEDFileUMesh)) + self.assertTrue(isinstance(d2.getMeshes()[0],MEDFileUMesh)) + self.assertTrue(isinstance(d2.getMeshes()['2DCurveMesh_1'],MEDFileUMesh)) + m1bis=d2.getMeshes().getMeshAtPos(0).getMeshAtLevel(0) + self.assertTrue(m1.isEqual(m1bis,1e-12)) + self.assertEqual(('f1', 'f21', 'f22'),d2.getFields().getFieldsNames()) + self.assertEqual([(-1,-1,0.0)],d2.getFields().getFieldAtPos(2).getTimeSteps()) + self.assertEqual([(-1,-1,0.0)],d2.getFields()[2].getTimeSteps()) + self.assertEqual([(-1,-1,0.0)],d2.getFields().getFieldWithName("f21").getTimeSteps()) + self.assertEqual([(-1,-1,0.0)],d2.getFields()["f21"].getTimeSteps()) + pass + + def testMEDField9(self): + # first test field profile WR. Full type but with some type missing + fname="Pyfile30.med" + m1=MEDLoaderDataForTest.build2DMesh_3() + mm1=MEDFileUMesh.New() ; mm1.setCoords(m1.getCoords()) ; mm1.setMeshAtLevel(0,m1) ; + mm1.write(fname,2) + ff1=MEDFileField1TS.New() + f1=MEDCouplingFieldDouble.New(ON_CELLS,ONE_TIME) ; f1.setName("F1") + d=DataArrayDouble.New() ; d.alloc(2*9,1) ; d.iota(7.); d.rearrange(2); d.setInfoOnComponent(0,"sigX [MPa]") ; d.setInfoOnComponent(1,"sigY [GPa]") + f1.setArray(d) # note that f1 is NOT defined fully (no mesh !). It is not a bug of test it is too test that MEDFileField1TS.appendFieldProfile is NOT sensible of that. + da=DataArrayInt.New(); da.alloc(9,1) ; da.iota(0) ; da.setName("sup1") + # + ff1.setFieldProfile(f1,mm1,0,da) + ff1.changePflsNames([(["sup1_NORM_QUAD4"],"ForV650")]) + ff1=ff1.deepCpy() + ff1.write(fname,0) + # + vals,pfl=ff1.getFieldWithProfile(ON_CELLS,0,mm1) ; vals.setName("") + self.assertTrue(pfl.isEqualWithoutConsideringStr(da))# profiles names cannot be contracted in pfl array name + self.assertTrue(vals.isEqual(d,1e-14)) + # + ff2=MEDFileField1TS.New(fname,f1.getName(),-1,-1) + ff3=MEDFileField1TS.New(fname,f1.getName(),-1,-1) + ff2.deepCpyGlobs(ff3) + sbt=ff2.getFieldSplitedByType2() + self.assertEqual(3,sbt[0][0])#TRI3 + self.assertEqual(0,sbt[0][1][0][0])#CELL For TRI3 + self.assertEqual("",sbt[0][1][0][2])#no profile For TRI3 + self.assertEqual([7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18],sbt[0][1][0][1].getValues())# values for TRI3 + self.assertEqual(4,sbt[1][0])#QUAD4 + self.assertEqual(0,sbt[1][1][0][0])#CELL For QUAD4 + self.assertEqual("ForV650",sbt[1][1][0][2])# profile For QUAD4 + self.assertEqual([19, 20, 21, 22, 23, 24],sbt[1][1][0][1].getValues())# values for QUAD4 + self.assertEqual([0],ff2.getTypesOfFieldAvailable()) + vals,pfl=ff2.getFieldWithProfile(ON_CELLS,0,mm1) ; vals.setName("") + self.assertTrue(pfl.isEqualWithoutConsideringStr(da)) + self.assertTrue(vals.isEqual(d,1e-14)) + pass + + def testMEDField10(self): + fname="Pyfile31.med" + m1=MEDLoaderDataForTest.build2DMesh_1() + m1.renumberCells([0,1,4,2,3,5],False) + mm1=MEDFileUMesh.New() ; mm1.setCoords(m1.getCoords()) ; mm1.setMeshAtLevel(0,m1) ; mm1.setName(m1.getName()) + mm1.write(fname,2) + ff1=MEDFileFieldMultiTS.New() + f1=MEDCouplingFieldDouble.New(ON_CELLS,ONE_TIME) ; f1.setName("F2") + d=DataArrayDouble.New() ; d.alloc(2*4,1) ; d.iota(7.); d.rearrange(2); d.setInfoOnComponent(0,"sigX [MPa]") ; d.setInfoOnComponent(1,"sigY [GPa]") + f1.setArray(d) # note that f1 is NOT defined fully (no mesh !). It is not a bug of test it is too test that MEDFileField1TS.appendFieldProfile is NOT sensible of that. + da=DataArrayInt.New(); da.setValues([0,1,2,4],4,1) ; da.setName("sup2") + # + ff1.appendFieldProfile(f1,mm1,0,da) + f1.setTime(1.2,1,2) ; e=d.applyFunc("2*x") ; e.copyStringInfoFrom(d) ; f1.setArray(e) ; + ff1.appendFieldProfile(f1,mm1,0,da) + ff1=ff1.deepCpy() + ff1.write(fname,0) + # + vals,pfl=ff1.getFieldWithProfile(ON_CELLS,1,2,0,mm1) ; vals.setName("") + self.assertTrue(pfl.isEqualWithoutConsideringStr(da)) + self.assertTrue(vals.isEqual(e,1e-14)) + vals,pfl=ff1.getFieldWithProfile(ON_CELLS,-1,-1,0,mm1) ; vals.setName("") + self.assertTrue(pfl.isEqualWithoutConsideringStr(da)) + self.assertTrue(vals.isEqual(d,1e-14)) + # + ff2=MEDFileFieldMultiTS.New(fname,f1.getName()) + self.assertEqual([(-1,-1,0.0), (1,2,1.2)],ff2.getTimeSteps()) + vals,pfl=ff2.getFieldWithProfile(ON_CELLS,1,2,0,mm1) ; vals.setName("") + self.assertTrue(pfl.isEqualWithoutConsideringStr(da)) + self.assertTrue(vals.isEqual(e,1e-14)) + vals,pfl=ff2.getFieldWithProfile(ON_CELLS,-1,-1,0,mm1) ; vals.setName("") + self.assertTrue(pfl.isEqualWithoutConsideringStr(da)) + self.assertTrue(vals.isEqual(d,1e-14)) + pass + + # idem testMEDField9 method except that here testing profile on nodes and not on cells. + def testMEDField11(self): + fname="Pyfile32.med" + m1=MEDLoaderDataForTest.build2DMesh_1() + m1.renumberCells([0,1,4,2,3,5],False) + mm1=MEDFileUMesh.New() ; mm1.setCoords(m1.getCoords()) ; mm1.setMeshAtLevel(0,m1) ; + mm1.write(fname,2) + ff1=MEDFileField1TS.New() + f1=MEDCouplingFieldDouble.New(ON_NODES,ONE_TIME) ; f1.setName("F1Node") + d=DataArrayDouble.New() ; d.alloc(2*6,1) ; d.iota(7.); d.rearrange(2); d.setInfoOnComponent(0,"sigX [MPa]") ; d.setInfoOnComponent(1,"sigY [GPa]") + f1.setArray(d) # note that f1 is NOT defined fully (no mesh !). It is not a bug of test it is too test that MEDFileField1TS.appendFieldProfile is NOT sensible of that. + da=DataArrayInt.New(); da.setValues([1,2,4,5,7,8],6,1) ; da.setName("sup1Node") + # + ff1.setFieldProfile(f1,mm1,0,da) + self.assertEqual(ff1.getNonEmptyLevels(),(-1, [])) + ff1.write(fname,0) + # + vals,pfl=ff1.getFieldWithProfile(ON_NODES,0,mm1) ; vals.setName("") + self.assertTrue(pfl.isEqualWithoutConsideringStr(da)) + self.assertTrue(vals.isEqual(d,1e-14)) + ## # + ff2=MEDFileField1TS.New(fname,f1.getName(),-1,-1) + vals,pfl=ff2.getFieldWithProfile(ON_NODES,0,mm1) ; vals.setName("") + self.assertTrue(pfl.isEqualWithoutConsideringStr(da)) + self.assertTrue(vals.isEqual(d,1e-14)) + pass + + def testMEDField12(self): + fname="Pyfile33.med" + m1=MEDLoaderDataForTest.build2DMesh_1() + m1.renumberCells([0,1,4,2,3,5],False) + mm1=MEDFileUMesh.New() ; mm1.setCoords(m1.getCoords()) ; mm1.setMeshAtLevel(0,m1) ; + mm1.write(fname,2) + ff1=MEDFileFieldMultiTS.New() + f1=MEDCouplingFieldDouble.New(ON_NODES,ONE_TIME) ; f1.setName("F1Node") + d=DataArrayDouble.New() ; d.alloc(2*6,1) ; d.iota(7.); d.rearrange(2); d.setInfoOnComponent(0,"sigX [MPa]") ; d.setInfoOnComponent(1,"sigY [GPa]") + f1.setArray(d) # note that f1 is NOT defined fully (no mesh !). It is not a bug of test it is too test that MEDFileField1TS.appendFieldProfile is NOT sensible of that. + da=DataArrayInt.New(); da.setValues([1,2,4,5,7,8],6,1) ; da.setName("sup1Node") + # + ff1.appendFieldProfile(f1,mm1,0,da) + f1.setTime(1.2,1,2) ; e=d.applyFunc("2*x") ; e.copyStringInfoFrom(d) ; f1.setArray(e) ; + ff1.appendFieldProfile(f1,mm1,0,da) + ff1.write(fname,0) + # + vals,pfl=ff1.getFieldWithProfile(ON_NODES,1,2,0,mm1) ; vals.setName("") + self.assertTrue(pfl.isEqualWithoutConsideringStr(da)) + self.assertTrue(vals.isEqual(e,1e-14)) + vals,pfl=ff1.getFieldWithProfile(ON_NODES,-1,-1,0,mm1) ; vals.setName("") + self.assertTrue(pfl.isEqualWithoutConsideringStr(da)) + self.assertTrue(vals.isEqual(d,1e-14)) + # + ff2=MEDFileFieldMultiTS.New(fname,f1.getName()) + vals,pfl=ff2.getFieldWithProfile(ON_NODES,1,2,0,mm1) ; vals.setName("") + self.assertTrue(pfl.isEqualWithoutConsideringStr(da)) + self.assertTrue(vals.isEqual(e,1e-14)) + vals,pfl=ff2.getFieldWithProfile(ON_NODES,-1,-1,0,mm1) ; vals.setName("") + self.assertTrue(pfl.isEqualWithoutConsideringStr(da)) + self.assertTrue(vals.isEqual(d,1e-14)) + pass + + def testMEDField13(self): + fname="Pyfile34.med" + m1=MEDLoaderDataForTest.build2DMesh_1() + m1.renumberCells([0,1,4,2,3,5],False) + tmp=m1.getName(); + m1=m1.buildPartOfMySelf(range(5),True) ; m1.setName(tmp) # suppression of last cell that is a polygon + mm1=MEDFileUMesh.New() ; mm1.setCoords(m1.getCoords()) ; mm1.setMeshAtLevel(0,m1) ; + mm1.write(fname,2) + ff1=MEDFileField1TS.New() + f1=MEDCouplingFieldDouble.New(ON_GAUSS_NE,ONE_TIME) ; f1.setName("F3Node") + d=DataArrayDouble.New() ; d.alloc(2*11,1) ; d.iota(7.); d.rearrange(2); d.setInfoOnComponent(0,"sigX [MPa]") ; d.setInfoOnComponent(1,"sigY [GPa]") + f1.setArray(d) # note that f1 is NOT defined fully (no mesh !). It is not a bug of test it is too test that MEDFileField1TS.appendFieldProfile is NOT sensible of that. + da=DataArrayInt.New(); da.setValues([0,2,3],3,1) ; da.setName("sup1NodeElt") + # + ff1.setFieldProfile(f1,mm1,0,da) + ff1.write(fname,0) + # + vals,pfl=ff1.getFieldWithProfile(ON_GAUSS_NE,0,mm1) ; vals.setName("") + self.assertTrue(pfl.isEqualWithoutConsideringStr(da)) + self.assertTrue(vals.isEqual(d,1e-14)) + # + ff2=MEDFileField1TS.New(fname,f1.getName(),-1,-1) + vals,pfl=ff2.getFieldWithProfile(ON_GAUSS_NE,0,mm1) ; vals.setName("") + self.assertTrue(pfl.isEqualWithoutConsideringStr(da)) + self.assertTrue(vals.isEqual(d,1e-14)) + pass + + def testMEDField14(self): + fname="Pyfile35.med" + m1=MEDLoaderDataForTest.build2DMesh_1() + m1.renumberCells([0,1,4,2,3,5],False) + tmp=m1.getName(); + m1=m1.buildPartOfMySelf(range(5),True) ; m1.setName(tmp) # suppression of last cell that is a polygon + mm1=MEDFileUMesh.New() ; mm1.setCoords(m1.getCoords()) ; mm1.setMeshAtLevel(0,m1) ; + mm1.write(fname,2) + ff1=MEDFileFieldMultiTS.New() + f1=MEDCouplingFieldDouble.New(ON_GAUSS_NE,ONE_TIME) ; f1.setName("F4Node") + d=DataArrayDouble.New() ; d.alloc(2*11,1) ; d.iota(7.); d.rearrange(2); d.setInfoOnComponent(0,"sigX [MPa]") ; d.setInfoOnComponent(1,"sigY [GPa]") + f1.setArray(d) # note that f1 is NOT defined fully (no mesh !). It is not a bug of test it is too test that MEDFileField1TS.appendFieldProfile is NOT sensible of that. + da=DataArrayInt.New(); da.setValues([0,2,3],3,1) ; da.setName("sup1NodeElt") + # + ff1.appendFieldProfile(f1,mm1,0,da) + f1.setTime(1.2,1,2) ; e=d.applyFunc("2*x") ; e.copyStringInfoFrom(d) ; f1.setArray(e) ; + ff1.appendFieldProfile(f1,mm1,0,da) + ff1.write(fname,0) + # + vals,pfl=ff1.getFieldWithProfile(ON_GAUSS_NE,-1,-1,0,mm1) ; vals.setName("") + self.assertTrue(pfl.isEqualWithoutConsideringStr(da)) + self.assertTrue(vals.isEqual(d,1e-14)) + vals,pfl=ff1.getFieldWithProfile(ON_GAUSS_NE,1,2,0,mm1) ; vals.setName("") + self.assertTrue(pfl.isEqualWithoutConsideringStr(da)) + self.assertTrue(vals.isEqual(e,1e-14)) + self.assertEqual([[3],[3]],ff1.getTypesOfFieldAvailable()) + # + ff2=MEDFileFieldMultiTS.New(fname,f1.getName()) + vals,pfl=ff1.getFieldWithProfile(ON_GAUSS_NE,-1,-1,0,mm1) ; vals.setName("") + self.assertTrue(pfl.isEqualWithoutConsideringStr(da)) + self.assertTrue(vals.isEqual(d,1e-14)) + vals,pfl=ff1.getFieldWithProfile(ON_GAUSS_NE,1,2,0,mm1) ; vals.setName("") + self.assertTrue(pfl.isEqualWithoutConsideringStr(da)) + self.assertTrue(vals.isEqual(e,1e-14)) + pass + # Tricky test of the case of in a MED file containing a Field on GAUSS_NE is lying on a profile that is reality represents all the geom entities of a level. + # By default when using setFieldProfile method such profile is not created because it is not useful ! So here a trick is used to force MEDLoader to do that + # for the necessity of the test ! The idea is too create artificially a mesh having one more fictious cell per type and to roll back right after ! + def testMEDField15(self): + fname="Pyfile36.med" + m0=MEDLoaderDataForTest.build2DMesh_1() + m0.renumberCells([0,1,4,2,3,5],False) + tmp=m0.getName(); + m1=m0.buildPartOfMySelf([0,1,1,2,3,3,4,4],True) ; m1.setName(tmp) # suppression of last cell that is a polygon and creation of one more cell per type + mm1=MEDFileUMesh.New() ; mm1.setCoords(m1.getCoords()) ; mm1.setMeshAtLevel(0,m1) ; + ff1=MEDFileField1TS.New() + f1=MEDCouplingFieldDouble.New(ON_GAUSS_NE,ONE_TIME) ; f1.setName("F4Node") + d=DataArrayDouble.New() ; d.alloc(2*20,1) ; d.iota(7.); d.rearrange(2); d.setInfoOnComponent(0,"sigX [MPa]") ; d.setInfoOnComponent(1,"sigY [GPa]") + f1.setArray(d) # note that f1 is NOT defined fully (no mesh !). It is not a bug of test it is too test that MEDFileField1TS.appendFieldProfile is NOT sensible of that. + da=DataArrayInt.New(); da.setValues([0,1,3,4,6],5,1) ; da.setName("sup1NodeElt") + # + ff1.setFieldProfile(f1,mm1,0,da) + m1=m0.buildPartOfMySelf(range(5),True) ; m1.setName(tmp) ; mm1.setMeshAtLevel(0,m1) ; + mm1.write(fname,2) + ff1.write(fname,0) + f1=ff1.getFieldOnMeshAtLevel(ON_GAUSS_NE,m1,0) + f2,p1=ff1.getFieldWithProfile(ON_GAUSS_NE,0,mm1) ; f2.setName("") + self.assertTrue(p1.isIdentity()) + self.assertEqual(5,p1.getNumberOfTuples()) + self.assertTrue(f1.getArray().isEqual(f2,1e-12)) + pass + # Test for getFieldAtTopLevel method + def testMEDField16(self): + fname="Pyfile37.med" + f1=MEDLoaderDataForTest.buildVecFieldOnCells_1(); + m1=f1.getMesh() + mm1=MEDFileUMesh.New() + mm1.setCoords(m1.getCoords()) + mm1.setMeshAtLevel(0,m1) + mm1.setName(m1.getName()) + ff1=MEDFileField1TS.New() + ff1.setFieldNoProfileSBT(f1) + m2=m1.buildDescendingConnectivity()[0] + m2.sortCellsInMEDFileFrmt() + m2.setName(m1.getName()) + mm1.setMeshAtLevel(-1,m2) + mm1.write(fname,2) + f2=m2.getMeasureField(True) + dd=DataArrayDouble.New() + dd.alloc(f2.getArray().getNumberOfTuples(),3) + dd[:,0]=f2.getArray() + dd[:,1]=2*f2.getArray() + dd[:,2]=3*f2.getArray() + f2=f2.buildNewTimeReprFromThis(ONE_TIME,False) + f2.setArray(dd) + f2.copyTinyStringsFrom(f1) + f2.copyTinyAttrFrom(f1) + ff1.setFieldNoProfileSBT(f2) + ff1.write(fname,0) + # Reading Pyfile37.med + ff2=MEDFileField1TS.New(fname,f2.getName(),0,1) + f1bis=ff2.getFieldAtLevel(ON_CELLS,0) + self.assertTrue(f1.isEqual(f1bis,1e-12,1e-12)) + f1bis=ff2.getFieldAtLevel(ON_CELLS,-1) + self.assertTrue(f2.isEqual(f1bis,1e-12,1e-12)) + f1bis=ff2.getFieldAtTopLevel(ON_CELLS) + self.assertTrue(f1.isEqual(f1bis,1e-12,1e-12)) + # More complex + fname="Pyfile38.med" + mm1.write(fname,2) + ff1=MEDFileField1TS.New() + ff1.setFieldNoProfileSBT(f2) + ff1.write(fname,0) + ff2=MEDFileField1TS.New(fname,f2.getName(),0,1) + f1bis=ff2.getFieldAtTopLevel(ON_CELLS) + self.assertTrue(f2.isEqual(f1bis,1e-12,1e-12)) + pass + + # Non regression test to check that globals are correctly appended on MEDFileFields::setFieldAtPos + def testMEDField17(self): + fname="Pyfile39.med" + m1=MEDLoaderDataForTest.build2DMesh_1() + m1.renumberCells([0,1,4,2,3,5],False) + mm1=MEDFileUMesh.New() ; mm1.setCoords(m1.getCoords()) ; mm1.setMeshAtLevel(0,m1) ; mm1.setName(m1.getName()) + mm1.write(fname,2) + ffs=MEDFileFields.New() + ff1=MEDFileFieldMultiTS.New() + f1=MEDCouplingFieldDouble.New(ON_CELLS,ONE_TIME) ; f1.setName("F2") + d=DataArrayDouble.New() ; d.alloc(2*4,1) ; d.iota(7.); d.rearrange(2); d.setInfoOnComponent(0,"sigX [MPa]") ; d.setInfoOnComponent(1,"sigY [GPa]") + f1.setArray(d) # note that f1 is NOT defined fully (no mesh !). It is not a bug of test it is too test that MEDFileField1TS.appendFieldProfile is NOT sensible of that. + da=DataArrayInt.New(); da.setValues([0,1,2,4],4,1) ; da.setName("sup2") + # + ff1.appendFieldProfile(f1,mm1,0,da) + f1.setTime(1.2,1,2) ; e=d.applyFunc("2*x") ; e.copyStringInfoFrom(d) ; f1.setArray(e) ; + ff1.appendFieldProfile(f1,mm1,0,da) + ffs.resize(1) + ffs.setFieldAtPos(0,ff1) + ffs=ffs.deepCpy() + ffs.write(fname,0) + # + ffsr=MEDFileFields.New(fname) + ff3=ffsr.getFieldAtPos(0) + f4=ff3.getFieldAtTopLevel(ON_CELLS,1,2) + self.assertTrue(f4.getArray().isEqual(f1.getArray(),1e-12)) + pass + + # Non regression test to check that globals are correctly appended on MEDFileFields::setFieldAtPos + def testMEDField18(self): + fname="Pyfile40.med" + m1=MEDLoaderDataForTest.build2DMesh_1() + m1.renumberCells([0,1,4,2,3,5],False) + mm1=MEDFileUMesh.New() ; mm1.setCoords(m1.getCoords()) ; mm1.setMeshAtLevel(0,m1) ; mm1.setName(m1.getName()) + mm1.write(fname,2) + ffs=MEDFileFields.New() + ff1=MEDFileFieldMultiTS.New() + f1=MEDCouplingFieldDouble.New(ON_CELLS,ONE_TIME) ; f1.setName("F2") + d=DataArrayDouble.New() ; d.alloc(2*4,1) ; d.iota(7.); d.rearrange(2); d.setInfoOnComponent(0,"sigX [MPa]") ; d.setInfoOnComponent(1,"sigY [GPa]") + f1.setArray(d) # note that f1 is NOT defined fully (no mesh !). It is not a bug of test it is too test that MEDFileField1TS.appendFieldProfile is NOT sensible of that. + da=DataArrayInt.New(); da.setValues([0,1,2,4],4,1) ; da.setName("sup2") + # + ff1.appendFieldProfile(f1,mm1,0,da) + f1.setTime(1.2,1,2) ; e=d.applyFunc("2*x") ; e.copyStringInfoFrom(d) ; f1.setArray(e) ; + ff1.appendFieldProfile(f1,mm1,0,da) + ffs.pushField(ff1) + ffs.write(fname,0) + # + ffsr=MEDFileFields.New(fname) + ff3=ffsr.getFieldAtPos(0) + f4=ff3.getFieldAtTopLevel(ON_CELLS,1,2) + self.assertTrue(f4.getArray().isEqual(f1.getArray(),1e-12)) + pass + + def testMEDFieldBug1(self): + fname="Pyfile13.med" + d=MEDFileData.New(fname) + self.assertEqual(('Loc_MyFirstFieldOnGaussPoint_NORM_QUAD4_1','Loc_MyFirstFieldOnGaussPoint_NORM_TRI3_0','Loc_MyFirstFieldOnGaussPoint_NORM_TRI6_2'),d.getFields().getFieldAtPos(0).getLocs()) + pass + + def testMEDMesh8(self): + m=MEDLoaderDataForTest.build1DMesh_1() + m.convertQuadraticCellsToLinear() + mm=MEDFileUMesh.New() + mm.setMeshAtLevel(0,m) + g1=DataArrayInt.New() ; g1.setValues([0,2],2,1) ; g1.setName("g1") + g2=DataArrayInt.New() ; g2.setValues([1,3],2,1) ; g2.setName("g2") + g3=DataArrayInt.New() ; g3.setValues([1,2,3],3,1) ; g3.setName("g3") + mm.setGroupsAtLevel(0,[g1,g2],False) + self.assertEqual(('g1','g2'),mm.getGroupsNames()) + self.assertEqual(('Family_-2','Family_-3'),mm.getFamiliesNames()) + self.assertEqual(('Family_-2',),mm.getFamiliesOnGroup('g1')) + self.assertEqual(('Family_-3',),mm.getFamiliesOnGroup('g2')) + mm.assignFamilyNameWithGroupName() + self.assertEqual(('g1','g2'),mm.getGroupsNames()) + self.assertEqual(('g1','g2'),mm.getFamiliesNames()) + self.assertEqual(('g1',),mm.getFamiliesOnGroup('g1')) + self.assertEqual(('g2',),mm.getFamiliesOnGroup('g2')) + # + mm=MEDFileUMesh.New() + mm.setMeshAtLevel(0,m) + mm.setGroupsAtLevel(0,[g1,g2,g3],False) + self.assertEqual(('g1','g2','g3'),mm.getGroupsNames()) + self.assertEqual(('Family_-2', 'Family_-4', 'Family_-5'),mm.getFamiliesNames()) + self.assertEqual(('Family_-2', 'Family_-4'),mm.getFamiliesOnGroup('g1')) + self.assertEqual(('Family_-5',),mm.getFamiliesOnGroup('g2')) + self.assertEqual(('Family_-4','Family_-5',),mm.getFamiliesOnGroup('g3')) + mm.assignFamilyNameWithGroupName() # here it does nothing because no such group-family bijection found + self.assertEqual(('g1','g2','g3'),mm.getGroupsNames()) + self.assertEqual(('Family_-2', 'Family_-4', 'Family_-5'),mm.getFamiliesNames()) + self.assertEqual(('Family_-2', 'Family_-4'),mm.getFamiliesOnGroup('g1')) + self.assertEqual(('Family_-5',),mm.getFamiliesOnGroup('g2')) + self.assertEqual(('Family_-4','Family_-5',),mm.getFamiliesOnGroup('g3')) + mm.changeFamilyId(5,6) + g=mm.getGroupArr(0,"g3") + self.assertTrue(g.isEqual(g3)); + g=mm.getGroupArr(0,"g2") + self.assertTrue(g.isEqual(g2)); + g=mm.getGroupArr(0,"g1") + self.assertTrue(g.isEqual(g1)); + pass + + # bug detected by gauthier + def testMEDLoaderMEDLoaderNSReadFieldDoubleDataInMedFile(self): + fname="Pyfile41.med" + f1=MEDLoaderDataForTest.buildVecFieldOnCells_1(); + m1=f1.getMesh() + mm1=MEDFileUMesh.New() + mm1.setCoords(m1.getCoords()) + mm1.setMeshAtLevel(0,m1) + mm1.write(fname,2) + ff1=MEDFileField1TS.New() + ff1.setFieldNoProfileSBT(f1) + ff1.write(fname,0) + # writing mesh1 and field1, now creation of mesh2 and field2 + f2=f1.deepCpy() + m2=f2.getMesh() + m2.translate([0.5,0.6,0.7]) + m2.setName("3DSurfMesh_2") + f2.getArray()[:]*=2. + f2.setName("VectorFieldOnCells2") + mm2=MEDFileUMesh.New() + mm2.setCoords(m2.getCoords()) + mm2.setMeshAtLevel(0,m2) + mm2.write(fname,0) + ff2=MEDFileField1TS.New() + ff2.setFieldNoProfileSBT(f2) + ff2.write(fname,0) + # + f3=MEDLoader.ReadFieldCell(fname,"3DSurfMesh_1",0,"VectorFieldOnCells",0,1) + self.assertTrue(f3.isEqual(f1,1e-12,1e-12)) + f4=MEDLoader.ReadFieldCell(fname,"3DSurfMesh_2",0,"VectorFieldOnCells2",0,1) + self.assertTrue(f4.isEqual(f2,1e-12,1e-12)) + pass + + def testMEDLoaderMultiLevelCellField1(self): + fname="Pyfile42.med" + m2,m1,m0,f2,f1,f0,p,n2,n1,n0,fns,fids,grpns,famIdsPerGrp=MEDLoaderDataForTest.buildMultiLevelMesh_1() + m=MEDFileUMesh.New() + m.setCoords(m2.getCoords()) + m.setMeshAtLevel(0,m2) + m.setMeshAtLevel(-1,m1) + m.setMeshAtLevel(-2,m0) + m.write(fname,2) + # + FieldName1="Field1" + compNames1=["comp1","comp2","comp3"] + ff1=MEDFileField1TS.New() + da2=DataArrayDouble.New() + da2.alloc(m2.getNumberOfCells()*len(compNames1),1) + da2.iota(7.) + da2.rearrange(len(compNames1)) + da2.setInfoOnComponents(compNames1) + f2=MEDCouplingFieldDouble.New(ON_CELLS,ONE_TIME) ; f2.setName(FieldName1) ; f2.setArray(da2) ; f2.setMesh(m2) ; f2.checkCoherency() + ff1.setFieldNoProfileSBT(f2) + self.assertEqual(ff1.getNonEmptyLevels(),(2, [0])) + da0=DataArrayDouble.New() + da0.alloc(m0.getNumberOfCells()*len(compNames1),1) + da0.iota(190.) + da0.rearrange(len(compNames1)) + da0.setInfoOnComponents(compNames1) + f0=MEDCouplingFieldDouble.New(ON_CELLS,ONE_TIME) ; f0.setName(FieldName1) ; f0.setArray(da0) ; f0.setMesh(m0) ; f0.checkCoherency() + ff1.setFieldNoProfileSBT(f0) + self.assertEqual(ff1.getNonEmptyLevels(),(2, [0,-2])) + da1=DataArrayDouble.New() + da1.alloc(m1.getNumberOfCells()*len(compNames1),1) + da1.iota(90.) + da1.rearrange(len(compNames1)) + da1.setInfoOnComponents(compNames1) + f1=MEDCouplingFieldDouble.New(ON_CELLS,ONE_TIME) ; f1.setName(FieldName1) ; f1.setArray(da1) ; f1.setMesh(m1) ; f1.checkCoherency() + ff1.setFieldNoProfileSBT(f1) + self.assertEqual(ff1.getNonEmptyLevels(),(2, [0,-1,-2])) + # + ff1.write(fname,0) + # + FieldName2="Field2" + compNames2=["comp11","comp22"] + ff2=MEDFileField1TS.New() + da0=DataArrayDouble.New() + da0.alloc(m0.getNumberOfCells()*2,1) + da0.iota(-190.) + da0.rearrange(2) + da0.setInfoOnComponents(compNames2) + f0=MEDCouplingFieldDouble.New(ON_CELLS,ONE_TIME) ; f0.setName(FieldName2) ; f0.setArray(da0) ; f0.setMesh(m0) ; f0.checkCoherency() + ff2.setFieldNoProfileSBT(f0) + self.assertEqual(ff2.getNonEmptyLevels(),(0, [0])) + da1=DataArrayDouble.New() + da1.alloc(m1.getNumberOfCells()*len(compNames2),1) + da1.iota(-90.) + da1.rearrange(len(compNames2)) + da1.setInfoOnComponents(compNames2) + f1=MEDCouplingFieldDouble.New(ON_CELLS,ONE_TIME) ; f1.setName(FieldName2) ; f1.setArray(da1) ; f1.setMesh(m1) ; f1.checkCoherency() + ff2.setFieldNoProfileSBT(f1) + self.assertEqual(ff2.getNonEmptyLevels(),(1, [0,-1])) + # + ff2.write(fname,0) + # + ff1=MEDFileField1TS.New(fname,FieldName1,-1,-1) + self.assertEqual(ff1.getNonEmptyLevels(),(2, [0,-1,-2])) + self.assertEqual(ff1.getFieldSplitedByType(),[(0, [(0, (0, 4), '', '')]), (1, [(0, (4, 84), '', '')]), (3, [(0, (84, 148), '', '')]), (4, [(0, (148, 212), '', '')])]) + ff2=MEDFileField1TS.New(fname,FieldName2,-1,-1) + self.assertEqual(ff2.getNonEmptyLevels(),(1, [0,-1])) + self.assertEqual(ff2.getFieldSplitedByType(),[(0, [(0, (0, 4), '', '')]), (1, [(0, (4, 84), '', '')])]) + pass + + def testFieldOnPflRetrieveOnMdimRelMax1(self): + fname="Pyfile43.med" + m2,m1,m0,f2,f1,f0,p,n2,n1,n0,fns,fids,grpns,famIdsPerGrp=MEDLoaderDataForTest.buildMultiLevelMesh_1() + m=MEDFileUMesh.New() + m.setMeshAtLevel(0,m2) + m.setMeshAtLevel(-1,m1) + m.setMeshAtLevel(-2,m0) + f=MEDFileField1TS.New() + ff=MEDCouplingFieldDouble.New(ON_NODES,ONE_TIME) + ff.setName("NodeFieldPfl") + arr=DataArrayDouble.New() ; arr.setValues([1.,10.,100.,2.,20.,200.],2,3) + ff.setArray(arr) + pfl=DataArrayInt.New() ; pfl.setValues([2,3],2,1) ; pfl.setName("PflNode") + f.setFieldProfile(ff,m,-2,pfl) + tes0=f.getFieldOnMeshAtLevel(ON_NODES,-1,m) + self.assertEqual(ON_NODES,tes0.getTypeOfField()) + self.assertEqual(1,tes0.getMesh().getMeshDimension()) + self.assertEqual(1,tes0.getMesh().getNumberOfCells()) + self.assertEqual(2,tes0.getMesh().getNumberOfNodes()) + self.assertEqual([1,0,1],tes0.getMesh().getNodalConnectivity().getValues()) + self.assertEqual([0,3],tes0.getMesh().getNodalConnectivityIndex().getValues()) + self.assertEqual(2,tes0.getArray().getNumberOfTuples()) + self.assertEqual(3,tes0.getArray().getNumberOfComponents()) + expected1=[1.,10.,100.,2.,20.,200.] + nodeCoordsWithValue1=[10.,2.5,0.] + nodeCoordsWithValue2=[10.,3.75,0.] + for i in xrange(3): + self.assertAlmostEqual(nodeCoordsWithValue1[i],tes0.getMesh().getCoordinatesOfNode(0)[i],13); + self.assertAlmostEqual(nodeCoordsWithValue2[i],tes0.getMesh().getCoordinatesOfNode(1)[i],13); + pass + for i in xrange(6): + self.assertAlmostEqual(expected1[i],tes0.getArray().getIJ(0,i),13); + pass + del tes0 + # + tes1=f.getFieldOnMeshAtLevel(ON_NODES,1,m) + self.assertEqual(ON_CELLS,tes1.getTypeOfField())# it is not a bug even if ON_NODES has been sepecified + self.assertEqual(0,tes1.getMesh().getMeshDimension()) + self.assertEqual(2,tes1.getMesh().getNumberOfCells()) + self.assertEqual(135,tes1.getMesh().getNumberOfNodes()) + self.assertEqual([0,2,0,3],tes1.getMesh().getNodalConnectivity().getValues()) + self.assertEqual([0,2,4],tes1.getMesh().getNodalConnectivityIndex().getValues()) + self.assertEqual(2,tes1.getArray().getNumberOfTuples()) + self.assertEqual(3,tes1.getArray().getNumberOfComponents()) + for i in xrange(6): + self.assertAlmostEqual(expected1[i],tes1.getArray().getIJ(0,i),13); + pass + m.write(fname,2) + f.write(fname,0) + # + pfl=DataArrayInt.New() ; pfl.setValues([3,2],2,1) ; pfl.setName("PflNode") + f=MEDFileField1TS.New() + f.setFieldProfile(ff,m,-2,pfl) + tes2=f.getFieldOnMeshAtLevel(ON_NODES,-1,m) + self.assertEqual(ON_NODES,tes2.getTypeOfField()) + self.assertEqual(1,tes2.getMesh().getMeshDimension()) + self.assertEqual(1,tes2.getMesh().getNumberOfCells()) + self.assertEqual(2,tes2.getMesh().getNumberOfNodes()) + self.assertEqual([1,0,1],tes2.getMesh().getNodalConnectivity().getValues()) + self.assertEqual([0,3],tes2.getMesh().getNodalConnectivityIndex().getValues()) + self.assertEqual(2,tes2.getArray().getNumberOfTuples()) + self.assertEqual(3,tes2.getArray().getNumberOfComponents()) + expected2=[2.,20.,200.,1.,10.,100.] + for i in xrange(3): + self.assertAlmostEqual(nodeCoordsWithValue1[i],tes2.getMesh().getCoordinatesOfNode(0)[i],13); + self.assertAlmostEqual(nodeCoordsWithValue2[i],tes2.getMesh().getCoordinatesOfNode(1)[i],13); + pass + for i in xrange(6): + self.assertAlmostEqual(expected2[i],tes2.getArray().getIJ(0,i),13);#compare tes2 and tes3 + pass + # + tes3=f.getFieldOnMeshAtLevel(ON_NODES,1,m) + self.assertEqual(ON_CELLS,tes3.getTypeOfField())# it is not a bug even if ON_NODES has been sepecified + self.assertEqual(0,tes3.getMesh().getMeshDimension()) + self.assertEqual(2,tes3.getMesh().getNumberOfCells()) + self.assertEqual(135,tes3.getMesh().getNumberOfNodes()) + self.assertEqual([0,3,0,2],tes3.getMesh().getNodalConnectivity().getValues()) + self.assertEqual([0,2,4],tes3.getMesh().getNodalConnectivityIndex().getValues()) + self.assertEqual(2,tes3.getArray().getNumberOfTuples()) + self.assertEqual(3,tes3.getArray().getNumberOfComponents()) + for i in xrange(6): + self.assertAlmostEqual(expected1[i],tes3.getArray().getIJ(0,i),13); + pass + pass + + def testBuildInnerBoundaryAlongM1Group1(self): + fname="Pyfile44.med" + m=MEDCouplingCMesh.New() + m.setCoordsAt(0,DataArrayDouble.New([0.,1.1,2.3,3.6,5.,6.5])) + m.setCoordsAt(1,DataArrayDouble.New([0.,1.1,2.3,3.6,5.])) + m=m.buildUnstructured() ; m.setName("AnthonyDuplicate") + m.getCoords().setInfoOnComponents(["X [km]","Z [mm]"]) + m2=m.buildDescendingConnectivity()[0][[8,11,14,20,21,22,23,24,25,26,31,32,33,34,35,36,37]] + m2.setName(m.getName()) + grp=DataArrayInt.New([4,6,8]) ; grp.setName("Grp") + grp2=DataArrayInt.New([9,16]) ; grp2.setName("Grp2") + mm=MEDFileUMesh.New() + mm.setMeshAtLevel(0,m) + mm.setMeshAtLevel(-1,m2) + mm.setGroupsAtLevel(-1,[grp,grp2]) + grpNode=DataArrayInt.New([4,21,23]) ; grpNode.setName("GrpNode") + mm.setGroupsAtLevel(1,[grpNode]) + ref0=[4,15,14,20,21,4,16,15,21,22,4,17,16,22,23] + ref1=[4,9,8,14,15,4,10,9,15,16,4,11,10,16,17] + ref2=[4,9,8,14,30,4,10,9,30,31,4,11,10,31,32] + # + self.assertEqual(30,mm.getNumberOfNodes()) + self.assertEqual(ref0,mm.getMeshAtLevel(0)[[12,13,14]].getNodalConnectivity().getValues()) + self.assertEqual(ref1,mm.getMeshAtLevel(0)[[7,8,9]].getNodalConnectivity().getValues()) + # + nodes,cells,cells2=mm.buildInnerBoundaryAlongM1Group("Grp") + self.assertEqual([15,16,17],nodes.getValues()); + self.assertEqual([7,8,9],cells.getValues()); + self.assertEqual([12,13,14],cells2.getValues()); + self.assertEqual(33,mm.getNumberOfNodes()) + self.assertEqual([4,6,8],mm.getGroupArr(-1,"Grp").getValues()) + self.assertEqual([9,16],mm.getGroupArr(-1,"Grp2").getValues()) + self.assertEqual([4,21,23],mm.getGroupArr(1,"GrpNode").getValues()) + self.assertEqual([17,18,19],mm.getGroupArr(-1,"Grp_dup").getValues()) + self.assertEqual(ref0,mm.getMeshAtLevel(0)[[12,13,14]].getNodalConnectivity().getValues())#cells 7,8,9 and 12,13,14 are lying on "Grp" but only 7,8 and 9 are renumbered + self.assertEqual(ref2,mm.getMeshAtLevel(0)[[7,8,9]].getNodalConnectivity().getValues())# + self.assertRaises(InterpKernelException,mm.getGroup(-1,"Grp_dup").checkGeoEquivalWith,mm.getGroup(-1,"Grp"),2,1e-12);# Grp_dup and Grp are not equal considering connectivity only + mm.getGroup(-1,"Grp_dup").checkGeoEquivalWith(mm.getGroup(-1,"Grp"),12,1e-12)# Grp_dup and Grp are equal considering connectivity and coordinates + refValues=DataArrayDouble.New([1.21,1.32,1.43,1.54,1.65,1.32,1.44,1.56,1.68,1.8,1.43,1.56,1.69,1.82,1.95,1.54,1.68,1.82,1.96,2.1]) + valsToTest=mm.getMeshAtLevel(0).getMeasureField(True).getArray() ; delta=(valsToTest-refValues) ; delta.abs() + self.assertTrue(delta.getMaxValue()[0]<1e-12) + # + mm.getCoords()[-len(nodes):]+=[0.,-0.3] + self.assertRaises(InterpKernelException,mm.getGroup(-1,"Grp_dup").checkGeoEquivalWith,mm.getGroup(-1,"Grp"),12,1e-12); + refValues2=refValues[:] ; refValues2[7:10]=[1.365,1.26,1.35] + valsToTest=mm.getMeshAtLevel(0).getMeasureField(True).getArray() ; delta=(valsToTest-refValues2) ; delta.abs() + self.assertTrue(delta.getMaxValue()[0]<1e-12) + mm.write(fname,2) + pass + + def testBuildInnerBoundaryAlongM1Group2(self): + fname="Pyfile45.med" + m=MEDCouplingCMesh.New() + m.setCoordsAt(0,DataArrayDouble.New([0.,1.1,2.3,3.6,5.,6.5])) + m.setCoordsAt(1,DataArrayDouble.New([0.,1.1,2.3,3.6,5.])) + m=m.buildUnstructured() ; m.setName("AnthonyDuplicate") + m.getCoords().setInfoOnComponents(["X [km]","Z [mm]"]) + m2=m.buildDescendingConnectivity()[0][[8,11,14,20,21,22,23,24,25,26,31,32,33,34,35,36,37]] + m2.setName(m.getName()) + grp=DataArrayInt.New([4,6]) ; grp.setName("Grp") + grp2=DataArrayInt.New([9,16]) ; grp2.setName("Grp2") + mm=MEDFileUMesh.New() + mm.setMeshAtLevel(0,m) + mm.setMeshAtLevel(-1,m2) + mm.setGroupsAtLevel(-1,[grp,grp2]) + grpNode=DataArrayInt.New([4,21,23]) ; grpNode.setName("GrpNode") + mm.setGroupsAtLevel(1,[grpNode]) + ref0=[4,15,14,20,21,4,16,15,21,22,4,17,16,22,23] + ref1=[4,9,8,14,15,4,10,9,15,16] + ref2=[4,9,8,14,30,4,10,9,30,16] + # + self.assertEqual(30,mm.getNumberOfNodes()) + self.assertEqual(ref0,mm.getMeshAtLevel(0)[[12,13,14]].getNodalConnectivity().getValues()) + self.assertEqual(ref1,mm.getMeshAtLevel(0)[[7,8]].getNodalConnectivity().getValues()) + # + nodes,cells,cells2=mm.buildInnerBoundaryAlongM1Group("Grp") + self.assertEqual([15],nodes.getValues()); + self.assertEqual([7,8],cells.getValues()); + self.assertEqual([12,13],cells2.getValues()); + self.assertEqual(31,mm.getNumberOfNodes()) + self.assertEqual([4,6],mm.getGroupArr(-1,"Grp").getValues()) + self.assertEqual([9,16],mm.getGroupArr(-1,"Grp2").getValues()) + self.assertEqual([4,21,23],mm.getGroupArr(1,"GrpNode").getValues()) + self.assertEqual([17,18],mm.getGroupArr(-1,"Grp_dup").getValues()) + self.assertEqual(ref0,mm.getMeshAtLevel(0)[[12,13,14]].getNodalConnectivity().getValues())#cells 7,8,9 and 12,13,14 are lying on "Grp" but only 7,8 and 9 are renumbered + self.assertEqual(ref2,mm.getMeshAtLevel(0)[[7,8]].getNodalConnectivity().getValues())# + self.assertRaises(InterpKernelException,mm.getGroup(-1,"Grp_dup").checkGeoEquivalWith,mm.getGroup(-1,"Grp"),2,1e-12);# Grp_dup and Grp are not equal considering connectivity only + mm.getGroup(-1,"Grp_dup").checkGeoEquivalWith(mm.getGroup(-1,"Grp"),12,1e-12)# Grp_dup and Grp are equal considering connectivity and coordinates + refValues=DataArrayDouble.New([1.21,1.32,1.43,1.54,1.65,1.32,1.44,1.56,1.68,1.8,1.43,1.56,1.69,1.82,1.95,1.54,1.68,1.82,1.96,2.1]) + valsToTest=mm.getMeshAtLevel(0).getMeasureField(True).getArray() ; delta=(valsToTest-refValues) ; delta.abs() + self.assertTrue(delta.getMaxValue()[0]<1e-12) + # + mm.getCoords()[-len(nodes):]+=[0.,-0.3] + self.assertRaises(InterpKernelException,mm.getGroup(-1,"Grp_dup").checkGeoEquivalWith,mm.getGroup(-1,"Grp"),12,1e-12); + refValues2=refValues[:] ; refValues2[7:9]=[1.365,1.47] + valsToTest=mm.getMeshAtLevel(0).getMeasureField(True).getArray() ; delta=(valsToTest-refValues2) ; delta.abs() + self.assertTrue(delta.getMaxValue()[0]<1e-12) + mm.write(fname,2) + pass + + def testBuildInnerBoundaryAlongM1Group3(self): + """ Test buildInnerBoundaryAlongM1Group() with *non-connex* cracks """ + fname = "Pyfile73.med" + m = MEDCouplingCMesh.New() + m.setCoordsAt(0, DataArrayDouble([0.0,1.1,2.3,3.6,5.0])) + m.setCoordsAt(1, DataArrayDouble([0.,1.,2.])) + m = m.buildUnstructured(); m.setName("simple") + m2 = m.buildDescendingConnectivity()[0] + m2.setName(m.getName()) + + # A crack in two non connected parts of the mesh: + grpSeg = DataArrayInt([3,19]) ; grpSeg.setName("Grp") + + mm = MEDFileUMesh.New() + mm.setMeshAtLevel(0,m) + mm.setMeshAtLevel(-1,m2) + mm.setGroupsAtLevel(-1,[grpSeg]) + nodes, cellsMod, cellsNotMod = mm.buildInnerBoundaryAlongM1Group("Grp") + self.assertEqual([1,13],nodes.getValues()); + self.assertEqual([0,6],cellsMod.getValues()); + self.assertEqual([1,7],cellsNotMod.getValues()); + self.assertEqual(17,mm.getNumberOfNodes()) + self.assertEqual([3,19],mm.getGroupArr(-1,"Grp").getValues()) + self.assertEqual([22,23],mm.getGroupArr(-1,"Grp_dup").getValues()) + ref0=[4, 15, 0, 5, 6, 4, 8, 7, 12, 16] + ref1=[4, 2, 1, 6, 7, 4, 9, 8, 13, 14] + self.assertEqual(ref0,mm.getMeshAtLevel(0)[[0,6]].getNodalConnectivity().getValues()) + self.assertEqual(ref1,mm.getMeshAtLevel(0)[[1,7]].getNodalConnectivity().getValues()) + self.assertRaises(InterpKernelException,mm.getGroup(-1,"Grp_dup").checkGeoEquivalWith,mm.getGroup(-1,"Grp"),2,1e-12);# Grp_dup and Grp are not equal considering connectivity only + mm.getGroup(-1,"Grp_dup").checkGeoEquivalWith(mm.getGroup(-1,"Grp"),12,1e-12)# Grp_dup and Grp are equal considering connectivity and coordinates + + refValues=DataArrayDouble([1.1, 1.2, 1.3, 1.4, 1.1, 1.2, 1.3, 1.4]) + valsToTest=mm.getMeshAtLevel(0).getMeasureField(True).getArray() ; delta=(valsToTest-refValues) ; delta.abs() + self.assertTrue(delta.getMaxValue()[0]<1e-10) + # + mm.getCoords()[-len(nodes):]+=[0.,-0.3] + self.assertRaises(InterpKernelException,mm.getGroup(-1,"Grp_dup").checkGeoEquivalWith,mm.getGroup(-1,"Grp"),12,1e-12); + refValues2=refValues[:] ; refValues2[0] = 1.265; refValues2[6] = 1.105 + valsToTest=mm.getMeshAtLevel(0).getMeasureField(True).getArray() ; delta=(valsToTest-refValues2) ; delta.abs() + self.assertTrue(delta.getMaxValue()[0]<1e-12) + mm.write(fname,2) + + def testBasicConstructors(self): + fname="Pyfile18.med" + m=MEDFileMesh.New(fname) + m=MEDFileMesh.New(fname,"ExampleOfMultiDimW",-1,-1) + m=MEDFileMesh.New(fname) + m=MEDFileUMesh(fname,"ExampleOfMultiDimW",-1,-1) + m=MEDFileUMesh(fname) + m=MEDFileUMesh() + self.testMEDMesh6() + m=MEDFileCMesh("MEDFileMesh5.med") + m=MEDFileCMesh("MEDFileMesh5.med","myFirstCartMesh",-1,-1) + m=MEDFileCMesh() + m=MEDFileMeshMultiTS() + m=MEDFileMeshMultiTS(fname) + m=MEDFileMeshMultiTS(fname,"ExampleOfMultiDimW") + m=MEDFileMeshes() + m=MEDFileMeshes(fname) + m=MEDFileField1TS() + m=MEDFileField1TS(fname,"FieldOnFacesShuffle",2,7) + m=MEDFileFieldMultiTS() + m=MEDFileFieldMultiTS(fname,"FieldOnFacesShuffle") + m=MEDFileFields() + m=MEDFileFields(fname) + m=MEDFileData() + m=MEDFileData(fname) + # + m=DataArrayInt() ; m=DataArrayInt(5,2) ; m=DataArrayInt([6,5,4,3,2,1],3,2) + m=DataArrayDouble() ; m=DataArrayDouble(5,2) ; m=DataArrayDouble([6,5,4,3,2,1],3,2) + m=MEDCouplingUMesh("jjj",2) ; m=MEDCouplingUMesh() + m=MEDCouplingCMesh() + m=MEDCouplingFieldDouble(ON_CELLS,ONE_TIME) + m=MEDCouplingFieldTemplate(ON_NODES) + m=MEDCouplingMultiFields([]) + m=MEDCouplingFieldOverTime([]) + pass + + # This is a non regression test. When a field lies partially on a mesh but fully on one of its geometric type. + def testBugSemiPartialField(self): + fname="Pyfile46.med" + m=MEDLoaderDataForTest.build2DMesh_3() + m=m[:10] ; m.setName("mesh") + f=m.getMeasureField(ON_CELLS) + f=f.buildNewTimeReprFromThis(ONE_TIME,False) + f.setTime(5.5,3,4) + f.setName("SemiPartialField") + # + f1=f[:6] ; f1.getMesh().setName(m.getName()) + f2=f[6:] ; f2.getMesh().setName(m.getName()) + # + mm=MEDFileUMesh.New() + mm.setMeshAtLevel(0,m) + ff=MEDFileField1TS.New() + ff.setFieldProfile(f1,mm,0,DataArrayInt.Range(0,6,1)) # no name on profile -> normally it is an error but in this special case + mm.write(fname,2) + ff.write(fname,0) + # + ff2=MEDFileField1TS.New(fname,f.getName(),f.getTime()[1],f.getTime()[2]) + fread=ff2.getFieldOnMeshAtLevel(ON_CELLS,0,mm) + fread2=ff2.getFieldAtLevel(ON_CELLS,0) + # + fread.checkCoherency() + fread2.checkCoherency() + self.assertTrue(fread.isEqual(f1,1e-12,1e-12)) + self.assertTrue(fread2.isEqual(f1,1e-12,1e-12)) + pass + + def testUnPolyze1(self): + fname="Pyfile47.med" + mm=MEDLoaderDataForTest.buildMLMeshUnPolyze(self) + ref=[13,14,14,12,12,12,12,12,12,12,12,13,12,14,14,13,15,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12] + self.assertEqual(ref,mm.getFamilyFieldAtLevel(1).getValues()) + self.assertEqual(mm.unPolyze()[:3],(True,[[3,2,0],[4,3,2],[5,4,5],[14,2,9],[16,3,11],[31,2,14]],[[3,3,0],[4,3,3],[5,3,6],[14,3,9],[16,3,12],[18,1,15]])) + mm.write(fname,2) + self.assertEqual(mm.getGroupArr(0,"grp0_L0").getValues(),[0,1,2,6]) + self.assertEqual(mm.getGroupArr(0,"grp1_L0").getValues(),[1,3,4,5,6]) + self.assertEqual(mm.getGroupArr(-1,"grp0_LM1").getValues(),[1,2,3,4,5]) + self.assertEqual(mm.getGroupArr(-1,"grp1_LM1").getValues(),[3,4,5,6]) + self.assertEqual(mm.getGroupArr(-1,"grp2_LM1").getValues(),[2,6,7,8]) + self.assertEqual(mm.getGroupArr(1,"grp0_Node").getValues(),[0,11,15,16]) + self.assertEqual(mm.getGroupArr(1,"grp1_Node").getValues(),[1,2,13,14,16]) + self.assertEqual(mm.getFamilyFieldAtLevel(1).getValues(),ref) + # to test + mm.setRenumFieldArr(0,None) + mm.setFamilyFieldArr(-1,None) + pass + + def testUnPolyze2(self): + fname="Pyfile48.med" + mfd=MEDFileData.New() + mm=MEDLoaderDataForTest.buildMLMeshUnPolyze(self) + meshes=MEDFileMeshes.New() + meshes.pushMesh(mm) + mfd.setMeshes(meshes) + fields=MEDFileFields.New() + mfd.setFields(fields) + ff=MEDFileFieldMultiTS.New() + fields.pushField(ff) + # + f0_0=MEDCouplingFieldDouble.New(ON_NODES,ONE_TIME) ; f0_0.setName("f0") + f0_0.setTime(9.5,3,4) + da=DataArrayDouble.New(38*2) ; da.iota(6.) ; da.rearrange(2) ; da.setInfoOnComponents(["Power [MW]","Density [kg/m^3]"]) + f0_0.setArray(da) + f0_0.setMesh(mm.getMeshAtLevel(0)) + ff.appendFieldNoProfileSBT(f0_0) + ff0=ff.getTimeStepAtPos(0) + f0_1=MEDCouplingFieldDouble.New(ON_CELLS,ONE_TIME) ; f0_1.setName("f0") + f0_1.setTime(9.5,3,4) + pfl=DataArrayInt.New([1,4,5,6]) ; pfl.setName("pfltest") + f0_1.setMesh(mm.getMeshAtLevel(0)[pfl]) + da=DataArrayDouble.New([1401.,101401.,1602.,101602.,3100.,103100.,3101.,103101.],4,2) ; da.setInfoOnComponents(["Power [MW]","Density [kg/m^3]"]) + f0_1.setArray(da) + ff0.setFieldProfile(f0_1,mm,0,pfl) + f0_2=MEDCouplingFieldDouble.New(ON_CELLS,ONE_TIME) ; f0_2.setName("f0")#provoquer error + f0_2.setTime(9.5,3,4) + pfl2=DataArrayInt.New([0,1,2,3,4,5,6,8]) ; pfl2.setName("pfltestM1") + da=DataArrayDouble.New([300.,100300.,301.,100301.,400.,100400.,401.,100401.,402.,100402.,3200.,103200.,3201.,103201.,3203.,103203.],8,2) ; da.setInfoOnComponents(["Power [MW]","Density [kg/m^3]"])#provoquer error + f0_2.setMesh(mm.getMeshAtLevel(-1)[pfl2]) + f0_2.setArray(da) + ff0.setFieldProfile(f0_2,mm,-1,pfl2) + mfd.getFields().shallowCpyGlobs(ff0) + # + mfd.unPolyzeMeshes() + # + fmts=mfd.getFields()[0] + self.assertEqual(fmts.getNumberOfTS(),1) + self.assertEqual(fmts.getTimeSteps(),[(3,4,9.5)]) + arr,entry=fmts.getUndergroundDataArrayExt(3,4) + self.assertEqual(entry,[((3,0),(38,40)),((4,0),(40,43)),((5,0),(43,46)),((14,0),(46,48)),((16,0),(48,49)),((18,0),(49,50)),((40,0),(0,38))]) + self.assertTrue(arr[38:40].isEqualWithoutConsideringStr(DataArrayDouble([300.0,100300.0,301.0,100301.0],2,2),1e-8)) + self.assertTrue(arr[40:43].isEqualWithoutConsideringStr(DataArrayDouble([400.0,100400.0,401.0,100401.0,402.0,100402.0],3,2),1e-8)) + self.assertTrue(arr[43:46].isEqualWithoutConsideringStr(DataArrayDouble([3200.0,103200.0,3201.0,103201.0,3203.0,103203.0],3,2),1e-8)) + self.assertTrue(arr[46:48].isEqualWithoutConsideringStr(DataArrayDouble([1401.0,101401.0,3100.0,103100.0],2,2),1e-8)) + self.assertTrue(arr[48:49].isEqualWithoutConsideringStr(DataArrayDouble([1602.0,101602.0],1,2),1e-8)) + self.assertTrue(arr[49:50].isEqualWithoutConsideringStr(DataArrayDouble([3101.0,103101.0],1,2),1e-8)) + self.assertEqual(('NewPfl_0','NewPfl_1','NewPfl_2'),fmts.getPflsReallyUsed()) + self.assertEqual([(3,[(0,(38,40),'NewPfl_0','')]),(4,[(0,(40,43),'','')]),(5,[(0,(43,46),'','')]),(14,[(0,(46,48),'NewPfl_1','')]),(16,[(0,(48,49),'NewPfl_2','')]),(18,[(0,(49,50),'','')]),(40,[(1,(0,38),'','')])],fmts.getFieldSplitedByType(3,4)) + self.assertEqual(fmts.getProfile("NewPfl_0").getValues(),[0,1]) + self.assertEqual(fmts.getProfile("NewPfl_1").getValues(),[1,2]) + self.assertEqual(fmts.getProfile("NewPfl_2").getValues(),[2]) + ftest0=fmts.getFieldOnMeshAtLevel(ON_CELLS,3,4,0,mfd.getMeshes()[0]) + self.assertTrue(ftest0.getArray().isEqualWithoutConsideringStr(DataArrayDouble([1401.,101401.,3100.,103100.,1602.,101602.,3101.,103101.],4,2),1e-8)) + self.assertEqual(ftest0.getMesh().getNodalConnectivity().getValues(),[14,4,5,6,7,14,26,27,28,29,16,20,21,22,23,24,25,18,30,31,32,33,34,35,36,37]) + self.assertEqual(ftest0.getMesh().getNodalConnectivityIndex().getValues(),[0,5,10,17,26]) + ftest1=fmts.getFieldOnMeshAtLevel(ON_CELLS,3,4,-1,mfd.getMeshes()[0]) + self.assertTrue(ftest1.getArray().isEqualWithoutConsideringStr(DataArrayDouble([300.,100300.,301.,100301.,400.,100400.,401.,100401.,402.,100402.,3200.,103200.,3201.,103201.,3203.,103203.]),1e-8)) + self.assertEqual(ftest1.getMesh().getNodalConnectivity().getValues(),[3,0,1,2,3,3,4,5,4,6,7,8,9,4,10,11,12,13,4,14,15,16,17,5,18,19,20,21,22,5,23,24,25,26,27,5,31,32,33,34,35,36,37]) + self.assertEqual(ftest1.getMesh().getNodalConnectivityIndex().getValues(),[0,4,8,13,18,23,29,35,43]) + # + mfd.write(fname,2) + pass + + def testGaussWriteOnPfl1(self): + fname="Pyfile49.med" + fname2="Pyfile50.med" + coords=DataArrayDouble([0.,0.,0.,1.,1.,1.,1.,0.,0.,0.5,0.5,1.,1.,0.5,0.5,0.],8,2) + mQ8=MEDCouplingUMesh("",2) ; mQ8.setCoords(coords) + mQ8.allocateCells(1) + mQ8.insertNextCell(NORM_QUAD8,range(8)) + mQ8.finishInsertingCells() + mQ4=MEDCouplingUMesh("",2) ; mQ4.setCoords(coords) + mQ4.allocateCells(1) + mQ4.insertNextCell(NORM_QUAD4,range(4)) + mQ4.finishInsertingCells() + mT3=MEDCouplingUMesh("",2) ; mT3.setCoords(coords) + mT3.allocateCells(1) + mT3.insertNextCell(NORM_TRI3,range(3)) + mT3.finishInsertingCells() + + tr=[[0.,4.],[2.,4.],[4.,4.],[6.,4.],[8.,4.],[10.,4.],[12.,4.],[14.,4.],[16.,4.],[18.,4.],[20.,4.],[0.,0.],[2.,0.], [0.,2.],[2.,2.],[4.,2.],[6.,2.],[8.,2.],[10.,2.],[12.,2.]] + ms=11*[mT3]+2*[mQ4]+7*[mQ8] + ms[:]=(elt.deepCpy() for elt in ms) + for m,t in zip(ms,tr): + d=m.getCoords() ; d+= t + pass + m=MEDCouplingUMesh.MergeUMeshes(ms) + m.setName("mesh") + m2=m[:13] ; m2.setName(m.getName()) + ### Use case 1 : Pfl on all tri3 and on all quad4. If we were on CELLS or GAUSS_NE no pfl were needed. But here 2 discs in tri3. + ### So here 2 pfls will be created (pfl_TRI3_loc_0 and pfl_TRI3_loc_1) + f=MEDCouplingFieldDouble.New(ON_GAUSS_PT,ONE_TIME) + f.setMesh(m2) + f.setTime(4.5,1,2) + da=DataArrayDouble(34) ; da.iota(3.) + f.setArray(da) + f.setName("fieldCellOnPflWithoutPfl") + fInvalid=f.deepCpy() + f.setGaussLocalizationOnCells([0,1,2,3,4,5,6,7,8],[0.,0.,1.,0.,1.,1.],[0.3,0.3,0.7,0.7],[0.8,0.2]) + f.setGaussLocalizationOnCells([9,10],[0.,0.,1.,0.,1.,1.],[0.3,0.3,0.7,0.7,0.8,0.8],[0.8,0.07,0.13]) + f.setGaussLocalizationOnCells([11,12],[0.,0.,1.,0.,1.,1.,0.,1.],[0.3,0.3,0.7,0.7,0.8,0.8,0.8,0.8,0.8,0.8],[0.8,0.07,0.1,0.01,0.02]) + f.checkCoherency() + fInvalid2=fInvalid.deepCpy() + fInvalid2.getDiscretization().setArrayOfDiscIds(f.getDiscretization().getArrayOfDiscIds()) + # + mm=MEDFileUMesh() + mm.setMeshAtLevel(0,m) + mm.write(fname,2) + # + f1ts=MEDFileField1TS.New() + pfl=DataArrayInt(range(13)) ; pfl.setName("pfl") + self.assertRaises(InterpKernelException,f1ts.setFieldProfile,fInvalid,mm,0,pfl) # fails because no Gauss localization per cell set ! + self.assertRaises(InterpKernelException,f1ts.setFieldProfile,fInvalid2,mm,0,pfl) # fails because no Gauss localization set whereas gauss locid per cell given ! + f1ts.setFieldProfile(f,mm,0,pfl) + f1ts.write(fname,0) + # + self.assertEqual(f1ts.getPfls(),('pfl_NORM_TRI3_loc_0', 'pfl_NORM_TRI3_loc_1')) + self.assertEqual(f1ts.getPflsReallyUsed(),('pfl_NORM_TRI3_loc_0', 'pfl_NORM_TRI3_loc_1')) + da1=DataArrayInt([0,1,2,3,4,5,6,7,8]) ; da1.setName("pfl_NORM_TRI3_loc_0") + self.assertTrue(f1ts.getProfile("pfl_NORM_TRI3_loc_0").isEqual(da1)) + da1=DataArrayInt([9,10]) ; da1.setName("pfl_NORM_TRI3_loc_1") + self.assertTrue(f1ts.getProfile("pfl_NORM_TRI3_loc_1").isEqual(da1)) + self.assertEqual(f1ts.getLocs(),('Loc_fieldCellOnPflWithoutPfl_NORM_TRI3_0', 'Loc_fieldCellOnPflWithoutPfl_NORM_TRI3_1', 'Loc_fieldCellOnPflWithoutPfl_NORM_QUAD4_2')) + self.assertEqual(f1ts.getLocsReallyUsed(),('Loc_fieldCellOnPflWithoutPfl_NORM_TRI3_0', 'Loc_fieldCellOnPflWithoutPfl_NORM_TRI3_1', 'Loc_fieldCellOnPflWithoutPfl_NORM_QUAD4_2')) + # + dataRead=MEDFileData.New(fname) + mRead=dataRead.getMeshes()[0] + f1tsRead=dataRead.getFields()[0][0] + f1tsRead.getFieldOnMeshAtLevel(ON_GAUSS_PT,0,mRead) + f2=f1tsRead.getFieldOnMeshAtLevel(ON_GAUSS_PT,0,mRead) + self.assertTrue(f.isEqual(f2,1e-12,1e-12)) + f2_bis=MEDLoader.ReadFieldGauss(fname,m.getName(),0,f.getName(),f.getTime()[1],f.getTime()[2]) + f2_bis.checkCoherency() + self.assertTrue(f.isEqual(f2_bis,1e-12,1e-12)) + # + MEDLoader.WriteField(fname2,f,True) + f2_ter=MEDLoader.ReadFieldGauss(fname2,m.getName(),0,f.getName(),f.getTime()[1],f.getTime()[2]) + self.assertTrue(f.isEqual(f2_ter,1e-12,1e-12)) + ## Use case 2 : Pfl on part tri3 with 2 disc and on part quad8 with 1 disc + f=MEDCouplingFieldDouble.New(ON_GAUSS_PT,ONE_TIME) + pfl=DataArrayInt([1,2,5,6,8,9,15,16,17,18]) ; pfl.setName("pfl2") + m2=m[pfl] ; m2.setName(m.getName()) + f.setMesh(m2) + f.setTime(4.5,1,2) + da=DataArrayDouble(35) ; da.iota(3.) + f.setArray(da) + f.setName("fieldCellOnPflWithoutPfl2") + f.setGaussLocalizationOnCells([0,1,3],[0.,0.,1.,0.,1.,1.],[0.3,0.3,0.7,0.7],[0.8,0.2]) + f.setGaussLocalizationOnCells([2,4,5],[0.,0.,1.,0.,1.,1.],[0.3,0.3,0.7,0.7,0.8,0.8],[0.8,0.07,0.13]) + f.setGaussLocalizationOnCells([6,7,8,9],[0.,0.,1.,0.,1.,1.,0.,1.,0.5,0.,1.,0.5,0.5,1.,0.,0.5],[0.3,0.3,0.7,0.7,0.8,0.8,0.8,0.8,0.8,0.8],[0.8,0.07,0.1,0.01,0.02]) + f.checkCoherency() + # + mm=MEDFileUMesh() + mm.setMeshAtLevel(0,m) + mm.write(fname,2) + f1ts=MEDFileField1TS.New() + f1ts.setFieldProfile(f,mm,0,pfl) + self.assertEqual(f1ts.getPfls(),('pfl2_NORM_TRI3_loc_0','pfl2_NORM_TRI3_loc_1','pfl2_NORM_QUAD8_loc_2')) + self.assertEqual(f1ts.getProfile("pfl2_NORM_TRI3_loc_0").getValues(),[1,2,6]) + self.assertEqual(f1ts.getProfile("pfl2_NORM_TRI3_loc_1").getValues(),[5,8,9]) + self.assertEqual(f1ts.getProfile("pfl2_NORM_QUAD8_loc_2").getValues(),[2,3,4,5]) + f1ts.write(fname,0) + dataRead=MEDFileData.New(fname) + mRead=dataRead.getMeshes()[0] + f1tsRead=dataRead.getFields()[0][0] + f1tsRead.getFieldOnMeshAtLevel(ON_GAUSS_PT,0,mRead) + f3=f1tsRead.getFieldOnMeshAtLevel(ON_GAUSS_PT,0,mRead) + f3.renumberCells([0,1,3,2,4,5,6,7,8,9]) + self.assertTrue(f.isEqual(f3,1e-12,1e-12)) + f3_bis=MEDLoader.ReadFieldGauss(fname,m.getName(),0,f.getName(),f.getTime()[1],f.getTime()[2]) + f3_bis.renumberCells([0,1,3,2,4,5,6,7,8,9]) + self.assertTrue(f.isEqual(f3_bis,1e-12,1e-12)) + # + MEDLoader.WriteField(fname2,f,True) + f3_ter=MEDLoader.ReadFieldGauss(fname2,m.getName(),0,f.getName(),f.getTime()[1],f.getTime()[2]) + f3_ter.renumberCells([0,1,3,2,4,5,6,7,8,9]) + self.assertTrue(f.isEqual(f3_ter,1e-12,1e-12)) + ## Use case 3 : no pfl but creation of pfls due to gauss pts + f=MEDCouplingFieldDouble.New(ON_GAUSS_PT,ONE_TIME) + f.setMesh(m) + f.setTime(4.5,1,2) + da=DataArrayDouble(60) ; da.iota(3.) + f.setArray(da) + f.setName("fieldCellWithoutPfl") + f.setGaussLocalizationOnCells([0,1,2,3,4,5,6,7,8],[0.,0.,1.,0.,1.,1.],[0.3,0.3,0.7,0.7],[0.8,0.2]) + f.setGaussLocalizationOnCells([9,10],[0.,0.,1.,0.,1.,1.],[0.3,0.3,0.7,0.7,0.8,0.8],[0.8,0.07,0.13]) + f.setGaussLocalizationOnCells([11,12],[0.,0.,1.,0.,1.,1.,0.,1.],[0.3,0.3,0.7,0.7,0.8,0.8,0.8,0.8,0.8,0.8],[0.8,0.07,0.1,0.01,0.02]) + f.setGaussLocalizationOnCells([13,14,15,17,18],[0.,0.,1.,0.,1.,1.,0.,1.,0.5,0.,1.,0.5,0.5,1.,0.,0.5],[0.3,0.3,0.7,0.7,0.8,0.8,0.8,0.8],[0.8,0.1,0.03,0.07]) + f.setGaussLocalizationOnCells([16,19],[0.,0.,1.,0.,1.,1.,0.,1.,0.5,0.,1.,0.5,0.5,1.,0.,0.5],[0.3,0.3,0.7,0.7,0.8,0.8],[0.8,0.1,0.1]) + f.checkCoherency() + mm=MEDFileUMesh() + mm.setMeshAtLevel(0,m) + f1ts=MEDFileField1TS.New() + f1ts.setFieldNoProfileSBT(f) + self.assertEqual(f1ts.getPfls(),('Pfl_fieldCellWithoutPfl_NORM_TRI3_0','Pfl_fieldCellWithoutPfl_NORM_TRI3_1','Pfl_fieldCellWithoutPfl_NORM_QUAD8_3','Pfl_fieldCellWithoutPfl_NORM_QUAD8_4')) + self.assertEqual(f1ts.getProfile("Pfl_fieldCellWithoutPfl_NORM_TRI3_0").getValues(),[0,1,2,3,4,5,6,7,8]) + self.assertEqual(f1ts.getProfile("Pfl_fieldCellWithoutPfl_NORM_TRI3_1").getValues(),[9,10]) + self.assertEqual(f1ts.getProfile("Pfl_fieldCellWithoutPfl_NORM_QUAD8_3").getValues(),[0,1,2,4,5]) + self.assertEqual(f1ts.getProfile("Pfl_fieldCellWithoutPfl_NORM_QUAD8_4").getValues(),[3,6]) + mm.write(fname,2) + f1ts.write(fname,0) + # + dataRead=MEDFileData.New(fname) + mRead=dataRead.getMeshes()[0] + f1tsRead=dataRead.getFields()[0][0] + f3=f1tsRead.getFieldOnMeshAtLevel(ON_GAUSS_PT,0,mRead) + f3.renumberCells([0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,17,18,16,19]) + self.assertTrue(f.isEqual(f3,1e-12,1e-12)) + f3_bis=MEDLoader.ReadFieldGauss(fname,m.getName(),0,f.getName(),f.getTime()[1],f.getTime()[2]) + f3_bis.renumberCells([0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,17,18,16,19]) + self.assertTrue(f.isEqual(f3_bis,1e-12,1e-12)) + # + MEDLoader.WriteField(fname2,f,True) + f3_ter=MEDLoader.ReadFieldGauss(fname2,m.getName(),0,f.getName(),f.getTime()[1],f.getTime()[2]) + f3_ter.renumberCells([0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,17,18,16,19]) + self.assertTrue(f.isEqual(f3_ter,1e-12,1e-12)) + pass + + # Testing profile on nodes when the profile is identity but not on all nodes. + def testMEDFieldPflOnNode1(self): + fname="Pyfile51.med" + coo=DataArrayDouble([0.,0.,0.5,0.,1.,0.,0.,0.5,0.5,0.5,1.,0.5,0.,1.,0.5,1.,1.,1.],9,2) + m0=MEDCouplingUMesh("Mesh",2) + m0.allocateCells(5) + m0.insertNextCell(NORM_TRI3,[1,4,2]) + m0.insertNextCell(NORM_TRI3,[4,5,2]) + m0.insertNextCell(NORM_QUAD4,[0,3,4,1]) + m0.insertNextCell(NORM_QUAD4,[3,6,7,4]) + m0.insertNextCell(NORM_QUAD4,[4,7,8,5]) + m0.finishInsertingCells() + m0.setCoords(coo) + m1=MEDCouplingUMesh(m0.getName(),1) + m1.allocateCells(9) + conn1=[0,1,0,3,3,4,4,1,5,4,2,4,1,2,3,6,5,8] + for i in xrange(9): + m1.insertNextCell(NORM_SEG2,conn1[2*i:2*i+2]) + pass + m1.finishInsertingCells() + m1.setCoords(coo) + # + m=MEDFileUMesh() + m.setMeshAtLevel(0,m0) + m.setMeshAtLevel(-1,m1) + # + dt=3 ; it=2 ; tim=4.5 + fieldNode0=MEDCouplingFieldDouble(ON_NODES,ONE_TIME) + fieldNode0.setName("fieldNode0") + fieldNode0.setTime(tim,dt,it) + pfl0=DataArrayInt([0,1,2,3,4]) ; pfl0.setName("PflIdentity0") # important to keep like that + arr=DataArrayDouble([10,11,12,13,14]) + fieldNode0.setArray(arr) + f0=MEDFileField1TS() + f0.setFieldProfile(fieldNode0,m,0,pfl0) + m.write(fname,2) ; f0.write(fname,0) + fieldNode1=MEDCouplingFieldDouble(ON_NODES,ONE_TIME) + fieldNode1.setName("fieldNode1") + fieldNode1.setTime(tim,dt,it) + pfl1=DataArrayInt([0,1,2,3,4,5,6]) ; pfl1.setName("PflIdentity1") + arr1=DataArrayDouble([20,21,22,23,24,25,26]) + fieldNode1.setArray(arr1) + f1=MEDFileField1TS() + f1.setFieldProfile(fieldNode1,m,-1,pfl1) + f1.write(fname,0) + del m,f0,m0,m1,f1 + ## Reading from file + m=MEDFileMesh.New(fname) + m0=m.getMeshAtLevel(0) + m00=m0.deepCpy() ; m00=m00[[0,2]] ; m00.setName(m.getName()) ; m00.zipCoords() + fieldNode0.setMesh(m00) + f0=MEDFileField1TS.New(fname,fieldNode0.getName(),dt,it) + ff0_1=f0.getFieldOnMeshAtLevel(ON_NODES,m0) + ff0_1.checkCoherency() + self.assertTrue(ff0_1.isEqual(fieldNode0,1e-12,1e-12)) + ff0_2=f0.getFieldAtLevel(ON_NODES,0) + ff0_2.checkCoherency() + self.assertTrue(ff0_2.isEqual(fieldNode0,1e-12,1e-12)) + ff0_3=f0.getFieldOnMeshAtLevel(ON_NODES,0,m) + ff0_3.checkCoherency() + self.assertTrue(ff0_3.isEqual(fieldNode0,1e-12,1e-12)) + ff0_4=MEDLoader.ReadFieldNode(fname,m.getName(),0,fieldNode0.getName(),dt,it) + ff0_4.checkCoherency() + self.assertTrue(ff0_4.isEqual(fieldNode0,1e-12,1e-12)) + f1=MEDFileField1TS.New(fname,fieldNode1.getName(),dt,it) + m1=m.getMeshAtLevel(-1) + m10=m1.deepCpy() ; m10=m10[[0,1,2,3,4,5,6,7]] ; m10.setName(m.getName()) ; m10.zipCoords() + fieldNode1.setMesh(m10) + ff1_1=f1.getFieldOnMeshAtLevel(ON_NODES,m1) + ff1_1.checkCoherency() + self.assertTrue(ff1_1.isEqual(fieldNode1,1e-12,1e-12)) + ff1_2=f1.getFieldAtLevel(ON_NODES,-1) + ff1_2.checkCoherency() + self.assertTrue(ff1_2.isEqual(fieldNode1,1e-12,1e-12)) + ff1_3=f1.getFieldOnMeshAtLevel(ON_NODES,-1,m) + ff1_3.checkCoherency() + self.assertTrue(ff1_3.isEqual(fieldNode1,1e-12,1e-12)) + ff1_4=MEDLoader.ReadFieldNode(fname,m.getName(),-1,fieldNode1.getName(),dt,it) + ff1_4.checkCoherency() + self.assertTrue(ff1_4.getMesh().isEqual(m10,1e-12)) + self.assertRaises(InterpKernelException,f1.getFieldOnMeshAtLevel,ON_NODES,m0) # error because impossible to build a sub mesh at level 0 lying on nodes [0,1,2,3,4,5,6] + self.assertRaises(InterpKernelException,f1.getFieldAtLevel,ON_NODES,0) # error because impossible to build a sub mesh at level 0 lying on nodes [0,1,2,3,4,5,6] + self.assertRaises(InterpKernelException,f1.getFieldOnMeshAtLevel,ON_NODES,0,m) # error because impossible to build a sub mesh at level 0 lying on nodes [0,1,2,3,4,5,6] + arr_r,pfl1_r=f1.getFieldWithProfile(ON_NODES,-1,m) + arr_r.setName(fieldNode1.getArray().getName()) + self.assertTrue(arr_r.isEqual(fieldNode1.getArray(),1e-12)) + pfl1_r.setName(pfl1.getName()) + self.assertTrue(pfl1_r.isEqual(pfl1)) + pass + + # Testing profile on nodes when the profile is identity but not on all nodes. + def testMEDFieldPflOnCell1(self): + fname="Pyfile52.med" + coo=DataArrayDouble([0.,0.,0.5,0.,1.,0.,0.,0.5,0.5,0.5,1.,0.5,0.,1.,0.5,1.,1.,1.],9,2) + m0=MEDCouplingUMesh("Mesh",2) + m0.allocateCells(5) + m0.insertNextCell(NORM_TRI3,[1,4,2]) + m0.insertNextCell(NORM_TRI3,[4,5,2]) + m0.insertNextCell(NORM_QUAD4,[0,3,4,1]) + m0.insertNextCell(NORM_QUAD4,[3,6,7,4]) + m0.insertNextCell(NORM_QUAD4,[4,7,8,5]) + m0.finishInsertingCells() + m0.setCoords(coo) + m1=MEDCouplingUMesh(m0.getName(),1) + m1.allocateCells(9) + conn1=[0,1,0,3,3,4,4,1,5,4,2,4,1,2,3,6,5,8] + for i in xrange(9): + m1.insertNextCell(NORM_SEG2,conn1[2*i:2*i+2]) + pass + m1.finishInsertingCells() + m1.setCoords(coo) + # + m=MEDFileUMesh() + m.setMeshAtLevel(0,m0) + m.setMeshAtLevel(-1,m1) + # + dt=3 ; it=2 ; tim=4.5 + fieldCell0=MEDCouplingFieldDouble(ON_CELLS,ONE_TIME) + fieldCell0.setName("fieldCell0") + fieldCell0.setTime(tim,dt,it) + pfl0=DataArrayInt([0,1,2]) ; pfl0.setName("PflIdentity0") # important to keep like that + arr=DataArrayDouble([10,11,12]) + fieldCell0.setArray(arr) + f0=MEDFileField1TS() + f0.setFieldProfile(fieldCell0,m,0,pfl0) + m.write(fname,2) ; f0.write(fname,0) + fieldCell1=MEDCouplingFieldDouble(ON_CELLS,ONE_TIME) + fieldCell1.setName("fieldCell1") + fieldCell1.setTime(tim,dt,it) + pfl1=DataArrayInt([0,1,2,3,4,5,6]) ; pfl1.setName("PflIdentity1") + arr1=DataArrayDouble([20,21,22,23,24,25,26]) + fieldCell1.setArray(arr1) + f1=MEDFileField1TS() + f1.setFieldProfile(fieldCell1,m,-1,pfl1) + f1.write(fname,0) + del m,f0,m0,m1,f1 + ## Reading from file + m=MEDFileMesh.New(fname) + m0=m.getMeshAtLevel(0) + m00=m0.deepCpy() ; m00=m00[pfl0] ; m00.setName(m.getName()) + fieldCell0.setMesh(m00) + f0=MEDFileField1TS.New(fname,fieldCell0.getName(),dt,it) + ff0_1=f0.getFieldOnMeshAtLevel(ON_CELLS,m0) + ff0_1.checkCoherency() + self.assertTrue(ff0_1.isEqual(fieldCell0,1e-12,1e-12)) + ff0_2=f0.getFieldAtLevel(ON_CELLS,0) + ff0_2.checkCoherency() + self.assertTrue(ff0_2.isEqual(fieldCell0,1e-12,1e-12)) + ff0_3=f0.getFieldOnMeshAtLevel(ON_CELLS,0,m) + ff0_3.checkCoherency() + self.assertTrue(ff0_3.isEqual(fieldCell0,1e-12,1e-12)) + ff0_4=MEDLoader.ReadFieldCell(fname,m.getName(),0,fieldCell0.getName(),dt,it) + ff0_4.checkCoherency() + self.assertTrue(ff0_4.isEqual(fieldCell0,1e-12,1e-12)) + f1=MEDFileField1TS.New(fname,fieldCell1.getName(),dt,it) + m1=m.getMeshAtLevel(-1) + m10=m1.deepCpy() ; m10=m10[pfl1] ; m10.setName(m.getName()) + fieldCell1.setMesh(m10) + ff1_1=f1.getFieldOnMeshAtLevel(ON_CELLS,m1) + ff1_1.checkCoherency() + self.assertTrue(ff1_1.isEqual(fieldCell1,1e-12,1e-12)) + ff1_2=f1.getFieldAtLevel(ON_CELLS,-1) + ff1_2.checkCoherency() + self.assertTrue(ff1_2.isEqual(fieldCell1,1e-12,1e-12)) + ff1_3=f1.getFieldOnMeshAtLevel(ON_CELLS,-1,m) + ff1_3.checkCoherency() + self.assertTrue(ff1_3.isEqual(fieldCell1,1e-12,1e-12)) + ff1_4=MEDLoader.ReadFieldCell(fname,m.getName(),-1,fieldCell1.getName(),dt,it) + ff1_4.checkCoherency() + self.assertTrue(ff1_4.getMesh().isEqual(m10,1e-12)) + self.assertRaises(InterpKernelException,f1.getFieldOnMeshAtLevel,ON_CELLS,m0) # error because impossible to build a sub mesh at level 0 lying on cells [0,1,2,3,4,5,6] + self.assertRaises(InterpKernelException,f1.getFieldAtLevel,ON_CELLS,0) # error because impossible to build a sub mesh at level 0 lying on cells [0,1,2,3,4,5,6] + self.assertRaises(InterpKernelException,f1.getFieldOnMeshAtLevel,ON_CELLS,0,m) # error because impossible to build a sub mesh at level 0 lying on cells [0,1,2,3,4,5,6] + arr_r,pfl1_r=f1.getFieldWithProfile(ON_CELLS,-1,m) + arr_r.setName(fieldCell1.getArray().getName()) + self.assertTrue(arr_r.isEqual(fieldCell1.getArray(),1e-12)) + pfl1_r.setName(pfl1.getName()) + self.assertTrue(pfl1_r.isEqual(pfl1)) + pass + + def testMEDFileUMeshZipCoords1(self): + m=MEDFileUMesh() + coo=DataArrayDouble(30) ; coo.iota(1.) ; coo.rearrange(3) ; coo.setInfoOnComponents(["aaa [b]","cc [dd]", "e [fff]"]) + m0=MEDCouplingUMesh("toto",2) ; m0.allocateCells(0) ; m0.insertNextCell(NORM_TRI3,[1,2,3]) ; m0.insertNextCell(NORM_QUAD4,[2,4,3,4]) ; m0.insertNextCell(NORM_POLYGON,[1,6,6,6,2]) + m1=MEDCouplingUMesh("toto",1) ; m1.allocateCells(0) ; m1.insertNextCell(NORM_SEG2,[1,6]) ; m1.insertNextCell(NORM_SEG2,[7,3]) + m2=MEDCouplingUMesh("toto",0) ; m2.allocateCells(0) ; m2.insertNextCell(NORM_POINT1,[2]) ; m2.insertNextCell(NORM_POINT1,[6]) ; m2.insertNextCell(NORM_POINT1,[8]) + m0.setCoords(coo) ; m.setMeshAtLevel(0,m0) + m1.setCoords(coo) ; m.setMeshAtLevel(-1,m1) + m2.setCoords(coo) ; m.setMeshAtLevel(-2,m2) + numCoo=DataArrayInt(10) ; numCoo.iota(3) ; m.setRenumFieldArr(1,numCoo) + famCoo=DataArrayInt(10) ; famCoo.iota(4) ; m.setFamilyFieldArr(1,famCoo) + da=DataArrayInt([20,30,40]) ; m.setRenumFieldArr(0,da) ; da=DataArrayInt([200,300,400]) ; m.setFamilyFieldArr(0,da) + da=DataArrayInt([50,60]) ; m.setRenumFieldArr(-1,da) ; da=DataArrayInt([500,600]) ; m.setFamilyFieldArr(-1,da) + da=DataArrayInt([70,80,90]) ; m.setRenumFieldArr(-2,da) ; da=DataArrayInt([700,800,900]) ; m.setFamilyFieldArr(-2,da) + o2n=m.zipCoords() + self.assertTrue(o2n.isEqual(DataArrayInt([-1,0,1,2,3,-1,4,5,6,-1]))) + self.assertTrue(m.getNumberFieldAtLevel(1).isEqual(DataArrayInt([4,5,6,7,9,10,11]))) + self.assertTrue(m.getFamilyFieldAtLevel(1).isEqual(DataArrayInt([5,6,7,8,10,11,12]))) + self.assertTrue(m.getMeshAtLevel(0).getNodalConnectivity().isEqual(DataArrayInt([3,0,1,2,4,1,3,2,3,5,0,4,4,4,1]))) + self.assertTrue(m.getMeshAtLevel(0).getNodalConnectivityIndex().isEqual(DataArrayInt([0,4,9,15]))) + self.assertTrue(m.getMeshAtLevel(-1).getNodalConnectivity().isEqual(DataArrayInt([1,0,4,1,5,2]))) + self.assertTrue(m.getMeshAtLevel(-1).getNodalConnectivityIndex().isEqual(DataArrayInt([0,3,6]))) + self.assertTrue(m.getMeshAtLevel(-2).getNodalConnectivity().isEqual(DataArrayInt([0,1,0,4,0,6]))) + self.assertTrue(m.getMeshAtLevel(-2).getNodalConnectivityIndex().isEqual(DataArrayInt([0,2,4,6]))) + pass + + def testMEDUMeshAddNodeGroup1(self): + fname="Pyfile53.med" + m=MEDFileUMesh() + coo=DataArrayDouble(39) ; coo.iota(1.) ; coo.rearrange(3) ; coo.setInfoOnComponents(["aaa [b]","cc [dd]", "e [fff]"]) + m0=MEDCouplingUMesh("toto",2) ; m0.allocateCells(0) ; m0.insertNextCell(NORM_TRI3,[1,2,3]) ; m0.insertNextCell(NORM_QUAD4,[2,4,3,4]) ; m0.insertNextCell(NORM_POLYGON,[1,6,6,6,2]) + m1=MEDCouplingUMesh("toto",1) ; m1.allocateCells(0) ; m1.insertNextCell(NORM_SEG2,[1,6]) ; m1.insertNextCell(NORM_SEG2,[7,3]) + m2=MEDCouplingUMesh("toto",0) ; m2.allocateCells(0) ; m2.insertNextCell(NORM_POINT1,[2]) ; m2.insertNextCell(NORM_POINT1,[6]) ; m2.insertNextCell(NORM_POINT1,[8]) + m0.setCoords(coo) ; m.setMeshAtLevel(0,m0) + m1.setCoords(coo) ; m.setMeshAtLevel(-1,m1) + m2.setCoords(coo) ; m.setMeshAtLevel(-2,m2) + # + mm=m.deepCpy() + famCoo=DataArrayInt([0,2,0,3,2,0,-1,0,0,0,0,-1,3]) ; mm.setFamilyFieldArr(1,famCoo) + da0=DataArrayInt([0,0,0]) ; mm.setFamilyFieldArr(0,da0) + da1=DataArrayInt([0,3]) ; mm.setFamilyFieldArr(-1,da1) + da2=DataArrayInt([0,0,0]) ; mm.setFamilyFieldArr(-2,da2) + mm.setFamilyId("MyFam",2) + mm.setFamilyId("MyOtherFam",3) + mm.setFamilyId("MyOther-1",-1) + mm.setFamiliesOnGroup("grp0",["MyOtherFam"]) + mm.setFamiliesOnGroup("grpA",["MyOther-1"]) + # + daTest=DataArrayInt([1,3,4,6,9,10,12]) ; daTest.setName("grp1") + mm.addNodeGroup(daTest) + self.assertTrue(mm.getGroupArr(1,daTest.getName()).isEqual(daTest)) + self.assertTrue(mm.getFamilyFieldAtLevel(1).isEqual(DataArrayInt([6,2,6,8,2,6,5,6,6,7,7,4,8]))) + for lev,arr in [(0,da0),(-1,da1),(-2,da2)]: + self.assertTrue(mm.getFamilyFieldAtLevel(lev).isEqual(arr)) + pass + self.assertEqual(mm.getFamiliesNames(),('Family_4','Family_5','Family_7','Family_8','MyFam','MyOther-1','MyOtherFam')) + self.assertEqual(mm.getGroupsNames(),('grp0','grp1','grpA')) + self.assertEqual(mm.getFamilyNameGivenId(3),'MyOtherFam') + self.assertEqual(mm.getFamilyNameGivenId(2),'MyFam') + for famName,famId in [('Family_4',4),('Family_5',5),('Family_7',7),('Family_8',8)]: + self.assertEqual(mm.getFamilyNameGivenId(famId),famName) + pass + self.assertEqual(mm.getFamiliesOnGroup("grp0"),('MyOtherFam','Family_8')) + da=DataArrayInt([3,12]) ; da.setName("grp0") + self.assertTrue(mm.getGroupArr(1,"grp0").isEqual(da)) + da.setValues([1]) + self.assertTrue(mm.getGroupArr(-1,"grp0").isEqual(da)) + mm.write(fname,2) + mm=MEDFileMesh.New(fname) + self.assertTrue(mm.getGroupArr(1,daTest.getName()).isEqual(daTest)) + self.assertTrue(mm.getFamilyFieldAtLevel(1).isEqual(DataArrayInt([6,2,6,8,2,6,5,6,6,7,7,4,8]))) + for lev,arr in [(0,da0),(-1,da1),(-2,da2)]: + self.assertTrue(mm.getFamilyFieldAtLevel(lev).isEqual(arr)) + pass + self.assertEqual(mm.getFamiliesNames(),('FAMILLE_ZERO','Family_4','Family_5','Family_7','Family_8','MyFam','MyOther-1','MyOtherFam')) + self.assertEqual(mm.getGroupsNames(),('grp0','grp1','grpA')) + self.assertEqual(mm.getFamilyNameGivenId(3),'MyOtherFam') + self.assertEqual(mm.getFamilyNameGivenId(2),'MyFam') + for famName,famId in [('Family_4',4),('Family_5',5),('Family_7',7),('Family_8',8)]: + self.assertEqual(mm.getFamilyNameGivenId(famId),famName) + pass + self.assertEqual(mm.getFamiliesOnGroup("grp0"),('Family_8','MyOtherFam')) + da=DataArrayInt([3,12]) ; da.setName("grp0") + self.assertTrue(mm.getGroupArr(1,"grp0").isEqual(da)) + da.setValues([1]) + self.assertTrue(mm.getGroupArr(-1,"grp0").isEqual(da)) + pass + + def testMEDUMeshAddGroup1(self): + fname="Pyfile54.med" + m=MEDFileUMesh() + coo=DataArrayDouble(9) ; coo.iota(1.) ; coo.rearrange(3) ; coo.setInfoOnComponents(["aaa [b]","cc [dd]", "e [fff]"]) + m0=MEDCouplingUMesh("toto",2) ; m0.allocateCells(0) + for i in xrange(7): + m0.insertNextCell(NORM_TRI3,[1,2,1]) + pass + for i in xrange(4): + m0.insertNextCell(NORM_QUAD4,[1,1,2,0]) + pass + for i in xrange(2): + m0.insertNextCell(NORM_POLYGON,[0,0,1,1,2,2]) + pass + m1=MEDCouplingUMesh("toto",1) ; m1.allocateCells(0) ; m1.insertNextCell(NORM_SEG2,[1,6]) ; m1.insertNextCell(NORM_SEG2,[7,3]) + m2=MEDCouplingUMesh("toto",0) ; m2.allocateCells(0) ; m2.insertNextCell(NORM_POINT1,[2]) ; m2.insertNextCell(NORM_POINT1,[6]) ; m2.insertNextCell(NORM_POINT1,[8]) + m0.setCoords(coo) ; m.setMeshAtLevel(0,m0) + m1.setCoords(coo) ; m.setMeshAtLevel(-1,m1) + m2.setCoords(coo) ; m.setMeshAtLevel(-2,m2) + # + mm=m.deepCpy() + famCoo=DataArrayInt([0,2,0,3,2,0,-1,0,0,0,0,-1,3]) ; mm.setFamilyFieldArr(0,famCoo) + da0=DataArrayInt([0,0,0]) ; mm.setFamilyFieldArr(1,da0) + da1=DataArrayInt([0,3]) ; mm.setFamilyFieldArr(-1,da1) + da2=DataArrayInt([0,0,0]) ; mm.setFamilyFieldArr(-2,da2) + mm.setFamilyId("MyFam",2) + mm.setFamilyId("MyOtherFam",3) + mm.setFamilyId("MyOther-1",-1) + mm.setFamiliesOnGroup("grp0",["MyOtherFam"]) + mm.setFamiliesOnGroup("grpA",["MyOther-1"]) + # + daTest=DataArrayInt([1,3,4,6,9,10,12]) ; daTest.setName("grp1") + mm.addGroup(0,daTest) + self.assertTrue(mm.getGroupArr(0,daTest.getName()).isEqual(daTest)) + self.assertTrue(mm.getFamilyFieldAtLevel(0).isEqual(DataArrayInt([-6,2,-6,-8,2,-6,-5,-6,-6,-7,-7,-4,-8]))) + for lev,arr in [(1,da0),(-1,da1),(-2,da2)]: + self.assertTrue(mm.getFamilyFieldAtLevel(lev).isEqual(arr)) + pass + self.assertEqual(mm.getFamiliesNames(),('Family_-4','Family_-5','Family_-7','Family_-8','MyFam','MyOther-1','MyOtherFam')) + self.assertEqual(mm.getGroupsNames(),('grp0','grp1','grpA')) + self.assertEqual(mm.getFamilyNameGivenId(3),'MyOtherFam') + self.assertEqual(mm.getFamilyNameGivenId(2),'MyFam') + for famName,famId in [('Family_-4',-4),('Family_-5',-5),('Family_-7',-7),('Family_-8',-8)]: + self.assertEqual(mm.getFamilyNameGivenId(famId),famName) + pass + self.assertEqual(mm.getFamiliesOnGroup("grp0"),('MyOtherFam','Family_-8')) + da=DataArrayInt([3,12]) ; da.setName("grp0") + self.assertTrue(mm.getGroupArr(0,"grp0").isEqual(da)) + da.setValues([1]) + self.assertTrue(mm.getGroupArr(-1,"grp0").isEqual(da)) + mm.write(fname,2) + mm=MEDFileMesh.New(fname) + self.assertTrue(mm.getGroupArr(0,daTest.getName()).isEqual(daTest)) + self.assertTrue(mm.getFamilyFieldAtLevel(0).isEqual(DataArrayInt([-6,2,-6,-8,2,-6,-5,-6,-6,-7,-7,-4,-8]))) + for lev,arr in [(1,da0),(-1,da1),(-2,da2)]: + self.assertTrue(mm.getFamilyFieldAtLevel(lev).isEqual(arr)) + pass + self.assertEqual(mm.getFamiliesNames(),('FAMILLE_ZERO','Family_-4','Family_-5','Family_-7','Family_-8','MyFam','MyOther-1','MyOtherFam')) + self.assertEqual(mm.getGroupsNames(),('grp0','grp1','grpA')) + self.assertEqual(mm.getFamilyNameGivenId(3),'MyOtherFam') + self.assertEqual(mm.getFamilyNameGivenId(2),'MyFam') + for famName,famId in [('Family_-4',-4),('Family_-5',-5),('Family_-7',-7),('Family_-8',-8)]: + self.assertEqual(mm.getFamilyNameGivenId(famId),famName) + pass + self.assertEqual(mm.getFamiliesOnGroup("grp0"),('Family_-8','MyOtherFam')) + da=DataArrayInt([3,12]) ; da.setName("grp0") + self.assertTrue(mm.getGroupArr(0,"grp0").isEqual(da)) + da.setValues([1]) + self.assertTrue(mm.getGroupArr(-1,"grp0").isEqual(da)) + pass + + def testHeapMem1(self): + a=DataArrayInt() ; aa=a.getHeapMemorySize() + a.alloc(0,1) + strMulFac=a.getHeapMemorySize()-aa ; del a ; del aa + # + m=MEDCouplingCMesh() + arr=DataArrayDouble(10,1) ; arr.iota(0) + m.setCoords(arr,arr) + m=m.buildUnstructured() + m.setName("mm") + f=m.getMeasureField(ON_CELLS) + self.assertIn(m.getHeapMemorySize(),xrange(3552-100,3552+100+4*strMulFac)) + self.assertIn(f.getHeapMemorySize(),xrange(4215-100,4215+100+8*strMulFac)) + # + mm=MEDFileUMesh() + mm.setMeshAtLevel(0,m) + self.assertIn(mm.getHeapMemorySize(),xrange(3889-100,3889+100+10*strMulFac)) + ff=MEDFileField1TS() + ff.setFieldNoProfileSBT(f) + self.assertIn(ff.getHeapMemorySize(),xrange(771-40,771+21+(4+1)*strMulFac)) + # + fff=MEDFileFieldMultiTS() + fff.appendFieldNoProfileSBT(f) + self.assertIn(fff.getHeapMemorySize(),xrange(815-50,815+30+(6+2)*strMulFac)) + f.setTime(1.,0,-1) + fff.appendFieldNoProfileSBT(f) + self.assertIn(fff.getHeapMemorySize(),xrange(1594-90,1594+50+(10+1)*strMulFac)) + self.assertIn(fff[0,-1].getHeapMemorySize(),xrange(771-40,771+20+(4+1)*strMulFac)) + f2=f[:50] + f2.setTime(2.,1,-1) + pfl=DataArrayInt.Range(0,50,1) ; pfl.setName("pfl") + fff.appendFieldProfile(f2,mm,0,pfl) + self.assertIn(fff.getHeapMemorySize(),xrange(2348-130,2348+100+(10+2)*strMulFac)) + self.assertIn(fff.getProfile("pfl").getHeapMemorySize(),xrange(204-10,204+10+2*strMulFac)) + self.assertIn(fff[1,-1].getHeapMemorySize(),xrange(738-50,738+30+4*strMulFac)) + pass + + def testCurveLinearMesh1(self): + fname="Pyfile55.med" + mesh=MEDCouplingCurveLinearMesh(); + mesh.setTime(2.3,4,5); + mesh.setTimeUnit("us"); + mesh.setName("Example of Cuve linear mesh"); + mesh.setDescription("buildCLMesh"); + a1=DataArrayDouble(3*20,1); + a1.iota(7.) ; a1.rearrange(3); + mesh.setCoords(a1); + mesh.setNodeGridStructure([4,5]); + mesh.checkCoherency(); + # + m=MEDFileCurveLinearMesh() + m.setMesh(mesh) + d=DataArrayInt(20) ; d.iota(4) + m.setFamilyFieldArr(1,d) + d3=DataArrayInt(20) ; d3.iota(400) + m.setRenumFieldArr(1,d3) + d2=DataArrayInt(12) ; d2.iota(40) + m.setFamilyFieldArr(0,d2) + d4=DataArrayInt(21) ; d4.iota(4000) + self.assertRaises(InterpKernelException,m.setRenumFieldArr,1,d4) + d4.popBackSilent() + m.setRenumFieldArr(1,d4) + m.write(fname,2) + # + m1=MEDFileCurveLinearMesh(fname) + mm=m1.getMesh() + self.assertTrue(mm.isEqual(mesh,1e-12)) + self.assertEqual(mm.getSpaceDimension(),3) + self.assertEqual(mm.getSpaceDimensionOnNodeStruct(),2) + # + m1=MEDFileMesh.New(fname) + self.assertTrue(isinstance(m1,MEDFileCurveLinearMesh)) + self.assertTrue(isinstance(m1.getUnivName(),str)) + self.assertTrue(len(m1.getUnivName())!=0) + self.assertTrue(m1.getMesh().isEqual(mesh,1e-12)) + pass + + def testParameters1(self): + fname="Pyfile56.med" + m=MEDCouplingCMesh() ; arr=DataArrayDouble([0.,1.2,3.5]) ; m.setCoords(arr,arr) ; m.setName("mesh") + mm=MEDFileCMesh() ; mm.setMesh(m) + ms=MEDFileMeshes() ; ms.pushMesh(mm) + data=MEDFileData() + p=MEDFileParameters() + data.setParams(p) ; data.setMeshes(ms) + pts=MEDFileParameterMultiTS() + pts.setName("A") ; pts.setDescription("An example of parameter") ; pts.setTimeUnit("ms") + pts.appendValue(1,2,3.4,567.89) + pts.appendValue(2,3,5.6,999.123) + pts2=pts.deepCpy() ; pts2.setName("B") ; pts2.setDescription("A second example") + p.pushParam(pts) ; p.pushParam(pts2) + data.write(fname,2) + p2=MEDFileParameters(fname) + self.assertTrue(p.isEqual(p2,1e-14)[0]) + self.assertAlmostEqual(p[1][1,2].getValue(),567.89,13) + p3=p.deepCpy() + pts4=pts2.deepCpy() + pts3=pts2.deepCpy() + self.assertTrue(pts3.isEqual(pts2,1e-14)[0]) + pts2.eraseTimeStepIds([0]) + self.assertTrue(not pts3.isEqual(pts2,1e-14)[0]) + del pts3[[3.4]] + self.assertTrue(pts3.isEqual(pts2,1e-14)[0]) + self.assertRaises(InterpKernelException,p[1].__getitem__,(1,2)) + self.assertRaises(InterpKernelException,p["B"].__getitem__,(1,2)) + self.assertAlmostEqual(p[0][1,2].getValue(),567.89,13) + self.assertAlmostEqual(p["A"][1,2].getValue(),567.89,13) + p=p3 + self.assertTrue(p.isEqual(p2,1e-14)[0]) + self.assertTrue(p2["B"].isEqual(pts,1e-14)[0]) + self.assertTrue(not p2["B"].isEqual(pts2,1e-14)[0]) + self.assertAlmostEqual(p2[0][1,2].getValue(),567.89,13) + self.assertEqual(p.getParamsNames(),('A','B')) + ptsr=MEDFileParameterMultiTS(fname,"B") + self.assertTrue(ptsr.isEqual(pts4,1e-14)[0]) + ptsr=MEDFileParameterMultiTS(fname) + self.assertTrue(ptsr.isEqual(pts,1e-14)[0]) + p1tsr=MEDFileParameterDouble1TS(fname) + self.assertEqual(p1tsr.getName(),"A") + self.assertAlmostEqual(p1tsr.getValue(),567.89,13) + p1tsr=MEDFileParameterDouble1TS(fname,"B") + self.assertEqual(p1tsr.getName(),"B") + self.assertAlmostEqual(p1tsr.getValue(),567.89,13) + p1tsr=MEDFileParameterDouble1TS(fname,"B",2,3) + self.assertEqual(p1tsr.getName(),"B") + self.assertAlmostEqual(p1tsr.getValue(),999.123,13) + data2=MEDFileData(fname) + self.assertEqual(2,data2.getNumberOfParams()) + self.assertAlmostEqual(data2.getParams()["B"][1,2].getValue(),567.89,13) + pass + + def testNamesOnCellAndNodesInMeshes1(self): + fname="Pyfile58.med" + fname2="Pyfile59.med" + m=MEDLoaderDataForTest.build3DSurfMesh_1() + m1=m.buildDescendingConnectivity()[0] + m1.sortCellsInMEDFileFrmt() + # + mm=MEDFileUMesh() + mm.setMeshAtLevel(0,m) + mm.setMeshAtLevel(-1,m1) + namesCellL0=DataArrayAsciiChar(6,16) + namesCellL0[:]=["CellL0#%.3d "%(i) for i in xrange(6)] + mm.setNameFieldAtLevel(0,namesCellL0) + namesCellL1=DataArrayAsciiChar.Aggregate([namesCellL0,namesCellL0,namesCellL0.substr(2)]) + namesCellL1[:]=["CellLM1#%.3d "%(i) for i in xrange(16)] + mm.setNameFieldAtLevel(-1,namesCellL1) + namesNodes=namesCellL1.substr(4,16) + namesNodes[:]=["Node#%.3d "%(i) for i in xrange(12)] + mm.setNameFieldAtLevel(1,namesNodes) + mm.write(fname,2) + # + mmr=MEDFileMesh.New(fname) + self.assertTrue(mm.getNameFieldAtLevel(0).isEqual(DataArrayAsciiChar(["CellL0#%.3d "%(i) for i in xrange(6)]))) + self.assertTrue(mm.getNameFieldAtLevel(-1).isEqual(DataArrayAsciiChar(["CellLM1#%.3d "%(i) for i in xrange(16)]))) + self.assertTrue(mm.getNameFieldAtLevel(1).isEqual(DataArrayAsciiChar(["Node#%.3d "%(i) for i in xrange(12)]))) + self.assertTrue(mm.isEqual(mmr,1e-12)[0]) + mmr.getNameFieldAtLevel(1).setIJ(0,0,'M') + self.assertTrue(not mm.isEqual(mmr,1e-12)[0]) + mmr.getNameFieldAtLevel(1).setIJ(0,0,'N') + self.assertTrue(mm.isEqual(mmr,1e-12)[0]) + mmCpy=mm.deepCpy() + self.assertTrue(mm.isEqual(mmCpy,1e-12)[0]) + # remove names on nodes + mmCpy.setNameFieldAtLevel(1,None) + self.assertTrue(not mm.isEqual(mmCpy,1e-12)[0]) + mm.setNameFieldAtLevel(1,None) + self.assertTrue(mm.isEqual(mmCpy,1e-12)[0]) + mm.setNameFieldAtLevel(-1,None) + mm.write(fname,2) + mmr=MEDFileMesh.New(fname) + self.assertEqual(mmr.getNameFieldAtLevel(1),None) + self.assertTrue(mmr.getNameFieldAtLevel(0).isEqual(DataArrayAsciiChar(["CellL0#%.3d "%(i) for i in xrange(6)]))) + self.assertEqual(mmr.getNameFieldAtLevel(-1),None) + # + c=MEDCouplingCMesh() + arr=DataArrayDouble([0.,1.1,2.3]) + c.setCoords(arr,arr) + c.setName("cmesh") + cc=MEDFileCMesh() + cc.setMesh(c) + cc.setNameFieldAtLevel(0,DataArrayAsciiChar(["Cell#%.3d "%(i) for i in xrange(4)])) + cc.setNameFieldAtLevel(1,DataArrayAsciiChar(["Node#%.3d "%(i) for i in xrange(9)])) + cc.write(fname2,2) + ccr=MEDFileMesh.New(fname2) + self.assertTrue(ccr.getNameFieldAtLevel(0).isEqual(DataArrayAsciiChar(["Cell#%.3d "%(i) for i in xrange(4)]))) + self.assertTrue(ccr.getNameFieldAtLevel(1).isEqual(DataArrayAsciiChar(["Node#%.3d "%(i) for i in xrange(9)]))) + self.assertTrue(cc.isEqual(ccr,1e-12)[0]) + ccr.getNameFieldAtLevel(1).setIJ(0,0,'M') + self.assertTrue(not cc.isEqual(ccr,1e-12)[0]) + ccr.getNameFieldAtLevel(1).setIJ(0,0,'N') + self.assertTrue(cc.isEqual(ccr,1e-12)[0]) + ccCpy=cc.deepCpy() + self.assertTrue(cc.isEqual(ccCpy,1e-12)[0]) + pass + + def testToExportInExamples1(self): + m=MEDCouplingCMesh() + arr=DataArrayDouble([0.,1.,2.,3.,4.]) + m.setCoords(arr,arr) + m=m.buildUnstructured() ; m.setName("mesh") + grp1=DataArrayInt([0,1,2,4,5,6,8,9,10,12,13,14]) ; grp1.setName("grp1") + grp2=DataArrayInt([3,7,11,15]) ; grp2.setName("grp2") + m2=m.computeSkin() + mm=MEDFileUMesh() + mm.setMeshAtLevel(0,m) + mm.setMeshAtLevel(-1,m2) + mm.setGroupsAtLevel(0,[grp1,grp2]) + mm.write("example.med",2) + # + m0=mm.getMeshAtLevel(0) + m1=mm.getMeshAtLevel(-1) + grp1=mm.getGroupArr(0,"grp1") + grp2=mm.getGroupArr(0,"grp2") + grps=[grp1,grp2] + whichGrp=DataArrayInt(m0.getNumberOfCells()) + whichGrp.fillWithValue(-1) + for grpId,grp in enumerate(grps): + whichGrp[grp]=grpId + pass + a,b,bI,c,cI=m0.buildDescendingConnectivity() + e,f=a.areCellsIncludedIn(m1,2) + self.assertTrue(e) + c2,c2I=MEDCouplingUMesh.ExtractFromIndexedArrays(f,c,cI) + self.assertTrue(c2I.deltaShiftIndex().isUniform(1)) + c2.transformWithIndArr(whichGrp) + splitOfM1=len(grps)*[None] + for grpId,grp in enumerate(grps): + tmp=c2.getIdsEqual(grpId) + splitOfM1[grpId]=tmp + pass + splitOfM1[0].isEqual(DataArrayInt([0,1,2,3,6,8,10,11,12,13])) + splitOfM1[1].isEqual(DataArrayInt([4,5,7,9,14,15])) + pass + + def testBugCorrection1(self): + fs=MEDFileFields() + fs.resize(3) + self.assertEqual(fs[0],None) + self.assertEqual(3,len(fs)) + pass + + def testCompareMEDFilesContainingOnlyFieldsOnCell1(self): + f1Name="Pyfile60.med" + f2Name="Pyfile61.med" + d1=MEDLoaderDataForTest.buildACompleteMEDDataStructureWithFieldsOnCells_1() + d1.write(f1Name,2) + d2=MEDLoaderDataForTest.buildACompleteMEDDataStructureWithFieldsOnCells_1() + d2.write(f2Name,2) + # reading and compare + d1=MEDFileData(f1Name) ; d2=MEDFileData(f2Name) + for mn in d1.getMeshes().getMeshesNames(): + m1=d1.getMeshes()[mn] + m2=d2.getMeshes()[mn] + for lev in m1.getNonEmptyLevels(): + grpsNames=m1.getGroupsOnSpecifiedLev(lev) + for grpName in grpsNames: + self.assertTrue(m1.getGroupArr(lev,grpName).isEqual(m2.getGroupArr(lev,grpName))) # compare groups + pass + pass + pass + for fieldn in d1.getFields().getFieldsNames(): + f1=d1.getFields()[fieldn] + f2=d2.getFields()[fieldn] + for it,order,tim in f1.getTimeSteps(): + f1t=f1[it,order] + f2t=f2[it,order] + if len(f1t.getPflsReallyUsed())!=0: + # profile case + for lev in f1t.getNonEmptyLevels()[1]: + arr1,pfl1=f1t.getFieldWithProfile(ON_CELLS,lev,m1) + arr2,pfl2=f2t.getFieldWithProfile(ON_CELLS,lev,m2) + self.assertTrue(pfl1.isEqual(pfl2)) + self.assertTrue(arr1.isEqual(arr2,1e-10)) + pass + pass + else: + # no profile case + for lev in f1t.getNonEmptyLevels()[1]: + f1mc=f1t.getFieldOnMeshAtLevel(ON_CELLS,lev,m1) + f2mc=f2t.getFieldOnMeshAtLevel(ON_CELLS,lev,m2) + self.assertTrue(f1mc.isEqual(f2mc,1e-10,1e-10)) + pass + pass + pass + pass + pass + + def testNonRegBugNormalizeFamIdsMEDFile1(self): + m=MEDCouplingCMesh() + arr=DataArrayDouble([0.,1.,2.,3.,4.]) + m.setCoords(arr,arr,arr) + m=m.buildUnstructured() + m2=m.buildDescendingConnectivity()[0] + m.setName("mesh") + g1=DataArrayInt([0,1,2,3]) ; g1.setName("g1") + g2=DataArrayInt([2,3,5,6]) ; g2.setName("g2") + g1Face=DataArrayInt([20,21,22,23]) ; g1Face.setName("g1Face") + g2Face=DataArrayInt([22,23,25,26]) ; g2Face.setName("g2Face") + g1Node=DataArrayInt([10,11,12,13]) ; g1Node.setName("g1Node") + g2Node=DataArrayInt([12,13,15,16]) ; g2Node.setName("g2Node") + mm=MEDFileUMesh() + mm.setMeshAtLevel(0,m) + mm.setGroupsAtLevel(0,[g1,g2]) + s1=set(mm.getFamiliesOnGroup("g1")) ; s2=set(mm.getFamiliesOnGroup("g2")) + self.assertEqual(mm.getGrpNonEmptyLevelsExt("g1"),(0,)) + self.assertEqual(mm.getGrpNonEmptyLevelsExt("g2"),(0,)) + mm.normalizeFamIdsMEDFile() + self.assertEqual(mm.getGrpNonEmptyLevelsExt("g1"),(0,)) + self.assertEqual(mm.getGrpNonEmptyLevelsExt("g2"),(0,)) + self.assertTrue(mm.getGroupArr(0,"g1").isEqual(g1)) + self.assertTrue(mm.getGroupArr(0,"g2").isEqual(g2)) + self.assertEqual(s1,set(mm.getFamiliesOnGroup("g1"))) + self.assertEqual(s2,set(mm.getFamiliesOnGroup("g2"))) + for g in mm.getGroupsOnSpecifiedLev(0): + for f in mm.getFamiliesIdsOnGroup(g): + self.assertTrue(f<0) + pass + pass + # + mm=MEDFileUMesh() + mm.setMeshAtLevel(0,m) + mm.setMeshAtLevel(-1,m2) + mm.setGroupsAtLevel(0,[g1,g2]) + mm.setGroupsAtLevel(-1,[g1Face,g2Face]) + s1=set(mm.getFamiliesOnGroup("g1")) ; s2=set(mm.getFamiliesOnGroup("g2")) + s3=set(mm.getFamiliesOnGroup("g1Face")) ; s4=set(mm.getFamiliesOnGroup("g2Face")) + self.assertEqual(mm.getGrpNonEmptyLevelsExt("g1"),(0,)) + self.assertEqual(mm.getGrpNonEmptyLevelsExt("g2"),(0,)) + self.assertEqual(mm.getGrpNonEmptyLevelsExt("g1Face"),(-1,)) + self.assertEqual(mm.getGrpNonEmptyLevelsExt("g2Face"),(-1,)) + mm.normalizeFamIdsMEDFile() + self.assertEqual(mm.getGrpNonEmptyLevelsExt("g1"),(0,)) + self.assertEqual(mm.getGrpNonEmptyLevelsExt("g2"),(0,)) + self.assertEqual(mm.getGrpNonEmptyLevelsExt("g1Face"),(-1,)) + self.assertEqual(mm.getGrpNonEmptyLevelsExt("g2Face"),(-1,)) + self.assertTrue(mm.getGroupArr(0,"g1").isEqual(g1)) + self.assertTrue(mm.getGroupArr(0,"g2").isEqual(g2)) + self.assertTrue(mm.getGroupArr(-1,"g1Face").isEqual(g1Face)) + self.assertTrue(mm.getGroupArr(-1,"g2Face").isEqual(g2Face)) + self.assertEqual(s1,set(mm.getFamiliesOnGroup("g1"))) + self.assertEqual(s2,set(mm.getFamiliesOnGroup("g2"))) + self.assertEqual(s3,set(mm.getFamiliesOnGroup("g1Face"))) + self.assertEqual(s4,set(mm.getFamiliesOnGroup("g2Face"))) + for lev in [0,-1]: + for g in mm.getGroupsOnSpecifiedLev(lev): + for f in mm.getFamiliesIdsOnGroup(g): + self.assertTrue(f<0) + pass + pass + pass + # + mm=MEDFileUMesh() + mm.setMeshAtLevel(0,m) + mm.setMeshAtLevel(-1,m2) + mm.setGroupsAtLevel(0,[g1,g2]) + mm.setGroupsAtLevel(-1,[g1Face,g2Face]) + mm.setGroupsAtLevel(1,[g1Node,g2Node]) + s1=set(mm.getFamiliesOnGroup("g1")) ; s2=set(mm.getFamiliesOnGroup("g2")) + s3=set(mm.getFamiliesOnGroup("g1Face")) ; s4=set(mm.getFamiliesOnGroup("g2Face")) + s5=set(mm.getFamiliesOnGroup("g1Node")) ; s6=set(mm.getFamiliesOnGroup("g2Node")) + self.assertEqual(mm.getGrpNonEmptyLevelsExt("g1"),(0,)) + self.assertEqual(mm.getGrpNonEmptyLevelsExt("g2"),(0,)) + self.assertEqual(mm.getGrpNonEmptyLevelsExt("g1Face"),(-1,)) + self.assertEqual(mm.getGrpNonEmptyLevelsExt("g2Face"),(-1,)) + self.assertEqual(mm.getGrpNonEmptyLevelsExt("g1Node"),(1,)) + self.assertEqual(mm.getGrpNonEmptyLevelsExt("g2Node"),(1,)) + mm.normalizeFamIdsMEDFile() + self.assertEqual(mm.getGrpNonEmptyLevelsExt("g1"),(0,)) + self.assertEqual(mm.getGrpNonEmptyLevelsExt("g2"),(0,)) + self.assertEqual(mm.getGrpNonEmptyLevelsExt("g1Face"),(-1,)) + self.assertEqual(mm.getGrpNonEmptyLevelsExt("g2Face"),(-1,)) + self.assertEqual(mm.getGrpNonEmptyLevelsExt("g1Node"),(1,)) + self.assertEqual(mm.getGrpNonEmptyLevelsExt("g2Node"),(1,)) + self.assertTrue(mm.getGroupArr(0,"g1").isEqual(g1)) + self.assertTrue(mm.getGroupArr(0,"g2").isEqual(g2)) + self.assertTrue(mm.getGroupArr(-1,"g1Face").isEqual(g1Face)) + self.assertTrue(mm.getGroupArr(-1,"g2Face").isEqual(g2Face)) + self.assertTrue(mm.getGroupArr(1,"g1Node").isEqual(g1Node)) + self.assertTrue(mm.getGroupArr(1,"g2Node").isEqual(g2Node)) + self.assertEqual(s1,set(mm.getFamiliesOnGroup("g1"))) + self.assertEqual(s2,set(mm.getFamiliesOnGroup("g2"))) + self.assertEqual(s3,set(mm.getFamiliesOnGroup("g1Face"))) + self.assertEqual(s4,set(mm.getFamiliesOnGroup("g2Face"))) + self.assertEqual(s5,set(mm.getFamiliesOnGroup("g1Node"))) + self.assertEqual(s6,set(mm.getFamiliesOnGroup("g2Node"))) + for lev in [0,-1]: + for g in mm.getGroupsOnSpecifiedLev(lev): + for f in mm.getFamiliesIdsOnGroup(g): + self.assertTrue(f<0) + pass + pass + pass + for g in mm.getGroupsOnSpecifiedLev(1): + for f in mm.getFamiliesIdsOnGroup(g): + self.assertTrue(f>0) + pass + pass + pass + + def testNonRegressionMantis22212ChangeGrpName(self): + fileName="Pyfile62.med" + m2,m1,m0,f2,f1,f0,p,n2,n1,n0,fns,fids,grpns,famIdsPerGrp=MEDLoaderDataForTest.buildMultiLevelMesh_1() + m=MEDFileUMesh.New() + m.setCoords(m2.getCoords()) + m.setMeshAtLevel(0,m2) + m.setMeshAtLevel(-1,m1) + m.setMeshAtLevel(-2,m0) + m.setFamilyFieldArr(0,f2) + m.setFamilyFieldArr(-1,f1) + m.setFamilyFieldArr(-2,f0) + m.setFamilyFieldArr(1,p) + nbOfFams=len(fns) + for i in xrange(nbOfFams): + m.addFamily(fns[i],fids[i]) + pass + nbOfGrps=len(grpns) + for i in xrange(nbOfGrps): + m.setFamiliesIdsOnGroup(grpns[i],famIdsPerGrp[i]) + pass + m.setName(m2.getName()) + m.setDescription(m2.getDescription()) + m.write(fileName,2) + # + mm0=MEDFileMesh.New(fileName) + mm1=MEDFileMesh.New(fileName) + groupNamesIni=MEDLoader.GetMeshGroupsNames(fileName,"ma") + for name in groupNamesIni: + mm1.changeGroupName(name,name+'N') + pass + mm1.write(fileName,2) + del mm1 + # + mm2=MEDFileMesh.New(fileName) + for name in groupNamesIni: + for lev in mm0.getGrpNonEmptyLevelsExt(name): + arr0=mm0.getGroupArr(lev,name) + arr2=mm2.getGroupArr(lev,name+'N') + arr0.setName(name+'N') + self.assertTrue(arr0.isEqual(arr2)) + pass + pass + pass + + def testInt32InMEDFileFieldStar1(self): + fname="Pyfile63.med" + f1=MEDLoaderDataForTest.buildVecFieldOnCells_1(); + arr=f1.getArray().convertToIntArr() + f1.setArray(None) + m1=f1.getMesh() + mm1=MEDFileUMesh.New() + mm1.setCoords(m1.getCoords()) + mm1.setMeshAtLevel(0,m1) + mm1.setName(m1.getName()) + mm1.write(fname,2) + ff1=MEDFileIntField1TS() + ff1.setFieldNoProfileSBT(f1,arr) + a,b=ff1.getFieldOnMeshAtLevel(0,ON_CELLS,mm1) + self.assertEqual(b.getInfoOnComponents(),['power [MW/m^3]','density [g/cm^3]','temperature [K]']) + self.assertTrue(b.isEqual(arr)) + self.assertTrue(a.isEqual(f1,1e-12,1e-12)) + ff1.write(fname,0) + ff2=MEDFileAnyTypeField1TS.New(fname) + self.assertEqual(ff2.getName(),"VectorFieldOnCells") + self.assertEqual(ff2.getTime(),[0,1,2.0]) + self.assertTrue(isinstance(ff2,MEDFileIntField1TS)) + a,b=ff1.getFieldOnMeshAtLevel(0,ON_CELLS,mm1) + self.assertEqual(b.getInfoOnComponents(),['power [MW/m^3]','density [g/cm^3]','temperature [K]']) + self.assertTrue(b.isEqual(arr)) + self.assertTrue(a.isEqual(f1,1e-12,1e-12)) + ff2.setTime(1,2,3.) + c=ff2.getUndergroundDataArray() ; c*=2 + ff2.write(fname,0) # 2 time steps in + ffs1=MEDFileAnyTypeFieldMultiTS.New(fname,"VectorFieldOnCells") + self.assertEqual(ffs1.getTimeSteps(),[(0, 1, 2.0), (1, 2, 3.0)]) + self.assertEqual(len(ffs1),2) + self.assertTrue(isinstance(ffs1,MEDFileIntFieldMultiTS)) + a,b=ffs1[2.].getFieldOnMeshAtLevel(0,ON_CELLS,mm1) + self.assertTrue(b.isEqual(arr)) + self.assertTrue(a.isEqual(f1,1e-12,1e-12)) + a,b=ffs1[2.].getFieldOnMeshAtLevel(0,ON_CELLS,mm1) + self.assertTrue(b.isEqual(arr)) + self.assertTrue(a.isEqual(f1,1e-12,1e-12)) + it=ffs1.__iter__() ; it.next() ; ff2bis=it.next() + a,b=ff2bis.getFieldOnMeshAtLevel(0,ON_CELLS,mm1) + self.assertTrue(b.isEqual(2*arr)) + f1.setTime(3.,1,2) + self.assertTrue(a.isEqual(f1,1e-12,1e-12)) + bc=DataArrayInt(6,3) ; bc[:]=0 ; bc.setInfoOnComponents(['power [MW/m^3]','density [g/cm^3]','temperature [K]']) + for it in ffs1: + a,b=it.getFieldOnMeshAtLevel(0,ON_CELLS,mm1) + bc+=b + pass + self.assertTrue(bc.isEqual(3*arr)) + nf1=MEDCouplingFieldDouble(ON_NODES) + nf1.setTime(9.,10,-1) + nf1.setMesh(f1.getMesh()) + narr=DataArrayInt(12,2) ; narr.setInfoOnComponents(["aa [u1]","bbbvv [ppp]"]) ; narr[:,0]=range(12) ; narr[:,1]=2*narr[:,0] + nf1.setName("VectorFieldOnNodes") + nff1=MEDFileIntField1TS.New() + nff1.setFieldNoProfileSBT(nf1,narr) + self.assertEqual(nff1.getInfo(),('aa [u1]','bbbvv [ppp]')) + self.assertEqual(nff1.getTime(),[10,-1,9.0]) + nff1.write(fname,0) + # + nf2=MEDCouplingFieldDouble(ON_NODES) + nf2.setTime(19.,20,-11) + nf2.setMesh(f1.getMesh()) + narr2=DataArrayInt(8,2) ; narr.setInfoOnComponents(["aapfl [u1]","bbbvvpfl [ppp]"]) ; narr2[:,0]=range(8) ; narr2[:,0]+=10 ; narr2[:,1]=3*narr2[:,0] + nf2.setName("VectorFieldOnNodesPfl") ; narr2.setName(nf2.getName()) + nff2=MEDFileIntField1TS.New() + npfl=DataArrayInt([1,2,4,5,6,7,10,11]) ; npfl.setName("npfl") + nff2.setFieldProfile(nf2,narr2,mm1,0,npfl) + nff2.getFieldWithProfile(ON_NODES,0,mm1) + a,b=nff2.getFieldWithProfile(ON_NODES,0,mm1) ; b.setName(npfl.getName()) + self.assertTrue(b.isEqual(npfl)) + self.assertTrue(a.isEqual(narr2)) + nff2.write(fname,0) + nff2bis=MEDFileIntField1TS(fname,"VectorFieldOnNodesPfl") + a,b=nff2bis.getFieldWithProfile(ON_NODES,0,mm1) ; b.setName(npfl.getName()) + self.assertTrue(b.isEqual(npfl)) + self.assertTrue(a.isEqual(narr2)) + # + nf3=MEDCouplingFieldDouble(ON_NODES) + nf3.setName("VectorFieldOnNodesDouble") + nf3.setTime(29.,30,-21) + nf3.setMesh(f1.getMesh()) + nf3.setArray(f1.getMesh().getCoords()) + nff3=MEDFileField1TS.New() + nff3.setFieldNoProfileSBT(nf3) + nff3.write(fname,0) + fs=MEDFileFields(fname) + self.assertEqual(len(fs),4) + ffs=[it for it in fs] + self.assertTrue(isinstance(ffs[0],MEDFileIntFieldMultiTS)) + self.assertTrue(isinstance(ffs[1],MEDFileIntFieldMultiTS)) + self.assertTrue(isinstance(ffs[2],MEDFileFieldMultiTS)) + self.assertTrue(isinstance(ffs[3],MEDFileIntFieldMultiTS)) + # + self.assertTrue(fs["VectorFieldOnCells"][0].getUndergroundDataArray().isEqualWithoutConsideringStr(arr)) + self.assertTrue(fs["VectorFieldOnCells"][1,2].getUndergroundDataArray().isEqualWithoutConsideringStr(2*arr)) + self.assertTrue(fs["VectorFieldOnNodesPfl"][0].getUndergroundDataArray().isEqualWithoutConsideringStr(narr2)) + self.assertTrue(fs["VectorFieldOnNodes"][9.].getUndergroundDataArray().isEqualWithoutConsideringStr(narr)) + self.assertTrue(fs["VectorFieldOnNodesDouble"][29.].getUndergroundDataArray().isEqualWithoutConsideringStr(f1.getMesh().getCoords(),1e-12)) + # + nf3_read=MEDFileFieldMultiTS(fname,"VectorFieldOnNodesDouble") + self.assertTrue(nf3_read[29.].getUndergroundDataArray().isEqualWithoutConsideringStr(f1.getMesh().getCoords(),1e-12)) + self.assertRaises(InterpKernelException,MEDFileIntFieldMultiTS.New,fname,"VectorFieldOnNodesDouble")# exception because trying to read a double field with int instance + self.assertRaises(InterpKernelException,MEDFileFieldMultiTS.New,fname,"VectorFieldOnNodes")# exception because trying to read a int field with double instance + MEDFileField1TS.New(fname,"VectorFieldOnNodesDouble",30,-21) + self.assertRaises(InterpKernelException,MEDFileIntField1TS.New,fname,"VectorFieldOnNodesDouble",30,-21)# exception because trying to read a double field with int instance + MEDFileIntField1TS.New(fname,"VectorFieldOnNodes",10,-1) + self.assertRaises(InterpKernelException,MEDFileField1TS.New,fname,"VectorFieldOnNodes",10,-1)# exception because trying to read a double field with int instance + # + self.assertEqual(fs.getMeshesNames(),('3DSurfMesh_1','3DSurfMesh_1','3DSurfMesh_1','3DSurfMesh_1')) + self.assertTrue(fs.changeMeshNames([('3DSurfMesh_1','3DSurfMesh')])) + self.assertEqual(fs.getMeshesNames(),('3DSurfMesh','3DSurfMesh','3DSurfMesh','3DSurfMesh')) + self.assertTrue(not fs.changeMeshNames([('3DSurfMesh_1','3DSurfMesh')])) + pass + + def testMEDFileFields1(self): + fname="Pyfile64.med" + f1=MEDCouplingFieldDouble(ON_NODES) + f1.setTime(0.001,0,-1) ; f1.setTimeUnit("us") + c=DataArrayDouble(12) ; c.iota(); m=MEDCouplingCMesh() ; m.setCoordsAt(0,c) ; m.setName("mesh") + mm=MEDFileCMesh() ; mm.setMesh(m) ; mm.write(fname,2) + f1.setMesh(m) + arr=DataArrayDouble(12,2) ; arr.setInfoOnComponents(["aa [u1]","bbbvv [ppp]"]) ; arr[:,0]=range(12) ; arr[:,1]=2*arr[:,0] + f1.setArray(arr) + f1.setName("Field1") + ff1=MEDFileField1TS.New() + ff1.setFieldNoProfileSBT(f1) + self.assertEqual(ff1.getDtUnit(),"us") + ff1.write(fname,0) + f1.setTime(1.001,1,-1) ; ff1=MEDFileField1TS.New() ; ff1.setFieldNoProfileSBT(f1) ; ff1.write(fname,0) + f1.setTime(2.001,2,-1) ; ff1=MEDFileField1TS.New() ; ff1.setFieldNoProfileSBT(f1) ; ff1.write(fname,0) + # + self.assertEqual(MEDFileFields(fname).getCommonIterations(),([(0,-1),(1,-1),(2,-1)],False)) + ff1s=MEDFileFieldMultiTS(fname,"Field1") + ff1s.setName("Field2") + ff1s.write(fname,0) + self.assertEqual(MEDFileFields(fname).getCommonIterations(),([(0,-1),(1,-1),(2,-1)],False)) + f1.setTime(3.001,3,-1) ; ff1=MEDFileField1TS.New() ; ff1.setFieldNoProfileSBT(f1) ; ff1.write(fname,0) + self.assertEqual(MEDFileFields(fname).getCommonIterations(),([(0,-1),(1,-1),(2,-1)],True)) + self.assertEqual(MEDFileFields(fname).partOfThisLyingOnSpecifiedTimeSteps([(1,-1)]).getCommonIterations(),([(1,-1)],False)) + self.assertEqual(MEDFileFields(fname).partOfThisNotLyingOnSpecifiedTimeSteps([(1,-1)]).getCommonIterations(),([(0,-1),(2,-1)],True)) + f1.setName("Field2") ; f1.setTime(3.001,3,-1) ; ff1=MEDFileField1TS.New() ; ff1.setFieldNoProfileSBT(f1) ; ff1.write(fname,0) + self.assertEqual(MEDFileFields(fname).getCommonIterations(),([(0,-1),(1,-1),(2,-1),(3,-1)],False)) + self.assertEqual(MEDFileFields(fname)[1].getDtUnit(),"us") + pass + + # Multi time steps and multi fields management without Globals (profiles, locs) aspects + def testMEDFileFields2(self): + fname="Pyfile65.med" + # to check that all is initialize + MEDFileField1TS().__str__() + MEDFileFieldMultiTS().__str__() + # building a mesh containing 4 tri3 + 5 quad4 + tri=MEDCouplingUMesh("tri",2) + tri.allocateCells() ; tri.insertNextCell(NORM_TRI3,[0,1,2]) + tri.setCoords(DataArrayDouble([(0.,0.),(0.,1.),(1.,0.)])) + tris=[tri.deepCpy() for i in xrange(4)] + for i,elt in enumerate(tris): elt.translate([i,0]) + tris=MEDCouplingUMesh.MergeUMeshes(tris) + quad=MEDCouplingUMesh("quad",2) + quad.allocateCells() ; quad.insertNextCell(NORM_QUAD4,[0,1,2,3]) + quad.setCoords(DataArrayDouble([(0.,0.),(0.,1.),(1.,1.),(1.,0.)])) + quads=[quad.deepCpy() for i in xrange(5)] + for i,elt in enumerate(quads): elt.translate([5+i,0]) + quads=MEDCouplingUMesh.MergeUMeshes(quads) + m=MEDCouplingUMesh.MergeUMeshes(tris,quads) + m.setName("mesh") ; m.getCoords().setInfoOnComponents(["XX [m]","YYY [km]"]) + # + fmts0_0=MEDFileFieldMultiTS() + fmts0_1=MEDFileFieldMultiTS() + # time steps + for i in xrange(10): + infos1=["aa [bb]","ccc [ddd]"] ; name1="1stField" + d=DataArrayDouble(18) ; d.iota(i*10) ; d.rearrange(2) ; d.setInfoOnComponents(infos1) + f=MEDCouplingFieldDouble(ON_CELLS) ; f.setName(name1) ; f.setArray(d) ; f.setMesh(m) + f.setTime(float(i+1)+0.1,i+1,-i-1) + fmts0_0.appendFieldNoProfileSBT(f) + f1ts=MEDFileField1TS() ; f1ts.setFieldNoProfileSBT(f) ; fmts0_1.pushBackTimeStep(f1ts) + self.assertEqual(fmts0_1.getName(),name1) + self.assertEqual(fmts0_0.getInfo(),('aa [bb]','ccc [ddd]')) + self.assertEqual(fmts0_1.getInfo(),('aa [bb]','ccc [ddd]')) + if i>1: + # components names have been modified to generate errors + d.setInfoOnComponents(['aa [bb]','eee [dd]']) + self.assertRaises(InterpKernelException,fmts0_0.appendFieldNoProfileSBT,f) + self.assertRaises(InterpKernelException,f1ts.setInfo,['aa [bb]'])#throw because mismatch of number of components + f1ts.setInfo(['aa [bb]','eee [dd]']) + self.assertRaises(InterpKernelException,fmts0_1.pushBackTimeStep,f1ts) + pass + # add a mismatch of nb of compos + pass + fmts0_2=fmts0_0.deepCpy() + fmts0_3=fmts0_0.deepCpy() + fmts0_4=fmts0_0.deepCpy() + fmts0_5=fmts0_0.shallowCpy() + self.assertTrue(len(fmts0_0)==10 and len(fmts0_1)==10 and len(fmts0_2)==10 and len(fmts0_3)==10 and len(fmts0_4)==10 and len(fmts0_5)==10) + del fmts0_2[::2] + self.assertTrue(len(fmts0_2)==5 and fmts0_2.getIterations()==[(2,-2),(4,-4),(6,-6),(8,-8),(10,-10)]) + del fmts0_3[[1.1,(6,-6),9]] + self.assertTrue(len(fmts0_3)==7 and fmts0_3.getIterations()==[(2,-2),(3,-3),(4,-4),(5,-5),(7,-7),(8,-8),(9,-9)]) + fmts0_6=fmts0_4[[1.1,(6,-6),8]] + self.assertTrue(isinstance(fmts0_6,MEDFileFieldMultiTS)) + self.assertTrue(len(fmts0_6)==3 and fmts0_6.getIterations()==[(1,-1),(6,-6),(9,-9)]) + fmts0_7=fmts0_4[::-3] + self.assertTrue(isinstance(fmts0_7,MEDFileFieldMultiTS)) + self.assertTrue(len(fmts0_7)==4 and fmts0_7.getIterations()==[(10,-10),(7,-7),(4,-4),(1,-1)]) + # + fs0=MEDFileFields() + fs0.pushField(fmts0_0) + fmts0_2.setName("2ndField") ; fs0.pushField(fmts0_2) + fmts0_3.setName("3rdField") ; fs0.pushField(fmts0_3) + fmts0_4.setName("4thField") ; fs0.pushField(fmts0_4) + self.assertTrue(len(fs0)==4 and fs0.getFieldsNames()==('1stField','2ndField','3rdField','4thField')) + fs0.write(fname,2) + fs0=MEDFileFields(fname) + self.assertEqual(fs0.getCommonIterations(),([(2,-2),(4,-4),(8,-8)],True)) + fs1=fs0.partOfThisLyingOnSpecifiedTimeSteps(fs0.getCommonIterations()[0]) + self.assertTrue(fs1.getFieldsNames()==('1stField','2ndField','3rdField','4thField') and fs1.getCommonIterations()==([(2,-2),(4,-4),(8,-8)],False)) + del fs1[["2ndField",3]] + self.assertTrue(fs1.getFieldsNames()==('1stField','3rdField') and fs1.getCommonIterations()==([(2,-2),(4,-4),(8,-8)],False)) + fs2=fs0[[0,"4thField"]] + self.assertTrue(isinstance(fs2,MEDFileFields)) + self.assertEqual(fs2.getFieldsNames(),('1stField','4thField')) + # + mm=MEDFileUMesh() ; mm.setMeshAtLevel(0,m) ; mm.write(fname,0) + pass + + # Multi time steps and multi fields management with Globals (profiles, locs) aspects + def testMEDFileFields3(self): + fname="Pyfile66.med" + # building a mesh containing 4 tri3 + 5 quad4 + tri=MEDCouplingUMesh("tri",2) + tri.allocateCells() ; tri.insertNextCell(NORM_TRI3,[0,1,2]) + tri.setCoords(DataArrayDouble([(0.,0.),(0.,1.),(1.,0.)])) + tris=[tri.deepCpy() for i in xrange(4)] + for i,elt in enumerate(tris): elt.translate([i,0]) + tris=MEDCouplingUMesh.MergeUMeshes(tris) + quad=MEDCouplingUMesh("quad",2) + quad.allocateCells() ; quad.insertNextCell(NORM_QUAD4,[0,1,2,3]) + quad.setCoords(DataArrayDouble([(0.,0.),(0.,1.),(1.,1.),(1.,0.)])) + quads=[quad.deepCpy() for i in xrange(5)] + for i,elt in enumerate(quads): elt.translate([5+i,0]) + quads=MEDCouplingUMesh.MergeUMeshes(quads) + m=MEDCouplingUMesh.MergeUMeshes(tris,quads) + m.setName("mesh") ; m.getCoords().setInfoOnComponents(["XX [m]","YYY [km]"]) + # + mm=MEDFileUMesh() ; mm.setMeshAtLevel(0,m) ; mm.write(fname,2) + # + pfl=DataArrayInt([0,1,2,3,4,5,6]) ; pfl.setName("pfl") + pfl2=DataArrayInt([0,1,2,3,4,5,6,8]) ; pfl2.setName("pfl2") + fmts0_0=MEDFileFieldMultiTS() + fmts0_1=MEDFileFieldMultiTS() + # time steps + for i in xrange(10): + infos1=["aa [bb]","ccc [ddd]"] ; name1="1stField" + d=DataArrayDouble(14) ; d.iota(i*10) ; d.rearrange(2) ; d.setInfoOnComponents(infos1) + f=MEDCouplingFieldDouble(ON_CELLS) ; f.setName(name1) ; f.setArray(d) ; f.setMesh(m) + f.setTime(float(i+1)+0.1,i+1,-i-1) + fmts0_0.appendFieldProfile(f,mm,0,pfl) + f1ts=MEDFileField1TS() ; f1ts.setFieldProfile(f,mm,0,pfl) ; fmts0_1.pushBackTimeStep(f1ts) + self.assertEqual(fmts0_0.getInfo(),('aa [bb]','ccc [ddd]')) + self.assertEqual(fmts0_1.getInfo(),('aa [bb]','ccc [ddd]')) + pass + # + self.assertEqual(fmts0_0.getPfls(),10*('pfl_NORM_QUAD4',)) + self.assertEqual(fmts0_1.getPfls(),('pfl_NORM_QUAD4',)) + fmts0_0.zipPflsNames() + self.assertEqual(fmts0_0.getPfls(),('pfl_NORM_QUAD4',)) + self.assertTrue(fmts0_1.getProfile("pfl_NORM_QUAD4").isEqual(fmts0_0.getProfile("pfl_NORM_QUAD4"))) + fmts0_2=fmts0_0.deepCpy() + fmts0_3=fmts0_0.deepCpy() + fmts0_4=fmts0_0.deepCpy() + fs0=MEDFileFields() + fs0.pushField(fmts0_0) + fmts0_2.setName("2ndField") ; fs0.pushField(fmts0_2) + fmts0_3.setName("3rdField") ; fs0.pushField(fmts0_3) + fmts0_4.setName("4thField") ; fs0.pushField(fmts0_4) + self.assertEqual(fs0.getPfls(),('pfl_NORM_QUAD4',)) + # + fmts0_5=MEDFileFieldMultiTS() + for i in xrange(7): + infos1=["aa [bb]","ccc [ddd]"] ; name1="1stField" + d=DataArrayDouble(16) ; d.iota(i*10) ; d.rearrange(2) ; d.setInfoOnComponents(infos1) + f=MEDCouplingFieldDouble(ON_CELLS) ; f.setName(name1) ; f.setArray(d) ; f.setMesh(m) + f.setTime(float(i+1)+0.1,i+1,-i-1) + f1ts=MEDFileField1TS() ; f1ts.setFieldProfile(f,mm,0,pfl2) ; fmts0_5.pushBackTimeStep(f1ts) + pass + fmts0_5.setName("5thField") ; fs0.pushField(fmts0_5) + self.assertEqual(fs0.getPfls(),('pfl_NORM_QUAD4','pfl2_NORM_QUAD4')) + fs0.checkGlobsCoherency() + fs0.write(fname,0) + pass + + def testSplitComponents1(self): + fname="Pyfile67.med" + # building a mesh containing 4 tri3 + 5 quad4 + tri=MEDCouplingUMesh("tri",2) + tri.allocateCells() ; tri.insertNextCell(NORM_TRI3,[0,1,2]) + tri.setCoords(DataArrayDouble([(0.,0.),(0.,1.),(1.,0.)])) + tris=[tri.deepCpy() for i in xrange(4)] + for i,elt in enumerate(tris): elt.translate([i,0]) + tris=MEDCouplingUMesh.MergeUMeshes(tris) + quad=MEDCouplingUMesh("quad",2) + quad.allocateCells() ; quad.insertNextCell(NORM_QUAD4,[0,1,2,3]) + quad.setCoords(DataArrayDouble([(0.,0.),(0.,1.),(1.,1.),(1.,0.)])) + quads=[quad.deepCpy() for i in xrange(5)] + for i,elt in enumerate(quads): elt.translate([5+i,0]) + quads=MEDCouplingUMesh.MergeUMeshes(quads) + m=MEDCouplingUMesh.MergeUMeshes(tris,quads) + m.setName("mesh") ; m.getCoords().setInfoOnComponents(["XX [m]","YYY [km]"]) + # + mm=MEDFileUMesh() ; mm.setMeshAtLevel(0,m) ; mm.write(fname,2) + # + pfl=DataArrayInt([0,1,2,3,4,5,6]) ; pfl.setName("pfl") + pfl2=DataArrayInt([0,1,2,3,4,5,6,8]) ; pfl2.setName("pfl2") + fs=MEDFileFields() + fmts0_1=MEDFileFieldMultiTS() + # time steps + infos1=['aa [bb]','ccc [ddd]',"ZZZZ [MW*s]"] + for i in xrange(10): + name1="1stField" + d=DataArrayDouble(21) ; d.iota(i*10) ; d.rearrange(3) ; d.setInfoOnComponents(infos1) + f=MEDCouplingFieldDouble(ON_CELLS) ; f.setName(name1) ; f.setArray(d) ; f.setMesh(m) + f.setTime(float(i+1)+0.1,i+1,-i-1) + f1ts=MEDFileField1TS() ; f1ts.setFieldProfile(f,mm,0,pfl) ; fmts0_1.pushBackTimeStep(f1ts) + self.assertEqual(fmts0_1.getInfo(),tuple(infos1)) + pass + fs.pushField(fmts0_1) + self.assertEqual(1,len(fs)) + l=fmts0_1.splitComponents() + self.assertEqual(3,len(l)) + for elt in l: self.assertEqual(10,len(elt)) + for elt in l: self.assertTrue(isinstance(elt,MEDFileFieldMultiTS)) + for elt in l: + elt.setName("%s_%s"%(elt.getName(),DataArray.GetVarNameFromInfo(elt.getInfo()[0]))) + pass + fs.pushFields(l) + self.assertEqual(4,len(fs)) + for elt in fs: self.assertEqual(10,len(elt)) + self.assertEqual(fs.getPfls(),('pfl_NORM_QUAD4',)) + self.assertEqual(fs.getPflsReallyUsed(),('pfl_NORM_QUAD4',)) + # + fs.write(fname,0) ; del fs + # + fs1=MEDFileFields(fname) + self.assertEqual(fs1.getPfls(),('pfl_NORM_QUAD4',)) + self.assertEqual(fs1.getPflsReallyUsed(),('pfl_NORM_QUAD4',)) + self.assertEqual(4,len(fs1)) + for i in xrange(10): + for j,fieldName in enumerate(['1stField_aa','1stField_ccc','1stField_ZZZZ']): + f1ts=fs1[fieldName][i] + f=f1ts.getFieldOnMeshAtLevel(ON_CELLS,0,mm) + d=DataArrayDouble(21) ; d.iota(i*10) ; d.rearrange(3) ; d=d[:,j] ; d.setInfoOnComponent(0,infos1[j]) + self.assertTrue(d.isEqual(f.getArray(),1e-13)) + pass + f1ts=fs1["1stField"][i] + f=f1ts.getFieldOnMeshAtLevel(ON_CELLS,0,mm) + d=DataArrayDouble(21) ; d.iota(i*10) ; d.rearrange(3) ; d.setInfoOnComponents(infos1) + self.assertTrue(d.isEqual(f.getArray(),1e-13)) + pass + pass + + def testMEDFileFieldConvertTo1(self): + fname="Pyfile68.med" + # building a mesh containing 4 tri3 + 5 quad4 + tri=MEDCouplingUMesh("tri",2) + tri.allocateCells() ; tri.insertNextCell(NORM_TRI3,[0,1,2]) + tri.setCoords(DataArrayDouble([(0.,0.),(0.,1.),(1.,0.)])) + tris=[tri.deepCpy() for i in xrange(4)] + for i,elt in enumerate(tris): elt.translate([i,0]) + tris=MEDCouplingUMesh.MergeUMeshes(tris) + quad=MEDCouplingUMesh("quad",2) + quad.allocateCells() ; quad.insertNextCell(NORM_QUAD4,[0,1,2,3]) + quad.setCoords(DataArrayDouble([(0.,0.),(0.,1.),(1.,1.),(1.,0.)])) + quads=[quad.deepCpy() for i in xrange(5)] + for i,elt in enumerate(quads): elt.translate([5+i,0]) + quads=MEDCouplingUMesh.MergeUMeshes(quads) + m=MEDCouplingUMesh.MergeUMeshes(tris,quads) + m.setName("mesh") ; m.getCoords().setInfoOnComponents(["XX [m]","YYY [km]"]) + mm=MEDFileUMesh() ; mm.setMeshAtLevel(0,m) + # + ff0=MEDFileField1TS() + f0=MEDCouplingFieldDouble(ON_CELLS,ONE_TIME) ; f0.setMesh(m) ; arr=DataArrayDouble(m.getNumberOfCells()*2) ; arr.iota() ; arr.rearrange(2) ; arr.setInfoOnComponents(["X [km]","YY [mm]"]) ; f0.setArray(arr) ; f0.setName("FieldCell") + f0.checkCoherency() + ff0.setFieldNoProfileSBT(f0) + # + fspExp=[(3,[(0,(0,4),'','')]),(4,[(0,(4,9),'','')])] + self.assertEqual(ff0.getFieldSplitedByType(),fspExp) + # + ff0i=ff0.convertToInt() + self.assertEqual(ff0i.getFieldSplitedByType(),fspExp) + self.assertTrue(arr.convertToIntArr().isEqual(ff0i.getUndergroundDataArray())) + # + ff1=ff0i.convertToDouble() + self.assertTrue(ff1.getUndergroundDataArray().isEqual(ff0.getUndergroundDataArray(),1e-13)) + self.assertEqual(ff1.getFieldSplitedByType(),fspExp) + # With profiles + del arr,f0,ff0,ff1,ff0i,fspExp + ff0=MEDFileField1TS() + f0=MEDCouplingFieldDouble(ON_CELLS,ONE_TIME) ; f0.setMesh(m[:7]) ; arr=DataArrayDouble(7*2) ; arr.iota() ; arr.rearrange(2) ; arr.setInfoOnComponents(["XX [pm]","YYY [hm]"]) ; f0.setArray(arr) ; f0.setName("FieldCellPfl") + f0.checkCoherency() + pfl=DataArrayInt.Range(0,7,1) ; pfl.setName("pfl") + ff0.setFieldProfile(f0,mm,0,pfl) + fspExp=[(3,[(0,(0,4),'','')]),(4,[(0,(4,7),'pfl_NORM_QUAD4','')])] + self.assertEqual(ff0.getFieldSplitedByType(),fspExp) + # + ff0i=ff0.convertToInt() + self.assertTrue(isinstance(ff0i,MEDFileIntField1TS)) + self.assertEqual(ff0i.getFieldSplitedByType(),fspExp) + self.assertTrue(arr.convertToIntArr().isEqual(ff0i.getUndergroundDataArray())) + # + ff1=ff0i.convertToDouble() + self.assertTrue(isinstance(ff1,MEDFileField1TS)) + self.assertTrue(ff1.getUndergroundDataArray().isEqual(ff0.getUndergroundDataArray(),1e-13)) + self.assertEqual(ff1.getFieldSplitedByType(),fspExp) + ## MultiTimeSteps + ff0=MEDFileFieldMultiTS() + f0=MEDCouplingFieldDouble(ON_CELLS,ONE_TIME) ; f0.setMesh(m[:7]) ; arr=DataArrayDouble(7*2) ; arr.iota() ; arr.rearrange(2) ; arr.setInfoOnComponents(["X [km]","YY [mm]"]) ; f0.setArray(arr) ; f0.setName("FieldCellMTime") ; f0.setTime(0.1,0,10) + f0.checkCoherency() + ff0.appendFieldProfile(f0,mm,0,pfl) + f0=MEDCouplingFieldDouble(ON_CELLS,ONE_TIME) ; f0.setMesh(m[:7]) ; arr=DataArrayDouble(7*2) ; arr.iota(100) ; arr.rearrange(2) ; arr.setInfoOnComponents(["X [km]","YY [mm]"]) ; f0.setArray(arr) ; f0.setName("FieldCellMTime") ; f0.setTime(1.1,1,11) + f0.checkCoherency() + ff0.appendFieldProfile(f0,mm,0,pfl) + f0=MEDCouplingFieldDouble(ON_CELLS,ONE_TIME) ; f0.setMesh(m[:7]) ; arr=DataArrayDouble(7*2) ; arr.iota(200) ; arr.rearrange(2) ; arr.setInfoOnComponents(["X [km]","YY [mm]"]) ; f0.setArray(arr) ; f0.setName("FieldCellMTime") ; f0.setTime(2.1,2,12) + f0.checkCoherency() + ff0.appendFieldProfile(f0,mm,0,pfl) + ff1=ff0.convertToInt() + self.assertTrue(isinstance(ff1,MEDFileIntFieldMultiTS)) + self.assertEqual(ff1.getTimeSteps(),[(0,10,0.1),(1,11,1.1),(2,12,2.1)]) + for delt,(dt,it,t) in zip([0,100,200],ff1.getTimeSteps()): + self.assertEqual(ff1.getFieldSplitedByType(dt,it),fspExp) + arr=ff1.getUndergroundDataArray(dt,it) + arr.isEqualWithoutConsideringStr(DataArrayInt.Range(delt,delt+7,1)) + pass + self.assertEqual(ff1.getPfls(),('pfl_NORM_QUAD4', 'pfl_NORM_QUAD4', 'pfl_NORM_QUAD4')) + # + mm.write(fname,2) + ff1.write(fname,0) + # + ff1=ff1.convertToDouble() + self.assertTrue(isinstance(ff1,MEDFileFieldMultiTS)) + self.assertEqual(ff1.getTimeSteps(),[(0,10,0.1),(1,11,1.1),(2,12,2.1)]) + for delt,(dt,it,t) in zip([0,100,200],ff1.getTimeSteps()): + self.assertEqual(ff1.getFieldSplitedByType(dt,it),fspExp) + arr=ff1.getUndergroundDataArray(dt,it) + arr.isEqualWithoutConsideringStr(DataArrayInt.Range(delt,delt+7,1).convertToDblArr(),1e-14) + pass + self.assertEqual(ff1.getPfls(),('pfl_NORM_QUAD4', 'pfl_NORM_QUAD4', 'pfl_NORM_QUAD4')) + # + ff1=MEDFileAnyTypeFieldMultiTS.New(fname,"FieldCellMTime") + self.assertTrue(isinstance(ff1,MEDFileIntFieldMultiTS)) + self.assertEqual(ff1.getTimeSteps(),[(0,10,0.1),(1,11,1.1),(2,12,2.1)]) + for delt,(dt,it,t) in zip([0,100,200],ff1.getTimeSteps()): + self.assertTrue(ff1.getFieldSplitedByType(dt,it),fspExp) + arr=ff1.getUndergroundDataArray(dt,it) + arr.isEqualWithoutConsideringStr(DataArrayInt.Range(delt,delt+7,1)) + pass + self.assertEqual(ff1.getPfls(),('pfl_NORM_QUAD4',)) + pass + + def testMEDFileFieldPartialLoading(self): + fname="Pyfile69.med" + # + a=DataArrayInt() ; aa=a.getHeapMemorySize() + a.alloc(0,1) + strMulFac=a.getHeapMemorySize()-aa ; del a ; del aa + # building a mesh containing 30 tri3 + 40 quad4 + tri=MEDCouplingUMesh("tri",2) + tri.allocateCells() ; tri.insertNextCell(NORM_TRI3,[0,1,2]) + tri.setCoords(DataArrayDouble([(0.,0.),(0.,1.),(1.,0.)])) + tris=[tri.deepCpy() for i in xrange(30)] + for i,elt in enumerate(tris): elt.translate([i,0]) + tris=MEDCouplingUMesh.MergeUMeshes(tris) + quad=MEDCouplingUMesh("quad",2) + quad.allocateCells() ; quad.insertNextCell(NORM_QUAD4,[0,1,2,3]) + quad.setCoords(DataArrayDouble([(0.,0.),(0.,1.),(1.,1.),(1.,0.)])) + quads=[quad.deepCpy() for i in xrange(40)] + for i,elt in enumerate(quads): elt.translate([40+i,0]) + quads=MEDCouplingUMesh.MergeUMeshes(quads) + m=MEDCouplingUMesh.MergeUMeshes(tris,quads) + m.setName("mesh") ; m.getCoords().setInfoOnComponents(["XX [m]","YYY [km]"]) + mm=MEDFileUMesh() ; mm.setMeshAtLevel(0,m) ; mm.write(fname,2) + # + ff0=MEDFileField1TS() + f0=MEDCouplingFieldDouble(ON_CELLS,ONE_TIME) ; f0.setMesh(m) ; arr=DataArrayDouble(m.getNumberOfCells()*2) ; arr.iota() ; arr.rearrange(2) ; arr.setInfoOnComponents(["X [km]","YY [mm]"]) ; f0.setArray(arr) ; f0.setName("FieldCell") + f0.checkCoherency() + ff0.setFieldNoProfileSBT(f0) + ff0.write(fname,0) + # + fspExp=[(3,[(0,(0,30),'','')]),(4,[(0,(30,70),'','')])] + self.assertEqual(ff0.getFieldSplitedByType(),fspExp) + # With profiles + ff0=MEDFileField1TS() + f0=MEDCouplingFieldDouble(ON_CELLS,ONE_TIME) ; f0.setMesh(m[:50]) ; arr=DataArrayDouble(50*2) ; arr.iota() ; arr.rearrange(2) ; arr.setInfoOnComponents(["XX [pm]","YYY [hm]"]) ; f0.setArray(arr) ; f0.setName("FieldCellPfl") + f0.checkCoherency() + pfl=DataArrayInt.Range(0,50,1) ; pfl.setName("pfl") + ff0.setFieldProfile(f0,mm,0,pfl) + fspExp=[(3,[(0,(0,30),'','')]),(4,[(0,(30,50),'pfl_NORM_QUAD4','')])] + self.assertEqual(ff0.getFieldSplitedByType(),fspExp) + ff0.write(fname,0) + # + ff0=MEDFileField1TS(fname,False) + self.assertEqual(ff0.getName(),"FieldCell") + self.assertTrue(not ff0.getUndergroundDataArray().isAllocated()) + self.assertEqual(ff0.getUndergroundDataArray().getInfoOnComponents(),['X [km]','YY [mm]']) + heap_memory_ref=ff0.getHeapMemorySize() + self.assertIn(heap_memory_ref,xrange(182,298+2*strMulFac)) + ff0.loadArrays() ## + arr=DataArrayDouble(140) ; arr.iota() ; arr.rearrange(2) + self.assertTrue(ff0.getUndergroundDataArray().isEqualWithoutConsideringStr(arr,1e-14)) + self.assertEqual(ff0.getHeapMemorySize()-heap_memory_ref,70*8*2) + # + ff0=MEDFileField1TS(fname,"FieldCellPfl",False) + self.assertEqual(ff0.getUndergroundDataArray().getInfoOnComponents(),["XX [pm]","YYY [hm]"]) + heap_memory_ref=ff0.getHeapMemorySize() + self.assertIn(heap_memory_ref,xrange(350,415+6*strMulFac)) + ff0.loadArrays() ## + arr=DataArrayDouble(100) ; arr.iota() ; arr.rearrange(2) + self.assertTrue(ff0.getUndergroundDataArray().isEqualWithoutConsideringStr(arr,1e-14)) + self.assertEqual(ff0.getHeapMemorySize()-heap_memory_ref,50*8*2) + ff0.loadArrays() ## + self.assertTrue(ff0.getUndergroundDataArray().isEqualWithoutConsideringStr(arr,1e-14)) + self.assertEqual(ff0.getHeapMemorySize()-heap_memory_ref,50*8*2) + ff0.getUndergroundDataArray().setIJ(30,1,5.5) + self.assertTrue(not ff0.getUndergroundDataArray().isEqualWithoutConsideringStr(arr,1e-14)) + ff0.loadArrays() ## + self.assertTrue(ff0.getUndergroundDataArray().isEqualWithoutConsideringStr(arr,1e-14)) + ff0.getUndergroundDataArray().setIJ(30,1,5.5) + self.assertTrue(not ff0.getUndergroundDataArray().isEqualWithoutConsideringStr(arr,1e-14)) + ff0.loadArraysIfNecessary() ## + self.assertEqual(ff0.getUndergroundDataArray().getIJ(30,1),5.5) + self.assertTrue(not ff0.getUndergroundDataArray().isEqualWithoutConsideringStr(arr,1e-14)) + heap_memory_ref=ff0.getHeapMemorySize() + self.assertIn(heap_memory_ref,xrange(1100,1215+2*strMulFac)) + ff0.unloadArrays() + hmd=ff0.getHeapMemorySize()-heap_memory_ref + self.assertEqual(hmd,-800) # -50*8*2 + ff0.loadArrays() ## + self.assertEqual(ff0.getHeapMemorySize()-heap_memory_ref,0) + # + ff0=MEDFileField1TS(fname,"FieldCellPfl",-1,-1,False) + heap_memory_ref=ff0.getHeapMemorySize() + self.assertIn(heap_memory_ref,xrange(299,415+6*strMulFac)) + ff0.loadArrays() ## + self.assertTrue(ff0.getUndergroundDataArray().isEqualWithoutConsideringStr(arr,1e-14)) + self.assertEqual(ff0.getHeapMemorySize()-heap_memory_ref,50*8*2) + # + fieldName="FieldCellMultiTS" + ff0=MEDFileFieldMultiTS() + for t in xrange(20): + f0=MEDCouplingFieldDouble(ON_CELLS,ONE_TIME) ; f0.setMesh(m) ; arr=DataArrayDouble(m.getNumberOfCells()*2) ; arr.iota(float(t+1000)) ; arr.rearrange(2) ; arr.setInfoOnComponents(["X [km]","YY [mm]"]) ; f0.setArray(arr) ; f0.setName(fieldName) + f0.setTime(float(t)+0.1,t,100+t) + f0.checkCoherency() + ff0.appendFieldNoProfileSBT(f0) + pass + ff0.write(fname,0) + # + ff0=MEDFileAnyTypeFieldMultiTS.New(fname,fieldName,False) + heap_memory_ref=ff0.getHeapMemorySize() + self.assertIn(heap_memory_ref,xrange(5536,5956+(80+26)*strMulFac)) + ff0.loadArrays() + self.assertEqual(ff0.getHeapMemorySize()-heap_memory_ref,20*70*8*2) + del ff0 + # + ffs=MEDFileFields(fname,False) + heap_memory_ref=ffs.getHeapMemorySize() + self.assertIn(heap_memory_ref,xrange(5335,6687+(80+50)*strMulFac)) + ffs.loadArrays() + self.assertEqual(ffs.getHeapMemorySize()-heap_memory_ref,20*70*8*2+70*8*2+50*8*2) + pass + + def testMEDFileMeshReadSelector1(self): + mrs=MEDFileMeshReadSelector() + self.assertTrue(mrs.isCellFamilyFieldReading() and mrs.isNodeFamilyFieldReading() and mrs.isCellNameFieldReading() and mrs.isNodeNameFieldReading() and mrs.isCellNumFieldReading() and mrs.isNodeNumFieldReading()) + mrs.__str__() ; mrs.__repr__() + # + mrs=MEDFileMeshReadSelector(0) + self.assertTrue(not mrs.isCellFamilyFieldReading() and not mrs.isNodeFamilyFieldReading() and not mrs.isCellNameFieldReading() and not mrs.isNodeNameFieldReading() and not mrs.isCellNumFieldReading() and not mrs.isNodeNumFieldReading()) + mrs=MEDFileMeshReadSelector(1) + self.assertTrue(mrs.isCellFamilyFieldReading() and not mrs.isNodeFamilyFieldReading() and not mrs.isCellNameFieldReading() and not mrs.isNodeNameFieldReading() and not mrs.isCellNumFieldReading() and not mrs.isNodeNumFieldReading()) + mrs=MEDFileMeshReadSelector(2) + self.assertTrue(not mrs.isCellFamilyFieldReading() and mrs.isNodeFamilyFieldReading() and not mrs.isCellNameFieldReading() and not mrs.isNodeNameFieldReading() and not mrs.isCellNumFieldReading() and not mrs.isNodeNumFieldReading()) + mrs=MEDFileMeshReadSelector(3) + self.assertTrue(mrs.isCellFamilyFieldReading() and mrs.isNodeFamilyFieldReading() and not mrs.isCellNameFieldReading() and not mrs.isNodeNameFieldReading() and not mrs.isCellNumFieldReading() and not mrs.isNodeNumFieldReading()) + mrs=MEDFileMeshReadSelector(4) + self.assertTrue(not mrs.isCellFamilyFieldReading() and not mrs.isNodeFamilyFieldReading() and mrs.isCellNameFieldReading() and not mrs.isNodeNameFieldReading() and not mrs.isCellNumFieldReading() and not mrs.isNodeNumFieldReading()) + mrs=MEDFileMeshReadSelector(5) + self.assertTrue(mrs.isCellFamilyFieldReading() and not mrs.isNodeFamilyFieldReading() and mrs.isCellNameFieldReading() and not mrs.isNodeNameFieldReading() and not mrs.isCellNumFieldReading() and not mrs.isNodeNumFieldReading()) + mrs=MEDFileMeshReadSelector(6) + self.assertTrue(not mrs.isCellFamilyFieldReading() and mrs.isNodeFamilyFieldReading() and mrs.isCellNameFieldReading() and not mrs.isNodeNameFieldReading() and not mrs.isCellNumFieldReading() and not mrs.isNodeNumFieldReading()) + mrs=MEDFileMeshReadSelector(7) + self.assertTrue(mrs.isCellFamilyFieldReading() and mrs.isNodeFamilyFieldReading() and mrs.isCellNameFieldReading() and not mrs.isNodeNameFieldReading() and not mrs.isCellNumFieldReading() and not mrs.isNodeNumFieldReading()) + mrs=MEDFileMeshReadSelector(8) + self.assertTrue(not mrs.isCellFamilyFieldReading() and not mrs.isNodeFamilyFieldReading() and not mrs.isCellNameFieldReading() and mrs.isNodeNameFieldReading() and not mrs.isCellNumFieldReading() and not mrs.isNodeNumFieldReading()) + mrs=MEDFileMeshReadSelector(9) + self.assertTrue(mrs.isCellFamilyFieldReading() and not mrs.isNodeFamilyFieldReading() and not mrs.isCellNameFieldReading() and mrs.isNodeNameFieldReading() and not mrs.isCellNumFieldReading() and not mrs.isNodeNumFieldReading()) + mrs=MEDFileMeshReadSelector(10) + self.assertTrue(not mrs.isCellFamilyFieldReading() and mrs.isNodeFamilyFieldReading() and not mrs.isCellNameFieldReading() and mrs.isNodeNameFieldReading() and not mrs.isCellNumFieldReading() and not mrs.isNodeNumFieldReading()) + mrs=MEDFileMeshReadSelector(11) + self.assertTrue(mrs.isCellFamilyFieldReading() and mrs.isNodeFamilyFieldReading() and not mrs.isCellNameFieldReading() and mrs.isNodeNameFieldReading() and not mrs.isCellNumFieldReading() and not mrs.isNodeNumFieldReading()) + mrs=MEDFileMeshReadSelector(12) + self.assertTrue(not mrs.isCellFamilyFieldReading() and not mrs.isNodeFamilyFieldReading() and mrs.isCellNameFieldReading() and mrs.isNodeNameFieldReading() and not mrs.isCellNumFieldReading() and not mrs.isNodeNumFieldReading()) + mrs=MEDFileMeshReadSelector(13) + self.assertTrue(mrs.isCellFamilyFieldReading() and not mrs.isNodeFamilyFieldReading() and mrs.isCellNameFieldReading() and mrs.isNodeNameFieldReading() and not mrs.isCellNumFieldReading() and not mrs.isNodeNumFieldReading()) + mrs=MEDFileMeshReadSelector(14) + self.assertTrue(not mrs.isCellFamilyFieldReading() and mrs.isNodeFamilyFieldReading() and mrs.isCellNameFieldReading() and mrs.isNodeNameFieldReading() and not mrs.isCellNumFieldReading() and not mrs.isNodeNumFieldReading()) + mrs=MEDFileMeshReadSelector(15) + self.assertTrue(mrs.isCellFamilyFieldReading() and mrs.isNodeFamilyFieldReading() and mrs.isCellNameFieldReading() and mrs.isNodeNameFieldReading() and not mrs.isCellNumFieldReading() and not mrs.isNodeNumFieldReading()) + mrs=MEDFileMeshReadSelector(16) + self.assertTrue(not mrs.isCellFamilyFieldReading() and not mrs.isNodeFamilyFieldReading() and not mrs.isCellNameFieldReading() and not mrs.isNodeNameFieldReading() and mrs.isCellNumFieldReading() and not mrs.isNodeNumFieldReading()) + mrs=MEDFileMeshReadSelector(17) + self.assertTrue(mrs.isCellFamilyFieldReading() and not mrs.isNodeFamilyFieldReading() and not mrs.isCellNameFieldReading() and not mrs.isNodeNameFieldReading() and mrs.isCellNumFieldReading() and not mrs.isNodeNumFieldReading()) + mrs=MEDFileMeshReadSelector(18) + self.assertTrue(not mrs.isCellFamilyFieldReading() and mrs.isNodeFamilyFieldReading() and not mrs.isCellNameFieldReading() and not mrs.isNodeNameFieldReading() and mrs.isCellNumFieldReading() and not mrs.isNodeNumFieldReading()) + mrs=MEDFileMeshReadSelector(19) + self.assertTrue(mrs.isCellFamilyFieldReading() and mrs.isNodeFamilyFieldReading() and not mrs.isCellNameFieldReading() and not mrs.isNodeNameFieldReading() and mrs.isCellNumFieldReading() and not mrs.isNodeNumFieldReading()) + mrs=MEDFileMeshReadSelector(20) + self.assertTrue(not mrs.isCellFamilyFieldReading() and not mrs.isNodeFamilyFieldReading() and mrs.isCellNameFieldReading() and not mrs.isNodeNameFieldReading() and mrs.isCellNumFieldReading() and not mrs.isNodeNumFieldReading()) + mrs=MEDFileMeshReadSelector(21) + self.assertTrue(mrs.isCellFamilyFieldReading() and not mrs.isNodeFamilyFieldReading() and mrs.isCellNameFieldReading() and not mrs.isNodeNameFieldReading() and mrs.isCellNumFieldReading() and not mrs.isNodeNumFieldReading()) + mrs=MEDFileMeshReadSelector(22) + self.assertTrue(not mrs.isCellFamilyFieldReading() and mrs.isNodeFamilyFieldReading() and mrs.isCellNameFieldReading() and not mrs.isNodeNameFieldReading() and mrs.isCellNumFieldReading() and not mrs.isNodeNumFieldReading()) + mrs=MEDFileMeshReadSelector(23) + self.assertTrue(mrs.isCellFamilyFieldReading() and mrs.isNodeFamilyFieldReading() and mrs.isCellNameFieldReading() and not mrs.isNodeNameFieldReading() and mrs.isCellNumFieldReading() and not mrs.isNodeNumFieldReading()) + mrs=MEDFileMeshReadSelector(24) + self.assertTrue(not mrs.isCellFamilyFieldReading() and not mrs.isNodeFamilyFieldReading() and not mrs.isCellNameFieldReading() and mrs.isNodeNameFieldReading() and mrs.isCellNumFieldReading() and not mrs.isNodeNumFieldReading()) + mrs=MEDFileMeshReadSelector(25) + self.assertTrue(mrs.isCellFamilyFieldReading() and not mrs.isNodeFamilyFieldReading() and not mrs.isCellNameFieldReading() and mrs.isNodeNameFieldReading() and mrs.isCellNumFieldReading() and not mrs.isNodeNumFieldReading()) + mrs=MEDFileMeshReadSelector(26) + self.assertTrue(not mrs.isCellFamilyFieldReading() and mrs.isNodeFamilyFieldReading() and not mrs.isCellNameFieldReading() and mrs.isNodeNameFieldReading() and mrs.isCellNumFieldReading() and not mrs.isNodeNumFieldReading()) + mrs=MEDFileMeshReadSelector(27) + self.assertTrue(mrs.isCellFamilyFieldReading() and mrs.isNodeFamilyFieldReading() and not mrs.isCellNameFieldReading() and mrs.isNodeNameFieldReading() and mrs.isCellNumFieldReading() and not mrs.isNodeNumFieldReading()) + mrs=MEDFileMeshReadSelector(28) + self.assertTrue(not mrs.isCellFamilyFieldReading() and not mrs.isNodeFamilyFieldReading() and mrs.isCellNameFieldReading() and mrs.isNodeNameFieldReading() and mrs.isCellNumFieldReading() and not mrs.isNodeNumFieldReading()) + mrs=MEDFileMeshReadSelector(29) + self.assertTrue(mrs.isCellFamilyFieldReading() and not mrs.isNodeFamilyFieldReading() and mrs.isCellNameFieldReading() and mrs.isNodeNameFieldReading() and mrs.isCellNumFieldReading() and not mrs.isNodeNumFieldReading()) + mrs=MEDFileMeshReadSelector(30) + self.assertTrue(not mrs.isCellFamilyFieldReading() and mrs.isNodeFamilyFieldReading() and mrs.isCellNameFieldReading() and mrs.isNodeNameFieldReading() and mrs.isCellNumFieldReading() and not mrs.isNodeNumFieldReading()) + mrs=MEDFileMeshReadSelector(31) + self.assertTrue(mrs.isCellFamilyFieldReading() and mrs.isNodeFamilyFieldReading() and mrs.isCellNameFieldReading() and mrs.isNodeNameFieldReading() and mrs.isCellNumFieldReading() and not mrs.isNodeNumFieldReading()) + mrs=MEDFileMeshReadSelector(32) + self.assertTrue(not mrs.isCellFamilyFieldReading() and not mrs.isNodeFamilyFieldReading() and not mrs.isCellNameFieldReading() and not mrs.isNodeNameFieldReading() and not mrs.isCellNumFieldReading() and mrs.isNodeNumFieldReading()) + mrs=MEDFileMeshReadSelector(33) + self.assertTrue(mrs.isCellFamilyFieldReading() and not mrs.isNodeFamilyFieldReading() and not mrs.isCellNameFieldReading() and not mrs.isNodeNameFieldReading() and not mrs.isCellNumFieldReading() and mrs.isNodeNumFieldReading()) + mrs=MEDFileMeshReadSelector(34) + self.assertTrue(not mrs.isCellFamilyFieldReading() and mrs.isNodeFamilyFieldReading() and not mrs.isCellNameFieldReading() and not mrs.isNodeNameFieldReading() and not mrs.isCellNumFieldReading() and mrs.isNodeNumFieldReading()) + mrs=MEDFileMeshReadSelector(35) + self.assertTrue(mrs.isCellFamilyFieldReading() and mrs.isNodeFamilyFieldReading() and not mrs.isCellNameFieldReading() and not mrs.isNodeNameFieldReading() and not mrs.isCellNumFieldReading() and mrs.isNodeNumFieldReading()) + mrs=MEDFileMeshReadSelector(36) + self.assertTrue(not mrs.isCellFamilyFieldReading() and not mrs.isNodeFamilyFieldReading() and mrs.isCellNameFieldReading() and not mrs.isNodeNameFieldReading() and not mrs.isCellNumFieldReading() and mrs.isNodeNumFieldReading()) + mrs=MEDFileMeshReadSelector(37) + self.assertTrue(mrs.isCellFamilyFieldReading() and not mrs.isNodeFamilyFieldReading() and mrs.isCellNameFieldReading() and not mrs.isNodeNameFieldReading() and not mrs.isCellNumFieldReading() and mrs.isNodeNumFieldReading()) + mrs=MEDFileMeshReadSelector(38) + self.assertTrue(not mrs.isCellFamilyFieldReading() and mrs.isNodeFamilyFieldReading() and mrs.isCellNameFieldReading() and not mrs.isNodeNameFieldReading() and not mrs.isCellNumFieldReading() and mrs.isNodeNumFieldReading()) + mrs=MEDFileMeshReadSelector(39) + self.assertTrue(mrs.isCellFamilyFieldReading() and mrs.isNodeFamilyFieldReading() and mrs.isCellNameFieldReading() and not mrs.isNodeNameFieldReading() and not mrs.isCellNumFieldReading() and mrs.isNodeNumFieldReading()) + mrs=MEDFileMeshReadSelector(40) + self.assertTrue(not mrs.isCellFamilyFieldReading() and not mrs.isNodeFamilyFieldReading() and not mrs.isCellNameFieldReading() and mrs.isNodeNameFieldReading() and not mrs.isCellNumFieldReading() and mrs.isNodeNumFieldReading()) + mrs=MEDFileMeshReadSelector(41) + self.assertTrue(mrs.isCellFamilyFieldReading() and not mrs.isNodeFamilyFieldReading() and not mrs.isCellNameFieldReading() and mrs.isNodeNameFieldReading() and not mrs.isCellNumFieldReading() and mrs.isNodeNumFieldReading()) + mrs=MEDFileMeshReadSelector(42) + self.assertTrue(not mrs.isCellFamilyFieldReading() and mrs.isNodeFamilyFieldReading() and not mrs.isCellNameFieldReading() and mrs.isNodeNameFieldReading() and not mrs.isCellNumFieldReading() and mrs.isNodeNumFieldReading()) + mrs=MEDFileMeshReadSelector(43) + self.assertTrue(mrs.isCellFamilyFieldReading() and mrs.isNodeFamilyFieldReading() and not mrs.isCellNameFieldReading() and mrs.isNodeNameFieldReading() and not mrs.isCellNumFieldReading() and mrs.isNodeNumFieldReading()) + mrs=MEDFileMeshReadSelector(44) + self.assertTrue(not mrs.isCellFamilyFieldReading() and not mrs.isNodeFamilyFieldReading() and mrs.isCellNameFieldReading() and mrs.isNodeNameFieldReading() and not mrs.isCellNumFieldReading() and mrs.isNodeNumFieldReading()) + mrs=MEDFileMeshReadSelector(45) + self.assertTrue(mrs.isCellFamilyFieldReading() and not mrs.isNodeFamilyFieldReading() and mrs.isCellNameFieldReading() and mrs.isNodeNameFieldReading() and not mrs.isCellNumFieldReading() and mrs.isNodeNumFieldReading()) + mrs=MEDFileMeshReadSelector(46) + self.assertTrue(not mrs.isCellFamilyFieldReading() and mrs.isNodeFamilyFieldReading() and mrs.isCellNameFieldReading() and mrs.isNodeNameFieldReading() and not mrs.isCellNumFieldReading() and mrs.isNodeNumFieldReading()) + mrs=MEDFileMeshReadSelector(47) + self.assertTrue(mrs.isCellFamilyFieldReading() and mrs.isNodeFamilyFieldReading() and mrs.isCellNameFieldReading() and mrs.isNodeNameFieldReading() and not mrs.isCellNumFieldReading() and mrs.isNodeNumFieldReading()) + mrs=MEDFileMeshReadSelector(48) + self.assertTrue(not mrs.isCellFamilyFieldReading() and not mrs.isNodeFamilyFieldReading() and not mrs.isCellNameFieldReading() and not mrs.isNodeNameFieldReading() and mrs.isCellNumFieldReading() and mrs.isNodeNumFieldReading()) + mrs=MEDFileMeshReadSelector(49) + self.assertTrue(mrs.isCellFamilyFieldReading() and not mrs.isNodeFamilyFieldReading() and not mrs.isCellNameFieldReading() and not mrs.isNodeNameFieldReading() and mrs.isCellNumFieldReading() and mrs.isNodeNumFieldReading()) + mrs=MEDFileMeshReadSelector(50) + self.assertTrue(not mrs.isCellFamilyFieldReading() and mrs.isNodeFamilyFieldReading() and not mrs.isCellNameFieldReading() and not mrs.isNodeNameFieldReading() and mrs.isCellNumFieldReading() and mrs.isNodeNumFieldReading()) + mrs=MEDFileMeshReadSelector(51) + self.assertTrue(mrs.isCellFamilyFieldReading() and mrs.isNodeFamilyFieldReading() and not mrs.isCellNameFieldReading() and not mrs.isNodeNameFieldReading() and mrs.isCellNumFieldReading() and mrs.isNodeNumFieldReading()) + mrs=MEDFileMeshReadSelector(52) + self.assertTrue(not mrs.isCellFamilyFieldReading() and not mrs.isNodeFamilyFieldReading() and mrs.isCellNameFieldReading() and not mrs.isNodeNameFieldReading() and mrs.isCellNumFieldReading() and mrs.isNodeNumFieldReading()) + mrs=MEDFileMeshReadSelector(53) + self.assertTrue(mrs.isCellFamilyFieldReading() and not mrs.isNodeFamilyFieldReading() and mrs.isCellNameFieldReading() and not mrs.isNodeNameFieldReading() and mrs.isCellNumFieldReading() and mrs.isNodeNumFieldReading()) + mrs=MEDFileMeshReadSelector(54) + self.assertTrue(not mrs.isCellFamilyFieldReading() and mrs.isNodeFamilyFieldReading() and mrs.isCellNameFieldReading() and not mrs.isNodeNameFieldReading() and mrs.isCellNumFieldReading() and mrs.isNodeNumFieldReading()) + mrs=MEDFileMeshReadSelector(55) + self.assertTrue(mrs.isCellFamilyFieldReading() and mrs.isNodeFamilyFieldReading() and mrs.isCellNameFieldReading() and not mrs.isNodeNameFieldReading() and mrs.isCellNumFieldReading() and mrs.isNodeNumFieldReading()) + mrs=MEDFileMeshReadSelector(56) + self.assertTrue(not mrs.isCellFamilyFieldReading() and not mrs.isNodeFamilyFieldReading() and not mrs.isCellNameFieldReading() and mrs.isNodeNameFieldReading() and mrs.isCellNumFieldReading() and mrs.isNodeNumFieldReading()) + mrs=MEDFileMeshReadSelector(57) + self.assertTrue(mrs.isCellFamilyFieldReading() and not mrs.isNodeFamilyFieldReading() and not mrs.isCellNameFieldReading() and mrs.isNodeNameFieldReading() and mrs.isCellNumFieldReading() and mrs.isNodeNumFieldReading()) + mrs=MEDFileMeshReadSelector(58) + self.assertTrue(not mrs.isCellFamilyFieldReading() and mrs.isNodeFamilyFieldReading() and not mrs.isCellNameFieldReading() and mrs.isNodeNameFieldReading() and mrs.isCellNumFieldReading() and mrs.isNodeNumFieldReading()) + mrs=MEDFileMeshReadSelector(59) + self.assertTrue(mrs.isCellFamilyFieldReading() and mrs.isNodeFamilyFieldReading() and not mrs.isCellNameFieldReading() and mrs.isNodeNameFieldReading() and mrs.isCellNumFieldReading() and mrs.isNodeNumFieldReading()) + mrs=MEDFileMeshReadSelector(60) + self.assertTrue(not mrs.isCellFamilyFieldReading() and not mrs.isNodeFamilyFieldReading() and mrs.isCellNameFieldReading() and mrs.isNodeNameFieldReading() and mrs.isCellNumFieldReading() and mrs.isNodeNumFieldReading()) + mrs=MEDFileMeshReadSelector(61) + self.assertTrue(mrs.isCellFamilyFieldReading() and not mrs.isNodeFamilyFieldReading() and mrs.isCellNameFieldReading() and mrs.isNodeNameFieldReading() and mrs.isCellNumFieldReading() and mrs.isNodeNumFieldReading()) + mrs=MEDFileMeshReadSelector(62) + self.assertTrue(not mrs.isCellFamilyFieldReading() and mrs.isNodeFamilyFieldReading() and mrs.isCellNameFieldReading() and mrs.isNodeNameFieldReading() and mrs.isCellNumFieldReading() and mrs.isNodeNumFieldReading()) + mrs=MEDFileMeshReadSelector(63) + self.assertTrue(mrs.isCellFamilyFieldReading() and mrs.isNodeFamilyFieldReading() and mrs.isCellNameFieldReading() and mrs.isNodeNameFieldReading() and mrs.isCellNumFieldReading() and mrs.isNodeNumFieldReading()) + # + mrs=MEDFileMeshReadSelector(63) + mrs.setCellFamilyFieldReading(False) + self.assertEqual(mrs.getCode(),62) + mrs.setCellFamilyFieldReading(True) + self.assertEqual(mrs.getCode(),63) + mrs.setNodeFamilyFieldReading(False) + self.assertEqual(mrs.getCode(),61) + mrs.setNodeFamilyFieldReading(True) + self.assertEqual(mrs.getCode(),63) + mrs.setCellNameFieldReading(False) + self.assertEqual(mrs.getCode(),59) + mrs.setCellNameFieldReading(True) + self.assertEqual(mrs.getCode(),63) + mrs.setNodeNameFieldReading(False) + self.assertEqual(mrs.getCode(),55) + mrs.setNodeNameFieldReading(True) + self.assertEqual(mrs.getCode(),63) + mrs.setCellNumFieldReading(False) + self.assertEqual(mrs.getCode(),47) + mrs.setCellNumFieldReading(True) + self.assertEqual(mrs.getCode(),63) + mrs.setNodeNumFieldReading(False) + self.assertEqual(mrs.getCode(),31) + mrs.setNodeNumFieldReading(True) + self.assertEqual(mrs.getCode(),63) + pass + + def testPartialReadOfMeshes(self): + fname="Pyfile70.med" + # building a mesh containing 4 tri3 + 5 quad4 + tri=MEDCouplingUMesh("tri",2) + tri.allocateCells() ; tri.insertNextCell(NORM_TRI3,[0,1,2]) + tri.setCoords(DataArrayDouble([(0.,0.),(0.,1.),(1.,0.)])) + tris=[tri.deepCpy() for i in xrange(4)] + for i,elt in enumerate(tris): elt.translate([i,0]) + tris=MEDCouplingUMesh.MergeUMeshes(tris) + quad=MEDCouplingUMesh("quad",2) + quad.allocateCells() ; quad.insertNextCell(NORM_QUAD4,[0,1,2,3]) + quad.setCoords(DataArrayDouble([(0.,0.),(0.,1.),(1.,1.),(1.,0.)])) + quads=[quad.deepCpy() for i in xrange(5)] + for i,elt in enumerate(quads): elt.translate([5+i,0]) + quads=MEDCouplingUMesh.MergeUMeshes(quads) + m=MEDCouplingUMesh.MergeUMeshes(tris,quads) + m.setName("mesh") ; m.getCoords().setInfoOnComponents(["XX [m]","YYY [km]"]) + m1=m.buildDescendingConnectivity()[0] + mm=MEDFileUMesh() ; mm.setMeshes([m,m1]) + # + grp0=DataArrayInt([1,2,3,5,6]) ; grp0.setName("grp0") + grp1=DataArrayInt([1,2,3,5,7,8]) ; grp1.setName("grp1") + mm.setGroupsAtLevel(0,[grp0,grp1]) + grp2=DataArrayInt.Range(0,32,2) ; grp2.setName("grp2") + grp3=DataArrayInt.Range(1,32,7) ; grp3.setName("grp3") + mm.setGroupsAtLevel(-1,[grp2,grp3]) + grp4=DataArrayInt.Range(0,32,2) ; grp4.setName("grp4") + grp5=DataArrayInt.Range(1,32,7) ; grp5.setName("grp5") + mm.setGroupsAtLevel(1,[grp4,grp5]) + mm.setRenumFieldArr(0,DataArrayInt.Range(2,11,1)) + mm.setRenumFieldArr(-1,DataArrayInt.Range(3,35,1)) + mm.setRenumFieldArr(1,DataArrayInt.Range(4,36,1)) + # + mm.write(fname,2) + ## + mm=MEDFileMesh.New(fname,"mesh",-1,-1,MEDFileMeshReadSelector()) + b4_ref_heap_mem=mm.getHeapMemorySize() + mm.getMeshAtLevel(0)## please let this line : force to move 1GTUMesh -> UMesh + mm.getMeshAtLevel(-1)## please let this line : force to move 1GTUMesh -> UMesh + ref_heap_mem=mm.getHeapMemorySize() + # check the gain of memory using 1GTUMesh instead of UMesh + self.assertTrue(ref_heap_mem-b4_ref_heap_mem>=(32+9)*4*2-32)# 32+9=nbCells 4=sizeof(int) 2=the types+index -32=loss linked to vector + # + mm=MEDFileMesh.New(fname,MEDFileMeshReadSelector(0)) + self.assertEqual(len(mm.getGroupsNames()),0) + self.assertTrue(mm.getMeshAtLevel(0).isEqual(m,1e-13)) + self.assertTrue(mm.getMeshAtLevel(-1).isEqual(m1,1e-13)) + self.assertTrue(mm.getFamilyFieldAtLevel(0) is None) + self.assertTrue(mm.getFamilyFieldAtLevel(-1) is None) + self.assertTrue(mm.getFamilyFieldAtLevel(1) is None) + self.assertTrue(mm.getNumberFieldAtLevel(0) is None) + self.assertTrue(mm.getNumberFieldAtLevel(-1) is None) + self.assertTrue(mm.getNumberFieldAtLevel(1) is None) + delta1=ref_heap_mem-mm.getHeapMemorySize() + self.assertTrue(delta1>=4*(32+9)*3+32*4*3) + # + mm=MEDFileMesh.New(fname,MEDFileMeshReadSelector(1)) + self.assertEqual(len(mm.getGroupsNames()),6) + self.assertTrue(mm.getMeshAtLevel(0).isEqual(m,1e-13)) + self.assertTrue(mm.getMeshAtLevel(-1).isEqual(m1,1e-13)) + self.assertTrue(mm.getFamilyFieldAtLevel(0)!=None) + self.assertTrue(mm.getFamilyFieldAtLevel(-1)!=None) + self.assertTrue(mm.getFamilyFieldAtLevel(1) is None) + self.assertTrue(mm.getNumberFieldAtLevel(0) is None) + self.assertTrue(mm.getNumberFieldAtLevel(-1) is None) + self.assertTrue(mm.getNumberFieldAtLevel(1) is None) + delta2=ref_heap_mem-mm.getHeapMemorySize() + self.assertTrue(delta2<delta1) + self.assertTrue(delta2>=4*(32+9)*1+32*4*3) + # + mm=MEDFileUMesh(fname,MEDFileMeshReadSelector(3)) + self.assertEqual(len(mm.getGroupsNames()),6) + self.assertTrue(mm.getMeshAtLevel(0).isEqual(m,1e-13)) + self.assertTrue(mm.getMeshAtLevel(-1).isEqual(m1,1e-13)) + self.assertTrue(mm.getFamilyFieldAtLevel(0)!=None) + self.assertTrue(mm.getFamilyFieldAtLevel(-1)!=None) + self.assertTrue(mm.getFamilyFieldAtLevel(1)!=None) + self.assertTrue(mm.getNumberFieldAtLevel(0) is None) + self.assertTrue(mm.getNumberFieldAtLevel(-1) is None) + self.assertTrue(mm.getNumberFieldAtLevel(1) is None) + delta3=ref_heap_mem-mm.getHeapMemorySize() + self.assertTrue(delta3<delta2) + self.assertTrue(delta3>=4*(32+9)*1+32*4*1) + # + mm=MEDFileUMesh(fname,"mesh",-1,-1,MEDFileMeshReadSelector(19)) + self.assertEqual(len(mm.getGroupsNames()),6) + self.assertTrue(mm.getMeshAtLevel(0).isEqual(m,1e-13)) + self.assertTrue(mm.getMeshAtLevel(-1).isEqual(m1,1e-13)) + self.assertTrue(mm.getFamilyFieldAtLevel(0)!=None) + self.assertTrue(mm.getFamilyFieldAtLevel(-1)!=None) + self.assertTrue(mm.getFamilyFieldAtLevel(1)!=None) + self.assertTrue(mm.getNumberFieldAtLevel(0)!=None) + self.assertTrue(mm.getNumberFieldAtLevel(-1)!=None) + self.assertTrue(mm.getNumberFieldAtLevel(1) is None) + delta4=ref_heap_mem-mm.getHeapMemorySize() + self.assertTrue(delta4<delta3) + self.assertTrue(delta4>=32*4*2) + # + mm=MEDFileUMesh.New(fname,"mesh",-1,-1,MEDFileMeshReadSelector(51)) + self.assertEqual(len(mm.getGroupsNames()),6) + self.assertTrue(mm.getMeshAtLevel(0).isEqual(m,1e-13)) + self.assertTrue(mm.getMeshAtLevel(-1).isEqual(m1,1e-13)) + self.assertTrue(mm.getFamilyFieldAtLevel(0)!=None) + self.assertTrue(mm.getFamilyFieldAtLevel(-1)!=None) + self.assertTrue(mm.getFamilyFieldAtLevel(1)!=None) + self.assertTrue(mm.getNumberFieldAtLevel(0)!=None) + self.assertTrue(mm.getNumberFieldAtLevel(-1)!=None) + self.assertTrue(mm.getNumberFieldAtLevel(1)!=None) + delta5=ref_heap_mem-mm.getHeapMemorySize() + self.assertTrue(delta5<delta4) + self.assertEqual(delta5,0) + pass + + # this test checks that setFieldProfile perform a check of the array length + # compared to the profile length. This test also checks that mesh attribute of field + # is not used by setFieldProfile (because across this test mesh is equal to None) + def testCheckCompatibilityPfl1(self): + # building a mesh containing 4 tri3 + 5 quad4 + tri=MEDCouplingUMesh("tri",2) + tri.allocateCells() ; tri.insertNextCell(NORM_TRI3,[0,1,2]) + tri.setCoords(DataArrayDouble([(0.,0.),(0.,1.),(1.,0.)])) + tris=[tri.deepCpy() for i in xrange(4)] + for i,elt in enumerate(tris): elt.translate([i,0]) + tris=MEDCouplingUMesh.MergeUMeshes(tris) + quad=MEDCouplingUMesh("quad",2) + quad.allocateCells() ; quad.insertNextCell(NORM_QUAD4,[0,1,2,3]) + quad.setCoords(DataArrayDouble([(0.,0.),(0.,1.),(1.,1.),(1.,0.)])) + quads=[quad.deepCpy() for i in xrange(5)] + for i,elt in enumerate(quads): elt.translate([5+i,0]) + quads=MEDCouplingUMesh.MergeUMeshes(quads) + m=MEDCouplingUMesh.MergeUMeshes(tris,quads) + m.setName("mesh") ; m.getCoords().setInfoOnComponents(["XX [m]","YYY [km]"]) + m1=m.buildDescendingConnectivity()[0] + mm=MEDFileUMesh() ; mm.setMeshes([m,m1]) + # + f1ts=MEDFileField1TS() + f=MEDCouplingFieldDouble(ON_NODES) + vals=DataArrayDouble(7) ; vals.iota(1000) + f.setArray(vals) + f.setName("anonymous") # f has no mesh it is not a bug + pfl=DataArrayInt([0,1,2,3,4,5,6]) ; pfl.setName("pfl") + f1ts.setFieldProfile(f,mm,0,pfl) + # + f1ts=MEDFileField1TS() + f=MEDCouplingFieldDouble(ON_NODES) + vals=DataArrayDouble(8) ; vals.iota(1000) + f.setArray(vals) + f.setName("anonymous") # f has no mesh it is not a bug + pfl=DataArrayInt([0,1,2,3,4,5,6]) ; pfl.setName("pfl") + self.assertRaises(InterpKernelException,f1ts.setFieldProfile,f,mm,0,pfl) + # + f1ts=MEDFileField1TS() + f=MEDCouplingFieldDouble(ON_CELLS) + vals=DataArrayDouble(7) ; vals.iota(1000) + f.setArray(vals) + f.setName("anonymous") # f has no mesh it is not a bug + pfl=DataArrayInt([1,2,3,5,6,7,8]) ; pfl.setName("pfl") + f1ts.setFieldProfile(f,mm,0,pfl) + self.assertTrue(f1ts.getUndergroundDataArray().isEqual(vals,1e-10)) + # + f1ts=MEDFileField1TS() + f=MEDCouplingFieldDouble(ON_GAUSS_PT) + vals=DataArrayDouble(27) ; vals.iota(1000) + f.setArray(vals) + f.setName("anonymous") # f has no mesh it is not a bug + pfl=DataArrayInt([1,2,3,5,6,7,8]) ; pfl.setName("pfl") + f.setMesh(m[pfl]) + f.setGaussLocalizationOnCells([0,1],[0.,0.,1.,0.,1.,1.],[0.3,0.3,0.7,0.7,0.1,0.1],[0.3,0.6,0.1]) + f.setGaussLocalizationOnCells([2],[0.,0.,1.,0.,1.,1.],[0.3,0.3],[1.]) + f.setGaussLocalizationOnCells([3,4,5,6],[0.,0.,1.,0.,1.,1.,0.,1.],[0.1,0.1,0.2,0.2,0.3,0.3,0.4,0.4,0.5,0.5],[0.2,0.3,0.4,0.07,0.03]) + f.setMesh(None) + f1ts.setFieldProfile(f,mm,0,pfl) + self.assertTrue(f1ts.getUndergroundDataArray().isEqual(vals,1e-10)) + vals=DataArrayDouble(26) ; vals.iota(1040) ; f.setArray(vals) + self.assertRaises(InterpKernelException,f1ts.setFieldProfile,f,mm,0,pfl) + vals=DataArrayDouble(27) ; vals.iota(1000) + self.assertTrue(f1ts.getUndergroundDataArray().isEqual(vals,1e-10)) + # + f1ts=MEDFileField1TS() + f=MEDCouplingFieldDouble(ON_GAUSS_NE) + vals=DataArrayDouble(25) ; vals.iota(1000) + f.setArray(vals) + f.setName("anonymous") # f has no mesh it is not a bug + pfl=DataArrayInt([1,2,3,5,6,7,8]) ; pfl.setName("pfl") + f1ts.setFieldProfile(f,mm,0,pfl) + self.assertTrue(f1ts.getUndergroundDataArray().isEqual(vals,1e-10)) + vals2=DataArrayDouble(26) ; vals2.iota(1050) + f.setArray(vals2) + self.assertRaises(InterpKernelException,f1ts.setFieldProfile,f,mm,0,pfl) + self.assertTrue(f1ts.getUndergroundDataArray().isEqual(vals,1e-10)) + # + f1ts=MEDFileField1TS() + self.assertRaises(InterpKernelException,f1ts.setFieldProfile,f,mm,0,pfl) + self.assertRaises(InterpKernelException,f1ts.setFieldProfile,f,mm,0,pfl) + f.setArray(vals) + f1ts.setFieldProfile(f,mm,0,pfl) + pass + + def testWRMeshWithNoCells(self): + fname="Pyfile71.med" + a=DataArrayDouble(4) ; a.iota() + c=MEDCouplingCMesh() ; c.setCoords(a,a) ; m0=c.buildUnstructured() + m00=MEDCouplingUMesh("mesh",1) ; m00.setCoords(m0.getCoords()) ; m00.allocateCells(0) + m=MEDFileUMesh() + m.setMeshAtLevel(0,m00) + m.setRenumFieldArr(1,DataArrayInt(range(10,26))) + m.setFamilyFieldArr(1,DataArrayInt([-1,-1,-1,-1,-1,-2,-2,-2,-2,-2,-2,0,-1,-3,-3,-3])) + m.write(fname,2) + del m,a,c,m0,m00 + # + m=MEDFileMesh.New(fname) + self.assertEqual((),m.getNonEmptyLevels()) + self.assertTrue(m.getCoords().isEqual(DataArrayDouble([(0,0),(1,0),(2,0),(3,0),(0,1),(1,1),(2,1),(3,1),(0,2),(1,2),(2,2),(3,2),(0,3),(1,3),(2,3),(3,3)]),1e-12)) + self.assertTrue(m.getNumberFieldAtLevel(1).isEqual(DataArrayInt(range(10,26)))) + self.assertTrue(m.getFamilyFieldAtLevel(1).isEqual(DataArrayInt([-1,-1,-1,-1,-1,-2,-2,-2,-2,-2,-2,0,-1,-3,-3,-3]))) + pass + + def testWRQPolyg1(self): + fname="Pyfile72.med" + m=MEDCoupling1SGTUMesh("mesh",NORM_QUAD4) ; m.allocateCells() + m.insertNextCell([0,2,1,3]) + m.setCoords(DataArrayDouble([0.,0.,1.,1.,1.,0.,0.,1.],4,2)) + # + ms=[m.deepCpy() for i in xrange(4)] + for i,elt in enumerate(ms): + elt.translate([float(i)*1.5,0.]) + pass + m0=MEDCoupling1SGTUMesh.Merge1SGTUMeshes(ms).buildUnstructured() + m0.convertAllToPoly() + # + ms=[m.deepCpy() for i in xrange(5)] + for i,elt in enumerate(ms): + elt.translate([float(i)*1.5,1.5]) + pass + m1=MEDCoupling1SGTUMesh.Merge1SGTUMeshes(ms).buildUnstructured() + m1.convertAllToPoly() + m1.convertLinearCellsToQuadratic() + # + m=MEDCouplingUMesh.MergeUMeshes(m0,m1) + ## + mm=MEDFileUMesh() + mm.setMeshAtLevel(0,m) + grp0=DataArrayInt([0,2,3]) ; grp0.setName("grp0") + grp1=DataArrayInt([4,6,7]) ; grp1.setName("grp1") + grp2=DataArrayInt([0,1,2,4,5,6]) ; grp2.setName("grp2") + mm.setGroupsAtLevel(0,[grp0,grp1,grp2]) + ## + mm.write(fname,2) + del mm + # + mm_read=MEDFileUMesh(fname) + self.assertTrue(mm_read.getGroupArr(0,"grp0").isEqual(grp0)) + self.assertTrue(mm_read.getGroupArr(0,"grp1").isEqual(grp1)) + self.assertTrue(mm_read.getGroupArr(0,"grp2").isEqual(grp2)) + self.assertTrue(mm_read.getMeshAtLevel(0).isEqual(m,1e-12)) + ## + f=MEDCouplingFieldDouble(ON_CELLS) ; f.setName("MyFirstField") + f.setMesh(m) + arr0=DataArrayDouble(9) ; arr0.iota() + arr1=DataArrayDouble(9) ; arr1.iota(100) + arr=DataArrayDouble.Meld(arr0,arr1) ; arr.setInfoOnComponents(["mm [kg]","sds [m]"]) + f.setArray(arr) ; f.checkCoherency() + f.setTime(5.6,1,2) + ff=MEDFileField1TS() + ff.setFieldNoProfileSBT(f) + ff.write(fname,0) + ## + ff_read=MEDFileField1TS(fname) + f_read=ff_read.getFieldOnMeshAtLevel(ON_CELLS,0,mm_read) + self.assertTrue(f_read.isEqual(f,1e-12,1e-12)) + pass + + def testLoadIfNecessaryOnFromScratchFields0(self): + """ + This test checks that a call to loadArraysIfNecessary works (does nothing) on field data structure whatever its level 1TS, MTS, Fields. + """ + fname="Pyfile77.med" + coords=DataArrayDouble([(0,0,0),(2,1,0),(1,0,0),(1,1,0),(2,0,0),(0,1,0)]) + m=MEDCouplingUMesh("mesh",2) ; m.setCoords(coords) + m.allocateCells() + m.insertNextCell(NORM_QUAD4,[0,5,3,2]) + m.insertNextCell(NORM_QUAD4,[4,2,3,1]) + m.finishInsertingCells() + # + mm=MEDFileUMesh() ; mm.setMeshAtLevel(0,m) + ms=MEDFileMeshes() ; ms.pushMesh(mm) + fs=MEDFileFields() + arrs=4*[None] + # + ff0=MEDFileFieldMultiTS() ; fs.pushField(ff0) + f0=MEDCouplingFieldDouble(ON_GAUSS_NE) ; f0.setMesh(m) ; f0.setTimeUnit("ms") + f0.setTime(1.1,1,1) + f0.setName("myELNOField") + arrs[0]=DataArrayDouble([7,5,3,1,5,3,1,7]) ; arrs[0].setInfoOnComponent(0,"Comp0") + f0.setArray(arrs[0]) + ff0.appendFieldNoProfileSBT(f0) + # + f0.setTime(2.2,2,1) + arrs[1]=DataArrayDouble([1,7,5,3,7,5,3,1]) ; arrs[1].setInfoOnComponent(0,"Comp0") + f0.setArray(arrs[1]) + ff0.appendFieldNoProfileSBT(f0) + # + f0.setTime(3.3,3,1) + arrs[2]=DataArrayDouble([3,1,7,5,1,7,5,3]) ; arrs[2].setInfoOnComponent(0,"Comp0") + f0.setArray(arrs[2]) + ff0.appendFieldNoProfileSBT(f0) + # + f0.setTime(4.4,4,1) + arrs[3]=DataArrayDouble([5,3,1,7,3,1,7,5]) ; arrs[3].setInfoOnComponent(0,"Comp0") + f0.setArray(arrs[3]) + ff0.appendFieldNoProfileSBT(f0) + # + for i,arr in enumerate(arrs): + self.assertTrue(fs[0][i].getUndergroundDataArray().isEqual(arr,1e-12)) + fs[0][i].loadArraysIfNecessary() + self.assertTrue(fs[0][i].getUndergroundDataArray().isEqual(arr,1e-12)) + pass + fs.loadArraysIfNecessary() + for i,arr in enumerate(arrs): + self.assertTrue(fs[0][i].getUndergroundDataArray().isEqual(arr,1e-12)) + pass + fs[0].loadArraysIfNecessary() + for i,arr in enumerate(arrs): + self.assertTrue(fs[0][i].getUndergroundDataArray().isEqual(arr,1e-12)) + pass + pass + + def testField1TSSetFieldNoProfileSBTPerGeoTypes(self): + """ This test is very important, because the same mechanism is used by the MEDReader to generate a field on all the mesh without any processing and memory. + """ + fname="Pyfile78.med" + coords=DataArrayDouble([-0.3,-0.3,0., 0.2,-0.3,0., 0.7,-0.3,0., -0.3,0.2,0., 0.2,0.2,0., 0.7,0.2,0., -0.3,0.7,0., 0.2,0.7,0., 0.7,0.7,0. ],9,3) + targetConn=[0,3,4,1, 1,4,2, 4,5,2, 6,7,4,3, 7,8,5,4]; + m0=MEDCouplingUMesh("mesh",3) ; m0.setCoords(coords) + m0.allocateCells() + for elt in [[0,1,2,3],[1,2,3,4],[2,3,4,5],[3,4,5,6],[4,5,6,7],[5,6,7,8]]:#6 + m0.insertNextCell(NORM_TETRA4,elt) + pass + for elt in [[0,1,2,3,4],[1,2,3,4,5],[2,3,4,5,6],[3,4,5,6,7],[4,5,6,7,8]]:#5 + m0.insertNextCell(NORM_PYRA5,elt) + pass + for elt in [[0,1,2,3,4,5],[1,2,3,4,5,6],[2,3,4,5,6,7],[3,4,5,6,7,8]]:#4 + m0.insertNextCell(NORM_PENTA6,elt) + pass + m0.checkCoherency2() + m1=MEDCouplingUMesh(); m1.setName("mesh") + m1.setMeshDimension(2); + m1.allocateCells(5); + m1.insertNextCell(NORM_TRI3,3,targetConn[4:7]); + m1.insertNextCell(NORM_TRI3,3,targetConn[7:10]); + m1.insertNextCell(NORM_QUAD4,4,targetConn[0:4]); + m1.insertNextCell(NORM_QUAD4,4,targetConn[10:14]); + m1.insertNextCell(NORM_QUAD4,4,targetConn[14:18]); + m1.setCoords(coords); + m3=MEDCouplingUMesh("mesh",0) ; m3.setCoords(coords) + m3.allocateCells() + m3.insertNextCell(NORM_POINT1,[2]) + m3.insertNextCell(NORM_POINT1,[3]) + m3.insertNextCell(NORM_POINT1,[4]) + m3.insertNextCell(NORM_POINT1,[5]) + # + mm=MEDFileUMesh() + mm.setMeshAtLevel(0,m0) + mm.setMeshAtLevel(-1,m1) + mm.setMeshAtLevel(-3,m3) + mm.write(fname,2) + #### The file is written only with one mesh and no fields. Let's put a field on it geo types per geo types. + mm=MEDFileMesh.New(fname) + fs=MEDFileFields() + fmts=MEDFileFieldMultiTS() + f1ts=MEDFileField1TS() + for lev in mm.getNonEmptyLevels(): + for gt in mm.getGeoTypesAtLevel(lev): + p0=mm.getDirectUndergroundSingleGeoTypeMesh(gt) + f=MEDCouplingFieldDouble(ON_CELLS) ; f.setMesh(p0) + arr=DataArrayDouble(f.getNumberOfTuplesExpected()) ; arr.iota() + f.setArray(arr) ; f.setName("f0") + f1ts.setFieldNoProfileSBT(f) + pass + pass + self.assertEqual(mm.getNonEmptyLevels(),(0,-1,-3)) + for lev in [0,-1,-3]: + mm.getDirectUndergroundSingleGeoTypeMeshes(lev) # please let this line, it is for the test to emulate that + pass + fmts.pushBackTimeStep(f1ts) + fs.pushField(fmts) + fs.write(fname,0) + del fs,fmts,f1ts + #### The file contains now one mesh and one cell field with all cells wathever their level ang type fetched. + fs=MEDFileFields(fname) + self.assertEqual(len(fs),1) + self.assertEqual(len(fs[0]),1) + f1ts=fs[0][0] + self.assertEqual(f1ts.getFieldSplitedByType(),[(0,[(0,(0,4),'','')]),(3,[(0,(4,6),'','')]),(4,[(0,(6,9),'','')]),(14,[(0,(9,15),'','')]),(15,[(0,(15,20),'','')]),(16,[(0,(20,24),'','')])]) + self.assertTrue(f1ts.getUndergroundDataArray().isEqual(DataArrayDouble([0,1,2,3,0,1,0,1,2,0,1,2,3,4,5,0,1,2,3,4,0,1,2,3]),1e-12)) + pass + + def testMEDFileUMeshSetName(self): + """ This test is a small but important one for MEDReader in sauv mode. When .sauv file is loaded the convertion is performed in memory and a preparation is done then. + This preparation makes access to internal MEDCouplingMesh pointers whose name must be updated. + """ + fname="Pyfile79.med" + targetConn=[0,3,4,1, 1,4,2, 4,5,2, 6,7,4,3, 7,8,5,4]; + mm=MEDFileUMesh() + m0=MEDCouplingUMesh() ; m0.setMeshDimension(2) # important no name here. + coords=DataArrayDouble([-0.3,-0.3,0., 0.2,-0.3,0., 0.7,-0.3,0., -0.3,0.2,0., 0.2,0.2,0., 0.7,0.2,0., -0.3,0.7,0., 0.2,0.7,0., 0.7,0.7,0. ],9,3) + m0.allocateCells(5); + m0.insertNextCell(NORM_TRI3,3,targetConn[4:7]); + m0.insertNextCell(NORM_TRI3,3,targetConn[7:10]); + m0.insertNextCell(NORM_QUAD4,4,targetConn[0:4]); + m0.insertNextCell(NORM_QUAD4,4,targetConn[10:14]); + m0.insertNextCell(NORM_QUAD4,4,targetConn[14:18]); + m0.setCoords(coords); + mm.setMeshAtLevel(0,m0) + m2=MEDCouplingUMesh() ; m2.setMeshDimension(0) ; m2.setCoords(coords) # important no name here. + m2.allocateCells() + m2.insertNextCell(NORM_POINT1,[2]) + m2.insertNextCell(NORM_POINT1,[3]) + m2.insertNextCell(NORM_POINT1,[4]) + m2.insertNextCell(NORM_POINT1,[5]) + mm.setMeshAtLevel(-2,m2) + self.assertEqual(mm.getName(),"") + self.assertEqual(mm.getMeshAtLevel(0).getName(),"") + mm.forceComputationOfParts() + self.assertEqual(mm.getDirectUndergroundSingleGeoTypeMesh(NORM_TRI3).getName(),"") + mm.setName("abc") + self.assertEqual(mm.getName(),"abc") + self.assertEqual(mm.getDirectUndergroundSingleGeoTypeMesh(NORM_TRI3).getName(),"abc") + self.assertEqual(mm.getDirectUndergroundSingleGeoTypeMesh(NORM_QUAD4).getName(),"abc") + self.assertEqual(mm.getDirectUndergroundSingleGeoTypeMesh(NORM_POINT1).getName(),"abc") + self.assertEqual(mm.getMeshAtLevel(0).getName(),"abc") + pass + + def testMEDFileFieldsUnloadArraysWithoutDataLoss1(self): + fileName="Pyfile80.med" + m=MEDCouplingCMesh() ; m.setName("cmesh") + arr=DataArrayDouble(6) ; arr.iota() + m.setCoords(arr,arr) + nbCells=m.getNumberOfCells() + self.assertEqual(25,nbCells) + f=MEDCouplingFieldDouble(ON_CELLS) + f.setName("FieldOnCell") ; f.setMesh(m) + arr=DataArrayDouble(nbCells) ; arr.iota() + mm=MEDFileCMesh() + mm.setMesh(m) + # + fmts=MEDFileFieldMultiTS() + # + for i in xrange(nbCells): + t=(float(i)+0.1,i+1,-i-2) + f.setTime(*t) + arr2=DataArrayDouble(nbCells) + perm=DataArrayInt(nbCells) ; perm.iota(i) ; perm%=nbCells + arr2[perm]=arr + f.setArray(arr2) + f1ts=MEDFileField1TS() + f1ts.setFieldNoProfileSBT(f) + fmts.pushBackTimeStep(f1ts) + pass + fmts.unloadArraysWithoutDataLoss() + self.assertTrue(fmts[0].getUndergroundDataArray().isEqual(DataArrayDouble([0.,1.,2.,3.,4.,5.,6.,7.,8.,9.,10.,11.,12.,13.,14.,15.,16.,17.,18.,19.,20.,21.,22.,23.,24.]),1e-12)) + fs=MEDFileFields() ; fs.pushField(fmts) + self.assertTrue(fs[0][0].getUndergroundDataArray().isEqual(DataArrayDouble([0.,1.,2.,3.,4.,5.,6.,7.,8.,9.,10.,11.,12.,13.,14.,15.,16.,17.,18.,19.,20.,21.,22.,23.,24.]),1e-12)) + fs.unloadArraysWithoutDataLoss() + self.assertTrue(fs[0][0].getUndergroundDataArray().isEqual(DataArrayDouble([0.,1.,2.,3.,4.,5.,6.,7.,8.,9.,10.,11.,12.,13.,14.,15.,16.,17.,18.,19.,20.,21.,22.,23.,24.]),1e-12)) + f1ts=fs[0][0] + self.assertTrue(f1ts.getUndergroundDataArray().isEqual(DataArrayDouble([0.,1.,2.,3.,4.,5.,6.,7.,8.,9.,10.,11.,12.,13.,14.,15.,16.,17.,18.,19.,20.,21.,22.,23.,24.]),1e-12)) + f1ts.unloadArraysWithoutDataLoss() + self.assertTrue(f1ts.getUndergroundDataArray().isEqual(DataArrayDouble([0.,1.,2.,3.,4.,5.,6.,7.,8.,9.,10.,11.,12.,13.,14.,15.,16.,17.,18.,19.,20.,21.,22.,23.,24.]),1e-12)) + mm.write(fileName,2) + fs.write(fileName,0) + del m,fmts,mm,f,f1ts + ## + mm=MEDFileMesh.New(fileName) + fmts=MEDFileFieldMultiTS(fileName) + self.assertTrue(fmts[0].getUndergroundDataArray().isEqual(DataArrayDouble([0.,1.,2.,3.,4.,5.,6.,7.,8.,9.,10.,11.,12.,13.,14.,15.,16.,17.,18.,19.,20.,21.,22.,23.,24.]),1e-12)) + fmts.unloadArraysWithoutDataLoss() + self.assertTrue(not fmts[0].getUndergroundDataArray().isAllocated()) + fmts.loadArraysIfNecessary() + self.assertTrue(fmts[0].getUndergroundDataArray().isEqual(DataArrayDouble([0.,1.,2.,3.,4.,5.,6.,7.,8.,9.,10.,11.,12.,13.,14.,15.,16.,17.,18.,19.,20.,21.,22.,23.,24.]),1e-12)) + del mm,fmts + fs=MEDFileFields(fileName) + self.assertTrue(fs[0][0].getUndergroundDataArray().isEqual(DataArrayDouble([0.,1.,2.,3.,4.,5.,6.,7.,8.,9.,10.,11.,12.,13.,14.,15.,16.,17.,18.,19.,20.,21.,22.,23.,24.]),1e-12)) + fs.unloadArraysWithoutDataLoss() + self.assertTrue(not fs[0][0].getUndergroundDataArray().isAllocated()) + fs.loadArraysIfNecessary() + self.assertTrue(fs[0][0].getUndergroundDataArray().isEqual(DataArrayDouble([0.,1.,2.,3.,4.,5.,6.,7.,8.,9.,10.,11.,12.,13.,14.,15.,16.,17.,18.,19.,20.,21.,22.,23.,24.]),1e-12)) + del fs + f1ts=MEDFileField1TS(fileName) + self.assertTrue(f1ts.getUndergroundDataArray().isEqual(DataArrayDouble([0.,1.,2.,3.,4.,5.,6.,7.,8.,9.,10.,11.,12.,13.,14.,15.,16.,17.,18.,19.,20.,21.,22.,23.,24.]),1e-12)) + f1ts.unloadArraysWithoutDataLoss() + self.assertTrue(not f1ts.getUndergroundDataArray().isAllocated()) + f1ts.loadArraysIfNecessary() + self.assertTrue(f1ts.getUndergroundDataArray().isEqual(DataArrayDouble([0.,1.,2.,3.,4.,5.,6.,7.,8.,9.,10.,11.,12.,13.,14.,15.,16.,17.,18.,19.,20.,21.,22.,23.,24.]),1e-12)) + pass + + def testMEDFileUMeshLoadPart1(self): + """ This method tests MEDFileUMesh.LoadPart that loads only a part of a specified mesh in a MED file. The part is specfied using a slice of cell ids. Only nodes on which cells lies are loaded to reduce at most the amount of + memory of the returned instance. + """ + fileName="Pyfile81.med" + arr=DataArrayDouble(6) ; arr.iota() + m=MEDCouplingCMesh() ; m.setCoords(arr,arr) + m=m.buildUnstructured() + m.setName("Mesh") + m.changeSpaceDimension(3,0.) + infos=["aa [b]","cc [de]","gg [klm]"] + m.getCoords().setInfoOnComponents(infos) + m.checkCoherency2() + mm=MEDFileUMesh() + mm.setMeshAtLevel(0,m) + m1=MEDCouplingCMesh() ; m1.setCoords(arr) ; m1.setName("Mesh") + m1=m1.buildUnstructured() ; m1.setCoords(m.getCoords()) + mm.setMeshAtLevel(-1,m1) + renum0=DataArrayInt([3,6,7,10,11,0,2,1,9,8,5,4,12,13,14,24,23,22,21,20,19,18,17,16,15]) + famField0=DataArrayInt([-3,-6,-7,-10,-11,0,-2,-1,-9,-8,-5,-4,-12,-13,-14,-24,-23,-22,-21,-20,-19,-18,-17,-16,-15]) + namesCellL0=DataArrayAsciiChar(25,16) + namesCellL0[:]=["Cell#%.3d "%(i) for i in xrange(25)] + renumM1=DataArrayInt([3,4,0,2,1]) + famFieldM1=DataArrayInt([-3,-4,0,-2,-1]) + mm.setRenumFieldArr(0,renum0) + mm.setFamilyFieldArr(0,famField0) + mm.setNameFieldAtLevel(0,namesCellL0) + mm.setRenumFieldArr(-1,renumM1) + mm.setFamilyFieldArr(-1,famFieldM1) + renum1=DataArrayInt([13,16,17,20,21,10,12,11,19,18,15,14,22,23,24,34,33,32,31,30,29,28,27,26,25,45,44,43,42,41,40,39,38,37,36,35]) + famField1=DataArrayInt([-13,-16,-17,-20,-21,-10,-12,-11,-19,-18,-15,-14,-22,-23,-24,-34,-33,-32,-31,-30,-29,-28,-27,-26,-25,-45,-44,-43,-42,-41,-40,-39,-38,-37,-36,-35]) + namesNodes=DataArrayAsciiChar(36,16) + namesNodes[:]=["Node#%.3d "%(i) for i in xrange(36)] + mm.setRenumFieldArr(1,renum1) + mm.setFamilyFieldArr(1,famField1) + mm.setNameFieldAtLevel(1,namesNodes) + mm.setFamilyId("Fam7",77) + mm.setFamilyId("Fam8",88) + mm.setGroupsOnFamily("Fam7",["Grp0","Grp1"]) + mm.setGroupsOnFamily("Fam8",["Grp1","Grp2"]) + mm.write(fileName,2) + # + mm0=MEDFileUMesh.LoadPartOf(fileName,"Mesh",[NORM_QUAD4],[0,10,1]) + self.assertEqual(mm0.getAllGeoTypes(),[NORM_QUAD4]) + self.assertTrue(mm0.getDirectUndergroundSingleGeoTypeMesh(NORM_QUAD4).getNodalConnectivity().isEqual(DataArrayInt([1,0,6,7,2,1,7,8,3,2,8,9,4,3,9,10,5,4,10,11,7,6,12,13,8,7,13,14,9,8,14,15,10,9,15,16,11,10,16,17]))) + coo=DataArrayDouble([(0,0,0),(1,0,0),(2,0,0),(3,0,0),(4,0,0),(5,0,0),(0,1,0),(1,1,0),(2,1,0),(3,1,0),(4,1,0),(5,1,0),(0,2,0),(1,2,0),(2,2,0),(3,2,0),(4,2,0),(5,2,0)]) ; coo.setInfoOnComponents(infos) + self.assertTrue(mm0.getCoords().isEqual(coo,1e-12)) + self.assertTrue(mm0.getFamilyFieldAtLevel(0).isEqual(famField0[:10])) + self.assertTrue(mm0.getNumberFieldAtLevel(0).isEqual(renum0[:10])) + self.assertTrue(mm0.getNameFieldAtLevel(0).isEqual(namesCellL0[:10])) + self.assertTrue(mm0.getFamilyFieldAtLevel(1).isEqual(famField1[:18])) + self.assertTrue(mm0.getNumberFieldAtLevel(1).isEqual(renum1[:18])) + self.assertTrue(mm0.getNameFieldAtLevel(1).isEqual(namesNodes[:18])) + # + mm1=MEDFileUMesh.LoadPartOf(fileName,"Mesh",[NORM_QUAD4],[11,25,1]) + self.assertEqual(mm1.getAllGeoTypes(),[NORM_QUAD4]) + self.assertTrue(mm1.getDirectUndergroundSingleGeoTypeMesh(NORM_QUAD4).getNodalConnectivity().isEqual(DataArrayInt([1,0,6,7,2,1,7,8,3,2,8,9,4,3,9,10,6,5,11,12,7,6,12,13,8,7,13,14,9,8,14,15,10,9,15,16,12,11,17,18,13,12,18,19,14,13,19,20,15,14,20,21,16,15,21,22]))) + coo=DataArrayDouble([(1,2,0),(2,2,0),(3,2,0),(4,2,0),(5,2,0),(0,3,0),(1,3,0),(2,3,0),(3,3,0),(4,3,0),(5,3,0),(0,4,0),(1,4,0),(2,4,0),(3,4,0),(4,4,0),(5,4,0),(0,5,0),(1,5,0),(2,5,0),(3,5,0),(4,5,0),(5,5,0)]) ; coo.setInfoOnComponents(infos) + self.assertTrue(mm1.getCoords().isEqual(coo,1e-12)) + self.assertTrue(mm1.getFamilyFieldAtLevel(0).isEqual(famField0[11:])) + self.assertTrue(mm1.getNumberFieldAtLevel(0).isEqual(renum0[11:])) + self.assertTrue(mm1.getNameFieldAtLevel(0).isEqual(namesCellL0[11:])) + self.assertTrue(mm1.getFamilyFieldAtLevel(1).isEqual(famField1[13:])) + self.assertTrue(mm1.getNumberFieldAtLevel(1).isEqual(renum1[13:])) + self.assertTrue(mm1.getNameFieldAtLevel(1).isEqual(namesNodes[13:])) + # + mm2=MEDFileUMesh.LoadPartOf(fileName,"Mesh",[NORM_SEG2,NORM_QUAD4],[0,5,1,1,10,1]) + self.assertEqual(mm2.getAllGeoTypes(),[NORM_QUAD4,NORM_SEG2]) + self.assertTrue(mm2.getFamilyFieldAtLevel(0).isEqual(famField0[1:10])) + self.assertTrue(mm2.getNumberFieldAtLevel(0).isEqual(renum0[1:10])) + self.assertTrue(mm2.getNameFieldAtLevel(0).isEqual(namesCellL0[1:10])) + self.assertTrue(mm2.getFamilyFieldAtLevel(-1).isEqual(famFieldM1)) + self.assertTrue(mm2.getNumberFieldAtLevel(-1).isEqual(renumM1)) + self.assertTrue(mm2.getNameFieldAtLevel(-1) is None) + self.assertTrue(mm2.getDirectUndergroundSingleGeoTypeMesh(NORM_QUAD4).getNodalConnectivity().isEqual(DataArrayInt([2,1,7,8,3,2,8,9,4,3,9,10,5,4,10,11,7,6,12,13,8,7,13,14,9,8,14,15,10,9,15,16,11,10,16,17]))) + self.assertTrue(mm2.getDirectUndergroundSingleGeoTypeMesh(NORM_SEG2).getNodalConnectivity().isEqual(DataArrayInt([0,1,1,2,2,3,3,4,4,5]))) + coo=DataArrayDouble([(0,0,0),(1,0,0),(2,0,0),(3,0,0),(4,0,0),(5,0,0),(0,1,0),(1,1,0),(2,1,0),(3,1,0),(4,1,0),(5,1,0),(0,2,0),(1,2,0),(2,2,0),(3,2,0),(4,2,0),(5,2,0)]) ; coo.setInfoOnComponents(infos) + self.assertTrue(mm2.getCoords().isEqual(coo,1e-12)) + self.assertTrue(mm2.getFamilyFieldAtLevel(1).isEqual(famField1[:18])) + self.assertTrue(mm2.getNumberFieldAtLevel(1).isEqual(renum1[:18])) + self.assertTrue(mm2.getNameFieldAtLevel(1).isEqual(namesNodes[:18])) + pass + + def testMEDFileFieldsLoadPart1(self): + """This method tests partial loading on fields on CELL. It is the same principle than those in testMEDFileUMeshLoadPart1. + """ + fileName="Pyfile82.med" + meshName="Mesh" + compos=["aa [kg]","bbb [m/s]"] + arr=DataArrayDouble(6) ; arr.iota() + m=MEDCouplingCMesh() ; m.setCoords(arr,arr) + m=m.buildUnstructured() + m.setName(meshName) + m.changeSpaceDimension(3,0.) + infos=["aa [b]","cc [de]","gg [klm]"] + m.getCoords().setInfoOnComponents(infos) + m.checkCoherency2() + f=MEDCouplingFieldDouble(ON_CELLS,ONE_TIME) ; f.setMesh(m) + f.setName("Field") + arr=DataArrayDouble(25,2) ; arr.setInfoOnComponents(compos) + arr[:,0]=range(25) + arr[:,1]=range(100,125) + f.setArray(arr) + MEDLoader.WriteField(fileName,f,2) + f=MEDCouplingFieldDouble(ON_NODES,ONE_TIME) ; f.setMesh(m) + f.setName("FieldNode") + arr=DataArrayDouble(36,2) ; arr.setInfoOnComponents(compos) + arr[:,0]=range(200,236) + arr[:,1]=range(300,336) + f.setArray(arr) + f.checkCoherency() + MEDLoader.WriteFieldUsingAlreadyWrittenMesh(fileName,f) + # + ms=MEDFileMeshes() + mm=MEDFileUMesh.LoadPartOf(fileName,meshName,[NORM_QUAD4],[0,6,1]) + ms.pushMesh(mm) + fs=MEDFileFields.LoadPartOf(fileName,False,ms) + self.assertEqual(fs[1][0].getFieldSplitedByType(),[(40,[(1,(0,14),'','')])]) + # + ms=MEDFileMeshes() + mm=MEDFileUMesh.LoadPartOf(fileName,meshName,[NORM_QUAD4],[3,15,1]) + ms.pushMesh(mm) + fs=MEDFileFields.LoadPartOf(fileName,False,ms) + fs=fs.deepCpy() + fs[0][0].loadArrays() + arr=DataArrayDouble(12,2) ; arr[:,0]=range(3,15) ; arr[:,1]=range(103,115) + arr.setInfoOnComponents(compos) + self.assertTrue(fs[0][0].getUndergroundDataArray().isEqual(arr,1e-12)) + fs[1][0].loadArrays() + arr=DataArrayDouble(21,2) ; arr[:,0]=range(203,224) ; arr[:,1]=range(303,324) + arr.setInfoOnComponents(compos) + self.assertTrue(fs[1][0].getUndergroundDataArray().isEqual(arr,1e-12)) + pass + + def testMEDFileWithoutCells1(self): + fileName="Pyfile83.med" + coo=DataArrayDouble([(0,0,0),(1,0,0),(2,0,0)]) + coo.setInfoOnComponents(["aa [m]","bbb [s]","cccc [m/s]"]) + mm=MEDFileUMesh() + mm.setCoords(coo) + mm.setName("mesh") + mm.write(fileName,2) + # + mm=MEDFileMesh.New(fileName) + self.assertEqual(mm.getName(),"mesh") + self.assertTrue(mm.getCoords().isEqual(coo,1e-12)) + pass + + def testZipCoordsWithLoadPart1(self): + """ Test close to Pyfile82.med except that here zipCoords on MEDFileUMesh is invoked here to see if the PartDef is correctly updated. + """ + fileName="Pyfile84.med" + meshName="Mesh" + compos=["aa [kg]","bbb [m/s]"] + arr=DataArrayDouble(6) ; arr.iota() + m=MEDCouplingCMesh() ; m.setCoords(arr,arr) + m=m.buildUnstructured() + m.setName(meshName) + m.changeSpaceDimension(3,0.) + infos=["aa [b]","cc [de]","gg [klm]"] + m.getCoords().setInfoOnComponents(infos) + m.checkCoherency2() + f=MEDCouplingFieldDouble(ON_CELLS,ONE_TIME) ; f.setMesh(m) + f.setName("Field") + arr=DataArrayDouble(25,2) ; arr.setInfoOnComponents(compos) + arr[:,0]=range(25) + arr[:,1]=range(100,125) + f.setArray(arr) + MEDLoader.WriteField(fileName,f,2) + f=MEDCouplingFieldDouble(ON_NODES,ONE_TIME) ; f.setMesh(m) + f.setName("FieldNode") + arr=DataArrayDouble(36,2) ; arr.setInfoOnComponents(compos) + arr[:,0]=range(200,236) + arr[:,1]=range(300,336) + f.setArray(arr) + f.checkCoherency() + MEDLoader.WriteFieldUsingAlreadyWrittenMesh(fileName,f) + # + ms=MEDFileMeshes() + mm=MEDFileUMesh.LoadPartOf(fileName,meshName,[NORM_QUAD4],[4,6,1]) + ms.pushMesh(mm) + spd=mm.getPartDefAtLevel(0,NORM_QUAD4) + self.assertEqual(spd.getSlice(),slice(4,6,1)) + spd=mm.getPartDefAtLevel(1) + self.assertEqual(spd.getSlice(),slice(4,14,1)) + self.assertTrue(spd.getNumberOfElems()==10 and spd.getNumberOfElems()==mm.getNumberOfNodes()) + mm.zipCoords() # <- The important line is here ! + spd=mm.getPartDefAtLevel(0,NORM_QUAD4) + self.assertEqual(spd.getSlice(),slice(4,6,1)) + spd=mm.getPartDefAtLevel(1) + self.assertTrue(spd.getNumberOfElems()==8 and spd.getNumberOfElems()==mm.getNumberOfNodes()) + self.assertTrue(spd.toDAI().isEqual(DataArrayInt([4,5,6,7,10,11,12,13]))) + fs=MEDFileFields.LoadPartOf(fileName,False,ms) + fs[0][0].loadArrays() + arr=DataArrayDouble([(4,104),(5,105)]) + arr.setInfoOnComponents(compos) + self.assertTrue(fs[0][0].getUndergroundDataArray().isEqual(arr,1e-12)) + fs[1][0].loadArrays() + arr=DataArrayDouble([(204,304),(205,305),(206,306),(207,307),(210,310),(211,311),(212,312),(213,313)]) + arr.setInfoOnComponents(compos) + self.assertTrue(fs[1][0].getUndergroundDataArray().isEqual(arr,1e-12)) + pass + + def testMEDFileCMeshSetGroupsAtLevel(self): + """ Non regression test to check that setGroupsAtLevel is available with MEDFileCMesh. + """ + m=MEDCouplingCMesh() ; m.setCoords(DataArrayDouble([0,1,2,3,4]),DataArrayDouble([0,1,2,3,4])) + m.setName("Mesh") + mm=MEDFileCMesh() ; mm.setMesh(m) + grp=DataArrayInt([1,3,4,5,7]) ; grp.setName("MyAssembly") + mm.setGroupsAtLevel(0,[grp]) + self.assertTrue(mm.getFamilyFieldAtLevel(0).isEqual(DataArrayInt([-1,-2,-1,-2,-2,-2,-1,-2,-1,-1,-1,-1,-1,-1,-1,-1]))) + pass + + def testMEDFileUMeshBuildExtrudedMesh1(self): + """ New functionality of MEDFileUMesh.buildExtrudedMesh.""" + fileName="Pyfile85.med" + meshName2D="Mesh" + meshName1D="Mesh1D" + meshName3DOut="Mesh3D" + # + d1=DataArrayInt([0,4,20,24]) + d2=DataArrayInt([0,1,2,3,7,8,12,13,17,18,19,20]) + # + a=DataArrayDouble(6) ; a.iota() + m=MEDCouplingCMesh() ; m.setCoords(a,a) + m=m.buildUnstructured() + d1c=d1.buildComplement(m.getNumberOfCells()) + m=m[d1c] ; m.zipCoords() + m0=m[d2] ; m1=m[d2.buildComplement(m.getNumberOfCells())] + m0.simplexize(0) + m=MEDCouplingUMesh.MergeUMeshesOnSameCoords([m0,m1]) + m.setName(meshName2D) + mMinus1,a,b,c,d=m.buildDescendingConnectivity() + e=d.deltaShiftIndex().getIdsEqual(1) + # + mm=MEDFileUMesh() + mm.setMeshAtLevel(0,m) ; mm.setMeshAtLevel(-1,mMinus1) + grp0=DataArrayInt([0,1,2,3,4,5,24,25,26]) ; grp0.setName("grp0") + mm.setGroupsAtLevel(0,[grp0]) + grp1=e ; grp1.setName("grp1") + mm.setGroupsAtLevel(-1,[grp1]) + mm.write(fileName,2) + # + a=DataArrayDouble(3) ; a.iota() + tmp=MEDCouplingCMesh() ; tmp.setCoords(a) ; tmp=tmp.buildUnstructured() + tmp.setName(meshName1D) + tmp.changeSpaceDimension(3) + tmp.setCoords(tmp.getCoords()[:,[1,2,0]]) + mm1D=MEDFileUMesh() + mm1D.setMeshAtLevel(0,tmp) + mm1D.write(fileName,0) + # test is here ! + mm2D=MEDFileMesh.New(fileName,meshName2D) + mm1D=MEDFileMesh.New(fileName,meshName1D) + m1D=mm1D.getMeshAtLevel(0) + mm3D=mm2D.buildExtrudedMesh(m1D,0) + # + self.assertEqual(mm3D.getName(),mm2D.getName()) + self.assertEqual(mm3D.getNumberOfCellsAtLevel(0),66) + self.assertEqual(mm3D.getNumberOfCellsAtLevel(-1),194) + self.assertEqual(mm3D.getGroupsNames(),('grp0','grp0_extruded','grp0_top','grp1','grp1_extruded','grp1_top')) + self.assertEqual(mm3D.getGrpNonEmptyLevels("grp0"),(-1,)) + self.assertEqual(mm3D.getGrpNonEmptyLevels("grp0_top"),(-1,)) + self.assertEqual(mm3D.getGrpNonEmptyLevels("grp0_extruded"),(0,)) + self.assertEqual(mm3D.getGrpNonEmptyLevels("grp1"),(-2,)) + self.assertEqual(mm3D.getGrpNonEmptyLevels("grp1_top"),(-2,)) + self.assertEqual(mm3D.getGrpNonEmptyLevels("grp1_extruded"),(-1,)) + d=DataArrayDouble([(1.,0.,0.),(2.,0.,0.),(3.,0.,0.),(4.,0.,0.),(0.,1.,0.),(1.,1.,0.),(2.,1.,0.),(3.,1.,0.),(4.,1.,0.),(5.,1.,0.),(0.,2.,0.),(1.,2.,0.),(2.,2.,0.),(3.,2.,0.),(4.,2.,0.),(5.,2.,0.),(0.,3.,0.),(1.,3.,0.),(2.,3.,0.),(3.,3.,0.),(4.,3.,0.),(5.,3.,0.),(0.,4.,0.),(1.,4.,0.),(2.,4.,0.),(3.,4.,0.),(4.,4.,0.),(5.,4.,0.),(1.,5.,0.),(2.,5.,0.),(3.,5.,0.),(4.,5.,0.),(1.,0.,1.),(2.,0.,1.),(3.,0.,1.),(4.,0.,1.),(0.,1.,1.),(1.,1.,1.),(2.,1.,1.),(3.,1.,1.),(4.,1.,1.),(5.,1.,1.),(0.,2.,1.),(1.,2.,1.),(2.,2.,1.),(3.,2.,1.),(4.,2.,1.),(5.,2.,1.),(0.,3.,1.),(1.,3.,1.),(2.,3.,1.),(3.,3.,1.),(4.,3.,1.),(5.,3.,1.),(0.,4.,1.),(1.,4.,1.),(2.,4.,1.),(3.,4.,1.),(4.,4.,1.),(5.,4.,1.),(1.,5.,1.),(2.,5.,1.),(3.,5.,1.),(4.,5.,1.),(1.,0.,2.),(2.,0.,2.),(3.,0.,2.),(4.,0.,2.),(0.,1.,2.),(1.,1.,2.),(2.,1.,2.),(3.,1.,2.),(4.,1.,2.),(5.,1.,2.),(0.,2.,2.),(1.,2.,2.),(2.,2.,2.),(3.,2.,2.),(4.,2.,2.),(5.,2.,2.),(0.,3.,2.),(1.,3.,2.),(2.,3.,2.),(3.,3.,2.),(4.,3.,2.),(5.,3.,2.),(0.,4.,2.),(1.,4.,2.),(2.,4.,2.),(3.,4.,2.),(4.,4.,2.),(5.,4.,2.),(1.,5.,2.),(2.,5.,2.),(3.,5.,2.),(4.,5.,2.)]) + self.assertTrue(mm3D.getCoords().isEqual(d,1e-12)) + d=DataArrayInt([16,1,0,5,33,32,37,16,1,5,6,33,37,38,16,2,1,6,34,33,38,16,2,6,7,34,38,39,16,3,2,7,35,34,39,16,3,7,8,35,39,40,16,5,4,10,37,36,42,16,5,10,11,37,42,43,16,9,8,14,41,40,46,16,9,14,15,41,46,47,16,11,10,16,43,42,48,16,11,16,17,43,48,49,16,15,14,20,47,46,52,16,15,20,21,47,52,53,16,17,16,22,49,48,54,16,17,22,23,49,54,55,16,21,20,26,53,52,58,16,21,26,27,53,58,59,16,24,23,28,56,55,60,16,24,28,29,56,60,61,16,25,24,29,57,56,61,16,25,29,30,57,61,62,16,26,25,30,58,57,62,16,26,30,31,58,62,63,16,33,32,37,65,64,69,16,33,37,38,65,69,70,16,34,33,38,66,65,70,16,34,38,39,66,70,71,16,35,34,39,67,66,71,16,35,39,40,67,71,72,16,37,36,42,69,68,74,16,37,42,43,69,74,75,16,41,40,46,73,72,78,16,41,46,47,73,78,79,16,43,42,48,75,74,80,16,43,48,49,75,80,81,16,47,46,52,79,78,84,16,47,52,53,79,84,85,16,49,48,54,81,80,86,16,49,54,55,81,86,87,16,53,52,58,85,84,90,16,53,58,59,85,90,91,16,56,55,60,88,87,92,16,56,60,61,88,92,93,16,57,56,61,89,88,93,16,57,61,62,89,93,94,16,58,57,62,90,89,94,16,58,62,63,90,94,95,18,6,5,11,12,38,37,43,44,18,7,6,12,13,39,38,44,45,18,8,7,13,14,40,39,45,46,18,12,11,17,18,44,43,49,50,18,13,12,18,19,45,44,50,51,18,14,13,19,20,46,45,51,52,18,18,17,23,24,50,49,55,56,18,19,18,24,25,51,50,56,57,18,20,19,25,26,52,51,57,58,18,38,37,43,44,70,69,75,76,18,39,38,44,45,71,70,76,77,18,40,39,45,46,72,71,77,78,18,44,43,49,50,76,75,81,82,18,45,44,50,51,77,76,82,83,18,46,45,51,52,78,77,83,84,18,50,49,55,56,82,81,87,88,18,51,50,56,57,83,82,88,89,18,52,51,57,58,84,83,89,90]) + self.assertTrue(mm3D[0].getNodalConnectivity().isEqual(d)) + d=DataArrayInt([0,7,14,21,28,35,42,49,56,63,70,77,84,91,98,105,112,119,126,133,140,147,154,161,168,175,182,189,196,203,210,217,224,231,238,245,252,259,266,273,280,287,294,301,308,315,322,329,336,345,354,363,372,381,390,399,408,417,426,435,444,453,462,471,480,489,498]) + self.assertTrue(mm3D[0].getNodalConnectivityIndex().isEqual(d)) + d=DataArrayInt([3,1,0,5,3,1,5,6,3,2,1,6,3,2,6,7,3,3,2,7,3,3,7,8,3,5,4,10,3,5,10,11,3,9,8,14,3,9,14,15,3,11,10,16,3,11,16,17,3,15,14,20,3,15,20,21,3,17,16,22,3,17,22,23,3,21,20,26,3,21,26,27,3,24,23,28,3,24,28,29,3,25,24,29,3,25,29,30,3,26,25,30,3,26,30,31,3,65,64,69,3,65,69,70,3,66,65,70,3,66,70,71,3,67,66,71,3,67,71,72,3,69,68,74,3,69,74,75,3,73,72,78,3,73,78,79,3,75,74,80,3,75,80,81,3,79,78,84,3,79,84,85,3,81,80,86,3,81,86,87,3,85,84,90,3,85,90,91,3,88,87,92,3,88,92,93,3,89,88,93,3,89,93,94,3,90,89,94,3,90,94,95,4,1,0,32,33,4,0,5,37,32,4,5,1,33,37,4,5,6,38,37,4,6,1,33,38,4,2,1,33,34,4,6,2,34,38,4,6,7,39,38,4,7,2,34,39,4,3,2,34,35,4,7,3,35,39,4,7,8,40,39,4,8,3,35,40,4,5,4,36,37,4,4,10,42,36,4,10,5,37,42,4,10,11,43,42,4,11,5,37,43,4,9,8,40,41,4,8,14,46,40,4,14,9,41,46,4,14,15,47,46,4,15,9,41,47,4,10,16,48,42,4,16,11,43,48,4,16,17,49,48,4,17,11,43,49,4,14,20,52,46,4,20,15,47,52,4,20,21,53,52,4,21,15,47,53,4,16,22,54,48,4,22,17,49,54,4,22,23,55,54,4,23,17,49,55,4,20,26,58,52,4,26,21,53,58,4,26,27,59,58,4,27,21,53,59,4,24,23,55,56,4,23,28,60,55,4,28,24,56,60,4,28,29,61,60,4,29,24,56,61,4,25,24,56,57,4,29,25,57,61,4,29,30,62,61,4,30,25,57,62,4,26,25,57,58,4,30,26,58,62,4,30,31,63,62,4,31,26,58,63,4,11,12,44,43,4,12,6,38,44,4,12,13,45,44,4,13,7,39,45,4,13,14,46,45,4,17,18,50,49,4,18,12,44,50,4,18,19,51,50,4,19,13,45,51,4,19,20,52,51,4,24,18,50,56,4,25,19,51,57,4,33,32,64,65,4,32,37,69,64,4,37,33,65,69,4,37,38,70,69,4,38,33,65,70,4,34,33,65,66,4,38,34,66,70,4,38,39,71,70,4,39,34,66,71,4,35,34,66,67,4,39,35,67,71,4,39,40,72,71,4,40,35,67,72,4,37,36,68,69,4,36,42,74,68,4,42,37,69,74,4,42,43,75,74,4,43,37,69,75,4,41,40,72,73,4,40,46,78,72,4,46,41,73,78,4,46,47,79,78,4,47,41,73,79,4,42,48,80,74,4,48,43,75,80,4,48,49,81,80,4,49,43,75,81,4,46,52,84,78,4,52,47,79,84,4,52,53,85,84,4,53,47,79,85,4,48,54,86,80,4,54,49,81,86,4,54,55,87,86,4,55,49,81,87,4,52,58,90,84,4,58,53,85,90,4,58,59,91,90,4,59,53,85,91,4,56,55,87,88,4,55,60,92,87,4,60,56,88,92,4,60,61,93,92,4,61,56,88,93,4,57,56,88,89,4,61,57,89,93,4,61,62,94,93,4,62,57,89,94,4,58,57,89,90,4,62,58,90,94,4,62,63,95,94,4,63,58,90,95,4,43,44,76,75,4,44,38,70,76,4,44,45,77,76,4,45,39,71,77,4,45,46,78,77,4,49,50,82,81,4,50,44,76,82,4,50,51,83,82,4,51,45,77,83,4,51,52,84,83,4,56,50,82,88,4,57,51,83,89,4,6,5,11,12,4,7,6,12,13,4,8,7,13,14,4,12,11,17,18,4,13,12,18,19,4,14,13,19,20,4,18,17,23,24,4,19,18,24,25,4,20,19,25,26,4,70,69,75,76,4,71,70,76,77,4,72,71,77,78,4,76,75,81,82,4,77,76,82,83,4,78,77,83,84,4,82,81,87,88,4,83,82,88,89,4,84,83,89,90]) + self.assertTrue(mm3D[-1].getNodalConnectivity().isEqual(d)) + d=DataArrayInt([0,4,8,12,16,20,24,28,32,36,40,44,48,52,56,60,64,68,72,76,80,84,88,92,96,100,104,108,112,116,120,124,128,132,136,140,144,148,152,156,160,164,168,172,176,180,184,188,192,197,202,207,212,217,222,227,232,237,242,247,252,257,262,267,272,277,282,287,292,297,302,307,312,317,322,327,332,337,342,347,352,357,362,367,372,377,382,387,392,397,402,407,412,417,422,427,432,437,442,447,452,457,462,467,472,477,482,487,492,497,502,507,512,517,522,527,532,537,542,547,552,557,562,567,572,577,582,587,592,597,602,607,612,617,622,627,632,637,642,647,652,657,662,667,672,677,682,687,692,697,702,707,712,717,722,727,732,737,742,747,752,757,762,767,772,777,782,787,792,797,802,807,812,817,822,827,832,837,842,847,852,857,862,867,872,877,882,887,892,897,902,907,912,917,922]) + self.assertTrue(mm3D[-1].getNodalConnectivityIndex().isEqual(d)) + d=DataArrayInt([1,1,0,1,0,5,1,5,1,1,5,6,1,6,1,1,2,1,1,6,2,1,6,7,1,7,2,1,3,2,1,7,3,1,7,8,1,8,3,1,5,4,1,4,10,1,10,5,1,10,11,1,11,5,1,9,8,1,8,14,1,14,9,1,14,15,1,15,9,1,10,16,1,16,11,1,16,17,1,17,11,1,14,20,1,20,15,1,20,21,1,21,15,1,16,22,1,22,17,1,22,23,1,23,17,1,20,26,1,26,21,1,26,27,1,27,21,1,24,23,1,23,28,1,28,24,1,28,29,1,29,24,1,25,24,1,29,25,1,29,30,1,30,25,1,26,25,1,30,26,1,30,31,1,31,26,1,11,12,1,12,6,1,12,13,1,13,7,1,13,14,1,17,18,1,18,12,1,18,19,1,19,13,1,19,20,1,24,18,1,25,19,1,65,64,1,64,69,1,69,65,1,69,70,1,70,65,1,66,65,1,70,66,1,70,71,1,71,66,1,67,66,1,71,67,1,71,72,1,72,67,1,69,68,1,68,74,1,74,69,1,74,75,1,75,69,1,73,72,1,72,78,1,78,73,1,78,79,1,79,73,1,74,80,1,80,75,1,80,81,1,81,75,1,78,84,1,84,79,1,84,85,1,85,79,1,80,86,1,86,81,1,86,87,1,87,81,1,84,90,1,90,85,1,90,91,1,91,85,1,88,87,1,87,92,1,92,88,1,92,93,1,93,88,1,89,88,1,93,89,1,93,94,1,94,89,1,90,89,1,94,90,1,94,95,1,95,90,1,75,76,1,76,70,1,76,77,1,77,71,1,77,78,1,81,82,1,82,76,1,82,83,1,83,77,1,83,84,1,88,82,1,89,83]) + self.assertTrue(mm3D[-2].getNodalConnectivity().isEqual(d)) + d=DataArrayInt(129) ; d.iota() ; d*=3 + self.assertTrue(mm3D[-2].getNodalConnectivityIndex().isEqual(d)) + # + self.assertEqual(mm3D.getGroupArr(-1,"grp0").getName(),"grp0") + self.assertEqual(mm3D.getGroupArr(-2,"grp1").getName(),"grp1") + self.assertTrue(mm3D.getGroupArr(-1,"grp0").isEqualWithoutConsideringStr(DataArrayInt([0,1,2,3,4,5,176,177,178]))) + self.assertTrue(mm3D.getGroupArr(-1,"grp0_top").isEqualWithoutConsideringStr(DataArrayInt([24,25,26,27,28,29,185,186,187]))) + self.assertTrue(mm3D.getGroupArr(-2,"grp1").isEqualWithoutConsideringStr(DataArrayInt([0,1,5,9,12,13,14,18,22,23,30,31,33,37,38,40,42,46,50,51]))) + self.assertTrue(mm3D.getGroupArr(-2,"grp1_top").isEqualWithoutConsideringStr(DataArrayInt([64,65,69,73,76,77,78,82,86,87,94,95,97,101,102,104,106,110,114,115]))) + self.assertTrue(mm3D.getGroupArr(0,"grp0_extruded").isEqualWithoutConsideringStr(DataArrayInt([0,1,2,3,4,5,24,25,26,27,28,29,48,49,50,57,58,59]))) + self.assertTrue(mm3D.getGroupArr(-1,"grp1_extruded").isEqualWithoutConsideringStr(DataArrayInt([48,49,53,57,60,61,62,66,70,71,78,79,81,85,86,88,90,94,98,99,112,113,117,121,124,125,126,130,134,135,142,143,145,149,150,152,154,158,162,163]))) + mm3D.setName("MeshExtruded") + mm3D.write(fileName,0) + pass + + @unittest.skipUnless(MEDCouplingHasNumPyBindings(),"requires numpy") + def testMEDFileUMeshPickeling1(self): + import cPickle + outFileName="Pyfile86.med" + c=DataArrayDouble([-0.3,-0.3, 0.2,-0.3, 0.7,-0.3, -0.3,0.2, 0.2,0.2, 0.7,0.2, -0.3,0.7, 0.2,0.7, 0.7,0.7 ],9,2) + c.setInfoOnComponents(["aa","bbb"]) + targetConn=[0,3,4,1, 1,4,2, 4,5,2, 6,7,4,3, 7,8,5,4] + m=MEDCouplingUMesh(); + m.setMeshDimension(2); + m.allocateCells(5); + m.insertNextCell(NORM_TRI3,3,targetConn[4:7]) + m.insertNextCell(NORM_TRI3,3,targetConn[7:10]) + m.insertNextCell(NORM_QUAD4,4,targetConn[0:4]) + m.insertNextCell(NORM_POLYGON,4,targetConn[10:14]) + m.insertNextCell(NORM_POLYGON,4,targetConn[14:18]) + m.finishInsertingCells(); + m.setCoords(c) + m.checkCoherency() + m1=MEDCouplingUMesh.New(); + m1.setMeshDimension(1); + m1.allocateCells(3); + m1.insertNextCell(NORM_SEG2,2,[1,4]) + m1.insertNextCell(NORM_SEG2,2,[3,6]) + m1.insertNextCell(NORM_SEG3,3,[2,8,5]) + m1.finishInsertingCells(); + m1.setCoords(c) + m1.checkCoherency() + m2=MEDCouplingUMesh.New(); + m2.setMeshDimension(0); + m2.allocateCells(4); + m2.insertNextCell(NORM_POINT1,1,[1]) + m2.insertNextCell(NORM_POINT1,1,[3]) + m2.insertNextCell(NORM_POINT1,1,[2]) + m2.insertNextCell(NORM_POINT1,1,[6]) + m2.finishInsertingCells(); + m2.setCoords(c) + m2.checkCoherency() + # + mm=MEDFileUMesh.New() + self.assertTrue(mm.getUnivNameWrStatus()) + mm.setName("MyFirstMEDCouplingMEDmesh") + mm.setDescription("IHopeToConvinceLastMEDMEMUsers") + mm.setCoords(c) + mm[-1]=m1; + mm[0]=m; + mm.setRenumFieldArr(0,DataArrayInt([32,41,50,56,7])) + mm[-2]=m2; + mm.setRenumFieldArr(-2,DataArrayInt([102,52,45,63])) + # playing with groups + g1_2=DataArrayInt.New() + g1_2.setValues([1,3],2,1) + g1_2.setName("G1") + g2_2=DataArrayInt.New() + g2_2.setValues([1,2,3],3,1) + g2_2.setName("G2") + mm.setGroupsAtLevel(0,[g1_2,g2_2],False) + g1_1=DataArrayInt.New() + g1_1.setValues([0,1,2],3,1) + g1_1.setName("G1") + g2_1=DataArrayInt.New() + g2_1.setValues([0,2],2,1) + g2_1.setName("G2") + mm.setGroupsAtLevel(-1,[g1_1,g2_1],False) + g1_N=DataArrayInt.New() + g1_N.setValues(range(8),8,1) + g1_N.setName("G1") + g2_N=DataArrayInt.New() + g2_N.setValues(range(9),9,1) + g2_N.setName("G2") + mm.setGroupsAtLevel(1,[g1_N,g2_N],False) + mm.createGroupOnAll(0,"GrpOnAllCell") + # check content of mm + t=mm.getGroupArr(0,"G1",False) + self.assertTrue(g1_2.isEqual(t)); + t=mm.getGroupArr(0,"G2",False) + self.assertTrue(g2_2.isEqual(t)); + t=mm.getGroupArr(-1,"G1",False) + self.assertTrue(g1_1.isEqual(t)); + t=mm.getGroupArr(-1,"G2",False) + self.assertTrue(g2_1.isEqual(t)); + t=mm.getGroupArr(1,"G1",False) + self.assertTrue(g1_N.isEqual(t)); + t=mm.getGroupArr(1,"G2",False) + self.assertTrue(g2_N.isEqual(t)); + self.assertTrue(mm.existsGroup("GrpOnAllCell")); + t=mm.getGroupArr(0,"GrpOnAllCell") + # + st=cPickle.dumps(mm,cPickle.HIGHEST_PROTOCOL) + mm2=cPickle.loads(st) + self.assertTrue(mm.isEqual(mm2,1e-12)[0]) + pass + + def testMEDFileFieldsLoadSpecificEntities1(self): + nbNodes=11 + fieldName="myField" + fileName="Pyfile87.med" + nbPdt=10 + meshName="Mesh" + # + m=MEDCouplingCMesh() + arr=DataArrayDouble(nbNodes) ; arr.iota() + m.setCoords(arr) + m=m.buildUnstructured() + m.setName(meshName) + # + fmts=MEDFileFieldMultiTS() + for i in xrange(nbPdt): + f=MEDCouplingFieldDouble(ON_NODES) + f.setMesh(m) + arr=DataArrayDouble(nbNodes) ; arr.iota() ; arr*=i + f.setArray(arr) + f.setName(fieldName) + f.setTime(float(i),i,0) + fmts.appendFieldNoProfileSBT(f) + pass + # + mm=MEDFileUMesh() ; mm[0]=m + fmts.write(fileName,2) + mm.write(fileName,0) + # + fs=MEDFileFields(fileName,False) + fs2=MEDFileFields.LoadSpecificEntities(fileName,[(ON_NODES,NORM_ERROR)],False) + fs.loadArraysIfNecessary() + fs2.loadArraysIfNecessary() + for i in xrange(nbPdt): + self.assertTrue(fs[fieldName][i].getUndergroundDataArray().isEqual(fs2[fieldName][i].getUndergroundDataArray(),1e-12)) + pass + m1=MEDCouplingCMesh() ; m1.setCoords(DataArrayDouble([0,1,2,3]),DataArrayDouble([0,1])) ; m1=m1.buildUnstructured() ; m1.simplexize(0) + m2=MEDCouplingCMesh() ; m2.setCoords(DataArrayDouble([3,4,5]),DataArrayDouble([0,1])) ; m2=m2.buildUnstructured() + m3=MEDCouplingUMesh.MergeUMeshes(m1,m2) ; m3.setName(meshName) + fmts=MEDFileFieldMultiTS() + for i in xrange(nbPdt): + f=MEDCouplingFieldDouble(ON_CELLS) + f.setMesh(m3) + arr=DataArrayDouble(8) ; arr.iota() ; arr*=i + f.setArray(arr) + f.setName(fieldName) + f.setTime(float(i),i,0) + fmts.appendFieldNoProfileSBT(f) + pass + mm=MEDFileUMesh() ; mm[0]=m3 + del mm[0] + self.assertEqual(mm.getNonEmptyLevels(),()) + mm[0]=m3 + self.assertEqual(mm.getNonEmptyLevels(),(0,)) + fmts.write(fileName,2) + fs=MEDFileFields(fileName,False) + fs2=MEDFileFields.LoadSpecificEntities(fileName,[(ON_CELLS,NORM_TRI3)],False) + fs3=MEDFileFieldMultiTS.LoadSpecificEntities(fileName,fieldName,[(ON_CELLS,NORM_QUAD4)],False) + fs4=MEDFileFields.LoadSpecificEntities(fileName,[(ON_CELLS,NORM_TRI3),(ON_CELLS,NORM_QUAD4)],False) + fs.loadArraysIfNecessary() + fs2.loadArraysIfNecessary() + fs3.loadArraysIfNecessary() + fs4.loadArraysIfNecessary() + for i in xrange(nbPdt): + self.assertTrue(fs[fieldName][i].getUndergroundDataArray()[:6].isEqual(fs2[fieldName][i].getUndergroundDataArray(),1e-12)) + self.assertTrue(fs[fieldName][i].getUndergroundDataArray()[6:8].isEqual(fs3[i].getUndergroundDataArray(),1e-12)) + self.assertTrue(fs[fieldName][i].getUndergroundDataArray().isEqual(fs4[fieldName][i].getUndergroundDataArray(),1e-12)) + pass + pass + + def testMEDFileLotsOfTSRW1(self): + nbNodes=11 + fieldName="myField" + fileName="Pyfile88.med" + nbPdt=300 # <- perftest = 30000 + meshName="Mesh" + # + maxPdt=100 # <- optimum = 500 + m=MEDCouplingCMesh() + arr=DataArrayDouble(nbNodes) ; arr.iota() + m.setCoords(arr) + m=m.buildUnstructured() + m.setName(meshName) + # + nbOfField=nbPdt/maxPdt + fs=MEDFileFields() + for j in xrange(nbOfField): + fmts=MEDFileFieldMultiTS() + s=DataArray.GetSlice(slice(0,nbPdt,1),j,nbOfField) + for i in xrange(s.start,s.stop,s.step): + f=MEDCouplingFieldDouble(ON_NODES) + f.setMesh(m) + arr=DataArrayDouble(nbNodes) ; arr.iota() ; arr*=i + f.setArray(arr) + f.setName("%s_%d"%(fieldName,j)) + f.setTime(float(i),i,0) + fmts.appendFieldNoProfileSBT(f) + pass + fs.pushField(fmts) + pass + # + mm=MEDFileUMesh() ; mm[0]=m + fs.write(fileName,2) + mm.write(fileName,0) + ############ + def appendInDict(d,key,val): + if key in d: + d[key].append(val) + else: + d[key]=[val] + pass + import re + allFields=MEDLoader.GetAllFieldNames(fileName) + allFieldsDict={} + pat=re.compile("([\d]+)([\s\S]+)$") + for st in allFields: + stRev=st[::-1] + m=pat.match(stRev) + if m: + appendInDict(allFieldsDict,m.group(2)[::-1],m.group(1)[::-1]) + pass + else: + appendInDict(allFieldsDict,st,'') + pass + pass + fs2=MEDFileFields() + for k in allFieldsDict: + if allFieldsDict[k]!=['']: + allFieldsDict[k]=sorted(allFieldsDict[k],key=lambda x: int(x)) + pass + fmts2=[] + for it in allFieldsDict[k]: + fmts2.append(MEDFileFieldMultiTS.LoadSpecificEntities(fileName,k+it,[(ON_NODES,NORM_ERROR)])) + pass + fmts2.reverse() + zeResu=fmts2.pop() + nbIter=len(fmts2) + for ii in xrange(nbIter): + zeResu.pushBackTimeSteps(fmts2.pop()) + pass + zeResu.setName(k) + fs2.pushField(zeResu) + pass + self.assertEqual(fs2[0].getTimeSteps(),[(i,0,float(i)) for i in xrange(nbPdt)]) + pass + + def testMEDFileMeshRearrangeFamIds1(self): + """ Test for bug EDF10720. The aim of this test is the call of MEDFileMesh.rearrangeFamilies.""" + fileName="Pyfile89.med" + meshName='Maillage_2' + mm=MEDFileUMesh() + coords=DataArrayDouble([(0.,0.,0.),(0.,0.,200.),(0.,200.,200.),(0.,200.,0.),(200.,0.,0.),(200.,0.,200.),(200.,200.,200.),(200.,200.,0.),(0.,0.,100.),(0.,100.,200.),(0.,200.,100.),(0.,100.,0.),(200.,0.,100.),(200.,100.,200.),(200.,200.,100.),(200.,100.,0.),(100.,0.,0.),(100.,0.,200.),(100.,200.,0.),(100.,200.,200.),(0.,116.87743909766768,83.12256090233232),(200.,116.87743909766768,83.12256090233232),(116.87743909766769,0.,116.87743909766769),(116.87743909766769,200.,116.87743909766769),(116.87743909766769,116.87743909766769,0.),(116.87743909766769,116.87743909766769,200.),(63.3851584383713,56.1391811199829,119.728314479261),(138.008709441123,116.039297556044,119.903790959468)]) + # + c0=DataArrayInt([14,1,26,9,8,14,17,26,1,8,14,27,26,17,22,14,26,16,20,8,14,8,0,16,11,14,16,20,11,24,14,25,20,26,27,14,22,26,24,27,14,26,16,22,24,14,8,26,22,17,14,20,9,25,26,14,19,20,25,23,14,23,6,27,25,14,19,23,10,20,14,27,22,21,24,14,27,21,14,18,14,26,9,25,17,14,13,27,25,17,14,27,18,24,21,14,22,21,15,12,14,27,20,24,18,14,23,25,27,20,14,13,27,6,25,14,23,27,6,14,14,15,16,22,12,14,27,17,13,22,14,22,27,21,13,14,24,16,22,15,14,24,18,7,21,14,12,4,15,16,14,22,12,5,13,14,8,26,16,22,14,13,27,21,14,14,20,18,10,3,14,14,27,18,23,14,14,27,6,13,14,21,22,13,12,14,25,26,17,27,14,19,9,25,20,14,26,24,20,16,14,22,24,15,21,14,9,26,1,17,14,23,27,18,20,14,20,11,18,3,14,14,18,21,7,14,19,2,9,10,14,19,23,25,6,14,18,23,20,10,14,20,26,8,9,14,22,13,5,17,14,24,11,18,20,14,21,15,7,24,14,19,20,10,9,14,20,26,27,24,14,16,8,11,20]) + c0i=DataArrayInt([0,5,10,15,20,25,30,35,40,45,50,55,60,65,70,75,80,85,90,95,100,105,110,115,120,125,130,135,140,145,150,155,160,165,170,175,180,185,190,195,200,205,210,215,220,225,230,235,240,245,250,255,260,265,270,275]) + m0=MEDCouplingUMesh(meshName,3) ; m0.setCoords(coords) + m0.setConnectivity(c0,c0i) + mm[0]=m0 + # + c1=DataArrayInt([3,8,20,11,3,8,9,20,3,9,2,10,3,20,9,10,3,0,8,11,3,9,8,1,3,20,10,3,3,11,20,3,3,15,21,12,3,5,12,13,3,21,13,12,3,15,12,4,3,14,6,13,3,14,13,21,3,7,14,21,3,7,21,15,3,5,22,12,3,4,12,16,3,17,1,8,3,16,8,0,3,5,17,22,3,12,22,16,3,22,17,8,3,16,22,8,3,10,2,19,3,7,18,14,3,14,23,6,3,3,10,18,3,23,19,6,3,18,23,14,3,10,19,23,3,10,23,18,3,3,18,11,3,7,24,18,3,15,4,16,3,11,16,0,3,7,15,24,3,18,24,11,3,24,15,16,3,11,24,16,3,9,19,2,3,19,25,6,3,17,5,13,3,1,17,9,3,25,13,6,3,9,25,19,3,17,13,25,3,17,25,9]) + c1i=DataArrayInt([0,4,8,12,16,20,24,28,32,36,40,44,48,52,56,60,64,68,72,76,80,84,88,92,96,100,104,108,112,116,120,124,128,132,136,140,144,148,152,156,160,164,168,172,176,180,184,188,192]) + m1=MEDCouplingUMesh(meshName,2) ; m1.setCoords(coords) + m1.setConnectivity(c1,c1i) + mm[-1]=m1 + # + c2=DataArrayInt([0,8,8,1,1,9,9,2,3,10,10,2,0,11,11,3,4,12,12,5,5,13,13,6,7,14,14,6,4,15,15,7,0,16,16,4,1,17,17,5,3,18,18,7,2,19,19,6]) + m2=MEDCoupling1SGTUMesh(meshName,NORM_SEG2) + m2.setNodalConnectivity(c2) ; m2.setCoords(coords) + mm[-2]=m2.buildUnstructured() + # + ref0=DataArrayInt(55) ; ref0[:]=0 + mm.setFamilyFieldArr(0,ref0) + mm.setFamilyFieldArr(1,DataArrayInt([0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0])) + ref1=DataArrayInt([0,0,0,0,0,0,0,0,-6,-6,-6,-6,-6,-6,-6,-6,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]) + mm.setFamilyFieldArr(-1,ref1) + ref2=DataArrayInt([0,0,-7,-7,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]) + mm.setFamilyFieldArr(-2,ref2) + # + for f,fid in (('FAMILLE_ZERO',0),('FAM_-6_Groupe_1',-6),('FAM_-7_Groupe_2',-7),('FAM_2_Groupe_3',2)): + mm.setFamilyId(f,fid) + for grp,fams in [('Groupe_1',('FAM_-6_Groupe_1',)),('Groupe_2',('FAM_-7_Groupe_2',)),('Groupe_3',('FAM_2_Groupe_3',))]: + mm.setFamiliesOnGroup(grp,fams) + mm.write(fileName,2) + # + mm=MEDFileMesh.New(fileName) + grp=mm.getGroup(-1,"Groupe_1") + dai=grp.computeFetchedNodeIds() + dai.setName("TOTO") + mm.addGroup(1,dai) + mm.rearrangeFamilies() # <- the aim of the test + self.assertTrue(dai.isEqual(mm.getGroupArr(1,"TOTO"))) + self.assertTrue(mm.getFamilyFieldAtLevel(0).isEqual(ref0)) + self.assertTrue(mm.getFamilyFieldAtLevel(-1).isEqual(ref1)) + self.assertTrue(mm.getFamilyFieldAtLevel(-2).isEqual(ref2)) + self.assertTrue(mm.getFamilyFieldAtLevel(1).isEqual(DataArrayInt([0,0,2,0,9,9,9,9,0,0,0,0,9,9,9,9,0,0,0,0,0,9,0,0,0,0,0,0]))) + allGrps=[('Groupe_1',('FAM_-6_Groupe_1',)),('Groupe_2',('FAM_-7_Groupe_2',)),('Groupe_3',('FAM_2_Groupe_3',)),('TOTO',('Family_9',))] + allFams=[('FAMILLE_ZERO',0),('FAM_-6_Groupe_1',-6),('FAM_-7_Groupe_2',-7),('FAM_2_Groupe_3',2),('Family_9',9)] + self.assertEqual(list(mm.getGroupsNames()),[elt[0] for elt in allGrps]) + for elt,fams in allGrps: + self.assertEqual(mm.getFamiliesOnGroup(elt),fams) + self.assertEqual(list(mm.getFamiliesNames()),[elt[0] for elt in allFams]) + for elt,eltId in allFams: + self.assertEqual(mm.getFamilyId(elt),eltId) + pass + + def testNonRegrCMeshSetFieldPfl1(self): + """ Non regression test. For structured mesh, push a false partial field in MEDFileField1TS using setFieldProfile.""" + ff=MEDFileField1TS() + meshName="mesh" + mm=MEDFileCMesh() + m=MEDCouplingCMesh() ; arr=DataArrayDouble(5) ; arr.iota() + m.setCoords(arr) + m.setName(meshName) + mm.setMesh(m) + field=MEDCouplingFieldDouble(ON_CELLS) + field.setMesh(m) + field.setArray(DataArrayDouble([1.2,2.3,3.4,4.5])) + field.setName("Field") + field.checkCoherency() + pfl=DataArrayInt([0,1,2,3]) ; pfl.setName("TUTU") #<- false profile because defined on all cells ! + ff.setFieldProfile(field,mm,0,pfl) # <- bug was revealed here ! + self.assertEqual(ff.getPfls(),()) + field2=ff.getFieldOnMeshAtLevel(ON_CELLS,0,mm) + self.assertTrue(field.isEqual(field2,1e-12,1e-12)) + del ff,mm,field,field2,pfl + # same with unstructured mesh + ff=MEDFileField1TS() + meshName="mesh" + mm=MEDFileUMesh() + m=MEDCouplingCMesh() ; arr=DataArrayDouble(5) ; arr.iota() + m.setCoords(arr) + m.setName(meshName) + m=m.buildUnstructured() + mm[0]=m + field=MEDCouplingFieldDouble(ON_CELLS) + field.setMesh(m) + field.setArray(DataArrayDouble([1.2,2.3,3.4,4.5])) + field.setName("Field") + field.checkCoherency() + pfl=DataArrayInt([0,1,2,3]) ; pfl.setName("TUTU") + ff.setFieldProfile(field,mm,0,pfl) + self.assertEqual(ff.getPfls(),()) + field2=ff.getFieldOnMeshAtLevel(ON_CELLS,0,mm) + self.assertTrue(field.isEqual(field2,1e-12,1e-12)) + pass + + def testMEDFileUMeshLinearToQuadraticAndRev1(self): + meshName="mesh" + fileName="Pyfile90.med" + fileName2="Pyfile91.med" + arr=DataArrayDouble(5) ; arr.iota() + m=MEDCouplingCMesh() ; m.setCoords(arr,arr) + m=m.buildUnstructured() + d=DataArrayInt([3,7,11,15]) + m1=m[d] + m1.simplexize(0) + m2=m[d.buildComplement(m.getNumberOfCells())] + m=MEDCouplingUMesh.MergeUMeshesOnSameCoords(m1,m2) + m.changeSpaceDimension(3,0.) + arr=DataArrayDouble(3) ; arr.iota() + m1D=MEDCouplingCMesh() ; m1D.setCoords(arr) ; m1D=m1D.buildUnstructured() ; m1D.changeSpaceDimension(3,0.) + m1D.setCoords(m1D.getCoords()[:,[1,2,0]]) + delta=m.getNumberOfNodes()*(m1D.getNumberOfNodes()-1) + m3D=m.buildExtrudedMesh(m1D,0) + m3D.sortCellsInMEDFileFrmt() + m3D.setName(meshName) + m2D=m ; m2D.setCoords(m3D.getCoords()) ; m2D.shiftNodeNumbersInConn(delta) ; m2D.setName(meshName) ; m2D.checkCoherency2() + m1D=m2D.computeSkin() ; m1D.setName(meshName) + m0D=MEDCouplingUMesh.Build0DMeshFromCoords(m3D.getCoords()) ; m0D.setName(meshName) ; m0D=m0D[[2,4,10]] + # + mm=MEDFileUMesh() + mm[0]=m3D ; mm[-1]=m2D ; mm[-2]=m1D ; mm[-3]=m0D + grpEdge0=DataArrayInt([1,2,3,5]) ; grpEdge0.setName("East") + grpEdge1=DataArrayInt([0,1]) ; grpEdge1.setName("Corner1") + grpFaceSouth=DataArrayInt([0,1,8,9,10]) ; grpFaceSouth.setName("SouthFace") + grpFaceNorth=DataArrayInt([6,7,17,18,19]) ; grpFaceNorth.setName("NorthFace") + diagFace=DataArrayInt([0,1,13,15,17]) ; diagFace.setName("DiagFace") + vol1=DataArrayInt([20,21,23,24]) ; vol1.setName("vol1") + vol2=DataArrayInt([2,3,4,5,21,24]) ; vol2.setName("vol2") + mm.setGroupsAtLevel(0,[vol1,vol2]) + mm.setGroupsAtLevel(-1,[grpFaceSouth,grpFaceNorth,diagFace]) + mm.setGroupsAtLevel(-2,[grpEdge0,grpEdge1]) + # + mmOut1=mm.linearToQuadratic(0,0.) + mmOut1.write(fileName2,2) + mmOut2=mmOut1.quadraticToLinear(0.) + self.assertTrue(mm.isEqual(mmOut2,1e-12)[0]) + pass + + def testMEDFileMeshAddGroup1(self): + m=MEDCouplingCMesh() + arrX=DataArrayDouble(9) ; arrX.iota() + arrY=DataArrayDouble(4) ; arrY.iota() + m.setCoords(arrX,arrY) + m.setName("mesh") + mm=MEDFileCMesh() + mm.setMesh(m) + grp0=DataArrayInt([3,5,6,21,22]) ; grp0.setName("grp0") + mm.addGroup(0,grp0) + grp1=DataArrayInt([3,4,5,8,18,19,22]) ; grp1.setName("grp1") + mm.addGroup(0,grp1) + grp2=DataArrayInt([0,1,2,10,11]) ; grp2.setName("grp2") + mm.addGroup(0,grp2) + grp3=DataArrayInt([23]) ; grp3.setName("grp3") + mm.addGroup(0,grp3) + for grp in [grp0,grp1,grp2,grp3]: + self.assertTrue(mm.getGroupArr(0,grp.getName()).isEqual(grp)) + self.assertEqual(mm.getGroupsNames(),('grp0','grp1','grp2','grp3')) + delta=12 + for grp in [grp0,grp1,grp2,grp3]: + grpNode=grp.deepCpy() ; grpNode+=delta ; grpNode.setName("%s_node"%grp.getName()) + mm.addGroup(1,grpNode) + self.assertEqual(mm.getGroupsNames(),('grp0','grp0_node','grp1','grp1_node','grp2','grp2_node','grp3','grp3_node')) + for grp in [grp0,grp1,grp2,grp3]: + self.assertTrue(mm.getGroupArr(0,grp.getName()).isEqual(grp)) + for grp in [grp0,grp1,grp2,grp3]: + grpExp=grp+delta ; grpExp.setName("%s_node"%grp.getName()) + self.assertTrue(mm.getGroupArr(1,"%s_node"%grp.getName()).isEqual(grpExp)) + mm.normalizeFamIdsMEDFile() + for grp in [grp0,grp1,grp2,grp3]: + self.assertTrue(mm.getGroupArr(0,grp.getName()).isEqual(grp)) + for grp in [grp0,grp1,grp2,grp3]: + grpExp=grp+delta ; grpExp.setName("%s_node"%grp.getName()) + self.assertTrue(mm.getGroupArr(1,"%s_node"%grp.getName()).isEqual(grpExp)) + pass + + pass + def testMEDFileJoint1(self): + fileName="Pyfile92.med" + coo=DataArrayDouble([(0,0,0),(1,0,0),(2,0,0)]) + coo.setInfoOnComponents(["x [cm]","y [cm]","z [cm]"]) + mm=MEDFileUMesh() + mm.setCoords(coo) + mm.setName("maa1") + mm.setDescription("un maillage") + mm.write(fileName,2) + node_correspond=MEDFileJointCorrespondence(DataArrayInt([1,2,3,4,5,6,7,8])) + cell_correspond=MEDFileJointCorrespondence(DataArrayInt([9,10,11,12]),NORM_TRI3,NORM_TRI3) + one_step_joint=MEDFileJointOneStep() + one_step_joint.pushCorrespondence(cell_correspond) + one_step_joint.pushCorrespondence(node_correspond) + one_joint=MEDFileJoint() + one_joint.pushStep(one_step_joint) + one_joint.setLocalMeshName("maa1") + one_joint.setRemoteMeshName("maa1") + one_joint.setDescription("joint_description") + one_joint.setJointName("joint_1") + one_joint.setDomainNumber(1) + self.assertEqual( one_joint.getLocalMeshName(), "maa1") + self.assertEqual( one_joint.getRemoteMeshName(), "maa1") + self.assertEqual( one_joint.getDescription(), "joint_description") + self.assertEqual( one_joint.getJointName(), "joint_1") + self.assertEqual( one_joint.getDomainNumber(), 1) + joints=MEDFileJoints() + joints.pushJoint(one_joint); + joints.write(fileName,0) + # read back + jointsR=MEDFileJoints(fileName,mm.getName()) + self.assertEqual( jointsR.getNumberOfJoints(), 1 ) + jR = jointsR.getJointAtPos(0) + self.assertTrue( jR.isEqual( one_joint )) + self.assertRaises( InterpKernelException, jointsR.getJointAtPos,1) + self.assertRaises( InterpKernelException, jointsR.destroyJointAtPos,1) + jointsR.destroyJointAtPos(0) + + pass + def testMEDFileJoint2(self): + fileNameWr="Pyfile93.med" + coo=DataArrayDouble([(0,0,0),(1,0,0),(2,0,0)]) + coo.setInfoOnComponents(["x [cm]","y [cm]","z [cm]"]) + mm=MEDFileUMesh() + mm.setCoords(coo) + mm.setName("maa1") + mm.setDescription("un maillage") + node_correspond=MEDFileJointCorrespondence(DataArrayInt([13,14,15,16])) + cell_correspond=MEDFileJointCorrespondence(DataArrayInt([17,18]),NORM_TETRA4,NORM_PENTA6) + one_step_joint=MEDFileJointOneStep() + two_step_joint=MEDFileJointOneStep() + one_joint=MEDFileJoint() + two_joint=MEDFileJoint() + one_step_joint.pushCorrespondence(node_correspond) + one_joint.pushStep(one_step_joint) + two_step_joint.pushCorrespondence(cell_correspond) + two_step_joint.pushCorrespondence(node_correspond) + two_joint.pushStep(two_step_joint) + one_joint.setLocalMeshName("maa1") + one_joint.setRemoteMeshName("maa1") + one_joint.setDescription("joint_description_1") + one_joint.setJointName("joint_1") + one_joint.setDomainNumber(1) + two_joint.setLocalMeshName("maa1") + two_joint.setRemoteMeshName("maa1") + two_joint.setDescription("joint_description_2") + two_joint.setJointName("joint_2") + two_joint.setDomainNumber(2) + joints=MEDFileJoints() + joints.pushJoint(one_joint) + joints.pushJoint(two_joint) + mm.setJoints( joints ) + mm.write(fileNameWr,2) + # + mm=MEDFileMesh.New(fileNameWr) + self.assertEqual( mm.getNumberOfJoints(), 2) + jointsR = mm.getJoints(); + self.assertEqual( jointsR.getMeshName(), mm.getName() ) + self.assertEqual( len( jointsR ), 2 ) + jointR1 = jointsR[0] + jointR2 = jointsR[1] + self.assertFalse( jointR1 is None ) + self.assertFalse( jointR2 is None ) + self.assertTrue( jointR1.isEqual( one_joint )) + self.assertTrue( jointR2.isEqual( two_joint )) + pass + + def testMEDFileJoint1(self): + node_correspond=MEDFileJointCorrespondence(DataArrayInt([1,2,3,4,5,6,7,8])) + cell_correspond=MEDFileJointCorrespondence(DataArrayInt([9,10,11,12]),NORM_TRI3,NORM_TRI3) + cell_correspon2=MEDFileJointCorrespondence(DataArrayInt([9,10,11]),NORM_TRI3,NORM_TRI3) + cell_correspon3=MEDFileJointCorrespondence(DataArrayInt([9,10,11,12]),NORM_TRI3,NORM_QUAD4) + joint1st_1=MEDFileJointOneStep() + joint1st_1.pushCorrespondence(cell_correspond) + joint1st_1.pushCorrespondence(node_correspond) + joint1st_2=MEDFileJointOneStep() + joint1st_2.pushCorrespondence(cell_correspond) + joint1st_2.pushCorrespondence(node_correspond) + joint1st_3=MEDFileJointOneStep() + joint1st_3.pushCorrespondence(node_correspond) + joint1st_3.pushCorrespondence(cell_correspond) + joint1st_4=MEDFileJointOneStep() + joint1st_4.pushCorrespondence(cell_correspond) + joint1st_5=MEDFileJointOneStep() + joint1st_5.pushCorrespondence(cell_correspon2) + joint1st_6=MEDFileJointOneStep() + joint1st_6.pushCorrespondence(cell_correspon3) + self.assertTrue( joint1st_1.isEqual( joint1st_2 )) + self.assertTrue( joint1st_1.isEqual( joint1st_3 )) + self.assertFalse( joint1st_1.isEqual( joint1st_4 )) + self.assertFalse( joint1st_4.isEqual( joint1st_5 )) + self.assertFalse( joint1st_4.isEqual( joint1st_6 )) + one_joint=MEDFileJoint() + one_joint.pushStep(joint1st_1) + one_joint.setLocalMeshName("maa1") + one_joint.setRemoteMeshName("maa2") + one_joint.setDescription("joint_description") + one_joint.setJointName("joint_1") + one_joint.setDomainNumber(1) + self.assertEqual( "maa1", one_joint.getLocalMeshName()) + self.assertEqual( "maa2", one_joint.getRemoteMeshName()) + self.assertEqual( "joint_description", one_joint.getDescription()) + self.assertEqual( 1, one_joint.getDomainNumber()) + self.assertEqual( "joint_1", one_joint.getJointName()) + pass + + @unittest.skipUnless('linux'==platform.system().lower(),"stderr redirection not ported on Windows ?") + def testMEDFileSafeCall0(self): + """ EDF11242 : check status of MED file calls to detect problems immediately. Sorry this test generates awful messages !""" + fname="Pyfile94.med" + errfname="Pyfile94.err" + class StdOutRedirect(object): + def __init__(self,fileName): + import os,sys + sys.stderr.flush() + self.stdoutOld=os.dup(2) + self.fdOfSinkFile=os.open(fileName,os.O_CREAT | os.O_RDWR) + fd2=os.dup2(self.fdOfSinkFile,2) + self.origPyVal=sys.stderr + class FlushFile(object): + def __init__(self,f): + self.f=f + def write(self,st): + self.f.write(st) + self.f.flush() + def flush(self): + return self.f.flush() + def isatty(self): + return self.f.isatty() + sys.stderr=FlushFile(os.fdopen(self.fdOfSinkFile,"w")) + def __del__(self): + import os,sys + sys.stderr=self.origPyVal + #os.fsync(self.fdOfSinkFile) + os.fsync(2) + os.dup2(self.stdoutOld,2) + os.close(self.stdoutOld) + import os + # first clean file if needed + if os.path.exists(fname): + os.remove(fname) + pass + # second : build a file from scratch + m=MEDCouplingCMesh() + arr=DataArrayDouble(11) ; arr.iota() + m.setCoords(arr,arr) + mm=MEDFileCMesh() + mm.setMesh(m) + mm.setName("mesh") + mm.write(fname,2) + # third : change permissions to remove write access on created file + os.chmod(fname,0444) + # four : try to append data on file -> check that it raises Exception + f=MEDCouplingFieldDouble(ON_CELLS) + f.setName("field") + f.setMesh(m) + f.setArray(DataArrayDouble(100)) + f.getArray()[:]=100. + f.checkCoherency() + f1ts=MEDFileField1TS() + f1ts.setFieldNoProfileSBT(f) + # redirect stderr + tmp=StdOutRedirect(errfname) + self.assertRaises(InterpKernelException,f1ts.write,fname,0) # it should raise ! + del tmp + # + if os.path.exists(errfname): + os.remove(errfname) + # + pass + + def testUnivStatus1(self): + """ Non regression test to check the effectiveness of univ write status.""" + fname="Pyfile95.med" + arr=DataArrayDouble(10) ; arr.iota() + m=MEDCouplingCMesh() ; m.setCoords(arr,arr) ; m.setName("mesh") + mm=MEDFileCMesh() ; mm.setMesh(m) + mm.setUnivNameWrStatus(False) # test is here + mm.write(fname,2) + mm=MEDFileCMesh(fname) + self.assertEqual(mm.getUnivName(),"") + mm.setUnivNameWrStatus(True) + mm.write(fname,2) + mm=MEDFileCMesh(fname) + self.assertTrue(mm.getUnivName()!="") + pass + + def testEmptyMesh(self): + """ MEDLoader should be able to consistently write and read an empty mesh (coords array + with 0 tuples """ + fname = "Pyfile96.med" + m = MEDCouplingUMesh('toto', 2) + m.setCoords(DataArrayDouble([], 0, 2)) + m.setConnectivity(DataArrayInt([]), DataArrayInt([0])) + mfu = MEDFileUMesh() + mfu.setMeshAtLevel(0, m) + mfu.write(fname, 2) + mfu2 = MEDFileUMesh(fname) + self.assertEqual('toto', mfu2.getName()) + lvl = mfu2.getNonEmptyLevels() + self.assertEqual((), lvl) + + @unittest.skipUnless(MEDCouplingHasNumPyBindings(),"requires numpy") + def testMEDFileUMeshPickeling2(self): + """ Check that pickalization can be performed on a unpickalized instance. Non regression test.""" + name="Mesh_1" + grpName1="HAUT" + grpName2="BASE" + hauteur=1. + nbOfNodesPerAxis=3 + arr=DataArrayDouble(nbOfNodesPerAxis) ; arr.iota() ; arr/=(nbOfNodesPerAxis-1) ; arr*=hauteur + m=MEDCouplingCMesh() ; m.setCoords(arr,arr,arr) ; m=m.buildUnstructured() ; m.setName(name) + mesh=MEDFileUMesh() ; mesh[0]=m + m1=m.computeSkin() ; mesh[-1]=m1 + # + bary1=m1.getBarycenterAndOwner()[:,2] + grp1=bary1.getIdsInRange(hauteur-1e-12,hauteur+1e-12) ; grp1.setName(grpName1) + grp2=bary1.getIdsInRange(0.-1e-12,0.+1e-12) ; grp2.setName(grpName2) + mesh.setGroupsAtLevel(-1,[grp1,grp2]) + + import cPickle + st=cPickle.dumps(mesh,2) + mm=cPickle.loads(st) + st2=cPickle.dumps(mm,2) + mm2=cPickle.loads(st2) + self.assertTrue(mesh.isEqual(mm2,1e-12)[0]) + pass + + pass + +if __name__ == "__main__": + unittest.main() diff --git a/src/medtool/src/MEDLoader/Swig/MEDLoaderTest4.py b/src/medtool/src/MEDLoader/Swig/MEDLoaderTest4.py new file mode 100644 index 000000000..706b63b09 --- /dev/null +++ b/src/medtool/src/MEDLoader/Swig/MEDLoaderTest4.py @@ -0,0 +1,5120 @@ +# -*- coding: iso-8859-1 -*- +# Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 +# 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) + +from MEDLoader import * +import unittest +from math import pi,e,sqrt + +class MEDLoaderTest4(unittest.TestCase): + """ + Test series to emulate the future MEDReader plugin for PARAVIS. + """ + def test1(self): + """ + This test is the most simple one. One time serie of one field with only cell fields with no profiles. + The only "difficulty" is that the cell field is lying on different levels (2D and 1D) to maximize the compatibility with ParaVIS. + """ + fname="ForMEDReader1.med" + # building a mesh containing 4 tri3 + 5 quad4 + tri=MEDCouplingUMesh("tri",2) + tri.allocateCells() ; tri.insertNextCell(NORM_TRI3,[0,1,2]) + tri.setCoords(DataArrayDouble([(0.,0.),(0.,1.),(1.,0.)])) + tris=[tri.deepCpy() for i in xrange(4)] + for i,elt in enumerate(tris): elt.translate([i,0]) + tris=MEDCouplingUMesh.MergeUMeshes(tris) + quad=MEDCouplingUMesh("quad",2) + quad.allocateCells() ; quad.insertNextCell(NORM_QUAD4,[0,1,2,3]) + quad.setCoords(DataArrayDouble([(0.,0.),(0.,1.),(1.,1.),(1.,0.)])) + quads=[quad.deepCpy() for i in xrange(5)] + for i,elt in enumerate(quads): elt.translate([5+i,0]) + quads=MEDCouplingUMesh.MergeUMeshes(quads) + m=MEDCouplingUMesh.MergeUMeshes(tris,quads) + m.setName("mesh") ; m.getCoords().setInfoOnComponents(["XX [m]","YYY [km]"]) + m1=m.buildDescendingConnectivity()[0] + mm=MEDFileUMesh() ; mm.setMeshes([m,m1]) + fam=DataArrayInt(9) ; fam.iota(0) ; mm.setFamilyFieldArr(0,fam) + fam=DataArrayInt(32) ; fam.iota(20) ; mm.setFamilyFieldArr(-1,fam) ; del fam + num=DataArrayInt(9) ; num.iota(100) ; mm.setRenumFieldArr(0,num) + num=DataArrayInt(32) ; num.iota(120) ; mm.setRenumFieldArr(-1,num) ; del num + # + fieldName="zeField" + fs=MEDFileFieldMultiTS() + ##### Time step 0 + i=0 + f=MEDFileField1TS() + fCell0=MEDCouplingFieldDouble(ON_CELLS) ; fCell0.setTime(float(i),i,0) + fCell0.setName(fieldName) ; fCell0.setMesh(m) + arr=DataArrayDouble(2*m.getNumberOfCells()) ; arr.iota(100) ; arr.rearrange(2) + fCell0.setArray(arr) ; arr.setInfoOnComponents(["Comp1 [m]","Com2 [s^2]"]) + fCell0.checkCoherency() + f.setFieldNoProfileSBT(fCell0) + fCell1=MEDCouplingFieldDouble(ON_CELLS) ; fCell1.setTime(float(i),i,0) + fCell1.setName(fieldName) ; fCell1.setMesh(m1) + arr=DataArrayDouble(2*m1.getNumberOfCells()) ; arr.iota(200) ; arr.rearrange(2) + fCell1.setArray(arr) ; arr.setInfoOnComponents(["Comp1 [m]","Com2 [s^2]"]) + fCell1.checkCoherency() + f.setFieldNoProfileSBT(fCell1) + fs.pushBackTimeStep(f) + ##### Time step 1 + i=1 + f=MEDFileField1TS() + fCell0=MEDCouplingFieldDouble(ON_CELLS) ; fCell0.setTime(float(i),i,0) + fCell0.setName(fieldName) ; fCell0.setMesh(m) + arr=DataArrayDouble(2*m.getNumberOfCells()) ; arr.iota(1100) ; arr.rearrange(2) + fCell0.setArray(arr) ; arr.setInfoOnComponents(["Comp1 [m]","Com2 [s^2]"]) + fCell0.checkCoherency() + f.setFieldNoProfileSBT(fCell0) + # + fCell1=MEDCouplingFieldDouble(ON_CELLS) ; fCell1.setTime(float(i),i,0) + fCell1.setName(fieldName) ; fCell1.setMesh(m1) + arr=DataArrayDouble(2*m1.getNumberOfCells()) ; arr.iota(1200) ; arr.rearrange(2) + fCell1.setArray(arr) ; arr.setInfoOnComponents(["Comp1 [m]","Com2 [s^2]"]) + fCell1.checkCoherency() + f.setFieldNoProfileSBT(fCell1) + fs.pushBackTimeStep(f) + ##### Time step 2 + i=2 + f=MEDFileField1TS() + fCell0=MEDCouplingFieldDouble(ON_CELLS) ; fCell0.setTime(float(i),i,0) + fCell0.setName(fieldName) ; fCell0.setMesh(m) + arr=DataArrayDouble(2*m.getNumberOfCells()) ; arr.iota(2100) ; arr.rearrange(2) + fCell0.setArray(arr) ; arr.setInfoOnComponents(["Comp1 [m]","Com2 [s^2]"]) + fCell0.checkCoherency() + f.setFieldNoProfileSBT(fCell0) + # + fCell1=MEDCouplingFieldDouble(ON_CELLS) ; fCell1.setTime(float(i),i,0) + fCell1.setName(fieldName) ; fCell1.setMesh(m1) + arr=DataArrayDouble(2*m1.getNumberOfCells()) ; arr.iota(2200) ; arr.rearrange(2) + fCell1.setArray(arr) ; arr.setInfoOnComponents(["Comp1 [m]","Com2 [s^2]"]) + fCell1.checkCoherency() + f.setFieldNoProfileSBT(fCell1) + fs.pushBackTimeStep(f) + ##### Time step 3 + i=3 + f=MEDFileField1TS() + # + fCell0=MEDCouplingFieldDouble(ON_CELLS) ; fCell0.setTime(float(i),i,0) + fCell0.setName(fieldName) ; fCell0.setMesh(m) + arr=DataArrayDouble(2*m.getNumberOfCells()) ; arr.iota(3100) ; arr.rearrange(2) + fCell0.setArray(arr) ; arr.setInfoOnComponents(["Comp1 [m]","Com2 [s^2]"]) + fCell0.checkCoherency() + f.setFieldNoProfileSBT(fCell0) + # + fCell1=MEDCouplingFieldDouble(ON_CELLS) ; fCell1.setTime(float(i),i,0) + fCell1.setName(fieldName) ; fCell1.setMesh(m1) + arr=DataArrayDouble(2*m1.getNumberOfCells()) ; arr.iota(3200) ; arr.rearrange(2) + fCell1.setArray(arr) ; arr.setInfoOnComponents(["Comp1 [m]","Com2 [s^2]"]) + fCell1.checkCoherency() + f.setFieldNoProfileSBT(fCell1) + # + fs.pushBackTimeStep(f) + ##### Time step 4 + i=4 + f=MEDFileField1TS() + # + fCell0=MEDCouplingFieldDouble(ON_CELLS) ; fCell0.setTime(float(i),i,0) + fCell0.setName(fieldName) ; fCell0.setMesh(m) + arr=DataArrayDouble(2*m.getNumberOfCells()) ; arr.iota(4100) ; arr.rearrange(2) + fCell0.setArray(arr) ; arr.setInfoOnComponents(["Comp1 [m]","Com2 [s^2]"]) + fCell0.checkCoherency() + f.setFieldNoProfileSBT(fCell0) + # + fCell1=MEDCouplingFieldDouble(ON_CELLS) ; fCell1.setTime(float(i),i,0) + fCell1.setName(fieldName) ; fCell1.setMesh(m1) + arr=DataArrayDouble(2*m1.getNumberOfCells()) ; arr.iota(4200) ; arr.rearrange(2) + fCell1.setArray(arr) ; arr.setInfoOnComponents(["Comp1 [m]","Com2 [s^2]"]) + fCell1.checkCoherency() + f.setFieldNoProfileSBT(fCell1) + fs.pushBackTimeStep(f) + mm.write(fname,2) + fs.write(fname,0) + a0Exp=mm.getCoords().deepCpy() + del m,m1,mm,fs,f,fCell0,fCell1 + ########## GO for reading in MEDReader, by not loading all. Mesh is fully loaded but not fields values + ms=MEDFileMeshes(fname) + fields=MEDFileFields(fname,False) # False is important to not read the values + fields.removeFieldsWithoutAnyTimeStep() + refMem=fields.getHeapMemorySize() + fields_per_mesh=[fields.partOfThisLyingOnSpecifiedMeshName(meshName) for meshName in ms.getMeshesNames()] + allFMTSLeavesToDisplay=[] + for fields in fields_per_mesh: + allFMTSLeavesToDisplay2=[] + for fmts in fields: + tmp=fmts.splitDiscretizations() + for itmp in tmp: + self.assertTrue(not itmp.presenceOfMultiDiscPerGeoType()) + pass + allFMTSLeavesToDisplay2+=tmp + pass + allFMTSLeavesToDisplay.append(allFMTSLeavesToDisplay2) + pass + self.assertEqual(len(allFMTSLeavesToDisplay),1) + self.assertEqual(len(allFMTSLeavesToDisplay[0]),1) + for fmts in allFMTSLeavesToDisplay[0]: + self.assertEqual(fmts.getTimeSteps(),[(0,0,0.),(1,0,1.),(2,0,2.),(3,0,3.),(4,0,4.)]) # All discretizations have the same time series + pass + allFMTSLeavesPerTimeSeries=MEDFileAnyTypeFieldMultiTS.SplitIntoCommonTimeSeries(sum(allFMTSLeavesToDisplay,[])) + self.assertEqual(len(allFMTSLeavesPerTimeSeries),1) + self.assertEqual(len(allFMTSLeavesPerTimeSeries[0]),1) + allFMTSLeavesPerCommonSupport=MEDFileAnyTypeFieldMultiTS.SplitPerCommonSupport(allFMTSLeavesPerTimeSeries[0],ms[ms.getMeshesNames()[0]]) + # + mst=MEDFileMeshStruct.New(ms[0]) + fcscp=allFMTSLeavesPerCommonSupport[0][1] + mml=fcscp.buildFromScratchDataSetSupport(0,fields) + mml2=mml.prepare() + self.assertTrue(isinstance(mml2,MEDUMeshMultiLev)) + for i in xrange(1,5): + self.assertTrue(fcscp.isDataSetSupportEqualToThePreviousOne(i,fields)) + pass + ncc,a0,a1,a2,a3,a4,a5=mml2.buildVTUArrays() + self.assertTrue(not ncc) + self.assertTrue(a0.isEqual(a0Exp.changeNbOfComponents(3,0.),1e-12)) + self.assertTrue(a1.isEqual(DataArrayByte([3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,5,5,5,5,9,9,9,9,9]))) + self.assertTrue(a2.isEqual(DataArrayInt([0,3,6,9,12,15,18,21,24,27,30,33,36,39,42,45,48,51,54,57,60,63,66,69,72,75,78,81,84,87,90,93,96,100,104,108,112,117,122,127,132]))) + self.assertTrue(a3.isEqual(DataArrayInt([2,0,1,2,1,2,2,2,0,2,3,4,2,4,5,2,5,3,2,6,7,2,7,8,2,8,6,2,9,10,2,10,11,2,11,9,2,12,13,2,13,14,2,14,15,2,15,12,2,16,17,2,17,18,2,18,19,2,19,16,2,20,21,2,21,22,2,22,23,2,23,20,2,24,25,2,25,26,2,26,27,2,27,24,2,28,29,2,29,30,2,30,31,2,31,28,3,0,1,2,3,3,4,5,3,6,7,8,3,9,10,11,4,12,13,14,15,4,16,17,18,19,4,20,21,22,23,4,24,25,26,27,4,28,29,30,31]))) + self.assertTrue(a4 is None) + self.assertTrue(a5 is None) + a6,a7=mml2.retrieveFamilyIdsOnCells() + self.assertTrue(a6.isEqual(DataArrayInt([20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,0,1,2,3,4,5,6,7,8]))) + self.assertTrue(not a7) + a8,a9=mml2.retrieveNumberIdsOnCells() + self.assertTrue(a8.isEqual(DataArrayInt([120,121,122,123,124,125,126,127,128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143,144,145,146,147,148,149,150,151,100,101,102,103,104,105,106,107,108]))) + self.assertTrue(not a9) + for i in xrange(5): + fsst=MEDFileField1TSStructItem.BuildItemFrom(fields[0][i],mst) + fields[0][i].loadArraysIfNecessary() + tmpMem=fields.getHeapMemorySize() + self.assertTrue(tmpMem-refMem>=41*2*8) + refMem=tmpMem + v=mml.buildDataArray(fsst,fields,fields[0][i].getUndergroundDataArray()) + self.assertEqual(v.getHiddenCppPointer(),fields[0][i].getUndergroundDataArray().getHiddenCppPointer()) + vExp=DataArrayDouble([200.,201.,202.,203.,204.,205.,206.,207.,208.,209.,210.,211.,212.,213.,214.,215.,216.,217.,218.,219.,220.,221.,222.,223.,224.,225.,226.,227.,228.,229.,230.,231.,232.,233.,234.,235.,236.,237.,238.,239.,240.,241.,242.,243.,244.,245.,246.,247.,248.,249.,250.,251.,252.,253.,254.,255.,256.,257.,258.,259.,260.,261.,262.,263.,100.,101.,102.,103.,104.,105.,106.,107.,108.,109.,110.,111.,112.,113.,114.,115.,116.,117.],41,2) ; vExp.setInfoOnComponents(['Comp1 [m]','Com2 [s^2]']) ; vExp+=i*1000 + self.assertTrue(v.isEqual(vExp,1e-12)) + pass + pass + + def test2(self): + """ + One time serie of one field with cell and node discretization in the same field with no profiles. + Here as there is no profile only one VTK support is requested. + """ + fname="ForMEDReader2.med" + # building a mesh containing 4 tri3 + 5 quad4 + tri=MEDCouplingUMesh("tri",2) + tri.allocateCells() ; tri.insertNextCell(NORM_TRI3,[0,1,2]) + tri.setCoords(DataArrayDouble([(0.,0.),(0.,1.),(1.,0.)])) + tris=[tri.deepCpy() for i in xrange(4)] + for i,elt in enumerate(tris): elt.translate([i,0]) + tris=MEDCouplingUMesh.MergeUMeshes(tris) + quad=MEDCouplingUMesh("quad",2) + quad.allocateCells() ; quad.insertNextCell(NORM_QUAD4,[0,1,2,3]) + quad.setCoords(DataArrayDouble([(0.,0.),(0.,1.),(1.,1.),(1.,0.)])) + quads=[quad.deepCpy() for i in xrange(5)] + for i,elt in enumerate(quads): elt.translate([5+i,0]) + quads=MEDCouplingUMesh.MergeUMeshes(quads) + m=MEDCouplingUMesh.MergeUMeshes(tris,quads) + m.setName("mesh") ; m.getCoords().setInfoOnComponents(["XX [m]","YYY [km]"]) + m1=m.buildDescendingConnectivity()[0] + mm=MEDFileUMesh() ; mm.setMeshes([m,m1]) + # + fieldName="zeField" + fs=MEDFileFieldMultiTS() + ##### Time step 0 + i=0 + f=MEDFileField1TS() + fCell0=MEDCouplingFieldDouble(ON_CELLS) ; fCell0.setTime(float(i),i,0) + fCell0.setName(fieldName) ; fCell0.setMesh(m) + arr=DataArrayDouble(2*m.getNumberOfCells()) ; arr.iota(100) ; arr.rearrange(2) + fCell0.setArray(arr) ; arr.setInfoOnComponents(["Comp1 [m]","Com2 [s^2]"]) + fCell0.checkCoherency() + f.setFieldNoProfileSBT(fCell0) + fCell1=MEDCouplingFieldDouble(ON_CELLS) ; fCell1.setTime(float(i),i,0) + fCell1.setName(fieldName) ; fCell1.setMesh(m1) + arr=DataArrayDouble(2*m1.getNumberOfCells()) ; arr.iota(200) ; arr.rearrange(2) + fCell1.setArray(arr) ; arr.setInfoOnComponents(["Comp1 [m]","Com2 [s^2]"]) + fCell1.checkCoherency() + f.setFieldNoProfileSBT(fCell1) + # + fNode=MEDCouplingFieldDouble(ON_NODES) ; fNode.setTime(float(i),i,0) + fNode.setName(fieldName) ; fNode.setMesh(m1) + arr=DataArrayDouble(2*m.getNumberOfNodes()) ; arr.iota(300) ; arr.rearrange(2) + fNode.setArray(arr) ; arr.setInfoOnComponents(["Comp1 [m]","Com2 [s^2]"]) + fNode.checkCoherency() + f.setFieldNoProfileSBT(fNode) + fs.pushBackTimeStep(f) + ##### Time step 1 + i=1 + f=MEDFileField1TS() + fCell0=MEDCouplingFieldDouble(ON_CELLS) ; fCell0.setTime(float(i),i,0) + fCell0.setName(fieldName) ; fCell0.setMesh(m) + arr=DataArrayDouble(2*m.getNumberOfCells()) ; arr.iota(1100) ; arr.rearrange(2) + fCell0.setArray(arr) ; arr.setInfoOnComponents(["Comp1 [m]","Com2 [s^2]"]) + fCell0.checkCoherency() + f.setFieldNoProfileSBT(fCell0) + # + fCell1=MEDCouplingFieldDouble(ON_CELLS) ; fCell1.setTime(float(i),i,0) + fCell1.setName(fieldName) ; fCell1.setMesh(m1) + arr=DataArrayDouble(2*m1.getNumberOfCells()) ; arr.iota(1200) ; arr.rearrange(2) + fCell1.setArray(arr) ; arr.setInfoOnComponents(["Comp1 [m]","Com2 [s^2]"]) + fCell1.checkCoherency() + f.setFieldNoProfileSBT(fCell1) + # + fNode=MEDCouplingFieldDouble(ON_NODES) ; fNode.setTime(float(i),i,0) + fNode.setName(fieldName) ; fNode.setMesh(m1) + arr=DataArrayDouble(2*m.getNumberOfNodes()) ; arr.iota(1300) ; arr.rearrange(2) + fNode.setArray(arr) ; arr.setInfoOnComponents(["Comp1 [m]","Com2 [s^2]"]) + fNode.checkCoherency() + f.setFieldNoProfileSBT(fNode) + fs.pushBackTimeStep(f) + ##### Time step 2 + i=2 + f=MEDFileField1TS() + fNode=MEDCouplingFieldDouble(ON_NODES) ; fNode.setTime(float(i),i,0) + fNode.setName(fieldName) ; fNode.setMesh(m1) + arr=DataArrayDouble(2*m.getNumberOfNodes()) ; arr.iota(2300) ; arr.rearrange(2) + fNode.setArray(arr) ; arr.setInfoOnComponents(["Comp1 [m]","Com2 [s^2]"]) + fNode.checkCoherency() + f.setFieldNoProfileSBT(fNode) + # + fCell0=MEDCouplingFieldDouble(ON_CELLS) ; fCell0.setTime(float(i),i,0) + fCell0.setName(fieldName) ; fCell0.setMesh(m) + arr=DataArrayDouble(2*m.getNumberOfCells()) ; arr.iota(2100) ; arr.rearrange(2) + fCell0.setArray(arr) ; arr.setInfoOnComponents(["Comp1 [m]","Com2 [s^2]"]) + fCell0.checkCoherency() + f.setFieldNoProfileSBT(fCell0) + # + fCell1=MEDCouplingFieldDouble(ON_CELLS) ; fCell1.setTime(float(i),i,0) + fCell1.setName(fieldName) ; fCell1.setMesh(m1) + arr=DataArrayDouble(2*m1.getNumberOfCells()) ; arr.iota(2200) ; arr.rearrange(2) + fCell1.setArray(arr) ; arr.setInfoOnComponents(["Comp1 [m]","Com2 [s^2]"]) + fCell1.checkCoherency() + f.setFieldNoProfileSBT(fCell1) + fs.pushBackTimeStep(f) + ##### Time step 3 + i=3 + f=MEDFileField1TS() + # + fCell0=MEDCouplingFieldDouble(ON_CELLS) ; fCell0.setTime(float(i),i,0) + fCell0.setName(fieldName) ; fCell0.setMesh(m) + arr=DataArrayDouble(2*m.getNumberOfCells()) ; arr.iota(3100) ; arr.rearrange(2) + fCell0.setArray(arr) ; arr.setInfoOnComponents(["Comp1 [m]","Com2 [s^2]"]) + fCell0.checkCoherency() + f.setFieldNoProfileSBT(fCell0) + # + fCell1=MEDCouplingFieldDouble(ON_CELLS) ; fCell1.setTime(float(i),i,0) + fCell1.setName(fieldName) ; fCell1.setMesh(m1) + arr=DataArrayDouble(2*m1.getNumberOfCells()) ; arr.iota(3200) ; arr.rearrange(2) + fCell1.setArray(arr) ; arr.setInfoOnComponents(["Comp1 [m]","Com2 [s^2]"]) + fCell1.checkCoherency() + f.setFieldNoProfileSBT(fCell1) + # + fNode=MEDCouplingFieldDouble(ON_NODES) ; fNode.setTime(float(i),i,0) + fNode.setName(fieldName) ; fNode.setMesh(m1) + arr=DataArrayDouble(2*m.getNumberOfNodes()) ; arr.iota(3300) ; arr.rearrange(2) + fNode.setArray(arr) ; arr.setInfoOnComponents(["Comp1 [m]","Com2 [s^2]"]) + fNode.checkCoherency() + f.setFieldNoProfileSBT(fNode) + # + fs.pushBackTimeStep(f) + ##### Time step 4 + i=4 + f=MEDFileField1TS() + # + fCell0=MEDCouplingFieldDouble(ON_CELLS) ; fCell0.setTime(float(i),i,0) + fCell0.setName(fieldName) ; fCell0.setMesh(m) + arr=DataArrayDouble(2*m.getNumberOfCells()) ; arr.iota(4100) ; arr.rearrange(2) + fCell0.setArray(arr) ; arr.setInfoOnComponents(["Comp1 [m]","Com2 [s^2]"]) + fCell0.checkCoherency() + f.setFieldNoProfileSBT(fCell0) + # + fCell1=MEDCouplingFieldDouble(ON_CELLS) ; fCell1.setTime(float(i),i,0) + fCell1.setName(fieldName) ; fCell1.setMesh(m1) + arr=DataArrayDouble(2*m1.getNumberOfCells()) ; arr.iota(4200) ; arr.rearrange(2) + fCell1.setArray(arr) ; arr.setInfoOnComponents(["Comp1 [m]","Com2 [s^2]"]) + fCell1.checkCoherency() + f.setFieldNoProfileSBT(fCell1) + # + fNode=MEDCouplingFieldDouble(ON_NODES) ; fNode.setTime(float(i),i,0) + fNode.setName(fieldName) ; fNode.setMesh(m1) + arr=DataArrayDouble(2*m.getNumberOfNodes()) ; arr.iota(4300) ; arr.rearrange(2) + fNode.setArray(arr) ; arr.setInfoOnComponents(["Comp1 [m]","Com2 [s^2]"]) + fNode.checkCoherency() + f.setFieldNoProfileSBT(fNode) + # + fs.pushBackTimeStep(f) + mm.write(fname,2) + fs.write(fname,0) + a0Exp=mm.getCoords().deepCpy() + del m,m1,mm,fs,f,fCell0,fCell1 + ########## GO for reading in MEDReader, by not loading all. Mesh is fully loaded but not fields values + ms=MEDFileMeshes(fname) + fields=MEDFileFields(fname,False) + fields.removeFieldsWithoutAnyTimeStep() + fields_per_mesh=[fields.partOfThisLyingOnSpecifiedMeshName(meshName) for meshName in ms.getMeshesNames()] + allFMTSLeavesToDisplay=[] + for fields in fields_per_mesh: + allFMTSLeavesToDisplay2=[] + for fmts in fields: + tmp=fmts.splitDiscretizations() + for itmp in tmp: + self.assertTrue(not itmp.presenceOfMultiDiscPerGeoType()) + pass + allFMTSLeavesToDisplay2+=tmp + pass + allFMTSLeavesToDisplay.append(allFMTSLeavesToDisplay2) + pass + self.assertEqual(len(allFMTSLeavesToDisplay),1) + self.assertEqual(len(allFMTSLeavesToDisplay[0]),2) + for fmts in allFMTSLeavesToDisplay[0]: + self.assertEqual(fmts.getTimeSteps(),[(0,0,0.),(1,0,1.),(2,0,2.),(3,0,3.),(4,0,4.)]) # All discretizations have the same time series + pass + allFMTSLeavesPerTimeSeries=MEDFileAnyTypeFieldMultiTS.SplitIntoCommonTimeSeries(sum(allFMTSLeavesToDisplay,[])) + self.assertEqual(len(allFMTSLeavesPerTimeSeries),1) + self.assertEqual(len(allFMTSLeavesPerTimeSeries[0]),2) + allFMTSLeavesPerCommonSupport=MEDFileAnyTypeFieldMultiTS.SplitPerCommonSupport(allFMTSLeavesPerTimeSeries[0],ms[ms.getMeshesNames()[0]]) + self.assertEqual(len(allFMTSLeavesPerCommonSupport),1) + self.assertEqual(len(allFMTSLeavesPerCommonSupport[0][0]),2) + # + mst=MEDFileMeshStruct.New(ms[0]) + fcscp=allFMTSLeavesPerCommonSupport[0][1] + mml=fcscp.buildFromScratchDataSetSupport(0,fields) + mml2=mml.prepare() + assert isinstance(mml2,MEDUMeshMultiLev) + for i in xrange(1,5): + self.assertTrue(fcscp.isDataSetSupportEqualToThePreviousOne(i,fields)) + pass + ncc,a0,a1,a2,a3,a4,a5=mml2.buildVTUArrays() + self.assertTrue(not ncc) + self.assertTrue(a0.isEqual(a0Exp.changeNbOfComponents(3,0.),1e-12)) + self.assertTrue(a1.isEqual(DataArrayByte([3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,5,5,5,5,9,9,9,9,9]))) + self.assertTrue(a2.isEqual(DataArrayInt([0,3,6,9,12,15,18,21,24,27,30,33,36,39,42,45,48,51,54,57,60,63,66,69,72,75,78,81,84,87,90,93,96,100,104,108,112,117,122,127,132]))) + self.assertTrue(a3.isEqual(DataArrayInt([2,0,1,2,1,2,2,2,0,2,3,4,2,4,5,2,5,3,2,6,7,2,7,8,2,8,6,2,9,10,2,10,11,2,11,9,2,12,13,2,13,14,2,14,15,2,15,12,2,16,17,2,17,18,2,18,19,2,19,16,2,20,21,2,21,22,2,22,23,2,23,20,2,24,25,2,25,26,2,26,27,2,27,24,2,28,29,2,29,30,2,30,31,2,31,28,3,0,1,2,3,3,4,5,3,6,7,8,3,9,10,11,4,12,13,14,15,4,16,17,18,19,4,20,21,22,23,4,24,25,26,27,4,28,29,30,31]))) + self.assertTrue(a4 is None) + self.assertTrue(a5 is None) + # for cells + for i in xrange(5): + f=allFMTSLeavesPerCommonSupport[0][0][0][i] + fsst=MEDFileField1TSStructItem.BuildItemFrom(f,mst)# Second 0 is for cells + f.loadArraysIfNecessary() + v=mml.buildDataArray(fsst,fields,f.getUndergroundDataArray()) + self.assertEqual(v.getHiddenCppPointer(),f.getUndergroundDataArray().getHiddenCppPointer()) + vExp=DataArrayDouble([200.,201.,202.,203.,204.,205.,206.,207.,208.,209.,210.,211.,212.,213.,214.,215.,216.,217.,218.,219.,220.,221.,222.,223.,224.,225.,226.,227.,228.,229.,230.,231.,232.,233.,234.,235.,236.,237.,238.,239.,240.,241.,242.,243.,244.,245.,246.,247.,248.,249.,250.,251.,252.,253.,254.,255.,256.,257.,258.,259.,260.,261.,262.,263.,100.,101.,102.,103.,104.,105.,106.,107.,108.,109.,110.,111.,112.,113.,114.,115.,116.,117.],41,2) ; vExp.setInfoOnComponents(['Comp1 [m]','Com2 [s^2]']) ; vExp+=i*1000 + self.assertTrue(v.isEqual(vExp,1e-12)) + pass + for i in xrange(5): + f=allFMTSLeavesPerCommonSupport[0][0][1][i] + fsst=MEDFileField1TSStructItem.BuildItemFrom(f,mst)# Second 0 is for cells + f.loadArraysIfNecessary() + v=mml.buildDataArray(fsst,fields,f.getUndergroundDataArray()) + self.assertEqual(v.getHiddenCppPointer(),f.getUndergroundDataArray().getHiddenCppPointer()) + vExp=DataArrayDouble([300.,301.,302.,303.,304.,305.,306.,307.,308.,309.,310.,311.,312.,313.,314.,315.,316.,317.,318.,319.,320.,321.,322.,323.,324.,325.,326.,327.,328.,329.,330.,331.,332.,333.,334.,335.,336.,337.,338.,339.,340.,341.,342.,343.,344.,345.,346.,347.,348.,349.,350.,351.,352.,353.,354.,355.,356.,357.,358.,359.,360.,361.,362.,363.],32,2) ; vExp.setInfoOnComponents(['Comp1 [m]','Com2 [s^2]']) ; vExp.setInfoOnComponents(['Comp1 [m]','Com2 [s^2]']) ; vExp+=i*1000 + self.assertTrue(v.isEqual(vExp,1e-12)) + pass + pass + + def test3(self): + """ This test is more advanced a same field is defined on CELLS for time steps 0, 2 and 4, and on NODES for time steps 1 and 3. + So two time step series on the same field. No profile here neither on cells nor on nodes. + """ + fname="ForMEDReader3.med" + # building a mesh containing 4 tri3 + 5 quad4 + tri=MEDCouplingUMesh("tri",2) + tri.allocateCells() ; tri.insertNextCell(NORM_TRI3,[0,1,2]) + tri.setCoords(DataArrayDouble([(0.,0.),(0.,1.),(1.,0.)])) + tris=[tri.deepCpy() for i in xrange(4)] + for i,elt in enumerate(tris): elt.translate([i,0]) + tris=MEDCouplingUMesh.MergeUMeshes(tris) + quad=MEDCouplingUMesh("quad",2) + quad.allocateCells() ; quad.insertNextCell(NORM_QUAD4,[0,1,2,3]) + quad.setCoords(DataArrayDouble([(0.,0.),(0.,1.),(1.,1.),(1.,0.)])) + quads=[quad.deepCpy() for i in xrange(5)] + for i,elt in enumerate(quads): elt.translate([5+i,0]) + quads=MEDCouplingUMesh.MergeUMeshes(quads) + m=MEDCouplingUMesh.MergeUMeshes(tris,quads) + m.setName("mesh") ; m.getCoords().setInfoOnComponents(["XX [m]","YYY [km]"]) + m1=m.buildDescendingConnectivity()[0] + mm=MEDFileUMesh() ; mm.setMeshes([m,m1]) + # + fieldName="zeField" + fs=MEDFileFieldMultiTS() + ##### Time step 0 on cells + i=0 + f=MEDFileField1TS() + fCell0=MEDCouplingFieldDouble(ON_CELLS) ; fCell0.setTime(float(i),i,0) + fCell0.setName(fieldName) ; fCell0.setMesh(m) + arr=DataArrayDouble(2*m.getNumberOfCells()) ; arr.iota(100) ; arr.rearrange(2) + fCell0.setArray(arr) ; arr.setInfoOnComponents(["Comp1 [m]","Com2 [s^2]"]) + fCell0.checkCoherency() + f.setFieldNoProfileSBT(fCell0) + fCell1=MEDCouplingFieldDouble(ON_CELLS) ; fCell1.setTime(float(i),i,0) + fCell1.setName(fieldName) ; fCell1.setMesh(m1) + arr=DataArrayDouble(2*m1.getNumberOfCells()) ; arr.iota(200) ; arr.rearrange(2) + fCell1.setArray(arr) ; arr.setInfoOnComponents(["Comp1 [m]","Com2 [s^2]"]) + fCell1.checkCoherency() + f.setFieldNoProfileSBT(fCell1) + fs.pushBackTimeStep(f) + ##### Time step 1 on nodes + i=1 + f=MEDFileField1TS() + fNode=MEDCouplingFieldDouble(ON_NODES) ; fNode.setTime(float(i),i,0) + fNode.setName(fieldName) ; fNode.setMesh(m1) + arr=DataArrayDouble(2*m.getNumberOfNodes()) ; arr.iota(1300) ; arr.rearrange(2) + fNode.setArray(arr) ; arr.setInfoOnComponents(["Comp1 [m]","Com2 [s^2]"]) + fNode.checkCoherency() + f.setFieldNoProfileSBT(fNode) + fs.pushBackTimeStep(f) + ##### Time step 2 on cells + i=2 + f=MEDFileField1TS() + fCell0=MEDCouplingFieldDouble(ON_CELLS) ; fCell0.setTime(float(i),i,0) + fCell0.setName(fieldName) ; fCell0.setMesh(m) + arr=DataArrayDouble(2*m.getNumberOfCells()) ; arr.iota(2100) ; arr.rearrange(2) + fCell0.setArray(arr) ; arr.setInfoOnComponents(["Comp1 [m]","Com2 [s^2]"]) + fCell0.checkCoherency() + f.setFieldNoProfileSBT(fCell0) + # + fCell1=MEDCouplingFieldDouble(ON_CELLS) ; fCell1.setTime(float(i),i,0) + fCell1.setName(fieldName) ; fCell1.setMesh(m1) + arr=DataArrayDouble(2*m1.getNumberOfCells()) ; arr.iota(2200) ; arr.rearrange(2) + fCell1.setArray(arr) ; arr.setInfoOnComponents(["Comp1 [m]","Com2 [s^2]"]) + fCell1.checkCoherency() + f.setFieldNoProfileSBT(fCell1) + fs.pushBackTimeStep(f) + ##### Time step 3 on nodes + i=3 + f=MEDFileField1TS() + fNode=MEDCouplingFieldDouble(ON_NODES) ; fNode.setTime(float(i),i,0) + fNode.setName(fieldName) ; fNode.setMesh(m1) + arr=DataArrayDouble(2*m.getNumberOfNodes()) ; arr.iota(3300) ; arr.rearrange(2) + fNode.setArray(arr) ; arr.setInfoOnComponents(["Comp1 [m]","Com2 [s^2]"]) + fNode.checkCoherency() + f.setFieldNoProfileSBT(fNode) + fs.pushBackTimeStep(f) + ##### Time step 4 + i=4 + f=MEDFileField1TS() + fCell0=MEDCouplingFieldDouble(ON_CELLS) ; fCell0.setTime(float(i),i,0) + fCell0.setName(fieldName) ; fCell0.setMesh(m) + arr=DataArrayDouble(2*m.getNumberOfCells()) ; arr.iota(4100) ; arr.rearrange(2) + fCell0.setArray(arr) ; arr.setInfoOnComponents(["Comp1 [m]","Com2 [s^2]"]) + fCell0.checkCoherency() + f.setFieldNoProfileSBT(fCell0) + # + fCell1=MEDCouplingFieldDouble(ON_CELLS) ; fCell1.setTime(float(i),i,0) + fCell1.setName(fieldName) ; fCell1.setMesh(m1) + arr=DataArrayDouble(2*m1.getNumberOfCells()) ; arr.iota(4200) ; arr.rearrange(2) + fCell1.setArray(arr) ; arr.setInfoOnComponents(["Comp1 [m]","Com2 [s^2]"]) + fCell1.checkCoherency() + f.setFieldNoProfileSBT(fCell1) + # + fs.pushBackTimeStep(f) + mm.write(fname,2) + fs.write(fname,0) + a0Exp=mm.getCoords().deepCpy() + del m,m1,mm,fs,f,fCell0,fCell1 + ########## GO for reading in MEDReader, by not loading all. Mesh is fully loaded but not fields values + ms=MEDFileMeshes(fname) + fields=MEDFileFields(fname,False) + fields.removeFieldsWithoutAnyTimeStep() + fields_per_mesh=[fields.partOfThisLyingOnSpecifiedMeshName(meshName) for meshName in ms.getMeshesNames()] + allFMTSLeavesToDisplay=[] + for fields in fields_per_mesh: + allFMTSLeavesToDisplay2=[] + for fmts in fields: + tmp=fmts.splitDiscretizations() + for itmp in tmp: + self.assertTrue(not itmp.presenceOfMultiDiscPerGeoType()) + pass + allFMTSLeavesToDisplay2+=tmp + pass + allFMTSLeavesToDisplay.append(allFMTSLeavesToDisplay2) + pass + self.assertEqual(len(allFMTSLeavesToDisplay),1) + self.assertEqual(len(allFMTSLeavesToDisplay[0]),2) + allFMTSLeavesPerTimeSeries=MEDFileAnyTypeFieldMultiTS.SplitIntoCommonTimeSeries(sum(allFMTSLeavesToDisplay,[])) + self.assertEqual(len(allFMTSLeavesPerTimeSeries),2) # two time series here : one for the cells, the second one for the nodes + self.assertEqual(len(allFMTSLeavesPerTimeSeries[0]),1) + self.assertEqual(len(allFMTSLeavesPerTimeSeries[1]),1) + allFMTSLeavesPerCommonSupport=MEDFileAnyTypeFieldMultiTS.SplitPerCommonSupport(allFMTSLeavesPerTimeSeries[0],ms[ms.getMeshesNames()[0]]) + self.assertEqual(len(allFMTSLeavesPerCommonSupport),1) + self.assertEqual(len(allFMTSLeavesPerCommonSupport[0][0]),1) + # + mst=MEDFileMeshStruct.New(ms[0]) + fcscp=allFMTSLeavesPerCommonSupport[0][1] # start with the cells + mml=fcscp.buildFromScratchDataSetSupport(0,fields) + mml2=mml.prepare() + self.assertTrue(isinstance(mml2,MEDUMeshMultiLev)) + for i in xrange(1,3): + self.assertTrue(fcscp.isDataSetSupportEqualToThePreviousOne(i,fields)) + pass + ncc,a0,a1,a2,a3,a4,a5=mml2.buildVTUArrays() + self.assertTrue(not ncc) + self.assertTrue(a0.isEqual(a0Exp.changeNbOfComponents(3,0.),1e-12)) + self.assertTrue(a1.isEqual(DataArrayByte([3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,5,5,5,5,9,9,9,9,9]))) + self.assertTrue(a2.isEqual(DataArrayInt([0,3,6,9,12,15,18,21,24,27,30,33,36,39,42,45,48,51,54,57,60,63,66,69,72,75,78,81,84,87,90,93,96,100,104,108,112,117,122,127,132]))) + self.assertTrue(a3.isEqual(DataArrayInt([2,0,1,2,1,2,2,2,0,2,3,4,2,4,5,2,5,3,2,6,7,2,7,8,2,8,6,2,9,10,2,10,11,2,11,9,2,12,13,2,13,14,2,14,15,2,15,12,2,16,17,2,17,18,2,18,19,2,19,16,2,20,21,2,21,22,2,22,23,2,23,20,2,24,25,2,25,26,2,26,27,2,27,24,2,28,29,2,29,30,2,30,31,2,31,28,3,0,1,2,3,3,4,5,3,6,7,8,3,9,10,11,4,12,13,14,15,4,16,17,18,19,4,20,21,22,23,4,24,25,26,27,4,28,29,30,31]))) + assert a4 is None + assert a5 is None + # for cells + for i in xrange(3): + f=allFMTSLeavesPerCommonSupport[0][0][0][i] + fsst=MEDFileField1TSStructItem.BuildItemFrom(f,mst)# Second 0 is for cells + f.loadArraysIfNecessary() + self.assertEqual(f.getName(),"zeField") + v=mml.buildDataArray(fsst,fields,f.getUndergroundDataArray()) + self.assertEqual(v.getHiddenCppPointer(),f.getUndergroundDataArray().getHiddenCppPointer()) + vExp=DataArrayDouble([200.,201.,202.,203.,204.,205.,206.,207.,208.,209.,210.,211.,212.,213.,214.,215.,216.,217.,218.,219.,220.,221.,222.,223.,224.,225.,226.,227.,228.,229.,230.,231.,232.,233.,234.,235.,236.,237.,238.,239.,240.,241.,242.,243.,244.,245.,246.,247.,248.,249.,250.,251.,252.,253.,254.,255.,256.,257.,258.,259.,260.,261.,262.,263.,100.,101.,102.,103.,104.,105.,106.,107.,108.,109.,110.,111.,112.,113.,114.,115.,116.,117.],41,2) ; vExp.setInfoOnComponents(['Comp1 [m]','Com2 [s^2]']) ; vExp+=i*2000 + self.assertTrue(v.isEqual(vExp,1e-12)) + pass + # for nodes + allFMTSLeavesPerCommonSupport=MEDFileAnyTypeFieldMultiTS.SplitPerCommonSupport(allFMTSLeavesPerTimeSeries[1],ms[ms.getMeshesNames()[0]]) + self.assertEqual(len(allFMTSLeavesPerCommonSupport),1) + self.assertEqual(len(allFMTSLeavesPerCommonSupport[0][0]),1) + fcscp=allFMTSLeavesPerCommonSupport[0][1] + mml=fcscp.buildFromScratchDataSetSupport(0,fields) + mml2=mml.prepare() + self.assertTrue(isinstance(mml2,MEDUMeshMultiLev)) + for i in xrange(1,2): + self.assertTrue(fcscp.isDataSetSupportEqualToThePreviousOne(i,fields)) + pass + ncc,a0,a1,a2,a3,a4,a5=mml2.buildVTUArrays() + self.assertTrue(not ncc) + self.assertTrue(a0.isEqual(a0Exp.changeNbOfComponents(3,0.),1e-12)) + self.assertTrue(a1.isEqual(DataArrayByte([5,5,5,5,9,9,9,9,9,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3]))) + self.assertTrue(a2.isEqual(DataArrayInt([0,4,8,12,16,21,26,31,36,41,44,47,50,53,56,59,62,65,68,71,74,77,80,83,86,89,92,95,98,101,104,107,110,113,116,119,122,125,128,131,134]))) + self.assertTrue(a3.isEqual(DataArrayInt([3,0,1,2,3,3,4,5,3,6,7,8,3,9,10,11,4,12,13,14,15,4,16,17,18,19,4,20,21,22,23,4,24,25,26,27,4,28,29,30,31,2,0,1,2,1,2,2,2,0,2,3,4,2,4,5,2,5,3,2,6,7,2,7,8,2,8,6,2,9,10,2,10,11,2,11,9,2,12,13,2,13,14,2,14,15,2,15,12,2,16,17,2,17,18,2,18,19,2,19,16,2,20,21,2,21,22,2,22,23,2,23,20,2,24,25,2,25,26,2,26,27,2,27,24,2,28,29,2,29,30,2,30,31,2,31,28]))) + self.assertTrue(a4 is None) + self.assertTrue(a5 is None) + for i in xrange(2): + f=allFMTSLeavesPerCommonSupport[0][0][0][i] + fsst=MEDFileField1TSStructItem.BuildItemFrom(f,mst)# Second 0 is for cells + f.loadArraysIfNecessary() + self.assertEqual(f.getName(),"zeField") + v=mml.buildDataArray(fsst,fields,f.getUndergroundDataArray()) + self.assertEqual(v.getHiddenCppPointer(),f.getUndergroundDataArray().getHiddenCppPointer()) + vExp=DataArrayDouble([300.,301.,302.,303.,304.,305.,306.,307.,308.,309.,310.,311.,312.,313.,314.,315.,316.,317.,318.,319.,320.,321.,322.,323.,324.,325.,326.,327.,328.,329.,330.,331.,332.,333.,334.,335.,336.,337.,338.,339.,340.,341.,342.,343.,344.,345.,346.,347.,348.,349.,350.,351.,352.,353.,354.,355.,356.,357.,358.,359.,360.,361.,362.,363.],32,2) ; vExp.setInfoOnComponents(['Comp1 [m]','Com2 [s^2]']) ; vExp.setInfoOnComponents(['Comp1 [m]','Com2 [s^2]']) ; vExp+=i*2000+1000 + self.assertTrue(v.isEqual(vExp,1e-12)) + pass + pass + + def test4(self): + """ This test defines 3 fields on nodes on the same mesh. All of these fields have no profile. + """ + fname="ForMEDReader4.med" + # building a mesh containing 4 tri3 + 5 quad4 + tri=MEDCouplingUMesh("tri",2) + tri.allocateCells() ; tri.insertNextCell(NORM_TRI3,[0,1,2]) + tri.setCoords(DataArrayDouble([(0.,0.),(0.,1.),(1.,0.)])) + tris=[tri.deepCpy() for i in xrange(4)] + for i,elt in enumerate(tris): elt.translate([i,0]) + tris=MEDCouplingUMesh.MergeUMeshes(tris) + quad=MEDCouplingUMesh("quad",2) + quad.allocateCells() ; quad.insertNextCell(NORM_QUAD4,[0,1,2,3]) + quad.setCoords(DataArrayDouble([(0.,0.),(0.,1.),(1.,1.),(1.,0.)])) + quads=[quad.deepCpy() for i in xrange(5)] + for i,elt in enumerate(quads): elt.translate([5+i,0]) + quads=MEDCouplingUMesh.MergeUMeshes(quads) + m=MEDCouplingUMesh.MergeUMeshes(tris,quads) + m.setName("mesh") ; m.getCoords().setInfoOnComponents(["XX [m]","YYY [km]"]) + mm=MEDFileUMesh() ; mm.setMeshes([m]) + # + fieldName1="zeField1" + fieldName2="zeField2" + fieldName3="zeField3" + fs1=MEDFileFieldMultiTS() ; fs2=MEDFileFieldMultiTS() ; fs3=MEDFileFieldMultiTS() + ##### Time step 0 + i=0 + f=MEDFileField1TS() + fNode=MEDCouplingFieldDouble(ON_NODES) ; fNode.setTime(float(i),i,0) + fNode.setName(fieldName1) ; fNode.setMesh(m) + arr=DataArrayDouble(2*m.getNumberOfNodes()) ; arr.iota(0+1000*i) ; arr.rearrange(2) + fNode.setArray(arr) ; arr.setInfoOnComponents(["Comp1_0 [m]","Com2_0 [s^2]"]) + fNode.checkCoherency() + f.setFieldNoProfileSBT(fNode) + fs1.pushBackTimeStep(f) + # + f=MEDFileField1TS() + fNode=MEDCouplingFieldDouble(ON_NODES) ; fNode.setTime(float(i),i,0) + fNode.setName(fieldName2) ; fNode.setMesh(m) + arr=DataArrayDouble(2*m.getNumberOfNodes()) ; arr.iota(100+1000*i) ; arr.rearrange(2) + fNode.setArray(arr) ; arr.setInfoOnComponents(["Comp1_1 [m]","Com2_1 [s^2]"]) + fNode.checkCoherency() + f.setFieldNoProfileSBT(fNode) + fs2.pushBackTimeStep(f) + # + f=MEDFileField1TS() + fNode=MEDCouplingFieldDouble(ON_NODES) ; fNode.setTime(float(i),i,0) + fNode.setName(fieldName3) ; fNode.setMesh(m) + arr=DataArrayDouble(2*m.getNumberOfNodes()) ; arr.iota(200+1000*i) ; arr.rearrange(2) + fNode.setArray(arr) ; arr.setInfoOnComponents(["Comp1_2 [m]","Com2_2 [s^2]"]) + fNode.checkCoherency() + f.setFieldNoProfileSBT(fNode) + fs3.pushBackTimeStep(f) + ##### Time step 1 + i=1 + f=MEDFileField1TS() + fNode=MEDCouplingFieldDouble(ON_NODES) ; fNode.setTime(float(i),i,0) + fNode.setName(fieldName1) ; fNode.setMesh(m) + arr=DataArrayDouble(2*m.getNumberOfNodes()) ; arr.iota(0+1000*i) ; arr.rearrange(2) + fNode.setArray(arr) ; arr.setInfoOnComponents(["Comp1_0 [m]","Com2_0 [s^2]"]) + fNode.checkCoherency() + f.setFieldNoProfileSBT(fNode) + fs1.pushBackTimeStep(f) + # + f=MEDFileField1TS() + fNode=MEDCouplingFieldDouble(ON_NODES) ; fNode.setTime(float(i),i,0) + fNode.setName(fieldName2) ; fNode.setMesh(m) + arr=DataArrayDouble(2*m.getNumberOfNodes()) ; arr.iota(100+1000*i) ; arr.rearrange(2) + fNode.setArray(arr) ; arr.setInfoOnComponents(["Comp1_1 [m]","Com2_1 [s^2]"]) + fNode.checkCoherency() + f.setFieldNoProfileSBT(fNode) + fs2.pushBackTimeStep(f) + # + f=MEDFileField1TS() + fNode=MEDCouplingFieldDouble(ON_NODES) ; fNode.setTime(float(i),i,0) + fNode.setName(fieldName3) ; fNode.setMesh(m) + arr=DataArrayDouble(2*m.getNumberOfNodes()) ; arr.iota(200+1000*i) ; arr.rearrange(2) + fNode.setArray(arr) ; arr.setInfoOnComponents(["Comp1_2 [m]","Com2_2 [s^2]"]) + fNode.checkCoherency() + f.setFieldNoProfileSBT(fNode) + fs3.pushBackTimeStep(f) + ##### Time step 2 + i=2 + f=MEDFileField1TS() + fNode=MEDCouplingFieldDouble(ON_NODES) ; fNode.setTime(float(i),i,0) + fNode.setName(fieldName1) ; fNode.setMesh(m) + arr=DataArrayDouble(2*m.getNumberOfNodes()) ; arr.iota(0+1000*i) ; arr.rearrange(2) + fNode.setArray(arr) ; arr.setInfoOnComponents(["Comp1_0 [m]","Com2_0 [s^2]"]) + fNode.checkCoherency() + f.setFieldNoProfileSBT(fNode) + fs1.pushBackTimeStep(f) + # + f=MEDFileField1TS() + fNode=MEDCouplingFieldDouble(ON_NODES) ; fNode.setTime(float(i),i,0) + fNode.setName(fieldName2) ; fNode.setMesh(m) + arr=DataArrayDouble(2*m.getNumberOfNodes()) ; arr.iota(100+1000*i) ; arr.rearrange(2) + fNode.setArray(arr) ; arr.setInfoOnComponents(["Comp1_1 [m]","Com2_1 [s^2]"]) + fNode.checkCoherency() + f.setFieldNoProfileSBT(fNode) + fs2.pushBackTimeStep(f) + # + f=MEDFileField1TS() + fNode=MEDCouplingFieldDouble(ON_NODES) ; fNode.setTime(float(i),i,0) + fNode.setName(fieldName3) ; fNode.setMesh(m) + arr=DataArrayDouble(2*m.getNumberOfNodes()) ; arr.iota(200+1000*i) ; arr.rearrange(2) + fNode.setArray(arr) ; arr.setInfoOnComponents(["Comp1_2 [m]","Com2_2 [s^2]"]) + fNode.checkCoherency() + f.setFieldNoProfileSBT(fNode) + fs3.pushBackTimeStep(f) + ##### Time step 3 + i=3 + f=MEDFileField1TS() + fNode=MEDCouplingFieldDouble(ON_NODES) ; fNode.setTime(float(i),i,0) + fNode.setName(fieldName1) ; fNode.setMesh(m) + arr=DataArrayDouble(2*m.getNumberOfNodes()) ; arr.iota(0+1000*i) ; arr.rearrange(2) + fNode.setArray(arr) ; arr.setInfoOnComponents(["Comp1_0 [m]","Com2_0 [s^2]"]) + fNode.checkCoherency() + f.setFieldNoProfileSBT(fNode) + fs1.pushBackTimeStep(f) + # + f=MEDFileField1TS() + fNode=MEDCouplingFieldDouble(ON_NODES) ; fNode.setTime(float(i),i,0) + fNode.setName(fieldName2) ; fNode.setMesh(m) + arr=DataArrayDouble(2*m.getNumberOfNodes()) ; arr.iota(100+1000*i) ; arr.rearrange(2) + fNode.setArray(arr) ; arr.setInfoOnComponents(["Comp1_1 [m]","Com2_1 [s^2]"]) + fNode.checkCoherency() + f.setFieldNoProfileSBT(fNode) + fs2.pushBackTimeStep(f) + # + f=MEDFileField1TS() + fNode=MEDCouplingFieldDouble(ON_NODES) ; fNode.setTime(float(i),i,0) + fNode.setName(fieldName3) ; fNode.setMesh(m) + arr=DataArrayDouble(2*m.getNumberOfNodes()) ; arr.iota(200+1000*i) ; arr.rearrange(2) + fNode.setArray(arr) ; arr.setInfoOnComponents(["Comp1_2 [m]","Com2_2 [s^2]"]) + fNode.checkCoherency() + f.setFieldNoProfileSBT(fNode) + fs3.pushBackTimeStep(f) + ##### Time step 4 + i=4 + f=MEDFileField1TS() + fNode=MEDCouplingFieldDouble(ON_NODES) ; fNode.setTime(float(i),i,0) + fNode.setName(fieldName1) ; fNode.setMesh(m) + arr=DataArrayDouble(2*m.getNumberOfNodes()) ; arr.iota(0+1000*i) ; arr.rearrange(2) + fNode.setArray(arr) ; arr.setInfoOnComponents(["Comp1_0 [m]","Com2_0 [s^2]"]) + fNode.checkCoherency() + f.setFieldNoProfileSBT(fNode) + fs1.pushBackTimeStep(f) + # + f=MEDFileField1TS() + fNode=MEDCouplingFieldDouble(ON_NODES) ; fNode.setTime(float(i),i,0) + fNode.setName(fieldName2) ; fNode.setMesh(m) + arr=DataArrayDouble(2*m.getNumberOfNodes()) ; arr.iota(100+1000*i) ; arr.rearrange(2) + fNode.setArray(arr) ; arr.setInfoOnComponents(["Comp1_1 [m]","Com2_1 [s^2]"]) + fNode.checkCoherency() + f.setFieldNoProfileSBT(fNode) + fs2.pushBackTimeStep(f) + # + f=MEDFileField1TS() + fNode=MEDCouplingFieldDouble(ON_NODES) ; fNode.setTime(float(i),i,0) + fNode.setName(fieldName3) ; fNode.setMesh(m) + arr=DataArrayDouble(2*m.getNumberOfNodes()) ; arr.iota(200+1000*i) ; arr.rearrange(2) + fNode.setArray(arr) ; arr.setInfoOnComponents(["Comp1_2 [m]","Com2_2 [s^2]"]) + fNode.checkCoherency() + f.setFieldNoProfileSBT(fNode) + fs3.pushBackTimeStep(f) + # + mm.write(fname,2) + fs1.write(fname,0) ; fs2.write(fname,0) ; fs3.write(fname,0) + a0Exp=mm.getCoords().deepCpy() + del m,mm,fs1,fs2,fs3,f,fNode + ########## GO for reading in MEDReader, by not loading all. Mesh is fully loaded but not fields values + ms=MEDFileMeshes(fname) + fields=MEDFileFields(fname,False) + fields.removeFieldsWithoutAnyTimeStep() + fields_per_mesh=[fields.partOfThisLyingOnSpecifiedMeshName(meshName) for meshName in ms.getMeshesNames()] + allFMTSLeavesToDisplay=[] + for fields in fields_per_mesh: + allFMTSLeavesToDisplay2=[] + for fmts in fields: + tmp=fmts.splitDiscretizations() + for itmp in tmp: + self.assertTrue(not itmp.presenceOfMultiDiscPerGeoType()) + pass + allFMTSLeavesToDisplay2+=tmp + pass + allFMTSLeavesToDisplay.append(allFMTSLeavesToDisplay2) + pass + self.assertEqual(len(allFMTSLeavesToDisplay),1) + self.assertEqual(len(allFMTSLeavesToDisplay[0]),3) + allFMTSLeavesPerTimeSeries=MEDFileAnyTypeFieldMultiTS.SplitIntoCommonTimeSeries(sum(allFMTSLeavesToDisplay,[])) + self.assertEqual(len(allFMTSLeavesPerTimeSeries),1) # one time serie here : because the 3 fields are defined on the same time steps + self.assertEqual(len(allFMTSLeavesPerTimeSeries[0]),3) + allFMTSLeavesPerCommonSupport=MEDFileAnyTypeFieldMultiTS.SplitPerCommonSupport(allFMTSLeavesPerTimeSeries[0],ms[ms.getMeshesNames()[0]]) + self.assertEqual(len(allFMTSLeavesPerCommonSupport),1) + self.assertEqual(len(allFMTSLeavesPerCommonSupport[0][0]),3) + # + mst=MEDFileMeshStruct.New(ms[0]) + fcscp=allFMTSLeavesPerCommonSupport[0][1] + self.assertEqual(len(allFMTSLeavesPerCommonSupport),1) + self.assertEqual(len(allFMTSLeavesPerCommonSupport[0][0]),3) + fcscp=allFMTSLeavesPerCommonSupport[0][1] + mml=fcscp.buildFromScratchDataSetSupport(0,fields) + mml2=mml.prepare() + self.assertTrue(isinstance(mml2,MEDUMeshMultiLev)) + for i in xrange(1,5): + self.assertTrue(fcscp.isDataSetSupportEqualToThePreviousOne(i,fields)) + pass + ncc,a0,a1,a2,a3,a4,a5=mml2.buildVTUArrays() + self.assertTrue(not ncc) + self.assertTrue(a0.isEqual(a0Exp.changeNbOfComponents(3,0.),1e-12)) + self.assertTrue(a1.isEqual(DataArrayByte([5,5,5,5,9,9,9,9,9]))) + self.assertTrue(a2.isEqual(DataArrayInt([0,4,8,12,16,21,26,31,36]))) + self.assertTrue(a3.isEqual(DataArrayInt([3,0,1,2,3,3,4,5,3,6,7,8,3,9,10,11,4,12,13,14,15,4,16,17,18,19,4,20,21,22,23,4,24,25,26,27,4,28,29,30,31]))) + self.assertTrue(a4 is None) + self.assertTrue(a5 is None) + # test all the time steps of the 1/1 time step serie, on field 1 + for i in xrange(5): + f=allFMTSLeavesPerCommonSupport[0][0][0][i] + fsst=MEDFileField1TSStructItem.BuildItemFrom(f,mst) + f.loadArraysIfNecessary() + v=mml.buildDataArray(fsst,fields,f.getUndergroundDataArray()) + self.assertEqual(f.getName(),fieldName1) + self.assertEqual(v.getHiddenCppPointer(),f.getUndergroundDataArray().getHiddenCppPointer()) + vExp=DataArrayDouble([0.,1.,2.,3.,4.,5.,6.,7.,8.,9.,10.,11.,12.,13.,14.,15.,16.,17.,18.,19.,20.,21.,22.,23.,24.,25.,26.,27.,28.,29.,30.,31.,32.,33.,34.,35.,36.,37.,38.,39.,40.,41.,42.,43.,44.,45.,46.,47.,48.,49.,50.,51.,52.,53.,54.,55.,56.,57.,58.,59.,60.,61.,62.,63.],32,2) ; vExp.setInfoOnComponents(['Comp1_0 [m]','Com2_0 [s^2]']) ; vExp+=i*1000 + self.assertTrue(v.isEqual(vExp,1e-12)) + pass + # test all the time steps of the 1/1 time step serie, on field 2 + for i in xrange(5): + f=allFMTSLeavesPerCommonSupport[0][0][1][i] + fsst=MEDFileField1TSStructItem.BuildItemFrom(f,mst) + f.loadArraysIfNecessary() + v=mml.buildDataArray(fsst,fields,f.getUndergroundDataArray()) + self.assertEqual(f.getName(),fieldName2) + self.assertEqual(v.getHiddenCppPointer(),f.getUndergroundDataArray().getHiddenCppPointer()) + vExp=DataArrayDouble([0.,1.,2.,3.,4.,5.,6.,7.,8.,9.,10.,11.,12.,13.,14.,15.,16.,17.,18.,19.,20.,21.,22.,23.,24.,25.,26.,27.,28.,29.,30.,31.,32.,33.,34.,35.,36.,37.,38.,39.,40.,41.,42.,43.,44.,45.,46.,47.,48.,49.,50.,51.,52.,53.,54.,55.,56.,57.,58.,59.,60.,61.,62.,63.],32,2) ; vExp.setInfoOnComponents(['Comp1_1 [m]','Com2_1 [s^2]']) ; vExp+=i*1000+100 + self.assertTrue(v.isEqual(vExp,1e-12)) + pass + # test all the time steps of the 1/1 time step serie, on field 3 + for i in xrange(5): + f=allFMTSLeavesPerCommonSupport[0][0][2][i] + fsst=MEDFileField1TSStructItem.BuildItemFrom(f,mst) + f.loadArraysIfNecessary() + v=mml.buildDataArray(fsst,fields,f.getUndergroundDataArray()) + self.assertEqual(f.getName(),fieldName3) + self.assertEqual(v.getHiddenCppPointer(),f.getUndergroundDataArray().getHiddenCppPointer()) + vExp=DataArrayDouble([0.,1.,2.,3.,4.,5.,6.,7.,8.,9.,10.,11.,12.,13.,14.,15.,16.,17.,18.,19.,20.,21.,22.,23.,24.,25.,26.,27.,28.,29.,30.,31.,32.,33.,34.,35.,36.,37.,38.,39.,40.,41.,42.,43.,44.,45.,46.,47.,48.,49.,50.,51.,52.,53.,54.,55.,56.,57.,58.,59.,60.,61.,62.,63.],32,2) ; vExp.setInfoOnComponents(['Comp1_2 [m]','Com2_2 [s^2]']) ; vExp+=i*1000+200 + self.assertTrue(v.isEqual(vExp,1e-12)) + pass + pass + + def test5(self): + """ This test plays with profiles both cell profiles and node profiles. Two first fields (resp on cells and on nodes) lie on the same mesh support whereas the third + mesh lies on a different mesh. + """ + fname="ForMEDReader5.med" + # building a mesh containing 6 tri3 + 5 quad4 + m=MEDCouplingUMesh("mesh",2) + coords=DataArrayDouble([(0,0),(1,0),(2,0),(3,0),(4,0),(0,1),(1,1),(2,1),(3,1),(4,1),(0,2),(1,2),(2,2),(3,2),(4,2)]) ; coords.setInfoOnComponents(["XX [m]","YYY [km]"]) + m.setCoords(coords) + m.allocateCells() + m.insertNextCell(NORM_TRI3,[2,7,3]) ; m.insertNextCell(NORM_TRI3,[7,8,3]) ; m.insertNextCell(NORM_TRI3,[3,8,4]) ; m.insertNextCell(NORM_TRI3,[8,9,4]) + m.insertNextCell(NORM_TRI3,[13,9,8]) ; m.insertNextCell(NORM_TRI3,[13,14,9]) + m.insertNextCell(NORM_QUAD4,[0,5,6,1]) ; m.insertNextCell(NORM_QUAD4,[1,6,7,2]) ; m.insertNextCell(NORM_QUAD4,[5,10,11,6]) ; m.insertNextCell(NORM_QUAD4,[6,11,12,7]) + m.insertNextCell(NORM_QUAD4,[12,13,8,7]) + mm=MEDFileUMesh() ; mm.setMeshes([m]) + fam=DataArrayInt(11) ; fam.iota(0) ; mm.setFamilyFieldArr(0,fam) ; del fam + num=DataArrayInt(11) ; num.iota(100) ; mm.setRenumFieldArr(0,num) ; del num + # + fieldName1="zeField1" ; pfl1=DataArrayInt([0,1,2,3,4,5]) ; pfl1.setName("pfl1") # on cells + fieldName2="zeField2" ; pfl2=DataArrayInt([2,3,4,7,8,9,13,14]) ; pfl2.setName("pfl2") # on nodes + fieldName3="zeField3" ; pfl3=DataArrayInt([0,1,2,3,4,5,9,10]) ; pfl3.setName("pfl3") # on cells but different support + fs1=MEDFileFieldMultiTS() ; fs2=MEDFileFieldMultiTS() ; fs3=MEDFileFieldMultiTS() + # + for i in xrange(5): + f=MEDFileField1TS() + fNode=MEDCouplingFieldDouble(ON_CELLS) ; fNode.setTime(float(i),i,0) + fNode.setName(fieldName1) + arr=DataArrayDouble(2*6) ; arr.iota(0+1000*i) ; arr.rearrange(2) + fNode.setArray(arr) ; arr.setInfoOnComponents(["Comp1_0 [m]","Com2_0 [s^2]"]) + f.setFieldProfile(fNode,mm,0,pfl1) + fs1.pushBackTimeStep(f) + # + f=MEDFileField1TS() + fNode=MEDCouplingFieldDouble(ON_NODES) ; fNode.setTime(float(i),i,0) + fNode.setName(fieldName2) + arr=DataArrayDouble(2*8) ; arr.iota(100+1000*i) ; arr.rearrange(2) + fNode.setArray(arr) ; arr.setInfoOnComponents(["Comp1_1 [m]","Com2_1 [s^2]"]) + f.setFieldProfile(fNode,mm,0,pfl2) + fs2.pushBackTimeStep(f) + # + f=MEDFileField1TS() + fNode=MEDCouplingFieldDouble(ON_CELLS) ; fNode.setTime(float(i),i,0) + fNode.setName(fieldName3) + arr=DataArrayDouble(2*8) ; arr.iota(200+1000*i) ; arr.rearrange(2) + fNode.setArray(arr) ; arr.setInfoOnComponents(["Comp1_2 [m]","Com2_2 [s^2]"]) + f.setFieldProfile(fNode,mm,0,pfl3) + fs3.pushBackTimeStep(f) + pass + mm.write(fname,2) + fs1.write(fname,0) ; fs2.write(fname,0) ; fs3.write(fname,0) + a0Exp=mm.getCoords().deepCpy() + del m,mm,fs1,fs2,fs3,f,fNode + ########## GO for reading in MEDReader,by not loading all. Mesh is fully loaded but not fields values + ms=MEDFileMeshes(fname) + fields=MEDFileFields(fname,False) + fields.removeFieldsWithoutAnyTimeStep() + fields_per_mesh=[fields.partOfThisLyingOnSpecifiedMeshName(meshName) for meshName in ms.getMeshesNames()] + allFMTSLeavesToDisplay=[] + for fields in fields_per_mesh: + allFMTSLeavesToDisplay2=[] + for fmts in fields: + tmp=fmts.splitDiscretizations() + for itmp in tmp: + self.assertTrue(not itmp.presenceOfMultiDiscPerGeoType()) + pass + allFMTSLeavesToDisplay2+=tmp + pass + allFMTSLeavesToDisplay.append(allFMTSLeavesToDisplay2) + pass + self.assertEqual(len(allFMTSLeavesToDisplay),1) + self.assertEqual(len(allFMTSLeavesToDisplay[0]),3) + allFMTSLeavesPerTimeSeries=MEDFileAnyTypeFieldMultiTS.SplitIntoCommonTimeSeries(sum(allFMTSLeavesToDisplay,[])) + self.assertEqual(len(allFMTSLeavesPerTimeSeries),1) # one time serie here : because the 3 fields are defined on the same time steps + self.assertEqual(len(allFMTSLeavesPerTimeSeries[0]),3) + allFMTSLeavesPerCommonSupport=MEDFileAnyTypeFieldMultiTS.SplitPerCommonSupport(allFMTSLeavesPerTimeSeries[0],ms[ms.getMeshesNames()[0]]) + ms[0].getDirectUndergroundSingleGeoTypeMeshes(0) + self.assertEqual(len(allFMTSLeavesPerCommonSupport),2) # 2 support here + self.assertEqual(len(allFMTSLeavesPerCommonSupport[0][0]),2) + self.assertEqual(len(allFMTSLeavesPerCommonSupport[1][0]),1) + # + mst=MEDFileMeshStruct.New(ms[0]) + fcscp=allFMTSLeavesPerCommonSupport[0][1] + mml=fcscp.buildFromScratchDataSetSupport(0,fields) + mml2=mml.prepare() + self.assertTrue(isinstance(mml2,MEDUMeshMultiLev)) + for i in xrange(1,5): + self.assertTrue((fcscp.isDataSetSupportEqualToThePreviousOne(i,fields))) + pass + ncc,a0,a1,a2,a3,a4,a5=mml2.buildVTUArrays() + self.assertTrue(not ncc) + self.assertTrue(a0.isEqual(a0Exp[pfl2].changeNbOfComponents(3,0.),1e-12)) + self.assertTrue(a1.isEqual(DataArrayByte([5,5,5,5,5,5]))) + self.assertTrue(a2.isEqual(DataArrayInt([0,4,8,12,16,20]))) + self.assertTrue(a3.isEqual(DataArrayInt([3,0,3,1,3,3,4,1,3,1,4,2,3,4,5,2,3,6,5,4,3,6,7,5]))) + assert a4 is None + assert a5 is None + a6,a7=mml2.retrieveFamilyIdsOnCells() + self.assertTrue(a6.isEqual(DataArrayInt([0,1,2,3,4,5]))) + self.assertTrue(not a7) + a8,a9=mml2.retrieveNumberIdsOnCells() + self.assertTrue(a8.isEqual(DataArrayInt([100,101,102,103,104,105]))) + self.assertTrue(not a9) + for i in xrange(5): + nbOfT=[6,8] + fieldNames=[fieldName1,fieldName2] + for j in xrange(2): + m={"i":j} + f=allFMTSLeavesPerCommonSupport[0][0][j][i] + fsst=MEDFileField1TSStructItem.BuildItemFrom(f,mst) + f.loadArraysIfNecessary() + v=mml.buildDataArray(fsst,fields,f.getUndergroundDataArray()) + self.assertEqual(f.getName(),fieldNames[j]) + self.assertEqual(v.getHiddenCppPointer(),f.getUndergroundDataArray().getHiddenCppPointer()) + vExp=DataArrayDouble(nbOfT[j]*2) ; vExp.iota(j*100+i*1000) ; vExp.rearrange(2) ; vExp.setInfoOnComponents(['Comp1_%(i)i [m]'%m,'Com2_%(i)i [s^2]'%m]) + self.assertTrue(v.isEqual(vExp,1e-12)) + pass + pass + # Let's go for the 2nd support + fcscp=allFMTSLeavesPerCommonSupport[1][1] + mml=fcscp.buildFromScratchDataSetSupport(0,fields) + mml2=mml.prepare() + self.assertTrue(isinstance(mml2,MEDUMeshMultiLev)) + for i in xrange(1,5): + self.assertTrue(fcscp.isDataSetSupportEqualToThePreviousOne(i,fields)) + pass + ncc,a0,a1,a2,a3,a4,a5=mml2.buildVTUArrays() + self.assertTrue(not ncc) + self.assertTrue(a0.isEqual(a0Exp.changeNbOfComponents(3,0.),1e-12)) + self.assertTrue(a1.isEqual(DataArrayByte([5,5,5,5,5,5,9,9]))) + self.assertTrue(a2.isEqual(DataArrayInt([0,4,8,12,16,20,24,29]))) + self.assertTrue(a3.isEqual(DataArrayInt([3,2,7,3,3,7,8,3,3,3,8,4,3,8,9,4,3,13,9,8,3,13,14,9,4,6,11,12,7,4,12,13,8,7]))) + self.assertTrue(a4 is None) + self.assertTrue(a5 is None) + a6,a7=mml2.retrieveFamilyIdsOnCells() + self.assertTrue(a6.isEqual(DataArrayInt([0,1,2,3,4,5,9,10]))) + self.assertTrue(not a7) + a8,a9=mml2.retrieveNumberIdsOnCells() + self.assertTrue(a8.isEqual(DataArrayInt([100,101,102,103,104,105,109,110]))) + self.assertTrue(not a9) + for i in xrange(5): + f=allFMTSLeavesPerCommonSupport[1][0][0][i] + fsst=MEDFileField1TSStructItem.BuildItemFrom(f,mst) + f.loadArraysIfNecessary() + v=mml.buildDataArray(fsst,fields,f.getUndergroundDataArray()) + self.assertEqual(f.getName(),"zeField3") + self.assertEqual(v.getHiddenCppPointer(),f.getUndergroundDataArray().getHiddenCppPointer()) + vExp=DataArrayDouble(8*2) ; vExp.iota(200+1000*i) ; vExp.rearrange(2) ; vExp.setInfoOnComponents(['Comp1_2 [m]'%m,'Com2_2 [s^2]'%m]) + self.assertTrue(v.isEqual(vExp,1e-12)) + pass + pass + + def test6(self): + """ This test plays with cartesian mesh and profiles. When a sub cartesian mesh can also be considered as a cartesian mesh it is done. + """ + fname="ForMEDReader6.med" + m=MEDCouplingCMesh("mesh") + coordsX=DataArrayDouble([0,1.1,2.2,3.3,4.4]) ; coordsX.setInfoOnComponents(["XX [m]"]) + coordsY=DataArrayDouble([0,1.7,3.4]) ; coordsY.setInfoOnComponents(["YYY [km]"]) + m.setCoords(coordsX,coordsY) + mm=MEDFileCMesh() ; mm.setMesh(m) + fam=DataArrayInt(8) ; fam.iota(0) ; mm.setFamilyFieldArr(0,fam) ; del fam + num=DataArrayInt(8) ; num.iota(100) ; mm.setRenumFieldArr(0,num) ; del num + num=DataArrayInt(15) ; num.iota(200) ; mm.setRenumFieldArr(1,num) ; del num + # + fieldName0="zeField0" ; # on cells + fieldName1="zeField1" ; pfl1=DataArrayInt([2,3,6,7]) ; pfl1.setName("pfl1") # on cells + fieldName2="zeField2" ; pfl2=DataArrayInt([2,3,4,7,8,9,12,13,14]) ; pfl2.setName("pfl2") # on nodes + fieldName3="zeField3" ; pfl3=DataArrayInt([2,3,5,7]) ; pfl3.setName("pfl3") # on cells but different support + fieldName4="zeField4" ;# on nodes + fs0=MEDFileFieldMultiTS() ; fs1=MEDFileFieldMultiTS() ; fs2=MEDFileFieldMultiTS() ; fs3=MEDFileFieldMultiTS() ; fs4=MEDFileFieldMultiTS() + # + for i in xrange(5): + f=MEDFileField1TS() + fNode=MEDCouplingFieldDouble(ON_CELLS) ; fNode.setTime(float(i),i,0) + fNode.setName(fieldName0) ; fNode.setMesh(m) + arr=DataArrayDouble(2*8) ; arr.iota(0+1000*i) ; arr.rearrange(2) + fNode.setArray(arr) ; arr.setInfoOnComponents(["Comp1_0 [m]","Com2_0 [s^2]"]) ; fNode.checkCoherency() + f.setFieldNoProfileSBT(fNode) + fs0.pushBackTimeStep(f) + # + f=MEDFileField1TS() + fNode=MEDCouplingFieldDouble(ON_CELLS) ; fNode.setTime(float(i),i,0) + fNode.setName(fieldName1) + arr=DataArrayDouble(2*4) ; arr.iota(100+1000*i) ; arr.rearrange(2) + fNode.setArray(arr) ; arr.setInfoOnComponents(["Comp1_1 [m]","Com2_1 [s^2]"]) + f.setFieldProfile(fNode,mm,0,pfl1) + self.assertEqual(pfl1.getName(),"pfl1") + fs1.pushBackTimeStep(f) + # + f=MEDFileField1TS() + fNode=MEDCouplingFieldDouble(ON_NODES) ; fNode.setTime(float(i),i,0) + fNode.setName(fieldName2) + arr=DataArrayDouble(2*9) ; arr.iota(200+1000*i) ; arr.rearrange(2) + fNode.setArray(arr) ; arr.setInfoOnComponents(["Comp1_2 [m]","Com2_2 [s^2]"]) + f.setFieldProfile(fNode,mm,0,pfl2) + self.assertEqual(pfl2.getName(),"pfl2") + fs2.pushBackTimeStep(f) + # + f=MEDFileField1TS() + fNode=MEDCouplingFieldDouble(ON_CELLS) ; fNode.setTime(float(i),i,0) + fNode.setName(fieldName3) + arr=DataArrayDouble(2*4) ; arr.iota(300+1000*i) ; arr.rearrange(2) + fNode.setArray(arr) ; arr.setInfoOnComponents(["Comp1_3 [m]","Com2_3 [s^2]"]) + f.setFieldProfile(fNode,mm,0,pfl3) + self.assertEqual(pfl3.getName(),"pfl3") + fs3.pushBackTimeStep(f) + # + f=MEDFileField1TS() + fNode=MEDCouplingFieldDouble(ON_NODES) ; fNode.setTime(float(i),i,0) + fNode.setName(fieldName4) ; fNode.setMesh(m) + arr=DataArrayDouble(2*15) ; arr.iota(400+1000*i) ; arr.rearrange(2) + fNode.setArray(arr) ; arr.setInfoOnComponents(["Comp1_4 [m]","Com2_4 [s^2]"]) ; fNode.checkCoherency() + f.setFieldNoProfileSBT(fNode) + fs4.pushBackTimeStep(f) + pass + mm.write(fname,2) + fs0.write(fname,0) ; fs1.write(fname,0) ; fs2.write(fname,0) ; fs3.write(fname,0) ; fs4.write(fname,0) + del m,mm,fs1,fs2,fs3,f,fNode + ########## GO for reading in MEDReader,by not loading all. Mesh is fully loaded but not fields values + ms=MEDFileMeshes(fname) + fields=MEDFileFields(fname,False) + fields.removeFieldsWithoutAnyTimeStep() + fields_per_mesh=[fields.partOfThisLyingOnSpecifiedMeshName(meshName) for meshName in ms.getMeshesNames()] + allFMTSLeavesToDisplay=[] + for fields in fields_per_mesh: + allFMTSLeavesToDisplay2=[] + for fmts in fields: + tmp=fmts.splitDiscretizations() + for itmp in tmp: + self.assertTrue(not itmp.presenceOfMultiDiscPerGeoType()) + pass + allFMTSLeavesToDisplay2+=tmp + pass + allFMTSLeavesToDisplay.append(allFMTSLeavesToDisplay2) + pass + self.assertEqual(len(allFMTSLeavesToDisplay),1) + self.assertEqual(len(allFMTSLeavesToDisplay[0]),5) + allFMTSLeavesPerTimeSeries=MEDFileAnyTypeFieldMultiTS.SplitIntoCommonTimeSeries(sum(allFMTSLeavesToDisplay,[])) + self.assertEqual(len(allFMTSLeavesPerTimeSeries),1) # one time serie here : because the 5 fields are defined on the same time steps + self.assertEqual(len(allFMTSLeavesPerTimeSeries[0]),5) + allFMTSLeavesPerCommonSupport=MEDFileAnyTypeFieldMultiTS.SplitPerCommonSupport(allFMTSLeavesPerTimeSeries[0],ms[ms.getMeshesNames()[0]]) + self.assertEqual(len(allFMTSLeavesPerCommonSupport),3) + self.assertEqual(len(allFMTSLeavesPerCommonSupport[0][0]),2) + self.assertEqual(len(allFMTSLeavesPerCommonSupport[1][0]),2) + self.assertEqual(len(allFMTSLeavesPerCommonSupport[2][0]),1) + # + mst=MEDFileMeshStruct.New(ms[0]) + # + fcscp=allFMTSLeavesPerCommonSupport[0][1] + mml=fcscp.buildFromScratchDataSetSupport(0,fields) + mml2=mml.prepare() + (a,b),c=mml2.buildVTUArrays() + self.assertTrue(c)# c is True here because the returned array is directly those coming from internal structure + self.assertTrue(a.isEqual(coordsX,1e-12)) + self.assertTrue(b.isEqual(coordsY,1e-12)) + self.assertTrue(isinstance(mml2,MEDCMeshMultiLev)) + for i in xrange(1,5): + self.assertTrue((fcscp.isDataSetSupportEqualToThePreviousOne(i,fields))) + pass + a6,a7=mml2.retrieveFamilyIdsOnCells() + self.assertTrue(a6.isEqual(DataArrayInt([0,1,2,3,4,5,6,7]))) + self.assertTrue(a7) # True because no copy + a8,a9=mml2.retrieveNumberIdsOnCells() + self.assertTrue(a8.isEqual(DataArrayInt([100,101,102,103,104,105,106,107]))) + self.assertTrue(a9) # True because no copy + a10,a11=mml2.retrieveNumberIdsOnNodes() + self.assertTrue(a10.isEqual(DataArrayInt([200,201,202,203,204,205,206,207,208,209,210,211,212,213,214]))) + self.assertTrue(a11) # True because no copy + for i in xrange(5): + f=allFMTSLeavesPerCommonSupport[0][0][0][i] + fsst=MEDFileField1TSStructItem.BuildItemFrom(f,mst) + f.loadArraysIfNecessary() + v=mml.buildDataArray(fsst,fields,f.getUndergroundDataArray()) + self.assertEqual(f.getName(),fieldName0) + self.assertEqual(v.getHiddenCppPointer(),f.getUndergroundDataArray().getHiddenCppPointer()) + vExp=DataArrayDouble(8*2) ; vExp.iota(0+i*1000) ; vExp.rearrange(2) ; vExp.setInfoOnComponents(['Comp1_0 [m]','Com2_0 [s^2]']) + self.assertTrue(v.isEqual(vExp,1e-12)) + # + f=allFMTSLeavesPerCommonSupport[0][0][1][i] + fsst=MEDFileField1TSStructItem.BuildItemFrom(f,mst) + f.loadArraysIfNecessary() + v=mml.buildDataArray(fsst,fields,f.getUndergroundDataArray()) + self.assertEqual(f.getName(),fieldName4) + self.assertEqual(v.getHiddenCppPointer(),f.getUndergroundDataArray().getHiddenCppPointer()) + vExp=DataArrayDouble(15*2) ; vExp.iota(400+i*1000) ; vExp.rearrange(2) ; vExp.setInfoOnComponents(['Comp1_4 [m]','Com2_4 [s^2]']) + self.assertTrue(v.isEqual(vExp,1e-12)) + pass + + fcscp=allFMTSLeavesPerCommonSupport[1][1] + mml=fcscp.buildFromScratchDataSetSupport(0,fields) + mml2=mml.prepare() + self.assertTrue(isinstance(mml2,MEDCMeshMultiLev)) # here the 2nd support is a part of CMesh that is also a CMesh -> CMesh not a UMesh + (a,b),c=mml2.buildVTUArrays() + self.assertTrue(not c)# c is False because this a sub support specialy built for buildVTUArrays + self.assertTrue(a.isEqual(coordsX[[2,3,4]],1e-12)) + self.assertTrue(b.isEqual(coordsY,1e-12)) + a6,a7=mml2.retrieveFamilyIdsOnCells() + self.assertTrue(a6.isEqual(DataArrayInt([2,3,6,7]))) + self.assertTrue(not a7) # False because copy + a8,a9=mml2.retrieveNumberIdsOnCells() + self.assertTrue(a8.isEqual(DataArrayInt([102,103,106,107]))) + self.assertTrue(not a9) # False because copy + a10,a11=mml2.retrieveNumberIdsOnNodes() + self.assertTrue(a10.isEqual(DataArrayInt([202,203,204,207,208,209,212,213,214]))) + self.assertTrue(not a11) # False because copy + for i in xrange(1,5): + self.assertTrue((fcscp.isDataSetSupportEqualToThePreviousOne(i,fields))) + pass + for i in xrange(5): + f=allFMTSLeavesPerCommonSupport[1][0][0][i] + fsst=MEDFileField1TSStructItem.BuildItemFrom(f,mst) + f.loadArraysIfNecessary() + v=mml.buildDataArray(fsst,fields,f.getUndergroundDataArray()) + self.assertEqual(f.getName(),fieldName1) + self.assertEqual(v.getHiddenCppPointer(),f.getUndergroundDataArray().getHiddenCppPointer()) + vExp=DataArrayDouble(4*2) ; vExp.iota(100+i*1000) ; vExp.rearrange(2) ; vExp.setInfoOnComponents(['Comp1_1 [m]','Com2_1 [s^2]']) + self.assertTrue(v.isEqual(vExp,1e-12)) + # + f=allFMTSLeavesPerCommonSupport[1][0][1][i] + fsst=MEDFileField1TSStructItem.BuildItemFrom(f,mst) + f.loadArraysIfNecessary() + v=mml.buildDataArray(fsst,fields,f.getUndergroundDataArray()) + self.assertEqual(f.getName(),fieldName2) + self.assertEqual(v.getHiddenCppPointer(),f.getUndergroundDataArray().getHiddenCppPointer()) + vExp=DataArrayDouble(9*2) ; vExp.iota(200+i*1000) ; vExp.rearrange(2) ; vExp.setInfoOnComponents(['Comp1_2 [m]','Com2_2 [s^2]']) + self.assertTrue(v.isEqual(vExp,1e-12)) + pass + # + fcscp=allFMTSLeavesPerCommonSupport[2][1] + mml=fcscp.buildFromScratchDataSetSupport(0,fields) + mml2=mml.prepare() + self.assertTrue(isinstance(mml2,MEDUMeshMultiLev)) # here the 3rd support is a part of CMesh but impossible to simplify more than a UMesh + ncc,a0,a1,a2,a3,a4,a5=mml2.buildVTUArrays() + self.assertTrue(not ncc) + a0Exp=DataArrayDouble([0.,0.,1.1,0.,2.2,0.,3.3,0.,4.4,0.,0.,1.7,1.1,1.7,2.2,1.7,3.3,1.7,4.4,1.7,0.,3.4,1.1,3.4,2.2,3.4,3.3,3.4,4.4,3.4],15,2) + a0Exp.setInfoOnComponents(["XX [m]","YYY [km]"]) + self.assertTrue(a0.isEqual(a0Exp.changeNbOfComponents(3,0.),1e-12)) + self.assertTrue(a1.isEqual(DataArrayByte([9,9,9,9]))) + self.assertTrue(a2.isEqual(DataArrayInt([0,5,10,15]))) + self.assertTrue(a3.isEqual(DataArrayInt([4,3,2,7,8,4,4,3,8,9,4,7,6,11,12,4,9,8,13,14]))) + self.assertTrue(a4 is None) + self.assertTrue(a5 is None) + a6,a7=mml2.retrieveFamilyIdsOnCells() + self.assertTrue(a6.isEqual(DataArrayInt([2,3,5,7]))) + self.assertTrue(not a7) # False because copy + a8,a9=mml2.retrieveNumberIdsOnCells() + self.assertTrue(a8.isEqual(DataArrayInt([102,103,105,107]))) + self.assertTrue(not a9) # False because copy + for i in xrange(5): + f=allFMTSLeavesPerCommonSupport[2][0][0][i] + fsst=MEDFileField1TSStructItem.BuildItemFrom(f,mst) + f.loadArraysIfNecessary() + v=mml.buildDataArray(fsst,fields,f.getUndergroundDataArray()) + self.assertEqual(f.getName(),fieldName3) + self.assertEqual(v.getHiddenCppPointer(),f.getUndergroundDataArray().getHiddenCppPointer()) + vExp=DataArrayDouble(4*2) ; vExp.iota(300+i*1000) ; vExp.rearrange(2) ; vExp.setInfoOnComponents(['Comp1_3 [m]','Com2_3 [s^2]']) + self.assertTrue(v.isEqual(vExp,1e-12)) + pass + pass + + def test7(self): + """ This test plays with curvilinear mesh and profiles. When a sub curvilinear mesh can also be considered as a cartesian mesh it is done. + This test is very similar to the test6. + """ + fname="ForMEDReader7.med" + m=MEDCouplingCurveLinearMesh("mesh") ; m.setNodeGridStructure([5,3]) + a0Exp=DataArrayDouble([0.,0.,1.1,0.,2.2,0.,3.3,0.,4.4,0.,0.,1.7,1.1,1.7,2.2,1.7,3.3,1.7,4.4,1.7,0.,3.4,1.1,3.4,2.2,3.4,3.3,3.4,4.4,3.4],15,2) + a0Exp.setInfoOnComponents(["XX [m]","YYY [km]"]) + m.setCoords(a0Exp) + mm=MEDFileCurveLinearMesh() ; mm.setMesh(m) + fam=DataArrayInt(8) ; fam.iota(0) ; mm.setFamilyFieldArr(0,fam) ; del fam + num=DataArrayInt(8) ; num.iota(100) ; mm.setRenumFieldArr(0,num) ; del num + # + fieldName0="zeField0" ; # on cells + fieldName1="zeField1" ; pfl1=DataArrayInt([2,3,6,7]) ; pfl1.setName("pfl1") # on cells + fieldName2="zeField2" ; pfl2=DataArrayInt([2,3,4,7,8,9,12,13,14]) ; pfl2.setName("pfl2") # on nodes + fieldName3="zeField3" ; pfl3=DataArrayInt([2,3,5,7]) ; pfl3.setName("pfl3") # on cells but different support + fieldName4="zeField4" ;# on nodes + fs0=MEDFileFieldMultiTS() ; fs1=MEDFileFieldMultiTS() ; fs2=MEDFileFieldMultiTS() ; fs3=MEDFileFieldMultiTS() ; fs4=MEDFileFieldMultiTS() + # + for i in xrange(5): + f=MEDFileField1TS() + fNode=MEDCouplingFieldDouble(ON_CELLS) ; fNode.setTime(float(i),i,0) + fNode.setName(fieldName0) ; fNode.setMesh(m) + arr=DataArrayDouble(2*8) ; arr.iota(0+1000*i) ; arr.rearrange(2) + fNode.setArray(arr) ; arr.setInfoOnComponents(["Comp1_0 [m]","Com2_0 [s^2]"]) ; fNode.checkCoherency() + f.setFieldNoProfileSBT(fNode) + fs0.pushBackTimeStep(f) + # + f=MEDFileField1TS() + fNode=MEDCouplingFieldDouble(ON_CELLS) ; fNode.setTime(float(i),i,0) + fNode.setName(fieldName1) + arr=DataArrayDouble(2*4) ; arr.iota(100+1000*i) ; arr.rearrange(2) + fNode.setArray(arr) ; arr.setInfoOnComponents(["Comp1_1 [m]","Com2_1 [s^2]"]) + f.setFieldProfile(fNode,mm,0,pfl1) + self.assertEqual(pfl1.getName(),"pfl1") + fs1.pushBackTimeStep(f) + # + f=MEDFileField1TS() + fNode=MEDCouplingFieldDouble(ON_NODES) ; fNode.setTime(float(i),i,0) + fNode.setName(fieldName2) + arr=DataArrayDouble(2*9) ; arr.iota(200+1000*i) ; arr.rearrange(2) + fNode.setArray(arr) ; arr.setInfoOnComponents(["Comp1_2 [m]","Com2_2 [s^2]"]) + f.setFieldProfile(fNode,mm,0,pfl2) + self.assertEqual(pfl2.getName(),"pfl2") + fs2.pushBackTimeStep(f) + # + f=MEDFileField1TS() + fNode=MEDCouplingFieldDouble(ON_CELLS) ; fNode.setTime(float(i),i,0) + fNode.setName(fieldName3) + arr=DataArrayDouble(2*4) ; arr.iota(300+1000*i) ; arr.rearrange(2) + fNode.setArray(arr) ; arr.setInfoOnComponents(["Comp1_3 [m]","Com2_3 [s^2]"]) + f.setFieldProfile(fNode,mm,0,pfl3) + self.assertEqual(pfl3.getName(),"pfl3") + fs3.pushBackTimeStep(f) + # + f=MEDFileField1TS() + fNode=MEDCouplingFieldDouble(ON_NODES) ; fNode.setTime(float(i),i,0) + fNode.setName(fieldName4) ; fNode.setMesh(m) + arr=DataArrayDouble(2*15) ; arr.iota(400+1000*i) ; arr.rearrange(2) + fNode.setArray(arr) ; arr.setInfoOnComponents(["Comp1_4 [m]","Com2_4 [s^2]"]) ; fNode.checkCoherency() + f.setFieldNoProfileSBT(fNode) + fs4.pushBackTimeStep(f) + pass + mm.write(fname,2) + fs0.write(fname,0) ; fs1.write(fname,0) ; fs2.write(fname,0) ; fs3.write(fname,0) ; fs4.write(fname,0) + del m,mm,fs1,fs2,fs3,f,fNode + ########## GO for reading in MEDReader,by not loading all. Mesh is fully loaded but not fields values + ms=MEDFileMeshes(fname) + fields=MEDFileFields(fname,False) + fields.removeFieldsWithoutAnyTimeStep() + fields_per_mesh=[fields.partOfThisLyingOnSpecifiedMeshName(meshName) for meshName in ms.getMeshesNames()] + allFMTSLeavesToDisplay=[] + for fields in fields_per_mesh: + allFMTSLeavesToDisplay2=[] + for fmts in fields: + tmp=fmts.splitDiscretizations() + for itmp in tmp: + self.assertTrue(not itmp.presenceOfMultiDiscPerGeoType()) + pass + allFMTSLeavesToDisplay2+=tmp + pass + allFMTSLeavesToDisplay.append(allFMTSLeavesToDisplay2) + pass + self.assertEqual(len(allFMTSLeavesToDisplay),1) + self.assertEqual(len(allFMTSLeavesToDisplay[0]),5) + allFMTSLeavesPerTimeSeries=MEDFileAnyTypeFieldMultiTS.SplitIntoCommonTimeSeries(sum(allFMTSLeavesToDisplay,[])) + self.assertEqual(len(allFMTSLeavesPerTimeSeries),1) # one time serie here : because the 5 fields are defined on the same time steps + self.assertEqual(len(allFMTSLeavesPerTimeSeries[0]),5) + allFMTSLeavesPerCommonSupport=MEDFileAnyTypeFieldMultiTS.SplitPerCommonSupport(allFMTSLeavesPerTimeSeries[0],ms[ms.getMeshesNames()[0]]) + self.assertEqual(len(allFMTSLeavesPerCommonSupport),3) + self.assertEqual(len(allFMTSLeavesPerCommonSupport[0][0]),2) + self.assertEqual(len(allFMTSLeavesPerCommonSupport[1][0]),2) + self.assertEqual(len(allFMTSLeavesPerCommonSupport[2][0]),1) + # + mst=MEDFileMeshStruct.New(ms[0]) + # + fcscp=allFMTSLeavesPerCommonSupport[0][1] + mml=fcscp.buildFromScratchDataSetSupport(0,fields) + mml2=mml.prepare() + self.assertTrue(isinstance(mml2,MEDCurveLinearMeshMultiLev)) + a,b,c=mml2.buildVTUArrays() + self.assertTrue(c)#True here because a is directly coming from internal data without copy + self.assertTrue(a.isEqual(a0Exp,1e-12)) + self.assertEqual(b,[5,3]) + a6,a7=mml2.retrieveFamilyIdsOnCells() + self.assertTrue(a6.isEqual(DataArrayInt([0,1,2,3,4,5,6,7]))) + self.assertTrue(a7) # True because no copy + a8,a9=mml2.retrieveNumberIdsOnCells() + self.assertTrue(a8.isEqual(DataArrayInt([100,101,102,103,104,105,106,107]))) + self.assertTrue(a9) # True because no copy + for i in xrange(1,5): + self.assertTrue((fcscp.isDataSetSupportEqualToThePreviousOne(i,fields))) + pass + for i in xrange(5): + f=allFMTSLeavesPerCommonSupport[0][0][0][i] + fsst=MEDFileField1TSStructItem.BuildItemFrom(f,mst) + f.loadArraysIfNecessary() + v=mml.buildDataArray(fsst,fields,f.getUndergroundDataArray()) + self.assertEqual(f.getName(),fieldName0) + self.assertEqual(v.getHiddenCppPointer(),f.getUndergroundDataArray().getHiddenCppPointer()) + vExp=DataArrayDouble(8*2) ; vExp.iota(0+i*1000) ; vExp.rearrange(2) ; vExp.setInfoOnComponents(['Comp1_0 [m]','Com2_0 [s^2]']) + self.assertTrue(v.isEqual(vExp,1e-12)) + # + f=allFMTSLeavesPerCommonSupport[0][0][1][i] + fsst=MEDFileField1TSStructItem.BuildItemFrom(f,mst) + f.loadArraysIfNecessary() + v=mml.buildDataArray(fsst,fields,f.getUndergroundDataArray()) + self.assertEqual(f.getName(),fieldName4) + self.assertEqual(v.getHiddenCppPointer(),f.getUndergroundDataArray().getHiddenCppPointer()) + vExp=DataArrayDouble(15*2) ; vExp.iota(400+i*1000) ; vExp.rearrange(2) ; vExp.setInfoOnComponents(['Comp1_4 [m]','Com2_4 [s^2]']) + self.assertTrue(v.isEqual(vExp,1e-12)) + pass + # + fcscp=allFMTSLeavesPerCommonSupport[1][1] + mml=fcscp.buildFromScratchDataSetSupport(0,fields) + mml2=mml.prepare() + self.assertTrue(isinstance(mml2,MEDCurveLinearMeshMultiLev)) # here the 2nd support is a part of CMesh that is also a CMesh -> CMesh not a UMesh + a,b,c=mml2.buildVTUArrays() + self.assertTrue(not c)#False here because a is the result of a computation not the internal strucutre + self.assertTrue(a.isEqual(a0Exp[pfl2],1e-12)) + self.assertEqual(b,[3,3]) + a6,a7=mml2.retrieveFamilyIdsOnCells() + self.assertTrue(a6.isEqual(DataArrayInt([2,3,6,7]))) + self.assertTrue(not a7) # False because copy + a8,a9=mml2.retrieveNumberIdsOnCells() + self.assertTrue(a8.isEqual(DataArrayInt([102,103,106,107]))) + self.assertTrue(not a9) # False because copy + for i in xrange(1,5): + self.assertTrue((fcscp.isDataSetSupportEqualToThePreviousOne(i,fields))) + pass + for i in xrange(5): + f=allFMTSLeavesPerCommonSupport[1][0][0][i] + fsst=MEDFileField1TSStructItem.BuildItemFrom(f,mst) + f.loadArraysIfNecessary() + v=mml.buildDataArray(fsst,fields,f.getUndergroundDataArray()) + self.assertEqual(f.getName(),fieldName1) + self.assertEqual(v.getHiddenCppPointer(),f.getUndergroundDataArray().getHiddenCppPointer()) + vExp=DataArrayDouble(4*2) ; vExp.iota(100+i*1000) ; vExp.rearrange(2) ; vExp.setInfoOnComponents(['Comp1_1 [m]','Com2_1 [s^2]']) + self.assertTrue(v.isEqual(vExp,1e-12)) + # + f=allFMTSLeavesPerCommonSupport[1][0][1][i] + fsst=MEDFileField1TSStructItem.BuildItemFrom(f,mst) + f.loadArraysIfNecessary() + v=mml.buildDataArray(fsst,fields,f.getUndergroundDataArray()) + self.assertEqual(f.getName(),fieldName2) + self.assertEqual(v.getHiddenCppPointer(),f.getUndergroundDataArray().getHiddenCppPointer()) + vExp=DataArrayDouble(9*2) ; vExp.iota(200+i*1000) ; vExp.rearrange(2) ; vExp.setInfoOnComponents(['Comp1_2 [m]','Com2_2 [s^2]']) + self.assertTrue(v.isEqual(vExp,1e-12)) + pass + # + fcscp=allFMTSLeavesPerCommonSupport[2][1] + mml=fcscp.buildFromScratchDataSetSupport(0,fields) + mml2=mml.prepare() + self.assertTrue(isinstance(mml2,MEDUMeshMultiLev)) # here the 3rd support is a part of CMesh but impossible to simplify more than a UMesh + ncc,a0,a1,a2,a3,a4,a5=mml2.buildVTUArrays() + self.assertTrue(not ncc) + a0Exp=DataArrayDouble([0.,0.,1.1,0.,2.2,0.,3.3,0.,4.4,0.,0.,1.7,1.1,1.7,2.2,1.7,3.3,1.7,4.4,1.7,0.,3.4,1.1,3.4,2.2,3.4,3.3,3.4,4.4,3.4],15,2) + a0Exp.setInfoOnComponents(["XX [m]","YYY [km]"]) + self.assertTrue(a0.isEqual(a0Exp.changeNbOfComponents(3,0.),1e-12)) + self.assertTrue(a1.isEqual(DataArrayByte([9,9,9,9]))) + self.assertTrue(a2.isEqual(DataArrayInt([0,5,10,15]))) + self.assertTrue(a3.isEqual(DataArrayInt([4,3,2,7,8,4,4,3,8,9,4,7,6,11,12,4,9,8,13,14]))) + self.assertTrue(a4 is None) + self.assertTrue(a5 is None) + a6,a7=mml2.retrieveFamilyIdsOnCells() + self.assertTrue(a6.isEqual(DataArrayInt([2,3,5,7]))) + self.assertTrue(not a7) # False because copy + a8,a9=mml2.retrieveNumberIdsOnCells() + self.assertTrue(a8.isEqual(DataArrayInt([102,103,105,107]))) + self.assertTrue(not a9) # False because copy + for i in xrange(5): + f=allFMTSLeavesPerCommonSupport[2][0][0][i] + fsst=MEDFileField1TSStructItem.BuildItemFrom(f,mst) + f.loadArraysIfNecessary() + v=mml.buildDataArray(fsst,fields,f.getUndergroundDataArray()) + self.assertEqual(f.getName(),fieldName3) + self.assertEqual(v.getHiddenCppPointer(),f.getUndergroundDataArray().getHiddenCppPointer()) + vExp=DataArrayDouble(4*2) ; vExp.iota(300+i*1000) ; vExp.rearrange(2) ; vExp.setInfoOnComponents(['Comp1_3 [m]','Com2_3 [s^2]']) + self.assertTrue(v.isEqual(vExp,1e-12)) + pass + pass + + def test8(self): + """ This test plays with with gauss fields with no profiles. + """ + fname="ForMEDReader8.med" + # building a mesh containing 6 tri3 + 5 quad4 + m=MEDCouplingUMesh("mesh",2) + coords=DataArrayDouble([(0,0),(1,0),(2,0),(3,0),(4,0),(0,1),(1,1),(2,1),(3,1),(4,1),(0,2),(1,2),(2,2),(3,2),(4,2)]) ; coords.setInfoOnComponents(["XX [m]","YYY [km]"]) + m.setCoords(coords) + m.allocateCells() + m.insertNextCell(NORM_TRI3,[2,7,3]) ; m.insertNextCell(NORM_TRI3,[7,8,3]) ; m.insertNextCell(NORM_TRI3,[3,8,4]) ; m.insertNextCell(NORM_TRI3,[8,9,4]) + m.insertNextCell(NORM_TRI3,[13,9,8]) ; m.insertNextCell(NORM_TRI3,[13,14,9]) + m.insertNextCell(NORM_QUAD4,[0,5,6,1]) ; m.insertNextCell(NORM_QUAD4,[1,6,7,2]) ; m.insertNextCell(NORM_QUAD4,[5,10,11,6]) ; m.insertNextCell(NORM_QUAD4,[6,11,12,7]) + m.insertNextCell(NORM_QUAD4,[12,13,8,7]) + mm=MEDFileUMesh() ; mm.setMeshes([m]) + # + fieldName0="zeField0" + fieldName1="zeField1" + fieldName2="zeField2" + fieldName3="zeField3" + fs0=MEDFileFieldMultiTS() ; fs1=MEDFileFieldMultiTS() ; fs2=MEDFileFieldMultiTS() ; fs3=MEDFileFieldMultiTS() + for i in xrange(5): + f=MEDFileField1TS() + fNode=MEDCouplingFieldDouble(ON_GAUSS_NE) ; fNode.setTime(float(i),i,0) + fNode.setName(fieldName0) ; fNode.setMesh(m) + arr=DataArrayDouble(2*38) ; arr.iota(0+1000*i) ; arr.rearrange(2) + fNode.setArray(arr) ; arr.setInfoOnComponents(["Comp1_0 [m]","Com2_0 [s^2]"]) ; fNode.checkCoherency() + f.setFieldNoProfileSBT(fNode) + fs0.pushBackTimeStep(f) + # + f=MEDFileField1TS() + fNode=MEDCouplingFieldDouble(ON_CELLS) ; fNode.setTime(float(i),i,0) + fNode.setName(fieldName1) ; fNode.setMesh(m) + arr=DataArrayDouble(2*11) ; arr.iota(100+1000*i) ; arr.rearrange(2) + fNode.setArray(arr) ; arr.setInfoOnComponents(["Comp1_1 [m]","Com2_1 [s^2]"]) ; fNode.checkCoherency() + f.setFieldNoProfileSBT(fNode) + fs1.pushBackTimeStep(f) + # + f=MEDFileField1TS() + fNode=MEDCouplingFieldDouble(ON_GAUSS_PT) ; fNode.setTime(float(i),i,0) + fNode.setName(fieldName2) ; fNode.setMesh(m) + fNode.setGaussLocalizationOnCells([0,1,2,3],[0.,0.,1.,0.,0.,1.],[0.5,0.5,0.7,0.7],[0.8,0.2]) + fNode.setGaussLocalizationOnCells([4,5],[0.,0.,1.,0.,0.,1.],[0.5,0.5,0.7,0.7,0.1,0.1,0.2,0.2,0.3,0.3],[0.8,0.05,0.1,0.04,0.01]) + fNode.setGaussLocalizationOnCells([6,7,8],[-1.,-1.,1.,-1.,1.,1.,-1.,1.],[0.5,0.5,0.7,0.7,0.1,0.1,0.2,0.2],[0.8,0.05,0.1,0.04]) + fNode.setGaussLocalizationOnCells([9,10],[-1.,-1.,1.,-1.,1.,1.,-1.,1.],[0.5,0.5,0.7,0.7,0.1,0.1,0.2,0.2,0.3,0.3,0.4,0.4,0.8,0.8],[0.8,0.05,0.1,0.01,0.02,0.005,0.005]) + arr=DataArrayDouble(2*(4*2+2*5+3*4+2*7)) ; arr.iota(300+1000*i) ; arr.rearrange(2) + fNode.setArray(arr) ; arr.setInfoOnComponents(["Comp1_2 [m]","Com2_2 [s^2]"]) ; fNode.checkCoherency() + f.setFieldNoProfileSBT(fNode) + fs2.pushBackTimeStep(f) + # + f=MEDFileField1TS() + fNode=MEDCouplingFieldDouble(ON_NODES) ; fNode.setTime(float(i),i,0) + fNode.setName(fieldName3) ; fNode.setMesh(m) + arr=DataArrayDouble(2*15) ; arr.iota(400+1000*i) ; arr.rearrange(2) + fNode.setArray(arr) ; arr.setInfoOnComponents(["Comp1_3 [m]","Com2_3 [s^2]"]) ; fNode.checkCoherency() + f.setFieldNoProfileSBT(fNode) + fs3.pushBackTimeStep(f) + # + pass + # + mm.write(fname,2) + fs0.write(fname,0) ; fs1.write(fname,0) ; fs2.write(fname,0) ; fs3.write(fname,0) + a0Exp=mm.getCoords().deepCpy() + del m,mm,fs1,fs2,fs3,f,fNode + ########## GO for reading in MEDReader,by not loading all. Mesh is fully loaded but not fields values + ms=MEDFileMeshes(fname) + fields=MEDFileFields(fname,False) + fields.removeFieldsWithoutAnyTimeStep() + fields_per_mesh=[fields.partOfThisLyingOnSpecifiedMeshName(meshName) for meshName in ms.getMeshesNames()] + allFMTSLeavesToDisplay=[] + for fields in fields_per_mesh: + allFMTSLeavesToDisplay2=[] + for fmts in fields: + tmp=fmts.splitDiscretizations() + #for itmp in tmp: + # self.assertTrue(not itmp.presenceOfMultiDiscPerGeoType()) + # pass + allFMTSLeavesToDisplay2+=tmp + pass + allFMTSLeavesToDisplay.append(allFMTSLeavesToDisplay2) + pass + self.assertEqual(len(allFMTSLeavesToDisplay),1) + self.assertEqual(len(allFMTSLeavesToDisplay[0]),4) + allFMTSLeavesPerTimeSeries=MEDFileAnyTypeFieldMultiTS.SplitIntoCommonTimeSeries(sum(allFMTSLeavesToDisplay,[])) + self.assertEqual(len(allFMTSLeavesPerTimeSeries),1) # one time serie here : because the 4 fields are defined on the same time steps + self.assertEqual(len(allFMTSLeavesPerTimeSeries[0]),4) + allFMTSLeavesPerCommonSupport=MEDFileAnyTypeFieldMultiTS.SplitPerCommonSupport(allFMTSLeavesPerTimeSeries[0],ms[ms.getMeshesNames()[0]]) + self.assertEqual(len(allFMTSLeavesPerCommonSupport),1) + self.assertEqual(len(allFMTSLeavesPerCommonSupport[0][0]),4) + # + mst=MEDFileMeshStruct.New(ms[0]) + # + fcscp=allFMTSLeavesPerCommonSupport[0][1] + mml=fcscp.buildFromScratchDataSetSupport(0,fields) + mml2=mml.prepare() + self.assertTrue(isinstance(mml2,MEDUMeshMultiLev)) + ncc,a0,a1,a2,a3,a4,a5=mml2.buildVTUArrays() + self.assertTrue(not ncc) + self.assertTrue(a0.isEqual(a0Exp.changeNbOfComponents(3,0.),1e-12)) + self.assertTrue(a1.isEqual(DataArrayByte([5,5,5,5,5,5,9,9,9,9,9]))) + self.assertTrue(a2.isEqual(DataArrayInt([0,4,8,12,16,20,24,29,34,39,44]))) + self.assertTrue(a3.isEqual(DataArrayInt([3,2,7,3,3,7,8,3,3,3,8,4,3,8,9,4,3,13,9,8,3,13,14,9,4,0,5,6,1,4,1,6,7,2,4,5,10,11,6,4,6,11,12,7,4,12,13,8,7]))) + self.assertTrue(a4 is None) + self.assertTrue(a5 is None) + for i in xrange(1,5): + self.assertTrue((fcscp.isDataSetSupportEqualToThePreviousOne(i,fields))) + pass + for i in xrange(5): + f=allFMTSLeavesPerCommonSupport[0][0][0][i] + fsst=MEDFileField1TSStructItem.BuildItemFrom(f,mst) + f.loadArraysIfNecessary() + v=mml.buildDataArray(fsst,fields,f.getUndergroundDataArray()) + self.assertEqual(f.getName(),fieldName0) + self.assertEqual(v.getHiddenCppPointer(),f.getUndergroundDataArray().getHiddenCppPointer()) + vExp=DataArrayDouble(38*2) ; vExp.iota(0+i*1000) ; vExp.rearrange(2) ; vExp.setInfoOnComponents(['Comp1_0 [m]','Com2_0 [s^2]']) + self.assertTrue(v.isEqual(vExp,1e-12)) + # + f=allFMTSLeavesPerCommonSupport[0][0][1][i] + fsst=MEDFileField1TSStructItem.BuildItemFrom(f,mst) + f.loadArraysIfNecessary() + v=mml.buildDataArray(fsst,fields,f.getUndergroundDataArray()) + self.assertEqual(f.getName(),fieldName1) + self.assertEqual(v.getHiddenCppPointer(),f.getUndergroundDataArray().getHiddenCppPointer()) + vExp=DataArrayDouble(11*2) ; vExp.iota(100+i*1000) ; vExp.rearrange(2) ; vExp.setInfoOnComponents(['Comp1_1 [m]','Com2_1 [s^2]']) + self.assertTrue(v.isEqual(vExp,1e-12)) + # + f=allFMTSLeavesPerCommonSupport[0][0][2][i] + fsst=MEDFileField1TSStructItem.BuildItemFrom(f,mst) + f.loadArraysIfNecessary() + v=mml.buildDataArray(fsst,fields,f.getUndergroundDataArray()) + self.assertEqual(f.getName(),fieldName2) + #self.assertEqual(v.getHiddenCppPointer(),f.getUndergroundDataArray().getHiddenCppPointer()) # not a bug + vExp=DataArrayDouble(44*2) ; vExp.iota(300+i*1000) ; vExp.rearrange(2) ; vExp.setInfoOnComponents(['Comp1_2 [m]','Com2_2 [s^2]']) + self.assertTrue(v.isEqual(vExp,1e-12)) + # + f=allFMTSLeavesPerCommonSupport[0][0][3][i] + fsst=MEDFileField1TSStructItem.BuildItemFrom(f,mst) + f.loadArraysIfNecessary() + v=mml.buildDataArray(fsst,fields,f.getUndergroundDataArray()) + self.assertEqual(f.getName(),fieldName3) + self.assertEqual(v.getHiddenCppPointer(),f.getUndergroundDataArray().getHiddenCppPointer()) + vExp=DataArrayDouble(15*2) ; vExp.iota(400+i*1000) ; vExp.rearrange(2) ; vExp.setInfoOnComponents(['Comp1_3 [m]','Com2_3 [s^2]']) + self.assertTrue(v.isEqual(vExp,1e-12)) + pass + # + pass + + def test9(self): + """ This test plays with with gauss fields with profiles. + """ + fname="ForMEDReader9.med" + # building a mesh containing 6 tri3 + 5 quad4 + m=MEDCouplingUMesh("mesh",2) + coords=DataArrayDouble([(0,0),(1,0),(2,0),(3,0),(4,0),(0,1),(1,1),(2,1),(3,1),(4,1),(0,2),(1,2),(2,2),(3,2),(4,2)]) ; coords.setInfoOnComponents(["XX [m]","YYY [km]"]) + m.setCoords(coords) + m.allocateCells() + m.insertNextCell(NORM_TRI3,[2,7,3]) ; m.insertNextCell(NORM_TRI3,[7,8,3]) ; m.insertNextCell(NORM_TRI3,[3,8,4]) ; m.insertNextCell(NORM_TRI3,[8,9,4]) + m.insertNextCell(NORM_TRI3,[13,9,8]) ; m.insertNextCell(NORM_TRI3,[13,14,9]) + m.insertNextCell(NORM_QUAD4,[0,5,6,1]) ; m.insertNextCell(NORM_QUAD4,[1,6,7,2]) ; m.insertNextCell(NORM_QUAD4,[5,10,11,6]) ; m.insertNextCell(NORM_QUAD4,[6,11,12,7]) + m.insertNextCell(NORM_QUAD4,[12,13,8,7]) + mm=MEDFileUMesh() ; mm.setMeshes([m]) + # + fieldName0="zeField0" + fieldName1="zeField1" + fieldName2="zeField2" + fieldName3="zeField3" + pfl1=DataArrayInt([0,1,7,9,10]) ; pfl1.setName("pfl1") # on cells + pfl2=DataArrayInt([1,2,3,6,7,8,11,12,13]) ; pfl2.setName("pfl2") # on nodes + fs0=MEDFileFieldMultiTS() ; fs1=MEDFileFieldMultiTS() ; fs2=MEDFileFieldMultiTS() ; fs3=MEDFileFieldMultiTS() + for i in xrange(5): + f=MEDFileField1TS() + fNode=MEDCouplingFieldDouble(ON_GAUSS_NE) ; fNode.setTime(float(i),i,0) + fNode.setName(fieldName0) + arr=DataArrayDouble(2*18) ; arr.iota(0+1000*i) ; arr.rearrange(2) + fNode.setArray(arr) ; arr.setInfoOnComponents(["Comp1_0 [m]","Com2_0 [s^2]"]) + f.setFieldProfile(fNode,mm,0,pfl1) + fs0.pushBackTimeStep(f) + # + f=MEDFileField1TS() + fNode=MEDCouplingFieldDouble(ON_CELLS) ; fNode.setTime(float(i),i,0) + fNode.setName(fieldName1) + arr=DataArrayDouble(2*5) ; arr.iota(100+1000*i) ; arr.rearrange(2) + fNode.setArray(arr) ; arr.setInfoOnComponents(["Comp1_1 [m]","Com2_1 [s^2]"]) + f.setFieldProfile(fNode,mm,0,pfl1) + fs1.pushBackTimeStep(f) + # + f=MEDFileField1TS() + fNode=MEDCouplingFieldDouble(ON_GAUSS_PT) ; fNode.setTime(float(i),i,0) + fNode.setName(fieldName2) ; fNode.setMesh(m[pfl1]) + fNode.setGaussLocalizationOnCells([0],[0.,0.,1.,0.,0.,1.],[0.5,0.5,0.7,0.7],[0.8,0.2]) + fNode.setGaussLocalizationOnCells([1],[0.,0.,1.,0.,0.,1.],[0.5,0.5,0.7,0.7,0.1,0.1,0.2,0.2,0.3,0.3],[0.8,0.05,0.1,0.04,0.01]) + fNode.setGaussLocalizationOnCells([2,3],[-1.,-1.,1.,-1.,1.,1.,-1.,1.],[0.5,0.5,0.7,0.7,0.1,0.1,0.2,0.2],[0.8,0.05,0.1,0.04]) + fNode.setGaussLocalizationOnCells([4],[-1.,-1.,1.,-1.,1.,1.,-1.,1.],[0.5,0.5,0.7,0.7,0.1,0.1,0.2,0.2,0.3,0.3,0.4,0.4,0.8,0.8],[0.8,0.05,0.1,0.01,0.02,0.005,0.005]) + arr=DataArrayDouble(2*(2*1+5*1+4*2+7*1)) ; arr.iota(300+1000*i) ; arr.rearrange(2) + fNode.setArray(arr) ; arr.setInfoOnComponents(["Comp1_2 [m]","Com2_2 [s^2]"]) ; fNode.checkCoherency() + f.setFieldProfile(fNode,mm,0,pfl1) + fs2.pushBackTimeStep(f) + # + f=MEDFileField1TS() + fNode=MEDCouplingFieldDouble(ON_NODES) ; fNode.setTime(float(i),i,0) + fNode.setName(fieldName3) + arr=DataArrayDouble(2*9) ; arr.iota(400+1000*i) ; arr.rearrange(2) + fNode.setArray(arr) ; arr.setInfoOnComponents(["Comp1_3 [m]","Com2_3 [s^2]"]) + f.setFieldProfile(fNode,mm,0,pfl2) + fs3.pushBackTimeStep(f) + # + pass + # + mm.write(fname,2) + fs0.write(fname,0) ; fs1.write(fname,0) ; fs2.write(fname,0) ; fs3.write(fname,0) + a0Exp=mm.getCoords().deepCpy() + del m,mm,fs1,fs2,fs3,f,fNode + ########## GO for reading in MEDReader,by not loading all. Mesh is fully loaded but not fields values + ms=MEDFileMeshes(fname) + fields=MEDFileFields(fname,False) + fields.removeFieldsWithoutAnyTimeStep() + fields_per_mesh=[fields.partOfThisLyingOnSpecifiedMeshName(meshName) for meshName in ms.getMeshesNames()] + allFMTSLeavesToDisplay=[] + for fields in fields_per_mesh: + allFMTSLeavesToDisplay2=[] + for fmts in fields: + tmp=fmts.splitDiscretizations() + #for itmp in tmp: + # self.assertTrue(not itmp.presenceOfMultiDiscPerGeoType()) + # pass + allFMTSLeavesToDisplay2+=tmp + pass + allFMTSLeavesToDisplay.append(allFMTSLeavesToDisplay2) + pass + self.assertEqual(len(allFMTSLeavesToDisplay),1) + self.assertEqual(len(allFMTSLeavesToDisplay[0]),4) + allFMTSLeavesPerTimeSeries=MEDFileAnyTypeFieldMultiTS.SplitIntoCommonTimeSeries(sum(allFMTSLeavesToDisplay,[])) + self.assertEqual(len(allFMTSLeavesPerTimeSeries),1) # one time serie here : because the 4 fields are defined on the same time steps + self.assertEqual(len(allFMTSLeavesPerTimeSeries[0]),4) + allFMTSLeavesPerCommonSupport=MEDFileAnyTypeFieldMultiTS.SplitPerCommonSupport(allFMTSLeavesPerTimeSeries[0],ms[ms.getMeshesNames()[0]]) + self.assertEqual(len(allFMTSLeavesPerCommonSupport),1) + self.assertEqual(len(allFMTSLeavesPerCommonSupport[0][0]),4) + # + mst=MEDFileMeshStruct.New(ms[0]) + # + fcscp=allFMTSLeavesPerCommonSupport[0][1] + mml=fcscp.buildFromScratchDataSetSupport(0,fields) + mml2=mml.prepare() + self.assertTrue(isinstance(mml2,MEDUMeshMultiLev)) + ncc,a0,a1,a2,a3,a4,a5=mml2.buildVTUArrays() + self.assertTrue(not ncc) + self.assertTrue(a0.isEqual(a0Exp[pfl2].changeNbOfComponents(3,0.),1e-12)) + self.assertTrue(a1.isEqual(DataArrayByte([5,5,9,9,9]))) + self.assertTrue(a2.isEqual(DataArrayInt([0,4,8,13,18]))) + self.assertTrue(a3.isEqual(DataArrayInt([3,1,4,2,3,4,5,2,4,0,3,4,1,4,3,6,7,4,4,7,8,5,4]))) + self.assertTrue(a4 is None) + self.assertTrue(a5 is None) + for i in xrange(1,5): + self.assertTrue((fcscp.isDataSetSupportEqualToThePreviousOne(i,fields))) + pass + for i in xrange(5): + f=allFMTSLeavesPerCommonSupport[0][0][0][i] + fsst=MEDFileField1TSStructItem.BuildItemFrom(f,mst) + f.loadArraysIfNecessary() + v=mml.buildDataArray(fsst,fields,f.getUndergroundDataArray()) + self.assertEqual(f.getName(),fieldName0) + self.assertEqual(v.getHiddenCppPointer(),f.getUndergroundDataArray().getHiddenCppPointer()) + vExp=DataArrayDouble(18*2) ; vExp.iota(0+i*1000) ; vExp.rearrange(2) ; vExp.setInfoOnComponents(['Comp1_0 [m]','Com2_0 [s^2]']) + self.assertTrue(v.isEqual(vExp,1e-12)) + # + f=allFMTSLeavesPerCommonSupport[0][0][1][i] + fsst=MEDFileField1TSStructItem.BuildItemFrom(f,mst) + f.loadArraysIfNecessary() + v=mml.buildDataArray(fsst,fields,f.getUndergroundDataArray()) + self.assertEqual(f.getName(),fieldName1) + self.assertEqual(v.getHiddenCppPointer(),f.getUndergroundDataArray().getHiddenCppPointer()) + vExp=DataArrayDouble(5*2) ; vExp.iota(100+i*1000) ; vExp.rearrange(2) ; vExp.setInfoOnComponents(['Comp1_1 [m]','Com2_1 [s^2]']) + self.assertTrue(v.isEqual(vExp,1e-12)) + # + f=allFMTSLeavesPerCommonSupport[0][0][2][i] + fsst=MEDFileField1TSStructItem.BuildItemFrom(f,mst) + f.loadArraysIfNecessary() + v=mml.buildDataArray(fsst,fields,f.getUndergroundDataArray()) + self.assertEqual(f.getName(),fieldName2) + #self.assertEqual(v.getHiddenCppPointer(),f.getUndergroundDataArray().getHiddenCppPointer()) # not a bug + vExp=DataArrayDouble(22*2) ; vExp.iota(300+i*1000) ; vExp.rearrange(2) ; vExp.setInfoOnComponents(['Comp1_2 [m]','Com2_2 [s^2]']) + self.assertTrue(v.isEqual(vExp,1e-12)) + # + f=allFMTSLeavesPerCommonSupport[0][0][3][i] + fsst=MEDFileField1TSStructItem.BuildItemFrom(f,mst) + f.loadArraysIfNecessary() + v=mml.buildDataArray(fsst,fields,f.getUndergroundDataArray()) + self.assertEqual(f.getName(),fieldName3) + self.assertEqual(v.getHiddenCppPointer(),f.getUndergroundDataArray().getHiddenCppPointer()) + vExp=DataArrayDouble(9*2) ; vExp.iota(400+i*1000) ; vExp.rearrange(2) ; vExp.setInfoOnComponents(['Comp1_3 [m]','Com2_3 [s^2]']) + self.assertTrue(v.isEqual(vExp,1e-12)) + pass + pass + + def test10(self): + """ This test plays with fields only on nodes containing profiles. + """ + fname="ForMEDReader10.med" + # building a mesh containing 6 tri3 + 5 quad4 + m=MEDCouplingUMesh("mesh",2) + coords=DataArrayDouble([(0,0),(1,0),(2,0),(3,0),(4,0),(0,1),(1,1),(2,1),(3,1),(4,1),(0,2),(1,2),(2,2),(3,2),(4,2)]) ; coords.setInfoOnComponents(["XX [m]","YYY [km]"]) + m.setCoords(coords) + m.allocateCells() + m.insertNextCell(NORM_TRI3,[2,7,3]) ; m.insertNextCell(NORM_TRI3,[7,8,3]) ; m.insertNextCell(NORM_TRI3,[3,8,4]) ; m.insertNextCell(NORM_TRI3,[8,9,4]) + m.insertNextCell(NORM_TRI3,[13,9,8]) ; m.insertNextCell(NORM_TRI3,[13,14,9]) + m.insertNextCell(NORM_QUAD4,[0,5,6,1]) ; m.insertNextCell(NORM_QUAD4,[1,6,7,2]) ; m.insertNextCell(NORM_QUAD4,[5,10,11,6]) ; m.insertNextCell(NORM_QUAD4,[6,11,12,7]) + m.insertNextCell(NORM_QUAD4,[12,13,8,7]) + mm=MEDFileUMesh() ; mm.setMeshes([m]) + # + fieldName0="zeField0" + fieldName1="zeField1" + fieldName2="zeField2" + pfl1=DataArrayInt([1,2,3,6,7,8,11,12,13]) ; pfl1.setName("pfl1") # on nodes + fs0=MEDFileFieldMultiTS() ; fs1=MEDFileFieldMultiTS() ; fs2=MEDFileFieldMultiTS() + for i in xrange(5): + f=MEDFileField1TS() + fNode=MEDCouplingFieldDouble(ON_NODES) ; fNode.setTime(float(i),i,0) + fNode.setName(fieldName0) + arr=DataArrayDouble(2*9) ; arr.iota(0+1000*i) ; arr.rearrange(2) + fNode.setArray(arr) ; arr.setInfoOnComponents(["Comp1_0 [m]","Com2_0 [s^2]"]) + f.setFieldProfile(fNode,mm,0,pfl1) + fs0.pushBackTimeStep(f) + # + f=MEDFileField1TS() + fNode=MEDCouplingFieldDouble(ON_NODES) ; fNode.setTime(float(i),i,0) + fNode.setName(fieldName1) + arr=DataArrayDouble(2*9) ; arr.iota(100+1000*i) ; arr.rearrange(2) + fNode.setArray(arr) ; arr.setInfoOnComponents(["Comp1_1 [m]","Com2_1 [s^2]"]) + f.setFieldProfile(fNode,mm,0,pfl1) + fs1.pushBackTimeStep(f) + # + f=MEDFileField1TS() + fNode=MEDCouplingFieldDouble(ON_NODES) ; fNode.setTime(float(i),i,0) + fNode.setName(fieldName2) + arr=DataArrayDouble(2*9) ; arr.iota(200+1000*i) ; arr.rearrange(2) + fNode.setArray(arr) ; arr.setInfoOnComponents(["Comp1_2 [m]","Com2_2 [s^2]"]) + f.setFieldProfile(fNode,mm,0,pfl1) + fs2.pushBackTimeStep(f) + # + pass + # + mm.write(fname,2) + fs0.write(fname,0) ; fs1.write(fname,0) ; fs2.write(fname,0) + a0Exp=mm.getCoords().deepCpy() + del m,mm,fs1,fs2,f,fNode + ########## GO for reading in MEDReader,by not loading all. Mesh is fully loaded but not fields values + ms=MEDFileMeshes(fname) + fields=MEDFileFields(fname,False) + fields.removeFieldsWithoutAnyTimeStep() + fields_per_mesh=[fields.partOfThisLyingOnSpecifiedMeshName(meshName) for meshName in ms.getMeshesNames()] + allFMTSLeavesToDisplay=[] + for fields in fields_per_mesh: + allFMTSLeavesToDisplay2=[] + for fmts in fields: + tmp=fmts.splitDiscretizations() + for itmp in tmp: + self.assertTrue(not itmp.presenceOfMultiDiscPerGeoType()) + pass + allFMTSLeavesToDisplay2+=tmp + pass + allFMTSLeavesToDisplay.append(allFMTSLeavesToDisplay2) + pass + self.assertEqual(len(allFMTSLeavesToDisplay),1) + self.assertEqual(len(allFMTSLeavesToDisplay[0]),3) + allFMTSLeavesPerTimeSeries=MEDFileAnyTypeFieldMultiTS.SplitIntoCommonTimeSeries(sum(allFMTSLeavesToDisplay,[])) + self.assertEqual(len(allFMTSLeavesPerTimeSeries),1) # one time serie here : because the 4 fields are defined on the same time steps + self.assertEqual(len(allFMTSLeavesPerTimeSeries[0]),3) + allFMTSLeavesPerCommonSupport=MEDFileAnyTypeFieldMultiTS.SplitPerCommonSupport(allFMTSLeavesPerTimeSeries[0],ms[ms.getMeshesNames()[0]]) + self.assertEqual(len(allFMTSLeavesPerCommonSupport),1) + self.assertEqual(len(allFMTSLeavesPerCommonSupport[0][0]),3) + # + mst=MEDFileMeshStruct.New(ms[0]) + # + fcscp=allFMTSLeavesPerCommonSupport[0][1] + mml=fcscp.buildFromScratchDataSetSupport(0,fields) + mml2=mml.prepare() + self.assertTrue(isinstance(mml2,MEDUMeshMultiLev)) + ncc,a0,a1,a2,a3,a4,a5=mml2.buildVTUArrays() + self.assertTrue(not ncc) + self.assertTrue(a0.isEqual(a0Exp[pfl1].changeNbOfComponents(3,0.),1e-12)) + self.assertTrue(a1.isEqual(DataArrayByte([5,5,9,9,9]))) + self.assertTrue(a2.isEqual(DataArrayInt([0,4,8,13,18]))) + self.assertTrue(a3.isEqual(DataArrayInt([3,1,4,2,3,4,5,2,4,0,3,4,1,4,3,6,7,4,4,7,8,5,4]))) + self.assertTrue(a4 is None) + self.assertTrue(a5 is None) + for i in xrange(1,5): + self.assertTrue((fcscp.isDataSetSupportEqualToThePreviousOne(i,fields))) + pass + for i in xrange(5): + f=allFMTSLeavesPerCommonSupport[0][0][0][i] + fsst=MEDFileField1TSStructItem.BuildItemFrom(f,mst) + f.loadArraysIfNecessary() + v=mml.buildDataArray(fsst,fields,f.getUndergroundDataArray()) + self.assertEqual(f.getName(),fieldName0) + #self.assertEqual(v.getHiddenCppPointer(),f.getUndergroundDataArray().getHiddenCppPointer()) # not a bug + vExp=DataArrayDouble(9*2) ; vExp.iota(0+i*1000) ; vExp.rearrange(2) ; vExp.setInfoOnComponents(['Comp1_0 [m]','Com2_0 [s^2]']) + self.assertTrue(v.isEqual(vExp,1e-12)) + # + f=allFMTSLeavesPerCommonSupport[0][0][1][i] + fsst=MEDFileField1TSStructItem.BuildItemFrom(f,mst) + f.loadArraysIfNecessary() + v=mml.buildDataArray(fsst,fields,f.getUndergroundDataArray()) + self.assertEqual(f.getName(),fieldName1) + #self.assertEqual(v.getHiddenCppPointer(),f.getUndergroundDataArray().getHiddenCppPointer()) # not a bug + vExp=DataArrayDouble(9*2) ; vExp.iota(100+i*1000) ; vExp.rearrange(2) ; vExp.setInfoOnComponents(['Comp1_1 [m]','Com2_1 [s^2]']) + self.assertTrue(v.isEqual(vExp,1e-12)) + # + f=allFMTSLeavesPerCommonSupport[0][0][2][i] + fsst=MEDFileField1TSStructItem.BuildItemFrom(f,mst) + f.loadArraysIfNecessary() + v=mml.buildDataArray(fsst,fields,f.getUndergroundDataArray()) + self.assertEqual(f.getName(),fieldName2) + #self.assertEqual(v.getHiddenCppPointer(),f.getUndergroundDataArray().getHiddenCppPointer()) # not a bug + vExp=DataArrayDouble(9*2) ; vExp.iota(200+i*1000) ; vExp.rearrange(2) ; vExp.setInfoOnComponents(['Comp1_2 [m]','Com2_2 [s^2]']) + self.assertTrue(v.isEqual(vExp,1e-12)) + pass + pass + + def test11(self): + """ This test is the ultimate test for the profiles with gauss points. It tests that even if there is non contiguous parts in definition of gauss points, it works ! + WARNING here, as no other discretizations exists, the priority is given to the field -> the mesh is renumbered to accelerate the build of array of field. + """ + fname="ForMEDReader11.med" + m=MEDCouplingCMesh("mesh") + arr=DataArrayDouble(5) ; arr.iota() + m.setCoords(arr,arr) + m=m.buildUnstructured() ; m.getCoords().setInfoOnComponents(["XX [m]","YYY [km]"]) + mm=MEDFileUMesh() ; mm.setMeshes([m]) + # + fieldName0="zeField0" + fs0=MEDFileFieldMultiTS() + for i in xrange(5): + f=MEDFileField1TS() + fNode=MEDCouplingFieldDouble(ON_GAUSS_PT) ; fNode.setTime(float(i),i,0) + fNode.setName(fieldName0) ; fNode.setMesh(m) + fNode.setGaussLocalizationOnCells([0,2,3,4,7,15],[-1.,-1.,1.,-1.,1.,1.,-1.,1.],[0.5,0.5,0.7,0.7],[0.8,0.2]) + fNode.setGaussLocalizationOnCells([1,5,8,9],[-1.,-1.,1.,-1.,1.,1.,-1.,1.],[0.5,0.5,0.7,0.7,0.1,0.1,0.2,0.2,0.3,0.3],[0.8,0.05,0.1,0.04,0.01]) + fNode.setGaussLocalizationOnCells([6,10,13],[-1.,-1.,1.,-1.,1.,1.,-1.,1.],[0.5,0.5,0.7,0.7,0.1,0.1,0.2,0.2],[0.8,0.05,0.1,0.04]) + fNode.setGaussLocalizationOnCells([11,12,14],[-1.,-1.,1.,-1.,1.,1.,-1.,1.],[0.5,0.5,0.7,0.7,0.1,0.1,0.2,0.2,0.3,0.3,0.4,0.4,0.8,0.8],[0.8,0.05,0.1,0.01,0.02,0.005,0.005]) + arr=DataArrayDouble(2*(2*6+5*4+4*3+7*3)) ; arr.iota(0+1000*i) ; arr.rearrange(2) + fNode.setArray(arr) ; arr.setInfoOnComponents(["Comp1_0 [m]","Com2_0 [s^2]"]) ; fNode.checkCoherency() + f.setFieldNoProfileSBT(fNode) + fs0.pushBackTimeStep(f) + pass + mm.write(fname,2) + fs0.write(fname,0) + a0Exp=mm.getCoords().deepCpy() + del m,mm,fs0,f,fNode + ########## GO for reading in MEDReader,by not loading all. Mesh is fully loaded but not fields values + ms=MEDFileMeshes(fname) + fields=MEDFileFields(fname,False) + fields.removeFieldsWithoutAnyTimeStep() + fields_per_mesh=[fields.partOfThisLyingOnSpecifiedMeshName(meshName) for meshName in ms.getMeshesNames()] + allFMTSLeavesToDisplay=[] + for fields in fields_per_mesh: + allFMTSLeavesToDisplay2=[] + for fmts in fields: + tmp=fmts.splitDiscretizations() + #for itmp in tmp: + # self.assertTrue(not itmp.presenceOfMultiDiscPerGeoType()) + # pass + allFMTSLeavesToDisplay2+=tmp + pass + allFMTSLeavesToDisplay.append(allFMTSLeavesToDisplay2) + pass + self.assertEqual(len(allFMTSLeavesToDisplay),1) + self.assertEqual(len(allFMTSLeavesToDisplay[0]),1) + allFMTSLeavesPerTimeSeries=MEDFileAnyTypeFieldMultiTS.SplitIntoCommonTimeSeries(sum(allFMTSLeavesToDisplay,[])) + self.assertEqual(len(allFMTSLeavesPerTimeSeries),1) # one time serie here : because the 1 field is defined on the same time steps + self.assertEqual(len(allFMTSLeavesPerTimeSeries[0]),1) + allFMTSLeavesPerCommonSupport=MEDFileAnyTypeFieldMultiTS.SplitPerCommonSupport(allFMTSLeavesPerTimeSeries[0],ms[ms.getMeshesNames()[0]]) + self.assertEqual(len(allFMTSLeavesPerCommonSupport),1) + self.assertEqual(len(allFMTSLeavesPerCommonSupport[0][0]),1) + # + mst=MEDFileMeshStruct.New(ms[0]) + # + fcscp=allFMTSLeavesPerCommonSupport[0][1] + mml=fcscp.buildFromScratchDataSetSupport(0,fields) + mml2=mml.prepare() + self.assertTrue(isinstance(mml2,MEDUMeshMultiLev)) + ncc,a0,a1,a2,a3,a4,a5=mml2.buildVTUArrays() + self.assertTrue(not ncc) + self.assertTrue(a0.isEqual(a0Exp.changeNbOfComponents(3,0.),1e-12)) + self.assertTrue(a1.isEqual(DataArrayByte([9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9]))) + self.assertTrue(a2.isEqual(DataArrayInt([0,5,10,15,20,25,30,35,40,45,50,55,60,65,70,75]))) + self.assertTrue(a3.isEqual(DataArrayInt([4,1,0,5,6,4,3,2,7,8,4,4,3,8,9,4,6,5,10,11,4,9,8,13,14,4,19,18,23,24,4,2,1,6,7,4,7,6,11,12,4,11,10,15,16,4,12,11,16,17,4,8,7,12,13,4,13,12,17,18,4,17,16,21,22,4,14,13,18,19,4,16,15,20,21,4,18,17,22,23]))) # <- here the mesh is renumbered : the mesh is equal to m[[0,2,3,4,7,15, 1,5,8,9, 6,10,13, 11,12,14]] + self.assertTrue(a4 is None) + self.assertTrue(a5 is None) + for i in xrange(1,5): + self.assertTrue((fcscp.isDataSetSupportEqualToThePreviousOne(i,fields))) + pass + for i in xrange(5): + f=allFMTSLeavesPerCommonSupport[0][0][0][i] + fsst=MEDFileField1TSStructItem.BuildItemFrom(f,mst) + f.loadArraysIfNecessary() + v=mml.buildDataArray(fsst,fields,f.getUndergroundDataArray()) + self.assertEqual(f.getName(),fieldName0) + self.assertEqual(v.getHiddenCppPointer(),f.getUndergroundDataArray().getHiddenCppPointer()) + vExp=DataArrayDouble([0.,1.,2.,3.,14.,15.,16.,17.,18.,19.,20.,21.,22.,23.,24.,25.,44.,45.,46.,47.,126.,127.,128.,129.,4.,5.,6.,7.,8.,9.,10.,11.,12.,13.,26.,27.,28.,29.,30.,31.,32.,33.,34.,35.,48.,49.,50.,51.,52.,53.,54.,55.,56.,57.,58.,59.,60.,61.,62.,63.,64.,65.,66.,67.,36.,37.,38.,39.,40.,41.,42.,43.,68.,69.,70.,71.,72.,73.,74.,75.,104.,105.,106.,107.,108.,109.,110.,111.,76.,77.,78.,79.,80.,81.,82.,83.,84.,85.,86.,87.,88.,89.,90.,91.,92.,93.,94.,95.,96.,97.,98.,99.,100.,101.,102.,103.,112.,113.,114.,115.,116.,117.,118.,119.,120.,121.,122.,123.,124.,125.],65,2) ; vExp.setInfoOnComponents(['Comp1_0 [m]','Com2_0 [s^2]']) + vExp+=i*1000 + self.assertTrue(v.isEqual(vExp,1e-12)) + pass + pass + + def test12(self): + """ This test is the second ultimate test for the profiles with gauss points. + This test is close to test11 but here a 2nd field on cells without profile. So here the mesh is expected to be the same than m. + """ + fname="ForMEDReader12.med" + m=MEDCouplingCMesh("mesh") + arr=DataArrayDouble(5) ; arr.iota() + m.setCoords(arr,arr) + m=m.buildUnstructured() ; m.getCoords().setInfoOnComponents(["XX [m]","YYY [km]"]) + mm=MEDFileUMesh() ; mm.setMeshes([m]) + # + fieldName0="zeField0" + fieldName1="zeField1" + fs0=MEDFileFieldMultiTS() ; fs1=MEDFileFieldMultiTS() + for i in xrange(5): + f=MEDFileField1TS() + fNode=MEDCouplingFieldDouble(ON_GAUSS_PT) ; fNode.setTime(float(i),i,0) + fNode.setName(fieldName0) ; fNode.setMesh(m) + fNode.setGaussLocalizationOnCells([0,2,3,4,7,15],[-1.,-1.,1.,-1.,1.,1.,-1.,1.],[0.5,0.5,0.7,0.7],[0.8,0.2]) + fNode.setGaussLocalizationOnCells([1,5,8,9],[-1.,-1.,1.,-1.,1.,1.,-1.,1.],[0.5,0.5,0.7,0.7,0.1,0.1,0.2,0.2,0.3,0.3],[0.8,0.05,0.1,0.04,0.01]) + fNode.setGaussLocalizationOnCells([6,10,13],[-1.,-1.,1.,-1.,1.,1.,-1.,1.],[0.5,0.5,0.7,0.7,0.1,0.1,0.2,0.2],[0.8,0.05,0.1,0.04]) + fNode.setGaussLocalizationOnCells([11,12,14],[-1.,-1.,1.,-1.,1.,1.,-1.,1.],[0.5,0.5,0.7,0.7,0.1,0.1,0.2,0.2,0.3,0.3,0.4,0.4,0.8,0.8],[0.8,0.05,0.1,0.01,0.02,0.005,0.005]) + arr=DataArrayDouble(2*(2*6+5*4+4*3+7*3)) ; arr.iota(0+1000*i) ; arr.rearrange(2) + fNode.setArray(arr) ; arr.setInfoOnComponents(["Comp1_0 [m]","Com2_0 [s^2]"]) ; fNode.checkCoherency() + f.setFieldNoProfileSBT(fNode) + fs0.pushBackTimeStep(f) + # + f=MEDFileField1TS() + fNode=MEDCouplingFieldDouble(ON_CELLS) ; fNode.setTime(float(i),i,0) + fNode.setName(fieldName1) ; fNode.setMesh(m) + arr=DataArrayDouble(2*16) ; arr.iota(300+1000*i) ; arr.rearrange(2) + fNode.setArray(arr) ; arr.setInfoOnComponents(["Comp1_1 [m]","Com2_1 [s^2]"]) ; fNode.checkCoherency() + f.setFieldNoProfileSBT(fNode) + fs1.pushBackTimeStep(f) + pass + mm.write(fname,2) + fs0.write(fname,0) ; fs1.write(fname,0) + a0Exp=mm.getCoords().deepCpy() + del m,mm,fs0,fs1,f,fNode + ########## GO for reading in MEDReader,by not loading all. Mesh is fully loaded but not fields values + ms=MEDFileMeshes(fname) + fields=MEDFileFields(fname,False) + fields.removeFieldsWithoutAnyTimeStep() + fields_per_mesh=[fields.partOfThisLyingOnSpecifiedMeshName(meshName) for meshName in ms.getMeshesNames()] + allFMTSLeavesToDisplay=[] + for fields in fields_per_mesh: + allFMTSLeavesToDisplay2=[] + for fmts in fields: + tmp=fmts.splitDiscretizations() + #for itmp in tmp: + # self.assertTrue(not itmp.presenceOfMultiDiscPerGeoType()) + # pass + allFMTSLeavesToDisplay2+=tmp + pass + allFMTSLeavesToDisplay.append(allFMTSLeavesToDisplay2) + pass + self.assertEqual(len(allFMTSLeavesToDisplay),1) + self.assertEqual(len(allFMTSLeavesToDisplay[0]),2) + allFMTSLeavesPerTimeSeries=MEDFileAnyTypeFieldMultiTS.SplitIntoCommonTimeSeries(sum(allFMTSLeavesToDisplay,[])) + self.assertEqual(len(allFMTSLeavesPerTimeSeries),1) # one time serie here : because the 2 fields are defined on the same time steps + self.assertEqual(len(allFMTSLeavesPerTimeSeries[0]),2) + allFMTSLeavesPerCommonSupport=MEDFileAnyTypeFieldMultiTS.SplitPerCommonSupport(allFMTSLeavesPerTimeSeries[0],ms[ms.getMeshesNames()[0]]) + self.assertEqual(len(allFMTSLeavesPerCommonSupport),1) + self.assertEqual(len(allFMTSLeavesPerCommonSupport[0][0]),2) + # + mst=MEDFileMeshStruct.New(ms[0]) + # + fcscp=allFMTSLeavesPerCommonSupport[0][1] + mml=fcscp.buildFromScratchDataSetSupport(0,fields) + mml2=mml.prepare() + self.assertTrue(isinstance(mml2,MEDUMeshMultiLev)) + ncc,a0,a1,a2,a3,a4,a5=mml2.buildVTUArrays() + self.assertTrue(not ncc) + self.assertTrue(a0.isEqual(a0Exp.changeNbOfComponents(3,0.),1e-12)) + self.assertTrue(a1.isEqual(DataArrayByte([9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9]))) + self.assertTrue(a2.isEqual(DataArrayInt([0,5,10,15,20,25,30,35,40,45,50,55,60,65,70,75]))) + self.assertTrue(a3.isEqual(DataArrayInt([4,1,0,5,6,4,2,1,6,7,4,3,2,7,8,4,4,3,8,9,4,6,5,10,11,4,7,6,11,12,4,8,7,12,13,4,9,8,13,14,4,11,10,15,16,4,12,11,16,17,4,13,12,17,18,4,14,13,18,19,4,16,15,20,21,4,17,16,21,22,4,18,17,22,23,4,19,18,23,24]))) # <- here the mesh is NOT renumbered : the mesh is equal to m + self.assertTrue(a4 is None) + self.assertTrue(a5 is None) + for i in xrange(1,5): + self.assertTrue((fcscp.isDataSetSupportEqualToThePreviousOne(i,fields))) + pass + for i in xrange(5): + f=allFMTSLeavesPerCommonSupport[0][0][0][i] + fsst=MEDFileField1TSStructItem.BuildItemFrom(f,mst) + f.loadArraysIfNecessary() + v=mml.buildDataArray(fsst,fields,f.getUndergroundDataArray()) + self.assertEqual(f.getName(),fieldName0) + #self.assertEqual(v.getHiddenCppPointer(),f.getUndergroundDataArray().getHiddenCppPointer()) # not a bug : huge reordering performed ! + vExp=DataArrayDouble(65*2) ; vExp.iota(0+i*1000) ; vExp.rearrange(2) ; vExp.setInfoOnComponents(['Comp1_0 [m]','Com2_0 [s^2]']) + self.assertTrue(v.isEqual(vExp,1e-12)) + # + f=allFMTSLeavesPerCommonSupport[0][0][1][i] + fsst=MEDFileField1TSStructItem.BuildItemFrom(f,mst) + f.loadArraysIfNecessary() + v=mml.buildDataArray(fsst,fields,f.getUndergroundDataArray()) + self.assertEqual(f.getName(),fieldName1) + self.assertEqual(v.getHiddenCppPointer(),f.getUndergroundDataArray().getHiddenCppPointer()) # not a bug : huge reordering performed ! + vExp=DataArrayDouble(16*2) ; vExp.iota(300+i*1000) ; vExp.rearrange(2) ; vExp.setInfoOnComponents(['Comp1_1 [m]','Com2_1 [s^2]']) + self.assertTrue(v.isEqual(vExp,1e-12)) + pass + + def test13(self): + """ Testing polyhedrons mixed with hexa8""" + fname="ForMEDReader13.med" + m=MEDCouplingUMesh("mesh",3) + m.allocateCells() + m.insertNextCell(NORM_HEXA8,[1,0,6,7,13,12,18,19]) ; m.insertNextCell(NORM_HEXA8,[2,1,7,8,14,13,19,20]) + m.insertNextCell(NORM_POLYHED,[3,2,8,9,-1,15,21,20,14,-1,3,15,14,2,-1,2,14,20,8,-1,8,20,21,9,-1,9,21,15,3]) + m.insertNextCell(NORM_POLYHED,[4,3,9,10,-1,16,22,21,15,-1,4,16,15,3,-1,3,15,21,9,-1,9,21,22,10,-1,10,22,16,4]) + m.insertNextCell(NORM_POLYHED,[5,4,10,11,-1,17,23,22,16,-1,5,17,16,4,-1,4,16,22,10,-1,10,22,23,11,-1,11,23,17,5]) + coords=DataArrayDouble([0.,0.,0.,1.,0.,0.,2.,0.,0.,3.,0.,0.,4.,0.,0.,5.,0.,0.,0.,1.,0.,1.,1.,0.,2.,1.,0.,3.,1.,0.,4.,1.,0.,5.,1.,0.,0.,0.,1.,1.,0.,1.,2.,0.,1.,3.,0.,1.,4.,0.,1.,5.,0.,1.,0.,1.,1.,1.,1.,1.,2.,1.,1.,3.,1.,1.,4.,1.,1.,5.,1.,1.],24,3) ; coords.setInfoOnComponents(["XX [m]","YYY [km]","ZZZZ [Mm]"]) + m.setCoords(coords) + mm=MEDFileUMesh() ; mm.setMeshes([m]) + fs0=MEDFileFieldMultiTS() ; fs1=MEDFileFieldMultiTS() ; fs2=MEDFileFieldMultiTS() ; fs3=MEDFileFieldMultiTS() + fieldName0="zeField0" + fieldName1="zeField1" + fieldName2="zeField2" ; pfl1=DataArrayInt([2,3]) ; pfl1.setName("pfl1") + fieldName3="zefield3" ; pfl2=DataArrayInt([2,3,4]) ; pfl2.setName("pfl2") + for i in xrange(5): + f=MEDFileField1TS() + fNode=MEDCouplingFieldDouble(ON_CELLS) ; fNode.setTime(float(i),i,0) + fNode.setName(fieldName0) ; fNode.setMesh(m) + arr=DataArrayDouble(2*5) ; arr.iota(0+1000*i) ; arr.rearrange(2) + fNode.setArray(arr) ; arr.setInfoOnComponents(["Comp1_0 [m]","Com2_0 [s^2]"]) ; fNode.checkCoherency() + f.setFieldNoProfileSBT(fNode) + fs0.pushBackTimeStep(f) + # + f=MEDFileField1TS() + fNode=MEDCouplingFieldDouble(ON_CELLS) ; fNode.setTime(float(i),i,0) + fNode.setName(fieldName1) ; fNode.setMesh(m) + arr=DataArrayDouble(2*5) ; arr.iota(100+1000*i) ; arr.rearrange(2) + fNode.setArray(arr) ; arr.setInfoOnComponents(["Comp1_1 [m]","Com2_1 [s^2]"]) ; fNode.checkCoherency() + f.setFieldNoProfileSBT(fNode) + fs1.pushBackTimeStep(f) + # + f=MEDFileField1TS() + fNode=MEDCouplingFieldDouble(ON_CELLS) ; fNode.setTime(float(i),i,0) + fNode.setName(fieldName2) ; fNode.setMesh(m[pfl1]) + arr=DataArrayDouble(2*2) ; arr.iota(200+1000*i) ; arr.rearrange(2) + fNode.setArray(arr) ; arr.setInfoOnComponents(["Comp1_2 [m]","Com2_2 [s^2]"]) ; fNode.checkCoherency() + f.setFieldProfile(fNode,mm,0,pfl1) + fs2.pushBackTimeStep(f) + # + f=MEDFileField1TS() + fNode=MEDCouplingFieldDouble(ON_CELLS) ; fNode.setTime(float(i),i,0) + fNode.setName(fieldName3) ; fNode.setMesh(m[pfl2]) + arr=DataArrayDouble(2*3) ; arr.iota(300+1000*i) ; arr.rearrange(2) + fNode.setArray(arr) ; arr.setInfoOnComponents(["Comp1_3 [m]","Com2_3 [s^2]"]) ; fNode.checkCoherency() + f.setFieldProfile(fNode,mm,0,pfl2) + fs3.pushBackTimeStep(f) + pass + mm.write(fname,2) + fs0.write(fname,0) ; fs1.write(fname,0) ; fs2.write(fname,0) ; fs3.write(fname,0) + a0Exp=mm.getCoords().deepCpy() + del m,mm,fs0 + ########## GO for reading in MEDReader,by not loading all. Mesh is fully loaded but not fields values + ms=MEDFileMeshes(fname) + fields=MEDFileFields(fname,False) + fields.removeFieldsWithoutAnyTimeStep() + fields_per_mesh=[fields.partOfThisLyingOnSpecifiedMeshName(meshName) for meshName in ms.getMeshesNames()] + allFMTSLeavesToDisplay=[] + for fields in fields_per_mesh: + allFMTSLeavesToDisplay2=[] + for fmts in fields: + tmp=fmts.splitDiscretizations() + for itmp in tmp: + self.assertTrue(not itmp.presenceOfMultiDiscPerGeoType()) + pass + allFMTSLeavesToDisplay2+=tmp + pass + allFMTSLeavesToDisplay.append(allFMTSLeavesToDisplay2) + pass + self.assertEqual(len(allFMTSLeavesToDisplay),1) + self.assertEqual(len(allFMTSLeavesToDisplay[0]),4) + allFMTSLeavesPerTimeSeries=MEDFileAnyTypeFieldMultiTS.SplitIntoCommonTimeSeries(sum(allFMTSLeavesToDisplay,[])) + self.assertEqual(len(allFMTSLeavesPerTimeSeries),1) # one time serie here : because the 2 fields are defined on the same time steps + self.assertEqual(len(allFMTSLeavesPerTimeSeries[0]),4) + allFMTSLeavesPerCommonSupport=MEDFileAnyTypeFieldMultiTS.SplitPerCommonSupport(allFMTSLeavesPerTimeSeries[0],ms[ms.getMeshesNames()[0]]) + self.assertEqual(len(allFMTSLeavesPerCommonSupport),3) + self.assertEqual(len(allFMTSLeavesPerCommonSupport[0][0]),2) + self.assertEqual(len(allFMTSLeavesPerCommonSupport[1][0]),1) + self.assertEqual(len(allFMTSLeavesPerCommonSupport[2][0]),1) + # + mst=MEDFileMeshStruct.New(ms[0]) + # + fcscp=allFMTSLeavesPerCommonSupport[0][1] + mml=fcscp.buildFromScratchDataSetSupport(0,fields) + mml2=mml.prepare() + self.assertTrue(isinstance(mml2,MEDUMeshMultiLev)) + ncc,a0,a1,a2,a3,a4,a5=mml2.buildVTUArrays() + self.assertTrue(ncc) + self.assertTrue(a0.isEqual(a0Exp,1e-12)) + self.assertTrue(a1.isEqual(DataArrayByte([12,12,42,42,42]))) + self.assertTrue(a2.isEqual(DataArrayInt([0,9,18,27,36]))) + self.assertTrue(a3.isEqual(DataArrayInt([8,1,0,6,7,13,12,18,19,8,2,1,7,8,14,13,19,20,8,2,3,8,9,14,15,20,21,8,3,4,9,10,15,16,21,22,8,4,5,10,11,16,17,22,23]))) + self.assertTrue(a4.isEqual(DataArrayInt([-1,-1,0,31,62]))) + self.assertTrue(a5.isEqual(DataArrayInt([6,4,3,2,8,9,4,15,21,20,14,4,3,15,14,2,4,2,14,20,8,4,8,20,21,9,4,9,21,15,3,6,4,4,3,9,10,4,16,22,21,15,4,4,16,15,3,4,3,15,21,9,4,9,21,22,10,4,10,22,16,4,6,4,5,4,10,11,4,17,23,22,16,4,5,17,16,4,4,4,16,22,10,4,10,22,23,11,4,11,23,17,5]))) + for i in xrange(1,5): + self.assertTrue((fcscp.isDataSetSupportEqualToThePreviousOne(i,fields))) + pass + pass + for i in xrange(5): + f=allFMTSLeavesPerCommonSupport[0][0][0][i] + fsst=MEDFileField1TSStructItem.BuildItemFrom(f,mst) + f.loadArraysIfNecessary() + v=mml.buildDataArray(fsst,fields,f.getUndergroundDataArray()) + self.assertEqual(f.getName(),fieldName0) + self.assertEqual(v.getHiddenCppPointer(),f.getUndergroundDataArray().getHiddenCppPointer()) + vExp=DataArrayDouble(5*2) ; vExp.iota(0+i*1000) ; vExp.rearrange(2) ; vExp.setInfoOnComponents(['Comp1_0 [m]','Com2_0 [s^2]']) + self.assertTrue(v.isEqual(vExp,1e-12)) + # + f=allFMTSLeavesPerCommonSupport[0][0][1][i] + fsst=MEDFileField1TSStructItem.BuildItemFrom(f,mst) + f.loadArraysIfNecessary() + v=mml.buildDataArray(fsst,fields,f.getUndergroundDataArray()) + self.assertEqual(f.getName(),fieldName1) + self.assertEqual(v.getHiddenCppPointer(),f.getUndergroundDataArray().getHiddenCppPointer()) + vExp=DataArrayDouble(5*2) ; vExp.iota(100+i*1000) ; vExp.rearrange(2) ; vExp.setInfoOnComponents(['Comp1_1 [m]','Com2_1 [s^2]']) + self.assertTrue(v.isEqual(vExp,1e-12)) + pass + # + fcscp=allFMTSLeavesPerCommonSupport[1][1] + mml=fcscp.buildFromScratchDataSetSupport(0,fields) + mml2=mml.prepare() + self.assertTrue(isinstance(mml2,MEDUMeshMultiLev)) + ncc,a0,a1,a2,a3,a4,a5=mml2.buildVTUArrays() + self.assertTrue(ncc) + self.assertTrue(a0.isEqual(a0Exp,1e-12)) + self.assertTrue(a1.isEqual(DataArrayByte([42,42]))) + self.assertTrue(a2.isEqual(DataArrayInt([0,9]))) + self.assertTrue(a3.isEqual(DataArrayInt([8,2,3,8,9,14,15,20,21,8,3,4,9,10,15,16,21,22]))) + self.assertTrue(a4.isEqual(DataArrayInt([0,31]))) + self.assertTrue(a5.isEqual(DataArrayInt([6,4,3,2,8,9,4,15,21,20,14,4,3,15,14,2,4,2,14,20,8,4,8,20,21,9,4,9,21,15,3,6,4,4,3,9,10,4,16,22,21,15,4,4,16,15,3,4,3,15,21,9,4,9,21,22,10,4,10,22,16,4]))) + for i in xrange(1,5): + self.assertTrue((fcscp.isDataSetSupportEqualToThePreviousOne(i,fields))) + pass + pass + for i in xrange(5): + f=allFMTSLeavesPerCommonSupport[1][0][0][i] + fsst=MEDFileField1TSStructItem.BuildItemFrom(f,mst) + f.loadArraysIfNecessary() + v=mml.buildDataArray(fsst,fields,f.getUndergroundDataArray()) + self.assertEqual(f.getName(),fieldName2) + self.assertEqual(v.getHiddenCppPointer(),f.getUndergroundDataArray().getHiddenCppPointer()) + vExp=DataArrayDouble(2*2) ; vExp.iota(200+i*1000) ; vExp.rearrange(2) ; vExp.setInfoOnComponents(['Comp1_2 [m]','Com2_2 [s^2]']) + self.assertTrue(v.isEqual(vExp,1e-12)) + pass + # + fcscp=allFMTSLeavesPerCommonSupport[2][1] + mml=fcscp.buildFromScratchDataSetSupport(0,fields) + mml2=mml.prepare() + self.assertTrue(isinstance(mml2,MEDUMeshMultiLev)) + ncc,a0,a1,a2,a3,a4,a5=mml2.buildVTUArrays() + self.assertTrue(ncc) + self.assertTrue(a0.isEqual(a0Exp,1e-12)) + self.assertTrue(a1.isEqual(DataArrayByte([42,42,42]))) + self.assertTrue(a2.isEqual(DataArrayInt([0,9,18]))) + self.assertTrue(a3.isEqual(DataArrayInt([8,2,3,8,9,14,15,20,21,8,3,4,9,10,15,16,21,22,8,4,5,10,11,16,17,22,23]))) + self.assertTrue(a4.isEqual(DataArrayInt([0,31,62]))) + self.assertTrue(a5.isEqual(DataArrayInt([6,4,3,2,8,9,4,15,21,20,14,4,3,15,14,2,4,2,14,20,8,4,8,20,21,9,4,9,21,15,3,6,4,4,3,9,10,4,16,22,21,15,4,4,16,15,3,4,3,15,21,9,4,9,21,22,10,4,10,22,16,4,6,4,5,4,10,11,4,17,23,22,16,4,5,17,16,4,4,4,16,22,10,4,10,22,23,11,4,11,23,17,5]))) + for i in xrange(1,5): + self.assertTrue((fcscp.isDataSetSupportEqualToThePreviousOne(i,fields))) + pass + pass + for i in xrange(5): + f=allFMTSLeavesPerCommonSupport[2][0][0][i] + fsst=MEDFileField1TSStructItem.BuildItemFrom(f,mst) + f.loadArraysIfNecessary() + v=mml.buildDataArray(fsst,fields,f.getUndergroundDataArray()) + self.assertEqual(f.getName(),fieldName3) + self.assertEqual(v.getHiddenCppPointer(),f.getUndergroundDataArray().getHiddenCppPointer()) + vExp=DataArrayDouble(3*2) ; vExp.iota(300+i*1000) ; vExp.rearrange(2) ; vExp.setInfoOnComponents(['Comp1_3 [m]','Com2_3 [s^2]']) + self.assertTrue(v.isEqual(vExp,1e-12)) + pass + pass + + def test14(self): + """ Testing only polyhedrons""" + fname="ForMEDReader14.med" + m=MEDCouplingUMesh("mesh",3) + m.allocateCells() + m.insertNextCell(NORM_POLYHED,[3,2,8,9,-1,15,21,20,14,-1,3,15,14,2,-1,2,14,20,8,-1,8,20,21,9,-1,9,21,15,3]) + m.insertNextCell(NORM_POLYHED,[4,3,9,10,-1,16,22,21,15,-1,4,16,15,3,-1,3,15,21,9,-1,9,21,22,10,-1,10,22,16,4]) + m.insertNextCell(NORM_POLYHED,[5,4,10,11,-1,17,23,22,16,-1,5,17,16,4,-1,4,16,22,10,-1,10,22,23,11,-1,11,23,17,5]) + coords=DataArrayDouble([0.,0.,0.,1.,0.,0.,2.,0.,0.,3.,0.,0.,4.,0.,0.,5.,0.,0.,0.,1.,0.,1.,1.,0.,2.,1.,0.,3.,1.,0.,4.,1.,0.,5.,1.,0.,0.,0.,1.,1.,0.,1.,2.,0.,1.,3.,0.,1.,4.,0.,1.,5.,0.,1.,0.,1.,1.,1.,1.,1.,2.,1.,1.,3.,1.,1.,4.,1.,1.,5.,1.,1.],24,3) ; coords.setInfoOnComponents(["XX [m]","YYY [km]","ZZZZ [Mm]"]) + m.setCoords(coords) + mm=MEDFileUMesh() ; mm.setMeshes([m]) + fs0=MEDFileFieldMultiTS() ; fs1=MEDFileFieldMultiTS() + fieldName0="zeField0" + fieldName1="zeField1" + for i in xrange(5): + f=MEDFileField1TS() + fNode=MEDCouplingFieldDouble(ON_CELLS) ; fNode.setTime(float(i),i,0) + fNode.setName(fieldName0) ; fNode.setMesh(m) + arr=DataArrayDouble(2*3) ; arr.iota(0+1000*i) ; arr.rearrange(2) + fNode.setArray(arr) ; arr.setInfoOnComponents(["Comp1_0 [m]","Com2_0 [s^2]"]) ; fNode.checkCoherency() + f.setFieldNoProfileSBT(fNode) + fs0.pushBackTimeStep(f) + # + f=MEDFileField1TS() + fNode=MEDCouplingFieldDouble(ON_CELLS) ; fNode.setTime(float(i),i,0) + fNode.setName(fieldName1) ; fNode.setMesh(m) + arr=DataArrayDouble(2*3) ; arr.iota(100+1000*i) ; arr.rearrange(2) + fNode.setArray(arr) ; arr.setInfoOnComponents(["Comp1_1 [m]","Com2_1 [s^2]"]) ; fNode.checkCoherency() + f.setFieldNoProfileSBT(fNode) + fs1.pushBackTimeStep(f) + pass + mm.write(fname,2) + fs0.write(fname,0) ; fs1.write(fname,0) + a0Exp=mm.getCoords().deepCpy() + del m,mm,fs0 + ########## GO for reading in MEDReader,by not loading all. Mesh is fully loaded but not fields values + ms=MEDFileMeshes(fname) + fields=MEDFileFields(fname,False) + fields.removeFieldsWithoutAnyTimeStep() + fields_per_mesh=[fields.partOfThisLyingOnSpecifiedMeshName(meshName) for meshName in ms.getMeshesNames()] + allFMTSLeavesToDisplay=[] + for fields in fields_per_mesh: + allFMTSLeavesToDisplay2=[] + for fmts in fields: + tmp=fmts.splitDiscretizations() + for itmp in tmp: + self.assertTrue(not itmp.presenceOfMultiDiscPerGeoType()) + pass + allFMTSLeavesToDisplay2+=tmp + pass + allFMTSLeavesToDisplay.append(allFMTSLeavesToDisplay2) + pass + self.assertEqual(len(allFMTSLeavesToDisplay),1) + self.assertEqual(len(allFMTSLeavesToDisplay[0]),2) + allFMTSLeavesPerTimeSeries=MEDFileAnyTypeFieldMultiTS.SplitIntoCommonTimeSeries(sum(allFMTSLeavesToDisplay,[])) + self.assertEqual(len(allFMTSLeavesPerTimeSeries),1) # one time serie here : because the 2 fields are defined on the same time steps + self.assertEqual(len(allFMTSLeavesPerTimeSeries[0]),2) + allFMTSLeavesPerCommonSupport=MEDFileAnyTypeFieldMultiTS.SplitPerCommonSupport(allFMTSLeavesPerTimeSeries[0],ms[ms.getMeshesNames()[0]]) + self.assertEqual(len(allFMTSLeavesPerCommonSupport),1) + self.assertEqual(len(allFMTSLeavesPerCommonSupport[0][0]),2) + # + mst=MEDFileMeshStruct.New(ms[0]) + # + fcscp=allFMTSLeavesPerCommonSupport[0][1] + mml=fcscp.buildFromScratchDataSetSupport(0,fields) + mml2=mml.prepare() + self.assertTrue(isinstance(mml2,MEDUMeshMultiLev)) + ncc,a0,a1,a2,a3,a4,a5=mml2.buildVTUArrays() + self.assertTrue(ncc) + self.assertTrue(a0.isEqual(a0Exp,1e-12)) + self.assertTrue(a1.isEqual(DataArrayByte([42,42,42]))) + self.assertTrue(a2.isEqual(DataArrayInt([0,9,18]))) + self.assertTrue(a3.isEqual(DataArrayInt([8,2,3,8,9,14,15,20,21,8,3,4,9,10,15,16,21,22,8,4,5,10,11,16,17,22,23]))) + self.assertTrue(a4.isEqual(DataArrayInt([0,31,62]))) + self.assertTrue(a5.isEqual(DataArrayInt([6,4,3,2,8,9,4,15,21,20,14,4,3,15,14,2,4,2,14,20,8,4,8,20,21,9,4,9,21,15,3,6,4,4,3,9,10,4,16,22,21,15,4,4,16,15,3,4,3,15,21,9,4,9,21,22,10,4,10,22,16,4,6,4,5,4,10,11,4,17,23,22,16,4,5,17,16,4,4,4,16,22,10,4,10,22,23,11,4,11,23,17,5]))) + for i in xrange(1,5): + self.assertTrue((fcscp.isDataSetSupportEqualToThePreviousOne(i,fields))) + pass + a6,a7=mml2.retrieveFamilyIdsOnCells() + self.assertTrue(a6.isEqual(DataArrayInt([0,0,0]))) + self.assertTrue(a7) + a8,a9=mml2.retrieveNumberIdsOnCells() + self.assertTrue(a8 is None) + self.assertTrue(a9) + for i in xrange(5): + f=allFMTSLeavesPerCommonSupport[0][0][0][i] + fsst=MEDFileField1TSStructItem.BuildItemFrom(f,mst) + f.loadArraysIfNecessary() + v=mml.buildDataArray(fsst,fields,f.getUndergroundDataArray()) + self.assertEqual(f.getName(),fieldName0) + self.assertEqual(v.getHiddenCppPointer(),f.getUndergroundDataArray().getHiddenCppPointer()) + vExp=DataArrayDouble(3*2) ; vExp.iota(0+i*1000) ; vExp.rearrange(2) ; vExp.setInfoOnComponents(['Comp1_0 [m]','Com2_0 [s^2]']) + self.assertTrue(v.isEqual(vExp,1e-12)) + # + f=allFMTSLeavesPerCommonSupport[0][0][1][i] + fsst=MEDFileField1TSStructItem.BuildItemFrom(f,mst) + f.loadArraysIfNecessary() + v=mml.buildDataArray(fsst,fields,f.getUndergroundDataArray()) + self.assertEqual(f.getName(),fieldName1) + self.assertEqual(v.getHiddenCppPointer(),f.getUndergroundDataArray().getHiddenCppPointer()) + vExp=DataArrayDouble(3*2) ; vExp.iota(100+i*1000) ; vExp.rearrange(2) ; vExp.setInfoOnComponents(['Comp1_1 [m]','Com2_1 [s^2]']) + self.assertTrue(v.isEqual(vExp,1e-12)) + pass + pass + + def test15(self): + """ + "ForMEDReader15.med" file has a spaceDim 3 mesh "mesh" (it is important !) + and a field "zeField" lying on a single geometric type for Cell discr and node part. + Test that can appear the most simple but it hides a big issue of MEDReader + that copies are reduced at most. So it can leads to SIGSEGV if the memory management is not OK for int* and double * similar between VTK and MEDCoupling. + """ + fname="ForMEDReader15.med" + m0=MEDCouplingCMesh() + arr=DataArrayDouble(3) ; arr.iota(0) + m0.setCoords(arr,arr,arr) + m0.setName("mesh") + m0=m0.buildUnstructured() + # + fieldName="zeField" + fCell=MEDCouplingFieldDouble(ON_CELLS) + fCell.setName(fieldName) + fCell.setMesh(m0) + # + fNode=MEDCouplingFieldDouble(ON_NODES) + fNode.setName(fieldName) + fNode.setMesh(m0) + # + mm=MEDFileUMesh() + mm.setMeshAtLevel(0,m0) + fam=DataArrayInt(8) ; fam.iota(0) ; mm.setFamilyFieldArr(0,fam) ; del fam + num=DataArrayInt(8) ; num.iota(100) ; mm.setRenumFieldArr(0,num) ; del num + # + ffs=MEDFileFieldMultiTS() + # TimeStep 0 + t=(1.,0,0) ; off=0. + f1ts=MEDFileField1TS() + a=DataArrayDouble(m0.getNumberOfCells()) ; a.iota(off) ; a.setInfoOnComponents(["xx [m]"]) + fCell.setArray(a) + fCell.setTime(*t) + fCell.checkCoherency() + a=DataArrayDouble(m0.getNumberOfNodes()) ; a.iota(off) ; a.setInfoOnComponents(["xx [m]"]) + a=a.negate() + fNode.setArray(a) + fNode.setTime(*t) + fNode.checkCoherency() + f1ts.setFieldNoProfileSBT(fCell) + f1ts.setFieldNoProfileSBT(fNode) + ffs.pushBackTimeStep(f1ts) + # TimeStep 1 + t=(2.1,1,0) ; off=100. + f1ts=MEDFileField1TS() + a=DataArrayDouble(m0.getNumberOfCells()) ; a.iota(off) ; a.setInfoOnComponents(["xx [m]"]) + fCell.setArray(a) + fCell.setTime(*t) + fCell.checkCoherency() + a=DataArrayDouble(m0.getNumberOfNodes()) ; a.iota(off) ; a.setInfoOnComponents(["xx [m]"]) + a=a.negate() + fNode.setArray(a) + fNode.setTime(*t) + fNode.checkCoherency() + f1ts.setFieldNoProfileSBT(fCell) + f1ts.setFieldNoProfileSBT(fNode) + ffs.pushBackTimeStep(f1ts) + # TimeStep 2 + t=(3.2,2,0) ; off=200. + f1ts=MEDFileField1TS() + a=DataArrayDouble(m0.getNumberOfCells()) ; a.iota(off) ; a.setInfoOnComponents(["xx [m]"]) + fCell.setArray(a) + fCell.setTime(*t) + fCell.checkCoherency() + a=DataArrayDouble(m0.getNumberOfNodes()) ; a.iota(off) ; a.setInfoOnComponents(["xx [m]"]) + a=a.negate() + fNode.setArray(a) + fNode.setTime(*t) + fNode.checkCoherency() + f1ts.setFieldNoProfileSBT(fCell) + f1ts.setFieldNoProfileSBT(fNode) + ffs.pushBackTimeStep(f1ts) + # TimeStep 3 + t=(4.3,3,1) ; off=300. + f1ts=MEDFileField1TS() + a=DataArrayDouble(m0.getNumberOfCells()) ; a.iota(off) ; a.setInfoOnComponents(["xx [m]"]) + fCell.setArray(a) + fCell.setTime(*t) + fCell.checkCoherency() + a=DataArrayDouble(m0.getNumberOfNodes()) ; a.iota(off) ; a.setInfoOnComponents(["xx [m]"]) + a=a.negate() + fNode.setArray(a) + fNode.setTime(*t) + fNode.checkCoherency() + f1ts.setFieldNoProfileSBT(fCell) + f1ts.setFieldNoProfileSBT(fNode) + ffs.pushBackTimeStep(f1ts) + # + mm.write(fname,2) + ffs.write(fname,0) + ########## GO for reading in MEDReader,by not loading all. Mesh is fully loaded but not fields values + ms=MEDFileMeshes(fname) + fields=MEDFileFields(fname,False) + fields.removeFieldsWithoutAnyTimeStep() + fields_per_mesh=[fields.partOfThisLyingOnSpecifiedMeshName(meshName) for meshName in ms.getMeshesNames()] + allFMTSLeavesToDisplay=[] + for fields in fields_per_mesh: + allFMTSLeavesToDisplay2=[] + for fmts in fields: + tmp=fmts.splitDiscretizations() + for itmp in tmp: + self.assertTrue(not itmp.presenceOfMultiDiscPerGeoType()) + pass + allFMTSLeavesToDisplay2+=tmp + pass + allFMTSLeavesToDisplay.append(allFMTSLeavesToDisplay2) + pass + self.assertEqual(len(allFMTSLeavesToDisplay),1) + self.assertEqual(len(allFMTSLeavesToDisplay[0]),2) + allFMTSLeavesPerTimeSeries=MEDFileAnyTypeFieldMultiTS.SplitIntoCommonTimeSeries(sum(allFMTSLeavesToDisplay,[])) + self.assertEqual(len(allFMTSLeavesPerTimeSeries),1) # one time serie here : because the 2 fields are defined on the same time steps + self.assertEqual(len(allFMTSLeavesPerTimeSeries[0]),2) + allFMTSLeavesPerCommonSupport=MEDFileAnyTypeFieldMultiTS.SplitPerCommonSupport(allFMTSLeavesPerTimeSeries[0],ms[ms.getMeshesNames()[0]]) + self.assertEqual(len(allFMTSLeavesPerCommonSupport),1) + self.assertEqual(len(allFMTSLeavesPerCommonSupport[0][0]),2) + # + mst=MEDFileMeshStruct.New(ms[0]) + # + fcscp=allFMTSLeavesPerCommonSupport[0][1] + mml=fcscp.buildFromScratchDataSetSupport(0,fields) + mml2=mml.prepare() + self.assertTrue(isinstance(mml2,MEDUMeshMultiLev)) + ncc,a0,a1,a2,a3,a4,a5=mml2.buildVTUArrays() + self.assertTrue(ncc) + self.assertTrue(a0.isEqual(DataArrayDouble([0.,0.,0.,1.,0.,0.,2.,0.,0.,0.,1.,0.,1.,1.,0.,2.,1.,0.,0.,2.,0.,1.,2.,0.,2.,2.,0.,0.,0.,1.,1.,0.,1.,2.,0.,1.,0.,1.,1.,1.,1.,1.,2.,1.,1.,0.,2.,1.,1.,2.,1.,2.,2.,1.,0.,0.,2.,1.,0.,2.,2.,0.,2.,0.,1.,2.,1.,1.,2.,2.,1.,2.,0.,2.,2.,1.,2.,2.,2.,2.,2.0],27,3),1e-12)) + self.assertTrue(a1.isEqual(DataArrayByte([12,12,12,12,12,12,12,12]))) + self.assertTrue(a2.isEqual(DataArrayInt([0,9,18,27,36,45,54,63]))) + self.assertTrue(a3.isEqual(DataArrayInt([8,1,0,3,4,10,9,12,13,8,2,1,4,5,11,10,13,14,8,4,3,6,7,13,12,15,16,8,5,4,7,8,14,13,16,17,8,10,9,12,13,19,18,21,22,8,11,10,13,14,20,19,22,23,8,13,12,15,16,22,21,24,25,8,14,13,16,17,23,22,25,26]))) + self.assertTrue(a4 is None) + self.assertTrue(a5 is None) + a6,a7=mml2.retrieveFamilyIdsOnCells() + self.assertTrue(a6.isEqual(DataArrayInt([0,1,2,3,4,5,6,7]))) + self.assertTrue(a7) # no copy here + a8,a9=mml2.retrieveNumberIdsOnCells() + self.assertTrue(a8.isEqual(DataArrayInt([100,101,102,103,104,105,106,107]))) + self.assertTrue(a9) # no copy here + pass + + def test16(self): + """ Here 2 meshes "mesh1" and "mesh2" and 4 fields (no profiles here) : + - "zeField1_0" (CELLS) and "zeField2_0" (NODES) on "mesh1" + - "zeField3_1" (CELLS) and "zeField4_1" (NODES) on "mesh2" + time steps series are the same for the whole 4 fields + """ + fname="ForMEDReader16.med" + m0=MEDCouplingCMesh() + arr=DataArrayDouble(3) ; arr.iota(0) + m0.setCoords(arr,arr,arr) + m0.setName("mesh1") + m0=m0.buildUnstructured() + # + fCell1=MEDCouplingFieldDouble(ON_CELLS) + fCell1.setName("zeField1_0") + fCell1.setMesh(m0) + # + fNode1=MEDCouplingFieldDouble(ON_NODES) + fNode1.setName("zeField2_0") + fNode1.setMesh(m0) + # + mms=MEDFileMeshes() + mm1=MEDFileUMesh() + mm1.setMeshAtLevel(0,m0) + fam=DataArrayInt([0,1,0,1,2,3,2,3]); mm1.setFamilyFieldArr(0,fam) ; del fam + num=DataArrayInt(8) ; num.iota(100) ; mm1.setRenumFieldArr(0,num) ; del num + mm1.setFamilyId("FAMILLE_ZERO",0) ; mm1.setFamilyId("Family1_1",1) ; mm1.setFamilyId("Family1_2",2) ; mm1.setFamilyId("Family1_3",3) ; mm1.setFamilyId("Family1_4",4) + mm1.setFamiliesIdsOnGroup("Grp1_1",[0,1]) ; mm1.setFamiliesIdsOnGroup("Grp1_2",[2,3]) + mms.pushMesh(mm1) ; del mm1 + # + m1=m0.deepCpy() ; m1.translate([2.5,0.,0.]) ; m1.setName("mesh2") + # + fCell2=MEDCouplingFieldDouble(ON_CELLS) + fCell2.setName("zeField3_1") + fCell2.setMesh(m1) + # + fNode2=MEDCouplingFieldDouble(ON_NODES) + fNode2.setName("zeField4_1") + fNode2.setMesh(m1) + # + mm2=MEDFileUMesh() + mm2.setMeshAtLevel(0,m1) + fam=DataArrayInt([0,1,0,1,2,3,2,3]); mm2.setFamilyFieldArr(0,fam) ; del fam + num=DataArrayInt(8) ; num.iota(200) ; mm2.setRenumFieldArr(0,num) ; del num + mm2.setFamilyId("FAMILLE_ZERO",0) ; mm2.setFamilyId("Family2_1",1) ; mm2.setFamilyId("Family2_2",2) ; mm2.setFamilyId("Family2_3",3) ; mm2.setFamilyId("Family2_4",4) + mm2.setFamiliesIdsOnGroup("Grp2_1",[0,1]) ; mm2.setFamiliesIdsOnGroup("Grp2_2",[2,3]) ; mm2.setFamiliesIdsOnGroup("Grp2_3",[1,2,3]) + mms.pushMesh(mm2) ; del mm2 + ffs1_1=MEDFileFieldMultiTS() + ffs1_2=MEDFileFieldMultiTS() + ffs2_1=MEDFileFieldMultiTS() + ffs2_2=MEDFileFieldMultiTS() + mts=MEDFileFields() + for elt in ffs1_1,ffs1_2,ffs2_1,ffs2_2: + mts.pushField(elt) + pass + # TimeStep 0 + t=(1.,0,0) ; off=0. + f1ts1=MEDFileField1TS() + f1ts2=MEDFileField1TS() + a=DataArrayDouble(m0.getNumberOfCells()) ; a.iota(off) ; a.setInfoOnComponents(["xx [m]"]) + fCell1.setArray(a) + fCell1.setTime(*t) + fCell1.checkCoherency() + a=DataArrayDouble(m0.getNumberOfNodes()) ; a.iota(off) ; a.setInfoOnComponents(["xx [m]"]) + a=a.negate() + fNode1.setArray(a) + fNode1.setTime(*t) + fNode1.checkCoherency() + f1ts1.setFieldNoProfileSBT(fCell1) ; ffs1_1.pushBackTimeStep(f1ts1) + f1ts2.setFieldNoProfileSBT(fNode1) ; ffs1_2.pushBackTimeStep(f1ts2) + # + f1ts1=MEDFileField1TS() + f1ts2=MEDFileField1TS() + a=DataArrayDouble(m1.getNumberOfCells()) ; a.iota(1000.+off) ; a.setInfoOnComponents(["xx [m]"]) + fCell2.setArray(a) + fCell2.setTime(*t) + fCell2.checkCoherency() + a=DataArrayDouble(m1.getNumberOfNodes()) ; a.iota(1000+off) ; a.setInfoOnComponents(["xx [m]"]) + a=a.negate() + fNode2.setArray(a) + fNode2.setTime(*t) + fNode2.checkCoherency() + f1ts1.setFieldNoProfileSBT(fCell2) ; ffs2_1.pushBackTimeStep(f1ts1) + f1ts2.setFieldNoProfileSBT(fNode2) ; ffs2_2.pushBackTimeStep(f1ts2) + # TimeStep 1 + t=(2.1,1,0) ; off=100. + f1ts1=MEDFileField1TS() + f1ts2=MEDFileField1TS() + a=DataArrayDouble(m0.getNumberOfCells()) ; a.iota(off) ; a.setInfoOnComponents(["xx [m]"]) + fCell1.setArray(a) + fCell1.setTime(*t) + fCell1.checkCoherency() + a=DataArrayDouble(m0.getNumberOfNodes()) ; a.iota(off) ; a.setInfoOnComponents(["xx [m]"]) + a=a.negate() + fNode1.setArray(a) + fNode1.setTime(*t) + fNode1.checkCoherency() + f1ts1.setFieldNoProfileSBT(fCell1) ; ffs1_1.pushBackTimeStep(f1ts1) + f1ts2.setFieldNoProfileSBT(fNode1) ; ffs1_2.pushBackTimeStep(f1ts2) + # + f1ts1=MEDFileField1TS() + f1ts2=MEDFileField1TS() + a=DataArrayDouble(m1.getNumberOfCells()) ; a.iota(1000.+off) ; a.setInfoOnComponents(["xx [m]"]) + fCell2.setArray(a) + fCell2.setTime(*t) + fCell2.checkCoherency() + a=DataArrayDouble(m1.getNumberOfNodes()) ; a.iota(1000+off) ; a.setInfoOnComponents(["xx [m]"]) + a=a.negate() + fNode2.setArray(a) + fNode2.setTime(*t) + fNode2.checkCoherency() + f1ts1.setFieldNoProfileSBT(fCell2) ; ffs2_1.pushBackTimeStep(f1ts1) + f1ts2.setFieldNoProfileSBT(fNode2) ; ffs2_2.pushBackTimeStep(f1ts2) + # TimeStep 2 + t=(3.1,2,0) ; off=200. + f1ts1=MEDFileField1TS() + f1ts2=MEDFileField1TS() + a=DataArrayDouble(m0.getNumberOfCells()) ; a.iota(off) ; a.setInfoOnComponents(["xx [m]"]) + fCell1.setArray(a) + fCell1.setTime(*t) + fCell1.checkCoherency() + a=DataArrayDouble(m0.getNumberOfNodes()) ; a.iota(off) ; a.setInfoOnComponents(["xx [m]"]) + a=a.negate() + fNode1.setArray(a) + fNode1.setTime(*t) + fNode1.checkCoherency() + f1ts1.setFieldNoProfileSBT(fCell1) ; ffs1_1.pushBackTimeStep(f1ts1) + f1ts2.setFieldNoProfileSBT(fNode1) ; ffs1_2.pushBackTimeStep(f1ts2) + # + f1ts1=MEDFileField1TS() + f1ts2=MEDFileField1TS() + a=DataArrayDouble(m1.getNumberOfCells()) ; a.iota(1000.+off) ; a.setInfoOnComponents(["xx [m]"]) + fCell2.setArray(a) + fCell2.setTime(*t) + fCell2.checkCoherency() + a=DataArrayDouble(m1.getNumberOfNodes()) ; a.iota(1000+off) ; a.setInfoOnComponents(["xx [m]"]) + a=a.negate() + fNode2.setArray(a) + fNode2.setTime(*t) + fNode2.checkCoherency() + f1ts1.setFieldNoProfileSBT(fCell2) ; ffs2_1.pushBackTimeStep(f1ts1) + f1ts2.setFieldNoProfileSBT(fNode2) ; ffs2_2.pushBackTimeStep(f1ts2) + # + mms.write(fname,2) ; mts.write(fname,0) + ########## GO for reading in MEDReader,by not loading all. Mesh is fully loaded but not fields values + ms=MEDFileMeshes(fname) + fields=MEDFileFields(fname,False) + fields.removeFieldsWithoutAnyTimeStep() + fields_per_mesh=[fields.partOfThisLyingOnSpecifiedMeshName(meshName) for meshName in ms.getMeshesNames()] + allFMTSLeavesToDisplay=[] + for fields in fields_per_mesh: + allFMTSLeavesToDisplay2=[] + for fmts in fields: + tmp=fmts.splitDiscretizations() + for itmp in tmp: + self.assertTrue(not itmp.presenceOfMultiDiscPerGeoType()) + pass + allFMTSLeavesToDisplay2+=tmp + pass + allFMTSLeavesToDisplay.append(allFMTSLeavesToDisplay2) + pass + self.assertEqual(len(allFMTSLeavesToDisplay),2) + self.assertEqual(len(allFMTSLeavesToDisplay[0]),2) + self.assertEqual(len(allFMTSLeavesToDisplay[1]),2) + allFMTSLeavesPerTimeSeries=MEDFileAnyTypeFieldMultiTS.SplitIntoCommonTimeSeries(sum(allFMTSLeavesToDisplay,[])) + self.assertEqual(len(allFMTSLeavesPerTimeSeries),1) # one time serie here : because the 2 fields are defined on the same time steps + self.assertEqual(len(allFMTSLeavesPerTimeSeries[0]),4) + allFMTSLeavesPerCommonSupport1=MEDFileAnyTypeFieldMultiTS.SplitPerCommonSupport(allFMTSLeavesToDisplay[0],ms[ms.getMeshesNames()[0]]) + self.assertEqual(len(allFMTSLeavesPerCommonSupport1),1) + self.assertEqual(len(allFMTSLeavesPerCommonSupport1[0][0]),2) + allFMTSLeavesPerCommonSupport2=MEDFileAnyTypeFieldMultiTS.SplitPerCommonSupport(allFMTSLeavesToDisplay[0],ms[ms.getMeshesNames()[0]]) + self.assertEqual(len(allFMTSLeavesPerCommonSupport2),1) + self.assertEqual(len(allFMTSLeavesPerCommonSupport2[0][0]),2) + pass + + def test17(self): + """ First test on GAUSS_NE (Elno). Here no Profiles. + 2 times steps. + """ + fname="ForMEDReader17.med" + fieldName1="MyFirstElno" + fieldName2="ACellField" + fieldName3="ANodeField" + coo=DataArrayDouble([0.,0.,1.,0.,2.,0.,0.,1.,1.,1.,2.,1.],6,2) + m=MEDCouplingUMesh("mesh",2) + m.setCoords(coo) + m.allocateCells() + m.insertNextCell(NORM_QUAD4,[0,3,4,1]) + m.insertNextCell(NORM_QUAD4,[1,4,5,2]) + m.checkCoherency2() + # + t=(1.1,0,-1) + f=MEDCouplingFieldDouble(ON_GAUSS_NE) ; f.setTime(*t) ; f.setMesh(m) + f.setArray(DataArrayDouble([3.,5.,7.,6.,2.,3.,11.,8.])) + f.setName(fieldName1) + f.checkCoherency() + MEDLoader.WriteField(fname,f,True) + f2=MEDCouplingFieldDouble(ON_CELLS) ; f2.setTime(*t) ; f2.setMesh(m) + f2.setArray(DataArrayDouble([7.,11.],2,1)) + f2.setName(fieldName2) + MEDLoader.WriteFieldUsingAlreadyWrittenMesh(fname,f2) + f3=MEDCouplingFieldDouble(ON_NODES) ; f3.setTime(*t) ; f3.setMesh(m) + f3.setArray(DataArrayDouble([1.,2.,4.,1.,2.,4.],6,1)) + f3.setName(fieldName3) + MEDLoader.WriteFieldUsingAlreadyWrittenMesh(fname,f3) + # + t=(2.1,1,-1) + f=MEDCouplingFieldDouble(ON_GAUSS_NE) ; f.setTime(*t) ; f.setMesh(m) + f.setArray(DataArrayDouble([7.,6.,3.,5.,11.,8.,2.,3.])) + f.setName(fieldName1) + f.checkCoherency() + MEDLoader.WriteFieldUsingAlreadyWrittenMesh(fname,f) + f2=MEDCouplingFieldDouble(ON_CELLS) ; f2.setTime(*t) ; f2.setMesh(m) + f2.setArray(DataArrayDouble([11.,7.],2,1)) + f2.setName(fieldName2) + MEDLoader.WriteFieldUsingAlreadyWrittenMesh(fname,f2) + f3=MEDCouplingFieldDouble(ON_NODES) ; f3.setTime(*t) ; f3.setMesh(m) + f3.setArray(DataArrayDouble([4.,2.,1.,4.,2.,1.],6,1)) + f3.setName(fieldName3) + MEDLoader.WriteFieldUsingAlreadyWrittenMesh(fname,f3) + ########## GO for reading in MEDReader,by not loading all. Mesh is fully loaded but not fields values + ms=MEDFileMeshes(fname) + fields=MEDFileFields(fname,False) + fields.removeFieldsWithoutAnyTimeStep() + fields_per_mesh=[fields.partOfThisLyingOnSpecifiedMeshName(meshName) for meshName in ms.getMeshesNames()] + allFMTSLeavesToDisplay=[] + for fields in fields_per_mesh: + allFMTSLeavesToDisplay2=[] + for fmts in fields: + tmp=fmts.splitDiscretizations() + for itmp in tmp: + self.assertTrue(not itmp.presenceOfMultiDiscPerGeoType()) + pass + allFMTSLeavesToDisplay2+=tmp + pass + allFMTSLeavesToDisplay.append(allFMTSLeavesToDisplay2) + pass + self.assertEqual(len(allFMTSLeavesToDisplay),1) + self.assertEqual(len(allFMTSLeavesToDisplay[0]),3) + allFMTSLeavesPerTimeSeries=MEDFileAnyTypeFieldMultiTS.SplitIntoCommonTimeSeries(sum(allFMTSLeavesToDisplay,[])) + self.assertEqual(len(allFMTSLeavesPerTimeSeries),1) + self.assertEqual(len(allFMTSLeavesPerTimeSeries[0]),3) + allFMTSLeavesPerCommonSupport1=MEDFileAnyTypeFieldMultiTS.SplitPerCommonSupport(allFMTSLeavesToDisplay[0],ms[ms.getMeshesNames()[0]]) + self.assertEqual(len(allFMTSLeavesPerCommonSupport1),1) + self.assertEqual(len(allFMTSLeavesPerCommonSupport1[0][0]),3) + # + mst=MEDFileMeshStruct.New(ms[0]) + # + fcscp=allFMTSLeavesPerCommonSupport1[0][1] + mml=fcscp.buildFromScratchDataSetSupport(0,fields) + mml2=mml.prepare() + self.assertTrue(isinstance(mml2,MEDUMeshMultiLev)) + ncc,a0,a1,a2,a3,a4,a5=mml2.buildVTUArrays() + self.assertTrue(not ncc) # spaceDim 2 -> VTK wants 3D + self.assertTrue(a0.isEqual(DataArrayDouble([0.,0.,0.,1.,0.,0.,2.,0.,0.,0.,1.,0.,1.,1.,0.,2.,1.,0.],6,3),1e-12)) + self.assertTrue(a1.isEqual(DataArrayByte([9,9]))) + self.assertTrue(a2.isEqual(DataArrayInt([0,5]))) + self.assertTrue(a3.isEqual(DataArrayInt([4,0,3,4,1,4,1,4,5,2]))) + self.assertTrue(a4 is None) + self.assertTrue(a5 is None) + a6,a7=mml2.retrieveFamilyIdsOnCells() + self.assertTrue(a6.isEqual(DataArrayInt([0,0]))) + self.assertTrue(a7) # no copy here + a8,a9=mml2.retrieveNumberIdsOnCells() + self.assertTrue(a8.isEqual(DataArrayInt([0,1]))) + self.assertTrue(a9) # no copy here + for i in xrange(1,2): + self.assertTrue((fcscp.isDataSetSupportEqualToThePreviousOne(i,fields))) + pass + vExp0=[DataArrayDouble([7.,11.]),DataArrayDouble([11.,7.])] + vExp1=[DataArrayDouble([3.,5.,7.,6.,2.,3.,11.,8.]),DataArrayDouble([7.,6.,3.,5.,11.,8.,2.,3.])] + for i in xrange(2): + f=allFMTSLeavesPerCommonSupport1[0][0][0][i] + fsst=MEDFileField1TSStructItem.BuildItemFrom(f,mst) + f.loadArraysIfNecessary() + v=mml.buildDataArray(fsst,fields,f.getUndergroundDataArray()) + self.assertEqual(f.getName(),fieldName2) + self.assertEqual(v.getHiddenCppPointer(),f.getUndergroundDataArray().getHiddenCppPointer()) + self.assertTrue(v.isEqual(vExp0[i],1e-12)) + # + f=allFMTSLeavesPerCommonSupport1[0][0][1][i] + fsst=MEDFileField1TSStructItem.BuildItemFrom(f,mst) + f.loadArraysIfNecessary() + v=mml.buildDataArray(fsst,fields,f.getUndergroundDataArray()) + self.assertEqual(f.getName(),fieldName1) + self.assertEqual(v.getHiddenCppPointer(),f.getUndergroundDataArray().getHiddenCppPointer()) + self.assertTrue(v.isEqual(vExp1[i],1e-12)) + pass + pass + + def test18(self): + """ First test on GAUSS_PT. Here no Profiles. 2 times steps. + """ + fname="ForMEDReader18.med" + fieldName1="MyFirstGauss" + fieldName2="ACellField" + fieldName3="ANodeField" + coo=DataArrayDouble([0.,0.,1.,0.,2.,0.,0.,1.,1.,1.,2.,1.],6,2) + m=MEDCouplingUMesh("mesh",2) + m.setCoords(coo) + m.allocateCells() + m.insertNextCell(NORM_QUAD4,[0,3,4,1]) + m.insertNextCell(NORM_QUAD4,[1,4,5,2]) + m.checkCoherency2() + # + t=(1.1,0,-1) + f=MEDCouplingFieldDouble(ON_GAUSS_PT) ; f.setTime(*t) ; f.setMesh(m) + f.setGaussLocalizationOnType(NORM_QUAD4,[-1.,-1.,1.,-1.,1.,1.,-1.,1.],[0.2,0.2,0.8,0.8],[0.7,0.3]) + f.setArray(DataArrayDouble([3.,5.,4.,6.])) ; f.getArray().setInfoOnComponents(["Smth"]) + f.setName(fieldName1) + f.checkCoherency() + MEDLoader.WriteField(fname,f,True) + f2=MEDCouplingFieldDouble(ON_CELLS) ; f2.setTime(*t) ; f2.setMesh(m) + f2.setArray(DataArrayDouble([7.,11.],2,1)) + f2.setName(fieldName2) + MEDLoader.WriteFieldUsingAlreadyWrittenMesh(fname,f2) + f3=MEDCouplingFieldDouble(ON_NODES) ; f3.setTime(*t) ; f3.setMesh(m) + f3.setArray(DataArrayDouble([1.,2.,4.,1.,2.,4.],6,1)) + f3.setName(fieldName3) + MEDLoader.WriteFieldUsingAlreadyWrittenMesh(fname,f3) + # + t=(2.1,1,-1) + f=MEDCouplingFieldDouble(ON_GAUSS_PT) ; f.setTime(*t) ; f.setMesh(m) + f.setGaussLocalizationOnType(NORM_QUAD4,[-1.,-1.,1.,-1.,1.,1.,-1.,1.],[0.2,0.2,0.8,0.8],[0.7,0.3]) + f.setArray(DataArrayDouble([5.,3.,6.,4.])) ; f.getArray().setInfoOnComponents(["Smth"]) + f.setName(fieldName1) + f.checkCoherency() + MEDLoader.WriteFieldUsingAlreadyWrittenMesh(fname,f) + f2=MEDCouplingFieldDouble(ON_CELLS) ; f2.setTime(*t) ; f2.setMesh(m) + f2.setArray(DataArrayDouble([11.,7.],2,1)) + f2.setName(fieldName2) + MEDLoader.WriteFieldUsingAlreadyWrittenMesh(fname,f2) + f3=MEDCouplingFieldDouble(ON_NODES) ; f3.setTime(*t) ; f3.setMesh(m) + f3.setArray(DataArrayDouble([4.,2.,1.,4.,2.,1.],6,1)) + f3.setName(fieldName3) + MEDLoader.WriteFieldUsingAlreadyWrittenMesh(fname,f3) + ########## GO for reading in MEDReader,by not loading all. Mesh is fully loaded but not fields values + ms=MEDFileMeshes(fname) + fields=MEDFileFields(fname,False) + fields.removeFieldsWithoutAnyTimeStep() + fields_per_mesh=[fields.partOfThisLyingOnSpecifiedMeshName(meshName) for meshName in ms.getMeshesNames()] + allFMTSLeavesToDisplay=[] + for fields in fields_per_mesh: + allFMTSLeavesToDisplay2=[] + for fmts in fields: + tmp=fmts.splitDiscretizations() + for itmp in tmp: + self.assertTrue(not itmp.presenceOfMultiDiscPerGeoType()) + pass + allFMTSLeavesToDisplay2+=tmp + pass + allFMTSLeavesToDisplay.append(allFMTSLeavesToDisplay2) + pass + self.assertEqual(len(allFMTSLeavesToDisplay),1) + self.assertEqual(len(allFMTSLeavesToDisplay[0]),3) + allFMTSLeavesPerTimeSeries=MEDFileAnyTypeFieldMultiTS.SplitIntoCommonTimeSeries(sum(allFMTSLeavesToDisplay,[])) + self.assertEqual(len(allFMTSLeavesPerTimeSeries),1) + self.assertEqual(len(allFMTSLeavesPerTimeSeries[0]),3) + allFMTSLeavesPerCommonSupport1=MEDFileAnyTypeFieldMultiTS.SplitPerCommonSupport(allFMTSLeavesToDisplay[0],ms[ms.getMeshesNames()[0]]) + self.assertEqual(len(allFMTSLeavesPerCommonSupport1),1) + self.assertEqual(len(allFMTSLeavesPerCommonSupport1[0][0]),3) + # + mst=MEDFileMeshStruct.New(ms[0]) + # + fcscp=allFMTSLeavesPerCommonSupport1[0][1] + self.assertEqual([NORM_QUAD4],fcscp.getGeoTypesAt(0,ms[0])) + mml=fcscp.buildFromScratchDataSetSupport(0,fields) + mml2=mml.prepare() + self.assertTrue(isinstance(mml2,MEDUMeshMultiLev)) + ncc,a0,a1,a2,a3,a4,a5=mml2.buildVTUArrays() + self.assertTrue(not ncc) # spaceDim 2 -> VTK wants 3D + self.assertTrue(a0.isEqual(DataArrayDouble([0.,0.,0.,1.,0.,0.,2.,0.,0.,0.,1.,0.,1.,1.,0.,2.,1.,0.],6,3),1e-12)) + self.assertTrue(a1.isEqual(DataArrayByte([9,9]))) + self.assertTrue(a2.isEqual(DataArrayInt([0,5]))) + self.assertTrue(a3.isEqual(DataArrayInt([4,0,3,4,1,4,1,4,5,2]))) + self.assertTrue(a4 is None) + self.assertTrue(a5 is None) + a6,a7=mml2.retrieveFamilyIdsOnCells() + self.assertTrue(a6.isEqual(DataArrayInt([0,0]))) + self.assertTrue(a7) # no copy here + a8,a9=mml2.retrieveNumberIdsOnCells() + self.assertTrue(a8.isEqual(DataArrayInt([0,1]))) + self.assertTrue(a9) # no copy here + for i in xrange(1,2): + self.assertTrue((fcscp.isDataSetSupportEqualToThePreviousOne(i,fields))) + pass + vExp0=[DataArrayDouble([7.,11.]),DataArrayDouble([11.,7.])] + vExp1=[DataArrayDouble([3.,5.,4.,6.]),DataArrayDouble([5.,3.,6.,4.])] + for i in xrange(2): + f=allFMTSLeavesPerCommonSupport1[0][0][0][i] + fsst=MEDFileField1TSStructItem.BuildItemFrom(f,mst) + f.loadArraysIfNecessary() + v=mml.buildDataArray(fsst,fields,f.getUndergroundDataArray()) + self.assertEqual(f.getName(),fieldName2) + self.assertEqual(v.getHiddenCppPointer(),f.getUndergroundDataArray().getHiddenCppPointer()) + self.assertTrue(v.isEqual(vExp0[i],1e-12)) + # + f=allFMTSLeavesPerCommonSupport1[0][0][1][i] + fsst=MEDFileField1TSStructItem.BuildItemFrom(f,mst) + f.loadArraysIfNecessary() + v=mml.buildDataArray(fsst,fields,f.getUndergroundDataArray()) + self.assertEqual(f.getName(),fieldName1) + self.assertEqual(v.getHiddenCppPointer(),f.getUndergroundDataArray().getHiddenCppPointer()) + vExp1[i].setInfoOnComponents(["Smth"]) + self.assertTrue(v.isEqual(vExp1[i],1e-12)) + pass + ## Now same exercise but with a different load strategy. All is load directly. + ms=MEDFileMeshes(fname) + fields=MEDFileFields(fname) # here all is read, the SauvReader (or other Reader) is emulated + fields_per_mesh=[fields.partOfThisLyingOnSpecifiedMeshName(meshName) for meshName in ms.getMeshesNames()] + allFMTSLeavesToDisplay=[] + for fields in fields_per_mesh: + allFMTSLeavesToDisplay2=[] + for fmts in fields: + tmp=fmts.splitDiscretizations() + for itmp in tmp: + self.assertTrue(not itmp.presenceOfMultiDiscPerGeoType()) + pass + allFMTSLeavesToDisplay2+=tmp + pass + allFMTSLeavesToDisplay.append(allFMTSLeavesToDisplay2) + pass + self.assertEqual(len(allFMTSLeavesToDisplay),1) + self.assertEqual(len(allFMTSLeavesToDisplay[0]),3) + allFMTSLeavesPerTimeSeries=MEDFileAnyTypeFieldMultiTS.SplitIntoCommonTimeSeries(sum(allFMTSLeavesToDisplay,[])) + self.assertEqual(len(allFMTSLeavesPerTimeSeries),1) + self.assertEqual(len(allFMTSLeavesPerTimeSeries[0]),3) + allFMTSLeavesPerCommonSupport1=MEDFileAnyTypeFieldMultiTS.SplitPerCommonSupport(allFMTSLeavesToDisplay[0],ms[ms.getMeshesNames()[0]]) + self.assertEqual(len(allFMTSLeavesPerCommonSupport1),1) + self.assertEqual(len(allFMTSLeavesPerCommonSupport1[0][0]),3) + # + mst=MEDFileMeshStruct.New(ms[0]) + # + fcscp=allFMTSLeavesPerCommonSupport1[0][1] + mml=fcscp.buildFromScratchDataSetSupport(0,fields) + mml2=mml.prepare() + self.assertTrue(isinstance(mml2,MEDUMeshMultiLev)) + ncc,a0,a1,a2,a3,a4,a5=mml2.buildVTUArrays() + self.assertTrue(not ncc) # spaceDim 2 -> VTK wants 3D + self.assertTrue(a0.isEqual(DataArrayDouble([0.,0.,0.,1.,0.,0.,2.,0.,0.,0.,1.,0.,1.,1.,0.,2.,1.,0.],6,3),1e-12)) + self.assertTrue(a1.isEqual(DataArrayByte([9,9]))) + self.assertTrue(a2.isEqual(DataArrayInt([0,5]))) + self.assertTrue(a3.isEqual(DataArrayInt([4,0,3,4,1,4,1,4,5,2]))) + self.assertTrue(a4 is None) + self.assertTrue(a5 is None) + a6,a7=mml2.retrieveFamilyIdsOnCells() + self.assertTrue(a6.isEqual(DataArrayInt([0,0]))) + self.assertTrue(a7) # no copy here + a8,a9=mml2.retrieveNumberIdsOnCells() + self.assertTrue(a8.isEqual(DataArrayInt([0,1]))) + self.assertTrue(a9) # no copy here + for i in xrange(1,2): + self.assertTrue((fcscp.isDataSetSupportEqualToThePreviousOne(i,fields))) + pass + vExp0=[DataArrayDouble([7.,11.]),DataArrayDouble([11.,7.])] + vExp1=[DataArrayDouble([3.,5.,4.,6.]),DataArrayDouble([5.,3.,6.,4.])] + for i in xrange(2): + f=allFMTSLeavesPerCommonSupport1[0][0][0][i] + fsst=MEDFileField1TSStructItem.BuildItemFrom(f,mst) # no load needed here + v=mml.buildDataArray(fsst,fields,f.getUndergroundDataArray()) + self.assertEqual(f.getName(),fieldName2) + self.assertEqual(v.getHiddenCppPointer(),f.getUndergroundDataArray().getHiddenCppPointer()) + self.assertTrue(v.isEqual(vExp0[i],1e-12)) + # + f=allFMTSLeavesPerCommonSupport1[0][0][1][i] + fsst=MEDFileField1TSStructItem.BuildItemFrom(f,mst) # no load needed here + v=mml.buildDataArray(fsst,fields,f.getUndergroundDataArray()) + self.assertEqual(f.getName(),fieldName1) + self.assertEqual(v.getHiddenCppPointer(),f.getUndergroundDataArray().getHiddenCppPointer()) + vExp1[i].setInfoOnComponents(["Smth"]) + self.assertTrue(v.isEqual(vExp1[i],1e-12)) + pass + pass + + def test19(self): + """ + This test is a simple non profile CELL field but lying on cells of dimension -1 (not 0 as "usual"). + """ + fname="ForMEDReader19.med" + fieldName="ACellFieldOnDimM1" + coo=DataArrayDouble(3) ; coo.iota() + m=MEDCouplingCMesh() ; m.setCoords(coo,coo,coo) ; m.setName("mesh") + m0=m.buildUnstructured() ; del m + m1=m0.computeSkin() + # + mm=MEDFileUMesh() + mm.setMeshAtLevel(0,m0) + mm.setMeshAtLevel(-1,m1) + ff=MEDFileFieldMultiTS() + # time 0 + t=(1.1,1,-1) + f=MEDCouplingFieldDouble(ON_CELLS) ; f.setTime(*t) ; f.setMesh(m1) + f.setName(fieldName) + arr=DataArrayDouble(24) ; arr.iota() ; arr.setInfoOnComponents(["AStr"]) + f.setArray(arr) + f.checkCoherency() + f1ts=MEDFileField1TS() ; f1ts.setFieldNoProfileSBT(f) + ff.pushBackTimeStep(f1ts) + # time 1 + t=(2.1,2,-2) + f=MEDCouplingFieldDouble(ON_CELLS) ; f.setTime(*t) ; f.setMesh(m1) + f.setName(fieldName) + arr=DataArrayDouble(24) ; arr.iota() ; arr.reverse() ; arr.setInfoOnComponents(["AStr"]) + f.setArray(arr) + f.checkCoherency() + f1ts=MEDFileField1TS() ; f1ts.setFieldNoProfileSBT(f) + ff.pushBackTimeStep(f1ts) + # + mm.write(fname,2) + ff.write(fname,0) + ########## GO for reading in MEDReader,by not loading all. Mesh is fully loaded but not fields values + ms=MEDFileMeshes(fname) + fields=MEDFileFields(fname,False) + fields.removeFieldsWithoutAnyTimeStep() + fields_per_mesh=[fields.partOfThisLyingOnSpecifiedMeshName(meshName) for meshName in ms.getMeshesNames()] + allFMTSLeavesToDisplay=[] + for fields in fields_per_mesh: + allFMTSLeavesToDisplay2=[] + for fmts in fields: + tmp=fmts.splitDiscretizations() + for itmp in tmp: + self.assertTrue(not itmp.presenceOfMultiDiscPerGeoType()) + pass + allFMTSLeavesToDisplay2+=tmp + pass + allFMTSLeavesToDisplay.append(allFMTSLeavesToDisplay2) + pass + self.assertEqual(len(allFMTSLeavesToDisplay),1) + self.assertEqual(len(allFMTSLeavesToDisplay[0]),1) + allFMTSLeavesPerTimeSeries=MEDFileAnyTypeFieldMultiTS.SplitIntoCommonTimeSeries(sum(allFMTSLeavesToDisplay,[])) + self.assertEqual(len(allFMTSLeavesPerTimeSeries),1) + self.assertEqual(len(allFMTSLeavesPerTimeSeries[0]),1) + allFMTSLeavesPerCommonSupport1=MEDFileAnyTypeFieldMultiTS.SplitPerCommonSupport(allFMTSLeavesToDisplay[0],ms[ms.getMeshesNames()[0]]) + self.assertEqual(len(allFMTSLeavesPerCommonSupport1),1) + self.assertEqual(len(allFMTSLeavesPerCommonSupport1[0][0]),1) + # + mst=MEDFileMeshStruct.New(ms[0]) + # + fcscp=allFMTSLeavesPerCommonSupport1[0][1] + mml=fcscp.buildFromScratchDataSetSupport(0,fields) + mml2=mml.prepare() + self.assertTrue(isinstance(mml2,MEDUMeshMultiLev)) + ncc,a0,a1,a2,a3,a4,a5=mml2.buildVTUArrays() + self.assertTrue(ncc) + self.assertTrue(a0.isEqual(DataArrayDouble([0.,0.,0.,1.,0.,0.,2.,0.,0.,0.,1.,0.,1.,1.,0.,2.,1.,0.,0.,2.,0.,1.,2.,0.,2.,2.,0.,0.,0.,1.,1.,0.,1.,2.,0.,1.,0.,1.,1.,1.,1.,1.,2.,1.,1.,0.,2.,1.,1.,2.,1.,2.,2.,1.,0.,0.,2.,1.,0.,2.,2.,0.,2.,0.,1.,2.,1.,1.,2.,2.,1.,2.,0.,2.,2.,1.,2.,2.,2.,2.,2.],27,3),1e-12)) + self.assertTrue(a1.isEqual(DataArrayByte([9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9]))) + self.assertTrue(a2.isEqual(DataArrayInt([0,5,10,15,20,25,30,35,40,45,50,55,60,65,70,75,80,85,90,95,100,105,110,115]))) + self.assertTrue(a3.isEqual(DataArrayInt([4,1,0,3,4,4,1,10,9,0,4,0,9,12,3,4,2,1,4,5,4,2,11,10,1,4,5,14,11,2,4,4,3,6,7,4,3,12,15,6,4,6,15,16,7,4,5,4,7,8,4,7,16,17,8,4,8,17,14,5,4,19,22,21,18,4,10,19,18,9,4,9,18,21,12,4,20,23,22,19,4,11,20,19,10,4,14,23,20,11,4,22,25,24,21,4,12,21,24,15,4,15,24,25,16,4,23,26,25,22,4,16,25,26,17,4,17,26,23,14]))) + self.assertTrue(a4 is None) + self.assertTrue(a5 is None) + a6,a7=mml2.retrieveFamilyIdsOnCells() + self.assertTrue(a6.isEqual(DataArrayInt([0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]))) + self.assertTrue(a7) # no copy here + a8,a9=mml2.retrieveNumberIdsOnCells() + self.assertTrue(a8 is None) + self.assertTrue(a9) # no copy here + a10,a11=mml2.retrieveFamilyIdsOnNodes() + self.assertTrue(not a10) + self.assertTrue(a11) # no copy here + a12,a13=mml2.retrieveNumberIdsOnNodes() + self.assertTrue(not a12) + self.assertTrue(a13) # no copy here + for i in xrange(1,2): + self.assertTrue((fcscp.isDataSetSupportEqualToThePreviousOne(i,fields))) + pass + for i in xrange(2): + f=allFMTSLeavesPerCommonSupport1[0][0][0][i] + fsst=MEDFileField1TSStructItem.BuildItemFrom(f,mst) + f.loadArraysIfNecessary() + v=mml.buildDataArray(fsst,fields,f.getUndergroundDataArray()) + self.assertEqual(f.getName(),fieldName) + self.assertEqual(v.getHiddenCppPointer(),f.getUndergroundDataArray().getHiddenCppPointer()) + vExp=DataArrayDouble(24) ; vExp.iota() + if i==1: vExp.reverse() + vExp.setInfoOnComponents(["AStr"]) + self.assertTrue(v.isEqual(vExp,1e-12)) + pass + pass + + def test20(self): + """ This test works with groups/families on cells AND on nodes. Here 4 fields each on same time steps (2). + 1 field on CELLS without profile, 1 field on CELLS with profile, 1 field on NODES without profile, 1 field on NODES with profile. + All of these 4 fields lies on a single mesh "mesh". The 2 fields on profile lies on a same support. + One drawback of this test : no multi geom type. Coming soon ! + """ + fname="ForMEDReader20.med" + fieldName0="ANodeField" + fieldName1="ACellField" + fieldName2="ANodeFieldPfl" + fieldName3="ACellFieldPfl" + pfl2=DataArrayInt([5,6,7,10,11,12,15,16,17,20,21,22]) ; pfl2.setName("pfl2") + pfl3=DataArrayInt([4,5,8,9,12,13]) ; pfl3.setName("pfl3") + # + arr=DataArrayDouble(5) ; arr.iota() + m=MEDCouplingCMesh("mesh") ; m.setCoords(arr,arr) + m=m.buildUnstructured() + mm=MEDFileUMesh() + mm.setMeshAtLevel(0,m) + fs=MEDFileFields() + fmts0=MEDFileFieldMultiTS() ; fs.pushField(fmts0) + fmts0.setDtUnit("s") + fmts1=MEDFileFieldMultiTS() ; fs.pushField(fmts1) + fmts1.setDtUnit("s") + fmts2=MEDFileFieldMultiTS() ; fs.pushField(fmts2) + fmts2.setDtUnit("s") + fmts3=MEDFileFieldMultiTS() ; fs.pushField(fmts3) + fmts3.setDtUnit("s") + #### + t=(1.1,0,-2) + f0=MEDCouplingFieldDouble(ON_NODES) ; f0.setMesh(m) + f0.setName(fieldName0) ; f0.setTime(*t) + da=m.getCoords().magnitude() ; da.setInfoOnComponents(["zeInfo"]) + f0.setArray(da) + f0.checkCoherency() + f1ts=MEDFileField1TS() + f1ts.setFieldNoProfileSBT(f0) + fmts0.pushBackTimeStep(f1ts) + # + f1=MEDCouplingFieldDouble(ON_CELLS) ; f1.setMesh(m) + f1.setName(fieldName1) ; f1.setTime(*t) + da=m.getBarycenterAndOwner().magnitude() ; da.setInfoOnComponents(["zeInfoCell"]) + f1.setArray(da) + f1.checkCoherency() + f1ts=MEDFileField1TS() + f1ts.setFieldNoProfileSBT(f1) + fmts1.pushBackTimeStep(f1ts) + # + f2=MEDCouplingFieldDouble(ON_NODES) ; mTmp=m[pfl3] ; mTmp.zipCoords() ; mTmp.setName(m.getName()) ; f2.setMesh(mTmp) + f2.setName(fieldName2) ; f2.setTime(*t) + da=m.getCoords().magnitude()[pfl2] ; da.setInfoOnComponents(["zzzz"]) + f2.setArray(da) + f2.checkCoherency() + f1ts=MEDFileField1TS() + f1ts.setFieldProfile(f2,mm,0,pfl2) + fmts2.pushBackTimeStep(f1ts) + # + f3=MEDCouplingFieldDouble(ON_CELLS) ; mTmp=m[pfl3] ; mTmp.setName(m.getName()) ; f3.setMesh(mTmp) + f3.setName(fieldName3) ; f3.setTime(*t) + da=mTmp.getBarycenterAndOwner().magnitude() ; da.setInfoOnComponents(["abcdefg"]) + f3.setArray(da) + f3.checkCoherency() + f1ts=MEDFileField1TS() + f1ts.setFieldProfile(f3,mm,0,pfl3) + fmts3.pushBackTimeStep(f1ts) + #### + t=(2.1,1,-3) + f0=MEDCouplingFieldDouble(ON_NODES) ; f0.setMesh(m) + f0.setName(fieldName0) ; f0.setTime(*t) + da=m.getCoords().magnitude() ; da.reverse() ; da.setInfoOnComponents(["zeInfo"]) + f0.setArray(da) + f0.checkCoherency() + f1ts=MEDFileField1TS() + f1ts.setFieldNoProfileSBT(f0) + fmts0.pushBackTimeStep(f1ts) + # + f1=MEDCouplingFieldDouble(ON_CELLS) ; f1.setMesh(m) + f1.setName(fieldName1) ; f1.setTime(*t) + da=m.getBarycenterAndOwner().magnitude() ; da.reverse() ; da.setInfoOnComponents(["zeInfoCell"]) + f1.setArray(da) + f1.checkCoherency() + f1ts=MEDFileField1TS() + f1ts.setFieldNoProfileSBT(f1) + fmts1.pushBackTimeStep(f1ts) + # + f2=MEDCouplingFieldDouble(ON_NODES) ; mTmp=m[pfl3] ; mTmp.zipCoords() ; mTmp.setName(m.getName()) ; f2.setMesh(mTmp) + f2.setName(fieldName2) ; f2.setTime(*t) + da=m.getCoords().magnitude()[pfl2] ; da.reverse() ; da.setInfoOnComponents(["zzzz"]) + f2.setArray(da) + f2.checkCoherency() + f1ts=MEDFileField1TS() + f1ts.setFieldProfile(f2,mm,0,pfl2) + fmts2.pushBackTimeStep(f1ts) + # + f3=MEDCouplingFieldDouble(ON_CELLS) ; mTmp=m[pfl3] ; mTmp.setName(m.getName()) ; f3.setMesh(mTmp) + f3.setName(fieldName3) ; f3.setTime(*t) + da=mTmp.getBarycenterAndOwner().magnitude() ; da.reverse() ; da.setInfoOnComponents(["abcdefg"]) + f3.setArray(da) + f3.checkCoherency() + f1ts=MEDFileField1TS() + f1ts.setFieldProfile(f3,mm,0,pfl3) + fmts3.pushBackTimeStep(f1ts) + #### + grp1=DataArrayInt([6,7,8,11,12,13,16,17,18]) ; grp1.setName("grp1") + grp2=DataArrayInt([10,11,15,16,20,21]) ; grp2.setName("grp2") + mm.setGroupsAtLevel(1,[grp1,grp2]) + grp3=DataArrayInt([4,5,6]) ; grp3.setName("grp3") + grp4=DataArrayInt([8,9,10]) ; grp4.setName("grp4") + mm.setGroupsAtLevel(0,[grp3,grp4]) + d=DataArrayInt(25) ; d.iota() ; d*=10 ; mm.setRenumFieldArr(1,d) + d=DataArrayInt(16) ; d.iota() ; d*=11 ; mm.setRenumFieldArr(0,d) + mm.write(fname,2) + fs.appendGlobs(fmts2,1e-12) + fs.appendGlobs(fmts3,1e-12) + fs.write(fname,0) + ########## GO for reading in MEDReader,by not loading all. Mesh is fully loaded but not fields values + ms=MEDFileMeshes(fname) + fields=MEDFileFields(fname,False) + fields.removeFieldsWithoutAnyTimeStep() + fields_per_mesh=[fields.partOfThisLyingOnSpecifiedMeshName(meshName) for meshName in ms.getMeshesNames()] + allFMTSLeavesToDisplay=[] + for fields in fields_per_mesh: + allFMTSLeavesToDisplay2=[] + for fmts in fields: + tmp=fmts.splitDiscretizations() + for itmp in tmp: + self.assertTrue(not itmp.presenceOfMultiDiscPerGeoType()) + pass + allFMTSLeavesToDisplay2+=tmp + pass + allFMTSLeavesToDisplay.append(allFMTSLeavesToDisplay2) + pass + self.assertEqual(len(allFMTSLeavesToDisplay),1) + self.assertEqual(len(allFMTSLeavesToDisplay[0]),4) + allFMTSLeavesPerTimeSeries=MEDFileAnyTypeFieldMultiTS.SplitIntoCommonTimeSeries(sum(allFMTSLeavesToDisplay,[])) + self.assertEqual(len(allFMTSLeavesPerTimeSeries),1) + self.assertEqual(len(allFMTSLeavesPerTimeSeries[0]),4) + allFMTSLeavesPerCommonSupport1=MEDFileAnyTypeFieldMultiTS.SplitPerCommonSupport(allFMTSLeavesToDisplay[0],ms[ms.getMeshesNames()[0]]) + self.assertEqual(len(allFMTSLeavesPerCommonSupport1),2) + self.assertEqual(len(allFMTSLeavesPerCommonSupport1[0][0]),2) + self.assertEqual(len(allFMTSLeavesPerCommonSupport1[1][0]),2) + # + mst=MEDFileMeshStruct.New(ms[0]) + # + fcscp=allFMTSLeavesPerCommonSupport1[0][1] + mml=fcscp.buildFromScratchDataSetSupport(0,fields) + mml2=mml.prepare() + self.assertTrue(isinstance(mml2,MEDUMeshMultiLev)) + ncc,a0,a1,a2,a3,a4,a5=mml2.buildVTUArrays() + self.assertTrue(not ncc) + self.assertTrue(a0.isEqual(DataArrayDouble([0.,0.,0.,1.,0.,0.,2.,0.,0.,3.,0.,0.,4.,0.,0.,0.,1.,0.,1.,1.,0.,2.,1.,0.,3.,1.,0.,4.,1.,0.,0.,2.,0.,1.,2.,0.,2.,2.,0.,3.,2.,0.,4.,2.,0.,0.,3.,0.,1.,3.,0.,2.,3.,0.,3.,3.,0.,4.,3.,0.,0.,4.,0.,1.,4.,0.,2.,4.,0.,3.,4.,0.,4.,4.,0.],25,3),1e-12)) + self.assertTrue(a1.isEqual(DataArrayByte([9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9]))) + self.assertTrue(a2.isEqual(DataArrayInt([0,5,10,15,20,25,30,35,40,45,50,55,60,65,70,75]))) + self.assertTrue(a3.isEqual(DataArrayInt([4,1,0,5,6,4,2,1,6,7,4,3,2,7,8,4,4,3,8,9,4,6,5,10,11,4,7,6,11,12,4,8,7,12,13,4,9,8,13,14,4,11,10,15,16,4,12,11,16,17,4,13,12,17,18,4,14,13,18,19,4,16,15,20,21,4,17,16,21,22,4,18,17,22,23,4,19,18,23,24]))) + self.assertTrue(a4 is None) + self.assertTrue(a5 is None) + a6,a7=mml2.retrieveFamilyIdsOnCells() + self.assertTrue(a6.isEqual(DataArrayInt([-5,-5,-5,-5,-6,-6,-6,-5,-7,-7,-7,-5,-5,-5,-5,-5]))) + self.assertTrue(a7) # no copy here + a8,a9=mml2.retrieveNumberIdsOnCells() + self.assertTrue(a8.isEqual(DataArrayInt([0,11,22,33,44,55,66,77,88,99,110,121,132,143,154,165]))) + self.assertTrue(a9) # no copy here + a10,a11=mml2.retrieveFamilyIdsOnNodes() + self.assertTrue(a10.isEqual(DataArrayInt([1,1,1,1,1,1,2,2,2,1,3,4,2,2,1,3,4,2,2,1,3,3,1,1,1]))) + self.assertTrue(a11) # no copy here + a12,a13=mml2.retrieveNumberIdsOnNodes() + self.assertTrue(a12.isEqual(DataArrayInt([0,10,20,30,40,50,60,70,80,90,100,110,120,130,140,150,160,170,180,190,200,210,220,230,240]))) + self.assertTrue(a13) # no copy here + for i in xrange(1,2): + self.assertTrue((fcscp.isDataSetSupportEqualToThePreviousOne(i,fields))) + pass + for i in xrange(2): + f=allFMTSLeavesPerCommonSupport1[0][0][0][i] + fsst=MEDFileField1TSStructItem.BuildItemFrom(f,mst) + f.loadArraysIfNecessary() + v=mml.buildDataArray(fsst,fields,f.getUndergroundDataArray()) + self.assertEqual(f.getName(),fieldName1) + self.assertEqual(v.getHiddenCppPointer(),f.getUndergroundDataArray().getHiddenCppPointer()) + vExp=DataArrayDouble([0.7071067811865476,1.5811388300841898,2.5495097567963922,3.5355339059327378,1.5811388300841898,2.1213203435596424,2.9154759474226504,3.8078865529319543,2.5495097567963922,2.9154759474226504,3.5355339059327378,4.301162633521313,3.5355339059327378,3.8078865529319543,4.301162633521313,4.949747468305833]) + if i==1: vExp.reverse() + vExp.setInfoOnComponents(["zeInfoCell"]) + self.assertTrue(v.isEqual(vExp,1e-12)) + # + f=allFMTSLeavesPerCommonSupport1[0][0][1][i] + fsst=MEDFileField1TSStructItem.BuildItemFrom(f,mst) + f.loadArraysIfNecessary() + v=mml.buildDataArray(fsst,fields,f.getUndergroundDataArray()) + self.assertEqual(f.getName(),fieldName0) + self.assertEqual(v.getHiddenCppPointer(),f.getUndergroundDataArray().getHiddenCppPointer()) + vExp=DataArrayDouble([0.,1.,2.,3.,4.,1.,1.4142135623730951,2.23606797749979,3.1622776601683795,4.123105625617661,2.,2.23606797749979,2.8284271247461903,3.605551275463989,4.47213595499958,3.,3.1622776601683795,3.605551275463989,4.242640687119285,5.,4.,4.123105625617661,4.47213595499958,5.,5.656854249492381]) + if i==1: vExp.reverse() + vExp.setInfoOnComponents(["zeInfo"]) + self.assertTrue(v.isEqual(vExp,1e-12)) + pass + ### Testing the 2nd support + fcscp=allFMTSLeavesPerCommonSupport1[1][1] + mml=fcscp.buildFromScratchDataSetSupport(0,fields) + mml2=mml.prepare() + self.assertTrue(isinstance(mml2,MEDUMeshMultiLev)) + ncc,a0,a1,a2,a3,a4,a5=mml2.buildVTUArrays() + self.assertTrue(not ncc) + self.assertTrue(not ncc) + self.assertTrue(a0.isEqual(DataArrayDouble([0.,1.,0.,1.,1.,0.,2.,1.,0.,0.,2.,0.,1.,2.,0.,2.,2.,0.,0.,3.,0.,1.,3.,0.,2.,3.,0.,0.,4.,0.,1.,4.,0.,2.,4.,0.],12,3),1e-12)) + self.assertTrue(a1.isEqual(DataArrayByte([9,9,9,9,9,9]))) + self.assertTrue(a2.isEqual(DataArrayInt([0,5,10,15,20,25]))) + self.assertTrue(a3.isEqual(DataArrayInt([4,1,0,3,4,4,2,1,4,5,4,4,3,6,7,4,5,4,7,8,4,7,6,9,10,4,8,7,10,11]))) + self.assertTrue(a4 is None) + self.assertTrue(a5 is None) + a6,a7=mml2.retrieveFamilyIdsOnCells() + self.assertTrue(a6.isEqual(DataArrayInt([-6,-6,-7,-7,-5,-5]))) + self.assertTrue(not a7) # copy here + a8,a9=mml2.retrieveNumberIdsOnCells() + self.assertTrue(a8.isEqual(DataArrayInt([44,55,88,99,132,143]))) + self.assertTrue(not a9) # copy here + a10,a11=mml2.retrieveFamilyIdsOnNodes() + self.assertTrue(a10.isEqual(DataArrayInt([1,2,2,3,4,2,3,4,2,3,3,1]))) + self.assertTrue(not a11) # copy here + a12,a13=mml2.retrieveNumberIdsOnNodes() + self.assertTrue(a12.isEqual(DataArrayInt([50,60,70,100,110,120,150,160,170,200,210,220]))) + self.assertTrue(not a13) # copy here + for i in xrange(2): + f=allFMTSLeavesPerCommonSupport1[1][0][0][i] + fsst=MEDFileField1TSStructItem.BuildItemFrom(f,mst) + f.loadArraysIfNecessary() + v=mml.buildDataArray(fsst,fields,f.getUndergroundDataArray()) + self.assertEqual(f.getName(),fieldName3) + self.assertEqual(v.getHiddenCppPointer(),f.getUndergroundDataArray().getHiddenCppPointer()) + vExp=DataArrayDouble([1.5811388300842,2.1213203435596,2.5495097567964,2.9154759474227,3.5355339059327,3.807886552932]) + if i==1: vExp.reverse() + vExp.setInfoOnComponents(["abcdefg"]) + self.assertTrue(v.isEqual(vExp,1e-12)) + # + f=allFMTSLeavesPerCommonSupport1[1][0][1][i] + fsst=MEDFileField1TSStructItem.BuildItemFrom(f,mst) + f.loadArraysIfNecessary() + v=mml.buildDataArray(fsst,fields,f.getUndergroundDataArray()) + self.assertEqual(f.getName(),fieldName2) + self.assertEqual(v.getHiddenCppPointer(),f.getUndergroundDataArray().getHiddenCppPointer()) + vExp=DataArrayDouble([1.,1.4142135623731,2.2360679774998,2.,2.2360679774998,2.8284271247462,3.,3.1622776601684,3.605551275464,4.,4.1231056256177,4.4721359549996]) + if i==1: vExp.reverse() + vExp.setInfoOnComponents(["zzzz"]) + self.assertTrue(v.isEqual(vExp,1e-12)) + pass + pass + + def test21(self): + """ Here the created MED file contains only a mesh. The aim here is to test capability of MEDReader to support no fields. + This test checks nothing but write a MED file to be used by MEDReader tests. + """ + fname="ForMEDReader21.med" + mm=MEDFileUMesh() + # + m0=MEDCouplingCMesh("mesh") ; arr=DataArrayDouble(5) ; arr.iota() ; m0.setCoords(arr,arr) ; m0=m0.buildUnstructured() + mm.setMeshAtLevel(0,m0) + grp0=DataArrayInt([5,6,9,10]) ; grp0.setName("Inside2D") + grp1=DataArrayInt([0,1,2,3,4,7,8,11,12,13,14,15]) ; grp1.setName("Border2D") + grp2=DataArrayInt([2,3,6,7]) ; grp2.setName("LowerRight2D") + mm.setGroupsAtLevel(0,[grp0,grp1,grp2]) + # + m1=MEDCouplingUMesh(m0.getName(),1) ; m1.setCoords(m0.getCoords()) ; m1.allocateCells() + for elt in [[0,1],[1,2],[2,3],[3,4],[4,9],[9,14],[14,19],[19,24],[24,23],[23,22],[22,21],[21,20],[20,15],[15,10],[10,5],[5,0],[2,7],[7,12],[12,17],[17,22], + [10,11],[11,12],[12,13],[13,14]]: + m1.insertNextCell(NORM_SEG2,elt) + pass + mm.setMeshAtLevel(-1,m1) + grp4=DataArrayInt([0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15]) ; grp4.setName("Border1D") + grp5=DataArrayInt([16,17,18,19,20,21,22,23]) ; grp5.setName("Inside1D") + grp6=DataArrayInt([18,19,22,23]) ; grp6.setName("UpperRight1D") + mm.setGroupsAtLevel(-1,[grp4,grp5,grp6]) + # + grp7=DataArrayInt([1,2,3,6,7,8,11,12,13,16,17,18,21,22,23]) ; grp7.setName("InsideYNode") + grp8=DataArrayInt([5,6,7,8,9,10,11,12,13,14,15,16,17,18,19]) ; grp8.setName("InsideXNode") + mm.setGroupsAtLevel(1,[grp7,grp8]) + # + mm.write(fname,2) + pass + + def test22(self): + """ Use case where a field on nodes (ANodeField) on a mesh defined both in meshdim 2 and meshdim 1. + The only possible geometrical support that suits the field is those with meshdim equal to 1 (-1 in relative). + """ + fname="ForMEDReader22.med" + fieldName0="ANodeField" + mm=MEDFileUMesh() + coo=DataArrayDouble([(4.,3.),(7.,3.),(2.,5.),(6.,5.),(9.,5.),(4.,7.),(8.,7.),(3.,8.),(9.,8.)]) + m0=MEDCouplingUMesh("mesh",2) ; m0.setCoords(coo) ; m0.allocateCells() ; m0.insertNextCell(NORM_TRI3,[2,3,0]) ; m0.insertNextCell(NORM_TRI3,[3,1,0]) ; m0.insertNextCell(NORM_TRI3,[3,4,1]) + mm.setMeshAtLevel(0,m0) + m1=MEDCouplingUMesh("mesh",1) ; m1.setCoords(coo) ; m1.allocateCells() ; m1.insertNextCell(NORM_SEG2,[2,0]) ; m1.insertNextCell(NORM_SEG2,[0,1]) ; m1.insertNextCell(NORM_SEG2,[1,4]) + m1.insertNextCell(NORM_SEG2,[3,5]) ; m1.insertNextCell(NORM_SEG2,[5,7]) ; m1.insertNextCell(NORM_SEG2,[3,6]) ; m1.insertNextCell(NORM_SEG2,[6,8]) + mm.setMeshAtLevel(-1,m1) + fs=MEDFileFields() + fmts0=MEDFileFieldMultiTS() ; fs.pushField(fmts0) + fmts0.setDtUnit("s") + # + t=(1.1,0,-2) + f0=MEDCouplingFieldDouble(ON_NODES) ; f0.setMesh(m1) + f0.setName(fieldName0) ; f0.setTime(*t) + da=DataArrayDouble(9) ; da.iota() ; da.setInfoOnComponents(["zeInfo"]) + f0.setArray(da) + f0.checkCoherency() + f1ts=MEDFileField1TS() + f1ts.setFieldNoProfileSBT(f0) + fmts0.pushBackTimeStep(f1ts) + # + t=(2.1,1,-3) + f0=MEDCouplingFieldDouble(ON_NODES) ; f0.setMesh(m1) + f0.setName(fieldName0) ; f0.setTime(*t) + da=DataArrayDouble(9) ; da.iota() ; da.reverse() ; da.setInfoOnComponents(["zeInfo"]) + f0.setArray(da) + f0.checkCoherency() + f1ts=MEDFileField1TS() + f1ts.setFieldNoProfileSBT(f0) + fmts0.pushBackTimeStep(f1ts) + # + mm.write(fname,2) + fs.write(fname,0) + ########## GO for reading in MEDReader,by not loading all. Mesh is fully loaded but not fields values + ms=MEDFileMeshes(fname) + fields=MEDFileFields(fname,False) + fields.removeFieldsWithoutAnyTimeStep() + fields_per_mesh=[fields.partOfThisLyingOnSpecifiedMeshName(meshName) for meshName in ms.getMeshesNames()] + allFMTSLeavesToDisplay=[] + for fields in fields_per_mesh: + allFMTSLeavesToDisplay2=[] + for fmts in fields: + tmp=fmts.splitDiscretizations() + for itmp in tmp: + self.assertTrue(not itmp.presenceOfMultiDiscPerGeoType()) + pass + allFMTSLeavesToDisplay2+=tmp + pass + allFMTSLeavesToDisplay.append(allFMTSLeavesToDisplay2) + pass + self.assertEqual(len(allFMTSLeavesToDisplay),1) + self.assertEqual(len(allFMTSLeavesToDisplay[0]),1) + allFMTSLeavesPerTimeSeries=MEDFileAnyTypeFieldMultiTS.SplitIntoCommonTimeSeries(sum(allFMTSLeavesToDisplay,[])) + self.assertEqual(len(allFMTSLeavesPerTimeSeries),1) + self.assertEqual(len(allFMTSLeavesPerTimeSeries[0]),1) + allFMTSLeavesPerCommonSupport1=MEDFileAnyTypeFieldMultiTS.SplitPerCommonSupport(allFMTSLeavesToDisplay[0],ms[ms.getMeshesNames()[0]]) + self.assertEqual(len(allFMTSLeavesPerCommonSupport1),1) + self.assertEqual(len(allFMTSLeavesPerCommonSupport1[0][0]),1) + # + mst=MEDFileMeshStruct.New(ms[0]) + # + fcscp=allFMTSLeavesPerCommonSupport1[0][1] + self.assertEqual([NORM_TRI3,NORM_SEG2],fcscp.getGeoTypesAt(0,ms[0]))#contains all cell types of underlying mesh because only nodes with no profiles + mml=fcscp.buildFromScratchDataSetSupport(0,fields) + mml2=mml.prepare() + self.assertTrue(isinstance(mml2,MEDUMeshMultiLev)) + ncc,a0,a1,a2,a3,a4,a5=mml2.buildVTUArrays() + self.assertTrue(not ncc) + self.assertTrue(a0.isEqual(DataArrayDouble([(4.,3.,0.),(7.,3.,0.),(2.,5.,0.),(6.,5.,0.),(9.,5.,0.),(4.,7.,0.),(8.,7.,0.),(3.,8.,0.),(9.,8.,0.)]),1e-12)) + self.assertTrue(a1.isEqual(DataArrayByte([5,5,5,3,3,3,3,3,3,3]))) + self.assertTrue(a2.isEqual(DataArrayInt([0,4,8,12,15,18,21,24,27,30]))) + self.assertTrue(a3.isEqual(DataArrayInt([3,2,3,0,3,3,1,0,3,3,4,1,2,2,0,2,0,1,2,1,4,2,3,5,2,5,7,2,3,6,2,6,8]))) + self.assertTrue(a4 is None) + self.assertTrue(a5 is None) + a6,a7=mml2.retrieveFamilyIdsOnCells() + self.assertTrue(a6.isEqual(DataArrayInt([0,0,0,0,0,0,0,0,0,0]))) + self.assertTrue(not a7) # copy here + a8,a9=mml2.retrieveNumberIdsOnCells() + self.assertTrue(not a8) + self.assertTrue(a9) # nocopy here + a10,a11=mml2.retrieveFamilyIdsOnNodes() + self.assertTrue(not a10) + self.assertTrue(a11) # no copy here + a12,a13=mml2.retrieveNumberIdsOnNodes() + self.assertTrue(not a12) + self.assertTrue(a13) # no copy here + # + f=allFMTSLeavesPerCommonSupport1[0][0][0][0] + fsst=MEDFileField1TSStructItem.BuildItemFrom(f,mst) + f.loadArraysIfNecessary() + v=mml.buildDataArray(fsst,fields,f.getUndergroundDataArray()) + self.assertEqual(f.getName(),fieldName0) + self.assertEqual(v.getHiddenCppPointer(),f.getUndergroundDataArray().getHiddenCppPointer()) + vExp=DataArrayDouble(9) ; vExp.iota() ; vExp.setInfoOnComponents(["zeInfo"]) + self.assertTrue(v.isEqual(vExp,1e-12)) + # + f=allFMTSLeavesPerCommonSupport1[0][0][0][1] + fsst=MEDFileField1TSStructItem.BuildItemFrom(f,mst) + f.loadArraysIfNecessary() + v=mml.buildDataArray(fsst,fields,f.getUndergroundDataArray()) + self.assertEqual(f.getName(),fieldName0) + self.assertEqual(v.getHiddenCppPointer(),f.getUndergroundDataArray().getHiddenCppPointer()) + vExp=DataArrayDouble(9) ; vExp.iota() ; vExp.setInfoOnComponents(["zeInfo"]) ; vExp.reverse() + self.assertTrue(v.isEqual(vExp,1e-12)) + pass + + def test23(self): + """ Non regression test 2219 of modes. Idem than test22 except that here the node field is on profile. + """ + fname="ForMEDReader23.med" + fieldName0="ANodeField" + mm=MEDFileUMesh() + coo=DataArrayDouble([(4.,3.),(7.,3.),(2.,5.),(6.,5.),(9.,5.),(4.,7.),(8.,7.),(3.,8.),(9.,8.)]) + m0=MEDCouplingUMesh("mesh",2) ; m0.setCoords(coo) ; m0.allocateCells() ; m0.insertNextCell(NORM_TRI3,[2,3,0]) ; m0.insertNextCell(NORM_TRI3,[3,1,0]) ; m0.insertNextCell(NORM_TRI3,[3,4,1]) + mm.setMeshAtLevel(0,m0) + m1=MEDCouplingUMesh("mesh",1) ; m1.setCoords(coo) ; m1.allocateCells() ; m1.insertNextCell(NORM_SEG2,[2,0]) ; m1.insertNextCell(NORM_SEG2,[0,1]) ; m1.insertNextCell(NORM_SEG2,[1,4]) + m1.insertNextCell(NORM_SEG2,[3,5]) ; m1.insertNextCell(NORM_SEG2,[5,7]) ; m1.insertNextCell(NORM_SEG2,[3,6]) ; m1.insertNextCell(NORM_SEG2,[6,8]) + mm.setMeshAtLevel(-1,m1) + fmts0=MEDFileFieldMultiTS() + fmts0.setDtUnit("s") + # + pfl=DataArrayInt([0,1,2,4]) ; pfl.setName("pfl") + pflCell=DataArrayInt([0,1,2]) ; m1Part=m1[pflCell] ; m1Part.zipCoords() + # + t=(1.1,0,-2) + f0=MEDCouplingFieldDouble(ON_NODES) ; f0.setMesh(m1Part) + f0.setName(fieldName0) ; f0.setTime(*t) + da=DataArrayDouble(4) ; da.iota() ; da.setInfoOnComponents(["zeInfo"]) + f0.setArray(da) + f0.checkCoherency() + f1ts=MEDFileField1TS() + f1ts.setFieldProfile(f0,mm,-1,pfl) + fmts0.pushBackTimeStep(f1ts) + # + t=(2.1,1,-3) + f0=MEDCouplingFieldDouble(ON_NODES) ; f0.setMesh(m1Part) + f0.setName(fieldName0) ; f0.setTime(*t) + da=DataArrayDouble(4) ; da.iota() ; da.reverse() ; da.setInfoOnComponents(["zeInfo"]) + f0.setArray(da) + f0.checkCoherency() + f1ts=MEDFileField1TS() + f1ts.setFieldProfile(f0,mm,-1,pfl) + fmts0.pushBackTimeStep(f1ts) + mm.write(fname,2) + fmts0.write(fname,0) + ########## GO for reading in MEDReader,by not loading all. Mesh is fully loaded but not fields values + ms=MEDFileMeshes(fname) + fields=MEDFileFields(fname,False) + fields.removeFieldsWithoutAnyTimeStep() + fields_per_mesh=[fields.partOfThisLyingOnSpecifiedMeshName(meshName) for meshName in ms.getMeshesNames()] + allFMTSLeavesToDisplay=[] + for fields in fields_per_mesh: + allFMTSLeavesToDisplay2=[] + for fmts in fields: + tmp=fmts.splitDiscretizations() + for itmp in tmp: + self.assertTrue(not itmp.presenceOfMultiDiscPerGeoType()) + pass + allFMTSLeavesToDisplay2+=tmp + pass + allFMTSLeavesToDisplay.append(allFMTSLeavesToDisplay2) + pass + self.assertEqual(len(allFMTSLeavesToDisplay),1) + self.assertEqual(len(allFMTSLeavesToDisplay[0]),1) + allFMTSLeavesPerTimeSeries=MEDFileAnyTypeFieldMultiTS.SplitIntoCommonTimeSeries(sum(allFMTSLeavesToDisplay,[])) + self.assertEqual(len(allFMTSLeavesPerTimeSeries),1) + self.assertEqual(len(allFMTSLeavesPerTimeSeries[0]),1) + allFMTSLeavesPerCommonSupport1=MEDFileAnyTypeFieldMultiTS.SplitPerCommonSupport(allFMTSLeavesToDisplay[0],ms[ms.getMeshesNames()[0]]) + self.assertEqual(len(allFMTSLeavesPerCommonSupport1),1) + self.assertEqual(len(allFMTSLeavesPerCommonSupport1[0][0]),1) + # + mst=MEDFileMeshStruct.New(ms[0]) + # + fcscp=allFMTSLeavesPerCommonSupport1[0][1] + mml=fcscp.buildFromScratchDataSetSupport(0,fields) + mml2=mml.prepare() + self.assertTrue(isinstance(mml2,MEDUMeshMultiLev)) + ncc,a0,a1,a2,a3,a4,a5=mml2.buildVTUArrays() + self.assertTrue(not ncc) + self.assertTrue(a0.isEqual(DataArrayDouble([(4.,3.,0.),(7.,3.,0.),(2.,5.,0.),(9.,5.,0.)]),1e-12)) + self.assertTrue(a1.isEqual(DataArrayByte([3,3,3]))) + self.assertTrue(a2.isEqual(DataArrayInt([0,3,6]))) + self.assertTrue(a3.isEqual(DataArrayInt([2,2,0,2,0,1,2,1,3]))) + self.assertTrue(a4 is None) + self.assertTrue(a5 is None) + a6,a7=mml2.retrieveFamilyIdsOnCells() + self.assertTrue(a6.isEqual(DataArrayInt([0,0,0]))) + self.assertTrue(not a7) # copy here + a8,a9=mml2.retrieveNumberIdsOnCells() + self.assertTrue(not a8) + self.assertTrue(a9) # nocopy here + a10,a11=mml2.retrieveFamilyIdsOnNodes() + self.assertTrue(not a10) + self.assertTrue(a11) # no copy here + a12,a13=mml2.retrieveNumberIdsOnNodes() + self.assertTrue(not a12) + self.assertTrue(a13) # no copy here + # + f=allFMTSLeavesPerCommonSupport1[0][0][0][0] + fsst=MEDFileField1TSStructItem.BuildItemFrom(f,mst) + f.loadArraysIfNecessary() + v=mml.buildDataArray(fsst,fields,f.getUndergroundDataArray()) + self.assertEqual(f.getName(),fieldName0) + vExp=DataArrayDouble(4) ; vExp.iota() ; vExp.setInfoOnComponents(["zeInfo"]) + self.assertTrue(v.isEqual(vExp,1e-12)) + # + f=allFMTSLeavesPerCommonSupport1[0][0][0][1] + fsst=MEDFileField1TSStructItem.BuildItemFrom(f,mst) + f.loadArraysIfNecessary() + v=mml.buildDataArray(fsst,fields,f.getUndergroundDataArray()) + self.assertEqual(f.getName(),fieldName0) + vExp=DataArrayDouble(4) ; vExp.iota() ; vExp.setInfoOnComponents(["zeInfo"]) ; vExp.reverse() + self.assertTrue(v.isEqual(vExp,1e-12)) + pass + + def test24(self): + """ Non regression test for cartesian mesh whose the 3rd direction has only one node. It a false 3D mesh. + """ + fname="ForMEDReader24.med" + fieldName0="zeFieldNode" + cmesh=MEDCouplingCMesh("mesh") + arr0=DataArrayDouble([0.,1.1,2.2,3.3,4.4]) + arr1=DataArrayDouble([0.,1.4,2.3]) + arr2=DataArrayDouble([5.]) + cmesh.setCoords(arr0,arr1,arr2) + fmts0=MEDFileFieldMultiTS() + fmts0.setDtUnit("s") + # + t=(1.1,2,3) + f=MEDCouplingFieldDouble(ON_NODES) ; f.setName(fieldName0) + f.setMesh(cmesh) + arr=DataArrayDouble(15) ; arr.setInfoOnComponents(["tutu"]) ; arr.iota() + f.setArray(arr) + f.setTime(*t) + f1ts=MEDFileField1TS() + f1ts.setFieldNoProfileSBT(f) + fmts0.pushBackTimeStep(f1ts) + # + t=(3.3,4,5) + arr=DataArrayDouble(15) ; arr.setInfoOnComponents(["tutu"]) ; arr.iota() + arr.reverse() + f.setArray(arr) + f.setTime(*t) + f1ts=MEDFileField1TS() + f1ts.setFieldNoProfileSBT(f) + fmts0.pushBackTimeStep(f1ts) + # + mm=MEDFileCMesh() ; mm.setMesh(cmesh) + mm.write(fname,2) + fmts0.write(fname,0) + ########## GO for reading in MEDReader,by not loading all. Mesh is fully loaded but not fields values + ms=MEDFileMeshes(fname) + fields=MEDFileFields(fname,False) + fields.removeFieldsWithoutAnyTimeStep() + fields_per_mesh=[fields.partOfThisLyingOnSpecifiedMeshName(meshName) for meshName in ms.getMeshesNames()] + allFMTSLeavesToDisplay=[] + for fields in fields_per_mesh: + allFMTSLeavesToDisplay2=[] + for fmts in fields: + tmp=fmts.splitDiscretizations() + for itmp in tmp: + self.assertTrue(not itmp.presenceOfMultiDiscPerGeoType()) + pass + allFMTSLeavesToDisplay2+=tmp + pass + allFMTSLeavesToDisplay.append(allFMTSLeavesToDisplay2) + pass + self.assertEqual(len(allFMTSLeavesToDisplay),1) + self.assertEqual(len(allFMTSLeavesToDisplay[0]),1) + allFMTSLeavesPerTimeSeries=MEDFileAnyTypeFieldMultiTS.SplitIntoCommonTimeSeries(sum(allFMTSLeavesToDisplay,[])) + self.assertEqual(len(allFMTSLeavesPerTimeSeries),1) + self.assertEqual(len(allFMTSLeavesPerTimeSeries[0]),1) + allFMTSLeavesPerCommonSupport=MEDFileAnyTypeFieldMultiTS.SplitPerCommonSupport(allFMTSLeavesToDisplay[0],ms[ms.getMeshesNames()[0]]) + self.assertEqual(len(allFMTSLeavesPerCommonSupport),1) + self.assertEqual(len(allFMTSLeavesPerCommonSupport[0][0]),1) + # + mst=MEDFileMeshStruct.New(ms[0]) + # + fcscp=allFMTSLeavesPerCommonSupport[0][1] + mml=fcscp.buildFromScratchDataSetSupport(0,fields) + mml2=mml.prepare() + self.assertTrue(isinstance(mml2,MEDCMeshMultiLev)) + (a,b,c),d=mml2.buildVTUArrays() + self.assertTrue(d)#d is True because the a,b and c are directly those in the internal data structure + self.assertTrue(a.isEqual(arr0,1e-12)) + self.assertTrue(b.isEqual(arr1,1e-12)) + self.assertTrue(c.isEqual(arr2,1e-12)) + for i in xrange(2): + f=allFMTSLeavesPerCommonSupport[0][0][0][i] + fsst=MEDFileField1TSStructItem.BuildItemFrom(f,mst) + f.loadArraysIfNecessary() + v=mml.buildDataArray(fsst,fields,f.getUndergroundDataArray()) + self.assertEqual(f.getName(),fieldName0) + self.assertEqual(v.getHiddenCppPointer(),f.getUndergroundDataArray().getHiddenCppPointer()) + vExp=DataArrayDouble(15) ; vExp.iota(0) ; vExp.setInfoOnComponents(["tutu"]) + if i==1: + vExp.reverse() + pass + self.assertTrue(v.isEqual(vExp,1e-12)) + pass + pass + + def test25(self): + """ A tricky test that reproduces an invalid behaviour + Here a same field is defined both on CELLS and GAUSS_PT, with a profile for each. + The problem appears on array computation when performing CELLS then GAUSS_PT and CELLS again. + """ + fname="ForMEDReader25.med" + m=MEDFileUMesh() + coords=DataArrayDouble([0.,0.,1.,0.,2.,0.,0.,1.,1.,1.,2.,1.,0.,2.,1.,2.,2.,2.,0.,3.,1.,3.,2.,3.,1.,4.,1.,5.,1.,6.],15,2) + m0=MEDCouplingUMesh("mesh",2) ; m0.setCoords(coords) + m0.allocateCells() + m0.insertNextCell(NORM_QUAD4,[0,3,4,1]) + m0.insertNextCell(NORM_QUAD4,[1,4,5,2]) + m0.insertNextCell(NORM_QUAD4,[3,6,7,4]) + m0.insertNextCell(NORM_QUAD4,[4,7,8,5]) + m0.insertNextCell(NORM_QUAD4,[6,9,10,7]) + m0.insertNextCell(NORM_QUAD4,[7,10,11,8]) + m.setMeshAtLevel(0,m0) + m1=MEDCouplingUMesh("mesh",1) ; m1.setCoords(coords) + m1.allocateCells() + m1.insertNextCell(NORM_SEG2,[10,12]) + m1.insertNextCell(NORM_SEG2,[12,13]) + m1.insertNextCell(NORM_SEG2,[13,14]) + m.setMeshAtLevel(-1,m1) + m.setFamilyFieldArr(0,DataArrayInt([-1,-2,-3,-4,-5,-6])) + m.setFamilyFieldArr(-1,DataArrayInt([-7,-8,-9])) + m.setFamilyFieldArr(1,DataArrayInt([3,4,5,6,7,8,9,10,11,12,13,14,15,16,17])) + m.setRenumFieldArr(0,DataArrayInt([101,102,103,104,105,106])) + m.setRenumFieldArr(-1,DataArrayInt([107,108,109])) + m.setRenumFieldArr(1,DataArrayInt([203,204,205,206,207,208,209,210,211,212,213,214,215,216,217])) + # + fmts=MEDFileFieldMultiTS() + info0=["aa","bbb"] + name0="zeField" + pflName0="pfl" + pflName1="pfl2" + # + f1ts=MEDFileField1TS() + f=MEDCouplingFieldDouble(ON_CELLS) ; f.setName(name0) + arr=DataArrayDouble([(-1,-11),(-2,-22)]) ; arr.setInfoOnComponents(info0) + f.setArray(arr) + pfl0=DataArrayInt([0,1]) ; pfl0.setName(pflName0) + f1ts.setFieldProfile(f,m,-1,pfl0) + del f + f2=MEDCouplingFieldDouble(ON_GAUSS_PT) ; f2.setName(name0) + arr=DataArrayDouble(15) ; arr.iota(1) + arr=DataArrayDouble.Meld(arr,arr+10) ; arr.setInfoOnComponents(info0) + f2.setArray(arr) + pfl1=DataArrayInt([1,3,5]) ; pfl1.setName(pflName1) + tmp=m0[pfl1] ; f2.setMesh(tmp) + f2.setGaussLocalizationOnType(NORM_QUAD4,[-1.,-1.,1.,-1.,1.,1.,-1.,1.],[-0.5,-0.5,0.5,-0.5,0.5,0.5,-0.5,0.5,0.,0.],[0.1,0.1,0.1,0.1,0.6]) + f2.checkCoherency() + f1ts.setFieldProfile(f2,m,0,pfl1) + fmts.pushBackTimeStep(f1ts) + # + m.write(fname,2) + fmts.write(fname,0) + ########## GO for reading in MEDReader,by not loading all. Mesh is fully loaded but not fields values + ms=MEDFileMeshes(fname) + fields=MEDFileFields(fname,False) # false is absolutely necessary for the test + fields.removeFieldsWithoutAnyTimeStep() + fields_per_mesh=[fields.partOfThisLyingOnSpecifiedMeshName(meshName) for meshName in ms.getMeshesNames()] + allFMTSLeavesToDisplay=[] + for fields in fields_per_mesh: + allFMTSLeavesToDisplay2=[] + for fmts in fields: + tmp=fmts.splitDiscretizations() + for itmp in tmp: + self.assertTrue(not itmp.presenceOfMultiDiscPerGeoType()) + pass + allFMTSLeavesToDisplay2+=tmp + pass + allFMTSLeavesToDisplay.append(allFMTSLeavesToDisplay2) + pass + self.assertEqual(len(allFMTSLeavesToDisplay),1) + self.assertEqual(len(allFMTSLeavesToDisplay[0]),2) + ### here the test is important !!! Pointers must be different ! + self.assertTrue(allFMTSLeavesToDisplay[0][0][0].getUndergroundDataArray().getHiddenCppPointer()!=allFMTSLeavesToDisplay[0][1][0].getUndergroundDataArray().getHiddenCppPointer()) + allFMTSLeavesPerTimeSeries=MEDFileAnyTypeFieldMultiTS.SplitIntoCommonTimeSeries(sum(allFMTSLeavesToDisplay,[])) + self.assertEqual(len(allFMTSLeavesPerTimeSeries),1) + self.assertEqual(len(allFMTSLeavesPerTimeSeries[0]),2) + ### here the test is important !!! Pointers must be different ! + self.assertTrue(allFMTSLeavesToDisplay[0][0][0].getUndergroundDataArray().getHiddenCppPointer()!=allFMTSLeavesToDisplay[0][1][0].getUndergroundDataArray().getHiddenCppPointer()) + allFMTSLeavesPerCommonSupport1=MEDFileAnyTypeFieldMultiTS.SplitPerCommonSupport(allFMTSLeavesToDisplay[0],ms[ms.getMeshesNames()[0]]) + self.assertTrue(allFMTSLeavesToDisplay[0][0][0].getUndergroundDataArray().getHiddenCppPointer()!=allFMTSLeavesToDisplay[0][1][0].getUndergroundDataArray().getHiddenCppPointer()) + self.assertEqual(len(allFMTSLeavesPerCommonSupport1),2) + self.assertEqual(len(allFMTSLeavesPerCommonSupport1[0][0]),1) + self.assertEqual(len(allFMTSLeavesPerCommonSupport1[1][0]),1) + # + mst=MEDFileMeshStruct.New(ms[0]) + # emulate first click + fcscp=allFMTSLeavesPerCommonSupport1[0][1] + self.assertEqual([NORM_SEG2],fcscp.getGeoTypesAt(0,ms[0])) + mml=fcscp.buildFromScratchDataSetSupport(0,fields) + mml2=mml.prepare() + self.assertTrue(isinstance(mml2,MEDUMeshMultiLev)) + ncc,a0,a1,a2,a3,a4,a5=mml2.buildVTUArrays() + self.assertTrue(not ncc) # copy here because 2D -> 3D + expCoords=coords.changeNbOfComponents(3,0.) + self.assertTrue(a0.isEqual(expCoords,1e-12)) + self.assertTrue(a1.isEqual(DataArrayByte([3,3]))) + self.assertTrue(a2.isEqual(DataArrayInt([0,3]))) + self.assertTrue(a3.isEqual(DataArrayInt([2,10,12,2,12,13]))) + self.assertTrue(a4 is None) + self.assertTrue(a5 is None) + a6,a7=mml2.retrieveFamilyIdsOnCells() + self.assertTrue(a6.isEqual(DataArrayInt([-7,-8]))) + self.assertTrue(not a7) # copy here because profile on cells + a8,a9=mml2.retrieveNumberIdsOnCells() + self.assertTrue(a8.isEqual(DataArrayInt([107,108]))) + self.assertTrue(not a9) # copy here because profile on cells + a10,a11=mml2.retrieveFamilyIdsOnNodes() + self.assertTrue(a10.isEqual(DataArrayInt([3,4,5,6,7,8,9,10,11,12,13,14,15,16,17]))) + self.assertTrue(a11) # no copy here + a12,a13=mml2.retrieveNumberIdsOnNodes() + self.assertTrue(a12.isEqual(DataArrayInt([203,204,205,206,207,208,209,210,211,212,213,214,215,216,217]))) + self.assertTrue(a13) # no copy here + fff0=allFMTSLeavesPerCommonSupport1[0][0][0][0] + fsst=MEDFileField1TSStructItem.BuildItemFrom(fff0,mst) + fff0.loadArraysIfNecessary() + self.assertEqual([ON_CELLS],fff0.getTypesOfFieldAvailable()) + v=mml.buildDataArray(fsst,fields,fff0.getUndergroundDataArray()) + self.assertEqual(fff0.getName(),name0) + self.assertEqual(v.getHiddenCppPointer(),fff0.getUndergroundDataArray().getHiddenCppPointer()) + vExp=DataArrayDouble([(-1,-11),(-2,-22)]) ; vExp.setInfoOnComponents(info0) + self.assertTrue(v.isEqual(vExp,1e-12)) + del fff0 + # emulate second click + fcscp=allFMTSLeavesPerCommonSupport1[1][1] + self.assertEqual([NORM_QUAD4],fcscp.getGeoTypesAt(0,ms[0])) + mml=fcscp.buildFromScratchDataSetSupport(0,fields) + mml2=mml.prepare() + self.assertTrue(isinstance(mml2,MEDUMeshMultiLev)) + ncc,a0,a1,a2,a3,a4,a5=mml2.buildVTUArrays() + self.assertTrue(not ncc) # copy here because 2D -> 3D + expCoords=coords.changeNbOfComponents(3,0.) + self.assertTrue(a0.isEqual(expCoords,1e-12)) + self.assertTrue(a1.isEqual(DataArrayByte([9,9,9]))) + self.assertTrue(a2.isEqual(DataArrayInt([0,5,10]))) + self.assertTrue(a3.isEqual(DataArrayInt([4,1,4,5,2,4,4,7,8,5,4,7,10,11,8]))) + self.assertTrue(a4 is None) + self.assertTrue(a5 is None) + a6,a7=mml2.retrieveFamilyIdsOnCells() + self.assertTrue(a6.isEqual(DataArrayInt([-2,-4,-6]))) + self.assertTrue(not a7) # copy here because profile on cells + a8,a9=mml2.retrieveNumberIdsOnCells() + self.assertTrue(a8.isEqual(DataArrayInt([102,104,106]))) + self.assertTrue(not a9) # copy here because profile on cells + a10,a11=mml2.retrieveFamilyIdsOnNodes() + self.assertTrue(a10.isEqual(DataArrayInt([3,4,5,6,7,8,9,10,11,12,13,14,15,16,17]))) + self.assertTrue(a11) # no copy here + a12,a13=mml2.retrieveNumberIdsOnNodes() + self.assertTrue(a12.isEqual(DataArrayInt([203,204,205,206,207,208,209,210,211,212,213,214,215,216,217]))) + self.assertTrue(a13) # no copy here + fff1=allFMTSLeavesPerCommonSupport1[1][0][0][0] + fsst=MEDFileField1TSStructItem.BuildItemFrom(fff1,mst) + fff1.loadArraysIfNecessary() + self.assertEqual([ON_GAUSS_PT],fff1.getTypesOfFieldAvailable()) + v=mml.buildDataArray(fsst,fields,fff1.getUndergroundDataArray()) + self.assertEqual(fff1.getName(),name0) + self.assertEqual(v.getHiddenCppPointer(),fff1.getUndergroundDataArray().getHiddenCppPointer()) + vExp=DataArrayDouble([1.,11.,2.,12.,3.,13.,4.,14.,5.,15.,6.,16.,7.,17.,8.,18.,9.,19.,10.,20.,11.,21.,12.,22.,13.,23.,14.,24.,15.,25.],15,2) ; vExp.setInfoOnComponents(info0) + self.assertTrue(v.isEqual(vExp,1e-12)) + # emulate third click + fcscp=allFMTSLeavesPerCommonSupport1[0][1] + mml=fcscp.buildFromScratchDataSetSupport(0,fields) + mml2=mml.prepare() + self.assertTrue(isinstance(mml2,MEDUMeshMultiLev)) + ncc,a0,a1,a2,a3,a4,a5=mml2.buildVTUArrays() + self.assertTrue(not ncc) # copy here because 2D -> 3D + expCoords=coords.changeNbOfComponents(3,0.) + self.assertTrue(a0.isEqual(expCoords,1e-12)) + self.assertTrue(a1.isEqual(DataArrayByte([3,3]))) + self.assertTrue(a2.isEqual(DataArrayInt([0,3]))) + self.assertTrue(a3.isEqual(DataArrayInt([2,10,12,2,12,13]))) + self.assertTrue(a4 is None) + self.assertTrue(a5 is None) + a6,a7=mml2.retrieveFamilyIdsOnCells() + self.assertTrue(a6.isEqual(DataArrayInt([-7,-8]))) + self.assertTrue(not a7) # copy here because profile on cells + a8,a9=mml2.retrieveNumberIdsOnCells() + self.assertTrue(a8.isEqual(DataArrayInt([107,108]))) + self.assertTrue(not a9) # copy here because profile on cells + a10,a11=mml2.retrieveFamilyIdsOnNodes() + self.assertTrue(a10.isEqual(DataArrayInt([3,4,5,6,7,8,9,10,11,12,13,14,15,16,17]))) + self.assertTrue(a11) # no copy here + a12,a13=mml2.retrieveNumberIdsOnNodes() + self.assertTrue(a12.isEqual(DataArrayInt([203,204,205,206,207,208,209,210,211,212,213,214,215,216,217]))) + self.assertTrue(a13) # no copy here + fff0=allFMTSLeavesPerCommonSupport1[0][0][0][0] + fsst=MEDFileField1TSStructItem.BuildItemFrom(fff0,mst) + fff0.loadArraysIfNecessary() + self.assertEqual([ON_CELLS],fff0.getTypesOfFieldAvailable()) + v=mml.buildDataArray(fsst,fields,fff0.getUndergroundDataArray()) + self.assertEqual(fff0.getName(),name0) + self.assertEqual(v.getHiddenCppPointer(),fff0.getUndergroundDataArray().getHiddenCppPointer()) + vExp=DataArrayDouble([(-1,-11),(-2,-22)]) ; vExp.setInfoOnComponents(info0) + self.assertTrue(v.isEqual(vExp,1e-12)) # <- THE test is here !!! + del fff0 + pass + + def test26(self): + """ Test focused on field on nodes (here f0Node and f1Node) lying on a profile of nodes that do not match perfectly a sub set of cells of its underlying mesh. See bug EDF 2405 and 2177. + For this type of fields the support will contain only vertices. + """ + fname="ForMEDReader26.med" + coords=DataArrayDouble([(0.,0.,0.),(1.,0.,0.),(2.,0.,0.),(3.,0.,0.),(0.,1.,0.),(1.,1.,0.),(2.,1.,0.),(3.,1.,0.),(0.,2.,0.),(1.,2.,0.),(2.,2.,0.),(3.,2.,0.),(0.,3.,0.),(1.,3.,0.),(2.,3.,0.),(3.,3.,0.)]) + m0=MEDCouplingUMesh("mesh",2) + m0.allocateCells() + for elt in [[2,6,3],[6,7,3],[9,6,5],[9,10,6]]: + m0.insertNextCell(NORM_TRI3,elt) + pass + for elt in [[0,4,5,1],[1,5,6,2],[4,8,9,5],[6,10,11,7],[8,12,13,9],[9,13,14,10],[10,14,15,11]]: + m0.insertNextCell(NORM_QUAD4,elt) + pass + m0.setCoords(coords) + ## + mm=MEDFileUMesh() + mm.setMeshAtLevel(0,m0) + mm.setFamilyFieldArr(0,DataArrayInt([-1,-2,-3,-4,-5,-6,-7,-8,-9,-10,-11])) + mm.setFamilyFieldArr(1,DataArrayInt([1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16])) + # + f1ts0Node=MEDFileField1TS() + f1ts1Node=MEDFileField1TS() + f1ts2Cell=MEDFileField1TS() + f1ts3Cell=MEDFileField1TS() + f1ts4Cell=MEDFileField1TS() + f1ts5Node=MEDFileField1TS() + # + pfl0=DataArrayInt([4,5,6,8,9,12]) ; pfl0.setName("pfl0") + pfl1=DataArrayInt([0,1,4,5,7,10]) ; pfl1.setName("pfl1") + pfl2=DataArrayInt([0,1,2,3,4,5,6,7,10,11,14,15]) ; pfl2.setName("pfl2") + # + f0Node=MEDCouplingFieldDouble(ON_NODES) ; f0Node.setName("f0Node") + arr0=DataArrayDouble(6) ; arr0.iota() + f0Node.setArray(arr0) + f1ts0Node.setFieldProfile(f0Node,mm,0,pfl0) + # + f1Node=MEDCouplingFieldDouble(ON_NODES) ; f1Node.setName("f1Node") + arr1=DataArrayDouble(6) ; arr1.iota() ; arr1.reverse() + f1Node.setArray(arr1) + f1ts1Node.setFieldProfile(f1Node,mm,0,pfl0) + # + f2Cell=MEDCouplingFieldDouble(ON_CELLS) ; f2Cell.setName("f2Cell") + arr2=DataArrayDouble([2,3,0,1,4,5]) + f2Cell.setArray(arr2) + f1ts2Cell.setFieldProfile(f2Cell,mm,0,pfl1) + # + f3Cell=MEDCouplingFieldDouble(ON_CELLS) ; f3Cell.setName("f3Cell") + arr3=DataArrayDouble([5,4,3,2,1,0]) + f3Cell.setArray(arr3) + f1ts3Cell.setFieldProfile(f3Cell,mm,0,pfl1) + # + f4Cell=MEDCouplingFieldDouble(ON_CELLS) ; f4Cell.setName("f4Cell") + arr4=DataArrayDouble([2,2,0,1,1,0]) + f4Cell.setArray(arr4) + f1ts4Cell.setFieldProfile(f4Cell,mm,0,pfl1) + # + f5Node=MEDCouplingFieldDouble(ON_NODES) ; f5Node.setName("f5Node") + arr5=DataArrayDouble([0,1,2,3,10,11,13,2,11,1,10,0]) + f5Node.setArray(arr5) + f1ts5Node.setFieldProfile(f5Node,mm,0,pfl2) + # + fs=MEDFileFields() + for f in [f1ts0Node,f1ts1Node,f1ts2Cell,f1ts3Cell,f1ts4Cell,f1ts5Node]: + fmts=MEDFileFieldMultiTS() + fmts.pushBackTimeStep(f) + fs.pushField(fmts) + pass + mm.write(fname,2) + fs.write(fname,0) + ########## GO for reading in MEDReader,by not loading all. Mesh is fully loaded but not fields values + ms=MEDFileMeshes(fname) + fields=MEDFileFields(fname,False) + fields.removeFieldsWithoutAnyTimeStep() + fields_per_mesh=[fields.partOfThisLyingOnSpecifiedMeshName(meshName) for meshName in ms.getMeshesNames()] + allFMTSLeavesToDisplay=[] + for fields in fields_per_mesh: + allFMTSLeavesToDisplay2=[] + for fmts in fields: + tmp=fmts.splitDiscretizations() + for itmp in tmp: + self.assertTrue(not itmp.presenceOfMultiDiscPerGeoType()) + pass + allFMTSLeavesToDisplay2+=tmp + pass + allFMTSLeavesToDisplay.append(allFMTSLeavesToDisplay2) + pass + self.assertEqual(len(allFMTSLeavesToDisplay),1) + self.assertEqual(len(allFMTSLeavesToDisplay[0]),6) + allFMTSLeavesPerTimeSeries=MEDFileAnyTypeFieldMultiTS.SplitIntoCommonTimeSeries(sum(allFMTSLeavesToDisplay,[])) + self.assertEqual(len(allFMTSLeavesPerTimeSeries),1) + self.assertEqual(len(allFMTSLeavesPerTimeSeries[0]),6) + allFMTSLeavesPerCommonSupport1=MEDFileAnyTypeFieldMultiTS.SplitPerCommonSupport(allFMTSLeavesToDisplay[0],ms[ms.getMeshesNames()[0]]) + self.assertEqual(len(allFMTSLeavesPerCommonSupport1),2) + self.assertEqual(len(allFMTSLeavesPerCommonSupport1[0][0]),4) + self.assertEqual(len(allFMTSLeavesPerCommonSupport1[1][0]),2)# <- the smart one is here + # + mst=MEDFileMeshStruct.New(ms[0]) + # + fcscp=allFMTSLeavesPerCommonSupport1[1][1] + mml=fcscp.buildFromScratchDataSetSupport(0,fields) + mml2=mml.prepare() + self.assertTrue(isinstance(mml2,MEDUMeshMultiLev)) + self.assertEqual([3,4,0],mml2.getGeoTypes()) + ncc,a0,a1,a2,a3,a4,a5=mml2.buildVTUArrays() + self.assertTrue(not ncc) + self.assertTrue(a0.isEqual(DataArrayDouble([0.,1.,0.,1.,1.,0.,2.,1.,0.,0.,2.,0.,1.,2.,0.,0.,3.,0.],6,3),1e-12)) + self.assertTrue(a1.isEqual(DataArrayByte([5,9,1]))) + self.assertTrue(a2.isEqual(DataArrayInt([0,4,9]))) + self.assertTrue(a3.isEqual(DataArrayInt([3,4,2,1,4,0,3,4,1,1,5]))) + self.assertTrue(a4 is None) + self.assertTrue(a5 is None) + a6,a7=mml2.retrieveFamilyIdsOnCells() + self.assertTrue(a6.isEqual(DataArrayInt([-3,-7,13]))) + self.assertTrue(not a7) # copy here because profile on cells + a8,a9=mml2.retrieveNumberIdsOnCells() + self.assertTrue(a8 is None) + self.assertTrue(a9) # no copy here because no number field + a10,a11=mml2.retrieveFamilyIdsOnNodes() + self.assertTrue(a10.isEqual(DataArrayInt([5,6,7,9,10,13]))) + self.assertTrue(not a11) # copy here + a12,a13=mml2.retrieveNumberIdsOnNodes() + self.assertTrue(a12 is None) + self.assertTrue(a13) # no copy here because no number field + # + fff0=allFMTSLeavesPerCommonSupport1[1][0][0][0] + fsst=MEDFileField1TSStructItem.BuildItemFrom(fff0,mst) + fff0.loadArraysIfNecessary() + v=mml2.buildDataArray(fsst,fields,fff0.getUndergroundDataArray()) + self.assertEqual(fff0.getName(),"f0Node") + self.assertEqual(v.getHiddenCppPointer(),fff0.getUndergroundDataArray().getHiddenCppPointer()) + vExp=DataArrayDouble([0.,1.,2.,3.,4.,5.]) + self.assertTrue(v.isEqual(vExp,1e-12)) # <- THE test is here !!! + # + fff1=allFMTSLeavesPerCommonSupport1[1][0][1][0] + fsst=MEDFileField1TSStructItem.BuildItemFrom(fff1,mst) + fff1.loadArraysIfNecessary() + v=mml2.buildDataArray(fsst,fields,fff1.getUndergroundDataArray()) + self.assertEqual(fff1.getName(),"f1Node") + self.assertEqual(v.getHiddenCppPointer(),fff1.getUndergroundDataArray().getHiddenCppPointer()) + vExp=DataArrayDouble([5.,4.,3.,2.,1.,0.]) + self.assertTrue(v.isEqual(vExp,1e-12)) # <- THE test is here !!! + pass + + def test27(self): + """ This test defines 2 fields f0 and f1 on nodes lying on an unstructured mesh with no cells. + f0 is a field on all nodes. f1 is a partial field on nodes. + """ + fname="ForMEDReader27.med" + coords=DataArrayDouble([(0.,0.,0.),(1.,0.,0.),(2.,0.,0.),(3.,0.,0.),(0.,1.,0.),(1.,1.,0.),(2.,1.,0.),(3.,1.,0.),(0.,2.,0.),(1.,2.,0.),(2.,2.,0.),(3.,2.,0.),(0.,3.,0.),(1.,3.,0.),(2.,3.,0.),(3.,3.,0.)]) + m0=MEDCouplingUMesh("mesh",2) + m0.allocateCells() + m0.setCoords(coords) + ## + mm=MEDFileUMesh() + mm.setMeshAtLevel(0,m0) + mm.setFamilyFieldArr(1,DataArrayInt([1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16])) + # + f1ts0=MEDFileField1TS() + f1ts1=MEDFileField1TS() + # + f0=MEDCouplingFieldDouble(ON_NODES) ; f0.setMesh(m0) ; f0.setName("f0NoPfl") + arr0=DataArrayDouble([0.,1.,2.,3.,1.,1.5,2.2,3.1,2.,2.2,3.,3.1,3.,3.1,3.5,4.]) + f0.setArray(arr0) + f0.checkCoherency() + f1ts0.setFieldNoProfileSBT(f0) + self.assertEqual(f1ts0.getMeshName(),"mesh") + # + pfl1=DataArrayInt([0,1,2,3,4,5,6,8,9,12]) ; pfl1.setName("pfl1") + f1=MEDCouplingFieldDouble(ON_NODES) ; f1.setName("f1Pfl") + arr1=DataArrayDouble([3.,2.,1.,0.,2.,1.5,0.,1.,0.,0.2]) + f1.setArray(arr1) + f1ts1.setFieldProfile(f1,mm,0,pfl1) + self.assertEqual(f1ts1.getMeshName(),"mesh") + # + fs=MEDFileFields() + fmts0=MEDFileFieldMultiTS() + fmts0.pushBackTimeStep(f1ts0) + fmts1=MEDFileFieldMultiTS() + fmts1.pushBackTimeStep(f1ts1) + fs.pushField(fmts0) ; fs.pushField(fmts1) + self.assertEqual(fs[0].getMeshName(),"mesh") + self.assertEqual(fs[1].getMeshName(),"mesh") + mm.write(fname,2) + fs.write(fname,0) + ########## GO for reading in MEDReader,by not loading all. Mesh is fully loaded but not fields values + ms=MEDFileMeshes(fname) + fields=MEDFileFields(fname,False) + fields.removeFieldsWithoutAnyTimeStep() + self.assertEqual(fields[0].getMeshName(),"mesh") + self.assertEqual(fields[1].getMeshName(),"mesh") + fields_per_mesh=[fields.partOfThisLyingOnSpecifiedMeshName(meshName) for meshName in ms.getMeshesNames()] + self.assertEqual(fields_per_mesh[0][0].getMeshName(),"mesh") + self.assertEqual(fields_per_mesh[0][1].getMeshName(),"mesh") + allFMTSLeavesToDisplay=[] + for fields in fields_per_mesh: + allFMTSLeavesToDisplay2=[] + for fmts in fields: + tmp=fmts.splitDiscretizations() + for itmp in tmp: + self.assertTrue(not itmp.presenceOfMultiDiscPerGeoType()) + pass + allFMTSLeavesToDisplay2+=tmp + pass + allFMTSLeavesToDisplay.append(allFMTSLeavesToDisplay2) + pass + self.assertEqual(len(allFMTSLeavesToDisplay),1) + self.assertEqual(len(allFMTSLeavesToDisplay[0]),2) + allFMTSLeavesPerTimeSeries=MEDFileAnyTypeFieldMultiTS.SplitIntoCommonTimeSeries(sum(allFMTSLeavesToDisplay,[])) + self.assertEqual(len(allFMTSLeavesPerTimeSeries),1) + self.assertEqual(len(allFMTSLeavesPerTimeSeries[0]),2) + allFMTSLeavesPerCommonSupport1=MEDFileAnyTypeFieldMultiTS.SplitPerCommonSupport(allFMTSLeavesToDisplay[0],ms[ms.getMeshesNames()[0]]) + self.assertEqual(len(allFMTSLeavesPerCommonSupport1),2) + self.assertEqual(len(allFMTSLeavesPerCommonSupport1[0][0]),1) + self.assertEqual(len(allFMTSLeavesPerCommonSupport1[1][0]),1) + # + mst=MEDFileMeshStruct.New(ms[0]) + # + fcscp=allFMTSLeavesPerCommonSupport1[0][1] + mml=fcscp.buildFromScratchDataSetSupport(0,fields) + mml2=mml.prepare() + self.assertTrue(isinstance(mml2,MEDUMeshMultiLev)) + ncc,a0,a1,a2,a3,a4,a5=mml2.buildVTUArrays() + self.assertTrue(ncc) + self.assertTrue(a0.isEqual(DataArrayDouble([(0.,0.,0.),(1.,0.,0.),(2.,0.,0.),(3.,0.,0.),(0.,1.,0.),(1.,1.,0.),(2.,1.,0.),(3.,1.,0.),(0.,2.,0.),(1.,2.,0.),(2.,2.,0.),(3.,2.,0.),(0.,3.,0.),(1.,3.,0.),(2.,3.,0.),(3.,3.,0.)]),1e-12)) + self.assertTrue(a1.isEqual(DataArrayByte([]))) + self.assertTrue(a2.isEqual(DataArrayInt([]))) + self.assertTrue(a3.isEqual(DataArrayInt([]))) + self.assertTrue(a4 is None) + self.assertTrue(a5 is None) + # + fff0=allFMTSLeavesPerCommonSupport1[0][0][0][0] + fsst=MEDFileField1TSStructItem.BuildItemFrom(fff0,mst) + fff0.loadArraysIfNecessary() + v=mml2.buildDataArray(fsst,fields,fff0.getUndergroundDataArray()) + self.assertEqual(fff0.getName(),"f0NoPfl") + self.assertEqual(v.getHiddenCppPointer(),fff0.getUndergroundDataArray().getHiddenCppPointer()) + vExp=DataArrayDouble([0.,1.,2.,3.,1.,1.5,2.2,3.1,2.,2.2,3.,3.1,3.,3.1,3.5,4]) + self.assertTrue(v.isEqual(vExp,1e-12)) + # + fcscp=allFMTSLeavesPerCommonSupport1[1][1] + mml=fcscp.buildFromScratchDataSetSupport(0,fields) + mml2=mml.prepare() + self.assertTrue(isinstance(mml2,MEDUMeshMultiLev)) + ncc,a0,a1,a2,a3,a4,a5=mml2.buildVTUArrays() + self.assertTrue(not ncc) + self.assertTrue(a0.isEqual(DataArrayDouble([(0,0,0),(1,0,0),(2,0,0),(3,0,0),(0,1,0),(1,1,0),(2,1,0),(0,2,0),(1,2,0),(0,3,0)]),1e-12)) + self.assertTrue(a1.isEqual(DataArrayByte([]))) + self.assertTrue(a2.isEqual(DataArrayInt([]))) + self.assertTrue(a3.isEqual(DataArrayInt([]))) + self.assertTrue(a4 is None) + self.assertTrue(a5 is None) + fff1=allFMTSLeavesPerCommonSupport1[1][0][0][0] + fsst=MEDFileField1TSStructItem.BuildItemFrom(fff1,mst) + fff1.loadArraysIfNecessary() + v=mml2.buildDataArray(fsst,fields,fff1.getUndergroundDataArray()) + self.assertEqual(fff1.getName(),"f1Pfl") + self.assertNotEqual(v.getHiddenCppPointer(),fff1.getUndergroundDataArray().getHiddenCppPointer()) # pointers are not equal because Profile + vExp=DataArrayDouble([3.,2.,1.,0.,2.,1.5,0.,1.,0.,0.2]) + self.assertTrue(v.isEqual(vExp,1e-12)) + pass + + def test28(self): + """ This test defines 2 fields f0,f1,f2,f3 lying on an unstructured mesh whith cells including NORM_POINT1. + Both f0 and f1 are on NODES and f2 and f3 are on cells. f1 and f2 share the same support. + f0 is on a nodal support that is not matchable with any cells (including NORM_POINT1) + This test is a more aggressive version of test26. + """ + fname="ForMEDReader28.med" + coords=DataArrayDouble([(0.,0.,0.),(1.,0.,0.),(2.,0.,0.),(3.,0.,0.),(0.,1.,0.),(1.,1.,0.),(2.,1.,0.),(3.,1.,0.),(0.,2.,0.),(1.,2.,0.),(2.,2.,0.),(3.,2.,0.),(0.,3.,0.),(1.,3.,0.),(2.,3.,0.),(3.,3.,0.)]) + m0=MEDCouplingUMesh("mesh",2) + m0.allocateCells() + for elt in [[2,6,3],[6,7,3],[9,6,5],[9,10,6]]: + m0.insertNextCell(NORM_TRI3,elt) + pass + for elt in [[0,4,5,1],[1,5,6,2],[4,8,9,5],[6,10,11,7],[8,12,13,9],[9,13,14,10],[10,14,15,11]]: + m0.insertNextCell(NORM_QUAD4,elt) + pass + m0.setCoords(coords) + m2=MEDCouplingUMesh("mesh",0) ; m2.setCoords(coords) + m2.allocateCells() + for elt in [[8],[13]]: + m2.insertNextCell(NORM_POINT1,elt) + pass + ## + mm=MEDFileUMesh() + mm.setMeshAtLevel(0,m0) + mm.setMeshAtLevel(-2,m2) + mm.setFamilyFieldArr(0,DataArrayInt([-1,-2,-3,-4,-5,-6,-7,-8,-9,-10,-11])) + mm.setFamilyFieldArr(-2,DataArrayInt([-12,-13])) + mm.setFamilyFieldArr(1,DataArrayInt([1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16])) + # + f1ts0Node=MEDFileField1TS() + f1ts1Node=MEDFileField1TS() + f1ts2Cell=MEDFileField1TS() + f1ts3Cell=MEDFileField1TS() + # + pfl0=DataArrayInt([4,5,6,8,9,12]) ; pfl0.setName("pfl0") + pfl1=DataArrayInt([0,1,4,5,7,10]) ; pfl1.setName("pfl1") + pfl2=DataArrayInt([0,1,2,3,4,5,6,7,10,11,14,15]) ; pfl2.setName("pfl2") + # + f0Node=MEDCouplingFieldDouble(ON_NODES) ; f0Node.setName("f0Node") + arr0=DataArrayDouble(6) ; arr0.iota() + f0Node.setArray(arr0) + f1ts0Node.setFieldProfile(f0Node,mm,0,pfl0) + # + f1Node=MEDCouplingFieldDouble(ON_NODES) ; f1Node.setName("f1Node") + arr1=DataArrayDouble(12) ; arr1.iota() ; arr1.reverse() + f1Node.setArray(arr1) + f1ts1Node.setFieldProfile(f1Node,mm,0,pfl2) + # + f2Cell=MEDCouplingFieldDouble(ON_CELLS) ; f2Cell.setName("f2Cell") + arr2=DataArrayDouble([2,3,0,1,4,5]) + f2Cell.setArray(arr2) + f1ts2Cell.setFieldProfile(f2Cell,mm,0,pfl1) + # + f3Cell=MEDCouplingFieldDouble(ON_CELLS) ; f3Cell.setName("f3Cell") + arr3=DataArrayDouble([5,4,3,2,1,0]) ; f3Cell.setArray(arr3) + f1ts3Cell.setFieldProfile(f3Cell,mm,0,pfl1) + f3Cell.setMesh(m2) + arr3=DataArrayDouble([-1.1,-3.1]) ; f3Cell.setArray(arr3) + f1ts3Cell.setFieldNoProfileSBT(f3Cell) + # + fs=MEDFileFields() + for f in [f1ts0Node,f1ts1Node,f1ts2Cell,f1ts3Cell]: + fmts=MEDFileFieldMultiTS() + fmts.pushBackTimeStep(f) + fs.pushField(fmts) + pass + mm.write(fname,2) + fs.write(fname,0) + ########## GO for reading in MEDReader,by not loading all. Mesh is fully loaded but not fields values + ms=MEDFileMeshes(fname) + fields=MEDFileFields(fname,False) + fields.removeFieldsWithoutAnyTimeStep() + fields_per_mesh=[fields.partOfThisLyingOnSpecifiedMeshName(meshName) for meshName in ms.getMeshesNames()] + allFMTSLeavesToDisplay=[] + for fields in fields_per_mesh: + allFMTSLeavesToDisplay2=[] + for fmts in fields: + tmp=fmts.splitDiscretizations() + for itmp in tmp: + self.assertTrue(not itmp.presenceOfMultiDiscPerGeoType()) + pass + allFMTSLeavesToDisplay2+=tmp + pass + allFMTSLeavesToDisplay.append(allFMTSLeavesToDisplay2) + pass + self.assertEqual(len(allFMTSLeavesToDisplay),1) + self.assertEqual(len(allFMTSLeavesToDisplay[0]),4) + allFMTSLeavesPerTimeSeries=MEDFileAnyTypeFieldMultiTS.SplitIntoCommonTimeSeries(sum(allFMTSLeavesToDisplay,[])) + self.assertEqual(len(allFMTSLeavesPerTimeSeries),1) + self.assertEqual(len(allFMTSLeavesPerTimeSeries[0]),4) + allFMTSLeavesPerCommonSupport1=MEDFileAnyTypeFieldMultiTS.SplitPerCommonSupport(allFMTSLeavesToDisplay[0],ms[ms.getMeshesNames()[0]]) + self.assertEqual(len(allFMTSLeavesPerCommonSupport1),3) + self.assertEqual(len(allFMTSLeavesPerCommonSupport1[0][0]),2) + self.assertEqual(len(allFMTSLeavesPerCommonSupport1[1][0]),1) + self.assertEqual(len(allFMTSLeavesPerCommonSupport1[2][0]),1) + # + mst=MEDFileMeshStruct.New(ms[0]) + # + fcscp=allFMTSLeavesPerCommonSupport1[2][1] + mml=fcscp.buildFromScratchDataSetSupport(0,fields) + mml2=mml.prepare() + self.assertTrue(isinstance(mml2,MEDUMeshMultiLev)) + ncc,a0,a1,a2,a3,a4,a5=mml2.buildVTUArrays() + self.assertTrue(not ncc) + self.assertTrue(a0.isEqual(DataArrayDouble([0.,1.,0.,1.,1.,0.,2.,1.,0.,0.,2.,0.,1.,2.,0.,0.,3.,0.],6,3),1e-12)) + self.assertTrue(a1.isEqual(DataArrayByte([5,9,1,1]))) + self.assertTrue(a2.isEqual(DataArrayInt([0,4,9,11]))) + self.assertTrue(a3.isEqual(DataArrayInt([3,4,2,1,4,0,3,4,1,1,3,1,5]))) + self.assertTrue(a4 is None) + self.assertTrue(a5 is None) + a6,a7=mml2.retrieveFamilyIdsOnCells() + self.assertTrue(a6.isEqual(DataArrayInt([-3,-7,-12,13]))) + self.assertTrue(not a7) # copy here because profile on cells + a8,a9=mml2.retrieveNumberIdsOnCells() + self.assertTrue(a8 is None) + self.assertTrue(a9) # no copy here because no number field + a10,a11=mml2.retrieveFamilyIdsOnNodes() + self.assertTrue(a10.isEqual(DataArrayInt([5,6,7,9,10,13]))) + self.assertTrue(not a11) # copy here + a12,a13=mml2.retrieveNumberIdsOnNodes() + self.assertTrue(a12 is None) + self.assertTrue(a13) # no copy here because no number field + # + fff0=allFMTSLeavesPerCommonSupport1[2][0][0][0] + fsst=MEDFileField1TSStructItem.BuildItemFrom(fff0,mst) + fff0.loadArraysIfNecessary() + v=mml2.buildDataArray(fsst,fields,fff0.getUndergroundDataArray()) + self.assertEqual(fff0.getName(),"f0Node") + self.assertEqual(v.getHiddenCppPointer(),fff0.getUndergroundDataArray().getHiddenCppPointer()) + vExp=DataArrayDouble([0.,1.,2.,3.,4.,5.]) + self.assertTrue(v.isEqual(vExp,1e-12)) # <- THE test is here !!! + ### + fcscp=allFMTSLeavesPerCommonSupport1[0][1] + mml=fcscp.buildFromScratchDataSetSupport(0,fields) + mml2=mml.prepare() + self.assertTrue(isinstance(mml2,MEDUMeshMultiLev)) + ncc,a0,a1,a2,a3,a4,a5=mml2.buildVTUArrays() + self.assertTrue(not ncc) + self.assertTrue(a0.isEqual(DataArrayDouble([(0,0,0),(1,0,0),(2,0,0),(3,0,0),(0,1,0),(1,1,0),(2,1,0),(3,1,0),(2,2,0),(3,2,0),(2,3,0),(3,3,0)]),1e-12)) + self.assertTrue(a1.isEqual(DataArrayByte([5,5,9,9,9,9]))) + self.assertTrue(a2.isEqual(DataArrayInt([0,4,8,13,18,23]))) + self.assertTrue(a3.isEqual(DataArrayInt([3,2,6,3,3,6,7,3,4,0,4,5,1,4,1,5,6,2,4,6,8,9,7,4,8,10,11,9]))) + self.assertTrue(a4 is None) + self.assertTrue(a5 is None) + fff1=allFMTSLeavesPerCommonSupport1[0][0][0][0] + fsst=MEDFileField1TSStructItem.BuildItemFrom(fff1,mst) + fff1.loadArraysIfNecessary() + v=mml2.buildDataArray(fsst,fields,fff1.getUndergroundDataArray()) + self.assertEqual(fff1.getName(),"f2Cell") + self.assertNotEqual(v.getHiddenCppPointer(),fff0.getUndergroundDataArray().getHiddenCppPointer()) + vExp=DataArrayDouble([2,3,0,1,4,5]) + self.assertTrue(v.isEqual(vExp,1e-12)) + fff2=allFMTSLeavesPerCommonSupport1[0][0][1][0] + fsst=MEDFileField1TSStructItem.BuildItemFrom(fff2,mst) + fff2.loadArraysIfNecessary() + v=mml2.buildDataArray(fsst,fields,fff2.getUndergroundDataArray()) + self.assertEqual(fff2.getName(),"f1Node") + self.assertNotEqual(v.getHiddenCppPointer(),fff0.getUndergroundDataArray().getHiddenCppPointer()) + vExp=DataArrayDouble([11,10,9,8,7,6,5,4,3,2,1,0]) + self.assertTrue(v.isEqual(vExp,1e-12)) + ### + fcscp=allFMTSLeavesPerCommonSupport1[1][1] + mml=fcscp.buildFromScratchDataSetSupport(0,fields) + mml2=mml.prepare() + self.assertTrue(isinstance(mml2,MEDUMeshMultiLev)) + ncc,a0,a1,a2,a3,a4,a5=mml2.buildVTUArrays() + self.assertTrue(ncc)# here all the 16 nodes are taken + self.assertTrue(a0.isEqual(DataArrayDouble([(0.,0.,0.),(1.,0.,0.),(2.,0.,0.),(3.,0.,0.),(0.,1.,0.),(1.,1.,0.),(2.,1.,0.),(3.,1.,0.),(0.,2.,0.),(1.,2.,0.),(2.,2.,0.),(3.,2.,0.),(0.,3.,0.),(1.,3.,0.),(2.,3.,0.),(3.,3.,0.)]),1e-12)) + self.assertTrue(a1.isEqual(DataArrayByte([1,1,5,5,9,9,9,9]))) + self.assertTrue(a2.isEqual(DataArrayInt([0,2,4,8,12,17,22,27]))) + self.assertTrue(a3.isEqual(DataArrayInt([1,8,1,13,3,2,6,3,3,6,7,3,4,0,4,5,1,4,1,5,6,2,4,6,10,11,7,4,10,14,15,11]))) + self.assertTrue(a4 is None) + self.assertTrue(a5 is None) + fff3=allFMTSLeavesPerCommonSupport1[1][0][0][0] + fsst=MEDFileField1TSStructItem.BuildItemFrom(fff3,mst) + fff3.loadArraysIfNecessary() + v=mml2.buildDataArray(fsst,fields,fff3.getUndergroundDataArray()) + self.assertEqual(fff3.getName(),"f3Cell") + self.assertNotEqual(v.getHiddenCppPointer(),fff0.getUndergroundDataArray().getHiddenCppPointer()) + vExp=DataArrayDouble([-1.1,-3.1,5,4,3,2,1,0]) + self.assertTrue(v.isEqual(vExp,1e-12)) + pass + + def test29(self): + """ This test focused on HEXA27 cell for which the MED numbering is not equal to the VTK numbering. So here the HEXA27 cell is those in MED file documentation (reference element). + """ + fname="ForMEDReader29.med" + coo=DataArrayDouble([[0.,2.,2.],[0.,0.,2.],[2.,0.,2.],[2.,2.,2.],[0.,2.,0.],[0.,0.,0.],[2.,0.,0.],[2.,2.,0.], [0.,1.,2.],[1.,0.,2.],[2.,1.,2.],[1.,2.,2.], [0.,1.,0.],[1.,0.,0.],[2.,1.,0.],[1.,2.,0.], [0.,2.,1.],[0.,0.,1.],[2.,0.,1.],[2.,2.,1.], [1.,1.,2.], [0.,1.,1.],[1.,0.,1.],[2.,1.,1.],[1.,2.,1.], [1.,1.,0.], [1.,1.,1.]]) + m=MEDCouplingUMesh("mesh",3) ; m.setCoords(coo) + m.allocateCells() + # MED = [0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26] + # VTK = [0,1,2,3,4,5,6,7, 8,9,10,11,12,13,14,15,16,17,18,19,24,22,21,23,20,25,26] + m.insertNextCell(NORM_HEXA27,[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26]) + fCell=MEDCouplingFieldDouble(ON_CELLS) ; fCell.setName("fCell") + arrCell=DataArrayDouble([7.]) ; arrCell.setInfoOnComponent(0,"smth") ; fCell.setArray(arrCell) + fCell.setMesh(m) + MEDLoader.WriteField(fname,fCell,True) + refCoo=[-1.,-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.,0.,1.,-1.,1.,0.,-1.,0.,-1.,-1.,-1.,0.,1.,0.,1.,1.,1.,0.,1.,0.,-1.,1.,-1.,-1.,0.,-1.,1.,0.,1.,1.,0.,1.,-1.,0.,0.,0.,-1.,-1.,0.,0.,0.,1.,0.,1.,0.,0.,0.,-1.,0.,0.,0.,1.,0.,0.,0.] + weights=[0.1714677640603571,0.27434842249657115,0.1714677640603571,0.27434842249657115,0.43895747599451346,0.27434842249657115,0.1714677640603571,0.27434842249657115,0.1714677640603571,0.27434842249657115,0.43895747599451346,0.27434842249657115,0.43895747599451346,0.7023319615912209,0.43895747599451346,0.27434842249657115,0.43895747599451346,0.27434842249657115,0.1714677640603571,0.27434842249657115,0.1714677640603571,0.27434842249657115,0.43895747599451346,0.27434842249657115,0.1714677640603571,0.27434842249657115,0.1714677640603571] + gCoords=[-0.774596669241483,-0.774596669241483,-0.774596669241483,-0.774596669241483,-0.774596669241483,0.0,-0.774596669241483,-0.774596669241483,0.774596669241483,-0.774596669241483,0.0,-0.774596669241483,-0.774596669241483,0.0,0.0,-0.774596669241483,0.0,0.774596669241483,-0.774596669241483,0.774596669241483,-0.774596669241483,-0.774596669241483,0.774596669241483,0.0,-0.774596669241483,0.774596669241483,0.774596669241483,0.0,-0.774596669241483,-0.774596669241483,0.0,-0.774596669241483,0.0,0.0,-0.774596669241483,0.774596669241483,0.0,0.0,-0.774596669241483,0.0,0.0,0.0,0.0,0.0,0.774596669241483,0.0,0.774596669241483,-0.774596669241483,0.0,0.774596669241483,0.0,0.0,0.774596669241483,0.774596669241483,0.774596669241483,-0.774596669241483,-0.774596669241483,0.774596669241483,-0.774596669241483,0.0,0.774596669241483,-0.774596669241483,0.774596669241483,0.774596669241483,0.0,-0.774596669241483,0.774596669241483,0.0,0.0,0.774596669241483,0.0,0.774596669241483,0.774596669241483,0.774596669241483,-0.774596669241483,0.774596669241483,0.774596669241483,0.0,0.774596669241483,0.774596669241483,0.774596669241483] + fGauss=MEDCouplingFieldDouble(ON_GAUSS_PT) ; fGauss.setName("fGauss") + fGauss.setMesh(m) + fGauss.setGaussLocalizationOnType(NORM_HEXA27,refCoo,gCoords,weights) + arrGauss=DataArrayDouble(fGauss.getNumberOfTuplesExpected()) ; arrGauss.setInfoOnComponent(0,"gaussc") ; arrGauss.iota() + fGauss.setArray(arrGauss) + MEDLoader.WriteFieldUsingAlreadyWrittenMesh(fname,fGauss) + ########## GO for reading in MEDReader,by not loading all. Mesh is fully loaded but not fields values + ms=MEDFileMeshes(fname) + fields=MEDFileFields(fname,False) + fields.removeFieldsWithoutAnyTimeStep() + fields_per_mesh=[fields.partOfThisLyingOnSpecifiedMeshName(meshName) for meshName in ms.getMeshesNames()] + allFMTSLeavesToDisplay=[] + for fields in fields_per_mesh: + allFMTSLeavesToDisplay2=[] + for fmts in fields: + tmp=fmts.splitDiscretizations() + for itmp in tmp: + self.assertTrue(not itmp.presenceOfMultiDiscPerGeoType()) + pass + allFMTSLeavesToDisplay2+=tmp + pass + allFMTSLeavesToDisplay.append(allFMTSLeavesToDisplay2) + pass + self.assertEqual(len(allFMTSLeavesToDisplay),1) + self.assertEqual(len(allFMTSLeavesToDisplay[0]),2) + allFMTSLeavesPerTimeSeries=MEDFileAnyTypeFieldMultiTS.SplitIntoCommonTimeSeries(sum(allFMTSLeavesToDisplay,[])) + self.assertEqual(len(allFMTSLeavesPerTimeSeries),1) + self.assertEqual(len(allFMTSLeavesPerTimeSeries[0]),2) + allFMTSLeavesPerCommonSupport1=MEDFileAnyTypeFieldMultiTS.SplitPerCommonSupport(allFMTSLeavesToDisplay[0],ms[ms.getMeshesNames()[0]]) + self.assertEqual(len(allFMTSLeavesPerCommonSupport1),1) + self.assertEqual(len(allFMTSLeavesPerCommonSupport1[0][0]),2) + # + mst=MEDFileMeshStruct.New(ms[0]) + # + fcscp=allFMTSLeavesPerCommonSupport1[0][1] + mml=fcscp.buildFromScratchDataSetSupport(0,fields) + mml2=mml.prepare() + self.assertTrue(isinstance(mml2,MEDUMeshMultiLev)) + ncc,a0,a1,a2,a3,a4,a5=mml2.buildVTUArrays() + self.assertTrue(a0.isEqual(coo,1e-12)) + self.assertTrue(a1.isEqual(DataArrayByte([29]))) + self.assertTrue(a2.isEqual(DataArrayInt([0]))) + # the connectivity must be not a iota as declared in m.insertNextCell + self.assertTrue(a3.isEqual(DataArrayInt([27,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,24,22,21,23,20,25,26])))# the test is on this line to check that connectivity has been processed for HEXA27 + self.assertTrue(a4 is None) + self.assertTrue(a5 is None) + ffCell=allFMTSLeavesPerCommonSupport1[0][0][0][0] + fsst=MEDFileField1TSStructItem.BuildItemFrom(ffCell,mst) + ffCell.loadArraysIfNecessary() + v=mml2.buildDataArray(fsst,fields,ffCell.getUndergroundDataArray()) + self.assertEqual(v.getHiddenCppPointer(),ffCell.getUndergroundDataArray().getHiddenCppPointer()) + self.assertEqual(ffCell.getName(),"fCell") + self.assertTrue(v.isEqual(arrCell,1e-12)) ; self.assertTrue(v.isEqualWithoutConsideringStr(DataArrayDouble([7.]),1e-12)) ; self.assertEqual(v.getInfoOnComponents(),["smth"]) + del ffCell + # + ffGauss=allFMTSLeavesPerCommonSupport1[0][0][1][0] + fsst=MEDFileField1TSStructItem.BuildItemFrom(ffGauss,mst) + ffGauss.loadArraysIfNecessary() + v=mml2.buildDataArray(fsst,fields,ffGauss.getUndergroundDataArray()) + self.assertEqual(v.getHiddenCppPointer(),ffGauss.getUndergroundDataArray().getHiddenCppPointer()) + self.assertEqual(ffGauss.getName(),"fGauss") + self.assertTrue(v.isEqual(arrGauss,1e-12)) ; self.assertTrue(v.isEqualWithoutConsideringStr(DataArrayDouble(range(27)),1e-12)) ; self.assertEqual(v.getInfoOnComponents(),["gaussc"]) + ffGauss=allFMTSLeavesPerCommonSupport1[0][0][1][0] + pass + + def test30(self): + """ This test is focused on cartesian meshes. Here the cartesian mesh "CartMesh" has a field on HEXA8 (FieldOnCells) and a field on QUAD4 (FieldOnFaces). + So the first one (FieldOnCells) lies on a cartesian mesh whereas the second one lies on unstructured one. + """ + fname="ForMEDReader30.med" + c=MEDCouplingCMesh() + arrX=DataArrayDouble(3) ; arrX.iota() + arrY=DataArrayDouble(4) ; arrY.iota() + arrZ=DataArrayDouble(5) ; arrZ.iota() + c.setCoords(arrX,arrY,arrZ) + c.setName("CartMesh") + cc=MEDFileCMesh() + cc.setMesh(c) + tmpFacesMesh=c.build1SGTSubLevelMesh() + famIdFaces=DataArrayInt(98) ; famIdFaces[:36]=-1 ; famIdFaces[36:68]=-2 ; famIdFaces[68:]=-3 + famIdCells=DataArrayInt(24) ; famIdCells[:]=0 + #cc.setFamilyFieldArr(0,famIdCells) + #cc.setFamilyFieldArr(-1,famIdFaces) + cc.addFamily("FacesX",-1) ; cc.addFamily("FacesY",-2) ; cc.addFamily("FacesZ",-3) + cc.setFamiliesOnGroup("FacesX1",["FacesX"]) + cc.setFamiliesOnGroup("FacesY1",["FacesY"]) + cc.setFamiliesOnGroup("FacesZ1",["FacesZ"]) + # + fmts0=MEDFileFieldMultiTS() + fmts1=MEDFileFieldMultiTS() + for i in xrange(30): + f1ts=MEDFileField1TS() + fFaces=MEDCouplingFieldDouble(ON_CELLS) ; fFaces.setName("FieldOnFaces") + arr=DataArrayDouble(98) ; arr.iota() ; arr[i]=100. + fFaces.setArray(arr) + fFaces.setTime(float(i)+0.1,i,-1) + fFaces.setMesh(tmpFacesMesh) + f1ts.setFieldNoProfileSBT(fFaces) + fmts0.pushBackTimeStep(f1ts) + # + f1ts=MEDFileField1TS() + fCells=MEDCouplingFieldDouble(ON_CELLS) ; fCells.setName("FieldOnCells") + arr=DataArrayDouble(24) ; arr.iota() ; arr[i%24]=30. + fCells.setArray(arr) + fCells.setTime(float(i)+0.1,i,-1) + fCells.setMesh(c) + f1ts.setFieldNoProfileSBT(fCells) + fmts1.pushBackTimeStep(f1ts) + pass + fs=MEDFileFields() + fs.pushField(fmts0) + fs.pushField(fmts1) + cc.write(fname,2) + fs.write(fname,0) + ########## GO for reading in MEDReader,by not loading all. Mesh is fully loaded but not fields values + ms=MEDFileMeshes(fname) + fields=MEDFileFields(fname,False) + fields.removeFieldsWithoutAnyTimeStep() + fields_per_mesh=[fields.partOfThisLyingOnSpecifiedMeshName(meshName) for meshName in ms.getMeshesNames()] + allFMTSLeavesToDisplay=[] + for fields in fields_per_mesh: + allFMTSLeavesToDisplay2=[] + for fmts in fields: + tmp=fmts.splitDiscretizations() + for itmp in tmp: + self.assertTrue(not itmp.presenceOfMultiDiscPerGeoType()) + pass + allFMTSLeavesToDisplay2+=tmp + pass + allFMTSLeavesToDisplay.append(allFMTSLeavesToDisplay2) + pass + self.assertEqual(len(allFMTSLeavesToDisplay),1) + self.assertEqual(len(allFMTSLeavesToDisplay[0]),2) + allFMTSLeavesPerTimeSeries=MEDFileAnyTypeFieldMultiTS.SplitIntoCommonTimeSeries(sum(allFMTSLeavesToDisplay,[])) + self.assertEqual(len(allFMTSLeavesPerTimeSeries),1) + self.assertEqual(len(allFMTSLeavesPerTimeSeries[0]),2) + allFMTSLeavesPerCommonSupport1=MEDFileAnyTypeFieldMultiTS.SplitPerCommonSupport(allFMTSLeavesToDisplay[0],ms[ms.getMeshesNames()[0]]) + self.assertEqual(len(allFMTSLeavesPerCommonSupport1),2) + self.assertEqual(len(allFMTSLeavesPerCommonSupport1[0][0]),1) + self.assertEqual(len(allFMTSLeavesPerCommonSupport1[1][0]),1) + # + mst=MEDFileMeshStruct.New(ms[0]) + # + fcscp=allFMTSLeavesPerCommonSupport1[0][1] + mml=fcscp.buildFromScratchDataSetSupport(0,fields) + mml2=mml.prepare() + self.assertTrue(isinstance(mml2,MEDCMeshMultiLev)) # here CMesh is important + (a,b,c),d=mml2.buildVTUArrays() + self.assertTrue(d)#d is True because the a,b and c are directly those in the internal data structure + self.assertTrue(a.isEqual(arrX,1e-12)) + self.assertTrue(b.isEqual(arrY,1e-12)) + self.assertTrue(c.isEqual(arrZ,1e-12)) + for i in xrange(30): + ffCell=allFMTSLeavesPerCommonSupport1[0][0][0][i] + fsst=MEDFileField1TSStructItem.BuildItemFrom(ffCell,mst) + ffCell.loadArraysIfNecessary() + v=mml2.buildDataArray(fsst,fields,ffCell.getUndergroundDataArray()) + self.assertEqual(v.getHiddenCppPointer(),ffCell.getUndergroundDataArray().getHiddenCppPointer()) + myarr=DataArrayDouble(24) ; myarr.iota() ; myarr[i%24]=30. + self.assertEqual(ffCell.getName(),"FieldOnCells") + self.assertTrue(v.isEqual(myarr,1e-12)) + pass + # + fcscp=allFMTSLeavesPerCommonSupport1[1][1] + mml=fcscp.buildFromScratchDataSetSupport(0,fields) + mml2=mml.prepare() + self.assertTrue(isinstance(mml2,MEDUMeshMultiLev)) # here UMesh is important + ref=ms[0].getImplicitFaceMesh().getCoords().getHiddenCppPointer() + ncc,a0,a1,a2,a3,a4,a5=mml2.buildVTUArrays() + self.assertEqual(ref,a0.getHiddenCppPointer()) + self.assertTrue(ncc) + self.assertTrue(a1.isEqual(DataArrayByte([9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9]))) + self.assertTrue(a2.isEqual(DataArrayInt([0,5,10,15,20,25,30,35,40,45,50,55,60,65,70,75,80,85,90,95,100,105,110,115,120,125,130,135,140,145,150,155,160,165,170,175,180,185,190,195,200,205,210,215,220,225,230,235,240,245,250,255,260,265,270,275,280,285,290,295,300,305,310,315,320,325,330,335,340,345,350,355,360,365,370,375,380,385,390,395,400,405,410,415,420,425,430,435,440,445,450,455,460,465,470,475,480,485]))) + self.assertTrue(a3.isEqual(DataArrayInt([4,0,12,15,3,4,12,24,27,15,4,24,36,39,27,4,36,48,51,39,4,3,15,18,6,4,15,27,30,18,4,27,39,42,30,4,39,51,54,42,4,6,18,21,9,4,18,30,33,21,4,30,42,45,33,4,42,54,57,45,4,1,13,16,4,4,13,25,28,16,4,25,37,40,28,4,37,49,52,40,4,4,16,19,7,4,16,28,31,19,4,28,40,43,31,4,40,52,55,43,4,7,19,22,10,4,19,31,34,22,4,31,43,46,34,4,43,55,58,46,4,2,14,17,5,4,14,26,29,17,4,26,38,41,29,4,38,50,53,41,4,5,17,20,8,4,17,29,32,20,4,29,41,44,32,4,41,53,56,44,4,8,20,23,11,4,20,32,35,23,4,32,44,47,35,4,44,56,59,47,4,0,12,13,1,4,12,24,25,13,4,24,36,37,25,4,36,48,49,37,4,1,13,14,2,4,13,25,26,14,4,25,37,38,26,4,37,49,50,38,4,3,15,16,4,4,15,27,28,16,4,27,39,40,28,4,39,51,52,40,4,4,16,17,5,4,16,28,29,17,4,28,40,41,29,4,40,52,53,41,4,6,18,19,7,4,18,30,31,19,4,30,42,43,31,4,42,54,55,43,4,7,19,20,8,4,19,31,32,20,4,31,43,44,32,4,43,55,56,44,4,9,21,22,10,4,21,33,34,22,4,33,45,46,34,4,45,57,58,46,4,10,22,23,11,4,22,34,35,23,4,34,46,47,35,4,46,58,59,47,4,0,1,4,3,4,3,4,7,6,4,6,7,10,9,4,1,2,5,4,4,4,5,8,7,4,7,8,11,10,4,12,13,16,15,4,15,16,19,18,4,18,19,22,21,4,13,14,17,16,4,16,17,20,19,4,19,20,23,22,4,24,25,28,27,4,27,28,31,30,4,30,31,34,33,4,25,26,29,28,4,28,29,32,31,4,31,32,35,34,4,36,37,40,39,4,39,40,43,42,4,42,43,46,45,4,37,38,41,40,4,40,41,44,43,4,43,44,47,46,4,48,49,52,51,4,51,52,55,54,4,54,55,58,57,4,49,50,53,52,4,52,53,56,55,4,55,56,59,58]))) + self.assertTrue(a4 is None) + self.assertTrue(a5 is None) + for i in xrange(30): + ffCell=allFMTSLeavesPerCommonSupport1[1][0][0][i] + fsst=MEDFileField1TSStructItem.BuildItemFrom(ffCell,mst) + ffCell.loadArraysIfNecessary() + v=mml2.buildDataArray(fsst,fields,ffCell.getUndergroundDataArray()) + self.assertEqual(v.getHiddenCppPointer(),ffCell.getUndergroundDataArray().getHiddenCppPointer()) + myarr=DataArrayDouble(98) ; myarr.iota() ; myarr[i]=100. + self.assertEqual(ffCell.getName(),"FieldOnFaces") + self.assertTrue(v.isEqual(myarr,1e-12)) + pass + pass + + def test31(self): + """non regression test of EDF 7972""" + fname="ForMEDReader31.med" + c=MEDCouplingCMesh() + arrX=DataArrayDouble(3) ; arrX.iota() + arrY=DataArrayDouble(4) ; arrY.iota() + arrZ=DataArrayDouble(5) ; arrZ.iota() + c.setCoords(arrX,arrY,arrZ) + c.setName("CartMesh") + cc=MEDFileCMesh() + cc.setMesh(c) + famIdCells=DataArrayInt(24) ; famIdCells[:]=0 + cc.setFamilyFieldArr(0,famIdCells) + #cc.setFamilyFieldArr(-1,famIdFaces) + cc.addFamily("FacesX",-1) ; cc.addFamily("FacesY",-2) ; cc.addFamily("FacesZ",-3) + cc.setFamiliesOnGroup("FacesX1",["FacesX"]) + cc.setFamiliesOnGroup("FacesY1",["FacesY"]) + cc.setFamiliesOnGroup("FacesZ1",["FacesZ"]) + fmts0=MEDFileFieldMultiTS() + fmts1=MEDFileFieldMultiTS() + pfl=DataArrayInt(11) ; pfl.iota() ; pfl.setName("PflOnHECA8") + for i in xrange(30): + f1ts=MEDFileField1TS() + fFaces=MEDCouplingFieldDouble(ON_CELLS) ; fFaces.setName("FieldOnCells") + arr=DataArrayDouble(11) ; arr.iota() ; arr[i%11]=100. + fFaces.setArray(arr) + fFaces.setTime(float(i)+0.1,i,-1) + fFaces.setMesh(c.buildUnstructured()[:11]) + f1ts.setFieldProfile(fFaces,cc,0,pfl)# here, a test is done to check that "NORM_HEXA8" string is not 30 times appended at the end of pfl name. + self.assertEqual("PflOnHECA8",pfl.getName()) + fmts0.pushBackTimeStep(f1ts) + pass + fs=MEDFileFields() + fs.pushField(fmts0) + cc.write(fname,2) + fs.write(fname,0) + ########## GO for reading in MEDReader,by not loading all. Mesh is fully loaded but not fields values + ms=MEDFileMeshes(fname) + fields=MEDFileFields(fname,False) + fields.removeFieldsWithoutAnyTimeStep() + fields_per_mesh=[fields.partOfThisLyingOnSpecifiedMeshName(meshName) for meshName in ms.getMeshesNames()] + allFMTSLeavesToDisplay=[] + for fields in fields_per_mesh: + allFMTSLeavesToDisplay2=[] + for fmts in fields: + tmp=fmts.splitDiscretizations() + for itmp in tmp: + self.assertTrue(not itmp.presenceOfMultiDiscPerGeoType()) + pass + allFMTSLeavesToDisplay2+=tmp + pass + allFMTSLeavesToDisplay.append(allFMTSLeavesToDisplay2) + pass + self.assertEqual(len(allFMTSLeavesToDisplay),1) + self.assertEqual(len(allFMTSLeavesToDisplay[0]),1) + allFMTSLeavesPerTimeSeries=MEDFileAnyTypeFieldMultiTS.SplitIntoCommonTimeSeries(sum(allFMTSLeavesToDisplay,[])) + self.assertEqual(len(allFMTSLeavesPerTimeSeries),1) + self.assertEqual(len(allFMTSLeavesPerTimeSeries[0]),1) + allFMTSLeavesPerCommonSupport1=MEDFileAnyTypeFieldMultiTS.SplitPerCommonSupport(allFMTSLeavesToDisplay[0],ms[ms.getMeshesNames()[0]]) + self.assertEqual(len(allFMTSLeavesPerCommonSupport1),1) + self.assertEqual(len(allFMTSLeavesPerCommonSupport1[0][0]),1) + # + mst=MEDFileMeshStruct.New(ms[0]) + # + fcscp=allFMTSLeavesPerCommonSupport1[0][1] + mml=fcscp.buildFromScratchDataSetSupport(0,fields) + mml2=mml.prepare() + self.assertTrue(isinstance(mml2,MEDUMeshMultiLev)) # here UMesh is important + ncc,a0,a1,a2,a3,a4,a5=mml2.buildVTUArrays() + self.assertTrue(not ncc)# here ncc=False because the coordinates are not in ms neither in children. This is the most important line in the test. + self.assertTrue(a0.isEqual(DataArrayDouble([0.,0.,0.,1.,0.,0.,2.,0.,0.,0.,1.,0.,1.,1.,0.,2.,1.,0.,0.,2.,0.,1.,2.,0.,2.,2.,0.,0.,3.,0.,1.,3.,0.,2.,3.,0.,0.,0.,1.,1.,0.,1.,2.,0.,1.,0.,1.,1.,1.,1.,1.,2.,1.,1.,0.,2.,1.,1.,2.,1.,2.,2.,1.,0.,3.,1.,1.,3.,1.,2.,3.,1.,0.,0.,2.,1.,0.,2.,2.,0.,2.,0.,1.,2.,1.,1.,2.,2.,1.,2.,0.,2.,2.,1.,2.,2.,2.,2.,2.,0.,3.,2.,1.,3.,2.,2.,3.,2.,0.,0.,3.,1.,0.,3.,2.,0.,3.,0.,1.,3.,1.,1.,3.,2.,1.,3.,0.,2.,3.,1.,2.,3.,2.,2.,3.,0.,3.,3.,1.,3.,3.,2.,3.,3.,0.,0.,4.,1.,0.,4.,2.,0.,4.,0.,1.,4.,1.,1.,4.,2.,1.,4.,0.,2.,4.,1.,2.,4.,2.,2.,4.,0.,3.,4.,1.,3.,4.,2.,3.,4.],60,3),1e-12)) + self.assertTrue(a1.isEqual(DataArrayByte([12,12,12,12,12,12,12,12,12,12,12]))) + self.assertTrue(a2.isEqual(DataArrayInt([0,9,18,27,36,45,54,63,72,81,90]))) + self.assertTrue(a3.isEqual(DataArrayInt([8,1,0,3,4,13,12,15,16,8,2,1,4,5,14,13,16,17,8,4,3,6,7,16,15,18,19,8,5,4,7,8,17,16,19,20,8,7,6,9,10,19,18,21,22,8,8,7,10,11,20,19,22,23,8,13,12,15,16,25,24,27,28,8,14,13,16,17,26,25,28,29,8,16,15,18,19,28,27,30,31,8,17,16,19,20,29,28,31,32,8,19,18,21,22,31,30,33,34]))) + self.assertTrue(a4 is None) + self.assertTrue(a5 is None) + for i in xrange(30): + ffCell=allFMTSLeavesPerCommonSupport1[0][0][0][i] + fsst=MEDFileField1TSStructItem.BuildItemFrom(ffCell,mst) + ffCell.loadArraysIfNecessary() + v=mml2.buildDataArray(fsst,fields,ffCell.getUndergroundDataArray()) + # self.assertEqual(v.getHiddenCppPointer(),ffCell.getUndergroundDataArray().getHiddenCppPointer()) # to be improved... maybe this line could be true + myarr=DataArrayDouble(11) ; myarr.iota() ; myarr[i%11]=100. + self.assertEqual(ffCell.getName(),"FieldOnCells") + self.assertTrue(v.isEqual(myarr,1e-12)) + pass + pass + + def test32(self): + """ This test is close to test30 except that here the profiles on dim-1 of structured mesh is considered here.""" + fname="ForMEDReader32.med" + c=MEDCouplingCMesh() + arrX=DataArrayDouble(3) ; arrX.iota() + arrY=DataArrayDouble(4) ; arrY.iota() + arrZ=DataArrayDouble(5) ; arrZ.iota() + c.setCoords(arrX,arrY,arrZ) + c.setName("CartMesh") + cc=MEDFileCMesh() + cc.setMesh(c) + tmpFacesMesh=c.build1SGTSubLevelMesh() + famIdFaces=DataArrayInt(98) ; famIdFaces[:36]=-1 ; famIdFaces[36:68]=-2 ; famIdFaces[68:]=-3 + famIdCells=DataArrayInt(24) ; famIdCells[:]=0 + cc.setFamilyFieldArr(0,famIdCells) + #cc.setFamilyFieldArr(-1,famIdFaces) + cc.addFamily("FacesX",-1) ; cc.addFamily("FacesY",-2) ; cc.addFamily("FacesZ",-3) + cc.setFamiliesOnGroup("FacesX1",["FacesX"]) + cc.setFamiliesOnGroup("FacesY1",["FacesY"]) + cc.setFamiliesOnGroup("FacesZ1",["FacesZ"]) + fmts0=MEDFileFieldMultiTS() + fmts1=MEDFileFieldMultiTS() + pfl=DataArrayInt(31) ; pfl.iota() ; pfl.setName("PflOnQUAD4") + for i in xrange(30): + f1ts=MEDFileField1TS() + fFaces=MEDCouplingFieldDouble(ON_CELLS) ; fFaces.setName("FieldOnFaces") + arr=DataArrayDouble(31) ; arr.iota() ; arr[i]=100. + fFaces.setArray(arr) + fFaces.setTime(float(i)+0.1,i,-1) + fFaces.setMesh(tmpFacesMesh[:31]) + f1ts.setFieldProfile(fFaces,cc,-1,pfl)# here, a test is done to check that "NORM_QUAD4" string is not 30 times appended at the end of pfl name. + self.assertEqual("PflOnQUAD4",pfl.getName()) + fmts0.pushBackTimeStep(f1ts) + # + f1ts=MEDFileField1TS() + fCells=MEDCouplingFieldDouble(ON_CELLS) ; fCells.setName("FieldOnCells") + arr=DataArrayDouble(24) ; arr.iota() ; arr[i%24]=30. + fCells.setArray(arr) + fCells.setTime(float(i)+0.1,i,-1) + fCells.setMesh(c) + f1ts.setFieldNoProfileSBT(fCells) + fmts1.pushBackTimeStep(f1ts) + pass + fs=MEDFileFields() + fs.pushField(fmts0) + fs.pushField(fmts1) + cc.write(fname,2) + fs.write(fname,0) + ########## GO for reading in MEDReader,by not loading all. Mesh is fully loaded but not fields values + ms=MEDFileMeshes(fname) + fields=MEDFileFields(fname,False) + fields.removeFieldsWithoutAnyTimeStep() + fields_per_mesh=[fields.partOfThisLyingOnSpecifiedMeshName(meshName) for meshName in ms.getMeshesNames()] + allFMTSLeavesToDisplay=[] + for fields in fields_per_mesh: + allFMTSLeavesToDisplay2=[] + for fmts in fields: + tmp=fmts.splitDiscretizations() + for itmp in tmp: + self.assertTrue(not itmp.presenceOfMultiDiscPerGeoType()) + pass + allFMTSLeavesToDisplay2+=tmp + pass + allFMTSLeavesToDisplay.append(allFMTSLeavesToDisplay2) + pass + self.assertEqual(len(allFMTSLeavesToDisplay),1) + self.assertEqual(len(allFMTSLeavesToDisplay[0]),2) + allFMTSLeavesPerTimeSeries=MEDFileAnyTypeFieldMultiTS.SplitIntoCommonTimeSeries(sum(allFMTSLeavesToDisplay,[])) + self.assertEqual(len(allFMTSLeavesPerTimeSeries),1) + self.assertEqual(len(allFMTSLeavesPerTimeSeries[0]),2) + allFMTSLeavesPerCommonSupport1=MEDFileAnyTypeFieldMultiTS.SplitPerCommonSupport(allFMTSLeavesToDisplay[0],ms[ms.getMeshesNames()[0]]) + self.assertEqual(len(allFMTSLeavesPerCommonSupport1),2) + self.assertEqual(len(allFMTSLeavesPerCommonSupport1[0][0]),1) + self.assertEqual(len(allFMTSLeavesPerCommonSupport1[1][0]),1) + # + mst=MEDFileMeshStruct.New(ms[0]) + # + fcscp=allFMTSLeavesPerCommonSupport1[0][1] + mml=fcscp.buildFromScratchDataSetSupport(0,fields) + mml2=mml.prepare() + self.assertTrue(isinstance(mml2,MEDCMeshMultiLev)) # here CMesh is important + (a,b,c),d=mml2.buildVTUArrays() + self.assertTrue(d)#d is True because the a,b and c are directly those in the internal data structure + self.assertTrue(a.isEqual(arrX,1e-12)) + self.assertTrue(b.isEqual(arrY,1e-12)) + self.assertTrue(c.isEqual(arrZ,1e-12)) + for i in xrange(30): + ffCell=allFMTSLeavesPerCommonSupport1[0][0][0][i] + fsst=MEDFileField1TSStructItem.BuildItemFrom(ffCell,mst) + ffCell.loadArraysIfNecessary() + v=mml2.buildDataArray(fsst,fields,ffCell.getUndergroundDataArray()) + self.assertEqual(v.getHiddenCppPointer(),ffCell.getUndergroundDataArray().getHiddenCppPointer()) + myarr=DataArrayDouble(24) ; myarr.iota() ; myarr[i%24]=30. + self.assertEqual(ffCell.getName(),"FieldOnCells") + self.assertTrue(v.isEqual(myarr,1e-12)) + pass + # + fcscp=allFMTSLeavesPerCommonSupport1[1][1] + mml=fcscp.buildFromScratchDataSetSupport(0,fields) + mml2=mml.prepare() + self.assertTrue(isinstance(mml2,MEDUMeshMultiLev)) # here UMesh is important + ncc,a0,a1,a2,a3,a4,a5=mml2.buildVTUArrays() + self.assertTrue(ncc)# True because, the coords are computed by the implicit unstructured level -1 structured mesh + self.assertTrue(a0.isEqual(DataArrayDouble([0.,0.,0.,1.,0.,0.,2.,0.,0.,0.,1.,0.,1.,1.,0.,2.,1.,0.,0.,2.,0.,1.,2.,0.,2.,2.,0.,0.,3.,0.,1.,3.,0.,2.,3.,0.,0.,0.,1.,1.,0.,1.,2.,0.,1.,0.,1.,1.,1.,1.,1.,2.,1.,1.,0.,2.,1.,1.,2.,1.,2.,2.,1.,0.,3.,1.,1.,3.,1.,2.,3.,1.,0.,0.,2.,1.,0.,2.,2.,0.,2.,0.,1.,2.,1.,1.,2.,2.,1.,2.,0.,2.,2.,1.,2.,2.,2.,2.,2.,0.,3.,2.,1.,3.,2.,2.,3.,2.,0.,0.,3.,1.,0.,3.,2.,0.,3.,0.,1.,3.,1.,1.,3.,2.,1.,3.,0.,2.,3.,1.,2.,3.,2.,2.,3.,0.,3.,3.,1.,3.,3.,2.,3.,3.,0.,0.,4.,1.,0.,4.,2.,0.,4.,0.,1.,4.,1.,1.,4.,2.,1.,4.,0.,2.,4.,1.,2.,4.,2.,2.,4.,0.,3.,4.,1.,3.,4.,2.,3.,4.],60,3),1e-12)) + self.assertTrue(a1.isEqual(DataArrayByte([9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9]))) + self.assertTrue(a2.isEqual(DataArrayInt([0,5,10,15,20,25,30,35,40,45,50,55,60,65,70,75,80,85,90,95,100,105,110,115,120,125,130,135,140,145,150]))) + self.assertTrue(a3.isEqual(DataArrayInt([4,0,12,15,3,4,12,24,27,15,4,24,36,39,27,4,36,48,51,39,4,3,15,18,6,4,15,27,30,18,4,27,39,42,30,4,39,51,54,42,4,6,18,21,9,4,18,30,33,21,4,30,42,45,33,4,42,54,57,45,4,1,13,16,4,4,13,25,28,16,4,25,37,40,28,4,37,49,52,40,4,4,16,19,7,4,16,28,31,19,4,28,40,43,31,4,40,52,55,43,4,7,19,22,10,4,19,31,34,22,4,31,43,46,34,4,43,55,58,46,4,2,14,17,5,4,14,26,29,17,4,26,38,41,29,4,38,50,53,41,4,5,17,20,8,4,17,29,32,20,4,29,41,44,32]))) + self.assertTrue(a4 is None) + self.assertTrue(a5 is None) + a6,a7=mml2.retrieveFamilyIdsOnCells() + self.assertTrue(a6 is None) + self.assertTrue(a7) + for i in xrange(30): + ffCell=allFMTSLeavesPerCommonSupport1[1][0][0][i] + fsst=MEDFileField1TSStructItem.BuildItemFrom(ffCell,mst) + ffCell.loadArraysIfNecessary() + v=mml2.buildDataArray(fsst,fields,ffCell.getUndergroundDataArray()) + self.assertEqual(v.getHiddenCppPointer(),ffCell.getUndergroundDataArray().getHiddenCppPointer()) + myarr=DataArrayDouble(31) ; myarr.iota() ; myarr[i]=100. + self.assertEqual(ffCell.getName(),"FieldOnFaces") + self.assertTrue(v.isEqual(myarr,1e-12)) + pass + pass + + def test33(self): + """Non regression test concerning polygons. Thanks Adrien. This bug can't be shown by simply reading an displaying a MED file containing only polygons. A filter must be applied on it to show it. The a2 array was responsible of that bug.""" + fname="ForMEDReader33.med" + fieldName="ACellField" + coo=DataArrayDouble([(5.5,0.5),(5.5,-0.5),(6.5,0.5),(6.5,-0.5),(6.5,1.5),(7.5,0.5),(7.5,-0.5),(7.5,1.5),(7.5,2.5),(8.5,0.5),(8.5,-0.5),(8.5,1.5),(8.5,2.5),(8.5,3.5),(8.55,0.5),(8.55,-0.5),(8.55,1.5),(8.55,2.5),(8.55,3.5)]) + m=MEDCouplingUMesh("mesh",2) + m.setCoords(coo) + m.allocateCells() + for i,c in enumerate([(1,0,2,3),(3,2,5,6),(2,4,7,5),(6,5,9,10),(5,7,11,9),(7,8,12,11),(10,9,14,15),(9,11,16,14),(11,12,17,16),(12,13,18,17)]): + if i<6: + typ=NORM_QUAD4 + pass + else: + typ=NORM_POLYGON + pass + m.insertNextCell(typ,c) + pass + mm=MEDFileUMesh() + mm.setMeshAtLevel(0,m) + mm.write(fname,2) + for i in xrange(15): + fCell0=MEDCouplingFieldDouble(ON_CELLS) ; fCell0.setTime(float(i)+0.1,i,0) + fCell0.setName(fieldName) ; fCell0.setMesh(m) + arr=DataArrayDouble(m.getNumberOfCells()) ; arr.iota(0) ; arr[i%10]=100. + fCell0.setArray(arr) ; arr.setInfoOnComponents(["Comp1 [m]"]) + fCell0.checkCoherency() + MEDLoader.WriteFieldUsingAlreadyWrittenMesh(fname,fCell0) + pass + ########## GO for reading in MEDReader,by not loading all. Mesh is fully loaded but not fields values + ms=MEDFileMeshes(fname) + fields=MEDFileFields(fname,False) + fields.removeFieldsWithoutAnyTimeStep() + fields_per_mesh=[fields.partOfThisLyingOnSpecifiedMeshName(meshName) for meshName in ms.getMeshesNames()] + allFMTSLeavesToDisplay=[] + for fields in fields_per_mesh: + allFMTSLeavesToDisplay2=[] + for fmts in fields: + tmp=fmts.splitDiscretizations() + for itmp in tmp: + self.assertTrue(not itmp.presenceOfMultiDiscPerGeoType()) + pass + allFMTSLeavesToDisplay2+=tmp + pass + allFMTSLeavesToDisplay.append(allFMTSLeavesToDisplay2) + pass + self.assertEqual(len(allFMTSLeavesToDisplay),1) + self.assertEqual(len(allFMTSLeavesToDisplay[0]),1) + allFMTSLeavesPerTimeSeries=MEDFileAnyTypeFieldMultiTS.SplitIntoCommonTimeSeries(sum(allFMTSLeavesToDisplay,[])) + self.assertEqual(len(allFMTSLeavesPerTimeSeries),1) + self.assertEqual(len(allFMTSLeavesPerTimeSeries[0]),1) + allFMTSLeavesPerCommonSupport1=MEDFileAnyTypeFieldMultiTS.SplitPerCommonSupport(allFMTSLeavesToDisplay[0],ms[ms.getMeshesNames()[0]]) + self.assertEqual(len(allFMTSLeavesPerCommonSupport1),1) + self.assertEqual(len(allFMTSLeavesPerCommonSupport1[0][0]),1) + # + mst=MEDFileMeshStruct.New(ms[0]) + # + fcscp=allFMTSLeavesPerCommonSupport1[0][1] + mml=fcscp.buildFromScratchDataSetSupport(0,fields) + mml2=mml.prepare() + self.assertTrue(isinstance(mml2,MEDUMeshMultiLev)) + ncc,a0,a1,a2,a3,a4,a5=mml2.buildVTUArrays() + self.assertTrue(not ncc)# false beacause 2D in MED file + self.assertTrue(a0.isEqual(DataArrayDouble([(5.5,0.5,0),(5.5,-0.5,0),(6.5,0.5,0),(6.5,-0.5,0),(6.5,1.5,0),(7.5,0.5,0),(7.5,-0.5,0),(7.5,1.5,0),(7.5,2.5,0),(8.5,0.5,0),(8.5,-0.5,0),(8.5,1.5,0),(8.5,2.5,0),(8.5,3.5,0),(8.55,0.5,0),(8.55,-0.5,0),(8.55,1.5,0),(8.55,2.5,0),(8.55,3.5,0)]),1e-12)) + self.assertTrue(a1.isEqual(DataArrayByte([9,9,9,9,9,9,7,7,7,7]))) + self.assertTrue(a2.isEqual(DataArrayInt([0,5,10,15,20,25,30,35,40,45])))# the bug was here. + self.assertTrue(a3.isEqual(DataArrayInt([4,1,0,2,3,4,3,2,5,6,4,2,4,7,5,4,6,5,9,10,4,5,7,11,9,4,7,8,12,11,4,10,9,14,15,4,9,11,16,14,4,11,12,17,16,4,12,13,18,17]))) + self.assertTrue(a4 is None) + self.assertTrue(a5 is None) + for i in xrange(15): + ffCell=allFMTSLeavesPerCommonSupport1[0][0][0][i] + fsst=MEDFileField1TSStructItem.BuildItemFrom(ffCell,mst) + ffCell.loadArraysIfNecessary() + v=mml2.buildDataArray(fsst,fields,ffCell.getUndergroundDataArray()) + self.assertEqual(v.getHiddenCppPointer(),ffCell.getUndergroundDataArray().getHiddenCppPointer()) + myarr=DataArrayDouble(10) ; myarr.iota() ; myarr[i%10]=100. ; myarr.setInfoOnComponent(0,"Comp1 [m]") + self.assertEqual(ffCell.getName(),fieldName) + self.assertTrue(v.isEqual(myarr,1e-12)) + pass + pass + + def test34(self): + """ This test is the thirs ultimate test (base on test12) for the profiles with gauss points. + This test highlight the hidden imp linked to bug #8655. + This test is close to test11 but here a 2nd field on cells without profile. So here the mesh is expected to be the same than m. + """ + fname="ForMEDReader34.med" + m=MEDCouplingCMesh("mesh") + arr=DataArrayDouble(5) ; arr.iota() + m.setCoords(arr,arr) + m=m.buildUnstructured() ; m.getCoords().setInfoOnComponents(["XX [m]","YYY [km]"]) + mm=MEDFileUMesh() ; mm.setMeshes([m]) + # + fieldName0="zeField0" + fieldName1="zeField1" + fs0=MEDFileFieldMultiTS() ; fs1=MEDFileFieldMultiTS() + for i in xrange(5): + f=MEDFileField1TS() + fNode=MEDCouplingFieldDouble(ON_GAUSS_PT) ; fNode.setTime(float(i),i,0) + fNode.setName(fieldName0) ; fNode.setMesh(m) + fNode.setGaussLocalizationOnCells([0,2,3,4,7,15],[-1.,-1.,1.,-1.,1.,1.,-1.,1.],[0.5,0.5,0.7,0.7],[0.8,0.2]) + fNode.setGaussLocalizationOnCells([1,5,8,9],[-1.,-1.,1.,-1.,1.,1.,-1.,1.],[0.5,0.5,0.7,0.7,0.1,0.1,0.2,0.2,0.3,0.3],[0.8,0.05,0.1,0.04,0.01]) + fNode.setGaussLocalizationOnCells([6,10,13],[-1.,-1.,1.,-1.,1.,1.,-1.,1.],[0.5,0.5,0.7,0.7,0.1,0.1,0.2,0.2],[0.8,0.05,0.1,0.04]) + fNode.setGaussLocalizationOnCells([11,12,14],[-1.,-1.,1.,-1.,1.,1.,-1.,1.],[0.5,0.5,0.7,0.7,0.1,0.1,0.2,0.2,0.3,0.3,0.4,0.4,0.8,0.8],[0.8,0.05,0.1,0.01,0.02,0.005,0.005]) + arr=DataArrayDouble(2*(2*6+5*4+4*3+7*3)) ; arr.iota(0+1000*i) ; arr.rearrange(2) + fNode.setArray(arr) ; arr.setInfoOnComponents(["Comp1_0 [m]","Com2_0 [s^2]"]) ; fNode.checkCoherency() + f.setFieldNoProfileSBT(fNode) + fs0.pushBackTimeStep(f) + # + f=MEDFileField1TS() + fNode=MEDCouplingFieldDouble(ON_CELLS) ; fNode.setTime(float(i),i,0) + fNode.setName(fieldName1) ; fNode.setMesh(m) + arr=DataArrayDouble(2*16) ; arr.iota(300+1000*i) ; arr.rearrange(2) + fNode.setArray(arr) ; arr.setInfoOnComponents(["Comp1_1 [m]","Com2_1 [s^2]"]) ; fNode.checkCoherency() + f.setFieldNoProfileSBT(fNode) + fs1.pushBackTimeStep(f) + pass + mm.write(fname,2) + fs0.write(fname,0) ; fs1.write(fname,0) + a0Exp=mm.getCoords().deepCpy() + del m,mm,fs0,fs1,f,fNode + ########## GO for reading in MEDReader,by not loading all. Mesh is fully loaded but not fields values + ms=MEDFileMeshes(fname) + fields=MEDFileFields(fname,False) + fields.removeFieldsWithoutAnyTimeStep() + fields_per_mesh=[fields.partOfThisLyingOnSpecifiedMeshName(meshName) for meshName in ms.getMeshesNames()] + allFMTSLeavesToDisplay=[] + for fields in fields_per_mesh: + allFMTSLeavesToDisplay2=[] + for fmts in fields: + tmp=fmts.splitDiscretizations() + for itmp in tmp: + if itmp.presenceOfMultiDiscPerGeoType(): + tmp2=itmp.splitMultiDiscrPerGeoTypes() + for iii,itmp2 in enumerate(tmp2): + name="%s_%i"%(itmp2.getName(),iii) + itmp2.setName(name) + allFMTSLeavesToDisplay2.append(itmp2) + pass + pass + else: + allFMTSLeavesToDisplay2.append(itmp) + pass + pass + allFMTSLeavesToDisplay.append(allFMTSLeavesToDisplay2) + pass + # Here 2 MED fields in input and at the end 5 ! 1+4 ! 4 fields have been built from zeField0 due to subspliting per dis / per geo type + self.assertEqual(len(allFMTSLeavesToDisplay),1) + self.assertEqual(len(allFMTSLeavesToDisplay[0]),5) + allFMTSLeavesPerTimeSeries=MEDFileAnyTypeFieldMultiTS.SplitIntoCommonTimeSeries(sum(allFMTSLeavesToDisplay,[])) + self.assertEqual(len(allFMTSLeavesPerTimeSeries),1) # one time serie here : because the 2 fields are defined on the same time steps + self.assertEqual(len(allFMTSLeavesPerTimeSeries[0]),5) + allFMTSLeavesPerCommonSupport=MEDFileAnyTypeFieldMultiTS.SplitPerCommonSupport(allFMTSLeavesPerTimeSeries[0],ms[ms.getMeshesNames()[0]]) + self.assertEqual(len(allFMTSLeavesPerCommonSupport),5) + for i in xrange(5): + self.assertEqual(len(allFMTSLeavesPerCommonSupport[i][0]),1) + # + mst=MEDFileMeshStruct.New(ms[0]) + # + fcscp=allFMTSLeavesPerCommonSupport[4][1] + mml=fcscp.buildFromScratchDataSetSupport(0,fields) + mml2=mml.prepare() + self.assertTrue(isinstance(mml2,MEDUMeshMultiLev)) + ncc,a0,a1,a2,a3,a4,a5=mml2.buildVTUArrays() + self.assertTrue(not ncc) + self.assertTrue(a0.isEqual(a0Exp.changeNbOfComponents(3,0.),1e-12)) + self.assertTrue(a1.isEqual(DataArrayByte([9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9]))) + self.assertTrue(a2.isEqual(DataArrayInt([0,5,10,15,20,25,30,35,40,45,50,55,60,65,70,75]))) + self.assertTrue(a3.isEqual(DataArrayInt([4,1,0,5,6,4,2,1,6,7,4,3,2,7,8,4,4,3,8,9,4,6,5,10,11,4,7,6,11,12,4,8,7,12,13,4,9,8,13,14,4,11,10,15,16,4,12,11,16,17,4,13,12,17,18,4,14,13,18,19,4,16,15,20,21,4,17,16,21,22,4,18,17,22,23,4,19,18,23,24]))) # <- here the mesh is NOT renumbered : the mesh is equal to m + self.assertTrue(a4 is None) + self.assertTrue(a5 is None) + for i in xrange(1,5): + self.assertTrue((fcscp.isDataSetSupportEqualToThePreviousOne(i,fields))) + pass + for i in xrange(5): + f=allFMTSLeavesPerCommonSupport[0][0][0][i] + fsst=MEDFileField1TSStructItem.BuildItemFrom(f,mst) + f.loadArraysIfNecessary() + v=mml.buildDataArray(fsst,fields,f.getUndergroundDataArray()) + self.assertEqual(f.getName(),fieldName0) + vExp=DataArrayDouble([(0.,1.),(2.,3.),(14.,15.),(16.,17.),(18.,19.),(20.,21.),(22.,23.),(24.,25.),(44.,45.),(46.,47.),(126.,127.),(128.,129.)]) + vExp.setInfoOnComponents(['Comp1_0 [m]','Com2_0 [s^2]']) + vExp+=i*1000 + self.assertTrue(v.isEqual(vExp,1e-12)) + # + f=allFMTSLeavesPerCommonSupport[1][0][0][i] + fsst=MEDFileField1TSStructItem.BuildItemFrom(f,mst) + f.loadArraysIfNecessary() + v=mml.buildDataArray(fsst,fields,f.getUndergroundDataArray()) + self.assertEqual(f.getName(),fieldName0) + vExp=DataArrayDouble([(4.,5.),(6.,7.),(8.,9.),(10.,11.),(12.,13.),(26.,27.),(28.,29.),(30.,31.),(32.,33.),(34.,35.),(48.,49.),(50.,51.),(52.,53.),(54.,55.),(56.,57.),(58.,59.),(60.,61.),(62.,63.),(64.,65.),(66.,67.)]) + vExp.setInfoOnComponents(['Comp1_0 [m]','Com2_0 [s^2]']) + vExp+=i*1000 + self.assertTrue(v.isEqual(vExp,1e-12)) + # + f=allFMTSLeavesPerCommonSupport[2][0][0][i] + fsst=MEDFileField1TSStructItem.BuildItemFrom(f,mst) + f.loadArraysIfNecessary() + v=mml.buildDataArray(fsst,fields,f.getUndergroundDataArray()) + self.assertEqual(f.getName(),fieldName0) + vExp=DataArrayDouble([(36.,37.),(38.,39.),(40.,41.),(42.,43.),(68.,69.),(70.,71.),(72.,73.),(74.,75.),(104.,105.),(106.,107.),(108.,109.),(110.,111.)]) + vExp.setInfoOnComponents(['Comp1_0 [m]','Com2_0 [s^2]']) + vExp+=i*1000 + self.assertTrue(v.isEqual(vExp,1e-12)) + # + f=allFMTSLeavesPerCommonSupport[3][0][0][i] + fsst=MEDFileField1TSStructItem.BuildItemFrom(f,mst) + f.loadArraysIfNecessary() + v=mml.buildDataArray(fsst,fields,f.getUndergroundDataArray()) + self.assertEqual(f.getName(),fieldName0) + vExp=DataArrayDouble([(76,77),(78,79),(80,81),(82,83),(84,85),(86,87),(88,89),(90,91),(92,93),(94,95),(96,97),(98,99),(100,101),(102,103),(112,113),(114,115),(116,117),(118,119),(120,121),(122,123),(124,125)]) + vExp.setInfoOnComponents(['Comp1_0 [m]','Com2_0 [s^2]']) + vExp+=i*1000 + self.assertTrue(v.isEqual(vExp,1e-12)) + # + f=allFMTSLeavesPerCommonSupport[4][0][0][i] + fsst=MEDFileField1TSStructItem.BuildItemFrom(f,mst) + f.loadArraysIfNecessary() + v=mml.buildDataArray(fsst,fields,f.getUndergroundDataArray()) + self.assertEqual(f.getName(),fieldName1) + self.assertEqual(v.getHiddenCppPointer(),f.getUndergroundDataArray().getHiddenCppPointer()) + vExp=DataArrayDouble(16*2) ; vExp.iota(300+i*1000) ; vExp.rearrange(2) ; vExp.setInfoOnComponents(['Comp1_1 [m]','Com2_1 [s^2]']) + self.assertTrue(v.isEqual(vExp,1e-12)) + pass + pass + + def test35(self): + """ Emulate MEDReader in // mode context. Here a Simple mesh having more nodes than really needed. This test focuses on that point particulary.""" + fname="ForMEDReader35.med" + arrX=DataArrayDouble(7) ; arrX.iota() + arrY=DataArrayDouble([0.,1.]) + m=MEDCouplingCMesh() ; m.setCoords(arrX,arrY) ; m=m.buildUnstructured() ; m=m[[0,5,1,4,2,3]] ; m.changeSpaceDimension(3,0.) ; m.setName("Mesh") + f=MEDCouplingFieldDouble(ON_CELLS) ; f.setMesh(m) ; f.setName("Field") ; f.setArray(DataArrayDouble([(0.1,1.1),(2.1,3.1),(4.1,5.1),(6.1,7.1),(8.1,9.1),(10.1,11.1)])) ; f.getArray().setInfoOnComponents(["aa","bbb"]) + MEDLoader.WriteUMesh(fname,m,True) + MEDLoader.WriteFieldUsingAlreadyWrittenMesh(fname,f) + ########## GO for reading in MEDReader,by not loading all. Mesh is fully loaded but not fields values + ms=MEDFileMeshes() # here we reproduce what is done by ParaMEDFileMeshes.ParaNew + ms.pushMesh(MEDFileUMesh.LoadPartOf(fname,"Mesh",[NORM_QUAD4],[0,2,1],-1,-1)); + ms[0].zipCoords() + # + fields=MEDFileFields.LoadPartOf(fname,False,ms); + fields.removeFieldsWithoutAnyTimeStep() + fields_per_mesh=[fields.partOfThisLyingOnSpecifiedMeshName(meshName) for meshName in ms.getMeshesNames()] + allFMTSLeavesToDisplay=[] + for fields in fields_per_mesh: + allFMTSLeavesToDisplay2=[] + for fmts in fields: + tmp=fmts.splitDiscretizations() + for itmp in tmp: + if itmp.presenceOfMultiDiscPerGeoType(): + tmp2=itmp.splitMultiDiscrPerGeoTypes() + for iii,itmp2 in enumerate(tmp2): + name="%s_%i"%(itmp2.getName(),iii) + itmp2.setName(name) + allFMTSLeavesToDisplay2.append(itmp2) + pass + pass + else: + allFMTSLeavesToDisplay2.append(itmp) + pass + pass + allFMTSLeavesToDisplay.append(allFMTSLeavesToDisplay2) + pass + # + self.assertEqual(len(allFMTSLeavesToDisplay),1) + self.assertEqual(len(allFMTSLeavesToDisplay[0]),1) + allFMTSLeavesPerTimeSeries=MEDFileAnyTypeFieldMultiTS.SplitIntoCommonTimeSeries(sum(allFMTSLeavesToDisplay,[])) + self.assertEqual(len(allFMTSLeavesPerTimeSeries),1) # one time serie here : because the 2 fields are defined on the same time steps + self.assertEqual(len(allFMTSLeavesPerTimeSeries[0]),1) + allFMTSLeavesPerCommonSupport=MEDFileAnyTypeFieldMultiTS.SplitPerCommonSupport(allFMTSLeavesPerTimeSeries[0],ms[ms.getMeshesNames()[0]]) + self.assertEqual(len(allFMTSLeavesPerCommonSupport),1) + self.assertEqual(len(allFMTSLeavesPerCommonSupport[0][0]),1) + # + mst=MEDFileMeshStruct.New(ms[0]) + # + fcscp=allFMTSLeavesPerCommonSupport[0][1] + mml=fcscp.buildFromScratchDataSetSupport(0,fields) + mml2=mml.prepare() + self.assertTrue(isinstance(mml2,MEDUMeshMultiLev)) + ncc,a0,a1,a2,a3,a4,a5=mml2.buildVTUArrays() + self.assertTrue(ncc) + self.assertTrue(a0.isEqual(m.getCoords()[[0,1,5,6,7,8,12,13]],1e-12))# <- the aim of the test + self.assertTrue(a1.isEqual(DataArrayByte([9,9]))) + self.assertTrue(a2.isEqual(DataArrayInt([0,5]))) + self.assertTrue(a3.isEqual(DataArrayInt([4,1,0,4,5,4,3,2,6,7]))) + self.assertTrue(a4 is None) + self.assertTrue(a5 is None) + f2=allFMTSLeavesPerCommonSupport[0][0][0][0] + fsst=MEDFileField1TSStructItem.BuildItemFrom(f2,mst) + f2.loadArraysIfNecessary() + v=mml.buildDataArray(fsst,fields,f2.getUndergroundDataArray()) + self.assertEqual(f2.getName(),f.getName()) + vExp=DataArrayDouble([(0.1,1.1),(2.1,3.1)]) + vExp.setInfoOnComponents(['aa','bbb']) + self.assertTrue(v.isEqual(vExp,1e-12)) + pass + + def test36(self): + """Bug EDF11027. Here mesh at level 0 (TRI3) does not fetch all the nodes. Level -1 (SEG2) does not fetch all the nodes neither. But all TRI3 + all SEG2 fetch all nodes. + aaa field on GAUSSPoints lying only on TRI3 share the same support than profile node field ccc. + But bbb field on all nodes is not on the same support. Past optimization that make the assumtion a support on all lev0 cells lies on all nodes is now over.""" + meshName="mesh" + fname="ForMEDReader36.med" + c=DataArrayDouble([(0,0),(1,0),(1,1),(0,1),(2,0),(-1,0),(1,2)]) + m0=MEDCoupling1SGTUMesh(meshName,NORM_TRI3) + m0.setCoords(c) + m0.setNodalConnectivity(DataArrayInt([0,2,1,3,2,0,2,4,1])) + mm=MEDFileUMesh() + mm[0]=m0 + m1=MEDCoupling1SGTUMesh(meshName,NORM_SEG2) + m1.setCoords(c) + m1.setNodalConnectivity(DataArrayInt([5,0,0,3,3,2,2,6])) + mm[-1]=m1 + # + zeTime=(1.1,2,3) + ff1=MEDFileField1TS() + f1=MEDCouplingFieldDouble(ON_NODES) ; f1.setMesh(m0) + arr=DataArrayDouble(7) ; arr.iota(2000) + f1.setArray(arr) + f1.setName("bbb") + f1.checkCoherency() + f1.setTime(*zeTime) + ff1.setFieldNoProfileSBT(f1) + # + ff2=MEDFileField1TS() + f2=MEDCouplingFieldDouble(ON_GAUSS_NE) ; f2.setMesh(m0) + arr=DataArrayDouble(9) ; arr.iota(4000) + f2.setArray(arr) + f2.setName("ddd") + f2.checkCoherency() + f2.setTime(*zeTime) + ff2.setFieldNoProfileSBT(f2) + # + ff3=MEDFileField1TS() + f3=MEDCouplingFieldDouble(ON_GAUSS_PT) ; f3.setMesh(m0) + f3.setGaussLocalizationOnType(NORM_TRI3,[0,0,1,0,0,1],[0.333333,0.333333],[0.5]) + arr=DataArrayDouble(3) ; arr.iota(1000) + f3.setArray(arr) + f3.checkCoherency() + f3.setTime(*zeTime) + f3.setName("aaa") + ff3.setFieldNoProfileSBT(f3) + # + ff4=MEDFileField1TS() + m0d=m0.deepCpy() ; m0d.zipCoords() + f4=MEDCouplingFieldDouble(ON_NODES) ; f4.setMesh(m0d) + arr=DataArrayDouble(5) ; arr.iota(3000) + f4.setArray(arr) + f4.setName("ccc") + f4.checkCoherency() + f4.setTime(*zeTime) + pfl=DataArrayInt([0,1,2,3,4]) ; pfl.setName("PFL") + ff4.setFieldProfile(f4,mm,0,pfl) + # + mm.write(fname,2) + ff3.write(fname,0) + ff1.write(fname,0) + ff4.write(fname,0) + ### + ms=MEDFileMeshes(fname) + fields=MEDFileFields(fname,False) + fields.removeFieldsWithoutAnyTimeStep() + fields_per_mesh=[fields.partOfThisLyingOnSpecifiedMeshName(meshName) for meshName in ms.getMeshesNames()] + allFMTSLeavesToDisplay=[] + for fields in fields_per_mesh: + allFMTSLeavesToDisplay2=[] + for fmts in fields: + tmp=fmts.splitDiscretizations() + for itmp in tmp: + self.assertTrue(not itmp.presenceOfMultiDiscPerGeoType()) + pass + allFMTSLeavesToDisplay2+=tmp + pass + allFMTSLeavesToDisplay.append(allFMTSLeavesToDisplay2) + pass + self.assertEqual(len(allFMTSLeavesToDisplay),1) + self.assertEqual(len(allFMTSLeavesToDisplay[0]),3) + allFMTSLeavesPerTimeSeries=MEDFileAnyTypeFieldMultiTS.SplitIntoCommonTimeSeries(sum(allFMTSLeavesToDisplay,[])) + self.assertEqual(len(allFMTSLeavesPerTimeSeries),1) + self.assertEqual(len(allFMTSLeavesPerTimeSeries[0]),3) + allFMTSLeavesPerCommonSupport1=MEDFileAnyTypeFieldMultiTS.SplitPerCommonSupport(allFMTSLeavesToDisplay[0],ms[ms.getMeshesNames()[0]]) + self.assertEqual(len(allFMTSLeavesPerCommonSupport1),2) + self.assertEqual(len(allFMTSLeavesPerCommonSupport1[0][0]),2) + self.assertEqual(len(allFMTSLeavesPerCommonSupport1[1][0]),1) + # + mst=MEDFileMeshStruct.New(ms[0]) + fcscp=allFMTSLeavesPerCommonSupport1[0][1] + mml=fcscp.buildFromScratchDataSetSupport(0,fields) + mml2=mml.prepare() + self.assertTrue(isinstance(mml2,MEDUMeshMultiLev)) + ncc,a0,a1,a2,a3,a4,a5=mml2.buildVTUArrays() + self.assertTrue(not ncc)# here ncc=False because the coordinates are not in ms neither in children. + self.assertTrue(a0.isEqual(DataArrayDouble([(0,0,0),(1,0,0),(1,1,0),(0,1,0),(2,0,0)]),1e-12)) + self.assertTrue(a1.isEqual(DataArrayByte([5,5,5]))) + self.assertTrue(a2.isEqual(DataArrayInt([0,4,8]))) + self.assertTrue(a3.isEqual(DataArrayInt([3,0,2,1,3,3,2,0,3,2,4,1]))) + self.assertTrue(a4 is None) + self.assertTrue(a5 is None) + for i in xrange(1): + ffCell=allFMTSLeavesPerCommonSupport1[0][0][0][i] + fsst=MEDFileField1TSStructItem.BuildItemFrom(ffCell,mst) + ffCell.loadArraysIfNecessary() + v=mml2.buildDataArray(fsst,fields,ffCell.getUndergroundDataArray()) + self.assertEqual(v.getHiddenCppPointer(),ffCell.getUndergroundDataArray().getHiddenCppPointer()) + v.isEqual(DataArrayDouble([1000,1001,1002]),1e-12) + # + ffCell=allFMTSLeavesPerCommonSupport1[0][0][1][i] + fsst=MEDFileField1TSStructItem.BuildItemFrom(ffCell,mst) + ffCell.loadArraysIfNecessary() + v=mml2.buildDataArray(fsst,fields,ffCell.getUndergroundDataArray()) + self.assertEqual(v.getHiddenCppPointer(),ffCell.getUndergroundDataArray().getHiddenCppPointer()) + v.isEqual(DataArrayDouble([3000,3001,3002,3003,3004]),1e-12) + pass + fcscp=allFMTSLeavesPerCommonSupport1[1][1] + mml=fcscp.buildFromScratchDataSetSupport(0,fields) + mml2=mml.prepare() + self.assertTrue(isinstance(mml2,MEDUMeshMultiLev)) + ncc,a0,a1,a2,a3,a4,a5=mml2.buildVTUArrays() + self.assertTrue(not ncc)# here ncc=False because the coordinates are not in ms neither in children. + self.assertTrue(a0.isEqual(DataArrayDouble([(0,0,0),(1,0,0),(1,1,0),(0,1,0),(2,0,0),(-1,0,0),(1,2,0)]),1e-12)) + self.assertTrue(a1.isEqual(DataArrayByte([5,5,5,3,3,3,3]))) + self.assertTrue(a2.isEqual(DataArrayInt([0,4,8,12,15,18,21]))) + self.assertTrue(a3.isEqual(DataArrayInt([3,0,2,1,3,3,2,0,3,2,4,1,2,5,0,2,0,3,2,3,2,2,2,6]))) + self.assertTrue(a4 is None) + self.assertTrue(a5 is None) + for i in xrange(1): + ffCell=allFMTSLeavesPerCommonSupport1[1][0][0][i] + fsst=MEDFileField1TSStructItem.BuildItemFrom(ffCell,mst) + ffCell.loadArraysIfNecessary() + v=mml2.buildDataArray(fsst,fields,ffCell.getUndergroundDataArray()) + self.assertEqual(v.getHiddenCppPointer(),ffCell.getUndergroundDataArray().getHiddenCppPointer()) + v.isEqual(DataArrayDouble([2000,2001,2002,2003,2004,2005,2006]),1e-12) + pass + pass + + pass + +if __name__ == "__main__": + unittest.main() diff --git a/src/medtool/src/MEDLoader/Swig/MEDLoaderTypemaps.i b/src/medtool/src/MEDLoader/Swig/MEDLoaderTypemaps.i new file mode 100644 index 000000000..5a415a685 --- /dev/null +++ b/src/medtool/src/MEDLoader/Swig/MEDLoaderTypemaps.i @@ -0,0 +1,358 @@ +// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 +// 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 <vector> + +static PyObject *convertMEDFileMesh(ParaMEDMEM::MEDFileMesh* mesh, int owner) throw(INTERP_KERNEL::Exception) +{ + PyObject *ret=0; + if(!mesh) + { + Py_XINCREF(Py_None); + return Py_None; + } + if(dynamic_cast<ParaMEDMEM::MEDFileUMesh *>(mesh)) + ret=SWIG_NewPointerObj((void*)mesh,SWIGTYPE_p_ParaMEDMEM__MEDFileUMesh,owner); + if(dynamic_cast<ParaMEDMEM::MEDFileCMesh *>(mesh)) + ret=SWIG_NewPointerObj((void*)mesh,SWIGTYPE_p_ParaMEDMEM__MEDFileCMesh,owner); + if(dynamic_cast<ParaMEDMEM::MEDFileCurveLinearMesh *>(mesh)) + ret=SWIG_NewPointerObj((void*)mesh,SWIGTYPE_p_ParaMEDMEM__MEDFileCurveLinearMesh,owner); + if(!ret) + throw INTERP_KERNEL::Exception("Not recognized type of MEDFileMesh on downcast !"); + return ret; +} + +static PyObject *convertMEDFileParameter1TS(ParaMEDMEM::MEDFileParameter1TS* p1ts, int owner) throw(INTERP_KERNEL::Exception) +{ + PyObject *ret=0; + if(!p1ts) + { + Py_XINCREF(Py_None); + return Py_None; + } + if(dynamic_cast<MEDFileParameterDouble1TS *>(p1ts)) + ret=SWIG_NewPointerObj((void*)p1ts,SWIGTYPE_p_ParaMEDMEM__MEDFileParameterDouble1TS,owner); + if(dynamic_cast<MEDFileParameterDouble1TSWTI *>(p1ts)) + ret=SWIG_NewPointerObj((void*)p1ts,SWIGTYPE_p_ParaMEDMEM__MEDFileParameterDouble1TSWTI,owner); + if(!ret) + throw INTERP_KERNEL::Exception("Not recognized type of MEDFileParameter1TS on downcast !"); + return ret; +} + +static PyObject *convertMEDFileField1TS(ParaMEDMEM::MEDFileAnyTypeField1TS *p, int owner) throw(INTERP_KERNEL::Exception) +{ + PyObject *ret=0; + if(!p) + { + Py_XINCREF(Py_None); + return Py_None; + } + if(dynamic_cast<MEDFileField1TS *>(p)) + ret=SWIG_NewPointerObj((void*)p,SWIGTYPE_p_ParaMEDMEM__MEDFileField1TS,owner); + if(dynamic_cast<MEDFileIntField1TS *>(p)) + ret=SWIG_NewPointerObj((void*)p,SWIGTYPE_p_ParaMEDMEM__MEDFileIntField1TS,owner); + if(!ret) + throw INTERP_KERNEL::Exception("Not recognized type of MEDFileAnyTypeField1TS on downcast !"); + return ret; +} + +static PyObject *convertMEDFileFieldMultiTS(ParaMEDMEM::MEDFileAnyTypeFieldMultiTS *p, int owner) throw(INTERP_KERNEL::Exception) +{ + PyObject *ret=0; + if(!p) + { + Py_XINCREF(Py_None); + return Py_None; + } + if(dynamic_cast<MEDFileFieldMultiTS *>(p)) + ret=SWIG_NewPointerObj((void*)p,SWIGTYPE_p_ParaMEDMEM__MEDFileFieldMultiTS,owner); + if(dynamic_cast<MEDFileIntFieldMultiTS *>(p)) + ret=SWIG_NewPointerObj((void*)p,SWIGTYPE_p_ParaMEDMEM__MEDFileIntFieldMultiTS,owner); + if(!ret) + throw INTERP_KERNEL::Exception("Not recognized type of MEDFileAnyTypeFieldMultiTS on downcast !"); + return ret; +} + +static PyObject *convertMEDMeshMultiLev(ParaMEDMEM::MEDMeshMultiLev *p, int owner) throw(INTERP_KERNEL::Exception) +{ + PyObject *ret=0; + if(!p) + { + Py_XINCREF(Py_None); + return Py_None; + } + if(dynamic_cast<MEDUMeshMultiLev *>(p)) + ret=SWIG_NewPointerObj((void*)p,SWIGTYPE_p_ParaMEDMEM__MEDUMeshMultiLev,owner); + if(dynamic_cast<MEDCMeshMultiLev *>(p)) + ret=SWIG_NewPointerObj((void*)p,SWIGTYPE_p_ParaMEDMEM__MEDCMeshMultiLev,owner); + if(dynamic_cast<MEDCurveLinearMeshMultiLev *>(p)) + ret=SWIG_NewPointerObj((void*)p,SWIGTYPE_p_ParaMEDMEM__MEDCurveLinearMeshMultiLev,owner); + if(!ret) + throw INTERP_KERNEL::Exception("Not recognized type of MEDMeshMultiLev on downcast !"); + return ret; +} + +static std::vector<std::pair<int,int> > convertTimePairIdsFromPy(PyObject *pyLi) throw(INTERP_KERNEL::Exception) +{ + std::vector<std::pair<int,int> > ret; + if(PyList_Check(pyLi)) + { + int size=PyList_Size(pyLi); + ret.resize(size); + for(int i=0;i<size;i++) + { + PyObject *o=PyList_GetItem(pyLi,i); + if(PyTuple_Check(o)) + { + std::pair<int,int> p; + int size2=PyTuple_Size(o); + if(size2!=2) + throw INTERP_KERNEL::Exception("tuples in list must be of size 2 (dt,it) !"); + PyObject *o0=PyTuple_GetItem(o,0); + if(PyInt_Check(o0)) + p.first=(int)PyInt_AS_LONG(o0); + else + throw INTERP_KERNEL::Exception("First elem of tuples in list must be integer : dt !"); + PyObject *o1=PyTuple_GetItem(o,1); + if(PyInt_Check(o1)) + p.second=(int)PyInt_AS_LONG(o1); + else + throw INTERP_KERNEL::Exception("Second elem of tuples in list must be integer : dt !"); + ret[i]=p; + } + else + throw INTERP_KERNEL::Exception("list must contain tuples only"); + } + } + else + throw INTERP_KERNEL::Exception("convertTimePairIdsFromPy : not a list"); + return ret; +} + +static void converPyListToVecString(PyObject *pyLi, std::vector<std::string>& v) +{ + if(PyList_Check(pyLi)) + { + int size=PyList_Size(pyLi); + v.resize(size); + for(int i=0;i<size;i++) + { + PyObject *o=PyList_GetItem(pyLi,i); + if(!PyString_Check(o)) + throw INTERP_KERNEL::Exception("In list passed in argument some elements are NOT strings ! Expected a list containing only strings !"); + const char *st=PyString_AsString(o); + v[i]=std::string(st); + } + } + else if(PyTuple_Check(pyLi)) + { + int size=PyTuple_Size(pyLi); + v.resize(size); + for(int i=0;i<size;i++) + { + PyObject *o=PyTuple_GetItem(pyLi,i); + if(!PyString_Check(o)) + throw INTERP_KERNEL::Exception("In tuple passed in argument some elements are NOT strings ! Expected a tuple containing only strings !"); + const char *st=PyString_AsString(o); + v[i]=std::string(st); + } + } + else if(PyString_Check(pyLi)) + { + v.resize(1); + v[0]=std::string((const char *)PyString_AsString(pyLi)); + } + else + { + throw INTERP_KERNEL::Exception("Unrecognized python argument : expected a list of string or tuple of string or string !"); + } +} + +static PyObject *convertFieldDoubleVecToPy(const std::vector<ParaMEDMEM::MEDCouplingFieldDouble *>& li) +{ + int sz=li.size(); + PyObject *ret=PyList_New(sz); + for(int i=0;i<sz;i++) + { + PyObject *o=SWIG_NewPointerObj((void*)li[i],SWIGTYPE_p_ParaMEDMEM__MEDCouplingFieldDouble,SWIG_POINTER_OWN | 0); + PyList_SetItem(ret,i,o); + } + return ret; +} + +PyObject *convertVecPairVecStToPy(const std::vector< std::pair<std::vector<std::string>, std::string > >& vec) +{ + int sz=(int)vec.size(); + PyObject *ret=PyList_New(sz); + for(int i=0;i<sz;i++) + { + PyObject *t=PyTuple_New(2); + int sz2=(int)vec[i].first.size(); + PyObject *ll=PyList_New(sz2); + for(int j=0;j<sz2;j++) + PyList_SetItem(ll,j,PyString_FromString(vec[i].first[j].c_str())); + PyTuple_SetItem(t,0,ll); + PyTuple_SetItem(t,1,PyString_FromString(vec[i].second.c_str())); + PyList_SetItem(ret,i,t); + } + return ret; +} + +std::vector< std::pair<std::string, std::string > > convertVecPairStStFromPy(PyObject *pyLi) +{ + std::vector< std::pair<std::string, std::string > > ret; + const char *msg="convertVecPairStStFromPy : Expecting PyList of Tuples of size 2 ! The first elt in tuple is one string and the 2nd one a string !"; + if(PyList_Check(pyLi)) + { + int size=PyList_Size(pyLi); + ret.resize(size); + for(int i=0;i<size;i++) + { + PyObject *o=PyList_GetItem(pyLi,i); + if(PyTuple_Check(o)) + { + std::pair<std::string, std::string> p; + int size2=PyTuple_Size(o); + if(size2!=2) + throw INTERP_KERNEL::Exception(msg); + PyObject *o0=PyTuple_GetItem(o,0); + if(PyString_Check(o0)) + p.first=std::string(PyString_AsString(o0)); + else + throw INTERP_KERNEL::Exception(msg); + PyObject *o1=PyTuple_GetItem(o,1); + if(PyString_Check(o1)) + p.second=std::string(PyString_AsString(o1)); + else + throw INTERP_KERNEL::Exception(msg); + ret[i]=p; + } + else + throw INTERP_KERNEL::Exception(msg); + } + return ret; + } + throw INTERP_KERNEL::Exception(msg); +} + +std::vector< std::pair<std::vector<std::string>, std::string > > convertVecPairVecStFromPy(PyObject *pyLi) +{ + std::vector< std::pair<std::vector<std::string>, std::string > > ret; + const char *msg="convertVecPairVecStFromPy : Expecting PyList of Tuples of size 2 ! The first elt in tuple is a list of strings and the 2nd one a string !"; + if(PyList_Check(pyLi)) + { + int size=PyList_Size(pyLi); + ret.resize(size); + for(int i=0;i<size;i++) + { + PyObject *o=PyList_GetItem(pyLi,i); + if(PyTuple_Check(o)) + { + std::pair<std::vector<std::string>, std::string> p; + int size2=PyTuple_Size(o); + if(size2!=2) + throw INTERP_KERNEL::Exception(msg); + PyObject *o0=PyTuple_GetItem(o,0); + if(PyList_Check(o0)) + { + int size3=PyList_Size(o0); + p.first.resize(size3); + for(int j=0;j<size3;j++) + { + PyObject *o0j=PyList_GetItem(o0,j); + if(PyString_Check(o0j)) + { + p.first[j]=std::string(PyString_AsString(o0j)); + } + else + throw INTERP_KERNEL::Exception(msg); + } + } + else + throw INTERP_KERNEL::Exception(msg); + PyObject *o1=PyTuple_GetItem(o,1); + if(PyString_Check(o1)) + p.second=std::string(PyString_AsString(o1)); + else + throw INTERP_KERNEL::Exception(msg); + ret[i]=p; + } + else + throw INTERP_KERNEL::Exception(msg); + } + return ret; + } + throw INTERP_KERNEL::Exception(msg); +} + +/*! + * Called by MEDFileAnyTypeFieldMultiTS::__getitem__ when \a elt0 is neither a list nor a slice. + * In this case a MEDFileAnyTypeField1TS object is returned. + */ +int MEDFileAnyTypeFieldMultiTSgetitemSingleTS__(const MEDFileAnyTypeFieldMultiTS *self, PyObject *elt0) throw(INTERP_KERNEL::Exception) +{ + if(elt0 && PyInt_Check(elt0)) + {//fmts[3] + return InterpreteNegativeInt(PyInt_AS_LONG(elt0),self->getNumberOfTS()); + } + else if(elt0 && PyTuple_Check(elt0)) + { + if(PyTuple_Size(elt0)==2) + { + PyObject *o0=PyTuple_GetItem(elt0,0); + PyObject *o1=PyTuple_GetItem(elt0,1); + if(PyInt_Check(o0) && PyInt_Check(o1)) + {//fmts(1,-1) + int iter=PyInt_AS_LONG(o0); + int order=PyInt_AS_LONG(o1); + return self->getPosOfTimeStep(iter,order); + } + else + throw INTERP_KERNEL::Exception("MEDFileAnyTypeFieldMultiTS::__getitem__ : invalid input param ! input is a tuple of size 2 but two integers are expected in this tuple to request a time steps !"); + } + else + throw INTERP_KERNEL::Exception("MEDFileAnyTypeFieldMultiTS::__getitem__ : invalid input param ! input is a tuple of size != 2 ! two integers are expected in this tuple to request a time steps !"); + } + else if(elt0 && PyFloat_Check(elt0)) + { + double val=PyFloat_AS_DOUBLE(elt0); + return self->getPosGivenTime(val); + } + else + throw INTERP_KERNEL::Exception("MEDFileAnyTypeFieldMultiTS::__getitem__ : invalid input params ! expected fmts[int], fmts[int,int], or fmts[double] to request one time step ! To request a series of time steps invoke fmts[slice], fmts[list of int], fmts[list of double], or fmts[list of int,int] !"); +} + +/*! + * Called by MEDFileAnyTypeFieldMultiTS::__getitem__ when \a obj is neither a list nor a slice. + * In this case a MEDFileAnyTypeField1TS object is returned. + */ +int MEDFileFieldsgetitemSingleTS__(const MEDFileFields *self, PyObject *obj) throw(INTERP_KERNEL::Exception) +{ + if(PyInt_Check(obj)) + { + return InterpreteNegativeInt((int)PyInt_AS_LONG(obj),self->getNumberOfFields()); + } + else if(PyString_Check(obj)) + { + return self->getPosFromFieldName(PyString_AsString(obj)); + } + else + throw INTERP_KERNEL::Exception("MEDFileFields::__getitem__ : only integer or string with fieldname supported !"); +} diff --git a/src/medtool/src/MEDLoader/Swig/SauvLoaderTest.py b/src/medtool/src/MEDLoader/Swig/SauvLoaderTest.py new file mode 100644 index 000000000..502e4e468 --- /dev/null +++ b/src/medtool/src/MEDLoader/Swig/SauvLoaderTest.py @@ -0,0 +1,391 @@ +# -*- coding: iso-8859-1 -*- +# Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 +# 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 : Edward AGAPOV (eap) + +from MEDLoader import * +import unittest, os +from MEDLoaderDataForTest import MEDLoaderDataForTest + +class SauvLoaderTest(unittest.TestCase): + + def testSauv2Med(self): + # get a file containing all types of readable piles + self.assertTrue( os.getenv("MED_ROOT_DIR") ) + sauvFile = os.path.join( os.getenv("MED_ROOT_DIR"), "share","salome", + "resources","med","allPillesTest.sauv") + self.assertTrue( os.access( sauvFile, os.F_OK)) + + # read SAUV and write MED + medFile = "SauvLoaderTest.med" + sr=SauvReader(sauvFile); + d2=sr.loadInMEDFileDS(); + d2.write(medFile,0); + + # check + self.assertEqual(1,d2.getNumberOfMeshes()) + self.assertEqual(8+97,d2.getNumberOfFields()) + mm = d2.getMeshes() + m = mm.getMeshAtPos(0) + self.assertEqual(17,len(m.getGroupsNames())) + + os.remove( medFile ) + pass + + def testMed2Sauv(self): + # read pointe.med + self.assertTrue( os.getenv("MED_ROOT_DIR") ) + medFile = os.path.join( os.getenv("MED_ROOT_DIR"), "share","salome", + "resources","med","pointe.med") + self.assertTrue( os.access( medFile, os.F_OK)) + pointeMed = MEDFileData.New( medFile ) + + # add 3 faces to pointeMed + pointeMedMesh = pointeMed.getMeshes().getMeshAtPos(0) + pointeM1D = MEDCouplingUMesh.New() + pointeM1D.setCoords( pointeMedMesh.getCoords() ) + pointeM1D.setMeshDimension( 2 ) + pointeM1D.allocateCells( 3 ) + pointeM1D.insertNextCell( NORM_TRI3, 3, [0,1,2]) + pointeM1D.insertNextCell( NORM_TRI3, 3, [0,1,3]) + pointeM1D.insertNextCell( NORM_QUAD4, 4, [10,11,12,13]) + pointeM1D.finishInsertingCells() + pointeMedMesh.setMeshAtLevel( -1, pointeM1D ) + pointeMed.getMeshes().setMeshAtPos( 0, pointeMedMesh ) + + # add a field on 2 faces to pointeMed + ff1=MEDFileFieldMultiTS.New() + f1=MEDCouplingFieldDouble.New(ON_GAUSS_NE,ONE_TIME) + #f1.setMesh( pointeM1D ) + f1.setName("Field on 2 faces") + d=DataArrayDouble.New() + d.alloc(3+4,2) + d.setInfoOnComponent(0,"sigX [MPa]") + d.setInfoOnComponent(1,"sigY [GPa]") + d.setValues([311,312,321,322,331,332,411,412,421,422,431,432,441,442],3+4,2) + f1.setArray(d) + da=DataArrayInt.New() + da.setValues([0,2],2,1) + da.setName("sup2") + ff1.appendFieldProfile(f1,pointeMedMesh,-1,da) + pointeMed.getFields().pushField( ff1 ) + + #remove fieldnodeint + pointeFields = pointeMed.getFields() + for i in range( pointeFields.getNumberOfFields() ): + if pointeFields.getFieldAtPos(i).getName() == "fieldnodeint": + pointeFields.destroyFieldAtPos( i ) + break + + # write pointeMed to SAUV + sauvFile = "SauvLoaderTest.sauv" + sw=SauvWriter(); + sw.setMEDFileDS(pointeMed); + sw.write(sauvFile); + + # read SAUV and check + sr=SauvReader.New(sauvFile); + d2=sr.loadInMEDFileDS(); + self.assertEqual(1,d2.getNumberOfMeshes()) + self.assertEqual(4,d2.getNumberOfFields()) + m = d2.getMeshes().getMeshAtPos(0) + self.assertEqual("maa1",m.getName()) + self.assertEqual(6,len(m.getGroupsNames())) + self.assertEqual(3,m.getMeshDimension()) + groups = m.getGroupsNames() + self.assertTrue( "groupe1" in groups ) + self.assertTrue( "groupe2" in groups ) + self.assertTrue( "groupe3" in groups ) + self.assertTrue( "groupe4" in groups ) + self.assertTrue( "groupe5" in groups ) + self.assertTrue( "maa1" in groups ) + self.assertEqual(16,m.getSizeAtLevel(0)) + um0 = m.getGenMeshAtLevel(0) + self.assertEqual(12, um0.getNumberOfCellsWithType( NORM_TETRA4 )) + self.assertEqual(2, um0.getNumberOfCellsWithType( NORM_PYRA5 )) + self.assertEqual(2, um0.getNumberOfCellsWithType( NORM_HEXA8 )) + um1 = m.getGenMeshAtLevel(-1) + self.assertEqual(2, um1.getNumberOfCellsWithType( NORM_TRI3 )) + pointeUM0 = pointeMedMesh.getGenMeshAtLevel(0) + self.assertTrue(m.getCoords().isEqualWithoutConsideringStr(pointeMedMesh.getCoords(),1e-12)) + self.assertEqual( um0.getMeasureField(0).accumulate(0), + pointeUM0.getMeasureField(0).accumulate(0),1e-12) + # check fields + # fieldnodedouble + fieldnodedoubleTS1 = pointeMed.getFields().getFieldWithName("fieldnodedouble") + fieldnodedoubleTS2 = d2.getFields().getFieldWithName("fieldnodedouble") + self.assertEqual( fieldnodedoubleTS1.getInfo(), fieldnodedoubleTS2.getInfo()) + self.assertEqual( fieldnodedoubleTS1.getNumberOfTS(), fieldnodedoubleTS2.getNumberOfTS()) + io1 = fieldnodedoubleTS1.getIterations() + io2 = fieldnodedoubleTS2.getIterations() + for i in range(fieldnodedoubleTS1.getNumberOfTS() ): + fnd1 = fieldnodedoubleTS1.getFieldOnMeshAtLevel(ON_NODES, io1[i][0],io1[i][1],pointeUM0) + fnd2 = fieldnodedoubleTS2.getFieldOnMeshAtLevel(ON_NODES, io2[i][0],io2[i][1],um0) + self.assertTrue( fnd1.getArray().isEqual( fnd2.getArray(), 1e-12 )) + # fieldcelldoublevector + fieldnodedoubleTS1 = pointeMed.getFields().getFieldWithName("fieldcelldoublevector") + fieldnodedoubleTS2 = d2.getFields().getFieldWithName("fieldcelldoublevector") + self.assertEqual( fieldnodedoubleTS1.getInfo(), fieldnodedoubleTS2.getInfo()) + self.assertEqual( fieldnodedoubleTS1.getNumberOfTS(), fieldnodedoubleTS2.getNumberOfTS()) + io1 = fieldnodedoubleTS1.getIterations() + io2 = fieldnodedoubleTS2.getIterations() + for i in range(fieldnodedoubleTS1.getNumberOfTS() ): + fnd1 = fieldnodedoubleTS1.getFieldOnMeshAtLevel(ON_CELLS, io1[i][0],io1[i][1],pointeUM0) + fnd2 = fieldnodedoubleTS2.getFieldOnMeshAtLevel(ON_CELLS, io2[i][0],io2[i][1],um0) + self.assertAlmostEqual( fnd1.accumulate(0), fnd2.accumulate(0) ) + self.assertAlmostEqual( fnd1.accumulate(1), fnd2.accumulate(1) ) + self.assertAlmostEqual( fnd1.accumulate(2), fnd2.accumulate(2) ) + # Field on 2 faces + fieldOnFaces = d2.getFields().getFieldWithName(f1.getName()) + io1 = fieldOnFaces.getIterations() + fof = fieldOnFaces.getFieldOnMeshAtLevel(f1.getTypeOfField(),io1[i][0],io1[i][1],um1) + self.assertTrue( d.isEqual( fof.getArray(), 1e-12 )) + pass + del sr + os.remove( sauvFile ) + pass + + def testSauv2MedWONodeFamilyNum(self): + """test for issue 0021673: [CEA 566] Bug in SauvWriter when writing meshes + having no family ids on nodes.""" + + myCoords=DataArrayDouble.New([-0.3,-0.3, 0.2,-0.3, 0.7,-0.3, -0.3,0.2, 0.2,0.2, 0.7,0.2, -0.3,0.7, 0.2,0.7, 0.7,0.7 ],9,2) + targetConn=[0,3,4,1, 1,4,2, 4,5,2, 6,7,4,3, 7,8,5,4]; + targetMesh=MEDCouplingUMesh.New("BugInSauvWriter",2); + targetMesh.allocateCells(5); + targetMesh.insertNextCell(NORM_TRI3,3,targetConn[4:7]); + targetMesh.insertNextCell(NORM_TRI3,3,targetConn[7:10]); + targetMesh.insertNextCell(NORM_QUAD4,4,targetConn[0:4]); + targetMesh.insertNextCell(NORM_QUAD4,4,targetConn[10:14]); + targetMesh.insertNextCell(NORM_QUAD4,4,targetConn[14:18]); + targetMesh.finishInsertingCells(); + targetMesh.setCoords(myCoords); + # + m=MEDFileUMesh.New() + m.setMeshAtLevel(0,targetMesh) + # start of bug + fam=DataArrayInt.New(targetMesh.getNumberOfNodes()) + fam[:]=0 + #m.setFamilyFieldArr(1,fam) + #end of bug + + ms=MEDFileMeshes.New() + ms.setMeshAtPos(0,m) + meddata=MEDFileData.New() + meddata.setMeshes(ms) + + medFile = "BugInSauvWriter.sauv" + sw=SauvWriter.New(); + sw.setMEDFileDS(meddata); + sw.write(medFile); + + os.remove( medFile ) + pass + + def testSauv2MedOnPipe1D(self): + """test for issue 0021745: [CEA 600] Some missing groups in mesh after reading a SAUV file with SauvReader.""" + sauvFile="Test_sauve_1D.sauv" + # Make a sauve file with a qudratic 1D mesh + m=MEDCouplingUMesh.New("pipe1D",1) + m.allocateCells(2); + targetConn=[0,2,1, 2,4,3] + m.insertNextCell(NORM_SEG3,3,targetConn[0:3]) + m.insertNextCell(NORM_SEG3,3,targetConn[3:6]) + m.finishInsertingCells(); + # coords + coords=[ 0.,1.,2.,4.,5. ]; + c=DataArrayDouble.New() + c.setValues(coords,5,1) + m.setCoords(c) + # MEDFileUMesh + mm=MEDFileUMesh.New() + mm.setName(m.getName()) + mm.setDescription("1D mesh") + mm.setCoords(c) + mm.setMeshAtLevel(0,m); + # MEDFileData + mfd1 = MEDFileData.New() + ms=MEDFileMeshes.New(); ms.setMeshAtPos(0,mm) + mfd1.setMeshes(ms) + # write + sw=SauvWriter.New() + sw.setMEDFileDS(mfd1) + sw.write(sauvFile) + # Check connectivity read from the sauv file + sr = SauvReader.New(sauvFile) + mfd2 = sr.loadInMEDFileDS() + mfMesh = mfd2.getMeshes()[0] + mesh = mfMesh.getMeshAtLevel(0) + self.assertTrue(mesh.getNodalConnectivity().isEqual(m.getNodalConnectivity())) + # + del sr + os.remove(sauvFile) + pass + + @unittest.skipUnless(MEDLoader.HasXDR(),"requires XDR") + def testMissingGroups(self): + """test for issue 0021749: [CEA 601] Some missing groups in mesh after reading a SAUV file with SauvReader.""" + self.assertTrue( os.getenv("MED_ROOT_DIR") ) + sauvFile = os.path.join( os.getenv("MED_ROOT_DIR"), "share","salome", + "resources","med","BDC-714.sauv") + self.assertTrue( os.access( sauvFile, os.F_OK)) + name_of_group_on_cells='Slice10:ABSORBER' + name_of_group_on_cells2='Slice10:00LR' + sr=SauvReader.New(sauvFile) + mfd2=sr.loadInMEDFileDS() + mfMesh=mfd2.getMeshes()[0] + # + self.assertTrue(name_of_group_on_cells in mfMesh.getGroupsNames()) + self.assertTrue(name_of_group_on_cells2 in mfMesh.getGroupsNames()) + self.assertEqual(270,len(mfMesh.getGroupsNames())) + # + ids1=mfMesh.getGroupArr(0,name_of_group_on_cells) + ids2=mfMesh.getGroupArr(0,name_of_group_on_cells2) + ids1.setName("") + ids2.setName("") + self.assertTrue(ids1.isEqual(ids2)) + pass + + def testGaussPt(self): + """issue 22321: [CEA 933] Bug when reading a sauve file containing field on Gauss Pt. + The problem was that a field ON_GAUSS_PT was created but no Gauss Localization + was defined""" + + # create a MEDFileData with a field ON_GAUSS_PT: 9 Gauss points, on 4 QUAD8 elements + f=MEDCouplingFieldDouble(ON_GAUSS_PT) + m=MEDCouplingUMesh("mesh",2) ; m.allocateCells() + m.insertNextCell(NORM_QUAD8,[0,2,4,6,1,3,5,7]) + m.insertNextCell(NORM_QUAD8,[2,9,11,4,8,10,12,3]) + m.insertNextCell(NORM_QUAD8,[6,4,14,16,5,13,15,17]) + m.insertNextCell(NORM_QUAD8,[4,11,19,14,12,18,20,13]) + m.setCoords(DataArrayDouble([(0,0),(0,0.25),(0,0.5),(0.25,0.5),(0.5,0.5),(0.5,0.25),(0.5,0),(0.25,0),(0,0.75),(0,1),(0.25,1),(0.5,1),(0.5,0.75),(0.75,0.5),(1,0.5),(1,0.25),(1,0),(0.75,0),(0.75,1),(1,1),(1,0.75)],21,2)) + f.setMesh(m) + arr=DataArrayDouble(4*9*2) ; arr.iota() ; arr.rearrange(2) ; arr.setInfoOnComponents(["YOUN []","NU []"]) + f.setArray(arr) + refCoo=[-1,-1,1,-1,1,1,-1,1,0,-1,1,0,0,1,-1,0] + gpCoo=[-0.7,-0.7,0.7,-0.7,0.7,0.7,-0.7,0.7,0,-0.7,0.7,0,0,0.7,-0.7,0,0,0] + wgt=[0.3,0.3,0.3,0.3,0.4,0.4,0.4,0.4,0.7] + f.setGaussLocalizationOnType(NORM_QUAD8,refCoo,gpCoo,wgt) + f.setName("SIGT") + f.checkCoherency() + # + mm=MEDFileUMesh() + mm.setMeshAtLevel(0,m) + mfm = MEDFileMeshes() + mfm.pushMesh( mm ) + ff=MEDFileField1TS() + ff.setFieldNoProfileSBT(f) + mfmts = MEDFileFieldMultiTS() + mfmts.pushBackTimeStep(ff) + mff = MEDFileFields() + mff.pushField( mfmts ) + mfd = MEDFileData.New() + mfd.setFields( mff ) + mfd.setMeshes( mfm ) + + # convert the MED file to a SAUV file + sauvFile = "SauvLoaderTest_testGaussPt.sauv" + sw=SauvWriter.New(); + sw.setMEDFileDS(mfd); + sw.write(sauvFile); + + # convert the SAUV file back to MED + sr=SauvReader.New(sauvFile); + d2=sr.loadInMEDFileDS(); + + self.assertEqual( 1, d2.getNumberOfFields() ) + self.assertEqual( 1, d2.getNumberOfMeshes() ) + mfm2 = d2.getMeshes()[0] + mff2 = d2.getFields()[0] + m2 = mfm2.getMeshAtLevel(0) + f2 = mff2.getTimeStepAtPos(0).getFieldOnMeshAtLevel(f.getTypeOfField(),0,mfm2) + f2.setGaussLocalizationOnType(NORM_QUAD8,refCoo,gpCoo,wgt) # not stored in SAUV + #f2.setOrder( f.getTime()[2] ) # not stored in SAUV + self.assertTrue( m2.isEqual( m, 1e-12 )) + self.assertTrue( f2.isEqual( f, 1e-12, 1e-12 )) + del sr + os.remove( sauvFile ) + pass + + def testSauvWriterGroupWithOneFamily(self): + """ + This test checks an option for sauv writing. It is requested here to copy a group from a family if a group is lying on a single family. + """ + import re + mfd=MEDLoaderDataForTest.buildAMEDFileDataWithGroupOnOneFamilyForSauv() + sauvFile = "mesh.sauv" + sw=SauvWriter.New() + sw.setMEDFileDS(mfd) + self.assertTrue(not sw.getCpyGrpIfOnASingleFamilyStatus()) + sw.setCpyGrpIfOnASingleFamilyStatus(True) + self.assertTrue(sw.getCpyGrpIfOnASingleFamilyStatus()) + sw.write(sauvFile) + + f = open(sauvFile) + # String pattern for the header of the sub meshes record ("PILE" number, number of named objects, number of objects) + pattern_pile= re.compile(r'\sPILE\sNUMERO\s+(?P<number>[0-9]+)NBRE\sOBJETS\sNOMMES\s+(?P<nbnamed>[0-9]+)NBRE\sOBJETS\s+(?P<nbobjects>[0-9]+)') + # String pattern for a sub mesh header (cell type, number of components and three numbers) + pattern_header=re.compile(r'\s+(?P<type>[0-9]+)\s+(?P<nbsubs>[0-9]+)\s+[0-9]+\s+[0-9]+\s+[0-9]+') + + nbobjects=0 + line = f.readline() + while(line): + match_pile = pattern_pile.match(line) + if match_pile: + number=int(match_pile.group("number")) + if number == 1: + nbnamed=int(match_pile.group("nbnamed")) + nbobjects=int(match_pile.group("nbobjects")) + break + pass + line=f.readline() + pass + + # Skipping the objects names + f.readline() + # Skipping the objects ids + f.readline() + + # Looking for each sub-mesh header + line = f.readline() + cur_object=0 + while(line and cur_object < nbobjects): + match_header=pattern_header.match(line) + if match_header: + cell_type=int(match_header.group("type")) + nb_subs=int(match_header.group("nbsubs")) + # Looking for a compound object + if cell_type == 0: + # Testing if there is only one component + self.assertTrue(nb_subs > 1) + else: + f.readline() + f.readline() + cur_object = cur_object + 1 + pass + pass + line=f.readline() + pass + f.close() + os.remove(sauvFile) + pass + + pass + +unittest.main() diff --git a/src/medtool/src/MEDLoader/Swig/VTKReader.py b/src/medtool/src/MEDLoader/Swig/VTKReader.py new file mode 100644 index 000000000..b54174459 --- /dev/null +++ b/src/medtool/src/MEDLoader/Swig/VTKReader.py @@ -0,0 +1,306 @@ +# -*- coding: iso-8859-1 -*- +# Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 +# 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/DM2S/STMF) + +from MEDLoader import * + +class PVDReader: + @classmethod + def New(cls,fileName): + """ Static constructor. """ + return PVDReader(fileName) + pass + + def __init__(self,fileName): + self._fileName=fileName + pass + + def loadTopInfo(self): + fd=open(self._fileName,"r") + return self.__parseXML(fd) + + def __parseXML(self,fd): + import xml.sax + class PVD_SAX_Reader(xml.sax.ContentHandler): + def __init__(self): + self._tsteps=[] + pass + def startElement(self,name,attrs): + if name=="VTKFile": + if attrs["type"]!="Collection": + raise Exception("Mismatch between reader (PVD) type and file content !") + return + if name=="DataSet": + self._tsteps.append((float(attrs["timestep"]),str(attrs["file"]))) + return + pass + pass + rd=PVD_SAX_Reader() + parser=xml.sax.make_parser() + parser.setContentHandler(rd) + parser.parse(fd) + return rd + pass + +class PVTUReader: + @classmethod + def New(cls,fileName): + """ Static constructor. """ + return PVTUReader(fileName) + pass + + def __init__(self,fileName): + self._fileName=fileName + pass + + def loadParaInfo(self): + fd=open(self._fileName,"r") + return self.__parseXML(fd) + + def __parseXML(self,fd): + import xml.sax + class PVTU_SAX_Reader(xml.sax.ContentHandler): + def __init__(self): + self._data_array={2:self.DAPointData,3:self.DACellData} + self._node_fields=[] + self._cell_fields=[] + self._pfiles=[] + self._tmp=None + pass + def DAPointData(self,attrs): + self._node_fields.append((str(attrs["Name"]),int(attrs["NumberOfComponents"]))) + pass + def DACellData(self,attrs): + self._cell_fields.append((str(attrs["Name"]),int(attrs["NumberOfComponents"]))) + pass + def startElement(self,name,attrs): + if name=="VTKFile": + if attrs["type"]!="PUnstructuredGrid": + raise Exception("Mismatch between reader (PVTU) type and file content !") + return + if name=="Piece": + self._pfiles.append(str(attrs["Source"])) + return + if name=="PPointData": + self._tmp=2 + return + if name=="PCellData": + self._tmp=3 + return + if name=="PDataArray": + if self._tmp in self._data_array.keys(): + self._data_array[self._tmp](attrs) + pass + return + pass + pass + rd=PVTU_SAX_Reader() + parser=xml.sax.make_parser() + parser.setContentHandler(rd) + parser.parse(fd) + return rd + pass + +class VTURawReader: + """ Converting a VTU file in raw mode into the MED format. + """ + VTKTypes_2_MC=[-1,0,-1,1,33,3,-1,5,-1,4,14,-1,NORM_HEXA8,16,15,-1,22,-1,-1,-1,-1,2,6,8,20,30,25,23,9,27,-1,-1,-1,-1,7,-1,-1,-1,-1,-1,-1,-1,31] + + class NormalException(Exception): + def __init__(self,lineNb): + Exception.__init__(self) + self._line_nb=lineNb + def getLineNb(self): + return self._line_nb + pass + + class NotRawVTUException(Exception): + pass + + def loadInMEDFileDS(self): + import numpy as np + fd=open(self._fileName,"r") + ref,rd=self.__parseXML(fd) + # + ret=MEDFileData() + ms=MEDFileMeshes() ; ret.setMeshes(ms) + fs=MEDFileFields() ; ret.setFields(fs) + # + types=np.memmap(fd,dtype=rd._type_types,mode='r',offset=ref+rd._off_types,shape=(rd._nb_cells,)) + types=self.__swapIfNecessary(rd._bo,types) + # mesh dimension detection + types2=types.copy() ; types2.sort() ; types2=np.unique(types2) + meshDim=MEDCouplingMesh.GetDimensionOfGeometricType(self.VTKTypes_2_MC[types2[0]]) + for typ in types2[1:]: + md=MEDCouplingMesh.GetDimensionOfGeometricType(self.VTKTypes_2_MC[typ]) + if md!=meshDim: + raise Exception("MultiLevel umeshes not managed yet !") + pass + m=MEDCouplingUMesh("mesh",meshDim) + # coordinates + coo=np.memmap(fd,dtype=rd._type_coords,mode='r',offset=ref+rd._off_coords,shape=(rd._nb_nodes*rd._space_dim,)) + coo=self.__swapIfNecessary(rd._bo,coo) ; coo=DataArrayDouble(np.array(coo,dtype='float64')) ; coo.rearrange(rd._space_dim) + m.setCoords(coo) + # connectivity + offsets=np.memmap(fd,dtype=rd._type_off,mode='r',offset=ref+rd._off_off,shape=(rd._nb_cells,)) + offsets=self.__swapIfNecessary(rd._bo,offsets) ; connLgth=offsets[-1] ; offsets2=DataArrayInt(rd._nb_cells+1) ; offsets2.setIJ(0,0,0) + offsets2[1:]=DataArrayInt(offsets) + offsets3=offsets2.deltaShiftIndex() ; offsets2=offsets3.deepCpy() ; offsets3+=1 ; offsets3.computeOffsets2() + offsets=offsets3 + tmp1=DataArrayInt(len(offsets2),2) ; tmp1[:,0]=1 ; tmp1[:,1]=offsets2 ; tmp1.rearrange(1) ; tmp1.computeOffsets2() + tmp1=DataArrayInt.Range(1,2*len(offsets2),2).buildExplicitArrByRanges(tmp1) + conn=np.memmap(fd,dtype=rd._type_conn,mode='r',offset=ref+rd._off_conn,shape=(connLgth,)) + conn=self.__swapIfNecessary(rd._bo,conn) + types=np.array(types,dtype='int32') ; types=DataArrayInt(types) ; types.transformWithIndArr(self.VTKTypes_2_MC) + conn2=DataArrayInt(offsets.back()) + conn2[offsets[0:-1]]=types + conn2[tmp1]=DataArrayInt(conn) + m.setConnectivity(conn2,offsets,True) + m.checkCoherency() ; mm=MEDFileUMesh() ; mm.setMeshAtLevel(0,m) ; ms.pushMesh(mm) + # Fields on nodes and on cells + for spatialDisc,nbEnt,fields in [(ON_NODES,rd._nb_nodes,rd._node_fields),(ON_CELLS,rd._nb_cells,rd._cell_fields)]: + for name,typ,nbCompo,off in fields: + ff=MEDFileFieldMultiTS() + f=MEDCouplingFieldDouble(spatialDisc,ONE_TIME) + f.setName(name) ; f.setMesh(m) + vals=np.memmap(fd,dtype=typ,mode='r',offset=ref+off,shape=(nbEnt*nbCompo)) + vals=self.__swapIfNecessary(rd._bo,vals) + arr=DataArrayDouble(np.array(vals,dtype='float64')) ; arr.rearrange(nbCompo) + f.setArray(arr) ; f.checkCoherency() + f.setTime(self._time[0],self._time[1],0) + ff.appendFieldNoProfileSBT(f) + fs.pushField(ff) + pass + pass + return ret + + def __parseXML(self,fd): + import xml.sax + class VTU_SAX_Reader(xml.sax.ContentHandler): + def __init__(self): + self._loc=None + self._data_array={0:self.DAPoints,1:self.DACells,2:self.DAPointData,3:self.DACellData} + self._node_fields=[] + self._cell_fields=[] + pass + def setLocator(self,loc): + self._loc=loc + def DAPoints(self,attrs): + self._space_dim=int(attrs["NumberOfComponents"]) + self._type_coords=str(attrs["type"]).lower() + self._off_coords=int(attrs["offset"]) + pass + def DACells(self,attrs): + if attrs["Name"]=="connectivity": + self._type_conn=str(attrs["type"]).lower() + self._off_conn=int(attrs["offset"]) + pass + if attrs["Name"]=="offsets": + self._type_off=str(attrs["type"]).lower() + self._off_off=int(attrs["offset"]) + pass + if attrs["Name"]=="types": + self._type_types=str(attrs["type"]).lower() + self._off_types=int(attrs["offset"]) + pass + pass + def DAPointData(self,attrs): + self._node_fields.append((str(attrs["Name"]),str(attrs["type"]).lower(),int(attrs["NumberOfComponents"]),int(attrs["offset"]))) + pass + def DACellData(self,attrs): + self._cell_fields.append((str(attrs["Name"]),str(attrs["type"]).lower(),int(attrs["NumberOfComponents"]),int(attrs["offset"]))) + pass + def startElement(self,name,attrs): + if name=="VTKFile": + if attrs["type"]!="UnstructuredGrid": + raise Exception("Mismatch between reader (VTU) type and file content !") + self._bo=bool(["LittleEndian","BigEndian"].index(attrs["byte_order"])) + pass + if name=="Piece": + self._nb_cells=int(attrs["NumberOfCells"]) + self._nb_nodes=int(attrs["NumberOfPoints"]) + return + if name=="Points": + self._tmp=0 + return + if name=="Cells": + self._tmp=1 + return + if name=="PointData": + self._tmp=2 + return + if name=="CellData": + self._tmp=3 + return + if name=="DataArray": + self._data_array[self._tmp](attrs) + return + if name=="AppendedData": + if str(attrs["encoding"])=="raw": + raise VTURawReader.NormalException(self._loc.getLineNumber()) + else: + raise VTURawReader.NotRawVTUException("The file is not a raw VTU ! Change reader !") + pass + pass + rd=VTU_SAX_Reader() + parser=xml.sax.make_parser() + parser.setContentHandler(rd) + locator=xml.sax.expatreader.ExpatLocator(parser) + rd.setLocator(locator) + isOK=False + try: + parser.parse(fd) + except self.NormalException as e: + isOK=True + fd.seek(0) + for i in xrange(e.getLineNb()): fd.readline() + ref=fd.tell()+5 + pass + if not isOK: + raise Exception("Error in VTURawReader : not a raw format ?") + return ref,rd + + @classmethod + def New(cls,fileName,tim=(0.,0)): + """ Static constructor. """ + return VTURawReader(fileName,tim) + pass + + def __init__(self,fileName,tim=(0.,0)): + msg="The time specified in constructor as 2nd arg should be a tuple containing 2 values 1 float and 1 int !" + if type(tim)!=tuple: + raise Exception(msg) + if len(tim)!=2: + raise Exception(msg) + if type(tim[0])!=float or type(tim[1])!=int: + raise Exception(msg) + self._fileName=fileName + self._time=tim + pass + + def __swapIfNecessary(self,b,arr): + if b: + ret=arr.copy() + ret.byteswap(True) + return ret + else: + return arr + pass + pass diff --git a/src/medtool/src/MEDLoader/Swig/case2med b/src/medtool/src/MEDLoader/Swig/case2med new file mode 100755 index 000000000..ef2e15286 --- /dev/null +++ b/src/medtool/src/MEDLoader/Swig/case2med @@ -0,0 +1,54 @@ +#!/usr/bin/env python +# -*- coding: iso-8859-1 -*- +# Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 +# 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 +# + +from CaseReader import CaseReader +from optparse import OptionParser +import os + +parser = OptionParser() +parser.set_usage("Convert a Case file to a MED file.\n %prog [options] case_file") +parser.add_option("-c", "--currentdir", action="store_true", dest="here", default=False, + help="Are generated MED file generated in current directory. By default not, MED file is generated in directory containing the input file (default False)") +(opts, args) = parser.parse_args() + +if len(args) != 1: + parser.print_usage() + exit(1) + pass + +fname=args[0] #"cas_test_simple.case" +if opts.here: + fOut=os.path.splitext(os.path.basename(fname))[0]+".med" + pass +else: + fOut=os.path.splitext(fname)[0]+".med" + pass +### +cr=CaseReader(fname) +try: + medfd=cr.loadInMEDFileDS() +except: + print "An error occured during the conversion!" + print "#######################################" + raise +medfd.write(fOut,2) +print "#########\nFile \"%s\" written !\n#########"%(fOut) + diff --git a/src/medtool/src/MEDLoader/Swig/med2case b/src/medtool/src/MEDLoader/Swig/med2case new file mode 100755 index 000000000..bec9f4f30 --- /dev/null +++ b/src/medtool/src/MEDLoader/Swig/med2case @@ -0,0 +1,63 @@ +#!/usr/bin/env python +# -*- coding: iso-8859-1 -*- +# Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 +# 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/DM2S/STMF/LGLS) + +from MEDLoader import MEDFileData,InterpKernelException +from CaseWriter import CaseWriter +from optparse import OptionParser +import os + +parser = OptionParser() +parser.set_usage("Convert a MED file to a Case file.\n %prog [options] med_file") +parser.add_option("-g", "--groups", action="store_true", dest="groups", default=False, + help="Are groups in meshes stored in MEDFile exported in output case as subparts (default False)") +parser.add_option("-c", "--currentdir", action="store_true", dest="here", default=False, + help="Are generated case,geo files generated in current directory. By default not, files are generated in directory containing the input file (default False)") +(opts, args) = parser.parse_args() + +if len(args) != 1: + parser.print_usage() + exit(1) + pass + +fname=os.path.abspath(args[0]) #"cas_test_simple.case" +if opts.here: + fOut=os.path.splitext(os.path.basename(fname))[0]+".case" + pass +else: + fOut=os.path.splitext(fname)[0]+".case" + pass +### +try: + cw=CaseWriter.New() + cw.setExportingGroups(opts.groups) + mfd=MEDFileData(fname) + cw.setMEDFileDS(mfd) + listOfWrittenFileNames=cw.write(fOut) +except InterpKernelException as e: + print "An error occurred during the conversion!" + print "#######################################" + raise e +print "#########" +for l in listOfWrittenFileNames: + print "File \"%s\" successfully written !"%(l) + pass +print "#########" diff --git a/src/medtool/src/MEDLoader/Swig/med2sauv b/src/medtool/src/MEDLoader/Swig/med2sauv new file mode 100755 index 000000000..8ba498033 --- /dev/null +++ b/src/medtool/src/MEDLoader/Swig/med2sauv @@ -0,0 +1,35 @@ +#!/usr/bin/env python +# -- +# Copyright (C) 2009-2015 CEA/DEN, EDF 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, 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 +# 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 : Erwan ADAM (CEA) +# -- + +from sys import argv,path +from os.path import dirname,abspath,sep +from medutilities import med2sauv + +d = argv[0] +d = dirname(d) +d = abspath(d+sep+".."+sep+"lib") +if d not in path: + path.insert(0,d) + pass + +med2sauv(*argv[1:]) diff --git a/src/medtool/src/MEDLoader/Swig/medutilities.py b/src/medtool/src/MEDLoader/Swig/medutilities.py new file mode 100644 index 000000000..64c541868 --- /dev/null +++ b/src/medtool/src/MEDLoader/Swig/medutilities.py @@ -0,0 +1,141 @@ +# -*- coding: iso-8859-1 -*- +# -- +# Copyright (C) 2009-2015 CEA/DEN, EDF 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, 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 +# 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 : Erwan ADAM (CEA), Anthony GEAY (CEA) +# -- + +from MEDLoader import * + +def my_remove(f): + from os import remove + try: + remove(f) + except OSError: + pass + return + +def convert(file_in, driver_in, driver_out, format=1, file_out=None): + # + print file_in + # + if file_out is None: + file_out = file_in + if driver_out == "GIBI": + file_out += ".sauv" + elif driver_out == "MED": + file_out += ".med" + else: + msg = "Driver out %s is unknown"%(driver_out) + raise NotImplementedError(msg) + pass + print file_out + # + if driver_in == "GIBI": + sr = SauvReader.New(file_in) + mfd= sr.loadInMEDFileDS() + pass + elif driver_in == "MED": + mfd = MEDFileData(file_in) + pass + else: + raise NotImplementedError("Driver in %s is unknown"%(driver_in)) + # + my_remove(file_out) + # + if driver_out == "GIBI": + sw=SauvWriter.New() + sw.setMEDFileDS(mfd,0);#0 ? + sw.write(file_out) + # + mesh = mfd.getMeshes()[0] + mesh_dim = mesh.getSpaceDimension() + if mesh_dim >= 3: + from sys import platform + if platform in ["win32"]: + f = open(file_out) + content = f.read() + f.close() + content = content.replace("IFOUR -1", "IFOUR 2") + content = content.replace("IFOMOD -1", "IFOMOD 2") + f = open(file_out, "w") + f.write(content) + f.close() + else: + cmd = "sed" + cmd += ' -e "s/IFOUR -1/IFOUR 2/g"' + cmd += ' -e "s/IFOMOD -1/IFOMOD 2/g"' + # cmd += ' -e "s/IECHO 1/IECHO 0/g"' + cmd += ' %s > .dummy'%(file_out) + cmd += ' && ' + cmd += ' mv -f .dummy %s'%(file_out) + from os import system + system(cmd) + pass + pass + # + if format == 0: + from castemlauncher import CastemLauncher + dgibi_stream = "\n" + dgibi_stream += "OPTI REST FORMAT '%s' ;\n"%(file_out) + dgibi_stream += "REST FORMAT;\n" + file_out = file_out.replace('__format__', '') + dgibi_stream += "OPTI SAUV '%s' ;\n"%(file_out) + dgibi_stream += "SAUV ;\n" + cl = CastemLauncher(dgibi_stream) + cl.addTmpFiles(file_out+'__format__', "UTILNOTI", "UTILPROC") + cl.run() + pass + return + elif driver_out == "MED": + mfd.write(file_out,2) + return + else: + raise NotImplementedError("Driver in %s is unknown"%(driver_in)) + +def sauv2med(*argv): + argv = list(argv) + for arg in argv: + convert(arg, "GIBI", "MED") + pass + return + +def med2sauv(*argv): + argv = list(argv) + format = 1 + for arg in argv[:]: + if arg.find('--format') == 0: + argv.remove(arg) + try: + value = arg.split("=")[1] + except IndexError: + usage(1) + pass + try: + value = int(value) + except ValueError: + usage(1) + pass + format = value + pass + pass + for arg in argv: + convert(arg, "MED", "GIBI", format) + pass + return diff --git a/src/medtool/src/MEDLoader/Swig/sauv2med b/src/medtool/src/MEDLoader/Swig/sauv2med new file mode 100755 index 000000000..d4f9cf693 --- /dev/null +++ b/src/medtool/src/MEDLoader/Swig/sauv2med @@ -0,0 +1,35 @@ +#!/usr/bin/env python +# -- +# Copyright (C) 2009-2015 CEA/DEN, EDF 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, 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 +# 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 : Erwan ADAM (CEA) +# -- + +from sys import argv,path +from os.path import dirname,abspath,sep +from medutilities import sauv2med + +d = argv[0] +d = dirname(d) +d = abspath(d+sep+".."+sep+"lib") +if d not in path: + path.insert(0,d) + pass + +sauv2med(*argv[1:]) diff --git a/src/medtool/src/MEDLoader/Test/CMakeLists.txt b/src/medtool/src/MEDLoader/Test/CMakeLists.txt new file mode 100644 index 000000000..96d121401 --- /dev/null +++ b/src/medtool/src/MEDLoader/Test/CMakeLists.txt @@ -0,0 +1,64 @@ +# Copyright (C) 2012-2015 CEA/DEN, EDF 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, 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 +# 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_DIRECTORIES( + ${CPPUNIT_INCLUDE_DIRS} + ${HDF5_INCLUDE_DIRS} + ${MEDFILE_INCLUDE_DIRS} + ${CMAKE_CURRENT_SOURCE_DIR}/.. + ${CMAKE_CURRENT_SOURCE_DIR}/../../MEDCoupling + ${CMAKE_CURRENT_SOURCE_DIR}/../../INTERP_KERNEL + ${CMAKE_CURRENT_SOURCE_DIR}/../../INTERP_KERNEL/Bases + ${CMAKE_CURRENT_SOURCE_DIR}/../../INTERP_KERNELTest # For common CppUnitTest.hxx file + ) + +SET(TestMEDLoader_SOURCES + TestMEDLoader.cxx + MEDLoaderTest.cxx + ) + +SET(TestSauvLoader_SOURCES + TestSauvLoader.cxx + SauvLoaderTest.cxx + ) + +#SALOME_GENERATE_TESTS_ENVIRONMENT(tests_env) + +ADD_EXECUTABLE(TestMEDLoader ${TestMEDLoader_SOURCES}) +TARGET_LINK_LIBRARIES(TestMEDLoader medloader ${CPPUNIT_LIBRARIES} ${PLATFORM_LIBS}) +ADD_TEST(TestMEDLoader TestMEDLoader) +SET_TESTS_PROPERTIES(TestMEDLoader PROPERTIES ENVIRONMENT "${tests_env}") + +ADD_EXECUTABLE(TestSauvLoader ${TestSauvLoader_SOURCES}) + +TARGET_LINK_LIBRARIES(TestSauvLoader medloader ${CPPUNIT_LIBRARIES} ${PLATFORM_LIBS}) +ADD_TEST(TestSauvLoader TestSauvLoader) +SET_TESTS_PROPERTIES(TestSauvLoader PROPERTIES ENVIRONMENT "${tests_env}") + +INSTALL(TARGETS TestMEDLoader TestSauvLoader DESTINATION ${MEDTOOL_INSTALL_BINS}) + +# Application tests + +SET(TEST_INSTALL_DIRECTORY ${MEDTOOL_INSTALL_SCRIPT_SCRIPTS}/test/MEDCoupling/MEDLoader) +INSTALL(TARGETS TestMEDLoader TestSauvLoader DESTINATION ${TEST_INSTALL_DIRECTORY}) + +INSTALL(FILES CTestTestfileInstall.cmake + DESTINATION ${TEST_INSTALL_DIRECTORY} + RENAME CTestTestfile.cmake) diff --git a/src/medtool/src/MEDLoader/Test/CTestTestfileInstall.cmake b/src/medtool/src/MEDLoader/Test/CTestTestfileInstall.cmake new file mode 100644 index 000000000..4cf399650 --- /dev/null +++ b/src/medtool/src/MEDLoader/Test/CTestTestfileInstall.cmake @@ -0,0 +1,24 @@ +# Copyright (C) 2015 CEA/DEN, EDF 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, 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 +# 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_TEST(TestMEDLoader TestMEDLoader) +SET_TESTS_PROPERTIES(TestMEDLoader PROPERTIES LABELS "${COMPONENT_NAME}") + +ADD_TEST(TestSauvLoader TestSauvLoader) +SET_TESTS_PROPERTIES(TestSauvLoader PROPERTIES LABELS "${COMPONENT_NAME}") diff --git a/src/medtool/src/MEDLoader/Test/MEDLoaderTest.cxx b/src/medtool/src/MEDLoader/Test/MEDLoaderTest.cxx new file mode 100644 index 000000000..b6267238f --- /dev/null +++ b/src/medtool/src/MEDLoader/Test/MEDLoaderTest.cxx @@ -0,0 +1,1097 @@ +// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 +// 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 "MEDLoaderTest.hxx" +#include "MEDLoader.hxx" +#include "MEDLoaderBase.hxx" +#include "MEDCouplingUMesh.hxx" +#include "MEDCouplingFieldDouble.hxx" +#include "MEDCouplingMemArray.hxx" + +#include <cmath> + +using namespace ParaMEDMEM; + +void MEDLoaderTest::testMesh1DRW() +{ + MEDCouplingUMesh *mesh=build1DMesh_1(); + mesh->checkCoherency(); + MEDLoader::WriteUMesh("file1.med",mesh,true); + MEDCouplingUMesh *mesh_rw=MEDLoader::ReadUMeshFromFile("file1.med",mesh->getName().c_str(),0); + CPPUNIT_ASSERT(mesh->isEqual(mesh_rw,1e-12)); + mesh_rw->decrRef(); + mesh->decrRef(); +} + +void MEDLoaderTest::testMesh2DCurveRW() +{ + MEDCouplingUMesh *mesh=build2DCurveMesh_1(); + mesh->checkCoherency(); + MEDLoader::WriteUMesh("file2.med",mesh,true); + MEDCouplingUMesh *mesh_rw=MEDLoader::ReadUMeshFromFile("file2.med",mesh->getName().c_str(),0); + CPPUNIT_ASSERT(mesh->isEqual(mesh_rw,1e-12)); + mesh_rw->decrRef(); + mesh->decrRef(); +} + +void MEDLoaderTest::testMesh2DRW() +{ + MEDCouplingUMesh *mesh=build2DMesh_1(); + mesh->checkCoherency(); + MEDLoader::WriteUMesh("file3.med",mesh,true); + MEDCouplingUMesh *mesh_rw=MEDLoader::ReadUMeshFromFile("file3.med",mesh->getName().c_str(),0); + CPPUNIT_ASSERT(mesh->isEqual(mesh_rw,1e-12)); + mesh_rw->decrRef(); + mesh->decrRef(); +} + +void MEDLoaderTest::testMesh3DSurfRW() +{ + MEDCouplingUMesh *mesh=build3DSurfMesh_1(); + mesh->checkCoherency(); + MEDLoader::WriteUMesh("file4.med",mesh,true); + MEDCouplingUMesh *mesh_rw=MEDLoader::ReadUMeshFromFile("file4.med",mesh->getName().c_str(),0); + CPPUNIT_ASSERT(mesh->isEqual(mesh_rw,1e-12)); + mesh_rw->decrRef(); + mesh->decrRef(); +} + +void MEDLoaderTest::testMesh3DRW() +{ + MEDCouplingUMesh *mesh=build3DMesh_1(); + mesh->checkCoherency(); + MEDLoader::WriteUMesh("file5.med",mesh,true); + MEDCouplingUMesh *mesh_rw=MEDLoader::ReadUMeshFromFile("file5.med",mesh->getName().c_str(),0); + CPPUNIT_ASSERT(mesh->isEqual(mesh_rw,1e-12)); + mesh_rw->decrRef(); + mesh->decrRef(); +} + +/*! + * Most basic test : one and only one MEDCoupling field in a new file. + */ +void MEDLoaderTest::testFieldRW1() +{ + MEDCouplingFieldDouble *f1=buildVecFieldOnCells_1(); + MEDLoader::WriteField("file6.med",f1,true); + MEDCouplingFieldDouble *f2=MEDLoader::ReadFieldCell("file6.med",f1->getMesh()->getName().c_str(),0,f1->getName().c_str(),0,1); + CPPUNIT_ASSERT(f1->isEqual(f2,1e-12,1e-12)); + f1->decrRef(); + f2->decrRef(); + // + f1=buildVecFieldOnNodes_1(); + MEDLoader::WriteField("file7.med",f1,true); + f2=MEDLoader::ReadFieldNode("file7.med",f1->getMesh()->getName().c_str(),0,f1->getName().c_str(),2,3); + CPPUNIT_ASSERT(f1->isEqual(f2,1e-12,1e-12)); + // testing kind message on error of field type. + CPPUNIT_ASSERT_THROW(MEDLoader::ReadFieldCell("file7.med",f1->getMesh()->getName().c_str(),0,f1->getName().c_str(),2,3),INTERP_KERNEL::Exception); + // + f1->decrRef(); + f2->decrRef(); +} + +/*! + * Multi field writing in a same file. + */ +void MEDLoaderTest::testFieldRW2() +{ + const char fileName[]="file8.med"; + static const double VAL1=12345.67890314; + static const double VAL2=-1111111111111.; + MEDCouplingFieldDouble *f1=buildVecFieldOnCells_1(); + MEDLoader::WriteField(fileName,f1,true); + f1->setTime(10.,8,9); + double *tmp=f1->getArray()->getPointer(); + tmp[0]=VAL1; + MEDLoader::WriteFieldUsingAlreadyWrittenMesh(fileName,f1); + f1->setTime(10.14,18,19); + tmp[0]=VAL2; + MEDLoader::WriteFieldUsingAlreadyWrittenMesh(fileName,f1); + //retrieving time steps... + MEDCouplingFieldDouble *f2=MEDLoader::ReadFieldCell(fileName,f1->getMesh()->getName().c_str(),0,f1->getName().c_str(),8,9); + f1->setTime(10.,8,9); + tmp[0]=VAL1; + CPPUNIT_ASSERT(f1->isEqual(f2,1e-12,1e-12)); + f2->decrRef(); + f2=MEDLoader::ReadFieldCell(fileName,f1->getMesh()->getName().c_str(),0,f1->getName().c_str(),0,1); + MEDCouplingFieldDouble *f3=buildVecFieldOnCells_1(); + CPPUNIT_ASSERT(f3->isEqual(f2,1e-12,1e-12)); + f3->decrRef(); + f2->decrRef(); + f2=MEDLoader::ReadFieldCell(fileName,f1->getMesh()->getName().c_str(),0,f1->getName().c_str(),18,19); + f1->setTime(10.14,18,19); + tmp[0]=VAL2; + CPPUNIT_ASSERT(f1->isEqual(f2,1e-12,1e-12)); + //test of throw on invalid (dt,it) + CPPUNIT_ASSERT_THROW(MEDLoader::ReadFieldCell(fileName,f1->getMesh()->getName().c_str(),0,f1->getName().c_str(),28,19),INTERP_KERNEL::Exception); + f2->decrRef(); + f1->decrRef(); + //ON NODES + f1=buildVecFieldOnNodes_1(); + const char fileName2[]="file9.med"; + MEDLoader::WriteField(fileName2,f1,true); + f1->setTime(110.,108,109); + tmp=f1->getArray()->getPointer(); + tmp[3]=VAL1; + MEDLoader::WriteFieldUsingAlreadyWrittenMesh(fileName2,f1); + f1->setTime(210.,208,209); + tmp[3]=VAL2; + MEDLoader::WriteFieldUsingAlreadyWrittenMesh(fileName2,f1); + f2=MEDLoader::ReadFieldNode(fileName2,f1->getMesh()->getName().c_str(),0,f1->getName().c_str(),108,109); + f1->setTime(110.,108,109); + tmp[3]=VAL1; + CPPUNIT_ASSERT(f1->isEqual(f2,1e-12,1e-12)); + f2->decrRef(); + f2=MEDLoader::ReadFieldNode(fileName2,f1->getMesh()->getName().c_str(),0,f1->getName().c_str(),2,3); + f3=buildVecFieldOnNodes_1(); + CPPUNIT_ASSERT(f3->isEqual(f2,1e-12,1e-12)); + f3->decrRef(); + f2->decrRef(); + f2=MEDLoader::ReadFieldNode(fileName2,f1->getMesh()->getName().c_str(),0,f1->getName().c_str(),208,209); + f1->setTime(210.,208,209); + tmp[3]=VAL2; + CPPUNIT_ASSERT(f1->isEqual(f2,1e-12,1e-12)); + f2->decrRef(); + f1->decrRef(); +} + +/*! + * Multi field in a same file, but this field has several + */ +void MEDLoaderTest::testFieldRW3() +{ + const char fileName[]="file11.med"; + static const double VAL1=12345.67890314; + static const double VAL2=-1111111111111.; + const char name1[]="AField"; + const char name3[]="AMesh1"; + MEDCouplingFieldDouble *f1=buildVecFieldOnCells_1(); + (const_cast<MEDCouplingMesh *>(f1->getMesh()))->setName(name3); + f1->setName(name1); + f1->setTime(10.,8,9); + double *tmp=f1->getArray()->getPointer(); + tmp[0]=VAL1; + MEDLoader::WriteField(fileName,f1,true); + f1->setTime(10.14,18,19); + tmp[0]=VAL2; + MEDLoader::WriteFieldUsingAlreadyWrittenMesh(fileName,f1); + f1->setTime(10.55,28,29); + tmp[0]=3*VAL1; + MEDLoader::WriteFieldUsingAlreadyWrittenMesh(fileName,f1); + f1->setTime(10.66,38,39); + tmp[0]=3*VAL2; + MEDLoader::WriteFieldUsingAlreadyWrittenMesh(fileName,f1); + f1->setTime(10.77,48,49); + tmp[0]=4*VAL2; + MEDLoader::WriteFieldUsingAlreadyWrittenMesh(fileName,f1); + //ON NODES + f1->decrRef(); + f1=buildVecFieldOnNodes_1(); + f1->setName(name1); + (const_cast<MEDCouplingMesh *>(f1->getMesh()))->setName(name3); + f1->setTime(110.,8,9); + MEDLoader::WriteFieldUsingAlreadyWrittenMesh(fileName,f1); + f1->setTime(110.,108,109); + tmp=f1->getArray()->getPointer(); + tmp[3]=VAL1; + MEDLoader::WriteFieldUsingAlreadyWrittenMesh(fileName,f1); + f1->setTime(210.,208,209); + tmp[3]=VAL2; + MEDLoader::WriteFieldUsingAlreadyWrittenMesh(fileName,f1); + // + std::vector< std::pair<int,int> > it1=MEDLoader::GetCellFieldIterations(fileName,name3,name1); + CPPUNIT_ASSERT_EQUAL(5,(int)it1.size()); + CPPUNIT_ASSERT_EQUAL(8,it1[0].first); CPPUNIT_ASSERT_EQUAL(9,it1[0].second); + CPPUNIT_ASSERT_EQUAL(18,it1[1].first); CPPUNIT_ASSERT_EQUAL(19,it1[1].second); + CPPUNIT_ASSERT_EQUAL(28,it1[2].first); CPPUNIT_ASSERT_EQUAL(29,it1[2].second); + CPPUNIT_ASSERT_EQUAL(38,it1[3].first); CPPUNIT_ASSERT_EQUAL(39,it1[3].second); + CPPUNIT_ASSERT_EQUAL(48,it1[4].first); CPPUNIT_ASSERT_EQUAL(49,it1[4].second); + std::vector< std::pair<int,int> > it3=MEDLoader::GetNodeFieldIterations(fileName,name3,name1); + CPPUNIT_ASSERT_EQUAL(3,(int)it3.size()); + CPPUNIT_ASSERT_EQUAL(8,it3[0].first); CPPUNIT_ASSERT_EQUAL(9,it3[0].second); + CPPUNIT_ASSERT_EQUAL(108,it3[1].first); CPPUNIT_ASSERT_EQUAL(109,it3[1].second); + CPPUNIT_ASSERT_EQUAL(208,it3[2].first); CPPUNIT_ASSERT_EQUAL(209,it3[2].second); + // + f1->decrRef(); + // + f1=MEDLoader::ReadFieldCell(fileName,name3,0,name1,8,9); + CPPUNIT_ASSERT_DOUBLES_EQUAL(VAL1,f1->getArray()->getConstPointer()[0],1e-13); + f1->decrRef(); + f1=MEDLoader::ReadFieldCell(fileName,name3,0,name1,18,19); + CPPUNIT_ASSERT_DOUBLES_EQUAL(VAL2,f1->getArray()->getConstPointer()[0],1e-13); + f1->decrRef(); + f1=MEDLoader::ReadFieldCell(fileName,name3,0,name1,28,29); + CPPUNIT_ASSERT_DOUBLES_EQUAL(3*VAL1,f1->getArray()->getConstPointer()[0],1e-13); + f1->decrRef(); + f1=MEDLoader::ReadFieldCell(fileName,name3,0,name1,38,39); + CPPUNIT_ASSERT_DOUBLES_EQUAL(3*VAL2,f1->getArray()->getConstPointer()[0],1e-13); + f1->decrRef(); + f1=MEDLoader::ReadFieldCell(fileName,name3,0,name1,48,49); + CPPUNIT_ASSERT_DOUBLES_EQUAL(4*VAL2,f1->getArray()->getConstPointer()[0],1e-13); + f1->decrRef(); + // + f1=MEDLoader::ReadFieldNode(fileName,name3,0,name1,8,9); + CPPUNIT_ASSERT_DOUBLES_EQUAL(71.,f1->getArray()->getConstPointer()[3],1e-13); + f1->decrRef(); + f1=MEDLoader::ReadFieldNode(fileName,name3,0,name1,108,109); + CPPUNIT_ASSERT_DOUBLES_EQUAL(VAL1,f1->getArray()->getConstPointer()[3],1e-13); + f1->decrRef(); + f1=MEDLoader::ReadFieldNode(fileName,name3,0,name1,208,209); + CPPUNIT_ASSERT_DOUBLES_EQUAL(VAL2,f1->getArray()->getConstPointer()[3],1e-13); + f1->decrRef(); +} + +void MEDLoaderTest::testMultiMeshRW1() +{ + const char fileName[]="file10.med"; + MEDCouplingUMesh *mesh1=build3DMesh_1(); + const int part1[5]={1,2,4,13,15}; + MEDCouplingUMesh *mesh2=(MEDCouplingUMesh *)mesh1->buildPartOfMySelf(part1,part1+5,true); + mesh2->setName("mesh2"); + const int part2[4]={3,4,13,14}; + MEDCouplingUMesh *mesh3=(MEDCouplingUMesh *)mesh1->buildPartOfMySelf(part2,part2+4,true); + mesh3->setName("mesh3"); + MEDCouplingUMesh *mesh4=MEDCouplingUMesh::New(); + mesh4->setName("mesh4"); + mesh4->setMeshDimension(3); + mesh4->allocateCells(1); + int conn[4]={0,11,1,3}; + mesh4->insertNextCell(INTERP_KERNEL::NORM_TETRA4,4,conn); + mesh4->finishInsertingCells(); + mesh4->setCoords(mesh1->getCoords()); + std::vector<const MEDCouplingUMesh *> meshes; + meshes.push_back(mesh1); + meshes.push_back(mesh2); + meshes.push_back(mesh3); + meshes.push_back(mesh4); + const char mnane[]="3DToto"; + MEDLoader::WriteUMeshesPartition(fileName,mnane,meshes,true); + // + MEDCouplingUMesh *mesh5=MEDLoader::ReadUMeshFromFile(fileName,mnane); + mesh1->setName(mnane); + const int part3[18]={0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17}; + MEDCouplingUMesh *mesh6=(MEDCouplingUMesh *)mesh5->buildPartOfMySelf(part3,part3+18,true); + mesh6->setName(mnane); + mesh5->decrRef(); + CPPUNIT_ASSERT(mesh6->isEqual(mesh1,1e-12)); + mesh6->decrRef(); + std::vector<std::string> grps=MEDLoader::GetMeshGroupsNames(fileName,mnane); + CPPUNIT_ASSERT_EQUAL(4,(int)grps.size()); + CPPUNIT_ASSERT(std::find(grps.begin(),grps.end(),std::string("mesh2"))!=grps.end()); + CPPUNIT_ASSERT(std::find(grps.begin(),grps.end(),std::string("mesh3"))!=grps.end()); + CPPUNIT_ASSERT(std::find(grps.begin(),grps.end(),std::string("mesh4"))!=grps.end()); + CPPUNIT_ASSERT(std::find(grps.begin(),grps.end(),std::string("3DMesh_1"))!=grps.end()); + // + std::vector<std::string> vec; + vec.push_back(std::string("mesh2")); + MEDCouplingUMesh *mesh2_2=MEDLoader::ReadUMeshFromGroups(fileName,mnane,0,vec); + CPPUNIT_ASSERT(mesh2_2->isEqual(mesh2,1e-12)); + mesh2_2->decrRef(); + vec.clear(); vec.push_back(std::string("mesh3")); + MEDCouplingUMesh *mesh3_2=MEDLoader::ReadUMeshFromGroups(fileName,mnane,0,vec); + CPPUNIT_ASSERT(mesh3_2->isEqual(mesh3,1e-12)); + mesh3_2->decrRef(); + vec.clear(); vec.push_back(std::string("mesh4")); + MEDCouplingUMesh *mesh4_2=MEDLoader::ReadUMeshFromGroups(fileName,mnane,0,vec); + CPPUNIT_ASSERT(mesh4_2->isEqual(mesh4,1e-12)); + mesh4_2->decrRef(); + vec.clear(); vec.push_back(std::string("3DMesh_1")); + MEDCouplingUMesh *mesh1_2=MEDLoader::ReadUMeshFromGroups(fileName,mnane,0,vec); + mesh1->setName("3DMesh_1"); + CPPUNIT_ASSERT(mesh1_2->isEqual(mesh1,1e-12)); + mesh1_2->decrRef(); + // + vec.clear(); vec.push_back(std::string("Family_-3")); vec.push_back(std::string("Family_-5")); + mesh2_2=MEDLoader::ReadUMeshFromFamilies(fileName,mnane,0,vec); + mesh2_2->setName("mesh2"); + CPPUNIT_ASSERT(mesh2_2->isEqual(mesh2,1e-12)); + mesh2_2->decrRef(); + // + std::vector<std::string> ret=MEDLoader::GetMeshFamiliesNamesOnGroup(fileName,"3DToto","3DMesh_1"); + CPPUNIT_ASSERT_EQUAL(4,(int)ret.size()); + CPPUNIT_ASSERT(ret[0]=="Family_-2"); + CPPUNIT_ASSERT(ret[1]=="Family_-3"); + CPPUNIT_ASSERT(ret[2]=="Family_-4"); + CPPUNIT_ASSERT(ret[3]=="Family_-5"); + // + std::vector<std::string> ret1=MEDLoader::GetMeshGroupsNamesOnFamily(fileName,"3DToto","Family_-3"); + CPPUNIT_ASSERT_EQUAL(2,(int)ret1.size()); + CPPUNIT_ASSERT(ret1[0]=="3DMesh_1"); + CPPUNIT_ASSERT(ret1[1]=="mesh2"); + // + mesh4->decrRef(); + mesh3->decrRef(); + mesh2->decrRef(); + mesh1->decrRef(); +} + +void MEDLoaderTest::testFieldProfilRW1() +{ + const char fileName[]="file12.med"; + MEDCouplingUMesh *mesh1=build3DMesh_1(); + bool b; + int newNbOfNodes; + DataArrayInt *da=mesh1->mergeNodes(1e-12,b,newNbOfNodes); + da->decrRef(); + MEDLoader::WriteUMesh(fileName,mesh1,true); + const int part1[5]={1,2,4,13,15}; + MEDCouplingUMesh *mesh2=(MEDCouplingUMesh *)mesh1->buildPartOfMySelf(part1,part1+5,true); + mesh2->setName(mesh1->getName().c_str());//<- important for the test + // + int nbOfCells=mesh2->getNumberOfCells(); + CPPUNIT_ASSERT_EQUAL(5,nbOfCells); + MEDCouplingFieldDouble *f1=MEDCouplingFieldDouble::New(ON_CELLS,ONE_TIME); + f1->setName("VectorFieldOnCells"); + f1->setMesh(mesh2); + DataArrayDouble *array=DataArrayDouble::New(); + array->alloc(nbOfCells,2); + f1->setArray(array); + array->decrRef(); + double *tmp=array->getPointer(); + const double arr1[10]={71.,171.,10.,110.,20.,120.,30.,130.,40.,140.}; + std::copy(arr1,arr1+10,tmp); + f1->setTime(3.14,2,7); + f1->checkCoherency(); + // + MEDLoader::WriteField(fileName,f1,false);//<- false important for the test + // + MEDCouplingFieldDouble *f2=MEDLoader::ReadFieldCell(fileName,f1->getMesh()->getName().c_str(),0,f1->getName().c_str(),2,7); + std::vector<ParaMEDMEM::TypeOfField> types=MEDLoader::GetTypesOfField(fileName,f1->getMesh()->getName().c_str(),f1->getName().c_str()); + CPPUNIT_ASSERT_EQUAL(1,(int)types.size()); + CPPUNIT_ASSERT(types[0]==ON_CELLS); + f2->checkCoherency(); + CPPUNIT_ASSERT(f1->isEqual(f2,1e-12,1e-12)); + // + f2->decrRef(); + f1->decrRef(); + mesh1->decrRef(); + mesh2->decrRef(); +} + +/*! + * Test MED file profiles. + */ +void MEDLoaderTest::testFieldNodeProfilRW1() +{ + const char fileName[]="file19.med"; + const char fileName2[]="file20.med"; + MEDCouplingUMesh *m=build2DMesh_1(); + int nbOfNodes=m->getNumberOfNodes(); + MEDLoader::WriteUMesh(fileName,m,true); + MEDCouplingFieldDouble *f1=MEDCouplingFieldDouble::New(ON_NODES,ONE_TIME); + f1->setName("VFieldOnNodes"); + f1->setMesh(m); + DataArrayDouble *array=DataArrayDouble::New(); + const double arr1[24]={1.,101.,2.,102.,3.,103.,4.,104.,5.,105.,6.,106.,7.,107.,8.,108.,9.,109.,10.,110.,11.,111.,12.,112.}; + array->alloc(nbOfNodes,2); + std::copy(arr1,arr1+24,array->getPointer()); + f1->setArray(array); + array->setInfoOnComponent(0,"tyty [mm]"); + array->setInfoOnComponent(1,"uiop [MW]"); + array->decrRef(); + f1->setTime(3.14,2,7); + f1->checkCoherency(); + const int arr2[2]={1,4};//node ids are 2,4,5,3,6,7 + MEDCouplingFieldDouble *f2=f1->buildSubPart(arr2,arr2+2); + (const_cast<MEDCouplingMesh *>(f2->getMesh()))->setName(f1->getMesh()->getName().c_str()); + MEDLoader::WriteField(fileName,f2,false);//<- false important for the test + // + MEDCouplingFieldDouble *f3=MEDLoader::ReadFieldNode(fileName,f2->getMesh()->getName().c_str(),0,f2->getName().c_str(),2,7); + f3->checkCoherency(); + CPPUNIT_ASSERT(f3->isEqual(f2,1e-12,1e-12)); + f3->decrRef(); + // + const int arr3[6]={1,3,0,5,2,4}; + f2->renumberNodes(arr3); + MEDLoader::WriteUMesh(fileName2,m,true); + MEDLoader::WriteField(fileName2,f2,false);//<- false important for the test + f3=MEDLoader::ReadFieldNode(fileName2,f2->getMesh()->getName().c_str(),0,f2->getName().c_str(),2,7); + f3->checkCoherency(); + CPPUNIT_ASSERT(f3->isEqual(f2,1e-12,1e-12)); + f3->decrRef(); + f2->decrRef(); + // + f1->decrRef(); + m->decrRef(); +} + +void MEDLoaderTest::testFieldNodeProfilRW2() +{ + const char fileName[]="file23.med"; + MEDCouplingUMesh *mesh=build3DSurfMesh_1(); + MEDLoader::WriteUMesh(fileName,mesh,true); + // + MEDCouplingFieldDouble *f1=MEDCouplingFieldDouble::New(ON_NODES,ONE_TIME); + f1->setName("FieldMix"); + f1->setMesh(mesh); + const double arr2[24]={ + 1071.,1171.,1010.,1110.,1020.,1120.,1030.,1130.,1040.,1140.,1050.,1150., + 1060.,1160.,1070.,1170.,1080.,1180.,1090.,1190.,1091.,1191.,1092.,1192. + }; + DataArrayDouble *array=DataArrayDouble::New(); + array->alloc(12,2); + f1->setArray(array); + array->setInfoOnComponent(0,"plkj [mm]"); + array->setInfoOnComponent(1,"pqqqss [mm]"); + array->decrRef(); + double *tmp=array->getPointer(); + std::copy(arr2,arr2+24,tmp); + f1->setTime(3.17,2,7); + // + const int renumArr[12]={3,7,2,1,5,11,10,0,9,6,8,4}; + f1->renumberNodes(renumArr); + f1->checkCoherency(); + MEDLoader::WriteField(fileName,f1,false);//<- false important for the test + MEDCouplingFieldDouble *f2=MEDLoader::ReadFieldNode(fileName,f1->getMesh()->getName().c_str(),0,f1->getName().c_str(),2,7); + CPPUNIT_ASSERT(f2->isEqual(f1,1e-12,1e-12)); + // + f2->decrRef(); + mesh->decrRef(); + f1->decrRef(); +} + +void MEDLoaderTest::testFieldGaussRW1() +{ + const char fileName[]="file13.med"; + MEDCouplingFieldDouble *f1=buildVecFieldOnGauss_1(); + MEDLoader::WriteField(fileName,f1,true); + MEDCouplingFieldDouble *f2=MEDLoader::ReadField(ON_GAUSS_PT,fileName,f1->getMesh()->getName().c_str(),0,f1->getName().c_str(),1,5); + CPPUNIT_ASSERT(f1->isEqual(f2,1e-12,1e-12)); + f2->decrRef(); + f1->decrRef(); +} + +void MEDLoaderTest::testFieldGaussNERW1() +{ + const char fileName[]="file14.med"; + MEDCouplingFieldDouble *f1=buildVecFieldOnGaussNE_1(); + MEDLoader::WriteField(fileName,f1,true); + std::vector<ParaMEDMEM::TypeOfField> tof(MEDLoader::GetTypesOfField(fileName,"2DMesh_2","MyFieldOnGaussNE")); + CPPUNIT_ASSERT_EQUAL(1,(int)tof.size()); + CPPUNIT_ASSERT(ON_GAUSS_NE==tof[0]); + MEDCouplingFieldDouble *f2=MEDLoader::ReadField(ON_GAUSS_NE,fileName,f1->getMesh()->getName().c_str(),0,f1->getName().c_str(),1,5); + CPPUNIT_ASSERT(f1->isEqual(f2,1e-12,1e-12)); + f2->decrRef(); + f1->decrRef(); +} + +void MEDLoaderTest::testLittleStrings1() +{ + std::string s("azeeeerrrtty"); + MEDLoaderBase::zipEqualConsChar(s,3); + CPPUNIT_ASSERT(s=="azertty"); +} + +void MEDLoaderTest::testSplitIntoNameAndUnit1() +{ + std::string s(" []"); + std::string c,u; + MEDLoaderBase::splitIntoNameAndUnit(s,c,u); + CPPUNIT_ASSERT(c.empty()); + CPPUNIT_ASSERT(u.empty()); + s=" lmmm kki jjj "; + MEDLoaderBase::strip(s); + CPPUNIT_ASSERT(s=="lmmm kki jjj"); + s=" "; + MEDLoaderBase::strip(s); + CPPUNIT_ASSERT(s.empty()); + s=""; + MEDLoaderBase::strip(s); + CPPUNIT_ASSERT(s.empty()); + s=" "; + MEDLoaderBase::strip(s); + CPPUNIT_ASSERT(s.empty()); + s=" pp"; + MEDLoaderBase::strip(s); + CPPUNIT_ASSERT(s=="pp"); +} + +void MEDLoaderTest::testMesh3DSurfShuffleRW() +{ + const char fileName[]="file15.med"; + MEDCouplingUMesh *mesh=build3DSurfMesh_1(); + const int renumber1[6]={2,5,1,0,3,4}; + mesh->renumberCells(renumber1,false); + mesh->checkCoherency(); + MEDLoader::WriteUMesh(fileName,mesh,true); + MEDCouplingUMesh *mesh_rw=MEDLoader::ReadUMeshFromFile(fileName,mesh->getName().c_str(),0); + CPPUNIT_ASSERT(mesh->isEqual(mesh_rw,1e-12)); + mesh_rw->decrRef(); + mesh->decrRef(); +} + +void MEDLoaderTest::testFieldShuffleRW1() +{ + const char fileName[]="file16.med"; + MEDCouplingUMesh *mesh=build3DSurfMesh_1(); + MEDCouplingFieldDouble *f1=MEDCouplingFieldDouble::New(ON_CELLS,ONE_TIME); + f1->setName("FieldOnCellsShuffle"); + f1->setMesh(mesh); + DataArrayDouble *array=DataArrayDouble::New(); + array->alloc(6,2); + f1->setArray(array); + array->decrRef(); + double *tmp=array->getPointer(); + const double arr1[12]={71.,171.,10.,110.,20.,120.,30.,130.,40.,140.,50.,150.}; + std::copy(arr1,arr1+12,tmp); + f1->setTime(3.14,2,7); + f1->checkCoherency(); + // + const int renumber1[6]={2,1,5,0,3,4}; + f1->renumberCells(renumber1,false); + MEDLoader::WriteField(fileName,f1,true); + MEDCouplingFieldDouble *f2=MEDLoader::ReadFieldCell(fileName,mesh->getName().c_str(),0,f1->getName().c_str(),2,7); + CPPUNIT_ASSERT(f2->isEqual(f1,1e-12,1e-12)); + f2->decrRef(); + // + mesh->decrRef(); + f1->decrRef(); +} + +/*! + * Shuffle de cells but no profile. Like pointe.med + */ +void MEDLoaderTest::testMultiFieldShuffleRW1() +{ + const char fileName[]="file17.med"; + MEDCouplingUMesh *m=build3DMesh_2(); + CPPUNIT_ASSERT_EQUAL(20,m->getNumberOfCells()); + CPPUNIT_ASSERT_EQUAL(45,m->getNumberOfNodes()); + const int polys[3]={1,4,6}; + std::vector<int> poly2(polys,polys+3); + m->convertToPolyTypes(&poly2[0],&poly2[0]+poly2.size()); + const int renum[20]={1,3,2,8,9,12,13,16,19,0,4,7,5,15,14,17,10,18,6,11}; + m->renumberCells(renum,false); + m->orientCorrectlyPolyhedrons(); + // Writing + MEDLoader::WriteUMesh(fileName,m,true); + MEDCouplingFieldDouble *f1Tmp=m->getMeasureField(false); + MEDCouplingFieldDouble *f1=f1Tmp->buildNewTimeReprFromThis(ONE_TIME,false); + f1Tmp->decrRef(); + f1->setTime(0.,1,2); + MEDCouplingFieldDouble *f_1=f1->cloneWithMesh(true); + MEDLoader::WriteFieldUsingAlreadyWrittenMesh(fileName,f1); + f1->applyFunc("2*x"); + f1->setTime(0.01,3,4); + MEDCouplingFieldDouble *f_2=f1->cloneWithMesh(true); + MEDLoader::WriteFieldUsingAlreadyWrittenMesh(fileName,f1); + f1->applyFunc("2*x/3"); + f1->setTime(0.02,5,6); + MEDCouplingFieldDouble *f_3=f1->cloneWithMesh(true); + MEDLoader::WriteFieldUsingAlreadyWrittenMesh(fileName,f1); + f1->decrRef(); + // Reading + std::vector<std::pair<int,int> > its; + its.push_back(std::pair<int,int>(1,2)); + its.push_back(std::pair<int,int>(3,4)); + its.push_back(std::pair<int,int>(5,6)); + std::vector<MEDCouplingFieldDouble *> fs=MEDLoader::ReadFieldsOnSameMesh(ON_CELLS,fileName,f_1->getMesh()->getName().c_str(),0,f_1->getName().c_str(),its); + CPPUNIT_ASSERT_EQUAL(3,(int)fs.size()); + const MEDCouplingMesh *mm=fs[0]->getMesh(); + CPPUNIT_ASSERT(fs[0]->isEqual(f_1,1e-12,1e-12)); + CPPUNIT_ASSERT(fs[1]->isEqual(f_2,1e-12,1e-12)); + CPPUNIT_ASSERT(fs[2]->isEqual(f_3,1e-12,1e-12)); + CPPUNIT_ASSERT(mm==fs[1]->getMesh());// <- important for the test + CPPUNIT_ASSERT(mm==fs[2]->getMesh());// <- important for the test + for(std::vector<MEDCouplingFieldDouble *>::iterator iter=fs.begin();iter!=fs.end();iter++) + (*iter)->decrRef(); + // + f_1->decrRef(); + f_2->decrRef(); + f_3->decrRef(); + // + m->decrRef(); +} + +void MEDLoaderTest::testWriteUMeshesRW1() +{ + const char fileName[]="file18.med"; + MEDCouplingUMesh *m3d=build3DMesh_2(); + const double pt[3]={0.,0.,-0.3}; + const double vec[3]={0.,0.,1.}; + std::vector<int> nodes; + m3d->findNodesOnPlane(pt,vec,1e-12,nodes); + MEDCouplingUMesh *m2d=(MEDCouplingUMesh *)m3d->buildFacePartOfMySelfNode(&nodes[0],&nodes[0]+nodes.size(),true); + const int renumber[5]={1,2,0,4,3}; + m2d->renumberCells(renumber,false); + m2d->setName("ExampleOfMultiDimW"); + std::vector<const MEDCouplingUMesh *> meshes; + meshes.push_back(m2d); + meshes.push_back(m3d); + MEDLoader::WriteUMeshes(fileName,meshes,true); + MEDCouplingUMesh *m3d_bis=MEDLoader::ReadUMeshFromFile(fileName,m2d->getName().c_str(),0); + CPPUNIT_ASSERT(!m3d_bis->isEqual(m3d,1e-12)); + m3d_bis->setName(m3d->getName().c_str()); + CPPUNIT_ASSERT(m3d_bis->isEqual(m3d,1e-12)); + MEDCouplingUMesh *m2d_bis=MEDLoader::ReadUMeshFromFile(fileName,m2d->getName().c_str(),-1);//-1 for faces + CPPUNIT_ASSERT(m2d_bis->isEqual(m2d,1e-12)); + // Creation of a field on faces. + MEDCouplingFieldDouble *f1=MEDCouplingFieldDouble::New(ON_CELLS,ONE_TIME); + f1->setName("FieldOnFacesShuffle"); + f1->setMesh(m2d); + DataArrayDouble *array=DataArrayDouble::New(); + array->alloc(m2d->getNumberOfCells(),2); + array->setInfoOnComponent(0,"plkj [mm]"); + array->setInfoOnComponent(1,"pqqqss [mm]"); + f1->setArray(array); + array->decrRef(); + double *tmp=array->getPointer(); + const double arr1[10]={71.,171.,10.,110.,20.,120.,30.,130.,40.,140.}; + std::copy(arr1,arr1+10,tmp); + f1->setTime(3.14,2,7); + f1->checkCoherency(); + MEDLoader::WriteFieldUsingAlreadyWrittenMesh(fileName,f1); + MEDCouplingFieldDouble *f2=MEDLoader::ReadFieldCell(fileName,f1->getMesh()->getName().c_str(),-1,f1->getName().c_str(),2,7); + CPPUNIT_ASSERT(f2->isEqual(f1,1e-12,1e-12)); + f1->decrRef(); + f2->decrRef(); + // + m2d_bis->decrRef(); + m3d_bis->decrRef(); + m2d->decrRef(); + m3d->decrRef(); +} + +void MEDLoaderTest::testMixCellAndNodesFieldRW1() +{ + const char fileName[]="file21.med"; + MEDCouplingUMesh *mesh=build3DSurfMesh_1(); + MEDCouplingFieldDouble *f1=MEDCouplingFieldDouble::New(ON_CELLS,ONE_TIME); + f1->setName("FieldMix"); + f1->setMesh(mesh); + DataArrayDouble *array=DataArrayDouble::New(); + array->alloc(6,2); + f1->setArray(array); + array->setInfoOnComponent(0,"plkj [mm]"); + array->setInfoOnComponent(1,"pqqqss [mm]"); + array->decrRef(); + double *tmp=array->getPointer(); + const double arr1[12]={71.,171.,10.,110.,20.,120.,30.,130.,40.,140.,50.,150.}; + std::copy(arr1,arr1+12,tmp); + f1->setTime(3.14,2,7); + f1->checkCoherency(); + // + MEDCouplingFieldDouble *f2=MEDCouplingFieldDouble::New(ON_NODES,ONE_TIME); + f2->setName("FieldMix"); + f2->setMesh(mesh); + array=DataArrayDouble::New(); + array->alloc(12,2); + f2->setArray(array); + array->setInfoOnComponent(0,"plkj [mm]"); + array->setInfoOnComponent(1,"pqqqss [mm]"); + array->decrRef(); + tmp=array->getPointer(); + const double arr2[24]={ + 1071.,1171.,1010.,1110.,1020.,1120.,1030.,1130.,1040.,1140.,1050.,1150., + 1060.,1160.,1070.,1170.,1080.,1180.,1090.,1190.,1091.,1191.,1092.,1192. + }; + std::copy(arr2,arr2+24,tmp); + f2->setTime(3.14,2,7); + f2->checkCoherency(); + // + MEDLoader::WriteField(fileName,f1,true); + std::vector<ParaMEDMEM::TypeOfField> ts=MEDLoader::GetTypesOfField(fileName,f1->getMesh()->getName().c_str(),f1->getName().c_str()); + CPPUNIT_ASSERT_EQUAL(1,(int)ts.size()); + CPPUNIT_ASSERT_EQUAL(ON_CELLS,ts[0]); + std::vector<std::string> fs=MEDLoader::GetAllFieldNamesOnMesh(fileName,f1->getMesh()->getName().c_str()); + CPPUNIT_ASSERT_EQUAL(1,(int)fs.size()); + CPPUNIT_ASSERT(fs[0]=="FieldMix"); + MEDLoader::WriteFieldUsingAlreadyWrittenMesh(fileName,f2); + fs=MEDLoader::GetAllFieldNamesOnMesh(fileName,f1->getMesh()->getName().c_str()); + CPPUNIT_ASSERT_EQUAL(1,(int)fs.size()); + CPPUNIT_ASSERT(fs[0]=="FieldMix"); + // + ts=MEDLoader::GetTypesOfField(fileName,f1->getMesh()->getName().c_str(),f1->getName().c_str()); + CPPUNIT_ASSERT_EQUAL(2,(int)ts.size()); + CPPUNIT_ASSERT_EQUAL(ON_NODES,ts[0]); + CPPUNIT_ASSERT_EQUAL(ON_CELLS,ts[1]); + // + MEDCouplingFieldDouble *f3=MEDLoader::ReadFieldNode(fileName,f1->getMesh()->getName().c_str(),0,f1->getName().c_str(),2,7); + CPPUNIT_ASSERT(f3->isEqual(f2,1e-12,1e-12)); + f3->decrRef(); + f3=MEDLoader::ReadFieldCell(fileName,f1->getMesh()->getName().c_str(),0,f1->getName().c_str(),2,7); + CPPUNIT_ASSERT(f3->isEqual(f1,1e-12,1e-12)); + f3->decrRef(); + // + f1->decrRef(); + f2->decrRef(); + mesh->decrRef(); +} + +void MEDLoaderTest::testGetAllFieldNamesRW1() +{ + const char fileName[]="file22.med"; + MEDCouplingUMesh *mesh=build2DMesh_2(); + MEDCouplingFieldDouble *f1=MEDCouplingFieldDouble::New(ON_NODES,ONE_TIME); + f1->setName("Field1"); + f1->setTime(3.44,5,6); + f1->setMesh(mesh); + f1->fillFromAnalytic(2,"x+y"); + MEDLoader::WriteField(fileName,f1,true); + f1->setTime(1002.3,7,8); + f1->fillFromAnalytic(2,"x+77.*y"); + MEDLoader::WriteFieldUsingAlreadyWrittenMesh(fileName,f1); + f1->setName("Field2"); + MEDLoader::WriteField(fileName,f1,false); + f1->setName("Field3"); + mesh->setName("2DMesh_2Bis"); + MEDLoader::WriteField(fileName,f1,false); + f1->decrRef(); + f1=MEDCouplingFieldDouble::New(ON_CELLS,ONE_TIME); + f1->setName("Field8"); + f1->setTime(8.99,7,9); + f1->setMesh(mesh); + f1->fillFromAnalytic(3,"3*x+y"); + MEDLoader::WriteField(fileName,f1,false); + f1->decrRef(); + std::vector<std::string> fs=MEDLoader::GetAllFieldNames(fileName); + CPPUNIT_ASSERT_EQUAL(4,(int)fs.size()); + CPPUNIT_ASSERT(fs[0]=="Field1"); + CPPUNIT_ASSERT(fs[1]=="Field2"); + CPPUNIT_ASSERT(fs[2]=="Field3"); + CPPUNIT_ASSERT(fs[3]=="Field8"); + mesh->decrRef(); +} + +MEDCouplingUMesh *MEDLoaderTest::build1DMesh_1() +{ + double coords[6]={ 0.0, 0.3, 0.75, 1.0, 1.4, 1.3 }; + int conn[9]={ 0,1, 1,2, 2,3 , 3,4,5}; + MEDCouplingUMesh *mesh=MEDCouplingUMesh::New(); + mesh->setName("1DMesh_1"); + mesh->setMeshDimension(1); + mesh->allocateCells(4); + mesh->insertNextCell(INTERP_KERNEL::NORM_SEG2,2,conn); + mesh->insertNextCell(INTERP_KERNEL::NORM_SEG2,2,conn+2); + mesh->insertNextCell(INTERP_KERNEL::NORM_SEG2,2,conn+4); + mesh->insertNextCell(INTERP_KERNEL::NORM_SEG3,3,conn+6); + mesh->finishInsertingCells(); + DataArrayDouble *myCoords=DataArrayDouble::New(); + myCoords->alloc(6,1); + myCoords->setInfoOnComponent(0,"tototototototot [m*m*m*m*m*m*m*m]"); + std::copy(coords,coords+6,myCoords->getPointer()); + mesh->setCoords(myCoords); + myCoords->decrRef(); + return mesh; +} + +MEDCouplingUMesh *MEDLoaderTest::build2DCurveMesh_1() +{ + double coords[12]={ 0.0,0.0, 0.3,0.3, 0.75,0.75, 1.0,1.0, 1.4,1.4, 1.3,1.3 }; + int conn[9]={ 0,1, 1,2, 2,3 , 3,4,5}; + MEDCouplingUMesh *mesh=MEDCouplingUMesh::New(); + mesh->setName("2DCurveMesh_1"); + mesh->setMeshDimension(1); + mesh->allocateCells(4); + mesh->insertNextCell(INTERP_KERNEL::NORM_SEG2,2,conn); + mesh->insertNextCell(INTERP_KERNEL::NORM_SEG2,2,conn+2); + mesh->insertNextCell(INTERP_KERNEL::NORM_SEG2,2,conn+4); + mesh->insertNextCell(INTERP_KERNEL::NORM_SEG3,3,conn+6); + mesh->finishInsertingCells(); + DataArrayDouble *myCoords=DataArrayDouble::New(); + myCoords->alloc(6,2); + std::copy(coords,coords+12,myCoords->getPointer()); + mesh->setCoords(myCoords); + myCoords->decrRef(); + return mesh; +} + +MEDCouplingUMesh *MEDLoaderTest::build2DMesh_1() +{ + double targetCoords[24]={-0.3,-0.3, 0.2,-0.3, 0.7,-0.3, -0.3,0.2, 0.2,0.2, 0.7,0.2, -0.3,0.7, 0.2,0.7, 0.7,0.7, -0.05,0.95, 0.2,1.2, 0.45,0.95 }; + int targetConn[24]={1,4,2, 4,5,2, 6,10,8,9,11,7, 0,3,4,1, 6,7,4,3, 7,8,5,4}; + MEDCouplingUMesh *targetMesh=MEDCouplingUMesh::New(); + targetMesh->setMeshDimension(2); + targetMesh->allocateCells(6); + targetMesh->setName("2DMesh_1"); + targetMesh->insertNextCell(INTERP_KERNEL::NORM_TRI3,3,targetConn); + targetMesh->insertNextCell(INTERP_KERNEL::NORM_TRI3,3,targetConn+3); + targetMesh->insertNextCell(INTERP_KERNEL::NORM_TRI6,6,targetConn+6); + targetMesh->insertNextCell(INTERP_KERNEL::NORM_QUAD4,4,targetConn+12); + targetMesh->insertNextCell(INTERP_KERNEL::NORM_QUAD4,4,targetConn+16); + targetMesh->insertNextCell(INTERP_KERNEL::NORM_POLYGON,4,targetConn+20); + targetMesh->finishInsertingCells(); + DataArrayDouble *myCoords=DataArrayDouble::New(); + myCoords->alloc(12,2); + myCoords->setInfoOnComponent(0,"tototototototot [m]"); + myCoords->setInfoOnComponent(1,"energie [kW]"); + std::copy(targetCoords,targetCoords+24,myCoords->getPointer()); + targetMesh->setCoords(myCoords); + myCoords->decrRef(); + return targetMesh; +} + +MEDCouplingUMesh *MEDLoaderTest::build2DMesh_2() +{ + double targetCoords[24]={ + -0.3,-0.3, 0.2,-0.3, 0.7,-0.3, -0.3,0.2, 0.2,0.2, 0.7,0.2, -0.3,0.7, 0.2,0.7, 0.7,0.7, + -0.05,0.95, 0.2,1.2, 0.45,0.95 + }; + int targetConn[24]={1,4,2, 4,5,2, 6,10,8,9,11,7, 0,3,4,1, 6,7,4,3, 7,8,5,4}; + MEDCouplingUMesh *targetMesh=MEDCouplingUMesh::New(); + targetMesh->setMeshDimension(2); + targetMesh->allocateCells(5); + targetMesh->setName("2DMesh_2"); + targetMesh->insertNextCell(INTERP_KERNEL::NORM_TRI3,3,targetConn); + targetMesh->insertNextCell(INTERP_KERNEL::NORM_TRI3,3,targetConn+3); + targetMesh->insertNextCell(INTERP_KERNEL::NORM_QUAD4,4,targetConn+12); + targetMesh->insertNextCell(INTERP_KERNEL::NORM_QUAD4,4,targetConn+16); + targetMesh->insertNextCell(INTERP_KERNEL::NORM_TRI6,6,targetConn+6); + targetMesh->finishInsertingCells(); + DataArrayDouble *myCoords=DataArrayDouble::New(); + myCoords->alloc(12,2); + myCoords->setInfoOnComponent(0,"toto [m]"); + myCoords->setInfoOnComponent(1,"energie [kW]"); + std::copy(targetCoords,targetCoords+24,myCoords->getPointer()); + targetMesh->setCoords(myCoords); + myCoords->decrRef(); + return targetMesh; +} + +MEDCouplingUMesh *MEDLoaderTest::build3DSurfMesh_1() +{ + double targetCoords[36]={ + -0.3,-0.3,-0.3, 0.2,-0.3,-0.3, 0.7,-0.3,-0.3, -0.3,0.2,-0.3, 0.2,0.2,-0.3, 0.7,0.2,-0.3, -0.3,0.7,-0.3, 0.2,0.7,-0.3, 0.7,0.7,-0.3 + ,-0.05,0.95,-0.3, 0.2,1.2,-0.3, 0.45,0.95,-0.3 + }; + int targetConn[24]={1,4,2, 4,5,2, 6,10,8,9,11,7, 0,3,4,1, 6,7,4,3, 7,8,5,4}; + MEDCouplingUMesh *targetMesh=MEDCouplingUMesh::New(); + targetMesh->setMeshDimension(2); + targetMesh->allocateCells(6); + targetMesh->setName("3DSurfMesh_1"); + targetMesh->insertNextCell(INTERP_KERNEL::NORM_TRI3,3,targetConn); + targetMesh->insertNextCell(INTERP_KERNEL::NORM_TRI3,3,targetConn+3); + targetMesh->insertNextCell(INTERP_KERNEL::NORM_QUAD4,4,targetConn+12); + targetMesh->insertNextCell(INTERP_KERNEL::NORM_QUAD4,4,targetConn+16); + targetMesh->insertNextCell(INTERP_KERNEL::NORM_TRI6,6,targetConn+6); + targetMesh->insertNextCell(INTERP_KERNEL::NORM_POLYGON,4,targetConn+20); + targetMesh->finishInsertingCells(); + DataArrayDouble *myCoords=DataArrayDouble::New(); + myCoords->alloc(12,3); + myCoords->setInfoOnComponent(0,"toto [m]"); + myCoords->setInfoOnComponent(2,"ff [km]");//component 1 is not set for test + std::copy(targetCoords,targetCoords+36,myCoords->getPointer()); + targetMesh->setCoords(myCoords); + myCoords->decrRef(); + return targetMesh; +} + +MEDCouplingUMesh *MEDLoaderTest::build3DMesh_1() +{ + double coords[180]={ + 0.,0.,0., 1.,1.,0., 1.,1.25,0., 0.,1.,0., 1.,1.5,0., 2.,0.,0., 2.,1.,0., 1.,2.,0., 0.,2.,0., 3.,1.,0., + 3.,2.,0., 0.,1.,0., 1.,3.,0., 2.,2.,0., 2.,3.,0., + 0.,0.,1., 1.,1.,1., 1.,1.25,1., 0.,1.,1., 1.,1.5,1., 2.,0.,1., 2.,1.,1., 1.,2.,1., 0.,2.,1., 3.,1.,1., + 3.,2.,1., 0.,1.,1., 1.,3.,1., 2.,2.,1., 2.,3.,1., + 0.,0.,2., 1.,1.,2., 1.,1.25,2., 0.,1.,2., 1.,1.5,2., 2.,0.,2., 2.,1.,2., 1.,2.,2., 0.,2.,2., 3.,1.,2., + 3.,2.,2., 0.,1.,2., 1.,3.,2., 2.,2.,2., 2.,3.,2., + 0.,0.,3., 1.,1.,3., 1.,1.25,3., 0.,1.,3., 1.,1.5,3., 2.,0.,3., 2.,1.,3., 1.,2.,3., 0.,2.,3., 3.,1.,3., + 3.,2.,3., 0.,1.,3., 1.,3.,3., 2.,2.,3., 2.,3.,3.}; + + int conn[354]={ + // 0 + 0,11,1,3,15,26,16,18, 1,2,4,7,13,6,-1,1,16,21,6,-1,6,21,28,13,-1,13,7,22,28,-1,7,4,19,22,-1,4,2,17,19,-1,2,1,16,17,-1,16,21,28,22,19,17, + 1,6,5,3,16,21,20,18, 13,10,9,6,28,25,24,21, + 11,8,7,4,2,1,-1,11,26,16,1,-1,1,16,17,2,-1,2,17,19,4,-1,4,19,22,7,-1,7,8,23,22,-1,8,11,26,23,-1,26,16,17,19,22,23, + 7,12,14,13,22,27,29,28, + // 1 + 15,26,16,18,30,41,31,33, 16,17,19,22,28,21,-1,16,31,36,21,-1,21,36,43,28,-1,28,22,37,43,-1,22,19,34,37,-1,19,17,32,34,-1,17,16,31,32,-1,31,36,43,37,34,32, + 16,21,20,18,31,36,35,33, 28,25,24,21,43,40,39,36, + 26,23,22,19,17,16,-1,26,41,31,16,-1,16,31,32,17,-1,17,32,34,19,-1,19,34,37,22,-1,22,23,38,37,-1,23,26,41,38,-1,41,31,32,34,37,38, + 22,27,29,28,37,42,44,43, + // 2 + 30,41,31,33,45,56,46,48, 31,32,34,37,43,36,-1,31,46,51,36,-1,36,51,58,43,-1,43,37,52,58,-1,37,34,49,52,-1,34,32,47,49,-1,32,31,46,47,-1,46,51,58,52,49,47, + 31,36,35,33,46,51,50,48, 43,40,39,36,58,55,54,51, + 41,38,37,34,32,31,-1,41,56,46,31,-1,31,46,47,32,-1,32,47,49,34,-1,34,49,52,37,-1,37,38,53,52,-1,38,41,56,53,-1,56,46,47,49,52,53, + 37,42,44,43,52,57,59,58 + }; + // + MEDCouplingUMesh *ret=MEDCouplingUMesh::New(); + ret->setName("3DMesh_1"); + ret->setMeshDimension(3); + ret->allocateCells(18); + // + ret->insertNextCell(INTERP_KERNEL::NORM_HEXA8,8,conn); + ret->insertNextCell(INTERP_KERNEL::NORM_HEXA8,8,conn+51); + ret->insertNextCell(INTERP_KERNEL::NORM_HEXA8,8,conn+59); + ret->insertNextCell(INTERP_KERNEL::NORM_HEXA8,8,conn+110); + // + ret->insertNextCell(INTERP_KERNEL::NORM_HEXA8,8,conn+118); + ret->insertNextCell(INTERP_KERNEL::NORM_HEXA8,8,conn+169); + ret->insertNextCell(INTERP_KERNEL::NORM_HEXA8,8,conn+177); + ret->insertNextCell(INTERP_KERNEL::NORM_HEXA8,8,conn+228); + // + ret->insertNextCell(INTERP_KERNEL::NORM_HEXA8,8,conn+236); + ret->insertNextCell(INTERP_KERNEL::NORM_HEXA8,8,conn+287); + ret->insertNextCell(INTERP_KERNEL::NORM_HEXA8,8,conn+295); + ret->insertNextCell(INTERP_KERNEL::NORM_HEXA8,8,conn+346); + // + ret->insertNextCell(INTERP_KERNEL::NORM_POLYHED,43,conn+8); + ret->insertNextCell(INTERP_KERNEL::NORM_POLYHED,43,conn+67); + ret->insertNextCell(INTERP_KERNEL::NORM_POLYHED,43,conn+126); + ret->insertNextCell(INTERP_KERNEL::NORM_POLYHED,43,conn+185); + ret->insertNextCell(INTERP_KERNEL::NORM_POLYHED,43,conn+244); + ret->insertNextCell(INTERP_KERNEL::NORM_POLYHED,43,conn+303); + // + ret->finishInsertingCells(); + DataArrayDouble *myCoords=DataArrayDouble::New(); + myCoords->alloc(60,3); + myCoords->setInfoOnComponent(0,"titi [m]"); + myCoords->setInfoOnComponent(1,"density power [MW/m^3]"); + myCoords->setInfoOnComponent(2,"t [kW]"); + std::copy(coords,coords+180,myCoords->getPointer()); + ret->setCoords(myCoords); + myCoords->decrRef(); + return ret; +} + +MEDCouplingUMesh *MEDLoaderTest::build3DMesh_2() +{ + MEDCouplingUMesh *m3dsurfBase=build3DSurfMesh_1(); + int numbers[5]={0,1,2,3,5}; + MEDCouplingUMesh *m3dsurf=(MEDCouplingUMesh *)m3dsurfBase->buildPartOfMySelf(numbers,numbers+5,false); + m3dsurfBase->decrRef(); + MEDCouplingUMesh *m1dBase=build1DMesh_1(); + int numbers2[4]={0,1,2,3}; + MEDCouplingUMesh *m1d=(MEDCouplingUMesh *)m1dBase->buildPartOfMySelf(numbers2,numbers2+4,false); + m1dBase->decrRef(); + m1d->changeSpaceDimension(3); + const double vec[3]={0.,1.,0.}; + const double pt[3]={0.,0.,0.}; + m1d->rotate(pt,vec,-M_PI/2.); + MEDCouplingUMesh *ret=m3dsurf->buildExtrudedMesh(m1d,0); + m1d->decrRef(); + m3dsurf->decrRef(); + return ret; +} + +MEDCouplingFieldDouble *MEDLoaderTest::buildVecFieldOnCells_1() +{ + MEDCouplingUMesh *mesh=build3DSurfMesh_1(); + int nbOfCells=mesh->getNumberOfCells(); + MEDCouplingFieldDouble *f1=MEDCouplingFieldDouble::New(ON_CELLS,ONE_TIME); + f1->setName("VectorFieldOnCells"); + f1->setMesh(mesh); + DataArrayDouble *array=DataArrayDouble::New(); + array->alloc(nbOfCells,3); + array->setInfoOnComponent(0,"power [MW/m^3]"); + array->setInfoOnComponent(1,"density [g/cm^3]"); + array->setInfoOnComponent(2,"temperature [K]"); + f1->setArray(array); + array->decrRef(); + double *tmp=array->getPointer(); + const double arr1[18]={0.,10.,20.,1.,11.,21.,2.,12.,22.,3.,13.,23.,4.,14.,24.,5.,15.,25.}; + std::copy(arr1,arr1+18,tmp); + f1->setTime(2.,0,1); + f1->checkCoherency(); + mesh->decrRef(); + return f1; +} + +MEDCouplingFieldDouble *MEDLoaderTest::buildVecFieldOnNodes_1() +{ + MEDCouplingUMesh *mesh=build3DSurfMesh_1(); + int nbOfNodes=mesh->getNumberOfNodes(); + MEDCouplingFieldDouble *f1=MEDCouplingFieldDouble::New(ON_NODES,ONE_TIME); + f1->setName("VectorFieldOnNodes"); + f1->setMesh(mesh); + DataArrayDouble *array=DataArrayDouble::New(); + array->alloc(nbOfNodes,3); + f1->setArray(array); + array->setInfoOnComponent(0,"power [MW/m^3]"); + array->setInfoOnComponent(1,"density [g/cm^3]"); + array->setInfoOnComponent(2,"temperature [K]"); + array->decrRef(); + double *tmp=array->getPointer(); + const double arr1[36]={ + 70.,80.,90.,71.,81.,91.,72.,82.,92.,73.,83.,93.,74.,84.,94.,75.,85.,95., + 1000.,10010.,10020.,1001.,10011.,10021.,1002.,10012.,10022.,1003.,10013.,10023.,1004.,10014.,10024.,1005.,10015.,10025., + }; + std::copy(arr1,arr1+36,tmp); + f1->setTime(2.12,2,3); + f1->checkCoherency(); + mesh->decrRef(); + return f1; +} + +MEDCouplingFieldDouble *MEDLoaderTest::buildVecFieldOnGauss_1() +{ + const double _a=0.446948490915965; + const double _b=0.091576213509771; + const double _p1=0.11169079483905; + const double _p2=0.0549758718227661; + const double refCoo1[6]={ 0.,0., 1.,0., 0.,1. }; + const double gsCoo1[12]={ 2*_b-1, 1-4*_b, 2*_b-1, 2.07*_b-1, 1-4*_b, + 2*_b-1, 1-4*_a, 2*_a-1, 2*_a-1, 1-4*_a, 2*_a-1, 2*_a-1 }; + const double wg1[6]={ 4*_p2, 4*_p2, 4*_p2, 4*_p1, 4*_p1, 4*_p1 }; + std::vector<double> _refCoo1(refCoo1,refCoo1+6); + std::vector<double> _gsCoo1(gsCoo1,gsCoo1+12); + std::vector<double> _wg1(wg1,wg1+6); + MEDCouplingUMesh *m=build2DMesh_2(); + MEDCouplingFieldDouble *f=MEDCouplingFieldDouble::New(ON_GAUSS_PT,ONE_TIME); + f->setTime(3.14,1,5); + f->setMesh(m); + f->setGaussLocalizationOnType(INTERP_KERNEL::NORM_TRI3,_refCoo1,_gsCoo1,_wg1); + const double refCoo2[12]={-1.0,1.0, -1.0,-1.0, 1.0,-1.0, -1.0,0.0, 0.0,-1.0, 0.0,0.0 }; + std::vector<double> _refCoo2(refCoo2,refCoo2+12); + std::vector<double> _gsCoo2(_gsCoo1); + std::vector<double> _wg2(_wg1); + _gsCoo2.resize(6); _wg2.resize(3); + const double refCoo3[8]={ 0.,0., 1.,0., 1.,1., 0.,1. }; + std::vector<double> _refCoo3(refCoo3,refCoo3+8); + _gsCoo1.resize(4); _wg1.resize(2); + f->setGaussLocalizationOnType(INTERP_KERNEL::NORM_QUAD4,_refCoo3,_gsCoo1,_wg1); + f->setGaussLocalizationOnType(INTERP_KERNEL::NORM_TRI6,_refCoo2,_gsCoo2,_wg2); + DataArrayDouble *array=DataArrayDouble::New(); + array->alloc(19,2); + double *ptr=array->getPointer(); + for(int i=0;i<19*2;i++) + ptr[i]=(double)(i+7); + f->setArray(array); + f->setName("MyFirstFieldOnGaussPoint"); + array->setInfoOnComponent(0,"power [MW/m^3]"); + array->setInfoOnComponent(1,"density"); + array->decrRef(); + f->checkCoherency(); + m->decrRef(); + return f; +} + +MEDCouplingFieldDouble *MEDLoaderTest::buildVecFieldOnGaussNE_1() +{ + MEDCouplingUMesh *m=build2DMesh_2(); + MEDCouplingFieldDouble *f=MEDCouplingFieldDouble::New(ON_GAUSS_NE,ONE_TIME); + f->setTime(3.14,1,5); + f->setMesh(m); + DataArrayDouble *array=DataArrayDouble::New(); + array->alloc(20,2); + double *ptr=array->getPointer(); + for(int i=0;i<20*2;i++) + ptr[i]=(double)(i+8); + f->setArray(array); + array->setInfoOnComponent(0,"power [W]"); + array->setInfoOnComponent(1,"temperature"); + f->setName("MyFieldOnGaussNE"); + array->decrRef(); + f->checkCoherency(); + m->decrRef(); + return f; +} + diff --git a/src/medtool/src/MEDLoader/Test/MEDLoaderTest.hxx b/src/medtool/src/MEDLoader/Test/MEDLoaderTest.hxx new file mode 100644 index 000000000..e0e842995 --- /dev/null +++ b/src/medtool/src/MEDLoader/Test/MEDLoaderTest.hxx @@ -0,0 +1,95 @@ +// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 +// 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 __MEDLOADERTEST_HXX__ +#define __MEDLOADERTEST_HXX__ + +#include <cppunit/extensions/HelperMacros.h> + +namespace ParaMEDMEM +{ + class MEDCouplingUMesh; + class MEDCouplingFieldDouble; + + class MEDLoaderTest : public CppUnit::TestFixture + { + CPPUNIT_TEST_SUITE(MEDLoaderTest); + CPPUNIT_TEST( testMesh1DRW ); + CPPUNIT_TEST( testMesh2DCurveRW ); + CPPUNIT_TEST( testMesh2DRW ); + CPPUNIT_TEST( testMesh3DSurfRW ); + CPPUNIT_TEST( testMesh3DRW ); + CPPUNIT_TEST( testFieldRW1 ); + CPPUNIT_TEST( testFieldRW2 ); + CPPUNIT_TEST( testFieldRW3 ); + CPPUNIT_TEST( testMultiMeshRW1 ); + CPPUNIT_TEST( testFieldProfilRW1 ); + CPPUNIT_TEST( testFieldNodeProfilRW1 ); + CPPUNIT_TEST( testFieldNodeProfilRW2 ); + CPPUNIT_TEST( testFieldGaussRW1 ); + CPPUNIT_TEST( testFieldGaussNERW1 ); + CPPUNIT_TEST( testLittleStrings1 ); + CPPUNIT_TEST( testSplitIntoNameAndUnit1 ); + CPPUNIT_TEST( testMesh3DSurfShuffleRW ); + CPPUNIT_TEST( testFieldShuffleRW1 ); + CPPUNIT_TEST( testMultiFieldShuffleRW1 ); + CPPUNIT_TEST( testWriteUMeshesRW1 ); + CPPUNIT_TEST( testMixCellAndNodesFieldRW1 ); + CPPUNIT_TEST( testGetAllFieldNamesRW1 ); + CPPUNIT_TEST_SUITE_END(); + public: + void testMesh1DRW(); + void testMesh2DCurveRW(); + void testMesh2DRW(); + void testMesh3DSurfRW(); + void testMesh3DRW(); + void testFieldRW1(); + void testFieldRW2(); + void testFieldRW3(); + void testMultiMeshRW1(); + void testFieldProfilRW1(); + void testFieldNodeProfilRW1(); + void testFieldNodeProfilRW2(); + void testFieldGaussRW1(); + void testFieldGaussNERW1(); + void testLittleStrings1(); + void testSplitIntoNameAndUnit1(); + void testMesh3DSurfShuffleRW(); + void testFieldShuffleRW1(); + void testMultiFieldShuffleRW1(); + void testWriteUMeshesRW1(); + void testMixCellAndNodesFieldRW1(); + void testGetAllFieldNamesRW1(); + private: + MEDCouplingUMesh *build1DMesh_1(); + MEDCouplingUMesh *build2DCurveMesh_1(); + MEDCouplingUMesh *build2DMesh_1(); + MEDCouplingUMesh *build2DMesh_2(); + MEDCouplingUMesh *build3DSurfMesh_1(); + MEDCouplingUMesh *build3DMesh_1(); + MEDCouplingUMesh *build3DMesh_2(); + MEDCouplingFieldDouble *buildVecFieldOnCells_1(); + MEDCouplingFieldDouble *buildVecFieldOnNodes_1(); + MEDCouplingFieldDouble *buildVecFieldOnGauss_1(); + MEDCouplingFieldDouble *buildVecFieldOnGaussNE_1(); + }; +} + +#endif diff --git a/src/medtool/src/MEDLoader/Test/SauvLoaderTest.cxx b/src/medtool/src/MEDLoader/Test/SauvLoaderTest.cxx new file mode 100644 index 000000000..b6195f6df --- /dev/null +++ b/src/medtool/src/MEDLoader/Test/SauvLoaderTest.cxx @@ -0,0 +1,354 @@ +// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// + +#include "SauvLoaderTest.hxx" + +#include "SauvReader.hxx" +#include "SauvWriter.hxx" +#include "MEDFileData.hxx" +#include "MEDCouplingFieldDouble.hxx" +#include "MEDCouplingMemArray.hxx" + +#ifdef WIN32 +# include <windows.h> +#else +# include <unistd.h> +#endif + +#include <vector> +#include <string> + +using namespace ParaMEDMEM; + +void SauvLoaderTest::testSauv2Med() +{ + // read a file containing all types of readable piles + std::string file = getResourceFile("allPillesTest.sauv"); + MEDCouplingAutoRefCountObjectPtr<SauvReader> sr=SauvReader::New(file.c_str()); + MEDCouplingAutoRefCountObjectPtr<MEDFileData> d2=sr->loadInMEDFileDS(); + // write MED + d2->write("allPillesTest.med",0); + // check + CPPUNIT_ASSERT_EQUAL(1,d2->getNumberOfMeshes()); + CPPUNIT_ASSERT_EQUAL(8+97,d2->getNumberOfFields()); + MEDFileMesh * m = d2->getMeshes()->getMeshAtPos(0); + CPPUNIT_ASSERT_EQUAL(17,int(m->getGroupsNames().size())); +} + +void SauvLoaderTest::testMed2SauvOnAMeshWithVoidFamily() +{ + // Create a mesh with 2 quads. + const int spaceDim = 2; + const int nbOfNodes = 6; + double coords[nbOfNodes*spaceDim] = {0,0, 1,0, 1,1, 0,1, 2,0, 2,1}; + int conn[8]={0,1,2,3, 1,4,5,2}; + MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> mesh2d=MEDCouplingUMesh::New("Mesh",spaceDim); + mesh2d->allocateCells(2); + mesh2d->insertNextCell(INTERP_KERNEL::NORM_QUAD4,4,conn); + mesh2d->insertNextCell(INTERP_KERNEL::NORM_QUAD4,4,conn+4); + mesh2d->finishInsertingCells(); + MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> myCoords=DataArrayDouble::New(); + myCoords->alloc(nbOfNodes,spaceDim); + std::copy(coords,coords+nbOfNodes*spaceDim,myCoords->getPointer()); + mesh2d->setCoords(myCoords); + + // create a MedFileUMesh + MEDCouplingAutoRefCountObjectPtr<MEDFileUMesh> m= MEDFileUMesh::New(); + m->setMeshAtLevel(0,mesh2d); + + // Create families and groups + + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> fam = DataArrayInt::New(); + fam->alloc(2,1); + int elemsFams[2] = {-2,-3}; + std::copy(elemsFams,elemsFams+2,fam->getPointer()); + + m->setFamilyFieldArr(0,fam); + + std::map<std::string,int> theFamilies; + theFamilies["FAM_-1"]=-1; + theFamilies["FAM_-2"]=-2; + theFamilies["FAM_-3"]=-3; + + std::map<std::string, std::vector<std::string> > theGroups; + theGroups["Group1"].push_back("FAM_-2"); + theGroups["Group2"].push_back("FAM_-3"); + theGroups["Grouptot"].push_back("FAM_-1"); + theGroups["Grouptot"].push_back("FAM_-2"); + theGroups["Grouptot"].push_back("FAM_-3"); + m->setFamilyInfo(theFamilies); + m->setGroupInfo(theGroups); + + // write to MED for visual check + //const char* medFile = "mesh_with_void_family.med"; + //m->write(medFile, 2); + + // write to SAUV + const char* sauvFile = "mesh_with_void_family.sauv"; + MEDCouplingAutoRefCountObjectPtr<MEDFileData> medData = MEDFileData::New(); + MEDCouplingAutoRefCountObjectPtr<MEDFileMeshes> medMeshes = MEDFileMeshes::New(); + MEDCouplingAutoRefCountObjectPtr<SauvWriter> sw=SauvWriter::New(); + medMeshes->setMeshAtPos(0, m); + medData->setMeshes(medMeshes); + sw->setMEDFileDS(medData); + sw->write(sauvFile); + + // read SAUV and check groups + MEDCouplingAutoRefCountObjectPtr<SauvReader> sr=SauvReader::New(sauvFile); + MEDCouplingAutoRefCountObjectPtr<MEDFileData> d2=sr->loadInMEDFileDS(); + MEDFileUMesh* m2 = static_cast<MEDFileUMesh*>( d2->getMeshes()->getMeshAtPos(0) ); + MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> group1 = m2->getGroup(0, "Group1"); + CPPUNIT_ASSERT_EQUAL(1,(int)group1->getNumberOfCells()); + MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> group2 = m2->getGroup(0, "Group2"); + CPPUNIT_ASSERT_EQUAL(1,(int)group2->getNumberOfCells()); + MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> grptot = m2->getGroup(0, "Grouptot"); + CPPUNIT_ASSERT_EQUAL(2,(int)grptot->getNumberOfCells()); +} + +void SauvLoaderTest::testSauv2MedOnA3SubsField() +{ + // read SAUV + std::string sauvFile = getResourceFile("portico_3subs.sauv"); + MEDCouplingAutoRefCountObjectPtr<SauvReader> sr=SauvReader::New(sauvFile.c_str()); + MEDCouplingAutoRefCountObjectPtr<MEDFileData> d2=sr->loadInMEDFileDS(); + // check mesh + MEDFileUMesh* m2 = static_cast<MEDFileUMesh*>(d2->getMeshes()->getMeshAtPos(0)); + MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> mesh1d = m2->getMeshAtLevel(0); + MEDCouplingAutoRefCountObjectPtr<MEDCouplingFieldDouble> length1dField = mesh1d->getMeasureField(0); + std::cout << "Length of 1d elements: " << length1dField->accumulate(0) << std::endl; + CPPUNIT_ASSERT_DOUBLES_EQUAL(3, length1dField->accumulate(0), 1e-12); + // check field + MEDCouplingAutoRefCountObjectPtr<MEDFileFieldMultiTS> field = + dynamic_cast<MEDFileFieldMultiTS *>(d2->getFields()->getFieldWithName("CHAM1D")); + std::cout << "Number of components in field: " << field->getInfo().size() << std::endl; + CPPUNIT_ASSERT_EQUAL(6,(int)field->getInfo().size()); + std::vector< std::pair<int,int> > timesteps = field->getIterations(); + + MEDCouplingAutoRefCountObjectPtr<MEDCouplingFieldDouble> field1d = + field->getFieldOnMeshAtLevel(ON_GAUSS_NE, timesteps[0].first, timesteps[0].second, 0, m2); + + // Check first component of the field + // 2 gauss points per element => 12 values + double values[12] = { + -7.687500000000e-03, + -7.687500000000e-03, + -4.562500000000e-03, + -4.562500000000e-03, + -8.208333333333e-03, + -8.208333333333e-03, + -6.125000000000e-03, + -6.125000000000e-03, + -4.041666666666e-03, + -4.041666666666e-03, + -6.111413346910e-07, + -6.111413346910e-07}; + + for (int i=0; i < field1d->getNumberOfTuples(); i++) + { + CPPUNIT_ASSERT_DOUBLES_EQUAL( values[i], field1d->getIJ(i, 0), 1e-12 ); + } +} + +void SauvLoaderTest::testMed2Sauv() +{ + // read pointe.med + std::string file = getResourceFile("pointe.med"); + MEDCouplingAutoRefCountObjectPtr<MEDFileData> pointeMed=MEDFileData::New(file.c_str()); + + // add 3 faces to pointeMed + MEDFileUMesh* pointeMedMesh = static_cast<MEDFileUMesh*>(pointeMed->getMeshes()->getMeshAtPos(0)); + MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> pointeM1D = MEDCouplingUMesh::New(); + DataArrayDouble *coords = pointeMedMesh->getCoords(); + pointeM1D->setCoords( coords ); + pointeM1D->setMeshDimension( 2 ); + pointeM1D->allocateCells( 3 ); + int conn[]= + { + 0,1,2, 0,1,3, 10,11,12,13 + }; + pointeM1D->insertNextCell( INTERP_KERNEL::NORM_TRI3, 3, conn); + pointeM1D->insertNextCell( INTERP_KERNEL::NORM_TRI3, 3, conn+3); + pointeM1D->insertNextCell( INTERP_KERNEL::NORM_QUAD4, 4, conn+6); + pointeM1D->finishInsertingCells(); + pointeMedMesh->setMeshAtLevel( -1, pointeM1D ); + pointeMed->getMeshes()->setMeshAtPos( 0, pointeMedMesh ); + + // add a field on 2 faces to pointeMed + MEDCouplingAutoRefCountObjectPtr<MEDFileFieldMultiTS> ff1=MEDFileFieldMultiTS::New(); + MEDCouplingAutoRefCountObjectPtr<MEDCouplingFieldDouble> f1=MEDCouplingFieldDouble::New(ON_GAUSS_NE,ONE_TIME); + f1->setMesh( pointeM1D ); + f1->setName("Field on 2 faces"); + MEDCouplingAutoRefCountObjectPtr<DataArrayDouble> d=DataArrayDouble::New(); + d->alloc(3+4,2); + d->setInfoOnComponent(0,"sigX [MPa]"); + d->setInfoOnComponent(1,"sigY [GPa]"); + double vals[2*(3+4)] = + { + 311,312,321,322,331,332,411,412,421,422,431,432,441,442 + }; + std::copy(vals,vals+d->getNbOfElems(),d->getPointer()); + f1->setArray(d); + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> da=DataArrayInt::New(); + int ids[] = + { + 0,2 + }; + da->alloc(2,1); + std::copy(ids,ids+da->getNbOfElems(),da->getPointer()); + da->setName("sup2"); + ff1->appendFieldProfile(f1,pointeMedMesh,-1,da); + pointeMed->getFields()->pushField( ff1 ); + + // remove "fieldnodeint" + MEDFileFields* pointeFields = pointeMed->getFields(); + for ( int i = 0; i < pointeFields->getNumberOfFields(); ++i ) + { + MEDCouplingAutoRefCountObjectPtr<MEDFileAnyTypeFieldMultiTS> ts = pointeFields->getFieldAtPos(i); + if ( std::string("fieldnodeint") == ts->getName()) + { + pointeFields->destroyFieldAtPos( i ); + break; + } + } + // write pointeMed to SAUV + const char* sauvFile = "pointe.sauv"; + MEDCouplingAutoRefCountObjectPtr<SauvWriter> sw=SauvWriter::New(); + sw->setMEDFileDS(pointeMed); + sw->write(sauvFile); + + // read SAUV and check + MEDCouplingAutoRefCountObjectPtr<SauvReader> sr=SauvReader::New(sauvFile); + MEDCouplingAutoRefCountObjectPtr<MEDFileData> d2=sr->loadInMEDFileDS(); + CPPUNIT_ASSERT_EQUAL(1,d2->getNumberOfMeshes()); + CPPUNIT_ASSERT_EQUAL(4,d2->getNumberOfFields()); + MEDFileUMesh * m = static_cast<MEDFileUMesh*>( d2->getMeshes()->getMeshAtPos(0) ); + CPPUNIT_ASSERT_EQUAL(std::string("maa1"),std::string(m->getName() )); + CPPUNIT_ASSERT_EQUAL(3,m->getMeshDimension()); + std::vector<std::string > groups = m->getGroupsNames(); + CPPUNIT_ASSERT_EQUAL(6,(int)groups.size()); + CPPUNIT_ASSERT( std::find(groups.begin(),groups.end(),"groupe1") != groups.end() ); + CPPUNIT_ASSERT( std::find(groups.begin(),groups.end(),"groupe2") != groups.end() ); + CPPUNIT_ASSERT( std::find(groups.begin(),groups.end(),"groupe3") != groups.end() ); + CPPUNIT_ASSERT( std::find(groups.begin(),groups.end(),"groupe4") != groups.end() ); + CPPUNIT_ASSERT( std::find(groups.begin(),groups.end(),"groupe5") != groups.end() ); + CPPUNIT_ASSERT( std::find(groups.begin(),groups.end(),"maa1") != groups.end() ); + CPPUNIT_ASSERT_EQUAL(16,m->getSizeAtLevel(0)); + MEDCouplingAutoRefCountObjectPtr<MEDCouplingMesh> um0 = m->getGenMeshAtLevel(0); + CPPUNIT_ASSERT_EQUAL(12, um0->getNumberOfCellsWithType( INTERP_KERNEL::NORM_TETRA4 )); + CPPUNIT_ASSERT_EQUAL(2, um0->getNumberOfCellsWithType( INTERP_KERNEL::NORM_PYRA5 )); + CPPUNIT_ASSERT_EQUAL(2, um0->getNumberOfCellsWithType( INTERP_KERNEL::NORM_HEXA8 )); + MEDCouplingAutoRefCountObjectPtr<MEDCouplingMesh> um1 = m->getGenMeshAtLevel(-1); + CPPUNIT_ASSERT_EQUAL(2, um1->getNumberOfCellsWithType( INTERP_KERNEL::NORM_TRI3 )); + MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> pointeUM0 = + static_cast<MEDCouplingUMesh*>( pointeMedMesh->getGenMeshAtLevel(0)); + DataArrayDouble *coo = m->getCoords(); + DataArrayDouble *pointeCoo = pointeMedMesh->getCoords(); + CPPUNIT_ASSERT(coo->isEqualWithoutConsideringStr(*pointeCoo,1e-12)); + MEDCouplingAutoRefCountObjectPtr<MEDCouplingFieldDouble> vol = um0->getMeasureField(0); + MEDCouplingAutoRefCountObjectPtr<MEDCouplingFieldDouble> pointeVol = pointeUM0->getMeasureField(0); + CPPUNIT_ASSERT_DOUBLES_EQUAL( vol->accumulate(0), pointeVol->accumulate(0),1e-12); + // check fields + // fieldnodedouble + MEDCouplingAutoRefCountObjectPtr<MEDFileFieldMultiTS> fieldnodedoubleTS1 = + dynamic_cast<MEDFileFieldMultiTS *>(pointeMed->getFields()->getFieldWithName("fieldnodedouble")); + MEDCouplingAutoRefCountObjectPtr<MEDFileFieldMultiTS> fieldnodedoubleTS2 = + dynamic_cast<MEDFileFieldMultiTS *>(d2->getFields()->getFieldWithName("fieldnodedouble")); + CPPUNIT_ASSERT_EQUAL( fieldnodedoubleTS1->getInfo().size(), fieldnodedoubleTS2->getInfo().size()); + for ( size_t i = 0; i < fieldnodedoubleTS1->getInfo().size(); ++i ) + CPPUNIT_ASSERT_EQUAL( fieldnodedoubleTS1->getInfo()[i], fieldnodedoubleTS2->getInfo()[i]); + CPPUNIT_ASSERT_EQUAL( fieldnodedoubleTS1->getNumberOfTS(), fieldnodedoubleTS2->getNumberOfTS()); + std::vector< std::pair<int,int> > io1 = fieldnodedoubleTS1->getIterations(); + std::vector< std::pair<int,int> > io2 = fieldnodedoubleTS2->getIterations(); + for ( int i =0; i < fieldnodedoubleTS1->getNumberOfTS(); ++i ) + { + MEDCouplingAutoRefCountObjectPtr<MEDCouplingFieldDouble> fnd1 = + fieldnodedoubleTS1->getFieldOnMeshAtLevel(ON_NODES, io1[i].first,io1[i].second,pointeUM0); + MEDCouplingAutoRefCountObjectPtr<MEDCouplingFieldDouble> fnd2 = + fieldnodedoubleTS2->getFieldOnMeshAtLevel(ON_NODES, io2[i].first,io2[i].second,um0); + CPPUNIT_ASSERT( fnd1->getArray()->isEqual( *fnd2->getArray(), 1e-12 )); + } + // fieldcelldoublevector + MEDCouplingAutoRefCountObjectPtr<MEDFileFieldMultiTS> fieldcelldoublevectorTS1 = + dynamic_cast<MEDFileFieldMultiTS *>(pointeMed->getFields()->getFieldWithName("fieldcelldoublevector")); + MEDCouplingAutoRefCountObjectPtr<MEDFileFieldMultiTS> fieldcelldoublevectorTS2 = + dynamic_cast<MEDFileFieldMultiTS *>(d2->getFields()->getFieldWithName("fieldcelldoublevector")); + CPPUNIT_ASSERT_EQUAL( fieldcelldoublevectorTS1->getInfo().size(), fieldcelldoublevectorTS2->getInfo().size()); + for ( size_t i = 0; i < fieldcelldoublevectorTS1->getInfo().size(); ++i ) + CPPUNIT_ASSERT_EQUAL( fieldcelldoublevectorTS1->getInfo()[i], fieldcelldoublevectorTS2->getInfo()[i]); + CPPUNIT_ASSERT_EQUAL( fieldcelldoublevectorTS1->getNumberOfTS(), fieldcelldoublevectorTS2->getNumberOfTS()); + io1 = fieldcelldoublevectorTS1->getIterations(); + io2 = fieldcelldoublevectorTS2->getIterations(); + for ( int i =0; i < fieldcelldoublevectorTS1->getNumberOfTS(); ++i ) + { + MEDCouplingAutoRefCountObjectPtr<MEDCouplingFieldDouble> fnd1 = + fieldcelldoublevectorTS1->getFieldOnMeshAtLevel(ON_CELLS, io1[i].first,io1[i].second,pointeUM0); + MEDCouplingAutoRefCountObjectPtr<MEDCouplingFieldDouble> fnd2 = + fieldcelldoublevectorTS2->getFieldOnMeshAtLevel(ON_CELLS, io2[i].first,io2[i].second,um0); + CPPUNIT_ASSERT_DOUBLES_EQUAL( fnd1->accumulate(0), fnd2->accumulate(0), 1e-12 ); + CPPUNIT_ASSERT_DOUBLES_EQUAL( fnd1->accumulate(1), fnd2->accumulate(1), 1e-12 ); + CPPUNIT_ASSERT_DOUBLES_EQUAL( fnd1->accumulate(2), fnd2->accumulate(2), 1e-12 ); + } + // "Field on 2 faces" + MEDCouplingAutoRefCountObjectPtr<MEDFileFieldMultiTS> fieldOnFaces = + dynamic_cast<MEDFileFieldMultiTS *>(d2->getFields()->getFieldWithName(f1->getName().c_str())); + io1 = fieldOnFaces->getIterations(); + MEDCouplingAutoRefCountObjectPtr<MEDCouplingFieldDouble> fof = + fieldOnFaces->getFieldOnMeshAtLevel(f1->getTypeOfField(),io1[0].first,io1[0].second,um1); + CPPUNIT_ASSERT( d->isEqual( *fof->getArray(), 1e-12 )); +} + +void SauvLoaderTest::tearDown() +{ + const int nbFilesToRemove = 3; + const char* fileToRemove[nbFilesToRemove] = { "allPillesTest.med", "pointe.sauv", "mesh_with_void_family.sauv" }; + for ( int i = 0; i < nbFilesToRemove; ++i ) + { +#ifdef WIN32 + if (GetFileAttributes(fileToRemove[i]) != INVALID_FILE_ATTRIBUTES) +#else + if (access(fileToRemove[i], F_OK) == 0) +#endif + remove(fileToRemove[i]); + } +} + +std::string SauvLoaderTest::getResourceFile( const std::string& filename ) +{ + std::string resourceFile = ""; + + if ( getenv("top_srcdir") ) { + // we are in 'make test' step + resourceFile = getenv("top_srcdir"); + resourceFile += "/resources/"; + } + else if ( getenv("MED_ROOT_DIR") ) { + // use MED_ROOT_DIR env.var + resourceFile = getenv("MED_ROOT_DIR"); + resourceFile += "/share/salome/resources/med/"; + } + resourceFile += filename; +#ifdef WIN32 + std::string fixedpath = resourceFile; + for ( int i=0; i < fixedpath.length(); ++i ) + if (fixedpath[i] == '/') + fixedpath[i] = '\\'; + return fixedpath; +#endif + return resourceFile; +} diff --git a/src/medtool/src/MEDLoader/Test/SauvLoaderTest.hxx b/src/medtool/src/MEDLoader/Test/SauvLoaderTest.hxx new file mode 100644 index 000000000..586285cad --- /dev/null +++ b/src/medtool/src/MEDLoader/Test/SauvLoaderTest.hxx @@ -0,0 +1,49 @@ +// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 +// 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 __SauvLoaderTest_HXX__ +#define __SauvLoaderTest_HXX__ + +#include <cppunit/extensions/HelperMacros.h> + +#include "MEDLoaderTest.hxx" + +namespace ParaMEDMEM +{ + class SauvLoaderTest : public CppUnit::TestFixture + { + CPPUNIT_TEST_SUITE(SauvLoaderTest); + CPPUNIT_TEST( testSauv2Med ); + CPPUNIT_TEST( testMed2Sauv ); + CPPUNIT_TEST( testMed2SauvOnAMeshWithVoidFamily ); + CPPUNIT_TEST( testSauv2MedOnA3SubsField ); + CPPUNIT_TEST_SUITE_END(); + public: + void testSauv2Med(); + void testMed2Sauv(); + void testMed2SauvOnAMeshWithVoidFamily(); + void testSauv2MedOnA3SubsField(); + + public: + void tearDown(); + static std::string getResourceFile( const std::string& filename ); + }; +} + +#endif diff --git a/src/medtool/src/MEDLoader/Test/TestMEDLoader.cxx b/src/medtool/src/MEDLoader/Test/TestMEDLoader.cxx new file mode 100644 index 000000000..8800a0405 --- /dev/null +++ b/src/medtool/src/MEDLoader/Test/TestMEDLoader.cxx @@ -0,0 +1,26 @@ +// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 +// 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 "CppUnitTest.hxx" +#include "MEDLoaderTest.hxx" + +CPPUNIT_TEST_SUITE_REGISTRATION( ParaMEDMEM::MEDLoaderTest ); + +#include "BasicMainTest.hxx" diff --git a/src/medtool/src/MEDLoader/Test/TestSauvLoader.cxx b/src/medtool/src/MEDLoader/Test/TestSauvLoader.cxx new file mode 100644 index 000000000..4fdbcdbce --- /dev/null +++ b/src/medtool/src/MEDLoader/Test/TestSauvLoader.cxx @@ -0,0 +1,25 @@ +// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// + +#include "CppUnitTest.hxx" +#include "SauvLoaderTest.hxx" + +CPPUNIT_TEST_SUITE_REGISTRATION( ParaMEDMEM::SauvLoaderTest ); + +#include "BasicMainTest.hxx" diff --git a/src/medtool/src/MEDPartitioner/CMakeLists.txt b/src/medtool/src/MEDPartitioner/CMakeLists.txt new file mode 100644 index 000000000..d1642c5cf --- /dev/null +++ b/src/medtool/src/MEDPartitioner/CMakeLists.txt @@ -0,0 +1,147 @@ +# Copyright (C) 2012-2015 CEA/DEN, EDF 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, 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 +# 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_DEFINITIONS(${HDF5_DEFINITIONS} ${MEDFILE_DEFINITIONS} ${LIBXML2_DEFINITIONS}) + +INCLUDE_DIRECTORIES( + ${LIBXML2_INCLUDE_DIR} + ${MEDFILE_INCLUDE_DIRS} + ${HDF5_INCLUDE_DIRS} + ${PTHREAD_INCLUDE_DIR} + ${CMAKE_CURRENT_SOURCE_DIR}/../MEDLoader + ${CMAKE_CURRENT_SOURCE_DIR}/../MEDCoupling + ${CMAKE_CURRENT_SOURCE_DIR}/../INTERP_KERNEL + ${CMAKE_CURRENT_SOURCE_DIR}/../INTERP_KERNEL/Bases + ${CMAKE_CURRENT_SOURCE_DIR}/../INTERP_KERNEL/Geometric2D + ${CMAKE_CURRENT_SOURCE_DIR}/../INTERP_KERNEL/ExprEval + ${CMAKE_CURRENT_SOURCE_DIR}/../INTERP_KERNEL/GaussPoints + ) + +IF(SALOME_MED_PARTITIONER_METIS) + ADD_DEFINITIONS(${METIS_DEFINITIONS}) + IF(MEDTOOL_METIS_V5) + ADD_DEFINITIONS("-DMED_ENABLE_METIS_V5") + ENDIF(MEDTOOL_METIS_V5) + INCLUDE_DIRECTORIES(${METIS_INCLUDE_DIRS}) +ENDIF(SALOME_MED_PARTITIONER_METIS) + + +######## +# VERY IMPORTANT PUT METIS BEFORE SCOTCH because +# metis.h is also in SCOTCH install dir !!! +######## +IF(SALOME_MED_PARTITIONER_SCOTCH) + ADD_DEFINITIONS(${SCOTCH_DEFINITIONS}) + INCLUDE_DIRECTORIES(${SCOTCH_INCLUDE_DIRS}) +ENDIF(SALOME_MED_PARTITIONER_SCOTCH) + +IF(SALOME_MED_PARTITIONER_PARMETIS) + ADD_DEFINITIONS(${PARMETIS_DEFINITIONS}) + INCLUDE_DIRECTORIES(${PARMETIS_INCLUDE_DIRS}) +ENDIF(SALOME_MED_PARTITIONER_PARMETIS) + +IF(SALOME_USE_MPI) + ADD_DEFINITIONS(${MPI_DEFINITIONS}) + INCLUDE_DIRECTORIES(${MPI_INCLUDE_DIRS}) +ENDIF(SALOME_USE_MPI) + +IF(SALOME_BUILD_TESTS) + ADD_SUBDIRECTORY(Test) +ENDIF(SALOME_BUILD_TESTS) + +SET(medpartitionercpp_HEADERS_HXX + MEDPARTITIONER_MeshCollection.hxx + MEDPARTITIONER_MeshCollectionDriver.hxx + MEDPARTITIONER_MeshCollectionMedXmlDriver.hxx + MEDPARTITIONER_MeshCollectionMedAsciiDriver.hxx + MEDPARTITIONER_ParallelTopology.hxx + MEDPARTITIONER_JointFinder.hxx + MEDPARTITIONER_Graph.hxx + MEDPARTITIONER_UserGraph.hxx + MEDPARTITIONER_Utils.hxx + MEDPARTITIONER.hxx + MEDPARTITIONER_ParaDomainSelector.hxx + MEDPARTITIONER_ConnectZone.hxx + MEDPARTITIONER_Topology.hxx + MEDPARTITIONER_MEDPartitioner.hxx + ) + +SET(medpartitionercpp_SOURCES + MEDPARTITIONER_MeshCollection.cxx + MEDPARTITIONER_MeshCollectionDriver.cxx + MEDPARTITIONER_MeshCollectionMedXmlDriver.cxx + MEDPARTITIONER_MeshCollectionMedAsciiDriver.cxx + MEDPARTITIONER_ParallelTopology.cxx + MEDPARTITIONER_Graph.cxx + MEDPARTITIONER_UserGraph.cxx + MEDPARTITIONER_Utils.cxx + MEDPARTITIONER_ParaDomainSelector.cxx + MEDPARTITIONER_ConnectZone.cxx + MEDPARTITIONER_metis.c + MEDPARTITIONER_MEDPartitioner.cxx + ) + +SET(medpartitionercpp_LDFLAGS + ${MEDFILE_C_LIBRARIES} + ${HDF5_LIBRARIES} + ${STDLIB} + ${LIBXML2_LIBRARIES} + interpkernel + medcoupling + medloader +) +IF(SALOME_MED_PARTITIONER_PARMETIS) + SET(medpartitionercpp_HEADERS_HXX ${medpartitionercpp_HEADERS_HXX} MEDPARTITIONER_ParMetisGraph.hxx) + SET(medpartitionercpp_SOURCES ${medpartitionercpp_SOURCES} MEDPARTITIONER_ParMetisGraph.cxx MEDPARTITIONER_MetisGraph.cxx) + SET(medpartitionercpp_DEFINITIONS "${medpartitionercpp_DEFINITIONS} ${PARMETIS_DEFINITIONS}") + SET(medpartitionercpp_LDFLAGS ${medpartitionercpp_LDFLAGS} ${PARMETIS_LIBRARIES}) +ENDIF(SALOME_MED_PARTITIONER_PARMETIS) +IF(SALOME_MED_PARTITIONER_METIS) + SET(medpartitionercpp_HEADERS_HXX ${medpartitionercpp_HEADERS_HXX} MEDPARTITIONER_MetisGraph.hxx) + SET(medpartitionercpp_SOURCES ${medpartitionercpp_SOURCES} MEDPARTITIONER_MetisGraph.cxx) + SET(medpartitionercpp_DEFINITIONS "${medpartitionercpp_DEFINITIONS} ${METIS_DEFINITIONS}") + SET(medpartitionercpp_LDFLAGS ${medpartitionercpp_LDFLAGS} ${METIS_LIBRARIES}) +ENDIF(SALOME_MED_PARTITIONER_METIS) +IF(SALOME_MED_PARTITIONER_SCOTCH) + SET(medpartitionercpp_HEADERS_HXX ${medpartitionercpp_HEADERS_HXX} MEDPARTITIONER_ScotchGraph.hxx) + SET(medpartitionercpp_SOURCES ${medpartitionercpp_SOURCES} MEDPARTITIONER_ScotchGraph.cxx) + SET(medpartitionercpp_DEFINITIONS "${medpartitionercpp_DEFINITIONS} ${SCOTCH_DEFINITIONS}") + SET(medpartitionercpp_LDFLAGS ${medpartitionercpp_LDFLAGS} ${SCOTCH_LIBRARIES}) +ENDIF(SALOME_MED_PARTITIONER_SCOTCH) + +IF(${SALOME_USE_MPI}) + SET(medpartitionercpp_SOURCES ${medpartitionercpp_SOURCES} MEDPARTITIONER_UtilsPara.cxx MEDPARTITIONER_JointFinder.cxx) + ADD_EXECUTABLE(medpartitioner_para medpartitioner_para.cxx) + SET(medpartitionercpp_LDFLAGS ${medpartitionercpp_LDFLAGS} ${MPI_LIBRARIES}) + SET_TARGET_PROPERTIES(medpartitioner_para PROPERTIES COMPILE_FLAGS "${medpartitionercpp_DEFINITIONS}") + TARGET_LINK_LIBRARIES(medpartitioner_para medpartitionercpp ${medpartitionercpp_LDFLAGS}) + INSTALL(TARGETS medpartitioner_para DESTINATION ${SALOME_INSTALL_BINS}) +ENDIF(${SALOME_USE_MPI}) + +ADD_DEFINITIONS(${medpartitionercpp_DEFINITIONS}) + +ADD_LIBRARY(medpartitionercpp SHARED ${medpartitionercpp_SOURCES}) +TARGET_LINK_LIBRARIES(medpartitionercpp ${medpartitionercpp_LDFLAGS} ${PLATFORM_LIBS} ${PTHREAD_LIBS}) +INSTALL(TARGETS medpartitionercpp DESTINATION ${MEDTOOL_INSTALL_LIBS}) + +ADD_EXECUTABLE(medpartitioner medpartitioner.cxx) +TARGET_LINK_LIBRARIES(medpartitioner medpartitionercpp ${medpartitionercpp_LDFLAGS}) +INSTALL(TARGETS medpartitioner DESTINATION ${MEDTOOL_INSTALL_BINS}) + +INSTALL(FILES ${medpartitionercpp_HEADERS_HXX} DESTINATION ${MEDTOOL_INSTALL_HEADERS}) diff --git a/src/medtool/src/MEDPartitioner/MEDPARTITIONER.hxx b/src/medtool/src/MEDPartitioner/MEDPARTITIONER.hxx new file mode 100755 index 000000000..0996534cc --- /dev/null +++ b/src/medtool/src/MEDPartitioner/MEDPARTITIONER.hxx @@ -0,0 +1,33 @@ +// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// + +#ifndef __MEDPARTITIONER_HXX__ +#define __MEDPARTITIONER_HXX__ + +#ifdef WIN32 +# if defined MEDPARTITIONERCPP_EXPORTS || defined medpartitionercpp_EXPORTS +# define MEDPARTITIONER_EXPORT __declspec( dllexport ) +# else +# define MEDPARTITIONER_EXPORT __declspec( dllimport ) +# endif +#else +# define MEDPARTITIONER_EXPORT +#endif + +#endif diff --git a/src/medtool/src/MEDPartitioner/MEDPARTITIONER_ConnectZone.cxx b/src/medtool/src/MEDPartitioner/MEDPARTITIONER_ConnectZone.cxx new file mode 100644 index 000000000..402d66249 --- /dev/null +++ b/src/medtool/src/MEDPartitioner/MEDPARTITIONER_ConnectZone.cxx @@ -0,0 +1,339 @@ +// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// + +#include "MEDPARTITIONER_ConnectZone.hxx" + +#include "MEDCouplingSkyLineArray.hxx" + +#include <map> + +using namespace ParaMEDMEM; + +MEDPARTITIONER::ConnectZone::ConnectZone(): + _name("") + ,_description("") + ,_local_domain_number(0) + ,_distant_domain_number(0) + ,_node_corresp(0) + ,_face_corresp(0) +{ +} + +MEDPARTITIONER::ConnectZone::~ConnectZone() +{ + delete _node_corresp; + delete _face_corresp; + for(std::map < std::pair <int, int>,MEDCouplingSkyLineArray * >::iterator iter=_entity_corresp.begin(); iter!=_entity_corresp.end();iter++) + { + delete iter->second; + } +} + +MEDPARTITIONER::ConnectZone::ConnectZone(const ConnectZone & myConnectZone): + _name(myConnectZone._name) + ,_description(myConnectZone._description) + ,_local_domain_number(myConnectZone._local_domain_number) + ,_distant_domain_number(myConnectZone._distant_domain_number) + ,_node_corresp(myConnectZone._node_corresp) + ,_face_corresp(myConnectZone._face_corresp) + ,_entity_corresp(myConnectZone._entity_corresp) +{ +} + +std::string MEDPARTITIONER::ConnectZone::getName() const +{ + return _name; +} + +std::string MEDPARTITIONER::ConnectZone::getDescription() const +{ + return _description; +} + +int MEDPARTITIONER::ConnectZone::getDistantDomainNumber() const +{ + return _distant_domain_number; +} + +int MEDPARTITIONER::ConnectZone::getLocalDomainNumber() const +{ + return _local_domain_number; +} + +ParaMEDMEM::MEDCouplingUMesh *MEDPARTITIONER::ConnectZone::getLocalMesh() const +{ + return _local_mesh; +} + +ParaMEDMEM::MEDCouplingUMesh *MEDPARTITIONER::ConnectZone::getDistantMesh() const +{ + return _distant_mesh; +} + +bool MEDPARTITIONER::ConnectZone::isEntityCorrespPresent(int localEntity, int distantEntity) const +{ + typedef std::map<std::pair<int,int>, MEDCouplingSkyLineArray*>::const_iterator map_iter; + for(map_iter iter=_entity_corresp.begin(); iter != _entity_corresp.end(); iter++) + { + if ((iter->first).first==localEntity && (iter->first).second==distantEntity) + return true; + } + return false; +} + +const int *MEDPARTITIONER::ConnectZone::getNodeCorrespIndex() const +{ + return _node_corresp->getIndex(); +} + +const int *MEDPARTITIONER::ConnectZone::getNodeCorrespValue() const +{ + return _node_corresp->getValue(); +} + +int MEDPARTITIONER::ConnectZone::getNodeNumber() const +{ + return _node_corresp->getNumberOf(); +} + +const ParaMEDMEM::MEDCouplingSkyLineArray * MEDPARTITIONER::ConnectZone::getNodeCorresp() const +{ + return _node_corresp; +} + +const int *MEDPARTITIONER::ConnectZone::getFaceCorrespIndex() const +{ + return _face_corresp->getIndex(); +} + +const int *MEDPARTITIONER::ConnectZone::getFaceCorrespValue() const +{ + return _face_corresp->getValue(); +} + +int MEDPARTITIONER::ConnectZone::getFaceNumber() const +{ + return _face_corresp->getNumberOf(); +} + +const ParaMEDMEM::MEDCouplingSkyLineArray * MEDPARTITIONER::ConnectZone::getFaceCorresp() const +{ + return _face_corresp; +} + +const int *MEDPARTITIONER::ConnectZone::getEntityCorrespIndex(int localEntity, + int distantEntity) const +{ + typedef std::map<std::pair<int,int>, MEDCouplingSkyLineArray*>::const_iterator map_iter; + + for(map_iter iter=_entity_corresp.begin();iter!=_entity_corresp.end();iter++) + { + if ((iter->first).first==localEntity && (iter->first).second==distantEntity) + return iter->second->getIndex(); + } + return 0; +} + +const int *MEDPARTITIONER::ConnectZone::getEntityCorrespValue(int localEntity, + int distantEntity) const +{ + typedef std::map<std::pair<int,int>, MEDCouplingSkyLineArray*>::const_iterator map_iter; + + for (map_iter iter=_entity_corresp.begin();iter!=_entity_corresp.end();iter++) + { + if ((iter->first).first==localEntity && (iter->first).second==distantEntity) + return iter->second->getValue(); + } + return 0; +} + +int MEDPARTITIONER::ConnectZone::getEntityCorrespNumber(int localEntity, + int distantEntity) const +{ + typedef std::map<std::pair<int,int>, MEDCouplingSkyLineArray*>::const_iterator map_iter; + + for(map_iter iter=_entity_corresp.begin();iter!=_entity_corresp.end();iter++) + { + if((iter->first).first==localEntity && (iter->first).second==distantEntity) + return iter->second->getNumberOf(); + } + return 0; +} + +int MEDPARTITIONER::ConnectZone::getEntityCorrespLength(int localEntity, + int distantEntity) const +{ + typedef std::map<std::pair<int,int>, MEDCouplingSkyLineArray*>::const_iterator map_iter; + + for (map_iter iter=_entity_corresp.begin(); iter != _entity_corresp.end(); iter++) + { + if ((iter->first).first==localEntity && (iter->first).second==distantEntity) + return iter->second->getLength(); + } + return 0; +} + +const ParaMEDMEM::MEDCouplingSkyLineArray * +MEDPARTITIONER::ConnectZone::getEntityCorresp(int localEntity, int distantEntity) const +{ + typedef std::map<std::pair<int,int>, MEDCouplingSkyLineArray*>::const_iterator map_iter; + + for (map_iter iter=_entity_corresp.begin(); iter != _entity_corresp.end(); iter++) + { + if ((iter->first).first==localEntity && (iter->first).second==distantEntity) + return iter->second; + } + return 0; +} + +std::vector< std::pair< int,int > > MEDPARTITIONER::ConnectZone::getEntities() const +{ + std::vector< std::pair< int,int > > types; + + std::map<std::pair<int,int>, MEDCouplingSkyLineArray*>::const_iterator + iter = _entity_corresp.begin(); + for ( ; iter != _entity_corresp.end(); iter++) + { + types.push_back( iter->first ); + } + + return types; +} + +void MEDPARTITIONER::ConnectZone::setName(const std::string& name) +{ + _name=name; +} + +void MEDPARTITIONER::ConnectZone::setDescription(const std::string& description) +{ + _description=description; +} + +void MEDPARTITIONER::ConnectZone::setDistantDomainNumber(int distantDomainNumber) +{ + _distant_domain_number=distantDomainNumber; +} + +void MEDPARTITIONER::ConnectZone::setLocalDomainNumber(int localDomainNumber) +{ + _local_domain_number=localDomainNumber; +} + +void MEDPARTITIONER::ConnectZone::setLocalMesh(ParaMEDMEM::MEDCouplingUMesh * localMesh) +{ + _local_mesh=localMesh; +} + +void MEDPARTITIONER::ConnectZone::setDistantMesh(ParaMEDMEM::MEDCouplingUMesh * distantMesh) +{ + _distant_mesh=distantMesh; +} + +/*! transforms an int array containing + * the node-node connections + * to a MEDCouplingSkyLineArray + */ +void MEDPARTITIONER::ConnectZone::setNodeCorresp(const int * nodeCorresp, int nbnode) +{ + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> indexArr( DataArrayInt::New() ); + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> valueArr( DataArrayInt::New() ); + indexArr->alloc( nbnode+1 ); + valueArr->alloc( 2*nbnode ); + int * index = indexArr->getPointer(); + int * value = valueArr->getPointer(); + for (int i=0; i<nbnode; i++) + { + index[i]=2*i; + value[2*i ]=nodeCorresp[2*i]; + value[2*i+1]=nodeCorresp[2*i+1]; + } + index[nbnode]=2*nbnode; + setNodeCorresp( new MEDCouplingSkyLineArray( indexArr, valueArr )); +} + +void MEDPARTITIONER::ConnectZone::setNodeCorresp(MEDCouplingSkyLineArray* array) +{ + if ( _node_corresp ) delete _node_corresp; + _node_corresp = array; +} + +/*! transforms an int array containing + * the face-face connections + * to a MEDCouplingSkyLineArray + */ +void MEDPARTITIONER::ConnectZone::setFaceCorresp(const int * faceCorresp, int nbface) +{ + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> indexArr( DataArrayInt::New() ); + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> valueArr( DataArrayInt::New() ); + indexArr->alloc( nbface+1 ); + valueArr->alloc( 2*nbface ); + int * index = indexArr->getPointer(); + int * value = valueArr->getPointer(); + for (int i=0; i<nbface; i++) + { + index[i]=2*i; + value[2*i]=faceCorresp[2*i]; + value[2*i+1]=faceCorresp[2*i+1]; + } + index[nbface]=2*nbface; + setFaceCorresp( new MEDCouplingSkyLineArray( indexArr, valueArr )); +} + +void MEDPARTITIONER::ConnectZone::setFaceCorresp(MEDCouplingSkyLineArray* array) +{ + if ( _face_corresp ) delete _face_corresp; + _face_corresp = array; +} + +/*! transforms an int array containing + * the entity-entity connections + * to a MEDCouplingSkyLineArray + * + * the resulting MEDCouplingSkyLineArray is put in the map + */ +void MEDPARTITIONER::ConnectZone::setEntityCorresp(int localEntity, int distantEntity, + const int *entityCorresp, int nbentity) +{ + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> indexArr( DataArrayInt::New() ); + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> valueArr( DataArrayInt::New() ); + indexArr->alloc( nbentity+1 ); + valueArr->alloc( 2*nbentity ); + int * index = indexArr->getPointer(); + int * value = valueArr->getPointer(); + for (int i=0; i<nbentity; i++) + { + index[i]=2*i; + value[2*i ]=entityCorresp[2*i]; + value[2*i+1]=entityCorresp[2*i+1]; + } + index[nbentity]=2*nbentity; + setEntityCorresp( localEntity, distantEntity, new MEDCouplingSkyLineArray(indexArr,valueArr)); +} + +void MEDPARTITIONER::ConnectZone::setEntityCorresp(int localEntity, int distantEntity, + MEDCouplingSkyLineArray *array) +{ + ParaMEDMEM::MEDCouplingSkyLineArray * nullArray = 0; + std::map < std::pair <int,int>, ParaMEDMEM::MEDCouplingSkyLineArray * >::iterator it; + it = _entity_corresp.insert + ( std::make_pair( std::make_pair(localEntity,distantEntity), nullArray )).first; + if ( it->second != nullArray ) delete it->second; + it->second = array; +} diff --git a/src/medtool/src/MEDPartitioner/MEDPARTITIONER_ConnectZone.hxx b/src/medtool/src/MEDPartitioner/MEDPARTITIONER_ConnectZone.hxx new file mode 100644 index 000000000..9572db1c8 --- /dev/null +++ b/src/medtool/src/MEDPartitioner/MEDPARTITIONER_ConnectZone.hxx @@ -0,0 +1,102 @@ +// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// + +#ifndef __MEDPARTITIONER_CONNECTZONE_HXX__ +#define __MEDPARTITIONER_CONNECTZONE_HXX__ + +#include "MEDPARTITIONER.hxx" + +namespace ParaMEDMEM +{ + class MEDCouplingUMesh; + class MEDCouplingSkyLineArray; +} + +#include <map> +#include <vector> +#include <string> + +namespace MEDPARTITIONER +{ + class MEDPARTITIONER_EXPORT ConnectZone + { + public : + ConnectZone(); + ~ConnectZone(); + ConnectZone(const ConnectZone & myConnectZone); + + std::string getName() const ; + std::string getDescription() const ; + int getDistantDomainNumber() const ; + int getLocalDomainNumber() const ; + ParaMEDMEM::MEDCouplingUMesh *getLocalMesh() const ; + ParaMEDMEM::MEDCouplingUMesh *getDistantMesh() const ; + + bool isEntityCorrespPresent(int localEntity,int distantEntity) const; + const int *getNodeCorrespIndex() const; + const int *getNodeCorrespValue() const; + int getNodeNumber() const; + const ParaMEDMEM::MEDCouplingSkyLineArray * getNodeCorresp() const; + const int *getFaceCorrespIndex() const; + const int *getFaceCorrespValue() const; + int getFaceNumber() const; + const ParaMEDMEM::MEDCouplingSkyLineArray * getFaceCorresp() const; + const int *getEntityCorrespIndex(int localEntity, + int distantEntity) const; + const int *getEntityCorrespValue(int localEntity, + int distantEntity) const; + int getEntityCorrespNumber(int localEntity, + int distantEntity) const; + int getEntityCorrespLength(int localEntity, + int distantEntity) const; + const ParaMEDMEM::MEDCouplingSkyLineArray * getEntityCorresp(int localEntity, + int distantEntity) const; + std::vector< std::pair< int,int > > getEntities() const; + + void setName(const std::string& name) ; + void setDescription(const std::string& description) ; + void setDistantDomainNumber(int distantDomainNumber) ; + void setLocalDomainNumber(int distantDomainNumber) ; + void setLocalMesh(ParaMEDMEM::MEDCouplingUMesh * localMesh) ; + void setDistantMesh(ParaMEDMEM::MEDCouplingUMesh * distantMesh) ; + + void setNodeCorresp(const int * nodeCorresp, int nbnode); + void setNodeCorresp(ParaMEDMEM::MEDCouplingSkyLineArray* array); + void setFaceCorresp(const int * faceCorresp, int nbface); + void setFaceCorresp(ParaMEDMEM::MEDCouplingSkyLineArray* array); + void setEntityCorresp(int localEntity, int distantEntity, + const int * entityCorresp, int nbentity); + void setEntityCorresp(int localEntity, int distantEntity, + ParaMEDMEM::MEDCouplingSkyLineArray *array); + private : + std::string _name; + std::string _description; + int _local_domain_number; + int _distant_domain_number; + + ParaMEDMEM::MEDCouplingUMesh * _local_mesh; + ParaMEDMEM::MEDCouplingUMesh * _distant_mesh; + + ParaMEDMEM::MEDCouplingSkyLineArray * _node_corresp; + ParaMEDMEM::MEDCouplingSkyLineArray * _face_corresp; + + std::map < std::pair <int,int>, ParaMEDMEM::MEDCouplingSkyLineArray * > _entity_corresp; + }; +} +# endif diff --git a/src/medtool/src/MEDPartitioner/MEDPARTITIONER_Graph.cxx b/src/medtool/src/MEDPartitioner/MEDPARTITIONER_Graph.cxx new file mode 100644 index 000000000..1904ae4f5 --- /dev/null +++ b/src/medtool/src/MEDPartitioner/MEDPARTITIONER_Graph.cxx @@ -0,0 +1,56 @@ +// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// + +#include "MEDPARTITIONER_Graph.hxx" + +#include "MEDCouplingSkyLineArray.hxx" + +#include <set> + +MEDPARTITIONER::Graph::Graph(ParaMEDMEM::MEDCouplingSkyLineArray *array, int *edgeweight):_graph(array),_partition(0),_edge_weight(edgeweight),_cell_weight(0) +{ +} + +MEDPARTITIONER::Graph::~Graph() +{ + delete _partition; + delete _graph; +} + +int MEDPARTITIONER::Graph::nbDomains() const +{ + std::set<int> domains; + if ( _partition ) + if ( ParaMEDMEM::DataArrayInt* array = _partition->getValueArray() ) + { + for ( const int * dom = array->begin(); dom != array->end(); ++dom ) + domains.insert( *dom ); + } + return domains.size(); +} + +const int *MEDPARTITIONER::Graph::getPart() const +{ + return _partition->getValue(); +} + +int MEDPARTITIONER::Graph::nbVertices() const +{ + return _graph->getNumberOf(); +} diff --git a/src/medtool/src/MEDPartitioner/MEDPARTITIONER_Graph.hxx b/src/medtool/src/MEDPartitioner/MEDPARTITIONER_Graph.hxx new file mode 100644 index 000000000..12227bdb0 --- /dev/null +++ b/src/medtool/src/MEDPartitioner/MEDPARTITIONER_Graph.hxx @@ -0,0 +1,70 @@ +// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// + +#ifndef __MEDPARTITIONER_GRAPH_HXX__ +#define __MEDPARTITIONER_GRAPH_HXX__ + +#include "MEDPARTITIONER.hxx" + +#include <string> + +namespace ParaMEDMEM +{ + class MEDCouplingSkyLineArray; +} + +namespace MEDPARTITIONER +{ + class ParaDomainSelector; + class MEDPARTITIONER_EXPORT Graph + { + public: + typedef enum {METIS,SCOTCH} splitter_type; + + Graph(){}; + //creates a graph from a SKYLINEARRAY + Graph(ParaMEDMEM::MEDCouplingSkyLineArray* graph, int* edgeweight=0); + virtual ~Graph(); + + void setEdgesWeights(int *edgeweight) { _edge_weight=edgeweight; } + void setVerticesWeights(int *cellweight) { _cell_weight=cellweight; } + + //computes partitioning of the graph + virtual void partGraph(int ndomain, const std::string& options_string="", ParaDomainSelector *sel=0) = 0; + + //returns the partitioning + const int *getPart() const; + + //returns the number of graph vertices (which can correspond to the cells in the mesh!) + int nbVertices() const; + + // returns nb of domains in _partition + int nbDomains() const; + + const ParaMEDMEM::MEDCouplingSkyLineArray *getGraph() const { return _graph; } + const ParaMEDMEM::MEDCouplingSkyLineArray *getPartition() const { return _partition; } + + protected: + ParaMEDMEM::MEDCouplingSkyLineArray* _graph; + ParaMEDMEM::MEDCouplingSkyLineArray* _partition; + int* _edge_weight; + int* _cell_weight; + }; +} +#endif diff --git a/src/medtool/src/MEDPartitioner/MEDPARTITIONER_JointFinder.cxx b/src/medtool/src/MEDPartitioner/MEDPARTITIONER_JointFinder.cxx new file mode 100644 index 000000000..1e826eac7 --- /dev/null +++ b/src/medtool/src/MEDPartitioner/MEDPARTITIONER_JointFinder.cxx @@ -0,0 +1,212 @@ +// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// + +#include "MEDPARTITIONER_JointFinder.hxx" +#include "MEDPARTITIONER_MeshCollection.hxx" +#include "MEDPARTITIONER_Topology.hxx" +#include "MEDPARTITIONER_ParaDomainSelector.hxx" +#include "MEDPARTITIONER_Utils.hxx" + +#include "MEDCouplingUMesh.hxx" +#include "BBTree.txx" + +/*! + * Method contributing to the distant cell graph + */ +MEDPARTITIONER::JointFinder::JointFinder(const MeshCollection& mc):_mesh_collection(mc),_domain_selector(mc.getParaDomainSelector()),_topology(mc.getTopology()) +{ +} + +MEDPARTITIONER::JointFinder::~JointFinder() +{ +} + +void MEDPARTITIONER::JointFinder::findCommonDistantNodes() +{ + int nbdomain=_topology->nbDomain(); + _distant_node_cell.resize(nbdomain); + _node_node.resize(nbdomain); + for (int i=0; i<nbdomain; i++) + { + _distant_node_cell[i].resize(nbdomain); + _node_node[i].resize(nbdomain); + } + int nbproc=_domain_selector->nbProcs(); + std::vector<BBTreeOfDim* > bbtree(nbdomain,(BBTreeOfDim*) 0); + std::vector<double* > bbxi(nbdomain,(double*) 0); + std::vector<ParaMEDMEM::DataArrayInt*> rev(nbdomain,(ParaMEDMEM::DataArrayInt*) 0); + std::vector<ParaMEDMEM::DataArrayInt*> revIndx(nbdomain,(ParaMEDMEM::DataArrayInt*) 0); + int meshDim=-1; + int spaceDim=-1; + + //init rev and revIndx and bbtree for my domain (of me:proc n) + for (int mydomain=0; mydomain<nbdomain; mydomain++) + { + if(!_domain_selector->isMyDomain(mydomain)) + continue; + const ParaMEDMEM::MEDCouplingUMesh* myMesh=_mesh_collection.getMesh(mydomain); + meshDim = myMesh->getMeshDimension(); + spaceDim= myMesh->getSpaceDimension(); + rev[mydomain] = ParaMEDMEM::DataArrayInt::New(); + revIndx[mydomain] = ParaMEDMEM::DataArrayInt::New(); + myMesh->getReverseNodalConnectivity(rev[mydomain],revIndx[mydomain]); + double* bbx=new double[2*spaceDim*myMesh->getNumberOfNodes()]; + for (int i=0; i<myMesh->getNumberOfNodes()*spaceDim; i++) + { + const double* coords=myMesh->getCoords()->getConstPointer(); + bbx[2*i]=(coords[i])-1e-12; + bbx[2*i+1]=bbx[2*i]+2e-12; + } + bbtree[mydomain]=new BBTreeOfDim( spaceDim, bbx,0,0,myMesh->getNumberOfNodes(),-1e-12); + //keep bbx because need it in getIntersectingElems + //no delete [] bbx yet + bbxi[mydomain]=bbx; + } + + //send my domains to other proc an receive other domains from other proc + for (int isource=0; isource<nbdomain; isource++) + { + for (int itarget=0; itarget<nbdomain; itarget++) + { + const ParaMEDMEM::MEDCouplingUMesh* sourceMesh=_mesh_collection.getMesh(isource); + if (_domain_selector->isMyDomain(isource)&&_domain_selector->isMyDomain(itarget)) + continue; + if (_domain_selector->isMyDomain(isource)) + { + //preparing data for treatment on target proc + int targetProc = _domain_selector->getProcessorID(itarget); + + std::vector<double> vec(spaceDim*sourceMesh->getNumberOfNodes()); + std::copy(sourceMesh->getCoords()->getConstPointer(),sourceMesh->getCoords()->getConstPointer()+sourceMesh->getNumberOfNodes()*spaceDim,&vec[0]); + SendDoubleVec(vec,targetProc); + + //retrieving target data for storage in commonDistantNodes array + std::vector<int> localCorrespondency; + RecvIntVec(localCorrespondency, targetProc); + for (std::size_t i=0; i<localCorrespondency.size()/2; i++) + { + _distant_node_cell[isource][itarget].insert(std::make_pair(localCorrespondency[2*i],localCorrespondency[2*i+1])); + } + + } + + if (_domain_selector->isMyDomain(itarget)) + { + //receiving data from source proc + int sourceProc = isource%nbproc; + std::vector<double> recvVec; + RecvDoubleVec(recvVec,sourceProc); + std::map<int,int> commonNodes; // (local nodes, distant nodes) list + for (int inode=0; inode<(recvVec.size()/spaceDim); inode++) + { + double* bbox=new double[2*spaceDim]; + for (int i=0; i<spaceDim; i++) + { + bbox[2*i]=recvVec[inode*spaceDim+i]-1e-12; + bbox[2*i+1]=bbox[2*i]+2e-12; + } + std::vector<int> inodes; + bbtree[itarget]->getIntersectingElems(bbox,inodes); + delete [] bbox; + + if (inodes.size()>0) + { + commonNodes.insert(std::make_pair(inodes[0],inode)); + } + + } + std::vector<int> nodeCellCorrespondency; + for (std::map<int,int>::iterator iter=commonNodes.begin(); iter!=commonNodes.end(); iter++) + { + _node_node[itarget][isource].push_back(std::make_pair(iter->first, iter->second));//storing node pairs in a vector + const int* revIndxPtr=revIndx[itarget]->getConstPointer(); + const int* revPtr=rev[itarget]->getConstPointer(); + for (int icell=revIndxPtr[iter->first]; icell<revIndxPtr[iter->first+1]; icell++) + { + nodeCellCorrespondency.push_back(iter->second); // + int globalCell=_topology->convertCellToGlobal(itarget,revPtr[icell]); + nodeCellCorrespondency.push_back(globalCell); + } + } + SendIntVec(nodeCellCorrespondency, sourceProc); //itarget proc send to other (otherLocalNode-itargetGlobalCell) + } + } + } + + //free rev(nbdomain) revIndx(nbdomain) bbtree(nbdomain) bbxi(nbdomain) + for (int i=0; i<nbdomain; i++) + { + if (rev[i]!=0) + rev[i]->decrRef(); + if (revIndx[i]!=0) + revIndx[i]->decrRef(); + if (bbtree[i]!=0) + delete bbtree[i]; + if (bbxi[i]!=0) + delete [] bbxi[i]; + } + + if (MyGlobals::_Verbose>100) + std::cout << "proc " << _domain_selector->rank() << " : end JointFinder::findCommonDistantNodes" << std::endl; +} + +std::vector<std::vector<std::multimap<int,int> > >& MEDPARTITIONER::JointFinder::getDistantNodeCell() +{ + return _distant_node_cell; +} + +std::vector<std::vector<std::vector<std::pair<int,int> > > >& MEDPARTITIONER::JointFinder::getNodeNode() +{ + return _node_node; +} + +void MEDPARTITIONER::JointFinder::print() +//it is for debug on small arrays under mpi 2,3 cpus +{ + int nbdomain=_topology->nbDomain(); + //MPI_Barrier(MPI_COMM_WORLD); + if (MyGlobals::_Is0verbose>0) + std::cout << "\nJointFinder print node-node (nn)iproc|itarget|isource|i|inodefirst-inodesecond\n\n" << + "JointFinder print distantNode=cell (nc)iproc|itarget|isource|inode=icell\n\n"; + for (int isource=0; isource<nbdomain; isource++) + { + for (int itarget=0; itarget<nbdomain; itarget++) + { + for (std::size_t i=0; i<_node_node[itarget][isource].size(); i++) + std::cout << " nn" << _domain_selector->rank() << itarget << "|" << isource << "|" << i << "|" << + _node_node[itarget][isource][i].first << "-" << + _node_node[itarget][isource][i].second; + } + } + std::cout<<std::endl; + //MPI_Barrier(MPI_COMM_WORLD); + for (int isource=0; isource<nbdomain; isource++) + { + for (int itarget=0; itarget<nbdomain; itarget++) + { + std::multimap<int,int>::iterator it; + for (it=_distant_node_cell[isource][itarget].begin() ; it!=_distant_node_cell[isource][itarget].end(); it++) + { + std::cout << " nc" << _domain_selector->rank() << "|" << itarget << "|" << isource << "|" << (*it).first << "=" << (*it).second; + } + } + } + std::cout << std::endl; + //MPI_Barrier(MPI_COMM_WORLD); +} diff --git a/src/medtool/src/MEDPartitioner/MEDPARTITIONER_JointFinder.hxx b/src/medtool/src/MEDPartitioner/MEDPARTITIONER_JointFinder.hxx new file mode 100644 index 000000000..4fcc9ace6 --- /dev/null +++ b/src/medtool/src/MEDPartitioner/MEDPARTITIONER_JointFinder.hxx @@ -0,0 +1,52 @@ +// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// + +#ifndef __MEDPARTITIONER_JOINTFINDER_HXX__ +#define __MEDPARTITIONER_JOINTFINDER_HXX__ + +#include "MEDPARTITIONER.hxx" + +#include <map> +#include <vector> + +namespace MEDPARTITIONER +{ + class Topology; + class MeshCollection; + class ParaDomainSelector; + + class MEDPARTITIONER_EXPORT JointFinder + { + public: + JointFinder(const MeshCollection& mc); + ~JointFinder(); + void findCommonDistantNodes(); + void print(); + std::vector<std::vector<std::multimap<int,int> > >& getDistantNodeCell(); + std::vector<std::vector<std::vector<std::pair<int,int> > > >& getNodeNode(); + private: + const MeshCollection& _mesh_collection; + const ParaDomainSelector *_domain_selector; + const Topology *_topology; + std::vector<std::vector<std::multimap<int,int> > > _distant_node_cell; + std::vector<std::vector<std::vector<std::pair<int,int> > > > _node_node; + + }; +} +#endif diff --git a/src/medtool/src/MEDPartitioner/MEDPARTITIONER_MEDPartitioner.cxx b/src/medtool/src/MEDPartitioner/MEDPARTITIONER_MEDPartitioner.cxx new file mode 100644 index 000000000..57e9ae919 --- /dev/null +++ b/src/medtool/src/MEDPartitioner/MEDPARTITIONER_MEDPartitioner.cxx @@ -0,0 +1,161 @@ +// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// + +#include "MEDPARTITIONER_MEDPartitioner.hxx" +#include "MEDPARTITIONER_MeshCollection.hxx" +#include "MEDPARTITIONER_Topology.hxx" +#include "MEDPARTITIONER_ParaDomainSelector.hxx" +#include "MEDPARTITIONER_ParallelTopology.hxx" +#include "MEDPARTITIONER_Utils.hxx" +#include "MEDPARTITIONER_Graph.hxx" +#include "MEDPARTITIONER_MetisGraph.hxx" +#include "MEDPARTITIONER_ScotchGraph.hxx" +#include "MEDPARTITIONER_MeshCollectionDriver.hxx" + +#include "MEDCouplingUMesh.hxx" +#include "MEDCouplingSkyLineArray.hxx" + +#include <iostream> +#include <vector> + +MEDPARTITIONER::MEDPartitioner::MEDPartitioner(const std::string& filename, int ndomains, const std::string& library,bool creates_boundary_faces, bool create_joints, bool mesure_memory): + _input_collection( 0 ), _output_collection( 0 ), _new_topology( 0 ) +{ + MyGlobals::_World_Size = 1; + MyGlobals::_Rank = 0; + MyGlobals::_Creates_Boundary_Faces = creates_boundary_faces; + MyGlobals::_Create_Joints = create_joints; + + ParaDomainSelector parallelizer(mesure_memory); + _input_collection=new MeshCollection(filename,parallelizer); + _input_collection->setParaDomainSelector( ¶llelizer ); + + MEDPARTITIONER::ParallelTopology* aPT = + (MEDPARTITIONER::ParallelTopology*) _input_collection->getTopology(); + aPT->setGlobalNumerotationDefault( _input_collection->getParaDomainSelector() ); + _input_collection->prepareFieldDescriptions(); + createPartitionCollection(ndomains, library, creates_boundary_faces, create_joints, mesure_memory); + + parallelizer.evaluateMemory(); +} + +MEDPARTITIONER::MEDPartitioner::MEDPartitioner(const ParaMEDMEM::MEDFileData* filedata, int ndomains, const std::string& library,bool creates_boundary_faces, bool create_joints, bool mesure_memory): + _input_collection( 0 ), _output_collection( 0 ), _new_topology( 0 ) +{ + MyGlobals::_World_Size = 1; + MyGlobals::_Rank = 0; + MyGlobals::_Creates_Boundary_Faces = creates_boundary_faces; + MyGlobals::_Create_Joints = create_joints; + + ParaDomainSelector parallelizer(mesure_memory); + _input_collection=new MeshCollection(); + _input_collection->setParaDomainSelector( ¶llelizer ); + _input_collection->retrieveDriver()->readMEDFileData(filedata); + + MEDPARTITIONER::ParallelTopology* aPT = + (MEDPARTITIONER::ParallelTopology*) _input_collection->getTopology(); + aPT->setGlobalNumerotationDefault( _input_collection->getParaDomainSelector() ); + _input_collection->prepareFieldDescriptions(); + createPartitionCollection(ndomains, library, creates_boundary_faces, create_joints, mesure_memory); + + parallelizer.evaluateMemory(); +} + +MEDPARTITIONER::MEDPartitioner::MEDPartitioner(const ParaMEDMEM::MEDFileData* filedata, MEDPARTITIONER ::Graph* graph, bool creates_boundary_faces, bool create_joints, bool mesure_memory): + _input_collection( 0 ), _output_collection( 0 ), _new_topology( 0 ) +{ + MyGlobals::_World_Size = 1; + MyGlobals::_Rank = 0; + MyGlobals::_Creates_Boundary_Faces = creates_boundary_faces; + MyGlobals::_Create_Joints = create_joints; + + ParaDomainSelector parallelizer(mesure_memory); + _input_collection=new MeshCollection(); + _input_collection->setParaDomainSelector( ¶llelizer ); + _input_collection->retrieveDriver()->readMEDFileData(filedata); + + MEDPARTITIONER::ParallelTopology* aPT = + (MEDPARTITIONER::ParallelTopology*) _input_collection->getTopology(); + aPT->setGlobalNumerotationDefault( _input_collection->getParaDomainSelector() ); + _input_collection->prepareFieldDescriptions(); + + _new_topology = new MEDPARTITIONER::ParallelTopology( graph, aPT, graph->nbDomains(), _input_collection->getMeshDimension() ); + _output_collection=new MeshCollection(*_input_collection,_new_topology,false,false); + _output_collection->filterFaceOnCell(); + + parallelizer.evaluateMemory(); +} + +MEDPARTITIONER::MEDPartitioner::~MEDPartitioner() +{ + delete _input_collection; _input_collection = 0; + delete _output_collection; _output_collection = 0; + delete _new_topology; _new_topology = 0; +} + +void MEDPARTITIONER::MEDPartitioner::createPartitionCollection(int ndomains, const std::string& library,bool creates_boundary_faces, bool create_joints, bool mesure_memory) +{ + //ParallelTopology* aPT = (ParallelTopology*) _input_collection->getTopology(); + if (library == "metis") + _new_topology = _input_collection->createPartition(ndomains,MEDPARTITIONER::Graph::METIS); + else + _new_topology = _input_collection->createPartition(ndomains,MEDPARTITIONER::Graph::SCOTCH); + _output_collection=new MeshCollection(*_input_collection,_new_topology,false,false); + _output_collection->filterFaceOnCell(); +} + +void MEDPARTITIONER::MEDPartitioner::write(const std::string& filename) +{ + ParaDomainSelector parallelizer(false); + _output_collection->setParaDomainSelector( ¶llelizer ); + _output_collection->write(filename); + parallelizer.evaluateMemory(); +} + +ParaMEDMEM::MEDFileData* MEDPARTITIONER::MEDPartitioner::getMEDFileData() +{ + return _output_collection->retrieveDriver()->getMEDFileData(); +} + +MEDPARTITIONER::Graph* MEDPARTITIONER::MEDPartitioner::Graph(ParaMEDMEM::MEDCouplingSkyLineArray* graph, Graph::splitter_type split, int* edgeweight) +{ + MEDPARTITIONER::Graph* cellGraph=0; + ParaMEDMEM::MEDCouplingSkyLineArray* arr = new ParaMEDMEM::MEDCouplingSkyLineArray(graph->getIndexArray(), graph->getValueArray()); + switch (split) + { + case Graph::METIS: + if ( !cellGraph ) + { +#ifdef MED_ENABLE_METIS + cellGraph=new METISGraph(arr,edgeweight); +#endif + } + if ( !cellGraph ) + throw INTERP_KERNEL::Exception("MEDPartitioner::Graph : PARMETIS/METIS is not available. Check your products, please."); + break; + case Graph::SCOTCH: +#ifdef MED_ENABLE_SCOTCH + cellGraph=new SCOTCHGraph(arr,edgeweight); +#else + throw INTERP_KERNEL::Exception("MEDPartitioner::Graph : SCOTCH is not available. Check your products, please."); +#endif + break; + } + return cellGraph; +} diff --git a/src/medtool/src/MEDPartitioner/MEDPARTITIONER_MEDPartitioner.hxx b/src/medtool/src/MEDPartitioner/MEDPARTITIONER_MEDPartitioner.hxx new file mode 100644 index 000000000..fecaf0cc9 --- /dev/null +++ b/src/medtool/src/MEDPartitioner/MEDPARTITIONER_MEDPartitioner.hxx @@ -0,0 +1,59 @@ +// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// + +#ifndef __MEDPARTITIONER_MEDPARTITIONER_HXX__ +#define __MEDPARTITIONER_MEDPARTITIONER_HXX__ + +#include "MEDPARTITIONER.hxx" +#include "MEDPARTITIONER_Graph.hxx" + +#include <map> +#include <vector> + +namespace ParaMEDMEM +{ + class MEDFileData; +} + +namespace MEDPARTITIONER +{ + class Topology; + class MeshCollection; + + class MEDPARTITIONER_EXPORT MEDPartitioner + { + public: + MEDPartitioner(const std::string& filename, int ndomains=1, const std::string& library="metis",bool creates_boundary_faces=false, bool create_joints=false, bool mesure_memory=false); + MEDPartitioner(const ParaMEDMEM::MEDFileData* fileData, int ndomains=1, const std::string& library="metis",bool creates_boundary_faces=false, bool create_joints=false, bool mesure_memory=false); + MEDPartitioner(const ParaMEDMEM::MEDFileData* fileData, Graph* graph, bool creates_boundary_faces=false, bool create_joints=false, bool mesure_memory=false); + static MEDPARTITIONER::Graph* Graph(ParaMEDMEM::MEDCouplingSkyLineArray* graph, Graph::splitter_type split=Graph::METIS, int* edgeweight=0); + void write(const std::string& filename); + ParaMEDMEM::MEDFileData* getMEDFileData(); + ~MEDPartitioner(); + + ParaMEDMEM::MEDFileData *convertToMEDFileData(MeshCollection* meshcollection); + void createPartitionCollection(int ndomains, const std::string& library,bool creates_boundary_faces, bool create_joints, bool mesure_memory); + + private: + MeshCollection* _input_collection; + MeshCollection* _output_collection; + Topology* _new_topology; + }; +} +#endif diff --git a/src/medtool/src/MEDPartitioner/MEDPARTITIONER_MeshCollection.cxx b/src/medtool/src/MEDPartitioner/MEDPARTITIONER_MeshCollection.cxx new file mode 100644 index 000000000..d0ad9d4cb --- /dev/null +++ b/src/medtool/src/MEDPartitioner/MEDPARTITIONER_MeshCollection.cxx @@ -0,0 +1,2459 @@ +// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// + +#include "MEDPARTITIONER_MeshCollection.hxx" + +#include "MEDPARTITIONER_ConnectZone.hxx" +#include "MEDPARTITIONER_Graph.hxx" +#include "MEDPARTITIONER_MeshCollectionDriver.hxx" +#include "MEDPARTITIONER_MeshCollectionMedAsciiDriver.hxx" +#include "MEDPARTITIONER_MeshCollectionMedXmlDriver.hxx" +#include "MEDPARTITIONER_ParaDomainSelector.hxx" +#include "MEDPARTITIONER_ParallelTopology.hxx" +#include "MEDPARTITIONER_Topology.hxx" +#include "MEDPARTITIONER_UserGraph.hxx" +#include "MEDPARTITIONER_Utils.hxx" + +#ifdef HAVE_MPI +#include "MEDPARTITIONER_JointFinder.hxx" +#endif + +#include "MEDCouplingAutoRefCountObjectPtr.hxx" +#include "MEDCouplingFieldDouble.hxx" +#include "MEDCouplingMemArray.hxx" +#include "MEDCouplingNormalizedUnstructuredMesh.hxx" +#include "MEDCouplingSkyLineArray.hxx" +#include "MEDCouplingUMesh.hxx" +#include "MEDLoader.hxx" +#include "MEDLoaderBase.hxx" + +#ifdef HAVE_MPI +#include <mpi.h> +#endif + +#ifdef MED_ENABLE_PARMETIS +#include "MEDPARTITIONER_ParMetisGraph.hxx" +#endif +#ifdef MED_ENABLE_METIS +#include "MEDPARTITIONER_MetisGraph.hxx" +#endif +#ifdef MED_ENABLE_SCOTCH +#include "MEDPARTITIONER_ScotchGraph.hxx" +#endif + +#include <set> +#include <vector> +#include <string> +#include <limits> +#include <iostream> +#include <fstream> + +MEDPARTITIONER::MeshCollection::MeshCollection() + : _topology(0), + _owns_topology(false), + _driver(0), + _domain_selector( 0 ), + _i_non_empty_mesh(-1), + _driver_type(MEDPARTITIONER::MedXml), + _subdomain_boundary_creates( MyGlobals::_Creates_Boundary_Faces ), + _family_splitting(false), + _create_empty_groups(false), + _joint_finder(0) +{ +} + +/*!constructor creating a new mesh collection (mesh series + topology) + *from an old collection and a new topology + * + * On output, the constructor has built the meshes corresponding to the new mesh collection. + * The new topology has been updated so that face and node mappings are included. + * The families have been cast to their projections in the new topology. + * + * \param initial_collection collection from which the data (coordinates, connectivity) are taken + * \param topology topology containing the cell mappings + */ + +MEDPARTITIONER::MeshCollection::MeshCollection(MeshCollection& initialCollection, + Topology* topology, + bool family_splitting, + bool create_empty_groups) + : _topology(topology), + _owns_topology(false), + _driver(0), + _domain_selector( initialCollection._domain_selector ), + _i_non_empty_mesh(-1), + _name(initialCollection._name), + _driver_type(MEDPARTITIONER::MedXml), + _subdomain_boundary_creates(MyGlobals::_Creates_Boundary_Faces), + _family_splitting(family_splitting), + _create_empty_groups(create_empty_groups), + _joint_finder(0) +{ + std::vector<std::vector<std::vector<int> > > new2oldIds(initialCollection.getTopology()->nbDomain()); + std::vector<ParaMEDMEM::DataArrayInt*> o2nRenumber; + + castCellMeshes(initialCollection, new2oldIds, o2nRenumber ); + + //defining the name for the collection and the underlying meshes + setName(initialCollection.getName()); + + ///////////////// + //treating faces + ///////////////// + +#ifdef HAVE_MPI + if (MyGlobals::_Verbose>0 && MyGlobals::_World_Size>1) + MPI_Barrier(MPI_COMM_WORLD); //synchronize verbose messages +#endif + if (MyGlobals::_Is0verbose) + std::cout<<"treating faces"<<std::endl; + NodeMapping nodeMapping; + //nodeMapping contains the mapping between old nodes and new nodes + // (iolddomain,ioldnode)->(inewdomain,inewnode) + createNodeMapping(initialCollection, nodeMapping); + std::vector<std::vector<std::vector<int> > > new2oldFaceIds; + castFaceMeshes(initialCollection, nodeMapping, new2oldFaceIds); + + //////////////////// + //treating families + //////////////////// +#ifdef HAVE_MPI + if (MyGlobals::_Verbose>0 && MyGlobals::_World_Size>1) + MPI_Barrier(MPI_COMM_WORLD); //synchronize verbose messages +#endif + if (MyGlobals::_Is0verbose) + { + if (isParallelMode()) + std::cout << "ParallelMode on " << topology->nbDomain() << " Domains" << std::endl; + else + std::cout << "NOT ParallelMode on " << topology->nbDomain() << " Domains" << std::endl; + } + if (MyGlobals::_Is0verbose>10) + std::cout<<"treating cell and face families"<<std::endl; + + castIntField(initialCollection.getMesh(), + this->getMesh(), + initialCollection.getCellFamilyIds(), + "cellFamily"); + castIntField(initialCollection.getFaceMesh(), + this->getFaceMesh(), + initialCollection.getFaceFamilyIds(), + "faceFamily"); + + //treating groups +#ifdef HAVE_MPI + if (MyGlobals::_Verbose>0 && MyGlobals::_World_Size>1) + MPI_Barrier(MPI_COMM_WORLD); //synchronize verbose messages +#endif + if (MyGlobals::_Is0verbose) + std::cout << "treating groups" << std::endl; + _family_info=initialCollection.getFamilyInfo(); + _group_info=initialCollection.getGroupInfo(); + +#ifdef HAVE_MPI + if (MyGlobals::_Verbose>0 && MyGlobals::_World_Size>1) + MPI_Barrier(MPI_COMM_WORLD); //synchronize verbose messages +#endif + if (MyGlobals::_Is0verbose) + std::cout << "treating fields" << std::endl; + castAllFields(initialCollection,"cellFieldDouble"); + if (_i_non_empty_mesh<0) + { + for (size_t i=0; i<_mesh.size(); i++) + { + if (_mesh[i]) + { + _i_non_empty_mesh=i; //first existing one local + break; + } + } + } + + // find faces common with neighbor domains and put them in groups + buildBoundaryFaces(); + + //building the connect zones necessary for writing joints + buildConnectZones( nodeMapping, o2nRenumber, initialCollection.getTopology()->nbDomain() ); + + // delete o2nRenumber + for ( size_t i = 0; i < o2nRenumber.size(); ++i ) + if ( o2nRenumber[i] ) + o2nRenumber[i]->decrRef(); +} + +/*! + Creates the meshes using the topology underlying he mesh collection and the mesh data + coming from the ancient collection + \param initialCollection collection from which the data is extracted to create the new meshes + \param [out] o2nRenumber returns for each new domain a permutation array returned by sortCellsInMEDFileFrmt() +*/ + +void MEDPARTITIONER::MeshCollection::castCellMeshes(MeshCollection& initialCollection, + std::vector<std::vector<std::vector<int> > >& new2oldIds, + std::vector<ParaMEDMEM::DataArrayInt*> & o2nRenumber) +{ + if (MyGlobals::_Verbose>10) + std::cout << "proc " << MyGlobals::_Rank << " : castCellMeshes" << std::endl; + if (_topology==0) + throw INTERP_KERNEL::Exception("Topology has not been defined on call to castCellMeshes"); + + int nbNewDomain=_topology->nbDomain(); + int nbOldDomain=initialCollection.getTopology()->nbDomain(); + + _mesh.resize(nbNewDomain); + o2nRenumber.resize(nbNewDomain,0); + int rank=MyGlobals::_Rank; + //splitting the initial domains into smaller bits + std::vector<std::vector<ParaMEDMEM::MEDCouplingUMesh*> > splitMeshes; + splitMeshes.resize(nbNewDomain); + for (int inew=0; inew<nbNewDomain; inew++) + { + splitMeshes[inew].resize(nbOldDomain, (ParaMEDMEM::MEDCouplingUMesh*)0); + } + + for (int iold=0; iold<nbOldDomain; iold++) + { + if (!isParallelMode() || initialCollection._domain_selector->isMyDomain(iold)) + { + int size=(initialCollection._mesh)[iold]->getNumberOfCells(); + std::vector<int> globalids(size); + initialCollection.getTopology()->getCellList(iold, &globalids[0]); + std::vector<int> ilocalnew(size); //local + std::vector<int> ipnew(size); //idomain old + _topology->convertGlobalCellList(&globalids[0],size,&ilocalnew[0],&ipnew[0]); + + new2oldIds[iold].resize(nbNewDomain); + for (int i=0; i<(int)ilocalnew.size(); i++) + { + new2oldIds[iold][ipnew[i]].push_back(i); + } + for (int inew=0; inew<nbNewDomain; inew++) + { + splitMeshes[inew][iold]=(ParaMEDMEM::MEDCouplingUMesh*) + (initialCollection.getMesh())[iold]->buildPartOfMySelf(&new2oldIds[iold][inew][0], + &new2oldIds[iold][inew][0]+new2oldIds[iold][inew].size(), + true); + if (MyGlobals::_Verbose>400) + std::cout<< "proc " << rank << " : a splitMesh iold inew NbCells " << iold << " " << inew << " " + << splitMeshes[inew][iold]->getNumberOfCells() << std::endl; + } + } + } +#ifdef HAVE_MPI + if (isParallelMode()) + { + //if (MyGlobals::_Verbose>300) std::cout<<"proc "<<rank<<" : castCellMeshes send/receive"<<std::endl; + for (int iold=0; iold<nbOldDomain; iold++) + for(int inew=0; inew<nbNewDomain; inew++) + { + if (initialCollection._domain_selector->isMyDomain(iold) && _domain_selector->isMyDomain(inew)) + continue; + + if(initialCollection._domain_selector->isMyDomain(iold)) + _domain_selector->sendMesh(*(splitMeshes[inew][iold]),_domain_selector->getProcessorID(inew)); + + if (_domain_selector->isMyDomain(inew)) + _domain_selector->recvMesh(splitMeshes[inew][iold],_domain_selector->getProcessorID(iold)); + + } + } +#endif + + //fusing the split meshes + if (MyGlobals::_Verbose>200) + std::cout << "proc " << rank << " : castCellMeshes fusing" << std::endl; + for (int inew=0; inew<nbNewDomain ;inew++) + { + std::vector<const ParaMEDMEM::MEDCouplingUMesh*> meshes; + + for (int i=0; i<(int)splitMeshes[inew].size(); i++) + if (splitMeshes[inew][i]!=0) + if (splitMeshes[inew][i]->getNumberOfCells()>0) + meshes.push_back(splitMeshes[inew][i]); + + if (!isParallelMode()||_domain_selector->isMyDomain(inew)) + { + if (meshes.size()==0) + { + _mesh[inew]=CreateEmptyMEDCouplingUMesh(); + std::cout << "WARNING : castCellMeshes fusing : no meshes try another number of processors" << std::endl; + } + else + { + _mesh[inew]=ParaMEDMEM::MEDCouplingUMesh::MergeUMeshes(meshes); + o2nRenumber[inew]=_mesh[inew]->sortCellsInMEDFileFrmt(); + bool areNodesMerged; + int nbNodesMerged; + if (meshes.size()>1) + { + ParaMEDMEM::DataArrayInt* array=_mesh[inew]->mergeNodes(1e-12,areNodesMerged,nbNodesMerged); + array->decrRef(); // array is not used in this case + } + _mesh[inew]->zipCoords(); + } + } + for (int i=0;i<(int)splitMeshes[inew].size();i++) + if (splitMeshes[inew][i]!=0) + splitMeshes[inew][i]->decrRef(); + } + if (MyGlobals::_Verbose>300) + std::cout << "proc " << rank << " : castCellMeshes end fusing" << std::endl; +} + +/*! + \param initialCollection source mesh collection + \param nodeMapping structure containing the correspondency between nodes in the initial collection and the node(s) in the new collection +*/ +void MEDPARTITIONER::MeshCollection::createNodeMapping( MeshCollection& initialCollection, NodeMapping& nodeMapping) +{ + using std::vector; + using std::make_pair; + // NodeMapping reverseNodeMapping; + for (int iold=0; iold<initialCollection.getTopology()->nbDomain();iold++) + { + + double* bbox; + BBTreeOfDim* tree = 0; + int dim = 3; + if (!isParallelMode() || (_domain_selector->isMyDomain(iold))) + { + // std::map<pair<double,pair<double, double> >, int > nodeClassifier; + ParaMEDMEM::DataArrayDouble* coords = initialCollection.getMesh(iold)->getCoords(); + double* coordsPtr=coords->getPointer(); + dim = coords->getNumberOfComponents(); + int nvertices=initialCollection.getMesh(iold)->getNumberOfNodes(); + bbox=new double[nvertices*2*dim]; + + for (int i=0; i<nvertices*dim;i++) + { + bbox[i*2]=coordsPtr[i]-1e-8; + bbox[i*2+1]=coordsPtr[i]+1e-8; + } + tree=new BBTreeOfDim( dim, bbox,0,0,nvertices,1e-9); + } + + for (int inew=0; inew<_topology->nbDomain(); inew++) + { +#ifdef HAVE_MPI + //sending meshes for parallel computation + if (isParallelMode() && _domain_selector->isMyDomain(inew) && !_domain_selector->isMyDomain(iold)) + _domain_selector->sendMesh(*(getMesh(inew)), _domain_selector->getProcessorID(iold)); + else if (isParallelMode() && !_domain_selector->isMyDomain(inew)&& _domain_selector->isMyDomain(iold)) + { + ParaMEDMEM::MEDCouplingUMesh* mesh; + _domain_selector->recvMesh(mesh, _domain_selector->getProcessorID(inew)); + ParaMEDMEM::DataArrayDouble* coords = mesh->getCoords(); + for (int inode=0; inode<mesh->getNumberOfNodes();inode++) + { + double* coordsPtr=coords->getPointer()+inode*dim; + vector<int> elems; + tree->getElementsAroundPoint(coordsPtr,elems); + if (elems.size()==0) continue; + nodeMapping.insert(make_pair(make_pair(iold,elems[0]),make_pair(inew,inode))); + } + mesh->decrRef(); + } + else if (!isParallelMode() || (_domain_selector->isMyDomain(inew) && _domain_selector->isMyDomain(iold))) +#else + if (!isParallelMode() || (_domain_selector->isMyDomain(inew) && _domain_selector->isMyDomain(iold))) +#endif + { + ParaMEDMEM::DataArrayDouble* coords = getMesh(inew)->getCoords(); + for (int inode=0; inode<_mesh[inew]->getNumberOfNodes();inode++) + { + double* coordsPtr=coords->getPointer()+inode*dim; + vector<int> elems; + tree->getElementsAroundPoint(coordsPtr,elems); + if (elems.size()==0) continue; + nodeMapping.insert(make_pair(make_pair(iold,elems[0]),make_pair(inew,inode))); + } + } + } + if (!isParallelMode() || (_domain_selector->isMyDomain(iold))) + { + delete tree; + delete[] bbox; + } + } + +} + +void getNodeIds(ParaMEDMEM::MEDCouplingUMesh& meshOne, ParaMEDMEM::MEDCouplingUMesh& meshTwo, std::vector<int>& nodeIds) +{ + using std::vector; + using MEDPARTITIONER::BBTreeOfDim; + if (!&meshOne || !&meshTwo) return; //empty or not existing + double* bbox; + BBTreeOfDim* tree = 0; + int nv1=meshOne.getNumberOfNodes(); + ParaMEDMEM::DataArrayDouble* coords=meshOne.getCoords(); + int dim = coords->getNumberOfComponents(); + + bbox=new double[nv1*2*dim]; + double* coordsPtr=coords->getPointer(); + for (int i=0; i<nv1*dim; i++) + { + bbox[i*2]=coordsPtr[i]-1e-8; + bbox[i*2+1]=coordsPtr[i]+1e-8; + } + tree=new BBTreeOfDim( dim, bbox,0,0,nv1,1e-9); + + int nv2=meshTwo.getNumberOfNodes(); + nodeIds.resize(nv2,-1); + coords=meshTwo.getCoords(); + for (int inode=0; inode<nv2; inode++) + { + double* coordsPtr2=coords->getPointer()+inode*dim; + vector<int> elems; + tree->getElementsAroundPoint(coordsPtr2,elems); + if (elems.size()==0) continue; + nodeIds[inode]=elems[0]; + } + delete tree; + delete[] bbox; +} + +/*! + creates the face meshes on the new domains from the faces on the old domain and the node mapping + faces at the interface are duplicated +*/ +void MEDPARTITIONER::MeshCollection::castFaceMeshes(MeshCollection& initialCollection, + const std::multimap<std::pair<int,int>, std::pair<int,int> >& nodeMapping, + std::vector<std::vector<std::vector<int> > >& new2oldIds) +{ + //splitMeshes structure will contain the partition of + //the old faces on the new ones + //splitMeshes[4][2] contains the faces from old domain 2 + //that have to be added to domain 4 + + using std::vector; + using std::map; + using std::multimap; + using std::pair; + using std::make_pair; + + if (MyGlobals::_Verbose>10) + std::cout << "proc " << MyGlobals::_Rank << " : castFaceMeshes" << std::endl; + if (_topology==0) + throw INTERP_KERNEL::Exception("Topology has not been defined on call to castFaceMeshes"); + + int nbNewDomain=_topology->nbDomain(); + int nbOldDomain=initialCollection.getTopology()->nbDomain(); + + vector<ParaMEDMEM::MEDCouplingUMesh*>& meshesCastFrom=initialCollection.getFaceMesh(); + vector<ParaMEDMEM::MEDCouplingUMesh*>& meshesCastTo=this->getFaceMesh(); + + vector< vector<ParaMEDMEM::MEDCouplingUMesh*> > splitMeshes; + + splitMeshes.resize(nbNewDomain); + for (int inew=0; inew<nbNewDomain; inew++) + { + splitMeshes[inew].resize(nbOldDomain, (ParaMEDMEM::MEDCouplingUMesh*)0); + } + new2oldIds.resize(nbOldDomain); + for (int iold=0; iold<nbOldDomain; iold++) new2oldIds[iold].resize(nbNewDomain); + + //init null pointer for empty meshes + for (int inew=0; inew<nbNewDomain; inew++) + { + for (int iold=0; iold<nbOldDomain; iold++) + { + splitMeshes[inew][iold]=0; //null for empty meshes + new2oldIds[iold][inew].clear(); + } + } + + //loop over the old domains to analyse the faces and decide + //on which new domain they belong + for (int iold=0; iold<nbOldDomain; iold++) + { + if (isParallelMode() && !initialCollection._domain_selector->isMyDomain(iold)) continue; + if (MyGlobals::_Verbose>400) + std::cout<<"proc "<<MyGlobals::_Rank<<" : castFaceMeshes iodDomain "<<iold<<std::endl; + //initial face mesh known : in my domain + if (meshesCastFrom[iold] != 0) + { + for (int ielem=0; ielem<meshesCastFrom[iold]->getNumberOfCells(); ielem++) + { + vector<int> nodes; + meshesCastFrom[iold]->getNodeIdsOfCell(ielem,nodes); + + map <int,int> faces; + + //analysis of element ielem + //counters are set for the element + //for each source node, the mapping is interrogated and the domain counters + //are incremented for each target node + //the face is considered as going to target domains if the counter of the domain + //is equal to the number of nodes + for (int inode=0; inode<(int)nodes.size(); inode++) + { + typedef multimap<pair<int,int>,pair<int,int> >::const_iterator MI; + int mynode=nodes[inode]; + + pair <MI,MI> myRange = nodeMapping.equal_range(make_pair(iold,mynode)); + for (MI iter=myRange.first; iter!=myRange.second; iter++) + { + int inew=iter->second.first; + if (faces.find(inew)==faces.end()) + faces[inew]=1; + else + faces[inew]++; + } + } + + for (map<int,int>::iterator iter=faces.begin(); iter!=faces.end(); iter++) + { + if (iter->second==(int)nodes.size()) + //cvw eligible but may be have to be face of a cell of this->getMesh()[inew]? + //it is not sure here... + //done before writeMedfile on option?... see filterFaceOnCell() + new2oldIds[iold][iter->first].push_back(ielem); + } + } + + //creating the splitMeshes from the face ids + for (int inew=0; inew<nbNewDomain; inew++) + { + if (meshesCastFrom[iold]->getNumberOfCells() > 0) + { + splitMeshes[inew][iold]= + (ParaMEDMEM::MEDCouplingUMesh*) + ( meshesCastFrom[iold]->buildPartOfMySelf(&new2oldIds[iold][inew][0], + &new2oldIds[iold][inew][0]+new2oldIds[iold][inew].size(), + true) + ); + splitMeshes[inew][iold]->zipCoords(); + } + else + { + splitMeshes[inew][iold]=CreateEmptyMEDCouplingUMesh(); + } + } + } + else + { + std::cout<<"proc "<<MyGlobals::_Rank<<" : castFaceMeshes empty mesh from iodDomain "<<iold<<std::endl; + } + } + +#ifdef HAVE_MPI + //send/receive stuff + if (isParallelMode()) + { + ParaMEDMEM::MEDCouplingUMesh *empty=CreateEmptyMEDCouplingUMesh(); + for (int iold=0; iold<nbOldDomain; iold++) + for (int inew=0; inew<nbNewDomain; inew++) + { + if (initialCollection._domain_selector->isMyDomain(iold) && !_domain_selector->isMyDomain(inew)) + { + if (splitMeshes[inew][iold] != 0) + { + _domain_selector->sendMesh(*(splitMeshes[inew][iold]), _domain_selector->getProcessorID(inew)); + //std::cout << "proc " << MyGlobals::_Rank << " : castFaceMeshes send " <<inew<<" "<<iold<<" "<<splitMeshes[inew][iold]->getNumberOfCells()<<std::endl; + } + else + { + _domain_selector->sendMesh(*(empty), _domain_selector->getProcessorID(inew)); + //std::cout << "proc " << MyGlobals::_Rank << " : castFaceMeshes sen0 " <<inew<<" "<<iold<<std::endl; + } + } + if (!initialCollection._domain_selector->isMyDomain(iold) && _domain_selector->isMyDomain(inew)) + _domain_selector->recvMesh(splitMeshes[inew][iold], _domain_selector->getProcessorID(iold)); + //int nb=0; + //if (splitMeshes[inew][iold]) + // nb=splitMeshes[inew][iold]->getNumberOfCells(); + //std::cout << "proc " << MyGlobals::_Rank << " : castFaceMeshes recv "<<inew<<" "<<iold<<" "<<nb<<std::endl;//" "<<splitMeshes[inew][iold]->getNumberOfCells()<<std::endl; + } + empty->decrRef(); + } +#endif + + //fusing the split meshes + if (MyGlobals::_Verbose>200) + std::cout << "proc " << MyGlobals::_Rank << " : castFaceMeshes fusing" << std::endl; + meshesCastTo.resize(nbNewDomain); + for (int inew=0; inew<nbNewDomain; inew++) + { + vector<const ParaMEDMEM::MEDCouplingUMesh*> myMeshes; + for (int iold=0; iold<nbOldDomain; iold++) + { + ParaMEDMEM::MEDCouplingUMesh *umesh=splitMeshes[inew][iold]; + if (umesh!=0) + if (umesh->getNumberOfCells()>0) + myMeshes.push_back(umesh); + } + + ParaMEDMEM::MEDCouplingUMesh *bndMesh = 0; + if ( _subdomain_boundary_creates && + _mesh[inew] && + _mesh[inew]->getNumberOfCells()>0 ) + { + bndMesh = + ((ParaMEDMEM::MEDCouplingUMesh *)_mesh[inew]->buildBoundaryMesh(/*keepCoords=*/true)); + if (bndMesh->getNumberOfCells()>0) + myMeshes.push_back( bndMesh ); + } + + if (myMeshes.size()>0) + { + meshesCastTo[inew]=ParaMEDMEM::MEDCouplingUMesh::MergeUMeshes(myMeshes); + meshesCastTo[inew]->sortCellsInMEDFileFrmt()->decrRef(); + } + else + { + ParaMEDMEM::MEDCouplingUMesh *empty=CreateEmptyMEDCouplingUMesh(); + meshesCastTo[inew]=empty; + } + for (int iold=0; iold<nbOldDomain; iold++) + if (splitMeshes[inew][iold]!=0) + splitMeshes[inew][iold]->decrRef(); + if ( bndMesh ) + bndMesh->decrRef(); + } + if (MyGlobals::_Verbose>300) + std::cout << "proc " << MyGlobals::_Rank << " : castFaceMeshes end fusing" << std::endl; +} + + + +void MEDPARTITIONER::MeshCollection::castIntField(std::vector<ParaMEDMEM::MEDCouplingUMesh*>& meshesCastFrom, + std::vector<ParaMEDMEM::MEDCouplingUMesh*>& meshesCastTo, + std::vector<ParaMEDMEM::DataArrayInt*>& arrayFrom, + std::string nameArrayTo) +{ + using std::vector; + + int ioldMax=meshesCastFrom.size(); + int inewMax=meshesCastTo.size(); + + + //preparing bounding box trees for accelerating source-target node identifications + if (MyGlobals::_Verbose>99) + std::cout<<"making accelerating structures"<<std::endl; + std::vector<BBTreeOfDim* > acceleratingStructures(ioldMax); + std::vector<ParaMEDMEM::DataArrayDouble*>bbox(ioldMax); + for (int iold =0; iold< ioldMax; iold++) + if (isParallelMode() && _domain_selector->isMyDomain(iold)) + { + ParaMEDMEM::DataArrayDouble* sourceCoords=meshesCastFrom[iold]->getBarycenterAndOwner(); + bbox[iold]=sourceCoords->computeBBoxPerTuple(1.e-6); + acceleratingStructures[iold]=new BBTreeOfDim( sourceCoords->getNumberOfComponents(), bbox[iold]->getConstPointer(),0,0,bbox[iold]->getNumberOfTuples()); + sourceCoords->decrRef(); + } + // send-recv operations +#ifdef HAVE_MPI + for (int inew=0; inew<inewMax; inew++) + { + for (int iold=0; iold<ioldMax; iold++) + { + //sending arrays for distant domains + if (isParallelMode() && _domain_selector->isMyDomain(iold) && !_domain_selector->isMyDomain(inew)) + { + //send mesh + _domain_selector->sendMesh(*meshesCastFrom[iold],_domain_selector->getProcessorID(inew)); + //send vector + int size=arrayFrom[iold]->getNumberOfTuples(); //cvw may be -1! + vector<int>sendIds; + if (MyGlobals::_Verbose>400) std::cout<<"proc "<<_domain_selector->rank()<<" : castIntField SendIntVec size "<<size<<std::endl; + if (size>0) //no empty + { + sendIds.resize(size); + std::copy(arrayFrom[iold]->getPointer(),arrayFrom[iold]->getPointer()+size,&sendIds[0]); + } + else //empty + { + size=0; + sendIds.resize(size); + } + SendIntVec(sendIds, _domain_selector->getProcessorID(inew)); + } + //receiving arrays from distant domains + if (isParallelMode() && !_domain_selector->isMyDomain(iold) && _domain_selector->isMyDomain(inew)) + { + //receive mesh + vector<int> recvIds; + ParaMEDMEM::MEDCouplingUMesh* recvMesh; + _domain_selector->recvMesh(recvMesh,_domain_selector->getProcessorID(iold)); + //receive vector + if (MyGlobals::_Verbose>400) std::cout<<"proc "<<_domain_selector->rank()<<" : castIntField recIntVec "<<std::endl; + RecvIntVec(recvIds, _domain_selector->getProcessorID(iold)); + remapIntField(inew,iold,*recvMesh,*meshesCastTo[inew],&recvIds[0],nameArrayTo,0); + recvMesh->decrRef(); //cww is it correct? + } + } + } +#endif + + //local contributions and aggregation + for (int inew=0; inew<inewMax; inew++) + { + for (int iold=0; iold<ioldMax; iold++) + if (!isParallelMode() || ( _domain_selector->isMyDomain(iold) && _domain_selector->isMyDomain(inew))) + { + remapIntField(inew,iold,*meshesCastFrom[iold],*meshesCastTo[inew],arrayFrom[iold]->getConstPointer(),nameArrayTo,acceleratingStructures[iold]); + } + } + for (int iold=0; iold<ioldMax;iold++) + if (isParallelMode() && _domain_selector->isMyDomain(iold)) + { + bbox[iold]->decrRef(); + delete acceleratingStructures[iold]; + } +} + +void MEDPARTITIONER::MeshCollection::remapIntField(int inew, int iold, + const ParaMEDMEM::MEDCouplingUMesh& sourceMesh, + const ParaMEDMEM::MEDCouplingUMesh& targetMesh, + const int* fromArray, + std::string nameArrayTo, + const BBTreeOfDim* myTree) +{ + + if (sourceMesh.getNumberOfCells()<=0) return; //empty mesh could exist + ParaMEDMEM::DataArrayDouble* targetCoords=targetMesh.getBarycenterAndOwner(); + const double* tc=targetCoords->getConstPointer(); + int targetSize=targetMesh.getNumberOfCells(); + int sourceSize=sourceMesh.getNumberOfCells(); + if (MyGlobals::_Verbose>200) + std::cout<<"remap vers target de taille "<<targetSize<<std::endl; + std::vector<int> ccI; + std::string str,cle; + str=nameArrayTo+"_toArray"; + cle=Cle1ToStr(str,inew); + int* toArray; + + const BBTreeOfDim* tree; + bool cleantree=false; + ParaMEDMEM::DataArrayDouble* sourceBBox=0; + int dim = targetCoords->getNumberOfComponents(); + if (myTree==0) + { + sourceBBox=sourceMesh.getBarycenterAndOwner()->computeBBoxPerTuple(1e-8); + tree=new BBTreeOfDim( dim, sourceBBox->getConstPointer(),0,0, sourceBBox->getNumberOfTuples(),1e-10); + cleantree=true; + } + else tree=myTree; + //first time iold : create and initiate + if (_map_dataarray_int.find(cle)==_map_dataarray_int.end()) + { + if (MyGlobals::_Is0verbose>100) + std::cout << "create " << cle << " size " << targetSize << std::endl; + ParaMEDMEM::DataArrayInt* p=ParaMEDMEM::DataArrayInt::New(); + p->alloc(targetSize,1); + p->fillWithZero(); + toArray=p->getPointer(); + _map_dataarray_int[cle]=p; + } + else //other times iold: refind and complete + { + toArray=_map_dataarray_int.find(cle)->second->getPointer(); + } + + std::map< int, int > isource2nb; // count coincident elements + std::map<int,int>::iterator i2nb; + + for (int itargetnode=0; itargetnode<targetSize; itargetnode++) + { + std::vector<int> intersectingElems; + tree->getElementsAroundPoint(tc+itargetnode*dim,intersectingElems); + if (intersectingElems.size()!=0) + { + int isourcenode=intersectingElems[0]; + if ( intersectingElems.size() > 1 ) + { + i2nb = isource2nb.insert( std::make_pair( isourcenode, 0 )).first; + isourcenode = intersectingElems[ i2nb->second++ ]; + } + if ( isourcenode < sourceSize ) // protection from invalid elements + { + toArray[itargetnode]=fromArray[isourcenode]; + ccI.push_back(itargetnode); + ccI.push_back(isourcenode); + } + } + } + if (MyGlobals::_Verbose>200) + std::cout<<"nb points trouves"<<ccI.size()/2<<std::endl; + //memories intersection for future same job on fields (if no existing cle=no intersection) + str=Cle2ToStr(nameArrayTo+"_ccI",inew,iold); + if (MyGlobals::_Verbose>700) + std::cout << "proc " << MyGlobals::_Rank << " : map memorize '" << str << "'\n"; + + _map_dataarray_int[str]=CreateDataArrayIntFromVector(ccI, 2); + + targetCoords->decrRef(); + if (cleantree) delete tree; + if (sourceBBox !=0) sourceBBox->decrRef(); +} + +void MEDPARTITIONER::MeshCollection::castAllFields(MeshCollection& initialCollection, std::string nameArrayTo) +{ + if (nameArrayTo!="cellFieldDouble") + throw INTERP_KERNEL::Exception("Error castAllField only on cellFieldDouble"); + + std::string nameTo="typeData=6"; //resume the type of field casted + // send-recv operations + int ioldMax=initialCollection.getMesh().size(); + int inewMax=this->getMesh().size(); + int iFieldMax=initialCollection.getFieldDescriptions().size(); + if (MyGlobals::_Verbose>10) + std::cout << "castAllFields with:\n" << ReprVectorOfString(initialCollection.getFieldDescriptions()) << std::endl; + //see collection.prepareFieldDescriptions() + for (int ifield=0; ifield<iFieldMax; ifield++) + { + std::string descriptionField=initialCollection.getFieldDescriptions()[ifield]; + if (descriptionField.find(nameTo)==std::string::npos) + continue; //only nameTo accepted in Fields name description +#ifdef HAVE_MPI + for (int inew=0; inew<inewMax; inew++) + { + for (int iold=0; iold<ioldMax; iold++) + { + //sending arrays for distant domains + if (isParallelMode() && _domain_selector->isMyDomain(iold) && !_domain_selector->isMyDomain(inew)) + { + int target=_domain_selector->getProcessorID(inew); + ParaMEDMEM::DataArrayDouble* field=initialCollection.getField(descriptionField,iold); + if (MyGlobals::_Verbose>10) + std::cout << "proc " << _domain_selector->rank() << " : castAllFields sendDouble" << std::endl; + SendDataArrayDouble(field, target); + } + //receiving arrays from distant domains + if (isParallelMode() && !_domain_selector->isMyDomain(iold) && _domain_selector->isMyDomain(inew)) + { + int source=_domain_selector->getProcessorID(iold); + //receive vector + if (MyGlobals::_Verbose>10) + std::cout << "proc " << _domain_selector->rank() << " : castAllFields recvDouble" << std::endl; + ParaMEDMEM::DataArrayDouble* field=RecvDataArrayDouble(source); + remapDoubleField(inew,iold,field,nameArrayTo,descriptionField); + } + } + } +#endif + //local contributions and aggregation + for (int inew=0; inew<inewMax; inew++) + { + for (int iold=0; iold<ioldMax; iold++) + if (!isParallelMode() || ( _domain_selector->isMyDomain(iold) && _domain_selector->isMyDomain(inew))) + { + ParaMEDMEM::DataArrayDouble* field=initialCollection.getField(descriptionField,iold); + remapDoubleField(inew,iold,field,nameArrayTo,descriptionField); + } + } + } +} + +void MEDPARTITIONER::MeshCollection::remapDoubleField(int inew, int iold, + ParaMEDMEM::DataArrayDouble* fromArray, + std::string nameArrayTo, + std::string descriptionField) +//here we use 'cellFamily_ccI inew iold' set in remapIntField +{ + if (nameArrayTo!="cellFieldDouble") + throw INTERP_KERNEL::Exception("Error remapDoubleField only on cellFieldDouble"); + std::string key=Cle2ToStr("cellFamily_ccI",inew,iold); + + std::map<std::string,ParaMEDMEM::DataArrayInt*>::iterator it1; + it1=_map_dataarray_int.find(key); + if (it1==_map_dataarray_int.end()) + { + std::cerr << "proc " << MyGlobals::_Rank << " : remapDoubleField key '" << key << "' not found" << std::endl; + std::cerr << " trying remap of field double on cells : " << descriptionField << std::endl; + return; + } + //create ccI in remapIntField + ParaMEDMEM::DataArrayInt *ccI=it1->second; + if (MyGlobals::_Verbose>300) + std::cout << "proc " << MyGlobals::_Rank << " : remapDoubleField " << key << " size " << ccI->getNbOfElems() << std::endl; + + int nbcell=this->getMesh()[inew]->getNumberOfCells(); + int nbcomp=fromArray->getNumberOfComponents(); + int nbPtGauss=StrToInt(ExtractFromDescription(descriptionField, "nbPtGauss=")); + + std::string tag="inewFieldDouble="+IntToStr(inew); + key=descriptionField+SerializeFromString(tag); + int fromArrayNbOfElem=fromArray->getNbOfElems(); + int fromArrayNbOfComp=fromArray->getNumberOfComponents(); + int fromArrayNbOfCell=fromArrayNbOfElem/fromArrayNbOfComp/nbPtGauss; + + if (MyGlobals::_Verbose>1000) + { + std::cout<<"proc " << MyGlobals::_Rank << " nbcell " << nbcell << " nbcomp " << nbcomp << " nbPtGauss " << nbPtGauss << + " fromArray nbOfElems " << fromArrayNbOfElem << + " nbTuples " << fromArray->getNumberOfTuples() << + " nbcells " << fromArrayNbOfCell << + " nbComponents " << fromArray->getNumberOfComponents() << std::endl; + } + + ParaMEDMEM::DataArrayDouble* field=0; + std::map<std::string,ParaMEDMEM::DataArrayDouble*>::iterator it2; + it2=_map_dataarray_double.find(key); + if (it2==_map_dataarray_double.end()) + { + if (MyGlobals::_Verbose>300) + std::cout << "proc "<< MyGlobals::_Rank << " : remapDoubleField key '" << key << "' not found and create it" << std::endl; + field=ParaMEDMEM::DataArrayDouble::New(); + _map_dataarray_double[key]=field; + field->alloc(nbcell*nbPtGauss,nbcomp); + field->fillWithZero(); + } + else + { + field=it2->second; + if (field->getNumberOfTuples()!=nbcell*nbPtGauss || field->getNumberOfComponents()!=nbcomp) + { + std::cerr << "proc " << MyGlobals::_Rank << " : remapDoubleField3 pb of size " << + " trying remap of field double on cells : \n" << descriptionField << std::endl; + return; + } + } + + if (nbPtGauss==1) + { + field->setPartOfValuesAdv(fromArray,ccI); + } + else + { + //replaced by setPartOfValuesAdv if nbPtGauss==1 + int iMax=ccI->getNbOfElems(); + int* pccI=ccI->getPointer(); + double* pField=field->getPointer(); + double* pFrom=fromArray->getPointer(); + int itarget, isource, delta=nbPtGauss*nbcomp; + for (int i=0; i<iMax; i=i+2) //cell + { + itarget=pccI[i]; + isource=pccI[i+1]; + if ((itarget<0) || (itarget>=nbcell) || (isource<0) || (isource>=fromArrayNbOfCell)) + throw INTERP_KERNEL::Exception("Error field override"); + int ita=itarget*delta; + int iso=isource*delta; + for (int k=0; k<delta; k++) pField[ita+k]=pFrom[iso+k]; //components and gausspoints + } + } +} + +namespace +{ + using namespace ParaMEDMEM; + //================================================================================ + /*! + * \brief Sort correspondence ids of one domain and permute ids of the other accordingly + * \param [in,out] ids1 - ids of one domain + * \param [in,out] ids2 - ids of another domain + * \param [in] delta - a delta to change all ids + * \param [in] removeEqual - to remove equal ids + * \return DataArrayInt* - array of ids joined back + */ + //================================================================================ + + DataArrayInt* sortCorrespondences( DataArrayInt* ids1, + DataArrayInt* ids2, + int delta, + bool removeEqual = false) + { + // sort + MEDCouplingAutoRefCountObjectPtr< DataArrayInt > renumN2O = ids1->buildPermArrPerLevel(); + ids1->renumberInPlaceR( renumN2O->begin() ); + ids2->renumberInPlaceR( renumN2O->begin() ); + + if ( removeEqual ) + { + ids1 = ids1->buildUnique(); + ids2 = ids2->buildUnique(); + } + if ( delta != 0 ) + { + int * id = ids1->getPointer(); + for ( ; id < ids1->end(); ++id ) + ++(*id); + id = ids2->getPointer(); + for ( ; id < ids2->end(); ++id ) + ++(*id); + } + + // join + DataArrayInt* ids12 = DataArrayInt::Meld( ids1, ids2 ); // two components + ids12->rearrange( 1 ); // make one component + return ids12; + } + + //================================================================================ + /*! + * \brief Renumber ids according to mesh->sortCellsInMEDFileFrmt() + * \param [in,out] ids - cell ids to renumber + * \param [in] o2nRenumber - renumbering array in "Old to New" mode + */ + //================================================================================ + + void renumber( DataArrayInt* ids, const DataArrayInt* o2nRenumber ) + { + if ( !ids || !o2nRenumber ) + return; + int * id = ids->getPointer(); + const int * o2n = o2nRenumber->getConstPointer(); + for ( ; id < ids->end(); ++id ) + { + *id = o2n[ *id ]; + } + } +} + +//================================================================================ +/*! + * \brief Fill up ConnectZone's stored in _topology with nodal correspondences + * \param [in] nodeMapping - mapping between old nodes and new nodes + * (iolddomain,ioldnode)->(inewdomain,inewnode) + * \param [in] o2nRenumber - renumbering array returned by mesh->sortCellsInMEDFileFrmt() + * per a new domain + * \param [in] nbInitialDomains - nb of old domains + */ +//================================================================================ + +void MEDPARTITIONER::MeshCollection::buildConnectZones( const NodeMapping& nodeMapping, + const std::vector<ParaMEDMEM::DataArrayInt*> & o2nRenumber, + int nbInitialDomains) +{ + if ( !MyGlobals::_Create_Joints || _topology->nbDomain() < 2 ) + return; + + if ( MyGlobals::_World_Size > 1 ) + { + _topology->getCZ().clear(); + return; // not implemented for parallel mode + } + + // at construction, _topology creates cell correspondences basing on Graph information, + // and here we + // 1) add node correspondences, + // 2) split cell correspondences by cell geometry types + // 3) sort ids to be in ascending order + + const int nb_domains = _topology->nbDomain(); + + // ================================== + // 1) add node correspondences + // ================================== + + std::vector< std::vector< std::vector< int > > > nodeCorresp( nb_domains ); + for ( int idomain = 0; idomain < nb_domains; ++idomain ) + { + nodeCorresp[ idomain ].resize( nb_domains ); + } + + NodeMapping::const_iterator nmIt1, nmIt2 = nodeMapping.begin(); + for ( nmIt1 = nmIt2; nmIt1 != nodeMapping.end(); nmIt1 = nmIt2 ) + { + // look for an "old" node mapped into several "new" nodes in different domains + int nbSameOld = 0; + while ( ++nmIt2 != nodeMapping.end() && nmIt2->first == nmIt1->first ) + nbSameOld += ( nmIt2->second != nmIt1->second ); + + if ( nbSameOld > 0 ) + { + NodeMapping::const_iterator nmEnd = nmIt2; + for ( ; true; ++nmIt1 ) + { + nmIt2 = nmIt1; + if ( ++nmIt2 == nmEnd ) + break; + int dom1 = nmIt1->second.first; + int node1 = nmIt1->second.second; + for ( ; nmIt2 != nmEnd; ++nmIt2 ) + { + int dom2 = nmIt2->second.first; + int node2 = nmIt2->second.second; + if ( dom1 != dom2 ) + { + nodeCorresp[ dom1 ][ dom2 ].push_back( node1 ); + nodeCorresp[ dom1 ][ dom2 ].push_back( node2 ); + nodeCorresp[ dom2 ][ dom1 ].push_back( node2 ); + nodeCorresp[ dom2 ][ dom1 ].push_back( node1 ); + } + } + } + } + } + + // add nodeCorresp to czVec + + std::vector<MEDPARTITIONER::ConnectZone*>& czVec = _topology->getCZ(); + + for ( int idomain = 0; idomain < nb_domains; ++idomain ) + { + for ( int idomainNear = 0; idomainNear < nb_domains; ++idomainNear ) + { + std::vector< int > & corresp = nodeCorresp[ idomain ][ idomainNear ]; + if ( corresp.empty() ) + continue; + + MEDPARTITIONER::ConnectZone* cz = 0; + for ( size_t i = 0; i < czVec.size() && !cz; ++i ) + if ( czVec[i] && + czVec[i]->getLocalDomainNumber () == idomain && + czVec[i]->getDistantDomainNumber() == idomainNear ) + cz = czVec[i]; + + if ( !cz ) + { + cz = new MEDPARTITIONER::ConnectZone(); + cz->setName( "Nodal Connect Zone defined by MEDPARTITIONER" ); + cz->setLocalDomainNumber ( idomain ); + cz->setDistantDomainNumber( idomainNear ); + czVec.push_back(cz); + } + + cz->setNodeCorresp( &corresp[0], corresp.size()/2 ); + } + } + + // ========================================================== + // 2) split cell correspondences by cell geometry types + // ========================================================== + + for ( size_t i = 0; i < czVec.size(); ++i ) + { + MEDPARTITIONER::ConnectZone* cz = czVec[i]; + if ( !cz || + cz->getEntityCorrespNumber( 0,0 ) == 0 || + cz->getLocalDomainNumber () > (int)_mesh.size() || + cz->getDistantDomainNumber() > (int)_mesh.size() ) + continue; + ParaMEDMEM::MEDCouplingUMesh* mesh1 = _mesh[ cz->getLocalDomainNumber () ]; + ParaMEDMEM::MEDCouplingUMesh* mesh2 = _mesh[ cz->getDistantDomainNumber() ]; + + // separate ids of two domains + const ParaMEDMEM::MEDCouplingSkyLineArray *corrArray = cz->getEntityCorresp( 0, 0 ); + const DataArrayInt* ids12 = corrArray->getValueArray(); + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ids1, ids2, ids12Sorted; + ids1 = ids12->selectByTupleId2( 0, corrArray->getLength(), 2 ); + ids2 = ids12->selectByTupleId2( 1, corrArray->getLength(), 2 ); + + // renumber cells according to mesh->sortCellsInMEDFileFrmt() + renumber( ids1, o2nRenumber[ cz->getLocalDomainNumber() ]); + renumber( ids2, o2nRenumber[ cz->getDistantDomainNumber() ]); + + // check nb cell types + std::set<INTERP_KERNEL::NormalizedCellType> types1, types2; + types1 = mesh1->getTypesOfPart( ids1->begin(), ids1->end() ); + types2 = mesh2->getTypesOfPart( ids2->begin(), ids2->end() ); + if ( types1.size() < 1 || types2.size() < 1 ) + continue; // parallel mode? + + MEDPARTITIONER::ConnectZone* cz21 = 0; // zone 2 -> 1 + for ( size_t j = 0; j < czVec.size() && !cz21; ++j ) + if ( czVec[j] && + czVec[j]->getLocalDomainNumber () == cz->getDistantDomainNumber() && + czVec[j]->getDistantDomainNumber() == cz->getLocalDomainNumber() ) + cz21 = czVec[j]; + + if ( types1.size() == 1 && types2.size() == 1 ) // split not needed, only sort + { + ids12Sorted = sortCorrespondences( ids1, ids2, /*delta=*/1 ); + cz->setEntityCorresp( *types1.begin(), *types2.begin(), + ids12Sorted->begin(), ids12Sorted->getNbOfElems() / 2 ); + + if ( cz21 )// set 2->1 correspondence + { + ids12Sorted = sortCorrespondences( ids2, ids1, /*delta=*/0 ); + cz21->setEntityCorresp( *types2.begin(), *types1.begin(), + ids12Sorted->begin(), ids12Sorted->getNbOfElems() / 2 ); + } + } + else // split and sort + { + typedef std::pair< std::vector< int >, std::vector< int > > T2Vecs; + T2Vecs idsByType[ INTERP_KERNEL::NORM_MAXTYPE ][ INTERP_KERNEL::NORM_MAXTYPE ]; + int t1, t2; + + const int nbIds = ids1->getNbOfElems(); + const int * p1 = ids1->begin(), * p2 = ids2->begin(); + for ( int i = 0; i < nbIds; ++i ) + { + t1 = mesh1->getTypeOfCell( p1[ i ]); + t2 = mesh2->getTypeOfCell( p2[ i ]); + T2Vecs & ids = idsByType[ t1 ][ t2 ]; + ids.first .push_back( p1[ i ]); + ids.second.push_back( p1[ i ]); + } + + const int maxType = int( INTERP_KERNEL::NORM_MAXTYPE ); + for ( t1 = 0; t1 < maxType; ++t1 ) + for ( t2 = 0; t2 < maxType; ++t2 ) + { + T2Vecs & ids = idsByType[ t1 ][ t2 ]; + if ( ids.first.empty() ) continue; + p1 = & ids.first[0]; + p2 = & ids.second[0]; + ids1->desallocate(); + ids1->pushBackValsSilent( p1, p1+ids.first.size() ); + ids2->desallocate(); + ids2->pushBackValsSilent( p2, p2+ids.first.size() ); + ids12Sorted = sortCorrespondences( ids1, ids2, /*delta=*/1 ); + + cz->setEntityCorresp( t1, t2, + ids12Sorted->begin(), ids12Sorted->getNbOfElems() / 2 ); + + if ( cz21 )// set 2->1 correspondence + { + ids12Sorted = sortCorrespondences( ids2, ids1, /*delta=*/0 ); + cz21->setEntityCorresp( t2, t1, + ids12Sorted->begin(), ids12Sorted->getNbOfElems() / 2 ); + break; + } + } + }// split and sort + + cz->setEntityCorresp( 0, 0, 0, 0 ); // erase ids computed by _topology + if ( cz21 ) + cz21->setEntityCorresp( 0, 0, 0, 0 ); + + } // loop on czVec + + + // ========================================== + // 3) sort node ids to be in ascending order + // ========================================== + + const bool removeEqual = ( nbInitialDomains > 1 ); + + for ( size_t i = 0; i < czVec.size(); ++i ) + { + MEDPARTITIONER::ConnectZone* cz = czVec[i]; + if ( !cz || cz->getNodeNumber() < 1 ) + continue; + if ( cz->getDistantDomainNumber() < cz->getLocalDomainNumber() ) + continue; // treat a pair of domains once + + MEDPARTITIONER::ConnectZone* cz21 = 0; // zone 2 -> 1 + for ( size_t j = 0; j < czVec.size() && !cz21; ++j ) + if ( czVec[j] && + czVec[j]->getLocalDomainNumber () == cz->getDistantDomainNumber() && + czVec[j]->getDistantDomainNumber() == cz->getLocalDomainNumber() ) + cz21 = czVec[j]; + + // separate ids of two domains + const ParaMEDMEM::MEDCouplingSkyLineArray *corrArray = cz->getNodeCorresp(); + const DataArrayInt *ids12 = corrArray->getValueArray(); + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> ids1, ids2, ids12Sorted; + ids1 = ids12->selectByTupleId2( 0, corrArray->getLength(), 2 ); + ids2 = ids12->selectByTupleId2( 1, corrArray->getLength(), 2 ); + + ids12Sorted = sortCorrespondences( ids1, ids2, /*delta=*/0, removeEqual ); + cz->setNodeCorresp( ids12Sorted->begin(), ids12Sorted->getNbOfElems() / 2 ); + + if ( cz21 )// set 2->1 correspondence + { + ids12Sorted = sortCorrespondences( ids2, ids1, /*delta=*/0, false ); + cz->setNodeCorresp( ids12Sorted->begin(), ids12Sorted->getNbOfElems() / 2 ); + } + } +} + +//================================================================================ +/*! + * \brief Find faces common with neighbor domains and put them in "JOINT_n_p_Faces" + * group (where "n" and "p" are domain IDs) + */ +//================================================================================ + +void MEDPARTITIONER::MeshCollection::buildBoundaryFaces() +{ + if (_topology->nbDomain() < 2 || !_subdomain_boundary_creates ) + return; + + if ( getMeshDimension() < 2 ) + return; + + using ParaMEDMEM::MEDCouplingUMesh; + using ParaMEDMEM::DataArrayDouble; + using ParaMEDMEM::DataArrayInt; + + std::vector<MEDCouplingUMesh*>& faceMeshes = getFaceMesh(); + int nbMeshes = faceMeshes.size(); + + //preparing bounding box trees for accelerating search of coincident faces + std::vector<BBTreeOfDim* > bbTrees(nbMeshes); + std::vector<DataArrayDouble*>bbox (nbMeshes); + for (int inew = 0; inew < nbMeshes-1; inew++) + if ( !isParallelMode() || _domain_selector->isMyDomain(inew) ) + { + DataArrayDouble* bcCoords = faceMeshes[inew]->getBarycenterAndOwner(); + bbox [inew] = bcCoords->computeBBoxPerTuple(1.e-6); + bbTrees[inew] = new BBTreeOfDim( bcCoords->getNumberOfComponents(), + bbox[inew]->getConstPointer(),0,0, + bbox[inew]->getNumberOfTuples()); + bcCoords->decrRef(); + } + + // loop on domains to find joint faces between them + for (int inew1 = 0; inew1 < nbMeshes; inew1++ ) + { + for (int inew2 = inew1+1; inew2 < nbMeshes; inew2++ ) + { + MEDCouplingUMesh* mesh1 = 0; + MEDCouplingUMesh* mesh2 = 0; + //MEDCouplingUMesh* recvMesh = 0; + bool mesh1Here = true, mesh2Here = true; + if (isParallelMode()) + { +#ifdef HAVE_MPI + mesh1Here = _domain_selector->isMyDomain(inew1); + mesh2Here = _domain_selector->isMyDomain(inew2); + if ( !mesh1Here && mesh2Here ) + { + //send mesh2 to domain of mesh1 + _domain_selector->sendMesh(*faceMeshes[inew2], + _domain_selector->getProcessorID(inew1)); + } + else if ( mesh1Here && !mesh2Here ) + { + //receiving mesh2 from a distant domain + _domain_selector->recvMesh(mesh2,_domain_selector->getProcessorID(inew2)); + if ( faceMeshes[ inew2 ] ) + faceMeshes[ inew2 ]->decrRef(); + faceMeshes[ inew2 ] = mesh2; + } +#endif + } + if ( mesh1Here && !mesh1 ) mesh1 = faceMeshes[ inew1 ]; + if ( mesh2Here && !mesh2 ) mesh2 = faceMeshes[ inew2 ]; + + // find coincident faces + std::vector< int > faces1, faces2; + if ( mesh1 && mesh2 ) + { + const DataArrayDouble* coords2 = mesh2->getBarycenterAndOwner(); + const double* c2 = coords2->getConstPointer(); + const int dim = coords2->getNumberOfComponents(); + const int nbFaces2 = mesh2->getNumberOfCells(); + const int nbFaces1 = mesh1->getNumberOfCells(); + + for (int i2 = 0; i2 < nbFaces2; i2++) + { + std::vector<int> coincFaces; + bbTrees[inew1]->getElementsAroundPoint( c2+i2*dim, coincFaces ); + if (coincFaces.size()!=0) + { + int i1 = coincFaces[0]; + // if ( coincFaces.size() > 1 ) + // { + // i2nb = isource2nb.insert( std::make_pair( i1 , 0 )).first; + // i1 = coincFaces[ i2nb->second++ ]; + // } + if ( i1 < nbFaces1 ) // protection from invalid elements + { + faces1.push_back( i1 ); + faces2.push_back( i2 ); + } + } + } + coords2->decrRef(); + } + + if ( isParallelMode()) + { +#ifdef HAVE_MPI + if ( mesh1Here && !mesh2Here ) + { + //send faces2 to domain of recvMesh + SendIntVec(faces2, _domain_selector->getProcessorID(inew2)); + } + else if ( !mesh1Here && mesh2Here ) + { + //receiving ids of faces from a domain of mesh1 + RecvIntVec(faces2, _domain_selector->getProcessorID(inew1)); + } +#endif + } + // if ( recvMesh ) + // recvMesh->decrRef(); + + // Create group "JOINT_inew1_inew2_Faces" and corresponding families + for ( int is2nd = 0; is2nd < 2; ++is2nd ) + { + createJointGroup( is2nd ? faces2 : faces1, + inew1 , inew2, is2nd ); + } + + } // loop on the 2nd domains (inew2) + } // loop on the 1st domains (inew1) + + + // delete bounding box trees + for (int inew = 0; inew < nbMeshes-1; inew++) + if (isParallelMode() && _domain_selector->isMyDomain(inew)) + { + bbox[inew]->decrRef(); + delete bbTrees[inew]; + } +} + +//================================================================================ +/*! + * \brief Create group "JOINT_inew1_inew2_Faces" and corresponding families + * \param faces - face ids to include into the group + * \param inew1 - index of the 1st domain + * \param inew2 - index of the 2nd domain + * \param is2nd - in which (1st or 2nd) domain to create the group + */ +//================================================================================ + +void MEDPARTITIONER::MeshCollection::createJointGroup( const std::vector< int >& faces, + const int inew1, + const int inew2, + const bool is2nd ) +{ + // get the name of JOINT group + std::string groupName; + { + std::ostringstream oss; + oss << "JOINT_" + << (is2nd ? inew2 : inew1 ) << "_" + << (is2nd ? inew1 : inew2 ) << "_" + << ( getMeshDimension()==2 ? "Edge" : "Face" ); + groupName = oss.str(); + } + + // remove existing "JOINT_*" group + _group_info.erase( groupName ); + + // get family IDs array + int* famIDs = 0; + int inew = (is2nd ? inew2 : inew1 ); + int totalNbFaces = _face_mesh[ inew ] ? _face_mesh[ inew ]->getNumberOfCells() : 0; + std::string cle = Cle1ToStr( "faceFamily_toArray", inew ); + if ( !_map_dataarray_int.count(cle) ) + { + if ( totalNbFaces > 0 ) + { + ParaMEDMEM::DataArrayInt* p=ParaMEDMEM::DataArrayInt::New(); + p->alloc( totalNbFaces, 1 ); + p->fillWithZero(); + famIDs = p->getPointer(); + _map_dataarray_int[cle]=p; + } + } + else + { + famIDs = _map_dataarray_int.find(cle)->second->getPointer(); + } + // find a family ID of an existing JOINT group + int familyID = 0; + std::map<std::string, int>::iterator name2id = _family_info.find( groupName ); + if ( name2id != _family_info.end() ) + familyID = name2id->second; + + // remove faces from the familyID-the family + if ( familyID != 0 && famIDs ) + for ( int i = 0; i < totalNbFaces; ++i ) + if ( famIDs[i] == familyID ) + famIDs[i] = 0; + + if ( faces.empty() ) + return; + + if ( familyID == 0 ) // generate a family ID for JOINT group + { + std::set< int > familyIDs; + for ( name2id = _family_info.begin(); name2id != _family_info.end(); ++name2id ) + familyIDs.insert( name2id->second ); + // find the next free family ID + int freeIdCount = inew1 * getNbOfGlobalMeshes() + inew2 + is2nd; + do + { + if ( !familyIDs.count( ++familyID )) + --freeIdCount; + } + while ( freeIdCount > 0 ); + } + + // push faces to familyID-th group + if ( faces.back() >= totalNbFaces ) + throw INTERP_KERNEL::Exception("MeshCollection::createJointGroup(): to high face ID"); + for ( size_t i = 0; i < faces.size(); ++i ) + famIDs[ faces[i] ] = familyID; + + // register JOINT group and family + _family_info[ groupName ] = familyID; // name of the group and family is same + _group_info [ groupName ].push_back( groupName ); +} + +/*! constructing the MESH collection from a distributed file + * + * \param filename name of the master file containing the list of all the MED files + */ +MEDPARTITIONER::MeshCollection::MeshCollection(const std::string& filename) + : _topology(0), + _owns_topology(true), + _driver(0), + _domain_selector( 0 ), + _i_non_empty_mesh(-1), + _driver_type(MEDPARTITIONER::Undefined), + _subdomain_boundary_creates(MyGlobals::_Creates_Boundary_Faces), + _family_splitting(false), + _create_empty_groups(false), + _joint_finder(0) +{ + try + { + _driver=new MeshCollectionMedXmlDriver(this); + _driver->read (filename.c_str()); + _driver_type = MedXml; + } + catch(...) + { // Handle all exceptions + if ( _driver ) delete _driver; _driver=0; + try + { + _driver=new MeshCollectionMedAsciiDriver(this); + _driver->read (filename.c_str()); + _driver_type=MedAscii; + } + catch(...) + { + delete _driver; + _driver=0; + throw INTERP_KERNEL::Exception("file does not comply with any recognized format"); + } + } + for ( int idomain = 0; idomain < (int)_mesh.size(); ++idomain ) + if ( _mesh[idomain] && _mesh[idomain]->getNumberOfNodes() > 0 ) + _i_non_empty_mesh = idomain; +} + +/*! Constructing the MESH collection from selected domains of a distributed file + * + * \param filename - name of the master file containing the list of all the MED files + * \param domainSelector - selector of domains to load + */ +MEDPARTITIONER::MeshCollection::MeshCollection(const std::string& filename, ParaDomainSelector& domainSelector) + : _topology(0), + _owns_topology(true), + _driver(0), + _domain_selector( &domainSelector ), + _i_non_empty_mesh(-1), + _driver_type(MEDPARTITIONER::Undefined), + _subdomain_boundary_creates(MyGlobals::_Creates_Boundary_Faces), + _family_splitting(false), + _create_empty_groups(false), + _joint_finder(0) +{ + std::string myfile=filename; + std::size_t found=myfile.find(".xml"); + if (found!=std::string::npos) //file .xml + { + try + { + _driver=new MeshCollectionMedXmlDriver(this); + _driver->read ( filename.c_str(), _domain_selector ); + _driver_type = MedXml; + } + catch(...) + { // Handle all exceptions + delete _driver; + throw INTERP_KERNEL::Exception("file .xml does not comply with any recognized format"); + } + } + else + { + found=myfile.find(".med"); + if (found!=std::string::npos) //file .med single + { + //make a temporary file .xml and retry MedXmlDriver + std::string xml="\ +<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n \ +<root>\n \ + <version maj=\"2\" min=\"3\" ver=\"1\"/>\n \ + <description what=\"\" when=\"\"/>\n \ + <content>\n \ + <mesh name=\"$meshName\"/>\n \ + </content>\n \ + <splitting>\n \ + <subdomain number=\"1\"/>\n \ + <global_numbering present=\"no\"/>\n \ + </splitting>\n \ + <files>\n \ + <subfile id=\"1\">\n \ + <name>$fileName</name>\n \ + <machine>localhost</machine>\n \ + </subfile>\n \ + </files>\n \ + <mapping>\n \ + <mesh name=\"$meshName\">\n \ + <chunk subdomain=\"1\">\n \ + <name>$meshName</name>\n \ + </chunk>\n \ + </mesh>\n \ + </mapping>\n \ +</root>\n"; + std::vector<std::string> meshNames=MEDLoader::GetMeshNames(myfile); + xml.replace(xml.find("$fileName"),9,myfile); + xml.replace(xml.find("$meshName"),9,meshNames[0]); + xml.replace(xml.find("$meshName"),9,meshNames[0]); + xml.replace(xml.find("$meshName"),9,meshNames[0]); + std::string nameFileXml(myfile); + nameFileXml.replace(nameFileXml.find(".med"),4,".xml"); + std::string nameFileXmlDN,nameFileXmlBN; + MEDLoaderBase::getDirAndBaseName(nameFileXml,nameFileXmlDN,nameFileXmlBN); + nameFileXml=MEDLoaderBase::joinPath(nameFileXmlDN,"medpartitioner_"+nameFileXmlBN); + if (_domain_selector->rank()==0) //only on to write it + { + std::ofstream f(nameFileXml.c_str()); + f<<xml; + f.close(); + } +#ifdef HAVE_MPI + if (MyGlobals::_World_Size>1) + MPI_Barrier(MPI_COMM_WORLD); //wait for creation of nameFileXml +#endif + try + { + _driver=new MeshCollectionMedXmlDriver(this); + _driver->read ( nameFileXml.c_str(), _domain_selector ); + _driver_type = MedXml; + } + catch(...) + { // Handle all exceptions + delete _driver; _driver=0; + throw INTERP_KERNEL::Exception("file medpartitioner_xxx.xml does not comply with any recognized format"); + } + } + else //no extension + { + try + { + _driver=new MeshCollectionMedAsciiDriver(this); + _driver->read ( filename.c_str(), _domain_selector ); + _driver_type=MedAscii; + } + catch(...) + { + delete _driver; + _driver=0; + throw INTERP_KERNEL::Exception("file name with no extension does not comply with any recognized format"); + } + } + } + // find non-empty domain mesh + for ( int idomain = 0; idomain < (int)_mesh.size(); ++idomain ) + if ( _mesh[idomain] && _mesh[idomain]->getNumberOfNodes() > 0 ) + _i_non_empty_mesh = idomain; + + try + { + //check for all proc/file compatibility of _field_descriptions +#ifdef HAVE_MPI + _field_descriptions=AllgathervVectorOfString(MyGlobals::_Field_Descriptions); +#else + _field_descriptions=MyGlobals::_Field_Descriptions; +#endif + } + catch(INTERP_KERNEL::Exception& e) + { + std::cerr << "proc " << MyGlobals::_Rank << " : INTERP_KERNEL_Exception : " << e.what() << std::endl; + throw INTERP_KERNEL::Exception("Something wrong verifying coherency of files med ands fields"); + } +#ifdef HAVE_MPI + try + { + //check for all proc/file compatibility of _family_info + std::vector<std::string> v2=AllgathervVectorOfString(VectorizeFromMapOfStringInt(_family_info)); + _family_info=DevectorizeToMapOfStringInt(v2); + } + catch(INTERP_KERNEL::Exception& e) + { + std::cerr << "proc " << MyGlobals::_Rank << " : INTERP_KERNEL_Exception : " << e.what() << std::endl; + throw INTERP_KERNEL::Exception("Something wrong merging all familyInfo"); + } + + try + { + //check for all proc/file compatibility of _group_info + std::vector<std::string> v2=AllgathervVectorOfString(VectorizeFromMapOfStringVectorOfString(_group_info)); + _group_info=DeleteDuplicatesInMapOfStringVectorOfString(DevectorizeToMapOfStringVectorOfString(v2)); + } + catch(INTERP_KERNEL::Exception& e) + { + std::cerr << "proc " << MyGlobals::_Rank << " : INTERP_KERNEL_Exception : " << e.what() << std::endl; + throw INTERP_KERNEL::Exception("Something wrong merging all groupInfo"); + } +#endif +} + +/*! constructing the MESH collection from a sequential MED-file + * + * \param filename MED file + * \param meshname name of the mesh that is to be read + */ +MEDPARTITIONER::MeshCollection::MeshCollection(const std::string& filename, const std::string& meshname) + : _topology(0), + _owns_topology(true), + _driver(0), + _domain_selector( 0 ), + _i_non_empty_mesh(-1), + _name(meshname), + _driver_type(MEDPARTITIONER::MedXml), + _subdomain_boundary_creates(MyGlobals::_Creates_Boundary_Faces), + _family_splitting(false), + _create_empty_groups(false), + _joint_finder(0) +{ + try // avoid memory leak in case of inexistent filename + { + retrieveDriver()->readSeq (filename.c_str(),meshname.c_str()); + } + catch (...) + { + delete _driver; + _driver=0; + throw INTERP_KERNEL::Exception("problem reading .med files"); + } + if ( _mesh[0] && _mesh[0]->getNumberOfNodes() > 0 ) + _i_non_empty_mesh = 0; +} + +MEDPARTITIONER::MeshCollection::~MeshCollection() +{ + for (int i=0; i<(int)_mesh.size();i++) + if (_mesh[i]!=0) _mesh[i]->decrRef(); + + for (int i=0; i<(int)_cell_family_ids.size();i++) + if (_cell_family_ids[i]!=0) + _cell_family_ids[i]->decrRef(); + + for (int i=0; i<(int)_face_mesh.size();i++) + if (_face_mesh[i]!=0) + _face_mesh[i]->decrRef(); + + for (int i=0; i<(int)_face_family_ids.size();i++) + if (_face_family_ids[i]!=0) + _face_family_ids[i]->decrRef(); + + for (std::map<std::string, ParaMEDMEM::DataArrayInt*>::iterator it=_map_dataarray_int.begin() ; it!=_map_dataarray_int.end(); it++ ) + if ((*it).second!=0) + (*it).second->decrRef(); + + for (std::map<std::string, ParaMEDMEM::DataArrayDouble*>::iterator it=_map_dataarray_double.begin() ; it!=_map_dataarray_double.end(); it++ ) + if ((*it).second!=0) + (*it).second->decrRef(); + + delete _driver; + if (_topology!=0 && _owns_topology) + delete _topology; +#ifdef HAVE_MPI + delete _joint_finder; +#endif +} + +/*! constructing the MESH collection from a file + * + * The method creates as many MED-files as there are domains in the + * collection. It also creates a master file that lists all the MED files. + * The MED files created in ths manner contain joints that describe the + * connectivity between subdomains. + * + * \param filename name of the master file that will contain the list of the MED files + * + */ +void MEDPARTITIONER::MeshCollection::write(const std::string& filename) +{ + //suppresses link with driver so that it can be changed for writing + delete _driver; + _driver=0; + retrieveDriver()->write (filename.c_str(), _domain_selector); +} + +/*! creates or gets the link to the collection driver + */ +MEDPARTITIONER::MeshCollectionDriver* MEDPARTITIONER::MeshCollection::retrieveDriver() +{ + if (_driver==0) + { + switch(_driver_type) + { + case MedXml: + _driver=new MeshCollectionMedXmlDriver(this); + break; + case MedAscii: + _driver=new MeshCollectionMedAsciiDriver(this); + break; + default: + throw INTERP_KERNEL::Exception("Unrecognized driver"); + } + } + return _driver; +} + + +/*! gets an existing driver + * + */ +MEDPARTITIONER::MeshCollectionDriver* MEDPARTITIONER::MeshCollection::getDriver() const +{ + return _driver; +} + +/*! + * retrieves the mesh dimension +*/ +int MEDPARTITIONER::MeshCollection::getMeshDimension() const +{ + return _i_non_empty_mesh < 0 ? -1 : _mesh[_i_non_empty_mesh]->getMeshDimension(); +} + +int MEDPARTITIONER::MeshCollection::getNbOfLocalMeshes() const +{ + int nb=0; + for (size_t i=0; i<_mesh.size(); i++) + { + if (_mesh[i]) nb++; + } + return nb; +} + +int MEDPARTITIONER::MeshCollection::getNbOfLocalCells() const +{ + int nb=0; + for (size_t i=0; i<_mesh.size(); i++) + { + if (_mesh[i]) nb=nb+_mesh[i]->getNumberOfCells(); + } + return nb; +} + +int MEDPARTITIONER::MeshCollection::getNbOfLocalFaces() const +{ + int nb=0; + for (size_t i=0; i<_face_mesh.size(); i++) + { + if (_face_mesh[i]) nb=nb+_face_mesh[i]->getNumberOfCells(); + } + return nb; +} + +std::vector<ParaMEDMEM::MEDCouplingUMesh*>& MEDPARTITIONER::MeshCollection::getMesh() +{ + return _mesh; +} + +std::vector<ParaMEDMEM::MEDCouplingUMesh*>& MEDPARTITIONER::MeshCollection::getFaceMesh() +{ + return _face_mesh; +} + +ParaMEDMEM::MEDCouplingUMesh* MEDPARTITIONER::MeshCollection::getMesh(int idomain) const +{ + return _mesh[idomain]; +} + +ParaMEDMEM::MEDCouplingUMesh* MEDPARTITIONER::MeshCollection::getFaceMesh(int idomain) +{ + return _face_mesh[idomain]; +} + +std::vector<MEDPARTITIONER::ConnectZone*>& MEDPARTITIONER::MeshCollection::getCZ() +{ + if ( _topology ) + return _topology->getCZ(); + + static std::vector<MEDPARTITIONER::ConnectZone*> noCZ; + return noCZ; +} + +MEDPARTITIONER::Topology* MEDPARTITIONER::MeshCollection::getTopology() const +{ + return _topology; +} + +void MEDPARTITIONER::MeshCollection::setTopology(Topology* topo, bool takeOwneship) +{ + if (_topology!=0) + { + throw INTERP_KERNEL::Exception("topology is already set"); + } + else + { + _topology = topo; + _owns_topology = takeOwneship; + } +} + +/*! Method creating the cell graph in serial mode + * + * \param array returns the pointer to the structure that contains the graph + * \param edgeweight returns the pointer to the table that contains the edgeweights + * (only used if indivisible regions are required) + */ +void MEDPARTITIONER::MeshCollection::buildCellGraph(ParaMEDMEM::MEDCouplingSkyLineArray* & array, int *& edgeweights ) +{ + + using std::map; + using std::vector; + using std::make_pair; + using std::pair; + + if (_topology->nbDomain()>1) throw INTERP_KERNEL::Exception("buildCellGraph should be used for one domain only"); + const ParaMEDMEM::MEDCouplingUMesh* mesh=_mesh[0]; + if (MyGlobals::_Verbose>50) + std::cout<<"getting nodal connectivity"<<std::endl; + + //looking for reverse nodal connectivity i global numbering + if (isParallelMode() && !_domain_selector->isMyDomain(0)) + { + vector<int> value; + vector<int> index(1,0); + + array=new ParaMEDMEM::MEDCouplingSkyLineArray(index,value); + return; + } + array=mesh->generateGraph(); +} +/*! Method creating the cell graph in multidomain mode + * + * \param array returns the pointer to the structure that contains the graph + * \param edgeweight returns the pointer to the table that contains the edgeweights + * (only used if indivisible regions are required) + */ +void MEDPARTITIONER::MeshCollection::buildParallelCellGraph(ParaMEDMEM::MEDCouplingSkyLineArray* & array, int *& edgeweights ) +{ + using std::multimap; + using std::vector; + using std::make_pair; + using std::pair; + + std::multimap< int, int > node2cell; + std::map< pair<int,int>, int > cell2cellcounter; + std::multimap<int,int> cell2cell; + + std::vector<std::vector<std::multimap<int,int> > > commonDistantNodes; + int nbdomain=_topology->nbDomain(); +#ifdef HAVE_MPI + if (isParallelMode()) + { + _joint_finder=new JointFinder(*this); + _joint_finder->findCommonDistantNodes(); + commonDistantNodes=_joint_finder->getDistantNodeCell(); + } + + if (MyGlobals::_Verbose>500) + _joint_finder->print(); +#endif + + if (MyGlobals::_Verbose>50) + std::cout<<"getting nodal connectivity"<<std::endl; + //looking for reverse nodal connectivity i global numbering + int meshDim = 3; + for (int idomain=0; idomain<nbdomain; idomain++) + { + if (isParallelMode() && !_domain_selector->isMyDomain(idomain)) + continue; + meshDim = _mesh[idomain]->getMeshDimension(); + + ParaMEDMEM::DataArrayInt* index=ParaMEDMEM::DataArrayInt::New(); + ParaMEDMEM::DataArrayInt* revConn=ParaMEDMEM::DataArrayInt::New(); + int nbNodes=_mesh[idomain]->getNumberOfNodes(); + _mesh[idomain]->getReverseNodalConnectivity(revConn,index); + //problem saturation over 1 000 000 nodes for 1 proc + if (MyGlobals::_Verbose>100) + std::cout << "proc " << MyGlobals::_Rank << " : getReverseNodalConnectivity done on " << nbNodes << " nodes" << std::endl; + int* index_ptr=index->getPointer(); + int* revConnPtr=revConn->getPointer(); + for (int i=0; i<nbNodes; i++) + { + for (int icell=index_ptr[i]; icell<index_ptr[i+1]; icell++) + { + int globalNode=_topology->convertNodeToGlobal(idomain,i); + int globalCell=_topology->convertCellToGlobal(idomain,revConnPtr[icell]); + node2cell.insert(make_pair(globalNode, globalCell)); + } + } + revConn->decrRef(); + index->decrRef(); +#ifdef HAVE_MPI + for (int iother=0; iother<nbdomain; iother++) + { + std::multimap<int,int>::iterator it; + int isource=idomain; + int itarget=iother; + for (it=_joint_finder->getDistantNodeCell()[isource][itarget].begin(); + it!=_joint_finder->getDistantNodeCell()[isource][itarget].end(); it++) + { + int globalNode=_topology->convertNodeToGlobal(idomain,(*it).first); + int globalCell=(*it).second; + node2cell.insert(make_pair(globalNode, globalCell)); + } + } +#endif + } //endfor idomain + + //creating graph arcs (cell to cell relations) + //arcs are stored in terms of (index,value) notation + // 0 3 5 6 6 + // 1 2 3 2 3 3 + // means 6 arcs (0,1), (0,2), (0,3), (1,2), (1,3), (2,3) + // in present version arcs are not doubled but reflexive (1,1) arcs are present for each cell + + //warning here one node have less than or equal effective number of cell with it + //but cell could have more than effective nodes + //because other equals nodes in other domain (with other global inode) + if (MyGlobals::_Verbose>50) + std::cout<< "proc " << MyGlobals::_Rank << " : creating graph arcs on nbNodes " << _topology->nbNodes() << std::endl; + + for (int inode=0;inode<_topology->nbNodes();inode++) + { + typedef multimap<int,int>::const_iterator MI; + std::pair <MI,MI> nodeRange=node2cell.equal_range(inode); + for (MI cell1=nodeRange.first;cell1!=nodeRange.second;cell1++) + for (MI cell2=nodeRange.first;cell2!=cell1;cell2++) + { + int icell1=cell1->second; + int icell2=cell2->second; + if (icell1>icell2) {int tmp=icell1; icell1=icell2; icell2=tmp;} + std::map<pair<int,int>,int>::iterator it=cell2cellcounter.find(make_pair(icell1,icell2)); + if (it==cell2cellcounter.end()) cell2cellcounter.insert(make_pair(make_pair(icell1,icell2),1)); + else (it->second)++; + } + } + // for (int icell1=0; icell1<_topology->nbCells(); icell1++) //on all nodes + // { + // typedef multimap<int,int>::const_iterator MI; + // std::pair <MI,MI> nodeRange=cell2node.equal_range(icell1); + // for (MI node1=nodeRange.first; node1!=nodeRange.second; node1++) //on nodes with icell + // { + // std::pair<MI,MI> cellRange=node2cell.equal_range(node1->second); + // for (MI cell2=cellRange.first; cell2!=cellRange.second; cell2++) //on one of these cell + // { + // int icell2=cell2->second; + // std::map<pair<int,int>,int>::iterator it=cell2cellcounter.find(make_pair(icell1,icell2)); + // if (it==cell2cellcounter.end()) cell2cellcounter.insert(make_pair(make_pair(icell1,icell2),1)); + // else (it->second)++; + // } + // } + // } + + + //converting the counter to a multimap structure + for (std::map<pair<int,int>,int>::const_iterator it=cell2cellcounter.begin(); + it!=cell2cellcounter.end(); + it++) + if (it->second>=meshDim) + { + cell2cell.insert(std::make_pair(it->first.first,it->first.second)); + cell2cell.insert(std::make_pair(it->first.second, it->first.first)); + } + + + if (MyGlobals::_Verbose>50) + std::cout << "proc " << MyGlobals::_Rank << " : create skylinearray" << std::endl; + //filling up index and value to create skylinearray structure + std::vector <int> index,value; + index.push_back(0); + int idep=0; + + for (int idomain=0; idomain<nbdomain; idomain++) + { + if (isParallelMode() && !_domain_selector->isMyDomain(idomain)) continue; + int nbCells=_mesh[idomain]->getNumberOfCells(); + for (int icell=0; icell<nbCells; icell++) + { + int size=0; + int globalCell=_topology->convertCellToGlobal(idomain,icell); + multimap<int,int>::iterator it; + pair<multimap<int,int>::iterator,multimap<int,int>::iterator> ret; + ret=cell2cell.equal_range(globalCell); + for (it=ret.first; it!=ret.second; ++it) + { + int ival=(*it).second; //no adding one existing yet + for (int i=idep ; i<idep+size ; i++) + { + if (value[i]==ival) + { + ival= -1; break; + } + } + if (ival!= -1) + { + value.push_back(ival); + size++; + } + } + idep=index[index.size()-1]+size; + index.push_back(idep); + } + } + + array=new ParaMEDMEM::MEDCouplingSkyLineArray(index,value); + + if (MyGlobals::_Verbose>100) + { + std::cout << "\nproc " << _domain_selector->rank() << " : end MeshCollection::buildCellGraph " << + index.size()-1 << " " << value.size() << std::endl; + int max=index.size()>15?15:index.size(); + if (index.size()>1) + { + for (int i=0; i<max; ++i) + std::cout<<index[i]<<" "; + std::cout << "... " << index[index.size()-1] << std::endl; + for (int i=0; i<max; ++i) + std::cout<< value[i] << " "; + int ll=index[index.size()-1]-1; + std::cout << "... (" << ll << ") " << value[ll-1] << " " << value[ll] << std::endl; + } + } + +} + + +/*! Creates the partition corresponding to the cell graph and the partition number + * + * \param nbdomain number of subdomains for the newly created graph + * + * returns a topology based on the new graph + */ +MEDPARTITIONER::Topology* MEDPARTITIONER::MeshCollection::createPartition(int nbdomain, + Graph::splitter_type split, + const std::string& options_string, + int *user_edge_weights, + int *user_vertices_weights) +{ + if (MyGlobals::_Verbose>10) + std::cout << "proc " << MyGlobals::_Rank << " : MeshCollection::createPartition : Building cell graph" << std::endl; + + if (nbdomain <1) + throw INTERP_KERNEL::Exception("Number of subdomains must be > 0"); + ParaMEDMEM::MEDCouplingSkyLineArray* array=0; + int* edgeweights=0; + + if (_topology->nbDomain()>1 || isParallelMode()) + buildParallelCellGraph(array,edgeweights); + else + buildCellGraph(array,edgeweights); + + Graph* cellGraph = 0; + switch (split) + { + case Graph::METIS: + if ( isParallelMode() && MyGlobals::_World_Size > 1 ) + { +#ifdef MED_ENABLE_PARMETIS + if (MyGlobals::_Verbose>10) + std::cout << "ParMETISGraph" << std::endl; + cellGraph=new ParMETISGraph(array,edgeweights); +#endif + } + if ( !cellGraph ) + { +#ifdef MED_ENABLE_METIS + if (MyGlobals::_Verbose>10) + std::cout << "METISGraph" << std::endl; + cellGraph=new METISGraph(array,edgeweights); +#endif + } + if ( !cellGraph ) + throw INTERP_KERNEL::Exception("MeshCollection::createPartition : PARMETIS/METIS is not available. Check your products, please."); + break; + + case Graph::SCOTCH: +#ifdef MED_ENABLE_SCOTCH + if (MyGlobals::_Verbose>10) + std::cout << "SCOTCHGraph" << std::endl; + cellGraph=new SCOTCHGraph(array,edgeweights); +#else + throw INTERP_KERNEL::Exception("MeshCollection::createPartition : SCOTCH is not available. Check your products, please."); +#endif + break; + } + + //!user-defined weights + if (user_edge_weights!=0) + cellGraph->setEdgesWeights(user_edge_weights); + if (user_vertices_weights!=0) + cellGraph->setVerticesWeights(user_vertices_weights); + + if (MyGlobals::_Is0verbose>10) + std::cout << "partitioning graph on " << nbdomain << " domains" << std::endl; + cellGraph->partGraph(nbdomain, options_string, _domain_selector); + + if (MyGlobals::_Is0verbose>10) + std::cout << "building new topology" << std::endl; + //cellGraph is a shared pointer + Topology *topology=0; + topology=new ParallelTopology (cellGraph, getTopology(), nbdomain, getMeshDimension()); + //cleaning + delete [] edgeweights; + delete cellGraph; + if (MyGlobals::_Verbose>11) + std::cout << "proc " << MyGlobals::_Rank << " : end MeshCollection::createPartition" << std::endl; + return topology; +} + +/*! Creates a topology for a partition specified by the user + * + * \param table user-specified partition (for each cell contains the domain number from 0 to n-1) + * + * returns a topology based on the new partition + */ +MEDPARTITIONER::Topology* MEDPARTITIONER::MeshCollection::createPartition(const int* partition) +{ + ParaMEDMEM::MEDCouplingSkyLineArray* array=0; + int* edgeweights=0; + + if ( _topology->nbDomain()>1) + buildParallelCellGraph(array,edgeweights); + else + buildCellGraph(array,edgeweights); + + Graph* cellGraph; + std::set<int> domains; + for (int i=0; i<_topology->nbCells(); i++) + { + domains.insert(partition[i]); + } + cellGraph=new UserGraph(array, partition, _topology->nbCells()); + + //cellGraph is a shared pointer + Topology *topology=0; + int nbdomain=domains.size(); + topology=new ParallelTopology (cellGraph, getTopology(), nbdomain, getMeshDimension()); + // if (array!=0) delete array; + delete cellGraph; + return topology; +} + +void MEDPARTITIONER::MeshCollection::setDomainNames(const std::string& name) +{ + for (int i=0; i<_topology->nbDomain(); i++) + { + std::ostringstream oss; + oss<<name<<"_"<<i; + if (!isParallelMode() || _domain_selector->isMyDomain(i)) + _mesh[i]->setName(oss.str()); + } +} + +ParaMEDMEM::DataArrayDouble *MEDPARTITIONER::MeshCollection::getField(std::string descriptionField, int iold) +//getField look for and read it if not done, and assume decrRef() in ~MeshCollection; +//something like MEDCouplingFieldDouble *f2=MEDLoader::ReadFieldCell(name,f1->getMesh()->getName(),0,f1->getName(),0,1); +{ + int rank=MyGlobals::_Rank; + std::string tag="ioldFieldDouble="+IntToStr(iold); + std::string descriptionIold=descriptionField+SerializeFromString(tag); + if (_map_dataarray_double.find(descriptionIold)!=_map_dataarray_double.end()) + { + if (MyGlobals::_Verbose>300) + std::cout << "proc " << rank << " : YET READ getField : " << descriptionIold << std::endl; + ParaMEDMEM::DataArrayDouble* res=_map_dataarray_double[descriptionIold]; + return res; + } + if (MyGlobals::_Verbose>200) + std::cout << "proc " << rank << " : TO BE READ getField : " << descriptionIold << std::endl; + std::string description, fileName, meshName, fieldName; + int typeField, DT, IT, entity; + fileName=MyGlobals::_File_Names[iold]; + if (MyGlobals::_Verbose>10) + std::cout << "proc " << MyGlobals::_Rank << " : in " << fileName << " " << iold << " " << descriptionIold << std::endl; + FieldShortDescriptionToData(descriptionIold, fieldName, typeField, entity, DT, IT); + meshName=MyGlobals::_Mesh_Names[iold]; + + ParaMEDMEM::MEDCouplingFieldDouble* f2=MEDLoader::ReadField((ParaMEDMEM::TypeOfField) typeField, + fileName, meshName, 0, fieldName, DT, IT); + + ParaMEDMEM::DataArrayDouble* res=f2->getArray(); + //to know names of components + std::vector<std::string> browse=BrowseFieldDouble(f2); + std::string localFieldInformation=descriptionIold+SerializeFromVectorOfString(browse); + if (MyGlobals::_Verbose>10) + std::cout << "proc " << MyGlobals::_Rank << " : localFieldInformation : " << localFieldInformation << std::endl; + MyGlobals::_General_Informations.push_back(localFieldInformation); + res->incrRef(); + f2->decrRef(); + _map_dataarray_double[descriptionIold]=res; + return res; +} + +void MEDPARTITIONER::MeshCollection::prepareFieldDescriptions() +//to have unique valid fields names/pointers/descriptions for partitionning +//filter _field_descriptions to be in all procs compliant and equal +{ + int nbfiles=MyGlobals::_File_Names.size(); //nb domains + if (nbfiles==0) + { + nbfiles=_topology->nbDomain(); + } + std::vector<std::string> r2; + //from allgatherv then vector(procs) of serialised vector(fields) of vector(description) data + for (int i=0; i<(int)_field_descriptions.size(); i++) + { + std::vector<std::string> r1=DeserializeToVectorOfString(_field_descriptions[i]); + for (int ii=0; ii<(int)r1.size(); ii++) + r2.push_back(r1[ii]); + } + //here vector(procs*fields) of serialised vector(description) data + _field_descriptions=r2; + int nbfields=_field_descriptions.size(); //on all domains + if ((nbfields%nbfiles)!=0) + { + if (MyGlobals::_Rank==0) + { + std::cerr<< "\nERROR : incoherent number of fields references in all files .med\n" << std::endl + << "fileMedNames :" << std::endl + << ReprVectorOfString(MyGlobals::_File_Names) + << "field_descriptions :" << std::endl + << ReprVectorOfString(MyGlobals::_Field_Descriptions); + } + throw INTERP_KERNEL::Exception("incoherent number of fields references in all files .med\n"); + } + _field_descriptions.resize(nbfields/nbfiles); + for (int i=0; i<(int)_field_descriptions.size(); i++) + { + std::string str=_field_descriptions[i]; + str=EraseTagSerialized(str,"idomain="); + str=EraseTagSerialized(str,"fileName="); + _field_descriptions[i]=str; + } +} + +//returns true if inodes of a face are in inodes of a cell +bool isFaceOncell(std::vector< int >& inodesFace, std::vector< int >& inodesCell) +{ + int ires=0; + int nbok=inodesFace.size(); + for (int i=0; i<nbok; i++) + { + int ii=inodesFace[i]; + if (ii<0) + std::cout << "isFaceOncell problem inodeface<0" << std::endl; + for (int j=0; j<(int)inodesCell.size(); j++) + { + if (ii==inodesCell[j]) + { + ires=ires+1; + break; //inode of face found + } + } + if (ires<i+1) + break; //inode of face not found do not continue... + } + return (ires==nbok); +} + +void MEDPARTITIONER::MeshCollection::filterFaceOnCell() +{ + for (int inew=0; inew<_topology->nbDomain(); inew++) + { + if (!isParallelMode() || _domain_selector->isMyDomain(inew)) + { + if (MyGlobals::_Verbose>200) + std::cout << "proc " << MyGlobals::_Rank << " : filterFaceOnCell on inewDomain " << inew << " nbOfFaces " << _face_mesh[inew]->getNumberOfCells() << std::endl; + ParaMEDMEM::MEDCouplingUMesh* mcel=_mesh[inew]; + ParaMEDMEM::MEDCouplingUMesh* mfac=_face_mesh[inew]; + + //to have cellnode=f(facenode)... inodeCell=nodeIds[inodeFace] + std::vector<int> nodeIds; + getNodeIds(*mcel, *mfac, nodeIds); + if (nodeIds.size()==0) + continue; //one empty mesh nothing to do + + ParaMEDMEM::DataArrayInt *revNodalCel=ParaMEDMEM::DataArrayInt::New(); + ParaMEDMEM::DataArrayInt *revNodalIndxCel=ParaMEDMEM::DataArrayInt::New(); + mcel->getReverseNodalConnectivity(revNodalCel,revNodalIndxCel); + int *revC=revNodalCel->getPointer(); + int *revIndxC=revNodalIndxCel->getPointer(); + + std::vector< int > faceOnCell; + std::vector< int > faceNotOnCell; + int nbface=mfac->getNumberOfCells(); + for (int iface=0; iface<nbface; iface++) + { + bool ok; + std::vector< int > inodesFace; + mfac->getNodeIdsOfCell(iface, inodesFace); + int nbnodFace=inodesFace.size(); + if ( nbnodFace != mfac->getNumberOfNodesInCell( iface )) + continue; // invalid node ids + //set inodesFace in mcel + int nbok = 0; + for (int i=0; i<nbnodFace; i++) + nbok += (( inodesFace[i]=nodeIds[inodesFace[i]] ) >= 0 ); + if ( nbok != nbnodFace ) + continue; + int inod=inodesFace[0]; + if (inod<0) + { + std::cout << "filterFaceOnCell problem 1" << std::endl; + continue; + } + int nbcell=revIndxC[inod+1]-revIndxC[inod]; + for (int j=0; j<nbcell; j++) //look for each cell with inod + { + int icel=revC[revIndxC[inod]+j]; + std::vector< int > inodesCell; + mcel->getNodeIdsOfCell(icel, inodesCell); + ok=isFaceOncell(inodesFace, inodesCell); + if (ok) break; + } + if (ok) + { + faceOnCell.push_back(iface); + } + else + { + faceNotOnCell.push_back(iface); + if (MyGlobals::_Is0verbose>300) + std::cout << "face NOT on cell " << iface << " " << faceOnCell.size()-1 << std::endl; + } + } + + revNodalCel->decrRef(); + revNodalIndxCel->decrRef(); + + // std::string keyy; + // keyy=Cle1ToStr("filterFaceOnCell",inew); + // _map_dataarray_int[keyy]=CreateDataArrayIntFromVector(faceOnCell); + // keyy=Cle1ToStr("filterNotFaceOnCell",inew); + // _map_dataarray_int[keyy]=CreateDataArrayIntFromVector(faceNotOnCell); + + // filter the face mesh + if ( faceOnCell.empty() ) + _face_mesh[inew] = CreateEmptyMEDCouplingUMesh(); + else + _face_mesh[inew] = (ParaMEDMEM::MEDCouplingUMesh *) + mfac->buildPartOfMySelf( &faceOnCell[0], &faceOnCell[0] + faceOnCell.size(),true); + mfac->decrRef(); + + // filter the face families + std::string key = Cle1ToStr("faceFamily_toArray",inew); + if ( getMapDataArrayInt().count( key )) + { + ParaMEDMEM::DataArrayInt * & fam = getMapDataArrayInt()[ key ]; + ParaMEDMEM::DataArrayInt * famFilter = ParaMEDMEM::DataArrayInt::New(); + famFilter->alloc(faceOnCell.size(),1); + int* pfamFilter = famFilter->getPointer(); + int* pfam = fam->getPointer(); + for ( size_t i=0; i<faceOnCell.size(); i++ ) + pfamFilter[i]=pfam[faceOnCell[i]]; + fam->decrRef(); + fam = famFilter; + } + } + } +} diff --git a/src/medtool/src/MEDPartitioner/MEDPARTITIONER_MeshCollection.hxx b/src/medtool/src/MEDPartitioner/MEDPARTITIONER_MeshCollection.hxx new file mode 100644 index 000000000..7f7ad1316 --- /dev/null +++ b/src/medtool/src/MEDPartitioner/MEDPARTITIONER_MeshCollection.hxx @@ -0,0 +1,250 @@ +// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// + +#ifndef __MEDPARTITIONER_MESHCOLLECTION_HXX__ +#define __MEDPARTITIONER_MESHCOLLECTION_HXX__ + +#include "MEDPARTITIONER.hxx" +#include "MEDPARTITIONER_Graph.hxx" +#include "MEDPARTITIONER_Utils.hxx" + +#include <map> +#include <vector> +#include <string> + +#include "BBTree.txx" + +namespace ParaMEDMEM +{ + class MEDCouplingUMesh; + class DataArrayInt; + class MEDCouplingSkyLineArray; +} + +namespace MEDPARTITIONER +{ + class Topology; + class MeshCollectionDriver; + class ParaDomainSelector; + class ConnectZone; + class JointFinder; + + typedef enum{MedAscii, MedXml, Undefined} DriverType; + typedef std::multimap<std::pair<int,int>, std::pair<int,int> > NodeMapping ; + typedef std::vector<std::pair<int,int> > NodeList; + + class MEDPARTITIONER_EXPORT MeshCollection + { + public: + MeshCollection(); + //Constructing from an existing mesh and a new topology + MeshCollection(MeshCollection&, Topology*, bool family_splitting=false, bool create_empty_groups=false); + //Constructing the mesh collection from a file + MeshCollection(const std::string& filename); + //Constructing the mesh collection from a file + MeshCollection(const std::string& filename, ParaDomainSelector& domainSelector); + //Constructing the mesh collection from a file + MeshCollection(const std::string& filename, const std::string& meshname); + ~MeshCollection(); + bool isParallelMode() const { return _domain_selector; } + + //writing to a distributed file + void write(const std::string& filename); + + //getting the driver + MeshCollectionDriver *retrieveDriver(); + MeshCollectionDriver *getDriver() const; + void setDriverType(MEDPARTITIONER::DriverType type) { _driver_type=type; } + + //creation of the cell graph + void buildCellGraph(ParaMEDMEM::MEDCouplingSkyLineArray* & array,int *& edgeweights ); + //creation of the cell graph + void buildParallelCellGraph(ParaMEDMEM::MEDCouplingSkyLineArray* & array,int *& edgeweights ); + + //creation and partition of the associated graph + Topology* createPartition(int nbdomain, Graph::splitter_type type = Graph::METIS, + const std::string& ="", int* edgeweights=0, int* verticesweights=0); + + //creation of a user specified partition + Topology* createPartition(const int* partition); + + //getting mesh dimension + int getMeshDimension() const; + int getNbOfLocalMeshes() const; + int getNbOfGlobalMeshes() const { return _mesh.size(); } + int getNbOfLocalCells() const; + int getNbOfLocalFaces() const; + + //getting a reference to mesh vector + std::vector<ParaMEDMEM::MEDCouplingUMesh*>& getMesh(); + std::vector<ParaMEDMEM::MEDCouplingUMesh*>& getFaceMesh(); + std::vector<std::vector<ParaMEDMEM::MEDCouplingUMesh*> >& getGroupMeshes(); + + ParaMEDMEM::MEDCouplingUMesh* getMesh(int idomain) const; + ParaMEDMEM::MEDCouplingUMesh* getFaceMesh(int idomain); + std::vector<ParaMEDMEM::MEDCouplingUMesh*>& getGroupMeshes(int idomain); + + std::vector<ParaMEDMEM::DataArrayInt*>& getCellFamilyIds() { return _cell_family_ids; } + std::vector<ParaMEDMEM::DataArrayInt*>& getFaceFamilyIds() { return _face_family_ids; } + + std::map<std::string, ParaMEDMEM::DataArrayInt*>& getMapDataArrayInt() { return _map_dataarray_int; } + std::map<std::string, ParaMEDMEM::DataArrayDouble*>& getMapDataArrayDouble() { return _map_dataarray_double; } + + std::map<std::string,int>& getFamilyInfo() { return _family_info; } + std::map<std::string, std::vector<std::string> >& getGroupInfo() { return _group_info; } + + ParaMEDMEM::DataArrayDouble* getField(std::string descriptionField, int iold); + std::vector<std::string>& getFieldDescriptions() { return _field_descriptions; } + void prepareFieldDescriptions(); + void filterFaceOnCell(); + + //getting a reference to connect zones vector + std::vector<MEDPARTITIONER::ConnectZone*>& getCZ(); + + //getting a pointer to topology + Topology* getTopology() const ; + ParaDomainSelector* getParaDomainSelector() const { return _domain_selector; } + void setParaDomainSelector(ParaDomainSelector* pds) { _domain_selector = pds; } + //setting a new topology + void setTopology(Topology* topology, bool takeOwneship); + + //getting/setting the name of the global mesh (as opposed + //to the name of a subdomain \a nn, which is name_nn) + std::string getName() const { return _name; } + void setName(const std::string& name) { _name=name; } + void setDomainNames(const std::string& name); + + void setNonEmptyMesh(int number) { _i_non_empty_mesh=number;} + + //getting/setting the description of the global mesh + std::string getDescription() const { return _description; } + void setDescription(const std::string& name) { _description=name; } + + //creates the node mapping between an old collection and the present one + void createNodeMapping(MeshCollection& initialCollection, + std::multimap<std::pair<int,int>,std::pair<int,int> >& nodeMapping); + + void castCellMeshes(MeshCollection& initialCollection, + std::vector<std::vector<std::vector<int> > >& new2oldIds, + std::vector<ParaMEDMEM::DataArrayInt*> & o2nRenumber); + + //creates faces on the new collection + void castFaceMeshes(MeshCollection& initialCollection, + const std::multimap<std::pair<int,int>, std::pair<int,int> >& nodeMapping, + std::vector<std::vector<std::vector<int> > >& new2oldIds); + + //constructing connect zones + void buildConnectZones( const NodeMapping& nodeMapping, + const std::vector<ParaMEDMEM::DataArrayInt*> & o2nRenumber, + int nbInitialDomains ); + + // Find faces common with neighbor domains and put them in groups + void buildBoundaryFaces(); + + private: + void castIntField(std::vector<ParaMEDMEM::MEDCouplingUMesh*>& meshesCastFrom, + std::vector<ParaMEDMEM::MEDCouplingUMesh*>& meshesCastTo, + std::vector<ParaMEDMEM::DataArrayInt*>& arrayFrom, + std::string nameArrayTo); + + void castAllFields(MeshCollection& initialCollection, + std::string nameArrayTo); + + void findCommonDistantNodes(std::vector<std::vector<std::multimap<int,int> > >& commonDistantNodes); + + + void remapIntField(int inew, int iold, + const ParaMEDMEM::MEDCouplingUMesh& sourceMesh, + const ParaMEDMEM::MEDCouplingUMesh& targetMesh, + const int* fromArray, + std::string nameArrayTo, + const BBTreeOfDim* tree); + + void remapDoubleField(int inew, int iold, + ParaMEDMEM::DataArrayDouble* fromArray, + std::string nameArrayTo, + std::string descriptionField); + + void createJointGroup( const std::vector< int >& faces, + const int inew1, + const int inew2, + const bool is2nd ); + private: + + //link to mesh_collection topology + Topology* _topology; + + //control over topology + bool _owns_topology; + + //Driver for read/write operations + MeshCollectionDriver* _driver; + + //Parallelizer - mark of parallel execution mode + ParaDomainSelector* _domain_selector; + + //links to meshes + std::vector<ParaMEDMEM::MEDCouplingUMesh*> _mesh; + std::vector<ParaMEDMEM::MEDCouplingUMesh*> _face_mesh; + + //index of a non empty mesh within _mesh (in parallel mode all of meshes can be empty) + int _i_non_empty_mesh; + + //family ids storages + std::vector<ParaMEDMEM::DataArrayInt*> _cell_family_ids; + std::vector<ParaMEDMEM::DataArrayInt*> _face_family_ids; + + //DataArrayInt* storages + std::map<std::string, ParaMEDMEM::DataArrayInt*> _map_dataarray_int; + //DataArrayDouble* storages + std::map<std::string, ParaMEDMEM::DataArrayDouble*> _map_dataarray_double; + + //fields to be partitioned + std::vector<std::string> _field_descriptions; + + //group family conversion + std::map<std::string, int> _family_info; + std::map<std::string, std::vector<std::string> > _group_info; + + //list of groups that are not to be splitted + std::vector<std::string> _indivisible_regions; + + //name of global mesh + std::string _name; + + //description of global mesh + std::string _description; + + //specifies the driver associated to the collection + DriverType _driver_type; + + //flag specifying that the splitter should create boundary constituent entity + //so that they are written in joints + bool _subdomain_boundary_creates; + + //flag specifying that families must be preserved by the splitting + bool _family_splitting; + + //flag specifying that groups must be created on all domains, even if they are empty + bool _create_empty_groups; + + JointFinder* _joint_finder; + }; +} +#endif diff --git a/src/medtool/src/MEDPartitioner/MEDPARTITIONER_MeshCollectionDriver.cxx b/src/medtool/src/MEDPartitioner/MEDPARTITIONER_MeshCollectionDriver.cxx new file mode 100644 index 000000000..68f12e7a5 --- /dev/null +++ b/src/medtool/src/MEDPartitioner/MEDPARTITIONER_MeshCollectionDriver.cxx @@ -0,0 +1,462 @@ +// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// + +#include "MEDPARTITIONER_MeshCollectionDriver.hxx" + +#include "MEDPARTITIONER_ConnectZone.hxx" +#include "MEDPARTITIONER_MeshCollection.hxx" +#include "MEDPARTITIONER_ParaDomainSelector.hxx" +#include "MEDPARTITIONER_ParallelTopology.hxx" +#include "MEDPARTITIONER_Utils.hxx" + +#include "MEDCouplingFieldDouble.hxx" +#include "MEDCouplingRefCountObject.hxx" +#include "MEDCouplingSkyLineArray.hxx" +#include "MEDCouplingUMesh.hxx" +#include "MEDFileData.hxx" +#include "MEDFileField.hxx" +#include "MEDFileJoint.hxx" +#include "MEDFileMesh.hxx" +#include "MEDLoader.hxx" + +#include <map> +#include <set> +#include <vector> +#include <string> +#include <fstream> +#include <iostream> + +#include <libxml/tree.h> +#include <libxml/parser.h> +#include <libxml/xpath.h> +#include <libxml/xpathInternals.h> + +#include "med.h" + +using namespace MEDPARTITIONER; + +MeshCollectionDriver::MeshCollectionDriver(MeshCollection* collection):_collection(collection) +{ +} + +/*!reads a unique MED File v>=2.1 + * and mounts the corresponding mesh in memory + *\param filename binary file + *\param meshname mesh name in the MED file + * */ +int MeshCollectionDriver::readSeq(const char* filename, const char* meshname) +{ + std::cout << "readSeq" << std::endl; + MyGlobals::_File_Names.resize(1); + MyGlobals::_File_Names[0]=std::string(filename); + + ParaMEDMEM::MEDFileUMesh* mfm=ParaMEDMEM::MEDFileUMesh::New(filename,meshname); + //puts the only mesh in the mesh vector + (_collection->getMesh()).push_back(mfm->getLevel0Mesh(false)); + (_collection->getFaceMesh()).push_back(mfm->getLevelM1Mesh(false)); + + //reading family ids + ParaMEDMEM::DataArrayInt* cellIds(mfm->getFamilyFieldAtLevel(0)->deepCpy()); + ParaMEDMEM::DataArrayInt* faceIds(mfm->getFamilyFieldAtLevel(-1)->deepCpy()); + (_collection->getCellFamilyIds()).push_back(cellIds); + (_collection->getFaceFamilyIds()).push_back(faceIds); + + //reading groups + (_collection->getFamilyInfo())=mfm->getFamilyInfo(); + (_collection->getGroupInfo())=mfm->getGroupInfo(); + + (_collection->getCZ()).clear(); + + ParallelTopology* aPT = new ParallelTopology((_collection->getMesh())); + _collection->setTopology(aPT, true); + _collection->setName(meshname); + _collection->setDomainNames(meshname); + return 0; +} + + +void MeshCollectionDriver::readMEDFileData(const ParaMEDMEM::MEDFileData* filedata) +{ + const int nbDomains = filedata->getMeshes()->getNumberOfMeshes(); + _collection->getMesh() .resize( nbDomains, 0 ); + _collection->getFaceMesh() .resize( nbDomains, 0 ); + _collection->getCellFamilyIds().resize( nbDomains, 0 ); + _collection->getFaceFamilyIds().resize( nbDomains, 0 ); + + for (int i=0; i<nbDomains; i++) + { + ParaMEDMEM::MEDFileUMesh *mfm = dynamic_cast<ParaMEDMEM::MEDFileUMesh *>(filedata->getMeshes()->getMeshAtPos(i)); + readData(mfm,i); + if ( mfm && mfm->getMeshDimension() > 0 ) + _collection->setNonEmptyMesh( i ); + } + + ParallelTopology* aPT = new ParallelTopology(_collection->getMesh()); + _collection->setTopology(aPT, true); + if ( nbDomains > 0 ) + { + _collection->setName( filedata->getMeshes()->getMeshAtPos(0)->getName() ); + _collection->setDomainNames( _collection->getName() ); + } + if ( ParaDomainSelector* domainSelector = _collection->getParaDomainSelector() ) + if ( _collection->isParallelMode() ) + { + //to know nb of cells on each proc to compute global cell ids from locally global + domainSelector->gatherNbOf(_collection->getMesh()); + } +} + +void MeshCollectionDriver::readFileData(std::string file,std::string meshname,int idomain) const +{ + ParaMEDMEM::MEDFileUMesh* mfm=ParaMEDMEM::MEDFileUMesh::New(file,meshname); + readData(mfm,idomain); + mfm->decrRef(); +} + +void MeshCollectionDriver::readData(ParaMEDMEM::MEDFileUMesh* mfm, int idomain) const +{ + std::vector<int> nonEmpty=mfm->getNonEmptyLevels(); + try + { + (_collection->getMesh())[idomain]=mfm->getLevel0Mesh(false); + //reading families groups + ParaMEDMEM::DataArrayInt* cellIds(mfm->getFamilyFieldAtLevel(0)->deepCpy()); + (_collection->getCellFamilyIds())[idomain]=cellIds; + } + catch(...) + { + (_collection->getMesh())[idomain]=CreateEmptyMEDCouplingUMesh(); // or 0 if you want tests; + ParaMEDMEM::DataArrayInt* empty=ParaMEDMEM::DataArrayInt::New(); + empty->alloc(0,1); + (_collection->getCellFamilyIds())[idomain]=empty; + std::cout<<"\nNO Level0Mesh (Cells)\n"; + } + try + { + if (nonEmpty.size()>1 && nonEmpty[1]==-1) + { + (_collection->getFaceMesh())[idomain]=mfm->getLevelM1Mesh(false); + //reading families groups + ParaMEDMEM::DataArrayInt* faceIds(mfm->getFamilyFieldAtLevel(-1)->deepCpy()); + (_collection->getFaceFamilyIds())[idomain]=faceIds; + if (MyGlobals::_Verbose>10) + std::cout << "proc " << MyGlobals::_Rank << " : WITH Faces\n"; + } + else + { + throw INTERP_KERNEL::Exception("no faces"); + } + } + catch(...) + { + (_collection->getFaceMesh())[idomain]=CreateEmptyMEDCouplingUMesh(); // or 0 if you want test; + ParaMEDMEM::DataArrayInt* empty=ParaMEDMEM::DataArrayInt::New(); + (_collection->getFaceFamilyIds())[idomain]=empty; + if (MyGlobals::_Verbose>10) + std::cout << "proc " << MyGlobals::_Rank << " : WITHOUT Faces\n"; + } + //reading groups + _collection->getFamilyInfo()=mfm->getFamilyInfo(); + _collection->getGroupInfo()=mfm->getGroupInfo(); +} + +void MeshCollectionDriver::readSubdomain(int idomain) +{ + std::string meshname=MyGlobals::_Mesh_Names[idomain]; + std::string file=MyGlobals::_File_Names[idomain]; + readFileData(file,meshname,idomain); + + std::vector<std::string> localInformation; + std::string str; + localInformation.push_back(str+"ioldDomain="+IntToStr(idomain)); + localInformation.push_back(str+"meshName="+meshname); + MyGlobals::_General_Informations.push_back(SerializeFromVectorOfString(localInformation)); + std::vector<std::string> localFields=BrowseAllFieldsOnMesh(file, meshname, idomain); + if (localFields.size()>0) + MyGlobals::_Field_Descriptions.push_back(SerializeFromVectorOfString(localFields)); +} + +ParaMEDMEM::MEDFileMesh* MeshCollectionDriver::getMesh(int idomain) const +{ + ParaMEDMEM::MEDFileUMesh* mfm = ParaMEDMEM::MEDFileUMesh::New(); + + ParaMEDMEM::MEDCouplingUMesh* cellMesh=_collection->getMesh(idomain); + ParaMEDMEM::MEDCouplingUMesh* faceMesh=_collection->getFaceMesh(idomain); + // std::string cleFilter=Cle1ToStr("filterFaceOnCell",idomain); + // ParaMEDMEM::DataArrayInt* filter=0; + // if (_collection->getMapDataArrayInt().find(cleFilter)!=_collection->getMapDataArrayInt().end()) + // { + // filter=_collection->getMapDataArrayInt().find(cleFilter)->second; + // int* index=filter->getPointer(); + // faceMeshFilter=(ParaMEDMEM::MEDCouplingUMesh *) faceMesh->buildPartOfMySelf(index,index+filter->getNbOfElems(),true); + // faceMesh=faceMeshFilter; + // } + // if (faceMeshFilter!=0) + // faceMeshFilter->decrRef(); + std::string finalMeshName=""; + if (MyGlobals::_General_Informations.size()!=0) + { + std::size_t found=MyGlobals::_General_Informations[0].find("finalMeshName="); + if ((found!=std::string::npos) && (found>0)) + { + finalMeshName=ExtractFromDescription(MyGlobals::_General_Informations[0], "finalMeshName="); + } + } + if (finalMeshName.empty()) + { + finalMeshName=_collection->getName(); + } + cellMesh->setName(finalMeshName); + mfm->setMeshAtLevel( 0, cellMesh ); + + faceMesh->checkCoherency(); + if (faceMesh->getNumberOfCells()>0) + { + faceMesh->tryToShareSameCoordsPermute(*cellMesh, 1e-10); + faceMesh->setName(finalMeshName); + mfm->setMeshAtLevel( -1, faceMesh ); + } + + // ParaMEDMEM::MEDCouplingUMesh* boundaryMesh=0; + // if (MyGlobals::_Creates_Boundary_Faces>0) + // { + // //try to write Boundary meshes + // bool keepCoords=false; //TODO or true + // boundaryMesh=(ParaMEDMEM::MEDCouplingUMesh *) cellMesh->buildBoundaryMesh(keepCoords); + // boundaryMesh->setName("boundaryMesh"); + // if (boundaryMesh!=0) + // { + // //doing that testMesh becomes second mesh sorted by alphabetical order of name + // MEDLoader::WriteUMesh(distfilename, boundaryMesh, false); + // boundaryMesh->decrRef(); + // } + + mfm->setFamilyInfo(_collection->getFamilyInfo()); + mfm->setGroupInfo(_collection->getGroupInfo()); + std::string key=Cle1ToStr("faceFamily_toArray",idomain); + if ( faceMesh->getNumberOfCells()>0 && _collection->getMapDataArrayInt().find(key)!=_collection->getMapDataArrayInt().end()) + mfm->setFamilyFieldArr(-1,_collection->getMapDataArrayInt().find(key)->second); + key=Cle1ToStr("cellFamily_toArray",idomain); + if (_collection->getMapDataArrayInt().find(key)!=_collection->getMapDataArrayInt().end()) + mfm->setFamilyFieldArr(0,_collection->getMapDataArrayInt().find(key)->second); + + // add joints + + using ParaMEDMEM::MEDCouplingAutoRefCountObjectPtr; + using ParaMEDMEM::MEDCouplingSkyLineArray; + using ParaMEDMEM::MEDFileJoint; + using ParaMEDMEM::MEDFileJointCorrespondence; + using ParaMEDMEM::MEDFileJointOneStep; + using ParaMEDMEM::MEDFileJoints; + using ParaMEDMEM::MEDFileJoints; + + if ( _collection->getCZ().size() > 0 ) + { + MEDCouplingAutoRefCountObjectPtr< MEDFileJoints > joints = MEDFileJoints::New(); + + for ( size_t i = 0; i < _collection->getCZ().size(); ++i ) + { + ConnectZone* cz = _collection->getCZ()[i]; + if ( !cz || + cz->getLocalDomainNumber() != idomain ) + continue; + { + std::ostringstream oss; + oss << "joint_" << cz->getDistantDomainNumber(); + cz->setName( oss.str() ); + } + { + std::ostringstream oss; + oss << "connect_zone_" << i; + cz->setDescription( oss.str() ); + } + + MEDCouplingAutoRefCountObjectPtr< MEDFileJoint> + joint = MEDFileJoint::New( cz->getName(), finalMeshName, + finalMeshName, cz->getDistantDomainNumber() ); + joint->setDescription( cz->getDescription() ); + joints->pushJoint( joint ); + + MEDCouplingAutoRefCountObjectPtr< MEDFileJointOneStep> j1st = MEDFileJointOneStep::New(); + joint->pushStep( j1st ); + + const MEDCouplingSkyLineArray * nodeCorr = cz->getNodeCorresp(); + if ( nodeCorr ) + { + MEDCouplingAutoRefCountObjectPtr< MEDFileJointCorrespondence > + corr = MEDFileJointCorrespondence::New( nodeCorr->getValueArray() ); + j1st->pushCorrespondence( corr ); + } + + std::vector< std::pair< int,int > > types = cz->getEntities(); + INTERP_KERNEL::NormalizedCellType t1, t2; + for ( size_t it = 0; it < types.size(); ++it ) + { + const MEDCouplingSkyLineArray * cellCorr = + cz->getEntityCorresp( types[it].first, types[it].second ); + if ( cellCorr && cellCorr->getNumberOf() > 0 ) + { + t1 = INTERP_KERNEL::NormalizedCellType( types[it].first ); + t2 = INTERP_KERNEL::NormalizedCellType( types[it].second ); + MEDCouplingAutoRefCountObjectPtr< MEDFileJointCorrespondence> + corr = MEDFileJointCorrespondence::New( cellCorr->getValueArray(), t1, t2 ); + j1st->pushCorrespondence( corr ); + } + } + } + mfm->setJoints( joints ); + } + + return mfm; +} + +ParaMEDMEM::MEDCouplingFieldDouble* MeshCollectionDriver::getField(std::string key, std::string description, ParaMEDMEM::DataArrayDouble* data, ParaMEDMEM::MEDFileMesh* mfm, int idomain) const +{ + std::string desc=description; + if (MyGlobals::_Verbose>20) + std::cout << "proc " << MyGlobals::_Rank << " : write field " << desc << std::endl; + std::string meshName, fieldName; + int typeField, DT, IT, entity; + FieldShortDescriptionToData(desc, fieldName, typeField, entity, DT, IT); + double time=StrToDouble(ExtractFromDescription(desc, "time=")); + int typeData=StrToInt(ExtractFromDescription(desc, "typeData=")); + std::string entityName=ExtractFromDescription(desc, "entityName="); + ParaMEDMEM::MEDCouplingFieldDouble* field=0; + if (typeData!=6) + { + std::cout << "WARNING : writeMedFile : typeData " << typeData << " not implemented for fields\n"; + } + if (entityName=="MED_CELL") + { + //there is a field of idomain to write + field=ParaMEDMEM::MEDCouplingFieldDouble::New(ParaMEDMEM::ON_CELLS,ParaMEDMEM::ONE_TIME); + } + if (entityName=="MED_NODE_ELEMENT") + { + //there is a field of idomain to write + field=ParaMEDMEM::MEDCouplingFieldDouble::New(ParaMEDMEM::ON_GAUSS_NE,ParaMEDMEM::ONE_TIME); + } + if (!field) + { + std::cout << "WARNING : writeMedFile : entityName " << entityName << " not implemented for fields\n"; + } + if (field && typeData==6) + { + field->setName(fieldName); + field->setMesh(mfm->getGenMeshAtLevel(0)); + ParaMEDMEM::DataArrayDouble *da=data; + //get information for components etc.. + std::vector<std::string> r1; + r1=SelectTagsInVectorOfString(MyGlobals::_General_Informations,"fieldName="+fieldName); + r1=SelectTagsInVectorOfString(r1,"typeField="+IntToStr(typeField)); + r1=SelectTagsInVectorOfString(r1,"DT="+IntToStr(DT)); + r1=SelectTagsInVectorOfString(r1,"IT="+IntToStr(IT)); + //not saved in file? field->setDescription(ExtractFromDescription(r1[0], "fieldDescription=")); + int nbc=StrToInt(ExtractFromDescription(r1[0], "nbComponents=")); + if (nbc==da->getNumberOfComponents()) + { + for (int i=0; i<nbc; i++) + da->setInfoOnComponent(i,ExtractFromDescription(r1[0], "componentInfo"+IntToStr(i)+"=")); + } + else + { + std::cerr << "Problem On field " << fieldName << " : number of components unexpected " << da->getNumberOfComponents() << std::endl; + } + field->setArray(da); + field->setTime(time,DT,IT); + field->checkCoherency(); + } + return field; +} + +void MeshCollectionDriver::writeMedFile(int idomain, const std::string& distfilename) const +{ + ParaMEDMEM::MEDFileMesh* mfm = getMesh( idomain ); + mfm->write(distfilename,2); + + std::string key="/inewFieldDouble="+IntToStr(idomain)+"/"; + std::map<std::string,ParaMEDMEM::DataArrayDouble*>::iterator it; + int nbfFieldFound=0; + for (it=_collection->getMapDataArrayDouble().begin() ; it!=_collection->getMapDataArrayDouble().end(); it++) + { + size_t found=(*it).first.find(key); + if (found==std::string::npos) + continue; + ParaMEDMEM::MEDCouplingFieldDouble* field=0; + field = getField(key, (*it).first, (*it).second, mfm, idomain); + nbfFieldFound++; + try + { + MEDLoader::WriteField(distfilename,field,false); + } + catch(INTERP_KERNEL::Exception& e) + { + //cout trying rewrite all data, only one field defined + std::string tmp,newName=distfilename; + std::string fieldName; + fieldName=field->getName(); + tmp+="_"+fieldName+"_"+IntToStr(nbfFieldFound)+".med"; + newName.replace(newName.find(".med"),4,tmp); + std::cout << "WARNING : writeMedFile : create a new file name with only one field because MEDLoader::WriteField throw:" << newName << std::endl; + MEDLoader::WriteField(newName,field,true); + } + } + mfm->decrRef(); +} + +ParaMEDMEM::MEDFileData* MeshCollectionDriver::getMEDFileData() +{ + ParaMEDMEM::MEDFileData* newdata = ParaMEDMEM::MEDFileData::New(); + + ParaMEDMEM::MEDCouplingAutoRefCountObjectPtr<ParaMEDMEM::MEDFileMeshes> meshes; + ParaMEDMEM::MEDCouplingAutoRefCountObjectPtr<ParaMEDMEM::MEDFileFields> fields; + meshes = ParaMEDMEM::MEDFileMeshes::New(); + fields = ParaMEDMEM::MEDFileFields::New(); + + for (size_t i=0; i<_collection->getMesh().size(); i++) + { + ParaMEDMEM::MEDFileMesh* mfm = getMesh( i ); + meshes->pushMesh(mfm); + + std::string key="/inewFieldDouble="+IntToStr(i)+"/"; + std::map<std::string,ParaMEDMEM::DataArrayDouble*>::iterator it; + ParaMEDMEM::MEDFileFieldMultiTS* fieldsMTS = ParaMEDMEM::MEDFileFieldMultiTS::New(); + for (it=_collection->getMapDataArrayDouble().begin() ; it!=_collection->getMapDataArrayDouble().end(); it++) + { + size_t found=(*it).first.find(key); + if (found==std::string::npos) + continue; + ParaMEDMEM::MEDCouplingFieldDouble* field=0; + field=getField(key, (*it).first, (*it).second, mfm, i); + ParaMEDMEM::MEDFileField1TS* f1ts = ParaMEDMEM::MEDFileField1TS::New(); + f1ts->setFieldNoProfileSBT(field); + fieldsMTS->pushBackTimeStep(f1ts); + + field->decrRef(); + f1ts->decrRef(); + } + fields->pushField(fieldsMTS); + + fieldsMTS->decrRef(); + mfm->decrRef(); + } + newdata->setMeshes(meshes); + newdata->setFields(fields); + return newdata; +} diff --git a/src/medtool/src/MEDPartitioner/MEDPARTITIONER_MeshCollectionDriver.hxx b/src/medtool/src/MEDPartitioner/MEDPARTITIONER_MeshCollectionDriver.hxx new file mode 100644 index 000000000..c378a3408 --- /dev/null +++ b/src/medtool/src/MEDPartitioner/MEDPARTITIONER_MeshCollectionDriver.hxx @@ -0,0 +1,63 @@ +// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// + +#ifndef __MEDPARTITIONER_MESHCOLLECTIONDRIVER_HXX__ +#define __MEDPARTITIONER_MESHCOLLECTIONDRIVER_HXX__ + +#include "MEDPARTITIONER.hxx" + +#include <vector> +#include <string> + +namespace ParaMEDMEM +{ + class DataArrayDouble; + class MEDCouplingFieldDouble; + class MEDFileData; + class MEDFileMesh; + class MEDFileUMesh; +} + +namespace MEDPARTITIONER +{ + class MeshCollection; + class ParaDomainSelector; + + class MEDPARTITIONER_EXPORT MeshCollectionDriver + { + public: + MeshCollectionDriver(MeshCollection*); + virtual ~MeshCollectionDriver() { } + virtual int read(const char*, ParaDomainSelector* sel=0) = 0; + int readSeq(const char*,const char*); + ParaMEDMEM::MEDFileData *getMEDFileData(); + virtual void write(const char*, ParaDomainSelector* sel=0) const = 0; + void readMEDFileData(const ParaMEDMEM::MEDFileData* filedata); + protected: + void readSubdomain(int idomain); + void readData(ParaMEDMEM::MEDFileUMesh* mfm, int idomain) const; + void readFileData(std::string file,std::string meshname,int idomain) const; + ParaMEDMEM::MEDFileMesh* getMesh(int idomain) const; + ParaMEDMEM::MEDCouplingFieldDouble* getField(std::string key, std::string description, ParaMEDMEM::DataArrayDouble* data, ParaMEDMEM::MEDFileMesh* mfm, int idomain) const; + void writeMedFile(int idomain, const std::string& distfilename) const; + protected: + MeshCollection* _collection; + }; +} +#endif diff --git a/src/medtool/src/MEDPartitioner/MEDPARTITIONER_MeshCollectionMedAsciiDriver.cxx b/src/medtool/src/MEDPartitioner/MEDPARTITIONER_MeshCollectionMedAsciiDriver.cxx new file mode 100644 index 000000000..4eb8360cb --- /dev/null +++ b/src/medtool/src/MEDPartitioner/MEDPARTITIONER_MeshCollectionMedAsciiDriver.cxx @@ -0,0 +1,205 @@ +// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// + +#include "MEDPARTITIONER_ParallelTopology.hxx" +#include "MEDPARTITIONER_MeshCollectionDriver.hxx" +#include "MEDPARTITIONER_MeshCollection.hxx" +#include "MEDPARTITIONER_MeshCollectionMedAsciiDriver.hxx" +#include "MEDPARTITIONER_ParaDomainSelector.hxx" +#include "MEDPARTITIONER_Utils.hxx" + +#include "MEDCouplingUMesh.hxx" +#include "MEDLoader.hxx" + +#include <map> +#include <set> +#include <vector> +#include <string> +#include <fstream> +#include <iostream> + +#include <libxml/tree.h> +#include <libxml/parser.h> +#include <libxml/xpath.h> +#include <libxml/xpathInternals.h> + +using namespace MEDPARTITIONER; + +MeshCollectionMedAsciiDriver::MeshCollectionMedAsciiDriver(MeshCollection* collection):MeshCollectionDriver(collection) +{ +} + +/*!reads a MED File v>=2.3 + * and mounts the corresponding meshes in memory + * the connect zones are created from the joints + * + *\param filename ascii file containing the list of MED v2.3 files + * */ + +int MeshCollectionMedAsciiDriver::read(ParaMEDMEM::MEDFileData* filedata) +{ + readMEDFileData(filedata); + + std::vector<MEDPARTITIONER::ConnectZone*> cz; // to fill from filedata + std::vector<int*> cellglobal; + std::vector<int*> nodeglobal; + std::vector<int*> faceglobal; + int size = (_collection->getMesh()).size(); + cellglobal.resize(size); + nodeglobal.resize(size); + faceglobal.resize(size); + for ( int idomain = 0; idomain < size; ++idomain ) + { + cellglobal[idomain]=0; + faceglobal[idomain]=0; + nodeglobal[idomain]=0; + if ( (_collection->getMesh())[idomain] && (_collection->getMesh())[idomain]->getNumberOfNodes() > 0 ) + _collection->setNonEmptyMesh(idomain); + } + //creation of topology from mesh and connect zones + ParallelTopology* aPT = new ParallelTopology((_collection->getMesh()), cz, cellglobal, nodeglobal, faceglobal); + _collection->setTopology(aPT,true); + + return 0; +} + +/*!reads a MED File v>=2.3 + * and mounts the corresponding meshes in memory + * the connect zones are created from the joints + * + *\param filename ascii file containing the list of MED v2.3 files + * */ + +int MeshCollectionMedAsciiDriver::read(const char* filename, ParaDomainSelector* domainSelector) +{ + //distributed meshes + std::vector<int*> cellglobal; + std::vector<int*> nodeglobal; + std::vector<int*> faceglobal; + int nbdomain; + + //reading ascii master file + try + { + std::ifstream asciiinput(filename); + if (!asciiinput) + throw INTERP_KERNEL::Exception("Master ASCII File does not exist"); + char charbuffer[512]; + asciiinput.getline(charbuffer,512); + + while (charbuffer[0]=='#') + { + asciiinput.getline(charbuffer,512); + } + + //reading number of domains + nbdomain=atoi(charbuffer); + MyGlobals::_File_Names.resize(nbdomain); + MyGlobals::_Mesh_Names.resize(nbdomain); + (_collection->getMesh()).resize(nbdomain); + cellglobal.resize(nbdomain); + nodeglobal.resize(nbdomain); + faceglobal.resize(nbdomain); + + if (nbdomain == 0) + throw INTERP_KERNEL::Exception("Empty ASCII master file"); + for (int i=0; i<nbdomain;i++) + { + //reading information about the domain + std::string mesh,host; + int idomain; + cellglobal[i]=0; + faceglobal[i]=0; + nodeglobal[i]=0; + + asciiinput >> mesh >> idomain >> MyGlobals::_Mesh_Names[i] >> host >> MyGlobals::_File_Names[i]; + + //Setting the name of the global mesh (which should be is the same for all the subdomains) + if (i==0) + _collection->setName(mesh); + + if (idomain!=i+1) + { + throw INTERP_KERNEL::Exception("domain must be written from 1 to N in ASCII file descriptor"); + } + if ( !domainSelector || domainSelector->isMyDomain(i)) + readSubdomain(i); + + } //loop on domains + } //of try + catch(...) + { + throw INTERP_KERNEL::Exception("I/O error reading parallel MED file"); + } + + //creation of topology from mesh and connect zones + ParallelTopology* aPT = new ParallelTopology((_collection->getMesh()), (_collection->getCZ()), cellglobal, nodeglobal, faceglobal); + _collection->setTopology(aPT, true); + + for (int i=0; i<nbdomain; i++) + { + delete [] cellglobal[i]; + delete [] nodeglobal[i]; + delete [] faceglobal[i]; + } + return 0; +} + +/*! writes the collection of meshes in a MED v2.3 file + * with the connect zones being written as joints + * \param filename name of the ascii file containing the meshes description + */ +void MeshCollectionMedAsciiDriver::write(const char* filename, ParaDomainSelector* domainSelector) const +{ + int nbdomains=_collection->getMesh().size(); + std::vector<std::string> filenames; + filenames.resize(nbdomains); + + //loop on the domains + for (int idomain=0; idomain<nbdomains; idomain++) + { + std::string distfilename; + std::ostringstream suffix; + suffix << filename << idomain+1 << ".med"; + distfilename=suffix.str(); + filenames[idomain]=distfilename; + + if ( !domainSelector || domainSelector->isMyDomain( idomain ) ) + { + if ( !_collection->getMesh()[idomain]->getNumberOfCells()==0 ) continue;//empty domain + MEDLoader::WriteUMesh(distfilename.c_str(),(_collection->getMesh())[idomain],true); + //writeSubdomain(idomain, nbdomains, distfilename.c_str(), domainSelector); + } + } + + //write master file + if ( !domainSelector || domainSelector->rank() == 0 ) + { + std::ofstream file(filename); + file << "#MED Fichier V 2.3"<<" " << std::endl; + file << "#" << " " << std::endl; + file << _collection->getMesh().size() << " " << std::endl; + + for (int idomain=0; idomain<nbdomains; idomain++) + file << _collection->getName() <<" "<< idomain+1 << " " + << (_collection->getMesh())[idomain]->getName() << " localhost " + << filenames[idomain] << " "<< std::endl; + } + +} diff --git a/src/medtool/src/MEDPartitioner/MEDPARTITIONER_MeshCollectionMedAsciiDriver.hxx b/src/medtool/src/MEDPartitioner/MEDPARTITIONER_MeshCollectionMedAsciiDriver.hxx new file mode 100644 index 000000000..2a22d9446 --- /dev/null +++ b/src/medtool/src/MEDPartitioner/MEDPARTITIONER_MeshCollectionMedAsciiDriver.hxx @@ -0,0 +1,41 @@ +// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// + +#ifndef __MEDPARTITIONER_MESHCOLLECTIONMEDASCIIDRIVER_HXX__ +#define __MEDPARTITIONER_MESHCOLLECTIONMEDASCIIDRIVER_HXX__ + +#include "MEDPARTITIONER.hxx" +#include "MEDPARTITIONER_MeshCollectionDriver.hxx" + +namespace MEDPARTITIONER +{ + class MeshCollection; + class MEDPARTITIONER_EXPORT MeshCollectionMedAsciiDriver : public MeshCollectionDriver + { + public: + MeshCollectionMedAsciiDriver(MeshCollection*); + virtual ~MeshCollectionMedAsciiDriver() { } + int read(const char*, ParaDomainSelector* sel=0); + int read(ParaMEDMEM::MEDFileData*); + void write(const char*, ParaDomainSelector* sel=0) const; + private: + std::string _master_filename; + }; +} +#endif diff --git a/src/medtool/src/MEDPartitioner/MEDPARTITIONER_MeshCollectionMedXmlDriver.cxx b/src/medtool/src/MEDPartitioner/MEDPARTITIONER_MeshCollectionMedXmlDriver.cxx new file mode 100644 index 000000000..0fcb460be --- /dev/null +++ b/src/medtool/src/MEDPartitioner/MEDPARTITIONER_MeshCollectionMedXmlDriver.cxx @@ -0,0 +1,306 @@ +// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// + +#include "MEDPARTITIONER_ParallelTopology.hxx" +#include "MEDPARTITIONER_MeshCollectionDriver.hxx" +#include "MEDPARTITIONER_MeshCollection.hxx" +#include "MEDPARTITIONER_MeshCollectionMedXmlDriver.hxx" +#include "MEDPARTITIONER_ParaDomainSelector.hxx" +#include "MEDPARTITIONER_Utils.hxx" + +#include "MEDCouplingUMesh.hxx" +#include "MEDLoader.hxx" +#include "MEDFileMesh.hxx" + +#include <map> +#include <set> +#include <vector> +#include <string> +#include <cstring> +#include <fstream> +#include <sstream> +#include <iostream> +#ifdef WIN32 +#include <time.h> +#include <windows.h> +#endif + + +#include <libxml/tree.h> +#include <libxml/parser.h> +#include <libxml/xpath.h> +#include <libxml/xpathInternals.h> + +using namespace MEDPARTITIONER; + +/*!\class MeshCollectionMedXmlDriver + * + *\brief Driver for MED 3.2 files having Xml master files + * + * Driver for reading and writing distributed files + * for which the master file is written in an Xml format compliant with + * the MED 3.2 specification. + * The reading and writing of the meshes and fields are apart : + * the meshes must always be written/read before the fields. Reading/Writing fields + * is optional and is done field after field. API for reading/writing fields + * is written with a template so that FIELD<int> and FIELD<double> + * can be conveniently handled. + */ + +MeshCollectionMedXmlDriver::MeshCollectionMedXmlDriver(MeshCollection* collection):MeshCollectionDriver(collection) +{ +} + +/*!reads a MED File Xml Master File v>=2.3 + * and mounts the corresponding meshes in memory + * the connect zones are created from the joints + * + *\param filename Xml file containing the list of MED v2.3 files + * */ + +int MeshCollectionMedXmlDriver::read(const char* filename, ParaDomainSelector* domainSelector) +{ + //distributed meshes + int nbdomain; + _master_filename=filename; + + //reading ascii master file + try + { + //Setting up the Xml tree corresponding to filename + xmlDocPtr master_doc=xmlParseFile(filename); + + if (!master_doc) + throw INTERP_KERNEL::Exception("Xml Master File does not exist or is not compliant with Xml scheme"); + + //number of domains + xmlXPathContextPtr xpathCtx = xmlXPathNewContext(master_doc); + xmlXPathObjectPtr xpathObj = xmlXPathEvalExpression(BAD_CAST "//splitting/subdomain", xpathCtx); + if (xpathObj==0 || xpathObj->nodesetval->nodeNr ==0) + throw INTERP_KERNEL::Exception("Xml Master File does not contain /MED/splitting/subdomain node"); + + //as subdomain has only one property which is "number" + //it suffices to take the content of its first child + const char* mystring = (const char*)xpathObj->nodesetval->nodeTab[0]->properties->children->content; + sscanf(mystring, "%d", &nbdomain); + + //mesh name + xmlXPathFreeObject(xpathObj); + xpathObj = xmlXPathEvalExpression(BAD_CAST "//content/mesh", xpathCtx); + if (xpathObj==0 || xpathObj->nodesetval->nodeNr ==0) + throw INTERP_KERNEL::Exception("Xml Master File does not contain /MED/content/mesh node"); + _collection->setName( (const char*)xpathObj->nodesetval->nodeTab[0]->properties->children->content); + + //cout << "nb domain " << nbdomain << endl; + MyGlobals::_File_Names.resize(nbdomain); + MyGlobals::_Mesh_Names.resize(nbdomain); + (_collection->getMesh()).resize(nbdomain); + (_collection->getFaceMesh()).resize(nbdomain); + (_collection->getCellFamilyIds()).resize(nbdomain); + (_collection->getFaceFamilyIds()).resize(nbdomain); + + //retrieving the node which contains the file names + const char filechar[]="//files/subfile"; + xmlXPathFreeObject(xpathObj); + xpathObj = xmlXPathEvalExpression(BAD_CAST filechar, xpathCtx); + if (xpathObj==0 || xpathObj->nodesetval->nodeNr ==0) + throw INTERP_KERNEL::Exception("Xml Master File does not contain /MED/files/subfile nodes"); + int nbfiles = xpathObj->nodesetval ->nodeNr; + + for (int i=0; i<nbfiles;i++) + { + //reading information about the domain + std::string host; + //reading file names + std::ostringstream name_search_string; + name_search_string<<"//files/subfile[@id=\""<<i+1<<"\"]/name"; + xmlXPathObjectPtr xpathObjfilename = + xmlXPathEvalExpression(BAD_CAST name_search_string.str().c_str(),xpathCtx); + if (xpathObjfilename->nodesetval ==0) + throw INTERP_KERNEL::Exception("Error retrieving a file name from subfile of Xml Master File"); + MyGlobals::_File_Names[i]=(const char*)xpathObjfilename->nodesetval->nodeTab[0]->children->content; + + //reading the local mesh names + std::ostringstream mesh_search_string; + mesh_search_string<<"//mapping/mesh/chunk[@subdomain=\""<<i+1<<"\"]/name"; + + xmlXPathObjectPtr xpathMeshObj = xmlXPathEvalExpression(BAD_CAST mesh_search_string.str().c_str(),xpathCtx); + if (xpathMeshObj->nodesetval ==0) + throw INTERP_KERNEL::Exception("Error retrieving mesh name from chunk of Xml Master File"); + MyGlobals::_Mesh_Names[i]=(const char*)xpathMeshObj->nodesetval->nodeTab[0]->children->content; + + if ( !domainSelector || domainSelector->isMyDomain(i)) + readSubdomain(i); + xmlXPathFreeObject(xpathObjfilename); + xmlXPathFreeObject(xpathMeshObj); + } //loop on domains + + //LIBXML cleanup + xmlXPathFreeObject(xpathObj); + xmlXPathFreeContext(xpathCtx); + xmlFreeDoc(master_doc); + + } //of try + catch(...) + { + throw INTERP_KERNEL::Exception("I/O error reading parallel MED file"); + } + + ParallelTopology* aPT = new ParallelTopology(_collection->getMesh()); + //creation of topology from mesh and connect zones + if ( _collection->isParallelMode() ) + { + //to know nb of cells on each proc to compute global cell ids from locally global + domainSelector->gatherNbOf(_collection->getMesh()); + } + _collection->setTopology(aPT, true); + _collection->setDomainNames(_collection->getName()); + return 0; +} + + +/*! writes the collection of meshes in a + * MED v2.3 Xml file + * with the connect zones being written as joints + * \param filename name of the Xml file containing the meshes description + */ +void MeshCollectionMedXmlDriver::write(const char* filename, ParaDomainSelector* domainSelector) const +{ + xmlDocPtr master_doc = 0; + xmlNodePtr root_node = 0, node, node2; + char buff[256]; + + //Creating the Xml document + master_doc = xmlNewDoc(BAD_CAST "1.0"); + root_node = xmlNewNode(0, BAD_CAST "root"); + xmlDocSetRootElement(master_doc,root_node); + + //Creating child nodes + // Version tag + node = xmlNewChild(root_node, 0, BAD_CAST "version",0); + xmlNewProp(node, BAD_CAST "maj", BAD_CAST "2"); + xmlNewProp(node, BAD_CAST "min", BAD_CAST "3"); + xmlNewProp(node, BAD_CAST "ver", BAD_CAST "1"); + + //Description tag + time_t present; + char date[20]; +#ifndef WIN32 + time( &present); + struct tm *time_asc = localtime(&present); + sprintf(date,"%02d%02d%02d",time_asc->tm_year + ,time_asc->tm_mon+1 + ,time_asc->tm_mday); +#else + SYSTEMTIME st; + GetLocalTime ( &st ); + sprintf(date,"%02d%02d%02d", + st.wYear + ,st.wMonth + ,st.wDay); +#endif + + node = xmlNewChild(root_node,0, BAD_CAST "description",0); + + xmlNewProp(node, BAD_CAST "what", BAD_CAST _collection->getDescription().c_str()); + xmlNewProp(node, BAD_CAST "when", BAD_CAST date); + + //Content tag + node =xmlNewChild(root_node,0, BAD_CAST "content",0); + node2 = xmlNewChild(node, 0, BAD_CAST "mesh",0); + xmlNewProp(node2, BAD_CAST "name", BAD_CAST _collection->getName().c_str()); + + //Splitting tag + node=xmlNewChild(root_node,0,BAD_CAST "splitting",0); + node2=xmlNewChild(node,0,BAD_CAST "subdomain",0); + sprintf(buff, "%d", (int)_collection->getMesh().size()); + xmlNewProp(node2, BAD_CAST "number", BAD_CAST buff); + node2=xmlNewChild(node,0,BAD_CAST "global_numbering",0); + xmlNewProp(node2, BAD_CAST "present", BAD_CAST "yes"); + + //Files tag + xmlNodePtr file_node=xmlNewChild(root_node,0,BAD_CAST "files",0); + + //Mapping tag + node = xmlNewChild(root_node,0,BAD_CAST "mapping",0); + xmlNodePtr mesh_node = xmlNewChild(node, 0, BAD_CAST "mesh",0); + xmlNewProp(mesh_node, BAD_CAST "name", BAD_CAST _collection->getName().c_str()); + + int nbdomains= _collection->getMesh().size(); + + //loop on the domains + std::string finalMeshName=""; + if (MyGlobals::_General_Informations.size()!=0) + { + std::size_t found=MyGlobals::_General_Informations[0].find("finalMeshName="); + if ((found!=std::string::npos) && (found>0)) + { + finalMeshName=ExtractFromDescription(MyGlobals::_General_Informations[0], "finalMeshName="); + } + } + if (finalMeshName.empty()) + { + finalMeshName=_collection->getName(); + } + for (int idomain=nbdomains-1; idomain>=0;idomain--) + { + std::string distfilename; + std::ostringstream suffix; + suffix<<filename<<idomain+1<<".med"; + distfilename=suffix.str(); + + if ( !domainSelector || domainSelector->isMyDomain( idomain ) ) + { + if ( (_collection->getMesh())[idomain]->getNumberOfCells()==0 ) + continue; //empty domain + if (MyGlobals::_Verbose>1) + std::cout << "proc "<< domainSelector->rank() << " : writeMedFile " << distfilename + << " "<< (_collection->getMesh())[idomain]->getNumberOfCells() << " cells" + << " " << (_collection->getFaceMesh())[idomain]->getNumberOfCells() << " faces" + << " " << (_collection->getMesh())[idomain]->getNumberOfNodes()<<" nodes" << std::endl; + writeMedFile(idomain,distfilename); + } + + if (domainSelector->rank()==0) + { + //updating the ascii description file + node = xmlNewChild(file_node, 0, BAD_CAST "subfile",0); + sprintf (buff,"%d",idomain+1); + xmlNewProp(node, BAD_CAST "id", BAD_CAST buff); + xmlNewChild(node,0,BAD_CAST "name",BAD_CAST distfilename.c_str()); + xmlNewChild(node,0,BAD_CAST "machine",BAD_CAST "localhost"); + + node = xmlNewChild(mesh_node,0, BAD_CAST "chunk",0); + xmlNewProp(node, BAD_CAST "subdomain", BAD_CAST buff); + xmlNewChild(node,0,BAD_CAST "name", BAD_CAST finalMeshName.c_str()); + //xmlNewChild(node,0,BAD_CAST "name", BAD_CAST ((_collection->getMesh())[idomain]->getName()).c_str()); + } + } + + //create the ascii description file + if (domainSelector->rank()==0) + { + std::string myfile(filename); + myfile.append(".xml"); + if ( !domainSelector || domainSelector->rank() == 0 ) + xmlSaveFormatFileEnc(myfile.c_str(), master_doc, "UTF-8", 1); + } + xmlFreeDoc(master_doc); + xmlCleanupParser(); +} diff --git a/src/medtool/src/MEDPartitioner/MEDPARTITIONER_MeshCollectionMedXmlDriver.hxx b/src/medtool/src/MEDPartitioner/MEDPARTITIONER_MeshCollectionMedXmlDriver.hxx new file mode 100644 index 000000000..5e2049b4d --- /dev/null +++ b/src/medtool/src/MEDPartitioner/MEDPARTITIONER_MeshCollectionMedXmlDriver.hxx @@ -0,0 +1,40 @@ +// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// + +#ifndef __MEDPARTITIONER_MESHCOLLECTIONMEDXMLDRIVER_HXX__ +#define __MEDPARTITIONER_MESHCOLLECTIONMEDXMLDRIVER_HXX__ + +#include "MEDPARTITIONER.hxx" +#include "MEDPARTITIONER_MeshCollectionDriver.hxx" + +namespace MEDPARTITIONER +{ + class MeshCollection; + class MEDPARTITIONER_EXPORT MeshCollectionMedXmlDriver : public MeshCollectionDriver + { + public: + MeshCollectionMedXmlDriver(MeshCollection*); + virtual ~MeshCollectionMedXmlDriver() { } + int read(const char*, ParaDomainSelector* sel=0); + void write(const char*, ParaDomainSelector* sel=0) const; + private : + std::string _master_filename; + }; +} +#endif diff --git a/src/medtool/src/MEDPartitioner/MEDPARTITIONER_MetisGraph.cxx b/src/medtool/src/MEDPartitioner/MEDPARTITIONER_MetisGraph.cxx new file mode 100644 index 000000000..7e3533815 --- /dev/null +++ b/src/medtool/src/MEDPartitioner/MEDPARTITIONER_MetisGraph.cxx @@ -0,0 +1,119 @@ +// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// + +#include "MEDPARTITIONER_MetisGraph.hxx" +#include "MEDPARTITIONER_ParaDomainSelector.hxx" +#include "MEDPARTITIONER_Utils.hxx" + +#include "MEDCouplingSkyLineArray.hxx" +#include "InterpKernelException.hxx" + +#include <iostream> + +extern "C" +{ +#include "MEDPARTITIONER_metis.h" +} + +using namespace MEDPARTITIONER; + +METISGraph::METISGraph():Graph() +{ +} + +METISGraph::METISGraph(ParaMEDMEM::MEDCouplingSkyLineArray* graph, int* edgeweight) + :Graph(graph,edgeweight) +{ +} + +METISGraph::~METISGraph() +{ +} + +void METISGraph::partGraph(int ndomain, + const std::string& options_string, + ParaDomainSelector *parallelizer) +{ + using std::vector; + if (MyGlobals::_Verbose>10) + std::cout << "proc " << MyGlobals::_Rank << " : METISGraph::partGraph" << std::endl; + + //number of graph vertices + int n=_graph->getNumberOf(); + //graph + int * xadj=const_cast<int*>(_graph->getIndex()); + int * adjncy=const_cast<int*>(_graph->getValue()); + //constraints + int * vwgt=_cell_weight; + int * adjwgt=_edge_weight; + int wgtflag=(_edge_weight!=0)?1:0+(_cell_weight!=0)?2:0; + //base 0 or 1 + int base=0; + //ndomain + int nparts=ndomain; + //options + /* + (0=default_option,option,random_seed) see defs.h + #define PMV3_OPTION_DBGLVL 1 + #define PMV3_OPTION_SEED 2 + #define PMV3_OPTION_IPART 3 + #define PMV3_OPTION_PSR 3 + seems no changes int options[4]={1,0,33,0}; //test for a random seed of 33 + */ + int options[20]={0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}; +#if !defined(MED_ENABLE_METIS) + throw INTERP_KERNEL::Exception("METISGraph::partGraph : METIS is not available. Check your products, please."); +#else + //output parameters + int edgecut; + int* partition=new int[n]; + + if(nparts >1) + { + if (MyGlobals::_Verbose>10) + std::cout << "METISGraph::partGraph METIS_PartGraph METIS_PartGraph(RecursiveOrKway)" << std::endl; + if (options_string != "k") + MEDPARTITIONER_METIS_PartGraphRecursive(&n, xadj, adjncy, vwgt, adjwgt, &wgtflag, + &base, &nparts, options, &edgecut, partition); + else + MEDPARTITIONER_METIS_PartGraphKway(&n, xadj, adjncy, vwgt, adjwgt, &wgtflag, + &base, &nparts, options, &edgecut, partition); + } + else //force this case because METIS send all 1 in value + { + for (int i=0; i<n; i++) + partition[i]=0; + } + vector<int> index(n+1); + vector<int> value(n); + index[0]=0; + for (int i=0; i<n; i++) + { + index[i+1]=index[i]+1; + value[i]=partition[i]; + } + delete [] partition; + + //creating a skylinearray with no copy of the index and partition array + //the fifth argument true specifies that only the pointers are passed + //to the object + _partition = new ParaMEDMEM::MEDCouplingSkyLineArray(index,value); +#endif +} + diff --git a/src/medtool/src/MEDPartitioner/MEDPARTITIONER_MetisGraph.hxx b/src/medtool/src/MEDPartitioner/MEDPARTITIONER_MetisGraph.hxx new file mode 100644 index 000000000..5954f9e4d --- /dev/null +++ b/src/medtool/src/MEDPartitioner/MEDPARTITIONER_MetisGraph.hxx @@ -0,0 +1,40 @@ +// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// + +#ifndef __MEDPARTITIONER_METISGRAPH_HXX__ +#define __MEDPARTITIONER_METISGRAPH_HXX__ + +#include "MEDPARTITIONER.hxx" +#include "MEDPARTITIONER_Graph.hxx" + +#include <string> + +namespace MEDPARTITIONER +{ + class MEDPARTITIONER_EXPORT METISGraph : public Graph + { + public: + METISGraph(); + METISGraph(ParaMEDMEM::MEDCouplingSkyLineArray*, int *edgeweight=0); + virtual ~METISGraph(); + void partGraph(int ndomain, const std::string& options_string="", ParaDomainSelector *sel=0); + }; +} + +#endif diff --git a/src/medtool/src/MEDPartitioner/MEDPARTITIONER_ParMetisGraph.cxx b/src/medtool/src/MEDPartitioner/MEDPARTITIONER_ParMetisGraph.cxx new file mode 100644 index 000000000..4c424f09f --- /dev/null +++ b/src/medtool/src/MEDPartitioner/MEDPARTITIONER_ParMetisGraph.cxx @@ -0,0 +1,143 @@ +// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// + +#include "MEDPARTITIONER_ParMetisGraph.hxx" +#include "MEDPARTITIONER_ParaDomainSelector.hxx" +#include "MEDPARTITIONER_Utils.hxx" + +#include "MEDCouplingSkyLineArray.hxx" +#include "InterpKernelException.hxx" + +#include <iostream> + +#ifdef MED_ENABLE_PARMETIS +#include <parmetis.h> +// #if PARMETIS_MAJOR_VERSION == 4 +// #define ParMETIS_PartKway ParMETIS_V3_PartKway +// #endif +#endif + +using namespace MEDPARTITIONER; + +ParMETISGraph::ParMETISGraph():Graph() +{ +} + +ParMETISGraph::ParMETISGraph(ParaMEDMEM::MEDCouplingSkyLineArray* graph, int* edgeweight) + :Graph(graph,edgeweight) +{ +} + +ParMETISGraph::~ParMETISGraph() +{ +} + +void ParMETISGraph::partGraph(int ndomain, + const std::string& options_string, + ParaDomainSelector *parallelizer) +{ + using std::vector; + vector<int> ran,vx,va; //for randomize + + if (MyGlobals::_Verbose>10) + std::cout << "proc " << MyGlobals::_Rank << " : ParMETISGraph::partGraph" << std::endl; + + // number of graph vertices + int n=_graph->getNumberOf(); + //graph + int * xadj=const_cast<int*>(_graph->getIndex()); + int * adjncy=const_cast<int*>(_graph->getValue()); + //constraints + int * vwgt=_cell_weight; + int * adjwgt=_edge_weight; + int wgtflag=(_edge_weight!=0)?1:0+(_cell_weight!=0)?2:0; + //base 0 or 1 + int base=0; + //ndomain + int nparts=ndomain; + //options + /* + (0=default_option,option,random_seed) see defs.h + #define PMV3_OPTION_DBGLVL 1 + #define PMV3_OPTION_SEED 2 + #define PMV3_OPTION_IPART 3 + #define PMV3_OPTION_PSR 3 + seems no changes int options[4]={1,0,33,0}; //test for a random seed of 33 + */ + int options[4]={0,0,0,0}; + // output parameters + int edgecut; +#if !defined(MED_ENABLE_PARMETIS) + throw INTERP_KERNEL::Exception("ParMETISGraph::partGraph : PARMETIS is not available. Check your products, please."); +#else + int* partition=new int[n]; + + if (MyGlobals::_Verbose>10) + std::cout << "proc " << MyGlobals::_Rank << " : ParMETISGraph::partGraph ParMETIS_PartKway new" << std::endl; + int * vtxdist=parallelizer->getProcVtxdist(); + MPI_Comm comm=MPI_COMM_WORLD; + ParMETIS_PartKway(vtxdist, xadj, adjncy, vwgt, + adjwgt, &wgtflag, &base, &nparts, options, + &edgecut, partition, &comm ); + + + /*doc from parmetis.h + void __cdecl ParMETIS_PartKway( + idxtype *vtxdist, idxtype *xadj, idxtype *adjncy, idxtype *vwgt, + idxtype *adjwgt, int *wgtflag, int *numflag, int *nparts, int *options, + int *edgecut, idxtype *part, MPI_Comm *comm); + + void __cdecl ParMETIS_V3_PartKway( + idxtype *vtxdist, idxtype *xadj, idxtype *adjncy, idxtype *vwgt, + idxtype *adjwgt, int *wgtflag, int *numflag, int *ncon, int *nparts, + float *tpwgts, float *ubvec, int *options, int *edgecut, idxtype *part, + MPI_Comm *comm); + */ + + vector<int> index(n+1); + vector<int> value(n); + index[0]=0; + if (ran.size()>0 && MyGlobals::_Atomize==0) //there is randomize + { + if (MyGlobals::_Is0verbose>100) + std::cout << "randomize" << std::endl; + for (int i=0; i<n; i++) + { + index[i+1]=index[i]+1; + value[ran[i]]=partition[i]; + } + } + else + { + for (int i=0; i<n; i++) + { + index[i+1]=index[i]+1; + value[i]=partition[i]; + } + } + delete [] partition; + + //creating a skylinearray with no copy of the index and partition array + //the fifth argument true specifies that only the pointers are passed + //to the object + + _partition = new ParaMEDMEM::MEDCouplingSkyLineArray(index,value); +#endif +} + diff --git a/src/medtool/src/MEDPartitioner/MEDPARTITIONER_ParMetisGraph.hxx b/src/medtool/src/MEDPartitioner/MEDPARTITIONER_ParMetisGraph.hxx new file mode 100644 index 000000000..2d61cec26 --- /dev/null +++ b/src/medtool/src/MEDPartitioner/MEDPARTITIONER_ParMetisGraph.hxx @@ -0,0 +1,40 @@ +// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// + +#ifndef __MEDPARTITIONER_ParMETISGraph_HXX__ +#define __MEDPARTITIONER_ParMETISGraph_HXX__ + +#include "MEDPARTITIONER.hxx" +#include "MEDPARTITIONER_Graph.hxx" + +#include <string> + +namespace MEDPARTITIONER +{ + class MEDPARTITIONER_EXPORT ParMETISGraph : public Graph + { + public: + ParMETISGraph(); + ParMETISGraph(ParaMEDMEM::MEDCouplingSkyLineArray*, int *edgeweight=0); + virtual ~ParMETISGraph(); + void partGraph(int ndomain, const std::string& options_string="", ParaDomainSelector *sel=0); + }; +} + +#endif diff --git a/src/medtool/src/MEDPartitioner/MEDPARTITIONER_ParaDomainSelector.cxx b/src/medtool/src/MEDPartitioner/MEDPARTITIONER_ParaDomainSelector.cxx new file mode 100644 index 000000000..7658b72f7 --- /dev/null +++ b/src/medtool/src/MEDPartitioner/MEDPARTITIONER_ParaDomainSelector.cxx @@ -0,0 +1,674 @@ +// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// + +#include "MEDPARTITIONER_ParaDomainSelector.hxx" +#include "MEDPARTITIONER_UserGraph.hxx" +#include "MEDPARTITIONER_Utils.hxx" + +#include "MEDCouplingUMesh.hxx" +#include "MEDCouplingSkyLineArray.hxx" + +#include <iostream> +#include <numeric> + +#ifdef HAVE_MPI +#include <mpi.h> +#endif + +/*! + * \brief Constructor. Find out my rank and world size + */ +MEDPARTITIONER::ParaDomainSelector::ParaDomainSelector(bool mesure_memory) + :_rank(0),_world_size(1), _nb_result_domains(-1), _init_time(0.0), + _mesure_memory(mesure_memory), _init_memory(0), _max_memory(0) +{ +#ifdef HAVE_MPI + if (MyGlobals::_Rank==-1) + { + MPI_Init(0,0); //do once only + MPI_Comm_size(MPI_COMM_WORLD,&_world_size) ; + MPI_Comm_rank(MPI_COMM_WORLD,&_rank) ; + } + else + { + _world_size=MyGlobals::_World_Size; + _rank=MyGlobals::_Rank; + } + _init_time = MPI_Wtime(); +#else + //sequential : no MPI + _world_size=1; + _rank=0; + if (MyGlobals::_Verbose>10) + std::cout << "WARNING : ParaDomainSelector contructor without parallel_mode World_Size=1 by default" << std::endl; +#endif + MyGlobals::_World_Size=_world_size; + MyGlobals::_Rank=_rank; + + if (MyGlobals::_Verbose>200) std::cout << "proc " << MyGlobals::_Rank << " of " << MyGlobals::_World_Size << std::endl; + evaluateMemory(); +} + +MEDPARTITIONER::ParaDomainSelector::~ParaDomainSelector() +{ +} + +/*! + * \brief Return true if is running on different hosts + */ +bool MEDPARTITIONER::ParaDomainSelector::isOnDifferentHosts() const +{ + evaluateMemory(); + if ( _world_size < 2 ) return false; + +#ifdef HAVE_MPI + char name_here[ MPI_MAX_PROCESSOR_NAME+1 ], name_there[ MPI_MAX_PROCESSOR_NAME+1 ]; + int size; + MPI_Get_processor_name( name_here, &size); + + int next_proc = (rank() + 1) % nbProcs(); + int prev_proc = (rank() - 1 + nbProcs()) % nbProcs(); + int tag = 1111111; + + MPI_Status status; + MPI_Sendrecv((void*)&name_here[0], MPI_MAX_PROCESSOR_NAME, MPI_CHAR, next_proc, tag, + (void*)&name_there[0], MPI_MAX_PROCESSOR_NAME, MPI_CHAR, prev_proc, tag, + MPI_COMM_WORLD, &status); + + //bug: (isOnDifferentHosts here and there) is not (isOnDifferentHosts somewhere) + //return string(name_here) != string(name_there); + + int sum_same = -1; + int same = 1; + if (std::string(name_here) != std::string(name_there)) + same=0; + MPI_Allreduce( &same, &sum_same, 1, MPI_INT, MPI_SUM, MPI_COMM_WORLD ); + return (sum_same != nbProcs()); +#endif + return false; +} + +/*! + * \brief Return true if the domain with domainIndex is to be loaded on this proc + * \param domainIndex - index of mesh domain + * \retval bool - to load or not + */ +bool MEDPARTITIONER::ParaDomainSelector::isMyDomain(int domainIndex) const +{ + evaluateMemory(); + return (_rank == getProcessorID( domainIndex )); +} + +/*! + * \brief Return processor id where the domain with domainIndex resides + * \param domainIndex - index of mesh domain + * \retval int - processor id + */ +int MEDPARTITIONER::ParaDomainSelector::getProcessorID(int domainIndex) const +{ + evaluateMemory(); + return ( domainIndex % _world_size ); +} + +/*! + * \brief Gather info on nb of cell entities on each processor and return total nb. + * + * Is called + * 1) for MED_CELL to know global id shift for domains at graph construction; + * 2) for sub-entity to know total nb of sub-entities before creating those of joints + */ +void MEDPARTITIONER::ParaDomainSelector::gatherNbOf(const std::vector<ParaMEDMEM::MEDCouplingUMesh*>& domain_meshes) +{ + evaluateMemory(); + // get nb of elems of each domain mesh + int nb_domains=domain_meshes.size(); + std::vector<int> nb_elems(nb_domains*2, 0); //NumberOfCells & NumberOfNodes + for (int i=0; i<nb_domains; ++i) + if ( domain_meshes[i] ) + { + nb_elems[i*2] = domain_meshes[i]->getNumberOfCells(); + nb_elems[i*2+1] = domain_meshes[i]->getNumberOfNodes(); + } + // receive nb of elems from other procs + std::vector<int> all_nb_elems; + if (MyGlobals::_World_Size==1) + { + all_nb_elems=nb_elems; + } + else + { +#ifdef HAVE_MPI + all_nb_elems.resize( nb_domains*2 ); + MPI_Allreduce((void*)&nb_elems[0], (void*)&all_nb_elems[0], nb_domains*2, MPI_INT, MPI_SUM, MPI_COMM_WORLD); +#else + throw INTERP_KERNEL::Exception("not(HAVE_MPI) incompatible with MPI_World_Size>1"); +#endif + } + int total_nb_cells=0, total_nb_nodes=0; + for (int i=0; i<nb_domains; ++i) + { + total_nb_cells+=all_nb_elems[i*2]; + total_nb_nodes+=all_nb_elems[i*2+1]; + } + + if (MyGlobals::_Is0verbose>10) + std::cout << "totalNbCells " << total_nb_cells << " totalNbNodes " << total_nb_nodes << std::endl; + + std::vector<int>& cell_shift_by_domain=_cell_shift_by_domain; + std::vector<int>& node_shift_by_domain=_node_shift_by_domain; + std::vector<int>& face_shift_by_domain=_face_shift_by_domain; + + std::vector< int > ordered_nbs_cell, ordered_nbs_node, domain_order(nb_domains); + ordered_nbs_cell.push_back(0); + ordered_nbs_node.push_back(0); + for (int iproc=0; iproc<nbProcs(); ++iproc) + for (int idomain=0; idomain<nb_domains; ++idomain) + if (getProcessorID( idomain )==iproc) + { + domain_order[idomain] = ordered_nbs_cell.size() - 1; + ordered_nbs_cell.push_back( ordered_nbs_cell.back() + all_nb_elems[idomain*2] ); + ordered_nbs_node.push_back( ordered_nbs_node.back() + all_nb_elems[idomain*2+1] ); + } + cell_shift_by_domain.resize( nb_domains+1, 0 ); + node_shift_by_domain.resize( nb_domains+1, 0 ); + face_shift_by_domain.resize( nb_domains+1, 0 ); + for (int idomain=0; idomain<nb_domains; ++idomain) + { + cell_shift_by_domain[ idomain ] = ordered_nbs_cell[ domain_order[ idomain ]]; + node_shift_by_domain[ idomain ] = ordered_nbs_node[ domain_order[ idomain ]]; + } + cell_shift_by_domain.back() = ordered_nbs_cell.back(); // to know total nb of elements + node_shift_by_domain.back() = ordered_nbs_node.back(); // to know total nb of elements + + if (MyGlobals::_Is0verbose>300) + { + std::cout << "proc " << MyGlobals::_Rank << " : cellShiftByDomain "; + for (int i=0; i<=nb_domains; ++i) + std::cout << cell_shift_by_domain[i] << "|"; + std::cout << std::endl; + std::cout << "proc " << MyGlobals::_Rank << " : nodeShiftBy_domain "; + for (int i=0; i<=nb_domains; ++i) + std::cout << node_shift_by_domain[i] << "|"; + std::cout << std::endl; + } + // fill _nb_vert_of_procs (is Vtxdist) + _nb_vert_of_procs.resize(_world_size+1); + _nb_vert_of_procs[0] = 0; // base = 0 + for (int i=0; i<nb_domains; ++i) + { + int rankk = getProcessorID(i); + _nb_vert_of_procs[rankk+1] += all_nb_elems[i*2]; + } + for (std::size_t i=1; i<_nb_vert_of_procs.size(); ++i) + _nb_vert_of_procs[i] += _nb_vert_of_procs[i-1]; // to CSR format : cumulated + + if (MyGlobals::_Is0verbose>200) + { + std::cout << "proc " << MyGlobals::_Rank << " : gatherNbOf : vtxdist is "; + for (int i = 0; i <= _world_size; ++i) + std::cout << _nb_vert_of_procs[i] << " "; + std::cout << std::endl; + } + + evaluateMemory(); + return; +} + +/*! + * \brief Return distribution of the graph vertices among the processors + * \retval int* - array containing nb of vertices (=cells) on all processors + * + * gatherNbOf() must be called before. + * The result array is to be used as the first arg of ParMETIS_V3_PartKway() and + * is freed by ParaDomainSelector. + */ +int *MEDPARTITIONER::ParaDomainSelector::getProcVtxdist() const +{ + evaluateMemory(); + if (_nb_vert_of_procs.empty()) + throw INTERP_KERNEL::Exception("_nb_vert_of_procs not set"); + return const_cast<int*>(& _nb_vert_of_procs[0]); +} + +/*! + * \brief Return nb of cells in domains with lower index. + * + * gatherNbOf() must be called before. + * Result added to local id on given domain gives id in the whole distributed mesh + */ +int MEDPARTITIONER::ParaDomainSelector::getDomainCellShift(int domainIndex) const +{ + evaluateMemory(); + if (_cell_shift_by_domain.empty()) + throw INTERP_KERNEL::Exception("_cell_shift_by_domain not set"); + return _cell_shift_by_domain[domainIndex]; +} + +int MEDPARTITIONER::ParaDomainSelector::getDomainNodeShift(int domainIndex) const +{ + evaluateMemory(); + if (_node_shift_by_domain.empty()) + throw INTERP_KERNEL::Exception("_node_shift_by_domain not set"); + return _node_shift_by_domain[domainIndex]; +} + +/*! + * \brief Return nb of nodes on processors with lower rank. + * + * gatherNbOf() must be called before. + * Result added to global id on this processor gives id in the whole distributed mesh + */ +int MEDPARTITIONER::ParaDomainSelector::getProcNodeShift() const +{ + evaluateMemory(); + if (_nb_vert_of_procs.empty()) + throw INTERP_KERNEL::Exception("_nb_vert_of_procs not set"); + return _nb_vert_of_procs[_rank]; +} + +/*! + * \brief Gather graphs from all processors into one + */ +std::auto_ptr<MEDPARTITIONER::Graph> MEDPARTITIONER::ParaDomainSelector::gatherGraph(const Graph* graph) const +{ + Graph* glob_graph = 0; + + evaluateMemory(); +#ifdef HAVE_MPI + + // --------------- + // Gather indices + // --------------- + + std::vector<int> index_size_of_proc( nbProcs() ); // index sizes - 1 + for ( std::size_t i = 1; i < _nb_vert_of_procs.size(); ++i ) + index_size_of_proc[i-1] = _nb_vert_of_procs[ i ] - _nb_vert_of_procs[ i-1 ]; + + int index_size = 1 + _cell_shift_by_domain.back(); + int *graph_index = new int[ index_size ]; + const int *index = graph->getGraph()->getIndex(); + int *proc_index_displacement = const_cast<int*>( & _nb_vert_of_procs[0] ); + + MPI_Allgatherv((void*) (index+1), // send local index except first 0 (or 1) + index_size_of_proc[_rank], // index size on this proc + MPI_INT, + (void*) graph_index, // receive indices + & index_size_of_proc[0], // index size on each proc + proc_index_displacement, // displacement of each proc index + MPI_INT, + MPI_COMM_WORLD); + graph_index[0] = index[0]; // it is not overwritten thanks to proc_index_displacement[0]==1 + + // get sizes of graph values on each proc by the got indices of graphs + std::vector< int > value_size_of_proc( nbProcs() ), proc_value_displacement(1,0); + for ( int i = 0; i < nbProcs(); ++i ) + { + if ( index_size_of_proc[i] > 0 ) + value_size_of_proc[i] = graph_index[ proc_index_displacement[ i+1 ]-1 ] - graph_index[0]; + else + value_size_of_proc[i] = 0; + proc_value_displacement.push_back( proc_value_displacement.back() + value_size_of_proc[i] ); + } + + // update graph_index + for ( int i = 1; i < nbProcs(); ++i ) + { + int shift = graph_index[ proc_index_displacement[i]-1 ]-graph_index[0]; + for ( int j = proc_index_displacement[i]; j < proc_index_displacement[i+1]; ++j ) + graph_index[ j ] += shift; + } + + // -------------- + // Gather values + // -------------- + + int value_size = graph_index[ index_size-1 ] - graph_index[ 0 ]; + int *graph_value = new int[ value_size ]; + const int *value = graph->getGraph()->getValue(); + + MPI_Allgatherv((void*) value, // send local value + value_size_of_proc[_rank], // value size on this proc + MPI_INT, + (void*) graph_value, // receive values + & value_size_of_proc[0], // value size on each proc + & proc_value_displacement[0], // displacement of each proc value + MPI_INT, + MPI_COMM_WORLD); + + // ----------------- + // Gather partition + // ----------------- + + int * partition = new int[ _cell_shift_by_domain.back() ]; + const int* part = graph->getPart(); + + MPI_Allgatherv((void*) part, // send local partition + index_size_of_proc[_rank], // index size on this proc + MPI_INT, + (void*)(partition-1), // -1 compensates proc_index_displacement[0]==1 + & index_size_of_proc[0], // index size on each proc + proc_index_displacement, // displacement of each proc index + MPI_INT, + MPI_COMM_WORLD); + + // ----------- + // Make graph + // ----------- + + // MEDCouplingSkyLineArray* array = + // new MEDCouplingSkyLineArray( index_size-1, value_size, graph_index, graph_value, true ); + + // glob_graph = new UserGraph( array, partition, index_size-1 ); + + evaluateMemory(); + + delete [] partition; + +#endif // HAVE_MPI + + return std::auto_ptr<Graph>( glob_graph ); +} + + +/*! + * \brief Set nb of cell/cell pairs in a joint between domains + */ +void MEDPARTITIONER::ParaDomainSelector::setNbCellPairs( int nb_cell_pairs, int dist_domain, int loc_domain ) +{ + // This method is needed for further computing global numbers of faces in joint. + // Store if both domains are on this proc else on one of procs only + if ( isMyDomain( dist_domain ) || dist_domain < loc_domain ) + { + if ( _nb_cell_pairs_by_joint.empty() ) + _nb_cell_pairs_by_joint.resize( _nb_result_domains*(_nb_result_domains+1), 0); + + int joint_id = jointId( loc_domain, dist_domain ); + _nb_cell_pairs_by_joint[ joint_id ] = nb_cell_pairs; + } + evaluateMemory(); +} + +//================================================================================ +/*! + * \brief Return nb of cell/cell pairs in a joint between domains on different procs + */ +//================================================================================ + +int MEDPARTITIONER::ParaDomainSelector::getNbCellPairs( int dist_domain, int loc_domain ) const +{ + evaluateMemory(); + + int joint_id = jointId( loc_domain, dist_domain ); + return _nb_cell_pairs_by_joint[ joint_id ]; +} + +//================================================================================ +/*! + * \brief Gather size of each joint + */ +//================================================================================ + +void MEDPARTITIONER::ParaDomainSelector::gatherNbCellPairs() +{ + if ( _nb_cell_pairs_by_joint.empty() ) + _nb_cell_pairs_by_joint.resize( _nb_result_domains*(_nb_result_domains+1), 0); + evaluateMemory(); + + std::vector< int > send_buf = _nb_cell_pairs_by_joint; +#ifdef HAVE_MPI + MPI_Allreduce((void*)&send_buf[0], + (void*)&_nb_cell_pairs_by_joint[0], + _nb_cell_pairs_by_joint.size(), + MPI_INT, MPI_SUM, MPI_COMM_WORLD); +#endif + // check that the set nbs of cell pairs are correct, + // namely that each joint is treated on one proc only + for ( std::size_t j = 0; j < _nb_cell_pairs_by_joint.size(); ++j ) + if ( _nb_cell_pairs_by_joint[j] != send_buf[j] && send_buf[j]>0 ) + throw INTERP_KERNEL::Exception("invalid nb of cell pairs"); +} + +//================================================================================ +/*! + * \brief Return the first global id of sub-entity for the joint + */ +//================================================================================ + +int MEDPARTITIONER::ParaDomainSelector::getFisrtGlobalIdOfSubentity( int loc_domain, int dist_domain ) const +{ + // total_nb_faces includes faces existing before creation of joint faces + // (got in gatherNbOf( MED_FACE )). + evaluateMemory(); + + int total_nb_faces = _face_shift_by_domain.empty() ? 0 : _face_shift_by_domain.back(); + int id = total_nb_faces + 1; + + if ( _nb_cell_pairs_by_joint.empty() ) + throw INTERP_KERNEL::Exception("gatherNbCellPairs() must be called before"); + int joint_id = jointId( loc_domain, dist_domain ); + for ( int j = 0; j < joint_id; ++j ) + id += _nb_cell_pairs_by_joint[ j ]; + + return id; +} + +//================================================================================ +/*! + * \brief Send-receive local ids of joint faces + */ +//================================================================================ + +int *MEDPARTITIONER::ParaDomainSelector::exchangeSubentityIds( int loc_domain, int dist_domain, + const std::vector<int>& loc_ids_here ) const +{ + int* loc_ids_dist = new int[ loc_ids_here.size()]; +#ifdef HAVE_MPI + int dest = getProcessorID( dist_domain ); + int tag = 2002 + jointId( loc_domain, dist_domain ); + MPI_Status status; + MPI_Sendrecv((void*)&loc_ids_here[0], loc_ids_here.size(), MPI_INT, dest, tag, + (void*) loc_ids_dist, loc_ids_here.size(), MPI_INT, dest, tag, + MPI_COMM_WORLD, &status); +#endif + evaluateMemory(); + + return loc_ids_dist; +} + +//================================================================================ +/*! + * \brief Return identifier for a joint + */ +//================================================================================ + +int MEDPARTITIONER::ParaDomainSelector::jointId( int local_domain, int distant_domain ) const +{ + evaluateMemory(); + if (_nb_result_domains < 0) + throw INTERP_KERNEL::Exception("setNbDomains() must be called before"); + + if ( local_domain < distant_domain ) + std::swap( local_domain, distant_domain ); + return local_domain * _nb_result_domains + distant_domain; +} + + +//================================================================================ +/*! + * \brief Return time passed from construction in seconds + */ +//================================================================================ + +double MEDPARTITIONER::ParaDomainSelector::getPassedTime() const +{ +#ifdef HAVE_MPI + return MPI_Wtime() - _init_time; +#else + return 0.0; +#endif +} + +/*! + Sends content of \a mesh to processor \a target. To be used with \a recvMesh method. + \param mesh mesh to be sent + \param target processor id of the target +*/ + +void MEDPARTITIONER::ParaDomainSelector::sendMesh(const ParaMEDMEM::MEDCouplingUMesh& mesh, int target) const +{ +#ifndef HAVE_MPI + throw INTERP_KERNEL::Exception("ParaDomainSelector::sendMesh : incoherent call in non_MPI mode"); +#else + if (MyGlobals::_Verbose>600) + std::cout << "proc " << _rank << " : sendMesh '" << mesh.getName() << "' size " << mesh.getNumberOfCells() << " to " << target << std::endl; + // First stage : sending sizes + // ------------------------------ + std::vector<int> tinyInfoLocal; + std::vector<std::string> tinyInfoLocalS; + std::vector<double> tinyInfoLocalD; + //Getting tiny info of local mesh to allow the distant proc to initialize and allocate + //the transmitted mesh. + mesh.getTinySerializationInformation(tinyInfoLocalD,tinyInfoLocal,tinyInfoLocalS); + tinyInfoLocal.push_back(mesh.getNumberOfCells()); + int tinySize=tinyInfoLocal.size(); + MPI_Send(&tinySize, 1, MPI_INT, target, 1113, MPI_COMM_WORLD); + MPI_Send(&tinyInfoLocal[0], tinyInfoLocal.size(), MPI_INT, target, 1112, MPI_COMM_WORLD); + + if (mesh.getNumberOfCells()>0) //no sends if empty + { + ParaMEDMEM::DataArrayInt *v1Local=0; + ParaMEDMEM::DataArrayDouble *v2Local=0; + //serialization of local mesh to send data to distant proc. + mesh.serialize(v1Local,v2Local); + int nbLocalElems=0; + int* ptLocal=0; + if(v1Local) //if empty getNbOfElems() is 1! + { + nbLocalElems=v1Local->getNbOfElems(); // if empty be 1! + ptLocal=v1Local->getPointer(); + } + MPI_Send(ptLocal, nbLocalElems, MPI_INT, target, 1111, MPI_COMM_WORLD); + int nbLocalElems2=0; + double *ptLocal2=0; + if(v2Local) //if empty be 0! + { + nbLocalElems2=v2Local->getNbOfElems(); + ptLocal2=v2Local->getPointer(); + } + MPI_Send(ptLocal2, nbLocalElems2, MPI_DOUBLE, target, 1110, MPI_COMM_WORLD); + if(v1Local) v1Local->decrRef(); + if(v2Local) v2Local->decrRef(); + } +#endif +} + +/*! Receives messages from proc \a source to fill mesh \a mesh. + To be used with \a sendMesh method. + \param mesh pointer to mesh that is filled + \param source processor id of the incoming messages +*/ +void MEDPARTITIONER::ParaDomainSelector::recvMesh(ParaMEDMEM::MEDCouplingUMesh*& mesh, int source)const +{ +#ifndef HAVE_MPI + throw INTERP_KERNEL::Exception("ParaDomainSelector::recvMesh : incoherent call in non_MPI mode"); +#else + // First stage : exchanging sizes + // ------------------------------ + std::vector<int> tinyInfoDistant; + std::vector<std::string> tinyInfoLocalS; + std::vector<double> tinyInfoDistantD(1); + //Getting tiny info of local mesh to allow the distant proc to initialize and allocate + //the transmitted mesh. + MPI_Status status; + int tinyVecSize; + MPI_Recv(&tinyVecSize, 1, MPI_INT, source, 1113, MPI_COMM_WORLD, &status); + tinyInfoDistant.resize(tinyVecSize); + std::fill(tinyInfoDistant.begin(),tinyInfoDistant.end(),0); + + MPI_Recv(&tinyInfoDistant[0], tinyVecSize, MPI_INT,source,1112,MPI_COMM_WORLD, &status); + //there was tinyInfoLocal.push_back(mesh.getNumberOfCells()); + int NumberOfCells=tinyInfoDistant[tinyVecSize-1]; + if (NumberOfCells>0) + { + ParaMEDMEM::DataArrayInt *v1Distant=ParaMEDMEM::DataArrayInt::New(); + ParaMEDMEM::DataArrayDouble *v2Distant=ParaMEDMEM::DataArrayDouble::New(); + //Building the right instance of copy of distant mesh. + ParaMEDMEM::MEDCouplingPointSet *distant_mesh_tmp= + ParaMEDMEM::MEDCouplingPointSet::BuildInstanceFromMeshType( + (ParaMEDMEM::MEDCouplingMeshType) tinyInfoDistant[0]); + std::vector<std::string> unusedTinyDistantSts; + mesh=dynamic_cast<ParaMEDMEM::MEDCouplingUMesh*> (distant_mesh_tmp); + + mesh->resizeForUnserialization(tinyInfoDistant,v1Distant,v2Distant,unusedTinyDistantSts); + int nbDistElem=0; + int *ptDist=0; + if(v1Distant) + { + nbDistElem=v1Distant->getNbOfElems(); + ptDist=v1Distant->getPointer(); + } + MPI_Recv(ptDist, nbDistElem, MPI_INT, source,1111, MPI_COMM_WORLD, &status); + double *ptDist2=0; + nbDistElem=0; + if(v2Distant) + { + nbDistElem=v2Distant->getNbOfElems(); + ptDist2=v2Distant->getPointer(); + } + MPI_Recv(ptDist2, nbDistElem, MPI_DOUBLE,source, 1110, MPI_COMM_WORLD, &status); + //finish unserialization + mesh->unserialization(tinyInfoDistantD,tinyInfoDistant,v1Distant,v2Distant,unusedTinyDistantSts); + if(v1Distant) v1Distant->decrRef(); + if(v2Distant) v2Distant->decrRef(); + } + else + { + mesh=CreateEmptyMEDCouplingUMesh(); + } + if (MyGlobals::_Verbose>600) + std::cout << "proc " << _rank << " : recvMesh '" << mesh->getName() << "' size " << mesh->getNumberOfCells() << " from " << source << std::endl; +#endif +} + +#ifndef WIN32 +#include <sys/sysinfo.h> +#endif + +/*! + * \brief Evaluate current memory usage and return the maximal one in KB + */ +int MEDPARTITIONER::ParaDomainSelector::evaluateMemory() const +{ + if ( _mesure_memory ) + { + int used_memory = 0; +#ifndef WIN32 + struct sysinfo si; + int err = sysinfo( &si ); + if ( !err ) + used_memory = (( si.totalram - si.freeram + si.totalswap - si.freeswap ) * si.mem_unit ) / 1024; +#endif + if ( used_memory > _max_memory ) + _max_memory = used_memory; + + if ( !_init_memory ) + _init_memory = used_memory; + } + return _max_memory - _init_memory; +} diff --git a/src/medtool/src/MEDPartitioner/MEDPARTITIONER_ParaDomainSelector.hxx b/src/medtool/src/MEDPartitioner/MEDPARTITIONER_ParaDomainSelector.hxx new file mode 100644 index 000000000..7db3c6082 --- /dev/null +++ b/src/medtool/src/MEDPartitioner/MEDPARTITIONER_ParaDomainSelector.hxx @@ -0,0 +1,119 @@ +// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// + +#ifndef __MEDPARTITIONER_PARADOMAINSELECTOR_HXX__ +#define __MEDPARTITIONER_PARADOMAINSELECTOR_HXX__ + +#include "MEDPARTITIONER.hxx" + +#include <memory> +#include <vector> + +namespace ParaMEDMEM +{ + class MEDCouplingUMesh; +} + +namespace MEDPARTITIONER +{ + class Graph; + class JointExchangeData; + + /*! + * \brief Communication helper in parallel mode + */ + class MEDPARTITIONER_EXPORT ParaDomainSelector + { + public: + ParaDomainSelector(bool mesure_memory=false); + ~ParaDomainSelector(); + + //processor rank + int rank() const { return _rank; } + //number of processors + int nbProcs() const { return _world_size; } + //true if is running on different hosts + bool isOnDifferentHosts() const; + //true if the domain with domainIndex is to be loaded on this proc + bool isMyDomain(int domainIndex) const; + //processor id where the domain with domainIndex resides + int getProcessorID(int domainIndex) const; + //Set nb of required domains. (Used to sort joints via jointId()) + void setNbDomains(int nb) { _nb_result_domains = nb; } + //identifier for a joint + int jointId( int local_domain, int distant_domain ) const; + + int getNbTotalCells() { return _cell_shift_by_domain.back(); } + int getNbTotalNodes() { return _node_shift_by_domain.back(); }; + int getNbTotalFaces() { return _face_shift_by_domain.back(); }; + + //Collect nb of entities on procs + void gatherNbOf(const std::vector<ParaMEDMEM::MEDCouplingUMesh*>& domain_meshes); + + //distribution of the graph vertices among the processors + int* getProcVtxdist() const; + + //nb of nodes on processors with lower rank + int getProcNodeShift() const; + //nb of cells in domains with lower index + int getDomainCellShift(int domainIndex) const; + //nb of nodes in domains with lower index + int getDomainNodeShift(int domainIndex) const; + + //Gather graphs from all processors into one + std::auto_ptr<Graph> gatherGraph(const Graph* graph) const; + + //Set nb of cell/cell pairs in a joint between domains + void setNbCellPairs( int nb_cell_pairs, int dist_domain, int loc_domain ); + //Gather size of each proc/proc joint + void gatherNbCellPairs(); + //nb of cell/cell pairs in a joint between domains on different procs + int getNbCellPairs( int dist_domain, int loc_domain ) const; + + //get the first global id of sub-entity for the joint + int getFisrtGlobalIdOfSubentity( int loc_domain, int dist_domain ) const; + //Send-receive local ids of joint faces + int* exchangeSubentityIds( int loc_domain, int dist_domain, + const std::vector<int>& loc_ids_here ) const; + //time passed from construction in seconds + double getPassedTime() const; + + //Evaluate current memory usage and return the maximal one in KB + int evaluateMemory() const; + + void sendMesh(const ParaMEDMEM::MEDCouplingUMesh& mesh, int target) const; + void recvMesh(ParaMEDMEM::MEDCouplingUMesh*& mesh, int source) const; + private: + int _rank; //my rank + int _world_size; //nb of processors + int _nb_result_domains; //required nb of domains + + std::vector< int > _nb_cell_pairs_by_joint; + std::vector< int > _nb_vert_of_procs; //graph vertices + std::vector< int > _cell_shift_by_domain; + std::vector< int > _node_shift_by_domain; + std::vector< int > _face_shift_by_domain; + + double _init_time; + bool _mesure_memory; + mutable int _init_memory; + mutable int _max_memory; + }; +} +#endif diff --git a/src/medtool/src/MEDPartitioner/MEDPARTITIONER_ParallelTopology.cxx b/src/medtool/src/MEDPartitioner/MEDPARTITIONER_ParallelTopology.cxx new file mode 100644 index 000000000..b65d3fdd1 --- /dev/null +++ b/src/medtool/src/MEDPartitioner/MEDPARTITIONER_ParallelTopology.cxx @@ -0,0 +1,674 @@ +// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// + +#include "MEDPARTITIONER_MeshCollection.hxx" +#include "MEDPARTITIONER_Topology.hxx" +#include "MEDPARTITIONER_Graph.hxx" +#include "MEDPARTITIONER_ParaDomainSelector.hxx" +#include "MEDPARTITIONER_ParallelTopology.hxx" +#include "MEDPARTITIONER_ConnectZone.hxx" +#include "MEDPARTITIONER_Utils.hxx" + +#include "MEDCouplingSkyLineArray.hxx" +#include "MEDCouplingUMesh.hxx" +#include "InterpKernelHashMap.hxx" + +#include <set> +#include <map> +#include <vector> +#include <iostream> + +#ifdef HAVE_MPI +#include <mpi.h> +#endif + +using namespace MEDPARTITIONER; + +ParallelTopology::ParallelTopology():_nb_domain(0),_mesh_dimension(0) +{ +} + +//constructing topology according to mesh collection without global numerotation (use setGlobalNumerotation later) +ParallelTopology::ParallelTopology(const std::vector<ParaMEDMEM::MEDCouplingUMesh*>& meshes) +{ + _nb_domain=meshes.size(); + _nb_cells.resize(_nb_domain); + _nb_nodes.resize(_nb_domain); + // _nb_faces.resize(_nb_domain); + + if (MyGlobals::_Is0verbose>100) + std::cout << "new ParallelTopology\n"; + _loc_to_glob.resize(0); //precaution, need gatherNbOf() setGlobalNumerotation() + _node_loc_to_glob.resize(0); //precaution, need gatherNbOf() setGlobalNumerotation() + //_face_loc_to_glob.resize(_nb_domain); + _mesh_dimension = -1; + bool parallel_mode = false; + for (int idomain=0; !parallel_mode && idomain<_nb_domain; idomain++) + parallel_mode = (!meshes[idomain]); + + if (MyGlobals::_Is0verbose>20 && !parallel_mode) + std::cout << "WARNING : ParallelTopology contructor without parallel_mode" << std::endl; + for (int idomain=0; idomain<_nb_domain; idomain++) + { + if ( !meshes[idomain] ) continue; + if (_mesh_dimension==-1) + { + _mesh_dimension = meshes[idomain]->getMeshDimension(); + } + else + { + if (_mesh_dimension!=meshes[idomain]->getMeshDimension()) + throw INTERP_KERNEL::Exception("meshes dimensions incompatible"); + } + _nb_cells[idomain]=meshes[idomain]->getNumberOfCells(); + _nb_nodes[idomain]=meshes[idomain]->getNumberOfNodes(); + //note: in parallel mode _nb_cells and _nb_nodes are not complete now, needs gatherNbOf() + } +} + +//constructing _loc_to_glob etc by default, needs gatherNbOf() done +void ParallelTopology::setGlobalNumerotationDefault(ParaDomainSelector* domainSelector) +{ + if (MyGlobals::_Is0verbose>100) + std::cout<< "setGlobalNumerotationDefault on " << _nb_domain << " domains\n"; + if (_loc_to_glob.size()!=0) throw INTERP_KERNEL::Exception("a global numerotation is done yet"); + _loc_to_glob.resize(_nb_domain); + _node_loc_to_glob.resize(_nb_domain); + + //warning because _nb_cells[idomain] is 0 if not my domain(s) + //we set loc_to_glob etc.. only for my domain(s) + if (MyGlobals::_Is0verbose>500) + std::cout << "(c)idomain|ilocalCell|iglobalCell" << std::endl; + for (int idomain=0; idomain<_nb_domain; idomain++) + { + _loc_to_glob[idomain].resize(_nb_cells[idomain]); + int domainCellShift=domainSelector->getDomainCellShift(idomain); + for (int i=0; i<_nb_cells[idomain]; i++) + { + int global=domainCellShift+i ; + _glob_to_loc.insert(std::make_pair(global,std::make_pair(idomain,i))); + _loc_to_glob[idomain][i]=global; + if (MyGlobals::_Verbose>500) + std::cout << "c" << idomain << "|" << i << "|" << global << " "; + } + } +#ifdef HAVE_MPI + if (MyGlobals::_Verbose>500 && MyGlobals::_World_Size>1) MPI_Barrier(MPI_COMM_WORLD); //synchronize verbose trace +#endif + if (MyGlobals::_Is0verbose>500) std::cout << std::endl; + + if (MyGlobals::_Is0verbose>500) std::cout << "(n)idomain|ilocalNode|iglobalNode" << std::endl; + for (int idomain=0; idomain<_nb_domain; idomain++) + { + _node_loc_to_glob[idomain].resize(_nb_nodes[idomain]); + int domainNodeShift=domainSelector->getDomainNodeShift(idomain); + for (int i=0; i<_nb_nodes[idomain]; i++) + { + int global=domainNodeShift+i ; + _node_glob_to_loc.insert(std::make_pair(global,std::make_pair(idomain,i))); + _node_loc_to_glob[idomain][i]=global; + if (MyGlobals::_Verbose>500) + std::cout << "n" << idomain << "|" << i << "|" << global << " "; + } + } +#ifdef HAVE_MPI + if (MyGlobals::_Verbose>500 && MyGlobals::_World_Size>1) MPI_Barrier(MPI_COMM_WORLD); //synchronize verbose trace +#endif + if (MyGlobals::_Is0verbose>500) std::cout << std::endl; + + _nb_total_cells=domainSelector->getNbTotalCells(); + _nb_total_nodes=domainSelector->getNbTotalNodes(); + _nb_total_faces=domainSelector->getNbTotalFaces(); + if (MyGlobals::_Is0verbose>200) + std::cout << "globalNumerotation default done meshDimension " << _mesh_dimension << " nbTotalCells " << _nb_total_cells << " nbTotalNodes " << _nb_total_nodes << std::endl; +} + +//constructing topology according to mesh collection +ParallelTopology::ParallelTopology(const std::vector<ParaMEDMEM::MEDCouplingUMesh*>& meshes, + const std::vector<MEDPARTITIONER::ConnectZone*>& cz, + std::vector<int*>& cellglobal, + std::vector<int*>& nodeglobal, + std::vector<int*>& faceglobal) +{ + _nb_domain=meshes.size(); + int index_global=0; + int index_node_global=0; + int index_face_global=0; + + _nb_cells.resize(_nb_domain); + _nb_nodes.resize(_nb_domain); + // _nb_faces.resize(_nb_domain); + + _loc_to_glob.resize(_nb_domain); + _node_loc_to_glob.resize(_nb_domain); + // _face_loc_to_glob.resize(_nb_domain); + + bool parallel_mode = false; + for (int idomain=0; !parallel_mode && idomain<_nb_domain; idomain++) + parallel_mode = (!meshes[idomain]); + + for (int idomain=0; idomain<_nb_domain; idomain++) + { + if ( !meshes[idomain] ) continue; + _mesh_dimension = meshes[idomain]->getMeshDimension(); + + //creating cell maps + _nb_cells[idomain]=meshes[idomain]->getNumberOfCells(); + // cout << "Nb cells (domain "<<idomain<<") = "<<_nb_cells[idomain]; + _loc_to_glob[idomain].resize(_nb_cells[idomain]); + + if (cellglobal[idomain]==0 || parallel_mode) + { + //int cellDomainShift=_cell_shift_by_domain[idomain]; + //creating global numbering from scratch + for (int i=0; i<_nb_cells[idomain]; i++) + { + int global=i ;//cellDomainShift+i; + _glob_to_loc.insert(std::make_pair(global,std::make_pair(idomain,i))); + _loc_to_glob[idomain][i]=global; + index_global++; + } + } + //using global numbering coming from a previous numbering + else + { + for (int i=0; i<_nb_cells[idomain]; i++) + { + int global=cellglobal[idomain][i]; + _glob_to_loc.insert(std::make_pair(global,std::make_pair(idomain,i))); + //_loc_to_glob[make_pair(idomain,i+1)]=global; + _loc_to_glob[idomain][i]=global; + index_global++; + } + } + + //cas sequentiel + if (_nb_domain==1) + { + _nb_total_cells=index_global; + _nb_cells[0]=index_global; + _node_loc_to_glob[idomain].resize(meshes[idomain]->getNumberOfNodes()); + for (int i=0; i<meshes[idomain]->getNumberOfNodes(); i++) + { + _node_glob_to_loc.insert(std::make_pair(i,std::make_pair(0,i))); + _node_loc_to_glob[0][i]=i; + } + _nb_total_nodes=meshes[idomain]->getNumberOfNodes(); + _nb_nodes[0]=_nb_total_nodes; + return; + } + + //creating node maps + _nb_nodes[idomain]=meshes[idomain]->getNumberOfNodes(); + INTERP_KERNEL::HashMap <int,std::pair<int,int> > local2distant; + _node_loc_to_glob[idomain].resize(_nb_nodes[idomain]); + for (std::size_t icz=0; icz<cz.size(); icz++) + { + if (cz[icz]->getLocalDomainNumber() == idomain && + cz[icz]->getLocalDomainNumber()>cz[icz]->getDistantDomainNumber()) + { + int nb_node= cz[icz]->getNodeNumber(); + const int* node_corresp=cz[icz]->getNodeCorrespValue(); + int distant_ip = cz[icz]->getDistantDomainNumber(); + for (int i=0; i< nb_node; i++) + { + int local= node_corresp[i*2]; + int distant = node_corresp[i*2+1]; + local2distant.insert(std::make_pair(local, std::make_pair(distant_ip,distant))); + } + } + } + // setting mappings for all nodes + if (nodeglobal[idomain]==0) + { + for (int inode=0; inode<_nb_nodes[idomain]; inode++) + { + if (local2distant.find(inode)==local2distant.end()) + { + index_node_global++; + _node_glob_to_loc.insert(std::make_pair(index_node_global,std::make_pair(idomain,inode))); + //_node_loc_to_glob[make_pair(idomain,inode+1)]=index_node_global; + _node_loc_to_glob[idomain][inode]=index_node_global; + } + else + { + int ip = (local2distant.find(inode)->second).first; + int distant = (local2distant.find(inode)->second).second; + int global_number=_loc_to_glob[ip][distant]; + _node_glob_to_loc.insert(std::make_pair(global_number,std::make_pair(idomain,inode))); + _node_loc_to_glob[idomain][inode]=global_number; + } + } + } + //using former node numbering + else + { + for (int inode=0; inode<_nb_nodes[idomain]; inode++) + { + int global_number=nodeglobal[idomain][inode]; + _node_glob_to_loc.insert(std::make_pair(global_number,std::make_pair(idomain,inode))); + _node_loc_to_glob[idomain][inode]=global_number; + } + } + } + + _nb_total_cells=index_global; + _nb_total_nodes=index_node_global; + _nb_total_faces=index_face_global; +} + + +//constructing ParallelTopology from an old topology and a graph +ParallelTopology::ParallelTopology(Graph* graph, Topology* oldTopology, int nb_domain, int mesh_dimension) +{ + + _nb_domain=nb_domain; + _mesh_dimension=mesh_dimension; + + if (MyGlobals::_Verbose>200) + std::cout << "proc " << MyGlobals::_Rank << " : new topology oldNbDomain " << + oldTopology->nbDomain() << " newNbDomain " << _nb_domain << std::endl; + _nb_cells.resize(_nb_domain,0); + _nb_nodes.resize(_nb_domain,0); + _nb_faces.resize(_nb_domain,0); + + _loc_to_glob.resize(_nb_domain); + _node_loc_to_glob.resize(_nb_domain); + _face_loc_to_glob.resize(_nb_domain); + + const int* part=graph->getPart(); //all cells for this proc (may be more domains) + _nb_total_cells=graph->nbVertices(); //all cells for this proc (may be more domains) + if (MyGlobals::_Verbose>300) + std::cout << "proc " << MyGlobals::_Rank << " : topology from partition, nbTotalCells " << _nb_total_cells << std::endl; + + int icellProc=0; //all cells of my domains are concatenated in part + for (int iold=0; iold<oldTopology->nbDomain(); iold++) + { + int ioldNbCell=oldTopology->getCellNumber(iold); + //std::cout<<"proc "<<MyGlobals::_Rank<<" : cell number old domain "<<iold<<" : "<<ioldNbCell<<std::endl; + //if not my old domains getCellNumber is 0 + std::vector<int> globalids(ioldNbCell); + oldTopology->getCellList(iold, &globalids[0]); //unique global numerotation + for (int icell=0; icell<ioldNbCell; icell++) + { + int idomain=part[icellProc]; + _nb_cells[idomain]++; + icellProc++; + int iGlobalCell=globalids[icell]; + _loc_to_glob[idomain].push_back(iGlobalCell); + _glob_to_loc.insert(std::make_pair(iGlobalCell, std::make_pair(idomain, _nb_cells[idomain]))); + } + } + + if (MyGlobals::_Verbose>300) + for (int idomain=0; idomain<_nb_domain; idomain++) + std::cout << "proc " << MyGlobals::_Rank << " : nbCells in new domain " << idomain << " : " << _nb_cells[idomain] << std::endl; + + // JOINTs + + if ( MyGlobals::_Create_Joints && nb_domain > 1 ) + { + std::vector< std::vector< std::vector< int > > > cellCorresp( nb_domain ); + for ( int idomain = 0; idomain < nb_domain; ++idomain ) + { + cellCorresp[ idomain ].resize( nb_domain ); + } + const ParaMEDMEM::MEDCouplingSkyLineArray* skylinegraph = graph->getGraph(); + const int* index = skylinegraph->getIndex(); + const int* value = skylinegraph->getValue(); + const int nbCells = skylinegraph->getNumberOf(); + + for ( int iGlob = 0; iGlob < nbCells; ++iGlob ) + { + int iGlobDom = part[ iGlob ]; + for ( int i = index[ iGlob ]; i < index[ iGlob+1 ]; i++ ) + { + int iGlobNear = value[ i ]; + if ( iGlob > iGlobNear ) + continue; // treat ( iGlob, iGlobNear ) pair once + int iGlobNearDom = part[ iGlobNear ]; + if ( iGlobDom != iGlobNearDom ) + { + int iLoc = convertGlobalCell( iGlob ).second - 1; // to MEDCoupling fmt + int iLocNear = convertGlobalCell( iGlobNear ).second - 1; + cellCorresp[ iGlobDom ][ iGlobNearDom ].push_back( iLoc ); + cellCorresp[ iGlobDom ][ iGlobNearDom ].push_back( iLocNear ); + cellCorresp[ iGlobNearDom ][ iGlobDom ].push_back( iLocNear ); + cellCorresp[ iGlobNearDom ][ iGlobDom ].push_back( iLoc ); + } + } + } + for ( int idomain = 0; idomain < nb_domain; ++idomain ) + { + for ( int idomainNear = 0; idomainNear < nb_domain; ++idomainNear ) + { + std::vector< int > & corresp = cellCorresp[ idomain ][ idomainNear ]; + if ( corresp.empty() ) + continue; + MEDPARTITIONER::ConnectZone* cz = new MEDPARTITIONER::ConnectZone(); + cz->setName( "Connect Zone defined by MEDPARTITIONER" ); + cz->setDistantDomainNumber( idomainNear ); + cz->setLocalDomainNumber ( idomain ); + cz->setEntityCorresp( 0,0, &corresp[0], corresp.size()/2 ); + _connect_zones.push_back( cz ); + } + } + } +} + +ParallelTopology::~ParallelTopology() +{ + for ( size_t i = 0; i < _connect_zones.size(); ++i ) + { + delete _connect_zones[i]; + _connect_zones[i] = 0; + } + _connect_zones.clear(); +} + +/*!Converts a list of global node numbers + * to a distributed array with local cell numbers. + * + * If a node in the list is represented on several domains, + * only the first value is returned + * */ +void ParallelTopology::convertGlobalNodeList(const int* node_list, int nbnode, int* local, int* ip) +{ + if (_node_glob_to_loc.empty()) + throw INTERP_KERNEL::Exception("Node mapping has not yet been built"); + for (int i=0; i< nbnode; i++) + { + std::pair<int,int> local_node = _node_glob_to_loc.find(node_list[i])->second; + ip[i]=local_node.first; + local[i]=local_node.second; + } +} + +/*!Converts a list of global node numbers on domain ip + * to a distributed array with local cell numbers. + * + * If a node in the list is represented on several domains, + * only the value with domain ip is returned + * + * */ +void ParallelTopology::convertGlobalNodeList(const int* node_list, int nbnode, int* local, int ip) +{ + if (_node_glob_to_loc.empty()) + throw INTERP_KERNEL::Exception("Node mapping has not yet been built"); + + for (int i=0; i< nbnode; i++) + { + typedef INTERP_KERNEL::HashMultiMap<int,std::pair<int,int> >::iterator mmiter; + std::pair<mmiter,mmiter> range=_node_glob_to_loc.equal_range(node_list[i]); + for (mmiter it=range.first; it !=range.second; it++) + { + int ipfound=(it->second).first; + if (ipfound==ip) + local[i]=(it->second).second; + } + } +} + +/*!Converts a list of global node numbers + * to a distributed array with local cell numbers. + * + * If a node in the list is represented on several domains, + * all the values are put in the array + * */ +void ParallelTopology::convertGlobalNodeListWithTwins(const int* node_list, int nbnode, int*& local, int*& ip,int*& full_array, int& size) +{ + if (_node_glob_to_loc.empty()) + throw INTERP_KERNEL::Exception("Node mapping has not yet been built"); + + size=0; + for (int i=0; i< nbnode; i++) + { + int count= _node_glob_to_loc.count(node_list[i]); + size+=count; + } + int index=0; + ip=new int[size]; + local=new int[size]; + full_array=new int[size]; + for (int i=0; i< nbnode; i++) + { + typedef INTERP_KERNEL::HashMultiMap<int,std::pair<int,int> >::iterator mmiter; + std::pair<mmiter,mmiter> range=_node_glob_to_loc.equal_range(node_list[i]); + for (mmiter it=range.first; it !=range.second; it++) + { + ip[index]=(it->second).first; + local[index]=(it->second).second; + full_array [index]=node_list[i]; + index++; + } + + } +} + +/*!Converts a list of global face numbers + * to a distributed array with local face numbers. + * + * If a face in the list is represented on several domains, + * all the values are put in the array + * */ +void ParallelTopology::convertGlobalFaceListWithTwins(const int* face_list, int nbface, int*& local, int*& ip, int*& full_array,int& size) +{ + size=0; + for (int i=0; i< nbface; i++) + { + //int count = _face_glob_to_loc.count(face_list[i]); + //if (count >1) MESSAGE_MED("face en doublon "<<face_list[i]); + size+= _face_glob_to_loc.count(face_list[i]); + } + int index=0; + ip=new int[size]; + local=new int[size]; + full_array=new int[size]; + for (int i=0; i< nbface; i++) + { + typedef INTERP_KERNEL::HashMultiMap<int,std::pair<int,int> >::iterator mmiter; + std::pair<mmiter,mmiter> range=_face_glob_to_loc.equal_range(face_list[i]); + for (mmiter it=range.first; it !=range.second; it++) + { + ip[index]=(it->second).first; + local[index]=(it->second).second; + full_array[index]=face_list[i]; + index++; + } + + } +} + +//!converts a list of global cell numbers +//!to a distributed array with local cell numbers +void ParallelTopology::convertGlobalCellList(const int* cell_list, int nbcell, int* local, int* ip) +{ + for (int i=0; i<nbcell; i++) + { + INTERP_KERNEL::HashMap<int, std::pair<int,int> >::const_iterator iter = _glob_to_loc.find(cell_list[i]); + if (iter == _glob_to_loc.end()) + { + std::cerr << "proc " << MyGlobals::_Rank << " : KO cell_list[" << i << "] : " << cell_list[i] << std::endl; + throw INTERP_KERNEL::Exception("ParallelTopology::convertGlobalCellList : Cell not found"); + } + else + { + ip[i]=(iter->second).first; //no domain + local[i]=(iter->second).second; //no local cell + } + } +} + +/*!Converts a list of global face numbers + * to a distributed array with local face numbers + */ +void ParallelTopology::convertGlobalFaceList(const int* face_list, int nbface, int* local, int* ip) +{ + for (int i=0; i< nbface; i++) + { + INTERP_KERNEL::HashMap<int, std::pair<int,int> >::const_iterator iter = _face_glob_to_loc.find(face_list[i]); + if (iter == _face_glob_to_loc.end()) + { + throw INTERP_KERNEL::Exception("ParallelTopology::convertGlobalFaceList : Face not found"); + } + ip[i]=(iter->second).first; + local[i]=(iter->second).second; + } +} + +/*!Converts a list of global node numbers on domain ip + * to a distributed array with local cell numbers. + * + * If a node in the list is represented on several domains, + * only the value with domain ip is returned + * + */ +void ParallelTopology::convertGlobalFaceList(const int* face_list, int nbface, int* local, int ip) +{ + for (int i=0; i< nbface; i++) + { + typedef INTERP_KERNEL::HashMultiMap<int,std::pair<int,int> >::iterator mmiter; + std::pair<mmiter,mmiter> range=_face_glob_to_loc.equal_range(face_list[i]); + for (mmiter it=range.first; it !=range.second; it++) + { + int ipfound=(it->second).first; + if (ipfound==ip) + local[i]=(it->second).second; + + } + } +} + +//replacing a table of global numbering with a table with local numberings +// type_connectivity contains global connectivity for each type in input +// type_connectivity contains local connectivity for each type in output +void ParallelTopology::convertToLocal2ndVersion(int* nodes, int nbnodes, int idomain) +{ + for (int inode=0; inode<nbnodes; inode++) + { + // cout <<" inode :"<<inode<< " global = "<<type_connectivity[type][inode]; + int global = nodes[inode]; + typedef INTERP_KERNEL::HashMultiMap<int,std::pair<int,int> >::iterator mmiter; + std::pair<mmiter,mmiter> range=_node_glob_to_loc.equal_range(global); + for (mmiter it=range.first; it !=range.second; it++) + { + if ((it->second).first==idomain) + nodes[inode]=(it->second).second; + } + } +} + +/*! + * \brief Return max global face number + */ +int ParallelTopology::getMaxGlobalFace() const +{ + int max = 0; + TGlob2LocsMap::const_iterator g_l_l = _face_glob_to_loc.begin(); + for ( ; g_l_l != _face_glob_to_loc.end(); ++g_l_l ) + if ( g_l_l->first > max ) + max = g_l_l->first; + return max; +} + +int ParallelTopology::getNodeNumber() const +{ + if (_node_glob_to_loc.empty()) return 0; + std::set <int> keys; + for (INTERP_KERNEL::HashMultiMap<int, std::pair<int,int> >::const_iterator iter= _node_glob_to_loc.begin(); iter!=_node_glob_to_loc.end(); iter++) + { + keys.insert(iter->first); + } + return keys.size(); +} + +/*! + * retrieving list of nodes in global numbers + */ +void ParallelTopology::getNodeList(int idomain, int *list) const +{ + for (int i=0; i<_nb_nodes[idomain]; i++) + list[i]=_node_loc_to_glob[idomain][i]; +} + +/*! + * retrieving list of nodes in global numbers + */ +void ParallelTopology::getCellList(int idomain, int *list) const +{ + for (int i=0; i<_nb_cells[idomain];i++) + list[i]=_loc_to_glob[idomain][i]; +} + +int ParallelTopology::getFaceNumber() const +{ + if (_face_glob_to_loc.empty()) + return 0; + std::set <int> keys; + for (INTERP_KERNEL::HashMultiMap<int, std::pair<int,int> >::const_iterator iter= _face_glob_to_loc.begin(); iter!=_face_glob_to_loc.end(); iter++) + { + keys.insert(iter->first); + } + return keys.size(); +} + +/*! + * retrieving list of faces in global numbers + */ +void ParallelTopology::getFaceList(int idomain, int *list) const +{ + for (int i=0; i<_nb_faces[idomain];i++) + list[i]=_face_loc_to_glob[idomain][i]; +} + +int ParallelTopology::convertGlobalFace(int iglobal, int idomain) +{ + typedef INTERP_KERNEL::HashMultiMap<int, std::pair<int,int> >::const_iterator MMiter; + std::pair<MMiter,MMiter> eq = _face_glob_to_loc.equal_range(iglobal); + for (MMiter it=eq.first; it != eq.second; it++) + if (it->second.first == idomain) + return it->second.second; + return -1; +} + +int ParallelTopology::convertGlobalNode(int iglobal, int idomain) +{ + typedef INTERP_KERNEL::HashMultiMap<int, std::pair<int,int> >::const_iterator MMiter; + std::pair<MMiter,MMiter> eq = _node_glob_to_loc.equal_range(iglobal); + for (MMiter it=eq.first; it != eq.second; it++) + { + if (it->second.first == idomain) + return it->second.second; + } + return -1; +} + +std::vector<MEDPARTITIONER::ConnectZone*>& ParallelTopology::getCZ() +{ + return _connect_zones; +} + +/*! + * adding a face to the topology + */ +void ParallelTopology::appendFace(int idomain, int ilocal, int iglobal) +{ + _face_loc_to_glob[idomain].push_back(iglobal); + _face_glob_to_loc.insert(std::make_pair(iglobal,std::make_pair(idomain,ilocal))); +} diff --git a/src/medtool/src/MEDPartitioner/MEDPARTITIONER_ParallelTopology.hxx b/src/medtool/src/MEDPartitioner/MEDPARTITIONER_ParallelTopology.hxx new file mode 100644 index 000000000..f18723fb2 --- /dev/null +++ b/src/medtool/src/MEDPartitioner/MEDPARTITIONER_ParallelTopology.hxx @@ -0,0 +1,194 @@ +// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// + +#ifndef __MEDPARTITIONER_PARALLELTOPOLOGY_HXX__ +#define __MEDPARTITIONER_PARALLELTOPOLOGY_HXX__ + +#include "MEDPARTITIONER.hxx" +#include "MEDPARTITIONER_Topology.hxx" + +#include "InterpKernelHashMap.hxx" + +#include <set> +#include <vector> + +namespace MEDPARTITIONER +{ + class Graph; + class MeshCollection; + class ParaDomainSelector; + + class MEDPARTITIONER_EXPORT ParallelTopology : public Topology + { + + public: + + ParallelTopology(); + ParallelTopology(const std::vector<ParaMEDMEM::MEDCouplingUMesh*>&); + ParallelTopology(const std::vector<ParaMEDMEM::MEDCouplingUMesh*>&, + const std::vector<MEDPARTITIONER::ConnectZone*>&, + std::vector<int*>&, + std::vector<int*>&, + std::vector<int*>&); + ParallelTopology(Graph* graph, Topology* oldTopology, int nbdomain, int mesh_dimension); + ~ParallelTopology(); + + void setGlobalNumerotationDefault(ParaDomainSelector* domainSelector); + + /*! converts a list of global cell numbers + * to a distributed array with local cell numbers + */ + void convertGlobalNodeList(const int*, int,int*,int*); + void convertGlobalNodeList(const int*, int,int*,int); + void convertGlobalNodeListWithTwins(const int* face_list, int nbnode, int*& local, int*& ip, int*& full_array, int& size); + + /*! converts a list of global node numbers + * to a distributed array with local cell numbers + */ + void convertGlobalCellList(const int*, int , int*, int *); + + /*! converts a list of global face numbers + * to a distributed array with local face numbers + */ + void convertGlobalFaceList(const int*, int , int*, int *); + void convertGlobalFaceList(const int*, int , int*, int); + void convertGlobalFaceListWithTwins(const int* face_list, int nbface, int*& local, int*& ip, int*& full_array,int& size); + + /*! converting node global numberings to local numberings */ + void convertToLocal2ndVersion(int* nodes, int nbnodes, int idomain); + + /*! converting node local numbering to global */ + int convertNodeToGlobal(int ip, int icell) const { return _node_loc_to_glob[ip][icell]; } + + /*! converting face local numbering to global */ + int convertFaceToGlobal(int ip, int iface) const { return _face_loc_to_glob[ip][iface]; } + + /*! converting cell global numbering to local */ + int convertCellToGlobal(int ip, int icell) const { return _loc_to_glob[ip][icell]; } + + void convertNodeToGlobal(int ip, const int* local, int n, int *global) const + { + for (int i=0; i<n; i++) + global[i]=_node_loc_to_glob[ip][local[i]]; + } + + void convertCellToGlobal(int ip, const int* local, int n, int *global) const + { + for (int i=0; i<n; i++) + global[i]=_loc_to_glob[ip][local[i]]; + } + + void convertFaceToGlobal(int ip, const int* local, int n, int *global) const + { + for (int i=0; i<n; i++) + global[i]=_face_loc_to_glob[ip][local[i]]; + } + + int nbDomain() const { return _nb_domain; } + + int nbCells() const { return _nb_total_cells; } + + int nbNodes() const { return _nb_total_nodes; } + + int nbCells( int idomain) const { return _nb_cells[idomain]; } + + /*! retrieving number of nodes */ + int getNodeNumber(int idomain) const { return _nb_nodes[idomain]; } + + int getNodeNumber() const; + + void getNodeList(int idomain, int* list) const; + + /*! retrieving cell numbers after merging in parallel mode */ + std::vector<int> & getFusedCellNumbers(int idomain) { return _cell_loc_to_glob_fuse[idomain]; } + + const std::vector<int>& getFusedCellNumbers(int idomain) const { return _cell_loc_to_glob_fuse[idomain]; } + + /*! retrieving face numbers after merging in parallel mode */ + std::vector<int> & getFusedFaceNumbers(int idomain) { return _face_loc_to_glob_fuse[idomain]; } + + const std::vector<int>& getFusedFaceNumbers(int idomain) const { return _face_loc_to_glob_fuse[idomain]; } + + /*! retrieving number of nodes */ + int getCellNumber(int idomain) const { return _nb_cells[idomain]; } + + int getCellDomainNumber(int global) const { return (_glob_to_loc.find(global)->second).first; } + + void getCellList(int idomain, int* list) const; + + int getFaceNumber(int idomain) const { return _nb_faces[idomain]; } + + int getFaceNumber() const; + + void getFaceList(int idomain, int* list) const; + + /*! converting a global cell number to a local representation (domain + local number) */ + std::pair<int,int> convertGlobalCell(int iglobal) const { return _glob_to_loc.find(iglobal)->second; } + + int convertGlobalFace(int iglobal, int idomain); + + int convertGlobalNode(int iglobal, int idomain); + + std::vector<MEDPARTITIONER::ConnectZone*>& getCZ(); + + //adding a face to the topology + void appendFace(int idomain, int ilocal, int iglobal); + + //return max global face number + int getMaxGlobalFace() const; + + private: + bool hasCellWithNodes( const MeshCollection&, int dom, const std::set<int>& nodes ); + + private: + //mapping global -> local + typedef INTERP_KERNEL::HashMultiMap<int,std::pair<int,int> > TGlob2DomainLoc; + + TGlob2DomainLoc _glob_to_loc; + TGlob2DomainLoc _node_glob_to_loc; + + //mapping local -> global + std::vector<std::vector<int> > _loc_to_glob; + std::vector<std::vector <int> > _node_loc_to_glob; + + // global numbers in parallel mode + std::vector<std::vector <int> > _cell_loc_to_glob_fuse; // glob nums after merging + std::vector<std::vector <int> > _face_loc_to_glob_fuse; // glob nums after merging + + //mapping global -> local + typedef INTERP_KERNEL::HashMultiMap<int,std::pair<int,int> > TGlob2LocsMap; + TGlob2LocsMap _face_glob_to_loc; + + //mapping local -> global + std::vector<std::vector <int> > _face_loc_to_glob; + std::vector<int> _nb_cells; + std::vector<int> _nb_nodes; + std::vector<int> _nb_faces; + int _nb_total_cells; + int _nb_total_nodes; + int _nb_total_faces; + int _nb_domain; + int _mesh_dimension; + + //links to connectzones + std::vector<MEDPARTITIONER::ConnectZone*> _connect_zones; + + }; +} +#endif diff --git a/src/medtool/src/MEDPartitioner/MEDPARTITIONER_ScotchGraph.cxx b/src/medtool/src/MEDPartitioner/MEDPARTITIONER_ScotchGraph.cxx new file mode 100644 index 000000000..1289291e1 --- /dev/null +++ b/src/medtool/src/MEDPartitioner/MEDPARTITIONER_ScotchGraph.cxx @@ -0,0 +1,117 @@ +// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// + +#include "MEDPARTITIONER_Graph.hxx" +#include "MEDPARTITIONER_ScotchGraph.hxx" +#include "MEDPARTITIONER_Utils.hxx" + +#include "MEDCouplingSkyLineArray.hxx" + +#include <cstdio> + +#ifdef MED_ENABLE_SCOTCH +extern "C" +{ +#define restrict +#include "scotch.h" +} +#endif + +using namespace MEDPARTITIONER; + +SCOTCHGraph::SCOTCHGraph():Graph() +{ +} + +SCOTCHGraph::SCOTCHGraph(ParaMEDMEM::MEDCouplingSkyLineArray* graph, int* edgeweight):Graph(graph,edgeweight) +{ +} + +SCOTCHGraph::~SCOTCHGraph() +{ +} + +void SCOTCHGraph::partGraph(int ndomain, const std::string& options_string, ParaDomainSelector* sel) +{ + if (MyGlobals::_Verbose>10) + std::cout << "proc " << MyGlobals::_Rank << " : SCOTCHGraph::partGraph" << std::endl; + + //number of graph vertices + int n = _graph->getNumberOf(); + //graph + int * xadj=const_cast<int*>(_graph->getIndex()); + int * adjncy=const_cast<int*>(_graph->getValue()); + //ndomain + int nparts=ndomain; + +#if !defined(MED_ENABLE_SCOTCH) + throw INTERP_KERNEL::Exception("SCOTCHGraph::partGraph : SCOTCH is not available. Check your products, please."); +#else + //output parameters + int* partition = new int[n+1]; + + SCOTCH_Graph scotch_graph; + SCOTCH_graphInit(&scotch_graph); + SCOTCH_graphBuild(&scotch_graph, + 0, //base first indice 0 + n, //nb of graph nodes + xadj, + 0, + _cell_weight, //graph vertices loads + 0, + xadj[n], //number of edges + adjncy, + _edge_weight); + SCOTCH_Strat scotch_strategy; + SCOTCH_stratInit(&scotch_strategy); + + //!user-defined options for the strategy + if (options_string!="") + SCOTCH_stratGraphMap(&scotch_strategy,options_string.c_str()); + + if (nparts>1) + { + if (MyGlobals::_Verbose>10) std::cout << "SCOTCHGraph::graphPart SCOTCH_graphPart" << std::endl; + SCOTCH_graphPart(&scotch_graph,nparts,&scotch_strategy,partition); + } + else //partition for 1 subdomain + { + for (int i=0; i<n+1; i++) + partition[i]=0; + } + + SCOTCH_stratExit(&scotch_strategy); + SCOTCH_graphExit(&scotch_graph); + + std::vector<int> index(n+1); + std::vector<int> value(n); + index[0]=0; + for (int i=0; i<n; i++) + { + index[i+1]=index[i]+1; + value[i]=partition[i]; + } + delete [] partition; + + //creating a skylinearray with no copy of the index and partition array + //the fifth argument true specifies that only the pointers are passed + //to the object + _partition = new ParaMEDMEM::MEDCouplingSkyLineArray(index,value); +#endif +} diff --git a/src/medtool/src/MEDPartitioner/MEDPARTITIONER_ScotchGraph.hxx b/src/medtool/src/MEDPartitioner/MEDPARTITIONER_ScotchGraph.hxx new file mode 100644 index 000000000..96f5854b0 --- /dev/null +++ b/src/medtool/src/MEDPartitioner/MEDPARTITIONER_ScotchGraph.hxx @@ -0,0 +1,40 @@ +// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// + +#ifndef __MEDPARTITIONER_SCOTCHGRAPH_HXX__ +#define __MEDPARTITIONER_SCOTCHGRAPH_HXX__ + +#include "MEDPARTITIONER.hxx" +#include "MEDPARTITIONER_Graph.hxx" + +#include <string> + +namespace MEDPARTITIONER +{ + class MEDPARTITIONER_EXPORT SCOTCHGraph : public Graph + { + public: + SCOTCHGraph(); + SCOTCHGraph(ParaMEDMEM::MEDCouplingSkyLineArray*, int* edgeweight=0); + virtual ~SCOTCHGraph(); + void partGraph(int ndomain, const std::string& options_string="", ParaDomainSelector* sel=0); + }; +} + +#endif diff --git a/src/medtool/src/MEDPartitioner/MEDPARTITIONER_Topology.hxx b/src/medtool/src/MEDPartitioner/MEDPARTITIONER_Topology.hxx new file mode 100644 index 000000000..018388c62 --- /dev/null +++ b/src/medtool/src/MEDPartitioner/MEDPARTITIONER_Topology.hxx @@ -0,0 +1,112 @@ +// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// + +#ifndef __MEDPARTITIONER_TOPOLOGY_HXX__ +#define __MEDPARTITIONER_TOPOLOGY_HXX__ + +#include "MEDPARTITIONER.hxx" + +#include <map> +#include <vector> + +namespace ParaMEDMEM +{ + class MEDCouplingUMesh; +} + +namespace MEDPARTITIONER +{ + class Graph; + class ConnectZone; + class MeshCollection; + class MEDPARTITIONER_FaceModel; + + class MEDPARTITIONER_EXPORT Topology + { + public: + Topology() { } + Topology(std::vector<ParaMEDMEM::MEDCouplingUMesh*>, std::vector<MEDPARTITIONER::ConnectZone*>) { } + virtual ~Topology() { } + + /*! converts a list of global cell numbers + * to a distributed array with local cell numbers + */ + virtual void convertGlobalNodeList(const int *list, int nb, int *local, int*ip) = 0; + virtual void convertGlobalNodeList(const int *list, int nb, int *local, int ip) = 0; + //converts a list of global node numbers + /*! to a distributed array with local cell numbers */ + virtual void convertGlobalCellList(const int*list , int nb, int *local, int*ip) = 0; + + /*! converts a list of global face numbers + * to a distributed array with local face numbers + */ + virtual void convertGlobalFaceList(const int*list , int nb, int* local, int*ip) = 0; + virtual void convertGlobalFaceList(const int*list , int nb, int* local, int ip) = 0; + virtual void convertGlobalFaceListWithTwins(const int *face_list, int nbface, int*& local, int*& ip, int*& full_array, int& size) = 0; + virtual void convertGlobalNodeListWithTwins(const int *face_list, int nbnode, int*& local, int*& ip, int*& full_array, int& size) = 0; + /*! number of doamins */ + virtual int nbDomain() const = 0; + /*! number of cells */ + virtual int nbCells() const = 0; + /*! number of nodes */ + virtual int nbNodes() const = 0; + /*! number of cells on a specific domain */ + virtual int nbCells(int idomain) const = 0; + /*! converting node global numberings to local numberings */ + virtual void convertToLocal2ndVersion(int*,int,int) = 0; + virtual int convertNodeToGlobal(int ip,int icell) const = 0; + virtual int convertFaceToGlobal(int ip,int icell) const = 0; + virtual int convertCellToGlobal(int ip,int icell) const = 0; + virtual void convertNodeToGlobal(int ip,const int *local, int n, int *global) const = 0; + virtual void convertCellToGlobal(int ip,const int *local, int n, int *global) const = 0; + virtual void convertFaceToGlobal(int ip,const int *local, int n, int *global) const = 0; + /*! retrieving number of nodes */ + virtual int getNodeNumber(int idomain) const = 0; + virtual int getNodeNumber() const = 0; + /*! retrieving list of nodes */ + virtual void getNodeList(int idomain, int *list) const = 0; + virtual std::vector<int> & getFusedCellNumbers(int idomain) = 0; + virtual const std::vector<int> & getFusedCellNumbers(int idomain) const = 0; + virtual std::vector<int> & getFusedFaceNumbers(int idomain) = 0; + virtual const std::vector<int> & getFusedFaceNumbers(int idomain) const = 0; + /*! retrieving number of nodes */ + virtual int getCellNumber(int idomain) const = 0; + /*! retrieving list of nodes */ + virtual void getCellList(int idomain, int *list) const = 0; + /*! retrieving number of faces */ + virtual int getFaceNumber(int idomain) const = 0; + virtual int getFaceNumber() const = 0; + /*! retrieving list of nodes */ + virtual void getFaceList(int idomain, int *list) const = 0; + /*! adding a face to the mapping */ + virtual void appendFace(int idomain, int ilocal, int iglobal) = 0; + /*! returns max global face number */ + virtual int getMaxGlobalFace() const = 0; + /*! converting a global cell number to a local representation */ + virtual std::pair<int,int> convertGlobalCell(int iglobal) const = 0; + /*! converting a global face number to a local representation */ + virtual int convertGlobalFace(int iglobal, int idomain) = 0; + /*! converting a global node number to a local representation */ + virtual int convertGlobalNode(int iglobal, int idomain) = 0; + /*! getting a reference to connect zones vector */ + virtual std::vector<MEDPARTITIONER::ConnectZone*>& getCZ() = 0; + }; +} + +#endif diff --git a/src/medtool/src/MEDPartitioner/MEDPARTITIONER_UserGraph.cxx b/src/medtool/src/MEDPartitioner/MEDPARTITIONER_UserGraph.cxx new file mode 100644 index 000000000..1d0808471 --- /dev/null +++ b/src/medtool/src/MEDPartitioner/MEDPARTITIONER_UserGraph.cxx @@ -0,0 +1,59 @@ +// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// + +#include "MEDPARTITIONER_Graph.hxx" +#include "MEDPARTITIONER_UserGraph.hxx" + +#include "MEDCouplingSkyLineArray.hxx" + +#include <iostream> +#include <vector> + +using namespace MEDPARTITIONER; + +/*! constructor that allows to specify the desired partition + * \param partition as table giving the domain number for each cell + * (domain numbers range from 0 to ndomain-1 + * \param n number of cells in the mesh + */ +UserGraph::UserGraph(ParaMEDMEM::MEDCouplingSkyLineArray *array, const int *partition, int n):Graph(array,0) +{ + + std::vector<int> index(n+1),value(n); + + index[0]=0; + for (int i=0; i<n; i++) + { + index[i+1]=index[i]+1; + value[i]=partition[i]; + } + + _partition = new ParaMEDMEM::MEDCouplingSkyLineArray(index,value); + +} + +UserGraph::~UserGraph() +{ +} + +void UserGraph::partGraph(int ndomain, const std::string& options, ParaDomainSelector* sel) +{ + std::cerr << "MEDPARTITIONER::UserGraph::partGraph() should not have to be used" << std::endl; +} + diff --git a/src/medtool/src/MEDPartitioner/MEDPARTITIONER_UserGraph.hxx b/src/medtool/src/MEDPartitioner/MEDPARTITIONER_UserGraph.hxx new file mode 100644 index 000000000..d6c5f6b5b --- /dev/null +++ b/src/medtool/src/MEDPartitioner/MEDPARTITIONER_UserGraph.hxx @@ -0,0 +1,38 @@ +// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// + +#ifndef __MEDPARTITIONER_USERGRAPH_HXX__ +#define __MEDPARTITIONER_USERGRAPH_HXX__ + +#include "MEDPARTITIONER.hxx" +#include "MEDPARTITIONER_Graph.hxx" + +#include <string> + +namespace MEDPARTITIONER +{ + class MEDPARTITIONER_EXPORT UserGraph : public Graph + { + public: + UserGraph(ParaMEDMEM::MEDCouplingSkyLineArray*, const int*, int); + virtual ~UserGraph(); + void partGraph(int, const std::string& options=std::string(""), ParaDomainSelector *sel=0); + }; +} +#endif diff --git a/src/medtool/src/MEDPartitioner/MEDPARTITIONER_Utils.cxx b/src/medtool/src/MEDPartitioner/MEDPARTITIONER_Utils.cxx new file mode 100644 index 000000000..861da009d --- /dev/null +++ b/src/medtool/src/MEDPartitioner/MEDPARTITIONER_Utils.cxx @@ -0,0 +1,880 @@ +// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// + +#include "MEDPARTITIONER_Utils.hxx" + +#include "MEDLoader.hxx" +#include "MEDLoaderBase.hxx" +#include "MEDFileUtilities.hxx" +#include "CellModel.hxx" +#include "MEDCouplingUMesh.hxx" +#include "MEDCouplingFieldDouble.hxx" +#include "InterpKernelException.hxx" +#include "MEDCouplingAutoRefCountObjectPtr.hxx" +#include "InterpKernelAutoPtr.hxx" + +#include <fstream> +#include <iostream> +#include <iomanip> +#include <sstream> +#include <string> +#include <cstring> + +using namespace MEDPARTITIONER; + +int MEDPARTITIONER::MyGlobals::_Verbose=0; +int MEDPARTITIONER::MyGlobals::_Is0verbose=0; +int MEDPARTITIONER::MyGlobals::_Rank=-1; +int MEDPARTITIONER::MyGlobals::_World_Size=-1; +int MEDPARTITIONER::MyGlobals::_Randomize=0; +int MEDPARTITIONER::MyGlobals::_Atomize=0; +int MEDPARTITIONER::MyGlobals::_Creates_Boundary_Faces=0; +int MEDPARTITIONER::MyGlobals::_Create_Joints=0; +std::vector<std::string> MEDPARTITIONER::MyGlobals::_File_Names; +std::vector<std::string> MEDPARTITIONER::MyGlobals::_Mesh_Names; +std::vector<std::string> MEDPARTITIONER::MyGlobals::_Field_Descriptions; +std::vector<std::string> MEDPARTITIONER::MyGlobals::_General_Informations; + +std::string MEDPARTITIONER::Trim(const std::string& s,const std::string& drop) +{ + std::string r(s); + r.erase(r.find_last_not_of(drop)+1); + return r.erase(0,r.find_first_not_of(drop)); +} + +std::string MEDPARTITIONER::IntToStr(const int i) +{ + std::ostringstream oss; + oss << i; + return oss.str(); +} + +std::string MEDPARTITIONER::DoubleToStr(const double i) +{ + std::ostringstream oss; + oss << i; + return oss.str(); +} + +int MEDPARTITIONER::StrToInt(const std::string& s) +{ + int res; + std::istringstream iss(s); + iss >> res; + return res; +} + +double MEDPARTITIONER::StrToDouble(const std::string& s) +{ + double res; + std::istringstream iss(s); + iss >> res; + return res; +} + +bool MEDPARTITIONER::TestArg(const char *arg, const char *argExpected, std::string& argValue) +{ + argValue=""; + std::size_t i; + for (i=0; i<strlen(arg); i++) + { + if (arg[i]=='=') + break; + if (arg[i]!=argExpected[i]) + return false; + } + for (std::size_t j=i+1; j<strlen(arg); j++) + argValue+=arg[j]; + return true; +} + +std::vector<int> MEDPARTITIONER::CreateRandomSize(const int size) +{ + std::vector<int> res(size); + for (int i=0; i<size; i++) + res[i]=i; + //cvw TODO or not? srand( (unsigned)time( NULL ) ); + srand( MyGlobals::_Randomize ); + for (int i=0; i<size; i++) + { + int ii=rand()%size; + int tmp=res[ii]; + res[ii]=res[i]; + res[i]=tmp; + } + return res; +} + +/*! + * randomize a xadj and adjncy, renumbering vertices belong rand. Works only on one processor!!!! + */ +void MEDPARTITIONER::RandomizeAdj(int* xadj, int* adjncy, std::vector<int>& ran, std::vector<int>& vx, std::vector<int>& va) +{ + if (MyGlobals::_World_Size>1) + { + std::cerr << "MEDPARTITIONER::RandomizeAdj only works on one proc!" << std::endl; + return; + } + int size=ran.size(); + std::vector<int> invran(size); + for (int i=0; i<size; i++) + invran[ran[i]]=i; + vx.resize(size+1); + int lga=xadj[size]; + va.resize(lga); + int jj=0; + vx[0]=0; + for (int i=0; i<size; i++) + { + int ir=ran[i]; + int ii=xadj[ir]; + int lgj=xadj[ir+1]-ii; + for (int j=0; j<lgj; j++) + { + va[jj]=invran[adjncy[ii]]; + jj=jj+1; + ii=ii+1; + } + vx[i+1]=jj; + } +} + +void MEDPARTITIONER::TestRandomize() +{ + //int xadj[6]={0,2,5,9,12,13}; //for first debug only + //int adjncy[13]={1,4,0,2,4,1,3,4,2,4,4,3,4}; + int xadj[6]={0,2,5,9,12,13}; + int adjncy[13]={0,0,1,1,1,2,2,2,2,3,3,3,4}; + int size=5; + std::vector<int> r=CreateRandomSize(size); + std::vector<int> vx,va; + RandomizeAdj(&xadj[0],&adjncy[0],r,vx,va); +} + +std::string MEDPARTITIONER::ReprVectorOfString(const std::vector<std::string>& vec) +{ + if (vec.size()==0) + return std::string(" NONE\n"); + std::ostringstream oss; + for (std::vector<std::string>::const_iterator i=vec.begin(); i!=vec.end(); ++i) + oss << " -> '" << *i << "'" << std::endl; + return oss.str(); +} + +std::string MEDPARTITIONER::ReprVectorOfString(const std::vector<std::string>& vec, const std::string separator) +{ + if (vec.size()==0) + return std::string(" NONE\n"); + std::ostringstream oss; + for (std::vector<std::string>::const_iterator i=vec.begin(); i!=vec.end(); ++i) + oss << separator << *i; + return oss.str(); +} + +std::string MEDPARTITIONER::ReprMapOfStringInt(const std::map<std::string,int>& mymap) +{ + if (mymap.size()==0) + return std::string(" NONE\n"); + std::ostringstream oss; + for (std::map<std::string,int>::const_iterator i=mymap.begin(); i!=mymap.end(); ++i) + oss << " -> [" << (*i).first << "]=" << (*i).second << std::endl; + return oss.str(); +} + +std::string MEDPARTITIONER::ReprMapOfStringVectorOfString(const std::map< std::string,std::vector<std::string> >& mymap) +{ + if (mymap.size()==0) + return std::string(" NONE\n"); + std::ostringstream oss; + for (std::map< std::string,std::vector<std::string> >::const_iterator i=mymap.begin(); i!=mymap.end(); ++i) + oss << " -> [" << (*i).first << "]=" << std::endl << ReprVectorOfString((*i).second) << std::endl; + return oss.str(); +} + +std::string MEDPARTITIONER::ReprFieldDescriptions(const std::vector<std::string>& vec, const std::string separator) +{ + if (vec.size()==0) + return std::string(" NONE\n"); + std::ostringstream oss; + for (std::vector<std::string>::const_iterator i=vec.begin(); i!=vec.end(); ++i) + { + oss << " ->"; + oss << ReprVectorOfString(DeserializeToVectorOfString(*i), separator) << std::endl; + } + return oss.str(); +} + +/*! + * a string "hello" gives a string " 5/hello/" + * serialized_FromVectorOfString_string+SerializeFromString("toto") is + * equivalent to vector<string>.push_back("toto") on serialized_FromVectorOfString_string + */ +std::string MEDPARTITIONER::SerializeFromString(const std::string& s) +{ + std::ostringstream oss; + oss << std::setw(5) << s.size() << "/" << s << "/"; + return oss.str(); +} + +/*! + * a vector of string gives a string + */ +std::string MEDPARTITIONER::SerializeFromVectorOfString(const std::vector<std::string>& vec) +{ + std::ostringstream oss; + for (std::vector<std::string>::const_iterator i=vec.begin(); i!=vec.end(); ++i) + oss<< std::setw(5) << (*i).size() << "/" << *i << "/"; + return oss.str(); +} + +/*! + * a string gives a vector of string + */ +std::vector<std::string> MEDPARTITIONER::DeserializeToVectorOfString(const std::string& str) +{ + std::vector<std::string> res; + std::size_t pos=0; + std::size_t posmax=str.size(); + if (posmax==0) + return res; //empty vector + std::size_t length; + while (pos < posmax-6) //setw(5)+" " + { + std::istringstream iss(str.substr(pos,5)); + iss >> length; + if ((str[pos+5]!='/') || (str[pos+6+length]!='/')) + { + std::cerr << "Error on string '" << str << "'" << std::endl;; + throw INTERP_KERNEL::Exception("Error on string"); + } + res.push_back(str.substr(pos+6,length)); + pos=pos+6+length+1; + } + return res; +} + +std::string MEDPARTITIONER::EraseTagSerialized(const std::string& fromStr, const std::string& tag) +{ + std::vector<std::string> vec=DeserializeToVectorOfString(fromStr); + std::vector<std::string> res; + for (std::size_t i=0; i<vec.size(); i++) + { + if (vec[i].find(tag)==std::string::npos) + res.push_back(vec[i]); + } + return MEDPARTITIONER::SerializeFromVectorOfString(res); +} + +/*! + * elements first and second of map give one elements in result vector of string + * converting formatted the int second as firsts characters ending at first slash + */ +std::vector<std::string> MEDPARTITIONER::VectorizeFromMapOfStringInt(const std::map<std::string,int>& mymap) +{ + std::vector<std::string> res; + for (std::map<std::string,int>::const_iterator i=mymap.begin(); i!=mymap.end(); ++i) + { + std::ostringstream oss; + oss << (*i).second << "/" << (*i).first; + res.push_back(oss.str()); + } + return res; +} + +/* + * if existing identicals (first,second) in vector no problem, else Exception + */ +std::map<std::string,int> MEDPARTITIONER::DevectorizeToMapOfStringInt(const std::vector<std::string>& vec) +{ + std::map<std::string,int> res; + for (std::vector<std::string>::const_iterator i=vec.begin(); i!=vec.end(); ++i) + { + std::size_t pos=0; + std::size_t posmax=(*i).size(); + std::size_t found=(*i).find('/'); //first slash + if ((found==std::string::npos) || (found<1)) + throw INTERP_KERNEL::Exception("Error aIntNumber/anyString is expected"); + int second; + std::istringstream iss((*i).substr(pos,found)); + iss >> second; + std::string first=(*i).substr(pos+found+1,posmax-found); + std::map<std::string,int>::iterator it=res.find(first); + if (it!=res.end()) + if ((*it).second!=second) + throw INTERP_KERNEL::Exception("Error not the same map value"); + res[first]=second; + } + return res; +} + +/*! + * elements first and second of map give one elements in result vector of string + * adding key map and length of second vector as first string in each serialized vector + * one serialized vector per key map + */ +std::vector<std::string> MEDPARTITIONER::VectorizeFromMapOfStringVectorOfString(const std::map< std::string,std::vector<std::string> >& mymap) +{ + std::vector<std::string> res; + for (std::map< std::string,std::vector<std::string> >::const_iterator i=mymap.begin(); i!=mymap.end(); ++i) + { + std::vector<std::string> vs=(*i).second; //a vector of string; + std::ostringstream oss; + oss << "Keymap/" << (*i).first << "/" << (*i).second.size(); + vs.insert(vs.begin(), oss.str()); + res.push_back(SerializeFromVectorOfString(vs)); + } + return res; +} + +/*! + * if existing identicals keymap in vector no problem + * duplicates in second vector + */ +std::map< std::string,std::vector<std::string> > MEDPARTITIONER::DevectorizeToMapOfStringVectorOfString(const std::vector<std::string>& vec) +{ + std::map< std::string,std::vector<std::string> > res; + for (std::vector<std::string>::const_iterator i=vec.begin(); i!=vec.end(); ++i) + { + std::vector<std::string> vs=DeserializeToVectorOfString(*i); + + std::string enTete=vs[0]; + std::size_t posmax=enTete.size(); + std::size_t foundKey=enTete.find("Keymap/"); + std::size_t foundSizeVector=enTete.find_last_of('/'); + if ((foundKey==std::string::npos) || (foundKey!=0) || ((foundKey+7)>=foundSizeVector)) + throw INTERP_KERNEL::Exception("Error Keymap/anyString/aIntNumber is expected"); + int sizeVector; + std::istringstream iss(enTete.substr(foundSizeVector+1,posmax-foundSizeVector)); + iss >> sizeVector; + std::string keymap=enTete.substr(foundKey+7,foundSizeVector-foundKey-7); + for (int ii=1; ii<=sizeVector; ii++) + res[keymap].push_back(vs[ii]); //add unconditionnaly,so merge duplicates in second vector + } + return res; +} + +/*! + * shit for unique and unique_copy for the duplicate CONSECUTIVE elements + * I do not want to sort + */ +std::vector<std::string> MEDPARTITIONER::SelectTagsInVectorOfString(const std::vector<std::string>& vec, const std::string tag) +{ + std::vector<std::string> res; + if (vec.size()==0) + return res; + for (std::vector<std::string>::const_iterator i=vec.begin(); i!=vec.end(); ++i) + { + if ((*i).find(tag)!=std::string::npos) res.push_back(*i); + } + return res; +} + +/*! + * + */ +std::vector<std::string> MEDPARTITIONER::DeleteDuplicatesInVectorOfString(const std::vector<std::string>& vec) +{ + std::vector<std::string> res; + if (vec.size()==0) return res; + //shit for unique and unique_copy for the duplicate CONSECUTIVE elements + //I do not want to sort + for (std::vector<std::string>::const_iterator i=vec.begin(); i!=vec.end(); ++i) + { + bool found=false; + for (std::vector<std::string>::const_iterator j=res.begin(); j!=res.end(); ++j) + { + if ((*i).compare(*j)==0) + { + found=true; + break; + } + } + if (!found) res.push_back(*i); + } + return res; +} + +std::map< std::string,std::vector<std::string> > MEDPARTITIONER::DeleteDuplicatesInMapOfStringVectorOfString(const std::map< std::string,std::vector<std::string> >& mymap) +{ + std::map< std::string,std::vector<std::string> > res; + for (std::map< std::string,std::vector<std::string> >::const_iterator i=mymap.begin(); i!=mymap.end(); ++i) + res[(*i).first]=DeleteDuplicatesInVectorOfString((*i).second); + return res; +} + +//void MEDPARTITIONER::sendRecvVectorOfString(const std::vector<string>& vec, const int source, const int target) +//TODO +std::string MEDPARTITIONER::Cle1ToStr(const std::string& s, const int inew) +{ + std::ostringstream oss; + oss << s << " " << inew; + return oss.str(); +} + +void MEDPARTITIONER::Cle1ToData(const std::string& key, std::string& s, int& inew) +{ + std::size_t posmax=key.size(); + std::size_t found=key.find(' '); + if ((found==std::string::npos) || (found<1)) + throw INTERP_KERNEL::Exception("Error 'aStringWithoutWhitespace aInt' is expected"); + s=key.substr(0,found); + std::istringstream iss(key.substr(found,posmax-found)); + iss >> inew; +} + +std::string MEDPARTITIONER::Cle2ToStr(const std::string& s, const int inew, const int iold) +{ + std::ostringstream oss; + oss << s << " " << inew << " " << iold; + return oss.str(); +} + +void MEDPARTITIONER::Cle2ToData(const std::string& key, std::string& s, int& inew, int& iold) +{ + std::size_t posmax=key.size(); + std::size_t found=key.find(' '); + if ((found==std::string::npos) || (found<1)) + throw INTERP_KERNEL::Exception("Error 'aStringWithoutWhitespace aInt aInt' is expected"); + s=key.substr(0,found); + std::istringstream iss(key.substr(found,posmax-found)); + iss >> inew >> iold; +} + +std::string MEDPARTITIONER::ExtractFromDescription(const std::string& description,const std::string& tag) +{ + std::size_t found=description.find(tag); + if ((found==std::string::npos) || (found<1)) + { + std::cerr << "ERROR : not found '" << tag << "' in '"<< description << "'\n"; + throw INTERP_KERNEL::Exception("Error ExtractFromDescription"); + } + std::size_t beg=found; + std::size_t end=beg; + if (description[found-1]!='/') + { + //find without '/'... and pray looking for first whitespace + //something like 'idomain=0 fileName=tmp.med meshName=...' + end=description.size(); + beg+=tag.length(); + std::string res=description.substr(beg,end-beg); + found=res.find(' '); + if (found==std::string::npos) + found=res.length(); + res=res.substr(0,found); + return res; + } + std::size_t lg=StrToInt(description.substr(found-6,found)); + beg+=tag.length(); + return description.substr(beg,lg-tag.length()); +} + +void MEDPARTITIONER::FieldDescriptionToData(const std::string& description, + int& idomain, std::string& fileName, std::string& meshName, std::string& fieldName, int& typeField, int& DT, int& IT) +{ + idomain=StrToInt(ExtractFromDescription(description,"idomain=")); + fileName=ExtractFromDescription(description,"fileName="); + meshName=ExtractFromDescription(description,"meshName="); + fieldName=ExtractFromDescription(description,"fieldName="); + typeField=StrToInt(ExtractFromDescription(description,"typeField=")); + DT=StrToInt(ExtractFromDescription(description,"DT=")); + IT=StrToInt(ExtractFromDescription(description,"IT=")); +} + +void MEDPARTITIONER::FieldShortDescriptionToData(const std::string& description, + std::string& fieldName, int& typeField, int& entity, int& DT, int& IT) +{ + fieldName=ExtractFromDescription(description,"fieldName="); + typeField=StrToInt(ExtractFromDescription(description,"typeField=")); + entity=StrToInt(ExtractFromDescription(description,"entity=")); + DT=StrToInt(ExtractFromDescription(description,"DT=")); + IT=StrToInt(ExtractFromDescription(description,"IT=")); +} + +ParaMEDMEM::DataArrayInt *MEDPARTITIONER::CreateDataArrayIntFromVector(const std::vector<int>& v) +{ + ParaMEDMEM::DataArrayInt* p=ParaMEDMEM::DataArrayInt::New(); + p->alloc(v.size(),1); + std::copy(v.begin(),v.end(),p->getPointer()); + return p; +} + +ParaMEDMEM::DataArrayInt *MEDPARTITIONER::CreateDataArrayIntFromVector(const std::vector<int>& v,const int nbComponents) +{ + ParaMEDMEM::DataArrayInt* p=ParaMEDMEM::DataArrayInt::New(); + if (v.size()%nbComponents!=0) + throw INTERP_KERNEL::Exception("Problem size modulo nbComponents != 0"); + p->alloc(v.size()/nbComponents,nbComponents); + std::copy(v.begin(),v.end(),p->getPointer()); + return p; +} + +ParaMEDMEM::DataArrayDouble* MEDPARTITIONER::CreateDataArrayDoubleFromVector(const std::vector<double>& v) +{ + ParaMEDMEM::DataArrayDouble* p=ParaMEDMEM::DataArrayDouble::New(); + p->alloc(v.size(),1); + std::copy(v.begin(),v.end(),p->getPointer()); + return p; +} + +/*! + */ +std::vector<std::string> MEDPARTITIONER::BrowseFieldDouble(const ParaMEDMEM::MEDCouplingFieldDouble* fd) +{ + std::vector<std::string> res; + if (fd->getArray()) + { + int nb=fd->getArray()->getNumberOfComponents(); + res.push_back("nbComponents="); res.back()+=IntToStr(nb); + for (int i=0; i<nb; i++) + { + res.push_back("componentInfo"); + res.back()+=IntToStr(i)+"="+fd->getArray()->getInfoOnComponent(i); + } + } + else + { + res.push_back("nbComponents=0"); //unknown + } + return res; +} + +/*! + * quick almost human readable information on all fields in a .med file + */ +std::vector<std::string> MEDPARTITIONER::BrowseAllFields(const std::string& myfile) +{ + std::vector<std::string> res; + std::vector<std::string> meshNames=MEDLoader::GetMeshNames(myfile); + + for (std::size_t i=0; i<meshNames.size(); i++) + { + std::vector<std::string> fieldNames= + MEDLoader::GetAllFieldNamesOnMesh(myfile,meshNames[i]); + for (std::size_t j = 0; j < fieldNames.size(); j++) + { + std::vector< ParaMEDMEM::TypeOfField > typeFields= + MEDLoader::GetTypesOfField(myfile, meshNames[i], fieldNames[j]); + for (std::size_t k = 0; k < typeFields.size(); k++) + { + std::vector< std::pair< int, int > > its= + MEDLoader::GetFieldIterations(typeFields[k], myfile, meshNames[i], fieldNames[j]); + if (MyGlobals::_Is0verbose>100) + std::cout<< "fieldName " << fieldNames[j] << " typeField " << typeFields[k] << " its.size() " << its.size() << std::endl; + for (std::size_t m = 0; m < its.size(); m++) + { + std::vector<std::string> resi; + resi.push_back("fileName="); resi.back()+=myfile; + resi.push_back("meshName="); resi.back()+=meshNames[i]; + resi.push_back("fieldName="); resi.back()+=fieldNames[j]; + resi.push_back("typeField="); resi.back()+=IntToStr((int)typeFields[k]); + resi.push_back("DT="); resi.back()+=IntToStr((int)its[m].first); + resi.push_back("IT="); resi.back()+=IntToStr((int)its[m].second); + res.push_back(SerializeFromVectorOfString(resi)); + } + } + } + } + return res; +} + +std::vector<std::string> MEDPARTITIONER::GetInfosOfField(const char *fileName, const char *meshName, const int idomain) +{ + const int lggeom=10; + const med_geometry_type GEOMTYPE[lggeom]={ //MED_N_CELL_FIXED_GEO] = { + //MED_POINT1, + //MED_SEG2, + //MED_SEG3, + //MED_SEG4, + //MED_TRIA3, + //MED_QUAD4, + //MED_TRIA6, + //MED_TRIA7, + //MED_QUAD8, + //MED_QUAD9, + MED_TETRA4, + MED_PYRA5, + MED_PENTA6, + MED_HEXA8, + MED_OCTA12, + MED_TETRA10, + MED_PYRA13, + MED_PENTA15, + MED_HEXA20, + MED_HEXA27, + //MED_POLYGON, + //MED_POLYHEDRON + }; + + const char * const GEOMTYPENAME[lggeom]={ + //"MED_POINT1", + //"MED_SEG2", + //"MED_SEG3", + //"MED_SEG4", + //"MED_TRIA3", + //"MED_QUAD4", + //"MED_TRIA6", + //"MED_TRIA7", + //"MED_QUAD8", + //"MED_QUAD9", + "MED_TETRA4", + "MED_PYRA5", + "MED_PENTA6", + "MED_HEXA8", + "MED_OCTA12", + "MED_TETRA10", + "MED_PYRA13", + "MED_PENTA15", + "MED_HEXA20", + "MED_HEXA27", + //"MED_POLYGONE", + //"MED_POLYEDRE", + }; + + + const int lgentity=3; + const med_entity_type ENTITYTYPE[lgentity]={ //MED_N_ENTITY_TYPES+2]={ + //MED_UNDEF_ENTITY_TYPE, + MED_CELL, + //MED_DESCENDING_FACE, + //MED_DESCENDING_EDGE, + MED_NODE, + MED_NODE_ELEMENT, + //MED_STRUCT_ELEMENT, + //MED_UNDEF_ENTITY_TYPE + }; + + const char * const ENTITYTYPENAME[lgentity]={ //MED_N_ENTITY_TYPES+2]={ + //"MED_UNDEF_ENTITY_TYPE", + "MED_CELL", + //"MED_FACE", + //"MED_ARETE", + "MED_NODE", + "MED_NODE_ELEMENT", + //"MED_STRUCT_ELEMENT", + //"MED_UNDEF_ENTITY_TYPE" + }; + + std::vector<std::string> res; + med_idt fid=MEDfileOpen(fileName,MED_ACC_RDONLY); + med_int nbFields=MEDnField(fid); + if (MyGlobals::_Verbose>20) + std::cout << "on filename " << fileName << " nbOfField " << nbFields << std::endl; + // + med_field_type typcha; + med_int numdt=0,numo=0; + med_float dt=0.0; + char *maa_ass=MEDLoaderBase::buildEmptyString(MED_NAME_SIZE); + char *nomcha=MEDLoaderBase::buildEmptyString(MED_NAME_SIZE); + med_bool localmesh; + // + for(int i=1; i<=nbFields; i++) + { + med_int ncomp=MEDfieldnComponent(fid,i); + INTERP_KERNEL::AutoPtr<char> comp=new char[ncomp*MED_SNAME_SIZE+1]; + INTERP_KERNEL::AutoPtr<char> unit=new char[ncomp*MED_SNAME_SIZE+1]; + INTERP_KERNEL::AutoPtr<char> dt_unit=new char[MED_LNAME_SIZE+1]; + med_int nbPdt; + MEDfieldInfo(fid,i,nomcha,maa_ass,&localmesh,&typcha,comp,unit,dt_unit,&nbPdt); + std::string curFieldName=MEDLoaderBase::buildStringFromFortran(nomcha,MED_NAME_SIZE+1); + std::string curMeshName=MEDLoaderBase::buildStringFromFortran(maa_ass,MED_NAME_SIZE+1); + for (int k=1; k<=nbPdt; k++) + { + MEDfieldComputingStepInfo(fid,nomcha,k,&numdt,&numo,&dt); + if (MyGlobals::_Verbose>20) + std::cout<< "on filename " << fileName << " field " << i << " fieldName " << curFieldName << " meshName " << curMeshName << + " typ " << typcha << " nbComponent " << ncomp << " nbPdt " << nbPdt << " noPdt " << k << + " ndt " << numdt << " nor " << numo << " dt " << dt << std::endl; + for (int ie=0; ie<lgentity; ie++) + { + for (int j=0; j<lggeom; j++) + { + int profilesize=0,nbi=0; + med_entity_type enttype=ENTITYTYPE[ie]; + //enttype=MED_NODE;enttype=MED_CELL;enttype=MED_NODE_ELEMENT; + char pflname[MED_NAME_SIZE+1]=""; + char locname[MED_NAME_SIZE+1]=""; + med_int nbofprofile=MEDfieldnProfile(fid,nomcha,numdt,numo,enttype,GEOMTYPE[j],pflname,locname); + int profileit=1; + if (enttype==MED_NODE) + { + med_geometry_type mygeomtype=MED_UNDEF_ENTITY_TYPE; + med_int nbOfVal=MEDfieldnValueWithProfile(fid,nomcha,numdt,numo,enttype,mygeomtype,profileit, + MED_COMPACT_PFLMODE,pflname,&profilesize,locname,&nbi); + if (nbOfVal>0) + { + if (MyGlobals::_Verbose>20) + std::cout << "on filename " << fileName << " entity " << enttype << " nbOfVal with " << + nbofprofile << " profile(s) for geomType (AUCUN) nbOfVal " << + nbOfVal << " profilName '" << pflname << "' profileSize " << profilesize << " nbPtGauss " << nbi << std::endl; + std::vector<std::string> resi; + resi.push_back("idomain="); resi.back()+=IntToStr(idomain); + resi.push_back("fileName="); resi.back()+=fileName; + resi.push_back("meshName="); resi.back()+=curMeshName; + resi.push_back("fieldName="); resi.back()+=curFieldName; + resi.push_back("typeField="); resi.back()+=IntToStr((int)ParaMEDMEM::ON_NODES); + resi.push_back("typeData="); resi.back()+=IntToStr((int)typcha); //6 for double? + resi.push_back("nbComponent="); resi.back()+=IntToStr((int)ncomp); + resi.push_back("DT="); resi.back()+=IntToStr((int)numdt); + resi.push_back("IT="); resi.back()+=IntToStr((int)numo); + resi.push_back("time="); resi.back()+=DoubleToStr(dt); + resi.push_back("entity="); resi.back()+=IntToStr((int)enttype); + resi.push_back("entityName="); resi.back()+=ENTITYTYPENAME[ie]; + resi.push_back("nbOfVal="); resi.back()+=IntToStr((int)nbOfVal); + resi.push_back("profilName="); resi.back()+=pflname; + resi.push_back("profileSize="); resi.back()+=IntToStr((int)profilesize); + resi.push_back("nbPtGauss="); resi.back()+=IntToStr((int)nbi); + res.push_back(SerializeFromVectorOfString(resi)); + } + break; //on nodes no need to scute all geomtype + } + else + { + med_geometry_type mygeomtype=GEOMTYPE[j]; + med_int nbOfVal=MEDfieldnValueWithProfile(fid,nomcha,numdt,numo,enttype,mygeomtype,profileit, + MED_COMPACT_PFLMODE,pflname,&profilesize,locname,&nbi); + if (nbOfVal>0) + { + if (MyGlobals::_Verbose>20) + std::cout << "on filename " << fileName << " entity " << enttype << " nbOfVal with " << + nbofprofile << " profile(s) for geomType " << + GEOMTYPE[j] << " " << GEOMTYPENAME[j] << " nbOfVal " << + nbOfVal << " profilName '" << pflname << "' profileSize " << profilesize << " nbPtGauss " << nbi << std::endl; + int typeField=-1; //unknown + if (enttype==MED_CELL) + typeField=ParaMEDMEM::ON_CELLS; + if (enttype==MED_NODE_ELEMENT) + typeField=ParaMEDMEM::ON_GAUSS_NE; + //if (enttype==??) typeField=ON_GAUSS_PT; + std::vector<std::string> resi; + resi.push_back("idomain="); resi.back()+=IntToStr(idomain); + resi.push_back("fileName="); resi.back()+=fileName; + resi.push_back("meshName="); resi.back()+=curMeshName; + resi.push_back("fieldName="); resi.back()+=curFieldName; + resi.push_back("typeField="); resi.back()+=IntToStr((int)typeField); + resi.push_back("typeData="); resi.back()+=IntToStr((int)typcha); //6 for double? + resi.push_back("nbComponent="); resi.back()+=IntToStr((int)ncomp); + resi.push_back("DT="); resi.back()+=IntToStr((int)numdt); + resi.push_back("IT="); resi.back()+=IntToStr((int)numo); + resi.push_back("time="); resi.back()+=DoubleToStr(dt); + resi.push_back("entity="); resi.back()+=IntToStr((int)enttype); + resi.push_back("entityName="); resi.back()+=ENTITYTYPENAME[ie]; + resi.push_back("geomType="); resi.back()+=IntToStr((int)GEOMTYPE[j]); + resi.push_back("geomTypeName="); resi.back()+=GEOMTYPENAME[j]; + resi.push_back("nbOfVal="); resi.back()+=IntToStr((int)nbOfVal); + resi.push_back("profilName="); resi.back()+=pflname; + resi.push_back("profileSize="); resi.back()+=IntToStr((int)profilesize); + resi.push_back("nbPtGauss="); resi.back()+=IntToStr((int)nbi); + if (typeField==(-1)) + { + std::cout << "WARNING : unknown typeField for entity type " << enttype << std::endl << + SerializeFromVectorOfString(resi) << std::endl; + continue; //do not register push_back + } + res.push_back(SerializeFromVectorOfString(resi)); + } + } + } + } + } + } + delete [] maa_ass; + delete [] nomcha; + MEDfileClose(fid); + if (MyGlobals::_Verbose>10) + std::cout << "detected fields:\n" << ReprVectorOfString(res) << std::endl; + return res; +} + +/*! + * quick almost human readable information on all fields on a mesh in a .med file + */ +std::vector<std::string> MEDPARTITIONER::BrowseAllFieldsOnMesh(const std::string& myfile, const std::string& mymesh, const int idomain) +{ + std::vector<std::string> res=GetInfosOfField(myfile.c_str(),mymesh.c_str(),idomain); + return res; +} + +/*! + * create empty MEDCouplingUMesh* dim 3 + */ +ParaMEDMEM::MEDCouplingUMesh* MEDPARTITIONER::CreateEmptyMEDCouplingUMesh() +{ + ParaMEDMEM::MEDCouplingUMesh* umesh=ParaMEDMEM::MEDCouplingUMesh::New(); + umesh->setMeshDimension(3); + umesh->allocateCells(0); + umesh->finishInsertingCells(); + ParaMEDMEM::DataArrayDouble *myCoords=ParaMEDMEM::DataArrayDouble::New(); + myCoords->alloc(0,3); + umesh->setCoords(myCoords); + umesh->setName("EMPTY"); + myCoords->decrRef(); + umesh->checkCoherency(); + return umesh; +} + +namespace MEDPARTITIONER +{ + BBTreeOfDim::BBTreeOfDim( int dim, + const double* bbs, + int* elems, + int level, + int nbelems, + double epsilon) + { + switch ( dim ) + { + case 3: + _tree=new BBTree<3> (bbs,elems,level,nbelems,epsilon); + _PgetElementsAroundPoint = & BBTreeOfDim::_getElementsAroundPoint< 3 >; + _PgetIntersectingElems = & BBTreeOfDim::_getIntersectingElems< 3 >; + break; + case 2: + _tree=new BBTree<2> (bbs,elems,level,nbelems,epsilon); + _PgetElementsAroundPoint = & BBTreeOfDim::_getElementsAroundPoint< 2 >; + _PgetIntersectingElems = & BBTreeOfDim::_getIntersectingElems< 2 >; + break; + case 1: + _tree=new BBTree<1> (bbs,elems,level,nbelems,epsilon); + _PgetElementsAroundPoint = & BBTreeOfDim::_getElementsAroundPoint< 1 >; + _PgetIntersectingElems = & BBTreeOfDim::_getIntersectingElems< 1 >; + break; + default: + _tree=0; + throw INTERP_KERNEL::Exception("BBTreeOfDim(): wrong space dimension"); + } + } + + BBTreeOfDim::~BBTreeOfDim() + { + delete (BBTree<3>*)_tree; + } + + void BBTreeOfDim::getElementsAroundPoint( const double* coordsPtr, + std::vector<int>& elems ) const + { + BBTreeOfDim* me = (BBTreeOfDim*) this; + (me->*_PgetElementsAroundPoint) ( coordsPtr, elems ); + } + void BBTreeOfDim::getIntersectingElems(const double* bb, + std::vector<int>& elems) const + { + BBTreeOfDim* me = (BBTreeOfDim*) this; + (me->*_PgetIntersectingElems) ( bb, elems ); + } +} diff --git a/src/medtool/src/MEDPartitioner/MEDPARTITIONER_Utils.hxx b/src/medtool/src/MEDPartitioner/MEDPARTITIONER_Utils.hxx new file mode 100644 index 000000000..64fc0c2b9 --- /dev/null +++ b/src/medtool/src/MEDPartitioner/MEDPARTITIONER_Utils.hxx @@ -0,0 +1,178 @@ +// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// + +#ifndef __MEDPARTITIONER_UTILS_HXX__ +#define __MEDPARTITIONER_UTILS_HXX__ + +#include "MEDPARTITIONER.hxx" + +#include "MEDCouplingUMesh.hxx" +#include "BBTree.txx" + +#include <string> +#include <vector> +#include <map> + +//# define LOCALIZED(message) #message , __FILE__ , __FUNCTION__ , __LINE__ + +namespace MEDPARTITIONER +{ + MEDPARTITIONER_EXPORT std::string Trim(const std::string& s,const std::string& drop); + MEDPARTITIONER_EXPORT std::string IntToStr(const int i); + MEDPARTITIONER_EXPORT std::string DoubleToStr(const double i); + MEDPARTITIONER_EXPORT int StrToInt(const std::string& s); + MEDPARTITIONER_EXPORT double StrToDouble(const std::string& s); + MEDPARTITIONER_EXPORT bool TestArg(const char *arg, const char *argExpected, std::string& argValue); + MEDPARTITIONER_EXPORT std::vector<int> CreateRandomSize(const int size); + MEDPARTITIONER_EXPORT void RandomizeAdj(int* xadj, int* adjncy, std::vector<int>& ran, std::vector<int>& vx, std::vector<int>& va); + MEDPARTITIONER_EXPORT void TestRandomize(); + + MEDPARTITIONER_EXPORT std::string ReprVectorOfString(const std::vector<std::string>& vec); + MEDPARTITIONER_EXPORT std::string ReprVectorOfString(const std::vector<std::string>& vec, const std::string separator); + MEDPARTITIONER_EXPORT std::string ReprMapOfStringInt(const std::map<std::string,int>& mymap); + MEDPARTITIONER_EXPORT std::string ReprMapOfStringVectorOfString(const std::map< std::string,std::vector<std::string> >& mymap); + MEDPARTITIONER_EXPORT std::string ReprFieldDescriptions(const std::vector<std::string>& vec,const std::string separator); + + MEDPARTITIONER_EXPORT std::string SerializeFromString(const std::string& s); + MEDPARTITIONER_EXPORT std::string SerializeFromVectorOfString(const std::vector<std::string>& vec); + MEDPARTITIONER_EXPORT std::vector<std::string> DeserializeToVectorOfString(const std::string& str); + MEDPARTITIONER_EXPORT std::string EraseTagSerialized(const std::string& fromStr, const std::string& tag); + + MEDPARTITIONER_EXPORT std::vector<std::string> VectorizeFromMapOfStringInt(const std::map<std::string,int>& mymap); + MEDPARTITIONER_EXPORT std::map<std::string,int> DevectorizeToMapOfStringInt(const std::vector<std::string>& vec); + + MEDPARTITIONER_EXPORT std::vector<std::string> VectorizeFromMapOfStringVectorOfString(const std::map< std::string,std::vector<std::string> >& mymap); + MEDPARTITIONER_EXPORT std::map< std::string,std::vector<std::string> > DevectorizeToMapOfStringVectorOfString(const std::vector<std::string>& vec); + + MEDPARTITIONER_EXPORT std::vector<std::string> SelectTagsInVectorOfString(const std::vector<std::string>& vec, const std::string tag); + MEDPARTITIONER_EXPORT std::vector<std::string> DeleteDuplicatesInVectorOfString(const std::vector<std::string>& vec); + MEDPARTITIONER_EXPORT std::map< std::string,std::vector<std::string> > DeleteDuplicatesInMapOfStringVectorOfString(const std::map< std::string,std::vector<std::string> >& mymap); + + MEDPARTITIONER_EXPORT std::string Cle1ToStr(const std::string& s, const int inew); + MEDPARTITIONER_EXPORT void Cle1ToData(const std::string& cle, std::string& s, int& inew); + + MEDPARTITIONER_EXPORT std::string Cle2ToStr(const std::string& s,const int inew,const int iold); + MEDPARTITIONER_EXPORT void Cle2ToData(const std::string& cle, std::string& s, int& inew, int& iold); + + MEDPARTITIONER_EXPORT std::string ExtractFromDescription(const std::string& description,const std::string& tag); + MEDPARTITIONER_EXPORT void FieldDescriptionToData(const std::string& description, + int& idomain, std::string& fileName, std::string& meshName, std::string& fieldName, + int& typeField, int& DT, int& IT); + MEDPARTITIONER_EXPORT void FieldShortDescriptionToData(const std::string& description, + std::string& fieldName, int& typeField, int& entity, int& DT, int& IT); + + ParaMEDMEM::DataArrayInt *CreateDataArrayIntFromVector(const std::vector<int>& v); + ParaMEDMEM::DataArrayInt *CreateDataArrayIntFromVector(const std::vector<int>& v, const int nbComponents); + ParaMEDMEM::DataArrayDouble *CreateDataArrayDoubleFromVector(const std::vector<double>& v); + + ParaMEDMEM::MEDCouplingUMesh *CreateEmptyMEDCouplingUMesh(); + + std::vector<std::string> BrowseFieldDouble(const ParaMEDMEM::MEDCouplingFieldDouble* fd); + std::vector<std::string> BrowseAllFields(const std::string& myfile); + std::vector<std::string> BrowseAllFieldsOnMesh(const std::string& myfile, const std::string& mymesh, const int idomain); + std::vector<std::string> GetInfosOfField(const char *fileName, const char *meshName, const int idomain ); + +#ifdef HAVE_MPI + //not adviced, interblocking, use sendAndReceive + //void SendVectorOfString(const std::vector<std::string>& vec, const int target); + //std::vector<std::string> RecvVectorOfString(const int source); + //TODO void sendRecvVectorOfString(const std::vector<std::string>& vec, const int source, const int target); + MEDPARTITIONER_EXPORT std::vector<std::string> SendAndReceiveVectorOfString(const std::vector<std::string>& vec, const int source, const int target); + MEDPARTITIONER_EXPORT std::vector<std::string> AllgathervVectorOfString(const std::vector<std::string>& vec); + + void SendDoubleVec(const std::vector<double>& vec, const int target); + std::vector<double> *RecvDoubleVec(const int source); + void RecvDoubleVec(std::vector<double>& vec, const int source); + + void SendIntVec(const std::vector<int>& vec, const int target); + std::vector<int>* RecvIntVec(int source); + void RecvIntVec(std::vector<int>& vec, const int source); + + void SendDataArrayInt(const ParaMEDMEM::DataArrayInt* da, const int target); + ParaMEDMEM::DataArrayInt *RecvDataArrayInt(const int source); + void SendDataArrayDouble(const ParaMEDMEM::DataArrayDouble* da, const int target); + ParaMEDMEM::DataArrayDouble *RecvDataArrayDouble(const int source); + + void TestVectorOfStringMpi(); + void TestMapOfStringIntMpi(); + void TestMapOfStringVectorOfStringMpi(); + void TestDataArrayMpi(); + void TestPersistantMpi0To1(int taille, int nb); + void TestPersistantMpiRing(int taille, int nb); + void TestPersistantMpiRingOnCommSplit(int taille, int nb); +#endif + + class MEDPARTITIONER_EXPORT MyGlobals + { + public : + static int _Verbose; //0 to 1000 over 200 is debug + static int _Rank; + static int _World_Size; + static int _Randomize; + static int _Atomize; + static int _Creates_Boundary_Faces; + static int _Create_Joints; + static int _Is0verbose; //trace cout if rank 0 and verbose + static std::vector<std::string> _File_Names; //on [iold] + static std::vector<std::string> _Mesh_Names; //on [iold] + static std::vector<std::string> _Field_Descriptions; + /*! used for descriptions of components of fields for example...*/ + static std::vector<std::string> _General_Informations; + }; + + + + /*! + * \brief Class encapsulating BBTree of dimension given at construction and + * providing all features of BBTree + */ + class BBTreeOfDim + { + void * _tree; + void (BBTreeOfDim::*_PgetElementsAroundPoint)( const double* coordsPtr, + std::vector<int>& elems ) const; + void (BBTreeOfDim::*_PgetIntersectingElems)( const double* bb, + std::vector<int>& elems ) const; + + template< int dim> + void _getElementsAroundPoint( const double* coordsPtr, + std::vector<int>& elems ) const + { + ((BBTree<dim,int>*)_tree)->getElementsAroundPoint( coordsPtr, elems ); + } + template< int dim> + void _getIntersectingElems(const double* bb, + std::vector<int>& elems) const + { + ((BBTree<dim,int>*)_tree)->getIntersectingElems( bb, elems ); + } + public: + + BBTreeOfDim( int dim, + const double* bbs, + int* elems, + int level, + int nbelems, + double epsilon=1e-12); + ~BBTreeOfDim(); + void getElementsAroundPoint(const double* coordsPtr, std::vector<int>& elems ) const; + void getIntersectingElems (const double* bb, std::vector<int>& elems) const; + }; +} +#endif diff --git a/src/medtool/src/MEDPartitioner/MEDPARTITIONER_UtilsPara.cxx b/src/medtool/src/MEDPartitioner/MEDPARTITIONER_UtilsPara.cxx new file mode 100644 index 000000000..12b5d6cf5 --- /dev/null +++ b/src/medtool/src/MEDPartitioner/MEDPARTITIONER_UtilsPara.cxx @@ -0,0 +1,732 @@ +// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// + +#include "MEDPARTITIONER_Utils.hxx" + +#include "MEDLoader.hxx" +#include "MEDLoaderBase.hxx" +#include "MEDFileUtilities.hxx" +#include "CellModel.hxx" +#include "MEDCouplingUMesh.hxx" +#include "MEDCouplingFieldDouble.hxx" +#include "InterpKernelException.hxx" +#include "MEDCouplingAutoRefCountObjectPtr.hxx" +#include "InterpKernelAutoPtr.hxx" + +#include <fstream> +#include <iostream> +#include <iomanip> +#include <sstream> +#include <string> + +#ifdef HAVE_MPI +#include <mpi.h> +#endif + +using namespace MEDPARTITIONER; + +/*! + * not optimized but suffisant + * return empty vector if i am not target + */ +std::vector<std::string> MEDPARTITIONER::SendAndReceiveVectorOfString(const std::vector<std::string>& vec, const int source, const int target) +{ + int rank=MyGlobals::_Rank; + + MPI_Status status; + int tag = 111001; + if (rank == source) + { + std::string str=SerializeFromVectorOfString(vec); + int size=str.length(); + MPI_Send( &size, 1, MPI_INT, target, tag, MPI_COMM_WORLD ); + MPI_Send( (void*)str.data(), str.length(), MPI_CHAR, target, tag+100, MPI_COMM_WORLD ); + } + + int recSize=0; + if (rank == target) + { + MPI_Recv(&recSize, 1, MPI_INT, source, tag, MPI_COMM_WORLD, &status); + std::string recData(recSize,'x'); + MPI_Recv((void*)recData.data(), recSize, MPI_CHAR, source, tag+100, MPI_COMM_WORLD, &status); + return DeserializeToVectorOfString(recData); //not empty one for target proc + } + std::vector<std::string> res; + return res; //empty one for other proc +} + +/*! + * strings NO need all same size!!!! + */ +std::vector<std::string> MEDPARTITIONER::AllgathervVectorOfString(const std::vector<std::string>& vec) +{ + if (MyGlobals::_World_Size==1) //nothing to do + return vec; + + int world_size=MyGlobals::_World_Size; + std::string str=SerializeFromVectorOfString(vec); + + std::vector<int> indexes(world_size); + int size=str.length(); + MPI_Allgather(&size, 1, MPI_INT, + &indexes[0], 1, MPI_INT, MPI_COMM_WORLD); + + //calcul of displacement + std::vector< int > disp(1,0); + for (int i=0; i<world_size; i++) disp.push_back( disp.back() + indexes[i] ); + + std::string recData(disp.back(),'x'); + MPI_Allgatherv((void*)str.data(), str.length(), MPI_CHAR, + (void*)recData.data(), &indexes[0], &disp[0], MPI_CHAR, + MPI_COMM_WORLD); + + //really extraordinary verbose for debug + std::vector<std::string> deserial=DeserializeToVectorOfString(recData); + if (MyGlobals::_Verbose>1000) + { + std::cout << "proc "<<MyGlobals::_Rank<<" : receive '" << recData << "'" << std::endl; + std::cout << "deserialize is : a vector of size " << deserial.size() << std::endl; + std::cout << ReprVectorOfString(deserial) << std::endl; + } + return deserial; +} + +/*! + Sends content of \a vec to processor \a target. To be used with \a RecvDoubleVec method. + \param vec vector to be sent + \param target processor id of the target +*/ +void MEDPARTITIONER::SendDoubleVec(const std::vector<double>& vec, const int target) +{ + int tag = 111002; + int size=vec.size(); + if (MyGlobals::_Verbose>1000) + std::cout << "proc " << MyGlobals::_Rank << " : --> SendDoubleVec " << size << std::endl; +#ifdef HAVE_MPI + MPI_Send(&size, 1, MPI_INT, target, tag, MPI_COMM_WORLD); + MPI_Send(const_cast<double*>(&vec[0]), size, MPI_DOUBLE, target, tag+100, MPI_COMM_WORLD); +#endif +} + +/*! Receives messages from proc \a source to fill vector<int> vec. + To be used with \a SendDoubleVec method. + + \param vec vector that is filled + \param source processor id of the incoming messages +*/ +std::vector<double>* MEDPARTITIONER::RecvDoubleVec(const int source) +{ + int tag = 111002; + int size; +#ifdef HAVE_MPI + MPI_Status status; + MPI_Recv(&size, 1, MPI_INT, source, tag, MPI_COMM_WORLD, &status); + if (MyGlobals::_Verbose>1000) + std::cout << "proc " << MyGlobals::_Rank << " : <-- RecvDoubleVec " << size << std::endl; + std::vector<double>* vec=new std::vector<double>; + vec->resize(size); + MPI_Recv(&vec[0], size, MPI_DOUBLE, source, tag+100, MPI_COMM_WORLD, &status); +#endif + return vec; +} + +void MEDPARTITIONER::RecvDoubleVec(std::vector<double>& vec, const int source) +{ + int tag = 111002; + int size; +#ifdef HAVE_MPI + MPI_Status status; + MPI_Recv(&size, 1, MPI_INT, source, tag, MPI_COMM_WORLD, &status); + if (MyGlobals::_Verbose>1000) + std::cout<< "proc " << MyGlobals::_Rank << " : <-- RecvDoubleVec " << size << std::endl;; + vec.resize(size); + MPI_Recv(&vec[0], size, MPI_DOUBLE, source, tag+100, MPI_COMM_WORLD, &status); +#endif +} +/*! + Sends content of \a vec to processor \a target. To be used with \a RecvIntVec method. + \param vec vector to be sent + \param target processor id of the target +*/ +void MEDPARTITIONER::SendIntVec(const std::vector<int>& vec, const int target) +{ + int tag = 111003; + int size=vec.size(); + if (MyGlobals::_Verbose>1000) + std::cout << "proc " << MyGlobals::_Rank << " : --> SendIntVec " << size << std::endl; +#ifdef HAVE_MPI + MPI_Send(&size, 1, MPI_INT, target, tag, MPI_COMM_WORLD); + MPI_Send(const_cast<int*>(&vec[0]), size,MPI_INT, target, tag+100, MPI_COMM_WORLD); +#endif +} + +/*! Receives messages from proc \a source to fill vector<int> vec. + To be used with \a SendIntVec method. + \param vec vector that is filled + \param source processor id of the incoming messages +*/ +std::vector<int> *MEDPARTITIONER::RecvIntVec(const int source) +{ + int tag = 111003; + int size; +#ifdef HAVE_MPI + MPI_Status status; + MPI_Recv(&size, 1, MPI_INT, source, tag, MPI_COMM_WORLD, &status); + if (MyGlobals::_Verbose>1000) + std::cout << "proc " << MyGlobals::_Rank << " : <-- RecvIntVec " << size << std::endl; + std::vector<int> *vec=new std::vector<int>; + vec->resize(size); + MPI_Recv(&vec[0], size, MPI_INT, source, tag+100, MPI_COMM_WORLD, &status); +#endif + return vec; +} + +void MEDPARTITIONER::RecvIntVec(std::vector<int>& vec, const int source) +{ + int tag = 111003; + int size; +#ifdef HAVE_MPI + MPI_Status status; + MPI_Recv(&size, 1, MPI_INT, source, tag, MPI_COMM_WORLD, &status); + if (MyGlobals::_Verbose>1000) + std::cout << "proc " << MyGlobals::_Rank << " : <-- RecvIntVec " << size << std::endl; + vec.resize(size); + MPI_Recv(&vec[0], size, MPI_INT, source, tag+100, MPI_COMM_WORLD,&status); +#endif +} + +/*! + Sends content of \a dataArrayInt to processor \a target. + To be used with \a RecvDataArrayInt method. + \param da dataArray to be sent + \param target processor id of the target +*/ +void MEDPARTITIONER::SendDataArrayInt(const ParaMEDMEM::DataArrayInt *da, const int target) +{ + if (da==0) + throw INTERP_KERNEL::Exception("Problem send DataArrayInt* NULL"); + int tag = 111004; + int size[3]; + size[0]=da->getNbOfElems(); + size[1]=da->getNumberOfTuples(); + size[2]=da->getNumberOfComponents(); + if (MyGlobals::_Verbose>1000) + std::cout << "proc " << MyGlobals::_Rank << " : --> SendDataArrayInt " << size[0] << std::endl; +#ifdef HAVE_MPI + MPI_Send(&size, 3, MPI_INT, target, tag, MPI_COMM_WORLD); + const int *p=da->getConstPointer(); + MPI_Send(const_cast<int*>(&p[0]), size[0] ,MPI_INT, target, tag+100, MPI_COMM_WORLD); +#endif +} + +/*! Receives messages from proc \a source to fill dataArrayInt da. + To be used with \a SendIntVec method. + \param da dataArrayInt that is filled + \param source processor id of the incoming messages +*/ +ParaMEDMEM::DataArrayInt *MEDPARTITIONER::RecvDataArrayInt(const int source) +{ + int tag = 111004; + int size[3]; +#ifdef HAVE_MPI + MPI_Status status; + MPI_Recv(size, 3, MPI_INT, source, tag, MPI_COMM_WORLD, &status); + if (MyGlobals::_Verbose>1000) + std::cout << "proc " << MyGlobals::_Rank << " : <-- RecvDataArrayInt " << size[0] << std::endl; + if (size[0]!=(size[1]*size[2])) + throw INTERP_KERNEL::Exception("Problem in RecvDataArrayInt incoherent sizes"); + ParaMEDMEM::DataArrayInt* da=ParaMEDMEM::DataArrayInt::New(); + da->alloc(size[1],size[2]); + int *p=da->getPointer(); + MPI_Recv(const_cast<int*>(&p[0]), size[0], MPI_INT, source, tag+100, MPI_COMM_WORLD, &status); +#endif + return da; +} + +/*! + Sends content of \a dataArrayInt to processor \a target. + To be used with \a RecvDataArrayDouble method. + \param da dataArray to be sent + \param target processor id of the target +*/ +void MEDPARTITIONER::SendDataArrayDouble(const ParaMEDMEM::DataArrayDouble *da, const int target) +{ + if (da==0) + throw INTERP_KERNEL::Exception("Problem send DataArrayDouble* NULL"); + int tag = 111005; + int size[3]; + size[0]=da->getNbOfElems(); + size[1]=da->getNumberOfTuples(); + size[2]=da->getNumberOfComponents(); + if (MyGlobals::_Verbose>1000) + std::cout << "proc " << MyGlobals::_Rank << " : --> SendDataArrayDouble " << size[0] << std::endl; +#ifdef HAVE_MPI + MPI_Send(&size, 3, MPI_INT, target, tag, MPI_COMM_WORLD); + const double *p=da->getConstPointer(); + MPI_Send(const_cast<double*>(&p[0]), size[0] ,MPI_DOUBLE, target, tag+100, MPI_COMM_WORLD); +#endif +} + +/*! Receives messages from proc \a source to fill dataArrayDouble da. + To be used with \a SendDoubleVec method. + \param da dataArrayDouble that is filled + \param source processor id of the incoming messages +*/ +ParaMEDMEM::DataArrayDouble* MEDPARTITIONER::RecvDataArrayDouble(const int source) +{ + int tag = 111005; + int size[3]; +#ifdef HAVE_MPI + MPI_Status status; + MPI_Recv(size, 3, MPI_INT, source, tag, MPI_COMM_WORLD, &status); + if (MyGlobals::_Verbose>1000) + std::cout << "proc " << MyGlobals::_Rank << " : <-- RecvDataArrayDouble " << size[0] << std::endl; + if (size[0]!=(size[1]*size[2])) + throw INTERP_KERNEL::Exception("Problem in RecvDataArrayDouble incoherent sizes"); + ParaMEDMEM::DataArrayDouble* da=ParaMEDMEM::DataArrayDouble::New(); + da->alloc(size[1],size[2]); + double *p=da->getPointer(); + MPI_Recv(const_cast<double*>(&p[0]), size[0], MPI_DOUBLE, source, tag+100, MPI_COMM_WORLD, &status); +#endif + return da; +} + +void MEDPARTITIONER::TestVectorOfStringMpi() +{ + int rank=MyGlobals::_Rank; + int world_size=MyGlobals::_World_Size; + std::vector<std::string> myVector; + std::ostringstream oss; + oss << "hello from " << std::setw(5) << rank << " " << std::string(rank+1,'n') << + " next is an empty one"; + myVector.push_back(oss.str()); + myVector.push_back(""); + myVector.push_back("next is an singleton"); + myVector.push_back("1"); + + if (rank==0) + { + std::string s0=SerializeFromVectorOfString(myVector); + std::vector<std::string> res=DeserializeToVectorOfString(s0); + if (res.size()!=myVector.size()) + throw INTERP_KERNEL::Exception("Problem in (de)serialise VectorOfString incoherent sizes"); + for (std::size_t i=0; i<myVector.size(); i++) + if (res[i]!=myVector[i]) + throw INTERP_KERNEL::Exception("Problem in (de)serialise VectorOfString incoherent elements"); + } + + for (int i=0; i<world_size; i++) + { + for (int j=0; j<world_size; j++) + { + std::vector<std::string> res=SendAndReceiveVectorOfString(myVector, i, j); + if ((rank==j) && MyGlobals::_Verbose>20) + std::cout << "proc " << rank << " : receive \n" << ReprVectorOfString(res) << std::endl; + if (rank==j) + { + if (res.size()!=myVector.size()) + throw INTERP_KERNEL::Exception("Problem in SendAndReceiveVectorOfString incoherent sizes"); + for (std::size_t ii=1; ii<myVector.size(); ii++) //first is different + if (res[i]!=myVector[ii]) + throw INTERP_KERNEL::Exception("Problem in SendAndReceiveVectorOfString incoherent elements"); + } + else + { + if (res.size()!=0) + throw INTERP_KERNEL::Exception("Problem in SendAndReceiveVectorOfString size have to be 0"); + } + } + } + std::vector<std::string> res=AllgathervVectorOfString(myVector); + //sometimes for test + res=AllgathervVectorOfString(myVector); + res=AllgathervVectorOfString(myVector); + if (rank==0 && MyGlobals::_Verbose>20) + std::cout << "proc " << rank << " : receive \n" << ReprVectorOfString(res) << std::endl; + if (res.size()!=myVector.size()*world_size) + throw INTERP_KERNEL::Exception("Problem in AllgathervVectorOfString incoherent sizes"); + int jj=-1; + for (int j=0; j<world_size; j++) + { + for (int i=0; i<(int)myVector.size(); i++) + { + jj=jj+1; + if (i==0) + continue; //first is different + if (res[jj]!=myVector[i]) + throw INTERP_KERNEL::Exception("Problem in AllgathervVectorOfString incoherent elements"); + } + } + if (MyGlobals::_Verbose) + std::cout << "proc " << rank << " : OK TestVectorOfStringMpi END" << std::endl; +} + +void MEDPARTITIONER::TestMapOfStringIntMpi() +{ + int rank=MyGlobals::_Rank; + std::map<std::string,int> myMap; + myMap["one"]=1; + myMap["two"]=22; //a bug + myMap["three"]=3; + myMap["two"]=2; //last speaking override + + if (rank==0) + { + std::vector<std::string> v2=VectorizeFromMapOfStringInt(myMap); + std::map<std::string,int> m3=DevectorizeToMapOfStringInt(v2); + if (ReprMapOfStringInt(m3)!=ReprMapOfStringInt(myMap)) + throw INTERP_KERNEL::Exception("Problem in (de)vectorize MapOfStringInt"); + } + + std::vector<std::string> v2=AllgathervVectorOfString(VectorizeFromMapOfStringInt(myMap)); + if (rank==0 && MyGlobals::_Verbose>20) + { + std::cout << "v2 is : a vector of size " << v2.size() << std::endl; + std::cout << ReprVectorOfString(v2) << std::endl; + std::map<std::string,int> m2=DevectorizeToMapOfStringInt(v2); + std::cout << "m2 is : a map of size " << m2.size() << std::endl; + std::cout << ReprMapOfStringInt(m2) << std::endl; + } + if (MyGlobals::_Verbose) + std::cout << "proc " << rank << " : OK TestMapOfStringIntMpi END" << std::endl; +} + +void MEDPARTITIONER::TestMapOfStringVectorOfStringMpi() +{ + int rank=MyGlobals::_Rank; + std::vector<std::string> myVector; + std::ostringstream oss; + oss << "hello from " << std::setw(5) << MyGlobals::_Rank << " " << std::string(rank+1,'n') << " next is an empty one"; + myVector.push_back(oss.str()); + myVector.push_back(""); + myVector.push_back("next is an singleton"); + myVector.push_back("1"); + + if (rank==0) + { + std::map< std::string,std::vector<std::string> > m2; + m2["first key"]=myVector; + m2["second key"]=myVector; + std::vector<std::string> v2=VectorizeFromMapOfStringVectorOfString(m2); + std::map< std::string,std::vector<std::string> > m3=DevectorizeToMapOfStringVectorOfString(v2); + if (rank==0 && MyGlobals::_Verbose>20) + std::cout << "m2 is : a MapOfStringVectorOfString of size " << m2.size() << std::endl; + std::cout << ReprMapOfStringVectorOfString(m2) << std::endl; + std::cout << "v2 is : a vector of size " << v2.size() << std::endl; + std::cout << ReprVectorOfString(v2) << std::endl; + std::cout << "m3 is : a map of size "<<m3.size() << std::endl; + std::cout << ReprMapOfStringVectorOfString(m3) << std::endl; + if (ReprMapOfStringVectorOfString(m3)!=ReprMapOfStringVectorOfString(m2)) + throw INTERP_KERNEL::Exception("Problem in (de)vectorize MapOfStringVectorOfString"); + } + + std::map< std::string,std::vector<std::string> > m4; + m4["1rst key"]=myVector; + m4["2snd key"]=myVector; + std::vector<std::string> v4=AllgathervVectorOfString(VectorizeFromMapOfStringVectorOfString(m4)); + if (rank==0 && MyGlobals::_Verbose>20) + { + std::map< std::string,std::vector<std::string> > m5=DevectorizeToMapOfStringVectorOfString(v4); + std::map< std::string,std::vector<std::string> > m6=DeleteDuplicatesInMapOfStringVectorOfString(m5); + std::cout<< "m5 is : a map of size "<<m5.size() << std::endl; + std::cout<< ReprMapOfStringVectorOfString(m5) << std::endl; + std::cout<< "m6 is : a map from m5 with deleteDuplicates of size " << m6.size() << std::endl; + std::cout<< ReprMapOfStringVectorOfString(m6) << std::endl; + } + if (MyGlobals::_Verbose) + std::cout<<"proc " << rank << " : OK TestMapOfStringVectorOfStringMpi END" << std::endl; +} + +void MEDPARTITIONER::TestDataArrayMpi() +{ + int rank=MyGlobals::_Rank; + //int + { + ParaMEDMEM::DataArrayInt* send=ParaMEDMEM::DataArrayInt::New(); + ParaMEDMEM::DataArrayInt* recv=0; + int nbOfTuples=5; + int numberOfComponents=3; + send->alloc(nbOfTuples,numberOfComponents); + std::vector<int> vals; + for (int j=0; j<nbOfTuples; j++) + for (int i=0; i<numberOfComponents; i++) vals.push_back((j+1)*10+i+1); + std::copy(vals.begin(),vals.end(),send->getPointer()); + if (rank==0) + SendDataArrayInt(send, 1); + if (rank==1) + recv=RecvDataArrayInt(0); + if (rank==1 && MyGlobals::_Verbose>20) + { + std::cout << send->repr() << std::endl; + std::cout << recv->repr() << std::endl; + } + if (rank==1) + { + if (send->repr()!=recv->repr()) + throw INTERP_KERNEL::Exception("Problem in send&recv DataArrayInt"); + } + send->decrRef(); + if (rank==1) + recv->decrRef(); + } + //double + { + ParaMEDMEM::DataArrayDouble* send=ParaMEDMEM::DataArrayDouble::New(); + ParaMEDMEM::DataArrayDouble* recv=0; + int nbOfTuples=5; + int numberOfComponents=3; + send->alloc(nbOfTuples,numberOfComponents); + std::vector<double> vals; + for (int j=0; j<nbOfTuples; j++) + for (int i=0; i<numberOfComponents; i++) vals.push_back(double(j+1)+double(i+1)/10); + std::copy(vals.begin(),vals.end(),send->getPointer()); + if (rank==0) SendDataArrayDouble(send, 1); + if (rank==1) recv=RecvDataArrayDouble(0); + if (rank==1 && MyGlobals::_Verbose>20) + { + std::cout << send->repr() << std::endl; + std::cout << recv->repr() << std::endl; + } + if (rank==1) + { + if (send->repr()!=recv->repr()) + throw INTERP_KERNEL::Exception("Problem in send&recv DataArrayDouble"); + } + send->decrRef(); + if (rank==1) recv->decrRef(); + } + + if (MyGlobals::_Verbose) + std::cout << "proc " << rank << " : OK TestDataArrayMpi END" << std::endl; +} + +void MEDPARTITIONER::TestPersistantMpi0To1(int taille, int nb) +{ + double temps_debut=MPI_Wtime(); + int rank=MyGlobals::_Rank; + std::vector<int> x, y; + int tag=111111; + MPI_Request requete0, requete1; + MPI_Status statut; + int ok=0; + std::string res; + if (rank==0) + { + x.resize(taille); + MPI_Ssend_init(&x[0], taille, MPI_INT, 1, tag, MPI_COMM_WORLD , &requete0); + for(int k=0; k<nb; k++) + { + for (int i=0; i<taille; ++i) x[i]=k; + //Envoi d’un gros message --> cela peut prendre du temps + MPI_Start(&requete0); + //Traitement sequentiel independant de "x" + //... + MPI_Wait(&requete0, &statut); + //Traitement sequentiel impliquant une modification de "x" en memoire + //x=... + } + MPI_Request_free(&requete0); + } + else if (rank == 1) + { + y.resize(taille); + MPI_Recv_init(&y[0], taille, MPI_INT, 0, tag, MPI_COMM_WORLD , &requete1); + for(int k=0; k<nb; k++) + { + //Pre-traitement sequentiel + //... + for (int i=0; i<taille; ++i) y[i]=(-1); + //Reception du gros message --> cela peut prendre du temps + MPI_Start(&requete1); + //Traitement sequentiel independant de "y" + //... + MPI_Wait(&requete1, &statut); + //Traitement sequentiel dependant de "y" + //...=f(y) + int nbb=0; + for (int i=0; i<taille; ++i) + if (y[i]==k) + nbb++; + if (nbb==taille) + ok++; + if (MyGlobals::_Verbose>9) + { + res="0K"; + if (nbb!=taille) + res="KO"; + std::cout << res << k << " "; + } + } + res="0K"; + if (ok!=nb) + res="BAD"; + if (MyGlobals::_Verbose>1) + std::cout << "result " << res << " time(sec) " << MPI_Wtime()-temps_debut << std::endl; + MPI_Request_free(&requete1); + } + //end_time=(MPI_WTIME()-start_time); +} + +void MEDPARTITIONER::TestPersistantMpiRing(int taille, int nb) +{ + double temps_debut=MPI_Wtime(); + int befo, next, rank, wsize, tagbefo, tagnext; + rank=MyGlobals::_Rank; + wsize=MyGlobals::_World_Size; + befo=rank-1; if (befo<0) befo=wsize-1; + next=rank+1; if (next>=wsize) next=0; + std::vector<int> x, y; + tagbefo=111111+befo; + tagnext=111111+rank; + MPI_Request requete0, requete1; + MPI_Status statut1, statut2; + int ok=0; + std::string res; + //cout<<"ini|"<<rank<<'|'<<befo<<'|'<<next<<' '; + { + x.resize(taille); + y.resize(taille); + MPI_Ssend_init(&x[0], taille, MPI_INT, next, tagnext, MPI_COMM_WORLD , &requete0); + MPI_Recv_init(&y[0], taille, MPI_INT, befo, tagbefo, MPI_COMM_WORLD , &requete1); + for(int k=0; k<nb; k++) + { + for (int i=0; i<taille; ++i) x[i]=k+rank; + //Envoi d’un gros message --> cela peut prendre du temps + MPI_Start(&requete0); + //Reception du gros message --> cela peut prendre du temps + for (int i=0; i<taille; ++i) y[i]=(-1); + MPI_Start(&requete1); + //Traitement sequentiel independant de "x" + //... + //Traitement sequentiel independant de "y" + //... + MPI_Wait(&requete1, &statut1); + //Traitement sequentiel dependant de "y" + //...=f(y) + int nbb=0; + for (int i=0; i<taille; ++i) + if (y[i]==k+befo) + nbb++; + if (nbb==taille) + ok++; + if (MyGlobals::_Verbose>9) + { + res="0K"+IntToStr(rank); + if (nbb!=taille) + res="KO"+IntToStr(rank); + std::cout << res << k << " "; + } + MPI_Wait(&requete0, &statut2); + //Traitement sequentiel impliquant une modification de "x" en memoire + //x=... + } + res="0K"; if (ok!=nb) res="MAUVAIS"; + temps_debut=MPI_Wtime()-temps_debut; + MPI_Request_free(&requete1); + MPI_Request_free(&requete0); + } + //end_time=(MPI_WTIME()-start_time); + if (MyGlobals::_Verbose>1) + std::cout << "result on proc " << rank << " " << res << " time(sec) " << temps_debut << std::endl; +} + +void MEDPARTITIONER::TestPersistantMpiRingOnCommSplit(int size, int nb) +{ + double temps_debut=MPI_Wtime(); + int rank=MyGlobals::_Rank; + MPI_Comm newcomm; + int color=1; + int rankMax=4; + if (rank>=rankMax) + color=MPI_UNDEFINED; + //MPI_Comm_dup (MPI_COMM_WORLD, &newcomm) ; + MPI_Comm_split(MPI_COMM_WORLD, color, rank, &newcomm); + + int befo, next, wsize, tagbefo, tagnext; + wsize=rankMax; + if (wsize>MyGlobals::_World_Size) + wsize=MyGlobals::_World_Size; + befo=rank-1; + if (befo<0) + befo=wsize-1; + next=rank+1; + if (next>=wsize) + next=0; + std::vector<int> x, y; + tagbefo=111111+befo; + tagnext=111111+rank; + MPI_Request requete0, requete1; + MPI_Status statut1, statut2; + int ok=0; + std::string res; + + if (color==1) + { + x.resize(size); + y.resize(size); + MPI_Ssend_init(&x[0], size, MPI_INT, next, tagnext, newcomm , &requete0); + MPI_Recv_init(&y[0], size, MPI_INT, befo, tagbefo, newcomm , &requete1); + for(int k=0; k<nb; k++) + { + for (int i=0; i<size; ++i) + x[i]=k+rank; + //Send of big message --> time consuming + MPI_Start(&requete0); + //Reception of big message --> time consuming + for (int i=0; i<size; ++i) + y[i]=-1; + MPI_Start(&requete1); + //Traitement sequentiel independant de "x" + //... + //Traitement sequentiel independant de "y" + //... + //cout<<"dsr|"<<rank<<' '; + MPI_Wait(&requete1, &statut1); + //Traitement sequentiel dependant de "y" + //...=f(y) + int nbb=0; + for (int i=0; i<size; ++i) + if (y[i]==k+befo) + nbb++; + if (nbb==size) + ok++; + if (MyGlobals::_Verbose>9) + { + res="0K"+IntToStr(rank); + if (nbb!=size) + res="KO"+IntToStr(rank); + std::cout << res << k << " "; + } + MPI_Wait(&requete0, &statut2); + //Traitement sequentiel impliquant une modification de "x" en memoire + //x=... + } + res="0K"; + if (ok!=nb) + res="MAUVAIS"; + temps_debut=MPI_Wtime()-temps_debut; + MPI_Request_free(&requete1); + MPI_Request_free(&requete0); + } + //MPI_Barrier(MPI_COMM_WORLD); + if (color==1) + MPI_Comm_free(&newcomm); + if (MyGlobals::_Verbose>1) + std::cout << "resultat proc " << rank <<" " << res << " time(sec) " << temps_debut << std::endl; +} diff --git a/src/medtool/src/MEDPartitioner/MEDPARTITIONER_metis.c b/src/medtool/src/MEDPartitioner/MEDPARTITIONER_metis.c new file mode 100644 index 000000000..f67c84932 --- /dev/null +++ b/src/medtool/src/MEDPartitioner/MEDPARTITIONER_metis.c @@ -0,0 +1,81 @@ +// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// + +// Creation of this C code is forced by the following. +// +// In case if Metis is a part of Parmetis V3, extern "C" {#include "metis.h"} causes +// inclusion of C++ code of MPI via parmetis.h <- mpi.h <- mpicxx.h +// that breaks compilation. To workaround this problem we create a wrapping C +// function, inclusion of whose declaration causes no problem. + +#include "MEDPARTITIONER_metis.h" + +#if defined(MED_ENABLE_METIS) & !defined(MED_ENABLE_PARMETIS) + #ifndef MED_ENABLE_METIS_V5 + #include "defs.h" + #endif // MED_ENABLE_METIS_V5 + #include "metis.h" + #ifdef MED_ENABLE_METIS_V5 + #define idxtype idx_t + #endif // MED_ENABLE_METIS_V5 +#else + typedef int idxtype; +#endif // defined(MED_ENABLE_METIS) & !defined(MED_ENABLE_PARMETIS) + +void MEDPARTITIONER_METIS_PartGraphRecursive(int *nvtxs, idxtype *xadj, idxtype *adjncy, idxtype *vwgt, + idxtype *adjwgt, int *wgtflag, int *numflag, int *nparts, + int *options, int *edgecut, idxtype *part) +{ +#if defined(MED_ENABLE_METIS) + #ifndef MED_ENABLE_METIS_V5 + METIS_PartGraphRecursive(nvtxs, xadj, adjncy, vwgt, + adjwgt, wgtflag, numflag, nparts, + options, edgecut, part); + #else + int ncon=1; + options[METIS_OPTION_NCUTS]=1; + options[METIS_OPTION_NITER]=1; + options[METIS_OPTION_UFACTOR]=1; + METIS_PartGraphRecursive(nvtxs, &ncon, xadj, adjncy, vwgt, 0 /* vsize*/, + adjwgt, nparts,/* tpwgts*/ 0,/* ubvec */ 0, + options, edgecut, part); + #endif +#endif +} + +void MEDPARTITIONER_METIS_PartGraphKway(int *nvtxs, idxtype *xadj, idxtype *adjncy, idxtype *vwgt, + idxtype *adjwgt, int *wgtflag, int *numflag, int *nparts, + int *options, int *edgecut, idxtype *part) +{ +#if defined(MED_ENABLE_METIS) + #ifndef MED_ENABLE_METIS_V5 + METIS_PartGraphKway(nvtxs, xadj, adjncy, vwgt, + adjwgt, wgtflag, numflag, nparts, + options, edgecut, part); + #else + int ncon=1; + options[METIS_OPTION_NCUTS]=1; + options[METIS_OPTION_NITER]=1; + options[METIS_OPTION_UFACTOR]=1; + METIS_PartGraphKway(nvtxs, &ncon, xadj, adjncy, vwgt, 0 /* vsize*/, + adjwgt, nparts, 0 , 0 /* ubvec */, + options, edgecut, part); + #endif +#endif +} diff --git a/src/medtool/src/MEDPartitioner/MEDPARTITIONER_metis.h b/src/medtool/src/MEDPartitioner/MEDPARTITIONER_metis.h new file mode 100644 index 000000000..eadfd7d50 --- /dev/null +++ b/src/medtool/src/MEDPartitioner/MEDPARTITIONER_metis.h @@ -0,0 +1,30 @@ +// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// + +// Creation of this C code is forced by the following. +// +// In case if Metis is a part of Parmetis V3, extern "C" {#include "metis.h"} causes +// inclusion of C++ code of MPI via parmetis.h <- mpi.h <- mpicxx.h +// that breaks compilation. To workaround this problem we create a wrapping C +// function, inclusion of whose declaration causes no problem. + + +void MEDPARTITIONER_METIS_PartGraphRecursive(int *, int *, int *, int *, int *, int *, int *, int *, int *, int *, int *); + +void MEDPARTITIONER_METIS_PartGraphKway(int *, int *, int *, int *, int *, int *, int *, int *, int *, int *, int *); diff --git a/src/medtool/src/MEDPartitioner/Test/CMakeLists.txt b/src/medtool/src/MEDPartitioner/Test/CMakeLists.txt new file mode 100644 index 000000000..25e10b994 --- /dev/null +++ b/src/medtool/src/MEDPartitioner/Test/CMakeLists.txt @@ -0,0 +1,65 @@ +# Copyright (C) 2012-2015 CEA/DEN, EDF 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, 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 +# 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_DEFINITIONS(${BOOST_DEFINITIONS} ${CPPUNIT_DEFINITIONS}) + +INCLUDE_DIRECTORIES( + ${CPPUNIT_INCLUDE_DIRS} + ${CMAKE_CURRENT_SOURCE_DIR}/.. + ${CMAKE_CURRENT_SOURCE_DIR}/../../INTERP_KERNELTest # for BasicMainTest.hxx + ) + +SET(MEDPARTITIONERTest_HEADERS_HXX + MEDPARTITIONERTest.hxx + ) + +SET(MEDPARTITIONERTest_SOURCES + MEDPARTITIONERTest.cxx + ) + +SET(MEDPARTITIONERTest_LDFLAGS medpartitionercpp ${CPPUNIT_LIBRARIES}) + +IF(SALOME_USE_MPI) + IF(SALOME_MED_PARTITIONER_PARMETIS) + SET(MEDPARTITIONERTest_SOURCES ${MEDPARTITIONERTest_SOURCES} MEDPARTITIONERTestPara.cxx) + ENDIF(SALOME_MED_PARTITIONER_PARMETIS) +ENDIF(SALOME_USE_MPI) + +ADD_LIBRARY(MEDPARTITIONERTest SHARED ${MEDPARTITIONERTest_SOURCES}) +TARGET_LINK_LIBRARIES(MEDPARTITIONERTest ${MEDPARTITIONERTest_LDFLAGS}) +INSTALL(TARGETS MEDPARTITIONERTest DESTINATION ${MEDTOOL_INSTALL_LIBS}) + +ADD_EXECUTABLE(TestMEDPARTITIONER TestMEDPARTITIONER.cxx) +TARGET_LINK_LIBRARIES(TestMEDPARTITIONER MEDPARTITIONERTest) +INSTALL(TARGETS TestMEDPARTITIONER DESTINATION ${MEDTOOL_INSTALL_BINS}) + +INSTALL(FILES ${MEDPARTITIONERTest_HEADERS_HXX} DESTINATION ${MEDTOOL_INSTALL_HEADERS}) + +#SALOME_GENERATE_TESTS_ENVIRONMENT(tests_env) +ADD_TEST(TestMEDPARTITIONER TestMEDPARTITIONER) +SET_TESTS_PROPERTIES(TestMEDPARTITIONER PROPERTIES ENVIRONMENT "${tests_env}") + +# Application tests + +SET(TEST_INSTALL_DIRECTORY ${MEDTOOL_INSTALL_SCRIPT_SCRIPTS}/test/MEDCoupling/MEDPartitioner) +INSTALL(TARGETS MEDPARTITIONERTest TestMEDPARTITIONER DESTINATION ${TEST_INSTALL_DIRECTORY}) + +INSTALL(FILES CTestTestfileInstall.cmake + DESTINATION ${TEST_INSTALL_DIRECTORY} + RENAME CTestTestfile.cmake) diff --git a/src/medtool/src/MEDPartitioner/Test/CTestTestfileInstall.cmake b/src/medtool/src/MEDPartitioner/Test/CTestTestfileInstall.cmake new file mode 100644 index 000000000..4605fa005 --- /dev/null +++ b/src/medtool/src/MEDPartitioner/Test/CTestTestfileInstall.cmake @@ -0,0 +1,21 @@ +# Copyright (C) 2015 CEA/DEN, EDF 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, 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 +# 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_TEST(TestMEDPARTITIONER TestMEDPARTITIONER) +SET_TESTS_PROPERTIES(TestMEDPARTITIONER PROPERTIES LABELS "${COMPONENT_NAME}") diff --git a/src/medtool/src/MEDPartitioner/Test/MEDPARTITIONERTest.cxx b/src/medtool/src/MEDPartitioner/Test/MEDPARTITIONERTest.cxx new file mode 100644 index 000000000..5144d40d3 --- /dev/null +++ b/src/medtool/src/MEDPartitioner/Test/MEDPARTITIONERTest.cxx @@ -0,0 +1,1506 @@ +// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// + +#include "MEDPARTITIONERTest.hxx" + +#include "MEDPARTITIONER_MeshCollection.hxx" +#include "MEDPARTITIONER_ParallelTopology.hxx" +#include "MEDPARTITIONER_ParaDomainSelector.hxx" +#include "MEDPARTITIONER_Utils.hxx" + +#include "CellModel.hxx" +#include "MEDFileMesh.hxx" +#include "MEDLoader.hxx" +#include "MEDLoaderBase.hxx" +#include "MEDCouplingUMesh.hxx" +#include "MEDCouplingExtrudedMesh.hxx" +#include "MEDCouplingFieldDouble.hxx" +#include "MEDCouplingMemArray.hxx" +#include "MEDCouplingMultiFields.hxx" + +#include <cppunit/TestAssert.h> + +#include <sstream> +#include <cmath> +#include <list> +#include <stdexcept> +#include <cstdlib> +#include <vector> + +#ifdef HAVE_MPI +#include <mpi.h> +#endif + +using namespace std; +using namespace ParaMEDMEM; +using namespace MEDPARTITIONER; + +void MEDPARTITIONERTest::setSize(int ni, int nj, int nk) +{ + this->_ni=ni; //nb of hexa9 + this->_nj=nj; + this->_nk=nk; + this->_ntot=_ni*_nj*_nk; + string ijk=IntToStr(ni)+"x"+IntToStr(nj)+"x"+IntToStr(nk); + this->_file_name="tmp_testMesh_"+ijk+".med"; + this->_file_name_with_faces="tmp_testMeshWithFaces_"+ijk+".med"; + string ij=IntToStr(ni)+"x"+IntToStr(nj); + this->_file_name2="tmp_testMesh_"+ij+".med"; + this->_mesh_name="testMesh"; +} + +void MEDPARTITIONERTest::setSmallSize() +{ + setSize(2,3,5); //nb of hexa9 +} + +void MEDPARTITIONERTest::setMedianSize() +{ + setSize(20,30,50); //nb of hexa9 +} + +void MEDPARTITIONERTest::setbigSize() +{ + setSize(200,300,500); //nb of hexa9 +} + +std::string MEDPARTITIONERTest::getPartitionerExe() const +{ + std::string execName; + if ( getenv("top_builddir")) // make distcheck + { + execName = getenv("top_builddir"); + execName += "/src/MEDPartitioner/medpartitioner"; + } + else if ( getenv("MED_ROOT_DIR") ) + { + execName=getenv("MED_ROOT_DIR"); //.../INSTALL/MED + execName+="/bin/salome/medpartitioner"; + } + else + { + CPPUNIT_FAIL("Can't find medpartitioner, neither MED_ROOT_DIR nor top_builddir is set"); + } + return execName; +} + +// ============================================================================ +/*! + * Set up the environment called at every CPPUNIT_TEST () + */ +// ============================================================================ +void MEDPARTITIONERTest::setUp() +{ + this->_verbose=0; +#if defined(HAVE_MPI) + if (MyGlobals::_Rank==-1) //do once only + { + MPI_Init(0,0); + MPI_Comm_size(MPI_COMM_WORLD, &MyGlobals::_World_Size); + MPI_Comm_rank(MPI_COMM_WORLD, &MyGlobals::_Rank); + } +#else + //sequential : no MPI + MyGlobals::_World_Size=1; + MyGlobals::_Rank=0; +#endif + + if (_verbose>10) + { +#if defined(HAVE_MPI) + cout<<"\ndefined(HAVE_MPI)"<<endl; +#else + cout<<"\nNOT defined(HAVE_MPI)"<<endl; +#endif +#if defined(MED_ENABLE_PARMETIS) + cout<<"defined(MED_ENABLE_PARMETIS)"<<endl; +#else + cout<<"NOT defined(MED_ENABLE_PARMETIS)"<<endl; +#endif +#if defined(MED_ENABLE_METIS) + cout<<"defined(MED_ENABLE_METIS)"<<endl; +#else + cout<<"NOT defined(MED_ENABLE_METIS)"<<endl; +#endif +#if defined(MED_ENABLE_SCOTCH) + cout<<"defined(MED_ENABLE_SCOTCH)"<<endl; +#else + cout<<"NOT defined(MED_ENABLE_SCOTCH)"<<endl; +#endif + } +} + +// ============================================================================ +/*! + * - delete + */ +// ============================================================================ +void MEDPARTITIONERTest::tearDown() +{ +} + +ParaMEDMEM::MEDCouplingUMesh * MEDPARTITIONERTest::buildCUBE3DMesh() +//only hexa8 +{ + vector<int> conn; + vector<double> coor; + for (int k=0; k<=_nk; k++) + for (int j=0; j<=_nj; j++) + for (int i=0; i<=_ni; i++) + { + coor.push_back(i+.1); + coor.push_back(j+.2); + coor.push_back(k+.3); + } + int ii; + for (int k=0; k<_nk; k++) + for (int j=0; j<_nj; j++) + for (int i=0; i<_ni; i++) + { + ii=i + j*(_ni+1) + k*(_ni+1)*(_nj+1); + conn.push_back(ii); + conn.push_back(ii+1); + ii=ii + _ni + 2 ; + conn.push_back(ii); + conn.push_back(ii-1); + + ii=i + j*(_ni+1) + (k+1)*(_ni+1)*(_nj+1); + conn.push_back(ii); + conn.push_back(ii+1); + ii=ii + _ni + 2 ; + conn.push_back(ii); + conn.push_back(ii-1); + } + + /* + if (_verbose) //only for debug + { + cout<< "\nnb coor " << (_ni+1)*(_nj+1)*(_nk+1)*3 << " " << coor.size() << endl; + for (int i=0; i<(int)coor.size(); i++) + cout << coor[i] << " "; + cout << endl; + cout << "\nnb conn " << (_ni)*(_nj)*(_nk)*8 << " " << conn.size() << endl; + for (int i=0; i<(int)conn.size(); i=i+8) + { + for (int j=0; j<8; j++) + cout << conn[i+j] << " "; + cout << endl; + } + cout << endl; + } + */ + + MEDCouplingUMesh *mesh=MEDCouplingUMesh::New(); + mesh->setMeshDimension(3); + int nbc=conn.size()/8; //nb of cells + int nbv=coor.size()/3; //nb of vertices + mesh->allocateCells(nbc); + for(int i=0; i<nbc; i++) + { + int onehexa[8]; + std::copy(conn.begin()+i*8,conn.begin()+(i+1)*8,onehexa); + if (false) //(_verbose) + { + for (int j=0; j<8; j++) cout<<onehexa[j]<<" "; + cout<<endl; + } + mesh->insertNextCell(INTERP_KERNEL::NORM_HEXA8,8,onehexa); + } + mesh->finishInsertingCells(); + DataArrayDouble *myCoords=DataArrayDouble::New(); + myCoords->alloc(nbv,3); + std::copy(coor.begin(),coor.end(),myCoords->getPointer()); + mesh->setCoords(myCoords); + mesh->setName(_mesh_name.c_str()); + myCoords->decrRef(); + mesh->checkCoherency(); + return mesh; +} + +ParaMEDMEM::MEDCouplingUMesh * MEDPARTITIONERTest::buildCARRE3DMesh() +//only quad4 in oblique (k=j) +{ + vector<int> conn; + vector<double> coor; + for (int j=0; j<=_nj; j++) + for (int i=0; i<=_ni; i++) + { + int k=j; + coor.push_back(i+.1); + coor.push_back(j+.2); + coor.push_back(k+.3); + } + int ii; + int k=0; + for (int j=0; j<_nj; j++) + for (int i=0; i<_ni; i++) + { + ii=i + j*(_ni+1) + k*(_ni+1)*(_nj+1); + conn.push_back(ii); + conn.push_back(ii+1); + ii=ii + _ni + 2 ; + conn.push_back(ii); + conn.push_back(ii-1); + } + + if (false) //(_verbose) + { + cout<<"\nnb coor "<<(_ni+1)*(_nj+1)*3<<" "<<coor.size()<<endl; + for (int i=0; i<(int)coor.size(); i++) + cout << coor[i] << " "; + cout<<endl; + cout<<"\nnb conn "<<(_ni)*(_nj)*4<<" "<<conn.size()<<endl; + for (int i=0; i<(int)conn.size(); i=i+4) + { + for (int j=0; j<4; j++) cout<<conn[i+j]<<" "; + cout<<endl; + } + cout<<endl; + } + + MEDCouplingUMesh *mesh=MEDCouplingUMesh::New(); + mesh->setMeshDimension(2); + int nbc=conn.size()/4; //nb of cells + int nbv=coor.size()/3; //nb of vertices + mesh->allocateCells(nbc); + for(int i=0; i<nbc; i++) + { + int onequa[4]; + std::copy(conn.begin()+i*4,conn.begin()+(i+1)*4,onequa); + if (false) //(_verbose) + { + for (int j=0; j<4; j++) cout<<onequa[j]<<" "; + cout<<endl; + } + mesh->insertNextCell(INTERP_KERNEL::NORM_QUAD4,4,onequa); + } + mesh->finishInsertingCells(); + DataArrayDouble *myCoords=DataArrayDouble::New(); + myCoords->alloc(nbv,3); + std::copy(coor.begin(),coor.end(),myCoords->getPointer()); + mesh->setCoords(myCoords); + mesh->setName(_mesh_name.c_str()); + myCoords->decrRef(); + mesh->checkCoherency(); + return mesh; +} + +ParaMEDMEM::MEDCouplingUMesh * MEDPARTITIONERTest::buildFACE3DMesh() +//only quad4 on a global face of the CUBE3D (k=0) +{ + vector<int> conn; + vector<double> coor; + for (int j=0; j<=_nj; j++) + for (int i=0; i<=_ni; i++) + { + int k=0; + coor.push_back(i+.1); + coor.push_back(j+.2); + coor.push_back(k+.3); + } + int ii; + int k=0; + for (int j=0; j<_nj; j++) + for (int i=0; i<_ni; i++) + { + ii=i + j*(_ni+1) + k*(_ni+1)*(_nj+1); + conn.push_back(ii); + conn.push_back(ii+1); + ii=ii + _ni + 2 ; + conn.push_back(ii); + conn.push_back(ii-1); + } + + if (false) //(_verbose) + { + cout<<"\nnb coor "<<(_ni+1)*(_nj+1)*3<<" "<<coor.size()<<endl; + for (int i=0; i<(int)coor.size(); i++) + cout << coor[i] << " "; + cout<<endl; + cout<<"\nnb conn "<<(_ni)*(_nj)*4<<" "<<conn.size()<<endl; + for (int i=0; i<(int)conn.size(); i=i+4) + { + for (int j=0; j<4; j++) + cout << conn[i+j] << " "; + cout << endl; + } + cout << endl; + } + + MEDCouplingUMesh *mesh=MEDCouplingUMesh::New(); + mesh->setMeshDimension(2); + int nbc=conn.size()/4; //nb of cells + int nbv=coor.size()/3; //nb of vertices + mesh->allocateCells(nbc); + for(int i=0; i<nbc; i++) + { + int onequa[4]; + std::copy(conn.begin()+i*4,conn.begin()+(i+1)*4,onequa); + if (false) //(_verbose) + { + for (int j=0; j<4; j++) cout<<onequa[j]<<" "; + cout<<endl; + } + mesh->insertNextCell(INTERP_KERNEL::NORM_QUAD4,4,onequa); + } + mesh->finishInsertingCells(); + DataArrayDouble *myCoords=DataArrayDouble::New(); + myCoords->alloc(nbv,3); + std::copy(coor.begin(),coor.end(),myCoords->getPointer()); + mesh->setCoords(myCoords); + mesh->setName(_mesh_name.c_str()); + myCoords->decrRef(); + mesh->checkCoherency(); + return mesh; +} + +MEDCouplingFieldDouble * MEDPARTITIONERTest::buildVecFieldOnCells(string myfileName) +{ + //int ni=2,nj=3,nk=5; //nb of hexa9 + vector<double> field; + for (int k=0; k<_nk; k++) + for (int j=0; j<_nj; j++) + for (int i=0; i<_ni; i++) + { + field.push_back(i+.1); + field.push_back(j+.2); + field.push_back(k+.3); + } + + MEDCouplingUMesh *mesh=MEDLoader::ReadUMeshFromFile(myfileName.c_str(),_mesh_name.c_str(),0); + int nbOfCells=mesh->getNumberOfCells(); + MEDCouplingFieldDouble *f1=MEDCouplingFieldDouble::New(ON_CELLS,ONE_TIME); + f1->setName("VectorFieldOnCells"); + f1->setDescription("DescriptionOfFieldOnCells"); //not saved in file? + f1->setMesh(mesh); + DataArrayDouble *myField=DataArrayDouble::New(); + myField->alloc(nbOfCells,3); + std::copy(field.begin(),field.end(),myField->getPointer()); + f1->setArray(myField); + myField->setInfoOnComponent(0,"vx"); + myField->setInfoOnComponent(1,"vy"); + myField->setInfoOnComponent(2,"vz"); + myField->decrRef(); + f1->setTime(2.,0,1); + f1->checkCoherency(); + mesh->decrRef(); + return f1; +} + +MEDCouplingFieldDouble * MEDPARTITIONERTest::buildVecFieldOnNodes() +{ + //int ni=2,nj=3,nk=5; //nb of hexa9 + vector<double> field; + for (int k=0; k<=_nk; k++) + for (int j=0; j<=_nj; j++) + for (int i=0; i<=_ni; i++) + { + field.push_back(i+.1); + field.push_back(j+.2); + field.push_back(k+.3); + } + + MEDCouplingUMesh *mesh=MEDLoader::ReadUMeshFromFile(_file_name.c_str(),_mesh_name.c_str(),0); + int nbOfNodes=mesh->getNumberOfNodes(); + MEDCouplingFieldDouble *f1=MEDCouplingFieldDouble::New(ON_NODES,ONE_TIME); + f1->setName("VectorFieldOnNodes"); + f1->setDescription("DescriptionOfFieldOnNodes"); //not saved in file? + f1->setMesh(mesh); + DataArrayDouble *myField=DataArrayDouble::New(); + myField->alloc(nbOfNodes,3); + std::copy(field.begin(),field.end(),myField->getPointer()); + f1->setArray(myField); + myField->setInfoOnComponent(0,"vx"); + myField->setInfoOnComponent(1,"vy"); + myField->setInfoOnComponent(2,"vz"); + myField->decrRef(); + f1->setTime(2.,0,1); + f1->checkCoherency(); + mesh->decrRef(); + return f1; +} + + +void MEDPARTITIONERTest::createTestMeshWithoutField() +{ + { + MEDCouplingUMesh * mesh = buildCUBE3DMesh(); + MEDLoader::WriteUMesh(_file_name.c_str(),mesh,true); + if (_verbose) cout<<endl<<_file_name<<" created"<<endl; + if (_ntot<1000000) //too long + { + MEDCouplingUMesh *mesh_rw=MEDLoader::ReadUMeshFromFile(_file_name.c_str(),mesh->getName().c_str(),0); + if (_verbose) cout<<_file_name<<" reread"<<endl; + CPPUNIT_ASSERT(mesh->isEqual(mesh_rw,1e-12)); + mesh_rw->decrRef(); + } + mesh->decrRef(); + } + + { + vector<const ParaMEDMEM::MEDCouplingUMesh*> meshes; + MEDCouplingUMesh * mesh1 = buildCUBE3DMesh(); + MEDCouplingUMesh * mesh2 = buildFACE3DMesh(); + mesh1->setName("testMesh"); + mesh2->setName("theFaces"); + mesh2->tryToShareSameCoordsPermute(*mesh1, 1e-9); + mesh2->checkCoherency(); + mesh1->checkCoherency(); + meshes.push_back(mesh1); + meshes.push_back(mesh2); + MEDLoader::WriteUMeshes(_file_name_with_faces.c_str(), meshes, true); + + ParaMEDMEM::MEDFileUMesh* mfm=ParaMEDMEM::MEDFileUMesh::New(_file_name_with_faces.c_str(), mesh1->getName().c_str()); + DataArrayInt* FacesFam=DataArrayInt::New(); + FacesFam->alloc(mfm->getSizeAtLevel(-1),1); + FacesFam->fillWithValue(-1); + DataArrayInt* CellsFam=DataArrayInt::New(); + CellsFam->alloc(mfm->getSizeAtLevel(0),1); + CellsFam->fillWithValue(1); + mfm->setFamilyFieldArr(-1,FacesFam); + mfm->setFamilyFieldArr(0,CellsFam); + map<string,int> theFamilies; + theFamilies["FAMILLE_ZERO"]=0; + theFamilies["FamilyFaces"]=-1; + theFamilies["FamilyCells"]=1; + map<string, vector<string> > theGroups; + theGroups["GroupFaces"].push_back("FamilyFaces"); + theGroups["GroupCells"].push_back("FamilyCells"); + mfm->setFamilyInfo(theFamilies); + mfm->setGroupInfo(theGroups); + mfm->write(_file_name_with_faces.c_str(),0); + FacesFam->decrRef(); + CellsFam->decrRef(); + + /*ce truc marche pas! + ParaMEDMEM::MEDFileUMesh* mfm=ParaMEDMEM::MEDFileUMesh::New(_file_name_with_faces.c_str(), mesh1->getName()); + vector<const ParaMEDMEM::MEDCouplingUMesh*> ms; + ms.push_back(mesh2); + mfm->setGroupsFromScratch(-1, ms); + mfm->write(_file_name_with_faces.c_str(),0); + */ + + if (_verbose) cout<<endl<<_file_name_with_faces<<" created"<<endl; + if (_ntot<1000000) //too long + { + MEDCouplingUMesh *mesh_rw=MEDLoader::ReadUMeshFromFile(_file_name_with_faces.c_str(),mesh1->getName().c_str(),0); + if (_verbose) cout<<_file_name_with_faces<<" reread"<<endl; + CPPUNIT_ASSERT(mesh1->isEqual(mesh_rw,1e-12)); + mesh_rw->decrRef(); + } + mesh1->decrRef(); + mesh2->decrRef(); + mfm->decrRef(); + } + + { + MEDCouplingUMesh * mesh = buildCARRE3DMesh(); + MEDLoader::WriteUMesh(_file_name2.c_str(),mesh,true); + if (_verbose) cout<<endl<<_file_name2<<" created"<<endl; + MEDCouplingUMesh *mesh_rw=MEDLoader::ReadUMeshFromFile(_file_name2.c_str(),mesh->getName().c_str(),0); + if (_verbose) cout<<_file_name2<<" reread"<<endl; + CPPUNIT_ASSERT(mesh->isEqual(mesh_rw,1e-12)); + mesh_rw->decrRef(); + mesh->decrRef(); + } +} + +/* +create a set of nbx*nby*nbz files mesh of ni*ny*nz cells +*/ +void MEDPARTITIONERTest::createHugeTestMesh(int ni, int nj, int nk, int nbx, int nby, int nbz, int nbTarget) +{ + setSize(ni,nj,nk); + _nb_target_huge=nbTarget; + MEDCouplingUMesh * mesh = buildCUBE3DMesh(); + //int nbx=1, nby=1, nbz=2; + std::vector< double > cooDep,cooFin; + mesh->getCoordinatesOfNode(0, cooDep); + mesh->getCoordinatesOfNode(mesh->getNumberOfNodes()-1, cooFin); + //cout<<endl<<cooDep[0]<<" "<<cooDep[1]<<" "<<cooDep[2]<<endl; + //cout<<cooFin[0]<<" "<<cooFin[1]<<" "<<cooFin[2]<<endl; + + string tagXml="\ +<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n \ +<root>\n \ + <version maj=\"2\" min=\"3\" ver=\"1\"/>\n \ + <description what=\"\" when=\"YYMMDDHHmm\"/>\n \ + <content>\n \ + <mesh name=\"testMesh\"/>\n \ + </content>\n \ + <splitting>\n \ + <subdomain number=\"$subdomainNumber\"/>\n \ + <global_numbering present=\"no\"/>\n \ + </splitting>\n \ + <files>\n$tagSubfile \ + </files>\n \ + <mapping>\n$tagMesh \ + </mapping>\n \ +</root>\n"; + + string tagSubfiles, tagSubfile="\ + <subfile id=\"$xyz\">\n \ + <name>$fileName</name>\n \ + <machine>localhost</machine>\n \ + </subfile>\n"; + string tagMeshes, tagMesh="\ + <mesh name=\"testMesh\">\n \ + <chunk subdomain=\"$xyz\">\n \ + <name>testMesh</name>\n \ + </chunk>\n \ + </mesh>\n"; + + int xyz=1; + string sxyz; + DataArrayDouble* coordsInit=mesh->getCoords()->deepCpy(); + double* ptrInit=coordsInit->getPointer(); + double deltax=cooFin[0]-cooDep[0]; + double deltay=cooFin[1]-cooDep[1]; + double deltaz=cooFin[2]-cooDep[2]; + + double dz=0.; + for (int z=0; z<nbz; z++) + { + double dy=0.; + for (int y=0; y<nby; y++) + { + double dx=0.; + for (int x=0; x<nbx; x++) + { + string fileName; + sxyz=IntToStr(xyz); + fileName="tmp_testMeshHuge_"+IntToStr(_ni)+"x"+IntToStr(_nj)+"x"+IntToStr(_nk)+"_"+sxyz+".med"; + + DataArrayDouble* coords=mesh->getCoords(); + //int nbOfComp=coords->getNumberOfComponents(); //be 3D + int nbOfTuple=coords->getNumberOfTuples(); + double* ptr=coords->getPointer(); + double* ptrini=ptrInit; + for (int i=0; i<nbOfTuple; i++) + { + *ptr=(*ptrini)+dx; ptr++; ptrini++; //be 3D + *ptr=(*ptrini)+dy; ptr++; ptrini++; + *ptr=(*ptrini)+dz; ptr++; ptrini++; + } + + MEDLoader::WriteUMesh(fileName.c_str(),mesh,true); + + tagSubfiles+=tagSubfile; + tagSubfiles.replace(tagSubfiles.find("$xyz"),4,sxyz); + tagSubfiles.replace(tagSubfiles.find("$fileName"),9,fileName); + + tagMeshes+=tagMesh; + tagMeshes.replace(tagMeshes.find("$xyz"),4,sxyz); + xyz++; + dx+=deltax; + } + dy+=deltay; + } + dz+=deltaz; + } + coordsInit->decrRef(); + + tagXml.replace(tagXml.find("$subdomainNumber"),16,sxyz); + tagXml.replace(tagXml.find("$tagSubfile"),11,tagSubfiles); + tagXml.replace(tagXml.find("$tagMesh"),8,tagMeshes); + + string nameFileXml; + _file_name_huge_xml="tmp_testMeshHuge_"+IntToStr(_ni)+"x"+IntToStr(_nj)+"x"+IntToStr(_nk)+"_"+sxyz+".xml"; + std::ofstream f(_file_name_huge_xml.c_str()); + f<<tagXml; + f.close(); + //cout<<"\n"<<tagXml<<endl; + if (_verbose) + cout<<endl<<nameFileXml<<" created"<<endl; + mesh->decrRef(); +} + +void MEDPARTITIONERTest::createTestMeshWithVecFieldOnCells() +{ + { + string name=_file_name; + MEDCouplingFieldDouble *f1=buildVecFieldOnCells(name); + name.replace(name.find(".med"),4,"_WithVecFieldOnCells.med"); + MEDLoader::WriteField(name.c_str(),f1,true); + f1->setTime(3.,1,1); //time,it,order + f1->applyFunc("x/2."); + MEDLoader::WriteField(name.c_str(),f1,false); + if (_verbose) cout<<endl<<name<<" created"<<endl; + if (_ntot<1000000) //too long + { + MEDCouplingFieldDouble *f2=MEDLoader::ReadFieldCell(name.c_str(),f1->getMesh()->getName().c_str(),0,f1->getName().c_str(),0,1); + //DataArrayDouble *res=f2->getArray(); + if (_verbose) cout<<name<<" reread"<<endl; + //CPPUNIT_ASSERT(f1->isEqual(f2,1e-12,1e-12)); + f2->decrRef(); + } + f1->decrRef(); + } + { + string name=_file_name; + MEDCouplingFieldDouble *f1=buildVecFieldOnCells(name); + name.replace(name.find(".med"),4,"_WithVecFieldOnGaussNe.med"); + MEDCouplingFieldDouble *f3=MEDCouplingFieldDouble::New(ON_GAUSS_NE,ONE_TIME); + f3->setMesh(f1->getMesh()); + //cout<<"\nNumberOfMeshPlacesExpected "<<f3->getNumberOfMeshPlacesExpected()<<" " + // /*<<getNumberOfTuples(f1->getMesh())<<" "*/ + // <<f3->getMesh()->getNumberOfNodes()<<" " + // <<f3->getMesh()->getNumberOfCells()<<endl; + f3->setName("MyFieldOnGaussNE"); + f3->setDescription("MyDescriptionNE"); + DataArrayDouble *array=DataArrayDouble::New(); + //int nb=f1->getMesh()->getNumberOfNodes(); + + /*8 pt de gauss by cell + int nb=f3->getMesh()->getNumberOfCells()*8; + array->alloc(nb,2); + double *ptr=array->getPointer(); + for (int i=0; i<nb*2; i=i+2) {ptr[i]=(double)(i/8) ; ptr[i]=2.*(double)(i/8);} + */ + + //more nbptgauss=8 by default needs set MEDCouplingFieldDiscretizationPerCell + //theory: (may be) http://www.code-aster.org/V2/doc/v9/fr/man_r/r3/r3.06.03.pdf + int nbptgauss=8; //nb pt de gauss by cell + int nbcell=f3->getMesh()->getNumberOfCells(); + int nb=nbcell*nbptgauss; + int nbcomp=2; + array->alloc(nb,nbcomp); + double *ptr=array->getPointer(); + int ii=0; + for (int i=0; i<nbcell; i++) + for (int j=0; j<nbptgauss; j++) + for (int k=0; k<nbcomp; k++) + { + //123.4 for 12th cell,3rd component, 4th gausspoint + ptr[ii]=(double)((i+1)*10+(k+1))+((double)(j+1))/10.; + ii++; + } + array->setInfoOnComponent(0,"vGx"); + array->setInfoOnComponent(1,"vGy"); + f3->setTime(4.,5,6); + f3->setArray(array); + array->decrRef(); + MEDLoader::WriteField(name.c_str(),f3,true); + if (_verbose) cout<<endl<<name<<" created"<<endl; + f3->checkCoherency(); + f1->decrRef(); + if (_ntot<1000000) //too long + { + MEDCouplingFieldDouble* f4=MEDLoader::ReadField(ON_GAUSS_NE, + name.c_str(), f3->getMesh()->getName().c_str(), 0, "MyFieldOnGaussNE", 5, 6); + if (_verbose) cout<<"MyFieldOnGaussNE reread"<<endl; + f4->decrRef(); + } + f3->decrRef(); + } + { + string name=_file_name_with_faces; + MEDCouplingFieldDouble *f1=buildVecFieldOnCells(name); + name.replace(name.find(".med"),4,"_WithVecFieldOnCells.med"); + MEDLoader::WriteField(name.c_str(),f1,true); + if (_verbose) cout<<endl<<name<<" created"<<endl; + if (_ntot<1000000) //too long + { + MEDCouplingFieldDouble *f2=MEDLoader::ReadFieldCell(name.c_str(),f1->getMesh()->getName().c_str(),0,f1->getName().c_str(),0,1); + if (_verbose) cout<<name<<" reread"<<endl; + //CPPUNIT_ASSERT(f1->isEqual(f2,1e-12,1e-12)); assertion failed!! + f2->decrRef(); + } + f1->decrRef(); + } +} + +void MEDPARTITIONERTest::createTestMeshWithVecFieldOnNodes() +{ + MEDCouplingFieldDouble *f1=buildVecFieldOnNodes(); + string name=_file_name; + name.replace(name.find(".med"),4,"_WithVecFieldOnNodes.med"); + MEDLoader::WriteField(name.c_str(),f1,true); + if (_verbose) cout<<endl<<name<<" created"<<endl; + if (_ntot<1000000) //too long + { + MEDCouplingFieldDouble *f2=MEDLoader::ReadFieldNode(name.c_str(),f1->getMesh()->getName().c_str(),0,f1->getName().c_str(),0,1); + if (_verbose) cout<<name<<" reread"<<endl; + //CPPUNIT_ASSERT(f1->isEqual(f2,1e-12,1e-12)); assertion failed!! + f2->decrRef(); + } + f1->decrRef(); +} + +void MEDPARTITIONERTest::verifyTestMeshWithVecFieldOnNodes() +{ + string name=_file_name; + name.replace(name.find(".med"),4,"_WithVecFieldOnNodes.med"); + MEDCouplingUMesh * m=MEDLoader::ReadUMeshFromFile(name.c_str(),_mesh_name.c_str(),0); + std::set<INTERP_KERNEL::NormalizedCellType> types(m->getAllGeoTypes()); + if (_verbose) + { + cout<<"\n types in "<<name<<" : "; + //for (std::set<INTERP_KERNEL::NormalizedCellType>::iterator t=types.begin(); t!=types.end(); ++t) cout<<" "<<*t; + for (std::set<INTERP_KERNEL::NormalizedCellType>::const_iterator t=types.begin(); t!=types.end(); ++t) + { + //INTERP_KERNEL::CellModel essai=INTERP_KERNEL::CellModel::GetCellModel(*t); + cout<<" "<<(INTERP_KERNEL::CellModel::GetCellModel(*t)).getRepr(); + } + cout<<endl; + } + m->decrRef(); + + MEDFileUMesh * mf = MEDFileUMesh::New(_file_name.c_str(),_mesh_name.c_str(),-1,-1); + vector<int> lev; + lev=mf->getNonEmptyLevels(); + if (_verbose) + { + cout<<" levels in "<<name<<" : "; + for (vector<int>::iterator l=lev.begin(); l!=lev.end(); ++l) cout<<" "<<*l; + cout<<endl; + } + mf->decrRef(); +} + +void MEDPARTITIONERTest::createTestMeshes() +{ + createTestMeshWithoutField(); + createTestMeshWithVecFieldOnCells(); + createTestMeshWithVecFieldOnNodes(); +} + +void MEDPARTITIONERTest::deleteTestMeshes() +{ + string cmd="rm *tmp_testMesh*"; + if (_verbose) cout<<endl<<cmd<<endl; + system(cmd.c_str()); //may be not if debug +} + +void MEDPARTITIONERTest::testMeshCollectionSingle() +{ + setSmallSize(); + createTestMeshes(); + MyGlobals::_World_Size=1; + MyGlobals::_Rank=0; + string fileName=_file_name_with_faces; + MEDPARTITIONER::ParaDomainSelector parallelizer(false); + MEDPARTITIONER::MeshCollection collection(fileName,parallelizer); + CPPUNIT_ASSERT(collection.isParallelMode()); + CPPUNIT_ASSERT_EQUAL(3, collection.getMeshDimension()); + CPPUNIT_ASSERT(collection.getName()=="testMesh"); + CPPUNIT_ASSERT_EQUAL(1,collection.getNbOfLocalMeshes()); + CPPUNIT_ASSERT_EQUAL(1,collection.getNbOfGlobalMeshes()); + CPPUNIT_ASSERT_EQUAL(_ni*_nj*_nk,collection.getNbOfLocalCells()); + CPPUNIT_ASSERT_EQUAL(_ni*_nj,collection.getNbOfLocalFaces()); +} + +void MEDPARTITIONERTest::testMeshCollectionXml() +{ + setSmallSize(); + createHugeTestMesh(_ni, _nj, _nk, 2, 2, 2, 32); //xml but not so huge + string fileName=_file_name_huge_xml; + MEDPARTITIONER::ParaDomainSelector parallelizer(false); + MEDPARTITIONER::MeshCollection collection(fileName,parallelizer); + CPPUNIT_ASSERT(collection.isParallelMode()); + CPPUNIT_ASSERT_EQUAL(3, collection.getMeshDimension()); + CPPUNIT_ASSERT(collection.getName()=="testMesh"); + CPPUNIT_ASSERT_EQUAL(8,collection.getNbOfLocalMeshes()); + CPPUNIT_ASSERT_EQUAL(8,collection.getNbOfGlobalMeshes()); + CPPUNIT_ASSERT_EQUAL(_ni*_nj*_nk*8,collection.getNbOfLocalCells()); + CPPUNIT_ASSERT_EQUAL(0,collection.getNbOfLocalFaces()); +} + + +//#################for metis + + + +#if defined(MED_ENABLE_METIS) +void MEDPARTITIONERTest::testMeshCollectionSinglePartitionMetis() +{ + setSmallSize(); + createTestMeshes(); + //MyGlobals::_Verbose=500; + string fileName=_file_name_with_faces; + int ndomains=2; + bool split_family=false; + bool empty_groups=false; + MEDPARTITIONER::ParaDomainSelector parallelizer(false); + MEDPARTITIONER::MeshCollection collection(fileName,parallelizer); + + MEDPARTITIONER::ParallelTopology* aPT = (MEDPARTITIONER::ParallelTopology*) collection.getTopology(); + aPT->setGlobalNumerotationDefault(collection.getParaDomainSelector()); + //Creating the graph and partitioning it + auto_ptr< MEDPARTITIONER::Topology > new_topo; + new_topo.reset( collection.createPartition(ndomains,MEDPARTITIONER::Graph::METIS) ); + //Creating a new mesh collection from the partitioning + MEDPARTITIONER::MeshCollection new_collection(collection,new_topo.get(),split_family,empty_groups); + + //example to create files + //MyGlobals::_General_Informations.clear(); + //MyGlobals::_General_Informations.push_back(SerializeFromString("finalMeshName=Merge")); + //if (MyGlobals::_Verbose>100) cout << "generalInformations : \n"<<ReprVectorOfString(MyGlobals::_General_Informations); + //new_collection.write("ttmp") + + CPPUNIT_ASSERT(new_collection.isParallelMode()); + CPPUNIT_ASSERT_EQUAL(3, new_collection.getMeshDimension()); + CPPUNIT_ASSERT(new_collection.getName()==collection.getName()); + CPPUNIT_ASSERT_EQUAL(ndomains,new_collection.getNbOfLocalMeshes()); + CPPUNIT_ASSERT_EQUAL(ndomains,new_collection.getNbOfGlobalMeshes()); + CPPUNIT_ASSERT_EQUAL(collection.getNbOfLocalCells(),new_collection.getNbOfLocalCells()); + CPPUNIT_ASSERT_EQUAL(collection.getNbOfLocalFaces(),new_collection.getNbOfLocalFaces()); +} + +void MEDPARTITIONERTest::testMeshCollectionComplexPartitionMetis() +{ + setSmallSize(); + createHugeTestMesh(_ni, _nj, _nk, 2, 2, 2, 32); //xml on 2*2*2 meshes but not so huge + string fileName=_file_name_huge_xml; + bool split_family=false; + bool empty_groups=false; + MEDPARTITIONER::ParaDomainSelector parallelizer(false); + MEDPARTITIONER::MeshCollection collection(fileName,parallelizer); + + MEDPARTITIONER::ParallelTopology* aPT = (MEDPARTITIONER::ParallelTopology*) collection.getTopology(); + aPT->setGlobalNumerotationDefault(collection.getParaDomainSelector()); + + for (int ndomains=2 ; ndomains<=16 ; ndomains++) + { + //Creating the graph and partitioning it + auto_ptr< MEDPARTITIONER::Topology > new_topo; + new_topo.reset( collection.createPartition(ndomains,MEDPARTITIONER::Graph::METIS) ); + //Creating a new mesh collection from the partitioning + MEDPARTITIONER::MeshCollection new_collection(collection,new_topo.get(),split_family,empty_groups); + + CPPUNIT_ASSERT_EQUAL(ndomains,new_collection.getNbOfLocalMeshes()); + CPPUNIT_ASSERT_EQUAL(ndomains,new_collection.getNbOfGlobalMeshes()); + CPPUNIT_ASSERT_EQUAL(collection.getNbOfLocalCells(),new_collection.getNbOfLocalCells()); + CPPUNIT_ASSERT_EQUAL(collection.getNbOfLocalFaces(),new_collection.getNbOfLocalFaces()); + } +} + +void MEDPARTITIONERTest::testMetisSmallSize() +{ + //#if !defined(HAVE_MPI) + setSmallSize(); + createTestMeshes(); + std::string MetisOrScotch("metis"); + launchMetisOrScotchMedpartitionerOnTestMeshes(MetisOrScotch); + verifyMetisOrScotchMedpartitionerOnSmallSizeForMesh(MetisOrScotch); + verifyMetisOrScotchMedpartitionerOnSmallSizeForFieldOnCells(MetisOrScotch); + verifyMetisOrScotchMedpartitionerOnSmallSizeForFieldOnGaussNe(MetisOrScotch); + //#endif +} +#endif + + +//#################for scotch + + +#if defined(MED_ENABLE_SCOTCH) +void MEDPARTITIONERTest::testMeshCollectionSinglePartitionScotch() +{ + setSmallSize(); + createTestMeshes(); + //MyGlobals::_Verbose=500; + string fileName=_file_name_with_faces; + int ndomains=2; + bool split_family=false; + bool empty_groups=false; + MEDPARTITIONER::ParaDomainSelector parallelizer(false); + MEDPARTITIONER::MeshCollection collection(fileName,parallelizer); + + MEDPARTITIONER::ParallelTopology* aPT = (MEDPARTITIONER::ParallelTopology*) collection.getTopology(); + aPT->setGlobalNumerotationDefault(collection.getParaDomainSelector()); + //Creating the graph and partitioning it + auto_ptr< MEDPARTITIONER::Topology > new_topo; + new_topo.reset( collection.createPartition(ndomains,MEDPARTITIONER::Graph::SCOTCH) ); + //Creating a new mesh collection from the partitioning + MEDPARTITIONER::MeshCollection new_collection(collection,new_topo.get(),split_family,empty_groups); + + //example to create files + //MyGlobals::_General_Informations.clear(); + //MyGlobals::_General_Informations.push_back(SerializeFromString("finalMeshName=Merge")); + //if (MyGlobals::_Verbose>100) cout << "generalInformations : \n"<<ReprVectorOfString(MyGlobals::_General_Informations); + //new_collection.write("ttmp") + + CPPUNIT_ASSERT(new_collection.isParallelMode()); + CPPUNIT_ASSERT_EQUAL(3, new_collection.getMeshDimension()); + CPPUNIT_ASSERT(new_collection.getName()==collection.getName()); + CPPUNIT_ASSERT_EQUAL(ndomains,new_collection.getNbOfLocalMeshes()); + CPPUNIT_ASSERT_EQUAL(ndomains,new_collection.getNbOfGlobalMeshes()); + CPPUNIT_ASSERT_EQUAL(collection.getNbOfLocalCells(),new_collection.getNbOfLocalCells()); + CPPUNIT_ASSERT_EQUAL(collection.getNbOfLocalFaces(),new_collection.getNbOfLocalFaces()); +} + +void MEDPARTITIONERTest::testMeshCollectionComplexPartitionScotch() +{ + setSmallSize(); + createHugeTestMesh(_ni, _nj, _nk, 2, 2, 2, 32); //xml on 2*2*2 meshes but not so huge + string fileName=_file_name_huge_xml; + bool split_family=false; + bool empty_groups=false; + MEDPARTITIONER::ParaDomainSelector parallelizer(false); + MEDPARTITIONER::MeshCollection collection(fileName,parallelizer); + + MEDPARTITIONER::ParallelTopology* aPT = (MEDPARTITIONER::ParallelTopology*) collection.getTopology(); + aPT->setGlobalNumerotationDefault(collection.getParaDomainSelector()); + + for (int ndomains=2 ; ndomains<=16 ; ndomains++) + { + //Creating the graph and partitioning it + auto_ptr< MEDPARTITIONER::Topology > new_topo; + new_topo.reset( collection.createPartition(ndomains,MEDPARTITIONER::Graph::SCOTCH) ); + //Creating a new mesh collection from the partitioning + MEDPARTITIONER::MeshCollection new_collection(collection,new_topo.get(),split_family,empty_groups); + + CPPUNIT_ASSERT_EQUAL(ndomains,new_collection.getNbOfLocalMeshes()); + CPPUNIT_ASSERT_EQUAL(ndomains,new_collection.getNbOfGlobalMeshes()); + CPPUNIT_ASSERT_EQUAL(collection.getNbOfLocalCells(),new_collection.getNbOfLocalCells()); + CPPUNIT_ASSERT_EQUAL(collection.getNbOfLocalFaces(),new_collection.getNbOfLocalFaces()); + } +} + +void MEDPARTITIONERTest::testScotchSmallSize() +{ + //#if !defined(HAVE_MPI) + setSmallSize(); + createTestMeshes(); + std::string MetisOrScotch("scotch"); + launchMetisOrScotchMedpartitionerOnTestMeshes(MetisOrScotch); + verifyMetisOrScotchMedpartitionerOnSmallSizeForMesh(MetisOrScotch); + verifyMetisOrScotchMedpartitionerOnSmallSizeForFieldOnCells(MetisOrScotch); + verifyMetisOrScotchMedpartitionerOnSmallSizeForFieldOnGaussNe(MetisOrScotch); + //#endif +} +#endif + +void MEDPARTITIONERTest::launchMetisOrScotchMedpartitionerOnTestMeshes(std::string MetisOrScotch) +{ + int res; + string cmd,execName,sourceName,targetName; + + execName=getPartitionerExe(); + + cmd="which "+execName+" 2>/dev/null 1>/dev/null"; //no trace + res=system(cmd.c_str()); + CPPUNIT_ASSERT_EQUAL_MESSAGE(execName + " - INVALID PATH TO medpartitioner", 0, res); + + cmd=execName+" --ndomains=2 --split-method="+MetisOrScotch; //on same proc + sourceName=_file_name; + targetName=_file_name; + targetName.replace(targetName.find(".med"),4,"_partitionedTo2_"); + cmd+=" --input-file="+sourceName+" --output-file="+targetName+" --verbose="+IntToStr(_verbose); + if (_verbose) cout<<endl<<cmd<<endl; + res=system(cmd.c_str()); + CPPUNIT_ASSERT_EQUAL(0, res); + + cmd=execName+" --ndomains=5 --split-method="+MetisOrScotch; //on less proc + sourceName=_file_name; + targetName=_file_name; + targetName.replace(targetName.find(".med"),4,"_partitionedTo5_"); + cmd+=" --input-file="+sourceName+" --output-file="+targetName+" --verbose="+IntToStr(_verbose); + if (_verbose) cout<<endl<<cmd<<endl; + res=system(cmd.c_str()); + CPPUNIT_ASSERT_EQUAL(0, res); + + cmd=execName+" --ndomains=1 --split-method="+MetisOrScotch; //on 1 proc + sourceName=targetName+".xml"; + targetName=_file_name; + targetName.replace(targetName.find(".med"),4,"_remergedFrom5_"); + cmd+=" --input-file="+sourceName+" --output-file="+targetName+" --verbose="+IntToStr(_verbose); + if (_verbose) cout<<endl<<cmd<<endl; + res=system(cmd.c_str()); + CPPUNIT_ASSERT_EQUAL(0, res); + + cmd=execName+" --ndomains=1 --split-method="+MetisOrScotch; //on more proc + //sourceName=targetName+".xml"; + targetName=_file_name; + targetName.replace(targetName.find(".med"),4,"_remergedFrom5_"); + cmd+=" --input-file="+sourceName+" --output-file="+targetName+" --verbose="+IntToStr(_verbose); + if (_verbose) cout<<endl<<cmd<<endl; + res=system(cmd.c_str()); + CPPUNIT_ASSERT_EQUAL(0, res); +} + +void MEDPARTITIONERTest::verifyMetisOrScotchMedpartitionerOnSmallSizeForMesh(std::string MetisOrScotch) +{ + int res; + string fileName,cmd,execName,sourceName,targetName,input; + execName=getPartitionerExe(); + fileName=_file_name_with_faces; + + ParaMEDMEM::MEDFileUMesh* initialMesh=ParaMEDMEM::MEDFileUMesh::New(fileName.c_str(),_mesh_name.c_str()); + ParaMEDMEM::MEDCouplingUMesh* cellMesh=initialMesh->getLevel0Mesh(false); + ParaMEDMEM::MEDCouplingUMesh* faceMesh=initialMesh->getLevelM1Mesh(false); + + cmd=execName+" --ndomains=5 --split-method="+MetisOrScotch; //on same proc + sourceName=fileName; + targetName=fileName; + targetName.replace(targetName.find(".med"),4,"_partitionedTo5_"); + cmd+=" --input-file="+sourceName+" --output-file="+targetName+" --verbose="+IntToStr(_verbose); + if (_verbose) cout<<endl<<cmd<<endl; + res=system(cmd.c_str()); + CPPUNIT_ASSERT_EQUAL(0, res); + input=targetName+".xml"; + + MEDPARTITIONER::ParaDomainSelector parallelizer(false); + MEDPARTITIONER::MeshCollection collection(input,parallelizer); + CPPUNIT_ASSERT_EQUAL(3, collection.getMeshDimension()); + std::vector<ParaMEDMEM::MEDCouplingUMesh*>cellMeshes=collection.getMesh(); + CPPUNIT_ASSERT_EQUAL(5, (int) cellMeshes.size()); + int nbcells=0; + for (std::size_t i = 0; i < cellMeshes.size(); i++) + nbcells+=cellMeshes[i]->getNumberOfCells(); + CPPUNIT_ASSERT_EQUAL(cellMesh->getNumberOfCells(), nbcells); + + std::vector<ParaMEDMEM::MEDCouplingUMesh*>faceMeshes=collection.getFaceMesh(); + CPPUNIT_ASSERT_EQUAL(5, (int) faceMeshes.size()); + int nbfaces=0; + for (std::size_t i=0; i < faceMeshes.size(); i++) + nbfaces+=faceMeshes[i]->getNumberOfCells(); + CPPUNIT_ASSERT_EQUAL(faceMesh->getNumberOfCells(), nbfaces); + + //merge split meshes and test equality + cmd=execName+" --ndomains=1 --split-method="+MetisOrScotch; //on same proc + sourceName=targetName+".xml"; + targetName=fileName; + targetName.replace(targetName.find(".med"),4,"_remergedFrom5_"); + cmd+=" --input-file="+sourceName+" --output-file="+targetName+" --verbose="+IntToStr(_verbose); + if (_verbose) cout<<endl<<cmd<<endl; + res=system(cmd.c_str()); + CPPUNIT_ASSERT_EQUAL(0, res); + + string refusedName=targetName+"1.med"; + ParaMEDMEM::MEDFileUMesh* refusedMesh=ParaMEDMEM::MEDFileUMesh::New(refusedName.c_str(),_mesh_name.c_str()); + ParaMEDMEM::MEDCouplingUMesh* refusedCellMesh=refusedMesh->getLevel0Mesh(false); + ParaMEDMEM::MEDCouplingUMesh* refusedFaceMesh=refusedMesh->getLevelM1Mesh(false); + + CPPUNIT_ASSERT_EQUAL(cellMesh->getNumberOfCells(), refusedCellMesh->getNumberOfCells()); + CPPUNIT_ASSERT_EQUAL(faceMesh->getNumberOfCells(), refusedFaceMesh->getNumberOfCells()); + + /*not the good job + ParaMEDMEM::MEDCouplingMesh* mergeCell=cellMesh->mergeMyselfWith(refusedCellMesh); + CPPUNIT_ASSERT_EQUAL(cellMesh->getNumberOfCells(), mergeCell->getNumberOfCells()); + + ParaMEDMEM::MEDCouplingMesh* mergeFace=faceMesh->mergeMyselfWith(refusedFaceMesh); + CPPUNIT_ASSERT_EQUAL(faceMesh->getNumberOfCells(), mergeFace->getNumberOfCells()); + + CPPUNIT_ASSERT(faceMesh->isEqual(refusedFaceMesh,1e-12)); + */ + + std::vector<const MEDCouplingUMesh *> meshes; + std::vector<DataArrayInt *> corr; + meshes.push_back(cellMesh); + refusedCellMesh->tryToShareSameCoordsPermute(*cellMesh, 1e-9); + meshes.push_back(refusedCellMesh); + MEDCouplingUMesh* fusedCell=MEDCouplingUMesh::FuseUMeshesOnSameCoords(meshes,0,corr); + CPPUNIT_ASSERT_EQUAL(cellMesh->getNumberOfCells(), fusedCell->getNumberOfCells()); + + meshes.resize(0); + for (std::size_t i = 0; i < corr.size(); i++) + corr[i]->decrRef(); + corr.resize(0); + meshes.push_back(faceMesh); + refusedFaceMesh->tryToShareSameCoordsPermute(*faceMesh, 1e-9); + meshes.push_back(refusedFaceMesh); + MEDCouplingUMesh* fusedFace=MEDCouplingUMesh::FuseUMeshesOnSameCoords(meshes,0,corr); + CPPUNIT_ASSERT_EQUAL(faceMesh->getNumberOfCells(), fusedFace->getNumberOfCells()); + + for (std::size_t i = 0; i < corr.size(); i++) + corr[i]->decrRef(); + fusedFace->decrRef(); + refusedFaceMesh->decrRef(); + faceMesh->decrRef(); + fusedCell->decrRef(); + refusedCellMesh->decrRef(); + refusedMesh->decrRef(); + cellMesh->decrRef(); + initialMesh->decrRef(); + //done in ~collection + //for (int i = 0; i < faceMeshes.size(); i++) faceMeshes[i]->decrRef(); + //for (int i = 0; i < cellMeshes.size(); i++) cellMeshes[i]->decrRef(); +} + +void MEDPARTITIONERTest::verifyMetisOrScotchMedpartitionerOnSmallSizeForFieldOnCells(std::string MetisOrScotch) +{ + int res; + string fileName,cmd,execName,sourceName,targetName,input; + execName=getPartitionerExe(); + fileName=_file_name; + fileName.replace(fileName.find(".med"),4,"_WithVecFieldOnCells.med"); + + ParaMEDMEM::MEDFileUMesh* initialMesh=ParaMEDMEM::MEDFileUMesh::New(fileName.c_str(),_mesh_name.c_str()); + ParaMEDMEM::MEDCouplingUMesh* cellMesh=initialMesh->getLevel0Mesh(false); + + cmd=execName+" --ndomains=5 --split-method="+MetisOrScotch; //on same proc + sourceName=fileName; + targetName=fileName; + targetName.replace(targetName.find(".med"),4,"_partitionedTo5_"); + cmd+=" --input-file="+sourceName+" --output-file="+targetName+" --verbose="+IntToStr(_verbose); + if (_verbose) cout<<endl<<cmd<<endl; + res=system(cmd.c_str()); + CPPUNIT_ASSERT_EQUAL(0, res); + input=targetName+".xml"; + + //merge split meshes and test equality + cmd=execName+" --ndomains=1 --split-method="+MetisOrScotch; //on same proc + sourceName=targetName+".xml"; + targetName=fileName; + targetName.replace(targetName.find(".med"),4,"_remergedFrom5_"); + cmd+=" --input-file="+sourceName+" --output-file="+targetName+" --verbose="+IntToStr(_verbose); + if (_verbose) cout<<endl<<cmd<<endl; + res=system(cmd.c_str()); + CPPUNIT_ASSERT_EQUAL(0, res); + + string refusedName=targetName+"1.med"; + ParaMEDMEM::MEDFileUMesh* refusedMesh=ParaMEDMEM::MEDFileUMesh::New(refusedName.c_str(),_mesh_name.c_str()); + ParaMEDMEM::MEDCouplingUMesh* refusedCellMesh=refusedMesh->getLevel0Mesh(false); + + CPPUNIT_ASSERT_EQUAL(cellMesh->getNumberOfCells(), refusedCellMesh->getNumberOfCells()); + + std::vector<const MEDCouplingUMesh *> meshes; + std::vector<DataArrayInt *> corr; + meshes.push_back(cellMesh); + refusedCellMesh->tryToShareSameCoordsPermute(*cellMesh, 1e-9); + meshes.push_back(refusedCellMesh); + MEDCouplingUMesh* fusedCell=MEDCouplingUMesh::FuseUMeshesOnSameCoords(meshes,0,corr); + CPPUNIT_ASSERT_EQUAL(cellMesh->getNumberOfCells(), fusedCell->getNumberOfCells()); + + MEDCouplingFieldDouble* field1=MEDLoader::ReadFieldCell(fileName.c_str(),initialMesh->getName().c_str(),0,"VectorFieldOnCells",0,1); + MEDCouplingFieldDouble* field2=MEDLoader::ReadFieldCell(refusedName.c_str(),refusedCellMesh->getName().c_str(),0,"VectorFieldOnCells",0,1); + + int nbcells=corr[1]->getNumberOfTuples(); + CPPUNIT_ASSERT_EQUAL(cellMesh->getNumberOfCells(), nbcells); + //use corr to test equality of field + DataArrayDouble* f1=field1->getArray(); + DataArrayDouble* f2=field2->getArray(); + if (_verbose>300) + { + cout<<"\nf1 : "<<f1->reprZip(); + cout<<"\nf2 : "<<f2->reprZip(); //field2->advancedRepradvancedRepr(); + for (std::size_t i = 0; i < corr.size(); i++) + cout << "\ncorr " << i << " : " << corr[i]->reprZip(); + + } + int nbequal=0; + int nbcomp=field1->getNumberOfComponents(); + double* p1=f1->getPointer(); + double* p2=f2->getPointer(); + int* pc=corr[1]->getPointer(); + for (int i = 0; i < nbcells; i++) + { + int i1=pc[i]*nbcomp; + int i2=i*nbcomp; + for (int j = 0; j < nbcomp; j++) + { + if (p1[i1+j]==p2[i2+j]) nbequal++; + //cout<<" "<<p1[i1+j]<<"="<<p2[i2+j]; + } + } + CPPUNIT_ASSERT_EQUAL(nbcells*nbcomp, nbequal); + + for (std::size_t i = 0; i < corr.size(); i++) + corr[i]->decrRef(); + field1->decrRef(); + field2->decrRef(); + fusedCell->decrRef(); + refusedMesh->decrRef(); + refusedCellMesh->decrRef(); + cellMesh->decrRef(); + initialMesh->decrRef(); +} + +void MEDPARTITIONERTest::verifyMetisOrScotchMedpartitionerOnSmallSizeForFieldOnGaussNe(std::string MetisOrScotch) +{ + int res; + string fileName,cmd,execName,sourceName,targetName,input; + execName=getPartitionerExe(); + fileName=_file_name; + fileName.replace(fileName.find(".med"),4,"_WithVecFieldOnGaussNe.med"); + + ParaMEDMEM::MEDFileUMesh* initialMesh=ParaMEDMEM::MEDFileUMesh::New(fileName.c_str(),_mesh_name.c_str()); + ParaMEDMEM::MEDCouplingUMesh* cellMesh=initialMesh->getLevel0Mesh(false); + + cmd=execName+" --ndomains=5 --split-method="+MetisOrScotch; //on same proc + sourceName=fileName; + targetName=fileName; + targetName.replace(targetName.find(".med"),4,"_partitionedTo5_"); + cmd+=" --input-file="+sourceName+" --output-file="+targetName+" --verbose="+IntToStr(_verbose); + if (_verbose) cout<<endl<<cmd<<endl; + res=system(cmd.c_str()); + CPPUNIT_ASSERT_EQUAL(0, res); + input=targetName+".xml"; + + //merge split meshes and test equality + cmd=execName+" --ndomains=1 --split-method="+MetisOrScotch; //on same proc + sourceName=targetName+".xml"; + targetName=fileName; + targetName.replace(targetName.find(".med"),4,"_remergedFrom5_"); + cmd+=" --input-file="+sourceName+" --output-file="+targetName+" --verbose="+IntToStr(_verbose); + if (_verbose) cout<<endl<<cmd<<endl; + res=system(cmd.c_str()); + CPPUNIT_ASSERT_EQUAL(0, res); + + string refusedName=targetName+"1.med"; + ParaMEDMEM::MEDFileUMesh* refusedMesh=ParaMEDMEM::MEDFileUMesh::New(refusedName.c_str(),_mesh_name.c_str()); + ParaMEDMEM::MEDCouplingUMesh* refusedCellMesh=refusedMesh->getLevel0Mesh(false); + + CPPUNIT_ASSERT_EQUAL(cellMesh->getNumberOfCells(), refusedCellMesh->getNumberOfCells()); + + std::vector<const MEDCouplingUMesh *> meshes; + std::vector<DataArrayInt *> corr; + meshes.push_back(cellMesh); + refusedCellMesh->tryToShareSameCoordsPermute(*cellMesh, 1e-9); + meshes.push_back(refusedCellMesh); + MEDCouplingUMesh* fusedCell=MEDCouplingUMesh::FuseUMeshesOnSameCoords(meshes,0,corr); + CPPUNIT_ASSERT_EQUAL(cellMesh->getNumberOfCells(), fusedCell->getNumberOfCells()); + + MEDCouplingFieldDouble* field1=MEDLoader::ReadField(ON_GAUSS_NE,fileName.c_str(),initialMesh->getName().c_str(),0,"MyFieldOnGaussNE",5,6); + MEDCouplingFieldDouble* field2=MEDLoader::ReadField(ON_GAUSS_NE,refusedName.c_str(),refusedCellMesh->getName().c_str(),0,"MyFieldOnGaussNE",5,6); + + int nbcells=corr[1]->getNumberOfTuples(); + CPPUNIT_ASSERT_EQUAL(cellMesh->getNumberOfCells(), nbcells); + //use corr to test equality of field + DataArrayDouble* f1=field1->getArray(); + DataArrayDouble* f2=field2->getArray(); + if (_verbose>300) + { + cout << "\nf1 : " << f1->reprZip(); //123.4 for 12th cell,3rd component, 4th gausspoint + cout << "\nf2 : " << f2->reprZip(); //field2->advancedRepradvancedRepr(); + for (std::size_t i = 0; i < corr.size(); i++) + cout << "\ncorr " << i << " : " << corr[i]->reprZip(); + + } + int nbequal=0; + int nbptgauss=8; + int nbcomp=field1->getNumberOfComponents(); + double* p1=f1->getPointer(); + double* p2=f2->getPointer(); + int* pc=corr[1]->getPointer(); + for (int i = 0; i < nbcells; i++) + { + int i1=pc[i]*nbcomp*nbptgauss; + int i2=i*nbcomp*nbptgauss; + for (int j = 0; j < nbcomp*nbptgauss; j++) + { + if (p1[i1+j]==p2[i2+j]) nbequal++; + //cout<<" "<<p1[i1+j]<<"="<<p2[i2+j]; + } + } + CPPUNIT_ASSERT_EQUAL(nbcells*nbcomp*nbptgauss, nbequal); + + for (std::size_t i = 0; i < corr.size(); i++) + corr[i]->decrRef(); + field1->decrRef(); + field2->decrRef(); + fusedCell->decrRef(); + refusedMesh->decrRef(); + refusedCellMesh->decrRef(); + cellMesh->decrRef(); + initialMesh->decrRef(); +} + +//================================================================================ +/*! + * \brief Test for 0021756: [CEA 602] MEDPartitioner improvements + */ +//================================================================================ + +void MEDPARTITIONERTest::testCreateBoundaryFaces2D() +{ + // Fixed complains are: + // - 2D is not available + // - groups and family handling is bugged (probably due to bug in the handling + // of arrayTo in castIntField()) + // - creates boundary faces option is not handled + + // Create a 2D mesh in a file + + const char fileName[] = "tmp_testCreateBoundaryFaces2D.med"; + + const int idFam1 = 3, idFam2 = 2; + int nbFam1, nbFam2, nbc; + { + const int nbX = 20, nbY = 15; + vector<int> conn; + vector<double> coor; + for (int j=0; j<=nbY; j++) + for (int i=0; i<=nbX; i++) + { + coor.push_back(i+.1); + coor.push_back(j+.2); + } + int ii; + for (int j=0; j<nbY; j++) + for (int i=0; i<nbX; i++) + { + ii=i + j*(nbX+1); + conn.push_back(ii); + conn.push_back(ii+1); + ii=ii + nbX + 2 ; + conn.push_back(ii); + conn.push_back(ii-1); + } + MEDCouplingUMesh *mesh=MEDCouplingUMesh::New(); + mesh->setMeshDimension(2); + + nbc=conn.size()/4; //nb of cells + mesh->allocateCells(nbc); + int* pConn = &conn[0]; + for(int i=0; i<nbc; i++, pConn+=4) + mesh->insertNextCell(INTERP_KERNEL::NORM_QUAD4,4,pConn); + mesh->finishInsertingCells(); + + int nbv=coor.size()/2; //nb of vertices + DataArrayDouble *myCoords=DataArrayDouble::New(); + myCoords->useArray( &coor[0], /*ownership=*/false, CPP_DEALLOC, nbv, 2 ); + mesh->setCoords(myCoords); + mesh->setName("FacesIn2D"); + myCoords->decrRef(); + mesh->checkCoherency(); + + // groups of cells + DataArrayInt* cellsFam=DataArrayInt::New(); + cellsFam->alloc(nbc,1); + nbFam1 = nbc/3, nbFam2 = nbc/2; + int iE = 0; + for ( int i = 0; i < nbFam1; ++i ) cellsFam->getPointer()[ iE++ ] = idFam1; + for ( int i = 0; i < nbFam2; ++i ) cellsFam->getPointer()[ iE++ ] = idFam2; + for ( ; iE < nbc; ) cellsFam->getPointer()[ iE++ ] = 0; + map<string,int> theFamilies; + theFamilies["FAMILLE_ZERO"]=0; + theFamilies["Family1" ]=idFam1; + theFamilies["Family2" ]=idFam2; + map<string, vector<string> > theGroups; + theGroups["Group1"].push_back("Family1"); + theGroups["Group2"].push_back("Family2"); + + // write mesh + MEDFileUMesh * fileMesh = MEDFileUMesh::New(); + fileMesh->setMeshAtLevel(0, mesh); + fileMesh->setFamilyInfo(theFamilies); + fileMesh->setGroupInfo(theGroups); + fileMesh->setFamilyFieldArr(0, cellsFam); + fileMesh->write(fileName,2); + + cellsFam->decrRef(); + mesh ->decrRef(); + fileMesh->decrRef(); + + } // mesh creation + + // Partition the mesh into 4 parts + + const int ndomains = 4; + ParaDomainSelector parallelizer(false); + MeshCollection collection(fileName,parallelizer); + ParallelTopology* aPT = (ParallelTopology*) collection.getTopology(); + aPT->setGlobalNumerotationDefault(collection.getParaDomainSelector()); + + std::auto_ptr< Topology > new_topo; +#if defined(MED_ENABLE_METIS) || defined(MED_ENABLE_PARMETIS) + new_topo.reset( collection.createPartition(ndomains,Graph::METIS) ); +#endif +#if defined(MED_ENABLE_SCOTCH) + if ( !new_topo.get() ) + new_topo.reset( collection.createPartition(ndomains,Graph::SCOTCH) ); +#endif + if ( !new_topo.get() ) + return; + + // Check that "2D is available" + + const char xmlName[] = "tmp_testCreateBoundaryFaces2D"; + { + MyGlobals::_Creates_Boundary_Faces = true; + MeshCollection new_collection(collection,new_topo.get()); + + CPPUNIT_ASSERT_EQUAL(ndomains,new_collection.getNbOfLocalMeshes()); + CPPUNIT_ASSERT_EQUAL(ndomains,new_collection.getNbOfGlobalMeshes()); + CPPUNIT_ASSERT_EQUAL(collection.getNbOfLocalCells(),new_collection.getNbOfLocalCells()); + CPPUNIT_ASSERT_EQUAL(0,collection.getNbOfLocalFaces()); + CPPUNIT_ASSERT (new_collection.getNbOfLocalFaces() > 0 ); + + MyGlobals::_General_Informations.clear(); + MyGlobals::_General_Informations.push_back(SerializeFromString("finalMeshName=2D")); + new_collection.write( xmlName ); + } + + // Check that "groups and family handling is NOT bugged" + + MeshCollection new_collection(std::string(xmlName)+".xml"); + std::map< int, int > famId2nb; // count total nb of cells in divided families + std::map< int, int >::iterator id2nn; + { + const std::vector<ParaMEDMEM::DataArrayInt*>& famIdsVec = new_collection.getCellFamilyIds(); + for ( size_t i = 0; i < famIdsVec.size(); ++i ) + { + ParaMEDMEM::DataArrayInt* famIdsArr = famIdsVec[i]; + for ( int j = famIdsArr->getNbOfElems()-1; j >= 0; --j ) + { + id2nn = famId2nb.insert( make_pair( famIdsArr->getPointer()[j], 0 )).first; + id2nn->second++; + } + } + } + CPPUNIT_ASSERT_EQUAL( 3, (int) famId2nb.size() ); // 3 fams/groups in all + CPPUNIT_ASSERT_EQUAL( 1, (int) famId2nb.count( 0 )); + CPPUNIT_ASSERT_EQUAL( 1, (int) famId2nb.count( idFam1 )); + CPPUNIT_ASSERT_EQUAL( 1, (int) famId2nb.count( idFam2 )); + CPPUNIT_ASSERT_EQUAL( nbFam1, famId2nb[ idFam1 ]); + CPPUNIT_ASSERT_EQUAL( nbFam2, famId2nb[ idFam2 ]); + CPPUNIT_ASSERT_EQUAL( nbc - nbFam1 - nbFam2, famId2nb[ 0 ]); + + // Check that "creates boundary faces option is handled" + + famId2nb.clear(); + const std::vector<ParaMEDMEM::DataArrayInt*>& famIdsVec = new_collection.getFaceFamilyIds(); + for ( size_t i = 0; i < famIdsVec.size(); ++i ) + { + ParaMEDMEM::DataArrayInt* famIdsArr = famIdsVec[i]; + for ( int j = famIdsArr->getNbOfElems()-1; j >= 0; --j ) + { + id2nn = famId2nb.insert( make_pair( famIdsArr->getPointer()[j], 0 )).first; + id2nn->second++; + } + } + + CPPUNIT_ASSERT( !famId2nb.empty() ); + + // for each "JOINT_n_p_..." group there must be "JOINT_p_n_..." group + // of the same size + std::map<std::string,int>& famName2id = new_collection.getFamilyInfo(); + std::map<std::string,int>::iterator na2id = famName2id.begin(), na2id2; + std::set< int > okFamIds; + okFamIds.insert(0); + for ( ; na2id != famName2id.end(); ++na2id ) + { + if ( okFamIds.count( na2id->second ) || na2id->first[0] != 'J') + continue; + na2id2 = na2id; + bool groupOK = false; + while ( !groupOK && ++na2id2 != famName2id.end() ) + groupOK = ( na2id2->first.find_first_not_of( na2id->first ) == std::string::npos ); + + CPPUNIT_ASSERT( groupOK ); + CPPUNIT_ASSERT( na2id->second != na2id2->second); + CPPUNIT_ASSERT_EQUAL( 1, (int) famId2nb.count( na2id2->second )); + CPPUNIT_ASSERT_EQUAL( 1, (int) famId2nb.count( na2id->second )); + CPPUNIT_ASSERT_EQUAL( (int) famId2nb[ na2id2->second ], + (int) famId2nb[ na2id->second ]); + okFamIds.insert( na2id2->second ); + } +} diff --git a/src/medtool/src/MEDPartitioner/Test/MEDPARTITIONERTest.hxx b/src/medtool/src/MEDPartitioner/Test/MEDPARTITIONERTest.hxx new file mode 100644 index 000000000..5e437cb32 --- /dev/null +++ b/src/medtool/src/MEDPartitioner/Test/MEDPARTITIONERTest.hxx @@ -0,0 +1,142 @@ +// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 +// 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 __MEDPARTITIONERTEST_HXX__ +#define __MEDPARTITIONERTEST_HXX__ + +#ifdef WIN32 +# if defined MEDPARTITIONERTEST_EXPORTS || defined MEDPARTITIONERTest_EXPORTS +# define MEDPARTITIONERTEST_EXPORT __declspec( dllexport ) +# else +# define MEDPARTITIONERTEST_EXPORT __declspec( dllimport ) +# endif +#else +# define MEDPARTITIONERTEST_EXPORT +#endif + + +#include <cppunit/extensions/HelperMacros.h> + +#include <set> +#include <string> +#include <iostream> + +#include "MEDCouplingUMesh.hxx" +#include "MEDCouplingExtrudedMesh.hxx" +#include "MEDCouplingFieldDouble.hxx" + +class MEDPARTITIONERTEST_EXPORT MEDPARTITIONERTest : public CppUnit::TestFixture +{ + CPPUNIT_TEST_SUITE( MEDPARTITIONERTest ); + CPPUNIT_TEST( testMeshCollectionSingle ); + CPPUNIT_TEST( testMeshCollectionXml ); +#if defined(MED_ENABLE_METIS) + CPPUNIT_TEST( testMeshCollectionSinglePartitionMetis ); + CPPUNIT_TEST( testMeshCollectionComplexPartitionMetis ); + CPPUNIT_TEST( testMetisSmallSize ); +#endif +#if defined(MED_ENABLE_SCOTCH) + CPPUNIT_TEST( testMeshCollectionSinglePartitionScotch ); + CPPUNIT_TEST( testMeshCollectionComplexPartitionScotch ); + CPPUNIT_TEST( testScotchSmallSize ); +#endif + +#if defined(HAVE_MPI) +#if defined(MED_ENABLE_PARMETIS) + //test with mpi on system + CPPUNIT_TEST( testMpirunSmallSize ); + CPPUNIT_TEST( testMpirunMedianSize ); + CPPUNIT_TEST( testMpirunHugeSize ); +#endif +#endif + + CPPUNIT_TEST( testCreateBoundaryFaces2D ); // imp 0021756 + + //CPPUNIT_TEST( deleteTestMeshes ); + CPPUNIT_TEST_SUITE_END(); + +public: + + //global use + int _ni; //nb of hexa9 + int _nj; + int _nk; + int _ntot; + std::string _file_name; //initial test mesh file med CUBE3D + std::string _file_name_with_faces; //initial test mesh file med CUBE3D plus a set of faces + std::string _file_name2; //initial test mesh file med CARRE3D + std::string _file_name_huge_xml; + int _nb_target_huge; + std::string _mesh_name; //initial test mesh file med + int _verbose; + + //for utils + void setSize(int ni, int nj, int nk); + void setSmallSize(); + void setMedianSize(); + void setbigSize(); + std::string getPartitionerExe() const; + ParaMEDMEM::MEDCouplingUMesh * buildCUBE3DMesh(); + ParaMEDMEM::MEDCouplingUMesh * buildFACE3DMesh(); + ParaMEDMEM::MEDCouplingUMesh * buildCARRE3DMesh(); + ParaMEDMEM::MEDCouplingFieldDouble * buildVecFieldOnCells(std::string myfileName); + ParaMEDMEM::MEDCouplingFieldDouble * buildVecFieldOnNodes(); + void createTestMeshWithoutField(); + void createTestMeshWithVecFieldOnCells(); + void createTestMeshWithVecFieldOnNodes(); + void verifyTestMeshWithVecFieldOnNodes(); + void verifyMetisOrScotchMedpartitionerOnSmallSizeForMesh(std::string MetisOrScotch); + void verifyMetisOrScotchMedpartitionerOnSmallSizeForFieldOnCells(std::string MetisOrScotch); + void verifyMetisOrScotchMedpartitionerOnSmallSizeForFieldOnGaussNe(std::string MetisOrScotch); + void verifyMedpartitionerOnSmallSizeForMesh(); + void verifyMedpartitionerOnSmallSizeForFieldOnCells(); + void verifyMedpartitionerOnSmallSizeForFieldOnGaussNe(); + void createTestMeshes(); + void createHugeTestMesh(int ni, int nj, int nk, int nbx, int nby, int nbz, int nbTarget); + void launchMetisOrScotchMedpartitionerOnTestMeshes(std::string MetisOrScotch); + void launchMedpartitionerOnTestMeshes(); + void launchMedpartitionerOnHugeTestMeshes(); + void deleteTestMeshes(); + + //for CPPUNIT_TEST + void setUp(); + void tearDown(); + void testMeshCollectionSingle(); + void testMeshCollectionXml(); +#if defined(MED_ENABLE_METIS) + void testMeshCollectionSinglePartitionMetis(); + void testMeshCollectionComplexPartitionMetis(); + void testMetisSmallSize(); +#endif +#if defined(MED_ENABLE_SCOTCH) + void testMeshCollectionSinglePartitionScotch(); + void testMeshCollectionComplexPartitionScotch(); + void testScotchSmallSize(); +#endif + +#if defined(HAVE_MPI) + void testMpirunSmallSize(); + void testMpirunMedianSize(); + void testMpirunHugeSize(); +#endif + + void testCreateBoundaryFaces2D(); +}; + +#endif diff --git a/src/medtool/src/MEDPartitioner/Test/MEDPARTITIONERTestPara.cxx b/src/medtool/src/MEDPartitioner/Test/MEDPARTITIONERTestPara.cxx new file mode 100644 index 000000000..5daaa525d --- /dev/null +++ b/src/medtool/src/MEDPartitioner/Test/MEDPARTITIONERTestPara.cxx @@ -0,0 +1,435 @@ +// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// + +#include "MEDPARTITIONERTest.hxx" + +#include "MEDPARTITIONER_MeshCollection.hxx" +#include "MEDPARTITIONER_ParallelTopology.hxx" +#include "MEDPARTITIONER_ParaDomainSelector.hxx" +#include "MEDPARTITIONER_Utils.hxx" + +#include "CellModel.hxx" +#include "MEDFileMesh.hxx" +#include "MEDLoader.hxx" +#include "MEDLoaderBase.hxx" +#include "MEDCouplingUMesh.hxx" +#include "MEDCouplingExtrudedMesh.hxx" +#include "MEDCouplingFieldDouble.hxx" +#include "MEDCouplingMemArray.hxx" +#include "MEDCouplingMultiFields.hxx" + +#include <cppunit/TestAssert.h> + +#include <sstream> +#include <cmath> +#include <list> +#include <stdexcept> +#include <cstdlib> +#include <vector> + +#include <mpi.h> + +using namespace std; +using namespace ParaMEDMEM; +using namespace MEDPARTITIONER; + +#if defined(HAVE_MPI) +void MEDPARTITIONERTest::verifyMedpartitionerOnSmallSizeForMesh() +{ + int res; + string fileName,cmd,execName,sourceName,targetName,input; + execName=getenv("MED_ROOT_DIR"); //.../INSTALL/MED + execName+="/bin/salome/medpartitioner_para"; + fileName=_file_name_with_faces; + + ParaMEDMEM::MEDFileUMesh* initialMesh=ParaMEDMEM::MEDFileUMesh::New(fileName.c_str(),_mesh_name.c_str()); + ParaMEDMEM::MEDCouplingUMesh* cellMesh=initialMesh->getLevel0Mesh(false); + ParaMEDMEM::MEDCouplingUMesh* faceMesh=initialMesh->getLevelM1Mesh(false); + + cmd="mpirun -np 5 "+execName+" --ndomains=5 --split-method=metis"; //on same proc + sourceName=fileName; + targetName=fileName; + targetName.replace(targetName.find(".med"),4,"_partitionedTo5_"); + cmd+=" --input-file="+sourceName+" --output-file="+targetName+" --verbose="+IntToStr(_verbose); + if (_verbose) cout<<endl<<cmd<<endl; + res=system(cmd.c_str()); + CPPUNIT_ASSERT_EQUAL(0, res); + input=targetName+".xml"; + + MEDPARTITIONER::ParaDomainSelector parallelizer(false); + MEDPARTITIONER::MeshCollection collection(input,parallelizer); + CPPUNIT_ASSERT_EQUAL(3, collection.getMeshDimension()); + std::vector<ParaMEDMEM::MEDCouplingUMesh*>cellMeshes=collection.getMesh(); + CPPUNIT_ASSERT_EQUAL(5, (int) cellMeshes.size()); + int nbcells=0; + for (std::size_t i = 0; i < cellMeshes.size(); i++) + nbcells+=cellMeshes[i]->getNumberOfCells(); + CPPUNIT_ASSERT_EQUAL(cellMesh->getNumberOfCells(), nbcells); + + std::vector<ParaMEDMEM::MEDCouplingUMesh*>faceMeshes=collection.getFaceMesh(); + CPPUNIT_ASSERT_EQUAL(5, (int) faceMeshes.size()); + int nbfaces=0; + for (std::size_t i=0; i < faceMeshes.size(); i++) + nbfaces+=faceMeshes[i]->getNumberOfCells(); + CPPUNIT_ASSERT_EQUAL(faceMesh->getNumberOfCells(), nbfaces); + + //merge split meshes and test equality + cmd="mpirun -np 1 "+execName+" --ndomains=1 --split-method=metis"; //on same proc + sourceName=targetName+".xml"; + targetName=fileName; + targetName.replace(targetName.find(".med"),4,"_remergedFrom5_"); + cmd+=" --input-file="+sourceName+" --output-file="+targetName+" --verbose="+IntToStr(_verbose); + if (_verbose) cout<<endl<<cmd<<endl; + res=system(cmd.c_str()); + CPPUNIT_ASSERT_EQUAL(0, res); + + string refusedName=targetName+"1.med"; + ParaMEDMEM::MEDFileUMesh* refusedMesh=ParaMEDMEM::MEDFileUMesh::New(refusedName.c_str(),_mesh_name.c_str()); + ParaMEDMEM::MEDCouplingUMesh* refusedCellMesh=refusedMesh->getLevel0Mesh(false); + ParaMEDMEM::MEDCouplingUMesh* refusedFaceMesh=refusedMesh->getLevelM1Mesh(false); + + CPPUNIT_ASSERT_EQUAL(cellMesh->getNumberOfCells(), refusedCellMesh->getNumberOfCells()); + CPPUNIT_ASSERT_EQUAL(faceMesh->getNumberOfCells(), refusedFaceMesh->getNumberOfCells()); + + /*not the good job + ParaMEDMEM::MEDCouplingMesh* mergeCell=cellMesh->mergeMyselfWith(refusedCellMesh); + CPPUNIT_ASSERT_EQUAL(cellMesh->getNumberOfCells(), mergeCell->getNumberOfCells()); + + ParaMEDMEM::MEDCouplingMesh* mergeFace=faceMesh->mergeMyselfWith(refusedFaceMesh); + CPPUNIT_ASSERT_EQUAL(faceMesh->getNumberOfCells(), mergeFace->getNumberOfCells()); + + CPPUNIT_ASSERT(faceMesh->isEqual(refusedFaceMesh,1e-12)); + */ + + std::vector<const MEDCouplingUMesh *> meshes; + std::vector<DataArrayInt *> corr; + meshes.push_back(cellMesh); + refusedCellMesh->tryToShareSameCoordsPermute(*cellMesh, 1e-9); + meshes.push_back(refusedCellMesh); + MEDCouplingUMesh* fusedCell=MEDCouplingUMesh::FuseUMeshesOnSameCoords(meshes,0,corr); + CPPUNIT_ASSERT_EQUAL(cellMesh->getNumberOfCells(), fusedCell->getNumberOfCells()); + + meshes.resize(0); + for (std::size_t i = 0; i < corr.size(); i++) + corr[i]->decrRef(); + corr.resize(0); + meshes.push_back(faceMesh); + refusedFaceMesh->tryToShareSameCoordsPermute(*faceMesh, 1e-9); + meshes.push_back(refusedFaceMesh); + MEDCouplingUMesh* fusedFace=MEDCouplingUMesh::FuseUMeshesOnSameCoords(meshes,0,corr); + CPPUNIT_ASSERT_EQUAL(faceMesh->getNumberOfCells(), fusedFace->getNumberOfCells()); + + for (std::size_t i = 0; i < corr.size(); i++) + corr[i]->decrRef(); + fusedFace->decrRef(); + refusedFaceMesh->decrRef(); + faceMesh->decrRef(); + fusedCell->decrRef(); + refusedCellMesh->decrRef(); + cellMesh->decrRef(); + //done in ~collection + //for (int i = 0; i < faceMeshes.size(); i++) faceMeshes[i]->decrRef(); + //for (int i = 0; i < cellMeshes.size(); i++) cellMeshes[i]->decrRef(); +} + +void MEDPARTITIONERTest::verifyMedpartitionerOnSmallSizeForFieldOnCells() +{ + int res; + string fileName,cmd,execName,sourceName,targetName,input; + execName=getenv("MED_ROOT_DIR"); //.../INSTALL/MED + execName+="/bin/salome/medpartitioner_para"; + fileName=_file_name; + fileName.replace(fileName.find(".med"),4,"_WithVecFieldOnCells.med"); + + ParaMEDMEM::MEDFileUMesh* initialMesh=ParaMEDMEM::MEDFileUMesh::New(fileName.c_str(),_mesh_name.c_str()); + ParaMEDMEM::MEDCouplingUMesh* cellMesh=initialMesh->getLevel0Mesh(false); + + cmd="mpirun -np 5 "+execName+" --ndomains=5 --split-method=metis"; //on same proc + sourceName=fileName; + targetName=fileName; + targetName.replace(targetName.find(".med"),4,"_partitionedTo5_"); + cmd+=" --input-file="+sourceName+" --output-file="+targetName+" --verbose="+IntToStr(_verbose); + if (_verbose) cout<<endl<<cmd<<endl; + res=system(cmd.c_str()); + CPPUNIT_ASSERT_EQUAL(0, res); + input=targetName+".xml"; + + //merge split meshes and test equality + cmd="mpirun -np 1 "+execName+" --ndomains=1 --split-method=metis"; //on same proc + sourceName=targetName+".xml"; + targetName=fileName; + targetName.replace(targetName.find(".med"),4,"_remergedFrom5_"); + cmd+=" --input-file="+sourceName+" --output-file="+targetName+" --verbose="+IntToStr(_verbose); + if (_verbose) cout<<endl<<cmd<<endl; + res=system(cmd.c_str()); + CPPUNIT_ASSERT_EQUAL(0, res); + + string refusedName=targetName+"1.med"; + ParaMEDMEM::MEDFileUMesh* refusedMesh=ParaMEDMEM::MEDFileUMesh::New(refusedName.c_str(),_mesh_name.c_str()); + ParaMEDMEM::MEDCouplingUMesh* refusedCellMesh=refusedMesh->getLevel0Mesh(false); + + CPPUNIT_ASSERT_EQUAL(cellMesh->getNumberOfCells(), refusedCellMesh->getNumberOfCells()); + + std::vector<const MEDCouplingUMesh *> meshes; + std::vector<DataArrayInt *> corr; + meshes.push_back(cellMesh); + refusedCellMesh->tryToShareSameCoordsPermute(*cellMesh, 1e-9); + meshes.push_back(refusedCellMesh); + MEDCouplingUMesh* fusedCell=MEDCouplingUMesh::FuseUMeshesOnSameCoords(meshes,0,corr); + CPPUNIT_ASSERT_EQUAL(cellMesh->getNumberOfCells(), fusedCell->getNumberOfCells()); + + MEDCouplingFieldDouble* field1=MEDLoader::ReadFieldCell(fileName.c_str(),initialMesh->getName().c_str(),0,"VectorFieldOnCells",0,1); + MEDCouplingFieldDouble* field2=MEDLoader::ReadFieldCell(refusedName.c_str(),refusedCellMesh->getName().c_str(),0,"VectorFieldOnCells",0,1); + + int nbcells=corr[1]->getNumberOfTuples(); + CPPUNIT_ASSERT_EQUAL(cellMesh->getNumberOfCells(), nbcells); + //use corr to test equality of field + DataArrayDouble* f1=field1->getArray(); + DataArrayDouble* f2=field2->getArray(); + if (_verbose>300) + { + cout<<"\nf1 : "<<f1->reprZip(); + cout<<"\nf2 : "<<f2->reprZip(); //field2->advancedRepradvancedRepr(); + for (std::size_t i = 0; i < corr.size(); i++) + cout << "\ncorr " << i << " : " << corr[i]->reprZip(); + + } + int nbequal=0; + int nbcomp=field1->getNumberOfComponents(); + double* p1=f1->getPointer(); + double* p2=f2->getPointer(); + int* pc=corr[1]->getPointer(); + for (int i = 0; i < nbcells; i++) + { + int i1=pc[i]*nbcomp; + int i2=i*nbcomp; + for (int j = 0; j < nbcomp; j++) + { + if (p1[i1+j]==p2[i2+j]) nbequal++; + //cout<<" "<<p1[i1+j]<<"="<<p2[i2+j]; + } + } + CPPUNIT_ASSERT_EQUAL(nbcells*nbcomp, nbequal); + + for (std::size_t i = 0; i < corr.size(); i++) + corr[i]->decrRef(); + field1->decrRef(); + field2->decrRef(); + fusedCell->decrRef(); + refusedCellMesh->decrRef(); + cellMesh->decrRef(); +} + +void MEDPARTITIONERTest::verifyMedpartitionerOnSmallSizeForFieldOnGaussNe() +{ + int res; + string fileName,cmd,execName,sourceName,targetName,input; + execName=getenv("MED_ROOT_DIR"); //.../INSTALL/MED + execName+="/bin/salome/medpartitioner_para"; + fileName=_file_name; + fileName.replace(fileName.find(".med"),4,"_WithVecFieldOnGaussNe.med"); + + ParaMEDMEM::MEDFileUMesh* initialMesh=ParaMEDMEM::MEDFileUMesh::New(fileName.c_str(),_mesh_name.c_str()); + ParaMEDMEM::MEDCouplingUMesh* cellMesh=initialMesh->getLevel0Mesh(false); + + cmd="mpirun -np 5 "+execName+" --ndomains=5 --split-method=metis"; //on same proc + sourceName=fileName; + targetName=fileName; + targetName.replace(targetName.find(".med"),4,"_partitionedTo5_"); + cmd+=" --input-file="+sourceName+" --output-file="+targetName+" --verbose="+IntToStr(_verbose); + if (_verbose) cout<<endl<<cmd<<endl; + res=system(cmd.c_str()); + CPPUNIT_ASSERT_EQUAL(0, res); + input=targetName+".xml"; + + //merge split meshes and test equality + cmd="mpirun -np 1 "+execName+" --ndomains=1 --split-method=metis"; //on same proc + sourceName=targetName+".xml"; + targetName=fileName; + targetName.replace(targetName.find(".med"),4,"_remergedFrom5_"); + cmd+=" --input-file="+sourceName+" --output-file="+targetName+" --verbose="+IntToStr(_verbose); + if (_verbose) cout<<endl<<cmd<<endl; + res=system(cmd.c_str()); + CPPUNIT_ASSERT_EQUAL(0, res); + + string refusedName=targetName+"1.med"; + ParaMEDMEM::MEDFileUMesh* refusedMesh=ParaMEDMEM::MEDFileUMesh::New(refusedName.c_str(),_mesh_name.c_str()); + ParaMEDMEM::MEDCouplingUMesh* refusedCellMesh=refusedMesh->getLevel0Mesh(false); + + CPPUNIT_ASSERT_EQUAL(cellMesh->getNumberOfCells(), refusedCellMesh->getNumberOfCells()); + + std::vector<const MEDCouplingUMesh *> meshes; + std::vector<DataArrayInt *> corr; + meshes.push_back(cellMesh); + refusedCellMesh->tryToShareSameCoordsPermute(*cellMesh, 1e-9); + meshes.push_back(refusedCellMesh); + MEDCouplingUMesh* fusedCell=MEDCouplingUMesh::FuseUMeshesOnSameCoords(meshes,0,corr); + CPPUNIT_ASSERT_EQUAL(cellMesh->getNumberOfCells(), fusedCell->getNumberOfCells()); + + MEDCouplingFieldDouble* field1=MEDLoader::ReadField(ON_GAUSS_NE,fileName.c_str(),initialMesh->getName().c_str(),0,"MyFieldOnGaussNE",5,6); + MEDCouplingFieldDouble* field2=MEDLoader::ReadField(ON_GAUSS_NE,refusedName.c_str(),refusedCellMesh->getName().c_str(),0,"MyFieldOnGaussNE",5,6); + + int nbcells=corr[1]->getNumberOfTuples(); + CPPUNIT_ASSERT_EQUAL(cellMesh->getNumberOfCells(), nbcells); + //use corr to test equality of field + DataArrayDouble* f1=field1->getArray(); + DataArrayDouble* f2=field2->getArray(); + if (_verbose>300) + { + cout << "\nf1 : " << f1->reprZip(); //123.4 for 12th cell,3rd component, 4th gausspoint + cout << "\nf2 : " << f2->reprZip(); //field2->advancedRepradvancedRepr(); + for (std::size_t i = 0; i < corr.size(); i++) + cout << "\ncorr " << i << " : " << corr[i]->reprZip(); + + } + int nbequal=0; + int nbptgauss=8; + int nbcomp=field1->getNumberOfComponents(); + double* p1=f1->getPointer(); + double* p2=f2->getPointer(); + int* pc=corr[1]->getPointer(); + for (int i = 0; i < nbcells; i++) + { + int i1=pc[i]*nbcomp*nbptgauss; + int i2=i*nbcomp*nbptgauss; + for (int j = 0; j < nbcomp*nbptgauss; j++) + { + if (p1[i1+j]==p2[i2+j]) nbequal++; + //cout<<" "<<p1[i1+j]<<"="<<p2[i2+j]; + } + } + CPPUNIT_ASSERT_EQUAL(nbcells*nbcomp*nbptgauss, nbequal); + + for (std::size_t i = 0; i < corr.size(); i++) + corr[i]->decrRef(); + field1->decrRef(); + field2->decrRef(); + fusedCell->decrRef(); + refusedCellMesh->decrRef(); + cellMesh->decrRef(); +} + +void MEDPARTITIONERTest::launchMedpartitionerOnTestMeshes() +{ + + /* examples + export INFI=/home/vb144235/resources/blade.med + //no need export MESH=Fuse_1 + export INFI=tmp_testMeshxxx.med + //no need export MESH=testMesh + mpirun -np 2 medpartitioner_para --input-file=$INFI --output-file=ttmp1_ --ndomains=4 + mpirun -np 5 medpartitioner_para --input-file=ttmp1_.xml --output-file=ttmp2_ --ndomains=5 + mpirun -np 2 valgrind medpartitioner_para --input-file=tmp_testMesh_20x30x50.med --output-file=ttmp1petit_ --ndomains=4 --dump-cpu-memory --verbose=111 + */ + int res; + string cmd,execName,sourceName,targetName; + + res=system("which mpirun 2>/dev/null 1>/dev/null"); //no trace + CPPUNIT_ASSERT_EQUAL(0, res); + + execName=getenv("MED_ROOT_DIR"); //.../INSTALL/MED + execName+="/bin/salome/medpartitioner_para"; + + cmd="which "+execName+" 2>/dev/null 1>/dev/null"; //no trace + res=system(cmd.c_str()); + CPPUNIT_ASSERT_EQUAL(0, res); + + cmd="mpirun -np 2 "+execName+" --ndomains=2 --split-method=metis"; //on same proc + sourceName=_file_name; + targetName=_file_name; + targetName.replace(targetName.find(".med"),4,"_partitionedTo2_"); + cmd+=" --input-file="+sourceName+" --output-file="+targetName+" --verbose="+IntToStr(_verbose); + if (_verbose) cout<<endl<<cmd<<endl; + res=system(cmd.c_str()); + CPPUNIT_ASSERT_EQUAL(0, res); + + cmd="mpirun -np 3 "+execName+" --ndomains=5 --split-method=metis"; //on less proc + sourceName=_file_name; + targetName=_file_name; + targetName.replace(targetName.find(".med"),4,"_partitionedTo5_"); + cmd+=" --input-file="+sourceName+" --output-file="+targetName+" --verbose="+IntToStr(_verbose); + if (_verbose) cout<<endl<<cmd<<endl; + res=system(cmd.c_str()); + CPPUNIT_ASSERT_EQUAL(0, res); + + cmd="mpirun -np 1 "+execName+" --ndomains=1 --split-method=metis"; //on 1 proc + sourceName=targetName+".xml"; + targetName=_file_name; + targetName.replace(targetName.find(".med"),4,"_remergedFrom5_"); + cmd+=" --input-file="+sourceName+" --output-file="+targetName+" --verbose="+IntToStr(_verbose); + if (_verbose) cout<<endl<<cmd<<endl; + res=system(cmd.c_str()); + CPPUNIT_ASSERT_EQUAL(0, res); + + cmd="mpirun -np 8 "+execName+" --ndomains=1 --split-method=metis"; //on more proc + //sourceName=targetName+".xml"; + targetName=_file_name; + targetName.replace(targetName.find(".med"),4,"_remergedFrom5_"); + cmd+=" --input-file="+sourceName+" --output-file="+targetName+" --verbose="+IntToStr(_verbose); + if (_verbose) cout<<endl<<cmd<<endl; + res=system(cmd.c_str()); + CPPUNIT_ASSERT_EQUAL(0, res); +} + +void MEDPARTITIONERTest::launchMedpartitionerOnHugeTestMeshes() +{ + int res=0; + string cmd,execName,sourceName,targetName; + execName=getenv("MED_ROOT_DIR"); //.../INSTALL/MED + execName+="/bin/salome/medpartitioner_para"; + + string snbTarget=IntToStr(_nb_target_huge); + cmd="mpirun -np "+snbTarget+" "+execName+" --ndomains="+snbTarget+" --split-method=metis"; //on same proc + sourceName=_file_name_huge_xml; + targetName=_file_name_huge_xml; + string tmp="_partitionedTo"+snbTarget+"_"; + targetName.replace(targetName.find(".xml"),4,tmp); + cmd+=" --input-file="+sourceName+" --output-file="+targetName+" --verbose="+IntToStr(_verbose); + if (_verbose) cout<<endl<<cmd<<endl; + res=system(cmd.c_str()); + CPPUNIT_ASSERT_EQUAL(0, res); +} + +void MEDPARTITIONERTest::testMpirunSmallSize() +{ + setSmallSize(); + createTestMeshes(); + launchMedpartitionerOnTestMeshes(); + verifyMedpartitionerOnSmallSizeForMesh(); + verifyMedpartitionerOnSmallSizeForFieldOnCells(); + verifyMedpartitionerOnSmallSizeForFieldOnGaussNe(); +} + +void MEDPARTITIONERTest::testMpirunMedianSize() +{ + setMedianSize(); + createTestMeshes(); + launchMedpartitionerOnTestMeshes(); +} + +void MEDPARTITIONERTest::testMpirunHugeSize() +{ + //setBigSize(); //may be a lot for now + setMedianSize(); + //create a set of nbx*nby*nbz files mesh of ni*ny*nz cells + //_verbose=1; + createHugeTestMesh(_ni, _nj, _nk, 2, 2, 2, 32); //it is now to know how far we are going to test + launchMedpartitionerOnHugeTestMeshes(); +} +#endif diff --git a/src/medtool/src/MEDPartitioner/Test/TestMEDPARTITIONER.cxx b/src/medtool/src/MEDPartitioner/Test/TestMEDPARTITIONER.cxx new file mode 100644 index 000000000..a46dd0a4a --- /dev/null +++ b/src/medtool/src/MEDPartitioner/Test/TestMEDPARTITIONER.cxx @@ -0,0 +1,27 @@ +// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// + +//include all MEDPARTITIONER Test +#include "MEDPARTITIONERTest.hxx" + +//Registers the fixture into the 'registry' +CPPUNIT_TEST_SUITE_REGISTRATION( MEDPARTITIONERTest ); + +//generic Main program from KERNEL_SRC/src/Basics/Test +#include "BasicMainTest.hxx" diff --git a/src/medtool/src/MEDPartitioner/medpartitioner.cxx b/src/medtool/src/MEDPartitioner/medpartitioner.cxx new file mode 100644 index 000000000..48b90a7d4 --- /dev/null +++ b/src/medtool/src/MEDPartitioner/medpartitioner.cxx @@ -0,0 +1,310 @@ +// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 +// 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 +// + +/* + examples of launch + export verb=1 + medpartitioner --input-file=blade.med --output-file=ttmp1_ --ndomains=2 --dump-cpu-memory --verbose=$verb + medpartitioner --input-file=medpartitioner_blade.xml --output-file=ttmp1_ --ndomains=2 --dump-cpu-memory --verbose=$verb + medpartitioner --input-file=ttmp1_.xml --output-file=tttmp1_ --ndomains=4 --dump-cpu-memory --verbose=$verb +*/ + +/* +#include "MEDPARTITIONER_Graph.hxx" +#include "MEDPARTITIONER_Topology.hxx" +#include "MEDPARTITIONER_ParaDomainSelector.hxx" +#include "MEDPARTITIONER_MeshCollection.hxx" +#include "MEDPARTITIONER_Utils.hxx" +*/ + +#include "MEDPARTITIONER_MeshCollection.hxx" +#include "MEDPARTITIONER_ParallelTopology.hxx" +#include "MEDPARTITIONER_ParaDomainSelector.hxx" +#include "MEDPARTITIONER_Utils.hxx" + +#include <string> +#include <fstream> +#include <cstring> +#include <cstdlib> +#include <iostream> + +using namespace std; +using namespace MEDPARTITIONER; + +int main(int argc, char** argv) +{ +#if !defined(MED_ENABLE_METIS) && !defined(MED_ENABLE_SCOTCH) + std::cout << "Sorry, no one split method is available. Please, compile with METIS or SCOTCH." << std::endl; + return 1; +#else + + // Defining options + // by parsing the command line + + bool split_family=false; + bool empty_groups=false; + bool mesure_memory=false; + bool filter_face=true; + + string input; + string output; + string meshname; + string library="metis"; //default + int ndomains; + int help=0; + + //sequential : no MPI + MyGlobals::_World_Size=1; + MyGlobals::_Rank=0; + MyGlobals::_Creates_Boundary_Faces=0; + MyGlobals::_Create_Joints=0; + + // Primitive parsing of command-line options + string desc ("Available options of medpartitioner V1.0:\n" + "\t--help : produces this help message\n" + "\t--verbose : echoes arguments\n" + "\t--input-file=<string> : name of the input .med file or .xml master file\n" + "\t--output-file=<string> : name of the resulting file (without extension)\n" + "\t--ndomains=<number> : number of subdomains in the output file, default is 1\n" +#if defined(MED_ENABLE_METIS) && defined(MED_ENABLE_SCOTCH) + //user can choose! + "\t--split-method=<string> : name of the splitting library (metis/scotch), default is metis\n" +#endif + "\t--creates-boundary-faces : creates boundary faces mesh in the output files\n" + "\t--creates-joints : creates joints in the output files\n" + "\t--dump-cpu-memory : dumps passed CPU time and maximal increase of used memory\n" + ); + + if (argc<=1) help=1; + string value; + for (int i = 1; i < argc; i++) + { + if (strlen(argv[i]) < 3) + { + cerr << "bad argument : "<< argv[i] << endl; + return 1; + } + + if (TestArg(argv[i],"--verbose",value)) + { + MyGlobals::_Verbose=1; + if (value!="") MyGlobals::_Verbose = atoi(value.c_str()); + } + else if (TestArg(argv[i],"--help",value)) help=1; +// else if (TestArg(argv[i],"--test",value)) test=1; + else if (TestArg(argv[i],"--input-file",value)) input=value; + else if (TestArg(argv[i],"--output-file",value)) output=value; + else if (TestArg(argv[i],"--split-method",value)) library=value; + else if (TestArg(argv[i],"--ndomains",value)) ndomains=atoi(value.c_str()); + else if (TestArg(argv[i],"--creates-boundary-faces",value)) MyGlobals::_Creates_Boundary_Faces=1; + else if (TestArg(argv[i],"--create-joints",value)) MyGlobals::_Create_Joints=1; + else if (TestArg(argv[i],"--dump-cpu-memory",value)) mesure_memory=true; + else + { + cerr << "unknown argument : "<< argv[i] << endl; + return 1; + } + } + + MyGlobals::_Is0verbose=MyGlobals::_Verbose; + +//no choice +#if defined(MED_ENABLE_METIS) && !defined(MED_ENABLE_SCOTCH) + library = "metis"; +#endif +#if !defined(MED_ENABLE_METIS) && defined(MED_ENABLE_SCOTCH) + library = "scotch"; +#endif +//user choice +#if defined(MED_ENABLE_METIS) && defined(MED_ENABLE_SCOTCH) + if ((library!="metis") && (library!="scotch")) + { + cerr << "split-method only available : metis, scotch" << endl; + return 1; + } +#endif + + if (help==1) + { + cout<<desc<<"\n"; + return 0; + } + + if (MyGlobals::_Is0verbose) + { + cout << "medpartitioner V1.0 :" << endl; + cout << " input-file = " << input << endl; + cout << " output-file = " << output << endl; + cout << " split-method = " << library << endl; + cout << " ndomains = " << ndomains << endl; + cout << " creates_boundary_faces = " << MyGlobals::_Creates_Boundary_Faces << endl; + cout << " create-joints = " << MyGlobals::_Create_Joints<< endl; + cout << " dump-cpu-memory = " << mesure_memory<< endl; + cout << " verbose = " << MyGlobals::_Verbose << endl; + } + //testing whether it is possible to write a file at the specified location + if (MyGlobals::_Rank==0) + { + string outputtest = output + ".testioms."; + ofstream testfile (outputtest.c_str()); + if (testfile.fail()) + { + cerr << "output-file directory does not exist or is in read-only access" << endl; + return 1; + } + //deletes test file + remove(outputtest.c_str()); + } + + // Beginning of the computation + + // Loading the mesh collection + if (MyGlobals::_Is0verbose) cout << "Reading input files "<<endl; + + try + { + /*MEDPARTITIONER::ParaDomainSelector parallelizer(mesure_memory); + MEDPARTITIONER::MeshCollection collection(input,parallelizer); + MEDPARTITIONER::ParallelTopology* aPT = (MEDPARTITIONER::ParallelTopology*) collection.getTopology(); + aPT->setGlobalNumerotationDefault(collection.getParaDomainSelector()); + //int nbfiles=MyGlobals::_fileMedNames->size(); //nb domains + //to have unique valid fields names/pointers/descriptions for partitionning + collection.prepareFieldDescriptions(); + //int nbfields=collection.getFieldDescriptions().size(); //on all domains + //cout<<ReprVectorOfString(collection.getFieldDescriptions()); + + if (MyGlobals::_Is0verbose) + { + cout<<"fileNames :"<<endl + <<ReprVectorOfString(MyGlobals::_File_Names); + cout<<"fieldDescriptions :"<<endl + <<ReprFieldDescriptions(collection.getFieldDescriptions()," "); //cvwat07 + cout<<"familyInfo :\n" + <<ReprMapOfStringInt(collection.getFamilyInfo())<<endl; + cout<<"groupInfo :\n" + <<ReprMapOfStringVectorOfString(collection.getGroupInfo())<<endl; + }*/ + MEDPARTITIONER::ParaDomainSelector parallelizer(mesure_memory); + MEDPARTITIONER::MeshCollection collection(input,parallelizer); + MEDPARTITIONER::ParallelTopology* aPT = (MEDPARTITIONER::ParallelTopology*) collection.getTopology(); + aPT->setGlobalNumerotationDefault(collection.getParaDomainSelector()); + //to have unique valid fields names/pointers/descriptions for partitionning + collection.prepareFieldDescriptions(); + + //MEDPARTITIONER::MeshCollection collection(input); + + //Creating the graph and partitioning it + if (MyGlobals::_Is0verbose) cout << "Computing partition with " << library << endl; + + auto_ptr< MEDPARTITIONER::Topology > new_topo; + if (library == "metis") + new_topo.reset( collection.createPartition(ndomains,MEDPARTITIONER::Graph::METIS)); + else + new_topo.reset( collection.createPartition(ndomains,MEDPARTITIONER::Graph::SCOTCH)); + parallelizer.evaluateMemory(); + + //Creating a new mesh collection from the partitioning + if (MyGlobals::_Is0verbose) cout << "Creating new meshes"<< endl; + MEDPARTITIONER::MeshCollection new_collection(collection,new_topo.get(),split_family,empty_groups); + + if (filter_face) new_collection.filterFaceOnCell(); + + //to get infos on all procs + + //see meshName + vector<string> finalInformations; + vector<string> r1,r2; + //r1=AllgathervVectorOfString(MyGlobals::_General_Informations); + r1=MyGlobals::_General_Informations; + //if (MyGlobals::_Is0verbose>1000) cout << "generalInformations : \n"<<ReprVectorOfString(r1); + r2=SelectTagsInVectorOfString(r1,"ioldDomain="); + r2=SelectTagsInVectorOfString(r2,"meshName="); + if (r2.size()==(collection.getMesh()).size()) + { + for (std::size_t i=0; i<r2.size(); i++) + r2[i]=EraseTagSerialized(r2[i],"ioldDomain="); + r2=DeleteDuplicatesInVectorOfString(r2); + if (r2.size()==1) + { + string finalMesh="finalMeshName="+ExtractFromDescription(r2[0], "meshName="); + finalInformations.push_back(SerializeFromString(finalMesh)); + } + } + if (finalInformations.size()==0) + { + if (MyGlobals::_Rank==0) + cerr<<"Problem on final meshName : set at 'Merge'"<<endl; + finalInformations.push_back(SerializeFromString("finalMeshName=Merge")); + } + + //see field info nbComponents & componentInfo (if fields present) + r2=SelectTagsInVectorOfString(r1,"fieldName="); + r2=SelectTagsInVectorOfString(r2,"nbComponents="); + //may be yes? or not? + for (std::size_t i=0; i<r2.size(); i++) + r2[i]=EraseTagSerialized(r2[i],"ioldFieldDouble="); + r2=DeleteDuplicatesInVectorOfString(r2); + for (std::size_t i=0; i<r2.size(); i++) + finalInformations.push_back(r2[i]); + + MyGlobals::_General_Informations=finalInformations; + if (MyGlobals::_Is0verbose) + cout << "generalInformations : \n"<<ReprVectorOfString(finalInformations); + + //new_collection.setSubdomainBoundaryCreates(creates_boundary_faces); + if (MyGlobals::_Is0verbose) cout << "Writing "<<ndomains<<" output files "<<output<<"xx.med"<<" and "<<output<<".xml"<<endl; + new_collection.write(output); + + /*if ( mesure_memory ) + if ( parallelizer.isOnDifferentHosts() || MyGlobals::_Rank==0 ) + { + cout << "Elapsed time = " << parallelizer.getPassedTime() + << ", max memory usage = " << parallelizer.evaluateMemory() << " KB" + << endl; + }*/ + + if (MyGlobals::_Is0verbose>0) cout<<"OK END"<< endl; + return 0; + } + catch(const char *mess) + { + cerr<<mess<<endl; + fflush(stderr); + return 1; + } + catch(INTERP_KERNEL::Exception& e) + { + cerr<<"INTERP_KERNEL_Exception : "<<e.what()<<endl; + fflush(stderr); + return 1; + } + catch(std::exception& e) + { + cerr<<"std_Exception : "<<e.what()<<endl; + fflush(stderr); + return 1; + } + catch(...) + { + cerr<<"an unknown type exception error was occured"<<endl; + fflush(stderr); + return 1; + } +#endif +} diff --git a/src/medtool/src/MEDPartitioner/medpartitioner_para.cxx b/src/medtool/src/MEDPartitioner/medpartitioner_para.cxx new file mode 100644 index 000000000..60c3295d2 --- /dev/null +++ b/src/medtool/src/MEDPartitioner/medpartitioner_para.cxx @@ -0,0 +1,353 @@ +// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 +// 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 +// + +/* + examples of launch + rm ttmp* tttmp* + export verb=11 + mpirun -np 2 medpartitioner_para --input-file=blade.med --output-file=ttmp1_ --ndomains=2 --dump-cpu-memory --verbose=$verb + mpirun -np 5 medpartitioner_para --input-file=blade.med --output-file=ttmp1_ --ndomains=2 --dump-cpu-memory --verbose=$verb + mpirun -np 4 medpartitioner_para --input-file=ttmp1_.xml --output-file=tttmp1_ --ndomains=4 --verbose=$verb + + mpirun -np 2 medpartitioner_para --ndomains=2 --input-file=tmp_testMesh_20x30x50.med --output-file=ttmp2_ --verbose=$verb + mpirun -np 2 medpartitioner_para --ndomains=2 --input-file=ttmp2_.xml --output-file=ttmp3_ --verbose=$verb + + mpirun -np 2 medpartitioner_para --ndomains=2 --input-file=tmp_testMeshWithFaces_20x30x50.med --output-file=ttmp2_ --verbose=$verb + mpirun -np 2 medpartitioner_para --ndomains=2 --input-file=ttmp2_.xml --output-file=ttmp3_ --verbose=$verb + + mpirun -np 2 medpartitioner_para --ndomains=2 --input-file=tmp_testMesh_20x30x50_WithVecFieldOnCells.med --output-file=ttmp2_ --verbose=$verb + mpirun -np 2 medpartitioner_para --ndomains=2 --input-file=tmp_testMesh_20x30x50_WithVecFieldOnNodes.med --output-file=ttmp2_ --verbose=$verb + mpirun -np 2 medpartitioner_para --ndomains=2 --input-file=ttmp2_.xml --output-file=ttmp3_ --verbose=$verb + + mpirun -np 4 medpartitioner_para --ndomains=4 --input-file=tmp_testMeshHuge_20x30x50_6.xml --output-file=ttmp3_ --verbose=1 +*/ + + +#include "MEDPARTITIONER_MeshCollection.hxx" +#include "MEDPARTITIONER_ParallelTopology.hxx" +#include "MEDPARTITIONER_ParaDomainSelector.hxx" +#include "MEDPARTITIONER_Utils.hxx" + +#include "MEDLoader.hxx" + +#include <fstream> +#include <iostream> +#include <iomanip> +#include <sstream> +#include <string> +#include <cstring> + +#ifdef HAVE_MPI +#include <mpi.h> +#endif + +using namespace std; +using namespace MEDPARTITIONER; + +int main(int argc, char** argv) +{ +#if !defined(MED_ENABLE_PARMETIS) + cout << "Sorry, no one split method is available. Please, compile with ParMETIS."<<endl; + return 1; +#else + + // Defining options + // by parsing the command line + + bool split_family=false; + bool empty_groups=false; + bool mesure_memory=false; + bool filter_face=true; + + string input; + string output; + string meshname; + string library="metis"; //default + int ndomains; + int help=0; + int test=0; + MPI_Init(&argc,&argv); + MPI_Comm_size(MPI_COMM_WORLD, &MyGlobals::_World_Size); + MPI_Comm_rank(MPI_COMM_WORLD, &MyGlobals::_Rank); + + //cout<<"proc "<<MyGlobals::_Rank<<" of "<<MyGlobals::_World_Size<<endl; //for debug + //TestVectorOfStringMpi(); //cvw + //TestRandomize(); + + //Primitive parsing of command-line options + string desc ("Available options of medpartitioner_para V1.0.3:\n" + "\t--help : produces this help message\n" + "\t--verbose : echoes arguments\n" + "\t--input-file=<string> : name of the input .med file or .xml master file\n" + "\t--output-file=<string> : name of the resulting file (without extension)\n" + "\t--ndomains=<number> : number of subdomains in the output file, default is 1\n" +#if defined(MED_ENABLE_PARMETIS) +// || defined(MED_ENABLE_PTSCOTCH) +//user can choose! (not yet) + "\t--split-method=<string> : name of the splitting library (metis/scotch), default is metis\n" +#endif + "\t--creates-boundary-faces : creates boundary faces mesh in the output files\n" + "\t--dump-cpu-memory : dumps passed CPU time and maximal increase of used memory\n" + //"\t--randomize=<number> : random seed for other partitionning (only on one proc)\n" + //"\t--atomize : do the opposite of a good partitionner (only on one proc)\n" + ); + + if (argc<=1) help=1; + string value; + for (int i = 1; i < argc; i++) + { + if (strlen(argv[i]) < 3) + { + if (MyGlobals::_Rank==0) cerr << "bad argument : "<< argv[i] << endl; + MPI_Finalize(); return 1; + } + + if (TestArg(argv[i],"--verbose",value)) + { + MyGlobals::_Verbose=1; + if (value!="") MyGlobals::_Verbose = atoi(value.c_str()); + } + else if (TestArg(argv[i],"--help",value)) help=1; + else if (TestArg(argv[i],"--test",value)) test=1; + else if (TestArg(argv[i],"--input-file",value)) input=value; + else if (TestArg(argv[i],"--output-file",value)) output=value; + else if (TestArg(argv[i],"--split-method",value)) library=value; + else if (TestArg(argv[i],"--ndomains",value)) ndomains=atoi(value.c_str()); + else if (TestArg(argv[i],"--randomize",value)) MyGlobals::_Randomize=atoi(value.c_str()); + else if (TestArg(argv[i],"--atomize",value)) MyGlobals::_Atomize=atoi(value.c_str()); + else if (TestArg(argv[i],"--creates-boundary-faces",value)) MyGlobals::_Creates_Boundary_Faces=1; + else if (TestArg(argv[i],"--dump-cpu-memory",value)) mesure_memory=true; + else + { + if (MyGlobals::_Rank==0) cerr << "unknown argument : "<< argv[i] << endl; + MPI_Finalize(); return 1; + } + } + + + if (MyGlobals::_Randomize!=0 && MyGlobals::_World_Size!=1) + { + if (MyGlobals::_Rank==0) cerr << "randomize only available on 1 proc (mpirun -np 1)" << endl; + MyGlobals::_Randomize=0; + } + +//no choice +#if defined(MED_ENABLE_PARMETIS) && !defined(MED_ENABLE_SCOTCH) + library = "metis"; +#endif +#if !defined(MED_ENABLE_PARMETIS) && defined(MED_ENABLE_SCOTCH) + library = "scotch"; +#endif +//user choice +#if defined(MED_ENABLE_PARMETIS) && defined(MED_ENABLE_SCOTCH) + if ((library!="metis") && (library!="scotch")) + { + if (MyGlobals::_Rank==0) cerr << "split-method only available : metis, scotch" << endl; + MPI_Finalize(); return 1; + } +#endif + + if (help==1) + { + if (MyGlobals::_Rank==0) cout<<desc<<"\n"; + MPI_Finalize(); return 0; + } + + MyGlobals::_Is0verbose=0; + if (MyGlobals::_Rank==0) MyGlobals::_Is0verbose=MyGlobals::_Verbose; + //MyGlobals::_Is0verbose=((MyGlobals::_Rank==0) && MyGlobals::_Verbose); + if (test==1) //only for debugger + { + if (MyGlobals::_Is0verbose>0) cout<<"tests on "<<MyGlobals::_Atomize<<" "<<ndomains<<endl; + //TestPersistantMpi0To1(MyGlobals::_Atomize, ndomains); + //TestPersistantMpiRing(MyGlobals::_Atomize, ndomains); + TestPersistantMpiRingOnCommSplit(MyGlobals::_Atomize, ndomains); + //MPI_Barrier(MPI_COMM_WORLD); + MPI_Finalize(); + return 0; + TestVectorOfStringMpi(); + TestMapOfStringIntMpi(); + TestMapOfStringVectorOfStringMpi(); + TestDataArrayMpi(); + MPI_Finalize(); + return 1; + } + + if (MyGlobals::_Is0verbose) + { + cout << "medpartitioner_para V1.0 :" << endl; + cout << " input-file = " << input << endl; + cout << " output-file = " << output << endl; + cout << " split-method = " << library << endl; + cout << " ndomains = " << ndomains << endl; + cout << " creates_boundary_faces = " << MyGlobals::_Creates_Boundary_Faces << endl; + cout << " dump-cpu-memory = " << mesure_memory<< endl; + cout << " verbose = " << MyGlobals::_Verbose << endl; + } + //testing whether it is possible to write a file at the specified location + if (MyGlobals::_Rank==0) + { + string outputtest = output + ".testioms."; + ofstream testfile (outputtest.c_str()); + if (testfile.fail()) + { + cerr << "output-file directory does not exist or is in read-only access" << endl; + MPI_Finalize(); return 1; + } + //deletes test file + remove(outputtest.c_str()); + } + + // Beginning of the computation + + // Loading the mesh collection + if (MyGlobals::_Is0verbose) cout << "Reading input files "<<endl; + + try + { + MEDPARTITIONER::ParaDomainSelector parallelizer(mesure_memory); + MEDPARTITIONER::MeshCollection collection(input,parallelizer); + MEDPARTITIONER::ParallelTopology* aPT = (MEDPARTITIONER::ParallelTopology*) collection.getTopology(); + aPT->setGlobalNumerotationDefault(collection.getParaDomainSelector()); + //int nbfiles=MyGlobals::_fileMedNames->size(); //nb domains + //to have unique valid fields names/pointers/descriptions for partitionning + collection.prepareFieldDescriptions(); + //int nbfields=collection.getFieldDescriptions().size(); //on all domains + //cout<<ReprVectorOfString(collection.getFieldDescriptions()); + + if (MyGlobals::_Is0verbose) + { + cout<<"fileNames :"<<endl + <<ReprVectorOfString(MyGlobals::_File_Names); + cout<<"fieldDescriptions :"<<endl + <<ReprFieldDescriptions(collection.getFieldDescriptions()," "); + cout<<"familyInfo :\n" + <<ReprMapOfStringInt(collection.getFamilyInfo())<<endl; + cout<<"groupInfo :\n" + <<ReprMapOfStringVectorOfString(collection.getGroupInfo())<<endl; + } + + //Creating the graph and partitioning it + if (MyGlobals::_Is0verbose) cout << "Computing partition "<< endl; + + auto_ptr< MEDPARTITIONER::Topology > new_topo; + if (library == "metis") + new_topo.reset( collection.createPartition(ndomains,MEDPARTITIONER::Graph::METIS)); + else + new_topo.reset( collection.createPartition(ndomains,MEDPARTITIONER::Graph::SCOTCH)); + parallelizer.evaluateMemory(); + + //Creating a new mesh collection from the partitioning + if (MyGlobals::_Is0verbose) cout << "Creating new meshes"<< endl; + MEDPARTITIONER::MeshCollection new_collection(collection,new_topo.get(),split_family,empty_groups); + //cout<<"proc "<<MyGlobals::_Rank<<" : new_collection done"<<endl; + parallelizer.evaluateMemory(); + + //if (!xml_output_master) new_collection.setDriverType(MEDPARTITIONER::MedAscii); + if (filter_face) new_collection.filterFaceOnCell(); + + //to get infos on all procs + + //see meshName + vector<string> finalInformations; + vector<string> r1,r2; + r1=AllgathervVectorOfString(MyGlobals::_General_Informations); + //if (MyGlobals::_Is0verbose>1000) cout << "generalInformations : \n"<<ReprVectorOfString(r1); + r2=SelectTagsInVectorOfString(r1,"ioldDomain="); + r2=SelectTagsInVectorOfString(r2,"meshName="); + if (r2.size()==(collection.getMesh()).size()) + { + for (std::size_t i=0; i<r2.size(); i++) + r2[i]=EraseTagSerialized(r2[i],"ioldDomain="); + r2=DeleteDuplicatesInVectorOfString(r2); + if (r2.size()==1) + { + string finalMesh="finalMeshName="+ExtractFromDescription(r2[0], "meshName="); + finalInformations.push_back(SerializeFromString(finalMesh)); + } + } + if (finalInformations.size()==0) + { + if (MyGlobals::_Rank==0) + cerr<<"Problem on final meshName : set at 'Merge'"<<endl; + finalInformations.push_back(SerializeFromString("finalMeshName=Merge")); + } + + //see field info nbComponents & componentInfo (if fields present) + r2=SelectTagsInVectorOfString(r1,"fieldName="); + r2=SelectTagsInVectorOfString(r2,"nbComponents="); + //may be yes? or not? + for (std::size_t i=0; i<r2.size(); i++) + r2[i]=EraseTagSerialized(r2[i],"ioldFieldDouble="); + r2=DeleteDuplicatesInVectorOfString(r2); + for (std::size_t i=0; i<r2.size(); i++) + finalInformations.push_back(r2[i]); + + MyGlobals::_General_Informations=finalInformations; + if (MyGlobals::_Is0verbose) + cout << "generalInformations : \n"<<ReprVectorOfString(finalInformations); + + //new_collection.setSubdomainBoundaryCreates(creates_boundary_faces); + if (MyGlobals::_Is0verbose) cout << "Writing "<<ndomains<<" output files "<<output<<"xx.med"<<" and "<<output<<".xml"<<endl; + new_collection.write(output); + + if ( mesure_memory ) + if ( parallelizer.isOnDifferentHosts() || MyGlobals::_Rank==0 ) + { + cout << "Elapsed time = " << parallelizer.getPassedTime() + << ", max memory usage = " << parallelizer.evaluateMemory() << " KB" + << endl; + } + if(MyGlobals::_World_Size>1) + MPI_Barrier(MPI_COMM_WORLD); + if (MyGlobals::_Is0verbose>0) cout<<"OK END"<< endl; + MPI_Finalize(); + return 0; + } + catch(const char *mess) + { + cerr<<"proc "<<MyGlobals::_Rank<<" : "<<mess<<endl; + fflush(stderr); + MPI_Finalize(); + return 1; + } + catch(INTERP_KERNEL::Exception& e) + { + cerr<<"proc "<<MyGlobals::_Rank<<" : INTERP_KERNEL_Exception : "<<e.what()<<endl; + fflush(stderr); + MPI_Finalize(); + return 1; + } + catch(std::exception& e) + { + cerr<<"proc "<<MyGlobals::_Rank<<" : std_Exception : "<<e.what()<<endl; + fflush(stderr); + MPI_Finalize(); + return 1; + } + catch(...) + { + cerr<<"proc "<<MyGlobals::_Rank<<" : an unknown type exception error was occured"<<endl; + fflush(stderr); + MPI_Finalize(); + return 1; + } +#endif +} + diff --git a/src/medtool/src/MEDPartitioner_Swig/CMakeLists.txt b/src/medtool/src/MEDPartitioner_Swig/CMakeLists.txt new file mode 100644 index 000000000..a8079c250 --- /dev/null +++ b/src/medtool/src/MEDPartitioner_Swig/CMakeLists.txt @@ -0,0 +1,76 @@ +# Copyright (C) 2012-2015 CEA/DEN, EDF 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, 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 +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +# +# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +# + +INCLUDE(${SWIG_USE_FILE}) + +ADD_DEFINITIONS(${PYTHON_DEFINITIONS} ${HDF5_DEFINITIONS} ${MEDFILE_DEFINITIONS} ) + +SET_SOURCE_FILES_PROPERTIES(MEDPartitioner.i PROPERTIES CPLUSPLUS ON) +SET_SOURCE_FILES_PROPERTIES(MEDPartitioner.i PROPERTIES SWIG_DEFINITIONS "-shadow") +SET(SWIG_MODULE_MEDPartitioner_EXTRA_FLAGS "${SWIG_EXTRA_FLAGS_FOR_NUMPYANDSCIPY};-DWITHOUT_AUTOFIELD") + +SET (MEDPartitioner_SWIG_DPYS_FILES + MEDPartitionerCommon.i) + +INCLUDE_DIRECTORIES( + ${PYTHON_INCLUDE_DIRS} + ${PTHREAD_INCLUDE_DIR} # pthread dependancy due to python2.7 library + ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_CURRENT_BINARY_DIR} + ${HDF5_INCLUDE_DIRS} + ${MEDFILE_INCLUDE_DIRS} + ${CMAKE_CURRENT_SOURCE_DIR}/../MEDPartitioner + ${CMAKE_CURRENT_SOURCE_DIR}/../MEDCoupling_Swig + ${CMAKE_CURRENT_SOURCE_DIR}/../MEDCoupling + ${CMAKE_CURRENT_SOURCE_DIR}/../MEDLoader + ${CMAKE_CURRENT_SOURCE_DIR}/../MEDLoader/Swig + ${CMAKE_CURRENT_SOURCE_DIR}/../INTERP_KERNEL + ${CMAKE_CURRENT_SOURCE_DIR}/../INTERP_KERNEL/Bases + ${CMAKE_CURRENT_SOURCE_DIR}/../INTERP_KERNEL/Geometric2D + ${CMAKE_CURRENT_SOURCE_DIR}/../INTERP_KERNEL/ExprEval + ${CMAKE_CURRENT_SOURCE_DIR}/../INTERP_KERNEL/GaussPoints + ) + +SWIG_ADD_MODULE(MEDPartitioner python MEDPartitioner.i) +SWIG_LINK_LIBRARIES(MEDPartitioner ${PYTHON_LIBRARIES} ${PLATFORM_LIBS} medpartitionercpp) + +IF(WIN32) + SET_TARGET_PROPERTIES(_MEDPartitioner PROPERTIES DEBUG_OUTPUT_NAME _MEDPartitioner_d) +ENDIF(WIN32) +INSTALL(TARGETS ${SWIG_MODULE_MEDPartitioner_REAL_NAME} DESTINATION ${MEDTOOL_INSTALL_PYTHON}) + +SET(PYFILES_TO_INSTALL ${CMAKE_CURRENT_BINARY_DIR}/MEDPartitioner.py) +#SALOME_INSTALL_SCRIPTS("${PYFILES_TO_INSTALL}" ${SALOME_INSTALL_SCRIPT_PYTHON}) +INSTALL(FILES "${PYFILES_TO_INSTALL}" DESTINATION ${MEDTOOL_INSTALL_SCRIPT_PYTHON}) + +INSTALL(FILES MEDPartitioner.i MEDPartitionerCommon.i DESTINATION ${MEDTOOL_INSTALL_HEADERS}) +INSTALL(FILES MEDPartitionerTest.py DESTINATION ${MEDTOOL_INSTALL_SCRIPT_PYTHON}) + +#SALOME_GENERATE_TESTS_ENVIRONMENT(tests_env) +ADD_TEST(MEDPartitionerTest ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/MEDPartitionerTest.py) +SET_TESTS_PROPERTIES(MEDPartitionerTest PROPERTIES ENVIRONMENT "${tests_env}") + +# Application tests + +SET(TEST_INSTALL_DIRECTORY ${MEDTOOL_INSTALL_SCRIPT_SCRIPTS}/test/MEDCoupling/MEDPartitioner_Swig) +INSTALL(FILES MEDPartitionerTest.py DESTINATION ${TEST_INSTALL_DIRECTORY}) + +INSTALL(FILES CTestTestfileInstall.cmake + DESTINATION ${TEST_INSTALL_DIRECTORY} + RENAME CTestTestfile.cmake) diff --git a/src/medtool/src/MEDPartitioner_Swig/CTestTestfileInstall.cmake b/src/medtool/src/MEDPartitioner_Swig/CTestTestfileInstall.cmake new file mode 100644 index 000000000..2100e6bf0 --- /dev/null +++ b/src/medtool/src/MEDPartitioner_Swig/CTestTestfileInstall.cmake @@ -0,0 +1,21 @@ +# Copyright (C) 2015 CEA/DEN, EDF 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, 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 +# 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_TEST(MEDPartitionerTest python MEDPartitionerTest.py) +SET_TESTS_PROPERTIES(MEDPartitionerTest PROPERTIES LABELS "${COMPONENT_NAME}") diff --git a/src/medtool/src/MEDPartitioner_Swig/MEDPartitioner.i b/src/medtool/src/MEDPartitioner_Swig/MEDPartitioner.i new file mode 100644 index 000000000..13f6d9ca9 --- /dev/null +++ b/src/medtool/src/MEDPartitioner_Swig/MEDPartitioner.i @@ -0,0 +1,140 @@ +// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// + +%include "MEDPartitionerCommon.i" + + +// %pythoncode %{ +// def ParaMEDMEMDataArrayDoublenew(cls,*args): +// import _MEDPartitioner +// return _MEDPartitioner.DataArrayDouble____new___(cls,args) +// def ParaMEDMEMDataArrayDoubleIadd(self,*args): +// import _MEDPartitioner +// return _MEDPartitioner.DataArrayDouble____iadd___(self, self, *args) +// def ParaMEDMEMDataArrayDoubleIsub(self,*args): +// import _MEDPartitioner +// return _MEDPartitioner.DataArrayDouble____isub___(self, self, *args) +// def ParaMEDMEMDataArrayDoubleImul(self,*args): +// import _MEDPartitioner +// return _MEDPartitioner.DataArrayDouble____imul___(self, self, *args) +// def ParaMEDMEMDataArrayDoubleIdiv(self,*args): +// import _MEDPartitioner +// return _MEDPartitioner.DataArrayDouble____idiv___(self, self, *args) +// def ParaMEDMEMDataArrayDoubleIpow(self,*args): +// import _MEDPartitioner +// return _MEDPartitioner.DataArrayDouble____ipow___(self, self, *args) +// def ParaMEDMEMDataArrayIntnew(cls,*args): +// import _MEDPartitioner +// return _MEDPartitioner.DataArrayInt____new___(cls,args) +// def ParaMEDMEMDataArrayIntIadd(self,*args): +// import _MEDPartitioner +// return _MEDPartitioner.DataArrayInt____iadd___(self, self, *args) +// def ParaMEDMEMDataArrayIntIsub(self,*args): +// import _MEDPartitioner +// return _MEDPartitioner.DataArrayInt____isub___(self, self, *args) +// def ParaMEDMEMDataArrayIntImul(self,*args): +// import _MEDPartitioner +// return _MEDPartitioner.DataArrayInt____imul___(self, self, *args) +// def ParaMEDMEMDataArrayIntIdiv(self,*args): +// import _MEDPartitioner +// return _MEDPartitioner.DataArrayInt____idiv___(self, self, *args) +// def ParaMEDMEMDataArrayIntImod(self,*args): +// import _MEDPartitioner +// return _MEDPartitioner.DataArrayInt____imod___(self, self, *args) +// def ParaMEDMEMDataArrayIntIpow(self,*args): +// import _MEDPartitioner +// return _MEDPartitioner.DataArrayInt____ipow___(self, self, *args) +// def ParaMEDMEMDataArrayDoubleTupleIadd(self,*args): +// import _MEDPartitioner +// return _MEDPartitioner.DataArrayDoubleTuple____iadd___(self, self, *args) +// def ParaMEDMEMDataArrayDoubleTupleIsub(self,*args): +// import _MEDPartitioner +// return _MEDPartitioner.DataArrayDoubleTuple____isub___(self, self, *args) +// def ParaMEDMEMDataArrayDoubleTupleImul(self,*args): +// import _MEDPartitioner +// return _MEDPartitioner.DataArrayDoubleTuple____imul___(self, self, *args) +// def ParaMEDMEMDataArrayDoubleTupleIdiv(self,*args): +// import _MEDPartitioner +// return _MEDPartitioner.DataArrayDoubleTuple____idiv___(self, self, *args) +// def ParaMEDMEMDataArrayIntTupleIadd(self,*args): +// import _MEDPartitioner +// return _MEDPartitioner.DataArrayIntTuple____iadd___(self, self, *args) +// def ParaMEDMEMDataArrayIntTupleIsub(self,*args): +// import _MEDPartitioner +// return _MEDPartitioner.DataArrayIntTuple____isub___(self, self, *args) +// def ParaMEDMEMDataArrayIntTupleImul(self,*args): +// import _MEDPartitioner +// return _MEDPartitioner.DataArrayIntTuple____imul___(self, self, *args) +// def ParaMEDMEMDataArrayIntTupleIdiv(self,*args): +// import _MEDPartitioner +// return _MEDPartitioner.DataArrayIntTuple____idiv___(self, self, *args) +// def ParaMEDMEMDataArrayIntTupleImod(self,*args): +// import _MEDPartitioner +// return _MEDPartitioner.DataArrayIntTuple____imod___(self, self, *args) +// %} + + +// %pythoncode %{ +// DataArrayDouble.__new__=classmethod(ParaMEDMEMDataArrayDoublenew) +// DataArrayDouble.__iadd__=ParaMEDMEMDataArrayDoubleIadd +// DataArrayDouble.__isub__=ParaMEDMEMDataArrayDoubleIsub +// DataArrayDouble.__imul__=ParaMEDMEMDataArrayDoubleImul +// DataArrayDouble.__idiv__=ParaMEDMEMDataArrayDoubleIdiv +// DataArrayDouble.__ipow__=ParaMEDMEMDataArrayDoubleIpow + +// DataArrayInt.__new__=classmethod(ParaMEDMEMDataArrayIntnew) +// DataArrayInt.__iadd__=ParaMEDMEMDataArrayIntIadd +// DataArrayInt.__isub__=ParaMEDMEMDataArrayIntIsub +// DataArrayInt.__imul__=ParaMEDMEMDataArrayIntImul +// DataArrayInt.__idiv__=ParaMEDMEMDataArrayIntIdiv +// DataArrayInt.__imod__=ParaMEDMEMDataArrayIntImod +// DataArrayInt.__ipow__=ParaMEDMEMDataArrayIntIpow + +// DataArrayDoubleTuple.__iadd__=ParaMEDMEMDataArrayDoubleTupleIadd +// DataArrayDoubleTuple.__isub__=ParaMEDMEMDataArrayDoubleTupleIsub +// DataArrayDoubleTuple.__imul__=ParaMEDMEMDataArrayDoubleTupleImul +// DataArrayDoubleTuple.__idiv__=ParaMEDMEMDataArrayDoubleTupleIdiv + +// DataArrayIntTuple.__iadd__=ParaMEDMEMDataArrayIntTupleIadd +// DataArrayIntTuple.__isub__=ParaMEDMEMDataArrayIntTupleIsub +// DataArrayIntTuple.__imul__=ParaMEDMEMDataArrayIntTupleImul +// DataArrayIntTuple.__idiv__=ParaMEDMEMDataArrayIntTupleIdiv +// DataArrayIntTuple.__imod__=ParaMEDMEMDataArrayIntTupleImod + +// del ParaMEDMEMDataArrayDoublenew +// del ParaMEDMEMDataArrayDoubleIadd +// del ParaMEDMEMDataArrayDoubleIsub +// del ParaMEDMEMDataArrayDoubleImul +// del ParaMEDMEMDataArrayDoubleIdiv +// del ParaMEDMEMDataArrayIntnew +// del ParaMEDMEMDataArrayIntIadd +// del ParaMEDMEMDataArrayIntIsub +// del ParaMEDMEMDataArrayIntImul +// del ParaMEDMEMDataArrayIntIdiv +// del ParaMEDMEMDataArrayIntImod +// del ParaMEDMEMDataArrayDoubleTupleIadd +// del ParaMEDMEMDataArrayDoubleTupleIsub +// del ParaMEDMEMDataArrayDoubleTupleImul +// del ParaMEDMEMDataArrayDoubleTupleIdiv +// del ParaMEDMEMDataArrayIntTupleIadd +// del ParaMEDMEMDataArrayIntTupleIsub +// del ParaMEDMEMDataArrayIntTupleImul +// del ParaMEDMEMDataArrayIntTupleIdiv +// del ParaMEDMEMDataArrayIntTupleImod +// %} diff --git a/src/medtool/src/MEDPartitioner_Swig/MEDPartitionerCommon.i b/src/medtool/src/MEDPartitioner_Swig/MEDPartitionerCommon.i new file mode 100644 index 000000000..93a390a81 --- /dev/null +++ b/src/medtool/src/MEDPartitioner_Swig/MEDPartitionerCommon.i @@ -0,0 +1,70 @@ +// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 +// 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 +// + +%module MEDPartitioner + +%include std_string.i + +%{ +#include "MEDFileData.hxx" + +#include "MEDPARTITIONER_MEDPartitioner.hxx" +#include "MEDPARTITIONER.hxx" +#include "MEDPARTITIONER_Graph.hxx" + +using namespace ParaMEDMEM; +using namespace INTERP_KERNEL; +using namespace MEDPARTITIONER; +%} + +%feature("autodoc", "1"); +%feature("docstring"); + +%newobject MEDPARTITIONER::MEDPartitioner::New; +%newobject MEDPARTITIONER::MEDPartitioner::Graph; +%newobject MEDPARTITIONER::MEDPartitioner::getMEDFileData; +%feature("unref") ParaMEDMEM::MEDFileData "$this->decrRef();" + +%nodefaultctor; + +%rename (InterpKernelException) INTERP_KERNEL::Exception; + +namespace MEDPARTITIONER +{ + class Graph + { + public: + virtual void partGraph(int ndomain, const std::string& options_string="", ParaDomainSelector *sel=0) throw(INTERP_KERNEL::Exception); + const ParaMEDMEM::MEDCouplingSkyLineArray *getGraph() const; + const ParaMEDMEM::MEDCouplingSkyLineArray *getPartition() const; + int nbVertices() const; + }; + + class MEDPartitioner + { + public: + MEDPartitioner(const std::string& filename, int ndomains=1, const std::string& library="metis",bool creates_boundary_faces=false, bool create_joints=false, bool mesure_memory=false) throw(INTERP_KERNEL::Exception); + MEDPartitioner(const ParaMEDMEM::MEDFileData* fileData, int ndomains=1, const std::string& library="metis",bool creates_boundary_faces=false, bool create_joints=false, bool mesure_memory=false) throw(INTERP_KERNEL::Exception); + MEDPartitioner(const ParaMEDMEM::MEDFileData* fileData, Graph* graph, bool creates_boundary_faces=false, bool create_joints=false, bool mesure_memory=false) throw(INTERP_KERNEL::Exception); + static MEDPARTITIONER::Graph* Graph(ParaMEDMEM::MEDCouplingSkyLineArray* graph, Graph::splitter_type split=Graph::METIS, int* edgeweight=0) throw(INTERP_KERNEL::Exception); + ParaMEDMEM::MEDFileData* getMEDFileData() throw(INTERP_KERNEL::Exception); + void write(const std::string& filename) throw(INTERP_KERNEL::Exception); + }; +} + diff --git a/src/medtool/src/MEDPartitioner_Swig/MEDPartitionerTest.py b/src/medtool/src/MEDPartitioner_Swig/MEDPartitionerTest.py new file mode 100644 index 000000000..8ad3c3064 --- /dev/null +++ b/src/medtool/src/MEDPartitioner_Swig/MEDPartitionerTest.py @@ -0,0 +1,100 @@ +# Copyright (C) 2012-2015 CEA/DEN, EDF 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, 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 +# 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 +# + +from MEDPartitioner import * +from MEDLoader import * +import unittest +from MEDLoaderDataForTest import MEDLoaderDataForTest + +class MEDPartitionerTest(unittest.TestCase): + def testPartition(self): + fname="PyPartitionTest.med" + data=MEDLoaderDataForTest.buildACompleteMEDDataStructureWithFieldsOnCells_1() + data.write(fname,2) + part_file=MEDPartitioner(fname,2) + part_data=MEDPartitioner(data,2) + part_file.write("splitted_PyPartitionTest_1") + part_data.write("splitted_PyPartitionTest_2") + part_file_xml=MEDPartitioner("splitted_PyPartitionTest_1.xml") + part_data_xml=MEDPartitioner("splitted_PyPartitionTest_2.xml") + data1=part_file_xml.getMEDFileData() + data2=part_data_xml.getMEDFileData() + m1d=data1.getMeshes().getMeshAtPos(0) + m2d=data2.getMeshes().getMeshAtPos(0) + self.assertTrue(m1d.isEqual(m2d,1e-12)) + pass + def testPartitionGraph(self): + data=MEDLoaderDataForTest.buildACompleteMEDDataStructureWithFieldsOnCells_1() + m=data.getMeshes().getMeshAtPos(0) + graph=MEDPartitioner.Graph(m.getLevel0Mesh().generateGraph()) + graph.partGraph(2) + tool=MEDPartitioner(data,graph) + data2=tool.getMEDFileData() + self.assertEqual( 2, data2.getMeshes().getNumberOfMeshes() ) + pass + def testPartitionWithJoints(self): + # cartesian mesh 4x4 + arr=DataArrayDouble(5) ; arr.iota() + c=MEDCouplingCMesh() ; c.setCoords(arr,arr) + m=c.buildUnstructured() + m.setName("mesh") + mm=MEDFileUMesh() + mm.setMeshAtLevel(0,m) + ms=MEDFileMeshes() ; ms.pushMesh(mm) + data=MEDFileData() + data.setMeshes(ms) + part_file=MEDPartitioner(data,4,"metis",True,True,True) + data_file=part_file.getMEDFileData() + meshes=data_file.getMeshes() + self.assertEqual( 4, meshes.getNumberOfMeshes()) + self.assertEqual( 3, meshes.getMeshAtPos(0).getJoints().getNumberOfJoints()) + self.assertEqual( 3, meshes.getMeshAtPos(1).getJoints().getNumberOfJoints()) + self.assertEqual( 3, meshes.getMeshAtPos(2).getJoints().getNumberOfJoints()) + self.assertEqual( 3, meshes.getMeshAtPos(3).getJoints().getNumberOfJoints()) + joints=meshes.getMeshAtPos(0).getJoints() + self.assertEqual( 1, joints.getJointAtPos(0).getDomainNumber(), 1) + self.assertEqual( 2, joints.getJointAtPos(1).getDomainNumber(), 2) + self.assertEqual( 3, joints.getJointAtPos(2).getDomainNumber(), 3) + self.assertEqual( 2, joints.getJointAtPos(0).getStepAtPos(0).getNumberOfCorrespondences()) + self.assertEqual( 2, joints.getJointAtPos(1).getStepAtPos(0).getNumberOfCorrespondences()) + self.assertEqual( 1, joints.getJointAtPos(2).getStepAtPos(0).getNumberOfCorrespondences()) + found=0 + for ii in xrange(joints.getJointAtPos(0).getStepAtPos(0).getNumberOfCorrespondences()): + correspond=joints.getJointAtPos(0).getStepAtPos(0).getCorrespondenceAtPos(ii) + if correspond.getCorrespondence().isEqual(DataArrayInt([1,3,2,4])): + found+=1 + self.assertEqual(NORM_QUAD4, correspond.getLocalGeometryType()) + self.assertEqual(NORM_QUAD4, correspond.getRemoteGeometryType()) + pass + pass + self.assertEqual(1,found) + pass + def testPartitionPartGraph(self): + arr=DataArrayDouble(5) ; arr.iota() + c=MEDCouplingCMesh() ; c.setCoords(arr,arr) + m=c.buildUnstructured() + part=MEDPartitioner.Graph(m.generateGraph()) + part.partGraph(2) + a=part.getGraph() + p=part.getPartition() + self.assertTrue(isinstance(a,MEDCouplingSkyLineArray)) + self.assertTrue(isinstance(p,MEDCouplingSkyLineArray)) + self.assertTrue(part.nbVertices() > 0 ) + pass +unittest.main() diff --git a/src/medtool/src/ParaMEDMEMTest/CMakeLists.txt b/src/medtool/src/ParaMEDMEMTest/CMakeLists.txt new file mode 100644 index 000000000..aa4336d0d --- /dev/null +++ b/src/medtool/src/ParaMEDMEMTest/CMakeLists.txt @@ -0,0 +1,137 @@ +# Copyright (C) 2012-2015 CEA/DEN, EDF 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, 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 +# 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_DEFINITIONS(${MPI_DEFINITIONS} ${CPPUNIT_DEFINITIONS}) + +INCLUDE_DIRECTORIES( + ${MPI_INCLUDE_DIRS} + ${CPPUNIT_INCLUDE_DIRS} + ${CMAKE_CURRENT_SOURCE_DIR}/../ParaMEDLoader + ${CMAKE_CURRENT_SOURCE_DIR}/../ParaMEDMEM + ${CMAKE_CURRENT_SOURCE_DIR}/../MEDLoader + ${CMAKE_CURRENT_SOURCE_DIR}/../MEDCoupling + ${CMAKE_CURRENT_SOURCE_DIR}/../INTERP_KERNEL + ${CMAKE_CURRENT_SOURCE_DIR}/../INTERP_KERNEL/Bases + ) + +SET(ParaMEDMEMTest_SOURCES + ParaMEDMEMTest.cxx + ParaMEDMEMTest_MPIProcessorGroup.cxx + ParaMEDMEMTest_BlockTopology.cxx + ParaMEDMEMTest_InterpKernelDEC.cxx + ParaMEDMEMTest_StructuredCoincidentDEC.cxx + ParaMEDMEMTest_MEDLoader.cxx + ParaMEDMEMTest_ICoco.cxx + ParaMEDMEMTest_Gauthier1.cxx + ParaMEDMEMTest_FabienAPI.cxx + ParaMEDMEMTest_NonCoincidentDEC.cxx + ParaMEDMEMTest_OverlapDEC.cxx + MPIAccessDECTest.cxx + test_AllToAllDEC.cxx + test_AllToAllvDEC.cxx + test_AllToAllTimeDEC.cxx + test_AllToAllvTimeDEC.cxx + test_AllToAllvTimeDoubleDEC.cxx + MPIAccessTest.cxx + test_MPI_Access_Send_Recv.cxx + test_MPI_Access_Cyclic_Send_Recv.cxx + test_MPI_Access_SendRecv.cxx + test_MPI_Access_ISend_IRecv.cxx + test_MPI_Access_Cyclic_ISend_IRecv.cxx + test_MPI_Access_ISendRecv.cxx + test_MPI_Access_Probe.cxx + test_MPI_Access_IProbe.cxx + test_MPI_Access_Cancel.cxx + test_MPI_Access_Send_Recv_Length.cxx + test_MPI_Access_ISend_IRecv_Length.cxx + test_MPI_Access_ISend_IRecv_Length_1.cxx + test_MPI_Access_Time.cxx + test_MPI_Access_Time_0.cxx + test_MPI_Access_ISend_IRecv_BottleNeck.cxx + ) + +ADD_LIBRARY(ParaMEDMEMTest SHARED ${ParaMEDMEMTest_SOURCES}) +SET_TARGET_PROPERTIES(ParaMEDMEMTest PROPERTIES COMPILE_FLAGS "") +TARGET_LINK_LIBRARIES(ParaMEDMEMTest paramedmem paramedloader ${CPPUNIT_LIBRARIES}) +INSTALL(TARGETS ParaMEDMEMTest DESTINATION ${MEDTOOL_INSTALL_LIBS}) + +SET(TESTSParaMEDMEM) +SET(TestParaMEDMEM_SOURCES + TestParaMEDMEM.cxx + ) +SET(TESTSParaMEDMEM ${TESTSParaMEDMEM} TestParaMEDMEM) + +SET(TestMPIAccessDEC_SOURCES + TestMPIAccessDEC.cxx + ) +SET(TESTSParaMEDMEM ${TESTSParaMEDMEM} TestMPIAccessDEC) + +SET(TestMPIAccess_SOURCES + TestMPIAccess.cxx + ) +SET(TESTSParaMEDMEM ${TESTSParaMEDMEM} TestMPIAccess) + +SET(test_perf_SOURCES + test_perf.cxx + ) +SET(TESTSParaMEDMEM ${TESTSParaMEDMEM} test_perf) + +IF(MPI2_IS_OK) + SET(ParaMEDMEMTestMPI2_1_SOURCES + MPI2Connector.cxx + ParaMEDMEMTestMPI2_1.cxx + ) + SET(TESTSParaMEDMEM ${TESTSParaMEDMEM} ParaMEDMEMTestMPI2_1) + + SET(ParaMEDMEMTestMPI2_2_SOURCES + MPI2Connector.cxx + ParaMEDMEMTestMPI2_2.cxx + ) + SET(TESTSParaMEDMEM ${TESTSParaMEDMEM} ParaMEDMEMTestMPI2_2) +ENDIF(MPI2_IS_OK) + +FOREACH(bintestparamem ${TESTSParaMEDMEM}) + ADD_EXECUTABLE(${bintestparamem} ${${bintestparamem}_SOURCES}) + TARGET_LINK_LIBRARIES(${bintestparamem} ParaMEDMEMTest) +ENDFOREACH(bintestparamem ${TESTSParaMEDMEM}) + +# Now add CMake tests - test_perf, ParaMEDMEMTestMPI2_1 and ParaMEDMEMTestMPI2_2 +# are left aside, as they are too specific +# +# -- some tests require 2, 3, 4 or 5 procs -- +ADD_TEST(NAME TestParaMEDMEM_Proc2 COMMAND ${MPIEXEC} -np 2 $<TARGET_FILE:TestParaMEDMEM>) +ADD_TEST(NAME TestParaMEDMEM_Proc3 COMMAND ${MPIEXEC} -np 3 $<TARGET_FILE:TestParaMEDMEM>) +ADD_TEST(NAME TestParaMEDMEM_Proc4 COMMAND ${MPIEXEC} -np 4 $<TARGET_FILE:TestParaMEDMEM>) +ADD_TEST(NAME TestParaMEDMEM_Proc5 COMMAND ${MPIEXEC} -np 5 $<TARGET_FILE:TestParaMEDMEM>) + +ADD_TEST(NAME TestMPIAccess_Proc2 COMMAND ${MPIEXEC} -np 2 $<TARGET_FILE:TestMPIAccess>) +ADD_TEST(NAME TestMPIAccess_Proc3 COMMAND ${MPIEXEC} -np 3 $<TARGET_FILE:TestMPIAccess>) + +ADD_TEST(NAME TestMPIAccessDEC_Proc4 COMMAND ${MPIEXEC} -np 4 $<TARGET_FILE:TestMPIAccessDEC>) + +# Installation rules +INSTALL(TARGETS ${TESTSParaMEDMEM} DESTINATION ${MEDTOOL_INSTALL_BINS}) +SET(COMMON_HEADERS_HXX + MPIMainTest.hxx + MPIAccessDECTest.hxx + MPIAccessTest.hxx + ParaMEDMEMTest.hxx + MPI2Connector.hxx +) +INSTALL(FILES ${COMMON_HEADERS_HXX} DESTINATION ${MEDTOOL_INSTALL_HEADERS}) diff --git a/src/medtool/src/RENUMBER/CMakeLists.txt b/src/medtool/src/RENUMBER/CMakeLists.txt new file mode 100644 index 000000000..baef96da9 --- /dev/null +++ b/src/medtool/src/RENUMBER/CMakeLists.txt @@ -0,0 +1,96 @@ +# Copyright (C) 2012-2015 CEA/DEN, EDF 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, 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 +# 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_DEFINITIONS(${HDF5_DEFINITIONS} ${BOOST_DEFINITIONS} ${MEDFILE_DEFINITIONS}) + +IF(Boost_FOUND) + ADD_DEFINITIONS("-DENABLE_BOOST") +ENDIF(Boost_FOUND) + +# Include directories +INCLUDE_DIRECTORIES( + ${MEDFILE_INCLUDE_DIRS} + ${HDF5_INCLUDE_DIRS} + ${CMAKE_CURRENT_SOURCE_DIR}/../MEDLoader + ${CMAKE_CURRENT_SOURCE_DIR}/../MEDCoupling + ${CMAKE_CURRENT_SOURCE_DIR}/../INTERP_KERNEL + ${CMAKE_CURRENT_SOURCE_DIR}/../INTERP_KERNEL/Bases + ${CMAKE_CURRENT_SOURCE_DIR}/../INTERP_KERNEL/Geometric2D + ${CMAKE_CURRENT_SOURCE_DIR}/../INTERP_KERNEL/ExprEval + ${CMAKE_CURRENT_SOURCE_DIR}/../INTERP_KERNEL/GaussPoints + ) + +IF(SALOME_USE_MPI) + ADD_DEFINITIONS(${MPI_DEFINITIONS}) + INCLUDE_DIRECTORIES(${MPI_INCLUDE_DIRS}) +ENDIF(SALOME_USE_MPI) + +SET(renumbercpp_HEADERS_HXX + RENUMBER_Renumbering.hxx + RenumberingFactory.hxx + RENUMBERDefines.hxx + ) + +SET(renumbercpp_SOURCES + RENUMBER_Renumbering.cxx + RenumberingFactory.cxx + ) + +SET(renumber_SOURCES + renumbering.cxx + ) + +SET(renumbercpp_LDFLAGS medloader) + +IF(PARMETIS_FOUND) + INCLUDE_DIRECTORIES(${PARMETIS_INCLUDE_DIRS}) +ENDIF(PARMETIS_FOUND) + +IF(METIS_FOUND) + INCLUDE_DIRECTORIES(${METIS_INCLUDE_DIRS}) + + SET(renumbercpp_SOURCES ${renumbercpp_SOURCES} RENUMBER_METISRenumbering.cxx) + SET(renumbercpp_HEADERS_HXX ${renumbercpp_HEADERS_HXX} RENUMBER_METISRenumbering.hxx) + SET(renumbercpp_LDFLAGS ${renumbercpp_LDFLAGS} ${METIS_LIBRARIES}) + SET(renumber_DEFINITIONS "${renumber_DEFINITIONS} ${METIS_DEFINITIONS}") +ENDIF(METIS_FOUND) + +IF(Boost_FOUND) + INCLUDE_DIRECTORIES(${Boost_INCLUDE_DIRS}) + + SET(renumbercpp_SOURCES ${renumbercpp_SOURCES} RENUMBER_BOOSTRenumbering.cxx) + SET(renumbercpp_HEADERS_HXX ${renumbercpp_HEADERS_HXX} RENUMBER_BOOSTRenumbering.hxx) + SET(renumbercpp_LDFLAGS ${renumbercpp_LDFLAGS} ${BOOST_LIBRARIES}) +ENDIF(Boost_FOUND) + +IF(SALOME_USE_MPI) + SET(renumbercpp_LDFLAGS ${renumbercpp_LDFLAGS} ${MPI_LIBRARIES}) +ENDIF(SALOME_USE_MPI) + +ADD_EXECUTABLE(renumber ${renumber_SOURCES}) +SET_TARGET_PROPERTIES(renumber PROPERTIES COMPILE_FLAGS "${renumber_DEFINITIONS}") +TARGET_LINK_LIBRARIES(renumber renumbercpp) +INSTALL(TARGETS renumber DESTINATION ${MEDTOOL_INSTALL_BINS}) + +ADD_LIBRARY(renumbercpp SHARED ${renumbercpp_SOURCES}) +SET_TARGET_PROPERTIES(renumbercpp PROPERTIES COMPILE_FLAGS "${renumber_DEFINITIONS}") +TARGET_LINK_LIBRARIES(renumbercpp ${renumbercpp_LDFLAGS}) +INSTALL(TARGETS renumbercpp DESTINATION ${MEDTOOL_INSTALL_LIBS}) + +INSTALL(FILES ${renumbercpp_HEADERS_HXX} DESTINATION ${MEDTOOL_INSTALL_HEADERS}) diff --git a/src/medtool/src/RENUMBER/RENUMBERDefines.hxx b/src/medtool/src/RENUMBER/RENUMBERDefines.hxx new file mode 100755 index 000000000..144284283 --- /dev/null +++ b/src/medtool/src/RENUMBER/RENUMBERDefines.hxx @@ -0,0 +1,34 @@ +// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 +// 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 __RENUMBERDEFINES_HXX__ +#define __RENUMBERDEFINES_HXX__ + +//export symbols +#ifdef WIN32 +# if defined RENUMBERCPP_EXPORTS || defined renumbercpp_EXPORTS +# define RENUMBER_EXPORT __declspec(dllexport) +# else +# define RENUMBER_EXPORT __declspec(dllimport) +# endif +#else +# define RENUMBER_EXPORT +#endif + +#endif // __RENUMBERDEFINES_HXX__ diff --git a/src/medtool/src/RENUMBER/RENUMBER_BOOSTRenumbering.cxx b/src/medtool/src/RENUMBER/RENUMBER_BOOSTRenumbering.cxx new file mode 100644 index 000000000..8b0f45885 --- /dev/null +++ b/src/medtool/src/RENUMBER/RENUMBER_BOOSTRenumbering.cxx @@ -0,0 +1,55 @@ +// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// + +#include "RENUMBER_BOOSTRenumbering.hxx" + +#include "MEDCouplingMemArray.hxx" +#include "MEDCouplingAutoRefCountObjectPtr.hxx" + +#include <boost/config.hpp> +#include <boost/graph/adjacency_list.hpp> +#include <boost/graph/cuthill_mckee_ordering.hpp> +#include <boost/graph/properties.hpp> +#include <boost/graph/bandwidth.hpp> + +void BOOSTRenumbering::renumber(const int *graph, const int *index_graph, int nbCell, ParaMEDMEM::DataArrayInt *&iperm, ParaMEDMEM::DataArrayInt *&perm) +{ + ParaMEDMEM::MEDCouplingAutoRefCountObjectPtr<ParaMEDMEM::DataArrayInt> out0(ParaMEDMEM::DataArrayInt::New()),out1(ParaMEDMEM::DataArrayInt::New()); + out0->alloc(nbCell,1); out1->alloc(nbCell,1); + out0->fillWithZero(); out1->fillWithZero(); + // + typedef boost::adjacency_list<boost::vecS, boost::vecS, boost::undirectedS, + boost::property<boost::vertex_color_t, boost::default_color_type, + boost::property<boost::vertex_degree_t,int> > > Graph; + typedef boost::graph_traits<Graph>::vertex_descriptor Vertex; + typedef boost::graph_traits<Graph>::vertices_size_type size_type; + Graph G(nbCell); + for (int i=0;i<nbCell;++i) + for (int j=index_graph[i];j<index_graph[i+1];++j) + add_edge(i,graph[j],G); + boost::property_map<Graph, boost::vertex_index_t>::type + index_map = boost::get(boost::vertex_index, G); + boost::cuthill_mckee_ordering(G, out0->getPointer(), boost::get(boost::vertex_color, G), + boost::make_degree_map(G)); + int *out0Ptr(out0->getPointer()),*out1Ptr(out1->getPointer()); + for(int c=0;c!=nbCell;++c) + out1Ptr[index_map[out0Ptr[nbCell-c-1]]]=c; + out0->reverse(); + iperm=out0.retn(); perm=out1.retn(); +} diff --git a/src/medtool/src/RENUMBER/RENUMBER_BOOSTRenumbering.hxx b/src/medtool/src/RENUMBER/RENUMBER_BOOSTRenumbering.hxx new file mode 100644 index 000000000..31e7d1eba --- /dev/null +++ b/src/medtool/src/RENUMBER/RENUMBER_BOOSTRenumbering.hxx @@ -0,0 +1,32 @@ +// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 +// 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 __BOOSTRENUMBERING_HXX__ +#define __BOOSTRENUMBERING_HXX__ + +#include "RENUMBERDefines.hxx" +#include "RENUMBER_Renumbering.hxx" + +class RENUMBER_EXPORT BOOSTRenumbering:public Renumbering +{ +public: + void renumber(const int *graph, const int *index_graph, int nbCell, ParaMEDMEM::DataArrayInt *&iperm, ParaMEDMEM::DataArrayInt *&perm); +}; + +#endif /*BOOSTRENUMBERING_HXX_*/ diff --git a/src/medtool/src/RENUMBER/RENUMBER_METISRenumbering.cxx b/src/medtool/src/RENUMBER/RENUMBER_METISRenumbering.cxx new file mode 100644 index 000000000..66820b686 --- /dev/null +++ b/src/medtool/src/RENUMBER/RENUMBER_METISRenumbering.cxx @@ -0,0 +1,45 @@ +// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 +// 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 +// + +#ifdef MED_ENABLE_PARMETIS +// include parmetis.h even if it is not needed here +// to avoid inclusion of c++ definitions within extern "C" +// from metis.h from parmetis.h from mpi.h(openmpi) from mpicxx.h +#include <parmetis.h> +#endif +extern "C" +{ +#include "metis.h" +} + +#include "MEDCouplingMemArray.hxx" +#include "MEDCouplingAutoRefCountObjectPtr.hxx" + +#include "RENUMBER_METISRenumbering.hxx" + +void METISRenumbering::renumber(const int *graph, const int *index_graph, int nbCell, ParaMEDMEM::DataArrayInt *&iperm, ParaMEDMEM::DataArrayInt *&perm) +{ + ParaMEDMEM::MEDCouplingAutoRefCountObjectPtr<ParaMEDMEM::DataArrayInt> out0(ParaMEDMEM::DataArrayInt::New()),out1(ParaMEDMEM::DataArrayInt::New()); + out0->alloc(nbCell,1); out1->alloc(nbCell,1); + out0->fillWithZero(); out1->fillWithZero(); + int num_flag=1; + int options=0; + METIS_NodeND(&nbCell,(int*)index_graph,(int*)graph,&num_flag,&options,out0->getPointer(),out1->getPointer()); + iperm=out0.retn(); perm=out1.retn(); +} diff --git a/src/medtool/src/RENUMBER/RENUMBER_METISRenumbering.hxx b/src/medtool/src/RENUMBER/RENUMBER_METISRenumbering.hxx new file mode 100644 index 000000000..ca20175eb --- /dev/null +++ b/src/medtool/src/RENUMBER/RENUMBER_METISRenumbering.hxx @@ -0,0 +1,32 @@ +// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 +// 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 __METISRENUMBERING_HXX__ +#define __METISRENUMBERING_HXX__ + +#include "RENUMBERDefines.hxx" +#include "RENUMBER_Renumbering.hxx" + +class RENUMBER_EXPORT METISRenumbering:public Renumbering +{ +public: + virtual void renumber(const int *graph, const int *index_graph, int nb_cell, ParaMEDMEM::DataArrayInt *&iperm, ParaMEDMEM::DataArrayInt *&perm); +}; + +#endif /*METISRENUMBERING_HXX_*/ diff --git a/src/medtool/src/RENUMBER/RENUMBER_Renumbering.cxx b/src/medtool/src/RENUMBER/RENUMBER_Renumbering.cxx new file mode 100644 index 000000000..84fa3bfae --- /dev/null +++ b/src/medtool/src/RENUMBER/RENUMBER_Renumbering.cxx @@ -0,0 +1,19 @@ +// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 +// 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 +// + diff --git a/src/medtool/src/RENUMBER/RENUMBER_Renumbering.hxx b/src/medtool/src/RENUMBER/RENUMBER_Renumbering.hxx new file mode 100644 index 000000000..6c21ee45c --- /dev/null +++ b/src/medtool/src/RENUMBER/RENUMBER_Renumbering.hxx @@ -0,0 +1,37 @@ +// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 +// 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 RENUMBERING_HXX_ +#define RENUMBERING_HXX_ +#include "RENUMBERDefines.hxx" +#include <vector> + +namespace ParaMEDMEM +{ + class DataArrayInt; +} + +class RENUMBER_EXPORT Renumbering +{ +public: + virtual void renumber(const int *graph, const int *index_graph, int nbCell, ParaMEDMEM::DataArrayInt *&iperm, ParaMEDMEM::DataArrayInt *&perm) = 0; + virtual ~Renumbering() { } +}; + +#endif /*RENUMBERING_HXX_*/ diff --git a/src/medtool/src/RENUMBER/RenumberingFactory.cxx b/src/medtool/src/RENUMBER/RenumberingFactory.cxx new file mode 100644 index 000000000..50cb5d146 --- /dev/null +++ b/src/medtool/src/RENUMBER/RenumberingFactory.cxx @@ -0,0 +1,83 @@ +// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// + +#include "RenumberingFactory.hxx" +#include "RENUMBER_Renumbering.hxx" +#ifdef MED_ENABLE_METIS +#include "RENUMBER_METISRenumbering.hxx" +#endif +#ifdef ENABLE_BOOST +#include "RENUMBER_BOOSTRenumbering.hxx" +#endif + +#include <iostream> + +using namespace std; + +namespace MED_RENUMBER +{ + Renumbering* RenumberingFactory(const string &s) + { +#ifdef MED_ENABLE_METIS +#ifdef ENABLE_BOOST + if (s=="METIS") + { + return new METISRenumbering; + } + else if(s=="BOOST") + { + return new BOOSTRenumbering; + } + else + { + std::cerr << "The method has to be METIS or BOOST" << std::endl; + return 0; + } +#endif +#ifndef ENABLE_BOOST + if (s=="METIS") + { + return new METISRenumbering; + } + else + { + std::cerr << "The method has to be METIS!" << std::endl; + return 0; + } +#endif +#endif +#ifndef MED_ENABLE_METIS +#ifdef ENABLE_BOOST + if (s=="BOOST") + { + return new BOOSTRenumbering; + } + else + { + std::cerr << "The method has to be BOOST!" << std::endl; + return 0; + } +#endif +#ifndef ENABLE_BOOST + std::cerr << "Error, no method compiled" << std::endl; + return 0; +#endif +#endif + } +} diff --git a/src/medtool/src/RENUMBER/RenumberingFactory.hxx b/src/medtool/src/RENUMBER/RenumberingFactory.hxx new file mode 100644 index 000000000..0ba3d5578 --- /dev/null +++ b/src/medtool/src/RENUMBER/RenumberingFactory.hxx @@ -0,0 +1,33 @@ +// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 +// 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 __RENUMBERINGFACTORY_HXX__ +#define __RENUMBERINGFACTORY_HXX__ + +#include "RENUMBERDefines.hxx" +#include "RENUMBER_Renumbering.hxx" + +#include <string> + +namespace MED_RENUMBER +{ + RENUMBER_EXPORT Renumbering* RenumberingFactory(const std::string& s); +} + +#endif /*RENUMBERINGFACTORY_HXX_*/ diff --git a/src/medtool/src/RENUMBER/renumbering.cxx b/src/medtool/src/RENUMBER/renumbering.cxx new file mode 100644 index 000000000..1fd4e3b73 --- /dev/null +++ b/src/medtool/src/RENUMBER/renumbering.cxx @@ -0,0 +1,128 @@ +// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// + +#include "MEDFileData.hxx" +#include "MEDFileMesh.hxx" +#include "MEDFileField.hxx" + +#include "MEDCouplingUMesh.hxx" + +#include "RenumberingFactory.hxx" + +#include <time.h> +#include <string> +#include <cstdlib> +#include <fstream> +#include <iostream> + +using namespace std; +using namespace ParaMEDMEM; +using namespace MED_RENUMBER; + +int main(int argc, char** argv) +{ + double t_begin,t_read_st,t_compute_graph,t_family,t_field; + t_begin=clock(); + if (argc <5) + { + cerr << "Usage : " << argv[0] + << " filename_in meshname method[BOOST/METIS] filename_out" << endl << endl; + return -1; + } + string filename_in = argv[1]; + string meshname = argv[2]; + string type_renum = argv[3]; + string filename_out = argv[4]; + + if(type_renum!="METIS" && type_renum!="BOOST") + { + cout << "The method has to be METIS or BOOST!" << endl; + return -1; + } + // Reading file structure + cout << "Reading : " << flush; + MEDCouplingAutoRefCountObjectPtr<MEDFileData> fd(MEDFileData::New(filename_in)); + MEDFileMesh *m=fd->getMeshes()->getMeshWithName(meshname); + MEDFileUMesh *mc=dynamic_cast<MEDFileUMesh *>(m); + if(!mc) + { + std::ostringstream oss; oss << "In file \"" << filename_in << "\" the mesh name \"" << meshname<< "\" exists but is not unstructured !"; + throw INTERP_KERNEL::Exception(oss.str().c_str()); + } + t_read_st=clock(); + cout << (t_read_st-t_begin)/(double) CLOCKS_PER_SEC << "s" << endl << flush; + // Reading mesh + MEDCouplingAutoRefCountObjectPtr<MEDCouplingUMesh> workMesh=mc->getMeshAtLevel(0); + std::vector<int> code=workMesh->getDistributionOfTypes(); + cout << "Building the graph : " << flush; + DataArrayInt *neighb=0,*neighbI=0; + workMesh->computeNeighborsOfCells(neighb,neighbI); + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> neighbSafe(neighb),neighbISafe(neighbI),ipermSafe,permSafe; + const int *graph=neighbSafe->begin(); + const int *graph_index=neighbISafe->begin(); + // Compute permutation iperm->new2old perm->old2new + DataArrayInt *iperm(0),*perm(0); + Renumbering *renumb=RenumberingFactory(type_renum); + renumb->renumber(graph,graph_index,workMesh->getNumberOfCells(),iperm,perm); + ipermSafe=iperm; permSafe=perm; + delete renumb; + ipermSafe=0;//erase new2old, we are using only old 2 new + t_compute_graph=clock(); + cout << " : " << (t_compute_graph-t_read_st)/(double) CLOCKS_PER_SEC << "s" << endl; + cout.flush(); + // Connectivity + cout << "Reordering connectivity & families and writing : " << flush; + workMesh->renumberCells(perm->begin(),false); + mc->setMeshAtLevel(0,workMesh); + const DataArrayInt *famField=mc->getFamilyFieldAtLevel(0); + if(famField) + { + MEDCouplingAutoRefCountObjectPtr<DataArrayInt> famField2=famField->renumber(perm->begin()); + mc->setFamilyFieldArr(0,famField2); + } + mc->write(filename_out,2); + t_family=clock(); + cout << " : " << (t_family-t_compute_graph)/(double) CLOCKS_PER_SEC << "s" << endl << flush; + // Fields + cout << "Reordering fields and writing : " << flush; + MEDFileFields *fs=fd->getFields(); + if(fs) + { + for(int i=0;i<fs->getNumberOfFields();i++) + { + MEDFileFieldMultiTS *fmts=dynamic_cast<MEDFileFieldMultiTS *>(fs->getFieldAtPos(i)); + if(!fmts) continue; + if(fmts->getMeshName()==meshname) + { + for(int j=0;j<fmts->getNumberOfTS();j++) + { + MEDFileField1TS *f1ts=dynamic_cast<MEDFileField1TS*>(fmts->getTimeStepAtPos(j)); + if(!f1ts) continue; + DataArrayDouble *arr=f1ts->getUndergroundDataArray(); + arr->renumberInPlace(perm->begin()); + } + } + } + fs->write(filename_out,0); + //fs->renumberEntitiesLyingOnMesh(meshname,code,code,o2n); bugged + } + t_field=clock(); + cout << " : " << (t_field-t_family)/(double) CLOCKS_PER_SEC << "s" << endl << flush; + return 0; +} diff --git a/src/medtool/src/RENUMBER/testRenumbering.py b/src/medtool/src/RENUMBER/testRenumbering.py new file mode 100755 index 000000000..c18ba6795 --- /dev/null +++ b/src/medtool/src/RENUMBER/testRenumbering.py @@ -0,0 +1,210 @@ +#!/usr/bin/env python +# -*- coding: iso-8859-1 -*- +# Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 +# 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 +# + +from MEDLoader import * +import os +import sys +import unittest + +class RenumberingTest(unittest.TestCase): + def testBoost2D(self): + filename="Test2D.med" + meshname="Mesh_1" + method="BOOST" + string_to_execute=self.dir_renumber+" "+self.dir_mesh+"/"+filename+" "+meshname+" "+method+" "+self.dir_mesh+"/out_"+filename + os.system(string_to_execute) + mm=MEDFileMesh.New(self.dir_mesh+"/out_"+filename,meshname) + m=mm.getMeshAtLevel(0) + ff=MEDFileField1TS(self.dir_mesh+"/out_"+filename,"Test field") + field_ini=DataArrayDouble([(2,3),(12,13),(14,15),(4,5),(6,7),(8,9),(16,17),(0,1),(10,11)]) + ff.getFieldOnMeshAtLevel(ON_CELLS,0,mm) + f=ff.getFieldOnMeshAtLevel(ON_CELLS,0,mm) + field=f.getArray().isEqual(field_ini,1e-15) + connectivite=[4,1,5,12,10,4,10,12,13,11,4,5,4,14,12,4,11,13,9,3,4,12,14,15,13,4,4,0,6,14,4,13,15,8,9,4,14,6,7,15,4,15,7,2,8] + connectivite_index=[0,5,10,15,20,25,30,35,40,45] + Boost2D=m.getNodalConnectivity().getValues()==connectivite and m.getNodalConnectivityIndex().getValues()==connectivite_index and field + self.assertTrue(Boost2D) + os.remove(self.dir_mesh+"/out_"+filename) + pass + + def tessMetis2D(self):#not activated yet + filename="Test2D.med" + meshname="Mesh_1" + method="METIS" + string_to_execute=self.dir_renumber+" "+self.dir_mesh+"/"+filename+" "+meshname+" "+method+" "+self.dir_mesh+"/out_"+filename + os.system(string_to_execute) + m = MESH(MED_DRIVER,self.dir_mesh+"/out_"+filename,meshname) + nbcell2dmetis=m.getNumberOfElements(MED_CELL,MED_ALL_ELEMENTS) + connectivite=[12,14,10,4,2,6,13,11,11,13,14,12,16,8,3,9,5,1,7,15,15,7,8,16,14,16,9,10,6,5,15,13,13,15,16,14] + connectivite_index=[1,5,9,13,17,21,25,29,33,37] + conn=m.getConnectivity(MED_NODAL,MED_CELL,MED_QUAD4) + conn_index=m.getConnectivityIndex(MED_NODAL,MED_CELL); + conn2dmetis=(list(conn)==connectivite) + conn_index2dmetis=(list(conn_index)==connectivite_index) + Metis2D=conn2dmetis and conn_index2dmetis and (nbcell2dmetis==9) + self.assertTrue(Metis2D) + os.remove(self.dir_mesh+"/out_"+filename) + pass + + def testBoost2DPolygon(self): + filename="Test2Dpoly.med" + meshname="Mesh_1" + method="BOOST" + string_to_execute=self.dir_renumber+" "+self.dir_mesh+"/"+filename+" "+meshname+" "+method+" "+self.dir_mesh+"/out_"+filename + os.system(string_to_execute) + mm=MEDFileMesh.New(self.dir_mesh+"/out_"+filename,meshname) + m=mm.getMeshAtLevel(0) + nbcell2dpolyboost=m.getNumberOfCells() + connectivite=[5,1,4,8,9,5,10,9,8,11,5,4,5,7,8,5,3,10,11,15,5,11,8,7,12,5,5,0,6,7,5,15,11,12,14,5,12,7,6,13,5,14,12,13,2] + connectivite_index=[0,5,10,15,20,25,30,35,40,45] + conn=m.getNodalConnectivity().getValues() + conn_index=m.getNodalConnectivityIndex().getValues() + conn2dpolyboost=(list(conn)==connectivite) + conn_index2dpolyboost=(list(conn_index)==connectivite_index) + PolyBoost2D=conn2dpolyboost and conn_index2dpolyboost and (nbcell2dpolyboost==9) + self.assertTrue(PolyBoost2D) + os.remove(self.dir_mesh+"/out_"+filename) + pass + + def tessMetis2DPolygon(self):#not activated yet + filename="Test2Dpoly.med" + meshname="Mesh_1" + method="METIS" + string_to_execute=self.dir_renumber+" "+self.dir_mesh+"/"+filename+" "+meshname+" "+method+" "+self.dir_mesh+"/out_"+filename + os.system(string_to_execute) + m = MESH(MED_DRIVER,self.dir_mesh+"/out_"+filename,meshname) + nbcell2dpolymetis=m.getNumberOfElements(MED_CELL,MED_ALL_ELEMENTS) + connectivite=[6,1,7,8,2,5,9,10,5,6,8,9,15,13,14,3,4,11,12,16,16,12,13,15,11,10,9,12,12,9,8,13,13,8,7,14] + connectivite_index=[1,5,9,13,17,21,25,29,33,37] + conn=m.getConnectivity(MED_NODAL,MED_CELL,MED_POLYGON) + conn_index=m.getConnectivityIndex(MED_NODAL,MED_CELL) + conn2dpolymetis=(list(conn)==connectivite) + conn_index2dpolymetis=(list(conn_index)==connectivite_index) + PolyMetis2D=conn2dpolymetis and conn_index2dpolymetis and (nbcell2dpolymetis==9) + self.assertTrue(PolyMetis2D) + os.remove(self.dir_mesh+"/out_"+filename) + pass + + def testBoost3D(self): + filename="Test3D.med" + meshname="Mesh_1" + method="BOOST" + string_to_execute=self.dir_renumber+" "+self.dir_mesh+"/"+filename+" "+meshname+" "+method+" "+self.dir_mesh+"/out_"+filename + os.system(string_to_execute) + mm=MEDFileMesh.New(self.dir_mesh+"/out_"+filename,meshname) + m=mm.getMeshAtLevel(0) + nbcell3dboost=m.getNumberOfCells() + connectivite=[18,22,12,4,17,26,21,13,25,18,16,5,12,22,24,15,21,26,18,26,21,13,25,23,14,6,19,18,8,22,17,0,20,26,25,9,18,24,15,21,26,18,7,14,23,18,1,16,22,8,11,24,26,20,18,20,26,25,9,10,23,19,2,18,11,24,26,20,3,18,23,10] + connectivite_index=[0,9,18,27,36,45,54,63,72] + conn=m.getNodalConnectivity().getValues() + conn_index=m.getNodalConnectivityIndex().getValues() + conn3dboost=(list(conn)==connectivite) + conn_index3dboost=(list(conn_index)==connectivite_index) + Boost3D=conn3dboost and conn_index3dboost and (nbcell3dboost==8) + self.assertTrue(Boost3D) + os.remove(self.dir_mesh+"/out_"+filename) + pass + + def tessMetis3D(self):#not activated yet + filename="Test3D.med" + meshname="Mesh_1" + method="METIS" + string_to_execute=self.dir_renumber+" "+self.dir_mesh+"/"+filename+" "+meshname+" "+method+" "+self.dir_mesh+"/out_"+filename + os.system(string_to_execute) + m = MESH(MED_DRIVER,self.dir_mesh+"/out_"+filename,meshname) + nbcell3dmetis=m.getNumberOfElements(MED_CELL,MED_ALL_ELEMENTS) + connectivite=[12,25,27,21,4,19,24,11,27,22,14,26,24,15,7,20,17,6,13,23,25,16,22,27,9,23,18,1,21,27,26,10,23,13,5,18,27,22,14,26,25,16,22,27,19,8,15,24,2,17,23,9,12,25,27,21,21,27,26,10,11,24,20,3] + connectivite_index=[1,9,17,25,33,41,49,57,65] + conn=m.getConnectivity(MED_NODAL,MED_CELL,MED_HEXA8) + conn_index=m.getConnectivityIndex(MED_NODAL,MED_CELL); + conn3dmetis=(list(conn)==connectivite) + conn_index3dmetis=(list(conn_index)==connectivite_index) + Metis3D=conn3dmetis&conn_index3dmetis&(nbcell3dmetis==8) + self.assertTrue(Metis3D) + os.remove(self.dir_mesh+"/out_"+filename) + pass + + def testBoost3DPoly(self): + filename="Test3Dpoly.med" + meshname="Mesh_1" + method="BOOST" + string_to_execute=self.dir_renumber+" "+self.dir_mesh+"/"+filename+" "+meshname+" "+method+" "+self.dir_mesh+"/out_"+filename + os.system(string_to_execute) + mm=MEDFileMesh.New(self.dir_mesh+"/out_"+filename,meshname) + m=mm.getMeshAtLevel(0) + nbcell3dpolyboost=m.getNumberOfCells() + connectivite=[31,22,12,4,17,-1,26,25,13,21,-1,22,26,21,12,-1,12,21,13,4,-1,4,13,25,17,-1,17,25,26,22,31,16,5,12,22,-1,24,26,21,15,-1,16,24,15,5,-1,5,15,21,12,-1,12,21,26,22,-1,22,26,24,16,31,26,21,13,25,-1,23,19,6,14,-1,26,23,14,21,-1,21,14,6,13,-1,13,6,19,25,-1,25,19,23,26,31,8,22,17,0,-1,20,9,25,26,-1,8,20,26,22,-1,22,26,25,17,-1,17,25,9,0,-1,0,9,20,8,31,24,15,21,26,-1,18,23,14,7,-1,24,18,7,15,-1,15,7,14,21,-1,21,14,23,26,-1,26,23,18,24,31,1,16,22,8,-1,11,20,26,24,-1,1,11,24,16,-1,16,24,26,22,-1,22,26,20,8,-1,8,20,11,1,31,20,26,25,9,-1,10,2,19,23,-1,20,10,23,26,-1,26,23,19,25,-1,25,19,2,9,-1,9,2,10,20,31,11,24,26,20,-1,3,10,23,18,-1,11,3,18,24,-1,24,18,23,26,-1,26,23,10,20,-1,20,10,3,11] + connectivite_index=[0,30,60,90,120,150,180,210,240] + conn=m.getNodalConnectivity().getValues() + conn_index=m.getNodalConnectivityIndex().getValues() + conn3dpolyboost=(connectivite==list(conn)) + conn_index3dpolyboost=(connectivite_index==list(conn_index)) + PolyBoost3D=(conn3dpolyboost and conn_index3dpolyboost and (nbcell3dpolyboost==8)) + self.assertTrue(PolyBoost3D) + os.remove(self.dir_mesh+"/out_"+filename) + pass + + def tessBoost3DPoly(self):#not activated yet + filename="Test3Dpoly.med" + meshname="Mesh_1" + method="METIS" + string_to_execute=self.dir_renumber+" "+self.dir_mesh+"/"+filename+" "+meshname+" "+method+" "+self.dir_mesh+"/out_"+filename + os.system(string_to_execute) + m = MESH(MED_DRIVER,self.dir_mesh+"/out_"+filename,meshname) + nbcell3dpolymetis=m.getNumberOfElements(MED_CELL,MED_ALL_ELEMENTS) + connectivite=[12,25,27,21,-1,4,11,24,19,-1,12,4,19,25,-1,25,19,24,27,-1,27,24,11,21,-1,21,11,4,12, + 27,22,14,26,-1,24,20,7,15,-1,27,24,15,22,-1,22,15,7,14,-1,14,7,20,26,-1,26,20,24,27, + 17,6,13,23,-1,25,27,22,16,-1,17,25,16,6,-1,6,16,22,13,-1,13,22,27,23,-1,23,27,25,17, + 9,23,18,1,-1,21,10,26,27,-1,9,21,27,23,-1,23,27,26,18,-1,18,26,10,1,-1,1,10,21,9, + 23,13,5,18,-1,27,26,14,22,-1,23,27,22,13,-1,13,22,14,5,-1,5,14,26,18,-1,18,26,27,23, + 25,16,22,27,-1,19,24,15,8,-1,25,19,8,16,-1,16,8,15,22,-1,22,15,24,27,-1,27,24,19,25, + 2,17,23,9,-1,12,21,27,25,-1,2,12,25,17,-1,17,25,27,23,-1,23,27,21,9,-1,9,21,12,2, + 21,27,26,10,-1,11,3,20,24,-1,21,11,24,27,-1,27,24,20,26,-1,26,20,3,10,-1,10,3,11,21] + connectivite_index=[1, 30, 59, 88, 117, 146, 175, 204, 233] + conn=m.getConnectivity(MED_NODAL,MED_CELL,MED_POLYHEDRA) + conn_index=m.getConnectivityIndex(MED_NODAL,MED_CELL); + conn3dpolymetis=(list(conn)==connectivite) + conn_index3dpolymetis=(list(conn_index)==connectivite_index) + PolyMetis3D=(conn3dpolymetis and conn_index3dpolymetis and (nbcell3dpolymetis==8)) + self.assertTrue(PolyMetis3D) + os.remove(self.dir_mesh+"/out_"+filename) + pass + + def setUp(self): + srcdir = os.getenv("srcdir") + med_root = os.getenv("MED_ROOT_DIR") + if srcdir: + # make test is being performed + self.dir_renumber="./renumber" + self.dir_mesh = os.path.join( srcdir, "../../resources") + elif med_root: + # hope renumber has been already installed + self.dir_renumber=os.path.join( med_root, "bin/salome/renumber") + self.dir_mesh = os.path.join( med_root, "share/salome/resources/med") + else: + # initial version + self.dir_renumber="../../../MED_INSTALL/bin/salome/renumber" + self.dir_mesh="../../resources" + pass + pass + pass + +unittest.main() diff --git a/src/medtool/src/RENUMBER_Swig/CMakeLists.txt b/src/medtool/src/RENUMBER_Swig/CMakeLists.txt new file mode 100644 index 000000000..ca5363830 --- /dev/null +++ b/src/medtool/src/RENUMBER_Swig/CMakeLists.txt @@ -0,0 +1,80 @@ +# Copyright (C) 2012-2015 CEA/DEN, EDF 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, 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 +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +# +# See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +# + +INCLUDE(${SWIG_USE_FILE}) + +ADD_DEFINITIONS(${PYTHON_DEFINITIONS}) + +SET_SOURCE_FILES_PROPERTIES(MEDRenumber.i PROPERTIES CPLUSPLUS ON) +SET_SOURCE_FILES_PROPERTIES(MEDRenumber.i PROPERTIES SWIG_DEFINITIONS "-shadow") +SET(SWIG_MODULE_MEDRenumber_EXTRA_FLAGS "${SWIG_EXTRA_FLAGS_FOR_NUMPYANDSCIPY};-DWITHOUT_AUTOFIELD") + +IF(Boost_FOUND) + SET(SWIG_MODULE_MEDRenumber_EXTRA_FLAGS -DHAS_BOOST ${SWIG_MODULE_MEDRenumber_EXTRA_FLAGS}) +ENDIF(Boost_FOUND) + +IF(METIS_FOUND) + SET(SWIG_MODULE_MEDRenumber_EXTRA_FLAGS -DHAS_METIS ${SWIG_MODULE_MEDRenumber_EXTRA_FLAGS}) +ENDIF(METIS_FOUND) + +SET (MEDRenumber_SWIG_DPYS_FILES + MEDRenumberCommon.i) + +INCLUDE_DIRECTORIES( + ${PYTHON_INCLUDE_DIRS} + ${PTHREAD_INCLUDE_DIR} # pthread dependancy due to python2.7 library + ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_CURRENT_BINARY_DIR} + ${CMAKE_CURRENT_SOURCE_DIR}/../RENUMBER + ${CMAKE_CURRENT_SOURCE_DIR}/../MEDCoupling_Swig + ${CMAKE_CURRENT_SOURCE_DIR}/../MEDCoupling + ${CMAKE_CURRENT_SOURCE_DIR}/../INTERP_KERNEL + ${CMAKE_CURRENT_SOURCE_DIR}/../INTERP_KERNEL/Bases + ${CMAKE_CURRENT_SOURCE_DIR}/../INTERP_KERNEL/Geometric2D + ${CMAKE_CURRENT_SOURCE_DIR}/../INTERP_KERNEL/ExprEval + ${CMAKE_CURRENT_SOURCE_DIR}/../INTERP_KERNEL/GaussPoints + ) + +SWIG_ADD_MODULE(MEDRenumber python MEDRenumber.i) +SWIG_LINK_LIBRARIES(MEDRenumber ${PYTHON_LIBRARIES} ${PLATFORM_LIBS} renumbercpp) + +IF(WIN32) + SET_TARGET_PROPERTIES(_MEDRenumber PROPERTIES DEBUG_OUTPUT_NAME _MEDRenumber_d) +ENDIF(WIN32) +INSTALL(TARGETS ${SWIG_MODULE_MEDRenumber_REAL_NAME} DESTINATION ${MEDTOOL_INSTALL_PYTHON}) + +#SET(PYFILES_TO_INSTALL ${CMAKE_CURRENT_BINARY_DIR}/MEDRenumber.py) +#SALOME_INSTALL_SCRIPTS("${PYFILES_TO_INSTALL}" ${SALOME_INSTALL_SCRIPT_PYTHON}) +INSTALL(FILES ${CMAKE_CURRENT_BINARY_DIR}/MEDRenumber.py DESTINATION ${MEDTOOL_INSTALL_SCRIPT_PYTHON}) + +INSTALL(FILES MEDRenumber.i MEDRenumberCommon.i DESTINATION ${MEDTOOL_INSTALL_HEADERS}) +INSTALL(FILES MEDRenumberTest.py DESTINATION ${MEDTOOL_INSTALL_SCRIPT_PYTHON}) + +#SALOME_GENERATE_TESTS_ENVIRONMENT(tests_env) +ADD_TEST(MEDRenumberTest ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/MEDRenumberTest.py) +SET_TESTS_PROPERTIES(MEDRenumberTest PROPERTIES ENVIRONMENT "${tests_env}") + +# Application tests + +SET(TEST_INSTALL_DIRECTORY ${MEDTOOL_INSTALL_SCRIPT_SCRIPTS}/test/MEDCoupling/RENUMBER_Swig) +INSTALL(FILES MEDRenumberTest.py DESTINATION ${TEST_INSTALL_DIRECTORY}) + +INSTALL(FILES CTestTestfileInstall.cmake + DESTINATION ${TEST_INSTALL_DIRECTORY} + RENAME CTestTestfile.cmake) diff --git a/src/medtool/src/RENUMBER_Swig/CTestTestfileInstall.cmake b/src/medtool/src/RENUMBER_Swig/CTestTestfileInstall.cmake new file mode 100644 index 000000000..aeaaf7124 --- /dev/null +++ b/src/medtool/src/RENUMBER_Swig/CTestTestfileInstall.cmake @@ -0,0 +1,21 @@ +# Copyright (C) 2015 CEA/DEN, EDF 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, 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 +# 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_TEST(MEDRenumberTest python MEDRenumberTest.py) +SET_TESTS_PROPERTIES(MEDRenumberTest PROPERTIES LABELS "${COMPONENT_NAME}") diff --git a/src/medtool/src/RENUMBER_Swig/MEDRenumber.i b/src/medtool/src/RENUMBER_Swig/MEDRenumber.i new file mode 100644 index 000000000..9ba28d274 --- /dev/null +++ b/src/medtool/src/RENUMBER_Swig/MEDRenumber.i @@ -0,0 +1,141 @@ +// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// + +%include "MEDRenumberCommon.i" + +%pythoncode %{ +def ParaMEDMEMDataArrayDoublenew(cls,*args): + import _MEDRenumber + return _MEDRenumber.DataArrayDouble____new___(cls,args) +def ParaMEDMEMDataArrayDoubleIadd(self,*args): + import _MEDRenumber + return _MEDRenumber.DataArrayDouble____iadd___(self, self, *args) +def ParaMEDMEMDataArrayDoubleIsub(self,*args): + import _MEDRenumber + return _MEDRenumber.DataArrayDouble____isub___(self, self, *args) +def ParaMEDMEMDataArrayDoubleImul(self,*args): + import _MEDRenumber + return _MEDRenumber.DataArrayDouble____imul___(self, self, *args) +def ParaMEDMEMDataArrayDoubleIdiv(self,*args): + import _MEDRenumber + return _MEDRenumber.DataArrayDouble____idiv___(self, self, *args) +def ParaMEDMEMDataArrayDoubleIpow(self,*args): + import _MEDRenumber + return _MEDRenumber.DataArrayDouble____ipow___(self, self, *args) +def ParaMEDMEMDataArrayIntnew(cls,*args): + import _MEDRenumber + return _MEDRenumber.DataArrayInt____new___(cls,args) +def ParaMEDMEMDataArrayIntIadd(self,*args): + import _MEDRenumber + return _MEDRenumber.DataArrayInt____iadd___(self, self, *args) +def ParaMEDMEMDataArrayIntIsub(self,*args): + import _MEDRenumber + return _MEDRenumber.DataArrayInt____isub___(self, self, *args) +def ParaMEDMEMDataArrayIntImul(self,*args): + import _MEDRenumber + return _MEDRenumber.DataArrayInt____imul___(self, self, *args) +def ParaMEDMEMDataArrayIntIdiv(self,*args): + import _MEDRenumber + return _MEDRenumber.DataArrayInt____idiv___(self, self, *args) +def ParaMEDMEMDataArrayIntImod(self,*args): + import _MEDRenumber + return _MEDRenumber.DataArrayInt____imod___(self, self, *args) +def ParaMEDMEMDataArrayIntIpow(self,*args): + import _MEDRenumber + return _MEDRenumber.DataArrayInt____ipow___(self, self, *args) +def ParaMEDMEMDataArrayDoubleTupleIadd(self,*args): + import _MEDRenumber + return _MEDRenumber.DataArrayDoubleTuple____iadd___(self, self, *args) +def ParaMEDMEMDataArrayDoubleTupleIsub(self,*args): + import _MEDRenumber + return _MEDRenumber.DataArrayDoubleTuple____isub___(self, self, *args) +def ParaMEDMEMDataArrayDoubleTupleImul(self,*args): + import _MEDRenumber + return _MEDRenumber.DataArrayDoubleTuple____imul___(self, self, *args) +def ParaMEDMEMDataArrayDoubleTupleIdiv(self,*args): + import _MEDRenumber + return _MEDRenumber.DataArrayDoubleTuple____idiv___(self, self, *args) +def ParaMEDMEMDataArrayIntTupleIadd(self,*args): + import _MEDRenumber + return _MEDRenumber.DataArrayIntTuple____iadd___(self, self, *args) +def ParaMEDMEMDataArrayIntTupleIsub(self,*args): + import _MEDRenumber + return _MEDRenumber.DataArrayIntTuple____isub___(self, self, *args) +def ParaMEDMEMDataArrayIntTupleImul(self,*args): + import _MEDRenumber + return _MEDRenumber.DataArrayIntTuple____imul___(self, self, *args) +def ParaMEDMEMDataArrayIntTupleIdiv(self,*args): + import _MEDRenumber + return _MEDRenumber.DataArrayIntTuple____idiv___(self, self, *args) +def ParaMEDMEMDataArrayIntTupleImod(self,*args): + import _MEDRenumber + return _MEDRenumber.DataArrayIntTuple____imod___(self, self, *args) +%} + + +%pythoncode %{ +InterpKernelException.__reduce__=INTERPKERNELExceptionReduce +DataArrayDouble.__new__=classmethod(ParaMEDMEMDataArrayDoublenew) +DataArrayDouble.__iadd__=ParaMEDMEMDataArrayDoubleIadd +DataArrayDouble.__isub__=ParaMEDMEMDataArrayDoubleIsub +DataArrayDouble.__imul__=ParaMEDMEMDataArrayDoubleImul +DataArrayDouble.__idiv__=ParaMEDMEMDataArrayDoubleIdiv +DataArrayDouble.__ipow__=ParaMEDMEMDataArrayDoubleIpow + +DataArrayInt.__new__=classmethod(ParaMEDMEMDataArrayIntnew) +DataArrayInt.__iadd__=ParaMEDMEMDataArrayIntIadd +DataArrayInt.__isub__=ParaMEDMEMDataArrayIntIsub +DataArrayInt.__imul__=ParaMEDMEMDataArrayIntImul +DataArrayInt.__idiv__=ParaMEDMEMDataArrayIntIdiv +DataArrayInt.__imod__=ParaMEDMEMDataArrayIntImod +DataArrayInt.__ipow__=ParaMEDMEMDataArrayIntIpow + +DataArrayDoubleTuple.__iadd__=ParaMEDMEMDataArrayDoubleTupleIadd +DataArrayDoubleTuple.__isub__=ParaMEDMEMDataArrayDoubleTupleIsub +DataArrayDoubleTuple.__imul__=ParaMEDMEMDataArrayDoubleTupleImul +DataArrayDoubleTuple.__idiv__=ParaMEDMEMDataArrayDoubleTupleIdiv + +DataArrayIntTuple.__iadd__=ParaMEDMEMDataArrayIntTupleIadd +DataArrayIntTuple.__isub__=ParaMEDMEMDataArrayIntTupleIsub +DataArrayIntTuple.__imul__=ParaMEDMEMDataArrayIntTupleImul +DataArrayIntTuple.__idiv__=ParaMEDMEMDataArrayIntTupleIdiv +DataArrayIntTuple.__imod__=ParaMEDMEMDataArrayIntTupleImod + +del INTERPKERNELExceptionReduce +del ParaMEDMEMDataArrayDoublenew +del ParaMEDMEMDataArrayDoubleIadd +del ParaMEDMEMDataArrayDoubleIsub +del ParaMEDMEMDataArrayDoubleImul +del ParaMEDMEMDataArrayDoubleIdiv +del ParaMEDMEMDataArrayIntnew +del ParaMEDMEMDataArrayIntIadd +del ParaMEDMEMDataArrayIntIsub +del ParaMEDMEMDataArrayIntImul +del ParaMEDMEMDataArrayIntIdiv +del ParaMEDMEMDataArrayIntImod +del ParaMEDMEMDataArrayDoubleTupleIadd +del ParaMEDMEMDataArrayDoubleTupleIsub +del ParaMEDMEMDataArrayDoubleTupleImul +del ParaMEDMEMDataArrayDoubleTupleIdiv +del ParaMEDMEMDataArrayIntTupleIadd +del ParaMEDMEMDataArrayIntTupleIsub +del ParaMEDMEMDataArrayIntTupleImul +del ParaMEDMEMDataArrayIntTupleIdiv +del ParaMEDMEMDataArrayIntTupleImod +%} diff --git a/src/medtool/src/RENUMBER_Swig/MEDRenumberCommon.i b/src/medtool/src/RENUMBER_Swig/MEDRenumberCommon.i new file mode 100644 index 000000000..85f5d7e7c --- /dev/null +++ b/src/medtool/src/RENUMBER_Swig/MEDRenumberCommon.i @@ -0,0 +1,107 @@ +// Copyright (C) 2007-2015 CEA/DEN, EDF 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, 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 +// 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) + +%module MEDRenumber + +%include std_vector.i +%include std_string.i + +%{ +#include "MEDCouplingMemArray.hxx" +#include "MEDCouplingAutoRefCountObjectPtr.hxx" +#include "MEDCouplingDataArrayTypemaps.i" + +#include "RenumberingFactory.hxx" +#include "RENUMBER_Renumbering.hxx" + +using namespace ParaMEDMEM; +using namespace INTERP_KERNEL; + using namespace MED_RENUMBER; +%} + +%template(ivec) std::vector<int>; +%template(dvec) std::vector<double>; +%template(svec) std::vector<std::string>; + +#ifdef WITH_NUMPY +%init %{ import_array(); %} +#endif + +%feature("autodoc", "1"); +%feature("docstring"); + +%newobject MED_RENUMBER::RenumberingFactory; + +%nodefaultctor; + +%rename (InterpKernelException) INTERP_KERNEL::Exception; + +%include "MEDCouplingRefCountObject.i" +%include "MEDCouplingMemArray.i" + +class Renumbering +{ +public: + %extend + { + virtual PyObject *renumber(const ParaMEDMEM::DataArrayInt *graph, const ParaMEDMEM::DataArrayInt *index_graph) throw(INTERP_KERNEL::Exception) + { + if(!graph || !index_graph) + throw INTERP_KERNEL::Exception("wrap of Renumbering::renumber : One of the input arrays is NULL !"); + if(!graph->isAllocated() || !index_graph->isAllocated()) + throw INTERP_KERNEL::Exception("wrap of Renumbering::renumber : One of the input arrays is not allocated !"); + ParaMEDMEM::DataArrayInt *out0(0),*out1(0); + self->renumber(graph->begin(),index_graph->begin(),index_graph->getNumberOfTuples()-1,out0,out1); + PyObject *ret=PyTuple_New(2); + PyTuple_SetItem(ret,0,SWIG_NewPointerObj(SWIG_as_voidptr(out0),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 )); + PyTuple_SetItem(ret,1,SWIG_NewPointerObj(SWIG_as_voidptr(out1),SWIGTYPE_p_ParaMEDMEM__DataArrayInt, SWIG_POINTER_OWN | 0 )); + return ret; + } + } + virtual ~Renumbering(); +}; + +namespace MED_RENUMBER +{ + Renumbering *RenumberingFactory(const std::string& s) throw(INTERP_KERNEL::Exception); +} + +%inline +{ + std::vector<std::string> RenumberAvailableMethods()throw(INTERP_KERNEL::Exception) + { + std::vector<std::string> ret; +#ifdef HAS_BOOST + ret.push_back(std::string("BOOST")); +#endif +#ifdef HAS_METIS + ret.push_back(std::string("METIS")); +#endif + return ret; + } +} + +%pythoncode %{ +import os +__filename=os.environ.get('PYTHONSTARTUP') +if __filename and os.path.isfile(__filename): + execfile(__filename) + pass +%} diff --git a/src/medtool/src/RENUMBER_Swig/MEDRenumberTest.py b/src/medtool/src/RENUMBER_Swig/MEDRenumberTest.py new file mode 100644 index 000000000..15199faa0 --- /dev/null +++ b/src/medtool/src/RENUMBER_Swig/MEDRenumberTest.py @@ -0,0 +1,41 @@ +# Copyright (C) 2012-2015 CEA/DEN, EDF 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, 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 +# 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 +# + +from MEDRenumber import * +import unittest + +class MEDRenumberTest(unittest.TestCase): + + @unittest.skipUnless("BOOST" in RenumberAvailableMethods(),"requires BOOST prerequisite !") + def test1(self): + from MEDCoupling import MEDCouplingCMesh + ren=RenumberingFactory("BOOST") + arr=DataArrayDouble(10) ; arr.iota() + c=MEDCouplingCMesh() ; c.setCoords(arr,arr) + m=c.buildUnstructured() + a,b=m.computeNeighborsOfCells() + n2o,o2n=ren.renumber(a,b) + self.assertTrue(o2n.isEqual(DataArrayInt([0,2,5,9,14,20,27,35,44,1,4,8,13,19,26,34,43,52,3,7,12,18,25,33,42,51,59,6,11,17,24,32,41,50,58,65,10,16,23,31,40,49,57,64,70,15,22,30,39,48,56,63,69,74,21,29,38,47,55,62,68,73,77,28,37,46,54,61,67,72,76,79,36,45,53,60,66,71,75,78,80]))) + pass + + def setUp(self): + pass + pass + +unittest.main()